From a6d2f108eabd2b5f5e8416a4f1ef3c6d7e543133 Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 15 Oct 2015 09:50:38 -0400 Subject: [PATCH 01/35] bump(github.com/prometheus/client_golang): 3b78d7a77f51ccbc364d4bc170920153022cfd08 --- Godeps/Godeps.json | 14 +- .../client_golang/extraction/discriminator.go | 74 -- .../extraction/discriminator_test.go | 126 -- .../client_golang/extraction/extraction.go | 15 - .../extraction/fixtures/empty.json | 0 .../fixtures/test0_0_1-0_0_2-large.json | 1032 ----------------- .../extraction/fixtures/test0_0_1-0_0_2.json | 79 -- .../extraction/metricfamilyprocessor.go | 318 ----- .../extraction/metricfamilyprocessor_test.go | 153 --- .../client_golang/extraction/processor.go | 84 -- .../extraction/processor0_0_1.go | 127 -- .../extraction/processor0_0_1_test.go | 185 --- .../extraction/processor0_0_2.go | 106 -- .../extraction/processor0_0_2_test.go | 225 ---- .../client_golang/extraction/textprocessor.go | 40 - .../extraction/textprocessor_test.go | 100 -- .../client_golang/model/fingerprinting.go | 110 -- .../client_golang/model/labelname.go | 71 -- .../client_golang/model/labelname_test.go | 55 - .../client_golang/model/labelset.go | 64 - .../client_golang/model/labelvalue.go | 36 - .../client_golang/model/labelvalue_test.go | 55 - .../prometheus/client_golang/model/metric.go | 132 --- .../client_golang/model/metric_test.go | 121 -- .../prometheus/client_golang/model/model.go | 15 - .../prometheus/client_golang/model/sample.go | 79 -- .../client_golang/model/sample_test.go | 126 -- .../client_golang/model/samplevalue.go | 37 - .../client_golang/model/signature.go | 150 --- .../client_golang/model/signature_test.go | 256 ---- .../client_golang/model/timestamp.go | 116 -- .../client_golang/model/timestamp_test.go | 86 -- .../client_golang/prometheus/counter.go | 2 +- .../client_golang/prometheus/desc.go | 18 +- .../client_golang/prometheus/doc.go | 11 +- .../client_golang/prometheus/examples_test.go | 131 +++ .../client_golang/prometheus/go_collector.go | 21 +- .../prometheus/go_collector_test.go | 71 +- .../client_golang/prometheus/histogram.go | 122 +- .../prometheus/histogram_test.go | 8 + .../client_golang/prometheus/http.go | 45 +- .../client_golang/prometheus/metric.go | 2 + .../client_golang/prometheus/registry.go | 106 +- .../client_golang/prometheus/registry_test.go | 20 +- .../client_golang/prometheus/summary.go | 102 +- .../client_golang/prometheus/untyped.go | 2 +- .../client_golang/prometheus/value.go | 6 +- .../client_golang/prometheus/vec.go | 10 +- .../client_golang/text/bench_test.go | 168 --- .../prometheus/client_golang/text/create.go | 315 ----- .../client_golang/text/create_test.go | 439 ------- .../prometheus/client_golang/text/parse.go | 739 ------------ .../client_golang/text/parse_test.go | 588 ---------- .../prometheus/client_golang/text/proto.go | 43 - .../client_golang/text/testdata/protobuf | Bin 8243 -> 0 bytes .../client_golang/text/testdata/protobuf.gz | Bin 2053 -> 0 bytes .../client_golang/text/testdata/text | 322 ----- .../client_golang/text/testdata/text.gz | Bin 2595 -> 0 bytes 58 files changed, 567 insertions(+), 6911 deletions(-) delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/discriminator.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/discriminator_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/extraction.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/fixtures/empty.json delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/fixtures/test0_0_1-0_0_2-large.json delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/fixtures/test0_0_1-0_0_2.json delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/metricfamilyprocessor.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/metricfamilyprocessor_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_1.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_1_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_2.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_2_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/textprocessor.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/textprocessor_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/fingerprinting.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelset.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/model.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/samplevalue.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/text/bench_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/text/create.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/text/create_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/text/parse.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/text/parse_test.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/text/proto.go delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/text/testdata/protobuf delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/text/testdata/protobuf.gz delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/text/testdata/text delete mode 100644 Godeps/_workspace/src/github.com/prometheus/client_golang/text/testdata/text.gz diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 97d4bee1054c..8f3053c91a97 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -737,20 +737,10 @@ "Comment": "0.4.0-1-g692492e", "Rev": "692492e54b553a81013254cc1fba4b6dd76fad30" }, - { - "ImportPath": "github.com/prometheus/client_golang/model", - "Comment": "0.4.0-1-g692492e", - "Rev": "692492e54b553a81013254cc1fba4b6dd76fad30" - }, { "ImportPath": "github.com/prometheus/client_golang/prometheus", - "Comment": "0.4.0-1-g692492e", - "Rev": "692492e54b553a81013254cc1fba4b6dd76fad30" - }, - { - "ImportPath": "github.com/prometheus/client_golang/text", - "Comment": "0.4.0-1-g692492e", - "Rev": "692492e54b553a81013254cc1fba4b6dd76fad30" + "Comment": "0.7.0-39-g3b78d7a", + "Rev": "3b78d7a77f51ccbc364d4bc170920153022cfd08" }, { "ImportPath": "github.com/prometheus/client_model/go", diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/discriminator.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/discriminator.go deleted file mode 100644 index a353c6378ce8..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/discriminator.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package extraction - -import ( - "errors" - "fmt" - "mime" - "net/http" -) - -// ProcessorForRequestHeader interprets a HTTP request header to determine -// what Processor should be used for the given input. If no acceptable -// Processor can be found, an error is returned. -func ProcessorForRequestHeader(header http.Header) (Processor, error) { - if header == nil { - return nil, errors.New("received illegal and nil header") - } - - mediatype, params, err := mime.ParseMediaType(header.Get("Content-Type")) - if err != nil { - return nil, fmt.Errorf("invalid Content-Type header %q: %s", header.Get("Content-Type"), err) - } - switch mediatype { - case "application/vnd.google.protobuf": - if params["proto"] != "io.prometheus.client.MetricFamily" { - return nil, fmt.Errorf("unrecognized protocol message %s", params["proto"]) - } - if params["encoding"] != "delimited" { - return nil, fmt.Errorf("unsupported encoding %s", params["encoding"]) - } - return MetricFamilyProcessor, nil - case "text/plain": - switch params["version"] { - case "0.0.4": - return Processor004, nil - case "": - // Fallback: most recent version. - return Processor004, nil - default: - return nil, fmt.Errorf("unrecognized API version %s", params["version"]) - } - case "application/json": - var prometheusAPIVersion string - - if params["schema"] == "prometheus/telemetry" && params["version"] != "" { - prometheusAPIVersion = params["version"] - } else { - prometheusAPIVersion = header.Get("X-Prometheus-API-Version") - } - - switch prometheusAPIVersion { - case "0.0.2": - return Processor002, nil - case "0.0.1": - return Processor001, nil - default: - return nil, fmt.Errorf("unrecognized API version %s", prometheusAPIVersion) - } - default: - return nil, fmt.Errorf("unsupported media type %q, expected %q", mediatype, "application/json") - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/discriminator_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/discriminator_test.go deleted file mode 100644 index 4f08248d643e..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/discriminator_test.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package extraction - -import ( - "errors" - "net/http" - "testing" -) - -func testDiscriminatorHTTPHeader(t testing.TB) { - var scenarios = []struct { - input map[string]string - output Processor - err error - }{ - { - output: nil, - err: errors.New("received illegal and nil header"), - }, - { - input: map[string]string{"Content-Type": "application/json", "X-Prometheus-API-Version": "0.0.0"}, - output: nil, - err: errors.New("unrecognized API version 0.0.0"), - }, - { - input: map[string]string{"Content-Type": "application/json", "X-Prometheus-API-Version": "0.0.1"}, - output: Processor001, - err: nil, - }, - { - input: map[string]string{"Content-Type": `application/json; schema="prometheus/telemetry"; version=0.0.0`}, - output: nil, - err: errors.New("unrecognized API version 0.0.0"), - }, - { - input: map[string]string{"Content-Type": `application/json; schema="prometheus/telemetry"; version=0.0.1`}, - output: Processor001, - err: nil, - }, - { - input: map[string]string{"Content-Type": `application/json; schema="prometheus/telemetry"; version=0.0.2`}, - output: Processor002, - err: nil, - }, - { - input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="io.prometheus.client.MetricFamily"; encoding="delimited"`}, - output: MetricFamilyProcessor, - err: nil, - }, - { - input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="illegal"; encoding="delimited"`}, - output: nil, - err: errors.New("unrecognized protocol message illegal"), - }, - { - input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="io.prometheus.client.MetricFamily"; encoding="illegal"`}, - output: nil, - err: errors.New("unsupported encoding illegal"), - }, - { - input: map[string]string{"Content-Type": `text/plain; version=0.0.4`}, - output: Processor004, - err: nil, - }, - { - input: map[string]string{"Content-Type": `text/plain`}, - output: Processor004, - err: nil, - }, - { - input: map[string]string{"Content-Type": `text/plain; version=0.0.3`}, - output: nil, - err: errors.New("unrecognized API version 0.0.3"), - }, - } - - for i, scenario := range scenarios { - var header http.Header - - if len(scenario.input) > 0 { - header = http.Header{} - } - - for key, value := range scenario.input { - header.Add(key, value) - } - - actual, err := ProcessorForRequestHeader(header) - - if scenario.err != err { - if scenario.err != nil && err != nil { - if scenario.err.Error() != err.Error() { - t.Errorf("%d. expected %s, got %s", i, scenario.err, err) - } - } else if scenario.err != nil || err != nil { - t.Errorf("%d. expected %s, got %s", i, scenario.err, err) - } - } - - if scenario.output != actual { - t.Errorf("%d. expected %s, got %s", i, scenario.output, actual) - } - } -} - -func TestDiscriminatorHTTPHeader(t *testing.T) { - testDiscriminatorHTTPHeader(t) -} - -func BenchmarkDiscriminatorHTTPHeader(b *testing.B) { - for i := 0; i < b.N; i++ { - testDiscriminatorHTTPHeader(b) - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/extraction.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/extraction.go deleted file mode 100644 index 31cdafad4bc9..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/extraction.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package extraction decodes Prometheus clients' data streams for consumers. -package extraction diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/fixtures/empty.json b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/fixtures/empty.json deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/fixtures/test0_0_1-0_0_2-large.json b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/fixtures/test0_0_1-0_0_2-large.json deleted file mode 100644 index 7168338c8b0e..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/fixtures/test0_0_1-0_0_2-large.json +++ /dev/null @@ -1,1032 +0,0 @@ -[ - { - "baseLabels": { - "__name__": "rpc_calls_total_0", - "job": "batch_job" - }, - "docstring": "Total count of RPC calls.", - "metric": { - "type": "counter", - "value": [ - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": 25 - }, - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "foo" - }, - "value": 25 - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_latency_microseconds_0" - }, - "docstring": "RPC latency summary.", - "metric": { - "type": "histogram", - "value": [ - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": { - "0.010000": 15.890724674774395, - "0.050000": 15.890724674774395, - "0.500000": 84.63044031436561, - "0.900000": 160.21100853053224, - "0.990000": 172.49828748957728 - } - }, - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": { - "0.010000": 0.0459814091918713, - "0.050000": 0.0459814091918713, - "0.500000": 0.6120456642749681, - "0.900000": 1.355915069887731, - "0.990000": 1.772733213161236 - } - }, - { - "labels": { - "foo": "bar", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_calls_total_1", - "job": "batch_job" - }, - "docstring": "Total count of RPC calls.", - "metric": { - "type": "counter", - "value": [ - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": 25 - }, - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "foo" - }, - "value": 25 - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_latency_microseconds_1" - }, - "docstring": "RPC latency summary.", - "metric": { - "type": "histogram", - "value": [ - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": { - "0.010000": 15.890724674774395, - "0.050000": 15.890724674774395, - "0.500000": 84.63044031436561, - "0.900000": 160.21100853053224, - "0.990000": 172.49828748957728 - } - }, - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": { - "0.010000": 0.0459814091918713, - "0.050000": 0.0459814091918713, - "0.500000": 0.6120456642749681, - "0.900000": 1.355915069887731, - "0.990000": 1.772733213161236 - } - }, - { - "labels": { - "foo": "bar", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_calls_total_2", - "job": "batch_job" - }, - "docstring": "Total count of RPC calls.", - "metric": { - "type": "counter", - "value": [ - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": 25 - }, - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "foo" - }, - "value": 25 - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_latency_microseconds_2" - }, - "docstring": "RPC latency summary.", - "metric": { - "type": "histogram", - "value": [ - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": { - "0.010000": 15.890724674774395, - "0.050000": 15.890724674774395, - "0.500000": 84.63044031436561, - "0.900000": 160.21100853053224, - "0.990000": 172.49828748957728 - } - }, - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": { - "0.010000": 0.0459814091918713, - "0.050000": 0.0459814091918713, - "0.500000": 0.6120456642749681, - "0.900000": 1.355915069887731, - "0.990000": 1.772733213161236 - } - }, - { - "labels": { - "foo": "bar", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_calls_total_3", - "job": "batch_job" - }, - "docstring": "Total count of RPC calls.", - "metric": { - "type": "counter", - "value": [ - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": 25 - }, - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "foo" - }, - "value": 25 - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_latency_microseconds_3" - }, - "docstring": "RPC latency summary.", - "metric": { - "type": "histogram", - "value": [ - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": { - "0.010000": 15.890724674774395, - "0.050000": 15.890724674774395, - "0.500000": 84.63044031436561, - "0.900000": 160.21100853053224, - "0.990000": 172.49828748957728 - } - }, - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": { - "0.010000": 0.0459814091918713, - "0.050000": 0.0459814091918713, - "0.500000": 0.6120456642749681, - "0.900000": 1.355915069887731, - "0.990000": 1.772733213161236 - } - }, - { - "labels": { - "foo": "bar", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_calls_total_4", - "job": "batch_job" - }, - "docstring": "Total count of RPC calls.", - "metric": { - "type": "counter", - "value": [ - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": 25 - }, - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "foo" - }, - "value": 25 - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_latency_microseconds_4" - }, - "docstring": "RPC latency summary.", - "metric": { - "type": "histogram", - "value": [ - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": { - "0.010000": 15.890724674774395, - "0.050000": 15.890724674774395, - "0.500000": 84.63044031436561, - "0.900000": 160.21100853053224, - "0.990000": 172.49828748957728 - } - }, - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": { - "0.010000": 0.0459814091918713, - "0.050000": 0.0459814091918713, - "0.500000": 0.6120456642749681, - "0.900000": 1.355915069887731, - "0.990000": 1.772733213161236 - } - }, - { - "labels": { - "foo": "bar", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_calls_total_5", - "job": "batch_job" - }, - "docstring": "Total count of RPC calls.", - "metric": { - "type": "counter", - "value": [ - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": 25 - }, - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "foo" - }, - "value": 25 - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_latency_microseconds_5" - }, - "docstring": "RPC latency summary.", - "metric": { - "type": "histogram", - "value": [ - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": { - "0.010000": 15.890724674774395, - "0.050000": 15.890724674774395, - "0.500000": 84.63044031436561, - "0.900000": 160.21100853053224, - "0.990000": 172.49828748957728 - } - }, - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": { - "0.010000": 0.0459814091918713, - "0.050000": 0.0459814091918713, - "0.500000": 0.6120456642749681, - "0.900000": 1.355915069887731, - "0.990000": 1.772733213161236 - } - }, - { - "labels": { - "foo": "bar", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_calls_total_6", - "job": "batch_job" - }, - "docstring": "Total count of RPC calls.", - "metric": { - "type": "counter", - "value": [ - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": 25 - }, - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "foo" - }, - "value": 25 - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_latency_microseconds_6" - }, - "docstring": "RPC latency summary.", - "metric": { - "type": "histogram", - "value": [ - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": { - "0.010000": 15.890724674774395, - "0.050000": 15.890724674774395, - "0.500000": 84.63044031436561, - "0.900000": 160.21100853053224, - "0.990000": 172.49828748957728 - } - }, - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": { - "0.010000": 0.0459814091918713, - "0.050000": 0.0459814091918713, - "0.500000": 0.6120456642749681, - "0.900000": 1.355915069887731, - "0.990000": 1.772733213161236 - } - }, - { - "labels": { - "foo": "bar", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_calls_total_7", - "job": "batch_job" - }, - "docstring": "Total count of RPC calls.", - "metric": { - "type": "counter", - "value": [ - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": 25 - }, - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "foo" - }, - "value": 25 - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_latency_microseconds_7" - }, - "docstring": "RPC latency summary.", - "metric": { - "type": "histogram", - "value": [ - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": { - "0.010000": 15.890724674774395, - "0.050000": 15.890724674774395, - "0.500000": 84.63044031436561, - "0.900000": 160.21100853053224, - "0.990000": 172.49828748957728 - } - }, - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": { - "0.010000": 0.0459814091918713, - "0.050000": 0.0459814091918713, - "0.500000": 0.6120456642749681, - "0.900000": 1.355915069887731, - "0.990000": 1.772733213161236 - } - }, - { - "labels": { - "foo": "bar", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_calls_total_8", - "job": "batch_job" - }, - "docstring": "Total count of RPC calls.", - "metric": { - "type": "counter", - "value": [ - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": 25 - }, - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "foo" - }, - "value": 25 - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_latency_microseconds_8" - }, - "docstring": "RPC latency summary.", - "metric": { - "type": "histogram", - "value": [ - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": { - "0.010000": 15.890724674774395, - "0.050000": 15.890724674774395, - "0.500000": 84.63044031436561, - "0.900000": 160.21100853053224, - "0.990000": 172.49828748957728 - } - }, - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": { - "0.010000": 0.0459814091918713, - "0.050000": 0.0459814091918713, - "0.500000": 0.6120456642749681, - "0.900000": 1.355915069887731, - "0.990000": 1.772733213161236 - } - }, - { - "labels": { - "foo": "bar", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_calls_total_9", - "job": "batch_job" - }, - "docstring": "Total count of RPC calls.", - "metric": { - "type": "counter", - "value": [ - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": 25 - }, - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": 25 - }, - { - "labels": { - "foo": "baz", - "service": "foo" - }, - "value": 25 - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_latency_microseconds_9" - }, - "docstring": "RPC latency summary.", - "metric": { - "type": "histogram", - "value": [ - { - "labels": { - "foo": "bar", - "service": "foo" - }, - "value": { - "0.010000": 15.890724674774395, - "0.050000": 15.890724674774395, - "0.500000": 84.63044031436561, - "0.900000": 160.21100853053224, - "0.990000": 172.49828748957728 - } - }, - { - "labels": { - "foo": "bar", - "service": "zed" - }, - "value": { - "0.010000": 0.0459814091918713, - "0.050000": 0.0459814091918713, - "0.500000": 0.6120456642749681, - "0.900000": 1.355915069887731, - "0.990000": 1.772733213161236 - } - }, - { - "labels": { - "foo": "bar", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - }, - { - "labels": { - "foo": "baz", - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - } - ] - } - } -] diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/fixtures/test0_0_1-0_0_2.json b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/fixtures/test0_0_1-0_0_2.json deleted file mode 100644 index 1ac5be7d7efe..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/fixtures/test0_0_1-0_0_2.json +++ /dev/null @@ -1,79 +0,0 @@ -[ - { - "baseLabels": { - "__name__": "rpc_calls_total", - "job": "batch_job" - }, - "docstring": "RPC calls.", - "metric": { - "type": "counter", - "value": [ - { - "labels": { - "service": "zed" - }, - "value": 25 - }, - { - "labels": { - "service": "bar" - }, - "value": 25 - }, - { - "labels": { - "service": "foo" - }, - "value": 25 - } - ] - } - }, - { - "baseLabels": { - "__name__": "rpc_latency_microseconds" - }, - "docstring": "RPC latency.", - "metric": { - "type": "histogram", - "value": [ - { - "labels": { - "service": "foo" - }, - "value": { - "0.010000": 15.890724674774395, - "0.050000": 15.890724674774395, - "0.500000": 84.63044031436561, - "0.900000": 160.21100853053224, - "0.990000": 172.49828748957728 - } - }, - { - "labels": { - "service": "zed" - }, - "value": { - "0.010000": 0.0459814091918713, - "0.050000": 0.0459814091918713, - "0.500000": 0.6120456642749681, - "0.900000": 1.355915069887731, - "0.990000": 1.772733213161236 - } - }, - { - "labels": { - "service": "bar" - }, - "value": { - "0.010000": 78.48563317257356, - "0.050000": 78.48563317257356, - "0.500000": 97.31798360385088, - "0.900000": 109.89202084295582, - "0.990000": 109.99626121011262 - } - } - ] - } - } -] diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/metricfamilyprocessor.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/metricfamilyprocessor.go deleted file mode 100644 index 5a8f40bbf3c7..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/metricfamilyprocessor.go +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package extraction - -import ( - "fmt" - "io" - "math" - - dto "github.com/prometheus/client_model/go" - - "github.com/matttproud/golang_protobuf_extensions/pbutil" - - "github.com/prometheus/client_golang/model" -) - -type metricFamilyProcessor struct{} - -// MetricFamilyProcessor decodes varint encoded record length-delimited streams -// of io.prometheus.client.MetricFamily. -// -// See http://godoc.org/github.com/matttproud/golang_protobuf_extensions/ext for -// more details. -var MetricFamilyProcessor = &metricFamilyProcessor{} - -func (m *metricFamilyProcessor) ProcessSingle(i io.Reader, out Ingester, o *ProcessOptions) error { - family := &dto.MetricFamily{} - - for { - family.Reset() - - if _, err := pbutil.ReadDelimited(i, family); err != nil { - if err == io.EOF { - return nil - } - return err - } - if err := extractMetricFamily(out, o, family); err != nil { - return err - } - } -} - -func extractMetricFamily(out Ingester, o *ProcessOptions, family *dto.MetricFamily) error { - switch family.GetType() { - case dto.MetricType_COUNTER: - if err := extractCounter(out, o, family); err != nil { - return err - } - case dto.MetricType_GAUGE: - if err := extractGauge(out, o, family); err != nil { - return err - } - case dto.MetricType_SUMMARY: - if err := extractSummary(out, o, family); err != nil { - return err - } - case dto.MetricType_UNTYPED: - if err := extractUntyped(out, o, family); err != nil { - return err - } - case dto.MetricType_HISTOGRAM: - if err := extractHistogram(out, o, family); err != nil { - return err - } - } - return nil -} - -func extractCounter(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error { - samples := make(model.Samples, 0, len(f.Metric)) - - for _, m := range f.Metric { - if m.Counter == nil { - continue - } - - sample := &model.Sample{ - Metric: model.Metric{}, - Value: model.SampleValue(m.Counter.GetValue()), - } - samples = append(samples, sample) - - if m.TimestampMs != nil { - sample.Timestamp = model.TimestampFromUnixNano(*m.TimestampMs * 1000000) - } else { - sample.Timestamp = o.Timestamp - } - - metric := sample.Metric - for _, p := range m.Label { - metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - metric[model.MetricNameLabel] = model.LabelValue(f.GetName()) - } - - return out.Ingest(samples) -} - -func extractGauge(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error { - samples := make(model.Samples, 0, len(f.Metric)) - - for _, m := range f.Metric { - if m.Gauge == nil { - continue - } - - sample := &model.Sample{ - Metric: model.Metric{}, - Value: model.SampleValue(m.Gauge.GetValue()), - } - samples = append(samples, sample) - - if m.TimestampMs != nil { - sample.Timestamp = model.TimestampFromUnixNano(*m.TimestampMs * 1000000) - } else { - sample.Timestamp = o.Timestamp - } - - metric := sample.Metric - for _, p := range m.Label { - metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - metric[model.MetricNameLabel] = model.LabelValue(f.GetName()) - } - - return out.Ingest(samples) -} - -func extractSummary(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error { - samples := make(model.Samples, 0, len(f.Metric)) - - for _, m := range f.Metric { - if m.Summary == nil { - continue - } - - timestamp := o.Timestamp - if m.TimestampMs != nil { - timestamp = model.TimestampFromUnixNano(*m.TimestampMs * 1000000) - } - - for _, q := range m.Summary.Quantile { - sample := &model.Sample{ - Metric: model.Metric{}, - Value: model.SampleValue(q.GetValue()), - Timestamp: timestamp, - } - samples = append(samples, sample) - - metric := sample.Metric - for _, p := range m.Label { - metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - // BUG(matt): Update other names to "quantile". - metric[model.LabelName(model.QuantileLabel)] = model.LabelValue(fmt.Sprint(q.GetQuantile())) - metric[model.MetricNameLabel] = model.LabelValue(f.GetName()) - } - - if m.Summary.SampleSum != nil { - sum := &model.Sample{ - Metric: model.Metric{}, - Value: model.SampleValue(m.Summary.GetSampleSum()), - Timestamp: timestamp, - } - samples = append(samples, sum) - - metric := sum.Metric - for _, p := range m.Label { - metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum") - } - - if m.Summary.SampleCount != nil { - count := &model.Sample{ - Metric: model.Metric{}, - Value: model.SampleValue(m.Summary.GetSampleCount()), - Timestamp: timestamp, - } - samples = append(samples, count) - - metric := count.Metric - for _, p := range m.Label { - metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count") - } - } - - return out.Ingest(samples) -} - -func extractUntyped(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error { - samples := make(model.Samples, 0, len(f.Metric)) - - for _, m := range f.Metric { - if m.Untyped == nil { - continue - } - - sample := &model.Sample{ - Metric: model.Metric{}, - Value: model.SampleValue(m.Untyped.GetValue()), - } - samples = append(samples, sample) - - if m.TimestampMs != nil { - sample.Timestamp = model.TimestampFromUnixNano(*m.TimestampMs * 1000000) - } else { - sample.Timestamp = o.Timestamp - } - - metric := sample.Metric - for _, p := range m.Label { - metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - metric[model.MetricNameLabel] = model.LabelValue(f.GetName()) - } - - return out.Ingest(samples) -} - -func extractHistogram(out Ingester, o *ProcessOptions, f *dto.MetricFamily) error { - samples := make(model.Samples, 0, len(f.Metric)) - - for _, m := range f.Metric { - if m.Histogram == nil { - continue - } - - timestamp := o.Timestamp - if m.TimestampMs != nil { - timestamp = model.TimestampFromUnixNano(*m.TimestampMs * 1000000) - } - - infSeen := false - - for _, q := range m.Histogram.Bucket { - sample := &model.Sample{ - Metric: model.Metric{}, - Value: model.SampleValue(q.GetCumulativeCount()), - Timestamp: timestamp, - } - samples = append(samples, sample) - - metric := sample.Metric - for _, p := range m.Label { - metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - metric[model.LabelName(model.BucketLabel)] = model.LabelValue(fmt.Sprint(q.GetUpperBound())) - metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket") - - if math.IsInf(q.GetUpperBound(), +1) { - infSeen = true - } - } - - if m.Histogram.SampleSum != nil { - sum := &model.Sample{ - Metric: model.Metric{}, - Value: model.SampleValue(m.Histogram.GetSampleSum()), - Timestamp: timestamp, - } - samples = append(samples, sum) - - metric := sum.Metric - for _, p := range m.Label { - metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum") - } - - if m.Histogram.SampleCount != nil { - count := &model.Sample{ - Metric: model.Metric{}, - Value: model.SampleValue(m.Histogram.GetSampleCount()), - Timestamp: timestamp, - } - samples = append(samples, count) - - metric := count.Metric - for _, p := range m.Label { - metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count") - - if !infSeen { - infBucket := &model.Sample{ - Metric: model.Metric{}, - Value: count.Value, - Timestamp: timestamp, - } - samples = append(samples, infBucket) - - metric := infBucket.Metric - for _, p := range m.Label { - metric[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - metric[model.LabelName(model.BucketLabel)] = model.LabelValue("+Inf") - metric[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket") - } - } - } - - return out.Ingest(samples) -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/metricfamilyprocessor_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/metricfamilyprocessor_test.go deleted file mode 100644 index 9ba0fdbce38f..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/metricfamilyprocessor_test.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package extraction - -import ( - "sort" - "strings" - "testing" - - "github.com/prometheus/client_golang/model" -) - -var testTime = model.Now() - -type metricFamilyProcessorScenario struct { - in string - expected, actual []model.Samples -} - -func (s *metricFamilyProcessorScenario) Ingest(samples model.Samples) error { - s.actual = append(s.actual, samples) - return nil -} - -func (s *metricFamilyProcessorScenario) test(t *testing.T, set int) { - i := strings.NewReader(s.in) - - o := &ProcessOptions{ - Timestamp: testTime, - } - - err := MetricFamilyProcessor.ProcessSingle(i, s, o) - if err != nil { - t.Fatalf("%d. got error: %s", set, err) - } - - if len(s.expected) != len(s.actual) { - t.Fatalf("%d. expected length %d, got %d", set, len(s.expected), len(s.actual)) - } - - for i, expected := range s.expected { - sort.Sort(s.actual[i]) - sort.Sort(expected) - - if !expected.Equal(s.actual[i]) { - t.Errorf("%d.%d. expected %s, got %s", set, i, expected, s.actual[i]) - } - } -} - -func TestMetricFamilyProcessor(t *testing.T) { - scenarios := []metricFamilyProcessorScenario{ - { - in: "", - }, - { - in: "\x8f\x01\n\rrequest_count\x12\x12Number of requests\x18\x00\"0\n#\n\x0fsome_label_name\x12\x10some_label_value\x1a\t\t\x00\x00\x00\x00\x00\x00E\xc0\"6\n)\n\x12another_label_name\x12\x13another_label_value\x1a\t\t\x00\x00\x00\x00\x00\x00U@", - expected: []model.Samples{ - model.Samples{ - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_count", "some_label_name": "some_label_value"}, - Value: -42, - Timestamp: testTime, - }, - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_count", "another_label_name": "another_label_value"}, - Value: 84, - Timestamp: testTime, - }, - }, - }, - }, - { - in: "\xb9\x01\n\rrequest_count\x12\x12Number of requests\x18\x02\"O\n#\n\x0fsome_label_name\x12\x10some_label_value\"(\x1a\x12\t\xaeG\xe1z\x14\xae\xef?\x11\x00\x00\x00\x00\x00\x00E\xc0\x1a\x12\t+\x87\x16\xd9\xce\xf7\xef?\x11\x00\x00\x00\x00\x00\x00U\xc0\"A\n)\n\x12another_label_name\x12\x13another_label_value\"\x14\x1a\x12\t\x00\x00\x00\x00\x00\x00\xe0?\x11\x00\x00\x00\x00\x00\x00$@", - expected: []model.Samples{ - model.Samples{ - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_count", "some_label_name": "some_label_value", "quantile": "0.99"}, - Value: -42, - Timestamp: testTime, - }, - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_count", "some_label_name": "some_label_value", "quantile": "0.999"}, - Value: -84, - Timestamp: testTime, - }, - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_count", "another_label_name": "another_label_value", "quantile": "0.5"}, - Value: 10, - Timestamp: testTime, - }, - }, - }, - }, - { - in: "\x8d\x01\n\x1drequest_duration_microseconds\x12\x15The response latency.\x18\x04\"S:Q\b\x85\x15\x11\xcd\xcc\xccL\x8f\xcb:A\x1a\v\b{\x11\x00\x00\x00\x00\x00\x00Y@\x1a\f\b\x9c\x03\x11\x00\x00\x00\x00\x00\x00^@\x1a\f\b\xd0\x04\x11\x00\x00\x00\x00\x00\x00b@\x1a\f\b\xf4\v\x11\x9a\x99\x99\x99\x99\x99e@\x1a\f\b\x85\x15\x11\x00\x00\x00\x00\x00\x00\xf0\u007f", - expected: []model.Samples{ - model.Samples{ - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_duration_microseconds_bucket", "le": "100"}, - Value: 123, - Timestamp: testTime, - }, - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_duration_microseconds_bucket", "le": "120"}, - Value: 412, - Timestamp: testTime, - }, - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_duration_microseconds_bucket", "le": "144"}, - Value: 592, - Timestamp: testTime, - }, - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_duration_microseconds_bucket", "le": "172.8"}, - Value: 1524, - Timestamp: testTime, - }, - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_duration_microseconds_bucket", "le": "+Inf"}, - Value: 2693, - Timestamp: testTime, - }, - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_duration_microseconds_sum"}, - Value: 1756047.3, - Timestamp: testTime, - }, - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "request_duration_microseconds_count"}, - Value: 2693, - Timestamp: testTime, - }, - }, - }, - }, - } - - for i, scenario := range scenarios { - scenario.test(t, i) - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor.go deleted file mode 100644 index 50c93c9e689a..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package extraction - -import ( - "io" - "time" - - "github.com/prometheus/client_golang/model" -) - -// ProcessOptions dictates how the interpreted stream should be rendered for -// consumption. -type ProcessOptions struct { - // Timestamp is added to each value from the stream that has no explicit - // timestamp set. - Timestamp model.Timestamp -} - -// Ingester consumes result streams in whatever way is desired by the user. -type Ingester interface { - Ingest(model.Samples) error -} - -// Processor is responsible for decoding the actual message responses from -// stream into a format that can be consumed with the end result written -// to the results channel. -type Processor interface { - // ProcessSingle treats the input as a single self-contained message body and - // transforms it accordingly. It has no support for streaming. - ProcessSingle(in io.Reader, out Ingester, o *ProcessOptions) error -} - -// Helper function to convert map[string]string into LabelSet. -// -// NOTE: This should be deleted when support for go 1.0.3 is removed; 1.1 is -// smart enough to unmarshal JSON objects into LabelSet directly. -func labelSet(labels map[string]string) model.LabelSet { - labelset := make(model.LabelSet, len(labels)) - - for k, v := range labels { - labelset[model.LabelName(k)] = model.LabelValue(v) - } - - return labelset -} - -// A basic interface only useful in testing contexts for dispensing the time -// in a controlled manner. -type instantProvider interface { - // The current instant. - Now() time.Time -} - -// Clock is a simple means for fluently wrapping around standard Go timekeeping -// mechanisms to enhance testability without compromising code readability. -// -// It is sufficient for use on bare initialization. A provider should be -// set only for test contexts. When not provided, it emits the current -// system time. -type clock struct { - // The underlying means through which time is provided, if supplied. - Provider instantProvider -} - -// Emit the current instant. -func (t *clock) Now() time.Time { - if t.Provider == nil { - return time.Now() - } - - return t.Provider.Now() -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_1.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_1.go deleted file mode 100644 index 7a728efb0e20..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_1.go +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package extraction - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - - "github.com/prometheus/client_golang/model" -) - -const ( - baseLabels001 = "baseLabels" - counter001 = "counter" - docstring001 = "docstring" - gauge001 = "gauge" - histogram001 = "histogram" - labels001 = "labels" - metric001 = "metric" - type001 = "type" - value001 = "value" - percentile001 = "percentile" -) - -// Processor001 is responsible for decoding payloads from protocol version -// 0.0.1. -var Processor001 = &processor001{} - -// processor001 is responsible for handling API version 0.0.1. -type processor001 struct{} - -// entity001 represents a the JSON structure that 0.0.1 uses. -type entity001 []struct { - BaseLabels map[string]string `json:"baseLabels"` - Docstring string `json:"docstring"` - Metric struct { - MetricType string `json:"type"` - Value []struct { - Labels map[string]string `json:"labels"` - Value interface{} `json:"value"` - } `json:"value"` - } `json:"metric"` -} - -func (p *processor001) ProcessSingle(in io.Reader, out Ingester, o *ProcessOptions) error { - // TODO(matt): Replace with plain-jane JSON unmarshalling. - buffer, err := ioutil.ReadAll(in) - if err != nil { - return err - } - - entities := entity001{} - if err = json.Unmarshal(buffer, &entities); err != nil { - return err - } - - // TODO(matt): This outer loop is a great basis for parallelization. - pendingSamples := model.Samples{} - for _, entity := range entities { - for _, value := range entity.Metric.Value { - labels := labelSet(entity.BaseLabels).Merge(labelSet(value.Labels)) - - switch entity.Metric.MetricType { - case gauge001, counter001: - sampleValue, ok := value.Value.(float64) - if !ok { - return fmt.Errorf("could not convert value from %s %s to float64", entity, value) - } - - pendingSamples = append(pendingSamples, &model.Sample{ - Metric: model.Metric(labels), - Timestamp: o.Timestamp, - Value: model.SampleValue(sampleValue), - }) - - break - - case histogram001: - sampleValue, ok := value.Value.(map[string]interface{}) - if !ok { - return fmt.Errorf("could not convert value from %q to a map[string]interface{}", value.Value) - } - - for percentile, percentileValue := range sampleValue { - individualValue, ok := percentileValue.(float64) - if !ok { - return fmt.Errorf("could not convert value from %q to a float64", percentileValue) - } - - childMetric := make(map[model.LabelName]model.LabelValue, len(labels)+1) - - for k, v := range labels { - childMetric[k] = v - } - - childMetric[model.LabelName(percentile001)] = model.LabelValue(percentile) - - pendingSamples = append(pendingSamples, &model.Sample{ - Metric: model.Metric(childMetric), - Timestamp: o.Timestamp, - Value: model.SampleValue(individualValue), - }) - } - - break - } - } - } - if len(pendingSamples) > 0 { - return out.Ingest(pendingSamples) - } - - return nil -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_1_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_1_test.go deleted file mode 100644 index b970b03e97f2..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_1_test.go +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package extraction - -import ( - "errors" - "os" - "path" - "sort" - "testing" - - "github.com/prometheus/client_golang/model" -) - -var test001Time = model.Now() - -type testProcessor001ProcessScenario struct { - in string - expected, actual []model.Samples - err error -} - -func (s *testProcessor001ProcessScenario) Ingest(samples model.Samples) error { - s.actual = append(s.actual, samples) - return nil -} - -func (s *testProcessor001ProcessScenario) test(t testing.TB, set int) { - reader, err := os.Open(path.Join("fixtures", s.in)) - if err != nil { - t.Fatalf("%d. couldn't open scenario input file %s: %s", set, s.in, err) - } - - options := &ProcessOptions{ - Timestamp: test001Time, - } - err = Processor001.ProcessSingle(reader, s, options) - if s.err != err && (s.err == nil || err == nil || err.Error() != s.err.Error()) { - t.Fatalf("%d. expected err of %s, got %s", set, s.err, err) - } - - if len(s.actual) != len(s.expected) { - t.Fatalf("%d. expected output length of %d, got %d", set, len(s.expected), len(s.actual)) - } - - for i, expected := range s.expected { - sort.Sort(s.actual[i]) - sort.Sort(expected) - - if !expected.Equal(s.actual[i]) { - t.Errorf("%d.%d. expected %s, got %s", set, i, expected, s.actual[i]) - } - } -} - -func testProcessor001Process(t testing.TB) { - var scenarios = []testProcessor001ProcessScenario{ - { - in: "empty.json", - err: errors.New("unexpected end of JSON input"), - }, - { - in: "test0_0_1-0_0_2.json", - expected: []model.Samples{ - model.Samples{ - &model.Sample{ - Metric: model.Metric{"service": "zed", model.MetricNameLabel: "rpc_calls_total", "job": "batch_job"}, - Value: 25, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"service": "bar", model.MetricNameLabel: "rpc_calls_total", "job": "batch_job"}, - Value: 25, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"service": "foo", model.MetricNameLabel: "rpc_calls_total", "job": "batch_job"}, - Value: 25, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.010000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "zed"}, - Value: 0.0459814091918713, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.010000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "bar"}, - Value: 78.48563317257356, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.010000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "foo"}, - Value: 15.890724674774395, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.050000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "zed"}, - Value: 0.0459814091918713, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.050000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "bar"}, - Value: 78.48563317257356, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.050000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "foo"}, - Value: 15.890724674774395, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.500000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "zed"}, - Value: 0.6120456642749681, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.500000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "bar"}, - Value: 97.31798360385088, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.500000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "foo"}, - Value: 84.63044031436561, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.900000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "zed"}, - Value: 1.355915069887731, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.900000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "bar"}, - Value: 109.89202084295582, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.900000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "foo"}, - Value: 160.21100853053224, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.990000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "zed"}, - Value: 1.772733213161236, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.990000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "bar"}, - Value: 109.99626121011262, - Timestamp: test001Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.990000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "foo"}, - Value: 172.49828748957728, - Timestamp: test001Time, - }, - }, - }, - }, - } - - for i, scenario := range scenarios { - scenario.test(t, i) - } -} - -func TestProcessor001Process(t *testing.T) { - testProcessor001Process(t) -} - -func BenchmarkProcessor001Process(b *testing.B) { - for i := 0; i < b.N; i++ { - testProcessor001Process(b) - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_2.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_2.go deleted file mode 100644 index 24c7e81554c6..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_2.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package extraction - -import ( - "encoding/json" - "fmt" - "io" - - "github.com/prometheus/client_golang/model" -) - -// Processor002 is responsible for decoding payloads from protocol version -// 0.0.2. -var Processor002 = &processor002{} - -type histogram002 struct { - Labels map[string]string `json:"labels"` - Values map[string]model.SampleValue `json:"value"` -} - -type counter002 struct { - Labels map[string]string `json:"labels"` - Value model.SampleValue `json:"value"` -} - -type processor002 struct{} - -func (p *processor002) ProcessSingle(in io.Reader, out Ingester, o *ProcessOptions) error { - // Processor for telemetry schema version 0.0.2. - // container for telemetry data - var entities []struct { - BaseLabels map[string]string `json:"baseLabels"` - Docstring string `json:"docstring"` - Metric struct { - Type string `json:"type"` - Values json.RawMessage `json:"value"` - } `json:"metric"` - } - - if err := json.NewDecoder(in).Decode(&entities); err != nil { - return err - } - - pendingSamples := model.Samples{} - for _, entity := range entities { - switch entity.Metric.Type { - case "counter", "gauge": - var values []counter002 - - if err := json.Unmarshal(entity.Metric.Values, &values); err != nil { - return fmt.Errorf("could not extract %s value: %s", entity.Metric.Type, err) - } - - for _, counter := range values { - labels := labelSet(entity.BaseLabels).Merge(labelSet(counter.Labels)) - - pendingSamples = append(pendingSamples, &model.Sample{ - Metric: model.Metric(labels), - Timestamp: o.Timestamp, - Value: counter.Value, - }) - } - - case "histogram": - var values []histogram002 - - if err := json.Unmarshal(entity.Metric.Values, &values); err != nil { - return fmt.Errorf("could not extract %s value: %s", entity.Metric.Type, err) - } - - for _, histogram := range values { - for percentile, value := range histogram.Values { - labels := labelSet(entity.BaseLabels).Merge(labelSet(histogram.Labels)) - labels[model.LabelName("percentile")] = model.LabelValue(percentile) - - pendingSamples = append(pendingSamples, &model.Sample{ - Metric: model.Metric(labels), - Timestamp: o.Timestamp, - Value: value, - }) - } - } - - default: - return fmt.Errorf("unknown metric type %q", entity.Metric.Type) - } - } - - if len(pendingSamples) > 0 { - return out.Ingest(pendingSamples) - } - - return nil -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_2_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_2_test.go deleted file mode 100644 index b2b758702083..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/processor0_0_2_test.go +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package extraction - -import ( - "bytes" - "errors" - "io/ioutil" - "os" - "path" - "runtime" - "sort" - "testing" - - "github.com/prometheus/client_golang/model" -) - -var test002Time = model.Now() - -type testProcessor002ProcessScenario struct { - in string - expected, actual []model.Samples - err error -} - -func (s *testProcessor002ProcessScenario) Ingest(samples model.Samples) error { - s.actual = append(s.actual, samples) - return nil -} - -func (s *testProcessor002ProcessScenario) test(t testing.TB, set int) { - reader, err := os.Open(path.Join("fixtures", s.in)) - if err != nil { - t.Fatalf("%d. couldn't open scenario input file %s: %s", set, s.in, err) - } - - options := &ProcessOptions{ - Timestamp: test002Time, - } - err = Processor002.ProcessSingle(reader, s, options) - if s.err != err && (s.err == nil || err == nil || err.Error() != s.err.Error()) { - t.Fatalf("%d. expected err of %s, got %s", set, s.err, err) - } - - if len(s.actual) != len(s.expected) { - t.Fatalf("%d. expected output length of %d, got %d", set, len(s.expected), len(s.actual)) - } - - for i, expected := range s.expected { - sort.Sort(s.actual[i]) - sort.Sort(expected) - - if !expected.Equal(s.actual[i]) { - t.Fatalf("%d.%d. expected %s, got %s", set, i, expected, s.actual[i]) - } - } -} - -func testProcessor002Process(t testing.TB) { - var scenarios = []testProcessor002ProcessScenario{ - { - in: "empty.json", - err: errors.New("EOF"), - }, - { - in: "test0_0_1-0_0_2.json", - expected: []model.Samples{ - model.Samples{ - &model.Sample{ - Metric: model.Metric{"service": "zed", model.MetricNameLabel: "rpc_calls_total", "job": "batch_job"}, - Value: 25, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"service": "bar", model.MetricNameLabel: "rpc_calls_total", "job": "batch_job"}, - Value: 25, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"service": "foo", model.MetricNameLabel: "rpc_calls_total", "job": "batch_job"}, - Value: 25, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.010000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "zed"}, - Value: 0.0459814091918713, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.010000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "bar"}, - Value: 78.48563317257356, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.010000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "foo"}, - Value: 15.890724674774395, - Timestamp: test002Time, - }, - &model.Sample{ - - Metric: model.Metric{"percentile": "0.050000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "zed"}, - Value: 0.0459814091918713, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.050000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "bar"}, - Value: 78.48563317257356, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.050000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "foo"}, - Value: 15.890724674774395, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.500000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "zed"}, - Value: 0.6120456642749681, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.500000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "bar"}, - Value: 97.31798360385088, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.500000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "foo"}, - Value: 84.63044031436561, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.900000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "zed"}, - Value: 1.355915069887731, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.900000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "bar"}, - Value: 109.89202084295582, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.900000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "foo"}, - Value: 160.21100853053224, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.990000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "zed"}, - Value: 1.772733213161236, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.990000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "bar"}, - Value: 109.99626121011262, - Timestamp: test002Time, - }, - &model.Sample{ - Metric: model.Metric{"percentile": "0.990000", model.MetricNameLabel: "rpc_latency_microseconds", "service": "foo"}, - Value: 172.49828748957728, - Timestamp: test002Time, - }, - }, - }, - }, - } - - for i, scenario := range scenarios { - scenario.test(t, i) - } -} - -func TestProcessor002Process(t *testing.T) { - testProcessor002Process(t) -} - -func BenchmarkProcessor002Process(b *testing.B) { - b.StopTimer() - - pre := runtime.MemStats{} - runtime.ReadMemStats(&pre) - - b.StartTimer() - - for i := 0; i < b.N; i++ { - testProcessor002Process(b) - } - - post := runtime.MemStats{} - runtime.ReadMemStats(&post) - - allocated := post.TotalAlloc - pre.TotalAlloc - - b.Logf("Allocated %d at %f per cycle with %d cycles.", allocated, float64(allocated)/float64(b.N), b.N) -} - -func BenchmarkProcessor002ParseOnly(b *testing.B) { - b.StopTimer() - data, err := ioutil.ReadFile("fixtures/test0_0_1-0_0_2-large.json") - if err != nil { - b.Fatal(err) - } - ing := fakeIngester{} - b.StartTimer() - - for i := 0; i < b.N; i++ { - if err := Processor002.ProcessSingle(bytes.NewReader(data), ing, &ProcessOptions{}); err != nil { - b.Fatal(err) - } - } -} - -type fakeIngester struct{} - -func (i fakeIngester) Ingest(model.Samples) error { - return nil -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/textprocessor.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/textprocessor.go deleted file mode 100644 index 2eca1c63a60b..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/textprocessor.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package extraction - -import ( - "io" - - "github.com/prometheus/client_golang/text" -) - -type processor004 struct{} - -// Processor004 s responsible for decoding payloads from the text based variety -// of protocol version 0.0.4. -var Processor004 = &processor004{} - -func (t *processor004) ProcessSingle(i io.Reader, out Ingester, o *ProcessOptions) error { - var parser text.Parser - metricFamilies, err := parser.TextToMetricFamilies(i) - if err != nil { - return err - } - for _, metricFamily := range metricFamilies { - if err := extractMetricFamily(out, o, metricFamily); err != nil { - return err - } - } - return nil -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/textprocessor_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/textprocessor_test.go deleted file mode 100644 index ff704a9bc3a8..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/extraction/textprocessor_test.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package extraction - -import ( - "sort" - "strings" - "testing" - - "github.com/prometheus/client_golang/model" -) - -var ( - ts = model.Now() - in = ` -# Only a quite simple scenario with two metric families. -# More complicated tests of the parser itself can be found in the text package. -# TYPE mf2 counter -mf2 3 -mf1{label="value1"} -3.14 123456 -mf1{label="value2"} 42 -mf2 4 -` - out = map[model.LabelValue]model.Samples{ - "mf1": model.Samples{ - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "mf1", "label": "value1"}, - Value: -3.14, - Timestamp: 123456, - }, - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "mf1", "label": "value2"}, - Value: 42, - Timestamp: ts, - }, - }, - "mf2": model.Samples{ - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "mf2"}, - Value: 3, - Timestamp: ts, - }, - &model.Sample{ - Metric: model.Metric{model.MetricNameLabel: "mf2"}, - Value: 4, - Timestamp: ts, - }, - }, - } -) - -type testIngester struct { - results []model.Samples -} - -func (i *testIngester) Ingest(s model.Samples) error { - i.results = append(i.results, s) - return nil -} - -func TestTextProcessor(t *testing.T) { - var ingester testIngester - i := strings.NewReader(in) - o := &ProcessOptions{ - Timestamp: ts, - } - - err := Processor004.ProcessSingle(i, &ingester, o) - if err != nil { - t.Fatal(err) - } - if expected, got := len(out), len(ingester.results); expected != got { - t.Fatalf("Expected length %d, got %d", expected, got) - } - for _, r := range ingester.results { - expected, ok := out[r[0].Metric[model.MetricNameLabel]] - if !ok { - t.Fatalf( - "Unexpected metric name %q", - r[0].Metric[model.MetricNameLabel], - ) - } - sort.Sort(expected) - sort.Sort(r) - if !expected.Equal(r) { - t.Errorf("expected %s, got %s", expected, r) - } - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/fingerprinting.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/fingerprinting.go deleted file mode 100644 index 5b2ffe3bb355..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/fingerprinting.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "fmt" - "strconv" -) - -// Fingerprint provides a hash-capable representation of a Metric. -// For our purposes, FNV-1A 64-bit is used. -type Fingerprint uint64 - -func (f Fingerprint) String() string { - return fmt.Sprintf("%016x", uint64(f)) -} - -// Less implements sort.Interface. -func (f Fingerprint) Less(o Fingerprint) bool { - return f < o -} - -// Equal implements sort.Interface. -func (f Fingerprint) Equal(o Fingerprint) bool { - return f == o -} - -// LoadFromString transforms a string representation into a Fingerprint. -func (f *Fingerprint) LoadFromString(s string) error { - num, err := strconv.ParseUint(s, 16, 64) - if err != nil { - return err - } - *f = Fingerprint(num) - return nil -} - -// Fingerprints represents a collection of Fingerprint subject to a given -// natural sorting scheme. It implements sort.Interface. -type Fingerprints []Fingerprint - -// Len implements sort.Interface. -func (f Fingerprints) Len() int { - return len(f) -} - -// Less implements sort.Interface. -func (f Fingerprints) Less(i, j int) bool { - return f[i] < f[j] -} - -// Swap implements sort.Interface. -func (f Fingerprints) Swap(i, j int) { - f[i], f[j] = f[j], f[i] -} - -// FingerprintSet is a set of Fingerprints. -type FingerprintSet map[Fingerprint]struct{} - -// Equal returns true if both sets contain the same elements (and not more). -func (s FingerprintSet) Equal(o FingerprintSet) bool { - if len(s) != len(o) { - return false - } - - for k := range s { - if _, ok := o[k]; !ok { - return false - } - } - - return true -} - -// Intersection returns the elements contained in both sets. -func (s FingerprintSet) Intersection(o FingerprintSet) FingerprintSet { - myLength, otherLength := len(s), len(o) - if myLength == 0 || otherLength == 0 { - return FingerprintSet{} - } - - subSet := s - superSet := o - - if otherLength < myLength { - subSet = o - superSet = s - } - - out := FingerprintSet{} - - for k := range subSet { - if _, ok := superSet[k]; ok { - out[k] = struct{}{} - } - } - - return out -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname.go deleted file mode 100644 index 75b2e79dae0d..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "strings" -) - -const ( - // ExporterLabelPrefix is the label name prefix to prepend if a - // synthetic label is already present in the exported metrics. - ExporterLabelPrefix LabelName = "exporter_" - - // MetricNameLabel is the label name indicating the metric name of a - // timeseries. - MetricNameLabel LabelName = "__name__" - - // ReservedLabelPrefix is a prefix which is not legal in user-supplied - // label names. - ReservedLabelPrefix = "__" - - // JobLabel is the label name indicating the job from which a timeseries - // was scraped. - JobLabel LabelName = "job" - - // BucketLabel is used for the label that defines the upper bound of a - // bucket of a histogram ("le" -> "less or equal"). - BucketLabel = "le" - - // QuantileLabel is used for the label that defines the quantile in a - // summary. - QuantileLabel = "quantile" -) - -// A LabelName is a key for a LabelSet or Metric. It has a value associated -// therewith. -type LabelName string - -// LabelNames is a sortable LabelName slice. In implements sort.Interface. -type LabelNames []LabelName - -func (l LabelNames) Len() int { - return len(l) -} - -func (l LabelNames) Less(i, j int) bool { - return l[i] < l[j] -} - -func (l LabelNames) Swap(i, j int) { - l[i], l[j] = l[j], l[i] -} - -func (l LabelNames) String() string { - labelStrings := make([]string, 0, len(l)) - for _, label := range l { - labelStrings = append(labelStrings, string(label)) - } - return strings.Join(labelStrings, ", ") -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname_test.go deleted file mode 100644 index 693228d347c9..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname_test.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "sort" - "testing" -) - -func testLabelNames(t testing.TB) { - var scenarios = []struct { - in LabelNames - out LabelNames - }{ - { - in: LabelNames{"ZZZ", "zzz"}, - out: LabelNames{"ZZZ", "zzz"}, - }, - { - in: LabelNames{"aaa", "AAA"}, - out: LabelNames{"AAA", "aaa"}, - }, - } - - for i, scenario := range scenarios { - sort.Sort(scenario.in) - - for j, expected := range scenario.out { - if expected != scenario.in[j] { - t.Errorf("%d.%d expected %s, got %s", i, j, expected, scenario.in[j]) - } - } - } -} - -func TestLabelNames(t *testing.T) { - testLabelNames(t) -} - -func BenchmarkLabelNames(b *testing.B) { - for i := 0; i < b.N; i++ { - testLabelNames(b) - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelset.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelset.go deleted file mode 100644 index b1b54fba35f3..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelset.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "fmt" - "sort" - "strings" -) - -// A LabelSet is a collection of LabelName and LabelValue pairs. The LabelSet -// may be fully-qualified down to the point where it may resolve to a single -// Metric in the data store or not. All operations that occur within the realm -// of a LabelSet can emit a vector of Metric entities to which the LabelSet may -// match. -type LabelSet map[LabelName]LabelValue - -// Merge is a helper function to non-destructively merge two label sets. -func (l LabelSet) Merge(other LabelSet) LabelSet { - result := make(LabelSet, len(l)) - - for k, v := range l { - result[k] = v - } - - for k, v := range other { - result[k] = v - } - - return result -} - -func (l LabelSet) String() string { - labelStrings := make([]string, 0, len(l)) - for label, value := range l { - labelStrings = append(labelStrings, fmt.Sprintf("%s=%q", label, value)) - } - - switch len(labelStrings) { - case 0: - return "" - default: - sort.Strings(labelStrings) - return fmt.Sprintf("{%s}", strings.Join(labelStrings, ", ")) - } -} - -// MergeFromMetric merges Metric into this LabelSet. -func (l LabelSet) MergeFromMetric(m Metric) { - for k, v := range m { - l[k] = v - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue.go deleted file mode 100644 index df2d14cc122c..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "sort" -) - -// A LabelValue is an associated value for a LabelName. -type LabelValue string - -// LabelValues is a sortable LabelValue slice. It implements sort.Interface. -type LabelValues []LabelValue - -func (l LabelValues) Len() int { - return len(l) -} - -func (l LabelValues) Less(i, j int) bool { - return sort.StringsAreSorted([]string{string(l[i]), string(l[j])}) -} - -func (l LabelValues) Swap(i, j int) { - l[i], l[j] = l[j], l[i] -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue_test.go deleted file mode 100644 index 15904edf4f1c..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue_test.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "sort" - "testing" -) - -func testLabelValues(t testing.TB) { - var scenarios = []struct { - in LabelValues - out LabelValues - }{ - { - in: LabelValues{"ZZZ", "zzz"}, - out: LabelValues{"ZZZ", "zzz"}, - }, - { - in: LabelValues{"aaa", "AAA"}, - out: LabelValues{"AAA", "aaa"}, - }, - } - - for i, scenario := range scenarios { - sort.Sort(scenario.in) - - for j, expected := range scenario.out { - if expected != scenario.in[j] { - t.Errorf("%d.%d expected %s, got %s", i, j, expected, scenario.in[j]) - } - } - } -} - -func TestLabelValues(t *testing.T) { - testLabelValues(t) -} - -func BenchmarkLabelValues(b *testing.B) { - for i := 0; i < b.N; i++ { - testLabelValues(b) - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric.go deleted file mode 100644 index 32f9d7fbca74..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric.go +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "encoding/json" - "fmt" - "sort" - "strings" -) - -var separator = []byte{0} - -// A Metric is similar to a LabelSet, but the key difference is that a Metric is -// a singleton and refers to one and only one stream of samples. -type Metric map[LabelName]LabelValue - -// Equal compares the fingerprints of both metrics. -func (m Metric) Equal(o Metric) bool { - return m.Fingerprint().Equal(o.Fingerprint()) -} - -// Before compares the fingerprints of both metrics. -func (m Metric) Before(o Metric) bool { - return m.Fingerprint().Less(o.Fingerprint()) -} - -// String implements Stringer. -func (m Metric) String() string { - metricName, hasName := m[MetricNameLabel] - numLabels := len(m) - 1 - if !hasName { - numLabels = len(m) - } - labelStrings := make([]string, 0, numLabels) - for label, value := range m { - if label != MetricNameLabel { - labelStrings = append(labelStrings, fmt.Sprintf("%s=%q", label, value)) - } - } - - switch numLabels { - case 0: - if hasName { - return string(metricName) - } - return "{}" - default: - sort.Strings(labelStrings) - return fmt.Sprintf("%s{%s}", metricName, strings.Join(labelStrings, ", ")) - } -} - -// Fingerprint returns a Metric's Fingerprint. -func (m Metric) Fingerprint() Fingerprint { - return metricToFingerprint(m) -} - -// Clone returns a copy of the Metric. -func (m Metric) Clone() Metric { - clone := Metric{} - for k, v := range m { - clone[k] = v - } - return clone -} - -// MergeFromLabelSet merges a label set into this Metric, prefixing a collision -// prefix to the label names merged from the label set where required. -func (m Metric) MergeFromLabelSet(labels LabelSet, collisionPrefix LabelName) { - for k, v := range labels { - if collisionPrefix != "" { - for { - if _, exists := m[k]; !exists { - break - } - k = collisionPrefix + k - } - } - - m[k] = v - } -} - -// COWMetric wraps a Metric to enable copy-on-write access patterns. -type COWMetric struct { - Copied bool - Metric Metric -} - -// Set sets a label name in the wrapped Metric to a given value and copies the -// Metric initially, if it is not already a copy. -func (m *COWMetric) Set(ln LabelName, lv LabelValue) { - m.doCOW() - m.Metric[ln] = lv -} - -// Delete deletes a given label name from the wrapped Metric and copies the -// Metric initially, if it is not already a copy. -func (m *COWMetric) Delete(ln LabelName) { - m.doCOW() - delete(m.Metric, ln) -} - -// doCOW copies the underlying Metric if it is not already a copy. -func (m *COWMetric) doCOW() { - if !m.Copied { - m.Metric = m.Metric.Clone() - m.Copied = true - } -} - -// String implements fmt.Stringer. -func (m COWMetric) String() string { - return m.Metric.String() -} - -// MarshalJSON implements json.Marshaler. -func (m COWMetric) MarshalJSON() ([]byte, error) { - return json.Marshal(m.Metric) -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric_test.go deleted file mode 100644 index d51b1842f6ab..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric_test.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import "testing" - -func testMetric(t testing.TB) { - var scenarios = []struct { - input Metric - fingerprint Fingerprint - }{ - { - input: Metric{}, - fingerprint: 14695981039346656037, - }, - { - input: Metric{ - "first_name": "electro", - "occupation": "robot", - "manufacturer": "westinghouse", - }, - fingerprint: 11310079640881077873, - }, - { - input: Metric{ - "x": "y", - }, - fingerprint: 13948396922932177635, - }, - { - input: Metric{ - "a": "bb", - "b": "c", - }, - fingerprint: 3198632812309449502, - }, - { - input: Metric{ - "a": "b", - "bb": "c", - }, - fingerprint: 5774953389407657638, - }, - } - - for i, scenario := range scenarios { - if scenario.fingerprint != scenario.input.Fingerprint() { - t.Errorf("%d. expected %d, got %d", i, scenario.fingerprint, scenario.input.Fingerprint()) - } - } -} - -func TestMetric(t *testing.T) { - testMetric(t) -} - -func BenchmarkMetric(b *testing.B) { - for i := 0; i < b.N; i++ { - testMetric(b) - } -} - -func TestCOWMetric(t *testing.T) { - testMetric := Metric{ - "to_delete": "test1", - "to_change": "test2", - } - - scenarios := []struct { - fn func(*COWMetric) - out Metric - }{ - { - fn: func(cm *COWMetric) { - cm.Delete("to_delete") - }, - out: Metric{ - "to_change": "test2", - }, - }, - { - fn: func(cm *COWMetric) { - cm.Set("to_change", "changed") - }, - out: Metric{ - "to_delete": "test1", - "to_change": "changed", - }, - }, - } - - for i, s := range scenarios { - orig := testMetric.Clone() - cm := &COWMetric{ - Metric: orig, - } - - s.fn(cm) - - // Test that the original metric was not modified. - if !orig.Equal(testMetric) { - t.Fatalf("%d. original metric changed; expected %v, got %v", i, testMetric, orig) - } - - // Test that the new metric has the right changes. - if !cm.Metric.Equal(s.out) { - t.Fatalf("%d. copied metric doesn't contain expected changes; expected %v, got %v", i, s.out, cm.Metric) - } - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/model.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/model.go deleted file mode 100644 index 189c5dcf6c16..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/model.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package model contains core representation of Prometheus client primitives. -package model diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample.go deleted file mode 100644 index c13a44d95c9c..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -// Sample is a sample value with a timestamp and a metric. -type Sample struct { - Metric Metric - Value SampleValue - Timestamp Timestamp -} - -// Equal compares first the metrics, then the timestamp, then the value. -func (s *Sample) Equal(o *Sample) bool { - if s == o { - return true - } - - if !s.Metric.Equal(o.Metric) { - return false - } - if !s.Timestamp.Equal(o.Timestamp) { - return false - } - if !s.Value.Equal(o.Value) { - return false - } - - return true -} - -// Samples is a sortable Sample slice. It implements sort.Interface. -type Samples []*Sample - -func (s Samples) Len() int { - return len(s) -} - -// Less compares first the metrics, then the timestamp. -func (s Samples) Less(i, j int) bool { - switch { - case s[i].Metric.Before(s[j].Metric): - return true - case s[j].Metric.Before(s[i].Metric): - return false - case s[i].Timestamp.Before(s[j].Timestamp): - return true - default: - return false - } -} - -func (s Samples) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -// Equal compares two sets of samples and returns true if they are equal. -func (s Samples) Equal(o Samples) bool { - if len(s) != len(o) { - return false - } - - for i, sample := range s { - if !sample.Equal(o[i]) { - return false - } - } - return true -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample_test.go deleted file mode 100644 index 3dc4ad2511a4..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample_test.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "sort" - "testing" -) - -func TestSamplesSort(t *testing.T) { - input := Samples{ - &Sample{ - // Fingerprint: 81f9c9ed24563f8f. - Metric: Metric{ - MetricNameLabel: "A", - }, - Timestamp: 1, - }, - &Sample{ - // Fingerprint: 81f9c9ed24563f8f. - Metric: Metric{ - MetricNameLabel: "A", - }, - Timestamp: 2, - }, - &Sample{ - // Fingerprint: 1bf6c9ed24543f8f. - Metric: Metric{ - MetricNameLabel: "C", - }, - Timestamp: 1, - }, - &Sample{ - // Fingerprint: 1bf6c9ed24543f8f. - Metric: Metric{ - MetricNameLabel: "C", - }, - Timestamp: 2, - }, - &Sample{ - // Fingerprint: 68f4c9ed24533f8f. - Metric: Metric{ - MetricNameLabel: "B", - }, - Timestamp: 1, - }, - &Sample{ - // Fingerprint: 68f4c9ed24533f8f. - Metric: Metric{ - MetricNameLabel: "B", - }, - Timestamp: 2, - }, - } - - expected := Samples{ - &Sample{ - // Fingerprint: 1bf6c9ed24543f8f. - Metric: Metric{ - MetricNameLabel: "C", - }, - Timestamp: 1, - }, - &Sample{ - // Fingerprint: 1bf6c9ed24543f8f. - Metric: Metric{ - MetricNameLabel: "C", - }, - Timestamp: 2, - }, - &Sample{ - // Fingerprint: 68f4c9ed24533f8f. - Metric: Metric{ - MetricNameLabel: "B", - }, - Timestamp: 1, - }, - &Sample{ - // Fingerprint: 68f4c9ed24533f8f. - Metric: Metric{ - MetricNameLabel: "B", - }, - Timestamp: 2, - }, - &Sample{ - // Fingerprint: 81f9c9ed24563f8f. - Metric: Metric{ - MetricNameLabel: "A", - }, - Timestamp: 1, - }, - &Sample{ - // Fingerprint: 81f9c9ed24563f8f. - Metric: Metric{ - MetricNameLabel: "A", - }, - Timestamp: 2, - }, - } - - sort.Sort(input) - - for i, actual := range input { - actualFp := actual.Metric.Fingerprint() - expectedFp := expected[i].Metric.Fingerprint() - - if !actualFp.Equal(expectedFp) { - t.Fatalf("%d. Incorrect fingerprint. Got %s; want %s", i, actualFp.String(), expectedFp.String()) - } - - if actual.Timestamp != expected[i].Timestamp { - t.Fatalf("%d. Incorrect timestamp. Got %s; want %s", i, actual.Timestamp, expected[i].Timestamp) - } - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/samplevalue.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/samplevalue.go deleted file mode 100644 index 469c2c0b0e5f..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/samplevalue.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "fmt" - "strconv" -) - -// A SampleValue is a representation of a value for a given sample at a given -// time. -type SampleValue float64 - -// Equal does a straight v==o. -func (v SampleValue) Equal(o SampleValue) bool { - return v == o -} - -// MarshalJSON implements json.Marshaler. -func (v SampleValue) MarshalJSON() ([]byte, error) { - return []byte(fmt.Sprintf(`"%s"`, v)), nil -} - -func (v SampleValue) String() string { - return strconv.FormatFloat(float64(v), 'f', -1, 64) -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature.go deleted file mode 100644 index cc77b192dd1c..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "bytes" - "hash" - "hash/fnv" - "sync" -) - -// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is -// used to separate label names, label values, and other strings from each other -// when calculating their combined hash value (aka signature aka fingerprint). -const SeparatorByte byte = 255 - -var ( - // cache the signature of an empty label set. - emptyLabelSignature = fnv.New64a().Sum64() - - hashAndBufPool sync.Pool -) - -type hashAndBuf struct { - h hash.Hash64 - b bytes.Buffer -} - -func getHashAndBuf() *hashAndBuf { - hb := hashAndBufPool.Get() - if hb == nil { - return &hashAndBuf{h: fnv.New64a()} - } - return hb.(*hashAndBuf) -} - -func putHashAndBuf(hb *hashAndBuf) { - hashAndBufPool.Put(hb) -} - -// LabelsToSignature returns a unique signature (i.e., fingerprint) for a given -// label set. -func LabelsToSignature(labels map[string]string) uint64 { - if len(labels) == 0 { - return emptyLabelSignature - } - - var result uint64 - hb := getHashAndBuf() - defer putHashAndBuf(hb) - - for labelName, labelValue := range labels { - hb.b.WriteString(labelName) - hb.b.WriteByte(SeparatorByte) - hb.b.WriteString(labelValue) - hb.h.Write(hb.b.Bytes()) - result ^= hb.h.Sum64() - hb.h.Reset() - hb.b.Reset() - } - return result -} - -// metricToFingerprint works exactly as LabelsToSignature but takes a Metric as -// parameter (rather than a label map) and returns a Fingerprint. -func metricToFingerprint(m Metric) Fingerprint { - if len(m) == 0 { - return Fingerprint(emptyLabelSignature) - } - - var result uint64 - hb := getHashAndBuf() - defer putHashAndBuf(hb) - - for labelName, labelValue := range m { - hb.b.WriteString(string(labelName)) - hb.b.WriteByte(SeparatorByte) - hb.b.WriteString(string(labelValue)) - hb.h.Write(hb.b.Bytes()) - result ^= hb.h.Sum64() - hb.h.Reset() - hb.b.Reset() - } - return Fingerprint(result) -} - -// SignatureForLabels works like LabelsToSignature but takes a Metric as -// parameter (rather than a label map) and only includes the labels with the -// specified LabelNames into the signature calculation. -func SignatureForLabels(m Metric, labels LabelNames) uint64 { - if len(m) == 0 || len(labels) == 0 { - return emptyLabelSignature - } - - var result uint64 - hb := getHashAndBuf() - defer putHashAndBuf(hb) - - for _, label := range labels { - hb.b.WriteString(string(label)) - hb.b.WriteByte(SeparatorByte) - hb.b.WriteString(string(m[label])) - hb.h.Write(hb.b.Bytes()) - result ^= hb.h.Sum64() - hb.h.Reset() - hb.b.Reset() - } - return result -} - -// SignatureWithoutLabels works like LabelsToSignature but takes a Metric as -// parameter (rather than a label map) and excludes the labels with any of the -// specified LabelNames from the signature calculation. -func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 { - if len(m) == 0 { - return emptyLabelSignature - } - - var result uint64 - hb := getHashAndBuf() - defer putHashAndBuf(hb) - - for labelName, labelValue := range m { - if _, exclude := labels[labelName]; exclude { - continue - } - hb.b.WriteString(string(labelName)) - hb.b.WriteByte(SeparatorByte) - hb.b.WriteString(string(labelValue)) - hb.h.Write(hb.b.Bytes()) - result ^= hb.h.Sum64() - hb.h.Reset() - hb.b.Reset() - } - if result == 0 { - return emptyLabelSignature - } - return result -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature_test.go deleted file mode 100644 index 7b3327d44069..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature_test.go +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "runtime" - "sync" - "testing" -) - -func TestLabelsToSignature(t *testing.T) { - var scenarios = []struct { - in map[string]string - out uint64 - }{ - { - in: map[string]string{}, - out: 14695981039346656037, - }, - { - in: map[string]string{"name": "garland, briggs", "fear": "love is not enough"}, - out: 12952432476264840823, - }, - } - - for i, scenario := range scenarios { - actual := LabelsToSignature(scenario.in) - - if actual != scenario.out { - t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) - } - } -} - -func TestMetricToFingerprint(t *testing.T) { - var scenarios = []struct { - in Metric - out Fingerprint - }{ - { - in: Metric{}, - out: 14695981039346656037, - }, - { - in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, - out: 12952432476264840823, - }, - } - - for i, scenario := range scenarios { - actual := metricToFingerprint(scenario.in) - - if actual != scenario.out { - t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) - } - } -} - -func TestSignatureForLabels(t *testing.T) { - var scenarios = []struct { - in Metric - labels LabelNames - out uint64 - }{ - { - in: Metric{}, - labels: nil, - out: 14695981039346656037, - }, - { - in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, - labels: LabelNames{"fear", "name"}, - out: 12952432476264840823, - }, - { - in: Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"}, - labels: LabelNames{"fear", "name"}, - out: 12952432476264840823, - }, - { - in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, - labels: LabelNames{}, - out: 14695981039346656037, - }, - { - in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, - labels: nil, - out: 14695981039346656037, - }, - } - - for i, scenario := range scenarios { - actual := SignatureForLabels(scenario.in, scenario.labels) - - if actual != scenario.out { - t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) - } - } -} - -func TestSignatureWithoutLabels(t *testing.T) { - var scenarios = []struct { - in Metric - labels map[LabelName]struct{} - out uint64 - }{ - { - in: Metric{}, - labels: nil, - out: 14695981039346656037, - }, - { - in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, - labels: map[LabelName]struct{}{"fear": struct{}{}, "name": struct{}{}}, - out: 14695981039346656037, - }, - { - in: Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"}, - labels: map[LabelName]struct{}{"foo": struct{}{}}, - out: 12952432476264840823, - }, - { - in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, - labels: map[LabelName]struct{}{}, - out: 12952432476264840823, - }, - { - in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, - labels: nil, - out: 12952432476264840823, - }, - } - - for i, scenario := range scenarios { - actual := SignatureWithoutLabels(scenario.in, scenario.labels) - - if actual != scenario.out { - t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) - } - } -} - -func benchmarkLabelToSignature(b *testing.B, l map[string]string, e uint64) { - for i := 0; i < b.N; i++ { - if a := LabelsToSignature(l); a != e { - b.Fatalf("expected signature of %d for %s, got %d", e, l, a) - } - } -} - -func BenchmarkLabelToSignatureScalar(b *testing.B) { - benchmarkLabelToSignature(b, nil, 14695981039346656037) -} - -func BenchmarkLabelToSignatureSingle(b *testing.B) { - benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value"}, 5147259542624943964) -} - -func BenchmarkLabelToSignatureDouble(b *testing.B) { - benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value"}, 18269973311206963528) -} - -func BenchmarkLabelToSignatureTriple(b *testing.B) { - benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676) -} - -func benchmarkMetricToFingerprint(b *testing.B, m Metric, e Fingerprint) { - for i := 0; i < b.N; i++ { - if a := metricToFingerprint(m); a != e { - b.Fatalf("expected signature of %d for %s, got %d", e, m, a) - } - } -} - -func BenchmarkMetricToFingerprintScalar(b *testing.B) { - benchmarkMetricToFingerprint(b, nil, 14695981039346656037) -} - -func BenchmarkMetricToFingerprintSingle(b *testing.B) { - benchmarkMetricToFingerprint(b, Metric{"first-label": "first-label-value"}, 5147259542624943964) -} - -func BenchmarkMetricToFingerprintDouble(b *testing.B) { - benchmarkMetricToFingerprint(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value"}, 18269973311206963528) -} - -func BenchmarkMetricToFingerprintTriple(b *testing.B) { - benchmarkMetricToFingerprint(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676) -} - -func TestEmptyLabelSignature(t *testing.T) { - input := []map[string]string{nil, {}} - - var ms runtime.MemStats - runtime.ReadMemStats(&ms) - - alloc := ms.Alloc - - for _, labels := range input { - LabelsToSignature(labels) - } - - runtime.ReadMemStats(&ms) - - if got := ms.Alloc; alloc != got { - t.Fatal("expected LabelsToSignature with empty labels not to perform allocations") - } -} - -func benchmarkMetricToFingerprintConc(b *testing.B, m Metric, e Fingerprint, concLevel int) { - var start, end sync.WaitGroup - start.Add(1) - end.Add(concLevel) - - for i := 0; i < concLevel; i++ { - go func() { - start.Wait() - for j := b.N / concLevel; j >= 0; j-- { - if a := metricToFingerprint(m); a != e { - b.Fatalf("expected signature of %d for %s, got %d", e, m, a) - } - } - end.Done() - }() - } - b.ResetTimer() - start.Done() - end.Wait() -} - -func BenchmarkMetricToFingerprintTripleConc1(b *testing.B) { - benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 1) -} - -func BenchmarkMetricToFingerprintTripleConc2(b *testing.B) { - benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 2) -} - -func BenchmarkMetricToFingerprintTripleConc4(b *testing.B) { - benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 4) -} - -func BenchmarkMetricToFingerprintTripleConc8(b *testing.B) { - benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 8) -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp.go deleted file mode 100644 index afffdcf753e5..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "math" - "strconv" - - native_time "time" -) - -// Timestamp is the number of milliseconds since the epoch -// (1970-01-01 00:00 UTC) excluding leap seconds. -type Timestamp int64 - -const ( - // MinimumTick is the minimum supported time resolution. This has to be - // at least native_time.Second in order for the code below to work. - MinimumTick = native_time.Millisecond - // second is the timestamp duration equivalent to one second. - second = int64(native_time.Second / MinimumTick) - // The number of nanoseconds per minimum tick. - nanosPerTick = int64(MinimumTick / native_time.Nanosecond) - - // Earliest is the earliest timestamp representable. Handy for - // initializing a high watermark. - Earliest = Timestamp(math.MinInt64) - // Latest is the latest timestamp representable. Handy for initializing - // a low watermark. - Latest = Timestamp(math.MaxInt64) -) - -// Equal reports whether two timestamps represent the same instant. -func (t Timestamp) Equal(o Timestamp) bool { - return t == o -} - -// Before reports whether the timestamp t is before o. -func (t Timestamp) Before(o Timestamp) bool { - return t < o -} - -// After reports whether the timestamp t is after o. -func (t Timestamp) After(o Timestamp) bool { - return t > o -} - -// Add returns the Timestamp t + d. -func (t Timestamp) Add(d native_time.Duration) Timestamp { - return t + Timestamp(d/MinimumTick) -} - -// Sub returns the Duration t - o. -func (t Timestamp) Sub(o Timestamp) native_time.Duration { - return native_time.Duration(t-o) * MinimumTick -} - -// Time returns the time.Time representation of t. -func (t Timestamp) Time() native_time.Time { - return native_time.Unix(int64(t)/second, (int64(t)%second)*nanosPerTick) -} - -// Unix returns t as a Unix time, the number of seconds elapsed -// since January 1, 1970 UTC. -func (t Timestamp) Unix() int64 { - return int64(t) / second -} - -// UnixNano returns t as a Unix time, the number of nanoseconds elapsed -// since January 1, 1970 UTC. -func (t Timestamp) UnixNano() int64 { - return int64(t) * nanosPerTick -} - -// String returns a string representation of the timestamp. -func (t Timestamp) String() string { - return strconv.FormatFloat(float64(t)/float64(second), 'f', -1, 64) -} - -// MarshalJSON implements the json.Marshaler interface. -func (t Timestamp) MarshalJSON() ([]byte, error) { - return []byte(t.String()), nil -} - -// Now returns the current time as a Timestamp. -func Now() Timestamp { - return TimestampFromTime(native_time.Now()) -} - -// TimestampFromTime returns the Timestamp equivalent to the time.Time t. -func TimestampFromTime(t native_time.Time) Timestamp { - return TimestampFromUnixNano(t.UnixNano()) -} - -// TimestampFromUnix returns the Timestamp equivalent to the Unix timestamp t -// provided in seconds. -func TimestampFromUnix(t int64) Timestamp { - return Timestamp(t * second) -} - -// TimestampFromUnixNano returns the Timestamp equivalent to the Unix timestamp -// t provided in nanoseconds. -func TimestampFromUnixNano(t int64) Timestamp { - return Timestamp(t / nanosPerTick) -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp_test.go deleted file mode 100644 index fa028a47deba..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp_test.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "testing" - native_time "time" -) - -func TestComparators(t *testing.T) { - t1a := TimestampFromUnix(0) - t1b := TimestampFromUnix(0) - t2 := TimestampFromUnix(2*second - 1) - - if !t1a.Equal(t1b) { - t.Fatalf("Expected %s to be equal to %s", t1a, t1b) - } - if t1a.Equal(t2) { - t.Fatalf("Expected %s to not be equal to %s", t1a, t2) - } - - if !t1a.Before(t2) { - t.Fatalf("Expected %s to be before %s", t1a, t2) - } - if t1a.Before(t1b) { - t.Fatalf("Expected %s to not be before %s", t1a, t1b) - } - - if !t2.After(t1a) { - t.Fatalf("Expected %s to be after %s", t2, t1a) - } - if t1b.After(t1a) { - t.Fatalf("Expected %s to not be after %s", t1b, t1a) - } -} - -func TestTimestampConversions(t *testing.T) { - unixSecs := int64(1136239445) - unixNsecs := int64(123456789) - unixNano := unixSecs*1000000000 + unixNsecs - - t1 := native_time.Unix(unixSecs, unixNsecs-unixNsecs%nanosPerTick) - t2 := native_time.Unix(unixSecs, unixNsecs) - - ts := TimestampFromUnixNano(unixNano) - if !ts.Time().Equal(t1) { - t.Fatalf("Expected %s, got %s", t1, ts.Time()) - } - - // Test available precision. - ts = TimestampFromTime(t2) - if !ts.Time().Equal(t1) { - t.Fatalf("Expected %s, got %s", t1, ts.Time()) - } - - if ts.UnixNano() != unixNano-unixNano%nanosPerTick { - t.Fatalf("Expected %d, got %d", unixNano, ts.UnixNano()) - } -} - -func TestDuration(t *testing.T) { - duration := native_time.Second + native_time.Minute + native_time.Hour - goTime := native_time.Unix(1136239445, 0) - - ts := TimestampFromTime(goTime) - if !goTime.Add(duration).Equal(ts.Add(duration).Time()) { - t.Fatalf("Expected %s to be equal to %s", goTime.Add(duration), ts.Add(duration)) - } - - earlier := ts.Add(-duration) - delta := ts.Sub(earlier) - if delta != duration { - t.Fatalf("Expected %s to be equal to %s", delta, duration) - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/counter.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/counter.go index f8d633fbd555..a2952d1c8819 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/counter.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/counter.go @@ -33,7 +33,7 @@ type Counter interface { // Set is used to set the Counter to an arbitrary value. It is only used // if you have to transfer a value from an external counter into this - // Prometheus metrics. Do not use it for regular handling of a + // Prometheus metric. Do not use it for regular handling of a // Prometheus counter (as it can be used to break the contract of // monotonically increasing values). Set(float64) diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/desc.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/desc.go index 7e1f9e85372c..fcde784d6405 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/desc.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/desc.go @@ -9,18 +9,20 @@ import ( "sort" "strings" - "github.com/prometheus/client_golang/model" + "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" - - "github.com/golang/protobuf/proto" ) var ( metricNameRE = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_:]*$`) - labelNameRE = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`) + labelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$") ) +// reservedLabelPrefix is a prefix which is not legal in user-supplied +// label names. +const reservedLabelPrefix = "__" + // Labels represents a collection of label name -> value mappings. This type is // commonly used with the With(Labels) and GetMetricWith(Labels) methods of // metric vector Collectors, e.g.: @@ -134,7 +136,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) * for _, val := range labelValues { b.Reset() b.WriteString(val) - b.WriteByte(model.SeparatorByte) + b.WriteByte(separatorByte) h.Write(b.Bytes()) } d.id = h.Sum64() @@ -145,12 +147,12 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) * h.Reset() b.Reset() b.WriteString(help) - b.WriteByte(model.SeparatorByte) + b.WriteByte(separatorByte) h.Write(b.Bytes()) for _, labelName := range labelNames { b.Reset() b.WriteString(labelName) - b.WriteByte(model.SeparatorByte) + b.WriteByte(separatorByte) h.Write(b.Bytes()) } d.dimHash = h.Sum64() @@ -195,5 +197,5 @@ func (d *Desc) String() string { func checkLabelName(l string) bool { return labelNameRE.MatchString(l) && - !strings.HasPrefix(l, model.ReservedLabelPrefix) + !strings.HasPrefix(l, reservedLabelPrefix) } diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/doc.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/doc.go index b98c135262ad..425fe8793cd8 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/doc.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/doc.go @@ -61,12 +61,13 @@ // It also exports some stats about the HTTP usage of the /metrics // endpoint. (See the Handler function for more detail.) // -// A more advanced metric type is the Summary. +// Two more advanced metric types are the Summary and Histogram. // -// In addition to the fundamental metric types Gauge, Counter, and Summary, a -// very important part of the Prometheus data model is the partitioning of -// samples along dimensions called labels, which results in metric vectors. The -// fundamental types are GaugeVec, CounterVec, and SummaryVec. +// In addition to the fundamental metric types Gauge, Counter, Summary, and +// Histogram, a very important part of the Prometheus data model is the +// partitioning of samples along dimensions called labels, which results in +// metric vectors. The fundamental types are GaugeVec, CounterVec, SummaryVec, +// and HistogramVec. // // Those are all the parts needed for basic usage. Detailed documentation and // examples are provided below. diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/examples_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/examples_test.go index d106c42c6b71..0344e465b0c3 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/examples_test.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/examples_test.go @@ -392,6 +392,9 @@ func ExampleSummaryVec() { temps.WithLabelValues("lithobates-catesbeianus").Observe(32 + math.Floor(100*math.Cos(float64(i)*0.11))/10) } + // Create a Summary without any observations. + temps.WithLabelValues("leiopelma-hochstetteri") + // Just for demonstration, let's check the state of the summary vector // by (ab)using its Collect method and the Write method of its elements // (which is usually only used by Prometheus internally - code like the @@ -414,6 +417,26 @@ func ExampleSummaryVec() { // Output: // [label: < // name: "species" + // value: "leiopelma-hochstetteri" + // > + // summary: < + // sample_count: 0 + // sample_sum: 0 + // quantile: < + // quantile: 0.5 + // value: nan + // > + // quantile: < + // quantile: 0.9 + // value: nan + // > + // quantile: < + // quantile: 0.99 + // value: nan + // > + // > + // label: < + // name: "species" // value: "lithobates-catesbeianus" // > // summary: < @@ -455,6 +478,56 @@ func ExampleSummaryVec() { // ] } +func ExampleConstSummary() { + desc := prometheus.NewDesc( + "http_request_duration_seconds", + "A summary of the HTTP request durations.", + []string{"code", "method"}, + prometheus.Labels{"owner": "example"}, + ) + + // Create a constant summary from values we got from a 3rd party telemetry system. + s := prometheus.MustNewConstSummary( + desc, + 4711, 403.34, + map[float64]float64{0.5: 42.3, 0.9: 323.3}, + "200", "get", + ) + + // Just for demonstration, let's check the state of the summary by + // (ab)using its Write method (which is usually only used by Prometheus + // internally). + metric := &dto.Metric{} + s.Write(metric) + fmt.Println(proto.MarshalTextString(metric)) + + // Output: + // label: < + // name: "code" + // value: "200" + // > + // label: < + // name: "method" + // value: "get" + // > + // label: < + // name: "owner" + // value: "example" + // > + // summary: < + // sample_count: 4711 + // sample_sum: 403.34 + // quantile: < + // quantile: 0.5 + // value: 42.3 + // > + // quantile: < + // quantile: 0.9 + // value: 323.3 + // > + // > +} + func ExampleHistogram() { temps := prometheus.NewHistogram(prometheus.HistogramOpts{ Name: "pond_temperature_celsius", @@ -501,6 +574,64 @@ func ExampleHistogram() { // > } +func ExampleConstHistogram() { + desc := prometheus.NewDesc( + "http_request_duration_seconds", + "A histogram of the HTTP request durations.", + []string{"code", "method"}, + prometheus.Labels{"owner": "example"}, + ) + + // Create a constant histogram from values we got from a 3rd party telemetry system. + h := prometheus.MustNewConstHistogram( + desc, + 4711, 403.34, + map[float64]uint64{25: 121, 50: 2403, 100: 3221, 200: 4233}, + "200", "get", + ) + + // Just for demonstration, let's check the state of the histogram by + // (ab)using its Write method (which is usually only used by Prometheus + // internally). + metric := &dto.Metric{} + h.Write(metric) + fmt.Println(proto.MarshalTextString(metric)) + + // Output: + // label: < + // name: "code" + // value: "200" + // > + // label: < + // name: "method" + // value: "get" + // > + // label: < + // name: "owner" + // value: "example" + // > + // histogram: < + // sample_count: 4711 + // sample_sum: 403.34 + // bucket: < + // cumulative_count: 121 + // upper_bound: 25 + // > + // bucket: < + // cumulative_count: 2403 + // upper_bound: 50 + // > + // bucket: < + // cumulative_count: 3221 + // upper_bound: 100 + // > + // bucket: < + // cumulative_count: 4233 + // upper_bound: 200 + // > + // > +} + func ExamplePushCollectors() { hostname, _ := os.Hostname() completionTime := prometheus.NewGauge(prometheus.GaugeOpts{ diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/go_collector.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/go_collector.go index d7b7a20a1239..85fa20be4559 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/go_collector.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/go_collector.go @@ -2,10 +2,13 @@ package prometheus import ( "runtime" + "runtime/debug" + "time" ) type goCollector struct { goroutines Gauge + gcDesc *Desc } // NewGoCollector returns a collector which exports metrics about the current @@ -13,19 +16,35 @@ type goCollector struct { func NewGoCollector() *goCollector { return &goCollector{ goroutines: NewGauge(GaugeOpts{ - Name: "process_goroutines", + Name: "go_goroutines", Help: "Number of goroutines that currently exist.", }), + gcDesc: NewDesc( + "go_gc_duration_seconds", + "A summary of the GC invocation durations.", + nil, nil), } } // Describe returns all descriptions of the collector. func (c *goCollector) Describe(ch chan<- *Desc) { ch <- c.goroutines.Desc() + ch <- c.gcDesc } // Collect returns the current state of all metrics of the collector. func (c *goCollector) Collect(ch chan<- Metric) { c.goroutines.Set(float64(runtime.NumGoroutine())) ch <- c.goroutines + + var stats debug.GCStats + stats.PauseQuantiles = make([]time.Duration, 5) + debug.ReadGCStats(&stats) + + quantiles := make(map[float64]float64) + for idx, pq := range stats.PauseQuantiles[1:] { + quantiles[float64(idx+1)/float64(len(stats.PauseQuantiles)-1)] = pq.Seconds() + } + quantiles[0.0] = stats.PauseQuantiles[0].Seconds() + ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), float64(stats.PauseTotal.Seconds()), quantiles) } diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/go_collector_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/go_collector_test.go index b0582d1b98b4..9a8858cbd2b8 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/go_collector_test.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/go_collector_test.go @@ -1,7 +1,7 @@ package prometheus import ( - "reflect" + "runtime" "testing" "time" @@ -35,6 +35,9 @@ func TestGoCollector(t *testing.T) { case Gauge: pb := &dto.Metric{} m.Write(pb) + if pb.GetGauge() == nil { + continue + } if old == -1 { old = int(pb.GetGauge().GetValue()) @@ -47,9 +50,71 @@ func TestGoCollector(t *testing.T) { t.Errorf("want 1 new goroutine, got %d", diff) } + // GoCollector performs two sends per call. + // On line 27 we need to receive the second send + // to shut down cleanly. + <-ch + return + } + case <-time.After(1 * time.Second): + t.Fatalf("expected collect timed out") + } + } +} + +func TestGCCollector(t *testing.T) { + var ( + c = NewGoCollector() + ch = make(chan Metric) + waitc = make(chan struct{}) + closec = make(chan struct{}) + oldGC uint64 + oldPause float64 + ) + defer close(closec) + + go func() { + c.Collect(ch) + // force GC + runtime.GC() + <-waitc + c.Collect(ch) + }() + + first := true + for { + select { + case metric := <-ch: + switch m := metric.(type) { + case *constSummary, *value: + pb := &dto.Metric{} + m.Write(pb) + if pb.GetSummary() == nil { + continue + } + + if len(pb.GetSummary().Quantile) != 5 { + t.Errorf("expected 4 buckets, got %d", len(pb.GetSummary().Quantile)) + } + for idx, want := range []float64{0.0, 0.25, 0.5, 0.75, 1.0} { + if *pb.GetSummary().Quantile[idx].Quantile != want { + t.Errorf("bucket #%d is off, got %f, want %f", idx, *pb.GetSummary().Quantile[idx].Quantile, want) + } + } + if first { + first = false + oldGC = *pb.GetSummary().SampleCount + oldPause = *pb.GetSummary().SampleSum + close(waitc) + continue + } + if diff := *pb.GetSummary().SampleCount - oldGC; diff != 1 { + t.Errorf("want 1 new garbage collection run, got %d", diff) + } + if diff := *pb.GetSummary().SampleSum - oldPause; diff <= 0 { + t.Errorf("want moar pause, got %f", diff) + } return - default: - t.Errorf("want type Gauge, got %s", reflect.TypeOf(metric)) } case <-time.After(1 * time.Second): t.Fatalf("expected collect timed out") diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/histogram.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/histogram.go index 9b36a6115065..f98a41bc89d6 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/histogram.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/histogram.go @@ -22,7 +22,6 @@ import ( "github.com/golang/protobuf/proto" - "github.com/prometheus/client_golang/model" dto "github.com/prometheus/client_model/go" ) @@ -49,6 +48,10 @@ type Histogram interface { Observe(float64) } +// bucketLabel is used for the label that defines the upper bound of a +// bucket of a histogram ("le" -> "less or equal"). +const bucketLabel = "le" + var ( // DefBuckets are the default Histogram buckets. The default buckets are // tailored to broadly measure the response time (in seconds) of a @@ -57,7 +60,7 @@ var ( DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} errBucketLabelNotAllowed = fmt.Errorf( - "%q is not allowed as label name in histograms", model.BucketLabel, + "%q is not allowed as label name in histograms", bucketLabel, ) ) @@ -147,7 +150,7 @@ type HistogramOpts struct { // element in the slice is the upper inclusive bound of a bucket. The // values must be sorted in strictly increasing order. There is no need // to add a highest bucket with +Inf bound, it will be added - // implicitly. The default value is DefObjectives. + // implicitly. The default value is DefBuckets. Buckets []float64 } @@ -171,12 +174,12 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr } for _, n := range desc.variableLabels { - if n == model.BucketLabel { + if n == bucketLabel { panic(errBucketLabelNotAllowed) } } for _, lp := range desc.constLabelPairs { - if lp.GetName() == model.BucketLabel { + if lp.GetName() == bucketLabel { panic(errBucketLabelNotAllowed) } } @@ -213,6 +216,13 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr } type histogram struct { + // sumBits contains the bits of the float64 representing the sum of all + // observations. sumBits and count have to go first in the struct to + // guarantee alignment for atomic operations. + // http://golang.org/pkg/sync/atomic/#pkg-note-BUG + sumBits uint64 + count uint64 + SelfCollector // Note that there is no mutex required. @@ -222,9 +232,6 @@ type histogram struct { counts []uint64 labelPairs []*dto.LabelPair - - sumBits uint64 // The bits of the float64 representing the sum of all observations. - count uint64 } func (h *histogram) Desc() *Desc { @@ -342,3 +349,102 @@ func (m *HistogramVec) WithLabelValues(lvs ...string) Histogram { func (m *HistogramVec) With(labels Labels) Histogram { return m.MetricVec.With(labels).(Histogram) } + +type constHistogram struct { + desc *Desc + count uint64 + sum float64 + buckets map[float64]uint64 + labelPairs []*dto.LabelPair +} + +func (h *constHistogram) Desc() *Desc { + return h.desc +} + +func (h *constHistogram) Write(out *dto.Metric) error { + his := &dto.Histogram{} + buckets := make([]*dto.Bucket, 0, len(h.buckets)) + + his.SampleCount = proto.Uint64(h.count) + his.SampleSum = proto.Float64(h.sum) + + for upperBound, count := range h.buckets { + buckets = append(buckets, &dto.Bucket{ + CumulativeCount: proto.Uint64(count), + UpperBound: proto.Float64(upperBound), + }) + } + + if len(buckets) > 0 { + sort.Sort(buckSort(buckets)) + } + his.Bucket = buckets + + out.Histogram = his + out.Label = h.labelPairs + + return nil +} + +// NewConstHistogram returns a metric representing a Prometheus histogram with +// fixed values for the count, sum, and bucket counts. As those parameters +// cannot be changed, the returned value does not implement the Histogram +// interface (but only the Metric interface). Users of this package will not +// have much use for it in regular operations. However, when implementing custom +// Collectors, it is useful as a throw-away metric that is generated on the fly +// to send it to Prometheus in the Collect method. +// +// buckets is a map of upper bounds to cumulative counts, excluding the +Inf +// bucket. +// +// NewConstHistogram returns an error if the length of labelValues is not +// consistent with the variable labels in Desc. +func NewConstHistogram( + desc *Desc, + count uint64, + sum float64, + buckets map[float64]uint64, + labelValues ...string, +) (Metric, error) { + if len(desc.variableLabels) != len(labelValues) { + return nil, errInconsistentCardinality + } + return &constHistogram{ + desc: desc, + count: count, + sum: sum, + buckets: buckets, + labelPairs: makeLabelPairs(desc, labelValues), + }, nil +} + +// MustNewConstHistogram is a version of NewConstHistogram that panics where +// NewConstMetric would have returned an error. +func MustNewConstHistogram( + desc *Desc, + count uint64, + sum float64, + buckets map[float64]uint64, + labelValues ...string, +) Metric { + m, err := NewConstHistogram(desc, count, sum, buckets, labelValues...) + if err != nil { + panic(err) + } + return m +} + +type buckSort []*dto.Bucket + +func (s buckSort) Len() int { + return len(s) +} + +func (s buckSort) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s buckSort) Less(i, j int) bool { + return s[i].GetUpperBound() < s[j].GetUpperBound() +} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/histogram_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/histogram_test.go index 855af4695019..11cf66b4fe2e 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/histogram_test.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/histogram_test.go @@ -124,6 +124,10 @@ func BenchmarkHistogramWrite8(b *testing.B) { var testBuckets = []float64{-2, -1, -0.5, 0, 0.5, 1, 2, math.Inf(+1)} func TestHistogramConcurrency(t *testing.T) { + if testing.Short() { + t.Skip("Skipping test in short mode.") + } + rand.Seed(42) it := func(n uint32) bool { @@ -198,6 +202,10 @@ func TestHistogramConcurrency(t *testing.T) { } func TestHistogramVecConcurrency(t *testing.T) { + if testing.Short() { + t.Skip("Skipping test in short mode.") + } + rand.Seed(42) objectives := make([]float64, 0, len(DefObjectives)) diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/http.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/http.go index dac92fd907c3..eabe602468f1 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/http.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/http.go @@ -14,6 +14,9 @@ package prometheus import ( + "bufio" + "io" + "net" "net/http" "strconv" "strings" @@ -141,7 +144,18 @@ func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.Respo urlLen = len(r.URL.String()) } go computeApproximateRequestSize(r, out, urlLen) - handlerFunc(delegate, r) + + _, cn := w.(http.CloseNotifier) + _, fl := w.(http.Flusher) + _, hj := w.(http.Hijacker) + _, rf := w.(io.ReaderFrom) + var rw http.ResponseWriter + if cn && fl && hj && rf { + rw = &fancyResponseWriterDelegator{delegate} + } else { + rw = delegate + } + handlerFunc(rw, r) elapsed := float64(time.Since(now)) / float64(time.Microsecond) @@ -178,7 +192,7 @@ type responseWriterDelegator struct { handler, method string status int - written int + written int64 wroteHeader bool } @@ -193,7 +207,32 @@ func (r *responseWriterDelegator) Write(b []byte) (int, error) { r.WriteHeader(http.StatusOK) } n, err := r.ResponseWriter.Write(b) - r.written += n + r.written += int64(n) + return n, err +} + +type fancyResponseWriterDelegator struct { + *responseWriterDelegator +} + +func (f *fancyResponseWriterDelegator) CloseNotify() <-chan bool { + return f.ResponseWriter.(http.CloseNotifier).CloseNotify() +} + +func (f *fancyResponseWriterDelegator) Flush() { + f.ResponseWriter.(http.Flusher).Flush() +} + +func (f *fancyResponseWriterDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return f.ResponseWriter.(http.Hijacker).Hijack() +} + +func (f *fancyResponseWriterDelegator) ReadFrom(r io.Reader) (int64, error) { + if !f.wroteHeader { + f.WriteHeader(http.StatusOK) + } + n, err := f.ResponseWriter.(io.ReaderFrom).ReadFrom(r) + f.written += n return n, err } diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/metric.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/metric.go index d8905de2e880..86fd81c108bd 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/metric.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/metric.go @@ -19,6 +19,8 @@ import ( dto "github.com/prometheus/client_model/go" ) +const separatorByte byte = 255 + // A Metric models a single sample value with its meta data being exported to // Prometheus. Implementers of Metric in this package inclued Gauge, Counter, // Untyped, and Summary. Users can implement their own Metric types, but that diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/registry.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/registry.go index 2515311b94d9..5970aaeeba95 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/registry.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/registry.go @@ -33,13 +33,10 @@ import ( "strings" "sync" - "bitbucket.org/ww/goautoneg" "github.com/golang/protobuf/proto" + "github.com/prometheus/common/expfmt" dto "github.com/prometheus/client_model/go" - - "github.com/prometheus/client_golang/model" - "github.com/prometheus/client_golang/text" ) var ( @@ -170,6 +167,11 @@ func Unregister(c Collector) bool { // checks are performed, but no further consistency checks (which would require // knowledge of a metric descriptor). // +// Sorting concerns: The caller is responsible for sorting the label pairs in +// each metric. However, the order of metrics will be sorted by the registry as +// it is required anyway after merging with the metric families collected +// conventionally. +// // The function must be callable at any time and concurrently. func SetMetricFamilyInjectionHook(hook func() []*dto.MetricFamily) { defRegistry.metricFamilyInjectionHook = hook @@ -341,7 +343,7 @@ func (r *registry) Push(job, instance, pushURL, method string) error { } buf := r.getBuf() defer r.giveBuf(buf) - if _, err := r.writePB(buf, text.WriteProtoDelimited); err != nil { + if err := r.writePB(expfmt.NewEncoder(buf, expfmt.FmtProtoDelim)); err != nil { if r.panicOnCollectError { panic(err) } @@ -364,11 +366,11 @@ func (r *registry) Push(job, instance, pushURL, method string) error { } func (r *registry) ServeHTTP(w http.ResponseWriter, req *http.Request) { - enc, contentType := chooseEncoder(req) + contentType := expfmt.Negotiate(req.Header) buf := r.getBuf() defer r.giveBuf(buf) writer, encoding := decorateWriter(req, buf) - if _, err := r.writePB(writer, enc); err != nil { + if err := r.writePB(expfmt.NewEncoder(writer, contentType)); err != nil { if r.panicOnCollectError { panic(err) } @@ -379,7 +381,7 @@ func (r *registry) ServeHTTP(w http.ResponseWriter, req *http.Request) { closer.Close() } header := w.Header() - header.Set(contentTypeHeader, contentType) + header.Set(contentTypeHeader, string(contentType)) header.Set(contentLengthHeader, fmt.Sprint(buf.Len())) if encoding != "" { header.Set(contentEncodingHeader, encoding) @@ -387,7 +389,7 @@ func (r *registry) ServeHTTP(w http.ResponseWriter, req *http.Request) { w.Write(buf.Bytes()) } -func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) { +func (r *registry) writePB(encoder expfmt.Encoder) error { var metricHashes map[uint64]struct{} if r.collectChecksEnabled { metricHashes = make(map[uint64]struct{}) @@ -439,7 +441,7 @@ func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) { // TODO: Consider different means of error reporting so // that a single erroneous metric could be skipped // instead of blowing up the whole collection. - return 0, fmt.Errorf("error collecting metric %v: %s", desc, err) + return fmt.Errorf("error collecting metric %v: %s", desc, err) } switch { case metricFamily.Type != nil: @@ -455,11 +457,11 @@ func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) { case dtoMetric.Histogram != nil: metricFamily.Type = dto.MetricType_HISTOGRAM.Enum() default: - return 0, fmt.Errorf("empty metric collected: %s", dtoMetric) + return fmt.Errorf("empty metric collected: %s", dtoMetric) } if r.collectChecksEnabled { if err := r.checkConsistency(metricFamily, dtoMetric, desc, metricHashes); err != nil { - return 0, err + return err } } metricFamily.Metric = append(metricFamily.Metric, dtoMetric) @@ -473,7 +475,7 @@ func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) { if r.collectChecksEnabled { for _, m := range mf.Metric { if err := r.checkConsistency(mf, m, nil, metricHashes); err != nil { - return 0, err + return err } } } @@ -482,7 +484,7 @@ func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) { for _, m := range mf.Metric { if r.collectChecksEnabled { if err := r.checkConsistency(existingMF, m, nil, metricHashes); err != nil { - return 0, err + return err } } existingMF.Metric = append(existingMF.Metric, m) @@ -503,15 +505,12 @@ func (r *registry) writePB(w io.Writer, writeEncoded encoder) (int, error) { } sort.Strings(names) - var written int for _, name := range names { - w, err := writeEncoded(w, metricFamiliesByName[name]) - written += w - if err != nil { - return written, err + if err := encoder.Encode(metricFamiliesByName[name]); err != nil { + return err } } - return written, nil + return nil } func (r *registry) checkConsistency(metricFamily *dto.MetricFamily, dtoMetric *dto.Metric, desc *Desc, metricHashes map[uint64]struct{}) error { @@ -520,10 +519,11 @@ func (r *registry) checkConsistency(metricFamily *dto.MetricFamily, dtoMetric *d if metricFamily.GetType() == dto.MetricType_GAUGE && dtoMetric.Gauge == nil || metricFamily.GetType() == dto.MetricType_COUNTER && dtoMetric.Counter == nil || metricFamily.GetType() == dto.MetricType_SUMMARY && dtoMetric.Summary == nil || + metricFamily.GetType() == dto.MetricType_HISTOGRAM && dtoMetric.Histogram == nil || metricFamily.GetType() == dto.MetricType_UNTYPED && dtoMetric.Untyped == nil { return fmt.Errorf( - "collected metric %q is not a %s", - dtoMetric, metricFamily.Type, + "collected metric %s %s is not a %s", + metricFamily.GetName(), dtoMetric, metricFamily.GetType(), ) } @@ -531,19 +531,24 @@ func (r *registry) checkConsistency(metricFamily *dto.MetricFamily, dtoMetric *d h := fnv.New64a() var buf bytes.Buffer buf.WriteString(metricFamily.GetName()) - buf.WriteByte(model.SeparatorByte) + buf.WriteByte(separatorByte) h.Write(buf.Bytes()) + // Make sure label pairs are sorted. We depend on it for the consistency + // check. Label pairs must be sorted by contract. But the point of this + // method is to check for contract violations. So we better do the sort + // now. + sort.Sort(LabelPairSorter(dtoMetric.Label)) for _, lp := range dtoMetric.Label { buf.Reset() buf.WriteString(lp.GetValue()) - buf.WriteByte(model.SeparatorByte) + buf.WriteByte(separatorByte) h.Write(buf.Bytes()) } metricHash := h.Sum64() if _, exists := metricHashes[metricHash]; exists { return fmt.Errorf( - "collected metric %q was collected before with the same name and label values", - dtoMetric, + "collected metric %s %s was collected before with the same name and label values", + metricFamily.GetName(), dtoMetric, ) } metricHashes[metricHash] = struct{}{} @@ -555,14 +560,14 @@ func (r *registry) checkConsistency(metricFamily *dto.MetricFamily, dtoMetric *d // Desc consistency with metric family. if metricFamily.GetName() != desc.fqName { return fmt.Errorf( - "collected metric %q has name %q but should have %q", - dtoMetric, metricFamily.GetName(), desc.fqName, + "collected metric %s %s has name %q but should have %q", + metricFamily.GetName(), dtoMetric, metricFamily.GetName(), desc.fqName, ) } if metricFamily.GetHelp() != desc.help { return fmt.Errorf( - "collected metric %q has help %q but should have %q", - dtoMetric, metricFamily.GetHelp(), desc.help, + "collected metric %s %s has help %q but should have %q", + metricFamily.GetName(), dtoMetric, metricFamily.GetHelp(), desc.help, ) } @@ -576,8 +581,8 @@ func (r *registry) checkConsistency(metricFamily *dto.MetricFamily, dtoMetric *d } if len(lpsFromDesc) != len(dtoMetric.Label) { return fmt.Errorf( - "labels in collected metric %q are inconsistent with descriptor %s", - dtoMetric, desc, + "labels in collected metric %s %s are inconsistent with descriptor %s", + metricFamily.GetName(), dtoMetric, desc, ) } sort.Sort(LabelPairSorter(lpsFromDesc)) @@ -586,8 +591,8 @@ func (r *registry) checkConsistency(metricFamily *dto.MetricFamily, dtoMetric *d if lpFromDesc.GetName() != lpFromMetric.GetName() || lpFromDesc.Value != nil && lpFromDesc.GetValue() != lpFromMetric.GetValue() { return fmt.Errorf( - "labels in collected metric %q are inconsistent with descriptor %s", - dtoMetric, desc, + "labels in collected metric %s %s are inconsistent with descriptor %s", + metricFamily.GetName(), dtoMetric, desc, ) } } @@ -597,7 +602,10 @@ func (r *registry) checkConsistency(metricFamily *dto.MetricFamily, dtoMetric *d // Is the desc registered? if _, exist := r.descIDs[desc.id]; !exist { - return fmt.Errorf("collected metric %q with unregistered descriptor %s", dtoMetric, desc) + return fmt.Errorf( + "collected metric %s %s with unregistered descriptor %s", + metricFamily.GetName(), dtoMetric, desc, + ) } return nil @@ -672,34 +680,6 @@ func newDefaultRegistry() *registry { return r } -func chooseEncoder(req *http.Request) (encoder, string) { - accepts := goautoneg.ParseAccept(req.Header.Get(acceptHeader)) - for _, accept := range accepts { - switch { - case accept.Type == "application" && - accept.SubType == "vnd.google.protobuf" && - accept.Params["proto"] == "io.prometheus.client.MetricFamily": - switch accept.Params["encoding"] { - case "delimited": - return text.WriteProtoDelimited, DelimitedTelemetryContentType - case "text": - return text.WriteProtoText, ProtoTextTelemetryContentType - case "compact-text": - return text.WriteProtoCompactText, ProtoCompactTextTelemetryContentType - default: - continue - } - case accept.Type == "text" && - accept.SubType == "plain" && - (accept.Params["version"] == "0.0.4" || accept.Params["version"] == ""): - return text.MetricFamilyToText, TextTelemetryContentType - default: - continue - } - } - return text.MetricFamilyToText, TextTelemetryContentType -} - // decorateWriter wraps a writer to handle gzip compression if requested. It // returns the decorated writer and the appropriate "Content-Encoding" header // (which is empty if no compression is enabled). diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/registry_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/registry_test.go index bbf11f69778c..f30c90c06be1 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/registry_test.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/registry_test.go @@ -68,14 +68,14 @@ func testHandler(t testing.TB) { Metric: []*dto.Metric{ { Label: []*dto.LabelPair{ - { - Name: proto.String("externallabelname"), - Value: proto.String("externalval1"), - }, { Name: proto.String("externalconstname"), Value: proto.String("externalconstvalue"), }, + { + Name: proto.String("externallabelname"), + Value: proto.String("externalval1"), + }, }, Counter: &dto.Counter{ Value: proto.Float64(1), @@ -100,27 +100,27 @@ func testHandler(t testing.TB) { externalMetricFamilyAsBytes := externalBuf.Bytes() externalMetricFamilyAsText := []byte(`# HELP externalname externaldocstring # TYPE externalname counter -externalname{externallabelname="externalval1",externalconstname="externalconstvalue"} 1 +externalname{externalconstname="externalconstvalue",externallabelname="externalval1"} 1 `) externalMetricFamilyAsProtoText := []byte(`name: "externalname" help: "externaldocstring" type: COUNTER metric: < - label: < - name: "externallabelname" - value: "externalval1" - > label: < name: "externalconstname" value: "externalconstvalue" > + label: < + name: "externallabelname" + value: "externalval1" + > counter: < value: 1 > > `) - externalMetricFamilyAsProtoCompactText := []byte(`name:"externalname" help:"externaldocstring" type:COUNTER metric: label: counter: > + externalMetricFamilyAsProtoCompactText := []byte(`name:"externalname" help:"externaldocstring" type:COUNTER metric: label: counter: > `) expectedMetricFamily := &dto.MetricFamily{ diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/summary.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/summary.go index dd336c51994a..fe81e004f670 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/summary.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/summary.go @@ -25,10 +25,12 @@ import ( "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" - - "github.com/prometheus/client_golang/model" ) +// quantileLabel is used for the label that defines the quantile in a +// summary. +const quantileLabel = "quantile" + // A Summary captures individual observations from an event or sample stream and // summarizes them in a manner similar to traditional summary statistics: 1. sum // of observations, 2. observation count, 3. rank estimations. @@ -57,7 +59,7 @@ var ( DefObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001} errQuantileLabelNotAllowed = fmt.Errorf( - "%q is not allowed as label name in summaries", model.QuantileLabel, + "%q is not allowed as label name in summaries", quantileLabel, ) ) @@ -112,7 +114,9 @@ type SummaryOpts struct { ConstLabels Labels // Objectives defines the quantile rank estimates with their respective - // absolute error. The default value is DefObjectives. + // absolute error. If Objectives[q] = e, then the value reported + // for q will be the φ-quantile value for some φ between q-e and q+e. + // The default value is DefObjectives. Objectives map[float64]float64 // MaxAge defines the duration for which an observation stays relevant @@ -170,12 +174,12 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary { } for _, n := range desc.variableLabels { - if n == model.QuantileLabel { + if n == quantileLabel { panic(errQuantileLabelNotAllowed) } } for _, lp := range desc.constLabelPairs { - if lp.GetName() == model.QuantileLabel { + if lp.GetName() == quantileLabel { panic(errQuantileLabelNotAllowed) } } @@ -448,3 +452,89 @@ func (m *SummaryVec) WithLabelValues(lvs ...string) Summary { func (m *SummaryVec) With(labels Labels) Summary { return m.MetricVec.With(labels).(Summary) } + +type constSummary struct { + desc *Desc + count uint64 + sum float64 + quantiles map[float64]float64 + labelPairs []*dto.LabelPair +} + +func (s *constSummary) Desc() *Desc { + return s.desc +} + +func (s *constSummary) Write(out *dto.Metric) error { + sum := &dto.Summary{} + qs := make([]*dto.Quantile, 0, len(s.quantiles)) + + sum.SampleCount = proto.Uint64(s.count) + sum.SampleSum = proto.Float64(s.sum) + + for rank, q := range s.quantiles { + qs = append(qs, &dto.Quantile{ + Quantile: proto.Float64(rank), + Value: proto.Float64(q), + }) + } + + if len(qs) > 0 { + sort.Sort(quantSort(qs)) + } + sum.Quantile = qs + + out.Summary = sum + out.Label = s.labelPairs + + return nil +} + +// NewConstSummary returns a metric representing a Prometheus summary with fixed +// values for the count, sum, and quantiles. As those parameters cannot be +// changed, the returned value does not implement the Summary interface (but +// only the Metric interface). Users of this package will not have much use for +// it in regular operations. However, when implementing custom Collectors, it is +// useful as a throw-away metric that is generated on the fly to send it to +// Prometheus in the Collect method. +// +// quantiles maps ranks to quantile values. For example, a median latency of +// 0.23s and a 99th percentile latency of 0.56s would be expressed as: +// map[float64]float64{0.5: 0.23, 0.99: 0.56} +// +// NewConstSummary returns an error if the length of labelValues is not +// consistent with the variable labels in Desc. +func NewConstSummary( + desc *Desc, + count uint64, + sum float64, + quantiles map[float64]float64, + labelValues ...string, +) (Metric, error) { + if len(desc.variableLabels) != len(labelValues) { + return nil, errInconsistentCardinality + } + return &constSummary{ + desc: desc, + count: count, + sum: sum, + quantiles: quantiles, + labelPairs: makeLabelPairs(desc, labelValues), + }, nil +} + +// MustNewConstSummary is a version of NewConstSummary that panics where +// NewConstMetric would have returned an error. +func MustNewConstSummary( + desc *Desc, + count uint64, + sum float64, + quantiles map[float64]float64, + labelValues ...string, +) Metric { + m, err := NewConstSummary(desc, count, sum, quantiles, labelValues...) + if err != nil { + panic(err) + } + return m +} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/untyped.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/untyped.go index a5a4e77b14b2..c65ab1c53126 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/untyped.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/untyped.go @@ -21,7 +21,7 @@ import "hash/fnv" // An Untyped metric works the same as a Gauge. The only difference is that to // no type information is implied. // -// To create Gauge instances, use NewUntyped. +// To create Untyped instances, use NewUntyped. type Untyped interface { Metric Collector diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/value.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/value.go index 107d43e37217..b54ac11e888e 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/value.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/value.go @@ -43,11 +43,15 @@ var errInconsistentCardinality = errors.New("inconsistent label cardinality") // ValueType. This is a low-level building block used by the library to back the // implementations of Counter, Gauge, and Untyped. type value struct { + // valBits containst the bits of the represented float64 value. It has + // to go first in the struct to guarantee alignment for atomic + // operations. http://golang.org/pkg/sync/atomic/#pkg-note-BUG + valBits uint64 + SelfCollector desc *Desc valType ValueType - valBits uint64 // These are the bits of the represented float64 value. labelPairs []*dto.LabelPair } diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/vec.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/vec.go index aa49deba1b4b..a1f3bdf37d83 100644 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/vec.go +++ b/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/vec.go @@ -58,6 +58,11 @@ func (m *MetricVec) Collect(ch chan<- Metric) { // GetMetricWithLabelValues returns the Metric for the given slice of label // values (same order as the VariableLabels in Desc). If that combination of // label values is accessed for the first time, a new Metric is created. +// +// It is possible to call this method without using the returned Metric to only +// create the new Metric but leave it at its start value (e.g. a Summary or +// Histogram without any observations). See also the SummaryVec example. +// // Keeping the Metric for later use is possible (and should be considered if // performance is critical), but keep in mind that Reset, DeleteLabelValues and // Delete can be used to delete the Metric from the MetricVec. In that case, the @@ -87,8 +92,9 @@ func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) { // GetMetricWith returns the Metric for the given Labels map (the label names // must match those of the VariableLabels in Desc). If that label map is -// accessed for the first time, a new Metric is created. Implications of keeping -// the Metric are the same as for GetMetricWithLabelValues. +// accessed for the first time, a new Metric is created. Implications of +// creating a Metric without using it and keeping the Metric for later use are +// the same as for GetMetricWithLabelValues. // // An error is returned if the number and names of the Labels are inconsistent // with those of the VariableLabels in Desc. diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/bench_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/text/bench_test.go deleted file mode 100644 index a97409ed3f93..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/bench_test.go +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2015 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package text - -import ( - "bytes" - "compress/gzip" - "io" - "io/ioutil" - "testing" - dto "github.com/prometheus/client_model/go" - - "github.com/matttproud/golang_protobuf_extensions/pbutil" -) - -// Benchmarks to show how much penalty text format parsing actually inflicts. -// -// Example results on Linux 3.13.0, Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz, go1.4. -// -// BenchmarkParseText 1000 1188535 ns/op 205085 B/op 6135 allocs/op -// BenchmarkParseTextGzip 1000 1376567 ns/op 246224 B/op 6151 allocs/op -// BenchmarkParseProto 10000 172790 ns/op 52258 B/op 1160 allocs/op -// BenchmarkParseProtoGzip 5000 324021 ns/op 94931 B/op 1211 allocs/op -// BenchmarkParseProtoMap 10000 187946 ns/op 58714 B/op 1203 allocs/op -// -// CONCLUSION: The overhead for the map is negligible. Text format needs ~5x more allocations. -// Without compression, it needs ~7x longer, but with compression (the more relevant scenario), -// the difference becomes less relevant, only ~4x. -// -// The test data contains 248 samples. -// -// BenchmarkProcessor002ParseOnly in the extraction package is not quite -// comparable to the benchmarks here, but it gives an idea: JSON parsing is even -// slower than text parsing and needs a comparable amount of allocs. - -// BenchmarkParseText benchmarks the parsing of a text-format scrape into metric -// family DTOs. -func BenchmarkParseText(b *testing.B) { - b.StopTimer() - data, err := ioutil.ReadFile("testdata/text") - if err != nil { - b.Fatal(err) - } - b.StartTimer() - - for i := 0; i < b.N; i++ { - if _, err := parser.TextToMetricFamilies(bytes.NewReader(data)); err != nil { - b.Fatal(err) - } - } -} - -// BenchmarkParseTextGzip benchmarks the parsing of a gzipped text-format scrape -// into metric family DTOs. -func BenchmarkParseTextGzip(b *testing.B) { - b.StopTimer() - data, err := ioutil.ReadFile("testdata/text.gz") - if err != nil { - b.Fatal(err) - } - b.StartTimer() - - for i := 0; i < b.N; i++ { - in, err := gzip.NewReader(bytes.NewReader(data)) - if err != nil { - b.Fatal(err) - } - if _, err := parser.TextToMetricFamilies(in); err != nil { - b.Fatal(err) - } - } -} - -// BenchmarkParseProto benchmarks the parsing of a protobuf-format scrape into -// metric family DTOs. Note that this does not build a map of metric families -// (as the text version does), because it is not required for Prometheus -// ingestion either. (However, it is required for the text-format parsing, as -// the metric family might be sprinkled all over the text, while the -// protobuf-format guarantees bundling at one place.) -func BenchmarkParseProto(b *testing.B) { - b.StopTimer() - data, err := ioutil.ReadFile("testdata/protobuf") - if err != nil { - b.Fatal(err) - } - b.StartTimer() - - for i := 0; i < b.N; i++ { - family := &dto.MetricFamily{} - in := bytes.NewReader(data) - for { - family.Reset() - if _, err := pbutil.ReadDelimited(in, family); err != nil { - if err == io.EOF { - break - } - b.Fatal(err) - } - } - } -} - -// BenchmarkParseProtoGzip is like BenchmarkParseProto above, but parses gzipped -// protobuf format. -func BenchmarkParseProtoGzip(b *testing.B) { - b.StopTimer() - data, err := ioutil.ReadFile("testdata/protobuf.gz") - if err != nil { - b.Fatal(err) - } - b.StartTimer() - - for i := 0; i < b.N; i++ { - family := &dto.MetricFamily{} - in, err := gzip.NewReader(bytes.NewReader(data)) - if err != nil { - b.Fatal(err) - } - for { - family.Reset() - if _, err := pbutil.ReadDelimited(in, family); err != nil { - if err == io.EOF { - break - } - b.Fatal(err) - } - } - } -} - -// BenchmarkParseProtoMap is like BenchmarkParseProto but DOES put the parsed -// metric family DTOs into a map. This is not happening during Prometheus -// ingestion. It is just here to measure the overhead of that map creation and -// separate it from the overhead of the text format parsing. -func BenchmarkParseProtoMap(b *testing.B) { - b.StopTimer() - data, err := ioutil.ReadFile("testdata/protobuf") - if err != nil { - b.Fatal(err) - } - b.StartTimer() - - for i := 0; i < b.N; i++ { - families := map[string]*dto.MetricFamily{} - in := bytes.NewReader(data) - for { - family := &dto.MetricFamily{} - if _, err := pbutil.ReadDelimited(in, family); err != nil { - if err == io.EOF { - break - } - b.Fatal(err) - } - families[family.GetName()] = family - } - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/create.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/text/create.go deleted file mode 100644 index 44304599466d..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/create.go +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package text contains helper functions to parse and create text-based -// exchange formats. The package currently supports (only) version 0.0.4 of the -// exchange format. Should other versions be supported in the future, some -// versioning scheme has to be applied. Possibilities include separate packages -// or separate functions. The best way depends on the nature of future changes, -// which is the reason why no versioning scheme has been applied prematurely -// here. -package text - -import ( - "bytes" - "fmt" - "io" - "math" - "strings" - - "github.com/prometheus/client_golang/model" - dto "github.com/prometheus/client_model/go" -) - -// MetricFamilyToText converts a MetricFamily proto message into text format and -// writes the resulting lines to 'out'. It returns the number of bytes written -// and any error encountered. This function does not perform checks on the -// content of the metric and label names, i.e. invalid metric or label names -// will result in invalid text format output. -// This method fulfills the type 'prometheus.encoder'. -func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) { - var written int - - // Fail-fast checks. - if len(in.Metric) == 0 { - return written, fmt.Errorf("MetricFamily has no metrics: %s", in) - } - name := in.GetName() - if name == "" { - return written, fmt.Errorf("MetricFamily has no name: %s", in) - } - if in.Type == nil { - return written, fmt.Errorf("MetricFamily has no type: %s", in) - } - - // Comments, first HELP, then TYPE. - if in.Help != nil { - n, err := fmt.Fprintf( - out, "# HELP %s %s\n", - name, escapeString(*in.Help, false), - ) - written += n - if err != nil { - return written, err - } - } - metricType := in.GetType() - n, err := fmt.Fprintf( - out, "# TYPE %s %s\n", - name, strings.ToLower(metricType.String()), - ) - written += n - if err != nil { - return written, err - } - - // Finally the samples, one line for each. - for _, metric := range in.Metric { - switch metricType { - case dto.MetricType_COUNTER: - if metric.Counter == nil { - return written, fmt.Errorf( - "expected counter in metric %s", metric, - ) - } - n, err = writeSample( - name, metric, "", "", - metric.Counter.GetValue(), - out, - ) - case dto.MetricType_GAUGE: - if metric.Gauge == nil { - return written, fmt.Errorf( - "expected gauge in metric %s", metric, - ) - } - n, err = writeSample( - name, metric, "", "", - metric.Gauge.GetValue(), - out, - ) - case dto.MetricType_UNTYPED: - if metric.Untyped == nil { - return written, fmt.Errorf( - "expected untyped in metric %s", metric, - ) - } - n, err = writeSample( - name, metric, "", "", - metric.Untyped.GetValue(), - out, - ) - case dto.MetricType_SUMMARY: - if metric.Summary == nil { - return written, fmt.Errorf( - "expected summary in metric %s", metric, - ) - } - for _, q := range metric.Summary.Quantile { - n, err = writeSample( - name, metric, - model.QuantileLabel, fmt.Sprint(q.GetQuantile()), - q.GetValue(), - out, - ) - written += n - if err != nil { - return written, err - } - } - n, err = writeSample( - name+"_sum", metric, "", "", - metric.Summary.GetSampleSum(), - out, - ) - if err != nil { - return written, err - } - written += n - n, err = writeSample( - name+"_count", metric, "", "", - float64(metric.Summary.GetSampleCount()), - out, - ) - case dto.MetricType_HISTOGRAM: - if metric.Histogram == nil { - return written, fmt.Errorf( - "expected summary in metric %s", metric, - ) - } - infSeen := false - for _, q := range metric.Histogram.Bucket { - n, err = writeSample( - name+"_bucket", metric, - model.BucketLabel, fmt.Sprint(q.GetUpperBound()), - float64(q.GetCumulativeCount()), - out, - ) - written += n - if err != nil { - return written, err - } - if math.IsInf(q.GetUpperBound(), +1) { - infSeen = true - } - } - if !infSeen { - n, err = writeSample( - name+"_bucket", metric, - model.BucketLabel, "+Inf", - float64(metric.Histogram.GetSampleCount()), - out, - ) - if err != nil { - return written, err - } - written += n - } - n, err = writeSample( - name+"_sum", metric, "", "", - metric.Histogram.GetSampleSum(), - out, - ) - if err != nil { - return written, err - } - written += n - n, err = writeSample( - name+"_count", metric, "", "", - float64(metric.Histogram.GetSampleCount()), - out, - ) - default: - return written, fmt.Errorf( - "unexpected type in metric %s", metric, - ) - } - written += n - if err != nil { - return written, err - } - } - return written, nil -} - -// writeSample writes a single sample in text format to out, given the metric -// name, the metric proto message itself, optionally an additional label name -// and value (use empty strings if not required), and the value. The function -// returns the number of bytes written and any error encountered. -func writeSample( - name string, - metric *dto.Metric, - additionalLabelName, additionalLabelValue string, - value float64, - out io.Writer, -) (int, error) { - var written int - n, err := fmt.Fprint(out, name) - written += n - if err != nil { - return written, err - } - n, err = labelPairsToText( - metric.Label, - additionalLabelName, additionalLabelValue, - out, - ) - written += n - if err != nil { - return written, err - } - n, err = fmt.Fprintf(out, " %v", value) - written += n - if err != nil { - return written, err - } - if metric.TimestampMs != nil { - n, err = fmt.Fprintf(out, " %v", *metric.TimestampMs) - written += n - if err != nil { - return written, err - } - } - n, err = out.Write([]byte{'\n'}) - written += n - if err != nil { - return written, err - } - return written, nil -} - -// labelPairsToText converts a slice of LabelPair proto messages plus the -// explicitly given additional label pair into text formatted as required by the -// text format and writes it to 'out'. An empty slice in combination with an -// empty string 'additionalLabelName' results in nothing being -// written. Otherwise, the label pairs are written, escaped as required by the -// text format, and enclosed in '{...}'. The function returns the number of -// bytes written and any error encountered. -func labelPairsToText( - in []*dto.LabelPair, - additionalLabelName, additionalLabelValue string, - out io.Writer, -) (int, error) { - if len(in) == 0 && additionalLabelName == "" { - return 0, nil - } - var written int - separator := '{' - for _, lp := range in { - n, err := fmt.Fprintf( - out, `%c%s="%s"`, - separator, lp.GetName(), escapeString(lp.GetValue(), true), - ) - written += n - if err != nil { - return written, err - } - separator = ',' - } - if additionalLabelName != "" { - n, err := fmt.Fprintf( - out, `%c%s="%s"`, - separator, additionalLabelName, - escapeString(additionalLabelValue, true), - ) - written += n - if err != nil { - return written, err - } - } - n, err := out.Write([]byte{'}'}) - written += n - if err != nil { - return written, err - } - return written, nil -} - -// escapeString replaces '\' by '\\', new line character by '\n', and - if -// includeDoubleQuote is true - '"' by '\"'. -func escapeString(v string, includeDoubleQuote bool) string { - result := bytes.NewBuffer(make([]byte, 0, len(v))) - for _, c := range v { - switch { - case c == '\\': - result.WriteString(`\\`) - case includeDoubleQuote && c == '"': - result.WriteString(`\"`) - case c == '\n': - result.WriteString(`\n`) - default: - result.WriteRune(c) - } - } - return result.String() -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/create_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/text/create_test.go deleted file mode 100644 index fe938de80c79..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/create_test.go +++ /dev/null @@ -1,439 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package text - -import ( - "bytes" - "math" - "strings" - "testing" - - "github.com/golang/protobuf/proto" - dto "github.com/prometheus/client_model/go" -) - -func testCreate(t testing.TB) { - var scenarios = []struct { - in *dto.MetricFamily - out string - }{ - // 0: Counter, NaN as value, timestamp given. - { - in: &dto.MetricFamily{ - Name: proto.String("name"), - Help: proto.String("two-line\n doc str\\ing"), - Type: dto.MetricType_COUNTER.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("labelname"), - Value: proto.String("val1"), - }, - &dto.LabelPair{ - Name: proto.String("basename"), - Value: proto.String("basevalue"), - }, - }, - Counter: &dto.Counter{ - Value: proto.Float64(math.NaN()), - }, - }, - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("labelname"), - Value: proto.String("val2"), - }, - &dto.LabelPair{ - Name: proto.String("basename"), - Value: proto.String("basevalue"), - }, - }, - Counter: &dto.Counter{ - Value: proto.Float64(.23), - }, - TimestampMs: proto.Int64(1234567890), - }, - }, - }, - out: `# HELP name two-line\n doc str\\ing -# TYPE name counter -name{labelname="val1",basename="basevalue"} NaN -name{labelname="val2",basename="basevalue"} 0.23 1234567890 -`, - }, - // 1: Gauge, some escaping required, +Inf as value, multi-byte characters in label values. - { - in: &dto.MetricFamily{ - Name: proto.String("gauge_name"), - Help: proto.String("gauge\ndoc\nstr\"ing"), - Type: dto.MetricType_GAUGE.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("name_1"), - Value: proto.String("val with\nnew line"), - }, - &dto.LabelPair{ - Name: proto.String("name_2"), - Value: proto.String("val with \\backslash and \"quotes\""), - }, - }, - Gauge: &dto.Gauge{ - Value: proto.Float64(math.Inf(+1)), - }, - }, - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("name_1"), - Value: proto.String("Björn"), - }, - &dto.LabelPair{ - Name: proto.String("name_2"), - Value: proto.String("佖佥"), - }, - }, - Gauge: &dto.Gauge{ - Value: proto.Float64(3.14E42), - }, - }, - }, - }, - out: `# HELP gauge_name gauge\ndoc\nstr"ing -# TYPE gauge_name gauge -gauge_name{name_1="val with\nnew line",name_2="val with \\backslash and \"quotes\""} +Inf -gauge_name{name_1="Björn",name_2="佖佥"} 3.14e+42 -`, - }, - // 2: Untyped, no help, one sample with no labels and -Inf as value, another sample with one label. - { - in: &dto.MetricFamily{ - Name: proto.String("untyped_name"), - Type: dto.MetricType_UNTYPED.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Untyped: &dto.Untyped{ - Value: proto.Float64(math.Inf(-1)), - }, - }, - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("name_1"), - Value: proto.String("value 1"), - }, - }, - Untyped: &dto.Untyped{ - Value: proto.Float64(-1.23e-45), - }, - }, - }, - }, - out: `# TYPE untyped_name untyped -untyped_name -Inf -untyped_name{name_1="value 1"} -1.23e-45 -`, - }, - // 3: Summary. - { - in: &dto.MetricFamily{ - Name: proto.String("summary_name"), - Help: proto.String("summary docstring"), - Type: dto.MetricType_SUMMARY.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Summary: &dto.Summary{ - SampleCount: proto.Uint64(42), - SampleSum: proto.Float64(-3.4567), - Quantile: []*dto.Quantile{ - &dto.Quantile{ - Quantile: proto.Float64(0.5), - Value: proto.Float64(-1.23), - }, - &dto.Quantile{ - Quantile: proto.Float64(0.9), - Value: proto.Float64(.2342354), - }, - &dto.Quantile{ - Quantile: proto.Float64(0.99), - Value: proto.Float64(0), - }, - }, - }, - }, - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("name_1"), - Value: proto.String("value 1"), - }, - &dto.LabelPair{ - Name: proto.String("name_2"), - Value: proto.String("value 2"), - }, - }, - Summary: &dto.Summary{ - SampleCount: proto.Uint64(4711), - SampleSum: proto.Float64(2010.1971), - Quantile: []*dto.Quantile{ - &dto.Quantile{ - Quantile: proto.Float64(0.5), - Value: proto.Float64(1), - }, - &dto.Quantile{ - Quantile: proto.Float64(0.9), - Value: proto.Float64(2), - }, - &dto.Quantile{ - Quantile: proto.Float64(0.99), - Value: proto.Float64(3), - }, - }, - }, - }, - }, - }, - out: `# HELP summary_name summary docstring -# TYPE summary_name summary -summary_name{quantile="0.5"} -1.23 -summary_name{quantile="0.9"} 0.2342354 -summary_name{quantile="0.99"} 0 -summary_name_sum -3.4567 -summary_name_count 42 -summary_name{name_1="value 1",name_2="value 2",quantile="0.5"} 1 -summary_name{name_1="value 1",name_2="value 2",quantile="0.9"} 2 -summary_name{name_1="value 1",name_2="value 2",quantile="0.99"} 3 -summary_name_sum{name_1="value 1",name_2="value 2"} 2010.1971 -summary_name_count{name_1="value 1",name_2="value 2"} 4711 -`, - }, - // 4: Histogram - { - in: &dto.MetricFamily{ - Name: proto.String("request_duration_microseconds"), - Help: proto.String("The response latency."), - Type: dto.MetricType_HISTOGRAM.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Histogram: &dto.Histogram{ - SampleCount: proto.Uint64(2693), - SampleSum: proto.Float64(1756047.3), - Bucket: []*dto.Bucket{ - &dto.Bucket{ - UpperBound: proto.Float64(100), - CumulativeCount: proto.Uint64(123), - }, - &dto.Bucket{ - UpperBound: proto.Float64(120), - CumulativeCount: proto.Uint64(412), - }, - &dto.Bucket{ - UpperBound: proto.Float64(144), - CumulativeCount: proto.Uint64(592), - }, - &dto.Bucket{ - UpperBound: proto.Float64(172.8), - CumulativeCount: proto.Uint64(1524), - }, - &dto.Bucket{ - UpperBound: proto.Float64(math.Inf(+1)), - CumulativeCount: proto.Uint64(2693), - }, - }, - }, - }, - }, - }, - out: `# HELP request_duration_microseconds The response latency. -# TYPE request_duration_microseconds histogram -request_duration_microseconds_bucket{le="100"} 123 -request_duration_microseconds_bucket{le="120"} 412 -request_duration_microseconds_bucket{le="144"} 592 -request_duration_microseconds_bucket{le="172.8"} 1524 -request_duration_microseconds_bucket{le="+Inf"} 2693 -request_duration_microseconds_sum 1.7560473e+06 -request_duration_microseconds_count 2693 -`, - }, - // 5: Histogram with missing +Inf bucket. - { - in: &dto.MetricFamily{ - Name: proto.String("request_duration_microseconds"), - Help: proto.String("The response latency."), - Type: dto.MetricType_HISTOGRAM.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Histogram: &dto.Histogram{ - SampleCount: proto.Uint64(2693), - SampleSum: proto.Float64(1756047.3), - Bucket: []*dto.Bucket{ - &dto.Bucket{ - UpperBound: proto.Float64(100), - CumulativeCount: proto.Uint64(123), - }, - &dto.Bucket{ - UpperBound: proto.Float64(120), - CumulativeCount: proto.Uint64(412), - }, - &dto.Bucket{ - UpperBound: proto.Float64(144), - CumulativeCount: proto.Uint64(592), - }, - &dto.Bucket{ - UpperBound: proto.Float64(172.8), - CumulativeCount: proto.Uint64(1524), - }, - }, - }, - }, - }, - }, - out: `# HELP request_duration_microseconds The response latency. -# TYPE request_duration_microseconds histogram -request_duration_microseconds_bucket{le="100"} 123 -request_duration_microseconds_bucket{le="120"} 412 -request_duration_microseconds_bucket{le="144"} 592 -request_duration_microseconds_bucket{le="172.8"} 1524 -request_duration_microseconds_bucket{le="+Inf"} 2693 -request_duration_microseconds_sum 1.7560473e+06 -request_duration_microseconds_count 2693 -`, - }, - } - - for i, scenario := range scenarios { - out := bytes.NewBuffer(make([]byte, 0, len(scenario.out))) - n, err := MetricFamilyToText(out, scenario.in) - if err != nil { - t.Errorf("%d. error: %s", i, err) - continue - } - if expected, got := len(scenario.out), n; expected != got { - t.Errorf( - "%d. expected %d bytes written, got %d", - i, expected, got, - ) - } - if expected, got := scenario.out, out.String(); expected != got { - t.Errorf( - "%d. expected out=%q, got %q", - i, expected, got, - ) - } - } - -} - -func TestCreate(t *testing.T) { - testCreate(t) -} - -func BenchmarkCreate(b *testing.B) { - for i := 0; i < b.N; i++ { - testCreate(b) - } -} - -func testCreateError(t testing.TB) { - var scenarios = []struct { - in *dto.MetricFamily - err string - }{ - // 0: No metric. - { - in: &dto.MetricFamily{ - Name: proto.String("name"), - Help: proto.String("doc string"), - Type: dto.MetricType_COUNTER.Enum(), - Metric: []*dto.Metric{}, - }, - err: "MetricFamily has no metrics", - }, - // 1: No metric name. - { - in: &dto.MetricFamily{ - Help: proto.String("doc string"), - Type: dto.MetricType_UNTYPED.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Untyped: &dto.Untyped{ - Value: proto.Float64(math.Inf(-1)), - }, - }, - }, - }, - err: "MetricFamily has no name", - }, - // 2: No metric type. - { - in: &dto.MetricFamily{ - Name: proto.String("name"), - Help: proto.String("doc string"), - Metric: []*dto.Metric{ - &dto.Metric{ - Untyped: &dto.Untyped{ - Value: proto.Float64(math.Inf(-1)), - }, - }, - }, - }, - err: "MetricFamily has no type", - }, - // 3: Wrong type. - { - in: &dto.MetricFamily{ - Name: proto.String("name"), - Help: proto.String("doc string"), - Type: dto.MetricType_COUNTER.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Untyped: &dto.Untyped{ - Value: proto.Float64(math.Inf(-1)), - }, - }, - }, - }, - err: "expected counter in metric", - }, - } - - for i, scenario := range scenarios { - var out bytes.Buffer - _, err := MetricFamilyToText(&out, scenario.in) - if err == nil { - t.Errorf("%d. expected error, got nil", i) - continue - } - if expected, got := scenario.err, err.Error(); strings.Index(got, expected) != 0 { - t.Errorf( - "%d. expected error starting with %q, got %q", - i, expected, got, - ) - } - } - -} - -func TestCreateError(t *testing.T) { - testCreateError(t) -} - -func BenchmarkCreateError(b *testing.B) { - for i := 0; i < b.N; i++ { - testCreateError(b) - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/parse.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/text/parse.go deleted file mode 100644 index e317d6850be9..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/parse.go +++ /dev/null @@ -1,739 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package text - -import ( - "bufio" - "bytes" - "fmt" - "io" - "math" - "strconv" - "strings" - - dto "github.com/prometheus/client_model/go" - - "github.com/golang/protobuf/proto" - "github.com/prometheus/client_golang/model" -) - -// A stateFn is a function that represents a state in a state machine. By -// executing it, the state is progressed to the next state. The stateFn returns -// another stateFn, which represents the new state. The end state is represented -// by nil. -type stateFn func() stateFn - -// ParseError signals errors while parsing the simple and flat text-based -// exchange format. -type ParseError struct { - Line int - Msg string -} - -// Error implements the error interface. -func (e ParseError) Error() string { - return fmt.Sprintf("text format parsing error in line %d: %s", e.Line, e.Msg) -} - -// Parser is used to parse the simple and flat text-based exchange format. Its -// nil value is ready to use. -type Parser struct { - metricFamiliesByName map[string]*dto.MetricFamily - buf *bufio.Reader // Where the parsed input is read through. - err error // Most recent error. - lineCount int // Tracks the line count for error messages. - currentByte byte // The most recent byte read. - currentToken bytes.Buffer // Re-used each time a token has to be gathered from multiple bytes. - currentMF *dto.MetricFamily - currentMetric *dto.Metric - currentLabelPair *dto.LabelPair - - // The remaining member variables are only used for summaries/histograms. - currentLabels map[string]string // All labels including '__name__' but excluding 'quantile'/'le' - // Summary specific. - summaries map[uint64]*dto.Metric // Key is created with LabelsToSignature. - currentQuantile float64 - // Histogram specific. - histograms map[uint64]*dto.Metric // Key is created with LabelsToSignature. - currentBucket float64 - // These tell us if the currently processed line ends on '_count' or - // '_sum' respectively and belong to a summary/histogram, representing the sample - // count and sum of that summary/histogram. - currentIsSummaryCount, currentIsSummarySum bool - currentIsHistogramCount, currentIsHistogramSum bool -} - -// TextToMetricFamilies reads 'in' as the simple and flat text-based exchange -// format and creates MetricFamily proto messages. It returns the MetricFamily -// proto messages in a map where the metric names are the keys, along with any -// error encountered. -// -// If the input contains duplicate metrics (i.e. lines with the same metric name -// and exactly the same label set), the resulting MetricFamily will contain -// duplicate Metric proto messages. Similar is true for duplicate label -// names. Checks for duplicates have to be performed separately, if required. -// -// Summaries are a rather special beast. You would probably not use them in the -// simple text format anyway. This method can deal with summaries if they are -// presented in exactly the way the text.Create function creates them. -// -// This method must not be called concurrently. If you want to parse different -// input concurrently, instantiate a separate Parser for each goroutine. -func (p *Parser) TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricFamily, error) { - p.reset(in) - for nextState := p.startOfLine; nextState != nil; nextState = nextState() { - // Magic happens here... - } - // Get rid of empty metric families. - for k, mf := range p.metricFamiliesByName { - if len(mf.GetMetric()) == 0 { - delete(p.metricFamiliesByName, k) - } - } - return p.metricFamiliesByName, p.err -} - -func (p *Parser) reset(in io.Reader) { - p.metricFamiliesByName = map[string]*dto.MetricFamily{} - if p.buf == nil { - p.buf = bufio.NewReader(in) - } else { - p.buf.Reset(in) - } - p.err = nil - p.lineCount = 0 - if p.summaries == nil || len(p.summaries) > 0 { - p.summaries = map[uint64]*dto.Metric{} - } - if p.histograms == nil || len(p.histograms) > 0 { - p.histograms = map[uint64]*dto.Metric{} - } - p.currentQuantile = math.NaN() - p.currentBucket = math.NaN() -} - -// startOfLine represents the state where the next byte read from p.buf is the -// start of a line (or whitespace leading up to it). -func (p *Parser) startOfLine() stateFn { - p.lineCount++ - if p.skipBlankTab(); p.err != nil { - // End of input reached. This is the only case where - // that is not an error but a signal that we are done. - p.err = nil - return nil - } - switch p.currentByte { - case '#': - return p.startComment - case '\n': - return p.startOfLine // Empty line, start the next one. - } - return p.readingMetricName -} - -// startComment represents the state where the next byte read from p.buf is the -// start of a comment (or whitespace leading up to it). -func (p *Parser) startComment() stateFn { - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte == '\n' { - return p.startOfLine - } - if p.readTokenUntilWhitespace(); p.err != nil { - return nil // Unexpected end of input. - } - // If we have hit the end of line already, there is nothing left - // to do. This is not considered a syntax error. - if p.currentByte == '\n' { - return p.startOfLine - } - keyword := p.currentToken.String() - if keyword != "HELP" && keyword != "TYPE" { - // Generic comment, ignore by fast forwarding to end of line. - for p.currentByte != '\n' { - if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil { - return nil // Unexpected end of input. - } - } - return p.startOfLine - } - // There is something. Next has to be a metric name. - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.readTokenAsMetricName(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte == '\n' { - // At the end of the line already. - // Again, this is not considered a syntax error. - return p.startOfLine - } - if !isBlankOrTab(p.currentByte) { - p.parseError("invalid metric name in comment") - return nil - } - p.setOrCreateCurrentMF() - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte == '\n' { - // At the end of the line already. - // Again, this is not considered a syntax error. - return p.startOfLine - } - switch keyword { - case "HELP": - return p.readingHelp - case "TYPE": - return p.readingType - } - panic(fmt.Sprintf("code error: unexpected keyword %q", keyword)) -} - -// readingMetricName represents the state where the last byte read (now in -// p.currentByte) is the first byte of a metric name. -func (p *Parser) readingMetricName() stateFn { - if p.readTokenAsMetricName(); p.err != nil { - return nil - } - if p.currentToken.Len() == 0 { - p.parseError("invalid metric name") - return nil - } - p.setOrCreateCurrentMF() - // Now is the time to fix the type if it hasn't happened yet. - if p.currentMF.Type == nil { - p.currentMF.Type = dto.MetricType_UNTYPED.Enum() - } - p.currentMetric = &dto.Metric{} - // Do not append the newly created currentMetric to - // currentMF.Metric right now. First wait if this is a summary, - // and the metric exists already, which we can only know after - // having read all the labels. - if p.skipBlankTabIfCurrentBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - return p.readingLabels -} - -// readingLabels represents the state where the last byte read (now in -// p.currentByte) is either the first byte of the label set (i.e. a '{'), or the -// first byte of the value (otherwise). -func (p *Parser) readingLabels() stateFn { - // Summaries/histograms are special. We have to reset the - // currentLabels map, currentQuantile and currentBucket before starting to - // read labels. - if p.currentMF.GetType() == dto.MetricType_SUMMARY || p.currentMF.GetType() == dto.MetricType_HISTOGRAM { - p.currentLabels = map[string]string{} - p.currentLabels[string(model.MetricNameLabel)] = p.currentMF.GetName() - p.currentQuantile = math.NaN() - p.currentBucket = math.NaN() - } - if p.currentByte != '{' { - return p.readingValue - } - return p.startLabelName -} - -// startLabelName represents the state where the next byte read from p.buf is -// the start of a label name (or whitespace leading up to it). -func (p *Parser) startLabelName() stateFn { - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte == '}' { - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - return p.readingValue - } - if p.readTokenAsLabelName(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentToken.Len() == 0 { - p.parseError(fmt.Sprintf("invalid label name for metric %q", p.currentMF.GetName())) - return nil - } - p.currentLabelPair = &dto.LabelPair{Name: proto.String(p.currentToken.String())} - if p.currentLabelPair.GetName() == string(model.MetricNameLabel) { - p.parseError(fmt.Sprintf("label name %q is reserved", model.MetricNameLabel)) - return nil - } - // Special summary/histogram treatment. Don't add 'quantile' and 'le' - // labels to 'real' labels. - if !(p.currentMF.GetType() == dto.MetricType_SUMMARY && p.currentLabelPair.GetName() == model.QuantileLabel) && - !(p.currentMF.GetType() == dto.MetricType_HISTOGRAM && p.currentLabelPair.GetName() == model.BucketLabel) { - p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPair) - } - if p.skipBlankTabIfCurrentBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte != '=' { - p.parseError(fmt.Sprintf("expected '=' after label name, found %q", p.currentByte)) - return nil - } - return p.startLabelValue -} - -// startLabelValue represents the state where the next byte read from p.buf is -// the start of a (quoted) label value (or whitespace leading up to it). -func (p *Parser) startLabelValue() stateFn { - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte != '"' { - p.parseError(fmt.Sprintf("expected '\"' at start of label value, found %q", p.currentByte)) - return nil - } - if p.readTokenAsLabelValue(); p.err != nil { - return nil - } - p.currentLabelPair.Value = proto.String(p.currentToken.String()) - // Special treatment of summaries: - // - Quantile labels are special, will result in dto.Quantile later. - // - Other labels have to be added to currentLabels for signature calculation. - if p.currentMF.GetType() == dto.MetricType_SUMMARY { - if p.currentLabelPair.GetName() == model.QuantileLabel { - if p.currentQuantile, p.err = strconv.ParseFloat(p.currentLabelPair.GetValue(), 64); p.err != nil { - // Create a more helpful error message. - p.parseError(fmt.Sprintf("expected float as value for 'quantile' label, got %q", p.currentLabelPair.GetValue())) - return nil - } - } else { - p.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue() - } - } - // Similar special treatment of histograms. - if p.currentMF.GetType() == dto.MetricType_HISTOGRAM { - if p.currentLabelPair.GetName() == model.BucketLabel { - if p.currentBucket, p.err = strconv.ParseFloat(p.currentLabelPair.GetValue(), 64); p.err != nil { - // Create a more helpful error message. - p.parseError(fmt.Sprintf("expected float as value for 'le' label, got %q", p.currentLabelPair.GetValue())) - return nil - } - } else { - p.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue() - } - } - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - switch p.currentByte { - case ',': - return p.startLabelName - - case '}': - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - return p.readingValue - default: - p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.Value)) - return nil - } -} - -// readingValue represents the state where the last byte read (now in -// p.currentByte) is the first byte of the sample value (i.e. a float). -func (p *Parser) readingValue() stateFn { - // When we are here, we have read all the labels, so for the - // special case of a summary/histogram, we can finally find out - // if the metric already exists. - if p.currentMF.GetType() == dto.MetricType_SUMMARY { - signature := model.LabelsToSignature(p.currentLabels) - if summary := p.summaries[signature]; summary != nil { - p.currentMetric = summary - } else { - p.summaries[signature] = p.currentMetric - p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric) - } - } else if p.currentMF.GetType() == dto.MetricType_HISTOGRAM { - signature := model.LabelsToSignature(p.currentLabels) - if histogram := p.histograms[signature]; histogram != nil { - p.currentMetric = histogram - } else { - p.histograms[signature] = p.currentMetric - p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric) - } - } else { - p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric) - } - if p.readTokenUntilWhitespace(); p.err != nil { - return nil // Unexpected end of input. - } - value, err := strconv.ParseFloat(p.currentToken.String(), 64) - if err != nil { - // Create a more helpful error message. - p.parseError(fmt.Sprintf("expected float as value, got %q", p.currentToken.String())) - return nil - } - switch p.currentMF.GetType() { - case dto.MetricType_COUNTER: - p.currentMetric.Counter = &dto.Counter{Value: proto.Float64(value)} - case dto.MetricType_GAUGE: - p.currentMetric.Gauge = &dto.Gauge{Value: proto.Float64(value)} - case dto.MetricType_UNTYPED: - p.currentMetric.Untyped = &dto.Untyped{Value: proto.Float64(value)} - case dto.MetricType_SUMMARY: - // *sigh* - if p.currentMetric.Summary == nil { - p.currentMetric.Summary = &dto.Summary{} - } - switch { - case p.currentIsSummaryCount: - p.currentMetric.Summary.SampleCount = proto.Uint64(uint64(value)) - case p.currentIsSummarySum: - p.currentMetric.Summary.SampleSum = proto.Float64(value) - case !math.IsNaN(p.currentQuantile): - p.currentMetric.Summary.Quantile = append( - p.currentMetric.Summary.Quantile, - &dto.Quantile{ - Quantile: proto.Float64(p.currentQuantile), - Value: proto.Float64(value), - }, - ) - } - case dto.MetricType_HISTOGRAM: - // *sigh* - if p.currentMetric.Histogram == nil { - p.currentMetric.Histogram = &dto.Histogram{} - } - switch { - case p.currentIsHistogramCount: - p.currentMetric.Histogram.SampleCount = proto.Uint64(uint64(value)) - case p.currentIsHistogramSum: - p.currentMetric.Histogram.SampleSum = proto.Float64(value) - case !math.IsNaN(p.currentBucket): - p.currentMetric.Histogram.Bucket = append( - p.currentMetric.Histogram.Bucket, - &dto.Bucket{ - UpperBound: proto.Float64(p.currentBucket), - CumulativeCount: proto.Uint64(uint64(value)), - }, - ) - } - default: - p.err = fmt.Errorf("unexpected type for metric name %q", p.currentMF.GetName()) - } - if p.currentByte == '\n' { - return p.startOfLine - } - return p.startTimestamp -} - -// startTimestamp represents the state where the next byte read from p.buf is -// the start of the timestamp (or whitespace leading up to it). -func (p *Parser) startTimestamp() stateFn { - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.readTokenUntilWhitespace(); p.err != nil { - return nil // Unexpected end of input. - } - timestamp, err := strconv.ParseInt(p.currentToken.String(), 10, 64) - if err != nil { - // Create a more helpful error message. - p.parseError(fmt.Sprintf("expected integer as timestamp, got %q", p.currentToken.String())) - return nil - } - p.currentMetric.TimestampMs = proto.Int64(timestamp) - if p.readTokenUntilNewline(false); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentToken.Len() > 0 { - p.parseError(fmt.Sprintf("spurious string after timestamp: %q", p.currentToken.String())) - return nil - } - return p.startOfLine -} - -// readingHelp represents the state where the last byte read (now in -// p.currentByte) is the first byte of the docstring after 'HELP'. -func (p *Parser) readingHelp() stateFn { - if p.currentMF.Help != nil { - p.parseError(fmt.Sprintf("second HELP line for metric name %q", p.currentMF.GetName())) - return nil - } - // Rest of line is the docstring. - if p.readTokenUntilNewline(true); p.err != nil { - return nil // Unexpected end of input. - } - p.currentMF.Help = proto.String(p.currentToken.String()) - return p.startOfLine -} - -// readingType represents the state where the last byte read (now in -// p.currentByte) is the first byte of the type hint after 'HELP'. -func (p *Parser) readingType() stateFn { - if p.currentMF.Type != nil { - p.parseError(fmt.Sprintf("second TYPE line for metric name %q, or TYPE reported after samples", p.currentMF.GetName())) - return nil - } - // Rest of line is the type. - if p.readTokenUntilNewline(false); p.err != nil { - return nil // Unexpected end of input. - } - metricType, ok := dto.MetricType_value[strings.ToUpper(p.currentToken.String())] - if !ok { - p.parseError(fmt.Sprintf("unknown metric type %q", p.currentToken.String())) - return nil - } - p.currentMF.Type = dto.MetricType(metricType).Enum() - return p.startOfLine -} - -// parseError sets p.err to a ParseError at the current line with the given -// message. -func (p *Parser) parseError(msg string) { - p.err = ParseError{ - Line: p.lineCount, - Msg: msg, - } -} - -// skipBlankTab reads (and discards) bytes from p.buf until it encounters a byte -// that is neither ' ' nor '\t'. That byte is left in p.currentByte. -func (p *Parser) skipBlankTab() { - for { - if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil || !isBlankOrTab(p.currentByte) { - return - } - } -} - -// skipBlankTabIfCurrentBlankTab works exactly as skipBlankTab but doesn't do -// anything if p.currentByte is neither ' ' nor '\t'. -func (p *Parser) skipBlankTabIfCurrentBlankTab() { - if isBlankOrTab(p.currentByte) { - p.skipBlankTab() - } -} - -// readTokenUntilWhitespace copies bytes from p.buf into p.currentToken. The -// first byte considered is the byte already read (now in p.currentByte). The -// first whitespace byte encountered is still copied into p.currentByte, but not -// into p.currentToken. -func (p *Parser) readTokenUntilWhitespace() { - p.currentToken.Reset() - for p.err == nil && !isBlankOrTab(p.currentByte) && p.currentByte != '\n' { - p.currentToken.WriteByte(p.currentByte) - p.currentByte, p.err = p.buf.ReadByte() - } -} - -// readTokenUntilNewline copies bytes from p.buf into p.currentToken. The first -// byte considered is the byte already read (now in p.currentByte). The first -// newline byte encountered is still copied into p.currentByte, but not into -// p.currentToken. If recognizeEscapeSequence is true, two escape sequences are -// recognized: '\\' tranlates into '\', and '\n' into a line-feed character. All -// other escape sequences are invalid and cause an error. -func (p *Parser) readTokenUntilNewline(recognizeEscapeSequence bool) { - p.currentToken.Reset() - escaped := false - for p.err == nil { - if recognizeEscapeSequence && escaped { - switch p.currentByte { - case '\\': - p.currentToken.WriteByte(p.currentByte) - case 'n': - p.currentToken.WriteByte('\n') - default: - p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) - return - } - escaped = false - } else { - switch p.currentByte { - case '\n': - return - case '\\': - escaped = true - default: - p.currentToken.WriteByte(p.currentByte) - } - } - p.currentByte, p.err = p.buf.ReadByte() - } -} - -// readTokenAsMetricName copies a metric name from p.buf into p.currentToken. -// The first byte considered is the byte already read (now in p.currentByte). -// The first byte not part of a metric name is still copied into p.currentByte, -// but not into p.currentToken. -func (p *Parser) readTokenAsMetricName() { - p.currentToken.Reset() - if !isValidMetricNameStart(p.currentByte) { - return - } - for { - p.currentToken.WriteByte(p.currentByte) - p.currentByte, p.err = p.buf.ReadByte() - if p.err != nil || !isValidMetricNameContinuation(p.currentByte) { - return - } - } -} - -// readTokenAsLabelName copies a label name from p.buf into p.currentToken. -// The first byte considered is the byte already read (now in p.currentByte). -// The first byte not part of a label name is still copied into p.currentByte, -// but not into p.currentToken. -func (p *Parser) readTokenAsLabelName() { - p.currentToken.Reset() - if !isValidLabelNameStart(p.currentByte) { - return - } - for { - p.currentToken.WriteByte(p.currentByte) - p.currentByte, p.err = p.buf.ReadByte() - if p.err != nil || !isValidLabelNameContinuation(p.currentByte) { - return - } - } -} - -// readTokenAsLabelValue copies a label value from p.buf into p.currentToken. -// In contrast to the other 'readTokenAs...' functions, which start with the -// last read byte in p.currentByte, this method ignores p.currentByte and starts -// with reading a new byte from p.buf. The first byte not part of a label value -// is still copied into p.currentByte, but not into p.currentToken. -func (p *Parser) readTokenAsLabelValue() { - p.currentToken.Reset() - escaped := false - for { - if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil { - return - } - if escaped { - switch p.currentByte { - case '"', '\\': - p.currentToken.WriteByte(p.currentByte) - case 'n': - p.currentToken.WriteByte('\n') - default: - p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) - return - } - escaped = false - continue - } - switch p.currentByte { - case '"': - return - case '\n': - p.parseError(fmt.Sprintf("label value %q contains unescaped new-line", p.currentToken.String())) - return - case '\\': - escaped = true - default: - p.currentToken.WriteByte(p.currentByte) - } - } -} - -func (p *Parser) setOrCreateCurrentMF() { - p.currentIsSummaryCount = false - p.currentIsSummarySum = false - p.currentIsHistogramCount = false - p.currentIsHistogramSum = false - name := p.currentToken.String() - if p.currentMF = p.metricFamiliesByName[name]; p.currentMF != nil { - return - } - // Try out if this is a _sum or _count for a summary/histogram. - summaryName := summaryMetricName(name) - if p.currentMF = p.metricFamiliesByName[summaryName]; p.currentMF != nil { - if p.currentMF.GetType() == dto.MetricType_SUMMARY { - if isCount(name) { - p.currentIsSummaryCount = true - } - if isSum(name) { - p.currentIsSummarySum = true - } - return - } - } - histogramName := histogramMetricName(name) - if p.currentMF = p.metricFamiliesByName[histogramName]; p.currentMF != nil { - if p.currentMF.GetType() == dto.MetricType_HISTOGRAM { - if isCount(name) { - p.currentIsHistogramCount = true - } - if isSum(name) { - p.currentIsHistogramSum = true - } - return - } - } - p.currentMF = &dto.MetricFamily{Name: proto.String(name)} - p.metricFamiliesByName[name] = p.currentMF -} - -func isValidLabelNameStart(b byte) bool { - return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' -} - -func isValidLabelNameContinuation(b byte) bool { - return isValidLabelNameStart(b) || (b >= '0' && b <= '9') -} - -func isValidMetricNameStart(b byte) bool { - return isValidLabelNameStart(b) || b == ':' -} - -func isValidMetricNameContinuation(b byte) bool { - return isValidLabelNameContinuation(b) || b == ':' -} - -func isBlankOrTab(b byte) bool { - return b == ' ' || b == '\t' -} - -func isCount(name string) bool { - return len(name) > 6 && name[len(name)-6:] == "_count" -} - -func isSum(name string) bool { - return len(name) > 4 && name[len(name)-4:] == "_sum" -} - -func isBucket(name string) bool { - return len(name) > 7 && name[len(name)-7:] == "_bucket" -} - -func summaryMetricName(name string) string { - switch { - case isCount(name): - return name[:len(name)-6] - case isSum(name): - return name[:len(name)-4] - default: - return name - } -} - -func histogramMetricName(name string) string { - switch { - case isCount(name): - return name[:len(name)-6] - case isSum(name): - return name[:len(name)-4] - case isBucket(name): - return name[:len(name)-7] - default: - return name - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/parse_test.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/text/parse_test.go deleted file mode 100644 index cc3e6470f0a3..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/parse_test.go +++ /dev/null @@ -1,588 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package text - -import ( - "math" - "strings" - "testing" - - "github.com/golang/protobuf/proto" - dto "github.com/prometheus/client_model/go" -) - -var parser Parser - -func testParse(t testing.TB) { - var scenarios = []struct { - in string - out []*dto.MetricFamily - }{ - // 0: Empty lines as input. - { - in: ` - -`, - out: []*dto.MetricFamily{}, - }, - // 1: Minimal case. - { - in: ` -minimal_metric 1.234 -another_metric -3e3 103948 -# Even that: -no_labels{} 3 -# HELP line for non-existing metric will be ignored. -`, - out: []*dto.MetricFamily{ - &dto.MetricFamily{ - Name: proto.String("minimal_metric"), - Type: dto.MetricType_UNTYPED.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Untyped: &dto.Untyped{ - Value: proto.Float64(1.234), - }, - }, - }, - }, - &dto.MetricFamily{ - Name: proto.String("another_metric"), - Type: dto.MetricType_UNTYPED.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Untyped: &dto.Untyped{ - Value: proto.Float64(-3e3), - }, - TimestampMs: proto.Int64(103948), - }, - }, - }, - &dto.MetricFamily{ - Name: proto.String("no_labels"), - Type: dto.MetricType_UNTYPED.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Untyped: &dto.Untyped{ - Value: proto.Float64(3), - }, - }, - }, - }, - }, - }, - // 2: Counters & gauges, docstrings, various whitespace, escape sequences. - { - in: ` -# A normal comment. -# -# TYPE name counter -name{labelname="val1",basename="basevalue"} NaN -name {labelname="val2",basename="base\"v\\al\nue"} 0.23 1234567890 -# HELP name two-line\n doc str\\ing - - # HELP name2 doc str"ing 2 - # TYPE name2 gauge -name2{labelname="val2" ,basename = "basevalue2" } +Inf 54321 -name2{ labelname = "val1" , }-Inf -`, - out: []*dto.MetricFamily{ - &dto.MetricFamily{ - Name: proto.String("name"), - Help: proto.String("two-line\n doc str\\ing"), - Type: dto.MetricType_COUNTER.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("labelname"), - Value: proto.String("val1"), - }, - &dto.LabelPair{ - Name: proto.String("basename"), - Value: proto.String("basevalue"), - }, - }, - Counter: &dto.Counter{ - Value: proto.Float64(math.NaN()), - }, - }, - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("labelname"), - Value: proto.String("val2"), - }, - &dto.LabelPair{ - Name: proto.String("basename"), - Value: proto.String("base\"v\\al\nue"), - }, - }, - Counter: &dto.Counter{ - Value: proto.Float64(.23), - }, - TimestampMs: proto.Int64(1234567890), - }, - }, - }, - &dto.MetricFamily{ - Name: proto.String("name2"), - Help: proto.String("doc str\"ing 2"), - Type: dto.MetricType_GAUGE.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("labelname"), - Value: proto.String("val2"), - }, - &dto.LabelPair{ - Name: proto.String("basename"), - Value: proto.String("basevalue2"), - }, - }, - Gauge: &dto.Gauge{ - Value: proto.Float64(math.Inf(+1)), - }, - TimestampMs: proto.Int64(54321), - }, - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("labelname"), - Value: proto.String("val1"), - }, - }, - Gauge: &dto.Gauge{ - Value: proto.Float64(math.Inf(-1)), - }, - }, - }, - }, - }, - }, - // 3: The evil summary, mixed with other types and funny comments. - { - in: ` -# TYPE my_summary summary -my_summary{n1="val1",quantile="0.5"} 110 -decoy -1 -2 -my_summary{n1="val1",quantile="0.9"} 140 1 -my_summary_count{n1="val1"} 42 -# Latest timestamp wins in case of a summary. -my_summary_sum{n1="val1"} 4711 2 -fake_sum{n1="val1"} 2001 -# TYPE another_summary summary -another_summary_count{n2="val2",n1="val1"} 20 -my_summary_count{n2="val2",n1="val1"} 5 5 -another_summary{n1="val1",n2="val2",quantile=".3"} -1.2 -my_summary_sum{n1="val2"} 08 15 -my_summary{n1="val3", quantile="0.2"} 4711 - my_summary{n1="val1",n2="val2",quantile="-12.34",} NaN -# some -# funny comments -# HELP -# HELP -# HELP my_summary -# HELP my_summary -`, - out: []*dto.MetricFamily{ - &dto.MetricFamily{ - Name: proto.String("fake_sum"), - Type: dto.MetricType_UNTYPED.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("n1"), - Value: proto.String("val1"), - }, - }, - Untyped: &dto.Untyped{ - Value: proto.Float64(2001), - }, - }, - }, - }, - &dto.MetricFamily{ - Name: proto.String("decoy"), - Type: dto.MetricType_UNTYPED.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Untyped: &dto.Untyped{ - Value: proto.Float64(-1), - }, - TimestampMs: proto.Int64(-2), - }, - }, - }, - &dto.MetricFamily{ - Name: proto.String("my_summary"), - Type: dto.MetricType_SUMMARY.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("n1"), - Value: proto.String("val1"), - }, - }, - Summary: &dto.Summary{ - SampleCount: proto.Uint64(42), - SampleSum: proto.Float64(4711), - Quantile: []*dto.Quantile{ - &dto.Quantile{ - Quantile: proto.Float64(0.5), - Value: proto.Float64(110), - }, - &dto.Quantile{ - Quantile: proto.Float64(0.9), - Value: proto.Float64(140), - }, - }, - }, - TimestampMs: proto.Int64(2), - }, - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("n2"), - Value: proto.String("val2"), - }, - &dto.LabelPair{ - Name: proto.String("n1"), - Value: proto.String("val1"), - }, - }, - Summary: &dto.Summary{ - SampleCount: proto.Uint64(5), - Quantile: []*dto.Quantile{ - &dto.Quantile{ - Quantile: proto.Float64(-12.34), - Value: proto.Float64(math.NaN()), - }, - }, - }, - TimestampMs: proto.Int64(5), - }, - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("n1"), - Value: proto.String("val2"), - }, - }, - Summary: &dto.Summary{ - SampleSum: proto.Float64(8), - }, - TimestampMs: proto.Int64(15), - }, - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("n1"), - Value: proto.String("val3"), - }, - }, - Summary: &dto.Summary{ - Quantile: []*dto.Quantile{ - &dto.Quantile{ - Quantile: proto.Float64(0.2), - Value: proto.Float64(4711), - }, - }, - }, - }, - }, - }, - &dto.MetricFamily{ - Name: proto.String("another_summary"), - Type: dto.MetricType_SUMMARY.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Label: []*dto.LabelPair{ - &dto.LabelPair{ - Name: proto.String("n2"), - Value: proto.String("val2"), - }, - &dto.LabelPair{ - Name: proto.String("n1"), - Value: proto.String("val1"), - }, - }, - Summary: &dto.Summary{ - SampleCount: proto.Uint64(20), - Quantile: []*dto.Quantile{ - &dto.Quantile{ - Quantile: proto.Float64(0.3), - Value: proto.Float64(-1.2), - }, - }, - }, - }, - }, - }, - }, - }, - // 4: The histogram. - { - in: ` -# HELP request_duration_microseconds The response latency. -# TYPE request_duration_microseconds histogram -request_duration_microseconds_bucket{le="100"} 123 -request_duration_microseconds_bucket{le="120"} 412 -request_duration_microseconds_bucket{le="144"} 592 -request_duration_microseconds_bucket{le="172.8"} 1524 -request_duration_microseconds_bucket{le="+Inf"} 2693 -request_duration_microseconds_sum 1.7560473e+06 -request_duration_microseconds_count 2693 -`, - out: []*dto.MetricFamily{ - { - Name: proto.String("request_duration_microseconds"), - Help: proto.String("The response latency."), - Type: dto.MetricType_HISTOGRAM.Enum(), - Metric: []*dto.Metric{ - &dto.Metric{ - Histogram: &dto.Histogram{ - SampleCount: proto.Uint64(2693), - SampleSum: proto.Float64(1756047.3), - Bucket: []*dto.Bucket{ - &dto.Bucket{ - UpperBound: proto.Float64(100), - CumulativeCount: proto.Uint64(123), - }, - &dto.Bucket{ - UpperBound: proto.Float64(120), - CumulativeCount: proto.Uint64(412), - }, - &dto.Bucket{ - UpperBound: proto.Float64(144), - CumulativeCount: proto.Uint64(592), - }, - &dto.Bucket{ - UpperBound: proto.Float64(172.8), - CumulativeCount: proto.Uint64(1524), - }, - &dto.Bucket{ - UpperBound: proto.Float64(math.Inf(+1)), - CumulativeCount: proto.Uint64(2693), - }, - }, - }, - }, - }, - }, - }, - }, - } - - for i, scenario := range scenarios { - out, err := parser.TextToMetricFamilies(strings.NewReader(scenario.in)) - if err != nil { - t.Errorf("%d. error: %s", i, err) - continue - } - if expected, got := len(scenario.out), len(out); expected != got { - t.Errorf( - "%d. expected %d MetricFamilies, got %d", - i, expected, got, - ) - } - for _, expected := range scenario.out { - got, ok := out[expected.GetName()] - if !ok { - t.Errorf( - "%d. expected MetricFamily %q, found none", - i, expected.GetName(), - ) - continue - } - if expected.String() != got.String() { - t.Errorf( - "%d. expected MetricFamily %s, got %s", - i, expected, got, - ) - } - } - } -} - -func TestParse(t *testing.T) { - testParse(t) -} - -func BenchmarkParse(b *testing.B) { - for i := 0; i < b.N; i++ { - testParse(b) - } -} - -func testParseError(t testing.TB) { - var scenarios = []struct { - in string - err string - }{ - // 0: No new-line at end of input. - { - in: `bla 3.14`, - err: "EOF", - }, - // 1: Invalid escape sequence in label value. - { - in: `metric{label="\t"} 3.14`, - err: "text format parsing error in line 1: invalid escape sequence", - }, - // 2: Newline in label value. - { - in: ` -metric{label="new -line"} 3.14 -`, - err: `text format parsing error in line 2: label value "new" contains unescaped new-line`, - }, - // 3: - { - in: `metric{@="bla"} 3.14`, - err: "text format parsing error in line 1: invalid label name for metric", - }, - // 4: - { - in: `metric{__name__="bla"} 3.14`, - err: `text format parsing error in line 1: label name "__name__" is reserved`, - }, - // 5: - { - in: `metric{label+="bla"} 3.14`, - err: "text format parsing error in line 1: expected '=' after label name", - }, - // 6: - { - in: `metric{label=bla} 3.14`, - err: "text format parsing error in line 1: expected '\"' at start of label value", - }, - // 7: - { - in: ` -# TYPE metric summary -metric{quantile="bla"} 3.14 -`, - err: "text format parsing error in line 3: expected float as value for 'quantile' label", - }, - // 8: - { - in: `metric{label="bla"+} 3.14`, - err: "text format parsing error in line 1: unexpected end of label value", - }, - // 9: - { - in: `metric{label="bla"} 3.14 2.72 -`, - err: "text format parsing error in line 1: expected integer as timestamp", - }, - // 10: - { - in: `metric{label="bla"} 3.14 2 3 -`, - err: "text format parsing error in line 1: spurious string after timestamp", - }, - // 11: - { - in: `metric{label="bla"} blubb -`, - err: "text format parsing error in line 1: expected float as value", - }, - // 12: - { - in: ` -# HELP metric one -# HELP metric two -`, - err: "text format parsing error in line 3: second HELP line for metric name", - }, - // 13: - { - in: ` -# TYPE metric counter -# TYPE metric untyped -`, - err: `text format parsing error in line 3: second TYPE line for metric name "metric", or TYPE reported after samples`, - }, - // 14: - { - in: ` -metric 4.12 -# TYPE metric counter -`, - err: `text format parsing error in line 3: second TYPE line for metric name "metric", or TYPE reported after samples`, - }, - // 14: - { - in: ` -# TYPE metric bla -`, - err: "text format parsing error in line 2: unknown metric type", - }, - // 15: - { - in: ` -# TYPE met-ric -`, - err: "text format parsing error in line 2: invalid metric name in comment", - }, - // 16: - { - in: `@invalidmetric{label="bla"} 3.14 2`, - err: "text format parsing error in line 1: invalid metric name", - }, - // 17: - { - in: `{label="bla"} 3.14 2`, - err: "text format parsing error in line 1: invalid metric name", - }, - // 18: - { - in: ` -# TYPE metric histogram -metric_bucket{le="bla"} 3.14 -`, - err: "text format parsing error in line 3: expected float as value for 'le' label", - }, - } - - for i, scenario := range scenarios { - _, err := parser.TextToMetricFamilies(strings.NewReader(scenario.in)) - if err == nil { - t.Errorf("%d. expected error, got nil", i) - continue - } - if expected, got := scenario.err, err.Error(); strings.Index(got, expected) != 0 { - t.Errorf( - "%d. expected error starting with %q, got %q", - i, expected, got, - ) - } - } - -} - -func TestParseError(t *testing.T) { - testParseError(t) -} - -func BenchmarkParseError(b *testing.B) { - for i := 0; i < b.N; i++ { - testParseError(b) - } -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/proto.go b/Godeps/_workspace/src/github.com/prometheus/client_golang/text/proto.go deleted file mode 100644 index e82bbb3b4089..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/proto.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package text - -import ( - "fmt" - "io" - - "github.com/golang/protobuf/proto" - "github.com/matttproud/golang_protobuf_extensions/pbutil" - - dto "github.com/prometheus/client_model/go" -) - -// WriteProtoDelimited writes the MetricFamily to the writer in delimited -// protobuf format and returns the number of bytes written and any error -// encountered. -func WriteProtoDelimited(w io.Writer, p *dto.MetricFamily) (int, error) { - return pbutil.WriteDelimited(w, p) -} - -// WriteProtoText writes the MetricFamily to the writer in text format and -// returns the number of bytes written and any error encountered. -func WriteProtoText(w io.Writer, p *dto.MetricFamily) (int, error) { - return fmt.Fprintf(w, "%s\n", proto.MarshalTextString(p)) -} - -// WriteProtoCompactText writes the MetricFamily to the writer in compact text -// format and returns the number of bytes written and any error encountered. -func WriteProtoCompactText(w io.Writer, p *dto.MetricFamily) (int, error) { - return fmt.Fprintf(w, "%s\n", p) -} diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/testdata/protobuf b/Godeps/_workspace/src/github.com/prometheus/client_golang/text/testdata/protobuf deleted file mode 100644 index df48256390c4f08c38e03f14d6cb90c8f5a96137..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8243 zcmeHMO^h5z74BI(_G~#2yW`-+u|v5bcx}8h>yTg(;%u)Rln@dp!G?ewX!my4%rx86 z-RY{1cN`8I;J|?>NC=`JL@WgIATV3bDwzbDnzy0>C{Og^i>e$?oxx7`$?ZnPfvrjn4kB_G(A$Y7DOXWV?w7GQcs~hrL}f+`?;SD zre~vbXm=_7rtX0F+4O{e4c%G_Z+9t!%nhb!8q@e$ojX?|=S%KDLq1-M@Wo$8*do_>e}|zP}gJ57S3=}G@8Z?)f&$5RqmTt zIDYUyElcx;#hj0A;EZ@D$IN7av2UPTt1v@7mNGxKKYEt`hm&HsLUNq;42DDT&<{yx z&T{TYyU_L^4T-(&uEj;8e3yGgA3!@eJf@+&4NBntS-IQwN8PJ!G^e!F4C)v0DkyiT zf^zaL-hw%B<(OyXnCV#<+k!bB_wUzQTXd@0T>M|@6nEo0zj$vP=I(xZ9Ol}W_?Vdt z=#u*s`Y-@eKq&QstngIxroe7df?YuY>Yy{jbVL~$;!}@*5wmDWFwIE9cr&M#apc4Sa@!BF{l&Ji=rxqO3F5a(3AY7Of}T zhtVxs-q2t3deCLgKkBbV!(v!L

&=dr?eqNNA8p8B23&in{EcLc6snK3~Yf<;HG6 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 diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/testdata/text b/Godeps/_workspace/src/github.com/prometheus/client_golang/text/testdata/text deleted file mode 100644 index 1b2b30221313..000000000000 --- a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/testdata/text +++ /dev/null @@ -1,322 +0,0 @@ -# HELP http_request_duration_microseconds The HTTP request latencies in microseconds. -# TYPE http_request_duration_microseconds summary -http_request_duration_microseconds{handler="/",quantile="0.5"} 0 -http_request_duration_microseconds{handler="/",quantile="0.9"} 0 -http_request_duration_microseconds{handler="/",quantile="0.99"} 0 -http_request_duration_microseconds_sum{handler="/"} 0 -http_request_duration_microseconds_count{handler="/"} 0 -http_request_duration_microseconds{handler="/alerts",quantile="0.5"} 0 -http_request_duration_microseconds{handler="/alerts",quantile="0.9"} 0 -http_request_duration_microseconds{handler="/alerts",quantile="0.99"} 0 -http_request_duration_microseconds_sum{handler="/alerts"} 0 -http_request_duration_microseconds_count{handler="/alerts"} 0 -http_request_duration_microseconds{handler="/api/metrics",quantile="0.5"} 0 -http_request_duration_microseconds{handler="/api/metrics",quantile="0.9"} 0 -http_request_duration_microseconds{handler="/api/metrics",quantile="0.99"} 0 -http_request_duration_microseconds_sum{handler="/api/metrics"} 0 -http_request_duration_microseconds_count{handler="/api/metrics"} 0 -http_request_duration_microseconds{handler="/api/query",quantile="0.5"} 0 -http_request_duration_microseconds{handler="/api/query",quantile="0.9"} 0 -http_request_duration_microseconds{handler="/api/query",quantile="0.99"} 0 -http_request_duration_microseconds_sum{handler="/api/query"} 0 -http_request_duration_microseconds_count{handler="/api/query"} 0 -http_request_duration_microseconds{handler="/api/query_range",quantile="0.5"} 0 -http_request_duration_microseconds{handler="/api/query_range",quantile="0.9"} 0 -http_request_duration_microseconds{handler="/api/query_range",quantile="0.99"} 0 -http_request_duration_microseconds_sum{handler="/api/query_range"} 0 -http_request_duration_microseconds_count{handler="/api/query_range"} 0 -http_request_duration_microseconds{handler="/api/targets",quantile="0.5"} 0 -http_request_duration_microseconds{handler="/api/targets",quantile="0.9"} 0 -http_request_duration_microseconds{handler="/api/targets",quantile="0.99"} 0 -http_request_duration_microseconds_sum{handler="/api/targets"} 0 -http_request_duration_microseconds_count{handler="/api/targets"} 0 -http_request_duration_microseconds{handler="/consoles/",quantile="0.5"} 0 -http_request_duration_microseconds{handler="/consoles/",quantile="0.9"} 0 -http_request_duration_microseconds{handler="/consoles/",quantile="0.99"} 0 -http_request_duration_microseconds_sum{handler="/consoles/"} 0 -http_request_duration_microseconds_count{handler="/consoles/"} 0 -http_request_duration_microseconds{handler="/graph",quantile="0.5"} 0 -http_request_duration_microseconds{handler="/graph",quantile="0.9"} 0 -http_request_duration_microseconds{handler="/graph",quantile="0.99"} 0 -http_request_duration_microseconds_sum{handler="/graph"} 0 -http_request_duration_microseconds_count{handler="/graph"} 0 -http_request_duration_microseconds{handler="/heap",quantile="0.5"} 0 -http_request_duration_microseconds{handler="/heap",quantile="0.9"} 0 -http_request_duration_microseconds{handler="/heap",quantile="0.99"} 0 -http_request_duration_microseconds_sum{handler="/heap"} 0 -http_request_duration_microseconds_count{handler="/heap"} 0 -http_request_duration_microseconds{handler="/static/",quantile="0.5"} 0 -http_request_duration_microseconds{handler="/static/",quantile="0.9"} 0 -http_request_duration_microseconds{handler="/static/",quantile="0.99"} 0 -http_request_duration_microseconds_sum{handler="/static/"} 0 -http_request_duration_microseconds_count{handler="/static/"} 0 -http_request_duration_microseconds{handler="prometheus",quantile="0.5"} 1307.275 -http_request_duration_microseconds{handler="prometheus",quantile="0.9"} 1858.632 -http_request_duration_microseconds{handler="prometheus",quantile="0.99"} 3087.384 -http_request_duration_microseconds_sum{handler="prometheus"} 179886.5000000001 -http_request_duration_microseconds_count{handler="prometheus"} 119 -# HELP http_request_size_bytes The HTTP request sizes in bytes. -# TYPE http_request_size_bytes summary -http_request_size_bytes{handler="/",quantile="0.5"} 0 -http_request_size_bytes{handler="/",quantile="0.9"} 0 -http_request_size_bytes{handler="/",quantile="0.99"} 0 -http_request_size_bytes_sum{handler="/"} 0 -http_request_size_bytes_count{handler="/"} 0 -http_request_size_bytes{handler="/alerts",quantile="0.5"} 0 -http_request_size_bytes{handler="/alerts",quantile="0.9"} 0 -http_request_size_bytes{handler="/alerts",quantile="0.99"} 0 -http_request_size_bytes_sum{handler="/alerts"} 0 -http_request_size_bytes_count{handler="/alerts"} 0 -http_request_size_bytes{handler="/api/metrics",quantile="0.5"} 0 -http_request_size_bytes{handler="/api/metrics",quantile="0.9"} 0 -http_request_size_bytes{handler="/api/metrics",quantile="0.99"} 0 -http_request_size_bytes_sum{handler="/api/metrics"} 0 -http_request_size_bytes_count{handler="/api/metrics"} 0 -http_request_size_bytes{handler="/api/query",quantile="0.5"} 0 -http_request_size_bytes{handler="/api/query",quantile="0.9"} 0 -http_request_size_bytes{handler="/api/query",quantile="0.99"} 0 -http_request_size_bytes_sum{handler="/api/query"} 0 -http_request_size_bytes_count{handler="/api/query"} 0 -http_request_size_bytes{handler="/api/query_range",quantile="0.5"} 0 -http_request_size_bytes{handler="/api/query_range",quantile="0.9"} 0 -http_request_size_bytes{handler="/api/query_range",quantile="0.99"} 0 -http_request_size_bytes_sum{handler="/api/query_range"} 0 -http_request_size_bytes_count{handler="/api/query_range"} 0 -http_request_size_bytes{handler="/api/targets",quantile="0.5"} 0 -http_request_size_bytes{handler="/api/targets",quantile="0.9"} 0 -http_request_size_bytes{handler="/api/targets",quantile="0.99"} 0 -http_request_size_bytes_sum{handler="/api/targets"} 0 -http_request_size_bytes_count{handler="/api/targets"} 0 -http_request_size_bytes{handler="/consoles/",quantile="0.5"} 0 -http_request_size_bytes{handler="/consoles/",quantile="0.9"} 0 -http_request_size_bytes{handler="/consoles/",quantile="0.99"} 0 -http_request_size_bytes_sum{handler="/consoles/"} 0 -http_request_size_bytes_count{handler="/consoles/"} 0 -http_request_size_bytes{handler="/graph",quantile="0.5"} 0 -http_request_size_bytes{handler="/graph",quantile="0.9"} 0 -http_request_size_bytes{handler="/graph",quantile="0.99"} 0 -http_request_size_bytes_sum{handler="/graph"} 0 -http_request_size_bytes_count{handler="/graph"} 0 -http_request_size_bytes{handler="/heap",quantile="0.5"} 0 -http_request_size_bytes{handler="/heap",quantile="0.9"} 0 -http_request_size_bytes{handler="/heap",quantile="0.99"} 0 -http_request_size_bytes_sum{handler="/heap"} 0 -http_request_size_bytes_count{handler="/heap"} 0 -http_request_size_bytes{handler="/static/",quantile="0.5"} 0 -http_request_size_bytes{handler="/static/",quantile="0.9"} 0 -http_request_size_bytes{handler="/static/",quantile="0.99"} 0 -http_request_size_bytes_sum{handler="/static/"} 0 -http_request_size_bytes_count{handler="/static/"} 0 -http_request_size_bytes{handler="prometheus",quantile="0.5"} 291 -http_request_size_bytes{handler="prometheus",quantile="0.9"} 291 -http_request_size_bytes{handler="prometheus",quantile="0.99"} 291 -http_request_size_bytes_sum{handler="prometheus"} 34488 -http_request_size_bytes_count{handler="prometheus"} 119 -# HELP http_requests_total Total number of HTTP requests made. -# TYPE http_requests_total counter -http_requests_total{code="200",handler="prometheus",method="get"} 119 -# HELP http_response_size_bytes The HTTP response sizes in bytes. -# TYPE http_response_size_bytes summary -http_response_size_bytes{handler="/",quantile="0.5"} 0 -http_response_size_bytes{handler="/",quantile="0.9"} 0 -http_response_size_bytes{handler="/",quantile="0.99"} 0 -http_response_size_bytes_sum{handler="/"} 0 -http_response_size_bytes_count{handler="/"} 0 -http_response_size_bytes{handler="/alerts",quantile="0.5"} 0 -http_response_size_bytes{handler="/alerts",quantile="0.9"} 0 -http_response_size_bytes{handler="/alerts",quantile="0.99"} 0 -http_response_size_bytes_sum{handler="/alerts"} 0 -http_response_size_bytes_count{handler="/alerts"} 0 -http_response_size_bytes{handler="/api/metrics",quantile="0.5"} 0 -http_response_size_bytes{handler="/api/metrics",quantile="0.9"} 0 -http_response_size_bytes{handler="/api/metrics",quantile="0.99"} 0 -http_response_size_bytes_sum{handler="/api/metrics"} 0 -http_response_size_bytes_count{handler="/api/metrics"} 0 -http_response_size_bytes{handler="/api/query",quantile="0.5"} 0 -http_response_size_bytes{handler="/api/query",quantile="0.9"} 0 -http_response_size_bytes{handler="/api/query",quantile="0.99"} 0 -http_response_size_bytes_sum{handler="/api/query"} 0 -http_response_size_bytes_count{handler="/api/query"} 0 -http_response_size_bytes{handler="/api/query_range",quantile="0.5"} 0 -http_response_size_bytes{handler="/api/query_range",quantile="0.9"} 0 -http_response_size_bytes{handler="/api/query_range",quantile="0.99"} 0 -http_response_size_bytes_sum{handler="/api/query_range"} 0 -http_response_size_bytes_count{handler="/api/query_range"} 0 -http_response_size_bytes{handler="/api/targets",quantile="0.5"} 0 -http_response_size_bytes{handler="/api/targets",quantile="0.9"} 0 -http_response_size_bytes{handler="/api/targets",quantile="0.99"} 0 -http_response_size_bytes_sum{handler="/api/targets"} 0 -http_response_size_bytes_count{handler="/api/targets"} 0 -http_response_size_bytes{handler="/consoles/",quantile="0.5"} 0 -http_response_size_bytes{handler="/consoles/",quantile="0.9"} 0 -http_response_size_bytes{handler="/consoles/",quantile="0.99"} 0 -http_response_size_bytes_sum{handler="/consoles/"} 0 -http_response_size_bytes_count{handler="/consoles/"} 0 -http_response_size_bytes{handler="/graph",quantile="0.5"} 0 -http_response_size_bytes{handler="/graph",quantile="0.9"} 0 -http_response_size_bytes{handler="/graph",quantile="0.99"} 0 -http_response_size_bytes_sum{handler="/graph"} 0 -http_response_size_bytes_count{handler="/graph"} 0 -http_response_size_bytes{handler="/heap",quantile="0.5"} 0 -http_response_size_bytes{handler="/heap",quantile="0.9"} 0 -http_response_size_bytes{handler="/heap",quantile="0.99"} 0 -http_response_size_bytes_sum{handler="/heap"} 0 -http_response_size_bytes_count{handler="/heap"} 0 -http_response_size_bytes{handler="/static/",quantile="0.5"} 0 -http_response_size_bytes{handler="/static/",quantile="0.9"} 0 -http_response_size_bytes{handler="/static/",quantile="0.99"} 0 -http_response_size_bytes_sum{handler="/static/"} 0 -http_response_size_bytes_count{handler="/static/"} 0 -http_response_size_bytes{handler="prometheus",quantile="0.5"} 2049 -http_response_size_bytes{handler="prometheus",quantile="0.9"} 2058 -http_response_size_bytes{handler="prometheus",quantile="0.99"} 2064 -http_response_size_bytes_sum{handler="prometheus"} 247001 -http_response_size_bytes_count{handler="prometheus"} 119 -# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds. -# TYPE process_cpu_seconds_total counter -process_cpu_seconds_total 0.55 -# HELP process_goroutines Number of goroutines that currently exist. -# TYPE process_goroutines gauge -process_goroutines 70 -# HELP process_max_fds Maximum number of open file descriptors. -# TYPE process_max_fds gauge -process_max_fds 8192 -# HELP process_open_fds Number of open file descriptors. -# TYPE process_open_fds gauge -process_open_fds 29 -# HELP process_resident_memory_bytes Resident memory size in bytes. -# TYPE process_resident_memory_bytes gauge -process_resident_memory_bytes 5.3870592e+07 -# HELP process_start_time_seconds Start time of the process since unix epoch in seconds. -# TYPE process_start_time_seconds gauge -process_start_time_seconds 1.42236894836e+09 -# HELP process_virtual_memory_bytes Virtual memory size in bytes. -# TYPE process_virtual_memory_bytes gauge -process_virtual_memory_bytes 5.41478912e+08 -# HELP prometheus_dns_sd_lookup_failures_total The number of DNS-SD lookup failures. -# TYPE prometheus_dns_sd_lookup_failures_total counter -prometheus_dns_sd_lookup_failures_total 0 -# HELP prometheus_dns_sd_lookups_total The number of DNS-SD lookups. -# TYPE prometheus_dns_sd_lookups_total counter -prometheus_dns_sd_lookups_total 7 -# HELP prometheus_evaluator_duration_milliseconds The duration for all evaluations to execute. -# TYPE prometheus_evaluator_duration_milliseconds summary -prometheus_evaluator_duration_milliseconds{quantile="0.01"} 0 -prometheus_evaluator_duration_milliseconds{quantile="0.05"} 0 -prometheus_evaluator_duration_milliseconds{quantile="0.5"} 0 -prometheus_evaluator_duration_milliseconds{quantile="0.9"} 1 -prometheus_evaluator_duration_milliseconds{quantile="0.99"} 1 -prometheus_evaluator_duration_milliseconds_sum 12 -prometheus_evaluator_duration_milliseconds_count 23 -# HELP prometheus_local_storage_checkpoint_duration_milliseconds The duration (in milliseconds) it took to checkpoint in-memory metrics and head chunks. -# TYPE prometheus_local_storage_checkpoint_duration_milliseconds gauge -prometheus_local_storage_checkpoint_duration_milliseconds 0 -# HELP prometheus_local_storage_chunk_ops_total The total number of chunk operations by their type. -# TYPE prometheus_local_storage_chunk_ops_total counter -prometheus_local_storage_chunk_ops_total{type="create"} 598 -prometheus_local_storage_chunk_ops_total{type="persist"} 174 -prometheus_local_storage_chunk_ops_total{type="pin"} 920 -prometheus_local_storage_chunk_ops_total{type="transcode"} 415 -prometheus_local_storage_chunk_ops_total{type="unpin"} 920 -# HELP prometheus_local_storage_indexing_batch_latency_milliseconds Quantiles for batch indexing latencies in milliseconds. -# TYPE prometheus_local_storage_indexing_batch_latency_milliseconds summary -prometheus_local_storage_indexing_batch_latency_milliseconds{quantile="0.5"} 0 -prometheus_local_storage_indexing_batch_latency_milliseconds{quantile="0.9"} 0 -prometheus_local_storage_indexing_batch_latency_milliseconds{quantile="0.99"} 0 -prometheus_local_storage_indexing_batch_latency_milliseconds_sum 0 -prometheus_local_storage_indexing_batch_latency_milliseconds_count 1 -# HELP prometheus_local_storage_indexing_batch_sizes Quantiles for indexing batch sizes (number of metrics per batch). -# TYPE prometheus_local_storage_indexing_batch_sizes summary -prometheus_local_storage_indexing_batch_sizes{quantile="0.5"} 2 -prometheus_local_storage_indexing_batch_sizes{quantile="0.9"} 2 -prometheus_local_storage_indexing_batch_sizes{quantile="0.99"} 2 -prometheus_local_storage_indexing_batch_sizes_sum 2 -prometheus_local_storage_indexing_batch_sizes_count 1 -# HELP prometheus_local_storage_indexing_queue_capacity The capacity of the indexing queue. -# TYPE prometheus_local_storage_indexing_queue_capacity gauge -prometheus_local_storage_indexing_queue_capacity 16384 -# HELP prometheus_local_storage_indexing_queue_length The number of metrics waiting to be indexed. -# TYPE prometheus_local_storage_indexing_queue_length gauge -prometheus_local_storage_indexing_queue_length 0 -# HELP prometheus_local_storage_ingested_samples_total The total number of samples ingested. -# TYPE prometheus_local_storage_ingested_samples_total counter -prometheus_local_storage_ingested_samples_total 30473 -# HELP prometheus_local_storage_invalid_preload_requests_total The total number of preload requests referring to a non-existent series. This is an indication of outdated label indexes. -# TYPE prometheus_local_storage_invalid_preload_requests_total counter -prometheus_local_storage_invalid_preload_requests_total 0 -# HELP prometheus_local_storage_memory_chunkdescs The current number of chunk descriptors in memory. -# TYPE prometheus_local_storage_memory_chunkdescs gauge -prometheus_local_storage_memory_chunkdescs 1059 -# HELP prometheus_local_storage_memory_chunks The current number of chunks in memory, excluding cloned chunks (i.e. chunks without a descriptor). -# TYPE prometheus_local_storage_memory_chunks gauge -prometheus_local_storage_memory_chunks 1020 -# HELP prometheus_local_storage_memory_series The current number of series in memory. -# TYPE prometheus_local_storage_memory_series gauge -prometheus_local_storage_memory_series 424 -# HELP prometheus_local_storage_persist_latency_microseconds A summary of latencies for persisting each chunk. -# TYPE prometheus_local_storage_persist_latency_microseconds summary -prometheus_local_storage_persist_latency_microseconds{quantile="0.5"} 30.377 -prometheus_local_storage_persist_latency_microseconds{quantile="0.9"} 203.539 -prometheus_local_storage_persist_latency_microseconds{quantile="0.99"} 2626.463 -prometheus_local_storage_persist_latency_microseconds_sum 20424.415 -prometheus_local_storage_persist_latency_microseconds_count 174 -# HELP prometheus_local_storage_persist_queue_capacity The total capacity of the persist queue. -# TYPE prometheus_local_storage_persist_queue_capacity gauge -prometheus_local_storage_persist_queue_capacity 1024 -# HELP prometheus_local_storage_persist_queue_length The current number of chunks waiting in the persist queue. -# TYPE prometheus_local_storage_persist_queue_length gauge -prometheus_local_storage_persist_queue_length 0 -# HELP prometheus_local_storage_series_ops_total The total number of series operations by their type. -# TYPE prometheus_local_storage_series_ops_total counter -prometheus_local_storage_series_ops_total{type="create"} 2 -prometheus_local_storage_series_ops_total{type="maintenance_in_memory"} 11 -# HELP prometheus_notifications_latency_milliseconds Latency quantiles for sending alert notifications (not including dropped notifications). -# TYPE prometheus_notifications_latency_milliseconds summary -prometheus_notifications_latency_milliseconds{quantile="0.5"} 0 -prometheus_notifications_latency_milliseconds{quantile="0.9"} 0 -prometheus_notifications_latency_milliseconds{quantile="0.99"} 0 -prometheus_notifications_latency_milliseconds_sum 0 -prometheus_notifications_latency_milliseconds_count 0 -# HELP prometheus_notifications_queue_capacity The capacity of the alert notifications queue. -# TYPE prometheus_notifications_queue_capacity gauge -prometheus_notifications_queue_capacity 100 -# HELP prometheus_notifications_queue_length The number of alert notifications in the queue. -# TYPE prometheus_notifications_queue_length gauge -prometheus_notifications_queue_length 0 -# HELP prometheus_rule_evaluation_duration_milliseconds The duration for a rule to execute. -# TYPE prometheus_rule_evaluation_duration_milliseconds summary -prometheus_rule_evaluation_duration_milliseconds{rule_type="alerting",quantile="0.5"} 0 -prometheus_rule_evaluation_duration_milliseconds{rule_type="alerting",quantile="0.9"} 0 -prometheus_rule_evaluation_duration_milliseconds{rule_type="alerting",quantile="0.99"} 2 -prometheus_rule_evaluation_duration_milliseconds_sum{rule_type="alerting"} 12 -prometheus_rule_evaluation_duration_milliseconds_count{rule_type="alerting"} 115 -prometheus_rule_evaluation_duration_milliseconds{rule_type="recording",quantile="0.5"} 0 -prometheus_rule_evaluation_duration_milliseconds{rule_type="recording",quantile="0.9"} 0 -prometheus_rule_evaluation_duration_milliseconds{rule_type="recording",quantile="0.99"} 3 -prometheus_rule_evaluation_duration_milliseconds_sum{rule_type="recording"} 15 -prometheus_rule_evaluation_duration_milliseconds_count{rule_type="recording"} 115 -# HELP prometheus_rule_evaluation_failures_total The total number of rule evaluation failures. -# TYPE prometheus_rule_evaluation_failures_total counter -prometheus_rule_evaluation_failures_total 0 -# HELP prometheus_samples_queue_capacity Capacity of the queue for unwritten samples. -# TYPE prometheus_samples_queue_capacity gauge -prometheus_samples_queue_capacity 4096 -# HELP prometheus_samples_queue_length Current number of items in the queue for unwritten samples. Each item comprises all samples exposed by one target as one metric family (i.e. metrics of the same name). -# TYPE prometheus_samples_queue_length gauge -prometheus_samples_queue_length 0 -# HELP prometheus_target_interval_length_seconds Actual intervals between scrapes. -# TYPE prometheus_target_interval_length_seconds summary -prometheus_target_interval_length_seconds{interval="15s",quantile="0.01"} 14 -prometheus_target_interval_length_seconds{interval="15s",quantile="0.05"} 14 -prometheus_target_interval_length_seconds{interval="15s",quantile="0.5"} 15 -prometheus_target_interval_length_seconds{interval="15s",quantile="0.9"} 15 -prometheus_target_interval_length_seconds{interval="15s",quantile="0.99"} 15 -prometheus_target_interval_length_seconds_sum{interval="15s"} 175 -prometheus_target_interval_length_seconds_count{interval="15s"} 12 -prometheus_target_interval_length_seconds{interval="1s",quantile="0.01"} 0 -prometheus_target_interval_length_seconds{interval="1s",quantile="0.05"} 0 -prometheus_target_interval_length_seconds{interval="1s",quantile="0.5"} 0 -prometheus_target_interval_length_seconds{interval="1s",quantile="0.9"} 1 -prometheus_target_interval_length_seconds{interval="1s",quantile="0.99"} 1 -prometheus_target_interval_length_seconds_sum{interval="1s"} 55 -prometheus_target_interval_length_seconds_count{interval="1s"} 117 diff --git a/Godeps/_workspace/src/github.com/prometheus/client_golang/text/testdata/text.gz b/Godeps/_workspace/src/github.com/prometheus/client_golang/text/testdata/text.gz deleted file mode 100644 index 46de5995ad79083b3e4a47f74936ac9382bc4ee5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2595 zcmV+;3f%P{iwFoRp~qAJ19WA0bO5zmU6Y$Q7Jctuq3U^=sZBg!8{0he!&D|!^Dvvr zZhE(Bo+ujBHWds6#H77l^WXPMh&CSrT?tPfk~HWXu8yRudj$Oh`R(KHpUH`_A}Hy% znpP}`>oR0Xo(1P5D)Wj)c@|gX@kGgQkB^^;Y(~hn1)FL(N;uct7JQ(8XU|9t=MTODRBN$JDAv-0l$BF+*5e=z};A%O07S&*nGuQO(j z>mWk-hgFMpQ_)zcr=+peP;yx+X@u_Lisa`rWn~iGK-4KN8)YZCY~}3`+G=b}F#to$ z@^TZI6-<^QtC$u@+|Vr$*n~g@4azV((%Xrw;#(rMl5eTtl60x;Ml=Hg7M4ePi_AR5 zWhuIvYk}Y`;R3PEC^}&Hxyn;oEiW7(g{&$T zOGz6lOF2!z9oUJ6#bPDLBo;y{NGx>}OqMblU^}Ra!R=`IYFF}DXsPD0l(QwXRMZT9 z1r}uvMcj$jioMF+IQ!Ll@7;uu%iOdxk_}6~P&?NkP;OYDNzoz`|$Y!B|ny zj%reuNgp&L4FZEROl#k@C-4^&Xc%S;&}O?m9I$#}oK6+6oP{ZQ6n|&+`H7Y!f9^S+ zik!okDveGH7f+_;o#NhWl*iERwd35sQ%b}ClgAJDu!kt)tP04Sbi$G~H#MGY%rG!z zqXsxvhKKo&h=>3i+chf&BMA|P4I`hz zdEunP01Z8x1s*LK%C+ePQyMV6TsWA4aWllCMbcU~oj@ZerWZ#K!MiszC|VYsf77Wl z^kaHav$XN*QGgD`PAaTJbBuMY-<^l{GCUqB&znByImP&6F7EmE+SM- zG~zI6k{C1#&h(r^E!3FXf6J?+xhl-@*c;Dt^g~d$@m8C|-tqi3{fDz3h6angWC5RM z?ff8L_@!p%fhI7K+r|)K7Ew}X$qS)H9-Zdqq=L8~tfGOt+OF4|-ND};Ham!RB;=n- z$?7oe_wT>WMVyREhJIkmCf;i6ZubY@h)3QL=l$J;%lU>F*wNp=&v19AS=VH;wR|< z-@2YDyw0vq){SG5#ZZ7{$KWYs(J5$t&FIpf4gZo0v=UiTG$bu<_=`zbn0|aQ&sJnn zW0LvYwv5idG2L=Lkr5YCG%3r8GOT)1XpqC*=1qVZ1-Edq2tU(b%|O@)2gek|0d>K2mV`aZrWlBBgViv1~zF z2&N}Wa_ufWf!jFSy}ss3GN|5?I4DY*=3zW~bFJu^YHI)jHOivo$`BSk}~3WQMl-poEuyZ_IjM|Hr)S#9?F8;~_e#+#M5@o&K<=yvPf zYP;Lm@ii5L1H-$T^%k=nvVz#-r--72keP8%NJs#-j+o%rO!WyAtW?t;b!v#o6xEgz zuy7am5LZwrG5RFbEPaiwm-)fo*N>i}-5iIAp|hVUfG42mFo8#AVHWYNSEfGkrbQuA zmb2tp)(Dl_r~cktB;R`Gr=pqIj>Kn1q(=iDDCdVk?T!_fc~QWY)oY~Omk`k?a-kkI zZ<7u2BOhyuw;&ihUj(MfWU8gn2O}(yYLq9}_$>QqbGb~fCu&~_)A$1DZ8VQXlDCqq6>I+Si%&LP2WB)_$3lw3ADGN z_NDAQ? z{(8`ap~;dXj Date: Thu, 15 Oct 2015 09:29:25 -0400 Subject: [PATCH 02/35] bump(github.com/fsouza/go-dockerclient): 1399676f53e6ccf46e0bf00751b21bed329bc60e --- Godeps/Godeps.json | 2 +- .../fsouza/go-dockerclient/.gitignore | 2 + .../fsouza/go-dockerclient/.travis.yml | 6 +- .../github.com/fsouza/go-dockerclient/AUTHORS | 7 + .../fsouza/go-dockerclient/README.markdown | 2 +- .../github.com/fsouza/go-dockerclient/auth.go | 6 +- .../fsouza/go-dockerclient/build_test.go | 10 + .../fsouza/go-dockerclient/client.go | 144 ++++++---- .../fsouza/go-dockerclient/client_test.go | 44 ++- .../fsouza/go-dockerclient/container.go | 260 +++++++++++------- .../fsouza/go-dockerclient/container_test.go | 54 +++- .../fsouza/go-dockerclient/event.go | 5 +- .../github.com/fsouza/go-dockerclient/exec.go | 41 +-- .../fsouza/go-dockerclient/image.go | 80 +++--- .../fsouza/go-dockerclient/image_test.go | 4 + .../github.com/fsouza/go-dockerclient/misc.go | 16 +- .../fsouza/go-dockerclient/network.go | 33 +-- .../go-dockerclient/testing/data/symlink | 1 - .../fsouza/go-dockerclient/testing/server.go | 12 +- .../github.com/fsouza/go-dockerclient/tls.go | 4 - .../fsouza/go-dockerclient/volume.go | 41 +-- 21 files changed, 501 insertions(+), 273 deletions(-) create mode 100644 Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.gitignore delete mode 120000 Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/symlink diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 8f3053c91a97..157fd28f8b35 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -406,7 +406,7 @@ }, { "ImportPath": "github.com/fsouza/go-dockerclient", - "Rev": "76fd6c68cf24c48ee6a2b25def997182a29f940e" + "Rev": "1399676f53e6ccf46e0bf00751b21bed329bc60e" }, { "ImportPath": "github.com/garyburd/redigo/internal", diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.gitignore b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.gitignore new file mode 100644 index 000000000000..5f6b48eae0d6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.gitignore @@ -0,0 +1,2 @@ +# temporary symlink for testing +testing/data/symlink diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.travis.yml b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.travis.yml index e03407b3e79b..927a999f0841 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.travis.yml +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.travis.yml @@ -1,9 +1,9 @@ language: go sudo: false go: - - 1.3.1 - - 1.4 - - 1.5 + - 1.3.3 + - 1.4.2 + - 1.5.1 - tip env: - GOARCH=amd64 diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/AUTHORS b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/AUTHORS index a149a7723c82..7abd05b14c21 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/AUTHORS +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/AUTHORS @@ -1,6 +1,7 @@ # This is the official list of go-dockerclient authors for copyright purposes. Adam Bell-Hanssen +Adrien Kohlbecker Aldrin Leal Andreas Jaekle Andrews Medina @@ -11,6 +12,7 @@ Ben McCann Brendan Fosberry Brian Lalor Brian Palmer +Bryan Boreham Burke Libbey Carlos Diaz-Padron Cesar Wong @@ -28,6 +30,7 @@ David Huie Dawn Chen Dinesh Subhraveti Ed +Erez Horev Eric Anderson Ewout Prangsma Fabio Rehm @@ -45,6 +48,7 @@ Jawher Moussa Jean-Baptiste Dalido Jeff Mitchell Jeffrey Hulten +Jen Andre Johan Euphrosine Kamil Domanski Karan Misra @@ -52,6 +56,7 @@ Kim, Hirokuni Kyle Allan Liron Levin Liu Peng +Lorenz Leutgeb Lucas Clemente Lucas Weiblen Mantas Matelis @@ -75,7 +80,9 @@ Rob Miller Robert Williamson Salvador Gironès Sam Rijs +Sami Wagiaalla Samuel Karp +Silas Sewell Simon Eskildsen Simon Menke Skolos diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/README.markdown b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/README.markdown index a124d0b45e0f..9f3c0ca1bacd 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/README.markdown +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/README.markdown @@ -5,7 +5,7 @@ [![GoDoc](https://img.shields.io/badge/api-Godoc-blue.svg?style=flat-square)](https://godoc.org/github.com/fsouza/go-dockerclient) This package presents a client for the Docker remote API. It also provides -support for the extensions in the [Swarm API](https://docs.docker.com/swarm/API/). +support for the extensions in the [Swarm API](https://docs.docker.com/swarm/api/swarm-api/). This package also provides support for docker's network API, which is a simple passthrough to the libnetwork remote API. Note that docker's network API is diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/auth.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/auth.go index d2af8780c2a7..30e3af3eb7a1 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/auth.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/auth.go @@ -127,12 +127,10 @@ func (c *Client) AuthCheck(conf *AuthConfiguration) error { if conf == nil { return fmt.Errorf("conf is nil") } - body, statusCode, err := c.do("POST", "/auth", doOptions{data: conf}) + resp, err := c.do("POST", "/auth", doOptions{data: conf}) if err != nil { return err } - if statusCode > 400 { - return fmt.Errorf("auth error (%d): %s", statusCode, body) - } + resp.Body.Close() return nil } diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/build_test.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/build_test.go index a4864db83703..c9640f20571e 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/build_test.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/build_test.go @@ -35,6 +35,16 @@ func TestBuildImageMultipleContextsError(t *testing.T) { func TestBuildImageContextDirDockerignoreParsing(t *testing.T) { fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK} client := newTestClient(fakeRT) + + if err := os.Symlink("doesnotexist", "testing/data/symlink"); err != nil { + t.Errorf("error creating symlink on demand: %s", err) + } + defer func() { + if err := os.Remove("testing/data/symlink"); err != nil { + t.Errorf("error removing symlink on demand: %s", err) + } + }() + var buf bytes.Buffer opts := BuildImageOptions{ Name: "testImage", diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client.go index c3d86f40b8af..0129eb334f4b 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client.go @@ -130,6 +130,7 @@ type Client struct { SkipServerVersionCheck bool HTTPClient *http.Client TLSConfig *tls.Config + Dialer *net.Dialer endpoint string endpointURL *url.URL @@ -137,6 +138,7 @@ type Client struct { requestedAPIVersion APIVersion serverAPIVersion APIVersion expectedAPIVersion APIVersion + unixHTTPClient *http.Client } // NewClient returns a Client instance ready for communication with the given @@ -191,6 +193,7 @@ func NewVersionedClient(endpoint string, apiVersionString string) (*Client, erro } return &Client{ HTTPClient: http.DefaultClient, + Dialer: &net.Dialer{}, endpoint: endpoint, endpointURL: u, eventMonitor: new(eventMonitoringState), @@ -302,6 +305,7 @@ func NewVersionedTLSClientFromBytes(endpoint string, certPEMBlock, keyPEMBlock, return &Client{ HTTPClient: &http.Client{Transport: tr}, TLSConfig: tlsConfig, + Dialer: &net.Dialer{}, endpoint: endpoint, endpointURL: u, eventMonitor: new(eventMonitoringState), @@ -326,32 +330,40 @@ func (c *Client) checkAPIVersion() error { return nil } +// Endpoint returns the current endpoint. It's useful for getting the endpoint +// when using functions that get this data from the environment (like +// NewClientFromEnv. +func (c *Client) Endpoint() string { + return c.endpoint +} + // Ping pings the docker server // // See https://goo.gl/kQCfJj for more details. func (c *Client) Ping() error { path := "/_ping" - body, status, err := c.do("GET", path, doOptions{}) + resp, err := c.do("GET", path, doOptions{}) if err != nil { return err } - if status != http.StatusOK { - return newError(status, body) + if resp.StatusCode != http.StatusOK { + return newError(resp) } + resp.Body.Close() return nil } func (c *Client) getServerAPIVersionString() (version string, err error) { - body, status, err := c.do("GET", "/version", doOptions{}) + resp, err := c.do("GET", "/version", doOptions{}) if err != nil { return "", err } - if status != http.StatusOK { - return "", fmt.Errorf("Received unexpected status %d while trying to retrieve the server version", status) + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("Received unexpected status %d while trying to retrieve the server version", resp.StatusCode) } var versionResponse map[string]interface{} - err = json.Unmarshal(body, &versionResponse) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&versionResponse); err != nil { return "", err } if version, ok := (versionResponse["ApiVersion"]).(string); ok { @@ -365,24 +377,35 @@ type doOptions struct { forceJSON bool } -func (c *Client) do(method, path string, doOptions doOptions) ([]byte, int, error) { +func (c *Client) do(method, path string, doOptions doOptions) (*http.Response, error) { var params io.Reader if doOptions.data != nil || doOptions.forceJSON { buf, err := json.Marshal(doOptions.data) if err != nil { - return nil, -1, err + return nil, err } params = bytes.NewBuffer(buf) } if path != "/version" && !c.SkipServerVersionCheck && c.expectedAPIVersion == nil { err := c.checkAPIVersion() if err != nil { - return nil, -1, err + return nil, err } } - req, err := http.NewRequest(method, c.getURL(path), params) + + httpClient := c.HTTPClient + protocol := c.endpointURL.Scheme + var u string + if protocol == "unix" { + httpClient = c.unixClient() + u = c.getFakeUnixURL(path) + } else { + u = c.getURL(path) + } + + req, err := http.NewRequest(method, u, params) if err != nil { - return nil, -1, err + return nil, err } req.Header.Set("User-Agent", userAgent) if doOptions.data != nil { @@ -390,40 +413,19 @@ func (c *Client) do(method, path string, doOptions doOptions) ([]byte, int, erro } else if method == "POST" { req.Header.Set("Content-Type", "plain/text") } - var resp *http.Response - protocol := c.endpointURL.Scheme - address := c.endpointURL.Path - if protocol == "unix" { - var dial net.Conn - dial, err = net.Dial(protocol, address) - if err != nil { - return nil, -1, err - } - defer dial.Close() - breader := bufio.NewReader(dial) - err = req.Write(dial) - if err != nil { - return nil, -1, err - } - resp, err = http.ReadResponse(breader, req) - } else { - resp, err = c.HTTPClient.Do(req) - } + + resp, err := httpClient.Do(req) if err != nil { if strings.Contains(err.Error(), "connection refused") { - return nil, -1, ErrConnectionRefused + return nil, ErrConnectionRefused } - return nil, -1, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, -1, err + return nil, err } + if resp.StatusCode < 200 || resp.StatusCode >= 400 { - return nil, resp.StatusCode, newError(resp.StatusCode, body) + return nil, newError(resp) } - return body, resp.StatusCode, nil + return resp, nil } type streamOptions struct { @@ -464,16 +466,12 @@ func (c *Client) stream(method, path string, streamOptions streamOptions) error address := c.endpointURL.Path if streamOptions.stdout == nil { streamOptions.stdout = ioutil.Discard - } else if t, ok := streamOptions.stdout.(io.Closer); ok { - defer t.Close() } if streamOptions.stderr == nil { streamOptions.stderr = ioutil.Discard - } else if t, ok := streamOptions.stderr.(io.Closer); ok { - defer t.Close() } if protocol == "unix" { - dial, err := net.Dial(protocol, address) + dial, err := c.Dialer.Dial(protocol, address) if err != nil { return err } @@ -509,11 +507,7 @@ func (c *Client) stream(method, path string, streamOptions streamOptions) error } defer resp.Body.Close() if resp.StatusCode < 200 || resp.StatusCode >= 400 { - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - return newError(resp.StatusCode, body) + return newError(resp) } if streamOptions.useJSONDecoder || resp.Header.Get("Content-Type") == "application/json" { // if we want to get raw json stream, just copy it back to output @@ -599,12 +593,12 @@ func (c *Client) hijack(method, path string, hijackOptions hijackOptions) error } var dial net.Conn if c.TLSConfig != nil && protocol != "unix" { - dial, err = tlsDial(protocol, address, c.TLSConfig) + dial, err = tlsDialWithDialer(c.Dialer, protocol, address, c.TLSConfig) if err != nil { return err } } else { - dial, err = net.Dial(protocol, address) + dial, err = c.Dialer.Dial(protocol, address) if err != nil { return err } @@ -666,6 +660,41 @@ func (c *Client) getURL(path string) string { return fmt.Sprintf("%s%s", urlStr, path) } +// getFakeUnixURL returns the URL needed to make an HTTP request over a UNIX +// domain socket to the given path. +func (c *Client) getFakeUnixURL(path string) string { + u := *c.endpointURL // Copy. + + // Override URL so that net/http will not complain. + u.Scheme = "http" + u.Host = "unix.sock" // Doesn't matter what this is - it's not used. + u.Path = "" + + urlStr := strings.TrimRight(u.String(), "/") + + if c.requestedAPIVersion != nil { + return fmt.Sprintf("%s/v%s%s", urlStr, c.requestedAPIVersion, path) + } + return fmt.Sprintf("%s%s", urlStr, path) +} + +func (c *Client) unixClient() *http.Client { + if c.unixHTTPClient != nil { + return c.unixHTTPClient + } + + socketPath := c.endpointURL.Path + c.unixHTTPClient = &http.Client{ + Transport: &http.Transport{ + Dial: func(network, addr string) (net.Conn, error) { + return c.Dialer.Dial("unix", socketPath) + }, + }, + } + + return c.unixHTTPClient +} + type jsonMessage struct { Status string `json:"status,omitempty"` Progress string `json:"progress,omitempty"` @@ -747,8 +776,13 @@ type Error struct { Message string } -func newError(status int, body []byte) *Error { - return &Error{Status: status, Message: string(body)} +func newError(resp *http.Response) *Error { + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return &Error{Status: resp.StatusCode, Message: fmt.Sprintf("cannot read body, err: %v", err)} + } + return &Error{Status: resp.StatusCode, Message: string(data)} } func (e *Error) Error() string { diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client_test.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client_test.go index c00c3d30c8e2..67230a4e15c2 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client_test.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client_test.go @@ -5,6 +5,7 @@ package docker import ( + "bytes" "fmt" "io/ioutil" "net" @@ -161,6 +162,16 @@ func TestNewTLSClient(t *testing.T) { } } +func TestEndpoint(t *testing.T) { + client, err := NewVersionedClient("http://localhost:4243", "1.12") + if err != nil { + t.Fatal(err) + } + if endpoint := client.Endpoint(); endpoint != client.endpoint { + t.Errorf("Client.Endpoint(): want %q. Got %q", client.endpoint, endpoint) + } +} + func TestGetURL(t *testing.T) { var tests = []struct { endpoint string @@ -185,8 +196,34 @@ func TestGetURL(t *testing.T) { } } +func TestGetFakeUnixURL(t *testing.T) { + var tests = []struct { + endpoint string + path string + expected string + }{ + {"unix://var/run/docker.sock", "/", "http://unix.sock/"}, + {"unix://var/run/docker.socket", "/", "http://unix.sock/"}, + {"unix://var/run/docker.sock", "/containers/ps", "http://unix.sock/containers/ps"}, + } + for _, tt := range tests { + client, _ := NewClient(tt.endpoint) + client.endpoint = tt.endpoint + client.SkipServerVersionCheck = true + got := client.getFakeUnixURL(tt.path) + if got != tt.expected { + t.Errorf("getURL(%q): Got %s. Want %s.", tt.path, got, tt.expected) + } + } +} + func TestError(t *testing.T) { - err := newError(400, []byte("bad parameter")) + fakeBody := ioutil.NopCloser(bytes.NewBufferString("bad parameter")) + resp := &http.Response{ + StatusCode: 400, + Body: fakeBody, + } + err := newError(resp) expected := Error{Status: 400, Message: "bad parameter"} if !reflect.DeepEqual(expected, *err) { t.Errorf("Wrong error type. Want %#v. Got %#v.", expected, *err) @@ -334,7 +371,7 @@ func TestPingErrorWithUnixSocket(t *testing.T) { } defer li.Close() if err != nil { - t.Fatalf("Expected to get listner, but failed: %#v", err) + t.Fatalf("Expected to get listener, but failed: %#v", err) } fd, err := li.Accept() @@ -345,7 +382,7 @@ func TestPingErrorWithUnixSocket(t *testing.T) { buf := make([]byte, 512) nr, err := fd.Read(buf) - // Create invalid response message to occur error + // Create invalid response message to trigger error. data := buf[0:nr] for i := 0; i < 10; i++ { data[i] = 63 @@ -366,6 +403,7 @@ func TestPingErrorWithUnixSocket(t *testing.T) { u, _ := parseEndpoint(endpoint, false) client := Client{ HTTPClient: http.DefaultClient, + Dialer: &net.Dialer{}, endpoint: endpoint, endpointURL: u, SkipServerVersionCheck: true, diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container.go index b74a992c0afe..faf12632f0be 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container.go @@ -5,7 +5,6 @@ package docker import ( - "bytes" "encoding/json" "errors" "fmt" @@ -61,13 +60,13 @@ type APIContainers struct { // See https://goo.gl/47a6tO for more details. func (c *Client) ListContainers(opts ListContainersOptions) ([]APIContainers, error) { path := "/containers/json?" + queryString(opts) - body, _, err := c.do("GET", path, doOptions{}) + resp, err := c.do("GET", path, doOptions{}) if err != nil { return nil, err } + defer resp.Body.Close() var containers []APIContainers - err = json.Unmarshal(body, &containers) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&containers); err != nil { return nil, err } return containers, nil @@ -206,6 +205,7 @@ type Config struct { DNS []string `json:"Dns,omitempty" yaml:"Dns,omitempty"` // For Docker API v1.9 and below only Image string `json:"Image,omitempty" yaml:"Image,omitempty"` Volumes map[string]struct{} `json:"Volumes,omitempty" yaml:"Volumes,omitempty"` + VolumeDriver string `json:"VolumeDriver,omitempty" yaml:"VolumeDriver,omitempty"` VolumesFrom string `json:"VolumesFrom,omitempty" yaml:"VolumesFrom,omitempty"` WorkingDir string `json:"WorkingDir,omitempty" yaml:"WorkingDir,omitempty"` MacAddress string `json:"MacAddress,omitempty" yaml:"MacAddress,omitempty"` @@ -271,13 +271,14 @@ type Container struct { NetworkSettings *NetworkSettings `json:"NetworkSettings,omitempty" yaml:"NetworkSettings,omitempty"` - SysInitPath string `json:"SysInitPath,omitempty" yaml:"SysInitPath,omitempty"` - ResolvConfPath string `json:"ResolvConfPath,omitempty" yaml:"ResolvConfPath,omitempty"` - HostnamePath string `json:"HostnamePath,omitempty" yaml:"HostnamePath,omitempty"` - HostsPath string `json:"HostsPath,omitempty" yaml:"HostsPath,omitempty"` - LogPath string `json:"LogPath,omitempty" yaml:"LogPath,omitempty"` - Name string `json:"Name,omitempty" yaml:"Name,omitempty"` - Driver string `json:"Driver,omitempty" yaml:"Driver,omitempty"` + SysInitPath string `json:"SysInitPath,omitempty" yaml:"SysInitPath,omitempty"` + ResolvConfPath string `json:"ResolvConfPath,omitempty" yaml:"ResolvConfPath,omitempty"` + HostnamePath string `json:"HostnamePath,omitempty" yaml:"HostnamePath,omitempty"` + HostsPath string `json:"HostsPath,omitempty" yaml:"HostsPath,omitempty"` + LogPath string `json:"LogPath,omitempty" yaml:"LogPath,omitempty"` + Name string `json:"Name,omitempty" yaml:"Name,omitempty"` + Driver string `json:"Driver,omitempty" yaml:"Driver,omitempty"` + Mounts []Mount `json:"Mounts,omitempty" yaml:"Mounts,omitempty"` Volumes map[string]string `json:"Volumes,omitempty" yaml:"Volumes,omitempty"` VolumesRW map[string]bool `json:"VolumesRW,omitempty" yaml:"VolumesRW,omitempty"` @@ -304,8 +305,12 @@ type RenameContainerOptions struct { // // See https://goo.gl/laSOIy for more details. func (c *Client) RenameContainer(opts RenameContainerOptions) error { - _, _, err := c.do("POST", fmt.Sprintf("/containers/"+opts.ID+"/rename?%s", queryString(opts)), doOptions{}) - return err + resp, err := c.do("POST", fmt.Sprintf("/containers/"+opts.ID+"/rename?%s", queryString(opts)), doOptions{}) + if err != nil { + return err + } + resp.Body.Close() + return nil } // InspectContainer returns information about a container by its ID. @@ -313,16 +318,16 @@ func (c *Client) RenameContainer(opts RenameContainerOptions) error { // See https://goo.gl/RdIq0b for more details. func (c *Client) InspectContainer(id string) (*Container, error) { path := "/containers/" + id + "/json" - body, status, err := c.do("GET", path, doOptions{}) - if status == http.StatusNotFound { - return nil, &NoSuchContainer{ID: id} - } + resp, err := c.do("GET", path, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return nil, &NoSuchContainer{ID: id} + } return nil, err } + defer resp.Body.Close() var container Container - err = json.Unmarshal(body, &container) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&container); err != nil { return nil, err } return &container, nil @@ -333,16 +338,16 @@ func (c *Client) InspectContainer(id string) (*Container, error) { // See https://goo.gl/9GsTIF for more details. func (c *Client) ContainerChanges(id string) ([]Change, error) { path := "/containers/" + id + "/changes" - body, status, err := c.do("GET", path, doOptions{}) - if status == http.StatusNotFound { - return nil, &NoSuchContainer{ID: id} - } + resp, err := c.do("GET", path, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return nil, &NoSuchContainer{ID: id} + } return nil, err } + defer resp.Body.Close() var changes []Change - err = json.Unmarshal(body, &changes) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&changes); err != nil { return nil, err } return changes, nil @@ -363,7 +368,7 @@ type CreateContainerOptions struct { // See https://goo.gl/WxQzrr for more details. func (c *Client) CreateContainer(opts CreateContainerOptions) (*Container, error) { path := "/containers/create?" + queryString(opts) - body, status, err := c.do( + resp, err := c.do( "POST", path, doOptions{ @@ -377,18 +382,21 @@ func (c *Client) CreateContainer(opts CreateContainerOptions) (*Container, error }, ) - if status == http.StatusNotFound { - return nil, ErrNoSuchImage - } - if status == http.StatusConflict { - return nil, ErrContainerAlreadyExists + if e, ok := err.(*Error); ok { + if e.Status == http.StatusNotFound { + return nil, ErrNoSuchImage + } + if e.Status == http.StatusConflict { + return nil, ErrContainerAlreadyExists + } } + if err != nil { return nil, err } + defer resp.Body.Close() var container Container - err = json.Unmarshal(body, &container) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&container); err != nil { return nil, err } @@ -449,6 +457,7 @@ type HostConfig struct { Binds []string `json:"Binds,omitempty" yaml:"Binds,omitempty"` CapAdd []string `json:"CapAdd,omitempty" yaml:"CapAdd,omitempty"` CapDrop []string `json:"CapDrop,omitempty" yaml:"CapDrop,omitempty"` + GroupAdd []string `json:"GroupAdd,omitempty" yaml:"GroupAdd,omitempty"` ContainerIDFile string `json:"ContainerIDFile,omitempty" yaml:"ContainerIDFile,omitempty"` LxcConf []KeyValuePair `json:"LxcConf,omitempty" yaml:"LxcConf,omitempty"` Privileged bool `json:"Privileged,omitempty" yaml:"Privileged,omitempty"` @@ -488,16 +497,17 @@ type HostConfig struct { // See https://goo.gl/MrBAJv for more details. func (c *Client) StartContainer(id string, hostConfig *HostConfig) error { path := "/containers/" + id + "/start" - _, status, err := c.do("POST", path, doOptions{data: hostConfig, forceJSON: true}) - if status == http.StatusNotFound { - return &NoSuchContainer{ID: id, Err: err} - } - if status == http.StatusNotModified { - return &ContainerAlreadyRunning{ID: id} - } + resp, err := c.do("POST", path, doOptions{data: hostConfig, forceJSON: true}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return &NoSuchContainer{ID: id, Err: err} + } return err } + if resp.StatusCode == http.StatusNotModified { + return &ContainerAlreadyRunning{ID: id} + } + resp.Body.Close() return nil } @@ -507,16 +517,17 @@ func (c *Client) StartContainer(id string, hostConfig *HostConfig) error { // See https://goo.gl/USqsFt for more details. func (c *Client) StopContainer(id string, timeout uint) error { path := fmt.Sprintf("/containers/%s/stop?t=%d", id, timeout) - _, status, err := c.do("POST", path, doOptions{}) - if status == http.StatusNotFound { - return &NoSuchContainer{ID: id} - } - if status == http.StatusNotModified { - return &ContainerNotRunning{ID: id} - } + resp, err := c.do("POST", path, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return &NoSuchContainer{ID: id} + } return err } + if resp.StatusCode == http.StatusNotModified { + return &ContainerNotRunning{ID: id} + } + resp.Body.Close() return nil } @@ -526,13 +537,14 @@ func (c *Client) StopContainer(id string, timeout uint) error { // See https://goo.gl/QzsDnz for more details. func (c *Client) RestartContainer(id string, timeout uint) error { path := fmt.Sprintf("/containers/%s/restart?t=%d", id, timeout) - _, status, err := c.do("POST", path, doOptions{}) - if status == http.StatusNotFound { - return &NoSuchContainer{ID: id} - } + resp, err := c.do("POST", path, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return &NoSuchContainer{ID: id} + } return err } + resp.Body.Close() return nil } @@ -541,13 +553,14 @@ func (c *Client) RestartContainer(id string, timeout uint) error { // See https://goo.gl/OF7W9X for more details. func (c *Client) PauseContainer(id string) error { path := fmt.Sprintf("/containers/%s/pause", id) - _, status, err := c.do("POST", path, doOptions{}) - if status == http.StatusNotFound { - return &NoSuchContainer{ID: id} - } + resp, err := c.do("POST", path, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return &NoSuchContainer{ID: id} + } return err } + resp.Body.Close() return nil } @@ -556,13 +569,14 @@ func (c *Client) PauseContainer(id string) error { // See https://goo.gl/7dwyPA for more details. func (c *Client) UnpauseContainer(id string) error { path := fmt.Sprintf("/containers/%s/unpause", id) - _, status, err := c.do("POST", path, doOptions{}) - if status == http.StatusNotFound { - return &NoSuchContainer{ID: id} - } + resp, err := c.do("POST", path, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return &NoSuchContainer{ID: id} + } return err } + resp.Body.Close() return nil } @@ -585,15 +599,15 @@ func (c *Client) TopContainer(id string, psArgs string) (TopResult, error) { args = fmt.Sprintf("?ps_args=%s", psArgs) } path := fmt.Sprintf("/containers/%s/top%s", id, args) - body, status, err := c.do("GET", path, doOptions{}) - if status == http.StatusNotFound { - return result, &NoSuchContainer{ID: id} - } + resp, err := c.do("GET", path, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return result, &NoSuchContainer{ID: id} + } return result, err } - err = json.Unmarshal(body, &result) - if err != nil { + defer resp.Body.Close() + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { return result, err } return result, nil @@ -768,7 +782,7 @@ func (c *Client) Stats(opts StatsOptions) (retErr error) { decoder := json.NewDecoder(readCloser) stats := new(Stats) - for err := decoder.Decode(&stats); err != io.EOF; err = decoder.Decode(stats) { + for err := decoder.Decode(stats); err != io.EOF; err = decoder.Decode(stats) { if err != nil { return err } @@ -797,13 +811,14 @@ type KillContainerOptions struct { // See https://goo.gl/hkS9i8 for more details. func (c *Client) KillContainer(opts KillContainerOptions) error { path := "/containers/" + opts.ID + "/kill" + "?" + queryString(opts) - _, status, err := c.do("POST", path, doOptions{}) - if status == http.StatusNotFound { - return &NoSuchContainer{ID: opts.ID} - } + resp, err := c.do("POST", path, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return &NoSuchContainer{ID: opts.ID} + } return err } + resp.Body.Close() return nil } @@ -828,43 +843,86 @@ type RemoveContainerOptions struct { // See https://goo.gl/RQyX62 for more details. func (c *Client) RemoveContainer(opts RemoveContainerOptions) error { path := "/containers/" + opts.ID + "?" + queryString(opts) - _, status, err := c.do("DELETE", path, doOptions{}) - if status == http.StatusNotFound { - return &NoSuchContainer{ID: opts.ID} - } + resp, err := c.do("DELETE", path, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return &NoSuchContainer{ID: opts.ID} + } return err } + resp.Body.Close() return nil } -// CopyFromContainerOptions is the set of options that can be used when copying -// files or folders from a container. +// UploadToContainerOptions is the set of options that can be used when +// uploading an archive into a container. +// +// See https://goo.gl/Ss97HW for more details. +type UploadToContainerOptions struct { + InputStream io.Reader `json:"-" qs:"-"` + Path string `qs:"path"` + NoOverwriteDirNonDir bool `qs:"noOverwriteDirNonDir"` +} + +// UploadToContainer uploads a tar archive to be extracted to a path in the +// filesystem of the container. +// +// See https://goo.gl/Ss97HW for more details. +func (c *Client) UploadToContainer(id string, opts UploadToContainerOptions) error { + url := fmt.Sprintf("/containers/%s/archive?", id) + queryString(opts) + + return c.stream("PUT", url, streamOptions{ + in: opts.InputStream, + }) +} + +// DownloadFromContainerOptions is the set of options that can be used when +// downloading resources from a container. +// +// See https://goo.gl/KnZJDX for more details. +type DownloadFromContainerOptions struct { + OutputStream io.Writer `json:"-" qs:"-"` + Path string `qs:"path"` +} + +// DownloadFromContainer downloads a tar archive of files or folders in a container. +// +// See https://goo.gl/KnZJDX for more details. +func (c *Client) DownloadFromContainer(id string, opts DownloadFromContainerOptions) error { + url := fmt.Sprintf("/containers/%s/archive?", id) + queryString(opts) + + return c.stream("GET", url, streamOptions{ + setRawTerminal: true, + stdout: opts.OutputStream, + }) +} + +// CopyFromContainerOptions has been DEPRECATED, please use DownloadFromContainerOptions along with DownloadFromContainer. // -// See https://goo.gl/4L7b07 for more details. +// See https://goo.gl/R2jevW for more details. type CopyFromContainerOptions struct { OutputStream io.Writer `json:"-"` Container string `json:"-"` Resource string } -// CopyFromContainer copy files or folders from a container, using a given -// resource. +// CopyFromContainer has been DEPRECATED, please use DownloadFromContainerOptions along with DownloadFromContainer. // -// See https://goo.gl/4L7b07 for more details. +// See https://goo.gl/R2jevW for more details. func (c *Client) CopyFromContainer(opts CopyFromContainerOptions) error { if opts.Container == "" { return &NoSuchContainer{ID: opts.Container} } url := fmt.Sprintf("/containers/%s/copy", opts.Container) - body, status, err := c.do("POST", url, doOptions{data: opts}) - if status == http.StatusNotFound { - return &NoSuchContainer{ID: opts.Container} - } + resp, err := c.do("POST", url, doOptions{data: opts}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return &NoSuchContainer{ID: opts.Container} + } return err } - _, err = io.Copy(opts.OutputStream, bytes.NewBuffer(body)) + defer resp.Body.Close() + _, err = io.Copy(opts.OutputStream, resp.Body) return err } @@ -873,16 +931,16 @@ func (c *Client) CopyFromContainer(opts CopyFromContainerOptions) error { // // See https://goo.gl/Gc1rge for more details. func (c *Client) WaitContainer(id string) (int, error) { - body, status, err := c.do("POST", "/containers/"+id+"/wait", doOptions{}) - if status == http.StatusNotFound { - return 0, &NoSuchContainer{ID: id} - } + resp, err := c.do("POST", "/containers/"+id+"/wait", doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return 0, &NoSuchContainer{ID: id} + } return 0, err } + defer resp.Body.Close() var r struct{ StatusCode int } - err = json.Unmarshal(body, &r) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&r); err != nil { return 0, err } return r.StatusCode, nil @@ -905,16 +963,16 @@ type CommitContainerOptions struct { // See https://goo.gl/mqfoCw for more details. func (c *Client) CommitContainer(opts CommitContainerOptions) (*Image, error) { path := "/commit?" + queryString(opts) - body, status, err := c.do("POST", path, doOptions{data: opts.Run}) - if status == http.StatusNotFound { - return nil, &NoSuchContainer{ID: opts.Container} - } + resp, err := c.do("POST", path, doOptions{data: opts.Run}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return nil, &NoSuchContainer{ID: opts.Container} + } return nil, err } + defer resp.Body.Close() var image Image - err = json.Unmarshal(body, &image) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&image); err != nil { return nil, err } return &image, nil @@ -1017,8 +1075,12 @@ func (c *Client) ResizeContainerTTY(id string, height, width int) error { params := make(url.Values) params.Set("h", strconv.Itoa(height)) params.Set("w", strconv.Itoa(width)) - _, _, err := c.do("POST", "/containers/"+id+"/resize?"+params.Encode(), doOptions{}) - return err + resp, err := c.do("POST", "/containers/"+id+"/resize?"+params.Encode(), doOptions{}) + if err != nil { + return err + } + resp.Body.Close() + return nil } // ExportContainerOptions is the set of parameters to the ExportContainer diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container_test.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container_test.go index d9dbea86fdbf..ea7fad2f6f7d 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container_test.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container_test.go @@ -238,7 +238,8 @@ func TestInspectContainer(t *testing.T) { "PublishAllPorts": false, "CgroupParent": "/mesos", "Memory": 17179869184, - "MemorySwap": 34359738368 + "MemorySwap": 34359738368, + "GroupAdd": ["fake", "12345"] } }` var expected Container @@ -1371,6 +1372,7 @@ func TestExportContainerViaUnixSocket(t *testing.T) { u, _ := parseEndpoint(endpoint, false) client := Client{ HTTPClient: http.DefaultClient, + Dialer: &net.Dialer{}, endpoint: endpoint, endpointURL: u, SkipServerVersionCheck: true, @@ -1426,17 +1428,60 @@ func TestExportContainerNoId(t *testing.T) { } } +func TestUploadToContainer(t *testing.T) { + content := "File content" + in := stdinMock{bytes.NewBufferString(content)} + fakeRT := &FakeRoundTripper{status: http.StatusOK} + client := newTestClient(fakeRT) + opts := UploadToContainerOptions{ + Path: "abc", + InputStream: in, + } + err := client.UploadToContainer("a123456", opts) + if err != nil { + t.Errorf("UploadToContainer: caught error %#v while uploading archive to container, expected nil", err) + } + + req := fakeRT.requests[0] + + if req.Method != "PUT" { + t.Errorf("UploadToContainer{Path:abc}: Wrong HTTP method. Want PUT. Got %s", req.Method) + } + + if pathParam := req.URL.Query().Get("path"); pathParam != "abc" { + t.Errorf("ListImages({Path:abc}): Wrong parameter. Want path=abc. Got path=%s", pathParam) + } + +} + +func TestDownloadFromContainer(t *testing.T) { + filecontent := "File content" + client := newTestClient(&FakeRoundTripper{message: filecontent, status: http.StatusOK}) + + var out bytes.Buffer + opts := DownloadFromContainerOptions{ + OutputStream: &out, + } + err := client.DownloadFromContainer("a123456", opts) + if err != nil { + t.Errorf("DownloadFromContainer: caught error %#v while downloading from container, expected nil", err.Error()) + } + if out.String() != filecontent { + t.Errorf("DownloadFromContainer: wrong stdout. Want %#v. Got %#v.", filecontent, out.String()) + } +} + func TestCopyFromContainer(t *testing.T) { content := "File content" out := stdoutMock{bytes.NewBufferString(content)} client := newTestClient(&FakeRoundTripper{status: http.StatusOK}) opts := CopyFromContainerOptions{ Container: "a123456", - OutputStream: out, + OutputStream: &out, } err := client.CopyFromContainer(opts) if err != nil { - t.Errorf("CopyFromContainer: caugh error %#v while copying from container, expected nil", err.Error()) + t.Errorf("CopyFromContainer: caught error %#v while copying from container, expected nil", err.Error()) } if out.String() != content { t.Errorf("CopyFromContainer: wrong stdout. Want %#v. Got %#v.", content, out.String()) @@ -1584,7 +1629,6 @@ func TestTopContainerWithPsArgs(t *testing.T) { } func TestStatsTimeout(t *testing.T) { - l, err := net.Listen("unix", "/tmp/docker_test.sock") if err != nil { t.Fatal(err) @@ -1594,7 +1638,7 @@ func TestStatsTimeout(t *testing.T) { go func() { l.Accept() received = true - time.Sleep(time.Millisecond * 250) + time.Sleep(time.Second) }() client, _ := NewClient("unix:///tmp/docker_test.sock") client.SkipServerVersionCheck = true diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/event.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/event.go index 5a85983cc896..eaffddb825fc 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/event.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/event.go @@ -5,7 +5,6 @@ package docker import ( - "crypto/tls" "encoding/json" "errors" "fmt" @@ -260,9 +259,9 @@ func (c *Client) eventHijack(startTime int64, eventChan chan *APIEvents, errChan var dial net.Conn var err error if c.TLSConfig == nil { - dial, err = net.Dial(protocol, address) + dial, err = c.Dialer.Dial(protocol, address) } else { - dial, err = tls.Dial(protocol, address, c.TLSConfig) + dial, err = tlsDialWithDialer(c.Dialer, protocol, address, c.TLSConfig) } if err != nil { return err diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/exec.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/exec.go index 84047f04efb2..f3b705fa0a73 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/exec.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/exec.go @@ -38,16 +38,16 @@ type CreateExecOptions struct { // See https://goo.gl/1KSIb7 for more details func (c *Client) CreateExec(opts CreateExecOptions) (*Exec, error) { path := fmt.Sprintf("/containers/%s/exec", opts.Container) - body, status, err := c.do("POST", path, doOptions{data: opts}) - if status == http.StatusNotFound { - return nil, &NoSuchContainer{ID: opts.Container} - } + resp, err := c.do("POST", path, doOptions{data: opts}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return nil, &NoSuchContainer{ID: opts.Container} + } return nil, err } + defer resp.Body.Close() var exec Exec - err = json.Unmarshal(body, &exec) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&exec); err != nil { return nil, err } @@ -90,13 +90,14 @@ func (c *Client) StartExec(id string, opts StartExecOptions) error { path := fmt.Sprintf("/exec/%s/start", id) if opts.Detach { - _, status, err := c.do("POST", path, doOptions{data: opts}) - if status == http.StatusNotFound { - return &NoSuchExec{ID: id} - } + resp, err := c.do("POST", path, doOptions{data: opts}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return &NoSuchExec{ID: id} + } return err } + defer resp.Body.Close() return nil } @@ -121,8 +122,12 @@ func (c *Client) ResizeExecTTY(id string, height, width int) error { params.Set("w", strconv.Itoa(width)) path := fmt.Sprintf("/exec/%s/resize?%s", id, params.Encode()) - _, _, err := c.do("POST", path, doOptions{}) - return err + resp, err := c.do("POST", path, doOptions{}) + if err != nil { + return err + } + resp.Body.Close() + return nil } // ExecProcessConfig is a type describing the command associated to a Exec @@ -156,16 +161,16 @@ type ExecInspect struct { // See https://goo.gl/gPtX9R for more details func (c *Client) InspectExec(id string) (*ExecInspect, error) { path := fmt.Sprintf("/exec/%s/json", id) - body, status, err := c.do("GET", path, doOptions{}) - if status == http.StatusNotFound { - return nil, &NoSuchExec{ID: id} - } + resp, err := c.do("GET", path, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return nil, &NoSuchExec{ID: id} + } return nil, err } + defer resp.Body.Close() var exec ExecInspect - err = json.Unmarshal(body, &exec) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&exec); err != nil { return nil, err } return &exec, nil diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image.go index f8be846901f9..87c1e19b1e1a 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image.go @@ -96,13 +96,13 @@ type ListImagesOptions struct { // See https://goo.gl/xBe1u3 for more details. func (c *Client) ListImages(opts ListImagesOptions) ([]APIImages, error) { path := "/images/json?" + queryString(opts) - body, _, err := c.do("GET", path, doOptions{}) + resp, err := c.do("GET", path, doOptions{}) if err != nil { return nil, err } + defer resp.Body.Close() var images []APIImages - err = json.Unmarshal(body, &images) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&images); err != nil { return nil, err } return images, nil @@ -122,16 +122,16 @@ type ImageHistory struct { // // See https://goo.gl/8bnTId for more details. func (c *Client) ImageHistory(name string) ([]ImageHistory, error) { - body, status, err := c.do("GET", "/images/"+name+"/history", doOptions{}) - if status == http.StatusNotFound { - return nil, ErrNoSuchImage - } + resp, err := c.do("GET", "/images/"+name+"/history", doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return nil, ErrNoSuchImage + } return nil, err } + defer resp.Body.Close() var history []ImageHistory - err = json.Unmarshal(body, &history) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&history); err != nil { return nil, err } return history, nil @@ -141,11 +141,15 @@ func (c *Client) ImageHistory(name string) ([]ImageHistory, error) { // // See https://goo.gl/V3ZWnK for more details. func (c *Client) RemoveImage(name string) error { - _, status, err := c.do("DELETE", "/images/"+name, doOptions{}) - if status == http.StatusNotFound { - return ErrNoSuchImage + resp, err := c.do("DELETE", "/images/"+name, doOptions{}) + if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return ErrNoSuchImage + } + return err } - return err + resp.Body.Close() + return nil } // RemoveImageOptions present the set of options available for removing an image @@ -163,37 +167,40 @@ type RemoveImageOptions struct { // See https://goo.gl/V3ZWnK for more details. func (c *Client) RemoveImageExtended(name string, opts RemoveImageOptions) error { uri := fmt.Sprintf("/images/%s?%s", name, queryString(&opts)) - _, status, err := c.do("DELETE", uri, doOptions{}) - if status == http.StatusNotFound { - return ErrNoSuchImage + resp, err := c.do("DELETE", uri, doOptions{}) + if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return ErrNoSuchImage + } + return err } - return err + resp.Body.Close() + return nil } // InspectImage returns an image by its name or ID. // // See https://goo.gl/jHPcg6 for more details. func (c *Client) InspectImage(name string) (*Image, error) { - body, status, err := c.do("GET", "/images/"+name+"/json", doOptions{}) - if status == http.StatusNotFound { - return nil, ErrNoSuchImage - } + resp, err := c.do("GET", "/images/"+name+"/json", doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return nil, ErrNoSuchImage + } return nil, err } + defer resp.Body.Close() var image Image // if the caller elected to skip checking the server's version, assume it's the latest if c.SkipServerVersionCheck || c.expectedAPIVersion.GreaterThanOrEqualTo(apiVersion112) { - err = json.Unmarshal(body, &image) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&image); err != nil { return nil, err } } else { var imagePre012 ImagePre012 - err = json.Unmarshal(body, &imagePre012) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&imagePre012); err != nil { return nil, err } @@ -409,6 +416,7 @@ type BuildImageOptions struct { Auth AuthConfiguration `qs:"-"` // for older docker X-Registry-Auth header AuthConfigs AuthConfigurations `qs:"-"` // for newer docker X-Registry-Config header ContextDir string `qs:"-"` + Ulimits []ULimit `qs:"-"` } // BuildImage builds an image from a tarball's url or a Dockerfile in the input @@ -442,7 +450,16 @@ func (c *Client) BuildImage(opts BuildImageOptions) error { } } - return c.stream("POST", fmt.Sprintf("/build?%s", queryString(&opts)), streamOptions{ + qs := queryString(&opts) + if len(opts.Ulimits) > 0 { + if b, err := json.Marshal(opts.Ulimits); err == nil { + item := url.Values(map[string][]string{}) + item.Add("ulimits", string(b)) + qs = fmt.Sprintf("%s&%s", qs, item.Encode()) + } + } + + return c.stream("POST", fmt.Sprintf("/build?%s", qs), streamOptions{ setRawTerminal: true, rawJSONStream: opts.RawJSONStream, headers: headers, @@ -477,10 +494,11 @@ func (c *Client) TagImage(name string, opts TagImageOptions) error { if name == "" { return ErrNoSuchImage } - _, status, err := c.do("POST", fmt.Sprintf("/images/"+name+"/tag?%s", + resp, err := c.do("POST", fmt.Sprintf("/images/"+name+"/tag?%s", queryString(&opts)), doOptions{}) + defer resp.Body.Close() - if status == http.StatusNotFound { + if resp.StatusCode == http.StatusNotFound { return ErrNoSuchImage } @@ -533,13 +551,13 @@ type APIImageSearch struct { // // See https://goo.gl/AYjyrF for more details. func (c *Client) SearchImages(term string) ([]APIImageSearch, error) { - body, _, err := c.do("GET", "/images/search?term="+term, doOptions{}) + resp, err := c.do("GET", "/images/search?term="+term, doOptions{}) + defer resp.Body.Close() if err != nil { return nil, err } var searchResult []APIImageSearch - err = json.Unmarshal(body, &searchResult) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&searchResult); err != nil { return nil, err } return searchResult, nil diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image_test.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image_test.go index bf010a2f994d..8d9ee7ae2ff3 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image_test.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image_test.go @@ -9,6 +9,7 @@ import ( "encoding/base64" "encoding/json" "io/ioutil" + "net" "net/http" "net/url" "os" @@ -24,6 +25,7 @@ func newTestClient(rt *FakeRoundTripper) Client { testAPIVersion, _ := NewAPIVersion("1.17") client := Client{ HTTPClient: &http.Client{Transport: rt}, + Dialer: &net.Dialer{}, endpoint: endpoint, endpointURL: u, SkipServerVersionCheck: true, @@ -680,6 +682,7 @@ func TestBuildImageParameters(t *testing.T) { Memswap: 2048, CPUShares: 10, CPUSetCPUs: "0-3", + Ulimits: []ULimit{ULimit{Name: "nofile", Soft: 100, Hard: 200}}, InputStream: &buf, OutputStream: &buf, } @@ -699,6 +702,7 @@ func TestBuildImageParameters(t *testing.T) { "memswap": {"2048"}, "cpushares": {"10"}, "cpusetcpus": {"0-3"}, + "ulimits": {"[{\"Name\":\"nofile\",\"Soft\":100,\"Hard\":200}]"}, } got := map[string][]string(req.URL.Query()) if !reflect.DeepEqual(got, expected) { diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/misc.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/misc.go index df22cf4945bd..34c96531ad90 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/misc.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/misc.go @@ -4,21 +4,19 @@ package docker -import ( - "bytes" - "strings" -) +import "strings" // Version returns version information about the docker server. // // See https://goo.gl/ND9R8L for more details. func (c *Client) Version() (*Env, error) { - body, _, err := c.do("GET", "/version", doOptions{}) + resp, err := c.do("GET", "/version", doOptions{}) if err != nil { return nil, err } + defer resp.Body.Close() var env Env - if err := env.Decode(bytes.NewReader(body)); err != nil { + if err := env.Decode(resp.Body); err != nil { return nil, err } return &env, nil @@ -28,13 +26,13 @@ func (c *Client) Version() (*Env, error) { // // See https://goo.gl/ElTHi2 for more details. func (c *Client) Info() (*Env, error) { - body, _, err := c.do("GET", "/info", doOptions{}) + resp, err := c.do("GET", "/info", doOptions{}) if err != nil { return nil, err } + defer resp.Body.Close() var info Env - err = info.Decode(bytes.NewReader(body)) - if err != nil { + if err := info.Decode(resp.Body); err != nil { return nil, err } return &info, nil diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/network.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/network.go index 0d3e2d43f243..e21e7dfeac9b 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/network.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/network.go @@ -38,12 +38,13 @@ type Endpoint struct { // // See https://goo.gl/4hCNtZ for more details. func (c *Client) ListNetworks() ([]Network, error) { - body, _, err := c.do("GET", "/networks", doOptions{}) + resp, err := c.do("GET", "/networks", doOptions{}) if err != nil { return nil, err } + defer resp.Body.Close() var networks []Network - if err := json.Unmarshal(body, &networks); err != nil { + if err := json.NewDecoder(resp.Body).Decode(&networks); err != nil { return nil, err } return networks, nil @@ -54,15 +55,16 @@ func (c *Client) ListNetworks() ([]Network, error) { // See https://goo.gl/4hCNtZ for more details. func (c *Client) NetworkInfo(id string) (*Network, error) { path := "/networks/" + id - body, status, err := c.do("GET", path, doOptions{}) - if status == http.StatusNotFound { - return nil, &NoSuchNetwork{ID: id} - } + resp, err := c.do("GET", path, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return nil, &NoSuchNetwork{ID: id} + } return nil, err } + defer resp.Body.Close() var network Network - if err := json.Unmarshal(body, &network); err != nil { + if err := json.NewDecoder(resp.Body).Decode(&network); err != nil { return nil, err } return &network, nil @@ -83,35 +85,34 @@ type CreateNetworkOptions struct { // // See http://goo.gl/mErxNp for more details. func (c *Client) CreateNetwork(opts CreateNetworkOptions) (*Network, error) { - body, status, err := c.do( + resp, err := c.do( "POST", "/networks", doOptions{ data: opts, }, ) - - if status == http.StatusConflict { - return nil, ErrNetworkAlreadyExists - } if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusConflict { + return nil, ErrNetworkAlreadyExists + } return nil, err } + defer resp.Body.Close() type createNetworkResponse struct { ID string } var ( network Network - resp createNetworkResponse + cnr createNetworkResponse ) - err = json.Unmarshal(body, &resp) - if err != nil { + if err := json.NewDecoder(resp.Body).Decode(&cnr); err != nil { return nil, err } network.Name = opts.Name - network.ID = resp.ID + network.ID = cnr.ID network.Type = opts.NetworkType return &network, nil diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/symlink b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/symlink deleted file mode 120000 index 3ddf86a35947..000000000000 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/symlink +++ /dev/null @@ -1 +0,0 @@ -doesnotexist \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server.go index 05cd2e25bf0e..46f6b672165b 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server.go @@ -957,7 +957,7 @@ func (s *DockerServer) createExecContainer(w http.ResponseWriter, r *http.Reques func (s *DockerServer) startExecContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] - if exec, err := s.getExec(id); err == nil { + if exec, err := s.getExec(id, false); err == nil { s.execMut.Lock() exec.Running = true s.execMut.Unlock() @@ -979,7 +979,7 @@ func (s *DockerServer) startExecContainer(w http.ResponseWriter, r *http.Request func (s *DockerServer) resizeExecContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] - if _, err := s.getExec(id); err == nil { + if _, err := s.getExec(id, false); err == nil { w.WriteHeader(http.StatusOK) return } @@ -988,7 +988,7 @@ func (s *DockerServer) resizeExecContainer(w http.ResponseWriter, r *http.Reques func (s *DockerServer) inspectExecContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] - if exec, err := s.getExec(id); err == nil { + if exec, err := s.getExec(id, true); err == nil { w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(exec) @@ -997,11 +997,15 @@ func (s *DockerServer) inspectExecContainer(w http.ResponseWriter, r *http.Reque w.WriteHeader(http.StatusNotFound) } -func (s *DockerServer) getExec(id string) (*docker.ExecInspect, error) { +func (s *DockerServer) getExec(id string, copy bool) (*docker.ExecInspect, error) { s.execMut.RLock() defer s.execMut.RUnlock() for _, exec := range s.execs { if exec.ID == id { + if copy { + cp := *exec + exec = &cp + } return exec, nil } } diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/tls.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/tls.go index 11d571761a8c..55f43174bf05 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/tls.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/tls.go @@ -94,7 +94,3 @@ func tlsDialWithDialer(dialer *net.Dialer, network, addr string, config *tls.Con // wrapper which holds both the TLS and raw connections. return &tlsClientCon{conn, rawConn}, nil } - -func tlsDial(network, addr string, config *tls.Config) (net.Conn, error) { - return tlsDialWithDialer(new(net.Dialer), network, addr, config) -} diff --git a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/volume.go b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/volume.go index 4e63272542bd..a989a6eee3d2 100644 --- a/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/volume.go +++ b/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/volume.go @@ -38,12 +38,13 @@ type ListVolumesOptions struct { // // See https://goo.gl/FZA4BK for more details. func (c *Client) ListVolumes(opts ListVolumesOptions) ([]Volume, error) { - body, _, err := c.do("GET", "/volumes?"+queryString(opts), doOptions{}) + resp, err := c.do("GET", "/volumes?"+queryString(opts), doOptions{}) if err != nil { return nil, err } + defer resp.Body.Close() m := make(map[string]interface{}) - if err := json.Unmarshal(body, &m); err != nil { + if err := json.NewDecoder(resp.Body).Decode(&m); err != nil { return nil, err } var volumes []Volume @@ -74,12 +75,13 @@ type CreateVolumeOptions struct { // // See https://goo.gl/pBUbZ9 for more details. func (c *Client) CreateVolume(opts CreateVolumeOptions) (*Volume, error) { - body, _, err := c.do("POST", "/volumes", doOptions{data: opts}) + resp, err := c.do("POST", "/volumes", doOptions{data: opts}) if err != nil { return nil, err } + defer resp.Body.Close() var volume Volume - if err := json.Unmarshal(body, &volume); err != nil { + if err := json.NewDecoder(resp.Body).Decode(&volume); err != nil { return nil, err } return &volume, nil @@ -89,15 +91,16 @@ func (c *Client) CreateVolume(opts CreateVolumeOptions) (*Volume, error) { // // See https://goo.gl/0g9A6i for more details. func (c *Client) InspectVolume(name string) (*Volume, error) { - body, status, err := c.do("GET", "/volumes/"+name, doOptions{}) - if status == http.StatusNotFound { - return nil, ErrNoSuchVolume - } + resp, err := c.do("GET", "/volumes/"+name, doOptions{}) if err != nil { + if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { + return nil, ErrNoSuchVolume + } return nil, err } + defer resp.Body.Close() var volume Volume - if err := json.Unmarshal(body, &volume); err != nil { + if err := json.NewDecoder(resp.Body).Decode(&volume); err != nil { return nil, err } return &volume, nil @@ -107,12 +110,18 @@ func (c *Client) InspectVolume(name string) (*Volume, error) { // // See https://goo.gl/79GNQz for more details. func (c *Client) RemoveVolume(name string) error { - _, status, err := c.do("DELETE", "/volumes/"+name, doOptions{}) - if status == http.StatusNotFound { - return ErrNoSuchVolume - } - if status == http.StatusConflict { - return ErrVolumeInUse + resp, err := c.do("DELETE", "/volumes/"+name, doOptions{}) + if err != nil { + if e, ok := err.(*Error); ok { + if e.Status == http.StatusNotFound { + return ErrNoSuchVolume + } + if e.Status == http.StatusConflict { + return ErrVolumeInUse + } + } + return nil } - return err + defer resp.Body.Close() + return nil } From e4969235f556de06bd583e41607b51785098a02a Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 15 Oct 2015 09:30:13 -0400 Subject: [PATCH 03/35] bump(github.com/ghodss/yaml): 73d445a93680fa1a78ae23a5839bad48f32ba1ee --- Godeps/Godeps.json | 2 +- .../src/github.com/ghodss/yaml/.travis.yml | 7 +++ .../src/github.com/ghodss/yaml/README.md | 2 + .../src/github.com/ghodss/yaml/yaml.go | 44 ++++++++++++++----- .../src/github.com/ghodss/yaml/yaml_test.go | 24 +++++++++- 5 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 Godeps/_workspace/src/github.com/ghodss/yaml/.travis.yml diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 157fd28f8b35..ee0fb07b8046 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -422,7 +422,7 @@ }, { "ImportPath": "github.com/ghodss/yaml", - "Rev": "588cb435e59ee8b6c2795482887755841ad67207" + "Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" }, { "ImportPath": "github.com/go-ldap/ldap", diff --git a/Godeps/_workspace/src/github.com/ghodss/yaml/.travis.yml b/Godeps/_workspace/src/github.com/ghodss/yaml/.travis.yml new file mode 100644 index 000000000000..0e9d6edc010a --- /dev/null +++ b/Godeps/_workspace/src/github.com/ghodss/yaml/.travis.yml @@ -0,0 +1,7 @@ +language: go +go: + - 1.3 + - 1.4 +script: + - go test + - go build diff --git a/Godeps/_workspace/src/github.com/ghodss/yaml/README.md b/Godeps/_workspace/src/github.com/ghodss/yaml/README.md index 2d603097fc05..f8f7e369549c 100644 --- a/Godeps/_workspace/src/github.com/ghodss/yaml/README.md +++ b/Godeps/_workspace/src/github.com/ghodss/yaml/README.md @@ -1,5 +1,7 @@ # YAML marshaling and unmarshaling support for Go +[![Build Status](https://travis-ci.org/ghodss/yaml.svg)](https://travis-ci.org/ghodss/yaml) + ## Introduction A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs. diff --git a/Godeps/_workspace/src/github.com/ghodss/yaml/yaml.go b/Godeps/_workspace/src/github.com/ghodss/yaml/yaml.go index 2f42d4dc6f02..c02beacb9a41 100644 --- a/Godeps/_workspace/src/github.com/ghodss/yaml/yaml.go +++ b/Godeps/_workspace/src/github.com/ghodss/yaml/yaml.go @@ -113,12 +113,11 @@ func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (in } } - // If yamlObj is a number, check if jsonTarget is a string - if so, coerce. - // Else return normal. + // If yamlObj is a number or a boolean, check if jsonTarget is a string - + // if so, coerce. Else return normal. // If yamlObj is a map or array, find the field that each key is // unmarshaling to, and when you recurse pass the reflect.Value for that // field back into this function. - switch typedYAMLObj := yamlObj.(type) { case map[interface{}]interface{}: // JSON does not support arbitrary keys in a map, so we must convert @@ -155,14 +154,22 @@ func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (in s = ".nan" } keyString = s + case bool: + if typedKey { + keyString = "true" + } else { + keyString = "false" + } default: return nil, fmt.Errorf("Unsupported map key of type: %s, key: %+#v, value: %+#v", reflect.TypeOf(k), k, v) } - // If jsonTarget is a struct (which it really should be), find the - // field it's going to map to. If it's not a struct, just pass nil - // - JSON conversion will error for us if it's a real issue. + // jsonTarget should be a struct or a map. If it's a struct, find + // the field it's going to map to and pass its reflect.Value. If + // it's a map, find the element type of the map and pass the + // reflect.Value created from that type. If it's neither, just pass + // nil - JSON conversion will error for us if it's a real issue. if jsonTarget != nil { t := *jsonTarget if t.Kind() == reflect.Struct { @@ -191,6 +198,15 @@ func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (in } continue } + } else if t.Kind() == reflect.Map { + // Create a zero value of the map's element type to use as + // the JSON target. + jtv := reflect.Zero(t.Type().Elem()) + strMap[keyString], err = convertToJSONableObject(v, &jtv) + if err != nil { + return nil, err + } + continue } } strMap[keyString], err = convertToJSONableObject(v, nil) @@ -234,15 +250,21 @@ func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (in // Based on my reading of go-yaml, it may return int, int64, // float64, or uint64. var s string - switch num := typedYAMLObj.(type) { + switch typedVal := typedYAMLObj.(type) { case int: - s = strconv.FormatInt(int64(num), 10) + s = strconv.FormatInt(int64(typedVal), 10) case int64: - s = strconv.FormatInt(num, 10) + s = strconv.FormatInt(typedVal, 10) case float64: - s = strconv.FormatFloat(num, 'g', -1, 32) + s = strconv.FormatFloat(typedVal, 'g', -1, 32) case uint64: - s = strconv.FormatUint(num, 10) + s = strconv.FormatUint(typedVal, 10) + case bool: + if typedVal { + s = "true" + } else { + s = "false" + } } if len(s) > 0 { yamlObj = interface{}(s) diff --git a/Godeps/_workspace/src/github.com/ghodss/yaml/yaml_test.go b/Godeps/_workspace/src/github.com/ghodss/yaml/yaml_test.go index cfbe0b54881e..0ae0954e9013 100644 --- a/Godeps/_workspace/src/github.com/ghodss/yaml/yaml_test.go +++ b/Godeps/_workspace/src/github.com/ghodss/yaml/yaml_test.go @@ -33,7 +33,12 @@ func TestMarshal(t *testing.T) { } type UnmarshalString struct { - A string + A string + True string +} + +type UnmarshalStringMap struct { + A map[string]string } type UnmarshalNestedString struct { @@ -56,7 +61,17 @@ type NestedSlice struct { func TestUnmarshal(t *testing.T) { y := []byte("a: 1") s1 := UnmarshalString{} - e1 := UnmarshalString{"1"} + e1 := UnmarshalString{A: "1"} + unmarshal(t, y, &s1, &e1) + + y = []byte("a: true") + s1 = UnmarshalString{} + e1 = UnmarshalString{A: "true"} + unmarshal(t, y, &s1, &e1) + + y = []byte("true: 1") + s1 = UnmarshalString{} + e1 = UnmarshalString{True: "1"} unmarshal(t, y, &s1, &e1) y = []byte("a:\n a: 1") @@ -68,6 +83,11 @@ func TestUnmarshal(t *testing.T) { s3 := UnmarshalSlice{} e3 := UnmarshalSlice{[]NestedSlice{NestedSlice{"abc", strPtr("def")}, NestedSlice{"123", strPtr("456")}}} unmarshal(t, y, &s3, &e3) + + y = []byte("a:\n b: 1") + s4 := UnmarshalStringMap{} + e4 := UnmarshalStringMap{map[string]string{"b": "1"}} + unmarshal(t, y, &s4, &e4) } func unmarshal(t *testing.T, y []byte, s, e interface{}) { From 2c59a8b0fa484139d7079f5bb39f37d360ee11cf Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 15 Oct 2015 09:21:14 -0400 Subject: [PATCH 04/35] bump(github.com/coreos/go-etcd): de3514f25635bbfb024fdaf2a8d5f67378492675 --- Godeps/Godeps.json | 4 +- .../github.com/coreos/go-etcd/etcd/client.go | 34 +- .../github.com/coreos/go-etcd/etcd/cluster.go | 21 +- .../coreos/go-etcd/etcd/requests.go | 2 +- .../coreos/go-etcd/etcd/response.generated.go | 1632 +++++++++-------- .../github.com/coreos/go-etcd/etcd/shuffle.go | 19 + 6 files changed, 879 insertions(+), 833 deletions(-) create mode 100644 Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/shuffle.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index ee0fb07b8046..4d1ffc31e5c9 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -242,8 +242,8 @@ }, { "ImportPath": "github.com/coreos/go-etcd/etcd", - "Comment": "v2.0.0-13-g4cceaf7", - "Rev": "4cceaf7283b76f27c4a732b20730dcdb61053bf5" + "Comment": "v2.0.0-34-gde3514f", + "Rev": "de3514f25635bbfb024fdaf2a8d5f67378492675" }, { "ImportPath": "github.com/coreos/go-oidc/http", diff --git a/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/client.go b/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/client.go index 727e5dfca46d..60ed762b99dd 100644 --- a/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/client.go +++ b/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/client.go @@ -192,7 +192,7 @@ func (c *Client) Close() { // initHTTPClient initializes a HTTP client for etcd client func (c *Client) initHTTPClient() { c.transport = &http.Transport{ - Dial: c.dial, + Dial: c.DefaultDial, TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, }, @@ -216,12 +216,12 @@ func (c *Client) initHTTPSClient(cert, key string) error { InsecureSkipVerify: true, } - tr := &http.Transport{ + c.transport = &http.Transport{ TLSClientConfig: tlsConfig, - Dial: c.dial, + Dial: c.DefaultDial, } - c.httpClient = &http.Client{Transport: tr} + c.httpClient = &http.Client{Transport: c.transport} return nil } @@ -391,29 +391,15 @@ func (c *Client) createHttpPath(serverName string, _path string) string { return u.String() } -// dial attempts to open a TCP connection to the provided address, explicitly +// DefaultDial attempts to open a TCP connection to the provided address, explicitly // enabling keep-alives with a one-second interval. -func (c *Client) dial(network, addr string) (net.Conn, error) { - conn, err := net.DialTimeout(network, addr, c.config.DialTimeout) - if err != nil { - return nil, err - } - - tcpConn, ok := conn.(*net.TCPConn) - if !ok { - return nil, errors.New("Failed type-assertion of net.Conn as *net.TCPConn") - } - - // Keep TCP alive to check whether or not the remote machine is down - if err = tcpConn.SetKeepAlive(true); err != nil { - return nil, err - } - - if err = tcpConn.SetKeepAlivePeriod(time.Second); err != nil { - return nil, err +func (c *Client) DefaultDial(network, addr string) (net.Conn, error) { + dialer := net.Dialer{ + Timeout: c.config.DialTimeout, + KeepAlive: time.Second, } - return tcpConn, nil + return dialer.Dial(network, addr) } func (c *Client) OpenCURL() { diff --git a/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/cluster.go b/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/cluster.go index 1ad3e155be52..d0461e17a252 100644 --- a/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/cluster.go +++ b/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/cluster.go @@ -3,12 +3,14 @@ package etcd import ( "math/rand" "strings" + "sync" ) type Cluster struct { Leader string `json:"leader"` Machines []string `json:"machines"` picked int + mu sync.RWMutex } func NewCluster(machines []string) *Cluster { @@ -17,6 +19,8 @@ func NewCluster(machines []string) *Cluster { machines = []string{"http://127.0.0.1:4001"} } + machines = shuffleStringSlice(machines) + logger.Debug("Shuffle cluster machines", machines) // default leader and machines return &Cluster{ Leader: "", @@ -25,13 +29,26 @@ func NewCluster(machines []string) *Cluster { } } -func (cl *Cluster) failure() { cl.picked = rand.Intn(len(cl.Machines)) } -func (cl *Cluster) pick() string { return cl.Machines[cl.picked] } +func (cl *Cluster) failure() { + cl.mu.Lock() + defer cl.mu.Unlock() + cl.picked = (cl.picked + 1) % len(cl.Machines) +} + +func (cl *Cluster) pick() string { + cl.mu.Lock() + defer cl.mu.Unlock() + return cl.Machines[cl.picked] +} func (cl *Cluster) updateFromStr(machines string) { + cl.mu.Lock() + defer cl.mu.Unlock() + cl.Machines = strings.Split(machines, ",") for i := range cl.Machines { cl.Machines[i] = strings.TrimSpace(cl.Machines[i]) } + cl.Machines = shuffleStringSlice(cl.Machines) cl.picked = rand.Intn(len(cl.Machines)) } diff --git a/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/requests.go b/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/requests.go index 3c3f436beac4..8f720f6f4426 100644 --- a/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/requests.go +++ b/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/requests.go @@ -348,7 +348,7 @@ func DefaultCheckRetry(cluster *Cluster, numReqs int, lastResp http.Response, } // sleep some time and expect leader election finish time.Sleep(time.Millisecond * 200) - logger.Warning("bad response status code", lastResp.StatusCode) + logger.Warning("bad response status code ", lastResp.StatusCode) return nil } diff --git a/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/response.generated.go b/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/response.generated.go index eb05e4c893f8..397488b14c09 100644 --- a/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/response.generated.go +++ b/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/response.generated.go @@ -9,501 +9,519 @@ import ( "errors" "fmt" codec1978 "github.com/ugorji/go/codec" - "net/http" + pkg1_http "net/http" "reflect" "runtime" - "time" + time "time" ) const ( - codecSelferC_UTF84402 = 1 - codecSelferC_RAW4402 = 0 - codecSelverValueTypeArray4402 = 10 - codecSelverValueTypeMap4402 = 9 + codecSelferC_UTF86669 = 1 + codecSelferC_RAW6669 = 0 + codecSelverValueTypeArray6669 = 10 + codecSelverValueTypeMap6669 = 9 ) var ( - codecSelferBitsize4402 = uint8(reflect.TypeOf(uint(0)).Bits()) - codecSelferOnlyMapOrArrayEncodeToStructErr4402 = errors.New(`only encoded map or array can be decoded into a struct`) + codecSelferBitsize6669 = uint8(reflect.TypeOf(uint(0)).Bits()) + codecSelferOnlyMapOrArrayEncodeToStructErr6669 = errors.New(`only encoded map or array can be decoded into a struct`) ) -type codecSelfer4402 struct{} +type codecSelfer6669 struct{} func init() { - if codec1978.GenVersion != 2 { + if codec1978.GenVersion != 4 { _, file, _, _ := runtime.Caller(0) err := fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v", - 2, codec1978.GenVersion, file) + 4, codec1978.GenVersion, file) panic(err) } if false { // reference the types, but skip this branch at build/run time - var v0 http.Header + var v0 pkg1_http.Header var v1 time.Time _, _ = v0, v1 } } func (x responseType) CodecEncodeSelf(e *codec1978.Encoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r - r.EncodeInt(int64(x)) + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + r.EncodeInt(int64(x)) + } } func (x *responseType) CodecDecodeSelf(d *codec1978.Decoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - *((*int)(x)) = int(r.DecodeInt(codecSelferBitsize4402)) + yym2 := z.DecBinary() + _ = yym2 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + *((*int)(x)) = int(r.DecodeInt(codecSelferBitsize6669)) + } } func (x *RawResponse) CodecEncodeSelf(e *codec1978.Encoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r if x == nil { r.EncodeNil() } else { - yysep1 := !z.EncBinary() - yy2arr1 := z.EncBasicHandle().StructToArray - var yyfirst1 bool - var yyq1 [3]bool - _, _, _, _ = yysep1, yyfirst1, yyq1, yy2arr1 - const yyr1 bool = false - if yyr1 || yy2arr1 { - r.EncodeArrayStart(3) - } else { - var yynn1 int = 3 - for _, b := range yyq1 { - if b { - yynn1++ - } - } - r.EncodeMapStart(yynn1) - } - if yyr1 || yy2arr1 { - r.EncodeInt(int64(x.StatusCode)) - } else { - yyfirst1 = true - r.EncodeString(codecSelferC_UTF84402, string("StatusCode")) - if yysep1 { - r.EncodeMapKVSeparator() - } - r.EncodeInt(int64(x.StatusCode)) - } - if yyr1 || yy2arr1 { - if yysep1 { - r.EncodeArrayEntrySeparator() - } - if x.Body == nil { - r.EncodeNil() - } else { - r.EncodeStringBytes(codecSelferC_RAW4402, []byte(x.Body)) - } + yym3 := z.EncBinary() + _ = yym3 + if false { + } else if z.HasExtensions() && z.EncExt(x) { } else { - if yyfirst1 { - r.EncodeMapEntrySeparator() + yysep4 := !z.EncBinary() + yy2arr4 := z.EncBasicHandle().StructToArray + var yyq4 [3]bool + _, _, _ = yysep4, yyq4, yy2arr4 + const yyr4 bool = false + if yyr4 || yy2arr4 { + r.EncodeArrayStart(3) } else { - yyfirst1 = true - } - r.EncodeString(codecSelferC_UTF84402, string("Body")) - if yysep1 { - r.EncodeMapKVSeparator() - } - if x.Body == nil { - r.EncodeNil() - } else { - r.EncodeStringBytes(codecSelferC_RAW4402, []byte(x.Body)) - } - } - if yyr1 || yy2arr1 { - if yysep1 { - r.EncodeArrayEntrySeparator() + var yynn4 int = 3 + for _, b := range yyq4 { + if b { + yynn4++ + } + } + r.EncodeMapStart(yynn4) } - if x.Header == nil { - r.EncodeNil() + if yyr4 || yy2arr4 { + yym6 := z.EncBinary() + _ = yym6 + if false { + } else { + r.EncodeInt(int64(x.StatusCode)) + } } else { - h.enchttp_Header(http.Header(x.Header), e) + r.EncodeString(codecSelferC_UTF86669, string("StatusCode")) + yym7 := z.EncBinary() + _ = yym7 + if false { + } else { + r.EncodeInt(int64(x.StatusCode)) + } } - } else { - if yyfirst1 { - r.EncodeMapEntrySeparator() + if yyr4 || yy2arr4 { + if x.Body == nil { + r.EncodeNil() + } else { + yym9 := z.EncBinary() + _ = yym9 + if false { + } else { + r.EncodeStringBytes(codecSelferC_RAW6669, []byte(x.Body)) + } + } } else { - yyfirst1 = true - } - r.EncodeString(codecSelferC_UTF84402, string("Header")) - if yysep1 { - r.EncodeMapKVSeparator() + r.EncodeString(codecSelferC_UTF86669, string("Body")) + if x.Body == nil { + r.EncodeNil() + } else { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + r.EncodeStringBytes(codecSelferC_RAW6669, []byte(x.Body)) + } + } } - if x.Header == nil { - r.EncodeNil() + if yyr4 || yy2arr4 { + if x.Header == nil { + r.EncodeNil() + } else { + yym12 := z.EncBinary() + _ = yym12 + if false { + } else if z.HasExtensions() && z.EncExt(x.Header) { + } else { + h.enchttp_Header((pkg1_http.Header)(x.Header), e) + } + } } else { - h.enchttp_Header(http.Header(x.Header), e) + r.EncodeString(codecSelferC_UTF86669, string("Header")) + if x.Header == nil { + r.EncodeNil() + } else { + yym13 := z.EncBinary() + _ = yym13 + if false { + } else if z.HasExtensions() && z.EncExt(x.Header) { + } else { + h.enchttp_Header((pkg1_http.Header)(x.Header), e) + } + } } - } - if yysep1 { - if yyr1 || yy2arr1 { - r.EncodeArrayEnd() - } else { - r.EncodeMapEnd() + if yysep4 { + r.EncodeEnd() } } } } func (x *RawResponse) CodecDecodeSelf(d *codec1978.Decoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - if r.IsContainerType(codecSelverValueTypeMap4402) { - yyl5 := r.ReadMapStart() - if yyl5 == 0 { - r.ReadMapEnd() - } else { - x.codecDecodeSelfFromMap(yyl5, d) - } - } else if r.IsContainerType(codecSelverValueTypeArray4402) { - yyl5 := r.ReadArrayStart() - if yyl5 == 0 { - r.ReadArrayEnd() + yym14 := z.DecBinary() + _ = yym14 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + if r.IsContainerType(codecSelverValueTypeMap6669) { + yyl15 := r.ReadMapStart() + if yyl15 == 0 { + r.ReadEnd() + } else { + x.codecDecodeSelfFromMap(yyl15, d) + } + } else if r.IsContainerType(codecSelverValueTypeArray6669) { + yyl15 := r.ReadArrayStart() + if yyl15 == 0 { + r.ReadEnd() + } else { + x.codecDecodeSelfFromArray(yyl15, d) + } } else { - x.codecDecodeSelfFromArray(yyl5, d) + panic(codecSelferOnlyMapOrArrayEncodeToStructErr6669) } - } else { - panic(codecSelferOnlyMapOrArrayEncodeToStructErr4402) } } func (x *RawResponse) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yys6Slc = z.DecScratchBuffer() // default slice to decode into - _ = yys6Slc - var yyhl6 bool = l >= 0 - for yyj6 := 0; ; yyj6++ { - if yyhl6 { - if yyj6 >= l { + var yys16Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys16Slc + var yyhl16 bool = l >= 0 + for yyj16 := 0; ; yyj16++ { + if yyhl16 { + if yyj16 >= l { break } } else { if r.CheckBreak() { break } - if yyj6 > 0 { - r.ReadMapEntrySeparator() - } - } - yys6Slc = r.DecodeBytes(yys6Slc, true, true) - yys6 := string(yys6Slc) - if !yyhl6 { - r.ReadMapKVSeparator() } - switch yys6 { + yys16Slc = r.DecodeBytes(yys16Slc, true, true) + yys16 := string(yys16Slc) + switch yys16 { case "StatusCode": if r.TryDecodeAsNil() { x.StatusCode = 0 } else { - x.StatusCode = int(r.DecodeInt(codecSelferBitsize4402)) + x.StatusCode = int(r.DecodeInt(codecSelferBitsize6669)) } case "Body": if r.TryDecodeAsNil() { x.Body = nil } else { - yyv8 := &x.Body - *yyv8 = r.DecodeBytes(*(*[]byte)(yyv8), false, false) + yyv18 := &x.Body + yym19 := z.DecBinary() + _ = yym19 + if false { + } else { + *yyv18 = r.DecodeBytes(*(*[]byte)(yyv18), false, false) + } } case "Header": if r.TryDecodeAsNil() { x.Header = nil } else { - yyv9 := &x.Header - h.dechttp_Header((*http.Header)(yyv9), d) + yyv20 := &x.Header + yym21 := z.DecBinary() + _ = yym21 + if false { + } else if z.HasExtensions() && z.DecExt(yyv20) { + } else { + h.dechttp_Header((*pkg1_http.Header)(yyv20), d) + } } default: - z.DecStructFieldNotFound(-1, yys6) - } // end switch yys6 - } // end for yyj6 - if !yyhl6 { - r.ReadMapEnd() + z.DecStructFieldNotFound(-1, yys16) + } // end switch yys16 + } // end for yyj16 + if !yyhl16 { + r.ReadEnd() } } func (x *RawResponse) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj10 int - var yyb10 bool - var yyhl10 bool = l >= 0 - yyj10++ - if yyhl10 { - yyb10 = yyj10 > l + var yyj22 int + var yyb22 bool + var yyhl22 bool = l >= 0 + yyj22++ + if yyhl22 { + yyb22 = yyj22 > l } else { - yyb10 = r.CheckBreak() + yyb22 = r.CheckBreak() } - if yyb10 { - r.ReadArrayEnd() + if yyb22 { + r.ReadEnd() return } if r.TryDecodeAsNil() { x.StatusCode = 0 } else { - x.StatusCode = int(r.DecodeInt(codecSelferBitsize4402)) + x.StatusCode = int(r.DecodeInt(codecSelferBitsize6669)) } - yyj10++ - if yyhl10 { - yyb10 = yyj10 > l + yyj22++ + if yyhl22 { + yyb22 = yyj22 > l } else { - yyb10 = r.CheckBreak() + yyb22 = r.CheckBreak() } - if yyb10 { - r.ReadArrayEnd() + if yyb22 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { x.Body = nil } else { - yyv12 := &x.Body - *yyv12 = r.DecodeBytes(*(*[]byte)(yyv12), false, false) + yyv24 := &x.Body + yym25 := z.DecBinary() + _ = yym25 + if false { + } else { + *yyv24 = r.DecodeBytes(*(*[]byte)(yyv24), false, false) + } } - yyj10++ - if yyhl10 { - yyb10 = yyj10 > l + yyj22++ + if yyhl22 { + yyb22 = yyj22 > l } else { - yyb10 = r.CheckBreak() + yyb22 = r.CheckBreak() } - if yyb10 { - r.ReadArrayEnd() + if yyb22 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { x.Header = nil } else { - yyv13 := &x.Header - h.dechttp_Header((*http.Header)(yyv13), d) + yyv26 := &x.Header + yym27 := z.DecBinary() + _ = yym27 + if false { + } else if z.HasExtensions() && z.DecExt(yyv26) { + } else { + h.dechttp_Header((*pkg1_http.Header)(yyv26), d) + } } for { - yyj10++ - if yyhl10 { - yyb10 = yyj10 > l + yyj22++ + if yyhl22 { + yyb22 = yyj22 > l } else { - yyb10 = r.CheckBreak() + yyb22 = r.CheckBreak() } - if yyb10 { + if yyb22 { break } - if yyj10 > 1 { - r.ReadArrayEntrySeparator() - } - z.DecStructFieldNotFound(yyj10-1, "") + z.DecStructFieldNotFound(yyj22-1, "") } - r.ReadArrayEnd() + r.ReadEnd() } func (x *Response) CodecEncodeSelf(e *codec1978.Encoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r if x == nil { r.EncodeNil() } else { - yysep14 := !z.EncBinary() - yy2arr14 := z.EncBasicHandle().StructToArray - var yyfirst14 bool - var yyq14 [6]bool - _, _, _, _ = yysep14, yyfirst14, yyq14, yy2arr14 - const yyr14 bool = false - yyq14[2] = x.PrevNode != nil - if yyr14 || yy2arr14 { - r.EncodeArrayStart(6) - } else { - var yynn14 int = 5 - for _, b := range yyq14 { - if b { - yynn14++ - } - } - r.EncodeMapStart(yynn14) - } - if yyr14 || yy2arr14 { - r.EncodeString(codecSelferC_UTF84402, string(x.Action)) + yym28 := z.EncBinary() + _ = yym28 + if false { + } else if z.HasExtensions() && z.EncExt(x) { } else { - yyfirst14 = true - r.EncodeString(codecSelferC_UTF84402, string("action")) - if yysep14 { - r.EncodeMapKVSeparator() - } - r.EncodeString(codecSelferC_UTF84402, string(x.Action)) - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() - } - if x.Node == nil { - r.EncodeNil() + yysep29 := !z.EncBinary() + yy2arr29 := z.EncBasicHandle().StructToArray + var yyq29 [6]bool + _, _, _ = yysep29, yyq29, yy2arr29 + const yyr29 bool = false + yyq29[2] = x.PrevNode != nil + if yyr29 || yy2arr29 { + r.EncodeArrayStart(6) } else { - x.Node.CodecEncodeSelf(e) - } - } else { - if yyfirst14 { - r.EncodeMapEntrySeparator() - } else { - yyfirst14 = true - } - r.EncodeString(codecSelferC_UTF84402, string("node")) - if yysep14 { - r.EncodeMapKVSeparator() + var yynn29 int = 5 + for _, b := range yyq29 { + if b { + yynn29++ + } + } + r.EncodeMapStart(yynn29) } - if x.Node == nil { - r.EncodeNil() + if yyr29 || yy2arr29 { + yym31 := z.EncBinary() + _ = yym31 + if false { + } else { + r.EncodeString(codecSelferC_UTF86669, string(x.Action)) + } } else { - x.Node.CodecEncodeSelf(e) - } - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() + r.EncodeString(codecSelferC_UTF86669, string("action")) + yym32 := z.EncBinary() + _ = yym32 + if false { + } else { + r.EncodeString(codecSelferC_UTF86669, string(x.Action)) + } } - if yyq14[2] { - if x.PrevNode == nil { + if yyr29 || yy2arr29 { + if x.Node == nil { r.EncodeNil() } else { - x.PrevNode.CodecEncodeSelf(e) + x.Node.CodecEncodeSelf(e) } } else { - r.EncodeNil() + r.EncodeString(codecSelferC_UTF86669, string("node")) + if x.Node == nil { + r.EncodeNil() + } else { + x.Node.CodecEncodeSelf(e) + } } - } else { - if yyq14[2] { - if yyfirst14 { - r.EncodeMapEntrySeparator() + if yyr29 || yy2arr29 { + if yyq29[2] { + if x.PrevNode == nil { + r.EncodeNil() + } else { + x.PrevNode.CodecEncodeSelf(e) + } } else { - yyfirst14 = true + r.EncodeNil() } - r.EncodeString(codecSelferC_UTF84402, string("prevNode")) - if yysep14 { - r.EncodeMapKVSeparator() + } else { + if yyq29[2] { + r.EncodeString(codecSelferC_UTF86669, string("prevNode")) + if x.PrevNode == nil { + r.EncodeNil() + } else { + x.PrevNode.CodecEncodeSelf(e) + } } - if x.PrevNode == nil { - r.EncodeNil() + } + if yyr29 || yy2arr29 { + yym36 := z.EncBinary() + _ = yym36 + if false { } else { - x.PrevNode.CodecEncodeSelf(e) + r.EncodeUint(uint64(x.EtcdIndex)) } - } - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() - } - r.EncodeUint(uint64(x.EtcdIndex)) - } else { - if yyfirst14 { - r.EncodeMapEntrySeparator() } else { - yyfirst14 = true - } - r.EncodeString(codecSelferC_UTF84402, string("etcdIndex")) - if yysep14 { - r.EncodeMapKVSeparator() - } - r.EncodeUint(uint64(x.EtcdIndex)) - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() + r.EncodeString(codecSelferC_UTF86669, string("etcdIndex")) + yym37 := z.EncBinary() + _ = yym37 + if false { + } else { + r.EncodeUint(uint64(x.EtcdIndex)) + } } - r.EncodeUint(uint64(x.RaftIndex)) - } else { - if yyfirst14 { - r.EncodeMapEntrySeparator() + if yyr29 || yy2arr29 { + yym39 := z.EncBinary() + _ = yym39 + if false { + } else { + r.EncodeUint(uint64(x.RaftIndex)) + } } else { - yyfirst14 = true - } - r.EncodeString(codecSelferC_UTF84402, string("raftIndex")) - if yysep14 { - r.EncodeMapKVSeparator() - } - r.EncodeUint(uint64(x.RaftIndex)) - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() + r.EncodeString(codecSelferC_UTF86669, string("raftIndex")) + yym40 := z.EncBinary() + _ = yym40 + if false { + } else { + r.EncodeUint(uint64(x.RaftIndex)) + } } - r.EncodeUint(uint64(x.RaftTerm)) - } else { - if yyfirst14 { - r.EncodeMapEntrySeparator() + if yyr29 || yy2arr29 { + yym42 := z.EncBinary() + _ = yym42 + if false { + } else { + r.EncodeUint(uint64(x.RaftTerm)) + } } else { - yyfirst14 = true - } - r.EncodeString(codecSelferC_UTF84402, string("raftTerm")) - if yysep14 { - r.EncodeMapKVSeparator() + r.EncodeString(codecSelferC_UTF86669, string("raftTerm")) + yym43 := z.EncBinary() + _ = yym43 + if false { + } else { + r.EncodeUint(uint64(x.RaftTerm)) + } } - r.EncodeUint(uint64(x.RaftTerm)) - } - if yysep14 { - if yyr14 || yy2arr14 { - r.EncodeArrayEnd() - } else { - r.EncodeMapEnd() + if yysep29 { + r.EncodeEnd() } } } } func (x *Response) CodecDecodeSelf(d *codec1978.Decoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - if r.IsContainerType(codecSelverValueTypeMap4402) { - yyl21 := r.ReadMapStart() - if yyl21 == 0 { - r.ReadMapEnd() - } else { - x.codecDecodeSelfFromMap(yyl21, d) - } - } else if r.IsContainerType(codecSelverValueTypeArray4402) { - yyl21 := r.ReadArrayStart() - if yyl21 == 0 { - r.ReadArrayEnd() + yym44 := z.DecBinary() + _ = yym44 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + if r.IsContainerType(codecSelverValueTypeMap6669) { + yyl45 := r.ReadMapStart() + if yyl45 == 0 { + r.ReadEnd() + } else { + x.codecDecodeSelfFromMap(yyl45, d) + } + } else if r.IsContainerType(codecSelverValueTypeArray6669) { + yyl45 := r.ReadArrayStart() + if yyl45 == 0 { + r.ReadEnd() + } else { + x.codecDecodeSelfFromArray(yyl45, d) + } } else { - x.codecDecodeSelfFromArray(yyl21, d) + panic(codecSelferOnlyMapOrArrayEncodeToStructErr6669) } - } else { - panic(codecSelferOnlyMapOrArrayEncodeToStructErr4402) } } func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yys22Slc = z.DecScratchBuffer() // default slice to decode into - _ = yys22Slc - var yyhl22 bool = l >= 0 - for yyj22 := 0; ; yyj22++ { - if yyhl22 { - if yyj22 >= l { + var yys46Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys46Slc + var yyhl46 bool = l >= 0 + for yyj46 := 0; ; yyj46++ { + if yyhl46 { + if yyj46 >= l { break } } else { if r.CheckBreak() { break } - if yyj22 > 0 { - r.ReadMapEntrySeparator() - } } - yys22Slc = r.DecodeBytes(yys22Slc, true, true) - yys22 := string(yys22Slc) - if !yyhl22 { - r.ReadMapKVSeparator() - } - switch yys22 { + yys46Slc = r.DecodeBytes(yys46Slc, true, true) + yys46 := string(yys46Slc) + switch yys46 { case "action": if r.TryDecodeAsNil() { x.Action = "" @@ -551,29 +569,29 @@ func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { x.RaftTerm = uint64(r.DecodeUint(64)) } default: - z.DecStructFieldNotFound(-1, yys22) - } // end switch yys22 - } // end for yyj22 - if !yyhl22 { - r.ReadMapEnd() + z.DecStructFieldNotFound(-1, yys46) + } // end switch yys46 + } // end for yyj46 + if !yyhl46 { + r.ReadEnd() } } func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj29 int - var yyb29 bool - var yyhl29 bool = l >= 0 - yyj29++ - if yyhl29 { - yyb29 = yyj29 > l + var yyj53 int + var yyb53 bool + var yyhl53 bool = l >= 0 + yyj53++ + if yyhl53 { + yyb53 = yyj53 > l } else { - yyb29 = r.CheckBreak() + yyb53 = r.CheckBreak() } - if yyb29 { - r.ReadArrayEnd() + if yyb53 { + r.ReadEnd() return } if r.TryDecodeAsNil() { @@ -581,17 +599,16 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.Action = string(r.DecodeString()) } - yyj29++ - if yyhl29 { - yyb29 = yyj29 > l + yyj53++ + if yyhl53 { + yyb53 = yyj53 > l } else { - yyb29 = r.CheckBreak() + yyb53 = r.CheckBreak() } - if yyb29 { - r.ReadArrayEnd() + if yyb53 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { if x.Node != nil { x.Node = nil @@ -602,17 +619,16 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Node.CodecDecodeSelf(d) } - yyj29++ - if yyhl29 { - yyb29 = yyj29 > l + yyj53++ + if yyhl53 { + yyb53 = yyj53 > l } else { - yyb29 = r.CheckBreak() + yyb53 = r.CheckBreak() } - if yyb29 { - r.ReadArrayEnd() + if yyb53 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { if x.PrevNode != nil { x.PrevNode = nil @@ -623,349 +639,347 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.PrevNode.CodecDecodeSelf(d) } - yyj29++ - if yyhl29 { - yyb29 = yyj29 > l + yyj53++ + if yyhl53 { + yyb53 = yyj53 > l } else { - yyb29 = r.CheckBreak() + yyb53 = r.CheckBreak() } - if yyb29 { - r.ReadArrayEnd() + if yyb53 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { x.EtcdIndex = 0 } else { x.EtcdIndex = uint64(r.DecodeUint(64)) } - yyj29++ - if yyhl29 { - yyb29 = yyj29 > l + yyj53++ + if yyhl53 { + yyb53 = yyj53 > l } else { - yyb29 = r.CheckBreak() + yyb53 = r.CheckBreak() } - if yyb29 { - r.ReadArrayEnd() + if yyb53 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { x.RaftIndex = 0 } else { x.RaftIndex = uint64(r.DecodeUint(64)) } - yyj29++ - if yyhl29 { - yyb29 = yyj29 > l + yyj53++ + if yyhl53 { + yyb53 = yyj53 > l } else { - yyb29 = r.CheckBreak() + yyb53 = r.CheckBreak() } - if yyb29 { - r.ReadArrayEnd() + if yyb53 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { x.RaftTerm = 0 } else { x.RaftTerm = uint64(r.DecodeUint(64)) } for { - yyj29++ - if yyhl29 { - yyb29 = yyj29 > l + yyj53++ + if yyhl53 { + yyb53 = yyj53 > l } else { - yyb29 = r.CheckBreak() + yyb53 = r.CheckBreak() } - if yyb29 { + if yyb53 { break } - if yyj29 > 1 { - r.ReadArrayEntrySeparator() - } - z.DecStructFieldNotFound(yyj29-1, "") + z.DecStructFieldNotFound(yyj53-1, "") } - r.ReadArrayEnd() + r.ReadEnd() } func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r if x == nil { r.EncodeNil() } else { - yysep36 := !z.EncBinary() - yy2arr36 := z.EncBasicHandle().StructToArray - var yyfirst36 bool - var yyq36 [8]bool - _, _, _, _ = yysep36, yyfirst36, yyq36, yy2arr36 - const yyr36 bool = false - yyq36[1] = x.Value != "" - yyq36[2] = x.Dir != false - yyq36[3] = x.Expiration != nil - yyq36[4] = x.TTL != 0 - yyq36[5] = len(x.Nodes) != 0 - yyq36[6] = x.ModifiedIndex != 0 - yyq36[7] = x.CreatedIndex != 0 - if yyr36 || yy2arr36 { - r.EncodeArrayStart(8) + yym60 := z.EncBinary() + _ = yym60 + if false { + } else if z.HasExtensions() && z.EncExt(x) { } else { - var yynn36 int = 1 - for _, b := range yyq36 { - if b { - yynn36++ - } - } - r.EncodeMapStart(yynn36) - } - if yyr36 || yy2arr36 { - r.EncodeString(codecSelferC_UTF84402, string(x.Key)) - } else { - yyfirst36 = true - r.EncodeString(codecSelferC_UTF84402, string("key")) - if yysep36 { - r.EncodeMapKVSeparator() - } - r.EncodeString(codecSelferC_UTF84402, string(x.Key)) - } - if yyr36 || yy2arr36 { - if yysep36 { - r.EncodeArrayEntrySeparator() - } - if yyq36[1] { - r.EncodeString(codecSelferC_UTF84402, string(x.Value)) + yysep61 := !z.EncBinary() + yy2arr61 := z.EncBasicHandle().StructToArray + var yyq61 [8]bool + _, _, _ = yysep61, yyq61, yy2arr61 + const yyr61 bool = false + yyq61[1] = x.Value != "" + yyq61[2] = x.Dir != false + yyq61[3] = x.Expiration != nil + yyq61[4] = x.TTL != 0 + yyq61[5] = len(x.Nodes) != 0 + yyq61[6] = x.ModifiedIndex != 0 + yyq61[7] = x.CreatedIndex != 0 + if yyr61 || yy2arr61 { + r.EncodeArrayStart(8) } else { - r.EncodeString(codecSelferC_UTF84402, "") + var yynn61 int = 1 + for _, b := range yyq61 { + if b { + yynn61++ + } + } + r.EncodeMapStart(yynn61) } - } else { - if yyq36[1] { - if yyfirst36 { - r.EncodeMapEntrySeparator() + if yyr61 || yy2arr61 { + yym63 := z.EncBinary() + _ = yym63 + if false { } else { - yyfirst36 = true - } - r.EncodeString(codecSelferC_UTF84402, string("value")) - if yysep36 { - r.EncodeMapKVSeparator() + r.EncodeString(codecSelferC_UTF86669, string(x.Key)) } - r.EncodeString(codecSelferC_UTF84402, string(x.Value)) - } - } - if yyr36 || yy2arr36 { - if yysep36 { - r.EncodeArrayEntrySeparator() - } - if yyq36[2] { - r.EncodeBool(bool(x.Dir)) } else { - r.EncodeBool(false) - } - } else { - if yyq36[2] { - if yyfirst36 { - r.EncodeMapEntrySeparator() + r.EncodeString(codecSelferC_UTF86669, string("key")) + yym64 := z.EncBinary() + _ = yym64 + if false { } else { - yyfirst36 = true - } - r.EncodeString(codecSelferC_UTF84402, string("dir")) - if yysep36 { - r.EncodeMapKVSeparator() + r.EncodeString(codecSelferC_UTF86669, string(x.Key)) } - r.EncodeBool(bool(x.Dir)) - } - } - if yyr36 || yy2arr36 { - if yysep36 { - r.EncodeArrayEntrySeparator() } - if yyq36[3] { - if x.Expiration == nil { - r.EncodeNil() + if yyr61 || yy2arr61 { + if yyq61[1] { + yym66 := z.EncBinary() + _ = yym66 + if false { + } else { + r.EncodeString(codecSelferC_UTF86669, string(x.Value)) + } } else { - z.EncFallback(x.Expiration) + r.EncodeString(codecSelferC_UTF86669, "") } } else { - r.EncodeNil() - } - } else { - if yyq36[3] { - if yyfirst36 { - r.EncodeMapEntrySeparator() - } else { - yyfirst36 = true - } - r.EncodeString(codecSelferC_UTF84402, string("expiration")) - if yysep36 { - r.EncodeMapKVSeparator() + if yyq61[1] { + r.EncodeString(codecSelferC_UTF86669, string("value")) + yym67 := z.EncBinary() + _ = yym67 + if false { + } else { + r.EncodeString(codecSelferC_UTF86669, string(x.Value)) + } } - if x.Expiration == nil { - r.EncodeNil() + } + if yyr61 || yy2arr61 { + if yyq61[2] { + yym69 := z.EncBinary() + _ = yym69 + if false { + } else { + r.EncodeBool(bool(x.Dir)) + } } else { - z.EncFallback(x.Expiration) + r.EncodeBool(false) } - } - } - if yyr36 || yy2arr36 { - if yysep36 { - r.EncodeArrayEntrySeparator() - } - if yyq36[4] { - r.EncodeInt(int64(x.TTL)) } else { - r.EncodeInt(0) + if yyq61[2] { + r.EncodeString(codecSelferC_UTF86669, string("dir")) + yym70 := z.EncBinary() + _ = yym70 + if false { + } else { + r.EncodeBool(bool(x.Dir)) + } + } } - } else { - if yyq36[4] { - if yyfirst36 { - r.EncodeMapEntrySeparator() + if yyr61 || yy2arr61 { + if yyq61[3] { + if x.Expiration == nil { + r.EncodeNil() + } else { + yym72 := z.EncBinary() + _ = yym72 + if false { + } else if yym73 := z.TimeRtidIfBinc(); yym73 != 0 { + r.EncodeBuiltin(yym73, x.Expiration) + } else if z.HasExtensions() && z.EncExt(x.Expiration) { + } else if yym72 { + z.EncBinaryMarshal(x.Expiration) + } else if !yym72 && z.IsJSONHandle() { + z.EncJSONMarshal(x.Expiration) + } else { + z.EncFallback(x.Expiration) + } + } } else { - yyfirst36 = true + r.EncodeNil() } - r.EncodeString(codecSelferC_UTF84402, string("ttl")) - if yysep36 { - r.EncodeMapKVSeparator() + } else { + if yyq61[3] { + r.EncodeString(codecSelferC_UTF86669, string("expiration")) + if x.Expiration == nil { + r.EncodeNil() + } else { + yym74 := z.EncBinary() + _ = yym74 + if false { + } else if yym75 := z.TimeRtidIfBinc(); yym75 != 0 { + r.EncodeBuiltin(yym75, x.Expiration) + } else if z.HasExtensions() && z.EncExt(x.Expiration) { + } else if yym74 { + z.EncBinaryMarshal(x.Expiration) + } else if !yym74 && z.IsJSONHandle() { + z.EncJSONMarshal(x.Expiration) + } else { + z.EncFallback(x.Expiration) + } + } } - r.EncodeInt(int64(x.TTL)) - } - } - if yyr36 || yy2arr36 { - if yysep36 { - r.EncodeArrayEntrySeparator() } - if yyq36[5] { - if x.Nodes == nil { - r.EncodeNil() + if yyr61 || yy2arr61 { + if yyq61[4] { + yym77 := z.EncBinary() + _ = yym77 + if false { + } else { + r.EncodeInt(int64(x.TTL)) + } } else { - x.Nodes.CodecEncodeSelf(e) + r.EncodeInt(0) } } else { - r.EncodeNil() + if yyq61[4] { + r.EncodeString(codecSelferC_UTF86669, string("ttl")) + yym78 := z.EncBinary() + _ = yym78 + if false { + } else { + r.EncodeInt(int64(x.TTL)) + } + } } - } else { - if yyq36[5] { - if yyfirst36 { - r.EncodeMapEntrySeparator() + if yyr61 || yy2arr61 { + if yyq61[5] { + if x.Nodes == nil { + r.EncodeNil() + } else { + x.Nodes.CodecEncodeSelf(e) + } } else { - yyfirst36 = true - } - r.EncodeString(codecSelferC_UTF84402, string("nodes")) - if yysep36 { - r.EncodeMapKVSeparator() - } - if x.Nodes == nil { r.EncodeNil() - } else { - x.Nodes.CodecEncodeSelf(e) } - } - } - if yyr36 || yy2arr36 { - if yysep36 { - r.EncodeArrayEntrySeparator() - } - if yyq36[6] { - r.EncodeUint(uint64(x.ModifiedIndex)) } else { - r.EncodeUint(0) + if yyq61[5] { + r.EncodeString(codecSelferC_UTF86669, string("nodes")) + if x.Nodes == nil { + r.EncodeNil() + } else { + x.Nodes.CodecEncodeSelf(e) + } + } } - } else { - if yyq36[6] { - if yyfirst36 { - r.EncodeMapEntrySeparator() + if yyr61 || yy2arr61 { + if yyq61[6] { + yym81 := z.EncBinary() + _ = yym81 + if false { + } else { + r.EncodeUint(uint64(x.ModifiedIndex)) + } } else { - yyfirst36 = true - } - r.EncodeString(codecSelferC_UTF84402, string("modifiedIndex")) - if yysep36 { - r.EncodeMapKVSeparator() + r.EncodeUint(0) } - r.EncodeUint(uint64(x.ModifiedIndex)) - } - } - if yyr36 || yy2arr36 { - if yysep36 { - r.EncodeArrayEntrySeparator() - } - if yyq36[7] { - r.EncodeUint(uint64(x.CreatedIndex)) } else { - r.EncodeUint(0) + if yyq61[6] { + r.EncodeString(codecSelferC_UTF86669, string("modifiedIndex")) + yym82 := z.EncBinary() + _ = yym82 + if false { + } else { + r.EncodeUint(uint64(x.ModifiedIndex)) + } + } } - } else { - if yyq36[7] { - if yyfirst36 { - r.EncodeMapEntrySeparator() + if yyr61 || yy2arr61 { + if yyq61[7] { + yym84 := z.EncBinary() + _ = yym84 + if false { + } else { + r.EncodeUint(uint64(x.CreatedIndex)) + } } else { - yyfirst36 = true + r.EncodeUint(0) } - r.EncodeString(codecSelferC_UTF84402, string("createdIndex")) - if yysep36 { - r.EncodeMapKVSeparator() + } else { + if yyq61[7] { + r.EncodeString(codecSelferC_UTF86669, string("createdIndex")) + yym85 := z.EncBinary() + _ = yym85 + if false { + } else { + r.EncodeUint(uint64(x.CreatedIndex)) + } } - r.EncodeUint(uint64(x.CreatedIndex)) } - } - if yysep36 { - if yyr36 || yy2arr36 { - r.EncodeArrayEnd() - } else { - r.EncodeMapEnd() + if yysep61 { + r.EncodeEnd() } } } } func (x *Node) CodecDecodeSelf(d *codec1978.Decoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - if r.IsContainerType(codecSelverValueTypeMap4402) { - yyl45 := r.ReadMapStart() - if yyl45 == 0 { - r.ReadMapEnd() - } else { - x.codecDecodeSelfFromMap(yyl45, d) - } - } else if r.IsContainerType(codecSelverValueTypeArray4402) { - yyl45 := r.ReadArrayStart() - if yyl45 == 0 { - r.ReadArrayEnd() + yym86 := z.DecBinary() + _ = yym86 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + if r.IsContainerType(codecSelverValueTypeMap6669) { + yyl87 := r.ReadMapStart() + if yyl87 == 0 { + r.ReadEnd() + } else { + x.codecDecodeSelfFromMap(yyl87, d) + } + } else if r.IsContainerType(codecSelverValueTypeArray6669) { + yyl87 := r.ReadArrayStart() + if yyl87 == 0 { + r.ReadEnd() + } else { + x.codecDecodeSelfFromArray(yyl87, d) + } } else { - x.codecDecodeSelfFromArray(yyl45, d) + panic(codecSelferOnlyMapOrArrayEncodeToStructErr6669) } - } else { - panic(codecSelferOnlyMapOrArrayEncodeToStructErr4402) } } func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yys46Slc = z.DecScratchBuffer() // default slice to decode into - _ = yys46Slc - var yyhl46 bool = l >= 0 - for yyj46 := 0; ; yyj46++ { - if yyhl46 { - if yyj46 >= l { + var yys88Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys88Slc + var yyhl88 bool = l >= 0 + for yyj88 := 0; ; yyj88++ { + if yyhl88 { + if yyj88 >= l { break } } else { if r.CheckBreak() { break } - if yyj46 > 0 { - r.ReadMapEntrySeparator() - } - } - yys46Slc = r.DecodeBytes(yys46Slc, true, true) - yys46 := string(yys46Slc) - if !yyhl46 { - r.ReadMapKVSeparator() } - switch yys46 { + yys88Slc = r.DecodeBytes(yys88Slc, true, true) + yys88 := string(yys88Slc) + switch yys88 { case "key": if r.TryDecodeAsNil() { x.Key = "" @@ -993,7 +1007,19 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { if x.Expiration == nil { x.Expiration = new(time.Time) } - z.DecFallback(x.Expiration, false) + yym93 := z.DecBinary() + _ = yym93 + if false { + } else if yym94 := z.TimeRtidIfBinc(); yym94 != 0 { + r.DecodeBuiltin(yym94, x.Expiration) + } else if z.HasExtensions() && z.DecExt(x.Expiration) { + } else if yym93 { + z.DecBinaryUnmarshal(x.Expiration) + } else if !yym93 && z.IsJSONHandle() { + z.DecJSONUnmarshal(x.Expiration) + } else { + z.DecFallback(x.Expiration, false) + } } case "ttl": if r.TryDecodeAsNil() { @@ -1005,8 +1031,8 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Nodes = nil } else { - yyv52 := &x.Nodes - yyv52.CodecDecodeSelf(d) + yyv96 := &x.Nodes + yyv96.CodecDecodeSelf(d) } case "modifiedIndex": if r.TryDecodeAsNil() { @@ -1021,29 +1047,29 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { x.CreatedIndex = uint64(r.DecodeUint(64)) } default: - z.DecStructFieldNotFound(-1, yys46) - } // end switch yys46 - } // end for yyj46 - if !yyhl46 { - r.ReadMapEnd() + z.DecStructFieldNotFound(-1, yys88) + } // end switch yys88 + } // end for yyj88 + if !yyhl88 { + r.ReadEnd() } } func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj55 int - var yyb55 bool - var yyhl55 bool = l >= 0 - yyj55++ - if yyhl55 { - yyb55 = yyj55 > l + var yyj99 int + var yyb99 bool + var yyhl99 bool = l >= 0 + yyj99++ + if yyhl99 { + yyb99 = yyj99 > l } else { - yyb55 = r.CheckBreak() + yyb99 = r.CheckBreak() } - if yyb55 { - r.ReadArrayEnd() + if yyb99 { + r.ReadEnd() return } if r.TryDecodeAsNil() { @@ -1051,49 +1077,46 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.Key = string(r.DecodeString()) } - yyj55++ - if yyhl55 { - yyb55 = yyj55 > l + yyj99++ + if yyhl99 { + yyb99 = yyj99 > l } else { - yyb55 = r.CheckBreak() + yyb99 = r.CheckBreak() } - if yyb55 { - r.ReadArrayEnd() + if yyb99 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { x.Value = "" } else { x.Value = string(r.DecodeString()) } - yyj55++ - if yyhl55 { - yyb55 = yyj55 > l + yyj99++ + if yyhl99 { + yyb99 = yyj99 > l } else { - yyb55 = r.CheckBreak() + yyb99 = r.CheckBreak() } - if yyb55 { - r.ReadArrayEnd() + if yyb99 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { x.Dir = false } else { x.Dir = bool(r.DecodeBool()) } - yyj55++ - if yyhl55 { - yyb55 = yyj55 > l + yyj99++ + if yyhl99 { + yyb99 = yyj99 > l } else { - yyb55 = r.CheckBreak() + yyb99 = r.CheckBreak() } - if yyb55 { - r.ReadArrayEnd() + if yyb99 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { if x.Expiration != nil { x.Expiration = nil @@ -1102,308 +1125,308 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.Expiration == nil { x.Expiration = new(time.Time) } - z.DecFallback(x.Expiration, false) + yym104 := z.DecBinary() + _ = yym104 + if false { + } else if yym105 := z.TimeRtidIfBinc(); yym105 != 0 { + r.DecodeBuiltin(yym105, x.Expiration) + } else if z.HasExtensions() && z.DecExt(x.Expiration) { + } else if yym104 { + z.DecBinaryUnmarshal(x.Expiration) + } else if !yym104 && z.IsJSONHandle() { + z.DecJSONUnmarshal(x.Expiration) + } else { + z.DecFallback(x.Expiration, false) + } } - yyj55++ - if yyhl55 { - yyb55 = yyj55 > l + yyj99++ + if yyhl99 { + yyb99 = yyj99 > l } else { - yyb55 = r.CheckBreak() + yyb99 = r.CheckBreak() } - if yyb55 { - r.ReadArrayEnd() + if yyb99 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { x.TTL = 0 } else { x.TTL = int64(r.DecodeInt(64)) } - yyj55++ - if yyhl55 { - yyb55 = yyj55 > l + yyj99++ + if yyhl99 { + yyb99 = yyj99 > l } else { - yyb55 = r.CheckBreak() + yyb99 = r.CheckBreak() } - if yyb55 { - r.ReadArrayEnd() + if yyb99 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { x.Nodes = nil } else { - yyv61 := &x.Nodes - yyv61.CodecDecodeSelf(d) + yyv107 := &x.Nodes + yyv107.CodecDecodeSelf(d) } - yyj55++ - if yyhl55 { - yyb55 = yyj55 > l + yyj99++ + if yyhl99 { + yyb99 = yyj99 > l } else { - yyb55 = r.CheckBreak() + yyb99 = r.CheckBreak() } - if yyb55 { - r.ReadArrayEnd() + if yyb99 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { x.ModifiedIndex = 0 } else { x.ModifiedIndex = uint64(r.DecodeUint(64)) } - yyj55++ - if yyhl55 { - yyb55 = yyj55 > l + yyj99++ + if yyhl99 { + yyb99 = yyj99 > l } else { - yyb55 = r.CheckBreak() + yyb99 = r.CheckBreak() } - if yyb55 { - r.ReadArrayEnd() + if yyb99 { + r.ReadEnd() return } - r.ReadArrayEntrySeparator() if r.TryDecodeAsNil() { x.CreatedIndex = 0 } else { x.CreatedIndex = uint64(r.DecodeUint(64)) } for { - yyj55++ - if yyhl55 { - yyb55 = yyj55 > l + yyj99++ + if yyhl99 { + yyb99 = yyj99 > l } else { - yyb55 = r.CheckBreak() + yyb99 = r.CheckBreak() } - if yyb55 { + if yyb99 { break } - if yyj55 > 1 { - r.ReadArrayEntrySeparator() - } - z.DecStructFieldNotFound(yyj55-1, "") + z.DecStructFieldNotFound(yyj99-1, "") } - r.ReadArrayEnd() + r.ReadEnd() } func (x Nodes) CodecEncodeSelf(e *codec1978.Encoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r if x == nil { r.EncodeNil() } else { - h.encNodes(Nodes(x), e) + yym110 := z.EncBinary() + _ = yym110 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + h.encNodes((Nodes)(x), e) + } } } func (x *Nodes) CodecDecodeSelf(d *codec1978.Decoder) { - var h codecSelfer4402 + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - h.decNodes((*Nodes)(x), d) + yym111 := z.DecBinary() + _ = yym111 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + h.decNodes((*Nodes)(x), d) + } } -func (x codecSelfer4402) enchttp_Header(v http.Header, e *codec1978.Encoder) { - var h codecSelfer4402 +func (x codecSelfer6669) enchttp_Header(v pkg1_http.Header, e *codec1978.Encoder) { + var h codecSelfer6669 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r r.EncodeMapStart(len(v)) - yys64 := !z.EncBinary() - yyj64 := 0 - if yys64 { - for yyk64, yyv64 := range v { - if yyj64 > 0 { - r.EncodeMapEntrySeparator() - } - r.EncodeString(codecSelferC_UTF84402, string(yyk64)) - r.EncodeMapKVSeparator() - if yyv64 == nil { - r.EncodeNil() - } else { - z.F.EncSliceStringV(yyv64, false, e) - } - yyj64++ + for yyk112, yyv112 := range v { + yym113 := z.EncBinary() + _ = yym113 + if false { + } else { + r.EncodeString(codecSelferC_UTF86669, string(yyk112)) } - r.EncodeMapEnd() - } else { - for yyk64, yyv64 := range v { - r.EncodeString(codecSelferC_UTF84402, string(yyk64)) - if yyv64 == nil { - r.EncodeNil() + if yyv112 == nil { + r.EncodeNil() + } else { + yym114 := z.EncBinary() + _ = yym114 + if false { } else { - z.F.EncSliceStringV(yyv64, false, e) + z.F.EncSliceStringV(yyv112, false, e) } } } + r.EncodeEnd() } -func (x codecSelfer4402) dechttp_Header(v *http.Header, d *codec1978.Decoder) { - var h codecSelfer4402 +func (x codecSelfer6669) dechttp_Header(v *pkg1_http.Header, d *codec1978.Decoder) { + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - yyv65 := *v - yyl65 := r.ReadMapStart() - if yyv65 == nil { - if yyl65 > 0 { - yyv65 = make(map[string][]string, yyl65) + yyv115 := *v + yyl115 := r.ReadMapStart() + if yyv115 == nil { + if yyl115 > 0 { + yyv115 = make(map[string][]string, yyl115) } else { - yyv65 = make(map[string][]string) // supports indefinite-length, etc + yyv115 = make(map[string][]string) // supports indefinite-length, etc } - *v = yyv65 + *v = yyv115 } - if yyl65 > 0 { - for yyj65 := 0; yyj65 < yyl65; yyj65++ { - var yymk65 string + if yyl115 > 0 { + for yyj115 := 0; yyj115 < yyl115; yyj115++ { + var yymk115 string if r.TryDecodeAsNil() { - yymk65 = "" + yymk115 = "" } else { - yymk65 = string(r.DecodeString()) + yymk115 = string(r.DecodeString()) } - yymv65 := yyv65[yymk65] + yymv115 := yyv115[yymk115] if r.TryDecodeAsNil() { - yymv65 = nil + yymv115 = nil } else { - yyv67 := &yymv65 - z.F.DecSliceStringX(yyv67, false, d) + yyv117 := &yymv115 + yym118 := z.DecBinary() + _ = yym118 + if false { + } else { + z.F.DecSliceStringX(yyv117, false, d) + } } - if yyv65 != nil { - yyv65[yymk65] = yymv65 + if yyv115 != nil { + yyv115[yymk115] = yymv115 } } - } else if yyl65 < 0 { - for yyj65 := 0; !r.CheckBreak(); yyj65++ { - if yyj65 > 0 { - r.ReadMapEntrySeparator() - } - var yymk65 string + } else if yyl115 < 0 { + for yyj115 := 0; !r.CheckBreak(); yyj115++ { + var yymk115 string if r.TryDecodeAsNil() { - yymk65 = "" + yymk115 = "" } else { - yymk65 = string(r.DecodeString()) + yymk115 = string(r.DecodeString()) } - r.ReadMapKVSeparator() - yymv65 := yyv65[yymk65] + yymv115 := yyv115[yymk115] if r.TryDecodeAsNil() { - yymv65 = nil + yymv115 = nil } else { - yyv69 := &yymv65 - z.F.DecSliceStringX(yyv69, false, d) + yyv120 := &yymv115 + yym121 := z.DecBinary() + _ = yym121 + if false { + } else { + z.F.DecSliceStringX(yyv120, false, d) + } } - if yyv65 != nil { - yyv65[yymk65] = yymv65 + if yyv115 != nil { + yyv115[yymk115] = yymv115 } } - r.ReadMapEnd() + r.ReadEnd() } // else len==0: TODO: Should we clear map entries? } -func (x codecSelfer4402) encNodes(v Nodes, e *codec1978.Encoder) { - var h codecSelfer4402 +func (x codecSelfer6669) encNodes(v Nodes, e *codec1978.Encoder) { + var h codecSelfer6669 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r r.EncodeArrayStart(len(v)) - yys70 := !z.EncBinary() - if yys70 { - for yyi70, yyv70 := range v { - if yyi70 > 0 { - r.EncodeArrayEntrySeparator() - } - if yyv70 == nil { - r.EncodeNil() - } else { - yyv70.CodecEncodeSelf(e) - } - } - r.EncodeArrayEnd() - } else { - for _, yyv70 := range v { - if yyv70 == nil { - r.EncodeNil() - } else { - yyv70.CodecEncodeSelf(e) - } + for _, yyv122 := range v { + if yyv122 == nil { + r.EncodeNil() + } else { + yyv122.CodecEncodeSelf(e) } } + r.EncodeEnd() } -func (x codecSelfer4402) decNodes(v *Nodes, d *codec1978.Decoder) { - var h codecSelfer4402 +func (x codecSelfer6669) decNodes(v *Nodes, d *codec1978.Decoder) { + var h codecSelfer6669 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - yyv71 := *v - yyh71, yyl71 := z.DecSliceHelperStart() + yyv123 := *v + yyh123, yyl123 := z.DecSliceHelperStart() + + var yyc123 bool + _ = yyc123 - var yyc71 bool - if yyv71 == nil { - if yyl71 <= 0 { - yyv71 = make(Nodes, 0) + if yyv123 == nil { + if yyl123 <= 0 { + yyv123 = make(Nodes, 0) } else { - yyv71 = make(Nodes, yyl71) + yyv123 = make(Nodes, yyl123) } - yyc71 = true + yyc123 = true } - if yyl71 == 0 { - if len(yyv71) != 0 { - yyv71 = yyv71[:0] - yyc71 = true + if yyl123 == 0 { + if len(yyv123) != 0 { + yyv123 = yyv123[:0] + yyc123 = true } - } else if yyl71 > 0 { + } else if yyl123 > 0 { - yyn71 := yyl71 - if yyl71 > cap(yyv71) { - yyv71 = make([]*Node, yyl71, yyl71) - yyc71 = true + yyn123 := yyl123 + if yyl123 > cap(yyv123) { + yyv123 = make([]*Node, yyl123, yyl123) + yyc123 = true - } else if yyl71 != len(yyv71) { - yyv71 = yyv71[:yyl71] - yyc71 = true + } else if yyl123 != len(yyv123) { + yyv123 = yyv123[:yyl123] + yyc123 = true } - yyj71 := 0 - for ; yyj71 < yyn71; yyj71++ { + yyj123 := 0 + for ; yyj123 < yyn123; yyj123++ { if r.TryDecodeAsNil() { - if yyv71[yyj71] != nil { - *yyv71[yyj71] = Node{} + if yyv123[yyj123] != nil { + *yyv123[yyj123] = Node{} } } else { - if yyv71[yyj71] == nil { - yyv71[yyj71] = new(Node) + if yyv123[yyj123] == nil { + yyv123[yyj123] = new(Node) } - yyw72 := yyv71[yyj71] - yyw72.CodecDecodeSelf(d) + yyw124 := yyv123[yyj123] + yyw124.CodecDecodeSelf(d) } } } else { - for yyj71 := 0; !r.CheckBreak(); yyj71++ { - if yyj71 >= len(yyv71) { - yyv71 = append(yyv71, nil) // var yyz71 *Node - yyc71 = true - } - if yyj71 > 0 { - yyh71.Sep(yyj71) + for yyj123 := 0; !r.CheckBreak(); yyj123++ { + if yyj123 >= len(yyv123) { + yyv123 = append(yyv123, nil) // var yyz123 *Node + yyc123 = true } - if yyj71 < len(yyv71) { + if yyj123 < len(yyv123) { if r.TryDecodeAsNil() { - if yyv71[yyj71] != nil { - *yyv71[yyj71] = Node{} + if yyv123[yyj123] != nil { + *yyv123[yyj123] = Node{} } } else { - if yyv71[yyj71] == nil { - yyv71[yyj71] = new(Node) + if yyv123[yyj123] == nil { + yyv123[yyj123] = new(Node) } - yyw73 := yyv71[yyj71] - yyw73.CodecDecodeSelf(d) + yyw125 := yyv123[yyj123] + yyw125.CodecDecodeSelf(d) } } else { @@ -1411,9 +1434,10 @@ func (x codecSelfer4402) decNodes(v *Nodes, d *codec1978.Decoder) { } } - yyh71.End() + yyh123.End() } - if yyc71 { - *v = yyv71 + if yyc123 { + *v = yyv123 } + } diff --git a/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/shuffle.go b/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/shuffle.go new file mode 100644 index 000000000000..c26ddac30cf6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd/shuffle.go @@ -0,0 +1,19 @@ +package etcd + +import ( + "math/rand" +) + +func shuffleStringSlice(cards []string) []string { + size := len(cards) + //Do not need to copy if nothing changed + if size <= 1 { + return cards + } + shuffled := make([]string, size) + index := rand.Perm(size) + for i := range cards { + shuffled[index[i]] = cards[i] + } + return shuffled +} From 6a99c8ccd1f92507ead04896cc9b5f38dafbc1a6 Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 15 Oct 2015 12:42:46 -0400 Subject: [PATCH 05/35] bump(k8s.io/kubernetes): 4c8e6f47ec23f390978e651232b375f5f9cde3c7 --- Godeps/Godeps.json | 505 +- .../github.com/ClusterHQ/flocker-go/README.md | 18 + .../github.com/ClusterHQ/flocker-go/client.go | 323 + .../ClusterHQ/flocker-go/client_test.go | 316 + .../github.com/ClusterHQ/flocker-go/doc.go | 2 + .../github.com/ClusterHQ/flocker-go/util.go | 34 + .../compute/metadata/metadata.go | 279 - .../util/mount/safe_format_and_mount_test.go | 172 - .../src/github.com/appc/cni/libcni/api.go | 65 + .../src/github.com/appc/cni/libcni/conf.go | 85 + .../github.com/appc/cni/pkg/invoke/args.go | 76 + .../github.com/appc/cni/pkg/invoke/exec.go | 80 + .../github.com/appc/cni/pkg/invoke/find.go | 37 + .../src/github.com/appc/cni/pkg/types/args.go | 50 + .../github.com/appc/cni/pkg/types/types.go | 166 + .../aws/aws-sdk-go/aws/awserr/error.go | 47 +- .../apierr/error.go => aws/awserr/types.go} | 96 +- .../aws/aws-sdk-go/aws/awsutil/copy.go | 8 + .../aws/aws-sdk-go/aws/awsutil/copy_test.go | 12 +- .../aws/aws-sdk-go/aws/awsutil/path_value.go | 12 + .../aws-sdk-go/aws/awsutil/path_value_test.go | 7 +- .../awsutil/{string_value.go => prettify.go} | 16 +- .../github.com/aws/aws-sdk-go/aws/config.go | 319 +- .../aws/aws-sdk-go/aws/config_test.go | 80 + .../aws/aws-sdk-go/aws/convert_types.go | 357 + .../aws/aws-sdk-go/aws/convert_types_test.go | 437 + .../handlers.go} | 97 +- .../aws/corehandlers/handlers_test.go | 107 + .../aws/corehandlers/param_validator.go | 144 + .../aws/corehandlers/param_validator_test.go | 134 + .../aws/credentials/chain_provider.go | 10 +- .../aws/credentials/chain_provider_test.go | 10 +- .../aws-sdk-go/aws/credentials/credentials.go | 48 +- .../aws/credentials/credentials_test.go | 3 +- .../aws/credentials/ec2_role_provider_test.go | 114 - .../{ => ec2rolecreds}/ec2_role_provider.go | 107 +- .../ec2rolecreds/ec2_role_provider_test.go | 161 + .../aws/credentials/env_provider.go | 16 +- .../shared_credentials_provider.go | 24 +- .../shared_credentials_provider_test.go | 25 +- .../aws/credentials/static_provider.go | 6 +- .../stscreds/assume_role_provider.go | 125 + .../stscreds/assume_role_provider_test.go | 59 + .../aws/aws-sdk-go/aws/defaults/defaults.go | 39 + .../aws/aws-sdk-go/aws/ec2metadata/api.go | 43 + .../aws-sdk-go/aws/ec2metadata/api_test.go | 100 + .../aws/aws-sdk-go/aws/ec2metadata/service.go | 135 + .../github.com/aws/aws-sdk-go/aws/errors.go | 17 + .../aws-sdk-go/aws/handler_functions_test.go | 81 - .../aws/aws-sdk-go/aws/handlers_test.go | 31 - .../github.com/aws/aws-sdk-go/aws/logger.go | 98 + .../aws/aws-sdk-go/aws/param_validator.go | 89 - .../aws-sdk-go/aws/param_validator_test.go | 84 - .../aws-sdk-go/aws/{ => request}/handlers.go | 53 +- .../aws-sdk-go/aws/request/handlers_test.go | 47 + .../aws-sdk-go/aws/{ => request}/request.go | 68 +- .../{ => request}/request_pagination_test.go | 90 +- .../aws/{ => request}/request_test.go | 96 +- .../aws/aws-sdk-go/aws/request/retryer.go | 71 + .../github.com/aws/aws-sdk-go/aws/service.go | 177 - .../aws-sdk-go/aws/service/default_retryer.go | 51 + .../aws/aws-sdk-go/aws/service/service.go | 133 + .../aws/service/serviceinfo/service_info.go | 15 + .../github.com/aws/aws-sdk-go/aws/types.go | 93 +- .../aws/aws-sdk-go/aws/types_test.go | 56 + .../github.com/aws/aws-sdk-go/aws/version.go | 2 +- .../internal/endpoints/endpoints.go | 1 + .../internal/endpoints/endpoints_map.go | 42 +- .../internal/protocol/ec2query/build.go | 8 +- .../internal/protocol/ec2query/build_test.go | 439 +- .../internal/protocol/ec2query/unmarshal.go | 18 +- .../protocol/ec2query/unmarshal_test.go | 347 +- .../internal/protocol/query/build.go | 8 +- .../internal/protocol/query/build_test.go | 730 +- .../internal/protocol/query/unmarshal.go | 10 +- .../protocol/query/unmarshal_error.go | 12 +- .../internal/protocol/query/unmarshal_test.go | 599 +- .../internal/protocol/rest/build.go | 35 +- .../internal/protocol/rest/unmarshal.go | 27 +- .../protocol/xml/xmlutil/unmarshal.go | 2 +- .../aws/aws-sdk-go/internal/signer/v4/v4.go | 171 +- .../aws-sdk-go/internal/signer/v4/v4_test.go | 117 +- .../aws/aws-sdk-go/service/autoscaling/api.go | 3474 +- .../autoscaling/autoscalingiface/interface.go | 119 + .../service/autoscaling/examples_test.go | 1039 +- .../aws-sdk-go/service/autoscaling/service.go | 28 +- .../aws/aws-sdk-go/service/ec2/api.go | 15083 ++++-- .../aws-sdk-go/service/ec2/customizations.go | 22 +- .../service/ec2/customizations_test.go | 4 +- .../service/ec2/ec2iface/interface.go | 491 +- .../aws-sdk-go/service/ec2/examples_test.go | 5169 +- .../aws/aws-sdk-go/service/ec2/service.go | 29 +- .../aws/aws-sdk-go/service/elb/api.go | 1441 +- .../service/elb/elbiface/interface.go | 59 + .../aws-sdk-go/service/elb/examples_test.go | 578 +- .../aws/aws-sdk-go/service/elb/service.go | 38 +- .../testdata/draft-ietf-httpbis-http2.xml | 5021 ++ .../gogo/protobuf/proto/all_test.go | 52 + .../github.com/gogo/protobuf/proto/clone.go | 11 + .../gogo/protobuf/proto/clone_test.go | 22 + .../github.com/gogo/protobuf/proto/decode.go | 40 +- .../github.com/gogo/protobuf/proto/encode.go | 57 +- .../github.com/gogo/protobuf/proto/equal.go | 11 + .../gogo/protobuf/proto/equal_test.go | 18 + .../src/github.com/gogo/protobuf/proto/lib.go | 72 +- .../gogo/protobuf/proto/properties.go | 65 +- .../protobuf/proto/proto3_proto/proto3.pb.go | 4 + .../gogo/protobuf/proto/size_test.go | 5 + .../gogo/protobuf/proto/testdata/Makefile | 37 + .../protobuf/proto/testdata/golden_test.go | 86 + .../gogo/protobuf/proto/testdata/test.pb.go | 2948 ++ .../protobuf/proto/testdata/test.pb.go.golden | 1737 + .../gogo/protobuf/proto/testdata/test.proto | 494 + .../github.com/gogo/protobuf/proto/text.go | 61 +- .../gogo/protobuf/proto/text_parser.go | 176 +- .../gogo/protobuf/proto/text_parser_test.go | 12 + .../gogo/protobuf/proto/text_test.go | 24 + .../jonboulle/clockwork/.travis.yml | 3 + .../mesos/mesos-go/detector/zoo/client.go | 444 - .../mesos/mesos-go/detector/zoo/client2.go | 88 + .../mesos-go/detector/zoo/client_test.go | 342 - .../mesos/mesos-go/detector/zoo/detect.go | 214 +- .../mesos-go/detector/zoo/detect_test.go | 552 +- .../mesos-go/detector/zoo/mocked_detect.go | 88 - .../mesos/mesos-go/detector/zoo/types.go | 6 - .../mesos-go/mesosproto/authentication.pb.go | 255 + .../mesos-go/mesosproto/authentication.proto | 53 + .../mesos-go/mesosproto/containerizer.pb.go | 31 +- .../mesos-go/mesosproto/containerizer.proto | 2 + .../mesos/mesos-go/mesosproto/internal.pb.go | 7 +- .../mesos/mesos-go/mesosproto/log.pb.go | 6760 +-- .../mesos/mesos-go/mesosproto/logpb_test.go | 2675 +- .../mesos/mesos-go/mesosproto/mesos.pb.go | 43782 ++++++++++------ .../mesos/mesos-go/mesosproto/mesos.proto | 461 +- .../mesos/mesos-go/mesosproto/mesospb_test.go | 15069 ++++-- .../mesos/mesos-go/mesosproto/messages.pb.go | 383 +- .../mesos/mesos-go/mesosproto/messages.proto | 136 +- .../mesos/mesos-go/mesosproto/registry.pb.go | 7 +- .../mesos/mesos-go/mesosproto/scheduler.pb.go | 508 +- .../mesos/mesos-go/mesosproto/scheduler.proto | 246 +- .../mesos/mesos-go/mesosproto/state.pb.go | 2417 +- .../mesos/mesos-go/mesosproto/statepb_test.go | 975 +- .../mesos/mesos-go/mesosutil/constants.go | 2 +- .../github.com/mesos/mesos-go/upid/upid.go | 5 +- .../prometheus/common/expfmt/bench_test.go | 171 + .../prometheus/common/expfmt/decode.go | 410 + .../prometheus/common/expfmt/decode_test.go | 373 + .../prometheus/common/expfmt/encode.go | 88 + .../prometheus/common/expfmt/expfmt.go | 37 + .../prometheus/common/expfmt/fuzz.go | 36 + .../expfmt/fuzz/corpus/from_test_parse_0 | 2 + .../expfmt/fuzz/corpus/from_test_parse_1 | 6 + .../expfmt/fuzz/corpus/from_test_parse_2 | 12 + .../expfmt/fuzz/corpus/from_test_parse_3 | 22 + .../expfmt/fuzz/corpus/from_test_parse_4 | 10 + .../fuzz/corpus/from_test_parse_error_0 | 1 + .../fuzz/corpus/from_test_parse_error_1 | 1 + .../fuzz/corpus/from_test_parse_error_10 | 1 + .../fuzz/corpus/from_test_parse_error_11 | 1 + .../fuzz/corpus/from_test_parse_error_12 | 3 + .../fuzz/corpus/from_test_parse_error_13 | 3 + .../fuzz/corpus/from_test_parse_error_14 | 3 + .../fuzz/corpus/from_test_parse_error_15 | 2 + .../fuzz/corpus/from_test_parse_error_16 | 2 + .../fuzz/corpus/from_test_parse_error_17 | 1 + .../fuzz/corpus/from_test_parse_error_18 | 1 + .../fuzz/corpus/from_test_parse_error_19 | 3 + .../fuzz/corpus/from_test_parse_error_2 | 3 + .../fuzz/corpus/from_test_parse_error_3 | 1 + .../fuzz/corpus/from_test_parse_error_4 | 1 + .../fuzz/corpus/from_test_parse_error_5 | 1 + .../fuzz/corpus/from_test_parse_error_6 | 1 + .../fuzz/corpus/from_test_parse_error_7 | 3 + .../fuzz/corpus/from_test_parse_error_8 | 1 + .../fuzz/corpus/from_test_parse_error_9 | 1 + .../common/expfmt/fuzz/corpus/minimal | 1 + .../prometheus/common/expfmt/json_decode.go | 162 + .../common/expfmt/json_decode_test.go | 124 + .../prometheus/common/expfmt/testdata/json2 | 46 + .../common/expfmt/testdata/protobuf | 516 + .../common/expfmt/testdata/protobuf.gz | 129 + .../prometheus/common/expfmt/testdata/test.gz | 163 + .../prometheus/common/expfmt/testdata/text | 322 + .../prometheus/common/expfmt/text_create.go | 305 + .../common/expfmt/text_create_test.go | 443 + .../prometheus/common/expfmt/text_parse.go | 746 + .../common/expfmt/text_parse_test.go | 586 + .../prometheus/common/model/fingerprinting.go | 105 + .../prometheus/common/model/labels.go | 188 + .../prometheus/common/model/labels_test.go | 91 + .../prometheus/common/model/labelset.go | 153 + .../prometheus/common/model/metric.go | 81 + .../prometheus/common/model/metric_test.go | 83 + .../prometheus/common/model/model.go | 16 + .../prometheus/common/model/signature.go | 190 + .../prometheus/common/model/signature_test.go | 304 + .../prometheus/common/model/time.go | 230 + .../prometheus/common/model/time_test.go | 86 + .../prometheus/common/model/value.go | 395 + .../prometheus/common/model/value_test.go | 362 + .../rackspace/gophercloud/CONTRIBUTING.md | 5 +- .../openstack/compute/v2/network_test.go | 78 + .../openstack/compute/v2/servergroup_test.go | 87 +- .../openstack/compute/v2/servers_test.go | 6 + .../rackspace/identity/v2/tokens_test.go | 61 + .../rackspace/gophercloud/auth_options.go | 4 + .../blockstorage/v1/snapshots/requests.go | 33 + .../blockstorage/v1/volumes/requests.go | 33 + .../blockstorage/v1/volumes/requests_test.go | 13 +- .../blockstorage/v1/volumes/testing/doc.go | 7 + .../{fixtures_test.go => testing/fixtures.go} | 2 +- .../bootfromvolume/requests_test.go | 2 + .../v2/extensions/diskconfig/requests_test.go | 2 + .../compute/v2/extensions/networks/doc.go | 2 + .../v2/extensions/networks/fixtures.go | 209 + .../v2/extensions/networks/requests.go | 22 + .../v2/extensions/networks/requests_test.go | 37 + .../compute/v2/extensions/networks/results.go | 222 + .../compute/v2/extensions/networks/urls.go | 17 + .../v2/extensions/networks/urls_test.go | 25 + .../v2/extensions/schedulerhints/doc.go | 3 + .../v2/extensions/schedulerhints/requests.go | 134 + .../schedulerhints/requests_test.go | 130 + .../v2/extensions/secgroups/fixtures.go | 2 + .../extensions/volumeattach/requests_test.go | 37 +- .../v2/extensions/volumeattach/testing/doc.go | 7 + .../volumeattach/{ => testing}/fixtures.go | 30 +- .../openstack/compute/v2/flavors/requests.go | 35 + .../openstack/compute/v2/images/requests.go | 37 + .../openstack/compute/v2/servers/requests.go | 147 +- .../compute/v2/servers/requests_test.go | 37 + .../openstack/identity/v2/tokens/errors.go | 2 +- .../openstack/identity/v2/tokens/requests.go | 32 +- .../identity/v2/tokens/requests_test.go | 5 +- .../openstack/identity/v3/roles/doc.go | 3 + .../openstack/identity/v3/roles/requests.go | 50 + .../identity/v3/roles/requests_test.go | 104 + .../openstack/identity/v3/roles/results.go | 81 + .../openstack/identity/v3/roles/urls.go | 7 + .../openstack/identity/v3/roles/urls_test.go | 15 + .../fwaas/firewalls/requests_test.go | 4 +- .../extensions/lbaas/pools/requests_test.go | 1 + .../v2/extensions/security/groups/requests.go | 38 + .../v2/extensions/security/rules/requests.go | 5 + .../networking/v2/networks/requests.go | 35 + .../networking/v2/networks/requests_test.go | 1 + .../openstack/networking/v2/ports/requests.go | 35 + .../networking/v2/subnets/requests.go | 39 +- .../networking/v2/subnets/results.go | 4 +- .../networking/v2/subnets/results_test.go | 54 + .../objectstorage/v1/accounts/requests.go | 8 +- .../objectstorage/v1/containers/requests.go | 12 +- .../objectstorage/v1/objects/fixtures.go | 17 +- .../objectstorage/v1/objects/requests.go | 59 +- .../objectstorage/v1/objects/requests_test.go | 35 +- .../orchestration/v1/stackevents/fixtures.go | 14 +- .../orchestration/v1/stackevents/results.go | 6 +- .../v1/stackresources/fixtures.go | 6 +- .../v1/stackresources/requests.go | 10 +- .../v1/stackresources/results.go | 8 +- .../orchestration/v1/stacks/fixtures.go | 8 +- .../orchestration/v1/stacks/results.go | 12 +- .../rackspace/gophercloud/pagination/http.go | 10 +- .../rackspace/gophercloud/pagination/pager.go | 6 +- .../rackspace/gophercloud/provider_client.go | 19 +- .../blockstorage/v1/volumes/delegate_test.go | 9 +- .../v2/bootfromvolume/delegate_test.go | 2 + .../rackspace/compute/v2/flavors/delegate.go | 11 +- .../rackspace/compute/v2/flavors/fixtures.go | 22 +- .../rackspace/compute/v2/flavors/results.go | 104 + .../rackspace/compute/v2/flavors/urls.go | 9 + .../rackspace/compute/v2/servers/requests.go | 37 +- .../compute/v2/servers/requests_test.go | 2 + .../compute/v2/volumeattach/delegate_test.go | 49 +- .../rackspace/lb/v1/nodes/fixtures.go | 36 + .../rackspace/lb/v1/nodes/requests.go | 7 +- .../rackspace/lb/v1/nodes/requests_test.go | 32 + .../rackspace/lb/v1/nodes/results.go | 3 + .../rackspace/lb/v1/sessions/fixtures.go | 1 + .../rackspace/lb/v1/ssl/fixtures.go | 1 + .../rackspace/lb/v1/throttle/fixtures.go | 1 + .../networking/v2/networks/delegate_test.go | 11 +- .../objectstorage/v1/bulk/requests.go | 4 +- .../v1/cdncontainers/requests.go | 12 +- .../objectstorage/v1/objects/delegate.go | 2 +- .../objectstorage/v1/objects/delegate_test.go | 16 +- .../rackspace/gophercloud/results.go | 3 + .../github.com/samuel/go-zookeeper/zk/conn.go | 42 +- .../samuel/go-zookeeper/zk/constants.go | 2 - .../github.com/samuel/go-zookeeper/zk/flw.go | 6 +- .../github.com/samuel/go-zookeeper/zk/lock.go | 13 +- .../samuel/go-zookeeper/zk/structs.go | 7 + .../samuel/go-zookeeper/zk/structs_test.go | 11 + .../src/github.com/spf13/pflag/.travis.yml | 17 + .../src/github.com/spf13/pflag/LICENSE | 28 + .../src/github.com/spf13/pflag/verify/all.sh | 69 + .../github.com/spf13/pflag/verify/gofmt.sh | 19 + .../github.com/spf13/pflag/verify/golint.sh | 15 + .../src/github.com/ugorji/go/codec/0doc.go | 2 +- .../src/github.com/ugorji/go/codec/binc.go | 17 +- .../src/github.com/ugorji/go/codec/cbor.go | 19 +- .../github.com/ugorji/go/codec/cbor_test.go | 2 +- .../github.com/ugorji/go/codec/codec_test.go | 60 +- .../ugorji/go/codec/codecgen/gen.go | 30 +- .../ugorji/go/codec/codecgen_test.go | 1 + .../src/github.com/ugorji/go/codec/decode.go | 703 +- .../src/github.com/ugorji/go/codec/encode.go | 589 +- .../ugorji/go/codec/fast-path.generated.go | 10576 ++-- .../ugorji/go/codec/fast-path.go.tmpl | 162 +- .../ugorji/go/codec/gen-dec-array.go.tmpl | 61 +- .../ugorji/go/codec/gen-dec-map.go.tmpl | 13 +- .../ugorji/go/codec/gen-helper.generated.go | 120 +- .../ugorji/go/codec/gen-helper.go.tmpl | 107 +- .../ugorji/go/codec/gen.generated.go | 76 +- .../src/github.com/ugorji/go/codec/gen.go | 689 +- .../src/github.com/ugorji/go/codec/helper.go | 219 +- .../ugorji/go/codec/helper_internal.go | 95 +- .../ugorji/go/codec/helper_not_unsafe.go | 2 +- .../github.com/ugorji/go/codec/helper_test.go | 2 +- .../ugorji/go/codec/helper_unsafe.go | 8 +- .../src/github.com/ugorji/go/codec/json.go | 305 +- .../src/github.com/ugorji/go/codec/msgpack.go | 23 +- .../src/github.com/ugorji/go/codec/noop.go | 59 +- .../github.com/ugorji/go/codec/prebuild.sh | 20 +- .../src/github.com/ugorji/go/codec/py_test.go | 5 +- .../src/github.com/ugorji/go/codec/rpc.go | 21 +- .../src/github.com/ugorji/go/codec/simple.go | 13 +- .../src/github.com/ugorji/go/codec/test.py | 5 +- .../src/github.com/ugorji/go/codec/tests.sh | 56 + .../src/github.com/ugorji/go/codec/time.go | 2 +- .../github.com/ugorji/go/codec/values_test.go | 7 +- .../golang.org/x/crypto/ssh/testdata/doc.go | 8 + .../golang.org/x/crypto/ssh/testdata/keys.go | 43 + .../html/charset/testdata/HTTP-charset.html | 48 + .../charset/testdata/HTTP-vs-UTF-8-BOM.html | 48 + .../testdata/HTTP-vs-meta-charset.html | 49 + .../testdata/HTTP-vs-meta-content.html | 49 + .../testdata/No-encoding-declaration.html | 47 + .../x/net/html/charset/testdata/README | 9 + .../html/charset/testdata/UTF-16BE-BOM.html | Bin 0 -> 2670 bytes .../html/charset/testdata/UTF-16LE-BOM.html | Bin 0 -> 2682 bytes .../testdata/UTF-8-BOM-vs-meta-charset.html | 49 + .../testdata/UTF-8-BOM-vs-meta-content.html | 48 + .../testdata/meta-charset-attribute.html | 48 + .../testdata/meta-content-attribute.html | 48 + .../golang.org/x/net/html/testdata/go1.html | 2237 + .../x/net/html/testdata/webkit/README | 28 + .../x/net/html/testdata/webkit/adoption01.dat | 194 + .../x/net/html/testdata/webkit/adoption02.dat | 31 + .../x/net/html/testdata/webkit/comments01.dat | 135 + .../x/net/html/testdata/webkit/doctype01.dat | 370 + .../x/net/html/testdata/webkit/entities01.dat | 603 + .../x/net/html/testdata/webkit/entities02.dat | 249 + .../html/testdata/webkit/html5test-com.dat | 246 + .../x/net/html/testdata/webkit/inbody01.dat | 43 + .../x/net/html/testdata/webkit/isindex.dat | 40 + ...pending-spec-changes-plain-text-unsafe.dat | Bin 0 -> 115 bytes .../testdata/webkit/pending-spec-changes.dat | 52 + .../testdata/webkit/plain-text-unsafe.dat | Bin 0 -> 4166 bytes .../net/html/testdata/webkit/scriptdata01.dat | 308 + .../testdata/webkit/scripted/adoption01.dat | 15 + .../testdata/webkit/scripted/webkit01.dat | 28 + .../x/net/html/testdata/webkit/tables01.dat | 212 + .../x/net/html/testdata/webkit/tests1.dat | 1952 + .../x/net/html/testdata/webkit/tests10.dat | 799 + .../x/net/html/testdata/webkit/tests11.dat | 482 + .../x/net/html/testdata/webkit/tests12.dat | 62 + .../x/net/html/testdata/webkit/tests14.dat | 74 + .../x/net/html/testdata/webkit/tests15.dat | 208 + .../x/net/html/testdata/webkit/tests16.dat | 2299 + .../x/net/html/testdata/webkit/tests17.dat | 153 + .../x/net/html/testdata/webkit/tests18.dat | 269 + .../x/net/html/testdata/webkit/tests19.dat | 1237 + .../x/net/html/testdata/webkit/tests2.dat | 763 + .../x/net/html/testdata/webkit/tests20.dat | 455 + .../x/net/html/testdata/webkit/tests21.dat | 221 + .../x/net/html/testdata/webkit/tests22.dat | 157 + .../x/net/html/testdata/webkit/tests23.dat | 155 + .../x/net/html/testdata/webkit/tests24.dat | 79 + .../x/net/html/testdata/webkit/tests25.dat | 219 + .../x/net/html/testdata/webkit/tests26.dat | 313 + .../x/net/html/testdata/webkit/tests3.dat | 305 + .../x/net/html/testdata/webkit/tests4.dat | 59 + .../x/net/html/testdata/webkit/tests5.dat | 191 + .../x/net/html/testdata/webkit/tests6.dat | 663 + .../x/net/html/testdata/webkit/tests7.dat | 390 + .../x/net/html/testdata/webkit/tests8.dat | 148 + .../x/net/html/testdata/webkit/tests9.dat | 457 + .../testdata/webkit/tests_innerHTML_1.dat | 741 + .../x/net/html/testdata/webkit/tricky01.dat | 261 + .../x/net/html/testdata/webkit/webkit01.dat | 610 + .../x/net/html/testdata/webkit/webkit02.dat | 159 + .../v2beta2/cloudmonitoring-api.json | 839 + .../v2beta2/cloudmonitoring-gen.go | 1366 + .../grpc/examples/route_guide/testdata/ca.pem | 14 + .../route_guide/testdata/route_guide_db.json | 601 + .../examples/route_guide/testdata/server1.key | 15 + .../examples/route_guide/testdata/server1.pem | 16 + .../grpc/interop/client/testdata/ca.pem | 14 + .../grpc/interop/client/testdata/server1.key | 15 + .../grpc/interop/client/testdata/server1.pem | 16 + .../grpc/interop/server/testdata/ca.pem | 14 + .../grpc/interop/server/testdata/server1.key | 15 + .../grpc/interop/server/testdata/server1.pem | 16 + .../grpc/test/testdata/ca.pem | 14 + .../grpc/test/testdata/server1.key | 15 + .../grpc/test/testdata/server1.pem | 16 + .../grpc/transport/testdata/ca.pem | 14 + .../grpc/transport/testdata/server1.key | 15 + .../grpc/transport/testdata/server1.pem | 16 + .../src/k8s.io/kubernetes/README.md | 9 +- .../kubernetes/api/swagger-spec/v1.json | 808 +- .../cmd/kube-apiserver/app/server.go | 154 +- .../cmd/kube-apiserver/app/server_test.go | 93 + .../app/controllermanager.go | 107 +- .../kube-controller-manager/app/plugins.go | 4 +- .../kubernetes/cmd/kube-proxy/app/server.go | 296 +- .../cmd/kube-proxy/app/server_test.go | 83 + .../kubernetes/cmd/kubelet/app/plugins.go | 6 + .../kubernetes/cmd/kubelet/app/server.go | 177 +- .../src/k8s.io/kubernetes/docs/README.md | 65 - .../k8s.io/kubernetes/docs/admin/README.md | 73 - .../docs/admin/accessing-the-api.md | 110 - .../docs/admin/admission-controllers.md | 181 - .../kubernetes/docs/admin/authentication.md | 78 - .../kubernetes/docs/admin/authorization.md | 165 - .../docs/admin/cluster-components.md | 152 - .../kubernetes/docs/admin/cluster-large.md | 100 - .../docs/admin/cluster-management.md | 189 - .../docs/admin/cluster-troubleshooting.md | 146 - .../k8s.io/kubernetes/docs/admin/daemon.yaml | 18 + .../src/k8s.io/kubernetes/docs/admin/dns.md | 76 - .../src/k8s.io/kubernetes/docs/admin/etcd.md | 83 - .../docs/admin/high-availability.md | 286 - .../admin/high-availability/default-kubelet | 8 - .../docs/admin/high-availability/etcd.yaml | 87 - .../docs/admin/high-availability/ha.png | Bin 38814 -> 0 bytes .../docs/admin/high-availability/ha.svg | 4 - .../high-availability/kube-apiserver.yaml | 90 - .../kube-controller-manager.yaml | 82 - .../high-availability/kube-scheduler.yaml | 30 - .../docs/admin/high-availability/monit-docker | 9 - .../admin/high-availability/monit-kubelet | 11 - .../admin/high-availability/podmaster.yaml | 43 - .../kubernetes/docs/admin/introduction.md | 112 - .../kubernetes/docs/admin/kube-apiserver.md | 109 - .../docs/admin/kube-controller-manager.md | 87 - .../kubernetes/docs/admin/kube-proxy.md | 69 - .../kubernetes/docs/admin/kube-scheduler.md | 68 - .../k8s.io/kubernetes/docs/admin/kubelet.md | 127 - .../kubernetes/docs/admin/multi-cluster.md | 99 - .../kubernetes/docs/admin/namespaces.md | 184 - .../docs/admin/namespaces/README.md | 288 - .../kubernetes/docs/admin/networking.md | 233 - .../src/k8s.io/kubernetes/docs/admin/node.md | 270 - .../kubernetes/docs/admin/ovs-networking.md | 52 - .../kubernetes/docs/admin/ovs-networking.png | Bin 71412 -> 0 bytes .../kubernetes/docs/admin/resource-quota.md | 179 - .../resourcequota/limits.yaml | 5 +- .../resourcequota/namespace.yaml | 0 .../resourcequota/quota.yaml | 0 .../src/k8s.io/kubernetes/docs/admin/salt.md | 137 - .../docs/admin/service-accounts-admin.md | 124 - .../docs/api-reference/definitions.html | 5910 --- .../docs/api-reference/definitions.md | 39 - .../docs/api-reference/operations.html | 23842 --------- .../docs/api-reference/operations.md | 39 - .../src/k8s.io/kubernetes/docs/api.md | 110 - .../k8s.io/kubernetes/docs/design/README.md | 55 - .../k8s.io/kubernetes/docs/design/access.md | 294 - .../docs/design/admission_control.md | 117 - .../design/admission_control_limit_range.md | 174 - .../admission_control_resource_quota.md | 194 - .../kubernetes/docs/design/architecture.dia | Bin 6522 -> 0 bytes .../kubernetes/docs/design/architecture.md | 83 - .../kubernetes/docs/design/architecture.png | Bin 222407 -> 0 bytes .../kubernetes/docs/design/architecture.svg | 499 - .../kubernetes/docs/design/clustering.md | 99 - .../docs/design/clustering/.gitignore | 1 - .../docs/design/clustering/Dockerfile | 12 - .../docs/design/clustering/Makefile | 29 - .../docs/design/clustering/README.md | 64 - .../docs/design/clustering/dynamic.png | Bin 72373 -> 0 bytes .../docs/design/clustering/dynamic.seqdiag | 24 - .../docs/design/clustering/static.png | Bin 36583 -> 0 bytes .../docs/design/clustering/static.seqdiag | 16 - .../command_execution_port_forwarding.md | 184 - .../docs/design/event_compression.md | 121 - .../kubernetes/docs/design/expansion.md | 424 - .../kubernetes/docs/design/identifiers.md | 130 - .../kubernetes/docs/design/namespaces.md | 373 - .../kubernetes/docs/design/networking.md | 214 - .../docs/design/persistent-storage.md | 242 - .../kubernetes/docs/design/principles.md | 93 - .../kubernetes/docs/design/resources.md | 268 - .../k8s.io/kubernetes/docs/design/secrets.md | 613 - .../k8s.io/kubernetes/docs/design/security.md | 155 - .../docs/design/security_context.md | 200 - .../docs/design/service_accounts.md | 205 - .../docs/design/simple-rolling-update.md | 137 - .../kubernetes/docs/design/versioning.md | 82 - .../k8s.io/kubernetes/docs/devel/README.md | 110 - .../kubernetes/docs/devel/api-conventions.md | 654 - .../kubernetes/docs/devel/api_changes.md | 382 - .../kubernetes/docs/devel/cherry-picks.md | 70 - .../kubernetes/docs/devel/cli-roadmap.md | 44 - .../kubernetes/docs/devel/client-libraries.md | 56 - .../docs/devel/coding-conventions.md | 43 - .../k8s.io/kubernetes/docs/devel/collab.md | 78 - .../docs/devel/developer-guides/vagrant.md | 382 - .../kubernetes/docs/devel/development.md | 353 - .../kubernetes/docs/devel/faster_reviews.md | 214 - .../kubernetes/docs/devel/flaky-tests.md | 103 - .../kubernetes/docs/devel/getting-builds.md | 60 - .../kubernetes/docs/devel/git_workflow.png | Bin 90004 -> 0 bytes .../kubernetes/docs/devel/instrumentation.md | 70 - .../k8s.io/kubernetes/docs/devel/issues.md | 56 - .../k8s.io/kubernetes/docs/devel/logging.md | 63 - .../docs/devel/making-release-notes.md | 77 - .../k8s.io/kubernetes/docs/devel/profiling.md | 79 - .../kubernetes/docs/devel/pull-requests.md | 66 - .../kubernetes/docs/devel/releasing.dot | 113 - .../k8s.io/kubernetes/docs/devel/releasing.md | 343 - .../kubernetes/docs/devel/releasing.png | Bin 30693 -> 0 bytes .../kubernetes/docs/devel/releasing.svg | 113 - .../k8s.io/kubernetes/docs/devel/scheduler.md | 84 - .../docs/devel/scheduler_algorithm.md | 72 - .../devel/writing-a-getting-started-guide.md | 134 - .../docs/getting-started-guides/README.md | 198 - .../docs/getting-started-guides/all-lines.png | Bin 226552 -> 0 bytes .../docs/getting-started-guides/aws-coreos.md | 250 - .../docs/getting-started-guides/aws.md | 144 - .../aws/cloud-configs/master.yaml | 177 - .../aws/cloud-configs/node.yaml | 81 - .../aws/cloudformation-template.json | 421 - .../getting-started-guides/aws/kubectl.md | 62 - .../docs/getting-started-guides/azure.md | 115 - .../bigquery-logging.png | Bin 57417 -> 0 bytes .../getting-started-guides/binary_release.md | 61 - .../centos/centos_manual_config.md | 207 - .../cloud-logging-console.png | Bin 87825 -> 0 bytes .../docs/getting-started-guides/cloudstack.md | 121 - .../docs/getting-started-guides/coreos.md | 49 - .../coreos/azure/.gitignore | 1 - .../coreos/azure/README.md | 269 - .../coreos/azure/addons/skydns-rc.yaml | 92 - .../coreos/azure/addons/skydns-svc.yaml | 20 - .../coreos/azure/azure-login.js | 3 - .../kubernetes-cluster-etcd-node-template.yml | 19 - ...kubernetes-cluster-main-nodes-template.yml | 339 - .../coreos/azure/create-kubernetes-cluster.js | 15 - .../coreos/azure/destroy-cluster.js | 7 - .../coreos/azure/expose_guestbook_app_port.sh | 29 - .../coreos/azure/external_access.png | Bin 292367 -> 0 bytes .../coreos/azure/initial_cluster.png | Bin 173212 -> 0 bytes .../coreos/azure/lib/azure_wrapper.js | 271 - .../coreos/azure/lib/cloud_config.js | 58 - .../azure/lib/deployment_logic/kubernetes.js | 77 - .../coreos/azure/lib/util.js | 33 - .../coreos/azure/package.json | 19 - .../coreos/azure/scale-kubernetes-cluster.js | 10 - .../coreos/bare_metal_offline.md | 707 - .../coreos/cloud-configs/master.yaml | 140 - .../coreos/cloud-configs/node.yaml | 98 - .../coreos/coreos_multinode_cluster.md | 174 - .../docker-multinode.md | 118 - .../docker-multinode/master.md | 204 - .../docker-multinode/master.sh | 151 - .../docker-multinode/testing.md | 101 - .../docker-multinode/worker.md | 167 - .../docker-multinode/worker.sh | 150 - .../docs/getting-started-guides/docker.md | 155 - .../getting-started-guides/es-browser.png | Bin 40769 -> 0 bytes .../fedora/fedora_ansible_config.md | 267 - .../fedora/fedora_manual_config.md | 242 - .../fedora/flannel_multi_node_cluster.md | 219 - .../docs/getting-started-guides/gce.md | 253 - .../docs/getting-started-guides/juju.md | 273 - .../getting-started-guides/k8s-docker.png | Bin 52545 -> 0 bytes .../k8s-singlenode-docker.png | Bin 31801 -> 0 bytes .../getting-started-guides/kibana-logs.png | Bin 183775 -> 0 bytes .../getting-started-guides/libvirt-coreos.md | 309 - .../docs/getting-started-guides/locally.md | 169 - .../logging-elasticsearch.md | 268 - .../docs/getting-started-guides/logging.md | 253 - .../docs/getting-started-guides/mesos.md | 376 - .../mesos/k8s-firewall.png | Bin 88722 -> 0 bytes .../mesos/k8s-guestbook.png | Bin 44000 -> 0 bytes .../docs/getting-started-guides/ovirt.md | 91 - .../docs/getting-started-guides/rackspace.md | 107 - .../docs/getting-started-guides/rkt/README.md | 139 - .../docs/getting-started-guides/scratch.md | 872 - .../getting-started-guides/ubuntu-calico.md | 290 - .../docs/getting-started-guides/ubuntu.md | 224 - .../docs/getting-started-guides/vagrant.md | 391 - .../docs/getting-started-guides/vsphere.md | 125 - .../kubernetes/docs/man/man1/.files_generated | 30 - .../docs/man/man1/kubectl-api-versions.1 | 130 - .../kubernetes/docs/man/man1/kubectl-attach.1 | 161 - .../docs/man/man1/kubectl-cluster-info.1 | 130 - .../man/man1/kubectl-config-set-cluster.1 | 153 - .../man/man1/kubectl-config-set-context.1 | 143 - .../man/man1/kubectl-config-set-credentials.1 | 169 - .../docs/man/man1/kubectl-config-set.1 | 132 - .../docs/man/man1/kubectl-config-unset.1 | 131 - .../man/man1/kubectl-config-use-context.1 | 130 - .../docs/man/man1/kubectl-config-view.1 | 181 - .../kubernetes/docs/man/man1/kubectl-config.1 | 136 - .../kubernetes/docs/man/man1/kubectl-create.1 | 156 - .../kubernetes/docs/man/man1/kubectl-delete.1 | 197 - .../docs/man/man1/kubectl-describe.1 | 173 - .../kubernetes/docs/man/man1/kubectl-exec.1 | 165 - .../kubernetes/docs/man/man1/kubectl-expose.1 | 222 - .../kubernetes/docs/man/man1/kubectl-get.1 | 207 - .../kubernetes/docs/man/man1/kubectl-label.1 | 193 - .../kubernetes/docs/man/man1/kubectl-logs.1 | 164 - .../docs/man/man1/kubectl-namespace.1 | 133 - .../kubernetes/docs/man/man1/kubectl-patch.1 | 154 - .../docs/man/man1/kubectl-port-forward.1 | 156 - .../kubernetes/docs/man/man1/kubectl-proxy.1 | 207 - .../docs/man/man1/kubectl-replace.1 | 175 - .../docs/man/man1/kubectl-rolling-update.1 | 207 - .../kubernetes/docs/man/man1/kubectl-run.1 | 201 - .../kubernetes/docs/man/man1/kubectl-scale.1 | 174 - .../kubernetes/docs/man/man1/kubectl-stop.1 | 187 - .../docs/man/man1/kubectl-version.1 | 134 - .../k8s.io/kubernetes/docs/man/man1/kubectl.1 | 132 - .../docs/reporting-security-issues.md | 57 - .../src/k8s.io/kubernetes/docs/roadmap.md | 43 - .../k8s.io/kubernetes/docs/troubleshooting.md | 76 - .../kubernetes/docs/user-guide/README.md | 135 - .../docs/user-guide/accessing-the-cluster.md | 323 - .../kubernetes/docs/user-guide/annotations.md | 64 - .../user-guide/application-troubleshooting.md | 211 - .../kubernetes/docs/user-guide/cadvisor.png | Bin 60222 -> 0 bytes .../docs/user-guide/compute-resources.md | 257 - .../docs/user-guide/config-best-practices.md | 59 - .../docs/user-guide/configuring-containers.md | 213 - .../user-guide/connecting-applications.md | 434 - ...connecting-to-applications-port-forward.md | 85 - .../connecting-to-applications-proxy.md | 65 - .../docs/user-guide/container-environment.md | 153 - .../kubernetes/docs/user-guide/containers.md | 127 - .../docs/user-guide/debugging-services.md | 560 - .../docs/user-guide/deploying-applications.md | 160 - .../docs/user-guide/docker-cli-to-kubectl.md | 337 - .../docs/user-guide/downward-api.md | 117 - .../docs/user-guide/downward-api/README.md | 72 - .../user-guide/downward-api/volume/README.md | 105 - .../user-guide/environment-guide/README.md | 126 - .../environment-guide/backend-rc.yaml | 30 - .../environment-guide/containers/README.md | 57 - .../containers/backend/Dockerfile | 2 - .../containers/show/Dockerfile | 2 - .../environment-guide/containers/show/show.go | 95 - .../user-guide/environment-guide/diagram.png | Bin 18765 -> 0 bytes .../user-guide/environment-guide/show-rc.yaml | 32 - .../k8s.io/kubernetes/docs/user-guide/gcm.png | Bin 209311 -> 0 bytes .../user-guide/getting-into-containers.md | 107 - .../kubernetes/docs/user-guide/identifiers.md | 51 - .../kubernetes/docs/user-guide/images.md | 283 - .../kubernetes/docs/user-guide/influx.png | Bin 534294 -> 0 bytes .../user-guide/introspection-and-debugging.md | 359 - .../kubernetes/docs/user-guide/job.yaml | 19 + .../docs/user-guide/k8s-ui-explore-filter.png | Bin 71468 -> 0 bytes .../user-guide/k8s-ui-explore-groupby.png | Bin 72408 -> 0 bytes .../user-guide/k8s-ui-explore-poddetail.png | Bin 52998 -> 0 bytes .../docs/user-guide/k8s-ui-explore.png | Bin 68948 -> 0 bytes .../docs/user-guide/k8s-ui-nodes.png | Bin 35568 -> 0 bytes .../docs/user-guide/k8s-ui-overview.png | Bin 78341 -> 0 bytes .../kubernetes/docs/user-guide/kibana.png | Bin 82617 -> 0 bytes .../docs/user-guide/known-issues.md | 59 - .../docs/user-guide/kubeconfig-file.md | 197 - .../docs/user-guide/kubectl/.files_generated | 30 - .../docs/user-guide/kubectl/kubectl.md | 108 - .../kubectl/kubectl_api-versions.md | 91 - .../docs/user-guide/kubectl/kubectl_attach.md | 108 - .../kubectl/kubectl_cluster-info.md | 91 - .../docs/user-guide/kubectl/kubectl_config.md | 104 - .../kubectl/kubectl_config_set-cluster.md | 106 - .../kubectl/kubectl_config_set-context.md | 99 - .../kubectl/kubectl_config_set-credentials.md | 119 - .../user-guide/kubectl/kubectl_config_set.md | 93 - .../kubectl/kubectl_config_unset.md | 92 - .../kubectl/kubectl_config_use-context.md | 91 - .../user-guide/kubectl/kubectl_config_view.md | 111 - .../docs/user-guide/kubectl/kubectl_create.md | 105 - .../docs/user-guide/kubectl/kubectl_delete.md | 126 - .../user-guide/kubectl/kubectl_describe.md | 122 - .../docs/user-guide/kubectl/kubectl_exec.md | 109 - .../docs/user-guide/kubectl/kubectl_expose.md | 125 - .../docs/user-guide/kubectl/kubectl_get.md | 133 - .../docs/user-guide/kubectl/kubectl_label.md | 123 - .../docs/user-guide/kubectl/kubectl_logs.md | 108 - .../user-guide/kubectl/kubectl_namespace.md | 94 - .../docs/user-guide/kubectl/kubectl_patch.md | 103 - .../kubectl/kubectl_port-forward.md | 109 - .../docs/user-guide/kubectl/kubectl_proxy.md | 130 - .../user-guide/kubectl/kubectl_replace.md | 112 - .../kubectl/kubectl_rolling-update.md | 125 - .../docs/user-guide/kubectl/kubectl_run.md | 120 - .../docs/user-guide/kubectl/kubectl_scale.md | 114 - .../docs/user-guide/kubectl/kubectl_stop.md | 120 - .../user-guide/kubectl/kubectl_version.md | 92 - .../kubernetes/docs/user-guide/labels.md | 148 - .../docs/user-guide/limitrange/README.md | 206 - .../user-guide/limitrange/invalid-pod.yaml | 12 - .../docs/user-guide/limitrange/limits.yaml | 23 - .../docs/user-guide/limitrange/namespace.yaml | 4 - .../docs/user-guide/limitrange/valid-pod.yaml | 14 - .../docs/user-guide/liveness/README.md | 120 - .../docs/user-guide/liveness/image/Dockerfile | 4 - .../docs/user-guide/liveness/image/Makefile | 13 - .../docs/user-guide/liveness/image/server.go | 46 - .../docs/user-guide/logging-demo/Makefile | 26 - .../docs/user-guide/logging-demo/README.md | 52 - .../user-guide/logging-demo/synth-logger.png | Bin 89284 -> 0 bytes .../kubernetes/docs/user-guide/logging.md | 128 - .../docs/user-guide/managing-deployments.md | 460 - .../user-guide/monitoring-architecture.png | Bin 22972 -> 0 bytes .../kubernetes/docs/user-guide/monitoring.md | 97 - .../kubernetes/docs/user-guide/namespaces.md | 125 - .../docs/user-guide/node-selection/README.md | 98 - .../kubernetes/docs/user-guide/overview.md | 59 - .../docs/user-guide/persistent-volumes.md | 230 - .../user-guide/persistent-volumes/README.md | 133 - .../kubernetes/docs/user-guide/pod-states.md | 143 - .../k8s.io/kubernetes/docs/user-guide/pods.md | 122 - .../kubernetes/docs/user-guide/prereqs.md | 93 - .../docs/user-guide/production-pods.md | 387 - .../kubernetes/docs/user-guide/quick-start.md | 110 - .../docs/user-guide/replication-controller.md | 130 - .../docs/user-guide/resourcequota/README.md | 189 - .../kubernetes/docs/user-guide/secrets.md | 535 - .../docs/user-guide/secrets/README.md | 96 - .../docs/user-guide/security-context.md | 41 - .../docs/user-guide/service-accounts.md | 134 - .../docs/user-guide/services-detail.png | Bin 68514 -> 0 bytes .../docs/user-guide/services-detail.svg | 570 - .../docs/user-guide/services-firewalls.md | 88 - .../docs/user-guide/services-overview.png | Bin 43306 -> 0 bytes .../docs/user-guide/services-overview.svg | 417 - .../kubernetes/docs/user-guide/services.md | 539 - .../docs/user-guide/sharing-clusters.md | 155 - .../docs/user-guide/simple-nginx.md | 93 - .../kubernetes/docs/user-guide/simple-yaml.md | 4 +- .../k8s.io/kubernetes/docs/user-guide/ui.md | 87 - .../docs/user-guide/update-demo/README.md | 161 - .../user-guide/update-demo/build-images.sh | 30 - .../update-demo/images/kitten/Dockerfile | 17 - .../update-demo/images/kitten/html/data.json | 3 - .../update-demo/images/kitten/html/kitten.jpg | Bin 14769 -> 0 bytes .../update-demo/images/nautilus/Dockerfile | 17 - .../images/nautilus/html/data.json | 3 - .../images/nautilus/html/nautilus.jpg | Bin 21231 -> 0 bytes .../update-demo/local/LICENSE.angular | 21 - .../update-demo/local/angular.min.js | 210 - .../update-demo/local/angular.min.js.map | 8 - .../user-guide/update-demo/local/index.html | 36 - .../user-guide/update-demo/local/script.js | 100 - .../user-guide/update-demo/local/style.css | 40 - .../kubernetes/docs/user-guide/volumes.md | 400 - .../docs/user-guide/walkthrough/README.md | 14 +- .../docs/user-guide/walkthrough/k8s201.md | 327 - .../docs/user-guide/working-with-resources.md | 99 - .../src/k8s.io/kubernetes/docs/warning.png | Bin 2363 -> 0 bytes .../src/k8s.io/kubernetes/docs/whatisk8s.md | 83 - .../celery-rabbitmq/celery-controller.yaml | 4 +- .../celery-rabbitmq/flower-controller.yaml | 4 +- .../celery-rabbitmq/flower-service.yaml | 2 +- .../celery-rabbitmq/rabbitmq-controller.yaml | 4 +- .../celery-rabbitmq/rabbitmq-service.yaml | 2 +- .../kubernetes/examples/cephfs/README.md | 68 - .../examples/cephfs/cephfs-with-secret.json | 39 - .../examples/cephfs/cephfs-with-secret.yaml | 22 + .../kubernetes/examples/cephfs/cephfs.json | 37 - .../kubernetes/examples/cephfs/cephfs.yaml | 21 + .../examples/cephfs/secret/ceph-secret.yaml | 6 - .../examples/elasticsearch/README.md | 196 - .../production_cluster/README.md | 222 - .../production_cluster/es-client-rc.yaml | 55 - .../production_cluster/es-data-rc.yaml | 50 - .../production_cluster/es-discovery-svc.yaml | 15 - .../production_cluster/es-master-rc.yaml | 52 - .../production_cluster/es-svc.yaml | 16 - .../production_cluster/service-account.yaml | 4 - .../kubernetes/examples/examples_test.go | 50 +- .../examples/experimental/deployment.yaml | 20 + .../kubernetes/examples/explorer/pod.json | 36 - .../kubernetes/examples/explorer/pod.yaml | 18 + .../kubernetes/examples/fibre_channel/fc.yaml | 18 + .../glusterfs/glusterfs-endpoints.json | 4 +- .../kubernetes/examples/guestbook/README.md | 609 - .../examples/guestbook/php-redis/Dockerfile | 7 - .../guestbook/php-redis/controllers.js | 29 - .../examples/guestbook/php-redis/index.html | 25 - .../examples/guestbook/php-redis/index.php | 33 - .../examples/guestbook/redis-slave/Dockerfile | 7 - .../examples/guestbook/redis-slave/run.sh | 17 - .../kubernetes/examples/iscsi/README.md | 30 +- .../kubernetes/examples/iscsi/iscsi.json | 10 +- .../javaweb-tomcat-sidecar/javaweb-2.yaml | 31 + .../javaweb-tomcat-sidecar/javaweb.yaml | 24 + .../kubernetes/examples/metadata/README.md | 102 - .../examples/metadata/metadata-volume.yaml | 31 - .../phabricator/authenticator-controller.json | 31 - .../phabricator/phabricator-controller.json | 14 + .../k8s.io/kubernetes/pkg/admission/errors.go | 37 +- .../src/k8s.io/kubernetes/pkg/api/context.go | 18 + .../k8s.io/kubernetes/pkg/api/conversion.go | 4 +- .../k8s.io/kubernetes/pkg/api/copy_test.go | 44 +- .../kubernetes/pkg/api/deep_copy_generated.go | 519 +- .../kubernetes/pkg/api/endpoints/util.go | 129 +- .../kubernetes/pkg/api/endpoints/util_test.go | 153 +- .../kubernetes/pkg/api/errors/errors.go | 170 +- .../kubernetes/pkg/api/errors/errors_test.go | 74 +- .../src/k8s.io/kubernetes/pkg/api/helpers.go | 17 +- .../kubernetes/pkg/api/install/install.go | 119 + .../pkg/api/install/install_test.go | 112 + .../kubernetes/pkg/api/latest/latest.go | 213 +- .../kubernetes/pkg/api/latest/latest_test.go | 127 +- .../src/k8s.io/kubernetes/pkg/api/mapper.go | 2 +- .../src/k8s.io/kubernetes/pkg/api/meta.go | 7 +- .../kubernetes/pkg/api/meta/interfaces.go | 3 +- .../kubernetes/pkg/api/meta/meta_test.go | 8 +- .../kubernetes/pkg/api/meta/restmapper.go | 25 + .../pkg/api/meta/restmapper_test.go | 5 + .../src/k8s.io/kubernetes/pkg/api/ref_test.go | 9 +- .../src/k8s.io/kubernetes/pkg/api/register.go | 101 +- .../pkg/api/registered/registered.go | 20 +- .../kubernetes/pkg/api/resource/quantity.go | 3 - .../kubernetes/pkg/api/resource_helpers.go | 20 +- .../k8s.io/kubernetes/pkg/api/rest/delete.go | 6 +- .../k8s.io/kubernetes/pkg/api/rest/rest.go | 26 +- .../pkg/api/rest/resttest/resttest.go | 15 +- .../k8s.io/kubernetes/pkg/api/rest/update.go | 25 +- .../kubernetes/pkg/api/serialization_test.go | 40 +- .../kubernetes/pkg/api/testapi/testapi.go | 67 +- .../testing/compat/compatibility_tester.go | 144 + .../kubernetes/pkg/api/testing/fuzzer.go | 47 +- .../kubernetes/pkg/api/testing/pod_specs.go | 32 + .../src/k8s.io/kubernetes/pkg/api/types.go | 747 +- .../k8s.io/kubernetes/pkg/api/unversioned.go | 58 - .../pkg/api/unversioned/duration.go | 47 + .../pkg/api/unversioned/duration_test.go | 153 + .../pkg/{util => api/unversioned}/time.go | 2 +- .../{util => api/unversioned}/time_test.go | 2 +- .../kubernetes/pkg/api/unversioned/types.go | 356 + .../types_swagger_doc_generated.go | 163 + .../kubernetes/pkg/api/util/group_version.go | 9 + .../pkg/api/util/group_version_test.go | 8 +- .../pkg/api/v1/backward_compatibility_test.go | 166 + .../kubernetes/pkg/api/v1/conversion.go | 127 +- .../pkg/api/v1/conversion_generated.go | 3291 +- .../kubernetes/pkg/api/v1/conversion_test.go | 23 - .../api/v1/conversion_volumesource_test.go | 75 - .../pkg/api/v1/deep_copy_generated.go | 558 +- .../k8s.io/kubernetes/pkg/api/v1/defaults.go | 74 +- .../kubernetes/pkg/api/v1/defaults_test.go | 71 + .../k8s.io/kubernetes/pkg/api/v1/register.go | 101 +- .../src/k8s.io/kubernetes/pkg/api/v1/types.go | 684 +- .../pkg/api/v1/types_swagger_doc_generated.go | 234 +- .../kubernetes/pkg/api/v1beta3/conversion.go | 888 - .../pkg/api/v1beta3/conversion_generated.go | 4708 -- .../pkg/api/v1beta3/conversion_test.go | 139 - .../v1beta3/conversion_volumesource_test.go | 62 - .../pkg/api/v1beta3/deep_copy_generated.go | 2529 - .../kubernetes/pkg/api/v1beta3/defaults.go | 218 - .../pkg/api/v1beta3/defaults_test.go | 471 - .../kubernetes/pkg/api/v1beta3/register.go | 134 - .../kubernetes/pkg/api/v1beta3/types.go | 2219 - .../kubernetes/pkg/api/validation/events.go | 6 +- .../kubernetes/pkg/api/validation/schema.go | 98 +- .../pkg/api/validation/schema_test.go | 28 + .../pkg/api/validation/validation.go | 331 +- .../pkg/api/validation/validation_test.go | 399 +- .../pkg/apis/experimental/latest/latest.go | 73 - .../pkg/apis/experimental/testapi/testapi.go | 52 - .../experimental/v1/conversion_generated.go | 2494 - .../experimental/validation/validation.go | 319 - .../deep_copy_generated.go | 564 +- .../pkg/apis/extensions/install/install.go | 92 + .../apis/extensions/install/install_test.go | 113 + .../{experimental => extensions}/register.go | 10 +- .../{experimental => extensions}/types.go | 323 +- .../v1 => extensions/v1beta1}/conversion.go | 185 +- .../v1beta1/conversion_generated.go | 4159 ++ .../v1beta1}/deep_copy_generated.go | 577 +- .../v1 => extensions/v1beta1}/defaults.go | 42 +- .../v1beta1}/defaults_test.go | 84 +- .../v1 => extensions/v1beta1}/register.go | 14 +- .../v1 => extensions/v1beta1}/types.go | 311 +- .../v1beta1}/types_swagger_doc_generated.go | 172 +- .../apis/extensions/validation/validation.go | 562 + .../validation/validation_test.go | 515 +- .../kubernetes/pkg/apiserver/api_installer.go | 88 +- .../pkg/apiserver/api_installer_test.go | 3 +- .../kubernetes/pkg/apiserver/apiserver.go | 161 +- .../pkg/apiserver/apiserver_test.go | 451 +- .../k8s.io/kubernetes/pkg/apiserver/authz.go | 1 + .../k8s.io/kubernetes/pkg/apiserver/errors.go | 43 +- .../kubernetes/pkg/apiserver/errors_test.go | 18 +- .../kubernetes/pkg/apiserver/handlers.go | 100 +- .../kubernetes/pkg/apiserver/handlers_test.go | 84 +- .../k8s.io/kubernetes/pkg/apiserver/index.go | 4 +- .../kubernetes/pkg/apiserver/resthandler.go | 171 +- .../pkg/apiserver/resthandler_test.go | 285 +- .../kubernetes/pkg/apiserver/testing/types.go | 64 + .../kubernetes/pkg/apiserver/validator.go | 14 +- .../kubernetes/pkg/apiserver/watch_test.go | 15 +- .../pkg/auth/authorizer/abac/abac.go | 2 +- .../pkg/auth/authorizer/interfaces.go | 8 + .../k8s.io/kubernetes/pkg/client/cache/doc.go | 2 +- .../pkg/client/cache/expiration_cache.go | 5 +- .../pkg/client/cache/expiration_cache_test.go | 4 +- .../kubernetes/pkg/client/cache/listers.go | 79 +- .../pkg/client/cache/listers_test.go | 34 +- .../pkg/client/cache/listwatch_test.go | 21 +- .../pkg/client/cache/reflector_test.go | 19 +- .../kubernetes/pkg/client/metrics/metrics.go | 8 +- .../kubernetes/pkg/client/record/event.go | 47 +- .../pkg/client/record/event_test.go | 482 +- .../pkg/client/record/events_cache.go | 30 +- .../pkg/client/record/events_cache_test.go | 28 +- .../kubernetes/pkg/client/record/fake.go | 4 +- .../pkg/client/unversioned/client.go | 69 +- .../pkg/client/unversioned/client_test.go | 77 +- .../clientcmd/client_config_test.go | 8 +- .../pkg/client/unversioned/clientcmd/doc.go | 12 +- .../client/unversioned/clientcmd/loader.go | 7 +- .../clientcmd/merged_client_builder.go | 2 +- .../unversioned/clientcmd/validation.go | 4 +- .../pkg/client/unversioned/conditions.go | 25 +- .../pkg/client/unversioned/daemon_sets.go | 40 +- .../client/unversioned/daemon_sets_test.go | 75 +- .../pkg/client/unversioned/deployment.go | 30 +- .../pkg/client/unversioned/deployment_test.go | 24 +- .../kubernetes/pkg/client/unversioned/doc.go | 8 +- .../pkg/client/unversioned/events.go | 17 + .../pkg/client/unversioned/events_test.go | 12 +- .../{experimental.go => extensions.go} | 83 +- .../kubernetes/pkg/client/unversioned/fake.go | 69 - .../pkg/client/unversioned/fake/fake.go | 72 + .../pkg/client/unversioned/helper.go | 104 +- .../unversioned/helper_blackbox_test.go | 112 + .../pkg/client/unversioned/helper_test.go | 134 +- .../unversioned/horizontalpodautoscaler.go | 38 +- .../horizontalpodautoscaler_test.go | 53 +- .../unversioned/import_known_versions.go | 23 + .../pkg/client/unversioned/ingress.go | 112 + .../pkg/client/unversioned/ingress_test.go | 230 + .../kubernetes/pkg/client/unversioned/jobs.go | 116 + .../pkg/client/unversioned/jobs_test.go | 222 + .../pkg/client/unversioned/limit_ranges.go | 6 +- .../client/unversioned/limit_ranges_test.go | 2 +- .../pkg/client/unversioned/nodes_test.go | 39 +- .../pkg/client/unversioned/pods_test.go | 3 +- .../unversioned/portforward/portforward.go | 124 +- .../portforward/portforward_test.go | 323 +- .../remotecommand/remotecommand.go | 180 +- .../remotecommand/remotecommand_test.go | 83 +- .../unversioned/replication_controllers.go | 14 +- .../replication_controllers_test.go | 33 +- .../pkg/client/unversioned/request.go | 111 +- .../pkg/client/unversioned/request_test.go | 125 +- .../pkg/client/unversioned/resource_quotas.go | 6 +- .../unversioned/resource_quotas_test.go | 2 +- .../pkg/client/unversioned/restclient_test.go | 33 +- .../pkg/client/unversioned/scale.go | 18 +- .../unversioned/securitycontextconstraints.go | 115 - .../securitycontextconstraints_test.go | 137 - .../pkg/client/unversioned/services.go | 7 +- .../pkg/client/unversioned/services_test.go | 8 +- .../client/unversioned/testclient/actions.go | 39 + .../testclient/fake_daemon_sets.go | 36 +- .../testclient/fake_deployments.go | 26 +- .../unversioned/testclient/fake_events.go | 14 + .../fake_horizontal_pod_autoscalers.go | 34 +- .../unversioned/testclient/fake_ingress.go | 86 + .../unversioned/testclient/fake_jobs.go | 86 + .../testclient/fake_limit_ranges.go | 4 +- .../unversioned/testclient/fake_nodes.go | 16 +- .../fake_persistent_volume_claims.go | 8 +- .../unversioned/testclient/fake_pods.go | 8 +- .../fake_replication_controllers.go | 12 +- .../testclient/fake_resource_quotas.go | 12 +- .../unversioned/testclient/fake_scales.go | 12 +- .../fake_securitycontextconstraints.go | 61 - .../unversioned/testclient/fake_services.go | 7 +- .../client/unversioned/testclient/fixture.go | 31 +- .../unversioned/testclient/testclient.go | 90 +- .../unversioned/testclient/testclient_test.go | 15 +- .../pkg/client/unversioned/transport.go | 60 +- .../pkg/client/unversioned/transport_test.go | 11 +- .../kubernetes/pkg/cloudprovider/cloud.go | 12 +- .../pkg/cloudprovider/providers/aws/aws.go | 463 +- .../providers/aws/aws_instancegroups.go | 5 +- .../providers/aws/aws_loadbalancer.go | 56 +- .../cloudprovider/providers/aws/aws_routes.go | 22 +- .../cloudprovider/providers/aws/aws_test.go | 204 +- .../pkg/cloudprovider/providers/gce/gce.go | 886 +- .../cloudprovider/providers/gce/gce_test.go | 32 +- .../pkg/controller/controller_utils.go | 137 +- .../pkg/controller/controller_utils_test.go | 7 +- .../pkg/controller/daemon/controller.go | 105 +- .../pkg/controller/daemon/controller_test.go | 100 +- .../deployment/deployment_controller.go | 279 + .../deployment/deployment_controller_test.go | 260 + .../kubernetes/pkg/controller/endpoint/doc.go | 2 +- .../endpoint/endpoints_controller.go | 33 +- .../endpoint/endpoints_controller_test.go | 124 +- .../controller/framework/controller_test.go | 6 +- .../framework/fake_controller_source.go | 14 +- .../kubernetes/pkg/controller/gc/doc.go | 24 + .../pkg/controller/gc/gc_controller.go | 135 + .../pkg/controller/gc/gc_controller_test.go | 108 + .../pkg/controller/job/controller.go | 469 + .../pkg/controller/job/controller_test.go | 486 + .../user => controller/job}/doc.go | 6 +- .../pkg/controller/namespace/doc.go | 2 +- .../namespace/namespace_controller.go | 137 +- .../namespace/namespace_controller_test.go | 43 +- .../kubernetes/pkg/controller/node/doc.go | 4 +- .../pkg/controller/node/nodecontroller.go | 55 +- .../controller/node/nodecontroller_test.go | 129 +- .../pkg/controller/node/rate_limited_queue.go | 9 +- .../node/rate_limited_queue_test.go | 6 +- ...ersistentvolume_claim_binder_controller.go | 6 +- ...tentvolume_claim_binder_controller_test.go | 2 +- .../persistentvolume_index_test.go | 77 +- .../persistentvolume_recycler_controller.go | 69 +- .../pkg/controller/persistentvolume/types.go | 53 +- .../controller/podautoscaler/horizontal.go | 170 +- .../podautoscaler/horizontal_test.go | 434 +- .../podautoscaler/metrics/metrics_client.go | 26 +- .../metrics/metrics_client_test.go | 418 +- .../pkg/controller/replication/doc.go | 2 +- .../replication/replication_controller.go | 58 +- .../replication_controller_test.go | 203 +- .../replication_controller_utils.go | 4 +- .../pkg/controller/resourcequota/doc.go | 2 +- .../resource_quota_controller.go | 10 +- .../resource_quota_controller_test.go | 2 +- .../kubernetes/pkg/controller/route/doc.go | 4 +- .../pkg/controller/route/routecontroller.go | 2 +- .../controller/route/routecontroller_test.go | 2 +- .../kubernetes/pkg/controller/service/doc.go | 4 +- .../controller/service/servicecontroller.go | 33 +- .../service/servicecontroller_test.go | 2 +- .../serviceaccounts_controller.go | 55 +- .../serviceaccounts_controller_test.go | 25 +- .../serviceaccount/tokens_controller.go | 32 +- .../pkg/controller/serviceaccount/util.go | 21 + .../kubernetes/pkg/conversion/converter.go | 7 +- .../pkg/conversion/converter_test.go | 28 + .../kubernetes/pkg/conversion/encode.go | 63 +- .../k8s.io/kubernetes/pkg/conversion/meta.go | 11 + .../kubernetes/pkg/conversion/meta_test.go | 22 + .../kubernetes/pkg/conversion/scheme.go | 3 +- .../pkg/conversion/unversioned_test.go | 92 + .../pkg/credentialprovider/config.go | 48 +- .../pkg/credentialprovider/config_test.go | 29 + .../pkg/credentialprovider/keyring.go | 9 +- .../k8s.io/kubernetes/pkg/kubectl/apply.go | 179 + .../pkg/kubectl/cmd/annotate_test.go | 13 +- .../kubernetes/pkg/kubectl/cmd/apiversions.go | 9 +- .../kubernetes/pkg/kubectl/cmd/apply.go | 164 + .../kubernetes/pkg/kubectl/cmd/apply_test.go | 260 + .../kubernetes/pkg/kubectl/cmd/attach.go | 36 +- .../kubernetes/pkg/kubectl/cmd/attach_test.go | 26 +- .../k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go | 23 +- .../kubernetes/pkg/kubectl/cmd/cmd_test.go | 40 +- .../pkg/kubectl/cmd/config/config.go | 2 +- .../pkg/kubectl/cmd/config/config_test.go | 2 +- .../pkg/kubectl/cmd/config/create_authinfo.go | 12 +- .../pkg/kubectl/cmd/config/create_cluster.go | 10 +- .../pkg/kubectl/cmd/config/create_context.go | 6 +- .../kubernetes/pkg/kubectl/cmd/config/set.go | 18 +- .../pkg/kubectl/cmd/config/unset.go | 6 +- .../pkg/kubectl/cmd/config/use_context.go | 6 +- .../kubernetes/pkg/kubectl/cmd/config/view.go | 4 +- .../kubernetes/pkg/kubectl/cmd/convert.go | 156 + .../kubernetes/pkg/kubectl/cmd/create.go | 9 + .../kubernetes/pkg/kubectl/cmd/create_test.go | 14 +- .../kubernetes/pkg/kubectl/cmd/delete_test.go | 55 +- .../pkg/kubectl/cmd/describe_test.go | 10 +- .../k8s.io/kubernetes/pkg/kubectl/cmd/edit.go | 397 + .../k8s.io/kubernetes/pkg/kubectl/cmd/exec.go | 52 +- .../kubernetes/pkg/kubectl/cmd/exec_test.go | 26 +- .../kubernetes/pkg/kubectl/cmd/explain.go | 85 + .../kubernetes/pkg/kubectl/cmd/expose.go | 97 +- .../kubernetes/pkg/kubectl/cmd/expose_test.go | 165 +- .../k8s.io/kubernetes/pkg/kubectl/cmd/get.go | 19 +- .../kubernetes/pkg/kubectl/cmd/get_test.go | 183 +- .../kubernetes/pkg/kubectl/cmd/label.go | 6 +- .../kubernetes/pkg/kubectl/cmd/label_test.go | 9 +- .../k8s.io/kubernetes/pkg/kubectl/cmd/log.go | 176 +- .../kubernetes/pkg/kubectl/cmd/log_test.go | 5 +- .../kubernetes/pkg/kubectl/cmd/patch_test.go | 10 +- .../kubernetes/pkg/kubectl/cmd/portforward.go | 38 +- .../pkg/kubectl/cmd/portforward_test.go | 36 +- .../kubernetes/pkg/kubectl/cmd/proxy.go | 6 +- .../kubernetes/pkg/kubectl/cmd/replace.go | 18 + .../pkg/kubectl/cmd/replace_test.go | 18 +- .../pkg/kubectl/cmd/rollingupdate.go | 74 +- .../pkg/kubectl/cmd/rollingupdate_test.go | 2 +- .../k8s.io/kubernetes/pkg/kubectl/cmd/run.go | 25 +- .../pkg/kubectl/cmd/util/editor/editor.go | 199 + .../kubectl/cmd/util/editor/editor_test.go | 63 + .../pkg/kubectl/cmd/util/editor/term.go | 27 + .../cmd/util/editor/term_unsupported.go | 26 + .../pkg/kubectl/cmd/util/factory.go | 124 +- .../pkg/kubectl/cmd/util/factory_test.go | 74 +- .../pkg/kubectl/cmd/util/helpers.go | 33 +- .../pkg/kubectl/cmd/util/helpers_test.go | 8 +- .../kubectl/cmd/util/jsonmerge/jsonmerge.go | 193 + .../kubernetes/pkg/kubectl/cmd/version.go | 1 + .../pkg/kubectl/custom_column_printer.go | 8 + .../pkg/kubectl/custom_column_printer_test.go | 3 +- .../k8s.io/kubernetes/pkg/kubectl/describe.go | 189 +- .../kubernetes/pkg/kubectl/describe_test.go | 47 +- .../k8s.io/kubernetes/pkg/kubectl/explain.go | 260 + .../k8s.io/kubernetes/pkg/kubectl/kubectl.go | 14 +- .../kubernetes/pkg/kubectl/proxy_server.go | 4 +- .../pkg/kubectl/resource/builder.go | 79 +- .../pkg/kubectl/resource/builder_test.go | 269 +- .../pkg/kubectl/resource/helper_test.go | 58 +- .../kubernetes/pkg/kubectl/resource/mapper.go | 1 + .../kubernetes/pkg/kubectl/resource/result.go | 5 +- .../pkg/kubectl/resource_printer.go | 273 +- .../pkg/kubectl/resource_printer_test.go | 85 +- .../kubernetes/pkg/kubectl/rolling_updater.go | 72 +- .../pkg/kubectl/rolling_updater_test.go | 21 +- .../src/k8s.io/kubernetes/pkg/kubectl/run.go | 4 +- .../k8s.io/kubernetes/pkg/kubectl/scale.go | 128 +- .../kubernetes/pkg/kubectl/scale_test.go | 294 +- .../k8s.io/kubernetes/pkg/kubectl/service.go | 3 +- .../pkg/kubectl/sorted_event_list_test.go | 14 +- .../kubernetes/pkg/kubectl/sorting_printer.go | 18 +- .../src/k8s.io/kubernetes/pkg/kubectl/stop.go | 84 +- .../kubernetes/pkg/kubectl/stop_test.go | 73 + .../kubernetes/pkg/kubectl/testing/types.go | 33 + .../pkg/kubelet/config/apiserver.go | 4 +- .../pkg/kubelet/config/apiserver_test.go | 34 +- .../kubernetes/pkg/kubelet/config/common.go | 6 +- .../pkg/kubelet/config/common_test.go | 11 +- .../kubernetes/pkg/kubelet/config/config.go | 143 +- .../pkg/kubelet/config/config_test.go | 166 +- .../kubernetes/pkg/kubelet/config/file.go | 12 +- .../pkg/kubelet/config/file_test.go | 28 +- .../kubernetes/pkg/kubelet/config/http.go | 8 +- .../pkg/kubelet/config/http_test.go | 57 +- .../pkg/kubelet/container/container_gc.go | 68 + .../container/container_reference_manager.go | 11 +- .../pkg/kubelet/container/fake_runtime.go | 32 +- .../pkg/kubelet/container/helpers.go | 21 +- .../pkg/kubelet/container/image_puller.go | 63 +- .../kubelet/container/image_puller_test.go | 119 + .../kubelet/container/readiness_manager.go | 59 - .../pkg/kubelet/container/ref_test.go | 3 +- .../pkg/kubelet/container/runtime.go | 46 +- .../pkg/kubelet/container_manager_linux.go | 172 +- .../kubelet/container_manager_linux_test.go | 125 + .../kubelet/container_manager_unsupported.go | 3 +- .../container_manager_unsupported_test.go | 72 + .../kubelet/{ => dockertools}/container_gc.go | 184 +- .../{ => dockertools}/container_gc_test.go | 33 +- .../pkg/kubelet/dockertools/convert.go | 4 +- .../pkg/kubelet/dockertools/convert_test.go | 3 +- .../pkg/kubelet/dockertools/docker.go | 8 +- .../pkg/kubelet/dockertools/docker_test.go | 140 +- .../kubelet/dockertools/fake_docker_client.go | 128 +- .../pkg/kubelet/dockertools/fake_manager.go | 14 +- .../pkg/kubelet/dockertools/manager.go | 530 +- .../pkg/kubelet/dockertools/manager_test.go | 484 +- .../pkg/kubelet/fake_pod_workers.go | 5 +- .../kubernetes/pkg/kubelet/image_manager.go | 33 +- .../pkg/kubelet/image_manager_test.go | 184 +- .../k8s.io/kubernetes/pkg/kubelet/kubelet.go | 335 +- .../kubernetes/pkg/kubelet/kubelet_test.go | 242 +- .../pkg/kubelet/lifecycle/handlers.go | 9 +- .../pkg/kubelet/lifecycle/handlers_test.go | 12 +- .../kubernetes/pkg/kubelet/network/cni/cni.go | 206 + .../pkg/kubelet/network/cni/cni_test.go | 197 + .../pkg/kubelet/network/exec/exec.go | 12 +- .../pkg/kubelet/network/exec/exec_test.go | 129 +- .../kubernetes/pkg/kubelet/network/plugins.go | 25 +- .../kubernetes/pkg/kubelet/network/testing.go | 5 + .../k8s.io/kubernetes/pkg/kubelet/networks.go | 5 + .../kubernetes/pkg/kubelet/oom_watcher.go | 3 +- .../pkg/kubelet/oom_watcher_test.go | 10 +- .../fake_mirror_client.go} | 64 +- .../{pod_manager.go => pod/manager.go} | 83 +- .../manager_test.go} | 22 +- .../pkg/kubelet/{ => pod}/mirror_client.go | 43 +- .../pkg/kubelet/pod/mirror_client_test.go | 54 + .../kubernetes/pkg/kubelet/pod_workers.go | 18 +- .../pkg/kubelet/pod_workers_test.go | 51 +- .../pkg/kubelet/prober/fake_manager.go | 37 + .../pkg/kubelet/prober/fake_prober.go | 45 + .../kubernetes/pkg/kubelet/prober/manager.go | 169 + .../pkg/kubelet/prober/manager_test.go | 283 + .../kubernetes/pkg/kubelet/prober/prober.go | 70 +- .../pkg/kubelet/prober/prober_test.go | 274 +- .../kubelet/prober/results/results_manager.go | 89 + .../prober/results/results_manager_test.go | 43 + .../kubernetes/pkg/kubelet/prober/worker.go | 153 + .../pkg/kubelet/prober/worker_test.go | 243 + .../pkg/kubelet/qos/memory_policy.go | 10 +- .../pkg/kubelet/qos/memory_policy_test.go | 40 +- .../kubernetes/pkg/kubelet/qos/util/qos.go | 12 +- .../pkg/kubelet/rkt/container_id.go | 15 +- .../k8s.io/kubernetes/pkg/kubelet/rkt/gc.go | 18 +- .../kubernetes/pkg/kubelet/rkt/pod_info.go | 8 +- .../k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go | 233 +- .../k8s.io/kubernetes/pkg/kubelet/runonce.go | 5 +- .../kubernetes/pkg/kubelet/runonce_test.go | 130 +- .../k8s.io/kubernetes/pkg/kubelet/server.go | 364 +- .../kubernetes/pkg/kubelet/server_test.go | 355 +- .../{status_manager.go => status/manager.go} | 143 +- .../manager_test.go} | 123 +- .../kubelet/{types.go => types/pod_update.go} | 34 +- .../pod_update_test.go} | 2 +- .../kubernetes/pkg/kubelet/types/types.go | 8 + .../src/k8s.io/kubernetes/pkg/kubelet/util.go | 13 +- .../k8s.io/kubernetes/pkg/kubelet/volumes.go | 42 +- .../k8s.io/kubernetes/pkg/labels/selector.go | 87 +- .../kubernetes/pkg/labels/selector_test.go | 38 +- .../pkg/master/import_known_versions.go | 23 + .../k8s.io/kubernetes/pkg/master/master.go | 425 +- .../kubernetes/pkg/master/master_test.go | 357 +- .../pkg/master/thirdparty_controller.go | 128 + .../pkg/master/thirdparty_controller_test.go | 204 + .../k8s.io/kubernetes/pkg/proxy/config/api.go | 2 +- .../kubernetes/pkg/proxy/iptables/proxier.go | 91 +- .../pkg/proxy/iptables/proxier_test.go | 3 +- .../src/k8s.io/kubernetes/pkg/proxy/types.go | 2 + .../kubernetes/pkg/proxy/userspace/proxier.go | 37 +- .../pkg/proxy/userspace/proxier_test.go | 6 + .../pkg/proxy/userspace/proxysocket.go | 4 +- .../pkg/proxy/userspace/roundrobin.go | 2 +- .../pkg/registry/controller/etcd/etcd.go | 21 +- .../pkg/registry/controller/etcd/etcd_test.go | 21 +- .../pkg/registry/controller/strategy.go | 24 +- .../pkg/registry/controller/strategy_test.go | 140 + .../pkg/registry/daemonset/etcd/etcd.go | 28 +- .../pkg/registry/daemonset/etcd/etcd_test.go | 43 +- .../pkg/registry/daemonset/strategy.go | 41 +- .../pkg/registry/deployment/etcd/etcd.go | 94 +- .../pkg/registry/deployment/etcd/etcd_test.go | 125 +- .../pkg/registry/deployment/registry.go | 87 + .../pkg/registry/deployment/strategy.go | 12 +- .../experimental/controller/etcd/etcd.go | 26 +- .../experimental/controller/etcd/etcd_test.go | 22 +- .../pkg/registry/generic/etcd/etcd.go | 52 +- .../pkg/registry/generic/etcd/etcd_test.go | 117 +- .../pkg/registry/generic/matcher.go | 37 +- .../pkg/registry/generic/matcher_test.go | 39 - .../pkg/registry/generic/rest/proxy.go | 32 +- .../pkg/registry/generic/rest/proxy_test.go | 48 +- .../registry/generic/rest/response_checker.go | 70 + .../generic/rest/response_checker_test.go | 94 + .../pkg/registry/generic/rest/streamer.go | 18 +- .../registry/generic/rest/streamer_test.go | 29 + .../horizontalpodautoscaler/etcd/etcd.go | 28 +- .../horizontalpodautoscaler/etcd/etcd_test.go | 47 +- .../horizontalpodautoscaler/strategy.go | 39 +- .../doc.go | 4 +- .../pkg/registry/ingress/etcd/etcd.go | 77 + .../pkg/registry/ingress/etcd/etcd_test.go | 203 + .../pkg/registry/ingress/strategy.go | 116 + .../k8s.io/kubernetes/pkg/registry/job/doc.go | 2 +- .../kubernetes/pkg/registry/job/etcd/etcd.go | 31 +- .../pkg/registry/job/etcd/etcd_test.go | 52 +- .../kubernetes/pkg/registry/job/registry.go | 26 +- .../kubernetes/pkg/registry/job/strategy.go | 40 +- .../pkg/registry/job/strategy_test.go | 156 + .../pkg/registry/namespace/etcd/etcd.go | 4 +- .../pkg/registry/namespace/etcd/etcd_test.go | 6 +- .../pkg/registry/namespace/strategy_test.go | 4 +- .../kubernetes/pkg/registry/pod/etcd/etcd.go | 49 +- .../pkg/registry/pod/etcd/etcd_test.go | 39 +- .../kubernetes/pkg/registry/pod/strategy.go | 17 + .../pkg/registry/registrytest/etcd.go | 4 +- .../securitycontextconstraints/etcd/etcd.go | 64 - .../etcd/etcd_test.go | 74 - .../securitycontextconstraints/registry.go | 87 - .../securitycontextconstraints/strategy.go | 88 - .../pkg/registry/service/allocator/bitmap.go | 4 - .../registry/service/allocator/etcd/etcd.go | 10 +- .../service/allocator/etcd/etcd_test.go | 4 +- .../registry/service/ipallocator/allocator.go | 5 +- .../service/portallocator/allocator.go | 1 + .../kubernetes/pkg/registry/service/rest.go | 6 +- .../pkg/registry/service/rest_test.go | 16 + .../registry/thirdpartyresource/etcd/etcd.go | 8 +- .../thirdpartyresource/etcd/etcd_test.go | 18 +- .../registry/thirdpartyresource/strategy.go | 12 +- .../registry/thirdpartyresourcedata/codec.go | 116 +- .../thirdpartyresourcedata/codec_test.go | 72 +- .../thirdpartyresourcedata/etcd/etcd.go | 8 +- .../thirdpartyresourcedata/etcd/etcd_test.go | 16 +- .../thirdpartyresourcedata/registry.go | 26 +- .../thirdpartyresourcedata/strategy.go | 12 +- .../registry/thirdpartyresourcedata/util.go | 4 +- .../thirdpartyresourcedata/util_test.go | 4 +- .../k8s.io/kubernetes/pkg/runtime/codec.go | 6 + .../pkg/runtime/conversion_generator.go | 62 +- .../pkg/runtime/deep_copy_generator.go | 18 +- .../k8s.io/kubernetes/pkg/runtime/helper.go | 19 +- .../kubernetes/pkg/runtime/helper_test.go | 23 + .../kubernetes/pkg/runtime/interfaces.go | 6 + .../k8s.io/kubernetes/pkg/runtime/scheme.go | 5 + .../kubernetes/pkg/runtime/scheme_test.go | 11 +- .../kubernetes/pkg/securitycontext/util.go | 36 - .../pkg/securitycontext/util_test.go | 72 - .../securitycontextconstraints/provider.go | 205 - .../provider_test.go | 393 - .../selinux/mustrunas.go | 82 - .../selinux/mustrunas_test.go | 157 - .../selinux/runasany.go | 42 - .../selinux/runasany_test.go | 71 - .../selinux/types.go | 30 - .../pkg/securitycontextconstraints/types.go | 33 - .../user/mustrunas.go | 71 - .../user/mustrunas_test.go | 90 - .../user/mustrunasrange.go | 76 - .../user/nonroot.go | 57 - .../user/nonroot_test.go | 78 - .../user/runasany.go | 42 - .../user/runasany_test.go | 58 - .../securitycontextconstraints/user/types.go | 30 - .../securitycontextconstraints/user/util.go | 57 - .../k8s.io/kubernetes/pkg/storage/cacher.go | 45 +- .../kubernetes/pkg/storage/cacher_test.go | 35 +- .../pkg/storage/etcd/api_object_versioner.go | 4 +- .../storage/etcd/api_object_versioner_test.go | 13 +- .../pkg/storage/etcd/etcd_helper.go | 94 +- .../pkg/storage/etcd/etcd_helper_test.go | 221 +- .../kubernetes/pkg/storage/etcd/etcd_util.go | 10 +- .../pkg/storage/etcd/etcd_watcher.go | 8 +- .../pkg/storage/etcd/etcd_watcher_test.go | 50 +- .../kubernetes/pkg/storage/interfaces.go | 23 +- .../testing/types.go} | 15 +- .../kubernetes/pkg/storage/watch_cache.go | 3 +- .../pkg/storage/watch_cache_test.go | 7 +- .../kubernetes/pkg/tools/etcdtest/etcdtest.go | 6 +- .../kubernetes/pkg/util/atomic_value.go | 2 +- .../kubernetes/pkg/util/atomic_value_test.go | 2 +- .../src/k8s.io/kubernetes/pkg/util/backoff.go | 14 + .../kubernetes/pkg/util/backoff_test.go | 69 + .../kubernetes/pkg/util/bandwidth/linux.go | 2 + .../pkg/util/bandwidth/linux_test.go | 2 + .../pkg/util/bandwidth/unsupported.go | 52 + .../pkg/util/deployment/deployment.go | 157 + .../kubernetes/pkg/util/errors/errors.go | 17 + .../kubernetes/pkg/util/errors/errors_test.go | 63 + .../pkg/util/fielderrors/fielderrors.go | 5 +- .../pkg/util/httpstream/httpstream.go | 7 + .../pkg/util/httpstream/spdy/roundtripper.go | 3 +- .../src/k8s.io/kubernetes/pkg/util/io/io.go | 6 +- .../k8s.io/kubernetes/pkg/util/io/io_test.go | 16 +- .../k8s.io/kubernetes/pkg/util/io/writer.go | 77 + .../kubernetes/pkg/util/iptables/iptables.go | 103 +- .../pkg/util/iptables/iptables_test.go | 155 +- .../pkg/util/jsonpath/jsonpath_test.go | 4 +- .../kubernetes/pkg/util/limitwriter/doc.go | 19 + .../pkg/util/limitwriter/limitwriter.go | 53 + .../k8s.io/kubernetes/pkg/util/mount/mount.go | 11 +- .../util/mount/safe_format_and_mount_test.go | 10 +- .../src/k8s.io/kubernetes/pkg/util/net.go | 63 - .../src/k8s.io/kubernetes/pkg/util/oom/oom.go | 6 +- .../kubernetes/pkg/util/oom/oom_fake.go | 15 +- .../kubernetes/pkg/util/oom/oom_linux.go | 14 +- .../kubernetes/pkg/util/oom/oom_linux_test.go | 46 +- .../pkg/util/oom/oom_unsupported.go | 12 +- .../kubernetes/pkg/util/proxy/transport.go | 5 +- .../pkg/util/proxy/transport_test.go | 8 + .../pkg/util/resource_container_linux.go | 5 + .../util/resource_container_unsupported.go | 4 + .../k8s.io/kubernetes/pkg/util/sets/set.go | 8 +- .../k8s.io/kubernetes/pkg/util/slice/slice.go | 3 +- .../k8s.io/kubernetes/pkg/util/ssh_test.go | 6 +- .../pkg/util/strategicpatch/patch.go | 343 +- .../pkg/util/strategicpatch/patch_test.go | 1068 +- .../kubernetes/pkg/util/sysctl/sysctl.go | 51 + .../src/k8s.io/kubernetes/pkg/util/util.go | 61 + .../pkg/util/{ => validation}/validation.go | 2 +- .../util/{ => validation}/validation_test.go | 2 +- .../k8s.io/kubernetes/pkg/util/wait/wait.go | 57 +- .../kubernetes/pkg/util/wait/wait_test.go | 107 +- .../pkg/util/wsstream/stream_test.go | 2 +- .../k8s.io/kubernetes/pkg/version/version.go | 16 + .../kubernetes/pkg/volume/aws_ebs/aws_ebs.go | 19 +- .../pkg/volume/aws_ebs/aws_ebs_test.go | 6 +- .../kubernetes/pkg/volume/cephfs/cephfs.go | 8 +- .../kubernetes/pkg/volume/cinder/cinder.go | 8 +- .../pkg/volume/downwardapi/downwardapi.go | 17 +- .../volume/downwardapi/downwardapi_test.go | 68 +- .../pkg/volume/empty_dir/empty_dir.go | 53 +- .../pkg/volume/empty_dir/empty_dir_test.go | 41 +- .../kubernetes/pkg/volume/fc/disk_manager.go | 112 + .../selinux => volume/fc}/doc.go | 7 +- .../src/k8s.io/kubernetes/pkg/volume/fc/fc.go | 198 + .../kubernetes/pkg/volume/fc/fc_test.go | 252 + .../kubernetes/pkg/volume/fc/fc_util.go | 200 + .../kubernetes/pkg/volume/fc/fc_util_test.go | 91 + .../kubernetes/pkg/volume/flocker/doc.go | 18 + .../kubernetes/pkg/volume/flocker/plugin.go | 232 + .../pkg/volume/flocker/plugin_test.go | 216 + .../kubernetes/pkg/volume/flocker/util.go | 28 + .../volume/flocker/util_test.go} | 28 +- .../kubernetes/pkg/volume/gce_pd/gce_pd.go | 8 +- .../pkg/volume/gce_pd/gce_pd_test.go | 6 +- .../kubernetes/pkg/volume/gce_pd/gce_util.go | 126 +- .../pkg/volume/git_repo/git_repo.go | 12 +- .../pkg/volume/git_repo/git_repo_test.go | 5 +- .../pkg/volume/glusterfs/glusterfs.go | 8 +- .../pkg/volume/glusterfs/glusterfs_test.go | 6 +- .../pkg/volume/host_path/host_path.go | 105 +- .../pkg/volume/host_path/host_path_test.go | 111 +- .../kubernetes/pkg/volume/iscsi/iscsi.go | 8 +- .../kubernetes/pkg/volume/iscsi/iscsi_test.go | 6 +- .../kubernetes/pkg/volume/iscsi/iscsi_util.go | 4 +- .../k8s.io/kubernetes/pkg/volume/nfs/nfs.go | 8 +- .../kubernetes/pkg/volume/nfs/nfs_test.go | 6 +- .../persistent_claim/persistent_claim.go | 8 +- .../persistent_claim/persistent_claim_test.go | 4 +- .../k8s.io/kubernetes/pkg/volume/plugins.go | 81 +- .../k8s.io/kubernetes/pkg/volume/rbd/rbd.go | 22 +- .../kubernetes/pkg/volume/rbd/rbd_test.go | 6 +- .../kubernetes/pkg/volume/rbd/rbd_util.go | 60 +- .../kubernetes/pkg/volume/secret/secret.go | 17 +- .../pkg/volume/secret/secret_test.go | 10 +- .../k8s.io/kubernetes/pkg/volume/testing.go | 42 +- .../k8s.io/kubernetes/pkg/volume/util/util.go | 13 - .../kubernetes/pkg/volume/util/util_test.go | 65 - .../k8s.io/kubernetes/pkg/volume/util_test.go | 2 +- .../k8s.io/kubernetes/pkg/volume/volume.go | 15 + .../kubernetes/pkg/watch/json/decoder_test.go | 3 +- .../src/k8s.io/kubernetes/pkg/watch/mux.go | 2 +- .../k8s.io/kubernetes/pkg/watch/mux_test.go | 4 +- .../plugin/cmd/kube-scheduler/app/server.go | 18 +- .../plugin/pkg/admission/exec/admission.go | 4 +- .../pkg/admission/exec/admission_test.go | 12 +- .../admission/initialresources/admission.go | 95 +- .../initialresources/admission_test.go | 168 +- .../admission/initialresources/data_source.go | 144 +- .../pkg/admission/initialresources/gcm.go | 133 + .../admission/initialresources/hawkular.go} | 25 +- .../admission/initialresources/influxdb.go | 158 + .../pkg/admission/limitranger/admission.go | 33 +- .../admission/limitranger/admission_test.go | 32 + .../admission/namespace/exists/admission.go | 13 +- .../namespace/lifecycle/admission.go | 12 +- .../namespace/lifecycle/admission_test.go | 9 +- .../pkg/admission/resourcequota/admission.go | 32 +- .../admission/resourcequota/admission_test.go | 10 +- .../pkg/admission/serviceaccount/admission.go | 46 +- .../serviceaccount/admission_test.go | 32 +- .../pkg/auth/authenticator/token/oidc/oidc.go | 11 +- .../authenticator/token/oidc/oidc_test.go | 2 - .../plugin/pkg/scheduler/algorithm/listers.go | 12 +- .../algorithm/predicates/predicates.go | 64 +- .../algorithm/predicates/predicates_test.go | 14 +- .../algorithm/priorities/priorities.go | 34 +- .../algorithm/priorities/priorities_test.go | 168 +- .../priorities/selector_spreading.go | 52 +- .../priorities/selector_spreading_test.go | 8 +- .../algorithm/scheduler_interface.go | 2 +- .../algorithm/scheduler_interface_test.go | 12 +- .../plugin/pkg/scheduler/algorithm/types.go | 2 +- .../defaults/compatibility_test.go | 11 +- .../algorithmprovider/defaults/defaults.go | 7 +- .../plugin/pkg/scheduler/api/types.go | 34 +- .../plugin/pkg/scheduler/api/v1/types.go | 34 +- .../plugin/pkg/scheduler/factory/factory.go | 22 +- .../pkg/scheduler/factory/factory_test.go | 17 +- .../plugin/pkg/scheduler/factory/plugins.go | 6 +- .../plugin/pkg/scheduler/generic_scheduler.go | 44 +- .../pkg/scheduler/generic_scheduler_test.go | 16 +- .../plugin/pkg/scheduler/scheduler.go | 20 +- .../plugin/pkg/scheduler/scheduler_test.go | 10 +- .../k8s.io/kubernetes/test/e2e/autoscaling.go | 145 +- .../kubernetes/test/e2e/autoscaling_utils.go | 190 +- .../kubernetes/test/e2e/cluster_upgrade.go | 4 +- .../kubernetes/test/e2e/container_probe.go | 7 +- .../src/k8s.io/kubernetes/test/e2e/core.go | 2 +- .../kubernetes/test/e2e/daemon_restart.go | 61 +- .../k8s.io/kubernetes/test/e2e/daemon_set.go | 311 +- .../src/k8s.io/kubernetes/test/e2e/density.go | 132 +- .../k8s.io/kubernetes/test/e2e/deployment.go | 271 + .../src/k8s.io/kubernetes/test/e2e/dns.go | 5 +- .../kubernetes/test/e2e/docker_containers.go | 20 +- .../kubernetes/test/e2e/downward_api.go | 97 +- .../kubernetes/test/e2e/downwardapi_volume.go | 4 +- .../k8s.io/kubernetes/test/e2e/e2e_test.go | 1 + .../k8s.io/kubernetes/test/e2e/empty_dir.go | 36 +- .../kubernetes/test/e2e/etcd_failure.go | 2 +- .../src/k8s.io/kubernetes/test/e2e/events.go | 2 +- .../k8s.io/kubernetes/test/e2e/examples.go | 55 +- .../k8s.io/kubernetes/test/e2e/expansion.go | 6 +- .../k8s.io/kubernetes/test/e2e/framework.go | 42 +- .../kubernetes/test/e2e/google_compute.go | 21 +- .../test/e2e/horizontal_pod_autoscaling.go | 166 +- .../k8s.io/kubernetes/test/e2e/host_path.go | 21 +- .../kubernetes/test/e2e/initial_resources.go | 75 + .../src/k8s.io/kubernetes/test/e2e/job.go | 261 + .../k8s.io/kubernetes/test/e2e/k8petstore.go | 170 + .../src/k8s.io/kubernetes/test/e2e/kube-ui.go | 2 +- .../src/k8s.io/kubernetes/test/e2e/kubectl.go | 260 +- .../src/k8s.io/kubernetes/test/e2e/kubelet.go | 17 +- .../kubernetes/test/e2e/kubelet_perf.go | 143 + .../kubernetes/test/e2e/kubelet_stats.go | 99 +- .../k8s.io/kubernetes/test/e2e/kubeproxy.go | 526 + .../src/k8s.io/kubernetes/test/e2e/load.go | 25 +- .../src/k8s.io/kubernetes/test/e2e/mesos.go | 53 + .../kubernetes/test/e2e/metrics_util.go | 303 + .../kubernetes/test/e2e/monitor_resources.go | 19 +- .../k8s.io/kubernetes/test/e2e/monitoring.go | 39 +- .../k8s.io/kubernetes/test/e2e/networking.go | 11 +- .../src/k8s.io/kubernetes/test/e2e/pd.go | 168 +- .../kubernetes/test/e2e/persistent_volumes.go | 7 +- .../src/k8s.io/kubernetes/test/e2e/pods.go | 47 +- .../k8s.io/kubernetes/test/e2e/portforward.go | 234 + .../k8s.io/kubernetes/test/e2e/pre_stop.go | 2 +- .../k8s.io/kubernetes/test/e2e/privileged.go | 181 + .../k8s.io/kubernetes/test/e2e/prompush.go | 3 +- .../src/k8s.io/kubernetes/test/e2e/proxy.go | 8 +- .../src/k8s.io/kubernetes/test/e2e/rc.go | 2 +- .../kubernetes/test/e2e/resize_nodes.go | 35 +- .../src/k8s.io/kubernetes/test/e2e/restart.go | 2 +- .../test/e2e/scheduler_predicates.go | 207 +- .../src/k8s.io/kubernetes/test/e2e/secrets.go | 4 +- .../src/k8s.io/kubernetes/test/e2e/service.go | 697 +- .../kubernetes/test/e2e/service_accounts.go | 2 +- .../kubernetes/test/e2e/service_latency.go | 4 +- .../test/e2e/serviceloadbalancers.go | 292 + .../src/k8s.io/kubernetes/test/e2e/ssh.go | 2 +- .../test/e2e/testing-manifests/haproxyrc.yaml | 49 + .../test/e2e/testing-manifests/netexecrc.yaml | 20 + .../e2e/testing-manifests/netexecsvc.yaml} | 12 +- .../test/e2e/testing-manifests/nginxrc.yaml | 16 + .../e2e/testing-manifests/nginxsvc.yaml} | 11 +- .../src/k8s.io/kubernetes/test/e2e/util.go | 499 +- .../src/k8s.io/kubernetes/test/e2e/volumes.go | 16 +- .../third_party/golang/template/exec.go | 4 +- 1547 files changed, 162543 insertions(+), 161326 deletions(-) create mode 100644 Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/README.md create mode 100644 Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/client.go create mode 100644 Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/client_test.go create mode 100644 Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/doc.go create mode 100644 Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/util.go delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/gcloud-golang/compute/metadata/metadata.go delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount/safe_format_and_mount_test.go create mode 100644 Godeps/_workspace/src/github.com/appc/cni/libcni/api.go create mode 100644 Godeps/_workspace/src/github.com/appc/cni/libcni/conf.go create mode 100644 Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/args.go create mode 100644 Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/exec.go create mode 100644 Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/find.go create mode 100644 Godeps/_workspace/src/github.com/appc/cni/pkg/types/args.go create mode 100644 Godeps/_workspace/src/github.com/appc/cni/pkg/types/types.go rename Godeps/_workspace/src/github.com/aws/aws-sdk-go/{internal/apierr/error.go => aws/awserr/types.go} (54%) rename Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/{string_value.go => prettify.go} (83%) create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config_test.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types_test.go rename Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/{handler_functions.go => corehandlers/handlers.go} (58%) create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator_test.go delete mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2_role_provider_test.go rename Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/{ => ec2rolecreds}/ec2_role_provider.go (58%) create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider_test.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/defaults/defaults.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api_test.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/errors.go delete mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handler_functions_test.go delete mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handlers_test.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/logger.go delete mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/param_validator.go delete mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/param_validator_test.go rename Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/{ => request}/handlers.go (57%) create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers_test.go rename Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/{ => request}/request.go (79%) rename Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/{ => request}/request_pagination_test.go (59%) rename Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/{ => request}/request_test.go (58%) create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/retryer.go delete mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/default_retryer.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/service.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/serviceinfo/service_info.go create mode 100644 Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types_test.go create mode 100644 Godeps/_workspace/src/github.com/bradfitz/http2/testdata/draft-ietf-httpbis-http2.xml create mode 100644 Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/Makefile create mode 100644 Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/golden_test.go create mode 100644 Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.pb.go create mode 100644 Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.pb.go.golden create mode 100644 Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.proto create mode 100644 Godeps/_workspace/src/github.com/jonboulle/clockwork/.travis.yml delete mode 100644 Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client.go create mode 100644 Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client2.go delete mode 100644 Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client_test.go delete mode 100644 Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/mocked_detect.go create mode 100644 Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.pb.go create mode 100644 Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.proto create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/bench_test.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode_test.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/encode.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/expfmt.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_0 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_1 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_2 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_3 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_4 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_0 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_1 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_10 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_11 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_12 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_13 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_14 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_15 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_16 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_17 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_18 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_19 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_2 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_3 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_4 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_5 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_6 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_7 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_8 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_9 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/minimal create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/json_decode.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/json_decode_test.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/json2 create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf.gz create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/test.gz create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/text create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create_test.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse_test.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/fingerprinting.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/labels.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/labels_test.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/labelset.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/metric.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/metric_test.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/model.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/signature.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/signature_test.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/time.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/time_test.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/value.go create mode 100644 Godeps/_workspace/src/github.com/prometheus/common/model/value_test.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/network_test.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/tokens_test.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing/doc.go rename Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/{fixtures_test.go => testing/fixtures.go} (99%) create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/doc.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/fixtures.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/requests.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/requests_test.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/results.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/urls.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/urls_test.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/doc.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/requests.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/requests_test.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing/doc.go rename Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/{ => testing}/fixtures.go (74%) create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/doc.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests_test.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/results.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls_test.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results_test.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/results.go create mode 100644 Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/urls.go create mode 100644 Godeps/_workspace/src/github.com/spf13/pflag/.travis.yml create mode 100644 Godeps/_workspace/src/github.com/spf13/pflag/LICENSE create mode 100644 Godeps/_workspace/src/github.com/spf13/pflag/verify/all.sh create mode 100644 Godeps/_workspace/src/github.com/spf13/pflag/verify/gofmt.sh create mode 100644 Godeps/_workspace/src/github.com/spf13/pflag/verify/golint.sh create mode 100644 Godeps/_workspace/src/github.com/ugorji/go/codec/tests.sh create mode 100644 Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/doc.go create mode 100644 Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/keys.go create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-charset.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-UTF-8-BOM.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-charset.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-content.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/No-encoding-declaration.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/README create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-16BE-BOM.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-16LE-BOM.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-charset.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-content.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/meta-charset-attribute.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/meta-content-attribute.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/go1.html create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/README create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/adoption01.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/adoption02.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/comments01.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/doctype01.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/entities01.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/entities02.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/html5test-com.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/inbody01.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/isindex.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/pending-spec-changes-plain-text-unsafe.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/pending-spec-changes.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/plain-text-unsafe.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/scriptdata01.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/scripted/adoption01.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/scripted/webkit01.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tables01.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests1.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests10.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests11.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests12.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests14.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests15.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests16.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests17.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests18.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests19.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests2.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests20.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests21.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests22.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests23.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests24.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests25.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests26.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests3.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests4.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests5.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests6.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests7.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests8.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests9.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests_innerHTML_1.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tricky01.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/webkit01.dat create mode 100644 Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/webkit02.dat create mode 100644 Godeps/_workspace/src/google.golang.org/api/cloudmonitoring/v2beta2/cloudmonitoring-api.json create mode 100644 Godeps/_workspace/src/google.golang.org/api/cloudmonitoring/v2beta2/cloudmonitoring-gen.go create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/testdata/ca.pem create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/testdata/route_guide_db.json create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/testdata/server1.key create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/examples/route_guide/testdata/server1.pem create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/interop/client/testdata/ca.pem create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/interop/client/testdata/server1.key create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/interop/client/testdata/server1.pem create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/interop/server/testdata/ca.pem create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/interop/server/testdata/server1.key create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/interop/server/testdata/server1.pem create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/test/testdata/ca.pem create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/test/testdata/server1.key create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/test/testdata/server1.pem create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/transport/testdata/ca.pem create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/transport/testdata/server1.key create mode 100644 Godeps/_workspace/src/google.golang.org/grpc/transport/testdata/server1.pem create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/cmd/kube-proxy/app/server_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/accessing-the-api.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/admission-controllers.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/authentication.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/authorization.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/cluster-components.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/cluster-large.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/cluster-management.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/cluster-troubleshooting.md create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/daemon.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/dns.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/etcd.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/high-availability.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/high-availability/default-kubelet delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/high-availability/etcd.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/high-availability/ha.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/high-availability/ha.svg delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/high-availability/kube-apiserver.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/high-availability/kube-controller-manager.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/high-availability/kube-scheduler.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/high-availability/monit-docker delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/high-availability/monit-kubelet delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/high-availability/podmaster.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/introduction.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/kube-apiserver.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/kube-controller-manager.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/kube-proxy.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/kube-scheduler.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/kubelet.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/multi-cluster.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/namespaces.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/namespaces/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/networking.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/node.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/ovs-networking.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/ovs-networking.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/resource-quota.md rename Godeps/_workspace/src/k8s.io/kubernetes/docs/{user-guide => admin}/resourcequota/limits.yaml (71%) mode change 100644 => 100755 rename Godeps/_workspace/src/k8s.io/kubernetes/docs/{user-guide => admin}/resourcequota/namespace.yaml (100%) rename Godeps/_workspace/src/k8s.io/kubernetes/docs/{user-guide => admin}/resourcequota/quota.yaml (100%) delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/salt.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/admin/service-accounts-admin.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/definitions.html delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/definitions.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/operations.html delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/operations.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/api.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/access.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control_limit_range.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control_resource_quota.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/architecture.dia delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/architecture.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/architecture.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/architecture.svg delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/.gitignore delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/Dockerfile delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/Makefile delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/dynamic.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/dynamic.seqdiag delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/static.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/static.seqdiag delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/command_execution_port_forwarding.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/event_compression.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/expansion.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/identifiers.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/namespaces.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/networking.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/persistent-storage.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/principles.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/resources.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/secrets.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/security.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/security_context.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/service_accounts.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/simple-rolling-update.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/design/versioning.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/api-conventions.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/api_changes.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/cherry-picks.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/cli-roadmap.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/client-libraries.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/coding-conventions.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/collab.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/developer-guides/vagrant.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/development.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/faster_reviews.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/flaky-tests.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/getting-builds.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/git_workflow.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/instrumentation.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/issues.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/logging.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/making-release-notes.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/profiling.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/pull-requests.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.dot delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.svg delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/scheduler.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/scheduler_algorithm.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/writing-a-getting-started-guide.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/all-lines.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws-coreos.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloud-configs/master.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloud-configs/node.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloudformation-template.json delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/kubectl.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/azure.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/bigquery-logging.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/binary_release.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/centos/centos_manual_config.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/cloud-logging-console.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/cloudstack.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/.gitignore delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/addons/skydns-rc.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/addons/skydns-svc.yaml delete mode 100755 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/azure-login.js delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/cloud_config_templates/kubernetes-cluster-etcd-node-template.yml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/cloud_config_templates/kubernetes-cluster-main-nodes-template.yml delete mode 100755 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/create-kubernetes-cluster.js delete mode 100755 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/destroy-cluster.js delete mode 100755 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/expose_guestbook_app_port.sh delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/external_access.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/initial_cluster.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/azure_wrapper.js delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/cloud_config.js delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/deployment_logic/kubernetes.js delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/util.js delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/package.json delete mode 100755 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/scale-kubernetes-cluster.js delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/bare_metal_offline.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/cloud-configs/master.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/cloud-configs/node.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/coreos_multinode_cluster.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/master.md delete mode 100755 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/master.sh delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/testing.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/worker.md delete mode 100755 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/worker.sh delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/es-browser.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/fedora/fedora_ansible_config.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/fedora/fedora_manual_config.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/fedora/flannel_multi_node_cluster.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/gce.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/juju.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/k8s-docker.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/k8s-singlenode-docker.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/kibana-logs.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/libvirt-coreos.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/locally.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/logging-elasticsearch.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/logging.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/mesos.md delete mode 100755 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/mesos/k8s-firewall.png delete mode 100755 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/mesos/k8s-guestbook.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/ovirt.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/rackspace.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/rkt/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/scratch.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/ubuntu-calico.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/ubuntu.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/vagrant.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/vsphere.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/.files_generated delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-api-versions.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-attach.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-cluster-info.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-cluster.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-context.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-credentials.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-unset.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-use-context.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-view.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-create.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-delete.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-describe.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-exec.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-expose.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-get.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-label.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-logs.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-namespace.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-patch.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-port-forward.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-proxy.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-replace.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-rolling-update.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-run.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-scale.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-stop.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-version.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl.1 delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/reporting-security-issues.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/roadmap.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/troubleshooting.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/accessing-the-cluster.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/annotations.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/application-troubleshooting.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/cadvisor.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/compute-resources.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/config-best-practices.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/configuring-containers.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-applications.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-to-applications-port-forward.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-to-applications-proxy.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/container-environment.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/containers.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/debugging-services.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/deploying-applications.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/docker-cli-to-kubectl.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api/volume/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/backend-rc.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/backend/Dockerfile delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/show/Dockerfile delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/show/show.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/diagram.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/show-rc.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/gcm.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/getting-into-containers.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/identifiers.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/images.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/influx.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/introspection-and-debugging.md create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/job.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore-filter.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore-groupby.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore-poddetail.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-nodes.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-overview.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kibana.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/known-issues.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubeconfig-file.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/.files_generated delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_api-versions.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_attach.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_cluster-info.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-cluster.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-context.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-credentials.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_unset.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_use-context.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_view.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_create.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_delete.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_describe.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_exec.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_expose.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_get.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_label.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_logs.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_namespace.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_patch.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_port-forward.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_proxy.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_replace.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_rolling-update.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_run.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_scale.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_stop.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_version.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/labels.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/invalid-pod.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/limits.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/namespace.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/valid-pod.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/Dockerfile delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/Makefile delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/server.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging-demo/Makefile delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging-demo/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging-demo/synth-logger.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/managing-deployments.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/monitoring-architecture.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/monitoring.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/namespaces.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/node-selection/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/overview.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/persistent-volumes.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/persistent-volumes/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/pod-states.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/pods.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/prereqs.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/production-pods.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/quick-start.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/replication-controller.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/resourcequota/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/secrets.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/secrets/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/security-context.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/service-accounts.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-detail.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-detail.svg delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-firewalls.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-overview.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-overview.svg delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/sharing-clusters.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/simple-nginx.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/ui.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/README.md delete mode 100755 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/build-images.sh delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/kitten/Dockerfile delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/kitten/html/data.json delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/kitten/html/kitten.jpg delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/nautilus/Dockerfile delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/nautilus/html/data.json delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/nautilus/html/nautilus.jpg delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/LICENSE.angular delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/angular.min.js delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/angular.min.js.map delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/index.html delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/script.js delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/style.css delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/volumes.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/walkthrough/k8s201.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/working-with-resources.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/warning.png delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/docs/whatisk8s.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs-with-secret.json create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs-with-secret.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs.json create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/secret/ceph-secret.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-client-rc.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-data-rc.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-discovery-svc.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-master-rc.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-svc.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/service-account.yaml create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/experimental/deployment.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/explorer/pod.json create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/explorer/pod.yaml create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/fibre_channel/fc.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/Dockerfile delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/controllers.js delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/index.html delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/index.php delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/redis-slave/Dockerfile delete mode 100755 Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/redis-slave/run.sh create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/javaweb-tomcat-sidecar/javaweb-2.yaml create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/javaweb-tomcat-sidecar/javaweb.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/metadata/README.md delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/metadata/metadata-volume.yaml delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/examples/phabricator/authenticator-controller.json create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/compat/compatibility_tester.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/pod_specs.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/duration.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/duration_test.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/{util => api/unversioned}/time.go (99%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/{util => api/unversioned}/time_test.go (99%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/types.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/types_swagger_doc_generated.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/backward_compatibility_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_volumesource_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_volumesource_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/register.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/latest/latest.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/testapi/testapi.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/conversion_generated.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/validation/validation.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/{experimental => extensions}/deep_copy_generated.go (62%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/install/install.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/install/install_test.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/{experimental => extensions}/register.go (85%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/{experimental => extensions}/types.go (58%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/{experimental/v1 => extensions/v1beta1}/conversion.go (56%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion_generated.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/{experimental/v1 => extensions/v1beta1}/deep_copy_generated.go (63%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/{experimental/v1 => extensions/v1beta1}/defaults.go (67%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/{experimental/v1 => extensions/v1beta1}/defaults_test.go (69%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/{experimental/v1 => extensions/v1beta1}/register.go (81%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/{experimental/v1 => extensions/v1beta1}/types.go (59%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/{experimental/v1 => extensions/v1beta1}/types_swagger_doc_generated.go (61%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/validation/validation.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/{experimental => extensions}/validation/validation_test.go (59%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/testing/types.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/{experimental.go => extensions.go} (50%) delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/fake.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/fake/fake.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper_blackbox_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/import_known_versions.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/ingress.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/ingress_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/jobs.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/jobs_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_ingress.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_jobs.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_securitycontextconstraints.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/deployment/deployment_controller.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/deployment/deployment_controller_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/doc.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/gc_controller.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/gc_controller_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/job/controller.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/job/controller_test.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/{securitycontextconstraints/user => controller/job}/doc.go (77%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/unversioned_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/apply.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apply.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apply_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/convert.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/edit.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/explain.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/editor.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/editor_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/term.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/term_unsupported.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/jsonmerge/jsonmerge.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/explain.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/testing/types.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/image_puller_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/readiness_manager.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_linux_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_unsupported_test.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/{ => dockertools}/container_gc.go (66%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/{ => dockertools}/container_gc_test.go (92%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/cni/cni.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/cni/cni_test.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/{mirror_client_test.go => pod/fake_mirror_client.go} (55%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/{pod_manager.go => pod/manager.go} (77%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/{pod_manager_test.go => pod/manager_test.go} (83%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/{ => pod}/mirror_client.go (70%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/mirror_client_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/fake_manager.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/fake_prober.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/manager.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/manager_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/results/results_manager.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/results/results_manager_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/worker.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/worker_test.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/{status_manager.go => status/manager.go} (61%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/{status_manager_test.go => status/manager_test.go} (63%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/{types.go => types/pod_update.go} (80%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/{types_test.go => types/pod_update_test.go} (98%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/import_known_versions.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/thirdparty_controller.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/thirdparty_controller_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/strategy_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/registry.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/response_checker.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/response_checker_test.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/{securitycontextconstraints => ingress}/doc.go (76%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/etcd/etcd.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/etcd/etcd_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/strategy.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/strategy_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/registry.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/strategy.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/types.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/types.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunasrange.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany_test.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/types.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/util.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/{kubelet/prober/prober_fake.go => storage/testing/types.go} (69%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/unsupported.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/deployment/deployment.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/writer.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/limitwriter/doc.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/limitwriter/limitwriter.go delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/net.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/sysctl/sysctl.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/{ => validation}/validation.go (99%) rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/{ => validation}/validation_test.go (99%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/disk_manager.go rename Godeps/_workspace/src/k8s.io/kubernetes/pkg/{securitycontextconstraints/selinux => volume/fc}/doc.go (76%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_util.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_util_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/doc.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/plugin.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/plugin_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/util.go rename Godeps/_workspace/src/k8s.io/kubernetes/{docs/user-guide/environment-guide/containers/backend/backend.go => pkg/volume/flocker/util_test.go} (59%) delete mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util/util_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/gcm.go rename Godeps/_workspace/src/k8s.io/kubernetes/{pkg/util/list.go => plugin/pkg/admission/initialresources/hawkular.go} (53%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/influxdb.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/deployment.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/initial_resources.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/job.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/k8petstore.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet_perf.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubeproxy.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/mesos.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/metrics_util.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/portforward.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/privileged.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/serviceloadbalancers.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/haproxyrc.yaml create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/netexecrc.yaml rename Godeps/_workspace/src/k8s.io/kubernetes/{docs/user-guide/environment-guide/show-srv.yaml => test/e2e/testing-manifests/netexecsvc.yaml} (60%) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/nginxrc.yaml rename Godeps/_workspace/src/k8s.io/kubernetes/{docs/user-guide/environment-guide/backend-srv.yaml => test/e2e/testing-manifests/nginxsvc.yaml} (52%) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 4d1ffc31e5c9..ec6634792e3f 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -27,6 +27,10 @@ "ImportPath": "github.com/AdRoll/goamz/s3", "Rev": "cc210f45dcb9889c2769a274522be2bf70edfb99" }, + { + "ImportPath": "github.com/ClusterHQ/flocker-go", + "Rev": "3f33ece70f6571f0ec45bfae2f243ab11fab6c52" + }, { "ImportPath": "github.com/MakeNowJust/heredoc", "Rev": "1d91351acdc1cb2f2c995864674b754134b86ca7" @@ -48,6 +52,21 @@ "ImportPath": "github.com/abbot/go-http-auth", "Rev": "c0ef4539dfab4d21c8ef20ba2924f9fc6f186d35" }, + { + "ImportPath": "github.com/appc/cni/libcni", + "Comment": "v0.1.0-27-g2a58bd9", + "Rev": "2a58bd9379ca33579f0cf631945b717aa4fa373d" + }, + { + "ImportPath": "github.com/appc/cni/pkg/invoke", + "Comment": "v0.1.0-27-g2a58bd9", + "Rev": "2a58bd9379ca33579f0cf631945b717aa4fa373d" + }, + { + "ImportPath": "github.com/appc/cni/pkg/types", + "Comment": "v0.1.0-27-g2a58bd9", + "Rev": "2a58bd9379ca33579f0cf631945b717aa4fa373d" + }, { "ImportPath": "github.com/appc/spec/schema", "Comment": "v0.6.1-30-gc928a0c", @@ -55,58 +74,53 @@ }, { "ImportPath": "github.com/aws/aws-sdk-go/aws", - "Comment": "v0.6.0-7-gcea3a42", - "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" - }, - { - "ImportPath": "github.com/aws/aws-sdk-go/internal/apierr", - "Comment": "v0.6.0-7-gcea3a42", - "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" + "Comment": "v0.9.9", + "Rev": "c4ae871ffc03691a7b039fa751a1e7afee56e920" }, { "ImportPath": "github.com/aws/aws-sdk-go/internal/endpoints", - "Comment": "v0.6.0-7-gcea3a42", - "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" + "Comment": "v0.9.9", + "Rev": "c4ae871ffc03691a7b039fa751a1e7afee56e920" }, { "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/ec2query", - "Comment": "v0.6.0-7-gcea3a42", - "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" + "Comment": "v0.9.9", + "Rev": "c4ae871ffc03691a7b039fa751a1e7afee56e920" }, { "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/query", - "Comment": "v0.6.0-7-gcea3a42", - "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" + "Comment": "v0.9.9", + "Rev": "c4ae871ffc03691a7b039fa751a1e7afee56e920" }, { "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/rest", - "Comment": "v0.6.0-7-gcea3a42", - "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" + "Comment": "v0.9.9", + "Rev": "c4ae871ffc03691a7b039fa751a1e7afee56e920" }, { "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil", - "Comment": "v0.6.0-7-gcea3a42", - "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" + "Comment": "v0.9.9", + "Rev": "c4ae871ffc03691a7b039fa751a1e7afee56e920" }, { "ImportPath": "github.com/aws/aws-sdk-go/internal/signer/v4", - "Comment": "v0.6.0-7-gcea3a42", - "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" + "Comment": "v0.9.9", + "Rev": "c4ae871ffc03691a7b039fa751a1e7afee56e920" }, { "ImportPath": "github.com/aws/aws-sdk-go/service/autoscaling", - "Comment": "v0.6.0-7-gcea3a42", - "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" + "Comment": "v0.9.9", + "Rev": "c4ae871ffc03691a7b039fa751a1e7afee56e920" }, { "ImportPath": "github.com/aws/aws-sdk-go/service/ec2", - "Comment": "v0.6.0-7-gcea3a42", - "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" + "Comment": "v0.9.9", + "Rev": "c4ae871ffc03691a7b039fa751a1e7afee56e920" }, { "ImportPath": "github.com/aws/aws-sdk-go/service/elb", - "Comment": "v0.6.0-7-gcea3a42", - "Rev": "cea3a425fc2d887d102e406ec2f8b37a57abd82f" + "Comment": "v0.9.9", + "Rev": "c4ae871ffc03691a7b039fa751a1e7afee56e920" }, { "ImportPath": "github.com/beorn7/perks/quantile", @@ -116,10 +130,6 @@ "ImportPath": "github.com/bradfitz/http2", "Rev": "f8202bc903bda493ebba4aa54922d78430c2c42f" }, - { - "ImportPath": "github.com/bradfitz/http2/hpack", - "Rev": "f8202bc903bda493ebba4aa54922d78430c2c42f" - }, { "ImportPath": "github.com/coreos/etcd/client", "Comment": "v2.1.2", @@ -284,11 +294,6 @@ "Comment": "v2-27-g97e243d", "Rev": "97e243d21a8e232e9d8af38ba2366dfcfceebeba" }, - { - "ImportPath": "github.com/coreos/go-systemd/journal", - "Comment": "v2-27-g97e243d", - "Rev": "97e243d21a8e232e9d8af38ba2366dfcfceebeba" - }, { "ImportPath": "github.com/coreos/go-systemd/unit", "Comment": "v2-27-g97e243d", @@ -436,8 +441,8 @@ }, { "ImportPath": "github.com/gogo/protobuf/proto", - "Comment": "v0.1", - "Rev": "6cab0cc9fec8f660c2cee46e1306ffc727261956" + "Comment": "v0.1-55-g2093b57", + "Rev": "2093b57e5ca2ccbee4626814100bc1aada691b18" }, { "ImportPath": "github.com/golang/glog", @@ -632,19 +637,23 @@ }, { "ImportPath": "github.com/mesos/mesos-go/detector", - "Rev": "65cb9ffec50a76f4ed9fe4808405b66b3bb7010d" + "Comment": "v0.0.1-20-gb164c06", + "Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" }, { "ImportPath": "github.com/mesos/mesos-go/mesosproto", - "Rev": "65cb9ffec50a76f4ed9fe4808405b66b3bb7010d" + "Comment": "v0.0.1-20-gb164c06", + "Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" }, { "ImportPath": "github.com/mesos/mesos-go/mesosutil", - "Rev": "65cb9ffec50a76f4ed9fe4808405b66b3bb7010d" + "Comment": "v0.0.1-20-gb164c06", + "Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" }, { "ImportPath": "github.com/mesos/mesos-go/upid", - "Rev": "65cb9ffec50a76f4ed9fe4808405b66b3bb7010d" + "Comment": "v0.0.1-20-gb164c06", + "Rev": "b164c06f346af1e93aecb6502f83d31dbacdbb91" }, { "ImportPath": "github.com/miekg/dns", @@ -747,14 +756,22 @@ "Comment": "model-0.0.2-12-gfa8ad6f", "Rev": "fa8ad6fec33561be4280a8f0514318c79d7f6cb6" }, + { + "ImportPath": "github.com/prometheus/common/expfmt", + "Rev": "ef7a9a5fb138aa5d3a19988537606226869a0390" + }, + { + "ImportPath": "github.com/prometheus/common/model", + "Rev": "ef7a9a5fb138aa5d3a19988537606226869a0390" + }, { "ImportPath": "github.com/prometheus/procfs", "Rev": "490cc6eb5fa45bf8a8b7b73c8bc82a8160e8531d" }, { "ImportPath": "github.com/rackspace/gophercloud", - "Comment": "v1.0.0-569-gf3ced00", - "Rev": "f3ced00552c1c7d4a6184500af9062cfb4ff4463" + "Comment": "v1.0.0-665-gf928634", + "Rev": "f92863476c034f851073599c09d90cd61ee95b3d" }, { "ImportPath": "github.com/russross/blackfriday", @@ -763,7 +780,7 @@ }, { "ImportPath": "github.com/samuel/go-zookeeper/zk", - "Rev": "d0e0d8e11f318e000a8cc434616d69e329edc374" + "Rev": "177002e16a0061912f02377e2dd8951a8b3551bc" }, { "ImportPath": "github.com/scalingdata/gcfg", @@ -826,7 +843,7 @@ }, { "ImportPath": "github.com/ugorji/go/codec", - "Rev": "821cda7e48749cacf7cad2c6ed01e96457ca7e9d" + "Rev": "2f4b94206aae781e63846a9bf02ad83c387d5296" }, { "ImportPath": "github.com/vaughan0/go-ini", @@ -858,11 +875,11 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "ea47fc708ee3e20177f3ca3716217c4ab75942cb" + "Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e" }, { "ImportPath": "golang.org/x/net/html", - "Rev": "ea47fc708ee3e20177f3ca3716217c4ab75942cb" + "Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e" }, { "ImportPath": "golang.org/x/net/internal/timeseries", @@ -878,12 +895,16 @@ }, { "ImportPath": "golang.org/x/net/websocket", - "Rev": "ea47fc708ee3e20177f3ca3716217c4ab75942cb" + "Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e" }, { "ImportPath": "golang.org/x/oauth2", "Rev": "b5adcc2dcdf009d0391547edc6ecbaff889f5bb9" }, + { + "ImportPath": "google.golang.org/api/cloudmonitoring/v2beta2", + "Rev": "0c2979aeaa5b573e60d3ddffe5ce8dca8df309bd" + }, { "ImportPath": "google.golang.org/api/compute/v1", "Rev": "0c2979aeaa5b573e60d3ddffe5ce8dca8df309bd" @@ -924,448 +945,478 @@ }, { "ImportPath": "k8s.io/kubernetes/cmd/kube-apiserver/app", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/cmd/kube-controller-manager/app", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/cmd/kube-proxy/app", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/cmd/kubelet/app", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/admission", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/api", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { - "ImportPath": "k8s.io/kubernetes/pkg/apis/experimental", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "ImportPath": "k8s.io/kubernetes/pkg/apis/extensions", + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/apiserver", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/authenticator", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/authorizer", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/handlers", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/user", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/capabilities", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/client/cache", + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/client/chaosclient", + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/client/metrics", + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/client/record", + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned", + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/cloudprovider", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/conversion", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/credentialprovider", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/fieldpath", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/fields", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/healthz", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/httplog", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubectl", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/labels", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/master", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/probe", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/proxy", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/componentstatus", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/controller", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/daemonset", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/deployment", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/endpoint", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/event", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/experimental/controller/etcd", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/generic", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/registry/ingress", + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/job", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/limitrange", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/namespace", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/node", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/persistentvolume", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/persistentvolumeclaim", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/pod", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/podtemplate", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/registrytest", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/resourcequota", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/secret", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/service", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/serviceaccount", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/thirdpartyresource", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/securitycontext", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/securitycontextconstraints", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/storage", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/tools", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/types", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/ui", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/util", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/version", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/pkg/watch", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/admit", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/deny", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { - "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/exec/denyprivileged", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/exec", + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/initialresources", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/limitranger", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/namespace/autoprovision", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/namespace/exists", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/namespace/lifecycle", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/resourcequota", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/securitycontext/scdeny", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/passwordfile", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/basicauth", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/keystone", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/x509", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/tokenfile", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/test/e2e", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/third_party/forked/coreos/go-etcd/etcd", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/third_party/forked/json", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/third_party/forked/reflect", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/third_party/golang/expansion", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/third_party/golang/netutil", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "k8s.io/kubernetes/third_party/golang/template", - "Comment": "v1.1.0-alpha.1-653-g86b4e77", - "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", + "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, { "ImportPath": "speter.net/go/exp/math/dec/inf", diff --git a/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/README.md b/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/README.md new file mode 100644 index 000000000000..7c57e11295ec --- /dev/null +++ b/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/README.md @@ -0,0 +1,18 @@ +flocker-go +========== + +[![circleci](https://circleci.com/gh/ClusterHQ/flocker-go.svg)](https://circleci.com/gh/ClusterHQ/flocker-go) + +flocker-go implements the package `flocker` that will let you easily interact +with a Flocker Control Service. + +What can it do? +--------------- + +You can check the package documentation here: https://godoc.org/github.com/ClusterHQ/flocker-go + +TODO +---- + +- Define a proper interface `flockerClientable` with all the needed methods for + wrapping the Flocker API. diff --git a/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/client.go b/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/client.go new file mode 100644 index 000000000000..e054ee121eec --- /dev/null +++ b/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/client.go @@ -0,0 +1,323 @@ +package flocker + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "time" +) + +// From https://github.com/ClusterHQ/flocker-docker-plugin/blob/master/flockerdockerplugin/adapter.py#L18 +const defaultVolumeSize = json.Number("107374182400") + +var ( + // A volume can take a long time to be available, if we don't want + // Kubernetes to wait forever we need to stop trying after some time, that + // time is defined here + timeoutWaitingForVolume = 2 * time.Minute + tickerWaitingForVolume = 5 * time.Second + + errStateNotFound = errors.New("State not found by Dataset ID") + errConfigurationNotFound = errors.New("Configuration not found by Name") + + errFlockerControlServiceHost = errors.New("The volume config must have a key CONTROL_SERVICE_HOST defined in the OtherAttributes field") + errFlockerControlServicePort = errors.New("The volume config must have a key CONTROL_SERVICE_PORT defined in the OtherAttributes field") + + errVolumeAlreadyExists = errors.New("The volume already exists") + errVolumeDoesNotExist = errors.New("The volume does not exist") + + errUpdatingDataset = errors.New("It was impossible to update the dataset") +) + +// Clientable exposes the needed methods to implement your own Flocker Client. +type Clientable interface { + CreateDataset(metaName string) (*DatasetState, error) + + GetDatasetState(datasetID string) (*DatasetState, error) + GetDatasetID(metaName string) (datasetID string, err error) + GetPrimaryUUID() (primaryUUID string, err error) + + UpdatePrimaryForDataset(primaryUUID, datasetID string) (*DatasetState, error) +} + +// Client is a default Flocker Client. +type Client struct { + *http.Client + + schema string + host string + port int + version string + + clientIP string + + maximumSize json.Number +} + +// NewClient creates a wrapper over http.Client to communicate with the flocker control service. +func NewClient(host string, port int, clientIP string, caCertPath, keyPath, certPath string) (*Client, error) { + client, err := newTLSClient(caCertPath, keyPath, certPath) + if err != nil { + return nil, err + } + + return &Client{ + Client: client, + schema: "https", + host: host, + port: port, + version: "v1", + maximumSize: defaultVolumeSize, + clientIP: clientIP, + }, nil +} + +/* +request do a request using the http.Client embedded to the control service +and returns the response or an error in case it happens. + +Note: you will need to deal with the response body call to Close if you +don't want to deal with problems later. +*/ +func (c Client) request(method, url string, payload interface{}) (*http.Response, error) { + var ( + b []byte + err error + ) + + if method == "POST" { // Just allow payload on POST + b, err = json.Marshal(payload) + if err != nil { + return nil, err + } + } + + req, err := http.NewRequest(method, url, bytes.NewBuffer(b)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + + // REMEMBER TO CLOSE THE BODY IN THE OUTSIDE FUNCTION + return c.Do(req) +} + +// post performs a post request with the indicated payload +func (c Client) post(url string, payload interface{}) (*http.Response, error) { + return c.request("POST", url, payload) +} + +// get performs a get request +func (c Client) get(url string) (*http.Response, error) { + return c.request("GET", url, nil) +} + +// getURL returns a full URI to the control service +func (c Client) getURL(path string) string { + return fmt.Sprintf("%s://%s:%d/%s/%s", c.schema, c.host, c.port, c.version, path) +} + +type configurationPayload struct { + Primary string `json:"primary"` + DatasetID string `json:"dataset_id,omitempty"` + MaximumSize json.Number `json:"maximum_size,omitempty"` + Metadata metadataPayload `json:"metadata,omitempty"` +} + +type metadataPayload struct { + Name string `json:"name,omitempty"` +} + +type DatasetState struct { + Path string `json:"path"` + DatasetID string `json:"dataset_id"` + Primary string `json:"primary,omitempty"` + MaximumSize json.Number `json:"maximum_size,omitempty"` +} + +type datasetStatePayload struct { + *DatasetState +} + +type nodeStatePayload struct { + UUID string `json:"uuid"` + Host string `json:"host"` +} + +// findIDInConfigurationsPayload returns the datasetID if it was found in the +// configurations payload, otherwise it will return an error. +func (c Client) findIDInConfigurationsPayload(body io.ReadCloser, name string) (datasetID string, err error) { + var configurations []configurationPayload + if err = json.NewDecoder(body).Decode(&configurations); err == nil { + for _, r := range configurations { + if r.Metadata.Name == name { + return r.DatasetID, nil + } + } + return "", errConfigurationNotFound + } + return "", err +} + +// GetPrimaryUUID returns the UUID of the primary Flocker Control Service for +// the given host. +func (c Client) GetPrimaryUUID() (uuid string, err error) { + resp, err := c.get(c.getURL("state/nodes")) + if err != nil { + return "", err + } + defer resp.Body.Close() + + var states []nodeStatePayload + if err = json.NewDecoder(resp.Body).Decode(&states); err == nil { + for _, s := range states { + if s.Host == c.clientIP { + return s.UUID, nil + } + } + return "", errStateNotFound + } + return "", err +} + +// GetDatasetState performs a get request to get the state of the given datasetID, if +// something goes wrong or the datasetID was not found it returns an error. +func (c Client) GetDatasetState(datasetID string) (*DatasetState, error) { + resp, err := c.get(c.getURL("state/datasets")) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var states []datasetStatePayload + if err = json.NewDecoder(resp.Body).Decode(&states); err == nil { + for _, s := range states { + if s.DatasetID == datasetID { + return s.DatasetState, nil + } + } + return nil, errStateNotFound + } + + return nil, err +} + +/* +CreateDataset creates a volume in Flocker, waits for it to be ready and +returns the dataset id. + +This process is a little bit complex but follows this flow: + +1. Find the Flocker Control Service UUID +2. Try to create the dataset +3. If it already exists an error is returned +4. If it didn't previously exist, wait for it to be ready +*/ +func (c Client) CreateDataset(metaName string) (*DatasetState, error) { + // 1) Find the primary Flocker UUID + // Note: it could be cached, but doing this query we health check it + primary, err := c.GetPrimaryUUID() + if err != nil { + return nil, err + } + + // 2) Try to create the dataset in the given Primary + payload := configurationPayload{ + Primary: primary, + MaximumSize: json.Number(c.maximumSize), + Metadata: metadataPayload{ + Name: metaName, + }, + } + + resp, err := c.post(c.getURL("configuration/datasets"), payload) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + // 3) Return if the dataset was previously created + if resp.StatusCode == http.StatusConflict { + return nil, errVolumeAlreadyExists + } + + if resp.StatusCode >= 300 { + return nil, fmt.Errorf("Expected: {1,2}xx creating the volume, got: %d", resp.StatusCode) + } + + var p configurationPayload + if err := json.NewDecoder(resp.Body).Decode(&p); err != nil { + return nil, err + } + + // 4) Wait until the dataset is ready for usage. In case it never gets + // ready there is a timeoutChan that will return an error + timeoutChan := time.NewTimer(timeoutWaitingForVolume).C + tickChan := time.NewTicker(tickerWaitingForVolume).C + + for { + if s, err := c.GetDatasetState(p.DatasetID); err == nil { + return s, nil + } else if err != errStateNotFound { + return nil, err + } + + select { + case <-timeoutChan: + return nil, err + case <-tickChan: + break + } + } +} + +// UpdatePrimaryForDataset will update the Primary for the given dataset +// returning the current DatasetState. +func (c Client) UpdatePrimaryForDataset(newPrimaryUUID, datasetID string) (*DatasetState, error) { + payload := struct { + Primary string `json:"primary"` + }{ + Primary: newPrimaryUUID, + } + + url := c.getURL(fmt.Sprintf("configuration/datasets/%s", datasetID)) + resp, err := c.post(url, payload) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode >= 300 { + return nil, errUpdatingDataset + } + + var s DatasetState + if err := json.NewDecoder(resp.Body).Decode(&s); err != nil { + return nil, err + } + + return &s, nil +} + +// GetDatasetID will return the DatasetID found for the given metadata name. +func (c Client) GetDatasetID(metaName string) (datasetID string, err error) { + resp, err := c.get(c.getURL("configuration/datasets")) + if err != nil { + return "", err + } + defer resp.Body.Close() + + var configurations []configurationPayload + if err = json.NewDecoder(resp.Body).Decode(&configurations); err == nil { + for _, c := range configurations { + if c.Metadata.Name == metaName { + return c.DatasetID, nil + } + } + return "", errConfigurationNotFound + } + return "", err +} diff --git a/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/client_test.go b/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/client_test.go new file mode 100644 index 000000000000..ef0feaf7e97e --- /dev/null +++ b/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/client_test.go @@ -0,0 +1,316 @@ +package flocker + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" + "strconv" + "strings" + "testing" + "time" + + "k8s.io/kubernetes/pkg/volume" + + "github.com/stretchr/testify/assert" +) + +func TestMaximumSizeIs1024Multiple(t *testing.T) { + assert := assert.New(t) + + n, err := strconv.Atoi(string(defaultVolumeSize)) + assert.NoError(err) + assert.Equal(0, n%1024) +} + +func TestPost(t *testing.T) { + const ( + expectedPayload = "foobar" + expectedStatusCode = 418 + ) + + assert := assert.New(t) + + type payload struct { + Test string `json:"test"` + } + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var result payload + err := json.NewDecoder(r.Body).Decode(&result) + assert.NoError(err) + assert.Equal(expectedPayload, result.Test) + w.WriteHeader(expectedStatusCode) + })) + defer ts.Close() + + c := Client{Client: &http.Client{}} + + resp, err := c.post(ts.URL, payload{expectedPayload}) + assert.NoError(err) + assert.Equal(expectedStatusCode, resp.StatusCode) +} + +func TestGet(t *testing.T) { + const ( + expectedStatusCode = 418 + ) + + assert := assert.New(t) + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(expectedStatusCode) + })) + defer ts.Close() + + c := Client{Client: &http.Client{}} + + resp, err := c.get(ts.URL) + assert.NoError(err) + assert.Equal(expectedStatusCode, resp.StatusCode) +} + +func TestFindIDInConfigurationsPayload(t *testing.T) { + const ( + searchedName = "search-for-this-name" + expected = "The-42-id" + ) + assert := assert.New(t) + + c := Client{} + + payload := fmt.Sprintf( + `[{"dataset_id": "1-2-3", "metadata": {"name": "test"}}, {"dataset_id": "The-42-id", "metadata": {"name": "%s"}}]`, + searchedName, + ) + + id, err := c.findIDInConfigurationsPayload( + ioutil.NopCloser(bytes.NewBufferString(payload)), searchedName, + ) + assert.NoError(err) + assert.Equal(expected, id) + + id, err = c.findIDInConfigurationsPayload( + ioutil.NopCloser(bytes.NewBufferString(payload)), "it will not be found", + ) + assert.Equal(errConfigurationNotFound, err) + + id, err = c.findIDInConfigurationsPayload( + ioutil.NopCloser(bytes.NewBufferString("invalid { json")), "", + ) + assert.Error(err) +} + +func TestFindPrimaryUUID(t *testing.T) { + const expectedPrimary = "primary-uuid" + assert := assert.New(t) + + var ( + mockedHost = "127.0.0.1" + mockedPrimary = expectedPrimary + ) + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal("GET", r.Method) + assert.Equal("/v1/state/nodes", r.URL.Path) + w.Write([]byte(fmt.Sprintf(`[{"host": "%s", "uuid": "%s"}]`, mockedHost, mockedPrimary))) + })) + + host, port, err := getHostAndPortFromTestServer(ts) + assert.NoError(err) + + c := newFlockerTestClient(host, port) + assert.NoError(err) + + mockedPrimary = expectedPrimary + primary, err := c.GetPrimaryUUID() + assert.NoError(err) + assert.Equal(expectedPrimary, primary) + + c.clientIP = "not.found" + _, err = c.GetPrimaryUUID() + assert.Equal(errStateNotFound, err) +} + +func TestGetURL(t *testing.T) { + const ( + expectedHost = "host" + expectedPort = 42 + ) + + assert := assert.New(t) + + c := newFlockerTestClient(expectedHost, expectedPort) + var expectedURL = fmt.Sprintf("%s://%s:%d/v1/test", c.schema, expectedHost, expectedPort) + + url := c.getURL("test") + assert.Equal(expectedURL, url) +} + +func getHostAndPortFromTestServer(ts *httptest.Server) (string, int, error) { + tsURL, err := url.Parse(ts.URL) + if err != nil { + return "", 0, err + } + + hostSplits := strings.Split(tsURL.Host, ":") + + port, err := strconv.Atoi(hostSplits[1]) + if err != nil { + return "", 0, nil + } + return hostSplits[0], port, nil +} + +func getVolumeConfig(host string, port int) volume.VolumeConfig { + return volume.VolumeConfig{ + OtherAttributes: map[string]string{ + "CONTROL_SERVICE_HOST": host, + "CONTROL_SERVICE_PORT": strconv.Itoa(port), + }, + } +} + +func TestHappyPathCreateDatasetFromNonExistent(t *testing.T) { + const ( + expectedDatasetName = "dir" + expectedPrimary = "A-B-C-D" + expectedDatasetID = "datasetID" + ) + expectedPath := fmt.Sprintf("/flocker/%s", expectedDatasetID) + + assert := assert.New(t) + var ( + numCalls int + err error + ) + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + numCalls++ + switch numCalls { + case 1: + assert.Equal("GET", r.Method) + assert.Equal("/v1/state/nodes", r.URL.Path) + w.Write([]byte(fmt.Sprintf(`[{"host": "127.0.0.1", "uuid": "%s"}]`, expectedPrimary))) + case 2: + assert.Equal("POST", r.Method) + assert.Equal("/v1/configuration/datasets", r.URL.Path) + + var c configurationPayload + err := json.NewDecoder(r.Body).Decode(&c) + assert.NoError(err) + assert.Equal(expectedPrimary, c.Primary) + assert.Equal(defaultVolumeSize, c.MaximumSize) + assert.Equal(expectedDatasetName, c.Metadata.Name) + + w.Write([]byte(fmt.Sprintf(`{"dataset_id": "%s"}`, expectedDatasetID))) + case 3: + assert.Equal("GET", r.Method) + assert.Equal("/v1/state/datasets", r.URL.Path) + w.Write([]byte(`[]`)) + case 4: + assert.Equal("GET", r.Method) + assert.Equal("/v1/state/datasets", r.URL.Path) + w.Write([]byte(fmt.Sprintf(`[{"dataset_id": "%s", "path": "/flocker/%s"}]`, expectedDatasetID, expectedDatasetID))) + } + })) + + host, port, err := getHostAndPortFromTestServer(ts) + assert.NoError(err) + + c := newFlockerTestClient(host, port) + assert.NoError(err) + + tickerWaitingForVolume = 1 * time.Millisecond // TODO: this is overriding globally + + s, err := c.CreateDataset(expectedDatasetName) + assert.NoError(err) + assert.Equal(expectedPath, s.Path) +} + +func TestCreateDatasetThatAlreadyExists(t *testing.T) { + const ( + datasetName = "dir" + expectedPrimary = "A-B-C-D" + ) + + assert := assert.New(t) + var numCalls int + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + numCalls++ + switch numCalls { + case 1: + assert.Equal("GET", r.Method) + assert.Equal("/v1/state/nodes", r.URL.Path) + w.Write([]byte(fmt.Sprintf(`[{"host": "127.0.0.1", "uuid": "%s"}]`, expectedPrimary))) + case 2: + assert.Equal("POST", r.Method) + assert.Equal("/v1/configuration/datasets", r.URL.Path) + w.WriteHeader(http.StatusConflict) + } + })) + + host, port, err := getHostAndPortFromTestServer(ts) + assert.NoError(err) + + c := newFlockerTestClient(host, port) + assert.NoError(err) + + _, err = c.CreateDataset(datasetName) + assert.Equal(errVolumeAlreadyExists, err) +} + +func TestUpdatePrimaryForDataset(t *testing.T) { + const ( + dir = "dir" + expectedPrimary = "the-new-primary" + expectedDatasetID = "datasetID" + ) + expectedURL := fmt.Sprintf("/v1/configuration/datasets/%s", expectedDatasetID) + + assert := assert.New(t) + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal("POST", r.Method) + assert.Equal(expectedURL, r.URL.Path) + + var c configurationPayload + err := json.NewDecoder(r.Body).Decode(&c) + assert.NoError(err) + + assert.Equal(expectedPrimary, c.Primary) + + w.Write([]byte(fmt.Sprintf(`{"dataset_id": "%s", "path": "just-to-double-check"}`, expectedDatasetID))) + })) + + host, port, err := getHostAndPortFromTestServer(ts) + assert.NoError(err) + + c := newFlockerTestClient(host, port) + assert.NoError(err) + + s, err := c.UpdatePrimaryForDataset(expectedPrimary, expectedDatasetID) + assert.NoError(err) + assert.Equal(expectedDatasetID, s.DatasetID) + assert.NotEqual("", s.Path) +} + +func TestInterfaceIsImplemented(t *testing.T) { + assert.Implements(t, (*Clientable)(nil), Client{}) +} + +func newFlockerTestClient(host string, port int) *Client { + return &Client{ + Client: &http.Client{}, + host: host, + port: port, + version: "v1", + schema: "http", + maximumSize: defaultVolumeSize, + clientIP: "127.0.0.1", + } +} diff --git a/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/doc.go b/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/doc.go new file mode 100644 index 000000000000..f3cd05b01962 --- /dev/null +++ b/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/doc.go @@ -0,0 +1,2 @@ +// flocker package allows you to easily interact with a Flocker Control Service. +package flocker diff --git a/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/util.go b/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/util.go new file mode 100644 index 000000000000..8322ea8cd788 --- /dev/null +++ b/Godeps/_workspace/src/github.com/ClusterHQ/flocker-go/util.go @@ -0,0 +1,34 @@ +package flocker + +import ( + "crypto/tls" + "crypto/x509" + "io/ioutil" + "net/http" +) + +// newTLSClient returns a new TLS http client +func newTLSClient(caCertPath, keyPath, certPath string) (*http.Client, error) { + // Client certificate + cert, err := tls.LoadX509KeyPair(certPath, keyPath) + if err != nil { + return nil, err + } + + // CA certificate + caCert, err := ioutil.ReadFile(caCertPath) + if err != nil { + return nil, err + } + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + + tlsConfig := &tls.Config{ + Certificates: []tls.Certificate{cert}, + RootCAs: caCertPool, + } + tlsConfig.BuildNameToCertificate() + transport := &http.Transport{TLSClientConfig: tlsConfig} + + return &http.Client{Transport: transport}, nil +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/gcloud-golang/compute/metadata/metadata.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/gcloud-golang/compute/metadata/metadata.go deleted file mode 100644 index b007cde63665..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/gcloud-golang/compute/metadata/metadata.go +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// 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 metadata provides access to Google Compute Engine (GCE) -// metadata and API service accounts. -// -// This package is a wrapper around the GCE metadata service, -// as documented at https://developers.google.com/compute/docs/metadata. -package metadata - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net" - "net/http" - "os" - "strings" - "sync" - "time" - - "google.golang.org/cloud/internal" -) - -type cachedValue struct { - k string - trim bool - mu sync.Mutex - v string -} - -var ( - projID = &cachedValue{k: "project/project-id", trim: true} - projNum = &cachedValue{k: "project/numeric-project-id", trim: true} - instID = &cachedValue{k: "instance/id", trim: true} -) - -var metaClient = &http.Client{ - Transport: &internal.Transport{ - Base: &http.Transport{ - Dial: (&net.Dialer{ - Timeout: 750 * time.Millisecond, - KeepAlive: 30 * time.Second, - }).Dial, - ResponseHeaderTimeout: 750 * time.Millisecond, - }, - }, -} - -// NotDefinedError is returned when requested metadata is not defined. -// -// The underlying string is the suffix after "/computeMetadata/v1/". -// -// This error is not returned if the value is defined to be the empty -// string. -type NotDefinedError string - -func (suffix NotDefinedError) Error() string { - return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix)) -} - -// Get returns a value from the metadata service. -// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". -// -// If the GCE_METADATA_HOST environment variable is not defined, a default of -// 169.254.169.254 will be used instead. -// -// If the requested metadata is not defined, the returned error will -// be of type NotDefinedError. -func Get(suffix string) (string, error) { - // Using a fixed IP makes it very difficult to spoof the metadata service in - // a container, which is an important use-case for local testing of cloud - // deployments. To enable spoofing of the metadata service, the environment - // variable GCE_METADATA_HOST is first inspected to decide where metadata - // requests shall go. - host := os.Getenv("GCE_METADATA_HOST") - if host == "" { - // Using 169.254.169.254 instead of "metadata" here because Go - // binaries built with the "netgo" tag and without cgo won't - // know the search suffix for "metadata" is - // ".google.internal", and this IP address is documented as - // being stable anyway. - host = "169.254.169.254" - } - url := "http://" + host + "/computeMetadata/v1/" + suffix - req, _ := http.NewRequest("GET", url, nil) - req.Header.Set("Metadata-Flavor", "Google") - res, err := metaClient.Do(req) - if err != nil { - return "", err - } - defer res.Body.Close() - if res.StatusCode == http.StatusNotFound { - return "", NotDefinedError(suffix) - } - if res.StatusCode != 200 { - return "", fmt.Errorf("status code %d trying to fetch %s", res.StatusCode, url) - } - all, err := ioutil.ReadAll(res.Body) - if err != nil { - return "", err - } - return string(all), nil -} - -func getTrimmed(suffix string) (s string, err error) { - s, err = Get(suffix) - s = strings.TrimSpace(s) - return -} - -func (c *cachedValue) get() (v string, err error) { - defer c.mu.Unlock() - c.mu.Lock() - if c.v != "" { - return c.v, nil - } - if c.trim { - v, err = getTrimmed(c.k) - } else { - v, err = Get(c.k) - } - if err == nil { - c.v = v - } - return -} - -var onGCE struct { - sync.Mutex - set bool - v bool -} - -// OnGCE reports whether this process is running on Google Compute Engine. -func OnGCE() bool { - defer onGCE.Unlock() - onGCE.Lock() - if onGCE.set { - return onGCE.v - } - onGCE.set = true - - // We use the DNS name of the metadata service here instead of the IP address - // because we expect that to fail faster in the not-on-GCE case. - res, err := metaClient.Get("http://metadata.google.internal") - if err != nil { - return false - } - onGCE.v = res.Header.Get("Metadata-Flavor") == "Google" - return onGCE.v -} - -// ProjectID returns the current instance's project ID string. -func ProjectID() (string, error) { return projID.get() } - -// NumericProjectID returns the current instance's numeric project ID. -func NumericProjectID() (string, error) { return projNum.get() } - -// InternalIP returns the instance's primary internal IP address. -func InternalIP() (string, error) { - return getTrimmed("instance/network-interfaces/0/ip") -} - -// ExternalIP returns the instance's primary external (public) IP address. -func ExternalIP() (string, error) { - return getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip") -} - -// Hostname returns the instance's hostname. This will be of the form -// ".c..internal". -func Hostname() (string, error) { - return getTrimmed("instance/hostname") -} - -// InstanceTags returns the list of user-defined instance tags, -// assigned when initially creating a GCE instance. -func InstanceTags() ([]string, error) { - var s []string - j, err := Get("instance/tags") - if err != nil { - return nil, err - } - if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil { - return nil, err - } - return s, nil -} - -// InstanceID returns the current VM's numeric instance ID. -func InstanceID() (string, error) { - return instID.get() -} - -// InstanceName returns the current VM's instance ID string. -func InstanceName() (string, error) { - host, err := Hostname() - if err != nil { - return "", err - } - return strings.Split(host, ".")[0], nil -} - -// Zone returns the current VM's zone, such as "us-central1-b". -func Zone() (string, error) { - zone, err := getTrimmed("instance/zone") - // zone is of the form "projects//zones/". - if err != nil { - return "", err - } - return zone[strings.LastIndex(zone, "/")+1:], nil -} - -// InstanceAttributes returns the list of user-defined attributes, -// assigned when initially creating a GCE VM instance. The value of an -// attribute can be obtained with InstanceAttributeValue. -func InstanceAttributes() ([]string, error) { return lines("instance/attributes/") } - -// ProjectAttributes returns the list of user-defined attributes -// applying to the project as a whole, not just this VM. The value of -// an attribute can be obtained with ProjectAttributeValue. -func ProjectAttributes() ([]string, error) { return lines("project/attributes/") } - -func lines(suffix string) ([]string, error) { - j, err := Get(suffix) - if err != nil { - return nil, err - } - s := strings.Split(strings.TrimSpace(j), "\n") - for i := range s { - s[i] = strings.TrimSpace(s[i]) - } - return s, nil -} - -// InstanceAttributeValue returns the value of the provided VM -// instance attribute. -// -// If the requested attribute is not defined, the returned error will -// be of type NotDefinedError. -// -// InstanceAttributeValue may return ("", nil) if the attribute was -// defined to be the empty string. -func InstanceAttributeValue(attr string) (string, error) { - return Get("instance/attributes/" + attr) -} - -// ProjectAttributeValue returns the value of the provided -// project attribute. -// -// If the requested attribute is not defined, the returned error will -// be of type NotDefinedError. -// -// ProjectAttributeValue may return ("", nil) if the attribute was -// defined to be the empty string. -func ProjectAttributeValue(attr string) (string, error) { - return Get("project/attributes/" + attr) -} - -// Scopes returns the service account scopes for the given account. -// The account may be empty or the string "default" to use the instance's -// main account. -func Scopes(serviceAccount string) ([]string, error) { - if serviceAccount == "" { - serviceAccount = "default" - } - return lines("instance/service-accounts/" + serviceAccount + "/scopes") -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount/safe_format_and_mount_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount/safe_format_and_mount_test.go deleted file mode 100644 index 455e08f9e1b2..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount/safe_format_and_mount_test.go +++ /dev/null @@ -1,172 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 mount - -import ( - "fmt" - "testing" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/util/exec" -) - -type ErrorMounter struct { - *FakeMounter - errIndex int - err []error -} - -func (mounter *ErrorMounter) Mount(source string, target string, fstype string, options []string) error { - i := mounter.errIndex - mounter.errIndex++ - if mounter.err != nil && mounter.err[i] != nil { - return mounter.err[i] - } - return mounter.FakeMounter.Mount(source, target, fstype, options) -} - -type ExecArgs struct { - command string - args []string - output string - err error -} - -func TestSafeFormatAndMount(t *testing.T) { - tests := []struct { - fstype string - mountOptions []string - execScripts []ExecArgs - mountErrs []error - expectedError error - }{ - { // Test a read only mount - fstype: "ext4", - mountOptions: []string{"ro"}, - }, - { // Test a normal mount - fstype: "ext4", - }, - - { // Test that 'file' is called and fails - fstype: "ext4", - mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'")}, - execScripts: []ExecArgs{ - {"file", []string{"-L", "--special-files", "/dev/foo"}, "ext4 filesystem", nil}, - }, - expectedError: fmt.Errorf("unknown filesystem type '(null)'"), - }, - { // Test that 'file' is called and confirms unformatted disk, format fails - fstype: "ext4", - mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'")}, - execScripts: []ExecArgs{ - {"file", []string{"-L", "--special-files", "/dev/foo"}, "data", nil}, - {"mkfs.ext4", []string{"-E", "lazy_itable_init=0,lazy_journal_init=0", "-F", "/dev/foo"}, "", fmt.Errorf("formatting failed")}, - }, - expectedError: fmt.Errorf("formatting failed"), - }, - { // Test that 'file' is called and confirms unformatted disk, format passes, second mount fails - fstype: "ext4", - mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), fmt.Errorf("Still cannot mount")}, - execScripts: []ExecArgs{ - {"file", []string{"-L", "--special-files", "/dev/foo"}, "data", nil}, - {"mkfs.ext4", []string{"-E", "lazy_itable_init=0,lazy_journal_init=0", "-F", "/dev/foo"}, "", nil}, - }, - expectedError: fmt.Errorf("Still cannot mount"), - }, - { // Test that 'file' is called and confirms unformatted disk, format passes, second mount passes - fstype: "ext4", - mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), nil}, - execScripts: []ExecArgs{ - {"file", []string{"-L", "--special-files", "/dev/foo"}, "data", nil}, - {"mkfs.ext4", []string{"-E", "lazy_itable_init=0,lazy_journal_init=0", "-F", "/dev/foo"}, "", nil}, - }, - expectedError: nil, - }, - { // Test that 'file' is called and confirms unformatted disk, format passes, second mount passes with ext3 - fstype: "ext3", - mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), nil}, - execScripts: []ExecArgs{ - {"file", []string{"-L", "--special-files", "/dev/foo"}, "data", nil}, - {"mkfs.ext3", []string{"-E", "lazy_itable_init=0,lazy_journal_init=0", "-F", "/dev/foo"}, "", nil}, - }, - expectedError: nil, - }, - } - - for _, test := range tests { - commandScripts := []exec.FakeCommandAction{} - for _, expected := range test.execScripts { - ecmd := expected.command - eargs := expected.args - output := expected.output - err := expected.err - commandScript := func(cmd string, args ...string) exec.Cmd { - if cmd != ecmd { - t.Errorf("Unexpected command %s. Expecting %s", cmd, ecmd) - } - - for j := range args { - if args[j] != eargs[j] { - t.Errorf("Unexpected args %v. Expecting %v", args, eargs) - } - } - fake := exec.FakeCmd{ - CombinedOutputScript: []exec.FakeCombinedOutputAction{ - func() ([]byte, error) { return []byte(output), err }, - }, - } - return exec.InitFakeCmd(&fake, cmd, args...) - } - commandScripts = append(commandScripts, commandScript) - } - - fake := exec.FakeExec{ - CommandScript: commandScripts, - } - - fakeMounter := ErrorMounter{&FakeMounter{}, 0, test.mountErrs} - mounter := SafeFormatAndMount{ - Interface: &fakeMounter, - Runner: &fake, - } - - device := "/dev/foo" - dest := "/mnt/bar" - err := mounter.Mount(device, dest, test.fstype, test.mountOptions) - if test.expectedError == nil { - if err != nil { - t.Errorf("unexpected non-error: %v", err) - } - - // Check that something was mounted on the directory - isMountPoint, err := fakeMounter.IsMountPoint(dest) - if err != nil || !isMountPoint { - t.Errorf("the directory was not mounted") - } - - //check that the correct device was mounted - mountedDevice, _, err := GetDeviceNameFromMount(fakeMounter.FakeMounter, dest) - if err != nil || mountedDevice != device { - t.Errorf("the correct device was not mounted") - } - } else { - if err == nil || test.expectedError.Error() != err.Error() { - t.Errorf("unexpected error: %v. Expecting %v", err, test.expectedError) - } - } - } -} diff --git a/Godeps/_workspace/src/github.com/appc/cni/libcni/api.go b/Godeps/_workspace/src/github.com/appc/cni/libcni/api.go new file mode 100644 index 000000000000..4ad714a03e99 --- /dev/null +++ b/Godeps/_workspace/src/github.com/appc/cni/libcni/api.go @@ -0,0 +1,65 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 libcni + +import ( + "strings" + + "github.com/appc/cni/pkg/invoke" + "github.com/appc/cni/pkg/types" +) + +type RuntimeConf struct { + ContainerID string + NetNS string + IfName string + Args [][2]string +} + +type NetworkConfig struct { + Network *types.NetConf + Bytes []byte +} + +type CNI interface { + AddNetwork(net *NetworkConfig, rt *RuntimeConf) (*types.Result, error) + DelNetwork(net *NetworkConfig, rt *RuntimeConf) error +} + +type CNIConfig struct { + Path []string +} + +func (c *CNIConfig) AddNetwork(net *NetworkConfig, rt *RuntimeConf) (*types.Result, error) { + pluginPath := invoke.FindInPath(net.Network.Type, c.Path) + return invoke.ExecPluginWithResult(pluginPath, net.Bytes, c.args("ADD", rt)) +} + +func (c *CNIConfig) DelNetwork(net *NetworkConfig, rt *RuntimeConf) error { + pluginPath := invoke.FindInPath(net.Network.Type, c.Path) + return invoke.ExecPluginWithoutResult(pluginPath, net.Bytes, c.args("DEL", rt)) +} + +// ===== +func (c *CNIConfig) args(action string, rt *RuntimeConf) *invoke.Args { + return &invoke.Args{ + Command: action, + ContainerID: rt.ContainerID, + NetNS: rt.NetNS, + PluginArgs: rt.Args, + IfName: rt.IfName, + Path: strings.Join(c.Path, ":"), + } +} diff --git a/Godeps/_workspace/src/github.com/appc/cni/libcni/conf.go b/Godeps/_workspace/src/github.com/appc/cni/libcni/conf.go new file mode 100644 index 000000000000..47babeb447f7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/appc/cni/libcni/conf.go @@ -0,0 +1,85 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 libcni + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "sort" +) + +func ConfFromBytes(bytes []byte) (*NetworkConfig, error) { + conf := &NetworkConfig{Bytes: bytes} + if err := json.Unmarshal(bytes, &conf.Network); err != nil { + return nil, fmt.Errorf("error parsing configuration: %s", err) + } + return conf, nil +} + +func ConfFromFile(filename string) (*NetworkConfig, error) { + bytes, err := ioutil.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("error reading %s: %s", filename, err) + } + return ConfFromBytes(bytes) +} + +func ConfFiles(dir string) ([]string, error) { + // In part, adapted from rkt/networking/podenv.go#listFiles + files, err := ioutil.ReadDir(dir) + switch { + case err == nil: // break + case os.IsNotExist(err): + return nil, nil + default: + return nil, err + } + + confFiles := []string{} + for _, f := range files { + if f.IsDir() { + continue + } + if filepath.Ext(f.Name()) == ".conf" { + confFiles = append(confFiles, filepath.Join(dir, f.Name())) + } + } + return confFiles, nil +} + +func LoadConf(dir, name string) (*NetworkConfig, error) { + files, err := ConfFiles(dir) + switch { + case err != nil: + return nil, err + case len(files) == 0: + return nil, fmt.Errorf("no net configurations found") + } + sort.Strings(files) + + for _, confFile := range files { + conf, err := ConfFromFile(confFile) + if err != nil { + return nil, err + } + if conf.Network.Name == name { + return conf, nil + } + } + return nil, fmt.Errorf(`no net configuration with name "%s" in %s`, name, dir) +} diff --git a/Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/args.go b/Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/args.go new file mode 100644 index 000000000000..6f0a813ad370 --- /dev/null +++ b/Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/args.go @@ -0,0 +1,76 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 invoke + +import ( + "os" + "strings" +) + +type CNIArgs interface { + // For use with os/exec; i.e., return nil to inherit the + // environment from this process + AsEnv() []string +} + +type inherited struct{} + +var inheritArgsFromEnv inherited + +func (_ *inherited) AsEnv() []string { + return nil +} + +func ArgsFromEnv() CNIArgs { + return &inheritArgsFromEnv +} + +type Args struct { + Command string + ContainerID string + NetNS string + PluginArgs [][2]string + PluginArgsStr string + IfName string + Path string +} + +func (args *Args) AsEnv() []string { + env := os.Environ() + pluginArgsStr := args.PluginArgsStr + if pluginArgsStr == "" { + pluginArgsStr = stringify(args.PluginArgs) + } + + env = append(env, + "CNI_COMMAND="+args.Command, + "CNI_CONTAINERID="+args.ContainerID, + "CNI_NETNS="+args.NetNS, + "CNI_ARGS="+pluginArgsStr, + "CNI_IFNAME="+args.IfName, + "CNI_PATH="+args.Path) + return env +} + +// taken from rkt/networking/net_plugin.go +func stringify(pluginArgs [][2]string) string { + entries := make([]string, len(pluginArgs)) + + for i, kv := range pluginArgs { + entries[i] = strings.Join(kv[:], "=") + } + + return strings.Join(entries, ";") +} diff --git a/Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/exec.go b/Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/exec.go new file mode 100644 index 000000000000..cf0cff47e93c --- /dev/null +++ b/Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/exec.go @@ -0,0 +1,80 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 invoke + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "os/exec" + "path/filepath" + + "github.com/appc/cni/pkg/types" +) + +func pluginErr(err error, output []byte) error { + if _, ok := err.(*exec.ExitError); ok { + emsg := types.Error{} + if perr := json.Unmarshal(output, &emsg); perr != nil { + return fmt.Errorf("netplugin failed but error parsing its diagnostic message %q: %v", string(output), perr) + } + details := "" + if emsg.Details != "" { + details = fmt.Sprintf("; %v", emsg.Details) + } + return fmt.Errorf("%v%v", emsg.Msg, details) + } + + return err +} + +func ExecPluginWithResult(pluginPath string, netconf []byte, args CNIArgs) (*types.Result, error) { + stdoutBytes, err := execPlugin(pluginPath, netconf, args) + if err != nil { + return nil, err + } + + res := &types.Result{} + err = json.Unmarshal(stdoutBytes, res) + return res, err +} + +func ExecPluginWithoutResult(pluginPath string, netconf []byte, args CNIArgs) error { + _, err := execPlugin(pluginPath, netconf, args) + return err +} + +func execPlugin(pluginPath string, netconf []byte, args CNIArgs) ([]byte, error) { + if pluginPath == "" { + return nil, fmt.Errorf("could not find %q plugin", filepath.Base(pluginPath)) + } + + stdout := &bytes.Buffer{} + + c := exec.Cmd{ + Env: args.AsEnv(), + Path: pluginPath, + Args: []string{pluginPath}, + Stdin: bytes.NewBuffer(netconf), + Stdout: stdout, + Stderr: os.Stderr, + } + if err := c.Run(); err != nil { + return nil, pluginErr(err, stdout.Bytes()) + } + + return stdout.Bytes(), nil +} diff --git a/Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/find.go b/Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/find.go new file mode 100644 index 000000000000..dfad12bc64f7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/appc/cni/pkg/invoke/find.go @@ -0,0 +1,37 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 invoke + +import ( + "os" + "path/filepath" + "strings" +) + +func FindInPath(plugin string, path []string) string { + for _, p := range path { + fullname := filepath.Join(p, plugin) + if fi, err := os.Stat(fullname); err == nil && fi.Mode().IsRegular() { + return fullname + } + } + return "" +} + +// Find returns the full path of the plugin by searching in CNI_PATH +func Find(plugin string) string { + paths := strings.Split(os.Getenv("CNI_PATH"), ":") + return FindInPath(plugin, paths) +} diff --git a/Godeps/_workspace/src/github.com/appc/cni/pkg/types/args.go b/Godeps/_workspace/src/github.com/appc/cni/pkg/types/args.go new file mode 100644 index 000000000000..68162435a81a --- /dev/null +++ b/Godeps/_workspace/src/github.com/appc/cni/pkg/types/args.go @@ -0,0 +1,50 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 types + +import ( + "encoding" + "fmt" + "reflect" + "strings" +) + +func LoadArgs(args string, container interface{}) error { + if args == "" { + return nil + } + + containerValue := reflect.ValueOf(container) + + pairs := strings.Split(args, ";") + for _, pair := range pairs { + kv := strings.Split(pair, "=") + if len(kv) != 2 { + return fmt.Errorf("ARGS: invalid pair %q", pair) + } + keyString := kv[0] + valueString := kv[1] + keyField := containerValue.Elem().FieldByName(keyString) + if !keyField.IsValid() { + return fmt.Errorf("ARGS: invalid key %q", keyString) + } + u := keyField.Addr().Interface().(encoding.TextUnmarshaler) + err := u.UnmarshalText([]byte(valueString)) + if err != nil { + return fmt.Errorf("ARGS: error parsing value of pair %q: %v)", pair, err) + } + } + return nil +} diff --git a/Godeps/_workspace/src/github.com/appc/cni/pkg/types/types.go b/Godeps/_workspace/src/github.com/appc/cni/pkg/types/types.go new file mode 100644 index 000000000000..21ba32d61f26 --- /dev/null +++ b/Godeps/_workspace/src/github.com/appc/cni/pkg/types/types.go @@ -0,0 +1,166 @@ +// Copyright 2015 CoreOS, Inc. +// +// 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 types + +import ( + "encoding/json" + "net" + "os" +) + +// like net.IPNet but adds JSON marshalling and unmarshalling +type IPNet net.IPNet + +// ParseCIDR takes a string like "10.2.3.1/24" and +// return IPNet with "10.2.3.1" and /24 mask +func ParseCIDR(s string) (*net.IPNet, error) { + ip, ipn, err := net.ParseCIDR(s) + if err != nil { + return nil, err + } + + ipn.IP = ip + return ipn, nil +} + +func (n IPNet) MarshalJSON() ([]byte, error) { + return json.Marshal((*net.IPNet)(&n).String()) +} + +func (n *IPNet) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + + tmp, err := ParseCIDR(s) + if err != nil { + return err + } + + *n = IPNet(*tmp) + return nil +} + +// NetConf describes a network. +type NetConf struct { + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` + IPAM struct { + Type string `json:"type,omitempty"` + } `json:"ipam,omitempty"` +} + +// Result is what gets returned from the plugin (via stdout) to the caller +type Result struct { + IP4 *IPConfig `json:"ip4,omitempty"` + IP6 *IPConfig `json:"ip6,omitempty"` +} + +func (r *Result) Print() error { + return prettyPrint(r) +} + +// IPConfig contains values necessary to configure an interface +type IPConfig struct { + IP net.IPNet + Gateway net.IP + Routes []Route +} + +type Route struct { + Dst net.IPNet + GW net.IP +} + +type Error struct { + Code uint `json:"code"` + Msg string `json:"msg"` + Details string `json:"details,omitempty"` +} + +func (e *Error) Error() string { + return e.Msg +} + +func (e *Error) Print() error { + return prettyPrint(e) +} + +// net.IPNet is not JSON (un)marshallable so this duality is needed +// for our custom IPNet type + +// JSON (un)marshallable types +type ipConfig struct { + IP IPNet `json:"ip"` + Gateway net.IP `json:"gateway,omitempty"` + Routes []Route `json:"routes,omitempty"` +} + +type route struct { + Dst IPNet `json:"dst"` + GW net.IP `json:"gw,omitempty"` +} + +func (c *IPConfig) MarshalJSON() ([]byte, error) { + ipc := ipConfig{ + IP: IPNet(c.IP), + Gateway: c.Gateway, + Routes: c.Routes, + } + + return json.Marshal(ipc) +} + +func (c *IPConfig) UnmarshalJSON(data []byte) error { + ipc := ipConfig{} + if err := json.Unmarshal(data, &ipc); err != nil { + return err + } + + c.IP = net.IPNet(ipc.IP) + c.Gateway = ipc.Gateway + c.Routes = ipc.Routes + return nil +} + +func (r *Route) UnmarshalJSON(data []byte) error { + rt := route{} + if err := json.Unmarshal(data, &rt); err != nil { + return err + } + + r.Dst = net.IPNet(rt.Dst) + r.GW = rt.GW + return nil +} + +func (r *Route) MarshalJSON() ([]byte, error) { + rt := route{ + Dst: IPNet(r.Dst), + GW: r.GW, + } + + return json.Marshal(rt) +} + +func prettyPrint(obj interface{}) error { + data, err := json.MarshalIndent(obj, "", " ") + if err != nil { + return err + } + _, err = os.Stdout.Write(data) + return err +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr/error.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr/error.go index cf54d89d1ed3..a52743bef1cd 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr/error.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr/error.go @@ -10,23 +10,23 @@ package awserr // // Example: // -// output, err := s3manage.Upload(svc, input, opts) -// if err != nil { -// if awsErr, ok := err.(awserr.Error); ok { -// // Get error details -// log.Println("Error:", err.Code(), err.Message()) +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if awsErr, ok := err.(awserr.Error); ok { +// // Get error details +// log.Println("Error:", err.Code(), err.Message()) // -// Prints out full error message, including original error if there was one. -// log.Println("Error:", err.Error()) +// // Prints out full error message, including original error if there was one. +// log.Println("Error:", err.Error()) // -// // Get original error -// if origErr := err.Err(); origErr != nil { -// // operate on original error. -// } -// } else { -// fmt.Println(err.Error()) -// } -// } +// // Get original error +// if origErr := err.Err(); origErr != nil { +// // operate on original error. +// } +// } else { +// fmt.Println(err.Error()) +// } +// } // type Error interface { // Satisfy the generic error interface. @@ -42,6 +42,17 @@ type Error interface { OrigErr() error } +// New returns an Error object described by the code, message, and origErr. +// +// If origErr satisfies the Error interface it will not be wrapped within a new +// Error object and will instead be returned. +func New(code, message string, origErr error) Error { + if e, ok := origErr.(Error); ok && e != nil { + return e + } + return newBaseError(code, message, origErr) +} + // A RequestFailure is an interface to extract request failure information from // an Error such as the request ID of the failed request returned by a service. // RequestFailures may not always have a requestID value if the request failed @@ -86,3 +97,9 @@ type RequestFailure interface { // to a connection error. RequestID() string } + +// NewRequestFailure returns a new request error wrapper for the given Error +// provided. +func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure { + return newRequestError(err, statusCode, reqID) +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/apierr/error.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr/types.go similarity index 54% rename from Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/apierr/error.go rename to Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr/types.go index c45555a9f000..003a6e8067e4 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/apierr/error.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr/types.go @@ -1,14 +1,28 @@ -// Package apierr represents API error types. -package apierr +package awserr import "fmt" -// A BaseError wraps the code and message which defines an error. It also +// SprintError returns a string of the formatted error code. +// +// Both extra and origErr are optional. If they are included their lines +// will be added, but if they are not included their lines will be ignored. +func SprintError(code, message, extra string, origErr error) string { + msg := fmt.Sprintf("%s: %s", code, message) + if extra != "" { + msg = fmt.Sprintf("%s\n\t%s", msg, extra) + } + if origErr != nil { + msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error()) + } + return msg +} + +// A baseError wraps the code and message which defines an error. It also // can be used to wrap an original error object. // // Should be used as the root for errors satisfying the awserr.Error. Also // for any error which does not fit into a specific error wrapper type. -type BaseError struct { +type baseError struct { // Classification of error code string @@ -20,7 +34,7 @@ type BaseError struct { origErr error } -// New returns an error object for the code, message, and err. +// newBaseError returns an error object for the code, message, and err. // // code is a short no whitespace phrase depicting the classification of // the error that is being created. @@ -28,8 +42,8 @@ type BaseError struct { // message is the free flow string containing detailed information about the error. // // origErr is the error object which will be nested under the new error to be returned. -func New(code, message string, origErr error) *BaseError { - return &BaseError{ +func newBaseError(code, message string, origErr error) *baseError { + return &baseError{ code: code, message: message, origErr: origErr, @@ -41,75 +55,56 @@ func New(code, message string, origErr error) *BaseError { // See ErrorWithExtra for formatting. // // Satisfies the error interface. -func (b *BaseError) Error() string { - return b.ErrorWithExtra("") +func (b baseError) Error() string { + return SprintError(b.code, b.message, "", b.origErr) } // String returns the string representation of the error. // Alias for Error to satisfy the stringer interface. -func (b *BaseError) String() string { +func (b baseError) String() string { return b.Error() } // Code returns the short phrase depicting the classification of the error. -func (b *BaseError) Code() string { +func (b baseError) Code() string { return b.code } // Message returns the error details message. -func (b *BaseError) Message() string { +func (b baseError) Message() string { return b.message } // OrigErr returns the original error if one was set. Nil is returned if no error // was set. -func (b *BaseError) OrigErr() error { +func (b baseError) OrigErr() error { return b.origErr } -// ErrorWithExtra is a helper method to add an extra string to the stratified -// error message. The extra message will be added on the next line below the -// error message like the following: -// -// : -// -// -// If there is a original error the error will be included on a new line. -// -// : -// -// caused by: -func (b *BaseError) ErrorWithExtra(extra string) string { - msg := fmt.Sprintf("%s: %s", b.code, b.message) - if extra != "" { - msg = fmt.Sprintf("%s\n\t%s", msg, extra) - } - if b.origErr != nil { - msg = fmt.Sprintf("%s\ncaused by: %s", msg, b.origErr.Error()) - } - return msg -} +// So that the Error interface type can be included as an anonymous field +// in the requestError struct and not conflict with the error.Error() method. +type awsError Error -// A RequestError wraps a request or service error. +// A requestError wraps a request or service error. // -// Composed of BaseError for code, message, and original error. -type RequestError struct { - *BaseError +// Composed of baseError for code, message, and original error. +type requestError struct { + awsError statusCode int requestID string } -// NewRequestError returns a wrapped error with additional information for request +// newRequestError returns a wrapped error with additional information for request // status code, and service requestID. // // Should be used to wrap all request which involve service requests. Even if // the request failed without a service response, but had an HTTP status code // that may be meaningful. // -// Also wraps original errors via the BaseError. -func NewRequestError(base *BaseError, statusCode int, requestID string) *RequestError { - return &RequestError{ - BaseError: base, +// Also wraps original errors via the baseError. +func newRequestError(err Error, statusCode int, requestID string) *requestError { + return &requestError{ + awsError: err, statusCode: statusCode, requestID: requestID, } @@ -117,23 +112,24 @@ func NewRequestError(base *BaseError, statusCode int, requestID string) *Request // Error returns the string representation of the error. // Satisfies the error interface. -func (r *RequestError) Error() string { - return r.ErrorWithExtra(fmt.Sprintf("status code: %d, request id: [%s]", - r.statusCode, r.requestID)) +func (r requestError) Error() string { + extra := fmt.Sprintf("status code: %d, request id: %s", + r.statusCode, r.requestID) + return SprintError(r.Code(), r.Message(), extra, r.OrigErr()) } // String returns the string representation of the error. // Alias for Error to satisfy the stringer interface. -func (r *RequestError) String() string { +func (r requestError) String() string { return r.Error() } // StatusCode returns the wrapped status code for the error -func (r *RequestError) StatusCode() int { +func (r requestError) StatusCode() int { return r.statusCode } // RequestID returns the wrapped requestID -func (r *RequestError) RequestID() string { +func (r requestError) RequestID() string { return r.requestID } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy.go index 99a11567f598..f91743c6e1d3 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy.go @@ -70,12 +70,20 @@ func rcopy(dst, src reflect.Value, root bool) { } } case reflect.Slice: + if src.IsNil() { + break + } + s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap()) dst.Set(s) for i := 0; i < src.Len(); i++ { rcopy(dst.Index(i), src.Index(i), false) } case reflect.Map: + if src.IsNil() { + break + } + s := reflect.MakeMap(src.Type()) dst.Set(s) for _, k := range src.MapKeys() { diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy_test.go index 4ae04ac1dd2c..4f26241a2b8b 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy_test.go @@ -27,7 +27,7 @@ func ExampleCopy() { awsutil.Copy(&f2, f1) // Print the result - fmt.Println(awsutil.StringValue(f2)) + fmt.Println(awsutil.Prettify(f2)) // Output: // { @@ -80,18 +80,26 @@ func TestCopy(t *testing.T) { func TestCopyIgnoreNilMembers(t *testing.T) { type Foo struct { A *string + B []string + C map[string]string } f := &Foo{} assert.Nil(t, f.A) + assert.Nil(t, f.B) + assert.Nil(t, f.C) var f2 Foo awsutil.Copy(&f2, f) assert.Nil(t, f2.A) + assert.Nil(t, f2.B) + assert.Nil(t, f2.C) fcopy := awsutil.CopyOf(f) f3 := fcopy.(*Foo) assert.Nil(t, f3.A) + assert.Nil(t, f3.B) + assert.Nil(t, f3.C) } func TestCopyPrimitive(t *testing.T) { @@ -183,7 +191,7 @@ func ExampleCopyOf() { var f2 *Foo = v.(*Foo) // Print the result - fmt.Println(awsutil.StringValue(f2)) + fmt.Println(awsutil.Prettify(f2)) // Output: // { diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go index 7ae01efe4278..905d82385ecd 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go @@ -81,6 +81,12 @@ func rValuesAtPath(v interface{}, path string, create bool, caseSensitive bool) value = reflect.Indirect(value) } + if value.Kind() == reflect.Slice || value.Kind() == reflect.Map { + if !create && value.IsNil() { + value = reflect.ValueOf(nil) + } + } + if value.IsValid() { nextvals = append(nextvals, value) } @@ -118,6 +124,12 @@ func rValuesAtPath(v interface{}, path string, create bool, caseSensitive bool) } value = reflect.Indirect(value.Index(i)) + if value.Kind() == reflect.Slice || value.Kind() == reflect.Map { + if !create && value.IsNil() { + value = reflect.ValueOf(nil) + } + } + if value.IsValid() { nextvals = append(nextvals, value) } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value_test.go index 1262cf6bef15..0da6b06fddcf 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value_test.go @@ -16,8 +16,8 @@ type Struct struct { } var data = Struct{ - A: []Struct{Struct{C: "value1"}, Struct{C: "value2"}, Struct{C: "value3"}}, - z: []Struct{Struct{C: "value1"}, Struct{C: "value2"}, Struct{C: "value3"}}, + A: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}}, + z: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}}, B: &Struct{B: &Struct{C: "terminal"}, D: &Struct{C: "terminal2"}}, C: "initial", } @@ -44,6 +44,7 @@ func TestValueAtPathFailure(t *testing.T) { assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "B.B.C.Z")) assert.Equal(t, []interface{}(nil), awsutil.ValuesAtPath(data, "z[-1].C")) assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(nil, "A.B.C")) + assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(Struct{}, "A")) } func TestSetValueAtPathSuccess(t *testing.T) { @@ -62,4 +63,6 @@ func TestSetValueAtPathSuccess(t *testing.T) { var s2 Struct awsutil.SetValueAtAnyPath(&s2, "b.b.c", "test0") assert.Equal(t, "test0", s2.B.B.C) + awsutil.SetValueAtAnyPath(&s2, "A", []Struct{{}}) + assert.Equal(t, []Struct{{}}, s2.A) } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go similarity index 83% rename from Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go rename to Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go index 09673a12ed27..0de3eaa0f639 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go @@ -8,16 +8,16 @@ import ( "strings" ) -// StringValue returns the string representation of a value. -func StringValue(i interface{}) string { +// Prettify returns the string representation of a value. +func Prettify(i interface{}) string { var buf bytes.Buffer - stringValue(reflect.ValueOf(i), 0, &buf) + prettify(reflect.ValueOf(i), 0, &buf) return buf.String() } -// stringValue will recursively walk value v to build a textual +// prettify will recursively walk value v to build a textual // representation of the value. -func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) { +func prettify(v reflect.Value, indent int, buf *bytes.Buffer) { for v.Kind() == reflect.Ptr { v = v.Elem() } @@ -52,7 +52,7 @@ func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) { val := v.FieldByName(n) buf.WriteString(strings.Repeat(" ", indent+2)) buf.WriteString(n + ": ") - stringValue(val, indent+2, buf) + prettify(val, indent+2, buf) if i < len(names)-1 { buf.WriteString(",\n") @@ -68,7 +68,7 @@ func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) { buf.WriteString("[" + nl) for i := 0; i < v.Len(); i++ { buf.WriteString(id2) - stringValue(v.Index(i), indent+2, buf) + prettify(v.Index(i), indent+2, buf) if i < v.Len()-1 { buf.WriteString("," + nl) @@ -82,7 +82,7 @@ func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) { for i, k := range v.MapKeys() { buf.WriteString(strings.Repeat(" ", indent+2)) buf.WriteString(k.String() + ": ") - stringValue(v.MapIndex(k), indent+2, buf) + prettify(v.MapIndex(k), indent+2, buf) if i < v.Len()-1 { buf.WriteString(",\n") diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config.go index bd805f36b80c..a72f702229f9 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config.go @@ -1,172 +1,239 @@ package aws import ( - "io" "net/http" - "os" "time" "github.com/aws/aws-sdk-go/aws/credentials" ) -// DefaultChainCredentials is a Credentials which will find the first available -// credentials Value from the list of Providers. -// -// This should be used in the default case. Once the type of credentials are -// known switching to the specific Credentials will be more efficient. -var DefaultChainCredentials = credentials.NewChainCredentials( - []credentials.Provider{ - &credentials.EnvProvider{}, - &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, - &credentials.EC2RoleProvider{ExpiryWindow: 5 * time.Minute}, - }) - // The default number of retries for a service. The value of -1 indicates that // the service specific retry default will be used. const DefaultRetries = -1 -// DefaultConfig is the default all service configuration will be based off of. -var DefaultConfig = &Config{ - Credentials: DefaultChainCredentials, - Endpoint: "", - Region: os.Getenv("AWS_REGION"), - DisableSSL: false, - ManualSend: false, - HTTPClient: http.DefaultClient, - LogHTTPBody: false, - LogLevel: 0, - Logger: os.Stdout, - MaxRetries: DefaultRetries, - DisableParamValidation: false, - DisableComputeChecksums: false, - S3ForcePathStyle: false, -} - -// A Config provides service configuration +// A Config provides service configuration for service clients. By default, +// all clients will use the {defaults.DefaultConfig} structure. type Config struct { - Credentials *credentials.Credentials - Endpoint string - Region string - DisableSSL bool - ManualSend bool - HTTPClient *http.Client - LogHTTPBody bool - LogLevel uint - Logger io.Writer - MaxRetries int - DisableParamValidation bool - DisableComputeChecksums bool - S3ForcePathStyle bool + // The credentials object to use when signing requests. Defaults to + // {defaults.DefaultChainCredentials}. + Credentials *credentials.Credentials + + // An optional endpoint URL (hostname only or fully qualified URI) + // that overrides the default generated endpoint for a client. Set this + // to `""` to use the default generated endpoint. + // + // @note You must still provide a `Region` value when specifying an + // endpoint for a client. + Endpoint *string + + // The region to send requests to. This parameter is required and must + // be configured globally or on a per-client basis unless otherwise + // noted. A full list of regions is found in the "Regions and Endpoints" + // document. + // + // @see http://docs.aws.amazon.com/general/latest/gr/rande.html + // AWS Regions and Endpoints + Region *string + + // Set this to `true` to disable SSL when sending requests. Defaults + // to `false`. + DisableSSL *bool + + // The HTTP client to use when sending requests. Defaults to + // `http.DefaultClient`. + HTTPClient *http.Client + + // An integer value representing the logging level. The default log level + // is zero (LogOff), which represents no logging. To enable logging set + // to a LogLevel Value. + LogLevel *LogLevelType + + // The logger writer interface to write logging messages to. Defaults to + // standard out. + Logger Logger + + // The maximum number of times that a request will be retried for failures. + // Defaults to -1, which defers the max retry setting to the service specific + // configuration. + MaxRetries *int + + // Disables semantic parameter validation, which validates input for missing + // required fields and/or other semantic request input errors. + DisableParamValidation *bool + + // Disables the computation of request and response checksums, e.g., + // CRC32 checksums in Amazon DynamoDB. + DisableComputeChecksums *bool + + // Set this to `true` to force the request to use path-style addressing, + // i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client will + // use virtual hosted bucket addressing when possible + // (`http://BUCKET.s3.amazonaws.com/KEY`). + // + // @note This configuration option is specific to the Amazon S3 service. + // @see http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html + // Amazon S3: Virtual Hosting of Buckets + S3ForcePathStyle *bool + + SleepDelay func(time.Duration) } -// Copy will return a shallow copy of the Config object. -func (c Config) Copy() Config { - dst := Config{} - dst.Credentials = c.Credentials - dst.Endpoint = c.Endpoint - dst.Region = c.Region - dst.DisableSSL = c.DisableSSL - dst.ManualSend = c.ManualSend - dst.HTTPClient = c.HTTPClient - dst.LogLevel = c.LogLevel - dst.Logger = c.Logger - dst.MaxRetries = c.MaxRetries - dst.DisableParamValidation = c.DisableParamValidation - dst.DisableComputeChecksums = c.DisableComputeChecksums - dst.S3ForcePathStyle = c.S3ForcePathStyle - - return dst -} - -// Merge merges the newcfg attribute values into this Config. Each attribute -// will be merged into this config if the newcfg attribute's value is non-zero. -// Due to this, newcfg attributes with zero values cannot be merged in. For -// example bool attributes cannot be cleared using Merge, and must be explicitly -// set on the Config structure. -func (c Config) Merge(newcfg *Config) *Config { - if newcfg == nil { +// NewConfig returns a new Config pointer that can be chained with builder methods to +// set multiple configuration values inline without using pointers. +// +// svc := s3.New(aws.NewConfig().WithRegion("us-west-2").WithMaxRetries(10)) +// +func NewConfig() *Config { + return &Config{} +} + +// WithCredentials sets a config Credentials value returning a Config pointer +// for chaining. +func (c *Config) WithCredentials(creds *credentials.Credentials) *Config { + c.Credentials = creds + return c +} + +// WithEndpoint sets a config Endpoint value returning a Config pointer for +// chaining. +func (c *Config) WithEndpoint(endpoint string) *Config { + c.Endpoint = &endpoint + return c +} + +// WithRegion sets a config Region value returning a Config pointer for +// chaining. +func (c *Config) WithRegion(region string) *Config { + c.Region = ®ion + return c +} + +// WithDisableSSL sets a config DisableSSL value returning a Config pointer +// for chaining. +func (c *Config) WithDisableSSL(disable bool) *Config { + c.DisableSSL = &disable + return c +} + +// WithHTTPClient sets a config HTTPClient value returning a Config pointer +// for chaining. +func (c *Config) WithHTTPClient(client *http.Client) *Config { + c.HTTPClient = client + return c +} + +// WithMaxRetries sets a config MaxRetries value returning a Config pointer +// for chaining. +func (c *Config) WithMaxRetries(max int) *Config { + c.MaxRetries = &max + return c +} + +// WithDisableParamValidation sets a config DisableParamValidation value +// returning a Config pointer for chaining. +func (c *Config) WithDisableParamValidation(disable bool) *Config { + c.DisableParamValidation = &disable + return c +} + +// WithDisableComputeChecksums sets a config DisableComputeChecksums value +// returning a Config pointer for chaining. +func (c *Config) WithDisableComputeChecksums(disable bool) *Config { + c.DisableComputeChecksums = &disable + return c +} + +// WithLogLevel sets a config LogLevel value returning a Config pointer for +// chaining. +func (c *Config) WithLogLevel(level LogLevelType) *Config { + c.LogLevel = &level + return c +} + +// WithLogger sets a config Logger value returning a Config pointer for +// chaining. +func (c *Config) WithLogger(logger Logger) *Config { + c.Logger = logger + return c +} + +// WithS3ForcePathStyle sets a config S3ForcePathStyle value returning a Config +// pointer for chaining. +func (c *Config) WithS3ForcePathStyle(force bool) *Config { + c.S3ForcePathStyle = &force + return c +} + +// WithSleepDelay overrides the function used to sleep while waiting for the +// next retry. Defaults to time.Sleep. +func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config { + c.SleepDelay = fn + return c +} + +// Merge returns a new Config with the other Config's attribute values merged into +// this Config. If the other Config's attribute is nil it will not be merged into +// the new Config to be returned. +func (c Config) Merge(other *Config) *Config { + if other == nil { return &c } - cfg := Config{} + dst := c - if newcfg != nil && newcfg.Credentials != nil { - cfg.Credentials = newcfg.Credentials - } else { - cfg.Credentials = c.Credentials + if other.Credentials != nil { + dst.Credentials = other.Credentials } - if newcfg != nil && newcfg.Endpoint != "" { - cfg.Endpoint = newcfg.Endpoint - } else { - cfg.Endpoint = c.Endpoint + if other.Endpoint != nil { + dst.Endpoint = other.Endpoint } - if newcfg != nil && newcfg.Region != "" { - cfg.Region = newcfg.Region - } else { - cfg.Region = c.Region + if other.Region != nil { + dst.Region = other.Region } - if newcfg != nil && newcfg.DisableSSL { - cfg.DisableSSL = newcfg.DisableSSL - } else { - cfg.DisableSSL = c.DisableSSL + if other.DisableSSL != nil { + dst.DisableSSL = other.DisableSSL } - if newcfg != nil && newcfg.ManualSend { - cfg.ManualSend = newcfg.ManualSend - } else { - cfg.ManualSend = c.ManualSend + if other.HTTPClient != nil { + dst.HTTPClient = other.HTTPClient } - if newcfg != nil && newcfg.HTTPClient != nil { - cfg.HTTPClient = newcfg.HTTPClient - } else { - cfg.HTTPClient = c.HTTPClient + if other.LogLevel != nil { + dst.LogLevel = other.LogLevel } - if newcfg != nil && newcfg.LogHTTPBody { - cfg.LogHTTPBody = newcfg.LogHTTPBody - } else { - cfg.LogHTTPBody = c.LogHTTPBody + if other.Logger != nil { + dst.Logger = other.Logger } - if newcfg != nil && newcfg.LogLevel != 0 { - cfg.LogLevel = newcfg.LogLevel - } else { - cfg.LogLevel = c.LogLevel + if other.MaxRetries != nil { + dst.MaxRetries = other.MaxRetries } - if newcfg != nil && newcfg.Logger != nil { - cfg.Logger = newcfg.Logger - } else { - cfg.Logger = c.Logger + if other.DisableParamValidation != nil { + dst.DisableParamValidation = other.DisableParamValidation } - if newcfg != nil && newcfg.MaxRetries != DefaultRetries { - cfg.MaxRetries = newcfg.MaxRetries - } else { - cfg.MaxRetries = c.MaxRetries + if other.DisableComputeChecksums != nil { + dst.DisableComputeChecksums = other.DisableComputeChecksums } - if newcfg != nil && newcfg.DisableParamValidation { - cfg.DisableParamValidation = newcfg.DisableParamValidation - } else { - cfg.DisableParamValidation = c.DisableParamValidation + if other.S3ForcePathStyle != nil { + dst.S3ForcePathStyle = other.S3ForcePathStyle } - if newcfg != nil && newcfg.DisableComputeChecksums { - cfg.DisableComputeChecksums = newcfg.DisableComputeChecksums - } else { - cfg.DisableComputeChecksums = c.DisableComputeChecksums + if other.SleepDelay != nil { + dst.SleepDelay = other.SleepDelay } - if newcfg != nil && newcfg.S3ForcePathStyle { - cfg.S3ForcePathStyle = newcfg.S3ForcePathStyle - } else { - cfg.S3ForcePathStyle = c.S3ForcePathStyle - } + return &dst +} - return &cfg +// Copy will return a shallow copy of the Config object. +func (c Config) Copy() *Config { + dst := c + return &dst } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config_test.go new file mode 100644 index 000000000000..c4320ca1ede4 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config_test.go @@ -0,0 +1,80 @@ +package aws + +import ( + "net/http" + "reflect" + "testing" + + "github.com/aws/aws-sdk-go/aws/credentials" +) + +var testCredentials = credentials.NewStaticCredentials("AKID", "SECRET", "SESSION") + +var copyTestConfig = Config{ + Credentials: testCredentials, + Endpoint: String("CopyTestEndpoint"), + Region: String("COPY_TEST_AWS_REGION"), + DisableSSL: Bool(true), + HTTPClient: http.DefaultClient, + LogLevel: LogLevel(LogDebug), + Logger: NewDefaultLogger(), + MaxRetries: Int(DefaultRetries), + DisableParamValidation: Bool(true), + DisableComputeChecksums: Bool(true), + S3ForcePathStyle: Bool(true), +} + +func TestCopy(t *testing.T) { + want := copyTestConfig + got := copyTestConfig.Copy() + if !reflect.DeepEqual(*got, want) { + t.Errorf("Copy() = %+v", got) + t.Errorf(" want %+v", want) + } +} + +func TestCopyReturnsNewInstance(t *testing.T) { + want := copyTestConfig + got := copyTestConfig.Copy() + if got == &want { + t.Errorf("Copy() = %p; want different instance as source %p", got, &want) + } +} + +var mergeTestZeroValueConfig = Config{} + +var mergeTestConfig = Config{ + Credentials: testCredentials, + Endpoint: String("MergeTestEndpoint"), + Region: String("MERGE_TEST_AWS_REGION"), + DisableSSL: Bool(true), + HTTPClient: http.DefaultClient, + LogLevel: LogLevel(LogDebug), + Logger: NewDefaultLogger(), + MaxRetries: Int(10), + DisableParamValidation: Bool(true), + DisableComputeChecksums: Bool(true), + S3ForcePathStyle: Bool(true), +} + +var mergeTests = []struct { + cfg *Config + in *Config + want *Config +}{ + {&Config{}, nil, &Config{}}, + {&Config{}, &mergeTestZeroValueConfig, &Config{}}, + {&Config{}, &mergeTestConfig, &mergeTestConfig}, +} + +func TestMerge(t *testing.T) { + for i, tt := range mergeTests { + got := tt.cfg.Merge(tt.in) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Config %d %+v", i, tt.cfg) + t.Errorf(" Merge(%+v)", tt.in) + t.Errorf(" got %+v", got) + t.Errorf(" want %+v", tt.want) + } + } +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types.go new file mode 100644 index 000000000000..d6a7b08dffe4 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types.go @@ -0,0 +1,357 @@ +package aws + +import "time" + +// String returns a pointer to of the string value passed in. +func String(v string) *string { + return &v +} + +// StringValue returns the value of the string pointer passed in or +// "" if the pointer is nil. +func StringValue(v *string) string { + if v != nil { + return *v + } + return "" +} + +// StringSlice converts a slice of string values into a slice of +// string pointers +func StringSlice(src []string) []*string { + dst := make([]*string, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// StringValueSlice converts a slice of string pointers into a slice of +// string values +func StringValueSlice(src []*string) []string { + dst := make([]string, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// StringMap converts a string map of string values into a string +// map of string pointers +func StringMap(src map[string]string) map[string]*string { + dst := make(map[string]*string) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// StringValueMap converts a string map of string pointers into a string +// map of string values +func StringValueMap(src map[string]*string) map[string]string { + dst := make(map[string]string) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Bool returns a pointer to of the bool value passed in. +func Bool(v bool) *bool { + return &v +} + +// BoolValue returns the value of the bool pointer passed in or +// false if the pointer is nil. +func BoolValue(v *bool) bool { + if v != nil { + return *v + } + return false +} + +// BoolSlice converts a slice of bool values into a slice of +// bool pointers +func BoolSlice(src []bool) []*bool { + dst := make([]*bool, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// BoolValueSlice converts a slice of bool pointers into a slice of +// bool values +func BoolValueSlice(src []*bool) []bool { + dst := make([]bool, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// BoolMap converts a string map of bool values into a string +// map of bool pointers +func BoolMap(src map[string]bool) map[string]*bool { + dst := make(map[string]*bool) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// BoolValueMap converts a string map of bool pointers into a string +// map of bool values +func BoolValueMap(src map[string]*bool) map[string]bool { + dst := make(map[string]bool) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int returns a pointer to of the int value passed in. +func Int(v int) *int { + return &v +} + +// IntValue returns the value of the int pointer passed in or +// 0 if the pointer is nil. +func IntValue(v *int) int { + if v != nil { + return *v + } + return 0 +} + +// IntSlice converts a slice of int values into a slice of +// int pointers +func IntSlice(src []int) []*int { + dst := make([]*int, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// IntValueSlice converts a slice of int pointers into a slice of +// int values +func IntValueSlice(src []*int) []int { + dst := make([]int, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// IntMap converts a string map of int values into a string +// map of int pointers +func IntMap(src map[string]int) map[string]*int { + dst := make(map[string]*int) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// IntValueMap converts a string map of int pointers into a string +// map of int values +func IntValueMap(src map[string]*int) map[string]int { + dst := make(map[string]int) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int64 returns a pointer to of the int64 value passed in. +func Int64(v int64) *int64 { + return &v +} + +// Int64Value returns the value of the int64 pointer passed in or +// 0 if the pointer is nil. +func Int64Value(v *int64) int64 { + if v != nil { + return *v + } + return 0 +} + +// Int64Slice converts a slice of int64 values into a slice of +// int64 pointers +func Int64Slice(src []int64) []*int64 { + dst := make([]*int64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int64ValueSlice converts a slice of int64 pointers into a slice of +// int64 values +func Int64ValueSlice(src []*int64) []int64 { + dst := make([]int64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Int64Map converts a string map of int64 values into a string +// map of int64 pointers +func Int64Map(src map[string]int64) map[string]*int64 { + dst := make(map[string]*int64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Int64ValueMap converts a string map of int64 pointers into a string +// map of int64 values +func Int64ValueMap(src map[string]*int64) map[string]int64 { + dst := make(map[string]int64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Float64 returns a pointer to of the float64 value passed in. +func Float64(v float64) *float64 { + return &v +} + +// Float64Value returns the value of the float64 pointer passed in or +// 0 if the pointer is nil. +func Float64Value(v *float64) float64 { + if v != nil { + return *v + } + return 0 +} + +// Float64Slice converts a slice of float64 values into a slice of +// float64 pointers +func Float64Slice(src []float64) []*float64 { + dst := make([]*float64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Float64ValueSlice converts a slice of float64 pointers into a slice of +// float64 values +func Float64ValueSlice(src []*float64) []float64 { + dst := make([]float64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Float64Map converts a string map of float64 values into a string +// map of float64 pointers +func Float64Map(src map[string]float64) map[string]*float64 { + dst := make(map[string]*float64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Float64ValueMap converts a string map of float64 pointers into a string +// map of float64 values +func Float64ValueMap(src map[string]*float64) map[string]float64 { + dst := make(map[string]float64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Time returns a pointer to of the time.Time value passed in. +func Time(v time.Time) *time.Time { + return &v +} + +// TimeValue returns the value of the time.Time pointer passed in or +// time.Time{} if the pointer is nil. +func TimeValue(v *time.Time) time.Time { + if v != nil { + return *v + } + return time.Time{} +} + +// TimeSlice converts a slice of time.Time values into a slice of +// time.Time pointers +func TimeSlice(src []time.Time) []*time.Time { + dst := make([]*time.Time, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// TimeValueSlice converts a slice of time.Time pointers into a slice of +// time.Time values +func TimeValueSlice(src []*time.Time) []time.Time { + dst := make([]time.Time, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// TimeMap converts a string map of time.Time values into a string +// map of time.Time pointers +func TimeMap(src map[string]time.Time) map[string]*time.Time { + dst := make(map[string]*time.Time) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// TimeValueMap converts a string map of time.Time pointers into a string +// map of time.Time values +func TimeValueMap(src map[string]*time.Time) map[string]time.Time { + dst := make(map[string]time.Time) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types_test.go new file mode 100644 index 000000000000..df7a3e5d2de5 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/convert_types_test.go @@ -0,0 +1,437 @@ +package aws + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +var testCasesStringSlice = [][]string{ + {"a", "b", "c", "d", "e"}, + {"a", "b", "", "", "e"}, +} + +func TestStringSlice(t *testing.T) { + for idx, in := range testCasesStringSlice { + if in == nil { + continue + } + out := StringSlice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := StringValueSlice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} + +var testCasesStringValueSlice = [][]*string{ + {String("a"), String("b"), nil, String("c")}, +} + +func TestStringValueSlice(t *testing.T) { + for idx, in := range testCasesStringValueSlice { + if in == nil { + continue + } + out := StringValueSlice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + if in[i] == nil { + assert.Empty(t, out[i], "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) + } + } + + out2 := StringSlice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + for i := range out2 { + if in[i] == nil { + assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) + } + } + } +} + +var testCasesStringMap = []map[string]string{ + {"a": "1", "b": "2", "c": "3"}, +} + +func TestStringMap(t *testing.T) { + for idx, in := range testCasesStringMap { + if in == nil { + continue + } + out := StringMap(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := StringValueMap(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} + +var testCasesBoolSlice = [][]bool{ + {true, true, false, false}, +} + +func TestBoolSlice(t *testing.T) { + for idx, in := range testCasesBoolSlice { + if in == nil { + continue + } + out := BoolSlice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := BoolValueSlice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} + +var testCasesBoolValueSlice = [][]*bool{} + +func TestBoolValueSlice(t *testing.T) { + for idx, in := range testCasesBoolValueSlice { + if in == nil { + continue + } + out := BoolValueSlice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + if in[i] == nil { + assert.Empty(t, out[i], "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) + } + } + + out2 := BoolSlice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + for i := range out2 { + if in[i] == nil { + assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) + } + } + } +} + +var testCasesBoolMap = []map[string]bool{ + {"a": true, "b": false, "c": true}, +} + +func TestBoolMap(t *testing.T) { + for idx, in := range testCasesBoolMap { + if in == nil { + continue + } + out := BoolMap(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := BoolValueMap(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} + +var testCasesIntSlice = [][]int{ + {1, 2, 3, 4}, +} + +func TestIntSlice(t *testing.T) { + for idx, in := range testCasesIntSlice { + if in == nil { + continue + } + out := IntSlice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := IntValueSlice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} + +var testCasesIntValueSlice = [][]*int{} + +func TestIntValueSlice(t *testing.T) { + for idx, in := range testCasesIntValueSlice { + if in == nil { + continue + } + out := IntValueSlice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + if in[i] == nil { + assert.Empty(t, out[i], "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) + } + } + + out2 := IntSlice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + for i := range out2 { + if in[i] == nil { + assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) + } + } + } +} + +var testCasesIntMap = []map[string]int{ + {"a": 3, "b": 2, "c": 1}, +} + +func TestIntMap(t *testing.T) { + for idx, in := range testCasesIntMap { + if in == nil { + continue + } + out := IntMap(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := IntValueMap(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} + +var testCasesInt64Slice = [][]int64{ + {1, 2, 3, 4}, +} + +func TestInt64Slice(t *testing.T) { + for idx, in := range testCasesInt64Slice { + if in == nil { + continue + } + out := Int64Slice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := Int64ValueSlice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} + +var testCasesInt64ValueSlice = [][]*int64{} + +func TestInt64ValueSlice(t *testing.T) { + for idx, in := range testCasesInt64ValueSlice { + if in == nil { + continue + } + out := Int64ValueSlice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + if in[i] == nil { + assert.Empty(t, out[i], "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) + } + } + + out2 := Int64Slice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + for i := range out2 { + if in[i] == nil { + assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) + } + } + } +} + +var testCasesInt64Map = []map[string]int64{ + {"a": 3, "b": 2, "c": 1}, +} + +func TestInt64Map(t *testing.T) { + for idx, in := range testCasesInt64Map { + if in == nil { + continue + } + out := Int64Map(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := Int64ValueMap(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} + +var testCasesFloat64Slice = [][]float64{ + {1, 2, 3, 4}, +} + +func TestFloat64Slice(t *testing.T) { + for idx, in := range testCasesFloat64Slice { + if in == nil { + continue + } + out := Float64Slice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := Float64ValueSlice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} + +var testCasesFloat64ValueSlice = [][]*float64{} + +func TestFloat64ValueSlice(t *testing.T) { + for idx, in := range testCasesFloat64ValueSlice { + if in == nil { + continue + } + out := Float64ValueSlice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + if in[i] == nil { + assert.Empty(t, out[i], "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) + } + } + + out2 := Float64Slice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + for i := range out2 { + if in[i] == nil { + assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) + } + } + } +} + +var testCasesFloat64Map = []map[string]float64{ + {"a": 3, "b": 2, "c": 1}, +} + +func TestFloat64Map(t *testing.T) { + for idx, in := range testCasesFloat64Map { + if in == nil { + continue + } + out := Float64Map(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := Float64ValueMap(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} + +var testCasesTimeSlice = [][]time.Time{ + {time.Now(), time.Now().AddDate(100, 0, 0)}, +} + +func TestTimeSlice(t *testing.T) { + for idx, in := range testCasesTimeSlice { + if in == nil { + continue + } + out := TimeSlice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := TimeValueSlice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} + +var testCasesTimeValueSlice = [][]*time.Time{} + +func TestTimeValueSlice(t *testing.T) { + for idx, in := range testCasesTimeValueSlice { + if in == nil { + continue + } + out := TimeValueSlice(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + if in[i] == nil { + assert.Empty(t, out[i], "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx) + } + } + + out2 := TimeSlice(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + for i := range out2 { + if in[i] == nil { + assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx) + } else { + assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx) + } + } + } +} + +var testCasesTimeMap = []map[string]time.Time{ + {"a": time.Now().AddDate(-100, 0, 0), "b": time.Now()}, +} + +func TestTimeMap(t *testing.T) { + for idx, in := range testCasesTimeMap { + if in == nil { + continue + } + out := TimeMap(in) + assert.Len(t, out, len(in), "Unexpected len at idx %d", idx) + for i := range out { + assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx) + } + + out2 := TimeValueMap(out) + assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx) + assert.Equal(t, in, out2, "Unexpected value at idx %d", idx) + } +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handler_functions.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go similarity index 58% rename from Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handler_functions.go rename to Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go index e15ab8291f7d..2fcb391a2880 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handler_functions.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go @@ -1,4 +1,4 @@ -package aws +package corehandlers import ( "bytes" @@ -9,16 +9,12 @@ import ( "net/url" "regexp" "strconv" - "time" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/request" ) -var sleepDelay = func(delay time.Duration) { - time.Sleep(delay) -} - // Interface for matching types which also have a Len method. type lener interface { Len() int @@ -27,7 +23,7 @@ type lener interface { // BuildContentLength builds the content length of a request based on the body, // or will use the HTTPRequest.Header's "Content-Length" if defined. If unable // to determine request body length and no "Content-Length" was specified it will panic. -func BuildContentLength(r *Request) { +var BuildContentLengthHandler = request.NamedHandler{"core.BuildContentLengthHandler", func(r *request.Request) { if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" { length, _ := strconv.ParseInt(slength, 10, 64) r.HTTPRequest.ContentLength = length @@ -41,27 +37,27 @@ func BuildContentLength(r *Request) { case lener: length = int64(body.Len()) case io.Seeker: - r.bodyStart, _ = body.Seek(0, 1) + r.BodyStart, _ = body.Seek(0, 1) end, _ := body.Seek(0, 2) - body.Seek(r.bodyStart, 0) // make sure to seek back to original location - length = end - r.bodyStart + body.Seek(r.BodyStart, 0) // make sure to seek back to original location + length = end - r.BodyStart default: panic("Cannot get length of body, must provide `ContentLength`") } r.HTTPRequest.ContentLength = length r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length)) -} +}} // UserAgentHandler is a request handler for injecting User agent into requests. -func UserAgentHandler(r *Request) { - r.HTTPRequest.Header.Set("User-Agent", SDKName+"/"+SDKVersion) -} +var UserAgentHandler = request.NamedHandler{"core.UserAgentHandler", func(r *request.Request) { + r.HTTPRequest.Header.Set("User-Agent", aws.SDKName+"/"+aws.SDKVersion) +}} -var reStatusCode = regexp.MustCompile(`^(\d+)`) +var reStatusCode = regexp.MustCompile(`^(\d{3})`) // SendHandler is a request handler to send service request using HTTP client. -func SendHandler(r *Request) { +var SendHandler = request.NamedHandler{"core.SendHandler", func(r *request.Request) { var err error r.HTTPResponse, err = r.Service.Config.HTTPClient.Do(r.HTTPRequest) if err != nil { @@ -69,8 +65,8 @@ func SendHandler(r *Request) { // response. e.g. 301 without location header comes back as string // error and r.HTTPResponse is nil. Other url redirect errors will // comeback in a similar method. - if e, ok := err.(*url.Error); ok { - if s := reStatusCode.FindStringSubmatch(e.Error()); s != nil { + if e, ok := err.(*url.Error); ok && e.Err != nil { + if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil { code, _ := strconv.ParseInt(s[1], 10, 64) r.HTTPResponse = &http.Response{ StatusCode: int(code), @@ -80,68 +76,61 @@ func SendHandler(r *Request) { return } } + if r.HTTPResponse == nil { + // Add a dummy request response object to ensure the HTTPResponse + // value is consistent. + r.HTTPResponse = &http.Response{ + StatusCode: int(0), + Status: http.StatusText(int(0)), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + } // Catch all other request errors. - r.Error = apierr.New("RequestError", "send request failed", err) - r.Retryable.Set(true) // network errors are retryable + r.Error = awserr.New("RequestError", "send request failed", err) + r.Retryable = aws.Bool(true) // network errors are retryable } -} +}} // ValidateResponseHandler is a request handler to validate service response. -func ValidateResponseHandler(r *Request) { +var ValidateResponseHandler = request.NamedHandler{"core.ValidateResponseHandler", func(r *request.Request) { if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 300 { // this may be replaced by an UnmarshalError handler - r.Error = apierr.New("UnknownError", "unknown error", nil) + r.Error = awserr.New("UnknownError", "unknown error", nil) } -} +}} // AfterRetryHandler performs final checks to determine if the request should // be retried and how long to delay. -func AfterRetryHandler(r *Request) { +var AfterRetryHandler = request.NamedHandler{"core.AfterRetryHandler", func(r *request.Request) { // If one of the other handlers already set the retry state // we don't want to override it based on the service's state - if !r.Retryable.IsSet() { - r.Retryable.Set(r.Service.ShouldRetry(r)) + if r.Retryable == nil { + r.Retryable = aws.Bool(r.ShouldRetry(r)) } if r.WillRetry() { - r.RetryDelay = r.Service.RetryRules(r) - sleepDelay(r.RetryDelay) + r.RetryDelay = r.RetryRules(r) + r.Service.Config.SleepDelay(r.RetryDelay) // when the expired token exception occurs the credentials // need to be expired locally so that the next request to // get credentials will trigger a credentials refresh. - if r.Error != nil { - if err, ok := r.Error.(awserr.Error); ok { - if isCodeExpiredCreds(err.Code()) { - r.Config.Credentials.Expire() - // The credentials will need to be resigned with new credentials - r.signed = false - } - } + if r.IsErrorExpired() { + r.Service.Config.Credentials.Expire() } r.RetryCount++ r.Error = nil } -} - -var ( - // ErrMissingRegion is an error that is returned if region configuration is - // not found. - ErrMissingRegion error = apierr.New("MissingRegion", "could not find region configuration", nil) - - // ErrMissingEndpoint is an error that is returned if an endpoint cannot be - // resolved for a service. - ErrMissingEndpoint error = apierr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil) -) +}} // ValidateEndpointHandler is a request handler to validate a request had the // appropriate Region and Endpoint set. Will set r.Error if the endpoint or // region is not valid. -func ValidateEndpointHandler(r *Request) { - if r.Service.SigningRegion == "" && r.Service.Config.Region == "" { - r.Error = ErrMissingRegion +var ValidateEndpointHandler = request.NamedHandler{"core.ValidateEndpointHandler", func(r *request.Request) { + if r.Service.SigningRegion == "" && aws.StringValue(r.Service.Config.Region) == "" { + r.Error = aws.ErrMissingRegion } else if r.Service.Endpoint == "" { - r.Error = ErrMissingEndpoint + r.Error = aws.ErrMissingEndpoint } -} +}} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go new file mode 100644 index 000000000000..214adcab0884 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go @@ -0,0 +1,107 @@ +package corehandlers_test + +import ( + "fmt" + "net/http" + "os" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" +) + +func TestValidateEndpointHandler(t *testing.T) { + os.Clearenv() + svc := service.New(aws.NewConfig().WithRegion("us-west-2")) + svc.Handlers.Clear() + svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler) + + req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) + err := req.Build() + + assert.NoError(t, err) +} + +func TestValidateEndpointHandlerErrorRegion(t *testing.T) { + os.Clearenv() + svc := service.New(nil) + svc.Handlers.Clear() + svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler) + + req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) + err := req.Build() + + assert.Error(t, err) + assert.Equal(t, aws.ErrMissingRegion, err) +} + +type mockCredsProvider struct { + expired bool + retrieveCalled bool +} + +func (m *mockCredsProvider) Retrieve() (credentials.Value, error) { + m.retrieveCalled = true + return credentials.Value{}, nil +} + +func (m *mockCredsProvider) IsExpired() bool { + return m.expired +} + +func TestAfterRetryRefreshCreds(t *testing.T) { + os.Clearenv() + credProvider := &mockCredsProvider{} + svc := service.New(&aws.Config{Credentials: credentials.NewCredentials(credProvider), MaxRetries: aws.Int(1)}) + + svc.Handlers.Clear() + svc.Handlers.ValidateResponse.PushBack(func(r *request.Request) { + r.Error = awserr.New("UnknownError", "", nil) + r.HTTPResponse = &http.Response{StatusCode: 400} + }) + svc.Handlers.UnmarshalError.PushBack(func(r *request.Request) { + r.Error = awserr.New("ExpiredTokenException", "", nil) + }) + svc.Handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) + + assert.True(t, svc.Config.Credentials.IsExpired(), "Expect to start out expired") + assert.False(t, credProvider.retrieveCalled) + + req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) + req.Send() + + assert.True(t, svc.Config.Credentials.IsExpired()) + assert.False(t, credProvider.retrieveCalled) + + _, err := svc.Config.Credentials.Get() + assert.NoError(t, err) + assert.True(t, credProvider.retrieveCalled) +} + +type testSendHandlerTransport struct{} + +func (t *testSendHandlerTransport) RoundTrip(r *http.Request) (*http.Response, error) { + return nil, fmt.Errorf("mock error") +} + +func TestSendHandlerError(t *testing.T) { + svc := service.New(&aws.Config{ + HTTPClient: &http.Client{ + Transport: &testSendHandlerTransport{}, + }, + }) + svc.Handlers.Clear() + svc.Handlers.Send.PushBackNamed(corehandlers.SendHandler) + r := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) + + r.Send() + + assert.Error(t, r.Error) + assert.NotNil(t, r.HTTPResponse) +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go new file mode 100644 index 000000000000..a22197734118 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go @@ -0,0 +1,144 @@ +package corehandlers + +import ( + "fmt" + "reflect" + "strconv" + "strings" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" +) + +// ValidateParameters is a request handler to validate the input parameters. +// Validating parameters only has meaning if done prior to the request being sent. +var ValidateParametersHandler = request.NamedHandler{"core.ValidateParametersHandler", func(r *request.Request) { + if r.ParamsFilled() { + v := validator{errors: []string{}} + v.validateAny(reflect.ValueOf(r.Params), "") + + if count := len(v.errors); count > 0 { + format := "%d validation errors:\n- %s" + msg := fmt.Sprintf(format, count, strings.Join(v.errors, "\n- ")) + r.Error = awserr.New("InvalidParameter", msg, nil) + } + } +}} + +// A validator validates values. Collects validations errors which occurs. +type validator struct { + errors []string +} + +// validateAny will validate any struct, slice or map type. All validations +// are also performed recursively for nested types. +func (v *validator) validateAny(value reflect.Value, path string) { + value = reflect.Indirect(value) + if !value.IsValid() { + return + } + + switch value.Kind() { + case reflect.Struct: + v.validateStruct(value, path) + case reflect.Slice: + for i := 0; i < value.Len(); i++ { + v.validateAny(value.Index(i), path+fmt.Sprintf("[%d]", i)) + } + case reflect.Map: + for _, n := range value.MapKeys() { + v.validateAny(value.MapIndex(n), path+fmt.Sprintf("[%q]", n.String())) + } + } +} + +// validateStruct will validate the struct value's fields. If the structure has +// nested types those types will be validated also. +func (v *validator) validateStruct(value reflect.Value, path string) { + prefix := "." + if path == "" { + prefix = "" + } + + for i := 0; i < value.Type().NumField(); i++ { + f := value.Type().Field(i) + if strings.ToLower(f.Name[0:1]) == f.Name[0:1] { + continue + } + fvalue := value.FieldByName(f.Name) + + err := validateField(f, fvalue, validateFieldRequired, validateFieldMin) + if err != nil { + v.errors = append(v.errors, fmt.Sprintf("%s: %s", err.Error(), path+prefix+f.Name)) + continue + } + + v.validateAny(fvalue, path+prefix+f.Name) + } +} + +type validatorFunc func(f reflect.StructField, fvalue reflect.Value) error + +func validateField(f reflect.StructField, fvalue reflect.Value, funcs ...validatorFunc) error { + for _, fn := range funcs { + if err := fn(f, fvalue); err != nil { + return err + } + } + return nil +} + +// Validates that a field has a valid value provided for required fields. +func validateFieldRequired(f reflect.StructField, fvalue reflect.Value) error { + if f.Tag.Get("required") == "" { + return nil + } + + switch fvalue.Kind() { + case reflect.Ptr, reflect.Slice, reflect.Map: + if fvalue.IsNil() { + return fmt.Errorf("missing required parameter") + } + default: + if !fvalue.IsValid() { + return fmt.Errorf("missing required parameter") + } + } + return nil +} + +// Validates that if a value is provided for a field, that value must be at +// least a minimum length. +func validateFieldMin(f reflect.StructField, fvalue reflect.Value) error { + minStr := f.Tag.Get("min") + if minStr == "" { + return nil + } + min, _ := strconv.ParseInt(minStr, 10, 64) + + kind := fvalue.Kind() + if kind == reflect.Ptr { + if fvalue.IsNil() { + return nil + } + fvalue = fvalue.Elem() + } + + switch fvalue.Kind() { + case reflect.String: + if int64(fvalue.Len()) < min { + return fmt.Errorf("field too short, minimum length %d", min) + } + case reflect.Slice, reflect.Map: + if fvalue.IsNil() { + return nil + } + if int64(fvalue.Len()) < min { + return fmt.Errorf("field too short, minimum length %d", min) + } + + // TODO min can also apply to number minimum value. + + } + return nil +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator_test.go new file mode 100644 index 000000000000..db483ba408b3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator_test.go @@ -0,0 +1,134 @@ +package corehandlers_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" + "github.com/aws/aws-sdk-go/aws/service/serviceinfo" + "github.com/stretchr/testify/require" +) + +var testSvc = func() *service.Service { + s := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: &aws.Config{}, + ServiceName: "mock-service", + APIVersion: "2015-01-01", + }, + } + return s +}() + +type StructShape struct { + RequiredList []*ConditionalStructShape `required:"true"` + RequiredMap map[string]*ConditionalStructShape `required:"true"` + RequiredBool *bool `required:"true"` + OptionalStruct *ConditionalStructShape + + hiddenParameter *string + + metadataStructureShape +} + +type metadataStructureShape struct { + SDKShapeTraits bool +} + +type ConditionalStructShape struct { + Name *string `required:"true"` + SDKShapeTraits bool +} + +func TestNoErrors(t *testing.T) { + input := &StructShape{ + RequiredList: []*ConditionalStructShape{}, + RequiredMap: map[string]*ConditionalStructShape{ + "key1": {Name: aws.String("Name")}, + "key2": {Name: aws.String("Name")}, + }, + RequiredBool: aws.Bool(true), + OptionalStruct: &ConditionalStructShape{Name: aws.String("Name")}, + } + + req := testSvc.NewRequest(&request.Operation{}, input, nil) + corehandlers.ValidateParametersHandler.Fn(req) + require.NoError(t, req.Error) +} + +func TestMissingRequiredParameters(t *testing.T) { + input := &StructShape{} + req := testSvc.NewRequest(&request.Operation{}, input, nil) + corehandlers.ValidateParametersHandler.Fn(req) + + require.Error(t, req.Error) + assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code()) + assert.Equal(t, "3 validation errors:\n- missing required parameter: RequiredList\n- missing required parameter: RequiredMap\n- missing required parameter: RequiredBool", req.Error.(awserr.Error).Message()) +} + +func TestNestedMissingRequiredParameters(t *testing.T) { + input := &StructShape{ + RequiredList: []*ConditionalStructShape{{}}, + RequiredMap: map[string]*ConditionalStructShape{ + "key1": {Name: aws.String("Name")}, + "key2": {}, + }, + RequiredBool: aws.Bool(true), + OptionalStruct: &ConditionalStructShape{}, + } + + req := testSvc.NewRequest(&request.Operation{}, input, nil) + corehandlers.ValidateParametersHandler.Fn(req) + + require.Error(t, req.Error) + assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code()) + assert.Equal(t, "3 validation errors:\n- missing required parameter: RequiredList[0].Name\n- missing required parameter: RequiredMap[\"key2\"].Name\n- missing required parameter: OptionalStruct.Name", req.Error.(awserr.Error).Message()) +} + +type testInput struct { + StringField string `min:"5"` + PtrStrField *string `min:"2"` + ListField []string `min:"3"` + MapField map[string]string `min:"4"` +} + +var testsFieldMin = []struct { + err awserr.Error + in testInput +}{ + { + err: awserr.New("InvalidParameter", "1 validation errors:\n- field too short, minimum length 5: StringField", nil), + in: testInput{StringField: "abcd"}, + }, + { + err: awserr.New("InvalidParameter", "2 validation errors:\n- field too short, minimum length 5: StringField\n- field too short, minimum length 3: ListField", nil), + in: testInput{StringField: "abcd", ListField: []string{"a", "b"}}, + }, + { + err: awserr.New("InvalidParameter", "3 validation errors:\n- field too short, minimum length 5: StringField\n- field too short, minimum length 3: ListField\n- field too short, minimum length 4: MapField", nil), + in: testInput{StringField: "abcd", ListField: []string{"a", "b"}, MapField: map[string]string{"a": "a", "b": "b"}}, + }, + { + err: awserr.New("InvalidParameter", "1 validation errors:\n- field too short, minimum length 2: PtrStrField", nil), + in: testInput{StringField: "abcde", PtrStrField: aws.String("v")}, + }, + { + err: nil, + in: testInput{StringField: "abcde", PtrStrField: aws.String("value"), + ListField: []string{"a", "b", "c"}, MapField: map[string]string{"a": "a", "b": "b", "c": "c", "d": "d"}}, + }, +} + +func TestValidateFieldMinParameter(t *testing.T) { + for i, c := range testsFieldMin { + req := testSvc.NewRequest(&request.Operation{}, &c.in, nil) + corehandlers.ValidateParametersHandler.Fn(req) + + require.Equal(t, c.err, req.Error, "%d case failed", i) + } +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go index 196be7c1728b..7f509ca83ca5 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go @@ -1,13 +1,15 @@ package credentials import ( - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" ) var ( // ErrNoValidProvidersFoundInChain Is returned when there are no valid // providers in the ChainProvider. - ErrNoValidProvidersFoundInChain = apierr.New("NoCredentialProviders", "no valid providers in chain", nil) + // + // @readonly + ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders", "no valid providers in chain", nil) ) // A ChainProvider will search for a provider which returns credentials @@ -36,7 +38,9 @@ var ( // &EnvProvider{}, // &EC2RoleProvider{}, // }) -// creds.Retrieve() +// +// // Usage of ChainCredentials with aws.Config +// svc := ec2.New(&aws.Config{Credentials: creds}) // type ChainProvider struct { Providers []Provider diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider_test.go index 1a275fcac255..4fba22f29f44 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/chain_provider_test.go @@ -3,15 +3,15 @@ package credentials import ( "testing" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/stretchr/testify/assert" ) func TestChainProviderGet(t *testing.T) { p := &ChainProvider{ Providers: []Provider{ - &stubProvider{err: apierr.New("FirstError", "first provider error", nil)}, - &stubProvider{err: apierr.New("SecondError", "second provider error", nil)}, + &stubProvider{err: awserr.New("FirstError", "first provider error", nil)}, + &stubProvider{err: awserr.New("SecondError", "second provider error", nil)}, &stubProvider{ creds: Value{ AccessKeyID: "AKID", @@ -62,8 +62,8 @@ func TestChainProviderWithNoProvider(t *testing.T) { func TestChainProviderWithNoValidProvider(t *testing.T) { p := &ChainProvider{ Providers: []Provider{ - &stubProvider{err: apierr.New("FirstError", "first provider error", nil)}, - &stubProvider{err: apierr.New("SecondError", "second provider error", nil)}, + &stubProvider{err: awserr.New("FirstError", "first provider error", nil)}, + &stubProvider{err: awserr.New("SecondError", "second provider error", nil)}, }, } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials.go index 6f6ec03127e9..2834a088aab9 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials.go @@ -63,6 +63,7 @@ import ( // svc := s3.New(&aws.Config{Credentials: AnonymousCredentials}) // // Access public S3 buckets. // +// @readonly var AnonymousCredentials = NewStaticCredentials("", "", "") // A Value is the AWS credentials value for individual credential fields. @@ -93,6 +94,50 @@ type Provider interface { IsExpired() bool } +// A Expiry provides shared expiration logic to be used by credentials +// providers to implement expiry functionality. +// +// The best method to use this struct is as an anonymous field within the +// provider's struct. +// +// Example: +// type EC2RoleProvider struct { +// Expiry +// ... +// } +type Expiry struct { + // The date/time when to expire on + expiration time.Time + + // If set will be used by IsExpired to determine the current time. + // Defaults to time.Now if CurrentTime is not set. Available for testing + // to be able to mock out the current time. + CurrentTime func() time.Time +} + +// SetExpiration sets the expiration IsExpired will check when called. +// +// If window is greater than 0 the expiration time will be reduced by the +// window value. +// +// Using a window is helpful to trigger credentials to expire sooner than +// the expiration time given to ensure no requests are made with expired +// tokens. +func (e *Expiry) SetExpiration(expiration time.Time, window time.Duration) { + e.expiration = expiration + if window > 0 { + e.expiration = e.expiration.Add(-window) + } +} + +// IsExpired returns if the credentials are expired. +func (e *Expiry) IsExpired() bool { + if e.CurrentTime == nil { + e.CurrentTime = time.Now + } + return e.expiration.Before(e.CurrentTime()) +} + // A Credentials provides synchronous safe retrieval of AWS credentials Value. // Credentials will cache the credentials value until they expire. Once the value // expires the next Get will attempt to retrieve valid credentials. @@ -173,6 +218,3 @@ func (c *Credentials) IsExpired() bool { func (c *Credentials) isExpired() bool { return c.forceRefresh || c.provider.IsExpired() } - -// Provide a stub-able time.Now for unit tests so expiry can be tested. -var currentTime = time.Now diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials_test.go index 779bb0da4a80..99c2b47742e0 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/credentials_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/internal/apierr" "github.com/stretchr/testify/assert" ) @@ -40,7 +39,7 @@ func TestCredentialsGet(t *testing.T) { } func TestCredentialsGetWithError(t *testing.T) { - c := NewCredentials(&stubProvider{err: apierr.New("provider error", "", nil), expired: true}) + c := NewCredentials(&stubProvider{err: awserr.New("provider error", "", nil), expired: true}) _, err := c.Get() assert.Equal(t, "provider error", err.(awserr.Error).Code(), "Expected provider error") diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2_role_provider_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2_role_provider_test.go deleted file mode 100644 index 5232a1dcafda..000000000000 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2_role_provider_test.go +++ /dev/null @@ -1,114 +0,0 @@ -package credentials - -import ( - "fmt" - "github.com/stretchr/testify/assert" - "net/http" - "net/http/httptest" - "testing" - "time" -) - -func initTestServer(expireOn string) *httptest.Server { - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.RequestURI == "/" { - fmt.Fprintln(w, "/creds") - } else { - fmt.Fprintf(w, `{ - "AccessKeyId" : "accessKey", - "SecretAccessKey" : "secret", - "Token" : "token", - "Expiration" : "%s" -}`, expireOn) - } - })) - - return server -} - -func TestEC2RoleProvider(t *testing.T) { - server := initTestServer("2014-12-16T01:51:37Z") - defer server.Close() - - p := &EC2RoleProvider{Client: http.DefaultClient, Endpoint: server.URL} - - creds, err := p.Retrieve() - assert.Nil(t, err, "Expect no error") - - assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match") - assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match") - assert.Equal(t, "token", creds.SessionToken, "Expect session token to match") -} - -func TestEC2RoleProviderIsExpired(t *testing.T) { - server := initTestServer("2014-12-16T01:51:37Z") - defer server.Close() - - p := &EC2RoleProvider{Client: http.DefaultClient, Endpoint: server.URL} - defer func() { - currentTime = time.Now - }() - currentTime = func() time.Time { - return time.Date(2014, 12, 15, 21, 26, 0, 0, time.UTC) - } - - assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.") - - _, err := p.Retrieve() - assert.Nil(t, err, "Expect no error") - - assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.") - - currentTime = func() time.Time { - return time.Date(3014, 12, 15, 21, 26, 0, 0, time.UTC) - } - - assert.True(t, p.IsExpired(), "Expect creds to be expired.") -} - -func TestEC2RoleProviderExpiryWindowIsExpired(t *testing.T) { - server := initTestServer("2014-12-16T01:51:37Z") - defer server.Close() - - p := &EC2RoleProvider{Client: http.DefaultClient, Endpoint: server.URL, ExpiryWindow: time.Hour * 1} - defer func() { - currentTime = time.Now - }() - currentTime = func() time.Time { - return time.Date(2014, 12, 15, 0, 51, 37, 0, time.UTC) - } - - assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.") - - _, err := p.Retrieve() - assert.Nil(t, err, "Expect no error") - - assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.") - - currentTime = func() time.Time { - return time.Date(2014, 12, 16, 0, 55, 37, 0, time.UTC) - } - - assert.True(t, p.IsExpired(), "Expect creds to be expired.") -} - -func BenchmarkEC2RoleProvider(b *testing.B) { - server := initTestServer("2014-12-16T01:51:37Z") - defer server.Close() - - p := &EC2RoleProvider{Client: http.DefaultClient, Endpoint: server.URL} - _, err := p.Retrieve() - if err != nil { - b.Fatal(err) - } - - b.ResetTimer() - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - _, err := p.Retrieve() - if err != nil { - b.Fatal(err) - } - } - }) -} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2_role_provider.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go similarity index 58% rename from Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2_role_provider.go rename to Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go index ed0c8ba9cd46..946a117206ee 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2_role_provider.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go @@ -1,24 +1,25 @@ -package credentials +package ec2rolecreds import ( "bufio" "encoding/json" "fmt" - "net/http" + "path" + "strings" "time" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/ec2metadata" ) -const metadataCredentialsEndpoint = "http://169.254.169.254/latest/meta-data/iam/security-credentials/" - // A EC2RoleProvider retrieves credentials from the EC2 service, and keeps track if // those credentials are expired. // // Example how to configure the EC2RoleProvider with custom http Client, Endpoint // or ExpiryWindow // -// p := &credentials.EC2RoleProvider{ +// p := &ec2rolecreds.EC2RoleProvider{ // // Pass in a custom timeout to be used when requesting // // IAM EC2 Role credentials. // Client: &http.Client{ @@ -31,13 +32,11 @@ const metadataCredentialsEndpoint = "http://169.254.169.254/latest/meta-data/iam // // specified the credentials will be expired early // ExpiryWindow: 0, // } -// type EC2RoleProvider struct { - // Endpoint must be fully quantified URL - Endpoint string + credentials.Expiry - // HTTP client to use when connecting to EC2 service - Client *http.Client + // EC2Metadata client to use when connecting to EC2 metadata service + Client *ec2metadata.Client // ExpiryWindow will allow the credentials to trigger refreshing prior to // the credentials actually expiring. This is beneficial so race conditions @@ -49,12 +48,9 @@ type EC2RoleProvider struct { // // If ExpiryWindow is 0 or less it will be ignored. ExpiryWindow time.Duration - - // The date/time at which the credentials expire. - expiresOn time.Time } -// NewEC2RoleCredentials returns a pointer to a new Credentials object +// NewCredentials returns a pointer to a new Credentials object // wrapping the EC2RoleProvider. // // Takes a custom http.Client which can be configured for custom handling of @@ -66,9 +62,8 @@ type EC2RoleProvider struct { // Window is the expiry window that will be subtracted from the expiry returned // by the role credential request. This is done so that the credentials will // expire sooner than their actual lifespan. -func NewEC2RoleCredentials(client *http.Client, endpoint string, window time.Duration) *Credentials { - return NewCredentials(&EC2RoleProvider{ - Endpoint: endpoint, +func NewCredentials(client *ec2metadata.Client, window time.Duration) *credentials.Credentials { + return credentials.NewCredentials(&EC2RoleProvider{ Client: client, ExpiryWindow: window, }) @@ -77,73 +72,67 @@ func NewEC2RoleCredentials(client *http.Client, endpoint string, window time.Dur // Retrieve retrieves credentials from the EC2 service. // Error will be returned if the request fails, or unable to extract // the desired credentials. -func (m *EC2RoleProvider) Retrieve() (Value, error) { +func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) { if m.Client == nil { - m.Client = http.DefaultClient - } - if m.Endpoint == "" { - m.Endpoint = metadataCredentialsEndpoint + m.Client = ec2metadata.New(nil) } - credsList, err := requestCredList(m.Client, m.Endpoint) + credsList, err := requestCredList(m.Client) if err != nil { - return Value{}, err + return credentials.Value{}, err } if len(credsList) == 0 { - return Value{}, apierr.New("EmptyEC2RoleList", "empty EC2 Role list", nil) + return credentials.Value{}, awserr.New("EmptyEC2RoleList", "empty EC2 Role list", nil) } credsName := credsList[0] - roleCreds, err := requestCred(m.Client, m.Endpoint, credsName) + roleCreds, err := requestCred(m.Client, credsName) if err != nil { - return Value{}, err + return credentials.Value{}, err } - m.expiresOn = roleCreds.Expiration - if m.ExpiryWindow > 0 { - // Offset based on expiry window if set. - m.expiresOn = m.expiresOn.Add(-m.ExpiryWindow) - } + m.SetExpiration(roleCreds.Expiration, m.ExpiryWindow) - return Value{ + return credentials.Value{ AccessKeyID: roleCreds.AccessKeyID, SecretAccessKey: roleCreds.SecretAccessKey, SessionToken: roleCreds.Token, }, nil } -// IsExpired returns if the credentials are expired. -func (m *EC2RoleProvider) IsExpired() bool { - return m.expiresOn.Before(currentTime()) -} - // A ec2RoleCredRespBody provides the shape for deserializing credential // request responses. type ec2RoleCredRespBody struct { + // Success State Expiration time.Time AccessKeyID string SecretAccessKey string Token string + + // Error state + Code string + Message string } +const iamSecurityCredsPath = "/iam/security-credentials" + // requestCredList requests a list of credentials from the EC2 service. // If there are no credentials, or there is an error making or receiving the request -func requestCredList(client *http.Client, endpoint string) ([]string, error) { - resp, err := client.Get(endpoint) +func requestCredList(client *ec2metadata.Client) ([]string, error) { + resp, err := client.GetMetadata(iamSecurityCredsPath) if err != nil { - return nil, apierr.New("ListEC2Role", "failed to list EC2 Roles", err) + return nil, awserr.New("EC2RoleRequestError", "failed to list EC2 Roles", err) } - defer resp.Body.Close() credsList := []string{} - s := bufio.NewScanner(resp.Body) + s := bufio.NewScanner(strings.NewReader(resp)) for s.Scan() { credsList = append(credsList, s.Text()) } if err := s.Err(); err != nil { - return nil, apierr.New("ReadEC2Role", "failed to read list of EC2 Roles", err) + return nil, awserr.New("SerializationError", "failed to read list of EC2 Roles", err) } return credsList, nil @@ -153,20 +142,26 @@ func requestCredList(client *http.Client, endpoint string) ([]string, error) { // // If the credentials cannot be found, or there is an error reading the response // and error will be returned. -func requestCred(client *http.Client, endpoint, credsName string) (*ec2RoleCredRespBody, error) { - resp, err := client.Get(endpoint + credsName) +func requestCred(client *ec2metadata.Client, credsName string) (ec2RoleCredRespBody, error) { + resp, err := client.GetMetadata(path.Join(iamSecurityCredsPath, credsName)) if err != nil { - return nil, apierr.New("GetEC2RoleCredentials", - fmt.Sprintf("failed to get %s EC2 Role credentials", credsName), - err) + return ec2RoleCredRespBody{}, + awserr.New("EC2RoleRequestError", + fmt.Sprintf("failed to get %s EC2 Role credentials", credsName), + err) + } + + respCreds := ec2RoleCredRespBody{} + if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil { + return ec2RoleCredRespBody{}, + awserr.New("SerializationError", + fmt.Sprintf("failed to decode %s EC2 Role credentials", credsName), + err) } - defer resp.Body.Close() - respCreds := &ec2RoleCredRespBody{} - if err := json.NewDecoder(resp.Body).Decode(respCreds); err != nil { - return nil, apierr.New("DecodeEC2RoleCredentials", - fmt.Sprintf("failed to decode %s EC2 Role credentials", credsName), - err) + if respCreds.Code != "Success" { + // If an error code was returned something failed requesting the role. + return ec2RoleCredRespBody{}, awserr.New(respCreds.Code, respCreds.Message, nil) } return respCreds, nil diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider_test.go new file mode 100644 index 000000000000..cd0cbc97e06c --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider_test.go @@ -0,0 +1,161 @@ +package ec2rolecreds_test + +import ( + "fmt" + "net/http" + "net/http/httptest" + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" + "github.com/aws/aws-sdk-go/aws/ec2metadata" +) + +const credsRespTmpl = `{ + "Code": "Success", + "Type": "AWS-HMAC", + "AccessKeyId" : "accessKey", + "SecretAccessKey" : "secret", + "Token" : "token", + "Expiration" : "%s", + "LastUpdated" : "2009-11-23T0:00:00Z" +}` + +const credsFailRespTmpl = `{ + "Code": "ErrorCode", + "Message": "ErrorMsg", + "LastUpdated": "2009-11-23T0:00:00Z" +}` + +func initTestServer(expireOn string, failAssume bool) *httptest.Server { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/latest/meta-data/iam/security-credentials" { + fmt.Fprintln(w, "RoleName") + } else if r.URL.Path == "/latest/meta-data/iam/security-credentials/RoleName" { + if failAssume { + fmt.Fprintf(w, credsFailRespTmpl) + } else { + fmt.Fprintf(w, credsRespTmpl, expireOn) + } + } else { + http.Error(w, "bad request", http.StatusBadRequest) + } + })) + + return server +} + +func TestEC2RoleProvider(t *testing.T) { + server := initTestServer("2014-12-16T01:51:37Z", false) + defer server.Close() + + p := &ec2rolecreds.EC2RoleProvider{ + Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}), + } + + creds, err := p.Retrieve() + assert.Nil(t, err, "Expect no error") + + assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match") + assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match") + assert.Equal(t, "token", creds.SessionToken, "Expect session token to match") +} + +func TestEC2RoleProviderFailAssume(t *testing.T) { + server := initTestServer("2014-12-16T01:51:37Z", true) + defer server.Close() + + p := &ec2rolecreds.EC2RoleProvider{ + Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}), + } + + creds, err := p.Retrieve() + assert.Error(t, err, "Expect error") + + e := err.(awserr.Error) + assert.Equal(t, "ErrorCode", e.Code()) + assert.Equal(t, "ErrorMsg", e.Message()) + assert.Nil(t, e.OrigErr()) + + assert.Equal(t, "", creds.AccessKeyID, "Expect access key ID to match") + assert.Equal(t, "", creds.SecretAccessKey, "Expect secret access key to match") + assert.Equal(t, "", creds.SessionToken, "Expect session token to match") +} + +func TestEC2RoleProviderIsExpired(t *testing.T) { + server := initTestServer("2014-12-16T01:51:37Z", false) + defer server.Close() + + p := &ec2rolecreds.EC2RoleProvider{ + Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}), + } + p.CurrentTime = func() time.Time { + return time.Date(2014, 12, 15, 21, 26, 0, 0, time.UTC) + } + + assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.") + + _, err := p.Retrieve() + assert.Nil(t, err, "Expect no error") + + assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.") + + p.CurrentTime = func() time.Time { + return time.Date(3014, 12, 15, 21, 26, 0, 0, time.UTC) + } + + assert.True(t, p.IsExpired(), "Expect creds to be expired.") +} + +func TestEC2RoleProviderExpiryWindowIsExpired(t *testing.T) { + server := initTestServer("2014-12-16T01:51:37Z", false) + defer server.Close() + + p := &ec2rolecreds.EC2RoleProvider{ + Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}), + ExpiryWindow: time.Hour * 1, + } + p.CurrentTime = func() time.Time { + return time.Date(2014, 12, 15, 0, 51, 37, 0, time.UTC) + } + + assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.") + + _, err := p.Retrieve() + assert.Nil(t, err, "Expect no error") + + assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.") + + p.CurrentTime = func() time.Time { + return time.Date(2014, 12, 16, 0, 55, 37, 0, time.UTC) + } + + assert.True(t, p.IsExpired(), "Expect creds to be expired.") +} + +func BenchmarkEC2RoleProvider(b *testing.B) { + server := initTestServer("2014-12-16T01:51:37Z", false) + defer server.Close() + + p := &ec2rolecreds.EC2RoleProvider{ + Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}), + } + _, err := p.Retrieve() + if err != nil { + b.Fatal(err) + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _, err := p.Retrieve() + if err != nil { + b.Fatal(err) + } + } + }) +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go index e9c575292ede..043e861d6f2c 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go @@ -3,24 +3,30 @@ package credentials import ( "os" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" ) var ( // ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be // found in the process's environment. - ErrAccessKeyIDNotFound = apierr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil) + // + // @readonly + ErrAccessKeyIDNotFound = awserr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil) + // ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key // can't be found in the process's environment. - ErrSecretAccessKeyNotFound = apierr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil) + // + // @readonly + ErrSecretAccessKeyNotFound = awserr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil) ) // A EnvProvider retrieves credentials from the environment variables of the // running process. Environment credentials never expire. // // Environment variables used: -// - Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY -// - Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY +// +// * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY +// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY type EnvProvider struct { retrieved bool } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go index d61b140be467..fac6d78c41e5 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go @@ -7,12 +7,14 @@ import ( "github.com/vaughan0/go-ini" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" ) var ( // ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found. - ErrSharedCredentialsHomeNotFound = apierr.New("UserHomeNotFound", "user home directory not found.", nil) + // + // @readonly + ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil) ) // A SharedCredentialsProvider retrieves credentials from the current user's home @@ -20,8 +22,12 @@ var ( // // Profile ini file example: $HOME/.aws/credentials type SharedCredentialsProvider struct { - // Path to the shared credentials file. If empty will default to current user's - // home directory. + // Path to the shared credentials file. + // + // If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the + // env value is empty will default to current user's home directory. + // Linux/OSX: "$HOME/.aws/credentials" + // Windows: "%USERPROFILE%\.aws\credentials" Filename string // AWS Profile to extract credentials from the shared credentials file. If empty @@ -72,20 +78,20 @@ func (p *SharedCredentialsProvider) IsExpired() bool { func loadProfile(filename, profile string) (Value, error) { config, err := ini.LoadFile(filename) if err != nil { - return Value{}, apierr.New("SharedCredsLoad", "failed to load shared credentials file", err) + return Value{}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err) } iniProfile := config.Section(profile) id, ok := iniProfile["aws_access_key_id"] if !ok { - return Value{}, apierr.New("SharedCredsAccessKey", + return Value{}, awserr.New("SharedCredsAccessKey", fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename), nil) } secret, ok := iniProfile["aws_secret_access_key"] if !ok { - return Value{}, apierr.New("SharedCredsSecret", + return Value{}, awserr.New("SharedCredsSecret", fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename), nil) } @@ -104,6 +110,10 @@ func loadProfile(filename, profile string) (Value, error) { // Will return an error if the user's home directory path cannot be found. func (p *SharedCredentialsProvider) filename() (string, error) { if p.Filename == "" { + if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); p.Filename != "" { + return p.Filename, nil + } + homeDir := os.Getenv("HOME") // *nix if homeDir == "" { // Windows homeDir = os.Getenv("USERPROFILE") diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider_test.go index 3621d56eddca..1d9983f2ce10 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider_test.go @@ -31,6 +31,19 @@ func TestSharedCredentialsProviderIsExpired(t *testing.T) { assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve") } +func TestSharedCredentialsProviderWithAWS_SHARED_CREDENTIALS_FILE(t *testing.T) { + os.Clearenv() + os.Setenv("AWS_SHARED_CREDENTIALS_FILE", "example.ini") + p := SharedCredentialsProvider{} + creds, err := p.Retrieve() + + assert.Nil(t, err, "Expect no error") + + assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match") + assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match") + assert.Equal(t, "token", creds.SessionToken, "Expect session token to match") +} + func TestSharedCredentialsProviderWithAWS_PROFILE(t *testing.T) { os.Clearenv() os.Setenv("AWS_PROFILE", "no_token") @@ -66,12 +79,10 @@ func BenchmarkSharedCredentialsProvider(b *testing.B) { } b.ResetTimer() - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - _, err := p.Retrieve() - if err != nil { - b.Fatal(err) - } + for i := 0; i < b.N; i++ { + _, err := p.Retrieve() + if err != nil { + b.Fatal(err) } - }) + } } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go index 4466cd263ccc..530a9ac2f363 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go @@ -1,12 +1,14 @@ package credentials import ( - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" ) var ( // ErrStaticCredentialsEmpty is emitted when static credentials are empty. - ErrStaticCredentialsEmpty = apierr.New("EmptyStaticCreds", "static credentials are empty", nil) + // + // @readonly + ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil) ) // A StaticProvider is a set of credentials which are set pragmatically, diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go new file mode 100644 index 000000000000..7a4459f80466 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go @@ -0,0 +1,125 @@ +// Package stscreds are credential Providers to retrieve STS AWS credentials. +// +// STS provides multiple ways to retrieve credentials which can be used when making +// future AWS service API operation calls. +package stscreds + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/service/sts" +) + +// AssumeRoler represents the minimal subset of the STS client API used by this provider. +type AssumeRoler interface { + AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) +} + +// AssumeRoleProvider retrieves temporary credentials from the STS service, and +// keeps track of their expiration time. This provider must be used explicitly, +// as it is not included in the credentials chain. +// +// Example how to configure a service to use this provider: +// +// config := &aws.Config{ +// Credentials: stscreds.NewCredentials(nil, "arn-of-the-role-to-assume", 10*time.Second), +// }) +// // Use config for creating your AWS service. +// +// Example how to obtain customised credentials: +// +// provider := &stscreds.Provider{ +// // Extend the duration to 1 hour. +// Duration: time.Hour, +// // Custom role name. +// RoleSessionName: "custom-session-name", +// } +// creds := credentials.NewCredentials(provider) +// +type AssumeRoleProvider struct { + credentials.Expiry + + // Custom STS client. If not set the default STS client will be used. + Client AssumeRoler + + // Role to be assumed. + RoleARN string + + // Session name, if you wish to reuse the credentials elsewhere. + RoleSessionName string + + // Expiry duration of the STS credentials. Defaults to 15 minutes if not set. + Duration time.Duration + + // Optional ExternalID to pass along, defaults to nil if not set. + ExternalID *string + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration +} + +// NewCredentials returns a pointer to a new Credentials object wrapping the +// AssumeRoleProvider. The credentials will expire every 15 minutes and the +// role will be named after a nanosecond timestamp of this operation. +// +// The sts and roleARN parameters are used for building the "AssumeRole" call. +// Pass nil as sts to use the default client. +// +// Window is the expiry window that will be subtracted from the expiry returned +// by the role credential request. This is done so that the credentials will +// expire sooner than their actual lifespan. +func NewCredentials(client AssumeRoler, roleARN string, window time.Duration) *credentials.Credentials { + return credentials.NewCredentials(&AssumeRoleProvider{ + Client: client, + RoleARN: roleARN, + ExpiryWindow: window, + }) +} + +// Retrieve generates a new set of temporary credentials using STS. +func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) { + + // Apply defaults where parameters are not set. + if p.Client == nil { + p.Client = sts.New(nil) + } + if p.RoleSessionName == "" { + // Try to work out a role name that will hopefully end up unique. + p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano()) + } + if p.Duration == 0 { + // Expire as often as AWS permits. + p.Duration = 15 * time.Minute + } + + roleOutput, err := p.Client.AssumeRole(&sts.AssumeRoleInput{ + DurationSeconds: aws.Int64(int64(p.Duration / time.Second)), + RoleArn: aws.String(p.RoleARN), + RoleSessionName: aws.String(p.RoleSessionName), + ExternalId: p.ExternalID, + }) + + if err != nil { + return credentials.Value{}, err + } + + // We will proactively generate new credentials before they expire. + p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow) + + return credentials.Value{ + AccessKeyID: *roleOutput.Credentials.AccessKeyId, + SecretAccessKey: *roleOutput.Credentials.SecretAccessKey, + SessionToken: *roleOutput.Credentials.SessionToken, + }, nil +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go new file mode 100644 index 000000000000..f5b97c0053b9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go @@ -0,0 +1,59 @@ +package stscreds + +import ( + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/sts" + "github.com/stretchr/testify/assert" +) + +type stubSTS struct { +} + +func (s *stubSTS) AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) { + expiry := time.Now().Add(60 * time.Minute) + return &sts.AssumeRoleOutput{ + Credentials: &sts.Credentials{ + // Just reflect the role arn to the provider. + AccessKeyId: input.RoleArn, + SecretAccessKey: aws.String("assumedSecretAccessKey"), + SessionToken: aws.String("assumedSessionToken"), + Expiration: &expiry, + }, + }, nil +} + +func TestAssumeRoleProvider(t *testing.T) { + stub := &stubSTS{} + p := &AssumeRoleProvider{ + Client: stub, + RoleARN: "roleARN", + } + + creds, err := p.Retrieve() + assert.Nil(t, err, "Expect no error") + + assert.Equal(t, "roleARN", creds.AccessKeyID, "Expect access key ID to be reflected role ARN") + assert.Equal(t, "assumedSecretAccessKey", creds.SecretAccessKey, "Expect secret access key to match") + assert.Equal(t, "assumedSessionToken", creds.SessionToken, "Expect session token to match") +} + +func BenchmarkAssumeRoleProvider(b *testing.B) { + stub := &stubSTS{} + p := &AssumeRoleProvider{ + Client: stub, + RoleARN: "roleARN", + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _, err := p.Retrieve() + if err != nil { + b.Fatal(err) + } + } + }) +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/defaults/defaults.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/defaults/defaults.go new file mode 100644 index 000000000000..2f161b57f1d5 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/defaults/defaults.go @@ -0,0 +1,39 @@ +package defaults + +import ( + "net/http" + "os" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" +) + +// DefaultChainCredentials is a Credentials which will find the first available +// credentials Value from the list of Providers. +// +// This should be used in the default case. Once the type of credentials are +// known switching to the specific Credentials will be more efficient. +var DefaultChainCredentials = credentials.NewChainCredentials( + []credentials.Provider{ + &credentials.EnvProvider{}, + &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, + &ec2rolecreds.EC2RoleProvider{ExpiryWindow: 5 * time.Minute}, + }) + +// DefaultConfig is the default all service configuration will be based off of. +// By default, all clients use this structure for initialization options unless +// a custom configuration object is passed in. +// +// You may modify this global structure to change all default configuration +// in the SDK. Note that configuration options are copied by value, so any +// modifications must happen before constructing a client. +var DefaultConfig = aws.NewConfig(). + WithCredentials(DefaultChainCredentials). + WithRegion(os.Getenv("AWS_REGION")). + WithHTTPClient(http.DefaultClient). + WithMaxRetries(aws.DefaultRetries). + WithLogger(aws.NewDefaultLogger()). + WithLogLevel(aws.LogOff). + WithSleepDelay(time.Sleep) diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go new file mode 100644 index 000000000000..9d784b6e6abe --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go @@ -0,0 +1,43 @@ +package ec2metadata + +import ( + "path" + + "github.com/aws/aws-sdk-go/aws/request" +) + +// GetMetadata uses the path provided to request +func (c *Client) GetMetadata(p string) (string, error) { + op := &request.Operation{ + Name: "GetMetadata", + HTTPMethod: "GET", + HTTPPath: path.Join("/", "meta-data", p), + } + + output := &metadataOutput{} + req := request.New(c.Service.ServiceInfo, c.Service.Handlers, c.Service.Retryer, op, nil, output) + + return output.Content, req.Send() +} + +// Region returns the region the instance is running in. +func (c *Client) Region() (string, error) { + resp, err := c.GetMetadata("placement/availability-zone") + if err != nil { + return "", err + } + + // returns region without the suffix. Eg: us-west-2a becomes us-west-2 + return resp[:len(resp)-1], nil +} + +// Available returns if the application has access to the EC2 Metadata service. +// Can be used to determine if application is running within an EC2 Instance and +// the metadata service is available. +func (c *Client) Available() bool { + if _, err := c.GetMetadata("instance-id"); err != nil { + return false + } + + return true +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api_test.go new file mode 100644 index 000000000000..61ab62a5305d --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api_test.go @@ -0,0 +1,100 @@ +package ec2metadata_test + +import ( + "bytes" + "io/ioutil" + "net/http" + "net/http/httptest" + "path" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/ec2metadata" + "github.com/aws/aws-sdk-go/aws/request" +) + +func initTestServer(path string, resp string) *httptest.Server { + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.RequestURI != path { + http.Error(w, "not found", http.StatusNotFound) + return + } + + w.Write([]byte(resp)) + })) +} + +func TestEndpoint(t *testing.T) { + c := ec2metadata.New(&ec2metadata.Config{}) + op := &request.Operation{ + Name: "GetMetadata", + HTTPMethod: "GET", + HTTPPath: path.Join("/", "meta-data", "testpath"), + } + + req := c.Service.NewRequest(op, nil, nil) + assert.Equal(t, "http://169.254.169.254/latest", req.Service.Endpoint) + assert.Equal(t, "http://169.254.169.254/latest/meta-data/testpath", req.HTTPRequest.URL.String()) +} + +func TestGetMetadata(t *testing.T) { + server := initTestServer( + "/latest/meta-data/some/path", + "success", // real response includes suffix + ) + defer server.Close() + c := ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}) + + resp, err := c.GetMetadata("some/path") + + assert.NoError(t, err) + assert.Equal(t, "success", resp) +} + +func TestGetRegion(t *testing.T) { + server := initTestServer( + "/latest/meta-data/placement/availability-zone", + "us-west-2a", // real response includes suffix + ) + defer server.Close() + c := ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}) + + region, err := c.Region() + + assert.NoError(t, err) + assert.Equal(t, "us-west-2", region) +} + +func TestMetadataAvailable(t *testing.T) { + server := initTestServer( + "/latest/meta-data/instance-id", + "instance-id", + ) + defer server.Close() + c := ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}) + + available := c.Available() + + assert.True(t, available) +} + +func TestMetadataNotAvailable(t *testing.T) { + c := ec2metadata.New(nil) + c.Handlers.Send.Clear() + c.Handlers.Send.PushBack(func(r *request.Request) { + r.HTTPResponse = &http.Response{ + StatusCode: int(0), + Status: http.StatusText(int(0)), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + r.Error = awserr.New("RequestError", "send request failed", nil) + r.Retryable = aws.Bool(true) // network errors are retryable + }) + + available := c.Available() + + assert.False(t, available) +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go new file mode 100644 index 000000000000..d230df6f9fa3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go @@ -0,0 +1,135 @@ +package ec2metadata + +import ( + "io/ioutil" + "net/http" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" + "github.com/aws/aws-sdk-go/aws/service/serviceinfo" +) + +// DefaultRetries states the default number of times the service client will +// attempt to retry a failed request before failing. +const DefaultRetries = 3 + +// A Config provides the configuration for the EC2 Metadata service. +type Config struct { + // An optional endpoint URL (hostname only or fully qualified URI) + // that overrides the default service endpoint for a client. Set this + // to nil, or `""` to use the default service endpoint. + Endpoint *string + + // The HTTP client to use when sending requests. Defaults to + // `http.DefaultClient`. + HTTPClient *http.Client + + // An integer value representing the logging level. The default log level + // is zero (LogOff), which represents no logging. To enable logging set + // to a LogLevel Value. + Logger aws.Logger + + // The logger writer interface to write logging messages to. Defaults to + // standard out. + LogLevel *aws.LogLevelType + + // The maximum number of times that a request will be retried for failures. + // Defaults to DefaultRetries for the number of retries to be performed + // per request. + MaxRetries *int +} + +// A Client is an EC2 Metadata service Client. +type Client struct { + *service.Service +} + +// New creates a new instance of the EC2 Metadata service client. +// +// In the general use case the configuration for this service client should not +// be needed and `nil` can be provided. Configuration is only needed if the +// `ec2metadata.Config` defaults need to be overridden. Eg. Setting LogLevel. +// +// @note This configuration will NOT be merged with the default AWS service +// client configuration `defaults.DefaultConfig`. Due to circular dependencies +// with the defaults package and credentials EC2 Role Provider. +func New(config *Config) *Client { + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: copyConfig(config), + ServiceName: "Client", + Endpoint: "http://169.254.169.254/latest", + APIVersion: "latest", + }, + } + service.Initialize() + service.Handlers.Unmarshal.PushBack(unmarshalHandler) + service.Handlers.UnmarshalError.PushBack(unmarshalError) + service.Handlers.Validate.Clear() + service.Handlers.Validate.PushBack(validateEndpointHandler) + + return &Client{service} +} + +func copyConfig(config *Config) *aws.Config { + if config == nil { + config = &Config{} + } + c := &aws.Config{ + Credentials: credentials.AnonymousCredentials, + Endpoint: config.Endpoint, + HTTPClient: config.HTTPClient, + Logger: config.Logger, + LogLevel: config.LogLevel, + MaxRetries: config.MaxRetries, + } + + if c.HTTPClient == nil { + c.HTTPClient = http.DefaultClient + } + if c.Logger == nil { + c.Logger = aws.NewDefaultLogger() + } + if c.LogLevel == nil { + c.LogLevel = aws.LogLevel(aws.LogOff) + } + if c.MaxRetries == nil { + c.MaxRetries = aws.Int(DefaultRetries) + } + + return c +} + +type metadataOutput struct { + Content string +} + +func unmarshalHandler(r *request.Request) { + defer r.HTTPResponse.Body.Close() + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err) + } + + data := r.Data.(*metadataOutput) + data.Content = string(b) +} + +func unmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + _, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err) + } + + // TODO extract the error... +} + +func validateEndpointHandler(r *request.Request) { + if r.Service.Endpoint == "" { + r.Error = aws.ErrMissingEndpoint + } +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/errors.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/errors.go new file mode 100644 index 000000000000..db2f481b01bd --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/errors.go @@ -0,0 +1,17 @@ +package aws + +import "github.com/aws/aws-sdk-go/aws/awserr" + +var ( + // ErrMissingRegion is an error that is returned if region configuration is + // not found. + // + // @readonly + ErrMissingRegion error = awserr.New("MissingRegion", "could not find region configuration", nil) + + // ErrMissingEndpoint is an error that is returned if an endpoint cannot be + // resolved for a service. + // + // @readonly + ErrMissingEndpoint error = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil) +) diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handler_functions_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handler_functions_test.go deleted file mode 100644 index 822db9fe2070..000000000000 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handler_functions_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package aws - -import ( - "net/http" - "os" - "testing" - - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/internal/apierr" - "github.com/stretchr/testify/assert" -) - -func TestValidateEndpointHandler(t *testing.T) { - os.Clearenv() - svc := NewService(&Config{Region: "us-west-2"}) - svc.Handlers.Clear() - svc.Handlers.Validate.PushBack(ValidateEndpointHandler) - - req := NewRequest(svc, &Operation{Name: "Operation"}, nil, nil) - err := req.Build() - - assert.NoError(t, err) -} - -func TestValidateEndpointHandlerErrorRegion(t *testing.T) { - os.Clearenv() - svc := NewService(nil) - svc.Handlers.Clear() - svc.Handlers.Validate.PushBack(ValidateEndpointHandler) - - req := NewRequest(svc, &Operation{Name: "Operation"}, nil, nil) - err := req.Build() - - assert.Error(t, err) - assert.Equal(t, ErrMissingRegion, err) -} - -type mockCredsProvider struct { - expired bool - retreiveCalled bool -} - -func (m *mockCredsProvider) Retrieve() (credentials.Value, error) { - m.retreiveCalled = true - return credentials.Value{}, nil -} - -func (m *mockCredsProvider) IsExpired() bool { - return m.expired -} - -func TestAfterRetryRefreshCreds(t *testing.T) { - os.Clearenv() - credProvider := &mockCredsProvider{} - svc := NewService(&Config{Credentials: credentials.NewCredentials(credProvider), MaxRetries: 1}) - - svc.Handlers.Clear() - svc.Handlers.ValidateResponse.PushBack(func(r *Request) { - r.Error = apierr.New("UnknownError", "", nil) - r.HTTPResponse = &http.Response{StatusCode: 400} - }) - svc.Handlers.UnmarshalError.PushBack(func(r *Request) { - r.Error = apierr.New("ExpiredTokenException", "", nil) - }) - svc.Handlers.AfterRetry.PushBack(func(r *Request) { - AfterRetryHandler(r) - }) - - assert.True(t, svc.Config.Credentials.IsExpired(), "Expect to start out expired") - assert.False(t, credProvider.retreiveCalled) - - req := NewRequest(svc, &Operation{Name: "Operation"}, nil, nil) - req.Send() - - assert.True(t, svc.Config.Credentials.IsExpired()) - assert.False(t, credProvider.retreiveCalled) - - _, err := svc.Config.Credentials.Get() - assert.NoError(t, err) - assert.True(t, credProvider.retreiveCalled) -} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handlers_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handlers_test.go deleted file mode 100644 index 26776f6da6cb..000000000000 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handlers_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package aws - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestHandlerList(t *testing.T) { - s := "" - r := &Request{} - l := HandlerList{} - l.PushBack(func(r *Request) { - s += "a" - r.Data = s - }) - l.Run(r) - assert.Equal(t, "a", s) - assert.Equal(t, "a", r.Data) -} - -func TestMultipleHandlers(t *testing.T) { - r := &Request{} - l := HandlerList{} - l.PushBack(func(r *Request) { r.Data = nil }) - l.PushFront(func(r *Request) { r.Data = Boolean(true) }) - l.Run(r) - if r.Data != nil { - t.Error("Expected handler to execute") - } -} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/logger.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/logger.go new file mode 100644 index 000000000000..f5369487384e --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/logger.go @@ -0,0 +1,98 @@ +package aws + +import ( + "log" + "os" +) + +// A LogLevelType defines the level logging should be performed at. Used to instruct +// the SDK which statements should be logged. +type LogLevelType uint + +// LogLevel returns the pointer to a LogLevel. Should be used to workaround +// not being able to take the address of a non-composite literal. +func LogLevel(l LogLevelType) *LogLevelType { + return &l +} + +// Value returns the LogLevel value or the default value LogOff if the LogLevel +// is nil. Safe to use on nil value LogLevelTypes. +func (l *LogLevelType) Value() LogLevelType { + if l != nil { + return *l + } + return LogOff +} + +// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be +// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If +// LogLevel is nill, will default to LogOff comparison. +func (l *LogLevelType) Matches(v LogLevelType) bool { + c := l.Value() + return c&v == v +} + +// AtLeast returns true if this LogLevel is at least high enough to satisfies v. +// Is safe to use on nil value LogLevelTypes. If LogLevel is nill, will default +// to LogOff comparison. +func (l *LogLevelType) AtLeast(v LogLevelType) bool { + c := l.Value() + return c >= v +} + +const ( + // LogOff states that no logging should be performed by the SDK. This is the + // default state of the SDK, and should be use to disable all logging. + LogOff LogLevelType = iota * 0x1000 + + // LogDebug state that debug output should be logged by the SDK. This should + // be used to inspect request made and responses received. + LogDebug +) + +// Debug Logging Sub Levels +const ( + // LogDebugWithSigning states that the SDK should log request signing and + // presigning events. This should be used to log the signing details of + // requests for debugging. Will also enable LogDebug. + LogDebugWithSigning LogLevelType = LogDebug | (1 << iota) + + // LogDebugWithHTTPBody states the SDK should log HTTP request and response + // HTTP bodys in addition to the headers and path. This should be used to + // see the body content of requests and responses made while using the SDK + // Will also enable LogDebug. + LogDebugWithHTTPBody + + // LogDebugWithRequestRetries states the SDK should log when service requests will + // be retried. This should be used to log when you want to log when service + // requests are being retried. Will also enable LogDebug. + LogDebugWithRequestRetries + + // LogDebugWithRequestErrors states the SDK should log when service requests fail + // to build, send, validate, or unmarshal. + LogDebugWithRequestErrors +) + +// A Logger is a minimalistic interface for the SDK to log messages to. Should +// be used to provide custom logging writers for the SDK to use. +type Logger interface { + Log(...interface{}) +} + +// NewDefaultLogger returns a Logger which will write log messages to stdout, and +// use same formatting runes as the stdlib log.Logger +func NewDefaultLogger() Logger { + return &defaultLogger{ + logger: log.New(os.Stdout, "", log.LstdFlags), + } +} + +// A defaultLogger provides a minimalistic logger satisfying the Logger interface. +type defaultLogger struct { + logger *log.Logger +} + +// Log logs the parameters to the stdlib logger. See log.Println. +func (l defaultLogger) Log(args ...interface{}) { + l.logger.Println(args...) +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/param_validator.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/param_validator.go deleted file mode 100644 index 7c1377281dfa..000000000000 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/param_validator.go +++ /dev/null @@ -1,89 +0,0 @@ -package aws - -import ( - "fmt" - "reflect" - "strings" - - "github.com/aws/aws-sdk-go/internal/apierr" -) - -// ValidateParameters is a request handler to validate the input parameters. -// Validating parameters only has meaning if done prior to the request being sent. -func ValidateParameters(r *Request) { - if r.ParamsFilled() { - v := validator{errors: []string{}} - v.validateAny(reflect.ValueOf(r.Params), "") - - if count := len(v.errors); count > 0 { - format := "%d validation errors:\n- %s" - msg := fmt.Sprintf(format, count, strings.Join(v.errors, "\n- ")) - r.Error = apierr.New("InvalidParameter", msg, nil) - } - } -} - -// A validator validates values. Collects validations errors which occurs. -type validator struct { - errors []string -} - -// validateAny will validate any struct, slice or map type. All validations -// are also performed recursively for nested types. -func (v *validator) validateAny(value reflect.Value, path string) { - value = reflect.Indirect(value) - if !value.IsValid() { - return - } - - switch value.Kind() { - case reflect.Struct: - v.validateStruct(value, path) - case reflect.Slice: - for i := 0; i < value.Len(); i++ { - v.validateAny(value.Index(i), path+fmt.Sprintf("[%d]", i)) - } - case reflect.Map: - for _, n := range value.MapKeys() { - v.validateAny(value.MapIndex(n), path+fmt.Sprintf("[%q]", n.String())) - } - } -} - -// validateStruct will validate the struct value's fields. If the structure has -// nested types those types will be validated also. -func (v *validator) validateStruct(value reflect.Value, path string) { - prefix := "." - if path == "" { - prefix = "" - } - - for i := 0; i < value.Type().NumField(); i++ { - f := value.Type().Field(i) - if strings.ToLower(f.Name[0:1]) == f.Name[0:1] { - continue - } - fvalue := value.FieldByName(f.Name) - - notset := false - if f.Tag.Get("required") != "" { - switch fvalue.Kind() { - case reflect.Ptr, reflect.Slice, reflect.Map: - if fvalue.IsNil() { - notset = true - } - default: - if !fvalue.IsValid() { - notset = true - } - } - } - - if notset { - msg := "missing required parameter: " + path + prefix + f.Name - v.errors = append(v.errors, msg) - } else { - v.validateAny(fvalue, path+prefix+f.Name) - } - } -} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/param_validator_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/param_validator_test.go deleted file mode 100644 index 66515673070b..000000000000 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/param_validator_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package aws_test - -import ( - "testing" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/stretchr/testify/assert" -) - -var service = func() *aws.Service { - s := &aws.Service{ - Config: &aws.Config{}, - ServiceName: "mock-service", - APIVersion: "2015-01-01", - } - return s -}() - -type StructShape struct { - RequiredList []*ConditionalStructShape `required:"true"` - RequiredMap map[string]*ConditionalStructShape `required:"true"` - RequiredBool *bool `required:"true"` - OptionalStruct *ConditionalStructShape - - hiddenParameter *string - - metadataStructureShape -} - -type metadataStructureShape struct { - SDKShapeTraits bool -} - -type ConditionalStructShape struct { - Name *string `required:"true"` - SDKShapeTraits bool -} - -func TestNoErrors(t *testing.T) { - input := &StructShape{ - RequiredList: []*ConditionalStructShape{}, - RequiredMap: map[string]*ConditionalStructShape{ - "key1": &ConditionalStructShape{Name: aws.String("Name")}, - "key2": &ConditionalStructShape{Name: aws.String("Name")}, - }, - RequiredBool: aws.Boolean(true), - OptionalStruct: &ConditionalStructShape{Name: aws.String("Name")}, - } - - req := aws.NewRequest(service, &aws.Operation{}, input, nil) - aws.ValidateParameters(req) - assert.NoError(t, req.Error) -} - -func TestMissingRequiredParameters(t *testing.T) { - input := &StructShape{} - req := aws.NewRequest(service, &aws.Operation{}, input, nil) - aws.ValidateParameters(req) - - assert.Error(t, req.Error) - assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code()) - assert.Equal(t, "3 validation errors:\n- missing required parameter: RequiredList\n- missing required parameter: RequiredMap\n- missing required parameter: RequiredBool", req.Error.(awserr.Error).Message()) -} - -func TestNestedMissingRequiredParameters(t *testing.T) { - input := &StructShape{ - RequiredList: []*ConditionalStructShape{&ConditionalStructShape{}}, - RequiredMap: map[string]*ConditionalStructShape{ - "key1": &ConditionalStructShape{Name: aws.String("Name")}, - "key2": &ConditionalStructShape{}, - }, - RequiredBool: aws.Boolean(true), - OptionalStruct: &ConditionalStructShape{}, - } - - req := aws.NewRequest(service, &aws.Operation{}, input, nil) - aws.ValidateParameters(req) - - assert.Error(t, req.Error) - assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code()) - assert.Equal(t, "3 validation errors:\n- missing required parameter: RequiredList[0].Name\n- missing required parameter: RequiredMap[\"key2\"].Name\n- missing required parameter: OptionalStruct.Name", req.Error.(awserr.Error).Message()) - -} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handlers.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers.go similarity index 57% rename from Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handlers.go rename to Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers.go index 1968cb9f8b1d..85bc122e7b3e 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/handlers.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers.go @@ -1,4 +1,4 @@ -package aws +package request // A Handlers provides a collection of request handlers for various // stages of handling requests. @@ -15,8 +15,8 @@ type Handlers struct { AfterRetry HandlerList } -// copy returns of this handler's lists. -func (h *Handlers) copy() Handlers { +// Copy returns of this handler's lists. +func (h *Handlers) Copy() Handlers { return Handlers{ Validate: h.Validate.copy(), Build: h.Build.copy(), @@ -47,19 +47,25 @@ func (h *Handlers) Clear() { // A HandlerList manages zero or more handlers in a list. type HandlerList struct { - list []func(*Request) + list []NamedHandler +} + +// A NamedHandler is a struct that contains a name and function callback. +type NamedHandler struct { + Name string + Fn func(*Request) } // copy creates a copy of the handler list. func (l *HandlerList) copy() HandlerList { var n HandlerList - n.list = append([]func(*Request){}, l.list...) + n.list = append([]NamedHandler{}, l.list...) return n } // Clear clears the handler list. func (l *HandlerList) Clear() { - l.list = []func(*Request){} + l.list = []NamedHandler{} } // Len returns the number of handlers in the list. @@ -67,19 +73,40 @@ func (l *HandlerList) Len() int { return len(l.list) } -// PushBack pushes handlers f to the back of the handler list. -func (l *HandlerList) PushBack(f ...func(*Request)) { - l.list = append(l.list, f...) +// PushBack pushes handler f to the back of the handler list. +func (l *HandlerList) PushBack(f func(*Request)) { + l.list = append(l.list, NamedHandler{"__anonymous", f}) } -// PushFront pushes handlers f to the front of the handler list. -func (l *HandlerList) PushFront(f ...func(*Request)) { - l.list = append(f, l.list...) +// PushFront pushes handler f to the front of the handler list. +func (l *HandlerList) PushFront(f func(*Request)) { + l.list = append([]NamedHandler{{"__anonymous", f}}, l.list...) +} + +// PushBackNamed pushes named handler f to the back of the handler list. +func (l *HandlerList) PushBackNamed(n NamedHandler) { + l.list = append(l.list, n) +} + +// PushFrontNamed pushes named handler f to the front of the handler list. +func (l *HandlerList) PushFrontNamed(n NamedHandler) { + l.list = append([]NamedHandler{n}, l.list...) +} + +// Remove removes a NamedHandler n +func (l *HandlerList) Remove(n NamedHandler) { + newlist := []NamedHandler{} + for _, m := range l.list { + if m.Name != n.Name { + newlist = append(newlist, m) + } + } + l.list = newlist } // Run executes all handlers in the list with a given request object. func (l *HandlerList) Run(r *Request) { for _, f := range l.list { - f(r) + f.Fn(r) } } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers_test.go new file mode 100644 index 000000000000..2ff05a8154e7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers_test.go @@ -0,0 +1,47 @@ +package request_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" +) + +func TestHandlerList(t *testing.T) { + s := "" + r := &request.Request{} + l := request.HandlerList{} + l.PushBack(func(r *request.Request) { + s += "a" + r.Data = s + }) + l.Run(r) + assert.Equal(t, "a", s) + assert.Equal(t, "a", r.Data) +} + +func TestMultipleHandlers(t *testing.T) { + r := &request.Request{} + l := request.HandlerList{} + l.PushBack(func(r *request.Request) { r.Data = nil }) + l.PushFront(func(r *request.Request) { r.Data = aws.Bool(true) }) + l.Run(r) + if r.Data != nil { + t.Error("Expected handler to execute") + } +} + +func TestNamedHandlers(t *testing.T) { + l := request.HandlerList{} + named := request.NamedHandler{"Name", func(r *request.Request) {}} + named2 := request.NamedHandler{"NotName", func(r *request.Request) {}} + l.PushBackNamed(named) + l.PushBackNamed(named) + l.PushBackNamed(named2) + l.PushBack(func(r *request.Request) {}) + assert.Equal(t, 4, l.Len()) + l.Remove(named) + assert.Equal(t, 2, l.Len()) +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request.go similarity index 79% rename from Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request.go rename to Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request.go index df5885fcb4b7..70c28b883164 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request.go @@ -1,7 +1,8 @@ -package aws +package request import ( "bytes" + "fmt" "io" "io/ioutil" "net/http" @@ -10,12 +11,15 @@ import ( "strings" "time" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/service/serviceinfo" ) // A Request is the service request to be made. type Request struct { - *Service + Retryer + Service serviceinfo.ServiceInfo Handlers Handlers Time time.Time ExpireTime time.Duration @@ -23,17 +27,16 @@ type Request struct { HTTPRequest *http.Request HTTPResponse *http.Response Body io.ReadSeeker - bodyStart int64 // offset from beginning of Body that the request body starts + BodyStart int64 // offset from beginning of Body that the request body starts Params interface{} Error error Data interface{} RequestID string RetryCount uint - Retryable SettableBool + Retryable *bool RetryDelay time.Duration - built bool - signed bool + built bool } // An Operation is the service API operation to be made. @@ -52,13 +55,13 @@ type Paginator struct { TruncationToken string } -// NewRequest returns a new Request pointer for the service API +// New returns a new Request pointer for the service API // operation and parameters. // // Params is any value of input parameters to be the request payload. // Data is pointer value to an object which the request's response // payload will be deserialized to. -func NewRequest(service *Service, operation *Operation, params interface{}, data interface{}) *Request { +func New(service serviceinfo.ServiceInfo, handlers Handlers, retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request { method := operation.HTTPMethod if method == "" { method = "POST" @@ -72,8 +75,9 @@ func NewRequest(service *Service, operation *Operation, params interface{}, data httpReq.URL, _ = url.Parse(service.Endpoint + p) r := &Request{ + Retryer: retryer, Service: service, - Handlers: service.Handlers.copy(), + Handlers: handlers.Copy(), Time: time.Now(), ExpireTime: 0, Operation: operation, @@ -90,7 +94,7 @@ func NewRequest(service *Service, operation *Operation, params interface{}, data // WillRetry returns if the request's can be retried. func (r *Request) WillRetry() bool { - return r.Error != nil && r.Retryable.Get() && r.RetryCount < r.Service.MaxRetries() + return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries() } // ParamsFilled returns if the request's parameters have been populated @@ -135,6 +139,20 @@ func (r *Request) Presign(expireTime time.Duration) (string, error) { return r.HTTPRequest.URL.String(), nil } +func debugLogReqError(r *Request, stage string, retrying bool, err error) { + if !r.Service.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) { + return + } + + retryStr := "not retrying" + if retrying { + retryStr = "will retry" + } + + r.Service.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v", + stage, r.Service.ServiceName, r.Operation.Name, retryStr, err)) +} + // Build will build the request's object so it can be signed and sent // to the service. Build will also validate all the request's parameters. // Anny additional build Handlers set on this request will be run @@ -150,6 +168,7 @@ func (r *Request) Build() error { r.Error = nil r.Handlers.Validate.Run(r) if r.Error != nil { + debugLogReqError(r, "Validate Request", false, r.Error) return r.Error } r.Handlers.Build.Run(r) @@ -164,17 +183,13 @@ func (r *Request) Build() error { // Send will build the request prior to signing. All Sign Handlers will // be executed in the order they were set. func (r *Request) Sign() error { - if r.signed { - return r.Error - } - r.Build() if r.Error != nil { + debugLogReqError(r, "Build Request", false, r.Error) return r.Error } r.Handlers.Sign.Run(r) - r.signed = r.Error != nil return r.Error } @@ -189,42 +204,57 @@ func (r *Request) Send() error { return r.Error } - if r.Retryable.Get() { + if aws.BoolValue(r.Retryable) { + if r.Service.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) { + r.Service.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d", + r.Service.ServiceName, r.Operation.Name, r.RetryCount)) + } + // Re-seek the body back to the original point in for a retry so that // send will send the body's contents again in the upcoming request. - r.Body.Seek(r.bodyStart, 0) + r.Body.Seek(r.BodyStart, 0) + r.HTTPRequest.Body = ioutil.NopCloser(r.Body) } - r.Retryable.Reset() + r.Retryable = nil r.Handlers.Send.Run(r) if r.Error != nil { + err := r.Error r.Handlers.Retry.Run(r) r.Handlers.AfterRetry.Run(r) if r.Error != nil { + debugLogReqError(r, "Send Request", false, r.Error) return r.Error } + debugLogReqError(r, "Send Request", true, err) continue } r.Handlers.UnmarshalMeta.Run(r) r.Handlers.ValidateResponse.Run(r) if r.Error != nil { + err := r.Error r.Handlers.UnmarshalError.Run(r) r.Handlers.Retry.Run(r) r.Handlers.AfterRetry.Run(r) if r.Error != nil { + debugLogReqError(r, "Validate Response", false, r.Error) return r.Error } + debugLogReqError(r, "Validate Response", true, err) continue } r.Handlers.Unmarshal.Run(r) if r.Error != nil { + err := r.Error r.Handlers.Retry.Run(r) r.Handlers.AfterRetry.Run(r) if r.Error != nil { + debugLogReqError(r, "Unmarshal Response", false, r.Error) return r.Error } + debugLogReqError(r, "Unmarshal Response", true, err) continue } @@ -285,7 +315,7 @@ func (r *Request) NextPage() *Request { } data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface() - nr := NewRequest(r.Service, r.Operation, awsutil.CopyOf(r.Params), data) + nr := New(r.Service, r.Handlers, r.Retryer, r.Operation, awsutil.CopyOf(r.Params), data) for i, intok := range nr.Operation.InputTokens { awsutil.SetValueAtAnyPath(nr.Params, intok, tokens[i]) } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request_pagination_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go similarity index 59% rename from Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request_pagination_test.go rename to Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go index eabd9aea7a4a..c0f151eeea6b 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request_pagination_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go @@ -1,13 +1,15 @@ -package aws_test +package request_test import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/internal/test/unit" "github.com/aws/aws-sdk-go/service/dynamodb" "github.com/aws/aws-sdk-go/service/s3" - "github.com/stretchr/testify/assert" ) var _ = unit.Imported @@ -19,16 +21,16 @@ func TestPagination(t *testing.T) { reqNum := 0 resps := []*dynamodb.ListTablesOutput{ - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("Table5")}}, + {TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")}, + {TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")}, + {TableNames: []*string{aws.String("Table5")}}, } db.Handlers.Send.Clear() // mock sending db.Handlers.Unmarshal.Clear() db.Handlers.UnmarshalMeta.Clear() db.Handlers.ValidateResponse.Clear() - db.Handlers.Build.PushBack(func(r *aws.Request) { + db.Handlers.Build.PushBack(func(r *request.Request) { in := r.Params.(*dynamodb.ListTablesInput) if in == nil { tokens = append(tokens, "") @@ -36,12 +38,12 @@ func TestPagination(t *testing.T) { tokens = append(tokens, *in.ExclusiveStartTableName) } }) - db.Handlers.Unmarshal.PushBack(func(r *aws.Request) { + db.Handlers.Unmarshal.PushBack(func(r *request.Request) { r.Data = resps[reqNum] reqNum++ }) - params := &dynamodb.ListTablesInput{Limit: aws.Long(2)} + params := &dynamodb.ListTablesInput{Limit: aws.Int64(2)} err := db.ListTablesPages(params, func(p *dynamodb.ListTablesOutput, last bool) bool { numPages++ for _, t := range p.TableNames { @@ -71,16 +73,16 @@ func TestPaginationEachPage(t *testing.T) { reqNum := 0 resps := []*dynamodb.ListTablesOutput{ - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("Table5")}}, + {TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")}, + {TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")}, + {TableNames: []*string{aws.String("Table5")}}, } db.Handlers.Send.Clear() // mock sending db.Handlers.Unmarshal.Clear() db.Handlers.UnmarshalMeta.Clear() db.Handlers.ValidateResponse.Clear() - db.Handlers.Build.PushBack(func(r *aws.Request) { + db.Handlers.Build.PushBack(func(r *request.Request) { in := r.Params.(*dynamodb.ListTablesInput) if in == nil { tokens = append(tokens, "") @@ -88,12 +90,12 @@ func TestPaginationEachPage(t *testing.T) { tokens = append(tokens, *in.ExclusiveStartTableName) } }) - db.Handlers.Unmarshal.PushBack(func(r *aws.Request) { + db.Handlers.Unmarshal.PushBack(func(r *request.Request) { r.Data = resps[reqNum] reqNum++ }) - params := &dynamodb.ListTablesInput{Limit: aws.Long(2)} + params := &dynamodb.ListTablesInput{Limit: aws.Int64(2)} req, _ := db.ListTablesRequest(params) err := req.EachPage(func(p interface{}, last bool) bool { numPages++ @@ -124,21 +126,21 @@ func TestPaginationEarlyExit(t *testing.T) { reqNum := 0 resps := []*dynamodb.ListTablesOutput{ - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("Table5")}}, + {TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")}, + {TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")}, + {TableNames: []*string{aws.String("Table5")}}, } db.Handlers.Send.Clear() // mock sending db.Handlers.Unmarshal.Clear() db.Handlers.UnmarshalMeta.Clear() db.Handlers.ValidateResponse.Clear() - db.Handlers.Unmarshal.PushBack(func(r *aws.Request) { + db.Handlers.Unmarshal.PushBack(func(r *request.Request) { r.Data = resps[reqNum] reqNum++ }) - params := &dynamodb.ListTablesInput{Limit: aws.Long(2)} + params := &dynamodb.ListTablesInput{Limit: aws.Int64(2)} err := db.ListTablesPages(params, func(p *dynamodb.ListTablesOutput, last bool) bool { numPages++ if numPages == 2 { @@ -164,7 +166,7 @@ func TestSkipPagination(t *testing.T) { client.Handlers.Unmarshal.Clear() client.Handlers.UnmarshalMeta.Clear() client.Handlers.ValidateResponse.Clear() - client.Handlers.Unmarshal.PushBack(func(r *aws.Request) { + client.Handlers.Unmarshal.PushBack(func(r *request.Request) { r.Data = &s3.HeadBucketOutput{} }) @@ -189,17 +191,17 @@ func TestPaginationTruncation(t *testing.T) { reqNum := &count resps := []*s3.ListObjectsOutput{ - &s3.ListObjectsOutput{IsTruncated: aws.Boolean(true), Contents: []*s3.Object{&s3.Object{Key: aws.String("Key1")}}}, - &s3.ListObjectsOutput{IsTruncated: aws.Boolean(true), Contents: []*s3.Object{&s3.Object{Key: aws.String("Key2")}}}, - &s3.ListObjectsOutput{IsTruncated: aws.Boolean(false), Contents: []*s3.Object{&s3.Object{Key: aws.String("Key3")}}}, - &s3.ListObjectsOutput{IsTruncated: aws.Boolean(true), Contents: []*s3.Object{&s3.Object{Key: aws.String("Key4")}}}, + {IsTruncated: aws.Bool(true), Contents: []*s3.Object{{Key: aws.String("Key1")}}}, + {IsTruncated: aws.Bool(true), Contents: []*s3.Object{{Key: aws.String("Key2")}}}, + {IsTruncated: aws.Bool(false), Contents: []*s3.Object{{Key: aws.String("Key3")}}}, + {IsTruncated: aws.Bool(true), Contents: []*s3.Object{{Key: aws.String("Key4")}}}, } client.Handlers.Send.Clear() // mock sending client.Handlers.Unmarshal.Clear() client.Handlers.UnmarshalMeta.Clear() client.Handlers.ValidateResponse.Clear() - client.Handlers.Unmarshal.PushBack(func(r *aws.Request) { + client.Handlers.Unmarshal.PushBack(func(r *request.Request) { r.Data = resps[*reqNum] *reqNum++ }) @@ -218,7 +220,7 @@ func TestPaginationTruncation(t *testing.T) { // Try again without truncation token at all count = 0 resps[1].IsTruncated = nil - resps[2].IsTruncated = aws.Boolean(true) + resps[2].IsTruncated = aws.Bool(true) results = []string{} err = client.ListObjectsPages(params, func(p *s3.ListObjectsOutput, last bool) bool { results = append(results, *p.Contents[0].Key) @@ -232,20 +234,20 @@ func TestPaginationTruncation(t *testing.T) { // Benchmarks var benchResps = []*dynamodb.ListTablesOutput{ - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, - &dynamodb.ListTablesOutput{TableNames: []*string{aws.String("TABLE")}}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, + {TableNames: []*string{aws.String("TABLE")}}, } var benchDb = func() *dynamodb.DynamoDB { @@ -260,12 +262,12 @@ var benchDb = func() *dynamodb.DynamoDB { func BenchmarkCodegenIterator(b *testing.B) { reqNum := 0 db := benchDb() - db.Handlers.Unmarshal.PushBack(func(r *aws.Request) { + db.Handlers.Unmarshal.PushBack(func(r *request.Request) { r.Data = benchResps[reqNum] reqNum++ }) - input := &dynamodb.ListTablesInput{Limit: aws.Long(2)} + input := &dynamodb.ListTablesInput{Limit: aws.Int64(2)} iter := func(fn func(*dynamodb.ListTablesOutput, bool) bool) error { page, _ := db.ListTablesRequest(input) for ; page != nil; page = page.NextPage() { @@ -289,12 +291,12 @@ func BenchmarkCodegenIterator(b *testing.B) { func BenchmarkEachPageIterator(b *testing.B) { reqNum := 0 db := benchDb() - db.Handlers.Unmarshal.PushBack(func(r *aws.Request) { + db.Handlers.Unmarshal.PushBack(func(r *request.Request) { r.Data = benchResps[reqNum] reqNum++ }) - input := &dynamodb.ListTablesInput{Limit: aws.Long(2)} + input := &dynamodb.ListTablesInput{Limit: aws.Int64(2)} for i := 0; i < b.N; i++ { reqNum = 0 req, _ := db.ListTablesRequest(input) diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_test.go similarity index 58% rename from Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request_test.go rename to Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_test.go index 27507f039d3e..6cea0bd2fffb 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_test.go @@ -1,4 +1,4 @@ -package aws +package request_test import ( "bytes" @@ -7,13 +7,14 @@ import ( "io" "io/ioutil" "net/http" - "reflect" "testing" "time" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" "github.com/stretchr/testify/assert" ) @@ -25,7 +26,7 @@ func body(str string) io.ReadCloser { return ioutil.NopCloser(bytes.NewReader([]byte(str))) } -func unmarshal(req *Request) { +func unmarshal(req *request.Request) { defer req.HTTPResponse.Body.Close() if req.Data != nil { json.NewDecoder(req.HTTPResponse.Body).Decode(req.Data) @@ -33,15 +34,15 @@ func unmarshal(req *Request) { return } -func unmarshalError(req *Request) { +func unmarshalError(req *request.Request) { bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body) if err != nil { - req.Error = apierr.New("UnmarshaleError", req.HTTPResponse.Status, err) + req.Error = awserr.New("UnmarshaleError", req.HTTPResponse.Status, err) return } if len(bodyBytes) == 0 { - req.Error = apierr.NewRequestError( - apierr.New("UnmarshaleError", req.HTTPResponse.Status, fmt.Errorf("empty body")), + req.Error = awserr.NewRequestFailure( + awserr.New("UnmarshaleError", req.HTTPResponse.Status, fmt.Errorf("empty body")), req.HTTPResponse.StatusCode, "", ) @@ -49,11 +50,11 @@ func unmarshalError(req *Request) { } var jsonErr jsonErrorResponse if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil { - req.Error = apierr.New("UnmarshaleError", "JSON unmarshal", err) + req.Error = awserr.New("UnmarshaleError", "JSON unmarshal", err) return } - req.Error = apierr.NewRequestError( - apierr.New(jsonErr.Code, jsonErr.Message, nil), + req.Error = awserr.NewRequestFailure( + awserr.New(jsonErr.Code, jsonErr.Message, nil), req.HTTPResponse.StatusCode, "", ) @@ -68,22 +69,22 @@ type jsonErrorResponse struct { func TestRequestRecoverRetry5xx(t *testing.T) { reqNum := 0 reqs := []http.Response{ - http.Response{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, - http.Response{StatusCode: 501, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, - http.Response{StatusCode: 200, Body: body(`{"data":"valid"}`)}, + {StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, + {StatusCode: 501, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, + {StatusCode: 200, Body: body(`{"data":"valid"}`)}, } - s := NewService(&Config{MaxRetries: 10}) + s := service.New(aws.NewConfig().WithMaxRetries(10)) s.Handlers.Validate.Clear() s.Handlers.Unmarshal.PushBack(unmarshal) s.Handlers.UnmarshalError.PushBack(unmarshalError) s.Handlers.Send.Clear() // mock sending - s.Handlers.Send.PushBack(func(r *Request) { + s.Handlers.Send.PushBack(func(r *request.Request) { r.HTTPResponse = &reqs[reqNum] reqNum++ }) out := &testData{} - r := NewRequest(s, &Operation{Name: "Operation"}, nil, out) + r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) err := r.Send() assert.Nil(t, err) assert.Equal(t, 2, int(r.RetryCount)) @@ -94,22 +95,22 @@ func TestRequestRecoverRetry5xx(t *testing.T) { func TestRequestRecoverRetry4xxRetryable(t *testing.T) { reqNum := 0 reqs := []http.Response{ - http.Response{StatusCode: 400, Body: body(`{"__type":"Throttling","message":"Rate exceeded."}`)}, - http.Response{StatusCode: 429, Body: body(`{"__type":"ProvisionedThroughputExceededException","message":"Rate exceeded."}`)}, - http.Response{StatusCode: 200, Body: body(`{"data":"valid"}`)}, + {StatusCode: 400, Body: body(`{"__type":"Throttling","message":"Rate exceeded."}`)}, + {StatusCode: 429, Body: body(`{"__type":"ProvisionedThroughputExceededException","message":"Rate exceeded."}`)}, + {StatusCode: 200, Body: body(`{"data":"valid"}`)}, } - s := NewService(&Config{MaxRetries: 10}) + s := service.New(aws.NewConfig().WithMaxRetries(10)) s.Handlers.Validate.Clear() s.Handlers.Unmarshal.PushBack(unmarshal) s.Handlers.UnmarshalError.PushBack(unmarshalError) s.Handlers.Send.Clear() // mock sending - s.Handlers.Send.PushBack(func(r *Request) { + s.Handlers.Send.PushBack(func(r *request.Request) { r.HTTPResponse = &reqs[reqNum] reqNum++ }) out := &testData{} - r := NewRequest(s, &Operation{Name: "Operation"}, nil, out) + r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) err := r.Send() assert.Nil(t, err) assert.Equal(t, 2, int(r.RetryCount)) @@ -118,16 +119,16 @@ func TestRequestRecoverRetry4xxRetryable(t *testing.T) { // test that retries don't occur for 4xx status codes with a response type that can't be retried func TestRequest4xxUnretryable(t *testing.T) { - s := NewService(&Config{MaxRetries: 10}) + s := service.New(aws.NewConfig().WithMaxRetries(10)) s.Handlers.Validate.Clear() s.Handlers.Unmarshal.PushBack(unmarshal) s.Handlers.UnmarshalError.PushBack(unmarshalError) s.Handlers.Send.Clear() // mock sending - s.Handlers.Send.PushBack(func(r *Request) { + s.Handlers.Send.PushBack(func(r *request.Request) { r.HTTPResponse = &http.Response{StatusCode: 401, Body: body(`{"__type":"SignatureDoesNotMatch","message":"Signature does not match."}`)} }) out := &testData{} - r := NewRequest(s, &Operation{Name: "Operation"}, nil, out) + r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) err := r.Send() assert.NotNil(t, err) if e, ok := err.(awserr.RequestFailure); ok { @@ -142,28 +143,28 @@ func TestRequest4xxUnretryable(t *testing.T) { func TestRequestExhaustRetries(t *testing.T) { delays := []time.Duration{} - sleepDelay = func(delay time.Duration) { + sleepDelay := func(delay time.Duration) { delays = append(delays, delay) } reqNum := 0 reqs := []http.Response{ - http.Response{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, - http.Response{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, - http.Response{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, - http.Response{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, + {StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, + {StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, + {StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, + {StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)}, } - s := NewService(&Config{MaxRetries: -1}) + s := service.New(aws.NewConfig().WithMaxRetries(aws.DefaultRetries).WithSleepDelay(sleepDelay)) s.Handlers.Validate.Clear() s.Handlers.Unmarshal.PushBack(unmarshal) s.Handlers.UnmarshalError.PushBack(unmarshalError) s.Handlers.Send.Clear() // mock sending - s.Handlers.Send.PushBack(func(r *Request) { + s.Handlers.Send.PushBack(func(r *request.Request) { r.HTTPResponse = &reqs[reqNum] reqNum++ }) - r := NewRequest(s, &Operation{Name: "Operation"}, nil, nil) + r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) err := r.Send() assert.NotNil(t, err) if e, ok := err.(awserr.RequestFailure); ok { @@ -174,18 +175,25 @@ func TestRequestExhaustRetries(t *testing.T) { assert.Equal(t, "UnknownError", err.(awserr.Error).Code()) assert.Equal(t, "An error occurred.", err.(awserr.Error).Message()) assert.Equal(t, 3, int(r.RetryCount)) - assert.True(t, reflect.DeepEqual([]time.Duration{30 * time.Millisecond, 60 * time.Millisecond, 120 * time.Millisecond}, delays)) + + expectDelays := []struct{ min, max time.Duration }{{30, 59}, {60, 118}, {120, 236}} + for i, v := range delays { + min := expectDelays[i].min * time.Millisecond + max := expectDelays[i].max * time.Millisecond + assert.True(t, min <= v && v <= max, + "Expect delay to be within range, i:%d, v:%s, min:%s, max:%s", i, v, min, max) + } } // test that the request is retried after the credentials are expired. func TestRequestRecoverExpiredCreds(t *testing.T) { reqNum := 0 reqs := []http.Response{ - http.Response{StatusCode: 400, Body: body(`{"__type":"ExpiredTokenException","message":"expired token"}`)}, - http.Response{StatusCode: 200, Body: body(`{"data":"valid"}`)}, + {StatusCode: 400, Body: body(`{"__type":"ExpiredTokenException","message":"expired token"}`)}, + {StatusCode: 200, Body: body(`{"data":"valid"}`)}, } - s := NewService(&Config{MaxRetries: 10, Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "")}) + s := service.New(&aws.Config{MaxRetries: aws.Int(10), Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "")}) s.Handlers.Validate.Clear() s.Handlers.Unmarshal.PushBack(unmarshal) s.Handlers.UnmarshalError.PushBack(unmarshalError) @@ -193,21 +201,21 @@ func TestRequestRecoverExpiredCreds(t *testing.T) { credExpiredBeforeRetry := false credExpiredAfterRetry := false - s.Handlers.AfterRetry.PushBack(func(r *Request) { - credExpiredAfterRetry = r.Config.Credentials.IsExpired() + s.Handlers.AfterRetry.PushBack(func(r *request.Request) { + credExpiredAfterRetry = r.Service.Config.Credentials.IsExpired() }) s.Handlers.Sign.Clear() - s.Handlers.Sign.PushBack(func(r *Request) { - r.Config.Credentials.Get() + s.Handlers.Sign.PushBack(func(r *request.Request) { + r.Service.Config.Credentials.Get() }) s.Handlers.Send.Clear() // mock sending - s.Handlers.Send.PushBack(func(r *Request) { + s.Handlers.Send.PushBack(func(r *request.Request) { r.HTTPResponse = &reqs[reqNum] reqNum++ }) out := &testData{} - r := NewRequest(s, &Operation{Name: "Operation"}, nil, out) + r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) err := r.Send() assert.Nil(t, err) diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/retryer.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/retryer.go new file mode 100644 index 000000000000..f03b0c659607 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/retryer.go @@ -0,0 +1,71 @@ +package request + +import ( + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// Retryer is an interface to control retry logic for a given service. +// The default implementation used by most services is the service.DefaultRetryer +// structure, which contains basic retry logic using exponential backoff. +type Retryer interface { + RetryRules(*Request) time.Duration + ShouldRetry(*Request) bool + MaxRetries() uint +} + +// retryableCodes is a collection of service response codes which are retry-able +// without any further action. +var retryableCodes = map[string]struct{}{ + "RequestError": {}, + "ProvisionedThroughputExceededException": {}, + "Throttling": {}, + "ThrottlingException": {}, + "RequestLimitExceeded": {}, + "RequestThrottled": {}, +} + +// credsExpiredCodes is a collection of error codes which signify the credentials +// need to be refreshed. Expired tokens require refreshing of credentials, and +// resigning before the request can be retried. +var credsExpiredCodes = map[string]struct{}{ + "ExpiredToken": {}, + "ExpiredTokenException": {}, + "RequestExpired": {}, // EC2 Only +} + +func isCodeRetryable(code string) bool { + if _, ok := retryableCodes[code]; ok { + return true + } + + return isCodeExpiredCreds(code) +} + +func isCodeExpiredCreds(code string) bool { + _, ok := credsExpiredCodes[code] + return ok +} + +// IsErrorRetryable returns whether the error is retryable, based on its Code. +// Returns false if the request has no Error set. +func (r *Request) IsErrorRetryable() bool { + if r.Error != nil { + if err, ok := r.Error.(awserr.Error); ok { + return isCodeRetryable(err.Code()) + } + } + return false +} + +// IsErrorExpired returns whether the error code is a credential expiry error. +// Returns false if the request has no Error set. +func (r *Request) IsErrorExpired() bool { + if r.Error != nil { + if err, ok := r.Error.(awserr.Error); ok { + return isCodeExpiredCreds(err.Code()) + } + } + return false +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service.go deleted file mode 100644 index 7e8e229ba4f2..000000000000 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service.go +++ /dev/null @@ -1,177 +0,0 @@ -package aws - -import ( - "fmt" - "math" - "net/http" - "net/http/httputil" - "regexp" - "time" - - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/internal/endpoints" -) - -// A Service implements the base service request and response handling -// used by all services. -type Service struct { - Config *Config - Handlers Handlers - ManualSend bool - ServiceName string - APIVersion string - Endpoint string - SigningName string - SigningRegion string - JSONVersion string - TargetPrefix string - RetryRules func(*Request) time.Duration - ShouldRetry func(*Request) bool - DefaultMaxRetries uint -} - -var schemeRE = regexp.MustCompile("^([^:]+)://") - -// NewService will return a pointer to a new Server object initialized. -func NewService(config *Config) *Service { - svc := &Service{Config: config} - svc.Initialize() - return svc -} - -// Initialize initializes the service. -func (s *Service) Initialize() { - if s.Config == nil { - s.Config = &Config{} - } - if s.Config.HTTPClient == nil { - s.Config.HTTPClient = http.DefaultClient - } - - if s.RetryRules == nil { - s.RetryRules = retryRules - } - - if s.ShouldRetry == nil { - s.ShouldRetry = shouldRetry - } - - s.DefaultMaxRetries = 3 - s.Handlers.Validate.PushBack(ValidateEndpointHandler) - s.Handlers.Build.PushBack(UserAgentHandler) - s.Handlers.Sign.PushBack(BuildContentLength) - s.Handlers.Send.PushBack(SendHandler) - s.Handlers.AfterRetry.PushBack(AfterRetryHandler) - s.Handlers.ValidateResponse.PushBack(ValidateResponseHandler) - s.AddDebugHandlers() - s.buildEndpoint() - - if !s.Config.DisableParamValidation { - s.Handlers.Validate.PushBack(ValidateParameters) - } -} - -// buildEndpoint builds the endpoint values the service will use to make requests with. -func (s *Service) buildEndpoint() { - if s.Config.Endpoint != "" { - s.Endpoint = s.Config.Endpoint - } else { - s.Endpoint, s.SigningRegion = - endpoints.EndpointForRegion(s.ServiceName, s.Config.Region) - } - - if s.Endpoint != "" && !schemeRE.MatchString(s.Endpoint) { - scheme := "https" - if s.Config.DisableSSL { - scheme = "http" - } - s.Endpoint = scheme + "://" + s.Endpoint - } -} - -// AddDebugHandlers injects debug logging handlers into the service to log request -// debug information. -func (s *Service) AddDebugHandlers() { - out := s.Config.Logger - if s.Config.LogLevel == 0 { - return - } - - s.Handlers.Send.PushFront(func(r *Request) { - logBody := r.Config.LogHTTPBody - dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody) - - fmt.Fprintf(out, "---[ REQUEST POST-SIGN ]-----------------------------\n") - fmt.Fprintf(out, "%s\n", string(dumpedBody)) - fmt.Fprintf(out, "-----------------------------------------------------\n") - }) - s.Handlers.Send.PushBack(func(r *Request) { - fmt.Fprintf(out, "---[ RESPONSE ]--------------------------------------\n") - if r.HTTPResponse != nil { - logBody := r.Config.LogHTTPBody - dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody) - fmt.Fprintf(out, "%s\n", string(dumpedBody)) - } else if r.Error != nil { - fmt.Fprintf(out, "%s\n", r.Error) - } - fmt.Fprintf(out, "-----------------------------------------------------\n") - }) -} - -// MaxRetries returns the number of maximum returns the service will use to make -// an individual API request. -func (s *Service) MaxRetries() uint { - if s.Config.MaxRetries < 0 { - return s.DefaultMaxRetries - } - return uint(s.Config.MaxRetries) -} - -// retryRules returns the delay duration before retrying this request again -func retryRules(r *Request) time.Duration { - delay := time.Duration(math.Pow(2, float64(r.RetryCount))) * 30 - return delay * time.Millisecond -} - -// retryableCodes is a collection of service response codes which are retry-able -// without any further action. -var retryableCodes = map[string]struct{}{ - "RequestError": struct{}{}, - "ProvisionedThroughputExceededException": struct{}{}, - "Throttling": struct{}{}, -} - -// credsExpiredCodes is a collection of error codes which signify the credentials -// need to be refreshed. Expired tokens require refreshing of credentials, and -// resigning before the request can be retried. -var credsExpiredCodes = map[string]struct{}{ - "ExpiredToken": struct{}{}, - "ExpiredTokenException": struct{}{}, - "RequestExpired": struct{}{}, // EC2 Only -} - -func isCodeRetryable(code string) bool { - if _, ok := retryableCodes[code]; ok { - return true - } - - return isCodeExpiredCreds(code) -} - -func isCodeExpiredCreds(code string) bool { - _, ok := credsExpiredCodes[code] - return ok -} - -// shouldRetry returns if the request should be retried. -func shouldRetry(r *Request) bool { - if r.HTTPResponse.StatusCode >= 500 { - return true - } - if r.Error != nil { - if err, ok := r.Error.(awserr.Error); ok { - return isCodeRetryable(err.Code()) - } - } - return false -} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/default_retryer.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/default_retryer.go new file mode 100644 index 000000000000..e642d16b716e --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/default_retryer.go @@ -0,0 +1,51 @@ +package service + +import ( + "math" + "math/rand" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" +) + +// DefaultRetryer implements basic retry logic using exponential backoff for +// most services. If you want to implement custom retry logic, implement the +// request.Retryer interface or create a structure type that composes this +// struct and override the specific methods. For example, to override only +// the MaxRetries method: +// +// type retryer struct { +// service.DefaultRetryer +// } +// +// // This implementation always has 100 max retries +// func (d retryer) MaxRetries() uint { return 100 } +type DefaultRetryer struct { + *Service +} + +// MaxRetries returns the number of maximum returns the service will use to make +// an individual API request. +func (d DefaultRetryer) MaxRetries() uint { + if aws.IntValue(d.Service.Config.MaxRetries) < 0 { + return d.DefaultMaxRetries + } + return uint(aws.IntValue(d.Service.Config.MaxRetries)) +} + +var seededRand = rand.New(rand.NewSource(time.Now().UnixNano())) + +// RetryRules returns the delay duration before retrying this request again +func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration { + delay := int(math.Pow(2, float64(r.RetryCount))) * (seededRand.Intn(30) + 30) + return time.Duration(delay) * time.Millisecond +} + +// ShouldRetry returns if the request should be retried. +func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { + if r.HTTPResponse.StatusCode >= 500 { + return true + } + return r.IsErrorRetryable() +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/service.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/service.go new file mode 100644 index 000000000000..7205212e19b1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/service.go @@ -0,0 +1,133 @@ +package service + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/http/httputil" + "regexp" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service/serviceinfo" + "github.com/aws/aws-sdk-go/internal/endpoints" +) + +// A Service implements the base service request and response handling +// used by all services. +type Service struct { + serviceinfo.ServiceInfo + request.Retryer + DefaultMaxRetries uint + Handlers request.Handlers +} + +var schemeRE = regexp.MustCompile("^([^:]+)://") + +// New will return a pointer to a new Server object initialized. +func New(config *aws.Config) *Service { + svc := &Service{ServiceInfo: serviceinfo.ServiceInfo{Config: config}} + svc.Initialize() + return svc +} + +// Initialize initializes the service. +func (s *Service) Initialize() { + if s.Config == nil { + s.Config = &aws.Config{} + } + if s.Config.HTTPClient == nil { + s.Config.HTTPClient = http.DefaultClient + } + if s.Config.SleepDelay == nil { + s.Config.SleepDelay = time.Sleep + } + + s.Retryer = DefaultRetryer{s} + s.DefaultMaxRetries = 3 + s.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler) + s.Handlers.Build.PushBackNamed(corehandlers.UserAgentHandler) + s.Handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler) + s.Handlers.Send.PushBackNamed(corehandlers.SendHandler) + s.Handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) + s.Handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler) + if !aws.BoolValue(s.Config.DisableParamValidation) { + s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler) + } + s.AddDebugHandlers() + s.buildEndpoint() +} + +// NewRequest returns a new Request pointer for the service API +// operation and parameters. +func (s *Service) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request { + return request.New(s.ServiceInfo, s.Handlers, s.Retryer, operation, params, data) +} + +// buildEndpoint builds the endpoint values the service will use to make requests with. +func (s *Service) buildEndpoint() { + if aws.StringValue(s.Config.Endpoint) != "" { + s.Endpoint = *s.Config.Endpoint + } else if s.Endpoint == "" { + s.Endpoint, s.SigningRegion = + endpoints.EndpointForRegion(s.ServiceName, aws.StringValue(s.Config.Region)) + } + + if s.Endpoint != "" && !schemeRE.MatchString(s.Endpoint) { + scheme := "https" + if aws.BoolValue(s.Config.DisableSSL) { + scheme = "http" + } + s.Endpoint = scheme + "://" + s.Endpoint + } +} + +// AddDebugHandlers injects debug logging handlers into the service to log request +// debug information. +func (s *Service) AddDebugHandlers() { + if !s.Config.LogLevel.AtLeast(aws.LogDebug) { + return + } + + s.Handlers.Send.PushFront(logRequest) + s.Handlers.Send.PushBack(logResponse) +} + +const logReqMsg = `DEBUG: Request %s/%s Details: +---[ REQUEST POST-SIGN ]----------------------------- +%s +-----------------------------------------------------` + +func logRequest(r *request.Request) { + logBody := r.Service.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) + dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody) + + if logBody { + // Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's + // Body as a NoOpCloser and will not be reset after read by the HTTP + // client reader. + r.Body.Seek(r.BodyStart, 0) + r.HTTPRequest.Body = ioutil.NopCloser(r.Body) + } + + r.Service.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.Service.ServiceName, r.Operation.Name, string(dumpedBody))) +} + +const logRespMsg = `DEBUG: Response %s/%s Details: +---[ RESPONSE ]-------------------------------------- +%s +-----------------------------------------------------` + +func logResponse(r *request.Request) { + var msg = "no reponse data" + if r.HTTPResponse != nil { + logBody := r.Service.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) + dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody) + msg = string(dumpedBody) + } else if r.Error != nil { + msg = r.Error.Error() + } + r.Service.Config.Logger.Log(fmt.Sprintf(logRespMsg, r.Service.ServiceName, r.Operation.Name, msg)) +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/serviceinfo/service_info.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/serviceinfo/service_info.go new file mode 100644 index 000000000000..a920e96a967d --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/serviceinfo/service_info.go @@ -0,0 +1,15 @@ +package serviceinfo + +import "github.com/aws/aws-sdk-go/aws" + +// ServiceInfo wraps immutable data from the service.Service structure. +type ServiceInfo struct { + Config *aws.Config + ServiceName string + APIVersion string + Endpoint string + SigningName string + SigningRegion string + JSONVersion string + TargetPrefix string +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types.go index 7801cb689a5a..846b732dda1f 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types.go @@ -1,36 +1,10 @@ package aws import ( - "fmt" "io" - "time" + "sync" ) -// String converts a Go string into a string pointer. -func String(v string) *string { - return &v -} - -// Boolean converts a Go bool into a boolean pointer. -func Boolean(v bool) *bool { - return &v -} - -// Long converts a Go int64 into a long pointer. -func Long(v int64) *int64 { - return &v -} - -// Double converts a Go float64 into a double pointer. -func Double(v float64) *float64 { - return &v -} - -// Time converts a Go Time into a Time pointer -func Time(t time.Time) *time.Time { - return &t -} - // ReadSeekCloser wraps a io.Reader returning a ReaderSeakerCloser func ReadSeekCloser(r io.Reader) ReaderSeekerCloser { return ReaderSeekerCloser{r} @@ -81,51 +55,34 @@ func (r ReaderSeekerCloser) Close() error { return nil } -// A SettableBool provides a boolean value which includes the state if -// the value was set or unset. The set state is in addition to the value's -// value(true|false) -type SettableBool struct { - value bool - set bool +// A WriteAtBuffer provides a in memory buffer supporting the io.WriterAt interface +// Can be used with the s3manager.Downloader to download content to a buffer +// in memory. Safe to use concurrently. +type WriteAtBuffer struct { + buf []byte + m sync.Mutex } -// SetBool returns a SettableBool with a value set -func SetBool(value bool) SettableBool { - return SettableBool{value: value, set: true} -} +// WriteAt writes a slice of bytes to a buffer starting at the position provided +// The number of bytes written will be returned, or error. Can overwrite previous +// written slices if the write ats overlap. +func (b *WriteAtBuffer) WriteAt(p []byte, pos int64) (n int, err error) { + b.m.Lock() + defer b.m.Unlock() -// Get returns the value. Will always be false if the SettableBool was not set. -func (b *SettableBool) Get() bool { - if !b.set { - return false + expLen := pos + int64(len(p)) + if int64(len(b.buf)) < expLen { + newBuf := make([]byte, expLen) + copy(newBuf, b.buf) + b.buf = newBuf } - return b.value -} - -// Set sets the value and updates the state that the value has been set. -func (b *SettableBool) Set(value bool) { - b.value = value - b.set = true -} - -// IsSet returns if the value has been set -func (b *SettableBool) IsSet() bool { - return b.set -} - -// Reset resets the state and value of the SettableBool to its initial default -// state of not set and zero value. -func (b *SettableBool) Reset() { - b.value = false - b.set = false -} - -// String returns the string representation of the value if set. Zero if not set. -func (b *SettableBool) String() string { - return fmt.Sprintf("%t", b.Get()) + copy(b.buf[pos:], p) + return len(p), nil } -// GoString returns the string representation of the SettableBool value and state -func (b *SettableBool) GoString() string { - return fmt.Sprintf("Bool{value:%t, set:%t}", b.value, b.set) +// Bytes returns a slice of bytes written to the buffer. +func (b *WriteAtBuffer) Bytes() []byte { + b.m.Lock() + defer b.m.Unlock() + return b.buf[:len(b.buf):len(b.buf)] } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types_test.go new file mode 100644 index 000000000000..a4ed20e7d220 --- /dev/null +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types_test.go @@ -0,0 +1,56 @@ +package aws + +import ( + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestWriteAtBuffer(t *testing.T) { + b := &WriteAtBuffer{} + + n, err := b.WriteAt([]byte{1}, 0) + assert.NoError(t, err) + assert.Equal(t, 1, n) + + n, err = b.WriteAt([]byte{1, 1, 1}, 5) + assert.NoError(t, err) + assert.Equal(t, 3, n) + + n, err = b.WriteAt([]byte{2}, 1) + assert.NoError(t, err) + assert.Equal(t, 1, n) + + n, err = b.WriteAt([]byte{3}, 2) + assert.NoError(t, err) + assert.Equal(t, 1, n) + + assert.Equal(t, []byte{1, 2, 3, 0, 0, 1, 1, 1}, b.Bytes()) +} + +func BenchmarkWriteAtBuffer(b *testing.B) { + buf := &WriteAtBuffer{} + r := rand.New(rand.NewSource(1)) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + to := r.Intn(10) * 4096 + bs := make([]byte, to) + buf.WriteAt(bs, r.Int63n(10)*4096) + } +} + +func BenchmarkWriteAtBufferParallel(b *testing.B) { + buf := &WriteAtBuffer{} + r := rand.New(rand.NewSource(1)) + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + to := r.Intn(10) * 4096 + bs := make([]byte, to) + buf.WriteAt(bs, r.Int63n(10)*4096) + } + }) +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/version.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/version.go index 7c156dbe2a28..f89f1e112faf 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/version.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "0.6.0" +const SDKVersion = "0.9.9" diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints.go index 32e87c8a4a4f..d040cccd57d3 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints.go @@ -2,6 +2,7 @@ package endpoints //go:generate go run ../model/cli/gen-endpoints/main.go endpoints.json endpoints_map.go +//go:generate gofmt -s -w endpoints_map.go import "strings" diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints_map.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints_map.go index 637fcbe43aad..894c1a643419 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints_map.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/endpoints/endpoints_map.go @@ -15,74 +15,74 @@ type endpointEntry struct { var endpointsMap = endpointStruct{ Version: 2, Endpoints: map[string]endpointEntry{ - "*/*": endpointEntry{ + "*/*": { Endpoint: "{service}.{region}.amazonaws.com", }, - "*/cloudfront": endpointEntry{ + "*/cloudfront": { Endpoint: "cloudfront.amazonaws.com", SigningRegion: "us-east-1", }, - "*/cloudsearchdomain": endpointEntry{ + "*/cloudsearchdomain": { Endpoint: "", SigningRegion: "us-east-1", }, - "*/iam": endpointEntry{ + "*/iam": { Endpoint: "iam.amazonaws.com", SigningRegion: "us-east-1", }, - "*/importexport": endpointEntry{ + "*/importexport": { Endpoint: "importexport.amazonaws.com", SigningRegion: "us-east-1", }, - "*/route53": endpointEntry{ + "*/route53": { Endpoint: "route53.amazonaws.com", SigningRegion: "us-east-1", }, - "*/sts": endpointEntry{ + "*/sts": { Endpoint: "sts.amazonaws.com", SigningRegion: "us-east-1", }, - "ap-northeast-1/s3": endpointEntry{ + "ap-northeast-1/s3": { Endpoint: "s3-{region}.amazonaws.com", }, - "ap-southeast-1/s3": endpointEntry{ + "ap-southeast-1/s3": { Endpoint: "s3-{region}.amazonaws.com", }, - "ap-southeast-2/s3": endpointEntry{ + "ap-southeast-2/s3": { Endpoint: "s3-{region}.amazonaws.com", }, - "cn-north-1/*": endpointEntry{ + "cn-north-1/*": { Endpoint: "{service}.{region}.amazonaws.com.cn", }, - "eu-central-1/s3": endpointEntry{ + "eu-central-1/s3": { Endpoint: "{service}.{region}.amazonaws.com", }, - "eu-west-1/s3": endpointEntry{ + "eu-west-1/s3": { Endpoint: "s3-{region}.amazonaws.com", }, - "sa-east-1/s3": endpointEntry{ + "sa-east-1/s3": { Endpoint: "s3-{region}.amazonaws.com", }, - "us-east-1/s3": endpointEntry{ + "us-east-1/s3": { Endpoint: "s3.amazonaws.com", }, - "us-east-1/sdb": endpointEntry{ + "us-east-1/sdb": { Endpoint: "sdb.amazonaws.com", SigningRegion: "us-east-1", }, - "us-gov-west-1/iam": endpointEntry{ + "us-gov-west-1/iam": { Endpoint: "iam.us-gov.amazonaws.com", }, - "us-gov-west-1/s3": endpointEntry{ + "us-gov-west-1/s3": { Endpoint: "s3-{region}.amazonaws.com", }, - "us-gov-west-1/sts": endpointEntry{ + "us-gov-west-1/sts": { Endpoint: "sts.us-gov-west-1.amazonaws.com", }, - "us-west-1/s3": endpointEntry{ + "us-west-1/s3": { Endpoint: "s3-{region}.amazonaws.com", }, - "us-west-2/s3": endpointEntry{ + "us-west-2/s3": { Endpoint: "s3-{region}.amazonaws.com", }, }, diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build.go index bdf2bc4f8256..fabe9b3c3043 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build.go @@ -6,19 +6,19 @@ package ec2query import ( "net/url" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/internal/protocol/query/queryutil" ) // Build builds a request for the EC2 protocol. -func Build(r *aws.Request) { +func Build(r *request.Request) { body := url.Values{ "Action": {r.Operation.Name}, "Version": {r.Service.APIVersion}, } if err := queryutil.Parse(body, r.Params, true); err != nil { - r.Error = apierr.New("Marshal", "failed encoding EC2 Query request", err) + r.Error = awserr.New("SerializationError", "failed encoding EC2 Query request", err) } if r.ExpireTime == 0 { diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build_test.go index f267f0215879..8b2e59a8ae04 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/build_test.go @@ -1,10 +1,6 @@ package ec2query_test import ( - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/internal/protocol/ec2query" - "github.com/aws/aws-sdk-go/internal/signer/v4" - "bytes" "encoding/json" "encoding/xml" @@ -15,7 +11,14 @@ import ( "testing" "time" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" + "github.com/aws/aws-sdk-go/aws/service/serviceinfo" + "github.com/aws/aws-sdk-go/internal/protocol/ec2query" "github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil" + "github.com/aws/aws-sdk-go/internal/signer/v4" "github.com/aws/aws-sdk-go/internal/util" "github.com/stretchr/testify/assert" ) @@ -31,17 +34,18 @@ var _ = util.Trim("") var _ = url.Values{} var _ = io.EOF -// InputService1ProtocolTest is a client for InputService1ProtocolTest. type InputService1ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService1ProtocolTest client. func NewInputService1ProtocolTest(config *aws.Config) *InputService1ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice1protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice1protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -57,70 +61,68 @@ func NewInputService1ProtocolTest(config *aws.Config) *InputService1ProtocolTest // newRequest creates a new request for a InputService1ProtocolTest operation and runs any // custom request initialization. -func (c *InputService1ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService1ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService1TestCaseOperation1Request generates a request for the InputService1TestCaseOperation1 operation. -func (c *InputService1ProtocolTest) InputService1TestCaseOperation1Request(input *InputService1TestShapeInputShape) (req *aws.Request, output *InputService1TestShapeInputService1TestCaseOperation1Output) { +const opInputService1TestCaseOperation1 = "OperationName" - if opInputService1TestCaseOperation1 == nil { - opInputService1TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService1TestCaseOperation1Request generates a request for the InputService1TestCaseOperation1 operation. +func (c *InputService1ProtocolTest) InputService1TestCaseOperation1Request(input *InputService1TestShapeInputService1TestCaseOperation1Input) (req *request.Request, output *InputService1TestShapeInputService1TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService1TestCaseOperation1, } if input == nil { - input = &InputService1TestShapeInputShape{} + input = &InputService1TestShapeInputService1TestCaseOperation1Input{} } - req = c.newRequest(opInputService1TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService1TestShapeInputService1TestCaseOperation1Output{} req.Data = output return } -func (c *InputService1ProtocolTest) InputService1TestCaseOperation1(input *InputService1TestShapeInputShape) (*InputService1TestShapeInputService1TestCaseOperation1Output, error) { +func (c *InputService1ProtocolTest) InputService1TestCaseOperation1(input *InputService1TestShapeInputService1TestCaseOperation1Input) (*InputService1TestShapeInputService1TestCaseOperation1Output, error) { req, out := c.InputService1TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService1TestCaseOperation1 *aws.Operation +type InputService1TestShapeInputService1TestCaseOperation1Input struct { + Bar *string `type:"string"` -type InputService1TestShapeInputService1TestCaseOperation1Output struct { - metadataInputService1TestShapeInputService1TestCaseOperation1Output `json:"-" xml:"-"` + Foo *string `type:"string"` + + metadataInputService1TestShapeInputService1TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService1TestShapeInputService1TestCaseOperation1Output struct { +type metadataInputService1TestShapeInputService1TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService1TestShapeInputShape struct { - Bar *string `type:"string"` - - Foo *string `type:"string"` - - metadataInputService1TestShapeInputShape `json:"-" xml:"-"` +type InputService1TestShapeInputService1TestCaseOperation1Output struct { + metadataInputService1TestShapeInputService1TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService1TestShapeInputShape struct { +type metadataInputService1TestShapeInputService1TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// InputService2ProtocolTest is a client for InputService2ProtocolTest. type InputService2ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService2ProtocolTest client. func NewInputService2ProtocolTest(config *aws.Config) *InputService2ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice2protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice2protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -136,72 +138,70 @@ func NewInputService2ProtocolTest(config *aws.Config) *InputService2ProtocolTest // newRequest creates a new request for a InputService2ProtocolTest operation and runs any // custom request initialization. -func (c *InputService2ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService2ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService2TestCaseOperation1Request generates a request for the InputService2TestCaseOperation1 operation. -func (c *InputService2ProtocolTest) InputService2TestCaseOperation1Request(input *InputService2TestShapeInputShape) (req *aws.Request, output *InputService2TestShapeInputService2TestCaseOperation1Output) { +const opInputService2TestCaseOperation1 = "OperationName" - if opInputService2TestCaseOperation1 == nil { - opInputService2TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService2TestCaseOperation1Request generates a request for the InputService2TestCaseOperation1 operation. +func (c *InputService2ProtocolTest) InputService2TestCaseOperation1Request(input *InputService2TestShapeInputService2TestCaseOperation1Input) (req *request.Request, output *InputService2TestShapeInputService2TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService2TestCaseOperation1, } if input == nil { - input = &InputService2TestShapeInputShape{} + input = &InputService2TestShapeInputService2TestCaseOperation1Input{} } - req = c.newRequest(opInputService2TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService2TestShapeInputService2TestCaseOperation1Output{} req.Data = output return } -func (c *InputService2ProtocolTest) InputService2TestCaseOperation1(input *InputService2TestShapeInputShape) (*InputService2TestShapeInputService2TestCaseOperation1Output, error) { +func (c *InputService2ProtocolTest) InputService2TestCaseOperation1(input *InputService2TestShapeInputService2TestCaseOperation1Input) (*InputService2TestShapeInputService2TestCaseOperation1Output, error) { req, out := c.InputService2TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService2TestCaseOperation1 *aws.Operation - -type InputService2TestShapeInputService2TestCaseOperation1Output struct { - metadataInputService2TestShapeInputService2TestCaseOperation1Output `json:"-" xml:"-"` -} - -type metadataInputService2TestShapeInputService2TestCaseOperation1Output struct { - SDKShapeTraits bool `type:"structure"` -} - -type InputService2TestShapeInputShape struct { +type InputService2TestShapeInputService2TestCaseOperation1Input struct { Bar *string `locationName:"barLocationName" type:"string"` Foo *string `type:"string"` Yuck *string `locationName:"yuckLocationName" queryName:"yuckQueryName" type:"string"` - metadataInputService2TestShapeInputShape `json:"-" xml:"-"` + metadataInputService2TestShapeInputService2TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService2TestShapeInputShape struct { +type metadataInputService2TestShapeInputService2TestCaseOperation1Input struct { + SDKShapeTraits bool `type:"structure"` +} + +type InputService2TestShapeInputService2TestCaseOperation1Output struct { + metadataInputService2TestShapeInputService2TestCaseOperation1Output `json:"-" xml:"-"` +} + +type metadataInputService2TestShapeInputService2TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// InputService3ProtocolTest is a client for InputService3ProtocolTest. type InputService3ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService3ProtocolTest client. func NewInputService3ProtocolTest(config *aws.Config) *InputService3ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice3protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice3protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -217,54 +217,51 @@ func NewInputService3ProtocolTest(config *aws.Config) *InputService3ProtocolTest // newRequest creates a new request for a InputService3ProtocolTest operation and runs any // custom request initialization. -func (c *InputService3ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService3ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService3TestCaseOperation1Request generates a request for the InputService3TestCaseOperation1 operation. -func (c *InputService3ProtocolTest) InputService3TestCaseOperation1Request(input *InputService3TestShapeInputShape) (req *aws.Request, output *InputService3TestShapeInputService3TestCaseOperation1Output) { +const opInputService3TestCaseOperation1 = "OperationName" - if opInputService3TestCaseOperation1 == nil { - opInputService3TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService3TestCaseOperation1Request generates a request for the InputService3TestCaseOperation1 operation. +func (c *InputService3ProtocolTest) InputService3TestCaseOperation1Request(input *InputService3TestShapeInputService3TestCaseOperation1Input) (req *request.Request, output *InputService3TestShapeInputService3TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService3TestCaseOperation1, } if input == nil { - input = &InputService3TestShapeInputShape{} + input = &InputService3TestShapeInputService3TestCaseOperation1Input{} } - req = c.newRequest(opInputService3TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService3TestShapeInputService3TestCaseOperation1Output{} req.Data = output return } -func (c *InputService3ProtocolTest) InputService3TestCaseOperation1(input *InputService3TestShapeInputShape) (*InputService3TestShapeInputService3TestCaseOperation1Output, error) { +func (c *InputService3ProtocolTest) InputService3TestCaseOperation1(input *InputService3TestShapeInputService3TestCaseOperation1Input) (*InputService3TestShapeInputService3TestCaseOperation1Output, error) { req, out := c.InputService3TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService3TestCaseOperation1 *aws.Operation +type InputService3TestShapeInputService3TestCaseOperation1Input struct { + StructArg *InputService3TestShapeStructType `locationName:"Struct" type:"structure"` -type InputService3TestShapeInputService3TestCaseOperation1Output struct { - metadataInputService3TestShapeInputService3TestCaseOperation1Output `json:"-" xml:"-"` + metadataInputService3TestShapeInputService3TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService3TestShapeInputService3TestCaseOperation1Output struct { +type metadataInputService3TestShapeInputService3TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService3TestShapeInputShape struct { - StructArg *InputService3TestShapeStructType `locationName:"Struct" type:"structure"` - - metadataInputService3TestShapeInputShape `json:"-" xml:"-"` +type InputService3TestShapeInputService3TestCaseOperation1Output struct { + metadataInputService3TestShapeInputService3TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService3TestShapeInputShape struct { +type metadataInputService3TestShapeInputService3TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } @@ -278,17 +275,18 @@ type metadataInputService3TestShapeStructType struct { SDKShapeTraits bool `type:"structure"` } -// InputService4ProtocolTest is a client for InputService4ProtocolTest. type InputService4ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService4ProtocolTest client. func NewInputService4ProtocolTest(config *aws.Config) *InputService4ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice4protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice4protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -304,68 +302,66 @@ func NewInputService4ProtocolTest(config *aws.Config) *InputService4ProtocolTest // newRequest creates a new request for a InputService4ProtocolTest operation and runs any // custom request initialization. -func (c *InputService4ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService4ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService4TestCaseOperation1Request generates a request for the InputService4TestCaseOperation1 operation. -func (c *InputService4ProtocolTest) InputService4TestCaseOperation1Request(input *InputService4TestShapeInputShape) (req *aws.Request, output *InputService4TestShapeInputService4TestCaseOperation1Output) { +const opInputService4TestCaseOperation1 = "OperationName" - if opInputService4TestCaseOperation1 == nil { - opInputService4TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService4TestCaseOperation1Request generates a request for the InputService4TestCaseOperation1 operation. +func (c *InputService4ProtocolTest) InputService4TestCaseOperation1Request(input *InputService4TestShapeInputService4TestCaseOperation1Input) (req *request.Request, output *InputService4TestShapeInputService4TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService4TestCaseOperation1, } if input == nil { - input = &InputService4TestShapeInputShape{} + input = &InputService4TestShapeInputService4TestCaseOperation1Input{} } - req = c.newRequest(opInputService4TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService4TestShapeInputService4TestCaseOperation1Output{} req.Data = output return } -func (c *InputService4ProtocolTest) InputService4TestCaseOperation1(input *InputService4TestShapeInputShape) (*InputService4TestShapeInputService4TestCaseOperation1Output, error) { +func (c *InputService4ProtocolTest) InputService4TestCaseOperation1(input *InputService4TestShapeInputService4TestCaseOperation1Input) (*InputService4TestShapeInputService4TestCaseOperation1Output, error) { req, out := c.InputService4TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService4TestCaseOperation1 *aws.Operation +type InputService4TestShapeInputService4TestCaseOperation1Input struct { + ListArg []*string `type:"list"` -type InputService4TestShapeInputService4TestCaseOperation1Output struct { - metadataInputService4TestShapeInputService4TestCaseOperation1Output `json:"-" xml:"-"` + metadataInputService4TestShapeInputService4TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService4TestShapeInputService4TestCaseOperation1Output struct { +type metadataInputService4TestShapeInputService4TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService4TestShapeInputShape struct { - ListArg []*string `type:"list"` - - metadataInputService4TestShapeInputShape `json:"-" xml:"-"` +type InputService4TestShapeInputService4TestCaseOperation1Output struct { + metadataInputService4TestShapeInputService4TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService4TestShapeInputShape struct { +type metadataInputService4TestShapeInputService4TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// InputService5ProtocolTest is a client for InputService5ProtocolTest. type InputService5ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService5ProtocolTest client. func NewInputService5ProtocolTest(config *aws.Config) *InputService5ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice5protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice5protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -381,68 +377,66 @@ func NewInputService5ProtocolTest(config *aws.Config) *InputService5ProtocolTest // newRequest creates a new request for a InputService5ProtocolTest operation and runs any // custom request initialization. -func (c *InputService5ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService5ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService5TestCaseOperation1Request generates a request for the InputService5TestCaseOperation1 operation. -func (c *InputService5ProtocolTest) InputService5TestCaseOperation1Request(input *InputService5TestShapeInputShape) (req *aws.Request, output *InputService5TestShapeInputService5TestCaseOperation1Output) { +const opInputService5TestCaseOperation1 = "OperationName" - if opInputService5TestCaseOperation1 == nil { - opInputService5TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService5TestCaseOperation1Request generates a request for the InputService5TestCaseOperation1 operation. +func (c *InputService5ProtocolTest) InputService5TestCaseOperation1Request(input *InputService5TestShapeInputService5TestCaseOperation1Input) (req *request.Request, output *InputService5TestShapeInputService5TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService5TestCaseOperation1, } if input == nil { - input = &InputService5TestShapeInputShape{} + input = &InputService5TestShapeInputService5TestCaseOperation1Input{} } - req = c.newRequest(opInputService5TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService5TestShapeInputService5TestCaseOperation1Output{} req.Data = output return } -func (c *InputService5ProtocolTest) InputService5TestCaseOperation1(input *InputService5TestShapeInputShape) (*InputService5TestShapeInputService5TestCaseOperation1Output, error) { +func (c *InputService5ProtocolTest) InputService5TestCaseOperation1(input *InputService5TestShapeInputService5TestCaseOperation1Input) (*InputService5TestShapeInputService5TestCaseOperation1Output, error) { req, out := c.InputService5TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService5TestCaseOperation1 *aws.Operation +type InputService5TestShapeInputService5TestCaseOperation1Input struct { + ListArg []*string `locationName:"ListMemberName" locationNameList:"item" type:"list"` -type InputService5TestShapeInputService5TestCaseOperation1Output struct { - metadataInputService5TestShapeInputService5TestCaseOperation1Output `json:"-" xml:"-"` + metadataInputService5TestShapeInputService5TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService5TestShapeInputService5TestCaseOperation1Output struct { +type metadataInputService5TestShapeInputService5TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService5TestShapeInputShape struct { - ListArg []*string `locationName:"ListMemberName" locationNameList:"item" type:"list"` - - metadataInputService5TestShapeInputShape `json:"-" xml:"-"` +type InputService5TestShapeInputService5TestCaseOperation1Output struct { + metadataInputService5TestShapeInputService5TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService5TestShapeInputShape struct { +type metadataInputService5TestShapeInputService5TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// InputService6ProtocolTest is a client for InputService6ProtocolTest. type InputService6ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService6ProtocolTest client. func NewInputService6ProtocolTest(config *aws.Config) *InputService6ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice6protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice6protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -458,68 +452,66 @@ func NewInputService6ProtocolTest(config *aws.Config) *InputService6ProtocolTest // newRequest creates a new request for a InputService6ProtocolTest operation and runs any // custom request initialization. -func (c *InputService6ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService6ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService6TestCaseOperation1Request generates a request for the InputService6TestCaseOperation1 operation. -func (c *InputService6ProtocolTest) InputService6TestCaseOperation1Request(input *InputService6TestShapeInputShape) (req *aws.Request, output *InputService6TestShapeInputService6TestCaseOperation1Output) { +const opInputService6TestCaseOperation1 = "OperationName" - if opInputService6TestCaseOperation1 == nil { - opInputService6TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService6TestCaseOperation1Request generates a request for the InputService6TestCaseOperation1 operation. +func (c *InputService6ProtocolTest) InputService6TestCaseOperation1Request(input *InputService6TestShapeInputService6TestCaseOperation1Input) (req *request.Request, output *InputService6TestShapeInputService6TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService6TestCaseOperation1, } if input == nil { - input = &InputService6TestShapeInputShape{} + input = &InputService6TestShapeInputService6TestCaseOperation1Input{} } - req = c.newRequest(opInputService6TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService6TestShapeInputService6TestCaseOperation1Output{} req.Data = output return } -func (c *InputService6ProtocolTest) InputService6TestCaseOperation1(input *InputService6TestShapeInputShape) (*InputService6TestShapeInputService6TestCaseOperation1Output, error) { +func (c *InputService6ProtocolTest) InputService6TestCaseOperation1(input *InputService6TestShapeInputService6TestCaseOperation1Input) (*InputService6TestShapeInputService6TestCaseOperation1Output, error) { req, out := c.InputService6TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService6TestCaseOperation1 *aws.Operation +type InputService6TestShapeInputService6TestCaseOperation1Input struct { + ListArg []*string `locationName:"ListMemberName" queryName:"ListQueryName" locationNameList:"item" type:"list"` -type InputService6TestShapeInputService6TestCaseOperation1Output struct { - metadataInputService6TestShapeInputService6TestCaseOperation1Output `json:"-" xml:"-"` + metadataInputService6TestShapeInputService6TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService6TestShapeInputService6TestCaseOperation1Output struct { +type metadataInputService6TestShapeInputService6TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService6TestShapeInputShape struct { - ListArg []*string `locationName:"ListMemberName" queryName:"ListQueryName" locationNameList:"item" type:"list"` - - metadataInputService6TestShapeInputShape `json:"-" xml:"-"` +type InputService6TestShapeInputService6TestCaseOperation1Output struct { + metadataInputService6TestShapeInputService6TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService6TestShapeInputShape struct { +type metadataInputService6TestShapeInputService6TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// InputService7ProtocolTest is a client for InputService7ProtocolTest. type InputService7ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService7ProtocolTest client. func NewInputService7ProtocolTest(config *aws.Config) *InputService7ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice7protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice7protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -535,68 +527,66 @@ func NewInputService7ProtocolTest(config *aws.Config) *InputService7ProtocolTest // newRequest creates a new request for a InputService7ProtocolTest operation and runs any // custom request initialization. -func (c *InputService7ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService7ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService7TestCaseOperation1Request generates a request for the InputService7TestCaseOperation1 operation. -func (c *InputService7ProtocolTest) InputService7TestCaseOperation1Request(input *InputService7TestShapeInputShape) (req *aws.Request, output *InputService7TestShapeInputService7TestCaseOperation1Output) { +const opInputService7TestCaseOperation1 = "OperationName" - if opInputService7TestCaseOperation1 == nil { - opInputService7TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService7TestCaseOperation1Request generates a request for the InputService7TestCaseOperation1 operation. +func (c *InputService7ProtocolTest) InputService7TestCaseOperation1Request(input *InputService7TestShapeInputService7TestCaseOperation1Input) (req *request.Request, output *InputService7TestShapeInputService7TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService7TestCaseOperation1, } if input == nil { - input = &InputService7TestShapeInputShape{} + input = &InputService7TestShapeInputService7TestCaseOperation1Input{} } - req = c.newRequest(opInputService7TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService7TestShapeInputService7TestCaseOperation1Output{} req.Data = output return } -func (c *InputService7ProtocolTest) InputService7TestCaseOperation1(input *InputService7TestShapeInputShape) (*InputService7TestShapeInputService7TestCaseOperation1Output, error) { +func (c *InputService7ProtocolTest) InputService7TestCaseOperation1(input *InputService7TestShapeInputService7TestCaseOperation1Input) (*InputService7TestShapeInputService7TestCaseOperation1Output, error) { req, out := c.InputService7TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService7TestCaseOperation1 *aws.Operation +type InputService7TestShapeInputService7TestCaseOperation1Input struct { + BlobArg []byte `type:"blob"` -type InputService7TestShapeInputService7TestCaseOperation1Output struct { - metadataInputService7TestShapeInputService7TestCaseOperation1Output `json:"-" xml:"-"` + metadataInputService7TestShapeInputService7TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService7TestShapeInputService7TestCaseOperation1Output struct { +type metadataInputService7TestShapeInputService7TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService7TestShapeInputShape struct { - BlobArg []byte `type:"blob"` - - metadataInputService7TestShapeInputShape `json:"-" xml:"-"` +type InputService7TestShapeInputService7TestCaseOperation1Output struct { + metadataInputService7TestShapeInputService7TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService7TestShapeInputShape struct { +type metadataInputService7TestShapeInputService7TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// InputService8ProtocolTest is a client for InputService8ProtocolTest. type InputService8ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService8ProtocolTest client. func NewInputService8ProtocolTest(config *aws.Config) *InputService8ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice8protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice8protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -612,54 +602,51 @@ func NewInputService8ProtocolTest(config *aws.Config) *InputService8ProtocolTest // newRequest creates a new request for a InputService8ProtocolTest operation and runs any // custom request initialization. -func (c *InputService8ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService8ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService8TestCaseOperation1Request generates a request for the InputService8TestCaseOperation1 operation. -func (c *InputService8ProtocolTest) InputService8TestCaseOperation1Request(input *InputService8TestShapeInputShape) (req *aws.Request, output *InputService8TestShapeInputService8TestCaseOperation1Output) { +const opInputService8TestCaseOperation1 = "OperationName" - if opInputService8TestCaseOperation1 == nil { - opInputService8TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService8TestCaseOperation1Request generates a request for the InputService8TestCaseOperation1 operation. +func (c *InputService8ProtocolTest) InputService8TestCaseOperation1Request(input *InputService8TestShapeInputService8TestCaseOperation1Input) (req *request.Request, output *InputService8TestShapeInputService8TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService8TestCaseOperation1, } if input == nil { - input = &InputService8TestShapeInputShape{} + input = &InputService8TestShapeInputService8TestCaseOperation1Input{} } - req = c.newRequest(opInputService8TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService8TestShapeInputService8TestCaseOperation1Output{} req.Data = output return } -func (c *InputService8ProtocolTest) InputService8TestCaseOperation1(input *InputService8TestShapeInputShape) (*InputService8TestShapeInputService8TestCaseOperation1Output, error) { +func (c *InputService8ProtocolTest) InputService8TestCaseOperation1(input *InputService8TestShapeInputService8TestCaseOperation1Input) (*InputService8TestShapeInputService8TestCaseOperation1Output, error) { req, out := c.InputService8TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService8TestCaseOperation1 *aws.Operation +type InputService8TestShapeInputService8TestCaseOperation1Input struct { + TimeArg *time.Time `type:"timestamp" timestampFormat:"iso8601"` -type InputService8TestShapeInputService8TestCaseOperation1Output struct { - metadataInputService8TestShapeInputService8TestCaseOperation1Output `json:"-" xml:"-"` + metadataInputService8TestShapeInputService8TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService8TestShapeInputService8TestCaseOperation1Output struct { +type metadataInputService8TestShapeInputService8TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService8TestShapeInputShape struct { - TimeArg *time.Time `type:"timestamp" timestampFormat:"iso8601"` - - metadataInputService8TestShapeInputShape `json:"-" xml:"-"` +type InputService8TestShapeInputService8TestCaseOperation1Output struct { + metadataInputService8TestShapeInputService8TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService8TestShapeInputShape struct { +type metadataInputService8TestShapeInputService8TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } @@ -671,7 +658,7 @@ func TestInputService1ProtocolTestScalarMembersCase1(t *testing.T) { svc := NewInputService1ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService1TestShapeInputShape{ + input := &InputService1TestShapeInputService1TestCaseOperation1Input{ Bar: aws.String("val2"), Foo: aws.String("val1"), } @@ -698,7 +685,7 @@ func TestInputService2ProtocolTestStructureWithLocationNameAndQueryNameAppliedTo svc := NewInputService2ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService2TestShapeInputShape{ + input := &InputService2TestShapeInputService2TestCaseOperation1Input{ Bar: aws.String("val2"), Foo: aws.String("val1"), Yuck: aws.String("val3"), @@ -726,7 +713,7 @@ func TestInputService3ProtocolTestNestedStructureMembersCase1(t *testing.T) { svc := NewInputService3ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService3TestShapeInputShape{ + input := &InputService3TestShapeInputService3TestCaseOperation1Input{ StructArg: &InputService3TestShapeStructType{ ScalarArg: aws.String("foo"), }, @@ -754,7 +741,7 @@ func TestInputService4ProtocolTestListTypesCase1(t *testing.T) { svc := NewInputService4ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService4TestShapeInputShape{ + input := &InputService4TestShapeInputService4TestCaseOperation1Input{ ListArg: []*string{ aws.String("foo"), aws.String("bar"), @@ -784,7 +771,7 @@ func TestInputService5ProtocolTestListWithLocationNameAppliedToMemberCase1(t *te svc := NewInputService5ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService5TestShapeInputShape{ + input := &InputService5TestShapeInputService5TestCaseOperation1Input{ ListArg: []*string{ aws.String("a"), aws.String("b"), @@ -814,7 +801,7 @@ func TestInputService6ProtocolTestListWithLocationNameAndQueryNameCase1(t *testi svc := NewInputService6ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService6TestShapeInputShape{ + input := &InputService6TestShapeInputService6TestCaseOperation1Input{ ListArg: []*string{ aws.String("a"), aws.String("b"), @@ -844,7 +831,7 @@ func TestInputService7ProtocolTestBase64EncodedBlobsCase1(t *testing.T) { svc := NewInputService7ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService7TestShapeInputShape{ + input := &InputService7TestShapeInputService7TestCaseOperation1Input{ BlobArg: []byte("foo"), } req, _ := svc.InputService7TestCaseOperation1Request(input) @@ -870,7 +857,7 @@ func TestInputService8ProtocolTestTimestampValuesCase1(t *testing.T) { svc := NewInputService8ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService8TestShapeInputShape{ + input := &InputService8TestShapeInputService8TestCaseOperation1Input{ TimeArg: aws.Time(time.Unix(1422172800, 0)), } req, _ := svc.InputService8TestCaseOperation1Request(input) diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal.go index b25ece116fb0..bb0f01588897 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal.go @@ -6,26 +6,26 @@ import ( "encoding/xml" "io" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil" ) // Unmarshal unmarshals a response body for the EC2 protocol. -func Unmarshal(r *aws.Request) { +func Unmarshal(r *request.Request) { defer r.HTTPResponse.Body.Close() if r.DataFilled() { decoder := xml.NewDecoder(r.HTTPResponse.Body) err := xmlutil.UnmarshalXML(r.Data, decoder, "") if err != nil { - r.Error = apierr.New("Unmarshal", "failed decoding EC2 Query response", err) + r.Error = awserr.New("SerializationError", "failed decoding EC2 Query response", err) return } } } // UnmarshalMeta unmarshals response headers for the EC2 protocol. -func UnmarshalMeta(r *aws.Request) { +func UnmarshalMeta(r *request.Request) { // TODO implement unmarshaling of request IDs } @@ -37,16 +37,16 @@ type xmlErrorResponse struct { } // UnmarshalError unmarshals a response error for the EC2 protocol. -func UnmarshalError(r *aws.Request) { +func UnmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() resp := &xmlErrorResponse{} err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) if err != nil && err != io.EOF { - r.Error = apierr.New("Unmarshal", "failed decoding EC2 Query error response", err) + r.Error = awserr.New("SerializationError", "failed decoding EC2 Query error response", err) } else { - r.Error = apierr.NewRequestError( - apierr.New(resp.Code, resp.Message, nil), + r.Error = awserr.NewRequestFailure( + awserr.New(resp.Code, resp.Message, nil), r.HTTPResponse.StatusCode, resp.RequestID, ) diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal_test.go index 058f47801c05..3d7b0430bdc6 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/ec2query/unmarshal_test.go @@ -1,10 +1,6 @@ package ec2query_test import ( - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/internal/protocol/ec2query" - "github.com/aws/aws-sdk-go/internal/signer/v4" - "bytes" "encoding/json" "encoding/xml" @@ -15,7 +11,14 @@ import ( "testing" "time" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" + "github.com/aws/aws-sdk-go/aws/service/serviceinfo" + "github.com/aws/aws-sdk-go/internal/protocol/ec2query" "github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil" + "github.com/aws/aws-sdk-go/internal/signer/v4" "github.com/aws/aws-sdk-go/internal/util" "github.com/stretchr/testify/assert" ) @@ -31,17 +34,18 @@ var _ = util.Trim("") var _ = url.Values{} var _ = io.EOF -// OutputService1ProtocolTest is a client for OutputService1ProtocolTest. type OutputService1ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService1ProtocolTest client. func NewOutputService1ProtocolTest(config *aws.Config) *OutputService1ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice1protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice1protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -57,39 +61,36 @@ func NewOutputService1ProtocolTest(config *aws.Config) *OutputService1ProtocolTe // newRequest creates a new request for a OutputService1ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService1ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService1ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService1TestCaseOperation1Request generates a request for the OutputService1TestCaseOperation1 operation. -func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1Request(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (req *aws.Request, output *OutputService1TestShapeOutputShape) { +const opOutputService1TestCaseOperation1 = "OperationName" - if opOutputService1TestCaseOperation1 == nil { - opOutputService1TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService1TestCaseOperation1Request generates a request for the OutputService1TestCaseOperation1 operation. +func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1Request(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (req *request.Request, output *OutputService1TestShapeOutputService1TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService1TestCaseOperation1, } if input == nil { input = &OutputService1TestShapeOutputService1TestCaseOperation1Input{} } - req = c.newRequest(opOutputService1TestCaseOperation1, input, output) - output = &OutputService1TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService1TestShapeOutputService1TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (*OutputService1TestShapeOutputShape, error) { +func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (*OutputService1TestShapeOutputService1TestCaseOperation1Output, error) { req, out := c.OutputService1TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService1TestCaseOperation1 *aws.Operation - type OutputService1TestShapeOutputService1TestCaseOperation1Input struct { metadataOutputService1TestShapeOutputService1TestCaseOperation1Input `json:"-" xml:"-"` } @@ -98,7 +99,7 @@ type metadataOutputService1TestShapeOutputService1TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService1TestShapeOutputShape struct { +type OutputService1TestShapeOutputService1TestCaseOperation1Output struct { Char *string `type:"character"` Double *float64 `type:"double"` @@ -115,24 +116,25 @@ type OutputService1TestShapeOutputShape struct { TrueBool *bool `type:"boolean"` - metadataOutputService1TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService1TestShapeOutputService1TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService1TestShapeOutputShape struct { +type metadataOutputService1TestShapeOutputService1TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService2ProtocolTest is a client for OutputService2ProtocolTest. type OutputService2ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService2ProtocolTest client. func NewOutputService2ProtocolTest(config *aws.Config) *OutputService2ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice2protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice2protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -148,39 +150,36 @@ func NewOutputService2ProtocolTest(config *aws.Config) *OutputService2ProtocolTe // newRequest creates a new request for a OutputService2ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService2ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService2ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService2TestCaseOperation1Request generates a request for the OutputService2TestCaseOperation1 operation. -func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1Request(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (req *aws.Request, output *OutputService2TestShapeOutputShape) { +const opOutputService2TestCaseOperation1 = "OperationName" - if opOutputService2TestCaseOperation1 == nil { - opOutputService2TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService2TestCaseOperation1Request generates a request for the OutputService2TestCaseOperation1 operation. +func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1Request(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (req *request.Request, output *OutputService2TestShapeOutputService2TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService2TestCaseOperation1, } if input == nil { input = &OutputService2TestShapeOutputService2TestCaseOperation1Input{} } - req = c.newRequest(opOutputService2TestCaseOperation1, input, output) - output = &OutputService2TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService2TestShapeOutputService2TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (*OutputService2TestShapeOutputShape, error) { +func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (*OutputService2TestShapeOutputService2TestCaseOperation1Output, error) { req, out := c.OutputService2TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService2TestCaseOperation1 *aws.Operation - type OutputService2TestShapeOutputService2TestCaseOperation1Input struct { metadataOutputService2TestShapeOutputService2TestCaseOperation1Input `json:"-" xml:"-"` } @@ -189,27 +188,28 @@ type metadataOutputService2TestShapeOutputService2TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService2TestShapeOutputShape struct { +type OutputService2TestShapeOutputService2TestCaseOperation1Output struct { Blob []byte `type:"blob"` - metadataOutputService2TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService2TestShapeOutputService2TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService2TestShapeOutputShape struct { +type metadataOutputService2TestShapeOutputService2TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService3ProtocolTest is a client for OutputService3ProtocolTest. type OutputService3ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService3ProtocolTest client. func NewOutputService3ProtocolTest(config *aws.Config) *OutputService3ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice3protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice3protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -225,39 +225,36 @@ func NewOutputService3ProtocolTest(config *aws.Config) *OutputService3ProtocolTe // newRequest creates a new request for a OutputService3ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService3ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService3ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService3TestCaseOperation1Request generates a request for the OutputService3TestCaseOperation1 operation. -func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1Request(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (req *aws.Request, output *OutputService3TestShapeOutputShape) { +const opOutputService3TestCaseOperation1 = "OperationName" - if opOutputService3TestCaseOperation1 == nil { - opOutputService3TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService3TestCaseOperation1Request generates a request for the OutputService3TestCaseOperation1 operation. +func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1Request(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (req *request.Request, output *OutputService3TestShapeOutputService3TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService3TestCaseOperation1, } if input == nil { input = &OutputService3TestShapeOutputService3TestCaseOperation1Input{} } - req = c.newRequest(opOutputService3TestCaseOperation1, input, output) - output = &OutputService3TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService3TestShapeOutputService3TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (*OutputService3TestShapeOutputShape, error) { +func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (*OutputService3TestShapeOutputService3TestCaseOperation1Output, error) { req, out := c.OutputService3TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService3TestCaseOperation1 *aws.Operation - type OutputService3TestShapeOutputService3TestCaseOperation1Input struct { metadataOutputService3TestShapeOutputService3TestCaseOperation1Input `json:"-" xml:"-"` } @@ -266,27 +263,28 @@ type metadataOutputService3TestShapeOutputService3TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService3TestShapeOutputShape struct { +type OutputService3TestShapeOutputService3TestCaseOperation1Output struct { ListMember []*string `type:"list"` - metadataOutputService3TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService3TestShapeOutputService3TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService3TestShapeOutputShape struct { +type metadataOutputService3TestShapeOutputService3TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService4ProtocolTest is a client for OutputService4ProtocolTest. type OutputService4ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService4ProtocolTest client. func NewOutputService4ProtocolTest(config *aws.Config) *OutputService4ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice4protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice4protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -302,39 +300,36 @@ func NewOutputService4ProtocolTest(config *aws.Config) *OutputService4ProtocolTe // newRequest creates a new request for a OutputService4ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService4ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService4ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService4TestCaseOperation1Request generates a request for the OutputService4TestCaseOperation1 operation. -func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1Request(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (req *aws.Request, output *OutputService4TestShapeOutputShape) { +const opOutputService4TestCaseOperation1 = "OperationName" - if opOutputService4TestCaseOperation1 == nil { - opOutputService4TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService4TestCaseOperation1Request generates a request for the OutputService4TestCaseOperation1 operation. +func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1Request(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (req *request.Request, output *OutputService4TestShapeOutputService4TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService4TestCaseOperation1, } if input == nil { input = &OutputService4TestShapeOutputService4TestCaseOperation1Input{} } - req = c.newRequest(opOutputService4TestCaseOperation1, input, output) - output = &OutputService4TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService4TestShapeOutputService4TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (*OutputService4TestShapeOutputShape, error) { +func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (*OutputService4TestShapeOutputService4TestCaseOperation1Output, error) { req, out := c.OutputService4TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService4TestCaseOperation1 *aws.Operation - type OutputService4TestShapeOutputService4TestCaseOperation1Input struct { metadataOutputService4TestShapeOutputService4TestCaseOperation1Input `json:"-" xml:"-"` } @@ -343,27 +338,28 @@ type metadataOutputService4TestShapeOutputService4TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService4TestShapeOutputShape struct { +type OutputService4TestShapeOutputService4TestCaseOperation1Output struct { ListMember []*string `locationNameList:"item" type:"list"` - metadataOutputService4TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService4TestShapeOutputService4TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService4TestShapeOutputShape struct { +type metadataOutputService4TestShapeOutputService4TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService5ProtocolTest is a client for OutputService5ProtocolTest. type OutputService5ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService5ProtocolTest client. func NewOutputService5ProtocolTest(config *aws.Config) *OutputService5ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice5protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice5protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -379,39 +375,36 @@ func NewOutputService5ProtocolTest(config *aws.Config) *OutputService5ProtocolTe // newRequest creates a new request for a OutputService5ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService5ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService5ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService5TestCaseOperation1Request generates a request for the OutputService5TestCaseOperation1 operation. -func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1Request(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (req *aws.Request, output *OutputService5TestShapeOutputShape) { +const opOutputService5TestCaseOperation1 = "OperationName" - if opOutputService5TestCaseOperation1 == nil { - opOutputService5TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService5TestCaseOperation1Request generates a request for the OutputService5TestCaseOperation1 operation. +func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1Request(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (req *request.Request, output *OutputService5TestShapeOutputService5TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService5TestCaseOperation1, } if input == nil { input = &OutputService5TestShapeOutputService5TestCaseOperation1Input{} } - req = c.newRequest(opOutputService5TestCaseOperation1, input, output) - output = &OutputService5TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService5TestShapeOutputService5TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (*OutputService5TestShapeOutputShape, error) { +func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (*OutputService5TestShapeOutputService5TestCaseOperation1Output, error) { req, out := c.OutputService5TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService5TestCaseOperation1 *aws.Operation - type OutputService5TestShapeOutputService5TestCaseOperation1Input struct { metadataOutputService5TestShapeOutputService5TestCaseOperation1Input `json:"-" xml:"-"` } @@ -420,27 +413,28 @@ type metadataOutputService5TestShapeOutputService5TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService5TestShapeOutputShape struct { +type OutputService5TestShapeOutputService5TestCaseOperation1Output struct { ListMember []*string `type:"list" flattened:"true"` - metadataOutputService5TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService5TestShapeOutputService5TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService5TestShapeOutputShape struct { +type metadataOutputService5TestShapeOutputService5TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService6ProtocolTest is a client for OutputService6ProtocolTest. type OutputService6ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService6ProtocolTest client. func NewOutputService6ProtocolTest(config *aws.Config) *OutputService6ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice6protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice6protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -456,39 +450,36 @@ func NewOutputService6ProtocolTest(config *aws.Config) *OutputService6ProtocolTe // newRequest creates a new request for a OutputService6ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService6ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService6ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService6TestCaseOperation1Request generates a request for the OutputService6TestCaseOperation1 operation. -func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1Request(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (req *aws.Request, output *OutputService6TestShapeOutputShape) { +const opOutputService6TestCaseOperation1 = "OperationName" - if opOutputService6TestCaseOperation1 == nil { - opOutputService6TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService6TestCaseOperation1Request generates a request for the OutputService6TestCaseOperation1 operation. +func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1Request(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (req *request.Request, output *OutputService6TestShapeOutputService6TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService6TestCaseOperation1, } if input == nil { input = &OutputService6TestShapeOutputService6TestCaseOperation1Input{} } - req = c.newRequest(opOutputService6TestCaseOperation1, input, output) - output = &OutputService6TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService6TestShapeOutputService6TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (*OutputService6TestShapeOutputShape, error) { +func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (*OutputService6TestShapeOutputService6TestCaseOperation1Output, error) { req, out := c.OutputService6TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService6TestCaseOperation1 *aws.Operation - type OutputService6TestShapeOutputService6TestCaseOperation1Input struct { metadataOutputService6TestShapeOutputService6TestCaseOperation1Input `json:"-" xml:"-"` } @@ -497,13 +488,13 @@ type metadataOutputService6TestShapeOutputService6TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService6TestShapeOutputShape struct { +type OutputService6TestShapeOutputService6TestCaseOperation1Output struct { Map map[string]*OutputService6TestShapeStructureType `type:"map"` - metadataOutputService6TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService6TestShapeOutputService6TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService6TestShapeOutputShape struct { +type metadataOutputService6TestShapeOutputService6TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } @@ -517,17 +508,18 @@ type metadataOutputService6TestShapeStructureType struct { SDKShapeTraits bool `type:"structure"` } -// OutputService7ProtocolTest is a client for OutputService7ProtocolTest. type OutputService7ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService7ProtocolTest client. func NewOutputService7ProtocolTest(config *aws.Config) *OutputService7ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice7protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice7protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -543,39 +535,36 @@ func NewOutputService7ProtocolTest(config *aws.Config) *OutputService7ProtocolTe // newRequest creates a new request for a OutputService7ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService7ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService7ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService7TestCaseOperation1Request generates a request for the OutputService7TestCaseOperation1 operation. -func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1Request(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (req *aws.Request, output *OutputService7TestShapeOutputShape) { +const opOutputService7TestCaseOperation1 = "OperationName" - if opOutputService7TestCaseOperation1 == nil { - opOutputService7TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService7TestCaseOperation1Request generates a request for the OutputService7TestCaseOperation1 operation. +func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1Request(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (req *request.Request, output *OutputService7TestShapeOutputService7TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService7TestCaseOperation1, } if input == nil { input = &OutputService7TestShapeOutputService7TestCaseOperation1Input{} } - req = c.newRequest(opOutputService7TestCaseOperation1, input, output) - output = &OutputService7TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService7TestShapeOutputService7TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (*OutputService7TestShapeOutputShape, error) { +func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (*OutputService7TestShapeOutputService7TestCaseOperation1Output, error) { req, out := c.OutputService7TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService7TestCaseOperation1 *aws.Operation - type OutputService7TestShapeOutputService7TestCaseOperation1Input struct { metadataOutputService7TestShapeOutputService7TestCaseOperation1Input `json:"-" xml:"-"` } @@ -584,27 +573,28 @@ type metadataOutputService7TestShapeOutputService7TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService7TestShapeOutputShape struct { +type OutputService7TestShapeOutputService7TestCaseOperation1Output struct { Map map[string]*string `type:"map" flattened:"true"` - metadataOutputService7TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService7TestShapeOutputService7TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService7TestShapeOutputShape struct { +type metadataOutputService7TestShapeOutputService7TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService8ProtocolTest is a client for OutputService8ProtocolTest. type OutputService8ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService8ProtocolTest client. func NewOutputService8ProtocolTest(config *aws.Config) *OutputService8ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice8protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice8protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -620,39 +610,36 @@ func NewOutputService8ProtocolTest(config *aws.Config) *OutputService8ProtocolTe // newRequest creates a new request for a OutputService8ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService8ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService8ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService8TestCaseOperation1Request generates a request for the OutputService8TestCaseOperation1 operation. -func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1Request(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (req *aws.Request, output *OutputService8TestShapeOutputShape) { +const opOutputService8TestCaseOperation1 = "OperationName" - if opOutputService8TestCaseOperation1 == nil { - opOutputService8TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService8TestCaseOperation1Request generates a request for the OutputService8TestCaseOperation1 operation. +func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1Request(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (req *request.Request, output *OutputService8TestShapeOutputService8TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService8TestCaseOperation1, } if input == nil { input = &OutputService8TestShapeOutputService8TestCaseOperation1Input{} } - req = c.newRequest(opOutputService8TestCaseOperation1, input, output) - output = &OutputService8TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService8TestShapeOutputService8TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (*OutputService8TestShapeOutputShape, error) { +func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (*OutputService8TestShapeOutputService8TestCaseOperation1Output, error) { req, out := c.OutputService8TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService8TestCaseOperation1 *aws.Operation - type OutputService8TestShapeOutputService8TestCaseOperation1Input struct { metadataOutputService8TestShapeOutputService8TestCaseOperation1Input `json:"-" xml:"-"` } @@ -661,13 +648,13 @@ type metadataOutputService8TestShapeOutputService8TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService8TestShapeOutputShape struct { +type OutputService8TestShapeOutputService8TestCaseOperation1Output struct { Map map[string]*string `locationNameKey:"foo" locationNameValue:"bar" type:"map" flattened:"true"` - metadataOutputService8TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService8TestShapeOutputService8TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService8TestShapeOutputShape struct { +type metadataOutputService8TestShapeOutputService8TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build.go index 0f17031a0d8f..83ed8758ef97 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build.go @@ -6,19 +6,19 @@ package query import ( "net/url" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/internal/protocol/query/queryutil" ) // Build builds a request for an AWS Query service. -func Build(r *aws.Request) { +func Build(r *request.Request) { body := url.Values{ "Action": {r.Operation.Name}, "Version": {r.Service.APIVersion}, } if err := queryutil.Parse(body, r.Params, false); err != nil { - r.Error = apierr.New("Marshal", "failed encoding Query request", err) + r.Error = awserr.New("SerializationError", "failed encoding Query request", err) return } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build_test.go index da266758b4f5..7b29fd79d747 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/build_test.go @@ -1,10 +1,6 @@ package query_test import ( - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/internal/protocol/query" - "github.com/aws/aws-sdk-go/internal/signer/v4" - "bytes" "encoding/json" "encoding/xml" @@ -15,7 +11,14 @@ import ( "testing" "time" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" + "github.com/aws/aws-sdk-go/aws/service/serviceinfo" + "github.com/aws/aws-sdk-go/internal/protocol/query" "github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil" + "github.com/aws/aws-sdk-go/internal/signer/v4" "github.com/aws/aws-sdk-go/internal/util" "github.com/stretchr/testify/assert" ) @@ -31,17 +34,18 @@ var _ = util.Trim("") var _ = url.Values{} var _ = io.EOF -// InputService1ProtocolTest is a client for InputService1ProtocolTest. type InputService1ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService1ProtocolTest client. func NewInputService1ProtocolTest(config *aws.Config) *InputService1ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice1protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice1protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -57,70 +61,68 @@ func NewInputService1ProtocolTest(config *aws.Config) *InputService1ProtocolTest // newRequest creates a new request for a InputService1ProtocolTest operation and runs any // custom request initialization. -func (c *InputService1ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService1ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService1TestCaseOperation1Request generates a request for the InputService1TestCaseOperation1 operation. -func (c *InputService1ProtocolTest) InputService1TestCaseOperation1Request(input *InputService1TestShapeInputShape) (req *aws.Request, output *InputService1TestShapeInputService1TestCaseOperation1Output) { +const opInputService1TestCaseOperation1 = "OperationName" - if opInputService1TestCaseOperation1 == nil { - opInputService1TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService1TestCaseOperation1Request generates a request for the InputService1TestCaseOperation1 operation. +func (c *InputService1ProtocolTest) InputService1TestCaseOperation1Request(input *InputService1TestShapeInputService1TestCaseOperation1Input) (req *request.Request, output *InputService1TestShapeInputService1TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService1TestCaseOperation1, } if input == nil { - input = &InputService1TestShapeInputShape{} + input = &InputService1TestShapeInputService1TestCaseOperation1Input{} } - req = c.newRequest(opInputService1TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService1TestShapeInputService1TestCaseOperation1Output{} req.Data = output return } -func (c *InputService1ProtocolTest) InputService1TestCaseOperation1(input *InputService1TestShapeInputShape) (*InputService1TestShapeInputService1TestCaseOperation1Output, error) { +func (c *InputService1ProtocolTest) InputService1TestCaseOperation1(input *InputService1TestShapeInputService1TestCaseOperation1Input) (*InputService1TestShapeInputService1TestCaseOperation1Output, error) { req, out := c.InputService1TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService1TestCaseOperation1 *aws.Operation +type InputService1TestShapeInputService1TestCaseOperation1Input struct { + Bar *string `type:"string"` -type InputService1TestShapeInputService1TestCaseOperation1Output struct { - metadataInputService1TestShapeInputService1TestCaseOperation1Output `json:"-" xml:"-"` + Foo *string `type:"string"` + + metadataInputService1TestShapeInputService1TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService1TestShapeInputService1TestCaseOperation1Output struct { +type metadataInputService1TestShapeInputService1TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService1TestShapeInputShape struct { - Bar *string `type:"string"` - - Foo *string `type:"string"` - - metadataInputService1TestShapeInputShape `json:"-" xml:"-"` +type InputService1TestShapeInputService1TestCaseOperation1Output struct { + metadataInputService1TestShapeInputService1TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService1TestShapeInputShape struct { +type metadataInputService1TestShapeInputService1TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// InputService2ProtocolTest is a client for InputService2ProtocolTest. type InputService2ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService2ProtocolTest client. func NewInputService2ProtocolTest(config *aws.Config) *InputService2ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice2protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice2protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -136,54 +138,51 @@ func NewInputService2ProtocolTest(config *aws.Config) *InputService2ProtocolTest // newRequest creates a new request for a InputService2ProtocolTest operation and runs any // custom request initialization. -func (c *InputService2ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService2ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService2TestCaseOperation1Request generates a request for the InputService2TestCaseOperation1 operation. -func (c *InputService2ProtocolTest) InputService2TestCaseOperation1Request(input *InputService2TestShapeInputShape) (req *aws.Request, output *InputService2TestShapeInputService2TestCaseOperation1Output) { +const opInputService2TestCaseOperation1 = "OperationName" - if opInputService2TestCaseOperation1 == nil { - opInputService2TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService2TestCaseOperation1Request generates a request for the InputService2TestCaseOperation1 operation. +func (c *InputService2ProtocolTest) InputService2TestCaseOperation1Request(input *InputService2TestShapeInputService2TestCaseOperation1Input) (req *request.Request, output *InputService2TestShapeInputService2TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService2TestCaseOperation1, } if input == nil { - input = &InputService2TestShapeInputShape{} + input = &InputService2TestShapeInputService2TestCaseOperation1Input{} } - req = c.newRequest(opInputService2TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService2TestShapeInputService2TestCaseOperation1Output{} req.Data = output return } -func (c *InputService2ProtocolTest) InputService2TestCaseOperation1(input *InputService2TestShapeInputShape) (*InputService2TestShapeInputService2TestCaseOperation1Output, error) { +func (c *InputService2ProtocolTest) InputService2TestCaseOperation1(input *InputService2TestShapeInputService2TestCaseOperation1Input) (*InputService2TestShapeInputService2TestCaseOperation1Output, error) { req, out := c.InputService2TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService2TestCaseOperation1 *aws.Operation +type InputService2TestShapeInputService2TestCaseOperation1Input struct { + StructArg *InputService2TestShapeStructType `type:"structure"` -type InputService2TestShapeInputService2TestCaseOperation1Output struct { - metadataInputService2TestShapeInputService2TestCaseOperation1Output `json:"-" xml:"-"` + metadataInputService2TestShapeInputService2TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService2TestShapeInputService2TestCaseOperation1Output struct { +type metadataInputService2TestShapeInputService2TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService2TestShapeInputShape struct { - StructArg *InputService2TestShapeStructType `type:"structure"` - - metadataInputService2TestShapeInputShape `json:"-" xml:"-"` +type InputService2TestShapeInputService2TestCaseOperation1Output struct { + metadataInputService2TestShapeInputService2TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService2TestShapeInputShape struct { +type metadataInputService2TestShapeInputService2TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } @@ -197,17 +196,18 @@ type metadataInputService2TestShapeStructType struct { SDKShapeTraits bool `type:"structure"` } -// InputService3ProtocolTest is a client for InputService3ProtocolTest. type InputService3ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService3ProtocolTest client. func NewInputService3ProtocolTest(config *aws.Config) *InputService3ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice3protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice3protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -223,66 +223,46 @@ func NewInputService3ProtocolTest(config *aws.Config) *InputService3ProtocolTest // newRequest creates a new request for a InputService3ProtocolTest operation and runs any // custom request initialization. -func (c *InputService3ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService3ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService3TestCaseOperation1Request generates a request for the InputService3TestCaseOperation1 operation. -func (c *InputService3ProtocolTest) InputService3TestCaseOperation1Request(input *InputService3TestShapeInputShape) (req *aws.Request, output *InputService3TestShapeInputService3TestCaseOperation1Output) { +const opInputService3TestCaseOperation1 = "OperationName" - if opInputService3TestCaseOperation1 == nil { - opInputService3TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService3TestCaseOperation1Request generates a request for the InputService3TestCaseOperation1 operation. +func (c *InputService3ProtocolTest) InputService3TestCaseOperation1Request(input *InputService3TestShapeInputService3TestCaseOperation1Input) (req *request.Request, output *InputService3TestShapeInputService3TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService3TestCaseOperation1, } if input == nil { - input = &InputService3TestShapeInputShape{} + input = &InputService3TestShapeInputService3TestCaseOperation1Input{} } - req = c.newRequest(opInputService3TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService3TestShapeInputService3TestCaseOperation1Output{} req.Data = output return } -func (c *InputService3ProtocolTest) InputService3TestCaseOperation1(input *InputService3TestShapeInputShape) (*InputService3TestShapeInputService3TestCaseOperation1Output, error) { +func (c *InputService3ProtocolTest) InputService3TestCaseOperation1(input *InputService3TestShapeInputService3TestCaseOperation1Input) (*InputService3TestShapeInputService3TestCaseOperation1Output, error) { req, out := c.InputService3TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService3TestCaseOperation1 *aws.Operation - -// InputService3TestCaseOperation2Request generates a request for the InputService3TestCaseOperation2 operation. -func (c *InputService3ProtocolTest) InputService3TestCaseOperation2Request(input *InputService3TestShapeInputShape) (req *aws.Request, output *InputService3TestShapeInputService3TestCaseOperation2Output) { - - if opInputService3TestCaseOperation2 == nil { - opInputService3TestCaseOperation2 = &aws.Operation{ - Name: "OperationName", - } - } - - if input == nil { - input = &InputService3TestShapeInputShape{} - } +type InputService3TestShapeInputService3TestCaseOperation1Input struct { + ListArg []*string `type:"list"` - req = c.newRequest(opInputService3TestCaseOperation2, input, output) - output = &InputService3TestShapeInputService3TestCaseOperation2Output{} - req.Data = output - return + metadataInputService3TestShapeInputService3TestCaseOperation1Input `json:"-" xml:"-"` } -func (c *InputService3ProtocolTest) InputService3TestCaseOperation2(input *InputService3TestShapeInputShape) (*InputService3TestShapeInputService3TestCaseOperation2Output, error) { - req, out := c.InputService3TestCaseOperation2Request(input) - err := req.Send() - return out, err +type metadataInputService3TestShapeInputService3TestCaseOperation1Input struct { + SDKShapeTraits bool `type:"structure"` } -var opInputService3TestCaseOperation2 *aws.Operation - type InputService3TestShapeInputService3TestCaseOperation1Output struct { metadataInputService3TestShapeInputService3TestCaseOperation1Output `json:"-" xml:"-"` } @@ -291,35 +271,18 @@ type metadataInputService3TestShapeInputService3TestCaseOperation1Output struct SDKShapeTraits bool `type:"structure"` } -type InputService3TestShapeInputService3TestCaseOperation2Output struct { - metadataInputService3TestShapeInputService3TestCaseOperation2Output `json:"-" xml:"-"` -} - -type metadataInputService3TestShapeInputService3TestCaseOperation2Output struct { - SDKShapeTraits bool `type:"structure"` -} - -type InputService3TestShapeInputShape struct { - ListArg []*string `type:"list"` - - metadataInputService3TestShapeInputShape `json:"-" xml:"-"` -} - -type metadataInputService3TestShapeInputShape struct { - SDKShapeTraits bool `type:"structure"` -} - -// InputService4ProtocolTest is a client for InputService4ProtocolTest. type InputService4ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService4ProtocolTest client. func NewInputService4ProtocolTest(config *aws.Config) *InputService4ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice4protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice4protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -335,66 +298,48 @@ func NewInputService4ProtocolTest(config *aws.Config) *InputService4ProtocolTest // newRequest creates a new request for a InputService4ProtocolTest operation and runs any // custom request initialization. -func (c *InputService4ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService4ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService4TestCaseOperation1Request generates a request for the InputService4TestCaseOperation1 operation. -func (c *InputService4ProtocolTest) InputService4TestCaseOperation1Request(input *InputService4TestShapeInputShape) (req *aws.Request, output *InputService4TestShapeInputService4TestCaseOperation1Output) { +const opInputService4TestCaseOperation1 = "OperationName" - if opInputService4TestCaseOperation1 == nil { - opInputService4TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService4TestCaseOperation1Request generates a request for the InputService4TestCaseOperation1 operation. +func (c *InputService4ProtocolTest) InputService4TestCaseOperation1Request(input *InputService4TestShapeInputService4TestCaseOperation1Input) (req *request.Request, output *InputService4TestShapeInputService4TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService4TestCaseOperation1, } if input == nil { - input = &InputService4TestShapeInputShape{} + input = &InputService4TestShapeInputService4TestCaseOperation1Input{} } - req = c.newRequest(opInputService4TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService4TestShapeInputService4TestCaseOperation1Output{} req.Data = output return } -func (c *InputService4ProtocolTest) InputService4TestCaseOperation1(input *InputService4TestShapeInputShape) (*InputService4TestShapeInputService4TestCaseOperation1Output, error) { +func (c *InputService4ProtocolTest) InputService4TestCaseOperation1(input *InputService4TestShapeInputService4TestCaseOperation1Input) (*InputService4TestShapeInputService4TestCaseOperation1Output, error) { req, out := c.InputService4TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService4TestCaseOperation1 *aws.Operation - -// InputService4TestCaseOperation2Request generates a request for the InputService4TestCaseOperation2 operation. -func (c *InputService4ProtocolTest) InputService4TestCaseOperation2Request(input *InputService4TestShapeInputShape) (req *aws.Request, output *InputService4TestShapeInputService4TestCaseOperation2Output) { - - if opInputService4TestCaseOperation2 == nil { - opInputService4TestCaseOperation2 = &aws.Operation{ - Name: "OperationName", - } - } +type InputService4TestShapeInputService4TestCaseOperation1Input struct { + ListArg []*string `type:"list" flattened:"true"` - if input == nil { - input = &InputService4TestShapeInputShape{} - } + ScalarArg *string `type:"string"` - req = c.newRequest(opInputService4TestCaseOperation2, input, output) - output = &InputService4TestShapeInputService4TestCaseOperation2Output{} - req.Data = output - return + metadataInputService4TestShapeInputService4TestCaseOperation1Input `json:"-" xml:"-"` } -func (c *InputService4ProtocolTest) InputService4TestCaseOperation2(input *InputService4TestShapeInputShape) (*InputService4TestShapeInputService4TestCaseOperation2Output, error) { - req, out := c.InputService4TestCaseOperation2Request(input) - err := req.Send() - return out, err +type metadataInputService4TestShapeInputService4TestCaseOperation1Input struct { + SDKShapeTraits bool `type:"structure"` } -var opInputService4TestCaseOperation2 *aws.Operation - type InputService4TestShapeInputService4TestCaseOperation1Output struct { metadataInputService4TestShapeInputService4TestCaseOperation1Output `json:"-" xml:"-"` } @@ -403,37 +348,18 @@ type metadataInputService4TestShapeInputService4TestCaseOperation1Output struct SDKShapeTraits bool `type:"structure"` } -type InputService4TestShapeInputService4TestCaseOperation2Output struct { - metadataInputService4TestShapeInputService4TestCaseOperation2Output `json:"-" xml:"-"` -} - -type metadataInputService4TestShapeInputService4TestCaseOperation2Output struct { - SDKShapeTraits bool `type:"structure"` -} - -type InputService4TestShapeInputShape struct { - ListArg []*string `type:"list" flattened:"true"` - - ScalarArg *string `type:"string"` - - metadataInputService4TestShapeInputShape `json:"-" xml:"-"` -} - -type metadataInputService4TestShapeInputShape struct { - SDKShapeTraits bool `type:"structure"` -} - -// InputService5ProtocolTest is a client for InputService5ProtocolTest. type InputService5ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService5ProtocolTest client. func NewInputService5ProtocolTest(config *aws.Config) *InputService5ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice5protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice5protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -449,66 +375,48 @@ func NewInputService5ProtocolTest(config *aws.Config) *InputService5ProtocolTest // newRequest creates a new request for a InputService5ProtocolTest operation and runs any // custom request initialization. -func (c *InputService5ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService5ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService5TestCaseOperation1Request generates a request for the InputService5TestCaseOperation1 operation. -func (c *InputService5ProtocolTest) InputService5TestCaseOperation1Request(input *InputService5TestShapeInputShape) (req *aws.Request, output *InputService5TestShapeInputService5TestCaseOperation1Output) { +const opInputService5TestCaseOperation1 = "OperationName" - if opInputService5TestCaseOperation1 == nil { - opInputService5TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService5TestCaseOperation1Request generates a request for the InputService5TestCaseOperation1 operation. +func (c *InputService5ProtocolTest) InputService5TestCaseOperation1Request(input *InputService5TestShapeInputService5TestCaseOperation1Input) (req *request.Request, output *InputService5TestShapeInputService5TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService5TestCaseOperation1, } if input == nil { - input = &InputService5TestShapeInputShape{} + input = &InputService5TestShapeInputService5TestCaseOperation1Input{} } - req = c.newRequest(opInputService5TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService5TestShapeInputService5TestCaseOperation1Output{} req.Data = output return } -func (c *InputService5ProtocolTest) InputService5TestCaseOperation1(input *InputService5TestShapeInputShape) (*InputService5TestShapeInputService5TestCaseOperation1Output, error) { +func (c *InputService5ProtocolTest) InputService5TestCaseOperation1(input *InputService5TestShapeInputService5TestCaseOperation1Input) (*InputService5TestShapeInputService5TestCaseOperation1Output, error) { req, out := c.InputService5TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService5TestCaseOperation1 *aws.Operation +type InputService5TestShapeInputService5TestCaseOperation1Input struct { + ListArg []*string `locationNameList:"ListArgLocation" type:"list" flattened:"true"` -// InputService5TestCaseOperation2Request generates a request for the InputService5TestCaseOperation2 operation. -func (c *InputService5ProtocolTest) InputService5TestCaseOperation2Request(input *InputService5TestShapeInputShape) (req *aws.Request, output *InputService5TestShapeInputService5TestCaseOperation2Output) { - - if opInputService5TestCaseOperation2 == nil { - opInputService5TestCaseOperation2 = &aws.Operation{ - Name: "OperationName", - } - } - - if input == nil { - input = &InputService5TestShapeInputShape{} - } + ScalarArg *string `type:"string"` - req = c.newRequest(opInputService5TestCaseOperation2, input, output) - output = &InputService5TestShapeInputService5TestCaseOperation2Output{} - req.Data = output - return + metadataInputService5TestShapeInputService5TestCaseOperation1Input `json:"-" xml:"-"` } -func (c *InputService5ProtocolTest) InputService5TestCaseOperation2(input *InputService5TestShapeInputShape) (*InputService5TestShapeInputService5TestCaseOperation2Output, error) { - req, out := c.InputService5TestCaseOperation2Request(input) - err := req.Send() - return out, err +type metadataInputService5TestShapeInputService5TestCaseOperation1Input struct { + SDKShapeTraits bool `type:"structure"` } -var opInputService5TestCaseOperation2 *aws.Operation - type InputService5TestShapeInputService5TestCaseOperation1Output struct { metadataInputService5TestShapeInputService5TestCaseOperation1Output `json:"-" xml:"-"` } @@ -517,35 +425,18 @@ type metadataInputService5TestShapeInputService5TestCaseOperation1Output struct SDKShapeTraits bool `type:"structure"` } -type InputService5TestShapeInputService5TestCaseOperation2Output struct { - metadataInputService5TestShapeInputService5TestCaseOperation2Output `json:"-" xml:"-"` -} - -type metadataInputService5TestShapeInputService5TestCaseOperation2Output struct { - SDKShapeTraits bool `type:"structure"` -} - -type InputService5TestShapeInputShape struct { - MapArg map[string]*string `type:"map"` - - metadataInputService5TestShapeInputShape `json:"-" xml:"-"` -} - -type metadataInputService5TestShapeInputShape struct { - SDKShapeTraits bool `type:"structure"` -} - -// InputService6ProtocolTest is a client for InputService6ProtocolTest. type InputService6ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService6ProtocolTest client. func NewInputService6ProtocolTest(config *aws.Config) *InputService6ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice6protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice6protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -561,68 +452,66 @@ func NewInputService6ProtocolTest(config *aws.Config) *InputService6ProtocolTest // newRequest creates a new request for a InputService6ProtocolTest operation and runs any // custom request initialization. -func (c *InputService6ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService6ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService6TestCaseOperation1Request generates a request for the InputService6TestCaseOperation1 operation. -func (c *InputService6ProtocolTest) InputService6TestCaseOperation1Request(input *InputService6TestShapeInputShape) (req *aws.Request, output *InputService6TestShapeInputService6TestCaseOperation1Output) { +const opInputService6TestCaseOperation1 = "OperationName" - if opInputService6TestCaseOperation1 == nil { - opInputService6TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService6TestCaseOperation1Request generates a request for the InputService6TestCaseOperation1 operation. +func (c *InputService6ProtocolTest) InputService6TestCaseOperation1Request(input *InputService6TestShapeInputService6TestCaseOperation1Input) (req *request.Request, output *InputService6TestShapeInputService6TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService6TestCaseOperation1, } if input == nil { - input = &InputService6TestShapeInputShape{} + input = &InputService6TestShapeInputService6TestCaseOperation1Input{} } - req = c.newRequest(opInputService6TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService6TestShapeInputService6TestCaseOperation1Output{} req.Data = output return } -func (c *InputService6ProtocolTest) InputService6TestCaseOperation1(input *InputService6TestShapeInputShape) (*InputService6TestShapeInputService6TestCaseOperation1Output, error) { +func (c *InputService6ProtocolTest) InputService6TestCaseOperation1(input *InputService6TestShapeInputService6TestCaseOperation1Input) (*InputService6TestShapeInputService6TestCaseOperation1Output, error) { req, out := c.InputService6TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService6TestCaseOperation1 *aws.Operation +type InputService6TestShapeInputService6TestCaseOperation1Input struct { + MapArg map[string]*string `type:"map"` -type InputService6TestShapeInputService6TestCaseOperation1Output struct { - metadataInputService6TestShapeInputService6TestCaseOperation1Output `json:"-" xml:"-"` + metadataInputService6TestShapeInputService6TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService6TestShapeInputService6TestCaseOperation1Output struct { +type metadataInputService6TestShapeInputService6TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService6TestShapeInputShape struct { - MapArg map[string]*string `locationNameKey:"TheKey" locationNameValue:"TheValue" type:"map"` - - metadataInputService6TestShapeInputShape `json:"-" xml:"-"` +type InputService6TestShapeInputService6TestCaseOperation1Output struct { + metadataInputService6TestShapeInputService6TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService6TestShapeInputShape struct { +type metadataInputService6TestShapeInputService6TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// InputService7ProtocolTest is a client for InputService7ProtocolTest. type InputService7ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService7ProtocolTest client. func NewInputService7ProtocolTest(config *aws.Config) *InputService7ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice7protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice7protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -638,68 +527,66 @@ func NewInputService7ProtocolTest(config *aws.Config) *InputService7ProtocolTest // newRequest creates a new request for a InputService7ProtocolTest operation and runs any // custom request initialization. -func (c *InputService7ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService7ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService7TestCaseOperation1Request generates a request for the InputService7TestCaseOperation1 operation. -func (c *InputService7ProtocolTest) InputService7TestCaseOperation1Request(input *InputService7TestShapeInputShape) (req *aws.Request, output *InputService7TestShapeInputService7TestCaseOperation1Output) { +const opInputService7TestCaseOperation1 = "OperationName" - if opInputService7TestCaseOperation1 == nil { - opInputService7TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService7TestCaseOperation1Request generates a request for the InputService7TestCaseOperation1 operation. +func (c *InputService7ProtocolTest) InputService7TestCaseOperation1Request(input *InputService7TestShapeInputService7TestCaseOperation1Input) (req *request.Request, output *InputService7TestShapeInputService7TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService7TestCaseOperation1, } if input == nil { - input = &InputService7TestShapeInputShape{} + input = &InputService7TestShapeInputService7TestCaseOperation1Input{} } - req = c.newRequest(opInputService7TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService7TestShapeInputService7TestCaseOperation1Output{} req.Data = output return } -func (c *InputService7ProtocolTest) InputService7TestCaseOperation1(input *InputService7TestShapeInputShape) (*InputService7TestShapeInputService7TestCaseOperation1Output, error) { +func (c *InputService7ProtocolTest) InputService7TestCaseOperation1(input *InputService7TestShapeInputService7TestCaseOperation1Input) (*InputService7TestShapeInputService7TestCaseOperation1Output, error) { req, out := c.InputService7TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService7TestCaseOperation1 *aws.Operation +type InputService7TestShapeInputService7TestCaseOperation1Input struct { + BlobArg []byte `type:"blob"` -type InputService7TestShapeInputService7TestCaseOperation1Output struct { - metadataInputService7TestShapeInputService7TestCaseOperation1Output `json:"-" xml:"-"` + metadataInputService7TestShapeInputService7TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService7TestShapeInputService7TestCaseOperation1Output struct { +type metadataInputService7TestShapeInputService7TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService7TestShapeInputShape struct { - BlobArg []byte `type:"blob"` - - metadataInputService7TestShapeInputShape `json:"-" xml:"-"` +type InputService7TestShapeInputService7TestCaseOperation1Output struct { + metadataInputService7TestShapeInputService7TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService7TestShapeInputShape struct { +type metadataInputService7TestShapeInputService7TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// InputService8ProtocolTest is a client for InputService8ProtocolTest. type InputService8ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService8ProtocolTest client. func NewInputService8ProtocolTest(config *aws.Config) *InputService8ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice8protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice8protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -715,68 +602,66 @@ func NewInputService8ProtocolTest(config *aws.Config) *InputService8ProtocolTest // newRequest creates a new request for a InputService8ProtocolTest operation and runs any // custom request initialization. -func (c *InputService8ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService8ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService8TestCaseOperation1Request generates a request for the InputService8TestCaseOperation1 operation. -func (c *InputService8ProtocolTest) InputService8TestCaseOperation1Request(input *InputService8TestShapeInputShape) (req *aws.Request, output *InputService8TestShapeInputService8TestCaseOperation1Output) { +const opInputService8TestCaseOperation1 = "OperationName" - if opInputService8TestCaseOperation1 == nil { - opInputService8TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService8TestCaseOperation1Request generates a request for the InputService8TestCaseOperation1 operation. +func (c *InputService8ProtocolTest) InputService8TestCaseOperation1Request(input *InputService8TestShapeInputService8TestCaseOperation1Input) (req *request.Request, output *InputService8TestShapeInputService8TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService8TestCaseOperation1, } if input == nil { - input = &InputService8TestShapeInputShape{} + input = &InputService8TestShapeInputService8TestCaseOperation1Input{} } - req = c.newRequest(opInputService8TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService8TestShapeInputService8TestCaseOperation1Output{} req.Data = output return } -func (c *InputService8ProtocolTest) InputService8TestCaseOperation1(input *InputService8TestShapeInputShape) (*InputService8TestShapeInputService8TestCaseOperation1Output, error) { +func (c *InputService8ProtocolTest) InputService8TestCaseOperation1(input *InputService8TestShapeInputService8TestCaseOperation1Input) (*InputService8TestShapeInputService8TestCaseOperation1Output, error) { req, out := c.InputService8TestCaseOperation1Request(input) err := req.Send() return out, err } -var opInputService8TestCaseOperation1 *aws.Operation +type InputService8TestShapeInputService8TestCaseOperation1Input struct { + TimeArg *time.Time `type:"timestamp" timestampFormat:"iso8601"` -type InputService8TestShapeInputService8TestCaseOperation1Output struct { - metadataInputService8TestShapeInputService8TestCaseOperation1Output `json:"-" xml:"-"` + metadataInputService8TestShapeInputService8TestCaseOperation1Input `json:"-" xml:"-"` } -type metadataInputService8TestShapeInputService8TestCaseOperation1Output struct { +type metadataInputService8TestShapeInputService8TestCaseOperation1Input struct { SDKShapeTraits bool `type:"structure"` } -type InputService8TestShapeInputShape struct { - TimeArg *time.Time `type:"timestamp" timestampFormat:"iso8601"` - - metadataInputService8TestShapeInputShape `json:"-" xml:"-"` +type InputService8TestShapeInputService8TestCaseOperation1Output struct { + metadataInputService8TestShapeInputService8TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataInputService8TestShapeInputShape struct { +type metadataInputService8TestShapeInputService8TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// InputService9ProtocolTest is a client for InputService9ProtocolTest. type InputService9ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new InputService9ProtocolTest client. func NewInputService9ProtocolTest(config *aws.Config) *InputService9ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "inputservice9protocoltest", - APIVersion: "2014-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "inputservice9protocoltest", + APIVersion: "2014-01-01", + }, } service.Initialize() @@ -792,26 +677,25 @@ func NewInputService9ProtocolTest(config *aws.Config) *InputService9ProtocolTest // newRequest creates a new request for a InputService9ProtocolTest operation and runs any // custom request initialization. -func (c *InputService9ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *InputService9ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// InputService9TestCaseOperation1Request generates a request for the InputService9TestCaseOperation1 operation. -func (c *InputService9ProtocolTest) InputService9TestCaseOperation1Request(input *InputService9TestShapeInputShape) (req *aws.Request, output *InputService9TestShapeInputService9TestCaseOperation1Output) { +const opInputService9TestCaseOperation1 = "OperationName" - if opInputService9TestCaseOperation1 == nil { - opInputService9TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// InputService9TestCaseOperation1Request generates a request for the InputService9TestCaseOperation1 operation. +func (c *InputService9ProtocolTest) InputService9TestCaseOperation1Request(input *InputService9TestShapeInputShape) (req *request.Request, output *InputService9TestShapeInputService9TestCaseOperation1Output) { + op := &request.Operation{ + Name: opInputService9TestCaseOperation1, } if input == nil { input = &InputService9TestShapeInputShape{} } - req = c.newRequest(opInputService9TestCaseOperation1, input, output) + req = c.newRequest(op, input, output) output = &InputService9TestShapeInputService9TestCaseOperation1Output{} req.Data = output return @@ -823,22 +707,19 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation1(input *Input return out, err } -var opInputService9TestCaseOperation1 *aws.Operation +const opInputService9TestCaseOperation2 = "OperationName" // InputService9TestCaseOperation2Request generates a request for the InputService9TestCaseOperation2 operation. -func (c *InputService9ProtocolTest) InputService9TestCaseOperation2Request(input *InputService9TestShapeInputShape) (req *aws.Request, output *InputService9TestShapeInputService9TestCaseOperation2Output) { - - if opInputService9TestCaseOperation2 == nil { - opInputService9TestCaseOperation2 = &aws.Operation{ - Name: "OperationName", - } +func (c *InputService9ProtocolTest) InputService9TestCaseOperation2Request(input *InputService9TestShapeInputShape) (req *request.Request, output *InputService9TestShapeInputService9TestCaseOperation2Output) { + op := &request.Operation{ + Name: opInputService9TestCaseOperation2, } if input == nil { input = &InputService9TestShapeInputShape{} } - req = c.newRequest(opInputService9TestCaseOperation2, input, output) + req = c.newRequest(op, input, output) output = &InputService9TestShapeInputService9TestCaseOperation2Output{} req.Data = output return @@ -850,22 +731,19 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation2(input *Input return out, err } -var opInputService9TestCaseOperation2 *aws.Operation +const opInputService9TestCaseOperation3 = "OperationName" // InputService9TestCaseOperation3Request generates a request for the InputService9TestCaseOperation3 operation. -func (c *InputService9ProtocolTest) InputService9TestCaseOperation3Request(input *InputService9TestShapeInputShape) (req *aws.Request, output *InputService9TestShapeInputService9TestCaseOperation3Output) { - - if opInputService9TestCaseOperation3 == nil { - opInputService9TestCaseOperation3 = &aws.Operation{ - Name: "OperationName", - } +func (c *InputService9ProtocolTest) InputService9TestCaseOperation3Request(input *InputService9TestShapeInputShape) (req *request.Request, output *InputService9TestShapeInputService9TestCaseOperation3Output) { + op := &request.Operation{ + Name: opInputService9TestCaseOperation3, } if input == nil { input = &InputService9TestShapeInputShape{} } - req = c.newRequest(opInputService9TestCaseOperation3, input, output) + req = c.newRequest(op, input, output) output = &InputService9TestShapeInputService9TestCaseOperation3Output{} req.Data = output return @@ -877,22 +755,19 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation3(input *Input return out, err } -var opInputService9TestCaseOperation3 *aws.Operation +const opInputService9TestCaseOperation4 = "OperationName" // InputService9TestCaseOperation4Request generates a request for the InputService9TestCaseOperation4 operation. -func (c *InputService9ProtocolTest) InputService9TestCaseOperation4Request(input *InputService9TestShapeInputShape) (req *aws.Request, output *InputService9TestShapeInputService9TestCaseOperation4Output) { - - if opInputService9TestCaseOperation4 == nil { - opInputService9TestCaseOperation4 = &aws.Operation{ - Name: "OperationName", - } +func (c *InputService9ProtocolTest) InputService9TestCaseOperation4Request(input *InputService9TestShapeInputShape) (req *request.Request, output *InputService9TestShapeInputService9TestCaseOperation4Output) { + op := &request.Operation{ + Name: opInputService9TestCaseOperation4, } if input == nil { input = &InputService9TestShapeInputShape{} } - req = c.newRequest(opInputService9TestCaseOperation4, input, output) + req = c.newRequest(op, input, output) output = &InputService9TestShapeInputService9TestCaseOperation4Output{} req.Data = output return @@ -904,22 +779,19 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation4(input *Input return out, err } -var opInputService9TestCaseOperation4 *aws.Operation +const opInputService9TestCaseOperation5 = "OperationName" // InputService9TestCaseOperation5Request generates a request for the InputService9TestCaseOperation5 operation. -func (c *InputService9ProtocolTest) InputService9TestCaseOperation5Request(input *InputService9TestShapeInputShape) (req *aws.Request, output *InputService9TestShapeInputService9TestCaseOperation5Output) { - - if opInputService9TestCaseOperation5 == nil { - opInputService9TestCaseOperation5 = &aws.Operation{ - Name: "OperationName", - } +func (c *InputService9ProtocolTest) InputService9TestCaseOperation5Request(input *InputService9TestShapeInputShape) (req *request.Request, output *InputService9TestShapeInputService9TestCaseOperation5Output) { + op := &request.Operation{ + Name: opInputService9TestCaseOperation5, } if input == nil { input = &InputService9TestShapeInputShape{} } - req = c.newRequest(opInputService9TestCaseOperation5, input, output) + req = c.newRequest(op, input, output) output = &InputService9TestShapeInputService9TestCaseOperation5Output{} req.Data = output return @@ -931,22 +803,19 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation5(input *Input return out, err } -var opInputService9TestCaseOperation5 *aws.Operation +const opInputService9TestCaseOperation6 = "OperationName" // InputService9TestCaseOperation6Request generates a request for the InputService9TestCaseOperation6 operation. -func (c *InputService9ProtocolTest) InputService9TestCaseOperation6Request(input *InputService9TestShapeInputShape) (req *aws.Request, output *InputService9TestShapeInputService9TestCaseOperation6Output) { - - if opInputService9TestCaseOperation6 == nil { - opInputService9TestCaseOperation6 = &aws.Operation{ - Name: "OperationName", - } +func (c *InputService9ProtocolTest) InputService9TestCaseOperation6Request(input *InputService9TestShapeInputShape) (req *request.Request, output *InputService9TestShapeInputService9TestCaseOperation6Output) { + op := &request.Operation{ + Name: opInputService9TestCaseOperation6, } if input == nil { input = &InputService9TestShapeInputShape{} } - req = c.newRequest(opInputService9TestCaseOperation6, input, output) + req = c.newRequest(op, input, output) output = &InputService9TestShapeInputService9TestCaseOperation6Output{} req.Data = output return @@ -958,8 +827,6 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation6(input *Input return out, err } -var opInputService9TestCaseOperation6 *aws.Operation - type InputService9TestShapeInputService9TestCaseOperation1Output struct { metadataInputService9TestShapeInputService9TestCaseOperation1Output `json:"-" xml:"-"` } @@ -1042,7 +909,7 @@ func TestInputService1ProtocolTestScalarMembersCase1(t *testing.T) { svc := NewInputService1ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService1TestShapeInputShape{ + input := &InputService1TestShapeInputService1TestCaseOperation1Input{ Bar: aws.String("val2"), Foo: aws.String("val1"), } @@ -1069,7 +936,7 @@ func TestInputService2ProtocolTestNestedStructureMembersCase1(t *testing.T) { svc := NewInputService2ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService2TestShapeInputShape{ + input := &InputService2TestShapeInputService2TestCaseOperation1Input{ StructArg: &InputService2TestShapeStructType{ ScalarArg: aws.String("foo"), }, @@ -1097,7 +964,7 @@ func TestInputService3ProtocolTestListTypesCase1(t *testing.T) { svc := NewInputService3ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService3TestShapeInputShape{ + input := &InputService3TestShapeInputService3TestCaseOperation1Input{ ListArg: []*string{ aws.String("foo"), aws.String("bar"), @@ -1123,37 +990,11 @@ func TestInputService3ProtocolTestListTypesCase1(t *testing.T) { } -func TestInputService3ProtocolTestListTypesCase2(t *testing.T) { - svc := NewInputService3ProtocolTest(nil) - svc.Endpoint = "https://test" - - input := &InputService3TestShapeInputShape{ - ListArg: []*string{}, - } - req, _ := svc.InputService3TestCaseOperation2Request(input) - r := req.HTTPRequest - - // build request - query.Build(req) - assert.NoError(t, req.Error) - - // assert body - assert.NotNil(t, r.Body) - body, _ := ioutil.ReadAll(r.Body) - assert.Equal(t, util.Trim(`Action=OperationName&ListArg=&Version=2014-01-01`), util.Trim(string(body))) - - // assert URL - assert.Equal(t, "https://test/", r.URL.String()) - - // assert headers - -} - func TestInputService4ProtocolTestFlattenedListCase1(t *testing.T) { svc := NewInputService4ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService4TestShapeInputShape{ + input := &InputService4TestShapeInputService4TestCaseOperation1Input{ ListArg: []*string{ aws.String("a"), aws.String("b"), @@ -1180,42 +1021,17 @@ func TestInputService4ProtocolTestFlattenedListCase1(t *testing.T) { } -func TestInputService4ProtocolTestFlattenedListCase2(t *testing.T) { - svc := NewInputService4ProtocolTest(nil) - svc.Endpoint = "https://test" - - input := &InputService4TestShapeInputShape{ - ListArg: []*string{}, - ScalarArg: aws.String("foo"), - } - req, _ := svc.InputService4TestCaseOperation2Request(input) - r := req.HTTPRequest - - // build request - query.Build(req) - assert.NoError(t, req.Error) - - // assert body - assert.NotNil(t, r.Body) - body, _ := ioutil.ReadAll(r.Body) - assert.Equal(t, util.Trim(`Action=OperationName&ListArg=&ScalarArg=foo&Version=2014-01-01`), util.Trim(string(body))) - - // assert URL - assert.Equal(t, "https://test/", r.URL.String()) - - // assert headers - -} - -func TestInputService5ProtocolTestSerializeMapTypeCase1(t *testing.T) { +func TestInputService5ProtocolTestFlattenedListWithLocationNameCase1(t *testing.T) { svc := NewInputService5ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService5TestShapeInputShape{ - MapArg: map[string]*string{ - "key1": aws.String("val1"), - "key2": aws.String("val2"), + input := &InputService5TestShapeInputService5TestCaseOperation1Input{ + ListArg: []*string{ + aws.String("a"), + aws.String("b"), + aws.String("c"), }, + ScalarArg: aws.String("foo"), } req, _ := svc.InputService5TestCaseOperation1Request(input) r := req.HTTPRequest @@ -1227,7 +1043,7 @@ func TestInputService5ProtocolTestSerializeMapTypeCase1(t *testing.T) { // assert body assert.NotNil(t, r.Body) body, _ := ioutil.ReadAll(r.Body) - assert.Equal(t, util.Trim(`Action=OperationName&MapArg.entry.1.key=key1&MapArg.entry.1.value=val1&MapArg.entry.2.key=key2&MapArg.entry.2.value=val2&Version=2014-01-01`), util.Trim(string(body))) + assert.Equal(t, util.Trim(`Action=OperationName&ListArgLocation.1=a&ListArgLocation.2=b&ListArgLocation.3=c&ScalarArg=foo&Version=2014-01-01`), util.Trim(string(body))) // assert URL assert.Equal(t, "https://test/", r.URL.String()) @@ -1236,37 +1052,11 @@ func TestInputService5ProtocolTestSerializeMapTypeCase1(t *testing.T) { } -func TestInputService5ProtocolTestSerializeMapTypeCase2(t *testing.T) { - svc := NewInputService5ProtocolTest(nil) - svc.Endpoint = "https://test" - - input := &InputService5TestShapeInputShape{ - MapArg: map[string]*string{}, - } - req, _ := svc.InputService5TestCaseOperation2Request(input) - r := req.HTTPRequest - - // build request - query.Build(req) - assert.NoError(t, req.Error) - - // assert body - assert.NotNil(t, r.Body) - body, _ := ioutil.ReadAll(r.Body) - assert.Equal(t, util.Trim(`Action=OperationName&MapArg=&Version=2014-01-01`), util.Trim(string(body))) - - // assert URL - assert.Equal(t, "https://test/", r.URL.String()) - - // assert headers - -} - -func TestInputService6ProtocolTestSerializeMapTypeWithLocationNameCase1(t *testing.T) { +func TestInputService6ProtocolTestSerializeMapTypeCase1(t *testing.T) { svc := NewInputService6ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService6TestShapeInputShape{ + input := &InputService6TestShapeInputService6TestCaseOperation1Input{ MapArg: map[string]*string{ "key1": aws.String("val1"), "key2": aws.String("val2"), @@ -1282,7 +1072,7 @@ func TestInputService6ProtocolTestSerializeMapTypeWithLocationNameCase1(t *testi // assert body assert.NotNil(t, r.Body) body, _ := ioutil.ReadAll(r.Body) - assert.Equal(t, util.Trim(`Action=OperationName&MapArg.entry.1.TheKey=key1&MapArg.entry.1.TheValue=val1&MapArg.entry.2.TheKey=key2&MapArg.entry.2.TheValue=val2&Version=2014-01-01`), util.Trim(string(body))) + assert.Equal(t, util.Trim(`Action=OperationName&MapArg.entry.1.key=key1&MapArg.entry.1.value=val1&MapArg.entry.2.key=key2&MapArg.entry.2.value=val2&Version=2014-01-01`), util.Trim(string(body))) // assert URL assert.Equal(t, "https://test/", r.URL.String()) @@ -1295,7 +1085,7 @@ func TestInputService7ProtocolTestBase64EncodedBlobsCase1(t *testing.T) { svc := NewInputService7ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService7TestShapeInputShape{ + input := &InputService7TestShapeInputService7TestCaseOperation1Input{ BlobArg: []byte("foo"), } req, _ := svc.InputService7TestCaseOperation1Request(input) @@ -1321,7 +1111,7 @@ func TestInputService8ProtocolTestTimestampValuesCase1(t *testing.T) { svc := NewInputService8ProtocolTest(nil) svc.Endpoint = "https://test" - input := &InputService8TestShapeInputShape{ + input := &InputService8TestShapeInputService8TestCaseOperation1Input{ TimeArg: aws.Time(time.Unix(1422172800, 0)), } req, _ := svc.InputService8TestCaseOperation1Request(input) @@ -1442,10 +1232,10 @@ func TestInputService9ProtocolTestRecursiveShapesCase4(t *testing.T) { input := &InputService9TestShapeInputShape{ RecursiveStruct: &InputService9TestShapeRecursiveStructType{ RecursiveList: []*InputService9TestShapeRecursiveStructType{ - &InputService9TestShapeRecursiveStructType{ + { NoRecurse: aws.String("foo"), }, - &InputService9TestShapeRecursiveStructType{ + { NoRecurse: aws.String("bar"), }, }, @@ -1477,10 +1267,10 @@ func TestInputService9ProtocolTestRecursiveShapesCase5(t *testing.T) { input := &InputService9TestShapeInputShape{ RecursiveStruct: &InputService9TestShapeRecursiveStructType{ RecursiveList: []*InputService9TestShapeRecursiveStructType{ - &InputService9TestShapeRecursiveStructType{ + { NoRecurse: aws.String("foo"), }, - &InputService9TestShapeRecursiveStructType{ + { RecursiveStruct: &InputService9TestShapeRecursiveStructType{ NoRecurse: aws.String("bar"), }, @@ -1514,10 +1304,10 @@ func TestInputService9ProtocolTestRecursiveShapesCase6(t *testing.T) { input := &InputService9TestShapeInputShape{ RecursiveStruct: &InputService9TestShapeRecursiveStructType{ RecursiveMap: map[string]*InputService9TestShapeRecursiveStructType{ - "bar": &InputService9TestShapeRecursiveStructType{ + "bar": { NoRecurse: aws.String("bar"), }, - "foo": &InputService9TestShapeRecursiveStructType{ + "foo": { NoRecurse: aws.String("foo"), }, }, diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal.go index 8acdd2274c31..a374f88b14f9 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal.go @@ -5,25 +5,25 @@ package query import ( "encoding/xml" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil" ) // Unmarshal unmarshals a response for an AWS Query service. -func Unmarshal(r *aws.Request) { +func Unmarshal(r *request.Request) { defer r.HTTPResponse.Body.Close() if r.DataFilled() { decoder := xml.NewDecoder(r.HTTPResponse.Body) err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result") if err != nil { - r.Error = apierr.New("Unmarshal", "failed decoding Query response", err) + r.Error = awserr.New("SerializationError", "failed decoding Query response", err) return } } } // UnmarshalMeta unmarshals header response values for an AWS Query service. -func UnmarshalMeta(r *aws.Request) { +func UnmarshalMeta(r *request.Request) { // TODO implement unmarshaling of request IDs } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_error.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_error.go index deb529524aa2..08609d920881 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_error.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_error.go @@ -4,8 +4,8 @@ import ( "encoding/xml" "io" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" ) type xmlErrorResponse struct { @@ -16,16 +16,16 @@ type xmlErrorResponse struct { } // UnmarshalError unmarshals an error response for an AWS Query service. -func UnmarshalError(r *aws.Request) { +func UnmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() resp := &xmlErrorResponse{} err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) if err != nil && err != io.EOF { - r.Error = apierr.New("Unmarshal", "failed to decode query XML error response", err) + r.Error = awserr.New("SerializationError", "failed to decode query XML error response", err) } else { - r.Error = apierr.NewRequestError( - apierr.New(resp.Code, resp.Message, nil), + r.Error = awserr.NewRequestFailure( + awserr.New(resp.Code, resp.Message, nil), r.HTTPResponse.StatusCode, resp.RequestID, ) diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_test.go index a17f56ccd58c..a0dcfc43adbf 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/query/unmarshal_test.go @@ -1,10 +1,6 @@ package query_test import ( - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/internal/protocol/query" - "github.com/aws/aws-sdk-go/internal/signer/v4" - "bytes" "encoding/json" "encoding/xml" @@ -15,7 +11,14 @@ import ( "testing" "time" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" + "github.com/aws/aws-sdk-go/aws/service/serviceinfo" + "github.com/aws/aws-sdk-go/internal/protocol/query" "github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil" + "github.com/aws/aws-sdk-go/internal/signer/v4" "github.com/aws/aws-sdk-go/internal/util" "github.com/stretchr/testify/assert" ) @@ -31,17 +34,18 @@ var _ = util.Trim("") var _ = url.Values{} var _ = io.EOF -// OutputService1ProtocolTest is a client for OutputService1ProtocolTest. type OutputService1ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService1ProtocolTest client. func NewOutputService1ProtocolTest(config *aws.Config) *OutputService1ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice1protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice1protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -57,39 +61,36 @@ func NewOutputService1ProtocolTest(config *aws.Config) *OutputService1ProtocolTe // newRequest creates a new request for a OutputService1ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService1ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService1ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService1TestCaseOperation1Request generates a request for the OutputService1TestCaseOperation1 operation. -func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1Request(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (req *aws.Request, output *OutputService1TestShapeOutputShape) { +const opOutputService1TestCaseOperation1 = "OperationName" - if opOutputService1TestCaseOperation1 == nil { - opOutputService1TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService1TestCaseOperation1Request generates a request for the OutputService1TestCaseOperation1 operation. +func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1Request(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (req *request.Request, output *OutputService1TestShapeOutputService1TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService1TestCaseOperation1, } if input == nil { input = &OutputService1TestShapeOutputService1TestCaseOperation1Input{} } - req = c.newRequest(opOutputService1TestCaseOperation1, input, output) - output = &OutputService1TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService1TestShapeOutputService1TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (*OutputService1TestShapeOutputShape, error) { +func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (*OutputService1TestShapeOutputService1TestCaseOperation1Output, error) { req, out := c.OutputService1TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService1TestCaseOperation1 *aws.Operation - type OutputService1TestShapeOutputService1TestCaseOperation1Input struct { metadataOutputService1TestShapeOutputService1TestCaseOperation1Input `json:"-" xml:"-"` } @@ -98,7 +99,7 @@ type metadataOutputService1TestShapeOutputService1TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService1TestShapeOutputShape struct { +type OutputService1TestShapeOutputService1TestCaseOperation1Output struct { Char *string `type:"character"` Double *float64 `type:"double"` @@ -117,24 +118,25 @@ type OutputService1TestShapeOutputShape struct { TrueBool *bool `type:"boolean"` - metadataOutputService1TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService1TestShapeOutputService1TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService1TestShapeOutputShape struct { +type metadataOutputService1TestShapeOutputService1TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService2ProtocolTest is a client for OutputService2ProtocolTest. type OutputService2ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService2ProtocolTest client. func NewOutputService2ProtocolTest(config *aws.Config) *OutputService2ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice2protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice2protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -150,39 +152,36 @@ func NewOutputService2ProtocolTest(config *aws.Config) *OutputService2ProtocolTe // newRequest creates a new request for a OutputService2ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService2ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService2ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService2TestCaseOperation1Request generates a request for the OutputService2TestCaseOperation1 operation. -func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1Request(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (req *aws.Request, output *OutputService2TestShapeOutputShape) { +const opOutputService2TestCaseOperation1 = "OperationName" - if opOutputService2TestCaseOperation1 == nil { - opOutputService2TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService2TestCaseOperation1Request generates a request for the OutputService2TestCaseOperation1 operation. +func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1Request(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (req *request.Request, output *OutputService2TestShapeOutputService2TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService2TestCaseOperation1, } if input == nil { input = &OutputService2TestShapeOutputService2TestCaseOperation1Input{} } - req = c.newRequest(opOutputService2TestCaseOperation1, input, output) - output = &OutputService2TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService2TestShapeOutputService2TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (*OutputService2TestShapeOutputShape, error) { +func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (*OutputService2TestShapeOutputService2TestCaseOperation1Output, error) { req, out := c.OutputService2TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService2TestCaseOperation1 *aws.Operation - type OutputService2TestShapeOutputService2TestCaseOperation1Input struct { metadataOutputService2TestShapeOutputService2TestCaseOperation1Input `json:"-" xml:"-"` } @@ -191,29 +190,30 @@ type metadataOutputService2TestShapeOutputService2TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService2TestShapeOutputShape struct { +type OutputService2TestShapeOutputService2TestCaseOperation1Output struct { Num *int64 `type:"integer"` Str *string `type:"string"` - metadataOutputService2TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService2TestShapeOutputService2TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService2TestShapeOutputShape struct { +type metadataOutputService2TestShapeOutputService2TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService3ProtocolTest is a client for OutputService3ProtocolTest. type OutputService3ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService3ProtocolTest client. func NewOutputService3ProtocolTest(config *aws.Config) *OutputService3ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice3protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice3protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -229,39 +229,36 @@ func NewOutputService3ProtocolTest(config *aws.Config) *OutputService3ProtocolTe // newRequest creates a new request for a OutputService3ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService3ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService3ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService3TestCaseOperation1Request generates a request for the OutputService3TestCaseOperation1 operation. -func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1Request(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (req *aws.Request, output *OutputService3TestShapeOutputShape) { +const opOutputService3TestCaseOperation1 = "OperationName" - if opOutputService3TestCaseOperation1 == nil { - opOutputService3TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService3TestCaseOperation1Request generates a request for the OutputService3TestCaseOperation1 operation. +func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1Request(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (req *request.Request, output *OutputService3TestShapeOutputService3TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService3TestCaseOperation1, } if input == nil { input = &OutputService3TestShapeOutputService3TestCaseOperation1Input{} } - req = c.newRequest(opOutputService3TestCaseOperation1, input, output) - output = &OutputService3TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService3TestShapeOutputService3TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (*OutputService3TestShapeOutputShape, error) { +func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (*OutputService3TestShapeOutputService3TestCaseOperation1Output, error) { req, out := c.OutputService3TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService3TestCaseOperation1 *aws.Operation - type OutputService3TestShapeOutputService3TestCaseOperation1Input struct { metadataOutputService3TestShapeOutputService3TestCaseOperation1Input `json:"-" xml:"-"` } @@ -270,27 +267,28 @@ type metadataOutputService3TestShapeOutputService3TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService3TestShapeOutputShape struct { +type OutputService3TestShapeOutputService3TestCaseOperation1Output struct { Blob []byte `type:"blob"` - metadataOutputService3TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService3TestShapeOutputService3TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService3TestShapeOutputShape struct { +type metadataOutputService3TestShapeOutputService3TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService4ProtocolTest is a client for OutputService4ProtocolTest. type OutputService4ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService4ProtocolTest client. func NewOutputService4ProtocolTest(config *aws.Config) *OutputService4ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice4protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice4protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -306,39 +304,36 @@ func NewOutputService4ProtocolTest(config *aws.Config) *OutputService4ProtocolTe // newRequest creates a new request for a OutputService4ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService4ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService4ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService4TestCaseOperation1Request generates a request for the OutputService4TestCaseOperation1 operation. -func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1Request(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (req *aws.Request, output *OutputService4TestShapeOutputShape) { +const opOutputService4TestCaseOperation1 = "OperationName" - if opOutputService4TestCaseOperation1 == nil { - opOutputService4TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService4TestCaseOperation1Request generates a request for the OutputService4TestCaseOperation1 operation. +func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1Request(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (req *request.Request, output *OutputService4TestShapeOutputService4TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService4TestCaseOperation1, } if input == nil { input = &OutputService4TestShapeOutputService4TestCaseOperation1Input{} } - req = c.newRequest(opOutputService4TestCaseOperation1, input, output) - output = &OutputService4TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService4TestShapeOutputService4TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (*OutputService4TestShapeOutputShape, error) { +func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (*OutputService4TestShapeOutputService4TestCaseOperation1Output, error) { req, out := c.OutputService4TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService4TestCaseOperation1 *aws.Operation - type OutputService4TestShapeOutputService4TestCaseOperation1Input struct { metadataOutputService4TestShapeOutputService4TestCaseOperation1Input `json:"-" xml:"-"` } @@ -347,27 +342,28 @@ type metadataOutputService4TestShapeOutputService4TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService4TestShapeOutputShape struct { +type OutputService4TestShapeOutputService4TestCaseOperation1Output struct { ListMember []*string `type:"list"` - metadataOutputService4TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService4TestShapeOutputService4TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService4TestShapeOutputShape struct { +type metadataOutputService4TestShapeOutputService4TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService5ProtocolTest is a client for OutputService5ProtocolTest. type OutputService5ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService5ProtocolTest client. func NewOutputService5ProtocolTest(config *aws.Config) *OutputService5ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice5protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice5protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -383,39 +379,36 @@ func NewOutputService5ProtocolTest(config *aws.Config) *OutputService5ProtocolTe // newRequest creates a new request for a OutputService5ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService5ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService5ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService5TestCaseOperation1Request generates a request for the OutputService5TestCaseOperation1 operation. -func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1Request(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (req *aws.Request, output *OutputService5TestShapeOutputShape) { +const opOutputService5TestCaseOperation1 = "OperationName" - if opOutputService5TestCaseOperation1 == nil { - opOutputService5TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService5TestCaseOperation1Request generates a request for the OutputService5TestCaseOperation1 operation. +func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1Request(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (req *request.Request, output *OutputService5TestShapeOutputService5TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService5TestCaseOperation1, } if input == nil { input = &OutputService5TestShapeOutputService5TestCaseOperation1Input{} } - req = c.newRequest(opOutputService5TestCaseOperation1, input, output) - output = &OutputService5TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService5TestShapeOutputService5TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (*OutputService5TestShapeOutputShape, error) { +func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (*OutputService5TestShapeOutputService5TestCaseOperation1Output, error) { req, out := c.OutputService5TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService5TestCaseOperation1 *aws.Operation - type OutputService5TestShapeOutputService5TestCaseOperation1Input struct { metadataOutputService5TestShapeOutputService5TestCaseOperation1Input `json:"-" xml:"-"` } @@ -424,27 +417,28 @@ type metadataOutputService5TestShapeOutputService5TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService5TestShapeOutputShape struct { +type OutputService5TestShapeOutputService5TestCaseOperation1Output struct { ListMember []*string `locationNameList:"item" type:"list"` - metadataOutputService5TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService5TestShapeOutputService5TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService5TestShapeOutputShape struct { +type metadataOutputService5TestShapeOutputService5TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService6ProtocolTest is a client for OutputService6ProtocolTest. type OutputService6ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService6ProtocolTest client. func NewOutputService6ProtocolTest(config *aws.Config) *OutputService6ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice6protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice6protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -460,39 +454,36 @@ func NewOutputService6ProtocolTest(config *aws.Config) *OutputService6ProtocolTe // newRequest creates a new request for a OutputService6ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService6ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService6ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService6TestCaseOperation1Request generates a request for the OutputService6TestCaseOperation1 operation. -func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1Request(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (req *aws.Request, output *OutputService6TestShapeOutputShape) { +const opOutputService6TestCaseOperation1 = "OperationName" - if opOutputService6TestCaseOperation1 == nil { - opOutputService6TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService6TestCaseOperation1Request generates a request for the OutputService6TestCaseOperation1 operation. +func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1Request(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (req *request.Request, output *OutputService6TestShapeOutputService6TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService6TestCaseOperation1, } if input == nil { input = &OutputService6TestShapeOutputService6TestCaseOperation1Input{} } - req = c.newRequest(opOutputService6TestCaseOperation1, input, output) - output = &OutputService6TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService6TestShapeOutputService6TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (*OutputService6TestShapeOutputShape, error) { +func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (*OutputService6TestShapeOutputService6TestCaseOperation1Output, error) { req, out := c.OutputService6TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService6TestCaseOperation1 *aws.Operation - type OutputService6TestShapeOutputService6TestCaseOperation1Input struct { metadataOutputService6TestShapeOutputService6TestCaseOperation1Input `json:"-" xml:"-"` } @@ -501,27 +492,28 @@ type metadataOutputService6TestShapeOutputService6TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService6TestShapeOutputShape struct { +type OutputService6TestShapeOutputService6TestCaseOperation1Output struct { ListMember []*string `type:"list" flattened:"true"` - metadataOutputService6TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService6TestShapeOutputService6TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService6TestShapeOutputShape struct { +type metadataOutputService6TestShapeOutputService6TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService7ProtocolTest is a client for OutputService7ProtocolTest. type OutputService7ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService7ProtocolTest client. func NewOutputService7ProtocolTest(config *aws.Config) *OutputService7ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice7protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice7protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -537,39 +529,36 @@ func NewOutputService7ProtocolTest(config *aws.Config) *OutputService7ProtocolTe // newRequest creates a new request for a OutputService7ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService7ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService7ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService7TestCaseOperation1Request generates a request for the OutputService7TestCaseOperation1 operation. -func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1Request(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (req *aws.Request, output *OutputService7TestShapeOutputShape) { +const opOutputService7TestCaseOperation1 = "OperationName" - if opOutputService7TestCaseOperation1 == nil { - opOutputService7TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService7TestCaseOperation1Request generates a request for the OutputService7TestCaseOperation1 operation. +func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1Request(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (req *request.Request, output *OutputService7TestShapeOutputService7TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService7TestCaseOperation1, } if input == nil { input = &OutputService7TestShapeOutputService7TestCaseOperation1Input{} } - req = c.newRequest(opOutputService7TestCaseOperation1, input, output) - output = &OutputService7TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService7TestShapeOutputService7TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (*OutputService7TestShapeOutputShape, error) { +func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (*OutputService7TestShapeOutputService7TestCaseOperation1Output, error) { req, out := c.OutputService7TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService7TestCaseOperation1 *aws.Operation - type OutputService7TestShapeOutputService7TestCaseOperation1Input struct { metadataOutputService7TestShapeOutputService7TestCaseOperation1Input `json:"-" xml:"-"` } @@ -578,27 +567,28 @@ type metadataOutputService7TestShapeOutputService7TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService7TestShapeOutputShape struct { +type OutputService7TestShapeOutputService7TestCaseOperation1Output struct { ListMember []*string `type:"list" flattened:"true"` - metadataOutputService7TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService7TestShapeOutputService7TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService7TestShapeOutputShape struct { +type metadataOutputService7TestShapeOutputService7TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService8ProtocolTest is a client for OutputService8ProtocolTest. type OutputService8ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService8ProtocolTest client. func NewOutputService8ProtocolTest(config *aws.Config) *OutputService8ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice8protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice8protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -614,39 +604,36 @@ func NewOutputService8ProtocolTest(config *aws.Config) *OutputService8ProtocolTe // newRequest creates a new request for a OutputService8ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService8ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService8ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService8TestCaseOperation1Request generates a request for the OutputService8TestCaseOperation1 operation. -func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1Request(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (req *aws.Request, output *OutputService8TestShapeOutputShape) { +const opOutputService8TestCaseOperation1 = "OperationName" - if opOutputService8TestCaseOperation1 == nil { - opOutputService8TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService8TestCaseOperation1Request generates a request for the OutputService8TestCaseOperation1 operation. +func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1Request(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (req *request.Request, output *OutputService8TestShapeOutputService8TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService8TestCaseOperation1, } if input == nil { input = &OutputService8TestShapeOutputService8TestCaseOperation1Input{} } - req = c.newRequest(opOutputService8TestCaseOperation1, input, output) - output = &OutputService8TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService8TestShapeOutputService8TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (*OutputService8TestShapeOutputShape, error) { +func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (*OutputService8TestShapeOutputService8TestCaseOperation1Output, error) { req, out := c.OutputService8TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService8TestCaseOperation1 *aws.Operation - type OutputService8TestShapeOutputService8TestCaseOperation1Input struct { metadataOutputService8TestShapeOutputService8TestCaseOperation1Input `json:"-" xml:"-"` } @@ -655,13 +642,13 @@ type metadataOutputService8TestShapeOutputService8TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService8TestShapeOutputShape struct { +type OutputService8TestShapeOutputService8TestCaseOperation1Output struct { List []*OutputService8TestShapeStructureShape `type:"list"` - metadataOutputService8TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService8TestShapeOutputService8TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService8TestShapeOutputShape struct { +type metadataOutputService8TestShapeOutputService8TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } @@ -679,17 +666,18 @@ type metadataOutputService8TestShapeStructureShape struct { SDKShapeTraits bool `type:"structure"` } -// OutputService9ProtocolTest is a client for OutputService9ProtocolTest. type OutputService9ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService9ProtocolTest client. func NewOutputService9ProtocolTest(config *aws.Config) *OutputService9ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice9protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice9protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -705,39 +693,36 @@ func NewOutputService9ProtocolTest(config *aws.Config) *OutputService9ProtocolTe // newRequest creates a new request for a OutputService9ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService9ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService9ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService9TestCaseOperation1Request generates a request for the OutputService9TestCaseOperation1 operation. -func (c *OutputService9ProtocolTest) OutputService9TestCaseOperation1Request(input *OutputService9TestShapeOutputService9TestCaseOperation1Input) (req *aws.Request, output *OutputService9TestShapeOutputShape) { +const opOutputService9TestCaseOperation1 = "OperationName" - if opOutputService9TestCaseOperation1 == nil { - opOutputService9TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService9TestCaseOperation1Request generates a request for the OutputService9TestCaseOperation1 operation. +func (c *OutputService9ProtocolTest) OutputService9TestCaseOperation1Request(input *OutputService9TestShapeOutputService9TestCaseOperation1Input) (req *request.Request, output *OutputService9TestShapeOutputService9TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService9TestCaseOperation1, } if input == nil { input = &OutputService9TestShapeOutputService9TestCaseOperation1Input{} } - req = c.newRequest(opOutputService9TestCaseOperation1, input, output) - output = &OutputService9TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService9TestShapeOutputService9TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService9ProtocolTest) OutputService9TestCaseOperation1(input *OutputService9TestShapeOutputService9TestCaseOperation1Input) (*OutputService9TestShapeOutputShape, error) { +func (c *OutputService9ProtocolTest) OutputService9TestCaseOperation1(input *OutputService9TestShapeOutputService9TestCaseOperation1Input) (*OutputService9TestShapeOutputService9TestCaseOperation1Output, error) { req, out := c.OutputService9TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService9TestCaseOperation1 *aws.Operation - type OutputService9TestShapeOutputService9TestCaseOperation1Input struct { metadataOutputService9TestShapeOutputService9TestCaseOperation1Input `json:"-" xml:"-"` } @@ -746,13 +731,13 @@ type metadataOutputService9TestShapeOutputService9TestCaseOperation1Input struct SDKShapeTraits bool `type:"structure"` } -type OutputService9TestShapeOutputShape struct { +type OutputService9TestShapeOutputService9TestCaseOperation1Output struct { List []*OutputService9TestShapeStructureShape `type:"list" flattened:"true"` - metadataOutputService9TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService9TestShapeOutputService9TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService9TestShapeOutputShape struct { +type metadataOutputService9TestShapeOutputService9TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } @@ -770,17 +755,18 @@ type metadataOutputService9TestShapeStructureShape struct { SDKShapeTraits bool `type:"structure"` } -// OutputService10ProtocolTest is a client for OutputService10ProtocolTest. type OutputService10ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService10ProtocolTest client. func NewOutputService10ProtocolTest(config *aws.Config) *OutputService10ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice10protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice10protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -796,39 +782,36 @@ func NewOutputService10ProtocolTest(config *aws.Config) *OutputService10Protocol // newRequest creates a new request for a OutputService10ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService10ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService10ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService10TestCaseOperation1Request generates a request for the OutputService10TestCaseOperation1 operation. -func (c *OutputService10ProtocolTest) OutputService10TestCaseOperation1Request(input *OutputService10TestShapeOutputService10TestCaseOperation1Input) (req *aws.Request, output *OutputService10TestShapeOutputShape) { +const opOutputService10TestCaseOperation1 = "OperationName" - if opOutputService10TestCaseOperation1 == nil { - opOutputService10TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService10TestCaseOperation1Request generates a request for the OutputService10TestCaseOperation1 operation. +func (c *OutputService10ProtocolTest) OutputService10TestCaseOperation1Request(input *OutputService10TestShapeOutputService10TestCaseOperation1Input) (req *request.Request, output *OutputService10TestShapeOutputService10TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService10TestCaseOperation1, } if input == nil { input = &OutputService10TestShapeOutputService10TestCaseOperation1Input{} } - req = c.newRequest(opOutputService10TestCaseOperation1, input, output) - output = &OutputService10TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService10TestShapeOutputService10TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService10ProtocolTest) OutputService10TestCaseOperation1(input *OutputService10TestShapeOutputService10TestCaseOperation1Input) (*OutputService10TestShapeOutputShape, error) { +func (c *OutputService10ProtocolTest) OutputService10TestCaseOperation1(input *OutputService10TestShapeOutputService10TestCaseOperation1Input) (*OutputService10TestShapeOutputService10TestCaseOperation1Output, error) { req, out := c.OutputService10TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService10TestCaseOperation1 *aws.Operation - type OutputService10TestShapeOutputService10TestCaseOperation1Input struct { metadataOutputService10TestShapeOutputService10TestCaseOperation1Input `json:"-" xml:"-"` } @@ -837,27 +820,28 @@ type metadataOutputService10TestShapeOutputService10TestCaseOperation1Input stru SDKShapeTraits bool `type:"structure"` } -type OutputService10TestShapeOutputShape struct { +type OutputService10TestShapeOutputService10TestCaseOperation1Output struct { List []*string `locationNameList:"NamedList" type:"list" flattened:"true"` - metadataOutputService10TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService10TestShapeOutputService10TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService10TestShapeOutputShape struct { +type metadataOutputService10TestShapeOutputService10TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService11ProtocolTest is a client for OutputService11ProtocolTest. type OutputService11ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService11ProtocolTest client. func NewOutputService11ProtocolTest(config *aws.Config) *OutputService11ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice11protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice11protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -873,39 +857,36 @@ func NewOutputService11ProtocolTest(config *aws.Config) *OutputService11Protocol // newRequest creates a new request for a OutputService11ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService11ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService11ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService11TestCaseOperation1Request generates a request for the OutputService11TestCaseOperation1 operation. -func (c *OutputService11ProtocolTest) OutputService11TestCaseOperation1Request(input *OutputService11TestShapeOutputService11TestCaseOperation1Input) (req *aws.Request, output *OutputService11TestShapeOutputShape) { +const opOutputService11TestCaseOperation1 = "OperationName" - if opOutputService11TestCaseOperation1 == nil { - opOutputService11TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService11TestCaseOperation1Request generates a request for the OutputService11TestCaseOperation1 operation. +func (c *OutputService11ProtocolTest) OutputService11TestCaseOperation1Request(input *OutputService11TestShapeOutputService11TestCaseOperation1Input) (req *request.Request, output *OutputService11TestShapeOutputService11TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService11TestCaseOperation1, } if input == nil { input = &OutputService11TestShapeOutputService11TestCaseOperation1Input{} } - req = c.newRequest(opOutputService11TestCaseOperation1, input, output) - output = &OutputService11TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService11TestShapeOutputService11TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService11ProtocolTest) OutputService11TestCaseOperation1(input *OutputService11TestShapeOutputService11TestCaseOperation1Input) (*OutputService11TestShapeOutputShape, error) { +func (c *OutputService11ProtocolTest) OutputService11TestCaseOperation1(input *OutputService11TestShapeOutputService11TestCaseOperation1Input) (*OutputService11TestShapeOutputService11TestCaseOperation1Output, error) { req, out := c.OutputService11TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService11TestCaseOperation1 *aws.Operation - type OutputService11TestShapeOutputService11TestCaseOperation1Input struct { metadataOutputService11TestShapeOutputService11TestCaseOperation1Input `json:"-" xml:"-"` } @@ -914,13 +895,13 @@ type metadataOutputService11TestShapeOutputService11TestCaseOperation1Input stru SDKShapeTraits bool `type:"structure"` } -type OutputService11TestShapeOutputShape struct { +type OutputService11TestShapeOutputService11TestCaseOperation1Output struct { Map map[string]*OutputService11TestShapeStructType `type:"map"` - metadataOutputService11TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService11TestShapeOutputService11TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService11TestShapeOutputShape struct { +type metadataOutputService11TestShapeOutputService11TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } @@ -934,17 +915,18 @@ type metadataOutputService11TestShapeStructType struct { SDKShapeTraits bool `type:"structure"` } -// OutputService12ProtocolTest is a client for OutputService12ProtocolTest. type OutputService12ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService12ProtocolTest client. func NewOutputService12ProtocolTest(config *aws.Config) *OutputService12ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice12protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice12protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -960,39 +942,36 @@ func NewOutputService12ProtocolTest(config *aws.Config) *OutputService12Protocol // newRequest creates a new request for a OutputService12ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService12ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService12ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService12TestCaseOperation1Request generates a request for the OutputService12TestCaseOperation1 operation. -func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1Request(input *OutputService12TestShapeOutputService12TestCaseOperation1Input) (req *aws.Request, output *OutputService12TestShapeOutputShape) { +const opOutputService12TestCaseOperation1 = "OperationName" - if opOutputService12TestCaseOperation1 == nil { - opOutputService12TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService12TestCaseOperation1Request generates a request for the OutputService12TestCaseOperation1 operation. +func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1Request(input *OutputService12TestShapeOutputService12TestCaseOperation1Input) (req *request.Request, output *OutputService12TestShapeOutputService12TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService12TestCaseOperation1, } if input == nil { input = &OutputService12TestShapeOutputService12TestCaseOperation1Input{} } - req = c.newRequest(opOutputService12TestCaseOperation1, input, output) - output = &OutputService12TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService12TestShapeOutputService12TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1(input *OutputService12TestShapeOutputService12TestCaseOperation1Input) (*OutputService12TestShapeOutputShape, error) { +func (c *OutputService12ProtocolTest) OutputService12TestCaseOperation1(input *OutputService12TestShapeOutputService12TestCaseOperation1Input) (*OutputService12TestShapeOutputService12TestCaseOperation1Output, error) { req, out := c.OutputService12TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService12TestCaseOperation1 *aws.Operation - type OutputService12TestShapeOutputService12TestCaseOperation1Input struct { metadataOutputService12TestShapeOutputService12TestCaseOperation1Input `json:"-" xml:"-"` } @@ -1001,27 +980,28 @@ type metadataOutputService12TestShapeOutputService12TestCaseOperation1Input stru SDKShapeTraits bool `type:"structure"` } -type OutputService12TestShapeOutputShape struct { +type OutputService12TestShapeOutputService12TestCaseOperation1Output struct { Map map[string]*string `type:"map" flattened:"true"` - metadataOutputService12TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService12TestShapeOutputService12TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService12TestShapeOutputShape struct { +type metadataOutputService12TestShapeOutputService12TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService13ProtocolTest is a client for OutputService13ProtocolTest. type OutputService13ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService13ProtocolTest client. func NewOutputService13ProtocolTest(config *aws.Config) *OutputService13ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice13protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice13protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -1037,39 +1017,36 @@ func NewOutputService13ProtocolTest(config *aws.Config) *OutputService13Protocol // newRequest creates a new request for a OutputService13ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService13ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService13ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService13TestCaseOperation1Request generates a request for the OutputService13TestCaseOperation1 operation. -func (c *OutputService13ProtocolTest) OutputService13TestCaseOperation1Request(input *OutputService13TestShapeOutputService13TestCaseOperation1Input) (req *aws.Request, output *OutputService13TestShapeOutputShape) { +const opOutputService13TestCaseOperation1 = "OperationName" - if opOutputService13TestCaseOperation1 == nil { - opOutputService13TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService13TestCaseOperation1Request generates a request for the OutputService13TestCaseOperation1 operation. +func (c *OutputService13ProtocolTest) OutputService13TestCaseOperation1Request(input *OutputService13TestShapeOutputService13TestCaseOperation1Input) (req *request.Request, output *OutputService13TestShapeOutputService13TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService13TestCaseOperation1, } if input == nil { input = &OutputService13TestShapeOutputService13TestCaseOperation1Input{} } - req = c.newRequest(opOutputService13TestCaseOperation1, input, output) - output = &OutputService13TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService13TestShapeOutputService13TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService13ProtocolTest) OutputService13TestCaseOperation1(input *OutputService13TestShapeOutputService13TestCaseOperation1Input) (*OutputService13TestShapeOutputShape, error) { +func (c *OutputService13ProtocolTest) OutputService13TestCaseOperation1(input *OutputService13TestShapeOutputService13TestCaseOperation1Input) (*OutputService13TestShapeOutputService13TestCaseOperation1Output, error) { req, out := c.OutputService13TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService13TestCaseOperation1 *aws.Operation - type OutputService13TestShapeOutputService13TestCaseOperation1Input struct { metadataOutputService13TestShapeOutputService13TestCaseOperation1Input `json:"-" xml:"-"` } @@ -1078,27 +1055,28 @@ type metadataOutputService13TestShapeOutputService13TestCaseOperation1Input stru SDKShapeTraits bool `type:"structure"` } -type OutputService13TestShapeOutputShape struct { +type OutputService13TestShapeOutputService13TestCaseOperation1Output struct { Map map[string]*string `locationName:"Attribute" locationNameKey:"Name" locationNameValue:"Value" type:"map" flattened:"true"` - metadataOutputService13TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService13TestShapeOutputService13TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService13TestShapeOutputShape struct { +type metadataOutputService13TestShapeOutputService13TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } -// OutputService14ProtocolTest is a client for OutputService14ProtocolTest. type OutputService14ProtocolTest struct { - *aws.Service + *service.Service } // New returns a new OutputService14ProtocolTest client. func NewOutputService14ProtocolTest(config *aws.Config) *OutputService14ProtocolTest { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "outputservice14protocoltest", - APIVersion: "", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "outputservice14protocoltest", + APIVersion: "", + }, } service.Initialize() @@ -1114,39 +1092,36 @@ func NewOutputService14ProtocolTest(config *aws.Config) *OutputService14Protocol // newRequest creates a new request for a OutputService14ProtocolTest operation and runs any // custom request initialization. -func (c *OutputService14ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *OutputService14ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) return req } -// OutputService14TestCaseOperation1Request generates a request for the OutputService14TestCaseOperation1 operation. -func (c *OutputService14ProtocolTest) OutputService14TestCaseOperation1Request(input *OutputService14TestShapeOutputService14TestCaseOperation1Input) (req *aws.Request, output *OutputService14TestShapeOutputShape) { +const opOutputService14TestCaseOperation1 = "OperationName" - if opOutputService14TestCaseOperation1 == nil { - opOutputService14TestCaseOperation1 = &aws.Operation{ - Name: "OperationName", - } +// OutputService14TestCaseOperation1Request generates a request for the OutputService14TestCaseOperation1 operation. +func (c *OutputService14ProtocolTest) OutputService14TestCaseOperation1Request(input *OutputService14TestShapeOutputService14TestCaseOperation1Input) (req *request.Request, output *OutputService14TestShapeOutputService14TestCaseOperation1Output) { + op := &request.Operation{ + Name: opOutputService14TestCaseOperation1, } if input == nil { input = &OutputService14TestShapeOutputService14TestCaseOperation1Input{} } - req = c.newRequest(opOutputService14TestCaseOperation1, input, output) - output = &OutputService14TestShapeOutputShape{} + req = c.newRequest(op, input, output) + output = &OutputService14TestShapeOutputService14TestCaseOperation1Output{} req.Data = output return } -func (c *OutputService14ProtocolTest) OutputService14TestCaseOperation1(input *OutputService14TestShapeOutputService14TestCaseOperation1Input) (*OutputService14TestShapeOutputShape, error) { +func (c *OutputService14ProtocolTest) OutputService14TestCaseOperation1(input *OutputService14TestShapeOutputService14TestCaseOperation1Input) (*OutputService14TestShapeOutputService14TestCaseOperation1Output, error) { req, out := c.OutputService14TestCaseOperation1Request(input) err := req.Send() return out, err } -var opOutputService14TestCaseOperation1 *aws.Operation - type OutputService14TestShapeOutputService14TestCaseOperation1Input struct { metadataOutputService14TestShapeOutputService14TestCaseOperation1Input `json:"-" xml:"-"` } @@ -1155,13 +1130,13 @@ type metadataOutputService14TestShapeOutputService14TestCaseOperation1Input stru SDKShapeTraits bool `type:"structure"` } -type OutputService14TestShapeOutputShape struct { +type OutputService14TestShapeOutputService14TestCaseOperation1Output struct { Map map[string]*string `locationNameKey:"foo" locationNameValue:"bar" type:"map" flattened:"true"` - metadataOutputService14TestShapeOutputShape `json:"-" xml:"-"` + metadataOutputService14TestShapeOutputService14TestCaseOperation1Output `json:"-" xml:"-"` } -type metadataOutputService14TestShapeOutputShape struct { +type metadataOutputService14TestShapeOutputService14TestCaseOperation1Output struct { SDKShapeTraits bool `type:"structure"` } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/build.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/build.go index 38c4512bea1c..326e96cc6251 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/build.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/build.go @@ -1,4 +1,4 @@ -// Package rest provides RESTful serialisation of AWS requests and responses. +// Package rest provides RESTful serialization of AWS requests and responses. package rest import ( @@ -13,8 +13,8 @@ import ( "strings" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" ) // RFC822 returns an RFC822 formatted timestamp for AWS protocols @@ -37,7 +37,7 @@ func init() { } // Build builds the REST component of a service request. -func Build(r *aws.Request) { +func Build(r *request.Request) { if r.ParamsFilled() { v := reflect.ValueOf(r.Params).Elem() buildLocationElements(r, v) @@ -45,7 +45,7 @@ func Build(r *aws.Request) { } } -func buildLocationElements(r *aws.Request, v reflect.Value) { +func buildLocationElements(r *request.Request, v reflect.Value) { query := r.HTTPRequest.URL.Query() for i := 0; i < v.NumField(); i++ { @@ -87,7 +87,7 @@ func buildLocationElements(r *aws.Request, v reflect.Value) { updatePath(r.HTTPRequest.URL, r.HTTPRequest.URL.Path) } -func buildBody(r *aws.Request, v reflect.Value) { +func buildBody(r *request.Request, v reflect.Value) { if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok { if payloadName := field.Tag.Get("payload"); payloadName != "" { pfield, _ := v.Type().FieldByName(payloadName) @@ -102,7 +102,7 @@ func buildBody(r *aws.Request, v reflect.Value) { case string: r.SetStringBody(reader) default: - r.Error = apierr.New("Marshal", + r.Error = awserr.New("SerializationError", "failed to encode REST request", fmt.Errorf("unknown payload type %s", payload.Type())) } @@ -112,30 +112,30 @@ func buildBody(r *aws.Request, v reflect.Value) { } } -func buildHeader(r *aws.Request, v reflect.Value, name string) { +func buildHeader(r *request.Request, v reflect.Value, name string) { str, err := convertType(v) if err != nil { - r.Error = apierr.New("Marshal", "failed to encode REST request", err) + r.Error = awserr.New("SerializationError", "failed to encode REST request", err) } else if str != nil { r.HTTPRequest.Header.Add(name, *str) } } -func buildHeaderMap(r *aws.Request, v reflect.Value, prefix string) { +func buildHeaderMap(r *request.Request, v reflect.Value, prefix string) { for _, key := range v.MapKeys() { str, err := convertType(v.MapIndex(key)) if err != nil { - r.Error = apierr.New("Marshal", "failed to encode REST request", err) + r.Error = awserr.New("SerializationError", "failed to encode REST request", err) } else if str != nil { r.HTTPRequest.Header.Add(prefix+key.String(), *str) } } } -func buildURI(r *aws.Request, v reflect.Value, name string) { +func buildURI(r *request.Request, v reflect.Value, name string) { value, err := convertType(v) if err != nil { - r.Error = apierr.New("Marshal", "failed to encode REST request", err) + r.Error = awserr.New("SerializationError", "failed to encode REST request", err) } else if value != nil { uri := r.HTTPRequest.URL.Path uri = strings.Replace(uri, "{"+name+"}", EscapePath(*value, true), -1) @@ -144,10 +144,10 @@ func buildURI(r *aws.Request, v reflect.Value, name string) { } } -func buildQueryString(r *aws.Request, v reflect.Value, name string, query url.Values) { +func buildQueryString(r *request.Request, v reflect.Value, name string, query url.Values) { str, err := convertType(v) if err != nil { - r.Error = apierr.New("Marshal", "failed to encode REST request", err) + r.Error = awserr.New("SerializationError", "failed to encode REST request", err) } else if str != nil { query.Set(name, *str) } @@ -156,8 +156,13 @@ func buildQueryString(r *aws.Request, v reflect.Value, name string, query url.Va func updatePath(url *url.URL, urlPath string) { scheme, query := url.Scheme, url.RawQuery + hasSlash := strings.HasSuffix(urlPath, "/") + // clean up path urlPath = path.Clean(urlPath) + if hasSlash && !strings.HasSuffix(urlPath, "/") { + urlPath += "/" + } // get formatted URL minus scheme so we can build this into Opaque url.Scheme, url.Path, url.RawQuery = "", "", "" diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/unmarshal.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/unmarshal.go index 009c5c95098f..06d9accbacb1 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/unmarshal.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/rest/unmarshal.go @@ -11,19 +11,28 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/internal/apierr" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" ) // Unmarshal unmarshals the REST component of a response in a REST service. -func Unmarshal(r *aws.Request) { +func Unmarshal(r *request.Request) { if r.DataFilled() { v := reflect.Indirect(reflect.ValueOf(r.Data)) unmarshalBody(r, v) + } +} + +// UnmarshalMeta unmarshals the REST metadata of a response in a REST service +func UnmarshalMeta(r *request.Request) { + r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") + if r.DataFilled() { + v := reflect.Indirect(reflect.ValueOf(r.Data)) unmarshalLocationElements(r, v) } } -func unmarshalBody(r *aws.Request, v reflect.Value) { +func unmarshalBody(r *request.Request, v reflect.Value) { if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok { if payloadName := field.Tag.Get("payload"); payloadName != "" { pfield, _ := v.Type().FieldByName(payloadName) @@ -34,14 +43,14 @@ func unmarshalBody(r *aws.Request, v reflect.Value) { case []byte: b, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { - r.Error = apierr.New("Unmarshal", "failed to decode REST response", err) + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) } else { payload.Set(reflect.ValueOf(b)) } case *string: b, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { - r.Error = apierr.New("Unmarshal", "failed to decode REST response", err) + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) } else { str := string(b) payload.Set(reflect.ValueOf(&str)) @@ -53,7 +62,7 @@ func unmarshalBody(r *aws.Request, v reflect.Value) { case "aws.ReadSeekCloser", "io.ReadCloser": payload.Set(reflect.ValueOf(r.HTTPResponse.Body)) default: - r.Error = apierr.New("Unmarshal", + r.Error = awserr.New("SerializationError", "failed to decode REST response", fmt.Errorf("unknown payload type %s", payload.Type())) } @@ -64,7 +73,7 @@ func unmarshalBody(r *aws.Request, v reflect.Value) { } } -func unmarshalLocationElements(r *aws.Request, v reflect.Value) { +func unmarshalLocationElements(r *request.Request, v reflect.Value) { for i := 0; i < v.NumField(); i++ { m, field := v.Field(i), v.Type().Field(i) if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) { @@ -83,14 +92,14 @@ func unmarshalLocationElements(r *aws.Request, v reflect.Value) { case "header": err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name)) if err != nil { - r.Error = apierr.New("Unmarshal", "failed to decode REST response", err) + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) break } case "headers": prefix := field.Tag.Get("locationName") err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix) if err != nil { - r.Error = apierr.New("Unmarshal", "failed to decode REST response", err) + r.Error = awserr.New("SerializationError", "failed to decode REST response", err) break } } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil/unmarshal.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil/unmarshal.go index a7b7a60b2ec0..5e4fe210b369 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil/unmarshal.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil/unmarshal.go @@ -114,7 +114,7 @@ func parseStruct(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { for _, a := range node.Attr { if name == a.Name.Local { // turn this into a text node for de-serializing - elems = []*XMLNode{&XMLNode{Text: a.Value}} + elems = []*XMLNode{{Text: a.Value}} } } } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/signer/v4/v4.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/signer/v4/v4.go index 8efda142091c..fc7bc35350e0 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/signer/v4/v4.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/signer/v4/v4.go @@ -14,10 +14,10 @@ import ( "strings" "time" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/internal/protocol/rest" - - "github.com/aws/aws-sdk-go/aws" ) const ( @@ -34,18 +34,17 @@ var ignoredHeaders = map[string]bool{ } type signer struct { - Request *http.Request - Time time.Time - ExpireTime time.Duration - ServiceName string - Region string - AccessKeyID string - SecretAccessKey string - SessionToken string - Query url.Values - Body io.ReadSeeker - Debug uint - Logger io.Writer + Request *http.Request + Time time.Time + ExpireTime time.Duration + ServiceName string + Region string + CredValues credentials.Value + Credentials *credentials.Credentials + Query url.Values + Body io.ReadSeeker + Debug aws.LogLevelType + Logger aws.Logger isPresign bool formattedTime string @@ -65,21 +64,16 @@ type signer struct { // Will sign the requests with the service config's Credentials object // Signing is skipped if the credentials is the credentials.AnonymousCredentials // object. -func Sign(req *aws.Request) { +func Sign(req *request.Request) { // If the request does not need to be signed ignore the signing of the // request if the AnonymousCredentials object is used. if req.Service.Config.Credentials == credentials.AnonymousCredentials { return } - creds, err := req.Service.Config.Credentials.Get() - if err != nil { - req.Error = err - return - } region := req.Service.SigningRegion if region == "" { - region = req.Service.Config.Region + region = aws.StringValue(req.Service.Config.Region) } name := req.Service.SigningName @@ -88,53 +82,86 @@ func Sign(req *aws.Request) { } s := signer{ - Request: req.HTTPRequest, - Time: req.Time, - ExpireTime: req.ExpireTime, - Query: req.HTTPRequest.URL.Query(), - Body: req.Body, - ServiceName: name, - Region: region, - AccessKeyID: creds.AccessKeyID, - SecretAccessKey: creds.SecretAccessKey, - SessionToken: creds.SessionToken, - Debug: req.Service.Config.LogLevel, - Logger: req.Service.Config.Logger, + Request: req.HTTPRequest, + Time: req.Time, + ExpireTime: req.ExpireTime, + Query: req.HTTPRequest.URL.Query(), + Body: req.Body, + ServiceName: name, + Region: region, + Credentials: req.Service.Config.Credentials, + Debug: req.Service.Config.LogLevel.Value(), + Logger: req.Service.Config.Logger, } - s.sign() - return + + req.Error = s.sign() } -func (v4 *signer) sign() { +func (v4 *signer) sign() error { if v4.ExpireTime != 0 { v4.isPresign = true } + if v4.isRequestSigned() { + if !v4.Credentials.IsExpired() { + // If the request is already signed, and the credentials have not + // expired yet ignore the signing request. + return nil + } + + // The credentials have expired for this request. The current signing + // is invalid, and needs to be request because the request will fail. + if v4.isPresign { + v4.removePresign() + // Update the request's query string to ensure the values stays in + // sync in the case retrieving the new credentials fails. + v4.Request.URL.RawQuery = v4.Query.Encode() + } + } + + var err error + v4.CredValues, err = v4.Credentials.Get() + if err != nil { + return err + } + if v4.isPresign { v4.Query.Set("X-Amz-Algorithm", authHeaderPrefix) - if v4.SessionToken != "" { - v4.Query.Set("X-Amz-Security-Token", v4.SessionToken) + if v4.CredValues.SessionToken != "" { + v4.Query.Set("X-Amz-Security-Token", v4.CredValues.SessionToken) } else { v4.Query.Del("X-Amz-Security-Token") } - } else if v4.SessionToken != "" { - v4.Request.Header.Set("X-Amz-Security-Token", v4.SessionToken) + } else if v4.CredValues.SessionToken != "" { + v4.Request.Header.Set("X-Amz-Security-Token", v4.CredValues.SessionToken) } v4.build() - if v4.Debug > 0 { - out := v4.Logger - fmt.Fprintf(out, "---[ CANONICAL STRING ]-----------------------------\n") - fmt.Fprintln(out, v4.canonicalString) - fmt.Fprintf(out, "---[ STRING TO SIGN ]--------------------------------\n") - fmt.Fprintln(out, v4.stringToSign) - if v4.isPresign { - fmt.Fprintf(out, "---[ SIGNED URL ]--------------------------------\n") - fmt.Fprintln(out, v4.Request.URL) - } - fmt.Fprintf(out, "-----------------------------------------------------\n") + if v4.Debug.Matches(aws.LogDebugWithSigning) { + v4.logSigningInfo() } + + return nil +} + +const logSignInfoMsg = `DEBUG: Request Signiture: +---[ CANONICAL STRING ]----------------------------- +%s +---[ STRING TO SIGN ]-------------------------------- +%s%s +-----------------------------------------------------` +const logSignedURLMsg = ` +---[ SIGNED URL ]------------------------------------ +%s` + +func (v4 *signer) logSigningInfo() { + signedURLMsg := "" + if v4.isPresign { + signedURLMsg = fmt.Sprintf(logSignedURLMsg, v4.Request.URL.String()) + } + msg := fmt.Sprintf(logSignInfoMsg, v4.canonicalString, v4.stringToSign, signedURLMsg) + v4.Logger.Log(msg) } func (v4 *signer) build() { @@ -152,7 +179,7 @@ func (v4 *signer) build() { v4.Request.URL.RawQuery += "&X-Amz-Signature=" + v4.signature } else { parts := []string{ - authHeaderPrefix + " Credential=" + v4.AccessKeyID + "/" + v4.credentialString, + authHeaderPrefix + " Credential=" + v4.CredValues.AccessKeyID + "/" + v4.credentialString, "SignedHeaders=" + v4.signedHeaders, "Signature=" + v4.signature, } @@ -182,7 +209,7 @@ func (v4 *signer) buildCredentialString() { }, "/") if v4.isPresign { - v4.Query.Set("X-Amz-Credential", v4.AccessKeyID+"/"+v4.credentialString) + v4.Query.Set("X-Amz-Credential", v4.CredValues.AccessKeyID+"/"+v4.credentialString) } } @@ -269,7 +296,7 @@ func (v4 *signer) buildStringToSign() { } func (v4 *signer) buildSignature() { - secret := v4.SecretAccessKey + secret := v4.CredValues.SecretAccessKey date := makeHmac([]byte("AWS4"+secret), []byte(v4.formattedShortTime)) region := makeHmac(date, []byte(v4.Region)) service := makeHmac(region, []byte(v4.ServiceName)) @@ -293,6 +320,29 @@ func (v4 *signer) bodyDigest() string { return hash } +// isRequestSigned returns if the request is currently signed or presigned +func (v4 *signer) isRequestSigned() bool { + if v4.isPresign && v4.Query.Get("X-Amz-Signature") != "" { + return true + } + if v4.Request.Header.Get("Authorization") != "" { + return true + } + + return false +} + +// unsign removes signing flags for both signed and presigned requests. +func (v4 *signer) removePresign() { + v4.Query.Del("X-Amz-Algorithm") + v4.Query.Del("X-Amz-Signature") + v4.Query.Del("X-Amz-Security-Token") + v4.Query.Del("X-Amz-Date") + v4.Query.Del("X-Amz-Expires") + v4.Query.Del("X-Amz-Credential") + v4.Query.Del("X-Amz-SignedHeaders") +} + func makeHmac(key []byte, data []byte) []byte { hash := hmac.New(sha256.New, key) hash.Write(data) @@ -306,21 +356,10 @@ func makeSha256(data []byte) []byte { } func makeSha256Reader(reader io.ReadSeeker) []byte { - packet := make([]byte, 4096) hash := sha256.New() - start, _ := reader.Seek(0, 1) defer reader.Seek(start, 0) - for { - n, err := reader.Read(packet) - if n > 0 { - hash.Write(packet[0:n]) - } - if err == io.EOF || n == 0 { - break - } - } - + io.Copy(hash, reader) return hash.Sum(nil) } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/signer/v4/v4_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/signer/v4/v4_test.go index 20f655ac6c7e..0ba9ff25f73a 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/signer/v4/v4_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/internal/signer/v4/v4_test.go @@ -8,6 +8,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" "github.com/stretchr/testify/assert" ) @@ -22,16 +24,14 @@ func buildSigner(serviceName string, region string, signTime time.Time, expireTi req.Header.Add("X-Amz-Meta-Other-Header", "some-value=!@#$%^&* (+)") return signer{ - Request: req, - Time: signTime, - ExpireTime: expireTime, - Query: req.URL.Query(), - Body: reader, - ServiceName: serviceName, - Region: region, - AccessKeyID: "AKID", - SecretAccessKey: "SECRET", - SessionToken: "SESSION", + Request: req, + Time: signTime, + ExpireTime: expireTime, + Query: req.URL.Query(), + Body: reader, + ServiceName: serviceName, + Region: region, + Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"), } } @@ -118,9 +118,9 @@ func TestSignPrecomputedBodyChecksum(t *testing.T) { } func TestAnonymousCredentials(t *testing.T) { - r := aws.NewRequest( - aws.NewService(&aws.Config{Credentials: credentials.AnonymousCredentials}), - &aws.Operation{ + svc := service.New(&aws.Config{Credentials: credentials.AnonymousCredentials}) + r := svc.NewRequest( + &request.Operation{ Name: "BatchGetItem", HTTPMethod: "POST", HTTPPath: "/", @@ -141,6 +141,97 @@ func TestAnonymousCredentials(t *testing.T) { assert.Empty(t, hQ.Get("X-Amz-Date")) } +func TestIgnoreResignRequestWithValidCreds(t *testing.T) { + svc := service.New(&aws.Config{ + Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"), + Region: aws.String("us-west-2"), + }) + r := svc.NewRequest( + &request.Operation{ + Name: "BatchGetItem", + HTTPMethod: "POST", + HTTPPath: "/", + }, + nil, + nil, + ) + + Sign(r) + sig := r.HTTPRequest.Header.Get("Authorization") + + Sign(r) + assert.Equal(t, sig, r.HTTPRequest.Header.Get("Authorization")) +} + +func TestIgnorePreResignRequestWithValidCreds(t *testing.T) { + svc := service.New(&aws.Config{ + Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"), + Region: aws.String("us-west-2"), + }) + r := svc.NewRequest( + &request.Operation{ + Name: "BatchGetItem", + HTTPMethod: "POST", + HTTPPath: "/", + }, + nil, + nil, + ) + r.ExpireTime = time.Minute * 10 + + Sign(r) + sig := r.HTTPRequest.Header.Get("X-Amz-Signature") + + Sign(r) + assert.Equal(t, sig, r.HTTPRequest.Header.Get("X-Amz-Signature")) +} + +func TestResignRequestExpiredCreds(t *testing.T) { + creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION") + svc := service.New(&aws.Config{Credentials: creds}) + r := svc.NewRequest( + &request.Operation{ + Name: "BatchGetItem", + HTTPMethod: "POST", + HTTPPath: "/", + }, + nil, + nil, + ) + Sign(r) + querySig := r.HTTPRequest.Header.Get("Authorization") + + creds.Expire() + + Sign(r) + assert.NotEqual(t, querySig, r.HTTPRequest.Header.Get("Authorization")) +} + +func TestPreResignRequestExpiredCreds(t *testing.T) { + provider := &credentials.StaticProvider{credentials.Value{"AKID", "SECRET", "SESSION"}} + creds := credentials.NewCredentials(provider) + svc := service.New(&aws.Config{Credentials: creds}) + r := svc.NewRequest( + &request.Operation{ + Name: "BatchGetItem", + HTTPMethod: "POST", + HTTPPath: "/", + }, + nil, + nil, + ) + r.ExpireTime = time.Minute * 10 + + Sign(r) + querySig := r.HTTPRequest.URL.Query().Get("X-Amz-Signature") + + creds.Expire() + r.Time = time.Now().Add(time.Hour * 48) + + Sign(r) + assert.NotEqual(t, querySig, r.HTTPRequest.URL.Query().Get("X-Amz-Signature")) +} + func BenchmarkPresignRequest(b *testing.B) { signer := buildSigner("dynamodb", "us-east-1", time.Now(), 300*time.Second, "{}") for i := 0; i < b.N; i++ { diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/api.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/api.go index 7c1443e21f96..34f6d43759f6 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/api.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/api.go @@ -4,32 +4,27 @@ package autoscaling import ( - "sync" "time" - "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" ) -var oprw sync.Mutex +const opAttachInstances = "AttachInstances" // AttachInstancesRequest generates a request for the AttachInstances operation. -func (c *AutoScaling) AttachInstancesRequest(input *AttachInstancesInput) (req *aws.Request, output *AttachInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAttachInstances == nil { - opAttachInstances = &aws.Operation{ - Name: "AttachInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) AttachInstancesRequest(input *AttachInstancesInput) (req *request.Request, output *AttachInstancesOutput) { + op := &request.Operation{ + Name: opAttachInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &AttachInstancesInput{} } - req = c.newRequest(opAttachInstances, input, output) + req = c.newRequest(op, input, output) output = &AttachInstancesOutput{} req.Data = output return @@ -37,8 +32,8 @@ func (c *AutoScaling) AttachInstancesRequest(input *AttachInstancesInput) (req * // Attaches one or more EC2 instances to the specified Auto Scaling group. // -// For more information, see Attach Amazon EC2 Instances to Your Existing Auto -// Scaling Group (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/attach-instance-asg.html) +// For more information, see Attach EC2 Instances to Your Auto Scaling Group +// (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/attach-instance-asg.html) // in the Auto Scaling Developer Guide. func (c *AutoScaling) AttachInstances(input *AttachInstancesInput) (*AttachInstancesOutput, error) { req, out := c.AttachInstancesRequest(input) @@ -46,26 +41,55 @@ func (c *AutoScaling) AttachInstances(input *AttachInstancesInput) (*AttachInsta return out, err } -var opAttachInstances *aws.Operation +const opAttachLoadBalancers = "AttachLoadBalancers" + +// AttachLoadBalancersRequest generates a request for the AttachLoadBalancers operation. +func (c *AutoScaling) AttachLoadBalancersRequest(input *AttachLoadBalancersInput) (req *request.Request, output *AttachLoadBalancersOutput) { + op := &request.Operation{ + Name: opAttachLoadBalancers, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AttachLoadBalancersInput{} + } + + req = c.newRequest(op, input, output) + output = &AttachLoadBalancersOutput{} + req.Data = output + return +} + +// Attaches one or more load balancers to the specified Auto Scaling group. +// +// To describe the load balancers for an Auto Scaling group, use DescribeLoadBalancers. +// To detach the load balancer from the Auto Scaling group, use DetachLoadBalancers. +// +// For more information, see Attach a Load Balancer to Your Auto Scaling Group +// (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/attach-load-balancer-asg.html) +// in the Auto Scaling Developer Guide. +func (c *AutoScaling) AttachLoadBalancers(input *AttachLoadBalancersInput) (*AttachLoadBalancersOutput, error) { + req, out := c.AttachLoadBalancersRequest(input) + err := req.Send() + return out, err +} + +const opCompleteLifecycleAction = "CompleteLifecycleAction" // CompleteLifecycleActionRequest generates a request for the CompleteLifecycleAction operation. -func (c *AutoScaling) CompleteLifecycleActionRequest(input *CompleteLifecycleActionInput) (req *aws.Request, output *CompleteLifecycleActionOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCompleteLifecycleAction == nil { - opCompleteLifecycleAction = &aws.Operation{ - Name: "CompleteLifecycleAction", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) CompleteLifecycleActionRequest(input *CompleteLifecycleActionInput) (req *request.Request, output *CompleteLifecycleActionOutput) { + op := &request.Operation{ + Name: opCompleteLifecycleAction, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CompleteLifecycleActionInput{} } - req = c.newRequest(opCompleteLifecycleAction, input, output) + req = c.newRequest(op, input, output) output = &CompleteLifecycleActionOutput{} req.Data = output return @@ -92,26 +116,21 @@ func (c *AutoScaling) CompleteLifecycleAction(input *CompleteLifecycleActionInpu return out, err } -var opCompleteLifecycleAction *aws.Operation +const opCreateAutoScalingGroup = "CreateAutoScalingGroup" // CreateAutoScalingGroupRequest generates a request for the CreateAutoScalingGroup operation. -func (c *AutoScaling) CreateAutoScalingGroupRequest(input *CreateAutoScalingGroupInput) (req *aws.Request, output *CreateAutoScalingGroupOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateAutoScalingGroup == nil { - opCreateAutoScalingGroup = &aws.Operation{ - Name: "CreateAutoScalingGroup", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) CreateAutoScalingGroupRequest(input *CreateAutoScalingGroupInput) (req *request.Request, output *CreateAutoScalingGroupOutput) { + op := &request.Operation{ + Name: opCreateAutoScalingGroup, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateAutoScalingGroupInput{} } - req = c.newRequest(opCreateAutoScalingGroup, input, output) + req = c.newRequest(op, input, output) output = &CreateAutoScalingGroupOutput{} req.Data = output return @@ -121,33 +140,31 @@ func (c *AutoScaling) CreateAutoScalingGroupRequest(input *CreateAutoScalingGrou // // If you exceed your maximum limit of Auto Scaling groups, which by default // is 20 per region, the call fails. For information about viewing and updating -// these limits, see DescribeAccountLimits. +// this limit, see DescribeAccountLimits. +// +// For more information, see Auto Scaling Groups (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AutoScalingGroup.html) +// in the Auto Scaling Developer Guide. func (c *AutoScaling) CreateAutoScalingGroup(input *CreateAutoScalingGroupInput) (*CreateAutoScalingGroupOutput, error) { req, out := c.CreateAutoScalingGroupRequest(input) err := req.Send() return out, err } -var opCreateAutoScalingGroup *aws.Operation +const opCreateLaunchConfiguration = "CreateLaunchConfiguration" // CreateLaunchConfigurationRequest generates a request for the CreateLaunchConfiguration operation. -func (c *AutoScaling) CreateLaunchConfigurationRequest(input *CreateLaunchConfigurationInput) (req *aws.Request, output *CreateLaunchConfigurationOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateLaunchConfiguration == nil { - opCreateLaunchConfiguration = &aws.Operation{ - Name: "CreateLaunchConfiguration", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) CreateLaunchConfigurationRequest(input *CreateLaunchConfigurationInput) (req *request.Request, output *CreateLaunchConfigurationOutput) { + op := &request.Operation{ + Name: opCreateLaunchConfiguration, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateLaunchConfigurationInput{} } - req = c.newRequest(opCreateLaunchConfiguration, input, output) + req = c.newRequest(op, input, output) output = &CreateLaunchConfigurationOutput{} req.Data = output return @@ -157,33 +174,31 @@ func (c *AutoScaling) CreateLaunchConfigurationRequest(input *CreateLaunchConfig // // If you exceed your maximum limit of launch configurations, which by default // is 100 per region, the call fails. For information about viewing and updating -// these limits, see DescribeAccountLimits. +// this limit, see DescribeAccountLimits. +// +// For more information, see Launch Configurations (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/LaunchConfiguration.html) +// in the Auto Scaling Developer Guide. func (c *AutoScaling) CreateLaunchConfiguration(input *CreateLaunchConfigurationInput) (*CreateLaunchConfigurationOutput, error) { req, out := c.CreateLaunchConfigurationRequest(input) err := req.Send() return out, err } -var opCreateLaunchConfiguration *aws.Operation +const opCreateOrUpdateTags = "CreateOrUpdateTags" // CreateOrUpdateTagsRequest generates a request for the CreateOrUpdateTags operation. -func (c *AutoScaling) CreateOrUpdateTagsRequest(input *CreateOrUpdateTagsInput) (req *aws.Request, output *CreateOrUpdateTagsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateOrUpdateTags == nil { - opCreateOrUpdateTags = &aws.Operation{ - Name: "CreateOrUpdateTags", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) CreateOrUpdateTagsRequest(input *CreateOrUpdateTagsInput) (req *request.Request, output *CreateOrUpdateTagsOutput) { + op := &request.Operation{ + Name: opCreateOrUpdateTags, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateOrUpdateTagsInput{} } - req = c.newRequest(opCreateOrUpdateTags, input, output) + req = c.newRequest(op, input, output) output = &CreateOrUpdateTagsOutput{} req.Data = output return @@ -191,10 +206,17 @@ func (c *AutoScaling) CreateOrUpdateTagsRequest(input *CreateOrUpdateTagsInput) // Creates or updates tags for the specified Auto Scaling group. // -// A tag's definition is composed of a resource ID, resource type, key and -// value, and the propagate flag. Value and the propagate flag are optional -// parameters. See the Request Parameters for more information. For more information, -// see Add, Modify, or Remove Auto Scaling Group Tags (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/ASTagging.html) +// A tag is defined by its resource ID, resource type, key, value, and propagate +// flag. The value and the propagate flag are optional parameters. The only +// supported resource type is auto-scaling-group, and the resource ID must be +// the name of the group. The PropagateAtLaunch flag determines whether the +// tag is added to instances launched in the group. Valid values are true or +// false. +// +// When you specify a tag with a key that already exists, the operation overwrites +// the previous tag definition, and you do not get an error message. +// +// For more information, see Tagging Auto Scaling Groups and Instances (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/ASTagging.html) // in the Auto Scaling Developer Guide. func (c *AutoScaling) CreateOrUpdateTags(input *CreateOrUpdateTagsInput) (*CreateOrUpdateTagsOutput, error) { req, out := c.CreateOrUpdateTagsRequest(input) @@ -202,26 +224,21 @@ func (c *AutoScaling) CreateOrUpdateTags(input *CreateOrUpdateTagsInput) (*Creat return out, err } -var opCreateOrUpdateTags *aws.Operation +const opDeleteAutoScalingGroup = "DeleteAutoScalingGroup" // DeleteAutoScalingGroupRequest generates a request for the DeleteAutoScalingGroup operation. -func (c *AutoScaling) DeleteAutoScalingGroupRequest(input *DeleteAutoScalingGroupInput) (req *aws.Request, output *DeleteAutoScalingGroupOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteAutoScalingGroup == nil { - opDeleteAutoScalingGroup = &aws.Operation{ - Name: "DeleteAutoScalingGroup", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DeleteAutoScalingGroupRequest(input *DeleteAutoScalingGroupInput) (req *request.Request, output *DeleteAutoScalingGroupOutput) { + op := &request.Operation{ + Name: opDeleteAutoScalingGroup, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteAutoScalingGroupInput{} } - req = c.newRequest(opDeleteAutoScalingGroup, input, output) + req = c.newRequest(op, input, output) output = &DeleteAutoScalingGroupOutput{} req.Data = output return @@ -231,35 +248,29 @@ func (c *AutoScaling) DeleteAutoScalingGroupRequest(input *DeleteAutoScalingGrou // // The group must have no instances and no scaling activities in progress. // -// To remove all instances before calling DeleteAutoScalingGroup, you can call -// UpdateAutoScalingGroup to set the minimum and maximum size of the AutoScalingGroup -// to zero. +// To remove all instances before calling DeleteAutoScalingGroup, call UpdateAutoScalingGroup +// to set the minimum and maximum size of the Auto Scaling group to zero. func (c *AutoScaling) DeleteAutoScalingGroup(input *DeleteAutoScalingGroupInput) (*DeleteAutoScalingGroupOutput, error) { req, out := c.DeleteAutoScalingGroupRequest(input) err := req.Send() return out, err } -var opDeleteAutoScalingGroup *aws.Operation +const opDeleteLaunchConfiguration = "DeleteLaunchConfiguration" // DeleteLaunchConfigurationRequest generates a request for the DeleteLaunchConfiguration operation. -func (c *AutoScaling) DeleteLaunchConfigurationRequest(input *DeleteLaunchConfigurationInput) (req *aws.Request, output *DeleteLaunchConfigurationOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteLaunchConfiguration == nil { - opDeleteLaunchConfiguration = &aws.Operation{ - Name: "DeleteLaunchConfiguration", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DeleteLaunchConfigurationRequest(input *DeleteLaunchConfigurationInput) (req *request.Request, output *DeleteLaunchConfigurationOutput) { + op := &request.Operation{ + Name: opDeleteLaunchConfiguration, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteLaunchConfigurationInput{} } - req = c.newRequest(opDeleteLaunchConfiguration, input, output) + req = c.newRequest(op, input, output) output = &DeleteLaunchConfigurationOutput{} req.Data = output return @@ -276,26 +287,21 @@ func (c *AutoScaling) DeleteLaunchConfiguration(input *DeleteLaunchConfiguration return out, err } -var opDeleteLaunchConfiguration *aws.Operation +const opDeleteLifecycleHook = "DeleteLifecycleHook" // DeleteLifecycleHookRequest generates a request for the DeleteLifecycleHook operation. -func (c *AutoScaling) DeleteLifecycleHookRequest(input *DeleteLifecycleHookInput) (req *aws.Request, output *DeleteLifecycleHookOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteLifecycleHook == nil { - opDeleteLifecycleHook = &aws.Operation{ - Name: "DeleteLifecycleHook", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DeleteLifecycleHookRequest(input *DeleteLifecycleHookInput) (req *request.Request, output *DeleteLifecycleHookOutput) { + op := &request.Operation{ + Name: opDeleteLifecycleHook, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteLifecycleHookInput{} } - req = c.newRequest(opDeleteLifecycleHook, input, output) + req = c.newRequest(op, input, output) output = &DeleteLifecycleHookOutput{} req.Data = output return @@ -311,26 +317,21 @@ func (c *AutoScaling) DeleteLifecycleHook(input *DeleteLifecycleHookInput) (*Del return out, err } -var opDeleteLifecycleHook *aws.Operation +const opDeleteNotificationConfiguration = "DeleteNotificationConfiguration" // DeleteNotificationConfigurationRequest generates a request for the DeleteNotificationConfiguration operation. -func (c *AutoScaling) DeleteNotificationConfigurationRequest(input *DeleteNotificationConfigurationInput) (req *aws.Request, output *DeleteNotificationConfigurationOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteNotificationConfiguration == nil { - opDeleteNotificationConfiguration = &aws.Operation{ - Name: "DeleteNotificationConfiguration", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DeleteNotificationConfigurationRequest(input *DeleteNotificationConfigurationInput) (req *request.Request, output *DeleteNotificationConfigurationOutput) { + op := &request.Operation{ + Name: opDeleteNotificationConfiguration, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteNotificationConfigurationInput{} } - req = c.newRequest(opDeleteNotificationConfiguration, input, output) + req = c.newRequest(op, input, output) output = &DeleteNotificationConfigurationOutput{} req.Data = output return @@ -343,26 +344,21 @@ func (c *AutoScaling) DeleteNotificationConfiguration(input *DeleteNotificationC return out, err } -var opDeleteNotificationConfiguration *aws.Operation +const opDeletePolicy = "DeletePolicy" // DeletePolicyRequest generates a request for the DeletePolicy operation. -func (c *AutoScaling) DeletePolicyRequest(input *DeletePolicyInput) (req *aws.Request, output *DeletePolicyOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeletePolicy == nil { - opDeletePolicy = &aws.Operation{ - Name: "DeletePolicy", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DeletePolicyRequest(input *DeletePolicyInput) (req *request.Request, output *DeletePolicyOutput) { + op := &request.Operation{ + Name: opDeletePolicy, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeletePolicyInput{} } - req = c.newRequest(opDeletePolicy, input, output) + req = c.newRequest(op, input, output) output = &DeletePolicyOutput{} req.Data = output return @@ -375,26 +371,21 @@ func (c *AutoScaling) DeletePolicy(input *DeletePolicyInput) (*DeletePolicyOutpu return out, err } -var opDeletePolicy *aws.Operation +const opDeleteScheduledAction = "DeleteScheduledAction" // DeleteScheduledActionRequest generates a request for the DeleteScheduledAction operation. -func (c *AutoScaling) DeleteScheduledActionRequest(input *DeleteScheduledActionInput) (req *aws.Request, output *DeleteScheduledActionOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteScheduledAction == nil { - opDeleteScheduledAction = &aws.Operation{ - Name: "DeleteScheduledAction", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DeleteScheduledActionRequest(input *DeleteScheduledActionInput) (req *request.Request, output *DeleteScheduledActionOutput) { + op := &request.Operation{ + Name: opDeleteScheduledAction, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteScheduledActionInput{} } - req = c.newRequest(opDeleteScheduledAction, input, output) + req = c.newRequest(op, input, output) output = &DeleteScheduledActionOutput{} req.Data = output return @@ -407,26 +398,21 @@ func (c *AutoScaling) DeleteScheduledAction(input *DeleteScheduledActionInput) ( return out, err } -var opDeleteScheduledAction *aws.Operation +const opDeleteTags = "DeleteTags" // DeleteTagsRequest generates a request for the DeleteTags operation. -func (c *AutoScaling) DeleteTagsRequest(input *DeleteTagsInput) (req *aws.Request, output *DeleteTagsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteTags == nil { - opDeleteTags = &aws.Operation{ - Name: "DeleteTags", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DeleteTagsRequest(input *DeleteTagsInput) (req *request.Request, output *DeleteTagsOutput) { + op := &request.Operation{ + Name: opDeleteTags, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteTagsInput{} } - req = c.newRequest(opDeleteTags, input, output) + req = c.newRequest(op, input, output) output = &DeleteTagsOutput{} req.Data = output return @@ -439,26 +425,21 @@ func (c *AutoScaling) DeleteTags(input *DeleteTagsInput) (*DeleteTagsOutput, err return out, err } -var opDeleteTags *aws.Operation +const opDescribeAccountLimits = "DescribeAccountLimits" // DescribeAccountLimitsRequest generates a request for the DescribeAccountLimits operation. -func (c *AutoScaling) DescribeAccountLimitsRequest(input *DescribeAccountLimitsInput) (req *aws.Request, output *DescribeAccountLimitsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeAccountLimits == nil { - opDescribeAccountLimits = &aws.Operation{ - Name: "DescribeAccountLimits", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DescribeAccountLimitsRequest(input *DescribeAccountLimitsInput) (req *request.Request, output *DescribeAccountLimitsOutput) { + op := &request.Operation{ + Name: opDescribeAccountLimits, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeAccountLimitsInput{} } - req = c.newRequest(opDescribeAccountLimits, input, output) + req = c.newRequest(op, input, output) output = &DescribeAccountLimitsOutput{} req.Data = output return @@ -467,71 +448,62 @@ func (c *AutoScaling) DescribeAccountLimitsRequest(input *DescribeAccountLimitsI // Describes the current Auto Scaling resource limits for your AWS account. // // For information about requesting an increase in these limits, see AWS Service -// Limits (http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html). +// Limits (http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html) +// in the Amazon Web Services General Reference. func (c *AutoScaling) DescribeAccountLimits(input *DescribeAccountLimitsInput) (*DescribeAccountLimitsOutput, error) { req, out := c.DescribeAccountLimitsRequest(input) err := req.Send() return out, err } -var opDescribeAccountLimits *aws.Operation +const opDescribeAdjustmentTypes = "DescribeAdjustmentTypes" // DescribeAdjustmentTypesRequest generates a request for the DescribeAdjustmentTypes operation. -func (c *AutoScaling) DescribeAdjustmentTypesRequest(input *DescribeAdjustmentTypesInput) (req *aws.Request, output *DescribeAdjustmentTypesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeAdjustmentTypes == nil { - opDescribeAdjustmentTypes = &aws.Operation{ - Name: "DescribeAdjustmentTypes", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DescribeAdjustmentTypesRequest(input *DescribeAdjustmentTypesInput) (req *request.Request, output *DescribeAdjustmentTypesOutput) { + op := &request.Operation{ + Name: opDescribeAdjustmentTypes, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeAdjustmentTypesInput{} } - req = c.newRequest(opDescribeAdjustmentTypes, input, output) + req = c.newRequest(op, input, output) output = &DescribeAdjustmentTypesOutput{} req.Data = output return } -// Lists the policy adjustment types for use with PutScalingPolicy. +// Describes the policy adjustment types for use with PutScalingPolicy. func (c *AutoScaling) DescribeAdjustmentTypes(input *DescribeAdjustmentTypesInput) (*DescribeAdjustmentTypesOutput, error) { req, out := c.DescribeAdjustmentTypesRequest(input) err := req.Send() return out, err } -var opDescribeAdjustmentTypes *aws.Operation +const opDescribeAutoScalingGroups = "DescribeAutoScalingGroups" // DescribeAutoScalingGroupsRequest generates a request for the DescribeAutoScalingGroups operation. -func (c *AutoScaling) DescribeAutoScalingGroupsRequest(input *DescribeAutoScalingGroupsInput) (req *aws.Request, output *DescribeAutoScalingGroupsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeAutoScalingGroups == nil { - opDescribeAutoScalingGroups = &aws.Operation{ - Name: "DescribeAutoScalingGroups", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxRecords", - TruncationToken: "", - }, - } +func (c *AutoScaling) DescribeAutoScalingGroupsRequest(input *DescribeAutoScalingGroupsInput) (req *request.Request, output *DescribeAutoScalingGroupsOutput) { + op := &request.Operation{ + Name: opDescribeAutoScalingGroups, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxRecords", + TruncationToken: "", + }, } if input == nil { input = &DescribeAutoScalingGroupsInput{} } - req = c.newRequest(opDescribeAutoScalingGroups, input, output) + req = c.newRequest(op, input, output) output = &DescribeAutoScalingGroupsOutput{} req.Data = output return @@ -539,10 +511,6 @@ func (c *AutoScaling) DescribeAutoScalingGroupsRequest(input *DescribeAutoScalin // Describes one or more Auto Scaling groups. If a list of names is not provided, // the call describes all Auto Scaling groups. -// -// You can specify a maximum number of items to be returned with a single call. -// If there are more items to return, the call returns a token. To get the next -// set of items, repeat the call with the returned token in the NextToken parameter. func (c *AutoScaling) DescribeAutoScalingGroups(input *DescribeAutoScalingGroupsInput) (*DescribeAutoScalingGroupsOutput, error) { req, out := c.DescribeAutoScalingGroupsRequest(input) err := req.Send() @@ -556,32 +524,27 @@ func (c *AutoScaling) DescribeAutoScalingGroupsPages(input *DescribeAutoScalingG }) } -var opDescribeAutoScalingGroups *aws.Operation +const opDescribeAutoScalingInstances = "DescribeAutoScalingInstances" // DescribeAutoScalingInstancesRequest generates a request for the DescribeAutoScalingInstances operation. -func (c *AutoScaling) DescribeAutoScalingInstancesRequest(input *DescribeAutoScalingInstancesInput) (req *aws.Request, output *DescribeAutoScalingInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeAutoScalingInstances == nil { - opDescribeAutoScalingInstances = &aws.Operation{ - Name: "DescribeAutoScalingInstances", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxRecords", - TruncationToken: "", - }, - } +func (c *AutoScaling) DescribeAutoScalingInstancesRequest(input *DescribeAutoScalingInstancesInput) (req *request.Request, output *DescribeAutoScalingInstancesOutput) { + op := &request.Operation{ + Name: opDescribeAutoScalingInstances, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxRecords", + TruncationToken: "", + }, } if input == nil { input = &DescribeAutoScalingInstancesInput{} } - req = c.newRequest(opDescribeAutoScalingInstances, input, output) + req = c.newRequest(op, input, output) output = &DescribeAutoScalingInstancesOutput{} req.Data = output return @@ -589,11 +552,6 @@ func (c *AutoScaling) DescribeAutoScalingInstancesRequest(input *DescribeAutoSca // Describes one or more Auto Scaling instances. If a list is not provided, // the call describes all instances. -// -// You can describe up to a maximum of 50 instances with a single call. By -// default, a call returns up to 20 instances. If there are more items to return, -// the call returns a token. To get the next set of items, repeat the call with -// the returned token in the NextToken parameter. func (c *AutoScaling) DescribeAutoScalingInstances(input *DescribeAutoScalingInstancesInput) (*DescribeAutoScalingInstancesOutput, error) { req, out := c.DescribeAutoScalingInstancesRequest(input) err := req.Send() @@ -607,64 +565,54 @@ func (c *AutoScaling) DescribeAutoScalingInstancesPages(input *DescribeAutoScali }) } -var opDescribeAutoScalingInstances *aws.Operation +const opDescribeAutoScalingNotificationTypes = "DescribeAutoScalingNotificationTypes" // DescribeAutoScalingNotificationTypesRequest generates a request for the DescribeAutoScalingNotificationTypes operation. -func (c *AutoScaling) DescribeAutoScalingNotificationTypesRequest(input *DescribeAutoScalingNotificationTypesInput) (req *aws.Request, output *DescribeAutoScalingNotificationTypesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeAutoScalingNotificationTypes == nil { - opDescribeAutoScalingNotificationTypes = &aws.Operation{ - Name: "DescribeAutoScalingNotificationTypes", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DescribeAutoScalingNotificationTypesRequest(input *DescribeAutoScalingNotificationTypesInput) (req *request.Request, output *DescribeAutoScalingNotificationTypesOutput) { + op := &request.Operation{ + Name: opDescribeAutoScalingNotificationTypes, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeAutoScalingNotificationTypesInput{} } - req = c.newRequest(opDescribeAutoScalingNotificationTypes, input, output) + req = c.newRequest(op, input, output) output = &DescribeAutoScalingNotificationTypesOutput{} req.Data = output return } -// Lists the notification types that are supported by Auto Scaling. +// Describes the notification types that are supported by Auto Scaling. func (c *AutoScaling) DescribeAutoScalingNotificationTypes(input *DescribeAutoScalingNotificationTypesInput) (*DescribeAutoScalingNotificationTypesOutput, error) { req, out := c.DescribeAutoScalingNotificationTypesRequest(input) err := req.Send() return out, err } -var opDescribeAutoScalingNotificationTypes *aws.Operation +const opDescribeLaunchConfigurations = "DescribeLaunchConfigurations" // DescribeLaunchConfigurationsRequest generates a request for the DescribeLaunchConfigurations operation. -func (c *AutoScaling) DescribeLaunchConfigurationsRequest(input *DescribeLaunchConfigurationsInput) (req *aws.Request, output *DescribeLaunchConfigurationsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeLaunchConfigurations == nil { - opDescribeLaunchConfigurations = &aws.Operation{ - Name: "DescribeLaunchConfigurations", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxRecords", - TruncationToken: "", - }, - } +func (c *AutoScaling) DescribeLaunchConfigurationsRequest(input *DescribeLaunchConfigurationsInput) (req *request.Request, output *DescribeLaunchConfigurationsOutput) { + op := &request.Operation{ + Name: opDescribeLaunchConfigurations, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxRecords", + TruncationToken: "", + }, } if input == nil { input = &DescribeLaunchConfigurationsInput{} } - req = c.newRequest(opDescribeLaunchConfigurations, input, output) + req = c.newRequest(op, input, output) output = &DescribeLaunchConfigurationsOutput{} req.Data = output return @@ -672,10 +620,6 @@ func (c *AutoScaling) DescribeLaunchConfigurationsRequest(input *DescribeLaunchC // Describes one or more launch configurations. If you omit the list of names, // then the call describes all launch configurations. -// -// You can specify a maximum number of items to be returned with a single call. -// If there are more items to return, the call returns a token. To get the next -// set of items, repeat the call with the returned token in the NextToken parameter. func (c *AutoScaling) DescribeLaunchConfigurations(input *DescribeLaunchConfigurationsInput) (*DescribeLaunchConfigurationsOutput, error) { req, out := c.DescribeLaunchConfigurationsRequest(input) err := req.Send() @@ -689,26 +633,21 @@ func (c *AutoScaling) DescribeLaunchConfigurationsPages(input *DescribeLaunchCon }) } -var opDescribeLaunchConfigurations *aws.Operation +const opDescribeLifecycleHookTypes = "DescribeLifecycleHookTypes" // DescribeLifecycleHookTypesRequest generates a request for the DescribeLifecycleHookTypes operation. -func (c *AutoScaling) DescribeLifecycleHookTypesRequest(input *DescribeLifecycleHookTypesInput) (req *aws.Request, output *DescribeLifecycleHookTypesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeLifecycleHookTypes == nil { - opDescribeLifecycleHookTypes = &aws.Operation{ - Name: "DescribeLifecycleHookTypes", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DescribeLifecycleHookTypesRequest(input *DescribeLifecycleHookTypesInput) (req *request.Request, output *DescribeLifecycleHookTypesOutput) { + op := &request.Operation{ + Name: opDescribeLifecycleHookTypes, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeLifecycleHookTypesInput{} } - req = c.newRequest(opDescribeLifecycleHookTypes, input, output) + req = c.newRequest(op, input, output) output = &DescribeLifecycleHookTypesOutput{} req.Data = output return @@ -721,26 +660,21 @@ func (c *AutoScaling) DescribeLifecycleHookTypes(input *DescribeLifecycleHookTyp return out, err } -var opDescribeLifecycleHookTypes *aws.Operation +const opDescribeLifecycleHooks = "DescribeLifecycleHooks" // DescribeLifecycleHooksRequest generates a request for the DescribeLifecycleHooks operation. -func (c *AutoScaling) DescribeLifecycleHooksRequest(input *DescribeLifecycleHooksInput) (req *aws.Request, output *DescribeLifecycleHooksOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeLifecycleHooks == nil { - opDescribeLifecycleHooks = &aws.Operation{ - Name: "DescribeLifecycleHooks", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DescribeLifecycleHooksRequest(input *DescribeLifecycleHooksInput) (req *request.Request, output *DescribeLifecycleHooksOutput) { + op := &request.Operation{ + Name: opDescribeLifecycleHooks, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeLifecycleHooksInput{} } - req = c.newRequest(opDescribeLifecycleHooks, input, output) + req = c.newRequest(op, input, output) output = &DescribeLifecycleHooksOutput{} req.Data = output return @@ -753,68 +687,84 @@ func (c *AutoScaling) DescribeLifecycleHooks(input *DescribeLifecycleHooksInput) return out, err } -var opDescribeLifecycleHooks *aws.Operation +const opDescribeLoadBalancers = "DescribeLoadBalancers" + +// DescribeLoadBalancersRequest generates a request for the DescribeLoadBalancers operation. +func (c *AutoScaling) DescribeLoadBalancersRequest(input *DescribeLoadBalancersInput) (req *request.Request, output *DescribeLoadBalancersOutput) { + op := &request.Operation{ + Name: opDescribeLoadBalancers, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeLoadBalancersInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeLoadBalancersOutput{} + req.Data = output + return +} + +// Describes the load balancers for the specified Auto Scaling group. +func (c *AutoScaling) DescribeLoadBalancers(input *DescribeLoadBalancersInput) (*DescribeLoadBalancersOutput, error) { + req, out := c.DescribeLoadBalancersRequest(input) + err := req.Send() + return out, err +} + +const opDescribeMetricCollectionTypes = "DescribeMetricCollectionTypes" // DescribeMetricCollectionTypesRequest generates a request for the DescribeMetricCollectionTypes operation. -func (c *AutoScaling) DescribeMetricCollectionTypesRequest(input *DescribeMetricCollectionTypesInput) (req *aws.Request, output *DescribeMetricCollectionTypesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeMetricCollectionTypes == nil { - opDescribeMetricCollectionTypes = &aws.Operation{ - Name: "DescribeMetricCollectionTypes", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DescribeMetricCollectionTypesRequest(input *DescribeMetricCollectionTypesInput) (req *request.Request, output *DescribeMetricCollectionTypesOutput) { + op := &request.Operation{ + Name: opDescribeMetricCollectionTypes, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeMetricCollectionTypesInput{} } - req = c.newRequest(opDescribeMetricCollectionTypes, input, output) + req = c.newRequest(op, input, output) output = &DescribeMetricCollectionTypesOutput{} req.Data = output return } -// Returns a list of metrics and a corresponding list of granularities for each -// metric. +// Describes the available CloudWatch metrics for Auto Scaling. // -// The GroupStandbyInstances metric is not returned by default. You must explicitly -// request it when calling EnableMetricsCollection. +// Note that the GroupStandbyInstances metric is not returned by default. You +// must explicitly request this metric when calling EnableMetricsCollection. func (c *AutoScaling) DescribeMetricCollectionTypes(input *DescribeMetricCollectionTypesInput) (*DescribeMetricCollectionTypesOutput, error) { req, out := c.DescribeMetricCollectionTypesRequest(input) err := req.Send() return out, err } -var opDescribeMetricCollectionTypes *aws.Operation +const opDescribeNotificationConfigurations = "DescribeNotificationConfigurations" // DescribeNotificationConfigurationsRequest generates a request for the DescribeNotificationConfigurations operation. -func (c *AutoScaling) DescribeNotificationConfigurationsRequest(input *DescribeNotificationConfigurationsInput) (req *aws.Request, output *DescribeNotificationConfigurationsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeNotificationConfigurations == nil { - opDescribeNotificationConfigurations = &aws.Operation{ - Name: "DescribeNotificationConfigurations", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxRecords", - TruncationToken: "", - }, - } +func (c *AutoScaling) DescribeNotificationConfigurationsRequest(input *DescribeNotificationConfigurationsInput) (req *request.Request, output *DescribeNotificationConfigurationsOutput) { + op := &request.Operation{ + Name: opDescribeNotificationConfigurations, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxRecords", + TruncationToken: "", + }, } if input == nil { input = &DescribeNotificationConfigurationsInput{} } - req = c.newRequest(opDescribeNotificationConfigurations, input, output) + req = c.newRequest(op, input, output) output = &DescribeNotificationConfigurationsOutput{} req.Data = output return @@ -835,42 +785,33 @@ func (c *AutoScaling) DescribeNotificationConfigurationsPages(input *DescribeNot }) } -var opDescribeNotificationConfigurations *aws.Operation +const opDescribePolicies = "DescribePolicies" // DescribePoliciesRequest generates a request for the DescribePolicies operation. -func (c *AutoScaling) DescribePoliciesRequest(input *DescribePoliciesInput) (req *aws.Request, output *DescribePoliciesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribePolicies == nil { - opDescribePolicies = &aws.Operation{ - Name: "DescribePolicies", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxRecords", - TruncationToken: "", - }, - } +func (c *AutoScaling) DescribePoliciesRequest(input *DescribePoliciesInput) (req *request.Request, output *DescribePoliciesOutput) { + op := &request.Operation{ + Name: opDescribePolicies, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxRecords", + TruncationToken: "", + }, } if input == nil { input = &DescribePoliciesInput{} } - req = c.newRequest(opDescribePolicies, input, output) + req = c.newRequest(op, input, output) output = &DescribePoliciesOutput{} req.Data = output return } // Describes the policies for the specified Auto Scaling group. -// -// You can specify a maximum number of items to be returned with a single call. -// If there are more items to return, the call returns a token. To get the next -// set of items, repeat the call with the returned token in the NextToken parameter. func (c *AutoScaling) DescribePolicies(input *DescribePoliciesInput) (*DescribePoliciesOutput, error) { req, out := c.DescribePoliciesRequest(input) err := req.Send() @@ -884,32 +825,27 @@ func (c *AutoScaling) DescribePoliciesPages(input *DescribePoliciesInput, fn fun }) } -var opDescribePolicies *aws.Operation +const opDescribeScalingActivities = "DescribeScalingActivities" // DescribeScalingActivitiesRequest generates a request for the DescribeScalingActivities operation. -func (c *AutoScaling) DescribeScalingActivitiesRequest(input *DescribeScalingActivitiesInput) (req *aws.Request, output *DescribeScalingActivitiesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeScalingActivities == nil { - opDescribeScalingActivities = &aws.Operation{ - Name: "DescribeScalingActivities", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxRecords", - TruncationToken: "", - }, - } +func (c *AutoScaling) DescribeScalingActivitiesRequest(input *DescribeScalingActivitiesInput) (req *request.Request, output *DescribeScalingActivitiesOutput) { + op := &request.Operation{ + Name: opDescribeScalingActivities, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxRecords", + TruncationToken: "", + }, } if input == nil { input = &DescribeScalingActivitiesInput{} } - req = c.newRequest(opDescribeScalingActivities, input, output) + req = c.newRequest(op, input, output) output = &DescribeScalingActivitiesOutput{} req.Data = output return @@ -919,10 +855,6 @@ func (c *AutoScaling) DescribeScalingActivitiesRequest(input *DescribeScalingAct // If you omit the ActivityIds, the call returns all activities from the past // six weeks. Activities are sorted by the start time. Activities still in progress // appear first on the list. -// -// You can specify a maximum number of items to be returned with a single call. -// If there are more items to return, the call returns a token. To get the next -// set of items, repeat the call with the returned token in the NextToken parameter. func (c *AutoScaling) DescribeScalingActivities(input *DescribeScalingActivitiesInput) (*DescribeScalingActivitiesOutput, error) { req, out := c.DescribeScalingActivitiesRequest(input) err := req.Send() @@ -936,72 +868,61 @@ func (c *AutoScaling) DescribeScalingActivitiesPages(input *DescribeScalingActiv }) } -var opDescribeScalingActivities *aws.Operation +const opDescribeScalingProcessTypes = "DescribeScalingProcessTypes" // DescribeScalingProcessTypesRequest generates a request for the DescribeScalingProcessTypes operation. -func (c *AutoScaling) DescribeScalingProcessTypesRequest(input *DescribeScalingProcessTypesInput) (req *aws.Request, output *DescribeScalingProcessTypesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeScalingProcessTypes == nil { - opDescribeScalingProcessTypes = &aws.Operation{ - Name: "DescribeScalingProcessTypes", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DescribeScalingProcessTypesRequest(input *DescribeScalingProcessTypesInput) (req *request.Request, output *DescribeScalingProcessTypesOutput) { + op := &request.Operation{ + Name: opDescribeScalingProcessTypes, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeScalingProcessTypesInput{} } - req = c.newRequest(opDescribeScalingProcessTypes, input, output) + req = c.newRequest(op, input, output) output = &DescribeScalingProcessTypesOutput{} req.Data = output return } -// Returns scaling process types for use in the ResumeProcesses and SuspendProcesses -// actions. +// Describes the scaling process types for use with ResumeProcesses and SuspendProcesses. func (c *AutoScaling) DescribeScalingProcessTypes(input *DescribeScalingProcessTypesInput) (*DescribeScalingProcessTypesOutput, error) { req, out := c.DescribeScalingProcessTypesRequest(input) err := req.Send() return out, err } -var opDescribeScalingProcessTypes *aws.Operation +const opDescribeScheduledActions = "DescribeScheduledActions" // DescribeScheduledActionsRequest generates a request for the DescribeScheduledActions operation. -func (c *AutoScaling) DescribeScheduledActionsRequest(input *DescribeScheduledActionsInput) (req *aws.Request, output *DescribeScheduledActionsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeScheduledActions == nil { - opDescribeScheduledActions = &aws.Operation{ - Name: "DescribeScheduledActions", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxRecords", - TruncationToken: "", - }, - } +func (c *AutoScaling) DescribeScheduledActionsRequest(input *DescribeScheduledActionsInput) (req *request.Request, output *DescribeScheduledActionsOutput) { + op := &request.Operation{ + Name: opDescribeScheduledActions, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxRecords", + TruncationToken: "", + }, } if input == nil { input = &DescribeScheduledActionsInput{} } - req = c.newRequest(opDescribeScheduledActions, input, output) + req = c.newRequest(op, input, output) output = &DescribeScheduledActionsOutput{} req.Data = output return } -// Lists the actions scheduled for your Auto Scaling group that haven't been -// executed. To list the actions that were already executed, use DescribeScalingActivities. +// Describes the actions scheduled for your Auto Scaling group that haven't +// run. To describe the actions that have already run, use DescribeScalingActivities. func (c *AutoScaling) DescribeScheduledActions(input *DescribeScheduledActionsInput) (*DescribeScheduledActionsOutput, error) { req, out := c.DescribeScheduledActionsRequest(input) err := req.Send() @@ -1015,32 +936,27 @@ func (c *AutoScaling) DescribeScheduledActionsPages(input *DescribeScheduledActi }) } -var opDescribeScheduledActions *aws.Operation +const opDescribeTags = "DescribeTags" // DescribeTagsRequest generates a request for the DescribeTags operation. -func (c *AutoScaling) DescribeTagsRequest(input *DescribeTagsInput) (req *aws.Request, output *DescribeTagsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeTags == nil { - opDescribeTags = &aws.Operation{ - Name: "DescribeTags", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxRecords", - TruncationToken: "", - }, - } +func (c *AutoScaling) DescribeTagsRequest(input *DescribeTagsInput) (req *request.Request, output *DescribeTagsOutput) { + op := &request.Operation{ + Name: opDescribeTags, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxRecords", + TruncationToken: "", + }, } if input == nil { input = &DescribeTagsInput{} } - req = c.newRequest(opDescribeTags, input, output) + req = c.newRequest(op, input, output) output = &DescribeTagsOutput{} req.Data = output return @@ -1069,58 +985,48 @@ func (c *AutoScaling) DescribeTagsPages(input *DescribeTagsInput, fn func(p *Des }) } -var opDescribeTags *aws.Operation +const opDescribeTerminationPolicyTypes = "DescribeTerminationPolicyTypes" // DescribeTerminationPolicyTypesRequest generates a request for the DescribeTerminationPolicyTypes operation. -func (c *AutoScaling) DescribeTerminationPolicyTypesRequest(input *DescribeTerminationPolicyTypesInput) (req *aws.Request, output *DescribeTerminationPolicyTypesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeTerminationPolicyTypes == nil { - opDescribeTerminationPolicyTypes = &aws.Operation{ - Name: "DescribeTerminationPolicyTypes", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DescribeTerminationPolicyTypesRequest(input *DescribeTerminationPolicyTypesInput) (req *request.Request, output *DescribeTerminationPolicyTypesOutput) { + op := &request.Operation{ + Name: opDescribeTerminationPolicyTypes, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeTerminationPolicyTypesInput{} } - req = c.newRequest(opDescribeTerminationPolicyTypes, input, output) + req = c.newRequest(op, input, output) output = &DescribeTerminationPolicyTypesOutput{} req.Data = output return } -// Lists the termination policies supported by Auto Scaling. +// Describes the termination policies supported by Auto Scaling. func (c *AutoScaling) DescribeTerminationPolicyTypes(input *DescribeTerminationPolicyTypesInput) (*DescribeTerminationPolicyTypesOutput, error) { req, out := c.DescribeTerminationPolicyTypesRequest(input) err := req.Send() return out, err } -var opDescribeTerminationPolicyTypes *aws.Operation +const opDetachInstances = "DetachInstances" // DetachInstancesRequest generates a request for the DetachInstances operation. -func (c *AutoScaling) DetachInstancesRequest(input *DetachInstancesInput) (req *aws.Request, output *DetachInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDetachInstances == nil { - opDetachInstances = &aws.Operation{ - Name: "DetachInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DetachInstancesRequest(input *DetachInstancesInput) (req *request.Request, output *DetachInstancesOutput) { + op := &request.Operation{ + Name: opDetachInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DetachInstancesInput{} } - req = c.newRequest(opDetachInstances, input, output) + req = c.newRequest(op, input, output) output = &DetachInstancesOutput{} req.Data = output return @@ -1139,26 +1045,53 @@ func (c *AutoScaling) DetachInstances(input *DetachInstancesInput) (*DetachInsta return out, err } -var opDetachInstances *aws.Operation +const opDetachLoadBalancers = "DetachLoadBalancers" + +// DetachLoadBalancersRequest generates a request for the DetachLoadBalancers operation. +func (c *AutoScaling) DetachLoadBalancersRequest(input *DetachLoadBalancersInput) (req *request.Request, output *DetachLoadBalancersOutput) { + op := &request.Operation{ + Name: opDetachLoadBalancers, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachLoadBalancersInput{} + } + + req = c.newRequest(op, input, output) + output = &DetachLoadBalancersOutput{} + req.Data = output + return +} + +// Removes one or more load balancers from the specified Auto Scaling group. +// +// When you detach a load balancer, it enters the Removing state while deregistering +// the instances in the group. When all instances are deregistered, then you +// can no longer describe the load balancer using DescribeLoadBalancers. Note +// that the instances remain running. +func (c *AutoScaling) DetachLoadBalancers(input *DetachLoadBalancersInput) (*DetachLoadBalancersOutput, error) { + req, out := c.DetachLoadBalancersRequest(input) + err := req.Send() + return out, err +} + +const opDisableMetricsCollection = "DisableMetricsCollection" // DisableMetricsCollectionRequest generates a request for the DisableMetricsCollection operation. -func (c *AutoScaling) DisableMetricsCollectionRequest(input *DisableMetricsCollectionInput) (req *aws.Request, output *DisableMetricsCollectionOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDisableMetricsCollection == nil { - opDisableMetricsCollection = &aws.Operation{ - Name: "DisableMetricsCollection", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) DisableMetricsCollectionRequest(input *DisableMetricsCollectionInput) (req *request.Request, output *DisableMetricsCollectionOutput) { + op := &request.Operation{ + Name: opDisableMetricsCollection, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DisableMetricsCollectionInput{} } - req = c.newRequest(opDisableMetricsCollection, input, output) + req = c.newRequest(op, input, output) output = &DisableMetricsCollectionOutput{} req.Data = output return @@ -1172,26 +1105,21 @@ func (c *AutoScaling) DisableMetricsCollection(input *DisableMetricsCollectionIn return out, err } -var opDisableMetricsCollection *aws.Operation +const opEnableMetricsCollection = "EnableMetricsCollection" // EnableMetricsCollectionRequest generates a request for the EnableMetricsCollection operation. -func (c *AutoScaling) EnableMetricsCollectionRequest(input *EnableMetricsCollectionInput) (req *aws.Request, output *EnableMetricsCollectionOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opEnableMetricsCollection == nil { - opEnableMetricsCollection = &aws.Operation{ - Name: "EnableMetricsCollection", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) EnableMetricsCollectionRequest(input *EnableMetricsCollectionInput) (req *request.Request, output *EnableMetricsCollectionOutput) { + op := &request.Operation{ + Name: opEnableMetricsCollection, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &EnableMetricsCollectionInput{} } - req = c.newRequest(opEnableMetricsCollection, input, output) + req = c.newRequest(op, input, output) output = &EnableMetricsCollectionOutput{} req.Data = output return @@ -1208,26 +1136,21 @@ func (c *AutoScaling) EnableMetricsCollection(input *EnableMetricsCollectionInpu return out, err } -var opEnableMetricsCollection *aws.Operation +const opEnterStandby = "EnterStandby" // EnterStandbyRequest generates a request for the EnterStandby operation. -func (c *AutoScaling) EnterStandbyRequest(input *EnterStandbyInput) (req *aws.Request, output *EnterStandbyOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opEnterStandby == nil { - opEnterStandby = &aws.Operation{ - Name: "EnterStandby", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) EnterStandbyRequest(input *EnterStandbyInput) (req *request.Request, output *EnterStandbyOutput) { + op := &request.Operation{ + Name: opEnterStandby, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &EnterStandbyInput{} } - req = c.newRequest(opEnterStandby, input, output) + req = c.newRequest(op, input, output) output = &EnterStandbyOutput{} req.Data = output return @@ -1243,26 +1166,21 @@ func (c *AutoScaling) EnterStandby(input *EnterStandbyInput) (*EnterStandbyOutpu return out, err } -var opEnterStandby *aws.Operation +const opExecutePolicy = "ExecutePolicy" // ExecutePolicyRequest generates a request for the ExecutePolicy operation. -func (c *AutoScaling) ExecutePolicyRequest(input *ExecutePolicyInput) (req *aws.Request, output *ExecutePolicyOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opExecutePolicy == nil { - opExecutePolicy = &aws.Operation{ - Name: "ExecutePolicy", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) ExecutePolicyRequest(input *ExecutePolicyInput) (req *request.Request, output *ExecutePolicyOutput) { + op := &request.Operation{ + Name: opExecutePolicy, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ExecutePolicyInput{} } - req = c.newRequest(opExecutePolicy, input, output) + req = c.newRequest(op, input, output) output = &ExecutePolicyOutput{} req.Data = output return @@ -1275,26 +1193,21 @@ func (c *AutoScaling) ExecutePolicy(input *ExecutePolicyInput) (*ExecutePolicyOu return out, err } -var opExecutePolicy *aws.Operation +const opExitStandby = "ExitStandby" // ExitStandbyRequest generates a request for the ExitStandby operation. -func (c *AutoScaling) ExitStandbyRequest(input *ExitStandbyInput) (req *aws.Request, output *ExitStandbyOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opExitStandby == nil { - opExitStandby = &aws.Operation{ - Name: "ExitStandby", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) ExitStandbyRequest(input *ExitStandbyInput) (req *request.Request, output *ExitStandbyOutput) { + op := &request.Operation{ + Name: opExitStandby, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ExitStandbyInput{} } - req = c.newRequest(opExitStandby, input, output) + req = c.newRequest(op, input, output) output = &ExitStandbyOutput{} req.Data = output return @@ -1310,26 +1223,21 @@ func (c *AutoScaling) ExitStandby(input *ExitStandbyInput) (*ExitStandbyOutput, return out, err } -var opExitStandby *aws.Operation +const opPutLifecycleHook = "PutLifecycleHook" // PutLifecycleHookRequest generates a request for the PutLifecycleHook operation. -func (c *AutoScaling) PutLifecycleHookRequest(input *PutLifecycleHookInput) (req *aws.Request, output *PutLifecycleHookOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opPutLifecycleHook == nil { - opPutLifecycleHook = &aws.Operation{ - Name: "PutLifecycleHook", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) PutLifecycleHookRequest(input *PutLifecycleHookInput) (req *request.Request, output *PutLifecycleHookOutput) { + op := &request.Operation{ + Name: opPutLifecycleHook, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &PutLifecycleHookInput{} } - req = c.newRequest(opPutLifecycleHook, input, output) + req = c.newRequest(op, input, output) output = &PutLifecycleHookOutput{} req.Data = output return @@ -1353,32 +1261,32 @@ func (c *AutoScaling) PutLifecycleHookRequest(input *PutLifecycleHookInput) (req // action. For more information, see Auto Scaling Pending State (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AutoScalingPendingState.html) // and Auto Scaling Terminating State (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AutoScalingTerminatingState.html) // in the Auto Scaling Developer Guide. +// +// If you exceed your maximum limit of lifecycle hooks, which by default is +// 50 per region, the call fails. For information about updating this limit, +// see AWS Service Limits (http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html) +// in the Amazon Web Services General Reference. func (c *AutoScaling) PutLifecycleHook(input *PutLifecycleHookInput) (*PutLifecycleHookOutput, error) { req, out := c.PutLifecycleHookRequest(input) err := req.Send() return out, err } -var opPutLifecycleHook *aws.Operation +const opPutNotificationConfiguration = "PutNotificationConfiguration" // PutNotificationConfigurationRequest generates a request for the PutNotificationConfiguration operation. -func (c *AutoScaling) PutNotificationConfigurationRequest(input *PutNotificationConfigurationInput) (req *aws.Request, output *PutNotificationConfigurationOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opPutNotificationConfiguration == nil { - opPutNotificationConfiguration = &aws.Operation{ - Name: "PutNotificationConfiguration", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) PutNotificationConfigurationRequest(input *PutNotificationConfigurationInput) (req *request.Request, output *PutNotificationConfigurationOutput) { + op := &request.Operation{ + Name: opPutNotificationConfiguration, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &PutNotificationConfigurationInput{} } - req = c.newRequest(opPutNotificationConfiguration, input, output) + req = c.newRequest(op, input, output) output = &PutNotificationConfigurationOutput{} req.Data = output return @@ -1399,26 +1307,21 @@ func (c *AutoScaling) PutNotificationConfiguration(input *PutNotificationConfigu return out, err } -var opPutNotificationConfiguration *aws.Operation +const opPutScalingPolicy = "PutScalingPolicy" // PutScalingPolicyRequest generates a request for the PutScalingPolicy operation. -func (c *AutoScaling) PutScalingPolicyRequest(input *PutScalingPolicyInput) (req *aws.Request, output *PutScalingPolicyOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opPutScalingPolicy == nil { - opPutScalingPolicy = &aws.Operation{ - Name: "PutScalingPolicy", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) PutScalingPolicyRequest(input *PutScalingPolicyInput) (req *request.Request, output *PutScalingPolicyOutput) { + op := &request.Operation{ + Name: opPutScalingPolicy, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &PutScalingPolicyInput{} } - req = c.newRequest(opPutScalingPolicy, input, output) + req = c.newRequest(op, input, output) output = &PutScalingPolicyOutput{} req.Data = output return @@ -1428,32 +1331,32 @@ func (c *AutoScaling) PutScalingPolicyRequest(input *PutScalingPolicyInput) (req // policy, use the existing policy name and set the parameters you want to change. // Any existing parameter not changed in an update to an existing policy is // not changed in this update request. +// +// If you exceed your maximum limit of step adjustments, which by default is +// 20 per region, the call fails. For information about updating this limit, +// see AWS Service Limits (http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html) +// in the Amazon Web Services General Reference. func (c *AutoScaling) PutScalingPolicy(input *PutScalingPolicyInput) (*PutScalingPolicyOutput, error) { req, out := c.PutScalingPolicyRequest(input) err := req.Send() return out, err } -var opPutScalingPolicy *aws.Operation +const opPutScheduledUpdateGroupAction = "PutScheduledUpdateGroupAction" // PutScheduledUpdateGroupActionRequest generates a request for the PutScheduledUpdateGroupAction operation. -func (c *AutoScaling) PutScheduledUpdateGroupActionRequest(input *PutScheduledUpdateGroupActionInput) (req *aws.Request, output *PutScheduledUpdateGroupActionOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opPutScheduledUpdateGroupAction == nil { - opPutScheduledUpdateGroupAction = &aws.Operation{ - Name: "PutScheduledUpdateGroupAction", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) PutScheduledUpdateGroupActionRequest(input *PutScheduledUpdateGroupActionInput) (req *request.Request, output *PutScheduledUpdateGroupActionOutput) { + op := &request.Operation{ + Name: opPutScheduledUpdateGroupAction, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &PutScheduledUpdateGroupActionInput{} } - req = c.newRequest(opPutScheduledUpdateGroupAction, input, output) + req = c.newRequest(op, input, output) output = &PutScheduledUpdateGroupActionOutput{} req.Data = output return @@ -1465,35 +1368,27 @@ func (c *AutoScaling) PutScheduledUpdateGroupActionRequest(input *PutScheduledUp // // For more information, see Scheduled Scaling (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/schedule_time.html) // in the Auto Scaling Developer Guide. -// -// Auto Scaling supports the date and time expressed in "YYYY-MM-DDThh:mm:ssZ" -// format in UTC/GMT only. func (c *AutoScaling) PutScheduledUpdateGroupAction(input *PutScheduledUpdateGroupActionInput) (*PutScheduledUpdateGroupActionOutput, error) { req, out := c.PutScheduledUpdateGroupActionRequest(input) err := req.Send() return out, err } -var opPutScheduledUpdateGroupAction *aws.Operation +const opRecordLifecycleActionHeartbeat = "RecordLifecycleActionHeartbeat" // RecordLifecycleActionHeartbeatRequest generates a request for the RecordLifecycleActionHeartbeat operation. -func (c *AutoScaling) RecordLifecycleActionHeartbeatRequest(input *RecordLifecycleActionHeartbeatInput) (req *aws.Request, output *RecordLifecycleActionHeartbeatOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opRecordLifecycleActionHeartbeat == nil { - opRecordLifecycleActionHeartbeat = &aws.Operation{ - Name: "RecordLifecycleActionHeartbeat", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) RecordLifecycleActionHeartbeatRequest(input *RecordLifecycleActionHeartbeatInput) (req *request.Request, output *RecordLifecycleActionHeartbeatOutput) { + op := &request.Operation{ + Name: opRecordLifecycleActionHeartbeat, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &RecordLifecycleActionHeartbeatInput{} } - req = c.newRequest(opRecordLifecycleActionHeartbeat, input, output) + req = c.newRequest(op, input, output) output = &RecordLifecycleActionHeartbeatOutput{} req.Data = output return @@ -1521,26 +1416,21 @@ func (c *AutoScaling) RecordLifecycleActionHeartbeat(input *RecordLifecycleActio return out, err } -var opRecordLifecycleActionHeartbeat *aws.Operation +const opResumeProcesses = "ResumeProcesses" // ResumeProcessesRequest generates a request for the ResumeProcesses operation. -func (c *AutoScaling) ResumeProcessesRequest(input *ScalingProcessQuery) (req *aws.Request, output *ResumeProcessesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opResumeProcesses == nil { - opResumeProcesses = &aws.Operation{ - Name: "ResumeProcesses", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) ResumeProcessesRequest(input *ScalingProcessQuery) (req *request.Request, output *ResumeProcessesOutput) { + op := &request.Operation{ + Name: opResumeProcesses, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ScalingProcessQuery{} } - req = c.newRequest(opResumeProcesses, input, output) + req = c.newRequest(op, input, output) output = &ResumeProcessesOutput{} req.Data = output return @@ -1557,58 +1447,51 @@ func (c *AutoScaling) ResumeProcesses(input *ScalingProcessQuery) (*ResumeProces return out, err } -var opResumeProcesses *aws.Operation +const opSetDesiredCapacity = "SetDesiredCapacity" // SetDesiredCapacityRequest generates a request for the SetDesiredCapacity operation. -func (c *AutoScaling) SetDesiredCapacityRequest(input *SetDesiredCapacityInput) (req *aws.Request, output *SetDesiredCapacityOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opSetDesiredCapacity == nil { - opSetDesiredCapacity = &aws.Operation{ - Name: "SetDesiredCapacity", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) SetDesiredCapacityRequest(input *SetDesiredCapacityInput) (req *request.Request, output *SetDesiredCapacityOutput) { + op := &request.Operation{ + Name: opSetDesiredCapacity, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &SetDesiredCapacityInput{} } - req = c.newRequest(opSetDesiredCapacity, input, output) + req = c.newRequest(op, input, output) output = &SetDesiredCapacityOutput{} req.Data = output return } -// Sets the size of the specified AutoScalingGroup. +// Sets the size of the specified Auto Scaling group. +// +// For more information about desired capacity, see What Is Auto Scaling? (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/WhatIsAutoScaling.html) +// in the Auto Scaling Developer Guide. func (c *AutoScaling) SetDesiredCapacity(input *SetDesiredCapacityInput) (*SetDesiredCapacityOutput, error) { req, out := c.SetDesiredCapacityRequest(input) err := req.Send() return out, err } -var opSetDesiredCapacity *aws.Operation +const opSetInstanceHealth = "SetInstanceHealth" // SetInstanceHealthRequest generates a request for the SetInstanceHealth operation. -func (c *AutoScaling) SetInstanceHealthRequest(input *SetInstanceHealthInput) (req *aws.Request, output *SetInstanceHealthOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opSetInstanceHealth == nil { - opSetInstanceHealth = &aws.Operation{ - Name: "SetInstanceHealth", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) SetInstanceHealthRequest(input *SetInstanceHealthInput) (req *request.Request, output *SetInstanceHealthOutput) { + op := &request.Operation{ + Name: opSetInstanceHealth, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &SetInstanceHealthInput{} } - req = c.newRequest(opSetInstanceHealth, input, output) + req = c.newRequest(op, input, output) output = &SetInstanceHealthOutput{} req.Data = output return @@ -1624,26 +1507,21 @@ func (c *AutoScaling) SetInstanceHealth(input *SetInstanceHealthInput) (*SetInst return out, err } -var opSetInstanceHealth *aws.Operation +const opSuspendProcesses = "SuspendProcesses" // SuspendProcessesRequest generates a request for the SuspendProcesses operation. -func (c *AutoScaling) SuspendProcessesRequest(input *ScalingProcessQuery) (req *aws.Request, output *SuspendProcessesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opSuspendProcesses == nil { - opSuspendProcesses = &aws.Operation{ - Name: "SuspendProcesses", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) SuspendProcessesRequest(input *ScalingProcessQuery) (req *request.Request, output *SuspendProcessesOutput) { + op := &request.Operation{ + Name: opSuspendProcesses, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ScalingProcessQuery{} } - req = c.newRequest(opSuspendProcesses, input, output) + req = c.newRequest(op, input, output) output = &SuspendProcessesOutput{} req.Data = output return @@ -1666,26 +1544,21 @@ func (c *AutoScaling) SuspendProcesses(input *ScalingProcessQuery) (*SuspendProc return out, err } -var opSuspendProcesses *aws.Operation +const opTerminateInstanceInAutoScalingGroup = "TerminateInstanceInAutoScalingGroup" // TerminateInstanceInAutoScalingGroupRequest generates a request for the TerminateInstanceInAutoScalingGroup operation. -func (c *AutoScaling) TerminateInstanceInAutoScalingGroupRequest(input *TerminateInstanceInAutoScalingGroupInput) (req *aws.Request, output *TerminateInstanceInAutoScalingGroupOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opTerminateInstanceInAutoScalingGroup == nil { - opTerminateInstanceInAutoScalingGroup = &aws.Operation{ - Name: "TerminateInstanceInAutoScalingGroup", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) TerminateInstanceInAutoScalingGroupRequest(input *TerminateInstanceInAutoScalingGroupInput) (req *request.Request, output *TerminateInstanceInAutoScalingGroupOutput) { + op := &request.Operation{ + Name: opTerminateInstanceInAutoScalingGroup, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &TerminateInstanceInAutoScalingGroupInput{} } - req = c.newRequest(opTerminateInstanceInAutoScalingGroup, input, output) + req = c.newRequest(op, input, output) output = &TerminateInstanceInAutoScalingGroupOutput{} req.Data = output return @@ -1702,96 +1575,89 @@ func (c *AutoScaling) TerminateInstanceInAutoScalingGroup(input *TerminateInstan return out, err } -var opTerminateInstanceInAutoScalingGroup *aws.Operation +const opUpdateAutoScalingGroup = "UpdateAutoScalingGroup" // UpdateAutoScalingGroupRequest generates a request for the UpdateAutoScalingGroup operation. -func (c *AutoScaling) UpdateAutoScalingGroupRequest(input *UpdateAutoScalingGroupInput) (req *aws.Request, output *UpdateAutoScalingGroupOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opUpdateAutoScalingGroup == nil { - opUpdateAutoScalingGroup = &aws.Operation{ - Name: "UpdateAutoScalingGroup", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *AutoScaling) UpdateAutoScalingGroupRequest(input *UpdateAutoScalingGroupInput) (req *request.Request, output *UpdateAutoScalingGroupOutput) { + op := &request.Operation{ + Name: opUpdateAutoScalingGroup, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &UpdateAutoScalingGroupInput{} } - req = c.newRequest(opUpdateAutoScalingGroup, input, output) + req = c.newRequest(op, input, output) output = &UpdateAutoScalingGroupOutput{} req.Data = output return } -// Updates the configuration for the specified AutoScalingGroup. +// Updates the configuration for the specified Auto Scaling group. // -// To update an Auto Scaling group with a launch configuration that has the -// InstanceMonitoring flag set to False, you must first ensure that collection -// of group metrics is disabled. Otherwise, calls to UpdateAutoScalingGroup -// will fail. If you have previously enabled group metrics collection, you can -// disable collection of all group metrics by calling DisableMetricsCollection. +// To update an Auto Scaling group with a launch configuration with InstanceMonitoring +// set to False, you must first disable the collection of group metrics. Otherwise, +// you will get an error. If you have previously enabled the collection of group +// metrics, you can disable it using DisableMetricsCollection. // -// The new settings are registered upon the completion of this call. Any -// launch configuration settings take effect on any triggers after this call -// returns. Scaling activities that are currently in progress aren't affected. +// The new settings are registered upon the completion of this call. Any launch +// configuration settings take effect on any triggers after this call returns. +// Scaling activities that are currently in progress aren't affected. // -// If a new value is specified for MinSize without specifying the value -// for DesiredCapacity, and if the new MinSize is larger than the current size -// of the Auto Scaling group, there will be an implicit call to SetDesiredCapacity -// to set the group to the new MinSize. +// Note the following: // -// If a new value is specified for MaxSize without specifying the value for +// If you specify a new value for MinSize without specifying a value for +// DesiredCapacity, and the new MinSize is larger than the current size of the +// group, we implicitly call SetDesiredCapacity to set the size of the group +// to the new value of MinSize. +// +// If you specify a new value for MaxSize without specifying a value for // DesiredCapacity, and the new MaxSize is smaller than the current size of -// the Auto Scaling group, there will be an implicit call to SetDesiredCapacity -// to set the group to the new MaxSize. +// the group, we implicitly call SetDesiredCapacity to set the size of the group +// to the new value of MaxSize. // -// All other optional parameters are left unchanged if not passed in the -// request. +// All other optional parameters are left unchanged if not specified. func (c *AutoScaling) UpdateAutoScalingGroup(input *UpdateAutoScalingGroupInput) (*UpdateAutoScalingGroupOutput, error) { req, out := c.UpdateAutoScalingGroupRequest(input) err := req.Send() return out, err } -var opUpdateAutoScalingGroup *aws.Operation - -// Describes a long-running process that represents a change to your Auto Scaling -// group, such as changing its size. This can also be a process to replace an -// instance, or a process to perform any other long-running operations. +// Describes scaling activity, which is a long-running process that represents +// a change to your Auto Scaling group, such as changing its size or replacing +// an instance. type Activity struct { // The ID of the activity. - ActivityID *string `locationName:"ActivityId" type:"string" required:"true"` + ActivityId *string `type:"string" required:"true"` // The name of the Auto Scaling group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` - // The reason the activity was begun. - Cause *string `type:"string" required:"true"` + // The reason the activity began. + Cause *string `min:"1" type:"string" required:"true"` - // A friendly, more verbose description of the scaling activity. + // A friendly, more verbose description of the activity. Description *string `type:"string"` - // The details about the scaling activity. + // The details about the activity. Details *string `type:"string"` - // The end time of this activity. + // The end time of the activity. EndTime *time.Time `type:"timestamp" timestampFormat:"iso8601"` // A value between 0 and 100 that indicates the progress of the activity. Progress *int64 `type:"integer"` - // The start time of this activity. + // The start time of the activity. StartTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` // The current status of the activity. - StatusCode *string `type:"string" required:"true"` + StatusCode *string `type:"string" required:"true" enum:"ScalingActivityStatusCode"` // A friendly, more verbose description of the activity status. - StatusMessage *string `type:"string"` + StatusMessage *string `min:"1" type:"string"` metadataActivity `json:"-" xml:"-"` } @@ -1800,14 +1666,24 @@ type metadataActivity struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Activity) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Activity) GoString() string { + return s.String() +} + // Describes a policy adjustment type. +// +// For more information, see Dynamic Scaling (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/as-scale-based-on-demand.html) +// in the Auto Scaling Developer Guide. type AdjustmentType struct { // The policy adjustment type. The valid values are ChangeInCapacity, ExactCapacity, // and PercentChangeInCapacity. - // - // For more information, see Dynamic Scaling (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/as-scale-based-on-demand.html) - // in the Auto Scaling Developer Guide. - AdjustmentType *string `type:"string"` + AdjustmentType *string `min:"1" type:"string"` metadataAdjustmentType `json:"-" xml:"-"` } @@ -1816,13 +1692,23 @@ type metadataAdjustmentType struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AdjustmentType) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AdjustmentType) GoString() string { + return s.String() +} + // Describes an alarm. type Alarm struct { // The Amazon Resource Name (ARN) of the alarm. - AlarmARN *string `type:"string"` + AlarmARN *string `min:"1" type:"string"` // The name of the alarm. - AlarmName *string `type:"string"` + AlarmName *string `min:"1" type:"string"` metadataAlarm `json:"-" xml:"-"` } @@ -1831,12 +1717,22 @@ type metadataAlarm struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Alarm) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Alarm) GoString() string { + return s.String() +} + type AttachInstancesInput struct { // The name of the group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` - // One or more EC2 instance IDs. You must specify at least one ID. - InstanceIDs []*string `locationName:"InstanceIds" type:"list"` + // One or more EC2 instance IDs. + InstanceIds []*string `type:"list"` metadataAttachInstancesInput `json:"-" xml:"-"` } @@ -1845,6 +1741,16 @@ type metadataAttachInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AttachInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachInstancesInput) GoString() string { + return s.String() +} + type AttachInstancesOutput struct { metadataAttachInstancesOutput `json:"-" xml:"-"` } @@ -1853,23 +1759,75 @@ type metadataAttachInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AttachInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachInstancesOutput) GoString() string { + return s.String() +} + +type AttachLoadBalancersInput struct { + // The name of the group. + AutoScalingGroupName *string `min:"1" type:"string"` + + // One or more load balancer names. + LoadBalancerNames []*string `type:"list"` + + metadataAttachLoadBalancersInput `json:"-" xml:"-"` +} + +type metadataAttachLoadBalancersInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s AttachLoadBalancersInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachLoadBalancersInput) GoString() string { + return s.String() +} + +type AttachLoadBalancersOutput struct { + metadataAttachLoadBalancersOutput `json:"-" xml:"-"` +} + +type metadataAttachLoadBalancersOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s AttachLoadBalancersOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachLoadBalancersOutput) GoString() string { + return s.String() +} + // Describes a block device mapping. type BlockDeviceMapping struct { // The device name exposed to the EC2 instance (for example, /dev/sdh or xvdh). - DeviceName *string `type:"string" required:"true"` + DeviceName *string `min:"1" type:"string" required:"true"` // The information about the Amazon EBS volume. - EBS *EBS `locationName:"Ebs" type:"structure"` + Ebs *Ebs `type:"structure"` // Suppresses a device mapping. // - // If NoDevice is set to true for the root device, the instance might fail - // the EC2 health check. Auto Scaling launches a replacement instance if the - // instance fails the health check. + // If this parameter is true for the root device, the instance might fail the + // EC2 health check. Auto Scaling launches a replacement instance if the instance + // fails the health check. NoDevice *bool `type:"boolean"` // The name of the virtual device, ephemeral0 to ephemeral3. - VirtualName *string `type:"string"` + VirtualName *string `min:"1" type:"string"` metadataBlockDeviceMapping `json:"-" xml:"-"` } @@ -1878,9 +1836,19 @@ type metadataBlockDeviceMapping struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s BlockDeviceMapping) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BlockDeviceMapping) GoString() string { + return s.String() +} + type CompleteLifecycleActionInput struct { // The name of the group for the lifecycle hook. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // The action for the group to take. This parameter can be either CONTINUE or // ABANDON. @@ -1889,10 +1857,10 @@ type CompleteLifecycleActionInput struct { // A universally unique identifier (UUID) that identifies a specific lifecycle // action associated with an instance. Auto Scaling sends this token to the // notification target you specified when you created the lifecycle hook. - LifecycleActionToken *string `type:"string" required:"true"` + LifecycleActionToken *string `min:"36" type:"string" required:"true"` // The name of the lifecycle hook. - LifecycleHookName *string `type:"string" required:"true"` + LifecycleHookName *string `min:"1" type:"string" required:"true"` metadataCompleteLifecycleActionInput `json:"-" xml:"-"` } @@ -1901,6 +1869,16 @@ type metadataCompleteLifecycleActionInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CompleteLifecycleActionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CompleteLifecycleActionInput) GoString() string { + return s.String() +} + type CompleteLifecycleActionOutput struct { metadataCompleteLifecycleActionOutput `json:"-" xml:"-"` } @@ -1909,24 +1887,34 @@ type metadataCompleteLifecycleActionOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CompleteLifecycleActionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CompleteLifecycleActionOutput) GoString() string { + return s.String() +} + type CreateAutoScalingGroupInput struct { // The name of the group. This name must be unique within the scope of your // AWS account. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // One or more Availability Zones for the group. This parameter is optional // if you specify subnets using the VPCZoneIdentifier parameter. - AvailabilityZones []*string `type:"list"` + AvailabilityZones []*string `min:"1" type:"list"` // The amount of time, in seconds, after a scaling activity completes before // another scaling activity can start. // - // If DefaultCooldown is not specified, the default value is 300. For more - // information, see Understanding Auto Scaling Cooldowns (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/Cooldown.html) + // If this parameter is not specified, the default value is 300. For more information, + // see Understanding Auto Scaling Cooldowns (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/Cooldown.html) // in the Auto Scaling Developer Guide. DefaultCooldown *int64 `type:"integer"` - // The number of EC2 instances that should be running in the group. This value + // The number of EC2 instances that should be running in the group. This number // must be greater than or equal to the minimum size of the group and less than // or equal to the maximum size of the group. DesiredCapacity *int64 `type:"integer"` @@ -1949,7 +1937,7 @@ type CreateAutoScalingGroupInput struct { // // By default, health checks use Amazon EC2 instance status checks to determine // the health of an instance. For more information, see Health Checks (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/healthcheck.html). - HealthCheckType *string `type:"string"` + HealthCheckType *string `min:"1" type:"string"` // The ID of the EC2 instance used to create a launch configuration for the // group. Alternatively, use the LaunchConfigurationName parameter to specify @@ -1960,14 +1948,14 @@ type CreateAutoScalingGroupInput struct { // derives its attributes from the specified instance, with the exception of // the block device mapping. // - // For more information, see Create an Auto Scaling Group Using an EC2 Instance - // ID (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/create-asg-from-instance.html) + // For more information, see Create an Auto Scaling Group from an EC2 Instance + // (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/create-asg-from-instance.html) // in the Auto Scaling Developer Guide. - InstanceID *string `locationName:"InstanceId" type:"string"` + InstanceId *string `min:"1" type:"string"` // The name of the launch configuration. Alternatively, use the InstanceId parameter // to specify an EC2 instance instead of a launch configuration. - LaunchConfigurationName *string `type:"string"` + LaunchConfigurationName *string `min:"1" type:"string"` // One or more load balancers. // @@ -1982,15 +1970,15 @@ type CreateAutoScalingGroupInput struct { MinSize *int64 `type:"integer" required:"true"` // The name of the placement group into which you'll launch your instances, - // if any. For more information, see Placement Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html). - PlacementGroup *string `type:"string"` + // if any. For more information, see Placement Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html) + // in the Amazon Elastic Compute Cloud User Guide. + PlacementGroup *string `min:"1" type:"string"` // The tag to be created or updated. Each tag should be defined by its resource // type, resource ID, key, value, and a propagate flag. Valid values: key=value, // value=value, propagate=true or false. Value and propagate are optional parameters. // - // For more information, see Add, Modify, or Remove Auto Scaling Group Tags - // (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/ASTagging.html) + // For more information, see Tagging Auto Scaling Groups and Instances (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/ASTagging.html) // in the Auto Scaling Developer Guide. Tags []*Tag `type:"list"` @@ -2008,9 +1996,10 @@ type CreateAutoScalingGroupInput struct { // If you specify subnets and Availability Zones with this call, ensure that // the subnets' Availability Zones match the Availability Zones specified. // - // For more information, see Auto Scaling and Amazon VPC (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/autoscalingsubnets.html) + // For more information, see Auto Scaling and Amazon Virtual Private Cloud + // (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/autoscalingsubnets.html) // in the Auto Scaling Developer Guide. - VPCZoneIdentifier *string `type:"string"` + VPCZoneIdentifier *string `min:"1" type:"string"` metadataCreateAutoScalingGroupInput `json:"-" xml:"-"` } @@ -2019,6 +2008,16 @@ type metadataCreateAutoScalingGroupInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateAutoScalingGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateAutoScalingGroupInput) GoString() string { + return s.String() +} + type CreateAutoScalingGroupOutput struct { metadataCreateAutoScalingGroupOutput `json:"-" xml:"-"` } @@ -2027,20 +2026,30 @@ type metadataCreateAutoScalingGroupOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateAutoScalingGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateAutoScalingGroupOutput) GoString() string { + return s.String() +} + type CreateLaunchConfigurationInput struct { // Used for groups that launch instances into a virtual private cloud (VPC). // Specifies whether to assign a public IP address to each instance. For more - // information, see Auto Scaling and Amazon VPC (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/autoscalingsubnets.html) + // information, see Auto Scaling and Amazon Virtual Private Cloud (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/autoscalingsubnets.html) // in the Auto Scaling Developer Guide. // - // If you specify a value for this parameter, be sure to specify at least - // one subnet using the VPCZoneIdentifier parameter when you create your group. + // If you specify a value for this parameter, be sure to specify at least one + // subnet using the VPCZoneIdentifier parameter when you create your group. // - // Default: If the instance is launched into a default subnet, the default + // Default: If the instance is launched into a default subnet, the default // is true. If the instance is launched into a nondefault subnet, the default - // is false. For more information, see Supported Platforms (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide//as-supported-platforms.html) + // is false. For more information, see Supported Platforms (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-supported-platforms.html) // in the Amazon Elastic Compute Cloud User Guide. - AssociatePublicIPAddress *bool `locationName:"AssociatePublicIpAddress" type:"boolean"` + AssociatePublicIpAddress *bool `type:"boolean"` // One or more mappings that specify how block devices are exposed to the instance. // For more information, see Block Device Mapping (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html) @@ -2048,14 +2057,14 @@ type CreateLaunchConfigurationInput struct { BlockDeviceMappings []*BlockDeviceMapping `type:"list"` // The ID of a ClassicLink-enabled VPC to link your EC2-Classic instances to. - // This parameter can only be used if you are launching EC2-Classic instances. + // This parameter is supported only if you are launching EC2-Classic instances. // For more information, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) // in the Amazon Elastic Compute Cloud User Guide. - ClassicLinkVPCID *string `locationName:"ClassicLinkVPCId" type:"string"` + ClassicLinkVPCId *string `min:"1" type:"string"` // The IDs of one or more security groups for the VPC specified in ClassicLinkVPCId. - // This parameter is required if ClassicLinkVPCId is specified, and cannot be - // used otherwise. For more information, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) + // This parameter is required if ClassicLinkVPCId is specified, and is not supported + // otherwise. For more information, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) // in the Amazon Elastic Compute Cloud User Guide. ClassicLinkVPCSecurityGroups []*string `type:"list"` @@ -2066,23 +2075,23 @@ type CreateLaunchConfigurationInput struct { // types. Additional usage charges apply. For more information, see Amazon EBS-Optimized // Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSOptimized.html) // in the Amazon Elastic Compute Cloud User Guide. - EBSOptimized *bool `locationName:"EbsOptimized" type:"boolean"` + EbsOptimized *bool `type:"boolean"` // The name or the Amazon Resource Name (ARN) of the instance profile associated // with the IAM role for the instance. // - // Amazon EC2 instances launched with an IAM role will automatically have AWS - // security credentials available. You can use IAM roles with Auto Scaling to - // automatically enable applications running on your Amazon EC2 instances to - // securely access other AWS resources. For more information, see Launch Auto - // Scaling Instances with an IAM Role (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/us-iam-role.html) + // EC2 instances launched with an IAM role will automatically have AWS security + // credentials available. You can use IAM roles with Auto Scaling to automatically + // enable applications running on your EC2 instances to securely access other + // AWS resources. For more information, see Launch Auto Scaling Instances with + // an IAM Role (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/us-iam-role.html) // in the Auto Scaling Developer Guide. - IAMInstanceProfile *string `locationName:"IamInstanceProfile" type:"string"` + IamInstanceProfile *string `min:"1" type:"string"` // The ID of the Amazon Machine Image (AMI) to use to launch your EC2 instances. // For more information, see Finding an AMI (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html) // in the Amazon Elastic Compute Cloud User Guide. - ImageID *string `locationName:"ImageId" type:"string"` + ImageId *string `min:"1" type:"string"` // The ID of the EC2 instance to use to create the launch configuration. // @@ -2095,53 +2104,54 @@ type CreateLaunchConfigurationInput struct { // For more information, see Create a Launch Configuration Using an EC2 Instance // (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/create-lc-with-instanceID.html) // in the Auto Scaling Developer Guide. - InstanceID *string `locationName:"InstanceId" type:"string"` + InstanceId *string `min:"1" type:"string"` // Enables detailed monitoring if it is disabled. Detailed monitoring is enabled // by default. // - // When detailed monitoring is enabled, Amazon Cloudwatch generates metrics + // When detailed monitoring is enabled, Amazon CloudWatch generates metrics // every minute and your account is charged a fee. When you disable detailed - // monitoring, by specifying False, Cloudwatch generates metrics every 5 minutes. + // monitoring, by specifying False, CloudWatch generates metrics every 5 minutes. // For more information, see Monitor Your Auto Scaling Instances (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/as-instance-monitoring.html) // in the Auto Scaling Developer Guide. InstanceMonitoring *InstanceMonitoring `type:"structure"` - // The instance type of the Amazon EC2 instance. For information about available - // Amazon EC2 instance types, see Available Instance Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#AvailableInstanceTypes) + // The instance type of the EC2 instance. For information about available instance + // types, see Available Instance Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#AvailableInstanceTypes) // in the Amazon Elastic Cloud Compute User Guide. - InstanceType *string `type:"string"` + InstanceType *string `min:"1" type:"string"` - // The ID of the kernel associated with the Amazon EC2 AMI. - KernelID *string `locationName:"KernelId" type:"string"` + // The ID of the kernel associated with the AMI. + KernelId *string `min:"1" type:"string"` // The name of the key pair. For more information, see Amazon EC2 Key Pairs // (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) in // the Amazon Elastic Compute Cloud User Guide. - KeyName *string `type:"string"` + KeyName *string `min:"1" type:"string"` // The name of the launch configuration. This name must be unique within the // scope of your AWS account. - LaunchConfigurationName *string `type:"string" required:"true"` + LaunchConfigurationName *string `min:"1" type:"string" required:"true"` // The tenancy of the instance. An instance with a tenancy of dedicated runs - // on single-tenant hardware and can only be launched in a VPC. + // on single-tenant hardware and can only be launched into a VPC. // // You must set the value of this parameter to dedicated if want to launch - // Dedicated Instances in a shared tenancy VPC (VPC with instance placement + // Dedicated Instances into a shared tenancy VPC (VPC with instance placement // tenancy attribute set to default). // // If you specify a value for this parameter, be sure to specify at least one - // VPC subnet using the VPCZoneIdentifier parameter when you create your group. + // subnet using the VPCZoneIdentifier parameter when you create your group. // - // For more information, see Auto Scaling and Amazon VPC (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/autoscalingsubnets.html) + // For more information, see Auto Scaling and Amazon Virtual Private Cloud + // (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/autoscalingsubnets.html) // in the Auto Scaling Developer Guide. // // Valid values: default | dedicated - PlacementTenancy *string `type:"string"` + PlacementTenancy *string `min:"1" type:"string"` - // The ID of the RAM disk associated with the Amazon EC2 AMI. - RAMDiskID *string `locationName:"RamdiskId" type:"string"` + // The ID of the RAM disk associated with the AMI. + RamdiskId *string `min:"1" type:"string"` // One or more security groups with which to associate the instances. // @@ -2150,7 +2160,7 @@ type CreateLaunchConfigurationInput struct { // groups for EC2-Classic, see Amazon EC2 Security Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html) // in the Amazon Elastic Compute Cloud User Guide. // - // If your instances are launched in a VPC, specify security group IDs. For + // If your instances are launched into a VPC, specify security group IDs. For // more information, see Security Groups for Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_SecurityGroups.html) // in the Amazon Virtual Private Cloud User Guide. SecurityGroups []*string `type:"list"` @@ -2160,7 +2170,7 @@ type CreateLaunchConfigurationInput struct { // the current Spot market price. For more information, see Launch Spot Instances // in Your Auto Scaling Group (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/US-SpotInstances.html) // in the Auto Scaling Developer Guide. - SpotPrice *string `type:"string"` + SpotPrice *string `min:"1" type:"string"` // The user data to make available to the launched EC2 instances. For more information, // see Instance Metadata and User Data (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) @@ -2177,6 +2187,16 @@ type metadataCreateLaunchConfigurationInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateLaunchConfigurationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLaunchConfigurationInput) GoString() string { + return s.String() +} + type CreateLaunchConfigurationOutput struct { metadataCreateLaunchConfigurationOutput `json:"-" xml:"-"` } @@ -2185,22 +2205,18 @@ type metadataCreateLaunchConfigurationOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateLaunchConfigurationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLaunchConfigurationOutput) GoString() string { + return s.String() +} + type CreateOrUpdateTagsInput struct { - // The tag to be created or updated. Each tag should be defined by its resource - // type, resource ID, key, value, and a propagate flag. The resource type and - // resource ID identify the type and name of resource for which the tag is created. - // Currently, auto-scaling-group is the only supported resource type. The valid - // value for the resource ID is groupname. - // - // The PropagateAtLaunch flag defines whether the new tag will be applied to - // instances launched by the group. Valid values are true or false. However, - // instances that are already running will not get the new or updated tag. Likewise, - // when you modify a tag, the updated version will be applied only to new instances - // launched by the group after the change. Running instances that had the previous - // version of the tag will continue to have the older tag. - // - // When you create a tag and a tag of the same name already exists, the operation - // overwrites the previous tag definition, but you will not get an error message. + // One or more tags. Tags []*Tag `type:"list" required:"true"` metadataCreateOrUpdateTagsInput `json:"-" xml:"-"` @@ -2210,6 +2226,16 @@ type metadataCreateOrUpdateTagsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateOrUpdateTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateOrUpdateTagsInput) GoString() string { + return s.String() +} + type CreateOrUpdateTagsOutput struct { metadataCreateOrUpdateTagsOutput `json:"-" xml:"-"` } @@ -2218,9 +2244,19 @@ type metadataCreateOrUpdateTagsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateOrUpdateTagsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateOrUpdateTagsOutput) GoString() string { + return s.String() +} + type DeleteAutoScalingGroupInput struct { // The name of the group to delete. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // Specifies that the group will be deleted along with all instances associated // with the group, without waiting for all instances to be terminated. This @@ -2234,6 +2270,16 @@ type metadataDeleteAutoScalingGroupInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteAutoScalingGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteAutoScalingGroupInput) GoString() string { + return s.String() +} + type DeleteAutoScalingGroupOutput struct { metadataDeleteAutoScalingGroupOutput `json:"-" xml:"-"` } @@ -2242,9 +2288,19 @@ type metadataDeleteAutoScalingGroupOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteAutoScalingGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteAutoScalingGroupOutput) GoString() string { + return s.String() +} + type DeleteLaunchConfigurationInput struct { // The name of the launch configuration. - LaunchConfigurationName *string `type:"string" required:"true"` + LaunchConfigurationName *string `min:"1" type:"string" required:"true"` metadataDeleteLaunchConfigurationInput `json:"-" xml:"-"` } @@ -2253,6 +2309,16 @@ type metadataDeleteLaunchConfigurationInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteLaunchConfigurationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLaunchConfigurationInput) GoString() string { + return s.String() +} + type DeleteLaunchConfigurationOutput struct { metadataDeleteLaunchConfigurationOutput `json:"-" xml:"-"` } @@ -2261,12 +2327,22 @@ type metadataDeleteLaunchConfigurationOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteLaunchConfigurationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLaunchConfigurationOutput) GoString() string { + return s.String() +} + type DeleteLifecycleHookInput struct { // The name of the Auto Scaling group for the lifecycle hook. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // The name of the lifecycle hook. - LifecycleHookName *string `type:"string" required:"true"` + LifecycleHookName *string `min:"1" type:"string" required:"true"` metadataDeleteLifecycleHookInput `json:"-" xml:"-"` } @@ -2275,6 +2351,16 @@ type metadataDeleteLifecycleHookInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteLifecycleHookInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLifecycleHookInput) GoString() string { + return s.String() +} + type DeleteLifecycleHookOutput struct { metadataDeleteLifecycleHookOutput `json:"-" xml:"-"` } @@ -2283,13 +2369,23 @@ type metadataDeleteLifecycleHookOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteLifecycleHookOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLifecycleHookOutput) GoString() string { + return s.String() +} + type DeleteNotificationConfigurationInput struct { // The name of the Auto Scaling group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // The Amazon Resource Name (ARN) of the Amazon Simple Notification Service // (SNS) topic. - TopicARN *string `type:"string" required:"true"` + TopicARN *string `min:"1" type:"string" required:"true"` metadataDeleteNotificationConfigurationInput `json:"-" xml:"-"` } @@ -2298,6 +2394,16 @@ type metadataDeleteNotificationConfigurationInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteNotificationConfigurationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNotificationConfigurationInput) GoString() string { + return s.String() +} + type DeleteNotificationConfigurationOutput struct { metadataDeleteNotificationConfigurationOutput `json:"-" xml:"-"` } @@ -2306,12 +2412,22 @@ type metadataDeleteNotificationConfigurationOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteNotificationConfigurationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNotificationConfigurationOutput) GoString() string { + return s.String() +} + type DeletePolicyInput struct { // The name of the Auto Scaling group. - AutoScalingGroupName *string `type:"string"` + AutoScalingGroupName *string `min:"1" type:"string"` // The name or Amazon Resource Name (ARN) of the policy. - PolicyName *string `type:"string" required:"true"` + PolicyName *string `min:"1" type:"string" required:"true"` metadataDeletePolicyInput `json:"-" xml:"-"` } @@ -2320,6 +2436,16 @@ type metadataDeletePolicyInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeletePolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeletePolicyInput) GoString() string { + return s.String() +} + type DeletePolicyOutput struct { metadataDeletePolicyOutput `json:"-" xml:"-"` } @@ -2328,12 +2454,22 @@ type metadataDeletePolicyOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeletePolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeletePolicyOutput) GoString() string { + return s.String() +} + type DeleteScheduledActionInput struct { // The name of the Auto Scaling group. - AutoScalingGroupName *string `type:"string"` + AutoScalingGroupName *string `min:"1" type:"string"` // The name of the action to delete. - ScheduledActionName *string `type:"string" required:"true"` + ScheduledActionName *string `min:"1" type:"string" required:"true"` metadataDeleteScheduledActionInput `json:"-" xml:"-"` } @@ -2342,6 +2478,16 @@ type metadataDeleteScheduledActionInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteScheduledActionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteScheduledActionInput) GoString() string { + return s.String() +} + type DeleteScheduledActionOutput struct { metadataDeleteScheduledActionOutput `json:"-" xml:"-"` } @@ -2350,6 +2496,16 @@ type metadataDeleteScheduledActionOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteScheduledActionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteScheduledActionOutput) GoString() string { + return s.String() +} + type DeleteTagsInput struct { // Each tag should be defined by its resource type, resource ID, key, value, // and a propagate flag. Valid values are: Resource type = auto-scaling-group, @@ -2364,6 +2520,16 @@ type metadataDeleteTagsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteTagsInput) GoString() string { + return s.String() +} + type DeleteTagsOutput struct { metadataDeleteTagsOutput `json:"-" xml:"-"` } @@ -2372,6 +2538,16 @@ type metadataDeleteTagsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteTagsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteTagsOutput) GoString() string { + return s.String() +} + type DescribeAccountLimitsInput struct { metadataDescribeAccountLimitsInput `json:"-" xml:"-"` } @@ -2380,6 +2556,16 @@ type metadataDescribeAccountLimitsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAccountLimitsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAccountLimitsInput) GoString() string { + return s.String() +} + type DescribeAccountLimitsOutput struct { // The maximum number of groups allowed for your AWS account. The default limit // is 20 per region. @@ -2396,6 +2582,16 @@ type metadataDescribeAccountLimitsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAccountLimitsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAccountLimitsOutput) GoString() string { + return s.String() +} + type DescribeAdjustmentTypesInput struct { metadataDescribeAdjustmentTypesInput `json:"-" xml:"-"` } @@ -2404,6 +2600,16 @@ type metadataDescribeAdjustmentTypesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAdjustmentTypesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAdjustmentTypesInput) GoString() string { + return s.String() +} + type DescribeAdjustmentTypesOutput struct { // The policy adjustment types. AdjustmentTypes []*AdjustmentType `type:"list"` @@ -2415,6 +2621,16 @@ type metadataDescribeAdjustmentTypesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAdjustmentTypesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAdjustmentTypesOutput) GoString() string { + return s.String() +} + type DescribeAutoScalingGroupsInput struct { // The group names. AutoScalingGroupNames []*string `type:"list"` @@ -2433,6 +2649,16 @@ type metadataDescribeAutoScalingGroupsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAutoScalingGroupsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAutoScalingGroupsInput) GoString() string { + return s.String() +} + type DescribeAutoScalingGroupsOutput struct { // The groups. AutoScalingGroups []*Group `type:"list" required:"true"` @@ -2448,11 +2674,21 @@ type metadataDescribeAutoScalingGroupsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAutoScalingGroupsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAutoScalingGroupsOutput) GoString() string { + return s.String() +} + type DescribeAutoScalingInstancesInput struct { // One or more Auto Scaling instances to describe, up to 50 instances. If you // omit this parameter, all Auto Scaling instances are described. If you specify // an ID that does not exist, it is ignored with no error. - InstanceIDs []*string `locationName:"InstanceIds" type:"list"` + InstanceIds []*string `type:"list"` // The maximum number of items to return with this call. MaxRecords *int64 `type:"integer"` @@ -2468,6 +2704,16 @@ type metadataDescribeAutoScalingInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAutoScalingInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAutoScalingInstancesInput) GoString() string { + return s.String() +} + type DescribeAutoScalingInstancesOutput struct { // The instances. AutoScalingInstances []*InstanceDetails `type:"list"` @@ -2483,6 +2729,16 @@ type metadataDescribeAutoScalingInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAutoScalingInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAutoScalingInstancesOutput) GoString() string { + return s.String() +} + type DescribeAutoScalingNotificationTypesInput struct { metadataDescribeAutoScalingNotificationTypesInput `json:"-" xml:"-"` } @@ -2491,6 +2747,16 @@ type metadataDescribeAutoScalingNotificationTypesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAutoScalingNotificationTypesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAutoScalingNotificationTypesInput) GoString() string { + return s.String() +} + type DescribeAutoScalingNotificationTypesOutput struct { // One or more of the following notification types: // @@ -2512,6 +2778,16 @@ type metadataDescribeAutoScalingNotificationTypesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAutoScalingNotificationTypesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAutoScalingNotificationTypesOutput) GoString() string { + return s.String() +} + type DescribeLaunchConfigurationsInput struct { // The launch configuration names. LaunchConfigurationNames []*string `type:"list"` @@ -2530,6 +2806,16 @@ type metadataDescribeLaunchConfigurationsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLaunchConfigurationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLaunchConfigurationsInput) GoString() string { + return s.String() +} + type DescribeLaunchConfigurationsOutput struct { // The launch configurations. LaunchConfigurations []*LaunchConfiguration `type:"list" required:"true"` @@ -2545,6 +2831,16 @@ type metadataDescribeLaunchConfigurationsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLaunchConfigurationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLaunchConfigurationsOutput) GoString() string { + return s.String() +} + type DescribeLifecycleHookTypesInput struct { metadataDescribeLifecycleHookTypesInput `json:"-" xml:"-"` } @@ -2553,6 +2849,16 @@ type metadataDescribeLifecycleHookTypesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLifecycleHookTypesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLifecycleHookTypesInput) GoString() string { + return s.String() +} + type DescribeLifecycleHookTypesOutput struct { // One or more of the following notification types: // @@ -2568,9 +2874,19 @@ type metadataDescribeLifecycleHookTypesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLifecycleHookTypesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLifecycleHookTypesOutput) GoString() string { + return s.String() +} + type DescribeLifecycleHooksInput struct { // The name of the group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // The names of one or more lifecycle hooks. LifecycleHookNames []*string `type:"list"` @@ -2582,6 +2898,16 @@ type metadataDescribeLifecycleHooksInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLifecycleHooksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLifecycleHooksInput) GoString() string { + return s.String() +} + type DescribeLifecycleHooksOutput struct { // The lifecycle hooks for the specified group. LifecycleHooks []*LifecycleHook `type:"list"` @@ -2593,6 +2919,69 @@ type metadataDescribeLifecycleHooksOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLifecycleHooksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLifecycleHooksOutput) GoString() string { + return s.String() +} + +type DescribeLoadBalancersInput struct { + // The name of the group. + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` + + // The maximum number of items to return with this call. + MaxRecords *int64 `type:"integer"` + + // The token for the next set of items to return. (You received this token from + // a previous call.) + NextToken *string `type:"string"` + + metadataDescribeLoadBalancersInput `json:"-" xml:"-"` +} + +type metadataDescribeLoadBalancersInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DescribeLoadBalancersInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLoadBalancersInput) GoString() string { + return s.String() +} + +type DescribeLoadBalancersOutput struct { + // The load balancers. + LoadBalancers []*LoadBalancerState `type:"list"` + + // The token to use when requesting the next set of items. If there are no additional + // items to return, the string is empty. + NextToken *string `type:"string"` + + metadataDescribeLoadBalancersOutput `json:"-" xml:"-"` +} + +type metadataDescribeLoadBalancersOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DescribeLoadBalancersOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLoadBalancersOutput) GoString() string { + return s.String() +} + type DescribeMetricCollectionTypesInput struct { metadataDescribeMetricCollectionTypesInput `json:"-" xml:"-"` } @@ -2601,30 +2990,21 @@ type metadataDescribeMetricCollectionTypesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeMetricCollectionTypesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeMetricCollectionTypesInput) GoString() string { + return s.String() +} + type DescribeMetricCollectionTypesOutput struct { - // The granularities for the listed metrics. + // The granularities for the metrics. Granularities []*MetricGranularityType `type:"list"` - // One or more of the following metrics: - // - // GroupMinSize - // - // GroupMaxSize - // - // GroupDesiredCapacity - // - // GroupInServiceInstances - // - // GroupPendingInstances - // - // GroupStandbyInstances - // - // GroupTerminatingInstances - // - // GroupTotalInstances - // - // The GroupStandbyInstances metric is not returned by default. You must - // explicitly request it when calling EnableMetricsCollection. + // One or more metrics. Metrics []*MetricCollectionType `type:"list"` metadataDescribeMetricCollectionTypesOutput `json:"-" xml:"-"` @@ -2634,6 +3014,16 @@ type metadataDescribeMetricCollectionTypesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeMetricCollectionTypesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeMetricCollectionTypesOutput) GoString() string { + return s.String() +} + type DescribeNotificationConfigurationsInput struct { // The name of the group. AutoScalingGroupNames []*string `type:"list"` @@ -2652,6 +3042,16 @@ type metadataDescribeNotificationConfigurationsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeNotificationConfigurationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNotificationConfigurationsInput) GoString() string { + return s.String() +} + type DescribeNotificationConfigurationsOutput struct { // The token to use when requesting the next set of items. If there are no additional // items to return, the string is empty. @@ -2667,9 +3067,19 @@ type metadataDescribeNotificationConfigurationsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeNotificationConfigurationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNotificationConfigurationsOutput) GoString() string { + return s.String() +} + type DescribePoliciesInput struct { // The name of the group. - AutoScalingGroupName *string `type:"string"` + AutoScalingGroupName *string `min:"1" type:"string"` // The maximum number of items to be returned with each call. MaxRecords *int64 `type:"integer"` @@ -2684,6 +3094,9 @@ type DescribePoliciesInput struct { // an unknown policy name, it is ignored with no error. PolicyNames []*string `type:"list"` + // One or more policy types. Valid values are SimpleScaling and StepScaling. + PolicyTypes []*string `type:"list"` + metadataDescribePoliciesInput `json:"-" xml:"-"` } @@ -2691,6 +3104,16 @@ type metadataDescribePoliciesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribePoliciesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribePoliciesInput) GoString() string { + return s.String() +} + type DescribePoliciesOutput struct { // The token to use when requesting the next set of items. If there are no additional // items to return, the string is empty. @@ -2706,16 +3129,26 @@ type metadataDescribePoliciesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribePoliciesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribePoliciesOutput) GoString() string { + return s.String() +} + type DescribeScalingActivitiesInput struct { - // A list containing the activity IDs of the desired scaling activities. If - // this list is omitted, all activities are described. If an AutoScalingGroupName - // is provided, the results are limited to that group. The list of requested - // activities cannot contain more than 50 items. If unknown activities are requested, - // they are ignored with no error. - ActivityIDs []*string `locationName:"ActivityIds" type:"list"` + // The activity IDs of the desired scaling activities. If this list is omitted, + // all activities are described. If the AutoScalingGroupName parameter is provided, + // the results are limited to that group. The list of requested activities cannot + // contain more than 50 items. If unknown activities are requested, they are + // ignored with no error. + ActivityIds []*string `type:"list"` // The name of the group. - AutoScalingGroupName *string `type:"string"` + AutoScalingGroupName *string `min:"1" type:"string"` // The maximum number of items to return with this call. MaxRecords *int64 `type:"integer"` @@ -2731,6 +3164,16 @@ type metadataDescribeScalingActivitiesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeScalingActivitiesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeScalingActivitiesInput) GoString() string { + return s.String() +} + type DescribeScalingActivitiesOutput struct { // The scaling activities. Activities []*Activity `type:"list" required:"true"` @@ -2746,6 +3189,16 @@ type metadataDescribeScalingActivitiesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeScalingActivitiesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeScalingActivitiesOutput) GoString() string { + return s.String() +} + type DescribeScalingProcessTypesInput struct { metadataDescribeScalingProcessTypesInput `json:"-" xml:"-"` } @@ -2754,6 +3207,16 @@ type metadataDescribeScalingProcessTypesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeScalingProcessTypesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeScalingProcessTypesInput) GoString() string { + return s.String() +} + type DescribeScalingProcessTypesOutput struct { // The names of the process types. Processes []*ProcessType `type:"list"` @@ -2765,9 +3228,19 @@ type metadataDescribeScalingProcessTypesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeScalingProcessTypesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeScalingProcessTypesOutput) GoString() string { + return s.String() +} + type DescribeScheduledActionsInput struct { // The name of the group. - AutoScalingGroupName *string `type:"string"` + AutoScalingGroupName *string `min:"1" type:"string"` // The latest scheduled start time to return. If scheduled action names are // provided, this parameter is ignored. @@ -2800,6 +3273,16 @@ type metadataDescribeScheduledActionsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeScheduledActionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeScheduledActionsInput) GoString() string { + return s.String() +} + type DescribeScheduledActionsOutput struct { // The token to use when requesting the next set of items. If there are no additional // items to return, the string is empty. @@ -2815,11 +3298,18 @@ type metadataDescribeScheduledActionsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeScheduledActionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeScheduledActionsOutput) GoString() string { + return s.String() +} + type DescribeTagsInput struct { - // The value of the filter type used to identify the tags to be returned. For - // example, you can filter so that tags are returned according to Auto Scaling - // group, the key and value, or whether the new tag will be applied to instances - // launched after the tag is created (PropagateAtLaunch). + // A filter used to scope the tags to return. Filters []*Filter `type:"list"` // The maximum number of items to return with this call. @@ -2836,6 +3326,16 @@ type metadataDescribeTagsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeTagsInput) GoString() string { + return s.String() +} + type DescribeTagsOutput struct { // The token to use when requesting the next set of items. If there are no additional // items to return, the string is empty. @@ -2851,6 +3351,16 @@ type metadataDescribeTagsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeTagsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeTagsOutput) GoString() string { + return s.String() +} + type DescribeTerminationPolicyTypesInput struct { metadataDescribeTerminationPolicyTypesInput `json:"-" xml:"-"` } @@ -2859,10 +3369,19 @@ type metadataDescribeTerminationPolicyTypesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeTerminationPolicyTypesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeTerminationPolicyTypesInput) GoString() string { + return s.String() +} + type DescribeTerminationPolicyTypesOutput struct { - // The Termination policies supported by Auto Scaling. They are: OldestInstance, - // OldestLaunchConfiguration, NewestInstance, ClosestToNextInstanceHour, and - // Default. + // The termination policies supported by Auto Scaling (OldestInstance, OldestLaunchConfiguration, + // NewestInstance, ClosestToNextInstanceHour, and Default). TerminationPolicyTypes []*string `type:"list"` metadataDescribeTerminationPolicyTypesOutput `json:"-" xml:"-"` @@ -2872,12 +3391,22 @@ type metadataDescribeTerminationPolicyTypesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeTerminationPolicyTypesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeTerminationPolicyTypesOutput) GoString() string { + return s.String() +} + type DetachInstancesInput struct { // The name of the group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // One or more instance IDs. - InstanceIDs []*string `locationName:"InstanceIds" type:"list"` + InstanceIds []*string `type:"list"` // If True, the Auto Scaling group decrements the desired capacity value by // the number of instances detached. @@ -2890,6 +3419,16 @@ type metadataDetachInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DetachInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachInstancesInput) GoString() string { + return s.String() +} + type DetachInstancesOutput struct { // The activities related to detaching the instances from the Auto Scaling group. Activities []*Activity `type:"list"` @@ -2901,11 +3440,63 @@ type metadataDetachInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DetachInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachInstancesOutput) GoString() string { + return s.String() +} + +type DetachLoadBalancersInput struct { + // The name of the group. + AutoScalingGroupName *string `min:"1" type:"string"` + + // One or more load balancer names. + LoadBalancerNames []*string `type:"list"` + + metadataDetachLoadBalancersInput `json:"-" xml:"-"` +} + +type metadataDetachLoadBalancersInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DetachLoadBalancersInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachLoadBalancersInput) GoString() string { + return s.String() +} + +type DetachLoadBalancersOutput struct { + metadataDetachLoadBalancersOutput `json:"-" xml:"-"` +} + +type metadataDetachLoadBalancersOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DetachLoadBalancersOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachLoadBalancersOutput) GoString() string { + return s.String() +} + type DisableMetricsCollectionInput struct { // The name or Amazon Resource Name (ARN) of the group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` - // One or more of the following metrics: + // One or more metrics. If you omit this parameter, all metrics are disabled. // // GroupMinSize // @@ -2922,8 +3513,6 @@ type DisableMetricsCollectionInput struct { // GroupTerminatingInstances // // GroupTotalInstances - // - // If you omit this parameter, all metrics are disabled. Metrics []*string `type:"list"` metadataDisableMetricsCollectionInput `json:"-" xml:"-"` @@ -2933,6 +3522,16 @@ type metadataDisableMetricsCollectionInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DisableMetricsCollectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableMetricsCollectionInput) GoString() string { + return s.String() +} + type DisableMetricsCollectionOutput struct { metadataDisableMetricsCollectionOutput `json:"-" xml:"-"` } @@ -2941,8 +3540,18 @@ type metadataDisableMetricsCollectionOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DisableMetricsCollectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableMetricsCollectionOutput) GoString() string { + return s.String() +} + // Describes an Amazon EBS volume. -type EBS struct { +type Ebs struct { // Indicates whether to delete the volume on instance termination. // // Default: true @@ -2954,10 +3563,10 @@ type EBS struct { // Valid values: Range is 100 to 4000. // // Default: None - IOPS *int64 `locationName:"Iops" type:"integer"` + Iops *int64 `min:"100" type:"integer"` // The ID of the snapshot. - SnapshotID *string `locationName:"SnapshotId" type:"string"` + SnapshotId *string `min:"1" type:"string"` // The volume size, in gigabytes. // @@ -2969,31 +3578,41 @@ type EBS struct { // volume size, the default is the size of the snapshot. // // Required: Required when the volume type is io1. - VolumeSize *int64 `type:"integer"` + VolumeSize *int64 `min:"1" type:"integer"` // The volume type. // // Valid values: standard | io1 | gp2 // // Default: standard - VolumeType *string `type:"string"` + VolumeType *string `min:"1" type:"string"` - metadataEBS `json:"-" xml:"-"` + metadataEbs `json:"-" xml:"-"` } -type metadataEBS struct { +type metadataEbs struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Ebs) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Ebs) GoString() string { + return s.String() +} + type EnableMetricsCollectionInput struct { // The name or ARN of the Auto Scaling group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` - // The granularity to associate with the metrics to collect. Currently, the - // only valid value is "1Minute". - Granularity *string `type:"string" required:"true"` + // The granularity to associate with the metrics to collect. The only valid + // value is 1Minute. + Granularity *string `min:"1" type:"string" required:"true"` - // One or more of the following metrics: + // One or more metrics. If you omit this parameter, all metrics are enabled. // // GroupMinSize // @@ -3011,10 +3630,8 @@ type EnableMetricsCollectionInput struct { // // GroupTotalInstances // - // If you omit this parameter, all metrics are enabled. - // - // The GroupStandbyInstances metric is not returned by default. You must explicitly - // request it when calling EnableMetricsCollection. + // Note that the GroupStandbyInstances metric is not enabled by default. You + // must explicitly request this metric. Metrics []*string `type:"list"` metadataEnableMetricsCollectionInput `json:"-" xml:"-"` @@ -3024,6 +3641,16 @@ type metadataEnableMetricsCollectionInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s EnableMetricsCollectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableMetricsCollectionInput) GoString() string { + return s.String() +} + type EnableMetricsCollectionOutput struct { metadataEnableMetricsCollectionOutput `json:"-" xml:"-"` } @@ -3032,13 +3659,39 @@ type metadataEnableMetricsCollectionOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s EnableMetricsCollectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableMetricsCollectionOutput) GoString() string { + return s.String() +} + // Describes an enabled metric. type EnabledMetric struct { - // The granularity of the metric. - Granularity *string `type:"string"` + // The granularity of the metric. The only valid value is 1Minute. + Granularity *string `min:"1" type:"string"` // The name of the metric. - Metric *string `type:"string"` + // + // GroupMinSize + // + // GroupMaxSize + // + // GroupDesiredCapacity + // + // GroupInServiceInstances + // + // GroupPendingInstances + // + // GroupStandbyInstances + // + // GroupTerminatingInstances + // + // GroupTotalInstances + Metric *string `min:"1" type:"string"` metadataEnabledMetric `json:"-" xml:"-"` } @@ -3047,13 +3700,23 @@ type metadataEnabledMetric struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s EnabledMetric) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnabledMetric) GoString() string { + return s.String() +} + type EnterStandbyInput struct { // The name of the Auto Scaling group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // One or more instances to move into Standby mode. You must specify at least // one instance ID. - InstanceIDs []*string `locationName:"InstanceIds" type:"list"` + InstanceIds []*string `type:"list"` // Specifies whether the instances moved to Standby mode count as part of the // Auto Scaling group's desired capacity. If set, the desired capacity for the @@ -3068,6 +3731,16 @@ type metadataEnterStandbyInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s EnterStandbyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnterStandbyInput) GoString() string { + return s.String() +} + type EnterStandbyOutput struct { // The activities related to moving instances into Standby mode. Activities []*Activity `type:"list"` @@ -3079,23 +3752,51 @@ type metadataEnterStandbyOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s EnterStandbyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnterStandbyOutput) GoString() string { + return s.String() +} + type ExecutePolicyInput struct { // The name or Amazon Resource Name (ARN) of the Auto Scaling group. - AutoScalingGroupName *string `type:"string"` + AutoScalingGroupName *string `min:"1" type:"string"` + + // The breach threshold for the alarm. + // + // This parameter is required if the policy type is StepScaling and not supported + // otherwise. + BreachThreshold *float64 `type:"double"` - // Set to True if you want Auto Scaling to wait for the cooldown period associated - // with the Auto Scaling group to complete before executing the policy. + // If this parameter is true, Auto Scaling waits for the cooldown period to + // complete before executing the policy. Otherwise, Auto Scaling executes the + // policy without waiting for the cooldown period to complete. // - // Set to False if you want Auto Scaling to circumvent the cooldown period - // associated with the Auto Scaling group and execute the policy before the - // cooldown period ends. + // This parameter is not supported if the policy type is StepScaling. // // For more information, see Understanding Auto Scaling Cooldowns (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/Cooldown.html) // in the Auto Scaling Developer Guide. HonorCooldown *bool `type:"boolean"` + // The metric value to compare to BreachThreshold. This enables you to execute + // a policy of type StepScaling and determine which step adjustment to use. + // For example, if the breach threshold is 50 and you want to use a step adjustment + // with a lower bound of 0 and an upper bound of 10, you can set the metric + // value to 59. + // + // If you specify a metric value that doesn't correspond to a step adjustment + // for the policy, the call returns an error. + // + // This parameter is required if the policy type is StepScaling and not supported + // otherwise. + MetricValue *float64 `type:"double"` + // The name or ARN of the policy. - PolicyName *string `type:"string" required:"true"` + PolicyName *string `min:"1" type:"string" required:"true"` metadataExecutePolicyInput `json:"-" xml:"-"` } @@ -3104,6 +3805,16 @@ type metadataExecutePolicyInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ExecutePolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExecutePolicyInput) GoString() string { + return s.String() +} + type ExecutePolicyOutput struct { metadataExecutePolicyOutput `json:"-" xml:"-"` } @@ -3112,12 +3823,22 @@ type metadataExecutePolicyOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ExecutePolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExecutePolicyOutput) GoString() string { + return s.String() +} + type ExitStandbyInput struct { // The name of the Auto Scaling group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // One or more instance IDs. You must specify at least one instance ID. - InstanceIDs []*string `locationName:"InstanceIds" type:"list"` + InstanceIds []*string `type:"list"` metadataExitStandbyInput `json:"-" xml:"-"` } @@ -3126,6 +3847,16 @@ type metadataExitStandbyInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ExitStandbyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExitStandbyInput) GoString() string { + return s.String() +} + type ExitStandbyOutput struct { // The activities related to moving instances out of Standby mode. Activities []*Activity `type:"list"` @@ -3137,6 +3868,16 @@ type metadataExitStandbyOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ExitStandbyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExitStandbyOutput) GoString() string { + return s.String() +} + // Describes a filter. type Filter struct { // The name of the filter. The valid values are: "auto-scaling-group", "key", @@ -3153,16 +3894,26 @@ type metadataFilter struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Filter) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Filter) GoString() string { + return s.String() +} + // Describes an Auto Scaling group. type Group struct { // The Amazon Resource Name (ARN) of the group. - AutoScalingGroupARN *string `type:"string"` + AutoScalingGroupARN *string `min:"1" type:"string"` // The name of the group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // One or more Availability Zones for the group. - AvailabilityZones []*string `type:"list" required:"true"` + AvailabilityZones []*string `min:"1" type:"list" required:"true"` // The date and time the group was created. CreatedTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` @@ -3171,10 +3922,10 @@ type Group struct { // scaling activities can start. DefaultCooldown *int64 `type:"integer" required:"true"` - // The size of the group. + // The desired size of the group. DesiredCapacity *int64 `type:"integer" required:"true"` - // The metrics enabled for this Auto Scaling group. + // The metrics enabled for the group. EnabledMetrics []*EnabledMetric `type:"list"` // The amount of time that Auto Scaling waits before checking an instance's @@ -3183,13 +3934,13 @@ type Group struct { // The service of interest for the health status check, which can be either // EC2 for Amazon EC2 or ELB for Elastic Load Balancing. - HealthCheckType *string `type:"string" required:"true"` + HealthCheckType *string `min:"1" type:"string" required:"true"` // The EC2 instances associated with the group. Instances []*Instance `type:"list"` // The name of the associated launch configuration. - LaunchConfigurationName *string `type:"string" required:"true"` + LaunchConfigurationName *string `min:"1" type:"string" required:"true"` // One or more load balancers associated with the group. LoadBalancerNames []*string `type:"list"` @@ -3202,26 +3953,25 @@ type Group struct { // The name of the placement group into which you'll launch your instances, // if any. For more information, see Placement Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html). - PlacementGroup *string `type:"string"` + PlacementGroup *string `min:"1" type:"string"` - // The current state of the Auto Scaling group when a DeleteAutoScalingGroup - // action is in progress. - Status *string `type:"string"` + // The current state of the group when DeleteAutoScalingGroup is in progress. + Status *string `min:"1" type:"string"` // The suspended processes associated with the group. SuspendedProcesses []*SuspendedProcess `type:"list"` - // The tags for the Auto Scaling group. + // The tags for the group. Tags []*TagDescription `type:"list"` - // The termination policies for this Auto Scaling group. + // The termination policies for the group. TerminationPolicies []*string `type:"list"` // One or more subnet IDs, if applicable, separated by commas. // // If you specify VPCZoneIdentifier and AvailabilityZones, ensure that the // Availability Zones of the subnets match the values for AvailabilityZones. - VPCZoneIdentifier *string `type:"string"` + VPCZoneIdentifier *string `min:"1" type:"string"` metadataGroup `json:"-" xml:"-"` } @@ -3230,24 +3980,33 @@ type metadataGroup struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Group) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Group) GoString() string { + return s.String() +} + // Describes an EC2 instance. type Instance struct { - // The Availability Zone associated with this instance. - AvailabilityZone *string `type:"string" required:"true"` + // The Availability Zone in which the instance is running. + AvailabilityZone *string `min:"1" type:"string" required:"true"` // The health status of the instance. - HealthStatus *string `type:"string" required:"true"` + HealthStatus *string `min:"1" type:"string" required:"true"` // The ID of the instance. - InstanceID *string `locationName:"InstanceId" type:"string" required:"true"` + InstanceId *string `min:"1" type:"string" required:"true"` // The launch configuration associated with the instance. - LaunchConfigurationName *string `type:"string" required:"true"` + LaunchConfigurationName *string `min:"1" type:"string" required:"true"` - // A description of the current lifecycle state. - // - // The Quarantined lifecycle state is not used. - LifecycleState *string `type:"string" required:"true"` + // A description of the current lifecycle state. Note that the Quarantined state + // is not used. + LifecycleState *string `type:"string" required:"true" enum:"LifecycleState"` metadataInstance `json:"-" xml:"-"` } @@ -3256,29 +4015,39 @@ type metadataInstance struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Instance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Instance) GoString() string { + return s.String() +} + // Describes an EC2 instance associated with an Auto Scaling group. type InstanceDetails struct { // The name of the Auto Scaling group associated with the instance. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // The Availability Zone for the instance. - AvailabilityZone *string `type:"string" required:"true"` + AvailabilityZone *string `min:"1" type:"string" required:"true"` // The health status of this instance. "Healthy" means that the instance is // healthy and should remain in service. "Unhealthy" means that the instance // is unhealthy and Auto Scaling should terminate and replace it. - HealthStatus *string `type:"string" required:"true"` + HealthStatus *string `min:"1" type:"string" required:"true"` // The ID of the instance. - InstanceID *string `locationName:"InstanceId" type:"string" required:"true"` + InstanceId *string `min:"1" type:"string" required:"true"` // The launch configuration associated with the instance. - LaunchConfigurationName *string `type:"string" required:"true"` + LaunchConfigurationName *string `min:"1" type:"string" required:"true"` // The lifecycle state for the instance. For more information, see Auto Scaling // Instance States (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AutoScalingGroupLifecycle.html#AutoScalingStates) // in the Auto Scaling Developer Guide. - LifecycleState *string `type:"string" required:"true"` + LifecycleState *string `min:"1" type:"string" required:"true"` metadataInstanceDetails `json:"-" xml:"-"` } @@ -3287,6 +4056,16 @@ type metadataInstanceDetails struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceDetails) GoString() string { + return s.String() +} + // Describes whether instance monitoring is enabled. type InstanceMonitoring struct { // If True, instance monitoring is enabled. @@ -3299,21 +4078,30 @@ type metadataInstanceMonitoring struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceMonitoring) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceMonitoring) GoString() string { + return s.String() +} + // Describes a launch configuration. type LaunchConfiguration struct { - // Specifies whether the EC2 instances are associated with a public IP address - // (true) or not (false). - AssociatePublicIPAddress *bool `locationName:"AssociatePublicIpAddress" type:"boolean"` + // Specifies whether the instances are associated with a public IP address (true) + // or not (false). + AssociatePublicIpAddress *bool `type:"boolean"` - // A block device mapping that specifies how block devices are exposed to the - // instance. Each mapping is made up of a virtualName and a deviceName. + // A block device mapping, which specifies the block devices for the instance. BlockDeviceMappings []*BlockDeviceMapping `type:"list"` // The ID of a ClassicLink-enabled VPC to link your EC2-Classic instances to. // This parameter can only be used if you are launching EC2-Classic instances. // For more information, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) // in the Amazon Elastic Compute Cloud User Guide. - ClassicLinkVPCID *string `locationName:"ClassicLinkVPCId" type:"string"` + ClassicLinkVPCId *string `min:"1" type:"string"` // The IDs of one or more security groups for the VPC specified in ClassicLinkVPCId. // This parameter is required if ClassicLinkVPCId is specified, and cannot be @@ -3325,48 +4113,48 @@ type LaunchConfiguration struct { CreatedTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` // Controls whether the instance is optimized for EBS I/O (true) or not (false). - EBSOptimized *bool `locationName:"EbsOptimized" type:"boolean"` + EbsOptimized *bool `type:"boolean"` // The name or Amazon Resource Name (ARN) of the instance profile associated // with the IAM role for the instance. - IAMInstanceProfile *string `locationName:"IamInstanceProfile" type:"string"` + IamInstanceProfile *string `min:"1" type:"string"` // The ID of the Amazon Machine Image (AMI). - ImageID *string `locationName:"ImageId" type:"string" required:"true"` + ImageId *string `min:"1" type:"string" required:"true"` // Controls whether instances in this group are launched with detailed monitoring. InstanceMonitoring *InstanceMonitoring `type:"structure"` - // The instance type for the EC2 instances. - InstanceType *string `type:"string" required:"true"` + // The instance type for the instances. + InstanceType *string `min:"1" type:"string" required:"true"` // The ID of the kernel associated with the AMI. - KernelID *string `locationName:"KernelId" type:"string"` + KernelId *string `min:"1" type:"string"` // The name of the key pair. - KeyName *string `type:"string"` + KeyName *string `min:"1" type:"string"` // The Amazon Resource Name (ARN) of the launch configuration. - LaunchConfigurationARN *string `type:"string"` + LaunchConfigurationARN *string `min:"1" type:"string"` // The name of the launch configuration. - LaunchConfigurationName *string `type:"string" required:"true"` + LaunchConfigurationName *string `min:"1" type:"string" required:"true"` // The tenancy of the instance, either default or dedicated. An instance with // dedicated tenancy runs in an isolated, single-tenant hardware and can only - // be launched in a VPC. - PlacementTenancy *string `type:"string"` + // be launched into a VPC. + PlacementTenancy *string `min:"1" type:"string"` // The ID of the RAM disk associated with the AMI. - RAMDiskID *string `locationName:"RamdiskId" type:"string"` + RamdiskId *string `min:"1" type:"string"` - // The security groups to associate with the EC2 instances. + // The security groups to associate with the instances. SecurityGroups []*string `type:"list"` // The price to bid when launching Spot Instances. - SpotPrice *string `type:"string"` + SpotPrice *string `min:"1" type:"string"` - // The user data available to the EC2 instances. + // The user data available to the instances. UserData *string `type:"string"` metadataLaunchConfiguration `json:"-" xml:"-"` @@ -3376,6 +4164,16 @@ type metadataLaunchConfiguration struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s LaunchConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchConfiguration) GoString() string { + return s.String() +} + // Describes a lifecycle hook, which tells Auto Scaling that you want to perform // an action when an instance launches or terminates. When you have a lifecycle // hook in place, the Auto Scaling group will either: @@ -3387,7 +4185,7 @@ type metadataLaunchConfiguration struct { // in the Auto Scaling Developer Guide. type LifecycleHook struct { // The name of the Auto Scaling group for the lifecycle hook. - AutoScalingGroupName *string `type:"string"` + AutoScalingGroupName *string `min:"1" type:"string"` // Defines the action the Auto Scaling group should take when the lifecycle // hook timeout elapses or if an unexpected failure occurs. The valid values @@ -3395,7 +4193,7 @@ type LifecycleHook struct { DefaultResult *string `type:"string"` // The maximum length of time an instance can remain in a Pending:Wait or Terminating:Wait - // state. Currently, this value is set at 48 hours. + // state. Currently, the maximum is set to 48 hours. GlobalTimeout *int64 `type:"integer"` // The amount of time that can elapse before the lifecycle hook times out. When @@ -3405,15 +4203,15 @@ type LifecycleHook struct { HeartbeatTimeout *int64 `type:"integer"` // The name of the lifecycle hook. - LifecycleHookName *string `type:"string"` + LifecycleHookName *string `min:"1" type:"string"` // The state of the EC2 instance to which you want to attach the lifecycle hook. - // For a list of lifecycle hook types, see DescribeLifecycleHooks. + // For a list of lifecycle hook types, see DescribeLifecycleHookTypes. LifecycleTransition *string `type:"string"` // Additional information that you want to include any time Auto Scaling sends // a message to the notification target. - NotificationMetadata *string `type:"string"` + NotificationMetadata *string `min:"1" type:"string"` // The ARN of the notification target that Auto Scaling uses to notify you when // an instance is in the transition state for the lifecycle hook. This ARN target @@ -3422,11 +4220,11 @@ type LifecycleHook struct { // // Lifecycle action token User account ID Name of the Auto Scaling group Lifecycle // hook name EC2 instance ID Lifecycle transition Notification metadata - NotificationTargetARN *string `type:"string"` + NotificationTargetARN *string `min:"1" type:"string"` // The ARN of the IAM role that allows the Auto Scaling group to publish to // the specified notification target. - RoleARN *string `type:"string"` + RoleARN *string `min:"1" type:"string"` metadataLifecycleHook `json:"-" xml:"-"` } @@ -3435,10 +4233,72 @@ type metadataLifecycleHook struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s LifecycleHook) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LifecycleHook) GoString() string { + return s.String() +} + +// Describes the state of a load balancer. +type LoadBalancerState struct { + // The name of the load balancer. + LoadBalancerName *string `min:"1" type:"string"` + + // The state of the load balancer. + // + // Adding - The instances in the group are being registered with the load + // balancer. + // + // Added - All instances in the group are registered with the load balancer. + // + // InService - At least one instance in the group passed an ELB health check. + // + // Removing - The instances are being deregistered from the load balancer. + // If connection draining is enabled, Elastic Load Balancing waits for in-flight + // requests to complete before deregistering the instances. + State *string `min:"1" type:"string"` + + metadataLoadBalancerState `json:"-" xml:"-"` +} + +type metadataLoadBalancerState struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s LoadBalancerState) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadBalancerState) GoString() string { + return s.String() +} + // Describes a metric. type MetricCollectionType struct { // The metric. - Metric *string `type:"string"` + // + // GroupMinSize + // + // GroupMaxSize + // + // GroupDesiredCapacity + // + // GroupInServiceInstances + // + // GroupPendingInstances + // + // GroupStandbyInstances + // + // GroupTerminatingInstances + // + // GroupTotalInstances + Metric *string `min:"1" type:"string"` metadataMetricCollectionType `json:"-" xml:"-"` } @@ -3447,10 +4307,20 @@ type metadataMetricCollectionType struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s MetricCollectionType) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MetricCollectionType) GoString() string { + return s.String() +} + // Describes a granularity of a metric. type MetricGranularityType struct { - // The granularity. - Granularity *string `type:"string"` + // The granularity. The only valid value is 1Minute. + Granularity *string `min:"1" type:"string"` metadataMetricGranularityType `json:"-" xml:"-"` } @@ -3459,17 +4329,37 @@ type metadataMetricGranularityType struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s MetricGranularityType) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MetricGranularityType) GoString() string { + return s.String() +} + // Describes a notification. type NotificationConfiguration struct { // The name of the group. - AutoScalingGroupName *string `type:"string"` + AutoScalingGroupName *string `min:"1" type:"string"` // The types of events for an action to start. - NotificationType *string `type:"string"` + // + // autoscaling:EC2_INSTANCE_LAUNCH + // + // autoscaling:EC2_INSTANCE_LAUNCH_ERROR + // + // autoscaling:EC2_INSTANCE_TERMINATE + // + // autoscaling:EC2_INSTANCE_TERMINATE_ERROR + // + // autoscaling:TEST_NOTIFICATION + NotificationType *string `min:"1" type:"string"` // The Amazon Resource Name (ARN) of the Amazon Simple Notification Service // (SNS) topic. - TopicARN *string `type:"string"` + TopicARN *string `min:"1" type:"string"` metadataNotificationConfiguration `json:"-" xml:"-"` } @@ -3478,81 +4368,39 @@ type metadataNotificationConfiguration struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s NotificationConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NotificationConfiguration) GoString() string { + return s.String() +} + // Describes a process type. // -// There are two primary Auto Scaling process types--Launch and Terminate. -// The Launch process creates a new EC2 instance for an Auto Scaling group, -// and the Terminate process removes an existing EC2 instance. The remaining -// Auto Scaling process types relate to specific Auto Scaling features: -// -// AddToLoadBalancer AlarmNotification AZRebalance HealthCheck ReplaceUnhealthy -// ScheduledActions If you suspend Launch or Terminate, all other process -// types are affected to varying degrees. The following descriptions discuss -// how each process type is affected by a suspension of Launch or Terminate. -// The AddToLoadBalancer process type adds instances to the load balancer when -// the instances are launched. If you suspend this process, Auto Scaling will -// launch the instances but will not add them to the load balancer. If you resume -// the AddToLoadBalancer process, Auto Scaling will also resume adding new instances -// to the load balancer when they are launched. However, Auto Scaling will not -// add running instances that were launched while the process was suspended; -// those instances must be added manually using the RegisterInstancesWithLoadBalancer -// (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/APIReference/API_RegisterInstancesWithLoadBalancer.html) -// call. -// -// The AlarmNotification process type accepts notifications from Amazon CloudWatch -// alarms that are associated with the Auto Scaling group. If you suspend the -// AlarmNotification process type, Auto Scaling will not automatically execute -// scaling policies that would be triggered by alarms. -// -// Although the AlarmNotification process type is not directly affected by -// a suspension of Launch or Terminate, alarm notifications are often used to -// signal that a change in the size of the Auto Scaling group is warranted. -// If you suspend Launch or Terminate, Auto Scaling might not be able to implement -// the alarm's associated policy. -// -// The AZRebalance process type seeks to maintain a balanced number of instances -// across Availability Zones within a Region. If you remove an Availability -// Zone from your Auto Scaling group or an Availability Zone otherwise becomes -// unhealthy or unavailable, Auto Scaling launches new instances in an unaffected -// Availability Zone before terminating the unhealthy or unavailable instances. -// When the unhealthy Availability Zone returns to a healthy state, Auto Scaling -// automatically redistributes the application instances evenly across all of -// the designated Availability Zones. -// -// If you call SuspendProcesses on the launch process type, the AZRebalance -// process will neither launch new instances nor terminate existing instances. -// This is because the AZRebalance process terminates existing instances only -// after launching the replacement instances. -// -// If you call SuspendProcesses on the terminate process type, the AZRebalance -// process can cause your Auto Scaling group to grow up to ten percent larger -// than the maximum size. This is because Auto Scaling allows groups to temporarily -// grow larger than the maximum size during rebalancing activities. If Auto -// Scaling cannot terminate instances, your Auto Scaling group could remain -// up to ten percent larger than the maximum size until you resume the terminate -// process type. -// -// The HealthCheck process type checks the health of the instances. Auto Scaling -// marks an instance as unhealthy if Amazon EC2 or Elastic Load Balancing informs -// Auto Scaling that the instance is unhealthy. The HealthCheck process can -// override the health status of an instance that you set with SetInstanceHealth. -// -// The ReplaceUnhealthy process type terminates instances that are marked as -// unhealthy and subsequently creates new instances to replace them. This process -// calls both of the primary process types--first Terminate and then Launch. -// -// The HealthCheck process type works in conjunction with the ReplaceUnhealthly -// process type to provide health check functionality. If you suspend either -// Launch or Terminate, the ReplaceUnhealthy process type will not function -// properly. -// -// The ScheduledActions process type performs scheduled actions that you create -// with PutScheduledUpdateGroupAction. Scheduled actions often involve launching -// new instances or terminating existing instances. If you suspend either Launch -// or Terminate, your scheduled actions might not function as expected. +// For more information, see Auto Scaling Processes (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/US_SuspendResume.html#process-types) +// in the Auto Scaling Developer Guide. type ProcessType struct { // The name of the process. - ProcessName *string `type:"string" required:"true"` + // + // Launch + // + // Terminate + // + // AddToLoadBalancer + // + // AlarmNotification + // + // AZRebalance + // + // HealthCheck + // + // ReplaceUnhealthy + // + // ScheduledActions + ProcessName *string `min:"1" type:"string" required:"true"` metadataProcessType `json:"-" xml:"-"` } @@ -3561,10 +4409,20 @@ type metadataProcessType struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ProcessType) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ProcessType) GoString() string { + return s.String() +} + type PutLifecycleHookInput struct { // The name of the Auto Scaling group to which you want to assign the lifecycle // hook. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // Defines the action the Auto Scaling group should take when the lifecycle // hook timeout elapses or if an unexpected failure occurs. The value for this @@ -3580,27 +4438,27 @@ type PutLifecycleHookInput struct { HeartbeatTimeout *int64 `type:"integer"` // The name of the lifecycle hook. - LifecycleHookName *string `type:"string" required:"true"` + LifecycleHookName *string `min:"1" type:"string" required:"true"` - // The Amazon EC2 instance state to which you want to attach the lifecycle hook. - // See DescribeLifecycleHookTypes for a list of available lifecycle hook types. + // The instance state to which you want to attach the lifecycle hook. For a + // list of lifecycle hook types, see DescribeLifecycleHookTypes. // - // This parameter is required for new lifecycle hooks, but optional when updating + // This parameter is required for new lifecycle hooks, but optional when updating // existing hooks. LifecycleTransition *string `type:"string"` // Contains additional information that you want to include any time Auto Scaling // sends a message to the notification target. - NotificationMetadata *string `type:"string"` + NotificationMetadata *string `min:"1" type:"string"` // The ARN of the notification target that Auto Scaling will use to notify you // when an instance is in the transition state for the lifecycle hook. This // ARN target can be either an SQS queue or an SNS topic. // - // This parameter is required for new lifecycle hooks, but optional when updating + // This parameter is required for new lifecycle hooks, but optional when updating // existing hooks. // - // The notification message sent to the target will include: + // The notification message sent to the target will include: // // LifecycleActionToken. The Lifecycle action token. AccountId. The user // account ID. AutoScalingGroupName. The name of the Auto Scaling group. LifecycleHookName. @@ -3612,14 +4470,14 @@ type PutLifecycleHookInput struct { // // When you call this operation, a test message is sent to the notification // target. This test message contains an additional key/value pair: Event:autoscaling:TEST_NOTIFICATION. - NotificationTargetARN *string `type:"string"` + NotificationTargetARN *string `min:"1" type:"string"` // The ARN of the IAM role that allows the Auto Scaling group to publish to // the specified notification target. // - // This parameter is required for new lifecycle hooks, but optional when updating + // This parameter is required for new lifecycle hooks, but optional when updating // existing hooks. - RoleARN *string `type:"string"` + RoleARN *string `min:"1" type:"string"` metadataPutLifecycleHookInput `json:"-" xml:"-"` } @@ -3628,6 +4486,16 @@ type metadataPutLifecycleHookInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PutLifecycleHookInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutLifecycleHookInput) GoString() string { + return s.String() +} + type PutLifecycleHookOutput struct { metadataPutLifecycleHookOutput `json:"-" xml:"-"` } @@ -3636,9 +4504,19 @@ type metadataPutLifecycleHookOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PutLifecycleHookOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutLifecycleHookOutput) GoString() string { + return s.String() +} + type PutNotificationConfigurationInput struct { // The name of the Auto Scaling group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // The type of event that will cause the notification to be sent. For details // about notification types supported by Auto Scaling, see DescribeAutoScalingNotificationTypes. @@ -3646,7 +4524,7 @@ type PutNotificationConfigurationInput struct { // The Amazon Resource Name (ARN) of the Amazon Simple Notification Service // (SNS) topic. - TopicARN *string `type:"string" required:"true"` + TopicARN *string `min:"1" type:"string" required:"true"` metadataPutNotificationConfigurationInput `json:"-" xml:"-"` } @@ -3655,6 +4533,16 @@ type metadataPutNotificationConfigurationInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PutNotificationConfigurationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutNotificationConfigurationInput) GoString() string { + return s.String() +} + type PutNotificationConfigurationOutput struct { metadataPutNotificationConfigurationOutput `json:"-" xml:"-"` } @@ -3663,41 +4551,81 @@ type metadataPutNotificationConfigurationOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PutNotificationConfigurationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutNotificationConfigurationOutput) GoString() string { + return s.String() +} + type PutScalingPolicyInput struct { - // Specifies whether the ScalingAdjustment is an absolute number or a percentage - // of the current capacity. Valid values are ChangeInCapacity, ExactCapacity, - // and PercentChangeInCapacity. + // The adjustment type. Valid values are ChangeInCapacity, ExactCapacity, and + // PercentChangeInCapacity. // // For more information, see Dynamic Scaling (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/as-scale-based-on-demand.html) // in the Auto Scaling Developer Guide. - AdjustmentType *string `type:"string" required:"true"` + AdjustmentType *string `min:"1" type:"string" required:"true"` // The name or ARN of the group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // The amount of time, in seconds, after a scaling activity completes and before - // the next scaling activity can start. + // the next scaling activity can start. If this parameter is not specified, + // the default cooldown period for the group applies. + // + // This parameter is not supported unless the policy type is SimpleScaling. // // For more information, see Understanding Auto Scaling Cooldowns (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/Cooldown.html) // in the Auto Scaling Developer Guide. Cooldown *int64 `type:"integer"` - // Used with AdjustmentType with the value PercentChangeInCapacity, the scaling - // policy changes the DesiredCapacity of the Auto Scaling group by at least - // the number of instances specified in the value. + // The estimated time, in seconds, until a newly launched instance can contribute + // to the CloudWatch metrics. The default is to use the value specified for + // the default cooldown period for the group. // - // You will get a ValidationError if you use MinAdjustmentStep on a policy - // with an AdjustmentType other than PercentChangeInCapacity. + // This parameter is not supported if the policy type is SimpleScaling. + EstimatedInstanceWarmup *int64 `type:"integer"` + + // The aggregation type for the CloudWatch metrics. Valid values are Minimum, + // Maximum, and Average. If the aggregation type is null, the value is treated + // as Average. + // + // This parameter is not supported if the policy type is SimpleScaling. + MetricAggregationType *string `min:"1" type:"string"` + + // The minimum number of instances to scale. If the value of AdjustmentType + // is PercentChangeInCapacity, the scaling policy changes the DesiredCapacity + // of the Auto Scaling group by at least this many instances. Otherwise, the + // error is ValidationError. + MinAdjustmentMagnitude *int64 `type:"integer"` + + // Available for backward compatibility. Use MinAdjustmentMagnitude instead. MinAdjustmentStep *int64 `type:"integer"` // The name of the policy. - PolicyName *string `type:"string" required:"true"` + PolicyName *string `min:"1" type:"string" required:"true"` - // The number of instances by which to scale. AdjustmentType determines the - // interpretation of this number (e.g., as an absolute number or as a percentage - // of the existing Auto Scaling group size). A positive increment adds to the - // current capacity and a negative value removes from the current capacity. - ScalingAdjustment *int64 `type:"integer" required:"true"` + // The policy type. Valid values are SimpleScaling and StepScaling. If the policy + // type is null, the value is treated as SimpleScaling. + PolicyType *string `min:"1" type:"string"` + + // The amount by which to scale, based on the specified adjustment type. A positive + // value adds to the current capacity while a negative number removes from the + // current capacity. + // + // This parameter is required if the policy type is SimpleScaling and not supported + // otherwise. + ScalingAdjustment *int64 `type:"integer"` + + // A set of adjustments that enable you to scale based on the size of the alarm + // breach. + // + // This parameter is required if the policy type is StepScaling and not supported + // otherwise. + StepAdjustments []*StepAdjustment `type:"list"` metadataPutScalingPolicyInput `json:"-" xml:"-"` } @@ -3706,9 +4634,19 @@ type metadataPutScalingPolicyInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PutScalingPolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutScalingPolicyInput) GoString() string { + return s.String() +} + type PutScalingPolicyOutput struct { // The Amazon Resource Name (ARN) of the policy. - PolicyARN *string `type:"string"` + PolicyARN *string `min:"1" type:"string"` metadataPutScalingPolicyOutput `json:"-" xml:"-"` } @@ -3717,11 +4655,21 @@ type metadataPutScalingPolicyOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PutScalingPolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutScalingPolicyOutput) GoString() string { + return s.String() +} + type PutScheduledUpdateGroupActionInput struct { // The name or Amazon Resource Name (ARN) of the Auto Scaling group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` - // The number of Amazon EC2 instances that should be running in the group. + // The number of EC2 instances that should be running in the group. DesiredCapacity *int64 `type:"integer"` // The time for this action to end. @@ -3730,35 +4678,34 @@ type PutScheduledUpdateGroupActionInput struct { // The maximum size for the Auto Scaling group. MaxSize *int64 `type:"integer"` - // The minimum size for the new Auto Scaling group. + // The minimum size for the Auto Scaling group. MinSize *int64 `type:"integer"` // The time when recurring future actions will start. Start time is specified - // by the user following the Unix cron syntax format. For information about - // cron syntax, go to Wikipedia, The Free Encyclopedia (http://en.wikipedia.org/wiki/Cron). + // by the user following the Unix cron syntax format. For more information, + // see Cron (http://en.wikipedia.org/wiki/Cron) in Wikipedia. // // When StartTime and EndTime are specified with Recurrence, they form the // boundaries of when the recurring action will start and stop. - Recurrence *string `type:"string"` + Recurrence *string `min:"1" type:"string"` // The name of this scaling action. - ScheduledActionName *string `type:"string" required:"true"` + ScheduledActionName *string `min:"1" type:"string" required:"true"` - // The time for this action to start, as in --start-time 2010-06-01T00:00:00Z. + // The time for this action to start, in "YYYY-MM-DDThh:mm:ssZ" format in UTC/GMT + // only (for example, 2014-06-01T00:00:00Z). // // If you try to schedule your action in the past, Auto Scaling returns an // error message. // // When StartTime and EndTime are specified with Recurrence, they form the - // boundaries of when the recurring action will start and stop. + // boundaries of when the recurring action starts and stops. StartTime *time.Time `type:"timestamp" timestampFormat:"iso8601"` - // Time is deprecated. + // This parameter is deprecated; use StartTime instead. // - // The time for this action to start. Time is an alias for StartTime and can - // be specified instead of StartTime, or vice versa. If both Time and StartTime - // are specified, their values should be identical. Otherwise, PutScheduledUpdateGroupAction - // will return an error. + // The time for this action to start. If both Time and StartTime are specified, + // their values must be identical. Time *time.Time `type:"timestamp" timestampFormat:"iso8601"` metadataPutScheduledUpdateGroupActionInput `json:"-" xml:"-"` @@ -3768,6 +4715,16 @@ type metadataPutScheduledUpdateGroupActionInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PutScheduledUpdateGroupActionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutScheduledUpdateGroupActionInput) GoString() string { + return s.String() +} + type PutScheduledUpdateGroupActionOutput struct { metadataPutScheduledUpdateGroupActionOutput `json:"-" xml:"-"` } @@ -3776,17 +4733,27 @@ type metadataPutScheduledUpdateGroupActionOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PutScheduledUpdateGroupActionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutScheduledUpdateGroupActionOutput) GoString() string { + return s.String() +} + type RecordLifecycleActionHeartbeatInput struct { // The name of the Auto Scaling group for the hook. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // A token that uniquely identifies a specific lifecycle action associated with // an instance. Auto Scaling sends this token to the notification target you // specified when you created the lifecycle hook. - LifecycleActionToken *string `type:"string" required:"true"` + LifecycleActionToken *string `min:"36" type:"string" required:"true"` // The name of the lifecycle hook. - LifecycleHookName *string `type:"string" required:"true"` + LifecycleHookName *string `min:"1" type:"string" required:"true"` metadataRecordLifecycleActionHeartbeatInput `json:"-" xml:"-"` } @@ -3795,6 +4762,16 @@ type metadataRecordLifecycleActionHeartbeatInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RecordLifecycleActionHeartbeatInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RecordLifecycleActionHeartbeatInput) GoString() string { + return s.String() +} + type RecordLifecycleActionHeartbeatOutput struct { metadataRecordLifecycleActionHeartbeatOutput `json:"-" xml:"-"` } @@ -3803,6 +4780,16 @@ type metadataRecordLifecycleActionHeartbeatOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RecordLifecycleActionHeartbeatOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RecordLifecycleActionHeartbeatOutput) GoString() string { + return s.String() +} + type ResumeProcessesOutput struct { metadataResumeProcessesOutput `json:"-" xml:"-"` } @@ -3811,38 +4798,67 @@ type metadataResumeProcessesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ResumeProcessesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResumeProcessesOutput) GoString() string { + return s.String() +} + // Describes a scaling policy. type ScalingPolicy struct { - // Specifies whether the ScalingAdjustment is an absolute number or a percentage - // of the current capacity. Valid values are ChangeInCapacity, ExactCapacity, - // and PercentChangeInCapacity. - AdjustmentType *string `type:"string"` + // The adjustment type, which specifies how ScalingAdjustment is interpreted. + // Valid values are ChangeInCapacity, ExactCapacity, and PercentChangeInCapacity. + AdjustmentType *string `min:"1" type:"string"` - // The CloudWatch Alarms related to the policy. + // The CloudWatch alarms related to the policy. Alarms []*Alarm `type:"list"` // The name of the Auto Scaling group associated with this scaling policy. - AutoScalingGroupName *string `type:"string"` + AutoScalingGroupName *string `min:"1" type:"string"` // The amount of time, in seconds, after a scaling activity completes before // any further trigger-related scaling activities can start. Cooldown *int64 `type:"integer"` - // Changes the DesiredCapacity of the Auto Scaling group by at least the specified - // number of instances. + // The estimated time, in seconds, until a newly launched instance can contribute + // to the CloudWatch metrics. + EstimatedInstanceWarmup *int64 `type:"integer"` + + // The aggregation type for the CloudWatch metrics. Valid values are Minimum, + // Maximum, and Average. + MetricAggregationType *string `min:"1" type:"string"` + + // The minimum number of instances to scale. If the value of AdjustmentType + // is PercentChangeInCapacity, the scaling policy changes the DesiredCapacity + // of the Auto Scaling group by at least this many instances. Otherwise, the + // error is ValidationError. + MinAdjustmentMagnitude *int64 `type:"integer"` + + // Available for backward compatibility. Use MinAdjustmentMagnitude instead. MinAdjustmentStep *int64 `type:"integer"` // The Amazon Resource Name (ARN) of the policy. - PolicyARN *string `type:"string"` + PolicyARN *string `min:"1" type:"string"` // The name of the scaling policy. - PolicyName *string `type:"string"` + PolicyName *string `min:"1" type:"string"` + + // The policy type. Valid values are SimpleScaling and StepScaling. + PolicyType *string `min:"1" type:"string"` - // The number associated with the specified adjustment type. A positive value - // adds to the current capacity and a negative value removes from the current - // capacity. + // The amount by which to scale, based on the specified adjustment type. A positive + // value adds to the current capacity while a negative number removes from the + // current capacity. ScalingAdjustment *int64 `type:"integer"` + // A set of adjustments that enable you to scale based on the size of the alarm + // breach. + StepAdjustments []*StepAdjustment `type:"list"` + metadataScalingPolicy `json:"-" xml:"-"` } @@ -3850,14 +4866,37 @@ type metadataScalingPolicy struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ScalingPolicy) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScalingPolicy) GoString() string { + return s.String() +} + type ScalingProcessQuery struct { // The name or Amazon Resource Name (ARN) of the Auto Scaling group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // One or more of the following processes: // - // Launch Terminate HealthCheck ReplaceUnhealthy AZRebalance AlarmNotification - // ScheduledActions AddToLoadBalancer + // Launch + // + // Terminate + // + // HealthCheck + // + // ReplaceUnhealthy + // + // AZRebalance + // + // AlarmNotification + // + // ScheduledActions + // + // AddToLoadBalancer ScalingProcesses []*string `type:"list"` metadataScalingProcessQuery `json:"-" xml:"-"` @@ -3867,16 +4906,26 @@ type metadataScalingProcessQuery struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ScalingProcessQuery) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScalingProcessQuery) GoString() string { + return s.String() +} + // Describes a scheduled update to an Auto Scaling group. type ScheduledUpdateGroupAction struct { // The name of the group. - AutoScalingGroupName *string `type:"string"` + AutoScalingGroupName *string `min:"1" type:"string"` // The number of instances you prefer to maintain in the group. DesiredCapacity *int64 `type:"integer"` - // The time that the action is scheduled to end. This value can be up to one - // month in the future. + // The date and time that the action is scheduled to end. This date and time + // can be up to one month in the future. EndTime *time.Time `type:"timestamp" timestampFormat:"iso8601"` // The maximum size of the group. @@ -3885,25 +4934,23 @@ type ScheduledUpdateGroupAction struct { // The minimum size of the group. MinSize *int64 `type:"integer"` - // The regular schedule that an action occurs. - Recurrence *string `type:"string"` + // The recurring schedule for the action. + Recurrence *string `min:"1" type:"string"` // The Amazon Resource Name (ARN) of the scheduled action. - ScheduledActionARN *string `type:"string"` + ScheduledActionARN *string `min:"1" type:"string"` // The name of the scheduled action. - ScheduledActionName *string `type:"string"` + ScheduledActionName *string `min:"1" type:"string"` - // The time that the action is scheduled to begin. This value can be up to one - // month in the future. + // The date and time that the action is scheduled to begin. This date and time + // can be up to one month in the future. // // When StartTime and EndTime are specified with Recurrence, they form the // boundaries of when the recurring action will start and stop. StartTime *time.Time `type:"timestamp" timestampFormat:"iso8601"` - // Time is deprecated. - // - // The time that the action is scheduled to begin. Time is an alias for StartTime. + // This parameter is deprecated; use StartTime instead. Time *time.Time `type:"timestamp" timestampFormat:"iso8601"` metadataScheduledUpdateGroupAction `json:"-" xml:"-"` @@ -3913,9 +4960,19 @@ type metadataScheduledUpdateGroupAction struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ScheduledUpdateGroupAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ScheduledUpdateGroupAction) GoString() string { + return s.String() +} + type SetDesiredCapacityInput struct { // The name of the Auto Scaling group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // The number of EC2 instances that should be running in the Auto Scaling group. DesiredCapacity *int64 `type:"integer" required:"true"` @@ -3933,6 +4990,16 @@ type metadataSetDesiredCapacityInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SetDesiredCapacityInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetDesiredCapacityInput) GoString() string { + return s.String() +} + type SetDesiredCapacityOutput struct { metadataSetDesiredCapacityOutput `json:"-" xml:"-"` } @@ -3941,14 +5008,24 @@ type metadataSetDesiredCapacityOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SetDesiredCapacityOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetDesiredCapacityOutput) GoString() string { + return s.String() +} + type SetInstanceHealthInput struct { // The health status of the instance. Set to Healthy if you want the instance // to remain in service. Set to Unhealthy if you want the instance to be out // of service. Auto Scaling will terminate and replace the unhealthy instance. - HealthStatus *string `type:"string" required:"true"` + HealthStatus *string `min:"1" type:"string" required:"true"` // The ID of the EC2 instance. - InstanceID *string `locationName:"InstanceId" type:"string" required:"true"` + InstanceId *string `min:"1" type:"string" required:"true"` // If the Auto Scaling group of the specified instance has a HealthCheckGracePeriod // specified for the group, by default, this call will respect the grace period. @@ -3966,6 +5043,16 @@ type metadataSetInstanceHealthInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SetInstanceHealthInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetInstanceHealthInput) GoString() string { + return s.String() +} + type SetInstanceHealthOutput struct { metadataSetInstanceHealthOutput `json:"-" xml:"-"` } @@ -3974,6 +5061,84 @@ type metadataSetInstanceHealthOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SetInstanceHealthOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetInstanceHealthOutput) GoString() string { + return s.String() +} + +// Describes an adjustment based on the difference between the value of the +// aggregated CloudWatch metric and the breach threshold that you've defined +// for the alarm. +// +// For the following examples, suppose that you have an alarm with a breach +// threshold of 50: +// +// If you want the adjustment to be triggered when the metric is greater +// than or equal to 50 and less than 60, specify a lower bound of 0 and an upper +// bound of 10. +// +// If you want the adjustment to be triggered when the metric is greater +// than 40 and less than or equal to 50, specify a lower bound of -10 and an +// upper bound of 0. +// +// There are a few rules for the step adjustments for your step policy: +// +// The ranges of your step adjustments can't overlap or have a gap. +// +// At most one step adjustment can have a null lower bound. If one step adjustment +// has a negative lower bound, then there must be a step adjustment with a null +// lower bound. +// +// At most one step adjustment can have a null upper bound. If one step adjustment +// has a positive upper bound, then there must be a step adjustment with a null +// upper bound. +// +// The upper and lower bound can't be null in the same step adjustment. +type StepAdjustment struct { + // The lower bound for the difference between the alarm threshold and the CloudWatch + // metric. If the metric value is above the breach threshold, the lower bound + // is inclusive (the metric must be greater than or equal to the threshold plus + // the lower bound). Otherwise, it is exclusive (the metric must be greater + // than the threshold plus the lower bound). A null value indicates negative + // infinity. + MetricIntervalLowerBound *float64 `type:"double"` + + // The upper bound for the difference between the alarm threshold and the CloudWatch + // metric. If the metric value is above the breach threshold, the upper bound + // is exclusive (the metric must be less than the threshold plus the upper bound). + // Otherwise, it is inclusive (the metric must be less than or equal to the + // threshold plus the upper bound). A null value indicates positive infinity. + // + // The upper bound must be greater than the lower bound. + MetricIntervalUpperBound *float64 `type:"double"` + + // The amount by which to scale, based on the specified adjustment type. A positive + // value adds to the current capacity while a negative number removes from the + // current capacity. + ScalingAdjustment *int64 `type:"integer" required:"true"` + + metadataStepAdjustment `json:"-" xml:"-"` +} + +type metadataStepAdjustment struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s StepAdjustment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StepAdjustment) GoString() string { + return s.String() +} + type SuspendProcessesOutput struct { metadataSuspendProcessesOutput `json:"-" xml:"-"` } @@ -3982,14 +5147,24 @@ type metadataSuspendProcessesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SuspendProcessesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SuspendProcessesOutput) GoString() string { + return s.String() +} + // Describes an Auto Scaling process that has been suspended. For more information, // see ProcessType. type SuspendedProcess struct { // The name of the suspended process. - ProcessName *string `type:"string"` + ProcessName *string `min:"1" type:"string"` // The reason that the process was suspended. - SuspensionReason *string `type:"string"` + SuspensionReason *string `min:"1" type:"string"` metadataSuspendedProcess `json:"-" xml:"-"` } @@ -3998,21 +5173,29 @@ type metadataSuspendedProcess struct { SDKShapeTraits bool `type:"structure"` } -// Describes a tag applied to an Auto Scaling group. +// String returns the string representation +func (s SuspendedProcess) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SuspendedProcess) GoString() string { + return s.String() +} + +// Describes a tag for an Auto Scaling group. type Tag struct { // The tag key. - Key *string `type:"string" required:"true"` + Key *string `min:"1" type:"string" required:"true"` - // Specifies whether the tag is applied to instances launched after the tag - // is created. The same behavior applies to updates: If you change a tag, it - // is applied to all instances launched after you made the change. + // Determines whether the tag is added to new instances as they are launched + // in the group. PropagateAtLaunch *bool `type:"boolean"` // The name of the group. - ResourceID *string `locationName:"ResourceId" type:"string"` + ResourceId *string `type:"string"` - // The kind of resource to which the tag is applied. Currently, Auto Scaling - // supports the auto-scaling-group resource type. + // The type of resource. The only supported value is auto-scaling-group. ResourceType *string `type:"string"` // The tag value. @@ -4025,21 +5208,29 @@ type metadataTag struct { SDKShapeTraits bool `type:"structure"` } -// Describes a tag applied to an Auto Scaling group. +// String returns the string representation +func (s Tag) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Tag) GoString() string { + return s.String() +} + +// Describes a tag for an Auto Scaling group. type TagDescription struct { // The tag key. - Key *string `type:"string"` + Key *string `min:"1" type:"string"` - // Specifies whether the tag is applied to instances launched after the tag - // is created. The same behavior applies to updates: If you change a tag, it - // is applied to all instances launched after you made the change. + // Determines whether the tag is added to new instances as they are launched + // in the group. PropagateAtLaunch *bool `type:"boolean"` // The name of the group. - ResourceID *string `locationName:"ResourceId" type:"string"` + ResourceId *string `type:"string"` - // The kind of resource to which the tag is applied. Currently, Auto Scaling - // supports the auto-scaling-group resource type. + // The type of resource. The only supported value is auto-scaling-group. ResourceType *string `type:"string"` // The tag value. @@ -4052,9 +5243,19 @@ type metadataTagDescription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s TagDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagDescription) GoString() string { + return s.String() +} + type TerminateInstanceInAutoScalingGroupInput struct { // The ID of the EC2 instance. - InstanceID *string `locationName:"InstanceId" type:"string" required:"true"` + InstanceId *string `min:"1" type:"string" required:"true"` // If true, terminating this instance also decrements the size of the Auto Scaling // group. @@ -4067,6 +5268,16 @@ type metadataTerminateInstanceInAutoScalingGroupInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s TerminateInstanceInAutoScalingGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TerminateInstanceInAutoScalingGroupInput) GoString() string { + return s.String() +} + type TerminateInstanceInAutoScalingGroupOutput struct { // A scaling activity. Activity *Activity `type:"structure"` @@ -4078,12 +5289,22 @@ type metadataTerminateInstanceInAutoScalingGroupOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s TerminateInstanceInAutoScalingGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TerminateInstanceInAutoScalingGroupOutput) GoString() string { + return s.String() +} + type UpdateAutoScalingGroupInput struct { // The name of the Auto Scaling group. - AutoScalingGroupName *string `type:"string" required:"true"` + AutoScalingGroupName *string `min:"1" type:"string" required:"true"` // One or more Availability Zones for the group. - AvailabilityZones []*string `type:"list"` + AvailabilityZones []*string `min:"1" type:"list"` // The amount of time, in seconds, after a scaling activity completes before // another scaling activity can start. For more information, see Understanding @@ -4091,23 +5312,23 @@ type UpdateAutoScalingGroupInput struct { DefaultCooldown *int64 `type:"integer"` // The number of EC2 instances that should be running in the Auto Scaling group. - // This value must be greater than or equal to the minimum size of the group + // This number must be greater than or equal to the minimum size of the group // and less than or equal to the maximum size of the group. DesiredCapacity *int64 `type:"integer"` - // The amount of time, in second, that Auto Scaling waits before checking the + // The amount of time, in seconds, that Auto Scaling waits before checking the // health status of an instance. The grace period begins when the instance passes - // System Status and the Instance Status checks from Amazon EC2. For more information, - // see DescribeInstanceStatus (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstanceStatus.html). + // the system status and instance status checks from Amazon EC2. For more information, + // see . HealthCheckGracePeriod *int64 `type:"integer"` // The type of health check for the instances in the Auto Scaling group. The // health check type can either be EC2 for Amazon EC2 or ELB for Elastic Load // Balancing. - HealthCheckType *string `type:"string"` + HealthCheckType *string `min:"1" type:"string"` // The name of the launch configuration. - LaunchConfigurationName *string `type:"string"` + LaunchConfigurationName *string `min:"1" type:"string"` // The maximum size of the Auto Scaling group. MaxSize *int64 `type:"integer"` @@ -4117,7 +5338,7 @@ type UpdateAutoScalingGroupInput struct { // The name of the placement group into which you'll launch your instances, // if any. For more information, see Placement Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html). - PlacementGroup *string `type:"string"` + PlacementGroup *string `min:"1" type:"string"` // A standalone termination policy or a list of termination policies used to // select the instance to terminate. The policies are executed in the order @@ -4128,15 +5349,16 @@ type UpdateAutoScalingGroupInput struct { // in the Auto Scaling Developer Guide. TerminationPolicies []*string `type:"list"` - // The subnet identifier for the Amazon VPC connection, if applicable. You can - // specify several subnets in a comma-separated list. + // The ID of the subnet, if you are launching into a VPC. You can specify several + // subnets in a comma-separated list. // - // When you specify VPCZoneIdentifier with AvailabilityZones, ensure that - // the subnets' Availability Zones match the values you specify for AvailabilityZones. + // When you specify VPCZoneIdentifier with AvailabilityZones, ensure that the + // subnets' Availability Zones match the values you specify for AvailabilityZones. // - // For more information, see Auto Scaling and Amazon VPC (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/autoscalingsubnets.html) + // For more information, see Auto Scaling and Amazon Virtual Private Cloud + // (http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/autoscalingsubnets.html) // in the Auto Scaling Developer Guide. - VPCZoneIdentifier *string `type:"string"` + VPCZoneIdentifier *string `min:"1" type:"string"` metadataUpdateAutoScalingGroupInput `json:"-" xml:"-"` } @@ -4145,6 +5367,16 @@ type metadataUpdateAutoScalingGroupInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s UpdateAutoScalingGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateAutoScalingGroupInput) GoString() string { + return s.String() +} + type UpdateAutoScalingGroupOutput struct { metadataUpdateAutoScalingGroupOutput `json:"-" xml:"-"` } @@ -4152,3 +5384,67 @@ type UpdateAutoScalingGroupOutput struct { type metadataUpdateAutoScalingGroupOutput struct { SDKShapeTraits bool `type:"structure"` } + +// String returns the string representation +func (s UpdateAutoScalingGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateAutoScalingGroupOutput) GoString() string { + return s.String() +} + +const ( + // @enum LifecycleState + LifecycleStatePending = "Pending" + // @enum LifecycleState + LifecycleStatePendingWait = "Pending:Wait" + // @enum LifecycleState + LifecycleStatePendingProceed = "Pending:Proceed" + // @enum LifecycleState + LifecycleStateQuarantined = "Quarantined" + // @enum LifecycleState + LifecycleStateInService = "InService" + // @enum LifecycleState + LifecycleStateTerminating = "Terminating" + // @enum LifecycleState + LifecycleStateTerminatingWait = "Terminating:Wait" + // @enum LifecycleState + LifecycleStateTerminatingProceed = "Terminating:Proceed" + // @enum LifecycleState + LifecycleStateTerminated = "Terminated" + // @enum LifecycleState + LifecycleStateDetaching = "Detaching" + // @enum LifecycleState + LifecycleStateDetached = "Detached" + // @enum LifecycleState + LifecycleStateEnteringStandby = "EnteringStandby" + // @enum LifecycleState + LifecycleStateStandby = "Standby" +) + +const ( + // @enum ScalingActivityStatusCode + ScalingActivityStatusCodeWaitingForSpotInstanceRequestId = "WaitingForSpotInstanceRequestId" + // @enum ScalingActivityStatusCode + ScalingActivityStatusCodeWaitingForSpotInstanceId = "WaitingForSpotInstanceId" + // @enum ScalingActivityStatusCode + ScalingActivityStatusCodeWaitingForInstanceId = "WaitingForInstanceId" + // @enum ScalingActivityStatusCode + ScalingActivityStatusCodePreInService = "PreInService" + // @enum ScalingActivityStatusCode + ScalingActivityStatusCodeInProgress = "InProgress" + // @enum ScalingActivityStatusCode + ScalingActivityStatusCodeWaitingForElbconnectionDraining = "WaitingForELBConnectionDraining" + // @enum ScalingActivityStatusCode + ScalingActivityStatusCodeMidLifecycleAction = "MidLifecycleAction" + // @enum ScalingActivityStatusCode + ScalingActivityStatusCodeWaitingForInstanceWarmup = "WaitingForInstanceWarmup" + // @enum ScalingActivityStatusCode + ScalingActivityStatusCodeSuccessful = "Successful" + // @enum ScalingActivityStatusCode + ScalingActivityStatusCodeFailed = "Failed" + // @enum ScalingActivityStatusCode + ScalingActivityStatusCodeCancelled = "Cancelled" +) diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface/interface.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface/interface.go index ab28228467f0..2de4f9e7e7f4 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface/interface.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface/interface.go @@ -4,98 +4,217 @@ package autoscalingiface import ( + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/service/autoscaling" ) // AutoScalingAPI is the interface type for autoscaling.AutoScaling. type AutoScalingAPI interface { + AttachInstancesRequest(*autoscaling.AttachInstancesInput) (*request.Request, *autoscaling.AttachInstancesOutput) + AttachInstances(*autoscaling.AttachInstancesInput) (*autoscaling.AttachInstancesOutput, error) + AttachLoadBalancersRequest(*autoscaling.AttachLoadBalancersInput) (*request.Request, *autoscaling.AttachLoadBalancersOutput) + + AttachLoadBalancers(*autoscaling.AttachLoadBalancersInput) (*autoscaling.AttachLoadBalancersOutput, error) + + CompleteLifecycleActionRequest(*autoscaling.CompleteLifecycleActionInput) (*request.Request, *autoscaling.CompleteLifecycleActionOutput) + CompleteLifecycleAction(*autoscaling.CompleteLifecycleActionInput) (*autoscaling.CompleteLifecycleActionOutput, error) + CreateAutoScalingGroupRequest(*autoscaling.CreateAutoScalingGroupInput) (*request.Request, *autoscaling.CreateAutoScalingGroupOutput) + CreateAutoScalingGroup(*autoscaling.CreateAutoScalingGroupInput) (*autoscaling.CreateAutoScalingGroupOutput, error) + CreateLaunchConfigurationRequest(*autoscaling.CreateLaunchConfigurationInput) (*request.Request, *autoscaling.CreateLaunchConfigurationOutput) + CreateLaunchConfiguration(*autoscaling.CreateLaunchConfigurationInput) (*autoscaling.CreateLaunchConfigurationOutput, error) + CreateOrUpdateTagsRequest(*autoscaling.CreateOrUpdateTagsInput) (*request.Request, *autoscaling.CreateOrUpdateTagsOutput) + CreateOrUpdateTags(*autoscaling.CreateOrUpdateTagsInput) (*autoscaling.CreateOrUpdateTagsOutput, error) + DeleteAutoScalingGroupRequest(*autoscaling.DeleteAutoScalingGroupInput) (*request.Request, *autoscaling.DeleteAutoScalingGroupOutput) + DeleteAutoScalingGroup(*autoscaling.DeleteAutoScalingGroupInput) (*autoscaling.DeleteAutoScalingGroupOutput, error) + DeleteLaunchConfigurationRequest(*autoscaling.DeleteLaunchConfigurationInput) (*request.Request, *autoscaling.DeleteLaunchConfigurationOutput) + DeleteLaunchConfiguration(*autoscaling.DeleteLaunchConfigurationInput) (*autoscaling.DeleteLaunchConfigurationOutput, error) + DeleteLifecycleHookRequest(*autoscaling.DeleteLifecycleHookInput) (*request.Request, *autoscaling.DeleteLifecycleHookOutput) + DeleteLifecycleHook(*autoscaling.DeleteLifecycleHookInput) (*autoscaling.DeleteLifecycleHookOutput, error) + DeleteNotificationConfigurationRequest(*autoscaling.DeleteNotificationConfigurationInput) (*request.Request, *autoscaling.DeleteNotificationConfigurationOutput) + DeleteNotificationConfiguration(*autoscaling.DeleteNotificationConfigurationInput) (*autoscaling.DeleteNotificationConfigurationOutput, error) + DeletePolicyRequest(*autoscaling.DeletePolicyInput) (*request.Request, *autoscaling.DeletePolicyOutput) + DeletePolicy(*autoscaling.DeletePolicyInput) (*autoscaling.DeletePolicyOutput, error) + DeleteScheduledActionRequest(*autoscaling.DeleteScheduledActionInput) (*request.Request, *autoscaling.DeleteScheduledActionOutput) + DeleteScheduledAction(*autoscaling.DeleteScheduledActionInput) (*autoscaling.DeleteScheduledActionOutput, error) + DeleteTagsRequest(*autoscaling.DeleteTagsInput) (*request.Request, *autoscaling.DeleteTagsOutput) + DeleteTags(*autoscaling.DeleteTagsInput) (*autoscaling.DeleteTagsOutput, error) + DescribeAccountLimitsRequest(*autoscaling.DescribeAccountLimitsInput) (*request.Request, *autoscaling.DescribeAccountLimitsOutput) + DescribeAccountLimits(*autoscaling.DescribeAccountLimitsInput) (*autoscaling.DescribeAccountLimitsOutput, error) + DescribeAdjustmentTypesRequest(*autoscaling.DescribeAdjustmentTypesInput) (*request.Request, *autoscaling.DescribeAdjustmentTypesOutput) + DescribeAdjustmentTypes(*autoscaling.DescribeAdjustmentTypesInput) (*autoscaling.DescribeAdjustmentTypesOutput, error) + DescribeAutoScalingGroupsRequest(*autoscaling.DescribeAutoScalingGroupsInput) (*request.Request, *autoscaling.DescribeAutoScalingGroupsOutput) + DescribeAutoScalingGroups(*autoscaling.DescribeAutoScalingGroupsInput) (*autoscaling.DescribeAutoScalingGroupsOutput, error) + DescribeAutoScalingGroupsPages(*autoscaling.DescribeAutoScalingGroupsInput, func(*autoscaling.DescribeAutoScalingGroupsOutput, bool) bool) error + + DescribeAutoScalingInstancesRequest(*autoscaling.DescribeAutoScalingInstancesInput) (*request.Request, *autoscaling.DescribeAutoScalingInstancesOutput) + DescribeAutoScalingInstances(*autoscaling.DescribeAutoScalingInstancesInput) (*autoscaling.DescribeAutoScalingInstancesOutput, error) + DescribeAutoScalingInstancesPages(*autoscaling.DescribeAutoScalingInstancesInput, func(*autoscaling.DescribeAutoScalingInstancesOutput, bool) bool) error + + DescribeAutoScalingNotificationTypesRequest(*autoscaling.DescribeAutoScalingNotificationTypesInput) (*request.Request, *autoscaling.DescribeAutoScalingNotificationTypesOutput) + DescribeAutoScalingNotificationTypes(*autoscaling.DescribeAutoScalingNotificationTypesInput) (*autoscaling.DescribeAutoScalingNotificationTypesOutput, error) + DescribeLaunchConfigurationsRequest(*autoscaling.DescribeLaunchConfigurationsInput) (*request.Request, *autoscaling.DescribeLaunchConfigurationsOutput) + DescribeLaunchConfigurations(*autoscaling.DescribeLaunchConfigurationsInput) (*autoscaling.DescribeLaunchConfigurationsOutput, error) + DescribeLaunchConfigurationsPages(*autoscaling.DescribeLaunchConfigurationsInput, func(*autoscaling.DescribeLaunchConfigurationsOutput, bool) bool) error + + DescribeLifecycleHookTypesRequest(*autoscaling.DescribeLifecycleHookTypesInput) (*request.Request, *autoscaling.DescribeLifecycleHookTypesOutput) + DescribeLifecycleHookTypes(*autoscaling.DescribeLifecycleHookTypesInput) (*autoscaling.DescribeLifecycleHookTypesOutput, error) + DescribeLifecycleHooksRequest(*autoscaling.DescribeLifecycleHooksInput) (*request.Request, *autoscaling.DescribeLifecycleHooksOutput) + DescribeLifecycleHooks(*autoscaling.DescribeLifecycleHooksInput) (*autoscaling.DescribeLifecycleHooksOutput, error) + DescribeLoadBalancersRequest(*autoscaling.DescribeLoadBalancersInput) (*request.Request, *autoscaling.DescribeLoadBalancersOutput) + + DescribeLoadBalancers(*autoscaling.DescribeLoadBalancersInput) (*autoscaling.DescribeLoadBalancersOutput, error) + + DescribeMetricCollectionTypesRequest(*autoscaling.DescribeMetricCollectionTypesInput) (*request.Request, *autoscaling.DescribeMetricCollectionTypesOutput) + DescribeMetricCollectionTypes(*autoscaling.DescribeMetricCollectionTypesInput) (*autoscaling.DescribeMetricCollectionTypesOutput, error) + DescribeNotificationConfigurationsRequest(*autoscaling.DescribeNotificationConfigurationsInput) (*request.Request, *autoscaling.DescribeNotificationConfigurationsOutput) + DescribeNotificationConfigurations(*autoscaling.DescribeNotificationConfigurationsInput) (*autoscaling.DescribeNotificationConfigurationsOutput, error) + DescribeNotificationConfigurationsPages(*autoscaling.DescribeNotificationConfigurationsInput, func(*autoscaling.DescribeNotificationConfigurationsOutput, bool) bool) error + + DescribePoliciesRequest(*autoscaling.DescribePoliciesInput) (*request.Request, *autoscaling.DescribePoliciesOutput) + DescribePolicies(*autoscaling.DescribePoliciesInput) (*autoscaling.DescribePoliciesOutput, error) + DescribePoliciesPages(*autoscaling.DescribePoliciesInput, func(*autoscaling.DescribePoliciesOutput, bool) bool) error + + DescribeScalingActivitiesRequest(*autoscaling.DescribeScalingActivitiesInput) (*request.Request, *autoscaling.DescribeScalingActivitiesOutput) + DescribeScalingActivities(*autoscaling.DescribeScalingActivitiesInput) (*autoscaling.DescribeScalingActivitiesOutput, error) + DescribeScalingActivitiesPages(*autoscaling.DescribeScalingActivitiesInput, func(*autoscaling.DescribeScalingActivitiesOutput, bool) bool) error + + DescribeScalingProcessTypesRequest(*autoscaling.DescribeScalingProcessTypesInput) (*request.Request, *autoscaling.DescribeScalingProcessTypesOutput) + DescribeScalingProcessTypes(*autoscaling.DescribeScalingProcessTypesInput) (*autoscaling.DescribeScalingProcessTypesOutput, error) + DescribeScheduledActionsRequest(*autoscaling.DescribeScheduledActionsInput) (*request.Request, *autoscaling.DescribeScheduledActionsOutput) + DescribeScheduledActions(*autoscaling.DescribeScheduledActionsInput) (*autoscaling.DescribeScheduledActionsOutput, error) + DescribeScheduledActionsPages(*autoscaling.DescribeScheduledActionsInput, func(*autoscaling.DescribeScheduledActionsOutput, bool) bool) error + + DescribeTagsRequest(*autoscaling.DescribeTagsInput) (*request.Request, *autoscaling.DescribeTagsOutput) + DescribeTags(*autoscaling.DescribeTagsInput) (*autoscaling.DescribeTagsOutput, error) + DescribeTagsPages(*autoscaling.DescribeTagsInput, func(*autoscaling.DescribeTagsOutput, bool) bool) error + + DescribeTerminationPolicyTypesRequest(*autoscaling.DescribeTerminationPolicyTypesInput) (*request.Request, *autoscaling.DescribeTerminationPolicyTypesOutput) + DescribeTerminationPolicyTypes(*autoscaling.DescribeTerminationPolicyTypesInput) (*autoscaling.DescribeTerminationPolicyTypesOutput, error) + DetachInstancesRequest(*autoscaling.DetachInstancesInput) (*request.Request, *autoscaling.DetachInstancesOutput) + DetachInstances(*autoscaling.DetachInstancesInput) (*autoscaling.DetachInstancesOutput, error) + DetachLoadBalancersRequest(*autoscaling.DetachLoadBalancersInput) (*request.Request, *autoscaling.DetachLoadBalancersOutput) + + DetachLoadBalancers(*autoscaling.DetachLoadBalancersInput) (*autoscaling.DetachLoadBalancersOutput, error) + + DisableMetricsCollectionRequest(*autoscaling.DisableMetricsCollectionInput) (*request.Request, *autoscaling.DisableMetricsCollectionOutput) + DisableMetricsCollection(*autoscaling.DisableMetricsCollectionInput) (*autoscaling.DisableMetricsCollectionOutput, error) + EnableMetricsCollectionRequest(*autoscaling.EnableMetricsCollectionInput) (*request.Request, *autoscaling.EnableMetricsCollectionOutput) + EnableMetricsCollection(*autoscaling.EnableMetricsCollectionInput) (*autoscaling.EnableMetricsCollectionOutput, error) + EnterStandbyRequest(*autoscaling.EnterStandbyInput) (*request.Request, *autoscaling.EnterStandbyOutput) + EnterStandby(*autoscaling.EnterStandbyInput) (*autoscaling.EnterStandbyOutput, error) + ExecutePolicyRequest(*autoscaling.ExecutePolicyInput) (*request.Request, *autoscaling.ExecutePolicyOutput) + ExecutePolicy(*autoscaling.ExecutePolicyInput) (*autoscaling.ExecutePolicyOutput, error) + ExitStandbyRequest(*autoscaling.ExitStandbyInput) (*request.Request, *autoscaling.ExitStandbyOutput) + ExitStandby(*autoscaling.ExitStandbyInput) (*autoscaling.ExitStandbyOutput, error) + PutLifecycleHookRequest(*autoscaling.PutLifecycleHookInput) (*request.Request, *autoscaling.PutLifecycleHookOutput) + PutLifecycleHook(*autoscaling.PutLifecycleHookInput) (*autoscaling.PutLifecycleHookOutput, error) + PutNotificationConfigurationRequest(*autoscaling.PutNotificationConfigurationInput) (*request.Request, *autoscaling.PutNotificationConfigurationOutput) + PutNotificationConfiguration(*autoscaling.PutNotificationConfigurationInput) (*autoscaling.PutNotificationConfigurationOutput, error) + PutScalingPolicyRequest(*autoscaling.PutScalingPolicyInput) (*request.Request, *autoscaling.PutScalingPolicyOutput) + PutScalingPolicy(*autoscaling.PutScalingPolicyInput) (*autoscaling.PutScalingPolicyOutput, error) + PutScheduledUpdateGroupActionRequest(*autoscaling.PutScheduledUpdateGroupActionInput) (*request.Request, *autoscaling.PutScheduledUpdateGroupActionOutput) + PutScheduledUpdateGroupAction(*autoscaling.PutScheduledUpdateGroupActionInput) (*autoscaling.PutScheduledUpdateGroupActionOutput, error) + RecordLifecycleActionHeartbeatRequest(*autoscaling.RecordLifecycleActionHeartbeatInput) (*request.Request, *autoscaling.RecordLifecycleActionHeartbeatOutput) + RecordLifecycleActionHeartbeat(*autoscaling.RecordLifecycleActionHeartbeatInput) (*autoscaling.RecordLifecycleActionHeartbeatOutput, error) + ResumeProcessesRequest(*autoscaling.ScalingProcessQuery) (*request.Request, *autoscaling.ResumeProcessesOutput) + ResumeProcesses(*autoscaling.ScalingProcessQuery) (*autoscaling.ResumeProcessesOutput, error) + SetDesiredCapacityRequest(*autoscaling.SetDesiredCapacityInput) (*request.Request, *autoscaling.SetDesiredCapacityOutput) + SetDesiredCapacity(*autoscaling.SetDesiredCapacityInput) (*autoscaling.SetDesiredCapacityOutput, error) + SetInstanceHealthRequest(*autoscaling.SetInstanceHealthInput) (*request.Request, *autoscaling.SetInstanceHealthOutput) + SetInstanceHealth(*autoscaling.SetInstanceHealthInput) (*autoscaling.SetInstanceHealthOutput, error) + SuspendProcessesRequest(*autoscaling.ScalingProcessQuery) (*request.Request, *autoscaling.SuspendProcessesOutput) + SuspendProcesses(*autoscaling.ScalingProcessQuery) (*autoscaling.SuspendProcessesOutput, error) + TerminateInstanceInAutoScalingGroupRequest(*autoscaling.TerminateInstanceInAutoScalingGroupInput) (*request.Request, *autoscaling.TerminateInstanceInAutoScalingGroupOutput) + TerminateInstanceInAutoScalingGroup(*autoscaling.TerminateInstanceInAutoScalingGroupInput) (*autoscaling.TerminateInstanceInAutoScalingGroupOutput, error) + UpdateAutoScalingGroupRequest(*autoscaling.UpdateAutoScalingGroupInput) (*request.Request, *autoscaling.UpdateAutoScalingGroupOutput) + UpdateAutoScalingGroup(*autoscaling.UpdateAutoScalingGroupInput) (*autoscaling.UpdateAutoScalingGroupOutput, error) } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/examples_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/examples_test.go index c9c2f5a7889c..bdcac9be04f6 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/examples_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/examples_test.go @@ -8,8 +8,6 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/autoscaling" ) @@ -21,7 +19,7 @@ func ExampleAutoScaling_AttachInstances() { params := &autoscaling.AttachInstancesInput{ AutoScalingGroupName: aws.String("ResourceName"), // Required - InstanceIDs: []*string{ + InstanceIds: []*string{ aws.String("XmlStringMaxLen16"), // Required // More values... }, @@ -29,22 +27,37 @@ func ExampleAutoScaling_AttachInstances() { resp, err := svc.AttachInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) +} + +func ExampleAutoScaling_AttachLoadBalancers() { + svc := autoscaling.New(nil) + + params := &autoscaling.AttachLoadBalancersInput{ + AutoScalingGroupName: aws.String("ResourceName"), + LoadBalancerNames: []*string{ + aws.String("XmlStringMaxLen255"), // Required + // More values... + }, + } + resp, err := svc.AttachLoadBalancers(params) + + if err != nil { + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return + } + + // Pretty-print the response data. + fmt.Println(resp) } func ExampleAutoScaling_CompleteLifecycleAction() { @@ -59,22 +72,14 @@ func ExampleAutoScaling_CompleteLifecycleAction() { resp, err := svc.CompleteLifecycleAction(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_CreateAutoScalingGroup() { @@ -82,17 +87,17 @@ func ExampleAutoScaling_CreateAutoScalingGroup() { params := &autoscaling.CreateAutoScalingGroupInput{ AutoScalingGroupName: aws.String("XmlStringMaxLen255"), // Required - MaxSize: aws.Long(1), // Required - MinSize: aws.Long(1), // Required + MaxSize: aws.Int64(1), // Required + MinSize: aws.Int64(1), // Required AvailabilityZones: []*string{ aws.String("XmlStringMaxLen255"), // Required // More values... }, - DefaultCooldown: aws.Long(1), - DesiredCapacity: aws.Long(1), - HealthCheckGracePeriod: aws.Long(1), + DefaultCooldown: aws.Int64(1), + DesiredCapacity: aws.Int64(1), + HealthCheckGracePeriod: aws.Int64(1), HealthCheckType: aws.String("XmlStringMaxLen32"), - InstanceID: aws.String("XmlStringMaxLen16"), + InstanceId: aws.String("XmlStringMaxLen16"), LaunchConfigurationName: aws.String("ResourceName"), LoadBalancerNames: []*string{ aws.String("XmlStringMaxLen255"), // Required @@ -100,10 +105,10 @@ func ExampleAutoScaling_CreateAutoScalingGroup() { }, PlacementGroup: aws.String("XmlStringMaxLen255"), Tags: []*autoscaling.Tag{ - &autoscaling.Tag{ // Required + { // Required Key: aws.String("TagKey"), // Required - PropagateAtLaunch: aws.Boolean(true), - ResourceID: aws.String("XmlString"), + PropagateAtLaunch: aws.Bool(true), + ResourceId: aws.String("XmlString"), ResourceType: aws.String("XmlString"), Value: aws.String("TagValue"), }, @@ -118,22 +123,14 @@ func ExampleAutoScaling_CreateAutoScalingGroup() { resp, err := svc.CreateAutoScalingGroup(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_CreateLaunchConfiguration() { @@ -141,39 +138,39 @@ func ExampleAutoScaling_CreateLaunchConfiguration() { params := &autoscaling.CreateLaunchConfigurationInput{ LaunchConfigurationName: aws.String("XmlStringMaxLen255"), // Required - AssociatePublicIPAddress: aws.Boolean(true), + AssociatePublicIpAddress: aws.Bool(true), BlockDeviceMappings: []*autoscaling.BlockDeviceMapping{ - &autoscaling.BlockDeviceMapping{ // Required + { // Required DeviceName: aws.String("XmlStringMaxLen255"), // Required - EBS: &autoscaling.EBS{ - DeleteOnTermination: aws.Boolean(true), - IOPS: aws.Long(1), - SnapshotID: aws.String("XmlStringMaxLen255"), - VolumeSize: aws.Long(1), + Ebs: &autoscaling.Ebs{ + DeleteOnTermination: aws.Bool(true), + Iops: aws.Int64(1), + SnapshotId: aws.String("XmlStringMaxLen255"), + VolumeSize: aws.Int64(1), VolumeType: aws.String("BlockDeviceEbsVolumeType"), }, - NoDevice: aws.Boolean(true), + NoDevice: aws.Bool(true), VirtualName: aws.String("XmlStringMaxLen255"), }, // More values... }, - ClassicLinkVPCID: aws.String("XmlStringMaxLen255"), + ClassicLinkVPCId: aws.String("XmlStringMaxLen255"), ClassicLinkVPCSecurityGroups: []*string{ aws.String("XmlStringMaxLen255"), // Required // More values... }, - EBSOptimized: aws.Boolean(true), - IAMInstanceProfile: aws.String("XmlStringMaxLen1600"), - ImageID: aws.String("XmlStringMaxLen255"), - InstanceID: aws.String("XmlStringMaxLen16"), + EbsOptimized: aws.Bool(true), + IamInstanceProfile: aws.String("XmlStringMaxLen1600"), + ImageId: aws.String("XmlStringMaxLen255"), + InstanceId: aws.String("XmlStringMaxLen16"), InstanceMonitoring: &autoscaling.InstanceMonitoring{ - Enabled: aws.Boolean(true), + Enabled: aws.Bool(true), }, InstanceType: aws.String("XmlStringMaxLen255"), - KernelID: aws.String("XmlStringMaxLen255"), + KernelId: aws.String("XmlStringMaxLen255"), KeyName: aws.String("XmlStringMaxLen255"), PlacementTenancy: aws.String("XmlStringMaxLen64"), - RAMDiskID: aws.String("XmlStringMaxLen255"), + RamdiskId: aws.String("XmlStringMaxLen255"), SecurityGroups: []*string{ aws.String("XmlString"), // Required // More values... @@ -184,22 +181,14 @@ func ExampleAutoScaling_CreateLaunchConfiguration() { resp, err := svc.CreateLaunchConfiguration(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_CreateOrUpdateTags() { @@ -207,10 +196,10 @@ func ExampleAutoScaling_CreateOrUpdateTags() { params := &autoscaling.CreateOrUpdateTagsInput{ Tags: []*autoscaling.Tag{ // Required - &autoscaling.Tag{ // Required + { // Required Key: aws.String("TagKey"), // Required - PropagateAtLaunch: aws.Boolean(true), - ResourceID: aws.String("XmlString"), + PropagateAtLaunch: aws.Bool(true), + ResourceId: aws.String("XmlString"), ResourceType: aws.String("XmlString"), Value: aws.String("TagValue"), }, @@ -220,22 +209,14 @@ func ExampleAutoScaling_CreateOrUpdateTags() { resp, err := svc.CreateOrUpdateTags(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DeleteAutoScalingGroup() { @@ -243,27 +224,19 @@ func ExampleAutoScaling_DeleteAutoScalingGroup() { params := &autoscaling.DeleteAutoScalingGroupInput{ AutoScalingGroupName: aws.String("ResourceName"), // Required - ForceDelete: aws.Boolean(true), + ForceDelete: aws.Bool(true), } resp, err := svc.DeleteAutoScalingGroup(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DeleteLaunchConfiguration() { @@ -275,22 +248,14 @@ func ExampleAutoScaling_DeleteLaunchConfiguration() { resp, err := svc.DeleteLaunchConfiguration(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DeleteLifecycleHook() { @@ -303,22 +268,14 @@ func ExampleAutoScaling_DeleteLifecycleHook() { resp, err := svc.DeleteLifecycleHook(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DeleteNotificationConfiguration() { @@ -331,22 +288,14 @@ func ExampleAutoScaling_DeleteNotificationConfiguration() { resp, err := svc.DeleteNotificationConfiguration(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DeletePolicy() { @@ -359,22 +308,14 @@ func ExampleAutoScaling_DeletePolicy() { resp, err := svc.DeletePolicy(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DeleteScheduledAction() { @@ -387,22 +328,14 @@ func ExampleAutoScaling_DeleteScheduledAction() { resp, err := svc.DeleteScheduledAction(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DeleteTags() { @@ -410,10 +343,10 @@ func ExampleAutoScaling_DeleteTags() { params := &autoscaling.DeleteTagsInput{ Tags: []*autoscaling.Tag{ // Required - &autoscaling.Tag{ // Required + { // Required Key: aws.String("TagKey"), // Required - PropagateAtLaunch: aws.Boolean(true), - ResourceID: aws.String("XmlString"), + PropagateAtLaunch: aws.Bool(true), + ResourceId: aws.String("XmlString"), ResourceType: aws.String("XmlString"), Value: aws.String("TagValue"), }, @@ -423,22 +356,14 @@ func ExampleAutoScaling_DeleteTags() { resp, err := svc.DeleteTags(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeAccountLimits() { @@ -448,22 +373,14 @@ func ExampleAutoScaling_DescribeAccountLimits() { resp, err := svc.DescribeAccountLimits(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeAdjustmentTypes() { @@ -473,22 +390,14 @@ func ExampleAutoScaling_DescribeAdjustmentTypes() { resp, err := svc.DescribeAdjustmentTypes(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeAutoScalingGroups() { @@ -499,60 +408,44 @@ func ExampleAutoScaling_DescribeAutoScalingGroups() { aws.String("ResourceName"), // Required // More values... }, - MaxRecords: aws.Long(1), + MaxRecords: aws.Int64(1), NextToken: aws.String("XmlString"), } resp, err := svc.DescribeAutoScalingGroups(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeAutoScalingInstances() { svc := autoscaling.New(nil) params := &autoscaling.DescribeAutoScalingInstancesInput{ - InstanceIDs: []*string{ + InstanceIds: []*string{ aws.String("XmlStringMaxLen16"), // Required // More values... }, - MaxRecords: aws.Long(1), + MaxRecords: aws.Int64(1), NextToken: aws.String("XmlString"), } resp, err := svc.DescribeAutoScalingInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeAutoScalingNotificationTypes() { @@ -562,22 +455,14 @@ func ExampleAutoScaling_DescribeAutoScalingNotificationTypes() { resp, err := svc.DescribeAutoScalingNotificationTypes(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeLaunchConfigurations() { @@ -588,28 +473,20 @@ func ExampleAutoScaling_DescribeLaunchConfigurations() { aws.String("ResourceName"), // Required // More values... }, - MaxRecords: aws.Long(1), + MaxRecords: aws.Int64(1), NextToken: aws.String("XmlString"), } resp, err := svc.DescribeLaunchConfigurations(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeLifecycleHookTypes() { @@ -619,22 +496,14 @@ func ExampleAutoScaling_DescribeLifecycleHookTypes() { resp, err := svc.DescribeLifecycleHookTypes(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeLifecycleHooks() { @@ -650,22 +519,35 @@ func ExampleAutoScaling_DescribeLifecycleHooks() { resp, err := svc.DescribeLifecycleHooks(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return + } + + // Pretty-print the response data. + fmt.Println(resp) +} + +func ExampleAutoScaling_DescribeLoadBalancers() { + svc := autoscaling.New(nil) + + params := &autoscaling.DescribeLoadBalancersInput{ + AutoScalingGroupName: aws.String("ResourceName"), // Required + MaxRecords: aws.Int64(1), + NextToken: aws.String("XmlString"), + } + resp, err := svc.DescribeLoadBalancers(params) + + if err != nil { + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeMetricCollectionTypes() { @@ -675,22 +557,14 @@ func ExampleAutoScaling_DescribeMetricCollectionTypes() { resp, err := svc.DescribeMetricCollectionTypes(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeNotificationConfigurations() { @@ -701,28 +575,20 @@ func ExampleAutoScaling_DescribeNotificationConfigurations() { aws.String("ResourceName"), // Required // More values... }, - MaxRecords: aws.Long(1), + MaxRecords: aws.Int64(1), NextToken: aws.String("XmlString"), } resp, err := svc.DescribeNotificationConfigurations(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribePolicies() { @@ -730,65 +596,53 @@ func ExampleAutoScaling_DescribePolicies() { params := &autoscaling.DescribePoliciesInput{ AutoScalingGroupName: aws.String("ResourceName"), - MaxRecords: aws.Long(1), + MaxRecords: aws.Int64(1), NextToken: aws.String("XmlString"), PolicyNames: []*string{ aws.String("ResourceName"), // Required // More values... }, + PolicyTypes: []*string{ + aws.String("XmlStringMaxLen64"), // Required + // More values... + }, } resp, err := svc.DescribePolicies(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeScalingActivities() { svc := autoscaling.New(nil) params := &autoscaling.DescribeScalingActivitiesInput{ - ActivityIDs: []*string{ + ActivityIds: []*string{ aws.String("XmlString"), // Required // More values... }, AutoScalingGroupName: aws.String("ResourceName"), - MaxRecords: aws.Long(1), + MaxRecords: aws.Int64(1), NextToken: aws.String("XmlString"), } resp, err := svc.DescribeScalingActivities(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeScalingProcessTypes() { @@ -798,22 +652,14 @@ func ExampleAutoScaling_DescribeScalingProcessTypes() { resp, err := svc.DescribeScalingProcessTypes(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeScheduledActions() { @@ -822,7 +668,7 @@ func ExampleAutoScaling_DescribeScheduledActions() { params := &autoscaling.DescribeScheduledActionsInput{ AutoScalingGroupName: aws.String("ResourceName"), EndTime: aws.Time(time.Now()), - MaxRecords: aws.Long(1), + MaxRecords: aws.Int64(1), NextToken: aws.String("XmlString"), ScheduledActionNames: []*string{ aws.String("ResourceName"), // Required @@ -833,22 +679,14 @@ func ExampleAutoScaling_DescribeScheduledActions() { resp, err := svc.DescribeScheduledActions(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeTags() { @@ -856,7 +694,7 @@ func ExampleAutoScaling_DescribeTags() { params := &autoscaling.DescribeTagsInput{ Filters: []*autoscaling.Filter{ - &autoscaling.Filter{ // Required + { // Required Name: aws.String("XmlString"), Values: []*string{ aws.String("XmlString"), // Required @@ -865,28 +703,20 @@ func ExampleAutoScaling_DescribeTags() { }, // More values... }, - MaxRecords: aws.Long(1), + MaxRecords: aws.Int64(1), NextToken: aws.String("XmlString"), } resp, err := svc.DescribeTags(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DescribeTerminationPolicyTypes() { @@ -896,22 +726,14 @@ func ExampleAutoScaling_DescribeTerminationPolicyTypes() { resp, err := svc.DescribeTerminationPolicyTypes(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DetachInstances() { @@ -919,8 +741,8 @@ func ExampleAutoScaling_DetachInstances() { params := &autoscaling.DetachInstancesInput{ AutoScalingGroupName: aws.String("ResourceName"), // Required - ShouldDecrementDesiredCapacity: aws.Boolean(true), // Required - InstanceIDs: []*string{ + ShouldDecrementDesiredCapacity: aws.Bool(true), // Required + InstanceIds: []*string{ aws.String("XmlStringMaxLen16"), // Required // More values... }, @@ -928,22 +750,37 @@ func ExampleAutoScaling_DetachInstances() { resp, err := svc.DetachInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return + } + + // Pretty-print the response data. + fmt.Println(resp) +} + +func ExampleAutoScaling_DetachLoadBalancers() { + svc := autoscaling.New(nil) + + params := &autoscaling.DetachLoadBalancersInput{ + AutoScalingGroupName: aws.String("ResourceName"), + LoadBalancerNames: []*string{ + aws.String("XmlStringMaxLen255"), // Required + // More values... + }, + } + resp, err := svc.DetachLoadBalancers(params) + + if err != nil { + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_DisableMetricsCollection() { @@ -959,22 +796,14 @@ func ExampleAutoScaling_DisableMetricsCollection() { resp, err := svc.DisableMetricsCollection(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_EnableMetricsCollection() { @@ -991,22 +820,14 @@ func ExampleAutoScaling_EnableMetricsCollection() { resp, err := svc.EnableMetricsCollection(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_EnterStandby() { @@ -1014,8 +835,8 @@ func ExampleAutoScaling_EnterStandby() { params := &autoscaling.EnterStandbyInput{ AutoScalingGroupName: aws.String("ResourceName"), // Required - ShouldDecrementDesiredCapacity: aws.Boolean(true), // Required - InstanceIDs: []*string{ + ShouldDecrementDesiredCapacity: aws.Bool(true), // Required + InstanceIds: []*string{ aws.String("XmlStringMaxLen16"), // Required // More values... }, @@ -1023,22 +844,14 @@ func ExampleAutoScaling_EnterStandby() { resp, err := svc.EnterStandby(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_ExecutePolicy() { @@ -1047,27 +860,21 @@ func ExampleAutoScaling_ExecutePolicy() { params := &autoscaling.ExecutePolicyInput{ PolicyName: aws.String("ResourceName"), // Required AutoScalingGroupName: aws.String("ResourceName"), - HonorCooldown: aws.Boolean(true), + BreachThreshold: aws.Float64(1.0), + HonorCooldown: aws.Bool(true), + MetricValue: aws.Float64(1.0), } resp, err := svc.ExecutePolicy(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_ExitStandby() { @@ -1075,7 +882,7 @@ func ExampleAutoScaling_ExitStandby() { params := &autoscaling.ExitStandbyInput{ AutoScalingGroupName: aws.String("ResourceName"), // Required - InstanceIDs: []*string{ + InstanceIds: []*string{ aws.String("XmlStringMaxLen16"), // Required // More values... }, @@ -1083,22 +890,14 @@ func ExampleAutoScaling_ExitStandby() { resp, err := svc.ExitStandby(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_PutLifecycleHook() { @@ -1108,7 +907,7 @@ func ExampleAutoScaling_PutLifecycleHook() { AutoScalingGroupName: aws.String("ResourceName"), // Required LifecycleHookName: aws.String("AsciiStringMaxLen255"), // Required DefaultResult: aws.String("LifecycleActionResult"), - HeartbeatTimeout: aws.Long(1), + HeartbeatTimeout: aws.Int64(1), LifecycleTransition: aws.String("LifecycleTransition"), NotificationMetadata: aws.String("XmlStringMaxLen1023"), NotificationTargetARN: aws.String("ResourceName"), @@ -1117,22 +916,14 @@ func ExampleAutoScaling_PutLifecycleHook() { resp, err := svc.PutLifecycleHook(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_PutNotificationConfiguration() { @@ -1149,54 +940,50 @@ func ExampleAutoScaling_PutNotificationConfiguration() { resp, err := svc.PutNotificationConfiguration(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_PutScalingPolicy() { svc := autoscaling.New(nil) params := &autoscaling.PutScalingPolicyInput{ - AdjustmentType: aws.String("XmlStringMaxLen255"), // Required - AutoScalingGroupName: aws.String("ResourceName"), // Required - PolicyName: aws.String("XmlStringMaxLen255"), // Required - ScalingAdjustment: aws.Long(1), // Required - Cooldown: aws.Long(1), - MinAdjustmentStep: aws.Long(1), + AdjustmentType: aws.String("XmlStringMaxLen255"), // Required + AutoScalingGroupName: aws.String("ResourceName"), // Required + PolicyName: aws.String("XmlStringMaxLen255"), // Required + Cooldown: aws.Int64(1), + EstimatedInstanceWarmup: aws.Int64(1), + MetricAggregationType: aws.String("XmlStringMaxLen32"), + MinAdjustmentMagnitude: aws.Int64(1), + MinAdjustmentStep: aws.Int64(1), + PolicyType: aws.String("XmlStringMaxLen64"), + ScalingAdjustment: aws.Int64(1), + StepAdjustments: []*autoscaling.StepAdjustment{ + { // Required + ScalingAdjustment: aws.Int64(1), // Required + MetricIntervalLowerBound: aws.Float64(1.0), + MetricIntervalUpperBound: aws.Float64(1.0), + }, + // More values... + }, } resp, err := svc.PutScalingPolicy(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_PutScheduledUpdateGroupAction() { @@ -1205,10 +992,10 @@ func ExampleAutoScaling_PutScheduledUpdateGroupAction() { params := &autoscaling.PutScheduledUpdateGroupActionInput{ AutoScalingGroupName: aws.String("ResourceName"), // Required ScheduledActionName: aws.String("XmlStringMaxLen255"), // Required - DesiredCapacity: aws.Long(1), + DesiredCapacity: aws.Int64(1), EndTime: aws.Time(time.Now()), - MaxSize: aws.Long(1), - MinSize: aws.Long(1), + MaxSize: aws.Int64(1), + MinSize: aws.Int64(1), Recurrence: aws.String("XmlStringMaxLen255"), StartTime: aws.Time(time.Now()), Time: aws.Time(time.Now()), @@ -1216,22 +1003,14 @@ func ExampleAutoScaling_PutScheduledUpdateGroupAction() { resp, err := svc.PutScheduledUpdateGroupAction(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_RecordLifecycleActionHeartbeat() { @@ -1245,22 +1024,14 @@ func ExampleAutoScaling_RecordLifecycleActionHeartbeat() { resp, err := svc.RecordLifecycleActionHeartbeat(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_ResumeProcesses() { @@ -1276,22 +1047,14 @@ func ExampleAutoScaling_ResumeProcesses() { resp, err := svc.ResumeProcesses(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_SetDesiredCapacity() { @@ -1299,28 +1062,20 @@ func ExampleAutoScaling_SetDesiredCapacity() { params := &autoscaling.SetDesiredCapacityInput{ AutoScalingGroupName: aws.String("ResourceName"), // Required - DesiredCapacity: aws.Long(1), // Required - HonorCooldown: aws.Boolean(true), + DesiredCapacity: aws.Int64(1), // Required + HonorCooldown: aws.Bool(true), } resp, err := svc.SetDesiredCapacity(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_SetInstanceHealth() { @@ -1328,28 +1083,20 @@ func ExampleAutoScaling_SetInstanceHealth() { params := &autoscaling.SetInstanceHealthInput{ HealthStatus: aws.String("XmlStringMaxLen32"), // Required - InstanceID: aws.String("XmlStringMaxLen16"), // Required - ShouldRespectGracePeriod: aws.Boolean(true), + InstanceId: aws.String("XmlStringMaxLen16"), // Required + ShouldRespectGracePeriod: aws.Bool(true), } resp, err := svc.SetInstanceHealth(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_SuspendProcesses() { @@ -1365,50 +1112,34 @@ func ExampleAutoScaling_SuspendProcesses() { resp, err := svc.SuspendProcesses(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_TerminateInstanceInAutoScalingGroup() { svc := autoscaling.New(nil) params := &autoscaling.TerminateInstanceInAutoScalingGroupInput{ - InstanceID: aws.String("XmlStringMaxLen16"), // Required - ShouldDecrementDesiredCapacity: aws.Boolean(true), // Required + InstanceId: aws.String("XmlStringMaxLen16"), // Required + ShouldDecrementDesiredCapacity: aws.Bool(true), // Required } resp, err := svc.TerminateInstanceInAutoScalingGroup(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleAutoScaling_UpdateAutoScalingGroup() { @@ -1420,13 +1151,13 @@ func ExampleAutoScaling_UpdateAutoScalingGroup() { aws.String("XmlStringMaxLen255"), // Required // More values... }, - DefaultCooldown: aws.Long(1), - DesiredCapacity: aws.Long(1), - HealthCheckGracePeriod: aws.Long(1), + DefaultCooldown: aws.Int64(1), + DesiredCapacity: aws.Int64(1), + HealthCheckGracePeriod: aws.Int64(1), HealthCheckType: aws.String("XmlStringMaxLen32"), LaunchConfigurationName: aws.String("ResourceName"), - MaxSize: aws.Long(1), - MinSize: aws.Long(1), + MaxSize: aws.Int64(1), + MinSize: aws.Int64(1), PlacementGroup: aws.String("XmlStringMaxLen255"), TerminationPolicies: []*string{ aws.String("XmlStringMaxLen1600"), // Required @@ -1437,20 +1168,12 @@ func ExampleAutoScaling_UpdateAutoScalingGroup() { resp, err := svc.UpdateAutoScalingGroup(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/service.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/service.go index 41d4b123f02e..d17015ad746c 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/service.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/autoscaling/service.go @@ -4,27 +4,35 @@ package autoscaling import ( "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" + "github.com/aws/aws-sdk-go/aws/service/serviceinfo" "github.com/aws/aws-sdk-go/internal/protocol/query" "github.com/aws/aws-sdk-go/internal/signer/v4" ) -// AutoScaling is a client for Auto Scaling. +// Auto Scaling is designed to automatically launch or terminate EC2 instances +// based on user-defined policies, schedules, and health checks. Use this service +// in conjunction with the Amazon CloudWatch and Elastic Load Balancing services. type AutoScaling struct { - *aws.Service + *service.Service } // Used for custom service initialization logic -var initService func(*aws.Service) +var initService func(*service.Service) // Used for custom request initialization logic -var initRequest func(*aws.Request) +var initRequest func(*request.Request) // New returns a new AutoScaling client. func New(config *aws.Config) *AutoScaling { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "autoscaling", - APIVersion: "2011-01-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "autoscaling", + APIVersion: "2011-01-01", + }, } service.Initialize() @@ -45,8 +53,8 @@ func New(config *aws.Config) *AutoScaling { // newRequest creates a new request for a AutoScaling operation and runs any // custom request initialization. -func (c *AutoScaling) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *AutoScaling) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) // Run custom request initialization if present if initRequest != nil { diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/api.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/api.go index 9255ab75c814..0327851d6078 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/api.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/api.go @@ -4,33 +4,28 @@ package ec2 import ( - "sync" "time" - "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" ) -var oprw sync.Mutex +const opAcceptVpcPeeringConnection = "AcceptVpcPeeringConnection" -// AcceptVPCPeeringConnectionRequest generates a request for the AcceptVPCPeeringConnection operation. -func (c *EC2) AcceptVPCPeeringConnectionRequest(input *AcceptVPCPeeringConnectionInput) (req *aws.Request, output *AcceptVPCPeeringConnectionOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAcceptVPCPeeringConnection == nil { - opAcceptVPCPeeringConnection = &aws.Operation{ - Name: "AcceptVpcPeeringConnection", - HTTPMethod: "POST", - HTTPPath: "/", - } +// AcceptVpcPeeringConnectionRequest generates a request for the AcceptVpcPeeringConnection operation. +func (c *EC2) AcceptVpcPeeringConnectionRequest(input *AcceptVpcPeeringConnectionInput) (req *request.Request, output *AcceptVpcPeeringConnectionOutput) { + op := &request.Operation{ + Name: opAcceptVpcPeeringConnection, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &AcceptVPCPeeringConnectionInput{} + input = &AcceptVpcPeeringConnectionInput{} } - req = c.newRequest(opAcceptVPCPeeringConnection, input, output) - output = &AcceptVPCPeeringConnectionOutput{} + req = c.newRequest(op, input, output) + output = &AcceptVpcPeeringConnectionOutput{} req.Data = output return } @@ -39,32 +34,27 @@ func (c *EC2) AcceptVPCPeeringConnectionRequest(input *AcceptVPCPeeringConnectio // connection must be in the pending-acceptance state, and you must be the owner // of the peer VPC. Use the DescribeVpcPeeringConnections request to view your // outstanding VPC peering connection requests. -func (c *EC2) AcceptVPCPeeringConnection(input *AcceptVPCPeeringConnectionInput) (*AcceptVPCPeeringConnectionOutput, error) { - req, out := c.AcceptVPCPeeringConnectionRequest(input) +func (c *EC2) AcceptVpcPeeringConnection(input *AcceptVpcPeeringConnectionInput) (*AcceptVpcPeeringConnectionOutput, error) { + req, out := c.AcceptVpcPeeringConnectionRequest(input) err := req.Send() return out, err } -var opAcceptVPCPeeringConnection *aws.Operation +const opAllocateAddress = "AllocateAddress" // AllocateAddressRequest generates a request for the AllocateAddress operation. -func (c *EC2) AllocateAddressRequest(input *AllocateAddressInput) (req *aws.Request, output *AllocateAddressOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAllocateAddress == nil { - opAllocateAddress = &aws.Operation{ - Name: "AllocateAddress", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) AllocateAddressRequest(input *AllocateAddressInput) (req *request.Request, output *AllocateAddressOutput) { + op := &request.Operation{ + Name: opAllocateAddress, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &AllocateAddressInput{} } - req = c.newRequest(opAllocateAddress, input, output) + req = c.newRequest(op, input, output) output = &AllocateAddressOutput{} req.Data = output return @@ -81,27 +71,22 @@ func (c *EC2) AllocateAddress(input *AllocateAddressInput) (*AllocateAddressOutp return out, err } -var opAllocateAddress *aws.Operation +const opAssignPrivateIpAddresses = "AssignPrivateIpAddresses" -// AssignPrivateIPAddressesRequest generates a request for the AssignPrivateIPAddresses operation. -func (c *EC2) AssignPrivateIPAddressesRequest(input *AssignPrivateIPAddressesInput) (req *aws.Request, output *AssignPrivateIPAddressesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAssignPrivateIPAddresses == nil { - opAssignPrivateIPAddresses = &aws.Operation{ - Name: "AssignPrivateIpAddresses", - HTTPMethod: "POST", - HTTPPath: "/", - } +// AssignPrivateIpAddressesRequest generates a request for the AssignPrivateIpAddresses operation. +func (c *EC2) AssignPrivateIpAddressesRequest(input *AssignPrivateIpAddressesInput) (req *request.Request, output *AssignPrivateIpAddressesOutput) { + op := &request.Operation{ + Name: opAssignPrivateIpAddresses, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &AssignPrivateIPAddressesInput{} + input = &AssignPrivateIpAddressesInput{} } - req = c.newRequest(opAssignPrivateIPAddresses, input, output) - output = &AssignPrivateIPAddressesOutput{} + req = c.newRequest(op, input, output) + output = &AssignPrivateIpAddressesOutput{} req.Data = output return } @@ -117,32 +102,27 @@ func (c *EC2) AssignPrivateIPAddressesRequest(input *AssignPrivateIPAddressesInp // in the Amazon Elastic Compute Cloud User Guide. // // AssignPrivateIpAddresses is available only in EC2-VPC. -func (c *EC2) AssignPrivateIPAddresses(input *AssignPrivateIPAddressesInput) (*AssignPrivateIPAddressesOutput, error) { - req, out := c.AssignPrivateIPAddressesRequest(input) +func (c *EC2) AssignPrivateIpAddresses(input *AssignPrivateIpAddressesInput) (*AssignPrivateIpAddressesOutput, error) { + req, out := c.AssignPrivateIpAddressesRequest(input) err := req.Send() return out, err } -var opAssignPrivateIPAddresses *aws.Operation +const opAssociateAddress = "AssociateAddress" // AssociateAddressRequest generates a request for the AssociateAddress operation. -func (c *EC2) AssociateAddressRequest(input *AssociateAddressInput) (req *aws.Request, output *AssociateAddressOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAssociateAddress == nil { - opAssociateAddress = &aws.Operation{ - Name: "AssociateAddress", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) AssociateAddressRequest(input *AssociateAddressInput) (req *request.Request, output *AssociateAddressOutput) { + op := &request.Operation{ + Name: opAssociateAddress, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &AssociateAddressInput{} } - req = c.newRequest(opAssociateAddress, input, output) + req = c.newRequest(op, input, output) output = &AssociateAddressOutput{} req.Data = output return @@ -171,27 +151,22 @@ func (c *EC2) AssociateAddress(input *AssociateAddressInput) (*AssociateAddressO return out, err } -var opAssociateAddress *aws.Operation +const opAssociateDhcpOptions = "AssociateDhcpOptions" -// AssociateDHCPOptionsRequest generates a request for the AssociateDHCPOptions operation. -func (c *EC2) AssociateDHCPOptionsRequest(input *AssociateDHCPOptionsInput) (req *aws.Request, output *AssociateDHCPOptionsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAssociateDHCPOptions == nil { - opAssociateDHCPOptions = &aws.Operation{ - Name: "AssociateDhcpOptions", - HTTPMethod: "POST", - HTTPPath: "/", - } +// AssociateDhcpOptionsRequest generates a request for the AssociateDhcpOptions operation. +func (c *EC2) AssociateDhcpOptionsRequest(input *AssociateDhcpOptionsInput) (req *request.Request, output *AssociateDhcpOptionsOutput) { + op := &request.Operation{ + Name: opAssociateDhcpOptions, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &AssociateDHCPOptionsInput{} + input = &AssociateDhcpOptionsInput{} } - req = c.newRequest(opAssociateDHCPOptions, input, output) - output = &AssociateDHCPOptionsOutput{} + req = c.newRequest(op, input, output) + output = &AssociateDhcpOptionsOutput{} req.Data = output return } @@ -208,32 +183,27 @@ func (c *EC2) AssociateDHCPOptionsRequest(input *AssociateDHCPOptionsInput) (req // // For more information, see DHCP Options Sets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) AssociateDHCPOptions(input *AssociateDHCPOptionsInput) (*AssociateDHCPOptionsOutput, error) { - req, out := c.AssociateDHCPOptionsRequest(input) +func (c *EC2) AssociateDhcpOptions(input *AssociateDhcpOptionsInput) (*AssociateDhcpOptionsOutput, error) { + req, out := c.AssociateDhcpOptionsRequest(input) err := req.Send() return out, err } -var opAssociateDHCPOptions *aws.Operation +const opAssociateRouteTable = "AssociateRouteTable" // AssociateRouteTableRequest generates a request for the AssociateRouteTable operation. -func (c *EC2) AssociateRouteTableRequest(input *AssociateRouteTableInput) (req *aws.Request, output *AssociateRouteTableOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAssociateRouteTable == nil { - opAssociateRouteTable = &aws.Operation{ - Name: "AssociateRouteTable", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) AssociateRouteTableRequest(input *AssociateRouteTableInput) (req *request.Request, output *AssociateRouteTableOutput) { + op := &request.Operation{ + Name: opAssociateRouteTable, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &AssociateRouteTableInput{} } - req = c.newRequest(opAssociateRouteTable, input, output) + req = c.newRequest(op, input, output) output = &AssociateRouteTableOutput{} req.Data = output return @@ -253,27 +223,22 @@ func (c *EC2) AssociateRouteTable(input *AssociateRouteTableInput) (*AssociateRo return out, err } -var opAssociateRouteTable *aws.Operation +const opAttachClassicLinkVpc = "AttachClassicLinkVpc" -// AttachClassicLinkVPCRequest generates a request for the AttachClassicLinkVPC operation. -func (c *EC2) AttachClassicLinkVPCRequest(input *AttachClassicLinkVPCInput) (req *aws.Request, output *AttachClassicLinkVPCOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAttachClassicLinkVPC == nil { - opAttachClassicLinkVPC = &aws.Operation{ - Name: "AttachClassicLinkVpc", - HTTPMethod: "POST", - HTTPPath: "/", - } +// AttachClassicLinkVpcRequest generates a request for the AttachClassicLinkVpc operation. +func (c *EC2) AttachClassicLinkVpcRequest(input *AttachClassicLinkVpcInput) (req *request.Request, output *AttachClassicLinkVpcOutput) { + op := &request.Operation{ + Name: opAttachClassicLinkVpc, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &AttachClassicLinkVPCInput{} + input = &AttachClassicLinkVpcInput{} } - req = c.newRequest(opAttachClassicLinkVPC, input, output) - output = &AttachClassicLinkVPCOutput{} + req = c.newRequest(op, input, output) + output = &AttachClassicLinkVpcOutput{} req.Data = output return } @@ -290,32 +255,27 @@ func (c *EC2) AttachClassicLinkVPCRequest(input *AttachClassicLinkVPCInput) (req // // Linking your instance to a VPC is sometimes referred to as attaching your // instance. -func (c *EC2) AttachClassicLinkVPC(input *AttachClassicLinkVPCInput) (*AttachClassicLinkVPCOutput, error) { - req, out := c.AttachClassicLinkVPCRequest(input) +func (c *EC2) AttachClassicLinkVpc(input *AttachClassicLinkVpcInput) (*AttachClassicLinkVpcOutput, error) { + req, out := c.AttachClassicLinkVpcRequest(input) err := req.Send() return out, err } -var opAttachClassicLinkVPC *aws.Operation +const opAttachInternetGateway = "AttachInternetGateway" // AttachInternetGatewayRequest generates a request for the AttachInternetGateway operation. -func (c *EC2) AttachInternetGatewayRequest(input *AttachInternetGatewayInput) (req *aws.Request, output *AttachInternetGatewayOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAttachInternetGateway == nil { - opAttachInternetGateway = &aws.Operation{ - Name: "AttachInternetGateway", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) AttachInternetGatewayRequest(input *AttachInternetGatewayInput) (req *request.Request, output *AttachInternetGatewayOutput) { + op := &request.Operation{ + Name: opAttachInternetGateway, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &AttachInternetGatewayInput{} } - req = c.newRequest(opAttachInternetGateway, input, output) + req = c.newRequest(op, input, output) output = &AttachInternetGatewayOutput{} req.Data = output return @@ -330,26 +290,21 @@ func (c *EC2) AttachInternetGateway(input *AttachInternetGatewayInput) (*AttachI return out, err } -var opAttachInternetGateway *aws.Operation +const opAttachNetworkInterface = "AttachNetworkInterface" // AttachNetworkInterfaceRequest generates a request for the AttachNetworkInterface operation. -func (c *EC2) AttachNetworkInterfaceRequest(input *AttachNetworkInterfaceInput) (req *aws.Request, output *AttachNetworkInterfaceOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAttachNetworkInterface == nil { - opAttachNetworkInterface = &aws.Operation{ - Name: "AttachNetworkInterface", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) AttachNetworkInterfaceRequest(input *AttachNetworkInterfaceInput) (req *request.Request, output *AttachNetworkInterfaceOutput) { + op := &request.Operation{ + Name: opAttachNetworkInterface, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &AttachNetworkInterfaceInput{} } - req = c.newRequest(opAttachNetworkInterface, input, output) + req = c.newRequest(op, input, output) output = &AttachNetworkInterfaceOutput{} req.Data = output return @@ -362,60 +317,21 @@ func (c *EC2) AttachNetworkInterface(input *AttachNetworkInterfaceInput) (*Attac return out, err } -var opAttachNetworkInterface *aws.Operation - -// AttachVPNGatewayRequest generates a request for the AttachVPNGateway operation. -func (c *EC2) AttachVPNGatewayRequest(input *AttachVPNGatewayInput) (req *aws.Request, output *AttachVPNGatewayOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAttachVPNGateway == nil { - opAttachVPNGateway = &aws.Operation{ - Name: "AttachVpnGateway", - HTTPMethod: "POST", - HTTPPath: "/", - } - } - - if input == nil { - input = &AttachVPNGatewayInput{} - } - - req = c.newRequest(opAttachVPNGateway, input, output) - output = &AttachVPNGatewayOutput{} - req.Data = output - return -} - -// Attaches a virtual private gateway to a VPC. For more information, see Adding -// a Hardware Virtual Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) -// in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) AttachVPNGateway(input *AttachVPNGatewayInput) (*AttachVPNGatewayOutput, error) { - req, out := c.AttachVPNGatewayRequest(input) - err := req.Send() - return out, err -} - -var opAttachVPNGateway *aws.Operation +const opAttachVolume = "AttachVolume" // AttachVolumeRequest generates a request for the AttachVolume operation. -func (c *EC2) AttachVolumeRequest(input *AttachVolumeInput) (req *aws.Request, output *VolumeAttachment) { - oprw.Lock() - defer oprw.Unlock() - - if opAttachVolume == nil { - opAttachVolume = &aws.Operation{ - Name: "AttachVolume", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) AttachVolumeRequest(input *AttachVolumeInput) (req *request.Request, output *VolumeAttachment) { + op := &request.Operation{ + Name: opAttachVolume, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &AttachVolumeInput{} } - req = c.newRequest(opAttachVolume, input, output) + req = c.newRequest(op, input, output) output = &VolumeAttachment{} req.Data = output return @@ -452,26 +368,50 @@ func (c *EC2) AttachVolume(input *AttachVolumeInput) (*VolumeAttachment, error) return out, err } -var opAttachVolume *aws.Operation +const opAttachVpnGateway = "AttachVpnGateway" -// AuthorizeSecurityGroupEgressRequest generates a request for the AuthorizeSecurityGroupEgress operation. -func (c *EC2) AuthorizeSecurityGroupEgressRequest(input *AuthorizeSecurityGroupEgressInput) (req *aws.Request, output *AuthorizeSecurityGroupEgressOutput) { - oprw.Lock() - defer oprw.Unlock() +// AttachVpnGatewayRequest generates a request for the AttachVpnGateway operation. +func (c *EC2) AttachVpnGatewayRequest(input *AttachVpnGatewayInput) (req *request.Request, output *AttachVpnGatewayOutput) { + op := &request.Operation{ + Name: opAttachVpnGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AttachVpnGatewayInput{} + } + + req = c.newRequest(op, input, output) + output = &AttachVpnGatewayOutput{} + req.Data = output + return +} + +// Attaches a virtual private gateway to a VPC. For more information, see Adding +// a Hardware Virtual Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) AttachVpnGateway(input *AttachVpnGatewayInput) (*AttachVpnGatewayOutput, error) { + req, out := c.AttachVpnGatewayRequest(input) + err := req.Send() + return out, err +} - if opAuthorizeSecurityGroupEgress == nil { - opAuthorizeSecurityGroupEgress = &aws.Operation{ - Name: "AuthorizeSecurityGroupEgress", - HTTPMethod: "POST", - HTTPPath: "/", - } +const opAuthorizeSecurityGroupEgress = "AuthorizeSecurityGroupEgress" + +// AuthorizeSecurityGroupEgressRequest generates a request for the AuthorizeSecurityGroupEgress operation. +func (c *EC2) AuthorizeSecurityGroupEgressRequest(input *AuthorizeSecurityGroupEgressInput) (req *request.Request, output *AuthorizeSecurityGroupEgressOutput) { + op := &request.Operation{ + Name: opAuthorizeSecurityGroupEgress, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &AuthorizeSecurityGroupEgressInput{} } - req = c.newRequest(opAuthorizeSecurityGroupEgress, input, output) + req = c.newRequest(op, input, output) output = &AuthorizeSecurityGroupEgressOutput{} req.Data = output return @@ -504,26 +444,21 @@ func (c *EC2) AuthorizeSecurityGroupEgress(input *AuthorizeSecurityGroupEgressIn return out, err } -var opAuthorizeSecurityGroupEgress *aws.Operation +const opAuthorizeSecurityGroupIngress = "AuthorizeSecurityGroupIngress" // AuthorizeSecurityGroupIngressRequest generates a request for the AuthorizeSecurityGroupIngress operation. -func (c *EC2) AuthorizeSecurityGroupIngressRequest(input *AuthorizeSecurityGroupIngressInput) (req *aws.Request, output *AuthorizeSecurityGroupIngressOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAuthorizeSecurityGroupIngress == nil { - opAuthorizeSecurityGroupIngress = &aws.Operation{ - Name: "AuthorizeSecurityGroupIngress", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) AuthorizeSecurityGroupIngressRequest(input *AuthorizeSecurityGroupIngressInput) (req *request.Request, output *AuthorizeSecurityGroupIngressOutput) { + op := &request.Operation{ + Name: opAuthorizeSecurityGroupIngress, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &AuthorizeSecurityGroupIngressInput{} } - req = c.newRequest(opAuthorizeSecurityGroupIngress, input, output) + req = c.newRequest(op, input, output) output = &AuthorizeSecurityGroupIngressOutput{} req.Data = output return @@ -554,26 +489,21 @@ func (c *EC2) AuthorizeSecurityGroupIngress(input *AuthorizeSecurityGroupIngress return out, err } -var opAuthorizeSecurityGroupIngress *aws.Operation +const opBundleInstance = "BundleInstance" // BundleInstanceRequest generates a request for the BundleInstance operation. -func (c *EC2) BundleInstanceRequest(input *BundleInstanceInput) (req *aws.Request, output *BundleInstanceOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opBundleInstance == nil { - opBundleInstance = &aws.Operation{ - Name: "BundleInstance", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) BundleInstanceRequest(input *BundleInstanceInput) (req *request.Request, output *BundleInstanceOutput) { + op := &request.Operation{ + Name: opBundleInstance, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &BundleInstanceInput{} } - req = c.newRequest(opBundleInstance, input, output) + req = c.newRequest(op, input, output) output = &BundleInstanceOutput{} req.Data = output return @@ -595,26 +525,21 @@ func (c *EC2) BundleInstance(input *BundleInstanceInput) (*BundleInstanceOutput, return out, err } -var opBundleInstance *aws.Operation +const opCancelBundleTask = "CancelBundleTask" // CancelBundleTaskRequest generates a request for the CancelBundleTask operation. -func (c *EC2) CancelBundleTaskRequest(input *CancelBundleTaskInput) (req *aws.Request, output *CancelBundleTaskOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCancelBundleTask == nil { - opCancelBundleTask = &aws.Operation{ - Name: "CancelBundleTask", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CancelBundleTaskRequest(input *CancelBundleTaskInput) (req *request.Request, output *CancelBundleTaskOutput) { + op := &request.Operation{ + Name: opCancelBundleTask, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CancelBundleTaskInput{} } - req = c.newRequest(opCancelBundleTask, input, output) + req = c.newRequest(op, input, output) output = &CancelBundleTaskOutput{} req.Data = output return @@ -627,26 +552,21 @@ func (c *EC2) CancelBundleTask(input *CancelBundleTaskInput) (*CancelBundleTaskO return out, err } -var opCancelBundleTask *aws.Operation +const opCancelConversionTask = "CancelConversionTask" // CancelConversionTaskRequest generates a request for the CancelConversionTask operation. -func (c *EC2) CancelConversionTaskRequest(input *CancelConversionTaskInput) (req *aws.Request, output *CancelConversionTaskOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCancelConversionTask == nil { - opCancelConversionTask = &aws.Operation{ - Name: "CancelConversionTask", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CancelConversionTaskRequest(input *CancelConversionTaskInput) (req *request.Request, output *CancelConversionTaskOutput) { + op := &request.Operation{ + Name: opCancelConversionTask, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CancelConversionTaskInput{} } - req = c.newRequest(opCancelConversionTask, input, output) + req = c.newRequest(op, input, output) output = &CancelConversionTaskOutput{} req.Data = output return @@ -667,26 +587,21 @@ func (c *EC2) CancelConversionTask(input *CancelConversionTaskInput) (*CancelCon return out, err } -var opCancelConversionTask *aws.Operation +const opCancelExportTask = "CancelExportTask" // CancelExportTaskRequest generates a request for the CancelExportTask operation. -func (c *EC2) CancelExportTaskRequest(input *CancelExportTaskInput) (req *aws.Request, output *CancelExportTaskOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCancelExportTask == nil { - opCancelExportTask = &aws.Operation{ - Name: "CancelExportTask", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CancelExportTaskRequest(input *CancelExportTaskInput) (req *request.Request, output *CancelExportTaskOutput) { + op := &request.Operation{ + Name: opCancelExportTask, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CancelExportTaskInput{} } - req = c.newRequest(opCancelExportTask, input, output) + req = c.newRequest(op, input, output) output = &CancelExportTaskOutput{} req.Data = output return @@ -702,26 +617,21 @@ func (c *EC2) CancelExportTask(input *CancelExportTaskInput) (*CancelExportTaskO return out, err } -var opCancelExportTask *aws.Operation +const opCancelImportTask = "CancelImportTask" // CancelImportTaskRequest generates a request for the CancelImportTask operation. -func (c *EC2) CancelImportTaskRequest(input *CancelImportTaskInput) (req *aws.Request, output *CancelImportTaskOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCancelImportTask == nil { - opCancelImportTask = &aws.Operation{ - Name: "CancelImportTask", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CancelImportTaskRequest(input *CancelImportTaskInput) (req *request.Request, output *CancelImportTaskOutput) { + op := &request.Operation{ + Name: opCancelImportTask, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CancelImportTaskInput{} } - req = c.newRequest(opCancelImportTask, input, output) + req = c.newRequest(op, input, output) output = &CancelImportTaskOutput{} req.Data = output return @@ -734,26 +644,21 @@ func (c *EC2) CancelImportTask(input *CancelImportTaskInput) (*CancelImportTaskO return out, err } -var opCancelImportTask *aws.Operation +const opCancelReservedInstancesListing = "CancelReservedInstancesListing" // CancelReservedInstancesListingRequest generates a request for the CancelReservedInstancesListing operation. -func (c *EC2) CancelReservedInstancesListingRequest(input *CancelReservedInstancesListingInput) (req *aws.Request, output *CancelReservedInstancesListingOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCancelReservedInstancesListing == nil { - opCancelReservedInstancesListing = &aws.Operation{ - Name: "CancelReservedInstancesListing", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CancelReservedInstancesListingRequest(input *CancelReservedInstancesListingInput) (req *request.Request, output *CancelReservedInstancesListingOutput) { + op := &request.Operation{ + Name: opCancelReservedInstancesListing, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CancelReservedInstancesListingInput{} } - req = c.newRequest(opCancelReservedInstancesListing, input, output) + req = c.newRequest(op, input, output) output = &CancelReservedInstancesListingOutput{} req.Data = output return @@ -770,26 +675,21 @@ func (c *EC2) CancelReservedInstancesListing(input *CancelReservedInstancesListi return out, err } -var opCancelReservedInstancesListing *aws.Operation +const opCancelSpotFleetRequests = "CancelSpotFleetRequests" // CancelSpotFleetRequestsRequest generates a request for the CancelSpotFleetRequests operation. -func (c *EC2) CancelSpotFleetRequestsRequest(input *CancelSpotFleetRequestsInput) (req *aws.Request, output *CancelSpotFleetRequestsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCancelSpotFleetRequests == nil { - opCancelSpotFleetRequests = &aws.Operation{ - Name: "CancelSpotFleetRequests", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CancelSpotFleetRequestsRequest(input *CancelSpotFleetRequestsInput) (req *request.Request, output *CancelSpotFleetRequestsOutput) { + op := &request.Operation{ + Name: opCancelSpotFleetRequests, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CancelSpotFleetRequestsInput{} } - req = c.newRequest(opCancelSpotFleetRequests, input, output) + req = c.newRequest(op, input, output) output = &CancelSpotFleetRequestsOutput{} req.Data = output return @@ -802,39 +702,34 @@ func (c *EC2) CancelSpotFleetRequests(input *CancelSpotFleetRequestsInput) (*Can return out, err } -var opCancelSpotFleetRequests *aws.Operation +const opCancelSpotInstanceRequests = "CancelSpotInstanceRequests" // CancelSpotInstanceRequestsRequest generates a request for the CancelSpotInstanceRequests operation. -func (c *EC2) CancelSpotInstanceRequestsRequest(input *CancelSpotInstanceRequestsInput) (req *aws.Request, output *CancelSpotInstanceRequestsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCancelSpotInstanceRequests == nil { - opCancelSpotInstanceRequests = &aws.Operation{ - Name: "CancelSpotInstanceRequests", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CancelSpotInstanceRequestsRequest(input *CancelSpotInstanceRequestsInput) (req *request.Request, output *CancelSpotInstanceRequestsOutput) { + op := &request.Operation{ + Name: opCancelSpotInstanceRequests, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CancelSpotInstanceRequestsInput{} } - req = c.newRequest(opCancelSpotInstanceRequests, input, output) + req = c.newRequest(op, input, output) output = &CancelSpotInstanceRequestsOutput{} req.Data = output return } -// Cancels one or more Spot Instance requests. Spot Instances are instances +// Cancels one or more Spot instance requests. Spot instances are instances // that Amazon EC2 starts on your behalf when the bid price that you specify -// exceeds the current Spot Price. Amazon EC2 periodically sets the Spot Price -// based on available Spot Instance capacity and current Spot Instance requests. +// exceeds the current Spot price. Amazon EC2 periodically sets the Spot price +// based on available Spot instance capacity and current Spot instance requests. // For more information, see Spot Instance Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) // in the Amazon Elastic Compute Cloud User Guide. // -// Canceling a Spot Instance request does not terminate running Spot Instances +// Canceling a Spot instance request does not terminate running Spot instances // associated with the request. func (c *EC2) CancelSpotInstanceRequests(input *CancelSpotInstanceRequestsInput) (*CancelSpotInstanceRequestsOutput, error) { req, out := c.CancelSpotInstanceRequestsRequest(input) @@ -842,26 +737,21 @@ func (c *EC2) CancelSpotInstanceRequests(input *CancelSpotInstanceRequestsInput) return out, err } -var opCancelSpotInstanceRequests *aws.Operation +const opConfirmProductInstance = "ConfirmProductInstance" // ConfirmProductInstanceRequest generates a request for the ConfirmProductInstance operation. -func (c *EC2) ConfirmProductInstanceRequest(input *ConfirmProductInstanceInput) (req *aws.Request, output *ConfirmProductInstanceOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opConfirmProductInstance == nil { - opConfirmProductInstance = &aws.Operation{ - Name: "ConfirmProductInstance", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ConfirmProductInstanceRequest(input *ConfirmProductInstanceInput) (req *request.Request, output *ConfirmProductInstanceOutput) { + op := &request.Operation{ + Name: opConfirmProductInstance, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ConfirmProductInstanceInput{} } - req = c.newRequest(opConfirmProductInstance, input, output) + req = c.newRequest(op, input, output) output = &ConfirmProductInstanceOutput{} req.Data = output return @@ -877,26 +767,21 @@ func (c *EC2) ConfirmProductInstance(input *ConfirmProductInstanceInput) (*Confi return out, err } -var opConfirmProductInstance *aws.Operation +const opCopyImage = "CopyImage" // CopyImageRequest generates a request for the CopyImage operation. -func (c *EC2) CopyImageRequest(input *CopyImageInput) (req *aws.Request, output *CopyImageOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCopyImage == nil { - opCopyImage = &aws.Operation{ - Name: "CopyImage", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CopyImageRequest(input *CopyImageInput) (req *request.Request, output *CopyImageOutput) { + op := &request.Operation{ + Name: opCopyImage, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CopyImageInput{} } - req = c.newRequest(opCopyImage, input, output) + req = c.newRequest(op, input, output) output = &CopyImageOutput{} req.Data = output return @@ -915,26 +800,21 @@ func (c *EC2) CopyImage(input *CopyImageInput) (*CopyImageOutput, error) { return out, err } -var opCopyImage *aws.Operation +const opCopySnapshot = "CopySnapshot" // CopySnapshotRequest generates a request for the CopySnapshot operation. -func (c *EC2) CopySnapshotRequest(input *CopySnapshotInput) (req *aws.Request, output *CopySnapshotOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCopySnapshot == nil { - opCopySnapshot = &aws.Operation{ - Name: "CopySnapshot", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CopySnapshotRequest(input *CopySnapshotInput) (req *request.Request, output *CopySnapshotOutput) { + op := &request.Operation{ + Name: opCopySnapshot, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CopySnapshotInput{} } - req = c.newRequest(opCopySnapshot, input, output) + req = c.newRequest(op, input, output) output = &CopySnapshotOutput{} req.Data = output return @@ -947,12 +827,12 @@ func (c *EC2) CopySnapshotRequest(input *CopySnapshotInput) (req *aws.Request, o // the HTTP request to. // // Copies of encrypted EBS snapshots remain encrypted. Copies of unencrypted -// snapshots remain unencrypted. +// snapshots remain unencrypted, unless the Encrypted flag is specified during +// the snapshot copy operation. By default, encrypted snapshot copies use the +// default AWS Key Management Service (AWS KMS) customer master key (CMK); however, +// you can specify a non-default CMK with the KmsKeyId parameter. // -// Copying snapshots that were encrypted with non-default AWS Key Management -// Service (KMS) master keys is not supported at this time. -// -// For more information, see Copying an Amazon EBS Snapshot (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-copy-snapshot.html) +// For more information, see Copying an Amazon EBS Snapshot (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-copy-snapshot.html) // in the Amazon Elastic Compute Cloud User Guide. func (c *EC2) CopySnapshot(input *CopySnapshotInput) (*CopySnapshotOutput, error) { req, out := c.CopySnapshotRequest(input) @@ -960,26 +840,21 @@ func (c *EC2) CopySnapshot(input *CopySnapshotInput) (*CopySnapshotOutput, error return out, err } -var opCopySnapshot *aws.Operation +const opCreateCustomerGateway = "CreateCustomerGateway" // CreateCustomerGatewayRequest generates a request for the CreateCustomerGateway operation. -func (c *EC2) CreateCustomerGatewayRequest(input *CreateCustomerGatewayInput) (req *aws.Request, output *CreateCustomerGatewayOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateCustomerGateway == nil { - opCreateCustomerGateway = &aws.Operation{ - Name: "CreateCustomerGateway", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateCustomerGatewayRequest(input *CreateCustomerGatewayInput) (req *request.Request, output *CreateCustomerGatewayOutput) { + op := &request.Operation{ + Name: opCreateCustomerGateway, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateCustomerGatewayInput{} } - req = c.newRequest(opCreateCustomerGateway, input, output) + req = c.newRequest(op, input, output) output = &CreateCustomerGatewayOutput{} req.Data = output return @@ -1016,27 +891,22 @@ func (c *EC2) CreateCustomerGateway(input *CreateCustomerGatewayInput) (*CreateC return out, err } -var opCreateCustomerGateway *aws.Operation +const opCreateDhcpOptions = "CreateDhcpOptions" -// CreateDHCPOptionsRequest generates a request for the CreateDHCPOptions operation. -func (c *EC2) CreateDHCPOptionsRequest(input *CreateDHCPOptionsInput) (req *aws.Request, output *CreateDHCPOptionsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateDHCPOptions == nil { - opCreateDHCPOptions = &aws.Operation{ - Name: "CreateDhcpOptions", - HTTPMethod: "POST", - HTTPPath: "/", - } +// CreateDhcpOptionsRequest generates a request for the CreateDhcpOptions operation. +func (c *EC2) CreateDhcpOptionsRequest(input *CreateDhcpOptionsInput) (req *request.Request, output *CreateDhcpOptionsOutput) { + op := &request.Operation{ + Name: opCreateDhcpOptions, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &CreateDHCPOptionsInput{} + input = &CreateDhcpOptionsInput{} } - req = c.newRequest(opCreateDHCPOptions, input, output) - output = &CreateDHCPOptionsOutput{} + req = c.newRequest(op, input, output) + output = &CreateDhcpOptionsOutput{} req.Data = output return } @@ -1070,32 +940,63 @@ func (c *EC2) CreateDHCPOptionsRequest(input *CreateDHCPOptionsInput) (req *aws. // either to AmazonProvidedDNS or to a domain name server of your choice. For // more information about DHCP options, see DHCP Options Sets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) CreateDHCPOptions(input *CreateDHCPOptionsInput) (*CreateDHCPOptionsOutput, error) { - req, out := c.CreateDHCPOptionsRequest(input) +func (c *EC2) CreateDhcpOptions(input *CreateDhcpOptionsInput) (*CreateDhcpOptionsOutput, error) { + req, out := c.CreateDhcpOptionsRequest(input) err := req.Send() return out, err } -var opCreateDHCPOptions *aws.Operation +const opCreateFlowLogs = "CreateFlowLogs" -// CreateImageRequest generates a request for the CreateImage operation. -func (c *EC2) CreateImageRequest(input *CreateImageInput) (req *aws.Request, output *CreateImageOutput) { - oprw.Lock() - defer oprw.Unlock() +// CreateFlowLogsRequest generates a request for the CreateFlowLogs operation. +func (c *EC2) CreateFlowLogsRequest(input *CreateFlowLogsInput) (req *request.Request, output *CreateFlowLogsOutput) { + op := &request.Operation{ + Name: opCreateFlowLogs, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateFlowLogsInput{} + } + + req = c.newRequest(op, input, output) + output = &CreateFlowLogsOutput{} + req.Data = output + return +} + +// Creates one or more flow logs to capture IP traffic for a specific network +// interface, subnet, or VPC. Flow logs are delivered to a specified log group +// in Amazon CloudWatch Logs. If you specify a VPC or subnet in the request, +// a log stream is created in CloudWatch Logs for each network interface in +// the subnet or VPC. Log streams can include information about accepted and +// rejected traffic to a network interface. You can view the data in your log +// streams using Amazon CloudWatch Logs. +// +// In your request, you must also specify an IAM role that has permission to +// publish logs to CloudWatch Logs. +func (c *EC2) CreateFlowLogs(input *CreateFlowLogsInput) (*CreateFlowLogsOutput, error) { + req, out := c.CreateFlowLogsRequest(input) + err := req.Send() + return out, err +} + +const opCreateImage = "CreateImage" - if opCreateImage == nil { - opCreateImage = &aws.Operation{ - Name: "CreateImage", - HTTPMethod: "POST", - HTTPPath: "/", - } +// CreateImageRequest generates a request for the CreateImage operation. +func (c *EC2) CreateImageRequest(input *CreateImageInput) (req *request.Request, output *CreateImageOutput) { + op := &request.Operation{ + Name: opCreateImage, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateImageInput{} } - req = c.newRequest(opCreateImage, input, output) + req = c.newRequest(op, input, output) output = &CreateImageOutput{} req.Data = output return @@ -1117,26 +1018,21 @@ func (c *EC2) CreateImage(input *CreateImageInput) (*CreateImageOutput, error) { return out, err } -var opCreateImage *aws.Operation +const opCreateInstanceExportTask = "CreateInstanceExportTask" // CreateInstanceExportTaskRequest generates a request for the CreateInstanceExportTask operation. -func (c *EC2) CreateInstanceExportTaskRequest(input *CreateInstanceExportTaskInput) (req *aws.Request, output *CreateInstanceExportTaskOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateInstanceExportTask == nil { - opCreateInstanceExportTask = &aws.Operation{ - Name: "CreateInstanceExportTask", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateInstanceExportTaskRequest(input *CreateInstanceExportTaskInput) (req *request.Request, output *CreateInstanceExportTaskOutput) { + op := &request.Operation{ + Name: opCreateInstanceExportTask, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateInstanceExportTaskInput{} } - req = c.newRequest(opCreateInstanceExportTask, input, output) + req = c.newRequest(op, input, output) output = &CreateInstanceExportTaskOutput{} req.Data = output return @@ -1154,26 +1050,21 @@ func (c *EC2) CreateInstanceExportTask(input *CreateInstanceExportTaskInput) (*C return out, err } -var opCreateInstanceExportTask *aws.Operation +const opCreateInternetGateway = "CreateInternetGateway" // CreateInternetGatewayRequest generates a request for the CreateInternetGateway operation. -func (c *EC2) CreateInternetGatewayRequest(input *CreateInternetGatewayInput) (req *aws.Request, output *CreateInternetGatewayOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateInternetGateway == nil { - opCreateInternetGateway = &aws.Operation{ - Name: "CreateInternetGateway", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateInternetGatewayRequest(input *CreateInternetGatewayInput) (req *request.Request, output *CreateInternetGatewayOutput) { + op := &request.Operation{ + Name: opCreateInternetGateway, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateInternetGatewayInput{} } - req = c.newRequest(opCreateInternetGateway, input, output) + req = c.newRequest(op, input, output) output = &CreateInternetGatewayOutput{} req.Data = output return @@ -1190,26 +1081,21 @@ func (c *EC2) CreateInternetGateway(input *CreateInternetGatewayInput) (*CreateI return out, err } -var opCreateInternetGateway *aws.Operation +const opCreateKeyPair = "CreateKeyPair" // CreateKeyPairRequest generates a request for the CreateKeyPair operation. -func (c *EC2) CreateKeyPairRequest(input *CreateKeyPairInput) (req *aws.Request, output *CreateKeyPairOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateKeyPair == nil { - opCreateKeyPair = &aws.Operation{ - Name: "CreateKeyPair", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateKeyPairRequest(input *CreateKeyPairInput) (req *request.Request, output *CreateKeyPairOutput) { + op := &request.Operation{ + Name: opCreateKeyPair, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateKeyPairInput{} } - req = c.newRequest(opCreateKeyPair, input, output) + req = c.newRequest(op, input, output) output = &CreateKeyPairOutput{} req.Data = output return @@ -1233,27 +1119,22 @@ func (c *EC2) CreateKeyPair(input *CreateKeyPairInput) (*CreateKeyPairOutput, er return out, err } -var opCreateKeyPair *aws.Operation +const opCreateNetworkAcl = "CreateNetworkAcl" -// CreateNetworkACLRequest generates a request for the CreateNetworkACL operation. -func (c *EC2) CreateNetworkACLRequest(input *CreateNetworkACLInput) (req *aws.Request, output *CreateNetworkACLOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateNetworkACL == nil { - opCreateNetworkACL = &aws.Operation{ - Name: "CreateNetworkAcl", - HTTPMethod: "POST", - HTTPPath: "/", - } +// CreateNetworkAclRequest generates a request for the CreateNetworkAcl operation. +func (c *EC2) CreateNetworkAclRequest(input *CreateNetworkAclInput) (req *request.Request, output *CreateNetworkAclOutput) { + op := &request.Operation{ + Name: opCreateNetworkAcl, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &CreateNetworkACLInput{} + input = &CreateNetworkAclInput{} } - req = c.newRequest(opCreateNetworkACL, input, output) - output = &CreateNetworkACLOutput{} + req = c.newRequest(op, input, output) + output = &CreateNetworkAclOutput{} req.Data = output return } @@ -1263,33 +1144,28 @@ func (c *EC2) CreateNetworkACLRequest(input *CreateNetworkACLInput) (req *aws.Re // // For more information about network ACLs, see Network ACLs (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) CreateNetworkACL(input *CreateNetworkACLInput) (*CreateNetworkACLOutput, error) { - req, out := c.CreateNetworkACLRequest(input) +func (c *EC2) CreateNetworkAcl(input *CreateNetworkAclInput) (*CreateNetworkAclOutput, error) { + req, out := c.CreateNetworkAclRequest(input) err := req.Send() return out, err } -var opCreateNetworkACL *aws.Operation - -// CreateNetworkACLEntryRequest generates a request for the CreateNetworkACLEntry operation. -func (c *EC2) CreateNetworkACLEntryRequest(input *CreateNetworkACLEntryInput) (req *aws.Request, output *CreateNetworkACLEntryOutput) { - oprw.Lock() - defer oprw.Unlock() +const opCreateNetworkAclEntry = "CreateNetworkAclEntry" - if opCreateNetworkACLEntry == nil { - opCreateNetworkACLEntry = &aws.Operation{ - Name: "CreateNetworkAclEntry", - HTTPMethod: "POST", - HTTPPath: "/", - } +// CreateNetworkAclEntryRequest generates a request for the CreateNetworkAclEntry operation. +func (c *EC2) CreateNetworkAclEntryRequest(input *CreateNetworkAclEntryInput) (req *request.Request, output *CreateNetworkAclEntryOutput) { + op := &request.Operation{ + Name: opCreateNetworkAclEntry, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &CreateNetworkACLEntryInput{} + input = &CreateNetworkAclEntryInput{} } - req = c.newRequest(opCreateNetworkACLEntry, input, output) - output = &CreateNetworkACLEntryOutput{} + req = c.newRequest(op, input, output) + output = &CreateNetworkAclEntryOutput{} req.Data = output return } @@ -1311,32 +1187,27 @@ func (c *EC2) CreateNetworkACLEntryRequest(input *CreateNetworkACLEntryInput) (r // // For more information about network ACLs, see Network ACLs (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) CreateNetworkACLEntry(input *CreateNetworkACLEntryInput) (*CreateNetworkACLEntryOutput, error) { - req, out := c.CreateNetworkACLEntryRequest(input) +func (c *EC2) CreateNetworkAclEntry(input *CreateNetworkAclEntryInput) (*CreateNetworkAclEntryOutput, error) { + req, out := c.CreateNetworkAclEntryRequest(input) err := req.Send() return out, err } -var opCreateNetworkACLEntry *aws.Operation +const opCreateNetworkInterface = "CreateNetworkInterface" // CreateNetworkInterfaceRequest generates a request for the CreateNetworkInterface operation. -func (c *EC2) CreateNetworkInterfaceRequest(input *CreateNetworkInterfaceInput) (req *aws.Request, output *CreateNetworkInterfaceOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateNetworkInterface == nil { - opCreateNetworkInterface = &aws.Operation{ - Name: "CreateNetworkInterface", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateNetworkInterfaceRequest(input *CreateNetworkInterfaceInput) (req *request.Request, output *CreateNetworkInterfaceOutput) { + op := &request.Operation{ + Name: opCreateNetworkInterface, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateNetworkInterfaceInput{} } - req = c.newRequest(opCreateNetworkInterface, input, output) + req = c.newRequest(op, input, output) output = &CreateNetworkInterfaceOutput{} req.Data = output return @@ -1353,26 +1224,21 @@ func (c *EC2) CreateNetworkInterface(input *CreateNetworkInterfaceInput) (*Creat return out, err } -var opCreateNetworkInterface *aws.Operation +const opCreatePlacementGroup = "CreatePlacementGroup" // CreatePlacementGroupRequest generates a request for the CreatePlacementGroup operation. -func (c *EC2) CreatePlacementGroupRequest(input *CreatePlacementGroupInput) (req *aws.Request, output *CreatePlacementGroupOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreatePlacementGroup == nil { - opCreatePlacementGroup = &aws.Operation{ - Name: "CreatePlacementGroup", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreatePlacementGroupRequest(input *CreatePlacementGroupInput) (req *request.Request, output *CreatePlacementGroupOutput) { + op := &request.Operation{ + Name: opCreatePlacementGroup, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreatePlacementGroupInput{} } - req = c.newRequest(opCreatePlacementGroup, input, output) + req = c.newRequest(op, input, output) output = &CreatePlacementGroupOutput{} req.Data = output return @@ -1390,26 +1256,21 @@ func (c *EC2) CreatePlacementGroup(input *CreatePlacementGroupInput) (*CreatePla return out, err } -var opCreatePlacementGroup *aws.Operation +const opCreateReservedInstancesListing = "CreateReservedInstancesListing" // CreateReservedInstancesListingRequest generates a request for the CreateReservedInstancesListing operation. -func (c *EC2) CreateReservedInstancesListingRequest(input *CreateReservedInstancesListingInput) (req *aws.Request, output *CreateReservedInstancesListingOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateReservedInstancesListing == nil { - opCreateReservedInstancesListing = &aws.Operation{ - Name: "CreateReservedInstancesListing", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateReservedInstancesListingRequest(input *CreateReservedInstancesListingInput) (req *request.Request, output *CreateReservedInstancesListingOutput) { + op := &request.Operation{ + Name: opCreateReservedInstancesListing, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateReservedInstancesListingInput{} } - req = c.newRequest(opCreateReservedInstancesListing, input, output) + req = c.newRequest(op, input, output) output = &CreateReservedInstancesListingOutput{} req.Data = output return @@ -1425,7 +1286,7 @@ func (c *EC2) CreateReservedInstancesListingRequest(input *CreateReservedInstanc // additional capacity. Reserved Instances bought and sold through the Reserved // Instance Marketplace work like any other Reserved Instances. // -// To sell your Reserved Instances, you must first register as a Seller in +// To sell your Reserved Instances, you must first register as a seller in // the Reserved Instance Marketplace. After completing the registration process, // you can create a Reserved Instance Marketplace listing of some or all of // your Reserved Instances, and specify the upfront price to receive for them. @@ -1441,26 +1302,21 @@ func (c *EC2) CreateReservedInstancesListing(input *CreateReservedInstancesListi return out, err } -var opCreateReservedInstancesListing *aws.Operation +const opCreateRoute = "CreateRoute" // CreateRouteRequest generates a request for the CreateRoute operation. -func (c *EC2) CreateRouteRequest(input *CreateRouteInput) (req *aws.Request, output *CreateRouteOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateRoute == nil { - opCreateRoute = &aws.Operation{ - Name: "CreateRoute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateRouteRequest(input *CreateRouteInput) (req *request.Request, output *CreateRouteOutput) { + op := &request.Operation{ + Name: opCreateRoute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateRouteInput{} } - req = c.newRequest(opCreateRoute, input, output) + req = c.newRequest(op, input, output) output = &CreateRouteOutput{} req.Data = output return @@ -1491,26 +1347,21 @@ func (c *EC2) CreateRoute(input *CreateRouteInput) (*CreateRouteOutput, error) { return out, err } -var opCreateRoute *aws.Operation +const opCreateRouteTable = "CreateRouteTable" // CreateRouteTableRequest generates a request for the CreateRouteTable operation. -func (c *EC2) CreateRouteTableRequest(input *CreateRouteTableInput) (req *aws.Request, output *CreateRouteTableOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateRouteTable == nil { - opCreateRouteTable = &aws.Operation{ - Name: "CreateRouteTable", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateRouteTableRequest(input *CreateRouteTableInput) (req *request.Request, output *CreateRouteTableOutput) { + op := &request.Operation{ + Name: opCreateRouteTable, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateRouteTableInput{} } - req = c.newRequest(opCreateRouteTable, input, output) + req = c.newRequest(op, input, output) output = &CreateRouteTableOutput{} req.Data = output return @@ -1527,26 +1378,21 @@ func (c *EC2) CreateRouteTable(input *CreateRouteTableInput) (*CreateRouteTableO return out, err } -var opCreateRouteTable *aws.Operation +const opCreateSecurityGroup = "CreateSecurityGroup" // CreateSecurityGroupRequest generates a request for the CreateSecurityGroup operation. -func (c *EC2) CreateSecurityGroupRequest(input *CreateSecurityGroupInput) (req *aws.Request, output *CreateSecurityGroupOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateSecurityGroup == nil { - opCreateSecurityGroup = &aws.Operation{ - Name: "CreateSecurityGroup", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateSecurityGroupRequest(input *CreateSecurityGroupInput) (req *request.Request, output *CreateSecurityGroupOutput) { + op := &request.Operation{ + Name: opCreateSecurityGroup, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateSecurityGroupInput{} } - req = c.newRequest(opCreateSecurityGroup, input, output) + req = c.newRequest(op, input, output) output = &CreateSecurityGroupOutput{} req.Data = output return @@ -1585,26 +1431,21 @@ func (c *EC2) CreateSecurityGroup(input *CreateSecurityGroupInput) (*CreateSecur return out, err } -var opCreateSecurityGroup *aws.Operation +const opCreateSnapshot = "CreateSnapshot" // CreateSnapshotRequest generates a request for the CreateSnapshot operation. -func (c *EC2) CreateSnapshotRequest(input *CreateSnapshotInput) (req *aws.Request, output *Snapshot) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateSnapshot == nil { - opCreateSnapshot = &aws.Operation{ - Name: "CreateSnapshot", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateSnapshotRequest(input *CreateSnapshotInput) (req *request.Request, output *Snapshot) { + op := &request.Operation{ + Name: opCreateSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateSnapshotInput{} } - req = c.newRequest(opCreateSnapshot, input, output) + req = c.newRequest(op, input, output) output = &Snapshot{} req.Data = output return @@ -1644,32 +1485,27 @@ func (c *EC2) CreateSnapshot(input *CreateSnapshotInput) (*Snapshot, error) { return out, err } -var opCreateSnapshot *aws.Operation +const opCreateSpotDatafeedSubscription = "CreateSpotDatafeedSubscription" // CreateSpotDatafeedSubscriptionRequest generates a request for the CreateSpotDatafeedSubscription operation. -func (c *EC2) CreateSpotDatafeedSubscriptionRequest(input *CreateSpotDatafeedSubscriptionInput) (req *aws.Request, output *CreateSpotDatafeedSubscriptionOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateSpotDatafeedSubscription == nil { - opCreateSpotDatafeedSubscription = &aws.Operation{ - Name: "CreateSpotDatafeedSubscription", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateSpotDatafeedSubscriptionRequest(input *CreateSpotDatafeedSubscriptionInput) (req *request.Request, output *CreateSpotDatafeedSubscriptionOutput) { + op := &request.Operation{ + Name: opCreateSpotDatafeedSubscription, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateSpotDatafeedSubscriptionInput{} } - req = c.newRequest(opCreateSpotDatafeedSubscription, input, output) + req = c.newRequest(op, input, output) output = &CreateSpotDatafeedSubscriptionOutput{} req.Data = output return } -// Creates a data feed for Spot Instances, enabling you to view Spot Instance +// Creates a data feed for Spot instances, enabling you to view Spot instance // usage logs. You can create one data feed per AWS account. For more information, // see Spot Instance Data Feed (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-data-feeds.html) // in the Amazon Elastic Compute Cloud User Guide. @@ -1679,26 +1515,21 @@ func (c *EC2) CreateSpotDatafeedSubscription(input *CreateSpotDatafeedSubscripti return out, err } -var opCreateSpotDatafeedSubscription *aws.Operation +const opCreateSubnet = "CreateSubnet" // CreateSubnetRequest generates a request for the CreateSubnet operation. -func (c *EC2) CreateSubnetRequest(input *CreateSubnetInput) (req *aws.Request, output *CreateSubnetOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateSubnet == nil { - opCreateSubnet = &aws.Operation{ - Name: "CreateSubnet", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateSubnetRequest(input *CreateSubnetInput) (req *request.Request, output *CreateSubnetOutput) { + op := &request.Operation{ + Name: opCreateSubnet, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateSubnetInput{} } - req = c.newRequest(opCreateSubnet, input, output) + req = c.newRequest(op, input, output) output = &CreateSubnetOutput{} req.Data = output return @@ -1735,26 +1566,21 @@ func (c *EC2) CreateSubnet(input *CreateSubnetInput) (*CreateSubnetOutput, error return out, err } -var opCreateSubnet *aws.Operation +const opCreateTags = "CreateTags" // CreateTagsRequest generates a request for the CreateTags operation. -func (c *EC2) CreateTagsRequest(input *CreateTagsInput) (req *aws.Request, output *CreateTagsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateTags == nil { - opCreateTags = &aws.Operation{ - Name: "CreateTags", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) CreateTagsRequest(input *CreateTagsInput) (req *request.Request, output *CreateTagsOutput) { + op := &request.Operation{ + Name: opCreateTags, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateTagsInput{} } - req = c.newRequest(opCreateTags, input, output) + req = c.newRequest(op, input, output) output = &CreateTagsOutput{} req.Data = output return @@ -1772,27 +1598,64 @@ func (c *EC2) CreateTags(input *CreateTagsInput) (*CreateTagsOutput, error) { return out, err } -var opCreateTags *aws.Operation +const opCreateVolume = "CreateVolume" + +// CreateVolumeRequest generates a request for the CreateVolume operation. +func (c *EC2) CreateVolumeRequest(input *CreateVolumeInput) (req *request.Request, output *Volume) { + op := &request.Operation{ + Name: opCreateVolume, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateVolumeInput{} + } + + req = c.newRequest(op, input, output) + output = &Volume{} + req.Data = output + return +} + +// Creates an EBS volume that can be attached to an instance in the same Availability +// Zone. The volume is created in the regional endpoint that you send the HTTP +// request to. For more information see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html). +// +// You can create a new empty volume or restore a volume from an EBS snapshot. +// Any AWS Marketplace product codes from the snapshot are propagated to the +// volume. +// +// You can create encrypted volumes with the Encrypted parameter. Encrypted +// volumes may only be attached to instances that support Amazon EBS encryption. +// Volumes that are created from encrypted snapshots are also automatically +// encrypted. For more information, see Amazon EBS Encryption (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// For more information, see Creating or Restoring an Amazon EBS Volume (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-creating-volume.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) CreateVolume(input *CreateVolumeInput) (*Volume, error) { + req, out := c.CreateVolumeRequest(input) + err := req.Send() + return out, err +} -// CreateVPCRequest generates a request for the CreateVPC operation. -func (c *EC2) CreateVPCRequest(input *CreateVPCInput) (req *aws.Request, output *CreateVPCOutput) { - oprw.Lock() - defer oprw.Unlock() +const opCreateVpc = "CreateVpc" - if opCreateVPC == nil { - opCreateVPC = &aws.Operation{ - Name: "CreateVpc", - HTTPMethod: "POST", - HTTPPath: "/", - } +// CreateVpcRequest generates a request for the CreateVpc operation. +func (c *EC2) CreateVpcRequest(input *CreateVpcInput) (req *request.Request, output *CreateVpcOutput) { + op := &request.Operation{ + Name: opCreateVpc, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &CreateVPCInput{} + input = &CreateVpcInput{} } - req = c.newRequest(opCreateVPC, input, output) - output = &CreateVPCOutput{} + req = c.newRequest(op, input, output) + output = &CreateVpcOutput{} req.Data = output return } @@ -1808,33 +1671,28 @@ func (c *EC2) CreateVPCRequest(input *CreateVPCInput) (req *aws.Request, output // which includes only a default DNS server that we provide (AmazonProvidedDNS). // For more information about DHCP options, see DHCP Options Sets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) CreateVPC(input *CreateVPCInput) (*CreateVPCOutput, error) { - req, out := c.CreateVPCRequest(input) +func (c *EC2) CreateVpc(input *CreateVpcInput) (*CreateVpcOutput, error) { + req, out := c.CreateVpcRequest(input) err := req.Send() return out, err } -var opCreateVPC *aws.Operation +const opCreateVpcEndpoint = "CreateVpcEndpoint" -// CreateVPCEndpointRequest generates a request for the CreateVPCEndpoint operation. -func (c *EC2) CreateVPCEndpointRequest(input *CreateVPCEndpointInput) (req *aws.Request, output *CreateVPCEndpointOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateVPCEndpoint == nil { - opCreateVPCEndpoint = &aws.Operation{ - Name: "CreateVpcEndpoint", - HTTPMethod: "POST", - HTTPPath: "/", - } +// CreateVpcEndpointRequest generates a request for the CreateVpcEndpoint operation. +func (c *EC2) CreateVpcEndpointRequest(input *CreateVpcEndpointInput) (req *request.Request, output *CreateVpcEndpointOutput) { + op := &request.Operation{ + Name: opCreateVpcEndpoint, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &CreateVPCEndpointInput{} + input = &CreateVpcEndpointInput{} } - req = c.newRequest(opCreateVPCEndpoint, input, output) - output = &CreateVPCEndpointOutput{} + req = c.newRequest(op, input, output) + output = &CreateVpcEndpointOutput{} req.Data = output return } @@ -1846,33 +1704,28 @@ func (c *EC2) CreateVPCEndpointRequest(input *CreateVPCEndpointInput) (req *aws. // the VPC route tables that use the endpoint. // // Currently, only endpoints to Amazon S3 are supported. -func (c *EC2) CreateVPCEndpoint(input *CreateVPCEndpointInput) (*CreateVPCEndpointOutput, error) { - req, out := c.CreateVPCEndpointRequest(input) +func (c *EC2) CreateVpcEndpoint(input *CreateVpcEndpointInput) (*CreateVpcEndpointOutput, error) { + req, out := c.CreateVpcEndpointRequest(input) err := req.Send() return out, err } -var opCreateVPCEndpoint *aws.Operation - -// CreateVPCPeeringConnectionRequest generates a request for the CreateVPCPeeringConnection operation. -func (c *EC2) CreateVPCPeeringConnectionRequest(input *CreateVPCPeeringConnectionInput) (req *aws.Request, output *CreateVPCPeeringConnectionOutput) { - oprw.Lock() - defer oprw.Unlock() +const opCreateVpcPeeringConnection = "CreateVpcPeeringConnection" - if opCreateVPCPeeringConnection == nil { - opCreateVPCPeeringConnection = &aws.Operation{ - Name: "CreateVpcPeeringConnection", - HTTPMethod: "POST", - HTTPPath: "/", - } +// CreateVpcPeeringConnectionRequest generates a request for the CreateVpcPeeringConnection operation. +func (c *EC2) CreateVpcPeeringConnectionRequest(input *CreateVpcPeeringConnectionInput) (req *request.Request, output *CreateVpcPeeringConnectionOutput) { + op := &request.Operation{ + Name: opCreateVpcPeeringConnection, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &CreateVPCPeeringConnectionInput{} + input = &CreateVpcPeeringConnectionInput{} } - req = c.newRequest(opCreateVPCPeeringConnection, input, output) - output = &CreateVPCPeeringConnectionOutput{} + req = c.newRequest(op, input, output) + output = &CreateVpcPeeringConnectionOutput{} req.Data = output return } @@ -1888,33 +1741,28 @@ func (c *EC2) CreateVPCPeeringConnectionRequest(input *CreateVPCPeeringConnectio // // A CreateVpcPeeringConnection request between VPCs with overlapping CIDR // blocks results in the VPC peering connection having a status of failed. -func (c *EC2) CreateVPCPeeringConnection(input *CreateVPCPeeringConnectionInput) (*CreateVPCPeeringConnectionOutput, error) { - req, out := c.CreateVPCPeeringConnectionRequest(input) +func (c *EC2) CreateVpcPeeringConnection(input *CreateVpcPeeringConnectionInput) (*CreateVpcPeeringConnectionOutput, error) { + req, out := c.CreateVpcPeeringConnectionRequest(input) err := req.Send() return out, err } -var opCreateVPCPeeringConnection *aws.Operation +const opCreateVpnConnection = "CreateVpnConnection" -// CreateVPNConnectionRequest generates a request for the CreateVPNConnection operation. -func (c *EC2) CreateVPNConnectionRequest(input *CreateVPNConnectionInput) (req *aws.Request, output *CreateVPNConnectionOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateVPNConnection == nil { - opCreateVPNConnection = &aws.Operation{ - Name: "CreateVpnConnection", - HTTPMethod: "POST", - HTTPPath: "/", - } +// CreateVpnConnectionRequest generates a request for the CreateVpnConnection operation. +func (c *EC2) CreateVpnConnectionRequest(input *CreateVpnConnectionInput) (req *request.Request, output *CreateVpnConnectionOutput) { + op := &request.Operation{ + Name: opCreateVpnConnection, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &CreateVPNConnectionInput{} + input = &CreateVpnConnectionInput{} } - req = c.newRequest(opCreateVPNConnection, input, output) - output = &CreateVPNConnectionOutput{} + req = c.newRequest(op, input, output) + output = &CreateVpnConnectionOutput{} req.Data = output return } @@ -1936,33 +1784,28 @@ func (c *EC2) CreateVPNConnectionRequest(input *CreateVPNConnectionInput) (req * // For more information about VPN connections, see Adding a Hardware Virtual // Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) CreateVPNConnection(input *CreateVPNConnectionInput) (*CreateVPNConnectionOutput, error) { - req, out := c.CreateVPNConnectionRequest(input) +func (c *EC2) CreateVpnConnection(input *CreateVpnConnectionInput) (*CreateVpnConnectionOutput, error) { + req, out := c.CreateVpnConnectionRequest(input) err := req.Send() return out, err } -var opCreateVPNConnection *aws.Operation - -// CreateVPNConnectionRouteRequest generates a request for the CreateVPNConnectionRoute operation. -func (c *EC2) CreateVPNConnectionRouteRequest(input *CreateVPNConnectionRouteInput) (req *aws.Request, output *CreateVPNConnectionRouteOutput) { - oprw.Lock() - defer oprw.Unlock() +const opCreateVpnConnectionRoute = "CreateVpnConnectionRoute" - if opCreateVPNConnectionRoute == nil { - opCreateVPNConnectionRoute = &aws.Operation{ - Name: "CreateVpnConnectionRoute", - HTTPMethod: "POST", - HTTPPath: "/", - } +// CreateVpnConnectionRouteRequest generates a request for the CreateVpnConnectionRoute operation. +func (c *EC2) CreateVpnConnectionRouteRequest(input *CreateVpnConnectionRouteInput) (req *request.Request, output *CreateVpnConnectionRouteOutput) { + op := &request.Operation{ + Name: opCreateVpnConnectionRoute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &CreateVPNConnectionRouteInput{} + input = &CreateVpnConnectionRouteInput{} } - req = c.newRequest(opCreateVPNConnectionRoute, input, output) - output = &CreateVPNConnectionRouteOutput{} + req = c.newRequest(op, input, output) + output = &CreateVpnConnectionRouteOutput{} req.Data = output return } @@ -1975,33 +1818,28 @@ func (c *EC2) CreateVPNConnectionRouteRequest(input *CreateVPNConnectionRouteInp // For more information about VPN connections, see Adding a Hardware Virtual // Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) CreateVPNConnectionRoute(input *CreateVPNConnectionRouteInput) (*CreateVPNConnectionRouteOutput, error) { - req, out := c.CreateVPNConnectionRouteRequest(input) +func (c *EC2) CreateVpnConnectionRoute(input *CreateVpnConnectionRouteInput) (*CreateVpnConnectionRouteOutput, error) { + req, out := c.CreateVpnConnectionRouteRequest(input) err := req.Send() return out, err } -var opCreateVPNConnectionRoute *aws.Operation +const opCreateVpnGateway = "CreateVpnGateway" -// CreateVPNGatewayRequest generates a request for the CreateVPNGateway operation. -func (c *EC2) CreateVPNGatewayRequest(input *CreateVPNGatewayInput) (req *aws.Request, output *CreateVPNGatewayOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateVPNGateway == nil { - opCreateVPNGateway = &aws.Operation{ - Name: "CreateVpnGateway", - HTTPMethod: "POST", - HTTPPath: "/", - } +// CreateVpnGatewayRequest generates a request for the CreateVpnGateway operation. +func (c *EC2) CreateVpnGatewayRequest(input *CreateVpnGatewayInput) (req *request.Request, output *CreateVpnGatewayOutput) { + op := &request.Operation{ + Name: opCreateVpnGateway, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &CreateVPNGatewayInput{} + input = &CreateVpnGatewayInput{} } - req = c.newRequest(opCreateVPNGateway, input, output) - output = &CreateVPNGatewayOutput{} + req = c.newRequest(op, input, output) + output = &CreateVpnGatewayOutput{} req.Data = output return } @@ -2013,147 +1851,112 @@ func (c *EC2) CreateVPNGatewayRequest(input *CreateVPNGatewayInput) (req *aws.Re // For more information about virtual private gateways, see Adding a Hardware // Virtual Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) CreateVPNGateway(input *CreateVPNGatewayInput) (*CreateVPNGatewayOutput, error) { - req, out := c.CreateVPNGatewayRequest(input) +func (c *EC2) CreateVpnGateway(input *CreateVpnGatewayInput) (*CreateVpnGatewayOutput, error) { + req, out := c.CreateVpnGatewayRequest(input) err := req.Send() return out, err } -var opCreateVPNGateway *aws.Operation - -// CreateVolumeRequest generates a request for the CreateVolume operation. -func (c *EC2) CreateVolumeRequest(input *CreateVolumeInput) (req *aws.Request, output *Volume) { - oprw.Lock() - defer oprw.Unlock() +const opDeleteCustomerGateway = "DeleteCustomerGateway" - if opCreateVolume == nil { - opCreateVolume = &aws.Operation{ - Name: "CreateVolume", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DeleteCustomerGatewayRequest generates a request for the DeleteCustomerGateway operation. +func (c *EC2) DeleteCustomerGatewayRequest(input *DeleteCustomerGatewayInput) (req *request.Request, output *DeleteCustomerGatewayOutput) { + op := &request.Operation{ + Name: opDeleteCustomerGateway, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &CreateVolumeInput{} + input = &DeleteCustomerGatewayInput{} } - req = c.newRequest(opCreateVolume, input, output) - output = &Volume{} + req = c.newRequest(op, input, output) + output = &DeleteCustomerGatewayOutput{} req.Data = output return } -// Creates an EBS volume that can be attached to an instance in the same Availability -// Zone. The volume is created in the regional endpoint that you send the HTTP -// request to. For more information see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html). -// -// You can create a new empty volume or restore a volume from an EBS snapshot. -// Any AWS Marketplace product codes from the snapshot are propagated to the -// volume. -// -// You can create encrypted volumes with the Encrypted parameter. Encrypted -// volumes may only be attached to instances that support Amazon EBS encryption. -// Volumes that are created from encrypted snapshots are also automatically -// encrypted. For more information, see Amazon EBS Encryption (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) -// in the Amazon Elastic Compute Cloud User Guide. -// -// For more information, see Creating or Restoring an Amazon EBS Volume (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-creating-volume.html) -// in the Amazon Elastic Compute Cloud User Guide. -func (c *EC2) CreateVolume(input *CreateVolumeInput) (*Volume, error) { - req, out := c.CreateVolumeRequest(input) +// Deletes the specified customer gateway. You must delete the VPN connection +// before you can delete the customer gateway. +func (c *EC2) DeleteCustomerGateway(input *DeleteCustomerGatewayInput) (*DeleteCustomerGatewayOutput, error) { + req, out := c.DeleteCustomerGatewayRequest(input) err := req.Send() return out, err } -var opCreateVolume *aws.Operation +const opDeleteDhcpOptions = "DeleteDhcpOptions" -// DeleteCustomerGatewayRequest generates a request for the DeleteCustomerGateway operation. -func (c *EC2) DeleteCustomerGatewayRequest(input *DeleteCustomerGatewayInput) (req *aws.Request, output *DeleteCustomerGatewayOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteCustomerGateway == nil { - opDeleteCustomerGateway = &aws.Operation{ - Name: "DeleteCustomerGateway", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DeleteDhcpOptionsRequest generates a request for the DeleteDhcpOptions operation. +func (c *EC2) DeleteDhcpOptionsRequest(input *DeleteDhcpOptionsInput) (req *request.Request, output *DeleteDhcpOptionsOutput) { + op := &request.Operation{ + Name: opDeleteDhcpOptions, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DeleteCustomerGatewayInput{} + input = &DeleteDhcpOptionsInput{} } - req = c.newRequest(opDeleteCustomerGateway, input, output) - output = &DeleteCustomerGatewayOutput{} + req = c.newRequest(op, input, output) + output = &DeleteDhcpOptionsOutput{} req.Data = output return } -// Deletes the specified customer gateway. You must delete the VPN connection -// before you can delete the customer gateway. -func (c *EC2) DeleteCustomerGateway(input *DeleteCustomerGatewayInput) (*DeleteCustomerGatewayOutput, error) { - req, out := c.DeleteCustomerGatewayRequest(input) +// Deletes the specified set of DHCP options. You must disassociate the set +// of DHCP options before you can delete it. You can disassociate the set of +// DHCP options by associating either a new set of options or the default set +// of options with the VPC. +func (c *EC2) DeleteDhcpOptions(input *DeleteDhcpOptionsInput) (*DeleteDhcpOptionsOutput, error) { + req, out := c.DeleteDhcpOptionsRequest(input) err := req.Send() return out, err } -var opDeleteCustomerGateway *aws.Operation +const opDeleteFlowLogs = "DeleteFlowLogs" -// DeleteDHCPOptionsRequest generates a request for the DeleteDHCPOptions operation. -func (c *EC2) DeleteDHCPOptionsRequest(input *DeleteDHCPOptionsInput) (req *aws.Request, output *DeleteDHCPOptionsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteDHCPOptions == nil { - opDeleteDHCPOptions = &aws.Operation{ - Name: "DeleteDhcpOptions", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DeleteFlowLogsRequest generates a request for the DeleteFlowLogs operation. +func (c *EC2) DeleteFlowLogsRequest(input *DeleteFlowLogsInput) (req *request.Request, output *DeleteFlowLogsOutput) { + op := &request.Operation{ + Name: opDeleteFlowLogs, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DeleteDHCPOptionsInput{} + input = &DeleteFlowLogsInput{} } - req = c.newRequest(opDeleteDHCPOptions, input, output) - output = &DeleteDHCPOptionsOutput{} + req = c.newRequest(op, input, output) + output = &DeleteFlowLogsOutput{} req.Data = output return } -// Deletes the specified set of DHCP options. You must disassociate the set -// of DHCP options before you can delete it. You can disassociate the set of -// DHCP options by associating either a new set of options or the default set -// of options with the VPC. -func (c *EC2) DeleteDHCPOptions(input *DeleteDHCPOptionsInput) (*DeleteDHCPOptionsOutput, error) { - req, out := c.DeleteDHCPOptionsRequest(input) +// Deletes one or more flow logs. +func (c *EC2) DeleteFlowLogs(input *DeleteFlowLogsInput) (*DeleteFlowLogsOutput, error) { + req, out := c.DeleteFlowLogsRequest(input) err := req.Send() return out, err } -var opDeleteDHCPOptions *aws.Operation +const opDeleteInternetGateway = "DeleteInternetGateway" // DeleteInternetGatewayRequest generates a request for the DeleteInternetGateway operation. -func (c *EC2) DeleteInternetGatewayRequest(input *DeleteInternetGatewayInput) (req *aws.Request, output *DeleteInternetGatewayOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteInternetGateway == nil { - opDeleteInternetGateway = &aws.Operation{ - Name: "DeleteInternetGateway", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeleteInternetGatewayRequest(input *DeleteInternetGatewayInput) (req *request.Request, output *DeleteInternetGatewayOutput) { + op := &request.Operation{ + Name: opDeleteInternetGateway, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteInternetGatewayInput{} } - req = c.newRequest(opDeleteInternetGateway, input, output) + req = c.newRequest(op, input, output) output = &DeleteInternetGatewayOutput{} req.Data = output return @@ -2167,26 +1970,21 @@ func (c *EC2) DeleteInternetGateway(input *DeleteInternetGatewayInput) (*DeleteI return out, err } -var opDeleteInternetGateway *aws.Operation +const opDeleteKeyPair = "DeleteKeyPair" // DeleteKeyPairRequest generates a request for the DeleteKeyPair operation. -func (c *EC2) DeleteKeyPairRequest(input *DeleteKeyPairInput) (req *aws.Request, output *DeleteKeyPairOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteKeyPair == nil { - opDeleteKeyPair = &aws.Operation{ - Name: "DeleteKeyPair", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeleteKeyPairRequest(input *DeleteKeyPairInput) (req *request.Request, output *DeleteKeyPairOutput) { + op := &request.Operation{ + Name: opDeleteKeyPair, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteKeyPairInput{} } - req = c.newRequest(opDeleteKeyPair, input, output) + req = c.newRequest(op, input, output) output = &DeleteKeyPairOutput{} req.Data = output return @@ -2199,92 +1997,77 @@ func (c *EC2) DeleteKeyPair(input *DeleteKeyPairInput) (*DeleteKeyPairOutput, er return out, err } -var opDeleteKeyPair *aws.Operation - -// DeleteNetworkACLRequest generates a request for the DeleteNetworkACL operation. -func (c *EC2) DeleteNetworkACLRequest(input *DeleteNetworkACLInput) (req *aws.Request, output *DeleteNetworkACLOutput) { - oprw.Lock() - defer oprw.Unlock() +const opDeleteNetworkAcl = "DeleteNetworkAcl" - if opDeleteNetworkACL == nil { - opDeleteNetworkACL = &aws.Operation{ - Name: "DeleteNetworkAcl", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DeleteNetworkAclRequest generates a request for the DeleteNetworkAcl operation. +func (c *EC2) DeleteNetworkAclRequest(input *DeleteNetworkAclInput) (req *request.Request, output *DeleteNetworkAclOutput) { + op := &request.Operation{ + Name: opDeleteNetworkAcl, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DeleteNetworkACLInput{} + input = &DeleteNetworkAclInput{} } - req = c.newRequest(opDeleteNetworkACL, input, output) - output = &DeleteNetworkACLOutput{} + req = c.newRequest(op, input, output) + output = &DeleteNetworkAclOutput{} req.Data = output return } // Deletes the specified network ACL. You can't delete the ACL if it's associated // with any subnets. You can't delete the default network ACL. -func (c *EC2) DeleteNetworkACL(input *DeleteNetworkACLInput) (*DeleteNetworkACLOutput, error) { - req, out := c.DeleteNetworkACLRequest(input) +func (c *EC2) DeleteNetworkAcl(input *DeleteNetworkAclInput) (*DeleteNetworkAclOutput, error) { + req, out := c.DeleteNetworkAclRequest(input) err := req.Send() return out, err } -var opDeleteNetworkACL *aws.Operation +const opDeleteNetworkAclEntry = "DeleteNetworkAclEntry" -// DeleteNetworkACLEntryRequest generates a request for the DeleteNetworkACLEntry operation. -func (c *EC2) DeleteNetworkACLEntryRequest(input *DeleteNetworkACLEntryInput) (req *aws.Request, output *DeleteNetworkACLEntryOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteNetworkACLEntry == nil { - opDeleteNetworkACLEntry = &aws.Operation{ - Name: "DeleteNetworkAclEntry", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DeleteNetworkAclEntryRequest generates a request for the DeleteNetworkAclEntry operation. +func (c *EC2) DeleteNetworkAclEntryRequest(input *DeleteNetworkAclEntryInput) (req *request.Request, output *DeleteNetworkAclEntryOutput) { + op := &request.Operation{ + Name: opDeleteNetworkAclEntry, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DeleteNetworkACLEntryInput{} + input = &DeleteNetworkAclEntryInput{} } - req = c.newRequest(opDeleteNetworkACLEntry, input, output) - output = &DeleteNetworkACLEntryOutput{} + req = c.newRequest(op, input, output) + output = &DeleteNetworkAclEntryOutput{} req.Data = output return } // Deletes the specified ingress or egress entry (rule) from the specified network // ACL. -func (c *EC2) DeleteNetworkACLEntry(input *DeleteNetworkACLEntryInput) (*DeleteNetworkACLEntryOutput, error) { - req, out := c.DeleteNetworkACLEntryRequest(input) +func (c *EC2) DeleteNetworkAclEntry(input *DeleteNetworkAclEntryInput) (*DeleteNetworkAclEntryOutput, error) { + req, out := c.DeleteNetworkAclEntryRequest(input) err := req.Send() return out, err } -var opDeleteNetworkACLEntry *aws.Operation +const opDeleteNetworkInterface = "DeleteNetworkInterface" // DeleteNetworkInterfaceRequest generates a request for the DeleteNetworkInterface operation. -func (c *EC2) DeleteNetworkInterfaceRequest(input *DeleteNetworkInterfaceInput) (req *aws.Request, output *DeleteNetworkInterfaceOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteNetworkInterface == nil { - opDeleteNetworkInterface = &aws.Operation{ - Name: "DeleteNetworkInterface", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeleteNetworkInterfaceRequest(input *DeleteNetworkInterfaceInput) (req *request.Request, output *DeleteNetworkInterfaceOutput) { + op := &request.Operation{ + Name: opDeleteNetworkInterface, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteNetworkInterfaceInput{} } - req = c.newRequest(opDeleteNetworkInterface, input, output) + req = c.newRequest(op, input, output) output = &DeleteNetworkInterfaceOutput{} req.Data = output return @@ -2298,26 +2081,21 @@ func (c *EC2) DeleteNetworkInterface(input *DeleteNetworkInterfaceInput) (*Delet return out, err } -var opDeleteNetworkInterface *aws.Operation +const opDeletePlacementGroup = "DeletePlacementGroup" // DeletePlacementGroupRequest generates a request for the DeletePlacementGroup operation. -func (c *EC2) DeletePlacementGroupRequest(input *DeletePlacementGroupInput) (req *aws.Request, output *DeletePlacementGroupOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeletePlacementGroup == nil { - opDeletePlacementGroup = &aws.Operation{ - Name: "DeletePlacementGroup", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeletePlacementGroupRequest(input *DeletePlacementGroupInput) (req *request.Request, output *DeletePlacementGroupOutput) { + op := &request.Operation{ + Name: opDeletePlacementGroup, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeletePlacementGroupInput{} } - req = c.newRequest(opDeletePlacementGroup, input, output) + req = c.newRequest(op, input, output) output = &DeletePlacementGroupOutput{} req.Data = output return @@ -2333,26 +2111,21 @@ func (c *EC2) DeletePlacementGroup(input *DeletePlacementGroupInput) (*DeletePla return out, err } -var opDeletePlacementGroup *aws.Operation +const opDeleteRoute = "DeleteRoute" // DeleteRouteRequest generates a request for the DeleteRoute operation. -func (c *EC2) DeleteRouteRequest(input *DeleteRouteInput) (req *aws.Request, output *DeleteRouteOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteRoute == nil { - opDeleteRoute = &aws.Operation{ - Name: "DeleteRoute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeleteRouteRequest(input *DeleteRouteInput) (req *request.Request, output *DeleteRouteOutput) { + op := &request.Operation{ + Name: opDeleteRoute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteRouteInput{} } - req = c.newRequest(opDeleteRoute, input, output) + req = c.newRequest(op, input, output) output = &DeleteRouteOutput{} req.Data = output return @@ -2365,26 +2138,21 @@ func (c *EC2) DeleteRoute(input *DeleteRouteInput) (*DeleteRouteOutput, error) { return out, err } -var opDeleteRoute *aws.Operation +const opDeleteRouteTable = "DeleteRouteTable" // DeleteRouteTableRequest generates a request for the DeleteRouteTable operation. -func (c *EC2) DeleteRouteTableRequest(input *DeleteRouteTableInput) (req *aws.Request, output *DeleteRouteTableOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteRouteTable == nil { - opDeleteRouteTable = &aws.Operation{ - Name: "DeleteRouteTable", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeleteRouteTableRequest(input *DeleteRouteTableInput) (req *request.Request, output *DeleteRouteTableOutput) { + op := &request.Operation{ + Name: opDeleteRouteTable, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteRouteTableInput{} } - req = c.newRequest(opDeleteRouteTable, input, output) + req = c.newRequest(op, input, output) output = &DeleteRouteTableOutput{} req.Data = output return @@ -2399,26 +2167,21 @@ func (c *EC2) DeleteRouteTable(input *DeleteRouteTableInput) (*DeleteRouteTableO return out, err } -var opDeleteRouteTable *aws.Operation +const opDeleteSecurityGroup = "DeleteSecurityGroup" // DeleteSecurityGroupRequest generates a request for the DeleteSecurityGroup operation. -func (c *EC2) DeleteSecurityGroupRequest(input *DeleteSecurityGroupInput) (req *aws.Request, output *DeleteSecurityGroupOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteSecurityGroup == nil { - opDeleteSecurityGroup = &aws.Operation{ - Name: "DeleteSecurityGroup", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeleteSecurityGroupRequest(input *DeleteSecurityGroupInput) (req *request.Request, output *DeleteSecurityGroupOutput) { + op := &request.Operation{ + Name: opDeleteSecurityGroup, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteSecurityGroupInput{} } - req = c.newRequest(opDeleteSecurityGroup, input, output) + req = c.newRequest(op, input, output) output = &DeleteSecurityGroupOutput{} req.Data = output return @@ -2435,26 +2198,21 @@ func (c *EC2) DeleteSecurityGroup(input *DeleteSecurityGroupInput) (*DeleteSecur return out, err } -var opDeleteSecurityGroup *aws.Operation +const opDeleteSnapshot = "DeleteSnapshot" // DeleteSnapshotRequest generates a request for the DeleteSnapshot operation. -func (c *EC2) DeleteSnapshotRequest(input *DeleteSnapshotInput) (req *aws.Request, output *DeleteSnapshotOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteSnapshot == nil { - opDeleteSnapshot = &aws.Operation{ - Name: "DeleteSnapshot", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeleteSnapshotRequest(input *DeleteSnapshotInput) (req *request.Request, output *DeleteSnapshotOutput) { + op := &request.Operation{ + Name: opDeleteSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteSnapshotInput{} } - req = c.newRequest(opDeleteSnapshot, input, output) + req = c.newRequest(op, input, output) output = &DeleteSnapshotOutput{} req.Data = output return @@ -2481,60 +2239,48 @@ func (c *EC2) DeleteSnapshot(input *DeleteSnapshotInput) (*DeleteSnapshotOutput, return out, err } -var opDeleteSnapshot *aws.Operation +const opDeleteSpotDatafeedSubscription = "DeleteSpotDatafeedSubscription" // DeleteSpotDatafeedSubscriptionRequest generates a request for the DeleteSpotDatafeedSubscription operation. -func (c *EC2) DeleteSpotDatafeedSubscriptionRequest(input *DeleteSpotDatafeedSubscriptionInput) (req *aws.Request, output *DeleteSpotDatafeedSubscriptionOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteSpotDatafeedSubscription == nil { - opDeleteSpotDatafeedSubscription = &aws.Operation{ - Name: "DeleteSpotDatafeedSubscription", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeleteSpotDatafeedSubscriptionRequest(input *DeleteSpotDatafeedSubscriptionInput) (req *request.Request, output *DeleteSpotDatafeedSubscriptionOutput) { + op := &request.Operation{ + Name: opDeleteSpotDatafeedSubscription, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteSpotDatafeedSubscriptionInput{} } - req = c.newRequest(opDeleteSpotDatafeedSubscription, input, output) + req = c.newRequest(op, input, output) output = &DeleteSpotDatafeedSubscriptionOutput{} req.Data = output return } -// Deletes the data feed for Spot Instances. For more information, see Spot -// Instance Data Feed (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-data-feeds.html) -// in the Amazon Elastic Compute Cloud User Guide. +// Deletes the data feed for Spot instances. func (c *EC2) DeleteSpotDatafeedSubscription(input *DeleteSpotDatafeedSubscriptionInput) (*DeleteSpotDatafeedSubscriptionOutput, error) { req, out := c.DeleteSpotDatafeedSubscriptionRequest(input) err := req.Send() return out, err } -var opDeleteSpotDatafeedSubscription *aws.Operation +const opDeleteSubnet = "DeleteSubnet" // DeleteSubnetRequest generates a request for the DeleteSubnet operation. -func (c *EC2) DeleteSubnetRequest(input *DeleteSubnetInput) (req *aws.Request, output *DeleteSubnetOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteSubnet == nil { - opDeleteSubnet = &aws.Operation{ - Name: "DeleteSubnet", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeleteSubnetRequest(input *DeleteSubnetInput) (req *request.Request, output *DeleteSubnetOutput) { + op := &request.Operation{ + Name: opDeleteSubnet, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteSubnetInput{} } - req = c.newRequest(opDeleteSubnet, input, output) + req = c.newRequest(op, input, output) output = &DeleteSubnetOutput{} req.Data = output return @@ -2548,26 +2294,21 @@ func (c *EC2) DeleteSubnet(input *DeleteSubnetInput) (*DeleteSubnetOutput, error return out, err } -var opDeleteSubnet *aws.Operation +const opDeleteTags = "DeleteTags" // DeleteTagsRequest generates a request for the DeleteTags operation. -func (c *EC2) DeleteTagsRequest(input *DeleteTagsInput) (req *aws.Request, output *DeleteTagsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteTags == nil { - opDeleteTags = &aws.Operation{ - Name: "DeleteTags", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeleteTagsRequest(input *DeleteTagsInput) (req *request.Request, output *DeleteTagsOutput) { + op := &request.Operation{ + Name: opDeleteTags, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteTagsInput{} } - req = c.newRequest(opDeleteTags, input, output) + req = c.newRequest(op, input, output) output = &DeleteTagsOutput{} req.Data = output return @@ -2584,27 +2325,55 @@ func (c *EC2) DeleteTags(input *DeleteTagsInput) (*DeleteTagsOutput, error) { return out, err } -var opDeleteTags *aws.Operation +const opDeleteVolume = "DeleteVolume" -// DeleteVPCRequest generates a request for the DeleteVPC operation. -func (c *EC2) DeleteVPCRequest(input *DeleteVPCInput) (req *aws.Request, output *DeleteVPCOutput) { - oprw.Lock() - defer oprw.Unlock() +// DeleteVolumeRequest generates a request for the DeleteVolume operation. +func (c *EC2) DeleteVolumeRequest(input *DeleteVolumeInput) (req *request.Request, output *DeleteVolumeOutput) { + op := &request.Operation{ + Name: opDeleteVolume, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteVolumeInput{} + } + + req = c.newRequest(op, input, output) + output = &DeleteVolumeOutput{} + req.Data = output + return +} + +// Deletes the specified EBS volume. The volume must be in the available state +// (not attached to an instance). +// +// The volume may remain in the deleting state for several minutes. +// +// For more information, see Deleting an Amazon EBS Volume (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-deleting-volume.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DeleteVolume(input *DeleteVolumeInput) (*DeleteVolumeOutput, error) { + req, out := c.DeleteVolumeRequest(input) + err := req.Send() + return out, err +} - if opDeleteVPC == nil { - opDeleteVPC = &aws.Operation{ - Name: "DeleteVpc", - HTTPMethod: "POST", - HTTPPath: "/", - } +const opDeleteVpc = "DeleteVpc" + +// DeleteVpcRequest generates a request for the DeleteVpc operation. +func (c *EC2) DeleteVpcRequest(input *DeleteVpcInput) (req *request.Request, output *DeleteVpcOutput) { + op := &request.Operation{ + Name: opDeleteVpc, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DeleteVPCInput{} + input = &DeleteVpcInput{} } - req = c.newRequest(opDeleteVPC, input, output) - output = &DeleteVPCOutput{} + req = c.newRequest(op, input, output) + output = &DeleteVpcOutput{} req.Data = output return } @@ -2614,66 +2383,56 @@ func (c *EC2) DeleteVPCRequest(input *DeleteVPCInput) (req *aws.Request, output // must terminate all instances running in the VPC, delete all security groups // associated with the VPC (except the default one), delete all route tables // associated with the VPC (except the default one), and so on. -func (c *EC2) DeleteVPC(input *DeleteVPCInput) (*DeleteVPCOutput, error) { - req, out := c.DeleteVPCRequest(input) +func (c *EC2) DeleteVpc(input *DeleteVpcInput) (*DeleteVpcOutput, error) { + req, out := c.DeleteVpcRequest(input) err := req.Send() return out, err } -var opDeleteVPC *aws.Operation - -// DeleteVPCEndpointsRequest generates a request for the DeleteVPCEndpoints operation. -func (c *EC2) DeleteVPCEndpointsRequest(input *DeleteVPCEndpointsInput) (req *aws.Request, output *DeleteVPCEndpointsOutput) { - oprw.Lock() - defer oprw.Unlock() +const opDeleteVpcEndpoints = "DeleteVpcEndpoints" - if opDeleteVPCEndpoints == nil { - opDeleteVPCEndpoints = &aws.Operation{ - Name: "DeleteVpcEndpoints", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DeleteVpcEndpointsRequest generates a request for the DeleteVpcEndpoints operation. +func (c *EC2) DeleteVpcEndpointsRequest(input *DeleteVpcEndpointsInput) (req *request.Request, output *DeleteVpcEndpointsOutput) { + op := &request.Operation{ + Name: opDeleteVpcEndpoints, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DeleteVPCEndpointsInput{} + input = &DeleteVpcEndpointsInput{} } - req = c.newRequest(opDeleteVPCEndpoints, input, output) - output = &DeleteVPCEndpointsOutput{} + req = c.newRequest(op, input, output) + output = &DeleteVpcEndpointsOutput{} req.Data = output return } // Deletes one or more specified VPC endpoints. Deleting the endpoint also deletes // the endpoint routes in the route tables that were associated with the endpoint. -func (c *EC2) DeleteVPCEndpoints(input *DeleteVPCEndpointsInput) (*DeleteVPCEndpointsOutput, error) { - req, out := c.DeleteVPCEndpointsRequest(input) +func (c *EC2) DeleteVpcEndpoints(input *DeleteVpcEndpointsInput) (*DeleteVpcEndpointsOutput, error) { + req, out := c.DeleteVpcEndpointsRequest(input) err := req.Send() return out, err } -var opDeleteVPCEndpoints *aws.Operation +const opDeleteVpcPeeringConnection = "DeleteVpcPeeringConnection" -// DeleteVPCPeeringConnectionRequest generates a request for the DeleteVPCPeeringConnection operation. -func (c *EC2) DeleteVPCPeeringConnectionRequest(input *DeleteVPCPeeringConnectionInput) (req *aws.Request, output *DeleteVPCPeeringConnectionOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteVPCPeeringConnection == nil { - opDeleteVPCPeeringConnection = &aws.Operation{ - Name: "DeleteVpcPeeringConnection", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DeleteVpcPeeringConnectionRequest generates a request for the DeleteVpcPeeringConnection operation. +func (c *EC2) DeleteVpcPeeringConnectionRequest(input *DeleteVpcPeeringConnectionInput) (req *request.Request, output *DeleteVpcPeeringConnectionOutput) { + op := &request.Operation{ + Name: opDeleteVpcPeeringConnection, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DeleteVPCPeeringConnectionInput{} + input = &DeleteVpcPeeringConnectionInput{} } - req = c.newRequest(opDeleteVPCPeeringConnection, input, output) - output = &DeleteVPCPeeringConnectionOutput{} + req = c.newRequest(op, input, output) + output = &DeleteVpcPeeringConnectionOutput{} req.Data = output return } @@ -2682,33 +2441,28 @@ func (c *EC2) DeleteVPCPeeringConnectionRequest(input *DeleteVPCPeeringConnectio // the owner of the peer VPC can delete the VPC peering connection if it's in // the active state. The owner of the requester VPC can delete a VPC peering // connection in the pending-acceptance state. -func (c *EC2) DeleteVPCPeeringConnection(input *DeleteVPCPeeringConnectionInput) (*DeleteVPCPeeringConnectionOutput, error) { - req, out := c.DeleteVPCPeeringConnectionRequest(input) +func (c *EC2) DeleteVpcPeeringConnection(input *DeleteVpcPeeringConnectionInput) (*DeleteVpcPeeringConnectionOutput, error) { + req, out := c.DeleteVpcPeeringConnectionRequest(input) err := req.Send() return out, err } -var opDeleteVPCPeeringConnection *aws.Operation - -// DeleteVPNConnectionRequest generates a request for the DeleteVPNConnection operation. -func (c *EC2) DeleteVPNConnectionRequest(input *DeleteVPNConnectionInput) (req *aws.Request, output *DeleteVPNConnectionOutput) { - oprw.Lock() - defer oprw.Unlock() +const opDeleteVpnConnection = "DeleteVpnConnection" - if opDeleteVPNConnection == nil { - opDeleteVPNConnection = &aws.Operation{ - Name: "DeleteVpnConnection", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DeleteVpnConnectionRequest generates a request for the DeleteVpnConnection operation. +func (c *EC2) DeleteVpnConnectionRequest(input *DeleteVpnConnectionInput) (req *request.Request, output *DeleteVpnConnectionOutput) { + op := &request.Operation{ + Name: opDeleteVpnConnection, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DeleteVPNConnectionInput{} + input = &DeleteVpnConnectionInput{} } - req = c.newRequest(opDeleteVPNConnection, input, output) - output = &DeleteVPNConnectionOutput{} + req = c.newRequest(op, input, output) + output = &DeleteVpnConnectionOutput{} req.Data = output return } @@ -2723,33 +2477,28 @@ func (c *EC2) DeleteVPNConnectionRequest(input *DeleteVPNConnectionInput) (req * // or virtual private gateway. If you create a new VPN connection, you must // reconfigure the customer gateway using the new configuration information // returned with the new VPN connection ID. -func (c *EC2) DeleteVPNConnection(input *DeleteVPNConnectionInput) (*DeleteVPNConnectionOutput, error) { - req, out := c.DeleteVPNConnectionRequest(input) +func (c *EC2) DeleteVpnConnection(input *DeleteVpnConnectionInput) (*DeleteVpnConnectionOutput, error) { + req, out := c.DeleteVpnConnectionRequest(input) err := req.Send() return out, err } -var opDeleteVPNConnection *aws.Operation +const opDeleteVpnConnectionRoute = "DeleteVpnConnectionRoute" -// DeleteVPNConnectionRouteRequest generates a request for the DeleteVPNConnectionRoute operation. -func (c *EC2) DeleteVPNConnectionRouteRequest(input *DeleteVPNConnectionRouteInput) (req *aws.Request, output *DeleteVPNConnectionRouteOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteVPNConnectionRoute == nil { - opDeleteVPNConnectionRoute = &aws.Operation{ - Name: "DeleteVpnConnectionRoute", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DeleteVpnConnectionRouteRequest generates a request for the DeleteVpnConnectionRoute operation. +func (c *EC2) DeleteVpnConnectionRouteRequest(input *DeleteVpnConnectionRouteInput) (req *request.Request, output *DeleteVpnConnectionRouteOutput) { + op := &request.Operation{ + Name: opDeleteVpnConnectionRoute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DeleteVPNConnectionRouteInput{} + input = &DeleteVpnConnectionRouteInput{} } - req = c.newRequest(opDeleteVPNConnectionRoute, input, output) - output = &DeleteVPNConnectionRouteOutput{} + req = c.newRequest(op, input, output) + output = &DeleteVpnConnectionRouteOutput{} req.Data = output return } @@ -2758,33 +2507,28 @@ func (c *EC2) DeleteVPNConnectionRouteRequest(input *DeleteVPNConnectionRouteInp // an existing virtual private gateway and a VPN customer gateway. The static // route allows traffic to be routed from the virtual private gateway to the // VPN customer gateway. -func (c *EC2) DeleteVPNConnectionRoute(input *DeleteVPNConnectionRouteInput) (*DeleteVPNConnectionRouteOutput, error) { - req, out := c.DeleteVPNConnectionRouteRequest(input) +func (c *EC2) DeleteVpnConnectionRoute(input *DeleteVpnConnectionRouteInput) (*DeleteVpnConnectionRouteOutput, error) { + req, out := c.DeleteVpnConnectionRouteRequest(input) err := req.Send() return out, err } -var opDeleteVPNConnectionRoute *aws.Operation - -// DeleteVPNGatewayRequest generates a request for the DeleteVPNGateway operation. -func (c *EC2) DeleteVPNGatewayRequest(input *DeleteVPNGatewayInput) (req *aws.Request, output *DeleteVPNGatewayOutput) { - oprw.Lock() - defer oprw.Unlock() +const opDeleteVpnGateway = "DeleteVpnGateway" - if opDeleteVPNGateway == nil { - opDeleteVPNGateway = &aws.Operation{ - Name: "DeleteVpnGateway", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DeleteVpnGatewayRequest generates a request for the DeleteVpnGateway operation. +func (c *EC2) DeleteVpnGatewayRequest(input *DeleteVpnGatewayInput) (req *request.Request, output *DeleteVpnGatewayOutput) { + op := &request.Operation{ + Name: opDeleteVpnGateway, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DeleteVPNGatewayInput{} + input = &DeleteVpnGatewayInput{} } - req = c.newRequest(opDeleteVPNGateway, input, output) - output = &DeleteVPNGatewayOutput{} + req = c.newRequest(op, input, output) + output = &DeleteVpnGatewayOutput{} req.Data = output return } @@ -2794,70 +2538,27 @@ func (c *EC2) DeleteVPNGatewayRequest(input *DeleteVPNGatewayInput) (req *aws.Re // VPN connection. Note that you don't need to delete the virtual private gateway // if you plan to delete and recreate the VPN connection between your VPC and // your network. -func (c *EC2) DeleteVPNGateway(input *DeleteVPNGatewayInput) (*DeleteVPNGatewayOutput, error) { - req, out := c.DeleteVPNGatewayRequest(input) - err := req.Send() - return out, err -} - -var opDeleteVPNGateway *aws.Operation - -// DeleteVolumeRequest generates a request for the DeleteVolume operation. -func (c *EC2) DeleteVolumeRequest(input *DeleteVolumeInput) (req *aws.Request, output *DeleteVolumeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteVolume == nil { - opDeleteVolume = &aws.Operation{ - Name: "DeleteVolume", - HTTPMethod: "POST", - HTTPPath: "/", - } - } - - if input == nil { - input = &DeleteVolumeInput{} - } - - req = c.newRequest(opDeleteVolume, input, output) - output = &DeleteVolumeOutput{} - req.Data = output - return -} - -// Deletes the specified EBS volume. The volume must be in the available state -// (not attached to an instance). -// -// The volume may remain in the deleting state for several minutes. -// -// For more information, see Deleting an Amazon EBS Volume (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-deleting-volume.html) -// in the Amazon Elastic Compute Cloud User Guide. -func (c *EC2) DeleteVolume(input *DeleteVolumeInput) (*DeleteVolumeOutput, error) { - req, out := c.DeleteVolumeRequest(input) +func (c *EC2) DeleteVpnGateway(input *DeleteVpnGatewayInput) (*DeleteVpnGatewayOutput, error) { + req, out := c.DeleteVpnGatewayRequest(input) err := req.Send() return out, err } -var opDeleteVolume *aws.Operation +const opDeregisterImage = "DeregisterImage" // DeregisterImageRequest generates a request for the DeregisterImage operation. -func (c *EC2) DeregisterImageRequest(input *DeregisterImageInput) (req *aws.Request, output *DeregisterImageOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeregisterImage == nil { - opDeregisterImage = &aws.Operation{ - Name: "DeregisterImage", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DeregisterImageRequest(input *DeregisterImageInput) (req *request.Request, output *DeregisterImageOutput) { + op := &request.Operation{ + Name: opDeregisterImage, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeregisterImageInput{} } - req = c.newRequest(opDeregisterImage, input, output) + req = c.newRequest(op, input, output) output = &DeregisterImageOutput{} req.Data = output return @@ -2873,26 +2574,21 @@ func (c *EC2) DeregisterImage(input *DeregisterImageInput) (*DeregisterImageOutp return out, err } -var opDeregisterImage *aws.Operation +const opDescribeAccountAttributes = "DescribeAccountAttributes" // DescribeAccountAttributesRequest generates a request for the DescribeAccountAttributes operation. -func (c *EC2) DescribeAccountAttributesRequest(input *DescribeAccountAttributesInput) (req *aws.Request, output *DescribeAccountAttributesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeAccountAttributes == nil { - opDescribeAccountAttributes = &aws.Operation{ - Name: "DescribeAccountAttributes", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeAccountAttributesRequest(input *DescribeAccountAttributesInput) (req *request.Request, output *DescribeAccountAttributesOutput) { + op := &request.Operation{ + Name: opDescribeAccountAttributes, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeAccountAttributesInput{} } - req = c.newRequest(opDescribeAccountAttributes, input, output) + req = c.newRequest(op, input, output) output = &DescribeAccountAttributesOutput{} req.Data = output return @@ -2923,26 +2619,21 @@ func (c *EC2) DescribeAccountAttributes(input *DescribeAccountAttributesInput) ( return out, err } -var opDescribeAccountAttributes *aws.Operation +const opDescribeAddresses = "DescribeAddresses" // DescribeAddressesRequest generates a request for the DescribeAddresses operation. -func (c *EC2) DescribeAddressesRequest(input *DescribeAddressesInput) (req *aws.Request, output *DescribeAddressesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeAddresses == nil { - opDescribeAddresses = &aws.Operation{ - Name: "DescribeAddresses", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeAddressesRequest(input *DescribeAddressesInput) (req *request.Request, output *DescribeAddressesOutput) { + op := &request.Operation{ + Name: opDescribeAddresses, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeAddressesInput{} } - req = c.newRequest(opDescribeAddresses, input, output) + req = c.newRequest(op, input, output) output = &DescribeAddressesOutput{} req.Data = output return @@ -2959,26 +2650,21 @@ func (c *EC2) DescribeAddresses(input *DescribeAddressesInput) (*DescribeAddress return out, err } -var opDescribeAddresses *aws.Operation +const opDescribeAvailabilityZones = "DescribeAvailabilityZones" // DescribeAvailabilityZonesRequest generates a request for the DescribeAvailabilityZones operation. -func (c *EC2) DescribeAvailabilityZonesRequest(input *DescribeAvailabilityZonesInput) (req *aws.Request, output *DescribeAvailabilityZonesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeAvailabilityZones == nil { - opDescribeAvailabilityZones = &aws.Operation{ - Name: "DescribeAvailabilityZones", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeAvailabilityZonesRequest(input *DescribeAvailabilityZonesInput) (req *request.Request, output *DescribeAvailabilityZonesOutput) { + op := &request.Operation{ + Name: opDescribeAvailabilityZones, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeAvailabilityZonesInput{} } - req = c.newRequest(opDescribeAvailabilityZones, input, output) + req = c.newRequest(op, input, output) output = &DescribeAvailabilityZonesOutput{} req.Data = output return @@ -2997,26 +2683,21 @@ func (c *EC2) DescribeAvailabilityZones(input *DescribeAvailabilityZonesInput) ( return out, err } -var opDescribeAvailabilityZones *aws.Operation +const opDescribeBundleTasks = "DescribeBundleTasks" // DescribeBundleTasksRequest generates a request for the DescribeBundleTasks operation. -func (c *EC2) DescribeBundleTasksRequest(input *DescribeBundleTasksInput) (req *aws.Request, output *DescribeBundleTasksOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeBundleTasks == nil { - opDescribeBundleTasks = &aws.Operation{ - Name: "DescribeBundleTasks", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeBundleTasksRequest(input *DescribeBundleTasksInput) (req *request.Request, output *DescribeBundleTasksOutput) { + op := &request.Operation{ + Name: opDescribeBundleTasks, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeBundleTasksInput{} } - req = c.newRequest(opDescribeBundleTasks, input, output) + req = c.newRequest(op, input, output) output = &DescribeBundleTasksOutput{} req.Data = output return @@ -3034,26 +2715,21 @@ func (c *EC2) DescribeBundleTasks(input *DescribeBundleTasksInput) (*DescribeBun return out, err } -var opDescribeBundleTasks *aws.Operation +const opDescribeClassicLinkInstances = "DescribeClassicLinkInstances" // DescribeClassicLinkInstancesRequest generates a request for the DescribeClassicLinkInstances operation. -func (c *EC2) DescribeClassicLinkInstancesRequest(input *DescribeClassicLinkInstancesInput) (req *aws.Request, output *DescribeClassicLinkInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeClassicLinkInstances == nil { - opDescribeClassicLinkInstances = &aws.Operation{ - Name: "DescribeClassicLinkInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeClassicLinkInstancesRequest(input *DescribeClassicLinkInstancesInput) (req *request.Request, output *DescribeClassicLinkInstancesOutput) { + op := &request.Operation{ + Name: opDescribeClassicLinkInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeClassicLinkInstancesInput{} } - req = c.newRequest(opDescribeClassicLinkInstances, input, output) + req = c.newRequest(op, input, output) output = &DescribeClassicLinkInstancesOutput{} req.Data = output return @@ -3069,26 +2745,21 @@ func (c *EC2) DescribeClassicLinkInstances(input *DescribeClassicLinkInstancesIn return out, err } -var opDescribeClassicLinkInstances *aws.Operation +const opDescribeConversionTasks = "DescribeConversionTasks" // DescribeConversionTasksRequest generates a request for the DescribeConversionTasks operation. -func (c *EC2) DescribeConversionTasksRequest(input *DescribeConversionTasksInput) (req *aws.Request, output *DescribeConversionTasksOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeConversionTasks == nil { - opDescribeConversionTasks = &aws.Operation{ - Name: "DescribeConversionTasks", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeConversionTasksRequest(input *DescribeConversionTasksInput) (req *request.Request, output *DescribeConversionTasksOutput) { + op := &request.Operation{ + Name: opDescribeConversionTasks, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeConversionTasksInput{} } - req = c.newRequest(opDescribeConversionTasks, input, output) + req = c.newRequest(op, input, output) output = &DescribeConversionTasksOutput{} req.Data = output return @@ -3104,26 +2775,21 @@ func (c *EC2) DescribeConversionTasks(input *DescribeConversionTasksInput) (*Des return out, err } -var opDescribeConversionTasks *aws.Operation +const opDescribeCustomerGateways = "DescribeCustomerGateways" // DescribeCustomerGatewaysRequest generates a request for the DescribeCustomerGateways operation. -func (c *EC2) DescribeCustomerGatewaysRequest(input *DescribeCustomerGatewaysInput) (req *aws.Request, output *DescribeCustomerGatewaysOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeCustomerGateways == nil { - opDescribeCustomerGateways = &aws.Operation{ - Name: "DescribeCustomerGateways", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeCustomerGatewaysRequest(input *DescribeCustomerGatewaysInput) (req *request.Request, output *DescribeCustomerGatewaysOutput) { + op := &request.Operation{ + Name: opDescribeCustomerGateways, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeCustomerGatewaysInput{} } - req = c.newRequest(opDescribeCustomerGateways, input, output) + req = c.newRequest(op, input, output) output = &DescribeCustomerGatewaysOutput{} req.Data = output return @@ -3140,27 +2806,22 @@ func (c *EC2) DescribeCustomerGateways(input *DescribeCustomerGatewaysInput) (*D return out, err } -var opDescribeCustomerGateways *aws.Operation - -// DescribeDHCPOptionsRequest generates a request for the DescribeDHCPOptions operation. -func (c *EC2) DescribeDHCPOptionsRequest(input *DescribeDHCPOptionsInput) (req *aws.Request, output *DescribeDHCPOptionsOutput) { - oprw.Lock() - defer oprw.Unlock() +const opDescribeDhcpOptions = "DescribeDhcpOptions" - if opDescribeDHCPOptions == nil { - opDescribeDHCPOptions = &aws.Operation{ - Name: "DescribeDhcpOptions", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DescribeDhcpOptionsRequest generates a request for the DescribeDhcpOptions operation. +func (c *EC2) DescribeDhcpOptionsRequest(input *DescribeDhcpOptionsInput) (req *request.Request, output *DescribeDhcpOptionsOutput) { + op := &request.Operation{ + Name: opDescribeDhcpOptions, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DescribeDHCPOptionsInput{} + input = &DescribeDhcpOptionsInput{} } - req = c.newRequest(opDescribeDHCPOptions, input, output) - output = &DescribeDHCPOptionsOutput{} + req = c.newRequest(op, input, output) + output = &DescribeDhcpOptionsOutput{} req.Data = output return } @@ -3169,32 +2830,27 @@ func (c *EC2) DescribeDHCPOptionsRequest(input *DescribeDHCPOptionsInput) (req * // // For more information about DHCP options sets, see DHCP Options Sets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) DescribeDHCPOptions(input *DescribeDHCPOptionsInput) (*DescribeDHCPOptionsOutput, error) { - req, out := c.DescribeDHCPOptionsRequest(input) +func (c *EC2) DescribeDhcpOptions(input *DescribeDhcpOptionsInput) (*DescribeDhcpOptionsOutput, error) { + req, out := c.DescribeDhcpOptionsRequest(input) err := req.Send() return out, err } -var opDescribeDHCPOptions *aws.Operation +const opDescribeExportTasks = "DescribeExportTasks" // DescribeExportTasksRequest generates a request for the DescribeExportTasks operation. -func (c *EC2) DescribeExportTasksRequest(input *DescribeExportTasksInput) (req *aws.Request, output *DescribeExportTasksOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeExportTasks == nil { - opDescribeExportTasks = &aws.Operation{ - Name: "DescribeExportTasks", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeExportTasksRequest(input *DescribeExportTasksInput) (req *request.Request, output *DescribeExportTasksOutput) { + op := &request.Operation{ + Name: opDescribeExportTasks, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeExportTasksInput{} } - req = c.newRequest(opDescribeExportTasks, input, output) + req = c.newRequest(op, input, output) output = &DescribeExportTasksOutput{} req.Data = output return @@ -3207,26 +2863,50 @@ func (c *EC2) DescribeExportTasks(input *DescribeExportTasksInput) (*DescribeExp return out, err } -var opDescribeExportTasks *aws.Operation +const opDescribeFlowLogs = "DescribeFlowLogs" -// DescribeImageAttributeRequest generates a request for the DescribeImageAttribute operation. -func (c *EC2) DescribeImageAttributeRequest(input *DescribeImageAttributeInput) (req *aws.Request, output *DescribeImageAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() +// DescribeFlowLogsRequest generates a request for the DescribeFlowLogs operation. +func (c *EC2) DescribeFlowLogsRequest(input *DescribeFlowLogsInput) (req *request.Request, output *DescribeFlowLogsOutput) { + op := &request.Operation{ + Name: opDescribeFlowLogs, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeFlowLogsInput{} + } + + req = c.newRequest(op, input, output) + output = &DescribeFlowLogsOutput{} + req.Data = output + return +} + +// Describes one or more flow logs. To view the information in your flow logs +// (the log streams for the network interfaces), you must use the CloudWatch +// Logs console or the CloudWatch Logs API. +func (c *EC2) DescribeFlowLogs(input *DescribeFlowLogsInput) (*DescribeFlowLogsOutput, error) { + req, out := c.DescribeFlowLogsRequest(input) + err := req.Send() + return out, err +} - if opDescribeImageAttribute == nil { - opDescribeImageAttribute = &aws.Operation{ - Name: "DescribeImageAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +const opDescribeImageAttribute = "DescribeImageAttribute" + +// DescribeImageAttributeRequest generates a request for the DescribeImageAttribute operation. +func (c *EC2) DescribeImageAttributeRequest(input *DescribeImageAttributeInput) (req *request.Request, output *DescribeImageAttributeOutput) { + op := &request.Operation{ + Name: opDescribeImageAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeImageAttributeInput{} } - req = c.newRequest(opDescribeImageAttribute, input, output) + req = c.newRequest(op, input, output) output = &DescribeImageAttributeOutput{} req.Data = output return @@ -3240,26 +2920,21 @@ func (c *EC2) DescribeImageAttribute(input *DescribeImageAttributeInput) (*Descr return out, err } -var opDescribeImageAttribute *aws.Operation +const opDescribeImages = "DescribeImages" // DescribeImagesRequest generates a request for the DescribeImages operation. -func (c *EC2) DescribeImagesRequest(input *DescribeImagesInput) (req *aws.Request, output *DescribeImagesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeImages == nil { - opDescribeImages = &aws.Operation{ - Name: "DescribeImages", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeImagesRequest(input *DescribeImagesInput) (req *request.Request, output *DescribeImagesOutput) { + op := &request.Operation{ + Name: opDescribeImages, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeImagesInput{} } - req = c.newRequest(opDescribeImages, input, output) + req = c.newRequest(op, input, output) output = &DescribeImagesOutput{} req.Data = output return @@ -3278,26 +2953,21 @@ func (c *EC2) DescribeImages(input *DescribeImagesInput) (*DescribeImagesOutput, return out, err } -var opDescribeImages *aws.Operation +const opDescribeImportImageTasks = "DescribeImportImageTasks" // DescribeImportImageTasksRequest generates a request for the DescribeImportImageTasks operation. -func (c *EC2) DescribeImportImageTasksRequest(input *DescribeImportImageTasksInput) (req *aws.Request, output *DescribeImportImageTasksOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeImportImageTasks == nil { - opDescribeImportImageTasks = &aws.Operation{ - Name: "DescribeImportImageTasks", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeImportImageTasksRequest(input *DescribeImportImageTasksInput) (req *request.Request, output *DescribeImportImageTasksOutput) { + op := &request.Operation{ + Name: opDescribeImportImageTasks, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeImportImageTasksInput{} } - req = c.newRequest(opDescribeImportImageTasks, input, output) + req = c.newRequest(op, input, output) output = &DescribeImportImageTasksOutput{} req.Data = output return @@ -3311,26 +2981,21 @@ func (c *EC2) DescribeImportImageTasks(input *DescribeImportImageTasksInput) (*D return out, err } -var opDescribeImportImageTasks *aws.Operation +const opDescribeImportSnapshotTasks = "DescribeImportSnapshotTasks" // DescribeImportSnapshotTasksRequest generates a request for the DescribeImportSnapshotTasks operation. -func (c *EC2) DescribeImportSnapshotTasksRequest(input *DescribeImportSnapshotTasksInput) (req *aws.Request, output *DescribeImportSnapshotTasksOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeImportSnapshotTasks == nil { - opDescribeImportSnapshotTasks = &aws.Operation{ - Name: "DescribeImportSnapshotTasks", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeImportSnapshotTasksRequest(input *DescribeImportSnapshotTasksInput) (req *request.Request, output *DescribeImportSnapshotTasksOutput) { + op := &request.Operation{ + Name: opDescribeImportSnapshotTasks, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeImportSnapshotTasksInput{} } - req = c.newRequest(opDescribeImportSnapshotTasks, input, output) + req = c.newRequest(op, input, output) output = &DescribeImportSnapshotTasksOutput{} req.Data = output return @@ -3343,26 +3008,21 @@ func (c *EC2) DescribeImportSnapshotTasks(input *DescribeImportSnapshotTasksInpu return out, err } -var opDescribeImportSnapshotTasks *aws.Operation +const opDescribeInstanceAttribute = "DescribeInstanceAttribute" // DescribeInstanceAttributeRequest generates a request for the DescribeInstanceAttribute operation. -func (c *EC2) DescribeInstanceAttributeRequest(input *DescribeInstanceAttributeInput) (req *aws.Request, output *DescribeInstanceAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeInstanceAttribute == nil { - opDescribeInstanceAttribute = &aws.Operation{ - Name: "DescribeInstanceAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeInstanceAttributeRequest(input *DescribeInstanceAttributeInput) (req *request.Request, output *DescribeInstanceAttributeOutput) { + op := &request.Operation{ + Name: opDescribeInstanceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeInstanceAttributeInput{} } - req = c.newRequest(opDescribeInstanceAttribute, input, output) + req = c.newRequest(op, input, output) output = &DescribeInstanceAttributeOutput{} req.Data = output return @@ -3379,32 +3039,27 @@ func (c *EC2) DescribeInstanceAttribute(input *DescribeInstanceAttributeInput) ( return out, err } -var opDescribeInstanceAttribute *aws.Operation +const opDescribeInstanceStatus = "DescribeInstanceStatus" // DescribeInstanceStatusRequest generates a request for the DescribeInstanceStatus operation. -func (c *EC2) DescribeInstanceStatusRequest(input *DescribeInstanceStatusInput) (req *aws.Request, output *DescribeInstanceStatusOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeInstanceStatus == nil { - opDescribeInstanceStatus = &aws.Operation{ - Name: "DescribeInstanceStatus", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxResults", - TruncationToken: "", - }, - } +func (c *EC2) DescribeInstanceStatusRequest(input *DescribeInstanceStatusInput) (req *request.Request, output *DescribeInstanceStatusOutput) { + op := &request.Operation{ + Name: opDescribeInstanceStatus, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, } if input == nil { input = &DescribeInstanceStatusInput{} } - req = c.newRequest(opDescribeInstanceStatus, input, output) + req = c.newRequest(op, input, output) output = &DescribeInstanceStatusOutput{} req.Data = output return @@ -3443,32 +3098,27 @@ func (c *EC2) DescribeInstanceStatusPages(input *DescribeInstanceStatusInput, fn }) } -var opDescribeInstanceStatus *aws.Operation +const opDescribeInstances = "DescribeInstances" // DescribeInstancesRequest generates a request for the DescribeInstances operation. -func (c *EC2) DescribeInstancesRequest(input *DescribeInstancesInput) (req *aws.Request, output *DescribeInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeInstances == nil { - opDescribeInstances = &aws.Operation{ - Name: "DescribeInstances", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxResults", - TruncationToken: "", - }, - } +func (c *EC2) DescribeInstancesRequest(input *DescribeInstancesInput) (req *request.Request, output *DescribeInstancesOutput) { + op := &request.Operation{ + Name: opDescribeInstances, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, } if input == nil { input = &DescribeInstancesInput{} } - req = c.newRequest(opDescribeInstances, input, output) + req = c.newRequest(op, input, output) output = &DescribeInstancesOutput{} req.Data = output return @@ -3497,26 +3147,21 @@ func (c *EC2) DescribeInstancesPages(input *DescribeInstancesInput, fn func(p *D }) } -var opDescribeInstances *aws.Operation +const opDescribeInternetGateways = "DescribeInternetGateways" // DescribeInternetGatewaysRequest generates a request for the DescribeInternetGateways operation. -func (c *EC2) DescribeInternetGatewaysRequest(input *DescribeInternetGatewaysInput) (req *aws.Request, output *DescribeInternetGatewaysOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeInternetGateways == nil { - opDescribeInternetGateways = &aws.Operation{ - Name: "DescribeInternetGateways", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeInternetGatewaysRequest(input *DescribeInternetGatewaysInput) (req *request.Request, output *DescribeInternetGatewaysOutput) { + op := &request.Operation{ + Name: opDescribeInternetGateways, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeInternetGatewaysInput{} } - req = c.newRequest(opDescribeInternetGateways, input, output) + req = c.newRequest(op, input, output) output = &DescribeInternetGatewaysOutput{} req.Data = output return @@ -3529,26 +3174,21 @@ func (c *EC2) DescribeInternetGateways(input *DescribeInternetGatewaysInput) (*D return out, err } -var opDescribeInternetGateways *aws.Operation +const opDescribeKeyPairs = "DescribeKeyPairs" // DescribeKeyPairsRequest generates a request for the DescribeKeyPairs operation. -func (c *EC2) DescribeKeyPairsRequest(input *DescribeKeyPairsInput) (req *aws.Request, output *DescribeKeyPairsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeKeyPairs == nil { - opDescribeKeyPairs = &aws.Operation{ - Name: "DescribeKeyPairs", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeKeyPairsRequest(input *DescribeKeyPairsInput) (req *request.Request, output *DescribeKeyPairsOutput) { + op := &request.Operation{ + Name: opDescribeKeyPairs, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeKeyPairsInput{} } - req = c.newRequest(opDescribeKeyPairs, input, output) + req = c.newRequest(op, input, output) output = &DescribeKeyPairsOutput{} req.Data = output return @@ -3564,26 +3204,21 @@ func (c *EC2) DescribeKeyPairs(input *DescribeKeyPairsInput) (*DescribeKeyPairsO return out, err } -var opDescribeKeyPairs *aws.Operation +const opDescribeMovingAddresses = "DescribeMovingAddresses" // DescribeMovingAddressesRequest generates a request for the DescribeMovingAddresses operation. -func (c *EC2) DescribeMovingAddressesRequest(input *DescribeMovingAddressesInput) (req *aws.Request, output *DescribeMovingAddressesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeMovingAddresses == nil { - opDescribeMovingAddresses = &aws.Operation{ - Name: "DescribeMovingAddresses", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeMovingAddressesRequest(input *DescribeMovingAddressesInput) (req *request.Request, output *DescribeMovingAddressesOutput) { + op := &request.Operation{ + Name: opDescribeMovingAddresses, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeMovingAddressesInput{} } - req = c.newRequest(opDescribeMovingAddresses, input, output) + req = c.newRequest(op, input, output) output = &DescribeMovingAddressesOutput{} req.Data = output return @@ -3598,27 +3233,22 @@ func (c *EC2) DescribeMovingAddresses(input *DescribeMovingAddressesInput) (*Des return out, err } -var opDescribeMovingAddresses *aws.Operation - -// DescribeNetworkACLsRequest generates a request for the DescribeNetworkACLs operation. -func (c *EC2) DescribeNetworkACLsRequest(input *DescribeNetworkACLsInput) (req *aws.Request, output *DescribeNetworkACLsOutput) { - oprw.Lock() - defer oprw.Unlock() +const opDescribeNetworkAcls = "DescribeNetworkAcls" - if opDescribeNetworkACLs == nil { - opDescribeNetworkACLs = &aws.Operation{ - Name: "DescribeNetworkAcls", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DescribeNetworkAclsRequest generates a request for the DescribeNetworkAcls operation. +func (c *EC2) DescribeNetworkAclsRequest(input *DescribeNetworkAclsInput) (req *request.Request, output *DescribeNetworkAclsOutput) { + op := &request.Operation{ + Name: opDescribeNetworkAcls, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DescribeNetworkACLsInput{} + input = &DescribeNetworkAclsInput{} } - req = c.newRequest(opDescribeNetworkACLs, input, output) - output = &DescribeNetworkACLsOutput{} + req = c.newRequest(op, input, output) + output = &DescribeNetworkAclsOutput{} req.Data = output return } @@ -3627,32 +3257,27 @@ func (c *EC2) DescribeNetworkACLsRequest(input *DescribeNetworkACLsInput) (req * // // For more information about network ACLs, see Network ACLs (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) DescribeNetworkACLs(input *DescribeNetworkACLsInput) (*DescribeNetworkACLsOutput, error) { - req, out := c.DescribeNetworkACLsRequest(input) +func (c *EC2) DescribeNetworkAcls(input *DescribeNetworkAclsInput) (*DescribeNetworkAclsOutput, error) { + req, out := c.DescribeNetworkAclsRequest(input) err := req.Send() return out, err } -var opDescribeNetworkACLs *aws.Operation +const opDescribeNetworkInterfaceAttribute = "DescribeNetworkInterfaceAttribute" // DescribeNetworkInterfaceAttributeRequest generates a request for the DescribeNetworkInterfaceAttribute operation. -func (c *EC2) DescribeNetworkInterfaceAttributeRequest(input *DescribeNetworkInterfaceAttributeInput) (req *aws.Request, output *DescribeNetworkInterfaceAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeNetworkInterfaceAttribute == nil { - opDescribeNetworkInterfaceAttribute = &aws.Operation{ - Name: "DescribeNetworkInterfaceAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeNetworkInterfaceAttributeRequest(input *DescribeNetworkInterfaceAttributeInput) (req *request.Request, output *DescribeNetworkInterfaceAttributeOutput) { + op := &request.Operation{ + Name: opDescribeNetworkInterfaceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeNetworkInterfaceAttributeInput{} } - req = c.newRequest(opDescribeNetworkInterfaceAttribute, input, output) + req = c.newRequest(op, input, output) output = &DescribeNetworkInterfaceAttributeOutput{} req.Data = output return @@ -3666,26 +3291,21 @@ func (c *EC2) DescribeNetworkInterfaceAttribute(input *DescribeNetworkInterfaceA return out, err } -var opDescribeNetworkInterfaceAttribute *aws.Operation +const opDescribeNetworkInterfaces = "DescribeNetworkInterfaces" // DescribeNetworkInterfacesRequest generates a request for the DescribeNetworkInterfaces operation. -func (c *EC2) DescribeNetworkInterfacesRequest(input *DescribeNetworkInterfacesInput) (req *aws.Request, output *DescribeNetworkInterfacesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeNetworkInterfaces == nil { - opDescribeNetworkInterfaces = &aws.Operation{ - Name: "DescribeNetworkInterfaces", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeNetworkInterfacesRequest(input *DescribeNetworkInterfacesInput) (req *request.Request, output *DescribeNetworkInterfacesOutput) { + op := &request.Operation{ + Name: opDescribeNetworkInterfaces, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeNetworkInterfacesInput{} } - req = c.newRequest(opDescribeNetworkInterfaces, input, output) + req = c.newRequest(op, input, output) output = &DescribeNetworkInterfacesOutput{} req.Data = output return @@ -3698,26 +3318,21 @@ func (c *EC2) DescribeNetworkInterfaces(input *DescribeNetworkInterfacesInput) ( return out, err } -var opDescribeNetworkInterfaces *aws.Operation +const opDescribePlacementGroups = "DescribePlacementGroups" // DescribePlacementGroupsRequest generates a request for the DescribePlacementGroups operation. -func (c *EC2) DescribePlacementGroupsRequest(input *DescribePlacementGroupsInput) (req *aws.Request, output *DescribePlacementGroupsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribePlacementGroups == nil { - opDescribePlacementGroups = &aws.Operation{ - Name: "DescribePlacementGroups", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribePlacementGroupsRequest(input *DescribePlacementGroupsInput) (req *request.Request, output *DescribePlacementGroupsOutput) { + op := &request.Operation{ + Name: opDescribePlacementGroups, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribePlacementGroupsInput{} } - req = c.newRequest(opDescribePlacementGroups, input, output) + req = c.newRequest(op, input, output) output = &DescribePlacementGroupsOutput{} req.Data = output return @@ -3732,26 +3347,21 @@ func (c *EC2) DescribePlacementGroups(input *DescribePlacementGroupsInput) (*Des return out, err } -var opDescribePlacementGroups *aws.Operation +const opDescribePrefixLists = "DescribePrefixLists" // DescribePrefixListsRequest generates a request for the DescribePrefixLists operation. -func (c *EC2) DescribePrefixListsRequest(input *DescribePrefixListsInput) (req *aws.Request, output *DescribePrefixListsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribePrefixLists == nil { - opDescribePrefixLists = &aws.Operation{ - Name: "DescribePrefixLists", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribePrefixListsRequest(input *DescribePrefixListsInput) (req *request.Request, output *DescribePrefixListsOutput) { + op := &request.Operation{ + Name: opDescribePrefixLists, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribePrefixListsInput{} } - req = c.newRequest(opDescribePrefixLists, input, output) + req = c.newRequest(op, input, output) output = &DescribePrefixListsOutput{} req.Data = output return @@ -3768,26 +3378,21 @@ func (c *EC2) DescribePrefixLists(input *DescribePrefixListsInput) (*DescribePre return out, err } -var opDescribePrefixLists *aws.Operation +const opDescribeRegions = "DescribeRegions" // DescribeRegionsRequest generates a request for the DescribeRegions operation. -func (c *EC2) DescribeRegionsRequest(input *DescribeRegionsInput) (req *aws.Request, output *DescribeRegionsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeRegions == nil { - opDescribeRegions = &aws.Operation{ - Name: "DescribeRegions", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeRegionsRequest(input *DescribeRegionsInput) (req *request.Request, output *DescribeRegionsOutput) { + op := &request.Operation{ + Name: opDescribeRegions, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeRegionsInput{} } - req = c.newRequest(opDescribeRegions, input, output) + req = c.newRequest(op, input, output) output = &DescribeRegionsOutput{} req.Data = output return @@ -3803,26 +3408,21 @@ func (c *EC2) DescribeRegions(input *DescribeRegionsInput) (*DescribeRegionsOutp return out, err } -var opDescribeRegions *aws.Operation +const opDescribeReservedInstances = "DescribeReservedInstances" // DescribeReservedInstancesRequest generates a request for the DescribeReservedInstances operation. -func (c *EC2) DescribeReservedInstancesRequest(input *DescribeReservedInstancesInput) (req *aws.Request, output *DescribeReservedInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeReservedInstances == nil { - opDescribeReservedInstances = &aws.Operation{ - Name: "DescribeReservedInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeReservedInstancesRequest(input *DescribeReservedInstancesInput) (req *request.Request, output *DescribeReservedInstancesOutput) { + op := &request.Operation{ + Name: opDescribeReservedInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeReservedInstancesInput{} } - req = c.newRequest(opDescribeReservedInstances, input, output) + req = c.newRequest(op, input, output) output = &DescribeReservedInstancesOutput{} req.Data = output return @@ -3838,26 +3438,21 @@ func (c *EC2) DescribeReservedInstances(input *DescribeReservedInstancesInput) ( return out, err } -var opDescribeReservedInstances *aws.Operation +const opDescribeReservedInstancesListings = "DescribeReservedInstancesListings" // DescribeReservedInstancesListingsRequest generates a request for the DescribeReservedInstancesListings operation. -func (c *EC2) DescribeReservedInstancesListingsRequest(input *DescribeReservedInstancesListingsInput) (req *aws.Request, output *DescribeReservedInstancesListingsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeReservedInstancesListings == nil { - opDescribeReservedInstancesListings = &aws.Operation{ - Name: "DescribeReservedInstancesListings", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeReservedInstancesListingsRequest(input *DescribeReservedInstancesListingsInput) (req *request.Request, output *DescribeReservedInstancesListingsOutput) { + op := &request.Operation{ + Name: opDescribeReservedInstancesListings, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeReservedInstancesListingsInput{} } - req = c.newRequest(opDescribeReservedInstancesListings, input, output) + req = c.newRequest(op, input, output) output = &DescribeReservedInstancesListingsOutput{} req.Data = output return @@ -3891,32 +3486,27 @@ func (c *EC2) DescribeReservedInstancesListings(input *DescribeReservedInstances return out, err } -var opDescribeReservedInstancesListings *aws.Operation +const opDescribeReservedInstancesModifications = "DescribeReservedInstancesModifications" // DescribeReservedInstancesModificationsRequest generates a request for the DescribeReservedInstancesModifications operation. -func (c *EC2) DescribeReservedInstancesModificationsRequest(input *DescribeReservedInstancesModificationsInput) (req *aws.Request, output *DescribeReservedInstancesModificationsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeReservedInstancesModifications == nil { - opDescribeReservedInstancesModifications = &aws.Operation{ - Name: "DescribeReservedInstancesModifications", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "", - TruncationToken: "", - }, - } +func (c *EC2) DescribeReservedInstancesModificationsRequest(input *DescribeReservedInstancesModificationsInput) (req *request.Request, output *DescribeReservedInstancesModificationsOutput) { + op := &request.Operation{ + Name: opDescribeReservedInstancesModifications, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, } if input == nil { input = &DescribeReservedInstancesModificationsInput{} } - req = c.newRequest(opDescribeReservedInstancesModifications, input, output) + req = c.newRequest(op, input, output) output = &DescribeReservedInstancesModificationsOutput{} req.Data = output return @@ -3942,32 +3532,27 @@ func (c *EC2) DescribeReservedInstancesModificationsPages(input *DescribeReserve }) } -var opDescribeReservedInstancesModifications *aws.Operation +const opDescribeReservedInstancesOfferings = "DescribeReservedInstancesOfferings" // DescribeReservedInstancesOfferingsRequest generates a request for the DescribeReservedInstancesOfferings operation. -func (c *EC2) DescribeReservedInstancesOfferingsRequest(input *DescribeReservedInstancesOfferingsInput) (req *aws.Request, output *DescribeReservedInstancesOfferingsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeReservedInstancesOfferings == nil { - opDescribeReservedInstancesOfferings = &aws.Operation{ - Name: "DescribeReservedInstancesOfferings", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxResults", - TruncationToken: "", - }, - } +func (c *EC2) DescribeReservedInstancesOfferingsRequest(input *DescribeReservedInstancesOfferingsInput) (req *request.Request, output *DescribeReservedInstancesOfferingsOutput) { + op := &request.Operation{ + Name: opDescribeReservedInstancesOfferings, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, } if input == nil { input = &DescribeReservedInstancesOfferingsInput{} } - req = c.newRequest(opDescribeReservedInstancesOfferings, input, output) + req = c.newRequest(op, input, output) output = &DescribeReservedInstancesOfferingsOutput{} req.Data = output return @@ -3994,26 +3579,21 @@ func (c *EC2) DescribeReservedInstancesOfferingsPages(input *DescribeReservedIns }) } -var opDescribeReservedInstancesOfferings *aws.Operation +const opDescribeRouteTables = "DescribeRouteTables" // DescribeRouteTablesRequest generates a request for the DescribeRouteTables operation. -func (c *EC2) DescribeRouteTablesRequest(input *DescribeRouteTablesInput) (req *aws.Request, output *DescribeRouteTablesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeRouteTables == nil { - opDescribeRouteTables = &aws.Operation{ - Name: "DescribeRouteTables", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeRouteTablesRequest(input *DescribeRouteTablesInput) (req *request.Request, output *DescribeRouteTablesOutput) { + op := &request.Operation{ + Name: opDescribeRouteTables, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeRouteTablesInput{} } - req = c.newRequest(opDescribeRouteTables, input, output) + req = c.newRequest(op, input, output) output = &DescribeRouteTablesOutput{} req.Data = output return @@ -4021,6 +3601,11 @@ func (c *EC2) DescribeRouteTablesRequest(input *DescribeRouteTablesInput) (req * // Describes one or more of your route tables. // +// Each subnet in your VPC must be associated with a route table. If a subnet +// is not explicitly associated with any route table, it is implicitly associated +// with the main route table. This command does not return the subnet ID for +// implicit associations. +// // For more information about route tables, see Route Tables (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Route_Tables.html) // in the Amazon Virtual Private Cloud User Guide. func (c *EC2) DescribeRouteTables(input *DescribeRouteTablesInput) (*DescribeRouteTablesOutput, error) { @@ -4029,26 +3614,21 @@ func (c *EC2) DescribeRouteTables(input *DescribeRouteTablesInput) (*DescribeRou return out, err } -var opDescribeRouteTables *aws.Operation +const opDescribeSecurityGroups = "DescribeSecurityGroups" // DescribeSecurityGroupsRequest generates a request for the DescribeSecurityGroups operation. -func (c *EC2) DescribeSecurityGroupsRequest(input *DescribeSecurityGroupsInput) (req *aws.Request, output *DescribeSecurityGroupsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeSecurityGroups == nil { - opDescribeSecurityGroups = &aws.Operation{ - Name: "DescribeSecurityGroups", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeSecurityGroupsRequest(input *DescribeSecurityGroupsInput) (req *request.Request, output *DescribeSecurityGroupsOutput) { + op := &request.Operation{ + Name: opDescribeSecurityGroups, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeSecurityGroupsInput{} } - req = c.newRequest(opDescribeSecurityGroups, input, output) + req = c.newRequest(op, input, output) output = &DescribeSecurityGroupsOutput{} req.Data = output return @@ -4068,26 +3648,21 @@ func (c *EC2) DescribeSecurityGroups(input *DescribeSecurityGroupsInput) (*Descr return out, err } -var opDescribeSecurityGroups *aws.Operation +const opDescribeSnapshotAttribute = "DescribeSnapshotAttribute" // DescribeSnapshotAttributeRequest generates a request for the DescribeSnapshotAttribute operation. -func (c *EC2) DescribeSnapshotAttributeRequest(input *DescribeSnapshotAttributeInput) (req *aws.Request, output *DescribeSnapshotAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeSnapshotAttribute == nil { - opDescribeSnapshotAttribute = &aws.Operation{ - Name: "DescribeSnapshotAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeSnapshotAttributeRequest(input *DescribeSnapshotAttributeInput) (req *request.Request, output *DescribeSnapshotAttributeOutput) { + op := &request.Operation{ + Name: opDescribeSnapshotAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeSnapshotAttributeInput{} } - req = c.newRequest(opDescribeSnapshotAttribute, input, output) + req = c.newRequest(op, input, output) output = &DescribeSnapshotAttributeOutput{} req.Data = output return @@ -4104,32 +3679,27 @@ func (c *EC2) DescribeSnapshotAttribute(input *DescribeSnapshotAttributeInput) ( return out, err } -var opDescribeSnapshotAttribute *aws.Operation +const opDescribeSnapshots = "DescribeSnapshots" // DescribeSnapshotsRequest generates a request for the DescribeSnapshots operation. -func (c *EC2) DescribeSnapshotsRequest(input *DescribeSnapshotsInput) (req *aws.Request, output *DescribeSnapshotsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeSnapshots == nil { - opDescribeSnapshots = &aws.Operation{ - Name: "DescribeSnapshots", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "", - TruncationToken: "", - }, - } +func (c *EC2) DescribeSnapshotsRequest(input *DescribeSnapshotsInput) (req *request.Request, output *DescribeSnapshotsOutput) { + op := &request.Operation{ + Name: opDescribeSnapshots, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, } if input == nil { input = &DescribeSnapshotsInput{} } - req = c.newRequest(opDescribeSnapshots, input, output) + req = c.newRequest(op, input, output) output = &DescribeSnapshotsOutput{} req.Data = output return @@ -4188,32 +3758,27 @@ func (c *EC2) DescribeSnapshotsPages(input *DescribeSnapshotsInput, fn func(p *D }) } -var opDescribeSnapshots *aws.Operation +const opDescribeSpotDatafeedSubscription = "DescribeSpotDatafeedSubscription" // DescribeSpotDatafeedSubscriptionRequest generates a request for the DescribeSpotDatafeedSubscription operation. -func (c *EC2) DescribeSpotDatafeedSubscriptionRequest(input *DescribeSpotDatafeedSubscriptionInput) (req *aws.Request, output *DescribeSpotDatafeedSubscriptionOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeSpotDatafeedSubscription == nil { - opDescribeSpotDatafeedSubscription = &aws.Operation{ - Name: "DescribeSpotDatafeedSubscription", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeSpotDatafeedSubscriptionRequest(input *DescribeSpotDatafeedSubscriptionInput) (req *request.Request, output *DescribeSpotDatafeedSubscriptionOutput) { + op := &request.Operation{ + Name: opDescribeSpotDatafeedSubscription, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeSpotDatafeedSubscriptionInput{} } - req = c.newRequest(opDescribeSpotDatafeedSubscription, input, output) + req = c.newRequest(op, input, output) output = &DescribeSpotDatafeedSubscriptionOutput{} req.Data = output return } -// Describes the data feed for Spot Instances. For more information, see Spot +// Describes the data feed for Spot instances. For more information, see Spot // Instance Data Feed (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-data-feeds.html) // in the Amazon Elastic Compute Cloud User Guide. func (c *EC2) DescribeSpotDatafeedSubscription(input *DescribeSpotDatafeedSubscriptionInput) (*DescribeSpotDatafeedSubscriptionOutput, error) { @@ -4222,26 +3787,21 @@ func (c *EC2) DescribeSpotDatafeedSubscription(input *DescribeSpotDatafeedSubscr return out, err } -var opDescribeSpotDatafeedSubscription *aws.Operation +const opDescribeSpotFleetInstances = "DescribeSpotFleetInstances" // DescribeSpotFleetInstancesRequest generates a request for the DescribeSpotFleetInstances operation. -func (c *EC2) DescribeSpotFleetInstancesRequest(input *DescribeSpotFleetInstancesInput) (req *aws.Request, output *DescribeSpotFleetInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeSpotFleetInstances == nil { - opDescribeSpotFleetInstances = &aws.Operation{ - Name: "DescribeSpotFleetInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeSpotFleetInstancesRequest(input *DescribeSpotFleetInstancesInput) (req *request.Request, output *DescribeSpotFleetInstancesOutput) { + op := &request.Operation{ + Name: opDescribeSpotFleetInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeSpotFleetInstancesInput{} } - req = c.newRequest(opDescribeSpotFleetInstances, input, output) + req = c.newRequest(op, input, output) output = &DescribeSpotFleetInstancesOutput{} req.Data = output return @@ -4254,26 +3814,21 @@ func (c *EC2) DescribeSpotFleetInstances(input *DescribeSpotFleetInstancesInput) return out, err } -var opDescribeSpotFleetInstances *aws.Operation +const opDescribeSpotFleetRequestHistory = "DescribeSpotFleetRequestHistory" // DescribeSpotFleetRequestHistoryRequest generates a request for the DescribeSpotFleetRequestHistory operation. -func (c *EC2) DescribeSpotFleetRequestHistoryRequest(input *DescribeSpotFleetRequestHistoryInput) (req *aws.Request, output *DescribeSpotFleetRequestHistoryOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeSpotFleetRequestHistory == nil { - opDescribeSpotFleetRequestHistory = &aws.Operation{ - Name: "DescribeSpotFleetRequestHistory", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeSpotFleetRequestHistoryRequest(input *DescribeSpotFleetRequestHistoryInput) (req *request.Request, output *DescribeSpotFleetRequestHistoryOutput) { + op := &request.Operation{ + Name: opDescribeSpotFleetRequestHistory, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeSpotFleetRequestHistoryInput{} } - req = c.newRequest(opDescribeSpotFleetRequestHistory, input, output) + req = c.newRequest(op, input, output) output = &DescribeSpotFleetRequestHistoryOutput{} req.Data = output return @@ -4291,26 +3846,21 @@ func (c *EC2) DescribeSpotFleetRequestHistory(input *DescribeSpotFleetRequestHis return out, err } -var opDescribeSpotFleetRequestHistory *aws.Operation +const opDescribeSpotFleetRequests = "DescribeSpotFleetRequests" // DescribeSpotFleetRequestsRequest generates a request for the DescribeSpotFleetRequests operation. -func (c *EC2) DescribeSpotFleetRequestsRequest(input *DescribeSpotFleetRequestsInput) (req *aws.Request, output *DescribeSpotFleetRequestsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeSpotFleetRequests == nil { - opDescribeSpotFleetRequests = &aws.Operation{ - Name: "DescribeSpotFleetRequests", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeSpotFleetRequestsRequest(input *DescribeSpotFleetRequestsInput) (req *request.Request, output *DescribeSpotFleetRequestsOutput) { + op := &request.Operation{ + Name: opDescribeSpotFleetRequests, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeSpotFleetRequestsInput{} } - req = c.newRequest(opDescribeSpotFleetRequests, input, output) + req = c.newRequest(op, input, output) output = &DescribeSpotFleetRequestsOutput{} req.Data = output return @@ -4323,40 +3873,35 @@ func (c *EC2) DescribeSpotFleetRequests(input *DescribeSpotFleetRequestsInput) ( return out, err } -var opDescribeSpotFleetRequests *aws.Operation +const opDescribeSpotInstanceRequests = "DescribeSpotInstanceRequests" // DescribeSpotInstanceRequestsRequest generates a request for the DescribeSpotInstanceRequests operation. -func (c *EC2) DescribeSpotInstanceRequestsRequest(input *DescribeSpotInstanceRequestsInput) (req *aws.Request, output *DescribeSpotInstanceRequestsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeSpotInstanceRequests == nil { - opDescribeSpotInstanceRequests = &aws.Operation{ - Name: "DescribeSpotInstanceRequests", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeSpotInstanceRequestsRequest(input *DescribeSpotInstanceRequestsInput) (req *request.Request, output *DescribeSpotInstanceRequestsOutput) { + op := &request.Operation{ + Name: opDescribeSpotInstanceRequests, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeSpotInstanceRequestsInput{} } - req = c.newRequest(opDescribeSpotInstanceRequests, input, output) + req = c.newRequest(op, input, output) output = &DescribeSpotInstanceRequestsOutput{} req.Data = output return } -// Describes the Spot Instance requests that belong to your account. Spot Instances +// Describes the Spot instance requests that belong to your account. Spot instances // are instances that Amazon EC2 launches when the bid price that you specify -// exceeds the current Spot Price. Amazon EC2 periodically sets the Spot Price -// based on available Spot Instance capacity and current Spot Instance requests. +// exceeds the current Spot price. Amazon EC2 periodically sets the Spot price +// based on available Spot instance capacity and current Spot instance requests. // For more information, see Spot Instance Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) // in the Amazon Elastic Compute Cloud User Guide. // -// You can use DescribeSpotInstanceRequests to find a running Spot Instance -// by examining the response. If the status of the Spot Instance is fulfilled, +// You can use DescribeSpotInstanceRequests to find a running Spot instance +// by examining the response. If the status of the Spot instance is fulfilled, // the instance ID appears in the response and contains the identifier of the // instance. Alternatively, you can use DescribeInstances with a filter to look // for instances where the instance lifecycle is spot. @@ -4366,38 +3911,33 @@ func (c *EC2) DescribeSpotInstanceRequests(input *DescribeSpotInstanceRequestsIn return out, err } -var opDescribeSpotInstanceRequests *aws.Operation +const opDescribeSpotPriceHistory = "DescribeSpotPriceHistory" // DescribeSpotPriceHistoryRequest generates a request for the DescribeSpotPriceHistory operation. -func (c *EC2) DescribeSpotPriceHistoryRequest(input *DescribeSpotPriceHistoryInput) (req *aws.Request, output *DescribeSpotPriceHistoryOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeSpotPriceHistory == nil { - opDescribeSpotPriceHistory = &aws.Operation{ - Name: "DescribeSpotPriceHistory", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxResults", - TruncationToken: "", - }, - } +func (c *EC2) DescribeSpotPriceHistoryRequest(input *DescribeSpotPriceHistoryInput) (req *request.Request, output *DescribeSpotPriceHistoryOutput) { + op := &request.Operation{ + Name: opDescribeSpotPriceHistory, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, } if input == nil { input = &DescribeSpotPriceHistoryInput{} } - req = c.newRequest(opDescribeSpotPriceHistory, input, output) + req = c.newRequest(op, input, output) output = &DescribeSpotPriceHistoryOutput{} req.Data = output return } -// Describes the Spot Price history. The prices returned are listed in chronological +// Describes the Spot price history. The prices returned are listed in chronological // order, from the oldest to the most recent, for up to the past 90 days. For // more information, see Spot Instance Pricing History (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances-history.html) // in the Amazon Elastic Compute Cloud User Guide. @@ -4419,26 +3959,21 @@ func (c *EC2) DescribeSpotPriceHistoryPages(input *DescribeSpotPriceHistoryInput }) } -var opDescribeSpotPriceHistory *aws.Operation +const opDescribeSubnets = "DescribeSubnets" // DescribeSubnetsRequest generates a request for the DescribeSubnets operation. -func (c *EC2) DescribeSubnetsRequest(input *DescribeSubnetsInput) (req *aws.Request, output *DescribeSubnetsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeSubnets == nil { - opDescribeSubnets = &aws.Operation{ - Name: "DescribeSubnets", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeSubnetsRequest(input *DescribeSubnetsInput) (req *request.Request, output *DescribeSubnetsOutput) { + op := &request.Operation{ + Name: opDescribeSubnets, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeSubnetsInput{} } - req = c.newRequest(opDescribeSubnets, input, output) + req = c.newRequest(op, input, output) output = &DescribeSubnetsOutput{} req.Data = output return @@ -4454,26 +3989,21 @@ func (c *EC2) DescribeSubnets(input *DescribeSubnetsInput) (*DescribeSubnetsOutp return out, err } -var opDescribeSubnets *aws.Operation +const opDescribeTags = "DescribeTags" // DescribeTagsRequest generates a request for the DescribeTags operation. -func (c *EC2) DescribeTagsRequest(input *DescribeTagsInput) (req *aws.Request, output *DescribeTagsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeTags == nil { - opDescribeTags = &aws.Operation{ - Name: "DescribeTags", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeTagsRequest(input *DescribeTagsInput) (req *request.Request, output *DescribeTagsOutput) { + op := &request.Operation{ + Name: opDescribeTags, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeTagsInput{} } - req = c.newRequest(opDescribeTags, input, output) + req = c.newRequest(op, input, output) output = &DescribeTagsOutput{} req.Data = output return @@ -4489,292 +4019,21 @@ func (c *EC2) DescribeTags(input *DescribeTagsInput) (*DescribeTagsOutput, error return out, err } -var opDescribeTags *aws.Operation - -// DescribeVPCAttributeRequest generates a request for the DescribeVPCAttribute operation. -func (c *EC2) DescribeVPCAttributeRequest(input *DescribeVPCAttributeInput) (req *aws.Request, output *DescribeVPCAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeVPCAttribute == nil { - opDescribeVPCAttribute = &aws.Operation{ - Name: "DescribeVpcAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } - } - - if input == nil { - input = &DescribeVPCAttributeInput{} - } - - req = c.newRequest(opDescribeVPCAttribute, input, output) - output = &DescribeVPCAttributeOutput{} - req.Data = output - return -} - -// Describes the specified attribute of the specified VPC. You can specify only -// one attribute at a time. -func (c *EC2) DescribeVPCAttribute(input *DescribeVPCAttributeInput) (*DescribeVPCAttributeOutput, error) { - req, out := c.DescribeVPCAttributeRequest(input) - err := req.Send() - return out, err -} - -var opDescribeVPCAttribute *aws.Operation - -// DescribeVPCClassicLinkRequest generates a request for the DescribeVPCClassicLink operation. -func (c *EC2) DescribeVPCClassicLinkRequest(input *DescribeVPCClassicLinkInput) (req *aws.Request, output *DescribeVPCClassicLinkOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeVPCClassicLink == nil { - opDescribeVPCClassicLink = &aws.Operation{ - Name: "DescribeVpcClassicLink", - HTTPMethod: "POST", - HTTPPath: "/", - } - } - - if input == nil { - input = &DescribeVPCClassicLinkInput{} - } - - req = c.newRequest(opDescribeVPCClassicLink, input, output) - output = &DescribeVPCClassicLinkOutput{} - req.Data = output - return -} - -// Describes the ClassicLink status of one or more VPCs. -func (c *EC2) DescribeVPCClassicLink(input *DescribeVPCClassicLinkInput) (*DescribeVPCClassicLinkOutput, error) { - req, out := c.DescribeVPCClassicLinkRequest(input) - err := req.Send() - return out, err -} - -var opDescribeVPCClassicLink *aws.Operation - -// DescribeVPCEndpointServicesRequest generates a request for the DescribeVPCEndpointServices operation. -func (c *EC2) DescribeVPCEndpointServicesRequest(input *DescribeVPCEndpointServicesInput) (req *aws.Request, output *DescribeVPCEndpointServicesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeVPCEndpointServices == nil { - opDescribeVPCEndpointServices = &aws.Operation{ - Name: "DescribeVpcEndpointServices", - HTTPMethod: "POST", - HTTPPath: "/", - } - } - - if input == nil { - input = &DescribeVPCEndpointServicesInput{} - } - - req = c.newRequest(opDescribeVPCEndpointServices, input, output) - output = &DescribeVPCEndpointServicesOutput{} - req.Data = output - return -} - -// Describes all supported AWS services that can be specified when creating -// a VPC endpoint. -func (c *EC2) DescribeVPCEndpointServices(input *DescribeVPCEndpointServicesInput) (*DescribeVPCEndpointServicesOutput, error) { - req, out := c.DescribeVPCEndpointServicesRequest(input) - err := req.Send() - return out, err -} - -var opDescribeVPCEndpointServices *aws.Operation - -// DescribeVPCEndpointsRequest generates a request for the DescribeVPCEndpoints operation. -func (c *EC2) DescribeVPCEndpointsRequest(input *DescribeVPCEndpointsInput) (req *aws.Request, output *DescribeVPCEndpointsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeVPCEndpoints == nil { - opDescribeVPCEndpoints = &aws.Operation{ - Name: "DescribeVpcEndpoints", - HTTPMethod: "POST", - HTTPPath: "/", - } - } - - if input == nil { - input = &DescribeVPCEndpointsInput{} - } - - req = c.newRequest(opDescribeVPCEndpoints, input, output) - output = &DescribeVPCEndpointsOutput{} - req.Data = output - return -} - -// Describes one or more of your VPC endpoints. -func (c *EC2) DescribeVPCEndpoints(input *DescribeVPCEndpointsInput) (*DescribeVPCEndpointsOutput, error) { - req, out := c.DescribeVPCEndpointsRequest(input) - err := req.Send() - return out, err -} - -var opDescribeVPCEndpoints *aws.Operation - -// DescribeVPCPeeringConnectionsRequest generates a request for the DescribeVPCPeeringConnections operation. -func (c *EC2) DescribeVPCPeeringConnectionsRequest(input *DescribeVPCPeeringConnectionsInput) (req *aws.Request, output *DescribeVPCPeeringConnectionsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeVPCPeeringConnections == nil { - opDescribeVPCPeeringConnections = &aws.Operation{ - Name: "DescribeVpcPeeringConnections", - HTTPMethod: "POST", - HTTPPath: "/", - } - } - - if input == nil { - input = &DescribeVPCPeeringConnectionsInput{} - } - - req = c.newRequest(opDescribeVPCPeeringConnections, input, output) - output = &DescribeVPCPeeringConnectionsOutput{} - req.Data = output - return -} - -// Describes one or more of your VPC peering connections. -func (c *EC2) DescribeVPCPeeringConnections(input *DescribeVPCPeeringConnectionsInput) (*DescribeVPCPeeringConnectionsOutput, error) { - req, out := c.DescribeVPCPeeringConnectionsRequest(input) - err := req.Send() - return out, err -} - -var opDescribeVPCPeeringConnections *aws.Operation - -// DescribeVPCsRequest generates a request for the DescribeVPCs operation. -func (c *EC2) DescribeVPCsRequest(input *DescribeVPCsInput) (req *aws.Request, output *DescribeVPCsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeVPCs == nil { - opDescribeVPCs = &aws.Operation{ - Name: "DescribeVpcs", - HTTPMethod: "POST", - HTTPPath: "/", - } - } - - if input == nil { - input = &DescribeVPCsInput{} - } - - req = c.newRequest(opDescribeVPCs, input, output) - output = &DescribeVPCsOutput{} - req.Data = output - return -} - -// Describes one or more of your VPCs. -func (c *EC2) DescribeVPCs(input *DescribeVPCsInput) (*DescribeVPCsOutput, error) { - req, out := c.DescribeVPCsRequest(input) - err := req.Send() - return out, err -} - -var opDescribeVPCs *aws.Operation - -// DescribeVPNConnectionsRequest generates a request for the DescribeVPNConnections operation. -func (c *EC2) DescribeVPNConnectionsRequest(input *DescribeVPNConnectionsInput) (req *aws.Request, output *DescribeVPNConnectionsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeVPNConnections == nil { - opDescribeVPNConnections = &aws.Operation{ - Name: "DescribeVpnConnections", - HTTPMethod: "POST", - HTTPPath: "/", - } - } - - if input == nil { - input = &DescribeVPNConnectionsInput{} - } - - req = c.newRequest(opDescribeVPNConnections, input, output) - output = &DescribeVPNConnectionsOutput{} - req.Data = output - return -} - -// Describes one or more of your VPN connections. -// -// For more information about VPN connections, see Adding a Hardware Virtual -// Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) -// in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) DescribeVPNConnections(input *DescribeVPNConnectionsInput) (*DescribeVPNConnectionsOutput, error) { - req, out := c.DescribeVPNConnectionsRequest(input) - err := req.Send() - return out, err -} - -var opDescribeVPNConnections *aws.Operation - -// DescribeVPNGatewaysRequest generates a request for the DescribeVPNGateways operation. -func (c *EC2) DescribeVPNGatewaysRequest(input *DescribeVPNGatewaysInput) (req *aws.Request, output *DescribeVPNGatewaysOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeVPNGateways == nil { - opDescribeVPNGateways = &aws.Operation{ - Name: "DescribeVpnGateways", - HTTPMethod: "POST", - HTTPPath: "/", - } - } - - if input == nil { - input = &DescribeVPNGatewaysInput{} - } - - req = c.newRequest(opDescribeVPNGateways, input, output) - output = &DescribeVPNGatewaysOutput{} - req.Data = output - return -} - -// Describes one or more of your virtual private gateways. -// -// For more information about virtual private gateways, see Adding an IPsec -// Hardware VPN to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) -// in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) DescribeVPNGateways(input *DescribeVPNGatewaysInput) (*DescribeVPNGatewaysOutput, error) { - req, out := c.DescribeVPNGatewaysRequest(input) - err := req.Send() - return out, err -} - -var opDescribeVPNGateways *aws.Operation +const opDescribeVolumeAttribute = "DescribeVolumeAttribute" // DescribeVolumeAttributeRequest generates a request for the DescribeVolumeAttribute operation. -func (c *EC2) DescribeVolumeAttributeRequest(input *DescribeVolumeAttributeInput) (req *aws.Request, output *DescribeVolumeAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeVolumeAttribute == nil { - opDescribeVolumeAttribute = &aws.Operation{ - Name: "DescribeVolumeAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DescribeVolumeAttributeRequest(input *DescribeVolumeAttributeInput) (req *request.Request, output *DescribeVolumeAttributeOutput) { + op := &request.Operation{ + Name: opDescribeVolumeAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeVolumeAttributeInput{} } - req = c.newRequest(opDescribeVolumeAttribute, input, output) + req = c.newRequest(op, input, output) output = &DescribeVolumeAttributeOutput{} req.Data = output return @@ -4791,32 +4050,27 @@ func (c *EC2) DescribeVolumeAttribute(input *DescribeVolumeAttributeInput) (*Des return out, err } -var opDescribeVolumeAttribute *aws.Operation +const opDescribeVolumeStatus = "DescribeVolumeStatus" // DescribeVolumeStatusRequest generates a request for the DescribeVolumeStatus operation. -func (c *EC2) DescribeVolumeStatusRequest(input *DescribeVolumeStatusInput) (req *aws.Request, output *DescribeVolumeStatusOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeVolumeStatus == nil { - opDescribeVolumeStatus = &aws.Operation{ - Name: "DescribeVolumeStatus", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxResults", - TruncationToken: "", - }, - } +func (c *EC2) DescribeVolumeStatusRequest(input *DescribeVolumeStatusInput) (req *request.Request, output *DescribeVolumeStatusOutput) { + op := &request.Operation{ + Name: opDescribeVolumeStatus, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, } if input == nil { input = &DescribeVolumeStatusInput{} } - req = c.newRequest(opDescribeVolumeStatus, input, output) + req = c.newRequest(op, input, output) output = &DescribeVolumeStatusOutput{} req.Data = output return @@ -4870,32 +4124,27 @@ func (c *EC2) DescribeVolumeStatusPages(input *DescribeVolumeStatusInput, fn fun }) } -var opDescribeVolumeStatus *aws.Operation +const opDescribeVolumes = "DescribeVolumes" // DescribeVolumesRequest generates a request for the DescribeVolumes operation. -func (c *EC2) DescribeVolumesRequest(input *DescribeVolumesInput) (req *aws.Request, output *DescribeVolumesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeVolumes == nil { - opDescribeVolumes = &aws.Operation{ - Name: "DescribeVolumes", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"NextToken"}, - OutputTokens: []string{"NextToken"}, - LimitToken: "MaxResults", - TruncationToken: "", - }, - } +func (c *EC2) DescribeVolumesRequest(input *DescribeVolumesInput) (req *request.Request, output *DescribeVolumesOutput) { + op := &request.Operation{ + Name: opDescribeVolumes, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, } if input == nil { input = &DescribeVolumesInput{} } - req = c.newRequest(opDescribeVolumes, input, output) + req = c.newRequest(op, input, output) output = &DescribeVolumesOutput{} req.Data = output return @@ -4925,282 +4174,468 @@ func (c *EC2) DescribeVolumesPages(input *DescribeVolumesInput, fn func(p *Descr }) } -var opDescribeVolumes *aws.Operation - -// DetachClassicLinkVPCRequest generates a request for the DetachClassicLinkVPC operation. -func (c *EC2) DetachClassicLinkVPCRequest(input *DetachClassicLinkVPCInput) (req *aws.Request, output *DetachClassicLinkVPCOutput) { - oprw.Lock() - defer oprw.Unlock() +const opDescribeVpcAttribute = "DescribeVpcAttribute" - if opDetachClassicLinkVPC == nil { - opDetachClassicLinkVPC = &aws.Operation{ - Name: "DetachClassicLinkVpc", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DescribeVpcAttributeRequest generates a request for the DescribeVpcAttribute operation. +func (c *EC2) DescribeVpcAttributeRequest(input *DescribeVpcAttributeInput) (req *request.Request, output *DescribeVpcAttributeOutput) { + op := &request.Operation{ + Name: opDescribeVpcAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DetachClassicLinkVPCInput{} + input = &DescribeVpcAttributeInput{} } - req = c.newRequest(opDetachClassicLinkVPC, input, output) - output = &DetachClassicLinkVPCOutput{} + req = c.newRequest(op, input, output) + output = &DescribeVpcAttributeOutput{} req.Data = output return } -// Unlinks (detaches) a linked EC2-Classic instance from a VPC. After the instance -// has been unlinked, the VPC security groups are no longer associated with -// it. An instance is automatically unlinked from a VPC when it's stopped. -func (c *EC2) DetachClassicLinkVPC(input *DetachClassicLinkVPCInput) (*DetachClassicLinkVPCOutput, error) { - req, out := c.DetachClassicLinkVPCRequest(input) +// Describes the specified attribute of the specified VPC. You can specify only +// one attribute at a time. +func (c *EC2) DescribeVpcAttribute(input *DescribeVpcAttributeInput) (*DescribeVpcAttributeOutput, error) { + req, out := c.DescribeVpcAttributeRequest(input) err := req.Send() return out, err } -var opDetachClassicLinkVPC *aws.Operation - -// DetachInternetGatewayRequest generates a request for the DetachInternetGateway operation. -func (c *EC2) DetachInternetGatewayRequest(input *DetachInternetGatewayInput) (req *aws.Request, output *DetachInternetGatewayOutput) { - oprw.Lock() - defer oprw.Unlock() +const opDescribeVpcClassicLink = "DescribeVpcClassicLink" - if opDetachInternetGateway == nil { - opDetachInternetGateway = &aws.Operation{ - Name: "DetachInternetGateway", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DescribeVpcClassicLinkRequest generates a request for the DescribeVpcClassicLink operation. +func (c *EC2) DescribeVpcClassicLinkRequest(input *DescribeVpcClassicLinkInput) (req *request.Request, output *DescribeVpcClassicLinkOutput) { + op := &request.Operation{ + Name: opDescribeVpcClassicLink, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DetachInternetGatewayInput{} + input = &DescribeVpcClassicLinkInput{} } - req = c.newRequest(opDetachInternetGateway, input, output) - output = &DetachInternetGatewayOutput{} + req = c.newRequest(op, input, output) + output = &DescribeVpcClassicLinkOutput{} req.Data = output return } -// Detaches an Internet gateway from a VPC, disabling connectivity between the -// Internet and the VPC. The VPC must not contain any running instances with -// Elastic IP addresses. -func (c *EC2) DetachInternetGateway(input *DetachInternetGatewayInput) (*DetachInternetGatewayOutput, error) { - req, out := c.DetachInternetGatewayRequest(input) +// Describes the ClassicLink status of one or more VPCs. +func (c *EC2) DescribeVpcClassicLink(input *DescribeVpcClassicLinkInput) (*DescribeVpcClassicLinkOutput, error) { + req, out := c.DescribeVpcClassicLinkRequest(input) err := req.Send() return out, err } -var opDetachInternetGateway *aws.Operation - -// DetachNetworkInterfaceRequest generates a request for the DetachNetworkInterface operation. -func (c *EC2) DetachNetworkInterfaceRequest(input *DetachNetworkInterfaceInput) (req *aws.Request, output *DetachNetworkInterfaceOutput) { - oprw.Lock() - defer oprw.Unlock() +const opDescribeVpcEndpointServices = "DescribeVpcEndpointServices" - if opDetachNetworkInterface == nil { - opDetachNetworkInterface = &aws.Operation{ - Name: "DetachNetworkInterface", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DescribeVpcEndpointServicesRequest generates a request for the DescribeVpcEndpointServices operation. +func (c *EC2) DescribeVpcEndpointServicesRequest(input *DescribeVpcEndpointServicesInput) (req *request.Request, output *DescribeVpcEndpointServicesOutput) { + op := &request.Operation{ + Name: opDescribeVpcEndpointServices, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DetachNetworkInterfaceInput{} + input = &DescribeVpcEndpointServicesInput{} } - req = c.newRequest(opDetachNetworkInterface, input, output) - output = &DetachNetworkInterfaceOutput{} + req = c.newRequest(op, input, output) + output = &DescribeVpcEndpointServicesOutput{} req.Data = output return } -// Detaches a network interface from an instance. -func (c *EC2) DetachNetworkInterface(input *DetachNetworkInterfaceInput) (*DetachNetworkInterfaceOutput, error) { - req, out := c.DetachNetworkInterfaceRequest(input) +// Describes all supported AWS services that can be specified when creating +// a VPC endpoint. +func (c *EC2) DescribeVpcEndpointServices(input *DescribeVpcEndpointServicesInput) (*DescribeVpcEndpointServicesOutput, error) { + req, out := c.DescribeVpcEndpointServicesRequest(input) err := req.Send() return out, err } -var opDetachNetworkInterface *aws.Operation +const opDescribeVpcEndpoints = "DescribeVpcEndpoints" -// DetachVPNGatewayRequest generates a request for the DetachVPNGateway operation. -func (c *EC2) DetachVPNGatewayRequest(input *DetachVPNGatewayInput) (req *aws.Request, output *DetachVPNGatewayOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDetachVPNGateway == nil { - opDetachVPNGateway = &aws.Operation{ - Name: "DetachVpnGateway", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DescribeVpcEndpointsRequest generates a request for the DescribeVpcEndpoints operation. +func (c *EC2) DescribeVpcEndpointsRequest(input *DescribeVpcEndpointsInput) (req *request.Request, output *DescribeVpcEndpointsOutput) { + op := &request.Operation{ + Name: opDescribeVpcEndpoints, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DetachVPNGatewayInput{} + input = &DescribeVpcEndpointsInput{} } - req = c.newRequest(opDetachVPNGateway, input, output) - output = &DetachVPNGatewayOutput{} + req = c.newRequest(op, input, output) + output = &DescribeVpcEndpointsOutput{} req.Data = output return } -// Detaches a virtual private gateway from a VPC. You do this if you're planning -// to turn off the VPC and not use it anymore. You can confirm a virtual private -// gateway has been completely detached from a VPC by describing the virtual -// private gateway (any attachments to the virtual private gateway are also -// described). -// -// You must wait for the attachment's state to switch to detached before you -// can delete the VPC or attach a different VPC to the virtual private gateway. -func (c *EC2) DetachVPNGateway(input *DetachVPNGatewayInput) (*DetachVPNGatewayOutput, error) { - req, out := c.DetachVPNGatewayRequest(input) +// Describes one or more of your VPC endpoints. +func (c *EC2) DescribeVpcEndpoints(input *DescribeVpcEndpointsInput) (*DescribeVpcEndpointsOutput, error) { + req, out := c.DescribeVpcEndpointsRequest(input) err := req.Send() return out, err } -var opDetachVPNGateway *aws.Operation - -// DetachVolumeRequest generates a request for the DetachVolume operation. -func (c *EC2) DetachVolumeRequest(input *DetachVolumeInput) (req *aws.Request, output *VolumeAttachment) { - oprw.Lock() - defer oprw.Unlock() +const opDescribeVpcPeeringConnections = "DescribeVpcPeeringConnections" - if opDetachVolume == nil { - opDetachVolume = &aws.Operation{ - Name: "DetachVolume", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DescribeVpcPeeringConnectionsRequest generates a request for the DescribeVpcPeeringConnections operation. +func (c *EC2) DescribeVpcPeeringConnectionsRequest(input *DescribeVpcPeeringConnectionsInput) (req *request.Request, output *DescribeVpcPeeringConnectionsOutput) { + op := &request.Operation{ + Name: opDescribeVpcPeeringConnections, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DetachVolumeInput{} + input = &DescribeVpcPeeringConnectionsInput{} } - req = c.newRequest(opDetachVolume, input, output) - output = &VolumeAttachment{} + req = c.newRequest(op, input, output) + output = &DescribeVpcPeeringConnectionsOutput{} req.Data = output return } -// Detaches an EBS volume from an instance. Make sure to unmount any file systems -// on the device within your operating system before detaching the volume. Failure -// to do so results in the volume being stuck in a busy state while detaching. -// -// If an Amazon EBS volume is the root device of an instance, it can't be detached -// while the instance is running. To detach the root volume, stop the instance -// first. -// -// When a volume with an AWS Marketplace product code is detached from an instance, -// the product code is no longer associated with the instance. -// -// For more information, see Detaching an Amazon EBS Volume (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-detaching-volume.html) -// in the Amazon Elastic Compute Cloud User Guide. -func (c *EC2) DetachVolume(input *DetachVolumeInput) (*VolumeAttachment, error) { - req, out := c.DetachVolumeRequest(input) +// Describes one or more of your VPC peering connections. +func (c *EC2) DescribeVpcPeeringConnections(input *DescribeVpcPeeringConnectionsInput) (*DescribeVpcPeeringConnectionsOutput, error) { + req, out := c.DescribeVpcPeeringConnectionsRequest(input) err := req.Send() return out, err } -var opDetachVolume *aws.Operation +const opDescribeVpcs = "DescribeVpcs" -// DisableVGWRoutePropagationRequest generates a request for the DisableVGWRoutePropagation operation. -func (c *EC2) DisableVGWRoutePropagationRequest(input *DisableVGWRoutePropagationInput) (req *aws.Request, output *DisableVGWRoutePropagationOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDisableVGWRoutePropagation == nil { - opDisableVGWRoutePropagation = &aws.Operation{ - Name: "DisableVgwRoutePropagation", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DescribeVpcsRequest generates a request for the DescribeVpcs operation. +func (c *EC2) DescribeVpcsRequest(input *DescribeVpcsInput) (req *request.Request, output *DescribeVpcsOutput) { + op := &request.Operation{ + Name: opDescribeVpcs, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DisableVGWRoutePropagationInput{} + input = &DescribeVpcsInput{} } - req = c.newRequest(opDisableVGWRoutePropagation, input, output) - output = &DisableVGWRoutePropagationOutput{} + req = c.newRequest(op, input, output) + output = &DescribeVpcsOutput{} req.Data = output return } -// Disables a virtual private gateway (VGW) from propagating routes to a specified -// route table of a VPC. -func (c *EC2) DisableVGWRoutePropagation(input *DisableVGWRoutePropagationInput) (*DisableVGWRoutePropagationOutput, error) { - req, out := c.DisableVGWRoutePropagationRequest(input) +// Describes one or more of your VPCs. +func (c *EC2) DescribeVpcs(input *DescribeVpcsInput) (*DescribeVpcsOutput, error) { + req, out := c.DescribeVpcsRequest(input) err := req.Send() return out, err } -var opDisableVGWRoutePropagation *aws.Operation +const opDescribeVpnConnections = "DescribeVpnConnections" -// DisableVPCClassicLinkRequest generates a request for the DisableVPCClassicLink operation. -func (c *EC2) DisableVPCClassicLinkRequest(input *DisableVPCClassicLinkInput) (req *aws.Request, output *DisableVPCClassicLinkOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDisableVPCClassicLink == nil { - opDisableVPCClassicLink = &aws.Operation{ - Name: "DisableVpcClassicLink", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DescribeVpnConnectionsRequest generates a request for the DescribeVpnConnections operation. +func (c *EC2) DescribeVpnConnectionsRequest(input *DescribeVpnConnectionsInput) (req *request.Request, output *DescribeVpnConnectionsOutput) { + op := &request.Operation{ + Name: opDescribeVpnConnections, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DisableVPCClassicLinkInput{} + input = &DescribeVpnConnectionsInput{} } - req = c.newRequest(opDisableVPCClassicLink, input, output) - output = &DisableVPCClassicLinkOutput{} + req = c.newRequest(op, input, output) + output = &DescribeVpnConnectionsOutput{} req.Data = output return } -// Disables ClassicLink for a VPC. You cannot disable ClassicLink for a VPC -// that has EC2-Classic instances linked to it. -func (c *EC2) DisableVPCClassicLink(input *DisableVPCClassicLinkInput) (*DisableVPCClassicLinkOutput, error) { - req, out := c.DisableVPCClassicLinkRequest(input) +// Describes one or more of your VPN connections. +// +// For more information about VPN connections, see Adding a Hardware Virtual +// Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) DescribeVpnConnections(input *DescribeVpnConnectionsInput) (*DescribeVpnConnectionsOutput, error) { + req, out := c.DescribeVpnConnectionsRequest(input) err := req.Send() return out, err } -var opDisableVPCClassicLink *aws.Operation - -// DisassociateAddressRequest generates a request for the DisassociateAddress operation. -func (c *EC2) DisassociateAddressRequest(input *DisassociateAddressInput) (req *aws.Request, output *DisassociateAddressOutput) { - oprw.Lock() - defer oprw.Unlock() +const opDescribeVpnGateways = "DescribeVpnGateways" - if opDisassociateAddress == nil { - opDisassociateAddress = &aws.Operation{ - Name: "DisassociateAddress", - HTTPMethod: "POST", - HTTPPath: "/", - } +// DescribeVpnGatewaysRequest generates a request for the DescribeVpnGateways operation. +func (c *EC2) DescribeVpnGatewaysRequest(input *DescribeVpnGatewaysInput) (req *request.Request, output *DescribeVpnGatewaysOutput) { + op := &request.Operation{ + Name: opDescribeVpnGateways, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &DisassociateAddressInput{} + input = &DescribeVpnGatewaysInput{} } - req = c.newRequest(opDisassociateAddress, input, output) - output = &DisassociateAddressOutput{} + req = c.newRequest(op, input, output) + output = &DescribeVpnGatewaysOutput{} req.Data = output return } -// Disassociates an Elastic IP address from the instance or network interface -// it's associated with. +// Describes one or more of your virtual private gateways. +// +// For more information about virtual private gateways, see Adding an IPsec +// Hardware VPN to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// in the Amazon Virtual Private Cloud User Guide. +func (c *EC2) DescribeVpnGateways(input *DescribeVpnGatewaysInput) (*DescribeVpnGatewaysOutput, error) { + req, out := c.DescribeVpnGatewaysRequest(input) + err := req.Send() + return out, err +} + +const opDetachClassicLinkVpc = "DetachClassicLinkVpc" + +// DetachClassicLinkVpcRequest generates a request for the DetachClassicLinkVpc operation. +func (c *EC2) DetachClassicLinkVpcRequest(input *DetachClassicLinkVpcInput) (req *request.Request, output *DetachClassicLinkVpcOutput) { + op := &request.Operation{ + Name: opDetachClassicLinkVpc, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachClassicLinkVpcInput{} + } + + req = c.newRequest(op, input, output) + output = &DetachClassicLinkVpcOutput{} + req.Data = output + return +} + +// Unlinks (detaches) a linked EC2-Classic instance from a VPC. After the instance +// has been unlinked, the VPC security groups are no longer associated with +// it. An instance is automatically unlinked from a VPC when it's stopped. +func (c *EC2) DetachClassicLinkVpc(input *DetachClassicLinkVpcInput) (*DetachClassicLinkVpcOutput, error) { + req, out := c.DetachClassicLinkVpcRequest(input) + err := req.Send() + return out, err +} + +const opDetachInternetGateway = "DetachInternetGateway" + +// DetachInternetGatewayRequest generates a request for the DetachInternetGateway operation. +func (c *EC2) DetachInternetGatewayRequest(input *DetachInternetGatewayInput) (req *request.Request, output *DetachInternetGatewayOutput) { + op := &request.Operation{ + Name: opDetachInternetGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachInternetGatewayInput{} + } + + req = c.newRequest(op, input, output) + output = &DetachInternetGatewayOutput{} + req.Data = output + return +} + +// Detaches an Internet gateway from a VPC, disabling connectivity between the +// Internet and the VPC. The VPC must not contain any running instances with +// Elastic IP addresses. +func (c *EC2) DetachInternetGateway(input *DetachInternetGatewayInput) (*DetachInternetGatewayOutput, error) { + req, out := c.DetachInternetGatewayRequest(input) + err := req.Send() + return out, err +} + +const opDetachNetworkInterface = "DetachNetworkInterface" + +// DetachNetworkInterfaceRequest generates a request for the DetachNetworkInterface operation. +func (c *EC2) DetachNetworkInterfaceRequest(input *DetachNetworkInterfaceInput) (req *request.Request, output *DetachNetworkInterfaceOutput) { + op := &request.Operation{ + Name: opDetachNetworkInterface, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachNetworkInterfaceInput{} + } + + req = c.newRequest(op, input, output) + output = &DetachNetworkInterfaceOutput{} + req.Data = output + return +} + +// Detaches a network interface from an instance. +func (c *EC2) DetachNetworkInterface(input *DetachNetworkInterfaceInput) (*DetachNetworkInterfaceOutput, error) { + req, out := c.DetachNetworkInterfaceRequest(input) + err := req.Send() + return out, err +} + +const opDetachVolume = "DetachVolume" + +// DetachVolumeRequest generates a request for the DetachVolume operation. +func (c *EC2) DetachVolumeRequest(input *DetachVolumeInput) (req *request.Request, output *VolumeAttachment) { + op := &request.Operation{ + Name: opDetachVolume, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachVolumeInput{} + } + + req = c.newRequest(op, input, output) + output = &VolumeAttachment{} + req.Data = output + return +} + +// Detaches an EBS volume from an instance. Make sure to unmount any file systems +// on the device within your operating system before detaching the volume. Failure +// to do so results in the volume being stuck in a busy state while detaching. +// +// If an Amazon EBS volume is the root device of an instance, it can't be detached +// while the instance is running. To detach the root volume, stop the instance +// first. +// +// When a volume with an AWS Marketplace product code is detached from an instance, +// the product code is no longer associated with the instance. +// +// For more information, see Detaching an Amazon EBS Volume (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-detaching-volume.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) DetachVolume(input *DetachVolumeInput) (*VolumeAttachment, error) { + req, out := c.DetachVolumeRequest(input) + err := req.Send() + return out, err +} + +const opDetachVpnGateway = "DetachVpnGateway" + +// DetachVpnGatewayRequest generates a request for the DetachVpnGateway operation. +func (c *EC2) DetachVpnGatewayRequest(input *DetachVpnGatewayInput) (req *request.Request, output *DetachVpnGatewayOutput) { + op := &request.Operation{ + Name: opDetachVpnGateway, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachVpnGatewayInput{} + } + + req = c.newRequest(op, input, output) + output = &DetachVpnGatewayOutput{} + req.Data = output + return +} + +// Detaches a virtual private gateway from a VPC. You do this if you're planning +// to turn off the VPC and not use it anymore. You can confirm a virtual private +// gateway has been completely detached from a VPC by describing the virtual +// private gateway (any attachments to the virtual private gateway are also +// described). +// +// You must wait for the attachment's state to switch to detached before you +// can delete the VPC or attach a different VPC to the virtual private gateway. +func (c *EC2) DetachVpnGateway(input *DetachVpnGatewayInput) (*DetachVpnGatewayOutput, error) { + req, out := c.DetachVpnGatewayRequest(input) + err := req.Send() + return out, err +} + +const opDisableVgwRoutePropagation = "DisableVgwRoutePropagation" + +// DisableVgwRoutePropagationRequest generates a request for the DisableVgwRoutePropagation operation. +func (c *EC2) DisableVgwRoutePropagationRequest(input *DisableVgwRoutePropagationInput) (req *request.Request, output *DisableVgwRoutePropagationOutput) { + op := &request.Operation{ + Name: opDisableVgwRoutePropagation, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DisableVgwRoutePropagationInput{} + } + + req = c.newRequest(op, input, output) + output = &DisableVgwRoutePropagationOutput{} + req.Data = output + return +} + +// Disables a virtual private gateway (VGW) from propagating routes to a specified +// route table of a VPC. +func (c *EC2) DisableVgwRoutePropagation(input *DisableVgwRoutePropagationInput) (*DisableVgwRoutePropagationOutput, error) { + req, out := c.DisableVgwRoutePropagationRequest(input) + err := req.Send() + return out, err +} + +const opDisableVpcClassicLink = "DisableVpcClassicLink" + +// DisableVpcClassicLinkRequest generates a request for the DisableVpcClassicLink operation. +func (c *EC2) DisableVpcClassicLinkRequest(input *DisableVpcClassicLinkInput) (req *request.Request, output *DisableVpcClassicLinkOutput) { + op := &request.Operation{ + Name: opDisableVpcClassicLink, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DisableVpcClassicLinkInput{} + } + + req = c.newRequest(op, input, output) + output = &DisableVpcClassicLinkOutput{} + req.Data = output + return +} + +// Disables ClassicLink for a VPC. You cannot disable ClassicLink for a VPC +// that has EC2-Classic instances linked to it. +func (c *EC2) DisableVpcClassicLink(input *DisableVpcClassicLinkInput) (*DisableVpcClassicLinkOutput, error) { + req, out := c.DisableVpcClassicLinkRequest(input) + err := req.Send() + return out, err +} + +const opDisassociateAddress = "DisassociateAddress" + +// DisassociateAddressRequest generates a request for the DisassociateAddress operation. +func (c *EC2) DisassociateAddressRequest(input *DisassociateAddressInput) (req *request.Request, output *DisassociateAddressOutput) { + op := &request.Operation{ + Name: opDisassociateAddress, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DisassociateAddressInput{} + } + + req = c.newRequest(op, input, output) + output = &DisassociateAddressOutput{} + req.Data = output + return +} + +// Disassociates an Elastic IP address from the instance or network interface +// it's associated with. // // An Elastic IP address is for use in either the EC2-Classic platform or in // a VPC. For more information, see Elastic IP Addresses (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) @@ -5214,26 +4649,21 @@ func (c *EC2) DisassociateAddress(input *DisassociateAddressInput) (*Disassociat return out, err } -var opDisassociateAddress *aws.Operation +const opDisassociateRouteTable = "DisassociateRouteTable" // DisassociateRouteTableRequest generates a request for the DisassociateRouteTable operation. -func (c *EC2) DisassociateRouteTableRequest(input *DisassociateRouteTableInput) (req *aws.Request, output *DisassociateRouteTableOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDisassociateRouteTable == nil { - opDisassociateRouteTable = &aws.Operation{ - Name: "DisassociateRouteTable", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) DisassociateRouteTableRequest(input *DisassociateRouteTableInput) (req *request.Request, output *DisassociateRouteTableOutput) { + op := &request.Operation{ + Name: opDisassociateRouteTable, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DisassociateRouteTableInput{} } - req = c.newRequest(opDisassociateRouteTable, input, output) + req = c.newRequest(op, input, output) output = &DisassociateRouteTableOutput{} req.Data = output return @@ -5251,130 +4681,110 @@ func (c *EC2) DisassociateRouteTable(input *DisassociateRouteTableInput) (*Disas return out, err } -var opDisassociateRouteTable *aws.Operation +const opEnableVgwRoutePropagation = "EnableVgwRoutePropagation" -// EnableVGWRoutePropagationRequest generates a request for the EnableVGWRoutePropagation operation. -func (c *EC2) EnableVGWRoutePropagationRequest(input *EnableVGWRoutePropagationInput) (req *aws.Request, output *EnableVGWRoutePropagationOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opEnableVGWRoutePropagation == nil { - opEnableVGWRoutePropagation = &aws.Operation{ - Name: "EnableVgwRoutePropagation", - HTTPMethod: "POST", - HTTPPath: "/", - } +// EnableVgwRoutePropagationRequest generates a request for the EnableVgwRoutePropagation operation. +func (c *EC2) EnableVgwRoutePropagationRequest(input *EnableVgwRoutePropagationInput) (req *request.Request, output *EnableVgwRoutePropagationOutput) { + op := &request.Operation{ + Name: opEnableVgwRoutePropagation, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &EnableVGWRoutePropagationInput{} + input = &EnableVgwRoutePropagationInput{} } - req = c.newRequest(opEnableVGWRoutePropagation, input, output) - output = &EnableVGWRoutePropagationOutput{} + req = c.newRequest(op, input, output) + output = &EnableVgwRoutePropagationOutput{} req.Data = output return } // Enables a virtual private gateway (VGW) to propagate routes to the specified // route table of a VPC. -func (c *EC2) EnableVGWRoutePropagation(input *EnableVGWRoutePropagationInput) (*EnableVGWRoutePropagationOutput, error) { - req, out := c.EnableVGWRoutePropagationRequest(input) +func (c *EC2) EnableVgwRoutePropagation(input *EnableVgwRoutePropagationInput) (*EnableVgwRoutePropagationOutput, error) { + req, out := c.EnableVgwRoutePropagationRequest(input) err := req.Send() return out, err } -var opEnableVGWRoutePropagation *aws.Operation - -// EnableVPCClassicLinkRequest generates a request for the EnableVPCClassicLink operation. -func (c *EC2) EnableVPCClassicLinkRequest(input *EnableVPCClassicLinkInput) (req *aws.Request, output *EnableVPCClassicLinkOutput) { - oprw.Lock() - defer oprw.Unlock() +const opEnableVolumeIO = "EnableVolumeIO" - if opEnableVPCClassicLink == nil { - opEnableVPCClassicLink = &aws.Operation{ - Name: "EnableVpcClassicLink", - HTTPMethod: "POST", - HTTPPath: "/", - } +// EnableVolumeIORequest generates a request for the EnableVolumeIO operation. +func (c *EC2) EnableVolumeIORequest(input *EnableVolumeIOInput) (req *request.Request, output *EnableVolumeIOOutput) { + op := &request.Operation{ + Name: opEnableVolumeIO, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &EnableVPCClassicLinkInput{} + input = &EnableVolumeIOInput{} } - req = c.newRequest(opEnableVPCClassicLink, input, output) - output = &EnableVPCClassicLinkOutput{} + req = c.newRequest(op, input, output) + output = &EnableVolumeIOOutput{} req.Data = output return } -// Enables a VPC for ClassicLink. You can then link EC2-Classic instances to -// your ClassicLink-enabled VPC to allow communication over private IP addresses. -// You cannot enable your VPC for ClassicLink if any of your VPC's route tables -// have existing routes for address ranges within the 10.0.0.0/8 IP address -// range, excluding local routes for VPCs in the 10.0.0.0/16 and 10.1.0.0/16 -// IP address ranges. For more information, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) -// in the Amazon Elastic Compute Cloud User Guide. -func (c *EC2) EnableVPCClassicLink(input *EnableVPCClassicLinkInput) (*EnableVPCClassicLinkOutput, error) { - req, out := c.EnableVPCClassicLinkRequest(input) +// Enables I/O operations for a volume that had I/O operations disabled because +// the data on the volume was potentially inconsistent. +func (c *EC2) EnableVolumeIO(input *EnableVolumeIOInput) (*EnableVolumeIOOutput, error) { + req, out := c.EnableVolumeIORequest(input) err := req.Send() return out, err } -var opEnableVPCClassicLink *aws.Operation - -// EnableVolumeIORequest generates a request for the EnableVolumeIO operation. -func (c *EC2) EnableVolumeIORequest(input *EnableVolumeIOInput) (req *aws.Request, output *EnableVolumeIOOutput) { - oprw.Lock() - defer oprw.Unlock() +const opEnableVpcClassicLink = "EnableVpcClassicLink" - if opEnableVolumeIO == nil { - opEnableVolumeIO = &aws.Operation{ - Name: "EnableVolumeIO", - HTTPMethod: "POST", - HTTPPath: "/", - } +// EnableVpcClassicLinkRequest generates a request for the EnableVpcClassicLink operation. +func (c *EC2) EnableVpcClassicLinkRequest(input *EnableVpcClassicLinkInput) (req *request.Request, output *EnableVpcClassicLinkOutput) { + op := &request.Operation{ + Name: opEnableVpcClassicLink, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &EnableVolumeIOInput{} + input = &EnableVpcClassicLinkInput{} } - req = c.newRequest(opEnableVolumeIO, input, output) - output = &EnableVolumeIOOutput{} + req = c.newRequest(op, input, output) + output = &EnableVpcClassicLinkOutput{} req.Data = output return } -// Enables I/O operations for a volume that had I/O operations disabled because -// the data on the volume was potentially inconsistent. -func (c *EC2) EnableVolumeIO(input *EnableVolumeIOInput) (*EnableVolumeIOOutput, error) { - req, out := c.EnableVolumeIORequest(input) +// Enables a VPC for ClassicLink. You can then link EC2-Classic instances to +// your ClassicLink-enabled VPC to allow communication over private IP addresses. +// You cannot enable your VPC for ClassicLink if any of your VPC's route tables +// have existing routes for address ranges within the 10.0.0.0/8 IP address +// range, excluding local routes for VPCs in the 10.0.0.0/16 and 10.1.0.0/16 +// IP address ranges. For more information, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) +// in the Amazon Elastic Compute Cloud User Guide. +func (c *EC2) EnableVpcClassicLink(input *EnableVpcClassicLinkInput) (*EnableVpcClassicLinkOutput, error) { + req, out := c.EnableVpcClassicLinkRequest(input) err := req.Send() return out, err } -var opEnableVolumeIO *aws.Operation +const opGetConsoleOutput = "GetConsoleOutput" // GetConsoleOutputRequest generates a request for the GetConsoleOutput operation. -func (c *EC2) GetConsoleOutputRequest(input *GetConsoleOutputInput) (req *aws.Request, output *GetConsoleOutputOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opGetConsoleOutput == nil { - opGetConsoleOutput = &aws.Operation{ - Name: "GetConsoleOutput", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) GetConsoleOutputRequest(input *GetConsoleOutputInput) (req *request.Request, output *GetConsoleOutputOutput) { + op := &request.Operation{ + Name: opGetConsoleOutput, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &GetConsoleOutputInput{} } - req = c.newRequest(opGetConsoleOutput, input, output) + req = c.newRequest(op, input, output) output = &GetConsoleOutputOutput{} req.Data = output return @@ -5404,26 +4814,21 @@ func (c *EC2) GetConsoleOutput(input *GetConsoleOutputInput) (*GetConsoleOutputO return out, err } -var opGetConsoleOutput *aws.Operation +const opGetPasswordData = "GetPasswordData" // GetPasswordDataRequest generates a request for the GetPasswordData operation. -func (c *EC2) GetPasswordDataRequest(input *GetPasswordDataInput) (req *aws.Request, output *GetPasswordDataOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opGetPasswordData == nil { - opGetPasswordData = &aws.Operation{ - Name: "GetPasswordData", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) GetPasswordDataRequest(input *GetPasswordDataInput) (req *request.Request, output *GetPasswordDataOutput) { + op := &request.Operation{ + Name: opGetPasswordData, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &GetPasswordDataInput{} } - req = c.newRequest(opGetPasswordData, input, output) + req = c.newRequest(op, input, output) output = &GetPasswordDataOutput{} req.Data = output return @@ -5449,26 +4854,21 @@ func (c *EC2) GetPasswordData(input *GetPasswordDataInput) (*GetPasswordDataOutp return out, err } -var opGetPasswordData *aws.Operation +const opImportImage = "ImportImage" // ImportImageRequest generates a request for the ImportImage operation. -func (c *EC2) ImportImageRequest(input *ImportImageInput) (req *aws.Request, output *ImportImageOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opImportImage == nil { - opImportImage = &aws.Operation{ - Name: "ImportImage", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ImportImageRequest(input *ImportImageInput) (req *request.Request, output *ImportImageOutput) { + op := &request.Operation{ + Name: opImportImage, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ImportImageInput{} } - req = c.newRequest(opImportImage, input, output) + req = c.newRequest(op, input, output) output = &ImportImageOutput{} req.Data = output return @@ -5482,26 +4882,21 @@ func (c *EC2) ImportImage(input *ImportImageInput) (*ImportImageOutput, error) { return out, err } -var opImportImage *aws.Operation +const opImportInstance = "ImportInstance" // ImportInstanceRequest generates a request for the ImportInstance operation. -func (c *EC2) ImportInstanceRequest(input *ImportInstanceInput) (req *aws.Request, output *ImportInstanceOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opImportInstance == nil { - opImportInstance = &aws.Operation{ - Name: "ImportInstance", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ImportInstanceRequest(input *ImportInstanceInput) (req *request.Request, output *ImportInstanceOutput) { + op := &request.Operation{ + Name: opImportInstance, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ImportInstanceInput{} } - req = c.newRequest(opImportInstance, input, output) + req = c.newRequest(op, input, output) output = &ImportInstanceOutput{} req.Data = output return @@ -5520,26 +4915,21 @@ func (c *EC2) ImportInstance(input *ImportInstanceInput) (*ImportInstanceOutput, return out, err } -var opImportInstance *aws.Operation +const opImportKeyPair = "ImportKeyPair" // ImportKeyPairRequest generates a request for the ImportKeyPair operation. -func (c *EC2) ImportKeyPairRequest(input *ImportKeyPairInput) (req *aws.Request, output *ImportKeyPairOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opImportKeyPair == nil { - opImportKeyPair = &aws.Operation{ - Name: "ImportKeyPair", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ImportKeyPairRequest(input *ImportKeyPairInput) (req *request.Request, output *ImportKeyPairOutput) { + op := &request.Operation{ + Name: opImportKeyPair, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ImportKeyPairInput{} } - req = c.newRequest(opImportKeyPair, input, output) + req = c.newRequest(op, input, output) output = &ImportKeyPairOutput{} req.Data = output return @@ -5559,26 +4949,21 @@ func (c *EC2) ImportKeyPair(input *ImportKeyPairInput) (*ImportKeyPairOutput, er return out, err } -var opImportKeyPair *aws.Operation +const opImportSnapshot = "ImportSnapshot" // ImportSnapshotRequest generates a request for the ImportSnapshot operation. -func (c *EC2) ImportSnapshotRequest(input *ImportSnapshotInput) (req *aws.Request, output *ImportSnapshotOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opImportSnapshot == nil { - opImportSnapshot = &aws.Operation{ - Name: "ImportSnapshot", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ImportSnapshotRequest(input *ImportSnapshotInput) (req *request.Request, output *ImportSnapshotOutput) { + op := &request.Operation{ + Name: opImportSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ImportSnapshotInput{} } - req = c.newRequest(opImportSnapshot, input, output) + req = c.newRequest(op, input, output) output = &ImportSnapshotOutput{} req.Data = output return @@ -5591,26 +4976,21 @@ func (c *EC2) ImportSnapshot(input *ImportSnapshotInput) (*ImportSnapshotOutput, return out, err } -var opImportSnapshot *aws.Operation +const opImportVolume = "ImportVolume" // ImportVolumeRequest generates a request for the ImportVolume operation. -func (c *EC2) ImportVolumeRequest(input *ImportVolumeInput) (req *aws.Request, output *ImportVolumeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opImportVolume == nil { - opImportVolume = &aws.Operation{ - Name: "ImportVolume", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ImportVolumeRequest(input *ImportVolumeInput) (req *request.Request, output *ImportVolumeOutput) { + op := &request.Operation{ + Name: opImportVolume, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ImportVolumeInput{} } - req = c.newRequest(opImportVolume, input, output) + req = c.newRequest(op, input, output) output = &ImportVolumeOutput{} req.Data = output return @@ -5628,26 +5008,21 @@ func (c *EC2) ImportVolume(input *ImportVolumeInput) (*ImportVolumeOutput, error return out, err } -var opImportVolume *aws.Operation +const opModifyImageAttribute = "ModifyImageAttribute" // ModifyImageAttributeRequest generates a request for the ModifyImageAttribute operation. -func (c *EC2) ModifyImageAttributeRequest(input *ModifyImageAttributeInput) (req *aws.Request, output *ModifyImageAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opModifyImageAttribute == nil { - opModifyImageAttribute = &aws.Operation{ - Name: "ModifyImageAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ModifyImageAttributeRequest(input *ModifyImageAttributeInput) (req *request.Request, output *ModifyImageAttributeOutput) { + op := &request.Operation{ + Name: opModifyImageAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ModifyImageAttributeInput{} } - req = c.newRequest(opModifyImageAttribute, input, output) + req = c.newRequest(op, input, output) output = &ModifyImageAttributeOutput{} req.Data = output return @@ -5664,26 +5039,21 @@ func (c *EC2) ModifyImageAttribute(input *ModifyImageAttributeInput) (*ModifyIma return out, err } -var opModifyImageAttribute *aws.Operation +const opModifyInstanceAttribute = "ModifyInstanceAttribute" // ModifyInstanceAttributeRequest generates a request for the ModifyInstanceAttribute operation. -func (c *EC2) ModifyInstanceAttributeRequest(input *ModifyInstanceAttributeInput) (req *aws.Request, output *ModifyInstanceAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opModifyInstanceAttribute == nil { - opModifyInstanceAttribute = &aws.Operation{ - Name: "ModifyInstanceAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ModifyInstanceAttributeRequest(input *ModifyInstanceAttributeInput) (req *request.Request, output *ModifyInstanceAttributeOutput) { + op := &request.Operation{ + Name: opModifyInstanceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ModifyInstanceAttributeInput{} } - req = c.newRequest(opModifyInstanceAttribute, input, output) + req = c.newRequest(op, input, output) output = &ModifyInstanceAttributeOutput{} req.Data = output return @@ -5701,26 +5071,21 @@ func (c *EC2) ModifyInstanceAttribute(input *ModifyInstanceAttributeInput) (*Mod return out, err } -var opModifyInstanceAttribute *aws.Operation +const opModifyNetworkInterfaceAttribute = "ModifyNetworkInterfaceAttribute" // ModifyNetworkInterfaceAttributeRequest generates a request for the ModifyNetworkInterfaceAttribute operation. -func (c *EC2) ModifyNetworkInterfaceAttributeRequest(input *ModifyNetworkInterfaceAttributeInput) (req *aws.Request, output *ModifyNetworkInterfaceAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opModifyNetworkInterfaceAttribute == nil { - opModifyNetworkInterfaceAttribute = &aws.Operation{ - Name: "ModifyNetworkInterfaceAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ModifyNetworkInterfaceAttributeRequest(input *ModifyNetworkInterfaceAttributeInput) (req *request.Request, output *ModifyNetworkInterfaceAttributeOutput) { + op := &request.Operation{ + Name: opModifyNetworkInterfaceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ModifyNetworkInterfaceAttributeInput{} } - req = c.newRequest(opModifyNetworkInterfaceAttribute, input, output) + req = c.newRequest(op, input, output) output = &ModifyNetworkInterfaceAttributeOutput{} req.Data = output return @@ -5734,26 +5099,21 @@ func (c *EC2) ModifyNetworkInterfaceAttribute(input *ModifyNetworkInterfaceAttri return out, err } -var opModifyNetworkInterfaceAttribute *aws.Operation +const opModifyReservedInstances = "ModifyReservedInstances" // ModifyReservedInstancesRequest generates a request for the ModifyReservedInstances operation. -func (c *EC2) ModifyReservedInstancesRequest(input *ModifyReservedInstancesInput) (req *aws.Request, output *ModifyReservedInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opModifyReservedInstances == nil { - opModifyReservedInstances = &aws.Operation{ - Name: "ModifyReservedInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ModifyReservedInstancesRequest(input *ModifyReservedInstancesInput) (req *request.Request, output *ModifyReservedInstancesOutput) { + op := &request.Operation{ + Name: opModifyReservedInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ModifyReservedInstancesInput{} } - req = c.newRequest(opModifyReservedInstances, input, output) + req = c.newRequest(op, input, output) output = &ModifyReservedInstancesOutput{} req.Data = output return @@ -5772,26 +5132,21 @@ func (c *EC2) ModifyReservedInstances(input *ModifyReservedInstancesInput) (*Mod return out, err } -var opModifyReservedInstances *aws.Operation +const opModifySnapshotAttribute = "ModifySnapshotAttribute" // ModifySnapshotAttributeRequest generates a request for the ModifySnapshotAttribute operation. -func (c *EC2) ModifySnapshotAttributeRequest(input *ModifySnapshotAttributeInput) (req *aws.Request, output *ModifySnapshotAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opModifySnapshotAttribute == nil { - opModifySnapshotAttribute = &aws.Operation{ - Name: "ModifySnapshotAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ModifySnapshotAttributeRequest(input *ModifySnapshotAttributeInput) (req *request.Request, output *ModifySnapshotAttributeOutput) { + op := &request.Operation{ + Name: opModifySnapshotAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ModifySnapshotAttributeInput{} } - req = c.newRequest(opModifySnapshotAttribute, input, output) + req = c.newRequest(op, input, output) output = &ModifySnapshotAttributeOutput{} req.Data = output return @@ -5814,26 +5169,21 @@ func (c *EC2) ModifySnapshotAttribute(input *ModifySnapshotAttributeInput) (*Mod return out, err } -var opModifySnapshotAttribute *aws.Operation +const opModifySubnetAttribute = "ModifySubnetAttribute" // ModifySubnetAttributeRequest generates a request for the ModifySubnetAttribute operation. -func (c *EC2) ModifySubnetAttributeRequest(input *ModifySubnetAttributeInput) (req *aws.Request, output *ModifySubnetAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opModifySubnetAttribute == nil { - opModifySubnetAttribute = &aws.Operation{ - Name: "ModifySubnetAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ModifySubnetAttributeRequest(input *ModifySubnetAttributeInput) (req *request.Request, output *ModifySubnetAttributeOutput) { + op := &request.Operation{ + Name: opModifySubnetAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ModifySubnetAttributeInput{} } - req = c.newRequest(opModifySubnetAttribute, input, output) + req = c.newRequest(op, input, output) output = &ModifySubnetAttributeOutput{} req.Data = output return @@ -5846,133 +5196,113 @@ func (c *EC2) ModifySubnetAttribute(input *ModifySubnetAttributeInput) (*ModifyS return out, err } -var opModifySubnetAttribute *aws.Operation +const opModifyVolumeAttribute = "ModifyVolumeAttribute" -// ModifyVPCAttributeRequest generates a request for the ModifyVPCAttribute operation. -func (c *EC2) ModifyVPCAttributeRequest(input *ModifyVPCAttributeInput) (req *aws.Request, output *ModifyVPCAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opModifyVPCAttribute == nil { - opModifyVPCAttribute = &aws.Operation{ - Name: "ModifyVpcAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +// ModifyVolumeAttributeRequest generates a request for the ModifyVolumeAttribute operation. +func (c *EC2) ModifyVolumeAttributeRequest(input *ModifyVolumeAttributeInput) (req *request.Request, output *ModifyVolumeAttributeOutput) { + op := &request.Operation{ + Name: opModifyVolumeAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &ModifyVPCAttributeInput{} + input = &ModifyVolumeAttributeInput{} } - req = c.newRequest(opModifyVPCAttribute, input, output) - output = &ModifyVPCAttributeOutput{} + req = c.newRequest(op, input, output) + output = &ModifyVolumeAttributeOutput{} req.Data = output return } -// Modifies the specified attribute of the specified VPC. -func (c *EC2) ModifyVPCAttribute(input *ModifyVPCAttributeInput) (*ModifyVPCAttributeOutput, error) { - req, out := c.ModifyVPCAttributeRequest(input) +// Modifies a volume attribute. +// +// By default, all I/O operations for the volume are suspended when the data +// on the volume is determined to be potentially inconsistent, to prevent undetectable, +// latent data corruption. The I/O access to the volume can be resumed by first +// enabling I/O access and then checking the data consistency on your volume. +// +// You can change the default behavior to resume I/O operations. We recommend +// that you change this only for boot volumes or for volumes that are stateless +// or disposable. +func (c *EC2) ModifyVolumeAttribute(input *ModifyVolumeAttributeInput) (*ModifyVolumeAttributeOutput, error) { + req, out := c.ModifyVolumeAttributeRequest(input) err := req.Send() return out, err } -var opModifyVPCAttribute *aws.Operation - -// ModifyVPCEndpointRequest generates a request for the ModifyVPCEndpoint operation. -func (c *EC2) ModifyVPCEndpointRequest(input *ModifyVPCEndpointInput) (req *aws.Request, output *ModifyVPCEndpointOutput) { - oprw.Lock() - defer oprw.Unlock() +const opModifyVpcAttribute = "ModifyVpcAttribute" - if opModifyVPCEndpoint == nil { - opModifyVPCEndpoint = &aws.Operation{ - Name: "ModifyVpcEndpoint", - HTTPMethod: "POST", - HTTPPath: "/", - } +// ModifyVpcAttributeRequest generates a request for the ModifyVpcAttribute operation. +func (c *EC2) ModifyVpcAttributeRequest(input *ModifyVpcAttributeInput) (req *request.Request, output *ModifyVpcAttributeOutput) { + op := &request.Operation{ + Name: opModifyVpcAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &ModifyVPCEndpointInput{} + input = &ModifyVpcAttributeInput{} } - req = c.newRequest(opModifyVPCEndpoint, input, output) - output = &ModifyVPCEndpointOutput{} + req = c.newRequest(op, input, output) + output = &ModifyVpcAttributeOutput{} req.Data = output return } -// Modifies attributes of a specified VPC endpoint. You can modify the policy -// associated with the endpoint, and you can add and remove route tables associated -// with the endpoint. -func (c *EC2) ModifyVPCEndpoint(input *ModifyVPCEndpointInput) (*ModifyVPCEndpointOutput, error) { - req, out := c.ModifyVPCEndpointRequest(input) +// Modifies the specified attribute of the specified VPC. +func (c *EC2) ModifyVpcAttribute(input *ModifyVpcAttributeInput) (*ModifyVpcAttributeOutput, error) { + req, out := c.ModifyVpcAttributeRequest(input) err := req.Send() return out, err } -var opModifyVPCEndpoint *aws.Operation +const opModifyVpcEndpoint = "ModifyVpcEndpoint" -// ModifyVolumeAttributeRequest generates a request for the ModifyVolumeAttribute operation. -func (c *EC2) ModifyVolumeAttributeRequest(input *ModifyVolumeAttributeInput) (req *aws.Request, output *ModifyVolumeAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opModifyVolumeAttribute == nil { - opModifyVolumeAttribute = &aws.Operation{ - Name: "ModifyVolumeAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +// ModifyVpcEndpointRequest generates a request for the ModifyVpcEndpoint operation. +func (c *EC2) ModifyVpcEndpointRequest(input *ModifyVpcEndpointInput) (req *request.Request, output *ModifyVpcEndpointOutput) { + op := &request.Operation{ + Name: opModifyVpcEndpoint, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &ModifyVolumeAttributeInput{} + input = &ModifyVpcEndpointInput{} } - req = c.newRequest(opModifyVolumeAttribute, input, output) - output = &ModifyVolumeAttributeOutput{} + req = c.newRequest(op, input, output) + output = &ModifyVpcEndpointOutput{} req.Data = output return } -// Modifies a volume attribute. -// -// By default, all I/O operations for the volume are suspended when the data -// on the volume is determined to be potentially inconsistent, to prevent undetectable, -// latent data corruption. The I/O access to the volume can be resumed by first -// enabling I/O access and then checking the data consistency on your volume. -// -// You can change the default behavior to resume I/O operations. We recommend -// that you change this only for boot volumes or for volumes that are stateless -// or disposable. -func (c *EC2) ModifyVolumeAttribute(input *ModifyVolumeAttributeInput) (*ModifyVolumeAttributeOutput, error) { - req, out := c.ModifyVolumeAttributeRequest(input) +// Modifies attributes of a specified VPC endpoint. You can modify the policy +// associated with the endpoint, and you can add and remove route tables associated +// with the endpoint. +func (c *EC2) ModifyVpcEndpoint(input *ModifyVpcEndpointInput) (*ModifyVpcEndpointOutput, error) { + req, out := c.ModifyVpcEndpointRequest(input) err := req.Send() return out, err } -var opModifyVolumeAttribute *aws.Operation +const opMonitorInstances = "MonitorInstances" // MonitorInstancesRequest generates a request for the MonitorInstances operation. -func (c *EC2) MonitorInstancesRequest(input *MonitorInstancesInput) (req *aws.Request, output *MonitorInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opMonitorInstances == nil { - opMonitorInstances = &aws.Operation{ - Name: "MonitorInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) MonitorInstancesRequest(input *MonitorInstancesInput) (req *request.Request, output *MonitorInstancesOutput) { + op := &request.Operation{ + Name: opMonitorInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &MonitorInstancesInput{} } - req = c.newRequest(opMonitorInstances, input, output) + req = c.newRequest(op, input, output) output = &MonitorInstancesOutput{} req.Data = output return @@ -5987,27 +5317,22 @@ func (c *EC2) MonitorInstances(input *MonitorInstancesInput) (*MonitorInstancesO return out, err } -var opMonitorInstances *aws.Operation +const opMoveAddressToVpc = "MoveAddressToVpc" -// MoveAddressToVPCRequest generates a request for the MoveAddressToVPC operation. -func (c *EC2) MoveAddressToVPCRequest(input *MoveAddressToVPCInput) (req *aws.Request, output *MoveAddressToVPCOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opMoveAddressToVPC == nil { - opMoveAddressToVPC = &aws.Operation{ - Name: "MoveAddressToVpc", - HTTPMethod: "POST", - HTTPPath: "/", - } +// MoveAddressToVpcRequest generates a request for the MoveAddressToVpc operation. +func (c *EC2) MoveAddressToVpcRequest(input *MoveAddressToVpcInput) (req *request.Request, output *MoveAddressToVpcOutput) { + op := &request.Operation{ + Name: opMoveAddressToVpc, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &MoveAddressToVPCInput{} + input = &MoveAddressToVpcInput{} } - req = c.newRequest(opMoveAddressToVPC, input, output) - output = &MoveAddressToVPCOutput{} + req = c.newRequest(op, input, output) + output = &MoveAddressToVpcOutput{} req.Data = output return } @@ -6019,32 +5344,27 @@ func (c *EC2) MoveAddressToVPCRequest(input *MoveAddressToVPCInput) (req *aws.Re // you move it back using the RestoreAddressToClassic request. You cannot move // an Elastic IP address that's allocated for use in the EC2-VPC platform to // the EC2-Classic platform. -func (c *EC2) MoveAddressToVPC(input *MoveAddressToVPCInput) (*MoveAddressToVPCOutput, error) { - req, out := c.MoveAddressToVPCRequest(input) +func (c *EC2) MoveAddressToVpc(input *MoveAddressToVpcInput) (*MoveAddressToVpcOutput, error) { + req, out := c.MoveAddressToVpcRequest(input) err := req.Send() return out, err } -var opMoveAddressToVPC *aws.Operation +const opPurchaseReservedInstancesOffering = "PurchaseReservedInstancesOffering" // PurchaseReservedInstancesOfferingRequest generates a request for the PurchaseReservedInstancesOffering operation. -func (c *EC2) PurchaseReservedInstancesOfferingRequest(input *PurchaseReservedInstancesOfferingInput) (req *aws.Request, output *PurchaseReservedInstancesOfferingOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opPurchaseReservedInstancesOffering == nil { - opPurchaseReservedInstancesOffering = &aws.Operation{ - Name: "PurchaseReservedInstancesOffering", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) PurchaseReservedInstancesOfferingRequest(input *PurchaseReservedInstancesOfferingInput) (req *request.Request, output *PurchaseReservedInstancesOfferingOutput) { + op := &request.Operation{ + Name: opPurchaseReservedInstancesOffering, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &PurchaseReservedInstancesOfferingInput{} } - req = c.newRequest(opPurchaseReservedInstancesOffering, input, output) + req = c.newRequest(op, input, output) output = &PurchaseReservedInstancesOfferingOutput{} req.Data = output return @@ -6052,9 +5372,8 @@ func (c *EC2) PurchaseReservedInstancesOfferingRequest(input *PurchaseReservedIn // Purchases a Reserved Instance for use with your account. With Amazon EC2 // Reserved Instances, you obtain a capacity reservation for a certain instance -// configuration over a specified period of time. You pay a lower usage rate -// than with On-Demand instances for the time that you actually use the capacity -// reservation. +// configuration over a specified period of time and pay a lower hourly rate +// compared to on-Demand Instance pricing. // // Use DescribeReservedInstancesOfferings to get a list of Reserved Instance // offerings that match your specifications. After you've purchased a Reserved @@ -6069,26 +5388,21 @@ func (c *EC2) PurchaseReservedInstancesOffering(input *PurchaseReservedInstances return out, err } -var opPurchaseReservedInstancesOffering *aws.Operation +const opRebootInstances = "RebootInstances" // RebootInstancesRequest generates a request for the RebootInstances operation. -func (c *EC2) RebootInstancesRequest(input *RebootInstancesInput) (req *aws.Request, output *RebootInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opRebootInstances == nil { - opRebootInstances = &aws.Operation{ - Name: "RebootInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) RebootInstancesRequest(input *RebootInstancesInput) (req *request.Request, output *RebootInstancesOutput) { + op := &request.Operation{ + Name: opRebootInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &RebootInstancesInput{} } - req = c.newRequest(opRebootInstances, input, output) + req = c.newRequest(op, input, output) output = &RebootInstancesOutput{} req.Data = output return @@ -6111,26 +5425,21 @@ func (c *EC2) RebootInstances(input *RebootInstancesInput) (*RebootInstancesOutp return out, err } -var opRebootInstances *aws.Operation +const opRegisterImage = "RegisterImage" // RegisterImageRequest generates a request for the RegisterImage operation. -func (c *EC2) RegisterImageRequest(input *RegisterImageInput) (req *aws.Request, output *RegisterImageOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opRegisterImage == nil { - opRegisterImage = &aws.Operation{ - Name: "RegisterImage", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) RegisterImageRequest(input *RegisterImageInput) (req *request.Request, output *RegisterImageOutput) { + op := &request.Operation{ + Name: opRegisterImage, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &RegisterImageInput{} } - req = c.newRequest(opRegisterImage, input, output) + req = c.newRequest(op, input, output) output = &RegisterImageOutput{} req.Data = output return @@ -6144,12 +5453,25 @@ func (c *EC2) RegisterImageRequest(input *RegisterImageInput) (req *aws.Request, // For Amazon EBS-backed instances, CreateImage creates and registers the AMI // in a single request, so you don't have to register the AMI yourself. // -// You can also use RegisterImage to create an Amazon EBS-backed AMI from a -// snapshot of a root device volume. For more information, see Launching an -// Instance from a Snapshot (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_LaunchingInstanceFromSnapshot.html) +// You can also use RegisterImage to create an Amazon EBS-backed Linux AMI +// from a snapshot of a root device volume. For more information, see Launching +// an Instance from a Snapshot (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_LaunchingInstanceFromSnapshot.html) // in the Amazon Elastic Compute Cloud User Guide. // -// If needed, you can deregister an AMI at any time. Any modifications you +// Some Linux distributions, such as Red Hat Enterprise Linux (RHEL) and SUSE +// Linux Enterprise Server (SLES), use the EC2 billingProduct code associated +// with an AMI to verify subscription status for package updates. Creating an +// AMI from an EBS snapshot does not maintain this billing code, and subsequent +// instances launched from such an AMI will not be able to connect to package +// update infrastructure. +// +// Similarly, although you can create a Windows AMI from a snapshot, you can't +// successfully launch an instance from the AMI. +// +// To create Windows AMIs or to create AMIs for Linux operating systems that +// must retain AMI billing codes to work properly, see CreateImage. +// +// If needed, you can deregister an AMI at any time. Any modifications you // make to an AMI backed by an instance store volume invalidates its registration. // If you make changes to an image, deregister the previous image and register // the new image. @@ -6162,27 +5484,22 @@ func (c *EC2) RegisterImage(input *RegisterImageInput) (*RegisterImageOutput, er return out, err } -var opRegisterImage *aws.Operation - -// RejectVPCPeeringConnectionRequest generates a request for the RejectVPCPeeringConnection operation. -func (c *EC2) RejectVPCPeeringConnectionRequest(input *RejectVPCPeeringConnectionInput) (req *aws.Request, output *RejectVPCPeeringConnectionOutput) { - oprw.Lock() - defer oprw.Unlock() +const opRejectVpcPeeringConnection = "RejectVpcPeeringConnection" - if opRejectVPCPeeringConnection == nil { - opRejectVPCPeeringConnection = &aws.Operation{ - Name: "RejectVpcPeeringConnection", - HTTPMethod: "POST", - HTTPPath: "/", - } +// RejectVpcPeeringConnectionRequest generates a request for the RejectVpcPeeringConnection operation. +func (c *EC2) RejectVpcPeeringConnectionRequest(input *RejectVpcPeeringConnectionInput) (req *request.Request, output *RejectVpcPeeringConnectionOutput) { + op := &request.Operation{ + Name: opRejectVpcPeeringConnection, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &RejectVPCPeeringConnectionInput{} + input = &RejectVpcPeeringConnectionInput{} } - req = c.newRequest(opRejectVPCPeeringConnection, input, output) - output = &RejectVPCPeeringConnectionOutput{} + req = c.newRequest(op, input, output) + output = &RejectVpcPeeringConnectionOutput{} req.Data = output return } @@ -6192,32 +5509,27 @@ func (c *EC2) RejectVPCPeeringConnectionRequest(input *RejectVPCPeeringConnectio // request to view your outstanding VPC peering connection requests. To delete // an active VPC peering connection, or to delete a VPC peering connection request // that you initiated, use DeleteVpcPeeringConnection. -func (c *EC2) RejectVPCPeeringConnection(input *RejectVPCPeeringConnectionInput) (*RejectVPCPeeringConnectionOutput, error) { - req, out := c.RejectVPCPeeringConnectionRequest(input) +func (c *EC2) RejectVpcPeeringConnection(input *RejectVpcPeeringConnectionInput) (*RejectVpcPeeringConnectionOutput, error) { + req, out := c.RejectVpcPeeringConnectionRequest(input) err := req.Send() return out, err } -var opRejectVPCPeeringConnection *aws.Operation +const opReleaseAddress = "ReleaseAddress" // ReleaseAddressRequest generates a request for the ReleaseAddress operation. -func (c *EC2) ReleaseAddressRequest(input *ReleaseAddressInput) (req *aws.Request, output *ReleaseAddressOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opReleaseAddress == nil { - opReleaseAddress = &aws.Operation{ - Name: "ReleaseAddress", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ReleaseAddressRequest(input *ReleaseAddressInput) (req *request.Request, output *ReleaseAddressOutput) { + op := &request.Operation{ + Name: opReleaseAddress, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ReleaseAddressInput{} } - req = c.newRequest(opReleaseAddress, input, output) + req = c.newRequest(op, input, output) output = &ReleaseAddressOutput{} req.Data = output return @@ -6244,27 +5556,22 @@ func (c *EC2) ReleaseAddress(input *ReleaseAddressInput) (*ReleaseAddressOutput, return out, err } -var opReleaseAddress *aws.Operation - -// ReplaceNetworkACLAssociationRequest generates a request for the ReplaceNetworkACLAssociation operation. -func (c *EC2) ReplaceNetworkACLAssociationRequest(input *ReplaceNetworkACLAssociationInput) (req *aws.Request, output *ReplaceNetworkACLAssociationOutput) { - oprw.Lock() - defer oprw.Unlock() +const opReplaceNetworkAclAssociation = "ReplaceNetworkAclAssociation" - if opReplaceNetworkACLAssociation == nil { - opReplaceNetworkACLAssociation = &aws.Operation{ - Name: "ReplaceNetworkAclAssociation", - HTTPMethod: "POST", - HTTPPath: "/", - } +// ReplaceNetworkAclAssociationRequest generates a request for the ReplaceNetworkAclAssociation operation. +func (c *EC2) ReplaceNetworkAclAssociationRequest(input *ReplaceNetworkAclAssociationInput) (req *request.Request, output *ReplaceNetworkAclAssociationOutput) { + op := &request.Operation{ + Name: opReplaceNetworkAclAssociation, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &ReplaceNetworkACLAssociationInput{} + input = &ReplaceNetworkAclAssociationInput{} } - req = c.newRequest(opReplaceNetworkACLAssociation, input, output) - output = &ReplaceNetworkACLAssociationOutput{} + req = c.newRequest(op, input, output) + output = &ReplaceNetworkAclAssociationOutput{} req.Data = output return } @@ -6273,33 +5580,28 @@ func (c *EC2) ReplaceNetworkACLAssociationRequest(input *ReplaceNetworkACLAssoci // create a subnet, it's automatically associated with the default network ACL. // For more information about network ACLs, see Network ACLs (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) ReplaceNetworkACLAssociation(input *ReplaceNetworkACLAssociationInput) (*ReplaceNetworkACLAssociationOutput, error) { - req, out := c.ReplaceNetworkACLAssociationRequest(input) +func (c *EC2) ReplaceNetworkAclAssociation(input *ReplaceNetworkAclAssociationInput) (*ReplaceNetworkAclAssociationOutput, error) { + req, out := c.ReplaceNetworkAclAssociationRequest(input) err := req.Send() return out, err } -var opReplaceNetworkACLAssociation *aws.Operation +const opReplaceNetworkAclEntry = "ReplaceNetworkAclEntry" -// ReplaceNetworkACLEntryRequest generates a request for the ReplaceNetworkACLEntry operation. -func (c *EC2) ReplaceNetworkACLEntryRequest(input *ReplaceNetworkACLEntryInput) (req *aws.Request, output *ReplaceNetworkACLEntryOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opReplaceNetworkACLEntry == nil { - opReplaceNetworkACLEntry = &aws.Operation{ - Name: "ReplaceNetworkAclEntry", - HTTPMethod: "POST", - HTTPPath: "/", - } +// ReplaceNetworkAclEntryRequest generates a request for the ReplaceNetworkAclEntry operation. +func (c *EC2) ReplaceNetworkAclEntryRequest(input *ReplaceNetworkAclEntryInput) (req *request.Request, output *ReplaceNetworkAclEntryOutput) { + op := &request.Operation{ + Name: opReplaceNetworkAclEntry, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &ReplaceNetworkACLEntryInput{} + input = &ReplaceNetworkAclEntryInput{} } - req = c.newRequest(opReplaceNetworkACLEntry, input, output) - output = &ReplaceNetworkACLEntryOutput{} + req = c.newRequest(op, input, output) + output = &ReplaceNetworkAclEntryOutput{} req.Data = output return } @@ -6307,32 +5609,27 @@ func (c *EC2) ReplaceNetworkACLEntryRequest(input *ReplaceNetworkACLEntryInput) // Replaces an entry (rule) in a network ACL. For more information about network // ACLs, see Network ACLs (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) // in the Amazon Virtual Private Cloud User Guide. -func (c *EC2) ReplaceNetworkACLEntry(input *ReplaceNetworkACLEntryInput) (*ReplaceNetworkACLEntryOutput, error) { - req, out := c.ReplaceNetworkACLEntryRequest(input) +func (c *EC2) ReplaceNetworkAclEntry(input *ReplaceNetworkAclEntryInput) (*ReplaceNetworkAclEntryOutput, error) { + req, out := c.ReplaceNetworkAclEntryRequest(input) err := req.Send() return out, err } -var opReplaceNetworkACLEntry *aws.Operation +const opReplaceRoute = "ReplaceRoute" // ReplaceRouteRequest generates a request for the ReplaceRoute operation. -func (c *EC2) ReplaceRouteRequest(input *ReplaceRouteInput) (req *aws.Request, output *ReplaceRouteOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opReplaceRoute == nil { - opReplaceRoute = &aws.Operation{ - Name: "ReplaceRoute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ReplaceRouteRequest(input *ReplaceRouteInput) (req *request.Request, output *ReplaceRouteOutput) { + op := &request.Operation{ + Name: opReplaceRoute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ReplaceRouteInput{} } - req = c.newRequest(opReplaceRoute, input, output) + req = c.newRequest(op, input, output) output = &ReplaceRouteOutput{} req.Data = output return @@ -6350,26 +5647,21 @@ func (c *EC2) ReplaceRoute(input *ReplaceRouteInput) (*ReplaceRouteOutput, error return out, err } -var opReplaceRoute *aws.Operation +const opReplaceRouteTableAssociation = "ReplaceRouteTableAssociation" // ReplaceRouteTableAssociationRequest generates a request for the ReplaceRouteTableAssociation operation. -func (c *EC2) ReplaceRouteTableAssociationRequest(input *ReplaceRouteTableAssociationInput) (req *aws.Request, output *ReplaceRouteTableAssociationOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opReplaceRouteTableAssociation == nil { - opReplaceRouteTableAssociation = &aws.Operation{ - Name: "ReplaceRouteTableAssociation", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ReplaceRouteTableAssociationRequest(input *ReplaceRouteTableAssociationInput) (req *request.Request, output *ReplaceRouteTableAssociationOutput) { + op := &request.Operation{ + Name: opReplaceRouteTableAssociation, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ReplaceRouteTableAssociationInput{} } - req = c.newRequest(opReplaceRouteTableAssociation, input, output) + req = c.newRequest(op, input, output) output = &ReplaceRouteTableAssociationOutput{} req.Data = output return @@ -6390,26 +5682,21 @@ func (c *EC2) ReplaceRouteTableAssociation(input *ReplaceRouteTableAssociationIn return out, err } -var opReplaceRouteTableAssociation *aws.Operation +const opReportInstanceStatus = "ReportInstanceStatus" // ReportInstanceStatusRequest generates a request for the ReportInstanceStatus operation. -func (c *EC2) ReportInstanceStatusRequest(input *ReportInstanceStatusInput) (req *aws.Request, output *ReportInstanceStatusOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opReportInstanceStatus == nil { - opReportInstanceStatus = &aws.Operation{ - Name: "ReportInstanceStatus", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ReportInstanceStatusRequest(input *ReportInstanceStatusInput) (req *request.Request, output *ReportInstanceStatusOutput) { + op := &request.Operation{ + Name: opReportInstanceStatus, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ReportInstanceStatusInput{} } - req = c.newRequest(opReportInstanceStatus, input, output) + req = c.newRequest(op, input, output) output = &ReportInstanceStatusOutput{} req.Data = output return @@ -6428,26 +5715,21 @@ func (c *EC2) ReportInstanceStatus(input *ReportInstanceStatusInput) (*ReportIns return out, err } -var opReportInstanceStatus *aws.Operation +const opRequestSpotFleet = "RequestSpotFleet" // RequestSpotFleetRequest generates a request for the RequestSpotFleet operation. -func (c *EC2) RequestSpotFleetRequest(input *RequestSpotFleetInput) (req *aws.Request, output *RequestSpotFleetOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opRequestSpotFleet == nil { - opRequestSpotFleet = &aws.Operation{ - Name: "RequestSpotFleet", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) RequestSpotFleetRequest(input *RequestSpotFleetInput) (req *request.Request, output *RequestSpotFleetOutput) { + op := &request.Operation{ + Name: opRequestSpotFleet, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &RequestSpotFleetInput{} } - req = c.newRequest(opRequestSpotFleet, input, output) + req = c.newRequest(op, input, output) output = &RequestSpotFleetOutput{} req.Data = output return @@ -6455,7 +5737,20 @@ func (c *EC2) RequestSpotFleetRequest(input *RequestSpotFleetInput) (req *aws.Re // Creates a Spot fleet request. // -// For more information, see Spot Fleets (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet.html) +// You can submit a single request that includes multiple launch specifications +// that vary by instance type, AMI, Availability Zone, or subnet. +// +// By default, the Spot fleet requests Spot instances in the Spot pool where +// the price per unit is the lowest. Each launch specification can include its +// own instance weighting that reflects the value of the instance type to your +// application workload. +// +// Alternatively, you can specify that the Spot fleet distribute the target +// capacity across the Spot pools included in its launch specifications. By +// ensuring that the Spot instances in your Spot fleet are in different Spot +// pools, you can improve the availability of your fleet. +// +// For more information, see Spot Fleet Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet-requests.html) // in the Amazon Elastic Compute Cloud User Guide. func (c *EC2) RequestSpotFleet(input *RequestSpotFleetInput) (*RequestSpotFleetOutput, error) { req, out := c.RequestSpotFleetRequest(input) @@ -6463,35 +5758,30 @@ func (c *EC2) RequestSpotFleet(input *RequestSpotFleetInput) (*RequestSpotFleetO return out, err } -var opRequestSpotFleet *aws.Operation +const opRequestSpotInstances = "RequestSpotInstances" // RequestSpotInstancesRequest generates a request for the RequestSpotInstances operation. -func (c *EC2) RequestSpotInstancesRequest(input *RequestSpotInstancesInput) (req *aws.Request, output *RequestSpotInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opRequestSpotInstances == nil { - opRequestSpotInstances = &aws.Operation{ - Name: "RequestSpotInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) RequestSpotInstancesRequest(input *RequestSpotInstancesInput) (req *request.Request, output *RequestSpotInstancesOutput) { + op := &request.Operation{ + Name: opRequestSpotInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &RequestSpotInstancesInput{} } - req = c.newRequest(opRequestSpotInstances, input, output) + req = c.newRequest(op, input, output) output = &RequestSpotInstancesOutput{} req.Data = output return } -// Creates a Spot Instance request. Spot Instances are instances that Amazon +// Creates a Spot instance request. Spot instances are instances that Amazon // EC2 launches when the bid price that you specify exceeds the current Spot -// Price. Amazon EC2 periodically sets the Spot Price based on available Spot -// Instance capacity and current Spot Instance requests. For more information, +// price. Amazon EC2 periodically sets the Spot price based on available Spot +// Instance capacity and current Spot instance requests. For more information, // see Spot Instance Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) // in the Amazon Elastic Compute Cloud User Guide. func (c *EC2) RequestSpotInstances(input *RequestSpotInstancesInput) (*RequestSpotInstancesOutput, error) { @@ -6500,26 +5790,21 @@ func (c *EC2) RequestSpotInstances(input *RequestSpotInstancesInput) (*RequestSp return out, err } -var opRequestSpotInstances *aws.Operation +const opResetImageAttribute = "ResetImageAttribute" // ResetImageAttributeRequest generates a request for the ResetImageAttribute operation. -func (c *EC2) ResetImageAttributeRequest(input *ResetImageAttributeInput) (req *aws.Request, output *ResetImageAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opResetImageAttribute == nil { - opResetImageAttribute = &aws.Operation{ - Name: "ResetImageAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ResetImageAttributeRequest(input *ResetImageAttributeInput) (req *request.Request, output *ResetImageAttributeOutput) { + op := &request.Operation{ + Name: opResetImageAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ResetImageAttributeInput{} } - req = c.newRequest(opResetImageAttribute, input, output) + req = c.newRequest(op, input, output) output = &ResetImageAttributeOutput{} req.Data = output return @@ -6534,26 +5819,21 @@ func (c *EC2) ResetImageAttribute(input *ResetImageAttributeInput) (*ResetImageA return out, err } -var opResetImageAttribute *aws.Operation +const opResetInstanceAttribute = "ResetInstanceAttribute" // ResetInstanceAttributeRequest generates a request for the ResetInstanceAttribute operation. -func (c *EC2) ResetInstanceAttributeRequest(input *ResetInstanceAttributeInput) (req *aws.Request, output *ResetInstanceAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opResetInstanceAttribute == nil { - opResetInstanceAttribute = &aws.Operation{ - Name: "ResetInstanceAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ResetInstanceAttributeRequest(input *ResetInstanceAttributeInput) (req *request.Request, output *ResetInstanceAttributeOutput) { + op := &request.Operation{ + Name: opResetInstanceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ResetInstanceAttributeInput{} } - req = c.newRequest(opResetInstanceAttribute, input, output) + req = c.newRequest(op, input, output) output = &ResetInstanceAttributeOutput{} req.Data = output return @@ -6574,26 +5854,21 @@ func (c *EC2) ResetInstanceAttribute(input *ResetInstanceAttributeInput) (*Reset return out, err } -var opResetInstanceAttribute *aws.Operation +const opResetNetworkInterfaceAttribute = "ResetNetworkInterfaceAttribute" // ResetNetworkInterfaceAttributeRequest generates a request for the ResetNetworkInterfaceAttribute operation. -func (c *EC2) ResetNetworkInterfaceAttributeRequest(input *ResetNetworkInterfaceAttributeInput) (req *aws.Request, output *ResetNetworkInterfaceAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opResetNetworkInterfaceAttribute == nil { - opResetNetworkInterfaceAttribute = &aws.Operation{ - Name: "ResetNetworkInterfaceAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ResetNetworkInterfaceAttributeRequest(input *ResetNetworkInterfaceAttributeInput) (req *request.Request, output *ResetNetworkInterfaceAttributeOutput) { + op := &request.Operation{ + Name: opResetNetworkInterfaceAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ResetNetworkInterfaceAttributeInput{} } - req = c.newRequest(opResetNetworkInterfaceAttribute, input, output) + req = c.newRequest(op, input, output) output = &ResetNetworkInterfaceAttributeOutput{} req.Data = output return @@ -6607,26 +5882,21 @@ func (c *EC2) ResetNetworkInterfaceAttribute(input *ResetNetworkInterfaceAttribu return out, err } -var opResetNetworkInterfaceAttribute *aws.Operation +const opResetSnapshotAttribute = "ResetSnapshotAttribute" // ResetSnapshotAttributeRequest generates a request for the ResetSnapshotAttribute operation. -func (c *EC2) ResetSnapshotAttributeRequest(input *ResetSnapshotAttributeInput) (req *aws.Request, output *ResetSnapshotAttributeOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opResetSnapshotAttribute == nil { - opResetSnapshotAttribute = &aws.Operation{ - Name: "ResetSnapshotAttribute", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) ResetSnapshotAttributeRequest(input *ResetSnapshotAttributeInput) (req *request.Request, output *ResetSnapshotAttributeOutput) { + op := &request.Operation{ + Name: opResetSnapshotAttribute, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ResetSnapshotAttributeInput{} } - req = c.newRequest(opResetSnapshotAttribute, input, output) + req = c.newRequest(op, input, output) output = &ResetSnapshotAttributeOutput{} req.Data = output return @@ -6643,26 +5913,21 @@ func (c *EC2) ResetSnapshotAttribute(input *ResetSnapshotAttributeInput) (*Reset return out, err } -var opResetSnapshotAttribute *aws.Operation +const opRestoreAddressToClassic = "RestoreAddressToClassic" // RestoreAddressToClassicRequest generates a request for the RestoreAddressToClassic operation. -func (c *EC2) RestoreAddressToClassicRequest(input *RestoreAddressToClassicInput) (req *aws.Request, output *RestoreAddressToClassicOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opRestoreAddressToClassic == nil { - opRestoreAddressToClassic = &aws.Operation{ - Name: "RestoreAddressToClassic", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) RestoreAddressToClassicRequest(input *RestoreAddressToClassicInput) (req *request.Request, output *RestoreAddressToClassicOutput) { + op := &request.Operation{ + Name: opRestoreAddressToClassic, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &RestoreAddressToClassicInput{} } - req = c.newRequest(opRestoreAddressToClassic, input, output) + req = c.newRequest(op, input, output) output = &RestoreAddressToClassicOutput{} req.Data = output return @@ -6678,26 +5943,21 @@ func (c *EC2) RestoreAddressToClassic(input *RestoreAddressToClassicInput) (*Res return out, err } -var opRestoreAddressToClassic *aws.Operation +const opRevokeSecurityGroupEgress = "RevokeSecurityGroupEgress" // RevokeSecurityGroupEgressRequest generates a request for the RevokeSecurityGroupEgress operation. -func (c *EC2) RevokeSecurityGroupEgressRequest(input *RevokeSecurityGroupEgressInput) (req *aws.Request, output *RevokeSecurityGroupEgressOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opRevokeSecurityGroupEgress == nil { - opRevokeSecurityGroupEgress = &aws.Operation{ - Name: "RevokeSecurityGroupEgress", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) RevokeSecurityGroupEgressRequest(input *RevokeSecurityGroupEgressInput) (req *request.Request, output *RevokeSecurityGroupEgressOutput) { + op := &request.Operation{ + Name: opRevokeSecurityGroupEgress, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &RevokeSecurityGroupEgressInput{} } - req = c.newRequest(opRevokeSecurityGroupEgress, input, output) + req = c.newRequest(op, input, output) output = &RevokeSecurityGroupEgressOutput{} req.Data = output return @@ -6720,26 +5980,21 @@ func (c *EC2) RevokeSecurityGroupEgress(input *RevokeSecurityGroupEgressInput) ( return out, err } -var opRevokeSecurityGroupEgress *aws.Operation +const opRevokeSecurityGroupIngress = "RevokeSecurityGroupIngress" // RevokeSecurityGroupIngressRequest generates a request for the RevokeSecurityGroupIngress operation. -func (c *EC2) RevokeSecurityGroupIngressRequest(input *RevokeSecurityGroupIngressInput) (req *aws.Request, output *RevokeSecurityGroupIngressOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opRevokeSecurityGroupIngress == nil { - opRevokeSecurityGroupIngress = &aws.Operation{ - Name: "RevokeSecurityGroupIngress", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) RevokeSecurityGroupIngressRequest(input *RevokeSecurityGroupIngressInput) (req *request.Request, output *RevokeSecurityGroupIngressOutput) { + op := &request.Operation{ + Name: opRevokeSecurityGroupIngress, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &RevokeSecurityGroupIngressInput{} } - req = c.newRequest(opRevokeSecurityGroupIngress, input, output) + req = c.newRequest(op, input, output) output = &RevokeSecurityGroupIngressOutput{} req.Data = output return @@ -6762,26 +6017,21 @@ func (c *EC2) RevokeSecurityGroupIngress(input *RevokeSecurityGroupIngressInput) return out, err } -var opRevokeSecurityGroupIngress *aws.Operation +const opRunInstances = "RunInstances" // RunInstancesRequest generates a request for the RunInstances operation. -func (c *EC2) RunInstancesRequest(input *RunInstancesInput) (req *aws.Request, output *Reservation) { - oprw.Lock() - defer oprw.Unlock() - - if opRunInstances == nil { - opRunInstances = &aws.Operation{ - Name: "RunInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) RunInstancesRequest(input *RunInstancesInput) (req *request.Request, output *Reservation) { + op := &request.Operation{ + Name: opRunInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &RunInstancesInput{} } - req = c.newRequest(opRunInstances, input, output) + req = c.newRequest(op, input, output) output = &Reservation{} req.Data = output return @@ -6799,6 +6049,12 @@ func (c *EC2) RunInstancesRequest(input *RunInstancesInput) (req *aws.Request, o // (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html) // in the Amazon Elastic Compute Cloud User Guide. // +// [EC2-VPC only accounts] If you don't specify a subnet in the request, we +// choose a default subnet from your default VPC for you. +// +// [EC2-Classic accounts] If you're launching into EC2-Classic and you don't +// specify an Availability Zone, we choose one for you. +// // Linux instances have access to the public key of the key pair at boot. You // can use this key to provide secure access to the instance. Amazon EC2 public // images use this feature to provide secure access without passwords. For more @@ -6826,26 +6082,21 @@ func (c *EC2) RunInstances(input *RunInstancesInput) (*Reservation, error) { return out, err } -var opRunInstances *aws.Operation +const opStartInstances = "StartInstances" // StartInstancesRequest generates a request for the StartInstances operation. -func (c *EC2) StartInstancesRequest(input *StartInstancesInput) (req *aws.Request, output *StartInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opStartInstances == nil { - opStartInstances = &aws.Operation{ - Name: "StartInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) StartInstancesRequest(input *StartInstancesInput) (req *request.Request, output *StartInstancesOutput) { + op := &request.Operation{ + Name: opStartInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &StartInstancesInput{} } - req = c.newRequest(opStartInstances, input, output) + req = c.newRequest(op, input, output) output = &StartInstancesOutput{} req.Data = output return @@ -6876,26 +6127,21 @@ func (c *EC2) StartInstances(input *StartInstancesInput) (*StartInstancesOutput, return out, err } -var opStartInstances *aws.Operation +const opStopInstances = "StopInstances" // StopInstancesRequest generates a request for the StopInstances operation. -func (c *EC2) StopInstancesRequest(input *StopInstancesInput) (req *aws.Request, output *StopInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opStopInstances == nil { - opStopInstances = &aws.Operation{ - Name: "StopInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) StopInstancesRequest(input *StopInstancesInput) (req *request.Request, output *StopInstancesOutput) { + op := &request.Operation{ + Name: opStopInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &StopInstancesInput{} } - req = c.newRequest(opStopInstances, input, output) + req = c.newRequest(op, input, output) output = &StopInstancesOutput{} req.Data = output return @@ -6938,26 +6184,21 @@ func (c *EC2) StopInstances(input *StopInstancesInput) (*StopInstancesOutput, er return out, err } -var opStopInstances *aws.Operation +const opTerminateInstances = "TerminateInstances" // TerminateInstancesRequest generates a request for the TerminateInstances operation. -func (c *EC2) TerminateInstancesRequest(input *TerminateInstancesInput) (req *aws.Request, output *TerminateInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opTerminateInstances == nil { - opTerminateInstances = &aws.Operation{ - Name: "TerminateInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) TerminateInstancesRequest(input *TerminateInstancesInput) (req *request.Request, output *TerminateInstancesOutput) { + op := &request.Operation{ + Name: opTerminateInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &TerminateInstancesInput{} } - req = c.newRequest(opTerminateInstances, input, output) + req = c.newRequest(op, input, output) output = &TerminateInstancesOutput{} req.Data = output return @@ -6976,9 +6217,10 @@ func (c *EC2) TerminateInstancesRequest(input *TerminateInstancesInput) (req *aw // instance store-backed instances. What happens to an instance differs if you // stop it or terminate it. For example, when you stop an instance, the root // device and any other devices attached to the instance persist. When you terminate -// an instance, the root device and any other devices attached during the instance -// launch are automatically deleted. For more information about the differences -// between stopping and terminating instances, see Instance Lifecycle (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-lifecycle.html) +// an instance, any attached EBS volumes with the DeleteOnTermination block +// device mapping parameter set to true are automatically deleted. For more +// information about the differences between stopping and terminating instances, +// see Instance Lifecycle (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-lifecycle.html) // in the Amazon Elastic Compute Cloud User Guide. // // For more information about troubleshooting, see Troubleshooting Terminating @@ -6990,58 +6232,48 @@ func (c *EC2) TerminateInstances(input *TerminateInstancesInput) (*TerminateInst return out, err } -var opTerminateInstances *aws.Operation - -// UnassignPrivateIPAddressesRequest generates a request for the UnassignPrivateIPAddresses operation. -func (c *EC2) UnassignPrivateIPAddressesRequest(input *UnassignPrivateIPAddressesInput) (req *aws.Request, output *UnassignPrivateIPAddressesOutput) { - oprw.Lock() - defer oprw.Unlock() +const opUnassignPrivateIpAddresses = "UnassignPrivateIpAddresses" - if opUnassignPrivateIPAddresses == nil { - opUnassignPrivateIPAddresses = &aws.Operation{ - Name: "UnassignPrivateIpAddresses", - HTTPMethod: "POST", - HTTPPath: "/", - } +// UnassignPrivateIpAddressesRequest generates a request for the UnassignPrivateIpAddresses operation. +func (c *EC2) UnassignPrivateIpAddressesRequest(input *UnassignPrivateIpAddressesInput) (req *request.Request, output *UnassignPrivateIpAddressesOutput) { + op := &request.Operation{ + Name: opUnassignPrivateIpAddresses, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { - input = &UnassignPrivateIPAddressesInput{} + input = &UnassignPrivateIpAddressesInput{} } - req = c.newRequest(opUnassignPrivateIPAddresses, input, output) - output = &UnassignPrivateIPAddressesOutput{} + req = c.newRequest(op, input, output) + output = &UnassignPrivateIpAddressesOutput{} req.Data = output return } // Unassigns one or more secondary private IP addresses from a network interface. -func (c *EC2) UnassignPrivateIPAddresses(input *UnassignPrivateIPAddressesInput) (*UnassignPrivateIPAddressesOutput, error) { - req, out := c.UnassignPrivateIPAddressesRequest(input) +func (c *EC2) UnassignPrivateIpAddresses(input *UnassignPrivateIpAddressesInput) (*UnassignPrivateIpAddressesOutput, error) { + req, out := c.UnassignPrivateIpAddressesRequest(input) err := req.Send() return out, err } -var opUnassignPrivateIPAddresses *aws.Operation +const opUnmonitorInstances = "UnmonitorInstances" // UnmonitorInstancesRequest generates a request for the UnmonitorInstances operation. -func (c *EC2) UnmonitorInstancesRequest(input *UnmonitorInstancesInput) (req *aws.Request, output *UnmonitorInstancesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opUnmonitorInstances == nil { - opUnmonitorInstances = &aws.Operation{ - Name: "UnmonitorInstances", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *EC2) UnmonitorInstancesRequest(input *UnmonitorInstancesInput) (req *request.Request, output *UnmonitorInstancesOutput) { + op := &request.Operation{ + Name: opUnmonitorInstances, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &UnmonitorInstancesInput{} } - req = c.newRequest(opUnmonitorInstances, input, output) + req = c.newRequest(op, input, output) output = &UnmonitorInstancesOutput{} req.Data = output return @@ -7056,9 +6288,7 @@ func (c *EC2) UnmonitorInstances(input *UnmonitorInstancesInput) (*UnmonitorInst return out, err } -var opUnmonitorInstances *aws.Operation - -type AcceptVPCPeeringConnectionInput struct { +type AcceptVpcPeeringConnectionInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -7066,26 +6296,46 @@ type AcceptVPCPeeringConnectionInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the VPC peering connection. - VPCPeeringConnectionID *string `locationName:"vpcPeeringConnectionId" type:"string"` + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` - metadataAcceptVPCPeeringConnectionInput `json:"-" xml:"-"` + metadataAcceptVpcPeeringConnectionInput `json:"-" xml:"-"` } -type metadataAcceptVPCPeeringConnectionInput struct { +type metadataAcceptVpcPeeringConnectionInput struct { SDKShapeTraits bool `type:"structure"` } -type AcceptVPCPeeringConnectionOutput struct { +// String returns the string representation +func (s AcceptVpcPeeringConnectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AcceptVpcPeeringConnectionInput) GoString() string { + return s.String() +} + +type AcceptVpcPeeringConnectionOutput struct { // Information about the VPC peering connection. - VPCPeeringConnection *VPCPeeringConnection `locationName:"vpcPeeringConnection" type:"structure"` + VpcPeeringConnection *VpcPeeringConnection `locationName:"vpcPeeringConnection" type:"structure"` - metadataAcceptVPCPeeringConnectionOutput `json:"-" xml:"-"` + metadataAcceptVpcPeeringConnectionOutput `json:"-" xml:"-"` } -type metadataAcceptVPCPeeringConnectionOutput struct { +type metadataAcceptVpcPeeringConnectionOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AcceptVpcPeeringConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AcceptVpcPeeringConnectionOutput) GoString() string { + return s.String() +} + // Describes an account attribute. type AccountAttribute struct { // The name of the account attribute. @@ -7101,6 +6351,16 @@ type metadataAccountAttribute struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AccountAttribute) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AccountAttribute) GoString() string { + return s.String() +} + // Describes a value of an account attribute. type AccountAttributeValue struct { // The value of the attribute. @@ -7113,16 +6373,26 @@ type metadataAccountAttributeValue struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AccountAttributeValue) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AccountAttributeValue) GoString() string { + return s.String() +} + // Describes a running instance in a Spot fleet. type ActiveInstance struct { // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The instance type. InstanceType *string `locationName:"instanceType" type:"string"` - // The ID of the Spot Instance request. - SpotInstanceRequestID *string `locationName:"spotInstanceRequestId" type:"string"` + // The ID of the Spot instance request. + SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` metadataActiveInstance `json:"-" xml:"-"` } @@ -7131,33 +6401,43 @@ type metadataActiveInstance struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ActiveInstance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ActiveInstance) GoString() string { + return s.String() +} + // Describes an Elastic IP address. type Address struct { // The ID representing the allocation of the address for use with EC2-VPC. - AllocationID *string `locationName:"allocationId" type:"string"` + AllocationId *string `locationName:"allocationId" type:"string"` // The ID representing the association of the address with an instance in a // VPC. - AssociationID *string `locationName:"associationId" type:"string"` + AssociationId *string `locationName:"associationId" type:"string"` // Indicates whether this Elastic IP address is for use with instances in EC2-Classic // (standard) or instances in a VPC (vpc). - Domain *string `locationName:"domain" type:"string"` + Domain *string `locationName:"domain" type:"string" enum:"DomainType"` // The ID of the instance that the address is associated with (if any). - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` // The ID of the AWS account that owns the network interface. - NetworkInterfaceOwnerID *string `locationName:"networkInterfaceOwnerId" type:"string"` + NetworkInterfaceOwnerId *string `locationName:"networkInterfaceOwnerId" type:"string"` // The private IP address associated with the Elastic IP address. - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` // The Elastic IP address. - PublicIP *string `locationName:"publicIp" type:"string"` + PublicIp *string `locationName:"publicIp" type:"string"` metadataAddress `json:"-" xml:"-"` } @@ -7166,11 +6446,21 @@ type metadataAddress struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Address) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Address) GoString() string { + return s.String() +} + type AllocateAddressInput struct { // Set to vpc to allocate the address for use with instances in a VPC. // // Default: The address is for use with instances in EC2-Classic. - Domain *string `type:"string"` + Domain *string `type:"string" enum:"DomainType"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -7185,17 +6475,27 @@ type metadataAllocateAddressInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AllocateAddressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AllocateAddressInput) GoString() string { + return s.String() +} + type AllocateAddressOutput struct { // [EC2-VPC] The ID that AWS assigns to represent the allocation of the Elastic // IP address for use with instances in a VPC. - AllocationID *string `locationName:"allocationId" type:"string"` + AllocationId *string `locationName:"allocationId" type:"string"` // Indicates whether this Elastic IP address is for use with instances in EC2-Classic // (standard) or instances in a VPC (vpc). - Domain *string `locationName:"domain" type:"string"` + Domain *string `locationName:"domain" type:"string" enum:"DomainType"` // The Elastic IP address. - PublicIP *string `locationName:"publicIp" type:"string"` + PublicIp *string `locationName:"publicIp" type:"string"` metadataAllocateAddressOutput `json:"-" xml:"-"` } @@ -7204,13 +6504,23 @@ type metadataAllocateAddressOutput struct { SDKShapeTraits bool `type:"structure"` } -type AssignPrivateIPAddressesInput struct { +// String returns the string representation +func (s AllocateAddressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AllocateAddressOutput) GoString() string { + return s.String() +} + +type AssignPrivateIpAddressesInput struct { // Indicates whether to allow an IP address that is already assigned to another // network interface or instance to be reassigned to the specified network interface. AllowReassignment *bool `locationName:"allowReassignment" type:"boolean"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string" required:"true"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` // One or more IP addresses to be assigned as a secondary private IP address // to the network interface. You can't specify this parameter when also specifying @@ -7218,30 +6528,50 @@ type AssignPrivateIPAddressesInput struct { // // If you don't specify an IP address, Amazon EC2 automatically selects an // IP address within the subnet range. - PrivateIPAddresses []*string `locationName:"privateIpAddress" locationNameList:"PrivateIpAddress" type:"list"` + PrivateIpAddresses []*string `locationName:"privateIpAddress" locationNameList:"PrivateIpAddress" type:"list"` // The number of secondary IP addresses to assign to the network interface. // You can't specify this parameter when also specifying private IP addresses. - SecondaryPrivateIPAddressCount *int64 `locationName:"secondaryPrivateIpAddressCount" type:"integer"` + SecondaryPrivateIpAddressCount *int64 `locationName:"secondaryPrivateIpAddressCount" type:"integer"` - metadataAssignPrivateIPAddressesInput `json:"-" xml:"-"` + metadataAssignPrivateIpAddressesInput `json:"-" xml:"-"` } -type metadataAssignPrivateIPAddressesInput struct { +type metadataAssignPrivateIpAddressesInput struct { SDKShapeTraits bool `type:"structure"` } -type AssignPrivateIPAddressesOutput struct { - metadataAssignPrivateIPAddressesOutput `json:"-" xml:"-"` +// String returns the string representation +func (s AssignPrivateIpAddressesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssignPrivateIpAddressesInput) GoString() string { + return s.String() +} + +type AssignPrivateIpAddressesOutput struct { + metadataAssignPrivateIpAddressesOutput `json:"-" xml:"-"` } -type metadataAssignPrivateIPAddressesOutput struct { +type metadataAssignPrivateIpAddressesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AssignPrivateIpAddressesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssignPrivateIpAddressesOutput) GoString() string { + return s.String() +} + type AssociateAddressInput struct { // [EC2-VPC] The allocation ID. This is required for EC2-VPC. - AllocationID *string `locationName:"AllocationId" type:"string"` + AllocationId *string `type:"string"` // [EC2-VPC] Allows an Elastic IP address that is already associated with an // instance or network interface to be re-associated with the specified instance @@ -7260,19 +6590,19 @@ type AssociateAddressInput struct { // can specify either the instance ID or the network interface ID, but not both. // The operation fails if you specify an instance ID unless exactly one network // interface is attached. - InstanceID *string `locationName:"InstanceId" type:"string"` + InstanceId *string `type:"string"` // [EC2-VPC] The ID of the network interface. If the instance has more than // one network interface, you must specify a network interface ID. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` // [EC2-VPC] The primary or secondary private IP address to associate with the // Elastic IP address. If no private IP address is specified, the Elastic IP // address is associated with the primary private IP address. - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` // The Elastic IP address. This is required for EC2-Classic. - PublicIP *string `locationName:"PublicIp" type:"string"` + PublicIp *string `type:"string"` metadataAssociateAddressInput `json:"-" xml:"-"` } @@ -7281,10 +6611,20 @@ type metadataAssociateAddressInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AssociateAddressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateAddressInput) GoString() string { + return s.String() +} + type AssociateAddressOutput struct { // [EC2-VPC] The ID that represents the association of the Elastic IP address // with an instance. - AssociationID *string `locationName:"associationId" type:"string"` + AssociationId *string `locationName:"associationId" type:"string"` metadataAssociateAddressOutput `json:"-" xml:"-"` } @@ -7293,10 +6633,20 @@ type metadataAssociateAddressOutput struct { SDKShapeTraits bool `type:"structure"` } -type AssociateDHCPOptionsInput struct { +// String returns the string representation +func (s AssociateAddressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateAddressOutput) GoString() string { + return s.String() +} + +type AssociateDhcpOptionsInput struct { // The ID of the DHCP options set, or default to associate no DHCP options with // the VPC. - DHCPOptionsID *string `locationName:"DhcpOptionsId" type:"string" required:"true"` + DhcpOptionsId *string `type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -7305,23 +6655,43 @@ type AssociateDHCPOptionsInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the VPC. - VPCID *string `locationName:"VpcId" type:"string" required:"true"` + VpcId *string `type:"string" required:"true"` - metadataAssociateDHCPOptionsInput `json:"-" xml:"-"` + metadataAssociateDhcpOptionsInput `json:"-" xml:"-"` } -type metadataAssociateDHCPOptionsInput struct { +type metadataAssociateDhcpOptionsInput struct { SDKShapeTraits bool `type:"structure"` } -type AssociateDHCPOptionsOutput struct { - metadataAssociateDHCPOptionsOutput `json:"-" xml:"-"` +// String returns the string representation +func (s AssociateDhcpOptionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateDhcpOptionsInput) GoString() string { + return s.String() +} + +type AssociateDhcpOptionsOutput struct { + metadataAssociateDhcpOptionsOutput `json:"-" xml:"-"` } -type metadataAssociateDHCPOptionsOutput struct { +type metadataAssociateDhcpOptionsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AssociateDhcpOptionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateDhcpOptionsOutput) GoString() string { + return s.String() +} + type AssociateRouteTableInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -7330,10 +6700,10 @@ type AssociateRouteTableInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the route table. - RouteTableID *string `locationName:"routeTableId" type:"string" required:"true"` + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` // The ID of the subnet. - SubnetID *string `locationName:"subnetId" type:"string" required:"true"` + SubnetId *string `locationName:"subnetId" type:"string" required:"true"` metadataAssociateRouteTableInput `json:"-" xml:"-"` } @@ -7342,9 +6712,19 @@ type metadataAssociateRouteTableInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AssociateRouteTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateRouteTableInput) GoString() string { + return s.String() +} + type AssociateRouteTableOutput struct { // The route table association ID (needed to disassociate the route table). - AssociationID *string `locationName:"associationId" type:"string"` + AssociationId *string `locationName:"associationId" type:"string"` metadataAssociateRouteTableOutput `json:"-" xml:"-"` } @@ -7353,7 +6733,17 @@ type metadataAssociateRouteTableOutput struct { SDKShapeTraits bool `type:"structure"` } -type AttachClassicLinkVPCInput struct { +// String returns the string representation +func (s AssociateRouteTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateRouteTableOutput) GoString() string { + return s.String() +} + +type AttachClassicLinkVpcInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -7365,29 +6755,49 @@ type AttachClassicLinkVPCInput struct { Groups []*string `locationName:"SecurityGroupId" locationNameList:"groupId" type:"list" required:"true"` // The ID of an EC2-Classic instance to link to the ClassicLink-enabled VPC. - InstanceID *string `locationName:"instanceId" type:"string" required:"true"` + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` // The ID of a ClassicLink-enabled VPC. - VPCID *string `locationName:"vpcId" type:"string" required:"true"` + VpcId *string `locationName:"vpcId" type:"string" required:"true"` - metadataAttachClassicLinkVPCInput `json:"-" xml:"-"` + metadataAttachClassicLinkVpcInput `json:"-" xml:"-"` } -type metadataAttachClassicLinkVPCInput struct { +type metadataAttachClassicLinkVpcInput struct { SDKShapeTraits bool `type:"structure"` } -type AttachClassicLinkVPCOutput struct { +// String returns the string representation +func (s AttachClassicLinkVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachClassicLinkVpcInput) GoString() string { + return s.String() +} + +type AttachClassicLinkVpcOutput struct { // Returns true if the request succeeds; otherwise, it returns an error. Return *bool `locationName:"return" type:"boolean"` - metadataAttachClassicLinkVPCOutput `json:"-" xml:"-"` + metadataAttachClassicLinkVpcOutput `json:"-" xml:"-"` } -type metadataAttachClassicLinkVPCOutput struct { +type metadataAttachClassicLinkVpcOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AttachClassicLinkVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachClassicLinkVpcOutput) GoString() string { + return s.String() +} + type AttachInternetGatewayInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -7396,10 +6806,10 @@ type AttachInternetGatewayInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the Internet gateway. - InternetGatewayID *string `locationName:"internetGatewayId" type:"string" required:"true"` + InternetGatewayId *string `locationName:"internetGatewayId" type:"string" required:"true"` // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string" required:"true"` + VpcId *string `locationName:"vpcId" type:"string" required:"true"` metadataAttachInternetGatewayInput `json:"-" xml:"-"` } @@ -7408,6 +6818,16 @@ type metadataAttachInternetGatewayInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AttachInternetGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachInternetGatewayInput) GoString() string { + return s.String() +} + type AttachInternetGatewayOutput struct { metadataAttachInternetGatewayOutput `json:"-" xml:"-"` } @@ -7416,6 +6836,16 @@ type metadataAttachInternetGatewayOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AttachInternetGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachInternetGatewayOutput) GoString() string { + return s.String() +} + type AttachNetworkInterfaceInput struct { // The index of the device for the network interface attachment. DeviceIndex *int64 `locationName:"deviceIndex" type:"integer" required:"true"` @@ -7427,10 +6857,10 @@ type AttachNetworkInterfaceInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string" required:"true"` + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string" required:"true"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` metadataAttachNetworkInterfaceInput `json:"-" xml:"-"` } @@ -7439,9 +6869,19 @@ type metadataAttachNetworkInterfaceInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AttachNetworkInterfaceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachNetworkInterfaceInput) GoString() string { + return s.String() +} + type AttachNetworkInterfaceOutput struct { // The ID of the network interface attachment. - AttachmentID *string `locationName:"attachmentId" type:"string"` + AttachmentId *string `locationName:"attachmentId" type:"string"` metadataAttachNetworkInterfaceOutput `json:"-" xml:"-"` } @@ -7450,61 +6890,101 @@ type metadataAttachNetworkInterfaceOutput struct { SDKShapeTraits bool `type:"structure"` } -type AttachVPNGatewayInput struct { +// String returns the string representation +func (s AttachNetworkInterfaceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachNetworkInterfaceOutput) GoString() string { + return s.String() +} + +type AttachVolumeInput struct { + // The device name to expose to the instance (for example, /dev/sdh or xvdh). + Device *string `type:"string" required:"true"` + // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The ID of the VPC. - VPCID *string `locationName:"VpcId" type:"string" required:"true"` + // The ID of the instance. + InstanceId *string `type:"string" required:"true"` - // The ID of the virtual private gateway. - VPNGatewayID *string `locationName:"VpnGatewayId" type:"string" required:"true"` + // The ID of the EBS volume. The volume and instance must be within the same + // Availability Zone. + VolumeId *string `type:"string" required:"true"` - metadataAttachVPNGatewayInput `json:"-" xml:"-"` + metadataAttachVolumeInput `json:"-" xml:"-"` } -type metadataAttachVPNGatewayInput struct { +type metadataAttachVolumeInput struct { SDKShapeTraits bool `type:"structure"` } -type AttachVPNGatewayOutput struct { - // Information about the attachment. - VPCAttachment *VPCAttachment `locationName:"attachment" type:"structure"` - - metadataAttachVPNGatewayOutput `json:"-" xml:"-"` +// String returns the string representation +func (s AttachVolumeInput) String() string { + return awsutil.Prettify(s) } -type metadataAttachVPNGatewayOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s AttachVolumeInput) GoString() string { + return s.String() } -type AttachVolumeInput struct { - // The device name to expose to the instance (for example, /dev/sdh or xvdh). - Device *string `type:"string" required:"true"` - +type AttachVpnGatewayInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The ID of the instance. - InstanceID *string `locationName:"InstanceId" type:"string" required:"true"` + // The ID of the VPC. + VpcId *string `type:"string" required:"true"` - // The ID of the EBS volume. The volume and instance must be within the same - // Availability Zone. - VolumeID *string `locationName:"VolumeId" type:"string" required:"true"` + // The ID of the virtual private gateway. + VpnGatewayId *string `type:"string" required:"true"` - metadataAttachVolumeInput `json:"-" xml:"-"` + metadataAttachVpnGatewayInput `json:"-" xml:"-"` } -type metadataAttachVolumeInput struct { +type metadataAttachVpnGatewayInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s AttachVpnGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachVpnGatewayInput) GoString() string { + return s.String() +} + +type AttachVpnGatewayOutput struct { + // Information about the attachment. + VpcAttachment *VpcAttachment `locationName:"attachment" type:"structure"` + + metadataAttachVpnGatewayOutput `json:"-" xml:"-"` +} + +type metadataAttachVpnGatewayOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AttachVpnGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachVpnGatewayOutput) GoString() string { + return s.String() +} + // The value to use when a resource attribute accepts a Boolean value. type AttributeBooleanValue struct { // Valid values are true or false. @@ -7517,6 +6997,16 @@ type metadataAttributeBooleanValue struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AttributeBooleanValue) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttributeBooleanValue) GoString() string { + return s.String() +} + // The value to use for a resource attribute. type AttributeValue struct { // Valid values are case-sensitive and vary by action. @@ -7529,10 +7019,20 @@ type metadataAttributeValue struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AttributeValue) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttributeValue) GoString() string { + return s.String() +} + type AuthorizeSecurityGroupEgressInput struct { // The CIDR IP address range. You can't specify this parameter when specifying // a source security group. - CIDRIP *string `locationName:"cidrIp" type:"string"` + CidrIp *string `locationName:"cidrIp" type:"string"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -7545,23 +7045,25 @@ type AuthorizeSecurityGroupEgressInput struct { FromPort *int64 `locationName:"fromPort" type:"integer"` // The ID of the security group. - GroupID *string `locationName:"groupId" type:"string" required:"true"` + GroupId *string `locationName:"groupId" type:"string" required:"true"` // A set of IP permissions. You can't specify a destination security group and // a CIDR IP address range. - IPPermissions []*IPPermission `locationName:"ipPermissions" locationNameList:"item" type:"list"` + IpPermissions []*IpPermission `locationName:"ipPermissions" locationNameList:"item" type:"list"` // The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)). // Use -1 to specify all. - IPProtocol *string `locationName:"ipProtocol" type:"string"` + IpProtocol *string `locationName:"ipProtocol" type:"string"` - // [EC2-Classic, default VPC] The name of the destination security group. You - // can't specify a destination security group and a CIDR IP address range. + // The name of a destination security group. To authorize outbound access to + // a destination security group, we recommend that you use a set of IP permissions + // instead. SourceSecurityGroupName *string `locationName:"sourceSecurityGroupName" type:"string"` - // The ID of the destination security group. You can't specify a destination - // security group and a CIDR IP address range. - SourceSecurityGroupOwnerID *string `locationName:"sourceSecurityGroupOwnerId" type:"string"` + // The AWS account number for a destination security group. To authorize outbound + // access to a destination security group, we recommend that you use a set of + // IP permissions instead. + SourceSecurityGroupOwnerId *string `locationName:"sourceSecurityGroupOwnerId" type:"string"` // The end of port range for the TCP and UDP protocols, or an ICMP code number. // For the ICMP code number, use -1 to specify all ICMP codes for the ICMP type. @@ -7574,6 +7076,16 @@ type metadataAuthorizeSecurityGroupEgressInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AuthorizeSecurityGroupEgressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AuthorizeSecurityGroupEgressInput) GoString() string { + return s.String() +} + type AuthorizeSecurityGroupEgressOutput struct { metadataAuthorizeSecurityGroupEgressOutput `json:"-" xml:"-"` } @@ -7582,10 +7094,20 @@ type metadataAuthorizeSecurityGroupEgressOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AuthorizeSecurityGroupEgressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AuthorizeSecurityGroupEgressOutput) GoString() string { + return s.String() +} + type AuthorizeSecurityGroupIngressInput struct { // The CIDR IP address range. You can't specify this parameter when specifying // a source security group. - CIDRIP *string `locationName:"CidrIp" type:"string"` + CidrIp *string `type:"string"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -7598,26 +7120,34 @@ type AuthorizeSecurityGroupIngressInput struct { FromPort *int64 `type:"integer"` // The ID of the security group. Required for a nondefault VPC. - GroupID *string `locationName:"GroupId" type:"string"` + GroupId *string `type:"string"` // [EC2-Classic, default VPC] The name of the security group. GroupName *string `type:"string"` // A set of IP permissions. Can be used to specify multiple rules in a single // command. - IPPermissions []*IPPermission `locationName:"IpPermissions" locationNameList:"item" type:"list"` + IpPermissions []*IpPermission `locationNameList:"item" type:"list"` // The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)). // (VPC only) Use -1 to specify all. - IPProtocol *string `locationName:"IpProtocol" type:"string"` + IpProtocol *string `type:"string"` // [EC2-Classic, default VPC] The name of the source security group. You can't - // specify a source security group and a CIDR IP address range. + // specify this parameter in combination with the following parameters: the + // CIDR IP address range, the start of the port range, the IP protocol, and + // the end of the port range. For EC2-VPC, the source security group must be + // in the same VPC. SourceSecurityGroupName *string `type:"string"` - // The ID of the source security group. You can't specify a source security - // group and a CIDR IP address range. - SourceSecurityGroupOwnerID *string `locationName:"SourceSecurityGroupOwnerId" type:"string"` + // [EC2-Classic, default VPC] The AWS account number for the source security + // group. For EC2-VPC, the source security group must be in the same VPC. You + // can't specify this parameter in combination with the following parameters: + // the CIDR IP address range, the IP protocol, the start of the port range, + // and the end of the port range. Creates rules that grant full ICMP, UDP, and + // TCP access. To create a rule with a specific IP protocol and port range, + // use a set of IP permissions instead. + SourceSecurityGroupOwnerId *string `type:"string"` // The end of port range for the TCP and UDP protocols, or an ICMP code number. // For the ICMP code number, use -1 to specify all ICMP codes for the ICMP type. @@ -7630,6 +7160,16 @@ type metadataAuthorizeSecurityGroupIngressInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AuthorizeSecurityGroupIngressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AuthorizeSecurityGroupIngressInput) GoString() string { + return s.String() +} + type AuthorizeSecurityGroupIngressOutput struct { metadataAuthorizeSecurityGroupIngressOutput `json:"-" xml:"-"` } @@ -7638,6 +7178,16 @@ type metadataAuthorizeSecurityGroupIngressOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AuthorizeSecurityGroupIngressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AuthorizeSecurityGroupIngressOutput) GoString() string { + return s.String() +} + // Describes an Availability Zone. type AvailabilityZone struct { // Any messages about the Availability Zone. @@ -7647,7 +7197,7 @@ type AvailabilityZone struct { RegionName *string `locationName:"regionName" type:"string"` // The state of the Availability Zone (available | impaired | unavailable). - State *string `locationName:"zoneState" type:"string"` + State *string `locationName:"zoneState" type:"string" enum:"AvailabilityZoneState"` // The name of the Availability Zone. ZoneName *string `locationName:"zoneName" type:"string"` @@ -7659,6 +7209,16 @@ type metadataAvailabilityZone struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AvailabilityZone) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AvailabilityZone) GoString() string { + return s.String() +} + // Describes a message about an Availability Zone. type AvailabilityZoneMessage struct { // The message about the Availability Zone. @@ -7671,6 +7231,16 @@ type metadataAvailabilityZoneMessage struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AvailabilityZoneMessage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AvailabilityZoneMessage) GoString() string { + return s.String() +} + type BlobAttributeValue struct { Value []byte `locationName:"value" type:"blob"` @@ -7681,6 +7251,16 @@ type metadataBlobAttributeValue struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s BlobAttributeValue) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BlobAttributeValue) GoString() string { + return s.String() +} + // Describes a block device mapping. type BlockDeviceMapping struct { // The device name exposed to the instance (for example, /dev/sdh or xvdh). @@ -7688,7 +7268,7 @@ type BlockDeviceMapping struct { // Parameters used to automatically set up EBS volumes when the instance is // launched. - EBS *EBSBlockDevice `locationName:"ebs" type:"structure"` + Ebs *EbsBlockDevice `locationName:"ebs" type:"structure"` // Suppresses the specified device included in the block device mapping of the // AMI. @@ -7713,6 +7293,16 @@ type metadataBlockDeviceMapping struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s BlockDeviceMapping) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BlockDeviceMapping) GoString() string { + return s.String() +} + type BundleInstanceInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -7727,7 +7317,7 @@ type BundleInstanceInput struct { // Default: None // // Required: Yes - InstanceID *string `locationName:"InstanceId" type:"string" required:"true"` + InstanceId *string `type:"string" required:"true"` // The bucket in which to store the AMI. You can specify a bucket that you already // own or a new bucket that Amazon EC2 creates on your behalf. If you specify @@ -7741,6 +7331,16 @@ type metadataBundleInstanceInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s BundleInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BundleInstanceInput) GoString() string { + return s.String() +} + type BundleInstanceOutput struct { // Information about the bundle task. BundleTask *BundleTask `locationName:"bundleInstanceTask" type:"structure"` @@ -7752,16 +7352,26 @@ type metadataBundleInstanceOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s BundleInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BundleInstanceOutput) GoString() string { + return s.String() +} + // Describes a bundle task. type BundleTask struct { // The ID of the bundle task. - BundleID *string `locationName:"bundleId" type:"string"` + BundleId *string `locationName:"bundleId" type:"string"` // If the task fails, a description of the error. BundleTaskError *BundleTaskError `locationName:"error" type:"structure"` // The ID of the instance associated with this bundle task. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The level of task completion, as a percent (for example, 20%). Progress *string `locationName:"progress" type:"string"` @@ -7770,7 +7380,7 @@ type BundleTask struct { StartTime *time.Time `locationName:"startTime" type:"timestamp" timestampFormat:"iso8601"` // The state of the task. - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"BundleTaskState"` // The Amazon S3 storage locations. Storage *Storage `locationName:"storage" type:"structure"` @@ -7785,6 +7395,16 @@ type metadataBundleTask struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s BundleTask) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BundleTask) GoString() string { + return s.String() +} + // Describes an error for BundleInstance. type BundleTaskError struct { // The error code. @@ -7800,9 +7420,19 @@ type metadataBundleTaskError struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s BundleTaskError) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BundleTaskError) GoString() string { + return s.String() +} + type CancelBundleTaskInput struct { // The ID of the bundle task. - BundleID *string `locationName:"BundleId" type:"string" required:"true"` + BundleId *string `type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -7817,6 +7447,16 @@ type metadataCancelBundleTaskInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelBundleTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelBundleTaskInput) GoString() string { + return s.String() +} + type CancelBundleTaskOutput struct { // Information about the bundle task. BundleTask *BundleTask `locationName:"bundleInstanceTask" type:"structure"` @@ -7828,9 +7468,19 @@ type metadataCancelBundleTaskOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelBundleTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelBundleTaskOutput) GoString() string { + return s.String() +} + type CancelConversionTaskInput struct { // The ID of the conversion task. - ConversionTaskID *string `locationName:"conversionTaskId" type:"string" required:"true"` + ConversionTaskId *string `locationName:"conversionTaskId" type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -7848,6 +7498,16 @@ type metadataCancelConversionTaskInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelConversionTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelConversionTaskInput) GoString() string { + return s.String() +} + type CancelConversionTaskOutput struct { metadataCancelConversionTaskOutput `json:"-" xml:"-"` } @@ -7856,9 +7516,19 @@ type metadataCancelConversionTaskOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelConversionTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelConversionTaskOutput) GoString() string { + return s.String() +} + type CancelExportTaskInput struct { // The ID of the export task. This is the ID returned by CreateInstanceExportTask. - ExportTaskID *string `locationName:"exportTaskId" type:"string" required:"true"` + ExportTaskId *string `locationName:"exportTaskId" type:"string" required:"true"` metadataCancelExportTaskInput `json:"-" xml:"-"` } @@ -7867,6 +7537,16 @@ type metadataCancelExportTaskInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelExportTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelExportTaskInput) GoString() string { + return s.String() +} + type CancelExportTaskOutput struct { metadataCancelExportTaskOutput `json:"-" xml:"-"` } @@ -7875,6 +7555,16 @@ type metadataCancelExportTaskOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelExportTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelExportTaskOutput) GoString() string { + return s.String() +} + type CancelImportTaskInput struct { // The reason for canceling the task. CancelReason *string `type:"string"` @@ -7886,7 +7576,7 @@ type CancelImportTaskInput struct { DryRun *bool `type:"boolean"` // The ID of the import image or import snapshot task to be canceled. - ImportTaskID *string `locationName:"ImportTaskId" type:"string"` + ImportTaskId *string `type:"string"` metadataCancelImportTaskInput `json:"-" xml:"-"` } @@ -7895,9 +7585,19 @@ type metadataCancelImportTaskInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelImportTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelImportTaskInput) GoString() string { + return s.String() +} + type CancelImportTaskOutput struct { // The ID of the task being canceled. - ImportTaskID *string `locationName:"importTaskId" type:"string"` + ImportTaskId *string `locationName:"importTaskId" type:"string"` // The current state of the task being canceled. PreviousState *string `locationName:"previousState" type:"string"` @@ -7912,9 +7612,19 @@ type metadataCancelImportTaskOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelImportTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelImportTaskOutput) GoString() string { + return s.String() +} + type CancelReservedInstancesListingInput struct { // The ID of the Reserved Instance listing. - ReservedInstancesListingID *string `locationName:"reservedInstancesListingId" type:"string" required:"true"` + ReservedInstancesListingId *string `locationName:"reservedInstancesListingId" type:"string" required:"true"` metadataCancelReservedInstancesListingInput `json:"-" xml:"-"` } @@ -7923,6 +7633,16 @@ type metadataCancelReservedInstancesListingInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelReservedInstancesListingInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelReservedInstancesListingInput) GoString() string { + return s.String() +} + type CancelReservedInstancesListingOutput struct { // The Reserved Instance listing. ReservedInstancesListings []*ReservedInstancesListing `locationName:"reservedInstancesListingsSet" locationNameList:"item" type:"list"` @@ -7934,10 +7654,20 @@ type metadataCancelReservedInstancesListingOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelReservedInstancesListingOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelReservedInstancesListingOutput) GoString() string { + return s.String() +} + // Describes a Spot fleet error. type CancelSpotFleetRequestsError struct { // The error code. - Code *string `locationName:"code" type:"string" required:"true"` + Code *string `locationName:"code" type:"string" required:"true" enum:"CancelBatchErrorCode"` // The description for the error code. Message *string `locationName:"message" type:"string" required:"true"` @@ -7949,13 +7679,23 @@ type metadataCancelSpotFleetRequestsError struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelSpotFleetRequestsError) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotFleetRequestsError) GoString() string { + return s.String() +} + // Describes a Spot fleet request that was not successfully canceled. type CancelSpotFleetRequestsErrorItem struct { // The error. Error *CancelSpotFleetRequestsError `locationName:"error" type:"structure" required:"true"` // The ID of the Spot fleet request. - SpotFleetRequestID *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` metadataCancelSpotFleetRequestsErrorItem `json:"-" xml:"-"` } @@ -7964,6 +7704,16 @@ type metadataCancelSpotFleetRequestsErrorItem struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelSpotFleetRequestsErrorItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotFleetRequestsErrorItem) GoString() string { + return s.String() +} + // Contains the parameters for CancelSpotFleetRequests. type CancelSpotFleetRequestsInput struct { // Checks whether you have the required permissions for the action, without @@ -7973,7 +7723,7 @@ type CancelSpotFleetRequestsInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The IDs of the Spot fleet requests. - SpotFleetRequestIDs []*string `locationName:"spotFleetRequestId" locationNameList:"item" type:"list" required:"true"` + SpotFleetRequestIds []*string `locationName:"spotFleetRequestId" locationNameList:"item" type:"list" required:"true"` // Indicates whether to terminate instances for a Spot fleet request if it is // canceled successfully. @@ -7986,6 +7736,16 @@ type metadataCancelSpotFleetRequestsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelSpotFleetRequestsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotFleetRequestsInput) GoString() string { + return s.String() +} + // Contains the output of CancelSpotFleetRequests. type CancelSpotFleetRequestsOutput struct { // Information about the Spot fleet requests that are successfully canceled. @@ -8001,16 +7761,26 @@ type metadataCancelSpotFleetRequestsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelSpotFleetRequestsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotFleetRequestsOutput) GoString() string { + return s.String() +} + // Describes a Spot fleet request that was successfully canceled. type CancelSpotFleetRequestsSuccessItem struct { // The current state of the Spot fleet request. - CurrentSpotFleetRequestState *string `locationName:"currentSpotFleetRequestState" type:"string" required:"true"` + CurrentSpotFleetRequestState *string `locationName:"currentSpotFleetRequestState" type:"string" required:"true" enum:"BatchState"` // The previous state of the Spot fleet request. - PreviousSpotFleetRequestState *string `locationName:"previousSpotFleetRequestState" type:"string" required:"true"` + PreviousSpotFleetRequestState *string `locationName:"previousSpotFleetRequestState" type:"string" required:"true" enum:"BatchState"` // The ID of the Spot fleet request. - SpotFleetRequestID *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` metadataCancelSpotFleetRequestsSuccessItem `json:"-" xml:"-"` } @@ -8019,6 +7789,16 @@ type metadataCancelSpotFleetRequestsSuccessItem struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelSpotFleetRequestsSuccessItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotFleetRequestsSuccessItem) GoString() string { + return s.String() +} + // Contains the parameters for CancelSpotInstanceRequests. type CancelSpotInstanceRequestsInput struct { // Checks whether you have the required permissions for the action, without @@ -8027,8 +7807,8 @@ type CancelSpotInstanceRequestsInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // One or more Spot Instance request IDs. - SpotInstanceRequestIDs []*string `locationName:"SpotInstanceRequestId" locationNameList:"SpotInstanceRequestId" type:"list" required:"true"` + // One or more Spot instance request IDs. + SpotInstanceRequestIds []*string `locationName:"SpotInstanceRequestId" locationNameList:"SpotInstanceRequestId" type:"list" required:"true"` metadataCancelSpotInstanceRequestsInput `json:"-" xml:"-"` } @@ -8037,9 +7817,19 @@ type metadataCancelSpotInstanceRequestsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelSpotInstanceRequestsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotInstanceRequestsInput) GoString() string { + return s.String() +} + // Contains the output of CancelSpotInstanceRequests. type CancelSpotInstanceRequestsOutput struct { - // One or more Spot Instance requests. + // One or more Spot instance requests. CancelledSpotInstanceRequests []*CancelledSpotInstanceRequest `locationName:"spotInstanceRequestSet" locationNameList:"item" type:"list"` metadataCancelSpotInstanceRequestsOutput `json:"-" xml:"-"` @@ -8049,13 +7839,23 @@ type metadataCancelSpotInstanceRequestsOutput struct { SDKShapeTraits bool `type:"structure"` } -// Describes a request to cancel a Spot Instance. +// String returns the string representation +func (s CancelSpotInstanceRequestsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelSpotInstanceRequestsOutput) GoString() string { + return s.String() +} + +// Describes a request to cancel a Spot instance. type CancelledSpotInstanceRequest struct { - // The ID of the Spot Instance request. - SpotInstanceRequestID *string `locationName:"spotInstanceRequestId" type:"string"` + // The ID of the Spot instance request. + SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` - // The state of the Spot Instance request. - State *string `locationName:"state" type:"string"` + // The state of the Spot instance request. + State *string `locationName:"state" type:"string" enum:"CancelSpotInstanceRequestState"` metadataCancelledSpotInstanceRequest `json:"-" xml:"-"` } @@ -8064,19 +7864,29 @@ type metadataCancelledSpotInstanceRequest struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CancelledSpotInstanceRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelledSpotInstanceRequest) GoString() string { + return s.String() +} + // Describes a linked EC2-Classic instance. type ClassicLinkInstance struct { // A list of security groups. Groups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // Any tags assigned to the instance. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string"` + VpcId *string `locationName:"vpcId" type:"string"` metadataClassicLinkInstance `json:"-" xml:"-"` } @@ -8085,6 +7895,16 @@ type metadataClassicLinkInstance struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ClassicLinkInstance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ClassicLinkInstance) GoString() string { + return s.String() +} + // Describes the client-specific data. type ClientData struct { // A user-defined comment about the disk upload. @@ -8106,6 +7926,16 @@ type metadataClientData struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ClientData) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ClientData) GoString() string { + return s.String() +} + type ConfirmProductInstanceInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -8114,7 +7944,7 @@ type ConfirmProductInstanceInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the instance. - InstanceID *string `locationName:"InstanceId" type:"string" required:"true"` + InstanceId *string `type:"string" required:"true"` // The product code. This must be a product code that you own. ProductCode *string `type:"string" required:"true"` @@ -8126,10 +7956,24 @@ type metadataConfirmProductInstanceInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ConfirmProductInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConfirmProductInstanceInput) GoString() string { + return s.String() +} + type ConfirmProductInstanceOutput struct { // The AWS account ID of the instance owner. This is only present if the product // code is attached to the instance. - OwnerID *string `locationName:"ownerId" type:"string"` + OwnerId *string `locationName:"ownerId" type:"string"` + + // The return value of the request. Returns true if the specified product code + // is owned by the requester and associated with the specified instance. + Return *bool `locationName:"return" type:"boolean"` metadataConfirmProductInstanceOutput `json:"-" xml:"-"` } @@ -8138,10 +7982,20 @@ type metadataConfirmProductInstanceOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ConfirmProductInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConfirmProductInstanceOutput) GoString() string { + return s.String() +} + // Describes a conversion task. type ConversionTask struct { // The ID of the conversion task. - ConversionTaskID *string `locationName:"conversionTaskId" type:"string" required:"true"` + ConversionTaskId *string `locationName:"conversionTaskId" type:"string" required:"true"` // The time when the task expires. If the upload isn't complete before the expiration // time, we automatically cancel the task. @@ -8156,7 +8010,7 @@ type ConversionTask struct { ImportVolume *ImportVolumeTaskDetails `locationName:"importVolume" type:"structure"` // The state of the conversion task. - State *string `locationName:"state" type:"string" required:"true"` + State *string `locationName:"state" type:"string" required:"true" enum:"ConversionTaskState"` // The status message related to the conversion task. StatusMessage *string `locationName:"statusMessage" type:"string"` @@ -8171,6 +8025,16 @@ type metadataConversionTask struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ConversionTask) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConversionTask) GoString() string { + return s.String() +} + type CopyImageInput struct { // Unique, case-sensitive identifier you provide to ensure idempotency of the // request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html) @@ -8190,7 +8054,7 @@ type CopyImageInput struct { Name *string `type:"string" required:"true"` // The ID of the AMI to copy. - SourceImageID *string `locationName:"SourceImageId" type:"string" required:"true"` + SourceImageId *string `type:"string" required:"true"` // The name of the region that contains the AMI to copy. SourceRegion *string `type:"string" required:"true"` @@ -8202,9 +8066,19 @@ type metadataCopyImageInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CopyImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopyImageInput) GoString() string { + return s.String() +} + type CopyImageOutput struct { // The ID of the new AMI. - ImageID *string `locationName:"imageId" type:"string"` + ImageId *string `locationName:"imageId" type:"string"` metadataCopyImageOutput `json:"-" xml:"-"` } @@ -8213,6 +8087,16 @@ type metadataCopyImageOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CopyImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopyImageOutput) GoString() string { + return s.String() +} + type CopySnapshotInput struct { // A description for the EBS snapshot. Description *string `type:"string"` @@ -8233,6 +8117,25 @@ type CopySnapshotInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` + // Specifies whether the destination snapshot should be encrypted. There is + // no way to create an unencrypted snapshot copy from an encrypted snapshot; + // however, you can encrypt a copy of an unencrypted snapshot with this flag. + // The default CMK for EBS is used unless a non-default AWS Key Management Service + // (AWS KMS) CMK is specified with KmsKeyId. For more information, see Amazon + // EBS Encryption (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) + // in the Amazon Elastic Compute Cloud User Guide. + Encrypted *bool `locationName:"encrypted" type:"boolean"` + + // The full ARN of the AWS Key Management Service (AWS KMS) CMK to use when + // creating the snapshot copy. This parameter is only required if you want to + // use a non-default CMK; if this parameter is not specified, the default CMK + // for EBS is used. The ARN contains the arn:aws:kms namespace, followed by + // the region of the CMK, the AWS account ID of the CMK owner, the key namespace, + // and then the CMK ID. For example, arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef. + // The specified CMK must exist in the region that the snapshot is being copied + // to. If a KmsKeyId is specified, the Encrypted flag must also be set. + KmsKeyId *string `locationName:"kmsKeyId" type:"string"` + // The pre-signed URL that facilitates copying an encrypted snapshot. This parameter // is only required when copying an encrypted snapshot with the Amazon EC2 Query // API; it is available as an optional parameter in all other cases. The PresignedUrl @@ -8245,13 +8148,13 @@ type CopySnapshotInput struct { // in the Amazon Simple Storage Service API Reference. An invalid or improperly // signed PresignedUrl will cause the copy operation to fail asynchronously, // and the snapshot will move to an error state. - PresignedURL *string `locationName:"presignedUrl" type:"string"` + PresignedUrl *string `locationName:"presignedUrl" type:"string"` // The ID of the region that contains the snapshot to be copied. SourceRegion *string `type:"string" required:"true"` // The ID of the EBS snapshot to copy. - SourceSnapshotID *string `locationName:"SourceSnapshotId" type:"string" required:"true"` + SourceSnapshotId *string `type:"string" required:"true"` metadataCopySnapshotInput `json:"-" xml:"-"` } @@ -8260,9 +8163,19 @@ type metadataCopySnapshotInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CopySnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopySnapshotInput) GoString() string { + return s.String() +} + type CopySnapshotOutput struct { // The ID of the new snapshot. - SnapshotID *string `locationName:"snapshotId" type:"string"` + SnapshotId *string `locationName:"snapshotId" type:"string"` metadataCopySnapshotOutput `json:"-" xml:"-"` } @@ -8271,11 +8184,21 @@ type metadataCopySnapshotOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CopySnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopySnapshotOutput) GoString() string { + return s.String() +} + type CreateCustomerGatewayInput struct { // For devices that support BGP, the customer gateway's BGP ASN. // // Default: 65000 - BGPASN *int64 `locationName:"BgpAsn" type:"integer" required:"true"` + BgpAsn *int64 `type:"integer" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -8285,10 +8208,10 @@ type CreateCustomerGatewayInput struct { // The Internet-routable IP address for the customer gateway's outside interface. // The address must be static. - PublicIP *string `locationName:"IpAddress" type:"string" required:"true"` + PublicIp *string `locationName:"IpAddress" type:"string" required:"true"` // The type of VPN connection that this customer gateway supports (ipsec.1). - Type *string `type:"string" required:"true"` + Type *string `type:"string" required:"true" enum:"GatewayType"` metadataCreateCustomerGatewayInput `json:"-" xml:"-"` } @@ -8297,6 +8220,16 @@ type metadataCreateCustomerGatewayInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateCustomerGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateCustomerGatewayInput) GoString() string { + return s.String() +} + type CreateCustomerGatewayOutput struct { // Information about the customer gateway. CustomerGateway *CustomerGateway `locationName:"customerGateway" type:"structure"` @@ -8308,9 +8241,19 @@ type metadataCreateCustomerGatewayOutput struct { SDKShapeTraits bool `type:"structure"` } -type CreateDHCPOptionsInput struct { +// String returns the string representation +func (s CreateCustomerGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateCustomerGatewayOutput) GoString() string { + return s.String() +} + +type CreateDhcpOptionsInput struct { // A DHCP configuration option. - DHCPConfigurations []*NewDHCPConfiguration `locationName:"dhcpConfiguration" locationNameList:"item" type:"list" required:"true"` + DhcpConfigurations []*NewDhcpConfiguration `locationName:"dhcpConfiguration" locationNameList:"item" type:"list" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -8318,24 +8261,110 @@ type CreateDHCPOptionsInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - metadataCreateDHCPOptionsInput `json:"-" xml:"-"` + metadataCreateDhcpOptionsInput `json:"-" xml:"-"` } -type metadataCreateDHCPOptionsInput struct { +type metadataCreateDhcpOptionsInput struct { SDKShapeTraits bool `type:"structure"` } -type CreateDHCPOptionsOutput struct { +// String returns the string representation +func (s CreateDhcpOptionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDhcpOptionsInput) GoString() string { + return s.String() +} + +type CreateDhcpOptionsOutput struct { // A set of DHCP options. - DHCPOptions *DHCPOptions `locationName:"dhcpOptions" type:"structure"` + DhcpOptions *DhcpOptions `locationName:"dhcpOptions" type:"structure"` + + metadataCreateDhcpOptionsOutput `json:"-" xml:"-"` +} + +type metadataCreateDhcpOptionsOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s CreateDhcpOptionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDhcpOptionsOutput) GoString() string { + return s.String() +} + +type CreateFlowLogsInput struct { + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // The ARN for the IAM role that's used to post flow logs to a CloudWatch Logs + // log group. + DeliverLogsPermissionArn *string `type:"string" required:"true"` + + // The name of the CloudWatch log group. + LogGroupName *string `type:"string" required:"true"` + + // One or more subnet, network interface, or VPC IDs. + ResourceIds []*string `locationName:"ResourceId" locationNameList:"item" type:"list" required:"true"` + + // The type of resource on which to create the flow log. + ResourceType *string `type:"string" required:"true" enum:"FlowLogsResourceType"` + + // The type of traffic to log. + TrafficType *string `type:"string" required:"true" enum:"TrafficType"` + + metadataCreateFlowLogsInput `json:"-" xml:"-"` +} + +type metadataCreateFlowLogsInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s CreateFlowLogsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFlowLogsInput) GoString() string { + return s.String() +} + +type CreateFlowLogsOutput struct { + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. + ClientToken *string `locationName:"clientToken" type:"string"` - metadataCreateDHCPOptionsOutput `json:"-" xml:"-"` + // The IDs of the flow logs. + FlowLogIds []*string `locationName:"flowLogIdSet" locationNameList:"item" type:"list"` + + // Information about the flow logs that could not be created successfully. + Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` + + metadataCreateFlowLogsOutput `json:"-" xml:"-"` } -type metadataCreateDHCPOptionsOutput struct { +type metadataCreateFlowLogsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateFlowLogsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFlowLogsOutput) GoString() string { + return s.String() +} + type CreateImageInput struct { // Information about one or more block device mappings. BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"BlockDeviceMapping" type:"list"` @@ -8350,7 +8379,7 @@ type CreateImageInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string" required:"true"` + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` // A name for the new image. // @@ -8373,9 +8402,19 @@ type metadataCreateImageInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateImageInput) GoString() string { + return s.String() +} + type CreateImageOutput struct { // The ID of the new AMI. - ImageID *string `locationName:"imageId" type:"string"` + ImageId *string `locationName:"imageId" type:"string"` metadataCreateImageOutput `json:"-" xml:"-"` } @@ -8384,6 +8423,16 @@ type metadataCreateImageOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateImageOutput) GoString() string { + return s.String() +} + type CreateInstanceExportTaskInput struct { // A description for the conversion task or the resource being exported. The // maximum length is 255 bytes. @@ -8393,10 +8442,10 @@ type CreateInstanceExportTaskInput struct { ExportToS3Task *ExportToS3TaskSpecification `locationName:"exportToS3" type:"structure"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string" required:"true"` + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` // The target virtualization environment. - TargetEnvironment *string `locationName:"targetEnvironment" type:"string"` + TargetEnvironment *string `locationName:"targetEnvironment" type:"string" enum:"ExportEnvironment"` metadataCreateInstanceExportTaskInput `json:"-" xml:"-"` } @@ -8405,6 +8454,16 @@ type metadataCreateInstanceExportTaskInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateInstanceExportTaskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInstanceExportTaskInput) GoString() string { + return s.String() +} + type CreateInstanceExportTaskOutput struct { // Information about the instance export task. ExportTask *ExportTask `locationName:"exportTask" type:"structure"` @@ -8416,6 +8475,16 @@ type metadataCreateInstanceExportTaskOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateInstanceExportTaskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInstanceExportTaskOutput) GoString() string { + return s.String() +} + type CreateInternetGatewayInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -8430,6 +8499,16 @@ type metadataCreateInternetGatewayInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateInternetGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInternetGatewayInput) GoString() string { + return s.String() +} + type CreateInternetGatewayOutput struct { // Information about the Internet gateway. InternetGateway *InternetGateway `locationName:"internetGateway" type:"structure"` @@ -8441,6 +8520,16 @@ type metadataCreateInternetGatewayOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateInternetGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInternetGatewayOutput) GoString() string { + return s.String() +} + type CreateKeyPairInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -8460,6 +8549,16 @@ type metadataCreateKeyPairInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateKeyPairInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateKeyPairInput) GoString() string { + return s.String() +} + // Describes a key pair. type CreateKeyPairOutput struct { // The SHA-1 digest of the DER encoded private key. @@ -8478,9 +8577,19 @@ type metadataCreateKeyPairOutput struct { SDKShapeTraits bool `type:"structure"` } -type CreateNetworkACLEntryInput struct { +// String returns the string representation +func (s CreateKeyPairOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateKeyPairOutput) GoString() string { + return s.String() +} + +type CreateNetworkAclEntryInput struct { // The network range to allow or deny, in CIDR notation (for example 172.16.0.0/24). - CIDRBlock *string `locationName:"cidrBlock" type:"string" required:"true"` + CidrBlock *string `locationName:"cidrBlock" type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -8494,10 +8603,10 @@ type CreateNetworkACLEntryInput struct { // ICMP protocol: The ICMP type and code. Required if specifying ICMP for the // protocol. - ICMPTypeCode *ICMPTypeCode `locationName:"Icmp" type:"structure"` + IcmpTypeCode *IcmpTypeCode `locationName:"Icmp" type:"structure"` // The ID of the network ACL. - NetworkACLID *string `locationName:"networkAclId" type:"string" required:"true"` + NetworkAclId *string `locationName:"networkAclId" type:"string" required:"true"` // TCP or UDP protocols: The range of ports the rule applies to. PortRange *PortRange `locationName:"portRange" type:"structure"` @@ -8506,7 +8615,7 @@ type CreateNetworkACLEntryInput struct { Protocol *string `locationName:"protocol" type:"string" required:"true"` // Indicates whether to allow or deny the traffic that matches the rule. - RuleAction *string `locationName:"ruleAction" type:"string" required:"true"` + RuleAction *string `locationName:"ruleAction" type:"string" required:"true" enum:"RuleAction"` // The rule number for the entry (for example, 100). ACL entries are processed // in ascending order by rule number. @@ -8514,22 +8623,42 @@ type CreateNetworkACLEntryInput struct { // Constraints: Positive integer from 1 to 32766 RuleNumber *int64 `locationName:"ruleNumber" type:"integer" required:"true"` - metadataCreateNetworkACLEntryInput `json:"-" xml:"-"` + metadataCreateNetworkAclEntryInput `json:"-" xml:"-"` } -type metadataCreateNetworkACLEntryInput struct { +type metadataCreateNetworkAclEntryInput struct { SDKShapeTraits bool `type:"structure"` } -type CreateNetworkACLEntryOutput struct { - metadataCreateNetworkACLEntryOutput `json:"-" xml:"-"` +// String returns the string representation +func (s CreateNetworkAclEntryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkAclEntryInput) GoString() string { + return s.String() +} + +type CreateNetworkAclEntryOutput struct { + metadataCreateNetworkAclEntryOutput `json:"-" xml:"-"` } -type metadataCreateNetworkACLEntryOutput struct { +type metadataCreateNetworkAclEntryOutput struct { SDKShapeTraits bool `type:"structure"` } -type CreateNetworkACLInput struct { +// String returns the string representation +func (s CreateNetworkAclEntryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkAclEntryOutput) GoString() string { + return s.String() +} + +type CreateNetworkAclInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -8537,26 +8666,46 @@ type CreateNetworkACLInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string" required:"true"` + VpcId *string `locationName:"vpcId" type:"string" required:"true"` - metadataCreateNetworkACLInput `json:"-" xml:"-"` + metadataCreateNetworkAclInput `json:"-" xml:"-"` } -type metadataCreateNetworkACLInput struct { +type metadataCreateNetworkAclInput struct { SDKShapeTraits bool `type:"structure"` } -type CreateNetworkACLOutput struct { +// String returns the string representation +func (s CreateNetworkAclInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkAclInput) GoString() string { + return s.String() +} + +type CreateNetworkAclOutput struct { // Information about the network ACL. - NetworkACL *NetworkACL `locationName:"networkAcl" type:"structure"` + NetworkAcl *NetworkAcl `locationName:"networkAcl" type:"structure"` - metadataCreateNetworkACLOutput `json:"-" xml:"-"` + metadataCreateNetworkAclOutput `json:"-" xml:"-"` } -type metadataCreateNetworkACLOutput struct { +type metadataCreateNetworkAclOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateNetworkAclOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkAclOutput) GoString() string { + return s.String() +} + type CreateNetworkInterfaceInput struct { // A description for the network interface. Description *string `locationName:"description" type:"string"` @@ -8574,10 +8723,10 @@ type CreateNetworkInterfaceInput struct { // an IP address, Amazon EC2 selects one for you from the subnet range. If you // specify an IP address, you cannot indicate any IP addresses specified in // privateIpAddresses as primary (only one IP address can be designated as primary). - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` // One or more private IP addresses. - PrivateIPAddresses []*PrivateIPAddressSpecification `locationName:"privateIpAddresses" locationNameList:"item" type:"list"` + PrivateIpAddresses []*PrivateIpAddressSpecification `locationName:"privateIpAddresses" locationNameList:"item" type:"list"` // The number of secondary private IP addresses to assign to a network interface. // When you specify a number of secondary IP addresses, Amazon EC2 selects these @@ -8588,10 +8737,10 @@ type CreateNetworkInterfaceInput struct { // by instance type. For more information, see Private IP Addresses Per ENI // Per Instance Type (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI) // in the Amazon Elastic Compute Cloud User Guide. - SecondaryPrivateIPAddressCount *int64 `locationName:"secondaryPrivateIpAddressCount" type:"integer"` + SecondaryPrivateIpAddressCount *int64 `locationName:"secondaryPrivateIpAddressCount" type:"integer"` // The ID of the subnet to associate with the network interface. - SubnetID *string `locationName:"subnetId" type:"string" required:"true"` + SubnetId *string `locationName:"subnetId" type:"string" required:"true"` metadataCreateNetworkInterfaceInput `json:"-" xml:"-"` } @@ -8600,6 +8749,16 @@ type metadataCreateNetworkInterfaceInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateNetworkInterfaceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkInterfaceInput) GoString() string { + return s.String() +} + type CreateNetworkInterfaceOutput struct { // Information about the network interface. NetworkInterface *NetworkInterface `locationName:"networkInterface" type:"structure"` @@ -8611,6 +8770,16 @@ type metadataCreateNetworkInterfaceOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateNetworkInterfaceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkInterfaceOutput) GoString() string { + return s.String() +} + type CreatePlacementGroupInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -8624,7 +8793,7 @@ type CreatePlacementGroupInput struct { GroupName *string `locationName:"groupName" type:"string" required:"true"` // The placement strategy. - Strategy *string `locationName:"strategy" type:"string" required:"true"` + Strategy *string `locationName:"strategy" type:"string" required:"true" enum:"PlacementStrategy"` metadataCreatePlacementGroupInput `json:"-" xml:"-"` } @@ -8633,6 +8802,16 @@ type metadataCreatePlacementGroupInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreatePlacementGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreatePlacementGroupInput) GoString() string { + return s.String() +} + type CreatePlacementGroupOutput struct { metadataCreatePlacementGroupOutput `json:"-" xml:"-"` } @@ -8641,6 +8820,16 @@ type metadataCreatePlacementGroupOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreatePlacementGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreatePlacementGroupOutput) GoString() string { + return s.String() +} + type CreateReservedInstancesListingInput struct { // Unique, case-sensitive identifier you provide to ensure idempotency of your // listings. This helps avoid duplicate listings. For more information, see @@ -8658,7 +8847,7 @@ type CreateReservedInstancesListingInput struct { PriceSchedules []*PriceScheduleSpecification `locationName:"priceSchedules" locationNameList:"item" type:"list" required:"true"` // The ID of the active Reserved Instance. - ReservedInstancesID *string `locationName:"reservedInstancesId" type:"string" required:"true"` + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string" required:"true"` metadataCreateReservedInstancesListingInput `json:"-" xml:"-"` } @@ -8667,6 +8856,16 @@ type metadataCreateReservedInstancesListingInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateReservedInstancesListingInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateReservedInstancesListingInput) GoString() string { + return s.String() +} + type CreateReservedInstancesListingOutput struct { // Information about the Reserved Instances listing. ReservedInstancesListings []*ReservedInstancesListing `locationName:"reservedInstancesListingsSet" locationNameList:"item" type:"list"` @@ -8678,14 +8877,20 @@ type metadataCreateReservedInstancesListingOutput struct { SDKShapeTraits bool `type:"structure"` } -type CreateRouteInput struct { - // Unique, case-sensitive identifier you provide to ensure the idempotency of - // the request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). - ClientToken *string `locationName:"clientToken" type:"string"` +// String returns the string representation +func (s CreateReservedInstancesListingOutput) String() string { + return awsutil.Prettify(s) +} +// GoString returns the string representation +func (s CreateReservedInstancesListingOutput) GoString() string { + return s.String() +} + +type CreateRouteInput struct { // The CIDR address block used for the destination match. Routing decisions // are based on the most specific match. - DestinationCIDRBlock *string `locationName:"destinationCidrBlock" type:"string" required:"true"` + DestinationCidrBlock *string `locationName:"destinationCidrBlock" type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -8695,20 +8900,20 @@ type CreateRouteInput struct { // The ID of an Internet gateway or virtual private gateway attached to your // VPC. - GatewayID *string `locationName:"gatewayId" type:"string"` + GatewayId *string `locationName:"gatewayId" type:"string"` // The ID of a NAT instance in your VPC. The operation fails if you specify // an instance ID unless exactly one network interface is attached. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The ID of a network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` // The ID of the route table for the route. - RouteTableID *string `locationName:"routeTableId" type:"string" required:"true"` + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` // The ID of a VPC peering connection. - VPCPeeringConnectionID *string `locationName:"vpcPeeringConnectionId" type:"string"` + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` metadataCreateRouteInput `json:"-" xml:"-"` } @@ -8717,11 +8922,17 @@ type metadataCreateRouteInput struct { SDKShapeTraits bool `type:"structure"` } -type CreateRouteOutput struct { - // Unique, case-sensitive identifier you provide to ensure the idempotency of - // the request. - ClientToken *string `locationName:"clientToken" type:"string"` +// String returns the string representation +func (s CreateRouteInput) String() string { + return awsutil.Prettify(s) +} +// GoString returns the string representation +func (s CreateRouteInput) GoString() string { + return s.String() +} + +type CreateRouteOutput struct { // Returns true if the request succeeds; otherwise, it returns an error. Return *bool `locationName:"return" type:"boolean"` @@ -8732,6 +8943,16 @@ type metadataCreateRouteOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateRouteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRouteOutput) GoString() string { + return s.String() +} + type CreateRouteTableInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -8740,7 +8961,7 @@ type CreateRouteTableInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string" required:"true"` + VpcId *string `locationName:"vpcId" type:"string" required:"true"` metadataCreateRouteTableInput `json:"-" xml:"-"` } @@ -8749,6 +8970,16 @@ type metadataCreateRouteTableInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateRouteTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRouteTableInput) GoString() string { + return s.String() +} + type CreateRouteTableOutput struct { // Information about the route table. RouteTable *RouteTable `locationName:"routeTable" type:"structure"` @@ -8760,6 +8991,16 @@ type metadataCreateRouteTableOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateRouteTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRouteTableOutput) GoString() string { + return s.String() +} + type CreateSecurityGroupInput struct { // A description for the security group. This is informational only. // @@ -8786,7 +9027,7 @@ type CreateSecurityGroupInput struct { GroupName *string `type:"string" required:"true"` // [EC2-VPC] The ID of the VPC. Required for EC2-VPC. - VPCID *string `locationName:"VpcId" type:"string"` + VpcId *string `type:"string"` metadataCreateSecurityGroupInput `json:"-" xml:"-"` } @@ -8795,9 +9036,19 @@ type metadataCreateSecurityGroupInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateSecurityGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSecurityGroupInput) GoString() string { + return s.String() +} + type CreateSecurityGroupOutput struct { // The ID of the security group. - GroupID *string `locationName:"groupId" type:"string"` + GroupId *string `locationName:"groupId" type:"string"` metadataCreateSecurityGroupOutput `json:"-" xml:"-"` } @@ -8806,6 +9057,16 @@ type metadataCreateSecurityGroupOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateSecurityGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSecurityGroupOutput) GoString() string { + return s.String() +} + type CreateSnapshotInput struct { // A description for the snapshot. Description *string `type:"string"` @@ -8817,7 +9078,7 @@ type CreateSnapshotInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the EBS volume. - VolumeID *string `locationName:"VolumeId" type:"string" required:"true"` + VolumeId *string `type:"string" required:"true"` metadataCreateSnapshotInput `json:"-" xml:"-"` } @@ -8826,9 +9087,19 @@ type metadataCreateSnapshotInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSnapshotInput) GoString() string { + return s.String() +} + // Contains the parameters for CreateSpotDatafeedSubscription. type CreateSpotDatafeedSubscriptionInput struct { - // The Amazon S3 bucket in which to store the Spot Instance data feed. + // The Amazon S3 bucket in which to store the Spot instance data feed. Bucket *string `locationName:"bucket" type:"string" required:"true"` // Checks whether you have the required permissions for the action, without @@ -8847,9 +9118,19 @@ type metadataCreateSpotDatafeedSubscriptionInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateSpotDatafeedSubscriptionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSpotDatafeedSubscriptionInput) GoString() string { + return s.String() +} + // Contains the output of CreateSpotDatafeedSubscription. type CreateSpotDatafeedSubscriptionOutput struct { - // The Spot Instance data feed subscription. + // The Spot instance data feed subscription. SpotDatafeedSubscription *SpotDatafeedSubscription `locationName:"spotDatafeedSubscription" type:"structure"` metadataCreateSpotDatafeedSubscriptionOutput `json:"-" xml:"-"` @@ -8859,6 +9140,16 @@ type metadataCreateSpotDatafeedSubscriptionOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateSpotDatafeedSubscriptionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSpotDatafeedSubscriptionOutput) GoString() string { + return s.String() +} + type CreateSubnetInput struct { // The Availability Zone for the subnet. // @@ -8866,7 +9157,7 @@ type CreateSubnetInput struct { AvailabilityZone *string `type:"string"` // The network range for the subnet, in CIDR notation. For example, 10.0.0.0/24. - CIDRBlock *string `locationName:"CidrBlock" type:"string" required:"true"` + CidrBlock *string `type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -8875,7 +9166,7 @@ type CreateSubnetInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the VPC. - VPCID *string `locationName:"VpcId" type:"string" required:"true"` + VpcId *string `type:"string" required:"true"` metadataCreateSubnetInput `json:"-" xml:"-"` } @@ -8884,6 +9175,16 @@ type metadataCreateSubnetInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateSubnetInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSubnetInput) GoString() string { + return s.String() +} + type CreateSubnetOutput struct { // Information about the subnet. Subnet *Subnet `locationName:"subnet" type:"structure"` @@ -8895,7 +9196,17 @@ type metadataCreateSubnetOutput struct { SDKShapeTraits bool `type:"structure"` } -type CreateTagsInput struct { +// String returns the string representation +func (s CreateSubnetOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSubnetOutput) GoString() string { + return s.String() +} + +type CreateTagsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -8917,6 +9228,16 @@ type metadataCreateTagsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateTagsInput) GoString() string { + return s.String() +} + type CreateTagsOutput struct { metadataCreateTagsOutput `json:"-" xml:"-"` } @@ -8925,7 +9246,144 @@ type metadataCreateTagsOutput struct { SDKShapeTraits bool `type:"structure"` } -type CreateVPCEndpointInput struct { +// String returns the string representation +func (s CreateTagsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateTagsOutput) GoString() string { + return s.String() +} + +type CreateVolumeInput struct { + // The Availability Zone in which to create the volume. Use DescribeAvailabilityZones + // to list the Availability Zones that are currently available to you. + AvailabilityZone *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // Specifies whether the volume should be encrypted. Encrypted Amazon EBS volumes + // may only be attached to instances that support Amazon EBS encryption. Volumes + // that are created from encrypted snapshots are automatically encrypted. There + // is no way to create an encrypted volume from an unencrypted snapshot or vice + // versa. If your AMI uses encrypted volumes, you can only launch it on supported + // instance types. For more information, see Amazon EBS Encryption (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) + // in the Amazon Elastic Compute Cloud User Guide. + Encrypted *bool `locationName:"encrypted" type:"boolean"` + + // Only valid for Provisioned IOPS (SSD) volumes. The number of I/O operations + // per second (IOPS) to provision for the volume, with a maximum ratio of 30 + // IOPS/GiB. + // + // Constraint: Range is 100 to 20000 for Provisioned IOPS (SSD) volumes + Iops *int64 `type:"integer"` + + // The full ARN of the AWS Key Management Service (AWS KMS) customer master + // key (CMK) to use when creating the encrypted volume. This parameter is only + // required if you want to use a non-default CMK; if this parameter is not specified, + // the default CMK for EBS is used. The ARN contains the arn:aws:kms namespace, + // followed by the region of the CMK, the AWS account ID of the CMK owner, the + // key namespace, and then the CMK ID. For example, arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef. + // If a KmsKeyId is specified, the Encrypted flag must also be set. + KmsKeyId *string `type:"string"` + + // The size of the volume, in GiBs. + // + // Constraints: 1-1024 for standard volumes, 1-16384 for gp2 volumes, and 4-16384 + // for io1 volumes. If you specify a snapshot, the volume size must be equal + // to or larger than the snapshot size. + // + // Default: If you're creating the volume from a snapshot and don't specify + // a volume size, the default is the snapshot size. + Size *int64 `type:"integer"` + + // The snapshot from which to create the volume. + SnapshotId *string `type:"string"` + + // The volume type. This can be gp2 for General Purpose (SSD) volumes, io1 for + // Provisioned IOPS (SSD) volumes, or standard for Magnetic volumes. + // + // Default: standard + VolumeType *string `type:"string" enum:"VolumeType"` + + metadataCreateVolumeInput `json:"-" xml:"-"` +} + +type metadataCreateVolumeInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s CreateVolumeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVolumeInput) GoString() string { + return s.String() +} + +// Describes the user or group to be added or removed from the permissions for +// a volume. +type CreateVolumePermission struct { + // The specific group that is to be added or removed from a volume's list of + // create volume permissions. + Group *string `locationName:"group" type:"string" enum:"PermissionGroup"` + + // The specific AWS account ID that is to be added or removed from a volume's + // list of create volume permissions. + UserId *string `locationName:"userId" type:"string"` + + metadataCreateVolumePermission `json:"-" xml:"-"` +} + +type metadataCreateVolumePermission struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s CreateVolumePermission) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVolumePermission) GoString() string { + return s.String() +} + +// Describes modifications to the permissions for a volume. +type CreateVolumePermissionModifications struct { + // Adds a specific AWS account ID or group to a volume's list of create volume + // permissions. + Add []*CreateVolumePermission `locationNameList:"item" type:"list"` + + // Removes a specific AWS account ID or group from a volume's list of create + // volume permissions. + Remove []*CreateVolumePermission `locationNameList:"item" type:"list"` + + metadataCreateVolumePermissionModifications `json:"-" xml:"-"` +} + +type metadataCreateVolumePermissionModifications struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s CreateVolumePermissionModifications) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVolumePermissionModifications) GoString() string { + return s.String() +} + +type CreateVpcEndpointInput struct { // Unique, case-sensitive identifier you provide to ensure the idempotency of // the request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). ClientToken *string `type:"string"` @@ -8942,40 +9400,60 @@ type CreateVPCEndpointInput struct { PolicyDocument *string `type:"string"` // One or more route table IDs. - RouteTableIDs []*string `locationName:"RouteTableId" locationNameList:"item" type:"list"` + RouteTableIds []*string `locationName:"RouteTableId" locationNameList:"item" type:"list"` - // The AWS service name, in the form com.amazonaws... To get - // a list of available services, use the DescribeVpcEndpointServices request. + // The AWS service name, in the form com.amazonaws.region.service. To get a + // list of available services, use the DescribeVpcEndpointServices request. ServiceName *string `type:"string" required:"true"` // The ID of the VPC in which the endpoint will be used. - VPCID *string `locationName:"VpcId" type:"string" required:"true"` + VpcId *string `type:"string" required:"true"` - metadataCreateVPCEndpointInput `json:"-" xml:"-"` + metadataCreateVpcEndpointInput `json:"-" xml:"-"` } -type metadataCreateVPCEndpointInput struct { +type metadataCreateVpcEndpointInput struct { SDKShapeTraits bool `type:"structure"` } -type CreateVPCEndpointOutput struct { +// String returns the string representation +func (s CreateVpcEndpointInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcEndpointInput) GoString() string { + return s.String() +} + +type CreateVpcEndpointOutput struct { // Unique, case-sensitive identifier you provide to ensure the idempotency of // the request. ClientToken *string `locationName:"clientToken" type:"string"` // Information about the endpoint. - VPCEndpoint *VPCEndpoint `locationName:"vpcEndpoint" type:"structure"` + VpcEndpoint *VpcEndpoint `locationName:"vpcEndpoint" type:"structure"` - metadataCreateVPCEndpointOutput `json:"-" xml:"-"` + metadataCreateVpcEndpointOutput `json:"-" xml:"-"` } -type metadataCreateVPCEndpointOutput struct { +type metadataCreateVpcEndpointOutput struct { SDKShapeTraits bool `type:"structure"` } -type CreateVPCInput struct { +// String returns the string representation +func (s CreateVpcEndpointOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcEndpointOutput) GoString() string { + return s.String() +} + +type CreateVpcInput struct { // The network range for the VPC, in CIDR notation. For example, 10.0.0.0/16. - CIDRBlock *string `locationName:"CidrBlock" type:"string" required:"true"` + CidrBlock *string `type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -8990,27 +9468,47 @@ type CreateVPCInput struct { // Dedicated tenancy instances run on single-tenant hardware. // // Default: default - InstanceTenancy *string `locationName:"instanceTenancy" type:"string"` + InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` - metadataCreateVPCInput `json:"-" xml:"-"` + metadataCreateVpcInput `json:"-" xml:"-"` } -type metadataCreateVPCInput struct { +type metadataCreateVpcInput struct { SDKShapeTraits bool `type:"structure"` } -type CreateVPCOutput struct { +// String returns the string representation +func (s CreateVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcInput) GoString() string { + return s.String() +} + +type CreateVpcOutput struct { // Information about the VPC. - VPC *VPC `locationName:"vpc" type:"structure"` + Vpc *Vpc `locationName:"vpc" type:"structure"` - metadataCreateVPCOutput `json:"-" xml:"-"` + metadataCreateVpcOutput `json:"-" xml:"-"` } -type metadataCreateVPCOutput struct { +type metadataCreateVpcOutput struct { SDKShapeTraits bool `type:"structure"` } -type CreateVPCPeeringConnectionInput struct { +// String returns the string representation +func (s CreateVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcOutput) GoString() string { + return s.String() +} + +type CreateVpcPeeringConnectionInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -9020,35 +9518,55 @@ type CreateVPCPeeringConnectionInput struct { // The AWS account ID of the owner of the peer VPC. // // Default: Your AWS account ID - PeerOwnerID *string `locationName:"peerOwnerId" type:"string"` + PeerOwnerId *string `locationName:"peerOwnerId" type:"string"` // The ID of the VPC with which you are creating the VPC peering connection. - PeerVPCID *string `locationName:"peerVpcId" type:"string"` + PeerVpcId *string `locationName:"peerVpcId" type:"string"` // The ID of the requester VPC. - VPCID *string `locationName:"vpcId" type:"string"` + VpcId *string `locationName:"vpcId" type:"string"` - metadataCreateVPCPeeringConnectionInput `json:"-" xml:"-"` + metadataCreateVpcPeeringConnectionInput `json:"-" xml:"-"` } -type metadataCreateVPCPeeringConnectionInput struct { +type metadataCreateVpcPeeringConnectionInput struct { SDKShapeTraits bool `type:"structure"` } -type CreateVPCPeeringConnectionOutput struct { +// String returns the string representation +func (s CreateVpcPeeringConnectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcPeeringConnectionInput) GoString() string { + return s.String() +} + +type CreateVpcPeeringConnectionOutput struct { // Information about the VPC peering connection. - VPCPeeringConnection *VPCPeeringConnection `locationName:"vpcPeeringConnection" type:"structure"` + VpcPeeringConnection *VpcPeeringConnection `locationName:"vpcPeeringConnection" type:"structure"` - metadataCreateVPCPeeringConnectionOutput `json:"-" xml:"-"` + metadataCreateVpcPeeringConnectionOutput `json:"-" xml:"-"` } -type metadataCreateVPCPeeringConnectionOutput struct { +type metadataCreateVpcPeeringConnectionOutput struct { SDKShapeTraits bool `type:"structure"` } -type CreateVPNConnectionInput struct { +// String returns the string representation +func (s CreateVpcPeeringConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcPeeringConnectionOutput) GoString() string { + return s.String() +} + +type CreateVpnConnectionInput struct { // The ID of the customer gateway. - CustomerGatewayID *string `locationName:"CustomerGatewayId" type:"string" required:"true"` + CustomerGatewayId *string `type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9061,89 +9579,97 @@ type CreateVPNConnectionInput struct { // true. // // Default: false - Options *VPNConnectionOptionsSpecification `locationName:"options" type:"structure"` + Options *VpnConnectionOptionsSpecification `locationName:"options" type:"structure"` // The type of VPN connection (ipsec.1). Type *string `type:"string" required:"true"` // The ID of the virtual private gateway. - VPNGatewayID *string `locationName:"VpnGatewayId" type:"string" required:"true"` + VpnGatewayId *string `type:"string" required:"true"` - metadataCreateVPNConnectionInput `json:"-" xml:"-"` + metadataCreateVpnConnectionInput `json:"-" xml:"-"` } -type metadataCreateVPNConnectionInput struct { +type metadataCreateVpnConnectionInput struct { SDKShapeTraits bool `type:"structure"` } -type CreateVPNConnectionOutput struct { +// String returns the string representation +func (s CreateVpnConnectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpnConnectionInput) GoString() string { + return s.String() +} + +type CreateVpnConnectionOutput struct { // Information about the VPN connection. - VPNConnection *VPNConnection `locationName:"vpnConnection" type:"structure"` + VpnConnection *VpnConnection `locationName:"vpnConnection" type:"structure"` - metadataCreateVPNConnectionOutput `json:"-" xml:"-"` + metadataCreateVpnConnectionOutput `json:"-" xml:"-"` } -type metadataCreateVPNConnectionOutput struct { +type metadataCreateVpnConnectionOutput struct { SDKShapeTraits bool `type:"structure"` } -type CreateVPNConnectionRouteInput struct { +// String returns the string representation +func (s CreateVpnConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpnConnectionOutput) GoString() string { + return s.String() +} + +type CreateVpnConnectionRouteInput struct { // The CIDR block associated with the local subnet of the customer network. - DestinationCIDRBlock *string `locationName:"DestinationCidrBlock" type:"string" required:"true"` + DestinationCidrBlock *string `type:"string" required:"true"` // The ID of the VPN connection. - VPNConnectionID *string `locationName:"VpnConnectionId" type:"string" required:"true"` + VpnConnectionId *string `type:"string" required:"true"` - metadataCreateVPNConnectionRouteInput `json:"-" xml:"-"` + metadataCreateVpnConnectionRouteInput `json:"-" xml:"-"` } -type metadataCreateVPNConnectionRouteInput struct { +type metadataCreateVpnConnectionRouteInput struct { SDKShapeTraits bool `type:"structure"` } -type CreateVPNConnectionRouteOutput struct { - metadataCreateVPNConnectionRouteOutput `json:"-" xml:"-"` +// String returns the string representation +func (s CreateVpnConnectionRouteInput) String() string { + return awsutil.Prettify(s) } -type metadataCreateVPNConnectionRouteOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s CreateVpnConnectionRouteInput) GoString() string { + return s.String() } -type CreateVPNGatewayInput struct { - // The Availability Zone for the virtual private gateway. - AvailabilityZone *string `type:"string"` - - // Checks whether you have the required permissions for the action, without - // actually making the request, and provides an error response. If you have - // the required permissions, the error response is DryRunOperation. Otherwise, - // it is UnauthorizedOperation. - DryRun *bool `locationName:"dryRun" type:"boolean"` - - // The type of VPN connection this virtual private gateway supports. - Type *string `type:"string" required:"true"` - - metadataCreateVPNGatewayInput `json:"-" xml:"-"` +type CreateVpnConnectionRouteOutput struct { + metadataCreateVpnConnectionRouteOutput `json:"-" xml:"-"` } -type metadataCreateVPNGatewayInput struct { +type metadataCreateVpnConnectionRouteOutput struct { SDKShapeTraits bool `type:"structure"` } -type CreateVPNGatewayOutput struct { - // Information about the virtual private gateway. - VPNGateway *VPNGateway `locationName:"vpnGateway" type:"structure"` - - metadataCreateVPNGatewayOutput `json:"-" xml:"-"` +// String returns the string representation +func (s CreateVpnConnectionRouteOutput) String() string { + return awsutil.Prettify(s) } -type metadataCreateVPNGatewayOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s CreateVpnConnectionRouteOutput) GoString() string { + return s.String() } -type CreateVolumeInput struct { - // The Availability Zone in which to create the volume. Use DescribeAvailabilityZones - // to list the Availability Zones that are currently available to you. - AvailabilityZone *string `type:"string" required:"true"` +type CreateVpnGatewayInput struct { + // The Availability Zone for the virtual private gateway. + AvailabilityZone *string `type:"string"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9151,102 +9677,58 @@ type CreateVolumeInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // Specifies whether the volume should be encrypted. Encrypted Amazon EBS volumes - // may only be attached to instances that support Amazon EBS encryption. Volumes - // that are created from encrypted snapshots are automatically encrypted. There - // is no way to create an encrypted volume from an unencrypted snapshot or vice - // versa. If your AMI uses encrypted volumes, you can only launch it on supported - // instance types. For more information, see Amazon EBS Encryption (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) - // in the Amazon Elastic Compute Cloud User Guide. - Encrypted *bool `locationName:"encrypted" type:"boolean"` - - // Only valid for Provisioned IOPS (SSD) volumes. The number of I/O operations - // per second (IOPS) to provision for the volume, with a maximum ratio of 30 - // IOPS/GiB. - // - // Constraint: Range is 100 to 20000 for Provisioned IOPS (SSD) volumes - IOPS *int64 `locationName:"Iops" type:"integer"` - - // The full ARN of the AWS Key Management Service (KMS) master key to use when - // creating the encrypted volume. This parameter is only required if you want - // to use a non-default master key; if this parameter is not specified, the - // default master key is used. The ARN contains the arn:aws:kms namespace, followed - // by the region of the master key, the AWS account ID of the master key owner, - // the key namespace, and then the master key ID. For example, arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef. - KMSKeyID *string `locationName:"KmsKeyId" type:"string"` - - // The size of the volume, in GiBs. - // - // Constraints: 1-1024 for standard volumes, 1-16384 for gp2 volumes, and 4-16384 - // for io1 volumes. If you specify a snapshot, the volume size must be equal - // to or larger than the snapshot size. - // - // Default: If you're creating the volume from a snapshot and don't specify - // a volume size, the default is the snapshot size. - Size *int64 `type:"integer"` - - // The snapshot from which to create the volume. - SnapshotID *string `locationName:"SnapshotId" type:"string"` - - // The volume type. This can be gp2 for General Purpose (SSD) volumes, io1 for - // Provisioned IOPS (SSD) volumes, or standard for Magnetic volumes. - // - // Default: standard - VolumeType *string `type:"string"` + // The type of VPN connection this virtual private gateway supports. + Type *string `type:"string" required:"true" enum:"GatewayType"` - metadataCreateVolumeInput `json:"-" xml:"-"` + metadataCreateVpnGatewayInput `json:"-" xml:"-"` } -type metadataCreateVolumeInput struct { +type metadataCreateVpnGatewayInput struct { SDKShapeTraits bool `type:"structure"` } -// Describes the user or group to be added or removed from the permissions for -// a volume. -type CreateVolumePermission struct { - // The specific group that is to be added or removed from a volume's list of - // create volume permissions. - Group *string `locationName:"group" type:"string"` +// String returns the string representation +func (s CreateVpnGatewayInput) String() string { + return awsutil.Prettify(s) +} - // The specific AWS account ID that is to be added or removed from a volume's - // list of create volume permissions. - UserID *string `locationName:"userId" type:"string"` +// GoString returns the string representation +func (s CreateVpnGatewayInput) GoString() string { + return s.String() +} - metadataCreateVolumePermission `json:"-" xml:"-"` +type CreateVpnGatewayOutput struct { + // Information about the virtual private gateway. + VpnGateway *VpnGateway `locationName:"vpnGateway" type:"structure"` + + metadataCreateVpnGatewayOutput `json:"-" xml:"-"` } -type metadataCreateVolumePermission struct { +type metadataCreateVpnGatewayOutput struct { SDKShapeTraits bool `type:"structure"` } -// Describes modifications to the permissions for a volume. -type CreateVolumePermissionModifications struct { - // Adds a specific AWS account ID or group to a volume's list of create volume - // permissions. - Add []*CreateVolumePermission `locationNameList:"item" type:"list"` - - // Removes a specific AWS account ID or group from a volume's list of create - // volume permissions. - Remove []*CreateVolumePermission `locationNameList:"item" type:"list"` - - metadataCreateVolumePermissionModifications `json:"-" xml:"-"` +// String returns the string representation +func (s CreateVpnGatewayOutput) String() string { + return awsutil.Prettify(s) } -type metadataCreateVolumePermissionModifications struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s CreateVpnGatewayOutput) GoString() string { + return s.String() } // Describes a customer gateway. type CustomerGateway struct { // The customer gateway's Border Gateway Protocol (BGP) Autonomous System Number // (ASN). - BGPASN *string `locationName:"bgpAsn" type:"string"` + BgpAsn *string `locationName:"bgpAsn" type:"string"` // The ID of the customer gateway. - CustomerGatewayID *string `locationName:"customerGatewayId" type:"string"` + CustomerGatewayId *string `locationName:"customerGatewayId" type:"string"` // The Internet-routable IP address of the customer gateway's outside interface. - IPAddress *string `locationName:"ipAddress" type:"string"` + IpAddress *string `locationName:"ipAddress" type:"string"` // The current state of the customer gateway (pending | available | deleting // | deleted). @@ -9265,42 +9747,19 @@ type metadataCustomerGateway struct { SDKShapeTraits bool `type:"structure"` } -// Describes a DHCP configuration option. -type DHCPConfiguration struct { - // The name of a DHCP option. - Key *string `locationName:"key" type:"string"` - - // One or more values for the DHCP option. - Values []*AttributeValue `locationName:"valueSet" locationNameList:"item" type:"list"` - - metadataDHCPConfiguration `json:"-" xml:"-"` -} - -type metadataDHCPConfiguration struct { - SDKShapeTraits bool `type:"structure"` -} - -// Describes a set of DHCP options. -type DHCPOptions struct { - // One or more DHCP options in the set. - DHCPConfigurations []*DHCPConfiguration `locationName:"dhcpConfigurationSet" locationNameList:"item" type:"list"` - - // The ID of the set of DHCP options. - DHCPOptionsID *string `locationName:"dhcpOptionsId" type:"string"` - - // Any tags assigned to the DHCP options set. - Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` - - metadataDHCPOptions `json:"-" xml:"-"` +// String returns the string representation +func (s CustomerGateway) String() string { + return awsutil.Prettify(s) } -type metadataDHCPOptions struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s CustomerGateway) GoString() string { + return s.String() } type DeleteCustomerGatewayInput struct { // The ID of the customer gateway. - CustomerGatewayID *string `locationName:"CustomerGatewayId" type:"string" required:"true"` + CustomerGatewayId *string `type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9315,6 +9774,16 @@ type metadataDeleteCustomerGatewayInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteCustomerGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteCustomerGatewayInput) GoString() string { + return s.String() +} + type DeleteCustomerGatewayOutput struct { metadataDeleteCustomerGatewayOutput `json:"-" xml:"-"` } @@ -9323,9 +9792,19 @@ type metadataDeleteCustomerGatewayOutput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteDHCPOptionsInput struct { +// String returns the string representation +func (s DeleteCustomerGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteCustomerGatewayOutput) GoString() string { + return s.String() +} + +type DeleteDhcpOptionsInput struct { // The ID of the DHCP options set. - DHCPOptionsID *string `locationName:"DhcpOptionsId" type:"string" required:"true"` + DhcpOptionsId *string `type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9333,30 +9812,92 @@ type DeleteDHCPOptionsInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - metadataDeleteDHCPOptionsInput `json:"-" xml:"-"` + metadataDeleteDhcpOptionsInput `json:"-" xml:"-"` } -type metadataDeleteDHCPOptionsInput struct { +type metadataDeleteDhcpOptionsInput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteDHCPOptionsOutput struct { - metadataDeleteDHCPOptionsOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DeleteDhcpOptionsInput) String() string { + return awsutil.Prettify(s) } -type metadataDeleteDHCPOptionsOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s DeleteDhcpOptionsInput) GoString() string { + return s.String() } -type DeleteInternetGatewayInput struct { - // Checks whether you have the required permissions for the action, without +type DeleteDhcpOptionsOutput struct { + metadataDeleteDhcpOptionsOutput `json:"-" xml:"-"` +} + +type metadataDeleteDhcpOptionsOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DeleteDhcpOptionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDhcpOptionsOutput) GoString() string { + return s.String() +} + +type DeleteFlowLogsInput struct { + // One or more flow log IDs. + FlowLogIds []*string `locationName:"FlowLogId" locationNameList:"item" type:"list" required:"true"` + + metadataDeleteFlowLogsInput `json:"-" xml:"-"` +} + +type metadataDeleteFlowLogsInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DeleteFlowLogsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteFlowLogsInput) GoString() string { + return s.String() +} + +type DeleteFlowLogsOutput struct { + // Information about the flow logs that could not be deleted successfully. + Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` + + metadataDeleteFlowLogsOutput `json:"-" xml:"-"` +} + +type metadataDeleteFlowLogsOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DeleteFlowLogsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteFlowLogsOutput) GoString() string { + return s.String() +} + +type DeleteInternetGatewayInput struct { + // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the Internet gateway. - InternetGatewayID *string `locationName:"internetGatewayId" type:"string" required:"true"` + InternetGatewayId *string `locationName:"internetGatewayId" type:"string" required:"true"` metadataDeleteInternetGatewayInput `json:"-" xml:"-"` } @@ -9365,6 +9906,16 @@ type metadataDeleteInternetGatewayInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteInternetGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteInternetGatewayInput) GoString() string { + return s.String() +} + type DeleteInternetGatewayOutput struct { metadataDeleteInternetGatewayOutput `json:"-" xml:"-"` } @@ -9373,6 +9924,16 @@ type metadataDeleteInternetGatewayOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteInternetGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteInternetGatewayOutput) GoString() string { + return s.String() +} + type DeleteKeyPairInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9390,6 +9951,16 @@ type metadataDeleteKeyPairInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteKeyPairInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteKeyPairInput) GoString() string { + return s.String() +} + type DeleteKeyPairOutput struct { metadataDeleteKeyPairOutput `json:"-" xml:"-"` } @@ -9398,7 +9969,17 @@ type metadataDeleteKeyPairOutput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteNetworkACLEntryInput struct { +// String returns the string representation +func (s DeleteKeyPairOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteKeyPairOutput) GoString() string { + return s.String() +} + +type DeleteNetworkAclEntryInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -9409,27 +9990,47 @@ type DeleteNetworkACLEntryInput struct { Egress *bool `locationName:"egress" type:"boolean" required:"true"` // The ID of the network ACL. - NetworkACLID *string `locationName:"networkAclId" type:"string" required:"true"` + NetworkAclId *string `locationName:"networkAclId" type:"string" required:"true"` // The rule number of the entry to delete. RuleNumber *int64 `locationName:"ruleNumber" type:"integer" required:"true"` - metadataDeleteNetworkACLEntryInput `json:"-" xml:"-"` + metadataDeleteNetworkAclEntryInput `json:"-" xml:"-"` } -type metadataDeleteNetworkACLEntryInput struct { +type metadataDeleteNetworkAclEntryInput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteNetworkACLEntryOutput struct { - metadataDeleteNetworkACLEntryOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DeleteNetworkAclEntryInput) String() string { + return awsutil.Prettify(s) } -type metadataDeleteNetworkACLEntryOutput struct { +// GoString returns the string representation +func (s DeleteNetworkAclEntryInput) GoString() string { + return s.String() +} + +type DeleteNetworkAclEntryOutput struct { + metadataDeleteNetworkAclEntryOutput `json:"-" xml:"-"` +} + +type metadataDeleteNetworkAclEntryOutput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteNetworkACLInput struct { +// String returns the string representation +func (s DeleteNetworkAclEntryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkAclEntryOutput) GoString() string { + return s.String() +} + +type DeleteNetworkAclInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -9437,23 +10038,43 @@ type DeleteNetworkACLInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the network ACL. - NetworkACLID *string `locationName:"networkAclId" type:"string" required:"true"` + NetworkAclId *string `locationName:"networkAclId" type:"string" required:"true"` - metadataDeleteNetworkACLInput `json:"-" xml:"-"` + metadataDeleteNetworkAclInput `json:"-" xml:"-"` } -type metadataDeleteNetworkACLInput struct { +type metadataDeleteNetworkAclInput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteNetworkACLOutput struct { - metadataDeleteNetworkACLOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DeleteNetworkAclInput) String() string { + return awsutil.Prettify(s) } -type metadataDeleteNetworkACLOutput struct { +// GoString returns the string representation +func (s DeleteNetworkAclInput) GoString() string { + return s.String() +} + +type DeleteNetworkAclOutput struct { + metadataDeleteNetworkAclOutput `json:"-" xml:"-"` +} + +type metadataDeleteNetworkAclOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteNetworkAclOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkAclOutput) GoString() string { + return s.String() +} + type DeleteNetworkInterfaceInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9462,7 +10083,7 @@ type DeleteNetworkInterfaceInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string" required:"true"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` metadataDeleteNetworkInterfaceInput `json:"-" xml:"-"` } @@ -9471,6 +10092,16 @@ type metadataDeleteNetworkInterfaceInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteNetworkInterfaceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkInterfaceInput) GoString() string { + return s.String() +} + type DeleteNetworkInterfaceOutput struct { metadataDeleteNetworkInterfaceOutput `json:"-" xml:"-"` } @@ -9479,6 +10110,16 @@ type metadataDeleteNetworkInterfaceOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteNetworkInterfaceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkInterfaceOutput) GoString() string { + return s.String() +} + type DeletePlacementGroupInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9496,6 +10137,16 @@ type metadataDeletePlacementGroupInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeletePlacementGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeletePlacementGroupInput) GoString() string { + return s.String() +} + type DeletePlacementGroupOutput struct { metadataDeletePlacementGroupOutput `json:"-" xml:"-"` } @@ -9504,10 +10155,20 @@ type metadataDeletePlacementGroupOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeletePlacementGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeletePlacementGroupOutput) GoString() string { + return s.String() +} + type DeleteRouteInput struct { // The CIDR range for the route. The value you specify must match the CIDR for // the route exactly. - DestinationCIDRBlock *string `locationName:"destinationCidrBlock" type:"string" required:"true"` + DestinationCidrBlock *string `locationName:"destinationCidrBlock" type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9516,7 +10177,7 @@ type DeleteRouteInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the route table. - RouteTableID *string `locationName:"routeTableId" type:"string" required:"true"` + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` metadataDeleteRouteInput `json:"-" xml:"-"` } @@ -9525,6 +10186,16 @@ type metadataDeleteRouteInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteRouteInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRouteInput) GoString() string { + return s.String() +} + type DeleteRouteOutput struct { metadataDeleteRouteOutput `json:"-" xml:"-"` } @@ -9533,6 +10204,16 @@ type metadataDeleteRouteOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteRouteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRouteOutput) GoString() string { + return s.String() +} + type DeleteRouteTableInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9541,7 +10222,7 @@ type DeleteRouteTableInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the route table. - RouteTableID *string `locationName:"routeTableId" type:"string" required:"true"` + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` metadataDeleteRouteTableInput `json:"-" xml:"-"` } @@ -9550,6 +10231,16 @@ type metadataDeleteRouteTableInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteRouteTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRouteTableInput) GoString() string { + return s.String() +} + type DeleteRouteTableOutput struct { metadataDeleteRouteTableOutput `json:"-" xml:"-"` } @@ -9558,6 +10249,16 @@ type metadataDeleteRouteTableOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteRouteTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRouteTableOutput) GoString() string { + return s.String() +} + type DeleteSecurityGroupInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9566,7 +10267,7 @@ type DeleteSecurityGroupInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the security group. Required for a nondefault VPC. - GroupID *string `locationName:"GroupId" type:"string"` + GroupId *string `type:"string"` // [EC2-Classic, default VPC] The name of the security group. You can specify // either the security group name or the security group ID. @@ -9579,6 +10280,16 @@ type metadataDeleteSecurityGroupInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteSecurityGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSecurityGroupInput) GoString() string { + return s.String() +} + type DeleteSecurityGroupOutput struct { metadataDeleteSecurityGroupOutput `json:"-" xml:"-"` } @@ -9587,6 +10298,16 @@ type metadataDeleteSecurityGroupOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteSecurityGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSecurityGroupOutput) GoString() string { + return s.String() +} + type DeleteSnapshotInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9595,7 +10316,7 @@ type DeleteSnapshotInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the EBS snapshot. - SnapshotID *string `locationName:"SnapshotId" type:"string" required:"true"` + SnapshotId *string `type:"string" required:"true"` metadataDeleteSnapshotInput `json:"-" xml:"-"` } @@ -9604,6 +10325,16 @@ type metadataDeleteSnapshotInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSnapshotInput) GoString() string { + return s.String() +} + type DeleteSnapshotOutput struct { metadataDeleteSnapshotOutput `json:"-" xml:"-"` } @@ -9612,6 +10343,16 @@ type metadataDeleteSnapshotOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSnapshotOutput) GoString() string { + return s.String() +} + // Contains the parameters for DeleteSpotDatafeedSubscription. type DeleteSpotDatafeedSubscriptionInput struct { // Checks whether you have the required permissions for the action, without @@ -9627,6 +10368,16 @@ type metadataDeleteSpotDatafeedSubscriptionInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteSpotDatafeedSubscriptionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSpotDatafeedSubscriptionInput) GoString() string { + return s.String() +} + type DeleteSpotDatafeedSubscriptionOutput struct { metadataDeleteSpotDatafeedSubscriptionOutput `json:"-" xml:"-"` } @@ -9635,6 +10386,16 @@ type metadataDeleteSpotDatafeedSubscriptionOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteSpotDatafeedSubscriptionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSpotDatafeedSubscriptionOutput) GoString() string { + return s.String() +} + type DeleteSubnetInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9643,7 +10404,7 @@ type DeleteSubnetInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the subnet. - SubnetID *string `locationName:"SubnetId" type:"string" required:"true"` + SubnetId *string `type:"string" required:"true"` metadataDeleteSubnetInput `json:"-" xml:"-"` } @@ -9652,6 +10413,16 @@ type metadataDeleteSubnetInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteSubnetInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSubnetInput) GoString() string { + return s.String() +} + type DeleteSubnetOutput struct { metadataDeleteSubnetOutput `json:"-" xml:"-"` } @@ -9660,6 +10431,16 @@ type metadataDeleteSubnetOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteSubnetOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSubnetOutput) GoString() string { + return s.String() +} + type DeleteTagsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9683,6 +10464,16 @@ type metadataDeleteTagsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteTagsInput) GoString() string { + return s.String() +} + type DeleteTagsOutput struct { metadataDeleteTagsOutput `json:"-" xml:"-"` } @@ -9691,7 +10482,62 @@ type metadataDeleteTagsOutput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPCEndpointsInput struct { +// String returns the string representation +func (s DeleteTagsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteTagsOutput) GoString() string { + return s.String() +} + +type DeleteVolumeInput struct { + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the volume. + VolumeId *string `type:"string" required:"true"` + + metadataDeleteVolumeInput `json:"-" xml:"-"` +} + +type metadataDeleteVolumeInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DeleteVolumeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVolumeInput) GoString() string { + return s.String() +} + +type DeleteVolumeOutput struct { + metadataDeleteVolumeOutput `json:"-" xml:"-"` +} + +type metadataDeleteVolumeOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DeleteVolumeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVolumeOutput) GoString() string { + return s.String() +} + +type DeleteVpcEndpointsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -9699,27 +10545,47 @@ type DeleteVPCEndpointsInput struct { DryRun *bool `type:"boolean"` // One or more endpoint IDs. - VPCEndpointIDs []*string `locationName:"VpcEndpointId" locationNameList:"item" type:"list" required:"true"` + VpcEndpointIds []*string `locationName:"VpcEndpointId" locationNameList:"item" type:"list" required:"true"` - metadataDeleteVPCEndpointsInput `json:"-" xml:"-"` + metadataDeleteVpcEndpointsInput `json:"-" xml:"-"` } -type metadataDeleteVPCEndpointsInput struct { +type metadataDeleteVpcEndpointsInput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPCEndpointsOutput struct { +// String returns the string representation +func (s DeleteVpcEndpointsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcEndpointsInput) GoString() string { + return s.String() +} + +type DeleteVpcEndpointsOutput struct { // Information about the endpoints that were not successfully deleted. Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` - metadataDeleteVPCEndpointsOutput `json:"-" xml:"-"` + metadataDeleteVpcEndpointsOutput `json:"-" xml:"-"` } -type metadataDeleteVPCEndpointsOutput struct { +type metadataDeleteVpcEndpointsOutput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPCInput struct { +// String returns the string representation +func (s DeleteVpcEndpointsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcEndpointsOutput) GoString() string { + return s.String() +} + +type DeleteVpcInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -9727,24 +10593,44 @@ type DeleteVPCInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the VPC. - VPCID *string `locationName:"VpcId" type:"string" required:"true"` + VpcId *string `type:"string" required:"true"` - metadataDeleteVPCInput `json:"-" xml:"-"` + metadataDeleteVpcInput `json:"-" xml:"-"` } -type metadataDeleteVPCInput struct { +type metadataDeleteVpcInput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPCOutput struct { - metadataDeleteVPCOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DeleteVpcInput) String() string { + return awsutil.Prettify(s) } -type metadataDeleteVPCOutput struct { +// GoString returns the string representation +func (s DeleteVpcInput) GoString() string { + return s.String() +} + +type DeleteVpcOutput struct { + metadataDeleteVpcOutput `json:"-" xml:"-"` +} + +type metadataDeleteVpcOutput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPCPeeringConnectionInput struct { +// String returns the string representation +func (s DeleteVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcOutput) GoString() string { + return s.String() +} + +type DeleteVpcPeeringConnectionInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -9752,27 +10638,47 @@ type DeleteVPCPeeringConnectionInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the VPC peering connection. - VPCPeeringConnectionID *string `locationName:"vpcPeeringConnectionId" type:"string" required:"true"` + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string" required:"true"` - metadataDeleteVPCPeeringConnectionInput `json:"-" xml:"-"` + metadataDeleteVpcPeeringConnectionInput `json:"-" xml:"-"` } -type metadataDeleteVPCPeeringConnectionInput struct { +type metadataDeleteVpcPeeringConnectionInput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPCPeeringConnectionOutput struct { +// String returns the string representation +func (s DeleteVpcPeeringConnectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcPeeringConnectionInput) GoString() string { + return s.String() +} + +type DeleteVpcPeeringConnectionOutput struct { // Returns true if the request succeeds; otherwise, it returns an error. Return *bool `locationName:"return" type:"boolean"` - metadataDeleteVPCPeeringConnectionOutput `json:"-" xml:"-"` + metadataDeleteVpcPeeringConnectionOutput `json:"-" xml:"-"` } -type metadataDeleteVPCPeeringConnectionOutput struct { +type metadataDeleteVpcPeeringConnectionOutput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPNConnectionInput struct { +// String returns the string representation +func (s DeleteVpcPeeringConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcPeeringConnectionOutput) GoString() string { + return s.String() +} + +type DeleteVpnConnectionInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -9780,46 +10686,86 @@ type DeleteVPNConnectionInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the VPN connection. - VPNConnectionID *string `locationName:"VpnConnectionId" type:"string" required:"true"` + VpnConnectionId *string `type:"string" required:"true"` - metadataDeleteVPNConnectionInput `json:"-" xml:"-"` + metadataDeleteVpnConnectionInput `json:"-" xml:"-"` } -type metadataDeleteVPNConnectionInput struct { +type metadataDeleteVpnConnectionInput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPNConnectionOutput struct { - metadataDeleteVPNConnectionOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DeleteVpnConnectionInput) String() string { + return awsutil.Prettify(s) } -type metadataDeleteVPNConnectionOutput struct { +// GoString returns the string representation +func (s DeleteVpnConnectionInput) GoString() string { + return s.String() +} + +type DeleteVpnConnectionOutput struct { + metadataDeleteVpnConnectionOutput `json:"-" xml:"-"` +} + +type metadataDeleteVpnConnectionOutput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPNConnectionRouteInput struct { +// String returns the string representation +func (s DeleteVpnConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpnConnectionOutput) GoString() string { + return s.String() +} + +type DeleteVpnConnectionRouteInput struct { // The CIDR block associated with the local subnet of the customer network. - DestinationCIDRBlock *string `locationName:"DestinationCidrBlock" type:"string" required:"true"` + DestinationCidrBlock *string `type:"string" required:"true"` // The ID of the VPN connection. - VPNConnectionID *string `locationName:"VpnConnectionId" type:"string" required:"true"` + VpnConnectionId *string `type:"string" required:"true"` - metadataDeleteVPNConnectionRouteInput `json:"-" xml:"-"` + metadataDeleteVpnConnectionRouteInput `json:"-" xml:"-"` } -type metadataDeleteVPNConnectionRouteInput struct { +type metadataDeleteVpnConnectionRouteInput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPNConnectionRouteOutput struct { - metadataDeleteVPNConnectionRouteOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DeleteVpnConnectionRouteInput) String() string { + return awsutil.Prettify(s) } -type metadataDeleteVPNConnectionRouteOutput struct { +// GoString returns the string representation +func (s DeleteVpnConnectionRouteInput) GoString() string { + return s.String() +} + +type DeleteVpnConnectionRouteOutput struct { + metadataDeleteVpnConnectionRouteOutput `json:"-" xml:"-"` +} + +type metadataDeleteVpnConnectionRouteOutput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPNGatewayInput struct { +// String returns the string representation +func (s DeleteVpnConnectionRouteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpnConnectionRouteOutput) GoString() string { + return s.String() +} + +type DeleteVpnGatewayInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -9827,46 +10773,41 @@ type DeleteVPNGatewayInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the virtual private gateway. - VPNGatewayID *string `locationName:"VpnGatewayId" type:"string" required:"true"` + VpnGatewayId *string `type:"string" required:"true"` - metadataDeleteVPNGatewayInput `json:"-" xml:"-"` + metadataDeleteVpnGatewayInput `json:"-" xml:"-"` } -type metadataDeleteVPNGatewayInput struct { +type metadataDeleteVpnGatewayInput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVPNGatewayOutput struct { - metadataDeleteVPNGatewayOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DeleteVpnGatewayInput) String() string { + return awsutil.Prettify(s) } -type metadataDeleteVPNGatewayOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s DeleteVpnGatewayInput) GoString() string { + return s.String() } -type DeleteVolumeInput struct { - // Checks whether you have the required permissions for the action, without - // actually making the request, and provides an error response. If you have - // the required permissions, the error response is DryRunOperation. Otherwise, - // it is UnauthorizedOperation. - DryRun *bool `locationName:"dryRun" type:"boolean"` - - // The ID of the volume. - VolumeID *string `locationName:"VolumeId" type:"string" required:"true"` - - metadataDeleteVolumeInput `json:"-" xml:"-"` +type DeleteVpnGatewayOutput struct { + metadataDeleteVpnGatewayOutput `json:"-" xml:"-"` } -type metadataDeleteVolumeInput struct { +type metadataDeleteVpnGatewayOutput struct { SDKShapeTraits bool `type:"structure"` } -type DeleteVolumeOutput struct { - metadataDeleteVolumeOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DeleteVpnGatewayOutput) String() string { + return awsutil.Prettify(s) } -type metadataDeleteVolumeOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s DeleteVpnGatewayOutput) GoString() string { + return s.String() } type DeregisterImageInput struct { @@ -9877,7 +10818,7 @@ type DeregisterImageInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the AMI. - ImageID *string `locationName:"ImageId" type:"string" required:"true"` + ImageId *string `type:"string" required:"true"` metadataDeregisterImageInput `json:"-" xml:"-"` } @@ -9886,6 +10827,16 @@ type metadataDeregisterImageInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeregisterImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeregisterImageInput) GoString() string { + return s.String() +} + type DeregisterImageOutput struct { metadataDeregisterImageOutput `json:"-" xml:"-"` } @@ -9894,6 +10845,16 @@ type metadataDeregisterImageOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeregisterImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeregisterImageOutput) GoString() string { + return s.String() +} + type DescribeAccountAttributesInput struct { // One or more account attribute names. AttributeNames []*string `locationName:"attributeName" locationNameList:"attributeName" type:"list"` @@ -9911,6 +10872,16 @@ type metadataDescribeAccountAttributesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAccountAttributesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAccountAttributesInput) GoString() string { + return s.String() +} + type DescribeAccountAttributesOutput struct { // Information about one or more account attributes. AccountAttributes []*AccountAttribute `locationName:"accountAttributeSet" locationNameList:"item" type:"list"` @@ -9922,11 +10893,21 @@ type metadataDescribeAccountAttributesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAccountAttributesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAccountAttributesOutput) GoString() string { + return s.String() +} + type DescribeAddressesInput struct { // [EC2-VPC] One or more allocation IDs. // // Default: Describes all your Elastic IP addresses. - AllocationIDs []*string `locationName:"AllocationId" locationNameList:"AllocationId" type:"list"` + AllocationIds []*string `locationName:"AllocationId" locationNameList:"AllocationId" type:"list"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -9960,7 +10941,7 @@ type DescribeAddressesInput struct { // [EC2-Classic] One or more Elastic IP addresses. // // Default: Describes all your Elastic IP addresses. - PublicIPs []*string `locationName:"PublicIp" locationNameList:"PublicIp" type:"list"` + PublicIps []*string `locationName:"PublicIp" locationNameList:"PublicIp" type:"list"` metadataDescribeAddressesInput `json:"-" xml:"-"` } @@ -9969,6 +10950,16 @@ type metadataDescribeAddressesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAddressesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAddressesInput) GoString() string { + return s.String() +} + type DescribeAddressesOutput struct { // Information about one or more Elastic IP addresses. Addresses []*Address `locationName:"addressesSet" locationNameList:"item" type:"list"` @@ -9980,6 +10971,16 @@ type metadataDescribeAddressesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAddressesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAddressesOutput) GoString() string { + return s.String() +} + type DescribeAvailabilityZonesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10009,6 +11010,16 @@ type metadataDescribeAvailabilityZonesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAvailabilityZonesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAvailabilityZonesInput) GoString() string { + return s.String() +} + type DescribeAvailabilityZonesOutput struct { // Information about one or more Availability Zones. AvailabilityZones []*AvailabilityZone `locationName:"availabilityZoneInfo" locationNameList:"item" type:"list"` @@ -10020,11 +11031,21 @@ type metadataDescribeAvailabilityZonesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeAvailabilityZonesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeAvailabilityZonesOutput) GoString() string { + return s.String() +} + type DescribeBundleTasksInput struct { // One or more bundle task IDs. // // Default: Describes all your bundle tasks. - BundleIDs []*string `locationName:"BundleId" locationNameList:"BundleId" type:"list"` + BundleIds []*string `locationName:"BundleId" locationNameList:"BundleId" type:"list"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10064,6 +11085,16 @@ type metadataDescribeBundleTasksInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeBundleTasksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeBundleTasksInput) GoString() string { + return s.String() +} + type DescribeBundleTasksOutput struct { // Information about one or more bundle tasks. BundleTasks []*BundleTask `locationName:"bundleInstanceTasksSet" locationNameList:"item" type:"list"` @@ -10075,6 +11106,16 @@ type metadataDescribeBundleTasksOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeBundleTasksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeBundleTasksOutput) GoString() string { + return s.String() +} + type DescribeClassicLinkInstancesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10104,7 +11145,7 @@ type DescribeClassicLinkInstancesInput struct { Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` // One or more instance IDs. Must be instances linked to a VPC through ClassicLink. - InstanceIDs []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` // The maximum number of results to return for the request in a single page. // The remaining results of the initial request can be seen by sending another @@ -10126,6 +11167,16 @@ type metadataDescribeClassicLinkInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeClassicLinkInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeClassicLinkInstancesInput) GoString() string { + return s.String() +} + type DescribeClassicLinkInstancesOutput struct { // Information about one or more linked EC2-Classic instances. Instances []*ClassicLinkInstance `locationName:"instancesSet" locationNameList:"item" type:"list"` @@ -10141,9 +11192,19 @@ type metadataDescribeClassicLinkInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeClassicLinkInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeClassicLinkInstancesOutput) GoString() string { + return s.String() +} + type DescribeConversionTasksInput struct { // One or more conversion task IDs. - ConversionTaskIDs []*string `locationName:"conversionTaskId" locationNameList:"item" type:"list"` + ConversionTaskIds []*string `locationName:"conversionTaskId" locationNameList:"item" type:"list"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10161,6 +11222,16 @@ type metadataDescribeConversionTasksInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeConversionTasksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeConversionTasksInput) GoString() string { + return s.String() +} + type DescribeConversionTasksOutput struct { // Information about the conversion tasks. ConversionTasks []*ConversionTask `locationName:"conversionTasks" locationNameList:"item" type:"list"` @@ -10172,11 +11243,21 @@ type metadataDescribeConversionTasksOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeConversionTasksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeConversionTasksOutput) GoString() string { + return s.String() +} + type DescribeCustomerGatewaysInput struct { // One or more customer gateway IDs. // // Default: Describes all your customer gateways. - CustomerGatewayIDs []*string `locationName:"CustomerGatewayId" locationNameList:"CustomerGatewayId" type:"list"` + CustomerGatewayIds []*string `locationName:"CustomerGatewayId" locationNameList:"CustomerGatewayId" type:"list"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10220,6 +11301,16 @@ type metadataDescribeCustomerGatewaysInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeCustomerGatewaysInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeCustomerGatewaysInput) GoString() string { + return s.String() +} + type DescribeCustomerGatewaysOutput struct { // Information about one or more customer gateways. CustomerGateways []*CustomerGateway `locationName:"customerGatewaySet" locationNameList:"item" type:"list"` @@ -10231,11 +11322,21 @@ type metadataDescribeCustomerGatewaysOutput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeDHCPOptionsInput struct { +// String returns the string representation +func (s DescribeCustomerGatewaysOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeCustomerGatewaysOutput) GoString() string { + return s.String() +} + +type DescribeDhcpOptionsInput struct { // The IDs of one or more DHCP options sets. // // Default: Describes all your DHCP options sets. - DHCPOptionsIDs []*string `locationName:"DhcpOptionsId" locationNameList:"DhcpOptionsId" type:"list"` + DhcpOptionsIds []*string `locationName:"DhcpOptionsId" locationNameList:"DhcpOptionsId" type:"list"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10264,27 +11365,47 @@ type DescribeDHCPOptionsInput struct { // independent of the tag-key filter. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - metadataDescribeDHCPOptionsInput `json:"-" xml:"-"` + metadataDescribeDhcpOptionsInput `json:"-" xml:"-"` } -type metadataDescribeDHCPOptionsInput struct { +type metadataDescribeDhcpOptionsInput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeDHCPOptionsOutput struct { +// String returns the string representation +func (s DescribeDhcpOptionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeDhcpOptionsInput) GoString() string { + return s.String() +} + +type DescribeDhcpOptionsOutput struct { // Information about one or more DHCP options sets. - DHCPOptions []*DHCPOptions `locationName:"dhcpOptionsSet" locationNameList:"item" type:"list"` + DhcpOptions []*DhcpOptions `locationName:"dhcpOptionsSet" locationNameList:"item" type:"list"` - metadataDescribeDHCPOptionsOutput `json:"-" xml:"-"` + metadataDescribeDhcpOptionsOutput `json:"-" xml:"-"` } -type metadataDescribeDHCPOptionsOutput struct { +type metadataDescribeDhcpOptionsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeDhcpOptionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeDhcpOptionsOutput) GoString() string { + return s.String() +} + type DescribeExportTasksInput struct { // One or more export task IDs. - ExportTaskIDs []*string `locationName:"exportTaskId" locationNameList:"ExportTaskId" type:"list"` + ExportTaskIds []*string `locationName:"exportTaskId" locationNameList:"ExportTaskId" type:"list"` metadataDescribeExportTasksInput `json:"-" xml:"-"` } @@ -10293,6 +11414,16 @@ type metadataDescribeExportTasksInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeExportTasksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeExportTasksInput) GoString() string { + return s.String() +} + type DescribeExportTasksOutput struct { // Information about the export tasks. ExportTasks []*ExportTask `locationName:"exportTaskSet" locationNameList:"item" type:"list"` @@ -10304,13 +11435,92 @@ type metadataDescribeExportTasksOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeExportTasksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeExportTasksOutput) GoString() string { + return s.String() +} + +type DescribeFlowLogsInput struct { + // One or more filters. + // + // deliver-log-status - The status of the logs delivery (SUCCESS | FAILED). + // + // flow-log-id - The ID of the flow log. + // + // log-group-name - The name of the log group. + // + // resource-id - The ID of the VPC, subnet, or network interface. + // + // traffic-type - The type of traffic (ACCEPT | REJECT | ALL) + Filter []*Filter `locationNameList:"Filter" type:"list"` + + // One or more flow log IDs. + FlowLogIds []*string `locationName:"FlowLogId" locationNameList:"item" type:"list"` + + // The maximum number of results to return for the request in a single page. + // The remaining results can be seen by sending another request with the returned + // NextToken value. This value can be between 5 and 1000; if MaxResults is given + // a value larger than 1000, only 1000 results are returned. You cannot specify + // this parameter and the flow log IDs parameter in the same request. + MaxResults *int64 `type:"integer"` + + // The token to retrieve the next page of results. + NextToken *string `type:"string"` + + metadataDescribeFlowLogsInput `json:"-" xml:"-"` +} + +type metadataDescribeFlowLogsInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DescribeFlowLogsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeFlowLogsInput) GoString() string { + return s.String() +} + +type DescribeFlowLogsOutput struct { + // Information about the flow logs. + FlowLogs []*FlowLog `locationName:"flowLogSet" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + metadataDescribeFlowLogsOutput `json:"-" xml:"-"` +} + +type metadataDescribeFlowLogsOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DescribeFlowLogsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeFlowLogsOutput) GoString() string { + return s.String() +} + type DescribeImageAttributeInput struct { // The AMI attribute. // // Note: Depending on your account privileges, the blockDeviceMapping attribute // may return a Client.AuthFailure error. If this happens, use DescribeImages // to get information about the block device mapping for the AMI. - Attribute *string `type:"string" required:"true"` + Attribute *string `type:"string" required:"true" enum:"ImageAttributeName"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10319,7 +11529,7 @@ type DescribeImageAttributeInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the AMI. - ImageID *string `locationName:"ImageId" type:"string" required:"true"` + ImageId *string `type:"string" required:"true"` metadataDescribeImageAttributeInput `json:"-" xml:"-"` } @@ -10328,6 +11538,16 @@ type metadataDescribeImageAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeImageAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImageAttributeInput) GoString() string { + return s.String() +} + // Describes an image attribute. type DescribeImageAttributeOutput struct { // One or more block device mapping entries. @@ -10337,10 +11557,10 @@ type DescribeImageAttributeOutput struct { Description *AttributeValue `locationName:"description" type:"structure"` // The ID of the AMI. - ImageID *string `locationName:"imageId" type:"string"` + ImageId *string `locationName:"imageId" type:"string"` // The kernel ID. - KernelID *AttributeValue `locationName:"kernel" type:"structure"` + KernelId *AttributeValue `locationName:"kernel" type:"structure"` // One or more launch permissions. LaunchPermissions []*LaunchPermission `locationName:"launchPermission" locationNameList:"item" type:"list"` @@ -10349,10 +11569,10 @@ type DescribeImageAttributeOutput struct { ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` // The RAM disk ID. - RAMDiskID *AttributeValue `locationName:"ramdisk" type:"structure"` + RamdiskId *AttributeValue `locationName:"ramdisk" type:"structure"` // The value to use for a resource attribute. - SRIOVNetSupport *AttributeValue `locationName:"sriovNetSupport" type:"structure"` + SriovNetSupport *AttributeValue `locationName:"sriovNetSupport" type:"structure"` metadataDescribeImageAttributeOutput `json:"-" xml:"-"` } @@ -10361,6 +11581,16 @@ type metadataDescribeImageAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeImageAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImageAttributeOutput) GoString() string { + return s.String() +} + type DescribeImagesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10447,7 +11677,7 @@ type DescribeImagesInput struct { // One or more image IDs. // // Default: Describes all images available to you. - ImageIDs []*string `locationName:"ImageId" locationNameList:"ImageId" type:"list"` + ImageIds []*string `locationName:"ImageId" locationNameList:"ImageId" type:"list"` // Filters the images by the owner. Specify an AWS account ID, amazon (owner // is Amazon), aws-marketplace (owner is AWS Marketplace), self (owner is the @@ -10462,6 +11692,16 @@ type metadataDescribeImagesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeImagesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImagesInput) GoString() string { + return s.String() +} + type DescribeImagesOutput struct { // Information about one or more images. Images []*Image `locationName:"imagesSet" locationNameList:"item" type:"list"` @@ -10473,6 +11713,16 @@ type metadataDescribeImagesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeImagesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImagesOutput) GoString() string { + return s.String() +} + type DescribeImportImageTasksInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10484,7 +11734,7 @@ type DescribeImportImageTasksInput struct { Filters []*Filter `locationNameList:"Filter" type:"list"` // A list of import image task IDs. - ImportTaskIDs []*string `locationName:"ImportTaskId" locationNameList:"ImportTaskId" type:"list"` + ImportTaskIds []*string `locationName:"ImportTaskId" locationNameList:"ImportTaskId" type:"list"` // The maximum number of results to return in a single request. MaxResults *int64 `type:"integer"` @@ -10499,6 +11749,16 @@ type metadataDescribeImportImageTasksInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeImportImageTasksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImportImageTasksInput) GoString() string { + return s.String() +} + type DescribeImportImageTasksOutput struct { // A list of zero or more import image tasks that are currently active or were // completed or canceled in the previous 7 days. @@ -10515,6 +11775,16 @@ type metadataDescribeImportImageTasksOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeImportImageTasksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImportImageTasksOutput) GoString() string { + return s.String() +} + type DescribeImportSnapshotTasksInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10526,7 +11796,7 @@ type DescribeImportSnapshotTasksInput struct { Filters []*Filter `locationNameList:"Filter" type:"list"` // A list of import snapshot task IDs. - ImportTaskIDs []*string `locationName:"ImportTaskId" locationNameList:"ImportTaskId" type:"list"` + ImportTaskIds []*string `locationName:"ImportTaskId" locationNameList:"ImportTaskId" type:"list"` // The maximum number of results to return in a single request. MaxResults *int64 `type:"integer"` @@ -10541,6 +11811,16 @@ type metadataDescribeImportSnapshotTasksInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeImportSnapshotTasksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImportSnapshotTasksInput) GoString() string { + return s.String() +} + type DescribeImportSnapshotTasksOutput struct { // A list of zero or more import snapshot tasks that are currently active or // were completed or canceled in the previous 7 days. @@ -10557,9 +11837,19 @@ type metadataDescribeImportSnapshotTasksOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeImportSnapshotTasksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeImportSnapshotTasksOutput) GoString() string { + return s.String() +} + type DescribeInstanceAttributeInput struct { // The instance attribute. - Attribute *string `locationName:"attribute" type:"string" required:"true"` + Attribute *string `locationName:"attribute" type:"string" required:"true" enum:"InstanceAttributeName"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10568,7 +11858,7 @@ type DescribeInstanceAttributeInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string" required:"true"` + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` metadataDescribeInstanceAttributeInput `json:"-" xml:"-"` } @@ -10577,6 +11867,16 @@ type metadataDescribeInstanceAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeInstanceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceAttributeInput) GoString() string { + return s.String() +} + // Describes an instance attribute. type DescribeInstanceAttributeOutput struct { // The block device mapping of the instance. @@ -10584,16 +11884,16 @@ type DescribeInstanceAttributeOutput struct { // If the value is true, you can't terminate the instance through the Amazon // EC2 console, CLI, or API; otherwise, you can. - DisableAPITermination *AttributeBooleanValue `locationName:"disableApiTermination" type:"structure"` + DisableApiTermination *AttributeBooleanValue `locationName:"disableApiTermination" type:"structure"` // Indicates whether the instance is optimized for EBS I/O. - EBSOptimized *AttributeBooleanValue `locationName:"ebsOptimized" type:"structure"` + EbsOptimized *AttributeBooleanValue `locationName:"ebsOptimized" type:"structure"` // The security groups associated with the instance. Groups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // Indicates whether an instance stops or terminates when you initiate shutdown // from the instance (using the operating system command for system shutdown). @@ -10603,25 +11903,25 @@ type DescribeInstanceAttributeOutput struct { InstanceType *AttributeValue `locationName:"instanceType" type:"structure"` // The kernel ID. - KernelID *AttributeValue `locationName:"kernel" type:"structure"` + KernelId *AttributeValue `locationName:"kernel" type:"structure"` // A list of product codes. ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` // The RAM disk ID. - RAMDiskID *AttributeValue `locationName:"ramdisk" type:"structure"` + RamdiskId *AttributeValue `locationName:"ramdisk" type:"structure"` // The name of the root device (for example, /dev/sda1 or /dev/xvda). RootDeviceName *AttributeValue `locationName:"rootDeviceName" type:"structure"` - // The value to use for a resource attribute. - SRIOVNetSupport *AttributeValue `locationName:"sriovNetSupport" type:"structure"` - // Indicates whether source/destination checking is enabled. A value of true // means checking is enabled, and false means checking is disabled. This value // must be false for a NAT instance to perform NAT. SourceDestCheck *AttributeBooleanValue `locationName:"sourceDestCheck" type:"structure"` + // The value to use for a resource attribute. + SriovNetSupport *AttributeValue `locationName:"sriovNetSupport" type:"structure"` + // The Base64-encoded MIME user data. UserData *AttributeValue `locationName:"userData" type:"structure"` @@ -10632,6 +11932,16 @@ type metadataDescribeInstanceAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeInstanceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceAttributeOutput) GoString() string { + return s.String() +} + type DescribeInstanceStatusInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10687,7 +11997,7 @@ type DescribeInstanceStatusInput struct { // Default: Describes all your instances. // // Constraints: Maximum 100 explicitly specified instance IDs. - InstanceIDs []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` // The maximum number of results to return for the request in a single page. // The remaining results of the initial request can be seen by sending another @@ -10707,6 +12017,16 @@ type metadataDescribeInstanceStatusInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeInstanceStatusInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceStatusInput) GoString() string { + return s.String() +} + type DescribeInstanceStatusOutput struct { // One or more instance status descriptions. InstanceStatuses []*InstanceStatus `locationName:"instanceStatusSet" locationNameList:"item" type:"list"` @@ -10722,6 +12042,16 @@ type metadataDescribeInstanceStatusOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeInstanceStatusOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceStatusOutput) GoString() string { + return s.String() +} + type DescribeInstancesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -10957,7 +12287,7 @@ type DescribeInstancesInput struct { // One or more instance IDs. // // Default: Describes all your instances. - InstanceIDs []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` // The maximum number of results to return for the request in a single page. // The remaining results of the initial request can be seen by sending another @@ -10977,6 +12307,16 @@ type metadataDescribeInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstancesInput) GoString() string { + return s.String() +} + type DescribeInstancesOutput struct { // The token to use to retrieve the next page of results. This value is null // when there are no more results to return. @@ -10992,6 +12332,16 @@ type metadataDescribeInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstancesOutput) GoString() string { + return s.String() +} + type DescribeInternetGatewaysInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -11024,7 +12374,7 @@ type DescribeInternetGatewaysInput struct { // One or more Internet gateway IDs. // // Default: Describes all your Internet gateways. - InternetGatewayIDs []*string `locationName:"internetGatewayId" locationNameList:"item" type:"list"` + InternetGatewayIds []*string `locationName:"internetGatewayId" locationNameList:"item" type:"list"` metadataDescribeInternetGatewaysInput `json:"-" xml:"-"` } @@ -11033,6 +12383,16 @@ type metadataDescribeInternetGatewaysInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeInternetGatewaysInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInternetGatewaysInput) GoString() string { + return s.String() +} + type DescribeInternetGatewaysOutput struct { // Information about one or more Internet gateways. InternetGateways []*InternetGateway `locationName:"internetGatewaySet" locationNameList:"item" type:"list"` @@ -11044,6 +12404,16 @@ type metadataDescribeInternetGatewaysOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeInternetGatewaysOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInternetGatewaysOutput) GoString() string { + return s.String() +} + type DescribeKeyPairsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -11070,6 +12440,16 @@ type metadataDescribeKeyPairsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeKeyPairsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeKeyPairsInput) GoString() string { + return s.String() +} + type DescribeKeyPairsOutput struct { // Information about one or more key pairs. KeyPairs []*KeyPairInfo `locationName:"keySet" locationNameList:"item" type:"list"` @@ -11081,6 +12461,16 @@ type metadataDescribeKeyPairsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeKeyPairsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeKeyPairsOutput) GoString() string { + return s.String() +} + type DescribeMovingAddressesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -11105,7 +12495,7 @@ type DescribeMovingAddressesInput struct { NextToken *string `locationName:"nextToken" type:"string"` // One or more Elastic IP addresses. - PublicIPs []*string `locationName:"publicIp" locationNameList:"item" type:"list"` + PublicIps []*string `locationName:"publicIp" locationNameList:"item" type:"list"` metadataDescribeMovingAddressesInput `json:"-" xml:"-"` } @@ -11114,6 +12504,16 @@ type metadataDescribeMovingAddressesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeMovingAddressesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeMovingAddressesInput) GoString() string { + return s.String() +} + type DescribeMovingAddressesOutput struct { // The status for each Elastic IP address. MovingAddressStatuses []*MovingAddressStatus `locationName:"movingAddressStatusSet" locationNameList:"item" type:"list"` @@ -11129,7 +12529,17 @@ type metadataDescribeMovingAddressesOutput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeNetworkACLsInput struct { +// String returns the string representation +func (s DescribeMovingAddressesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeMovingAddressesOutput) GoString() string { + return s.String() +} + +type DescribeNetworkAclsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -11188,29 +12598,49 @@ type DescribeNetworkACLsInput struct { // One or more network ACL IDs. // // Default: Describes all your network ACLs. - NetworkACLIDs []*string `locationName:"NetworkAclId" locationNameList:"item" type:"list"` + NetworkAclIds []*string `locationName:"NetworkAclId" locationNameList:"item" type:"list"` - metadataDescribeNetworkACLsInput `json:"-" xml:"-"` + metadataDescribeNetworkAclsInput `json:"-" xml:"-"` } -type metadataDescribeNetworkACLsInput struct { +type metadataDescribeNetworkAclsInput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeNetworkACLsOutput struct { +// String returns the string representation +func (s DescribeNetworkAclsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkAclsInput) GoString() string { + return s.String() +} + +type DescribeNetworkAclsOutput struct { // Information about one or more network ACLs. - NetworkACLs []*NetworkACL `locationName:"networkAclSet" locationNameList:"item" type:"list"` + NetworkAcls []*NetworkAcl `locationName:"networkAclSet" locationNameList:"item" type:"list"` - metadataDescribeNetworkACLsOutput `json:"-" xml:"-"` + metadataDescribeNetworkAclsOutput `json:"-" xml:"-"` } -type metadataDescribeNetworkACLsOutput struct { +type metadataDescribeNetworkAclsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeNetworkAclsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkAclsOutput) GoString() string { + return s.String() +} + type DescribeNetworkInterfaceAttributeInput struct { // The attribute of the network interface. - Attribute *string `locationName:"attribute" type:"string"` + Attribute *string `locationName:"attribute" type:"string" enum:"NetworkInterfaceAttribute"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -11219,7 +12649,7 @@ type DescribeNetworkInterfaceAttributeInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string" required:"true"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` metadataDescribeNetworkInterfaceAttributeInput `json:"-" xml:"-"` } @@ -11228,6 +12658,16 @@ type metadataDescribeNetworkInterfaceAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeNetworkInterfaceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkInterfaceAttributeInput) GoString() string { + return s.String() +} + type DescribeNetworkInterfaceAttributeOutput struct { // The attachment (if any) of the network interface. Attachment *NetworkInterfaceAttachment `locationName:"attachment" type:"structure"` @@ -11239,7 +12679,7 @@ type DescribeNetworkInterfaceAttributeOutput struct { Groups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` // Indicates whether source/destination checking is enabled. SourceDestCheck *AttributeBooleanValue `locationName:"sourceDestCheck" type:"structure"` @@ -11251,6 +12691,16 @@ type metadataDescribeNetworkInterfaceAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeNetworkInterfaceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkInterfaceAttributeOutput) GoString() string { + return s.String() +} + type DescribeNetworkInterfacesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -11362,7 +12812,7 @@ type DescribeNetworkInterfacesInput struct { // One or more network interface IDs. // // Default: Describes all your network interfaces. - NetworkInterfaceIDs []*string `locationName:"NetworkInterfaceId" locationNameList:"item" type:"list"` + NetworkInterfaceIds []*string `locationName:"NetworkInterfaceId" locationNameList:"item" type:"list"` metadataDescribeNetworkInterfacesInput `json:"-" xml:"-"` } @@ -11371,6 +12821,16 @@ type metadataDescribeNetworkInterfacesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeNetworkInterfacesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkInterfacesInput) GoString() string { + return s.String() +} + type DescribeNetworkInterfacesOutput struct { // Information about one or more network interfaces. NetworkInterfaces []*NetworkInterface `locationName:"networkInterfaceSet" locationNameList:"item" type:"list"` @@ -11382,6 +12842,16 @@ type metadataDescribeNetworkInterfacesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeNetworkInterfacesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkInterfacesOutput) GoString() string { + return s.String() +} + type DescribePlacementGroupsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -11411,6 +12881,16 @@ type metadataDescribePlacementGroupsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribePlacementGroupsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribePlacementGroupsInput) GoString() string { + return s.String() +} + type DescribePlacementGroupsOutput struct { // One or more placement groups. PlacementGroups []*PlacementGroup `locationName:"placementGroupSet" locationNameList:"item" type:"list"` @@ -11422,6 +12902,16 @@ type metadataDescribePlacementGroupsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribePlacementGroupsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribePlacementGroupsOutput) GoString() string { + return s.String() +} + type DescribePrefixListsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -11449,7 +12939,7 @@ type DescribePrefixListsInput struct { NextToken *string `type:"string"` // One or more prefix list IDs. - PrefixListIDs []*string `locationName:"PrefixListId" locationNameList:"item" type:"list"` + PrefixListIds []*string `locationName:"PrefixListId" locationNameList:"item" type:"list"` metadataDescribePrefixListsInput `json:"-" xml:"-"` } @@ -11458,6 +12948,16 @@ type metadataDescribePrefixListsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribePrefixListsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribePrefixListsInput) GoString() string { + return s.String() +} + type DescribePrefixListsOutput struct { // The token to use when requesting the next set of items. If there are no additional // items to return, the string is empty. @@ -11473,6 +12973,16 @@ type metadataDescribePrefixListsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribePrefixListsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribePrefixListsOutput) GoString() string { + return s.String() +} + type DescribeRegionsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -11497,6 +13007,16 @@ type metadataDescribeRegionsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeRegionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRegionsInput) GoString() string { + return s.String() +} + type DescribeRegionsOutput struct { // Information about one or more regions. Regions []*Region `locationName:"regionInfo" locationNameList:"item" type:"list"` @@ -11508,6 +13028,16 @@ type metadataDescribeRegionsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeRegionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRegionsOutput) GoString() string { + return s.String() +} + type DescribeReservedInstancesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -11523,7 +13053,7 @@ type DescribeReservedInstancesInput struct { // duration - The duration of the Reserved Instance (one year or three years), // in seconds (31536000 | 94608000). // - // end - The time when the Reserved Instance expires (for example, 2014-08-07T11:54:42.000Z). + // end - The time when the Reserved Instance expires (for example, 2015-08-07T11:54:42.000Z). // // fixed-price - The purchase price of the Reserved Instance (for example, // 9800.0). @@ -11531,8 +13061,15 @@ type DescribeReservedInstancesInput struct { // instance-type - The instance type on which the Reserved Instance can be // used. // - // product-description - The product description of the Reserved Instance - // (Linux/UNIX | Linux/UNIX (Amazon VPC) | Windows | Windows (Amazon VPC)). + // product-description - The Reserved Instance product platform description. + // Instances that include (Amazon VPC) in the product platform description will + // only be displayed to EC2-Classic account holders and are for use with Amazon + // VPC. (Linux/UNIX | Linux/UNIX (Amazon VPC) | SUSE Linux | SUSE Linux (Amazon + // VPC) | Red Hat Enterprise Linux | Red Hat Enterprise Linux (Amazon VPC) | + // Windows | Windows (Amazon VPC) | Windows with SQL Server Standard | Windows + // with SQL Server Standard (Amazon VPC) | Windows with SQL Server Web | Windows + // with SQL Server Web (Amazon VPC) | Windows with SQL Server Enterprise | Windows + // with SQL Server Enterprise (Amazon VPC)). // // reserved-instances-id - The ID of the Reserved Instance. // @@ -11561,13 +13098,13 @@ type DescribeReservedInstancesInput struct { // The Reserved Instance offering type. If you are using tools that predate // the 2011-11-01 API version, you only have access to the Medium Utilization // Reserved Instance offering type. - OfferingType *string `locationName:"offeringType" type:"string"` + OfferingType *string `locationName:"offeringType" type:"string" enum:"OfferingTypeValues"` // One or more Reserved Instance IDs. // // Default: Describes all your Reserved Instances, or only those otherwise // specified. - ReservedInstancesIDs []*string `locationName:"ReservedInstancesId" locationNameList:"ReservedInstancesId" type:"list"` + ReservedInstancesIds []*string `locationName:"ReservedInstancesId" locationNameList:"ReservedInstancesId" type:"list"` metadataDescribeReservedInstancesInput `json:"-" xml:"-"` } @@ -11576,6 +13113,16 @@ type metadataDescribeReservedInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeReservedInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesInput) GoString() string { + return s.String() +} + type DescribeReservedInstancesListingsInput struct { // One or more filters. // @@ -11590,10 +13137,10 @@ type DescribeReservedInstancesListingsInput struct { Filters []*Filter `locationName:"filters" locationNameList:"Filter" type:"list"` // One or more Reserved Instance IDs. - ReservedInstancesID *string `locationName:"reservedInstancesId" type:"string"` + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` // One or more Reserved Instance Listing IDs. - ReservedInstancesListingID *string `locationName:"reservedInstancesListingId" type:"string"` + ReservedInstancesListingId *string `locationName:"reservedInstancesListingId" type:"string"` metadataDescribeReservedInstancesListingsInput `json:"-" xml:"-"` } @@ -11602,6 +13149,16 @@ type metadataDescribeReservedInstancesListingsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeReservedInstancesListingsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesListingsInput) GoString() string { + return s.String() +} + type DescribeReservedInstancesListingsOutput struct { // Information about the Reserved Instance listing. ReservedInstancesListings []*ReservedInstancesListing `locationName:"reservedInstancesListingsSet" locationNameList:"item" type:"list"` @@ -11613,6 +13170,16 @@ type metadataDescribeReservedInstancesListingsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeReservedInstancesListingsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesListingsOutput) GoString() string { + return s.String() +} + type DescribeReservedInstancesModificationsInput struct { // One or more filters. // @@ -11654,7 +13221,7 @@ type DescribeReservedInstancesModificationsInput struct { NextToken *string `locationName:"nextToken" type:"string"` // IDs for the submitted modification request. - ReservedInstancesModificationIDs []*string `locationName:"ReservedInstancesModificationId" locationNameList:"ReservedInstancesModificationId" type:"list"` + ReservedInstancesModificationIds []*string `locationName:"ReservedInstancesModificationId" locationNameList:"ReservedInstancesModificationId" type:"list"` metadataDescribeReservedInstancesModificationsInput `json:"-" xml:"-"` } @@ -11663,6 +13230,16 @@ type metadataDescribeReservedInstancesModificationsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeReservedInstancesModificationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesModificationsInput) GoString() string { + return s.String() +} + type DescribeReservedInstancesModificationsOutput struct { // The token to use to retrieve the next page of results. This value is null // when there are no more results to return. @@ -11678,6 +13255,16 @@ type metadataDescribeReservedInstancesModificationsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeReservedInstancesModificationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesModificationsOutput) GoString() string { + return s.String() +} + type DescribeReservedInstancesOfferingsInput struct { // The Availability Zone in which the Reserved Instance can be used. AvailabilityZone *string `type:"string"` @@ -11706,8 +13293,15 @@ type DescribeReservedInstancesOfferingsInput struct { // When this filter is not used, which is the default behavior, all offerings // from AWS and Reserved Instance Marketplace are listed. // - // product-description - The description of the Reserved Instance (Linux/UNIX - // | Linux/UNIX (Amazon VPC) | Windows | Windows (Amazon VPC)). + // product-description - The Reserved Instance product platform description. + // Instances that include (Amazon VPC) in the product platform description will + // only be displayed to EC2-Classic account holders and are for use with Amazon + // VPC. (Linux/UNIX | Linux/UNIX (Amazon VPC) | SUSE Linux | SUSE Linux (Amazon + // VPC) | Red Hat Enterprise Linux | Red Hat Enterprise Linux (Amazon VPC) | + // Windows | Windows (Amazon VPC) | Windows with SQL Server Standard | Windows + // with SQL Server Standard (Amazon VPC) | Windows with SQL Server Web | Windows + // with SQL Server Web (Amazon VPC) | Windows with SQL Server Enterprise | Windows + // with SQL Server Enterprise (Amazon VPC)) // // reserved-instances-offering-id - The Reserved Instances offering ID. // @@ -11723,12 +13317,12 @@ type DescribeReservedInstancesOfferingsInput struct { // VPC. // // Default: default - InstanceTenancy *string `locationName:"instanceTenancy" type:"string"` + InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` // The instance type on which the Reserved Instance can be used. For more information, // see Instance Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) // in the Amazon Elastic Compute Cloud User Guide. - InstanceType *string `type:"string"` + InstanceType *string `type:"string" enum:"InstanceType"` // The maximum duration (in seconds) to filter when searching for offerings. // @@ -11758,14 +13352,14 @@ type DescribeReservedInstancesOfferingsInput struct { // The Reserved Instance offering type. If you are using tools that predate // the 2011-11-01 API version, you only have access to the Medium Utilization // Reserved Instance offering type. - OfferingType *string `locationName:"offeringType" type:"string"` + OfferingType *string `locationName:"offeringType" type:"string" enum:"OfferingTypeValues"` - // The Reserved Instance description. Instances that include (Amazon VPC) in - // the description are for use with Amazon VPC. - ProductDescription *string `type:"string"` + // The Reserved Instance product platform description. Instances that include + // (Amazon VPC) in the description are for use with Amazon VPC. + ProductDescription *string `type:"string" enum:"RIProductDescription"` // One or more Reserved Instances offering IDs. - ReservedInstancesOfferingIDs []*string `locationName:"ReservedInstancesOfferingId" type:"list"` + ReservedInstancesOfferingIds []*string `locationName:"ReservedInstancesOfferingId" type:"list"` metadataDescribeReservedInstancesOfferingsInput `json:"-" xml:"-"` } @@ -11774,6 +13368,16 @@ type metadataDescribeReservedInstancesOfferingsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeReservedInstancesOfferingsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesOfferingsInput) GoString() string { + return s.String() +} + type DescribeReservedInstancesOfferingsOutput struct { // The token to use to retrieve the next page of results. This value is null // when there are no more results to return. @@ -11789,6 +13393,16 @@ type metadataDescribeReservedInstancesOfferingsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeReservedInstancesOfferingsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesOfferingsOutput) GoString() string { + return s.String() +} + type DescribeReservedInstancesOutput struct { // A list of Reserved Instances. ReservedInstances []*ReservedInstances `locationName:"reservedInstancesSet" locationNameList:"item" type:"list"` @@ -11800,6 +13414,16 @@ type metadataDescribeReservedInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeReservedInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeReservedInstancesOutput) GoString() string { + return s.String() +} + type DescribeRouteTablesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -11865,7 +13489,7 @@ type DescribeRouteTablesInput struct { // One or more route table IDs. // // Default: Describes all your route tables. - RouteTableIDs []*string `locationName:"RouteTableId" locationNameList:"item" type:"list"` + RouteTableIds []*string `locationName:"RouteTableId" locationNameList:"item" type:"list"` metadataDescribeRouteTablesInput `json:"-" xml:"-"` } @@ -11874,6 +13498,16 @@ type metadataDescribeRouteTablesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeRouteTablesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRouteTablesInput) GoString() string { + return s.String() +} + type DescribeRouteTablesOutput struct { // Information about one or more route tables. RouteTables []*RouteTable `locationName:"routeTableSet" locationNameList:"item" type:"list"` @@ -11885,14 +13519,26 @@ type metadataDescribeRouteTablesOutput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeSecurityGroupsInput struct { - // Checks whether you have the required permissions for the action, without - // actually making the request, and provides an error response. If you have +// String returns the string representation +func (s DescribeRouteTablesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRouteTablesOutput) GoString() string { + return s.String() +} + +type DescribeSecurityGroupsInput struct { + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // One or more filters. + // One or more filters. If using multiple filters for rules, the results include + // security groups for which any combination of rules - not necessarily a single + // rule - match all filters. // // description - The description of the security group. // @@ -11936,7 +13582,7 @@ type DescribeSecurityGroupsInput struct { // VPC. // // Default: Describes all your security groups. - GroupIDs []*string `locationName:"GroupId" locationNameList:"groupId" type:"list"` + GroupIds []*string `locationName:"GroupId" locationNameList:"groupId" type:"list"` // [EC2-Classic and default VPC only] One or more security group names. You // can specify either the security group name or the security group ID. For @@ -11953,6 +13599,16 @@ type metadataDescribeSecurityGroupsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSecurityGroupsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSecurityGroupsInput) GoString() string { + return s.String() +} + type DescribeSecurityGroupsOutput struct { // Information about one or more security groups. SecurityGroups []*SecurityGroup `locationName:"securityGroupInfo" locationNameList:"item" type:"list"` @@ -11964,9 +13620,19 @@ type metadataDescribeSecurityGroupsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSecurityGroupsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSecurityGroupsOutput) GoString() string { + return s.String() +} + type DescribeSnapshotAttributeInput struct { // The snapshot attribute you would like to view. - Attribute *string `type:"string" required:"true"` + Attribute *string `type:"string" required:"true" enum:"SnapshotAttributeName"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -11975,7 +13641,7 @@ type DescribeSnapshotAttributeInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the EBS snapshot. - SnapshotID *string `locationName:"SnapshotId" type:"string" required:"true"` + SnapshotId *string `type:"string" required:"true"` metadataDescribeSnapshotAttributeInput `json:"-" xml:"-"` } @@ -11984,6 +13650,16 @@ type metadataDescribeSnapshotAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSnapshotAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSnapshotAttributeInput) GoString() string { + return s.String() +} + type DescribeSnapshotAttributeOutput struct { // A list of permissions for creating volumes from the snapshot. CreateVolumePermissions []*CreateVolumePermission `locationName:"createVolumePermission" locationNameList:"item" type:"list"` @@ -11992,7 +13668,7 @@ type DescribeSnapshotAttributeOutput struct { ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` // The ID of the EBS snapshot. - SnapshotID *string `locationName:"snapshotId" type:"string"` + SnapshotId *string `locationName:"snapshotId" type:"string"` metadataDescribeSnapshotAttributeOutput `json:"-" xml:"-"` } @@ -12001,6 +13677,16 @@ type metadataDescribeSnapshotAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSnapshotAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSnapshotAttributeOutput) GoString() string { + return s.String() +} + type DescribeSnapshotsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -12063,15 +13749,15 @@ type DescribeSnapshotsInput struct { // Returns the snapshots owned by the specified owner. Multiple owners can be // specified. - OwnerIDs []*string `locationName:"Owner" locationNameList:"Owner" type:"list"` + OwnerIds []*string `locationName:"Owner" locationNameList:"Owner" type:"list"` // One or more AWS accounts IDs that can create volumes from the snapshot. - RestorableByUserIDs []*string `locationName:"RestorableBy" type:"list"` + RestorableByUserIds []*string `locationName:"RestorableBy" type:"list"` // One or more snapshot IDs. // // Default: Describes snapshots for which you have launch permissions. - SnapshotIDs []*string `locationName:"SnapshotId" locationNameList:"SnapshotId" type:"list"` + SnapshotIds []*string `locationName:"SnapshotId" locationNameList:"SnapshotId" type:"list"` metadataDescribeSnapshotsInput `json:"-" xml:"-"` } @@ -12080,6 +13766,16 @@ type metadataDescribeSnapshotsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSnapshotsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSnapshotsInput) GoString() string { + return s.String() +} + type DescribeSnapshotsOutput struct { // The NextToken value to include in a future DescribeSnapshots request. When // the results of a DescribeSnapshots request exceed MaxResults, this value @@ -12097,6 +13793,16 @@ type metadataDescribeSnapshotsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSnapshotsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSnapshotsOutput) GoString() string { + return s.String() +} + // Contains the parameters for DescribeSpotDatafeedSubscription. type DescribeSpotDatafeedSubscriptionInput struct { // Checks whether you have the required permissions for the action, without @@ -12112,9 +13818,19 @@ type metadataDescribeSpotDatafeedSubscriptionInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotDatafeedSubscriptionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotDatafeedSubscriptionInput) GoString() string { + return s.String() +} + // Contains the output of DescribeSpotDatafeedSubscription. type DescribeSpotDatafeedSubscriptionOutput struct { - // The Spot Instance data feed subscription. + // The Spot instance data feed subscription. SpotDatafeedSubscription *SpotDatafeedSubscription `locationName:"spotDatafeedSubscription" type:"structure"` metadataDescribeSpotDatafeedSubscriptionOutput `json:"-" xml:"-"` @@ -12124,6 +13840,16 @@ type metadataDescribeSpotDatafeedSubscriptionOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotDatafeedSubscriptionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotDatafeedSubscriptionOutput) GoString() string { + return s.String() +} + // Contains the parameters for DescribeSpotFleetInstances. type DescribeSpotFleetInstancesInput struct { // Checks whether you have the required permissions for the action, without @@ -12141,7 +13867,7 @@ type DescribeSpotFleetInstancesInput struct { NextToken *string `locationName:"nextToken" type:"string"` // The ID of the Spot fleet request. - SpotFleetRequestID *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` metadataDescribeSpotFleetInstancesInput `json:"-" xml:"-"` } @@ -12150,6 +13876,16 @@ type metadataDescribeSpotFleetInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotFleetInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetInstancesInput) GoString() string { + return s.String() +} + // Contains the output of DescribeSpotFleetInstances. type DescribeSpotFleetInstancesOutput struct { // The running instances. Note that this list is refreshed periodically and @@ -12161,7 +13897,7 @@ type DescribeSpotFleetInstancesOutput struct { NextToken *string `locationName:"nextToken" type:"string"` // The ID of the Spot fleet request. - SpotFleetRequestID *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` metadataDescribeSpotFleetInstancesOutput `json:"-" xml:"-"` } @@ -12170,6 +13906,16 @@ type metadataDescribeSpotFleetInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotFleetInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetInstancesOutput) GoString() string { + return s.String() +} + // Contains the parameters for DescribeSpotFleetRequestHistory. type DescribeSpotFleetRequestHistoryInput struct { // Checks whether you have the required permissions for the action, without @@ -12179,7 +13925,7 @@ type DescribeSpotFleetRequestHistoryInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The type of events to describe. By default, all events are described. - EventType *string `locationName:"eventType" type:"string"` + EventType *string `locationName:"eventType" type:"string" enum:"EventType"` // The maximum number of results to return in a single call. Specify a value // between 1 and 1000. The default value is 1000. To retrieve the remaining @@ -12190,7 +13936,7 @@ type DescribeSpotFleetRequestHistoryInput struct { NextToken *string `locationName:"nextToken" type:"string"` // The ID of the Spot fleet request. - SpotFleetRequestID *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` // The starting date and time for the events, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). StartTime *time.Time `locationName:"startTime" type:"timestamp" timestampFormat:"iso8601" required:"true"` @@ -12202,6 +13948,16 @@ type metadataDescribeSpotFleetRequestHistoryInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotFleetRequestHistoryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetRequestHistoryInput) GoString() string { + return s.String() +} + // Contains the output of DescribeSpotFleetRequestHistory. type DescribeSpotFleetRequestHistoryOutput struct { // Information about the events in the history of the Spot fleet request. @@ -12218,7 +13974,7 @@ type DescribeSpotFleetRequestHistoryOutput struct { NextToken *string `locationName:"nextToken" type:"string"` // The ID of the Spot fleet request. - SpotFleetRequestID *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` // The starting date and time for the events, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). StartTime *time.Time `locationName:"startTime" type:"timestamp" timestampFormat:"iso8601" required:"true"` @@ -12230,6 +13986,16 @@ type metadataDescribeSpotFleetRequestHistoryOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotFleetRequestHistoryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetRequestHistoryOutput) GoString() string { + return s.String() +} + // Contains the parameters for DescribeSpotFleetRequests. type DescribeSpotFleetRequestsInput struct { // Checks whether you have the required permissions for the action, without @@ -12247,7 +14013,7 @@ type DescribeSpotFleetRequestsInput struct { NextToken *string `locationName:"nextToken" type:"string"` // The IDs of the Spot fleet requests. - SpotFleetRequestIDs []*string `locationName:"spotFleetRequestId" locationNameList:"item" type:"list"` + SpotFleetRequestIds []*string `locationName:"spotFleetRequestId" locationNameList:"item" type:"list"` metadataDescribeSpotFleetRequestsInput `json:"-" xml:"-"` } @@ -12256,6 +14022,16 @@ type metadataDescribeSpotFleetRequestsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotFleetRequestsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetRequestsInput) GoString() string { + return s.String() +} + // Contains the output of DescribeSpotFleetRequests. type DescribeSpotFleetRequestsOutput struct { // The token required to retrieve the next set of results. This value is null @@ -12272,6 +14048,16 @@ type metadataDescribeSpotFleetRequestsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotFleetRequestsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotFleetRequestsOutput) GoString() string { + return s.String() +} + // Contains the parameters for DescribeSpotInstanceRequests. type DescribeSpotInstanceRequestsInput struct { // Checks whether you have the required permissions for the action, without @@ -12284,7 +14070,7 @@ type DescribeSpotInstanceRequestsInput struct { // // availability-zone-group - The Availability Zone group. // - // create-time - The time stamp when the Spot Instance request was created. + // create-time - The time stamp when the Spot instance request was created. // // fault-code - The fault code related to the request. // @@ -12292,7 +14078,7 @@ type DescribeSpotInstanceRequestsInput struct { // // instance-id - The ID of the instance that fulfilled the request. // - // launch-group - The Spot Instance launch group. + // launch-group - The Spot instance launch group. // // launch.block-device-mapping.delete-on-termination - Indicates whether // the Amazon EBS volume is deleted on instance termination. @@ -12320,7 +14106,7 @@ type DescribeSpotInstanceRequestsInput struct { // launch.key-name - The name of the key pair the instance launched with. // // launch.monitoring-enabled - Whether monitoring is enabled for the Spot - // Instance. + // instance. // // launch.ramdisk-id - The RAM disk ID. // @@ -12351,21 +14137,21 @@ type DescribeSpotInstanceRequestsInput struct { // product-description - The product description associated with the instance // (Linux/UNIX | Windows). // - // spot-instance-request-id - The Spot Instance request ID. + // spot-instance-request-id - The Spot instance request ID. // - // spot-price - The maximum hourly price for any Spot Instance launched to + // spot-price - The maximum hourly price for any Spot instance launched to // fulfill the request. // - // state - The state of the Spot Instance request (open | active | closed + // state - The state of the Spot instance request (open | active | closed // | cancelled | failed). Spot bid status information can help you track your - // Amazon EC2 Spot Instance requests. For more information, see Spot Bid Status + // Amazon EC2 Spot instance requests. For more information, see Spot Bid Status // (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html) // in the Amazon Elastic Compute Cloud User Guide. // // status-code - The short code describing the most recent evaluation of - // your Spot Instance request. + // your Spot instance request. // - // status-message - The message explaining the status of the Spot Instance + // status-message - The message explaining the status of the Spot instance // request. // // tag:key=value - The key/value combination of a tag assigned to the resource. @@ -12380,7 +14166,7 @@ type DescribeSpotInstanceRequestsInput struct { // tag-value - The value of a tag assigned to the resource. This filter is // independent of the tag-key filter. // - // type - The type of Spot Instance request (one-time | persistent). + // type - The type of Spot instance request (one-time | persistent). // // launched-availability-zone - The Availability Zone in which the bid is // launched. @@ -12390,8 +14176,8 @@ type DescribeSpotInstanceRequestsInput struct { // valid-until - The end date of the request. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // One or more Spot Instance request IDs. - SpotInstanceRequestIDs []*string `locationName:"SpotInstanceRequestId" locationNameList:"SpotInstanceRequestId" type:"list"` + // One or more Spot instance request IDs. + SpotInstanceRequestIds []*string `locationName:"SpotInstanceRequestId" locationNameList:"SpotInstanceRequestId" type:"list"` metadataDescribeSpotInstanceRequestsInput `json:"-" xml:"-"` } @@ -12400,9 +14186,19 @@ type metadataDescribeSpotInstanceRequestsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotInstanceRequestsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotInstanceRequestsInput) GoString() string { + return s.String() +} + // Contains the output of DescribeSpotInstanceRequests. type DescribeSpotInstanceRequestsOutput struct { - // One or more Spot Instance requests. + // One or more Spot instance requests. SpotInstanceRequests []*SpotInstanceRequest `locationName:"spotInstanceRequestSet" locationNameList:"item" type:"list"` metadataDescribeSpotInstanceRequestsOutput `json:"-" xml:"-"` @@ -12412,6 +14208,16 @@ type metadataDescribeSpotInstanceRequestsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotInstanceRequestsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotInstanceRequestsOutput) GoString() string { + return s.String() +} + // Contains the parameters for DescribeSpotPriceHistory. type DescribeSpotPriceHistoryInput struct { // Filters the results by the specified Availability Zone. @@ -12433,14 +14239,14 @@ type DescribeSpotPriceHistoryInput struct { // // instance-type - The type of instance (for example, m1.small). // - // product-description - The product description for the Spot Price (Linux/UNIX + // product-description - The product description for the Spot price (Linux/UNIX // | SUSE Linux | Windows | Linux/UNIX (Amazon VPC) | SUSE Linux (Amazon VPC) // | Windows (Amazon VPC)). // - // spot-price - The Spot Price. The value must match exactly (or use wildcards; + // spot-price - The Spot price. The value must match exactly (or use wildcards; // greater than or less than comparison is not supported). // - // timestamp - The timestamp of the Spot Price history, in UTC format (for + // timestamp - The timestamp of the Spot price history, in UTC format (for // example, YYYY-MM-DDTHH:MM:SSZ). You can use wildcards (* and ?). Greater // than or less than comparison is not supported. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` @@ -12470,13 +14276,23 @@ type metadataDescribeSpotPriceHistoryInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotPriceHistoryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotPriceHistoryInput) GoString() string { + return s.String() +} + // Contains the output of DescribeSpotPriceHistory. type DescribeSpotPriceHistoryOutput struct { // The token required to retrieve the next set of results. This value is null // when there are no more results to return. NextToken *string `locationName:"nextToken" type:"string"` - // The historical Spot Prices. + // The historical Spot prices. SpotPriceHistory []*SpotPrice `locationName:"spotPriceHistorySet" locationNameList:"item" type:"list"` metadataDescribeSpotPriceHistoryOutput `json:"-" xml:"-"` @@ -12486,6 +14302,16 @@ type metadataDescribeSpotPriceHistoryOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSpotPriceHistoryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSpotPriceHistoryOutput) GoString() string { + return s.String() +} + type DescribeSubnetsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -12530,7 +14356,7 @@ type DescribeSubnetsInput struct { // One or more subnet IDs. // // Default: Describes all your subnets. - SubnetIDs []*string `locationName:"SubnetId" locationNameList:"SubnetId" type:"list"` + SubnetIds []*string `locationName:"SubnetId" locationNameList:"SubnetId" type:"list"` metadataDescribeSubnetsInput `json:"-" xml:"-"` } @@ -12539,6 +14365,16 @@ type metadataDescribeSubnetsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSubnetsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSubnetsInput) GoString() string { + return s.String() +} + type DescribeSubnetsOutput struct { // Information about one or more subnets. Subnets []*Subnet `locationName:"subnetSet" locationNameList:"item" type:"list"` @@ -12550,6 +14386,16 @@ type metadataDescribeSubnetsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeSubnetsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeSubnetsOutput) GoString() string { + return s.String() +} + type DescribeTagsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -12588,6 +14434,16 @@ type metadataDescribeTagsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeTagsInput) GoString() string { + return s.String() +} + type DescribeTagsOutput struct { // The token to use to retrieve the next page of results. This value is null // when there are no more results to return.. @@ -12603,189 +14459,177 @@ type metadataDescribeTagsOutput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVPCAttributeInput struct { - // The VPC attribute. - Attribute *string `type:"string"` - - // Checks whether you have the required permissions for the action, without - // actually making the request, and provides an error response. If you have - // the required permissions, the error response is DryRunOperation. Otherwise, - // it is UnauthorizedOperation. - DryRun *bool `locationName:"dryRun" type:"boolean"` - - // The ID of the VPC. - VPCID *string `locationName:"VpcId" type:"string" required:"true"` - - metadataDescribeVPCAttributeInput `json:"-" xml:"-"` -} - -type metadataDescribeVPCAttributeInput struct { - SDKShapeTraits bool `type:"structure"` +// String returns the string representation +func (s DescribeTagsOutput) String() string { + return awsutil.Prettify(s) } -type DescribeVPCAttributeOutput struct { - // Indicates whether the instances launched in the VPC get DNS hostnames. If - // this attribute is true, instances in the VPC get DNS hostnames; otherwise, - // they do not. - EnableDNSHostnames *AttributeBooleanValue `locationName:"enableDnsHostnames" type:"structure"` - - // Indicates whether DNS resolution is enabled for the VPC. If this attribute - // is true, the Amazon DNS server resolves DNS hostnames for your instances - // to their corresponding IP addresses; otherwise, it does not. - EnableDNSSupport *AttributeBooleanValue `locationName:"enableDnsSupport" type:"structure"` - - // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string"` - - metadataDescribeVPCAttributeOutput `json:"-" xml:"-"` +// GoString returns the string representation +func (s DescribeTagsOutput) GoString() string { + return s.String() } -type metadataDescribeVPCAttributeOutput struct { - SDKShapeTraits bool `type:"structure"` -} +type DescribeVolumeAttributeInput struct { + // The instance attribute. + Attribute *string `type:"string" enum:"VolumeAttributeName"` -type DescribeVPCClassicLinkInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // One or more filters. - // - // is-classic-link-enabled - Whether the VPC is enabled for ClassicLink (true - // | false). - // - // tag:key=value - The key/value combination of a tag assigned to the resource. - // - // tag-key - The key of a tag assigned to the resource. This filter is independent - // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" - // and the filter "tag-value=X", you get any resources assigned both the tag - // key Purpose (regardless of what the tag's value is), and the tag value X - // (regardless of what the tag's key is). If you want to list only resources - // where Purpose is X, see the tag:key=value filter. - // - // tag-value - The value of a tag assigned to the resource. This filter is - // independent of the tag-key filter. - Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - - // One or more VPCs for which you want to describe the ClassicLink status. - VPCIDs []*string `locationName:"VpcId" locationNameList:"VpcId" type:"list"` + // The ID of the volume. + VolumeId *string `type:"string" required:"true"` - metadataDescribeVPCClassicLinkInput `json:"-" xml:"-"` + metadataDescribeVolumeAttributeInput `json:"-" xml:"-"` } -type metadataDescribeVPCClassicLinkInput struct { +type metadataDescribeVolumeAttributeInput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVPCClassicLinkOutput struct { - // The ClassicLink status of one or more VPCs. - VPCs []*VPCClassicLink `locationName:"vpcSet" locationNameList:"item" type:"list"` - - metadataDescribeVPCClassicLinkOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DescribeVolumeAttributeInput) String() string { + return awsutil.Prettify(s) } -type metadataDescribeVPCClassicLinkOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s DescribeVolumeAttributeInput) GoString() string { + return s.String() } -type DescribeVPCEndpointServicesInput struct { - // Checks whether you have the required permissions for the action, without - // actually making the request, and provides an error response. If you have - // the required permissions, the error response is DryRunOperation. Otherwise, - // it is UnauthorizedOperation. - DryRun *bool `type:"boolean"` +type DescribeVolumeAttributeOutput struct { + // The state of autoEnableIO attribute. + AutoEnableIO *AttributeBooleanValue `locationName:"autoEnableIO" type:"structure"` - // The maximum number of items to return for this request. The request returns - // a token that you can specify in a subsequent call to get the next set of - // results. - // - // Constraint: If the value is greater than 1000, we return only 1000 items. - MaxResults *int64 `type:"integer"` + // A list of product codes. + ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` - // The token for the next set of items to return. (You received this token from - // a prior call.) - NextToken *string `type:"string"` + // The ID of the volume. + VolumeId *string `locationName:"volumeId" type:"string"` - metadataDescribeVPCEndpointServicesInput `json:"-" xml:"-"` + metadataDescribeVolumeAttributeOutput `json:"-" xml:"-"` } -type metadataDescribeVPCEndpointServicesInput struct { +type metadataDescribeVolumeAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVPCEndpointServicesOutput struct { - // The token to use when requesting the next set of items. If there are no additional - // items to return, the string is empty. - NextToken *string `locationName:"nextToken" type:"string"` - - // A list of supported AWS services. - ServiceNames []*string `locationName:"serviceNameSet" locationNameList:"item" type:"list"` - - metadataDescribeVPCEndpointServicesOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DescribeVolumeAttributeOutput) String() string { + return awsutil.Prettify(s) } -type metadataDescribeVPCEndpointServicesOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s DescribeVolumeAttributeOutput) GoString() string { + return s.String() } -type DescribeVPCEndpointsInput struct { +type DescribeVolumeStatusInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. - DryRun *bool `type:"boolean"` + DryRun *bool `locationName:"dryRun" type:"boolean"` // One or more filters. // - // service-name: The name of the AWS service. + // action.code - The action code for the event (for example, enable-volume-io). // - // vpc-id: The ID of the VPC in which the endpoint resides. + // action.description - A description of the action. // - // vpc-endpoint-id: The ID of the endpoint. + // action.event-id - The event ID associated with the action. // - // vpc-endpoint-state: The state of the endpoint. (pending | available | - // deleting | deleted) + // availability-zone - The Availability Zone of the instance. + // + // event.description - A description of the event. + // + // event.event-id - The event ID. + // + // event.event-type - The event type (for io-enabled: passed | failed; for + // io-performance: io-performance:degraded | io-performance:severely-degraded + // | io-performance:stalled). + // + // event.not-after - The latest end time for the event. + // + // event.not-before - The earliest start time for the event. + // + // volume-status.details-name - The cause for volume-status.status (io-enabled + // | io-performance). + // + // volume-status.details-status - The status of volume-status.details-name + // (for io-enabled: passed | failed; for io-performance: normal | degraded | + // severely-degraded | stalled). + // + // volume-status.status - The status of the volume (ok | impaired | warning + // | insufficient-data). Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of items to return for this request. The request returns - // a token that you can specify in a subsequent call to get the next set of - // results. - // - // Constraint: If the value is greater than 1000, we return only 1000 items. + // The maximum number of volume results returned by DescribeVolumeStatus in + // paginated output. When this parameter is used, the request only returns MaxResults + // results in a single page along with a NextToken response element. The remaining + // results of the initial request can be seen by sending another request with + // the returned NextToken value. This value can be between 5 and 1000; if MaxResults + // is given a value larger than 1000, only 1000 results are returned. If this + // parameter is not used, then DescribeVolumeStatus returns all results. You + // cannot specify this parameter and the volume IDs parameter in the same request. MaxResults *int64 `type:"integer"` - // The token for the next set of items to return. (You received this token from - // a prior call.) + // The NextToken value to include in a future DescribeVolumeStatus request. + // When the results of the request exceed MaxResults, this value can be used + // to retrieve the next page of results. This value is null when there are no + // more results to return. NextToken *string `type:"string"` - // One or more endpoint IDs. - VPCEndpointIDs []*string `locationName:"VpcEndpointId" locationNameList:"item" type:"list"` + // One or more volume IDs. + // + // Default: Describes all your volumes. + VolumeIds []*string `locationName:"VolumeId" locationNameList:"VolumeId" type:"list"` - metadataDescribeVPCEndpointsInput `json:"-" xml:"-"` + metadataDescribeVolumeStatusInput `json:"-" xml:"-"` } -type metadataDescribeVPCEndpointsInput struct { +type metadataDescribeVolumeStatusInput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVPCEndpointsOutput struct { - // The token to use when requesting the next set of items. If there are no additional - // items to return, the string is empty. +// String returns the string representation +func (s DescribeVolumeStatusInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVolumeStatusInput) GoString() string { + return s.String() +} + +type DescribeVolumeStatusOutput struct { + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. NextToken *string `locationName:"nextToken" type:"string"` - // Information about the endpoints. - VPCEndpoints []*VPCEndpoint `locationName:"vpcEndpointSet" locationNameList:"item" type:"list"` + // A list of volumes. + VolumeStatuses []*VolumeStatusItem `locationName:"volumeStatusSet" locationNameList:"item" type:"list"` - metadataDescribeVPCEndpointsOutput `json:"-" xml:"-"` + metadataDescribeVolumeStatusOutput `json:"-" xml:"-"` } -type metadataDescribeVPCEndpointsOutput struct { +type metadataDescribeVolumeStatusOutput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVPCPeeringConnectionsInput struct { +// String returns the string representation +func (s DescribeVolumeStatusOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVolumeStatusOutput) GoString() string { + return s.String() +} + +type DescribeVolumesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -12794,27 +14638,32 @@ type DescribeVPCPeeringConnectionsInput struct { // One or more filters. // - // accepter-vpc-info.cidr-block - The CIDR block of the peer VPC. + // attachment.attach-time - The time stamp when the attachment initiated. // - // accepter-vpc-info.owner-id - The AWS account ID of the owner of the peer - // VPC. + // attachment.delete-on-termination - Whether the volume is deleted on instance + // termination. // - // accepter-vpc-info.vpc-id - The ID of the peer VPC. + // attachment.device - The device name that is exposed to the instance (for + // example, /dev/sda1). // - // expiration-time - The expiration date and time for the VPC peering connection. + // attachment.instance-id - The ID of the instance the volume is attached + // to. // - // requester-vpc-info.cidr-block - The CIDR block of the requester's VPC. + // attachment.status - The attachment state (attaching | attached | detaching + // | detached). // - // requester-vpc-info.owner-id - The AWS account ID of the owner of the requester - // VPC. + // availability-zone - The Availability Zone in which the volume was created. // - // requester-vpc-info.vpc-id - The ID of the requester VPC. + // create-time - The time stamp when the volume was created. // - // status-code - The status of the VPC peering connection (pending-acceptance - // | failed | expired | provisioning | active | deleted | rejected). + // encrypted - The encryption status of the volume. // - // status-message - A message that provides more information about the status - // of the VPC peering connection, if applicable. + // size - The size of the volume, in GiB. + // + // snapshot-id - The snapshot from which the volume was created. + // + // status - The status of the volume (creating | available | in-use | deleting + // | deleted | error). // // tag:key=value - The key/value combination of a tag assigned to the resource. // @@ -12828,162 +14677,139 @@ type DescribeVPCPeeringConnectionsInput struct { // tag-value - The value of a tag assigned to the resource. This filter is // independent of the tag-key filter. // - // vpc-peering-connection-id - The ID of the VPC peering connection. + // volume-id - The volume ID. + // + // volume-type - The Amazon EBS volume type. This can be gp2 for General + // Purpose (SSD) volumes, io1 for Provisioned IOPS (SSD) volumes, or standard + // for Magnetic volumes. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // One or more VPC peering connection IDs. - // - // Default: Describes all your VPC peering connections. - VPCPeeringConnectionIDs []*string `locationName:"VpcPeeringConnectionId" locationNameList:"item" type:"list"` + // The maximum number of volume results returned by DescribeVolumes in paginated + // output. When this parameter is used, DescribeVolumes only returns MaxResults + // results in a single page along with a NextToken response element. The remaining + // results of the initial request can be seen by sending another DescribeVolumes + // request with the returned NextToken value. This value can be between 5 and + // 1000; if MaxResults is given a value larger than 1000, only 1000 results + // are returned. If this parameter is not used, then DescribeVolumes returns + // all results. You cannot specify this parameter and the volume IDs parameter + // in the same request. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The NextToken value returned from a previous paginated DescribeVolumes request + // where MaxResults was used and the results exceeded the value of that parameter. + // Pagination continues from the end of the previous results that returned the + // NextToken value. This value is null when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // One or more volume IDs. + VolumeIds []*string `locationName:"VolumeId" locationNameList:"VolumeId" type:"list"` - metadataDescribeVPCPeeringConnectionsInput `json:"-" xml:"-"` + metadataDescribeVolumesInput `json:"-" xml:"-"` } -type metadataDescribeVPCPeeringConnectionsInput struct { +type metadataDescribeVolumesInput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVPCPeeringConnectionsOutput struct { - // Information about the VPC peering connections. - VPCPeeringConnections []*VPCPeeringConnection `locationName:"vpcPeeringConnectionSet" locationNameList:"item" type:"list"` +// String returns the string representation +func (s DescribeVolumesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVolumesInput) GoString() string { + return s.String() +} + +type DescribeVolumesOutput struct { + // The NextToken value to include in a future DescribeVolumes request. When + // the results of a DescribeVolumes request exceed MaxResults, this value can + // be used to retrieve the next page of results. This value is null when there + // are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about the volumes. + Volumes []*Volume `locationName:"volumeSet" locationNameList:"item" type:"list"` - metadataDescribeVPCPeeringConnectionsOutput `json:"-" xml:"-"` + metadataDescribeVolumesOutput `json:"-" xml:"-"` } -type metadataDescribeVPCPeeringConnectionsOutput struct { +type metadataDescribeVolumesOutput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVPCsInput struct { +// String returns the string representation +func (s DescribeVolumesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVolumesOutput) GoString() string { + return s.String() +} + +type DescribeVpcAttributeInput struct { + // The VPC attribute. + Attribute *string `type:"string" enum:"VpcAttributeName"` + // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // One or more filters. - // - // cidr - The CIDR block of the VPC. The CIDR block you specify must exactly - // match the VPC's CIDR block for information to be returned for the VPC. Must - // contain the slash followed by one or two digits (for example, /28). - // - // dhcp-options-id - The ID of a set of DHCP options. - // - // isDefault - Indicates whether the VPC is the default VPC. - // - // state - The state of the VPC (pending | available). - // - // tag:key=value - The key/value combination of a tag assigned to the resource. - // - // tag-key - The key of a tag assigned to the resource. This filter is independent - // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" - // and the filter "tag-value=X", you get any resources assigned both the tag - // key Purpose (regardless of what the tag's value is), and the tag value X - // (regardless of what the tag's key is). If you want to list only resources - // where Purpose is X, see the tag:key=value filter. - // - // tag-value - The value of a tag assigned to the resource. This filter is - // independent of the tag-key filter. - // - // vpc-id - The ID of the VPC. - Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - - // One or more VPC IDs. - // - // Default: Describes all your VPCs. - VPCIDs []*string `locationName:"VpcId" locationNameList:"VpcId" type:"list"` + // The ID of the VPC. + VpcId *string `type:"string" required:"true"` - metadataDescribeVPCsInput `json:"-" xml:"-"` + metadataDescribeVpcAttributeInput `json:"-" xml:"-"` } -type metadataDescribeVPCsInput struct { +type metadataDescribeVpcAttributeInput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVPCsOutput struct { - // Information about one or more VPCs. - VPCs []*VPC `locationName:"vpcSet" locationNameList:"item" type:"list"` - - metadataDescribeVPCsOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DescribeVpcAttributeInput) String() string { + return awsutil.Prettify(s) } -type metadataDescribeVPCsOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s DescribeVpcAttributeInput) GoString() string { + return s.String() } -type DescribeVPNConnectionsInput struct { - // Checks whether you have the required permissions for the action, without - // actually making the request, and provides an error response. If you have - // the required permissions, the error response is DryRunOperation. Otherwise, - // it is UnauthorizedOperation. - DryRun *bool `locationName:"dryRun" type:"boolean"` +type DescribeVpcAttributeOutput struct { + // Indicates whether the instances launched in the VPC get DNS hostnames. If + // this attribute is true, instances in the VPC get DNS hostnames; otherwise, + // they do not. + EnableDnsHostnames *AttributeBooleanValue `locationName:"enableDnsHostnames" type:"structure"` - // One or more filters. - // - // customer-gateway-configuration - The configuration information for the - // customer gateway. - // - // customer-gateway-id - The ID of a customer gateway associated with the - // VPN connection. - // - // state - The state of the VPN connection (pending | available | deleting - // | deleted). - // - // option.static-routes-only - Indicates whether the connection has static - // routes only. Used for devices that do not support Border Gateway Protocol - // (BGP). - // - // route.destination-cidr-block - The destination CIDR block. This corresponds - // to the subnet used in a customer data center. - // - // bgp-asn - The BGP Autonomous System Number (ASN) associated with a BGP - // device. - // - // tag:key=value - The key/value combination of a tag assigned to the resource. - // - // tag-key - The key of a tag assigned to the resource. This filter is independent - // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" - // and the filter "tag-value=X", you get any resources assigned both the tag - // key Purpose (regardless of what the tag's value is), and the tag value X - // (regardless of what the tag's key is). If you want to list only resources - // where Purpose is X, see the tag:key=value filter. - // - // tag-value - The value of a tag assigned to the resource. This filter is - // independent of the tag-key filter. - // - // type - The type of VPN connection. Currently the only supported type is - // ipsec.1. - // - // vpn-connection-id - The ID of the VPN connection. - // - // vpn-gateway-id - The ID of a virtual private gateway associated with the - // VPN connection. - Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + // Indicates whether DNS resolution is enabled for the VPC. If this attribute + // is true, the Amazon DNS server resolves DNS hostnames for your instances + // to their corresponding IP addresses; otherwise, it does not. + EnableDnsSupport *AttributeBooleanValue `locationName:"enableDnsSupport" type:"structure"` - // One or more VPN connection IDs. - // - // Default: Describes your VPN connections. - VPNConnectionIDs []*string `locationName:"VpnConnectionId" locationNameList:"VpnConnectionId" type:"list"` + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` - metadataDescribeVPNConnectionsInput `json:"-" xml:"-"` + metadataDescribeVpcAttributeOutput `json:"-" xml:"-"` } -type metadataDescribeVPNConnectionsInput struct { +type metadataDescribeVpcAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVPNConnectionsOutput struct { - // Information about one or more VPN connections. - VPNConnections []*VPNConnection `locationName:"vpnConnectionSet" locationNameList:"item" type:"list"` - - metadataDescribeVPNConnectionsOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DescribeVpcAttributeOutput) String() string { + return awsutil.Prettify(s) } -type metadataDescribeVPNConnectionsOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s DescribeVpcAttributeOutput) GoString() string { + return s.String() } -type DescribeVPNGatewaysInput struct { +type DescribeVpcClassicLinkInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -12992,15 +14818,8 @@ type DescribeVPNGatewaysInput struct { // One or more filters. // - // attachment.state - The current state of the attachment between the gateway - // and the VPC (attaching | attached | detaching | detached). - // - // attachment.vpc-id - The ID of an attached VPC. - // - // availability-zone - The Availability Zone for the virtual private gateway. - // - // state - The state of the virtual private gateway (pending | available - // | deleting | deleted). + // is-classic-link-enabled - Whether the VPC is enabled for ClassicLink (true + // | false). // // tag:key=value - The key/value combination of a tag assigned to the resource. // @@ -13013,157 +14832,185 @@ type DescribeVPNGatewaysInput struct { // // tag-value - The value of a tag assigned to the resource. This filter is // independent of the tag-key filter. - // - // type - The type of virtual private gateway. Currently the only supported - // type is ipsec.1. - // - // vpn-gateway-id - The ID of the virtual private gateway. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // One or more virtual private gateway IDs. - // - // Default: Describes all your virtual private gateways. - VPNGatewayIDs []*string `locationName:"VpnGatewayId" locationNameList:"VpnGatewayId" type:"list"` + // One or more VPCs for which you want to describe the ClassicLink status. + VpcIds []*string `locationName:"VpcId" locationNameList:"VpcId" type:"list"` - metadataDescribeVPNGatewaysInput `json:"-" xml:"-"` + metadataDescribeVpcClassicLinkInput `json:"-" xml:"-"` } -type metadataDescribeVPNGatewaysInput struct { +type metadataDescribeVpcClassicLinkInput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVPNGatewaysOutput struct { - // Information about one or more virtual private gateways. - VPNGateways []*VPNGateway `locationName:"vpnGatewaySet" locationNameList:"item" type:"list"` +// String returns the string representation +func (s DescribeVpcClassicLinkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcClassicLinkInput) GoString() string { + return s.String() +} + +type DescribeVpcClassicLinkOutput struct { + // The ClassicLink status of one or more VPCs. + Vpcs []*VpcClassicLink `locationName:"vpcSet" locationNameList:"item" type:"list"` - metadataDescribeVPNGatewaysOutput `json:"-" xml:"-"` + metadataDescribeVpcClassicLinkOutput `json:"-" xml:"-"` } -type metadataDescribeVPNGatewaysOutput struct { +type metadataDescribeVpcClassicLinkOutput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVolumeAttributeInput struct { - // The instance attribute. - Attribute *string `type:"string"` +// String returns the string representation +func (s DescribeVpcClassicLinkOutput) String() string { + return awsutil.Prettify(s) +} +// GoString returns the string representation +func (s DescribeVpcClassicLinkOutput) GoString() string { + return s.String() +} + +type DescribeVpcEndpointServicesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. - DryRun *bool `locationName:"dryRun" type:"boolean"` + DryRun *bool `type:"boolean"` - // The ID of the volume. - VolumeID *string `locationName:"VolumeId" type:"string" required:"true"` + // The maximum number of items to return for this request. The request returns + // a token that you can specify in a subsequent call to get the next set of + // results. + // + // Constraint: If the value is greater than 1000, we return only 1000 items. + MaxResults *int64 `type:"integer"` - metadataDescribeVolumeAttributeInput `json:"-" xml:"-"` + // The token for the next set of items to return. (You received this token from + // a prior call.) + NextToken *string `type:"string"` + + metadataDescribeVpcEndpointServicesInput `json:"-" xml:"-"` } -type metadataDescribeVolumeAttributeInput struct { +type metadataDescribeVpcEndpointServicesInput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVolumeAttributeOutput struct { - // The state of autoEnableIO attribute. - AutoEnableIO *AttributeBooleanValue `locationName:"autoEnableIO" type:"structure"` +// String returns the string representation +func (s DescribeVpcEndpointServicesInput) String() string { + return awsutil.Prettify(s) +} - // A list of product codes. - ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` +// GoString returns the string representation +func (s DescribeVpcEndpointServicesInput) GoString() string { + return s.String() +} - // The ID of the volume. - VolumeID *string `locationName:"volumeId" type:"string"` +type DescribeVpcEndpointServicesOutput struct { + // The token to use when requesting the next set of items. If there are no additional + // items to return, the string is empty. + NextToken *string `locationName:"nextToken" type:"string"` - metadataDescribeVolumeAttributeOutput `json:"-" xml:"-"` + // A list of supported AWS services. + ServiceNames []*string `locationName:"serviceNameSet" locationNameList:"item" type:"list"` + + metadataDescribeVpcEndpointServicesOutput `json:"-" xml:"-"` } -type metadataDescribeVolumeAttributeOutput struct { +type metadataDescribeVpcEndpointServicesOutput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVolumeStatusInput struct { +// String returns the string representation +func (s DescribeVpcEndpointServicesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointServicesOutput) GoString() string { + return s.String() +} + +type DescribeVpcEndpointsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. - DryRun *bool `locationName:"dryRun" type:"boolean"` + DryRun *bool `type:"boolean"` // One or more filters. // - // action.code - The action code for the event (for example, enable-volume-io). - // - // action.description - A description of the action. - // - // action.event-id - The event ID associated with the action. - // - // availability-zone - The Availability Zone of the instance. + // service-name: The name of the AWS service. // - // event.description - A description of the event. + // vpc-id: The ID of the VPC in which the endpoint resides. // - // event.event-id - The event ID. + // vpc-endpoint-id: The ID of the endpoint. // - // event.event-type - The event type (for io-enabled: passed | failed; for - // io-performance: io-performance:degraded | io-performance:severely-degraded - // | io-performance:stalled). - // - // event.not-after - The latest end time for the event. - // - // event.not-before - The earliest start time for the event. - // - // volume-status.details-name - The cause for volume-status.status (io-enabled - // | io-performance). - // - // volume-status.details-status - The status of volume-status.details-name - // (for io-enabled: passed | failed; for io-performance: normal | degraded | - // severely-degraded | stalled). - // - // volume-status.status - The status of the volume (ok | impaired | warning - // | insufficient-data). + // vpc-endpoint-state: The state of the endpoint. (pending | available | + // deleting | deleted) Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of volume results returned by DescribeVolumeStatus in - // paginated output. When this parameter is used, the request only returns MaxResults - // results in a single page along with a NextToken response element. The remaining - // results of the initial request can be seen by sending another request with - // the returned NextToken value. This value can be between 5 and 1000; if MaxResults - // is given a value larger than 1000, only 1000 results are returned. If this - // parameter is not used, then DescribeVolumeStatus returns all results. You - // cannot specify this parameter and the volume IDs parameter in the same request. + // The maximum number of items to return for this request. The request returns + // a token that you can specify in a subsequent call to get the next set of + // results. + // + // Constraint: If the value is greater than 1000, we return only 1000 items. MaxResults *int64 `type:"integer"` - // The NextToken value to include in a future DescribeVolumeStatus request. - // When the results of the request exceed MaxResults, this value can be used - // to retrieve the next page of results. This value is null when there are no - // more results to return. + // The token for the next set of items to return. (You received this token from + // a prior call.) NextToken *string `type:"string"` - // One or more volume IDs. - // - // Default: Describes all your volumes. - VolumeIDs []*string `locationName:"VolumeId" locationNameList:"VolumeId" type:"list"` + // One or more endpoint IDs. + VpcEndpointIds []*string `locationName:"VpcEndpointId" locationNameList:"item" type:"list"` - metadataDescribeVolumeStatusInput `json:"-" xml:"-"` + metadataDescribeVpcEndpointsInput `json:"-" xml:"-"` } -type metadataDescribeVolumeStatusInput struct { +type metadataDescribeVpcEndpointsInput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVolumeStatusOutput struct { - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. +// String returns the string representation +func (s DescribeVpcEndpointsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointsInput) GoString() string { + return s.String() +} + +type DescribeVpcEndpointsOutput struct { + // The token to use when requesting the next set of items. If there are no additional + // items to return, the string is empty. NextToken *string `locationName:"nextToken" type:"string"` - // A list of volumes. - VolumeStatuses []*VolumeStatusItem `locationName:"volumeStatusSet" locationNameList:"item" type:"list"` + // Information about the endpoints. + VpcEndpoints []*VpcEndpoint `locationName:"vpcEndpointSet" locationNameList:"item" type:"list"` - metadataDescribeVolumeStatusOutput `json:"-" xml:"-"` + metadataDescribeVpcEndpointsOutput `json:"-" xml:"-"` } -type metadataDescribeVolumeStatusOutput struct { +type metadataDescribeVpcEndpointsOutput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVolumesInput struct { +// String returns the string representation +func (s DescribeVpcEndpointsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointsOutput) GoString() string { + return s.String() +} + +type DescribeVpcPeeringConnectionsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -13172,32 +15019,27 @@ type DescribeVolumesInput struct { // One or more filters. // - // attachment.attach-time - The time stamp when the attachment initiated. - // - // attachment.delete-on-termination - Whether the volume is deleted on instance - // termination. - // - // attachment.device - The device name that is exposed to the instance (for - // example, /dev/sda1). + // accepter-vpc-info.cidr-block - The CIDR block of the peer VPC. // - // attachment.instance-id - The ID of the instance the volume is attached - // to. + // accepter-vpc-info.owner-id - The AWS account ID of the owner of the peer + // VPC. // - // attachment.status - The attachment state (attaching | attached | detaching - // | detached). + // accepter-vpc-info.vpc-id - The ID of the peer VPC. // - // availability-zone - The Availability Zone in which the volume was created. + // expiration-time - The expiration date and time for the VPC peering connection. // - // create-time - The time stamp when the volume was created. + // requester-vpc-info.cidr-block - The CIDR block of the requester's VPC. // - // encrypted - The encryption status of the volume. + // requester-vpc-info.owner-id - The AWS account ID of the owner of the requester + // VPC. // - // size - The size of the volume, in GiB. + // requester-vpc-info.vpc-id - The ID of the requester VPC. // - // snapshot-id - The snapshot from which the volume was created. + // status-code - The status of the VPC peering connection (pending-acceptance + // | failed | expired | provisioning | active | deleted | rejected). // - // status - The status of the volume (creating | available | in-use | deleting - // | deleted | error). + // status-message - A message that provides more information about the status + // of the VPC peering connection, if applicable. // // tag:key=value - The key/value combination of a tag assigned to the resource. // @@ -13211,172 +15053,448 @@ type DescribeVolumesInput struct { // tag-value - The value of a tag assigned to the resource. This filter is // independent of the tag-key filter. // - // volume-id - The volume ID. - // - // volume-type - The Amazon EBS volume type. This can be gp2 for General - // Purpose (SSD) volumes, io1 for Provisioned IOPS (SSD) volumes, or standard - // for Magnetic volumes. + // vpc-peering-connection-id - The ID of the VPC peering connection. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of volume results returned by DescribeVolumes in paginated - // output. When this parameter is used, DescribeVolumes only returns MaxResults - // results in a single page along with a NextToken response element. The remaining - // results of the initial request can be seen by sending another DescribeVolumes - // request with the returned NextToken value. This value can be between 5 and - // 1000; if MaxResults is given a value larger than 1000, only 1000 results - // are returned. If this parameter is not used, then DescribeVolumes returns - // all results. You cannot specify this parameter and the volume IDs parameter - // in the same request. - MaxResults *int64 `locationName:"maxResults" type:"integer"` - - // The NextToken value returned from a previous paginated DescribeVolumes request - // where MaxResults was used and the results exceeded the value of that parameter. - // Pagination continues from the end of the previous results that returned the - // NextToken value. This value is null when there are no more results to return. - NextToken *string `locationName:"nextToken" type:"string"` - - // One or more volume IDs. - VolumeIDs []*string `locationName:"VolumeId" locationNameList:"VolumeId" type:"list"` + // One or more VPC peering connection IDs. + // + // Default: Describes all your VPC peering connections. + VpcPeeringConnectionIds []*string `locationName:"VpcPeeringConnectionId" locationNameList:"item" type:"list"` - metadataDescribeVolumesInput `json:"-" xml:"-"` + metadataDescribeVpcPeeringConnectionsInput `json:"-" xml:"-"` } -type metadataDescribeVolumesInput struct { +type metadataDescribeVpcPeeringConnectionsInput struct { SDKShapeTraits bool `type:"structure"` } -type DescribeVolumesOutput struct { - // The NextToken value to include in a future DescribeVolumes request. When - // the results of a DescribeVolumes request exceed MaxResults, this value can - // be used to retrieve the next page of results. This value is null when there - // are no more results to return. - NextToken *string `locationName:"nextToken" type:"string"` +// String returns the string representation +func (s DescribeVpcPeeringConnectionsInput) String() string { + return awsutil.Prettify(s) +} - // Information about the volumes. - Volumes []*Volume `locationName:"volumeSet" locationNameList:"item" type:"list"` +// GoString returns the string representation +func (s DescribeVpcPeeringConnectionsInput) GoString() string { + return s.String() +} - metadataDescribeVolumesOutput `json:"-" xml:"-"` +type DescribeVpcPeeringConnectionsOutput struct { + // Information about the VPC peering connections. + VpcPeeringConnections []*VpcPeeringConnection `locationName:"vpcPeeringConnectionSet" locationNameList:"item" type:"list"` + + metadataDescribeVpcPeeringConnectionsOutput `json:"-" xml:"-"` } -type metadataDescribeVolumesOutput struct { +type metadataDescribeVpcPeeringConnectionsOutput struct { SDKShapeTraits bool `type:"structure"` } -type DetachClassicLinkVPCInput struct { +// String returns the string representation +func (s DescribeVpcPeeringConnectionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcPeeringConnectionsOutput) GoString() string { + return s.String() +} + +type DescribeVpcsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The ID of the instance to unlink from the VPC. - InstanceID *string `locationName:"instanceId" type:"string" required:"true"` + // One or more filters. + // + // cidr - The CIDR block of the VPC. The CIDR block you specify must exactly + // match the VPC's CIDR block for information to be returned for the VPC. Must + // contain the slash followed by one or two digits (for example, /28). + // + // dhcp-options-id - The ID of a set of DHCP options. + // + // isDefault - Indicates whether the VPC is the default VPC. + // + // state - The state of the VPC (pending | available). + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter is + // independent of the tag-key filter. + // + // vpc-id - The ID of the VPC. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The ID of the VPC to which the instance is linked. - VPCID *string `locationName:"vpcId" type:"string" required:"true"` + // One or more VPC IDs. + // + // Default: Describes all your VPCs. + VpcIds []*string `locationName:"VpcId" locationNameList:"VpcId" type:"list"` - metadataDetachClassicLinkVPCInput `json:"-" xml:"-"` + metadataDescribeVpcsInput `json:"-" xml:"-"` } -type metadataDetachClassicLinkVPCInput struct { +type metadataDescribeVpcsInput struct { SDKShapeTraits bool `type:"structure"` } -type DetachClassicLinkVPCOutput struct { - // Returns true if the request succeeds; otherwise, it returns an error. - Return *bool `locationName:"return" type:"boolean"` +// String returns the string representation +func (s DescribeVpcsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcsInput) GoString() string { + return s.String() +} + +type DescribeVpcsOutput struct { + // Information about one or more VPCs. + Vpcs []*Vpc `locationName:"vpcSet" locationNameList:"item" type:"list"` - metadataDetachClassicLinkVPCOutput `json:"-" xml:"-"` + metadataDescribeVpcsOutput `json:"-" xml:"-"` } -type metadataDetachClassicLinkVPCOutput struct { +type metadataDescribeVpcsOutput struct { SDKShapeTraits bool `type:"structure"` } -type DetachInternetGatewayInput struct { +// String returns the string representation +func (s DescribeVpcsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcsOutput) GoString() string { + return s.String() +} + +type DescribeVpnConnectionsInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The ID of the Internet gateway. - InternetGatewayID *string `locationName:"internetGatewayId" type:"string" required:"true"` + // One or more filters. + // + // customer-gateway-configuration - The configuration information for the + // customer gateway. + // + // customer-gateway-id - The ID of a customer gateway associated with the + // VPN connection. + // + // state - The state of the VPN connection (pending | available | deleting + // | deleted). + // + // option.static-routes-only - Indicates whether the connection has static + // routes only. Used for devices that do not support Border Gateway Protocol + // (BGP). + // + // route.destination-cidr-block - The destination CIDR block. This corresponds + // to the subnet used in a customer data center. + // + // bgp-asn - The BGP Autonomous System Number (ASN) associated with a BGP + // device. + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter is + // independent of the tag-key filter. + // + // type - The type of VPN connection. Currently the only supported type is + // ipsec.1. + // + // vpn-connection-id - The ID of the VPN connection. + // + // vpn-gateway-id - The ID of a virtual private gateway associated with the + // VPN connection. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string" required:"true"` + // One or more VPN connection IDs. + // + // Default: Describes your VPN connections. + VpnConnectionIds []*string `locationName:"VpnConnectionId" locationNameList:"VpnConnectionId" type:"list"` - metadataDetachInternetGatewayInput `json:"-" xml:"-"` + metadataDescribeVpnConnectionsInput `json:"-" xml:"-"` } -type metadataDetachInternetGatewayInput struct { +type metadataDescribeVpnConnectionsInput struct { SDKShapeTraits bool `type:"structure"` } -type DetachInternetGatewayOutput struct { - metadataDetachInternetGatewayOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DescribeVpnConnectionsInput) String() string { + return awsutil.Prettify(s) } -type metadataDetachInternetGatewayOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s DescribeVpnConnectionsInput) GoString() string { + return s.String() } -type DetachNetworkInterfaceInput struct { - // The ID of the attachment. - AttachmentID *string `locationName:"attachmentId" type:"string" required:"true"` - - // Checks whether you have the required permissions for the action, without - // actually making the request, and provides an error response. If you have - // the required permissions, the error response is DryRunOperation. Otherwise, - // it is UnauthorizedOperation. - DryRun *bool `locationName:"dryRun" type:"boolean"` - - // Specifies whether to force a detachment. - Force *bool `locationName:"force" type:"boolean"` +type DescribeVpnConnectionsOutput struct { + // Information about one or more VPN connections. + VpnConnections []*VpnConnection `locationName:"vpnConnectionSet" locationNameList:"item" type:"list"` - metadataDetachNetworkInterfaceInput `json:"-" xml:"-"` + metadataDescribeVpnConnectionsOutput `json:"-" xml:"-"` } -type metadataDetachNetworkInterfaceInput struct { +type metadataDescribeVpnConnectionsOutput struct { SDKShapeTraits bool `type:"structure"` } -type DetachNetworkInterfaceOutput struct { - metadataDetachNetworkInterfaceOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DescribeVpnConnectionsOutput) String() string { + return awsutil.Prettify(s) } -type metadataDetachNetworkInterfaceOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s DescribeVpnConnectionsOutput) GoString() string { + return s.String() } -type DetachVPNGatewayInput struct { +type DescribeVpnGatewaysInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The ID of the VPC. - VPCID *string `locationName:"VpcId" type:"string" required:"true"` - - // The ID of the virtual private gateway. - VPNGatewayID *string `locationName:"VpnGatewayId" type:"string" required:"true"` + // One or more filters. + // + // attachment.state - The current state of the attachment between the gateway + // and the VPC (attaching | attached | detaching | detached). + // + // attachment.vpc-id - The ID of an attached VPC. + // + // availability-zone - The Availability Zone for the virtual private gateway. + // + // state - The state of the virtual private gateway (pending | available + // | deleting | deleted). + // + // tag:key=value - The key/value combination of a tag assigned to the resource. + // + // tag-key - The key of a tag assigned to the resource. This filter is independent + // of the tag-value filter. For example, if you use both the filter "tag-key=Purpose" + // and the filter "tag-value=X", you get any resources assigned both the tag + // key Purpose (regardless of what the tag's value is), and the tag value X + // (regardless of what the tag's key is). If you want to list only resources + // where Purpose is X, see the tag:key=value filter. + // + // tag-value - The value of a tag assigned to the resource. This filter is + // independent of the tag-key filter. + // + // type - The type of virtual private gateway. Currently the only supported + // type is ipsec.1. + // + // vpn-gateway-id - The ID of the virtual private gateway. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more virtual private gateway IDs. + // + // Default: Describes all your virtual private gateways. + VpnGatewayIds []*string `locationName:"VpnGatewayId" locationNameList:"VpnGatewayId" type:"list"` + + metadataDescribeVpnGatewaysInput `json:"-" xml:"-"` +} + +type metadataDescribeVpnGatewaysInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DescribeVpnGatewaysInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpnGatewaysInput) GoString() string { + return s.String() +} + +type DescribeVpnGatewaysOutput struct { + // Information about one or more virtual private gateways. + VpnGateways []*VpnGateway `locationName:"vpnGatewaySet" locationNameList:"item" type:"list"` + + metadataDescribeVpnGatewaysOutput `json:"-" xml:"-"` +} + +type metadataDescribeVpnGatewaysOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DescribeVpnGatewaysOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpnGatewaysOutput) GoString() string { + return s.String() +} + +type DetachClassicLinkVpcInput struct { + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the instance to unlink from the VPC. + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` + + // The ID of the VPC to which the instance is linked. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` + + metadataDetachClassicLinkVpcInput `json:"-" xml:"-"` +} + +type metadataDetachClassicLinkVpcInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DetachClassicLinkVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachClassicLinkVpcInput) GoString() string { + return s.String() +} + +type DetachClassicLinkVpcOutput struct { + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` + + metadataDetachClassicLinkVpcOutput `json:"-" xml:"-"` +} + +type metadataDetachClassicLinkVpcOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DetachClassicLinkVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachClassicLinkVpcOutput) GoString() string { + return s.String() +} + +type DetachInternetGatewayInput struct { + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the Internet gateway. + InternetGatewayId *string `locationName:"internetGatewayId" type:"string" required:"true"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` + + metadataDetachInternetGatewayInput `json:"-" xml:"-"` +} + +type metadataDetachInternetGatewayInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DetachInternetGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachInternetGatewayInput) GoString() string { + return s.String() +} + +type DetachInternetGatewayOutput struct { + metadataDetachInternetGatewayOutput `json:"-" xml:"-"` +} + +type metadataDetachInternetGatewayOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DetachInternetGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachInternetGatewayOutput) GoString() string { + return s.String() +} + +type DetachNetworkInterfaceInput struct { + // The ID of the attachment. + AttachmentId *string `locationName:"attachmentId" type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` - metadataDetachVPNGatewayInput `json:"-" xml:"-"` + // Specifies whether to force a detachment. + Force *bool `locationName:"force" type:"boolean"` + + metadataDetachNetworkInterfaceInput `json:"-" xml:"-"` } -type metadataDetachVPNGatewayInput struct { +type metadataDetachNetworkInterfaceInput struct { SDKShapeTraits bool `type:"structure"` } -type DetachVPNGatewayOutput struct { - metadataDetachVPNGatewayOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DetachNetworkInterfaceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachNetworkInterfaceInput) GoString() string { + return s.String() +} + +type DetachNetworkInterfaceOutput struct { + metadataDetachNetworkInterfaceOutput `json:"-" xml:"-"` } -type metadataDetachVPNGatewayOutput struct { +type metadataDetachNetworkInterfaceOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DetachNetworkInterfaceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachNetworkInterfaceOutput) GoString() string { + return s.String() +} + type DetachVolumeInput struct { // The device name. Device *string `type:"string"` @@ -13397,10 +15515,10 @@ type DetachVolumeInput struct { Force *bool `type:"boolean"` // The ID of the instance. - InstanceID *string `locationName:"InstanceId" type:"string"` + InstanceId *string `type:"string"` // The ID of the volume. - VolumeID *string `locationName:"VolumeId" type:"string" required:"true"` + VolumeId *string `type:"string" required:"true"` metadataDetachVolumeInput `json:"-" xml:"-"` } @@ -13409,29 +15527,160 @@ type metadataDetachVolumeInput struct { SDKShapeTraits bool `type:"structure"` } -type DisableVGWRoutePropagationInput struct { +// String returns the string representation +func (s DetachVolumeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachVolumeInput) GoString() string { + return s.String() +} + +type DetachVpnGatewayInput struct { + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the VPC. + VpcId *string `type:"string" required:"true"` + + // The ID of the virtual private gateway. + VpnGatewayId *string `type:"string" required:"true"` + + metadataDetachVpnGatewayInput `json:"-" xml:"-"` +} + +type metadataDetachVpnGatewayInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DetachVpnGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachVpnGatewayInput) GoString() string { + return s.String() +} + +type DetachVpnGatewayOutput struct { + metadataDetachVpnGatewayOutput `json:"-" xml:"-"` +} + +type metadataDetachVpnGatewayOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DetachVpnGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachVpnGatewayOutput) GoString() string { + return s.String() +} + +// Describes a DHCP configuration option. +type DhcpConfiguration struct { + // The name of a DHCP option. + Key *string `locationName:"key" type:"string"` + + // One or more values for the DHCP option. + Values []*AttributeValue `locationName:"valueSet" locationNameList:"item" type:"list"` + + metadataDhcpConfiguration `json:"-" xml:"-"` +} + +type metadataDhcpConfiguration struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DhcpConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DhcpConfiguration) GoString() string { + return s.String() +} + +// Describes a set of DHCP options. +type DhcpOptions struct { + // One or more DHCP options in the set. + DhcpConfigurations []*DhcpConfiguration `locationName:"dhcpConfigurationSet" locationNameList:"item" type:"list"` + + // The ID of the set of DHCP options. + DhcpOptionsId *string `locationName:"dhcpOptionsId" type:"string"` + + // Any tags assigned to the DHCP options set. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + metadataDhcpOptions `json:"-" xml:"-"` +} + +type metadataDhcpOptions struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s DhcpOptions) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DhcpOptions) GoString() string { + return s.String() +} + +type DisableVgwRoutePropagationInput struct { // The ID of the virtual private gateway. - GatewayID *string `locationName:"GatewayId" type:"string" required:"true"` + GatewayId *string `type:"string" required:"true"` // The ID of the route table. - RouteTableID *string `locationName:"RouteTableId" type:"string" required:"true"` + RouteTableId *string `type:"string" required:"true"` - metadataDisableVGWRoutePropagationInput `json:"-" xml:"-"` + metadataDisableVgwRoutePropagationInput `json:"-" xml:"-"` } -type metadataDisableVGWRoutePropagationInput struct { +type metadataDisableVgwRoutePropagationInput struct { SDKShapeTraits bool `type:"structure"` } -type DisableVGWRoutePropagationOutput struct { - metadataDisableVGWRoutePropagationOutput `json:"-" xml:"-"` +// String returns the string representation +func (s DisableVgwRoutePropagationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableVgwRoutePropagationInput) GoString() string { + return s.String() +} + +type DisableVgwRoutePropagationOutput struct { + metadataDisableVgwRoutePropagationOutput `json:"-" xml:"-"` } -type metadataDisableVGWRoutePropagationOutput struct { +type metadataDisableVgwRoutePropagationOutput struct { SDKShapeTraits bool `type:"structure"` } -type DisableVPCClassicLinkInput struct { +// String returns the string representation +func (s DisableVgwRoutePropagationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableVgwRoutePropagationOutput) GoString() string { + return s.String() +} + +type DisableVpcClassicLinkInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -13439,29 +15688,49 @@ type DisableVPCClassicLinkInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string" required:"true"` + VpcId *string `locationName:"vpcId" type:"string" required:"true"` - metadataDisableVPCClassicLinkInput `json:"-" xml:"-"` + metadataDisableVpcClassicLinkInput `json:"-" xml:"-"` } -type metadataDisableVPCClassicLinkInput struct { +type metadataDisableVpcClassicLinkInput struct { SDKShapeTraits bool `type:"structure"` } -type DisableVPCClassicLinkOutput struct { +// String returns the string representation +func (s DisableVpcClassicLinkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableVpcClassicLinkInput) GoString() string { + return s.String() +} + +type DisableVpcClassicLinkOutput struct { // Returns true if the request succeeds; otherwise, it returns an error. Return *bool `locationName:"return" type:"boolean"` - metadataDisableVPCClassicLinkOutput `json:"-" xml:"-"` + metadataDisableVpcClassicLinkOutput `json:"-" xml:"-"` } -type metadataDisableVPCClassicLinkOutput struct { +type metadataDisableVpcClassicLinkOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DisableVpcClassicLinkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableVpcClassicLinkOutput) GoString() string { + return s.String() +} + type DisassociateAddressInput struct { // [EC2-VPC] The association ID. Required for EC2-VPC. - AssociationID *string `locationName:"AssociationId" type:"string"` + AssociationId *string `type:"string"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -13470,7 +15739,7 @@ type DisassociateAddressInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // [EC2-Classic] The Elastic IP address. Required for EC2-Classic. - PublicIP *string `locationName:"PublicIp" type:"string"` + PublicIp *string `type:"string"` metadataDisassociateAddressInput `json:"-" xml:"-"` } @@ -13479,6 +15748,16 @@ type metadataDisassociateAddressInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DisassociateAddressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateAddressInput) GoString() string { + return s.String() +} + type DisassociateAddressOutput struct { metadataDisassociateAddressOutput `json:"-" xml:"-"` } @@ -13487,10 +15766,20 @@ type metadataDisassociateAddressOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DisassociateAddressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateAddressOutput) GoString() string { + return s.String() +} + type DisassociateRouteTableInput struct { // The association ID representing the current association between the route // table and subnet. - AssociationID *string `locationName:"associationId" type:"string" required:"true"` + AssociationId *string `locationName:"associationId" type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -13505,6 +15794,16 @@ type metadataDisassociateRouteTableInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DisassociateRouteTableInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateRouteTableInput) GoString() string { + return s.String() +} + type DisassociateRouteTableOutput struct { metadataDisassociateRouteTableOutput `json:"-" xml:"-"` } @@ -13513,6 +15812,16 @@ type metadataDisassociateRouteTableOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DisassociateRouteTableOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateRouteTableOutput) GoString() string { + return s.String() +} + // Describes a disk image. type DiskImage struct { // A description of the disk image. @@ -13531,20 +15840,30 @@ type metadataDiskImage struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DiskImage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskImage) GoString() string { + return s.String() +} + // Describes a disk image. type DiskImageDescription struct { // The checksum computed for the disk image. Checksum *string `locationName:"checksum" type:"string"` // The disk image format. - Format *string `locationName:"format" type:"string" required:"true"` + Format *string `locationName:"format" type:"string" required:"true" enum:"DiskImageFormat"` // A presigned URL for the import manifest stored in Amazon S3. For information // about creating a presigned URL for an Amazon S3 object, read the "Query String // Request Authentication Alternative" section of the Authenticating REST Requests // (http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) // topic in the Amazon Simple Storage Service Developer Guide. - ImportManifestURL *string `locationName:"importManifestUrl" type:"string" required:"true"` + ImportManifestUrl *string `locationName:"importManifestUrl" type:"string" required:"true"` // The size of the disk image, in GiB. Size *int64 `locationName:"size" type:"long" required:"true"` @@ -13556,20 +15875,30 @@ type metadataDiskImageDescription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DiskImageDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskImageDescription) GoString() string { + return s.String() +} + // Describes a disk image. type DiskImageDetail struct { // The size of the disk image, in GiB. Bytes *int64 `locationName:"bytes" type:"long" required:"true"` // The disk image format. - Format *string `locationName:"format" type:"string" required:"true"` + Format *string `locationName:"format" type:"string" required:"true" enum:"DiskImageFormat"` // A presigned URL for the import manifest stored in Amazon S3 and presented // here as an Amazon S3 presigned URL. For information about creating a presigned // URL for an Amazon S3 object, read the "Query String Request Authentication // Alternative" section of the Authenticating REST Requests (http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) // topic in the Amazon Simple Storage Service Developer Guide. - ImportManifestURL *string `locationName:"importManifestUrl" type:"string" required:"true"` + ImportManifestUrl *string `locationName:"importManifestUrl" type:"string" required:"true"` metadataDiskImageDetail `json:"-" xml:"-"` } @@ -13578,10 +15907,20 @@ type metadataDiskImageDetail struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DiskImageDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskImageDetail) GoString() string { + return s.String() +} + // Describes a disk image volume. type DiskImageVolumeDescription struct { // The volume identifier. - ID *string `locationName:"id" type:"string" required:"true"` + Id *string `locationName:"id" type:"string" required:"true"` // The size of the volume, in GiB. Size *int64 `locationName:"size" type:"long"` @@ -13593,10 +15932,20 @@ type metadataDiskImageVolumeDescription struct { SDKShapeTraits bool `type:"structure"` } -// Describes a block device for an EBS volume. -type EBSBlockDevice struct { - // Indicates whether the EBS volume is deleted on instance termination. - DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` +// String returns the string representation +func (s DiskImageVolumeDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskImageVolumeDescription) GoString() string { + return s.String() +} + +// Describes a block device for an EBS volume. +type EbsBlockDevice struct { + // Indicates whether the EBS volume is deleted on instance termination. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` // Indicates whether the EBS volume is encrypted. Encrypted Amazon EBS volumes // may only be attached to instances that support Amazon EBS encryption. @@ -13615,10 +15964,10 @@ type EBSBlockDevice struct { // // Condition: This parameter is required for requests to create io1 volumes; // it is not used in requests to create standard or gp2 volumes. - IOPS *int64 `locationName:"iops" type:"integer"` + Iops *int64 `locationName:"iops" type:"integer"` // The ID of the snapshot. - SnapshotID *string `locationName:"snapshotId" type:"string"` + SnapshotId *string `locationName:"snapshotId" type:"string"` // The size of the volume, in GiB. // @@ -13634,17 +15983,27 @@ type EBSBlockDevice struct { // IOPS (SSD) volumes, and standard for Magnetic volumes. // // Default: standard - VolumeType *string `locationName:"volumeType" type:"string"` + VolumeType *string `locationName:"volumeType" type:"string" enum:"VolumeType"` - metadataEBSBlockDevice `json:"-" xml:"-"` + metadataEbsBlockDevice `json:"-" xml:"-"` } -type metadataEBSBlockDevice struct { +type metadataEbsBlockDevice struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s EbsBlockDevice) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EbsBlockDevice) GoString() string { + return s.String() +} + // Describes a parameter used to set up an EBS volume in a block device mapping. -type EBSInstanceBlockDevice struct { +type EbsInstanceBlockDevice struct { // The time stamp when the attachment initiated. AttachTime *time.Time `locationName:"attachTime" type:"timestamp" timestampFormat:"iso8601"` @@ -13652,107 +16011,187 @@ type EBSInstanceBlockDevice struct { DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` // The attachment state. - Status *string `locationName:"status" type:"string"` + Status *string `locationName:"status" type:"string" enum:"AttachmentStatus"` // The ID of the EBS volume. - VolumeID *string `locationName:"volumeId" type:"string"` + VolumeId *string `locationName:"volumeId" type:"string"` - metadataEBSInstanceBlockDevice `json:"-" xml:"-"` + metadataEbsInstanceBlockDevice `json:"-" xml:"-"` } -type metadataEBSInstanceBlockDevice struct { +type metadataEbsInstanceBlockDevice struct { SDKShapeTraits bool `type:"structure"` } -type EBSInstanceBlockDeviceSpecification struct { +// String returns the string representation +func (s EbsInstanceBlockDevice) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EbsInstanceBlockDevice) GoString() string { + return s.String() +} + +type EbsInstanceBlockDeviceSpecification struct { // Indicates whether the volume is deleted on instance termination. DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` // The ID of the EBS volume. - VolumeID *string `locationName:"volumeId" type:"string"` + VolumeId *string `locationName:"volumeId" type:"string"` - metadataEBSInstanceBlockDeviceSpecification `json:"-" xml:"-"` + metadataEbsInstanceBlockDeviceSpecification `json:"-" xml:"-"` } -type metadataEBSInstanceBlockDeviceSpecification struct { +type metadataEbsInstanceBlockDeviceSpecification struct { SDKShapeTraits bool `type:"structure"` } -type EnableVGWRoutePropagationInput struct { +// String returns the string representation +func (s EbsInstanceBlockDeviceSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EbsInstanceBlockDeviceSpecification) GoString() string { + return s.String() +} + +type EnableVgwRoutePropagationInput struct { // The ID of the virtual private gateway. - GatewayID *string `locationName:"GatewayId" type:"string" required:"true"` + GatewayId *string `type:"string" required:"true"` // The ID of the route table. - RouteTableID *string `locationName:"RouteTableId" type:"string" required:"true"` + RouteTableId *string `type:"string" required:"true"` - metadataEnableVGWRoutePropagationInput `json:"-" xml:"-"` + metadataEnableVgwRoutePropagationInput `json:"-" xml:"-"` } -type metadataEnableVGWRoutePropagationInput struct { +type metadataEnableVgwRoutePropagationInput struct { SDKShapeTraits bool `type:"structure"` } -type EnableVGWRoutePropagationOutput struct { - metadataEnableVGWRoutePropagationOutput `json:"-" xml:"-"` +// String returns the string representation +func (s EnableVgwRoutePropagationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVgwRoutePropagationInput) GoString() string { + return s.String() +} + +type EnableVgwRoutePropagationOutput struct { + metadataEnableVgwRoutePropagationOutput `json:"-" xml:"-"` } -type metadataEnableVGWRoutePropagationOutput struct { +type metadataEnableVgwRoutePropagationOutput struct { SDKShapeTraits bool `type:"structure"` } -type EnableVPCClassicLinkInput struct { +// String returns the string representation +func (s EnableVgwRoutePropagationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVgwRoutePropagationOutput) GoString() string { + return s.String() +} + +type EnableVolumeIOInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string" required:"true"` + // The ID of the volume. + VolumeId *string `locationName:"volumeId" type:"string" required:"true"` - metadataEnableVPCClassicLinkInput `json:"-" xml:"-"` + metadataEnableVolumeIOInput `json:"-" xml:"-"` } -type metadataEnableVPCClassicLinkInput struct { +type metadataEnableVolumeIOInput struct { SDKShapeTraits bool `type:"structure"` } -type EnableVPCClassicLinkOutput struct { - // Returns true if the request succeeds; otherwise, it returns an error. - Return *bool `locationName:"return" type:"boolean"` +// String returns the string representation +func (s EnableVolumeIOInput) String() string { + return awsutil.Prettify(s) +} - metadataEnableVPCClassicLinkOutput `json:"-" xml:"-"` +// GoString returns the string representation +func (s EnableVolumeIOInput) GoString() string { + return s.String() +} + +type EnableVolumeIOOutput struct { + metadataEnableVolumeIOOutput `json:"-" xml:"-"` } -type metadataEnableVPCClassicLinkOutput struct { +type metadataEnableVolumeIOOutput struct { SDKShapeTraits bool `type:"structure"` } -type EnableVolumeIOInput struct { +// String returns the string representation +func (s EnableVolumeIOOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVolumeIOOutput) GoString() string { + return s.String() +} + +type EnableVpcClassicLinkInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The ID of the volume. - VolumeID *string `locationName:"volumeId" type:"string" required:"true"` + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string" required:"true"` - metadataEnableVolumeIOInput `json:"-" xml:"-"` + metadataEnableVpcClassicLinkInput `json:"-" xml:"-"` } -type metadataEnableVolumeIOInput struct { +type metadataEnableVpcClassicLinkInput struct { SDKShapeTraits bool `type:"structure"` } -type EnableVolumeIOOutput struct { - metadataEnableVolumeIOOutput `json:"-" xml:"-"` +// String returns the string representation +func (s EnableVpcClassicLinkInput) String() string { + return awsutil.Prettify(s) } -type metadataEnableVolumeIOOutput struct { +// GoString returns the string representation +func (s EnableVpcClassicLinkInput) GoString() string { + return s.String() +} + +type EnableVpcClassicLinkOutput struct { + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` + + metadataEnableVpcClassicLinkOutput `json:"-" xml:"-"` +} + +type metadataEnableVpcClassicLinkOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s EnableVpcClassicLinkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableVpcClassicLinkOutput) GoString() string { + return s.String() +} + // Describes a Spot fleet event. type EventInformation struct { // The description of the event. @@ -13766,33 +16205,35 @@ type EventInformation struct { // either to launch or terminate an instance. // // spotFleetRequestConfigurationInvalid - The configuration is not valid. - // For more information, see the description. spotInstanceCountLimitExceeded - // - You've reached the limit on the number of Spot Instances that you can launch. + // For more information, see the description. + // + // spotInstanceCountLimitExceeded - You've reached the limit on the number + // of Spot instances that you can launch. // // The following are the fleetRequestChange events. // // active - The Spot fleet has been validated and Amazon EC2 is attempting - // to maintain the target number of running Spot Instances. + // to maintain the target number of running Spot instances. // - // cancelled - The Spot fleet is canceled and has no running Spot Instances. + // cancelled - The Spot fleet is canceled and has no running Spot instances. // The Spot fleet will be deleted two days after its instances were terminated. // // cancelled_running - The Spot fleet is canceled and will not launch additional - // Spot Instances, but its existing Spot Instances will continue to run until - // they are interrupted or terminated. + // Spot instances, but its existing Spot instances continue to run until they + // are interrupted or terminated. // - // cancelled_terminating - The Spot fleet is canceled and its Spot Instances + // cancelled_terminating - The Spot fleet is canceled and its Spot instances // are terminating. // // expired - The Spot fleet request has expired. A subsequent event indicates - // that the instances were terminated, if the request was created with terminateInstancesWithExpiration + // that the instances were terminated, if the request was created with TerminateInstancesWithExpiration // set. // // price_update - The bid price for a launch configuration was adjusted because // it was too high. This change is permanent. // // submitted - The Spot fleet request is being evaluated and Amazon EC2 is - // preparing to launch the target number of Spot Instances. + // preparing to launch the target number of Spot instances. // // The following are the instanceChange events. // @@ -13803,7 +16244,7 @@ type EventInformation struct { // The ID of the instance. This information is available only for instanceChange // events. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` metadataEventInformation `json:"-" xml:"-"` } @@ -13812,13 +16253,23 @@ type metadataEventInformation struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s EventInformation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EventInformation) GoString() string { + return s.String() +} + // Describes an instance export task. type ExportTask struct { // A description of the resource being exported. Description *string `locationName:"description" type:"string"` // The ID of the export task. - ExportTaskID *string `locationName:"exportTaskId" type:"string"` + ExportTaskId *string `locationName:"exportTaskId" type:"string"` // Information about the export task. ExportToS3Task *ExportToS3Task `locationName:"exportToS3" type:"structure"` @@ -13827,7 +16278,7 @@ type ExportTask struct { InstanceExportDetails *InstanceExportDetails `locationName:"instanceExport" type:"structure"` // The state of the export task. - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"ExportTaskState"` // The status message related to the export task. StatusMessage *string `locationName:"statusMessage" type:"string"` @@ -13839,14 +16290,24 @@ type metadataExportTask struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ExportTask) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExportTask) GoString() string { + return s.String() +} + // Describes the format and location for an instance export task. type ExportToS3Task struct { // The container format used to combine disk images with metadata (such as OVF). // If absent, only the disk image is exported. - ContainerFormat *string `locationName:"containerFormat" type:"string"` + ContainerFormat *string `locationName:"containerFormat" type:"string" enum:"ContainerFormat"` // The format for the exported image. - DiskImageFormat *string `locationName:"diskImageFormat" type:"string"` + DiskImageFormat *string `locationName:"diskImageFormat" type:"string" enum:"DiskImageFormat"` // The S3 bucket for the destination image. The destination bucket must exist // and grant WRITE and READ_ACP permissions to the AWS account vm-import-export@amazon.com. @@ -13862,14 +16323,24 @@ type metadataExportToS3Task struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ExportToS3Task) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExportToS3Task) GoString() string { + return s.String() +} + // Describes an instance export task. type ExportToS3TaskSpecification struct { // The container format used to combine disk images with metadata (such as OVF). // If absent, only the disk image is exported. - ContainerFormat *string `locationName:"containerFormat" type:"string"` + ContainerFormat *string `locationName:"containerFormat" type:"string" enum:"ContainerFormat"` // The format for the exported image. - DiskImageFormat *string `locationName:"diskImageFormat" type:"string"` + DiskImageFormat *string `locationName:"diskImageFormat" type:"string" enum:"DiskImageFormat"` // The S3 bucket for the destination image. The destination bucket must exist // and grant WRITE and READ_ACP permissions to the AWS account vm-import-export@amazon.com. @@ -13886,6 +16357,16 @@ type metadataExportToS3TaskSpecification struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ExportToS3TaskSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExportToS3TaskSpecification) GoString() string { + return s.String() +} + // A filter name and value pair that is used to return a more specific list // of results. Filters can be used to match a set of resources by various criteria, // such as tags, attributes, or IDs. @@ -13903,6 +16384,66 @@ type metadataFilter struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Filter) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Filter) GoString() string { + return s.String() +} + +// Describes a flow log. +type FlowLog struct { + // The date and time the flow log was created. + CreationTime *time.Time `locationName:"creationTime" type:"timestamp" timestampFormat:"iso8601"` + + // Information about the error that occurred. Rate limited indicates that CloudWatch + // logs throttling has been applied for one or more network interfaces. Access + // error indicates that the IAM role associated with the flow log does not have + // sufficient permissions to publish to CloudWatch Logs. Unknown error indicates + // an internal error. + DeliverLogsErrorMessage *string `locationName:"deliverLogsErrorMessage" type:"string"` + + // The ARN of the IAM role that posts logs to CloudWatch Logs. + DeliverLogsPermissionArn *string `locationName:"deliverLogsPermissionArn" type:"string"` + + // The status of the logs delivery (SUCCESS | FAILED). + DeliverLogsStatus *string `locationName:"deliverLogsStatus" type:"string"` + + // The flow log ID. + FlowLogId *string `locationName:"flowLogId" type:"string"` + + // The status of the flow log (ACTIVE). + FlowLogStatus *string `locationName:"flowLogStatus" type:"string"` + + // The name of the flow log group. + LogGroupName *string `locationName:"logGroupName" type:"string"` + + // The ID of the resource on which the flow log was created. + ResourceId *string `locationName:"resourceId" type:"string"` + + // The type of traffic captured for the flow log. + TrafficType *string `locationName:"trafficType" type:"string" enum:"TrafficType"` + + metadataFlowLog `json:"-" xml:"-"` +} + +type metadataFlowLog struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s FlowLog) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FlowLog) GoString() string { + return s.String() +} + type GetConsoleOutputInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -13911,7 +16452,7 @@ type GetConsoleOutputInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the instance. - InstanceID *string `locationName:"InstanceId" type:"string" required:"true"` + InstanceId *string `type:"string" required:"true"` metadataGetConsoleOutputInput `json:"-" xml:"-"` } @@ -13920,9 +16461,19 @@ type metadataGetConsoleOutputInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s GetConsoleOutputInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetConsoleOutputInput) GoString() string { + return s.String() +} + type GetConsoleOutputOutput struct { // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The console output, Base64 encoded. Output *string `locationName:"output" type:"string"` @@ -13937,6 +16488,16 @@ type metadataGetConsoleOutputOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s GetConsoleOutputOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetConsoleOutputOutput) GoString() string { + return s.String() +} + type GetPasswordDataInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -13945,7 +16506,7 @@ type GetPasswordDataInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the Windows instance. - InstanceID *string `locationName:"InstanceId" type:"string" required:"true"` + InstanceId *string `type:"string" required:"true"` metadataGetPasswordDataInput `json:"-" xml:"-"` } @@ -13954,9 +16515,19 @@ type metadataGetPasswordDataInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s GetPasswordDataInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetPasswordDataInput) GoString() string { + return s.String() +} + type GetPasswordDataOutput struct { // The ID of the Windows instance. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The password of the instance. PasswordData *string `locationName:"passwordData" type:"string"` @@ -13971,10 +16542,20 @@ type metadataGetPasswordDataOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s GetPasswordDataOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetPasswordDataOutput) GoString() string { + return s.String() +} + // Describes a security group. type GroupIdentifier struct { // The ID of the security group. - GroupID *string `locationName:"groupId" type:"string"` + GroupId *string `locationName:"groupId" type:"string"` // The name of the security group. GroupName *string `locationName:"groupName" type:"string"` @@ -13986,6 +16567,16 @@ type metadataGroupIdentifier struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s GroupIdentifier) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GroupIdentifier) GoString() string { + return s.String() +} + // Describes an event in the history of the Spot fleet request. type HistoryRecord struct { // Information about the event. @@ -13999,7 +16590,7 @@ type HistoryRecord struct { // of the Spot fleet request. // // instanceChange - Indicates that an instance was launched or terminated. - EventType *string `locationName:"eventType" type:"string" required:"true"` + EventType *string `locationName:"eventType" type:"string" required:"true" enum:"EventType"` // The date and time of the event, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). Timestamp *time.Time `locationName:"timestamp" type:"timestamp" timestampFormat:"iso8601" required:"true"` @@ -14011,107 +16602,95 @@ type metadataHistoryRecord struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s HistoryRecord) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HistoryRecord) GoString() string { + return s.String() +} + // Describes an IAM instance profile. -type IAMInstanceProfile struct { +type IamInstanceProfile struct { // The Amazon Resource Name (ARN) of the instance profile. - ARN *string `locationName:"arn" type:"string"` + Arn *string `locationName:"arn" type:"string"` // The ID of the instance profile. - ID *string `locationName:"id" type:"string"` + Id *string `locationName:"id" type:"string"` - metadataIAMInstanceProfile `json:"-" xml:"-"` + metadataIamInstanceProfile `json:"-" xml:"-"` } -type metadataIAMInstanceProfile struct { +type metadataIamInstanceProfile struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s IamInstanceProfile) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IamInstanceProfile) GoString() string { + return s.String() +} + // Describes an IAM instance profile. -type IAMInstanceProfileSpecification struct { +type IamInstanceProfileSpecification struct { // The Amazon Resource Name (ARN) of the instance profile. - ARN *string `locationName:"arn" type:"string"` + Arn *string `locationName:"arn" type:"string"` // The name of the instance profile. Name *string `locationName:"name" type:"string"` - metadataIAMInstanceProfileSpecification `json:"-" xml:"-"` + metadataIamInstanceProfileSpecification `json:"-" xml:"-"` } -type metadataIAMInstanceProfileSpecification struct { +type metadataIamInstanceProfileSpecification struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s IamInstanceProfileSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IamInstanceProfileSpecification) GoString() string { + return s.String() +} + // Describes the ICMP type and code. -type ICMPTypeCode struct { +type IcmpTypeCode struct { // The ICMP type. A value of -1 means all types. Code *int64 `locationName:"code" type:"integer"` // The ICMP code. A value of -1 means all codes for the specified ICMP type. Type *int64 `locationName:"type" type:"integer"` - metadataICMPTypeCode `json:"-" xml:"-"` -} - -type metadataICMPTypeCode struct { - SDKShapeTraits bool `type:"structure"` -} - -// Describes a security group rule. -type IPPermission struct { - // The start of port range for the TCP and UDP protocols, or an ICMP type number. - // A value of -1 indicates all ICMP types. - FromPort *int64 `locationName:"fromPort" type:"integer"` - - // The protocol. - // - // When you call DescribeSecurityGroups, the protocol value returned is the - // number. Exception: For TCP, UDP, and ICMP, the value returned is the name - // (for example, tcp, udp, or icmp). For a list of protocol numbers, see Protocol - // Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml). - // (VPC only) When you call AuthorizeSecurityGroupIngress, you can use -1 to - // specify all. - IPProtocol *string `locationName:"ipProtocol" type:"string"` - - // One or more IP ranges. - IPRanges []*IPRange `locationName:"ipRanges" locationNameList:"item" type:"list"` - - // (Valid for AuthorizeSecurityGroupEgress, RevokeSecurityGroupEgress and DescribeSecurityGroups - // only) One or more prefix list IDs for an AWS service. In an AuthorizeSecurityGroupEgress - // request, this is the AWS service that you want to access through a VPC endpoint - // from instances associated with the security group. - PrefixListIDs []*PrefixListID `locationName:"prefixListIds" locationNameList:"item" type:"list"` - - // The end of port range for the TCP and UDP protocols, or an ICMP code. A value - // of -1 indicates all ICMP codes for the specified ICMP type. - ToPort *int64 `locationName:"toPort" type:"integer"` - - // One or more security group and AWS account ID pairs. - UserIDGroupPairs []*UserIDGroupPair `locationName:"groups" locationNameList:"item" type:"list"` - - metadataIPPermission `json:"-" xml:"-"` + metadataIcmpTypeCode `json:"-" xml:"-"` } -type metadataIPPermission struct { +type metadataIcmpTypeCode struct { SDKShapeTraits bool `type:"structure"` } -// Describes an IP range. -type IPRange struct { - // The CIDR range. You can either specify a CIDR range or a source security - // group, not both. - CIDRIP *string `locationName:"cidrIp" type:"string"` - - metadataIPRange `json:"-" xml:"-"` +// String returns the string representation +func (s IcmpTypeCode) String() string { + return awsutil.Prettify(s) } -type metadataIPRange struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s IcmpTypeCode) GoString() string { + return s.String() } // Describes an image. type Image struct { // The architecture of the image. - Architecture *string `locationName:"architecture" type:"string"` + Architecture *string `locationName:"architecture" type:"string" enum:"ArchitectureValues"` // Any block device mapping entries. BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` @@ -14123,10 +16702,10 @@ type Image struct { Description *string `locationName:"description" type:"string"` // The hypervisor type of the image. - Hypervisor *string `locationName:"hypervisor" type:"string"` + Hypervisor *string `locationName:"hypervisor" type:"string" enum:"HypervisorType"` // The ID of the AMI. - ImageID *string `locationName:"imageId" type:"string"` + ImageId *string `locationName:"imageId" type:"string"` // The location of the AMI. ImageLocation *string `locationName:"imageLocation" type:"string"` @@ -14136,20 +16715,20 @@ type Image struct { ImageOwnerAlias *string `locationName:"imageOwnerAlias" type:"string"` // The type of image. - ImageType *string `locationName:"imageType" type:"string"` + ImageType *string `locationName:"imageType" type:"string" enum:"ImageTypeValues"` // The kernel associated with the image, if any. Only applicable for machine // images. - KernelID *string `locationName:"kernelId" type:"string"` + KernelId *string `locationName:"kernelId" type:"string"` // The name of the AMI that was provided during image creation. Name *string `locationName:"name" type:"string"` // The AWS account ID of the image owner. - OwnerID *string `locationName:"imageOwnerId" type:"string"` + OwnerId *string `locationName:"imageOwnerId" type:"string"` // The value is Windows for Windows AMIs; otherwise blank. - Platform *string `locationName:"platform" type:"string"` + Platform *string `locationName:"platform" type:"string" enum:"PlatformValues"` // Any product codes associated with the AMI. ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` @@ -14161,21 +16740,21 @@ type Image struct { // The RAM disk associated with the image, if any. Only applicable for machine // images. - RAMDiskID *string `locationName:"ramdiskId" type:"string"` + RamdiskId *string `locationName:"ramdiskId" type:"string"` // The device name of the root device (for example, /dev/sda1 or /dev/xvda). RootDeviceName *string `locationName:"rootDeviceName" type:"string"` // The type of root device used by the AMI. The AMI can use an EBS volume or // an instance store volume. - RootDeviceType *string `locationName:"rootDeviceType" type:"string"` + RootDeviceType *string `locationName:"rootDeviceType" type:"string" enum:"DeviceType"` // Specifies whether enhanced networking is enabled. - SRIOVNetSupport *string `locationName:"sriovNetSupport" type:"string"` + SriovNetSupport *string `locationName:"sriovNetSupport" type:"string"` // The current state of the AMI. If the state is available, the image is successfully // registered and can be used to launch an instance. - State *string `locationName:"imageState" type:"string"` + State *string `locationName:"imageState" type:"string" enum:"ImageState"` // The reason for the state change. StateReason *StateReason `locationName:"stateReason" type:"structure"` @@ -14184,7 +16763,7 @@ type Image struct { Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` // The type of virtualization of the AMI. - VirtualizationType *string `locationName:"virtualizationType" type:"string"` + VirtualizationType *string `locationName:"virtualizationType" type:"string" enum:"VirtualizationType"` metadataImage `json:"-" xml:"-"` } @@ -14193,6 +16772,16 @@ type metadataImage struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Image) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Image) GoString() string { + return s.String() +} + // Describes the disk container object for an import image task. type ImageDiskContainer struct { // The description of the disk image. @@ -14207,11 +16796,11 @@ type ImageDiskContainer struct { Format *string `type:"string"` // The ID of the EBS snapshot to be used for importing the snapshot. - SnapshotID *string `locationName:"SnapshotId" type:"string"` + SnapshotId *string `type:"string"` // The URL to the Amazon S3-based disk image being imported. The URL can either // be a https URL (https://..) or an Amazon S3 URL (s3://..) - URL *string `locationName:"Url" type:"string"` + Url *string `type:"string"` // The S3 bucket for the disk image. UserBucket *UserBucket `type:"structure"` @@ -14223,6 +16812,16 @@ type metadataImageDiskContainer struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImageDiskContainer) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImageDiskContainer) GoString() string { + return s.String() +} + type ImportImageInput struct { // The architecture of the virtual machine. // @@ -14277,6 +16876,16 @@ type metadataImportImageInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportImageInput) GoString() string { + return s.String() +} + type ImportImageOutput struct { // The architecture of the virtual machine. Architecture *string `locationName:"architecture" type:"string"` @@ -14288,10 +16897,10 @@ type ImportImageOutput struct { Hypervisor *string `locationName:"hypervisor" type:"string"` // The ID of the Amazon Machine Image (AMI) created by the import task. - ImageID *string `locationName:"imageId" type:"string"` + ImageId *string `locationName:"imageId" type:"string"` // The task ID of the import image task. - ImportTaskID *string `locationName:"importTaskId" type:"string"` + ImportTaskId *string `locationName:"importTaskId" type:"string"` // The license type of the virtual machine. LicenseType *string `locationName:"licenseType" type:"string"` @@ -14318,6 +16927,16 @@ type metadataImportImageOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportImageOutput) GoString() string { + return s.String() +} + // Describes an import image task. type ImportImageTask struct { // The architecture of the virtual machine. @@ -14334,10 +16953,10 @@ type ImportImageTask struct { Hypervisor *string `locationName:"hypervisor" type:"string"` // The ID of the Amazon Machine Image (AMI) of the imported virtual machine. - ImageID *string `locationName:"imageId" type:"string"` + ImageId *string `locationName:"imageId" type:"string"` // The ID of the import image task. - ImportTaskID *string `locationName:"importTaskId" type:"string"` + ImportTaskId *string `locationName:"importTaskId" type:"string"` // The license type of the virtual machine. LicenseType *string `locationName:"licenseType" type:"string"` @@ -14364,6 +16983,16 @@ type metadataImportImageTask struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportImageTask) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportImageTask) GoString() string { + return s.String() +} + type ImportInstanceInput struct { // A description for the instance being imported. Description *string `locationName:"description" type:"string"` @@ -14381,7 +17010,7 @@ type ImportInstanceInput struct { LaunchSpecification *ImportInstanceLaunchSpecification `locationName:"launchSpecification" type:"structure"` // The instance operating system. - Platform *string `locationName:"platform" type:"string" required:"true"` + Platform *string `locationName:"platform" type:"string" required:"true" enum:"PlatformValues"` metadataImportInstanceInput `json:"-" xml:"-"` } @@ -14390,28 +17019,38 @@ type metadataImportInstanceInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportInstanceInput) GoString() string { + return s.String() +} + // Describes the launch specification for VM import. type ImportInstanceLaunchSpecification struct { // Reserved. AdditionalInfo *string `locationName:"additionalInfo" type:"string"` // The architecture of the instance. - Architecture *string `locationName:"architecture" type:"string"` + Architecture *string `locationName:"architecture" type:"string" enum:"ArchitectureValues"` // One or more security group IDs. - GroupIDs []*string `locationName:"GroupId" locationNameList:"SecurityGroupId" type:"list"` + GroupIds []*string `locationName:"GroupId" locationNameList:"SecurityGroupId" type:"list"` // One or more security group names. GroupNames []*string `locationName:"GroupName" locationNameList:"SecurityGroup" type:"list"` // Indicates whether an instance stops or terminates when you initiate shutdown // from the instance (using the operating system command for system shutdown). - InstanceInitiatedShutdownBehavior *string `locationName:"instanceInitiatedShutdownBehavior" type:"string"` + InstanceInitiatedShutdownBehavior *string `locationName:"instanceInitiatedShutdownBehavior" type:"string" enum:"ShutdownBehavior"` // The instance type. For more information about the instance types that you // can import, see Before You Get Started (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/VMImportPrerequisites.html) // in the Amazon Elastic Compute Cloud User Guide. - InstanceType *string `locationName:"instanceType" type:"string"` + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` // Indicates whether monitoring is enabled. Monitoring *bool `locationName:"monitoring" type:"boolean"` @@ -14420,10 +17059,10 @@ type ImportInstanceLaunchSpecification struct { Placement *Placement `locationName:"placement" type:"structure"` // [EC2-VPC] An available IP address from the IP address range of the subnet. - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` // [EC2-VPC] The ID of the subnet in which to launch the instance. - SubnetID *string `locationName:"subnetId" type:"string"` + SubnetId *string `locationName:"subnetId" type:"string"` // The Base64-encoded MIME user data to be made available to the instance. UserData *UserData `locationName:"userData" type:"structure"` @@ -14435,6 +17074,16 @@ type metadataImportInstanceLaunchSpecification struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportInstanceLaunchSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportInstanceLaunchSpecification) GoString() string { + return s.String() +} + type ImportInstanceOutput struct { // Information about the conversion task. ConversionTask *ConversionTask `locationName:"conversionTask" type:"structure"` @@ -14446,16 +17095,26 @@ type metadataImportInstanceOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportInstanceOutput) GoString() string { + return s.String() +} + // Describes an import instance task. type ImportInstanceTaskDetails struct { // A description of the task. Description *string `locationName:"description" type:"string"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The instance operating system. - Platform *string `locationName:"platform" type:"string"` + Platform *string `locationName:"platform" type:"string" enum:"PlatformValues"` // One or more volumes. Volumes []*ImportInstanceVolumeDetailItem `locationName:"volumes" locationNameList:"item" type:"list" required:"true"` @@ -14467,6 +17126,16 @@ type metadataImportInstanceTaskDetails struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportInstanceTaskDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportInstanceTaskDetails) GoString() string { + return s.String() +} + // Describes an import volume task. type ImportInstanceVolumeDetailItem struct { // The Availability Zone where the resulting instance will reside. @@ -14497,6 +17166,16 @@ type metadataImportInstanceVolumeDetailItem struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportInstanceVolumeDetailItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportInstanceVolumeDetailItem) GoString() string { + return s.String() +} + type ImportKeyPairInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -14518,6 +17197,16 @@ type metadataImportKeyPairInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportKeyPairInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportKeyPairInput) GoString() string { + return s.String() +} + type ImportKeyPairOutput struct { // The MD5 public key fingerprint as specified in section 4 of RFC 4716. KeyFingerprint *string `locationName:"keyFingerprint" type:"string"` @@ -14532,6 +17221,16 @@ type metadataImportKeyPairOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportKeyPairOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportKeyPairOutput) GoString() string { + return s.String() +} + type ImportSnapshotInput struct { // The client-specific data. ClientData *ClientData `type:"structure"` @@ -14561,12 +17260,22 @@ type metadataImportSnapshotInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportSnapshotInput) GoString() string { + return s.String() +} + type ImportSnapshotOutput struct { // A description of the import snapshot task. Description *string `locationName:"description" type:"string"` // The ID of the import snapshot task. - ImportTaskID *string `locationName:"importTaskId" type:"string"` + ImportTaskId *string `locationName:"importTaskId" type:"string"` // Information about the import snapshot task. SnapshotTaskDetail *SnapshotTaskDetail `locationName:"snapshotTaskDetail" type:"structure"` @@ -14578,13 +17287,23 @@ type metadataImportSnapshotOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportSnapshotOutput) GoString() string { + return s.String() +} + // Describes an import snapshot task. type ImportSnapshotTask struct { // A description of the import snapshot task. Description *string `locationName:"description" type:"string"` // The ID of the import snapshot task. - ImportTaskID *string `locationName:"importTaskId" type:"string"` + ImportTaskId *string `locationName:"importTaskId" type:"string"` // Describes an import snapshot task. SnapshotTaskDetail *SnapshotTaskDetail `locationName:"snapshotTaskDetail" type:"structure"` @@ -14596,6 +17315,16 @@ type metadataImportSnapshotTask struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportSnapshotTask) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportSnapshotTask) GoString() string { + return s.String() +} + type ImportVolumeInput struct { // The Availability Zone for the resulting EBS volume. AvailabilityZone *string `locationName:"availabilityZone" type:"string" required:"true"` @@ -14622,6 +17351,16 @@ type metadataImportVolumeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportVolumeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportVolumeInput) GoString() string { + return s.String() +} + type ImportVolumeOutput struct { // Information about the conversion task. ConversionTask *ConversionTask `locationName:"conversionTask" type:"structure"` @@ -14633,6 +17372,16 @@ type metadataImportVolumeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportVolumeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportVolumeOutput) GoString() string { + return s.String() +} + // Describes an import volume task. type ImportVolumeTaskDetails struct { // The Availability Zone where the resulting volume will reside. @@ -14657,14 +17406,24 @@ type metadataImportVolumeTaskDetails struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ImportVolumeTaskDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportVolumeTaskDetails) GoString() string { + return s.String() +} + // Describes an instance. type Instance struct { // The AMI launch index, which can be used to find this instance in the launch // group. - AMILaunchIndex *int64 `locationName:"amiLaunchIndex" type:"integer"` + AmiLaunchIndex *int64 `locationName:"amiLaunchIndex" type:"integer"` // The architecture of the image. - Architecture *string `locationName:"architecture" type:"string"` + Architecture *string `locationName:"architecture" type:"string" enum:"ArchitectureValues"` // Any block device mapping entries for the instance. BlockDeviceMappings []*InstanceBlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` @@ -14677,28 +17436,28 @@ type Instance struct { // stack to provide optimal I/O performance. This optimization isn't available // with all instance types. Additional usage charges apply when using an EBS // Optimized instance. - EBSOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` // The hypervisor type of the instance. - Hypervisor *string `locationName:"hypervisor" type:"string"` + Hypervisor *string `locationName:"hypervisor" type:"string" enum:"HypervisorType"` // The IAM instance profile associated with the instance. - IAMInstanceProfile *IAMInstanceProfile `locationName:"iamInstanceProfile" type:"structure"` + IamInstanceProfile *IamInstanceProfile `locationName:"iamInstanceProfile" type:"structure"` // The ID of the AMI used to launch the instance. - ImageID *string `locationName:"imageId" type:"string"` + ImageId *string `locationName:"imageId" type:"string"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // Indicates whether this is a Spot Instance. - InstanceLifecycle *string `locationName:"instanceLifecycle" type:"string"` + InstanceLifecycle *string `locationName:"instanceLifecycle" type:"string" enum:"InstanceLifecycleType"` // The instance type. - InstanceType *string `locationName:"instanceType" type:"string"` + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` // The kernel associated with this instance. - KernelID *string `locationName:"kernelId" type:"string"` + KernelId *string `locationName:"kernelId" type:"string"` // The name of the key pair, if this instance was launched with an associated // key pair. @@ -14717,38 +17476,35 @@ type Instance struct { Placement *Placement `locationName:"placement" type:"structure"` // The value is Windows for Windows instances; otherwise blank. - Platform *string `locationName:"platform" type:"string"` + Platform *string `locationName:"platform" type:"string" enum:"PlatformValues"` // The private DNS name assigned to the instance. This DNS name can only be // used inside the Amazon EC2 network. This name is not available until the // instance enters the running state. - PrivateDNSName *string `locationName:"privateDnsName" type:"string"` + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` // The private IP address assigned to the instance. - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` // The product codes attached to this instance. ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` // The public DNS name assigned to the instance. This name is not available // until the instance enters the running state. - PublicDNSName *string `locationName:"dnsName" type:"string"` + PublicDnsName *string `locationName:"dnsName" type:"string"` // The public IP address assigned to the instance. - PublicIPAddress *string `locationName:"ipAddress" type:"string"` + PublicIpAddress *string `locationName:"ipAddress" type:"string"` // The RAM disk associated with this instance. - RAMDiskID *string `locationName:"ramdiskId" type:"string"` + RamdiskId *string `locationName:"ramdiskId" type:"string"` // The root device name (for example, /dev/sda1 or /dev/xvda). RootDeviceName *string `locationName:"rootDeviceName" type:"string"` // The root device type used by the AMI. The AMI can use an EBS volume or an // instance store volume. - RootDeviceType *string `locationName:"rootDeviceType" type:"string"` - - // Specifies whether enhanced networking is enabled. - SRIOVNetSupport *string `locationName:"sriovNetSupport" type:"string"` + RootDeviceType *string `locationName:"rootDeviceType" type:"string" enum:"DeviceType"` // One or more security groups for the instance. SecurityGroups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` @@ -14762,7 +17518,10 @@ type Instance struct { SourceDestCheck *bool `locationName:"sourceDestCheck" type:"boolean"` // The ID of the Spot Instance request. - SpotInstanceRequestID *string `locationName:"spotInstanceRequestId" type:"string"` + SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` + + // Specifies whether enhanced networking is enabled. + SriovNetSupport *string `locationName:"sriovNetSupport" type:"string"` // The current state of the instance. State *InstanceState `locationName:"instanceState" type:"structure"` @@ -14774,16 +17533,16 @@ type Instance struct { StateTransitionReason *string `locationName:"reason" type:"string"` // The ID of the subnet in which the instance is running. - SubnetID *string `locationName:"subnetId" type:"string"` + SubnetId *string `locationName:"subnetId" type:"string"` // Any tags assigned to the instance. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` - // The ID of the VPC in which the instance is running. - VPCID *string `locationName:"vpcId" type:"string"` - // The virtualization type of the instance. - VirtualizationType *string `locationName:"virtualizationType" type:"string"` + VirtualizationType *string `locationName:"virtualizationType" type:"string" enum:"VirtualizationType"` + + // The ID of the VPC in which the instance is running. + VpcId *string `locationName:"vpcId" type:"string"` metadataInstance `json:"-" xml:"-"` } @@ -14792,6 +17551,16 @@ type metadataInstance struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Instance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Instance) GoString() string { + return s.String() +} + // Describes a block device mapping. type InstanceBlockDeviceMapping struct { // The device name exposed to the instance (for example, /dev/sdh or xvdh). @@ -14799,7 +17568,7 @@ type InstanceBlockDeviceMapping struct { // Parameters used to automatically set up EBS volumes when the instance is // launched. - EBS *EBSInstanceBlockDevice `locationName:"ebs" type:"structure"` + Ebs *EbsInstanceBlockDevice `locationName:"ebs" type:"structure"` metadataInstanceBlockDeviceMapping `json:"-" xml:"-"` } @@ -14808,6 +17577,16 @@ type metadataInstanceBlockDeviceMapping struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceBlockDeviceMapping) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceBlockDeviceMapping) GoString() string { + return s.String() +} + // Describes a block device mapping entry. type InstanceBlockDeviceMappingSpecification struct { // The device name exposed to the instance (for example, /dev/sdh or xvdh). @@ -14815,7 +17594,7 @@ type InstanceBlockDeviceMappingSpecification struct { // Parameters used to automatically set up EBS volumes when the instance is // launched. - EBS *EBSInstanceBlockDeviceSpecification `locationName:"ebs" type:"structure"` + Ebs *EbsInstanceBlockDeviceSpecification `locationName:"ebs" type:"structure"` // suppress the specified device included in the block device mapping. NoDevice *string `locationName:"noDevice" type:"string"` @@ -14830,13 +17609,23 @@ type metadataInstanceBlockDeviceMappingSpecification struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceBlockDeviceMappingSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceBlockDeviceMappingSpecification) GoString() string { + return s.String() +} + // Describes a Reserved Instance listing state. type InstanceCount struct { // The number of listed Reserved Instances in the state specified by the state. InstanceCount *int64 `locationName:"instanceCount" type:"integer"` // The states of the listed Reserved Instances. - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"ListingState"` metadataInstanceCount `json:"-" xml:"-"` } @@ -14845,13 +17634,23 @@ type metadataInstanceCount struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceCount) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceCount) GoString() string { + return s.String() +} + // Describes an instance to export. type InstanceExportDetails struct { // The ID of the resource being exported. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The target virtualization environment. - TargetEnvironment *string `locationName:"targetEnvironment" type:"string"` + TargetEnvironment *string `locationName:"targetEnvironment" type:"string" enum:"ExportEnvironment"` metadataInstanceExportDetails `json:"-" xml:"-"` } @@ -14860,10 +17659,20 @@ type metadataInstanceExportDetails struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceExportDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceExportDetails) GoString() string { + return s.String() +} + // Describes the monitoring information of the instance. type InstanceMonitoring struct { // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The monitoring information. Monitoring *Monitoring `locationName:"monitoring" type:"structure"` @@ -14875,6 +17684,16 @@ type metadataInstanceMonitoring struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceMonitoring) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceMonitoring) GoString() string { + return s.String() +} + // Describes a network interface. type InstanceNetworkInterface struct { // The association information for an Elastic IP associated with the network @@ -14891,34 +17710,34 @@ type InstanceNetworkInterface struct { Groups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` // The MAC address. - MACAddress *string `locationName:"macAddress" type:"string"` + MacAddress *string `locationName:"macAddress" type:"string"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` // The ID of the AWS account that created the network interface. - OwnerID *string `locationName:"ownerId" type:"string"` + OwnerId *string `locationName:"ownerId" type:"string"` // The private DNS name. - PrivateDNSName *string `locationName:"privateDnsName" type:"string"` + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` // The IP address of the network interface within the subnet. - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` // The private IP addresses associated with the network interface. - PrivateIPAddresses []*InstancePrivateIPAddress `locationName:"privateIpAddressesSet" locationNameList:"item" type:"list"` + PrivateIpAddresses []*InstancePrivateIpAddress `locationName:"privateIpAddressesSet" locationNameList:"item" type:"list"` // Indicates whether to validate network traffic to or from this network interface. SourceDestCheck *bool `locationName:"sourceDestCheck" type:"boolean"` // The status of the network interface. - Status *string `locationName:"status" type:"string"` + Status *string `locationName:"status" type:"string" enum:"NetworkInterfaceStatus"` // The ID of the subnet. - SubnetID *string `locationName:"subnetId" type:"string"` + SubnetId *string `locationName:"subnetId" type:"string"` // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string"` + VpcId *string `locationName:"vpcId" type:"string"` metadataInstanceNetworkInterface `json:"-" xml:"-"` } @@ -14927,16 +17746,26 @@ type metadataInstanceNetworkInterface struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceNetworkInterface) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceNetworkInterface) GoString() string { + return s.String() +} + // Describes association information for an Elastic IP address. type InstanceNetworkInterfaceAssociation struct { // The ID of the owner of the Elastic IP address. - IPOwnerID *string `locationName:"ipOwnerId" type:"string"` + IpOwnerId *string `locationName:"ipOwnerId" type:"string"` // The public DNS name. - PublicDNSName *string `locationName:"publicDnsName" type:"string"` + PublicDnsName *string `locationName:"publicDnsName" type:"string"` // The public IP address or Elastic IP address bound to the network interface. - PublicIP *string `locationName:"publicIp" type:"string"` + PublicIp *string `locationName:"publicIp" type:"string"` metadataInstanceNetworkInterfaceAssociation `json:"-" xml:"-"` } @@ -14945,13 +17774,23 @@ type metadataInstanceNetworkInterfaceAssociation struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceNetworkInterfaceAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceNetworkInterfaceAssociation) GoString() string { + return s.String() +} + // Describes a network interface attachment. type InstanceNetworkInterfaceAttachment struct { // The time stamp when the attachment initiated. AttachTime *time.Time `locationName:"attachTime" type:"timestamp" timestampFormat:"iso8601"` // The ID of the network interface attachment. - AttachmentID *string `locationName:"attachmentId" type:"string"` + AttachmentId *string `locationName:"attachmentId" type:"string"` // Indicates whether the network interface is deleted when the instance is terminated. DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` @@ -14960,7 +17799,7 @@ type InstanceNetworkInterfaceAttachment struct { DeviceIndex *int64 `locationName:"deviceIndex" type:"integer"` // The attachment state. - Status *string `locationName:"status" type:"string"` + Status *string `locationName:"status" type:"string" enum:"AttachmentStatus"` metadataInstanceNetworkInterfaceAttachment `json:"-" xml:"-"` } @@ -14969,6 +17808,16 @@ type metadataInstanceNetworkInterfaceAttachment struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceNetworkInterfaceAttachment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceNetworkInterfaceAttachment) GoString() string { + return s.String() +} + // Describes a network interface. type InstanceNetworkInterfaceSpecification struct { // Indicates whether to assign a public IP address to an instance you launch @@ -14976,7 +17825,7 @@ type InstanceNetworkInterfaceSpecification struct { // for eth0, and can only be assigned to a new network interface, not an existing // one. You cannot specify more than one network interface in the request. If // launching into a default subnet, the default value is true. - AssociatePublicIPAddress *bool `locationName:"associatePublicIpAddress" type:"boolean"` + AssociatePublicIpAddress *bool `locationName:"associatePublicIpAddress" type:"boolean"` // If set to true, the interface is deleted when the instance is terminated. // You can specify true only if creating a new network interface when launching @@ -14997,24 +17846,24 @@ type InstanceNetworkInterfaceSpecification struct { Groups []*string `locationName:"SecurityGroupId" locationNameList:"SecurityGroupId" type:"list"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` // The private IP address of the network interface. Applies only if creating // a network interface when launching an instance. - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` // One or more private IP addresses to assign to the network interface. Only // one private IP address can be designated as primary. - PrivateIPAddresses []*PrivateIPAddressSpecification `locationName:"privateIpAddressesSet" queryName:"PrivateIpAddresses" locationNameList:"item" type:"list"` + PrivateIpAddresses []*PrivateIpAddressSpecification `locationName:"privateIpAddressesSet" queryName:"PrivateIpAddresses" locationNameList:"item" type:"list"` // The number of secondary private IP addresses. You can't specify this option // and specify more than one private IP address using the private IP addresses // option. - SecondaryPrivateIPAddressCount *int64 `locationName:"secondaryPrivateIpAddressCount" type:"integer"` + SecondaryPrivateIpAddressCount *int64 `locationName:"secondaryPrivateIpAddressCount" type:"integer"` // The ID of the subnet associated with the network string. Applies only if // creating a network interface when launching an instance. - SubnetID *string `locationName:"subnetId" type:"string"` + SubnetId *string `locationName:"subnetId" type:"string"` metadataInstanceNetworkInterfaceSpecification `json:"-" xml:"-"` } @@ -15023,8 +17872,18 @@ type metadataInstanceNetworkInterfaceSpecification struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceNetworkInterfaceSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceNetworkInterfaceSpecification) GoString() string { + return s.String() +} + // Describes a private IP address. -type InstancePrivateIPAddress struct { +type InstancePrivateIpAddress struct { // The association information for an Elastic IP address for the network interface. Association *InstanceNetworkInterfaceAssociation `locationName:"association" type:"structure"` @@ -15033,18 +17892,28 @@ type InstancePrivateIPAddress struct { Primary *bool `locationName:"primary" type:"boolean"` // The private DNS name. - PrivateDNSName *string `locationName:"privateDnsName" type:"string"` + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` // The private IP address of the network interface. - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` - metadataInstancePrivateIPAddress `json:"-" xml:"-"` + metadataInstancePrivateIpAddress `json:"-" xml:"-"` } -type metadataInstancePrivateIPAddress struct { +type metadataInstancePrivateIpAddress struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstancePrivateIpAddress) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstancePrivateIpAddress) GoString() string { + return s.String() +} + // Describes the current state of the instance. type InstanceState struct { // The low byte represents the state. The high byte is an opaque internal value @@ -15064,7 +17933,7 @@ type InstanceState struct { Code *int64 `locationName:"code" type:"integer"` // The current state of the instance. - Name *string `locationName:"name" type:"string"` + Name *string `locationName:"name" type:"string" enum:"InstanceStateName"` metadataInstanceState `json:"-" xml:"-"` } @@ -15073,13 +17942,23 @@ type metadataInstanceState struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceState) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceState) GoString() string { + return s.String() +} + // Describes an instance state change. type InstanceStateChange struct { // The current state of the instance. CurrentState *InstanceState `locationName:"currentState" type:"structure"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The previous state of the instance. PreviousState *InstanceState `locationName:"previousState" type:"structure"` @@ -15091,6 +17970,16 @@ type metadataInstanceStateChange struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceStateChange) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceStateChange) GoString() string { + return s.String() +} + // Describes the status of an instance. type InstanceStatus struct { // The Availability Zone of the instance. @@ -15100,7 +17989,7 @@ type InstanceStatus struct { Events []*InstanceStatusEvent `locationName:"eventsSet" locationNameList:"item" type:"list"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The intended state of the instance. DescribeInstanceStatus requires that // an instance be in the running state. @@ -15122,6 +18011,16 @@ type metadataInstanceStatus struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceStatus) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceStatus) GoString() string { + return s.String() +} + // Describes the instance status. type InstanceStatusDetails struct { // The time when a status check failed. For an instance that was launched and @@ -15129,10 +18028,10 @@ type InstanceStatusDetails struct { ImpairedSince *time.Time `locationName:"impairedSince" type:"timestamp" timestampFormat:"iso8601"` // The type of instance status. - Name *string `locationName:"name" type:"string"` + Name *string `locationName:"name" type:"string" enum:"StatusName"` // The status. - Status *string `locationName:"status" type:"string"` + Status *string `locationName:"status" type:"string" enum:"StatusType"` metadataInstanceStatusDetails `json:"-" xml:"-"` } @@ -15141,10 +18040,20 @@ type metadataInstanceStatusDetails struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceStatusDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceStatusDetails) GoString() string { + return s.String() +} + // Describes a scheduled event for an instance. type InstanceStatusEvent struct { // The event code. - Code *string `locationName:"code" type:"string"` + Code *string `locationName:"code" type:"string" enum:"EventCode"` // A description of the event. // @@ -15166,13 +18075,23 @@ type metadataInstanceStatusEvent struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceStatusEvent) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceStatusEvent) GoString() string { + return s.String() +} + // Describes the status of an instance. type InstanceStatusSummary struct { // The system instance health or application instance health. Details []*InstanceStatusDetails `locationName:"details" locationNameList:"item" type:"list"` // The status. - Status *string `locationName:"status" type:"string"` + Status *string `locationName:"status" type:"string" enum:"SummaryStatus"` metadataInstanceStatusSummary `json:"-" xml:"-"` } @@ -15181,13 +18100,23 @@ type metadataInstanceStatusSummary struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceStatusSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceStatusSummary) GoString() string { + return s.String() +} + // Describes an Internet gateway. type InternetGateway struct { // Any VPCs attached to the Internet gateway. Attachments []*InternetGatewayAttachment `locationName:"attachmentSet" locationNameList:"item" type:"list"` // The ID of the Internet gateway. - InternetGatewayID *string `locationName:"internetGatewayId" type:"string"` + InternetGatewayId *string `locationName:"internetGatewayId" type:"string"` // Any tags assigned to the Internet gateway. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` @@ -15199,13 +18128,23 @@ type metadataInternetGateway struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InternetGateway) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InternetGateway) GoString() string { + return s.String() +} + // Describes the attachment of a VPC to an Internet gateway. type InternetGatewayAttachment struct { // The current state of the attachment. - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"AttachmentStatus"` // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string"` + VpcId *string `locationName:"vpcId" type:"string"` metadataInternetGatewayAttachment `json:"-" xml:"-"` } @@ -15214,6 +18153,88 @@ type metadataInternetGatewayAttachment struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InternetGatewayAttachment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InternetGatewayAttachment) GoString() string { + return s.String() +} + +// Describes a security group rule. +type IpPermission struct { + // The start of port range for the TCP and UDP protocols, or an ICMP type number. + // A value of -1 indicates all ICMP types. + FromPort *int64 `locationName:"fromPort" type:"integer"` + + // The protocol. + // + // When you call DescribeSecurityGroups, the protocol value returned is the + // number. Exception: For TCP, UDP, and ICMP, the value returned is the name + // (for example, tcp, udp, or icmp). For a list of protocol numbers, see Protocol + // Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml). + // (VPC only) When you call AuthorizeSecurityGroupIngress, you can use -1 to + // specify all. + IpProtocol *string `locationName:"ipProtocol" type:"string"` + + // One or more IP ranges. + IpRanges []*IpRange `locationName:"ipRanges" locationNameList:"item" type:"list"` + + // (Valid for AuthorizeSecurityGroupEgress, RevokeSecurityGroupEgress and DescribeSecurityGroups + // only) One or more prefix list IDs for an AWS service. In an AuthorizeSecurityGroupEgress + // request, this is the AWS service that you want to access through a VPC endpoint + // from instances associated with the security group. + PrefixListIds []*PrefixListId `locationName:"prefixListIds" locationNameList:"item" type:"list"` + + // The end of port range for the TCP and UDP protocols, or an ICMP code. A value + // of -1 indicates all ICMP codes for the specified ICMP type. + ToPort *int64 `locationName:"toPort" type:"integer"` + + // One or more security group and AWS account ID pairs. + UserIdGroupPairs []*UserIdGroupPair `locationName:"groups" locationNameList:"item" type:"list"` + + metadataIpPermission `json:"-" xml:"-"` +} + +type metadataIpPermission struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s IpPermission) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IpPermission) GoString() string { + return s.String() +} + +// Describes an IP range. +type IpRange struct { + // The CIDR range. You can either specify a CIDR range or a source security + // group, not both. + CidrIp *string `locationName:"cidrIp" type:"string"` + + metadataIpRange `json:"-" xml:"-"` +} + +type metadataIpRange struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s IpRange) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IpRange) GoString() string { + return s.String() +} + // Describes a key pair. type KeyPairInfo struct { // If you used CreateKeyPair to create the key pair, this is the SHA-1 digest @@ -15232,13 +18253,23 @@ type metadataKeyPairInfo struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s KeyPairInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s KeyPairInfo) GoString() string { + return s.String() +} + // Describes a launch permission. type LaunchPermission struct { // The name of the group. - Group *string `locationName:"group" type:"string"` + Group *string `locationName:"group" type:"string" enum:"PermissionGroup"` // The AWS account ID. - UserID *string `locationName:"userId" type:"string"` + UserId *string `locationName:"userId" type:"string"` metadataLaunchPermission `json:"-" xml:"-"` } @@ -15247,6 +18278,16 @@ type metadataLaunchPermission struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s LaunchPermission) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchPermission) GoString() string { + return s.String() +} + // Describes a launch permission modification. type LaunchPermissionModifications struct { // The AWS account ID to add to the list of launch permissions for the AMI. @@ -15263,6 +18304,16 @@ type metadataLaunchPermissionModifications struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s LaunchPermissionModifications) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchPermissionModifications) GoString() string { + return s.String() +} + // Describes the launch specification for an instance. type LaunchSpecification struct { // Deprecated. @@ -15278,19 +18329,19 @@ type LaunchSpecification struct { // Optimized instance. // // Default: false - EBSOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` // The IAM instance profile. - IAMInstanceProfile *IAMInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` + IamInstanceProfile *IamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` // The ID of the AMI. - ImageID *string `locationName:"imageId" type:"string"` + ImageId *string `locationName:"imageId" type:"string"` // The instance type. - InstanceType *string `locationName:"instanceType" type:"string"` + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` // The ID of the kernel. - KernelID *string `locationName:"kernelId" type:"string"` + KernelId *string `locationName:"kernelId" type:"string"` // The name of the key pair. KeyName *string `locationName:"keyName" type:"string"` @@ -15305,7 +18356,7 @@ type LaunchSpecification struct { Placement *SpotPlacement `locationName:"placement" type:"structure"` // The ID of the RAM disk. - RAMDiskID *string `locationName:"ramdiskId" type:"string"` + RamdiskId *string `locationName:"ramdiskId" type:"string"` // One or more security groups. To request an instance in a nondefault VPC, // you must specify the ID of the security group. To request an instance in @@ -15314,7 +18365,7 @@ type LaunchSpecification struct { SecurityGroups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` // The ID of the subnet in which to launch the instance. - SubnetID *string `locationName:"subnetId" type:"string"` + SubnetId *string `locationName:"subnetId" type:"string"` // The Base64-encoded MIME user data to make available to the instances. UserData *string `locationName:"userData" type:"string"` @@ -15326,6 +18377,16 @@ type metadataLaunchSpecification struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s LaunchSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchSpecification) GoString() string { + return s.String() +} + type ModifyImageAttributeInput struct { // The name of the attribute to modify. Attribute *string `type:"string"` @@ -15340,13 +18401,13 @@ type ModifyImageAttributeInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the AMI. - ImageID *string `locationName:"ImageId" type:"string" required:"true"` + ImageId *string `type:"string" required:"true"` // A launch permission modification. LaunchPermission *LaunchPermissionModifications `type:"structure"` // The operation type. - OperationType *string `type:"string"` + OperationType *string `type:"string" enum:"OperationType"` // One or more product codes. After you add a product code to an AMI, it can't // be removed. This is only valid when modifying the productCodes attribute. @@ -15358,7 +18419,7 @@ type ModifyImageAttributeInput struct { // One or more AWS account IDs. This is only valid when modifying the launchPermission // attribute. - UserIDs []*string `locationName:"UserId" locationNameList:"UserId" type:"list"` + UserIds []*string `locationName:"UserId" locationNameList:"UserId" type:"list"` // The value of the attribute being modified. This is only valid when modifying // the description attribute. @@ -15371,6 +18432,16 @@ type metadataModifyImageAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifyImageAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyImageAttributeInput) GoString() string { + return s.String() +} + type ModifyImageAttributeOutput struct { metadataModifyImageAttributeOutput `json:"-" xml:"-"` } @@ -15379,9 +18450,19 @@ type metadataModifyImageAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifyImageAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyImageAttributeOutput) GoString() string { + return s.String() +} + type ModifyInstanceAttributeInput struct { // The name of the attribute. - Attribute *string `locationName:"attribute" type:"string"` + Attribute *string `locationName:"attribute" type:"string" enum:"InstanceAttributeName"` // Modifies the DeleteOnTermination attribute for volumes that are currently // attached. The volume must be owned by the caller. If no value is specified @@ -15395,8 +18476,9 @@ type ModifyInstanceAttributeInput struct { BlockDeviceMappings []*InstanceBlockDeviceMappingSpecification `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` // If the value is true, you can't terminate the instance using the Amazon EC2 - // console, CLI, or API; otherwise, you can. - DisableAPITermination *AttributeBooleanValue `locationName:"disableApiTermination" type:"structure"` + // console, CLI, or API; otherwise, you can. You cannot use this paramater for + // Spot Instances. + DisableApiTermination *AttributeBooleanValue `locationName:"disableApiTermination" type:"structure"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -15409,7 +18491,7 @@ type ModifyInstanceAttributeInput struct { // stack to provide optimal EBS I/O performance. This optimization isn't available // with all instance types. Additional usage charges apply when using an EBS // Optimized instance. - EBSOptimized *AttributeBooleanValue `locationName:"ebsOptimized" type:"structure"` + EbsOptimized *AttributeBooleanValue `locationName:"ebsOptimized" type:"structure"` // [EC2-VPC] Changes the security groups of the instance. You must specify at // least one security group, even if it's just the default security group for @@ -15417,7 +18499,7 @@ type ModifyInstanceAttributeInput struct { Groups []*string `locationName:"GroupId" locationNameList:"groupId" type:"list"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string" required:"true"` + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` // Specifies whether an instance stops or terminates when you initiate shutdown // from the instance (using the operating system command for system shutdown). @@ -15436,7 +18518,12 @@ type ModifyInstanceAttributeInput struct { // Changes the instance's RAM disk to the specified value. We recommend that // you use PV-GRUB instead of kernels and RAM disks. For more information, see // PV-GRUB (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedKernels.html). - RAMDisk *AttributeValue `locationName:"ramdisk" type:"structure"` + Ramdisk *AttributeValue `locationName:"ramdisk" type:"structure"` + + // Specifies whether source/destination checking is enabled. A value of true + // means that checking is enabled, and false means checking is disabled. This + // value must be false for a NAT instance to perform NAT. + SourceDestCheck *AttributeBooleanValue `type:"structure"` // Set to simple to enable enhanced networking for the instance. // @@ -15444,18 +18531,13 @@ type ModifyInstanceAttributeInput struct { // // This option is supported only for HVM instances. Specifying this option // with a PV instance can make it unreachable. - SRIOVNetSupport *AttributeValue `locationName:"sriovNetSupport" type:"structure"` - - // Specifies whether source/destination checking is enabled. A value of true - // means that checking is enabled, and false means checking is disabled. This - // value must be false for a NAT instance to perform NAT. - SourceDestCheck *AttributeBooleanValue `type:"structure"` + SriovNetSupport *AttributeValue `locationName:"sriovNetSupport" type:"structure"` // Changes the instance's user data to the specified value. UserData *BlobAttributeValue `locationName:"userData" type:"structure"` // A new value for the attribute. Use only with the kernel, ramdisk, userData, - // disableApiTermination, or intanceInitiateShutdownBehavior attribute. + // disableApiTermination, or instanceInitiatedShutdownBehavior attribute. Value *string `locationName:"value" type:"string"` metadataModifyInstanceAttributeInput `json:"-" xml:"-"` @@ -15465,6 +18547,16 @@ type metadataModifyInstanceAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifyInstanceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyInstanceAttributeInput) GoString() string { + return s.String() +} + type ModifyInstanceAttributeOutput struct { metadataModifyInstanceAttributeOutput `json:"-" xml:"-"` } @@ -15473,6 +18565,16 @@ type metadataModifyInstanceAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifyInstanceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyInstanceAttributeOutput) GoString() string { + return s.String() +} + type ModifyNetworkInterfaceAttributeInput struct { // Information about the interface attachment. If modifying the 'delete on termination' // attribute, you must specify the ID of the interface attachment. @@ -15494,7 +18596,7 @@ type ModifyNetworkInterfaceAttributeInput struct { Groups []*string `locationName:"SecurityGroupId" locationNameList:"SecurityGroupId" type:"list"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string" required:"true"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` // Indicates whether source/destination checking is enabled. A value of true // means checking is enabled, and false means checking is disabled. This value @@ -15510,6 +18612,16 @@ type metadataModifyNetworkInterfaceAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifyNetworkInterfaceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyNetworkInterfaceAttributeInput) GoString() string { + return s.String() +} + type ModifyNetworkInterfaceAttributeOutput struct { metadataModifyNetworkInterfaceAttributeOutput `json:"-" xml:"-"` } @@ -15518,13 +18630,23 @@ type metadataModifyNetworkInterfaceAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifyNetworkInterfaceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyNetworkInterfaceAttributeOutput) GoString() string { + return s.String() +} + type ModifyReservedInstancesInput struct { // A unique, case-sensitive token you provide to ensure idempotency of your // modification request. For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). ClientToken *string `locationName:"clientToken" type:"string"` // The IDs of the Reserved Instances to modify. - ReservedInstancesIDs []*string `locationName:"ReservedInstancesId" locationNameList:"ReservedInstancesId" type:"list" required:"true"` + ReservedInstancesIds []*string `locationName:"ReservedInstancesId" locationNameList:"ReservedInstancesId" type:"list" required:"true"` // The configuration settings for the Reserved Instances to modify. TargetConfigurations []*ReservedInstancesConfiguration `locationName:"ReservedInstancesConfigurationSetItemType" locationNameList:"item" type:"list" required:"true"` @@ -15536,9 +18658,19 @@ type metadataModifyReservedInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifyReservedInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyReservedInstancesInput) GoString() string { + return s.String() +} + type ModifyReservedInstancesOutput struct { // The ID for the modification. - ReservedInstancesModificationID *string `locationName:"reservedInstancesModificationId" type:"string"` + ReservedInstancesModificationId *string `locationName:"reservedInstancesModificationId" type:"string"` metadataModifyReservedInstancesOutput `json:"-" xml:"-"` } @@ -15547,9 +18679,21 @@ type metadataModifyReservedInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifyReservedInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyReservedInstancesOutput) GoString() string { + return s.String() +} + type ModifySnapshotAttributeInput struct { // The snapshot attribute to modify. - Attribute *string `type:"string"` + // + // Only volume creation permissions may be modified at the customer level. + Attribute *string `type:"string" enum:"SnapshotAttributeName"` // A JSON representation of the snapshot attribute modification. CreateVolumePermission *CreateVolumePermissionModifications `type:"structure"` @@ -15564,13 +18708,13 @@ type ModifySnapshotAttributeInput struct { GroupNames []*string `locationName:"UserGroup" locationNameList:"GroupName" type:"list"` // The type of operation to perform to the attribute. - OperationType *string `type:"string"` + OperationType *string `type:"string" enum:"OperationType"` // The ID of the snapshot. - SnapshotID *string `locationName:"SnapshotId" type:"string" required:"true"` + SnapshotId *string `type:"string" required:"true"` // The account ID to modify for the snapshot. - UserIDs []*string `locationName:"UserId" locationNameList:"UserId" type:"list"` + UserIds []*string `locationName:"UserId" locationNameList:"UserId" type:"list"` metadataModifySnapshotAttributeInput `json:"-" xml:"-"` } @@ -15579,6 +18723,16 @@ type metadataModifySnapshotAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifySnapshotAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifySnapshotAttributeInput) GoString() string { + return s.String() +} + type ModifySnapshotAttributeOutput struct { metadataModifySnapshotAttributeOutput `json:"-" xml:"-"` } @@ -15587,13 +18741,23 @@ type metadataModifySnapshotAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifySnapshotAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifySnapshotAttributeOutput) GoString() string { + return s.String() +} + type ModifySubnetAttributeInput struct { // Specify true to indicate that instances launched into the specified subnet // should be assigned public IP address. - MapPublicIPOnLaunch *AttributeBooleanValue `locationName:"MapPublicIpOnLaunch" type:"structure"` + MapPublicIpOnLaunch *AttributeBooleanValue `type:"structure"` // The ID of the subnet. - SubnetID *string `locationName:"subnetId" type:"string" required:"true"` + SubnetId *string `locationName:"subnetId" type:"string" required:"true"` metadataModifySubnetAttributeInput `json:"-" xml:"-"` } @@ -15602,6 +18766,16 @@ type metadataModifySubnetAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifySubnetAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifySubnetAttributeInput) GoString() string { + return s.String() +} + type ModifySubnetAttributeOutput struct { metadataModifySubnetAttributeOutput `json:"-" xml:"-"` } @@ -15610,41 +18784,119 @@ type metadataModifySubnetAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } -type ModifyVPCAttributeInput struct { +// String returns the string representation +func (s ModifySubnetAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifySubnetAttributeOutput) GoString() string { + return s.String() +} + +type ModifyVolumeAttributeInput struct { + // Indicates whether the volume should be auto-enabled for I/O operations. + AutoEnableIO *AttributeBooleanValue `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `locationName:"dryRun" type:"boolean"` + + // The ID of the volume. + VolumeId *string `type:"string" required:"true"` + + metadataModifyVolumeAttributeInput `json:"-" xml:"-"` +} + +type metadataModifyVolumeAttributeInput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s ModifyVolumeAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVolumeAttributeInput) GoString() string { + return s.String() +} + +type ModifyVolumeAttributeOutput struct { + metadataModifyVolumeAttributeOutput `json:"-" xml:"-"` +} + +type metadataModifyVolumeAttributeOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s ModifyVolumeAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVolumeAttributeOutput) GoString() string { + return s.String() +} + +type ModifyVpcAttributeInput struct { // Indicates whether the instances launched in the VPC get DNS hostnames. If // enabled, instances in the VPC get DNS hostnames; otherwise, they do not. // // You can only enable DNS hostnames if you also enable DNS support. - EnableDNSHostnames *AttributeBooleanValue `locationName:"EnableDnsHostnames" type:"structure"` + EnableDnsHostnames *AttributeBooleanValue `type:"structure"` // Indicates whether the DNS resolution is supported for the VPC. If enabled, // queries to the Amazon provided DNS server at the 169.254.169.253 IP address, // or the reserved IP address at the base of the VPC network range "plus two" // will succeed. If disabled, the Amazon provided DNS service in the VPC that // resolves public DNS hostnames to IP addresses is not enabled. - EnableDNSSupport *AttributeBooleanValue `locationName:"EnableDnsSupport" type:"structure"` + EnableDnsSupport *AttributeBooleanValue `type:"structure"` // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string" required:"true"` + VpcId *string `locationName:"vpcId" type:"string" required:"true"` - metadataModifyVPCAttributeInput `json:"-" xml:"-"` + metadataModifyVpcAttributeInput `json:"-" xml:"-"` } -type metadataModifyVPCAttributeInput struct { +type metadataModifyVpcAttributeInput struct { SDKShapeTraits bool `type:"structure"` } -type ModifyVPCAttributeOutput struct { - metadataModifyVPCAttributeOutput `json:"-" xml:"-"` +// String returns the string representation +func (s ModifyVpcAttributeInput) String() string { + return awsutil.Prettify(s) } -type metadataModifyVPCAttributeOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s ModifyVpcAttributeInput) GoString() string { + return s.String() } -type ModifyVPCEndpointInput struct { +type ModifyVpcAttributeOutput struct { + metadataModifyVpcAttributeOutput `json:"-" xml:"-"` +} + +type metadataModifyVpcAttributeOutput struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s ModifyVpcAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcAttributeOutput) GoString() string { + return s.String() +} + +type ModifyVpcEndpointInput struct { // One or more route tables IDs to associate with the endpoint. - AddRouteTableIDs []*string `locationName:"AddRouteTableId" locationNameList:"item" type:"list"` + AddRouteTableIds []*string `locationName:"AddRouteTableId" locationNameList:"item" type:"list"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -15657,59 +18909,51 @@ type ModifyVPCEndpointInput struct { PolicyDocument *string `type:"string"` // One or more route table IDs to disassociate from the endpoint. - RemoveRouteTableIDs []*string `locationName:"RemoveRouteTableId" locationNameList:"item" type:"list"` + RemoveRouteTableIds []*string `locationName:"RemoveRouteTableId" locationNameList:"item" type:"list"` // Specify true to reset the policy document to the default policy. The default // policy allows access to the service. ResetPolicy *bool `type:"boolean"` // The ID of the endpoint. - VPCEndpointID *string `locationName:"VpcEndpointId" type:"string" required:"true"` + VpcEndpointId *string `type:"string" required:"true"` - metadataModifyVPCEndpointInput `json:"-" xml:"-"` + metadataModifyVpcEndpointInput `json:"-" xml:"-"` } -type metadataModifyVPCEndpointInput struct { +type metadataModifyVpcEndpointInput struct { SDKShapeTraits bool `type:"structure"` } -type ModifyVPCEndpointOutput struct { - // Returns true if the request succeeds; otherwise, it returns an error. - Return *bool `locationName:"return" type:"boolean"` - - metadataModifyVPCEndpointOutput `json:"-" xml:"-"` +// String returns the string representation +func (s ModifyVpcEndpointInput) String() string { + return awsutil.Prettify(s) } -type metadataModifyVPCEndpointOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s ModifyVpcEndpointInput) GoString() string { + return s.String() } -type ModifyVolumeAttributeInput struct { - // Indicates whether the volume should be auto-enabled for I/O operations. - AutoEnableIO *AttributeBooleanValue `type:"structure"` - - // Checks whether you have the required permissions for the action, without - // actually making the request, and provides an error response. If you have - // the required permissions, the error response is DryRunOperation. Otherwise, - // it is UnauthorizedOperation. - DryRun *bool `locationName:"dryRun" type:"boolean"` - - // The ID of the volume. - VolumeID *string `locationName:"VolumeId" type:"string" required:"true"` +type ModifyVpcEndpointOutput struct { + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` - metadataModifyVolumeAttributeInput `json:"-" xml:"-"` + metadataModifyVpcEndpointOutput `json:"-" xml:"-"` } -type metadataModifyVolumeAttributeInput struct { +type metadataModifyVpcEndpointOutput struct { SDKShapeTraits bool `type:"structure"` } -type ModifyVolumeAttributeOutput struct { - metadataModifyVolumeAttributeOutput `json:"-" xml:"-"` +// String returns the string representation +func (s ModifyVpcEndpointOutput) String() string { + return awsutil.Prettify(s) } -type metadataModifyVolumeAttributeOutput struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s ModifyVpcEndpointOutput) GoString() string { + return s.String() } type MonitorInstancesInput struct { @@ -15720,7 +18964,7 @@ type MonitorInstancesInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // One or more instance IDs. - InstanceIDs []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` metadataMonitorInstancesInput `json:"-" xml:"-"` } @@ -15729,6 +18973,16 @@ type metadataMonitorInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s MonitorInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MonitorInstancesInput) GoString() string { + return s.String() +} + type MonitorInstancesOutput struct { // Monitoring information for one or more instances. InstanceMonitorings []*InstanceMonitoring `locationName:"instancesSet" locationNameList:"item" type:"list"` @@ -15740,10 +18994,20 @@ type metadataMonitorInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s MonitorInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MonitorInstancesOutput) GoString() string { + return s.String() +} + // Describes the monitoring for the instance. type Monitoring struct { // Indicates whether monitoring is enabled for the instance. - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"MonitoringState"` metadataMonitoring `json:"-" xml:"-"` } @@ -15752,7 +19016,17 @@ type metadataMonitoring struct { SDKShapeTraits bool `type:"structure"` } -type MoveAddressToVPCInput struct { +// String returns the string representation +func (s Monitoring) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Monitoring) GoString() string { + return s.String() +} + +type MoveAddressToVpcInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -15760,37 +19034,57 @@ type MoveAddressToVPCInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The Elastic IP address. - PublicIP *string `locationName:"publicIp" type:"string" required:"true"` + PublicIp *string `locationName:"publicIp" type:"string" required:"true"` - metadataMoveAddressToVPCInput `json:"-" xml:"-"` + metadataMoveAddressToVpcInput `json:"-" xml:"-"` } -type metadataMoveAddressToVPCInput struct { +type metadataMoveAddressToVpcInput struct { SDKShapeTraits bool `type:"structure"` } -type MoveAddressToVPCOutput struct { +// String returns the string representation +func (s MoveAddressToVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MoveAddressToVpcInput) GoString() string { + return s.String() +} + +type MoveAddressToVpcOutput struct { // The allocation ID for the Elastic IP address. - AllocationID *string `locationName:"allocationId" type:"string"` + AllocationId *string `locationName:"allocationId" type:"string"` // The status of the move of the IP address. - Status *string `locationName:"status" type:"string"` + Status *string `locationName:"status" type:"string" enum:"Status"` - metadataMoveAddressToVPCOutput `json:"-" xml:"-"` + metadataMoveAddressToVpcOutput `json:"-" xml:"-"` } -type metadataMoveAddressToVPCOutput struct { +type metadataMoveAddressToVpcOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s MoveAddressToVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MoveAddressToVpcOutput) GoString() string { + return s.String() +} + // Describes the status of a moving Elastic IP address. type MovingAddressStatus struct { // The status of the Elastic IP address that's being moved to the EC2-VPC platform, // or restored to the EC2-Classic platform. - MoveStatus *string `locationName:"moveStatus" type:"string"` + MoveStatus *string `locationName:"moveStatus" type:"string" enum:"MoveStatus"` // The Elastic IP address. - PublicIP *string `locationName:"publicIp" type:"string"` + PublicIp *string `locationName:"publicIp" type:"string"` metadataMovingAddressStatus `json:"-" xml:"-"` } @@ -15799,62 +19093,92 @@ type metadataMovingAddressStatus struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s MovingAddressStatus) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MovingAddressStatus) GoString() string { + return s.String() +} + // Describes a network ACL. -type NetworkACL struct { +type NetworkAcl struct { // Any associations between the network ACL and one or more subnets - Associations []*NetworkACLAssociation `locationName:"associationSet" locationNameList:"item" type:"list"` + Associations []*NetworkAclAssociation `locationName:"associationSet" locationNameList:"item" type:"list"` // One or more entries (rules) in the network ACL. - Entries []*NetworkACLEntry `locationName:"entrySet" locationNameList:"item" type:"list"` + Entries []*NetworkAclEntry `locationName:"entrySet" locationNameList:"item" type:"list"` // Indicates whether this is the default network ACL for the VPC. IsDefault *bool `locationName:"default" type:"boolean"` // The ID of the network ACL. - NetworkACLID *string `locationName:"networkAclId" type:"string"` + NetworkAclId *string `locationName:"networkAclId" type:"string"` // Any tags assigned to the network ACL. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` // The ID of the VPC for the network ACL. - VPCID *string `locationName:"vpcId" type:"string"` + VpcId *string `locationName:"vpcId" type:"string"` - metadataNetworkACL `json:"-" xml:"-"` + metadataNetworkAcl `json:"-" xml:"-"` } -type metadataNetworkACL struct { +type metadataNetworkAcl struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s NetworkAcl) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkAcl) GoString() string { + return s.String() +} + // Describes an association between a network ACL and a subnet. -type NetworkACLAssociation struct { +type NetworkAclAssociation struct { // The ID of the association between a network ACL and a subnet. - NetworkACLAssociationID *string `locationName:"networkAclAssociationId" type:"string"` + NetworkAclAssociationId *string `locationName:"networkAclAssociationId" type:"string"` // The ID of the network ACL. - NetworkACLID *string `locationName:"networkAclId" type:"string"` + NetworkAclId *string `locationName:"networkAclId" type:"string"` // The ID of the subnet. - SubnetID *string `locationName:"subnetId" type:"string"` + SubnetId *string `locationName:"subnetId" type:"string"` - metadataNetworkACLAssociation `json:"-" xml:"-"` + metadataNetworkAclAssociation `json:"-" xml:"-"` } -type metadataNetworkACLAssociation struct { +type metadataNetworkAclAssociation struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s NetworkAclAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkAclAssociation) GoString() string { + return s.String() +} + // Describes an entry in a network ACL. -type NetworkACLEntry struct { +type NetworkAclEntry struct { // The network range to allow or deny, in CIDR notation. - CIDRBlock *string `locationName:"cidrBlock" type:"string"` + CidrBlock *string `locationName:"cidrBlock" type:"string"` // Indicates whether the rule is an egress rule (applied to traffic leaving // the subnet). Egress *bool `locationName:"egress" type:"boolean"` // ICMP protocol: The ICMP type and code. - ICMPTypeCode *ICMPTypeCode `locationName:"icmpTypeCode" type:"structure"` + IcmpTypeCode *IcmpTypeCode `locationName:"icmpTypeCode" type:"structure"` // TCP or UDP protocols: The range of ports the rule applies to. PortRange *PortRange `locationName:"portRange" type:"structure"` @@ -15863,19 +19187,29 @@ type NetworkACLEntry struct { Protocol *string `locationName:"protocol" type:"string"` // Indicates whether to allow or deny the traffic that matches the rule. - RuleAction *string `locationName:"ruleAction" type:"string"` + RuleAction *string `locationName:"ruleAction" type:"string" enum:"RuleAction"` // The rule number for the entry. ACL entries are processed in ascending order // by rule number. RuleNumber *int64 `locationName:"ruleNumber" type:"integer"` - metadataNetworkACLEntry `json:"-" xml:"-"` + metadataNetworkAclEntry `json:"-" xml:"-"` } -type metadataNetworkACLEntry struct { +type metadataNetworkAclEntry struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s NetworkAclEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkAclEntry) GoString() string { + return s.String() +} + // Describes a network interface. type NetworkInterface struct { // The association information for an Elastic IP associated with the network @@ -15895,26 +19229,26 @@ type NetworkInterface struct { Groups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` // The MAC address. - MACAddress *string `locationName:"macAddress" type:"string"` + MacAddress *string `locationName:"macAddress" type:"string"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` // The AWS account ID of the owner of the network interface. - OwnerID *string `locationName:"ownerId" type:"string"` + OwnerId *string `locationName:"ownerId" type:"string"` // The private DNS name. - PrivateDNSName *string `locationName:"privateDnsName" type:"string"` + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` // The IP address of the network interface within the subnet. - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` // The private IP addresses associated with the network interface. - PrivateIPAddresses []*NetworkInterfacePrivateIPAddress `locationName:"privateIpAddressesSet" locationNameList:"item" type:"list"` + PrivateIpAddresses []*NetworkInterfacePrivateIpAddress `locationName:"privateIpAddressesSet" locationNameList:"item" type:"list"` // The ID of the entity that launched the instance on your behalf (for example, // AWS Management Console or Auto Scaling). - RequesterID *string `locationName:"requesterId" type:"string"` + RequesterId *string `locationName:"requesterId" type:"string"` // Indicates whether the network interface is being managed by AWS. RequesterManaged *bool `locationName:"requesterManaged" type:"boolean"` @@ -15923,16 +19257,16 @@ type NetworkInterface struct { SourceDestCheck *bool `locationName:"sourceDestCheck" type:"boolean"` // The status of the network interface. - Status *string `locationName:"status" type:"string"` + Status *string `locationName:"status" type:"string" enum:"NetworkInterfaceStatus"` // The ID of the subnet. - SubnetID *string `locationName:"subnetId" type:"string"` + SubnetId *string `locationName:"subnetId" type:"string"` // Any tags assigned to the network interface. TagSet []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string"` + VpcId *string `locationName:"vpcId" type:"string"` metadataNetworkInterface `json:"-" xml:"-"` } @@ -15941,22 +19275,32 @@ type metadataNetworkInterface struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s NetworkInterface) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterface) GoString() string { + return s.String() +} + // Describes association information for an Elastic IP address. type NetworkInterfaceAssociation struct { // The allocation ID. - AllocationID *string `locationName:"allocationId" type:"string"` + AllocationId *string `locationName:"allocationId" type:"string"` // The association ID. - AssociationID *string `locationName:"associationId" type:"string"` + AssociationId *string `locationName:"associationId" type:"string"` // The ID of the Elastic IP address owner. - IPOwnerID *string `locationName:"ipOwnerId" type:"string"` + IpOwnerId *string `locationName:"ipOwnerId" type:"string"` // The public DNS name. - PublicDNSName *string `locationName:"publicDnsName" type:"string"` + PublicDnsName *string `locationName:"publicDnsName" type:"string"` // The address of the Elastic IP address bound to the network interface. - PublicIP *string `locationName:"publicIp" type:"string"` + PublicIp *string `locationName:"publicIp" type:"string"` metadataNetworkInterfaceAssociation `json:"-" xml:"-"` } @@ -15965,13 +19309,23 @@ type metadataNetworkInterfaceAssociation struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s NetworkInterfaceAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterfaceAssociation) GoString() string { + return s.String() +} + // Describes a network interface attachment. type NetworkInterfaceAttachment struct { // The timestamp indicating when the attachment initiated. AttachTime *time.Time `locationName:"attachTime" type:"timestamp" timestampFormat:"iso8601"` // The ID of the network interface attachment. - AttachmentID *string `locationName:"attachmentId" type:"string"` + AttachmentId *string `locationName:"attachmentId" type:"string"` // Indicates whether the network interface is deleted when the instance is terminated. DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` @@ -15980,13 +19334,13 @@ type NetworkInterfaceAttachment struct { DeviceIndex *int64 `locationName:"deviceIndex" type:"integer"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The AWS account ID of the owner of the instance. - InstanceOwnerID *string `locationName:"instanceOwnerId" type:"string"` + InstanceOwnerId *string `locationName:"instanceOwnerId" type:"string"` // The attachment state. - Status *string `locationName:"status" type:"string"` + Status *string `locationName:"status" type:"string" enum:"AttachmentStatus"` metadataNetworkInterfaceAttachment `json:"-" xml:"-"` } @@ -15995,10 +19349,20 @@ type metadataNetworkInterfaceAttachment struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s NetworkInterfaceAttachment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterfaceAttachment) GoString() string { + return s.String() +} + // Describes an attachment change. type NetworkInterfaceAttachmentChanges struct { // The ID of the network interface attachment. - AttachmentID *string `locationName:"attachmentId" type:"string"` + AttachmentId *string `locationName:"attachmentId" type:"string"` // Indicates whether the network interface is deleted when the instance is terminated. DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` @@ -16010,8 +19374,18 @@ type metadataNetworkInterfaceAttachmentChanges struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s NetworkInterfaceAttachmentChanges) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterfaceAttachmentChanges) GoString() string { + return s.String() +} + // Describes the private IP address of a network interface. -type NetworkInterfacePrivateIPAddress struct { +type NetworkInterfacePrivateIpAddress struct { // The association information for an Elastic IP address associated with the // network interface. Association *NetworkInterfaceAssociation `locationName:"association" type:"structure"` @@ -16021,30 +19395,50 @@ type NetworkInterfacePrivateIPAddress struct { Primary *bool `locationName:"primary" type:"boolean"` // The private DNS name. - PrivateDNSName *string `locationName:"privateDnsName" type:"string"` + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` // The private IP address. - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` - metadataNetworkInterfacePrivateIPAddress `json:"-" xml:"-"` + metadataNetworkInterfacePrivateIpAddress `json:"-" xml:"-"` } -type metadataNetworkInterfacePrivateIPAddress struct { +type metadataNetworkInterfacePrivateIpAddress struct { SDKShapeTraits bool `type:"structure"` } -type NewDHCPConfiguration struct { +// String returns the string representation +func (s NetworkInterfacePrivateIpAddress) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterfacePrivateIpAddress) GoString() string { + return s.String() +} + +type NewDhcpConfiguration struct { Key *string `locationName:"key" type:"string"` Values []*string `locationName:"Value" locationNameList:"item" type:"list"` - metadataNewDHCPConfiguration `json:"-" xml:"-"` + metadataNewDhcpConfiguration `json:"-" xml:"-"` } -type metadataNewDHCPConfiguration struct { +type metadataNewDhcpConfiguration struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s NewDhcpConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NewDhcpConfiguration) GoString() string { + return s.String() +} + // Describes the placement for the instance. type Placement struct { // The Availability Zone of the instance. @@ -16055,7 +19449,7 @@ type Placement struct { // The tenancy of the instance (if the instance is running in a VPC). An instance // with a tenancy of dedicated runs on single-tenant hardware. - Tenancy *string `locationName:"tenancy" type:"string"` + Tenancy *string `locationName:"tenancy" type:"string" enum:"Tenancy"` metadataPlacement `json:"-" xml:"-"` } @@ -16064,16 +19458,26 @@ type metadataPlacement struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Placement) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Placement) GoString() string { + return s.String() +} + // Describes a placement group. type PlacementGroup struct { // The name of the placement group. GroupName *string `locationName:"groupName" type:"string"` // The state of the placement group. - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"PlacementGroupState"` // The placement strategy. - Strategy *string `locationName:"strategy" type:"string"` + Strategy *string `locationName:"strategy" type:"string" enum:"PlacementStrategy"` metadataPlacementGroup `json:"-" xml:"-"` } @@ -16082,6 +19486,16 @@ type metadataPlacementGroup struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PlacementGroup) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PlacementGroup) GoString() string { + return s.String() +} + // Describes a range of ports. type PortRange struct { // The first port in the range. @@ -16097,13 +19511,23 @@ type metadataPortRange struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PortRange) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PortRange) GoString() string { + return s.String() +} + // Describes prefixes for AWS services. type PrefixList struct { // The IP address range of the AWS service. - CIDRs []*string `locationName:"cidrSet" locationNameList:"item" type:"list"` + Cidrs []*string `locationName:"cidrSet" locationNameList:"item" type:"list"` // The ID of the prefix. - PrefixListID *string `locationName:"prefixListId" type:"string"` + PrefixListId *string `locationName:"prefixListId" type:"string"` // The name of the prefix. PrefixListName *string `locationName:"prefixListName" type:"string"` @@ -16115,18 +19539,38 @@ type metadataPrefixList struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PrefixList) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PrefixList) GoString() string { + return s.String() +} + // The ID of the prefix. -type PrefixListID struct { +type PrefixListId struct { // The ID of the prefix. - PrefixListID *string `locationName:"prefixListId" type:"string"` + PrefixListId *string `locationName:"prefixListId" type:"string"` - metadataPrefixListID `json:"-" xml:"-"` + metadataPrefixListId `json:"-" xml:"-"` } -type metadataPrefixListID struct { +type metadataPrefixListId struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PrefixListId) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PrefixListId) GoString() string { + return s.String() +} + // Describes the price for a Reserved Instance. type PriceSchedule struct { // The current price schedule, as determined by the term remaining for the Reserved @@ -16143,7 +19587,7 @@ type PriceSchedule struct { // The currency for transacting the Reserved Instance resale. At this time, // the only supported currency is USD. - CurrencyCode *string `locationName:"currencyCode" type:"string"` + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` // The fixed price for the term. Price *float64 `locationName:"price" type:"double"` @@ -16159,11 +19603,21 @@ type metadataPriceSchedule struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PriceSchedule) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PriceSchedule) GoString() string { + return s.String() +} + // Describes the price for a Reserved Instance. type PriceScheduleSpecification struct { // The currency for transacting the Reserved Instance resale. At this time, // the only supported currency is USD. - CurrencyCode *string `locationName:"currencyCode" type:"string"` + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` // The fixed price for the term. Price *float64 `locationName:"price" type:"double"` @@ -16179,6 +19633,16 @@ type metadataPriceScheduleSpecification struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PriceScheduleSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PriceScheduleSpecification) GoString() string { + return s.String() +} + // Describes a Reserved Instance offering. type PricingDetail struct { // The number of instances available for the price. @@ -16194,29 +19658,49 @@ type metadataPricingDetail struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PricingDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PricingDetail) GoString() string { + return s.String() +} + // Describes a secondary private IP address for a network interface. -type PrivateIPAddressSpecification struct { +type PrivateIpAddressSpecification struct { // Indicates whether the private IP address is the primary private IP address. // Only one IP address can be designated as primary. Primary *bool `locationName:"primary" type:"boolean"` // The private IP addresses. - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string" required:"true"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string" required:"true"` - metadataPrivateIPAddressSpecification `json:"-" xml:"-"` + metadataPrivateIpAddressSpecification `json:"-" xml:"-"` } -type metadataPrivateIPAddressSpecification struct { +type metadataPrivateIpAddressSpecification struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PrivateIpAddressSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PrivateIpAddressSpecification) GoString() string { + return s.String() +} + // Describes a product code. type ProductCode struct { // The product code. - ProductCodeID *string `locationName:"productCode" type:"string"` + ProductCodeId *string `locationName:"productCode" type:"string"` // The type of product code. - ProductCodeType *string `locationName:"type" type:"string"` + ProductCodeType *string `locationName:"type" type:"string" enum:"ProductCodeValues"` metadataProductCode `json:"-" xml:"-"` } @@ -16225,18 +19709,38 @@ type metadataProductCode struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ProductCode) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ProductCode) GoString() string { + return s.String() +} + // Describes a virtual private gateway propagating route. -type PropagatingVGW struct { +type PropagatingVgw struct { // The ID of the virtual private gateway (VGW). - GatewayID *string `locationName:"gatewayId" type:"string"` + GatewayId *string `locationName:"gatewayId" type:"string"` - metadataPropagatingVGW `json:"-" xml:"-"` + metadataPropagatingVgw `json:"-" xml:"-"` } -type metadataPropagatingVGW struct { +type metadataPropagatingVgw struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PropagatingVgw) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PropagatingVgw) GoString() string { + return s.String() +} + type PurchaseReservedInstancesOfferingInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -16253,7 +19757,7 @@ type PurchaseReservedInstancesOfferingInput struct { LimitPrice *ReservedInstanceLimitPrice `locationName:"limitPrice" type:"structure"` // The ID of the Reserved Instance offering to purchase. - ReservedInstancesOfferingID *string `locationName:"ReservedInstancesOfferingId" type:"string" required:"true"` + ReservedInstancesOfferingId *string `type:"string" required:"true"` metadataPurchaseReservedInstancesOfferingInput `json:"-" xml:"-"` } @@ -16262,9 +19766,19 @@ type metadataPurchaseReservedInstancesOfferingInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PurchaseReservedInstancesOfferingInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PurchaseReservedInstancesOfferingInput) GoString() string { + return s.String() +} + type PurchaseReservedInstancesOfferingOutput struct { // The IDs of the purchased Reserved Instances. - ReservedInstancesID *string `locationName:"reservedInstancesId" type:"string"` + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` metadataPurchaseReservedInstancesOfferingOutput `json:"-" xml:"-"` } @@ -16273,6 +19787,16 @@ type metadataPurchaseReservedInstancesOfferingOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PurchaseReservedInstancesOfferingOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PurchaseReservedInstancesOfferingOutput) GoString() string { + return s.String() +} + type RebootInstancesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -16281,7 +19805,7 @@ type RebootInstancesInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // One or more instance IDs. - InstanceIDs []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` metadataRebootInstancesInput `json:"-" xml:"-"` } @@ -16290,6 +19814,16 @@ type metadataRebootInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RebootInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RebootInstancesInput) GoString() string { + return s.String() +} + type RebootInstancesOutput struct { metadataRebootInstancesOutput `json:"-" xml:"-"` } @@ -16298,13 +19832,23 @@ type metadataRebootInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RebootInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RebootInstancesOutput) GoString() string { + return s.String() +} + // Describes a recurring charge. type RecurringCharge struct { // The amount of the recurring charge. Amount *float64 `locationName:"amount" type:"double"` // The frequency of the recurring charge. - Frequency *string `locationName:"frequency" type:"string"` + Frequency *string `locationName:"frequency" type:"string" enum:"RecurringChargeFrequency"` metadataRecurringCharge `json:"-" xml:"-"` } @@ -16313,6 +19857,16 @@ type metadataRecurringCharge struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RecurringCharge) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RecurringCharge) GoString() string { + return s.String() +} + // Describes a region. type Region struct { // The region service endpoint. @@ -16328,12 +19882,22 @@ type metadataRegion struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Region) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Region) GoString() string { + return s.String() +} + type RegisterImageInput struct { // The architecture of the AMI. // // Default: For Amazon EBS-backed AMIs, i386. For instance store-backed AMIs, // the architecture specified in the manifest file. - Architecture *string `locationName:"architecture" type:"string"` + Architecture *string `locationName:"architecture" type:"string" enum:"ArchitectureValues"` // One or more block device mapping entries. BlockDeviceMappings []*BlockDeviceMapping `locationName:"BlockDeviceMapping" locationNameList:"BlockDeviceMapping" type:"list"` @@ -16351,7 +19915,7 @@ type RegisterImageInput struct { ImageLocation *string `type:"string"` // The ID of the kernel. - KernelID *string `locationName:"kernelId" type:"string"` + KernelId *string `locationName:"kernelId" type:"string"` // A name for your AMI. // @@ -16361,7 +19925,7 @@ type RegisterImageInput struct { Name *string `locationName:"name" type:"string" required:"true"` // The ID of the RAM disk. - RAMDiskID *string `locationName:"ramdiskId" type:"string"` + RamdiskId *string `locationName:"ramdiskId" type:"string"` // The name of the root device (for example, /dev/sda1, or /dev/xvda). RootDeviceName *string `locationName:"rootDeviceName" type:"string"` @@ -16373,7 +19937,7 @@ type RegisterImageInput struct { // // This option is supported only for HVM AMIs. Specifying this option with // a PV AMI can make instances launched from the AMI unreachable. - SRIOVNetSupport *string `locationName:"sriovNetSupport" type:"string"` + SriovNetSupport *string `locationName:"sriovNetSupport" type:"string"` // The type of virtualization. // @@ -16387,9 +19951,19 @@ type metadataRegisterImageInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RegisterImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RegisterImageInput) GoString() string { + return s.String() +} + type RegisterImageOutput struct { // The ID of the newly registered AMI. - ImageID *string `locationName:"imageId" type:"string"` + ImageId *string `locationName:"imageId" type:"string"` metadataRegisterImageOutput `json:"-" xml:"-"` } @@ -16398,7 +19972,17 @@ type metadataRegisterImageOutput struct { SDKShapeTraits bool `type:"structure"` } -type RejectVPCPeeringConnectionInput struct { +// String returns the string representation +func (s RegisterImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RegisterImageOutput) GoString() string { + return s.String() +} + +type RejectVpcPeeringConnectionInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, @@ -16406,29 +19990,49 @@ type RejectVPCPeeringConnectionInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the VPC peering connection. - VPCPeeringConnectionID *string `locationName:"vpcPeeringConnectionId" type:"string" required:"true"` + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string" required:"true"` - metadataRejectVPCPeeringConnectionInput `json:"-" xml:"-"` + metadataRejectVpcPeeringConnectionInput `json:"-" xml:"-"` } -type metadataRejectVPCPeeringConnectionInput struct { +type metadataRejectVpcPeeringConnectionInput struct { SDKShapeTraits bool `type:"structure"` } -type RejectVPCPeeringConnectionOutput struct { +// String returns the string representation +func (s RejectVpcPeeringConnectionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RejectVpcPeeringConnectionInput) GoString() string { + return s.String() +} + +type RejectVpcPeeringConnectionOutput struct { // Returns true if the request succeeds; otherwise, it returns an error. Return *bool `locationName:"return" type:"boolean"` - metadataRejectVPCPeeringConnectionOutput `json:"-" xml:"-"` + metadataRejectVpcPeeringConnectionOutput `json:"-" xml:"-"` } -type metadataRejectVPCPeeringConnectionOutput struct { +type metadataRejectVpcPeeringConnectionOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RejectVpcPeeringConnectionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RejectVpcPeeringConnectionOutput) GoString() string { + return s.String() +} + type ReleaseAddressInput struct { // [EC2-VPC] The allocation ID. Required for EC2-VPC. - AllocationID *string `locationName:"AllocationId" type:"string"` + AllocationId *string `type:"string"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -16437,7 +20041,7 @@ type ReleaseAddressInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // [EC2-Classic] The Elastic IP address. Required for EC2-Classic. - PublicIP *string `locationName:"PublicIp" type:"string"` + PublicIp *string `type:"string"` metadataReleaseAddressInput `json:"-" xml:"-"` } @@ -16446,6 +20050,16 @@ type metadataReleaseAddressInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReleaseAddressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReleaseAddressInput) GoString() string { + return s.String() +} + type ReleaseAddressOutput struct { metadataReleaseAddressOutput `json:"-" xml:"-"` } @@ -16454,10 +20068,20 @@ type metadataReleaseAddressOutput struct { SDKShapeTraits bool `type:"structure"` } -type ReplaceNetworkACLAssociationInput struct { +// String returns the string representation +func (s ReleaseAddressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReleaseAddressOutput) GoString() string { + return s.String() +} + +type ReplaceNetworkAclAssociationInput struct { // The ID of the current association between the original network ACL and the // subnet. - AssociationID *string `locationName:"associationId" type:"string" required:"true"` + AssociationId *string `locationName:"associationId" type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -16466,29 +20090,49 @@ type ReplaceNetworkACLAssociationInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the new network ACL to associate with the subnet. - NetworkACLID *string `locationName:"networkAclId" type:"string" required:"true"` + NetworkAclId *string `locationName:"networkAclId" type:"string" required:"true"` - metadataReplaceNetworkACLAssociationInput `json:"-" xml:"-"` + metadataReplaceNetworkAclAssociationInput `json:"-" xml:"-"` } -type metadataReplaceNetworkACLAssociationInput struct { +type metadataReplaceNetworkAclAssociationInput struct { SDKShapeTraits bool `type:"structure"` } -type ReplaceNetworkACLAssociationOutput struct { +// String returns the string representation +func (s ReplaceNetworkAclAssociationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceNetworkAclAssociationInput) GoString() string { + return s.String() +} + +type ReplaceNetworkAclAssociationOutput struct { // The ID of the new association. - NewAssociationID *string `locationName:"newAssociationId" type:"string"` + NewAssociationId *string `locationName:"newAssociationId" type:"string"` - metadataReplaceNetworkACLAssociationOutput `json:"-" xml:"-"` + metadataReplaceNetworkAclAssociationOutput `json:"-" xml:"-"` } -type metadataReplaceNetworkACLAssociationOutput struct { +type metadataReplaceNetworkAclAssociationOutput struct { SDKShapeTraits bool `type:"structure"` } -type ReplaceNetworkACLEntryInput struct { +// String returns the string representation +func (s ReplaceNetworkAclAssociationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceNetworkAclAssociationOutput) GoString() string { + return s.String() +} + +type ReplaceNetworkAclEntryInput struct { // The network range to allow or deny, in CIDR notation. - CIDRBlock *string `locationName:"cidrBlock" type:"string" required:"true"` + CidrBlock *string `locationName:"cidrBlock" type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -16503,10 +20147,10 @@ type ReplaceNetworkACLEntryInput struct { // ICMP protocol: The ICMP type and code. Required if specifying 1 (ICMP) for // the protocol. - ICMPTypeCode *ICMPTypeCode `locationName:"Icmp" type:"structure"` + IcmpTypeCode *IcmpTypeCode `locationName:"Icmp" type:"structure"` // The ID of the ACL. - NetworkACLID *string `locationName:"networkAclId" type:"string" required:"true"` + NetworkAclId *string `locationName:"networkAclId" type:"string" required:"true"` // TCP or UDP protocols: The range of ports the rule applies to. Required if // specifying 6 (TCP) or 17 (UDP) for the protocol. @@ -16516,30 +20160,50 @@ type ReplaceNetworkACLEntryInput struct { Protocol *string `locationName:"protocol" type:"string" required:"true"` // Indicates whether to allow or deny the traffic that matches the rule. - RuleAction *string `locationName:"ruleAction" type:"string" required:"true"` + RuleAction *string `locationName:"ruleAction" type:"string" required:"true" enum:"RuleAction"` // The rule number of the entry to replace. RuleNumber *int64 `locationName:"ruleNumber" type:"integer" required:"true"` - metadataReplaceNetworkACLEntryInput `json:"-" xml:"-"` + metadataReplaceNetworkAclEntryInput `json:"-" xml:"-"` } -type metadataReplaceNetworkACLEntryInput struct { +type metadataReplaceNetworkAclEntryInput struct { SDKShapeTraits bool `type:"structure"` } -type ReplaceNetworkACLEntryOutput struct { - metadataReplaceNetworkACLEntryOutput `json:"-" xml:"-"` +// String returns the string representation +func (s ReplaceNetworkAclEntryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceNetworkAclEntryInput) GoString() string { + return s.String() } -type metadataReplaceNetworkACLEntryOutput struct { +type ReplaceNetworkAclEntryOutput struct { + metadataReplaceNetworkAclEntryOutput `json:"-" xml:"-"` +} + +type metadataReplaceNetworkAclEntryOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReplaceNetworkAclEntryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceNetworkAclEntryOutput) GoString() string { + return s.String() +} + type ReplaceRouteInput struct { // The CIDR address block used for the destination match. The value you provide // must match the CIDR of an existing route in the table. - DestinationCIDRBlock *string `locationName:"destinationCidrBlock" type:"string" required:"true"` + DestinationCidrBlock *string `locationName:"destinationCidrBlock" type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -16548,19 +20212,19 @@ type ReplaceRouteInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of an Internet gateway or virtual private gateway. - GatewayID *string `locationName:"gatewayId" type:"string"` + GatewayId *string `locationName:"gatewayId" type:"string"` // The ID of a NAT instance in your VPC. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The ID of a network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` // The ID of the route table. - RouteTableID *string `locationName:"routeTableId" type:"string" required:"true"` + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` // The ID of a VPC peering connection. - VPCPeeringConnectionID *string `locationName:"vpcPeeringConnectionId" type:"string"` + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` metadataReplaceRouteInput `json:"-" xml:"-"` } @@ -16569,6 +20233,16 @@ type metadataReplaceRouteInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReplaceRouteInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceRouteInput) GoString() string { + return s.String() +} + type ReplaceRouteOutput struct { metadataReplaceRouteOutput `json:"-" xml:"-"` } @@ -16577,9 +20251,19 @@ type metadataReplaceRouteOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReplaceRouteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceRouteOutput) GoString() string { + return s.String() +} + type ReplaceRouteTableAssociationInput struct { // The association ID. - AssociationID *string `locationName:"associationId" type:"string" required:"true"` + AssociationId *string `locationName:"associationId" type:"string" required:"true"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -16588,7 +20272,7 @@ type ReplaceRouteTableAssociationInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the new route table to associate with the subnet. - RouteTableID *string `locationName:"routeTableId" type:"string" required:"true"` + RouteTableId *string `locationName:"routeTableId" type:"string" required:"true"` metadataReplaceRouteTableAssociationInput `json:"-" xml:"-"` } @@ -16597,9 +20281,19 @@ type metadataReplaceRouteTableAssociationInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReplaceRouteTableAssociationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceRouteTableAssociationInput) GoString() string { + return s.String() +} + type ReplaceRouteTableAssociationOutput struct { // The ID of the new association. - NewAssociationID *string `locationName:"newAssociationId" type:"string"` + NewAssociationId *string `locationName:"newAssociationId" type:"string"` metadataReplaceRouteTableAssociationOutput `json:"-" xml:"-"` } @@ -16608,6 +20302,16 @@ type metadataReplaceRouteTableAssociationOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReplaceRouteTableAssociationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReplaceRouteTableAssociationOutput) GoString() string { + return s.String() +} + type ReportInstanceStatusInput struct { // Descriptive text about the health state of your instance. Description *string `locationName:"description" type:"string"` @@ -16652,7 +20356,7 @@ type ReportInstanceStatusInput struct { StartTime *time.Time `locationName:"startTime" type:"timestamp" timestampFormat:"iso8601"` // The status of all instances listed. - Status *string `locationName:"status" type:"string" required:"true"` + Status *string `locationName:"status" type:"string" required:"true" enum:"ReportStatusType"` metadataReportInstanceStatusInput `json:"-" xml:"-"` } @@ -16661,6 +20365,16 @@ type metadataReportInstanceStatusInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReportInstanceStatusInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReportInstanceStatusInput) GoString() string { + return s.String() +} + type ReportInstanceStatusOutput struct { metadataReportInstanceStatusOutput `json:"-" xml:"-"` } @@ -16669,6 +20383,16 @@ type metadataReportInstanceStatusOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReportInstanceStatusOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReportInstanceStatusOutput) GoString() string { + return s.String() +} + // Contains the parameters for RequestSpotFleet. type RequestSpotFleetInput struct { // Checks whether you have the required permissions for the action, without @@ -16687,10 +20411,20 @@ type metadataRequestSpotFleetInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RequestSpotFleetInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RequestSpotFleetInput) GoString() string { + return s.String() +} + // Contains the output of RequestSpotFleet. type RequestSpotFleetOutput struct { // The ID of the Spot fleet request. - SpotFleetRequestID *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` metadataRequestSpotFleetOutput `json:"-" xml:"-"` } @@ -16699,23 +20433,33 @@ type metadataRequestSpotFleetOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RequestSpotFleetOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RequestSpotFleetOutput) GoString() string { + return s.String() +} + // Contains the parameters for RequestSpotInstances. type RequestSpotInstancesInput struct { // The user-specified name for a logical grouping of bids. // // When you specify an Availability Zone group in a Spot Instance request, - // all Spot Instances in the request are launched in the same Availability Zone. + // all Spot instances in the request are launched in the same Availability Zone. // Instance proximity is maintained with this parameter, but the choice of Availability // Zone is not. The group applies only to bids for Spot Instances of the same - // instance type. Any additional Spot Instance requests that are specified with + // instance type. Any additional Spot instance requests that are specified with // the same Availability Zone group name are launched in that same Availability // Zone, as long as at least one instance from the group is still active. // // If there is no active instance running in the Availability Zone group that - // you specify for a new Spot Instance request (all instances are terminated, + // you specify for a new Spot instance request (all instances are terminated, // the bid is expired, or the bid falls below current market), then Amazon EC2 // launches the instance in any Availability Zone where the constraint can be - // met. Consequently, the subsequent set of Spot Instances could be placed in + // met. Consequently, the subsequent set of Spot instances could be placed in // a different zone from the original request, even if you specified the same // Availability Zone group. // @@ -16733,12 +20477,12 @@ type RequestSpotInstancesInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The maximum number of Spot Instances to launch. + // The maximum number of Spot instances to launch. // // Default: 1 InstanceCount *int64 `locationName:"instanceCount" type:"integer"` - // The instance launch group. Launch groups are Spot Instances that launch together + // The instance launch group. Launch groups are Spot instances that launch together // and terminate together. // // Default: Instances are launched and terminated individually @@ -16747,14 +20491,14 @@ type RequestSpotInstancesInput struct { // Describes the launch specification for an instance. LaunchSpecification *RequestSpotLaunchSpecification `type:"structure"` - // The maximum hourly price (bid) for any Spot Instance launched to fulfill + // The maximum hourly price (bid) for any Spot instance launched to fulfill // the request. SpotPrice *string `locationName:"spotPrice" type:"string" required:"true"` - // The Spot Instance request type. + // The Spot instance request type. // // Default: one-time - Type *string `locationName:"type" type:"string"` + Type *string `locationName:"type" type:"string" enum:"SpotInstanceType"` // The start date of the request. If this is a one-time request, the request // becomes active at this date and time and remains active until all instances @@ -16780,9 +20524,19 @@ type metadataRequestSpotInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RequestSpotInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RequestSpotInstancesInput) GoString() string { + return s.String() +} + // Contains the output of RequestSpotInstances. type RequestSpotInstancesOutput struct { - // One or more Spot Instance requests. + // One or more Spot instance requests. SpotInstanceRequests []*SpotInstanceRequest `locationName:"spotInstanceRequestSet" locationNameList:"item" type:"list"` metadataRequestSpotInstancesOutput `json:"-" xml:"-"` @@ -16792,6 +20546,16 @@ type metadataRequestSpotInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RequestSpotInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RequestSpotInstancesOutput) GoString() string { + return s.String() +} + // Describes the launch specification for an instance. type RequestSpotLaunchSpecification struct { // Deprecated. @@ -16807,19 +20571,19 @@ type RequestSpotLaunchSpecification struct { // Optimized instance. // // Default: false - EBSOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` // The IAM instance profile. - IAMInstanceProfile *IAMInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` + IamInstanceProfile *IamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` // The ID of the AMI. - ImageID *string `locationName:"imageId" type:"string"` + ImageId *string `locationName:"imageId" type:"string"` // The instance type. - InstanceType *string `locationName:"instanceType" type:"string"` + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` // The ID of the kernel. - KernelID *string `locationName:"kernelId" type:"string"` + KernelId *string `locationName:"kernelId" type:"string"` // The name of the key pair. KeyName *string `locationName:"keyName" type:"string"` @@ -16834,14 +20598,14 @@ type RequestSpotLaunchSpecification struct { Placement *SpotPlacement `locationName:"placement" type:"structure"` // The ID of the RAM disk. - RAMDiskID *string `locationName:"ramdiskId" type:"string"` + RamdiskId *string `locationName:"ramdiskId" type:"string"` - SecurityGroupIDs []*string `locationName:"SecurityGroupId" locationNameList:"item" type:"list"` + SecurityGroupIds []*string `locationName:"SecurityGroupId" locationNameList:"item" type:"list"` SecurityGroups []*string `locationName:"SecurityGroup" locationNameList:"item" type:"list"` // The ID of the subnet in which to launch the instance. - SubnetID *string `locationName:"subnetId" type:"string"` + SubnetId *string `locationName:"subnetId" type:"string"` // The Base64-encoded MIME user data to make available to the instances. UserData *string `locationName:"userData" type:"string"` @@ -16853,6 +20617,16 @@ type metadataRequestSpotLaunchSpecification struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RequestSpotLaunchSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RequestSpotLaunchSpecification) GoString() string { + return s.String() +} + // Describes a reservation. type Reservation struct { // One or more security groups. @@ -16862,14 +20636,14 @@ type Reservation struct { Instances []*Instance `locationName:"instancesSet" locationNameList:"item" type:"list"` // The ID of the AWS account that owns the reservation. - OwnerID *string `locationName:"ownerId" type:"string"` + OwnerId *string `locationName:"ownerId" type:"string"` // The ID of the requester that launched the instances on your behalf (for example, // AWS Management Console or Auto Scaling). - RequesterID *string `locationName:"requesterId" type:"string"` + RequesterId *string `locationName:"requesterId" type:"string"` // The ID of the reservation. - ReservationID *string `locationName:"reservationId" type:"string"` + ReservationId *string `locationName:"reservationId" type:"string"` metadataReservation `json:"-" xml:"-"` } @@ -16878,15 +20652,25 @@ type metadataReservation struct { SDKShapeTraits bool `type:"structure"` } -// Describes the limit price of a Reserved Instance offering. -type ReservedInstanceLimitPrice struct { - // Used for Reserved Instance Marketplace offerings. Specifies the limit price +// String returns the string representation +func (s Reservation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Reservation) GoString() string { + return s.String() +} + +// Describes the limit price of a Reserved Instance offering. +type ReservedInstanceLimitPrice struct { + // Used for Reserved Instance Marketplace offerings. Specifies the limit price // on the total order (instanceCount * price). Amount *float64 `locationName:"amount" type:"double"` // The currency in which the limitPrice amount is specified. At this time, the // only supported currency is USD. - CurrencyCode *string `locationName:"currencyCode" type:"string"` + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` metadataReservedInstanceLimitPrice `json:"-" xml:"-"` } @@ -16895,6 +20679,16 @@ type metadataReservedInstanceLimitPrice struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReservedInstanceLimitPrice) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstanceLimitPrice) GoString() string { + return s.String() +} + // Describes a Reserved Instance. type ReservedInstances struct { // The Availability Zone in which the Reserved Instance can be used. @@ -16902,7 +20696,7 @@ type ReservedInstances struct { // The currency of the Reserved Instance. It's specified using ISO 4217 standard // currency codes. At this time, the only supported currency is USD. - CurrencyCode *string `locationName:"currencyCode" type:"string"` + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` // The duration of the Reserved Instance, in seconds. Duration *int64 `locationName:"duration" type:"long"` @@ -16917,28 +20711,28 @@ type ReservedInstances struct { InstanceCount *int64 `locationName:"instanceCount" type:"integer"` // The tenancy of the reserved instance. - InstanceTenancy *string `locationName:"instanceTenancy" type:"string"` + InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` // The instance type on which the Reserved Instance can be used. - InstanceType *string `locationName:"instanceType" type:"string"` + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` // The Reserved Instance offering type. - OfferingType *string `locationName:"offeringType" type:"string"` + OfferingType *string `locationName:"offeringType" type:"string" enum:"OfferingTypeValues"` - // The Reserved Instance description. - ProductDescription *string `locationName:"productDescription" type:"string"` + // The Reserved Instance product platform description. + ProductDescription *string `locationName:"productDescription" type:"string" enum:"RIProductDescription"` // The recurring charge tag assigned to the resource. RecurringCharges []*RecurringCharge `locationName:"recurringCharges" locationNameList:"item" type:"list"` // The ID of the Reserved Instance. - ReservedInstancesID *string `locationName:"reservedInstancesId" type:"string"` + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` // The date and time the Reserved Instance started. Start *time.Time `locationName:"start" type:"timestamp" timestampFormat:"iso8601"` // The state of the Reserved Instance purchase. - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"ReservedInstanceState"` // Any tags assigned to the resource. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` @@ -16953,6 +20747,16 @@ type metadataReservedInstances struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReservedInstances) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstances) GoString() string { + return s.String() +} + // Describes the configuration settings for the modified Reserved Instances. type ReservedInstancesConfiguration struct { // The Availability Zone for the modified Reserved Instances. @@ -16962,7 +20766,7 @@ type ReservedInstancesConfiguration struct { InstanceCount *int64 `locationName:"instanceCount" type:"integer"` // The instance type for the modified Reserved Instances. - InstanceType *string `locationName:"instanceType" type:"string"` + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` // The network platform of the modified Reserved Instances, which is either // EC2-Classic or EC2-VPC. @@ -16975,18 +20779,38 @@ type metadataReservedInstancesConfiguration struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReservedInstancesConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesConfiguration) GoString() string { + return s.String() +} + // Describes the ID of a Reserved Instance. -type ReservedInstancesID struct { +type ReservedInstancesId struct { // The ID of the Reserved Instance. - ReservedInstancesID *string `locationName:"reservedInstancesId" type:"string"` + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` - metadataReservedInstancesID `json:"-" xml:"-"` + metadataReservedInstancesId `json:"-" xml:"-"` } -type metadataReservedInstancesID struct { +type metadataReservedInstancesId struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReservedInstancesId) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesId) GoString() string { + return s.String() +} + // Describes a Reserved Instance listing. type ReservedInstancesListing struct { // A unique, case-sensitive key supplied by the client to ensure that the request @@ -17003,13 +20827,13 @@ type ReservedInstancesListing struct { PriceSchedules []*PriceSchedule `locationName:"priceSchedules" locationNameList:"item" type:"list"` // The ID of the Reserved Instance. - ReservedInstancesID *string `locationName:"reservedInstancesId" type:"string"` + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` // The ID of the Reserved Instance listing. - ReservedInstancesListingID *string `locationName:"reservedInstancesListingId" type:"string"` + ReservedInstancesListingId *string `locationName:"reservedInstancesListingId" type:"string"` // The status of the Reserved Instance listing. - Status *string `locationName:"status" type:"string"` + Status *string `locationName:"status" type:"string" enum:"ListingStatus"` // The reason for the current status of the Reserved Instance listing. The response // can be blank. @@ -17028,6 +20852,16 @@ type metadataReservedInstancesListing struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReservedInstancesListing) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesListing) GoString() string { + return s.String() +} + // Describes a Reserved Instance modification. type ReservedInstancesModification struct { // A unique, case-sensitive key supplied by the client to ensure that the request @@ -17045,10 +20879,10 @@ type ReservedInstancesModification struct { ModificationResults []*ReservedInstancesModificationResult `locationName:"modificationResultSet" locationNameList:"item" type:"list"` // The IDs of one or more Reserved Instances. - ReservedInstancesIDs []*ReservedInstancesID `locationName:"reservedInstancesSet" locationNameList:"item" type:"list"` + ReservedInstancesIds []*ReservedInstancesId `locationName:"reservedInstancesSet" locationNameList:"item" type:"list"` // A unique ID for the Reserved Instance modification. - ReservedInstancesModificationID *string `locationName:"reservedInstancesModificationId" type:"string"` + ReservedInstancesModificationId *string `locationName:"reservedInstancesModificationId" type:"string"` // The status of the Reserved Instances modification request. Status *string `locationName:"status" type:"string"` @@ -17066,10 +20900,20 @@ type metadataReservedInstancesModification struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReservedInstancesModification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesModification) GoString() string { + return s.String() +} + type ReservedInstancesModificationResult struct { // The ID for the Reserved Instances that were created as part of the modification // request. This field is only available when the modification is fulfilled. - ReservedInstancesID *string `locationName:"reservedInstancesId" type:"string"` + ReservedInstancesId *string `locationName:"reservedInstancesId" type:"string"` // The target Reserved Instances configurations supplied as part of the modification // request. @@ -17082,6 +20926,16 @@ type metadataReservedInstancesModificationResult struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReservedInstancesModificationResult) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesModificationResult) GoString() string { + return s.String() +} + // Describes a Reserved Instance offering. type ReservedInstancesOffering struct { // The Availability Zone in which the Reserved Instance can be used. @@ -17090,7 +20944,7 @@ type ReservedInstancesOffering struct { // The currency of the Reserved Instance offering you are purchasing. It's specified // using ISO 4217 standard currency codes. At this time, the only supported // currency is USD. - CurrencyCode *string `locationName:"currencyCode" type:"string"` + CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` // The duration of the Reserved Instance, in seconds. Duration *int64 `locationName:"duration" type:"long"` @@ -17099,10 +20953,10 @@ type ReservedInstancesOffering struct { FixedPrice *float64 `locationName:"fixedPrice" type:"float"` // The tenancy of the reserved instance. - InstanceTenancy *string `locationName:"instanceTenancy" type:"string"` + InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` // The instance type on which the Reserved Instance can be used. - InstanceType *string `locationName:"instanceType" type:"string"` + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` // Indicates whether the offering is available through the Reserved Instance // Marketplace (resale) or AWS. If it's a Reserved Instance Marketplace offering, @@ -17110,19 +20964,19 @@ type ReservedInstancesOffering struct { Marketplace *bool `locationName:"marketplace" type:"boolean"` // The Reserved Instance offering type. - OfferingType *string `locationName:"offeringType" type:"string"` + OfferingType *string `locationName:"offeringType" type:"string" enum:"OfferingTypeValues"` // The pricing details of the Reserved Instance offering. PricingDetails []*PricingDetail `locationName:"pricingDetailsSet" locationNameList:"item" type:"list"` - // The Reserved Instance description. - ProductDescription *string `locationName:"productDescription" type:"string"` + // The Reserved Instance product platform description. + ProductDescription *string `locationName:"productDescription" type:"string" enum:"RIProductDescription"` // The recurring charge tag assigned to the resource. RecurringCharges []*RecurringCharge `locationName:"recurringCharges" locationNameList:"item" type:"list"` // The ID of the Reserved Instance offering. - ReservedInstancesOfferingID *string `locationName:"reservedInstancesOfferingId" type:"string"` + ReservedInstancesOfferingId *string `locationName:"reservedInstancesOfferingId" type:"string"` // The usage price of the Reserved Instance, per hour. UsagePrice *float64 `locationName:"usagePrice" type:"float"` @@ -17134,10 +20988,20 @@ type metadataReservedInstancesOffering struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ReservedInstancesOffering) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReservedInstancesOffering) GoString() string { + return s.String() +} + type ResetImageAttributeInput struct { // The attribute to reset (currently you can only reset the launch permission // attribute). - Attribute *string `type:"string" required:"true"` + Attribute *string `type:"string" required:"true" enum:"ResetImageAttributeName"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -17146,7 +21010,7 @@ type ResetImageAttributeInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the AMI. - ImageID *string `locationName:"ImageId" type:"string" required:"true"` + ImageId *string `type:"string" required:"true"` metadataResetImageAttributeInput `json:"-" xml:"-"` } @@ -17155,6 +21019,16 @@ type metadataResetImageAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ResetImageAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetImageAttributeInput) GoString() string { + return s.String() +} + type ResetImageAttributeOutput struct { metadataResetImageAttributeOutput `json:"-" xml:"-"` } @@ -17163,9 +21037,19 @@ type metadataResetImageAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ResetImageAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetImageAttributeOutput) GoString() string { + return s.String() +} + type ResetInstanceAttributeInput struct { // The attribute to reset. - Attribute *string `locationName:"attribute" type:"string" required:"true"` + Attribute *string `locationName:"attribute" type:"string" required:"true" enum:"InstanceAttributeName"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -17174,7 +21058,7 @@ type ResetInstanceAttributeInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string" required:"true"` + InstanceId *string `locationName:"instanceId" type:"string" required:"true"` metadataResetInstanceAttributeInput `json:"-" xml:"-"` } @@ -17183,6 +21067,16 @@ type metadataResetInstanceAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ResetInstanceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetInstanceAttributeInput) GoString() string { + return s.String() +} + type ResetInstanceAttributeOutput struct { metadataResetInstanceAttributeOutput `json:"-" xml:"-"` } @@ -17191,6 +21085,16 @@ type metadataResetInstanceAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ResetInstanceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetInstanceAttributeOutput) GoString() string { + return s.String() +} + type ResetNetworkInterfaceAttributeInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -17199,7 +21103,7 @@ type ResetNetworkInterfaceAttributeInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string" required:"true"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` // The source/destination checking attribute. Resets the value to true. SourceDestCheck *string `locationName:"sourceDestCheck" type:"string"` @@ -17211,6 +21115,16 @@ type metadataResetNetworkInterfaceAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ResetNetworkInterfaceAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetNetworkInterfaceAttributeInput) GoString() string { + return s.String() +} + type ResetNetworkInterfaceAttributeOutput struct { metadataResetNetworkInterfaceAttributeOutput `json:"-" xml:"-"` } @@ -17219,10 +21133,20 @@ type metadataResetNetworkInterfaceAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ResetNetworkInterfaceAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetNetworkInterfaceAttributeOutput) GoString() string { + return s.String() +} + type ResetSnapshotAttributeInput struct { - // The attribute to reset (currently only the attribute for permission to create - // volumes can be reset). - Attribute *string `type:"string" required:"true"` + // The attribute to reset. Currently, only the attribute for permission to create + // volumes can be reset. + Attribute *string `type:"string" required:"true" enum:"SnapshotAttributeName"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -17231,7 +21155,7 @@ type ResetSnapshotAttributeInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The ID of the snapshot. - SnapshotID *string `locationName:"SnapshotId" type:"string" required:"true"` + SnapshotId *string `type:"string" required:"true"` metadataResetSnapshotAttributeInput `json:"-" xml:"-"` } @@ -17240,6 +21164,16 @@ type metadataResetSnapshotAttributeInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ResetSnapshotAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetSnapshotAttributeInput) GoString() string { + return s.String() +} + type ResetSnapshotAttributeOutput struct { metadataResetSnapshotAttributeOutput `json:"-" xml:"-"` } @@ -17248,6 +21182,16 @@ type metadataResetSnapshotAttributeOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ResetSnapshotAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetSnapshotAttributeOutput) GoString() string { + return s.String() +} + type RestoreAddressToClassicInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -17256,7 +21200,7 @@ type RestoreAddressToClassicInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // The Elastic IP address. - PublicIP *string `locationName:"publicIp" type:"string" required:"true"` + PublicIp *string `locationName:"publicIp" type:"string" required:"true"` metadataRestoreAddressToClassicInput `json:"-" xml:"-"` } @@ -17265,12 +21209,22 @@ type metadataRestoreAddressToClassicInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RestoreAddressToClassicInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RestoreAddressToClassicInput) GoString() string { + return s.String() +} + type RestoreAddressToClassicOutput struct { // The Elastic IP address. - PublicIP *string `locationName:"publicIp" type:"string"` + PublicIp *string `locationName:"publicIp" type:"string"` // The move status for the IP address. - Status *string `locationName:"status" type:"string"` + Status *string `locationName:"status" type:"string" enum:"Status"` metadataRestoreAddressToClassicOutput `json:"-" xml:"-"` } @@ -17279,10 +21233,20 @@ type metadataRestoreAddressToClassicOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RestoreAddressToClassicOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RestoreAddressToClassicOutput) GoString() string { + return s.String() +} + type RevokeSecurityGroupEgressInput struct { // The CIDR IP address range. You can't specify this parameter when specifying // a source security group. - CIDRIP *string `locationName:"cidrIp" type:"string"` + CidrIp *string `locationName:"cidrIp" type:"string"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -17295,23 +21259,25 @@ type RevokeSecurityGroupEgressInput struct { FromPort *int64 `locationName:"fromPort" type:"integer"` // The ID of the security group. - GroupID *string `locationName:"groupId" type:"string" required:"true"` + GroupId *string `locationName:"groupId" type:"string" required:"true"` // A set of IP permissions. You can't specify a destination security group and // a CIDR IP address range. - IPPermissions []*IPPermission `locationName:"ipPermissions" locationNameList:"item" type:"list"` + IpPermissions []*IpPermission `locationName:"ipPermissions" locationNameList:"item" type:"list"` // The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)). // Use -1 to specify all. - IPProtocol *string `locationName:"ipProtocol" type:"string"` + IpProtocol *string `locationName:"ipProtocol" type:"string"` - // [EC2-Classic, default VPC] The name of the destination security group. You - // can't specify a destination security group and a CIDR IP address range. + // The name of a destination security group. To revoke outbound access to a + // destination security group, we recommend that you use a set of IP permissions + // instead. SourceSecurityGroupName *string `locationName:"sourceSecurityGroupName" type:"string"` - // The ID of the destination security group. You can't specify a destination - // security group and a CIDR IP address range. - SourceSecurityGroupOwnerID *string `locationName:"sourceSecurityGroupOwnerId" type:"string"` + // The AWS account number for a destination security group. To revoke outbound + // access to a destination security group, we recommend that you use a set of + // IP permissions instead. + SourceSecurityGroupOwnerId *string `locationName:"sourceSecurityGroupOwnerId" type:"string"` // The end of port range for the TCP and UDP protocols, or an ICMP code number. // For the ICMP code number, use -1 to specify all ICMP codes for the ICMP type. @@ -17324,6 +21290,16 @@ type metadataRevokeSecurityGroupEgressInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RevokeSecurityGroupEgressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RevokeSecurityGroupEgressInput) GoString() string { + return s.String() +} + type RevokeSecurityGroupEgressOutput struct { metadataRevokeSecurityGroupEgressOutput `json:"-" xml:"-"` } @@ -17332,10 +21308,20 @@ type metadataRevokeSecurityGroupEgressOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RevokeSecurityGroupEgressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RevokeSecurityGroupEgressOutput) GoString() string { + return s.String() +} + type RevokeSecurityGroupIngressInput struct { // The CIDR IP address range. You can't specify this parameter when specifying // a source security group. - CIDRIP *string `locationName:"CidrIp" type:"string"` + CidrIp *string `type:"string"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -17347,27 +21333,35 @@ type RevokeSecurityGroupIngressInput struct { // For the ICMP type number, use -1 to specify all ICMP types. FromPort *int64 `type:"integer"` - // The ID of the security group. - GroupID *string `locationName:"GroupId" type:"string"` + // The ID of the security group. Required for a security group in a nondefault + // VPC. + GroupId *string `type:"string"` // [EC2-Classic, default VPC] The name of the security group. GroupName *string `type:"string"` // A set of IP permissions. You can't specify a source security group and a // CIDR IP address range. - IPPermissions []*IPPermission `locationName:"IpPermissions" locationNameList:"item" type:"list"` + IpPermissions []*IpPermission `locationNameList:"item" type:"list"` // The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)). // Use -1 to specify all. - IPProtocol *string `locationName:"IpProtocol" type:"string"` + IpProtocol *string `type:"string"` // [EC2-Classic, default VPC] The name of the source security group. You can't - // specify a source security group and a CIDR IP address range. + // specify this parameter in combination with the following parameters: the + // CIDR IP address range, the start of the port range, the IP protocol, and + // the end of the port range. For EC2-VPC, the source security group must be + // in the same VPC. SourceSecurityGroupName *string `type:"string"` - // The ID of the source security group. You can't specify a source security - // group and a CIDR IP address range. - SourceSecurityGroupOwnerID *string `locationName:"SourceSecurityGroupOwnerId" type:"string"` + // [EC2-Classic, default VPC] The AWS account ID of the source security group. + // For EC2-VPC, the source security group must be in the same VPC. You can't + // specify this parameter in combination with the following parameters: the + // CIDR IP address range, the IP protocol, the start of the port range, and + // the end of the port range. To revoke a specific rule for an IP protocol and + // port range, use a set of IP permissions instead. + SourceSecurityGroupOwnerId *string `type:"string"` // The end of port range for the TCP and UDP protocols, or an ICMP code number. // For the ICMP code number, use -1 to specify all ICMP codes for the ICMP type. @@ -17380,6 +21374,16 @@ type metadataRevokeSecurityGroupIngressInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RevokeSecurityGroupIngressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RevokeSecurityGroupIngressInput) GoString() string { + return s.String() +} + type RevokeSecurityGroupIngressOutput struct { metadataRevokeSecurityGroupIngressOutput `json:"-" xml:"-"` } @@ -17388,25 +21392,35 @@ type metadataRevokeSecurityGroupIngressOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RevokeSecurityGroupIngressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RevokeSecurityGroupIngressOutput) GoString() string { + return s.String() +} + // Describes a route in a route table. type Route struct { // The CIDR block used for the destination match. - DestinationCIDRBlock *string `locationName:"destinationCidrBlock" type:"string"` + DestinationCidrBlock *string `locationName:"destinationCidrBlock" type:"string"` // The prefix of the AWS service. - DestinationPrefixListID *string `locationName:"destinationPrefixListId" type:"string"` + DestinationPrefixListId *string `locationName:"destinationPrefixListId" type:"string"` // The ID of a gateway attached to your VPC. - GatewayID *string `locationName:"gatewayId" type:"string"` + GatewayId *string `locationName:"gatewayId" type:"string"` // The ID of a NAT instance in your VPC. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` // The AWS account ID of the owner of the instance. - InstanceOwnerID *string `locationName:"instanceOwnerId" type:"string"` + InstanceOwnerId *string `locationName:"instanceOwnerId" type:"string"` // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` // Describes how the route was created. // @@ -17414,15 +21428,15 @@ type Route struct { // route table was created. CreateRoute indicates that the route was manually // added to the route table. EnableVgwRoutePropagation indicates that the route // was propagated by route propagation. - Origin *string `locationName:"origin" type:"string"` + Origin *string `locationName:"origin" type:"string" enum:"RouteOrigin"` // The state of the route. The blackhole state indicates that the route's target // isn't available (for example, the specified gateway isn't attached to the // VPC, or the specified NAT instance has been terminated). - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"RouteState"` // The ID of the VPC peering connection. - VPCPeeringConnectionID *string `locationName:"vpcPeeringConnectionId" type:"string"` + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` metadataRoute `json:"-" xml:"-"` } @@ -17431,16 +21445,26 @@ type metadataRoute struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Route) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Route) GoString() string { + return s.String() +} + // Describes a route table. type RouteTable struct { // The associations between the route table and one or more subnets. Associations []*RouteTableAssociation `locationName:"associationSet" locationNameList:"item" type:"list"` // Any virtual private gateway (VGW) propagating routes. - PropagatingVGWs []*PropagatingVGW `locationName:"propagatingVgwSet" locationNameList:"item" type:"list"` + PropagatingVgws []*PropagatingVgw `locationName:"propagatingVgwSet" locationNameList:"item" type:"list"` // The ID of the route table. - RouteTableID *string `locationName:"routeTableId" type:"string"` + RouteTableId *string `locationName:"routeTableId" type:"string"` // The routes in the route table. Routes []*Route `locationName:"routeSet" locationNameList:"item" type:"list"` @@ -17449,7 +21473,7 @@ type RouteTable struct { Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string"` + VpcId *string `locationName:"vpcId" type:"string"` metadataRouteTable `json:"-" xml:"-"` } @@ -17458,19 +21482,29 @@ type metadataRouteTable struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RouteTable) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RouteTable) GoString() string { + return s.String() +} + // Describes an association between a route table and a subnet. type RouteTableAssociation struct { // Indicates whether this is the main route table. Main *bool `locationName:"main" type:"boolean"` // The ID of the association between a route table and a subnet. - RouteTableAssociationID *string `locationName:"routeTableAssociationId" type:"string"` + RouteTableAssociationId *string `locationName:"routeTableAssociationId" type:"string"` // The ID of the route table. - RouteTableID *string `locationName:"routeTableId" type:"string"` + RouteTableId *string `locationName:"routeTableId" type:"string"` - // The ID of the subnet. - SubnetID *string `locationName:"subnetId" type:"string"` + // The ID of the subnet. A subnet ID is not returned for an implicit association. + SubnetId *string `locationName:"subnetId" type:"string"` metadataRouteTableAssociation `json:"-" xml:"-"` } @@ -17479,6 +21513,16 @@ type metadataRouteTableAssociation struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RouteTableAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RouteTableAssociation) GoString() string { + return s.String() +} + type RunInstancesInput struct { // Reserved. AdditionalInfo *string `locationName:"additionalInfo" type:"string"` @@ -17501,7 +21545,7 @@ type RunInstancesInput struct { // from the instance. // // Default: false - DisableAPITermination *bool `locationName:"disableApiTermination" type:"boolean"` + DisableApiTermination *bool `locationName:"disableApiTermination" type:"boolean"` // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -17516,32 +21560,32 @@ type RunInstancesInput struct { // instance. // // Default: false - EBSOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` // The IAM instance profile. - IAMInstanceProfile *IAMInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` + IamInstanceProfile *IamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` // The ID of the AMI, which you can get by calling DescribeImages. - ImageID *string `locationName:"ImageId" type:"string" required:"true"` + ImageId *string `type:"string" required:"true"` // Indicates whether an instance stops or terminates when you initiate shutdown // from the instance (using the operating system command for system shutdown). // // Default: stop - InstanceInitiatedShutdownBehavior *string `locationName:"instanceInitiatedShutdownBehavior" type:"string"` + InstanceInitiatedShutdownBehavior *string `locationName:"instanceInitiatedShutdownBehavior" type:"string" enum:"ShutdownBehavior"` // The instance type. For more information, see Instance Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) // in the Amazon Elastic Compute Cloud User Guide. // // Default: m1.small - InstanceType *string `type:"string"` + InstanceType *string `type:"string" enum:"InstanceType"` // The ID of the kernel. // // We recommend that you use PV-GRUB instead of kernels and RAM disks. For // more information, see PV-GRUB (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedkernels.html) // in the Amazon Elastic Compute Cloud User Guide. - KernelID *string `locationName:"KernelId" type:"string"` + KernelId *string `type:"string"` // The name of the key pair. You can create a key pair using CreateKeyPair or // ImportKeyPair. @@ -17587,19 +21631,19 @@ type RunInstancesInput struct { // and PrivateIpAddresses.n.PrivateIpAddress is set to an IP address. // // Default: We select an IP address from the IP address range of the subnet. - PrivateIPAddress *string `locationName:"privateIpAddress" type:"string"` + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` // The ID of the RAM disk. // // We recommend that you use PV-GRUB instead of kernels and RAM disks. For // more information, see PV-GRUB (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedkernels.html) // in the Amazon Elastic Compute Cloud User Guide. - RAMDiskID *string `locationName:"RamdiskId" type:"string"` + RamdiskId *string `type:"string"` // One or more security group IDs. You can create a security group using CreateSecurityGroup. // // Default: Amazon EC2 uses the default security group. - SecurityGroupIDs []*string `locationName:"SecurityGroupId" locationNameList:"SecurityGroupId" type:"list"` + SecurityGroupIds []*string `locationName:"SecurityGroupId" locationNameList:"SecurityGroupId" type:"list"` // [EC2-Classic, default VPC] One or more security group names. For a nondefault // VPC, you must use security group IDs instead. @@ -17608,7 +21652,7 @@ type RunInstancesInput struct { SecurityGroups []*string `locationName:"SecurityGroup" locationNameList:"SecurityGroup" type:"list"` // [EC2-VPC] The ID of the subnet to launch the instance into. - SubnetID *string `locationName:"SubnetId" type:"string"` + SubnetId *string `type:"string"` // The Base64-encoded MIME user data for the instances. UserData *string `type:"string"` @@ -17620,6 +21664,16 @@ type metadataRunInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RunInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RunInstancesInput) GoString() string { + return s.String() +} + // Describes the monitoring for the instance. type RunInstancesMonitoringEnabled struct { // Indicates whether monitoring is enabled for the instance. @@ -17632,13 +21686,23 @@ type metadataRunInstancesMonitoringEnabled struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RunInstancesMonitoringEnabled) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RunInstancesMonitoringEnabled) GoString() string { + return s.String() +} + // Describes the storage parameters for S3 and S3 buckets for an instance store-backed // AMI. type S3Storage struct { // The access key ID of the owner of the bucket. Before you specify a value // for your access key ID, review and follow the guidance in Best Practices // for Managing AWS Access Keys (http://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html). - AWSAccessKeyID *string `locationName:"AWSAccessKeyId" type:"string"` + AWSAccessKeyId *string `type:"string"` // The bucket in which to store the AMI. You can specify a bucket that you already // own or a new bucket that Amazon EC2 creates on your behalf. If you specify @@ -17662,31 +21726,41 @@ type metadataS3Storage struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s S3Storage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s S3Storage) GoString() string { + return s.String() +} + // Describes a security group type SecurityGroup struct { // A description of the security group. Description *string `locationName:"groupDescription" type:"string"` // The ID of the security group. - GroupID *string `locationName:"groupId" type:"string"` + GroupId *string `locationName:"groupId" type:"string"` // The name of the security group. GroupName *string `locationName:"groupName" type:"string"` // One or more inbound rules associated with the security group. - IPPermissions []*IPPermission `locationName:"ipPermissions" locationNameList:"item" type:"list"` + IpPermissions []*IpPermission `locationName:"ipPermissions" locationNameList:"item" type:"list"` // [EC2-VPC] One or more outbound rules associated with the security group. - IPPermissionsEgress []*IPPermission `locationName:"ipPermissionsEgress" locationNameList:"item" type:"list"` + IpPermissionsEgress []*IpPermission `locationName:"ipPermissionsEgress" locationNameList:"item" type:"list"` // The AWS account ID of the owner of the security group. - OwnerID *string `locationName:"ownerId" type:"string"` + OwnerId *string `locationName:"ownerId" type:"string"` // Any tags assigned to the security group. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` // [EC2-VPC] The ID of the VPC for the security group. - VPCID *string `locationName:"vpcId" type:"string"` + VpcId *string `locationName:"vpcId" type:"string"` metadataSecurityGroup `json:"-" xml:"-"` } @@ -17695,42 +21769,69 @@ type metadataSecurityGroup struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SecurityGroup) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SecurityGroup) GoString() string { + return s.String() +} + // Describes a snapshot. type Snapshot struct { + // The data encryption key identifier for the snapshot. This value is a unique + // identifier that corresponds to the data encryption key that was used to encrypt + // the original volume or snapshot copy. Because data encryption keys are inherited + // by volumes created from snapshots, and vice versa, if snapshots share the + // same data encryption key identifier, then they belong to the same volume/snapshot + // lineage. This parameter is only returned by the DescribeSnapshots API operation. + DataEncryptionKeyId *string `locationName:"dataEncryptionKeyId" type:"string"` + // The description for the snapshot. Description *string `locationName:"description" type:"string"` // Indicates whether the snapshot is encrypted. Encrypted *bool `locationName:"encrypted" type:"boolean"` - // The full ARN of the AWS Key Management Service (KMS) master key that was - // used to protect the volume encryption key for the parent volume. - KMSKeyID *string `locationName:"kmsKeyId" type:"string"` + // The full ARN of the AWS Key Management Service (AWS KMS) customer master + // key (CMK) that was used to protect the volume encryption key for the parent + // volume. + KmsKeyId *string `locationName:"kmsKeyId" type:"string"` // The AWS account alias (for example, amazon, self) or AWS account ID that // owns the snapshot. OwnerAlias *string `locationName:"ownerAlias" type:"string"` // The AWS account ID of the EBS snapshot owner. - OwnerID *string `locationName:"ownerId" type:"string"` + OwnerId *string `locationName:"ownerId" type:"string"` // The progress of the snapshot, as a percentage. Progress *string `locationName:"progress" type:"string"` - // The ID of the snapshot. - SnapshotID *string `locationName:"snapshotId" type:"string"` + // The ID of the snapshot. Each snapshot receives a unique identifier when it + // is created. + SnapshotId *string `locationName:"snapshotId" type:"string"` // The time stamp when the snapshot was initiated. StartTime *time.Time `locationName:"startTime" type:"timestamp" timestampFormat:"iso8601"` // The snapshot state. - State *string `locationName:"status" type:"string"` + State *string `locationName:"status" type:"string" enum:"SnapshotState"` + + // Encrypted Amazon EBS snapshots are copied asynchronously. If a snapshot copy + // operation fails (for example, if the proper AWS Key Management Service (AWS + // KMS) permissions are not obtained) this field displays error state details + // to help you diagnose why the error occurred. This parameter is only returned + // by the DescribeSnapshots API operation. + StateMessage *string `locationName:"statusMessage" type:"string"` // Any tags assigned to the snapshot. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` - // The ID of the volume. - VolumeID *string `locationName:"volumeId" type:"string"` + // The ID of the volume that was used to create the snapshot. + VolumeId *string `locationName:"volumeId" type:"string"` // The size of the volume, in GiB. VolumeSize *int64 `locationName:"volumeSize" type:"integer"` @@ -17742,6 +21843,16 @@ type metadataSnapshot struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Snapshot) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Snapshot) GoString() string { + return s.String() +} + // Describes the snapshot created from the imported disk. type SnapshotDetail struct { // A description for the snapshot. @@ -17760,7 +21871,7 @@ type SnapshotDetail struct { Progress *string `locationName:"progress" type:"string"` // The snapshot ID of the disk being imported. - SnapshotID *string `locationName:"snapshotId" type:"string"` + SnapshotId *string `locationName:"snapshotId" type:"string"` // A brief status of the snapshot creation. Status *string `locationName:"status" type:"string"` @@ -17769,7 +21880,7 @@ type SnapshotDetail struct { StatusMessage *string `locationName:"statusMessage" type:"string"` // The URL used to access the disk image. - URL *string `locationName:"url" type:"string"` + Url *string `locationName:"url" type:"string"` // Describes the S3 bucket for the disk image. UserBucket *UserBucketDetails `locationName:"userBucket" type:"structure"` @@ -17781,6 +21892,16 @@ type metadataSnapshotDetail struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SnapshotDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SnapshotDetail) GoString() string { + return s.String() +} + // The disk container object for the import snapshot request. type SnapshotDiskContainer struct { // The description of the disk image being imported. @@ -17793,7 +21914,7 @@ type SnapshotDiskContainer struct { // The URL to the Amazon S3-based disk image being imported. It can either be // a https URL (https://..) or an Amazon S3 URL (s3://..). - URL *string `locationName:"Url" type:"string"` + Url *string `type:"string"` // Describes the S3 bucket for the disk image. UserBucket *UserBucket `type:"structure"` @@ -17805,6 +21926,16 @@ type metadataSnapshotDiskContainer struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SnapshotDiskContainer) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SnapshotDiskContainer) GoString() string { + return s.String() +} + // Details about the import snapshot task. type SnapshotTaskDetail struct { // The description of the snapshot. @@ -17820,7 +21951,7 @@ type SnapshotTaskDetail struct { Progress *string `locationName:"progress" type:"string"` // The snapshot ID of the disk being imported. - SnapshotID *string `locationName:"snapshotId" type:"string"` + SnapshotId *string `locationName:"snapshotId" type:"string"` // A brief status for the import snapshot task. Status *string `locationName:"status" type:"string"` @@ -17829,7 +21960,7 @@ type SnapshotTaskDetail struct { StatusMessage *string `locationName:"statusMessage" type:"string"` // The URL of the disk image from which the snapshot is created. - URL *string `locationName:"url" type:"string"` + Url *string `locationName:"url" type:"string"` // The S3 bucket for the disk image. UserBucket *UserBucketDetails `locationName:"userBucket" type:"structure"` @@ -17841,22 +21972,32 @@ type metadataSnapshotTaskDetail struct { SDKShapeTraits bool `type:"structure"` } -// Describes the data feed for a Spot Instance. +// String returns the string representation +func (s SnapshotTaskDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SnapshotTaskDetail) GoString() string { + return s.String() +} + +// Describes the data feed for a Spot instance. type SpotDatafeedSubscription struct { - // The Amazon S3 bucket where the Spot Instance data feed is located. + // The Amazon S3 bucket where the Spot instance data feed is located. Bucket *string `locationName:"bucket" type:"string"` - // The fault codes for the Spot Instance request, if any. + // The fault codes for the Spot instance request, if any. Fault *SpotInstanceStateFault `locationName:"fault" type:"structure"` // The AWS account ID of the account. - OwnerID *string `locationName:"ownerId" type:"string"` + OwnerId *string `locationName:"ownerId" type:"string"` // The prefix that is prepended to data feed files. Prefix *string `locationName:"prefix" type:"string"` - // The state of the Spot Instance data feed subscription. - State *string `locationName:"state" type:"string"` + // The state of the Spot instance data feed subscription. + State *string `locationName:"state" type:"string" enum:"DatafeedSubscriptionState"` metadataSpotDatafeedSubscription `json:"-" xml:"-"` } @@ -17865,16 +22006,138 @@ type metadataSpotDatafeedSubscription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SpotDatafeedSubscription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotDatafeedSubscription) GoString() string { + return s.String() +} + +// Describes the launch specification for one or more Spot instances. +type SpotFleetLaunchSpecification struct { + // Deprecated. + AddressingType *string `locationName:"addressingType" type:"string"` + + // One or more block device mapping entries. + BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` + + // Indicates whether the instances are optimized for EBS I/O. This optimization + // provides dedicated throughput to Amazon EBS and an optimized configuration + // stack to provide optimal EBS I/O performance. This optimization isn't available + // with all instance types. Additional usage charges apply when using an EBS + // Optimized instance. + // + // Default: false + EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + + // The IAM instance profile. + IamInstanceProfile *IamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` + + // The ID of the AMI. + ImageId *string `locationName:"imageId" type:"string"` + + // The instance type. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // The ID of the kernel. + KernelId *string `locationName:"kernelId" type:"string"` + + // The name of the key pair. + KeyName *string `locationName:"keyName" type:"string"` + + // Enable or disable monitoring for the instances. + Monitoring *SpotFleetMonitoring `locationName:"monitoring" type:"structure"` + + // One or more network interfaces. + NetworkInterfaces []*InstanceNetworkInterfaceSpecification `locationName:"networkInterfaceSet" locationNameList:"item" type:"list"` + + // The placement information. + Placement *SpotPlacement `locationName:"placement" type:"structure"` + + // The ID of the RAM disk. + RamdiskId *string `locationName:"ramdiskId" type:"string"` + + // One or more security groups. To request an instance in a nondefault VPC, + // you must specify the ID of the security group. To request an instance in + // EC2-Classic or a default VPC, you can specify the name or the ID of the security + // group. + SecurityGroups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` + + // The bid price per unit hour for the specified instance type. If this value + // is not specified, the default is the Spot bid price specified for the fleet. + // To determine the bid price per unit hour, divide the Spot bid price by the + // value of WeightedCapacity. + SpotPrice *string `locationName:"spotPrice" type:"string"` + + // The ID of the subnet in which to launch the instances. + SubnetId *string `locationName:"subnetId" type:"string"` + + // The Base64-encoded MIME user data to make available to the instances. + UserData *string `locationName:"userData" type:"string"` + + // The number of units provided by the specified instance type. These are the + // same units that you chose to set the target capacity in terms (instances + // or a performance characteristic such as vCPUs, memory, or I/O). + // + // If the target capacity divided by this value is not a whole number, we round + // the number of instances to the next whole number. If this value is not specified, + // the default is 1. + WeightedCapacity *float64 `locationName:"weightedCapacity" type:"double"` + + metadataSpotFleetLaunchSpecification `json:"-" xml:"-"` +} + +type metadataSpotFleetLaunchSpecification struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s SpotFleetLaunchSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotFleetLaunchSpecification) GoString() string { + return s.String() +} + +// Describes whether monitoring is enabled. +type SpotFleetMonitoring struct { + // Enables monitoring for the instance. + // + // Default: false + Enabled *bool `locationName:"enabled" type:"boolean"` + + metadataSpotFleetMonitoring `json:"-" xml:"-"` +} + +type metadataSpotFleetMonitoring struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s SpotFleetMonitoring) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotFleetMonitoring) GoString() string { + return s.String() +} + // Describes a Spot fleet request. type SpotFleetRequestConfig struct { // Information about the configuration of the Spot fleet request. SpotFleetRequestConfig *SpotFleetRequestConfigData `locationName:"spotFleetRequestConfig" type:"structure" required:"true"` // The ID of the Spot fleet request. - SpotFleetRequestID *string `locationName:"spotFleetRequestId" type:"string" required:"true"` + SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` // The state of the Spot fleet request. - SpotFleetRequestState *string `locationName:"spotFleetRequestState" type:"string" required:"true"` + SpotFleetRequestState *string `locationName:"spotFleetRequestState" type:"string" required:"true" enum:"BatchState"` metadataSpotFleetRequestConfig `json:"-" xml:"-"` } @@ -17883,30 +22146,45 @@ type metadataSpotFleetRequestConfig struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SpotFleetRequestConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotFleetRequestConfig) GoString() string { + return s.String() +} + // Describes the configuration of a Spot fleet request. type SpotFleetRequestConfigData struct { + // Determines how to allocate the target capacity across the Spot pools specified + // by the Spot fleet request. The default is lowestPrice. + AllocationStrategy *string `locationName:"allocationStrategy" type:"string" enum:"AllocationStrategy"` + // A unique, case-sensitive identifier you provide to ensure idempotency of // your listings. This helps avoid duplicate listings. For more information, // see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). ClientToken *string `locationName:"clientToken" type:"string"` - // Grants the Spot fleet service permission to terminate instances on your behalf - // when you cancel a Spot fleet request using CancelSpotFleetRequests or when + // Grants the Spot fleet permission to terminate Spot instances on your behalf + // when you cancel its Spot fleet request using CancelSpotFleetRequests or when // the Spot fleet request expires, if you set terminateInstancesWithExpiration. - IAMFleetRole *string `locationName:"iamFleetRole" type:"string" required:"true"` + IamFleetRole *string `locationName:"iamFleetRole" type:"string" required:"true"` - // Information about the launch specifications for the instances. - LaunchSpecifications []*LaunchSpecification `locationName:"launchSpecifications" locationNameList:"item" type:"list" required:"true"` + // Information about the launch specifications for the Spot fleet request. + LaunchSpecifications []*SpotFleetLaunchSpecification `locationName:"launchSpecifications" locationNameList:"item" min:"1" type:"list" required:"true"` - // The maximum hourly price (bid) for any Spot Instance launched to fulfill - // the request. + // The bid price per unit hour. SpotPrice *string `locationName:"spotPrice" type:"string" required:"true"` - // The maximum number of Spot Instances to launch. + // The number of units to request. You can choose to set the target capacity + // in terms of instances or a performance characteristic that is important to + // your application workload, such as vCPUs, memory, or I/O. TargetCapacity *int64 `locationName:"targetCapacity" type:"integer" required:"true"` - // Indicates whether running instances should be terminated when the Spot fleet - // request expires. + // Indicates whether running Spot instances should be terminated when the Spot + // fleet request expires. TerminateInstancesWithExpiration *bool `locationName:"terminateInstancesWithExpiration" type:"boolean"` // The start date and time of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). @@ -17914,7 +22192,7 @@ type SpotFleetRequestConfigData struct { ValidFrom *time.Time `locationName:"validFrom" type:"timestamp" timestampFormat:"iso8601"` // The end date and time of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). - // At this point, no new Spot Instance requests are placed or enabled to fulfill + // At this point, no new Spot instance requests are placed or enabled to fulfill // the request. ValidUntil *time.Time `locationName:"validUntil" type:"timestamp" timestampFormat:"iso8601"` @@ -17925,25 +22203,35 @@ type metadataSpotFleetRequestConfigData struct { SDKShapeTraits bool `type:"structure"` } -// Describe a Spot Instance request. +// String returns the string representation +func (s SpotFleetRequestConfigData) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotFleetRequestConfigData) GoString() string { + return s.String() +} + +// Describe a Spot instance request. type SpotInstanceRequest struct { // The Availability Zone group. If you specify the same Availability Zone group - // for all Spot Instance requests, all Spot Instances are launched in the same + // for all Spot instance requests, all Spot instances are launched in the same // Availability Zone. AvailabilityZoneGroup *string `locationName:"availabilityZoneGroup" type:"string"` - // The date and time when the Spot Instance request was created, in UTC format + // The date and time when the Spot instance request was created, in UTC format // (for example, YYYY-MM-DDTHH:MM:SSZ). CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601"` - // The fault codes for the Spot Instance request, if any. + // The fault codes for the Spot instance request, if any. Fault *SpotInstanceStateFault `locationName:"fault" type:"structure"` - // The instance ID, if an instance has been launched to fulfill the Spot Instance + // The instance ID, if an instance has been launched to fulfill the Spot instance // request. - InstanceID *string `locationName:"instanceId" type:"string"` + InstanceId *string `locationName:"instanceId" type:"string"` - // The instance launch group. Launch groups are Spot Instances that launch together + // The instance launch group. Launch groups are Spot instances that launch together // and terminate together. LaunchGroup *string `locationName:"launchGroup" type:"string"` @@ -17953,30 +22241,30 @@ type SpotInstanceRequest struct { // The Availability Zone in which the bid is launched. LaunchedAvailabilityZone *string `locationName:"launchedAvailabilityZone" type:"string"` - // The product description associated with the Spot Instance. - ProductDescription *string `locationName:"productDescription" type:"string"` + // The product description associated with the Spot instance. + ProductDescription *string `locationName:"productDescription" type:"string" enum:"RIProductDescription"` - // The ID of the Spot Instance request. - SpotInstanceRequestID *string `locationName:"spotInstanceRequestId" type:"string"` + // The ID of the Spot instance request. + SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` - // The maximum hourly price (bid) for any Spot Instance launched to fulfill + // The maximum hourly price (bid) for any Spot instance launched to fulfill // the request. SpotPrice *string `locationName:"spotPrice" type:"string"` - // The state of the Spot Instance request. Spot bid status information can help - // you track your Spot Instance requests. For more information, see Spot Bid + // The state of the Spot instance request. Spot bid status information can help + // you track your Spot instance requests. For more information, see Spot Bid // Status (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html) // in the Amazon Elastic Compute Cloud User Guide. - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"SpotInstanceState"` - // The status code and status message describing the Spot Instance request. + // The status code and status message describing the Spot instance request. Status *SpotInstanceStatus `locationName:"status" type:"structure"` // Any tags assigned to the resource. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` - // The Spot Instance request type. - Type *string `locationName:"type" type:"string"` + // The Spot instance request type. + Type *string `locationName:"type" type:"string" enum:"SpotInstanceType"` // The start date of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). // If this is a one-time request, the request becomes active at this date and @@ -17998,12 +22286,22 @@ type metadataSpotInstanceRequest struct { SDKShapeTraits bool `type:"structure"` } -// Describes a Spot Instance state change. +// String returns the string representation +func (s SpotInstanceRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotInstanceRequest) GoString() string { + return s.String() +} + +// Describes a Spot instance state change. type SpotInstanceStateFault struct { - // The reason code for the Spot Instance state change. + // The reason code for the Spot instance state change. Code *string `locationName:"code" type:"string"` - // The message for the Spot Instance state change. + // The message for the Spot instance state change. Message *string `locationName:"message" type:"string"` metadataSpotInstanceStateFault `json:"-" xml:"-"` @@ -18013,7 +22311,17 @@ type metadataSpotInstanceStateFault struct { SDKShapeTraits bool `type:"structure"` } -// Describes the status of a Spot Instance request. +// String returns the string representation +func (s SpotInstanceStateFault) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotInstanceStateFault) GoString() string { + return s.String() +} + +// Describes the status of a Spot instance request. type SpotInstanceStatus struct { // The status code. Code *string `locationName:"code" type:"string"` @@ -18032,7 +22340,17 @@ type metadataSpotInstanceStatus struct { SDKShapeTraits bool `type:"structure"` } -// Describes Spot Instance placement. +// String returns the string representation +func (s SpotInstanceStatus) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotInstanceStatus) GoString() string { + return s.String() +} + +// Describes Spot instance placement. type SpotPlacement struct { // The Availability Zone. AvailabilityZone *string `locationName:"availabilityZone" type:"string"` @@ -18047,19 +22365,29 @@ type metadataSpotPlacement struct { SDKShapeTraits bool `type:"structure"` } -// Describes the maximum hourly price (bid) for any Spot Instance launched to +// String returns the string representation +func (s SpotPlacement) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotPlacement) GoString() string { + return s.String() +} + +// Describes the maximum hourly price (bid) for any Spot instance launched to // fulfill the request. type SpotPrice struct { // The Availability Zone. AvailabilityZone *string `locationName:"availabilityZone" type:"string"` // The instance type. - InstanceType *string `locationName:"instanceType" type:"string"` + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` // A general description of the AMI. - ProductDescription *string `locationName:"productDescription" type:"string"` + ProductDescription *string `locationName:"productDescription" type:"string" enum:"RIProductDescription"` - // The maximum price (bid) that you are willing to pay for a Spot Instance. + // The maximum price (bid) that you are willing to pay for a Spot instance. SpotPrice *string `locationName:"spotPrice" type:"string"` // The date and time the request was created, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). @@ -18072,7 +22400,17 @@ type metadataSpotPrice struct { SDKShapeTraits bool `type:"structure"` } -type StartInstancesInput struct { +// String returns the string representation +func (s SpotPrice) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotPrice) GoString() string { + return s.String() +} + +type StartInstancesInput struct { // Reserved. AdditionalInfo *string `locationName:"additionalInfo" type:"string"` @@ -18083,7 +22421,7 @@ type StartInstancesInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // One or more instance IDs. - InstanceIDs []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` metadataStartInstancesInput `json:"-" xml:"-"` } @@ -18092,6 +22430,16 @@ type metadataStartInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s StartInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartInstancesInput) GoString() string { + return s.String() +} + type StartInstancesOutput struct { // Information about one or more started instances. StartingInstances []*InstanceStateChange `locationName:"instancesSet" locationNameList:"item" type:"list"` @@ -18103,6 +22451,16 @@ type metadataStartInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s StartInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartInstancesOutput) GoString() string { + return s.String() +} + // Describes a state change. type StateReason struct { // The reason code for the state change. @@ -18140,6 +22498,16 @@ type metadataStateReason struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s StateReason) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StateReason) GoString() string { + return s.String() +} + type StopInstancesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -18156,7 +22524,7 @@ type StopInstancesInput struct { Force *bool `locationName:"force" type:"boolean"` // One or more instance IDs. - InstanceIDs []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` metadataStopInstancesInput `json:"-" xml:"-"` } @@ -18165,6 +22533,16 @@ type metadataStopInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s StopInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopInstancesInput) GoString() string { + return s.String() +} + type StopInstancesOutput struct { // Information about one or more stopped instances. StoppingInstances []*InstanceStateChange `locationName:"instancesSet" locationNameList:"item" type:"list"` @@ -18176,6 +22554,16 @@ type metadataStopInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s StopInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopInstancesOutput) GoString() string { + return s.String() +} + // Describes the storage location for an instance store-backed AMI. type Storage struct { // An Amazon S3 storage location. @@ -18188,6 +22576,16 @@ type metadataStorage struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Storage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Storage) GoString() string { + return s.String() +} + // Describes a subnet. type Subnet struct { // The Availability Zone of the subnet. @@ -18195,28 +22593,28 @@ type Subnet struct { // The number of unused IP addresses in the subnet. Note that the IP addresses // for any stopped instances are considered unavailable. - AvailableIPAddressCount *int64 `locationName:"availableIpAddressCount" type:"integer"` + AvailableIpAddressCount *int64 `locationName:"availableIpAddressCount" type:"integer"` // The CIDR block assigned to the subnet. - CIDRBlock *string `locationName:"cidrBlock" type:"string"` + CidrBlock *string `locationName:"cidrBlock" type:"string"` // Indicates whether this is the default subnet for the Availability Zone. - DefaultForAZ *bool `locationName:"defaultForAz" type:"boolean"` + DefaultForAz *bool `locationName:"defaultForAz" type:"boolean"` // Indicates whether instances launched in this subnet receive a public IP address. - MapPublicIPOnLaunch *bool `locationName:"mapPublicIpOnLaunch" type:"boolean"` + MapPublicIpOnLaunch *bool `locationName:"mapPublicIpOnLaunch" type:"boolean"` // The current state of the subnet. - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"SubnetState"` // The ID of the subnet. - SubnetID *string `locationName:"subnetId" type:"string"` + SubnetId *string `locationName:"subnetId" type:"string"` // Any tags assigned to the subnet. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` // The ID of the VPC the subnet is in. - VPCID *string `locationName:"vpcId" type:"string"` + VpcId *string `locationName:"vpcId" type:"string"` metadataSubnet `json:"-" xml:"-"` } @@ -18225,6 +22623,16 @@ type metadataSubnet struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Subnet) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Subnet) GoString() string { + return s.String() +} + // Describes a tag. type Tag struct { // The key of the tag. @@ -18246,16 +22654,26 @@ type metadataTag struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Tag) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Tag) GoString() string { + return s.String() +} + // Describes a tag. type TagDescription struct { // The tag key. Key *string `locationName:"key" type:"string"` // The ID of the resource. For example, ami-1a2b3c4d. - ResourceID *string `locationName:"resourceId" type:"string"` + ResourceId *string `locationName:"resourceId" type:"string"` // The resource type. - ResourceType *string `locationName:"resourceType" type:"string"` + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` // The tag value. Value *string `locationName:"value" type:"string"` @@ -18267,6 +22685,16 @@ type metadataTagDescription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s TagDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagDescription) GoString() string { + return s.String() +} + type TerminateInstancesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -18275,7 +22703,7 @@ type TerminateInstancesInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // One or more instance IDs. - InstanceIDs []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` metadataTerminateInstancesInput `json:"-" xml:"-"` } @@ -18284,6 +22712,16 @@ type metadataTerminateInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s TerminateInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TerminateInstancesInput) GoString() string { + return s.String() +} + type TerminateInstancesOutput struct { // Information about one or more terminated instances. TerminatingInstances []*InstanceStateChange `locationName:"instancesSet" locationNameList:"item" type:"list"` @@ -18295,29 +22733,59 @@ type metadataTerminateInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } -type UnassignPrivateIPAddressesInput struct { +// String returns the string representation +func (s TerminateInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TerminateInstancesOutput) GoString() string { + return s.String() +} + +type UnassignPrivateIpAddressesInput struct { // The ID of the network interface. - NetworkInterfaceID *string `locationName:"networkInterfaceId" type:"string" required:"true"` + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string" required:"true"` // The secondary private IP addresses to unassign from the network interface. // You can specify this option multiple times to unassign more than one IP address. - PrivateIPAddresses []*string `locationName:"privateIpAddress" locationNameList:"PrivateIpAddress" type:"list" required:"true"` + PrivateIpAddresses []*string `locationName:"privateIpAddress" locationNameList:"PrivateIpAddress" type:"list" required:"true"` - metadataUnassignPrivateIPAddressesInput `json:"-" xml:"-"` + metadataUnassignPrivateIpAddressesInput `json:"-" xml:"-"` } -type metadataUnassignPrivateIPAddressesInput struct { +type metadataUnassignPrivateIpAddressesInput struct { SDKShapeTraits bool `type:"structure"` } -type UnassignPrivateIPAddressesOutput struct { - metadataUnassignPrivateIPAddressesOutput `json:"-" xml:"-"` +// String returns the string representation +func (s UnassignPrivateIpAddressesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnassignPrivateIpAddressesInput) GoString() string { + return s.String() } -type metadataUnassignPrivateIPAddressesOutput struct { +type UnassignPrivateIpAddressesOutput struct { + metadataUnassignPrivateIpAddressesOutput `json:"-" xml:"-"` +} + +type metadataUnassignPrivateIpAddressesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s UnassignPrivateIpAddressesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnassignPrivateIpAddressesOutput) GoString() string { + return s.String() +} + type UnmonitorInstancesInput struct { // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have @@ -18326,7 +22794,7 @@ type UnmonitorInstancesInput struct { DryRun *bool `locationName:"dryRun" type:"boolean"` // One or more instance IDs. - InstanceIDs []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list" required:"true"` metadataUnmonitorInstancesInput `json:"-" xml:"-"` } @@ -18335,6 +22803,16 @@ type metadataUnmonitorInstancesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s UnmonitorInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnmonitorInstancesInput) GoString() string { + return s.String() +} + type UnmonitorInstancesOutput struct { // Monitoring information for one or more instances. InstanceMonitorings []*InstanceMonitoring `locationName:"instancesSet" locationNameList:"item" type:"list"` @@ -18346,13 +22824,23 @@ type metadataUnmonitorInstancesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s UnmonitorInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnmonitorInstancesOutput) GoString() string { + return s.String() +} + // Information about items that were not successfully processed in a batch call. type UnsuccessfulItem struct { // Information about the error. Error *UnsuccessfulItemError `locationName:"error" type:"structure" required:"true"` // The ID of the resource. - ResourceID *string `locationName:"resourceId" type:"string"` + ResourceId *string `locationName:"resourceId" type:"string"` metadataUnsuccessfulItem `json:"-" xml:"-"` } @@ -18361,7 +22849,17 @@ type metadataUnsuccessfulItem struct { SDKShapeTraits bool `type:"structure"` } -// Information about the error that occured. For more information about errors, +// String returns the string representation +func (s UnsuccessfulItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnsuccessfulItem) GoString() string { + return s.String() +} + +// Information about the error that occurred. For more information about errors, // see Error Codes (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html). type UnsuccessfulItemError struct { // The error code. @@ -18377,6 +22875,16 @@ type metadataUnsuccessfulItemError struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s UnsuccessfulItemError) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnsuccessfulItemError) GoString() string { + return s.String() +} + // Describes the S3 bucket for the disk image. type UserBucket struct { // The name of the S3 bucket where the disk image is located. @@ -18392,6 +22900,16 @@ type metadataUserBucket struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s UserBucket) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UserBucket) GoString() string { + return s.String() +} + // Describes the S3 bucket for the disk image. type UserBucketDetails struct { // The S3 bucket from which the disk image was created. @@ -18407,6 +22925,16 @@ type metadataUserBucketDetails struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s UserBucketDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UserBucketDetails) GoString() string { + return s.String() +} + // Describes the user data to be made available to an instance. type UserData struct { // The Base64-encoded MIME user data for the instance. @@ -18419,10 +22947,20 @@ type metadataUserData struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s UserData) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UserData) GoString() string { + return s.String() +} + // Describes a security group and AWS account ID pair. -type UserIDGroupPair struct { +type UserIdGroupPair struct { // The ID of the security group. - GroupID *string `locationName:"groupId" type:"string"` + GroupId *string `locationName:"groupId" type:"string"` // The name of the security group. In a request, use this parameter for a security // group in EC2-Classic or a default VPC only. For a security group in a nondefault @@ -18430,17 +22968,27 @@ type UserIDGroupPair struct { GroupName *string `locationName:"groupName" type:"string"` // The ID of an AWS account. EC2-Classic only. - UserID *string `locationName:"userId" type:"string"` + UserId *string `locationName:"userId" type:"string"` - metadataUserIDGroupPair `json:"-" xml:"-"` + metadataUserIdGroupPair `json:"-" xml:"-"` } -type metadataUserIDGroupPair struct { +type metadataUserIdGroupPair struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s UserIdGroupPair) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UserIdGroupPair) GoString() string { + return s.String() +} + // Describes telemetry for a VPN tunnel. -type VGWTelemetry struct { +type VgwTelemetry struct { // The number of accepted routes. AcceptedRouteCount *int64 `locationName:"acceptedRouteCount" type:"integer"` @@ -18449,481 +22997,1574 @@ type VGWTelemetry struct { // The Internet-routable IP address of the virtual private gateway's outside // interface. - OutsideIPAddress *string `locationName:"outsideIpAddress" type:"string"` + OutsideIpAddress *string `locationName:"outsideIpAddress" type:"string"` // The status of the VPN tunnel. - Status *string `locationName:"status" type:"string"` + Status *string `locationName:"status" type:"string" enum:"TelemetryStatus"` // If an error occurs, a description of the error. StatusMessage *string `locationName:"statusMessage" type:"string"` - metadataVGWTelemetry `json:"-" xml:"-"` + metadataVgwTelemetry `json:"-" xml:"-"` } -type metadataVGWTelemetry struct { +type metadataVgwTelemetry struct { SDKShapeTraits bool `type:"structure"` } -// Describes a VPC. -type VPC struct { - // The CIDR block for the VPC. - CIDRBlock *string `locationName:"cidrBlock" type:"string"` - - // The ID of the set of DHCP options you've associated with the VPC (or default - // if the default options are associated with the VPC). - DHCPOptionsID *string `locationName:"dhcpOptionsId" type:"string"` - - // The allowed tenancy of instances launched into the VPC. - InstanceTenancy *string `locationName:"instanceTenancy" type:"string"` - - // Indicates whether the VPC is the default VPC. - IsDefault *bool `locationName:"isDefault" type:"boolean"` +// String returns the string representation +func (s VgwTelemetry) String() string { + return awsutil.Prettify(s) +} - // The current state of the VPC. - State *string `locationName:"state" type:"string"` +// GoString returns the string representation +func (s VgwTelemetry) GoString() string { + return s.String() +} - // Any tags assigned to the VPC. - Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` +// Describes a volume. +type Volume struct { + // Information about the volume attachments. + Attachments []*VolumeAttachment `locationName:"attachmentSet" locationNameList:"item" type:"list"` - // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string"` + // The Availability Zone for the volume. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` - metadataVPC `json:"-" xml:"-"` -} + // The time stamp when volume creation was initiated. + CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601"` -type metadataVPC struct { - SDKShapeTraits bool `type:"structure"` -} + // Indicates whether the volume will be encrypted. + Encrypted *bool `locationName:"encrypted" type:"boolean"` -// Describes an attachment between a virtual private gateway and a VPC. -type VPCAttachment struct { - // The current state of the attachment. - State *string `locationName:"state" type:"string"` + // The number of I/O operations per second (IOPS) that the volume supports. + // For Provisioned IOPS (SSD) volumes, this represents the number of IOPS that + // are provisioned for the volume. For General Purpose (SSD) volumes, this represents + // the baseline performance of the volume and the rate at which the volume accumulates + // I/O credits for bursting. For more information on General Purpose (SSD) baseline + // performance, I/O credits, and bursting, see Amazon EBS Volume Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html) + // in the Amazon Elastic Compute Cloud User Guide. + // + // Constraint: Range is 100 to 20000 for Provisioned IOPS (SSD) volumes and + // 3 to 10000 for General Purpose (SSD) volumes. + // + // Condition: This parameter is required for requests to create io1 volumes; + // it is not used in requests to create standard or gp2 volumes. + Iops *int64 `locationName:"iops" type:"integer"` - // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string"` + // The full ARN of the AWS Key Management Service (AWS KMS) customer master + // key (CMK) that was used to protect the volume encryption key for the volume. + KmsKeyId *string `locationName:"kmsKeyId" type:"string"` - metadataVPCAttachment `json:"-" xml:"-"` -} + // The size of the volume, in GiBs. + Size *int64 `locationName:"size" type:"integer"` -type metadataVPCAttachment struct { - SDKShapeTraits bool `type:"structure"` -} + // The snapshot from which the volume was created, if applicable. + SnapshotId *string `locationName:"snapshotId" type:"string"` -// Describes whether a VPC is enabled for ClassicLink. -type VPCClassicLink struct { - // Indicates whether the VPC is enabled for ClassicLink. - ClassicLinkEnabled *bool `locationName:"classicLinkEnabled" type:"boolean"` + // The volume state. + State *string `locationName:"status" type:"string" enum:"VolumeState"` - // Any tags assigned to the VPC. + // Any tags assigned to the volume. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` - // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string"` + // The ID of the volume. + VolumeId *string `locationName:"volumeId" type:"string"` - metadataVPCClassicLink `json:"-" xml:"-"` + // The volume type. This can be gp2 for General Purpose (SSD) volumes, io1 for + // Provisioned IOPS (SSD) volumes, or standard for Magnetic volumes. + VolumeType *string `locationName:"volumeType" type:"string" enum:"VolumeType"` + + metadataVolume `json:"-" xml:"-"` } -type metadataVPCClassicLink struct { +type metadataVolume struct { SDKShapeTraits bool `type:"structure"` } -// Describes a VPC endpoint. -type VPCEndpoint struct { - // The date and time the VPC endpoint was created. - CreationTimestamp *time.Time `locationName:"creationTimestamp" type:"timestamp" timestampFormat:"iso8601"` +// String returns the string representation +func (s Volume) String() string { + return awsutil.Prettify(s) +} - // The policy document associated with the endpoint. - PolicyDocument *string `locationName:"policyDocument" type:"string"` +// GoString returns the string representation +func (s Volume) GoString() string { + return s.String() +} - // One or more route tables associated with the endpoint. - RouteTableIDs []*string `locationName:"routeTableIdSet" locationNameList:"item" type:"list"` +// Describes volume attachment details. +type VolumeAttachment struct { + // The time stamp when the attachment initiated. + AttachTime *time.Time `locationName:"attachTime" type:"timestamp" timestampFormat:"iso8601"` - // The name of the AWS service to which the endpoint is associated. - ServiceName *string `locationName:"serviceName" type:"string"` + // Indicates whether the EBS volume is deleted on instance termination. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` - // The state of the VPC endpoint. - State *string `locationName:"state" type:"string"` + // The device name. + Device *string `locationName:"device" type:"string"` - // The ID of the VPC endpoint. - VPCEndpointID *string `locationName:"vpcEndpointId" type:"string"` + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` - // The ID of the VPC to which the endpoint is associated. - VPCID *string `locationName:"vpcId" type:"string"` + // The attachment state of the volume. + State *string `locationName:"status" type:"string" enum:"VolumeAttachmentState"` + + // The ID of the volume. + VolumeId *string `locationName:"volumeId" type:"string"` - metadataVPCEndpoint `json:"-" xml:"-"` + metadataVolumeAttachment `json:"-" xml:"-"` } -type metadataVPCEndpoint struct { +type metadataVolumeAttachment struct { SDKShapeTraits bool `type:"structure"` } -// Describes a VPC peering connection. -type VPCPeeringConnection struct { - // The information of the peer VPC. - AccepterVPCInfo *VPCPeeringConnectionVPCInfo `locationName:"accepterVpcInfo" type:"structure"` - - // The time that an unaccepted VPC peering connection will expire. - ExpirationTime *time.Time `locationName:"expirationTime" type:"timestamp" timestampFormat:"iso8601"` +// String returns the string representation +func (s VolumeAttachment) String() string { + return awsutil.Prettify(s) +} - // The information of the requester VPC. - RequesterVPCInfo *VPCPeeringConnectionVPCInfo `locationName:"requesterVpcInfo" type:"structure"` +// GoString returns the string representation +func (s VolumeAttachment) GoString() string { + return s.String() +} - // The status of the VPC peering connection. - Status *VPCPeeringConnectionStateReason `locationName:"status" type:"structure"` +// Describes an EBS volume. +type VolumeDetail struct { + // The size of the volume, in GiB. + Size *int64 `locationName:"size" type:"long" required:"true"` - // Any tags assigned to the resource. - Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + metadataVolumeDetail `json:"-" xml:"-"` +} - // The ID of the VPC peering connection. - VPCPeeringConnectionID *string `locationName:"vpcPeeringConnectionId" type:"string"` +type metadataVolumeDetail struct { + SDKShapeTraits bool `type:"structure"` +} - metadataVPCPeeringConnection `json:"-" xml:"-"` +// String returns the string representation +func (s VolumeDetail) String() string { + return awsutil.Prettify(s) } -type metadataVPCPeeringConnection struct { - SDKShapeTraits bool `type:"structure"` +// GoString returns the string representation +func (s VolumeDetail) GoString() string { + return s.String() } -// Describes the status of a VPC peering connection. -type VPCPeeringConnectionStateReason struct { - // The status of the VPC peering connection. +// Describes a volume status operation code. +type VolumeStatusAction struct { + // The code identifying the operation, for example, enable-volume-io. Code *string `locationName:"code" type:"string"` - // A message that provides more information about the status, if applicable. - Message *string `locationName:"message" type:"string"` + // A description of the operation. + Description *string `locationName:"description" type:"string"` - metadataVPCPeeringConnectionStateReason `json:"-" xml:"-"` + // The ID of the event associated with this operation. + EventId *string `locationName:"eventId" type:"string"` + + // The event type associated with this operation. + EventType *string `locationName:"eventType" type:"string"` + + metadataVolumeStatusAction `json:"-" xml:"-"` } -type metadataVPCPeeringConnectionStateReason struct { +type metadataVolumeStatusAction struct { SDKShapeTraits bool `type:"structure"` } -// Describes a VPC in a VPC peering connection. -type VPCPeeringConnectionVPCInfo struct { - // The CIDR block for the VPC. - CIDRBlock *string `locationName:"cidrBlock" type:"string"` +// String returns the string representation +func (s VolumeStatusAction) String() string { + return awsutil.Prettify(s) +} - // The AWS account ID of the VPC owner. - OwnerID *string `locationName:"ownerId" type:"string"` +// GoString returns the string representation +func (s VolumeStatusAction) GoString() string { + return s.String() +} - // The ID of the VPC. - VPCID *string `locationName:"vpcId" type:"string"` +// Describes a volume status. +type VolumeStatusDetails struct { + // The name of the volume status. + Name *string `locationName:"name" type:"string" enum:"VolumeStatusName"` - metadataVPCPeeringConnectionVPCInfo `json:"-" xml:"-"` + // The intended status of the volume status. + Status *string `locationName:"status" type:"string"` + + metadataVolumeStatusDetails `json:"-" xml:"-"` } -type metadataVPCPeeringConnectionVPCInfo struct { +type metadataVolumeStatusDetails struct { SDKShapeTraits bool `type:"structure"` } -// Describes a VPN connection. -type VPNConnection struct { - // The configuration information for the VPN connection's customer gateway (in - // the native XML format). This element is always present in the CreateVpnConnection - // response; however, it's present in the DescribeVpnConnections response only - // if the VPN connection is in the pending or available state. - CustomerGatewayConfiguration *string `locationName:"customerGatewayConfiguration" type:"string"` - - // The ID of the customer gateway at your end of the VPN connection. - CustomerGatewayID *string `locationName:"customerGatewayId" type:"string"` +// String returns the string representation +func (s VolumeStatusDetails) String() string { + return awsutil.Prettify(s) +} - // The VPN connection options. - Options *VPNConnectionOptions `locationName:"options" type:"structure"` +// GoString returns the string representation +func (s VolumeStatusDetails) GoString() string { + return s.String() +} - // The static routes associated with the VPN connection. - Routes []*VPNStaticRoute `locationName:"routes" locationNameList:"item" type:"list"` +// Describes a volume status event. +type VolumeStatusEvent struct { + // A description of the event. + Description *string `locationName:"description" type:"string"` - // The current state of the VPN connection. - State *string `locationName:"state" type:"string"` + // The ID of this event. + EventId *string `locationName:"eventId" type:"string"` + + // The type of this event. + EventType *string `locationName:"eventType" type:"string"` + + // The latest end time of the event. + NotAfter *time.Time `locationName:"notAfter" type:"timestamp" timestampFormat:"iso8601"` + + // The earliest start time of the event. + NotBefore *time.Time `locationName:"notBefore" type:"timestamp" timestampFormat:"iso8601"` + + metadataVolumeStatusEvent `json:"-" xml:"-"` +} + +type metadataVolumeStatusEvent struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s VolumeStatusEvent) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VolumeStatusEvent) GoString() string { + return s.String() +} + +// Describes the status of a volume. +type VolumeStatusInfo struct { + // The details of the volume status. + Details []*VolumeStatusDetails `locationName:"details" locationNameList:"item" type:"list"` + + // The status of the volume. + Status *string `locationName:"status" type:"string" enum:"VolumeStatusInfoStatus"` + + metadataVolumeStatusInfo `json:"-" xml:"-"` +} + +type metadataVolumeStatusInfo struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s VolumeStatusInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VolumeStatusInfo) GoString() string { + return s.String() +} + +// Describes the volume status. +type VolumeStatusItem struct { + // The details of the operation. + Actions []*VolumeStatusAction `locationName:"actionsSet" locationNameList:"item" type:"list"` + + // The Availability Zone of the volume. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // A list of events associated with the volume. + Events []*VolumeStatusEvent `locationName:"eventsSet" locationNameList:"item" type:"list"` + + // The volume ID. + VolumeId *string `locationName:"volumeId" type:"string"` + + // The volume status. + VolumeStatus *VolumeStatusInfo `locationName:"volumeStatus" type:"structure"` + + metadataVolumeStatusItem `json:"-" xml:"-"` +} + +type metadataVolumeStatusItem struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s VolumeStatusItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VolumeStatusItem) GoString() string { + return s.String() +} + +// Describes a VPC. +type Vpc struct { + // The CIDR block for the VPC. + CidrBlock *string `locationName:"cidrBlock" type:"string"` + + // The ID of the set of DHCP options you've associated with the VPC (or default + // if the default options are associated with the VPC). + DhcpOptionsId *string `locationName:"dhcpOptionsId" type:"string"` + + // The allowed tenancy of instances launched into the VPC. + InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` + + // Indicates whether the VPC is the default VPC. + IsDefault *bool `locationName:"isDefault" type:"boolean"` + + // The current state of the VPC. + State *string `locationName:"state" type:"string" enum:"VpcState"` + + // Any tags assigned to the VPC. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` + + metadataVpc `json:"-" xml:"-"` +} + +type metadataVpc struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s Vpc) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Vpc) GoString() string { + return s.String() +} + +// Describes an attachment between a virtual private gateway and a VPC. +type VpcAttachment struct { + // The current state of the attachment. + State *string `locationName:"state" type:"string" enum:"AttachmentStatus"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` + + metadataVpcAttachment `json:"-" xml:"-"` +} + +type metadataVpcAttachment struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s VpcAttachment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcAttachment) GoString() string { + return s.String() +} + +// Describes whether a VPC is enabled for ClassicLink. +type VpcClassicLink struct { + // Indicates whether the VPC is enabled for ClassicLink. + ClassicLinkEnabled *bool `locationName:"classicLinkEnabled" type:"boolean"` + + // Any tags assigned to the VPC. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` + + metadataVpcClassicLink `json:"-" xml:"-"` +} + +type metadataVpcClassicLink struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s VpcClassicLink) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcClassicLink) GoString() string { + return s.String() +} + +// Describes a VPC endpoint. +type VpcEndpoint struct { + // The date and time the VPC endpoint was created. + CreationTimestamp *time.Time `locationName:"creationTimestamp" type:"timestamp" timestampFormat:"iso8601"` + + // The policy document associated with the endpoint. + PolicyDocument *string `locationName:"policyDocument" type:"string"` + + // One or more route tables associated with the endpoint. + RouteTableIds []*string `locationName:"routeTableIdSet" locationNameList:"item" type:"list"` + + // The name of the AWS service to which the endpoint is associated. + ServiceName *string `locationName:"serviceName" type:"string"` + + // The state of the VPC endpoint. + State *string `locationName:"state" type:"string" enum:"State"` + + // The ID of the VPC endpoint. + VpcEndpointId *string `locationName:"vpcEndpointId" type:"string"` + + // The ID of the VPC to which the endpoint is associated. + VpcId *string `locationName:"vpcId" type:"string"` + + metadataVpcEndpoint `json:"-" xml:"-"` +} + +type metadataVpcEndpoint struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s VpcEndpoint) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcEndpoint) GoString() string { + return s.String() +} + +// Describes a VPC peering connection. +type VpcPeeringConnection struct { + // The information of the peer VPC. + AccepterVpcInfo *VpcPeeringConnectionVpcInfo `locationName:"accepterVpcInfo" type:"structure"` + + // The time that an unaccepted VPC peering connection will expire. + ExpirationTime *time.Time `locationName:"expirationTime" type:"timestamp" timestampFormat:"iso8601"` + + // The information of the requester VPC. + RequesterVpcInfo *VpcPeeringConnectionVpcInfo `locationName:"requesterVpcInfo" type:"structure"` + + // The status of the VPC peering connection. + Status *VpcPeeringConnectionStateReason `locationName:"status" type:"structure"` + + // Any tags assigned to the resource. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + + // The ID of the VPC peering connection. + VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` + + metadataVpcPeeringConnection `json:"-" xml:"-"` +} + +type metadataVpcPeeringConnection struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s VpcPeeringConnection) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcPeeringConnection) GoString() string { + return s.String() +} + +// Describes the status of a VPC peering connection. +type VpcPeeringConnectionStateReason struct { + // The status of the VPC peering connection. + Code *string `locationName:"code" type:"string" enum:"VpcPeeringConnectionStateReasonCode"` + + // A message that provides more information about the status, if applicable. + Message *string `locationName:"message" type:"string"` + + metadataVpcPeeringConnectionStateReason `json:"-" xml:"-"` +} + +type metadataVpcPeeringConnectionStateReason struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s VpcPeeringConnectionStateReason) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcPeeringConnectionStateReason) GoString() string { + return s.String() +} + +// Describes a VPC in a VPC peering connection. +type VpcPeeringConnectionVpcInfo struct { + // The CIDR block for the VPC. + CidrBlock *string `locationName:"cidrBlock" type:"string"` + + // The AWS account ID of the VPC owner. + OwnerId *string `locationName:"ownerId" type:"string"` + + // The ID of the VPC. + VpcId *string `locationName:"vpcId" type:"string"` + + metadataVpcPeeringConnectionVpcInfo `json:"-" xml:"-"` +} + +type metadataVpcPeeringConnectionVpcInfo struct { + SDKShapeTraits bool `type:"structure"` +} + +// String returns the string representation +func (s VpcPeeringConnectionVpcInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcPeeringConnectionVpcInfo) GoString() string { + return s.String() +} + +// Describes a VPN connection. +type VpnConnection struct { + // The configuration information for the VPN connection's customer gateway (in + // the native XML format). This element is always present in the CreateVpnConnection + // response; however, it's present in the DescribeVpnConnections response only + // if the VPN connection is in the pending or available state. + CustomerGatewayConfiguration *string `locationName:"customerGatewayConfiguration" type:"string"` + + // The ID of the customer gateway at your end of the VPN connection. + CustomerGatewayId *string `locationName:"customerGatewayId" type:"string"` + + // The VPN connection options. + Options *VpnConnectionOptions `locationName:"options" type:"structure"` + + // The static routes associated with the VPN connection. + Routes []*VpnStaticRoute `locationName:"routes" locationNameList:"item" type:"list"` + + // The current state of the VPN connection. + State *string `locationName:"state" type:"string" enum:"VpnState"` // Any tags assigned to the VPN connection. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` // The type of VPN connection. - Type *string `locationName:"type" type:"string"` + Type *string `locationName:"type" type:"string" enum:"GatewayType"` // Information about the VPN tunnel. - VGWTelemetry []*VGWTelemetry `locationName:"vgwTelemetry" locationNameList:"item" type:"list"` + VgwTelemetry []*VgwTelemetry `locationName:"vgwTelemetry" locationNameList:"item" type:"list"` // The ID of the VPN connection. - VPNConnectionID *string `locationName:"vpnConnectionId" type:"string"` + VpnConnectionId *string `locationName:"vpnConnectionId" type:"string"` // The ID of the virtual private gateway at the AWS side of the VPN connection. - VPNGatewayID *string `locationName:"vpnGatewayId" type:"string"` + VpnGatewayId *string `locationName:"vpnGatewayId" type:"string"` - metadataVPNConnection `json:"-" xml:"-"` + metadataVpnConnection `json:"-" xml:"-"` } -type metadataVPNConnection struct { +type metadataVpnConnection struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s VpnConnection) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpnConnection) GoString() string { + return s.String() +} + // Describes VPN connection options. -type VPNConnectionOptions struct { +type VpnConnectionOptions struct { // Indicates whether the VPN connection uses static routes only. Static routes // must be used for devices that don't support BGP. StaticRoutesOnly *bool `locationName:"staticRoutesOnly" type:"boolean"` - metadataVPNConnectionOptions `json:"-" xml:"-"` + metadataVpnConnectionOptions `json:"-" xml:"-"` } -type metadataVPNConnectionOptions struct { +type metadataVpnConnectionOptions struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s VpnConnectionOptions) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpnConnectionOptions) GoString() string { + return s.String() +} + // Describes VPN connection options. -type VPNConnectionOptionsSpecification struct { +type VpnConnectionOptionsSpecification struct { // Indicates whether the VPN connection uses static routes only. Static routes // must be used for devices that don't support BGP. StaticRoutesOnly *bool `locationName:"staticRoutesOnly" type:"boolean"` - metadataVPNConnectionOptionsSpecification `json:"-" xml:"-"` + metadataVpnConnectionOptionsSpecification `json:"-" xml:"-"` } -type metadataVPNConnectionOptionsSpecification struct { +type metadataVpnConnectionOptionsSpecification struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s VpnConnectionOptionsSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpnConnectionOptionsSpecification) GoString() string { + return s.String() +} + // Describes a virtual private gateway. -type VPNGateway struct { +type VpnGateway struct { // The Availability Zone where the virtual private gateway was created. AvailabilityZone *string `locationName:"availabilityZone" type:"string"` // The current state of the virtual private gateway. - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"VpnState"` // Any tags assigned to the virtual private gateway. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` // The type of VPN connection the virtual private gateway supports. - Type *string `locationName:"type" type:"string"` + Type *string `locationName:"type" type:"string" enum:"GatewayType"` // Any VPCs attached to the virtual private gateway. - VPCAttachments []*VPCAttachment `locationName:"attachments" locationNameList:"item" type:"list"` + VpcAttachments []*VpcAttachment `locationName:"attachments" locationNameList:"item" type:"list"` // The ID of the virtual private gateway. - VPNGatewayID *string `locationName:"vpnGatewayId" type:"string"` + VpnGatewayId *string `locationName:"vpnGatewayId" type:"string"` - metadataVPNGateway `json:"-" xml:"-"` + metadataVpnGateway `json:"-" xml:"-"` } -type metadataVPNGateway struct { +type metadataVpnGateway struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s VpnGateway) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpnGateway) GoString() string { + return s.String() +} + // Describes a static route for a VPN connection. -type VPNStaticRoute struct { +type VpnStaticRoute struct { // The CIDR block associated with the local subnet of the customer data center. - DestinationCIDRBlock *string `locationName:"destinationCidrBlock" type:"string"` + DestinationCidrBlock *string `locationName:"destinationCidrBlock" type:"string"` // Indicates how the routes were provided. - Source *string `locationName:"source" type:"string"` + Source *string `locationName:"source" type:"string" enum:"VpnStaticRouteSource"` // The current state of the static route. - State *string `locationName:"state" type:"string"` + State *string `locationName:"state" type:"string" enum:"VpnState"` - metadataVPNStaticRoute `json:"-" xml:"-"` + metadataVpnStaticRoute `json:"-" xml:"-"` } -type metadataVPNStaticRoute struct { +type metadataVpnStaticRoute struct { SDKShapeTraits bool `type:"structure"` } -// Describes a volume. -type Volume struct { - // Information about the volume attachments. - Attachments []*VolumeAttachment `locationName:"attachmentSet" locationNameList:"item" type:"list"` +// String returns the string representation +func (s VpnStaticRoute) String() string { + return awsutil.Prettify(s) +} - // The Availability Zone for the volume. - AvailabilityZone *string `locationName:"availabilityZone" type:"string"` +// GoString returns the string representation +func (s VpnStaticRoute) GoString() string { + return s.String() +} - // The time stamp when volume creation was initiated. - CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601"` +const ( + // @enum AccountAttributeName + AccountAttributeNameSupportedPlatforms = "supported-platforms" + // @enum AccountAttributeName + AccountAttributeNameDefaultVpc = "default-vpc" +) - // Indicates whether the volume will be encrypted. - Encrypted *bool `locationName:"encrypted" type:"boolean"` +const ( + // @enum AllocationStrategy + AllocationStrategyLowestPrice = "lowestPrice" + // @enum AllocationStrategy + AllocationStrategyDiversified = "diversified" +) - // The number of I/O operations per second (IOPS) that the volume supports. - // For Provisioned IOPS (SSD) volumes, this represents the number of IOPS that - // are provisioned for the volume. For General Purpose (SSD) volumes, this represents - // the baseline performance of the volume and the rate at which the volume accumulates - // I/O credits for bursting. For more information on General Purpose (SSD) baseline - // performance, I/O credits, and bursting, see Amazon EBS Volume Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html) - // in the Amazon Elastic Compute Cloud User Guide. - // - // Constraint: Range is 100 to 20000 for Provisioned IOPS (SSD) volumes and - // 3 to 10000 for General Purpose (SSD) volumes. - // - // Condition: This parameter is required for requests to create io1 volumes; - // it is not used in requests to create standard or gp2 volumes. - IOPS *int64 `locationName:"iops" type:"integer"` +const ( + // @enum ArchitectureValues + ArchitectureValuesI386 = "i386" + // @enum ArchitectureValues + ArchitectureValuesX8664 = "x86_64" +) - // The full ARN of the AWS Key Management Service (KMS) master key that was - // used to protect the volume encryption key for the volume. - KMSKeyID *string `locationName:"kmsKeyId" type:"string"` +const ( + // @enum AttachmentStatus + AttachmentStatusAttaching = "attaching" + // @enum AttachmentStatus + AttachmentStatusAttached = "attached" + // @enum AttachmentStatus + AttachmentStatusDetaching = "detaching" + // @enum AttachmentStatus + AttachmentStatusDetached = "detached" +) - // The size of the volume, in GiBs. - Size *int64 `locationName:"size" type:"integer"` +const ( + // @enum AvailabilityZoneState + AvailabilityZoneStateAvailable = "available" +) - // The snapshot from which the volume was created, if applicable. - SnapshotID *string `locationName:"snapshotId" type:"string"` +const ( + // @enum BatchState + BatchStateSubmitted = "submitted" + // @enum BatchState + BatchStateActive = "active" + // @enum BatchState + BatchStateCancelled = "cancelled" + // @enum BatchState + BatchStateFailed = "failed" + // @enum BatchState + BatchStateCancelledRunning = "cancelled_running" + // @enum BatchState + BatchStateCancelledTerminating = "cancelled_terminating" +) - // The volume state. - State *string `locationName:"status" type:"string"` +const ( + // @enum BundleTaskState + BundleTaskStatePending = "pending" + // @enum BundleTaskState + BundleTaskStateWaitingForShutdown = "waiting-for-shutdown" + // @enum BundleTaskState + BundleTaskStateBundling = "bundling" + // @enum BundleTaskState + BundleTaskStateStoring = "storing" + // @enum BundleTaskState + BundleTaskStateCancelling = "cancelling" + // @enum BundleTaskState + BundleTaskStateComplete = "complete" + // @enum BundleTaskState + BundleTaskStateFailed = "failed" +) - // Any tags assigned to the volume. - Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` +const ( + // @enum CancelBatchErrorCode + CancelBatchErrorCodeFleetRequestIdDoesNotExist = "fleetRequestIdDoesNotExist" + // @enum CancelBatchErrorCode + CancelBatchErrorCodeFleetRequestIdMalformed = "fleetRequestIdMalformed" + // @enum CancelBatchErrorCode + CancelBatchErrorCodeFleetRequestNotInCancellableState = "fleetRequestNotInCancellableState" + // @enum CancelBatchErrorCode + CancelBatchErrorCodeUnexpectedError = "unexpectedError" +) - // The ID of the volume. - VolumeID *string `locationName:"volumeId" type:"string"` +const ( + // @enum CancelSpotInstanceRequestState + CancelSpotInstanceRequestStateActive = "active" + // @enum CancelSpotInstanceRequestState + CancelSpotInstanceRequestStateOpen = "open" + // @enum CancelSpotInstanceRequestState + CancelSpotInstanceRequestStateClosed = "closed" + // @enum CancelSpotInstanceRequestState + CancelSpotInstanceRequestStateCancelled = "cancelled" + // @enum CancelSpotInstanceRequestState + CancelSpotInstanceRequestStateCompleted = "completed" +) - // The volume type. This can be gp2 for General Purpose (SSD) volumes, io1 for - // Provisioned IOPS (SSD) volumes, or standard for Magnetic volumes. - VolumeType *string `locationName:"volumeType" type:"string"` +const ( + // @enum ContainerFormat + ContainerFormatOva = "ova" +) - metadataVolume `json:"-" xml:"-"` -} +const ( + // @enum ConversionTaskState + ConversionTaskStateActive = "active" + // @enum ConversionTaskState + ConversionTaskStateCancelling = "cancelling" + // @enum ConversionTaskState + ConversionTaskStateCancelled = "cancelled" + // @enum ConversionTaskState + ConversionTaskStateCompleted = "completed" +) -type metadataVolume struct { - SDKShapeTraits bool `type:"structure"` -} +const ( + // @enum CurrencyCodeValues + CurrencyCodeValuesUsd = "USD" +) -// Describes volume attachment details. -type VolumeAttachment struct { - // The time stamp when the attachment initiated. - AttachTime *time.Time `locationName:"attachTime" type:"timestamp" timestampFormat:"iso8601"` +const ( + // @enum DatafeedSubscriptionState + DatafeedSubscriptionStateActive = "Active" + // @enum DatafeedSubscriptionState + DatafeedSubscriptionStateInactive = "Inactive" +) - // Indicates whether the EBS volume is deleted on instance termination. - DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` +const ( + // @enum DeviceType + DeviceTypeEbs = "ebs" + // @enum DeviceType + DeviceTypeInstanceStore = "instance-store" +) - // The device name. - Device *string `locationName:"device" type:"string"` +const ( + // @enum DiskImageFormat + DiskImageFormatVmdk = "VMDK" + // @enum DiskImageFormat + DiskImageFormatRaw = "RAW" + // @enum DiskImageFormat + DiskImageFormatVhd = "VHD" +) - // The ID of the instance. - InstanceID *string `locationName:"instanceId" type:"string"` +const ( + // @enum DomainType + DomainTypeVpc = "vpc" + // @enum DomainType + DomainTypeStandard = "standard" +) - // The attachment state of the volume. - State *string `locationName:"status" type:"string"` +const ( + // @enum EventCode + EventCodeInstanceReboot = "instance-reboot" + // @enum EventCode + EventCodeSystemReboot = "system-reboot" + // @enum EventCode + EventCodeSystemMaintenance = "system-maintenance" + // @enum EventCode + EventCodeInstanceRetirement = "instance-retirement" + // @enum EventCode + EventCodeInstanceStop = "instance-stop" +) - // The ID of the volume. - VolumeID *string `locationName:"volumeId" type:"string"` +const ( + // @enum EventType + EventTypeInstanceChange = "instanceChange" + // @enum EventType + EventTypeFleetRequestChange = "fleetRequestChange" + // @enum EventType + EventTypeError = "error" +) - metadataVolumeAttachment `json:"-" xml:"-"` -} +const ( + // @enum ExportEnvironment + ExportEnvironmentCitrix = "citrix" + // @enum ExportEnvironment + ExportEnvironmentVmware = "vmware" + // @enum ExportEnvironment + ExportEnvironmentMicrosoft = "microsoft" +) -type metadataVolumeAttachment struct { - SDKShapeTraits bool `type:"structure"` -} +const ( + // @enum ExportTaskState + ExportTaskStateActive = "active" + // @enum ExportTaskState + ExportTaskStateCancelling = "cancelling" + // @enum ExportTaskState + ExportTaskStateCancelled = "cancelled" + // @enum ExportTaskState + ExportTaskStateCompleted = "completed" +) -// Describes an EBS volume. -type VolumeDetail struct { - // The size of the volume, in GiB. - Size *int64 `locationName:"size" type:"long" required:"true"` +const ( + // @enum FlowLogsResourceType + FlowLogsResourceTypeVpc = "VPC" + // @enum FlowLogsResourceType + FlowLogsResourceTypeSubnet = "Subnet" + // @enum FlowLogsResourceType + FlowLogsResourceTypeNetworkInterface = "NetworkInterface" +) - metadataVolumeDetail `json:"-" xml:"-"` -} +const ( + // @enum GatewayType + GatewayTypeIpsec1 = "ipsec.1" +) -type metadataVolumeDetail struct { - SDKShapeTraits bool `type:"structure"` -} +const ( + // @enum HypervisorType + HypervisorTypeOvm = "ovm" + // @enum HypervisorType + HypervisorTypeXen = "xen" +) -// Describes a volume status operation code. -type VolumeStatusAction struct { - // The code identifying the operation, for example, enable-volume-io. - Code *string `locationName:"code" type:"string"` +const ( + // @enum ImageAttributeName + ImageAttributeNameDescription = "description" + // @enum ImageAttributeName + ImageAttributeNameKernel = "kernel" + // @enum ImageAttributeName + ImageAttributeNameRamdisk = "ramdisk" + // @enum ImageAttributeName + ImageAttributeNameLaunchPermission = "launchPermission" + // @enum ImageAttributeName + ImageAttributeNameProductCodes = "productCodes" + // @enum ImageAttributeName + ImageAttributeNameBlockDeviceMapping = "blockDeviceMapping" + // @enum ImageAttributeName + ImageAttributeNameSriovNetSupport = "sriovNetSupport" +) - // A description of the operation. - Description *string `locationName:"description" type:"string"` +const ( + // @enum ImageState + ImageStatePending = "pending" + // @enum ImageState + ImageStateAvailable = "available" + // @enum ImageState + ImageStateInvalid = "invalid" + // @enum ImageState + ImageStateDeregistered = "deregistered" + // @enum ImageState + ImageStateTransient = "transient" + // @enum ImageState + ImageStateFailed = "failed" + // @enum ImageState + ImageStateError = "error" +) - // The ID of the event associated with this operation. - EventID *string `locationName:"eventId" type:"string"` +const ( + // @enum ImageTypeValues + ImageTypeValuesMachine = "machine" + // @enum ImageTypeValues + ImageTypeValuesKernel = "kernel" + // @enum ImageTypeValues + ImageTypeValuesRamdisk = "ramdisk" +) - // The event type associated with this operation. - EventType *string `locationName:"eventType" type:"string"` +const ( + // @enum InstanceAttributeName + InstanceAttributeNameInstanceType = "instanceType" + // @enum InstanceAttributeName + InstanceAttributeNameKernel = "kernel" + // @enum InstanceAttributeName + InstanceAttributeNameRamdisk = "ramdisk" + // @enum InstanceAttributeName + InstanceAttributeNameUserData = "userData" + // @enum InstanceAttributeName + InstanceAttributeNameDisableApiTermination = "disableApiTermination" + // @enum InstanceAttributeName + InstanceAttributeNameInstanceInitiatedShutdownBehavior = "instanceInitiatedShutdownBehavior" + // @enum InstanceAttributeName + InstanceAttributeNameRootDeviceName = "rootDeviceName" + // @enum InstanceAttributeName + InstanceAttributeNameBlockDeviceMapping = "blockDeviceMapping" + // @enum InstanceAttributeName + InstanceAttributeNameProductCodes = "productCodes" + // @enum InstanceAttributeName + InstanceAttributeNameSourceDestCheck = "sourceDestCheck" + // @enum InstanceAttributeName + InstanceAttributeNameGroupSet = "groupSet" + // @enum InstanceAttributeName + InstanceAttributeNameEbsOptimized = "ebsOptimized" + // @enum InstanceAttributeName + InstanceAttributeNameSriovNetSupport = "sriovNetSupport" +) - metadataVolumeStatusAction `json:"-" xml:"-"` -} +const ( + // @enum InstanceLifecycleType + InstanceLifecycleTypeSpot = "spot" +) -type metadataVolumeStatusAction struct { - SDKShapeTraits bool `type:"structure"` -} +const ( + // @enum InstanceStateName + InstanceStateNamePending = "pending" + // @enum InstanceStateName + InstanceStateNameRunning = "running" + // @enum InstanceStateName + InstanceStateNameShuttingDown = "shutting-down" + // @enum InstanceStateName + InstanceStateNameTerminated = "terminated" + // @enum InstanceStateName + InstanceStateNameStopping = "stopping" + // @enum InstanceStateName + InstanceStateNameStopped = "stopped" +) -// Describes a volume status. -type VolumeStatusDetails struct { - // The name of the volume status. - Name *string `locationName:"name" type:"string"` +const ( + // @enum InstanceType + InstanceTypeT1Micro = "t1.micro" + // @enum InstanceType + InstanceTypeM1Small = "m1.small" + // @enum InstanceType + InstanceTypeM1Medium = "m1.medium" + // @enum InstanceType + InstanceTypeM1Large = "m1.large" + // @enum InstanceType + InstanceTypeM1Xlarge = "m1.xlarge" + // @enum InstanceType + InstanceTypeM3Medium = "m3.medium" + // @enum InstanceType + InstanceTypeM3Large = "m3.large" + // @enum InstanceType + InstanceTypeM3Xlarge = "m3.xlarge" + // @enum InstanceType + InstanceTypeM32xlarge = "m3.2xlarge" + // @enum InstanceType + InstanceTypeM4Large = "m4.large" + // @enum InstanceType + InstanceTypeM4Xlarge = "m4.xlarge" + // @enum InstanceType + InstanceTypeM42xlarge = "m4.2xlarge" + // @enum InstanceType + InstanceTypeM44xlarge = "m4.4xlarge" + // @enum InstanceType + InstanceTypeM410xlarge = "m4.10xlarge" + // @enum InstanceType + InstanceTypeT2Micro = "t2.micro" + // @enum InstanceType + InstanceTypeT2Small = "t2.small" + // @enum InstanceType + InstanceTypeT2Medium = "t2.medium" + // @enum InstanceType + InstanceTypeT2Large = "t2.large" + // @enum InstanceType + InstanceTypeM2Xlarge = "m2.xlarge" + // @enum InstanceType + InstanceTypeM22xlarge = "m2.2xlarge" + // @enum InstanceType + InstanceTypeM24xlarge = "m2.4xlarge" + // @enum InstanceType + InstanceTypeCr18xlarge = "cr1.8xlarge" + // @enum InstanceType + InstanceTypeI2Xlarge = "i2.xlarge" + // @enum InstanceType + InstanceTypeI22xlarge = "i2.2xlarge" + // @enum InstanceType + InstanceTypeI24xlarge = "i2.4xlarge" + // @enum InstanceType + InstanceTypeI28xlarge = "i2.8xlarge" + // @enum InstanceType + InstanceTypeHi14xlarge = "hi1.4xlarge" + // @enum InstanceType + InstanceTypeHs18xlarge = "hs1.8xlarge" + // @enum InstanceType + InstanceTypeC1Medium = "c1.medium" + // @enum InstanceType + InstanceTypeC1Xlarge = "c1.xlarge" + // @enum InstanceType + InstanceTypeC3Large = "c3.large" + // @enum InstanceType + InstanceTypeC3Xlarge = "c3.xlarge" + // @enum InstanceType + InstanceTypeC32xlarge = "c3.2xlarge" + // @enum InstanceType + InstanceTypeC34xlarge = "c3.4xlarge" + // @enum InstanceType + InstanceTypeC38xlarge = "c3.8xlarge" + // @enum InstanceType + InstanceTypeC4Large = "c4.large" + // @enum InstanceType + InstanceTypeC4Xlarge = "c4.xlarge" + // @enum InstanceType + InstanceTypeC42xlarge = "c4.2xlarge" + // @enum InstanceType + InstanceTypeC44xlarge = "c4.4xlarge" + // @enum InstanceType + InstanceTypeC48xlarge = "c4.8xlarge" + // @enum InstanceType + InstanceTypeCc14xlarge = "cc1.4xlarge" + // @enum InstanceType + InstanceTypeCc28xlarge = "cc2.8xlarge" + // @enum InstanceType + InstanceTypeG22xlarge = "g2.2xlarge" + // @enum InstanceType + InstanceTypeCg14xlarge = "cg1.4xlarge" + // @enum InstanceType + InstanceTypeR3Large = "r3.large" + // @enum InstanceType + InstanceTypeR3Xlarge = "r3.xlarge" + // @enum InstanceType + InstanceTypeR32xlarge = "r3.2xlarge" + // @enum InstanceType + InstanceTypeR34xlarge = "r3.4xlarge" + // @enum InstanceType + InstanceTypeR38xlarge = "r3.8xlarge" + // @enum InstanceType + InstanceTypeD2Xlarge = "d2.xlarge" + // @enum InstanceType + InstanceTypeD22xlarge = "d2.2xlarge" + // @enum InstanceType + InstanceTypeD24xlarge = "d2.4xlarge" + // @enum InstanceType + InstanceTypeD28xlarge = "d2.8xlarge" +) - // The intended status of the volume status. - Status *string `locationName:"status" type:"string"` +const ( + // @enum ListingState + ListingStateAvailable = "available" + // @enum ListingState + ListingStateSold = "sold" + // @enum ListingState + ListingStateCancelled = "cancelled" + // @enum ListingState + ListingStatePending = "pending" +) - metadataVolumeStatusDetails `json:"-" xml:"-"` -} +const ( + // @enum ListingStatus + ListingStatusActive = "active" + // @enum ListingStatus + ListingStatusPending = "pending" + // @enum ListingStatus + ListingStatusCancelled = "cancelled" + // @enum ListingStatus + ListingStatusClosed = "closed" +) -type metadataVolumeStatusDetails struct { - SDKShapeTraits bool `type:"structure"` -} +const ( + // @enum MonitoringState + MonitoringStateDisabled = "disabled" + // @enum MonitoringState + MonitoringStateDisabling = "disabling" + // @enum MonitoringState + MonitoringStateEnabled = "enabled" + // @enum MonitoringState + MonitoringStatePending = "pending" +) -// Describes a volume status event. -type VolumeStatusEvent struct { - // A description of the event. - Description *string `locationName:"description" type:"string"` +const ( + // @enum MoveStatus + MoveStatusMovingToVpc = "movingToVpc" + // @enum MoveStatus + MoveStatusRestoringToClassic = "restoringToClassic" +) - // The ID of this event. - EventID *string `locationName:"eventId" type:"string"` +const ( + // @enum NetworkInterfaceAttribute + NetworkInterfaceAttributeDescription = "description" + // @enum NetworkInterfaceAttribute + NetworkInterfaceAttributeGroupSet = "groupSet" + // @enum NetworkInterfaceAttribute + NetworkInterfaceAttributeSourceDestCheck = "sourceDestCheck" + // @enum NetworkInterfaceAttribute + NetworkInterfaceAttributeAttachment = "attachment" +) - // The type of this event. - EventType *string `locationName:"eventType" type:"string"` +const ( + // @enum NetworkInterfaceStatus + NetworkInterfaceStatusAvailable = "available" + // @enum NetworkInterfaceStatus + NetworkInterfaceStatusAttaching = "attaching" + // @enum NetworkInterfaceStatus + NetworkInterfaceStatusInUse = "in-use" + // @enum NetworkInterfaceStatus + NetworkInterfaceStatusDetaching = "detaching" +) - // The latest end time of the event. - NotAfter *time.Time `locationName:"notAfter" type:"timestamp" timestampFormat:"iso8601"` +const ( + // @enum OfferingTypeValues + OfferingTypeValuesHeavyUtilization = "Heavy Utilization" + // @enum OfferingTypeValues + OfferingTypeValuesMediumUtilization = "Medium Utilization" + // @enum OfferingTypeValues + OfferingTypeValuesLightUtilization = "Light Utilization" + // @enum OfferingTypeValues + OfferingTypeValuesNoUpfront = "No Upfront" + // @enum OfferingTypeValues + OfferingTypeValuesPartialUpfront = "Partial Upfront" + // @enum OfferingTypeValues + OfferingTypeValuesAllUpfront = "All Upfront" +) - // The earliest start time of the event. - NotBefore *time.Time `locationName:"notBefore" type:"timestamp" timestampFormat:"iso8601"` +const ( + // @enum OperationType + OperationTypeAdd = "add" + // @enum OperationType + OperationTypeRemove = "remove" +) - metadataVolumeStatusEvent `json:"-" xml:"-"` -} +const ( + // @enum PermissionGroup + PermissionGroupAll = "all" +) -type metadataVolumeStatusEvent struct { - SDKShapeTraits bool `type:"structure"` -} +const ( + // @enum PlacementGroupState + PlacementGroupStatePending = "pending" + // @enum PlacementGroupState + PlacementGroupStateAvailable = "available" + // @enum PlacementGroupState + PlacementGroupStateDeleting = "deleting" + // @enum PlacementGroupState + PlacementGroupStateDeleted = "deleted" +) -// Describes the status of a volume. -type VolumeStatusInfo struct { - // The details of the volume status. - Details []*VolumeStatusDetails `locationName:"details" locationNameList:"item" type:"list"` +const ( + // @enum PlacementStrategy + PlacementStrategyCluster = "cluster" +) - // The status of the volume. - Status *string `locationName:"status" type:"string"` +const ( + // @enum PlatformValues + PlatformValuesWindows = "Windows" +) - metadataVolumeStatusInfo `json:"-" xml:"-"` -} +const ( + // @enum ProductCodeValues + ProductCodeValuesDevpay = "devpay" + // @enum ProductCodeValues + ProductCodeValuesMarketplace = "marketplace" +) -type metadataVolumeStatusInfo struct { - SDKShapeTraits bool `type:"structure"` -} +const ( + // @enum RIProductDescription + RIProductDescriptionLinuxUnix = "Linux/UNIX" + // @enum RIProductDescription + RIProductDescriptionLinuxUnixamazonVpc = "Linux/UNIX (Amazon VPC)" + // @enum RIProductDescription + RIProductDescriptionWindows = "Windows" + // @enum RIProductDescription + RIProductDescriptionWindowsAmazonVpc = "Windows (Amazon VPC)" +) -// Describes the volume status. -type VolumeStatusItem struct { - // The details of the operation. - Actions []*VolumeStatusAction `locationName:"actionsSet" locationNameList:"item" type:"list"` +const ( + // @enum RecurringChargeFrequency + RecurringChargeFrequencyHourly = "Hourly" +) - // The Availability Zone of the volume. - AvailabilityZone *string `locationName:"availabilityZone" type:"string"` +const ( + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesInstanceStuckInState = "instance-stuck-in-state" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesUnresponsive = "unresponsive" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesNotAcceptingCredentials = "not-accepting-credentials" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesPasswordNotAvailable = "password-not-available" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesPerformanceNetwork = "performance-network" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesPerformanceInstanceStore = "performance-instance-store" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesPerformanceEbsVolume = "performance-ebs-volume" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesPerformanceOther = "performance-other" + // @enum ReportInstanceReasonCodes + ReportInstanceReasonCodesOther = "other" +) - // A list of events associated with the volume. - Events []*VolumeStatusEvent `locationName:"eventsSet" locationNameList:"item" type:"list"` +const ( + // @enum ReportStatusType + ReportStatusTypeOk = "ok" + // @enum ReportStatusType + ReportStatusTypeImpaired = "impaired" +) - // The volume ID. - VolumeID *string `locationName:"volumeId" type:"string"` +const ( + // @enum ReservedInstanceState + ReservedInstanceStatePaymentPending = "payment-pending" + // @enum ReservedInstanceState + ReservedInstanceStateActive = "active" + // @enum ReservedInstanceState + ReservedInstanceStatePaymentFailed = "payment-failed" + // @enum ReservedInstanceState + ReservedInstanceStateRetired = "retired" +) - // The volume status. - VolumeStatus *VolumeStatusInfo `locationName:"volumeStatus" type:"structure"` +const ( + // @enum ResetImageAttributeName + ResetImageAttributeNameLaunchPermission = "launchPermission" +) - metadataVolumeStatusItem `json:"-" xml:"-"` -} +const ( + // @enum ResourceType + ResourceTypeCustomerGateway = "customer-gateway" + // @enum ResourceType + ResourceTypeDhcpOptions = "dhcp-options" + // @enum ResourceType + ResourceTypeImage = "image" + // @enum ResourceType + ResourceTypeInstance = "instance" + // @enum ResourceType + ResourceTypeInternetGateway = "internet-gateway" + // @enum ResourceType + ResourceTypeNetworkAcl = "network-acl" + // @enum ResourceType + ResourceTypeNetworkInterface = "network-interface" + // @enum ResourceType + ResourceTypeReservedInstances = "reserved-instances" + // @enum ResourceType + ResourceTypeRouteTable = "route-table" + // @enum ResourceType + ResourceTypeSnapshot = "snapshot" + // @enum ResourceType + ResourceTypeSpotInstancesRequest = "spot-instances-request" + // @enum ResourceType + ResourceTypeSubnet = "subnet" + // @enum ResourceType + ResourceTypeSecurityGroup = "security-group" + // @enum ResourceType + ResourceTypeVolume = "volume" + // @enum ResourceType + ResourceTypeVpc = "vpc" + // @enum ResourceType + ResourceTypeVpnConnection = "vpn-connection" + // @enum ResourceType + ResourceTypeVpnGateway = "vpn-gateway" +) -type metadataVolumeStatusItem struct { - SDKShapeTraits bool `type:"structure"` -} +const ( + // @enum RouteOrigin + RouteOriginCreateRouteTable = "CreateRouteTable" + // @enum RouteOrigin + RouteOriginCreateRoute = "CreateRoute" + // @enum RouteOrigin + RouteOriginEnableVgwRoutePropagation = "EnableVgwRoutePropagation" +) + +const ( + // @enum RouteState + RouteStateActive = "active" + // @enum RouteState + RouteStateBlackhole = "blackhole" +) + +const ( + // @enum RuleAction + RuleActionAllow = "allow" + // @enum RuleAction + RuleActionDeny = "deny" +) + +const ( + // @enum ShutdownBehavior + ShutdownBehaviorStop = "stop" + // @enum ShutdownBehavior + ShutdownBehaviorTerminate = "terminate" +) + +const ( + // @enum SnapshotAttributeName + SnapshotAttributeNameProductCodes = "productCodes" + // @enum SnapshotAttributeName + SnapshotAttributeNameCreateVolumePermission = "createVolumePermission" +) + +const ( + // @enum SnapshotState + SnapshotStatePending = "pending" + // @enum SnapshotState + SnapshotStateCompleted = "completed" + // @enum SnapshotState + SnapshotStateError = "error" +) + +const ( + // @enum SpotInstanceState + SpotInstanceStateOpen = "open" + // @enum SpotInstanceState + SpotInstanceStateActive = "active" + // @enum SpotInstanceState + SpotInstanceStateClosed = "closed" + // @enum SpotInstanceState + SpotInstanceStateCancelled = "cancelled" + // @enum SpotInstanceState + SpotInstanceStateFailed = "failed" +) + +const ( + // @enum SpotInstanceType + SpotInstanceTypeOneTime = "one-time" + // @enum SpotInstanceType + SpotInstanceTypePersistent = "persistent" +) + +const ( + // @enum State + StatePending = "Pending" + // @enum State + StateAvailable = "Available" + // @enum State + StateDeleting = "Deleting" + // @enum State + StateDeleted = "Deleted" +) + +const ( + // @enum Status + StatusMoveInProgress = "MoveInProgress" + // @enum Status + StatusInVpc = "InVpc" + // @enum Status + StatusInClassic = "InClassic" +) + +const ( + // @enum StatusName + StatusNameReachability = "reachability" +) + +const ( + // @enum StatusType + StatusTypePassed = "passed" + // @enum StatusType + StatusTypeFailed = "failed" + // @enum StatusType + StatusTypeInsufficientData = "insufficient-data" + // @enum StatusType + StatusTypeInitializing = "initializing" +) + +const ( + // @enum SubnetState + SubnetStatePending = "pending" + // @enum SubnetState + SubnetStateAvailable = "available" +) + +const ( + // @enum SummaryStatus + SummaryStatusOk = "ok" + // @enum SummaryStatus + SummaryStatusImpaired = "impaired" + // @enum SummaryStatus + SummaryStatusInsufficientData = "insufficient-data" + // @enum SummaryStatus + SummaryStatusNotApplicable = "not-applicable" + // @enum SummaryStatus + SummaryStatusInitializing = "initializing" +) + +const ( + // @enum TelemetryStatus + TelemetryStatusUp = "UP" + // @enum TelemetryStatus + TelemetryStatusDown = "DOWN" +) + +const ( + // @enum Tenancy + TenancyDefault = "default" + // @enum Tenancy + TenancyDedicated = "dedicated" +) + +const ( + // @enum TrafficType + TrafficTypeAccept = "ACCEPT" + // @enum TrafficType + TrafficTypeReject = "REJECT" + // @enum TrafficType + TrafficTypeAll = "ALL" +) + +const ( + // @enum VirtualizationType + VirtualizationTypeHvm = "hvm" + // @enum VirtualizationType + VirtualizationTypeParavirtual = "paravirtual" +) + +const ( + // @enum VolumeAttachmentState + VolumeAttachmentStateAttaching = "attaching" + // @enum VolumeAttachmentState + VolumeAttachmentStateAttached = "attached" + // @enum VolumeAttachmentState + VolumeAttachmentStateDetaching = "detaching" + // @enum VolumeAttachmentState + VolumeAttachmentStateDetached = "detached" +) + +const ( + // @enum VolumeAttributeName + VolumeAttributeNameAutoEnableIo = "autoEnableIO" + // @enum VolumeAttributeName + VolumeAttributeNameProductCodes = "productCodes" +) + +const ( + // @enum VolumeState + VolumeStateCreating = "creating" + // @enum VolumeState + VolumeStateAvailable = "available" + // @enum VolumeState + VolumeStateInUse = "in-use" + // @enum VolumeState + VolumeStateDeleting = "deleting" + // @enum VolumeState + VolumeStateDeleted = "deleted" + // @enum VolumeState + VolumeStateError = "error" +) + +const ( + // @enum VolumeStatusInfoStatus + VolumeStatusInfoStatusOk = "ok" + // @enum VolumeStatusInfoStatus + VolumeStatusInfoStatusImpaired = "impaired" + // @enum VolumeStatusInfoStatus + VolumeStatusInfoStatusInsufficientData = "insufficient-data" +) + +const ( + // @enum VolumeStatusName + VolumeStatusNameIoEnabled = "io-enabled" + // @enum VolumeStatusName + VolumeStatusNameIoPerformance = "io-performance" +) + +const ( + // @enum VolumeType + VolumeTypeStandard = "standard" + // @enum VolumeType + VolumeTypeIo1 = "io1" + // @enum VolumeType + VolumeTypeGp2 = "gp2" +) + +const ( + // @enum VpcAttributeName + VpcAttributeNameEnableDnsSupport = "enableDnsSupport" + // @enum VpcAttributeName + VpcAttributeNameEnableDnsHostnames = "enableDnsHostnames" +) + +const ( + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeInitiatingRequest = "initiating-request" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodePendingAcceptance = "pending-acceptance" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeActive = "active" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeDeleted = "deleted" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeRejected = "rejected" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeFailed = "failed" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeExpired = "expired" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeProvisioning = "provisioning" + // @enum VpcPeeringConnectionStateReasonCode + VpcPeeringConnectionStateReasonCodeDeleting = "deleting" +) + +const ( + // @enum VpcState + VpcStatePending = "pending" + // @enum VpcState + VpcStateAvailable = "available" +) + +const ( + // @enum VpnState + VpnStatePending = "pending" + // @enum VpnState + VpnStateAvailable = "available" + // @enum VpnState + VpnStateDeleting = "deleting" + // @enum VpnState + VpnStateDeleted = "deleted" +) + +const ( + // @enum VpnStaticRouteSource + VpnStaticRouteSourceStatic = "Static" +) diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations.go index f080166e03a6..99f0820477ee 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations.go @@ -3,19 +3,19 @@ package ec2 import ( "time" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" ) func init() { - initRequest = func(r *aws.Request) { - if r.Operation == opCopySnapshot { // fill the PresignedURL parameter + initRequest = func(r *request.Request) { + if r.Operation.Name == opCopySnapshot { // fill the PresignedURL parameter r.Handlers.Build.PushFront(fillPresignedURL) } } } -func fillPresignedURL(r *aws.Request) { +func fillPresignedURL(r *request.Request) { if !r.ParamsFilled() { return } @@ -23,7 +23,7 @@ func fillPresignedURL(r *aws.Request) { params := r.Params.(*CopySnapshotInput) // Stop if PresignedURL/DestinationRegion is set - if params.PresignedURL != nil || params.DestinationRegion != nil { + if params.PresignedUrl != nil || params.DestinationRegion != nil { return } @@ -33,16 +33,16 @@ func fillPresignedURL(r *aws.Request) { // Set destination region. Avoids infinite handler loop. // Also needed to sign sub-request. - params.DestinationRegion = &r.Service.Config.Region + params.DestinationRegion = r.Service.Config.Region // Create a new client pointing at source region. // We will use this to presign the CopySnapshot request against // the source region - config := r.Service.Config.Copy() + config := r.Service.Config.Copy(). + WithEndpoint(""). + WithRegion(*params.SourceRegion) - config.Endpoint = "" - config.Region = *params.SourceRegion - client := New(&config) + client := New(config) // Presign a CopySnapshot request with modified params req, _ := client.CopySnapshotRequest(params) @@ -53,5 +53,5 @@ func fillPresignedURL(r *aws.Request) { } // We have our URL, set it on params - params.PresignedURL = &url + params.PresignedUrl = &url } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations_test.go index 24956345a238..38617b1ffeee 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations_test.go @@ -14,7 +14,7 @@ import ( var _ = unit.Imported func TestCopySnapshotPresignedURL(t *testing.T) { - svc := ec2.New(&aws.Config{Region: "us-west-2"}) + svc := ec2.New(&aws.Config{Region: aws.String("us-west-2")}) assert.NotPanics(t, func() { // Doesn't panic on nil input @@ -24,7 +24,7 @@ func TestCopySnapshotPresignedURL(t *testing.T) { req, _ := svc.CopySnapshotRequest(&ec2.CopySnapshotInput{ SourceRegion: aws.String("us-west-1"), - SourceSnapshotID: aws.String("snap-id"), + SourceSnapshotId: aws.String("snap-id"), }) req.Sign() diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface.go index aa2b112c5a70..e10a2aa1f8b5 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface.go @@ -4,366 +4,753 @@ package ec2iface import ( + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/service/ec2" ) // EC2API is the interface type for ec2.EC2. type EC2API interface { - AcceptVPCPeeringConnection(*ec2.AcceptVPCPeeringConnectionInput) (*ec2.AcceptVPCPeeringConnectionOutput, error) + AcceptVpcPeeringConnectionRequest(*ec2.AcceptVpcPeeringConnectionInput) (*request.Request, *ec2.AcceptVpcPeeringConnectionOutput) + + AcceptVpcPeeringConnection(*ec2.AcceptVpcPeeringConnectionInput) (*ec2.AcceptVpcPeeringConnectionOutput, error) + + AllocateAddressRequest(*ec2.AllocateAddressInput) (*request.Request, *ec2.AllocateAddressOutput) AllocateAddress(*ec2.AllocateAddressInput) (*ec2.AllocateAddressOutput, error) - AssignPrivateIPAddresses(*ec2.AssignPrivateIPAddressesInput) (*ec2.AssignPrivateIPAddressesOutput, error) + AssignPrivateIpAddressesRequest(*ec2.AssignPrivateIpAddressesInput) (*request.Request, *ec2.AssignPrivateIpAddressesOutput) + + AssignPrivateIpAddresses(*ec2.AssignPrivateIpAddressesInput) (*ec2.AssignPrivateIpAddressesOutput, error) + + AssociateAddressRequest(*ec2.AssociateAddressInput) (*request.Request, *ec2.AssociateAddressOutput) AssociateAddress(*ec2.AssociateAddressInput) (*ec2.AssociateAddressOutput, error) - AssociateDHCPOptions(*ec2.AssociateDHCPOptionsInput) (*ec2.AssociateDHCPOptionsOutput, error) + AssociateDhcpOptionsRequest(*ec2.AssociateDhcpOptionsInput) (*request.Request, *ec2.AssociateDhcpOptionsOutput) + + AssociateDhcpOptions(*ec2.AssociateDhcpOptionsInput) (*ec2.AssociateDhcpOptionsOutput, error) + + AssociateRouteTableRequest(*ec2.AssociateRouteTableInput) (*request.Request, *ec2.AssociateRouteTableOutput) AssociateRouteTable(*ec2.AssociateRouteTableInput) (*ec2.AssociateRouteTableOutput, error) - AttachClassicLinkVPC(*ec2.AttachClassicLinkVPCInput) (*ec2.AttachClassicLinkVPCOutput, error) + AttachClassicLinkVpcRequest(*ec2.AttachClassicLinkVpcInput) (*request.Request, *ec2.AttachClassicLinkVpcOutput) + + AttachClassicLinkVpc(*ec2.AttachClassicLinkVpcInput) (*ec2.AttachClassicLinkVpcOutput, error) + + AttachInternetGatewayRequest(*ec2.AttachInternetGatewayInput) (*request.Request, *ec2.AttachInternetGatewayOutput) AttachInternetGateway(*ec2.AttachInternetGatewayInput) (*ec2.AttachInternetGatewayOutput, error) + AttachNetworkInterfaceRequest(*ec2.AttachNetworkInterfaceInput) (*request.Request, *ec2.AttachNetworkInterfaceOutput) + AttachNetworkInterface(*ec2.AttachNetworkInterfaceInput) (*ec2.AttachNetworkInterfaceOutput, error) - AttachVPNGateway(*ec2.AttachVPNGatewayInput) (*ec2.AttachVPNGatewayOutput, error) + AttachVolumeRequest(*ec2.AttachVolumeInput) (*request.Request, *ec2.VolumeAttachment) AttachVolume(*ec2.AttachVolumeInput) (*ec2.VolumeAttachment, error) + AttachVpnGatewayRequest(*ec2.AttachVpnGatewayInput) (*request.Request, *ec2.AttachVpnGatewayOutput) + + AttachVpnGateway(*ec2.AttachVpnGatewayInput) (*ec2.AttachVpnGatewayOutput, error) + + AuthorizeSecurityGroupEgressRequest(*ec2.AuthorizeSecurityGroupEgressInput) (*request.Request, *ec2.AuthorizeSecurityGroupEgressOutput) + AuthorizeSecurityGroupEgress(*ec2.AuthorizeSecurityGroupEgressInput) (*ec2.AuthorizeSecurityGroupEgressOutput, error) + AuthorizeSecurityGroupIngressRequest(*ec2.AuthorizeSecurityGroupIngressInput) (*request.Request, *ec2.AuthorizeSecurityGroupIngressOutput) + AuthorizeSecurityGroupIngress(*ec2.AuthorizeSecurityGroupIngressInput) (*ec2.AuthorizeSecurityGroupIngressOutput, error) + BundleInstanceRequest(*ec2.BundleInstanceInput) (*request.Request, *ec2.BundleInstanceOutput) + BundleInstance(*ec2.BundleInstanceInput) (*ec2.BundleInstanceOutput, error) + CancelBundleTaskRequest(*ec2.CancelBundleTaskInput) (*request.Request, *ec2.CancelBundleTaskOutput) + CancelBundleTask(*ec2.CancelBundleTaskInput) (*ec2.CancelBundleTaskOutput, error) + CancelConversionTaskRequest(*ec2.CancelConversionTaskInput) (*request.Request, *ec2.CancelConversionTaskOutput) + CancelConversionTask(*ec2.CancelConversionTaskInput) (*ec2.CancelConversionTaskOutput, error) + CancelExportTaskRequest(*ec2.CancelExportTaskInput) (*request.Request, *ec2.CancelExportTaskOutput) + CancelExportTask(*ec2.CancelExportTaskInput) (*ec2.CancelExportTaskOutput, error) + CancelImportTaskRequest(*ec2.CancelImportTaskInput) (*request.Request, *ec2.CancelImportTaskOutput) + CancelImportTask(*ec2.CancelImportTaskInput) (*ec2.CancelImportTaskOutput, error) + CancelReservedInstancesListingRequest(*ec2.CancelReservedInstancesListingInput) (*request.Request, *ec2.CancelReservedInstancesListingOutput) + CancelReservedInstancesListing(*ec2.CancelReservedInstancesListingInput) (*ec2.CancelReservedInstancesListingOutput, error) + CancelSpotFleetRequestsRequest(*ec2.CancelSpotFleetRequestsInput) (*request.Request, *ec2.CancelSpotFleetRequestsOutput) + CancelSpotFleetRequests(*ec2.CancelSpotFleetRequestsInput) (*ec2.CancelSpotFleetRequestsOutput, error) + CancelSpotInstanceRequestsRequest(*ec2.CancelSpotInstanceRequestsInput) (*request.Request, *ec2.CancelSpotInstanceRequestsOutput) + CancelSpotInstanceRequests(*ec2.CancelSpotInstanceRequestsInput) (*ec2.CancelSpotInstanceRequestsOutput, error) + ConfirmProductInstanceRequest(*ec2.ConfirmProductInstanceInput) (*request.Request, *ec2.ConfirmProductInstanceOutput) + ConfirmProductInstance(*ec2.ConfirmProductInstanceInput) (*ec2.ConfirmProductInstanceOutput, error) + CopyImageRequest(*ec2.CopyImageInput) (*request.Request, *ec2.CopyImageOutput) + CopyImage(*ec2.CopyImageInput) (*ec2.CopyImageOutput, error) + CopySnapshotRequest(*ec2.CopySnapshotInput) (*request.Request, *ec2.CopySnapshotOutput) + CopySnapshot(*ec2.CopySnapshotInput) (*ec2.CopySnapshotOutput, error) + CreateCustomerGatewayRequest(*ec2.CreateCustomerGatewayInput) (*request.Request, *ec2.CreateCustomerGatewayOutput) + CreateCustomerGateway(*ec2.CreateCustomerGatewayInput) (*ec2.CreateCustomerGatewayOutput, error) - CreateDHCPOptions(*ec2.CreateDHCPOptionsInput) (*ec2.CreateDHCPOptionsOutput, error) + CreateDhcpOptionsRequest(*ec2.CreateDhcpOptionsInput) (*request.Request, *ec2.CreateDhcpOptionsOutput) + + CreateDhcpOptions(*ec2.CreateDhcpOptionsInput) (*ec2.CreateDhcpOptionsOutput, error) + + CreateFlowLogsRequest(*ec2.CreateFlowLogsInput) (*request.Request, *ec2.CreateFlowLogsOutput) + + CreateFlowLogs(*ec2.CreateFlowLogsInput) (*ec2.CreateFlowLogsOutput, error) + + CreateImageRequest(*ec2.CreateImageInput) (*request.Request, *ec2.CreateImageOutput) CreateImage(*ec2.CreateImageInput) (*ec2.CreateImageOutput, error) + CreateInstanceExportTaskRequest(*ec2.CreateInstanceExportTaskInput) (*request.Request, *ec2.CreateInstanceExportTaskOutput) + CreateInstanceExportTask(*ec2.CreateInstanceExportTaskInput) (*ec2.CreateInstanceExportTaskOutput, error) + CreateInternetGatewayRequest(*ec2.CreateInternetGatewayInput) (*request.Request, *ec2.CreateInternetGatewayOutput) + CreateInternetGateway(*ec2.CreateInternetGatewayInput) (*ec2.CreateInternetGatewayOutput, error) + CreateKeyPairRequest(*ec2.CreateKeyPairInput) (*request.Request, *ec2.CreateKeyPairOutput) + CreateKeyPair(*ec2.CreateKeyPairInput) (*ec2.CreateKeyPairOutput, error) - CreateNetworkACL(*ec2.CreateNetworkACLInput) (*ec2.CreateNetworkACLOutput, error) + CreateNetworkAclRequest(*ec2.CreateNetworkAclInput) (*request.Request, *ec2.CreateNetworkAclOutput) + + CreateNetworkAcl(*ec2.CreateNetworkAclInput) (*ec2.CreateNetworkAclOutput, error) - CreateNetworkACLEntry(*ec2.CreateNetworkACLEntryInput) (*ec2.CreateNetworkACLEntryOutput, error) + CreateNetworkAclEntryRequest(*ec2.CreateNetworkAclEntryInput) (*request.Request, *ec2.CreateNetworkAclEntryOutput) + + CreateNetworkAclEntry(*ec2.CreateNetworkAclEntryInput) (*ec2.CreateNetworkAclEntryOutput, error) + + CreateNetworkInterfaceRequest(*ec2.CreateNetworkInterfaceInput) (*request.Request, *ec2.CreateNetworkInterfaceOutput) CreateNetworkInterface(*ec2.CreateNetworkInterfaceInput) (*ec2.CreateNetworkInterfaceOutput, error) + CreatePlacementGroupRequest(*ec2.CreatePlacementGroupInput) (*request.Request, *ec2.CreatePlacementGroupOutput) + CreatePlacementGroup(*ec2.CreatePlacementGroupInput) (*ec2.CreatePlacementGroupOutput, error) + CreateReservedInstancesListingRequest(*ec2.CreateReservedInstancesListingInput) (*request.Request, *ec2.CreateReservedInstancesListingOutput) + CreateReservedInstancesListing(*ec2.CreateReservedInstancesListingInput) (*ec2.CreateReservedInstancesListingOutput, error) + CreateRouteRequest(*ec2.CreateRouteInput) (*request.Request, *ec2.CreateRouteOutput) + CreateRoute(*ec2.CreateRouteInput) (*ec2.CreateRouteOutput, error) + CreateRouteTableRequest(*ec2.CreateRouteTableInput) (*request.Request, *ec2.CreateRouteTableOutput) + CreateRouteTable(*ec2.CreateRouteTableInput) (*ec2.CreateRouteTableOutput, error) + CreateSecurityGroupRequest(*ec2.CreateSecurityGroupInput) (*request.Request, *ec2.CreateSecurityGroupOutput) + CreateSecurityGroup(*ec2.CreateSecurityGroupInput) (*ec2.CreateSecurityGroupOutput, error) + CreateSnapshotRequest(*ec2.CreateSnapshotInput) (*request.Request, *ec2.Snapshot) + CreateSnapshot(*ec2.CreateSnapshotInput) (*ec2.Snapshot, error) + CreateSpotDatafeedSubscriptionRequest(*ec2.CreateSpotDatafeedSubscriptionInput) (*request.Request, *ec2.CreateSpotDatafeedSubscriptionOutput) + CreateSpotDatafeedSubscription(*ec2.CreateSpotDatafeedSubscriptionInput) (*ec2.CreateSpotDatafeedSubscriptionOutput, error) + CreateSubnetRequest(*ec2.CreateSubnetInput) (*request.Request, *ec2.CreateSubnetOutput) + CreateSubnet(*ec2.CreateSubnetInput) (*ec2.CreateSubnetOutput, error) + CreateTagsRequest(*ec2.CreateTagsInput) (*request.Request, *ec2.CreateTagsOutput) + CreateTags(*ec2.CreateTagsInput) (*ec2.CreateTagsOutput, error) - CreateVPC(*ec2.CreateVPCInput) (*ec2.CreateVPCOutput, error) + CreateVolumeRequest(*ec2.CreateVolumeInput) (*request.Request, *ec2.Volume) - CreateVPCEndpoint(*ec2.CreateVPCEndpointInput) (*ec2.CreateVPCEndpointOutput, error) + CreateVolume(*ec2.CreateVolumeInput) (*ec2.Volume, error) - CreateVPCPeeringConnection(*ec2.CreateVPCPeeringConnectionInput) (*ec2.CreateVPCPeeringConnectionOutput, error) + CreateVpcRequest(*ec2.CreateVpcInput) (*request.Request, *ec2.CreateVpcOutput) - CreateVPNConnection(*ec2.CreateVPNConnectionInput) (*ec2.CreateVPNConnectionOutput, error) + CreateVpc(*ec2.CreateVpcInput) (*ec2.CreateVpcOutput, error) - CreateVPNConnectionRoute(*ec2.CreateVPNConnectionRouteInput) (*ec2.CreateVPNConnectionRouteOutput, error) + CreateVpcEndpointRequest(*ec2.CreateVpcEndpointInput) (*request.Request, *ec2.CreateVpcEndpointOutput) - CreateVPNGateway(*ec2.CreateVPNGatewayInput) (*ec2.CreateVPNGatewayOutput, error) + CreateVpcEndpoint(*ec2.CreateVpcEndpointInput) (*ec2.CreateVpcEndpointOutput, error) - CreateVolume(*ec2.CreateVolumeInput) (*ec2.Volume, error) + CreateVpcPeeringConnectionRequest(*ec2.CreateVpcPeeringConnectionInput) (*request.Request, *ec2.CreateVpcPeeringConnectionOutput) + + CreateVpcPeeringConnection(*ec2.CreateVpcPeeringConnectionInput) (*ec2.CreateVpcPeeringConnectionOutput, error) + + CreateVpnConnectionRequest(*ec2.CreateVpnConnectionInput) (*request.Request, *ec2.CreateVpnConnectionOutput) + + CreateVpnConnection(*ec2.CreateVpnConnectionInput) (*ec2.CreateVpnConnectionOutput, error) + + CreateVpnConnectionRouteRequest(*ec2.CreateVpnConnectionRouteInput) (*request.Request, *ec2.CreateVpnConnectionRouteOutput) + + CreateVpnConnectionRoute(*ec2.CreateVpnConnectionRouteInput) (*ec2.CreateVpnConnectionRouteOutput, error) + + CreateVpnGatewayRequest(*ec2.CreateVpnGatewayInput) (*request.Request, *ec2.CreateVpnGatewayOutput) + + CreateVpnGateway(*ec2.CreateVpnGatewayInput) (*ec2.CreateVpnGatewayOutput, error) + + DeleteCustomerGatewayRequest(*ec2.DeleteCustomerGatewayInput) (*request.Request, *ec2.DeleteCustomerGatewayOutput) DeleteCustomerGateway(*ec2.DeleteCustomerGatewayInput) (*ec2.DeleteCustomerGatewayOutput, error) - DeleteDHCPOptions(*ec2.DeleteDHCPOptionsInput) (*ec2.DeleteDHCPOptionsOutput, error) + DeleteDhcpOptionsRequest(*ec2.DeleteDhcpOptionsInput) (*request.Request, *ec2.DeleteDhcpOptionsOutput) + + DeleteDhcpOptions(*ec2.DeleteDhcpOptionsInput) (*ec2.DeleteDhcpOptionsOutput, error) + + DeleteFlowLogsRequest(*ec2.DeleteFlowLogsInput) (*request.Request, *ec2.DeleteFlowLogsOutput) + + DeleteFlowLogs(*ec2.DeleteFlowLogsInput) (*ec2.DeleteFlowLogsOutput, error) + + DeleteInternetGatewayRequest(*ec2.DeleteInternetGatewayInput) (*request.Request, *ec2.DeleteInternetGatewayOutput) DeleteInternetGateway(*ec2.DeleteInternetGatewayInput) (*ec2.DeleteInternetGatewayOutput, error) + DeleteKeyPairRequest(*ec2.DeleteKeyPairInput) (*request.Request, *ec2.DeleteKeyPairOutput) + DeleteKeyPair(*ec2.DeleteKeyPairInput) (*ec2.DeleteKeyPairOutput, error) - DeleteNetworkACL(*ec2.DeleteNetworkACLInput) (*ec2.DeleteNetworkACLOutput, error) + DeleteNetworkAclRequest(*ec2.DeleteNetworkAclInput) (*request.Request, *ec2.DeleteNetworkAclOutput) - DeleteNetworkACLEntry(*ec2.DeleteNetworkACLEntryInput) (*ec2.DeleteNetworkACLEntryOutput, error) + DeleteNetworkAcl(*ec2.DeleteNetworkAclInput) (*ec2.DeleteNetworkAclOutput, error) + + DeleteNetworkAclEntryRequest(*ec2.DeleteNetworkAclEntryInput) (*request.Request, *ec2.DeleteNetworkAclEntryOutput) + + DeleteNetworkAclEntry(*ec2.DeleteNetworkAclEntryInput) (*ec2.DeleteNetworkAclEntryOutput, error) + + DeleteNetworkInterfaceRequest(*ec2.DeleteNetworkInterfaceInput) (*request.Request, *ec2.DeleteNetworkInterfaceOutput) DeleteNetworkInterface(*ec2.DeleteNetworkInterfaceInput) (*ec2.DeleteNetworkInterfaceOutput, error) + DeletePlacementGroupRequest(*ec2.DeletePlacementGroupInput) (*request.Request, *ec2.DeletePlacementGroupOutput) + DeletePlacementGroup(*ec2.DeletePlacementGroupInput) (*ec2.DeletePlacementGroupOutput, error) + DeleteRouteRequest(*ec2.DeleteRouteInput) (*request.Request, *ec2.DeleteRouteOutput) + DeleteRoute(*ec2.DeleteRouteInput) (*ec2.DeleteRouteOutput, error) + DeleteRouteTableRequest(*ec2.DeleteRouteTableInput) (*request.Request, *ec2.DeleteRouteTableOutput) + DeleteRouteTable(*ec2.DeleteRouteTableInput) (*ec2.DeleteRouteTableOutput, error) + DeleteSecurityGroupRequest(*ec2.DeleteSecurityGroupInput) (*request.Request, *ec2.DeleteSecurityGroupOutput) + DeleteSecurityGroup(*ec2.DeleteSecurityGroupInput) (*ec2.DeleteSecurityGroupOutput, error) + DeleteSnapshotRequest(*ec2.DeleteSnapshotInput) (*request.Request, *ec2.DeleteSnapshotOutput) + DeleteSnapshot(*ec2.DeleteSnapshotInput) (*ec2.DeleteSnapshotOutput, error) + DeleteSpotDatafeedSubscriptionRequest(*ec2.DeleteSpotDatafeedSubscriptionInput) (*request.Request, *ec2.DeleteSpotDatafeedSubscriptionOutput) + DeleteSpotDatafeedSubscription(*ec2.DeleteSpotDatafeedSubscriptionInput) (*ec2.DeleteSpotDatafeedSubscriptionOutput, error) + DeleteSubnetRequest(*ec2.DeleteSubnetInput) (*request.Request, *ec2.DeleteSubnetOutput) + DeleteSubnet(*ec2.DeleteSubnetInput) (*ec2.DeleteSubnetOutput, error) + DeleteTagsRequest(*ec2.DeleteTagsInput) (*request.Request, *ec2.DeleteTagsOutput) + DeleteTags(*ec2.DeleteTagsInput) (*ec2.DeleteTagsOutput, error) - DeleteVPC(*ec2.DeleteVPCInput) (*ec2.DeleteVPCOutput, error) + DeleteVolumeRequest(*ec2.DeleteVolumeInput) (*request.Request, *ec2.DeleteVolumeOutput) - DeleteVPCEndpoints(*ec2.DeleteVPCEndpointsInput) (*ec2.DeleteVPCEndpointsOutput, error) + DeleteVolume(*ec2.DeleteVolumeInput) (*ec2.DeleteVolumeOutput, error) - DeleteVPCPeeringConnection(*ec2.DeleteVPCPeeringConnectionInput) (*ec2.DeleteVPCPeeringConnectionOutput, error) + DeleteVpcRequest(*ec2.DeleteVpcInput) (*request.Request, *ec2.DeleteVpcOutput) - DeleteVPNConnection(*ec2.DeleteVPNConnectionInput) (*ec2.DeleteVPNConnectionOutput, error) + DeleteVpc(*ec2.DeleteVpcInput) (*ec2.DeleteVpcOutput, error) - DeleteVPNConnectionRoute(*ec2.DeleteVPNConnectionRouteInput) (*ec2.DeleteVPNConnectionRouteOutput, error) + DeleteVpcEndpointsRequest(*ec2.DeleteVpcEndpointsInput) (*request.Request, *ec2.DeleteVpcEndpointsOutput) - DeleteVPNGateway(*ec2.DeleteVPNGatewayInput) (*ec2.DeleteVPNGatewayOutput, error) + DeleteVpcEndpoints(*ec2.DeleteVpcEndpointsInput) (*ec2.DeleteVpcEndpointsOutput, error) - DeleteVolume(*ec2.DeleteVolumeInput) (*ec2.DeleteVolumeOutput, error) + DeleteVpcPeeringConnectionRequest(*ec2.DeleteVpcPeeringConnectionInput) (*request.Request, *ec2.DeleteVpcPeeringConnectionOutput) + + DeleteVpcPeeringConnection(*ec2.DeleteVpcPeeringConnectionInput) (*ec2.DeleteVpcPeeringConnectionOutput, error) + + DeleteVpnConnectionRequest(*ec2.DeleteVpnConnectionInput) (*request.Request, *ec2.DeleteVpnConnectionOutput) + + DeleteVpnConnection(*ec2.DeleteVpnConnectionInput) (*ec2.DeleteVpnConnectionOutput, error) + + DeleteVpnConnectionRouteRequest(*ec2.DeleteVpnConnectionRouteInput) (*request.Request, *ec2.DeleteVpnConnectionRouteOutput) + + DeleteVpnConnectionRoute(*ec2.DeleteVpnConnectionRouteInput) (*ec2.DeleteVpnConnectionRouteOutput, error) + + DeleteVpnGatewayRequest(*ec2.DeleteVpnGatewayInput) (*request.Request, *ec2.DeleteVpnGatewayOutput) + + DeleteVpnGateway(*ec2.DeleteVpnGatewayInput) (*ec2.DeleteVpnGatewayOutput, error) + + DeregisterImageRequest(*ec2.DeregisterImageInput) (*request.Request, *ec2.DeregisterImageOutput) DeregisterImage(*ec2.DeregisterImageInput) (*ec2.DeregisterImageOutput, error) + DescribeAccountAttributesRequest(*ec2.DescribeAccountAttributesInput) (*request.Request, *ec2.DescribeAccountAttributesOutput) + DescribeAccountAttributes(*ec2.DescribeAccountAttributesInput) (*ec2.DescribeAccountAttributesOutput, error) + DescribeAddressesRequest(*ec2.DescribeAddressesInput) (*request.Request, *ec2.DescribeAddressesOutput) + DescribeAddresses(*ec2.DescribeAddressesInput) (*ec2.DescribeAddressesOutput, error) + DescribeAvailabilityZonesRequest(*ec2.DescribeAvailabilityZonesInput) (*request.Request, *ec2.DescribeAvailabilityZonesOutput) + DescribeAvailabilityZones(*ec2.DescribeAvailabilityZonesInput) (*ec2.DescribeAvailabilityZonesOutput, error) + DescribeBundleTasksRequest(*ec2.DescribeBundleTasksInput) (*request.Request, *ec2.DescribeBundleTasksOutput) + DescribeBundleTasks(*ec2.DescribeBundleTasksInput) (*ec2.DescribeBundleTasksOutput, error) + DescribeClassicLinkInstancesRequest(*ec2.DescribeClassicLinkInstancesInput) (*request.Request, *ec2.DescribeClassicLinkInstancesOutput) + DescribeClassicLinkInstances(*ec2.DescribeClassicLinkInstancesInput) (*ec2.DescribeClassicLinkInstancesOutput, error) + DescribeConversionTasksRequest(*ec2.DescribeConversionTasksInput) (*request.Request, *ec2.DescribeConversionTasksOutput) + DescribeConversionTasks(*ec2.DescribeConversionTasksInput) (*ec2.DescribeConversionTasksOutput, error) + DescribeCustomerGatewaysRequest(*ec2.DescribeCustomerGatewaysInput) (*request.Request, *ec2.DescribeCustomerGatewaysOutput) + DescribeCustomerGateways(*ec2.DescribeCustomerGatewaysInput) (*ec2.DescribeCustomerGatewaysOutput, error) - DescribeDHCPOptions(*ec2.DescribeDHCPOptionsInput) (*ec2.DescribeDHCPOptionsOutput, error) + DescribeDhcpOptionsRequest(*ec2.DescribeDhcpOptionsInput) (*request.Request, *ec2.DescribeDhcpOptionsOutput) + + DescribeDhcpOptions(*ec2.DescribeDhcpOptionsInput) (*ec2.DescribeDhcpOptionsOutput, error) + + DescribeExportTasksRequest(*ec2.DescribeExportTasksInput) (*request.Request, *ec2.DescribeExportTasksOutput) DescribeExportTasks(*ec2.DescribeExportTasksInput) (*ec2.DescribeExportTasksOutput, error) + DescribeFlowLogsRequest(*ec2.DescribeFlowLogsInput) (*request.Request, *ec2.DescribeFlowLogsOutput) + + DescribeFlowLogs(*ec2.DescribeFlowLogsInput) (*ec2.DescribeFlowLogsOutput, error) + + DescribeImageAttributeRequest(*ec2.DescribeImageAttributeInput) (*request.Request, *ec2.DescribeImageAttributeOutput) + DescribeImageAttribute(*ec2.DescribeImageAttributeInput) (*ec2.DescribeImageAttributeOutput, error) + DescribeImagesRequest(*ec2.DescribeImagesInput) (*request.Request, *ec2.DescribeImagesOutput) + DescribeImages(*ec2.DescribeImagesInput) (*ec2.DescribeImagesOutput, error) + DescribeImportImageTasksRequest(*ec2.DescribeImportImageTasksInput) (*request.Request, *ec2.DescribeImportImageTasksOutput) + DescribeImportImageTasks(*ec2.DescribeImportImageTasksInput) (*ec2.DescribeImportImageTasksOutput, error) + DescribeImportSnapshotTasksRequest(*ec2.DescribeImportSnapshotTasksInput) (*request.Request, *ec2.DescribeImportSnapshotTasksOutput) + DescribeImportSnapshotTasks(*ec2.DescribeImportSnapshotTasksInput) (*ec2.DescribeImportSnapshotTasksOutput, error) + DescribeInstanceAttributeRequest(*ec2.DescribeInstanceAttributeInput) (*request.Request, *ec2.DescribeInstanceAttributeOutput) + DescribeInstanceAttribute(*ec2.DescribeInstanceAttributeInput) (*ec2.DescribeInstanceAttributeOutput, error) + DescribeInstanceStatusRequest(*ec2.DescribeInstanceStatusInput) (*request.Request, *ec2.DescribeInstanceStatusOutput) + DescribeInstanceStatus(*ec2.DescribeInstanceStatusInput) (*ec2.DescribeInstanceStatusOutput, error) + DescribeInstanceStatusPages(*ec2.DescribeInstanceStatusInput, func(*ec2.DescribeInstanceStatusOutput, bool) bool) error + + DescribeInstancesRequest(*ec2.DescribeInstancesInput) (*request.Request, *ec2.DescribeInstancesOutput) + DescribeInstances(*ec2.DescribeInstancesInput) (*ec2.DescribeInstancesOutput, error) + DescribeInstancesPages(*ec2.DescribeInstancesInput, func(*ec2.DescribeInstancesOutput, bool) bool) error + + DescribeInternetGatewaysRequest(*ec2.DescribeInternetGatewaysInput) (*request.Request, *ec2.DescribeInternetGatewaysOutput) + DescribeInternetGateways(*ec2.DescribeInternetGatewaysInput) (*ec2.DescribeInternetGatewaysOutput, error) + DescribeKeyPairsRequest(*ec2.DescribeKeyPairsInput) (*request.Request, *ec2.DescribeKeyPairsOutput) + DescribeKeyPairs(*ec2.DescribeKeyPairsInput) (*ec2.DescribeKeyPairsOutput, error) + DescribeMovingAddressesRequest(*ec2.DescribeMovingAddressesInput) (*request.Request, *ec2.DescribeMovingAddressesOutput) + DescribeMovingAddresses(*ec2.DescribeMovingAddressesInput) (*ec2.DescribeMovingAddressesOutput, error) - DescribeNetworkACLs(*ec2.DescribeNetworkACLsInput) (*ec2.DescribeNetworkACLsOutput, error) + DescribeNetworkAclsRequest(*ec2.DescribeNetworkAclsInput) (*request.Request, *ec2.DescribeNetworkAclsOutput) + + DescribeNetworkAcls(*ec2.DescribeNetworkAclsInput) (*ec2.DescribeNetworkAclsOutput, error) + + DescribeNetworkInterfaceAttributeRequest(*ec2.DescribeNetworkInterfaceAttributeInput) (*request.Request, *ec2.DescribeNetworkInterfaceAttributeOutput) DescribeNetworkInterfaceAttribute(*ec2.DescribeNetworkInterfaceAttributeInput) (*ec2.DescribeNetworkInterfaceAttributeOutput, error) + DescribeNetworkInterfacesRequest(*ec2.DescribeNetworkInterfacesInput) (*request.Request, *ec2.DescribeNetworkInterfacesOutput) + DescribeNetworkInterfaces(*ec2.DescribeNetworkInterfacesInput) (*ec2.DescribeNetworkInterfacesOutput, error) + DescribePlacementGroupsRequest(*ec2.DescribePlacementGroupsInput) (*request.Request, *ec2.DescribePlacementGroupsOutput) + DescribePlacementGroups(*ec2.DescribePlacementGroupsInput) (*ec2.DescribePlacementGroupsOutput, error) + DescribePrefixListsRequest(*ec2.DescribePrefixListsInput) (*request.Request, *ec2.DescribePrefixListsOutput) + DescribePrefixLists(*ec2.DescribePrefixListsInput) (*ec2.DescribePrefixListsOutput, error) + DescribeRegionsRequest(*ec2.DescribeRegionsInput) (*request.Request, *ec2.DescribeRegionsOutput) + DescribeRegions(*ec2.DescribeRegionsInput) (*ec2.DescribeRegionsOutput, error) + DescribeReservedInstancesRequest(*ec2.DescribeReservedInstancesInput) (*request.Request, *ec2.DescribeReservedInstancesOutput) + DescribeReservedInstances(*ec2.DescribeReservedInstancesInput) (*ec2.DescribeReservedInstancesOutput, error) + DescribeReservedInstancesListingsRequest(*ec2.DescribeReservedInstancesListingsInput) (*request.Request, *ec2.DescribeReservedInstancesListingsOutput) + DescribeReservedInstancesListings(*ec2.DescribeReservedInstancesListingsInput) (*ec2.DescribeReservedInstancesListingsOutput, error) + DescribeReservedInstancesModificationsRequest(*ec2.DescribeReservedInstancesModificationsInput) (*request.Request, *ec2.DescribeReservedInstancesModificationsOutput) + DescribeReservedInstancesModifications(*ec2.DescribeReservedInstancesModificationsInput) (*ec2.DescribeReservedInstancesModificationsOutput, error) + DescribeReservedInstancesModificationsPages(*ec2.DescribeReservedInstancesModificationsInput, func(*ec2.DescribeReservedInstancesModificationsOutput, bool) bool) error + + DescribeReservedInstancesOfferingsRequest(*ec2.DescribeReservedInstancesOfferingsInput) (*request.Request, *ec2.DescribeReservedInstancesOfferingsOutput) + DescribeReservedInstancesOfferings(*ec2.DescribeReservedInstancesOfferingsInput) (*ec2.DescribeReservedInstancesOfferingsOutput, error) + DescribeReservedInstancesOfferingsPages(*ec2.DescribeReservedInstancesOfferingsInput, func(*ec2.DescribeReservedInstancesOfferingsOutput, bool) bool) error + + DescribeRouteTablesRequest(*ec2.DescribeRouteTablesInput) (*request.Request, *ec2.DescribeRouteTablesOutput) + DescribeRouteTables(*ec2.DescribeRouteTablesInput) (*ec2.DescribeRouteTablesOutput, error) + DescribeSecurityGroupsRequest(*ec2.DescribeSecurityGroupsInput) (*request.Request, *ec2.DescribeSecurityGroupsOutput) + DescribeSecurityGroups(*ec2.DescribeSecurityGroupsInput) (*ec2.DescribeSecurityGroupsOutput, error) + DescribeSnapshotAttributeRequest(*ec2.DescribeSnapshotAttributeInput) (*request.Request, *ec2.DescribeSnapshotAttributeOutput) + DescribeSnapshotAttribute(*ec2.DescribeSnapshotAttributeInput) (*ec2.DescribeSnapshotAttributeOutput, error) + DescribeSnapshotsRequest(*ec2.DescribeSnapshotsInput) (*request.Request, *ec2.DescribeSnapshotsOutput) + DescribeSnapshots(*ec2.DescribeSnapshotsInput) (*ec2.DescribeSnapshotsOutput, error) + DescribeSnapshotsPages(*ec2.DescribeSnapshotsInput, func(*ec2.DescribeSnapshotsOutput, bool) bool) error + + DescribeSpotDatafeedSubscriptionRequest(*ec2.DescribeSpotDatafeedSubscriptionInput) (*request.Request, *ec2.DescribeSpotDatafeedSubscriptionOutput) + DescribeSpotDatafeedSubscription(*ec2.DescribeSpotDatafeedSubscriptionInput) (*ec2.DescribeSpotDatafeedSubscriptionOutput, error) + DescribeSpotFleetInstancesRequest(*ec2.DescribeSpotFleetInstancesInput) (*request.Request, *ec2.DescribeSpotFleetInstancesOutput) + DescribeSpotFleetInstances(*ec2.DescribeSpotFleetInstancesInput) (*ec2.DescribeSpotFleetInstancesOutput, error) + DescribeSpotFleetRequestHistoryRequest(*ec2.DescribeSpotFleetRequestHistoryInput) (*request.Request, *ec2.DescribeSpotFleetRequestHistoryOutput) + DescribeSpotFleetRequestHistory(*ec2.DescribeSpotFleetRequestHistoryInput) (*ec2.DescribeSpotFleetRequestHistoryOutput, error) + DescribeSpotFleetRequestsRequest(*ec2.DescribeSpotFleetRequestsInput) (*request.Request, *ec2.DescribeSpotFleetRequestsOutput) + DescribeSpotFleetRequests(*ec2.DescribeSpotFleetRequestsInput) (*ec2.DescribeSpotFleetRequestsOutput, error) + DescribeSpotInstanceRequestsRequest(*ec2.DescribeSpotInstanceRequestsInput) (*request.Request, *ec2.DescribeSpotInstanceRequestsOutput) + DescribeSpotInstanceRequests(*ec2.DescribeSpotInstanceRequestsInput) (*ec2.DescribeSpotInstanceRequestsOutput, error) + DescribeSpotPriceHistoryRequest(*ec2.DescribeSpotPriceHistoryInput) (*request.Request, *ec2.DescribeSpotPriceHistoryOutput) + DescribeSpotPriceHistory(*ec2.DescribeSpotPriceHistoryInput) (*ec2.DescribeSpotPriceHistoryOutput, error) + DescribeSpotPriceHistoryPages(*ec2.DescribeSpotPriceHistoryInput, func(*ec2.DescribeSpotPriceHistoryOutput, bool) bool) error + + DescribeSubnetsRequest(*ec2.DescribeSubnetsInput) (*request.Request, *ec2.DescribeSubnetsOutput) + DescribeSubnets(*ec2.DescribeSubnetsInput) (*ec2.DescribeSubnetsOutput, error) + DescribeTagsRequest(*ec2.DescribeTagsInput) (*request.Request, *ec2.DescribeTagsOutput) + DescribeTags(*ec2.DescribeTagsInput) (*ec2.DescribeTagsOutput, error) - DescribeVPCAttribute(*ec2.DescribeVPCAttributeInput) (*ec2.DescribeVPCAttributeOutput, error) + DescribeVolumeAttributeRequest(*ec2.DescribeVolumeAttributeInput) (*request.Request, *ec2.DescribeVolumeAttributeOutput) - DescribeVPCClassicLink(*ec2.DescribeVPCClassicLinkInput) (*ec2.DescribeVPCClassicLinkOutput, error) + DescribeVolumeAttribute(*ec2.DescribeVolumeAttributeInput) (*ec2.DescribeVolumeAttributeOutput, error) - DescribeVPCEndpointServices(*ec2.DescribeVPCEndpointServicesInput) (*ec2.DescribeVPCEndpointServicesOutput, error) + DescribeVolumeStatusRequest(*ec2.DescribeVolumeStatusInput) (*request.Request, *ec2.DescribeVolumeStatusOutput) - DescribeVPCEndpoints(*ec2.DescribeVPCEndpointsInput) (*ec2.DescribeVPCEndpointsOutput, error) + DescribeVolumeStatus(*ec2.DescribeVolumeStatusInput) (*ec2.DescribeVolumeStatusOutput, error) - DescribeVPCPeeringConnections(*ec2.DescribeVPCPeeringConnectionsInput) (*ec2.DescribeVPCPeeringConnectionsOutput, error) + DescribeVolumeStatusPages(*ec2.DescribeVolumeStatusInput, func(*ec2.DescribeVolumeStatusOutput, bool) bool) error - DescribeVPCs(*ec2.DescribeVPCsInput) (*ec2.DescribeVPCsOutput, error) + DescribeVolumesRequest(*ec2.DescribeVolumesInput) (*request.Request, *ec2.DescribeVolumesOutput) - DescribeVPNConnections(*ec2.DescribeVPNConnectionsInput) (*ec2.DescribeVPNConnectionsOutput, error) + DescribeVolumes(*ec2.DescribeVolumesInput) (*ec2.DescribeVolumesOutput, error) - DescribeVPNGateways(*ec2.DescribeVPNGatewaysInput) (*ec2.DescribeVPNGatewaysOutput, error) + DescribeVolumesPages(*ec2.DescribeVolumesInput, func(*ec2.DescribeVolumesOutput, bool) bool) error - DescribeVolumeAttribute(*ec2.DescribeVolumeAttributeInput) (*ec2.DescribeVolumeAttributeOutput, error) + DescribeVpcAttributeRequest(*ec2.DescribeVpcAttributeInput) (*request.Request, *ec2.DescribeVpcAttributeOutput) - DescribeVolumeStatus(*ec2.DescribeVolumeStatusInput) (*ec2.DescribeVolumeStatusOutput, error) + DescribeVpcAttribute(*ec2.DescribeVpcAttributeInput) (*ec2.DescribeVpcAttributeOutput, error) - DescribeVolumes(*ec2.DescribeVolumesInput) (*ec2.DescribeVolumesOutput, error) + DescribeVpcClassicLinkRequest(*ec2.DescribeVpcClassicLinkInput) (*request.Request, *ec2.DescribeVpcClassicLinkOutput) + + DescribeVpcClassicLink(*ec2.DescribeVpcClassicLinkInput) (*ec2.DescribeVpcClassicLinkOutput, error) + + DescribeVpcEndpointServicesRequest(*ec2.DescribeVpcEndpointServicesInput) (*request.Request, *ec2.DescribeVpcEndpointServicesOutput) + + DescribeVpcEndpointServices(*ec2.DescribeVpcEndpointServicesInput) (*ec2.DescribeVpcEndpointServicesOutput, error) + + DescribeVpcEndpointsRequest(*ec2.DescribeVpcEndpointsInput) (*request.Request, *ec2.DescribeVpcEndpointsOutput) + + DescribeVpcEndpoints(*ec2.DescribeVpcEndpointsInput) (*ec2.DescribeVpcEndpointsOutput, error) + + DescribeVpcPeeringConnectionsRequest(*ec2.DescribeVpcPeeringConnectionsInput) (*request.Request, *ec2.DescribeVpcPeeringConnectionsOutput) + + DescribeVpcPeeringConnections(*ec2.DescribeVpcPeeringConnectionsInput) (*ec2.DescribeVpcPeeringConnectionsOutput, error) - DetachClassicLinkVPC(*ec2.DetachClassicLinkVPCInput) (*ec2.DetachClassicLinkVPCOutput, error) + DescribeVpcsRequest(*ec2.DescribeVpcsInput) (*request.Request, *ec2.DescribeVpcsOutput) + + DescribeVpcs(*ec2.DescribeVpcsInput) (*ec2.DescribeVpcsOutput, error) + + DescribeVpnConnectionsRequest(*ec2.DescribeVpnConnectionsInput) (*request.Request, *ec2.DescribeVpnConnectionsOutput) + + DescribeVpnConnections(*ec2.DescribeVpnConnectionsInput) (*ec2.DescribeVpnConnectionsOutput, error) + + DescribeVpnGatewaysRequest(*ec2.DescribeVpnGatewaysInput) (*request.Request, *ec2.DescribeVpnGatewaysOutput) + + DescribeVpnGateways(*ec2.DescribeVpnGatewaysInput) (*ec2.DescribeVpnGatewaysOutput, error) + + DetachClassicLinkVpcRequest(*ec2.DetachClassicLinkVpcInput) (*request.Request, *ec2.DetachClassicLinkVpcOutput) + + DetachClassicLinkVpc(*ec2.DetachClassicLinkVpcInput) (*ec2.DetachClassicLinkVpcOutput, error) + + DetachInternetGatewayRequest(*ec2.DetachInternetGatewayInput) (*request.Request, *ec2.DetachInternetGatewayOutput) DetachInternetGateway(*ec2.DetachInternetGatewayInput) (*ec2.DetachInternetGatewayOutput, error) + DetachNetworkInterfaceRequest(*ec2.DetachNetworkInterfaceInput) (*request.Request, *ec2.DetachNetworkInterfaceOutput) + DetachNetworkInterface(*ec2.DetachNetworkInterfaceInput) (*ec2.DetachNetworkInterfaceOutput, error) - DetachVPNGateway(*ec2.DetachVPNGatewayInput) (*ec2.DetachVPNGatewayOutput, error) + DetachVolumeRequest(*ec2.DetachVolumeInput) (*request.Request, *ec2.VolumeAttachment) DetachVolume(*ec2.DetachVolumeInput) (*ec2.VolumeAttachment, error) - DisableVGWRoutePropagation(*ec2.DisableVGWRoutePropagationInput) (*ec2.DisableVGWRoutePropagationOutput, error) + DetachVpnGatewayRequest(*ec2.DetachVpnGatewayInput) (*request.Request, *ec2.DetachVpnGatewayOutput) + + DetachVpnGateway(*ec2.DetachVpnGatewayInput) (*ec2.DetachVpnGatewayOutput, error) + + DisableVgwRoutePropagationRequest(*ec2.DisableVgwRoutePropagationInput) (*request.Request, *ec2.DisableVgwRoutePropagationOutput) + + DisableVgwRoutePropagation(*ec2.DisableVgwRoutePropagationInput) (*ec2.DisableVgwRoutePropagationOutput, error) - DisableVPCClassicLink(*ec2.DisableVPCClassicLinkInput) (*ec2.DisableVPCClassicLinkOutput, error) + DisableVpcClassicLinkRequest(*ec2.DisableVpcClassicLinkInput) (*request.Request, *ec2.DisableVpcClassicLinkOutput) + + DisableVpcClassicLink(*ec2.DisableVpcClassicLinkInput) (*ec2.DisableVpcClassicLinkOutput, error) + + DisassociateAddressRequest(*ec2.DisassociateAddressInput) (*request.Request, *ec2.DisassociateAddressOutput) DisassociateAddress(*ec2.DisassociateAddressInput) (*ec2.DisassociateAddressOutput, error) + DisassociateRouteTableRequest(*ec2.DisassociateRouteTableInput) (*request.Request, *ec2.DisassociateRouteTableOutput) + DisassociateRouteTable(*ec2.DisassociateRouteTableInput) (*ec2.DisassociateRouteTableOutput, error) - EnableVGWRoutePropagation(*ec2.EnableVGWRoutePropagationInput) (*ec2.EnableVGWRoutePropagationOutput, error) + EnableVgwRoutePropagationRequest(*ec2.EnableVgwRoutePropagationInput) (*request.Request, *ec2.EnableVgwRoutePropagationOutput) + + EnableVgwRoutePropagation(*ec2.EnableVgwRoutePropagationInput) (*ec2.EnableVgwRoutePropagationOutput, error) - EnableVPCClassicLink(*ec2.EnableVPCClassicLinkInput) (*ec2.EnableVPCClassicLinkOutput, error) + EnableVolumeIORequest(*ec2.EnableVolumeIOInput) (*request.Request, *ec2.EnableVolumeIOOutput) EnableVolumeIO(*ec2.EnableVolumeIOInput) (*ec2.EnableVolumeIOOutput, error) + EnableVpcClassicLinkRequest(*ec2.EnableVpcClassicLinkInput) (*request.Request, *ec2.EnableVpcClassicLinkOutput) + + EnableVpcClassicLink(*ec2.EnableVpcClassicLinkInput) (*ec2.EnableVpcClassicLinkOutput, error) + + GetConsoleOutputRequest(*ec2.GetConsoleOutputInput) (*request.Request, *ec2.GetConsoleOutputOutput) + GetConsoleOutput(*ec2.GetConsoleOutputInput) (*ec2.GetConsoleOutputOutput, error) + GetPasswordDataRequest(*ec2.GetPasswordDataInput) (*request.Request, *ec2.GetPasswordDataOutput) + GetPasswordData(*ec2.GetPasswordDataInput) (*ec2.GetPasswordDataOutput, error) + ImportImageRequest(*ec2.ImportImageInput) (*request.Request, *ec2.ImportImageOutput) + ImportImage(*ec2.ImportImageInput) (*ec2.ImportImageOutput, error) + ImportInstanceRequest(*ec2.ImportInstanceInput) (*request.Request, *ec2.ImportInstanceOutput) + ImportInstance(*ec2.ImportInstanceInput) (*ec2.ImportInstanceOutput, error) + ImportKeyPairRequest(*ec2.ImportKeyPairInput) (*request.Request, *ec2.ImportKeyPairOutput) + ImportKeyPair(*ec2.ImportKeyPairInput) (*ec2.ImportKeyPairOutput, error) + ImportSnapshotRequest(*ec2.ImportSnapshotInput) (*request.Request, *ec2.ImportSnapshotOutput) + ImportSnapshot(*ec2.ImportSnapshotInput) (*ec2.ImportSnapshotOutput, error) + ImportVolumeRequest(*ec2.ImportVolumeInput) (*request.Request, *ec2.ImportVolumeOutput) + ImportVolume(*ec2.ImportVolumeInput) (*ec2.ImportVolumeOutput, error) + ModifyImageAttributeRequest(*ec2.ModifyImageAttributeInput) (*request.Request, *ec2.ModifyImageAttributeOutput) + ModifyImageAttribute(*ec2.ModifyImageAttributeInput) (*ec2.ModifyImageAttributeOutput, error) + ModifyInstanceAttributeRequest(*ec2.ModifyInstanceAttributeInput) (*request.Request, *ec2.ModifyInstanceAttributeOutput) + ModifyInstanceAttribute(*ec2.ModifyInstanceAttributeInput) (*ec2.ModifyInstanceAttributeOutput, error) + ModifyNetworkInterfaceAttributeRequest(*ec2.ModifyNetworkInterfaceAttributeInput) (*request.Request, *ec2.ModifyNetworkInterfaceAttributeOutput) + ModifyNetworkInterfaceAttribute(*ec2.ModifyNetworkInterfaceAttributeInput) (*ec2.ModifyNetworkInterfaceAttributeOutput, error) + ModifyReservedInstancesRequest(*ec2.ModifyReservedInstancesInput) (*request.Request, *ec2.ModifyReservedInstancesOutput) + ModifyReservedInstances(*ec2.ModifyReservedInstancesInput) (*ec2.ModifyReservedInstancesOutput, error) + ModifySnapshotAttributeRequest(*ec2.ModifySnapshotAttributeInput) (*request.Request, *ec2.ModifySnapshotAttributeOutput) + ModifySnapshotAttribute(*ec2.ModifySnapshotAttributeInput) (*ec2.ModifySnapshotAttributeOutput, error) - ModifySubnetAttribute(*ec2.ModifySubnetAttributeInput) (*ec2.ModifySubnetAttributeOutput, error) + ModifySubnetAttributeRequest(*ec2.ModifySubnetAttributeInput) (*request.Request, *ec2.ModifySubnetAttributeOutput) - ModifyVPCAttribute(*ec2.ModifyVPCAttributeInput) (*ec2.ModifyVPCAttributeOutput, error) + ModifySubnetAttribute(*ec2.ModifySubnetAttributeInput) (*ec2.ModifySubnetAttributeOutput, error) - ModifyVPCEndpoint(*ec2.ModifyVPCEndpointInput) (*ec2.ModifyVPCEndpointOutput, error) + ModifyVolumeAttributeRequest(*ec2.ModifyVolumeAttributeInput) (*request.Request, *ec2.ModifyVolumeAttributeOutput) ModifyVolumeAttribute(*ec2.ModifyVolumeAttributeInput) (*ec2.ModifyVolumeAttributeOutput, error) + ModifyVpcAttributeRequest(*ec2.ModifyVpcAttributeInput) (*request.Request, *ec2.ModifyVpcAttributeOutput) + + ModifyVpcAttribute(*ec2.ModifyVpcAttributeInput) (*ec2.ModifyVpcAttributeOutput, error) + + ModifyVpcEndpointRequest(*ec2.ModifyVpcEndpointInput) (*request.Request, *ec2.ModifyVpcEndpointOutput) + + ModifyVpcEndpoint(*ec2.ModifyVpcEndpointInput) (*ec2.ModifyVpcEndpointOutput, error) + + MonitorInstancesRequest(*ec2.MonitorInstancesInput) (*request.Request, *ec2.MonitorInstancesOutput) + MonitorInstances(*ec2.MonitorInstancesInput) (*ec2.MonitorInstancesOutput, error) - MoveAddressToVPC(*ec2.MoveAddressToVPCInput) (*ec2.MoveAddressToVPCOutput, error) + MoveAddressToVpcRequest(*ec2.MoveAddressToVpcInput) (*request.Request, *ec2.MoveAddressToVpcOutput) + + MoveAddressToVpc(*ec2.MoveAddressToVpcInput) (*ec2.MoveAddressToVpcOutput, error) + + PurchaseReservedInstancesOfferingRequest(*ec2.PurchaseReservedInstancesOfferingInput) (*request.Request, *ec2.PurchaseReservedInstancesOfferingOutput) PurchaseReservedInstancesOffering(*ec2.PurchaseReservedInstancesOfferingInput) (*ec2.PurchaseReservedInstancesOfferingOutput, error) + RebootInstancesRequest(*ec2.RebootInstancesInput) (*request.Request, *ec2.RebootInstancesOutput) + RebootInstances(*ec2.RebootInstancesInput) (*ec2.RebootInstancesOutput, error) + RegisterImageRequest(*ec2.RegisterImageInput) (*request.Request, *ec2.RegisterImageOutput) + RegisterImage(*ec2.RegisterImageInput) (*ec2.RegisterImageOutput, error) - RejectVPCPeeringConnection(*ec2.RejectVPCPeeringConnectionInput) (*ec2.RejectVPCPeeringConnectionOutput, error) + RejectVpcPeeringConnectionRequest(*ec2.RejectVpcPeeringConnectionInput) (*request.Request, *ec2.RejectVpcPeeringConnectionOutput) + + RejectVpcPeeringConnection(*ec2.RejectVpcPeeringConnectionInput) (*ec2.RejectVpcPeeringConnectionOutput, error) + + ReleaseAddressRequest(*ec2.ReleaseAddressInput) (*request.Request, *ec2.ReleaseAddressOutput) ReleaseAddress(*ec2.ReleaseAddressInput) (*ec2.ReleaseAddressOutput, error) - ReplaceNetworkACLAssociation(*ec2.ReplaceNetworkACLAssociationInput) (*ec2.ReplaceNetworkACLAssociationOutput, error) + ReplaceNetworkAclAssociationRequest(*ec2.ReplaceNetworkAclAssociationInput) (*request.Request, *ec2.ReplaceNetworkAclAssociationOutput) + + ReplaceNetworkAclAssociation(*ec2.ReplaceNetworkAclAssociationInput) (*ec2.ReplaceNetworkAclAssociationOutput, error) + + ReplaceNetworkAclEntryRequest(*ec2.ReplaceNetworkAclEntryInput) (*request.Request, *ec2.ReplaceNetworkAclEntryOutput) - ReplaceNetworkACLEntry(*ec2.ReplaceNetworkACLEntryInput) (*ec2.ReplaceNetworkACLEntryOutput, error) + ReplaceNetworkAclEntry(*ec2.ReplaceNetworkAclEntryInput) (*ec2.ReplaceNetworkAclEntryOutput, error) + + ReplaceRouteRequest(*ec2.ReplaceRouteInput) (*request.Request, *ec2.ReplaceRouteOutput) ReplaceRoute(*ec2.ReplaceRouteInput) (*ec2.ReplaceRouteOutput, error) + ReplaceRouteTableAssociationRequest(*ec2.ReplaceRouteTableAssociationInput) (*request.Request, *ec2.ReplaceRouteTableAssociationOutput) + ReplaceRouteTableAssociation(*ec2.ReplaceRouteTableAssociationInput) (*ec2.ReplaceRouteTableAssociationOutput, error) + ReportInstanceStatusRequest(*ec2.ReportInstanceStatusInput) (*request.Request, *ec2.ReportInstanceStatusOutput) + ReportInstanceStatus(*ec2.ReportInstanceStatusInput) (*ec2.ReportInstanceStatusOutput, error) + RequestSpotFleetRequest(*ec2.RequestSpotFleetInput) (*request.Request, *ec2.RequestSpotFleetOutput) + RequestSpotFleet(*ec2.RequestSpotFleetInput) (*ec2.RequestSpotFleetOutput, error) + RequestSpotInstancesRequest(*ec2.RequestSpotInstancesInput) (*request.Request, *ec2.RequestSpotInstancesOutput) + RequestSpotInstances(*ec2.RequestSpotInstancesInput) (*ec2.RequestSpotInstancesOutput, error) + ResetImageAttributeRequest(*ec2.ResetImageAttributeInput) (*request.Request, *ec2.ResetImageAttributeOutput) + ResetImageAttribute(*ec2.ResetImageAttributeInput) (*ec2.ResetImageAttributeOutput, error) + ResetInstanceAttributeRequest(*ec2.ResetInstanceAttributeInput) (*request.Request, *ec2.ResetInstanceAttributeOutput) + ResetInstanceAttribute(*ec2.ResetInstanceAttributeInput) (*ec2.ResetInstanceAttributeOutput, error) + ResetNetworkInterfaceAttributeRequest(*ec2.ResetNetworkInterfaceAttributeInput) (*request.Request, *ec2.ResetNetworkInterfaceAttributeOutput) + ResetNetworkInterfaceAttribute(*ec2.ResetNetworkInterfaceAttributeInput) (*ec2.ResetNetworkInterfaceAttributeOutput, error) + ResetSnapshotAttributeRequest(*ec2.ResetSnapshotAttributeInput) (*request.Request, *ec2.ResetSnapshotAttributeOutput) + ResetSnapshotAttribute(*ec2.ResetSnapshotAttributeInput) (*ec2.ResetSnapshotAttributeOutput, error) + RestoreAddressToClassicRequest(*ec2.RestoreAddressToClassicInput) (*request.Request, *ec2.RestoreAddressToClassicOutput) + RestoreAddressToClassic(*ec2.RestoreAddressToClassicInput) (*ec2.RestoreAddressToClassicOutput, error) + RevokeSecurityGroupEgressRequest(*ec2.RevokeSecurityGroupEgressInput) (*request.Request, *ec2.RevokeSecurityGroupEgressOutput) + RevokeSecurityGroupEgress(*ec2.RevokeSecurityGroupEgressInput) (*ec2.RevokeSecurityGroupEgressOutput, error) + RevokeSecurityGroupIngressRequest(*ec2.RevokeSecurityGroupIngressInput) (*request.Request, *ec2.RevokeSecurityGroupIngressOutput) + RevokeSecurityGroupIngress(*ec2.RevokeSecurityGroupIngressInput) (*ec2.RevokeSecurityGroupIngressOutput, error) + RunInstancesRequest(*ec2.RunInstancesInput) (*request.Request, *ec2.Reservation) + RunInstances(*ec2.RunInstancesInput) (*ec2.Reservation, error) + StartInstancesRequest(*ec2.StartInstancesInput) (*request.Request, *ec2.StartInstancesOutput) + StartInstances(*ec2.StartInstancesInput) (*ec2.StartInstancesOutput, error) + StopInstancesRequest(*ec2.StopInstancesInput) (*request.Request, *ec2.StopInstancesOutput) + StopInstances(*ec2.StopInstancesInput) (*ec2.StopInstancesOutput, error) + TerminateInstancesRequest(*ec2.TerminateInstancesInput) (*request.Request, *ec2.TerminateInstancesOutput) + TerminateInstances(*ec2.TerminateInstancesInput) (*ec2.TerminateInstancesOutput, error) - UnassignPrivateIPAddresses(*ec2.UnassignPrivateIPAddressesInput) (*ec2.UnassignPrivateIPAddressesOutput, error) + UnassignPrivateIpAddressesRequest(*ec2.UnassignPrivateIpAddressesInput) (*request.Request, *ec2.UnassignPrivateIpAddressesOutput) + + UnassignPrivateIpAddresses(*ec2.UnassignPrivateIpAddressesInput) (*ec2.UnassignPrivateIpAddressesOutput, error) + + UnmonitorInstancesRequest(*ec2.UnmonitorInstancesInput) (*request.Request, *ec2.UnmonitorInstancesOutput) UnmonitorInstances(*ec2.UnmonitorInstancesInput) (*ec2.UnmonitorInstancesOutput, error) } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/examples_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/examples_test.go index 76b63320285e..6da3b190cc21 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/examples_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/examples_test.go @@ -8,40 +8,30 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/ec2" ) var _ time.Duration var _ bytes.Buffer -func ExampleEC2_AcceptVPCPeeringConnection() { +func ExampleEC2_AcceptVpcPeeringConnection() { svc := ec2.New(nil) - params := &ec2.AcceptVPCPeeringConnectionInput{ - DryRun: aws.Boolean(true), - VPCPeeringConnectionID: aws.String("String"), + params := &ec2.AcceptVpcPeeringConnectionInput{ + DryRun: aws.Bool(true), + VpcPeeringConnectionId: aws.String("String"), } - resp, err := svc.AcceptVPCPeeringConnection(params) + resp, err := svc.AcceptVpcPeeringConnection(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_AllocateAddress() { @@ -49,548 +39,420 @@ func ExampleEC2_AllocateAddress() { params := &ec2.AllocateAddressInput{ Domain: aws.String("DomainType"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.AllocateAddress(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_AssignPrivateIPAddresses() { +func ExampleEC2_AssignPrivateIpAddresses() { svc := ec2.New(nil) - params := &ec2.AssignPrivateIPAddressesInput{ - NetworkInterfaceID: aws.String("String"), // Required - AllowReassignment: aws.Boolean(true), - PrivateIPAddresses: []*string{ + params := &ec2.AssignPrivateIpAddressesInput{ + NetworkInterfaceId: aws.String("String"), // Required + AllowReassignment: aws.Bool(true), + PrivateIpAddresses: []*string{ aws.String("String"), // Required // More values... }, - SecondaryPrivateIPAddressCount: aws.Long(1), + SecondaryPrivateIpAddressCount: aws.Int64(1), } - resp, err := svc.AssignPrivateIPAddresses(params) + resp, err := svc.AssignPrivateIpAddresses(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_AssociateAddress() { svc := ec2.New(nil) params := &ec2.AssociateAddressInput{ - AllocationID: aws.String("String"), - AllowReassociation: aws.Boolean(true), - DryRun: aws.Boolean(true), - InstanceID: aws.String("String"), - NetworkInterfaceID: aws.String("String"), - PrivateIPAddress: aws.String("String"), - PublicIP: aws.String("String"), + AllocationId: aws.String("String"), + AllowReassociation: aws.Bool(true), + DryRun: aws.Bool(true), + InstanceId: aws.String("String"), + NetworkInterfaceId: aws.String("String"), + PrivateIpAddress: aws.String("String"), + PublicIp: aws.String("String"), } resp, err := svc.AssociateAddress(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_AssociateDHCPOptions() { +func ExampleEC2_AssociateDhcpOptions() { svc := ec2.New(nil) - params := &ec2.AssociateDHCPOptionsInput{ - DHCPOptionsID: aws.String("String"), // Required - VPCID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.AssociateDhcpOptionsInput{ + DhcpOptionsId: aws.String("String"), // Required + VpcId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.AssociateDHCPOptions(params) + resp, err := svc.AssociateDhcpOptions(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_AssociateRouteTable() { svc := ec2.New(nil) params := &ec2.AssociateRouteTableInput{ - RouteTableID: aws.String("String"), // Required - SubnetID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + RouteTableId: aws.String("String"), // Required + SubnetId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.AssociateRouteTable(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_AttachClassicLinkVPC() { +func ExampleEC2_AttachClassicLinkVpc() { svc := ec2.New(nil) - params := &ec2.AttachClassicLinkVPCInput{ + params := &ec2.AttachClassicLinkVpcInput{ Groups: []*string{ // Required aws.String("String"), // Required // More values... }, - InstanceID: aws.String("String"), // Required - VPCID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + InstanceId: aws.String("String"), // Required + VpcId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.AttachClassicLinkVPC(params) + resp, err := svc.AttachClassicLinkVpc(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_AttachInternetGateway() { svc := ec2.New(nil) params := &ec2.AttachInternetGatewayInput{ - InternetGatewayID: aws.String("String"), // Required - VPCID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + InternetGatewayId: aws.String("String"), // Required + VpcId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.AttachInternetGateway(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_AttachNetworkInterface() { svc := ec2.New(nil) params := &ec2.AttachNetworkInterfaceInput{ - DeviceIndex: aws.Long(1), // Required - InstanceID: aws.String("String"), // Required - NetworkInterfaceID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + DeviceIndex: aws.Int64(1), // Required + InstanceId: aws.String("String"), // Required + NetworkInterfaceId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.AttachNetworkInterface(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_AttachVPNGateway() { +func ExampleEC2_AttachVolume() { svc := ec2.New(nil) - params := &ec2.AttachVPNGatewayInput{ - VPCID: aws.String("String"), // Required - VPNGatewayID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.AttachVolumeInput{ + Device: aws.String("String"), // Required + InstanceId: aws.String("String"), // Required + VolumeId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.AttachVPNGateway(params) + resp, err := svc.AttachVolume(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_AttachVolume() { +func ExampleEC2_AttachVpnGateway() { svc := ec2.New(nil) - params := &ec2.AttachVolumeInput{ - Device: aws.String("String"), // Required - InstanceID: aws.String("String"), // Required - VolumeID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.AttachVpnGatewayInput{ + VpcId: aws.String("String"), // Required + VpnGatewayId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.AttachVolume(params) + resp, err := svc.AttachVpnGateway(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_AuthorizeSecurityGroupEgress() { svc := ec2.New(nil) params := &ec2.AuthorizeSecurityGroupEgressInput{ - GroupID: aws.String("String"), // Required - CIDRIP: aws.String("String"), - DryRun: aws.Boolean(true), - FromPort: aws.Long(1), - IPPermissions: []*ec2.IPPermission{ - &ec2.IPPermission{ // Required - FromPort: aws.Long(1), - IPProtocol: aws.String("String"), - IPRanges: []*ec2.IPRange{ - &ec2.IPRange{ // Required - CIDRIP: aws.String("String"), + GroupId: aws.String("String"), // Required + CidrIp: aws.String("String"), + DryRun: aws.Bool(true), + FromPort: aws.Int64(1), + IpPermissions: []*ec2.IpPermission{ + { // Required + FromPort: aws.Int64(1), + IpProtocol: aws.String("String"), + IpRanges: []*ec2.IpRange{ + { // Required + CidrIp: aws.String("String"), }, // More values... }, - PrefixListIDs: []*ec2.PrefixListID{ - &ec2.PrefixListID{ // Required - PrefixListID: aws.String("String"), + PrefixListIds: []*ec2.PrefixListId{ + { // Required + PrefixListId: aws.String("String"), }, // More values... }, - ToPort: aws.Long(1), - UserIDGroupPairs: []*ec2.UserIDGroupPair{ - &ec2.UserIDGroupPair{ // Required - GroupID: aws.String("String"), + ToPort: aws.Int64(1), + UserIdGroupPairs: []*ec2.UserIdGroupPair{ + { // Required + GroupId: aws.String("String"), GroupName: aws.String("String"), - UserID: aws.String("String"), + UserId: aws.String("String"), }, // More values... }, }, // More values... }, - IPProtocol: aws.String("String"), + IpProtocol: aws.String("String"), SourceSecurityGroupName: aws.String("String"), - SourceSecurityGroupOwnerID: aws.String("String"), - ToPort: aws.Long(1), + SourceSecurityGroupOwnerId: aws.String("String"), + ToPort: aws.Int64(1), } resp, err := svc.AuthorizeSecurityGroupEgress(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_AuthorizeSecurityGroupIngress() { svc := ec2.New(nil) params := &ec2.AuthorizeSecurityGroupIngressInput{ - CIDRIP: aws.String("String"), - DryRun: aws.Boolean(true), - FromPort: aws.Long(1), - GroupID: aws.String("String"), + CidrIp: aws.String("String"), + DryRun: aws.Bool(true), + FromPort: aws.Int64(1), + GroupId: aws.String("String"), GroupName: aws.String("String"), - IPPermissions: []*ec2.IPPermission{ - &ec2.IPPermission{ // Required - FromPort: aws.Long(1), - IPProtocol: aws.String("String"), - IPRanges: []*ec2.IPRange{ - &ec2.IPRange{ // Required - CIDRIP: aws.String("String"), + IpPermissions: []*ec2.IpPermission{ + { // Required + FromPort: aws.Int64(1), + IpProtocol: aws.String("String"), + IpRanges: []*ec2.IpRange{ + { // Required + CidrIp: aws.String("String"), }, // More values... }, - PrefixListIDs: []*ec2.PrefixListID{ - &ec2.PrefixListID{ // Required - PrefixListID: aws.String("String"), + PrefixListIds: []*ec2.PrefixListId{ + { // Required + PrefixListId: aws.String("String"), }, // More values... }, - ToPort: aws.Long(1), - UserIDGroupPairs: []*ec2.UserIDGroupPair{ - &ec2.UserIDGroupPair{ // Required - GroupID: aws.String("String"), + ToPort: aws.Int64(1), + UserIdGroupPairs: []*ec2.UserIdGroupPair{ + { // Required + GroupId: aws.String("String"), GroupName: aws.String("String"), - UserID: aws.String("String"), + UserId: aws.String("String"), }, // More values... }, }, // More values... }, - IPProtocol: aws.String("String"), + IpProtocol: aws.String("String"), SourceSecurityGroupName: aws.String("String"), - SourceSecurityGroupOwnerID: aws.String("String"), - ToPort: aws.Long(1), + SourceSecurityGroupOwnerId: aws.String("String"), + ToPort: aws.Int64(1), } resp, err := svc.AuthorizeSecurityGroupIngress(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_BundleInstance() { svc := ec2.New(nil) params := &ec2.BundleInstanceInput{ - InstanceID: aws.String("String"), // Required + InstanceId: aws.String("String"), // Required Storage: &ec2.Storage{ // Required S3: &ec2.S3Storage{ - AWSAccessKeyID: aws.String("String"), + AWSAccessKeyId: aws.String("String"), Bucket: aws.String("String"), Prefix: aws.String("String"), UploadPolicy: []byte("PAYLOAD"), UploadPolicySignature: aws.String("String"), }, }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.BundleInstance(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CancelBundleTask() { svc := ec2.New(nil) params := &ec2.CancelBundleTaskInput{ - BundleID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + BundleId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.CancelBundleTask(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CancelConversionTask() { svc := ec2.New(nil) params := &ec2.CancelConversionTaskInput{ - ConversionTaskID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + ConversionTaskId: aws.String("String"), // Required + DryRun: aws.Bool(true), ReasonMessage: aws.String("String"), } resp, err := svc.CancelConversionTask(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CancelExportTask() { svc := ec2.New(nil) params := &ec2.CancelExportTaskInput{ - ExportTaskID: aws.String("String"), // Required + ExportTaskId: aws.String("String"), // Required } resp, err := svc.CancelExportTask(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CancelImportTask() { @@ -598,147 +460,107 @@ func ExampleEC2_CancelImportTask() { params := &ec2.CancelImportTaskInput{ CancelReason: aws.String("String"), - DryRun: aws.Boolean(true), - ImportTaskID: aws.String("String"), + DryRun: aws.Bool(true), + ImportTaskId: aws.String("String"), } resp, err := svc.CancelImportTask(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CancelReservedInstancesListing() { svc := ec2.New(nil) params := &ec2.CancelReservedInstancesListingInput{ - ReservedInstancesListingID: aws.String("String"), // Required + ReservedInstancesListingId: aws.String("String"), // Required } resp, err := svc.CancelReservedInstancesListing(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CancelSpotFleetRequests() { svc := ec2.New(nil) params := &ec2.CancelSpotFleetRequestsInput{ - SpotFleetRequestIDs: []*string{ // Required + SpotFleetRequestIds: []*string{ // Required aws.String("String"), // Required // More values... }, - TerminateInstances: aws.Boolean(true), // Required - DryRun: aws.Boolean(true), + TerminateInstances: aws.Bool(true), // Required + DryRun: aws.Bool(true), } resp, err := svc.CancelSpotFleetRequests(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CancelSpotInstanceRequests() { svc := ec2.New(nil) params := &ec2.CancelSpotInstanceRequestsInput{ - SpotInstanceRequestIDs: []*string{ // Required + SpotInstanceRequestIds: []*string{ // Required aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.CancelSpotInstanceRequests(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ConfirmProductInstance() { svc := ec2.New(nil) params := &ec2.ConfirmProductInstanceInput{ - InstanceID: aws.String("String"), // Required + InstanceId: aws.String("String"), // Required ProductCode: aws.String("String"), // Required - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.ConfirmProductInstance(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CopyImage() { @@ -746,31 +568,23 @@ func ExampleEC2_CopyImage() { params := &ec2.CopyImageInput{ Name: aws.String("String"), // Required - SourceImageID: aws.String("String"), // Required + SourceImageId: aws.String("String"), // Required SourceRegion: aws.String("String"), // Required ClientToken: aws.String("String"), Description: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.CopyImage(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CopySnapshot() { @@ -778,69 +592,55 @@ func ExampleEC2_CopySnapshot() { params := &ec2.CopySnapshotInput{ SourceRegion: aws.String("String"), // Required - SourceSnapshotID: aws.String("String"), // Required + SourceSnapshotId: aws.String("String"), // Required Description: aws.String("String"), DestinationRegion: aws.String("String"), - DryRun: aws.Boolean(true), - PresignedURL: aws.String("String"), + DryRun: aws.Bool(true), + Encrypted: aws.Bool(true), + KmsKeyId: aws.String("String"), + PresignedUrl: aws.String("String"), } resp, err := svc.CopySnapshot(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateCustomerGateway() { svc := ec2.New(nil) params := &ec2.CreateCustomerGatewayInput{ - BGPASN: aws.Long(1), // Required - PublicIP: aws.String("String"), // Required + BgpAsn: aws.Int64(1), // Required + PublicIp: aws.String("String"), // Required Type: aws.String("GatewayType"), // Required - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.CreateCustomerGateway(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_CreateDHCPOptions() { +func ExampleEC2_CreateDhcpOptions() { svc := ec2.New(nil) - params := &ec2.CreateDHCPOptionsInput{ - DHCPConfigurations: []*ec2.NewDHCPConfiguration{ // Required - &ec2.NewDHCPConfiguration{ // Required + params := &ec2.CreateDhcpOptionsInput{ + DhcpConfigurations: []*ec2.NewDhcpConfiguration{ // Required + { // Required Key: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -849,44 +649,63 @@ func ExampleEC2_CreateDHCPOptions() { }, // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), + } + resp, err := svc.CreateDhcpOptions(params) + + if err != nil { + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return + } + + // Pretty-print the response data. + fmt.Println(resp) +} + +func ExampleEC2_CreateFlowLogs() { + svc := ec2.New(nil) + + params := &ec2.CreateFlowLogsInput{ + DeliverLogsPermissionArn: aws.String("String"), // Required + LogGroupName: aws.String("String"), // Required + ResourceIds: []*string{ // Required + aws.String("String"), // Required + // More values... + }, + ResourceType: aws.String("FlowLogsResourceType"), // Required + TrafficType: aws.String("TrafficType"), // Required + ClientToken: aws.String("String"), } - resp, err := svc.CreateDHCPOptions(params) + resp, err := svc.CreateFlowLogs(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateImage() { svc := ec2.New(nil) params := &ec2.CreateImageInput{ - InstanceID: aws.String("String"), // Required + InstanceId: aws.String("String"), // Required Name: aws.String("String"), // Required BlockDeviceMappings: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ // Required + { // Required DeviceName: aws.String("String"), - EBS: &ec2.EBSBlockDevice{ - DeleteOnTermination: aws.Boolean(true), - Encrypted: aws.Boolean(true), - IOPS: aws.Long(1), - SnapshotID: aws.String("String"), - VolumeSize: aws.Long(1), + Ebs: &ec2.EbsBlockDevice{ + DeleteOnTermination: aws.Bool(true), + Encrypted: aws.Bool(true), + Iops: aws.Int64(1), + SnapshotId: aws.String("String"), + VolumeSize: aws.Int64(1), VolumeType: aws.String("VolumeType"), }, NoDevice: aws.String("String"), @@ -895,35 +714,27 @@ func ExampleEC2_CreateImage() { // More values... }, Description: aws.String("String"), - DryRun: aws.Boolean(true), - NoReboot: aws.Boolean(true), + DryRun: aws.Bool(true), + NoReboot: aws.Bool(true), } resp, err := svc.CreateImage(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateInstanceExportTask() { svc := ec2.New(nil) params := &ec2.CreateInstanceExportTaskInput{ - InstanceID: aws.String("String"), // Required + InstanceId: aws.String("String"), // Required Description: aws.String("String"), ExportToS3Task: &ec2.ExportToS3TaskSpecification{ ContainerFormat: aws.String("ContainerFormat"), @@ -936,49 +747,33 @@ func ExampleEC2_CreateInstanceExportTask() { resp, err := svc.CreateInstanceExportTask(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateInternetGateway() { svc := ec2.New(nil) params := &ec2.CreateInternetGatewayInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.CreateInternetGateway(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateKeyPair() { @@ -986,138 +781,106 @@ func ExampleEC2_CreateKeyPair() { params := &ec2.CreateKeyPairInput{ KeyName: aws.String("String"), // Required - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.CreateKeyPair(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_CreateNetworkACL() { +func ExampleEC2_CreateNetworkAcl() { svc := ec2.New(nil) - params := &ec2.CreateNetworkACLInput{ - VPCID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.CreateNetworkAclInput{ + VpcId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.CreateNetworkACL(params) + resp, err := svc.CreateNetworkAcl(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_CreateNetworkACLEntry() { +func ExampleEC2_CreateNetworkAclEntry() { svc := ec2.New(nil) - params := &ec2.CreateNetworkACLEntryInput{ - CIDRBlock: aws.String("String"), // Required - Egress: aws.Boolean(true), // Required - NetworkACLID: aws.String("String"), // Required + params := &ec2.CreateNetworkAclEntryInput{ + CidrBlock: aws.String("String"), // Required + Egress: aws.Bool(true), // Required + NetworkAclId: aws.String("String"), // Required Protocol: aws.String("String"), // Required RuleAction: aws.String("RuleAction"), // Required - RuleNumber: aws.Long(1), // Required - DryRun: aws.Boolean(true), - ICMPTypeCode: &ec2.ICMPTypeCode{ - Code: aws.Long(1), - Type: aws.Long(1), + RuleNumber: aws.Int64(1), // Required + DryRun: aws.Bool(true), + IcmpTypeCode: &ec2.IcmpTypeCode{ + Code: aws.Int64(1), + Type: aws.Int64(1), }, PortRange: &ec2.PortRange{ - From: aws.Long(1), - To: aws.Long(1), + From: aws.Int64(1), + To: aws.Int64(1), }, } - resp, err := svc.CreateNetworkACLEntry(params) + resp, err := svc.CreateNetworkAclEntry(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateNetworkInterface() { svc := ec2.New(nil) params := &ec2.CreateNetworkInterfaceInput{ - SubnetID: aws.String("String"), // Required + SubnetId: aws.String("String"), // Required Description: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Groups: []*string{ aws.String("String"), // Required // More values... }, - PrivateIPAddress: aws.String("String"), - PrivateIPAddresses: []*ec2.PrivateIPAddressSpecification{ - &ec2.PrivateIPAddressSpecification{ // Required - PrivateIPAddress: aws.String("String"), // Required - Primary: aws.Boolean(true), + PrivateIpAddress: aws.String("String"), + PrivateIpAddresses: []*ec2.PrivateIpAddressSpecification{ + { // Required + PrivateIpAddress: aws.String("String"), // Required + Primary: aws.Bool(true), }, // More values... }, - SecondaryPrivateIPAddressCount: aws.Long(1), + SecondaryPrivateIpAddressCount: aws.Int64(1), } resp, err := svc.CreateNetworkInterface(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreatePlacementGroup() { @@ -1126,27 +889,19 @@ func ExampleEC2_CreatePlacementGroup() { params := &ec2.CreatePlacementGroupInput{ GroupName: aws.String("String"), // Required Strategy: aws.String("PlacementStrategy"), // Required - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.CreatePlacementGroup(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateReservedInstancesListing() { @@ -1154,98 +909,73 @@ func ExampleEC2_CreateReservedInstancesListing() { params := &ec2.CreateReservedInstancesListingInput{ ClientToken: aws.String("String"), // Required - InstanceCount: aws.Long(1), // Required + InstanceCount: aws.Int64(1), // Required PriceSchedules: []*ec2.PriceScheduleSpecification{ // Required - &ec2.PriceScheduleSpecification{ // Required + { // Required CurrencyCode: aws.String("CurrencyCodeValues"), - Price: aws.Double(1.0), - Term: aws.Long(1), + Price: aws.Float64(1.0), + Term: aws.Int64(1), }, // More values... }, - ReservedInstancesID: aws.String("String"), // Required + ReservedInstancesId: aws.String("String"), // Required } resp, err := svc.CreateReservedInstancesListing(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateRoute() { svc := ec2.New(nil) params := &ec2.CreateRouteInput{ - DestinationCIDRBlock: aws.String("String"), // Required - RouteTableID: aws.String("String"), // Required - ClientToken: aws.String("String"), - DryRun: aws.Boolean(true), - GatewayID: aws.String("String"), - InstanceID: aws.String("String"), - NetworkInterfaceID: aws.String("String"), - VPCPeeringConnectionID: aws.String("String"), + DestinationCidrBlock: aws.String("String"), // Required + RouteTableId: aws.String("String"), // Required + DryRun: aws.Bool(true), + GatewayId: aws.String("String"), + InstanceId: aws.String("String"), + NetworkInterfaceId: aws.String("String"), + VpcPeeringConnectionId: aws.String("String"), } resp, err := svc.CreateRoute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateRouteTable() { svc := ec2.New(nil) params := &ec2.CreateRouteTableInput{ - VPCID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + VpcId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.CreateRouteTable(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateSecurityGroup() { @@ -1254,57 +984,41 @@ func ExampleEC2_CreateSecurityGroup() { params := &ec2.CreateSecurityGroupInput{ Description: aws.String("String"), // Required GroupName: aws.String("String"), // Required - DryRun: aws.Boolean(true), - VPCID: aws.String("String"), + DryRun: aws.Bool(true), + VpcId: aws.String("String"), } resp, err := svc.CreateSecurityGroup(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateSnapshot() { svc := ec2.New(nil) params := &ec2.CreateSnapshotInput{ - VolumeID: aws.String("String"), // Required + VolumeId: aws.String("String"), // Required Description: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.CreateSnapshot(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateSpotDatafeedSubscription() { @@ -1312,58 +1026,42 @@ func ExampleEC2_CreateSpotDatafeedSubscription() { params := &ec2.CreateSpotDatafeedSubscriptionInput{ Bucket: aws.String("String"), // Required - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Prefix: aws.String("String"), } resp, err := svc.CreateSpotDatafeedSubscription(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateSubnet() { svc := ec2.New(nil) params := &ec2.CreateSubnetInput{ - CIDRBlock: aws.String("String"), // Required - VPCID: aws.String("String"), // Required + CidrBlock: aws.String("String"), // Required + VpcId: aws.String("String"), // Required AvailabilityZone: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.CreateSubnet(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_CreateTags() { @@ -1375,335 +1073,269 @@ func ExampleEC2_CreateTags() { // More values... }, Tags: []*ec2.Tag{ // Required - &ec2.Tag{ // Required + { // Required Key: aws.String("String"), Value: aws.String("String"), }, // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.CreateTags(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return + } + + // Pretty-print the response data. + fmt.Println(resp) +} + +func ExampleEC2_CreateVolume() { + svc := ec2.New(nil) + + params := &ec2.CreateVolumeInput{ + AvailabilityZone: aws.String("String"), // Required + DryRun: aws.Bool(true), + Encrypted: aws.Bool(true), + Iops: aws.Int64(1), + KmsKeyId: aws.String("String"), + Size: aws.Int64(1), + SnapshotId: aws.String("String"), + VolumeType: aws.String("VolumeType"), + } + resp, err := svc.CreateVolume(params) + + if err != nil { + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_CreateVPC() { +func ExampleEC2_CreateVpc() { svc := ec2.New(nil) - params := &ec2.CreateVPCInput{ - CIDRBlock: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.CreateVpcInput{ + CidrBlock: aws.String("String"), // Required + DryRun: aws.Bool(true), InstanceTenancy: aws.String("Tenancy"), } - resp, err := svc.CreateVPC(params) + resp, err := svc.CreateVpc(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_CreateVPCEndpoint() { +func ExampleEC2_CreateVpcEndpoint() { svc := ec2.New(nil) - params := &ec2.CreateVPCEndpointInput{ + params := &ec2.CreateVpcEndpointInput{ ServiceName: aws.String("String"), // Required - VPCID: aws.String("String"), // Required + VpcId: aws.String("String"), // Required ClientToken: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), PolicyDocument: aws.String("String"), - RouteTableIDs: []*string{ + RouteTableIds: []*string{ aws.String("String"), // Required // More values... }, } - resp, err := svc.CreateVPCEndpoint(params) + resp, err := svc.CreateVpcEndpoint(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_CreateVPCPeeringConnection() { +func ExampleEC2_CreateVpcPeeringConnection() { svc := ec2.New(nil) - params := &ec2.CreateVPCPeeringConnectionInput{ - DryRun: aws.Boolean(true), - PeerOwnerID: aws.String("String"), - PeerVPCID: aws.String("String"), - VPCID: aws.String("String"), + params := &ec2.CreateVpcPeeringConnectionInput{ + DryRun: aws.Bool(true), + PeerOwnerId: aws.String("String"), + PeerVpcId: aws.String("String"), + VpcId: aws.String("String"), } - resp, err := svc.CreateVPCPeeringConnection(params) + resp, err := svc.CreateVpcPeeringConnection(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_CreateVPNConnection() { +func ExampleEC2_CreateVpnConnection() { svc := ec2.New(nil) - params := &ec2.CreateVPNConnectionInput{ - CustomerGatewayID: aws.String("String"), // Required + params := &ec2.CreateVpnConnectionInput{ + CustomerGatewayId: aws.String("String"), // Required Type: aws.String("String"), // Required - VPNGatewayID: aws.String("String"), // Required - DryRun: aws.Boolean(true), - Options: &ec2.VPNConnectionOptionsSpecification{ - StaticRoutesOnly: aws.Boolean(true), + VpnGatewayId: aws.String("String"), // Required + DryRun: aws.Bool(true), + Options: &ec2.VpnConnectionOptionsSpecification{ + StaticRoutesOnly: aws.Bool(true), }, } - resp, err := svc.CreateVPNConnection(params) + resp, err := svc.CreateVpnConnection(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_CreateVPNConnectionRoute() { +func ExampleEC2_CreateVpnConnectionRoute() { svc := ec2.New(nil) - params := &ec2.CreateVPNConnectionRouteInput{ - DestinationCIDRBlock: aws.String("String"), // Required - VPNConnectionID: aws.String("String"), // Required + params := &ec2.CreateVpnConnectionRouteInput{ + DestinationCidrBlock: aws.String("String"), // Required + VpnConnectionId: aws.String("String"), // Required } - resp, err := svc.CreateVPNConnectionRoute(params) + resp, err := svc.CreateVpnConnectionRoute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_CreateVPNGateway() { +func ExampleEC2_CreateVpnGateway() { svc := ec2.New(nil) - params := &ec2.CreateVPNGatewayInput{ + params := &ec2.CreateVpnGatewayInput{ Type: aws.String("GatewayType"), // Required AvailabilityZone: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } - resp, err := svc.CreateVPNGateway(params) + resp, err := svc.CreateVpnGateway(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_CreateVolume() { +func ExampleEC2_DeleteCustomerGateway() { svc := ec2.New(nil) - params := &ec2.CreateVolumeInput{ - AvailabilityZone: aws.String("String"), // Required - DryRun: aws.Boolean(true), - Encrypted: aws.Boolean(true), - IOPS: aws.Long(1), - KMSKeyID: aws.String("String"), - Size: aws.Long(1), - SnapshotID: aws.String("String"), - VolumeType: aws.String("VolumeType"), + params := &ec2.DeleteCustomerGatewayInput{ + CustomerGatewayId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.CreateVolume(params) + resp, err := svc.DeleteCustomerGateway(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DeleteCustomerGateway() { +func ExampleEC2_DeleteDhcpOptions() { svc := ec2.New(nil) - params := &ec2.DeleteCustomerGatewayInput{ - CustomerGatewayID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.DeleteDhcpOptionsInput{ + DhcpOptionsId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.DeleteCustomerGateway(params) + resp, err := svc.DeleteDhcpOptions(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DeleteDHCPOptions() { +func ExampleEC2_DeleteFlowLogs() { svc := ec2.New(nil) - params := &ec2.DeleteDHCPOptionsInput{ - DHCPOptionsID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.DeleteFlowLogsInput{ + FlowLogIds: []*string{ // Required + aws.String("String"), // Required + // More values... + }, } - resp, err := svc.DeleteDHCPOptions(params) + resp, err := svc.DeleteFlowLogs(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeleteInternetGateway() { svc := ec2.New(nil) params := &ec2.DeleteInternetGatewayInput{ - InternetGatewayID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + InternetGatewayId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DeleteInternetGateway(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeleteKeyPair() { @@ -1711,113 +1343,81 @@ func ExampleEC2_DeleteKeyPair() { params := &ec2.DeleteKeyPairInput{ KeyName: aws.String("String"), // Required - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.DeleteKeyPair(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DeleteNetworkACL() { +func ExampleEC2_DeleteNetworkAcl() { svc := ec2.New(nil) - params := &ec2.DeleteNetworkACLInput{ - NetworkACLID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.DeleteNetworkAclInput{ + NetworkAclId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.DeleteNetworkACL(params) + resp, err := svc.DeleteNetworkAcl(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DeleteNetworkACLEntry() { +func ExampleEC2_DeleteNetworkAclEntry() { svc := ec2.New(nil) - params := &ec2.DeleteNetworkACLEntryInput{ - Egress: aws.Boolean(true), // Required - NetworkACLID: aws.String("String"), // Required - RuleNumber: aws.Long(1), // Required - DryRun: aws.Boolean(true), + params := &ec2.DeleteNetworkAclEntryInput{ + Egress: aws.Bool(true), // Required + NetworkAclId: aws.String("String"), // Required + RuleNumber: aws.Int64(1), // Required + DryRun: aws.Bool(true), } - resp, err := svc.DeleteNetworkACLEntry(params) + resp, err := svc.DeleteNetworkAclEntry(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeleteNetworkInterface() { svc := ec2.New(nil) params := &ec2.DeleteNetworkInterfaceInput{ - NetworkInterfaceID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + NetworkInterfaceId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DeleteNetworkInterface(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeletePlacementGroup() { @@ -1825,196 +1425,140 @@ func ExampleEC2_DeletePlacementGroup() { params := &ec2.DeletePlacementGroupInput{ GroupName: aws.String("String"), // Required - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.DeletePlacementGroup(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeleteRoute() { svc := ec2.New(nil) params := &ec2.DeleteRouteInput{ - DestinationCIDRBlock: aws.String("String"), // Required - RouteTableID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + DestinationCidrBlock: aws.String("String"), // Required + RouteTableId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DeleteRoute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeleteRouteTable() { svc := ec2.New(nil) params := &ec2.DeleteRouteTableInput{ - RouteTableID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + RouteTableId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DeleteRouteTable(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeleteSecurityGroup() { svc := ec2.New(nil) params := &ec2.DeleteSecurityGroupInput{ - DryRun: aws.Boolean(true), - GroupID: aws.String("String"), + DryRun: aws.Bool(true), + GroupId: aws.String("String"), GroupName: aws.String("String"), } resp, err := svc.DeleteSecurityGroup(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeleteSnapshot() { svc := ec2.New(nil) params := &ec2.DeleteSnapshotInput{ - SnapshotID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + SnapshotId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DeleteSnapshot(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeleteSpotDatafeedSubscription() { svc := ec2.New(nil) params := &ec2.DeleteSpotDatafeedSubscriptionInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.DeleteSpotDatafeedSubscription(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeleteSubnet() { svc := ec2.New(nil) params := &ec2.DeleteSubnetInput{ - SubnetID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + SubnetId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DeleteSubnet(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeleteTags() { @@ -2025,9 +1569,9 @@ func ExampleEC2_DeleteTags() { aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Tags: []*ec2.Tag{ - &ec2.Tag{ // Required + { // Required Key: aws.String("String"), Value: aws.String("String"), }, @@ -2037,249 +1581,177 @@ func ExampleEC2_DeleteTags() { resp, err := svc.DeleteTags(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DeleteVPC() { +func ExampleEC2_DeleteVolume() { svc := ec2.New(nil) - params := &ec2.DeleteVPCInput{ - VPCID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.DeleteVolumeInput{ + VolumeId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.DeleteVPC(params) + resp, err := svc.DeleteVolume(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DeleteVPCEndpoints() { +func ExampleEC2_DeleteVpc() { svc := ec2.New(nil) - params := &ec2.DeleteVPCEndpointsInput{ - VPCEndpointIDs: []*string{ // Required - aws.String("String"), // Required - // More values... - }, - DryRun: aws.Boolean(true), + params := &ec2.DeleteVpcInput{ + VpcId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.DeleteVPCEndpoints(params) + resp, err := svc.DeleteVpc(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DeleteVPCPeeringConnection() { +func ExampleEC2_DeleteVpcEndpoints() { svc := ec2.New(nil) - params := &ec2.DeleteVPCPeeringConnectionInput{ - VPCPeeringConnectionID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.DeleteVpcEndpointsInput{ + VpcEndpointIds: []*string{ // Required + aws.String("String"), // Required + // More values... + }, + DryRun: aws.Bool(true), } - resp, err := svc.DeleteVPCPeeringConnection(params) + resp, err := svc.DeleteVpcEndpoints(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DeleteVPNConnection() { +func ExampleEC2_DeleteVpcPeeringConnection() { svc := ec2.New(nil) - params := &ec2.DeleteVPNConnectionInput{ - VPNConnectionID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.DeleteVpcPeeringConnectionInput{ + VpcPeeringConnectionId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.DeleteVPNConnection(params) + resp, err := svc.DeleteVpcPeeringConnection(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DeleteVPNConnectionRoute() { +func ExampleEC2_DeleteVpnConnection() { svc := ec2.New(nil) - params := &ec2.DeleteVPNConnectionRouteInput{ - DestinationCIDRBlock: aws.String("String"), // Required - VPNConnectionID: aws.String("String"), // Required + params := &ec2.DeleteVpnConnectionInput{ + VpnConnectionId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.DeleteVPNConnectionRoute(params) + resp, err := svc.DeleteVpnConnection(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DeleteVPNGateway() { +func ExampleEC2_DeleteVpnConnectionRoute() { svc := ec2.New(nil) - params := &ec2.DeleteVPNGatewayInput{ - VPNGatewayID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.DeleteVpnConnectionRouteInput{ + DestinationCidrBlock: aws.String("String"), // Required + VpnConnectionId: aws.String("String"), // Required } - resp, err := svc.DeleteVPNGateway(params) + resp, err := svc.DeleteVpnConnectionRoute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DeleteVolume() { +func ExampleEC2_DeleteVpnGateway() { svc := ec2.New(nil) - params := &ec2.DeleteVolumeInput{ - VolumeID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.DeleteVpnGatewayInput{ + VpnGatewayId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.DeleteVolume(params) + resp, err := svc.DeleteVpnGateway(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DeregisterImage() { svc := ec2.New(nil) params := &ec2.DeregisterImageInput{ - ImageID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + ImageId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DeregisterImage(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeAccountAttributes() { @@ -2290,40 +1762,32 @@ func ExampleEC2_DescribeAccountAttributes() { aws.String("AccountAttributeName"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.DescribeAccountAttributes(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeAddresses() { svc := ec2.New(nil) params := &ec2.DescribeAddressesInput{ - AllocationIDs: []*string{ + AllocationIds: []*string{ aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2332,7 +1796,7 @@ func ExampleEC2_DescribeAddresses() { }, // More values... }, - PublicIPs: []*string{ + PublicIps: []*string{ aws.String("String"), // Required // More values... }, @@ -2340,31 +1804,23 @@ func ExampleEC2_DescribeAddresses() { resp, err := svc.DescribeAddresses(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeAvailabilityZones() { svc := ec2.New(nil) params := &ec2.DescribeAvailabilityZonesInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2381,35 +1837,27 @@ func ExampleEC2_DescribeAvailabilityZones() { resp, err := svc.DescribeAvailabilityZones(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeBundleTasks() { svc := ec2.New(nil) params := &ec2.DescribeBundleTasksInput{ - BundleIDs: []*string{ + BundleIds: []*string{ aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2422,31 +1870,23 @@ func ExampleEC2_DescribeBundleTasks() { resp, err := svc.DescribeBundleTasks(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeClassicLinkInstances() { svc := ec2.New(nil) params := &ec2.DescribeClassicLinkInstancesInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2455,45 +1895,37 @@ func ExampleEC2_DescribeClassicLinkInstances() { }, // More values... }, - InstanceIDs: []*string{ + InstanceIds: []*string{ aws.String("String"), // Required // More values... }, - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), } resp, err := svc.DescribeClassicLinkInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeConversionTasks() { svc := ec2.New(nil) params := &ec2.DescribeConversionTasksInput{ - ConversionTaskIDs: []*string{ + ConversionTaskIds: []*string{ aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2506,35 +1938,27 @@ func ExampleEC2_DescribeConversionTasks() { resp, err := svc.DescribeConversionTasks(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeCustomerGateways() { svc := ec2.New(nil) params := &ec2.DescribeCustomerGatewaysInput{ - CustomerGatewayIDs: []*string{ + CustomerGatewayIds: []*string{ aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2547,35 +1971,27 @@ func ExampleEC2_DescribeCustomerGateways() { resp, err := svc.DescribeCustomerGateways(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DescribeDHCPOptions() { +func ExampleEC2_DescribeDhcpOptions() { svc := ec2.New(nil) - params := &ec2.DescribeDHCPOptionsInput{ - DHCPOptionsIDs: []*string{ + params := &ec2.DescribeDhcpOptionsInput{ + DhcpOptionsIds: []*string{ aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2585,32 +2001,24 @@ func ExampleEC2_DescribeDHCPOptions() { // More values... }, } - resp, err := svc.DescribeDHCPOptions(params) + resp, err := svc.DescribeDhcpOptions(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeExportTasks() { svc := ec2.New(nil) params := &ec2.DescribeExportTasksInput{ - ExportTaskIDs: []*string{ + ExportTaskIds: []*string{ aws.String("String"), // Required // More values... }, @@ -2618,22 +2026,48 @@ func ExampleEC2_DescribeExportTasks() { resp, err := svc.DescribeExportTasks(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) +} + +func ExampleEC2_DescribeFlowLogs() { + svc := ec2.New(nil) + + params := &ec2.DescribeFlowLogsInput{ + Filter: []*ec2.Filter{ + { // Required + Name: aws.String("String"), + Values: []*string{ + aws.String("String"), // Required + // More values... + }, + }, + // More values... + }, + FlowLogIds: []*string{ + aws.String("String"), // Required + // More values... + }, + MaxResults: aws.Int64(1), + NextToken: aws.String("String"), + } + resp, err := svc.DescribeFlowLogs(params) + + if err != nil { + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return + } + + // Pretty-print the response data. + fmt.Println(resp) } func ExampleEC2_DescribeImageAttribute() { @@ -2641,41 +2075,33 @@ func ExampleEC2_DescribeImageAttribute() { params := &ec2.DescribeImageAttributeInput{ Attribute: aws.String("ImageAttributeName"), // Required - ImageID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + ImageId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DescribeImageAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeImages() { svc := ec2.New(nil) params := &ec2.DescribeImagesInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), ExecutableUsers: []*string{ aws.String("String"), // Required // More values... }, Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2684,7 +2110,7 @@ func ExampleEC2_DescribeImages() { }, // More values... }, - ImageIDs: []*string{ + ImageIds: []*string{ aws.String("String"), // Required // More values... }, @@ -2696,31 +2122,23 @@ func ExampleEC2_DescribeImages() { resp, err := svc.DescribeImages(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeImportImageTasks() { svc := ec2.New(nil) params := &ec2.DescribeImportImageTasksInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2729,41 +2147,33 @@ func ExampleEC2_DescribeImportImageTasks() { }, // More values... }, - ImportTaskIDs: []*string{ + ImportTaskIds: []*string{ aws.String("String"), // Required // More values... }, - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), } resp, err := svc.DescribeImportImageTasks(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeImportSnapshotTasks() { svc := ec2.New(nil) params := &ec2.DescribeImportSnapshotTasksInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2772,32 +2182,24 @@ func ExampleEC2_DescribeImportSnapshotTasks() { }, // More values... }, - ImportTaskIDs: []*string{ + ImportTaskIds: []*string{ aws.String("String"), // Required // More values... }, - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), } resp, err := svc.DescribeImportSnapshotTasks(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeInstanceAttribute() { @@ -2805,37 +2207,29 @@ func ExampleEC2_DescribeInstanceAttribute() { params := &ec2.DescribeInstanceAttributeInput{ Attribute: aws.String("InstanceAttributeName"), // Required - InstanceID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + InstanceId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DescribeInstanceAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeInstanceStatus() { svc := ec2.New(nil) params := &ec2.DescribeInstanceStatusInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2844,42 +2238,34 @@ func ExampleEC2_DescribeInstanceStatus() { }, // More values... }, - IncludeAllInstances: aws.Boolean(true), - InstanceIDs: []*string{ + IncludeAllInstances: aws.Bool(true), + InstanceIds: []*string{ aws.String("String"), // Required // More values... }, - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), } resp, err := svc.DescribeInstanceStatus(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeInstances() { svc := ec2.New(nil) params := &ec2.DescribeInstancesInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2888,41 +2274,33 @@ func ExampleEC2_DescribeInstances() { }, // More values... }, - InstanceIDs: []*string{ + InstanceIds: []*string{ aws.String("String"), // Required // More values... }, - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), } resp, err := svc.DescribeInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeInternetGateways() { svc := ec2.New(nil) params := &ec2.DescribeInternetGatewaysInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2931,7 +2309,7 @@ func ExampleEC2_DescribeInternetGateways() { }, // More values... }, - InternetGatewayIDs: []*string{ + InternetGatewayIds: []*string{ aws.String("String"), // Required // More values... }, @@ -2939,31 +2317,23 @@ func ExampleEC2_DescribeInternetGateways() { resp, err := svc.DescribeInternetGateways(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeKeyPairs() { svc := ec2.New(nil) params := &ec2.DescribeKeyPairsInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -2980,31 +2350,23 @@ func ExampleEC2_DescribeKeyPairs() { resp, err := svc.DescribeKeyPairs(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeMovingAddresses() { svc := ec2.New(nil) params := &ec2.DescribeMovingAddressesInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3013,9 +2375,9 @@ func ExampleEC2_DescribeMovingAddresses() { }, // More values... }, - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), - PublicIPs: []*string{ + PublicIps: []*string{ aws.String("String"), // Required // More values... }, @@ -3023,31 +2385,23 @@ func ExampleEC2_DescribeMovingAddresses() { resp, err := svc.DescribeMovingAddresses(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DescribeNetworkACLs() { +func ExampleEC2_DescribeNetworkAcls() { svc := ec2.New(nil) - params := &ec2.DescribeNetworkACLsInput{ - DryRun: aws.Boolean(true), + params := &ec2.DescribeNetworkAclsInput{ + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3056,68 +2410,52 @@ func ExampleEC2_DescribeNetworkACLs() { }, // More values... }, - NetworkACLIDs: []*string{ + NetworkAclIds: []*string{ aws.String("String"), // Required // More values... }, } - resp, err := svc.DescribeNetworkACLs(params) + resp, err := svc.DescribeNetworkAcls(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeNetworkInterfaceAttribute() { svc := ec2.New(nil) params := &ec2.DescribeNetworkInterfaceAttributeInput{ - NetworkInterfaceID: aws.String("String"), // Required + NetworkInterfaceId: aws.String("String"), // Required Attribute: aws.String("NetworkInterfaceAttribute"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.DescribeNetworkInterfaceAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeNetworkInterfaces() { svc := ec2.New(nil) params := &ec2.DescribeNetworkInterfacesInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3126,7 +2464,7 @@ func ExampleEC2_DescribeNetworkInterfaces() { }, // More values... }, - NetworkInterfaceIDs: []*string{ + NetworkInterfaceIds: []*string{ aws.String("String"), // Required // More values... }, @@ -3134,31 +2472,23 @@ func ExampleEC2_DescribeNetworkInterfaces() { resp, err := svc.DescribeNetworkInterfaces(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribePlacementGroups() { svc := ec2.New(nil) params := &ec2.DescribePlacementGroupsInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3175,31 +2505,23 @@ func ExampleEC2_DescribePlacementGroups() { resp, err := svc.DescribePlacementGroups(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribePrefixLists() { svc := ec2.New(nil) params := &ec2.DescribePrefixListsInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3208,9 +2530,9 @@ func ExampleEC2_DescribePrefixLists() { }, // More values... }, - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), - PrefixListIDs: []*string{ + PrefixListIds: []*string{ aws.String("String"), // Required // More values... }, @@ -3218,31 +2540,23 @@ func ExampleEC2_DescribePrefixLists() { resp, err := svc.DescribePrefixLists(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeRegions() { svc := ec2.New(nil) params := &ec2.DescribeRegionsInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3259,31 +2573,23 @@ func ExampleEC2_DescribeRegions() { resp, err := svc.DescribeRegions(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeReservedInstances() { svc := ec2.New(nil) params := &ec2.DescribeReservedInstancesInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3293,7 +2599,7 @@ func ExampleEC2_DescribeReservedInstances() { // More values... }, OfferingType: aws.String("OfferingTypeValues"), - ReservedInstancesIDs: []*string{ + ReservedInstancesIds: []*string{ aws.String("String"), // Required // More values... }, @@ -3301,22 +2607,14 @@ func ExampleEC2_DescribeReservedInstances() { resp, err := svc.DescribeReservedInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeReservedInstancesListings() { @@ -3324,7 +2622,7 @@ func ExampleEC2_DescribeReservedInstancesListings() { params := &ec2.DescribeReservedInstancesListingsInput{ Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3333,28 +2631,20 @@ func ExampleEC2_DescribeReservedInstancesListings() { }, // More values... }, - ReservedInstancesID: aws.String("String"), - ReservedInstancesListingID: aws.String("String"), + ReservedInstancesId: aws.String("String"), + ReservedInstancesListingId: aws.String("String"), } resp, err := svc.DescribeReservedInstancesListings(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeReservedInstancesModifications() { @@ -3362,7 +2652,7 @@ func ExampleEC2_DescribeReservedInstancesModifications() { params := &ec2.DescribeReservedInstancesModificationsInput{ Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3372,7 +2662,7 @@ func ExampleEC2_DescribeReservedInstancesModifications() { // More values... }, NextToken: aws.String("String"), - ReservedInstancesModificationIDs: []*string{ + ReservedInstancesModificationIds: []*string{ aws.String("String"), // Required // More values... }, @@ -3380,22 +2670,14 @@ func ExampleEC2_DescribeReservedInstancesModifications() { resp, err := svc.DescribeReservedInstancesModifications(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeReservedInstancesOfferings() { @@ -3403,9 +2685,9 @@ func ExampleEC2_DescribeReservedInstancesOfferings() { params := &ec2.DescribeReservedInstancesOfferingsInput{ AvailabilityZone: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3414,17 +2696,17 @@ func ExampleEC2_DescribeReservedInstancesOfferings() { }, // More values... }, - IncludeMarketplace: aws.Boolean(true), + IncludeMarketplace: aws.Bool(true), InstanceTenancy: aws.String("Tenancy"), InstanceType: aws.String("InstanceType"), - MaxDuration: aws.Long(1), - MaxInstanceCount: aws.Long(1), - MaxResults: aws.Long(1), - MinDuration: aws.Long(1), + MaxDuration: aws.Int64(1), + MaxInstanceCount: aws.Int64(1), + MaxResults: aws.Int64(1), + MinDuration: aws.Int64(1), NextToken: aws.String("String"), OfferingType: aws.String("OfferingTypeValues"), ProductDescription: aws.String("RIProductDescription"), - ReservedInstancesOfferingIDs: []*string{ + ReservedInstancesOfferingIds: []*string{ aws.String("String"), // Required // More values... }, @@ -3432,31 +2714,23 @@ func ExampleEC2_DescribeReservedInstancesOfferings() { resp, err := svc.DescribeReservedInstancesOfferings(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeRouteTables() { svc := ec2.New(nil) params := &ec2.DescribeRouteTablesInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3465,7 +2739,7 @@ func ExampleEC2_DescribeRouteTables() { }, // More values... }, - RouteTableIDs: []*string{ + RouteTableIds: []*string{ aws.String("String"), // Required // More values... }, @@ -3473,31 +2747,23 @@ func ExampleEC2_DescribeRouteTables() { resp, err := svc.DescribeRouteTables(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeSecurityGroups() { svc := ec2.New(nil) params := &ec2.DescribeSecurityGroupsInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3506,7 +2772,7 @@ func ExampleEC2_DescribeSecurityGroups() { }, // More values... }, - GroupIDs: []*string{ + GroupIds: []*string{ aws.String("String"), // Required // More values... }, @@ -3518,22 +2784,14 @@ func ExampleEC2_DescribeSecurityGroups() { resp, err := svc.DescribeSecurityGroups(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeSnapshotAttribute() { @@ -3541,37 +2799,29 @@ func ExampleEC2_DescribeSnapshotAttribute() { params := &ec2.DescribeSnapshotAttributeInput{ Attribute: aws.String("SnapshotAttributeName"), // Required - SnapshotID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + SnapshotId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DescribeSnapshotAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeSnapshots() { svc := ec2.New(nil) params := &ec2.DescribeSnapshotsInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3580,17 +2830,17 @@ func ExampleEC2_DescribeSnapshots() { }, // More values... }, - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), - OwnerIDs: []*string{ + OwnerIds: []*string{ aws.String("String"), // Required // More values... }, - RestorableByUserIDs: []*string{ + RestorableByUserIds: []*string{ aws.String("String"), // Required // More values... }, - SnapshotIDs: []*string{ + SnapshotIds: []*string{ aws.String("String"), // Required // More values... }, @@ -3598,121 +2848,89 @@ func ExampleEC2_DescribeSnapshots() { resp, err := svc.DescribeSnapshots(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeSpotDatafeedSubscription() { svc := ec2.New(nil) params := &ec2.DescribeSpotDatafeedSubscriptionInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.DescribeSpotDatafeedSubscription(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeSpotFleetInstances() { svc := ec2.New(nil) params := &ec2.DescribeSpotFleetInstancesInput{ - SpotFleetRequestID: aws.String("String"), // Required - DryRun: aws.Boolean(true), - MaxResults: aws.Long(1), + SpotFleetRequestId: aws.String("String"), // Required + DryRun: aws.Bool(true), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), } resp, err := svc.DescribeSpotFleetInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeSpotFleetRequestHistory() { svc := ec2.New(nil) params := &ec2.DescribeSpotFleetRequestHistoryInput{ - SpotFleetRequestID: aws.String("String"), // Required + SpotFleetRequestId: aws.String("String"), // Required StartTime: aws.Time(time.Now()), // Required - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), EventType: aws.String("EventType"), - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), } resp, err := svc.DescribeSpotFleetRequestHistory(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeSpotFleetRequests() { svc := ec2.New(nil) params := &ec2.DescribeSpotFleetRequestsInput{ - DryRun: aws.Boolean(true), - MaxResults: aws.Long(1), + DryRun: aws.Bool(true), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), - SpotFleetRequestIDs: []*string{ + SpotFleetRequestIds: []*string{ aws.String("String"), // Required // More values... }, @@ -3720,31 +2938,23 @@ func ExampleEC2_DescribeSpotFleetRequests() { resp, err := svc.DescribeSpotFleetRequests(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeSpotInstanceRequests() { svc := ec2.New(nil) params := &ec2.DescribeSpotInstanceRequestsInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3753,7 +2963,7 @@ func ExampleEC2_DescribeSpotInstanceRequests() { }, // More values... }, - SpotInstanceRequestIDs: []*string{ + SpotInstanceRequestIds: []*string{ aws.String("String"), // Required // More values... }, @@ -3761,22 +2971,14 @@ func ExampleEC2_DescribeSpotInstanceRequests() { resp, err := svc.DescribeSpotInstanceRequests(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeSpotPriceHistory() { @@ -3784,10 +2986,10 @@ func ExampleEC2_DescribeSpotPriceHistory() { params := &ec2.DescribeSpotPriceHistoryInput{ AvailabilityZone: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), EndTime: aws.Time(time.Now()), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3800,7 +3002,7 @@ func ExampleEC2_DescribeSpotPriceHistory() { aws.String("InstanceType"), // Required // More values... }, - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), ProductDescriptions: []*string{ aws.String("String"), // Required @@ -3811,31 +3013,23 @@ func ExampleEC2_DescribeSpotPriceHistory() { resp, err := svc.DescribeSpotPriceHistory(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeSubnets() { svc := ec2.New(nil) params := &ec2.DescribeSubnetsInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3844,7 +3038,7 @@ func ExampleEC2_DescribeSubnets() { }, // More values... }, - SubnetIDs: []*string{ + SubnetIds: []*string{ aws.String("String"), // Required // More values... }, @@ -3852,31 +3046,23 @@ func ExampleEC2_DescribeSubnets() { resp, err := svc.DescribeSubnets(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DescribeTags() { svc := ec2.New(nil) params := &ec2.DescribeTagsInput{ - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3885,66 +3071,50 @@ func ExampleEC2_DescribeTags() { }, // More values... }, - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), } resp, err := svc.DescribeTags(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DescribeVPCAttribute() { +func ExampleEC2_DescribeVolumeAttribute() { svc := ec2.New(nil) - params := &ec2.DescribeVPCAttributeInput{ - VPCID: aws.String("String"), // Required - Attribute: aws.String("VpcAttributeName"), - DryRun: aws.Boolean(true), + params := &ec2.DescribeVolumeAttributeInput{ + VolumeId: aws.String("String"), // Required + Attribute: aws.String("VolumeAttributeName"), + DryRun: aws.Bool(true), } - resp, err := svc.DescribeVPCAttribute(params) + resp, err := svc.DescribeVolumeAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DescribeVPCClassicLink() { +func ExampleEC2_DescribeVolumeStatus() { svc := ec2.New(nil) - params := &ec2.DescribeVPCClassicLinkInput{ - DryRun: aws.Boolean(true), + params := &ec2.DescribeVolumeStatusInput{ + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -3953,68 +3123,33 @@ func ExampleEC2_DescribeVPCClassicLink() { }, // More values... }, - VPCIDs: []*string{ + MaxResults: aws.Int64(1), + NextToken: aws.String("String"), + VolumeIds: []*string{ aws.String("String"), // Required // More values... }, } - resp, err := svc.DescribeVPCClassicLink(params) - - if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } - } - - // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) -} - -func ExampleEC2_DescribeVPCEndpointServices() { - svc := ec2.New(nil) - - params := &ec2.DescribeVPCEndpointServicesInput{ - DryRun: aws.Boolean(true), - MaxResults: aws.Long(1), - NextToken: aws.String("String"), - } - resp, err := svc.DescribeVPCEndpointServices(params) + resp, err := svc.DescribeVolumeStatus(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DescribeVPCEndpoints() { +func ExampleEC2_DescribeVolumes() { svc := ec2.New(nil) - params := &ec2.DescribeVPCEndpointsInput{ - DryRun: aws.Boolean(true), + params := &ec2.DescribeVolumesInput{ + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -4023,41 +3158,54 @@ func ExampleEC2_DescribeVPCEndpoints() { }, // More values... }, - MaxResults: aws.Long(1), + MaxResults: aws.Int64(1), NextToken: aws.String("String"), - VPCEndpointIDs: []*string{ + VolumeIds: []*string{ aws.String("String"), // Required // More values... }, } - resp, err := svc.DescribeVPCEndpoints(params) + resp, err := svc.DescribeVolumes(params) + + if err != nil { + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return + } + + // Pretty-print the response data. + fmt.Println(resp) +} + +func ExampleEC2_DescribeVpcAttribute() { + svc := ec2.New(nil) + + params := &ec2.DescribeVpcAttributeInput{ + VpcId: aws.String("String"), // Required + Attribute: aws.String("VpcAttributeName"), + DryRun: aws.Bool(true), + } + resp, err := svc.DescribeVpcAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DescribeVPCPeeringConnections() { +func ExampleEC2_DescribeVpcClassicLink() { svc := ec2.New(nil) - params := &ec2.DescribeVPCPeeringConnectionsInput{ - DryRun: aws.Boolean(true), + params := &ec2.DescribeVpcClassicLinkInput{ + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -4066,39 +3214,52 @@ func ExampleEC2_DescribeVPCPeeringConnections() { }, // More values... }, - VPCPeeringConnectionIDs: []*string{ + VpcIds: []*string{ aws.String("String"), // Required // More values... }, } - resp, err := svc.DescribeVPCPeeringConnections(params) + resp, err := svc.DescribeVpcClassicLink(params) + + if err != nil { + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return + } + + // Pretty-print the response data. + fmt.Println(resp) +} + +func ExampleEC2_DescribeVpcEndpointServices() { + svc := ec2.New(nil) + + params := &ec2.DescribeVpcEndpointServicesInput{ + DryRun: aws.Bool(true), + MaxResults: aws.Int64(1), + NextToken: aws.String("String"), + } + resp, err := svc.DescribeVpcEndpointServices(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DescribeVPCs() { +func ExampleEC2_DescribeVpcEndpoints() { svc := ec2.New(nil) - params := &ec2.DescribeVPCsInput{ - DryRun: aws.Boolean(true), + params := &ec2.DescribeVpcEndpointsInput{ + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -4107,39 +3268,33 @@ func ExampleEC2_DescribeVPCs() { }, // More values... }, - VPCIDs: []*string{ + MaxResults: aws.Int64(1), + NextToken: aws.String("String"), + VpcEndpointIds: []*string{ aws.String("String"), // Required // More values... }, } - resp, err := svc.DescribeVPCs(params) + resp, err := svc.DescribeVpcEndpoints(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DescribeVPNConnections() { +func ExampleEC2_DescribeVpcPeeringConnections() { svc := ec2.New(nil) - params := &ec2.DescribeVPNConnectionsInput{ - DryRun: aws.Boolean(true), + params := &ec2.DescribeVpcPeeringConnectionsInput{ + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -4148,39 +3303,31 @@ func ExampleEC2_DescribeVPNConnections() { }, // More values... }, - VPNConnectionIDs: []*string{ + VpcPeeringConnectionIds: []*string{ aws.String("String"), // Required // More values... }, } - resp, err := svc.DescribeVPNConnections(params) + resp, err := svc.DescribeVpcPeeringConnections(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DescribeVPNGateways() { +func ExampleEC2_DescribeVpcs() { svc := ec2.New(nil) - params := &ec2.DescribeVPNGatewaysInput{ - DryRun: aws.Boolean(true), + params := &ec2.DescribeVpcsInput{ + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -4189,68 +3336,31 @@ func ExampleEC2_DescribeVPNGateways() { }, // More values... }, - VPNGatewayIDs: []*string{ + VpcIds: []*string{ aws.String("String"), // Required // More values... }, } - resp, err := svc.DescribeVPNGateways(params) + resp, err := svc.DescribeVpcs(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DescribeVolumeAttribute() { +func ExampleEC2_DescribeVpnConnections() { svc := ec2.New(nil) - params := &ec2.DescribeVolumeAttributeInput{ - VolumeID: aws.String("String"), // Required - Attribute: aws.String("VolumeAttributeName"), - DryRun: aws.Boolean(true), - } - resp, err := svc.DescribeVolumeAttribute(params) - - if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } - } - - // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) -} - -func ExampleEC2_DescribeVolumeStatus() { - svc := ec2.New(nil) - - params := &ec2.DescribeVolumeStatusInput{ - DryRun: aws.Boolean(true), + params := &ec2.DescribeVpnConnectionsInput{ + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -4259,41 +3369,31 @@ func ExampleEC2_DescribeVolumeStatus() { }, // More values... }, - MaxResults: aws.Long(1), - NextToken: aws.String("String"), - VolumeIDs: []*string{ + VpnConnectionIds: []*string{ aws.String("String"), // Required // More values... }, } - resp, err := svc.DescribeVolumeStatus(params) + resp, err := svc.DescribeVpnConnections(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DescribeVolumes() { +func ExampleEC2_DescribeVpnGateways() { svc := ec2.New(nil) - params := &ec2.DescribeVolumesInput{ - DryRun: aws.Boolean(true), + params := &ec2.DescribeVpnGatewaysInput{ + DryRun: aws.Bool(true), Filters: []*ec2.Filter{ - &ec2.Filter{ // Required + { // Required Name: aws.String("String"), Values: []*string{ aws.String("String"), // Required @@ -4302,432 +3402,310 @@ func ExampleEC2_DescribeVolumes() { }, // More values... }, - MaxResults: aws.Long(1), - NextToken: aws.String("String"), - VolumeIDs: []*string{ + VpnGatewayIds: []*string{ aws.String("String"), // Required // More values... }, } - resp, err := svc.DescribeVolumes(params) + resp, err := svc.DescribeVpnGateways(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DetachClassicLinkVPC() { +func ExampleEC2_DetachClassicLinkVpc() { svc := ec2.New(nil) - params := &ec2.DetachClassicLinkVPCInput{ - InstanceID: aws.String("String"), // Required - VPCID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.DetachClassicLinkVpcInput{ + InstanceId: aws.String("String"), // Required + VpcId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.DetachClassicLinkVPC(params) + resp, err := svc.DetachClassicLinkVpc(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DetachInternetGateway() { svc := ec2.New(nil) params := &ec2.DetachInternetGatewayInput{ - InternetGatewayID: aws.String("String"), // Required - VPCID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + InternetGatewayId: aws.String("String"), // Required + VpcId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DetachInternetGateway(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DetachNetworkInterface() { svc := ec2.New(nil) params := &ec2.DetachNetworkInterfaceInput{ - AttachmentID: aws.String("String"), // Required - DryRun: aws.Boolean(true), - Force: aws.Boolean(true), + AttachmentId: aws.String("String"), // Required + DryRun: aws.Bool(true), + Force: aws.Bool(true), } resp, err := svc.DetachNetworkInterface(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DetachVPNGateway() { +func ExampleEC2_DetachVolume() { svc := ec2.New(nil) - params := &ec2.DetachVPNGatewayInput{ - VPCID: aws.String("String"), // Required - VPNGatewayID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.DetachVolumeInput{ + VolumeId: aws.String("String"), // Required + Device: aws.String("String"), + DryRun: aws.Bool(true), + Force: aws.Bool(true), + InstanceId: aws.String("String"), } - resp, err := svc.DetachVPNGateway(params) + resp, err := svc.DetachVolume(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DetachVolume() { +func ExampleEC2_DetachVpnGateway() { svc := ec2.New(nil) - params := &ec2.DetachVolumeInput{ - VolumeID: aws.String("String"), // Required - Device: aws.String("String"), - DryRun: aws.Boolean(true), - Force: aws.Boolean(true), - InstanceID: aws.String("String"), + params := &ec2.DetachVpnGatewayInput{ + VpcId: aws.String("String"), // Required + VpnGatewayId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.DetachVolume(params) + resp, err := svc.DetachVpnGateway(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DisableVGWRoutePropagation() { +func ExampleEC2_DisableVgwRoutePropagation() { svc := ec2.New(nil) - params := &ec2.DisableVGWRoutePropagationInput{ - GatewayID: aws.String("String"), // Required - RouteTableID: aws.String("String"), // Required + params := &ec2.DisableVgwRoutePropagationInput{ + GatewayId: aws.String("String"), // Required + RouteTableId: aws.String("String"), // Required } - resp, err := svc.DisableVGWRoutePropagation(params) + resp, err := svc.DisableVgwRoutePropagation(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_DisableVPCClassicLink() { +func ExampleEC2_DisableVpcClassicLink() { svc := ec2.New(nil) - params := &ec2.DisableVPCClassicLinkInput{ - VPCID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.DisableVpcClassicLinkInput{ + VpcId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.DisableVPCClassicLink(params) + resp, err := svc.DisableVpcClassicLink(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DisassociateAddress() { svc := ec2.New(nil) params := &ec2.DisassociateAddressInput{ - AssociationID: aws.String("String"), - DryRun: aws.Boolean(true), - PublicIP: aws.String("String"), + AssociationId: aws.String("String"), + DryRun: aws.Bool(true), + PublicIp: aws.String("String"), } resp, err := svc.DisassociateAddress(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_DisassociateRouteTable() { svc := ec2.New(nil) params := &ec2.DisassociateRouteTableInput{ - AssociationID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + AssociationId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.DisassociateRouteTable(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_EnableVGWRoutePropagation() { +func ExampleEC2_EnableVgwRoutePropagation() { svc := ec2.New(nil) - params := &ec2.EnableVGWRoutePropagationInput{ - GatewayID: aws.String("String"), // Required - RouteTableID: aws.String("String"), // Required + params := &ec2.EnableVgwRoutePropagationInput{ + GatewayId: aws.String("String"), // Required + RouteTableId: aws.String("String"), // Required } - resp, err := svc.EnableVGWRoutePropagation(params) + resp, err := svc.EnableVgwRoutePropagation(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_EnableVPCClassicLink() { +func ExampleEC2_EnableVolumeIO() { svc := ec2.New(nil) - params := &ec2.EnableVPCClassicLinkInput{ - VPCID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.EnableVolumeIOInput{ + VolumeId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.EnableVPCClassicLink(params) + resp, err := svc.EnableVolumeIO(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_EnableVolumeIO() { +func ExampleEC2_EnableVpcClassicLink() { svc := ec2.New(nil) - params := &ec2.EnableVolumeIOInput{ - VolumeID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.EnableVpcClassicLinkInput{ + VpcId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.EnableVolumeIO(params) + resp, err := svc.EnableVpcClassicLink(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_GetConsoleOutput() { svc := ec2.New(nil) params := &ec2.GetConsoleOutputInput{ - InstanceID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + InstanceId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.GetConsoleOutput(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_GetPasswordData() { svc := ec2.New(nil) params := &ec2.GetPasswordDataInput{ - InstanceID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + InstanceId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.GetPasswordData(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ImportImage() { @@ -4738,18 +3716,18 @@ func ExampleEC2_ImportImage() { ClientData: &ec2.ClientData{ Comment: aws.String("String"), UploadEnd: aws.Time(time.Now()), - UploadSize: aws.Double(1.0), + UploadSize: aws.Float64(1.0), UploadStart: aws.Time(time.Now()), }, ClientToken: aws.String("String"), Description: aws.String("String"), DiskContainers: []*ec2.ImageDiskContainer{ - &ec2.ImageDiskContainer{ // Required + { // Required Description: aws.String("String"), DeviceName: aws.String("String"), Format: aws.String("String"), - SnapshotID: aws.String("String"), - URL: aws.String("String"), + SnapshotId: aws.String("String"), + Url: aws.String("String"), UserBucket: &ec2.UserBucket{ S3Bucket: aws.String("String"), S3Key: aws.String("String"), @@ -4757,7 +3735,7 @@ func ExampleEC2_ImportImage() { }, // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Hypervisor: aws.String("String"), LicenseType: aws.String("String"), Platform: aws.String("String"), @@ -4766,22 +3744,14 @@ func ExampleEC2_ImportImage() { resp, err := svc.ImportImage(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ImportInstance() { @@ -4791,24 +3761,24 @@ func ExampleEC2_ImportInstance() { Platform: aws.String("PlatformValues"), // Required Description: aws.String("String"), DiskImages: []*ec2.DiskImage{ - &ec2.DiskImage{ // Required + { // Required Description: aws.String("String"), Image: &ec2.DiskImageDetail{ - Bytes: aws.Long(1), // Required + Bytes: aws.Int64(1), // Required Format: aws.String("DiskImageFormat"), // Required - ImportManifestURL: aws.String("String"), // Required + ImportManifestUrl: aws.String("String"), // Required }, Volume: &ec2.VolumeDetail{ - Size: aws.Long(1), // Required + Size: aws.Int64(1), // Required }, }, // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), LaunchSpecification: &ec2.ImportInstanceLaunchSpecification{ AdditionalInfo: aws.String("String"), Architecture: aws.String("ArchitectureValues"), - GroupIDs: []*string{ + GroupIds: []*string{ aws.String("String"), // Required // More values... }, @@ -4818,14 +3788,14 @@ func ExampleEC2_ImportInstance() { }, InstanceInitiatedShutdownBehavior: aws.String("ShutdownBehavior"), InstanceType: aws.String("InstanceType"), - Monitoring: aws.Boolean(true), + Monitoring: aws.Bool(true), Placement: &ec2.Placement{ AvailabilityZone: aws.String("String"), GroupName: aws.String("String"), Tenancy: aws.String("Tenancy"), }, - PrivateIPAddress: aws.String("String"), - SubnetID: aws.String("String"), + PrivateIpAddress: aws.String("String"), + SubnetId: aws.String("String"), UserData: &ec2.UserData{ Data: aws.String("String"), }, @@ -4834,22 +3804,14 @@ func ExampleEC2_ImportInstance() { resp, err := svc.ImportInstance(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ImportKeyPair() { @@ -4858,27 +3820,19 @@ func ExampleEC2_ImportKeyPair() { params := &ec2.ImportKeyPairInput{ KeyName: aws.String("String"), // Required PublicKeyMaterial: []byte("PAYLOAD"), // Required - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.ImportKeyPair(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ImportSnapshot() { @@ -4888,7 +3842,7 @@ func ExampleEC2_ImportSnapshot() { ClientData: &ec2.ClientData{ Comment: aws.String("String"), UploadEnd: aws.Time(time.Now()), - UploadSize: aws.Double(1.0), + UploadSize: aws.Float64(1.0), UploadStart: aws.Time(time.Now()), }, ClientToken: aws.String("String"), @@ -4896,34 +3850,26 @@ func ExampleEC2_ImportSnapshot() { DiskContainer: &ec2.SnapshotDiskContainer{ Description: aws.String("String"), Format: aws.String("String"), - URL: aws.String("String"), + Url: aws.String("String"), UserBucket: &ec2.UserBucket{ S3Bucket: aws.String("String"), S3Key: aws.String("String"), }, }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), RoleName: aws.String("String"), } resp, err := svc.ImportSnapshot(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ImportVolume() { @@ -4932,64 +3878,56 @@ func ExampleEC2_ImportVolume() { params := &ec2.ImportVolumeInput{ AvailabilityZone: aws.String("String"), // Required Image: &ec2.DiskImageDetail{ // Required - Bytes: aws.Long(1), // Required + Bytes: aws.Int64(1), // Required Format: aws.String("DiskImageFormat"), // Required - ImportManifestURL: aws.String("String"), // Required + ImportManifestUrl: aws.String("String"), // Required }, Volume: &ec2.VolumeDetail{ // Required - Size: aws.Long(1), // Required + Size: aws.Int64(1), // Required }, Description: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.ImportVolume(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ModifyImageAttribute() { svc := ec2.New(nil) params := &ec2.ModifyImageAttributeInput{ - ImageID: aws.String("String"), // Required + ImageId: aws.String("String"), // Required Attribute: aws.String("String"), Description: &ec2.AttributeValue{ Value: aws.String("String"), }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), LaunchPermission: &ec2.LaunchPermissionModifications{ Add: []*ec2.LaunchPermission{ - &ec2.LaunchPermission{ // Required + { // Required Group: aws.String("PermissionGroup"), - UserID: aws.String("String"), + UserId: aws.String("String"), }, // More values... }, Remove: []*ec2.LaunchPermission{ - &ec2.LaunchPermission{ // Required + { // Required Group: aws.String("PermissionGroup"), - UserID: aws.String("String"), + UserId: aws.String("String"), }, // More values... }, }, - OperationType: aws.String("String"), + OperationType: aws.String("OperationType"), ProductCodes: []*string{ aws.String("String"), // Required // More values... @@ -4998,7 +3936,7 @@ func ExampleEC2_ModifyImageAttribute() { aws.String("String"), // Required // More values... }, - UserIDs: []*string{ + UserIds: []*string{ aws.String("String"), // Required // More values... }, @@ -5007,48 +3945,40 @@ func ExampleEC2_ModifyImageAttribute() { resp, err := svc.ModifyImageAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ModifyInstanceAttribute() { svc := ec2.New(nil) params := &ec2.ModifyInstanceAttributeInput{ - InstanceID: aws.String("String"), // Required + InstanceId: aws.String("String"), // Required Attribute: aws.String("InstanceAttributeName"), BlockDeviceMappings: []*ec2.InstanceBlockDeviceMappingSpecification{ - &ec2.InstanceBlockDeviceMappingSpecification{ // Required + { // Required DeviceName: aws.String("String"), - EBS: &ec2.EBSInstanceBlockDeviceSpecification{ - DeleteOnTermination: aws.Boolean(true), - VolumeID: aws.String("String"), + Ebs: &ec2.EbsInstanceBlockDeviceSpecification{ + DeleteOnTermination: aws.Bool(true), + VolumeId: aws.String("String"), }, NoDevice: aws.String("String"), VirtualName: aws.String("String"), }, // More values... }, - DisableAPITermination: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(true), + DisableApiTermination: &ec2.AttributeBooleanValue{ + Value: aws.Bool(true), }, - DryRun: aws.Boolean(true), - EBSOptimized: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(true), + DryRun: aws.Bool(true), + EbsOptimized: &ec2.AttributeBooleanValue{ + Value: aws.Bool(true), }, Groups: []*string{ aws.String("String"), // Required @@ -5063,14 +3993,14 @@ func ExampleEC2_ModifyInstanceAttribute() { Kernel: &ec2.AttributeValue{ Value: aws.String("String"), }, - RAMDisk: &ec2.AttributeValue{ - Value: aws.String("String"), - }, - SRIOVNetSupport: &ec2.AttributeValue{ + Ramdisk: &ec2.AttributeValue{ Value: aws.String("String"), }, SourceDestCheck: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(true), + Value: aws.Bool(true), + }, + SriovNetSupport: &ec2.AttributeValue{ + Value: aws.String("String"), }, UserData: &ec2.BlobAttributeValue{ Value: []byte("PAYLOAD"), @@ -5080,78 +4010,62 @@ func ExampleEC2_ModifyInstanceAttribute() { resp, err := svc.ModifyInstanceAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ModifyNetworkInterfaceAttribute() { svc := ec2.New(nil) params := &ec2.ModifyNetworkInterfaceAttributeInput{ - NetworkInterfaceID: aws.String("String"), // Required + NetworkInterfaceId: aws.String("String"), // Required Attachment: &ec2.NetworkInterfaceAttachmentChanges{ - AttachmentID: aws.String("String"), - DeleteOnTermination: aws.Boolean(true), + AttachmentId: aws.String("String"), + DeleteOnTermination: aws.Bool(true), }, Description: &ec2.AttributeValue{ Value: aws.String("String"), }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), Groups: []*string{ aws.String("String"), // Required // More values... }, SourceDestCheck: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(true), + Value: aws.Bool(true), }, } resp, err := svc.ModifyNetworkInterfaceAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ModifyReservedInstances() { svc := ec2.New(nil) params := &ec2.ModifyReservedInstancesInput{ - ReservedInstancesIDs: []*string{ // Required + ReservedInstancesIds: []*string{ // Required aws.String("String"), // Required // More values... }, TargetConfigurations: []*ec2.ReservedInstancesConfiguration{ // Required - &ec2.ReservedInstancesConfiguration{ // Required + { // Required AvailabilityZone: aws.String("String"), - InstanceCount: aws.Long(1), + InstanceCount: aws.Int64(1), InstanceType: aws.String("InstanceType"), Platform: aws.String("String"), }, @@ -5162,53 +4076,45 @@ func ExampleEC2_ModifyReservedInstances() { resp, err := svc.ModifyReservedInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ModifySnapshotAttribute() { svc := ec2.New(nil) params := &ec2.ModifySnapshotAttributeInput{ - SnapshotID: aws.String("String"), // Required + SnapshotId: aws.String("String"), // Required Attribute: aws.String("SnapshotAttributeName"), CreateVolumePermission: &ec2.CreateVolumePermissionModifications{ Add: []*ec2.CreateVolumePermission{ - &ec2.CreateVolumePermission{ // Required + { // Required Group: aws.String("PermissionGroup"), - UserID: aws.String("String"), + UserId: aws.String("String"), }, // More values... }, Remove: []*ec2.CreateVolumePermission{ - &ec2.CreateVolumePermission{ // Required + { // Required Group: aws.String("PermissionGroup"), - UserID: aws.String("String"), + UserId: aws.String("String"), }, // More values... }, }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), GroupNames: []*string{ aws.String("String"), // Required // More values... }, - OperationType: aws.String("String"), - UserIDs: []*string{ + OperationType: aws.String("OperationType"), + UserIds: []*string{ aws.String("String"), // Required // More values... }, @@ -5216,277 +4122,205 @@ func ExampleEC2_ModifySnapshotAttribute() { resp, err := svc.ModifySnapshotAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ModifySubnetAttribute() { svc := ec2.New(nil) params := &ec2.ModifySubnetAttributeInput{ - SubnetID: aws.String("String"), // Required - MapPublicIPOnLaunch: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(true), + SubnetId: aws.String("String"), // Required + MapPublicIpOnLaunch: &ec2.AttributeBooleanValue{ + Value: aws.Bool(true), }, } resp, err := svc.ModifySubnetAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_ModifyVPCAttribute() { +func ExampleEC2_ModifyVolumeAttribute() { svc := ec2.New(nil) - params := &ec2.ModifyVPCAttributeInput{ - VPCID: aws.String("String"), // Required - EnableDNSHostnames: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(true), - }, - EnableDNSSupport: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(true), + params := &ec2.ModifyVolumeAttributeInput{ + VolumeId: aws.String("String"), // Required + AutoEnableIO: &ec2.AttributeBooleanValue{ + Value: aws.Bool(true), }, + DryRun: aws.Bool(true), } - resp, err := svc.ModifyVPCAttribute(params) + resp, err := svc.ModifyVolumeAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_ModifyVPCEndpoint() { +func ExampleEC2_ModifyVpcAttribute() { svc := ec2.New(nil) - params := &ec2.ModifyVPCEndpointInput{ - VPCEndpointID: aws.String("String"), // Required - AddRouteTableIDs: []*string{ - aws.String("String"), // Required - // More values... + params := &ec2.ModifyVpcAttributeInput{ + VpcId: aws.String("String"), // Required + EnableDnsHostnames: &ec2.AttributeBooleanValue{ + Value: aws.Bool(true), }, - DryRun: aws.Boolean(true), - PolicyDocument: aws.String("String"), - RemoveRouteTableIDs: []*string{ - aws.String("String"), // Required - // More values... + EnableDnsSupport: &ec2.AttributeBooleanValue{ + Value: aws.Bool(true), }, - ResetPolicy: aws.Boolean(true), } - resp, err := svc.ModifyVPCEndpoint(params) + resp, err := svc.ModifyVpcAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_ModifyVolumeAttribute() { +func ExampleEC2_ModifyVpcEndpoint() { svc := ec2.New(nil) - params := &ec2.ModifyVolumeAttributeInput{ - VolumeID: aws.String("String"), // Required - AutoEnableIO: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(true), + params := &ec2.ModifyVpcEndpointInput{ + VpcEndpointId: aws.String("String"), // Required + AddRouteTableIds: []*string{ + aws.String("String"), // Required + // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), + PolicyDocument: aws.String("String"), + RemoveRouteTableIds: []*string{ + aws.String("String"), // Required + // More values... + }, + ResetPolicy: aws.Bool(true), } - resp, err := svc.ModifyVolumeAttribute(params) + resp, err := svc.ModifyVpcEndpoint(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_MonitorInstances() { svc := ec2.New(nil) params := &ec2.MonitorInstancesInput{ - InstanceIDs: []*string{ // Required + InstanceIds: []*string{ // Required aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.MonitorInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_MoveAddressToVPC() { +func ExampleEC2_MoveAddressToVpc() { svc := ec2.New(nil) - params := &ec2.MoveAddressToVPCInput{ - PublicIP: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.MoveAddressToVpcInput{ + PublicIp: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.MoveAddressToVPC(params) + resp, err := svc.MoveAddressToVpc(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_PurchaseReservedInstancesOffering() { svc := ec2.New(nil) params := &ec2.PurchaseReservedInstancesOfferingInput{ - InstanceCount: aws.Long(1), // Required - ReservedInstancesOfferingID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + InstanceCount: aws.Int64(1), // Required + ReservedInstancesOfferingId: aws.String("String"), // Required + DryRun: aws.Bool(true), LimitPrice: &ec2.ReservedInstanceLimitPrice{ - Amount: aws.Double(1.0), + Amount: aws.Float64(1.0), CurrencyCode: aws.String("CurrencyCodeValues"), }, } resp, err := svc.PurchaseReservedInstancesOffering(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_RebootInstances() { svc := ec2.New(nil) params := &ec2.RebootInstancesInput{ - InstanceIDs: []*string{ // Required + InstanceIds: []*string{ // Required aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.RebootInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_RegisterImage() { @@ -5496,14 +4330,14 @@ func ExampleEC2_RegisterImage() { Name: aws.String("String"), // Required Architecture: aws.String("ArchitectureValues"), BlockDeviceMappings: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ // Required + { // Required DeviceName: aws.String("String"), - EBS: &ec2.EBSBlockDevice{ - DeleteOnTermination: aws.Boolean(true), - Encrypted: aws.Boolean(true), - IOPS: aws.Long(1), - SnapshotID: aws.String("String"), - VolumeSize: aws.Long(1), + Ebs: &ec2.EbsBlockDevice{ + DeleteOnTermination: aws.Bool(true), + Encrypted: aws.Bool(true), + Iops: aws.Int64(1), + SnapshotId: aws.String("String"), + VolumeSize: aws.Int64(1), VolumeType: aws.String("VolumeType"), }, NoDevice: aws.String("String"), @@ -5512,222 +4346,166 @@ func ExampleEC2_RegisterImage() { // More values... }, Description: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), ImageLocation: aws.String("String"), - KernelID: aws.String("String"), - RAMDiskID: aws.String("String"), + KernelId: aws.String("String"), + RamdiskId: aws.String("String"), RootDeviceName: aws.String("String"), - SRIOVNetSupport: aws.String("String"), + SriovNetSupport: aws.String("String"), VirtualizationType: aws.String("String"), } resp, err := svc.RegisterImage(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_RejectVPCPeeringConnection() { +func ExampleEC2_RejectVpcPeeringConnection() { svc := ec2.New(nil) - params := &ec2.RejectVPCPeeringConnectionInput{ - VPCPeeringConnectionID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.RejectVpcPeeringConnectionInput{ + VpcPeeringConnectionId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.RejectVPCPeeringConnection(params) + resp, err := svc.RejectVpcPeeringConnection(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ReleaseAddress() { svc := ec2.New(nil) params := &ec2.ReleaseAddressInput{ - AllocationID: aws.String("String"), - DryRun: aws.Boolean(true), - PublicIP: aws.String("String"), + AllocationId: aws.String("String"), + DryRun: aws.Bool(true), + PublicIp: aws.String("String"), } resp, err := svc.ReleaseAddress(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_ReplaceNetworkACLAssociation() { +func ExampleEC2_ReplaceNetworkAclAssociation() { svc := ec2.New(nil) - params := &ec2.ReplaceNetworkACLAssociationInput{ - AssociationID: aws.String("String"), // Required - NetworkACLID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + params := &ec2.ReplaceNetworkAclAssociationInput{ + AssociationId: aws.String("String"), // Required + NetworkAclId: aws.String("String"), // Required + DryRun: aws.Bool(true), } - resp, err := svc.ReplaceNetworkACLAssociation(params) + resp, err := svc.ReplaceNetworkAclAssociation(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_ReplaceNetworkACLEntry() { +func ExampleEC2_ReplaceNetworkAclEntry() { svc := ec2.New(nil) - params := &ec2.ReplaceNetworkACLEntryInput{ - CIDRBlock: aws.String("String"), // Required - Egress: aws.Boolean(true), // Required - NetworkACLID: aws.String("String"), // Required + params := &ec2.ReplaceNetworkAclEntryInput{ + CidrBlock: aws.String("String"), // Required + Egress: aws.Bool(true), // Required + NetworkAclId: aws.String("String"), // Required Protocol: aws.String("String"), // Required RuleAction: aws.String("RuleAction"), // Required - RuleNumber: aws.Long(1), // Required - DryRun: aws.Boolean(true), - ICMPTypeCode: &ec2.ICMPTypeCode{ - Code: aws.Long(1), - Type: aws.Long(1), + RuleNumber: aws.Int64(1), // Required + DryRun: aws.Bool(true), + IcmpTypeCode: &ec2.IcmpTypeCode{ + Code: aws.Int64(1), + Type: aws.Int64(1), }, PortRange: &ec2.PortRange{ - From: aws.Long(1), - To: aws.Long(1), + From: aws.Int64(1), + To: aws.Int64(1), }, } - resp, err := svc.ReplaceNetworkACLEntry(params) + resp, err := svc.ReplaceNetworkAclEntry(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ReplaceRoute() { svc := ec2.New(nil) params := &ec2.ReplaceRouteInput{ - DestinationCIDRBlock: aws.String("String"), // Required - RouteTableID: aws.String("String"), // Required - DryRun: aws.Boolean(true), - GatewayID: aws.String("String"), - InstanceID: aws.String("String"), - NetworkInterfaceID: aws.String("String"), - VPCPeeringConnectionID: aws.String("String"), + DestinationCidrBlock: aws.String("String"), // Required + RouteTableId: aws.String("String"), // Required + DryRun: aws.Bool(true), + GatewayId: aws.String("String"), + InstanceId: aws.String("String"), + NetworkInterfaceId: aws.String("String"), + VpcPeeringConnectionId: aws.String("String"), } resp, err := svc.ReplaceRoute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ReplaceRouteTableAssociation() { svc := ec2.New(nil) params := &ec2.ReplaceRouteTableAssociationInput{ - AssociationID: aws.String("String"), // Required - RouteTableID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + AssociationId: aws.String("String"), // Required + RouteTableId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.ReplaceRouteTableAssociation(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ReportInstanceStatus() { @@ -5744,29 +4522,21 @@ func ExampleEC2_ReportInstanceStatus() { }, Status: aws.String("ReportStatusType"), // Required Description: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), EndTime: aws.Time(time.Now()), StartTime: aws.Time(time.Now()), } resp, err := svc.ReportInstanceStatus(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_RequestSpotFleet() { @@ -5774,19 +4544,19 @@ func ExampleEC2_RequestSpotFleet() { params := &ec2.RequestSpotFleetInput{ SpotFleetRequestConfig: &ec2.SpotFleetRequestConfigData{ // Required - IAMFleetRole: aws.String("String"), // Required - LaunchSpecifications: []*ec2.LaunchSpecification{ // Required - &ec2.LaunchSpecification{ // Required + IamFleetRole: aws.String("String"), // Required + LaunchSpecifications: []*ec2.SpotFleetLaunchSpecification{ // Required + { // Required AddressingType: aws.String("String"), BlockDeviceMappings: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ // Required + { // Required DeviceName: aws.String("String"), - EBS: &ec2.EBSBlockDevice{ - DeleteOnTermination: aws.Boolean(true), - Encrypted: aws.Boolean(true), - IOPS: aws.Long(1), - SnapshotID: aws.String("String"), - VolumeSize: aws.Long(1), + Ebs: &ec2.EbsBlockDevice{ + DeleteOnTermination: aws.Bool(true), + Encrypted: aws.Bool(true), + Iops: aws.Int64(1), + SnapshotId: aws.String("String"), + VolumeSize: aws.Int64(1), VolumeType: aws.String("VolumeType"), }, NoDevice: aws.String("String"), @@ -5794,39 +4564,39 @@ func ExampleEC2_RequestSpotFleet() { }, // More values... }, - EBSOptimized: aws.Boolean(true), - IAMInstanceProfile: &ec2.IAMInstanceProfileSpecification{ - ARN: aws.String("String"), + EbsOptimized: aws.Bool(true), + IamInstanceProfile: &ec2.IamInstanceProfileSpecification{ + Arn: aws.String("String"), Name: aws.String("String"), }, - ImageID: aws.String("String"), + ImageId: aws.String("String"), InstanceType: aws.String("InstanceType"), - KernelID: aws.String("String"), + KernelId: aws.String("String"), KeyName: aws.String("String"), - Monitoring: &ec2.RunInstancesMonitoringEnabled{ - Enabled: aws.Boolean(true), // Required + Monitoring: &ec2.SpotFleetMonitoring{ + Enabled: aws.Bool(true), }, NetworkInterfaces: []*ec2.InstanceNetworkInterfaceSpecification{ - &ec2.InstanceNetworkInterfaceSpecification{ // Required - AssociatePublicIPAddress: aws.Boolean(true), - DeleteOnTermination: aws.Boolean(true), + { // Required + AssociatePublicIpAddress: aws.Bool(true), + DeleteOnTermination: aws.Bool(true), Description: aws.String("String"), - DeviceIndex: aws.Long(1), + DeviceIndex: aws.Int64(1), Groups: []*string{ aws.String("String"), // Required // More values... }, - NetworkInterfaceID: aws.String("String"), - PrivateIPAddress: aws.String("String"), - PrivateIPAddresses: []*ec2.PrivateIPAddressSpecification{ - &ec2.PrivateIPAddressSpecification{ // Required - PrivateIPAddress: aws.String("String"), // Required - Primary: aws.Boolean(true), + NetworkInterfaceId: aws.String("String"), + PrivateIpAddress: aws.String("String"), + PrivateIpAddresses: []*ec2.PrivateIpAddressSpecification{ + { // Required + PrivateIpAddress: aws.String("String"), // Required + Primary: aws.Bool(true), }, // More values... }, - SecondaryPrivateIPAddressCount: aws.Long(1), - SubnetID: aws.String("String"), + SecondaryPrivateIpAddressCount: aws.Int64(1), + SubnetId: aws.String("String"), }, // More values... }, @@ -5834,47 +4604,42 @@ func ExampleEC2_RequestSpotFleet() { AvailabilityZone: aws.String("String"), GroupName: aws.String("String"), }, - RAMDiskID: aws.String("String"), + RamdiskId: aws.String("String"), SecurityGroups: []*ec2.GroupIdentifier{ - &ec2.GroupIdentifier{ // Required - GroupID: aws.String("String"), + { // Required + GroupId: aws.String("String"), GroupName: aws.String("String"), }, // More values... }, - SubnetID: aws.String("String"), - UserData: aws.String("String"), + SpotPrice: aws.String("String"), + SubnetId: aws.String("String"), + UserData: aws.String("String"), + WeightedCapacity: aws.Float64(1.0), }, // More values... }, SpotPrice: aws.String("String"), // Required - TargetCapacity: aws.Long(1), // Required + TargetCapacity: aws.Int64(1), // Required + AllocationStrategy: aws.String("AllocationStrategy"), ClientToken: aws.String("String"), - TerminateInstancesWithExpiration: aws.Boolean(true), + TerminateInstancesWithExpiration: aws.Bool(true), ValidFrom: aws.Time(time.Now()), ValidUntil: aws.Time(time.Now()), }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.RequestSpotFleet(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_RequestSpotInstances() { @@ -5884,20 +4649,20 @@ func ExampleEC2_RequestSpotInstances() { SpotPrice: aws.String("String"), // Required AvailabilityZoneGroup: aws.String("String"), ClientToken: aws.String("String"), - DryRun: aws.Boolean(true), - InstanceCount: aws.Long(1), + DryRun: aws.Bool(true), + InstanceCount: aws.Int64(1), LaunchGroup: aws.String("String"), LaunchSpecification: &ec2.RequestSpotLaunchSpecification{ AddressingType: aws.String("String"), BlockDeviceMappings: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ // Required + { // Required DeviceName: aws.String("String"), - EBS: &ec2.EBSBlockDevice{ - DeleteOnTermination: aws.Boolean(true), - Encrypted: aws.Boolean(true), - IOPS: aws.Long(1), - SnapshotID: aws.String("String"), - VolumeSize: aws.Long(1), + Ebs: &ec2.EbsBlockDevice{ + DeleteOnTermination: aws.Bool(true), + Encrypted: aws.Bool(true), + Iops: aws.Int64(1), + SnapshotId: aws.String("String"), + VolumeSize: aws.Int64(1), VolumeType: aws.String("VolumeType"), }, NoDevice: aws.String("String"), @@ -5905,39 +4670,39 @@ func ExampleEC2_RequestSpotInstances() { }, // More values... }, - EBSOptimized: aws.Boolean(true), - IAMInstanceProfile: &ec2.IAMInstanceProfileSpecification{ - ARN: aws.String("String"), + EbsOptimized: aws.Bool(true), + IamInstanceProfile: &ec2.IamInstanceProfileSpecification{ + Arn: aws.String("String"), Name: aws.String("String"), }, - ImageID: aws.String("String"), + ImageId: aws.String("String"), InstanceType: aws.String("InstanceType"), - KernelID: aws.String("String"), + KernelId: aws.String("String"), KeyName: aws.String("String"), Monitoring: &ec2.RunInstancesMonitoringEnabled{ - Enabled: aws.Boolean(true), // Required + Enabled: aws.Bool(true), // Required }, NetworkInterfaces: []*ec2.InstanceNetworkInterfaceSpecification{ - &ec2.InstanceNetworkInterfaceSpecification{ // Required - AssociatePublicIPAddress: aws.Boolean(true), - DeleteOnTermination: aws.Boolean(true), + { // Required + AssociatePublicIpAddress: aws.Bool(true), + DeleteOnTermination: aws.Bool(true), Description: aws.String("String"), - DeviceIndex: aws.Long(1), + DeviceIndex: aws.Int64(1), Groups: []*string{ aws.String("String"), // Required // More values... }, - NetworkInterfaceID: aws.String("String"), - PrivateIPAddress: aws.String("String"), - PrivateIPAddresses: []*ec2.PrivateIPAddressSpecification{ - &ec2.PrivateIPAddressSpecification{ // Required - PrivateIPAddress: aws.String("String"), // Required - Primary: aws.Boolean(true), + NetworkInterfaceId: aws.String("String"), + PrivateIpAddress: aws.String("String"), + PrivateIpAddresses: []*ec2.PrivateIpAddressSpecification{ + { // Required + PrivateIpAddress: aws.String("String"), // Required + Primary: aws.Bool(true), }, // More values... }, - SecondaryPrivateIPAddressCount: aws.Long(1), - SubnetID: aws.String("String"), + SecondaryPrivateIpAddressCount: aws.Int64(1), + SubnetId: aws.String("String"), }, // More values... }, @@ -5945,8 +4710,8 @@ func ExampleEC2_RequestSpotInstances() { AvailabilityZone: aws.String("String"), GroupName: aws.String("String"), }, - RAMDiskID: aws.String("String"), - SecurityGroupIDs: []*string{ + RamdiskId: aws.String("String"), + SecurityGroupIds: []*string{ aws.String("String"), // Required // More values... }, @@ -5954,7 +4719,7 @@ func ExampleEC2_RequestSpotInstances() { aws.String("String"), // Required // More values... }, - SubnetID: aws.String("String"), + SubnetId: aws.String("String"), UserData: aws.String("String"), }, Type: aws.String("SpotInstanceType"), @@ -5964,22 +4729,14 @@ func ExampleEC2_RequestSpotInstances() { resp, err := svc.RequestSpotInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ResetImageAttribute() { @@ -5987,28 +4744,20 @@ func ExampleEC2_ResetImageAttribute() { params := &ec2.ResetImageAttributeInput{ Attribute: aws.String("ResetImageAttributeName"), // Required - ImageID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + ImageId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.ResetImageAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ResetInstanceAttribute() { @@ -6016,57 +4765,41 @@ func ExampleEC2_ResetInstanceAttribute() { params := &ec2.ResetInstanceAttributeInput{ Attribute: aws.String("InstanceAttributeName"), // Required - InstanceID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + InstanceId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.ResetInstanceAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ResetNetworkInterfaceAttribute() { svc := ec2.New(nil) params := &ec2.ResetNetworkInterfaceAttributeInput{ - NetworkInterfaceID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + NetworkInterfaceId: aws.String("String"), // Required + DryRun: aws.Bool(true), SourceDestCheck: aws.String("String"), } resp, err := svc.ResetNetworkInterfaceAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_ResetSnapshotAttribute() { @@ -6074,200 +4807,168 @@ func ExampleEC2_ResetSnapshotAttribute() { params := &ec2.ResetSnapshotAttributeInput{ Attribute: aws.String("SnapshotAttributeName"), // Required - SnapshotID: aws.String("String"), // Required - DryRun: aws.Boolean(true), + SnapshotId: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.ResetSnapshotAttribute(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_RestoreAddressToClassic() { svc := ec2.New(nil) params := &ec2.RestoreAddressToClassicInput{ - PublicIP: aws.String("String"), // Required - DryRun: aws.Boolean(true), + PublicIp: aws.String("String"), // Required + DryRun: aws.Bool(true), } resp, err := svc.RestoreAddressToClassic(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_RevokeSecurityGroupEgress() { svc := ec2.New(nil) params := &ec2.RevokeSecurityGroupEgressInput{ - GroupID: aws.String("String"), // Required - CIDRIP: aws.String("String"), - DryRun: aws.Boolean(true), - FromPort: aws.Long(1), - IPPermissions: []*ec2.IPPermission{ - &ec2.IPPermission{ // Required - FromPort: aws.Long(1), - IPProtocol: aws.String("String"), - IPRanges: []*ec2.IPRange{ - &ec2.IPRange{ // Required - CIDRIP: aws.String("String"), + GroupId: aws.String("String"), // Required + CidrIp: aws.String("String"), + DryRun: aws.Bool(true), + FromPort: aws.Int64(1), + IpPermissions: []*ec2.IpPermission{ + { // Required + FromPort: aws.Int64(1), + IpProtocol: aws.String("String"), + IpRanges: []*ec2.IpRange{ + { // Required + CidrIp: aws.String("String"), }, // More values... }, - PrefixListIDs: []*ec2.PrefixListID{ - &ec2.PrefixListID{ // Required - PrefixListID: aws.String("String"), + PrefixListIds: []*ec2.PrefixListId{ + { // Required + PrefixListId: aws.String("String"), }, // More values... }, - ToPort: aws.Long(1), - UserIDGroupPairs: []*ec2.UserIDGroupPair{ - &ec2.UserIDGroupPair{ // Required - GroupID: aws.String("String"), + ToPort: aws.Int64(1), + UserIdGroupPairs: []*ec2.UserIdGroupPair{ + { // Required + GroupId: aws.String("String"), GroupName: aws.String("String"), - UserID: aws.String("String"), + UserId: aws.String("String"), }, // More values... }, }, // More values... }, - IPProtocol: aws.String("String"), + IpProtocol: aws.String("String"), SourceSecurityGroupName: aws.String("String"), - SourceSecurityGroupOwnerID: aws.String("String"), - ToPort: aws.Long(1), + SourceSecurityGroupOwnerId: aws.String("String"), + ToPort: aws.Int64(1), } resp, err := svc.RevokeSecurityGroupEgress(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_RevokeSecurityGroupIngress() { svc := ec2.New(nil) params := &ec2.RevokeSecurityGroupIngressInput{ - CIDRIP: aws.String("String"), - DryRun: aws.Boolean(true), - FromPort: aws.Long(1), - GroupID: aws.String("String"), + CidrIp: aws.String("String"), + DryRun: aws.Bool(true), + FromPort: aws.Int64(1), + GroupId: aws.String("String"), GroupName: aws.String("String"), - IPPermissions: []*ec2.IPPermission{ - &ec2.IPPermission{ // Required - FromPort: aws.Long(1), - IPProtocol: aws.String("String"), - IPRanges: []*ec2.IPRange{ - &ec2.IPRange{ // Required - CIDRIP: aws.String("String"), + IpPermissions: []*ec2.IpPermission{ + { // Required + FromPort: aws.Int64(1), + IpProtocol: aws.String("String"), + IpRanges: []*ec2.IpRange{ + { // Required + CidrIp: aws.String("String"), }, // More values... }, - PrefixListIDs: []*ec2.PrefixListID{ - &ec2.PrefixListID{ // Required - PrefixListID: aws.String("String"), + PrefixListIds: []*ec2.PrefixListId{ + { // Required + PrefixListId: aws.String("String"), }, // More values... }, - ToPort: aws.Long(1), - UserIDGroupPairs: []*ec2.UserIDGroupPair{ - &ec2.UserIDGroupPair{ // Required - GroupID: aws.String("String"), + ToPort: aws.Int64(1), + UserIdGroupPairs: []*ec2.UserIdGroupPair{ + { // Required + GroupId: aws.String("String"), GroupName: aws.String("String"), - UserID: aws.String("String"), + UserId: aws.String("String"), }, // More values... }, }, // More values... }, - IPProtocol: aws.String("String"), + IpProtocol: aws.String("String"), SourceSecurityGroupName: aws.String("String"), - SourceSecurityGroupOwnerID: aws.String("String"), - ToPort: aws.Long(1), + SourceSecurityGroupOwnerId: aws.String("String"), + ToPort: aws.Int64(1), } resp, err := svc.RevokeSecurityGroupIngress(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_RunInstances() { svc := ec2.New(nil) params := &ec2.RunInstancesInput{ - ImageID: aws.String("String"), // Required - MaxCount: aws.Long(1), // Required - MinCount: aws.Long(1), // Required + ImageId: aws.String("String"), // Required + MaxCount: aws.Int64(1), // Required + MinCount: aws.Int64(1), // Required AdditionalInfo: aws.String("String"), BlockDeviceMappings: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ // Required + { // Required DeviceName: aws.String("String"), - EBS: &ec2.EBSBlockDevice{ - DeleteOnTermination: aws.Boolean(true), - Encrypted: aws.Boolean(true), - IOPS: aws.Long(1), - SnapshotID: aws.String("String"), - VolumeSize: aws.Long(1), + Ebs: &ec2.EbsBlockDevice{ + DeleteOnTermination: aws.Bool(true), + Encrypted: aws.Bool(true), + Iops: aws.Int64(1), + SnapshotId: aws.String("String"), + VolumeSize: aws.Int64(1), VolumeType: aws.String("VolumeType"), }, NoDevice: aws.String("String"), @@ -6276,41 +4977,41 @@ func ExampleEC2_RunInstances() { // More values... }, ClientToken: aws.String("String"), - DisableAPITermination: aws.Boolean(true), - DryRun: aws.Boolean(true), - EBSOptimized: aws.Boolean(true), - IAMInstanceProfile: &ec2.IAMInstanceProfileSpecification{ - ARN: aws.String("String"), + DisableApiTermination: aws.Bool(true), + DryRun: aws.Bool(true), + EbsOptimized: aws.Bool(true), + IamInstanceProfile: &ec2.IamInstanceProfileSpecification{ + Arn: aws.String("String"), Name: aws.String("String"), }, InstanceInitiatedShutdownBehavior: aws.String("ShutdownBehavior"), InstanceType: aws.String("InstanceType"), - KernelID: aws.String("String"), + KernelId: aws.String("String"), KeyName: aws.String("String"), Monitoring: &ec2.RunInstancesMonitoringEnabled{ - Enabled: aws.Boolean(true), // Required + Enabled: aws.Bool(true), // Required }, NetworkInterfaces: []*ec2.InstanceNetworkInterfaceSpecification{ - &ec2.InstanceNetworkInterfaceSpecification{ // Required - AssociatePublicIPAddress: aws.Boolean(true), - DeleteOnTermination: aws.Boolean(true), + { // Required + AssociatePublicIpAddress: aws.Bool(true), + DeleteOnTermination: aws.Bool(true), Description: aws.String("String"), - DeviceIndex: aws.Long(1), + DeviceIndex: aws.Int64(1), Groups: []*string{ aws.String("String"), // Required // More values... }, - NetworkInterfaceID: aws.String("String"), - PrivateIPAddress: aws.String("String"), - PrivateIPAddresses: []*ec2.PrivateIPAddressSpecification{ - &ec2.PrivateIPAddressSpecification{ // Required - PrivateIPAddress: aws.String("String"), // Required - Primary: aws.Boolean(true), + NetworkInterfaceId: aws.String("String"), + PrivateIpAddress: aws.String("String"), + PrivateIpAddresses: []*ec2.PrivateIpAddressSpecification{ + { // Required + PrivateIpAddress: aws.String("String"), // Required + Primary: aws.Bool(true), }, // More values... }, - SecondaryPrivateIPAddressCount: aws.Long(1), - SubnetID: aws.String("String"), + SecondaryPrivateIpAddressCount: aws.Int64(1), + SubnetId: aws.String("String"), }, // More values... }, @@ -6319,9 +5020,9 @@ func ExampleEC2_RunInstances() { GroupName: aws.String("String"), Tenancy: aws.String("Tenancy"), }, - PrivateIPAddress: aws.String("String"), - RAMDiskID: aws.String("String"), - SecurityGroupIDs: []*string{ + PrivateIpAddress: aws.String("String"), + RamdiskId: aws.String("String"), + SecurityGroupIds: []*string{ aws.String("String"), // Required // More values... }, @@ -6329,183 +5030,135 @@ func ExampleEC2_RunInstances() { aws.String("String"), // Required // More values... }, - SubnetID: aws.String("String"), + SubnetId: aws.String("String"), UserData: aws.String("String"), } resp, err := svc.RunInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_StartInstances() { svc := ec2.New(nil) params := &ec2.StartInstancesInput{ - InstanceIDs: []*string{ // Required + InstanceIds: []*string{ // Required aws.String("String"), // Required // More values... }, AdditionalInfo: aws.String("String"), - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.StartInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_StopInstances() { svc := ec2.New(nil) params := &ec2.StopInstancesInput{ - InstanceIDs: []*string{ // Required + InstanceIds: []*string{ // Required aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), - Force: aws.Boolean(true), + DryRun: aws.Bool(true), + Force: aws.Bool(true), } resp, err := svc.StopInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_TerminateInstances() { svc := ec2.New(nil) params := &ec2.TerminateInstancesInput{ - InstanceIDs: []*string{ // Required + InstanceIds: []*string{ // Required aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.TerminateInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } -func ExampleEC2_UnassignPrivateIPAddresses() { +func ExampleEC2_UnassignPrivateIpAddresses() { svc := ec2.New(nil) - params := &ec2.UnassignPrivateIPAddressesInput{ - NetworkInterfaceID: aws.String("String"), // Required - PrivateIPAddresses: []*string{ // Required + params := &ec2.UnassignPrivateIpAddressesInput{ + NetworkInterfaceId: aws.String("String"), // Required + PrivateIpAddresses: []*string{ // Required aws.String("String"), // Required // More values... }, } - resp, err := svc.UnassignPrivateIPAddresses(params) + resp, err := svc.UnassignPrivateIpAddresses(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleEC2_UnmonitorInstances() { svc := ec2.New(nil) params := &ec2.UnmonitorInstancesInput{ - InstanceIDs: []*string{ // Required + InstanceIds: []*string{ // Required aws.String("String"), // Required // More values... }, - DryRun: aws.Boolean(true), + DryRun: aws.Bool(true), } resp, err := svc.UnmonitorInstances(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/service.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/service.go index 792be71fb322..102c8fe026d7 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/service.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/service.go @@ -4,27 +4,36 @@ package ec2 import ( "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" + "github.com/aws/aws-sdk-go/aws/service/serviceinfo" "github.com/aws/aws-sdk-go/internal/protocol/ec2query" "github.com/aws/aws-sdk-go/internal/signer/v4" ) -// EC2 is a client for Amazon EC2. +// Amazon Elastic Compute Cloud (Amazon EC2) provides resizable computing capacity +// in the Amazon Web Services (AWS) cloud. Using Amazon EC2 eliminates your +// need to invest in hardware up front, so you can develop and deploy applications +// faster. type EC2 struct { - *aws.Service + *service.Service } // Used for custom service initialization logic -var initService func(*aws.Service) +var initService func(*service.Service) // Used for custom request initialization logic -var initRequest func(*aws.Request) +var initRequest func(*request.Request) // New returns a new EC2 client. func New(config *aws.Config) *EC2 { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "ec2", - APIVersion: "2015-04-15", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "ec2", + APIVersion: "2015-04-15", + }, } service.Initialize() @@ -45,8 +54,8 @@ func New(config *aws.Config) *EC2 { // newRequest creates a new request for a EC2 operation and runs any // custom request initialization. -func (c *EC2) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *EC2) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) // Run custom request initialization if present if initRequest != nil { diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/api.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/api.go index 18fa15edf227..14126085b6af 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/api.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/api.go @@ -4,32 +4,27 @@ package elb import ( - "sync" "time" - "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" ) -var oprw sync.Mutex +const opAddTags = "AddTags" // AddTagsRequest generates a request for the AddTags operation. -func (c *ELB) AddTagsRequest(input *AddTagsInput) (req *aws.Request, output *AddTagsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAddTags == nil { - opAddTags = &aws.Operation{ - Name: "AddTags", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) AddTagsRequest(input *AddTagsInput) (req *request.Request, output *AddTagsOutput) { + op := &request.Operation{ + Name: opAddTags, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &AddTagsInput{} } - req = c.newRequest(opAddTags, input, output) + req = c.newRequest(op, input, output) output = &AddTagsOutput{} req.Data = output return @@ -41,7 +36,7 @@ func (c *ELB) AddTagsRequest(input *AddTagsInput) (req *aws.Request, output *Add // Each tag consists of a key and an optional value. If a tag with the same // key is already associated with the load balancer, AddTags updates its value. // -// For more information, see Tagging (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#tagging-elb) +// For more information, see Tag Your Load Balancer (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/add-remove-tags.html) // in the Elastic Load Balancing Developer Guide. func (c *ELB) AddTags(input *AddTagsInput) (*AddTagsOutput, error) { req, out := c.AddTagsRequest(input) @@ -49,26 +44,21 @@ func (c *ELB) AddTags(input *AddTagsInput) (*AddTagsOutput, error) { return out, err } -var opAddTags *aws.Operation +const opApplySecurityGroupsToLoadBalancer = "ApplySecurityGroupsToLoadBalancer" // ApplySecurityGroupsToLoadBalancerRequest generates a request for the ApplySecurityGroupsToLoadBalancer operation. -func (c *ELB) ApplySecurityGroupsToLoadBalancerRequest(input *ApplySecurityGroupsToLoadBalancerInput) (req *aws.Request, output *ApplySecurityGroupsToLoadBalancerOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opApplySecurityGroupsToLoadBalancer == nil { - opApplySecurityGroupsToLoadBalancer = &aws.Operation{ - Name: "ApplySecurityGroupsToLoadBalancer", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) ApplySecurityGroupsToLoadBalancerRequest(input *ApplySecurityGroupsToLoadBalancerInput) (req *request.Request, output *ApplySecurityGroupsToLoadBalancerOutput) { + op := &request.Operation{ + Name: opApplySecurityGroupsToLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ApplySecurityGroupsToLoadBalancerInput{} } - req = c.newRequest(opApplySecurityGroupsToLoadBalancer, input, output) + req = c.newRequest(op, input, output) output = &ApplySecurityGroupsToLoadBalancerOutput{} req.Data = output return @@ -78,7 +68,7 @@ func (c *ELB) ApplySecurityGroupsToLoadBalancerRequest(input *ApplySecurityGroup // private cloud (VPC). The specified security groups override the previously // associated security groups. // -// For more information, see Manage Security Groups for Amazon VPC (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/USVPC_ApplySG.html) +// For more information, see Security Groups for Load Balancers in a VPC (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-security-groups.html#elb-vpc-security-groups) // in the Elastic Load Balancing Developer Guide. func (c *ELB) ApplySecurityGroupsToLoadBalancer(input *ApplySecurityGroupsToLoadBalancerInput) (*ApplySecurityGroupsToLoadBalancerOutput, error) { req, out := c.ApplySecurityGroupsToLoadBalancerRequest(input) @@ -86,26 +76,21 @@ func (c *ELB) ApplySecurityGroupsToLoadBalancer(input *ApplySecurityGroupsToLoad return out, err } -var opApplySecurityGroupsToLoadBalancer *aws.Operation +const opAttachLoadBalancerToSubnets = "AttachLoadBalancerToSubnets" // AttachLoadBalancerToSubnetsRequest generates a request for the AttachLoadBalancerToSubnets operation. -func (c *ELB) AttachLoadBalancerToSubnetsRequest(input *AttachLoadBalancerToSubnetsInput) (req *aws.Request, output *AttachLoadBalancerToSubnetsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opAttachLoadBalancerToSubnets == nil { - opAttachLoadBalancerToSubnets = &aws.Operation{ - Name: "AttachLoadBalancerToSubnets", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) AttachLoadBalancerToSubnetsRequest(input *AttachLoadBalancerToSubnetsInput) (req *request.Request, output *AttachLoadBalancerToSubnetsOutput) { + op := &request.Operation{ + Name: opAttachLoadBalancerToSubnets, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &AttachLoadBalancerToSubnetsInput{} } - req = c.newRequest(opAttachLoadBalancerToSubnets, input, output) + req = c.newRequest(op, input, output) output = &AttachLoadBalancerToSubnetsOutput{} req.Data = output return @@ -115,7 +100,8 @@ func (c *ELB) AttachLoadBalancerToSubnetsRequest(input *AttachLoadBalancerToSubn // load balancer. // // The load balancer evenly distributes requests across all registered subnets. -// For more information, see Elastic Load Balancing in Amazon VPC (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/UserScenariosForVPC.html) +// For more information, see Add or Remove Subnets for Your Load Balancer in +// a VPC (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-manage-subnets.html) // in the Elastic Load Balancing Developer Guide. func (c *ELB) AttachLoadBalancerToSubnets(input *AttachLoadBalancerToSubnetsInput) (*AttachLoadBalancerToSubnetsOutput, error) { req, out := c.AttachLoadBalancerToSubnetsRequest(input) @@ -123,26 +109,21 @@ func (c *ELB) AttachLoadBalancerToSubnets(input *AttachLoadBalancerToSubnetsInpu return out, err } -var opAttachLoadBalancerToSubnets *aws.Operation +const opConfigureHealthCheck = "ConfigureHealthCheck" // ConfigureHealthCheckRequest generates a request for the ConfigureHealthCheck operation. -func (c *ELB) ConfigureHealthCheckRequest(input *ConfigureHealthCheckInput) (req *aws.Request, output *ConfigureHealthCheckOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opConfigureHealthCheck == nil { - opConfigureHealthCheck = &aws.Operation{ - Name: "ConfigureHealthCheck", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) ConfigureHealthCheckRequest(input *ConfigureHealthCheckInput) (req *request.Request, output *ConfigureHealthCheckOutput) { + op := &request.Operation{ + Name: opConfigureHealthCheck, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ConfigureHealthCheckInput{} } - req = c.newRequest(opConfigureHealthCheck, input, output) + req = c.newRequest(op, input, output) output = &ConfigureHealthCheckOutput{} req.Data = output return @@ -151,7 +132,7 @@ func (c *ELB) ConfigureHealthCheckRequest(input *ConfigureHealthCheckInput) (req // Specifies the health check settings to use when evaluating the health state // of your back-end instances. // -// For more information, see Health Checks (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#healthcheck) +// For more information, see Configure Health Checks (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-healthchecks.html) // in the Elastic Load Balancing Developer Guide. func (c *ELB) ConfigureHealthCheck(input *ConfigureHealthCheckInput) (*ConfigureHealthCheckOutput, error) { req, out := c.ConfigureHealthCheckRequest(input) @@ -159,26 +140,21 @@ func (c *ELB) ConfigureHealthCheck(input *ConfigureHealthCheckInput) (*Configure return out, err } -var opConfigureHealthCheck *aws.Operation +const opCreateAppCookieStickinessPolicy = "CreateAppCookieStickinessPolicy" // CreateAppCookieStickinessPolicyRequest generates a request for the CreateAppCookieStickinessPolicy operation. -func (c *ELB) CreateAppCookieStickinessPolicyRequest(input *CreateAppCookieStickinessPolicyInput) (req *aws.Request, output *CreateAppCookieStickinessPolicyOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateAppCookieStickinessPolicy == nil { - opCreateAppCookieStickinessPolicy = &aws.Operation{ - Name: "CreateAppCookieStickinessPolicy", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) CreateAppCookieStickinessPolicyRequest(input *CreateAppCookieStickinessPolicyInput) (req *request.Request, output *CreateAppCookieStickinessPolicyOutput) { + op := &request.Operation{ + Name: opCreateAppCookieStickinessPolicy, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateAppCookieStickinessPolicyInput{} } - req = c.newRequest(opCreateAppCookieStickinessPolicy, input, output) + req = c.newRequest(op, input, output) output = &CreateAppCookieStickinessPolicyOutput{} req.Data = output return @@ -197,7 +173,7 @@ func (c *ELB) CreateAppCookieStickinessPolicyRequest(input *CreateAppCookieStick // If the application cookie is explicitly removed or expires, the session // stops being sticky until a new application cookie is issued. // -// For more information, see Application-Controlled Session Stickiness (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/US_StickySessions.html#US_EnableStickySessionsAppCookies) +// For more information, see Application-Controlled Session Stickiness (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-sticky-sessions.html#enable-sticky-sessions-application) // in the Elastic Load Balancing Developer Guide. func (c *ELB) CreateAppCookieStickinessPolicy(input *CreateAppCookieStickinessPolicyInput) (*CreateAppCookieStickinessPolicyOutput, error) { req, out := c.CreateAppCookieStickinessPolicyRequest(input) @@ -205,26 +181,21 @@ func (c *ELB) CreateAppCookieStickinessPolicy(input *CreateAppCookieStickinessPo return out, err } -var opCreateAppCookieStickinessPolicy *aws.Operation +const opCreateLBCookieStickinessPolicy = "CreateLBCookieStickinessPolicy" // CreateLBCookieStickinessPolicyRequest generates a request for the CreateLBCookieStickinessPolicy operation. -func (c *ELB) CreateLBCookieStickinessPolicyRequest(input *CreateLBCookieStickinessPolicyInput) (req *aws.Request, output *CreateLBCookieStickinessPolicyOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateLBCookieStickinessPolicy == nil { - opCreateLBCookieStickinessPolicy = &aws.Operation{ - Name: "CreateLBCookieStickinessPolicy", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) CreateLBCookieStickinessPolicyRequest(input *CreateLBCookieStickinessPolicyInput) (req *request.Request, output *CreateLBCookieStickinessPolicyOutput) { + op := &request.Operation{ + Name: opCreateLBCookieStickinessPolicy, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateLBCookieStickinessPolicyInput{} } - req = c.newRequest(opCreateLBCookieStickinessPolicy, input, output) + req = c.newRequest(op, input, output) output = &CreateLBCookieStickinessPolicyOutput{} req.Data = output return @@ -245,7 +216,7 @@ func (c *ELB) CreateLBCookieStickinessPolicyRequest(input *CreateLBCookieStickin // the same user to that server. The validity of the cookie is based on the // cookie expiration time, which is specified in the policy configuration. // -// For more information, see Duration-Based Session Stickiness (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/US_StickySessions.html#US_EnableStickySessionsLBCookies) +// For more information, see Duration-Based Session Stickiness (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-sticky-sessions.html#enable-sticky-sessions-duration) // in the Elastic Load Balancing Developer Guide. func (c *ELB) CreateLBCookieStickinessPolicy(input *CreateLBCookieStickinessPolicyInput) (*CreateLBCookieStickinessPolicyOutput, error) { req, out := c.CreateLBCookieStickinessPolicyRequest(input) @@ -253,26 +224,21 @@ func (c *ELB) CreateLBCookieStickinessPolicy(input *CreateLBCookieStickinessPoli return out, err } -var opCreateLBCookieStickinessPolicy *aws.Operation +const opCreateLoadBalancer = "CreateLoadBalancer" // CreateLoadBalancerRequest generates a request for the CreateLoadBalancer operation. -func (c *ELB) CreateLoadBalancerRequest(input *CreateLoadBalancerInput) (req *aws.Request, output *CreateLoadBalancerOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateLoadBalancer == nil { - opCreateLoadBalancer = &aws.Operation{ - Name: "CreateLoadBalancer", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) CreateLoadBalancerRequest(input *CreateLoadBalancerInput) (req *request.Request, output *CreateLoadBalancerOutput) { + op := &request.Operation{ + Name: opCreateLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateLoadBalancerInput{} } - req = c.newRequest(opCreateLoadBalancer, input, output) + req = c.newRequest(op, input, output) output = &CreateLoadBalancerOutput{} req.Data = output return @@ -281,51 +247,36 @@ func (c *ELB) CreateLoadBalancerRequest(input *CreateLoadBalancerInput) (req *aw // Creates a load balancer. // // If the call completes successfully, a new load balancer is created with -// a unique Domain Name Service (DNS) name. The DNS name includes the name of -// the AWS region in which the load balancer was created. For example, the DNS -// name might end with either of the following: -// -// us-east-1.elb.amazonaws.com us-west-2.elb.amazonaws.com For information -// about the AWS regions supported by Elastic Load Balancing, see Regions and -// Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#elb_region) -// in the Amazon Web Services General Reference. +// a unique Domain Name Service (DNS) name. The load balancer receives incoming +// traffic and routes it to the registered instances. For more information, +// see How Elastic Load Balancing Works (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/how-elb-works.html) +// in the Elastic Load Balancing Developer Guide. // // You can create up to 20 load balancers per region per account. You can request // an increase for the number of load balancers for your account. For more information, // see Elastic Load Balancing Limits (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-limits.html) // in the Elastic Load Balancing Developer Guide. -// -// Elastic Load Balancing supports load balancing your EC2 instances launched -// in either the EC2-Classic or EC2-VPC platform. For more information, see -// Elastic Load Balancing in EC2-Classic (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/UserScenariosForEC2.html) -// or Elastic Load Balancing in a VPC (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/UserScenariosForVPC.html) -// in the Elastic Load Balancing Developer Guide. func (c *ELB) CreateLoadBalancer(input *CreateLoadBalancerInput) (*CreateLoadBalancerOutput, error) { req, out := c.CreateLoadBalancerRequest(input) err := req.Send() return out, err } -var opCreateLoadBalancer *aws.Operation +const opCreateLoadBalancerListeners = "CreateLoadBalancerListeners" // CreateLoadBalancerListenersRequest generates a request for the CreateLoadBalancerListeners operation. -func (c *ELB) CreateLoadBalancerListenersRequest(input *CreateLoadBalancerListenersInput) (req *aws.Request, output *CreateLoadBalancerListenersOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateLoadBalancerListeners == nil { - opCreateLoadBalancerListeners = &aws.Operation{ - Name: "CreateLoadBalancerListeners", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) CreateLoadBalancerListenersRequest(input *CreateLoadBalancerListenersInput) (req *request.Request, output *CreateLoadBalancerListenersOutput) { + op := &request.Operation{ + Name: opCreateLoadBalancerListeners, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateLoadBalancerListenersInput{} } - req = c.newRequest(opCreateLoadBalancerListeners, input, output) + req = c.newRequest(op, input, output) output = &CreateLoadBalancerListenersOutput{} req.Data = output return @@ -344,26 +295,21 @@ func (c *ELB) CreateLoadBalancerListeners(input *CreateLoadBalancerListenersInpu return out, err } -var opCreateLoadBalancerListeners *aws.Operation +const opCreateLoadBalancerPolicy = "CreateLoadBalancerPolicy" // CreateLoadBalancerPolicyRequest generates a request for the CreateLoadBalancerPolicy operation. -func (c *ELB) CreateLoadBalancerPolicyRequest(input *CreateLoadBalancerPolicyInput) (req *aws.Request, output *CreateLoadBalancerPolicyOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opCreateLoadBalancerPolicy == nil { - opCreateLoadBalancerPolicy = &aws.Operation{ - Name: "CreateLoadBalancerPolicy", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) CreateLoadBalancerPolicyRequest(input *CreateLoadBalancerPolicyInput) (req *request.Request, output *CreateLoadBalancerPolicyOutput) { + op := &request.Operation{ + Name: opCreateLoadBalancerPolicy, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &CreateLoadBalancerPolicyInput{} } - req = c.newRequest(opCreateLoadBalancerPolicy, input, output) + req = c.newRequest(op, input, output) output = &CreateLoadBalancerPolicyOutput{} req.Data = output return @@ -380,26 +326,21 @@ func (c *ELB) CreateLoadBalancerPolicy(input *CreateLoadBalancerPolicyInput) (*C return out, err } -var opCreateLoadBalancerPolicy *aws.Operation +const opDeleteLoadBalancer = "DeleteLoadBalancer" // DeleteLoadBalancerRequest generates a request for the DeleteLoadBalancer operation. -func (c *ELB) DeleteLoadBalancerRequest(input *DeleteLoadBalancerInput) (req *aws.Request, output *DeleteLoadBalancerOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteLoadBalancer == nil { - opDeleteLoadBalancer = &aws.Operation{ - Name: "DeleteLoadBalancer", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) DeleteLoadBalancerRequest(input *DeleteLoadBalancerInput) (req *request.Request, output *DeleteLoadBalancerOutput) { + op := &request.Operation{ + Name: opDeleteLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteLoadBalancerInput{} } - req = c.newRequest(opDeleteLoadBalancer, input, output) + req = c.newRequest(op, input, output) output = &DeleteLoadBalancerOutput{} req.Data = output return @@ -421,26 +362,21 @@ func (c *ELB) DeleteLoadBalancer(input *DeleteLoadBalancerInput) (*DeleteLoadBal return out, err } -var opDeleteLoadBalancer *aws.Operation +const opDeleteLoadBalancerListeners = "DeleteLoadBalancerListeners" // DeleteLoadBalancerListenersRequest generates a request for the DeleteLoadBalancerListeners operation. -func (c *ELB) DeleteLoadBalancerListenersRequest(input *DeleteLoadBalancerListenersInput) (req *aws.Request, output *DeleteLoadBalancerListenersOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteLoadBalancerListeners == nil { - opDeleteLoadBalancerListeners = &aws.Operation{ - Name: "DeleteLoadBalancerListeners", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) DeleteLoadBalancerListenersRequest(input *DeleteLoadBalancerListenersInput) (req *request.Request, output *DeleteLoadBalancerListenersOutput) { + op := &request.Operation{ + Name: opDeleteLoadBalancerListeners, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteLoadBalancerListenersInput{} } - req = c.newRequest(opDeleteLoadBalancerListeners, input, output) + req = c.newRequest(op, input, output) output = &DeleteLoadBalancerListenersOutput{} req.Data = output return @@ -453,26 +389,21 @@ func (c *ELB) DeleteLoadBalancerListeners(input *DeleteLoadBalancerListenersInpu return out, err } -var opDeleteLoadBalancerListeners *aws.Operation +const opDeleteLoadBalancerPolicy = "DeleteLoadBalancerPolicy" // DeleteLoadBalancerPolicyRequest generates a request for the DeleteLoadBalancerPolicy operation. -func (c *ELB) DeleteLoadBalancerPolicyRequest(input *DeleteLoadBalancerPolicyInput) (req *aws.Request, output *DeleteLoadBalancerPolicyOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeleteLoadBalancerPolicy == nil { - opDeleteLoadBalancerPolicy = &aws.Operation{ - Name: "DeleteLoadBalancerPolicy", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) DeleteLoadBalancerPolicyRequest(input *DeleteLoadBalancerPolicyInput) (req *request.Request, output *DeleteLoadBalancerPolicyOutput) { + op := &request.Operation{ + Name: opDeleteLoadBalancerPolicy, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeleteLoadBalancerPolicyInput{} } - req = c.newRequest(opDeleteLoadBalancerPolicy, input, output) + req = c.newRequest(op, input, output) output = &DeleteLoadBalancerPolicyOutput{} req.Data = output return @@ -486,26 +417,21 @@ func (c *ELB) DeleteLoadBalancerPolicy(input *DeleteLoadBalancerPolicyInput) (*D return out, err } -var opDeleteLoadBalancerPolicy *aws.Operation +const opDeregisterInstancesFromLoadBalancer = "DeregisterInstancesFromLoadBalancer" // DeregisterInstancesFromLoadBalancerRequest generates a request for the DeregisterInstancesFromLoadBalancer operation. -func (c *ELB) DeregisterInstancesFromLoadBalancerRequest(input *DeregisterInstancesFromLoadBalancerInput) (req *aws.Request, output *DeregisterInstancesFromLoadBalancerOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDeregisterInstancesFromLoadBalancer == nil { - opDeregisterInstancesFromLoadBalancer = &aws.Operation{ - Name: "DeregisterInstancesFromLoadBalancer", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) DeregisterInstancesFromLoadBalancerRequest(input *DeregisterInstancesFromLoadBalancerInput) (req *request.Request, output *DeregisterInstancesFromLoadBalancerOutput) { + op := &request.Operation{ + Name: opDeregisterInstancesFromLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DeregisterInstancesFromLoadBalancerInput{} } - req = c.newRequest(opDeregisterInstancesFromLoadBalancer, input, output) + req = c.newRequest(op, input, output) output = &DeregisterInstancesFromLoadBalancerOutput{} req.Data = output return @@ -526,26 +452,21 @@ func (c *ELB) DeregisterInstancesFromLoadBalancer(input *DeregisterInstancesFrom return out, err } -var opDeregisterInstancesFromLoadBalancer *aws.Operation +const opDescribeInstanceHealth = "DescribeInstanceHealth" // DescribeInstanceHealthRequest generates a request for the DescribeInstanceHealth operation. -func (c *ELB) DescribeInstanceHealthRequest(input *DescribeInstanceHealthInput) (req *aws.Request, output *DescribeInstanceHealthOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeInstanceHealth == nil { - opDescribeInstanceHealth = &aws.Operation{ - Name: "DescribeInstanceHealth", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) DescribeInstanceHealthRequest(input *DescribeInstanceHealthInput) (req *request.Request, output *DescribeInstanceHealthOutput) { + op := &request.Operation{ + Name: opDescribeInstanceHealth, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeInstanceHealthInput{} } - req = c.newRequest(opDescribeInstanceHealth, input, output) + req = c.newRequest(op, input, output) output = &DescribeInstanceHealthOutput{} req.Data = output return @@ -561,26 +482,21 @@ func (c *ELB) DescribeInstanceHealth(input *DescribeInstanceHealthInput) (*Descr return out, err } -var opDescribeInstanceHealth *aws.Operation +const opDescribeLoadBalancerAttributes = "DescribeLoadBalancerAttributes" // DescribeLoadBalancerAttributesRequest generates a request for the DescribeLoadBalancerAttributes operation. -func (c *ELB) DescribeLoadBalancerAttributesRequest(input *DescribeLoadBalancerAttributesInput) (req *aws.Request, output *DescribeLoadBalancerAttributesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeLoadBalancerAttributes == nil { - opDescribeLoadBalancerAttributes = &aws.Operation{ - Name: "DescribeLoadBalancerAttributes", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) DescribeLoadBalancerAttributesRequest(input *DescribeLoadBalancerAttributesInput) (req *request.Request, output *DescribeLoadBalancerAttributesOutput) { + op := &request.Operation{ + Name: opDescribeLoadBalancerAttributes, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeLoadBalancerAttributesInput{} } - req = c.newRequest(opDescribeLoadBalancerAttributes, input, output) + req = c.newRequest(op, input, output) output = &DescribeLoadBalancerAttributesOutput{} req.Data = output return @@ -593,26 +509,21 @@ func (c *ELB) DescribeLoadBalancerAttributes(input *DescribeLoadBalancerAttribut return out, err } -var opDescribeLoadBalancerAttributes *aws.Operation +const opDescribeLoadBalancerPolicies = "DescribeLoadBalancerPolicies" // DescribeLoadBalancerPoliciesRequest generates a request for the DescribeLoadBalancerPolicies operation. -func (c *ELB) DescribeLoadBalancerPoliciesRequest(input *DescribeLoadBalancerPoliciesInput) (req *aws.Request, output *DescribeLoadBalancerPoliciesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeLoadBalancerPolicies == nil { - opDescribeLoadBalancerPolicies = &aws.Operation{ - Name: "DescribeLoadBalancerPolicies", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) DescribeLoadBalancerPoliciesRequest(input *DescribeLoadBalancerPoliciesInput) (req *request.Request, output *DescribeLoadBalancerPoliciesOutput) { + op := &request.Operation{ + Name: opDescribeLoadBalancerPolicies, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeLoadBalancerPoliciesInput{} } - req = c.newRequest(opDescribeLoadBalancerPolicies, input, output) + req = c.newRequest(op, input, output) output = &DescribeLoadBalancerPoliciesOutput{} req.Data = output return @@ -632,26 +543,21 @@ func (c *ELB) DescribeLoadBalancerPolicies(input *DescribeLoadBalancerPoliciesIn return out, err } -var opDescribeLoadBalancerPolicies *aws.Operation +const opDescribeLoadBalancerPolicyTypes = "DescribeLoadBalancerPolicyTypes" // DescribeLoadBalancerPolicyTypesRequest generates a request for the DescribeLoadBalancerPolicyTypes operation. -func (c *ELB) DescribeLoadBalancerPolicyTypesRequest(input *DescribeLoadBalancerPolicyTypesInput) (req *aws.Request, output *DescribeLoadBalancerPolicyTypesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeLoadBalancerPolicyTypes == nil { - opDescribeLoadBalancerPolicyTypes = &aws.Operation{ - Name: "DescribeLoadBalancerPolicyTypes", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) DescribeLoadBalancerPolicyTypesRequest(input *DescribeLoadBalancerPolicyTypesInput) (req *request.Request, output *DescribeLoadBalancerPolicyTypesOutput) { + op := &request.Operation{ + Name: opDescribeLoadBalancerPolicyTypes, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeLoadBalancerPolicyTypesInput{} } - req = c.newRequest(opDescribeLoadBalancerPolicyTypes, input, output) + req = c.newRequest(op, input, output) output = &DescribeLoadBalancerPolicyTypesOutput{} req.Data = output return @@ -667,32 +573,27 @@ func (c *ELB) DescribeLoadBalancerPolicyTypes(input *DescribeLoadBalancerPolicyT return out, err } -var opDescribeLoadBalancerPolicyTypes *aws.Operation +const opDescribeLoadBalancers = "DescribeLoadBalancers" // DescribeLoadBalancersRequest generates a request for the DescribeLoadBalancers operation. -func (c *ELB) DescribeLoadBalancersRequest(input *DescribeLoadBalancersInput) (req *aws.Request, output *DescribeLoadBalancersOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeLoadBalancers == nil { - opDescribeLoadBalancers = &aws.Operation{ - Name: "DescribeLoadBalancers", - HTTPMethod: "POST", - HTTPPath: "/", - Paginator: &aws.Paginator{ - InputTokens: []string{"Marker"}, - OutputTokens: []string{"NextMarker"}, - LimitToken: "", - TruncationToken: "", - }, - } +func (c *ELB) DescribeLoadBalancersRequest(input *DescribeLoadBalancersInput) (req *request.Request, output *DescribeLoadBalancersOutput) { + op := &request.Operation{ + Name: opDescribeLoadBalancers, + HTTPMethod: "POST", + HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"Marker"}, + OutputTokens: []string{"NextMarker"}, + LimitToken: "", + TruncationToken: "", + }, } if input == nil { input = &DescribeLoadBalancersInput{} } - req = c.newRequest(opDescribeLoadBalancers, input, output) + req = c.newRequest(op, input, output) output = &DescribeLoadBalancersOutput{} req.Data = output return @@ -713,26 +614,21 @@ func (c *ELB) DescribeLoadBalancersPages(input *DescribeLoadBalancersInput, fn f }) } -var opDescribeLoadBalancers *aws.Operation +const opDescribeTags = "DescribeTags" // DescribeTagsRequest generates a request for the DescribeTags operation. -func (c *ELB) DescribeTagsRequest(input *DescribeTagsInput) (req *aws.Request, output *DescribeTagsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDescribeTags == nil { - opDescribeTags = &aws.Operation{ - Name: "DescribeTags", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) DescribeTagsRequest(input *DescribeTagsInput) (req *request.Request, output *DescribeTagsOutput) { + op := &request.Operation{ + Name: opDescribeTags, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DescribeTagsInput{} } - req = c.newRequest(opDescribeTags, input, output) + req = c.newRequest(op, input, output) output = &DescribeTagsOutput{} req.Data = output return @@ -745,26 +641,21 @@ func (c *ELB) DescribeTags(input *DescribeTagsInput) (*DescribeTagsOutput, error return out, err } -var opDescribeTags *aws.Operation +const opDetachLoadBalancerFromSubnets = "DetachLoadBalancerFromSubnets" // DetachLoadBalancerFromSubnetsRequest generates a request for the DetachLoadBalancerFromSubnets operation. -func (c *ELB) DetachLoadBalancerFromSubnetsRequest(input *DetachLoadBalancerFromSubnetsInput) (req *aws.Request, output *DetachLoadBalancerFromSubnetsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDetachLoadBalancerFromSubnets == nil { - opDetachLoadBalancerFromSubnets = &aws.Operation{ - Name: "DetachLoadBalancerFromSubnets", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) DetachLoadBalancerFromSubnetsRequest(input *DetachLoadBalancerFromSubnetsInput) (req *request.Request, output *DetachLoadBalancerFromSubnetsOutput) { + op := &request.Operation{ + Name: opDetachLoadBalancerFromSubnets, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DetachLoadBalancerFromSubnetsInput{} } - req = c.newRequest(opDetachLoadBalancerFromSubnets, input, output) + req = c.newRequest(op, input, output) output = &DetachLoadBalancerFromSubnetsOutput{} req.Data = output return @@ -782,26 +673,21 @@ func (c *ELB) DetachLoadBalancerFromSubnets(input *DetachLoadBalancerFromSubnets return out, err } -var opDetachLoadBalancerFromSubnets *aws.Operation +const opDisableAvailabilityZonesForLoadBalancer = "DisableAvailabilityZonesForLoadBalancer" // DisableAvailabilityZonesForLoadBalancerRequest generates a request for the DisableAvailabilityZonesForLoadBalancer operation. -func (c *ELB) DisableAvailabilityZonesForLoadBalancerRequest(input *DisableAvailabilityZonesForLoadBalancerInput) (req *aws.Request, output *DisableAvailabilityZonesForLoadBalancerOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opDisableAvailabilityZonesForLoadBalancer == nil { - opDisableAvailabilityZonesForLoadBalancer = &aws.Operation{ - Name: "DisableAvailabilityZonesForLoadBalancer", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) DisableAvailabilityZonesForLoadBalancerRequest(input *DisableAvailabilityZonesForLoadBalancerInput) (req *request.Request, output *DisableAvailabilityZonesForLoadBalancerOutput) { + op := &request.Operation{ + Name: opDisableAvailabilityZonesForLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &DisableAvailabilityZonesForLoadBalancerInput{} } - req = c.newRequest(opDisableAvailabilityZonesForLoadBalancer, input, output) + req = c.newRequest(op, input, output) output = &DisableAvailabilityZonesForLoadBalancerOutput{} req.Data = output return @@ -825,26 +711,21 @@ func (c *ELB) DisableAvailabilityZonesForLoadBalancer(input *DisableAvailability return out, err } -var opDisableAvailabilityZonesForLoadBalancer *aws.Operation +const opEnableAvailabilityZonesForLoadBalancer = "EnableAvailabilityZonesForLoadBalancer" // EnableAvailabilityZonesForLoadBalancerRequest generates a request for the EnableAvailabilityZonesForLoadBalancer operation. -func (c *ELB) EnableAvailabilityZonesForLoadBalancerRequest(input *EnableAvailabilityZonesForLoadBalancerInput) (req *aws.Request, output *EnableAvailabilityZonesForLoadBalancerOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opEnableAvailabilityZonesForLoadBalancer == nil { - opEnableAvailabilityZonesForLoadBalancer = &aws.Operation{ - Name: "EnableAvailabilityZonesForLoadBalancer", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) EnableAvailabilityZonesForLoadBalancerRequest(input *EnableAvailabilityZonesForLoadBalancerInput) (req *request.Request, output *EnableAvailabilityZonesForLoadBalancerOutput) { + op := &request.Operation{ + Name: opEnableAvailabilityZonesForLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &EnableAvailabilityZonesForLoadBalancerInput{} } - req = c.newRequest(opEnableAvailabilityZonesForLoadBalancer, input, output) + req = c.newRequest(op, input, output) output = &EnableAvailabilityZonesForLoadBalancerOutput{} req.Data = output return @@ -864,26 +745,21 @@ func (c *ELB) EnableAvailabilityZonesForLoadBalancer(input *EnableAvailabilityZo return out, err } -var opEnableAvailabilityZonesForLoadBalancer *aws.Operation +const opModifyLoadBalancerAttributes = "ModifyLoadBalancerAttributes" // ModifyLoadBalancerAttributesRequest generates a request for the ModifyLoadBalancerAttributes operation. -func (c *ELB) ModifyLoadBalancerAttributesRequest(input *ModifyLoadBalancerAttributesInput) (req *aws.Request, output *ModifyLoadBalancerAttributesOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opModifyLoadBalancerAttributes == nil { - opModifyLoadBalancerAttributes = &aws.Operation{ - Name: "ModifyLoadBalancerAttributes", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) ModifyLoadBalancerAttributesRequest(input *ModifyLoadBalancerAttributesInput) (req *request.Request, output *ModifyLoadBalancerAttributesOutput) { + op := &request.Operation{ + Name: opModifyLoadBalancerAttributes, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &ModifyLoadBalancerAttributesInput{} } - req = c.newRequest(opModifyLoadBalancerAttributes, input, output) + req = c.newRequest(op, input, output) output = &ModifyLoadBalancerAttributesOutput{} req.Data = output return @@ -909,26 +785,21 @@ func (c *ELB) ModifyLoadBalancerAttributes(input *ModifyLoadBalancerAttributesIn return out, err } -var opModifyLoadBalancerAttributes *aws.Operation +const opRegisterInstancesWithLoadBalancer = "RegisterInstancesWithLoadBalancer" // RegisterInstancesWithLoadBalancerRequest generates a request for the RegisterInstancesWithLoadBalancer operation. -func (c *ELB) RegisterInstancesWithLoadBalancerRequest(input *RegisterInstancesWithLoadBalancerInput) (req *aws.Request, output *RegisterInstancesWithLoadBalancerOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opRegisterInstancesWithLoadBalancer == nil { - opRegisterInstancesWithLoadBalancer = &aws.Operation{ - Name: "RegisterInstancesWithLoadBalancer", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) RegisterInstancesWithLoadBalancerRequest(input *RegisterInstancesWithLoadBalancerInput) (req *request.Request, output *RegisterInstancesWithLoadBalancerOutput) { + op := &request.Operation{ + Name: opRegisterInstancesWithLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &RegisterInstancesWithLoadBalancerInput{} } - req = c.newRequest(opRegisterInstancesWithLoadBalancer, input, output) + req = c.newRequest(op, input, output) output = &RegisterInstancesWithLoadBalancerOutput{} req.Data = output return @@ -967,26 +838,21 @@ func (c *ELB) RegisterInstancesWithLoadBalancer(input *RegisterInstancesWithLoad return out, err } -var opRegisterInstancesWithLoadBalancer *aws.Operation +const opRemoveTags = "RemoveTags" // RemoveTagsRequest generates a request for the RemoveTags operation. -func (c *ELB) RemoveTagsRequest(input *RemoveTagsInput) (req *aws.Request, output *RemoveTagsOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opRemoveTags == nil { - opRemoveTags = &aws.Operation{ - Name: "RemoveTags", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) RemoveTagsRequest(input *RemoveTagsInput) (req *request.Request, output *RemoveTagsOutput) { + op := &request.Operation{ + Name: opRemoveTags, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &RemoveTagsInput{} } - req = c.newRequest(opRemoveTags, input, output) + req = c.newRequest(op, input, output) output = &RemoveTagsOutput{} req.Data = output return @@ -999,26 +865,21 @@ func (c *ELB) RemoveTags(input *RemoveTagsInput) (*RemoveTagsOutput, error) { return out, err } -var opRemoveTags *aws.Operation +const opSetLoadBalancerListenerSSLCertificate = "SetLoadBalancerListenerSSLCertificate" // SetLoadBalancerListenerSSLCertificateRequest generates a request for the SetLoadBalancerListenerSSLCertificate operation. -func (c *ELB) SetLoadBalancerListenerSSLCertificateRequest(input *SetLoadBalancerListenerSSLCertificateInput) (req *aws.Request, output *SetLoadBalancerListenerSSLCertificateOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opSetLoadBalancerListenerSSLCertificate == nil { - opSetLoadBalancerListenerSSLCertificate = &aws.Operation{ - Name: "SetLoadBalancerListenerSSLCertificate", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) SetLoadBalancerListenerSSLCertificateRequest(input *SetLoadBalancerListenerSSLCertificateInput) (req *request.Request, output *SetLoadBalancerListenerSSLCertificateOutput) { + op := &request.Operation{ + Name: opSetLoadBalancerListenerSSLCertificate, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &SetLoadBalancerListenerSSLCertificateInput{} } - req = c.newRequest(opSetLoadBalancerListenerSSLCertificate, input, output) + req = c.newRequest(op, input, output) output = &SetLoadBalancerListenerSSLCertificateOutput{} req.Data = output return @@ -1037,26 +898,21 @@ func (c *ELB) SetLoadBalancerListenerSSLCertificate(input *SetLoadBalancerListen return out, err } -var opSetLoadBalancerListenerSSLCertificate *aws.Operation +const opSetLoadBalancerPoliciesForBackendServer = "SetLoadBalancerPoliciesForBackendServer" // SetLoadBalancerPoliciesForBackendServerRequest generates a request for the SetLoadBalancerPoliciesForBackendServer operation. -func (c *ELB) SetLoadBalancerPoliciesForBackendServerRequest(input *SetLoadBalancerPoliciesForBackendServerInput) (req *aws.Request, output *SetLoadBalancerPoliciesForBackendServerOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opSetLoadBalancerPoliciesForBackendServer == nil { - opSetLoadBalancerPoliciesForBackendServer = &aws.Operation{ - Name: "SetLoadBalancerPoliciesForBackendServer", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) SetLoadBalancerPoliciesForBackendServerRequest(input *SetLoadBalancerPoliciesForBackendServerInput) (req *request.Request, output *SetLoadBalancerPoliciesForBackendServerOutput) { + op := &request.Operation{ + Name: opSetLoadBalancerPoliciesForBackendServer, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &SetLoadBalancerPoliciesForBackendServerInput{} } - req = c.newRequest(opSetLoadBalancerPoliciesForBackendServer, input, output) + req = c.newRequest(op, input, output) output = &SetLoadBalancerPoliciesForBackendServerOutput{} req.Data = output return @@ -1079,26 +935,21 @@ func (c *ELB) SetLoadBalancerPoliciesForBackendServer(input *SetLoadBalancerPoli return out, err } -var opSetLoadBalancerPoliciesForBackendServer *aws.Operation +const opSetLoadBalancerPoliciesOfListener = "SetLoadBalancerPoliciesOfListener" // SetLoadBalancerPoliciesOfListenerRequest generates a request for the SetLoadBalancerPoliciesOfListener operation. -func (c *ELB) SetLoadBalancerPoliciesOfListenerRequest(input *SetLoadBalancerPoliciesOfListenerInput) (req *aws.Request, output *SetLoadBalancerPoliciesOfListenerOutput) { - oprw.Lock() - defer oprw.Unlock() - - if opSetLoadBalancerPoliciesOfListener == nil { - opSetLoadBalancerPoliciesOfListener = &aws.Operation{ - Name: "SetLoadBalancerPoliciesOfListener", - HTTPMethod: "POST", - HTTPPath: "/", - } +func (c *ELB) SetLoadBalancerPoliciesOfListenerRequest(input *SetLoadBalancerPoliciesOfListenerInput) (req *request.Request, output *SetLoadBalancerPoliciesOfListenerOutput) { + op := &request.Operation{ + Name: opSetLoadBalancerPoliciesOfListener, + HTTPMethod: "POST", + HTTPPath: "/", } if input == nil { input = &SetLoadBalancerPoliciesOfListenerInput{} } - req = c.newRequest(opSetLoadBalancerPoliciesOfListener, input, output) + req = c.newRequest(op, input, output) output = &SetLoadBalancerPoliciesOfListenerOutput{} req.Data = output return @@ -1112,8 +963,6 @@ func (c *ELB) SetLoadBalancerPoliciesOfListener(input *SetLoadBalancerPoliciesOf return out, err } -var opSetLoadBalancerPoliciesOfListener *aws.Operation - // Information about the AccessLog attribute. type AccessLog struct { // The interval for publishing the access logs. You can specify an interval @@ -1140,12 +989,22 @@ type metadataAccessLog struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AccessLog) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AccessLog) GoString() string { + return s.String() +} + type AddTagsInput struct { // The name of the load balancer. You can specify one load balancer only. LoadBalancerNames []*string `type:"list" required:"true"` // The tags. - Tags []*Tag `type:"list" required:"true"` + Tags []*Tag `min:"1" type:"list" required:"true"` metadataAddTagsInput `json:"-" xml:"-"` } @@ -1154,6 +1013,16 @@ type metadataAddTagsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AddTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AddTagsInput) GoString() string { + return s.String() +} + type AddTagsOutput struct { metadataAddTagsOutput `json:"-" xml:"-"` } @@ -1162,6 +1031,16 @@ type metadataAddTagsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AddTagsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AddTagsOutput) GoString() string { + return s.String() +} + // This data type is reserved. type AdditionalAttribute struct { // This parameter is reserved. @@ -1177,6 +1056,16 @@ type metadataAdditionalAttribute struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AdditionalAttribute) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AdditionalAttribute) GoString() string { + return s.String() +} + // Information about a policy for application-controlled session stickiness. type AppCookieStickinessPolicy struct { // The name of the application cookie used for stickiness. @@ -1193,6 +1082,16 @@ type metadataAppCookieStickinessPolicy struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AppCookieStickinessPolicy) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AppCookieStickinessPolicy) GoString() string { + return s.String() +} + type ApplySecurityGroupsToLoadBalancerInput struct { // The name of the load balancer. LoadBalancerName *string `type:"string" required:"true"` @@ -1208,6 +1107,16 @@ type metadataApplySecurityGroupsToLoadBalancerInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ApplySecurityGroupsToLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ApplySecurityGroupsToLoadBalancerInput) GoString() string { + return s.String() +} + type ApplySecurityGroupsToLoadBalancerOutput struct { // The IDs of the security groups associated with the load balancer. SecurityGroups []*string `type:"list"` @@ -1219,6 +1128,16 @@ type metadataApplySecurityGroupsToLoadBalancerOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ApplySecurityGroupsToLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ApplySecurityGroupsToLoadBalancerOutput) GoString() string { + return s.String() +} + type AttachLoadBalancerToSubnetsInput struct { // The name of the load balancer. LoadBalancerName *string `type:"string" required:"true"` @@ -1234,6 +1153,16 @@ type metadataAttachLoadBalancerToSubnetsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AttachLoadBalancerToSubnetsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachLoadBalancerToSubnetsInput) GoString() string { + return s.String() +} + type AttachLoadBalancerToSubnetsOutput struct { // The IDs of the subnets attached to the load balancer. Subnets []*string `type:"list"` @@ -1245,10 +1174,20 @@ type metadataAttachLoadBalancerToSubnetsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s AttachLoadBalancerToSubnetsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachLoadBalancerToSubnetsOutput) GoString() string { + return s.String() +} + // Information about the configuration of a back-end server. type BackendServerDescription struct { // The port on which the back-end server is listening. - InstancePort *int64 `type:"integer"` + InstancePort *int64 `min:"1" type:"integer"` // The names of the policies enabled for the back-end server. PolicyNames []*string `type:"list"` @@ -1260,6 +1199,16 @@ type metadataBackendServerDescription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s BackendServerDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BackendServerDescription) GoString() string { + return s.String() +} + type ConfigureHealthCheckInput struct { // The configuration information for the new health check. HealthCheck *HealthCheck `type:"structure" required:"true"` @@ -1274,6 +1223,16 @@ type metadataConfigureHealthCheckInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ConfigureHealthCheckInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConfigureHealthCheckInput) GoString() string { + return s.String() +} + type ConfigureHealthCheckOutput struct { // The updated health check. HealthCheck *HealthCheck `type:"structure"` @@ -1285,6 +1244,16 @@ type metadataConfigureHealthCheckOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ConfigureHealthCheckOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConfigureHealthCheckOutput) GoString() string { + return s.String() +} + // Information about the ConnectionDraining attribute. type ConnectionDraining struct { // Specifies whether connection draining is enabled for the load balancer. @@ -1301,11 +1270,21 @@ type metadataConnectionDraining struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ConnectionDraining) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConnectionDraining) GoString() string { + return s.String() +} + // Information about the ConnectionSettings attribute. type ConnectionSettings struct { // The time, in seconds, that the connection is allowed to be idle (no data // has been sent over the connection) before it is closed by the load balancer. - IdleTimeout *int64 `type:"integer" required:"true"` + IdleTimeout *int64 `min:"1" type:"integer" required:"true"` metadataConnectionSettings `json:"-" xml:"-"` } @@ -1314,6 +1293,16 @@ type metadataConnectionSettings struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ConnectionSettings) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConnectionSettings) GoString() string { + return s.String() +} + type CreateAppCookieStickinessPolicyInput struct { // The name of the application cookie used for stickiness. CookieName *string `type:"string" required:"true"` @@ -1332,6 +1321,16 @@ type metadataCreateAppCookieStickinessPolicyInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateAppCookieStickinessPolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateAppCookieStickinessPolicyInput) GoString() string { + return s.String() +} + type CreateAppCookieStickinessPolicyOutput struct { metadataCreateAppCookieStickinessPolicyOutput `json:"-" xml:"-"` } @@ -1340,6 +1339,16 @@ type metadataCreateAppCookieStickinessPolicyOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateAppCookieStickinessPolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateAppCookieStickinessPolicyOutput) GoString() string { + return s.String() +} + type CreateLBCookieStickinessPolicyInput struct { // The time period, in seconds, after which the cookie should be considered // stale. If you do not specify this parameter, the sticky session lasts for @@ -1360,6 +1369,16 @@ type metadataCreateLBCookieStickinessPolicyInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateLBCookieStickinessPolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLBCookieStickinessPolicyInput) GoString() string { + return s.String() +} + type CreateLBCookieStickinessPolicyOutput struct { metadataCreateLBCookieStickinessPolicyOutput `json:"-" xml:"-"` } @@ -1368,6 +1387,16 @@ type metadataCreateLBCookieStickinessPolicyOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateLBCookieStickinessPolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLBCookieStickinessPolicyOutput) GoString() string { + return s.String() +} + type CreateLoadBalancerInput struct { // One or more Availability Zones from the same region as the load balancer. // Traffic is equally distributed across all specified Availability Zones. @@ -1380,8 +1409,7 @@ type CreateLoadBalancerInput struct { // The listeners. // - // For more information, see Listener Configurations for Elastic Load Balancing - // (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-listener-config.html) + // For more information, see Listeners for Your Load Balancer (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-listener-config.html) // in the Elastic Load Balancing Developer Guide. Listeners []*Listener `type:"list" required:"true"` @@ -1415,7 +1443,7 @@ type CreateLoadBalancerInput struct { // // For more information about tagging your load balancer, see Tagging (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#tagging-elb) // in the Elastic Load Balancing Developer Guide. - Tags []*Tag `type:"list"` + Tags []*Tag `min:"1" type:"list"` metadataCreateLoadBalancerInput `json:"-" xml:"-"` } @@ -1424,6 +1452,16 @@ type metadataCreateLoadBalancerInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLoadBalancerInput) GoString() string { + return s.String() +} + type CreateLoadBalancerListenersInput struct { // The listeners. Listeners []*Listener `type:"list" required:"true"` @@ -1438,6 +1476,16 @@ type metadataCreateLoadBalancerListenersInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateLoadBalancerListenersInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLoadBalancerListenersInput) GoString() string { + return s.String() +} + type CreateLoadBalancerListenersOutput struct { metadataCreateLoadBalancerListenersOutput `json:"-" xml:"-"` } @@ -1446,6 +1494,16 @@ type metadataCreateLoadBalancerListenersOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateLoadBalancerListenersOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLoadBalancerListenersOutput) GoString() string { + return s.String() +} + type CreateLoadBalancerOutput struct { // The DNS name of the load balancer. DNSName *string `type:"string"` @@ -1457,6 +1515,16 @@ type metadataCreateLoadBalancerOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLoadBalancerOutput) GoString() string { + return s.String() +} + type CreateLoadBalancerPolicyInput struct { // The name of the load balancer. LoadBalancerName *string `type:"string" required:"true"` @@ -1478,6 +1546,16 @@ type metadataCreateLoadBalancerPolicyInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateLoadBalancerPolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLoadBalancerPolicyInput) GoString() string { + return s.String() +} + type CreateLoadBalancerPolicyOutput struct { metadataCreateLoadBalancerPolicyOutput `json:"-" xml:"-"` } @@ -1486,6 +1564,16 @@ type metadataCreateLoadBalancerPolicyOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CreateLoadBalancerPolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLoadBalancerPolicyOutput) GoString() string { + return s.String() +} + // Information about the CrossZoneLoadBalancing attribute. type CrossZoneLoadBalancing struct { // Specifies whether cross-zone load balancing is enabled for the load balancer. @@ -1498,6 +1586,16 @@ type metadataCrossZoneLoadBalancing struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s CrossZoneLoadBalancing) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CrossZoneLoadBalancing) GoString() string { + return s.String() +} + type DeleteLoadBalancerInput struct { // The name of the load balancer. LoadBalancerName *string `type:"string" required:"true"` @@ -1509,6 +1607,16 @@ type metadataDeleteLoadBalancerInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLoadBalancerInput) GoString() string { + return s.String() +} + type DeleteLoadBalancerListenersInput struct { // The name of the load balancer. LoadBalancerName *string `type:"string" required:"true"` @@ -1523,6 +1631,16 @@ type metadataDeleteLoadBalancerListenersInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteLoadBalancerListenersInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLoadBalancerListenersInput) GoString() string { + return s.String() +} + type DeleteLoadBalancerListenersOutput struct { metadataDeleteLoadBalancerListenersOutput `json:"-" xml:"-"` } @@ -1531,6 +1649,16 @@ type metadataDeleteLoadBalancerListenersOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteLoadBalancerListenersOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLoadBalancerListenersOutput) GoString() string { + return s.String() +} + type DeleteLoadBalancerOutput struct { metadataDeleteLoadBalancerOutput `json:"-" xml:"-"` } @@ -1539,6 +1667,16 @@ type metadataDeleteLoadBalancerOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLoadBalancerOutput) GoString() string { + return s.String() +} + // = type DeleteLoadBalancerPolicyInput struct { // The name of the load balancer. @@ -1554,6 +1692,16 @@ type metadataDeleteLoadBalancerPolicyInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteLoadBalancerPolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLoadBalancerPolicyInput) GoString() string { + return s.String() +} + type DeleteLoadBalancerPolicyOutput struct { metadataDeleteLoadBalancerPolicyOutput `json:"-" xml:"-"` } @@ -1562,6 +1710,16 @@ type metadataDeleteLoadBalancerPolicyOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeleteLoadBalancerPolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLoadBalancerPolicyOutput) GoString() string { + return s.String() +} + type DeregisterInstancesFromLoadBalancerInput struct { // The IDs of the instances. Instances []*Instance `type:"list" required:"true"` @@ -1576,6 +1734,16 @@ type metadataDeregisterInstancesFromLoadBalancerInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeregisterInstancesFromLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeregisterInstancesFromLoadBalancerInput) GoString() string { + return s.String() +} + type DeregisterInstancesFromLoadBalancerOutput struct { // The remaining instances registered with the load balancer. Instances []*Instance `type:"list"` @@ -1587,6 +1755,16 @@ type metadataDeregisterInstancesFromLoadBalancerOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DeregisterInstancesFromLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeregisterInstancesFromLoadBalancerOutput) GoString() string { + return s.String() +} + type DescribeInstanceHealthInput struct { // The IDs of the instances. Instances []*Instance `type:"list"` @@ -1601,6 +1779,16 @@ type metadataDescribeInstanceHealthInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeInstanceHealthInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceHealthInput) GoString() string { + return s.String() +} + type DescribeInstanceHealthOutput struct { // Information about the health of the instances. InstanceStates []*InstanceState `type:"list"` @@ -1612,6 +1800,16 @@ type metadataDescribeInstanceHealthOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeInstanceHealthOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceHealthOutput) GoString() string { + return s.String() +} + type DescribeLoadBalancerAttributesInput struct { // The name of the load balancer. LoadBalancerName *string `type:"string" required:"true"` @@ -1623,6 +1821,16 @@ type metadataDescribeLoadBalancerAttributesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLoadBalancerAttributesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLoadBalancerAttributesInput) GoString() string { + return s.String() +} + type DescribeLoadBalancerAttributesOutput struct { // Information about the load balancer attributes. LoadBalancerAttributes *LoadBalancerAttributes `type:"structure"` @@ -1634,6 +1842,16 @@ type metadataDescribeLoadBalancerAttributesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLoadBalancerAttributesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLoadBalancerAttributesOutput) GoString() string { + return s.String() +} + type DescribeLoadBalancerPoliciesInput struct { // The name of the load balancer. LoadBalancerName *string `type:"string"` @@ -1648,6 +1866,16 @@ type metadataDescribeLoadBalancerPoliciesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLoadBalancerPoliciesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLoadBalancerPoliciesInput) GoString() string { + return s.String() +} + type DescribeLoadBalancerPoliciesOutput struct { // Information about the policies. PolicyDescriptions []*PolicyDescription `type:"list"` @@ -1659,6 +1887,16 @@ type metadataDescribeLoadBalancerPoliciesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLoadBalancerPoliciesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLoadBalancerPoliciesOutput) GoString() string { + return s.String() +} + type DescribeLoadBalancerPolicyTypesInput struct { // The names of the policy types. If no names are specified, describes all policy // types defined by Elastic Load Balancing. @@ -1671,6 +1909,16 @@ type metadataDescribeLoadBalancerPolicyTypesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLoadBalancerPolicyTypesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLoadBalancerPolicyTypesInput) GoString() string { + return s.String() +} + type DescribeLoadBalancerPolicyTypesOutput struct { // Information about the policy types. PolicyTypeDescriptions []*PolicyTypeDescription `type:"list"` @@ -1682,6 +1930,16 @@ type metadataDescribeLoadBalancerPolicyTypesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLoadBalancerPolicyTypesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLoadBalancerPolicyTypesOutput) GoString() string { + return s.String() +} + type DescribeLoadBalancersInput struct { // The names of the load balancers. LoadBalancerNames []*string `type:"list"` @@ -1692,7 +1950,7 @@ type DescribeLoadBalancersInput struct { // The maximum number of results to return with this call (a number from 1 to // 400). The default is 400. - PageSize *int64 `type:"integer"` + PageSize *int64 `min:"1" type:"integer"` metadataDescribeLoadBalancersInput `json:"-" xml:"-"` } @@ -1701,6 +1959,16 @@ type metadataDescribeLoadBalancersInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLoadBalancersInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLoadBalancersInput) GoString() string { + return s.String() +} + type DescribeLoadBalancersOutput struct { // Information about the load balancers. LoadBalancerDescriptions []*LoadBalancerDescription `type:"list"` @@ -1716,9 +1984,19 @@ type metadataDescribeLoadBalancersOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeLoadBalancersOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLoadBalancersOutput) GoString() string { + return s.String() +} + type DescribeTagsInput struct { // The names of the load balancers. - LoadBalancerNames []*string `type:"list" required:"true"` + LoadBalancerNames []*string `min:"1" type:"list" required:"true"` metadataDescribeTagsInput `json:"-" xml:"-"` } @@ -1727,6 +2005,16 @@ type metadataDescribeTagsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeTagsInput) GoString() string { + return s.String() +} + type DescribeTagsOutput struct { // Information about the tags. TagDescriptions []*TagDescription `type:"list"` @@ -1738,6 +2026,16 @@ type metadataDescribeTagsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DescribeTagsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeTagsOutput) GoString() string { + return s.String() +} + type DetachLoadBalancerFromSubnetsInput struct { // The name of the load balancer. LoadBalancerName *string `type:"string" required:"true"` @@ -1752,6 +2050,16 @@ type metadataDetachLoadBalancerFromSubnetsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DetachLoadBalancerFromSubnetsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachLoadBalancerFromSubnetsInput) GoString() string { + return s.String() +} + type DetachLoadBalancerFromSubnetsOutput struct { // The IDs of the remaining subnets for the load balancer. Subnets []*string `type:"list"` @@ -1763,6 +2071,16 @@ type metadataDetachLoadBalancerFromSubnetsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DetachLoadBalancerFromSubnetsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachLoadBalancerFromSubnetsOutput) GoString() string { + return s.String() +} + type DisableAvailabilityZonesForLoadBalancerInput struct { // The Availability Zones. AvailabilityZones []*string `type:"list" required:"true"` @@ -1777,6 +2095,16 @@ type metadataDisableAvailabilityZonesForLoadBalancerInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DisableAvailabilityZonesForLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableAvailabilityZonesForLoadBalancerInput) GoString() string { + return s.String() +} + type DisableAvailabilityZonesForLoadBalancerOutput struct { // The remaining Availability Zones for the load balancer. AvailabilityZones []*string `type:"list"` @@ -1788,6 +2116,16 @@ type metadataDisableAvailabilityZonesForLoadBalancerOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s DisableAvailabilityZonesForLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisableAvailabilityZonesForLoadBalancerOutput) GoString() string { + return s.String() +} + type EnableAvailabilityZonesForLoadBalancerInput struct { // The Availability Zones. These must be in the same region as the load balancer. AvailabilityZones []*string `type:"list" required:"true"` @@ -1802,6 +2140,16 @@ type metadataEnableAvailabilityZonesForLoadBalancerInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s EnableAvailabilityZonesForLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableAvailabilityZonesForLoadBalancerInput) GoString() string { + return s.String() +} + type EnableAvailabilityZonesForLoadBalancerOutput struct { // The updated list of Availability Zones for the load balancer. AvailabilityZones []*string `type:"list"` @@ -1813,15 +2161,25 @@ type metadataEnableAvailabilityZonesForLoadBalancerOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s EnableAvailabilityZonesForLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnableAvailabilityZonesForLoadBalancerOutput) GoString() string { + return s.String() +} + // Information about a health check. type HealthCheck struct { // The number of consecutive health checks successes required before moving // the instance to the Healthy state. - HealthyThreshold *int64 `type:"integer" required:"true"` + HealthyThreshold *int64 `min:"2" type:"integer" required:"true"` // The approximate interval, in seconds, between health checks of an individual // instance. - Interval *int64 `type:"integer" required:"true"` + Interval *int64 `min:"1" type:"integer" required:"true"` // The instance being checked. The protocol is either TCP, HTTP, HTTPS, or SSL. // The range of valid ports is one (1) through 65535. @@ -1847,11 +2205,11 @@ type HealthCheck struct { // check. // // This value must be less than the Interval value. - Timeout *int64 `type:"integer" required:"true"` + Timeout *int64 `min:"1" type:"integer" required:"true"` // The number of consecutive health check failures required before moving the // instance to the Unhealthy state. - UnhealthyThreshold *int64 `type:"integer" required:"true"` + UnhealthyThreshold *int64 `min:"2" type:"integer" required:"true"` metadataHealthCheck `json:"-" xml:"-"` } @@ -1860,10 +2218,20 @@ type metadataHealthCheck struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s HealthCheck) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HealthCheck) GoString() string { + return s.String() +} + // The ID of a back-end instance. type Instance struct { // The ID of the instance. - InstanceID *string `locationName:"InstanceId" type:"string"` + InstanceId *string `type:"string"` metadataInstance `json:"-" xml:"-"` } @@ -1872,6 +2240,16 @@ type metadataInstance struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Instance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Instance) GoString() string { + return s.String() +} + // Information about the state of a back-end instance. type InstanceState struct { // A description of the instance state. This string can contain one or more @@ -1906,7 +2284,7 @@ type InstanceState struct { Description *string `type:"string"` // The ID of the instance. - InstanceID *string `locationName:"InstanceId" type:"string"` + InstanceId *string `type:"string"` // Information about the cause of OutOfService instances. Specifically, whether // the cause is Elastic Load Balancing or the instance. @@ -1926,6 +2304,16 @@ type metadataInstanceState struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s InstanceState) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceState) GoString() string { + return s.String() +} + // Information about a policy for duration-based session stickiness. type LBCookieStickinessPolicy struct { // The time period, in seconds, after which the cookie should be considered @@ -1944,15 +2332,24 @@ type metadataLBCookieStickinessPolicy struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s LBCookieStickinessPolicy) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LBCookieStickinessPolicy) GoString() string { + return s.String() +} + // Information about a listener. // // For information about the protocols and the ports supported by Elastic Load // Balancing, see Listener Configurations for Elastic Load Balancing (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-listener-config.html) // in the Elastic Load Balancing Developer Guide. type Listener struct { - // The port on which the instance server is listening - 25, 80, 443, 465, 587, - // or 1024-65535. - InstancePort *int64 `type:"integer" required:"true"` + // The port on which the instance is listening. + InstancePort *int64 `min:"1" type:"integer" required:"true"` // The protocol to use for routing traffic to back-end instances: HTTP, HTTPS, // TCP, or SSL. @@ -1967,8 +2364,8 @@ type Listener struct { // is HTTP or TCP, the listener's InstanceProtocol must be HTTP or TCP. InstanceProtocol *string `type:"string"` - // The port on which the load balancer is listening: 25, 80, 443, 465, 587, - // or 1024-65535. + // The port on which the load balancer is listening. The supported ports are: + // 25, 80, 443, 465, 587, and 1024-65535. LoadBalancerPort *int64 `type:"integer" required:"true"` // The load balancer transport protocol to use for routing: HTTP, HTTPS, TCP, @@ -1976,7 +2373,7 @@ type Listener struct { Protocol *string `type:"string" required:"true"` // The Amazon Resource Name (ARN) of the server certificate. - SSLCertificateID *string `locationName:"SSLCertificateId" type:"string"` + SSLCertificateId *string `type:"string"` metadataListener `json:"-" xml:"-"` } @@ -1985,6 +2382,16 @@ type metadataListener struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Listener) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Listener) GoString() string { + return s.String() +} + // The policies enabled for a listener. type ListenerDescription struct { // Information about a listener. @@ -2004,6 +2411,16 @@ type metadataListenerDescription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ListenerDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListenerDescription) GoString() string { + return s.String() +} + // The attributes for a load balancer. type LoadBalancerAttributes struct { // If enabled, the load balancer captures detailed information of all requests @@ -2047,6 +2464,16 @@ type metadataLoadBalancerAttributes struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s LoadBalancerAttributes) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadBalancerAttributes) GoString() string { + return s.String() +} + // Information about a load balancer. type LoadBalancerDescription struct { // The Availability Zones for the load balancer. @@ -2109,7 +2536,7 @@ type LoadBalancerDescription struct { Subnets []*string `type:"list"` // The ID of the VPC for the load balancer. - VPCID *string `locationName:"VPCId" type:"string"` + VPCId *string `type:"string"` metadataLoadBalancerDescription `json:"-" xml:"-"` } @@ -2118,6 +2545,16 @@ type metadataLoadBalancerDescription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s LoadBalancerDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadBalancerDescription) GoString() string { + return s.String() +} + type ModifyLoadBalancerAttributesInput struct { // The attributes of the load balancer. LoadBalancerAttributes *LoadBalancerAttributes `type:"structure" required:"true"` @@ -2132,6 +2569,16 @@ type metadataModifyLoadBalancerAttributesInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifyLoadBalancerAttributesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyLoadBalancerAttributesInput) GoString() string { + return s.String() +} + type ModifyLoadBalancerAttributesOutput struct { // The attributes for a load balancer. LoadBalancerAttributes *LoadBalancerAttributes `type:"structure"` @@ -2146,6 +2593,16 @@ type metadataModifyLoadBalancerAttributesOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s ModifyLoadBalancerAttributesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyLoadBalancerAttributesOutput) GoString() string { + return s.String() +} + // The policies for a load balancer. type Policies struct { // The stickiness policies created using CreateAppCookieStickinessPolicy. @@ -2164,6 +2621,16 @@ type metadataPolicies struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Policies) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Policies) GoString() string { + return s.String() +} + // Information about a policy attribute. type PolicyAttribute struct { // The name of the attribute. @@ -2179,6 +2646,16 @@ type metadataPolicyAttribute struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PolicyAttribute) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PolicyAttribute) GoString() string { + return s.String() +} + // Information about a policy attribute. type PolicyAttributeDescription struct { // The name of the attribute. @@ -2194,6 +2671,16 @@ type metadataPolicyAttributeDescription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PolicyAttributeDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PolicyAttributeDescription) GoString() string { + return s.String() +} + // Information about a policy attribute type. type PolicyAttributeTypeDescription struct { // The name of the attribute. @@ -2224,6 +2711,16 @@ type metadataPolicyAttributeTypeDescription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PolicyAttributeTypeDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PolicyAttributeTypeDescription) GoString() string { + return s.String() +} + // Information about a policy. type PolicyDescription struct { // The policy attributes. @@ -2242,6 +2739,16 @@ type metadataPolicyDescription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PolicyDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PolicyDescription) GoString() string { + return s.String() +} + // Information about a policy type. type PolicyTypeDescription struct { // A description of the policy type. @@ -2261,6 +2768,16 @@ type metadataPolicyTypeDescription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s PolicyTypeDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PolicyTypeDescription) GoString() string { + return s.String() +} + type RegisterInstancesWithLoadBalancerInput struct { // The IDs of the instances. Instances []*Instance `type:"list" required:"true"` @@ -2275,6 +2792,16 @@ type metadataRegisterInstancesWithLoadBalancerInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RegisterInstancesWithLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RegisterInstancesWithLoadBalancerInput) GoString() string { + return s.String() +} + type RegisterInstancesWithLoadBalancerOutput struct { // The updated list of instances for the load balancer. Instances []*Instance `type:"list"` @@ -2286,13 +2813,23 @@ type metadataRegisterInstancesWithLoadBalancerOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RegisterInstancesWithLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RegisterInstancesWithLoadBalancerOutput) GoString() string { + return s.String() +} + type RemoveTagsInput struct { // The name of the load balancer. You can specify a maximum of one load balancer // name. LoadBalancerNames []*string `type:"list" required:"true"` // The list of tag keys to remove. - Tags []*TagKeyOnly `type:"list" required:"true"` + Tags []*TagKeyOnly `min:"1" type:"list" required:"true"` metadataRemoveTagsInput `json:"-" xml:"-"` } @@ -2301,6 +2838,16 @@ type metadataRemoveTagsInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RemoveTagsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RemoveTagsInput) GoString() string { + return s.String() +} + type RemoveTagsOutput struct { metadataRemoveTagsOutput `json:"-" xml:"-"` } @@ -2309,6 +2856,16 @@ type metadataRemoveTagsOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s RemoveTagsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RemoveTagsOutput) GoString() string { + return s.String() +} + type SetLoadBalancerListenerSSLCertificateInput struct { // The name of the load balancer. LoadBalancerName *string `type:"string" required:"true"` @@ -2317,7 +2874,7 @@ type SetLoadBalancerListenerSSLCertificateInput struct { LoadBalancerPort *int64 `type:"integer" required:"true"` // The Amazon Resource Name (ARN) of the SSL certificate. - SSLCertificateID *string `locationName:"SSLCertificateId" type:"string" required:"true"` + SSLCertificateId *string `type:"string" required:"true"` metadataSetLoadBalancerListenerSSLCertificateInput `json:"-" xml:"-"` } @@ -2326,6 +2883,16 @@ type metadataSetLoadBalancerListenerSSLCertificateInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SetLoadBalancerListenerSSLCertificateInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetLoadBalancerListenerSSLCertificateInput) GoString() string { + return s.String() +} + type SetLoadBalancerListenerSSLCertificateOutput struct { metadataSetLoadBalancerListenerSSLCertificateOutput `json:"-" xml:"-"` } @@ -2334,6 +2901,16 @@ type metadataSetLoadBalancerListenerSSLCertificateOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SetLoadBalancerListenerSSLCertificateOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetLoadBalancerListenerSSLCertificateOutput) GoString() string { + return s.String() +} + type SetLoadBalancerPoliciesForBackendServerInput struct { // The port number associated with the back-end server. InstancePort *int64 `type:"integer" required:"true"` @@ -2352,6 +2929,16 @@ type metadataSetLoadBalancerPoliciesForBackendServerInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SetLoadBalancerPoliciesForBackendServerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetLoadBalancerPoliciesForBackendServerInput) GoString() string { + return s.String() +} + type SetLoadBalancerPoliciesForBackendServerOutput struct { metadataSetLoadBalancerPoliciesForBackendServerOutput `json:"-" xml:"-"` } @@ -2360,6 +2947,16 @@ type metadataSetLoadBalancerPoliciesForBackendServerOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SetLoadBalancerPoliciesForBackendServerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetLoadBalancerPoliciesForBackendServerOutput) GoString() string { + return s.String() +} + type SetLoadBalancerPoliciesOfListenerInput struct { // The name of the load balancer. LoadBalancerName *string `type:"string" required:"true"` @@ -2378,6 +2975,16 @@ type metadataSetLoadBalancerPoliciesOfListenerInput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SetLoadBalancerPoliciesOfListenerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetLoadBalancerPoliciesOfListenerInput) GoString() string { + return s.String() +} + type SetLoadBalancerPoliciesOfListenerOutput struct { metadataSetLoadBalancerPoliciesOfListenerOutput `json:"-" xml:"-"` } @@ -2386,6 +2993,16 @@ type metadataSetLoadBalancerPoliciesOfListenerOutput struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SetLoadBalancerPoliciesOfListenerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SetLoadBalancerPoliciesOfListenerOutput) GoString() string { + return s.String() +} + // Information about a source security group. type SourceSecurityGroup struct { // The name of the security group. @@ -2401,10 +3018,20 @@ type metadataSourceSecurityGroup struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s SourceSecurityGroup) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SourceSecurityGroup) GoString() string { + return s.String() +} + // Information about a tag. type Tag struct { // The key of the tag. - Key *string `type:"string" required:"true"` + Key *string `min:"1" type:"string" required:"true"` // The value of the tag. Value *string `type:"string"` @@ -2416,13 +3043,23 @@ type metadataTag struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s Tag) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Tag) GoString() string { + return s.String() +} + // The tags associated with a load balancer. type TagDescription struct { // The name of the load balancer. LoadBalancerName *string `type:"string"` // The tags. - Tags []*Tag `type:"list"` + Tags []*Tag `min:"1" type:"list"` metadataTagDescription `json:"-" xml:"-"` } @@ -2431,10 +3068,20 @@ type metadataTagDescription struct { SDKShapeTraits bool `type:"structure"` } +// String returns the string representation +func (s TagDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagDescription) GoString() string { + return s.String() +} + // The key of a tag. type TagKeyOnly struct { // The name of the key. - Key *string `type:"string"` + Key *string `min:"1" type:"string"` metadataTagKeyOnly `json:"-" xml:"-"` } @@ -2442,3 +3089,13 @@ type TagKeyOnly struct { type metadataTagKeyOnly struct { SDKShapeTraits bool `type:"structure"` } + +// String returns the string representation +func (s TagKeyOnly) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagKeyOnly) GoString() string { + return s.String() +} diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/elbiface/interface.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/elbiface/interface.go index 5beab180cecf..a1b4214745e2 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/elbiface/interface.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/elbiface/interface.go @@ -4,64 +4,123 @@ package elbiface import ( + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/service/elb" ) // ELBAPI is the interface type for elb.ELB. type ELBAPI interface { + AddTagsRequest(*elb.AddTagsInput) (*request.Request, *elb.AddTagsOutput) + AddTags(*elb.AddTagsInput) (*elb.AddTagsOutput, error) + ApplySecurityGroupsToLoadBalancerRequest(*elb.ApplySecurityGroupsToLoadBalancerInput) (*request.Request, *elb.ApplySecurityGroupsToLoadBalancerOutput) + ApplySecurityGroupsToLoadBalancer(*elb.ApplySecurityGroupsToLoadBalancerInput) (*elb.ApplySecurityGroupsToLoadBalancerOutput, error) + AttachLoadBalancerToSubnetsRequest(*elb.AttachLoadBalancerToSubnetsInput) (*request.Request, *elb.AttachLoadBalancerToSubnetsOutput) + AttachLoadBalancerToSubnets(*elb.AttachLoadBalancerToSubnetsInput) (*elb.AttachLoadBalancerToSubnetsOutput, error) + ConfigureHealthCheckRequest(*elb.ConfigureHealthCheckInput) (*request.Request, *elb.ConfigureHealthCheckOutput) + ConfigureHealthCheck(*elb.ConfigureHealthCheckInput) (*elb.ConfigureHealthCheckOutput, error) + CreateAppCookieStickinessPolicyRequest(*elb.CreateAppCookieStickinessPolicyInput) (*request.Request, *elb.CreateAppCookieStickinessPolicyOutput) + CreateAppCookieStickinessPolicy(*elb.CreateAppCookieStickinessPolicyInput) (*elb.CreateAppCookieStickinessPolicyOutput, error) + CreateLBCookieStickinessPolicyRequest(*elb.CreateLBCookieStickinessPolicyInput) (*request.Request, *elb.CreateLBCookieStickinessPolicyOutput) + CreateLBCookieStickinessPolicy(*elb.CreateLBCookieStickinessPolicyInput) (*elb.CreateLBCookieStickinessPolicyOutput, error) + CreateLoadBalancerRequest(*elb.CreateLoadBalancerInput) (*request.Request, *elb.CreateLoadBalancerOutput) + CreateLoadBalancer(*elb.CreateLoadBalancerInput) (*elb.CreateLoadBalancerOutput, error) + CreateLoadBalancerListenersRequest(*elb.CreateLoadBalancerListenersInput) (*request.Request, *elb.CreateLoadBalancerListenersOutput) + CreateLoadBalancerListeners(*elb.CreateLoadBalancerListenersInput) (*elb.CreateLoadBalancerListenersOutput, error) + CreateLoadBalancerPolicyRequest(*elb.CreateLoadBalancerPolicyInput) (*request.Request, *elb.CreateLoadBalancerPolicyOutput) + CreateLoadBalancerPolicy(*elb.CreateLoadBalancerPolicyInput) (*elb.CreateLoadBalancerPolicyOutput, error) + DeleteLoadBalancerRequest(*elb.DeleteLoadBalancerInput) (*request.Request, *elb.DeleteLoadBalancerOutput) + DeleteLoadBalancer(*elb.DeleteLoadBalancerInput) (*elb.DeleteLoadBalancerOutput, error) + DeleteLoadBalancerListenersRequest(*elb.DeleteLoadBalancerListenersInput) (*request.Request, *elb.DeleteLoadBalancerListenersOutput) + DeleteLoadBalancerListeners(*elb.DeleteLoadBalancerListenersInput) (*elb.DeleteLoadBalancerListenersOutput, error) + DeleteLoadBalancerPolicyRequest(*elb.DeleteLoadBalancerPolicyInput) (*request.Request, *elb.DeleteLoadBalancerPolicyOutput) + DeleteLoadBalancerPolicy(*elb.DeleteLoadBalancerPolicyInput) (*elb.DeleteLoadBalancerPolicyOutput, error) + DeregisterInstancesFromLoadBalancerRequest(*elb.DeregisterInstancesFromLoadBalancerInput) (*request.Request, *elb.DeregisterInstancesFromLoadBalancerOutput) + DeregisterInstancesFromLoadBalancer(*elb.DeregisterInstancesFromLoadBalancerInput) (*elb.DeregisterInstancesFromLoadBalancerOutput, error) + DescribeInstanceHealthRequest(*elb.DescribeInstanceHealthInput) (*request.Request, *elb.DescribeInstanceHealthOutput) + DescribeInstanceHealth(*elb.DescribeInstanceHealthInput) (*elb.DescribeInstanceHealthOutput, error) + DescribeLoadBalancerAttributesRequest(*elb.DescribeLoadBalancerAttributesInput) (*request.Request, *elb.DescribeLoadBalancerAttributesOutput) + DescribeLoadBalancerAttributes(*elb.DescribeLoadBalancerAttributesInput) (*elb.DescribeLoadBalancerAttributesOutput, error) + DescribeLoadBalancerPoliciesRequest(*elb.DescribeLoadBalancerPoliciesInput) (*request.Request, *elb.DescribeLoadBalancerPoliciesOutput) + DescribeLoadBalancerPolicies(*elb.DescribeLoadBalancerPoliciesInput) (*elb.DescribeLoadBalancerPoliciesOutput, error) + DescribeLoadBalancerPolicyTypesRequest(*elb.DescribeLoadBalancerPolicyTypesInput) (*request.Request, *elb.DescribeLoadBalancerPolicyTypesOutput) + DescribeLoadBalancerPolicyTypes(*elb.DescribeLoadBalancerPolicyTypesInput) (*elb.DescribeLoadBalancerPolicyTypesOutput, error) + DescribeLoadBalancersRequest(*elb.DescribeLoadBalancersInput) (*request.Request, *elb.DescribeLoadBalancersOutput) + DescribeLoadBalancers(*elb.DescribeLoadBalancersInput) (*elb.DescribeLoadBalancersOutput, error) + DescribeLoadBalancersPages(*elb.DescribeLoadBalancersInput, func(*elb.DescribeLoadBalancersOutput, bool) bool) error + + DescribeTagsRequest(*elb.DescribeTagsInput) (*request.Request, *elb.DescribeTagsOutput) + DescribeTags(*elb.DescribeTagsInput) (*elb.DescribeTagsOutput, error) + DetachLoadBalancerFromSubnetsRequest(*elb.DetachLoadBalancerFromSubnetsInput) (*request.Request, *elb.DetachLoadBalancerFromSubnetsOutput) + DetachLoadBalancerFromSubnets(*elb.DetachLoadBalancerFromSubnetsInput) (*elb.DetachLoadBalancerFromSubnetsOutput, error) + DisableAvailabilityZonesForLoadBalancerRequest(*elb.DisableAvailabilityZonesForLoadBalancerInput) (*request.Request, *elb.DisableAvailabilityZonesForLoadBalancerOutput) + DisableAvailabilityZonesForLoadBalancer(*elb.DisableAvailabilityZonesForLoadBalancerInput) (*elb.DisableAvailabilityZonesForLoadBalancerOutput, error) + EnableAvailabilityZonesForLoadBalancerRequest(*elb.EnableAvailabilityZonesForLoadBalancerInput) (*request.Request, *elb.EnableAvailabilityZonesForLoadBalancerOutput) + EnableAvailabilityZonesForLoadBalancer(*elb.EnableAvailabilityZonesForLoadBalancerInput) (*elb.EnableAvailabilityZonesForLoadBalancerOutput, error) + ModifyLoadBalancerAttributesRequest(*elb.ModifyLoadBalancerAttributesInput) (*request.Request, *elb.ModifyLoadBalancerAttributesOutput) + ModifyLoadBalancerAttributes(*elb.ModifyLoadBalancerAttributesInput) (*elb.ModifyLoadBalancerAttributesOutput, error) + RegisterInstancesWithLoadBalancerRequest(*elb.RegisterInstancesWithLoadBalancerInput) (*request.Request, *elb.RegisterInstancesWithLoadBalancerOutput) + RegisterInstancesWithLoadBalancer(*elb.RegisterInstancesWithLoadBalancerInput) (*elb.RegisterInstancesWithLoadBalancerOutput, error) + RemoveTagsRequest(*elb.RemoveTagsInput) (*request.Request, *elb.RemoveTagsOutput) + RemoveTags(*elb.RemoveTagsInput) (*elb.RemoveTagsOutput, error) + SetLoadBalancerListenerSSLCertificateRequest(*elb.SetLoadBalancerListenerSSLCertificateInput) (*request.Request, *elb.SetLoadBalancerListenerSSLCertificateOutput) + SetLoadBalancerListenerSSLCertificate(*elb.SetLoadBalancerListenerSSLCertificateInput) (*elb.SetLoadBalancerListenerSSLCertificateOutput, error) + SetLoadBalancerPoliciesForBackendServerRequest(*elb.SetLoadBalancerPoliciesForBackendServerInput) (*request.Request, *elb.SetLoadBalancerPoliciesForBackendServerOutput) + SetLoadBalancerPoliciesForBackendServer(*elb.SetLoadBalancerPoliciesForBackendServerInput) (*elb.SetLoadBalancerPoliciesForBackendServerOutput, error) + SetLoadBalancerPoliciesOfListenerRequest(*elb.SetLoadBalancerPoliciesOfListenerInput) (*request.Request, *elb.SetLoadBalancerPoliciesOfListenerOutput) + SetLoadBalancerPoliciesOfListener(*elb.SetLoadBalancerPoliciesOfListenerInput) (*elb.SetLoadBalancerPoliciesOfListenerOutput, error) } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/examples_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/examples_test.go index 354af9bb8c32..765c050eaafd 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/examples_test.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/examples_test.go @@ -8,8 +8,6 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/elb" ) @@ -25,7 +23,7 @@ func ExampleELB_AddTags() { // More values... }, Tags: []*elb.Tag{ // Required - &elb.Tag{ // Required + { // Required Key: aws.String("TagKey"), // Required Value: aws.String("TagValue"), }, @@ -35,22 +33,14 @@ func ExampleELB_AddTags() { resp, err := svc.AddTags(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_ApplySecurityGroupsToLoadBalancer() { @@ -66,22 +56,14 @@ func ExampleELB_ApplySecurityGroupsToLoadBalancer() { resp, err := svc.ApplySecurityGroupsToLoadBalancer(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_AttachLoadBalancerToSubnets() { @@ -97,22 +79,14 @@ func ExampleELB_AttachLoadBalancerToSubnets() { resp, err := svc.AttachLoadBalancerToSubnets(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_ConfigureHealthCheck() { @@ -120,33 +94,25 @@ func ExampleELB_ConfigureHealthCheck() { params := &elb.ConfigureHealthCheckInput{ HealthCheck: &elb.HealthCheck{ // Required - HealthyThreshold: aws.Long(1), // Required - Interval: aws.Long(1), // Required + HealthyThreshold: aws.Int64(1), // Required + Interval: aws.Int64(1), // Required Target: aws.String("HealthCheckTarget"), // Required - Timeout: aws.Long(1), // Required - UnhealthyThreshold: aws.Long(1), // Required + Timeout: aws.Int64(1), // Required + UnhealthyThreshold: aws.Int64(1), // Required }, LoadBalancerName: aws.String("AccessPointName"), // Required } resp, err := svc.ConfigureHealthCheck(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_CreateAppCookieStickinessPolicy() { @@ -160,22 +126,14 @@ func ExampleELB_CreateAppCookieStickinessPolicy() { resp, err := svc.CreateAppCookieStickinessPolicy(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_CreateLBCookieStickinessPolicy() { @@ -184,27 +142,19 @@ func ExampleELB_CreateLBCookieStickinessPolicy() { params := &elb.CreateLBCookieStickinessPolicyInput{ LoadBalancerName: aws.String("AccessPointName"), // Required PolicyName: aws.String("PolicyName"), // Required - CookieExpirationPeriod: aws.Long(1), + CookieExpirationPeriod: aws.Int64(1), } resp, err := svc.CreateLBCookieStickinessPolicy(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_CreateLoadBalancer() { @@ -212,12 +162,12 @@ func ExampleELB_CreateLoadBalancer() { params := &elb.CreateLoadBalancerInput{ Listeners: []*elb.Listener{ // Required - &elb.Listener{ // Required - InstancePort: aws.Long(1), // Required - LoadBalancerPort: aws.Long(1), // Required + { // Required + InstancePort: aws.Int64(1), // Required + LoadBalancerPort: aws.Int64(1), // Required Protocol: aws.String("Protocol"), // Required InstanceProtocol: aws.String("Protocol"), - SSLCertificateID: aws.String("SSLCertificateId"), + SSLCertificateId: aws.String("SSLCertificateId"), }, // More values... }, @@ -236,7 +186,7 @@ func ExampleELB_CreateLoadBalancer() { // More values... }, Tags: []*elb.Tag{ - &elb.Tag{ // Required + { // Required Key: aws.String("TagKey"), // Required Value: aws.String("TagValue"), }, @@ -246,22 +196,14 @@ func ExampleELB_CreateLoadBalancer() { resp, err := svc.CreateLoadBalancer(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_CreateLoadBalancerListeners() { @@ -269,12 +211,12 @@ func ExampleELB_CreateLoadBalancerListeners() { params := &elb.CreateLoadBalancerListenersInput{ Listeners: []*elb.Listener{ // Required - &elb.Listener{ // Required - InstancePort: aws.Long(1), // Required - LoadBalancerPort: aws.Long(1), // Required + { // Required + InstancePort: aws.Int64(1), // Required + LoadBalancerPort: aws.Int64(1), // Required Protocol: aws.String("Protocol"), // Required InstanceProtocol: aws.String("Protocol"), - SSLCertificateID: aws.String("SSLCertificateId"), + SSLCertificateId: aws.String("SSLCertificateId"), }, // More values... }, @@ -283,22 +225,14 @@ func ExampleELB_CreateLoadBalancerListeners() { resp, err := svc.CreateLoadBalancerListeners(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_CreateLoadBalancerPolicy() { @@ -309,7 +243,7 @@ func ExampleELB_CreateLoadBalancerPolicy() { PolicyName: aws.String("PolicyName"), // Required PolicyTypeName: aws.String("PolicyTypeName"), // Required PolicyAttributes: []*elb.PolicyAttribute{ - &elb.PolicyAttribute{ // Required + { // Required AttributeName: aws.String("AttributeName"), AttributeValue: aws.String("AttributeValue"), }, @@ -319,22 +253,14 @@ func ExampleELB_CreateLoadBalancerPolicy() { resp, err := svc.CreateLoadBalancerPolicy(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DeleteLoadBalancer() { @@ -346,22 +272,14 @@ func ExampleELB_DeleteLoadBalancer() { resp, err := svc.DeleteLoadBalancer(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DeleteLoadBalancerListeners() { @@ -370,29 +288,21 @@ func ExampleELB_DeleteLoadBalancerListeners() { params := &elb.DeleteLoadBalancerListenersInput{ LoadBalancerName: aws.String("AccessPointName"), // Required LoadBalancerPorts: []*int64{ // Required - aws.Long(1), // Required + aws.Int64(1), // Required // More values... }, } resp, err := svc.DeleteLoadBalancerListeners(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DeleteLoadBalancerPolicy() { @@ -405,22 +315,14 @@ func ExampleELB_DeleteLoadBalancerPolicy() { resp, err := svc.DeleteLoadBalancerPolicy(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DeregisterInstancesFromLoadBalancer() { @@ -428,8 +330,8 @@ func ExampleELB_DeregisterInstancesFromLoadBalancer() { params := &elb.DeregisterInstancesFromLoadBalancerInput{ Instances: []*elb.Instance{ // Required - &elb.Instance{ // Required - InstanceID: aws.String("InstanceId"), + { // Required + InstanceId: aws.String("InstanceId"), }, // More values... }, @@ -438,22 +340,14 @@ func ExampleELB_DeregisterInstancesFromLoadBalancer() { resp, err := svc.DeregisterInstancesFromLoadBalancer(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DescribeInstanceHealth() { @@ -462,8 +356,8 @@ func ExampleELB_DescribeInstanceHealth() { params := &elb.DescribeInstanceHealthInput{ LoadBalancerName: aws.String("AccessPointName"), // Required Instances: []*elb.Instance{ - &elb.Instance{ // Required - InstanceID: aws.String("InstanceId"), + { // Required + InstanceId: aws.String("InstanceId"), }, // More values... }, @@ -471,22 +365,14 @@ func ExampleELB_DescribeInstanceHealth() { resp, err := svc.DescribeInstanceHealth(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DescribeLoadBalancerAttributes() { @@ -498,22 +384,14 @@ func ExampleELB_DescribeLoadBalancerAttributes() { resp, err := svc.DescribeLoadBalancerAttributes(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DescribeLoadBalancerPolicies() { @@ -529,22 +407,14 @@ func ExampleELB_DescribeLoadBalancerPolicies() { resp, err := svc.DescribeLoadBalancerPolicies(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DescribeLoadBalancerPolicyTypes() { @@ -559,22 +429,14 @@ func ExampleELB_DescribeLoadBalancerPolicyTypes() { resp, err := svc.DescribeLoadBalancerPolicyTypes(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DescribeLoadBalancers() { @@ -586,27 +448,19 @@ func ExampleELB_DescribeLoadBalancers() { // More values... }, Marker: aws.String("Marker"), - PageSize: aws.Long(1), + PageSize: aws.Int64(1), } resp, err := svc.DescribeLoadBalancers(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DescribeTags() { @@ -621,22 +475,14 @@ func ExampleELB_DescribeTags() { resp, err := svc.DescribeTags(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DetachLoadBalancerFromSubnets() { @@ -652,22 +498,14 @@ func ExampleELB_DetachLoadBalancerFromSubnets() { resp, err := svc.DetachLoadBalancerFromSubnets(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_DisableAvailabilityZonesForLoadBalancer() { @@ -683,22 +521,14 @@ func ExampleELB_DisableAvailabilityZonesForLoadBalancer() { resp, err := svc.DisableAvailabilityZonesForLoadBalancer(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_EnableAvailabilityZonesForLoadBalancer() { @@ -714,22 +544,14 @@ func ExampleELB_EnableAvailabilityZonesForLoadBalancer() { resp, err := svc.EnableAvailabilityZonesForLoadBalancer(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_ModifyLoadBalancerAttributes() { @@ -738,27 +560,27 @@ func ExampleELB_ModifyLoadBalancerAttributes() { params := &elb.ModifyLoadBalancerAttributesInput{ LoadBalancerAttributes: &elb.LoadBalancerAttributes{ // Required AccessLog: &elb.AccessLog{ - Enabled: aws.Boolean(true), // Required - EmitInterval: aws.Long(1), + Enabled: aws.Bool(true), // Required + EmitInterval: aws.Int64(1), S3BucketName: aws.String("S3BucketName"), S3BucketPrefix: aws.String("AccessLogPrefix"), }, AdditionalAttributes: []*elb.AdditionalAttribute{ - &elb.AdditionalAttribute{ // Required + { // Required Key: aws.String("StringVal"), Value: aws.String("StringVal"), }, // More values... }, ConnectionDraining: &elb.ConnectionDraining{ - Enabled: aws.Boolean(true), // Required - Timeout: aws.Long(1), + Enabled: aws.Bool(true), // Required + Timeout: aws.Int64(1), }, ConnectionSettings: &elb.ConnectionSettings{ - IdleTimeout: aws.Long(1), // Required + IdleTimeout: aws.Int64(1), // Required }, CrossZoneLoadBalancing: &elb.CrossZoneLoadBalancing{ - Enabled: aws.Boolean(true), // Required + Enabled: aws.Bool(true), // Required }, }, LoadBalancerName: aws.String("AccessPointName"), // Required @@ -766,22 +588,14 @@ func ExampleELB_ModifyLoadBalancerAttributes() { resp, err := svc.ModifyLoadBalancerAttributes(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_RegisterInstancesWithLoadBalancer() { @@ -789,8 +603,8 @@ func ExampleELB_RegisterInstancesWithLoadBalancer() { params := &elb.RegisterInstancesWithLoadBalancerInput{ Instances: []*elb.Instance{ // Required - &elb.Instance{ // Required - InstanceID: aws.String("InstanceId"), + { // Required + InstanceId: aws.String("InstanceId"), }, // More values... }, @@ -799,22 +613,14 @@ func ExampleELB_RegisterInstancesWithLoadBalancer() { resp, err := svc.RegisterInstancesWithLoadBalancer(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_RemoveTags() { @@ -826,7 +632,7 @@ func ExampleELB_RemoveTags() { // More values... }, Tags: []*elb.TagKeyOnly{ // Required - &elb.TagKeyOnly{ // Required + { // Required Key: aws.String("TagKey"), }, // More values... @@ -835,22 +641,14 @@ func ExampleELB_RemoveTags() { resp, err := svc.RemoveTags(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_SetLoadBalancerListenerSSLCertificate() { @@ -858,35 +656,27 @@ func ExampleELB_SetLoadBalancerListenerSSLCertificate() { params := &elb.SetLoadBalancerListenerSSLCertificateInput{ LoadBalancerName: aws.String("AccessPointName"), // Required - LoadBalancerPort: aws.Long(1), // Required - SSLCertificateID: aws.String("SSLCertificateId"), // Required + LoadBalancerPort: aws.Int64(1), // Required + SSLCertificateId: aws.String("SSLCertificateId"), // Required } resp, err := svc.SetLoadBalancerListenerSSLCertificate(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_SetLoadBalancerPoliciesForBackendServer() { svc := elb.New(nil) params := &elb.SetLoadBalancerPoliciesForBackendServerInput{ - InstancePort: aws.Long(1), // Required + InstancePort: aws.Int64(1), // Required LoadBalancerName: aws.String("AccessPointName"), // Required PolicyNames: []*string{ // Required aws.String("PolicyName"), // Required @@ -896,22 +686,14 @@ func ExampleELB_SetLoadBalancerPoliciesForBackendServer() { resp, err := svc.SetLoadBalancerPoliciesForBackendServer(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } func ExampleELB_SetLoadBalancerPoliciesOfListener() { @@ -919,7 +701,7 @@ func ExampleELB_SetLoadBalancerPoliciesOfListener() { params := &elb.SetLoadBalancerPoliciesOfListenerInput{ LoadBalancerName: aws.String("AccessPointName"), // Required - LoadBalancerPort: aws.Long(1), // Required + LoadBalancerPort: aws.Int64(1), // Required PolicyNames: []*string{ // Required aws.String("PolicyName"), // Required // More values... @@ -928,20 +710,12 @@ func ExampleELB_SetLoadBalancerPoliciesOfListener() { resp, err := svc.SetLoadBalancerPoliciesOfListener(params) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - // Generic AWS Error with Code, Message, and original error (if any) - fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) - if reqErr, ok := err.(awserr.RequestFailure); ok { - // A service error occurred - fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()) - } - } else { - // This case should never be hit, The SDK should alwsy return an - // error which satisfies the awserr.Error interface. - fmt.Println(err.Error()) - } + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + return } // Pretty-print the response data. - fmt.Println(awsutil.StringValue(resp)) + fmt.Println(resp) } diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/service.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/service.go index b77651c5356b..20eda10fe43b 100644 --- a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/service.go +++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/elb/service.go @@ -4,27 +4,45 @@ package elb import ( "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/service" + "github.com/aws/aws-sdk-go/aws/service/serviceinfo" "github.com/aws/aws-sdk-go/internal/protocol/query" "github.com/aws/aws-sdk-go/internal/signer/v4" ) -// ELB is a client for Elastic Load Balancing. +// Elastic Load Balancing distributes incoming traffic across your EC2 instances. +// +// For information about the features of Elastic Load Balancing, see What Is +// Elastic Load Balancing? (http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elastic-load-balancing.html) +// in the Elastic Load Balancing Developer Guide. +// +// For information about the AWS regions supported by Elastic Load Balancing, +// see Regions and Endpoints - Elastic Load Balancing (http://docs.aws.amazon.com/general/latest/gr/rande.html#elb_region) +// in the Amazon Web Services General Reference. +// +// All Elastic Load Balancing operations are idempotent, which means that they +// complete at most one time. If you repeat an operation, it succeeds with a +// 200 OK response code. type ELB struct { - *aws.Service + *service.Service } // Used for custom service initialization logic -var initService func(*aws.Service) +var initService func(*service.Service) // Used for custom request initialization logic -var initRequest func(*aws.Request) +var initRequest func(*request.Request) // New returns a new ELB client. func New(config *aws.Config) *ELB { - service := &aws.Service{ - Config: aws.DefaultConfig.Merge(config), - ServiceName: "elasticloadbalancing", - APIVersion: "2012-06-01", + service := &service.Service{ + ServiceInfo: serviceinfo.ServiceInfo{ + Config: defaults.DefaultConfig.Merge(config), + ServiceName: "elasticloadbalancing", + APIVersion: "2012-06-01", + }, } service.Initialize() @@ -45,8 +63,8 @@ func New(config *aws.Config) *ELB { // newRequest creates a new request for a ELB operation and runs any // custom request initialization. -func (c *ELB) newRequest(op *aws.Operation, params, data interface{}) *aws.Request { - req := aws.NewRequest(c.Service, op, params, data) +func (c *ELB) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) // Run custom request initialization if present if initRequest != nil { diff --git a/Godeps/_workspace/src/github.com/bradfitz/http2/testdata/draft-ietf-httpbis-http2.xml b/Godeps/_workspace/src/github.com/bradfitz/http2/testdata/draft-ietf-httpbis-http2.xml new file mode 100644 index 000000000000..31a84bed4f07 --- /dev/null +++ b/Godeps/_workspace/src/github.com/bradfitz/http2/testdata/draft-ietf-httpbis-http2.xml @@ -0,0 +1,5021 @@ + + + + + + + + + + + + + + + + + + + Hypertext Transfer Protocol version 2 + + + Twist +

+ mbelshe@chromium.org +
+ + + + Google, Inc +
+ fenix@google.com +
+
+ + + Mozilla +
+ + 331 E Evelyn Street + Mountain View + CA + 94041 + US + + martin.thomson@gmail.com +
+
+ + + Applications + HTTPbis + HTTP + SPDY + Web + + + + This specification describes an optimized expression of the semantics of the Hypertext + Transfer Protocol (HTTP). HTTP/2 enables a more efficient use of network resources and a + reduced perception of latency by introducing header field compression and allowing multiple + concurrent messages on the same connection. It also introduces unsolicited push of + representations from servers to clients. + + + This specification is an alternative to, but does not obsolete, the HTTP/1.1 message syntax. + HTTP's existing semantics remain unchanged. + + + + + + Discussion of this draft takes place on the HTTPBIS working group mailing list + (ietf-http-wg@w3.org), which is archived at . + + + Working Group information can be found at ; that specific to HTTP/2 are at . + + + The changes in this draft are summarized in . + + + + + + +
+ + + The Hypertext Transfer Protocol (HTTP) is a wildly successful protocol. However, the + HTTP/1.1 message format () has + several characteristics that have a negative overall effect on application performance + today. + + + In particular, HTTP/1.0 allowed only one request to be outstanding at a time on a given + TCP connection. HTTP/1.1 added request pipelining, but this only partially addressed + request concurrency and still suffers from head-of-line blocking. Therefore, HTTP/1.1 + clients that need to make many requests typically use multiple connections to a server in + order to achieve concurrency and thereby reduce latency. + + + Furthermore, HTTP header fields are often repetitive and verbose, causing unnecessary + network traffic, as well as causing the initial TCP congestion + window to quickly fill. This can result in excessive latency when multiple requests are + made on a new TCP connection. + + + HTTP/2 addresses these issues by defining an optimized mapping of HTTP's semantics to an + underlying connection. Specifically, it allows interleaving of request and response + messages on the same connection and uses an efficient coding for HTTP header fields. It + also allows prioritization of requests, letting more important requests complete more + quickly, further improving performance. + + + The resulting protocol is more friendly to the network, because fewer TCP connections can + be used in comparison to HTTP/1.x. This means less competition with other flows, and + longer-lived connections, which in turn leads to better utilization of available network + capacity. + + + Finally, HTTP/2 also enables more efficient processing of messages through use of binary + message framing. + +
+ +
+ + HTTP/2 provides an optimized transport for HTTP semantics. HTTP/2 supports all of the core + features of HTTP/1.1, but aims to be more efficient in several ways. + + + The basic protocol unit in HTTP/2 is a frame. Each frame + type serves a different purpose. For example, HEADERS and + DATA frames form the basis of HTTP requests and + responses; other frame types like SETTINGS, + WINDOW_UPDATE, and PUSH_PROMISE are used in support of other + HTTP/2 features. + + + Multiplexing of requests is achieved by having each HTTP request-response exchange + associated with its own stream. Streams are largely + independent of each other, so a blocked or stalled request or response does not prevent + progress on other streams. + + + Flow control and prioritization ensure that it is possible to efficiently use multiplexed + streams. Flow control helps to ensure that only data that + can be used by a receiver is transmitted. Prioritization ensures that limited resources can be directed + to the most important streams first. + + + HTTP/2 adds a new interaction mode, whereby a server can push + responses to a client. Server push allows a server to speculatively send a client + data that the server anticipates the client will need, trading off some network usage + against a potential latency gain. The server does this by synthesizing a request, which it + sends as a PUSH_PROMISE frame. The server is then able to send a response to + the synthetic request on a separate stream. + + + Frames that contain HTTP header fields are compressed. + HTTP requests can be highly redundant, so compression can reduce the size of requests and + responses significantly. + + +
+ + The HTTP/2 specification is split into four parts: + + + Starting HTTP/2 covers how an HTTP/2 connection is + initiated. + + + The framing and streams layers describe the way HTTP/2 frames are + structured and formed into multiplexed streams. + + + Frame and error + definitions include details of the frame and error types used in HTTP/2. + + + HTTP mappings and additional + requirements describe how HTTP semantics are expressed using frames and + streams. + + + + + While some of the frame and stream layer concepts are isolated from HTTP, this + specification does not define a completely generic framing layer. The framing and streams + layers are tailored to the needs of the HTTP protocol and server push. + +
+ +
+ + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD + NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as + described in RFC 2119. + + + All numeric values are in network byte order. Values are unsigned unless otherwise + indicated. Literal values are provided in decimal or hexadecimal as appropriate. + Hexadecimal literals are prefixed with 0x to distinguish them + from decimal literals. + + + The following terms are used: + + + The endpoint initiating the HTTP/2 connection. + + + A transport-layer connection between two endpoints. + + + An error that affects the entire HTTP/2 connection. + + + Either the client or server of the connection. + + + The smallest unit of communication within an HTTP/2 connection, consisting of a header + and a variable-length sequence of octets structured according to the frame type. + + + An endpoint. When discussing a particular endpoint, "peer" refers to the endpoint + that is remote to the primary subject of discussion. + + + An endpoint that is receiving frames. + + + An endpoint that is transmitting frames. + + + The endpoint which did not initiate the HTTP/2 connection. + + + A bi-directional flow of frames across a virtual channel within the HTTP/2 connection. + + + An error on the individual HTTP/2 stream. + + + + + Finally, the terms "gateway", "intermediary", "proxy", and "tunnel" are defined + in . + +
+
+ +
+ + An HTTP/2 connection is an application layer protocol running on top of a TCP connection + (). The client is the TCP connection initiator. + + + HTTP/2 uses the same "http" and "https" URI schemes used by HTTP/1.1. HTTP/2 shares the same + default port numbers: 80 for "http" URIs and 443 for "https" URIs. As a result, + implementations processing requests for target resource URIs like http://example.org/foo or https://example.com/bar are required to first discover whether the + upstream server (the immediate peer to which the client wishes to establish a connection) + supports HTTP/2. + + + + The means by which support for HTTP/2 is determined is different for "http" and "https" + URIs. Discovery for "http" URIs is described in . Discovery + for "https" URIs is described in . + + +
+ + The protocol defined in this document has two identifiers. + + + + The string "h2" identifies the protocol where HTTP/2 uses TLS. This identifier is used in the TLS application layer protocol negotiation extension (ALPN) + field and any place that HTTP/2 over TLS is identified. + + + The "h2" string is serialized into an ALPN protocol identifier as the two octet + sequence: 0x68, 0x32. + + + + + The string "h2c" identifies the protocol where HTTP/2 is run over cleartext TCP. + This identifier is used in the HTTP/1.1 Upgrade header field and any place that + HTTP/2 over TCP is identified. + + + + + + Negotiating "h2" or "h2c" implies the use of the transport, security, framing and message + semantics described in this document. + + + RFC Editor's Note: please remove the remainder of this section prior to the + publication of a final version of this document. + + + Only implementations of the final, published RFC can identify themselves as "h2" or "h2c". + Until such an RFC exists, implementations MUST NOT identify themselves using these + strings. + + + Examples and text throughout the rest of this document use "h2" as a matter of + editorial convenience only. Implementations of draft versions MUST NOT identify using + this string. + + + Implementations of draft versions of the protocol MUST add the string "-" and the + corresponding draft number to the identifier. For example, draft-ietf-httpbis-http2-11 + over TLS is identified using the string "h2-11". + + + Non-compatible experiments that are based on these draft versions MUST append the string + "-" and an experiment name to the identifier. For example, an experimental implementation + of packet mood-based encoding based on draft-ietf-httpbis-http2-09 might identify itself + as "h2-09-emo". Note that any label MUST conform to the "token" syntax defined in + . Experimenters are + encouraged to coordinate their experiments on the ietf-http-wg@w3.org mailing list. + +
+ +
+ + A client that makes a request for an "http" URI without prior knowledge about support for + HTTP/2 uses the HTTP Upgrade mechanism (). The client makes an HTTP/1.1 request that includes an Upgrade + header field identifying HTTP/2 with the "h2c" token. The HTTP/1.1 request MUST include + exactly one HTTP2-Settings header field. + +
+ For example: + + +]]> +
+ + Requests that contain an entity body MUST be sent in their entirety before the client can + send HTTP/2 frames. This means that a large request entity can block the use of the + connection until it is completely sent. + + + If concurrency of an initial request with subsequent requests is important, an OPTIONS + request can be used to perform the upgrade to HTTP/2, at the cost of an additional + round-trip. + + + A server that does not support HTTP/2 can respond to the request as though the Upgrade + header field were absent: + +
+ +HTTP/1.1 200 OK +Content-Length: 243 +Content-Type: text/html + +... + +
+ + A server MUST ignore a "h2" token in an Upgrade header field. Presence of a token with + "h2" implies HTTP/2 over TLS, which is instead negotiated as described in . + + + A server that supports HTTP/2 can accept the upgrade with a 101 (Switching Protocols) + response. After the empty line that terminates the 101 response, the server can begin + sending HTTP/2 frames. These frames MUST include a response to the request that initiated + the Upgrade. + + +
+ + For example: + + +HTTP/1.1 101 Switching Protocols +Connection: Upgrade +Upgrade: h2c + +[ HTTP/2 connection ... + +
+ + The first HTTP/2 frame sent by the server is a SETTINGS frame () as the server connection preface (). Upon receiving the 101 response, the client sends a connection preface, which includes a + SETTINGS frame. + + + The HTTP/1.1 request that is sent prior to upgrade is assigned stream identifier 1 and is + assigned default priority values. Stream 1 is + implicitly half closed from the client toward the server, since the request is completed + as an HTTP/1.1 request. After commencing the HTTP/2 connection, stream 1 is used for the + response. + + +
+ + A request that upgrades from HTTP/1.1 to HTTP/2 MUST include exactly one HTTP2-Settings header field. The HTTP2-Settings header field is a connection-specific header field + that includes parameters that govern the HTTP/2 connection, provided in anticipation of + the server accepting the request to upgrade. + +
+ +
+ + A server MUST NOT upgrade the connection to HTTP/2 if this header field is not present, + or if more than one is present. A server MUST NOT send this header field. + + + + The content of the HTTP2-Settings header field is the + payload of a SETTINGS frame (), encoded as a + base64url string (that is, the URL- and filename-safe Base64 encoding described in , with any trailing '=' characters omitted). The + ABNF production for token68 is + defined in . + + + Since the upgrade is only intended to apply to the immediate connection, a client + sending HTTP2-Settings MUST also send HTTP2-Settings as a connection option in the Connection header field to prevent it from being forwarded + downstream. + + + A server decodes and interprets these values as it would any other + SETTINGS frame. Acknowledgement of the + SETTINGS parameters is not necessary, since a 101 response serves as implicit + acknowledgment. Providing these values in the Upgrade request gives a client an + opportunity to provide parameters prior to receiving any frames from the server. + +
+
+ +
+ + A client that makes a request to an "https" URI uses TLS + with the application layer protocol negotiation extension. + + + HTTP/2 over TLS uses the "h2" application token. The "h2c" token MUST NOT be sent by a + client or selected by a server. + + + Once TLS negotiation is complete, both the client and the server send a connection preface. + +
+ +
+ + A client can learn that a particular server supports HTTP/2 by other means. For example, + describes a mechanism for advertising this capability. + + + A client MAY immediately send HTTP/2 frames to a server that is known to support HTTP/2, + after the connection preface; a server can + identify such a connection by the presence of the connection preface. This only affects + the establishment of HTTP/2 connections over cleartext TCP; implementations that support + HTTP/2 over TLS MUST use protocol negotiation in TLS. + + + Without additional information, prior support for HTTP/2 is not a strong signal that a + given server will support HTTP/2 for future connections. For example, it is possible for + server configurations to change, for configurations to differ between instances in + clustered servers, or for network conditions to change. + +
+ +
+ + Upon establishment of a TCP connection and determination that HTTP/2 will be used by both + peers, each endpoint MUST send a connection preface as a final confirmation and to + establish the initial SETTINGS parameters for the HTTP/2 connection. The client and + server each send a different connection preface. + + + The client connection preface starts with a sequence of 24 octets, which in hex notation + are: + +
+ +
+ + (the string PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n). This sequence + is followed by a SETTINGS frame (). The + SETTINGS frame MAY be empty. The client sends the client connection + preface immediately upon receipt of a 101 Switching Protocols response (indicating a + successful upgrade), or as the first application data octets of a TLS connection. If + starting an HTTP/2 connection with prior knowledge of server support for the protocol, the + client connection preface is sent upon connection establishment. + + + + + The client connection preface is selected so that a large proportion of HTTP/1.1 or + HTTP/1.0 servers and intermediaries do not attempt to process further frames. Note + that this does not address the concerns raised in . + + + + + The server connection preface consists of a potentially empty SETTINGS + frame () that MUST be the first frame the server sends in the + HTTP/2 connection. + + + The SETTINGS frames received from a peer as part of the connection preface + MUST be acknowledged (see ) after sending the connection + preface. + + + To avoid unnecessary latency, clients are permitted to send additional frames to the + server immediately after sending the client connection preface, without waiting to receive + the server connection preface. It is important to note, however, that the server + connection preface SETTINGS frame might include parameters that necessarily + alter how a client is expected to communicate with the server. Upon receiving the + SETTINGS frame, the client is expected to honor any parameters established. + In some configurations, it is possible for the server to transmit SETTINGS + before the client sends additional frames, providing an opportunity to avoid this issue. + + + Clients and servers MUST treat an invalid connection preface as a connection error of type + PROTOCOL_ERROR. A GOAWAY frame () + MAY be omitted in this case, since an invalid preface indicates that the peer is not using + HTTP/2. + +
+
+ +
+ + Once the HTTP/2 connection is established, endpoints can begin exchanging frames. + + +
+ + All frames begin with a fixed 9-octet header followed by a variable-length payload. + +
+ +
+ + The fields of the frame header are defined as: + + + + The length of the frame payload expressed as an unsigned 24-bit integer. Values + greater than 214 (16,384) MUST NOT be sent unless the receiver has + set a larger value for SETTINGS_MAX_FRAME_SIZE. + + + The 9 octets of the frame header are not included in this value. + + + + + The 8-bit type of the frame. The frame type determines the format and semantics of + the frame. Implementations MUST ignore and discard any frame that has a type that + is unknown. + + + + + An 8-bit field reserved for frame-type specific boolean flags. + + + Flags are assigned semantics specific to the indicated frame type. Flags that have + no defined semantics for a particular frame type MUST be ignored, and MUST be left + unset (0) when sending. + + + + + A reserved 1-bit field. The semantics of this bit are undefined and the bit MUST + remain unset (0) when sending and MUST be ignored when receiving. + + + + + A 31-bit stream identifier (see ). The value 0 is + reserved for frames that are associated with the connection as a whole as opposed to + an individual stream. + + + + + + The structure and content of the frame payload is dependent entirely on the frame type. + +
+ +
+ + The size of a frame payload is limited by the maximum size that a receiver advertises in + the SETTINGS_MAX_FRAME_SIZE setting. This setting can have any value + between 214 (16,384) and 224-1 (16,777,215) octets, + inclusive. + + + All implementations MUST be capable of receiving and minimally processing frames up to + 214 octets in length, plus the 9 octet frame + header. The size of the frame header is not included when describing frame sizes. + + + Certain frame types, such as PING, impose additional limits + on the amount of payload data allowed. + + + + + If a frame size exceeds any defined limit, or is too small to contain mandatory frame + data, the endpoint MUST send a FRAME_SIZE_ERROR error. A frame size error + in a frame that could alter the state of the entire connection MUST be treated as a connection error; this includes any frame carrying + a header block (that is, HEADERS, + PUSH_PROMISE, and CONTINUATION), SETTINGS, + and any WINDOW_UPDATE frame with a stream identifier of 0. + + + Endpoints are not obligated to use all available space in a frame. Responsiveness can be + improved by using frames that are smaller than the permitted maximum size. Sending large + frames can result in delays in sending time-sensitive frames (such + RST_STREAM, WINDOW_UPDATE, or PRIORITY) + which if blocked by the transmission of a large frame, could affect performance. + +
+ +
+ + Just as in HTTP/1, a header field in HTTP/2 is a name with one or more associated values. + They are used within HTTP request and response messages as well as server push operations + (see ). + + + Header lists are collections of zero or more header fields. When transmitted over a + connection, a header list is serialized into a header block using HTTP Header Compression. The serialized header block is then + divided into one or more octet sequences, called header block fragments, and transmitted + within the payload of HEADERS, PUSH_PROMISE or CONTINUATION frames. + + + The Cookie header field is treated specially by the HTTP + mapping (see ). + + + A receiving endpoint reassembles the header block by concatenating its fragments, then + decompresses the block to reconstruct the header list. + + + A complete header block consists of either: + + + a single HEADERS or PUSH_PROMISE frame, + with the END_HEADERS flag set, or + + + a HEADERS or PUSH_PROMISE frame with the END_HEADERS + flag cleared and one or more CONTINUATION frames, + where the last CONTINUATION frame has the END_HEADERS flag set. + + + + + Header compression is stateful. One compression context and one decompression context is + used for the entire connection. Each header block is processed as a discrete unit. + Header blocks MUST be transmitted as a contiguous sequence of frames, with no interleaved + frames of any other type or from any other stream. The last frame in a sequence of + HEADERS or CONTINUATION frames MUST have the END_HEADERS + flag set. The last frame in a sequence of PUSH_PROMISE or + CONTINUATION frames MUST have the END_HEADERS flag set. This allows a + header block to be logically equivalent to a single frame. + + + Header block fragments can only be sent as the payload of HEADERS, + PUSH_PROMISE or CONTINUATION frames, because these frames + carry data that can modify the compression context maintained by a receiver. An endpoint + receiving HEADERS, PUSH_PROMISE or + CONTINUATION frames MUST reassemble header blocks and perform decompression + even if the frames are to be discarded. A receiver MUST terminate the connection with a + connection error of type + COMPRESSION_ERROR if it does not decompress a header block. + +
+
+ +
+ + A "stream" is an independent, bi-directional sequence of frames exchanged between the client + and server within an HTTP/2 connection. Streams have several important characteristics: + + + A single HTTP/2 connection can contain multiple concurrently open streams, with either + endpoint interleaving frames from multiple streams. + + + Streams can be established and used unilaterally or shared by either the client or + server. + + + Streams can be closed by either endpoint. + + + The order in which frames are sent on a stream is significant. Recipients process frames + in the order they are received. In particular, the order of HEADERS, + and DATA frames is semantically significant. + + + Streams are identified by an integer. Stream identifiers are assigned to streams by the + endpoint initiating the stream. + + + + +
+ + The lifecycle of a stream is shown in . + + +
+ + | |<-----------' | + | R | closed | R | + `-------------------->| |<--------------------' + +--------+ + + H: HEADERS frame (with implied CONTINUATIONs) + PP: PUSH_PROMISE frame (with implied CONTINUATIONs) + ES: END_STREAM flag + R: RST_STREAM frame +]]> + +
+ + + Note that this diagram shows stream state transitions and the frames and flags that affect + those transitions only. In this regard, CONTINUATION frames do not result + in state transitions; they are effectively part of the HEADERS or + PUSH_PROMISE that they follow. For this purpose, the END_STREAM flag is + processed as a separate event to the frame that bears it; a HEADERS frame + with the END_STREAM flag set can cause two state transitions. + + + Both endpoints have a subjective view of the state of a stream that could be different + when frames are in transit. Endpoints do not coordinate the creation of streams; they are + created unilaterally by either endpoint. The negative consequences of a mismatch in + states are limited to the "closed" state after sending RST_STREAM, where + frames might be received for some time after closing. + + + Streams have the following states: + + + + + + All streams start in the "idle" state. In this state, no frames have been + exchanged. + + + The following transitions are valid from this state: + + + Sending or receiving a HEADERS frame causes the stream to become + "open". The stream identifier is selected as described in . The same HEADERS frame can also + cause a stream to immediately become "half closed". + + + Sending a PUSH_PROMISE frame marks the associated stream for + later use. The stream state for the reserved stream transitions to "reserved + (local)". + + + Receiving a PUSH_PROMISE frame marks the associated stream as + reserved by the remote peer. The state of the stream becomes "reserved + (remote)". + + + + + Receiving any frames other than HEADERS or + PUSH_PROMISE on a stream in this state MUST be treated as a connection error of type + PROTOCOL_ERROR. + + + + + + + A stream in the "reserved (local)" state is one that has been promised by sending a + PUSH_PROMISE frame. A PUSH_PROMISE frame reserves an + idle stream by associating the stream with an open stream that was initiated by the + remote peer (see ). + + + In this state, only the following transitions are possible: + + + The endpoint can send a HEADERS frame. This causes the stream to + open in a "half closed (remote)" state. + + + Either endpoint can send a RST_STREAM frame to cause the stream + to become "closed". This releases the stream reservation. + + + + + An endpoint MUST NOT send any type of frame other than HEADERS or + RST_STREAM in this state. + + + A PRIORITY frame MAY be received in this state. Receiving any type + of frame other than RST_STREAM or PRIORITY on a stream + in this state MUST be treated as a connection + error of type PROTOCOL_ERROR. + + + + + + + A stream in the "reserved (remote)" state has been reserved by a remote peer. + + + In this state, only the following transitions are possible: + + + Receiving a HEADERS frame causes the stream to transition to + "half closed (local)". + + + Either endpoint can send a RST_STREAM frame to cause the stream + to become "closed". This releases the stream reservation. + + + + + An endpoint MAY send a PRIORITY frame in this state to reprioritize + the reserved stream. An endpoint MUST NOT send any type of frame other than + RST_STREAM, WINDOW_UPDATE, or PRIORITY + in this state. + + + Receiving any type of frame other than HEADERS or + RST_STREAM on a stream in this state MUST be treated as a connection error of type + PROTOCOL_ERROR. + + + + + + + A stream in the "open" state may be used by both peers to send frames of any type. + In this state, sending peers observe advertised stream + level flow control limits. + + + From this state either endpoint can send a frame with an END_STREAM flag set, which + causes the stream to transition into one of the "half closed" states: an endpoint + sending an END_STREAM flag causes the stream state to become "half closed (local)"; + an endpoint receiving an END_STREAM flag causes the stream state to become "half + closed (remote)". + + + Either endpoint can send a RST_STREAM frame from this state, causing + it to transition immediately to "closed". + + + + + + + A stream that is in the "half closed (local)" state cannot be used for sending + frames. Only WINDOW_UPDATE, PRIORITY and + RST_STREAM frames can be sent in this state. + + + A stream transitions from this state to "closed" when a frame that contains an + END_STREAM flag is received, or when either peer sends a RST_STREAM + frame. + + + A receiver can ignore WINDOW_UPDATE frames in this state, which might + arrive for a short period after a frame bearing the END_STREAM flag is sent. + + + PRIORITY frames received in this state are used to reprioritize + streams that depend on the current stream. + + + + + + + A stream that is "half closed (remote)" is no longer being used by the peer to send + frames. In this state, an endpoint is no longer obligated to maintain a receiver + flow control window if it performs flow control. + + + If an endpoint receives additional frames for a stream that is in this state, other + than WINDOW_UPDATE, PRIORITY or + RST_STREAM, it MUST respond with a stream error of type + STREAM_CLOSED. + + + A stream that is "half closed (remote)" can be used by the endpoint to send frames + of any type. In this state, the endpoint continues to observe advertised stream level flow control limits. + + + A stream can transition from this state to "closed" by sending a frame that contains + an END_STREAM flag, or when either peer sends a RST_STREAM frame. + + + + + + + The "closed" state is the terminal state. + + + An endpoint MUST NOT send frames other than PRIORITY on a closed + stream. An endpoint that receives any frame other than PRIORITY + after receiving a RST_STREAM MUST treat that as a stream error of type + STREAM_CLOSED. Similarly, an endpoint that receives any frames after + receiving a frame with the END_STREAM flag set MUST treat that as a connection error of type + STREAM_CLOSED, unless the frame is permitted as described below. + + + WINDOW_UPDATE or RST_STREAM frames can be received in + this state for a short period after a DATA or HEADERS + frame containing an END_STREAM flag is sent. Until the remote peer receives and + processes RST_STREAM or the frame bearing the END_STREAM flag, it + might send frames of these types. Endpoints MUST ignore + WINDOW_UPDATE or RST_STREAM frames received in this + state, though endpoints MAY choose to treat frames that arrive a significant time + after sending END_STREAM as a connection + error of type PROTOCOL_ERROR. + + + PRIORITY frames can be sent on closed streams to prioritize streams + that are dependent on the closed stream. Endpoints SHOULD process + PRIORITY frame, though they can be ignored if the stream has been + removed from the dependency tree (see ). + + + If this state is reached as a result of sending a RST_STREAM frame, + the peer that receives the RST_STREAM might have already sent - or + enqueued for sending - frames on the stream that cannot be withdrawn. An endpoint + MUST ignore frames that it receives on closed streams after it has sent a + RST_STREAM frame. An endpoint MAY choose to limit the period over + which it ignores frames and treat frames that arrive after this time as being in + error. + + + Flow controlled frames (i.e., DATA) received after sending + RST_STREAM are counted toward the connection flow control window. + Even though these frames might be ignored, because they are sent before the sender + receives the RST_STREAM, the sender will consider the frames to count + against the flow control window. + + + An endpoint might receive a PUSH_PROMISE frame after it sends + RST_STREAM. PUSH_PROMISE causes a stream to become + "reserved" even if the associated stream has been reset. Therefore, a + RST_STREAM is needed to close an unwanted promised stream. + + + + + + In the absence of more specific guidance elsewhere in this document, implementations + SHOULD treat the receipt of a frame that is not expressly permitted in the description of + a state as a connection error of type + PROTOCOL_ERROR. Frame of unknown types are ignored. + + + An example of the state transitions for an HTTP request/response exchange can be found in + . An example of the state transitions for server push can be + found in and . + + +
+ + Streams are identified with an unsigned 31-bit integer. Streams initiated by a client + MUST use odd-numbered stream identifiers; those initiated by the server MUST use + even-numbered stream identifiers. A stream identifier of zero (0x0) is used for + connection control messages; the stream identifier zero cannot be used to establish a + new stream. + + + HTTP/1.1 requests that are upgraded to HTTP/2 (see ) are + responded to with a stream identifier of one (0x1). After the upgrade + completes, stream 0x1 is "half closed (local)" to the client. Therefore, stream 0x1 + cannot be selected as a new stream identifier by a client that upgrades from HTTP/1.1. + + + The identifier of a newly established stream MUST be numerically greater than all + streams that the initiating endpoint has opened or reserved. This governs streams that + are opened using a HEADERS frame and streams that are reserved using + PUSH_PROMISE. An endpoint that receives an unexpected stream identifier + MUST respond with a connection error of + type PROTOCOL_ERROR. + + + The first use of a new stream identifier implicitly closes all streams in the "idle" + state that might have been initiated by that peer with a lower-valued stream identifier. + For example, if a client sends a HEADERS frame on stream 7 without ever + sending a frame on stream 5, then stream 5 transitions to the "closed" state when the + first frame for stream 7 is sent or received. + + + Stream identifiers cannot be reused. Long-lived connections can result in an endpoint + exhausting the available range of stream identifiers. A client that is unable to + establish a new stream identifier can establish a new connection for new streams. A + server that is unable to establish a new stream identifier can send a + GOAWAY frame so that the client is forced to open a new connection for + new streams. + +
+ +
+ + A peer can limit the number of concurrently active streams using the + SETTINGS_MAX_CONCURRENT_STREAMS parameter (see ) within a SETTINGS frame. The maximum concurrent + streams setting is specific to each endpoint and applies only to the peer that receives + the setting. That is, clients specify the maximum number of concurrent streams the + server can initiate, and servers specify the maximum number of concurrent streams the + client can initiate. + + + Streams that are in the "open" state, or either of the "half closed" states count toward + the maximum number of streams that an endpoint is permitted to open. Streams in any of + these three states count toward the limit advertised in the + SETTINGS_MAX_CONCURRENT_STREAMS setting. Streams in either of the + "reserved" states do not count toward the stream limit. + + + Endpoints MUST NOT exceed the limit set by their peer. An endpoint that receives a + HEADERS frame that causes their advertised concurrent stream limit to be + exceeded MUST treat this as a stream error. An + endpoint that wishes to reduce the value of + SETTINGS_MAX_CONCURRENT_STREAMS to a value that is below the current + number of open streams can either close streams that exceed the new value or allow + streams to complete. + +
+
+ +
+ + Using streams for multiplexing introduces contention over use of the TCP connection, + resulting in blocked streams. A flow control scheme ensures that streams on the same + connection do not destructively interfere with each other. Flow control is used for both + individual streams and for the connection as a whole. + + + HTTP/2 provides for flow control through use of the WINDOW_UPDATE frame. + + +
+ + HTTP/2 stream flow control aims to allow a variety of flow control algorithms to be + used without requiring protocol changes. Flow control in HTTP/2 has the following + characteristics: + + + Flow control is specific to a connection; i.e., it is "hop-by-hop", not + "end-to-end". + + + Flow control is based on window update frames. Receivers advertise how many octets + they are prepared to receive on a stream and for the entire connection. This is a + credit-based scheme. + + + Flow control is directional with overall control provided by the receiver. A + receiver MAY choose to set any window size that it desires for each stream and for + the entire connection. A sender MUST respect flow control limits imposed by a + receiver. Clients, servers and intermediaries all independently advertise their + flow control window as a receiver and abide by the flow control limits set by + their peer when sending. + + + The initial value for the flow control window is 65,535 octets for both new streams + and the overall connection. + + + The frame type determines whether flow control applies to a frame. Of the frames + specified in this document, only DATA frames are subject to flow + control; all other frame types do not consume space in the advertised flow control + window. This ensures that important control frames are not blocked by flow control. + + + Flow control cannot be disabled. + + + HTTP/2 defines only the format and semantics of the WINDOW_UPDATE + frame (). This document does not stipulate how a + receiver decides when to send this frame or the value that it sends, nor does it + specify how a sender chooses to send packets. Implementations are able to select + any algorithm that suits their needs. + + + + + Implementations are also responsible for managing how requests and responses are sent + based on priority; choosing how to avoid head of line blocking for requests; and + managing the creation of new streams. Algorithm choices for these could interact with + any flow control algorithm. + +
+ +
+ + Flow control is defined to protect endpoints that are operating under resource + constraints. For example, a proxy needs to share memory between many connections, and + also might have a slow upstream connection and a fast downstream one. Flow control + addresses cases where the receiver is unable process data on one stream, yet wants to + continue to process other streams in the same connection. + + + Deployments that do not require this capability can advertise a flow control window of + the maximum size, incrementing the available space when new data is received. This + effectively disables flow control for that receiver. Conversely, a sender is always + subject to the flow control window advertised by the receiver. + + + Deployments with constrained resources (for example, memory) can employ flow control to + limit the amount of memory a peer can consume. Note, however, that this can lead to + suboptimal use of available network resources if flow control is enabled without + knowledge of the bandwidth-delay product (see ). + + + Even with full awareness of the current bandwidth-delay product, implementation of flow + control can be difficult. When using flow control, the receiver MUST read from the TCP + receive buffer in a timely fashion. Failure to do so could lead to a deadlock when + critical frames, such as WINDOW_UPDATE, are not read and acted upon. + +
+
+ +
+ + A client can assign a priority for a new stream by including prioritization information in + the HEADERS frame that opens the stream. For an existing + stream, the PRIORITY frame can be used to change the + priority. + + + The purpose of prioritization is to allow an endpoint to express how it would prefer its + peer allocate resources when managing concurrent streams. Most importantly, priority can + be used to select streams for transmitting frames when there is limited capacity for + sending. + + + Streams can be prioritized by marking them as dependent on the completion of other streams + (). Each dependency is assigned a relative weight, a number + that is used to determine the relative proportion of available resources that are assigned + to streams dependent on the same stream. + + + + Explicitly setting the priority for a stream is input to a prioritization process. It + does not guarantee any particular processing or transmission order for the stream relative + to any other stream. An endpoint cannot force a peer to process concurrent streams in a + particular order using priority. Expressing priority is therefore only ever a suggestion. + + + Providing prioritization information is optional, so default values are used if no + explicit indicator is provided (). + + +
+ + Each stream can be given an explicit dependency on another stream. Including a + dependency expresses a preference to allocate resources to the identified stream rather + than to the dependent stream. + + + A stream that is not dependent on any other stream is given a stream dependency of 0x0. + In other words, the non-existent stream 0 forms the root of the tree. + + + A stream that depends on another stream is a dependent stream. The stream upon which a + stream is dependent is a parent stream. A dependency on a stream that is not currently + in the tree - such as a stream in the "idle" state - results in that stream being given + a default priority. + + + When assigning a dependency on another stream, the stream is added as a new dependency + of the parent stream. Dependent streams that share the same parent are not ordered with + respect to each other. For example, if streams B and C are dependent on stream A, and + if stream D is created with a dependency on stream A, this results in a dependency order + of A followed by B, C, and D in any order. + +
+ /|\ + B C B D C +]]> +
+ + An exclusive flag allows for the insertion of a new level of dependencies. The + exclusive flag causes the stream to become the sole dependency of its parent stream, + causing other dependencies to become dependent on the exclusive stream. In the + previous example, if stream D is created with an exclusive dependency on stream A, this + results in D becoming the dependency parent of B and C. + +
+ D + B C / \ + B C +]]> +
+ + Inside the dependency tree, a dependent stream SHOULD only be allocated resources if all + of the streams that it depends on (the chain of parent streams up to 0x0) are either + closed, or it is not possible to make progress on them. + + + A stream cannot depend on itself. An endpoint MUST treat this as a stream error of type PROTOCOL_ERROR. + +
+ +
+ + All dependent streams are allocated an integer weight between 1 and 256 (inclusive). + + + Streams with the same parent SHOULD be allocated resources proportionally based on their + weight. Thus, if stream B depends on stream A with weight 4, and C depends on stream A + with weight 12, and if no progress can be made on A, stream B ideally receives one third + of the resources allocated to stream C. + +
+ +
+ + Stream priorities are changed using the PRIORITY frame. Setting a + dependency causes a stream to become dependent on the identified parent stream. + + + Dependent streams move with their parent stream if the parent is reprioritized. Setting + a dependency with the exclusive flag for a reprioritized stream moves all the + dependencies of the new parent stream to become dependent on the reprioritized stream. + + + If a stream is made dependent on one of its own dependencies, the formerly dependent + stream is first moved to be dependent on the reprioritized stream's previous parent. + The moved dependency retains its weight. + +
+ + For example, consider an original dependency tree where B and C depend on A, D and E + depend on C, and F depends on D. If A is made dependent on D, then D takes the place + of A. All other dependency relationships stay the same, except for F, which becomes + dependent on A if the reprioritization is exclusive. + + F B C ==> F A OR A + / \ | / \ /|\ + D E E B C B C F + | | | + F E E + (intermediate) (non-exclusive) (exclusive) +]]> +
+
+ +
+ + When a stream is removed from the dependency tree, its dependencies can be moved to + become dependent on the parent of the closed stream. The weights of new dependencies + are recalculated by distributing the weight of the dependency of the closed stream + proportionally based on the weights of its dependencies. + + + Streams that are removed from the dependency tree cause some prioritization information + to be lost. Resources are shared between streams with the same parent stream, which + means that if a stream in that set closes or becomes blocked, any spare capacity + allocated to a stream is distributed to the immediate neighbors of the stream. However, + if the common dependency is removed from the tree, those streams share resources with + streams at the next highest level. + + + For example, assume streams A and B share a parent, and streams C and D both depend on + stream A. Prior to the removal of stream A, if streams A and D are unable to proceed, + then stream C receives all the resources dedicated to stream A. If stream A is removed + from the tree, the weight of stream A is divided between streams C and D. If stream D + is still unable to proceed, this results in stream C receiving a reduced proportion of + resources. For equal starting weights, C receives one third, rather than one half, of + available resources. + + + It is possible for a stream to become closed while prioritization information that + creates a dependency on that stream is in transit. If a stream identified in a + dependency has no associated priority information, then the dependent stream is instead + assigned a default priority. This potentially creates + suboptimal prioritization, since the stream could be given a priority that is different + to what is intended. + + + To avoid these problems, an endpoint SHOULD retain stream prioritization state for a + period after streams become closed. The longer state is retained, the lower the chance + that streams are assigned incorrect or default priority values. + + + This could create a large state burden for an endpoint, so this state MAY be limited. + An endpoint MAY apply a fixed upper limit on the number of closed streams for which + prioritization state is tracked to limit state exposure. The amount of additional state + an endpoint maintains could be dependent on load; under high load, prioritization state + can be discarded to limit resource commitments. In extreme cases, an endpoint could + even discard prioritization state for active or reserved streams. If a fixed limit is + applied, endpoints SHOULD maintain state for at least as many streams as allowed by + their setting for SETTINGS_MAX_CONCURRENT_STREAMS. + + + An endpoint receiving a PRIORITY frame that changes the priority of a + closed stream SHOULD alter the dependencies of the streams that depend on it, if it has + retained enough state to do so. + +
+ +
+ + Providing priority information is optional. Streams are assigned a non-exclusive + dependency on stream 0x0 by default. Pushed streams + initially depend on their associated stream. In both cases, streams are assigned a + default weight of 16. + +
+
+ +
+ + HTTP/2 framing permits two classes of error: + + + An error condition that renders the entire connection unusable is a connection error. + + + An error in an individual stream is a stream error. + + + + + A list of error codes is included in . + + +
+ + A connection error is any error which prevents further processing of the framing layer, + or which corrupts any connection state. + + + An endpoint that encounters a connection error SHOULD first send a GOAWAY + frame () with the stream identifier of the last stream that it + successfully received from its peer. The GOAWAY frame includes an error + code that indicates why the connection is terminating. After sending the + GOAWAY frame, the endpoint MUST close the TCP connection. + + + It is possible that the GOAWAY will not be reliably received by the + receiving endpoint (see ). In the event of a connection error, + GOAWAY only provides a best effort attempt to communicate with the peer + about why the connection is being terminated. + + + An endpoint can end a connection at any time. In particular, an endpoint MAY choose to + treat a stream error as a connection error. Endpoints SHOULD send a + GOAWAY frame when ending a connection, providing that circumstances + permit it. + +
+ +
+ + A stream error is an error related to a specific stream that does not affect processing + of other streams. + + + An endpoint that detects a stream error sends a RST_STREAM frame () that contains the stream identifier of the stream where the error + occurred. The RST_STREAM frame includes an error code that indicates the + type of error. + + + A RST_STREAM is the last frame that an endpoint can send on a stream. + The peer that sends the RST_STREAM frame MUST be prepared to receive any + frames that were sent or enqueued for sending by the remote peer. These frames can be + ignored, except where they modify connection state (such as the state maintained for + header compression, or flow control). + + + Normally, an endpoint SHOULD NOT send more than one RST_STREAM frame for + any stream. However, an endpoint MAY send additional RST_STREAM frames if + it receives frames on a closed stream after more than a round-trip time. This behavior + is permitted to deal with misbehaving implementations. + + + An endpoint MUST NOT send a RST_STREAM in response to an + RST_STREAM frame, to avoid looping. + +
+ +
+ + If the TCP connection is closed or reset while streams remain in open or half closed + states, then the endpoint MUST assume that those streams were abnormally interrupted and + could be incomplete. + +
+
+ +
+ + HTTP/2 permits extension of the protocol. Protocol extensions can be used to provide + additional services or alter any aspect of the protocol, within the limitations described + in this section. Extensions are effective only within the scope of a single HTTP/2 + connection. + + + Extensions are permitted to use new frame types, new + settings, or new error + codes. Registries are established for managing these extension points: frame types, settings and + error codes. + + + Implementations MUST ignore unknown or unsupported values in all extensible protocol + elements. Implementations MUST discard frames that have unknown or unsupported types. + This means that any of these extension points can be safely used by extensions without + prior arrangement or negotiation. However, extension frames that appear in the middle of + a header block are not permitted; these MUST be treated + as a connection error of type + PROTOCOL_ERROR. + + + However, extensions that could change the semantics of existing protocol components MUST + be negotiated before being used. For example, an extension that changes the layout of the + HEADERS frame cannot be used until the peer has given a positive signal + that this is acceptable. In this case, it could also be necessary to coordinate when the + revised layout comes into effect. Note that treating any frame other than + DATA frames as flow controlled is such a change in semantics, and can only + be done through negotiation. + + + This document doesn't mandate a specific method for negotiating the use of an extension, + but notes that a setting could be used for that + purpose. If both peers set a value that indicates willingness to use the extension, then + the extension can be used. If a setting is used for extension negotiation, the initial + value MUST be defined so that the extension is initially disabled. + +
+
+ +
+ + This specification defines a number of frame types, each identified by a unique 8-bit type + code. Each frame type serves a distinct purpose either in the establishment and management + of the connection as a whole, or of individual streams. + + + The transmission of specific frame types can alter the state of a connection. If endpoints + fail to maintain a synchronized view of the connection state, successful communication + within the connection will no longer be possible. Therefore, it is important that endpoints + have a shared comprehension of how the state is affected by the use any given frame. + + +
+ + DATA frames (type=0x0) convey arbitrary, variable-length sequences of octets associated + with a stream. One or more DATA frames are used, for instance, to carry HTTP request or + response payloads. + + + DATA frames MAY also contain arbitrary padding. Padding can be added to DATA frames to + obscure the size of messages. + +
+ +
+ + The DATA frame contains the following fields: + + + An 8-bit field containing the length of the frame padding in units of octets. This + field is optional and is only present if the PADDED flag is set. + + + Application data. The amount of data is the remainder of the frame payload after + subtracting the length of the other fields that are present. + + + Padding octets that contain no application semantic value. Padding octets MUST be set + to zero when sending and ignored when receiving. + + + + + + The DATA frame defines the following flags: + + + Bit 1 being set indicates that this frame is the last that the endpoint will send for + the identified stream. Setting this flag causes the stream to enter one of the "half closed" states or the "closed" state. + + + Bit 4 being set indicates that the Pad Length field and any padding that it describes + is present. + + + + + DATA frames MUST be associated with a stream. If a DATA frame is received whose stream + identifier field is 0x0, the recipient MUST respond with a connection error of type + PROTOCOL_ERROR. + + + DATA frames are subject to flow control and can only be sent when a stream is in the + "open" or "half closed (remote)" states. The entire DATA frame payload is included in flow + control, including Pad Length and Padding fields if present. If a DATA frame is received + whose stream is not in "open" or "half closed (local)" state, the recipient MUST respond + with a stream error of type + STREAM_CLOSED. + + + The total number of padding octets is determined by the value of the Pad Length field. If + the length of the padding is greater than the length of the frame payload, the recipient + MUST treat this as a connection error of + type PROTOCOL_ERROR. + + + A frame can be increased in size by one octet by including a Pad Length field with a + value of zero. + + + + + Padding is a security feature; see . + +
+ +
+ + The HEADERS frame (type=0x1) is used to open a stream, + and additionally carries a header block fragment. HEADERS frames can be sent on a stream + in the "open" or "half closed (remote)" states. + +
+ +
+ + The HEADERS frame payload has the following fields: + + + An 8-bit field containing the length of the frame padding in units of octets. This + field is only present if the PADDED flag is set. + + + A single bit flag indicates that the stream dependency is exclusive, see . This field is only present if the PRIORITY flag is set. + + + A 31-bit stream identifier for the stream that this stream depends on, see . This field is only present if the PRIORITY flag is set. + + + An 8-bit weight for the stream, see . Add one to the + value to obtain a weight between 1 and 256. This field is only present if the + PRIORITY flag is set. + + + A header block fragment. + + + Padding octets that contain no application semantic value. Padding octets MUST be set + to zero when sending and ignored when receiving. + + + + + + The HEADERS frame defines the following flags: + + + + Bit 1 being set indicates that the header block is + the last that the endpoint will send for the identified stream. Setting this flag + causes the stream to enter one of "half closed" + states. + + + A HEADERS frame carries the END_STREAM flag that signals the end of a stream. + However, a HEADERS frame with the END_STREAM flag set can be followed by + CONTINUATION frames on the same stream. Logically, the + CONTINUATION frames are part of the HEADERS frame. + + + + + Bit 3 being set indicates that this frame contains an entire header block and is not followed by any + CONTINUATION frames. + + + A HEADERS frame without the END_HEADERS flag set MUST be followed by a + CONTINUATION frame for the same stream. A receiver MUST treat the + receipt of any other type of frame or a frame on a different stream as a connection error of type + PROTOCOL_ERROR. + + + + + Bit 4 being set indicates that the Pad Length field and any padding that it + describes is present. + + + + + Bit 6 being set indicates that the Exclusive Flag (E), Stream Dependency, and Weight + fields are present; see . + + + + + + + The payload of a HEADERS frame contains a header block + fragment. A header block that does not fit within a HEADERS frame is continued in + a CONTINUATION frame. + + + + HEADERS frames MUST be associated with a stream. If a HEADERS frame is received whose + stream identifier field is 0x0, the recipient MUST respond with a connection error of type + PROTOCOL_ERROR. + + + + The HEADERS frame changes the connection state as described in . + + + + The HEADERS frame includes optional padding. Padding fields and flags are identical to + those defined for DATA frames. + + + Prioritization information in a HEADERS frame is logically equivalent to a separate + PRIORITY frame, but inclusion in HEADERS avoids the potential for churn in + stream prioritization when new streams are created. Priorization fields in HEADERS frames + subsequent to the first on a stream reprioritize the + stream. + +
+ +
+ + The PRIORITY frame (type=0x2) specifies the sender-advised + priority of a stream. It can be sent at any time for an existing stream, including + closed streams. This enables reprioritization of existing streams. + +
+ +
+ + The payload of a PRIORITY frame contains the following fields: + + + A single bit flag indicates that the stream dependency is exclusive, see . + + + A 31-bit stream identifier for the stream that this stream depends on, see . + + + An 8-bit weight for the identified stream dependency, see . Add one to the value to obtain a weight between 1 and 256. + + + + + + The PRIORITY frame does not define any flags. + + + + The PRIORITY frame is associated with an existing stream. If a PRIORITY frame is received + with a stream identifier of 0x0, the recipient MUST respond with a connection error of type + PROTOCOL_ERROR. + + + The PRIORITY frame can be sent on a stream in any of the "reserved (remote)", "open", + "half closed (local)", "half closed (remote)", or "closed" states, though it cannot be + sent between consecutive frames that comprise a single header + block. Note that this frame could arrive after processing or frame sending has + completed, which would cause it to have no effect on the current stream. For a stream + that is in the "half closed (remote)" or "closed" - state, this frame can only affect + processing of the current stream and not frame transmission. + + + The PRIORITY frame is the only frame that can be sent for a stream in the "closed" state. + This allows for the reprioritization of a group of dependent streams by altering the + priority of a parent stream, which might be closed. However, a PRIORITY frame sent on a + closed stream risks being ignored due to the peer having discarded priority state + information for that stream. + +
+ +
+ + The RST_STREAM frame (type=0x3) allows for abnormal termination of a stream. When sent by + the initiator of a stream, it indicates that they wish to cancel the stream or that an + error condition has occurred. When sent by the receiver of a stream, it indicates that + either the receiver is rejecting the stream, requesting that the stream be cancelled, or + that an error condition has occurred. + +
+ +
+ + + The RST_STREAM frame contains a single unsigned, 32-bit integer identifying the error code. The error code indicates why the stream is being + terminated. + + + + The RST_STREAM frame does not define any flags. + + + + The RST_STREAM frame fully terminates the referenced stream and causes it to enter the + closed state. After receiving a RST_STREAM on a stream, the receiver MUST NOT send + additional frames for that stream, with the exception of PRIORITY. However, + after sending the RST_STREAM, the sending endpoint MUST be prepared to receive and process + additional frames sent on the stream that might have been sent by the peer prior to the + arrival of the RST_STREAM. + + + + RST_STREAM frames MUST be associated with a stream. If a RST_STREAM frame is received + with a stream identifier of 0x0, the recipient MUST treat this as a connection error of type + PROTOCOL_ERROR. + + + + RST_STREAM frames MUST NOT be sent for a stream in the "idle" state. If a RST_STREAM + frame identifying an idle stream is received, the recipient MUST treat this as a connection error of type + PROTOCOL_ERROR. + + +
+ +
+ + The SETTINGS frame (type=0x4) conveys configuration parameters that affect how endpoints + communicate, such as preferences and constraints on peer behavior. The SETTINGS frame is + also used to acknowledge the receipt of those parameters. Individually, a SETTINGS + parameter can also be referred to as a "setting". + + + SETTINGS parameters are not negotiated; they describe characteristics of the sending peer, + which are used by the receiving peer. Different values for the same parameter can be + advertised by each peer. For example, a client might set a high initial flow control + window, whereas a server might set a lower value to conserve resources. + + + + A SETTINGS frame MUST be sent by both endpoints at the start of a connection, and MAY be + sent at any other time by either endpoint over the lifetime of the connection. + Implementations MUST support all of the parameters defined by this specification. + + + + Each parameter in a SETTINGS frame replaces any existing value for that parameter. + Parameters are processed in the order in which they appear, and a receiver of a SETTINGS + frame does not need to maintain any state other than the current value of its + parameters. Therefore, the value of a SETTINGS parameter is the last value that is seen by + a receiver. + + + SETTINGS parameters are acknowledged by the receiving peer. To enable this, the SETTINGS + frame defines the following flag: + + + Bit 1 being set indicates that this frame acknowledges receipt and application of the + peer's SETTINGS frame. When this bit is set, the payload of the SETTINGS frame MUST + be empty. Receipt of a SETTINGS frame with the ACK flag set and a length field value + other than 0 MUST be treated as a connection + error of type FRAME_SIZE_ERROR. For more info, see Settings Synchronization. + + + + + SETTINGS frames always apply to a connection, never a single stream. The stream + identifier for a SETTINGS frame MUST be zero (0x0). If an endpoint receives a SETTINGS + frame whose stream identifier field is anything other than 0x0, the endpoint MUST respond + with a connection error of type + PROTOCOL_ERROR. + + + The SETTINGS frame affects connection state. A badly formed or incomplete SETTINGS frame + MUST be treated as a connection error of type + PROTOCOL_ERROR. + + +
+ + The payload of a SETTINGS frame consists of zero or more parameters, each consisting of + an unsigned 16-bit setting identifier and an unsigned 32-bit value. + + +
+ +
+
+ +
+ + The following parameters are defined: + + + + Allows the sender to inform the remote endpoint of the maximum size of the header + compression table used to decode header blocks, in octets. The encoder can select + any size equal to or less than this value by using signaling specific to the + header compression format inside a header block. The initial value is 4,096 + octets. + + + + + This setting can be use to disable server + push. An endpoint MUST NOT send a PUSH_PROMISE frame if it + receives this parameter set to a value of 0. An endpoint that has both set this + parameter to 0 and had it acknowledged MUST treat the receipt of a + PUSH_PROMISE frame as a connection error of type + PROTOCOL_ERROR. + + + The initial value is 1, which indicates that server push is permitted. Any value + other than 0 or 1 MUST be treated as a connection error of type + PROTOCOL_ERROR. + + + + + Indicates the maximum number of concurrent streams that the sender will allow. + This limit is directional: it applies to the number of streams that the sender + permits the receiver to create. Initially there is no limit to this value. It is + recommended that this value be no smaller than 100, so as to not unnecessarily + limit parallelism. + + + A value of 0 for SETTINGS_MAX_CONCURRENT_STREAMS SHOULD NOT be treated as special + by endpoints. A zero value does prevent the creation of new streams, however this + can also happen for any limit that is exhausted with active streams. Servers + SHOULD only set a zero value for short durations; if a server does not wish to + accept requests, closing the connection could be preferable. + + + + + Indicates the sender's initial window size (in octets) for stream level flow + control. The initial value is 216-1 (65,535) octets. + + + This setting affects the window size of all streams, including existing streams, + see . + + + Values above the maximum flow control window size of 231-1 MUST + be treated as a connection error of + type FLOW_CONTROL_ERROR. + + + + + Indicates the size of the largest frame payload that the sender is willing to + receive, in octets. + + + The initial value is 214 (16,384) octets. The value advertised by + an endpoint MUST be between this initial value and the maximum allowed frame size + (224-1 or 16,777,215 octets), inclusive. Values outside this range + MUST be treated as a connection error + of type PROTOCOL_ERROR. + + + + + This advisory setting informs a peer of the maximum size of header list that the + sender is prepared to accept, in octets. The value is based on the uncompressed + size of header fields, including the length of the name and value in octets plus + an overhead of 32 octets for each header field. + + + For any given request, a lower limit than what is advertised MAY be enforced. The + initial value of this setting is unlimited. + + + + + + An endpoint that receives a SETTINGS frame with any unknown or unsupported identifier + MUST ignore that setting. + +
+ +
+ + Most values in SETTINGS benefit from or require an understanding of when the peer has + received and applied the changed parameter values. In order to provide + such synchronization timepoints, the recipient of a SETTINGS frame in which the ACK flag + is not set MUST apply the updated parameters as soon as possible upon receipt. + + + The values in the SETTINGS frame MUST be processed in the order they appear, with no + other frame processing between values. Unsupported parameters MUST be ignored. Once + all values have been processed, the recipient MUST immediately emit a SETTINGS frame + with the ACK flag set. Upon receiving a SETTINGS frame with the ACK flag set, the sender + of the altered parameters can rely on the setting having been applied. + + + If the sender of a SETTINGS frame does not receive an acknowledgement within a + reasonable amount of time, it MAY issue a connection error of type + SETTINGS_TIMEOUT. + +
+
+ +
+ + The PUSH_PROMISE frame (type=0x5) is used to notify the peer endpoint in advance of + streams the sender intends to initiate. The PUSH_PROMISE frame includes the unsigned + 31-bit identifier of the stream the endpoint plans to create along with a set of headers + that provide additional context for the stream. contains a + thorough description of the use of PUSH_PROMISE frames. + + +
+ +
+ + The PUSH_PROMISE frame payload has the following fields: + + + An 8-bit field containing the length of the frame padding in units of octets. This + field is only present if the PADDED flag is set. + + + A single reserved bit. + + + An unsigned 31-bit integer that identifies the stream that is reserved by the + PUSH_PROMISE. The promised stream identifier MUST be a valid choice for the next + stream sent by the sender (see new stream + identifier). + + + A header block fragment containing request header + fields. + + + Padding octets. + + + + + + The PUSH_PROMISE frame defines the following flags: + + + + Bit 3 being set indicates that this frame contains an entire header block and is not followed by any + CONTINUATION frames. + + + A PUSH_PROMISE frame without the END_HEADERS flag set MUST be followed by a + CONTINUATION frame for the same stream. A receiver MUST treat the receipt of any + other type of frame or a frame on a different stream as a connection error of type + PROTOCOL_ERROR. + + + + + Bit 4 being set indicates that the Pad Length field and any padding that it + describes is present. + + + + + + + PUSH_PROMISE frames MUST be associated with an existing, peer-initiated stream. The stream + identifier of a PUSH_PROMISE frame indicates the stream it is associated with. If the + stream identifier field specifies the value 0x0, a recipient MUST respond with a connection error of type + PROTOCOL_ERROR. + + + + Promised streams are not required to be used in the order they are promised. The + PUSH_PROMISE only reserves stream identifiers for later use. + + + + PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH setting of the + peer endpoint is set to 0. An endpoint that has set this setting and has received + acknowledgement MUST treat the receipt of a PUSH_PROMISE frame as a connection error of type + PROTOCOL_ERROR. + + + Recipients of PUSH_PROMISE frames can choose to reject promised streams by returning a + RST_STREAM referencing the promised stream identifier back to the sender of + the PUSH_PROMISE. + + + + A PUSH_PROMISE frame modifies the connection state in two ways. The inclusion of a header block potentially modifies the state maintained for + header compression. PUSH_PROMISE also reserves a stream for later use, causing the + promised stream to enter the "reserved" state. A sender MUST NOT send a PUSH_PROMISE on a + stream unless that stream is either "open" or "half closed (remote)"; the sender MUST + ensure that the promised stream is a valid choice for a new stream identifier (that is, the promised stream MUST + be in the "idle" state). + + + Since PUSH_PROMISE reserves a stream, ignoring a PUSH_PROMISE frame causes the stream + state to become indeterminate. A receiver MUST treat the receipt of a PUSH_PROMISE on a + stream that is neither "open" nor "half closed (local)" as a connection error of type + PROTOCOL_ERROR. However, an endpoint that has sent + RST_STREAM on the associated stream MUST handle PUSH_PROMISE frames that + might have been created before the RST_STREAM frame is received and + processed. + + + A receiver MUST treat the receipt of a PUSH_PROMISE that promises an illegal stream identifier (that is, an identifier for a + stream that is not currently in the "idle" state) as a connection error of type + PROTOCOL_ERROR. + + + + The PUSH_PROMISE frame includes optional padding. Padding fields and flags are identical + to those defined for DATA frames. + +
+ +
+ + The PING frame (type=0x6) is a mechanism for measuring a minimal round trip time from the + sender, as well as determining whether an idle connection is still functional. PING + frames can be sent from any endpoint. + +
+ +
+ + + In addition to the frame header, PING frames MUST contain 8 octets of data in the payload. + A sender can include any value it chooses and use those bytes in any fashion. + + + Receivers of a PING frame that does not include an ACK flag MUST send a PING frame with + the ACK flag set in response, with an identical payload. PING responses SHOULD be given + higher priority than any other frame. + + + + The PING frame defines the following flags: + + + Bit 1 being set indicates that this PING frame is a PING response. An endpoint MUST + set this flag in PING responses. An endpoint MUST NOT respond to PING frames + containing this flag. + + + + + PING frames are not associated with any individual stream. If a PING frame is received + with a stream identifier field value other than 0x0, the recipient MUST respond with a + connection error of type + PROTOCOL_ERROR. + + + Receipt of a PING frame with a length field value other than 8 MUST be treated as a connection error of type + FRAME_SIZE_ERROR. + + +
+ +
+ + The GOAWAY frame (type=0x7) informs the remote peer to stop creating streams on this + connection. GOAWAY can be sent by either the client or the server. Once sent, the sender + will ignore frames sent on any new streams with identifiers higher than the included last + stream identifier. Receivers of a GOAWAY frame MUST NOT open additional streams on the + connection, although a new connection can be established for new streams. + + + The purpose of this frame is to allow an endpoint to gracefully stop accepting new + streams, while still finishing processing of previously established streams. This enables + administrative actions, like server maintainance. + + + There is an inherent race condition between an endpoint starting new streams and the + remote sending a GOAWAY frame. To deal with this case, the GOAWAY contains the stream + identifier of the last peer-initiated stream which was or might be processed on the + sending endpoint in this connection. For instance, if the server sends a GOAWAY frame, + the identified stream is the highest numbered stream initiated by the client. + + + If the receiver of the GOAWAY has sent data on streams with a higher stream identifier + than what is indicated in the GOAWAY frame, those streams are not or will not be + processed. The receiver of the GOAWAY frame can treat the streams as though they had + never been created at all, thereby allowing those streams to be retried later on a new + connection. + + + Endpoints SHOULD always send a GOAWAY frame before closing a connection so that the remote + can know whether a stream has been partially processed or not. For example, if an HTTP + client sends a POST at the same time that a server closes a connection, the client cannot + know if the server started to process that POST request if the server does not send a + GOAWAY frame to indicate what streams it might have acted on. + + + An endpoint might choose to close a connection without sending GOAWAY for misbehaving + peers. + + +
+ +
+ + The GOAWAY frame does not define any flags. + + + The GOAWAY frame applies to the connection, not a specific stream. An endpoint MUST treat + a GOAWAY frame with a stream identifier other than 0x0 as a connection error of type + PROTOCOL_ERROR. + + + The last stream identifier in the GOAWAY frame contains the highest numbered stream + identifier for which the sender of the GOAWAY frame might have taken some action on, or + might yet take action on. All streams up to and including the identified stream might + have been processed in some way. The last stream identifier can be set to 0 if no streams + were processed. + + + In this context, "processed" means that some data from the stream was passed to some + higher layer of software that might have taken some action as a result. + + + If a connection terminates without a GOAWAY frame, the last stream identifier is + effectively the highest possible stream identifier. + + + On streams with lower or equal numbered identifiers that were not closed completely prior + to the connection being closed, re-attempting requests, transactions, or any protocol + activity is not possible, with the exception of idempotent actions like HTTP GET, PUT, or + DELETE. Any protocol activity that uses higher numbered streams can be safely retried + using a new connection. + + + Activity on streams numbered lower or equal to the last stream identifier might still + complete successfully. The sender of a GOAWAY frame might gracefully shut down a + connection by sending a GOAWAY frame, maintaining the connection in an open state until + all in-progress streams complete. + + + An endpoint MAY send multiple GOAWAY frames if circumstances change. For instance, an + endpoint that sends GOAWAY with NO_ERROR during graceful shutdown could + subsequently encounter an condition that requires immediate termination of the connection. + The last stream identifier from the last GOAWAY frame received indicates which streams + could have been acted upon. Endpoints MUST NOT increase the value they send in the last + stream identifier, since the peers might already have retried unprocessed requests on + another connection. + + + A client that is unable to retry requests loses all requests that are in flight when the + server closes the connection. This is especially true for intermediaries that might + not be serving clients using HTTP/2. A server that is attempting to gracefully shut down + a connection SHOULD send an initial GOAWAY frame with the last stream identifier set to + 231-1 and a NO_ERROR code. This signals to the client that + a shutdown is imminent and that no further requests can be initiated. After waiting at + least one round trip time, the server can send another GOAWAY frame with an updated last + stream identifier. This ensures that a connection can be cleanly shut down without losing + requests. + + + + After sending a GOAWAY frame, the sender can discard frames for streams with identifiers + higher than the identified last stream. However, any frames that alter connection state + cannot be completely ignored. For instance, HEADERS, + PUSH_PROMISE and CONTINUATION frames MUST be minimally + processed to ensure the state maintained for header compression is consistent (see ); similarly DATA frames MUST be counted toward the connection flow + control window. Failure to process these frames can cause flow control or header + compression state to become unsynchronized. + + + + The GOAWAY frame also contains a 32-bit error code that + contains the reason for closing the connection. + + + Endpoints MAY append opaque data to the payload of any GOAWAY frame. Additional debug + data is intended for diagnostic purposes only and carries no semantic value. Debug + information could contain security- or privacy-sensitive data. Logged or otherwise + persistently stored debug data MUST have adequate safeguards to prevent unauthorized + access. + +
+ +
+ + The WINDOW_UPDATE frame (type=0x8) is used to implement flow control; see for an overview. + + + Flow control operates at two levels: on each individual stream and on the entire + connection. + + + Both types of flow control are hop-by-hop; that is, only between the two endpoints. + Intermediaries do not forward WINDOW_UPDATE frames between dependent connections. + However, throttling of data transfer by any receiver can indirectly cause the propagation + of flow control information toward the original sender. + + + Flow control only applies to frames that are identified as being subject to flow control. + Of the frame types defined in this document, this includes only DATA frames. + Frames that are exempt from flow control MUST be accepted and processed, unless the + receiver is unable to assign resources to handling the frame. A receiver MAY respond with + a stream error or connection error of type + FLOW_CONTROL_ERROR if it is unable to accept a frame. + +
+ +
+ + The payload of a WINDOW_UPDATE frame is one reserved bit, plus an unsigned 31-bit integer + indicating the number of octets that the sender can transmit in addition to the existing + flow control window. The legal range for the increment to the flow control window is 1 to + 231-1 (0x7fffffff) octets. + + + The WINDOW_UPDATE frame does not define any flags. + + + The WINDOW_UPDATE frame can be specific to a stream or to the entire connection. In the + former case, the frame's stream identifier indicates the affected stream; in the latter, + the value "0" indicates that the entire connection is the subject of the frame. + + + A receiver MUST treat the receipt of a WINDOW_UPDATE frame with an flow control window + increment of 0 as a stream error of type + PROTOCOL_ERROR; errors on the connection flow control window MUST be + treated as a connection error. + + + WINDOW_UPDATE can be sent by a peer that has sent a frame bearing the END_STREAM flag. + This means that a receiver could receive a WINDOW_UPDATE frame on a "half closed (remote)" + or "closed" stream. A receiver MUST NOT treat this as an error, see . + + + A receiver that receives a flow controlled frame MUST always account for its contribution + against the connection flow control window, unless the receiver treats this as a connection error. This is necessary even if the + frame is in error. Since the sender counts the frame toward the flow control window, if + the receiver does not, the flow control window at sender and receiver can become + different. + + +
+ + Flow control in HTTP/2 is implemented using a window kept by each sender on every + stream. The flow control window is a simple integer value that indicates how many octets + of data the sender is permitted to transmit; as such, its size is a measure of the + buffering capacity of the receiver. + + + Two flow control windows are applicable: the stream flow control window and the + connection flow control window. The sender MUST NOT send a flow controlled frame with a + length that exceeds the space available in either of the flow control windows advertised + by the receiver. Frames with zero length with the END_STREAM flag set (that is, an + empty DATA frame) MAY be sent if there is no available space in either + flow control window. + + + For flow control calculations, the 9 octet frame header is not counted. + + + After sending a flow controlled frame, the sender reduces the space available in both + windows by the length of the transmitted frame. + + + The receiver of a frame sends a WINDOW_UPDATE frame as it consumes data and frees up + space in flow control windows. Separate WINDOW_UPDATE frames are sent for the stream + and connection level flow control windows. + + + A sender that receives a WINDOW_UPDATE frame updates the corresponding window by the + amount specified in the frame. + + + A sender MUST NOT allow a flow control window to exceed 231-1 octets. + If a sender receives a WINDOW_UPDATE that causes a flow control window to exceed this + maximum it MUST terminate either the stream or the connection, as appropriate. For + streams, the sender sends a RST_STREAM with the error code of + FLOW_CONTROL_ERROR code; for the connection, a GOAWAY + frame with a FLOW_CONTROL_ERROR code. + + + Flow controlled frames from the sender and WINDOW_UPDATE frames from the receiver are + completely asynchronous with respect to each other. This property allows a receiver to + aggressively update the window size kept by the sender to prevent streams from stalling. + +
+ +
+ + When an HTTP/2 connection is first established, new streams are created with an initial + flow control window size of 65,535 octets. The connection flow control window is 65,535 + octets. Both endpoints can adjust the initial window size for new streams by including + a value for SETTINGS_INITIAL_WINDOW_SIZE in the SETTINGS + frame that forms part of the connection preface. The connection flow control window can + only be changed using WINDOW_UPDATE frames. + + + Prior to receiving a SETTINGS frame that sets a value for + SETTINGS_INITIAL_WINDOW_SIZE, an endpoint can only use the default + initial window size when sending flow controlled frames. Similarly, the connection flow + control window is set to the default initial window size until a WINDOW_UPDATE frame is + received. + + + A SETTINGS frame can alter the initial flow control window size for all + current streams. When the value of SETTINGS_INITIAL_WINDOW_SIZE changes, + a receiver MUST adjust the size of all stream flow control windows that it maintains by + the difference between the new value and the old value. + + + A change to SETTINGS_INITIAL_WINDOW_SIZE can cause the available space in + a flow control window to become negative. A sender MUST track the negative flow control + window, and MUST NOT send new flow controlled frames until it receives WINDOW_UPDATE + frames that cause the flow control window to become positive. + + + For example, if the client sends 60KB immediately on connection establishment, and the + server sets the initial window size to be 16KB, the client will recalculate the + available flow control window to be -44KB on receipt of the SETTINGS + frame. The client retains a negative flow control window until WINDOW_UPDATE frames + restore the window to being positive, after which the client can resume sending. + + + A SETTINGS frame cannot alter the connection flow control window. + + + An endpoint MUST treat a change to SETTINGS_INITIAL_WINDOW_SIZE that + causes any flow control window to exceed the maximum size as a connection error of type + FLOW_CONTROL_ERROR. + +
+ +
+ + A receiver that wishes to use a smaller flow control window than the current size can + send a new SETTINGS frame. However, the receiver MUST be prepared to + receive data that exceeds this window size, since the sender might send data that + exceeds the lower limit prior to processing the SETTINGS frame. + + + After sending a SETTINGS frame that reduces the initial flow control window size, a + receiver has two options for handling streams that exceed flow control limits: + + + The receiver can immediately send RST_STREAM with + FLOW_CONTROL_ERROR error code for the affected streams. + + + The receiver can accept the streams and tolerate the resulting head of line + blocking, sending WINDOW_UPDATE frames as it consumes data. + + + +
+
+ +
+ + The CONTINUATION frame (type=0x9) is used to continue a sequence of header block fragments. Any number of CONTINUATION frames can + be sent on an existing stream, as long as the preceding frame is on the same stream and is + a HEADERS, PUSH_PROMISE or CONTINUATION frame without the + END_HEADERS flag set. + + +
+ +
+ + The CONTINUATION frame payload contains a header block + fragment. + + + + The CONTINUATION frame defines the following flag: + + + + Bit 3 being set indicates that this frame ends a header + block. + + + If the END_HEADERS bit is not set, this frame MUST be followed by another + CONTINUATION frame. A receiver MUST treat the receipt of any other type of frame or + a frame on a different stream as a connection + error of type PROTOCOL_ERROR. + + + + + + + The CONTINUATION frame changes the connection state as defined in . + + + + CONTINUATION frames MUST be associated with a stream. If a CONTINUATION frame is received + whose stream identifier field is 0x0, the recipient MUST respond with a connection error of type PROTOCOL_ERROR. + + + + A CONTINUATION frame MUST be preceded by a HEADERS, + PUSH_PROMISE or CONTINUATION frame without the END_HEADERS flag set. A + recipient that observes violation of this rule MUST respond with a connection error of type + PROTOCOL_ERROR. + +
+
+ +
+ + Error codes are 32-bit fields that are used in RST_STREAM and + GOAWAY frames to convey the reasons for the stream or connection error. + + + + Error codes share a common code space. Some error codes apply only to either streams or the + entire connection and have no defined semantics in the other context. + + + + The following error codes are defined: + + + The associated condition is not as a result of an error. For example, a + GOAWAY might include this code to indicate graceful shutdown of a + connection. + + + The endpoint detected an unspecific protocol error. This error is for use when a more + specific error code is not available. + + + The endpoint encountered an unexpected internal error. + + + The endpoint detected that its peer violated the flow control protocol. + + + The endpoint sent a SETTINGS frame, but did not receive a response in a + timely manner. See Settings Synchronization. + + + The endpoint received a frame after a stream was half closed. + + + The endpoint received a frame with an invalid size. + + + The endpoint refuses the stream prior to performing any application processing, see + for details. + + + Used by the endpoint to indicate that the stream is no longer needed. + + + The endpoint is unable to maintain the header compression context for the connection. + + + The connection established in response to a CONNECT + request was reset or abnormally closed. + + + The endpoint detected that its peer is exhibiting a behavior that might be generating + excessive load. + + + The underlying transport has properties that do not meet minimum security + requirements (see ). + + + + + Unknown or unsupported error codes MUST NOT trigger any special behavior. These MAY be + treated by an implementation as being equivalent to INTERNAL_ERROR. + +
+ +
+ + HTTP/2 is intended to be as compatible as possible with current uses of HTTP. This means + that, from the application perspective, the features of the protocol are largely + unchanged. To achieve this, all request and response semantics are preserved, although the + syntax of conveying those semantics has changed. + + + Thus, the specification and requirements of HTTP/1.1 Semantics and Content , Conditional Requests , Range Requests , Caching and Authentication are applicable to HTTP/2. Selected portions of HTTP/1.1 Message Syntax + and Routing , such as the HTTP and HTTPS URI schemes, are also + applicable in HTTP/2, but the expression of those semantics for this protocol are defined + in the sections below. + + +
+ + A client sends an HTTP request on a new stream, using a previously unused stream identifier. A server sends an HTTP response on + the same stream as the request. + + + An HTTP message (request or response) consists of: + + + for a response only, zero or more HEADERS frames (each followed by zero + or more CONTINUATION frames) containing the message headers of + informational (1xx) HTTP responses (see and ), + and + + + one HEADERS frame (followed by zero or more CONTINUATION + frames) containing the message headers (see ), and + + + zero or more DATA frames containing the message payload (see ), and + + + optionally, one HEADERS frame, followed by zero or more + CONTINUATION frames containing the trailer-part, if present (see ). + + + The last frame in the sequence bears an END_STREAM flag, noting that a + HEADERS frame bearing the END_STREAM flag can be followed by + CONTINUATION frames that carry any remaining portions of the header block. + + + Other frames (from any stream) MUST NOT occur between either HEADERS frame + and any CONTINUATION frames that might follow. + + + + Trailing header fields are carried in a header block that also terminates the stream. + That is, a sequence starting with a HEADERS frame, followed by zero or more + CONTINUATION frames, where the HEADERS frame bears an + END_STREAM flag. Header blocks after the first that do not terminate the stream are not + part of an HTTP request or response. + + + A HEADERS frame (and associated CONTINUATION frames) can + only appear at the start or end of a stream. An endpoint that receives a + HEADERS frame without the END_STREAM flag set after receiving a final + (non-informational) status code MUST treat the corresponding request or response as malformed. + + + + An HTTP request/response exchange fully consumes a single stream. A request starts with + the HEADERS frame that puts the stream into an "open" state. The request + ends with a frame bearing END_STREAM, which causes the stream to become "half closed + (local)" for the client and "half closed (remote)" for the server. A response starts with + a HEADERS frame and ends with a frame bearing END_STREAM, which places the + stream in the "closed" state. + + + +
+ + HTTP/2 removes support for the 101 (Switching Protocols) informational status code + (). + + + The semantics of 101 (Switching Protocols) aren't applicable to a multiplexed protocol. + Alternative protocols are able to use the same mechanisms that HTTP/2 uses to negotiate + their use (see ). + +
+ +
+ + HTTP header fields carry information as a series of key-value pairs. For a listing of + registered HTTP headers, see the Message Header Field Registry maintained at . + + +
+ + While HTTP/1.x used the message start-line (see ) to convey the target URI and method of the request, and the + status code for the response, HTTP/2 uses special pseudo-header fields beginning with + ':' character (ASCII 0x3a) for this purpose. + + + Pseudo-header fields are not HTTP header fields. Endpoints MUST NOT generate + pseudo-header fields other than those defined in this document. + + + Pseudo-header fields are only valid in the context in which they are defined. + Pseudo-header fields defined for requests MUST NOT appear in responses; pseudo-header + fields defined for responses MUST NOT appear in requests. Pseudo-header fields MUST + NOT appear in trailers. Endpoints MUST treat a request or response that contains + undefined or invalid pseudo-header fields as malformed. + + + Just as in HTTP/1.x, header field names are strings of ASCII characters that are + compared in a case-insensitive fashion. However, header field names MUST be converted + to lowercase prior to their encoding in HTTP/2. A request or response containing + uppercase header field names MUST be treated as malformed. + + + All pseudo-header fields MUST appear in the header block before regular header fields. + Any request or response that contains a pseudo-header field that appears in a header + block after a regular header field MUST be treated as malformed. + +
+ +
+ + HTTP/2 does not use the Connection header field to + indicate connection-specific header fields; in this protocol, connection-specific + metadata is conveyed by other means. An endpoint MUST NOT generate a HTTP/2 message + containing connection-specific header fields; any message containing + connection-specific header fields MUST be treated as malformed. + + + This means that an intermediary transforming an HTTP/1.x message to HTTP/2 will need + to remove any header fields nominated by the Connection header field, along with the + Connection header field itself. Such intermediaries SHOULD also remove other + connection-specific header fields, such as Keep-Alive, Proxy-Connection, + Transfer-Encoding and Upgrade, even if they are not nominated by Connection. + + + One exception to this is the TE header field, which MAY be present in an HTTP/2 + request, but when it is MUST NOT contain any value other than "trailers". + + + + + HTTP/2 purposefully does not support upgrade to another protocol. The handshake + methods described in are believed sufficient to + negotiate the use of alternative protocols. + + + +
+ +
+ + The following pseudo-header fields are defined for HTTP/2 requests: + + + + The :method pseudo-header field includes the HTTP + method (). + + + + + The :scheme pseudo-header field includes the scheme + portion of the target URI (). + + + :scheme is not restricted to http and https schemed URIs. A + proxy or gateway can translate requests for non-HTTP schemes, enabling the use + of HTTP to interact with non-HTTP services. + + + + + The :authority pseudo-header field includes the + authority portion of the target URI (). The authority MUST NOT include the deprecated userinfo subcomponent for http + or https schemed URIs. + + + To ensure that the HTTP/1.1 request line can be reproduced accurately, this + pseudo-header field MUST be omitted when translating from an HTTP/1.1 request + that has a request target in origin or asterisk form (see ). Clients that generate + HTTP/2 requests directly SHOULD use the :authority pseudo-header + field instead of the Host header field. An + intermediary that converts an HTTP/2 request to HTTP/1.1 MUST create a Host header field if one is not present in a request by + copying the value of the :authority pseudo-header + field. + + + + + The :path pseudo-header field includes the path and + query parts of the target URI (the path-absolute + production from and optionally a '?' character + followed by the query production, see and ). A request in asterisk form includes the value '*' for the + :path pseudo-header field. + + + This pseudo-header field MUST NOT be empty for http + or https URIs; http or + https URIs that do not contain a path component + MUST include a value of '/'. The exception to this rule is an OPTIONS request + for an http or https + URI that does not include a path component; these MUST include a :path pseudo-header field with a value of '*' (see ). + + + + + + All HTTP/2 requests MUST include exactly one valid value for the :method, :scheme, and :path pseudo-header fields, unless it is a CONNECT request. An HTTP request that omits mandatory + pseudo-header fields is malformed. + + + HTTP/2 does not define a way to carry the version identifier that is included in the + HTTP/1.1 request line. + +
+ +
+ + For HTTP/2 responses, a single :status pseudo-header + field is defined that carries the HTTP status code field (see ). This pseudo-header field MUST be included in all + responses, otherwise the response is malformed. + + + HTTP/2 does not define a way to carry the version or reason phrase that is included in + an HTTP/1.1 status line. + +
+ +
+ + The Cookie header field can carry a significant amount of + redundant data. + + + The Cookie header field uses a semi-colon (";") to delimit cookie-pairs (or "crumbs"). + This header field doesn't follow the list construction rules in HTTP (see ), which prevents cookie-pairs from + being separated into different name-value pairs. This can significantly reduce + compression efficiency as individual cookie-pairs are updated. + + + To allow for better compression efficiency, the Cookie header field MAY be split into + separate header fields, each with one or more cookie-pairs. If there are multiple + Cookie header fields after decompression, these MUST be concatenated into a single + octet string using the two octet delimiter of 0x3B, 0x20 (the ASCII string "; ") + before being passed into a non-HTTP/2 context, such as an HTTP/1.1 connection, or a + generic HTTP server application. + +
+ + Therefore, the following two lists of Cookie header fields are semantically + equivalent. + + +
+
+ +
+ + A malformed request or response is one that is an otherwise valid sequence of HTTP/2 + frames, but is otherwise invalid due to the presence of extraneous frames, prohibited + header fields, the absence of mandatory header fields, or the inclusion of uppercase + header field names. + + + A request or response that includes an entity body can include a content-length header field. A request or response is also + malformed if the value of a content-length header field + does not equal the sum of the DATA frame payload lengths that form the + body. A response that is defined to have no payload, as described in , can have a non-zero + content-length header field, even though no content is + included in DATA frames. + + + Intermediaries that process HTTP requests or responses (i.e., any intermediary not + acting as a tunnel) MUST NOT forward a malformed request or response. Malformed + requests or responses that are detected MUST be treated as a stream error of type PROTOCOL_ERROR. + + + For malformed requests, a server MAY send an HTTP response prior to closing or + resetting the stream. Clients MUST NOT accept a malformed response. Note that these + requirements are intended to protect against several types of common attacks against + HTTP; they are deliberately strict, because being permissive can expose + implementations to these vulnerabilities. + +
+
+ +
+ + This section shows HTTP/1.1 requests and responses, with illustrations of equivalent + HTTP/2 requests and responses. + + + An HTTP GET request includes request header fields and no body and is therefore + transmitted as a single HEADERS frame, followed by zero or more + CONTINUATION frames containing the serialized block of request header + fields. The HEADERS frame in the following has both the END_HEADERS and + END_STREAM flags set; no CONTINUATION frames are sent: + + +
+ + END_STREAM + Accept: image/jpeg + END_HEADERS + :method = GET + :scheme = https + :path = /resource + host = example.org + accept = image/jpeg +]]> +
+ + + Similarly, a response that includes only response header fields is transmitted as a + HEADERS frame (again, followed by zero or more + CONTINUATION frames) containing the serialized block of response header + fields. + + +
+ + END_STREAM + Expires: Thu, 23 Jan ... + END_HEADERS + :status = 304 + etag = "xyzzy" + expires = Thu, 23 Jan ... +]]> +
+ + + An HTTP POST request that includes request header fields and payload data is transmitted + as one HEADERS frame, followed by zero or more + CONTINUATION frames containing the request header fields, followed by one + or more DATA frames, with the last CONTINUATION (or + HEADERS) frame having the END_HEADERS flag set and the final + DATA frame having the END_STREAM flag set: + + +
+ - END_STREAM + Content-Type: image/jpeg - END_HEADERS + Content-Length: 123 :method = POST + :path = /resource + {binary data} :scheme = https + + CONTINUATION + + END_HEADERS + content-type = image/jpeg + host = example.org + content-length = 123 + + DATA + + END_STREAM + {binary data} +]]> + + Note that data contributing to any given header field could be spread between header + block fragments. The allocation of header fields to frames in this example is + illustrative only. + +
+ + + A response that includes header fields and payload data is transmitted as a + HEADERS frame, followed by zero or more CONTINUATION + frames, followed by one or more DATA frames, with the last + DATA frame in the sequence having the END_STREAM flag set: + + +
+ - END_STREAM + Content-Length: 123 + END_HEADERS + :status = 200 + {binary data} content-type = image/jpeg + content-length = 123 + + DATA + + END_STREAM + {binary data} +]]> +
+ + + Trailing header fields are sent as a header block after both the request or response + header block and all the DATA frames have been sent. The + HEADERS frame starting the trailers header block has the END_STREAM flag + set. + + +
+ - END_STREAM + Transfer-Encoding: chunked + END_HEADERS + Trailer: Foo :status = 200 + content-length = 123 + 123 content-type = image/jpeg + {binary data} trailer = Foo + 0 + Foo: bar DATA + - END_STREAM + {binary data} + + HEADERS + + END_STREAM + + END_HEADERS + foo = bar +]]> +
+ + +
+ + An informational response using a 1xx status code other than 101 is transmitted as a + HEADERS frame, followed by zero or more CONTINUATION + frames: + + - END_STREAM + + END_HEADERS + :status = 103 + extension-field = bar +]]> +
+
+ +
+ + In HTTP/1.1, an HTTP client is unable to retry a non-idempotent request when an error + occurs, because there is no means to determine the nature of the error. It is possible + that some server processing occurred prior to the error, which could result in + undesirable effects if the request were reattempted. + + + HTTP/2 provides two mechanisms for providing a guarantee to a client that a request has + not been processed: + + + The GOAWAY frame indicates the highest stream number that might have + been processed. Requests on streams with higher numbers are therefore guaranteed to + be safe to retry. + + + The REFUSED_STREAM error code can be included in a + RST_STREAM frame to indicate that the stream is being closed prior to + any processing having occurred. Any request that was sent on the reset stream can + be safely retried. + + + + + Requests that have not been processed have not failed; clients MAY automatically retry + them, even those with non-idempotent methods. + + + A server MUST NOT indicate that a stream has not been processed unless it can guarantee + that fact. If frames that are on a stream are passed to the application layer for any + stream, then REFUSED_STREAM MUST NOT be used for that stream, and a + GOAWAY frame MUST include a stream identifier that is greater than or + equal to the given stream identifier. + + + In addition to these mechanisms, the PING frame provides a way for a + client to easily test a connection. Connections that remain idle can become broken as + some middleboxes (for instance, network address translators, or load balancers) silently + discard connection bindings. The PING frame allows a client to safely + test whether a connection is still active without sending a request. + +
+
+ +
+ + HTTP/2 allows a server to pre-emptively send (or "push") responses (along with + corresponding "promised" requests) to a client in association with a previous + client-initiated request. This can be useful when the server knows the client will need + to have those responses available in order to fully process the response to the original + request. + + + + Pushing additional message exchanges in this fashion is optional, and is negotiated + between individual endpoints. The SETTINGS_ENABLE_PUSH setting can be set + to 0 to indicate that server push is disabled. + + + Promised requests MUST be cacheable (see ), MUST be safe (see ) and MUST NOT include a request body. Clients that receive a + promised request that is not cacheable, unsafe or that includes a request body MUST + reset the stream with a stream error of type + PROTOCOL_ERROR. + + + Pushed responses that are cacheable (see ) can be stored by the client, if it implements a HTTP + cache. Pushed responses are considered successfully validated on the origin server (e.g., + if the "no-cache" cache response directive is present) while the stream identified by the + promised stream ID is still open. + + + Pushed responses that are not cacheable MUST NOT be stored by any HTTP cache. They MAY + be made available to the application separately. + + + An intermediary can receive pushes from the server and choose not to forward them on to + the client. In other words, how to make use of the pushed information is up to that + intermediary. Equally, the intermediary might choose to make additional pushes to the + client, without any action taken by the server. + + + A client cannot push. Thus, servers MUST treat the receipt of a + PUSH_PROMISE frame as a connection + error of type PROTOCOL_ERROR. Clients MUST reject any attempt to + change the SETTINGS_ENABLE_PUSH setting to a value other than 0 by treating + the message as a connection error of type + PROTOCOL_ERROR. + + +
+ + Server push is semantically equivalent to a server responding to a request; however, in + this case that request is also sent by the server, as a PUSH_PROMISE + frame. + + + The PUSH_PROMISE frame includes a header block that contains a complete + set of request header fields that the server attributes to the request. It is not + possible to push a response to a request that includes a request body. + + + + Pushed responses are always associated with an explicit request from the client. The + PUSH_PROMISE frames sent by the server are sent on that explicit + request's stream. The PUSH_PROMISE frame also includes a promised stream + identifier, chosen from the stream identifiers available to the server (see ). + + + + The header fields in PUSH_PROMISE and any subsequent + CONTINUATION frames MUST be a valid and complete set of request header fields. The server MUST include a method in + the :method header field that is safe and cacheable. If a + client receives a PUSH_PROMISE that does not include a complete and valid + set of header fields, or the :method header field identifies + a method that is not safe, it MUST respond with a stream error of type PROTOCOL_ERROR. + + + + The server SHOULD send PUSH_PROMISE () + frames prior to sending any frames that reference the promised responses. This avoids a + race where clients issue requests prior to receiving any PUSH_PROMISE + frames. + + + For example, if the server receives a request for a document containing embedded links + to multiple image files, and the server chooses to push those additional images to the + client, sending push promises before the DATA frames that contain the + image links ensures that the client is able to see the promises before discovering + embedded links. Similarly, if the server pushes responses referenced by the header block + (for instance, in Link header fields), sending the push promises before sending the + header block ensures that clients do not request them. + + + + PUSH_PROMISE frames MUST NOT be sent by the client. + + + PUSH_PROMISE frames can be sent by the server in response to any + client-initiated stream, but the stream MUST be in either the "open" or "half closed + (remote)" state with respect to the server. PUSH_PROMISE frames are + interspersed with the frames that comprise a response, though they cannot be + interspersed with HEADERS and CONTINUATION frames that + comprise a single header block. + + + Sending a PUSH_PROMISE frame creates a new stream and puts the stream + into the “reserved (local)” state for the server and the “reserved (remote)” state for + the client. + +
+ +
+ + After sending the PUSH_PROMISE frame, the server can begin delivering the + pushed response as a response on a server-initiated + stream that uses the promised stream identifier. The server uses this stream to + transmit an HTTP response, using the same sequence of frames as defined in . This stream becomes "half closed" + to the client after the initial HEADERS frame is sent. + + + + Once a client receives a PUSH_PROMISE frame and chooses to accept the + pushed response, the client SHOULD NOT issue any requests for the promised response + until after the promised stream has closed. + + + + If the client determines, for any reason, that it does not wish to receive the pushed + response from the server, or if the server takes too long to begin sending the promised + response, the client can send an RST_STREAM frame, using either the + CANCEL or REFUSED_STREAM codes, and referencing the pushed + stream's identifier. + + + A client can use the SETTINGS_MAX_CONCURRENT_STREAMS setting to limit the + number of responses that can be concurrently pushed by a server. Advertising a + SETTINGS_MAX_CONCURRENT_STREAMS value of zero disables server push by + preventing the server from creating the necessary streams. This does not prohibit a + server from sending PUSH_PROMISE frames; clients need to reset any + promised streams that are not wanted. + + + + Clients receiving a pushed response MUST validate that either the server is + authoritative (see ), or the proxy that provided the pushed + response is configured for the corresponding request. For example, a server that offers + a certificate for only the example.com DNS-ID or Common Name + is not permitted to push a response for https://www.example.org/doc. + + + The response for a PUSH_PROMISE stream begins with a + HEADERS frame, which immediately puts the stream into the “half closed + (remote)” state for the server and “half closed (local)” state for the client, and ends + with a frame bearing END_STREAM, which places the stream in the "closed" state. + + + The client never sends a frame with the END_STREAM flag for a server push. + + + +
+ +
+ +
+ + In HTTP/1.x, the pseudo-method CONNECT () is used to convert an HTTP connection into a tunnel to a remote host. + CONNECT is primarily used with HTTP proxies to establish a TLS session with an origin + server for the purposes of interacting with https resources. + + + In HTTP/2, the CONNECT method is used to establish a tunnel over a single HTTP/2 stream to + a remote host, for similar purposes. The HTTP header field mapping works as defined in + Request Header Fields, with a few + differences. Specifically: + + + The :method header field is set to CONNECT. + + + The :scheme and :path header + fields MUST be omitted. + + + The :authority header field contains the host and port to + connect to (equivalent to the authority-form of the request-target of CONNECT + requests, see ). + + + + + A proxy that supports CONNECT establishes a TCP connection to + the server identified in the :authority header field. Once + this connection is successfully established, the proxy sends a HEADERS + frame containing a 2xx series status code to the client, as defined in . + + + After the initial HEADERS frame sent by each peer, all subsequent + DATA frames correspond to data sent on the TCP connection. The payload of + any DATA frames sent by the client is transmitted by the proxy to the TCP + server; data received from the TCP server is assembled into DATA frames by + the proxy. Frame types other than DATA or stream management frames + (RST_STREAM, WINDOW_UPDATE, and PRIORITY) + MUST NOT be sent on a connected stream, and MUST be treated as a stream error if received. + + + The TCP connection can be closed by either peer. The END_STREAM flag on a + DATA frame is treated as being equivalent to the TCP FIN bit. A client is + expected to send a DATA frame with the END_STREAM flag set after receiving + a frame bearing the END_STREAM flag. A proxy that receives a DATA frame + with the END_STREAM flag set sends the attached data with the FIN bit set on the last TCP + segment. A proxy that receives a TCP segment with the FIN bit set sends a + DATA frame with the END_STREAM flag set. Note that the final TCP segment + or DATA frame could be empty. + + + A TCP connection error is signaled with RST_STREAM. A proxy treats any + error in the TCP connection, which includes receiving a TCP segment with the RST bit set, + as a stream error of type + CONNECT_ERROR. Correspondingly, a proxy MUST send a TCP segment with the + RST bit set if it detects an error with the stream or the HTTP/2 connection. + +
+
+ +
+ + This section outlines attributes of the HTTP protocol that improve interoperability, reduce + exposure to known security vulnerabilities, or reduce the potential for implementation + variation. + + +
+ + HTTP/2 connections are persistent. For best performance, it is expected clients will not + close connections until it is determined that no further communication with a server is + necessary (for example, when a user navigates away from a particular web page), or until + the server closes the connection. + + + Clients SHOULD NOT open more than one HTTP/2 connection to a given host and port pair, + where host is derived from a URI, a selected alternative + service, or a configured proxy. + + + A client can create additional connections as replacements, either to replace connections + that are near to exhausting the available stream + identifier space, to refresh the keying material for a TLS connection, or to + replace connections that have encountered errors. + + + A client MAY open multiple connections to the same IP address and TCP port using different + Server Name Indication values or to provide different TLS + client certificates, but SHOULD avoid creating multiple connections with the same + configuration. + + + Servers are encouraged to maintain open connections for as long as possible, but are + permitted to terminate idle connections if necessary. When either endpoint chooses to + close the transport-layer TCP connection, the terminating endpoint SHOULD first send a + GOAWAY () frame so that both endpoints can reliably + determine whether previously sent frames have been processed and gracefully complete or + terminate any necessary remaining tasks. + + +
+ + Connections that are made to an origin servers, either directly or through a tunnel + created using the CONNECT method MAY be reused for + requests with multiple different URI authority components. A connection can be reused + as long as the origin server is authoritative. For + http resources, this depends on the host having resolved to + the same IP address. + + + For https resources, connection reuse additionally depends + on having a certificate that is valid for the host in the URI. An origin server might + offer a certificate with multiple subjectAltName attributes, + or names with wildcards, one of which is valid for the authority in the URI. For + example, a certificate with a subjectAltName of *.example.com might permit the use of the same connection for + requests to URIs starting with https://a.example.com/ and + https://b.example.com/. + + + In some deployments, reusing a connection for multiple origins can result in requests + being directed to the wrong origin server. For example, TLS termination might be + performed by a middlebox that uses the TLS Server Name Indication + (SNI) extension to select an origin server. This means that it is possible + for clients to send confidential information to servers that might not be the intended + target for the request, even though the server is otherwise authoritative. + + + A server that does not wish clients to reuse connections can indicate that it is not + authoritative for a request by sending a 421 (Misdirected Request) status code in response + to the request (see ). + + + A client that is configured to use a proxy over HTTP/2 directs requests to that proxy + through a single connection. That is, all requests sent via a proxy reuse the + connection to the proxy. + +
+ +
+ + The 421 (Misdirected Request) status code indicates that the request was directed at a + server that is not able to produce a response. This can be sent by a server that is not + configured to produce responses for the combination of scheme and authority that are + included in the request URI. + + + Clients receiving a 421 (Misdirected Request) response from a server MAY retry the + request - whether the request method is idempotent or not - over a different connection. + This is possible if a connection is reused () or if an alternative + service is selected (). + + + This status code MUST NOT be generated by proxies. + + + A 421 response is cacheable by default; i.e., unless otherwise indicated by the method + definition or explicit cache controls (see ). + +
+
+ +
+ + Implementations of HTTP/2 MUST support TLS 1.2 for HTTP/2 over + TLS. The general TLS usage guidance in SHOULD be followed, with + some additional restrictions that are specific to HTTP/2. + + + + An implementation of HTTP/2 over TLS MUST use TLS 1.2 or higher with the restrictions on + feature set and cipher suite described in this section. Due to implementation + limitations, it might not be possible to fail TLS negotiation. An endpoint MUST + immediately terminate an HTTP/2 connection that does not meet these minimum requirements + with a connection error of type + INADEQUATE_SECURITY. + + +
+ + The TLS implementation MUST support the Server Name Indication + (SNI) extension to TLS. HTTP/2 clients MUST indicate the target domain name when + negotiating TLS. + + + The TLS implementation MUST disable compression. TLS compression can lead to the + exposure of information that would not otherwise be revealed . + Generic compression is unnecessary since HTTP/2 provides compression features that are + more aware of context and therefore likely to be more appropriate for use for + performance, security or other reasons. + + + The TLS implementation MUST disable renegotiation. An endpoint MUST treat a TLS + renegotiation as a connection error of type + PROTOCOL_ERROR. Note that disabling renegotiation can result in + long-lived connections becoming unusable due to limits on the number of messages the + underlying cipher suite can encipher. + + + A client MAY use renegotiation to provide confidentiality protection for client + credentials offered in the handshake, but any renegotiation MUST occur prior to sending + the connection preface. A server SHOULD request a client certificate if it sees a + renegotiation request immediately after establishing a connection. + + + This effectively prevents the use of renegotiation in response to a request for a + specific protected resource. A future specification might provide a way to support this + use case. + +
+ +
+ + The set of TLS cipher suites that are permitted in HTTP/2 is restricted. HTTP/2 MUST + only be used with cipher suites that have ephemeral key exchange, such as the ephemeral Diffie-Hellman (DHE) or the elliptic curve variant (ECDHE). Ephemeral key exchange MUST + have a minimum size of 2048 bits for DHE or security level of 128 bits for ECDHE. + Clients MUST accept DHE sizes of up to 4096 bits. HTTP MUST NOT be used with cipher + suites that use stream or block ciphers. Authenticated Encryption with Additional Data + (AEAD) modes, such as the Galois Counter Model (GCM) mode for + AES are acceptable. + + + The effect of these restrictions is that TLS 1.2 implementations could have + non-intersecting sets of available cipher suites, since these prevent the use of the + cipher suite that TLS 1.2 makes mandatory. To avoid this problem, implementations of + HTTP/2 that use TLS 1.2 MUST support TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 with P256 . + + + Clients MAY advertise support of cipher suites that are prohibited by the above + restrictions in order to allow for connection to servers that do not support HTTP/2. + This enables a fallback to protocols without these constraints without the additional + latency imposed by using a separate connection for fallback. + +
+
+
+ +
+
+ + HTTP/2 relies on the HTTP/1.1 definition of authority for determining whether a server is + authoritative in providing a given response, see . This relies on local name resolution for the "http" + URI scheme, and the authenticated server identity for the "https" scheme (see ). + +
+ +
+ + In a cross-protocol attack, an attacker causes a client to initiate a transaction in one + protocol toward a server that understands a different protocol. An attacker might be able + to cause the transaction to appear as valid transaction in the second protocol. In + combination with the capabilities of the web context, this can be used to interact with + poorly protected servers in private networks. + + + Completing a TLS handshake with an ALPN identifier for HTTP/2 can be considered sufficient + protection against cross protocol attacks. ALPN provides a positive indication that a + server is willing to proceed with HTTP/2, which prevents attacks on other TLS-based + protocols. + + + The encryption in TLS makes it difficult for attackers to control the data which could be + used in a cross-protocol attack on a cleartext protocol. + + + The cleartext version of HTTP/2 has minimal protection against cross-protocol attacks. + The connection preface contains a string that is + designed to confuse HTTP/1.1 servers, but no special protection is offered for other + protocols. A server that is willing to ignore parts of an HTTP/1.1 request containing an + Upgrade header field in addition to the client connection preface could be exposed to a + cross-protocol attack. + +
+ +
+ + HTTP/2 header field names and values are encoded as sequences of octets with a length + prefix. This enables HTTP/2 to carry any string of octets as the name or value of a + header field. An intermediary that translates HTTP/2 requests or responses into HTTP/1.1 + directly could permit the creation of corrupted HTTP/1.1 messages. An attacker might + exploit this behavior to cause the intermediary to create HTTP/1.1 messages with illegal + header fields, extra header fields, or even new messages that are entirely falsified. + + + Header field names or values that contain characters not permitted by HTTP/1.1, including + carriage return (ASCII 0xd) or line feed (ASCII 0xa) MUST NOT be translated verbatim by an + intermediary, as stipulated in . + + + Translation from HTTP/1.x to HTTP/2 does not produce the same opportunity to an attacker. + Intermediaries that perform translation to HTTP/2 MUST remove any instances of the obs-fold production from header field values. + +
+ +
+ + Pushed responses do not have an explicit request from the client; the request + is provided by the server in the PUSH_PROMISE frame. + + + Caching responses that are pushed is possible based on the guidance provided by the origin + server in the Cache-Control header field. However, this can cause issues if a single + server hosts more than one tenant. For example, a server might offer multiple users each + a small portion of its URI space. + + + Where multiple tenants share space on the same server, that server MUST ensure that + tenants are not able to push representations of resources that they do not have authority + over. Failure to enforce this would allow a tenant to provide a representation that would + be served out of cache, overriding the actual representation that the authoritative tenant + provides. + + + Pushed responses for which an origin server is not authoritative (see + ) are never cached or used. + +
+ +
+ + An HTTP/2 connection can demand a greater commitment of resources to operate than a + HTTP/1.1 connection. The use of header compression and flow control depend on a + commitment of resources for storing a greater amount of state. Settings for these + features ensure that memory commitments for these features are strictly bounded. + + + The number of PUSH_PROMISE frames is not constrained in the same fashion. + A client that accepts server push SHOULD limit the number of streams it allows to be in + the "reserved (remote)" state. Excessive number of server push streams can be treated as + a stream error of type + ENHANCE_YOUR_CALM. + + + Processing capacity cannot be guarded as effectively as state capacity. + + + The SETTINGS frame can be abused to cause a peer to expend additional + processing time. This might be done by pointlessly changing SETTINGS parameters, setting + multiple undefined parameters, or changing the same setting multiple times in the same + frame. WINDOW_UPDATE or PRIORITY frames can be abused to + cause an unnecessary waste of resources. + + + Large numbers of small or empty frames can be abused to cause a peer to expend time + processing frame headers. Note however that some uses are entirely legitimate, such as + the sending of an empty DATA frame to end a stream. + + + Header compression also offers some opportunities to waste processing resources; see for more details on potential abuses. + + + Limits in SETTINGS parameters cannot be reduced instantaneously, which + leaves an endpoint exposed to behavior from a peer that could exceed the new limits. In + particular, immediately after establishing a connection, limits set by a server are not + known to clients and could be exceeded without being an obvious protocol violation. + + + All these features - i.e., SETTINGS changes, small frames, header + compression - have legitimate uses. These features become a burden only when they are + used unnecessarily or to excess. + + + An endpoint that doesn't monitor this behavior exposes itself to a risk of denial of + service attack. Implementations SHOULD track the use of these features and set limits on + their use. An endpoint MAY treat activity that is suspicious as a connection error of type + ENHANCE_YOUR_CALM. + + +
+ + A large header block can cause an implementation to + commit a large amount of state. Header fields that are critical for routing can appear + toward the end of a header block, which prevents streaming of header fields to their + ultimate destination. For this an other reasons, such as ensuring cache correctness, + means that an endpoint might need to buffer the entire header block. Since there is no + hard limit to the size of a header block, some endpoints could be forced commit a large + amount of available memory for header fields. + + + An endpoint can use the SETTINGS_MAX_HEADER_LIST_SIZE to advise peers of + limits that might apply on the size of header blocks. This setting is only advisory, so + endpoints MAY choose to send header blocks that exceed this limit and risk having the + request or response being treated as malformed. This setting specific to a connection, + so any request or response could encounter a hop with a lower, unknown limit. An + intermediary can attempt to avoid this problem by passing on values presented by + different peers, but they are not obligated to do so. + + + A server that receives a larger header block than it is willing to handle can send an + HTTP 431 (Request Header Fields Too Large) status code . A + client can discard responses that it cannot process. The header block MUST be processed + to ensure a consistent connection state, unless the connection is closed. + +
+
+ +
+ + HTTP/2 enables greater use of compression for both header fields () and entity bodies. Compression can allow an attacker to recover + secret data when it is compressed in the same context as data under attacker control. + + + There are demonstrable attacks on compression that exploit the characteristics of the web + (e.g., ). The attacker induces multiple requests containing + varying plaintext, observing the length of the resulting ciphertext in each, which + reveals a shorter length when a guess about the secret is correct. + + + Implementations communicating on a secure channel MUST NOT compress content that includes + both confidential and attacker-controlled data unless separate compression dictionaries + are used for each source of data. Compression MUST NOT be used if the source of data + cannot be reliably determined. Generic stream compression, such as that provided by TLS + MUST NOT be used with HTTP/2 (). + + + Further considerations regarding the compression of header fields are described in . + +
+ +
+ + Padding within HTTP/2 is not intended as a replacement for general purpose padding, such + as might be provided by TLS. Redundant padding could even be + counterproductive. Correct application can depend on having specific knowledge of the + data that is being padded. + + + To mitigate attacks that rely on compression, disabling or limiting compression might be + preferable to padding as a countermeasure. + + + Padding can be used to obscure the exact size of frame content, and is provided to + mitigate specific attacks within HTTP. For example, attacks where compressed content + includes both attacker-controlled plaintext and secret data (see for example, ). + + + Use of padding can result in less protection than might seem immediately obvious. At + best, padding only makes it more difficult for an attacker to infer length information by + increasing the number of frames an attacker has to observe. Incorrectly implemented + padding schemes can be easily defeated. In particular, randomized padding with a + predictable distribution provides very little protection; similarly, padding payloads to a + fixed size exposes information as payload sizes cross the fixed size boundary, which could + be possible if an attacker can control plaintext. + + + Intermediaries SHOULD retain padding for DATA frames, but MAY drop padding + for HEADERS and PUSH_PROMISE frames. A valid reason for an + intermediary to change the amount of padding of frames is to improve the protections that + padding provides. + +
+ +
+ + Several characteristics of HTTP/2 provide an observer an opportunity to correlate actions + of a single client or server over time. This includes the value of settings, the manner + in which flow control windows are managed, the way priorities are allocated to streams, + timing of reactions to stimulus, and handling of any optional features. + + + As far as this creates observable differences in behavior, they could be used as a basis + for fingerprinting a specific client, as defined in . + +
+
+ +
+ + A string for identifying HTTP/2 is entered into the "Application Layer Protocol Negotiation + (ALPN) Protocol IDs" registry established in . + + + This document establishes a registry for frame types, settings, and error codes. These new + registries are entered into a new "Hypertext Transfer Protocol (HTTP) 2 Parameters" section. + + + This document registers the HTTP2-Settings header field for + use in HTTP; and the 421 (Misdirected Request) status code. + + + This document registers the PRI method for use in HTTP, to avoid + collisions with the connection preface. + + +
+ + This document creates two registrations for the identification of HTTP/2 in the + "Application Layer Protocol Negotiation (ALPN) Protocol IDs" registry established in . + + + The "h2" string identifies HTTP/2 when used over TLS: + + HTTP/2 over TLS + 0x68 0x32 ("h2") + This document + + + + The "h2c" string identifies HTTP/2 when used over cleartext TCP: + + HTTP/2 over TCP + 0x68 0x32 0x63 ("h2c") + This document + + +
+ +
+ + This document establishes a registry for HTTP/2 frame type codes. The "HTTP/2 Frame + Type" registry manages an 8-bit space. The "HTTP/2 Frame Type" registry operates under + either of the "IETF Review" or "IESG Approval" policies for + values between 0x00 and 0xef, with values between 0xf0 and 0xff being reserved for + experimental use. + + + New entries in this registry require the following information: + + + A name or label for the frame type. + + + The 8-bit code assigned to the frame type. + + + A reference to a specification that includes a description of the frame layout, + it's semantics and flags that the frame type uses, including any parts of the frame + that are conditionally present based on the value of flags. + + + + + The entries in the following table are registered by this document. + + + Frame Type + Code + Section + DATA0x0 + HEADERS0x1 + PRIORITY0x2 + RST_STREAM0x3 + SETTINGS0x4 + PUSH_PROMISE0x5 + PING0x6 + GOAWAY0x7 + WINDOW_UPDATE0x8 + CONTINUATION0x9 + +
+ +
+ + This document establishes a registry for HTTP/2 settings. The "HTTP/2 Settings" registry + manages a 16-bit space. The "HTTP/2 Settings" registry operates under the "Expert Review" policy for values in the range from 0x0000 to + 0xefff, with values between and 0xf000 and 0xffff being reserved for experimental use. + + + New registrations are advised to provide the following information: + + + A symbolic name for the setting. Specifying a setting name is optional. + + + The 16-bit code assigned to the setting. + + + An initial value for the setting. + + + An optional reference to a specification that describes the use of the setting. + + + + + An initial set of setting registrations can be found in . + + + Name + Code + Initial Value + Specification + HEADER_TABLE_SIZE + 0x14096 + ENABLE_PUSH + 0x21 + MAX_CONCURRENT_STREAMS + 0x3(infinite) + INITIAL_WINDOW_SIZE + 0x465535 + MAX_FRAME_SIZE + 0x516384 + MAX_HEADER_LIST_SIZE + 0x6(infinite) + + +
+ +
+ + This document establishes a registry for HTTP/2 error codes. The "HTTP/2 Error Code" + registry manages a 32-bit space. The "HTTP/2 Error Code" registry operates under the + "Expert Review" policy. + + + Registrations for error codes are required to include a description of the error code. An + expert reviewer is advised to examine new registrations for possible duplication with + existing error codes. Use of existing registrations is to be encouraged, but not + mandated. + + + New registrations are advised to provide the following information: + + + A name for the error code. Specifying an error code name is optional. + + + The 32-bit error code value. + + + A brief description of the error code semantics, longer if no detailed specification + is provided. + + + An optional reference for a specification that defines the error code. + + + + + The entries in the following table are registered by this document. + + + Name + Code + Description + Specification + NO_ERROR0x0 + Graceful shutdown + + PROTOCOL_ERROR0x1 + Protocol error detected + + INTERNAL_ERROR0x2 + Implementation fault + + FLOW_CONTROL_ERROR0x3 + Flow control limits exceeded + + SETTINGS_TIMEOUT0x4 + Settings not acknowledged + + STREAM_CLOSED0x5 + Frame received for closed stream + + FRAME_SIZE_ERROR0x6 + Frame size incorrect + + REFUSED_STREAM0x7 + Stream not processed + + CANCEL0x8 + Stream cancelled + + COMPRESSION_ERROR0x9 + Compression state not updated + + CONNECT_ERROR0xa + TCP connection error for CONNECT method + + ENHANCE_YOUR_CALM0xb + Processing capacity exceeded + + INADEQUATE_SECURITY0xc + Negotiated TLS parameters not acceptable + + + +
+ +
+ + This section registers the HTTP2-Settings header field in the + Permanent Message Header Field Registry. + + + HTTP2-Settings + + + http + + + standard + + + IETF + + + of this document + + + This header field is only used by an HTTP/2 client for Upgrade-based negotiation. + + + +
+ +
+ + This section registers the PRI method in the HTTP Method + Registry (). + + + PRI + + + No + + + No + + + of this document + + + This method is never used by an actual client. This method will appear to be used + when an HTTP/1.1 server or intermediary attempts to parse an HTTP/2 connection + preface. + + + +
+ +
+ + This document registers the 421 (Misdirected Request) HTTP Status code in the Hypertext + Transfer Protocol (HTTP) Status Code Registry (). + + + + + 421 + + + Misdirected Request + + + of this document + + + +
+ +
+ +
+ + This document includes substantial input from the following individuals: + + + Adam Langley, Wan-Teh Chang, Jim Morrison, Mark Nottingham, Alyssa Wilk, Costin + Manolache, William Chan, Vitaliy Lvin, Joe Chan, Adam Barth, Ryan Hamilton, Gavin + Peters, Kent Alstad, Kevin Lindsay, Paul Amer, Fan Yang, Jonathan Leighton (SPDY + contributors). + + + Gabriel Montenegro and Willy Tarreau (Upgrade mechanism). + + + William Chan, Salvatore Loreto, Osama Mazahir, Gabriel Montenegro, Jitu Padhye, Roberto + Peon, Rob Trace (Flow control). + + + Mike Bishop (Extensibility). + + + Mark Nottingham, Julian Reschke, James Snell, Jeff Pinner, Mike Bishop, Herve Ruellan + (Substantial editorial contributions). + + + Kari Hurtta, Tatsuhiro Tsujikawa, Greg Wilkins, Poul-Henning Kamp. + + + Alexey Melnikov was an editor of this document during 2013. + + + A substantial proportion of Martin's contribution was supported by Microsoft during his + employment there. + + + +
+
+ + + + + + HPACK - Header Compression for HTTP/2 + + + + + + + + + + + + Transmission Control Protocol + + + University of Southern California (USC)/Information Sciences + Institute + + + + + + + + + + + Key words for use in RFCs to Indicate Requirement Levels + + + Harvard University +
sob@harvard.edu
+
+ +
+ + +
+ + + + + HTTP Over TLS + + + + + + + + + + Uniform Resource Identifier (URI): Generic + Syntax + + + + + + + + + + + + The Base16, Base32, and Base64 Data Encodings + + + + + + + + + Guidelines for Writing an IANA Considerations Section in RFCs + + + + + + + + + + + Augmented BNF for Syntax Specifications: ABNF + + + + + + + + + + + The Transport Layer Security (TLS) Protocol Version 1.2 + + + + + + + + + + + Transport Layer Security (TLS) Extensions: Extension Definitions + + + + + + + + + + Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension + + + + + + + + + + + + + TLS Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois + Counter Mode (GCM) + + + + + + + + + + + Digital Signature Standard (DSS) + + NIST + + + + + + + + + Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing + + Adobe Systems Incorporated +
fielding@gbiv.com
+
+ + greenbytes GmbH +
julian.reschke@greenbytes.de
+
+ +
+ + +
+ + + + Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content + + Adobe Systems Incorporated +
fielding@gbiv.com
+
+ + greenbytes GmbH +
julian.reschke@greenbytes.de
+
+ +
+ + +
+ + + Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests + + Adobe Systems Incorporated +
fielding@gbiv.com
+
+ + greenbytes GmbH +
julian.reschke@greenbytes.de
+
+ +
+ +
+ + + Hypertext Transfer Protocol (HTTP/1.1): Range Requests + + Adobe Systems Incorporated +
fielding@gbiv.com
+
+ + World Wide Web Consortium +
ylafon@w3.org
+
+ + greenbytes GmbH +
julian.reschke@greenbytes.de
+
+ +
+ +
+ + + Hypertext Transfer Protocol (HTTP/1.1): Caching + + Adobe Systems Incorporated +
fielding@gbiv.com
+
+ + Akamai +
mnot@mnot.net
+
+ + greenbytes GmbH +
julian.reschke@greenbytes.de
+
+ +
+ + +
+ + + Hypertext Transfer Protocol (HTTP/1.1): Authentication + + Adobe Systems Incorporated +
fielding@gbiv.com
+
+ + greenbytes GmbH +
julian.reschke@greenbytes.de
+
+ +
+ + +
+ + + + HTTP State Management Mechanism + + + + + +
+ + + + + + TCP Extensions for High Performance + + + + + + + + + + + + Transport Layer Security Protocol Compression Methods + + + + + + + + + Additional HTTP Status Codes + + + + + + + + + + + Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS) + + + + + + + + + + + + + + + AES Galois Counter Mode (GCM) Cipher Suites for TLS + + + + + + + + + + + + HTML5 + + + + + + + + + + + Latest version available at + . + + + + + + + Talking to Yourself for Fun and Profit + + + + + + + + + + + + + + BREACH: Reviving the CRIME Attack + + + + + + + + + + + Registration Procedures for Message Header Fields + + Nine by Nine +
GK-IETF@ninebynine.org
+
+ + BEA Systems +
mnot@pobox.com
+
+ + HP Labs +
JeffMogul@acm.org
+
+ +
+ + +
+ + + + Recommendations for Secure Use of TLS and DTLS + + + + + + + + + + + + + + + + + + HTTP Alternative Services + + + Akamai + + + Mozilla + + + greenbytes + + + + + + +
+ +
+ + This section is to be removed by RFC Editor before publication. + + +
+ + Renamed Not Authoritative status code to Misdirected Request. + +
+ +
+ + Pseudo-header fields are now required to appear strictly before regular ones. + + + Restored 1xx series status codes, except 101. + + + Changed frame length field 24-bits. Expanded frame header to 9 octets. Added a setting + to limit the damage. + + + Added a setting to advise peers of header set size limits. + + + Removed segments. + + + Made non-semantic-bearing HEADERS frames illegal in the HTTP mapping. + +
+ +
+ + Restored extensibility options. + + + Restricting TLS cipher suites to AEAD only. + + + Removing Content-Encoding requirements. + + + Permitting the use of PRIORITY after stream close. + + + Removed ALTSVC frame. + + + Removed BLOCKED frame. + + + Reducing the maximum padding size to 256 octets; removing padding from + CONTINUATION frames. + + + Removed per-frame GZIP compression. + +
+ +
+ + Added BLOCKED frame (at risk). + + + Simplified priority scheme. + + + Added DATA per-frame GZIP compression. + +
+ +
+ + Changed "connection header" to "connection preface" to avoid confusion. + + + Added dependency-based stream prioritization. + + + Added "h2c" identifier to distinguish between cleartext and secured HTTP/2. + + + Adding missing padding to PUSH_PROMISE. + + + Integrate ALTSVC frame and supporting text. + + + Dropping requirement on "deflate" Content-Encoding. + + + Improving security considerations around use of compression. + +
+ +
+ + Adding padding for data frames. + + + Renumbering frame types, error codes, and settings. + + + Adding INADEQUATE_SECURITY error code. + + + Updating TLS usage requirements to 1.2; forbidding TLS compression. + + + Removing extensibility for frames and settings. + + + Changing setting identifier size. + + + Removing the ability to disable flow control. + + + Changing the protocol identification token to "h2". + + + Changing the use of :authority to make it optional and to allow userinfo in non-HTTP + cases. + + + Allowing split on 0x0 for Cookie. + + + Reserved PRI method in HTTP/1.1 to avoid possible future collisions. + +
+ +
+ + Added cookie crumbling for more efficient header compression. + + + Added header field ordering with the value-concatenation mechanism. + +
+ +
+ + Marked draft for implementation. + +
+ +
+ + Adding definition for CONNECT method. + + + Constraining the use of push to safe, cacheable methods with no request body. + + + Changing from :host to :authority to remove any potential confusion. + + + Adding setting for header compression table size. + + + Adding settings acknowledgement. + + + Removing unnecessary and potentially problematic flags from CONTINUATION. + + + Added denial of service considerations. + +
+
+ + Marking the draft ready for implementation. + + + Renumbering END_PUSH_PROMISE flag. + + + Editorial clarifications and changes. + +
+ +
+ + Added CONTINUATION frame for HEADERS and PUSH_PROMISE. + + + PUSH_PROMISE is no longer implicitly prohibited if SETTINGS_MAX_CONCURRENT_STREAMS is + zero. + + + Push expanded to allow all safe methods without a request body. + + + Clarified the use of HTTP header fields in requests and responses. Prohibited HTTP/1.1 + hop-by-hop header fields. + + + Requiring that intermediaries not forward requests with missing or illegal routing + :-headers. + + + Clarified requirements around handling different frames after stream close, stream reset + and GOAWAY. + + + Added more specific prohibitions for sending of different frame types in various stream + states. + + + Making the last received setting value the effective value. + + + Clarified requirements on TLS version, extension and ciphers. + +
+ +
+ + Committed major restructuring atrocities. + + + Added reference to first header compression draft. + + + Added more formal description of frame lifecycle. + + + Moved END_STREAM (renamed from FINAL) back to HEADERS/DATA. + + + Removed HEADERS+PRIORITY, added optional priority to HEADERS frame. + + + Added PRIORITY frame. + +
+ +
+ + Added continuations to frames carrying header blocks. + + + Replaced use of "session" with "connection" to avoid confusion with other HTTP stateful + concepts, like cookies. + + + Removed "message". + + + Switched to TLS ALPN from NPN. + + + Editorial changes. + +
+ +
+ + Added IANA considerations section for frame types, error codes and settings. + + + Removed data frame compression. + + + Added PUSH_PROMISE. + + + Added globally applicable flags to framing. + + + Removed zlib-based header compression mechanism. + + + Updated references. + + + Clarified stream identifier reuse. + + + Removed CREDENTIALS frame and associated mechanisms. + + + Added advice against naive implementation of flow control. + + + Added session header section. + + + Restructured frame header. Removed distinction between data and control frames. + + + Altered flow control properties to include session-level limits. + + + Added note on cacheability of pushed resources and multiple tenant servers. + + + Changed protocol label form based on discussions. + +
+ +
+ + Changed title throughout. + + + Removed section on Incompatibilities with SPDY draft#2. + + + Changed INTERNAL_ERROR on GOAWAY to have a value of 2 . + + + Replaced abstract and introduction. + + + Added section on starting HTTP/2.0, including upgrade mechanism. + + + Removed unused references. + + + Added flow control principles based on . + +
+ +
+ + Adopted as base for draft-ietf-httpbis-http2. + + + Updated authors/editors list. + + + Added status note. + +
+
+ +
+ + diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/all_test.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/all_test.go index 88c506cf0afc..5f27645ec072 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/all_test.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/all_test.go @@ -1958,6 +1958,58 @@ func TestMapFieldWithNil(t *testing.T) { } } +func TestOneof(t *testing.T) { + m := &Communique{} + b, err := Marshal(m) + if err != nil { + t.Fatalf("Marshal of empty message with oneof: %v", err) + } + if len(b) != 0 { + t.Errorf("Marshal of empty message yielded too many bytes: %v", b) + } + + m = &Communique{ + Union: &Communique_Name{"Barry"}, + } + + // Round-trip. + b, err = Marshal(m) + if err != nil { + t.Fatalf("Marshal of message with oneof: %v", err) + } + if len(b) != 7 { // name tag/wire (1) + name len (1) + name (5) + t.Errorf("Incorrect marshal of message with oneof: %v", b) + } + m.Reset() + if err := Unmarshal(b, m); err != nil { + t.Fatalf("Unmarshal of message with oneof: %v", err) + } + if x, ok := m.Union.(*Communique_Name); !ok || x.Name != "Barry" { + t.Errorf("After round trip, Union = %+v", m.Union) + } + if name := m.GetName(); name != "Barry" { + t.Errorf("After round trip, GetName = %q, want %q", name, "Barry") + } + + // Let's try with a message in the oneof. + m.Union = &Communique_Msg{&Strings{StringField: String("deep deep string")}} + b, err = Marshal(m) + if err != nil { + t.Fatalf("Marshal of message with oneof set to message: %v", err) + } + if len(b) != 20 { // msg tag/wire (1) + msg len (1) + msg (1 + 1 + 16) + t.Errorf("Incorrect marshal of message with oneof set to message: %v", b) + } + m.Reset() + if err := Unmarshal(b, m); err != nil { + t.Fatalf("Unmarshal of message with oneof set to message: %v", err) + } + ss, ok := m.Union.(*Communique_Msg) + if !ok || ss.Msg.GetStringField() != "deep deep string" { + t.Errorf("After round trip with oneof set to message, Union = %+v", m.Union) + } +} + // Benchmarks func testMsg() *GoTest { diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone.go index 57297947beb2..4ff1ff59e714 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone.go @@ -125,6 +125,17 @@ func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { return } out.Set(in) + case reflect.Interface: + // Probably a oneof field; copy non-nil values. + if in.IsNil() { + return + } + // Allocate destination if it is not set, or set to a different type. + // Otherwise we will merge as normal. + if out.IsNil() || out.Elem().Type() != in.Elem().Type() { + out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) + } + mergeAny(out.Elem(), in.Elem(), false, nil) case reflect.Map: if in.Len() == 0 { return diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone_test.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone_test.go index 7eef89ee09e1..f065210b8941 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone_test.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone_test.go @@ -232,6 +232,28 @@ var mergeTests = []struct { Data: []byte("texas!"), }, }, + // Oneof fields should merge by assignment. + { + src: &pb.Communique{ + Union: &pb.Communique_Number{Number: 41}, + }, + dst: &pb.Communique{ + Union: &pb.Communique_Name{Name: "Bobby Tables"}, + }, + want: &pb.Communique{ + Union: &pb.Communique_Number{Number: 41}, + }, + }, + // Oneof nil is the same as not set. + { + src: &pb.Communique{}, + dst: &pb.Communique{ + Union: &pb.Communique_Name{Name: "Bobby Tables"}, + }, + want: &pb.Communique{ + Union: &pb.Communique_Name{Name: "Bobby Tables"}, + }, + }, } func TestMerge(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/decode.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/decode.go index f7b1884b3cb3..34258942aeee 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/decode.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/decode.go @@ -46,6 +46,10 @@ import ( // errOverflow is returned when an integer is too large to be represented. var errOverflow = errors.New("proto: integer overflow") +// ErrInternalBadWireType is returned by generated code when an incorrect +// wire type is encountered. It does not get returned to user code. +var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") + // The fundamental decoders that interpret bytes on the wire. // Those that take integer types all return uint64 and are // therefore of type valueDecoder. @@ -314,6 +318,24 @@ func UnmarshalMerge(buf []byte, pb Message) error { return NewBuffer(buf).Unmarshal(pb) } +// DecodeMessage reads a count-delimited message from the Buffer. +func (p *Buffer) DecodeMessage(pb Message) error { + enc, err := p.DecodeRawBytes(false) + if err != nil { + return err + } + return NewBuffer(enc).Unmarshal(pb) +} + +// DecodeGroup reads a tag-delimited group from the Buffer. +func (p *Buffer) DecodeGroup(pb Message) error { + typ, base, err := getbase(pb) + if err != nil { + return err + } + return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base) +} + // Unmarshal parses the protocol buffer representation in the // Buffer and places the decoded result in pb. If the struct // underlying pb does not match the data in the buffer, the results can be @@ -370,11 +392,11 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group if prop.extendable { if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) { if err = o.skip(st, tag, wire); err == nil { - if ee, ok := e.(extensionsMap); ok { + if ee, eok := e.(extensionsMap); eok { ext := ee.ExtensionMap()[int32(tag)] // may be missing ext.enc = append(ext.enc, o.buf[oi:o.index]...) ee.ExtensionMap()[int32(tag)] = ext - } else if ee, ok := e.(extensionsBytes); ok { + } else if ee, eok := e.(extensionsBytes); eok { ext := ee.GetExtensions() *ext = append(*ext, o.buf[oi:o.index]...) } @@ -382,6 +404,20 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group continue } } + // Maybe it's a oneof? + if prop.oneofUnmarshaler != nil { + m := structPointer_Interface(base, st).(Message) + // First return value indicates whether tag is a oneof field. + ok, err = prop.oneofUnmarshaler(m, tag, wire, o) + if err == ErrInternalBadWireType { + // Map the error to something more descriptive. + // Do the formatting here to save generated code space. + err = fmt.Errorf("bad wiretype for oneof field in %T", m) + } + if ok { + continue + } + } err = o.skipAndSave(st, tag, wire, base, prop.unrecField) continue } diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/encode.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/encode.go index 91f3f0784d2c..89d0caa8268f 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/encode.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/encode.go @@ -228,6 +228,20 @@ func Marshal(pb Message) ([]byte, error) { return p.buf, err } +// EncodeMessage writes the protocol buffer to the Buffer, +// prefixed by a varint-encoded length. +func (p *Buffer) EncodeMessage(pb Message) error { + t, base, err := getbase(pb) + if structPointer_IsNil(base) { + return ErrNil + } + if err == nil { + var state errorState + err = p.enc_len_struct(GetProperties(t.Elem()), base, &state) + } + return err +} + // Marshal takes the protocol buffer // and encodes it into the wire format, writing the result to the // Buffer. @@ -318,7 +332,7 @@ func size_bool(p *Properties, base structPointer) int { func size_proto3_bool(p *Properties, base structPointer) int { v := *structPointer_BoolVal(base, p.field) - if !v { + if !v && !p.oneof { return 0 } return len(p.tagcode) + 1 // each bool takes exactly one byte @@ -361,7 +375,7 @@ func size_int32(p *Properties, base structPointer) (n int) { func size_proto3_int32(p *Properties, base structPointer) (n int) { v := structPointer_Word32Val(base, p.field) x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range - if x == 0 { + if x == 0 && !p.oneof { return 0 } n += len(p.tagcode) @@ -407,7 +421,7 @@ func size_uint32(p *Properties, base structPointer) (n int) { func size_proto3_uint32(p *Properties, base structPointer) (n int) { v := structPointer_Word32Val(base, p.field) x := word32Val_Get(v) - if x == 0 { + if x == 0 && !p.oneof { return 0 } n += len(p.tagcode) @@ -452,7 +466,7 @@ func size_int64(p *Properties, base structPointer) (n int) { func size_proto3_int64(p *Properties, base structPointer) (n int) { v := structPointer_Word64Val(base, p.field) x := word64Val_Get(v) - if x == 0 { + if x == 0 && !p.oneof { return 0 } n += len(p.tagcode) @@ -495,7 +509,7 @@ func size_string(p *Properties, base structPointer) (n int) { func size_proto3_string(p *Properties, base structPointer) (n int) { v := *structPointer_StringVal(base, p.field) - if v == "" { + if v == "" && !p.oneof { return 0 } n += len(p.tagcode) @@ -667,7 +681,7 @@ func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error func size_slice_byte(p *Properties, base structPointer) (n int) { s := *structPointer_Bytes(base, p.field) - if s == nil { + if s == nil && !p.oneof { return 0 } n += len(p.tagcode) @@ -677,7 +691,7 @@ func size_slice_byte(p *Properties, base structPointer) (n int) { func size_proto3_slice_byte(p *Properties, base structPointer) (n int) { s := *structPointer_Bytes(base, p.field) - if len(s) == 0 { + if len(s) == 0 && !p.oneof { return 0 } n += len(p.tagcode) @@ -1201,6 +1215,14 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { } } + // Do oneof fields. + if prop.oneofMarshaler != nil { + m := structPointer_Interface(base, prop.stype).(Message) + if err := prop.oneofMarshaler(m, o); err != nil { + return err + } + } + // Add unrecognized fields at the end. if prop.unrecField.IsValid() { v := *structPointer_Bytes(base, prop.unrecField) @@ -1226,6 +1248,27 @@ func size_struct(prop *StructProperties, base structPointer) (n int) { n += len(v) } + // Factor in any oneof fields. + // TODO: This could be faster and use less reflection. + if prop.oneofMarshaler != nil { + sv := reflect.ValueOf(structPointer_Interface(base, prop.stype)).Elem() + for i := 0; i < prop.stype.NumField(); i++ { + fv := sv.Field(i) + if fv.Kind() != reflect.Interface || fv.IsNil() { + continue + } + if prop.stype.Field(i).Tag.Get("protobuf_oneof") == "" { + continue + } + spv := fv.Elem() // interface -> *T + sv := spv.Elem() // *T -> T + sf := sv.Type().Field(0) // StructField inside T + var prop Properties + prop.Init(sf.Type, "whatever", sf.Tag.Get("protobuf"), &sf) + n += prop.size(&prop, toStructPointer(spv)) + } + } + return } diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal.go index d8673a3e97ae..5475c3d9596f 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal.go @@ -154,6 +154,17 @@ func equalAny(v1, v2 reflect.Value) bool { return v1.Float() == v2.Float() case reflect.Int32, reflect.Int64: return v1.Int() == v2.Int() + case reflect.Interface: + // Probably a oneof field; compare the inner values. + n1, n2 := v1.IsNil(), v2.IsNil() + if n1 || n2 { + return n1 == n2 + } + e1, e2 := v1.Elem(), v2.Elem() + if e1.Type() != e2.Type() { + return false + } + return equalAny(e1, e2) case reflect.Map: if v1.Len() != v2.Len() { return false diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal_test.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal_test.go index ef6048008d3e..7cb36d3785d8 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal_test.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal_test.go @@ -180,6 +180,24 @@ var EqualTests = []struct { &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}}, false, }, + { + "oneof same", + &pb.Communique{Union: &pb.Communique_Number{Number: 41}}, + &pb.Communique{Union: &pb.Communique_Number{Number: 41}}, + true, + }, + { + "oneof one nil", + &pb.Communique{Union: &pb.Communique_Number{Number: 41}}, + &pb.Communique{}, + false, + }, + { + "oneof different", + &pb.Communique{Union: &pb.Communique_Number{Number: 41}}, + &pb.Communique{Union: &pb.Communique_Name{Name: "Bobby Tables"}}, + false, + }, } func TestEqual(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/lib.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/lib.go index d36f9ad1293b..b964734c7728 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/lib.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/lib.go @@ -66,6 +66,8 @@ for a protocol buffer variable v: that contain it (if any) followed by the CamelCased name of the extension field itself. HasExtension, ClearExtension, GetExtension and SetExtension are functions for manipulating extensions. + - Oneof field sets are given a single field in their message, + with distinguished wrapper types for each possible field value. - Marshal and Unmarshal are functions to encode and decode the wire format. The simplest way to describe this is to see an example. @@ -82,6 +84,10 @@ Given file test.proto, containing optional group OptionalGroup = 4 { required string RequiredField = 5; } + oneof union { + int32 number = 6; + string name = 7; + } } The resulting file, test.pb.go, is: @@ -120,15 +126,40 @@ The resulting file, test.pb.go, is: } type Test struct { - Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` - Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` - Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` - Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` - XXX_unrecognized []byte `json:"-"` + Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` + Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` + Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` + Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` + // Types that are valid to be assigned to Union: + // *Test_Number + // *Test_Name + Union isTest_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` } func (m *Test) Reset() { *m = Test{} } func (m *Test) String() string { return proto.CompactTextString(m) } - func (*Test) ProtoMessage() {} + func (*Test) ProtoMessage() {} + + type isTest_Union interface { + isTest_Union() + } + + type Test_Number struct { + Number int32 `protobuf:"varint,6,opt,name=number"` + } + type Test_Name struct { + Name string `protobuf:"bytes,7,opt,name=name"` + } + + func (*Test_Number) isTest_Union() {} + func (*Test_Name) isTest_Union() {} + + func (m *Test) GetUnion() isTest_Union { + if m != nil { + return m.Union + } + return nil + } const Default_Test_Type int32 = 77 func (m *Test) GetLabel() string { @@ -165,6 +196,20 @@ The resulting file, test.pb.go, is: return "" } + func (m *Test) GetNumber() int32 { + if x, ok := m.GetUnion().(*Test_Number); ok { + return x.Number + } + return 0 + } + + func (m *Test) GetName() string { + if x, ok := m.GetUnion().(*Test_Name); ok { + return x.Name + } + return "" + } + func init() { proto.RegisterEnum("example.FOO", FOO_name, FOO_value) } @@ -187,6 +232,7 @@ package main Optionalgroup: &pb.Test_OptionalGroup{ RequiredField: proto.String("good bye"), }, + Union: &pb.Test_Name{"fred"}, } data, err := proto.Marshal(test) if err != nil { @@ -201,6 +247,11 @@ package main if test.GetLabel() != newTest.GetLabel() { log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) } + // Use a type switch to determine which oneof was set. + switch u := test.Union.(type) { + case *pb.Test_Number: // u.Number contains the number. + case *pb.Test_Name: // u.Name contains the string. + } // etc. } */ @@ -460,7 +511,6 @@ out: break out } fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) - break case WireVarint: u, err = p.DecodeVarint() @@ -471,19 +521,11 @@ out: fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) case WireStartGroup: - if err != nil { - fmt.Printf("%3d: t=%3d start err %v\n", index, tag, err) - break out - } fmt.Printf("%3d: t=%3d start\n", index, tag) depth++ case WireEndGroup: depth-- - if err != nil { - fmt.Printf("%3d: t=%3d end err %v\n", index, tag, err) - break out - } fmt.Printf("%3d: t=%3d end\n", index, tag) } } diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/properties.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/properties.go index 13245c00df24..1bb17a26abb1 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/properties.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/properties.go @@ -89,6 +89,12 @@ type decoder func(p *Buffer, prop *Properties, base structPointer) error // A valueDecoder decodes a single integer in a particular encoding. type valueDecoder func(o *Buffer) (x uint64, err error) +// A oneofMarshaler does the marshaling for all oneof fields in a message. +type oneofMarshaler func(Message, *Buffer) error + +// A oneofUnmarshaler does the unmarshaling for a oneof field in a message. +type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error) + // tagMap is an optimization over map[int]int for typical protocol buffer // use-cases. Encoded protocol buffers are often in tag order with small tag // numbers. @@ -137,6 +143,21 @@ type StructProperties struct { order []int // list of struct field numbers in tag order unrecField field // field id of the XXX_unrecognized []byte field extendable bool // is this an extendable proto + + oneofMarshaler oneofMarshaler + oneofUnmarshaler oneofUnmarshaler + stype reflect.Type + + // OneofTypes contains information about the oneof fields in this message. + // It is keyed by the original name of a field. + OneofTypes map[string]*OneofProperties +} + +// OneofProperties represents information about a specific field in a oneof. +type OneofProperties struct { + Type reflect.Type // pointer to generated struct type for this oneof field + Field int // struct field number of the containing oneof in the message + Prop *Properties } // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. @@ -161,6 +182,7 @@ type Properties struct { Packed bool // relevant for repeated primitives only Enum string // set for enum types only proto3 bool // whether this is known to be a proto3 field; set for []byte only + oneof bool // whether this is a oneof field Default string // default value HasDefault bool // whether an explicit default was provided @@ -216,6 +238,9 @@ func (p *Properties) String() string { if p.proto3 { s += ",proto3" } + if p.oneof { + s += ",oneof" + } if len(p.Enum) > 0 { s += ",enum=" + p.Enum } @@ -292,6 +317,8 @@ func (p *Properties) Parse(s string) { p.Enum = f[5:] case f == "proto3": p.proto3 = true + case f == "oneof": + p.oneof = true case strings.HasPrefix(f, "def="): p.HasDefault = true p.Default = f[4:] // rest of string @@ -733,6 +760,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { if f.Name == "XXX_unrecognized" { // special case prop.unrecField = toField(&f) } + oneof := f.Tag.Get("protobuf_oneof") != "" // special case prop.Prop[i] = p prop.order[i] = i if debug { @@ -742,7 +770,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { } print("\n") } - if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") { + if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof { fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]") } } @@ -750,6 +778,41 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { // Re-order prop.order. sort.Sort(prop) + type oneofMessage interface { + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), []interface{}) + } + if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { + var oots []interface{} + prop.oneofMarshaler, prop.oneofUnmarshaler, oots = om.XXX_OneofFuncs() + prop.stype = t + + // Interpret oneof metadata. + prop.OneofTypes = make(map[string]*OneofProperties) + for _, oot := range oots { + oop := &OneofProperties{ + Type: reflect.ValueOf(oot).Type(), // *T + Prop: new(Properties), + } + sft := oop.Type.Elem().Field(0) + oop.Prop.Name = sft.Name + oop.Prop.Parse(sft.Tag.Get("protobuf")) + // There will be exactly one interface field that + // this new value is assignable to. + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Type.Kind() != reflect.Interface { + continue + } + if !oop.Type.AssignableTo(f.Type) { + continue + } + oop.Field = i + break + } + prop.OneofTypes[oop.Prop.OrigName] = oop + } + } + // build required counts // build tags reqCount := 0 diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto/proto3.pb.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto/proto3.pb.go index 2f2da4604485..b48227622f6f 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto/proto3.pb.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto/proto3.pb.go @@ -16,10 +16,14 @@ It has these top-level messages: package proto3_proto import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" +import math "math" import testdata "github.com/gogo/protobuf/proto/testdata" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf type Message_Humour int32 diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/size_test.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/size_test.go index 457a479ebb41..f4b8b8e3a0a5 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/size_test.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/size_test.go @@ -124,6 +124,11 @@ var SizeTests = []struct { {"map field with big entry", &pb.MessageWithMap{NameMapping: map[int32]string{8: strings.Repeat("x", 125)}}}, {"map field with big key and val", &pb.MessageWithMap{StrToStr: map[string]string{strings.Repeat("x", 70): strings.Repeat("y", 70)}}}, {"map field with big numeric key", &pb.MessageWithMap{NameMapping: map[int32]string{0xf00d: "om nom nom"}}}, + + {"oneof not set", &pb.Communique{}}, + {"oneof zero int32", &pb.Communique{Union: &pb.Communique_Number{Number: 0}}}, + {"oneof int32", &pb.Communique{Union: &pb.Communique_Number{Number: 3}}}, + {"oneof string", &pb.Communique{Union: &pb.Communique_Name{Name: "Rhythmic Fman"}}}, } func TestSize(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/Makefile b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/Makefile new file mode 100644 index 000000000000..31d83277ccf1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/Makefile @@ -0,0 +1,37 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +all: regenerate + +regenerate: + go install github.com/gogo/protobuf/protoc-min-version + protoc-min-version --version="3.0.0" --gogo_out=. test.proto + diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/golden_test.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/golden_test.go new file mode 100644 index 000000000000..8e84515377a9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/golden_test.go @@ -0,0 +1,86 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Verify that the compiler output for test.proto is unchanged. + +package testdata + +import ( + "crypto/sha1" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "testing" +) + +// sum returns in string form (for easy comparison) the SHA-1 hash of the named file. +func sum(t *testing.T, name string) string { + data, err := ioutil.ReadFile(name) + if err != nil { + t.Fatal(err) + } + t.Logf("sum(%q): length is %d", name, len(data)) + hash := sha1.New() + _, err = hash.Write(data) + if err != nil { + t.Fatal(err) + } + return fmt.Sprintf("% x", hash.Sum(nil)) +} + +func run(t *testing.T, name string, args ...string) { + cmd := exec.Command(name, args...) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + if err != nil { + t.Fatal(err) + } +} + +func TestGolden(t *testing.T) { + // Compute the original checksum. + goldenSum := sum(t, "test.pb.go") + // Run the proto compiler. + run(t, "protoc", "--gogo_out="+os.TempDir(), "test.proto") + newFile := filepath.Join(os.TempDir(), "test.pb.go") + defer os.Remove(newFile) + // Compute the new checksum. + newSum := sum(t, newFile) + // Verify + if newSum != goldenSum { + run(t, "diff", "-u", "test.pb.go", newFile) + t.Fatal("Code generated by protoc-gen-go has changed; update test.pb.go") + } +} diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.pb.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.pb.go new file mode 100644 index 000000000000..0c200f6a41c0 --- /dev/null +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.pb.go @@ -0,0 +1,2948 @@ +// Code generated by protoc-gen-gogo. +// source: test.proto +// DO NOT EDIT! + +/* +Package testdata is a generated protocol buffer package. + +It is generated from these files: + test.proto + +It has these top-level messages: + GoEnum + GoTestField + GoTest + GoSkipTest + NonPackedTest + PackedTest + MaxTag + OldMessage + NewMessage + InnerMessage + OtherMessage + MyMessage + Ext + DefaultsMessage + MyMessageSet + Empty + MessageList + Strings + Defaults + SubDefaults + RepeatedEnum + MoreRepeated + GroupOld + GroupNew + FloatingPoint + MessageWithMap + Communique +*/ +package testdata + +import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +type FOO int32 + +const ( + FOO_FOO1 FOO = 1 +) + +var FOO_name = map[int32]string{ + 1: "FOO1", +} +var FOO_value = map[string]int32{ + "FOO1": 1, +} + +func (x FOO) Enum() *FOO { + p := new(FOO) + *p = x + return p +} +func (x FOO) String() string { + return proto.EnumName(FOO_name, int32(x)) +} +func (x *FOO) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FOO_value, data, "FOO") + if err != nil { + return err + } + *x = FOO(value) + return nil +} + +// An enum, for completeness. +type GoTest_KIND int32 + +const ( + GoTest_VOID GoTest_KIND = 0 + // Basic types + GoTest_BOOL GoTest_KIND = 1 + GoTest_BYTES GoTest_KIND = 2 + GoTest_FINGERPRINT GoTest_KIND = 3 + GoTest_FLOAT GoTest_KIND = 4 + GoTest_INT GoTest_KIND = 5 + GoTest_STRING GoTest_KIND = 6 + GoTest_TIME GoTest_KIND = 7 + // Groupings + GoTest_TUPLE GoTest_KIND = 8 + GoTest_ARRAY GoTest_KIND = 9 + GoTest_MAP GoTest_KIND = 10 + // Table types + GoTest_TABLE GoTest_KIND = 11 + // Functions + GoTest_FUNCTION GoTest_KIND = 12 +) + +var GoTest_KIND_name = map[int32]string{ + 0: "VOID", + 1: "BOOL", + 2: "BYTES", + 3: "FINGERPRINT", + 4: "FLOAT", + 5: "INT", + 6: "STRING", + 7: "TIME", + 8: "TUPLE", + 9: "ARRAY", + 10: "MAP", + 11: "TABLE", + 12: "FUNCTION", +} +var GoTest_KIND_value = map[string]int32{ + "VOID": 0, + "BOOL": 1, + "BYTES": 2, + "FINGERPRINT": 3, + "FLOAT": 4, + "INT": 5, + "STRING": 6, + "TIME": 7, + "TUPLE": 8, + "ARRAY": 9, + "MAP": 10, + "TABLE": 11, + "FUNCTION": 12, +} + +func (x GoTest_KIND) Enum() *GoTest_KIND { + p := new(GoTest_KIND) + *p = x + return p +} +func (x GoTest_KIND) String() string { + return proto.EnumName(GoTest_KIND_name, int32(x)) +} +func (x *GoTest_KIND) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(GoTest_KIND_value, data, "GoTest_KIND") + if err != nil { + return err + } + *x = GoTest_KIND(value) + return nil +} + +type MyMessage_Color int32 + +const ( + MyMessage_RED MyMessage_Color = 0 + MyMessage_GREEN MyMessage_Color = 1 + MyMessage_BLUE MyMessage_Color = 2 +) + +var MyMessage_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} +var MyMessage_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x MyMessage_Color) Enum() *MyMessage_Color { + p := new(MyMessage_Color) + *p = x + return p +} +func (x MyMessage_Color) String() string { + return proto.EnumName(MyMessage_Color_name, int32(x)) +} +func (x *MyMessage_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(MyMessage_Color_value, data, "MyMessage_Color") + if err != nil { + return err + } + *x = MyMessage_Color(value) + return nil +} + +type DefaultsMessage_DefaultsEnum int32 + +const ( + DefaultsMessage_ZERO DefaultsMessage_DefaultsEnum = 0 + DefaultsMessage_ONE DefaultsMessage_DefaultsEnum = 1 + DefaultsMessage_TWO DefaultsMessage_DefaultsEnum = 2 +) + +var DefaultsMessage_DefaultsEnum_name = map[int32]string{ + 0: "ZERO", + 1: "ONE", + 2: "TWO", +} +var DefaultsMessage_DefaultsEnum_value = map[string]int32{ + "ZERO": 0, + "ONE": 1, + "TWO": 2, +} + +func (x DefaultsMessage_DefaultsEnum) Enum() *DefaultsMessage_DefaultsEnum { + p := new(DefaultsMessage_DefaultsEnum) + *p = x + return p +} +func (x DefaultsMessage_DefaultsEnum) String() string { + return proto.EnumName(DefaultsMessage_DefaultsEnum_name, int32(x)) +} +func (x *DefaultsMessage_DefaultsEnum) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(DefaultsMessage_DefaultsEnum_value, data, "DefaultsMessage_DefaultsEnum") + if err != nil { + return err + } + *x = DefaultsMessage_DefaultsEnum(value) + return nil +} + +type Defaults_Color int32 + +const ( + Defaults_RED Defaults_Color = 0 + Defaults_GREEN Defaults_Color = 1 + Defaults_BLUE Defaults_Color = 2 +) + +var Defaults_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} +var Defaults_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x Defaults_Color) Enum() *Defaults_Color { + p := new(Defaults_Color) + *p = x + return p +} +func (x Defaults_Color) String() string { + return proto.EnumName(Defaults_Color_name, int32(x)) +} +func (x *Defaults_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Defaults_Color_value, data, "Defaults_Color") + if err != nil { + return err + } + *x = Defaults_Color(value) + return nil +} + +type RepeatedEnum_Color int32 + +const ( + RepeatedEnum_RED RepeatedEnum_Color = 1 +) + +var RepeatedEnum_Color_name = map[int32]string{ + 1: "RED", +} +var RepeatedEnum_Color_value = map[string]int32{ + "RED": 1, +} + +func (x RepeatedEnum_Color) Enum() *RepeatedEnum_Color { + p := new(RepeatedEnum_Color) + *p = x + return p +} +func (x RepeatedEnum_Color) String() string { + return proto.EnumName(RepeatedEnum_Color_name, int32(x)) +} +func (x *RepeatedEnum_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(RepeatedEnum_Color_value, data, "RepeatedEnum_Color") + if err != nil { + return err + } + *x = RepeatedEnum_Color(value) + return nil +} + +type GoEnum struct { + Foo *FOO `protobuf:"varint,1,req,name=foo,enum=testdata.FOO" json:"foo,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoEnum) Reset() { *m = GoEnum{} } +func (m *GoEnum) String() string { return proto.CompactTextString(m) } +func (*GoEnum) ProtoMessage() {} + +func (m *GoEnum) GetFoo() FOO { + if m != nil && m.Foo != nil { + return *m.Foo + } + return FOO_FOO1 +} + +type GoTestField struct { + Label *string `protobuf:"bytes,1,req,name=Label" json:"Label,omitempty"` + Type *string `protobuf:"bytes,2,req,name=Type" json:"Type,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTestField) Reset() { *m = GoTestField{} } +func (m *GoTestField) String() string { return proto.CompactTextString(m) } +func (*GoTestField) ProtoMessage() {} + +func (m *GoTestField) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *GoTestField) GetType() string { + if m != nil && m.Type != nil { + return *m.Type + } + return "" +} + +type GoTest struct { + // Some typical parameters + Kind *GoTest_KIND `protobuf:"varint,1,req,name=Kind,enum=testdata.GoTest_KIND" json:"Kind,omitempty"` + Table *string `protobuf:"bytes,2,opt,name=Table" json:"Table,omitempty"` + Param *int32 `protobuf:"varint,3,opt,name=Param" json:"Param,omitempty"` + // Required, repeated and optional foreign fields. + RequiredField *GoTestField `protobuf:"bytes,4,req,name=RequiredField" json:"RequiredField,omitempty"` + RepeatedField []*GoTestField `protobuf:"bytes,5,rep,name=RepeatedField" json:"RepeatedField,omitempty"` + OptionalField *GoTestField `protobuf:"bytes,6,opt,name=OptionalField" json:"OptionalField,omitempty"` + // Required fields of all basic types + F_BoolRequired *bool `protobuf:"varint,10,req,name=F_Bool_required" json:"F_Bool_required,omitempty"` + F_Int32Required *int32 `protobuf:"varint,11,req,name=F_Int32_required" json:"F_Int32_required,omitempty"` + F_Int64Required *int64 `protobuf:"varint,12,req,name=F_Int64_required" json:"F_Int64_required,omitempty"` + F_Fixed32Required *uint32 `protobuf:"fixed32,13,req,name=F_Fixed32_required" json:"F_Fixed32_required,omitempty"` + F_Fixed64Required *uint64 `protobuf:"fixed64,14,req,name=F_Fixed64_required" json:"F_Fixed64_required,omitempty"` + F_Uint32Required *uint32 `protobuf:"varint,15,req,name=F_Uint32_required" json:"F_Uint32_required,omitempty"` + F_Uint64Required *uint64 `protobuf:"varint,16,req,name=F_Uint64_required" json:"F_Uint64_required,omitempty"` + F_FloatRequired *float32 `protobuf:"fixed32,17,req,name=F_Float_required" json:"F_Float_required,omitempty"` + F_DoubleRequired *float64 `protobuf:"fixed64,18,req,name=F_Double_required" json:"F_Double_required,omitempty"` + F_StringRequired *string `protobuf:"bytes,19,req,name=F_String_required" json:"F_String_required,omitempty"` + F_BytesRequired []byte `protobuf:"bytes,101,req,name=F_Bytes_required" json:"F_Bytes_required,omitempty"` + F_Sint32Required *int32 `protobuf:"zigzag32,102,req,name=F_Sint32_required" json:"F_Sint32_required,omitempty"` + F_Sint64Required *int64 `protobuf:"zigzag64,103,req,name=F_Sint64_required" json:"F_Sint64_required,omitempty"` + // Repeated fields of all basic types + F_BoolRepeated []bool `protobuf:"varint,20,rep,name=F_Bool_repeated" json:"F_Bool_repeated,omitempty"` + F_Int32Repeated []int32 `protobuf:"varint,21,rep,name=F_Int32_repeated" json:"F_Int32_repeated,omitempty"` + F_Int64Repeated []int64 `protobuf:"varint,22,rep,name=F_Int64_repeated" json:"F_Int64_repeated,omitempty"` + F_Fixed32Repeated []uint32 `protobuf:"fixed32,23,rep,name=F_Fixed32_repeated" json:"F_Fixed32_repeated,omitempty"` + F_Fixed64Repeated []uint64 `protobuf:"fixed64,24,rep,name=F_Fixed64_repeated" json:"F_Fixed64_repeated,omitempty"` + F_Uint32Repeated []uint32 `protobuf:"varint,25,rep,name=F_Uint32_repeated" json:"F_Uint32_repeated,omitempty"` + F_Uint64Repeated []uint64 `protobuf:"varint,26,rep,name=F_Uint64_repeated" json:"F_Uint64_repeated,omitempty"` + F_FloatRepeated []float32 `protobuf:"fixed32,27,rep,name=F_Float_repeated" json:"F_Float_repeated,omitempty"` + F_DoubleRepeated []float64 `protobuf:"fixed64,28,rep,name=F_Double_repeated" json:"F_Double_repeated,omitempty"` + F_StringRepeated []string `protobuf:"bytes,29,rep,name=F_String_repeated" json:"F_String_repeated,omitempty"` + F_BytesRepeated [][]byte `protobuf:"bytes,201,rep,name=F_Bytes_repeated" json:"F_Bytes_repeated,omitempty"` + F_Sint32Repeated []int32 `protobuf:"zigzag32,202,rep,name=F_Sint32_repeated" json:"F_Sint32_repeated,omitempty"` + F_Sint64Repeated []int64 `protobuf:"zigzag64,203,rep,name=F_Sint64_repeated" json:"F_Sint64_repeated,omitempty"` + // Optional fields of all basic types + F_BoolOptional *bool `protobuf:"varint,30,opt,name=F_Bool_optional" json:"F_Bool_optional,omitempty"` + F_Int32Optional *int32 `protobuf:"varint,31,opt,name=F_Int32_optional" json:"F_Int32_optional,omitempty"` + F_Int64Optional *int64 `protobuf:"varint,32,opt,name=F_Int64_optional" json:"F_Int64_optional,omitempty"` + F_Fixed32Optional *uint32 `protobuf:"fixed32,33,opt,name=F_Fixed32_optional" json:"F_Fixed32_optional,omitempty"` + F_Fixed64Optional *uint64 `protobuf:"fixed64,34,opt,name=F_Fixed64_optional" json:"F_Fixed64_optional,omitempty"` + F_Uint32Optional *uint32 `protobuf:"varint,35,opt,name=F_Uint32_optional" json:"F_Uint32_optional,omitempty"` + F_Uint64Optional *uint64 `protobuf:"varint,36,opt,name=F_Uint64_optional" json:"F_Uint64_optional,omitempty"` + F_FloatOptional *float32 `protobuf:"fixed32,37,opt,name=F_Float_optional" json:"F_Float_optional,omitempty"` + F_DoubleOptional *float64 `protobuf:"fixed64,38,opt,name=F_Double_optional" json:"F_Double_optional,omitempty"` + F_StringOptional *string `protobuf:"bytes,39,opt,name=F_String_optional" json:"F_String_optional,omitempty"` + F_BytesOptional []byte `protobuf:"bytes,301,opt,name=F_Bytes_optional" json:"F_Bytes_optional,omitempty"` + F_Sint32Optional *int32 `protobuf:"zigzag32,302,opt,name=F_Sint32_optional" json:"F_Sint32_optional,omitempty"` + F_Sint64Optional *int64 `protobuf:"zigzag64,303,opt,name=F_Sint64_optional" json:"F_Sint64_optional,omitempty"` + // Default-valued fields of all basic types + F_BoolDefaulted *bool `protobuf:"varint,40,opt,name=F_Bool_defaulted,def=1" json:"F_Bool_defaulted,omitempty"` + F_Int32Defaulted *int32 `protobuf:"varint,41,opt,name=F_Int32_defaulted,def=32" json:"F_Int32_defaulted,omitempty"` + F_Int64Defaulted *int64 `protobuf:"varint,42,opt,name=F_Int64_defaulted,def=64" json:"F_Int64_defaulted,omitempty"` + F_Fixed32Defaulted *uint32 `protobuf:"fixed32,43,opt,name=F_Fixed32_defaulted,def=320" json:"F_Fixed32_defaulted,omitempty"` + F_Fixed64Defaulted *uint64 `protobuf:"fixed64,44,opt,name=F_Fixed64_defaulted,def=640" json:"F_Fixed64_defaulted,omitempty"` + F_Uint32Defaulted *uint32 `protobuf:"varint,45,opt,name=F_Uint32_defaulted,def=3200" json:"F_Uint32_defaulted,omitempty"` + F_Uint64Defaulted *uint64 `protobuf:"varint,46,opt,name=F_Uint64_defaulted,def=6400" json:"F_Uint64_defaulted,omitempty"` + F_FloatDefaulted *float32 `protobuf:"fixed32,47,opt,name=F_Float_defaulted,def=314159" json:"F_Float_defaulted,omitempty"` + F_DoubleDefaulted *float64 `protobuf:"fixed64,48,opt,name=F_Double_defaulted,def=271828" json:"F_Double_defaulted,omitempty"` + F_StringDefaulted *string `protobuf:"bytes,49,opt,name=F_String_defaulted,def=hello, \"world!\"\n" json:"F_String_defaulted,omitempty"` + F_BytesDefaulted []byte `protobuf:"bytes,401,opt,name=F_Bytes_defaulted,def=Bignose" json:"F_Bytes_defaulted,omitempty"` + F_Sint32Defaulted *int32 `protobuf:"zigzag32,402,opt,name=F_Sint32_defaulted,def=-32" json:"F_Sint32_defaulted,omitempty"` + F_Sint64Defaulted *int64 `protobuf:"zigzag64,403,opt,name=F_Sint64_defaulted,def=-64" json:"F_Sint64_defaulted,omitempty"` + // Packed repeated fields (no string or bytes). + F_BoolRepeatedPacked []bool `protobuf:"varint,50,rep,packed,name=F_Bool_repeated_packed" json:"F_Bool_repeated_packed,omitempty"` + F_Int32RepeatedPacked []int32 `protobuf:"varint,51,rep,packed,name=F_Int32_repeated_packed" json:"F_Int32_repeated_packed,omitempty"` + F_Int64RepeatedPacked []int64 `protobuf:"varint,52,rep,packed,name=F_Int64_repeated_packed" json:"F_Int64_repeated_packed,omitempty"` + F_Fixed32RepeatedPacked []uint32 `protobuf:"fixed32,53,rep,packed,name=F_Fixed32_repeated_packed" json:"F_Fixed32_repeated_packed,omitempty"` + F_Fixed64RepeatedPacked []uint64 `protobuf:"fixed64,54,rep,packed,name=F_Fixed64_repeated_packed" json:"F_Fixed64_repeated_packed,omitempty"` + F_Uint32RepeatedPacked []uint32 `protobuf:"varint,55,rep,packed,name=F_Uint32_repeated_packed" json:"F_Uint32_repeated_packed,omitempty"` + F_Uint64RepeatedPacked []uint64 `protobuf:"varint,56,rep,packed,name=F_Uint64_repeated_packed" json:"F_Uint64_repeated_packed,omitempty"` + F_FloatRepeatedPacked []float32 `protobuf:"fixed32,57,rep,packed,name=F_Float_repeated_packed" json:"F_Float_repeated_packed,omitempty"` + F_DoubleRepeatedPacked []float64 `protobuf:"fixed64,58,rep,packed,name=F_Double_repeated_packed" json:"F_Double_repeated_packed,omitempty"` + F_Sint32RepeatedPacked []int32 `protobuf:"zigzag32,502,rep,packed,name=F_Sint32_repeated_packed" json:"F_Sint32_repeated_packed,omitempty"` + F_Sint64RepeatedPacked []int64 `protobuf:"zigzag64,503,rep,packed,name=F_Sint64_repeated_packed" json:"F_Sint64_repeated_packed,omitempty"` + Requiredgroup *GoTest_RequiredGroup `protobuf:"group,70,req,name=RequiredGroup" json:"requiredgroup,omitempty"` + Repeatedgroup []*GoTest_RepeatedGroup `protobuf:"group,80,rep,name=RepeatedGroup" json:"repeatedgroup,omitempty"` + Optionalgroup *GoTest_OptionalGroup `protobuf:"group,90,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest) Reset() { *m = GoTest{} } +func (m *GoTest) String() string { return proto.CompactTextString(m) } +func (*GoTest) ProtoMessage() {} + +const Default_GoTest_F_BoolDefaulted bool = true +const Default_GoTest_F_Int32Defaulted int32 = 32 +const Default_GoTest_F_Int64Defaulted int64 = 64 +const Default_GoTest_F_Fixed32Defaulted uint32 = 320 +const Default_GoTest_F_Fixed64Defaulted uint64 = 640 +const Default_GoTest_F_Uint32Defaulted uint32 = 3200 +const Default_GoTest_F_Uint64Defaulted uint64 = 6400 +const Default_GoTest_F_FloatDefaulted float32 = 314159 +const Default_GoTest_F_DoubleDefaulted float64 = 271828 +const Default_GoTest_F_StringDefaulted string = "hello, \"world!\"\n" + +var Default_GoTest_F_BytesDefaulted []byte = []byte("Bignose") + +const Default_GoTest_F_Sint32Defaulted int32 = -32 +const Default_GoTest_F_Sint64Defaulted int64 = -64 + +func (m *GoTest) GetKind() GoTest_KIND { + if m != nil && m.Kind != nil { + return *m.Kind + } + return GoTest_VOID +} + +func (m *GoTest) GetTable() string { + if m != nil && m.Table != nil { + return *m.Table + } + return "" +} + +func (m *GoTest) GetParam() int32 { + if m != nil && m.Param != nil { + return *m.Param + } + return 0 +} + +func (m *GoTest) GetRequiredField() *GoTestField { + if m != nil { + return m.RequiredField + } + return nil +} + +func (m *GoTest) GetRepeatedField() []*GoTestField { + if m != nil { + return m.RepeatedField + } + return nil +} + +func (m *GoTest) GetOptionalField() *GoTestField { + if m != nil { + return m.OptionalField + } + return nil +} + +func (m *GoTest) GetF_BoolRequired() bool { + if m != nil && m.F_BoolRequired != nil { + return *m.F_BoolRequired + } + return false +} + +func (m *GoTest) GetF_Int32Required() int32 { + if m != nil && m.F_Int32Required != nil { + return *m.F_Int32Required + } + return 0 +} + +func (m *GoTest) GetF_Int64Required() int64 { + if m != nil && m.F_Int64Required != nil { + return *m.F_Int64Required + } + return 0 +} + +func (m *GoTest) GetF_Fixed32Required() uint32 { + if m != nil && m.F_Fixed32Required != nil { + return *m.F_Fixed32Required + } + return 0 +} + +func (m *GoTest) GetF_Fixed64Required() uint64 { + if m != nil && m.F_Fixed64Required != nil { + return *m.F_Fixed64Required + } + return 0 +} + +func (m *GoTest) GetF_Uint32Required() uint32 { + if m != nil && m.F_Uint32Required != nil { + return *m.F_Uint32Required + } + return 0 +} + +func (m *GoTest) GetF_Uint64Required() uint64 { + if m != nil && m.F_Uint64Required != nil { + return *m.F_Uint64Required + } + return 0 +} + +func (m *GoTest) GetF_FloatRequired() float32 { + if m != nil && m.F_FloatRequired != nil { + return *m.F_FloatRequired + } + return 0 +} + +func (m *GoTest) GetF_DoubleRequired() float64 { + if m != nil && m.F_DoubleRequired != nil { + return *m.F_DoubleRequired + } + return 0 +} + +func (m *GoTest) GetF_StringRequired() string { + if m != nil && m.F_StringRequired != nil { + return *m.F_StringRequired + } + return "" +} + +func (m *GoTest) GetF_BytesRequired() []byte { + if m != nil { + return m.F_BytesRequired + } + return nil +} + +func (m *GoTest) GetF_Sint32Required() int32 { + if m != nil && m.F_Sint32Required != nil { + return *m.F_Sint32Required + } + return 0 +} + +func (m *GoTest) GetF_Sint64Required() int64 { + if m != nil && m.F_Sint64Required != nil { + return *m.F_Sint64Required + } + return 0 +} + +func (m *GoTest) GetF_BoolRepeated() []bool { + if m != nil { + return m.F_BoolRepeated + } + return nil +} + +func (m *GoTest) GetF_Int32Repeated() []int32 { + if m != nil { + return m.F_Int32Repeated + } + return nil +} + +func (m *GoTest) GetF_Int64Repeated() []int64 { + if m != nil { + return m.F_Int64Repeated + } + return nil +} + +func (m *GoTest) GetF_Fixed32Repeated() []uint32 { + if m != nil { + return m.F_Fixed32Repeated + } + return nil +} + +func (m *GoTest) GetF_Fixed64Repeated() []uint64 { + if m != nil { + return m.F_Fixed64Repeated + } + return nil +} + +func (m *GoTest) GetF_Uint32Repeated() []uint32 { + if m != nil { + return m.F_Uint32Repeated + } + return nil +} + +func (m *GoTest) GetF_Uint64Repeated() []uint64 { + if m != nil { + return m.F_Uint64Repeated + } + return nil +} + +func (m *GoTest) GetF_FloatRepeated() []float32 { + if m != nil { + return m.F_FloatRepeated + } + return nil +} + +func (m *GoTest) GetF_DoubleRepeated() []float64 { + if m != nil { + return m.F_DoubleRepeated + } + return nil +} + +func (m *GoTest) GetF_StringRepeated() []string { + if m != nil { + return m.F_StringRepeated + } + return nil +} + +func (m *GoTest) GetF_BytesRepeated() [][]byte { + if m != nil { + return m.F_BytesRepeated + } + return nil +} + +func (m *GoTest) GetF_Sint32Repeated() []int32 { + if m != nil { + return m.F_Sint32Repeated + } + return nil +} + +func (m *GoTest) GetF_Sint64Repeated() []int64 { + if m != nil { + return m.F_Sint64Repeated + } + return nil +} + +func (m *GoTest) GetF_BoolOptional() bool { + if m != nil && m.F_BoolOptional != nil { + return *m.F_BoolOptional + } + return false +} + +func (m *GoTest) GetF_Int32Optional() int32 { + if m != nil && m.F_Int32Optional != nil { + return *m.F_Int32Optional + } + return 0 +} + +func (m *GoTest) GetF_Int64Optional() int64 { + if m != nil && m.F_Int64Optional != nil { + return *m.F_Int64Optional + } + return 0 +} + +func (m *GoTest) GetF_Fixed32Optional() uint32 { + if m != nil && m.F_Fixed32Optional != nil { + return *m.F_Fixed32Optional + } + return 0 +} + +func (m *GoTest) GetF_Fixed64Optional() uint64 { + if m != nil && m.F_Fixed64Optional != nil { + return *m.F_Fixed64Optional + } + return 0 +} + +func (m *GoTest) GetF_Uint32Optional() uint32 { + if m != nil && m.F_Uint32Optional != nil { + return *m.F_Uint32Optional + } + return 0 +} + +func (m *GoTest) GetF_Uint64Optional() uint64 { + if m != nil && m.F_Uint64Optional != nil { + return *m.F_Uint64Optional + } + return 0 +} + +func (m *GoTest) GetF_FloatOptional() float32 { + if m != nil && m.F_FloatOptional != nil { + return *m.F_FloatOptional + } + return 0 +} + +func (m *GoTest) GetF_DoubleOptional() float64 { + if m != nil && m.F_DoubleOptional != nil { + return *m.F_DoubleOptional + } + return 0 +} + +func (m *GoTest) GetF_StringOptional() string { + if m != nil && m.F_StringOptional != nil { + return *m.F_StringOptional + } + return "" +} + +func (m *GoTest) GetF_BytesOptional() []byte { + if m != nil { + return m.F_BytesOptional + } + return nil +} + +func (m *GoTest) GetF_Sint32Optional() int32 { + if m != nil && m.F_Sint32Optional != nil { + return *m.F_Sint32Optional + } + return 0 +} + +func (m *GoTest) GetF_Sint64Optional() int64 { + if m != nil && m.F_Sint64Optional != nil { + return *m.F_Sint64Optional + } + return 0 +} + +func (m *GoTest) GetF_BoolDefaulted() bool { + if m != nil && m.F_BoolDefaulted != nil { + return *m.F_BoolDefaulted + } + return Default_GoTest_F_BoolDefaulted +} + +func (m *GoTest) GetF_Int32Defaulted() int32 { + if m != nil && m.F_Int32Defaulted != nil { + return *m.F_Int32Defaulted + } + return Default_GoTest_F_Int32Defaulted +} + +func (m *GoTest) GetF_Int64Defaulted() int64 { + if m != nil && m.F_Int64Defaulted != nil { + return *m.F_Int64Defaulted + } + return Default_GoTest_F_Int64Defaulted +} + +func (m *GoTest) GetF_Fixed32Defaulted() uint32 { + if m != nil && m.F_Fixed32Defaulted != nil { + return *m.F_Fixed32Defaulted + } + return Default_GoTest_F_Fixed32Defaulted +} + +func (m *GoTest) GetF_Fixed64Defaulted() uint64 { + if m != nil && m.F_Fixed64Defaulted != nil { + return *m.F_Fixed64Defaulted + } + return Default_GoTest_F_Fixed64Defaulted +} + +func (m *GoTest) GetF_Uint32Defaulted() uint32 { + if m != nil && m.F_Uint32Defaulted != nil { + return *m.F_Uint32Defaulted + } + return Default_GoTest_F_Uint32Defaulted +} + +func (m *GoTest) GetF_Uint64Defaulted() uint64 { + if m != nil && m.F_Uint64Defaulted != nil { + return *m.F_Uint64Defaulted + } + return Default_GoTest_F_Uint64Defaulted +} + +func (m *GoTest) GetF_FloatDefaulted() float32 { + if m != nil && m.F_FloatDefaulted != nil { + return *m.F_FloatDefaulted + } + return Default_GoTest_F_FloatDefaulted +} + +func (m *GoTest) GetF_DoubleDefaulted() float64 { + if m != nil && m.F_DoubleDefaulted != nil { + return *m.F_DoubleDefaulted + } + return Default_GoTest_F_DoubleDefaulted +} + +func (m *GoTest) GetF_StringDefaulted() string { + if m != nil && m.F_StringDefaulted != nil { + return *m.F_StringDefaulted + } + return Default_GoTest_F_StringDefaulted +} + +func (m *GoTest) GetF_BytesDefaulted() []byte { + if m != nil && m.F_BytesDefaulted != nil { + return m.F_BytesDefaulted + } + return append([]byte(nil), Default_GoTest_F_BytesDefaulted...) +} + +func (m *GoTest) GetF_Sint32Defaulted() int32 { + if m != nil && m.F_Sint32Defaulted != nil { + return *m.F_Sint32Defaulted + } + return Default_GoTest_F_Sint32Defaulted +} + +func (m *GoTest) GetF_Sint64Defaulted() int64 { + if m != nil && m.F_Sint64Defaulted != nil { + return *m.F_Sint64Defaulted + } + return Default_GoTest_F_Sint64Defaulted +} + +func (m *GoTest) GetF_BoolRepeatedPacked() []bool { + if m != nil { + return m.F_BoolRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Int32RepeatedPacked() []int32 { + if m != nil { + return m.F_Int32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Int64RepeatedPacked() []int64 { + if m != nil { + return m.F_Int64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Fixed32RepeatedPacked() []uint32 { + if m != nil { + return m.F_Fixed32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Fixed64RepeatedPacked() []uint64 { + if m != nil { + return m.F_Fixed64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Uint32RepeatedPacked() []uint32 { + if m != nil { + return m.F_Uint32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Uint64RepeatedPacked() []uint64 { + if m != nil { + return m.F_Uint64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_FloatRepeatedPacked() []float32 { + if m != nil { + return m.F_FloatRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_DoubleRepeatedPacked() []float64 { + if m != nil { + return m.F_DoubleRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Sint32RepeatedPacked() []int32 { + if m != nil { + return m.F_Sint32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Sint64RepeatedPacked() []int64 { + if m != nil { + return m.F_Sint64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetRequiredgroup() *GoTest_RequiredGroup { + if m != nil { + return m.Requiredgroup + } + return nil +} + +func (m *GoTest) GetRepeatedgroup() []*GoTest_RepeatedGroup { + if m != nil { + return m.Repeatedgroup + } + return nil +} + +func (m *GoTest) GetOptionalgroup() *GoTest_OptionalGroup { + if m != nil { + return m.Optionalgroup + } + return nil +} + +// Required, repeated, and optional groups. +type GoTest_RequiredGroup struct { + RequiredField *string `protobuf:"bytes,71,req,name=RequiredField" json:"RequiredField,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest_RequiredGroup) Reset() { *m = GoTest_RequiredGroup{} } +func (m *GoTest_RequiredGroup) String() string { return proto.CompactTextString(m) } +func (*GoTest_RequiredGroup) ProtoMessage() {} + +func (m *GoTest_RequiredGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +type GoTest_RepeatedGroup struct { + RequiredField *string `protobuf:"bytes,81,req,name=RequiredField" json:"RequiredField,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest_RepeatedGroup) Reset() { *m = GoTest_RepeatedGroup{} } +func (m *GoTest_RepeatedGroup) String() string { return proto.CompactTextString(m) } +func (*GoTest_RepeatedGroup) ProtoMessage() {} + +func (m *GoTest_RepeatedGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +type GoTest_OptionalGroup struct { + RequiredField *string `protobuf:"bytes,91,req,name=RequiredField" json:"RequiredField,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest_OptionalGroup) Reset() { *m = GoTest_OptionalGroup{} } +func (m *GoTest_OptionalGroup) String() string { return proto.CompactTextString(m) } +func (*GoTest_OptionalGroup) ProtoMessage() {} + +func (m *GoTest_OptionalGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +// For testing skipping of unrecognized fields. +// Numbers are all big, larger than tag numbers in GoTestField, +// the message used in the corresponding test. +type GoSkipTest struct { + SkipInt32 *int32 `protobuf:"varint,11,req,name=skip_int32" json:"skip_int32,omitempty"` + SkipFixed32 *uint32 `protobuf:"fixed32,12,req,name=skip_fixed32" json:"skip_fixed32,omitempty"` + SkipFixed64 *uint64 `protobuf:"fixed64,13,req,name=skip_fixed64" json:"skip_fixed64,omitempty"` + SkipString *string `protobuf:"bytes,14,req,name=skip_string" json:"skip_string,omitempty"` + Skipgroup *GoSkipTest_SkipGroup `protobuf:"group,15,req,name=SkipGroup" json:"skipgroup,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoSkipTest) Reset() { *m = GoSkipTest{} } +func (m *GoSkipTest) String() string { return proto.CompactTextString(m) } +func (*GoSkipTest) ProtoMessage() {} + +func (m *GoSkipTest) GetSkipInt32() int32 { + if m != nil && m.SkipInt32 != nil { + return *m.SkipInt32 + } + return 0 +} + +func (m *GoSkipTest) GetSkipFixed32() uint32 { + if m != nil && m.SkipFixed32 != nil { + return *m.SkipFixed32 + } + return 0 +} + +func (m *GoSkipTest) GetSkipFixed64() uint64 { + if m != nil && m.SkipFixed64 != nil { + return *m.SkipFixed64 + } + return 0 +} + +func (m *GoSkipTest) GetSkipString() string { + if m != nil && m.SkipString != nil { + return *m.SkipString + } + return "" +} + +func (m *GoSkipTest) GetSkipgroup() *GoSkipTest_SkipGroup { + if m != nil { + return m.Skipgroup + } + return nil +} + +type GoSkipTest_SkipGroup struct { + GroupInt32 *int32 `protobuf:"varint,16,req,name=group_int32" json:"group_int32,omitempty"` + GroupString *string `protobuf:"bytes,17,req,name=group_string" json:"group_string,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoSkipTest_SkipGroup) Reset() { *m = GoSkipTest_SkipGroup{} } +func (m *GoSkipTest_SkipGroup) String() string { return proto.CompactTextString(m) } +func (*GoSkipTest_SkipGroup) ProtoMessage() {} + +func (m *GoSkipTest_SkipGroup) GetGroupInt32() int32 { + if m != nil && m.GroupInt32 != nil { + return *m.GroupInt32 + } + return 0 +} + +func (m *GoSkipTest_SkipGroup) GetGroupString() string { + if m != nil && m.GroupString != nil { + return *m.GroupString + } + return "" +} + +// For testing packed/non-packed decoder switching. +// A serialized instance of one should be deserializable as the other. +type NonPackedTest struct { + A []int32 `protobuf:"varint,1,rep,name=a" json:"a,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NonPackedTest) Reset() { *m = NonPackedTest{} } +func (m *NonPackedTest) String() string { return proto.CompactTextString(m) } +func (*NonPackedTest) ProtoMessage() {} + +func (m *NonPackedTest) GetA() []int32 { + if m != nil { + return m.A + } + return nil +} + +type PackedTest struct { + B []int32 `protobuf:"varint,1,rep,packed,name=b" json:"b,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *PackedTest) Reset() { *m = PackedTest{} } +func (m *PackedTest) String() string { return proto.CompactTextString(m) } +func (*PackedTest) ProtoMessage() {} + +func (m *PackedTest) GetB() []int32 { + if m != nil { + return m.B + } + return nil +} + +type MaxTag struct { + // Maximum possible tag number. + LastField *string `protobuf:"bytes,536870911,opt,name=last_field" json:"last_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MaxTag) Reset() { *m = MaxTag{} } +func (m *MaxTag) String() string { return proto.CompactTextString(m) } +func (*MaxTag) ProtoMessage() {} + +func (m *MaxTag) GetLastField() string { + if m != nil && m.LastField != nil { + return *m.LastField + } + return "" +} + +type OldMessage struct { + Nested *OldMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"` + Num *int32 `protobuf:"varint,2,opt,name=num" json:"num,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OldMessage) Reset() { *m = OldMessage{} } +func (m *OldMessage) String() string { return proto.CompactTextString(m) } +func (*OldMessage) ProtoMessage() {} + +func (m *OldMessage) GetNested() *OldMessage_Nested { + if m != nil { + return m.Nested + } + return nil +} + +func (m *OldMessage) GetNum() int32 { + if m != nil && m.Num != nil { + return *m.Num + } + return 0 +} + +type OldMessage_Nested struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OldMessage_Nested) Reset() { *m = OldMessage_Nested{} } +func (m *OldMessage_Nested) String() string { return proto.CompactTextString(m) } +func (*OldMessage_Nested) ProtoMessage() {} + +func (m *OldMessage_Nested) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +// NewMessage is wire compatible with OldMessage; +// imagine it as a future version. +type NewMessage struct { + Nested *NewMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"` + // This is an int32 in OldMessage. + Num *int64 `protobuf:"varint,2,opt,name=num" json:"num,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NewMessage) Reset() { *m = NewMessage{} } +func (m *NewMessage) String() string { return proto.CompactTextString(m) } +func (*NewMessage) ProtoMessage() {} + +func (m *NewMessage) GetNested() *NewMessage_Nested { + if m != nil { + return m.Nested + } + return nil +} + +func (m *NewMessage) GetNum() int64 { + if m != nil && m.Num != nil { + return *m.Num + } + return 0 +} + +type NewMessage_Nested struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + FoodGroup *string `protobuf:"bytes,2,opt,name=food_group" json:"food_group,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NewMessage_Nested) Reset() { *m = NewMessage_Nested{} } +func (m *NewMessage_Nested) String() string { return proto.CompactTextString(m) } +func (*NewMessage_Nested) ProtoMessage() {} + +func (m *NewMessage_Nested) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *NewMessage_Nested) GetFoodGroup() string { + if m != nil && m.FoodGroup != nil { + return *m.FoodGroup + } + return "" +} + +type InnerMessage struct { + Host *string `protobuf:"bytes,1,req,name=host" json:"host,omitempty"` + Port *int32 `protobuf:"varint,2,opt,name=port,def=4000" json:"port,omitempty"` + Connected *bool `protobuf:"varint,3,opt,name=connected" json:"connected,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *InnerMessage) Reset() { *m = InnerMessage{} } +func (m *InnerMessage) String() string { return proto.CompactTextString(m) } +func (*InnerMessage) ProtoMessage() {} + +const Default_InnerMessage_Port int32 = 4000 + +func (m *InnerMessage) GetHost() string { + if m != nil && m.Host != nil { + return *m.Host + } + return "" +} + +func (m *InnerMessage) GetPort() int32 { + if m != nil && m.Port != nil { + return *m.Port + } + return Default_InnerMessage_Port +} + +func (m *InnerMessage) GetConnected() bool { + if m != nil && m.Connected != nil { + return *m.Connected + } + return false +} + +type OtherMessage struct { + Key *int64 `protobuf:"varint,1,opt,name=key" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` + Weight *float32 `protobuf:"fixed32,3,opt,name=weight" json:"weight,omitempty"` + Inner *InnerMessage `protobuf:"bytes,4,opt,name=inner" json:"inner,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OtherMessage) Reset() { *m = OtherMessage{} } +func (m *OtherMessage) String() string { return proto.CompactTextString(m) } +func (*OtherMessage) ProtoMessage() {} + +func (m *OtherMessage) GetKey() int64 { + if m != nil && m.Key != nil { + return *m.Key + } + return 0 +} + +func (m *OtherMessage) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *OtherMessage) GetWeight() float32 { + if m != nil && m.Weight != nil { + return *m.Weight + } + return 0 +} + +func (m *OtherMessage) GetInner() *InnerMessage { + if m != nil { + return m.Inner + } + return nil +} + +type MyMessage struct { + Count *int32 `protobuf:"varint,1,req,name=count" json:"count,omitempty"` + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + Quote *string `protobuf:"bytes,3,opt,name=quote" json:"quote,omitempty"` + Pet []string `protobuf:"bytes,4,rep,name=pet" json:"pet,omitempty"` + Inner *InnerMessage `protobuf:"bytes,5,opt,name=inner" json:"inner,omitempty"` + Others []*OtherMessage `protobuf:"bytes,6,rep,name=others" json:"others,omitempty"` + RepInner []*InnerMessage `protobuf:"bytes,12,rep,name=rep_inner" json:"rep_inner,omitempty"` + Bikeshed *MyMessage_Color `protobuf:"varint,7,opt,name=bikeshed,enum=testdata.MyMessage_Color" json:"bikeshed,omitempty"` + Somegroup *MyMessage_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"` + // This field becomes [][]byte in the generated code. + RepBytes [][]byte `protobuf:"bytes,10,rep,name=rep_bytes" json:"rep_bytes,omitempty"` + Bigfloat *float64 `protobuf:"fixed64,11,opt,name=bigfloat" json:"bigfloat,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MyMessage) Reset() { *m = MyMessage{} } +func (m *MyMessage) String() string { return proto.CompactTextString(m) } +func (*MyMessage) ProtoMessage() {} + +var extRange_MyMessage = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*MyMessage) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MyMessage +} +func (m *MyMessage) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *MyMessage) GetCount() int32 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +func (m *MyMessage) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MyMessage) GetQuote() string { + if m != nil && m.Quote != nil { + return *m.Quote + } + return "" +} + +func (m *MyMessage) GetPet() []string { + if m != nil { + return m.Pet + } + return nil +} + +func (m *MyMessage) GetInner() *InnerMessage { + if m != nil { + return m.Inner + } + return nil +} + +func (m *MyMessage) GetOthers() []*OtherMessage { + if m != nil { + return m.Others + } + return nil +} + +func (m *MyMessage) GetRepInner() []*InnerMessage { + if m != nil { + return m.RepInner + } + return nil +} + +func (m *MyMessage) GetBikeshed() MyMessage_Color { + if m != nil && m.Bikeshed != nil { + return *m.Bikeshed + } + return MyMessage_RED +} + +func (m *MyMessage) GetSomegroup() *MyMessage_SomeGroup { + if m != nil { + return m.Somegroup + } + return nil +} + +func (m *MyMessage) GetRepBytes() [][]byte { + if m != nil { + return m.RepBytes + } + return nil +} + +func (m *MyMessage) GetBigfloat() float64 { + if m != nil && m.Bigfloat != nil { + return *m.Bigfloat + } + return 0 +} + +type MyMessage_SomeGroup struct { + GroupField *int32 `protobuf:"varint,9,opt,name=group_field" json:"group_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MyMessage_SomeGroup) Reset() { *m = MyMessage_SomeGroup{} } +func (m *MyMessage_SomeGroup) String() string { return proto.CompactTextString(m) } +func (*MyMessage_SomeGroup) ProtoMessage() {} + +func (m *MyMessage_SomeGroup) GetGroupField() int32 { + if m != nil && m.GroupField != nil { + return *m.GroupField + } + return 0 +} + +type Ext struct { + Data *string `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Ext) Reset() { *m = Ext{} } +func (m *Ext) String() string { return proto.CompactTextString(m) } +func (*Ext) ProtoMessage() {} + +func (m *Ext) GetData() string { + if m != nil && m.Data != nil { + return *m.Data + } + return "" +} + +var E_Ext_More = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*Ext)(nil), + Field: 103, + Name: "testdata.Ext.more", + Tag: "bytes,103,opt,name=more", +} + +var E_Ext_Text = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*string)(nil), + Field: 104, + Name: "testdata.Ext.text", + Tag: "bytes,104,opt,name=text", +} + +var E_Ext_Number = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 105, + Name: "testdata.Ext.number", + Tag: "varint,105,opt,name=number", +} + +type DefaultsMessage struct { + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *DefaultsMessage) Reset() { *m = DefaultsMessage{} } +func (m *DefaultsMessage) String() string { return proto.CompactTextString(m) } +func (*DefaultsMessage) ProtoMessage() {} + +var extRange_DefaultsMessage = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*DefaultsMessage) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_DefaultsMessage +} +func (m *DefaultsMessage) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +type MyMessageSet struct { + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MyMessageSet) Reset() { *m = MyMessageSet{} } +func (m *MyMessageSet) String() string { return proto.CompactTextString(m) } +func (*MyMessageSet) ProtoMessage() {} + +func (m *MyMessageSet) Marshal() ([]byte, error) { + return proto.MarshalMessageSet(m.ExtensionMap()) +} +func (m *MyMessageSet) Unmarshal(buf []byte) error { + return proto.UnmarshalMessageSet(buf, m.ExtensionMap()) +} +func (m *MyMessageSet) MarshalJSON() ([]byte, error) { + return proto.MarshalMessageSetJSON(m.XXX_extensions) +} +func (m *MyMessageSet) UnmarshalJSON(buf []byte) error { + return proto.UnmarshalMessageSetJSON(buf, m.XXX_extensions) +} + +// ensure MyMessageSet satisfies proto.Marshaler and proto.Unmarshaler +var _ proto.Marshaler = (*MyMessageSet)(nil) +var _ proto.Unmarshaler = (*MyMessageSet)(nil) + +var extRange_MyMessageSet = []proto.ExtensionRange{ + {100, 2147483646}, +} + +func (*MyMessageSet) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MyMessageSet +} +func (m *MyMessageSet) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +type Empty struct { + XXX_unrecognized []byte `json:"-"` +} + +func (m *Empty) Reset() { *m = Empty{} } +func (m *Empty) String() string { return proto.CompactTextString(m) } +func (*Empty) ProtoMessage() {} + +type MessageList struct { + Message []*MessageList_Message `protobuf:"group,1,rep,name=Message" json:"message,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MessageList) Reset() { *m = MessageList{} } +func (m *MessageList) String() string { return proto.CompactTextString(m) } +func (*MessageList) ProtoMessage() {} + +func (m *MessageList) GetMessage() []*MessageList_Message { + if m != nil { + return m.Message + } + return nil +} + +type MessageList_Message struct { + Name *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"` + Count *int32 `protobuf:"varint,3,req,name=count" json:"count,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MessageList_Message) Reset() { *m = MessageList_Message{} } +func (m *MessageList_Message) String() string { return proto.CompactTextString(m) } +func (*MessageList_Message) ProtoMessage() {} + +func (m *MessageList_Message) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MessageList_Message) GetCount() int32 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +type Strings struct { + StringField *string `protobuf:"bytes,1,opt,name=string_field" json:"string_field,omitempty"` + BytesField []byte `protobuf:"bytes,2,opt,name=bytes_field" json:"bytes_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Strings) Reset() { *m = Strings{} } +func (m *Strings) String() string { return proto.CompactTextString(m) } +func (*Strings) ProtoMessage() {} + +func (m *Strings) GetStringField() string { + if m != nil && m.StringField != nil { + return *m.StringField + } + return "" +} + +func (m *Strings) GetBytesField() []byte { + if m != nil { + return m.BytesField + } + return nil +} + +type Defaults struct { + // Default-valued fields of all basic types. + // Same as GoTest, but copied here to make testing easier. + F_Bool *bool `protobuf:"varint,1,opt,name=F_Bool,def=1" json:"F_Bool,omitempty"` + F_Int32 *int32 `protobuf:"varint,2,opt,name=F_Int32,def=32" json:"F_Int32,omitempty"` + F_Int64 *int64 `protobuf:"varint,3,opt,name=F_Int64,def=64" json:"F_Int64,omitempty"` + F_Fixed32 *uint32 `protobuf:"fixed32,4,opt,name=F_Fixed32,def=320" json:"F_Fixed32,omitempty"` + F_Fixed64 *uint64 `protobuf:"fixed64,5,opt,name=F_Fixed64,def=640" json:"F_Fixed64,omitempty"` + F_Uint32 *uint32 `protobuf:"varint,6,opt,name=F_Uint32,def=3200" json:"F_Uint32,omitempty"` + F_Uint64 *uint64 `protobuf:"varint,7,opt,name=F_Uint64,def=6400" json:"F_Uint64,omitempty"` + F_Float *float32 `protobuf:"fixed32,8,opt,name=F_Float,def=314159" json:"F_Float,omitempty"` + F_Double *float64 `protobuf:"fixed64,9,opt,name=F_Double,def=271828" json:"F_Double,omitempty"` + F_String *string `protobuf:"bytes,10,opt,name=F_String,def=hello, \"world!\"\n" json:"F_String,omitempty"` + F_Bytes []byte `protobuf:"bytes,11,opt,name=F_Bytes,def=Bignose" json:"F_Bytes,omitempty"` + F_Sint32 *int32 `protobuf:"zigzag32,12,opt,name=F_Sint32,def=-32" json:"F_Sint32,omitempty"` + F_Sint64 *int64 `protobuf:"zigzag64,13,opt,name=F_Sint64,def=-64" json:"F_Sint64,omitempty"` + F_Enum *Defaults_Color `protobuf:"varint,14,opt,name=F_Enum,enum=testdata.Defaults_Color,def=1" json:"F_Enum,omitempty"` + // More fields with crazy defaults. + F_Pinf *float32 `protobuf:"fixed32,15,opt,name=F_Pinf,def=inf" json:"F_Pinf,omitempty"` + F_Ninf *float32 `protobuf:"fixed32,16,opt,name=F_Ninf,def=-inf" json:"F_Ninf,omitempty"` + F_Nan *float32 `protobuf:"fixed32,17,opt,name=F_Nan,def=nan" json:"F_Nan,omitempty"` + // Sub-message. + Sub *SubDefaults `protobuf:"bytes,18,opt,name=sub" json:"sub,omitempty"` + // Redundant but explicit defaults. + StrZero *string `protobuf:"bytes,19,opt,name=str_zero,def=" json:"str_zero,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Defaults) Reset() { *m = Defaults{} } +func (m *Defaults) String() string { return proto.CompactTextString(m) } +func (*Defaults) ProtoMessage() {} + +const Default_Defaults_F_Bool bool = true +const Default_Defaults_F_Int32 int32 = 32 +const Default_Defaults_F_Int64 int64 = 64 +const Default_Defaults_F_Fixed32 uint32 = 320 +const Default_Defaults_F_Fixed64 uint64 = 640 +const Default_Defaults_F_Uint32 uint32 = 3200 +const Default_Defaults_F_Uint64 uint64 = 6400 +const Default_Defaults_F_Float float32 = 314159 +const Default_Defaults_F_Double float64 = 271828 +const Default_Defaults_F_String string = "hello, \"world!\"\n" + +var Default_Defaults_F_Bytes []byte = []byte("Bignose") + +const Default_Defaults_F_Sint32 int32 = -32 +const Default_Defaults_F_Sint64 int64 = -64 +const Default_Defaults_F_Enum Defaults_Color = Defaults_GREEN + +var Default_Defaults_F_Pinf float32 = float32(math.Inf(1)) +var Default_Defaults_F_Ninf float32 = float32(math.Inf(-1)) +var Default_Defaults_F_Nan float32 = float32(math.NaN()) + +func (m *Defaults) GetF_Bool() bool { + if m != nil && m.F_Bool != nil { + return *m.F_Bool + } + return Default_Defaults_F_Bool +} + +func (m *Defaults) GetF_Int32() int32 { + if m != nil && m.F_Int32 != nil { + return *m.F_Int32 + } + return Default_Defaults_F_Int32 +} + +func (m *Defaults) GetF_Int64() int64 { + if m != nil && m.F_Int64 != nil { + return *m.F_Int64 + } + return Default_Defaults_F_Int64 +} + +func (m *Defaults) GetF_Fixed32() uint32 { + if m != nil && m.F_Fixed32 != nil { + return *m.F_Fixed32 + } + return Default_Defaults_F_Fixed32 +} + +func (m *Defaults) GetF_Fixed64() uint64 { + if m != nil && m.F_Fixed64 != nil { + return *m.F_Fixed64 + } + return Default_Defaults_F_Fixed64 +} + +func (m *Defaults) GetF_Uint32() uint32 { + if m != nil && m.F_Uint32 != nil { + return *m.F_Uint32 + } + return Default_Defaults_F_Uint32 +} + +func (m *Defaults) GetF_Uint64() uint64 { + if m != nil && m.F_Uint64 != nil { + return *m.F_Uint64 + } + return Default_Defaults_F_Uint64 +} + +func (m *Defaults) GetF_Float() float32 { + if m != nil && m.F_Float != nil { + return *m.F_Float + } + return Default_Defaults_F_Float +} + +func (m *Defaults) GetF_Double() float64 { + if m != nil && m.F_Double != nil { + return *m.F_Double + } + return Default_Defaults_F_Double +} + +func (m *Defaults) GetF_String() string { + if m != nil && m.F_String != nil { + return *m.F_String + } + return Default_Defaults_F_String +} + +func (m *Defaults) GetF_Bytes() []byte { + if m != nil && m.F_Bytes != nil { + return m.F_Bytes + } + return append([]byte(nil), Default_Defaults_F_Bytes...) +} + +func (m *Defaults) GetF_Sint32() int32 { + if m != nil && m.F_Sint32 != nil { + return *m.F_Sint32 + } + return Default_Defaults_F_Sint32 +} + +func (m *Defaults) GetF_Sint64() int64 { + if m != nil && m.F_Sint64 != nil { + return *m.F_Sint64 + } + return Default_Defaults_F_Sint64 +} + +func (m *Defaults) GetF_Enum() Defaults_Color { + if m != nil && m.F_Enum != nil { + return *m.F_Enum + } + return Default_Defaults_F_Enum +} + +func (m *Defaults) GetF_Pinf() float32 { + if m != nil && m.F_Pinf != nil { + return *m.F_Pinf + } + return Default_Defaults_F_Pinf +} + +func (m *Defaults) GetF_Ninf() float32 { + if m != nil && m.F_Ninf != nil { + return *m.F_Ninf + } + return Default_Defaults_F_Ninf +} + +func (m *Defaults) GetF_Nan() float32 { + if m != nil && m.F_Nan != nil { + return *m.F_Nan + } + return Default_Defaults_F_Nan +} + +func (m *Defaults) GetSub() *SubDefaults { + if m != nil { + return m.Sub + } + return nil +} + +func (m *Defaults) GetStrZero() string { + if m != nil && m.StrZero != nil { + return *m.StrZero + } + return "" +} + +type SubDefaults struct { + N *int64 `protobuf:"varint,1,opt,name=n,def=7" json:"n,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *SubDefaults) Reset() { *m = SubDefaults{} } +func (m *SubDefaults) String() string { return proto.CompactTextString(m) } +func (*SubDefaults) ProtoMessage() {} + +const Default_SubDefaults_N int64 = 7 + +func (m *SubDefaults) GetN() int64 { + if m != nil && m.N != nil { + return *m.N + } + return Default_SubDefaults_N +} + +type RepeatedEnum struct { + Color []RepeatedEnum_Color `protobuf:"varint,1,rep,name=color,enum=testdata.RepeatedEnum_Color" json:"color,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *RepeatedEnum) Reset() { *m = RepeatedEnum{} } +func (m *RepeatedEnum) String() string { return proto.CompactTextString(m) } +func (*RepeatedEnum) ProtoMessage() {} + +func (m *RepeatedEnum) GetColor() []RepeatedEnum_Color { + if m != nil { + return m.Color + } + return nil +} + +type MoreRepeated struct { + Bools []bool `protobuf:"varint,1,rep,name=bools" json:"bools,omitempty"` + BoolsPacked []bool `protobuf:"varint,2,rep,packed,name=bools_packed" json:"bools_packed,omitempty"` + Ints []int32 `protobuf:"varint,3,rep,name=ints" json:"ints,omitempty"` + IntsPacked []int32 `protobuf:"varint,4,rep,packed,name=ints_packed" json:"ints_packed,omitempty"` + Int64SPacked []int64 `protobuf:"varint,7,rep,packed,name=int64s_packed" json:"int64s_packed,omitempty"` + Strings []string `protobuf:"bytes,5,rep,name=strings" json:"strings,omitempty"` + Fixeds []uint32 `protobuf:"fixed32,6,rep,name=fixeds" json:"fixeds,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MoreRepeated) Reset() { *m = MoreRepeated{} } +func (m *MoreRepeated) String() string { return proto.CompactTextString(m) } +func (*MoreRepeated) ProtoMessage() {} + +func (m *MoreRepeated) GetBools() []bool { + if m != nil { + return m.Bools + } + return nil +} + +func (m *MoreRepeated) GetBoolsPacked() []bool { + if m != nil { + return m.BoolsPacked + } + return nil +} + +func (m *MoreRepeated) GetInts() []int32 { + if m != nil { + return m.Ints + } + return nil +} + +func (m *MoreRepeated) GetIntsPacked() []int32 { + if m != nil { + return m.IntsPacked + } + return nil +} + +func (m *MoreRepeated) GetInt64SPacked() []int64 { + if m != nil { + return m.Int64SPacked + } + return nil +} + +func (m *MoreRepeated) GetStrings() []string { + if m != nil { + return m.Strings + } + return nil +} + +func (m *MoreRepeated) GetFixeds() []uint32 { + if m != nil { + return m.Fixeds + } + return nil +} + +type GroupOld struct { + G *GroupOld_G `protobuf:"group,101,opt,name=G" json:"g,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupOld) Reset() { *m = GroupOld{} } +func (m *GroupOld) String() string { return proto.CompactTextString(m) } +func (*GroupOld) ProtoMessage() {} + +func (m *GroupOld) GetG() *GroupOld_G { + if m != nil { + return m.G + } + return nil +} + +type GroupOld_G struct { + X *int32 `protobuf:"varint,2,opt,name=x" json:"x,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupOld_G) Reset() { *m = GroupOld_G{} } +func (m *GroupOld_G) String() string { return proto.CompactTextString(m) } +func (*GroupOld_G) ProtoMessage() {} + +func (m *GroupOld_G) GetX() int32 { + if m != nil && m.X != nil { + return *m.X + } + return 0 +} + +type GroupNew struct { + G *GroupNew_G `protobuf:"group,101,opt,name=G" json:"g,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupNew) Reset() { *m = GroupNew{} } +func (m *GroupNew) String() string { return proto.CompactTextString(m) } +func (*GroupNew) ProtoMessage() {} + +func (m *GroupNew) GetG() *GroupNew_G { + if m != nil { + return m.G + } + return nil +} + +type GroupNew_G struct { + X *int32 `protobuf:"varint,2,opt,name=x" json:"x,omitempty"` + Y *int32 `protobuf:"varint,3,opt,name=y" json:"y,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupNew_G) Reset() { *m = GroupNew_G{} } +func (m *GroupNew_G) String() string { return proto.CompactTextString(m) } +func (*GroupNew_G) ProtoMessage() {} + +func (m *GroupNew_G) GetX() int32 { + if m != nil && m.X != nil { + return *m.X + } + return 0 +} + +func (m *GroupNew_G) GetY() int32 { + if m != nil && m.Y != nil { + return *m.Y + } + return 0 +} + +type FloatingPoint struct { + F *float64 `protobuf:"fixed64,1,req,name=f" json:"f,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FloatingPoint) Reset() { *m = FloatingPoint{} } +func (m *FloatingPoint) String() string { return proto.CompactTextString(m) } +func (*FloatingPoint) ProtoMessage() {} + +func (m *FloatingPoint) GetF() float64 { + if m != nil && m.F != nil { + return *m.F + } + return 0 +} + +type MessageWithMap struct { + NameMapping map[int32]string `protobuf:"bytes,1,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + MsgMapping map[int64]*FloatingPoint `protobuf:"bytes,2,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + ByteMapping map[bool][]byte `protobuf:"bytes,3,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + StrToStr map[string]string `protobuf:"bytes,4,rep,name=str_to_str" json:"str_to_str,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MessageWithMap) Reset() { *m = MessageWithMap{} } +func (m *MessageWithMap) String() string { return proto.CompactTextString(m) } +func (*MessageWithMap) ProtoMessage() {} + +func (m *MessageWithMap) GetNameMapping() map[int32]string { + if m != nil { + return m.NameMapping + } + return nil +} + +func (m *MessageWithMap) GetMsgMapping() map[int64]*FloatingPoint { + if m != nil { + return m.MsgMapping + } + return nil +} + +func (m *MessageWithMap) GetByteMapping() map[bool][]byte { + if m != nil { + return m.ByteMapping + } + return nil +} + +func (m *MessageWithMap) GetStrToStr() map[string]string { + if m != nil { + return m.StrToStr + } + return nil +} + +type Communique struct { + MakeMeCry *bool `protobuf:"varint,1,opt,name=make_me_cry" json:"make_me_cry,omitempty"` + // This is a oneof, called "union". + // + // Types that are valid to be assigned to Union: + // *Communique_Number + // *Communique_Name + // *Communique_Data + // *Communique_TempC + // *Communique_Col + // *Communique_Msg + Union isCommunique_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Communique) Reset() { *m = Communique{} } +func (m *Communique) String() string { return proto.CompactTextString(m) } +func (*Communique) ProtoMessage() {} + +type isCommunique_Union interface { + isCommunique_Union() +} + +type Communique_Number struct { + Number int32 `protobuf:"varint,5,opt,name=number,oneof"` +} +type Communique_Name struct { + Name string `protobuf:"bytes,6,opt,name=name,oneof"` +} +type Communique_Data struct { + Data []byte `protobuf:"bytes,7,opt,name=data,oneof"` +} +type Communique_TempC struct { + TempC float64 `protobuf:"fixed64,8,opt,name=temp_c,oneof"` +} +type Communique_Col struct { + Col MyMessage_Color `protobuf:"varint,9,opt,name=col,enum=testdata.MyMessage_Color,oneof"` +} +type Communique_Msg struct { + Msg *Strings `protobuf:"bytes,10,opt,name=msg,oneof"` +} + +func (*Communique_Number) isCommunique_Union() {} +func (*Communique_Name) isCommunique_Union() {} +func (*Communique_Data) isCommunique_Union() {} +func (*Communique_TempC) isCommunique_Union() {} +func (*Communique_Col) isCommunique_Union() {} +func (*Communique_Msg) isCommunique_Union() {} + +func (m *Communique) GetUnion() isCommunique_Union { + if m != nil { + return m.Union + } + return nil +} + +func (m *Communique) GetMakeMeCry() bool { + if m != nil && m.MakeMeCry != nil { + return *m.MakeMeCry + } + return false +} + +func (m *Communique) GetNumber() int32 { + if x, ok := m.GetUnion().(*Communique_Number); ok { + return x.Number + } + return 0 +} + +func (m *Communique) GetName() string { + if x, ok := m.GetUnion().(*Communique_Name); ok { + return x.Name + } + return "" +} + +func (m *Communique) GetData() []byte { + if x, ok := m.GetUnion().(*Communique_Data); ok { + return x.Data + } + return nil +} + +func (m *Communique) GetTempC() float64 { + if x, ok := m.GetUnion().(*Communique_TempC); ok { + return x.TempC + } + return 0 +} + +func (m *Communique) GetCol() MyMessage_Color { + if x, ok := m.GetUnion().(*Communique_Col); ok { + return x.Col + } + return MyMessage_RED +} + +func (m *Communique) GetMsg() *Strings { + if x, ok := m.GetUnion().(*Communique_Msg); ok { + return x.Msg + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Communique) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{}) { + return _Communique_OneofMarshaler, _Communique_OneofUnmarshaler, []interface{}{ + (*Communique_Number)(nil), + (*Communique_Name)(nil), + (*Communique_Data)(nil), + (*Communique_TempC)(nil), + (*Communique_Col)(nil), + (*Communique_Msg)(nil), + } +} + +func _Communique_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Communique) + // union + switch x := m.Union.(type) { + case *Communique_Number: + _ = b.EncodeVarint(5<<3 | proto.WireVarint) + _ = b.EncodeVarint(uint64(x.Number)) + case *Communique_Name: + _ = b.EncodeVarint(6<<3 | proto.WireBytes) + _ = b.EncodeStringBytes(x.Name) + case *Communique_Data: + _ = b.EncodeVarint(7<<3 | proto.WireBytes) + _ = b.EncodeRawBytes(x.Data) + case *Communique_TempC: + _ = b.EncodeVarint(8<<3 | proto.WireFixed64) + _ = b.EncodeFixed64(math.Float64bits(x.TempC)) + case *Communique_Col: + _ = b.EncodeVarint(9<<3 | proto.WireVarint) + _ = b.EncodeVarint(uint64(x.Col)) + case *Communique_Msg: + _ = b.EncodeVarint(10<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Msg); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("Communique.Union has unexpected type %T", x) + } + return nil +} + +func _Communique_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Communique) + switch tag { + case 5: // union.number + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Communique_Number{int32(x)} + return true, err + case 6: // union.name + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Union = &Communique_Name{x} + return true, err + case 7: // union.data + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeRawBytes(true) + m.Union = &Communique_Data{x} + return true, err + case 8: // union.temp_c + if wire != proto.WireFixed64 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed64() + m.Union = &Communique_TempC{math.Float64frombits(x)} + return true, err + case 9: // union.col + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Communique_Col{MyMessage_Color(x)} + return true, err + case 10: // union.msg + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Strings) + err := b.DecodeMessage(msg) + m.Union = &Communique_Msg{msg} + return true, err + default: + return false, nil + } +} + +var E_Greeting = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: ([]string)(nil), + Field: 106, + Name: "testdata.greeting", + Tag: "bytes,106,rep,name=greeting", +} + +var E_NoDefaultDouble = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float64)(nil), + Field: 101, + Name: "testdata.no_default_double", + Tag: "fixed64,101,opt,name=no_default_double", +} + +var E_NoDefaultFloat = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float32)(nil), + Field: 102, + Name: "testdata.no_default_float", + Tag: "fixed32,102,opt,name=no_default_float", +} + +var E_NoDefaultInt32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 103, + Name: "testdata.no_default_int32", + Tag: "varint,103,opt,name=no_default_int32", +} + +var E_NoDefaultInt64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 104, + Name: "testdata.no_default_int64", + Tag: "varint,104,opt,name=no_default_int64", +} + +var E_NoDefaultUint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 105, + Name: "testdata.no_default_uint32", + Tag: "varint,105,opt,name=no_default_uint32", +} + +var E_NoDefaultUint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 106, + Name: "testdata.no_default_uint64", + Tag: "varint,106,opt,name=no_default_uint64", +} + +var E_NoDefaultSint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 107, + Name: "testdata.no_default_sint32", + Tag: "zigzag32,107,opt,name=no_default_sint32", +} + +var E_NoDefaultSint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 108, + Name: "testdata.no_default_sint64", + Tag: "zigzag64,108,opt,name=no_default_sint64", +} + +var E_NoDefaultFixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 109, + Name: "testdata.no_default_fixed32", + Tag: "fixed32,109,opt,name=no_default_fixed32", +} + +var E_NoDefaultFixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 110, + Name: "testdata.no_default_fixed64", + Tag: "fixed64,110,opt,name=no_default_fixed64", +} + +var E_NoDefaultSfixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 111, + Name: "testdata.no_default_sfixed32", + Tag: "fixed32,111,opt,name=no_default_sfixed32", +} + +var E_NoDefaultSfixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 112, + Name: "testdata.no_default_sfixed64", + Tag: "fixed64,112,opt,name=no_default_sfixed64", +} + +var E_NoDefaultBool = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*bool)(nil), + Field: 113, + Name: "testdata.no_default_bool", + Tag: "varint,113,opt,name=no_default_bool", +} + +var E_NoDefaultString = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*string)(nil), + Field: 114, + Name: "testdata.no_default_string", + Tag: "bytes,114,opt,name=no_default_string", +} + +var E_NoDefaultBytes = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: ([]byte)(nil), + Field: 115, + Name: "testdata.no_default_bytes", + Tag: "bytes,115,opt,name=no_default_bytes", +} + +var E_NoDefaultEnum = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil), + Field: 116, + Name: "testdata.no_default_enum", + Tag: "varint,116,opt,name=no_default_enum,enum=testdata.DefaultsMessage_DefaultsEnum", +} + +var E_DefaultDouble = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float64)(nil), + Field: 201, + Name: "testdata.default_double", + Tag: "fixed64,201,opt,name=default_double,def=3.1415", +} + +var E_DefaultFloat = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float32)(nil), + Field: 202, + Name: "testdata.default_float", + Tag: "fixed32,202,opt,name=default_float,def=3.14", +} + +var E_DefaultInt32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 203, + Name: "testdata.default_int32", + Tag: "varint,203,opt,name=default_int32,def=42", +} + +var E_DefaultInt64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 204, + Name: "testdata.default_int64", + Tag: "varint,204,opt,name=default_int64,def=43", +} + +var E_DefaultUint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 205, + Name: "testdata.default_uint32", + Tag: "varint,205,opt,name=default_uint32,def=44", +} + +var E_DefaultUint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 206, + Name: "testdata.default_uint64", + Tag: "varint,206,opt,name=default_uint64,def=45", +} + +var E_DefaultSint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 207, + Name: "testdata.default_sint32", + Tag: "zigzag32,207,opt,name=default_sint32,def=46", +} + +var E_DefaultSint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 208, + Name: "testdata.default_sint64", + Tag: "zigzag64,208,opt,name=default_sint64,def=47", +} + +var E_DefaultFixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 209, + Name: "testdata.default_fixed32", + Tag: "fixed32,209,opt,name=default_fixed32,def=48", +} + +var E_DefaultFixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 210, + Name: "testdata.default_fixed64", + Tag: "fixed64,210,opt,name=default_fixed64,def=49", +} + +var E_DefaultSfixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 211, + Name: "testdata.default_sfixed32", + Tag: "fixed32,211,opt,name=default_sfixed32,def=50", +} + +var E_DefaultSfixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 212, + Name: "testdata.default_sfixed64", + Tag: "fixed64,212,opt,name=default_sfixed64,def=51", +} + +var E_DefaultBool = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*bool)(nil), + Field: 213, + Name: "testdata.default_bool", + Tag: "varint,213,opt,name=default_bool,def=1", +} + +var E_DefaultString = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*string)(nil), + Field: 214, + Name: "testdata.default_string", + Tag: "bytes,214,opt,name=default_string,def=Hello, string", +} + +var E_DefaultBytes = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: ([]byte)(nil), + Field: 215, + Name: "testdata.default_bytes", + Tag: "bytes,215,opt,name=default_bytes,def=Hello, bytes", +} + +var E_DefaultEnum = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil), + Field: 216, + Name: "testdata.default_enum", + Tag: "varint,216,opt,name=default_enum,enum=testdata.DefaultsMessage_DefaultsEnum,def=1", +} + +var E_X201 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 201, + Name: "testdata.x201", + Tag: "bytes,201,opt,name=x201", +} + +var E_X202 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 202, + Name: "testdata.x202", + Tag: "bytes,202,opt,name=x202", +} + +var E_X203 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 203, + Name: "testdata.x203", + Tag: "bytes,203,opt,name=x203", +} + +var E_X204 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 204, + Name: "testdata.x204", + Tag: "bytes,204,opt,name=x204", +} + +var E_X205 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 205, + Name: "testdata.x205", + Tag: "bytes,205,opt,name=x205", +} + +var E_X206 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 206, + Name: "testdata.x206", + Tag: "bytes,206,opt,name=x206", +} + +var E_X207 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 207, + Name: "testdata.x207", + Tag: "bytes,207,opt,name=x207", +} + +var E_X208 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 208, + Name: "testdata.x208", + Tag: "bytes,208,opt,name=x208", +} + +var E_X209 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 209, + Name: "testdata.x209", + Tag: "bytes,209,opt,name=x209", +} + +var E_X210 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 210, + Name: "testdata.x210", + Tag: "bytes,210,opt,name=x210", +} + +var E_X211 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 211, + Name: "testdata.x211", + Tag: "bytes,211,opt,name=x211", +} + +var E_X212 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 212, + Name: "testdata.x212", + Tag: "bytes,212,opt,name=x212", +} + +var E_X213 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 213, + Name: "testdata.x213", + Tag: "bytes,213,opt,name=x213", +} + +var E_X214 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 214, + Name: "testdata.x214", + Tag: "bytes,214,opt,name=x214", +} + +var E_X215 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 215, + Name: "testdata.x215", + Tag: "bytes,215,opt,name=x215", +} + +var E_X216 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 216, + Name: "testdata.x216", + Tag: "bytes,216,opt,name=x216", +} + +var E_X217 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 217, + Name: "testdata.x217", + Tag: "bytes,217,opt,name=x217", +} + +var E_X218 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 218, + Name: "testdata.x218", + Tag: "bytes,218,opt,name=x218", +} + +var E_X219 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 219, + Name: "testdata.x219", + Tag: "bytes,219,opt,name=x219", +} + +var E_X220 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 220, + Name: "testdata.x220", + Tag: "bytes,220,opt,name=x220", +} + +var E_X221 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 221, + Name: "testdata.x221", + Tag: "bytes,221,opt,name=x221", +} + +var E_X222 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 222, + Name: "testdata.x222", + Tag: "bytes,222,opt,name=x222", +} + +var E_X223 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 223, + Name: "testdata.x223", + Tag: "bytes,223,opt,name=x223", +} + +var E_X224 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 224, + Name: "testdata.x224", + Tag: "bytes,224,opt,name=x224", +} + +var E_X225 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 225, + Name: "testdata.x225", + Tag: "bytes,225,opt,name=x225", +} + +var E_X226 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 226, + Name: "testdata.x226", + Tag: "bytes,226,opt,name=x226", +} + +var E_X227 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 227, + Name: "testdata.x227", + Tag: "bytes,227,opt,name=x227", +} + +var E_X228 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 228, + Name: "testdata.x228", + Tag: "bytes,228,opt,name=x228", +} + +var E_X229 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 229, + Name: "testdata.x229", + Tag: "bytes,229,opt,name=x229", +} + +var E_X230 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 230, + Name: "testdata.x230", + Tag: "bytes,230,opt,name=x230", +} + +var E_X231 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 231, + Name: "testdata.x231", + Tag: "bytes,231,opt,name=x231", +} + +var E_X232 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 232, + Name: "testdata.x232", + Tag: "bytes,232,opt,name=x232", +} + +var E_X233 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 233, + Name: "testdata.x233", + Tag: "bytes,233,opt,name=x233", +} + +var E_X234 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 234, + Name: "testdata.x234", + Tag: "bytes,234,opt,name=x234", +} + +var E_X235 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 235, + Name: "testdata.x235", + Tag: "bytes,235,opt,name=x235", +} + +var E_X236 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 236, + Name: "testdata.x236", + Tag: "bytes,236,opt,name=x236", +} + +var E_X237 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 237, + Name: "testdata.x237", + Tag: "bytes,237,opt,name=x237", +} + +var E_X238 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 238, + Name: "testdata.x238", + Tag: "bytes,238,opt,name=x238", +} + +var E_X239 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 239, + Name: "testdata.x239", + Tag: "bytes,239,opt,name=x239", +} + +var E_X240 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 240, + Name: "testdata.x240", + Tag: "bytes,240,opt,name=x240", +} + +var E_X241 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 241, + Name: "testdata.x241", + Tag: "bytes,241,opt,name=x241", +} + +var E_X242 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 242, + Name: "testdata.x242", + Tag: "bytes,242,opt,name=x242", +} + +var E_X243 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 243, + Name: "testdata.x243", + Tag: "bytes,243,opt,name=x243", +} + +var E_X244 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 244, + Name: "testdata.x244", + Tag: "bytes,244,opt,name=x244", +} + +var E_X245 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 245, + Name: "testdata.x245", + Tag: "bytes,245,opt,name=x245", +} + +var E_X246 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 246, + Name: "testdata.x246", + Tag: "bytes,246,opt,name=x246", +} + +var E_X247 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 247, + Name: "testdata.x247", + Tag: "bytes,247,opt,name=x247", +} + +var E_X248 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 248, + Name: "testdata.x248", + Tag: "bytes,248,opt,name=x248", +} + +var E_X249 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 249, + Name: "testdata.x249", + Tag: "bytes,249,opt,name=x249", +} + +var E_X250 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 250, + Name: "testdata.x250", + Tag: "bytes,250,opt,name=x250", +} + +func init() { + proto.RegisterEnum("testdata.FOO", FOO_name, FOO_value) + proto.RegisterEnum("testdata.GoTest_KIND", GoTest_KIND_name, GoTest_KIND_value) + proto.RegisterEnum("testdata.MyMessage_Color", MyMessage_Color_name, MyMessage_Color_value) + proto.RegisterEnum("testdata.DefaultsMessage_DefaultsEnum", DefaultsMessage_DefaultsEnum_name, DefaultsMessage_DefaultsEnum_value) + proto.RegisterEnum("testdata.Defaults_Color", Defaults_Color_name, Defaults_Color_value) + proto.RegisterEnum("testdata.RepeatedEnum_Color", RepeatedEnum_Color_name, RepeatedEnum_Color_value) + proto.RegisterExtension(E_Ext_More) + proto.RegisterExtension(E_Ext_Text) + proto.RegisterExtension(E_Ext_Number) + proto.RegisterExtension(E_Greeting) + proto.RegisterExtension(E_NoDefaultDouble) + proto.RegisterExtension(E_NoDefaultFloat) + proto.RegisterExtension(E_NoDefaultInt32) + proto.RegisterExtension(E_NoDefaultInt64) + proto.RegisterExtension(E_NoDefaultUint32) + proto.RegisterExtension(E_NoDefaultUint64) + proto.RegisterExtension(E_NoDefaultSint32) + proto.RegisterExtension(E_NoDefaultSint64) + proto.RegisterExtension(E_NoDefaultFixed32) + proto.RegisterExtension(E_NoDefaultFixed64) + proto.RegisterExtension(E_NoDefaultSfixed32) + proto.RegisterExtension(E_NoDefaultSfixed64) + proto.RegisterExtension(E_NoDefaultBool) + proto.RegisterExtension(E_NoDefaultString) + proto.RegisterExtension(E_NoDefaultBytes) + proto.RegisterExtension(E_NoDefaultEnum) + proto.RegisterExtension(E_DefaultDouble) + proto.RegisterExtension(E_DefaultFloat) + proto.RegisterExtension(E_DefaultInt32) + proto.RegisterExtension(E_DefaultInt64) + proto.RegisterExtension(E_DefaultUint32) + proto.RegisterExtension(E_DefaultUint64) + proto.RegisterExtension(E_DefaultSint32) + proto.RegisterExtension(E_DefaultSint64) + proto.RegisterExtension(E_DefaultFixed32) + proto.RegisterExtension(E_DefaultFixed64) + proto.RegisterExtension(E_DefaultSfixed32) + proto.RegisterExtension(E_DefaultSfixed64) + proto.RegisterExtension(E_DefaultBool) + proto.RegisterExtension(E_DefaultString) + proto.RegisterExtension(E_DefaultBytes) + proto.RegisterExtension(E_DefaultEnum) + proto.RegisterExtension(E_X201) + proto.RegisterExtension(E_X202) + proto.RegisterExtension(E_X203) + proto.RegisterExtension(E_X204) + proto.RegisterExtension(E_X205) + proto.RegisterExtension(E_X206) + proto.RegisterExtension(E_X207) + proto.RegisterExtension(E_X208) + proto.RegisterExtension(E_X209) + proto.RegisterExtension(E_X210) + proto.RegisterExtension(E_X211) + proto.RegisterExtension(E_X212) + proto.RegisterExtension(E_X213) + proto.RegisterExtension(E_X214) + proto.RegisterExtension(E_X215) + proto.RegisterExtension(E_X216) + proto.RegisterExtension(E_X217) + proto.RegisterExtension(E_X218) + proto.RegisterExtension(E_X219) + proto.RegisterExtension(E_X220) + proto.RegisterExtension(E_X221) + proto.RegisterExtension(E_X222) + proto.RegisterExtension(E_X223) + proto.RegisterExtension(E_X224) + proto.RegisterExtension(E_X225) + proto.RegisterExtension(E_X226) + proto.RegisterExtension(E_X227) + proto.RegisterExtension(E_X228) + proto.RegisterExtension(E_X229) + proto.RegisterExtension(E_X230) + proto.RegisterExtension(E_X231) + proto.RegisterExtension(E_X232) + proto.RegisterExtension(E_X233) + proto.RegisterExtension(E_X234) + proto.RegisterExtension(E_X235) + proto.RegisterExtension(E_X236) + proto.RegisterExtension(E_X237) + proto.RegisterExtension(E_X238) + proto.RegisterExtension(E_X239) + proto.RegisterExtension(E_X240) + proto.RegisterExtension(E_X241) + proto.RegisterExtension(E_X242) + proto.RegisterExtension(E_X243) + proto.RegisterExtension(E_X244) + proto.RegisterExtension(E_X245) + proto.RegisterExtension(E_X246) + proto.RegisterExtension(E_X247) + proto.RegisterExtension(E_X248) + proto.RegisterExtension(E_X249) + proto.RegisterExtension(E_X250) +} diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.pb.go.golden b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.pb.go.golden new file mode 100644 index 000000000000..0387853d56c6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.pb.go.golden @@ -0,0 +1,1737 @@ +// Code generated by protoc-gen-gogo. +// source: test.proto +// DO NOT EDIT! + +package testdata + +import proto "github.com/gogo/protobuf/proto" +import json "encoding/json" +import math "math" + +import () + +// Reference proto, json, and math imports to suppress error if they are not otherwise used. +var _ = proto.Marshal +var _ = &json.SyntaxError{} +var _ = math.Inf + +type FOO int32 + +const ( + FOO_FOO1 FOO = 1 +) + +var FOO_name = map[int32]string{ + 1: "FOO1", +} +var FOO_value = map[string]int32{ + "FOO1": 1, +} + +func (x FOO) Enum() *FOO { + p := new(FOO) + *p = x + return p +} +func (x FOO) String() string { + return proto.EnumName(FOO_name, int32(x)) +} +func (x FOO) MarshalJSON() ([]byte, error) { + return json.Marshal(x.String()) +} +func (x *FOO) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FOO_value, data, "FOO") + if err != nil { + return err + } + *x = FOO(value) + return nil +} + +type GoTest_KIND int32 + +const ( + GoTest_VOID GoTest_KIND = 0 + GoTest_BOOL GoTest_KIND = 1 + GoTest_BYTES GoTest_KIND = 2 + GoTest_FINGERPRINT GoTest_KIND = 3 + GoTest_FLOAT GoTest_KIND = 4 + GoTest_INT GoTest_KIND = 5 + GoTest_STRING GoTest_KIND = 6 + GoTest_TIME GoTest_KIND = 7 + GoTest_TUPLE GoTest_KIND = 8 + GoTest_ARRAY GoTest_KIND = 9 + GoTest_MAP GoTest_KIND = 10 + GoTest_TABLE GoTest_KIND = 11 + GoTest_FUNCTION GoTest_KIND = 12 +) + +var GoTest_KIND_name = map[int32]string{ + 0: "VOID", + 1: "BOOL", + 2: "BYTES", + 3: "FINGERPRINT", + 4: "FLOAT", + 5: "INT", + 6: "STRING", + 7: "TIME", + 8: "TUPLE", + 9: "ARRAY", + 10: "MAP", + 11: "TABLE", + 12: "FUNCTION", +} +var GoTest_KIND_value = map[string]int32{ + "VOID": 0, + "BOOL": 1, + "BYTES": 2, + "FINGERPRINT": 3, + "FLOAT": 4, + "INT": 5, + "STRING": 6, + "TIME": 7, + "TUPLE": 8, + "ARRAY": 9, + "MAP": 10, + "TABLE": 11, + "FUNCTION": 12, +} + +func (x GoTest_KIND) Enum() *GoTest_KIND { + p := new(GoTest_KIND) + *p = x + return p +} +func (x GoTest_KIND) String() string { + return proto.EnumName(GoTest_KIND_name, int32(x)) +} +func (x GoTest_KIND) MarshalJSON() ([]byte, error) { + return json.Marshal(x.String()) +} +func (x *GoTest_KIND) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(GoTest_KIND_value, data, "GoTest_KIND") + if err != nil { + return err + } + *x = GoTest_KIND(value) + return nil +} + +type MyMessage_Color int32 + +const ( + MyMessage_RED MyMessage_Color = 0 + MyMessage_GREEN MyMessage_Color = 1 + MyMessage_BLUE MyMessage_Color = 2 +) + +var MyMessage_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} +var MyMessage_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x MyMessage_Color) Enum() *MyMessage_Color { + p := new(MyMessage_Color) + *p = x + return p +} +func (x MyMessage_Color) String() string { + return proto.EnumName(MyMessage_Color_name, int32(x)) +} +func (x MyMessage_Color) MarshalJSON() ([]byte, error) { + return json.Marshal(x.String()) +} +func (x *MyMessage_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(MyMessage_Color_value, data, "MyMessage_Color") + if err != nil { + return err + } + *x = MyMessage_Color(value) + return nil +} + +type Defaults_Color int32 + +const ( + Defaults_RED Defaults_Color = 0 + Defaults_GREEN Defaults_Color = 1 + Defaults_BLUE Defaults_Color = 2 +) + +var Defaults_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} +var Defaults_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x Defaults_Color) Enum() *Defaults_Color { + p := new(Defaults_Color) + *p = x + return p +} +func (x Defaults_Color) String() string { + return proto.EnumName(Defaults_Color_name, int32(x)) +} +func (x Defaults_Color) MarshalJSON() ([]byte, error) { + return json.Marshal(x.String()) +} +func (x *Defaults_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Defaults_Color_value, data, "Defaults_Color") + if err != nil { + return err + } + *x = Defaults_Color(value) + return nil +} + +type RepeatedEnum_Color int32 + +const ( + RepeatedEnum_RED RepeatedEnum_Color = 1 +) + +var RepeatedEnum_Color_name = map[int32]string{ + 1: "RED", +} +var RepeatedEnum_Color_value = map[string]int32{ + "RED": 1, +} + +func (x RepeatedEnum_Color) Enum() *RepeatedEnum_Color { + p := new(RepeatedEnum_Color) + *p = x + return p +} +func (x RepeatedEnum_Color) String() string { + return proto.EnumName(RepeatedEnum_Color_name, int32(x)) +} +func (x RepeatedEnum_Color) MarshalJSON() ([]byte, error) { + return json.Marshal(x.String()) +} +func (x *RepeatedEnum_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(RepeatedEnum_Color_value, data, "RepeatedEnum_Color") + if err != nil { + return err + } + *x = RepeatedEnum_Color(value) + return nil +} + +type GoEnum struct { + Foo *FOO `protobuf:"varint,1,req,name=foo,enum=testdata.FOO" json:"foo,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoEnum) Reset() { *m = GoEnum{} } +func (m *GoEnum) String() string { return proto.CompactTextString(m) } +func (*GoEnum) ProtoMessage() {} + +func (m *GoEnum) GetFoo() FOO { + if m != nil && m.Foo != nil { + return *m.Foo + } + return 0 +} + +type GoTestField struct { + Label *string `protobuf:"bytes,1,req" json:"Label,omitempty"` + Type *string `protobuf:"bytes,2,req" json:"Type,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTestField) Reset() { *m = GoTestField{} } +func (m *GoTestField) String() string { return proto.CompactTextString(m) } +func (*GoTestField) ProtoMessage() {} + +func (m *GoTestField) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *GoTestField) GetType() string { + if m != nil && m.Type != nil { + return *m.Type + } + return "" +} + +type GoTest struct { + Kind *GoTest_KIND `protobuf:"varint,1,req,enum=testdata.GoTest_KIND" json:"Kind,omitempty"` + Table *string `protobuf:"bytes,2,opt" json:"Table,omitempty"` + Param *int32 `protobuf:"varint,3,opt" json:"Param,omitempty"` + RequiredField *GoTestField `protobuf:"bytes,4,req" json:"RequiredField,omitempty"` + RepeatedField []*GoTestField `protobuf:"bytes,5,rep" json:"RepeatedField,omitempty"` + OptionalField *GoTestField `protobuf:"bytes,6,opt" json:"OptionalField,omitempty"` + F_BoolRequired *bool `protobuf:"varint,10,req,name=F_Bool_required" json:"F_Bool_required,omitempty"` + F_Int32Required *int32 `protobuf:"varint,11,req,name=F_Int32_required" json:"F_Int32_required,omitempty"` + F_Int64Required *int64 `protobuf:"varint,12,req,name=F_Int64_required" json:"F_Int64_required,omitempty"` + F_Fixed32Required *uint32 `protobuf:"fixed32,13,req,name=F_Fixed32_required" json:"F_Fixed32_required,omitempty"` + F_Fixed64Required *uint64 `protobuf:"fixed64,14,req,name=F_Fixed64_required" json:"F_Fixed64_required,omitempty"` + F_Uint32Required *uint32 `protobuf:"varint,15,req,name=F_Uint32_required" json:"F_Uint32_required,omitempty"` + F_Uint64Required *uint64 `protobuf:"varint,16,req,name=F_Uint64_required" json:"F_Uint64_required,omitempty"` + F_FloatRequired *float32 `protobuf:"fixed32,17,req,name=F_Float_required" json:"F_Float_required,omitempty"` + F_DoubleRequired *float64 `protobuf:"fixed64,18,req,name=F_Double_required" json:"F_Double_required,omitempty"` + F_StringRequired *string `protobuf:"bytes,19,req,name=F_String_required" json:"F_String_required,omitempty"` + F_BytesRequired []byte `protobuf:"bytes,101,req,name=F_Bytes_required" json:"F_Bytes_required,omitempty"` + F_Sint32Required *int32 `protobuf:"zigzag32,102,req,name=F_Sint32_required" json:"F_Sint32_required,omitempty"` + F_Sint64Required *int64 `protobuf:"zigzag64,103,req,name=F_Sint64_required" json:"F_Sint64_required,omitempty"` + F_BoolRepeated []bool `protobuf:"varint,20,rep,name=F_Bool_repeated" json:"F_Bool_repeated,omitempty"` + F_Int32Repeated []int32 `protobuf:"varint,21,rep,name=F_Int32_repeated" json:"F_Int32_repeated,omitempty"` + F_Int64Repeated []int64 `protobuf:"varint,22,rep,name=F_Int64_repeated" json:"F_Int64_repeated,omitempty"` + F_Fixed32Repeated []uint32 `protobuf:"fixed32,23,rep,name=F_Fixed32_repeated" json:"F_Fixed32_repeated,omitempty"` + F_Fixed64Repeated []uint64 `protobuf:"fixed64,24,rep,name=F_Fixed64_repeated" json:"F_Fixed64_repeated,omitempty"` + F_Uint32Repeated []uint32 `protobuf:"varint,25,rep,name=F_Uint32_repeated" json:"F_Uint32_repeated,omitempty"` + F_Uint64Repeated []uint64 `protobuf:"varint,26,rep,name=F_Uint64_repeated" json:"F_Uint64_repeated,omitempty"` + F_FloatRepeated []float32 `protobuf:"fixed32,27,rep,name=F_Float_repeated" json:"F_Float_repeated,omitempty"` + F_DoubleRepeated []float64 `protobuf:"fixed64,28,rep,name=F_Double_repeated" json:"F_Double_repeated,omitempty"` + F_StringRepeated []string `protobuf:"bytes,29,rep,name=F_String_repeated" json:"F_String_repeated,omitempty"` + F_BytesRepeated [][]byte `protobuf:"bytes,201,rep,name=F_Bytes_repeated" json:"F_Bytes_repeated,omitempty"` + F_Sint32Repeated []int32 `protobuf:"zigzag32,202,rep,name=F_Sint32_repeated" json:"F_Sint32_repeated,omitempty"` + F_Sint64Repeated []int64 `protobuf:"zigzag64,203,rep,name=F_Sint64_repeated" json:"F_Sint64_repeated,omitempty"` + F_BoolOptional *bool `protobuf:"varint,30,opt,name=F_Bool_optional" json:"F_Bool_optional,omitempty"` + F_Int32Optional *int32 `protobuf:"varint,31,opt,name=F_Int32_optional" json:"F_Int32_optional,omitempty"` + F_Int64Optional *int64 `protobuf:"varint,32,opt,name=F_Int64_optional" json:"F_Int64_optional,omitempty"` + F_Fixed32Optional *uint32 `protobuf:"fixed32,33,opt,name=F_Fixed32_optional" json:"F_Fixed32_optional,omitempty"` + F_Fixed64Optional *uint64 `protobuf:"fixed64,34,opt,name=F_Fixed64_optional" json:"F_Fixed64_optional,omitempty"` + F_Uint32Optional *uint32 `protobuf:"varint,35,opt,name=F_Uint32_optional" json:"F_Uint32_optional,omitempty"` + F_Uint64Optional *uint64 `protobuf:"varint,36,opt,name=F_Uint64_optional" json:"F_Uint64_optional,omitempty"` + F_FloatOptional *float32 `protobuf:"fixed32,37,opt,name=F_Float_optional" json:"F_Float_optional,omitempty"` + F_DoubleOptional *float64 `protobuf:"fixed64,38,opt,name=F_Double_optional" json:"F_Double_optional,omitempty"` + F_StringOptional *string `protobuf:"bytes,39,opt,name=F_String_optional" json:"F_String_optional,omitempty"` + F_BytesOptional []byte `protobuf:"bytes,301,opt,name=F_Bytes_optional" json:"F_Bytes_optional,omitempty"` + F_Sint32Optional *int32 `protobuf:"zigzag32,302,opt,name=F_Sint32_optional" json:"F_Sint32_optional,omitempty"` + F_Sint64Optional *int64 `protobuf:"zigzag64,303,opt,name=F_Sint64_optional" json:"F_Sint64_optional,omitempty"` + F_BoolDefaulted *bool `protobuf:"varint,40,opt,name=F_Bool_defaulted,def=1" json:"F_Bool_defaulted,omitempty"` + F_Int32Defaulted *int32 `protobuf:"varint,41,opt,name=F_Int32_defaulted,def=32" json:"F_Int32_defaulted,omitempty"` + F_Int64Defaulted *int64 `protobuf:"varint,42,opt,name=F_Int64_defaulted,def=64" json:"F_Int64_defaulted,omitempty"` + F_Fixed32Defaulted *uint32 `protobuf:"fixed32,43,opt,name=F_Fixed32_defaulted,def=320" json:"F_Fixed32_defaulted,omitempty"` + F_Fixed64Defaulted *uint64 `protobuf:"fixed64,44,opt,name=F_Fixed64_defaulted,def=640" json:"F_Fixed64_defaulted,omitempty"` + F_Uint32Defaulted *uint32 `protobuf:"varint,45,opt,name=F_Uint32_defaulted,def=3200" json:"F_Uint32_defaulted,omitempty"` + F_Uint64Defaulted *uint64 `protobuf:"varint,46,opt,name=F_Uint64_defaulted,def=6400" json:"F_Uint64_defaulted,omitempty"` + F_FloatDefaulted *float32 `protobuf:"fixed32,47,opt,name=F_Float_defaulted,def=314159" json:"F_Float_defaulted,omitempty"` + F_DoubleDefaulted *float64 `protobuf:"fixed64,48,opt,name=F_Double_defaulted,def=271828" json:"F_Double_defaulted,omitempty"` + F_StringDefaulted *string `protobuf:"bytes,49,opt,name=F_String_defaulted,def=hello, \"world!\"\n" json:"F_String_defaulted,omitempty"` + F_BytesDefaulted []byte `protobuf:"bytes,401,opt,name=F_Bytes_defaulted,def=Bignose" json:"F_Bytes_defaulted,omitempty"` + F_Sint32Defaulted *int32 `protobuf:"zigzag32,402,opt,name=F_Sint32_defaulted,def=-32" json:"F_Sint32_defaulted,omitempty"` + F_Sint64Defaulted *int64 `protobuf:"zigzag64,403,opt,name=F_Sint64_defaulted,def=-64" json:"F_Sint64_defaulted,omitempty"` + F_BoolRepeatedPacked []bool `protobuf:"varint,50,rep,packed,name=F_Bool_repeated_packed" json:"F_Bool_repeated_packed,omitempty"` + F_Int32RepeatedPacked []int32 `protobuf:"varint,51,rep,packed,name=F_Int32_repeated_packed" json:"F_Int32_repeated_packed,omitempty"` + F_Int64RepeatedPacked []int64 `protobuf:"varint,52,rep,packed,name=F_Int64_repeated_packed" json:"F_Int64_repeated_packed,omitempty"` + F_Fixed32RepeatedPacked []uint32 `protobuf:"fixed32,53,rep,packed,name=F_Fixed32_repeated_packed" json:"F_Fixed32_repeated_packed,omitempty"` + F_Fixed64RepeatedPacked []uint64 `protobuf:"fixed64,54,rep,packed,name=F_Fixed64_repeated_packed" json:"F_Fixed64_repeated_packed,omitempty"` + F_Uint32RepeatedPacked []uint32 `protobuf:"varint,55,rep,packed,name=F_Uint32_repeated_packed" json:"F_Uint32_repeated_packed,omitempty"` + F_Uint64RepeatedPacked []uint64 `protobuf:"varint,56,rep,packed,name=F_Uint64_repeated_packed" json:"F_Uint64_repeated_packed,omitempty"` + F_FloatRepeatedPacked []float32 `protobuf:"fixed32,57,rep,packed,name=F_Float_repeated_packed" json:"F_Float_repeated_packed,omitempty"` + F_DoubleRepeatedPacked []float64 `protobuf:"fixed64,58,rep,packed,name=F_Double_repeated_packed" json:"F_Double_repeated_packed,omitempty"` + F_Sint32RepeatedPacked []int32 `protobuf:"zigzag32,502,rep,packed,name=F_Sint32_repeated_packed" json:"F_Sint32_repeated_packed,omitempty"` + F_Sint64RepeatedPacked []int64 `protobuf:"zigzag64,503,rep,packed,name=F_Sint64_repeated_packed" json:"F_Sint64_repeated_packed,omitempty"` + Requiredgroup *GoTest_RequiredGroup `protobuf:"group,70,req,name=RequiredGroup" json:"requiredgroup,omitempty"` + Repeatedgroup []*GoTest_RepeatedGroup `protobuf:"group,80,rep,name=RepeatedGroup" json:"repeatedgroup,omitempty"` + Optionalgroup *GoTest_OptionalGroup `protobuf:"group,90,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest) Reset() { *m = GoTest{} } +func (m *GoTest) String() string { return proto.CompactTextString(m) } +func (*GoTest) ProtoMessage() {} + +const Default_GoTest_F_BoolDefaulted bool = true +const Default_GoTest_F_Int32Defaulted int32 = 32 +const Default_GoTest_F_Int64Defaulted int64 = 64 +const Default_GoTest_F_Fixed32Defaulted uint32 = 320 +const Default_GoTest_F_Fixed64Defaulted uint64 = 640 +const Default_GoTest_F_Uint32Defaulted uint32 = 3200 +const Default_GoTest_F_Uint64Defaulted uint64 = 6400 +const Default_GoTest_F_FloatDefaulted float32 = 314159 +const Default_GoTest_F_DoubleDefaulted float64 = 271828 +const Default_GoTest_F_StringDefaulted string = "hello, \"world!\"\n" + +var Default_GoTest_F_BytesDefaulted []byte = []byte("Bignose") + +const Default_GoTest_F_Sint32Defaulted int32 = -32 +const Default_GoTest_F_Sint64Defaulted int64 = -64 + +func (m *GoTest) GetKind() GoTest_KIND { + if m != nil && m.Kind != nil { + return *m.Kind + } + return 0 +} + +func (m *GoTest) GetTable() string { + if m != nil && m.Table != nil { + return *m.Table + } + return "" +} + +func (m *GoTest) GetParam() int32 { + if m != nil && m.Param != nil { + return *m.Param + } + return 0 +} + +func (m *GoTest) GetRequiredField() *GoTestField { + if m != nil { + return m.RequiredField + } + return nil +} + +func (m *GoTest) GetRepeatedField() []*GoTestField { + if m != nil { + return m.RepeatedField + } + return nil +} + +func (m *GoTest) GetOptionalField() *GoTestField { + if m != nil { + return m.OptionalField + } + return nil +} + +func (m *GoTest) GetF_BoolRequired() bool { + if m != nil && m.F_BoolRequired != nil { + return *m.F_BoolRequired + } + return false +} + +func (m *GoTest) GetF_Int32Required() int32 { + if m != nil && m.F_Int32Required != nil { + return *m.F_Int32Required + } + return 0 +} + +func (m *GoTest) GetF_Int64Required() int64 { + if m != nil && m.F_Int64Required != nil { + return *m.F_Int64Required + } + return 0 +} + +func (m *GoTest) GetF_Fixed32Required() uint32 { + if m != nil && m.F_Fixed32Required != nil { + return *m.F_Fixed32Required + } + return 0 +} + +func (m *GoTest) GetF_Fixed64Required() uint64 { + if m != nil && m.F_Fixed64Required != nil { + return *m.F_Fixed64Required + } + return 0 +} + +func (m *GoTest) GetF_Uint32Required() uint32 { + if m != nil && m.F_Uint32Required != nil { + return *m.F_Uint32Required + } + return 0 +} + +func (m *GoTest) GetF_Uint64Required() uint64 { + if m != nil && m.F_Uint64Required != nil { + return *m.F_Uint64Required + } + return 0 +} + +func (m *GoTest) GetF_FloatRequired() float32 { + if m != nil && m.F_FloatRequired != nil { + return *m.F_FloatRequired + } + return 0 +} + +func (m *GoTest) GetF_DoubleRequired() float64 { + if m != nil && m.F_DoubleRequired != nil { + return *m.F_DoubleRequired + } + return 0 +} + +func (m *GoTest) GetF_StringRequired() string { + if m != nil && m.F_StringRequired != nil { + return *m.F_StringRequired + } + return "" +} + +func (m *GoTest) GetF_BytesRequired() []byte { + if m != nil { + return m.F_BytesRequired + } + return nil +} + +func (m *GoTest) GetF_Sint32Required() int32 { + if m != nil && m.F_Sint32Required != nil { + return *m.F_Sint32Required + } + return 0 +} + +func (m *GoTest) GetF_Sint64Required() int64 { + if m != nil && m.F_Sint64Required != nil { + return *m.F_Sint64Required + } + return 0 +} + +func (m *GoTest) GetF_BoolRepeated() []bool { + if m != nil { + return m.F_BoolRepeated + } + return nil +} + +func (m *GoTest) GetF_Int32Repeated() []int32 { + if m != nil { + return m.F_Int32Repeated + } + return nil +} + +func (m *GoTest) GetF_Int64Repeated() []int64 { + if m != nil { + return m.F_Int64Repeated + } + return nil +} + +func (m *GoTest) GetF_Fixed32Repeated() []uint32 { + if m != nil { + return m.F_Fixed32Repeated + } + return nil +} + +func (m *GoTest) GetF_Fixed64Repeated() []uint64 { + if m != nil { + return m.F_Fixed64Repeated + } + return nil +} + +func (m *GoTest) GetF_Uint32Repeated() []uint32 { + if m != nil { + return m.F_Uint32Repeated + } + return nil +} + +func (m *GoTest) GetF_Uint64Repeated() []uint64 { + if m != nil { + return m.F_Uint64Repeated + } + return nil +} + +func (m *GoTest) GetF_FloatRepeated() []float32 { + if m != nil { + return m.F_FloatRepeated + } + return nil +} + +func (m *GoTest) GetF_DoubleRepeated() []float64 { + if m != nil { + return m.F_DoubleRepeated + } + return nil +} + +func (m *GoTest) GetF_StringRepeated() []string { + if m != nil { + return m.F_StringRepeated + } + return nil +} + +func (m *GoTest) GetF_BytesRepeated() [][]byte { + if m != nil { + return m.F_BytesRepeated + } + return nil +} + +func (m *GoTest) GetF_Sint32Repeated() []int32 { + if m != nil { + return m.F_Sint32Repeated + } + return nil +} + +func (m *GoTest) GetF_Sint64Repeated() []int64 { + if m != nil { + return m.F_Sint64Repeated + } + return nil +} + +func (m *GoTest) GetF_BoolOptional() bool { + if m != nil && m.F_BoolOptional != nil { + return *m.F_BoolOptional + } + return false +} + +func (m *GoTest) GetF_Int32Optional() int32 { + if m != nil && m.F_Int32Optional != nil { + return *m.F_Int32Optional + } + return 0 +} + +func (m *GoTest) GetF_Int64Optional() int64 { + if m != nil && m.F_Int64Optional != nil { + return *m.F_Int64Optional + } + return 0 +} + +func (m *GoTest) GetF_Fixed32Optional() uint32 { + if m != nil && m.F_Fixed32Optional != nil { + return *m.F_Fixed32Optional + } + return 0 +} + +func (m *GoTest) GetF_Fixed64Optional() uint64 { + if m != nil && m.F_Fixed64Optional != nil { + return *m.F_Fixed64Optional + } + return 0 +} + +func (m *GoTest) GetF_Uint32Optional() uint32 { + if m != nil && m.F_Uint32Optional != nil { + return *m.F_Uint32Optional + } + return 0 +} + +func (m *GoTest) GetF_Uint64Optional() uint64 { + if m != nil && m.F_Uint64Optional != nil { + return *m.F_Uint64Optional + } + return 0 +} + +func (m *GoTest) GetF_FloatOptional() float32 { + if m != nil && m.F_FloatOptional != nil { + return *m.F_FloatOptional + } + return 0 +} + +func (m *GoTest) GetF_DoubleOptional() float64 { + if m != nil && m.F_DoubleOptional != nil { + return *m.F_DoubleOptional + } + return 0 +} + +func (m *GoTest) GetF_StringOptional() string { + if m != nil && m.F_StringOptional != nil { + return *m.F_StringOptional + } + return "" +} + +func (m *GoTest) GetF_BytesOptional() []byte { + if m != nil { + return m.F_BytesOptional + } + return nil +} + +func (m *GoTest) GetF_Sint32Optional() int32 { + if m != nil && m.F_Sint32Optional != nil { + return *m.F_Sint32Optional + } + return 0 +} + +func (m *GoTest) GetF_Sint64Optional() int64 { + if m != nil && m.F_Sint64Optional != nil { + return *m.F_Sint64Optional + } + return 0 +} + +func (m *GoTest) GetF_BoolDefaulted() bool { + if m != nil && m.F_BoolDefaulted != nil { + return *m.F_BoolDefaulted + } + return Default_GoTest_F_BoolDefaulted +} + +func (m *GoTest) GetF_Int32Defaulted() int32 { + if m != nil && m.F_Int32Defaulted != nil { + return *m.F_Int32Defaulted + } + return Default_GoTest_F_Int32Defaulted +} + +func (m *GoTest) GetF_Int64Defaulted() int64 { + if m != nil && m.F_Int64Defaulted != nil { + return *m.F_Int64Defaulted + } + return Default_GoTest_F_Int64Defaulted +} + +func (m *GoTest) GetF_Fixed32Defaulted() uint32 { + if m != nil && m.F_Fixed32Defaulted != nil { + return *m.F_Fixed32Defaulted + } + return Default_GoTest_F_Fixed32Defaulted +} + +func (m *GoTest) GetF_Fixed64Defaulted() uint64 { + if m != nil && m.F_Fixed64Defaulted != nil { + return *m.F_Fixed64Defaulted + } + return Default_GoTest_F_Fixed64Defaulted +} + +func (m *GoTest) GetF_Uint32Defaulted() uint32 { + if m != nil && m.F_Uint32Defaulted != nil { + return *m.F_Uint32Defaulted + } + return Default_GoTest_F_Uint32Defaulted +} + +func (m *GoTest) GetF_Uint64Defaulted() uint64 { + if m != nil && m.F_Uint64Defaulted != nil { + return *m.F_Uint64Defaulted + } + return Default_GoTest_F_Uint64Defaulted +} + +func (m *GoTest) GetF_FloatDefaulted() float32 { + if m != nil && m.F_FloatDefaulted != nil { + return *m.F_FloatDefaulted + } + return Default_GoTest_F_FloatDefaulted +} + +func (m *GoTest) GetF_DoubleDefaulted() float64 { + if m != nil && m.F_DoubleDefaulted != nil { + return *m.F_DoubleDefaulted + } + return Default_GoTest_F_DoubleDefaulted +} + +func (m *GoTest) GetF_StringDefaulted() string { + if m != nil && m.F_StringDefaulted != nil { + return *m.F_StringDefaulted + } + return Default_GoTest_F_StringDefaulted +} + +func (m *GoTest) GetF_BytesDefaulted() []byte { + if m != nil && m.F_BytesDefaulted != nil { + return m.F_BytesDefaulted + } + return append([]byte(nil), Default_GoTest_F_BytesDefaulted...) +} + +func (m *GoTest) GetF_Sint32Defaulted() int32 { + if m != nil && m.F_Sint32Defaulted != nil { + return *m.F_Sint32Defaulted + } + return Default_GoTest_F_Sint32Defaulted +} + +func (m *GoTest) GetF_Sint64Defaulted() int64 { + if m != nil && m.F_Sint64Defaulted != nil { + return *m.F_Sint64Defaulted + } + return Default_GoTest_F_Sint64Defaulted +} + +func (m *GoTest) GetF_BoolRepeatedPacked() []bool { + if m != nil { + return m.F_BoolRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Int32RepeatedPacked() []int32 { + if m != nil { + return m.F_Int32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Int64RepeatedPacked() []int64 { + if m != nil { + return m.F_Int64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Fixed32RepeatedPacked() []uint32 { + if m != nil { + return m.F_Fixed32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Fixed64RepeatedPacked() []uint64 { + if m != nil { + return m.F_Fixed64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Uint32RepeatedPacked() []uint32 { + if m != nil { + return m.F_Uint32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Uint64RepeatedPacked() []uint64 { + if m != nil { + return m.F_Uint64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_FloatRepeatedPacked() []float32 { + if m != nil { + return m.F_FloatRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_DoubleRepeatedPacked() []float64 { + if m != nil { + return m.F_DoubleRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Sint32RepeatedPacked() []int32 { + if m != nil { + return m.F_Sint32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Sint64RepeatedPacked() []int64 { + if m != nil { + return m.F_Sint64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetRequiredgroup() *GoTest_RequiredGroup { + if m != nil { + return m.Requiredgroup + } + return nil +} + +func (m *GoTest) GetRepeatedgroup() []*GoTest_RepeatedGroup { + if m != nil { + return m.Repeatedgroup + } + return nil +} + +func (m *GoTest) GetOptionalgroup() *GoTest_OptionalGroup { + if m != nil { + return m.Optionalgroup + } + return nil +} + +type GoTest_RequiredGroup struct { + RequiredField *string `protobuf:"bytes,71,req" json:"RequiredField,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest_RequiredGroup) Reset() { *m = GoTest_RequiredGroup{} } + +func (m *GoTest_RequiredGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +type GoTest_RepeatedGroup struct { + RequiredField *string `protobuf:"bytes,81,req" json:"RequiredField,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest_RepeatedGroup) Reset() { *m = GoTest_RepeatedGroup{} } + +func (m *GoTest_RepeatedGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +type GoTest_OptionalGroup struct { + RequiredField *string `protobuf:"bytes,91,req" json:"RequiredField,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest_OptionalGroup) Reset() { *m = GoTest_OptionalGroup{} } + +func (m *GoTest_OptionalGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +type GoSkipTest struct { + SkipInt32 *int32 `protobuf:"varint,11,req,name=skip_int32" json:"skip_int32,omitempty"` + SkipFixed32 *uint32 `protobuf:"fixed32,12,req,name=skip_fixed32" json:"skip_fixed32,omitempty"` + SkipFixed64 *uint64 `protobuf:"fixed64,13,req,name=skip_fixed64" json:"skip_fixed64,omitempty"` + SkipString *string `protobuf:"bytes,14,req,name=skip_string" json:"skip_string,omitempty"` + Skipgroup *GoSkipTest_SkipGroup `protobuf:"group,15,req,name=SkipGroup" json:"skipgroup,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoSkipTest) Reset() { *m = GoSkipTest{} } +func (m *GoSkipTest) String() string { return proto.CompactTextString(m) } +func (*GoSkipTest) ProtoMessage() {} + +func (m *GoSkipTest) GetSkipInt32() int32 { + if m != nil && m.SkipInt32 != nil { + return *m.SkipInt32 + } + return 0 +} + +func (m *GoSkipTest) GetSkipFixed32() uint32 { + if m != nil && m.SkipFixed32 != nil { + return *m.SkipFixed32 + } + return 0 +} + +func (m *GoSkipTest) GetSkipFixed64() uint64 { + if m != nil && m.SkipFixed64 != nil { + return *m.SkipFixed64 + } + return 0 +} + +func (m *GoSkipTest) GetSkipString() string { + if m != nil && m.SkipString != nil { + return *m.SkipString + } + return "" +} + +func (m *GoSkipTest) GetSkipgroup() *GoSkipTest_SkipGroup { + if m != nil { + return m.Skipgroup + } + return nil +} + +type GoSkipTest_SkipGroup struct { + GroupInt32 *int32 `protobuf:"varint,16,req,name=group_int32" json:"group_int32,omitempty"` + GroupString *string `protobuf:"bytes,17,req,name=group_string" json:"group_string,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoSkipTest_SkipGroup) Reset() { *m = GoSkipTest_SkipGroup{} } + +func (m *GoSkipTest_SkipGroup) GetGroupInt32() int32 { + if m != nil && m.GroupInt32 != nil { + return *m.GroupInt32 + } + return 0 +} + +func (m *GoSkipTest_SkipGroup) GetGroupString() string { + if m != nil && m.GroupString != nil { + return *m.GroupString + } + return "" +} + +type NonPackedTest struct { + A []int32 `protobuf:"varint,1,rep,name=a" json:"a,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NonPackedTest) Reset() { *m = NonPackedTest{} } +func (m *NonPackedTest) String() string { return proto.CompactTextString(m) } +func (*NonPackedTest) ProtoMessage() {} + +func (m *NonPackedTest) GetA() []int32 { + if m != nil { + return m.A + } + return nil +} + +type PackedTest struct { + B []int32 `protobuf:"varint,1,rep,packed,name=b" json:"b,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *PackedTest) Reset() { *m = PackedTest{} } +func (m *PackedTest) String() string { return proto.CompactTextString(m) } +func (*PackedTest) ProtoMessage() {} + +func (m *PackedTest) GetB() []int32 { + if m != nil { + return m.B + } + return nil +} + +type MaxTag struct { + LastField *string `protobuf:"bytes,536870911,opt,name=last_field" json:"last_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MaxTag) Reset() { *m = MaxTag{} } +func (m *MaxTag) String() string { return proto.CompactTextString(m) } +func (*MaxTag) ProtoMessage() {} + +func (m *MaxTag) GetLastField() string { + if m != nil && m.LastField != nil { + return *m.LastField + } + return "" +} + +type OldMessage struct { + Nested *OldMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OldMessage) Reset() { *m = OldMessage{} } +func (m *OldMessage) String() string { return proto.CompactTextString(m) } +func (*OldMessage) ProtoMessage() {} + +func (m *OldMessage) GetNested() *OldMessage_Nested { + if m != nil { + return m.Nested + } + return nil +} + +type OldMessage_Nested struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OldMessage_Nested) Reset() { *m = OldMessage_Nested{} } +func (m *OldMessage_Nested) String() string { return proto.CompactTextString(m) } +func (*OldMessage_Nested) ProtoMessage() {} + +func (m *OldMessage_Nested) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +type NewMessage struct { + Nested *NewMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NewMessage) Reset() { *m = NewMessage{} } +func (m *NewMessage) String() string { return proto.CompactTextString(m) } +func (*NewMessage) ProtoMessage() {} + +func (m *NewMessage) GetNested() *NewMessage_Nested { + if m != nil { + return m.Nested + } + return nil +} + +type NewMessage_Nested struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + FoodGroup *string `protobuf:"bytes,2,opt,name=food_group" json:"food_group,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NewMessage_Nested) Reset() { *m = NewMessage_Nested{} } +func (m *NewMessage_Nested) String() string { return proto.CompactTextString(m) } +func (*NewMessage_Nested) ProtoMessage() {} + +func (m *NewMessage_Nested) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *NewMessage_Nested) GetFoodGroup() string { + if m != nil && m.FoodGroup != nil { + return *m.FoodGroup + } + return "" +} + +type InnerMessage struct { + Host *string `protobuf:"bytes,1,req,name=host" json:"host,omitempty"` + Port *int32 `protobuf:"varint,2,opt,name=port,def=4000" json:"port,omitempty"` + Connected *bool `protobuf:"varint,3,opt,name=connected" json:"connected,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *InnerMessage) Reset() { *m = InnerMessage{} } +func (m *InnerMessage) String() string { return proto.CompactTextString(m) } +func (*InnerMessage) ProtoMessage() {} + +const Default_InnerMessage_Port int32 = 4000 + +func (m *InnerMessage) GetHost() string { + if m != nil && m.Host != nil { + return *m.Host + } + return "" +} + +func (m *InnerMessage) GetPort() int32 { + if m != nil && m.Port != nil { + return *m.Port + } + return Default_InnerMessage_Port +} + +func (m *InnerMessage) GetConnected() bool { + if m != nil && m.Connected != nil { + return *m.Connected + } + return false +} + +type OtherMessage struct { + Key *int64 `protobuf:"varint,1,opt,name=key" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` + Weight *float32 `protobuf:"fixed32,3,opt,name=weight" json:"weight,omitempty"` + Inner *InnerMessage `protobuf:"bytes,4,opt,name=inner" json:"inner,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OtherMessage) Reset() { *m = OtherMessage{} } +func (m *OtherMessage) String() string { return proto.CompactTextString(m) } +func (*OtherMessage) ProtoMessage() {} + +func (m *OtherMessage) GetKey() int64 { + if m != nil && m.Key != nil { + return *m.Key + } + return 0 +} + +func (m *OtherMessage) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *OtherMessage) GetWeight() float32 { + if m != nil && m.Weight != nil { + return *m.Weight + } + return 0 +} + +func (m *OtherMessage) GetInner() *InnerMessage { + if m != nil { + return m.Inner + } + return nil +} + +type MyMessage struct { + Count *int32 `protobuf:"varint,1,req,name=count" json:"count,omitempty"` + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + Quote *string `protobuf:"bytes,3,opt,name=quote" json:"quote,omitempty"` + Pet []string `protobuf:"bytes,4,rep,name=pet" json:"pet,omitempty"` + Inner *InnerMessage `protobuf:"bytes,5,opt,name=inner" json:"inner,omitempty"` + Others []*OtherMessage `protobuf:"bytes,6,rep,name=others" json:"others,omitempty"` + Bikeshed *MyMessage_Color `protobuf:"varint,7,opt,name=bikeshed,enum=testdata.MyMessage_Color" json:"bikeshed,omitempty"` + Somegroup *MyMessage_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"` + RepBytes [][]byte `protobuf:"bytes,10,rep,name=rep_bytes" json:"rep_bytes,omitempty"` + Bigfloat *float64 `protobuf:"fixed64,11,opt,name=bigfloat" json:"bigfloat,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MyMessage) Reset() { *m = MyMessage{} } +func (m *MyMessage) String() string { return proto.CompactTextString(m) } +func (*MyMessage) ProtoMessage() {} + +var extRange_MyMessage = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*MyMessage) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MyMessage +} +func (m *MyMessage) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *MyMessage) GetCount() int32 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +func (m *MyMessage) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MyMessage) GetQuote() string { + if m != nil && m.Quote != nil { + return *m.Quote + } + return "" +} + +func (m *MyMessage) GetPet() []string { + if m != nil { + return m.Pet + } + return nil +} + +func (m *MyMessage) GetInner() *InnerMessage { + if m != nil { + return m.Inner + } + return nil +} + +func (m *MyMessage) GetOthers() []*OtherMessage { + if m != nil { + return m.Others + } + return nil +} + +func (m *MyMessage) GetBikeshed() MyMessage_Color { + if m != nil && m.Bikeshed != nil { + return *m.Bikeshed + } + return 0 +} + +func (m *MyMessage) GetSomegroup() *MyMessage_SomeGroup { + if m != nil { + return m.Somegroup + } + return nil +} + +func (m *MyMessage) GetRepBytes() [][]byte { + if m != nil { + return m.RepBytes + } + return nil +} + +func (m *MyMessage) GetBigfloat() float64 { + if m != nil && m.Bigfloat != nil { + return *m.Bigfloat + } + return 0 +} + +type MyMessage_SomeGroup struct { + GroupField *int32 `protobuf:"varint,9,opt,name=group_field" json:"group_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MyMessage_SomeGroup) Reset() { *m = MyMessage_SomeGroup{} } + +func (m *MyMessage_SomeGroup) GetGroupField() int32 { + if m != nil && m.GroupField != nil { + return *m.GroupField + } + return 0 +} + +type Ext struct { + Data *string `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Ext) Reset() { *m = Ext{} } +func (m *Ext) String() string { return proto.CompactTextString(m) } +func (*Ext) ProtoMessage() {} + +func (m *Ext) GetData() string { + if m != nil && m.Data != nil { + return *m.Data + } + return "" +} + +var E_Ext_More = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*Ext)(nil), + Field: 103, + Name: "testdata.Ext.more", + Tag: "bytes,103,opt,name=more", +} + +var E_Ext_Text = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*string)(nil), + Field: 104, + Name: "testdata.Ext.text", + Tag: "bytes,104,opt,name=text", +} + +var E_Ext_Number = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 105, + Name: "testdata.Ext.number", + Tag: "varint,105,opt,name=number", +} + +type MessageList struct { + Message []*MessageList_Message `protobuf:"group,1,rep" json:"message,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MessageList) Reset() { *m = MessageList{} } +func (m *MessageList) String() string { return proto.CompactTextString(m) } +func (*MessageList) ProtoMessage() {} + +func (m *MessageList) GetMessage() []*MessageList_Message { + if m != nil { + return m.Message + } + return nil +} + +type MessageList_Message struct { + Name *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"` + Count *int32 `protobuf:"varint,3,req,name=count" json:"count,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MessageList_Message) Reset() { *m = MessageList_Message{} } + +func (m *MessageList_Message) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MessageList_Message) GetCount() int32 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +type Strings struct { + StringField *string `protobuf:"bytes,1,opt,name=string_field" json:"string_field,omitempty"` + BytesField []byte `protobuf:"bytes,2,opt,name=bytes_field" json:"bytes_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Strings) Reset() { *m = Strings{} } +func (m *Strings) String() string { return proto.CompactTextString(m) } +func (*Strings) ProtoMessage() {} + +func (m *Strings) GetStringField() string { + if m != nil && m.StringField != nil { + return *m.StringField + } + return "" +} + +func (m *Strings) GetBytesField() []byte { + if m != nil { + return m.BytesField + } + return nil +} + +type Defaults struct { + F_Bool *bool `protobuf:"varint,1,opt,def=1" json:"F_Bool,omitempty"` + F_Int32 *int32 `protobuf:"varint,2,opt,def=32" json:"F_Int32,omitempty"` + F_Int64 *int64 `protobuf:"varint,3,opt,def=64" json:"F_Int64,omitempty"` + F_Fixed32 *uint32 `protobuf:"fixed32,4,opt,def=320" json:"F_Fixed32,omitempty"` + F_Fixed64 *uint64 `protobuf:"fixed64,5,opt,def=640" json:"F_Fixed64,omitempty"` + F_Uint32 *uint32 `protobuf:"varint,6,opt,def=3200" json:"F_Uint32,omitempty"` + F_Uint64 *uint64 `protobuf:"varint,7,opt,def=6400" json:"F_Uint64,omitempty"` + F_Float *float32 `protobuf:"fixed32,8,opt,def=314159" json:"F_Float,omitempty"` + F_Double *float64 `protobuf:"fixed64,9,opt,def=271828" json:"F_Double,omitempty"` + F_String *string `protobuf:"bytes,10,opt,def=hello, \"world!\"\n" json:"F_String,omitempty"` + F_Bytes []byte `protobuf:"bytes,11,opt,def=Bignose" json:"F_Bytes,omitempty"` + F_Sint32 *int32 `protobuf:"zigzag32,12,opt,def=-32" json:"F_Sint32,omitempty"` + F_Sint64 *int64 `protobuf:"zigzag64,13,opt,def=-64" json:"F_Sint64,omitempty"` + F_Enum *Defaults_Color `protobuf:"varint,14,opt,enum=testdata.Defaults_Color,def=1" json:"F_Enum,omitempty"` + F_Pinf *float32 `protobuf:"fixed32,15,opt,def=inf" json:"F_Pinf,omitempty"` + F_Ninf *float32 `protobuf:"fixed32,16,opt,def=-inf" json:"F_Ninf,omitempty"` + F_Nan *float32 `protobuf:"fixed32,17,opt,def=nan" json:"F_Nan,omitempty"` + Sub *SubDefaults `protobuf:"bytes,18,opt,name=sub" json:"sub,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Defaults) Reset() { *m = Defaults{} } +func (m *Defaults) String() string { return proto.CompactTextString(m) } +func (*Defaults) ProtoMessage() {} + +const Default_Defaults_F_Bool bool = true +const Default_Defaults_F_Int32 int32 = 32 +const Default_Defaults_F_Int64 int64 = 64 +const Default_Defaults_F_Fixed32 uint32 = 320 +const Default_Defaults_F_Fixed64 uint64 = 640 +const Default_Defaults_F_Uint32 uint32 = 3200 +const Default_Defaults_F_Uint64 uint64 = 6400 +const Default_Defaults_F_Float float32 = 314159 +const Default_Defaults_F_Double float64 = 271828 +const Default_Defaults_F_String string = "hello, \"world!\"\n" + +var Default_Defaults_F_Bytes []byte = []byte("Bignose") + +const Default_Defaults_F_Sint32 int32 = -32 +const Default_Defaults_F_Sint64 int64 = -64 +const Default_Defaults_F_Enum Defaults_Color = Defaults_GREEN + +var Default_Defaults_F_Pinf float32 = float32(math.Inf(1)) +var Default_Defaults_F_Ninf float32 = float32(math.Inf(-1)) +var Default_Defaults_F_Nan float32 = float32(math.NaN()) + +func (m *Defaults) GetF_Bool() bool { + if m != nil && m.F_Bool != nil { + return *m.F_Bool + } + return Default_Defaults_F_Bool +} + +func (m *Defaults) GetF_Int32() int32 { + if m != nil && m.F_Int32 != nil { + return *m.F_Int32 + } + return Default_Defaults_F_Int32 +} + +func (m *Defaults) GetF_Int64() int64 { + if m != nil && m.F_Int64 != nil { + return *m.F_Int64 + } + return Default_Defaults_F_Int64 +} + +func (m *Defaults) GetF_Fixed32() uint32 { + if m != nil && m.F_Fixed32 != nil { + return *m.F_Fixed32 + } + return Default_Defaults_F_Fixed32 +} + +func (m *Defaults) GetF_Fixed64() uint64 { + if m != nil && m.F_Fixed64 != nil { + return *m.F_Fixed64 + } + return Default_Defaults_F_Fixed64 +} + +func (m *Defaults) GetF_Uint32() uint32 { + if m != nil && m.F_Uint32 != nil { + return *m.F_Uint32 + } + return Default_Defaults_F_Uint32 +} + +func (m *Defaults) GetF_Uint64() uint64 { + if m != nil && m.F_Uint64 != nil { + return *m.F_Uint64 + } + return Default_Defaults_F_Uint64 +} + +func (m *Defaults) GetF_Float() float32 { + if m != nil && m.F_Float != nil { + return *m.F_Float + } + return Default_Defaults_F_Float +} + +func (m *Defaults) GetF_Double() float64 { + if m != nil && m.F_Double != nil { + return *m.F_Double + } + return Default_Defaults_F_Double +} + +func (m *Defaults) GetF_String() string { + if m != nil && m.F_String != nil { + return *m.F_String + } + return Default_Defaults_F_String +} + +func (m *Defaults) GetF_Bytes() []byte { + if m != nil && m.F_Bytes != nil { + return m.F_Bytes + } + return append([]byte(nil), Default_Defaults_F_Bytes...) +} + +func (m *Defaults) GetF_Sint32() int32 { + if m != nil && m.F_Sint32 != nil { + return *m.F_Sint32 + } + return Default_Defaults_F_Sint32 +} + +func (m *Defaults) GetF_Sint64() int64 { + if m != nil && m.F_Sint64 != nil { + return *m.F_Sint64 + } + return Default_Defaults_F_Sint64 +} + +func (m *Defaults) GetF_Enum() Defaults_Color { + if m != nil && m.F_Enum != nil { + return *m.F_Enum + } + return Default_Defaults_F_Enum +} + +func (m *Defaults) GetF_Pinf() float32 { + if m != nil && m.F_Pinf != nil { + return *m.F_Pinf + } + return Default_Defaults_F_Pinf +} + +func (m *Defaults) GetF_Ninf() float32 { + if m != nil && m.F_Ninf != nil { + return *m.F_Ninf + } + return Default_Defaults_F_Ninf +} + +func (m *Defaults) GetF_Nan() float32 { + if m != nil && m.F_Nan != nil { + return *m.F_Nan + } + return Default_Defaults_F_Nan +} + +func (m *Defaults) GetSub() *SubDefaults { + if m != nil { + return m.Sub + } + return nil +} + +type SubDefaults struct { + N *int64 `protobuf:"varint,1,opt,name=n,def=7" json:"n,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *SubDefaults) Reset() { *m = SubDefaults{} } +func (m *SubDefaults) String() string { return proto.CompactTextString(m) } +func (*SubDefaults) ProtoMessage() {} + +const Default_SubDefaults_N int64 = 7 + +func (m *SubDefaults) GetN() int64 { + if m != nil && m.N != nil { + return *m.N + } + return Default_SubDefaults_N +} + +type RepeatedEnum struct { + Color []RepeatedEnum_Color `protobuf:"varint,1,rep,name=color,enum=testdata.RepeatedEnum_Color" json:"color,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *RepeatedEnum) Reset() { *m = RepeatedEnum{} } +func (m *RepeatedEnum) String() string { return proto.CompactTextString(m) } +func (*RepeatedEnum) ProtoMessage() {} + +func (m *RepeatedEnum) GetColor() []RepeatedEnum_Color { + if m != nil { + return m.Color + } + return nil +} + +type MoreRepeated struct { + Bools []bool `protobuf:"varint,1,rep,name=bools" json:"bools,omitempty"` + BoolsPacked []bool `protobuf:"varint,2,rep,packed,name=bools_packed" json:"bools_packed,omitempty"` + Ints []int32 `protobuf:"varint,3,rep,name=ints" json:"ints,omitempty"` + IntsPacked []int32 `protobuf:"varint,4,rep,packed,name=ints_packed" json:"ints_packed,omitempty"` + Strings []string `protobuf:"bytes,5,rep,name=strings" json:"strings,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MoreRepeated) Reset() { *m = MoreRepeated{} } +func (m *MoreRepeated) String() string { return proto.CompactTextString(m) } +func (*MoreRepeated) ProtoMessage() {} + +func (m *MoreRepeated) GetBools() []bool { + if m != nil { + return m.Bools + } + return nil +} + +func (m *MoreRepeated) GetBoolsPacked() []bool { + if m != nil { + return m.BoolsPacked + } + return nil +} + +func (m *MoreRepeated) GetInts() []int32 { + if m != nil { + return m.Ints + } + return nil +} + +func (m *MoreRepeated) GetIntsPacked() []int32 { + if m != nil { + return m.IntsPacked + } + return nil +} + +func (m *MoreRepeated) GetStrings() []string { + if m != nil { + return m.Strings + } + return nil +} + +type GroupOld struct { + G *GroupOld_G `protobuf:"group,1,opt" json:"g,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupOld) Reset() { *m = GroupOld{} } +func (m *GroupOld) String() string { return proto.CompactTextString(m) } +func (*GroupOld) ProtoMessage() {} + +func (m *GroupOld) GetG() *GroupOld_G { + if m != nil { + return m.G + } + return nil +} + +type GroupOld_G struct { + X *int32 `protobuf:"varint,2,opt,name=x" json:"x,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupOld_G) Reset() { *m = GroupOld_G{} } + +func (m *GroupOld_G) GetX() int32 { + if m != nil && m.X != nil { + return *m.X + } + return 0 +} + +type GroupNew struct { + G *GroupNew_G `protobuf:"group,1,opt" json:"g,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupNew) Reset() { *m = GroupNew{} } +func (m *GroupNew) String() string { return proto.CompactTextString(m) } +func (*GroupNew) ProtoMessage() {} + +func (m *GroupNew) GetG() *GroupNew_G { + if m != nil { + return m.G + } + return nil +} + +type GroupNew_G struct { + X *int32 `protobuf:"varint,2,opt,name=x" json:"x,omitempty"` + Y *int32 `protobuf:"varint,3,opt,name=y" json:"y,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupNew_G) Reset() { *m = GroupNew_G{} } + +func (m *GroupNew_G) GetX() int32 { + if m != nil && m.X != nil { + return *m.X + } + return 0 +} + +func (m *GroupNew_G) GetY() int32 { + if m != nil && m.Y != nil { + return *m.Y + } + return 0 +} + +var E_Greeting = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: ([]string)(nil), + Field: 106, + Name: "testdata.greeting", + Tag: "bytes,106,rep,name=greeting", +} + +func init() { + proto.RegisterEnum("testdata.FOO", FOO_name, FOO_value) + proto.RegisterEnum("testdata.GoTest_KIND", GoTest_KIND_name, GoTest_KIND_value) + proto.RegisterEnum("testdata.MyMessage_Color", MyMessage_Color_name, MyMessage_Color_value) + proto.RegisterEnum("testdata.Defaults_Color", Defaults_Color_name, Defaults_Color_value) + proto.RegisterEnum("testdata.RepeatedEnum_Color", RepeatedEnum_Color_name, RepeatedEnum_Color_value) + proto.RegisterExtension(E_Ext_More) + proto.RegisterExtension(E_Ext_Text) + proto.RegisterExtension(E_Ext_Number) + proto.RegisterExtension(E_Greeting) +} diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.proto b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.proto new file mode 100644 index 000000000000..3d1cbb675d50 --- /dev/null +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.proto @@ -0,0 +1,494 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A feature-rich test file for the protocol compiler and libraries. + +syntax = "proto2"; + +package testdata; + +enum FOO { FOO1 = 1; }; + +message GoEnum { + required FOO foo = 1; +} + +message GoTestField { + required string Label = 1; + required string Type = 2; +} + +message GoTest { + // An enum, for completeness. + enum KIND { + VOID = 0; + + // Basic types + BOOL = 1; + BYTES = 2; + FINGERPRINT = 3; + FLOAT = 4; + INT = 5; + STRING = 6; + TIME = 7; + + // Groupings + TUPLE = 8; + ARRAY = 9; + MAP = 10; + + // Table types + TABLE = 11; + + // Functions + FUNCTION = 12; // last tag + }; + + // Some typical parameters + required KIND Kind = 1; + optional string Table = 2; + optional int32 Param = 3; + + // Required, repeated and optional foreign fields. + required GoTestField RequiredField = 4; + repeated GoTestField RepeatedField = 5; + optional GoTestField OptionalField = 6; + + // Required fields of all basic types + required bool F_Bool_required = 10; + required int32 F_Int32_required = 11; + required int64 F_Int64_required = 12; + required fixed32 F_Fixed32_required = 13; + required fixed64 F_Fixed64_required = 14; + required uint32 F_Uint32_required = 15; + required uint64 F_Uint64_required = 16; + required float F_Float_required = 17; + required double F_Double_required = 18; + required string F_String_required = 19; + required bytes F_Bytes_required = 101; + required sint32 F_Sint32_required = 102; + required sint64 F_Sint64_required = 103; + + // Repeated fields of all basic types + repeated bool F_Bool_repeated = 20; + repeated int32 F_Int32_repeated = 21; + repeated int64 F_Int64_repeated = 22; + repeated fixed32 F_Fixed32_repeated = 23; + repeated fixed64 F_Fixed64_repeated = 24; + repeated uint32 F_Uint32_repeated = 25; + repeated uint64 F_Uint64_repeated = 26; + repeated float F_Float_repeated = 27; + repeated double F_Double_repeated = 28; + repeated string F_String_repeated = 29; + repeated bytes F_Bytes_repeated = 201; + repeated sint32 F_Sint32_repeated = 202; + repeated sint64 F_Sint64_repeated = 203; + + // Optional fields of all basic types + optional bool F_Bool_optional = 30; + optional int32 F_Int32_optional = 31; + optional int64 F_Int64_optional = 32; + optional fixed32 F_Fixed32_optional = 33; + optional fixed64 F_Fixed64_optional = 34; + optional uint32 F_Uint32_optional = 35; + optional uint64 F_Uint64_optional = 36; + optional float F_Float_optional = 37; + optional double F_Double_optional = 38; + optional string F_String_optional = 39; + optional bytes F_Bytes_optional = 301; + optional sint32 F_Sint32_optional = 302; + optional sint64 F_Sint64_optional = 303; + + // Default-valued fields of all basic types + optional bool F_Bool_defaulted = 40 [default=true]; + optional int32 F_Int32_defaulted = 41 [default=32]; + optional int64 F_Int64_defaulted = 42 [default=64]; + optional fixed32 F_Fixed32_defaulted = 43 [default=320]; + optional fixed64 F_Fixed64_defaulted = 44 [default=640]; + optional uint32 F_Uint32_defaulted = 45 [default=3200]; + optional uint64 F_Uint64_defaulted = 46 [default=6400]; + optional float F_Float_defaulted = 47 [default=314159.]; + optional double F_Double_defaulted = 48 [default=271828.]; + optional string F_String_defaulted = 49 [default="hello, \"world!\"\n"]; + optional bytes F_Bytes_defaulted = 401 [default="Bignose"]; + optional sint32 F_Sint32_defaulted = 402 [default = -32]; + optional sint64 F_Sint64_defaulted = 403 [default = -64]; + + // Packed repeated fields (no string or bytes). + repeated bool F_Bool_repeated_packed = 50 [packed=true]; + repeated int32 F_Int32_repeated_packed = 51 [packed=true]; + repeated int64 F_Int64_repeated_packed = 52 [packed=true]; + repeated fixed32 F_Fixed32_repeated_packed = 53 [packed=true]; + repeated fixed64 F_Fixed64_repeated_packed = 54 [packed=true]; + repeated uint32 F_Uint32_repeated_packed = 55 [packed=true]; + repeated uint64 F_Uint64_repeated_packed = 56 [packed=true]; + repeated float F_Float_repeated_packed = 57 [packed=true]; + repeated double F_Double_repeated_packed = 58 [packed=true]; + repeated sint32 F_Sint32_repeated_packed = 502 [packed=true]; + repeated sint64 F_Sint64_repeated_packed = 503 [packed=true]; + + // Required, repeated, and optional groups. + required group RequiredGroup = 70 { + required string RequiredField = 71; + }; + + repeated group RepeatedGroup = 80 { + required string RequiredField = 81; + }; + + optional group OptionalGroup = 90 { + required string RequiredField = 91; + }; +} + +// For testing skipping of unrecognized fields. +// Numbers are all big, larger than tag numbers in GoTestField, +// the message used in the corresponding test. +message GoSkipTest { + required int32 skip_int32 = 11; + required fixed32 skip_fixed32 = 12; + required fixed64 skip_fixed64 = 13; + required string skip_string = 14; + required group SkipGroup = 15 { + required int32 group_int32 = 16; + required string group_string = 17; + } +} + +// For testing packed/non-packed decoder switching. +// A serialized instance of one should be deserializable as the other. +message NonPackedTest { + repeated int32 a = 1; +} + +message PackedTest { + repeated int32 b = 1 [packed=true]; +} + +message MaxTag { + // Maximum possible tag number. + optional string last_field = 536870911; +} + +message OldMessage { + message Nested { + optional string name = 1; + } + optional Nested nested = 1; + + optional int32 num = 2; +} + +// NewMessage is wire compatible with OldMessage; +// imagine it as a future version. +message NewMessage { + message Nested { + optional string name = 1; + optional string food_group = 2; + } + optional Nested nested = 1; + + // This is an int32 in OldMessage. + optional int64 num = 2; +} + +// Smaller tests for ASCII formatting. + +message InnerMessage { + required string host = 1; + optional int32 port = 2 [default=4000]; + optional bool connected = 3; +} + +message OtherMessage { + optional int64 key = 1; + optional bytes value = 2; + optional float weight = 3; + optional InnerMessage inner = 4; +} + +message MyMessage { + required int32 count = 1; + optional string name = 2; + optional string quote = 3; + repeated string pet = 4; + optional InnerMessage inner = 5; + repeated OtherMessage others = 6; + repeated InnerMessage rep_inner = 12; + + enum Color { + RED = 0; + GREEN = 1; + BLUE = 2; + }; + optional Color bikeshed = 7; + + optional group SomeGroup = 8 { + optional int32 group_field = 9; + } + + // This field becomes [][]byte in the generated code. + repeated bytes rep_bytes = 10; + + optional double bigfloat = 11; + + extensions 100 to max; +} + +message Ext { + extend MyMessage { + optional Ext more = 103; + optional string text = 104; + optional int32 number = 105; + } + + optional string data = 1; +} + +extend MyMessage { + repeated string greeting = 106; +} + +message DefaultsMessage { + enum DefaultsEnum { + ZERO = 0; + ONE = 1; + TWO = 2; + }; + extensions 100 to max; +} + +extend DefaultsMessage { + optional double no_default_double = 101; + optional float no_default_float = 102; + optional int32 no_default_int32 = 103; + optional int64 no_default_int64 = 104; + optional uint32 no_default_uint32 = 105; + optional uint64 no_default_uint64 = 106; + optional sint32 no_default_sint32 = 107; + optional sint64 no_default_sint64 = 108; + optional fixed32 no_default_fixed32 = 109; + optional fixed64 no_default_fixed64 = 110; + optional sfixed32 no_default_sfixed32 = 111; + optional sfixed64 no_default_sfixed64 = 112; + optional bool no_default_bool = 113; + optional string no_default_string = 114; + optional bytes no_default_bytes = 115; + optional DefaultsMessage.DefaultsEnum no_default_enum = 116; + + optional double default_double = 201 [default = 3.1415]; + optional float default_float = 202 [default = 3.14]; + optional int32 default_int32 = 203 [default = 42]; + optional int64 default_int64 = 204 [default = 43]; + optional uint32 default_uint32 = 205 [default = 44]; + optional uint64 default_uint64 = 206 [default = 45]; + optional sint32 default_sint32 = 207 [default = 46]; + optional sint64 default_sint64 = 208 [default = 47]; + optional fixed32 default_fixed32 = 209 [default = 48]; + optional fixed64 default_fixed64 = 210 [default = 49]; + optional sfixed32 default_sfixed32 = 211 [default = 50]; + optional sfixed64 default_sfixed64 = 212 [default = 51]; + optional bool default_bool = 213 [default = true]; + optional string default_string = 214 [default = "Hello, string"]; + optional bytes default_bytes = 215 [default = "Hello, bytes"]; + optional DefaultsMessage.DefaultsEnum default_enum = 216 [default = ONE]; +} + +message MyMessageSet { + option message_set_wire_format = true; + extensions 100 to max; +} + +message Empty { +} + +extend MyMessageSet { + optional Empty x201 = 201; + optional Empty x202 = 202; + optional Empty x203 = 203; + optional Empty x204 = 204; + optional Empty x205 = 205; + optional Empty x206 = 206; + optional Empty x207 = 207; + optional Empty x208 = 208; + optional Empty x209 = 209; + optional Empty x210 = 210; + optional Empty x211 = 211; + optional Empty x212 = 212; + optional Empty x213 = 213; + optional Empty x214 = 214; + optional Empty x215 = 215; + optional Empty x216 = 216; + optional Empty x217 = 217; + optional Empty x218 = 218; + optional Empty x219 = 219; + optional Empty x220 = 220; + optional Empty x221 = 221; + optional Empty x222 = 222; + optional Empty x223 = 223; + optional Empty x224 = 224; + optional Empty x225 = 225; + optional Empty x226 = 226; + optional Empty x227 = 227; + optional Empty x228 = 228; + optional Empty x229 = 229; + optional Empty x230 = 230; + optional Empty x231 = 231; + optional Empty x232 = 232; + optional Empty x233 = 233; + optional Empty x234 = 234; + optional Empty x235 = 235; + optional Empty x236 = 236; + optional Empty x237 = 237; + optional Empty x238 = 238; + optional Empty x239 = 239; + optional Empty x240 = 240; + optional Empty x241 = 241; + optional Empty x242 = 242; + optional Empty x243 = 243; + optional Empty x244 = 244; + optional Empty x245 = 245; + optional Empty x246 = 246; + optional Empty x247 = 247; + optional Empty x248 = 248; + optional Empty x249 = 249; + optional Empty x250 = 250; +} + +message MessageList { + repeated group Message = 1 { + required string name = 2; + required int32 count = 3; + } +} + +message Strings { + optional string string_field = 1; + optional bytes bytes_field = 2; +} + +message Defaults { + enum Color { + RED = 0; + GREEN = 1; + BLUE = 2; + } + + // Default-valued fields of all basic types. + // Same as GoTest, but copied here to make testing easier. + optional bool F_Bool = 1 [default=true]; + optional int32 F_Int32 = 2 [default=32]; + optional int64 F_Int64 = 3 [default=64]; + optional fixed32 F_Fixed32 = 4 [default=320]; + optional fixed64 F_Fixed64 = 5 [default=640]; + optional uint32 F_Uint32 = 6 [default=3200]; + optional uint64 F_Uint64 = 7 [default=6400]; + optional float F_Float = 8 [default=314159.]; + optional double F_Double = 9 [default=271828.]; + optional string F_String = 10 [default="hello, \"world!\"\n"]; + optional bytes F_Bytes = 11 [default="Bignose"]; + optional sint32 F_Sint32 = 12 [default=-32]; + optional sint64 F_Sint64 = 13 [default=-64]; + optional Color F_Enum = 14 [default=GREEN]; + + // More fields with crazy defaults. + optional float F_Pinf = 15 [default=inf]; + optional float F_Ninf = 16 [default=-inf]; + optional float F_Nan = 17 [default=nan]; + + // Sub-message. + optional SubDefaults sub = 18; + + // Redundant but explicit defaults. + optional string str_zero = 19 [default=""]; +} + +message SubDefaults { + optional int64 n = 1 [default=7]; +} + +message RepeatedEnum { + enum Color { + RED = 1; + } + repeated Color color = 1; +} + +message MoreRepeated { + repeated bool bools = 1; + repeated bool bools_packed = 2 [packed=true]; + repeated int32 ints = 3; + repeated int32 ints_packed = 4 [packed=true]; + repeated int64 int64s_packed = 7 [packed=true]; + repeated string strings = 5; + repeated fixed32 fixeds = 6; +} + +// GroupOld and GroupNew have the same wire format. +// GroupNew has a new field inside a group. + +message GroupOld { + optional group G = 101 { + optional int32 x = 2; + } +} + +message GroupNew { + optional group G = 101 { + optional int32 x = 2; + optional int32 y = 3; + } +} + +message FloatingPoint { + required double f = 1; +} + +message MessageWithMap { + map name_mapping = 1; + map msg_mapping = 2; + map byte_mapping = 3; + map str_to_str = 4; +} + +message Communique { + optional bool make_me_cry = 1; + + // This is a oneof, called "union". + oneof union { + int32 number = 5; + string name = 6; + bytes data = 7; + double temp_c = 8; + MyMessage.Color col = 9; + Strings msg = 10; + } +} diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text.go index 36524244188d..c12caecafb99 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text.go @@ -42,6 +42,7 @@ import ( "bufio" "bytes" "encoding" + "errors" "fmt" "io" "log" @@ -331,6 +332,32 @@ func writeStruct(w *textWriter, sv reflect.Value) error { } } + if fv.Kind() == reflect.Interface { + // Check if it is a oneof. + if st.Field(i).Tag.Get("protobuf_oneof") != "" { + // fv is nil, or holds a pointer to generated struct. + // That generated struct has exactly one field, + // which has a protobuf struct tag. + if fv.IsNil() { + continue + } + inner := fv.Elem().Elem() // interface -> *T -> T + tag := inner.Type().Field(0).Tag.Get("protobuf") + props.Parse(tag) // Overwrite the outer props. + // Write the value in the oneof, not the oneof itself. + fv = inner.Field(0) + + // Special case to cope with malformed messages gracefully: + // If the value in the oneof is a nil pointer, don't panic + // in writeAny. + if fv.Kind() == reflect.Ptr && fv.IsNil() { + // Use errors.New so writeAny won't render quotes. + msg := errors.New("/* nil */") + fv = reflect.ValueOf(&msg).Elem() + } + } + } + if err := writeName(w, props); err != nil { return err } @@ -396,15 +423,17 @@ func writeAny(w *textWriter, v reflect.Value, props *Properties) error { v = reflect.Indirect(v) if props != nil && len(props.CustomType) > 0 { - var custom Marshaler = v.Interface().(Marshaler) - data, err := custom.Marshal() - if err != nil { - return err - } - if err := writeString(w, string(data)); err != nil { - return err + custom, ok := v.Interface().(Marshaler) + if ok { + data, err := custom.Marshal() + if err != nil { + return err + } + if err := writeString(w, string(data)); err != nil { + return err + } + return nil } - return nil } // Floats have special cases. @@ -533,8 +562,8 @@ func writeMessageSet(w *textWriter, ms *MessageSet) error { pb := reflect.New(msd.t.Elem()) if err := Unmarshal(item.Message, pb.Interface().(Message)); err != nil { - if _, err := fmt.Fprintf(w, "/* bad message: %v */\n", err); err != nil { - return err + if _, ferr := fmt.Fprintf(w, "/* bad message: %v */\n", err); ferr != nil { + return ferr } } else { if err := writeStruct(w, pb.Elem()); err != nil { @@ -569,19 +598,19 @@ func writeUnknownStruct(w *textWriter, data []byte) error { for b.index < len(b.buf) { x, err := b.DecodeVarint() if err != nil { - _, err := fmt.Fprintf(w, "/* %v */\n", err) - return err + _, ferr := fmt.Fprintf(w, "/* %v */\n", err) + return ferr } wire, tag := x&7, x>>3 if wire == WireEndGroup { w.unindent() - if _, err := w.Write(endBraceNewline); err != nil { - return err + if _, werr := w.Write(endBraceNewline); werr != nil { + return werr } continue } - if _, err := fmt.Fprint(w, tag); err != nil { - return err + if _, ferr := fmt.Fprint(w, tag); ferr != nil { + return ferr } if wire != WireStartGroup { if err := w.WriteByte(':'); err != nil { diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser.go index 9b2fab593572..acc001fd2780 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser.go @@ -390,8 +390,7 @@ func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSet } // Returns the index in the struct for the named field, as well as the parsed tag properties. -func structFieldByName(st reflect.Type, name string) (int, *Properties, bool) { - sprops := GetProperties(st) +func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { i, ok := sprops.decoderOrigNames[name] if ok { return i, sprops.Prop[i], true @@ -443,7 +442,8 @@ func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseEr func (p *textParser) readStruct(sv reflect.Value, terminator string) error { st := sv.Type() - reqCount := GetProperties(st).reqCount + sprops := GetProperties(st) + reqCount := sprops.reqCount var reqFieldErr error fieldSet := make(map[string]bool) // A struct is a sequence of "name: value", terminated by one of @@ -525,95 +525,107 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { sl = reflect.Append(sl, ext) SetExtension(ep, desc, sl.Interface()) } - } else { - // This is a normal, non-extension field. - name := tok.value - fi, props, ok := structFieldByName(st, name) - if !ok { - return p.errorf("unknown field name %q in %v", name, st) + if err := p.consumeOptionalSeparator(); err != nil { + return err } + continue + } - dst := sv.Field(fi) - - if dst.Kind() == reflect.Map { - // Consume any colon. - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Construct the map if it doesn't already exist. - if dst.IsNil() { - dst.Set(reflect.MakeMap(dst.Type())) - } - key := reflect.New(dst.Type().Key()).Elem() - val := reflect.New(dst.Type().Elem()).Elem() - - // The map entry should be this sequence of tokens: - // < key : KEY value : VALUE > - // Technically the "key" and "value" could come in any order, - // but in practice they won't. - - tok := p.next() - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - if err := p.consumeToken("key"); err != nil { - return err - } - if err := p.consumeToken(":"); err != nil { - return err - } - if err := p.readAny(key, props.mkeyprop); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - if err := p.consumeToken("value"); err != nil { - return err - } - if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { - return err - } - if err := p.readAny(val, props.mvalprop); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - if err := p.consumeToken(terminator); err != nil { - return err - } + // This is a normal, non-extension field. + name := tok.value + var dst reflect.Value + fi, props, ok := structFieldByName(sprops, name) + if ok { + dst = sv.Field(fi) + } else if oop, ok := sprops.OneofTypes[name]; ok { + // It is a oneof. + props = oop.Prop + nv := reflect.New(oop.Type.Elem()) + dst = nv.Elem().Field(0) + sv.Field(oop.Field).Set(nv) + } + if !dst.IsValid() { + return p.errorf("unknown field name %q in %v", name, st) + } - dst.SetMapIndex(key, val) - continue + if dst.Kind() == reflect.Map { + // Consume any colon. + if err := p.checkForColon(props, dst.Type()); err != nil { + return err } - // Check that it's not already set if it's not a repeated field. - if !props.Repeated && fieldSet[name] { - return p.errorf("non-repeated field %q was repeated", name) + // Construct the map if it doesn't already exist. + if dst.IsNil() { + dst.Set(reflect.MakeMap(dst.Type())) } - - if err := p.checkForColon(props, st.Field(fi).Type); err != nil { + key := reflect.New(dst.Type().Key()).Elem() + val := reflect.New(dst.Type().Elem()).Elem() + + // The map entry should be this sequence of tokens: + // < key : KEY value : VALUE > + // Technically the "key" and "value" could come in any order, + // but in practice they won't. + + tok := p.next() + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + if err := p.consumeToken("key"); err != nil { + return err + } + if err := p.consumeToken(":"); err != nil { + return err + } + if err := p.readAny(key, props.mkeyprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + if err := p.consumeToken("value"); err != nil { + return err + } + if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { + return err + } + if err := p.readAny(val, props.mvalprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + if err := p.consumeToken(terminator); err != nil { return err } - // Parse into the field. - fieldSet[name] = true - if err := p.readAny(dst, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } else if props.Required { - reqCount-- + dst.SetMapIndex(key, val) + continue + } + + // Check that it's not already set if it's not a repeated field. + if !props.Repeated && fieldSet[name] { + return p.errorf("non-repeated field %q was repeated", name) + } + + if err := p.checkForColon(props, dst.Type()); err != nil { + return err + } + + // Parse into the field. + fieldSet[name] = true + if err := p.readAny(dst, props); err != nil { + if _, ok := err.(*RequiredNotSetError); !ok { + return err } + reqFieldErr = err + } else if props.Required { + reqCount-- } if err := p.consumeOptionalSeparator(); err != nil { diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser_test.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser_test.go index f1c62319251b..0ac8a51c5e98 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser_test.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser_test.go @@ -486,6 +486,18 @@ func TestMapParsing(t *testing.T) { } } +func TestOneofParsing(t *testing.T) { + const in = `name:"Shrek"` + m := new(Communique) + want := &Communique{Union: &Communique_Name{"Shrek"}} + if err := UnmarshalText(in, m); err != nil { + t.Fatal(err) + } + if !Equal(m, want) { + t.Errorf("\n got %v\nwant %v", m, want) + } +} + var benchInput string func init() { diff --git a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_test.go b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_test.go index a98504ef35d0..6524048428f0 100644 --- a/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_test.go +++ b/Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_test.go @@ -208,6 +208,30 @@ func TestMarshalTextUnknownEnum(t *testing.T) { } } +func TestTextOneof(t *testing.T) { + tests := []struct { + m proto.Message + want string + }{ + // zero message + {&pb.Communique{}, ``}, + // scalar field + {&pb.Communique{Union: &pb.Communique_Number{Number: 4}}, `number:4`}, + // message field + {&pb.Communique{Union: &pb.Communique_Msg{ + Msg: &pb.Strings{StringField: proto.String("why hello!")}, + }}, `msg:`}, + // bad oneof (should not panic) + {&pb.Communique{Union: &pb.Communique_Msg{Msg: nil}}, `msg:/* nil */`}, + } + for _, test := range tests { + got := strings.TrimSpace(test.m.String()) + if got != test.want { + t.Errorf("\n got %s\nwant %s", got, test.want) + } + } +} + func BenchmarkMarshalTextBuffered(b *testing.B) { buf := new(bytes.Buffer) m := newTestMessage() diff --git a/Godeps/_workspace/src/github.com/jonboulle/clockwork/.travis.yml b/Godeps/_workspace/src/github.com/jonboulle/clockwork/.travis.yml new file mode 100644 index 000000000000..6a363c70f86b --- /dev/null +++ b/Godeps/_workspace/src/github.com/jonboulle/clockwork/.travis.yml @@ -0,0 +1,3 @@ +language: go +go: + - 1.3 diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client.go deleted file mode 100644 index 3e42c2d7c448..000000000000 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client.go +++ /dev/null @@ -1,444 +0,0 @@ -package zoo - -import ( - "errors" - "fmt" - "sync" - "sync/atomic" - "time" - - log "github.com/golang/glog" - "github.com/samuel/go-zookeeper/zk" -) - -const ( - defaultSessionTimeout = 60 * time.Second - defaultReconnectTimeout = 5 * time.Second - currentPath = "." - defaultRewatchDelay = 200 * time.Millisecond -) - -type stateType int32 - -const ( - disconnectedState stateType = iota - connectionRequestedState - connectionAttemptState - connectedState -) - -func (s stateType) String() string { - switch s { - case disconnectedState: - return "DISCONNECTED" - case connectionRequestedState: - return "REQUESTED" - case connectionAttemptState: - return "ATTEMPT" - case connectedState: - return "CONNECTED" - default: - panic(fmt.Sprintf("unrecognized state: %d", int32(s))) - } -} - -type Client struct { - conn Connector - defaultFactory Factory - factory Factory // must never be nil, use setFactory to update - state stateType - reconnCount uint64 - reconnDelay time.Duration - rootPath string - errorHandler ErrorHandler // must never be nil - connectOnce sync.Once - stopOnce sync.Once - shouldStop chan struct{} // signal chan - shouldReconn chan struct{} // message chan - connLock sync.Mutex - hasConnected chan struct{} // message chan - rewatchDelay time.Duration -} - -func newClient(hosts []string, path string) (*Client, error) { - zkc := &Client{ - reconnDelay: defaultReconnectTimeout, - rewatchDelay: defaultRewatchDelay, - rootPath: path, - shouldStop: make(chan struct{}), - shouldReconn: make(chan struct{}, 1), - hasConnected: make(chan struct{}, 1), - errorHandler: ErrorHandler(func(*Client, error) {}), - defaultFactory: asFactory(func() (Connector, <-chan zk.Event, error) { - return zk.Connect(hosts, defaultSessionTimeout) - }), - } - zkc.setFactory(zkc.defaultFactory) - // TODO(vlad): validate URIs - return zkc, nil -} - -func (zkc *Client) setFactory(f Factory) { - if f == nil { - f = zkc.defaultFactory - } - zkc.factory = asFactory(func() (c Connector, ch <-chan zk.Event, err error) { - select { - case <-zkc.shouldStop: - err = errors.New("client stopping") - default: - zkc.connLock.Lock() - defer zkc.connLock.Unlock() - if zkc.conn != nil { - zkc.conn.Close() - } - c, ch, err = f.create() - zkc.conn = c - } - return - }) -} - -// return true only if the client's state was changed from `from` to `to` -func (zkc *Client) stateChange(from, to stateType) (result bool) { - defer func() { - log.V(3).Infof("stateChange: from=%v to=%v result=%v", from, to, result) - }() - result = atomic.CompareAndSwapInt32((*int32)(&zkc.state), int32(from), int32(to)) - return -} - -// connect to zookeeper, blocks on the initial call to doConnect() -func (zkc *Client) connect() { - select { - case <-zkc.shouldStop: - return - default: - zkc.connectOnce.Do(func() { - if zkc.stateChange(disconnectedState, connectionRequestedState) { - if err := zkc.doConnect(); err != nil { - log.Error(err) - zkc.errorHandler(zkc, err) - } - } - go func() { - for { - select { - case <-zkc.shouldStop: - zkc.connLock.Lock() - defer zkc.connLock.Unlock() - if zkc.conn != nil { - zkc.conn.Close() - } - return - case <-zkc.shouldReconn: - if err := zkc.reconnect(); err != nil { - log.Error(err) - zkc.errorHandler(zkc, err) - } - } - } - }() - }) - } - return -} - -// attempt to reconnect to zookeeper. will ignore attempts to reconnect -// if not disconnected. if reconnection is attempted then this func will block -// for at least reconnDelay before actually attempting to connect to zookeeper. -func (zkc *Client) reconnect() error { - if !zkc.stateChange(disconnectedState, connectionRequestedState) { - log.V(4).Infoln("Ignoring reconnect, currently connected/connecting.") - return nil - } - - defer func() { zkc.reconnCount++ }() - - log.V(4).Infoln("Delaying reconnection for ", zkc.reconnDelay) - <-time.After(zkc.reconnDelay) - - return zkc.doConnect() -} - -func (zkc *Client) doConnect() error { - if !zkc.stateChange(connectionRequestedState, connectionAttemptState) { - log.V(4).Infoln("aborting doConnect, connection attempt already in progress or else disconnected") - return nil - } - - // if we're not connected by the time we return then we failed. - defer func() { - zkc.stateChange(connectionAttemptState, disconnectedState) - }() - - // create Connector instance - conn, sessionEvents, err := zkc.factory.create() - if err != nil { - // once the factory stops producing connectors, it's time to stop - zkc.stop() - return err - } - - zkc.connLock.Lock() - zkc.conn = conn - zkc.connLock.Unlock() - - log.V(4).Infof("Created connection object of type %T\n", conn) - connected := make(chan struct{}) - sessionExpired := make(chan struct{}) - go func() { - defer close(sessionExpired) - zkc.monitorSession(sessionEvents, connected) - }() - - // wait for connected confirmation - select { - case <-connected: - if !zkc.stateChange(connectionAttemptState, connectedState) { - log.V(4).Infoln("failed to transition to connected state") - // we could be: - // - disconnected ... reconnect() will try to connect again, otherwise; - // - connected ... another goroutine already established a connection - // - connectionRequested ... another goroutine is already trying to connect - zkc.requestReconnect() - } - log.Infoln("zookeeper client connected") - case <-sessionExpired: - // connection was disconnected before it was ever really 'connected' - if !zkc.stateChange(connectionAttemptState, disconnectedState) { - //programming error - panic("failed to transition from connection-attempt to disconnected state") - } - zkc.requestReconnect() - case <-zkc.shouldStop: - // noop - } - return nil -} - -// signal for reconnect unless we're shutting down -func (zkc *Client) requestReconnect() { - select { - case <-zkc.shouldStop: - // abort reconnect request, client is shutting down - default: - select { - case zkc.shouldReconn <- struct{}{}: - // reconnect request successful - default: - // reconnect chan is full: reconnect has already - // been requested. move on. - } - } -} - -// monitor a zookeeper session event channel, closes the 'connected' channel once -// a zookeeper connection has been established. errors are forwarded to the client's -// errorHandler. the closing of the sessionEvents chan triggers a call to client.onDisconnected. -// this func blocks until either the client's shouldStop or sessionEvents chan are closed. -func (zkc *Client) monitorSession(sessionEvents <-chan zk.Event, connected chan struct{}) { - firstConnected := true - for { - select { - case <-zkc.shouldStop: - return - case e, ok := <-sessionEvents: - if !ok { - // once sessionEvents is closed, the embedded ZK client will - // no longer attempt to reconnect. - zkc.onDisconnected() - return - } else if e.Err != nil { - log.Errorf("received state error: %s", e.Err.Error()) - zkc.errorHandler(zkc, e.Err) - } - switch e.State { - case zk.StateConnecting: - log.Infoln("connecting to zookeeper..") - - case zk.StateConnected: - log.V(2).Infoln("received StateConnected") - if firstConnected { - close(connected) // signal session listener - firstConnected = false - } - // let any listeners know about the change - select { - case <-zkc.shouldStop: // noop - case zkc.hasConnected <- struct{}{}: // noop - default: // message buf full, this becomes a non-blocking noop - } - - case zk.StateDisconnected: - log.Infoln("zookeeper client disconnected") - - case zk.StateExpired: - log.Infoln("zookeeper client session expired") - } - } - } -} - -// watch the child nodes for changes, at the specified path. -// callers that specify a path of `currentPath` will watch the currently set rootPath, -// otherwise the watchedPath is calculated as rootPath+path. -// this func spawns a go routine to actually do the watching, and so returns immediately. -// in the absense of errors a signalling channel is returned that will close -// upon the termination of the watch (e.g. due to disconnection). -func (zkc *Client) watchChildren(path string, watcher ChildWatcher) (<-chan struct{}, error) { - watchPath := zkc.rootPath - if path != "" && path != currentPath { - watchPath = watchPath + path - } - - log.V(2).Infoln("Watching children for path", watchPath) - watchEnded := make(chan struct{}) - go func() { - defer close(watchEnded) - zkc._watchChildren(watchPath, watcher) - }() - return watchEnded, nil -} - -// continuation of watchChildren. blocks until either underlying zk connector terminates, or else this -// client is shut down. continuously renews child watches. -func (zkc *Client) _watchChildren(watchPath string, watcher ChildWatcher) { - watcher(zkc, watchPath) // prime the listener - var zkevents <-chan zk.Event - var err error - first := true - for { - // we really only expect this to happen when zk session has expired, - // give the connection a little time to re-establish itself - for { - //TODO(jdef) it would be better if we could listen for broadcast Connection/Disconnection events, - //emitted whenever the embedded client cycles (read: when the connection state of this client changes). - //As it currently stands, if the embedded client cycles fast enough, we may actually not notice it here - //and keep on watching like nothing bad happened. - if !zkc.isConnected() { - log.Warningf("no longer connected to server, exiting child watch") - return - } - if first { - first = false - } else { - select { - case <-zkc.shouldStop: - return - case <-time.After(zkc.rewatchDelay): - } - } - _, _, zkevents, err = zkc.conn.ChildrenW(watchPath) - if err == nil { - log.V(2).Infoln("rewatching children for path", watchPath) - break - } - log.V(1).Infof("unable to watch children for path %s: %s", watchPath, err.Error()) - zkc.errorHandler(zkc, err) - } - // zkevents is (at most) a one-trick channel - // (a) a child event happens (no error) - // (b) the embedded client is shutting down (zk.ErrClosing) - // (c) the zk session expires (zk.ErrSessionExpired) - select { - case <-zkc.shouldStop: - return - case e, ok := <-zkevents: - if !ok { - log.Warningf("expected a single zk event before channel close") - break // the select - } - switch e.Type { - //TODO(jdef) should we not also watch for EventNode{Created,Deleted,DataChanged}? - case zk.EventNodeChildrenChanged: - log.V(2).Infoln("Handling: zk.EventNodeChildrenChanged") - watcher(zkc, e.Path) - continue - default: - if e.Err != nil { - zkc.errorHandler(zkc, e.Err) - if e.Type == zk.EventNotWatching && e.State == zk.StateDisconnected { - if e.Err == zk.ErrClosing { - log.V(1).Infof("watch invalidated, embedded client terminating") - return - } - log.V(1).Infof("watch invalidated, attempting to watch again: %v", e.Err) - } else { - log.Warningf("received error while watching path %s: %s", watchPath, e.Err.Error()) - } - } - } - } - } -} - -func (zkc *Client) onDisconnected() { - if st := zkc.getState(); st == connectedState && zkc.stateChange(st, disconnectedState) { - log.Infoln("disconnected from the server, reconnecting...") - zkc.requestReconnect() - return - } -} - -// return a channel that gets an empty struct every time a connection happens -func (zkc *Client) connections() <-chan struct{} { - return zkc.hasConnected -} - -func (zkc *Client) getState() stateType { - return stateType(atomic.LoadInt32((*int32)(&zkc.state))) -} - -// convenience function -func (zkc *Client) isConnected() bool { - return zkc.getState() == connectedState -} - -// convenience function -func (zkc *Client) isConnecting() bool { - state := zkc.getState() - return state == connectionRequestedState || state == connectionAttemptState -} - -// convenience function -func (zkc *Client) isDisconnected() bool { - return zkc.getState() == disconnectedState -} - -func (zkc *Client) list(path string) ([]string, error) { - if !zkc.isConnected() { - return nil, errors.New("Unable to list children, client not connected.") - } - - children, _, err := zkc.conn.Children(path) - if err != nil { - return nil, err - } - - return children, nil -} - -func (zkc *Client) data(path string) ([]byte, error) { - if !zkc.isConnected() { - return nil, errors.New("Unable to retrieve node data, client not connected.") - } - - data, _, err := zkc.conn.Get(path) - if err != nil { - return nil, err - } - - return data, nil -} - -func (zkc *Client) stop() { - zkc.stopOnce.Do(func() { - close(zkc.shouldStop) - }) -} - -// when this channel is closed the client is either stopping, or has stopped -func (zkc *Client) stopped() <-chan struct{} { - return zkc.shouldStop -} diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client2.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client2.go new file mode 100644 index 000000000000..8d3799a08139 --- /dev/null +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client2.go @@ -0,0 +1,88 @@ +package zoo + +import ( + "sync" + "time" + + "github.com/samuel/go-zookeeper/zk" +) + +const ( + defaultSessionTimeout = 60 * time.Second + currentPath = "." +) + +var zkSessionTimeout = defaultSessionTimeout + +type client2 struct { + *zk.Conn + path string + done chan struct{} // signal chan, closes when the underlying connection terminates + stopOnce sync.Once +} + +func connect2(hosts []string, path string) (*client2, error) { + c, ev, err := zk.Connect(hosts, zkSessionTimeout) + if err != nil { + return nil, err + } + done := make(chan struct{}) + go func() { + // close the 'done' chan when the zk event chan closes (signals termination of zk connection) + defer close(done) + for { + if _, ok := <-ev; !ok { + return + } + } + }() + return &client2{ + Conn: c, + path: path, + done: done, + }, nil +} + +func (c *client2) stopped() <-chan struct{} { + return c.done +} + +func (c *client2) stop() { + c.stopOnce.Do(c.Close) +} + +func (c *client2) data(path string) (data []byte, err error) { + data, _, err = c.Get(path) + return +} + +func (c *client2) watchChildren(path string) (string, <-chan []string, <-chan error) { + errCh := make(chan error, 1) + snap := make(chan []string) + + watchPath := c.path + if path != "" && path != currentPath { + watchPath = watchPath + path + } + go func() { + defer close(errCh) + for { + children, _, ev, err := c.ChildrenW(watchPath) + if err != nil { + errCh <- err + return + } + select { + case snap <- children: + case <-c.done: + return + } + e := <-ev // wait for the next watch-related event + if e.Err != nil { + errCh <- e.Err + return + } + } + }() + return watchPath, snap, errCh +} diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client_test.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client_test.go deleted file mode 100644 index 1ebca734b36e..000000000000 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/client_test.go +++ /dev/null @@ -1,342 +0,0 @@ -package zoo - -import ( - "errors" - "fmt" - "os" - "strings" - "sync/atomic" - "testing" - "time" - - "github.com/gogo/protobuf/proto" - log "github.com/golang/glog" - util "github.com/mesos/mesos-go/mesosutil" - "github.com/samuel/go-zookeeper/zk" - "github.com/stretchr/testify/assert" -) - -var test_zk_hosts = []string{"localhost:2181"} - -const ( - test_zk_path = "/test" -) - -func TestClientNew(t *testing.T) { - path := "/mesos" - chEvent := make(chan zk.Event) - connector := makeMockConnector(path, chEvent) - - c, err := newClient(test_zk_hosts, path) - assert.NoError(t, err) - assert.NotNil(t, c) - assert.False(t, c.isConnected()) - c.conn = connector - -} - -// This test requires zookeeper to be running. -// You must also set env variable ZK_HOSTS to point to zk hosts. -// The zk package does not offer a way to mock its connection function. -func TestClientConnectIntegration(t *testing.T) { - if os.Getenv("ZK_HOSTS") == "" { - t.Skip("Skipping zk-server connection test: missing env ZK_HOSTS.") - } - hosts := strings.Split(os.Getenv("ZK_HOSTS"), ",") - c, err := newClient(hosts, "/mesos") - assert.NoError(t, err) - c.errorHandler = ErrorHandler(func(c *Client, e error) { - err = e - }) - c.connect() - assert.NoError(t, err) - - c.connect() - assert.NoError(t, err) - assert.True(t, c.isConnected()) -} - -func TestClientConnect(t *testing.T) { - c, err := makeClient() - assert.NoError(t, err) - assert.False(t, c.isConnected()) - c.connect() - assert.True(t, c.isConnected()) - assert.False(t, c.isConnecting()) -} - -func TestClient_FlappingConnection(t *testing.T) { - c, err := newClient(test_zk_hosts, test_zk_path) - c.reconnDelay = 10 * time.Millisecond // we don't want this test to take forever - defer c.stop() - - assert.NoError(t, err) - - attempts := 0 - c.setFactory(asFactory(func() (Connector, <-chan zk.Event, error) { - log.V(2).Infof("**** Using zk.Conn adapter ****") - ch0 := make(chan zk.Event, 10) // session chan - ch1 := make(chan zk.Event) // watch chan - go func() { - if attempts > 1 { - t.Fatalf("only one connector instance is expected") - } - attempts++ - for i := 0; i < 4; i++ { - ch0 <- zk.Event{ - Type: zk.EventSession, - State: zk.StateConnecting, - Path: test_zk_path, - } - ch0 <- zk.Event{ - Type: zk.EventSession, - State: zk.StateConnected, - Path: test_zk_path, - } - time.Sleep(200 * time.Millisecond) - ch0 <- zk.Event{ - Type: zk.EventSession, - State: zk.StateDisconnected, - Path: test_zk_path, - } - } - }() - connector := makeMockConnector(test_zk_path, ch1) - return connector, ch0, nil - })) - - go c.connect() - time.Sleep(2 * time.Second) - assert.True(t, c.isConnected()) - assert.Equal(t, 1, attempts) -} - -func TestClientWatchChildren(t *testing.T) { - c, err := makeClient() - assert.NoError(t, err) - c.errorHandler = ErrorHandler(func(c *Client, e error) { - err = e - }) - c.connect() - assert.NoError(t, err) - wCh := make(chan struct{}, 1) - childrenWatcher := ChildWatcher(func(zkc *Client, path string) { - log.V(4).Infoln("Path", path, "changed!") - children, err := c.list(path) - assert.NoError(t, err) - assert.Equal(t, 3, len(children)) - assert.Equal(t, "info_0", children[0]) - assert.Equal(t, "info_5", children[1]) - assert.Equal(t, "info_10", children[2]) - wCh <- struct{}{} - }) - - _, err = c.watchChildren(currentPath, childrenWatcher) - assert.NoError(t, err) - - select { - case <-wCh: - case <-time.After(time.Millisecond * 700): - panic("Waited too long...") - } -} - -func TestClientWatchErrors(t *testing.T) { - path := "/test" - ch := make(chan zk.Event, 1) - ch <- zk.Event{ - Type: zk.EventNotWatching, - Err: errors.New("Event Error"), - } - - c, err := makeClient() - c.state = connectedState - - assert.NoError(t, err) - c.conn = makeMockConnector(path, (<-chan zk.Event)(ch)) - wCh := make(chan struct{}, 1) - c.errorHandler = ErrorHandler(func(zkc *Client, err error) { - assert.Error(t, err) - wCh <- struct{}{} - }) - - c.watchChildren(currentPath, ChildWatcher(func(*Client, string) {})) - - select { - case <-wCh: - case <-time.After(time.Millisecond * 700): - t.Fatalf("timed out waiting for error message") - } - -} - -func TestWatchChildren_flappy(t *testing.T) { - c, err := newClient(test_zk_hosts, test_zk_path) - c.reconnDelay = 10 * time.Millisecond // we don't want this test to take forever - - assert.NoError(t, err) - - attempts := 0 - conn := NewMockConnector() - defer func() { - if !t.Failed() { - conn.AssertExpectations(t) - } - }() - defer func() { - // stop client and give it time to shut down the connector - c.stop() - time.Sleep(100 * time.Millisecond) - }() - c.setFactory(asFactory(func() (Connector, <-chan zk.Event, error) { - log.V(2).Infof("**** Using zk.Conn adapter ****") - ch0 := make(chan zk.Event, 10) // session chan - ch1 := make(chan zk.Event) // watch chan - go func() { - if attempts > 1 { - t.Fatalf("only one connector instance is expected") - } - attempts++ - for i := 0; i < 4; i++ { - ch0 <- zk.Event{ - Type: zk.EventSession, - State: zk.StateConnecting, - Path: test_zk_path, - } - ch0 <- zk.Event{ - Type: zk.EventSession, - State: zk.StateConnected, - Path: test_zk_path, - } - time.Sleep(200 * time.Millisecond) - ch0 <- zk.Event{ - Type: zk.EventSession, - State: zk.StateDisconnected, - Path: test_zk_path, - } - } - ch0 <- zk.Event{ - Type: zk.EventSession, - State: zk.StateConnecting, - Path: test_zk_path, - } - ch0 <- zk.Event{ - Type: zk.EventSession, - State: zk.StateConnected, - Path: test_zk_path, - } - ch1 <- zk.Event{ - Type: zk.EventNodeChildrenChanged, - Path: test_zk_path, - } - }() - simulatedErr := errors.New("simulated watch error") - conn.On("ChildrenW", test_zk_path).Return(nil, nil, nil, simulatedErr).Times(4) - conn.On("ChildrenW", test_zk_path).Return([]string{test_zk_path}, &zk.Stat{}, (<-chan zk.Event)(ch1), nil) - conn.On("Close").Return(nil) - return conn, ch0, nil - })) - - go c.connect() - var watchChildrenCount uint64 - watcherFunc := ChildWatcher(func(zkc *Client, path string) { - log.V(1).Infof("ChildWatcher invoked %d", atomic.LoadUint64(&watchChildrenCount)) - }) - startTime := time.Now() - endTime := startTime.Add(2 * time.Second) -watcherLoop: - for time.Now().Before(endTime) { - log.V(1).Infof("entered watcherLoop") - select { - case <-c.connections(): - log.V(1).Infof("invoking watchChildren") - if _, err := c.watchChildren(currentPath, watcherFunc); err == nil { - // watching children succeeded!! - t.Logf("child watch success") - atomic.AddUint64(&watchChildrenCount, 1) - } else { - // setting the watch failed - t.Logf("setting child watch failed: %v", err) - continue watcherLoop - } - case <-c.stopped(): - t.Logf("detected client termination") - break watcherLoop - case <-time.After(endTime.Sub(time.Now())): - } - } - - wantChildrenCount := atomic.LoadUint64(&watchChildrenCount) - assert.Equal(t, uint64(5), wantChildrenCount, "expected watchChildrenCount = 5 instead of %d, should be reinvoked upon initial ChildrenW failures", wantChildrenCount) -} - -func makeClient() (*Client, error) { - ch0 := make(chan zk.Event, 2) - ch1 := make(chan zk.Event, 1) - - ch0 <- zk.Event{ - State: zk.StateConnected, - Path: test_zk_path, - } - ch1 <- zk.Event{ - Type: zk.EventNodeChildrenChanged, - Path: test_zk_path, - } - go func() { - time.Sleep(1 * time.Second) - ch0 <- zk.Event{ - State: zk.StateDisconnected, - } - close(ch0) - close(ch1) - }() - - c, err := newClient(test_zk_hosts, test_zk_path) - if err != nil { - return nil, err - } - - // only allow a single connection - first := true - c.setFactory(asFactory(func() (Connector, <-chan zk.Event, error) { - if !first { - return nil, nil, errors.New("only a single connection attempt allowed for mock connector") - } else { - first = false - } - log.V(2).Infof("**** Using zk.Conn adapter ****") - connector := makeMockConnector(test_zk_path, ch1) - return connector, ch0, nil - })) - - return c, nil -} - -func makeMockConnector(path string, chEvent <-chan zk.Event) *MockConnector { - log.V(2).Infoln("Making Connector mock.") - conn := NewMockConnector() - conn.On("Close").Return(nil) - conn.On("ChildrenW", path).Return([]string{path}, &zk.Stat{}, chEvent, nil) - conn.On("Children", path).Return([]string{"info_0", "info_5", "info_10"}, &zk.Stat{}, nil) - conn.On("Get", fmt.Sprintf("%s/info_0", path)).Return(makeTestMasterInfo(), &zk.Stat{}, nil) - - return conn -} - -func newTestMasterInfo(id int) []byte { - miPb := util.NewMasterInfo(fmt.Sprintf("master(%d)@localhost:5050", id), 123456789, 400) - data, err := proto.Marshal(miPb) - if err != nil { - panic(err) - } - return data -} - -func makeTestMasterInfo() []byte { - miPb := util.NewMasterInfo("master@localhost:5050", 123456789, 400) - data, err := proto.Marshal(miPb) - if err != nil { - panic(err) - } - return data -} diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/detect.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/detect.go index 48eee4b41401..aca08fe4b2aa 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/detect.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/detect.go @@ -19,6 +19,7 @@ package zoo import ( + "encoding/json" "fmt" "math" "net/url" @@ -37,25 +38,37 @@ import ( const ( // prefix for nodes listed at the ZK URL path nodePrefix = "info_" + nodeJSONPrefix = "json.info_" defaultMinDetectorCyclePeriod = 1 * time.Second ) // reasonable default for a noop change listener var ignoreChanged = detector.OnMasterChanged(func(*mesos.MasterInfo) {}) +type zkInterface interface { + stopped() <-chan struct{} + stop() + data(string) ([]byte, error) + watchChildren(string) (string, <-chan []string, <-chan error) +} + +type infoCodec func(path, node string) (*mesos.MasterInfo, error) + // Detector uses ZooKeeper to detect new leading master. type MasterDetector struct { - client *Client + client zkInterface leaderNode string - // for one-time zk client initiation - bootstrap sync.Once + bootstrapLock sync.RWMutex // guard against concurrent invocations of bootstrapFunc + bootstrapFunc func() error // for one-time zk client initiation // latch: only install, at most, one ignoreChanged listener; see MasterDetector.Detect ignoreInstalled int32 // detection should not signal master change listeners more frequently than this minDetectorCyclePeriod time.Duration + done chan struct{} + cancel func() } // Internal constructor function @@ -66,17 +79,20 @@ func NewMasterDetector(zkurls string) (*MasterDetector, error) { return nil, err } - client, err := newClient(zkHosts, zkPath) - if err != nil { - return nil, err - } - detector := &MasterDetector{ - client: client, minDetectorCyclePeriod: defaultMinDetectorCyclePeriod, + done: make(chan struct{}), + cancel: func() {}, } - log.V(2).Infoln("Created new detector, watching ", zkHosts, zkPath) + detector.bootstrapFunc = func() (err error) { + if detector.client == nil { + detector.client, err = connect2(zkHosts, zkPath) + } + return + } + + log.V(2).Infoln("Created new detector to watch", zkHosts, zkPath) return detector, nil } @@ -94,42 +110,35 @@ func parseZk(zkurls string) ([]string, string, error) { // returns a chan that, when closed, indicates termination of the detector func (md *MasterDetector) Done() <-chan struct{} { - return md.client.stopped() + return md.done } func (md *MasterDetector) Cancel() { - md.client.stop() + md.bootstrapLock.RLock() + defer md.bootstrapLock.RUnlock() + md.cancel() } -//TODO(jdef) execute async because we don't want to stall our client's event loop? if so -//then we also probably want serial event delivery (aka. delivery via a chan) but then we -//have to deal with chan buffer sizes .. ugh. This is probably the least painful for now. -func (md *MasterDetector) childrenChanged(zkc *Client, path string, obs detector.MasterChanged) { - log.V(2).Infof("fetching children at path '%v'", path) - list, err := zkc.list(path) - if err != nil { - log.Warning(err) - return - } - +func (md *MasterDetector) childrenChanged(path string, list []string, obs detector.MasterChanged) { md.notifyMasterChanged(path, list, obs) md.notifyAllMasters(path, list, obs) } func (md *MasterDetector) notifyMasterChanged(path string, list []string, obs detector.MasterChanged) { - topNode := selectTopNode(list) + // mesos v0.24 writes JSON only, v0.23 writes json and protobuf, v0.22 and prior only write protobuf + topNode, codec := md.selectTopNode(list) if md.leaderNode == topNode { log.V(2).Infof("ignoring children-changed event, leader has not changed: %v", path) return } - log.V(2).Infof("changing leader node from %s -> %s", md.leaderNode, topNode) + log.V(2).Infof("changing leader node from %q -> %q", md.leaderNode, topNode) md.leaderNode = topNode var masterInfo *mesos.MasterInfo if md.leaderNode != "" { var err error - if masterInfo, err = md.pullMasterInfo(path, topNode); err != nil { + if masterInfo, err = codec(path, topNode); err != nil { log.Errorln(err.Error()) } } @@ -156,7 +165,21 @@ func (md *MasterDetector) pullMasterInfo(path, node string) (*mesos.MasterInfo, masterInfo := &mesos.MasterInfo{} err = proto.Unmarshal(data, masterInfo) if err != nil { - return nil, fmt.Errorf("failed to unmarshall MasterInfo data from zookeeper: %v", err) + return nil, fmt.Errorf("failed to unmarshal protobuf MasterInfo data from zookeeper: %v", err) + } + return masterInfo, nil +} + +func (md *MasterDetector) pullMasterJsonInfo(path, node string) (*mesos.MasterInfo, error) { + data, err := md.client.data(fmt.Sprintf("%s/%s", path, node)) + if err != nil { + return nil, fmt.Errorf("failed to retrieve leader data: %v", err) + } + + masterInfo := &mesos.MasterInfo{} + err = json.Unmarshal(data, masterInfo) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal json MasterInfo data from zookeeper: %v", err) } return masterInfo, nil } @@ -167,18 +190,52 @@ func (md *MasterDetector) notifyAllMasters(path string, list []string, obs detec // not interested in entire master list return } - masters := []*mesos.MasterInfo{} - for _, node := range list { - info, err := md.pullMasterInfo(path, node) + + // mesos v0.24 writes JSON only, v0.23 writes json and protobuf, v0.22 and prior only write protobuf + masters := map[string]*mesos.MasterInfo{} + tryStore := func(node string, codec infoCodec) { + info, err := codec(path, node) if err != nil { log.Errorln(err.Error()) } else { - masters = append(masters, info) + masters[info.GetId()] = info } } + for _, node := range list { + // compare https://github.com/apache/mesos/blob/0.23.0/src/master/detector.cpp#L437 + if strings.HasPrefix(node, nodePrefix) { + tryStore(node, md.pullMasterInfo) + } else if strings.HasPrefix(node, nodeJSONPrefix) { + tryStore(node, md.pullMasterJsonInfo) + } else { + continue + } + } + masterList := make([]*mesos.MasterInfo, 0, len(masters)) + for _, v := range masters { + masterList = append(masterList, v) + } - log.V(2).Infof("notifying of master membership change: %+v", masters) - logPanic(func() { all.UpdatedMasters(masters) }) + log.V(2).Infof("notifying of master membership change: %+v", masterList) + logPanic(func() { all.UpdatedMasters(masterList) }) +} + +func (md *MasterDetector) callBootstrap() (e error) { + log.V(2).Infoln("invoking detector boostrap") + md.bootstrapLock.Lock() + defer md.bootstrapLock.Unlock() + + clientConfigured := md.client != nil + if e = md.bootstrapFunc(); e == nil && !clientConfigured && md.client != nil { + // chain the lifetime of this detector to that of the newly created client impl + client := md.client + md.cancel = client.stop + go func() { + defer close(md.done) + <-client.stopped() + }() + } + return } // the first call to Detect will kickstart a connection to zookeeper. a nil change listener may @@ -187,70 +244,111 @@ func (md *MasterDetector) notifyAllMasters(path string, list []string, obs detec // once, and each time the spec'd listener will be added to the list of those receiving notifications. func (md *MasterDetector) Detect(f detector.MasterChanged) (err error) { // kickstart zk client connectivity - md.bootstrap.Do(func() { go md.client.connect() }) + if err := md.callBootstrap(); err != nil { + log.V(3).Infoln("failed to execute bootstrap function", err.Error()) + return err + } if f == nil { // only ever install, at most, one ignoreChanged listener. multiple instances of it // just consume resources and generate misleading log messages. if !atomic.CompareAndSwapInt32(&md.ignoreInstalled, 0, 1) { + log.V(3).Infoln("ignoreChanged listener already installed") return } f = ignoreChanged } + log.V(3).Infoln("spawning detect()") go md.detect(f) return nil } func (md *MasterDetector) detect(f detector.MasterChanged) { + log.V(3).Infoln("detecting children at", currentPath) detectLoop: for { - started := time.Now() select { case <-md.Done(): return - case <-md.client.connections(): - // we let the golang runtime manage our listener list for us, in form of goroutines that - // callback to the master change notification listen func's - if watchEnded, err := md.client.watchChildren(currentPath, ChildWatcher(func(zkc *Client, path string) { - md.childrenChanged(zkc, path, f) - })); err == nil { - log.V(2).Infoln("detector listener installed") + default: + } + log.V(3).Infoln("watching children at", currentPath) + path, childrenCh, errCh := md.client.watchChildren(currentPath) + rewatch := false + for { + started := time.Now() + select { + case children := <-childrenCh: + md.childrenChanged(path, children, f) + case err, ok := <-errCh: + // check for a tie first (required for predictability (tests)); the downside of + // doing this is that a listener might get two callbacks back-to-back ("new leader", + // followed by "no leader"). select { - case <-watchEnded: + case children := <-childrenCh: + md.childrenChanged(path, children, f) + default: + } + if ok { + log.V(1).Infoln("child watch ended with error, master lost; error was:", err.Error()) + } else { + // detector shutdown likely... + log.V(1).Infoln("child watch ended, master lost") + } + select { + case <-md.Done(): + return + default: if md.leaderNode != "" { - log.V(1).Infof("child watch ended, signaling master lost") + log.V(2).Infof("changing leader node from %q -> \"\"", md.leaderNode) md.leaderNode = "" f.OnMasterChanged(nil) } - case <-md.client.stopped(): + } + rewatch = true + } + // rate-limit master changes + if elapsed := time.Now().Sub(started); elapsed > 0 { + log.V(2).Infoln("resting before next detection cycle") + select { + case <-md.Done(): return + case <-time.After(md.minDetectorCyclePeriod - elapsed): // noop } - } else { - log.V(1).Infof("child watch ended with error: %v", err) + } + if rewatch { continue detectLoop } } - // rate-limit master changes - if elapsed := time.Now().Sub(started); elapsed > 0 { - log.V(2).Infoln("resting before next detection cycle") - select { - case <-md.Done(): - return - case <-time.After(md.minDetectorCyclePeriod - elapsed): // noop - } + } +} + +func (md *MasterDetector) selectTopNode(list []string) (topNode string, codec infoCodec) { + // mesos v0.24 writes JSON only, v0.23 writes json and protobuf, v0.22 and prior only write protobuf + topNode = selectTopNodePrefix(list, nodeJSONPrefix) + codec = md.pullMasterJsonInfo + if topNode == "" { + topNode = selectTopNodePrefix(list, nodePrefix) + codec = md.pullMasterInfo + + if topNode != "" { + log.Warningf("Leading master is using a Protobuf binary format when registering "+ + "with Zookeeper (%s): this will be deprecated as of Mesos 0.24 (see MESOS-2340).", + topNode) } } + return } -func selectTopNode(list []string) (node string) { +func selectTopNodePrefix(list []string, pre string) (node string) { var leaderSeq uint64 = math.MaxUint64 for _, v := range list { - if !strings.HasPrefix(v, nodePrefix) { + if !strings.HasPrefix(v, pre) { continue // only care about participants } - seqStr := strings.TrimPrefix(v, nodePrefix) + seqStr := strings.TrimPrefix(v, pre) seq, err := strconv.ParseUint(seqStr, 10, 64) if err != nil { log.Warningf("unexpected zk node format '%s': %v", seqStr, err) diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/detect_test.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/detect_test.go index de1ce9762a97..863e7caa3b35 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/detect_test.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/detect_test.go @@ -1,9 +1,7 @@ package zoo import ( - "errors" "fmt" - "sort" "sync" "testing" "time" @@ -12,14 +10,16 @@ import ( log "github.com/golang/glog" "github.com/mesos/mesos-go/detector" mesos "github.com/mesos/mesos-go/mesosproto" + util "github.com/mesos/mesos-go/mesosutil" "github.com/samuel/go-zookeeper/zk" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) const ( - zkurl = "zk://127.0.0.1:2181/mesos" - zkurl_bad = "zk://127.0.0.1:2181" + zkurl = "zk://127.0.0.1:2181/mesos" + zkurl_bad = "zk://127.0.0.1:2181" + test_zk_path = "/test" ) func TestParseZk_single(t *testing.T) { @@ -43,361 +43,299 @@ func TestParseZk_multiIP(t *testing.T) { assert.Equal(t, "/mesos", path) } -func TestMasterDetectorStart(t *testing.T) { - c, err := makeClient() - assert.False(t, c.isConnected()) - md, err := NewMasterDetector(zkurl) - defer md.Cancel() - assert.NoError(t, err) - c.errorHandler = ErrorHandler(func(c *Client, e error) { - err = e - }) - md.client = c // override zk.Conn with our own. - md.client.connect() - assert.NoError(t, err) - assert.True(t, c.isConnected()) +type mockZkClient struct { + mock.Mock } -func TestMasterDetectorChildrenChanged(t *testing.T) { - wCh := make(chan struct{}, 1) +func (m *mockZkClient) stopped() (a <-chan struct{}) { + args := m.Called() + if x := args.Get(0); x != nil { + a = x.(<-chan struct{}) + } + return +} - c, err := makeClient() - assert.NoError(t, err) - assert.False(t, c.isConnected()) +func (m *mockZkClient) stop() { + m.Called() +} + +func (m *mockZkClient) data(path string) (a []byte, b error) { + args := m.Called(path) + if x := args.Get(0); x != nil { + a = x.([]byte) + } + b = args.Error(1) + return +} +func (m *mockZkClient) watchChildren(path string) (a string, b <-chan []string, c <-chan error) { + args := m.Called(path) + a = args.String(0) + if x := args.Get(1); x != nil { + b = x.(<-chan []string) + } + if x := args.Get(2); x != nil { + c = x.(<-chan error) + } + return +} + +// newMockZkClient returns a mocked implementation of zkInterface that implements expectations +// for stop() and stopped(); multiple calls to stop() are safe. +func newMockZkClient(initialChildren ...string) (mocked *mockZkClient, snaps chan []string, errs chan error) { + var doneOnce sync.Once + done := make(chan struct{}) + + mocked = &mockZkClient{} + mocked.On("stop").Return().Run(func(_ mock.Arguments) { doneOnce.Do(func() { close(done) }) }) + mocked.On("stopped").Return((<-chan struct{})(done)) + + if initialChildren != nil { + errs = make(chan error) // this is purposefully unbuffered (some tests depend on this) + snaps = make(chan []string, 1) + snaps <- initialChildren[:] + mocked.On("watchChildren", currentPath).Return( + test_zk_path, (<-chan []string)(snaps), (<-chan error)(errs)).Run( + func(_ mock.Arguments) { log.V(1).Infoln("watchChildren invoked") }) + } + return +} + +func newTestMasterInfo(id int) []byte { + miPb := util.NewMasterInfo(fmt.Sprintf("master(%d)@localhost:5050", id), 123456789, 400) + data, err := proto.Marshal(miPb) + if err != nil { + panic(err) + } + return data +} + +func TestMasterDetectorChildrenChanged(t *testing.T) { md, err := NewMasterDetector(zkurl) defer md.Cancel() assert.NoError(t, err) - // override zk.Conn with our own. - c.errorHandler = ErrorHandler(func(c *Client, e error) { - err = e - }) - md.client = c - md.client.connect() - assert.NoError(t, err) - assert.True(t, c.isConnected()) + + path := test_zk_path + snapDetected := make(chan struct{}) + md.bootstrapFunc = func() error { + if md.client != nil { + return nil + } + log.V(1).Infoln("bootstrapping detector") + defer log.V(1).Infoln("bootstrapping detector ..finished") + + mocked, _, errs := newMockZkClient("info_0", "info_5", "info_10") + md.client = mocked + md.minDetectorCyclePeriod = 10 * time.Millisecond // we don't have all day! + + mocked.On("data", fmt.Sprintf("%s/info_0", path)).Return(newTestMasterInfo(0), nil) + + // wait for the first child snapshot to be processed before signaling end-of-watch + // (which is signalled by closing errs). + go func() { + defer close(errs) + select { + case <-snapDetected: + case <-md.Done(): + t.Errorf("detector died before child snapshot") + } + }() + return nil + } called := 0 - md.Detect(detector.OnMasterChanged(func(master *mesos.MasterInfo) { + lostMaster := make(chan struct{}) + const expectedLeader = "master(0)@localhost:5050" + err = md.Detect(detector.OnMasterChanged(func(master *mesos.MasterInfo) { //expect 2 calls in sequence: the first setting a master //and the second clearing it switch called++; called { case 1: + defer close(snapDetected) assert.NotNil(t, master) - assert.Equal(t, master.GetId(), "master@localhost:5050") - wCh <- struct{}{} + assert.Equal(t, expectedLeader, master.GetId()) case 2: + md.Cancel() + defer close(lostMaster) assert.Nil(t, master) - wCh <- struct{}{} default: - t.Fatalf("unexpected notification call attempt %d", called) + t.Errorf("unexpected notification call attempt %d", called) } })) + assert.NoError(t, err) + + fatalOn(t, 10*time.Second, lostMaster, "Waited too long for lost master") - startWait := time.Now() select { - case <-wCh: - case <-time.After(time.Second * 3): - panic("Waited too long...") + case <-md.Done(): + assert.Equal(t, 2, called, "expected 2 detection callbacks instead of %d", called) + case <-time.After(time.Second * 10): + panic("Waited too long for detector shutdown...") } - - // wait for the disconnect event, should be triggered - // 1s after the connected event - waited := time.Now().Sub(startWait) - time.Sleep((2 * time.Second) - waited) - assert.False(t, c.isConnected()) } -// single connector instance, session does not expire, but it's internal connection to zk is flappy -func TestMasterDetectFlappingConnectionState(t *testing.T) { - c, err := newClient(test_zk_hosts, test_zk_path) +// single connector instance, it's internal connection to zk is flappy +func TestMasterDetectorFlappyConnectionState(t *testing.T) { + md, err := NewMasterDetector(zkurl) + defer md.Cancel() assert.NoError(t, err) - initialChildren := []string{"info_005", "info_010", "info_022"} - connector := NewMockConnector() - connector.On("Close").Return(nil) - connector.On("Children", test_zk_path).Return(initialChildren, &zk.Stat{}, nil) - + const ITERATIONS = 3 var wg sync.WaitGroup - wg.Add(2) // async flapping, master change detection + wg.Add(1 + ITERATIONS) // +1 for the initial snapshot that's sent for the first watch + path := test_zk_path - first := true - c.setFactory(asFactory(func() (Connector, <-chan zk.Event, error) { - if !first { - t.Fatalf("only one connector instance expected") - return nil, nil, errors.New("ran out of connectors") - } else { - first = false + md.bootstrapFunc = func() error { + if md.client != nil { + return nil } - sessionEvents := make(chan zk.Event, 10) - watchEvents := make(chan zk.Event, 10) + log.V(1).Infoln("bootstrapping detector") + defer log.V(1).Infoln("bootstrapping detector ..finished") - connector.On("Get", fmt.Sprintf("%s/info_005", test_zk_path)).Return(newTestMasterInfo(1), &zk.Stat{}, nil).Once() - connector.On("ChildrenW", test_zk_path).Return([]string{test_zk_path}, &zk.Stat{}, (<-chan zk.Event)(watchEvents), nil) + children := []string{"info_0", "info_5", "info_10"} + mocked, snaps, errs := newMockZkClient(children...) + md.client = mocked + md.minDetectorCyclePeriod = 10 * time.Millisecond // we don't have all day! + + mocked.On("data", fmt.Sprintf("%s/info_0", path)).Return(newTestMasterInfo(0), nil) + + // the first snapshot will be sent immediately and the detector will be awaiting en event. + // cycle through some connected/disconnected events but maintain the same snapshot go func() { - defer wg.Done() - time.Sleep(100 * time.Millisecond) - for attempt := 0; attempt < 5; attempt++ { - sessionEvents <- zk.Event{ - Type: zk.EventSession, - State: zk.StateConnected, - } - time.Sleep(500 * time.Millisecond) - sessionEvents <- zk.Event{ - Type: zk.EventSession, - State: zk.StateDisconnected, - } - } - sessionEvents <- zk.Event{ - Type: zk.EventSession, - State: zk.StateConnected, + defer close(errs) + for attempt := 0; attempt < ITERATIONS; attempt++ { + // send an error, should cause the detector to re-issue a watch + errs <- zk.ErrSessionExpired + // the detection loop issues another watch, so send it a snapshot.. + // send another snapshot + snaps <- children } }() - return connector, sessionEvents, nil - })) - c.reconnDelay = 0 // there should be no reconnect, but just in case don't drag the test out - - md, err := NewMasterDetector(zkurl) - defer md.Cancel() - assert.NoError(t, err) - - c.errorHandler = ErrorHandler(func(c *Client, e error) { - t.Logf("zk client error: %v", e) - }) - md.client = c - - startTime := time.Now() - detected := false - md.Detect(detector.OnMasterChanged(func(master *mesos.MasterInfo) { - if detected { - t.Fatalf("already detected master, was not expecting another change: %v", master) - } else { - detected = true - assert.NotNil(t, master, fmt.Sprintf("on-master-changed %v", detected)) - t.Logf("Leader change detected at %v: '%+v'", time.Now().Sub(startTime), master) - wg.Done() - } - })) - - completed := make(chan struct{}) - go func() { - defer close(completed) - wg.Wait() - }() - - select { - case <-completed: // expected - case <-time.After(3 * time.Second): - t.Fatalf("failed to detect master change") + return nil } -} - -func TestMasterDetectFlappingConnector(t *testing.T) { - c, err := newClient(test_zk_hosts, test_zk_path) - assert.NoError(t, err) - - initialChildren := []string{"info_005", "info_010", "info_022"} - connector := NewMockConnector() - connector.On("Close").Return(nil) - connector.On("Children", test_zk_path).Return(initialChildren, &zk.Stat{}, nil) - - // timing - // t=0 t=400ms t=800ms t=1200ms t=1600ms t=2000ms t=2400ms - // |--=--=--=--|--=--=--=--|--=--=--=--|--=--=--=--|--=--=--=--|--=--=--=--|--=--=--=--|--=--=--=-- - // c1 d1 c3 d3 c5 d5 d6 ... - // c2 d2 c4 d4 c6 c7 ... - // M M' M M' M M' - attempt := 0 - c.setFactory(asFactory(func() (Connector, <-chan zk.Event, error) { - attempt++ - sessionEvents := make(chan zk.Event, 5) - watchEvents := make(chan zk.Event, 5) - - sessionEvents <- zk.Event{ - Type: zk.EventSession, - State: zk.StateConnected, - } - connector.On("Get", fmt.Sprintf("%s/info_005", test_zk_path)).Return(newTestMasterInfo(attempt), &zk.Stat{}, nil).Once() - connector.On("ChildrenW", test_zk_path).Return([]string{test_zk_path}, &zk.Stat{}, (<-chan zk.Event)(watchEvents), nil) - go func(attempt int) { - defer close(sessionEvents) - defer close(watchEvents) - time.Sleep(400 * time.Millisecond) - // this is the order in which the embedded zk implementation does it - sessionEvents <- zk.Event{ - Type: zk.EventSession, - State: zk.StateDisconnected, - } - connector.On("ChildrenW", test_zk_path).Return(nil, nil, nil, zk.ErrSessionExpired).Once() - watchEvents <- zk.Event{ - Type: zk.EventNotWatching, - State: zk.StateDisconnected, - Path: test_zk_path, - Err: zk.ErrSessionExpired, + called := 0 + lostMaster := make(chan struct{}) + const EXPECTED_CALLS = (ITERATIONS * 2) + 2 // +1 for initial snapshot, +1 for final lost-leader (close(errs)) + err = md.Detect(detector.OnMasterChanged(func(master *mesos.MasterInfo) { + called++ + log.V(3).Infof("detector invoked: called %d", called) + switch { + case called < EXPECTED_CALLS: + if master != nil { + wg.Done() + assert.Equal(t, master.GetId(), "master(0)@localhost:5050") } - }(attempt) - return connector, sessionEvents, nil - })) - c.reconnDelay = 100 * time.Millisecond - c.rewatchDelay = c.reconnDelay / 2 - - md, err := NewMasterDetector(zkurl) - md.minDetectorCyclePeriod = 600 * time.Millisecond - - defer md.Cancel() - assert.NoError(t, err) - - c.errorHandler = ErrorHandler(func(c *Client, e error) { - t.Logf("zk client error: %v", e) - }) - md.client = c - - var wg sync.WaitGroup - wg.Add(6) // 3 x (connected, disconnected) - detected := 0 - startTime := time.Now() - md.Detect(detector.OnMasterChanged(func(master *mesos.MasterInfo) { - if detected > 5 { - // ignore - return - } - if (detected & 1) == 0 { - assert.NotNil(t, master, fmt.Sprintf("on-master-changed-%d", detected)) - } else { - assert.Nil(t, master, fmt.Sprintf("on-master-changed-%d", detected)) + case called == EXPECTED_CALLS: + md.Cancel() + defer close(lostMaster) + assert.Nil(t, master) + default: + t.Errorf("unexpected notification call attempt %d", called) } - t.Logf("Leader change detected at %v: '%+v'", time.Now().Sub(startTime), master) - detected++ - wg.Done() })) + assert.NoError(t, err) - completed := make(chan struct{}) - go func() { - defer close(completed) - wg.Wait() - }() + fatalAfter(t, 10*time.Second, wg.Wait, "Waited too long for new-master alerts") + fatalOn(t, 3*time.Second, lostMaster, "Waited too long for lost master") select { - case <-completed: // expected - case <-time.After(3 * time.Second): - t.Fatalf("failed to detect flapping master changes") + case <-md.Done(): + assert.Equal(t, EXPECTED_CALLS, called, "expected %d detection callbacks instead of %d", EXPECTED_CALLS, called) + case <-time.After(time.Second * 10): + panic("Waited too long for detector shutdown...") } } -func TestMasterDetectMultiple(t *testing.T) { - ch0 := make(chan zk.Event, 5) - ch1 := make(chan zk.Event, 5) - - ch0 <- zk.Event{ - Type: zk.EventSession, - State: zk.StateConnected, - } - - c, err := newClient(test_zk_hosts, test_zk_path) - assert.NoError(t, err) - - initialChildren := []string{"info_005", "info_010", "info_022"} - connector := NewMockConnector() - connector.On("Close").Return(nil) - connector.On("Children", test_zk_path).Return(initialChildren, &zk.Stat{}, nil).Once() - connector.On("ChildrenW", test_zk_path).Return([]string{test_zk_path}, &zk.Stat{}, (<-chan zk.Event)(ch1), nil) - - first := true - c.setFactory(asFactory(func() (Connector, <-chan zk.Event, error) { - log.V(2).Infof("**** Using zk.Conn adapter ****") - if !first { - return nil, nil, errors.New("only 1 connector allowed") - } else { - first = false - } - return connector, ch0, nil - })) - +func TestMasterDetector_multipleLeadershipChanges(t *testing.T) { md, err := NewMasterDetector(zkurl) defer md.Cancel() assert.NoError(t, err) - c.errorHandler = ErrorHandler(func(c *Client, e error) { - err = e - }) - md.client = c - - // **** Test 4 consecutive ChildrenChangedEvents ****** - // setup event changes - sequences := [][]string{ + leadershipChanges := [][]string{ {"info_014", "info_010", "info_005"}, {"info_005", "info_004", "info_022"}, {}, // indicates no master {"info_017", "info_099", "info_200"}, } + ITERATIONS := len(leadershipChanges) + + // +1 for initial snapshot, +1 for final lost-leader (close(errs)) + EXPECTED_CALLS := (ITERATIONS + 2) + var wg sync.WaitGroup - startTime := time.Now() - detected := 0 - md.Detect(detector.OnMasterChanged(func(master *mesos.MasterInfo) { - if detected == 2 { - assert.Nil(t, master, fmt.Sprintf("on-master-changed-%d", detected)) - } else { - assert.NotNil(t, master, fmt.Sprintf("on-master-changed-%d", detected)) + wg.Add(ITERATIONS) // +1 for the initial snapshot that's sent for the first watch, -1 because set 3 is empty + path := test_zk_path + + md.bootstrapFunc = func() error { + if md.client != nil { + return nil } - t.Logf("Leader change detected at %v: '%+v'", time.Now().Sub(startTime), master) - detected++ - wg.Done() - })) + log.V(1).Infoln("bootstrapping detector") + defer log.V(1).Infoln("bootstrapping detector ..finished") - // 3 leadership changes + disconnect (leader change to '') - wg.Add(4) + children := []string{"info_0", "info_5", "info_10"} + mocked, snaps, errs := newMockZkClient(children...) + md.client = mocked + md.minDetectorCyclePeriod = 10 * time.Millisecond // we don't have all day! - go func() { - for i := range sequences { - sorted := make([]string, len(sequences[i])) - copy(sorted, sequences[i]) - sort.Strings(sorted) - t.Logf("testing master change sequence %d, path '%v'", i, test_zk_path) - connector.On("Children", test_zk_path).Return(sequences[i], &zk.Stat{}, nil).Once() - if len(sequences[i]) > 0 { - connector.On("Get", fmt.Sprintf("%s/%s", test_zk_path, sorted[0])).Return(newTestMasterInfo(i), &zk.Stat{}, nil).Once() + mocked.On("data", fmt.Sprintf("%s/info_0", path)).Return(newTestMasterInfo(0), nil) + mocked.On("data", fmt.Sprintf("%s/info_005", path)).Return(newTestMasterInfo(5), nil) + mocked.On("data", fmt.Sprintf("%s/info_004", path)).Return(newTestMasterInfo(4), nil) + mocked.On("data", fmt.Sprintf("%s/info_017", path)).Return(newTestMasterInfo(17), nil) + + // the first snapshot will be sent immediately and the detector will be awaiting en event. + // cycle through some connected/disconnected events but maintain the same snapshot + go func() { + defer close(errs) + for attempt := 0; attempt < ITERATIONS; attempt++ { + snaps <- leadershipChanges[attempt] } - ch1 <- zk.Event{ - Type: zk.EventNodeChildrenChanged, - Path: test_zk_path, + }() + return nil + } + + called := 0 + lostMaster := make(chan struct{}) + expectedLeaders := []int{0, 5, 4, 17} + leaderIdx := 0 + err = md.Detect(detector.OnMasterChanged(func(master *mesos.MasterInfo) { + called++ + log.V(3).Infof("detector invoked: called %d", called) + switch { + case called < EXPECTED_CALLS: + if master != nil { + expectedLeader := fmt.Sprintf("master(%d)@localhost:5050", expectedLeaders[leaderIdx]) + assert.Equal(t, expectedLeader, master.GetId()) + leaderIdx++ + wg.Done() } - time.Sleep(100 * time.Millisecond) // give async routines time to catch up - } - time.Sleep(1 * time.Second) // give async routines time to catch up - t.Logf("disconnecting...") - ch0 <- zk.Event{ - State: zk.StateDisconnected, + case called == EXPECTED_CALLS: + md.Cancel() + defer close(lostMaster) + assert.Nil(t, master) + default: + t.Errorf("unexpected notification call attempt %d", called) } - //TODO(jdef) does order of close matter here? probably, meaking client code is weak - close(ch0) - time.Sleep(500 * time.Millisecond) // give async routines time to catch up - close(ch1) - }() - completed := make(chan struct{}) - go func() { - defer close(completed) - wg.Wait() - }() + })) + assert.NoError(t, err) - defer func() { - if r := recover(); r != nil { - t.Fatal(r) - } - }() + fatalAfter(t, 10*time.Second, wg.Wait, "Waited too long for new-master alerts") + fatalOn(t, 3*time.Second, lostMaster, "Waited too long for lost master") select { - case <-time.After(2 * time.Second): - panic("timed out waiting for master changes to propagate") - case <-completed: + case <-md.Done(): + assert.Equal(t, EXPECTED_CALLS, called, "expected %d detection callbacks instead of %d", EXPECTED_CALLS, called) + case <-time.After(time.Second * 10): + panic("Waited too long for detector shutdown...") } } func TestMasterDetect_selectTopNode_none(t *testing.T) { assert := assert.New(t) nodeList := []string{} - node := selectTopNode(nodeList) + node := selectTopNodePrefix(nodeList, "foo") assert.Equal("", node) } @@ -410,10 +348,25 @@ func TestMasterDetect_selectTopNode_0000x(t *testing.T) { "info_0000000061", "info_0000000008", } - node := selectTopNode(nodeList) + node := selectTopNodePrefix(nodeList, nodePrefix) assert.Equal("info_0000000008", node) } +func TestMasterDetect_selectTopNode_mixJson(t *testing.T) { + assert := assert.New(t) + nodeList := []string{ + nodePrefix + "0000000046", + nodePrefix + "0000000032", + nodeJSONPrefix + "0000000046", + nodeJSONPrefix + "0000000032", + } + node := selectTopNodePrefix(nodeList, nodeJSONPrefix) + assert.Equal(nodeJSONPrefix+"0000000032", node) + + node = selectTopNodePrefix(nodeList, nodePrefix) + assert.Equal(nodePrefix+"0000000032", node) +} + func TestMasterDetect_selectTopNode_mixedEntries(t *testing.T) { assert := assert.New(t) nodeList := []string{ @@ -424,7 +377,7 @@ func TestMasterDetect_selectTopNode_mixedEntries(t *testing.T) { "log_replicas_fdgwsdfgsdf", "bar", } - node := selectTopNode(nodeList) + node := selectTopNodePrefix(nodeList, nodePrefix) assert.Equal("info_0000000032", node) } @@ -451,15 +404,25 @@ func afterFunc(f func()) <-chan struct{} { } func fatalAfter(t *testing.T, d time.Duration, f func(), msg string, args ...interface{}) { - ch := afterFunc(f) + fatalOn(t, d, afterFunc(f), msg, args...) +} + +func fatalOn(t *testing.T, d time.Duration, ch <-chan struct{}, msg string, args ...interface{}) { select { case <-ch: return case <-time.After(d): - t.Fatalf(msg, args...) + // check for a tie + select { + case <-ch: + return + default: + t.Fatalf(msg, args...) + } } } +/* TODO(jdef) refactor this to work with the new zkInterface func TestNotifyAllMasters(t *testing.T) { c, err := newClient(test_zk_hosts, test_zk_path) assert.NoError(t, err) @@ -482,7 +445,7 @@ func TestNotifyAllMasters(t *testing.T) { assert.NoError(t, err) c.errorHandler = ErrorHandler(func(c *Client, e error) { - t.Fatalf("unexpected error: %v", e) + t.Errorf("unexpected error: %v", e) }) md.client = c @@ -562,3 +525,4 @@ func TestNotifyAllMasters(t *testing.T) { connector.On("Close").Return(nil) } +*/ diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/mocked_detect.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/mocked_detect.go deleted file mode 100644 index d887b6dc869f..000000000000 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/mocked_detect.go +++ /dev/null @@ -1,88 +0,0 @@ -package zoo - -import ( - "errors" - "fmt" - "net/url" - - "github.com/gogo/protobuf/proto" - log "github.com/golang/glog" - util "github.com/mesos/mesos-go/mesosutil" - "github.com/samuel/go-zookeeper/zk" -) - -type MockMasterDetector struct { - *MasterDetector - zkPath string - conCh chan zk.Event - sesCh chan zk.Event -} - -func NewMockMasterDetector(zkurls string) (*MockMasterDetector, error) { - log.V(4).Infoln("Creating mock zk master detector") - md, err := NewMasterDetector(zkurls) - if err != nil { - return nil, err - } - - u, _ := url.Parse(zkurls) - m := &MockMasterDetector{ - MasterDetector: md, - zkPath: u.Path, - conCh: make(chan zk.Event, 5), - sesCh: make(chan zk.Event, 5), - } - - path := m.zkPath - connector := NewMockConnector() - connector.On("Children", path).Return([]string{"info_0", "info_5", "info_10"}, &zk.Stat{}, nil) - connector.On("Get", fmt.Sprintf("%s/info_0", path)).Return(m.makeMasterInfo(), &zk.Stat{}, nil) - connector.On("Close").Return(nil) - connector.On("ChildrenW", m.zkPath).Return([]string{m.zkPath}, &zk.Stat{}, (<-chan zk.Event)(m.sesCh), nil) - - first := true - m.client.setFactory(asFactory(func() (Connector, <-chan zk.Event, error) { - if !first { - return nil, nil, errors.New("only 1 connector allowed") - } else { - first = false - } - return connector, m.conCh, nil - })) - - return m, nil -} - -func (m *MockMasterDetector) Start() { - m.client.connect() -} - -func (m *MockMasterDetector) ScheduleConnEvent(s zk.State) { - log.V(4).Infof("Scheduling zk connection event with state: %v\n", s) - go func() { - m.conCh <- zk.Event{ - State: s, - Path: m.zkPath, - } - }() -} - -func (m *MockMasterDetector) ScheduleSessEvent(t zk.EventType) { - log.V(4).Infof("Scheduling zk session event with state: %v\n", t) - go func() { - m.sesCh <- zk.Event{ - Type: t, - Path: m.zkPath, - } - }() -} - -func (m *MockMasterDetector) makeMasterInfo() []byte { - miPb := util.NewMasterInfo("master", 123456789, 400) - miPb.Pid = proto.String("master@127.0.0.1:5050") - data, err := proto.Marshal(miPb) - if err != nil { - panic(err) - } - return data -} diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/types.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/types.go index 811614042149..9b24b51b7cd7 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/types.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/detector/zoo/types.go @@ -14,12 +14,6 @@ type Connector interface { Get(string) ([]byte, *zk.Stat, error) } -// interface for handling watcher event when zk.EventNodeChildrenChanged. -type ChildWatcher func(*Client, string) - -// interface for handling errors (session and watch related). -type ErrorHandler func(*Client, error) - //Factory is an adapter to trap the creation of zk.Conn instances //since the official zk API does not expose an interface for zk.Conn. type Factory interface { diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.pb.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.pb.go new file mode 100644 index 000000000000..76bd7b3a9d14 --- /dev/null +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.pb.go @@ -0,0 +1,255 @@ +// Code generated by protoc-gen-gogo. +// source: authentication.proto +// DO NOT EDIT! + +/* + Package mesosproto is a generated protocol buffer package. + + It is generated from these files: + authentication.proto + containerizer.proto + internal.proto + log.proto + mesos.proto + messages.proto + registry.proto + scheduler.proto + state.proto + + It has these top-level messages: + AuthenticateMessage + AuthenticationMechanismsMessage + AuthenticationStartMessage + AuthenticationStepMessage + AuthenticationCompletedMessage + AuthenticationFailedMessage + AuthenticationErrorMessage + Launch + Update + Wait + Destroy + Usage + Termination + Containers + InternalMasterChangeDetected + InternalTryAuthentication + InternalAuthenticationResult + Promise + Action + Metadata + Record + PromiseRequest + PromiseResponse + WriteRequest + WriteResponse + LearnedMessage + RecoverRequest + RecoverResponse + FrameworkID + OfferID + SlaveID + TaskID + ExecutorID + ContainerID + FrameworkInfo + HealthCheck + CommandInfo + ExecutorInfo + MasterInfo + SlaveInfo + Value + Attribute + Resource + TrafficControlStatistics + ResourceStatistics + ResourceUsage + PerfStatistics + Request + Offer + TaskInfo + TaskStatus + Filters + Environment + Parameter + Parameters + Credential + Credentials + ACL + ACLs + RateLimit + RateLimits + Volume + ContainerInfo + Labels + Label + Port + Ports + DiscoveryInfo + Task + StatusUpdate + StatusUpdateRecord + SubmitSchedulerRequest + SubmitSchedulerResponse + ExecutorToFrameworkMessage + FrameworkToExecutorMessage + RegisterFrameworkMessage + ReregisterFrameworkMessage + FrameworkRegisteredMessage + FrameworkReregisteredMessage + UnregisterFrameworkMessage + DeactivateFrameworkMessage + ResourceRequestMessage + ResourceOffersMessage + LaunchTasksMessage + RescindResourceOfferMessage + ReviveOffersMessage + RunTaskMessage + KillTaskMessage + StatusUpdateMessage + StatusUpdateAcknowledgementMessage + LostSlaveMessage + ReconcileTasksMessage + FrameworkErrorMessage + RegisterSlaveMessage + ReregisterSlaveMessage + SlaveRegisteredMessage + SlaveReregisteredMessage + UnregisterSlaveMessage + MasterSlaveConnection + PingSlaveMessage + PongSlaveMessage + ShutdownFrameworkMessage + ShutdownExecutorMessage + UpdateFrameworkMessage + CheckpointResourcesMessage + UpdateSlaveMessage + RegisterExecutorMessage + ExecutorRegisteredMessage + ExecutorReregisteredMessage + ExitedExecutorMessage + ReconnectExecutorMessage + ReregisterExecutorMessage + ShutdownMessage + Archive + TaskHealthStatus + HookExecuted + Registry + Event + Call + Entry + Operation +*/ +package mesosproto + +import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +type AuthenticateMessage struct { + Pid *string `protobuf:"bytes,1,req,name=pid" json:"pid,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *AuthenticateMessage) Reset() { *m = AuthenticateMessage{} } +func (m *AuthenticateMessage) String() string { return proto.CompactTextString(m) } +func (*AuthenticateMessage) ProtoMessage() {} + +func (m *AuthenticateMessage) GetPid() string { + if m != nil && m.Pid != nil { + return *m.Pid + } + return "" +} + +type AuthenticationMechanismsMessage struct { + Mechanisms []string `protobuf:"bytes,1,rep,name=mechanisms" json:"mechanisms,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *AuthenticationMechanismsMessage) Reset() { *m = AuthenticationMechanismsMessage{} } +func (m *AuthenticationMechanismsMessage) String() string { return proto.CompactTextString(m) } +func (*AuthenticationMechanismsMessage) ProtoMessage() {} + +func (m *AuthenticationMechanismsMessage) GetMechanisms() []string { + if m != nil { + return m.Mechanisms + } + return nil +} + +type AuthenticationStartMessage struct { + Mechanism *string `protobuf:"bytes,1,req,name=mechanism" json:"mechanism,omitempty"` + Data []byte `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *AuthenticationStartMessage) Reset() { *m = AuthenticationStartMessage{} } +func (m *AuthenticationStartMessage) String() string { return proto.CompactTextString(m) } +func (*AuthenticationStartMessage) ProtoMessage() {} + +func (m *AuthenticationStartMessage) GetMechanism() string { + if m != nil && m.Mechanism != nil { + return *m.Mechanism + } + return "" +} + +func (m *AuthenticationStartMessage) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +type AuthenticationStepMessage struct { + Data []byte `protobuf:"bytes,1,req,name=data" json:"data,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *AuthenticationStepMessage) Reset() { *m = AuthenticationStepMessage{} } +func (m *AuthenticationStepMessage) String() string { return proto.CompactTextString(m) } +func (*AuthenticationStepMessage) ProtoMessage() {} + +func (m *AuthenticationStepMessage) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +type AuthenticationCompletedMessage struct { + XXX_unrecognized []byte `json:"-"` +} + +func (m *AuthenticationCompletedMessage) Reset() { *m = AuthenticationCompletedMessage{} } +func (m *AuthenticationCompletedMessage) String() string { return proto.CompactTextString(m) } +func (*AuthenticationCompletedMessage) ProtoMessage() {} + +type AuthenticationFailedMessage struct { + XXX_unrecognized []byte `json:"-"` +} + +func (m *AuthenticationFailedMessage) Reset() { *m = AuthenticationFailedMessage{} } +func (m *AuthenticationFailedMessage) String() string { return proto.CompactTextString(m) } +func (*AuthenticationFailedMessage) ProtoMessage() {} + +type AuthenticationErrorMessage struct { + Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *AuthenticationErrorMessage) Reset() { *m = AuthenticationErrorMessage{} } +func (m *AuthenticationErrorMessage) String() string { return proto.CompactTextString(m) } +func (*AuthenticationErrorMessage) ProtoMessage() {} + +func (m *AuthenticationErrorMessage) GetError() string { + if m != nil && m.Error != nil { + return *m.Error + } + return "" +} diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.proto b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.proto new file mode 100644 index 000000000000..d8e42569e398 --- /dev/null +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.proto @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 mesosproto; + +import "mesos.proto"; + + +message AuthenticateMessage { + required string pid = 1; // PID that needs to be authenticated. +} + + +message AuthenticationMechanismsMessage { + repeated string mechanisms = 1; // List of available SASL mechanisms. +} + + +message AuthenticationStartMessage { + required string mechanism = 1; + optional bytes data = 2; +} + + +message AuthenticationStepMessage { + required bytes data = 1; +} + + +message AuthenticationCompletedMessage {} + + +message AuthenticationFailedMessage {} + + +message AuthenticationErrorMessage { + optional string error = 1; +} diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/containerizer.pb.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/containerizer.pb.go index 2e1e7921c53f..da62428f0801 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/containerizer.pb.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/containerizer.pb.go @@ -2,37 +2,17 @@ // source: containerizer.proto // DO NOT EDIT! -/* - Package mesosproto is a generated protocol buffer package. - - It is generated from these files: - containerizer.proto - internal.proto - log.proto - mesos.proto - messages.proto - registry.proto - scheduler.proto - state.proto - - It has these top-level messages: - Launch - Update - Wait - Destroy - Usage - Termination - Containers -*/ package mesosproto import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" import math "math" -// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb" +// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf // * @@ -200,6 +180,8 @@ func (m *Usage) GetContainerId() *ContainerID { type Termination struct { // A container may be killed if it exceeds its resources; this will // be indicated by killed=true and described by the message string. + // TODO(jaybuff): As part of MESOS-2035 we should remove killed and + // replace it with a TaskStatus::Reason. Killed *bool `protobuf:"varint,1,req,name=killed" json:"killed,omitempty"` Message *string `protobuf:"bytes,2,req,name=message" json:"message,omitempty"` // Exit status of the process. @@ -250,6 +232,3 @@ func (m *Containers) GetContainers() []*ContainerID { } return nil } - -func init() { -} diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/containerizer.proto b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/containerizer.proto index 79eda5319765..878060cc4923 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/containerizer.proto +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/containerizer.proto @@ -82,6 +82,8 @@ message Usage { message Termination { // A container may be killed if it exceeds its resources; this will // be indicated by killed=true and described by the message string. + // TODO(jaybuff): As part of MESOS-2035 we should remove killed and + // replace it with a TaskStatus::Reason. required bool killed = 1; required string message = 2; diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/internal.pb.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/internal.pb.go index c794dd359dab..8988e89978be 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/internal.pb.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/internal.pb.go @@ -5,12 +5,14 @@ package mesosproto import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" import math "math" -// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb" +// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf // For use with detector callbacks @@ -73,6 +75,3 @@ func (m *InternalAuthenticationResult) GetPid() string { } return "" } - -func init() { -} diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/log.pb.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/log.pb.go index 06db2ecc1840..2b62f81d64af 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/log.pb.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/log.pb.go @@ -5,30 +5,24 @@ package mesosproto import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" import math "math" -// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb" +// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto" -import io1 "io" -import fmt4 "fmt" -import github_com_gogo_protobuf_proto2 "github.com/gogo/protobuf/proto" +import bytes "bytes" -import fmt5 "fmt" -import strings2 "strings" -import reflect2 "reflect" +import strings "strings" +import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" +import sort "sort" +import strconv "strconv" +import reflect "reflect" -import fmt6 "fmt" -import strings3 "strings" -import github_com_gogo_protobuf_proto3 "github.com/gogo/protobuf/proto" -import sort1 "sort" -import strconv1 "strconv" -import reflect3 "reflect" - -import fmt7 "fmt" -import bytes1 "bytes" +import io "io" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf type Action_Type int32 @@ -614,2104 +608,1540 @@ func init() { proto.RegisterEnum("mesosproto.Metadata_Status", Metadata_Status_name, Metadata_Status_value) proto.RegisterEnum("mesosproto.Record_Type", Record_Type_name, Record_Type_value) } -func (m *Promise) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Proposal", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Proposal = &v - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy +func (this *Promise) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } + return fmt.Errorf("that == nil && this != nil") } - return nil -} -func (m *Action) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + + that1, ok := that.(*Promise) + if !ok { + return fmt.Errorf("that is not of type *Promise") + } + if that1 == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Position", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Position = &v - case 2: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Promised", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Promised = &v - case 3: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Performed", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Performed = &v - case 4: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Learned", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Learned = &b - case 5: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var v Action_Type - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (Action_Type(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Type = &v - case 6: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Nop", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - if m.Nop == nil { - m.Nop = &Action_Nop{} - } - if err := m.Nop.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 7: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Append", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - if m.Append == nil { - m.Append = &Action_Append{} - } - if err := m.Append.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 8: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Truncate", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - if m.Truncate == nil { - m.Truncate = &Action_Truncate{} - } - if err := m.Truncate.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that is type *Promise but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Promisebut is not nil && this == nil") + } + if this.Proposal != nil && that1.Proposal != nil { + if *this.Proposal != *that1.Proposal { + return fmt.Errorf("Proposal this(%v) Not Equal that(%v)", *this.Proposal, *that1.Proposal) } + } else if this.Proposal != nil { + return fmt.Errorf("this.Proposal == nil && that.Proposal != nil") + } else if that1.Proposal != nil { + return fmt.Errorf("Proposal this(%v) Not Equal that(%v)", this.Proposal, that1.Proposal) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *Action_Nop) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Promise) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - switch fieldNum { - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*Promise) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false } - return nil -} -func (m *Action_Append) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Bytes", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + byteLen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - m.Bytes = append([]byte{}, data[index:postIndex]...) - index = postIndex - case 2: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Cksum", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + byteLen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - m.Cksum = append([]byte{}, data[index:postIndex]...) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + if this.Proposal != nil && that1.Proposal != nil { + if *this.Proposal != *that1.Proposal { + return false } + } else if this.Proposal != nil { + return false + } else if that1.Proposal != nil { + return false } - return nil + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *Action_Truncate) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Action) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field To", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.To = &v - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Action) + if !ok { + return fmt.Errorf("that is not of type *Action") + } + if that1 == nil { + if this == nil { + return nil } + return fmt.Errorf("that is type *Action but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Actionbut is not nil && this == nil") } - return nil -} -func (m *Metadata) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if this.Position != nil && that1.Position != nil { + if *this.Position != *that1.Position { + return fmt.Errorf("Position this(%v) Not Equal that(%v)", *this.Position, *that1.Position) } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var v Metadata_Status - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (Metadata_Status(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Status = &v - case 2: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Promised", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Promised = &v - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } else if this.Position != nil { + return fmt.Errorf("this.Position == nil && that.Position != nil") + } else if that1.Position != nil { + return fmt.Errorf("Position this(%v) Not Equal that(%v)", this.Position, that1.Position) + } + if this.Promised != nil && that1.Promised != nil { + if *this.Promised != *that1.Promised { + return fmt.Errorf("Promised this(%v) Not Equal that(%v)", *this.Promised, *that1.Promised) + } + } else if this.Promised != nil { + return fmt.Errorf("this.Promised == nil && that.Promised != nil") + } else if that1.Promised != nil { + return fmt.Errorf("Promised this(%v) Not Equal that(%v)", this.Promised, that1.Promised) + } + if this.Performed != nil && that1.Performed != nil { + if *this.Performed != *that1.Performed { + return fmt.Errorf("Performed this(%v) Not Equal that(%v)", *this.Performed, *that1.Performed) + } + } else if this.Performed != nil { + return fmt.Errorf("this.Performed == nil && that.Performed != nil") + } else if that1.Performed != nil { + return fmt.Errorf("Performed this(%v) Not Equal that(%v)", this.Performed, that1.Performed) + } + if this.Learned != nil && that1.Learned != nil { + if *this.Learned != *that1.Learned { + return fmt.Errorf("Learned this(%v) Not Equal that(%v)", *this.Learned, *that1.Learned) + } + } else if this.Learned != nil { + return fmt.Errorf("this.Learned == nil && that.Learned != nil") + } else if that1.Learned != nil { + return fmt.Errorf("Learned this(%v) Not Equal that(%v)", this.Learned, that1.Learned) + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) } + } else if this.Type != nil { + return fmt.Errorf("this.Type == nil && that.Type != nil") + } else if that1.Type != nil { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + } + if !this.Nop.Equal(that1.Nop) { + return fmt.Errorf("Nop this(%v) Not Equal that(%v)", this.Nop, that1.Nop) + } + if !this.Append.Equal(that1.Append) { + return fmt.Errorf("Append this(%v) Not Equal that(%v)", this.Append, that1.Append) + } + if !this.Truncate.Equal(that1.Truncate) { + return fmt.Errorf("Truncate this(%v) Not Equal that(%v)", this.Truncate, that1.Truncate) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *Record) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Action) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var v Record_Type - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (Record_Type(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Type = &v - case 2: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Promise", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - if m.Promise == nil { - m.Promise = &Promise{} - } - if err := m.Promise.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 3: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Action", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - if m.Action == nil { - m.Action = &Action{} - } - if err := m.Action.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 4: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Metadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - if m.Metadata == nil { - m.Metadata = &Metadata{} - } - if err := m.Metadata.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*Action) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false } - return nil -} -func (m *PromiseRequest) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if this.Position != nil && that1.Position != nil { + if *this.Position != *that1.Position { + return false } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Proposal", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Proposal = &v - case 2: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Position", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Position = &v - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } else if this.Position != nil { + return false + } else if that1.Position != nil { + return false + } + if this.Promised != nil && that1.Promised != nil { + if *this.Promised != *that1.Promised { + return false } + } else if this.Promised != nil { + return false + } else if that1.Promised != nil { + return false } - return nil + if this.Performed != nil && that1.Performed != nil { + if *this.Performed != *that1.Performed { + return false + } + } else if this.Performed != nil { + return false + } else if that1.Performed != nil { + return false + } + if this.Learned != nil && that1.Learned != nil { + if *this.Learned != *that1.Learned { + return false + } + } else if this.Learned != nil { + return false + } else if that1.Learned != nil { + return false + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return false + } + } else if this.Type != nil { + return false + } else if that1.Type != nil { + return false + } + if !this.Nop.Equal(that1.Nop) { + return false + } + if !this.Append.Equal(that1.Append) { + return false + } + if !this.Truncate.Equal(that1.Truncate) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *PromiseResponse) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Action_Nop) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Okay", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Okay = &b - case 2: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Proposal", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Proposal = &v - case 4: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Position", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Position = &v - case 3: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Action", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - if m.Action == nil { - m.Action = &Action{} - } - if err := m.Action.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Action_Nop) + if !ok { + return fmt.Errorf("that is not of type *Action_Nop") + } + if that1 == nil { + if this == nil { + return nil } + return fmt.Errorf("that is type *Action_Nop but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Action_Nopbut is not nil && this == nil") + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *WriteRequest) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Action_Nop) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Proposal", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Proposal = &v - case 2: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Position", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Position = &v - case 3: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Learned", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Learned = &b - case 4: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var v Action_Type - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (Action_Type(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Type = &v - case 5: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Nop", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - if m.Nop == nil { - m.Nop = &Action_Nop{} - } - if err := m.Nop.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 6: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Append", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - if m.Append == nil { - m.Append = &Action_Append{} - } - if err := m.Append.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 7: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Truncate", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - if m.Truncate == nil { - m.Truncate = &Action_Truncate{} - } - if err := m.Truncate.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*Action_Nop) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Action_Append) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Action_Append) + if !ok { + return fmt.Errorf("that is not of type *Action_Append") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Action_Append but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Action_Appendbut is not nil && this == nil") + } + if !bytes.Equal(this.Bytes, that1.Bytes) { + return fmt.Errorf("Bytes this(%v) Not Equal that(%v)", this.Bytes, that1.Bytes) + } + if !bytes.Equal(this.Cksum, that1.Cksum) { + return fmt.Errorf("Cksum this(%v) Not Equal that(%v)", this.Cksum, that1.Cksum) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Action_Append) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Action_Append) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !bytes.Equal(this.Bytes, that1.Bytes) { + return false + } + if !bytes.Equal(this.Cksum, that1.Cksum) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Action_Truncate) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Action_Truncate) + if !ok { + return fmt.Errorf("that is not of type *Action_Truncate") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Action_Truncate but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Action_Truncatebut is not nil && this == nil") + } + if this.To != nil && that1.To != nil { + if *this.To != *that1.To { + return fmt.Errorf("To this(%v) Not Equal that(%v)", *this.To, *that1.To) + } + } else if this.To != nil { + return fmt.Errorf("this.To == nil && that.To != nil") + } else if that1.To != nil { + return fmt.Errorf("To this(%v) Not Equal that(%v)", this.To, that1.To) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Action_Truncate) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Action_Truncate) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.To != nil && that1.To != nil { + if *this.To != *that1.To { + return false + } + } else if this.To != nil { + return false + } else if that1.To != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Metadata) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Metadata) + if !ok { + return fmt.Errorf("that is not of type *Metadata") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Metadata but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Metadatabut is not nil && this == nil") + } + if this.Status != nil && that1.Status != nil { + if *this.Status != *that1.Status { + return fmt.Errorf("Status this(%v) Not Equal that(%v)", *this.Status, *that1.Status) + } + } else if this.Status != nil { + return fmt.Errorf("this.Status == nil && that.Status != nil") + } else if that1.Status != nil { + return fmt.Errorf("Status this(%v) Not Equal that(%v)", this.Status, that1.Status) + } + if this.Promised != nil && that1.Promised != nil { + if *this.Promised != *that1.Promised { + return fmt.Errorf("Promised this(%v) Not Equal that(%v)", *this.Promised, *that1.Promised) + } + } else if this.Promised != nil { + return fmt.Errorf("this.Promised == nil && that.Promised != nil") + } else if that1.Promised != nil { + return fmt.Errorf("Promised this(%v) Not Equal that(%v)", this.Promised, that1.Promised) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Metadata) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Metadata) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Status != nil && that1.Status != nil { + if *this.Status != *that1.Status { + return false + } + } else if this.Status != nil { + return false + } else if that1.Status != nil { + return false + } + if this.Promised != nil && that1.Promised != nil { + if *this.Promised != *that1.Promised { + return false } + } else if this.Promised != nil { + return false + } else if that1.Promised != nil { + return false } - return nil + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *WriteResponse) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Record) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Okay", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Okay = &b - case 2: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Proposal", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Proposal = &v - case 3: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Position", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Position = &v - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Record) + if !ok { + return fmt.Errorf("that is not of type *Record") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Record but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Recordbut is not nil && this == nil") + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) } + } else if this.Type != nil { + return fmt.Errorf("this.Type == nil && that.Type != nil") + } else if that1.Type != nil { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + } + if !this.Promise.Equal(that1.Promise) { + return fmt.Errorf("Promise this(%v) Not Equal that(%v)", this.Promise, that1.Promise) + } + if !this.Action.Equal(that1.Action) { + return fmt.Errorf("Action this(%v) Not Equal that(%v)", this.Action, that1.Action) + } + if !this.Metadata.Equal(that1.Metadata) { + return fmt.Errorf("Metadata this(%v) Not Equal that(%v)", this.Metadata, that1.Metadata) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *LearnedMessage) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Record) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt4.Errorf("proto: wrong wireType = %d for field Action", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io1.ErrUnexpectedEOF - } - if m.Action == nil { - m.Action = &Action{} - } - if err := m.Action.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*Record) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return false + } + } else if this.Type != nil { + return false + } else if that1.Type != nil { + return false + } + if !this.Promise.Equal(that1.Promise) { + return false + } + if !this.Action.Equal(that1.Action) { + return false + } + if !this.Metadata.Equal(that1.Metadata) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *PromiseRequest) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*PromiseRequest) + if !ok { + return fmt.Errorf("that is not of type *PromiseRequest") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *PromiseRequest but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *PromiseRequestbut is not nil && this == nil") + } + if this.Proposal != nil && that1.Proposal != nil { + if *this.Proposal != *that1.Proposal { + return fmt.Errorf("Proposal this(%v) Not Equal that(%v)", *this.Proposal, *that1.Proposal) + } + } else if this.Proposal != nil { + return fmt.Errorf("this.Proposal == nil && that.Proposal != nil") + } else if that1.Proposal != nil { + return fmt.Errorf("Proposal this(%v) Not Equal that(%v)", this.Proposal, that1.Proposal) + } + if this.Position != nil && that1.Position != nil { + if *this.Position != *that1.Position { + return fmt.Errorf("Position this(%v) Not Equal that(%v)", *this.Position, *that1.Position) + } + } else if this.Position != nil { + return fmt.Errorf("this.Position == nil && that.Position != nil") + } else if that1.Position != nil { + return fmt.Errorf("Position this(%v) Not Equal that(%v)", this.Position, that1.Position) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *RecoverRequest) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *PromiseRequest) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*PromiseRequest) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Proposal != nil && that1.Proposal != nil { + if *this.Proposal != *that1.Proposal { + return false + } + } else if this.Proposal != nil { + return false + } else if that1.Proposal != nil { + return false + } + if this.Position != nil && that1.Position != nil { + if *this.Position != *that1.Position { + return false + } + } else if this.Position != nil { + return false + } else if that1.Position != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *PromiseResponse) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - switch fieldNum { - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*PromiseResponse) + if !ok { + return fmt.Errorf("that is not of type *PromiseResponse") + } + if that1 == nil { + if this == nil { + return nil } + return fmt.Errorf("that is type *PromiseResponse but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *PromiseResponsebut is not nil && this == nil") } - return nil -} -func (m *RecoverResponse) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if this.Okay != nil && that1.Okay != nil { + if *this.Okay != *that1.Okay { + return fmt.Errorf("Okay this(%v) Not Equal that(%v)", *this.Okay, *that1.Okay) } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var v Metadata_Status - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (Metadata_Status(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Status = &v - case 2: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field Begin", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Begin = &v - case 3: - if wireType != 0 { - return fmt4.Errorf("proto: wrong wireType = %d for field End", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io1.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.End = &v - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto2.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io1.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } else if this.Okay != nil { + return fmt.Errorf("this.Okay == nil && that.Okay != nil") + } else if that1.Okay != nil { + return fmt.Errorf("Okay this(%v) Not Equal that(%v)", this.Okay, that1.Okay) + } + if this.Proposal != nil && that1.Proposal != nil { + if *this.Proposal != *that1.Proposal { + return fmt.Errorf("Proposal this(%v) Not Equal that(%v)", *this.Proposal, *that1.Proposal) } + } else if this.Proposal != nil { + return fmt.Errorf("this.Proposal == nil && that.Proposal != nil") + } else if that1.Proposal != nil { + return fmt.Errorf("Proposal this(%v) Not Equal that(%v)", this.Proposal, that1.Proposal) } - return nil -} -func (this *Promise) String() string { - if this == nil { - return "nil" + if this.Position != nil && that1.Position != nil { + if *this.Position != *that1.Position { + return fmt.Errorf("Position this(%v) Not Equal that(%v)", *this.Position, *that1.Position) + } + } else if this.Position != nil { + return fmt.Errorf("this.Position == nil && that.Position != nil") + } else if that1.Position != nil { + return fmt.Errorf("Position this(%v) Not Equal that(%v)", this.Position, that1.Position) } - s := strings2.Join([]string{`&Promise{`, - `Proposal:` + valueToStringLog(this.Proposal) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Action) String() string { - if this == nil { - return "nil" + if !this.Action.Equal(that1.Action) { + return fmt.Errorf("Action this(%v) Not Equal that(%v)", this.Action, that1.Action) } - s := strings2.Join([]string{`&Action{`, - `Position:` + valueToStringLog(this.Position) + `,`, - `Promised:` + valueToStringLog(this.Promised) + `,`, - `Performed:` + valueToStringLog(this.Performed) + `,`, - `Learned:` + valueToStringLog(this.Learned) + `,`, - `Type:` + valueToStringLog(this.Type) + `,`, - `Nop:` + strings2.Replace(fmt5.Sprintf("%v", this.Nop), "Action_Nop", "Action_Nop", 1) + `,`, - `Append:` + strings2.Replace(fmt5.Sprintf("%v", this.Append), "Action_Append", "Action_Append", 1) + `,`, - `Truncate:` + strings2.Replace(fmt5.Sprintf("%v", this.Truncate), "Action_Truncate", "Action_Truncate", 1) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Action_Nop) String() string { - if this == nil { - return "nil" + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } - s := strings2.Join([]string{`&Action_Nop{`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + return nil } -func (this *Action_Append) String() string { - if this == nil { - return "nil" +func (this *PromiseResponse) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false } - s := strings2.Join([]string{`&Action_Append{`, - `Bytes:` + valueToStringLog(this.Bytes) + `,`, - `Cksum:` + valueToStringLog(this.Cksum) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Action_Truncate) String() string { - if this == nil { - return "nil" + + that1, ok := that.(*PromiseResponse) + if !ok { + return false } - s := strings2.Join([]string{`&Action_Truncate{`, - `To:` + valueToStringLog(this.To) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Metadata) String() string { - if this == nil { - return "nil" + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false } - s := strings2.Join([]string{`&Metadata{`, - `Status:` + valueToStringLog(this.Status) + `,`, - `Promised:` + valueToStringLog(this.Promised) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Record) String() string { - if this == nil { - return "nil" + if this.Okay != nil && that1.Okay != nil { + if *this.Okay != *that1.Okay { + return false + } + } else if this.Okay != nil { + return false + } else if that1.Okay != nil { + return false } - s := strings2.Join([]string{`&Record{`, - `Type:` + valueToStringLog(this.Type) + `,`, - `Promise:` + strings2.Replace(fmt5.Sprintf("%v", this.Promise), "Promise", "Promise", 1) + `,`, - `Action:` + strings2.Replace(fmt5.Sprintf("%v", this.Action), "Action", "Action", 1) + `,`, - `Metadata:` + strings2.Replace(fmt5.Sprintf("%v", this.Metadata), "Metadata", "Metadata", 1) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *PromiseRequest) String() string { - if this == nil { - return "nil" + if this.Proposal != nil && that1.Proposal != nil { + if *this.Proposal != *that1.Proposal { + return false + } + } else if this.Proposal != nil { + return false + } else if that1.Proposal != nil { + return false } - s := strings2.Join([]string{`&PromiseRequest{`, - `Proposal:` + valueToStringLog(this.Proposal) + `,`, - `Position:` + valueToStringLog(this.Position) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *PromiseResponse) String() string { - if this == nil { - return "nil" + if this.Position != nil && that1.Position != nil { + if *this.Position != *that1.Position { + return false + } + } else if this.Position != nil { + return false + } else if that1.Position != nil { + return false } - s := strings2.Join([]string{`&PromiseResponse{`, - `Okay:` + valueToStringLog(this.Okay) + `,`, - `Proposal:` + valueToStringLog(this.Proposal) + `,`, - `Position:` + valueToStringLog(this.Position) + `,`, - `Action:` + strings2.Replace(fmt5.Sprintf("%v", this.Action), "Action", "Action", 1) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *WriteRequest) String() string { - if this == nil { - return "nil" + if !this.Action.Equal(that1.Action) { + return false } - s := strings2.Join([]string{`&WriteRequest{`, - `Proposal:` + valueToStringLog(this.Proposal) + `,`, - `Position:` + valueToStringLog(this.Position) + `,`, - `Learned:` + valueToStringLog(this.Learned) + `,`, - `Type:` + valueToStringLog(this.Type) + `,`, - `Nop:` + strings2.Replace(fmt5.Sprintf("%v", this.Nop), "Action_Nop", "Action_Nop", 1) + `,`, - `Append:` + strings2.Replace(fmt5.Sprintf("%v", this.Append), "Action_Append", "Action_Append", 1) + `,`, - `Truncate:` + strings2.Replace(fmt5.Sprintf("%v", this.Truncate), "Action_Truncate", "Action_Truncate", 1) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *WriteResponse) String() string { - if this == nil { - return "nil" + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false } - s := strings2.Join([]string{`&WriteResponse{`, - `Okay:` + valueToStringLog(this.Okay) + `,`, - `Proposal:` + valueToStringLog(this.Proposal) + `,`, - `Position:` + valueToStringLog(this.Position) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + return true } -func (this *LearnedMessage) String() string { - if this == nil { - return "nil" +func (this *WriteRequest) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") } - s := strings2.Join([]string{`&LearnedMessage{`, - `Action:` + strings2.Replace(fmt5.Sprintf("%v", this.Action), "Action", "Action", 1) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *RecoverRequest) String() string { - if this == nil { - return "nil" + + that1, ok := that.(*WriteRequest) + if !ok { + return fmt.Errorf("that is not of type *WriteRequest") } - s := strings2.Join([]string{`&RecoverRequest{`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *RecoverResponse) String() string { - if this == nil { - return "nil" + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *WriteRequest but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *WriteRequestbut is not nil && this == nil") } - s := strings2.Join([]string{`&RecoverResponse{`, - `Status:` + valueToStringLog(this.Status) + `,`, - `Begin:` + valueToStringLog(this.Begin) + `,`, - `End:` + valueToStringLog(this.End) + `,`, - `XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func valueToStringLog(v interface{}) string { - rv := reflect2.ValueOf(v) - if rv.IsNil() { - return "nil" + if this.Proposal != nil && that1.Proposal != nil { + if *this.Proposal != *that1.Proposal { + return fmt.Errorf("Proposal this(%v) Not Equal that(%v)", *this.Proposal, *that1.Proposal) + } + } else if this.Proposal != nil { + return fmt.Errorf("this.Proposal == nil && that.Proposal != nil") + } else if that1.Proposal != nil { + return fmt.Errorf("Proposal this(%v) Not Equal that(%v)", this.Proposal, that1.Proposal) } - pv := reflect2.Indirect(rv).Interface() - return fmt5.Sprintf("*%v", pv) -} -func (m *Promise) Size() (n int) { - var l int - _ = l - if m.Proposal != nil { - n += 1 + sovLog(uint64(*m.Proposal)) + if this.Position != nil && that1.Position != nil { + if *this.Position != *that1.Position { + return fmt.Errorf("Position this(%v) Not Equal that(%v)", *this.Position, *that1.Position) + } + } else if this.Position != nil { + return fmt.Errorf("this.Position == nil && that.Position != nil") + } else if that1.Position != nil { + return fmt.Errorf("Position this(%v) Not Equal that(%v)", this.Position, that1.Position) } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.Learned != nil && that1.Learned != nil { + if *this.Learned != *that1.Learned { + return fmt.Errorf("Learned this(%v) Not Equal that(%v)", *this.Learned, *that1.Learned) + } + } else if this.Learned != nil { + return fmt.Errorf("this.Learned == nil && that.Learned != nil") + } else if that1.Learned != nil { + return fmt.Errorf("Learned this(%v) Not Equal that(%v)", this.Learned, that1.Learned) } - return n + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) + } + } else if this.Type != nil { + return fmt.Errorf("this.Type == nil && that.Type != nil") + } else if that1.Type != nil { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + } + if !this.Nop.Equal(that1.Nop) { + return fmt.Errorf("Nop this(%v) Not Equal that(%v)", this.Nop, that1.Nop) + } + if !this.Append.Equal(that1.Append) { + return fmt.Errorf("Append this(%v) Not Equal that(%v)", this.Append, that1.Append) + } + if !this.Truncate.Equal(that1.Truncate) { + return fmt.Errorf("Truncate this(%v) Not Equal that(%v)", this.Truncate, that1.Truncate) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil } +func (this *WriteRequest) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } -func (m *Action) Size() (n int) { - var l int - _ = l - if m.Position != nil { - n += 1 + sovLog(uint64(*m.Position)) + that1, ok := that.(*WriteRequest) + if !ok { + return false } - if m.Promised != nil { - n += 1 + sovLog(uint64(*m.Promised)) + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false } - if m.Performed != nil { - n += 1 + sovLog(uint64(*m.Performed)) + if this.Proposal != nil && that1.Proposal != nil { + if *this.Proposal != *that1.Proposal { + return false + } + } else if this.Proposal != nil { + return false + } else if that1.Proposal != nil { + return false } - if m.Learned != nil { - n += 2 + if this.Position != nil && that1.Position != nil { + if *this.Position != *that1.Position { + return false + } + } else if this.Position != nil { + return false + } else if that1.Position != nil { + return false } - if m.Type != nil { - n += 1 + sovLog(uint64(*m.Type)) + if this.Learned != nil && that1.Learned != nil { + if *this.Learned != *that1.Learned { + return false + } + } else if this.Learned != nil { + return false + } else if that1.Learned != nil { + return false } - if m.Nop != nil { - l = m.Nop.Size() - n += 1 + l + sovLog(uint64(l)) + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return false + } + } else if this.Type != nil { + return false + } else if that1.Type != nil { + return false } - if m.Append != nil { - l = m.Append.Size() - n += 1 + l + sovLog(uint64(l)) + if !this.Nop.Equal(that1.Nop) { + return false } - if m.Truncate != nil { - l = m.Truncate.Size() - n += 1 + l + sovLog(uint64(l)) + if !this.Append.Equal(that1.Append) { + return false } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if !this.Truncate.Equal(that1.Truncate) { + return false } - return n + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } +func (this *WriteResponse) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } -func (m *Action_Nop) Size() (n int) { - var l int - _ = l - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + that1, ok := that.(*WriteResponse) + if !ok { + return fmt.Errorf("that is not of type *WriteResponse") } - return n + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *WriteResponse but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *WriteResponsebut is not nil && this == nil") + } + if this.Okay != nil && that1.Okay != nil { + if *this.Okay != *that1.Okay { + return fmt.Errorf("Okay this(%v) Not Equal that(%v)", *this.Okay, *that1.Okay) + } + } else if this.Okay != nil { + return fmt.Errorf("this.Okay == nil && that.Okay != nil") + } else if that1.Okay != nil { + return fmt.Errorf("Okay this(%v) Not Equal that(%v)", this.Okay, that1.Okay) + } + if this.Proposal != nil && that1.Proposal != nil { + if *this.Proposal != *that1.Proposal { + return fmt.Errorf("Proposal this(%v) Not Equal that(%v)", *this.Proposal, *that1.Proposal) + } + } else if this.Proposal != nil { + return fmt.Errorf("this.Proposal == nil && that.Proposal != nil") + } else if that1.Proposal != nil { + return fmt.Errorf("Proposal this(%v) Not Equal that(%v)", this.Proposal, that1.Proposal) + } + if this.Position != nil && that1.Position != nil { + if *this.Position != *that1.Position { + return fmt.Errorf("Position this(%v) Not Equal that(%v)", *this.Position, *that1.Position) + } + } else if this.Position != nil { + return fmt.Errorf("this.Position == nil && that.Position != nil") + } else if that1.Position != nil { + return fmt.Errorf("Position this(%v) Not Equal that(%v)", this.Position, that1.Position) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil } +func (this *WriteResponse) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } -func (m *Action_Append) Size() (n int) { - var l int - _ = l - if m.Bytes != nil { - l = len(m.Bytes) - n += 1 + l + sovLog(uint64(l)) + that1, ok := that.(*WriteResponse) + if !ok { + return false } - if m.Cksum != nil { - l = len(m.Cksum) - n += 1 + l + sovLog(uint64(l)) + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Okay != nil && that1.Okay != nil { + if *this.Okay != *that1.Okay { + return false + } + } else if this.Okay != nil { + return false + } else if that1.Okay != nil { + return false + } + if this.Proposal != nil && that1.Proposal != nil { + if *this.Proposal != *that1.Proposal { + return false + } + } else if this.Proposal != nil { + return false + } else if that1.Proposal != nil { + return false + } + if this.Position != nil && that1.Position != nil { + if *this.Position != *that1.Position { + return false + } + } else if this.Position != nil { + return false + } else if that1.Position != nil { + return false } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false } - return n + return true } +func (this *LearnedMessage) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } -func (m *Action_Truncate) Size() (n int) { - var l int - _ = l - if m.To != nil { - n += 1 + sovLog(uint64(*m.To)) + that1, ok := that.(*LearnedMessage) + if !ok { + return fmt.Errorf("that is not of type *LearnedMessage") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *LearnedMessage but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *LearnedMessagebut is not nil && this == nil") } - return n + if !this.Action.Equal(that1.Action) { + return fmt.Errorf("Action this(%v) Not Equal that(%v)", this.Action, that1.Action) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil } +func (this *LearnedMessage) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } -func (m *Metadata) Size() (n int) { - var l int - _ = l - if m.Status != nil { - n += 1 + sovLog(uint64(*m.Status)) + that1, ok := that.(*LearnedMessage) + if !ok { + return false } - if m.Promised != nil { - n += 1 + sovLog(uint64(*m.Promised)) + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if !this.Action.Equal(that1.Action) { + return false } - return n -} - -func (m *Record) Size() (n int) { - var l int - _ = l - if m.Type != nil { - n += 1 + sovLog(uint64(*m.Type)) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false } - if m.Promise != nil { - l = m.Promise.Size() - n += 1 + l + sovLog(uint64(l)) + return true +} +func (this *RecoverRequest) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") } - if m.Action != nil { - l = m.Action.Size() - n += 1 + l + sovLog(uint64(l)) + + that1, ok := that.(*RecoverRequest) + if !ok { + return fmt.Errorf("that is not of type *RecoverRequest") } - if m.Metadata != nil { - l = m.Metadata.Size() - n += 1 + l + sovLog(uint64(l)) + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *RecoverRequest but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *RecoverRequestbut is not nil && this == nil") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } - return n + return nil } +func (this *RecoverRequest) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } -func (m *PromiseRequest) Size() (n int) { - var l int - _ = l - if m.Proposal != nil { - n += 1 + sovLog(uint64(*m.Proposal)) + that1, ok := that.(*RecoverRequest) + if !ok { + return false } - if m.Position != nil { - n += 1 + sovLog(uint64(*m.Position)) + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false } - return n + return true } +func (this *RecoverResponse) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } -func (m *PromiseResponse) Size() (n int) { - var l int - _ = l - if m.Okay != nil { - n += 2 + that1, ok := that.(*RecoverResponse) + if !ok { + return fmt.Errorf("that is not of type *RecoverResponse") } - if m.Proposal != nil { - n += 1 + sovLog(uint64(*m.Proposal)) + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *RecoverResponse but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *RecoverResponsebut is not nil && this == nil") } - if m.Position != nil { - n += 1 + sovLog(uint64(*m.Position)) + if this.Status != nil && that1.Status != nil { + if *this.Status != *that1.Status { + return fmt.Errorf("Status this(%v) Not Equal that(%v)", *this.Status, *that1.Status) + } + } else if this.Status != nil { + return fmt.Errorf("this.Status == nil && that.Status != nil") + } else if that1.Status != nil { + return fmt.Errorf("Status this(%v) Not Equal that(%v)", this.Status, that1.Status) } - if m.Action != nil { - l = m.Action.Size() - n += 1 + l + sovLog(uint64(l)) + if this.Begin != nil && that1.Begin != nil { + if *this.Begin != *that1.Begin { + return fmt.Errorf("Begin this(%v) Not Equal that(%v)", *this.Begin, *that1.Begin) + } + } else if this.Begin != nil { + return fmt.Errorf("this.Begin == nil && that.Begin != nil") + } else if that1.Begin != nil { + return fmt.Errorf("Begin this(%v) Not Equal that(%v)", this.Begin, that1.Begin) } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.End != nil && that1.End != nil { + if *this.End != *that1.End { + return fmt.Errorf("End this(%v) Not Equal that(%v)", *this.End, *that1.End) + } + } else if this.End != nil { + return fmt.Errorf("this.End == nil && that.End != nil") + } else if that1.End != nil { + return fmt.Errorf("End this(%v) Not Equal that(%v)", this.End, that1.End) } - return n -} - -func (m *WriteRequest) Size() (n int) { - var l int - _ = l - if m.Proposal != nil { - n += 1 + sovLog(uint64(*m.Proposal)) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } - if m.Position != nil { - n += 1 + sovLog(uint64(*m.Position)) + return nil +} +func (this *RecoverResponse) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false } - if m.Learned != nil { - n += 2 + + that1, ok := that.(*RecoverResponse) + if !ok { + return false } - if m.Type != nil { - n += 1 + sovLog(uint64(*m.Type)) + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false } - if m.Nop != nil { - l = m.Nop.Size() - n += 1 + l + sovLog(uint64(l)) + if this.Status != nil && that1.Status != nil { + if *this.Status != *that1.Status { + return false + } + } else if this.Status != nil { + return false + } else if that1.Status != nil { + return false } - if m.Append != nil { - l = m.Append.Size() - n += 1 + l + sovLog(uint64(l)) + if this.Begin != nil && that1.Begin != nil { + if *this.Begin != *that1.Begin { + return false + } + } else if this.Begin != nil { + return false + } else if that1.Begin != nil { + return false } - if m.Truncate != nil { - l = m.Truncate.Size() - n += 1 + l + sovLog(uint64(l)) + if this.End != nil && that1.End != nil { + if *this.End != *that1.End { + return false + } + } else if this.End != nil { + return false + } else if that1.End != nil { + return false } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false } - return n + return true } - -func (m *WriteResponse) Size() (n int) { - var l int - _ = l - if m.Okay != nil { - n += 2 - } - if m.Proposal != nil { - n += 1 + sovLog(uint64(*m.Proposal)) +func (this *Promise) GoString() string { + if this == nil { + return "nil" } - if m.Position != nil { - n += 1 + sovLog(uint64(*m.Position)) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Promise{") + if this.Proposal != nil { + s = append(s, "Proposal: "+valueToGoStringLog(this.Proposal, "uint64")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - return n + s = append(s, "}") + return strings.Join(s, "") } - -func (m *LearnedMessage) Size() (n int) { - var l int - _ = l - if m.Action != nil { - l = m.Action.Size() - n += 1 + l + sovLog(uint64(l)) +func (this *Action) GoString() string { + if this == nil { + return "nil" } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + s := make([]string, 0, 12) + s = append(s, "&mesosproto.Action{") + if this.Position != nil { + s = append(s, "Position: "+valueToGoStringLog(this.Position, "uint64")+",\n") } - return n -} - -func (m *RecoverRequest) Size() (n int) { - var l int - _ = l - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.Promised != nil { + s = append(s, "Promised: "+valueToGoStringLog(this.Promised, "uint64")+",\n") } - return n -} - -func (m *RecoverResponse) Size() (n int) { - var l int - _ = l - if m.Status != nil { - n += 1 + sovLog(uint64(*m.Status)) + if this.Performed != nil { + s = append(s, "Performed: "+valueToGoStringLog(this.Performed, "uint64")+",\n") } - if m.Begin != nil { - n += 1 + sovLog(uint64(*m.Begin)) + if this.Learned != nil { + s = append(s, "Learned: "+valueToGoStringLog(this.Learned, "bool")+",\n") } - if m.End != nil { - n += 1 + sovLog(uint64(*m.End)) + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringLog(this.Type, "mesosproto.Action_Type")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.Nop != nil { + s = append(s, "Nop: "+fmt.Sprintf("%#v", this.Nop)+",\n") } - return n -} - -func sovLog(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } + if this.Append != nil { + s = append(s, "Append: "+fmt.Sprintf("%#v", this.Append)+",\n") } - return n -} -func sozLog(x uint64) (n int) { - return sovLog(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + if this.Truncate != nil { + s = append(s, "Truncate: "+fmt.Sprintf("%#v", this.Truncate)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func NewPopulatedPromise(r randyLog, easy bool) *Promise { - this := &Promise{} - v1 := uint64(r.Uint32()) - this.Proposal = &v1 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 2) +func (this *Action_Nop) GoString() string { + if this == nil { + return "nil" } - return this + s := make([]string, 0, 4) + s = append(s, "&mesosproto.Action_Nop{") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func NewPopulatedAction(r randyLog, easy bool) *Action { - this := &Action{} - v2 := uint64(r.Uint32()) - this.Position = &v2 - v3 := uint64(r.Uint32()) - this.Promised = &v3 - if r.Intn(10) != 0 { - v4 := uint64(r.Uint32()) - this.Performed = &v4 +func (this *Action_Append) GoString() string { + if this == nil { + return "nil" } - if r.Intn(10) != 0 { - v5 := bool(r.Intn(2) == 0) - this.Learned = &v5 + s := make([]string, 0, 6) + s = append(s, "&mesosproto.Action_Append{") + if this.Bytes != nil { + s = append(s, "Bytes: "+valueToGoStringLog(this.Bytes, "byte")+",\n") } - if r.Intn(10) != 0 { - v6 := Action_Type([]int32{1, 2, 3}[r.Intn(3)]) - this.Type = &v6 + if this.Cksum != nil { + s = append(s, "Cksum: "+valueToGoStringLog(this.Cksum, "byte")+",\n") } - if r.Intn(10) != 0 { - this.Nop = NewPopulatedAction_Nop(r, easy) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if r.Intn(10) != 0 { - this.Append = NewPopulatedAction_Append(r, easy) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Action_Truncate) GoString() string { + if this == nil { + return "nil" } - if r.Intn(10) != 0 { - this.Truncate = NewPopulatedAction_Truncate(r, easy) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Action_Truncate{") + if this.To != nil { + s = append(s, "To: "+valueToGoStringLog(this.To, "uint64")+",\n") } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 9) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - return this + s = append(s, "}") + return strings.Join(s, "") } - -func NewPopulatedAction_Nop(r randyLog, easy bool) *Action_Nop { - this := &Action_Nop{} - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 1) +func (this *Metadata) GoString() string { + if this == nil { + return "nil" } - return this -} - -func NewPopulatedAction_Append(r randyLog, easy bool) *Action_Append { - this := &Action_Append{} - v7 := r.Intn(100) - this.Bytes = make([]byte, v7) - for i := 0; i < v7; i++ { - this.Bytes[i] = byte(r.Intn(256)) + s := make([]string, 0, 6) + s = append(s, "&mesosproto.Metadata{") + if this.Status != nil { + s = append(s, "Status: "+valueToGoStringLog(this.Status, "mesosproto.Metadata_Status")+",\n") } - if r.Intn(10) != 0 { - v8 := r.Intn(100) - this.Cksum = make([]byte, v8) - for i := 0; i < v8; i++ { - this.Cksum[i] = byte(r.Intn(256)) - } + if this.Promised != nil { + s = append(s, "Promised: "+valueToGoStringLog(this.Promised, "uint64")+",\n") } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 3) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - return this + s = append(s, "}") + return strings.Join(s, "") } - -func NewPopulatedAction_Truncate(r randyLog, easy bool) *Action_Truncate { - this := &Action_Truncate{} - v9 := uint64(r.Uint32()) - this.To = &v9 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 2) +func (this *Record) GoString() string { + if this == nil { + return "nil" } - return this -} - -func NewPopulatedMetadata(r randyLog, easy bool) *Metadata { - this := &Metadata{} - v10 := Metadata_Status([]int32{1, 2, 3, 4}[r.Intn(4)]) - this.Status = &v10 - v11 := uint64(r.Uint32()) - this.Promised = &v11 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 3) + s := make([]string, 0, 8) + s = append(s, "&mesosproto.Record{") + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringLog(this.Type, "mesosproto.Record_Type")+",\n") } - return this -} - -func NewPopulatedRecord(r randyLog, easy bool) *Record { - this := &Record{} - v12 := Record_Type([]int32{1, 2, 3}[r.Intn(3)]) - this.Type = &v12 - if r.Intn(10) != 0 { - this.Promise = NewPopulatedPromise(r, easy) + if this.Promise != nil { + s = append(s, "Promise: "+fmt.Sprintf("%#v", this.Promise)+",\n") } - if r.Intn(10) != 0 { - this.Action = NewPopulatedAction(r, easy) + if this.Action != nil { + s = append(s, "Action: "+fmt.Sprintf("%#v", this.Action)+",\n") } - if r.Intn(10) != 0 { - this.Metadata = NewPopulatedMetadata(r, easy) + if this.Metadata != nil { + s = append(s, "Metadata: "+fmt.Sprintf("%#v", this.Metadata)+",\n") } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 5) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - return this + s = append(s, "}") + return strings.Join(s, "") } - -func NewPopulatedPromiseRequest(r randyLog, easy bool) *PromiseRequest { - this := &PromiseRequest{} - v13 := uint64(r.Uint32()) - this.Proposal = &v13 - if r.Intn(10) != 0 { - v14 := uint64(r.Uint32()) - this.Position = &v14 +func (this *PromiseRequest) GoString() string { + if this == nil { + return "nil" } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 3) + s := make([]string, 0, 6) + s = append(s, "&mesosproto.PromiseRequest{") + if this.Proposal != nil { + s = append(s, "Proposal: "+valueToGoStringLog(this.Proposal, "uint64")+",\n") } - return this + if this.Position != nil { + s = append(s, "Position: "+valueToGoStringLog(this.Position, "uint64")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func NewPopulatedPromiseResponse(r randyLog, easy bool) *PromiseResponse { - this := &PromiseResponse{} - v15 := bool(r.Intn(2) == 0) - this.Okay = &v15 - v16 := uint64(r.Uint32()) - this.Proposal = &v16 - if r.Intn(10) != 0 { - v17 := uint64(r.Uint32()) - this.Position = &v17 +func (this *PromiseResponse) GoString() string { + if this == nil { + return "nil" } - if r.Intn(10) != 0 { - this.Action = NewPopulatedAction(r, easy) + s := make([]string, 0, 8) + s = append(s, "&mesosproto.PromiseResponse{") + if this.Okay != nil { + s = append(s, "Okay: "+valueToGoStringLog(this.Okay, "bool")+",\n") } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 5) + if this.Proposal != nil { + s = append(s, "Proposal: "+valueToGoStringLog(this.Proposal, "uint64")+",\n") } - return this + if this.Position != nil { + s = append(s, "Position: "+valueToGoStringLog(this.Position, "uint64")+",\n") + } + if this.Action != nil { + s = append(s, "Action: "+fmt.Sprintf("%#v", this.Action)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func NewPopulatedWriteRequest(r randyLog, easy bool) *WriteRequest { - this := &WriteRequest{} - v18 := uint64(r.Uint32()) - this.Proposal = &v18 - v19 := uint64(r.Uint32()) - this.Position = &v19 - if r.Intn(10) != 0 { - v20 := bool(r.Intn(2) == 0) - this.Learned = &v20 +func (this *WriteRequest) GoString() string { + if this == nil { + return "nil" } - v21 := Action_Type([]int32{1, 2, 3}[r.Intn(3)]) - this.Type = &v21 - if r.Intn(10) != 0 { - this.Nop = NewPopulatedAction_Nop(r, easy) + s := make([]string, 0, 11) + s = append(s, "&mesosproto.WriteRequest{") + if this.Proposal != nil { + s = append(s, "Proposal: "+valueToGoStringLog(this.Proposal, "uint64")+",\n") } - if r.Intn(10) != 0 { - this.Append = NewPopulatedAction_Append(r, easy) + if this.Position != nil { + s = append(s, "Position: "+valueToGoStringLog(this.Position, "uint64")+",\n") } - if r.Intn(10) != 0 { - this.Truncate = NewPopulatedAction_Truncate(r, easy) + if this.Learned != nil { + s = append(s, "Learned: "+valueToGoStringLog(this.Learned, "bool")+",\n") } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 8) + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringLog(this.Type, "mesosproto.Action_Type")+",\n") } - return this -} - -func NewPopulatedWriteResponse(r randyLog, easy bool) *WriteResponse { - this := &WriteResponse{} - v22 := bool(r.Intn(2) == 0) - this.Okay = &v22 - v23 := uint64(r.Uint32()) - this.Proposal = &v23 - v24 := uint64(r.Uint32()) - this.Position = &v24 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 4) + if this.Nop != nil { + s = append(s, "Nop: "+fmt.Sprintf("%#v", this.Nop)+",\n") } - return this -} - -func NewPopulatedLearnedMessage(r randyLog, easy bool) *LearnedMessage { - this := &LearnedMessage{} - this.Action = NewPopulatedAction(r, easy) - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 2) + if this.Append != nil { + s = append(s, "Append: "+fmt.Sprintf("%#v", this.Append)+",\n") } - return this -} - -func NewPopulatedRecoverRequest(r randyLog, easy bool) *RecoverRequest { - this := &RecoverRequest{} - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 1) + if this.Truncate != nil { + s = append(s, "Truncate: "+fmt.Sprintf("%#v", this.Truncate)+",\n") } - return this + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func NewPopulatedRecoverResponse(r randyLog, easy bool) *RecoverResponse { - this := &RecoverResponse{} - v25 := Metadata_Status([]int32{1, 2, 3, 4}[r.Intn(4)]) - this.Status = &v25 - if r.Intn(10) != 0 { - v26 := uint64(r.Uint32()) - this.Begin = &v26 +func (this *WriteResponse) GoString() string { + if this == nil { + return "nil" } - if r.Intn(10) != 0 { - v27 := uint64(r.Uint32()) - this.End = &v27 + s := make([]string, 0, 7) + s = append(s, "&mesosproto.WriteResponse{") + if this.Okay != nil { + s = append(s, "Okay: "+valueToGoStringLog(this.Okay, "bool")+",\n") } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedLog(r, 4) + if this.Proposal != nil { + s = append(s, "Proposal: "+valueToGoStringLog(this.Proposal, "uint64")+",\n") } - return this -} - -type randyLog interface { - Float32() float32 - Float64() float64 - Int63() int64 - Int31() int32 - Uint32() uint32 - Intn(n int) int + if this.Position != nil { + s = append(s, "Position: "+valueToGoStringLog(this.Position, "uint64")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func randUTF8RuneLog(r randyLog) rune { - res := rune(r.Uint32() % 1112064) - if 55296 <= res { - res += 2047 +func (this *LearnedMessage) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&mesosproto.LearnedMessage{") + if this.Action != nil { + s = append(s, "Action: "+fmt.Sprintf("%#v", this.Action)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - return res + s = append(s, "}") + return strings.Join(s, "") } -func randStringLog(r randyLog) string { - v28 := r.Intn(100) - tmps := make([]rune, v28) - for i := 0; i < v28; i++ { - tmps[i] = randUTF8RuneLog(r) +func (this *RecoverRequest) GoString() string { + if this == nil { + return "nil" } - return string(tmps) + s := make([]string, 0, 4) + s = append(s, "&mesosproto.RecoverRequest{") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func randUnrecognizedLog(r randyLog, maxFieldNumber int) (data []byte) { - l := r.Intn(5) - for i := 0; i < l; i++ { - wire := r.Intn(4) - if wire == 3 { - wire = 5 - } - fieldNumber := maxFieldNumber + r.Intn(100) - data = randFieldLog(data, r, fieldNumber, wire) +func (this *RecoverResponse) GoString() string { + if this == nil { + return "nil" } - return data + s := make([]string, 0, 7) + s = append(s, "&mesosproto.RecoverResponse{") + if this.Status != nil { + s = append(s, "Status: "+valueToGoStringLog(this.Status, "mesosproto.Metadata_Status")+",\n") + } + if this.Begin != nil { + s = append(s, "Begin: "+valueToGoStringLog(this.Begin, "uint64")+",\n") + } + if this.End != nil { + s = append(s, "End: "+valueToGoStringLog(this.End, "uint64")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func randFieldLog(data []byte, r randyLog, fieldNumber int, wire int) []byte { - key := uint32(fieldNumber)<<3 | uint32(wire) - switch wire { - case 0: - data = encodeVarintPopulateLog(data, uint64(key)) - v29 := r.Int63() - if r.Intn(2) == 0 { - v29 *= -1 - } - data = encodeVarintPopulateLog(data, uint64(v29)) - case 1: - data = encodeVarintPopulateLog(data, uint64(key)) - data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) - case 2: - data = encodeVarintPopulateLog(data, uint64(key)) - ll := r.Intn(100) - data = encodeVarintPopulateLog(data, uint64(ll)) - for j := 0; j < ll; j++ { - data = append(data, byte(r.Intn(256))) - } - default: - data = encodeVarintPopulateLog(data, uint64(key)) - data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) +func valueToGoStringLog(v interface{}, typ string) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" } - return data + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) } -func encodeVarintPopulateLog(data []byte, v uint64) []byte { - for v >= 1<<7 { - data = append(data, uint8(uint64(v)&0x7f|0x80)) - v >>= 7 +func extensionToGoStringLog(e map[int32]github_com_gogo_protobuf_proto.Extension) string { + if e == nil { + return "nil" } - data = append(data, uint8(v)) - return data + s := "map[int32]proto.Extension{" + keys := make([]int, 0, len(e)) + for k := range e { + keys = append(keys, int(k)) + } + sort.Ints(keys) + ss := []string{} + for _, k := range keys { + ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString()) + } + s += strings.Join(ss, ",") + "}" + return s } func (m *Promise) Marshal() (data []byte, err error) { size := m.Size() @@ -2723,12 +2153,14 @@ func (m *Promise) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Promise) MarshalTo(data []byte) (n int, err error) { +func (m *Promise) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Proposal != nil { + if m.Proposal == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("proposal") + } else { data[i] = 0x8 i++ i = encodeVarintLog(data, i, uint64(*m.Proposal)) @@ -2749,17 +2181,21 @@ func (m *Action) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Action) MarshalTo(data []byte) (n int, err error) { +func (m *Action) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Position != nil { + if m.Position == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("position") + } else { data[i] = 0x8 i++ i = encodeVarintLog(data, i, uint64(*m.Position)) } - if m.Promised != nil { + if m.Promised == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("promised") + } else { data[i] = 0x10 i++ i = encodeVarintLog(data, i, uint64(*m.Promised)) @@ -2830,7 +2266,7 @@ func (m *Action_Nop) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Action_Nop) MarshalTo(data []byte) (n int, err error) { +func (m *Action_Nop) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -2851,12 +2287,14 @@ func (m *Action_Append) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Action_Append) MarshalTo(data []byte) (n int, err error) { +func (m *Action_Append) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Bytes != nil { + if m.Bytes == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("bytes") + } else { data[i] = 0xa i++ i = encodeVarintLog(data, i, uint64(len(m.Bytes))) @@ -2884,12 +2322,14 @@ func (m *Action_Truncate) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Action_Truncate) MarshalTo(data []byte) (n int, err error) { +func (m *Action_Truncate) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.To != nil { + if m.To == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("to") + } else { data[i] = 0x8 i++ i = encodeVarintLog(data, i, uint64(*m.To)) @@ -2910,17 +2350,21 @@ func (m *Metadata) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Metadata) MarshalTo(data []byte) (n int, err error) { +func (m *Metadata) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Status != nil { + if m.Status == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("status") + } else { data[i] = 0x8 i++ i = encodeVarintLog(data, i, uint64(*m.Status)) } - if m.Promised != nil { + if m.Promised == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("promised") + } else { data[i] = 0x10 i++ i = encodeVarintLog(data, i, uint64(*m.Promised)) @@ -2941,12 +2385,14 @@ func (m *Record) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Record) MarshalTo(data []byte) (n int, err error) { +func (m *Record) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Type != nil { + if m.Type == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } else { data[i] = 0x8 i++ i = encodeVarintLog(data, i, uint64(*m.Type)) @@ -2997,12 +2443,14 @@ func (m *PromiseRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *PromiseRequest) MarshalTo(data []byte) (n int, err error) { +func (m *PromiseRequest) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Proposal != nil { + if m.Proposal == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("proposal") + } else { data[i] = 0x8 i++ i = encodeVarintLog(data, i, uint64(*m.Proposal)) @@ -3028,12 +2476,14 @@ func (m *PromiseResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *PromiseResponse) MarshalTo(data []byte) (n int, err error) { +func (m *PromiseResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Okay != nil { + if m.Okay == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("okay") + } else { data[i] = 0x8 i++ if *m.Okay { @@ -3043,16 +2493,13 @@ func (m *PromiseResponse) MarshalTo(data []byte) (n int, err error) { } i++ } - if m.Proposal != nil { + if m.Proposal == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("proposal") + } else { data[i] = 0x10 i++ i = encodeVarintLog(data, i, uint64(*m.Proposal)) } - if m.Position != nil { - data[i] = 0x20 - i++ - i = encodeVarintLog(data, i, uint64(*m.Position)) - } if m.Action != nil { data[i] = 0x1a i++ @@ -3063,6 +2510,11 @@ func (m *PromiseResponse) MarshalTo(data []byte) (n int, err error) { } i += n7 } + if m.Position != nil { + data[i] = 0x20 + i++ + i = encodeVarintLog(data, i, uint64(*m.Position)) + } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) } @@ -3079,17 +2531,21 @@ func (m *WriteRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *WriteRequest) MarshalTo(data []byte) (n int, err error) { +func (m *WriteRequest) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Proposal != nil { + if m.Proposal == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("proposal") + } else { data[i] = 0x8 i++ i = encodeVarintLog(data, i, uint64(*m.Proposal)) } - if m.Position != nil { + if m.Position == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("position") + } else { data[i] = 0x10 i++ i = encodeVarintLog(data, i, uint64(*m.Position)) @@ -3104,7 +2560,9 @@ func (m *WriteRequest) MarshalTo(data []byte) (n int, err error) { } i++ } - if m.Type != nil { + if m.Type == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } else { data[i] = 0x20 i++ i = encodeVarintLog(data, i, uint64(*m.Type)) @@ -3155,12 +2613,14 @@ func (m *WriteResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *WriteResponse) MarshalTo(data []byte) (n int, err error) { +func (m *WriteResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Okay != nil { + if m.Okay == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("okay") + } else { data[i] = 0x8 i++ if *m.Okay { @@ -3170,12 +2630,16 @@ func (m *WriteResponse) MarshalTo(data []byte) (n int, err error) { } i++ } - if m.Proposal != nil { + if m.Proposal == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("proposal") + } else { data[i] = 0x10 i++ i = encodeVarintLog(data, i, uint64(*m.Proposal)) } - if m.Position != nil { + if m.Position == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("position") + } else { data[i] = 0x18 i++ i = encodeVarintLog(data, i, uint64(*m.Position)) @@ -3196,12 +2660,14 @@ func (m *LearnedMessage) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *LearnedMessage) MarshalTo(data []byte) (n int, err error) { +func (m *LearnedMessage) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Action != nil { + if m.Action == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("action") + } else { data[i] = 0xa i++ i = encodeVarintLog(data, i, uint64(m.Action.Size())) @@ -3227,7 +2693,7 @@ func (m *RecoverRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *RecoverRequest) MarshalTo(data []byte) (n int, err error) { +func (m *RecoverRequest) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -3248,12 +2714,14 @@ func (m *RecoverResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *RecoverResponse) MarshalTo(data []byte) (n int, err error) { +func (m *RecoverResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Status != nil { + if m.Status == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("status") + } else { data[i] = 0x8 i++ i = encodeVarintLog(data, i, uint64(*m.Status)) @@ -3301,1406 +2769,2378 @@ func encodeVarintLog(data []byte, offset int, v uint64) int { data[offset] = uint8(v) return offset + 1 } -func (this *Promise) GoString() string { - if this == nil { - return "nil" +func NewPopulatedPromise(r randyLog, easy bool) *Promise { + this := &Promise{} + v1 := uint64(uint64(r.Uint32())) + this.Proposal = &v1 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 2) } - s := strings3.Join([]string{`&mesosproto.Promise{` + - `Proposal:` + valueToGoStringLog(this.Proposal, "uint64"), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + return this } -func (this *Action) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedAction(r randyLog, easy bool) *Action { + this := &Action{} + v2 := uint64(uint64(r.Uint32())) + this.Position = &v2 + v3 := uint64(uint64(r.Uint32())) + this.Promised = &v3 + if r.Intn(10) != 0 { + v4 := uint64(uint64(r.Uint32())) + this.Performed = &v4 } - s := strings3.Join([]string{`&mesosproto.Action{` + - `Position:` + valueToGoStringLog(this.Position, "uint64"), - `Promised:` + valueToGoStringLog(this.Promised, "uint64"), - `Performed:` + valueToGoStringLog(this.Performed, "uint64"), - `Learned:` + valueToGoStringLog(this.Learned, "bool"), - `Type:` + valueToGoStringLog(this.Type, "mesosproto.Action_Type"), - `Nop:` + fmt6.Sprintf("%#v", this.Nop), - `Append:` + fmt6.Sprintf("%#v", this.Append), - `Truncate:` + fmt6.Sprintf("%#v", this.Truncate), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + if r.Intn(10) != 0 { + v5 := bool(bool(r.Intn(2) == 0)) + this.Learned = &v5 + } + if r.Intn(10) != 0 { + v6 := Action_Type([]int32{1, 2, 3}[r.Intn(3)]) + this.Type = &v6 + } + if r.Intn(10) != 0 { + this.Nop = NewPopulatedAction_Nop(r, easy) + } + if r.Intn(10) != 0 { + this.Append = NewPopulatedAction_Append(r, easy) + } + if r.Intn(10) != 0 { + this.Truncate = NewPopulatedAction_Truncate(r, easy) + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 9) + } + return this } -func (this *Action_Nop) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedAction_Nop(r randyLog, easy bool) *Action_Nop { + this := &Action_Nop{} + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 1) } - s := strings3.Join([]string{`&mesosproto.Action_Nop{` + - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + return this } -func (this *Action_Append) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedAction_Append(r randyLog, easy bool) *Action_Append { + this := &Action_Append{} + v7 := r.Intn(100) + this.Bytes = make([]byte, v7) + for i := 0; i < v7; i++ { + this.Bytes[i] = byte(r.Intn(256)) } - s := strings3.Join([]string{`&mesosproto.Action_Append{` + - `Bytes:` + valueToGoStringLog(this.Bytes, "byte"), - `Cksum:` + valueToGoStringLog(this.Cksum, "byte"), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + if r.Intn(10) != 0 { + v8 := r.Intn(100) + this.Cksum = make([]byte, v8) + for i := 0; i < v8; i++ { + this.Cksum[i] = byte(r.Intn(256)) + } + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 3) + } + return this } -func (this *Action_Truncate) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedAction_Truncate(r randyLog, easy bool) *Action_Truncate { + this := &Action_Truncate{} + v9 := uint64(uint64(r.Uint32())) + this.To = &v9 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 2) } - s := strings3.Join([]string{`&mesosproto.Action_Truncate{` + - `To:` + valueToGoStringLog(this.To, "uint64"), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + return this } -func (this *Metadata) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedMetadata(r randyLog, easy bool) *Metadata { + this := &Metadata{} + v10 := Metadata_Status([]int32{1, 2, 3, 4}[r.Intn(4)]) + this.Status = &v10 + v11 := uint64(uint64(r.Uint32())) + this.Promised = &v11 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 3) } - s := strings3.Join([]string{`&mesosproto.Metadata{` + - `Status:` + valueToGoStringLog(this.Status, "mesosproto.Metadata_Status"), - `Promised:` + valueToGoStringLog(this.Promised, "uint64"), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + return this } -func (this *Record) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedRecord(r randyLog, easy bool) *Record { + this := &Record{} + v12 := Record_Type([]int32{1, 2, 3}[r.Intn(3)]) + this.Type = &v12 + if r.Intn(10) != 0 { + this.Promise = NewPopulatedPromise(r, easy) } - s := strings3.Join([]string{`&mesosproto.Record{` + - `Type:` + valueToGoStringLog(this.Type, "mesosproto.Record_Type"), - `Promise:` + fmt6.Sprintf("%#v", this.Promise), - `Action:` + fmt6.Sprintf("%#v", this.Action), - `Metadata:` + fmt6.Sprintf("%#v", this.Metadata), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + if r.Intn(10) != 0 { + this.Action = NewPopulatedAction(r, easy) + } + if r.Intn(10) != 0 { + this.Metadata = NewPopulatedMetadata(r, easy) + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 5) + } + return this } -func (this *PromiseRequest) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedPromiseRequest(r randyLog, easy bool) *PromiseRequest { + this := &PromiseRequest{} + v13 := uint64(uint64(r.Uint32())) + this.Proposal = &v13 + if r.Intn(10) != 0 { + v14 := uint64(uint64(r.Uint32())) + this.Position = &v14 } - s := strings3.Join([]string{`&mesosproto.PromiseRequest{` + - `Proposal:` + valueToGoStringLog(this.Proposal, "uint64"), - `Position:` + valueToGoStringLog(this.Position, "uint64"), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 3) + } + return this } -func (this *PromiseResponse) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedPromiseResponse(r randyLog, easy bool) *PromiseResponse { + this := &PromiseResponse{} + v15 := bool(bool(r.Intn(2) == 0)) + this.Okay = &v15 + v16 := uint64(uint64(r.Uint32())) + this.Proposal = &v16 + if r.Intn(10) != 0 { + this.Action = NewPopulatedAction(r, easy) + } + if r.Intn(10) != 0 { + v17 := uint64(uint64(r.Uint32())) + this.Position = &v17 + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 5) } - s := strings3.Join([]string{`&mesosproto.PromiseResponse{` + - `Okay:` + valueToGoStringLog(this.Okay, "bool"), - `Proposal:` + valueToGoStringLog(this.Proposal, "uint64"), - `Position:` + valueToGoStringLog(this.Position, "uint64"), - `Action:` + fmt6.Sprintf("%#v", this.Action), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + return this } -func (this *WriteRequest) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedWriteRequest(r randyLog, easy bool) *WriteRequest { + this := &WriteRequest{} + v18 := uint64(uint64(r.Uint32())) + this.Proposal = &v18 + v19 := uint64(uint64(r.Uint32())) + this.Position = &v19 + if r.Intn(10) != 0 { + v20 := bool(bool(r.Intn(2) == 0)) + this.Learned = &v20 } - s := strings3.Join([]string{`&mesosproto.WriteRequest{` + - `Proposal:` + valueToGoStringLog(this.Proposal, "uint64"), - `Position:` + valueToGoStringLog(this.Position, "uint64"), - `Learned:` + valueToGoStringLog(this.Learned, "bool"), - `Type:` + valueToGoStringLog(this.Type, "mesosproto.Action_Type"), - `Nop:` + fmt6.Sprintf("%#v", this.Nop), - `Append:` + fmt6.Sprintf("%#v", this.Append), - `Truncate:` + fmt6.Sprintf("%#v", this.Truncate), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *WriteResponse) GoString() string { - if this == nil { - return "nil" + v21 := Action_Type([]int32{1, 2, 3}[r.Intn(3)]) + this.Type = &v21 + if r.Intn(10) != 0 { + this.Nop = NewPopulatedAction_Nop(r, easy) } - s := strings3.Join([]string{`&mesosproto.WriteResponse{` + - `Okay:` + valueToGoStringLog(this.Okay, "bool"), - `Proposal:` + valueToGoStringLog(this.Proposal, "uint64"), - `Position:` + valueToGoStringLog(this.Position, "uint64"), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *LearnedMessage) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + this.Append = NewPopulatedAction_Append(r, easy) } - s := strings3.Join([]string{`&mesosproto.LearnedMessage{` + - `Action:` + fmt6.Sprintf("%#v", this.Action), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + if r.Intn(10) != 0 { + this.Truncate = NewPopulatedAction_Truncate(r, easy) + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 8) + } + return this } -func (this *RecoverRequest) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedWriteResponse(r randyLog, easy bool) *WriteResponse { + this := &WriteResponse{} + v22 := bool(bool(r.Intn(2) == 0)) + this.Okay = &v22 + v23 := uint64(uint64(r.Uint32())) + this.Proposal = &v23 + v24 := uint64(uint64(r.Uint32())) + this.Position = &v24 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 4) } - s := strings3.Join([]string{`&mesosproto.RecoverRequest{` + - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + return this } -func (this *RecoverResponse) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedLearnedMessage(r randyLog, easy bool) *LearnedMessage { + this := &LearnedMessage{} + this.Action = NewPopulatedAction(r, easy) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 2) } - s := strings3.Join([]string{`&mesosproto.RecoverResponse{` + - `Status:` + valueToGoStringLog(this.Status, "mesosproto.Metadata_Status"), - `Begin:` + valueToGoStringLog(this.Begin, "uint64"), - `End:` + valueToGoStringLog(this.End, "uint64"), - `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + return this } -func valueToGoStringLog(v interface{}, typ string) string { - rv := reflect3.ValueOf(v) - if rv.IsNil() { - return "nil" + +func NewPopulatedRecoverRequest(r randyLog, easy bool) *RecoverRequest { + this := &RecoverRequest{} + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 1) } - pv := reflect3.Indirect(rv).Interface() - return fmt6.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) + return this } -func extensionToGoStringLog(e map[int32]github_com_gogo_protobuf_proto3.Extension) string { - if e == nil { - return "nil" + +func NewPopulatedRecoverResponse(r randyLog, easy bool) *RecoverResponse { + this := &RecoverResponse{} + v25 := Metadata_Status([]int32{1, 2, 3, 4}[r.Intn(4)]) + this.Status = &v25 + if r.Intn(10) != 0 { + v26 := uint64(uint64(r.Uint32())) + this.Begin = &v26 } - s := "map[int32]proto.Extension{" - keys := make([]int, 0, len(e)) - for k := range e { - keys = append(keys, int(k)) + if r.Intn(10) != 0 { + v27 := uint64(uint64(r.Uint32())) + this.End = &v27 } - sort1.Ints(keys) - ss := []string{} - for _, k := range keys { - ss = append(ss, strconv1.Itoa(k)+": "+e[int32(k)].GoString()) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedLog(r, 4) } - s += strings3.Join(ss, ",") + "}" - return s + return this } -func (this *Promise) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that == nil && this != nil") - } - that1, ok := that.(*Promise) - if !ok { - return fmt7.Errorf("that is not of type *Promise") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *Promise but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *Promisebut is not nil && this == nil") - } - if this.Proposal != nil && that1.Proposal != nil { - if *this.Proposal != *that1.Proposal { - return fmt7.Errorf("Proposal this(%v) Not Equal that(%v)", *this.Proposal, *that1.Proposal) - } - } else if this.Proposal != nil { - return fmt7.Errorf("this.Proposal == nil && that.Proposal != nil") - } else if that1.Proposal != nil { - return fmt7.Errorf("Proposal this(%v) Not Equal that(%v)", this.Proposal, that1.Proposal) +type randyLog interface { + Float32() float32 + Float64() float64 + Int63() int64 + Int31() int32 + Uint32() uint32 + Intn(n int) int +} + +func randUTF8RuneLog(r randyLog) rune { + ru := r.Intn(62) + if ru < 10 { + return rune(ru + 48) + } else if ru < 36 { + return rune(ru + 55) } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + return rune(ru + 61) +} +func randStringLog(r randyLog) string { + v28 := r.Intn(100) + tmps := make([]rune, v28) + for i := 0; i < v28; i++ { + tmps[i] = randUTF8RuneLog(r) } - return nil + return string(tmps) } -func (this *Promise) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func randUnrecognizedLog(r randyLog, maxFieldNumber int) (data []byte) { + l := r.Intn(5) + for i := 0; i < l; i++ { + wire := r.Intn(4) + if wire == 3 { + wire = 5 } - return false - } - - that1, ok := that.(*Promise) - if !ok { - return false + fieldNumber := maxFieldNumber + r.Intn(100) + data = randFieldLog(data, r, fieldNumber, wire) } - if that1 == nil { - if this == nil { - return true + return data +} +func randFieldLog(data []byte, r randyLog, fieldNumber int, wire int) []byte { + key := uint32(fieldNumber)<<3 | uint32(wire) + switch wire { + case 0: + data = encodeVarintPopulateLog(data, uint64(key)) + v29 := r.Int63() + if r.Intn(2) == 0 { + v29 *= -1 } - return false - } else if this == nil { - return false - } - if this.Proposal != nil && that1.Proposal != nil { - if *this.Proposal != *that1.Proposal { - return false + data = encodeVarintPopulateLog(data, uint64(v29)) + case 1: + data = encodeVarintPopulateLog(data, uint64(key)) + data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) + case 2: + data = encodeVarintPopulateLog(data, uint64(key)) + ll := r.Intn(100) + data = encodeVarintPopulateLog(data, uint64(ll)) + for j := 0; j < ll; j++ { + data = append(data, byte(r.Intn(256))) } - } else if this.Proposal != nil { - return false - } else if that1.Proposal != nil { - return false - } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + default: + data = encodeVarintPopulateLog(data, uint64(key)) + data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) } - return true + return data } -func (this *Action) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that == nil && this != nil") +func encodeVarintPopulateLog(data []byte, v uint64) []byte { + for v >= 1<<7 { + data = append(data, uint8(uint64(v)&0x7f|0x80)) + v >>= 7 } - - that1, ok := that.(*Action) - if !ok { - return fmt7.Errorf("that is not of type *Action") + data = append(data, uint8(v)) + return data +} +func (m *Promise) Size() (n int) { + var l int + _ = l + if m.Proposal != nil { + n += 1 + sovLog(uint64(*m.Proposal)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *Action but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *Actionbut is not nil && this == nil") + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.Position != nil && that1.Position != nil { - if *this.Position != *that1.Position { - return fmt7.Errorf("Position this(%v) Not Equal that(%v)", *this.Position, *that1.Position) - } - } else if this.Position != nil { - return fmt7.Errorf("this.Position == nil && that.Position != nil") - } else if that1.Position != nil { - return fmt7.Errorf("Position this(%v) Not Equal that(%v)", this.Position, that1.Position) + return n +} + +func (m *Action) Size() (n int) { + var l int + _ = l + if m.Position != nil { + n += 1 + sovLog(uint64(*m.Position)) } - if this.Promised != nil && that1.Promised != nil { - if *this.Promised != *that1.Promised { - return fmt7.Errorf("Promised this(%v) Not Equal that(%v)", *this.Promised, *that1.Promised) - } - } else if this.Promised != nil { - return fmt7.Errorf("this.Promised == nil && that.Promised != nil") - } else if that1.Promised != nil { - return fmt7.Errorf("Promised this(%v) Not Equal that(%v)", this.Promised, that1.Promised) + if m.Promised != nil { + n += 1 + sovLog(uint64(*m.Promised)) } - if this.Performed != nil && that1.Performed != nil { - if *this.Performed != *that1.Performed { - return fmt7.Errorf("Performed this(%v) Not Equal that(%v)", *this.Performed, *that1.Performed) - } - } else if this.Performed != nil { - return fmt7.Errorf("this.Performed == nil && that.Performed != nil") - } else if that1.Performed != nil { - return fmt7.Errorf("Performed this(%v) Not Equal that(%v)", this.Performed, that1.Performed) + if m.Performed != nil { + n += 1 + sovLog(uint64(*m.Performed)) } - if this.Learned != nil && that1.Learned != nil { - if *this.Learned != *that1.Learned { - return fmt7.Errorf("Learned this(%v) Not Equal that(%v)", *this.Learned, *that1.Learned) - } - } else if this.Learned != nil { - return fmt7.Errorf("this.Learned == nil && that.Learned != nil") - } else if that1.Learned != nil { - return fmt7.Errorf("Learned this(%v) Not Equal that(%v)", this.Learned, that1.Learned) + if m.Learned != nil { + n += 2 } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return fmt7.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) - } - } else if this.Type != nil { - return fmt7.Errorf("this.Type == nil && that.Type != nil") - } else if that1.Type != nil { - return fmt7.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + if m.Type != nil { + n += 1 + sovLog(uint64(*m.Type)) } - if !this.Nop.Equal(that1.Nop) { - return fmt7.Errorf("Nop this(%v) Not Equal that(%v)", this.Nop, that1.Nop) + if m.Nop != nil { + l = m.Nop.Size() + n += 1 + l + sovLog(uint64(l)) } - if !this.Append.Equal(that1.Append) { - return fmt7.Errorf("Append this(%v) Not Equal that(%v)", this.Append, that1.Append) + if m.Append != nil { + l = m.Append.Size() + n += 1 + l + sovLog(uint64(l)) } - if !this.Truncate.Equal(that1.Truncate) { - return fmt7.Errorf("Truncate this(%v) Not Equal that(%v)", this.Truncate, that1.Truncate) + if m.Truncate != nil { + l = m.Truncate.Size() + n += 1 + l + sovLog(uint64(l)) } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *Action) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - that1, ok := that.(*Action) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Position != nil && that1.Position != nil { - if *this.Position != *that1.Position { - return false - } - } else if this.Position != nil { - return false - } else if that1.Position != nil { - return false +func (m *Action_Nop) Size() (n int) { + var l int + _ = l + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.Promised != nil && that1.Promised != nil { - if *this.Promised != *that1.Promised { - return false - } - } else if this.Promised != nil { - return false - } else if that1.Promised != nil { - return false + return n +} + +func (m *Action_Append) Size() (n int) { + var l int + _ = l + if m.Bytes != nil { + l = len(m.Bytes) + n += 1 + l + sovLog(uint64(l)) } - if this.Performed != nil && that1.Performed != nil { - if *this.Performed != *that1.Performed { - return false - } - } else if this.Performed != nil { - return false - } else if that1.Performed != nil { - return false + if m.Cksum != nil { + l = len(m.Cksum) + n += 1 + l + sovLog(uint64(l)) } - if this.Learned != nil && that1.Learned != nil { - if *this.Learned != *that1.Learned { - return false - } - } else if this.Learned != nil { - return false - } else if that1.Learned != nil { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return false - } - } else if this.Type != nil { - return false - } else if that1.Type != nil { - return false + return n +} + +func (m *Action_Truncate) Size() (n int) { + var l int + _ = l + if m.To != nil { + n += 1 + sovLog(uint64(*m.To)) } - if !this.Nop.Equal(that1.Nop) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.Append.Equal(that1.Append) { - return false + return n +} + +func (m *Metadata) Size() (n int) { + var l int + _ = l + if m.Status != nil { + n += 1 + sovLog(uint64(*m.Status)) } - if !this.Truncate.Equal(that1.Truncate) { - return false + if m.Promised != nil { + n += 1 + sovLog(uint64(*m.Promised)) } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *Action_Nop) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that == nil && this != nil") - } - that1, ok := that.(*Action_Nop) - if !ok { - return fmt7.Errorf("that is not of type *Action_Nop") +func (m *Record) Size() (n int) { + var l int + _ = l + if m.Type != nil { + n += 1 + sovLog(uint64(*m.Type)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *Action_Nop but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *Action_Nopbut is not nil && this == nil") + if m.Promise != nil { + l = m.Promise.Size() + n += 1 + l + sovLog(uint64(l)) } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.Action != nil { + l = m.Action.Size() + n += 1 + l + sovLog(uint64(l)) } - return nil -} -func (this *Action_Nop) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + if m.Metadata != nil { + l = m.Metadata.Size() + n += 1 + l + sovLog(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } + return n +} - that1, ok := that.(*Action_Nop) - if !ok { - return false +func (m *PromiseRequest) Size() (n int) { + var l int + _ = l + if m.Proposal != nil { + n += 1 + sovLog(uint64(*m.Proposal)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.Position != nil { + n += 1 + sovLog(uint64(*m.Position)) } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *Action_Append) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that == nil && this != nil") - } - that1, ok := that.(*Action_Append) - if !ok { - return fmt7.Errorf("that is not of type *Action_Append") +func (m *PromiseResponse) Size() (n int) { + var l int + _ = l + if m.Okay != nil { + n += 2 } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *Action_Append but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *Action_Appendbut is not nil && this == nil") + if m.Proposal != nil { + n += 1 + sovLog(uint64(*m.Proposal)) } - if !bytes1.Equal(this.Bytes, that1.Bytes) { - return fmt7.Errorf("Bytes this(%v) Not Equal that(%v)", this.Bytes, that1.Bytes) + if m.Action != nil { + l = m.Action.Size() + n += 1 + l + sovLog(uint64(l)) } - if !bytes1.Equal(this.Cksum, that1.Cksum) { - return fmt7.Errorf("Cksum this(%v) Not Equal that(%v)", this.Cksum, that1.Cksum) + if m.Position != nil { + n += 1 + sovLog(uint64(*m.Position)) } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *Action_Append) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - that1, ok := that.(*Action_Append) - if !ok { - return false +func (m *WriteRequest) Size() (n int) { + var l int + _ = l + if m.Proposal != nil { + n += 1 + sovLog(uint64(*m.Proposal)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.Position != nil { + n += 1 + sovLog(uint64(*m.Position)) } - if !bytes1.Equal(this.Bytes, that1.Bytes) { - return false + if m.Learned != nil { + n += 2 } - if !bytes1.Equal(this.Cksum, that1.Cksum) { - return false + if m.Type != nil { + n += 1 + sovLog(uint64(*m.Type)) + } + if m.Nop != nil { + l = m.Nop.Size() + n += 1 + l + sovLog(uint64(l)) + } + if m.Append != nil { + l = m.Append.Size() + n += 1 + l + sovLog(uint64(l)) + } + if m.Truncate != nil { + l = m.Truncate.Size() + n += 1 + l + sovLog(uint64(l)) } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *Action_Truncate) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that == nil && this != nil") - } - that1, ok := that.(*Action_Truncate) - if !ok { - return fmt7.Errorf("that is not of type *Action_Truncate") +func (m *WriteResponse) Size() (n int) { + var l int + _ = l + if m.Okay != nil { + n += 2 } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *Action_Truncate but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *Action_Truncatebut is not nil && this == nil") + if m.Proposal != nil { + n += 1 + sovLog(uint64(*m.Proposal)) } - if this.To != nil && that1.To != nil { - if *this.To != *that1.To { - return fmt7.Errorf("To this(%v) Not Equal that(%v)", *this.To, *that1.To) - } - } else if this.To != nil { - return fmt7.Errorf("this.To == nil && that.To != nil") - } else if that1.To != nil { - return fmt7.Errorf("To this(%v) Not Equal that(%v)", this.To, that1.To) + if m.Position != nil { + n += 1 + sovLog(uint64(*m.Position)) } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *Action_Truncate) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + +func (m *LearnedMessage) Size() (n int) { + var l int + _ = l + if m.Action != nil { + l = m.Action.Size() + n += 1 + l + sovLog(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } + return n +} - that1, ok := that.(*Action_Truncate) - if !ok { - return false +func (m *RecoverRequest) Size() (n int) { + var l int + _ = l + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + return n +} + +func (m *RecoverResponse) Size() (n int) { + var l int + _ = l + if m.Status != nil { + n += 1 + sovLog(uint64(*m.Status)) } - if this.To != nil && that1.To != nil { - if *this.To != *that1.To { - return false - } - } else if this.To != nil { - return false - } else if that1.To != nil { - return false + if m.Begin != nil { + n += 1 + sovLog(uint64(*m.Begin)) } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.End != nil { + n += 1 + sovLog(uint64(*m.End)) } - return true + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n } -func (this *Metadata) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil + +func sovLog(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break } - return fmt7.Errorf("that == nil && this != nil") } - - that1, ok := that.(*Metadata) - if !ok { - return fmt7.Errorf("that is not of type *Metadata") + return n +} +func sozLog(x uint64) (n int) { + return sovLog(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *Promise) String() string { + if this == nil { + return "nil" } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *Metadata but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *Metadatabut is not nil && this == nil") + s := strings.Join([]string{`&Promise{`, + `Proposal:` + valueToStringLog(this.Proposal) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Action) String() string { + if this == nil { + return "nil" } - if this.Status != nil && that1.Status != nil { - if *this.Status != *that1.Status { - return fmt7.Errorf("Status this(%v) Not Equal that(%v)", *this.Status, *that1.Status) - } - } else if this.Status != nil { - return fmt7.Errorf("this.Status == nil && that.Status != nil") - } else if that1.Status != nil { - return fmt7.Errorf("Status this(%v) Not Equal that(%v)", this.Status, that1.Status) + s := strings.Join([]string{`&Action{`, + `Position:` + valueToStringLog(this.Position) + `,`, + `Promised:` + valueToStringLog(this.Promised) + `,`, + `Performed:` + valueToStringLog(this.Performed) + `,`, + `Learned:` + valueToStringLog(this.Learned) + `,`, + `Type:` + valueToStringLog(this.Type) + `,`, + `Nop:` + strings.Replace(fmt.Sprintf("%v", this.Nop), "Action_Nop", "Action_Nop", 1) + `,`, + `Append:` + strings.Replace(fmt.Sprintf("%v", this.Append), "Action_Append", "Action_Append", 1) + `,`, + `Truncate:` + strings.Replace(fmt.Sprintf("%v", this.Truncate), "Action_Truncate", "Action_Truncate", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Action_Nop) String() string { + if this == nil { + return "nil" } - if this.Promised != nil && that1.Promised != nil { - if *this.Promised != *that1.Promised { - return fmt7.Errorf("Promised this(%v) Not Equal that(%v)", *this.Promised, *that1.Promised) - } - } else if this.Promised != nil { - return fmt7.Errorf("this.Promised == nil && that.Promised != nil") - } else if that1.Promised != nil { - return fmt7.Errorf("Promised this(%v) Not Equal that(%v)", this.Promised, that1.Promised) + s := strings.Join([]string{`&Action_Nop{`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Action_Append) String() string { + if this == nil { + return "nil" } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + s := strings.Join([]string{`&Action_Append{`, + `Bytes:` + valueToStringLog(this.Bytes) + `,`, + `Cksum:` + valueToStringLog(this.Cksum) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Action_Truncate) String() string { + if this == nil { + return "nil" } - return nil + s := strings.Join([]string{`&Action_Truncate{`, + `To:` + valueToStringLog(this.To) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s } -func (this *Metadata) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false +func (this *Metadata) String() string { + if this == nil { + return "nil" } - - that1, ok := that.(*Metadata) - if !ok { - return false + s := strings.Join([]string{`&Metadata{`, + `Status:` + valueToStringLog(this.Status) + `,`, + `Promised:` + valueToStringLog(this.Promised) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Record) String() string { + if this == nil { + return "nil" } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + s := strings.Join([]string{`&Record{`, + `Type:` + valueToStringLog(this.Type) + `,`, + `Promise:` + strings.Replace(fmt.Sprintf("%v", this.Promise), "Promise", "Promise", 1) + `,`, + `Action:` + strings.Replace(fmt.Sprintf("%v", this.Action), "Action", "Action", 1) + `,`, + `Metadata:` + strings.Replace(fmt.Sprintf("%v", this.Metadata), "Metadata", "Metadata", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *PromiseRequest) String() string { + if this == nil { + return "nil" } - if this.Status != nil && that1.Status != nil { - if *this.Status != *that1.Status { - return false - } - } else if this.Status != nil { - return false - } else if that1.Status != nil { - return false + s := strings.Join([]string{`&PromiseRequest{`, + `Proposal:` + valueToStringLog(this.Proposal) + `,`, + `Position:` + valueToStringLog(this.Position) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *PromiseResponse) String() string { + if this == nil { + return "nil" } - if this.Promised != nil && that1.Promised != nil { - if *this.Promised != *that1.Promised { - return false - } - } else if this.Promised != nil { - return false - } else if that1.Promised != nil { - return false + s := strings.Join([]string{`&PromiseResponse{`, + `Okay:` + valueToStringLog(this.Okay) + `,`, + `Proposal:` + valueToStringLog(this.Proposal) + `,`, + `Action:` + strings.Replace(fmt.Sprintf("%v", this.Action), "Action", "Action", 1) + `,`, + `Position:` + valueToStringLog(this.Position) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *WriteRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&WriteRequest{`, + `Proposal:` + valueToStringLog(this.Proposal) + `,`, + `Position:` + valueToStringLog(this.Position) + `,`, + `Learned:` + valueToStringLog(this.Learned) + `,`, + `Type:` + valueToStringLog(this.Type) + `,`, + `Nop:` + strings.Replace(fmt.Sprintf("%v", this.Nop), "Action_Nop", "Action_Nop", 1) + `,`, + `Append:` + strings.Replace(fmt.Sprintf("%v", this.Append), "Action_Append", "Action_Append", 1) + `,`, + `Truncate:` + strings.Replace(fmt.Sprintf("%v", this.Truncate), "Action_Truncate", "Action_Truncate", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *WriteResponse) String() string { + if this == nil { + return "nil" } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + s := strings.Join([]string{`&WriteResponse{`, + `Okay:` + valueToStringLog(this.Okay) + `,`, + `Proposal:` + valueToStringLog(this.Proposal) + `,`, + `Position:` + valueToStringLog(this.Position) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *LearnedMessage) String() string { + if this == nil { + return "nil" } - return true + s := strings.Join([]string{`&LearnedMessage{`, + `Action:` + strings.Replace(fmt.Sprintf("%v", this.Action), "Action", "Action", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s } -func (this *Record) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that == nil && this != nil") +func (this *RecoverRequest) String() string { + if this == nil { + return "nil" } - - that1, ok := that.(*Record) - if !ok { - return fmt7.Errorf("that is not of type *Record") + s := strings.Join([]string{`&RecoverRequest{`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *RecoverResponse) String() string { + if this == nil { + return "nil" } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *Record but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *Recordbut is not nil && this == nil") + s := strings.Join([]string{`&RecoverResponse{`, + `Status:` + valueToStringLog(this.Status) + `,`, + `Begin:` + valueToStringLog(this.Begin) + `,`, + `End:` + valueToStringLog(this.End) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func valueToStringLog(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return fmt7.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *Promise) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Proposal", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Proposal = &v + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Type != nil { - return fmt7.Errorf("this.Type == nil && that.Type != nil") - } else if that1.Type != nil { - return fmt7.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) - } - if !this.Promise.Equal(that1.Promise) { - return fmt7.Errorf("Promise this(%v) Not Equal that(%v)", this.Promise, that1.Promise) - } - if !this.Action.Equal(that1.Action) { - return fmt7.Errorf("Action this(%v) Not Equal that(%v)", this.Action, that1.Action) - } - if !this.Metadata.Equal(that1.Metadata) { - return fmt7.Errorf("Metadata this(%v) Not Equal that(%v)", this.Metadata, that1.Metadata) } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("proposal") } + return nil } -func (this *Record) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*Record) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true +func (m *Action) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } else if this == nil { - return false - } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Position", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Position = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Promised", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Promised = &v + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Performed", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Performed = &v + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Learned", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Learned = &b + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v Action_Type + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (Action_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Nop", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Nop == nil { + m.Nop = &Action_Nop{} + } + if err := m.Nop.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Append", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Append == nil { + m.Append = &Action_Append{} + } + if err := m.Append.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Truncate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Truncate == nil { + m.Truncate = &Action_Truncate{} + } + if err := m.Truncate.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Type != nil { - return false - } else if that1.Type != nil { - return false - } - if !this.Promise.Equal(that1.Promise) { - return false - } - if !this.Action.Equal(that1.Action) { - return false - } - if !this.Metadata.Equal(that1.Metadata) { - return false } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("position") } - return true -} -func (this *PromiseRequest) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("promised") } - that1, ok := that.(*PromiseRequest) - if !ok { - return fmt7.Errorf("that is not of type *PromiseRequest") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *PromiseRequest but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *PromiseRequestbut is not nil && this == nil") - } - if this.Proposal != nil && that1.Proposal != nil { - if *this.Proposal != *that1.Proposal { - return fmt7.Errorf("Proposal this(%v) Not Equal that(%v)", *this.Proposal, *that1.Proposal) - } - } else if this.Proposal != nil { - return fmt7.Errorf("this.Proposal == nil && that.Proposal != nil") - } else if that1.Proposal != nil { - return fmt7.Errorf("Proposal this(%v) Not Equal that(%v)", this.Proposal, that1.Proposal) - } - if this.Position != nil && that1.Position != nil { - if *this.Position != *that1.Position { - return fmt7.Errorf("Position this(%v) Not Equal that(%v)", *this.Position, *that1.Position) - } - } else if this.Position != nil { - return fmt7.Errorf("this.Position == nil && that.Position != nil") - } else if that1.Position != nil { - return fmt7.Errorf("Position this(%v) Not Equal that(%v)", this.Position, that1.Position) - } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *PromiseRequest) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*PromiseRequest) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Proposal != nil && that1.Proposal != nil { - if *this.Proposal != *that1.Proposal { - return false - } - } else if this.Proposal != nil { - return false - } else if that1.Proposal != nil { - return false - } - if this.Position != nil && that1.Position != nil { - if *this.Position != *that1.Position { - return false +func (m *Action_Nop) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Position != nil { - return false - } else if that1.Position != nil { - return false - } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true -} -func (this *PromiseResponse) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil + fieldNum := int32(wire >> 3) + switch fieldNum { + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt7.Errorf("that == nil && this != nil") } - that1, ok := that.(*PromiseResponse) - if !ok { - return fmt7.Errorf("that is not of type *PromiseResponse") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *PromiseResponse but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *PromiseResponsebut is not nil && this == nil") - } - if this.Okay != nil && that1.Okay != nil { - if *this.Okay != *that1.Okay { - return fmt7.Errorf("Okay this(%v) Not Equal that(%v)", *this.Okay, *that1.Okay) - } - } else if this.Okay != nil { - return fmt7.Errorf("this.Okay == nil && that.Okay != nil") - } else if that1.Okay != nil { - return fmt7.Errorf("Okay this(%v) Not Equal that(%v)", this.Okay, that1.Okay) - } - if this.Proposal != nil && that1.Proposal != nil { - if *this.Proposal != *that1.Proposal { - return fmt7.Errorf("Proposal this(%v) Not Equal that(%v)", *this.Proposal, *that1.Proposal) - } - } else if this.Proposal != nil { - return fmt7.Errorf("this.Proposal == nil && that.Proposal != nil") - } else if that1.Proposal != nil { - return fmt7.Errorf("Proposal this(%v) Not Equal that(%v)", this.Proposal, that1.Proposal) - } - if this.Position != nil && that1.Position != nil { - if *this.Position != *that1.Position { - return fmt7.Errorf("Position this(%v) Not Equal that(%v)", *this.Position, *that1.Position) - } - } else if this.Position != nil { - return fmt7.Errorf("this.Position == nil && that.Position != nil") - } else if that1.Position != nil { - return fmt7.Errorf("Position this(%v) Not Equal that(%v)", this.Position, that1.Position) - } - if !this.Action.Equal(that1.Action) { - return fmt7.Errorf("Action this(%v) Not Equal that(%v)", this.Action, that1.Action) - } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *PromiseResponse) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*PromiseResponse) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Okay != nil && that1.Okay != nil { - if *this.Okay != *that1.Okay { - return false - } - } else if this.Okay != nil { - return false - } else if that1.Okay != nil { - return false - } - if this.Proposal != nil && that1.Proposal != nil { - if *this.Proposal != *that1.Proposal { - return false - } - } else if this.Proposal != nil { - return false - } else if that1.Proposal != nil { - return false - } - if this.Position != nil && that1.Position != nil { - if *this.Position != *that1.Position { - return false - } - } else if this.Position != nil { - return false - } else if that1.Position != nil { - return false - } - if !this.Action.Equal(that1.Action) { - return false - } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true -} -func (this *WriteRequest) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that == nil && this != nil") - } - - that1, ok := that.(*WriteRequest) - if !ok { - return fmt7.Errorf("that is not of type *WriteRequest") - } - if that1 == nil { - if this == nil { - return nil +func (m *Action_Append) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return fmt7.Errorf("that is type *WriteRequest but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *WriteRequestbut is not nil && this == nil") - } - if this.Proposal != nil && that1.Proposal != nil { - if *this.Proposal != *that1.Proposal { - return fmt7.Errorf("Proposal this(%v) Not Equal that(%v)", *this.Proposal, *that1.Proposal) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Bytes", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Bytes = append([]byte{}, data[iNdEx:postIndex]...) + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Cksum", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Cksum = append([]byte{}, data[iNdEx:postIndex]...) + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Proposal != nil { - return fmt7.Errorf("this.Proposal == nil && that.Proposal != nil") - } else if that1.Proposal != nil { - return fmt7.Errorf("Proposal this(%v) Not Equal that(%v)", this.Proposal, that1.Proposal) } - if this.Position != nil && that1.Position != nil { - if *this.Position != *that1.Position { - return fmt7.Errorf("Position this(%v) Not Equal that(%v)", *this.Position, *that1.Position) - } - } else if this.Position != nil { - return fmt7.Errorf("this.Position == nil && that.Position != nil") - } else if that1.Position != nil { - return fmt7.Errorf("Position this(%v) Not Equal that(%v)", this.Position, that1.Position) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("bytes") } - if this.Learned != nil && that1.Learned != nil { - if *this.Learned != *that1.Learned { - return fmt7.Errorf("Learned this(%v) Not Equal that(%v)", *this.Learned, *that1.Learned) + + return nil +} +func (m *Action_Truncate) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Learned != nil { - return fmt7.Errorf("this.Learned == nil && that.Learned != nil") - } else if that1.Learned != nil { - return fmt7.Errorf("Learned this(%v) Not Equal that(%v)", this.Learned, that1.Learned) - } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return fmt7.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field To", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.To = &v + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Type != nil { - return fmt7.Errorf("this.Type == nil && that.Type != nil") - } else if that1.Type != nil { - return fmt7.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) } - if !this.Nop.Equal(that1.Nop) { - return fmt7.Errorf("Nop this(%v) Not Equal that(%v)", this.Nop, that1.Nop) - } - if !this.Append.Equal(that1.Append) { - return fmt7.Errorf("Append this(%v) Not Equal that(%v)", this.Append, that1.Append) - } - if !this.Truncate.Equal(that1.Truncate) { - return fmt7.Errorf("Truncate this(%v) Not Equal that(%v)", this.Truncate, that1.Truncate) - } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("to") } + return nil } -func (this *WriteRequest) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *Metadata) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } - - that1, ok := that.(*WriteRequest) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var v Metadata_Status + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (Metadata_Status(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Status = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Promised", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Promised = &v + hasFields[0] |= uint64(0x00000002) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false - } else if this == nil { - return false } - if this.Proposal != nil && that1.Proposal != nil { - if *this.Proposal != *that1.Proposal { - return false - } - } else if this.Proposal != nil { - return false - } else if that1.Proposal != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("status") } - if this.Position != nil && that1.Position != nil { - if *this.Position != *that1.Position { - return false - } - } else if this.Position != nil { - return false - } else if that1.Position != nil { - return false + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("promised") } - if this.Learned != nil && that1.Learned != nil { - if *this.Learned != *that1.Learned { - return false + + return nil +} +func (m *Record) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Learned != nil { - return false - } else if that1.Learned != nil { - return false - } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v Record_Type + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (Record_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Promise", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Promise == nil { + m.Promise = &Promise{} + } + if err := m.Promise.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Action == nil { + m.Action = &Action{} + } + if err := m.Action.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Metadata == nil { + m.Metadata = &Metadata{} + } + if err := m.Metadata.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Type != nil { - return false - } else if that1.Type != nil { - return false - } - if !this.Nop.Equal(that1.Nop) { - return false - } - if !this.Append.Equal(that1.Append) { - return false - } - if !this.Truncate.Equal(that1.Truncate) { - return false } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true -} -func (this *WriteResponse) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") } - that1, ok := that.(*WriteResponse) - if !ok { - return fmt7.Errorf("that is not of type *WriteResponse") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *WriteResponse but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *WriteResponsebut is not nil && this == nil") - } - if this.Okay != nil && that1.Okay != nil { - if *this.Okay != *that1.Okay { - return fmt7.Errorf("Okay this(%v) Not Equal that(%v)", *this.Okay, *that1.Okay) - } - } else if this.Okay != nil { - return fmt7.Errorf("this.Okay == nil && that.Okay != nil") - } else if that1.Okay != nil { - return fmt7.Errorf("Okay this(%v) Not Equal that(%v)", this.Okay, that1.Okay) - } - if this.Proposal != nil && that1.Proposal != nil { - if *this.Proposal != *that1.Proposal { - return fmt7.Errorf("Proposal this(%v) Not Equal that(%v)", *this.Proposal, *that1.Proposal) - } - } else if this.Proposal != nil { - return fmt7.Errorf("this.Proposal == nil && that.Proposal != nil") - } else if that1.Proposal != nil { - return fmt7.Errorf("Proposal this(%v) Not Equal that(%v)", this.Proposal, that1.Proposal) - } - if this.Position != nil && that1.Position != nil { - if *this.Position != *that1.Position { - return fmt7.Errorf("Position this(%v) Not Equal that(%v)", *this.Position, *that1.Position) - } - } else if this.Position != nil { - return fmt7.Errorf("this.Position == nil && that.Position != nil") - } else if that1.Position != nil { - return fmt7.Errorf("Position this(%v) Not Equal that(%v)", this.Position, that1.Position) - } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *WriteResponse) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*WriteResponse) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Okay != nil && that1.Okay != nil { - if *this.Okay != *that1.Okay { - return false - } - } else if this.Okay != nil { - return false - } else if that1.Okay != nil { - return false - } - if this.Proposal != nil && that1.Proposal != nil { - if *this.Proposal != *that1.Proposal { - return false +func (m *PromiseRequest) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Proposal != nil { - return false - } else if that1.Proposal != nil { - return false - } - if this.Position != nil && that1.Position != nil { - if *this.Position != *that1.Position { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Proposal", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Proposal = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Position", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Position = &v + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Position != nil { - return false - } else if that1.Position != nil { - return false } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("proposal") } - return true + + return nil } -func (this *LearnedMessage) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func (m *PromiseResponse) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return fmt7.Errorf("that == nil && this != nil") - } - - that1, ok := that.(*LearnedMessage) - if !ok { - return fmt7.Errorf("that is not of type *LearnedMessage") - } - if that1 == nil { - if this == nil { - return nil + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Okay", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Okay = &b + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Proposal", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Proposal = &v + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Action == nil { + m.Action = &Action{} + } + if err := m.Action.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Position", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Position = &v + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt7.Errorf("that is type *LearnedMessage but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *LearnedMessagebut is not nil && this == nil") } - if !this.Action.Equal(that1.Action) { - return fmt7.Errorf("Action this(%v) Not Equal that(%v)", this.Action, that1.Action) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("okay") } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("proposal") } + return nil } -func (this *LearnedMessage) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *WriteRequest) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } - - that1, ok := that.(*LearnedMessage) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Proposal", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Proposal = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Position", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Position = &v + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Learned", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Learned = &b + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v Action_Type + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (Action_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + hasFields[0] |= uint64(0x00000004) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Nop", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Nop == nil { + m.Nop = &Action_Nop{} + } + if err := m.Nop.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Append", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Append == nil { + m.Append = &Action_Append{} + } + if err := m.Append.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Truncate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Truncate == nil { + m.Truncate = &Action_Truncate{} + } + if err := m.Truncate.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false - } else if this == nil { - return false } - if !this.Action.Equal(that1.Action) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("proposal") } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("position") } - return true -} -func (this *RecoverRequest) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000004) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") } - that1, ok := that.(*RecoverRequest) - if !ok { - return fmt7.Errorf("that is not of type *RecoverRequest") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *RecoverRequest but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *RecoverRequestbut is not nil && this == nil") - } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *RecoverRequest) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*RecoverRequest) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true +func (m *WriteResponse) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } else if this == nil { - return false - } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true -} -func (this *RecoverResponse) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Okay", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Okay = &b + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Proposal", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Proposal = &v + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Position", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Position = &v + hasFields[0] |= uint64(0x00000004) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt7.Errorf("that == nil && this != nil") } - - that1, ok := that.(*RecoverResponse) - if !ok { - return fmt7.Errorf("that is not of type *RecoverResponse") + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("okay") } - if that1 == nil { - if this == nil { - return nil - } - return fmt7.Errorf("that is type *RecoverResponse but is nil && this != nil") - } else if this == nil { - return fmt7.Errorf("that is type *RecoverResponsebut is not nil && this == nil") + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("proposal") } - if this.Status != nil && that1.Status != nil { - if *this.Status != *that1.Status { - return fmt7.Errorf("Status this(%v) Not Equal that(%v)", *this.Status, *that1.Status) - } - } else if this.Status != nil { - return fmt7.Errorf("this.Status == nil && that.Status != nil") - } else if that1.Status != nil { - return fmt7.Errorf("Status this(%v) Not Equal that(%v)", this.Status, that1.Status) + if hasFields[0]&uint64(0x00000004) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("position") } - if this.Begin != nil && that1.Begin != nil { - if *this.Begin != *that1.Begin { - return fmt7.Errorf("Begin this(%v) Not Equal that(%v)", *this.Begin, *that1.Begin) + + return nil +} +func (m *LearnedMessage) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Begin != nil { - return fmt7.Errorf("this.Begin == nil && that.Begin != nil") - } else if that1.Begin != nil { - return fmt7.Errorf("Begin this(%v) Not Equal that(%v)", this.Begin, that1.Begin) - } - if this.End != nil && that1.End != nil { - if *this.End != *that1.End { - return fmt7.Errorf("End this(%v) Not Equal that(%v)", *this.End, *that1.End) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLog + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Action == nil { + m.Action = &Action{} + } + if err := m.Action.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.End != nil { - return fmt7.Errorf("this.End == nil && that.End != nil") - } else if that1.End != nil { - return fmt7.Errorf("End this(%v) Not Equal that(%v)", this.End, that1.End) } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("action") } + return nil } -func (this *RecoverResponse) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *RecoverRequest) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + switch fieldNum { + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false } - that1, ok := that.(*RecoverResponse) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + return nil +} +func (m *RecoverResponse) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } else if this == nil { - return false - } - if this.Status != nil && that1.Status != nil { - if *this.Status != *that1.Status { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var v Metadata_Status + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (Metadata_Status(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Status = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Begin", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Begin = &v + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field End", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.End = &v + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipLog(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLog + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Status != nil { - return false - } else if that1.Status != nil { - return false } - if this.Begin != nil && that1.Begin != nil { - if *this.Begin != *that1.Begin { - return false - } - } else if this.Begin != nil { - return false - } else if that1.Begin != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("status") } - if this.End != nil && that1.End != nil { - if *this.End != *that1.End { - return false + + return nil +} +func skipLog(data []byte) (n int, err error) { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if data[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthLog + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipLog(data[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) } - } else if this.End != nil { - return false - } else if that1.End != nil { - return false - } - if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false } - return true + panic("unreachable") } + +var ( + ErrInvalidLengthLog = fmt.Errorf("proto: negative length found during unmarshaling") +) diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/logpb_test.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/logpb_test.go index 0511bd3d8e40..20e6005eaf72 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/logpb_test.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/logpb_test.go @@ -4,60 +4,60 @@ package mesosproto -import testing7 "testing" -import math_rand7 "math/rand" -import time7 "time" -import github_com_gogo_protobuf_proto4 "github.com/gogo/protobuf/proto" -import testing8 "testing" -import math_rand8 "math/rand" -import time8 "time" -import encoding_json1 "encoding/json" -import testing9 "testing" -import math_rand9 "math/rand" -import time9 "time" -import github_com_gogo_protobuf_proto5 "github.com/gogo/protobuf/proto" -import math_rand10 "math/rand" -import time10 "time" -import testing10 "testing" -import fmt2 "fmt" -import math_rand11 "math/rand" -import time11 "time" -import testing11 "testing" -import github_com_gogo_protobuf_proto6 "github.com/gogo/protobuf/proto" -import math_rand12 "math/rand" -import time12 "time" -import testing12 "testing" -import fmt3 "fmt" -import go_parser1 "go/parser" -import math_rand13 "math/rand" -import time13 "time" -import testing13 "testing" -import github_com_gogo_protobuf_proto7 "github.com/gogo/protobuf/proto" - -func TestPromiseProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +import testing "testing" +import math_rand "math/rand" +import time "time" +import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" +import github_com_gogo_protobuf_jsonpb "github.com/gogo/protobuf/jsonpb" +import fmt "fmt" +import go_parser "go/parser" +import proto "github.com/gogo/protobuf/proto" +import math "math" + +// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +func TestPromiseProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromise(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Promise{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestPromiseMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestPromiseMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromise(popr, false) size := p.Size() data := make([]byte, size) @@ -66,25 +66,25 @@ func TestPromiseMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Promise{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkPromiseProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkPromiseProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Promise, 10000) for i := 0; i < 10000; i++ { @@ -92,7 +92,7 @@ func BenchmarkPromiseProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -101,12 +101,12 @@ func BenchmarkPromiseProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkPromiseProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkPromiseProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedPromise(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedPromise(popr, false)) if err != nil { panic(err) } @@ -116,37 +116,50 @@ func BenchmarkPromiseProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestActionProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestActionProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestActionMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestActionMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction(popr, false) size := p.Size() data := make([]byte, size) @@ -155,25 +168,25 @@ func TestActionMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkActionProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkActionProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Action, 10000) for i := 0; i < 10000; i++ { @@ -181,7 +194,7 @@ func BenchmarkActionProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -190,12 +203,12 @@ func BenchmarkActionProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkActionProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkActionProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedAction(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedAction(popr, false)) if err != nil { panic(err) } @@ -205,37 +218,50 @@ func BenchmarkActionProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestAction_NopProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestAction_NopProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Nop(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action_Nop{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestAction_NopMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestAction_NopMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Nop(popr, false) size := p.Size() data := make([]byte, size) @@ -244,25 +270,25 @@ func TestAction_NopMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action_Nop{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkAction_NopProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkAction_NopProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Action_Nop, 10000) for i := 0; i < 10000; i++ { @@ -270,7 +296,7 @@ func BenchmarkAction_NopProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -279,12 +305,12 @@ func BenchmarkAction_NopProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkAction_NopProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkAction_NopProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedAction_Nop(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedAction_Nop(popr, false)) if err != nil { panic(err) } @@ -294,37 +320,50 @@ func BenchmarkAction_NopProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestAction_AppendProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestAction_AppendProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Append(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action_Append{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestAction_AppendMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestAction_AppendMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Append(popr, false) size := p.Size() data := make([]byte, size) @@ -333,25 +372,25 @@ func TestAction_AppendMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action_Append{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkAction_AppendProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkAction_AppendProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Action_Append, 10000) for i := 0; i < 10000; i++ { @@ -359,7 +398,7 @@ func BenchmarkAction_AppendProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -368,12 +407,12 @@ func BenchmarkAction_AppendProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkAction_AppendProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkAction_AppendProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedAction_Append(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedAction_Append(popr, false)) if err != nil { panic(err) } @@ -383,37 +422,50 @@ func BenchmarkAction_AppendProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestAction_TruncateProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestAction_TruncateProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Truncate(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action_Truncate{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestAction_TruncateMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestAction_TruncateMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Truncate(popr, false) size := p.Size() data := make([]byte, size) @@ -422,25 +474,25 @@ func TestAction_TruncateMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action_Truncate{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkAction_TruncateProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkAction_TruncateProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Action_Truncate, 10000) for i := 0; i < 10000; i++ { @@ -448,7 +500,7 @@ func BenchmarkAction_TruncateProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -457,12 +509,12 @@ func BenchmarkAction_TruncateProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkAction_TruncateProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkAction_TruncateProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedAction_Truncate(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedAction_Truncate(popr, false)) if err != nil { panic(err) } @@ -472,37 +524,50 @@ func BenchmarkAction_TruncateProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestMetadataProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestMetadataProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedMetadata(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Metadata{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestMetadataMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestMetadataMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedMetadata(popr, false) size := p.Size() data := make([]byte, size) @@ -511,25 +576,25 @@ func TestMetadataMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Metadata{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkMetadataProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkMetadataProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Metadata, 10000) for i := 0; i < 10000; i++ { @@ -537,7 +602,7 @@ func BenchmarkMetadataProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -546,12 +611,12 @@ func BenchmarkMetadataProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkMetadataProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkMetadataProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedMetadata(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedMetadata(popr, false)) if err != nil { panic(err) } @@ -561,37 +626,50 @@ func BenchmarkMetadataProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestRecordProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestRecordProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecord(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Record{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestRecordMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestRecordMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecord(popr, false) size := p.Size() data := make([]byte, size) @@ -600,25 +678,25 @@ func TestRecordMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Record{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkRecordProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkRecordProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Record, 10000) for i := 0; i < 10000; i++ { @@ -626,7 +704,7 @@ func BenchmarkRecordProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -635,12 +713,12 @@ func BenchmarkRecordProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkRecordProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkRecordProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedRecord(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedRecord(popr, false)) if err != nil { panic(err) } @@ -650,37 +728,50 @@ func BenchmarkRecordProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestPromiseRequestProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestPromiseRequestProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseRequest(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &PromiseRequest{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestPromiseRequestMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestPromiseRequestMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseRequest(popr, false) size := p.Size() data := make([]byte, size) @@ -689,25 +780,25 @@ func TestPromiseRequestMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &PromiseRequest{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkPromiseRequestProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkPromiseRequestProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*PromiseRequest, 10000) for i := 0; i < 10000; i++ { @@ -715,7 +806,7 @@ func BenchmarkPromiseRequestProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -724,12 +815,12 @@ func BenchmarkPromiseRequestProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkPromiseRequestProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkPromiseRequestProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedPromiseRequest(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedPromiseRequest(popr, false)) if err != nil { panic(err) } @@ -739,37 +830,50 @@ func BenchmarkPromiseRequestProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestPromiseResponseProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestPromiseResponseProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseResponse(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &PromiseResponse{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestPromiseResponseMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestPromiseResponseMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseResponse(popr, false) size := p.Size() data := make([]byte, size) @@ -778,25 +882,25 @@ func TestPromiseResponseMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &PromiseResponse{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkPromiseResponseProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkPromiseResponseProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*PromiseResponse, 10000) for i := 0; i < 10000; i++ { @@ -804,7 +908,7 @@ func BenchmarkPromiseResponseProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -813,12 +917,12 @@ func BenchmarkPromiseResponseProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkPromiseResponseProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkPromiseResponseProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedPromiseResponse(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedPromiseResponse(popr, false)) if err != nil { panic(err) } @@ -828,37 +932,50 @@ func BenchmarkPromiseResponseProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestWriteRequestProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestWriteRequestProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteRequest(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &WriteRequest{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestWriteRequestMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestWriteRequestMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteRequest(popr, false) size := p.Size() data := make([]byte, size) @@ -867,25 +984,25 @@ func TestWriteRequestMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &WriteRequest{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkWriteRequestProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkWriteRequestProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*WriteRequest, 10000) for i := 0; i < 10000; i++ { @@ -893,7 +1010,7 @@ func BenchmarkWriteRequestProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -902,12 +1019,12 @@ func BenchmarkWriteRequestProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkWriteRequestProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkWriteRequestProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedWriteRequest(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedWriteRequest(popr, false)) if err != nil { panic(err) } @@ -917,37 +1034,50 @@ func BenchmarkWriteRequestProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestWriteResponseProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestWriteResponseProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteResponse(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &WriteResponse{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestWriteResponseMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestWriteResponseMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteResponse(popr, false) size := p.Size() data := make([]byte, size) @@ -956,25 +1086,25 @@ func TestWriteResponseMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &WriteResponse{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkWriteResponseProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkWriteResponseProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*WriteResponse, 10000) for i := 0; i < 10000; i++ { @@ -982,7 +1112,7 @@ func BenchmarkWriteResponseProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -991,12 +1121,12 @@ func BenchmarkWriteResponseProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkWriteResponseProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkWriteResponseProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedWriteResponse(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedWriteResponse(popr, false)) if err != nil { panic(err) } @@ -1006,37 +1136,50 @@ func BenchmarkWriteResponseProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestLearnedMessageProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestLearnedMessageProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedLearnedMessage(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &LearnedMessage{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestLearnedMessageMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestLearnedMessageMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedLearnedMessage(popr, false) size := p.Size() data := make([]byte, size) @@ -1045,25 +1188,25 @@ func TestLearnedMessageMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &LearnedMessage{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkLearnedMessageProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkLearnedMessageProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*LearnedMessage, 10000) for i := 0; i < 10000; i++ { @@ -1071,7 +1214,7 @@ func BenchmarkLearnedMessageProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -1080,12 +1223,12 @@ func BenchmarkLearnedMessageProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkLearnedMessageProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkLearnedMessageProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedLearnedMessage(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedLearnedMessage(popr, false)) if err != nil { panic(err) } @@ -1095,37 +1238,50 @@ func BenchmarkLearnedMessageProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestRecoverRequestProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestRecoverRequestProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverRequest(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &RecoverRequest{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestRecoverRequestMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestRecoverRequestMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverRequest(popr, false) size := p.Size() data := make([]byte, size) @@ -1134,25 +1290,25 @@ func TestRecoverRequestMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &RecoverRequest{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkRecoverRequestProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkRecoverRequestProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*RecoverRequest, 10000) for i := 0; i < 10000; i++ { @@ -1160,7 +1316,7 @@ func BenchmarkRecoverRequestProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -1169,12 +1325,12 @@ func BenchmarkRecoverRequestProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkRecoverRequestProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkRecoverRequestProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedRecoverRequest(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedRecoverRequest(popr, false)) if err != nil { panic(err) } @@ -1184,37 +1340,50 @@ func BenchmarkRecoverRequestProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestRecoverResponseProto(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestRecoverResponseProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverResponse(popr, false) - data, err := github_com_gogo_protobuf_proto4.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &RecoverResponse{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestRecoverResponseMarshalTo(t *testing7.T) { - popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano())) +func TestRecoverResponseMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverResponse(popr, false) size := p.Size() data := make([]byte, size) @@ -1223,25 +1392,25 @@ func TestRecoverResponseMarshalTo(t *testing7.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &RecoverResponse{} - if err := github_com_gogo_protobuf_proto4.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkRecoverResponseProtoMarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkRecoverResponseProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*RecoverResponse, 10000) for i := 0; i < 10000; i++ { @@ -1249,7 +1418,7 @@ func BenchmarkRecoverResponseProtoMarshal(b *testing7.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -1258,12 +1427,12 @@ func BenchmarkRecoverResponseProtoMarshal(b *testing7.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkRecoverResponseProtoUnmarshal(b *testing7.B) { - popr := math_rand7.New(math_rand7.NewSource(616)) +func BenchmarkRecoverResponseProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto4.Marshal(NewPopulatedRecoverResponse(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedRecoverResponse(popr, false)) if err != nil { panic(err) } @@ -1273,876 +1442,1199 @@ func BenchmarkRecoverResponseProtoUnmarshal(b *testing7.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto4.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestPromiseJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestPromiseJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromise(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Promise{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestActionJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestActionJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestAction_NopJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestAction_NopJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Nop(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action_Nop{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestAction_AppendJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestAction_AppendJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Append(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action_Append{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestAction_TruncateJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestAction_TruncateJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Truncate(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Action_Truncate{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestMetadataJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestMetadataJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedMetadata(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Metadata{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestRecordJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestRecordJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecord(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Record{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestPromiseRequestJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestPromiseRequestJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseRequest(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &PromiseRequest{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestPromiseResponseJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestPromiseResponseJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseResponse(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &PromiseResponse{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestWriteRequestJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestWriteRequestJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteRequest(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &WriteRequest{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestWriteResponseJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestWriteResponseJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteResponse(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &WriteResponse{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestLearnedMessageJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestLearnedMessageJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedLearnedMessage(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &LearnedMessage{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestRecoverRequestJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestRecoverRequestJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverRequest(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &RecoverRequest{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestRecoverResponseJSON(t *testing8.T) { - popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano())) +func TestRecoverResponseJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverResponse(popr, true) - jsondata, err := encoding_json1.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &RecoverResponse{} - err = encoding_json1.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestPromiseProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestPromiseProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromise(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Promise{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestPromiseProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestPromiseProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromise(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Promise{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestActionProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestActionProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Action{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestActionProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestActionProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Action{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestAction_NopProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestAction_NopProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Nop(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Action_Nop{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestAction_NopProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestAction_NopProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Nop(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Action_Nop{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestAction_AppendProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestAction_AppendProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Append(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Action_Append{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestAction_AppendProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestAction_AppendProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Append(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Action_Append{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestAction_TruncateProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestAction_TruncateProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Truncate(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Action_Truncate{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestAction_TruncateProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestAction_TruncateProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Truncate(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Action_Truncate{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestMetadataProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestMetadataProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedMetadata(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Metadata{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestMetadataProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestMetadataProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedMetadata(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Metadata{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestRecordProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestRecordProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecord(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Record{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestRecordProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestRecordProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecord(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Record{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestPromiseRequestProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestPromiseRequestProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseRequest(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &PromiseRequest{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestPromiseRequestProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestPromiseRequestProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseRequest(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &PromiseRequest{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestPromiseResponseProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestPromiseResponseProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseResponse(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &PromiseResponse{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestPromiseResponseProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestPromiseResponseProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseResponse(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &PromiseResponse{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestWriteRequestProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestWriteRequestProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteRequest(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &WriteRequest{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestWriteRequestProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestWriteRequestProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteRequest(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &WriteRequest{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestWriteResponseProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestWriteResponseProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteResponse(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &WriteResponse{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestWriteResponseProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestWriteResponseProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteResponse(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &WriteResponse{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestLearnedMessageProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestLearnedMessageProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedLearnedMessage(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &LearnedMessage{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestLearnedMessageProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestLearnedMessageProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedLearnedMessage(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &LearnedMessage{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestRecoverRequestProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestRecoverRequestProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverRequest(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &RecoverRequest{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestRecoverRequestProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestRecoverRequestProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverRequest(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &RecoverRequest{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestRecoverResponseProtoText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestRecoverResponseProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverResponse(popr, true) - data := github_com_gogo_protobuf_proto5.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &RecoverResponse{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestRecoverResponseProtoCompactText(t *testing9.T) { - popr := math_rand9.New(math_rand9.NewSource(time9.Now().UnixNano())) +func TestRecoverResponseProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverResponse(popr, true) - data := github_com_gogo_protobuf_proto5.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &RecoverResponse{} - if err := github_com_gogo_protobuf_proto5.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestPromiseStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestPromiseVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPromise(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Promise{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestActionStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestActionVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedAction(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Action{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestAction_NopStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestAction_NopVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedAction_Nop(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Action_Nop{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestAction_AppendStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestAction_AppendVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedAction_Append(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Action_Append{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestAction_TruncateStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestAction_TruncateVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedAction_Truncate(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Action_Truncate{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestMetadataStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestMetadataVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedMetadata(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Metadata{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestRecordStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestRecordVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedRecord(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Record{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestPromiseRequestStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestPromiseRequestVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPromiseRequest(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &PromiseRequest{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestPromiseResponseStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestPromiseResponseVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPromiseResponse(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &PromiseResponse{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestWriteRequestStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestWriteRequestVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedWriteRequest(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &WriteRequest{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestWriteResponseStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestWriteResponseVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedWriteResponse(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) } -} -func TestLearnedMessageStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) + msg := &WriteResponse{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestLearnedMessageVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedLearnedMessage(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &LearnedMessage{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestRecoverRequestVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedRecoverRequest(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &RecoverRequest{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestRecoverResponseVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedRecoverResponse(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &RecoverResponse{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestPromiseGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPromise(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) } } -func TestRecoverRequestStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestActionGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedAction(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestAction_NopGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedAction_Nop(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestAction_AppendGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedAction_Append(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestAction_TruncateGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedAction_Truncate(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestMetadataGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedMetadata(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestRecordGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedRecord(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestPromiseRequestGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPromiseRequest(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestPromiseResponseGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPromiseResponse(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestWriteRequestGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedWriteRequest(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestWriteResponseGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedWriteResponse(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestLearnedMessageGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedLearnedMessage(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestRecoverRequestGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedRecoverRequest(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) } } -func TestRecoverResponseStringer(t *testing10.T) { - popr := math_rand10.New(math_rand10.NewSource(time10.Now().UnixNano())) +func TestRecoverResponseGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedRecoverResponse(popr, false) - s1 := p.String() - s2 := fmt2.Sprintf("%v", p) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) } } -func TestPromiseSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestPromiseSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromise(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkPromiseSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkPromiseSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Promise, 1000) for i := 0; i < 1000; i++ { @@ -2155,29 +2647,30 @@ func BenchmarkPromiseSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestActionSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestActionSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkActionSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkActionSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Action, 1000) for i := 0; i < 1000; i++ { @@ -2190,29 +2683,30 @@ func BenchmarkActionSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestAction_NopSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestAction_NopSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Nop(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkAction_NopSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkAction_NopSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Action_Nop, 1000) for i := 0; i < 1000; i++ { @@ -2225,29 +2719,30 @@ func BenchmarkAction_NopSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestAction_AppendSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestAction_AppendSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Append(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkAction_AppendSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkAction_AppendSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Action_Append, 1000) for i := 0; i < 1000; i++ { @@ -2260,29 +2755,30 @@ func BenchmarkAction_AppendSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestAction_TruncateSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestAction_TruncateSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAction_Truncate(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkAction_TruncateSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkAction_TruncateSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Action_Truncate, 1000) for i := 0; i < 1000; i++ { @@ -2295,29 +2791,30 @@ func BenchmarkAction_TruncateSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestMetadataSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestMetadataSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedMetadata(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkMetadataSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkMetadataSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Metadata, 1000) for i := 0; i < 1000; i++ { @@ -2330,29 +2827,30 @@ func BenchmarkMetadataSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestRecordSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestRecordSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecord(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkRecordSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkRecordSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Record, 1000) for i := 0; i < 1000; i++ { @@ -2365,29 +2863,30 @@ func BenchmarkRecordSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestPromiseRequestSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestPromiseRequestSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseRequest(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkPromiseRequestSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkPromiseRequestSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*PromiseRequest, 1000) for i := 0; i < 1000; i++ { @@ -2400,29 +2899,30 @@ func BenchmarkPromiseRequestSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestPromiseResponseSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestPromiseResponseSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedPromiseResponse(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkPromiseResponseSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkPromiseResponseSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*PromiseResponse, 1000) for i := 0; i < 1000; i++ { @@ -2435,29 +2935,30 @@ func BenchmarkPromiseResponseSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestWriteRequestSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestWriteRequestSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteRequest(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkWriteRequestSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkWriteRequestSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*WriteRequest, 1000) for i := 0; i < 1000; i++ { @@ -2470,29 +2971,30 @@ func BenchmarkWriteRequestSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestWriteResponseSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestWriteResponseSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedWriteResponse(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkWriteResponseSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkWriteResponseSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*WriteResponse, 1000) for i := 0; i < 1000; i++ { @@ -2505,29 +3007,30 @@ func BenchmarkWriteResponseSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestLearnedMessageSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestLearnedMessageSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedLearnedMessage(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkLearnedMessageSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkLearnedMessageSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*LearnedMessage, 1000) for i := 0; i < 1000; i++ { @@ -2540,29 +3043,30 @@ func BenchmarkLearnedMessageSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestRecoverRequestSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestRecoverRequestSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverRequest(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkRecoverRequestSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkRecoverRequestSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*RecoverRequest, 1000) for i := 0; i < 1000; i++ { @@ -2575,29 +3079,30 @@ func BenchmarkRecoverRequestSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestRecoverResponseSize(t *testing11.T) { - popr := math_rand11.New(math_rand11.NewSource(time11.Now().UnixNano())) +func TestRecoverResponseSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedRecoverResponse(popr, true) - size2 := github_com_gogo_protobuf_proto6.Size(p) - data, err := github_com_gogo_protobuf_proto6.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto6.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkRecoverResponseSize(b *testing11.B) { - popr := math_rand11.New(math_rand11.NewSource(616)) +func BenchmarkRecoverResponseSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*RecoverResponse, 1000) for i := 0; i < 1000; i++ { @@ -2610,396 +3115,130 @@ func BenchmarkRecoverResponseSize(b *testing11.B) { b.SetBytes(int64(total / b.N)) } -func TestPromiseGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestPromiseStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPromise(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestActionGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestActionStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedAction(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestAction_NopGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestAction_NopStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedAction_Nop(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestAction_AppendGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestAction_AppendStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedAction_Append(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestAction_TruncateGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestAction_TruncateStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedAction_Truncate(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestMetadataGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestMetadataStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedMetadata(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestRecordGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestRecordStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedRecord(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestPromiseRequestGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestPromiseRequestStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPromiseRequest(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestPromiseResponseGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestPromiseResponseStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPromiseResponse(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestWriteRequestGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestWriteRequestStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedWriteRequest(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestWriteResponseGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestWriteResponseStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedWriteResponse(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestLearnedMessageGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestLearnedMessageStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedLearnedMessage(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestRecoverRequestGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestRecoverRequestStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedRecoverRequest(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestRecoverResponseGoString(t *testing12.T) { - popr := math_rand12.New(math_rand12.NewSource(time12.Now().UnixNano())) +func TestRecoverResponseStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedRecoverResponse(popr, false) - s1 := p.GoString() - s2 := fmt3.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser1.ParseExpr(s1) - if err != nil { - panic(err) - } -} -func TestPromiseVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedPromise(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &Promise{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestActionVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedAction(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &Action{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestAction_NopVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedAction_Nop(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &Action_Nop{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestAction_AppendVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedAction_Append(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &Action_Append{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestAction_TruncateVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedAction_Truncate(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &Action_Truncate{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestMetadataVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedMetadata(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &Metadata{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestRecordVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedRecord(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &Record{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestPromiseRequestVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedPromiseRequest(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &PromiseRequest{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestPromiseResponseVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedPromiseResponse(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &PromiseResponse{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestWriteRequestVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedWriteRequest(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &WriteRequest{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestWriteResponseVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedWriteResponse(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &WriteResponse{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestLearnedMessageVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedLearnedMessage(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &LearnedMessage{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestRecoverRequestVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedRecoverRequest(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &RecoverRequest{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestRecoverResponseVerboseEqual(t *testing13.T) { - popr := math_rand13.New(math_rand13.NewSource(time13.Now().UnixNano())) - p := NewPopulatedRecoverResponse(popr, false) - data, err := github_com_gogo_protobuf_proto7.Marshal(p) - if err != nil { - panic(err) - } - msg := &RecoverResponse{} - if err := github_com_gogo_protobuf_proto7.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + t.Fatalf("String want %v got %v", s1, s2) } } diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesos.pb.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesos.pb.go index a39d1cc6c8c0..007d24d3fdb4 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesos.pb.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesos.pb.go @@ -5,33 +5,24 @@ package mesosproto import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" import math "math" -// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb" +// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto" -import io "io" -import math1 "math" -import fmt "fmt" -import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" +import bytes "bytes" -import fmt1 "fmt" import strings "strings" -import reflect "reflect" - -import math2 "math" - -import fmt2 "fmt" -import strings1 "strings" -import github_com_gogo_protobuf_proto1 "github.com/gogo/protobuf/proto" +import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" import sort "sort" import strconv "strconv" -import reflect1 "reflect" +import reflect "reflect" -import fmt3 "fmt" -import bytes "bytes" +import io "io" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf // * @@ -92,9 +83,7 @@ const ( TaskState_TASK_FAILED TaskState = 3 TaskState_TASK_KILLED TaskState = 4 TaskState_TASK_LOST TaskState = 5 - // TASK_ERROR is currently unused but will be introduced in 0.22.0. - // TODO(dhamon): Start using TASK_ERROR. - TaskState_TASK_ERROR TaskState = 7 + TaskState_TASK_ERROR TaskState = 7 ) var TaskState_name = map[int32]string{ @@ -135,6 +124,39 @@ func (x *TaskState) UnmarshalJSON(data []byte) error { return nil } +type FrameworkInfo_Capability_Type int32 + +const ( + // Receive offers with revocable resources. See 'Resource' + // message for details. + // TODO(vinod): This is currently a no-op. + FrameworkInfo_Capability_REVOCABLE_RESOURCES FrameworkInfo_Capability_Type = 1 +) + +var FrameworkInfo_Capability_Type_name = map[int32]string{ + 1: "REVOCABLE_RESOURCES", +} +var FrameworkInfo_Capability_Type_value = map[string]int32{ + "REVOCABLE_RESOURCES": 1, +} + +func (x FrameworkInfo_Capability_Type) Enum() *FrameworkInfo_Capability_Type { + p := new(FrameworkInfo_Capability_Type) + *p = x + return p +} +func (x FrameworkInfo_Capability_Type) String() string { + return proto.EnumName(FrameworkInfo_Capability_Type_name, int32(x)) +} +func (x *FrameworkInfo_Capability_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FrameworkInfo_Capability_Type_value, data, "FrameworkInfo_Capability_Type") + if err != nil { + return err + } + *x = FrameworkInfo_Capability_Type(value) + return nil +} + type Value_Type int32 const ( @@ -174,7 +196,49 @@ func (x *Value_Type) UnmarshalJSON(data []byte) error { return nil } -// * Describes the source of the task status update. +type Offer_Operation_Type int32 + +const ( + Offer_Operation_LAUNCH Offer_Operation_Type = 1 + Offer_Operation_RESERVE Offer_Operation_Type = 2 + Offer_Operation_UNRESERVE Offer_Operation_Type = 3 + Offer_Operation_CREATE Offer_Operation_Type = 4 + Offer_Operation_DESTROY Offer_Operation_Type = 5 +) + +var Offer_Operation_Type_name = map[int32]string{ + 1: "LAUNCH", + 2: "RESERVE", + 3: "UNRESERVE", + 4: "CREATE", + 5: "DESTROY", +} +var Offer_Operation_Type_value = map[string]int32{ + "LAUNCH": 1, + "RESERVE": 2, + "UNRESERVE": 3, + "CREATE": 4, + "DESTROY": 5, +} + +func (x Offer_Operation_Type) Enum() *Offer_Operation_Type { + p := new(Offer_Operation_Type) + *p = x + return p +} +func (x Offer_Operation_Type) String() string { + return proto.EnumName(Offer_Operation_Type_name, int32(x)) +} +func (x *Offer_Operation_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Offer_Operation_Type_value, data, "Offer_Operation_Type") + if err != nil { + return err + } + *x = Offer_Operation_Type(value) + return nil +} + +// Describes the source of the task status update. type TaskStatus_Source int32 const ( @@ -211,11 +275,15 @@ func (x *TaskStatus_Source) UnmarshalJSON(data []byte) error { return nil } -// * Detailed reason for the task status update. +// Detailed reason for the task status update. +// +// TODO(bmahler): Differentiate between slave removal reasons +// (e.g. unhealthy vs. unregistered for maintenance). type TaskStatus_Reason int32 const ( TaskStatus_REASON_COMMAND_EXECUTOR_FAILED TaskStatus_Reason = 0 + TaskStatus_REASON_EXECUTOR_PREEMPTED TaskStatus_Reason = 17 TaskStatus_REASON_EXECUTOR_TERMINATED TaskStatus_Reason = 1 TaskStatus_REASON_EXECUTOR_UNREGISTERED TaskStatus_Reason = 2 TaskStatus_REASON_FRAMEWORK_REMOVED TaskStatus_Reason = 3 @@ -225,6 +293,7 @@ const ( TaskStatus_REASON_MASTER_DISCONNECTED TaskStatus_Reason = 7 TaskStatus_REASON_MEMORY_LIMIT TaskStatus_Reason = 8 TaskStatus_REASON_RECONCILIATION TaskStatus_Reason = 9 + TaskStatus_REASON_RESOURCES_UNKNOWN TaskStatus_Reason = 18 TaskStatus_REASON_SLAVE_DISCONNECTED TaskStatus_Reason = 10 TaskStatus_REASON_SLAVE_REMOVED TaskStatus_Reason = 11 TaskStatus_REASON_SLAVE_RESTARTED TaskStatus_Reason = 12 @@ -236,6 +305,7 @@ const ( var TaskStatus_Reason_name = map[int32]string{ 0: "REASON_COMMAND_EXECUTOR_FAILED", + 17: "REASON_EXECUTOR_PREEMPTED", 1: "REASON_EXECUTOR_TERMINATED", 2: "REASON_EXECUTOR_UNREGISTERED", 3: "REASON_FRAMEWORK_REMOVED", @@ -245,6 +315,7 @@ var TaskStatus_Reason_name = map[int32]string{ 7: "REASON_MASTER_DISCONNECTED", 8: "REASON_MEMORY_LIMIT", 9: "REASON_RECONCILIATION", + 18: "REASON_RESOURCES_UNKNOWN", 10: "REASON_SLAVE_DISCONNECTED", 11: "REASON_SLAVE_REMOVED", 12: "REASON_SLAVE_RESTARTED", @@ -255,6 +326,7 @@ var TaskStatus_Reason_name = map[int32]string{ } var TaskStatus_Reason_value = map[string]int32{ "REASON_COMMAND_EXECUTOR_FAILED": 0, + "REASON_EXECUTOR_PREEMPTED": 17, "REASON_EXECUTOR_TERMINATED": 1, "REASON_EXECUTOR_UNREGISTERED": 2, "REASON_FRAMEWORK_REMOVED": 3, @@ -264,6 +336,7 @@ var TaskStatus_Reason_value = map[string]int32{ "REASON_MASTER_DISCONNECTED": 7, "REASON_MEMORY_LIMIT": 8, "REASON_RECONCILIATION": 9, + "REASON_RESOURCES_UNKNOWN": 18, "REASON_SLAVE_DISCONNECTED": 10, "REASON_SLAVE_REMOVED": 11, "REASON_SLAVE_RESTARTED": 12, @@ -430,6 +503,42 @@ func (x *ContainerInfo_DockerInfo_Network) UnmarshalJSON(data []byte) error { return nil } +type DiscoveryInfo_Visibility int32 + +const ( + DiscoveryInfo_FRAMEWORK DiscoveryInfo_Visibility = 0 + DiscoveryInfo_CLUSTER DiscoveryInfo_Visibility = 1 + DiscoveryInfo_EXTERNAL DiscoveryInfo_Visibility = 2 +) + +var DiscoveryInfo_Visibility_name = map[int32]string{ + 0: "FRAMEWORK", + 1: "CLUSTER", + 2: "EXTERNAL", +} +var DiscoveryInfo_Visibility_value = map[string]int32{ + "FRAMEWORK": 0, + "CLUSTER": 1, + "EXTERNAL": 2, +} + +func (x DiscoveryInfo_Visibility) Enum() *DiscoveryInfo_Visibility { + p := new(DiscoveryInfo_Visibility) + *p = x + return p +} +func (x DiscoveryInfo_Visibility) String() string { + return proto.EnumName(DiscoveryInfo_Visibility_name, int32(x)) +} +func (x *DiscoveryInfo_Visibility) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(DiscoveryInfo_Visibility_value, data, "DiscoveryInfo_Visibility") + if err != nil { + return err + } + *x = DiscoveryInfo_Visibility(value) + return nil +} + // * // A unique ID assigned to a framework. A framework can reuse this ID // in order to do failover (see MesosSchedulerDriver). @@ -544,41 +653,51 @@ func (m *ContainerID) GetValue() string { } // * -// Describes a framework. The user field is used to determine the -// Unix user that an executor/task should be launched as. If the user -// field is set to an empty string Mesos will automagically set it -// to the current user. Note that the ID is only available after a -// framework has registered, however, it is included here in order to -// facilitate scheduler failover (i.e., if it is set then the -// MesosSchedulerDriver expects the scheduler is performing failover). -// The amount of time that the master will wait for the scheduler to -// failover before removing the framework is specified by -// failover_timeout. If checkpoint is set, framework pid, executor -// pids and status updates are checkpointed to disk by the slaves. -// Checkpointing allows a restarted slave to reconnect with old -// executors and recover status updates, at the cost of disk I/O. -// The role field is used to group frameworks for allocation -// decisions, depending on the allocation policy being used. -// If the hostname field is set to an empty string Mesos will -// automagically set it to the current hostname. -// The principal field should match the credential the framework uses -// in authentication. This field is used for framework API rate -// exporting and limiting and should be set even if authentication is -// not enabled if these features are desired. -// The webui_url field allows a framework to advertise its web UI, so -// that the Mesos web UI can link to it. It is expected to be a full -// URL, for example http://my-scheduler.example.com:8080/. +// Describes a framework. type FrameworkInfo struct { - User *string `protobuf:"bytes,1,req,name=user" json:"user,omitempty"` - Name *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"` - Id *FrameworkID `protobuf:"bytes,3,opt,name=id" json:"id,omitempty"` - FailoverTimeout *float64 `protobuf:"fixed64,4,opt,name=failover_timeout,def=0" json:"failover_timeout,omitempty"` - Checkpoint *bool `protobuf:"varint,5,opt,name=checkpoint,def=0" json:"checkpoint,omitempty"` - Role *string `protobuf:"bytes,6,opt,name=role,def=*" json:"role,omitempty"` - Hostname *string `protobuf:"bytes,7,opt,name=hostname" json:"hostname,omitempty"` - Principal *string `protobuf:"bytes,8,opt,name=principal" json:"principal,omitempty"` - WebuiUrl *string `protobuf:"bytes,9,opt,name=webui_url" json:"webui_url,omitempty"` - XXX_unrecognized []byte `json:"-"` + // Used to determine the Unix user that an executor or task should + // be launched as. If the user field is set to an empty string Mesos + // will automagically set it to the current user. + User *string `protobuf:"bytes,1,req,name=user" json:"user,omitempty"` + // Name of the framework that shows up in the Mesos Web UI. + Name *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"` + // Note that 'id' is only available after a framework has + // registered, however, it is included here in order to facilitate + // scheduler failover (i.e., if it is set then the + // MesosSchedulerDriver expects the scheduler is performing + // failover). + Id *FrameworkID `protobuf:"bytes,3,opt,name=id" json:"id,omitempty"` + // The amount of time that the master will wait for the scheduler to + // failover before it tears down the framework by killing all its + // tasks/executors. This should be non-zero if a framework expects + // to reconnect after a failover and not lose its tasks/executors. + FailoverTimeout *float64 `protobuf:"fixed64,4,opt,name=failover_timeout,def=0" json:"failover_timeout,omitempty"` + // If set, framework pid, executor pids and status updates are + // checkpointed to disk by the slaves. Checkpointing allows a + // restarted slave to reconnect with old executors and recover + // status updates, at the cost of disk I/O. + Checkpoint *bool `protobuf:"varint,5,opt,name=checkpoint,def=0" json:"checkpoint,omitempty"` + // Used to group frameworks for allocation decisions, depending on + // the allocation policy being used. + Role *string `protobuf:"bytes,6,opt,name=role,def=*" json:"role,omitempty"` + // Used to indicate the current host from which the scheduler is + // registered in the Mesos Web UI. If set to an empty string Mesos + // will automagically set it to the current hostname. + Hostname *string `protobuf:"bytes,7,opt,name=hostname" json:"hostname,omitempty"` + // This field should match the credential's principal the framework + // uses for authentication. This field is used for framework API + // rate limiting and dynamic reservations. It should be set even + // if authentication is not enabled if these features are desired. + Principal *string `protobuf:"bytes,8,opt,name=principal" json:"principal,omitempty"` + // This field allows a framework to advertise its web UI, so that + // the Mesos web UI can link to it. It is expected to be a full URL, + // for example http://my-scheduler.example.com:8080/. + WebuiUrl *string `protobuf:"bytes,9,opt,name=webui_url" json:"webui_url,omitempty"` + // This field allows a framework to advertise its set of + // capabilities (e.g., ability to receive offers for revocable + // resources). + Capabilities []*FrameworkInfo_Capability `protobuf:"bytes,10,rep,name=capabilities" json:"capabilities,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *FrameworkInfo) Reset() { *m = FrameworkInfo{} } @@ -651,12 +770,35 @@ func (m *FrameworkInfo) GetWebuiUrl() string { return "" } +func (m *FrameworkInfo) GetCapabilities() []*FrameworkInfo_Capability { + if m != nil { + return m.Capabilities + } + return nil +} + +type FrameworkInfo_Capability struct { + Type *FrameworkInfo_Capability_Type `protobuf:"varint,1,req,name=type,enum=mesosproto.FrameworkInfo_Capability_Type" json:"type,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FrameworkInfo_Capability) Reset() { *m = FrameworkInfo_Capability{} } +func (*FrameworkInfo_Capability) ProtoMessage() {} + +func (m *FrameworkInfo_Capability) GetType() FrameworkInfo_Capability_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return FrameworkInfo_Capability_REVOCABLE_RESOURCES +} + // * // Describes a health check for a task or executor (or any arbitrary // process/command). A "strategy" is picked by specifying one of the -// optional fields, currently only 'http' and 'command' are -// supported. Specifying more than one strategy is an error. +// optional fields; currently only 'command' is supported. +// Specifying more than one strategy is an error. type HealthCheck struct { + // HTTP health check - not yet recommended for use, see MESOS-2533. Http *HealthCheck_HTTP `protobuf:"bytes,1,opt,name=http" json:"http,omitempty"` // Amount of time to wait until starting the health checks. DelaySeconds *float64 `protobuf:"fixed64,2,opt,name=delay_seconds,def=15" json:"delay_seconds,omitempty"` @@ -731,7 +873,8 @@ func (m *HealthCheck) GetCommand() *CommandInfo { return nil } -// Describes an HTTP health check. +// Describes an HTTP health check. This is not fully implemented and not +// recommended for use - see MESOS-2533. type HealthCheck_HTTP struct { // Port to send the HTTP request. Port *uint32 `protobuf:"varint,1,req,name=port" json:"port,omitempty"` @@ -862,10 +1005,25 @@ func (m *CommandInfo) GetUser() string { } type CommandInfo_URI struct { - Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` - Executable *bool `protobuf:"varint,2,opt,name=executable" json:"executable,omitempty"` - Extract *bool `protobuf:"varint,3,opt,name=extract,def=1" json:"extract,omitempty"` - XXX_unrecognized []byte `json:"-"` + Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + Executable *bool `protobuf:"varint,2,opt,name=executable" json:"executable,omitempty"` + // In case the fetched file is recognized as an archive, extract + // its contents into the sandbox. Note that a cached archive is + // not copied from the cache to the sandbox in case extraction + // originates from an archive in the cache. + Extract *bool `protobuf:"varint,3,opt,name=extract,def=1" json:"extract,omitempty"` + // If this field is "true", the fetcher cache will be used. If not, + // fetching bypasses the cache and downloads directly into the + // sandbox directory, no matter whether a suitable cache file is + // available or not. The former directs the fetcher to download to + // the file cache, then copy from there to the sandbox. Subsequent + // fetch attempts with the same URI will omit downloading and copy + // from the cache as long as the file is resident there. Cache files + // may get evicted at any time, which then leads to renewed + // downloading. See also "docs/fetcher.md" and + // "docs/fetcher-cache-internals.md". + Cache *bool `protobuf:"varint,4,opt,name=cache" json:"cache,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *CommandInfo_URI) Reset() { *m = CommandInfo_URI{} } @@ -894,6 +1052,13 @@ func (m *CommandInfo_URI) GetExtract() bool { return Default_CommandInfo_URI_Extract } +func (m *CommandInfo_URI) GetCache() bool { + if m != nil && m.Cache != nil { + return *m.Cache + } + return false +} + // Describes a container. // Not all containerizers currently implement ContainerInfo, so it // is possible that a launched task will fail due to supplying this @@ -947,9 +1112,14 @@ type ExecutorInfo struct { // NOTE: Source is exposed alongside the resource usage of the // executor via JSON on the slave. This allows users to import // usage information into a time series database for monitoring. - Source *string `protobuf:"bytes,10,opt,name=source" json:"source,omitempty"` - Data []byte `protobuf:"bytes,4,opt,name=data" json:"data,omitempty"` - XXX_unrecognized []byte `json:"-"` + Source *string `protobuf:"bytes,10,opt,name=source" json:"source,omitempty"` + Data []byte `protobuf:"bytes,4,opt,name=data" json:"data,omitempty"` + // Service discovery information for the executor. It is not + // interpreted or acted upon by Mesos. It is up to a service + // discovery system to use this information as needed and to handle + // executors without service discovery information. + Discovery *DiscoveryInfo `protobuf:"bytes,12,opt,name=discovery" json:"discovery,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *ExecutorInfo) Reset() { *m = ExecutorInfo{} } @@ -1011,6 +1181,13 @@ func (m *ExecutorInfo) GetData() []byte { return nil } +func (m *ExecutorInfo) GetDiscovery() *DiscoveryInfo { + if m != nil { + return m.Discovery + } + return nil +} + // * // Describes a master. This will probably have more fields in the // future which might be used, for example, to link a framework webui @@ -1021,6 +1198,7 @@ type MasterInfo struct { Port *uint32 `protobuf:"varint,3,req,name=port,def=5050" json:"port,omitempty"` Pid *string `protobuf:"bytes,4,opt,name=pid" json:"pid,omitempty"` Hostname *string `protobuf:"bytes,5,opt,name=hostname" json:"hostname,omitempty"` + Version *string `protobuf:"bytes,6,opt,name=version" json:"version,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -1064,6 +1242,13 @@ func (m *MasterInfo) GetHostname() string { return "" } +func (m *MasterInfo) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + // * // Describes a slave. Note that the 'id' field is only available after // a slave is registered with the master, and is made available here @@ -1071,13 +1256,15 @@ func (m *MasterInfo) GetHostname() string { // checkpointing its own information and potentially frameworks' // information (if a framework has checkpointing enabled). type SlaveInfo struct { - Hostname *string `protobuf:"bytes,1,req,name=hostname" json:"hostname,omitempty"` - Port *int32 `protobuf:"varint,8,opt,name=port,def=5051" json:"port,omitempty"` - Resources []*Resource `protobuf:"bytes,3,rep,name=resources" json:"resources,omitempty"` - Attributes []*Attribute `protobuf:"bytes,5,rep,name=attributes" json:"attributes,omitempty"` - Id *SlaveID `protobuf:"bytes,6,opt,name=id" json:"id,omitempty"` - Checkpoint *bool `protobuf:"varint,7,opt,name=checkpoint,def=0" json:"checkpoint,omitempty"` - XXX_unrecognized []byte `json:"-"` + Hostname *string `protobuf:"bytes,1,req,name=hostname" json:"hostname,omitempty"` + Port *int32 `protobuf:"varint,8,opt,name=port,def=5051" json:"port,omitempty"` + Resources []*Resource `protobuf:"bytes,3,rep,name=resources" json:"resources,omitempty"` + Attributes []*Attribute `protobuf:"bytes,5,rep,name=attributes" json:"attributes,omitempty"` + Id *SlaveID `protobuf:"bytes,6,opt,name=id" json:"id,omitempty"` + // TODO(joerg84): Remove checkpoint field as with 0.22.0 + // slave checkpointing is enabled for all slaves (MESOS-2317). + Checkpoint *bool `protobuf:"varint,7,opt,name=checkpoint,def=0" json:"checkpoint,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *SlaveInfo) Reset() { *m = SlaveInfo{} } @@ -1329,13 +1516,25 @@ func (m *Attribute) GetText() *Value_Text { // TODO(benh): Add better support for "expected" resources (e.g., // cpus, memory, disk, network). type Resource struct { - Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` - Type *Value_Type `protobuf:"varint,2,req,name=type,enum=mesosproto.Value_Type" json:"type,omitempty"` - Scalar *Value_Scalar `protobuf:"bytes,3,opt,name=scalar" json:"scalar,omitempty"` - Ranges *Value_Ranges `protobuf:"bytes,4,opt,name=ranges" json:"ranges,omitempty"` - Set *Value_Set `protobuf:"bytes,5,opt,name=set" json:"set,omitempty"` - Role *string `protobuf:"bytes,6,opt,name=role,def=*" json:"role,omitempty"` - XXX_unrecognized []byte `json:"-"` + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + Type *Value_Type `protobuf:"varint,2,req,name=type,enum=mesosproto.Value_Type" json:"type,omitempty"` + Scalar *Value_Scalar `protobuf:"bytes,3,opt,name=scalar" json:"scalar,omitempty"` + Ranges *Value_Ranges `protobuf:"bytes,4,opt,name=ranges" json:"ranges,omitempty"` + Set *Value_Set `protobuf:"bytes,5,opt,name=set" json:"set,omitempty"` + Role *string `protobuf:"bytes,6,opt,name=role,def=*" json:"role,omitempty"` + // If this is set, this resource was dynamically reserved by an + // operator or a framework. Otherwise, this resource is either unreserved + // or statically reserved by an operator via the --resources flag. + Reservation *Resource_ReservationInfo `protobuf:"bytes,8,opt,name=reservation" json:"reservation,omitempty"` + Disk *Resource_DiskInfo `protobuf:"bytes,7,opt,name=disk" json:"disk,omitempty"` + // If this is set, the resources are revocable, i.e., any tasks or + // executors launched using these resources could get preempted or + // throttled at any time. This could be used by frameworks to run + // best effort tasks that do not need strict uptime or performance + // guarantees. Note that if this is set, 'disk' or 'reservation' + // cannot be set. + Revocable *Resource_RevocableInfo `protobuf:"bytes,9,opt,name=revocable" json:"revocable,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *Resource) Reset() { *m = Resource{} } @@ -1385,10 +1584,232 @@ func (m *Resource) GetRole() string { return Default_Resource_Role } +func (m *Resource) GetReservation() *Resource_ReservationInfo { + if m != nil { + return m.Reservation + } + return nil +} + +func (m *Resource) GetDisk() *Resource_DiskInfo { + if m != nil { + return m.Disk + } + return nil +} + +func (m *Resource) GetRevocable() *Resource_RevocableInfo { + if m != nil { + return m.Revocable + } + return nil +} + +type Resource_ReservationInfo struct { + // This field indicates the principal of the operator or framework + // that reserved this resource. It is used in conjunction with the + // "unreserve" ACL to determine whether the entity attempting to + // unreserve this resource is permitted to do so. + // NOTE: This field should match the FrameworkInfo.principal of + // the framework that reserved this resource. + Principal *string `protobuf:"bytes,1,req,name=principal" json:"principal,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_ReservationInfo) Reset() { *m = Resource_ReservationInfo{} } +func (*Resource_ReservationInfo) ProtoMessage() {} + +func (m *Resource_ReservationInfo) GetPrincipal() string { + if m != nil && m.Principal != nil { + return *m.Principal + } + return "" +} + +type Resource_DiskInfo struct { + Persistence *Resource_DiskInfo_Persistence `protobuf:"bytes,1,opt,name=persistence" json:"persistence,omitempty"` + // Describes how this disk resource will be mounted in the + // container. If not set, the disk resource will be used as the + // sandbox. Otherwise, it will be mounted according to the + // 'container_path' inside 'volume'. The 'host_path' inside + // 'volume' is ignored. + // NOTE: If 'volume' is set but 'persistence' is not set, the + // volume will be automatically garbage collected after + // task/executor terminates. Currently, if 'persistence' is set, + // 'volume' must be set. + Volume *Volume `protobuf:"bytes,2,opt,name=volume" json:"volume,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_DiskInfo) Reset() { *m = Resource_DiskInfo{} } +func (*Resource_DiskInfo) ProtoMessage() {} + +func (m *Resource_DiskInfo) GetPersistence() *Resource_DiskInfo_Persistence { + if m != nil { + return m.Persistence + } + return nil +} + +func (m *Resource_DiskInfo) GetVolume() *Volume { + if m != nil { + return m.Volume + } + return nil +} + +// Describes a persistent disk volume. +// A persistent disk volume will not be automatically garbage +// collected if the task/executor/slave terminates, but is +// re-offered to the framework(s) belonging to the 'role'. +// A framework can set the ID (if it is not set yet) to express +// the intention to create a new persistent disk volume from a +// regular disk resource. To reuse a previously created volume, a +// framework can launch a task/executor when it receives an offer +// with a persistent volume, i.e., ID is set. +// NOTE: Currently, we do not allow a persistent disk volume +// without a reservation (i.e., 'role' should not be '*'). +type Resource_DiskInfo_Persistence struct { + // A unique ID for the persistent disk volume. + // NOTE: The ID needs to be unique per role on each slave. + Id *string `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_DiskInfo_Persistence) Reset() { *m = Resource_DiskInfo_Persistence{} } +func (*Resource_DiskInfo_Persistence) ProtoMessage() {} + +func (m *Resource_DiskInfo_Persistence) GetId() string { + if m != nil && m.Id != nil { + return *m.Id + } + return "" +} + +type Resource_RevocableInfo struct { + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_RevocableInfo) Reset() { *m = Resource_RevocableInfo{} } +func (*Resource_RevocableInfo) ProtoMessage() {} + +// * +// When the network bandwidth caps are enabled and the container +// is over its limit, outbound packets may be either delayed or +// dropped completely either because it exceeds the maximum bandwidth +// allocation for a single container (the cap) or because the combined +// network traffic of multiple containers on the host exceeds the +// transmit capacity of the host (the share). We can report the +// following statistics for each of these conditions exported directly +// from the Linux Traffic Control Queueing Discipline. // +// id : name of the limiter, e.g. 'tx_bw_cap' +// backlog : number of packets currently delayed +// bytes : total bytes seen +// drops : number of packets dropped in total +// overlimits : number of packets which exceeded allocation +// packets : total packets seen +// qlen : number of packets currently queued +// rate_bps : throughput in bytes/sec +// rate_pps : throughput in packets/sec +// requeues : number of times a packet has been delayed due to +// locking or device contention issues +// +// More information on the operation of Linux Traffic Control can be +// found at http://www.lartc.org/lartc.html. +type TrafficControlStatistics struct { + Id *string `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` + Backlog *uint64 `protobuf:"varint,2,opt,name=backlog" json:"backlog,omitempty"` + Bytes *uint64 `protobuf:"varint,3,opt,name=bytes" json:"bytes,omitempty"` + Drops *uint64 `protobuf:"varint,4,opt,name=drops" json:"drops,omitempty"` + Overlimits *uint64 `protobuf:"varint,5,opt,name=overlimits" json:"overlimits,omitempty"` + Packets *uint64 `protobuf:"varint,6,opt,name=packets" json:"packets,omitempty"` + Qlen *uint64 `protobuf:"varint,7,opt,name=qlen" json:"qlen,omitempty"` + Ratebps *uint64 `protobuf:"varint,8,opt,name=ratebps" json:"ratebps,omitempty"` + Ratepps *uint64 `protobuf:"varint,9,opt,name=ratepps" json:"ratepps,omitempty"` + Requeues *uint64 `protobuf:"varint,10,opt,name=requeues" json:"requeues,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *TrafficControlStatistics) Reset() { *m = TrafficControlStatistics{} } +func (*TrafficControlStatistics) ProtoMessage() {} + +func (m *TrafficControlStatistics) GetId() string { + if m != nil && m.Id != nil { + return *m.Id + } + return "" +} + +func (m *TrafficControlStatistics) GetBacklog() uint64 { + if m != nil && m.Backlog != nil { + return *m.Backlog + } + return 0 +} + +func (m *TrafficControlStatistics) GetBytes() uint64 { + if m != nil && m.Bytes != nil { + return *m.Bytes + } + return 0 +} + +func (m *TrafficControlStatistics) GetDrops() uint64 { + if m != nil && m.Drops != nil { + return *m.Drops + } + return 0 +} + +func (m *TrafficControlStatistics) GetOverlimits() uint64 { + if m != nil && m.Overlimits != nil { + return *m.Overlimits + } + return 0 +} + +func (m *TrafficControlStatistics) GetPackets() uint64 { + if m != nil && m.Packets != nil { + return *m.Packets + } + return 0 +} + +func (m *TrafficControlStatistics) GetQlen() uint64 { + if m != nil && m.Qlen != nil { + return *m.Qlen + } + return 0 +} + +func (m *TrafficControlStatistics) GetRatebps() uint64 { + if m != nil && m.Ratebps != nil { + return *m.Ratebps + } + return 0 +} + +func (m *TrafficControlStatistics) GetRatepps() uint64 { + if m != nil && m.Ratepps != nil { + return *m.Ratepps + } + return 0 +} + +func (m *TrafficControlStatistics) GetRequeues() uint64 { + if m != nil && m.Requeues != nil { + return *m.Requeues + } + return 0 +} + +// * // A snapshot of resource usage statistics. type ResourceStatistics struct { Timestamp *float64 `protobuf:"fixed64,1,req,name=timestamp" json:"timestamp,omitempty"` + Processes *uint32 `protobuf:"varint,30,opt,name=processes" json:"processes,omitempty"` + Threads *uint32 `protobuf:"varint,31,opt,name=threads" json:"threads,omitempty"` // CPU Usage Information: // Total CPU time spent in user mode, and kernel mode. CpusUserTimeSecs *float64 `protobuf:"fixed64,2,opt,name=cpus_user_time_secs" json:"cpus_user_time_secs,omitempty"` @@ -1399,14 +1820,42 @@ type ResourceStatistics struct { CpusNrPeriods *uint32 `protobuf:"varint,7,opt,name=cpus_nr_periods" json:"cpus_nr_periods,omitempty"` CpusNrThrottled *uint32 `protobuf:"varint,8,opt,name=cpus_nr_throttled" json:"cpus_nr_throttled,omitempty"` CpusThrottledTimeSecs *float64 `protobuf:"fixed64,9,opt,name=cpus_throttled_time_secs" json:"cpus_throttled_time_secs,omitempty"` - // Memory Usage Information: - MemRssBytes *uint64 `protobuf:"varint,5,opt,name=mem_rss_bytes" json:"mem_rss_bytes,omitempty"` - // Amount of memory resources allocated. + // mem_total_bytes was added in 0.23.0 to represent the total memory + // of a process in RAM (as opposed to in Swap). This was previously + // reported as mem_rss_bytes, which was also changed in 0.23.0 to + // represent only the anonymous memory usage, to keep in sync with + // Linux kernel's (arguably erroneous) use of terminology. + MemTotalBytes *uint64 `protobuf:"varint,36,opt,name=mem_total_bytes" json:"mem_total_bytes,omitempty"` + // Total memory + swap usage. This is set if swap is enabled. + MemTotalMemswBytes *uint64 `protobuf:"varint,37,opt,name=mem_total_memsw_bytes" json:"mem_total_memsw_bytes,omitempty"` + // Hard memory limit for a container. MemLimitBytes *uint64 `protobuf:"varint,6,opt,name=mem_limit_bytes" json:"mem_limit_bytes,omitempty"` - // Broken out memory usage information (files, anonymous, and mmaped files) - MemFileBytes *uint64 `protobuf:"varint,10,opt,name=mem_file_bytes" json:"mem_file_bytes,omitempty"` - MemAnonBytes *uint64 `protobuf:"varint,11,opt,name=mem_anon_bytes" json:"mem_anon_bytes,omitempty"` + // Soft memory limit for a container. + MemSoftLimitBytes *uint64 `protobuf:"varint,38,opt,name=mem_soft_limit_bytes" json:"mem_soft_limit_bytes,omitempty"` + // TODO(chzhcn) mem_file_bytes and mem_anon_bytes are deprecated in + // 0.23.0 and will be removed in 0.24.0. + MemFileBytes *uint64 `protobuf:"varint,10,opt,name=mem_file_bytes" json:"mem_file_bytes,omitempty"` + MemAnonBytes *uint64 `protobuf:"varint,11,opt,name=mem_anon_bytes" json:"mem_anon_bytes,omitempty"` + // mem_cache_bytes is added in 0.23.0 to represent page cache usage. + MemCacheBytes *uint64 `protobuf:"varint,39,opt,name=mem_cache_bytes" json:"mem_cache_bytes,omitempty"` + // Since 0.23.0, mem_rss_bytes is changed to represent only + // anonymous memory usage. Note that neither its requiredness, type, + // name nor numeric tag has been changed. + MemRssBytes *uint64 `protobuf:"varint,5,opt,name=mem_rss_bytes" json:"mem_rss_bytes,omitempty"` MemMappedFileBytes *uint64 `protobuf:"varint,12,opt,name=mem_mapped_file_bytes" json:"mem_mapped_file_bytes,omitempty"` + // This is only set if swap is enabled. + MemSwapBytes *uint64 `protobuf:"varint,40,opt,name=mem_swap_bytes" json:"mem_swap_bytes,omitempty"` + // Number of occurrences of different levels of memory pressure + // events reported by memory cgroup. Pressure listening (re)starts + // with these values set to 0 when slave (re)starts. See + // https://www.kernel.org/doc/Documentation/cgroups/memory.txt for + // more details. + MemLowPressureCounter *uint64 `protobuf:"varint,32,opt,name=mem_low_pressure_counter" json:"mem_low_pressure_counter,omitempty"` + MemMediumPressureCounter *uint64 `protobuf:"varint,33,opt,name=mem_medium_pressure_counter" json:"mem_medium_pressure_counter,omitempty"` + MemCriticalPressureCounter *uint64 `protobuf:"varint,34,opt,name=mem_critical_pressure_counter" json:"mem_critical_pressure_counter,omitempty"` + // Disk Usage Information for executor working directory. + DiskLimitBytes *uint64 `protobuf:"varint,26,opt,name=disk_limit_bytes" json:"disk_limit_bytes,omitempty"` + DiskUsedBytes *uint64 `protobuf:"varint,27,opt,name=disk_used_bytes" json:"disk_used_bytes,omitempty"` // Perf statistics. Perf *PerfStatistics `protobuf:"bytes,13,opt,name=perf" json:"perf,omitempty"` // Network Usage Information: @@ -1420,11 +1869,17 @@ type ResourceStatistics struct { NetTxDropped *uint64 `protobuf:"varint,21,opt,name=net_tx_dropped" json:"net_tx_dropped,omitempty"` // The kernel keeps track of RTT (round-trip time) for its TCP // sockets. RTT is a way to tell the latency of a container. - NetTcpRttMicrosecsP50 *float64 `protobuf:"fixed64,22,opt,name=net_tcp_rtt_microsecs_p50" json:"net_tcp_rtt_microsecs_p50,omitempty"` - NetTcpRttMicrosecsP90 *float64 `protobuf:"fixed64,23,opt,name=net_tcp_rtt_microsecs_p90" json:"net_tcp_rtt_microsecs_p90,omitempty"` - NetTcpRttMicrosecsP95 *float64 `protobuf:"fixed64,24,opt,name=net_tcp_rtt_microsecs_p95" json:"net_tcp_rtt_microsecs_p95,omitempty"` - NetTcpRttMicrosecsP99 *float64 `protobuf:"fixed64,25,opt,name=net_tcp_rtt_microsecs_p99" json:"net_tcp_rtt_microsecs_p99,omitempty"` - XXX_unrecognized []byte `json:"-"` + NetTcpRttMicrosecsP50 *float64 `protobuf:"fixed64,22,opt,name=net_tcp_rtt_microsecs_p50" json:"net_tcp_rtt_microsecs_p50,omitempty"` + NetTcpRttMicrosecsP90 *float64 `protobuf:"fixed64,23,opt,name=net_tcp_rtt_microsecs_p90" json:"net_tcp_rtt_microsecs_p90,omitempty"` + NetTcpRttMicrosecsP95 *float64 `protobuf:"fixed64,24,opt,name=net_tcp_rtt_microsecs_p95" json:"net_tcp_rtt_microsecs_p95,omitempty"` + NetTcpRttMicrosecsP99 *float64 `protobuf:"fixed64,25,opt,name=net_tcp_rtt_microsecs_p99" json:"net_tcp_rtt_microsecs_p99,omitempty"` + NetTcpActiveConnections *float64 `protobuf:"fixed64,28,opt,name=net_tcp_active_connections" json:"net_tcp_active_connections,omitempty"` + NetTcpTimeWaitConnections *float64 `protobuf:"fixed64,29,opt,name=net_tcp_time_wait_connections" json:"net_tcp_time_wait_connections,omitempty"` + // Network traffic flowing into or out of a container can be delayed + // or dropped due to congestion or policy inside and outside the + // container. + NetTrafficControlStatistics []*TrafficControlStatistics `protobuf:"bytes,35,rep,name=net_traffic_control_statistics" json:"net_traffic_control_statistics,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *ResourceStatistics) Reset() { *m = ResourceStatistics{} } @@ -1437,6 +1892,20 @@ func (m *ResourceStatistics) GetTimestamp() float64 { return 0 } +func (m *ResourceStatistics) GetProcesses() uint32 { + if m != nil && m.Processes != nil { + return *m.Processes + } + return 0 +} + +func (m *ResourceStatistics) GetThreads() uint32 { + if m != nil && m.Threads != nil { + return *m.Threads + } + return 0 +} + func (m *ResourceStatistics) GetCpusUserTimeSecs() float64 { if m != nil && m.CpusUserTimeSecs != nil { return *m.CpusUserTimeSecs @@ -1479,9 +1948,16 @@ func (m *ResourceStatistics) GetCpusThrottledTimeSecs() float64 { return 0 } -func (m *ResourceStatistics) GetMemRssBytes() uint64 { - if m != nil && m.MemRssBytes != nil { - return *m.MemRssBytes +func (m *ResourceStatistics) GetMemTotalBytes() uint64 { + if m != nil && m.MemTotalBytes != nil { + return *m.MemTotalBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemTotalMemswBytes() uint64 { + if m != nil && m.MemTotalMemswBytes != nil { + return *m.MemTotalMemswBytes } return 0 } @@ -1493,6 +1969,13 @@ func (m *ResourceStatistics) GetMemLimitBytes() uint64 { return 0 } +func (m *ResourceStatistics) GetMemSoftLimitBytes() uint64 { + if m != nil && m.MemSoftLimitBytes != nil { + return *m.MemSoftLimitBytes + } + return 0 +} + func (m *ResourceStatistics) GetMemFileBytes() uint64 { if m != nil && m.MemFileBytes != nil { return *m.MemFileBytes @@ -1507,6 +1990,20 @@ func (m *ResourceStatistics) GetMemAnonBytes() uint64 { return 0 } +func (m *ResourceStatistics) GetMemCacheBytes() uint64 { + if m != nil && m.MemCacheBytes != nil { + return *m.MemCacheBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemRssBytes() uint64 { + if m != nil && m.MemRssBytes != nil { + return *m.MemRssBytes + } + return 0 +} + func (m *ResourceStatistics) GetMemMappedFileBytes() uint64 { if m != nil && m.MemMappedFileBytes != nil { return *m.MemMappedFileBytes @@ -1514,37 +2011,79 @@ func (m *ResourceStatistics) GetMemMappedFileBytes() uint64 { return 0 } -func (m *ResourceStatistics) GetPerf() *PerfStatistics { - if m != nil { - return m.Perf +func (m *ResourceStatistics) GetMemSwapBytes() uint64 { + if m != nil && m.MemSwapBytes != nil { + return *m.MemSwapBytes } - return nil + return 0 } -func (m *ResourceStatistics) GetNetRxPackets() uint64 { - if m != nil && m.NetRxPackets != nil { - return *m.NetRxPackets +func (m *ResourceStatistics) GetMemLowPressureCounter() uint64 { + if m != nil && m.MemLowPressureCounter != nil { + return *m.MemLowPressureCounter } return 0 } -func (m *ResourceStatistics) GetNetRxBytes() uint64 { - if m != nil && m.NetRxBytes != nil { - return *m.NetRxBytes +func (m *ResourceStatistics) GetMemMediumPressureCounter() uint64 { + if m != nil && m.MemMediumPressureCounter != nil { + return *m.MemMediumPressureCounter } return 0 } -func (m *ResourceStatistics) GetNetRxErrors() uint64 { - if m != nil && m.NetRxErrors != nil { - return *m.NetRxErrors +func (m *ResourceStatistics) GetMemCriticalPressureCounter() uint64 { + if m != nil && m.MemCriticalPressureCounter != nil { + return *m.MemCriticalPressureCounter } return 0 } -func (m *ResourceStatistics) GetNetRxDropped() uint64 { - if m != nil && m.NetRxDropped != nil { - return *m.NetRxDropped +func (m *ResourceStatistics) GetDiskLimitBytes() uint64 { + if m != nil && m.DiskLimitBytes != nil { + return *m.DiskLimitBytes + } + return 0 +} + +func (m *ResourceStatistics) GetDiskUsedBytes() uint64 { + if m != nil && m.DiskUsedBytes != nil { + return *m.DiskUsedBytes + } + return 0 +} + +func (m *ResourceStatistics) GetPerf() *PerfStatistics { + if m != nil { + return m.Perf + } + return nil +} + +func (m *ResourceStatistics) GetNetRxPackets() uint64 { + if m != nil && m.NetRxPackets != nil { + return *m.NetRxPackets + } + return 0 +} + +func (m *ResourceStatistics) GetNetRxBytes() uint64 { + if m != nil && m.NetRxBytes != nil { + return *m.NetRxBytes + } + return 0 +} + +func (m *ResourceStatistics) GetNetRxErrors() uint64 { + if m != nil && m.NetRxErrors != nil { + return *m.NetRxErrors + } + return 0 +} + +func (m *ResourceStatistics) GetNetRxDropped() uint64 { + if m != nil && m.NetRxDropped != nil { + return *m.NetRxDropped } return 0 } @@ -1605,63 +2144,73 @@ func (m *ResourceStatistics) GetNetTcpRttMicrosecsP99() float64 { return 0 } +func (m *ResourceStatistics) GetNetTcpActiveConnections() float64 { + if m != nil && m.NetTcpActiveConnections != nil { + return *m.NetTcpActiveConnections + } + return 0 +} + +func (m *ResourceStatistics) GetNetTcpTimeWaitConnections() float64 { + if m != nil && m.NetTcpTimeWaitConnections != nil { + return *m.NetTcpTimeWaitConnections + } + return 0 +} + +func (m *ResourceStatistics) GetNetTrafficControlStatistics() []*TrafficControlStatistics { + if m != nil { + return m.NetTrafficControlStatistics + } + return nil +} + // * -// Describes a snapshot of the resource usage for an executor. -// -// TODO(bmahler): Note that we want to be sending this information -// to the master, and subsequently to the relevant scheduler. So -// this proto is designed to be easy for the scheduler to use, this -// is why we provide the slave id, executor info / task info. +// Describes a snapshot of the resource usage for executors. type ResourceUsage struct { - SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"` - FrameworkId *FrameworkID `protobuf:"bytes,2,req,name=framework_id" json:"framework_id,omitempty"` - ExecutorId *ExecutorID `protobuf:"bytes,3,opt,name=executor_id" json:"executor_id,omitempty"` - ExecutorName *string `protobuf:"bytes,4,opt,name=executor_name" json:"executor_name,omitempty"` - TaskId *TaskID `protobuf:"bytes,5,opt,name=task_id" json:"task_id,omitempty"` - // If missing, the isolation module cannot provide resource usage. - Statistics *ResourceStatistics `protobuf:"bytes,6,opt,name=statistics" json:"statistics,omitempty"` - XXX_unrecognized []byte `json:"-"` + Executors []*ResourceUsage_Executor `protobuf:"bytes,1,rep,name=executors" json:"executors,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *ResourceUsage) Reset() { *m = ResourceUsage{} } func (*ResourceUsage) ProtoMessage() {} -func (m *ResourceUsage) GetSlaveId() *SlaveID { +func (m *ResourceUsage) GetExecutors() []*ResourceUsage_Executor { if m != nil { - return m.SlaveId + return m.Executors } return nil } -func (m *ResourceUsage) GetFrameworkId() *FrameworkID { - if m != nil { - return m.FrameworkId - } - return nil +type ResourceUsage_Executor struct { + ExecutorInfo *ExecutorInfo `protobuf:"bytes,1,req,name=executor_info" json:"executor_info,omitempty"` + // This includes resources used by the executor itself + // as well as its active tasks. + Allocated []*Resource `protobuf:"bytes,2,rep,name=allocated" json:"allocated,omitempty"` + // Current resource usage. If absent, the containerizer + // cannot provide resource usage. + Statistics *ResourceStatistics `protobuf:"bytes,3,opt,name=statistics" json:"statistics,omitempty"` + XXX_unrecognized []byte `json:"-"` } -func (m *ResourceUsage) GetExecutorId() *ExecutorID { +func (m *ResourceUsage_Executor) Reset() { *m = ResourceUsage_Executor{} } +func (*ResourceUsage_Executor) ProtoMessage() {} + +func (m *ResourceUsage_Executor) GetExecutorInfo() *ExecutorInfo { if m != nil { - return m.ExecutorId + return m.ExecutorInfo } return nil } -func (m *ResourceUsage) GetExecutorName() string { - if m != nil && m.ExecutorName != nil { - return *m.ExecutorName - } - return "" -} - -func (m *ResourceUsage) GetTaskId() *TaskID { +func (m *ResourceUsage_Executor) GetAllocated() []*Resource { if m != nil { - return m.TaskId + return m.Allocated } return nil } -func (m *ResourceUsage) GetStatistics() *ResourceStatistics { +func (m *ResourceUsage_Executor) GetStatistics() *ResourceStatistics { if m != nil { return m.Statistics } @@ -2118,6 +2667,8 @@ func (m *PerfStatistics) GetNodePrefetchMisses() uint64 { // to proactively influence the allocator. If 'slave_id' is provided // then this request is assumed to only apply to resources on that // slave. +// +// TODO(vinod): Remove this once the old driver is removed. type Request struct { SlaveId *SlaveID `protobuf:"bytes,1,opt,name=slave_id" json:"slave_id,omitempty"` Resources []*Resource `protobuf:"bytes,2,rep,name=resources" json:"resources,omitempty"` @@ -2207,6 +2758,137 @@ func (m *Offer) GetExecutorIds() []*ExecutorID { return nil } +// Defines an operation that can be performed against offers. +type Offer_Operation struct { + Type *Offer_Operation_Type `protobuf:"varint,1,req,name=type,enum=mesosproto.Offer_Operation_Type" json:"type,omitempty"` + Launch *Offer_Operation_Launch `protobuf:"bytes,2,opt,name=launch" json:"launch,omitempty"` + Reserve *Offer_Operation_Reserve `protobuf:"bytes,3,opt,name=reserve" json:"reserve,omitempty"` + Unreserve *Offer_Operation_Unreserve `protobuf:"bytes,4,opt,name=unreserve" json:"unreserve,omitempty"` + Create *Offer_Operation_Create `protobuf:"bytes,5,opt,name=create" json:"create,omitempty"` + Destroy *Offer_Operation_Destroy `protobuf:"bytes,6,opt,name=destroy" json:"destroy,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation) Reset() { *m = Offer_Operation{} } +func (*Offer_Operation) ProtoMessage() {} + +func (m *Offer_Operation) GetType() Offer_Operation_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Offer_Operation_LAUNCH +} + +func (m *Offer_Operation) GetLaunch() *Offer_Operation_Launch { + if m != nil { + return m.Launch + } + return nil +} + +func (m *Offer_Operation) GetReserve() *Offer_Operation_Reserve { + if m != nil { + return m.Reserve + } + return nil +} + +func (m *Offer_Operation) GetUnreserve() *Offer_Operation_Unreserve { + if m != nil { + return m.Unreserve + } + return nil +} + +func (m *Offer_Operation) GetCreate() *Offer_Operation_Create { + if m != nil { + return m.Create + } + return nil +} + +func (m *Offer_Operation) GetDestroy() *Offer_Operation_Destroy { + if m != nil { + return m.Destroy + } + return nil +} + +type Offer_Operation_Launch struct { + TaskInfos []*TaskInfo `protobuf:"bytes,1,rep,name=task_infos" json:"task_infos,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation_Launch) Reset() { *m = Offer_Operation_Launch{} } +func (*Offer_Operation_Launch) ProtoMessage() {} + +func (m *Offer_Operation_Launch) GetTaskInfos() []*TaskInfo { + if m != nil { + return m.TaskInfos + } + return nil +} + +type Offer_Operation_Reserve struct { + Resources []*Resource `protobuf:"bytes,1,rep,name=resources" json:"resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation_Reserve) Reset() { *m = Offer_Operation_Reserve{} } +func (*Offer_Operation_Reserve) ProtoMessage() {} + +func (m *Offer_Operation_Reserve) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +type Offer_Operation_Unreserve struct { + Resources []*Resource `protobuf:"bytes,1,rep,name=resources" json:"resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation_Unreserve) Reset() { *m = Offer_Operation_Unreserve{} } +func (*Offer_Operation_Unreserve) ProtoMessage() {} + +func (m *Offer_Operation_Unreserve) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +type Offer_Operation_Create struct { + Volumes []*Resource `protobuf:"bytes,1,rep,name=volumes" json:"volumes,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation_Create) Reset() { *m = Offer_Operation_Create{} } +func (*Offer_Operation_Create) ProtoMessage() {} + +func (m *Offer_Operation_Create) GetVolumes() []*Resource { + if m != nil { + return m.Volumes + } + return nil +} + +type Offer_Operation_Destroy struct { + Volumes []*Resource `protobuf:"bytes,1,rep,name=volumes" json:"volumes,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation_Destroy) Reset() { *m = Offer_Operation_Destroy{} } +func (*Offer_Operation_Destroy) ProtoMessage() {} + +func (m *Offer_Operation_Destroy) GetVolumes() []*Resource { + if m != nil { + return m.Volumes + } + return nil +} + // * // Describes a task. Passed from the scheduler all the way to an // executor (see SchedulerDriver::launchTasks and @@ -2226,8 +2908,19 @@ type TaskInfo struct { Data []byte `protobuf:"bytes,6,opt,name=data" json:"data,omitempty"` // A health check for the task (currently in *alpha* and initial // support will only be for TaskInfo's that have a CommandInfo). - HealthCheck *HealthCheck `protobuf:"bytes,8,opt,name=health_check" json:"health_check,omitempty"` - XXX_unrecognized []byte `json:"-"` + HealthCheck *HealthCheck `protobuf:"bytes,8,opt,name=health_check" json:"health_check,omitempty"` + // Labels are free-form key value pairs which are exposed through + // master and slave endpoints. Labels will not be interpreted or + // acted upon by Mesos itself. As opposed to the data field, labels + // will be kept in memory on master and slave processes. Therefore, + // labels should be used to tag tasks with light-weight meta-data. + Labels *Labels `protobuf:"bytes,10,opt,name=labels" json:"labels,omitempty"` + // Service discovery information for the task. It is not interpreted + // or acted upon by Mesos. It is up to a service discovery system + // to use this information as needed and to handle tasks without + // service discovery information. + Discovery *DiscoveryInfo `protobuf:"bytes,11,opt,name=discovery" json:"discovery,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *TaskInfo) Reset() { *m = TaskInfo{} } @@ -2296,6 +2989,20 @@ func (m *TaskInfo) GetHealthCheck() *HealthCheck { return nil } +func (m *TaskInfo) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +func (m *TaskInfo) GetDiscovery() *DiscoveryInfo { + if m != nil { + return m.Discovery + } + return nil +} + // * // Describes the current status of a task. type TaskStatus struct { @@ -2308,6 +3015,16 @@ type TaskStatus struct { SlaveId *SlaveID `protobuf:"bytes,5,opt,name=slave_id" json:"slave_id,omitempty"` ExecutorId *ExecutorID `protobuf:"bytes,7,opt,name=executor_id" json:"executor_id,omitempty"` Timestamp *float64 `protobuf:"fixed64,6,opt,name=timestamp" json:"timestamp,omitempty"` + // Statuses that are delivered reliably to the scheduler will + // include a 'uuid'. The status is considered delivered once + // it is acknowledged by the scheduler. Schedulers can choose + // to either explicitly acknowledge statuses or let the scheduler + // driver implicitly acknowledge (default). + // + // TODO(bmahler): This is currently overwritten in the scheduler + // driver and executor driver, but executors will need to set this + // to a valid RFC-4122 UUID if using the HTTP API. + Uuid []byte `protobuf:"bytes,11,opt,name=uuid" json:"uuid,omitempty"` // Describes whether the task has been determined to be healthy // (true) or unhealthy (false) according to the HealthCheck field in // the command info. @@ -2381,6 +3098,13 @@ func (m *TaskStatus) GetTimestamp() float64 { return 0 } +func (m *TaskStatus) GetUuid() []byte { + if m != nil { + return m.Uuid + } + return nil +} + func (m *TaskStatus) GetHealthy() bool { if m != nil && m.Healthy != nil { return *m.Healthy @@ -2895,11 +3619,15 @@ type ContainerInfo_DockerInfo struct { PortMappings []*ContainerInfo_DockerInfo_PortMapping `protobuf:"bytes,3,rep,name=port_mappings" json:"port_mappings,omitempty"` Privileged *bool `protobuf:"varint,4,opt,name=privileged,def=0" json:"privileged,omitempty"` // Allowing arbitrary parameters to be passed to docker CLI. - // Note that anything passed to this field is not guranteed + // Note that anything passed to this field is not guaranteed // to be supported moving forward, as we might move away from // the docker CLI. - Parameters []*Parameter `protobuf:"bytes,5,rep,name=parameters" json:"parameters,omitempty"` - XXX_unrecognized []byte `json:"-"` + Parameters []*Parameter `protobuf:"bytes,5,rep,name=parameters" json:"parameters,omitempty"` + // With this flag set to true, the docker containerizer will + // pull the docker image from the registry even if the image + // is already downloaded on the slave. + ForcePullImage *bool `protobuf:"varint,6,opt,name=force_pull_image" json:"force_pull_image,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *ContainerInfo_DockerInfo) Reset() { *m = ContainerInfo_DockerInfo{} } @@ -2943,6 +3671,13 @@ func (m *ContainerInfo_DockerInfo) GetParameters() []*Parameter { return nil } +func (m *ContainerInfo_DockerInfo) GetForcePullImage() bool { + if m != nil && m.ForcePullImage != nil { + return *m.ForcePullImage + } + return false +} + type ContainerInfo_DockerInfo_PortMapping struct { HostPort *uint32 `protobuf:"varint,1,req,name=host_port" json:"host_port,omitempty"` ContainerPort *uint32 `protobuf:"varint,2,req,name=container_port" json:"container_port,omitempty"` @@ -2975,10588 +3710,11961 @@ func (m *ContainerInfo_DockerInfo_PortMapping) GetProtocol() string { return "" } -func init() { - proto.RegisterEnum("mesosproto.Status", Status_name, Status_value) - proto.RegisterEnum("mesosproto.TaskState", TaskState_name, TaskState_value) - proto.RegisterEnum("mesosproto.Value_Type", Value_Type_name, Value_Type_value) - proto.RegisterEnum("mesosproto.TaskStatus_Source", TaskStatus_Source_name, TaskStatus_Source_value) - proto.RegisterEnum("mesosproto.TaskStatus_Reason", TaskStatus_Reason_name, TaskStatus_Reason_value) - proto.RegisterEnum("mesosproto.ACL_Entity_Type", ACL_Entity_Type_name, ACL_Entity_Type_value) - proto.RegisterEnum("mesosproto.Volume_Mode", Volume_Mode_name, Volume_Mode_value) - proto.RegisterEnum("mesosproto.ContainerInfo_Type", ContainerInfo_Type_name, ContainerInfo_Type_value) - proto.RegisterEnum("mesosproto.ContainerInfo_DockerInfo_Network", ContainerInfo_DockerInfo_Network_name, ContainerInfo_DockerInfo_Network_value) +// * +// Collection of labels. +type Labels struct { + Labels []*Label `protobuf:"bytes,1,rep,name=labels" json:"labels,omitempty"` + XXX_unrecognized []byte `json:"-"` } -func (m *FrameworkID) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - 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) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Value = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy - } + +func (m *Labels) Reset() { *m = Labels{} } +func (*Labels) ProtoMessage() {} + +func (m *Labels) GetLabels() []*Label { + if m != nil { + return m.Labels } return nil } -func (m *OfferID) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - 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) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Value = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy - } + +// * +// Key, value pair used to store free form user-data. +type Label struct { + Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` + Value *string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Label) Reset() { *m = Label{} } +func (*Label) ProtoMessage() {} + +func (m *Label) GetKey() string { + if m != nil && m.Key != nil { + return *m.Key + } + return "" +} + +func (m *Label) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +// * +// Named port used for service discovery. +type Port struct { + Number *uint32 `protobuf:"varint,1,req,name=number" json:"number,omitempty"` + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + Protocol *string `protobuf:"bytes,3,opt,name=protocol" json:"protocol,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Port) Reset() { *m = Port{} } +func (*Port) ProtoMessage() {} + +func (m *Port) GetNumber() uint32 { + if m != nil && m.Number != nil { + return *m.Number + } + return 0 +} + +func (m *Port) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Port) GetProtocol() string { + if m != nil && m.Protocol != nil { + return *m.Protocol + } + return "" +} + +// * +// Collection of ports. +type Ports struct { + Ports []*Port `protobuf:"bytes,1,rep,name=ports" json:"ports,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Ports) Reset() { *m = Ports{} } +func (*Ports) ProtoMessage() {} + +func (m *Ports) GetPorts() []*Port { + if m != nil { + return m.Ports } return nil } -func (m *SlaveID) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - 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) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Value = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy - } + +// * +// Service discovery information. +// The visibility field restricts discovery within a framework +// (FRAMEWORK), within a Mesos cluster (CLUSTER), or places no +// restrictions (EXTERNAL). +// The environment, location, and version fields provide first class +// support for common attributes used to differentiate between +// similar services. The environment may receive values such as +// PROD/QA/DEV, the location field may receive values like +// EAST-US/WEST-US/EUROPE/AMEA, and the version field may receive +// values like v2.0/v0.9. The exact use of these fields is up to each +// service discovery system. +type DiscoveryInfo struct { + Visibility *DiscoveryInfo_Visibility `protobuf:"varint,1,req,name=visibility,enum=mesosproto.DiscoveryInfo_Visibility" json:"visibility,omitempty"` + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + Environment *string `protobuf:"bytes,3,opt,name=environment" json:"environment,omitempty"` + Location *string `protobuf:"bytes,4,opt,name=location" json:"location,omitempty"` + Version *string `protobuf:"bytes,5,opt,name=version" json:"version,omitempty"` + Ports *Ports `protobuf:"bytes,6,opt,name=ports" json:"ports,omitempty"` + Labels *Labels `protobuf:"bytes,7,opt,name=labels" json:"labels,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *DiscoveryInfo) Reset() { *m = DiscoveryInfo{} } +func (*DiscoveryInfo) ProtoMessage() {} + +func (m *DiscoveryInfo) GetVisibility() DiscoveryInfo_Visibility { + if m != nil && m.Visibility != nil { + return *m.Visibility + } + return DiscoveryInfo_FRAMEWORK +} + +func (m *DiscoveryInfo) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *DiscoveryInfo) GetEnvironment() string { + if m != nil && m.Environment != nil { + return *m.Environment + } + return "" +} + +func (m *DiscoveryInfo) GetLocation() string { + if m != nil && m.Location != nil { + return *m.Location + } + return "" +} + +func (m *DiscoveryInfo) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + +func (m *DiscoveryInfo) GetPorts() *Ports { + if m != nil { + return m.Ports } return nil } -func (m *TaskID) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + +func (m *DiscoveryInfo) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +func init() { + proto.RegisterEnum("mesosproto.Status", Status_name, Status_value) + proto.RegisterEnum("mesosproto.TaskState", TaskState_name, TaskState_value) + proto.RegisterEnum("mesosproto.FrameworkInfo_Capability_Type", FrameworkInfo_Capability_Type_name, FrameworkInfo_Capability_Type_value) + proto.RegisterEnum("mesosproto.Value_Type", Value_Type_name, Value_Type_value) + proto.RegisterEnum("mesosproto.Offer_Operation_Type", Offer_Operation_Type_name, Offer_Operation_Type_value) + proto.RegisterEnum("mesosproto.TaskStatus_Source", TaskStatus_Source_name, TaskStatus_Source_value) + proto.RegisterEnum("mesosproto.TaskStatus_Reason", TaskStatus_Reason_name, TaskStatus_Reason_value) + proto.RegisterEnum("mesosproto.ACL_Entity_Type", ACL_Entity_Type_name, ACL_Entity_Type_value) + proto.RegisterEnum("mesosproto.Volume_Mode", Volume_Mode_name, Volume_Mode_value) + proto.RegisterEnum("mesosproto.ContainerInfo_Type", ContainerInfo_Type_name, ContainerInfo_Type_value) + proto.RegisterEnum("mesosproto.ContainerInfo_DockerInfo_Network", ContainerInfo_DockerInfo_Network_name, ContainerInfo_DockerInfo_Network_value) + proto.RegisterEnum("mesosproto.DiscoveryInfo_Visibility", DiscoveryInfo_Visibility_name, DiscoveryInfo_Visibility_value) +} +func (this *FrameworkID) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Value = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*FrameworkID) + if !ok { + return fmt.Errorf("that is not of type *FrameworkID") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *FrameworkID but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *FrameworkIDbut is not nil && this == nil") + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *ExecutorID) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *FrameworkID) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Value = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*FrameworkID) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *OfferID) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*OfferID) + if !ok { + return fmt.Errorf("that is not of type *OfferID") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *OfferID but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *OfferIDbut is not nil && this == nil") + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *ContainerID) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *OfferID) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Value = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*OfferID) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *SlaveID) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*SlaveID) + if !ok { + return fmt.Errorf("that is not of type *SlaveID") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *SlaveID but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *SlaveIDbut is not nil && this == nil") + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *FrameworkInfo) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *SlaveID) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.User = &s - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Name = &s - index = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Id == nil { - m.Id = &FrameworkID{} - } - if err := m.Id.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 4: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field FailoverTimeout", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.FailoverTimeout = &v2 - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Checkpoint", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Checkpoint = &b - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Role = &s - index = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Hostname = &s - index = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Principal", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Principal = &s - index = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field WebuiUrl", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.WebuiUrl = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*SlaveID) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false } - return nil + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *HealthCheck) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *TaskID) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Http", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Http == nil { - m.Http = &HealthCheck_HTTP{} - } - if err := m.Http.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 2: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field DelaySeconds", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.DelaySeconds = &v2 - case 3: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field IntervalSeconds", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.IntervalSeconds = &v2 - case 4: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field TimeoutSeconds", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.TimeoutSeconds = &v2 - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ConsecutiveFailures", wireType) - } - var v uint32 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.ConsecutiveFailures = &v - case 6: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field GracePeriodSeconds", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.GracePeriodSeconds = &v2 - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Command", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Command == nil { - m.Command = &CommandInfo{} - } - if err := m.Command.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*TaskID) + if !ok { + return fmt.Errorf("that is not of type *TaskID") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *TaskID but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *TaskIDbut is not nil && this == nil") + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *HealthCheck_HTTP) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - 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) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) - } - var v uint32 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Port = &v - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Path = &s - index = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Statuses", wireType) - } - var v uint32 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Statuses = append(m.Statuses, v) - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy +func (this *TaskID) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } + return false } - return nil -} -func (m *CommandInfo) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + + that1, ok := that.(*TaskID) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Container == nil { - m.Container = &CommandInfo_ContainerInfo{} - } - if err := m.Container.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Uris", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Uris = append(m.Uris, &CommandInfo_URI{}) - m.Uris[len(m.Uris)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Environment", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Environment == nil { - m.Environment = &Environment{} - } - if err := m.Environment.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Shell", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Shell = &b - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Value = &s - index = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Arguments", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Arguments = append(m.Arguments, string(data[index:postIndex])) - index = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.User = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } else if this == nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false } - return nil + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *CommandInfo_URI) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - 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) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Value = &s - index = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Executable", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Executable = &b - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Extract", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Extract = &b - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy +func (this *ExecutorID) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ExecutorID) + if !ok { + return fmt.Errorf("that is not of type *ExecutorID") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ExecutorID but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ExecutorIDbut is not nil && this == nil") + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *CommandInfo_ContainerInfo) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *ExecutorID) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Image", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Image = &s - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Options", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Options = append(m.Options, string(data[index:postIndex])) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*ExecutorID) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *ContainerID) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ContainerID) + if !ok { + return fmt.Errorf("that is not of type *ContainerID") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ContainerID but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ContainerIDbut is not nil && this == nil") + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *ExecutorInfo) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *ContainerID) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExecutorId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ExecutorId == nil { - m.ExecutorId = &ExecutorID{} - } - if err := m.ExecutorId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FrameworkId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.FrameworkId == nil { - m.FrameworkId = &FrameworkID{} - } - if err := m.FrameworkId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Command", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Command == nil { - m.Command = &CommandInfo{} - } - if err := m.Command.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Container == nil { - m.Container = &ContainerInfo{} - } - if err := m.Container.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resources = append(m.Resources, &Resource{}) - m.Resources[len(m.Resources)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Name = &s - index = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Source = &s - index = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append([]byte{}, data[index:postIndex]...) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*ContainerID) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *FrameworkInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*FrameworkInfo) + if !ok { + return fmt.Errorf("that is not of type *FrameworkInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *FrameworkInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *FrameworkInfobut is not nil && this == nil") + } + if this.User != nil && that1.User != nil { + if *this.User != *that1.User { + return fmt.Errorf("User this(%v) Not Equal that(%v)", *this.User, *that1.User) + } + } else if this.User != nil { + return fmt.Errorf("this.User == nil && that.User != nil") + } else if that1.User != nil { + return fmt.Errorf("User this(%v) Not Equal that(%v)", this.User, that1.User) + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) + } + } else if this.Name != nil { + return fmt.Errorf("this.Name == nil && that.Name != nil") + } else if that1.Name != nil { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + } + if !this.Id.Equal(that1.Id) { + return fmt.Errorf("Id this(%v) Not Equal that(%v)", this.Id, that1.Id) + } + if this.FailoverTimeout != nil && that1.FailoverTimeout != nil { + if *this.FailoverTimeout != *that1.FailoverTimeout { + return fmt.Errorf("FailoverTimeout this(%v) Not Equal that(%v)", *this.FailoverTimeout, *that1.FailoverTimeout) + } + } else if this.FailoverTimeout != nil { + return fmt.Errorf("this.FailoverTimeout == nil && that.FailoverTimeout != nil") + } else if that1.FailoverTimeout != nil { + return fmt.Errorf("FailoverTimeout this(%v) Not Equal that(%v)", this.FailoverTimeout, that1.FailoverTimeout) + } + if this.Checkpoint != nil && that1.Checkpoint != nil { + if *this.Checkpoint != *that1.Checkpoint { + return fmt.Errorf("Checkpoint this(%v) Not Equal that(%v)", *this.Checkpoint, *that1.Checkpoint) } + } else if this.Checkpoint != nil { + return fmt.Errorf("this.Checkpoint == nil && that.Checkpoint != nil") + } else if that1.Checkpoint != nil { + return fmt.Errorf("Checkpoint this(%v) Not Equal that(%v)", this.Checkpoint, that1.Checkpoint) + } + if this.Role != nil && that1.Role != nil { + if *this.Role != *that1.Role { + return fmt.Errorf("Role this(%v) Not Equal that(%v)", *this.Role, *that1.Role) + } + } else if this.Role != nil { + return fmt.Errorf("this.Role == nil && that.Role != nil") + } else if that1.Role != nil { + return fmt.Errorf("Role this(%v) Not Equal that(%v)", this.Role, that1.Role) + } + if this.Hostname != nil && that1.Hostname != nil { + if *this.Hostname != *that1.Hostname { + return fmt.Errorf("Hostname this(%v) Not Equal that(%v)", *this.Hostname, *that1.Hostname) + } + } else if this.Hostname != nil { + return fmt.Errorf("this.Hostname == nil && that.Hostname != nil") + } else if that1.Hostname != nil { + return fmt.Errorf("Hostname this(%v) Not Equal that(%v)", this.Hostname, that1.Hostname) + } + if this.Principal != nil && that1.Principal != nil { + if *this.Principal != *that1.Principal { + return fmt.Errorf("Principal this(%v) Not Equal that(%v)", *this.Principal, *that1.Principal) + } + } else if this.Principal != nil { + return fmt.Errorf("this.Principal == nil && that.Principal != nil") + } else if that1.Principal != nil { + return fmt.Errorf("Principal this(%v) Not Equal that(%v)", this.Principal, that1.Principal) + } + if this.WebuiUrl != nil && that1.WebuiUrl != nil { + if *this.WebuiUrl != *that1.WebuiUrl { + return fmt.Errorf("WebuiUrl this(%v) Not Equal that(%v)", *this.WebuiUrl, *that1.WebuiUrl) + } + } else if this.WebuiUrl != nil { + return fmt.Errorf("this.WebuiUrl == nil && that.WebuiUrl != nil") + } else if that1.WebuiUrl != nil { + return fmt.Errorf("WebuiUrl this(%v) Not Equal that(%v)", this.WebuiUrl, that1.WebuiUrl) + } + if len(this.Capabilities) != len(that1.Capabilities) { + return fmt.Errorf("Capabilities this(%v) Not Equal that(%v)", len(this.Capabilities), len(that1.Capabilities)) + } + for i := range this.Capabilities { + if !this.Capabilities[i].Equal(that1.Capabilities[i]) { + return fmt.Errorf("Capabilities this[%v](%v) Not Equal that[%v](%v)", i, this.Capabilities[i], i, that1.Capabilities[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *MasterInfo) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *FrameworkInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Id = &s - index = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Ip", wireType) - } - var v uint32 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Ip = &v - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) - } - var v uint32 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Port = &v - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pid", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Pid = &s - index = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Hostname = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*FrameworkInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false } - return nil -} -func (m *SlaveInfo) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if this.User != nil && that1.User != nil { + if *this.User != *that1.User { + return false } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Hostname = &s - index = postIndex - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Port = &v - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resources = append(m.Resources, &Resource{}) - m.Resources[len(m.Resources)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Attributes = append(m.Attributes, &Attribute{}) - m.Attributes[len(m.Attributes)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Id == nil { - m.Id = &SlaveID{} - } - if err := m.Id.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Checkpoint", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Checkpoint = &b - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } else if this.User != nil { + return false + } else if that1.User != nil { + return false + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return false } + } else if this.Name != nil { + return false + } else if that1.Name != nil { + return false } - return nil -} -func (m *Value) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if !this.Id.Equal(that1.Id) { + return false + } + if this.FailoverTimeout != nil && that1.FailoverTimeout != nil { + if *this.FailoverTimeout != *that1.FailoverTimeout { + return false } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var v Value_Type - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (Value_Type(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Type = &v - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Scalar", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Scalar == nil { - m.Scalar = &Value_Scalar{} - } - if err := m.Scalar.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Ranges == nil { - m.Ranges = &Value_Ranges{} - } - if err := m.Ranges.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Set", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Set == nil { - m.Set = &Value_Set{} - } - if err := m.Set.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Text", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Text == nil { - m.Text = &Value_Text{} - } - if err := m.Text.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } else if this.FailoverTimeout != nil { + return false + } else if that1.FailoverTimeout != nil { + return false + } + if this.Checkpoint != nil && that1.Checkpoint != nil { + if *this.Checkpoint != *that1.Checkpoint { + return false } + } else if this.Checkpoint != nil { + return false + } else if that1.Checkpoint != nil { + return false } - return nil -} -func (m *Value_Scalar) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if this.Role != nil && that1.Role != nil { + if *this.Role != *that1.Role { + return false } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.Value = &v2 - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } else if this.Role != nil { + return false + } else if that1.Role != nil { + return false + } + if this.Hostname != nil && that1.Hostname != nil { + if *this.Hostname != *that1.Hostname { + return false } + } else if this.Hostname != nil { + return false + } else if that1.Hostname != nil { + return false } - return nil -} -func (m *Value_Range) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if this.Principal != nil && that1.Principal != nil { + if *this.Principal != *that1.Principal { + return false } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Begin", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Begin = &v - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field End", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.End = &v - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } else if this.Principal != nil { + return false + } else if that1.Principal != nil { + return false + } + if this.WebuiUrl != nil && that1.WebuiUrl != nil { + if *this.WebuiUrl != *that1.WebuiUrl { + return false } + } else if this.WebuiUrl != nil { + return false + } else if that1.WebuiUrl != nil { + return false } - return nil + if len(this.Capabilities) != len(that1.Capabilities) { + return false + } + for i := range this.Capabilities { + if !this.Capabilities[i].Equal(that1.Capabilities[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *Value_Ranges) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *FrameworkInfo_Capability) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Range", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Range = append(m.Range, &Value_Range{}) - m.Range[len(m.Range)-1].Unmarshal(data[index:postIndex]) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*FrameworkInfo_Capability) + if !ok { + return fmt.Errorf("that is not of type *FrameworkInfo_Capability") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *FrameworkInfo_Capability but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *FrameworkInfo_Capabilitybut is not nil && this == nil") + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) } + } else if this.Type != nil { + return fmt.Errorf("this.Type == nil && that.Type != nil") + } else if that1.Type != nil { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *Value_Set) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *FrameworkInfo_Capability) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Item", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Item = append(m.Item, string(data[index:postIndex])) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*FrameworkInfo_Capability) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false } - return nil + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return false + } + } else if this.Type != nil { + return false + } else if that1.Type != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *Value_Text) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *HealthCheck) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Value = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*HealthCheck) + if !ok { + return fmt.Errorf("that is not of type *HealthCheck") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *HealthCheck but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *HealthCheckbut is not nil && this == nil") + } + if !this.Http.Equal(that1.Http) { + return fmt.Errorf("Http this(%v) Not Equal that(%v)", this.Http, that1.Http) + } + if this.DelaySeconds != nil && that1.DelaySeconds != nil { + if *this.DelaySeconds != *that1.DelaySeconds { + return fmt.Errorf("DelaySeconds this(%v) Not Equal that(%v)", *this.DelaySeconds, *that1.DelaySeconds) + } + } else if this.DelaySeconds != nil { + return fmt.Errorf("this.DelaySeconds == nil && that.DelaySeconds != nil") + } else if that1.DelaySeconds != nil { + return fmt.Errorf("DelaySeconds this(%v) Not Equal that(%v)", this.DelaySeconds, that1.DelaySeconds) + } + if this.IntervalSeconds != nil && that1.IntervalSeconds != nil { + if *this.IntervalSeconds != *that1.IntervalSeconds { + return fmt.Errorf("IntervalSeconds this(%v) Not Equal that(%v)", *this.IntervalSeconds, *that1.IntervalSeconds) + } + } else if this.IntervalSeconds != nil { + return fmt.Errorf("this.IntervalSeconds == nil && that.IntervalSeconds != nil") + } else if that1.IntervalSeconds != nil { + return fmt.Errorf("IntervalSeconds this(%v) Not Equal that(%v)", this.IntervalSeconds, that1.IntervalSeconds) + } + if this.TimeoutSeconds != nil && that1.TimeoutSeconds != nil { + if *this.TimeoutSeconds != *that1.TimeoutSeconds { + return fmt.Errorf("TimeoutSeconds this(%v) Not Equal that(%v)", *this.TimeoutSeconds, *that1.TimeoutSeconds) + } + } else if this.TimeoutSeconds != nil { + return fmt.Errorf("this.TimeoutSeconds == nil && that.TimeoutSeconds != nil") + } else if that1.TimeoutSeconds != nil { + return fmt.Errorf("TimeoutSeconds this(%v) Not Equal that(%v)", this.TimeoutSeconds, that1.TimeoutSeconds) + } + if this.ConsecutiveFailures != nil && that1.ConsecutiveFailures != nil { + if *this.ConsecutiveFailures != *that1.ConsecutiveFailures { + return fmt.Errorf("ConsecutiveFailures this(%v) Not Equal that(%v)", *this.ConsecutiveFailures, *that1.ConsecutiveFailures) } + } else if this.ConsecutiveFailures != nil { + return fmt.Errorf("this.ConsecutiveFailures == nil && that.ConsecutiveFailures != nil") + } else if that1.ConsecutiveFailures != nil { + return fmt.Errorf("ConsecutiveFailures this(%v) Not Equal that(%v)", this.ConsecutiveFailures, that1.ConsecutiveFailures) + } + if this.GracePeriodSeconds != nil && that1.GracePeriodSeconds != nil { + if *this.GracePeriodSeconds != *that1.GracePeriodSeconds { + return fmt.Errorf("GracePeriodSeconds this(%v) Not Equal that(%v)", *this.GracePeriodSeconds, *that1.GracePeriodSeconds) + } + } else if this.GracePeriodSeconds != nil { + return fmt.Errorf("this.GracePeriodSeconds == nil && that.GracePeriodSeconds != nil") + } else if that1.GracePeriodSeconds != nil { + return fmt.Errorf("GracePeriodSeconds this(%v) Not Equal that(%v)", this.GracePeriodSeconds, that1.GracePeriodSeconds) + } + if !this.Command.Equal(that1.Command) { + return fmt.Errorf("Command this(%v) Not Equal that(%v)", this.Command, that1.Command) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *Attribute) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *HealthCheck) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Name = &s - index = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var v Value_Type - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (Value_Type(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Type = &v - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Scalar", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Scalar == nil { - m.Scalar = &Value_Scalar{} - } - if err := m.Scalar.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Ranges == nil { - m.Ranges = &Value_Ranges{} - } - if err := m.Ranges.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Set", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Set == nil { - m.Set = &Value_Set{} - } - if err := m.Set.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Text", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Text == nil { - m.Text = &Value_Text{} - } - if err := m.Text.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*HealthCheck) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false + } + if !this.Http.Equal(that1.Http) { + return false + } + if this.DelaySeconds != nil && that1.DelaySeconds != nil { + if *this.DelaySeconds != *that1.DelaySeconds { + return false + } + } else if this.DelaySeconds != nil { + return false + } else if that1.DelaySeconds != nil { + return false + } + if this.IntervalSeconds != nil && that1.IntervalSeconds != nil { + if *this.IntervalSeconds != *that1.IntervalSeconds { + return false + } + } else if this.IntervalSeconds != nil { + return false + } else if that1.IntervalSeconds != nil { + return false + } + if this.TimeoutSeconds != nil && that1.TimeoutSeconds != nil { + if *this.TimeoutSeconds != *that1.TimeoutSeconds { + return false + } + } else if this.TimeoutSeconds != nil { + return false + } else if that1.TimeoutSeconds != nil { + return false + } + if this.ConsecutiveFailures != nil && that1.ConsecutiveFailures != nil { + if *this.ConsecutiveFailures != *that1.ConsecutiveFailures { + return false + } + } else if this.ConsecutiveFailures != nil { + return false + } else if that1.ConsecutiveFailures != nil { + return false + } + if this.GracePeriodSeconds != nil && that1.GracePeriodSeconds != nil { + if *this.GracePeriodSeconds != *that1.GracePeriodSeconds { + return false + } + } else if this.GracePeriodSeconds != nil { + return false + } else if that1.GracePeriodSeconds != nil { + return false + } + if !this.Command.Equal(that1.Command) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *HealthCheck_HTTP) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*HealthCheck_HTTP) + if !ok { + return fmt.Errorf("that is not of type *HealthCheck_HTTP") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *HealthCheck_HTTP but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *HealthCheck_HTTPbut is not nil && this == nil") + } + if this.Port != nil && that1.Port != nil { + if *this.Port != *that1.Port { + return fmt.Errorf("Port this(%v) Not Equal that(%v)", *this.Port, *that1.Port) + } + } else if this.Port != nil { + return fmt.Errorf("this.Port == nil && that.Port != nil") + } else if that1.Port != nil { + return fmt.Errorf("Port this(%v) Not Equal that(%v)", this.Port, that1.Port) + } + if this.Path != nil && that1.Path != nil { + if *this.Path != *that1.Path { + return fmt.Errorf("Path this(%v) Not Equal that(%v)", *this.Path, *that1.Path) + } + } else if this.Path != nil { + return fmt.Errorf("this.Path == nil && that.Path != nil") + } else if that1.Path != nil { + return fmt.Errorf("Path this(%v) Not Equal that(%v)", this.Path, that1.Path) + } + if len(this.Statuses) != len(that1.Statuses) { + return fmt.Errorf("Statuses this(%v) Not Equal that(%v)", len(this.Statuses), len(that1.Statuses)) + } + for i := range this.Statuses { + if this.Statuses[i] != that1.Statuses[i] { + return fmt.Errorf("Statuses this[%v](%v) Not Equal that[%v](%v)", i, this.Statuses[i], i, that1.Statuses[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *Resource) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *HealthCheck_HTTP) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Name = &s - index = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var v Value_Type - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (Value_Type(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Type = &v - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Scalar", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Scalar == nil { - m.Scalar = &Value_Scalar{} - } - if err := m.Scalar.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Ranges == nil { - m.Ranges = &Value_Ranges{} - } - if err := m.Ranges.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Set", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Set == nil { - m.Set = &Value_Set{} - } - if err := m.Set.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Role = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*HealthCheck_HTTP) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Port != nil && that1.Port != nil { + if *this.Port != *that1.Port { + return false + } + } else if this.Port != nil { + return false + } else if that1.Port != nil { + return false + } + if this.Path != nil && that1.Path != nil { + if *this.Path != *that1.Path { + return false + } + } else if this.Path != nil { + return false + } else if that1.Path != nil { + return false + } + if len(this.Statuses) != len(that1.Statuses) { + return false + } + for i := range this.Statuses { + if this.Statuses[i] != that1.Statuses[i] { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *CommandInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*CommandInfo) + if !ok { + return fmt.Errorf("that is not of type *CommandInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *CommandInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *CommandInfobut is not nil && this == nil") + } + if !this.Container.Equal(that1.Container) { + return fmt.Errorf("Container this(%v) Not Equal that(%v)", this.Container, that1.Container) + } + if len(this.Uris) != len(that1.Uris) { + return fmt.Errorf("Uris this(%v) Not Equal that(%v)", len(this.Uris), len(that1.Uris)) + } + for i := range this.Uris { + if !this.Uris[i].Equal(that1.Uris[i]) { + return fmt.Errorf("Uris this[%v](%v) Not Equal that[%v](%v)", i, this.Uris[i], i, that1.Uris[i]) + } + } + if !this.Environment.Equal(that1.Environment) { + return fmt.Errorf("Environment this(%v) Not Equal that(%v)", this.Environment, that1.Environment) + } + if this.Shell != nil && that1.Shell != nil { + if *this.Shell != *that1.Shell { + return fmt.Errorf("Shell this(%v) Not Equal that(%v)", *this.Shell, *that1.Shell) + } + } else if this.Shell != nil { + return fmt.Errorf("this.Shell == nil && that.Shell != nil") + } else if that1.Shell != nil { + return fmt.Errorf("Shell this(%v) Not Equal that(%v)", this.Shell, that1.Shell) + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if len(this.Arguments) != len(that1.Arguments) { + return fmt.Errorf("Arguments this(%v) Not Equal that(%v)", len(this.Arguments), len(that1.Arguments)) + } + for i := range this.Arguments { + if this.Arguments[i] != that1.Arguments[i] { + return fmt.Errorf("Arguments this[%v](%v) Not Equal that[%v](%v)", i, this.Arguments[i], i, that1.Arguments[i]) + } + } + if this.User != nil && that1.User != nil { + if *this.User != *that1.User { + return fmt.Errorf("User this(%v) Not Equal that(%v)", *this.User, *that1.User) } + } else if this.User != nil { + return fmt.Errorf("this.User == nil && that.User != nil") + } else if that1.User != nil { + return fmt.Errorf("User this(%v) Not Equal that(%v)", this.User, that1.User) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *ResourceStatistics) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *CommandInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.Timestamp = &v2 - case 2: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field CpusUserTimeSecs", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.CpusUserTimeSecs = &v2 - case 3: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field CpusSystemTimeSecs", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.CpusSystemTimeSecs = &v2 - case 4: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field CpusLimit", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.CpusLimit = &v2 - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CpusNrPeriods", wireType) - } - var v uint32 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.CpusNrPeriods = &v - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CpusNrThrottled", wireType) - } - var v uint32 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.CpusNrThrottled = &v - case 9: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field CpusThrottledTimeSecs", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.CpusThrottledTimeSecs = &v2 - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MemRssBytes", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.MemRssBytes = &v - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MemLimitBytes", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.MemLimitBytes = &v - case 10: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MemFileBytes", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.MemFileBytes = &v - case 11: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MemAnonBytes", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.MemAnonBytes = &v - case 12: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MemMappedFileBytes", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.MemMappedFileBytes = &v - case 13: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Perf", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Perf == nil { - m.Perf = &PerfStatistics{} - } - if err := m.Perf.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 14: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NetRxPackets", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NetRxPackets = &v - case 15: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NetRxBytes", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NetRxBytes = &v - case 16: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NetRxErrors", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NetRxErrors = &v - case 17: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NetRxDropped", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NetRxDropped = &v - case 18: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NetTxPackets", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NetTxPackets = &v - case 19: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NetTxBytes", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NetTxBytes = &v - case 20: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NetTxErrors", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NetTxErrors = &v - case 21: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NetTxDropped", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NetTxDropped = &v - case 22: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field NetTcpRttMicrosecsP50", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.NetTcpRttMicrosecsP50 = &v2 - case 23: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field NetTcpRttMicrosecsP90", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.NetTcpRttMicrosecsP90 = &v2 - case 24: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field NetTcpRttMicrosecsP95", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.NetTcpRttMicrosecsP95 = &v2 - case 25: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field NetTcpRttMicrosecsP99", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.NetTcpRttMicrosecsP99 = &v2 - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy - } - } - return nil -} -func (m *ResourceUsage) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - 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) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SlaveId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.SlaveId == nil { - m.SlaveId = &SlaveID{} - } - if err := m.SlaveId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FrameworkId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.FrameworkId == nil { - m.FrameworkId = &FrameworkID{} - } - if err := m.FrameworkId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExecutorId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ExecutorId == nil { - m.ExecutorId = &ExecutorID{} - } - if err := m.ExecutorId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExecutorName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.ExecutorName = &s - index = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TaskId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TaskId == nil { - m.TaskId = &TaskID{} - } - if err := m.TaskId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Statistics", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Statistics == nil { - m.Statistics = &ResourceStatistics{} - } - if err := m.Statistics.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy - } - } - return nil -} -func (m *PerfStatistics) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - 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) - switch fieldNum { - case 1: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.Timestamp = &v2 - case 2: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.Duration = &v2 - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Cycles", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Cycles = &v - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field StalledCyclesFrontend", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.StalledCyclesFrontend = &v - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field StalledCyclesBackend", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.StalledCyclesBackend = &v - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Instructions", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Instructions = &v - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CacheReferences", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.CacheReferences = &v - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CacheMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.CacheMisses = &v - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Branches", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Branches = &v - case 10: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BranchMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.BranchMisses = &v - case 11: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BusCycles", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.BusCycles = &v - case 12: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RefCycles", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.RefCycles = &v - case 13: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field CpuClock", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.CpuClock = &v2 - case 14: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field TaskClock", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.TaskClock = &v2 - case 15: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field PageFaults", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.PageFaults = &v - case 16: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MinorFaults", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.MinorFaults = &v - case 17: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MajorFaults", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.MajorFaults = &v - case 18: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ContextSwitches", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.ContextSwitches = &v - case 19: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CpuMigrations", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.CpuMigrations = &v - case 20: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AlignmentFaults", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.AlignmentFaults = &v - case 21: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field EmulationFaults", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.EmulationFaults = &v - case 22: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field L1DcacheLoads", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.L1DcacheLoads = &v - case 23: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field L1DcacheLoadMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.L1DcacheLoadMisses = &v - case 24: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field L1DcacheStores", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.L1DcacheStores = &v - case 25: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field L1DcacheStoreMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.L1DcacheStoreMisses = &v - case 26: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field L1DcachePrefetches", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.L1DcachePrefetches = &v - case 27: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field L1DcachePrefetchMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.L1DcachePrefetchMisses = &v - case 28: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field L1IcacheLoads", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.L1IcacheLoads = &v - case 29: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field L1IcacheLoadMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.L1IcacheLoadMisses = &v - case 30: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field L1IcachePrefetches", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.L1IcachePrefetches = &v - case 31: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field L1IcachePrefetchMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.L1IcachePrefetchMisses = &v - case 32: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LlcLoads", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.LlcLoads = &v - case 33: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LlcLoadMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.LlcLoadMisses = &v - case 34: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LlcStores", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.LlcStores = &v - case 35: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LlcStoreMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.LlcStoreMisses = &v - case 36: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LlcPrefetches", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.LlcPrefetches = &v - case 37: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LlcPrefetchMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.LlcPrefetchMisses = &v - case 38: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DtlbLoads", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.DtlbLoads = &v - case 39: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DtlbLoadMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.DtlbLoadMisses = &v - case 40: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DtlbStores", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.DtlbStores = &v - case 41: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DtlbStoreMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.DtlbStoreMisses = &v - case 42: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DtlbPrefetches", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.DtlbPrefetches = &v - case 43: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DtlbPrefetchMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.DtlbPrefetchMisses = &v - case 44: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ItlbLoads", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.ItlbLoads = &v - case 45: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ItlbLoadMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.ItlbLoadMisses = &v - case 46: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BranchLoads", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.BranchLoads = &v - case 47: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BranchLoadMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.BranchLoadMisses = &v - case 48: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeLoads", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NodeLoads = &v - case 49: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeLoadMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NodeLoadMisses = &v - case 50: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeStores", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NodeStores = &v - case 51: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeStoreMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NodeStoreMisses = &v - case 52: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NodePrefetches", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NodePrefetches = &v - case 53: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NodePrefetchMisses", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NodePrefetchMisses = &v - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*CommandInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !this.Container.Equal(that1.Container) { + return false + } + if len(this.Uris) != len(that1.Uris) { + return false + } + for i := range this.Uris { + if !this.Uris[i].Equal(that1.Uris[i]) { + return false + } + } + if !this.Environment.Equal(that1.Environment) { + return false + } + if this.Shell != nil && that1.Shell != nil { + if *this.Shell != *that1.Shell { + return false + } + } else if this.Shell != nil { + return false + } else if that1.Shell != nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if len(this.Arguments) != len(that1.Arguments) { + return false + } + for i := range this.Arguments { + if this.Arguments[i] != that1.Arguments[i] { + return false + } + } + if this.User != nil && that1.User != nil { + if *this.User != *that1.User { + return false + } + } else if this.User != nil { + return false + } else if that1.User != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *CommandInfo_URI) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*CommandInfo_URI) + if !ok { + return fmt.Errorf("that is not of type *CommandInfo_URI") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *CommandInfo_URI but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *CommandInfo_URIbut is not nil && this == nil") + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if this.Executable != nil && that1.Executable != nil { + if *this.Executable != *that1.Executable { + return fmt.Errorf("Executable this(%v) Not Equal that(%v)", *this.Executable, *that1.Executable) + } + } else if this.Executable != nil { + return fmt.Errorf("this.Executable == nil && that.Executable != nil") + } else if that1.Executable != nil { + return fmt.Errorf("Executable this(%v) Not Equal that(%v)", this.Executable, that1.Executable) + } + if this.Extract != nil && that1.Extract != nil { + if *this.Extract != *that1.Extract { + return fmt.Errorf("Extract this(%v) Not Equal that(%v)", *this.Extract, *that1.Extract) + } + } else if this.Extract != nil { + return fmt.Errorf("this.Extract == nil && that.Extract != nil") + } else if that1.Extract != nil { + return fmt.Errorf("Extract this(%v) Not Equal that(%v)", this.Extract, that1.Extract) + } + if this.Cache != nil && that1.Cache != nil { + if *this.Cache != *that1.Cache { + return fmt.Errorf("Cache this(%v) Not Equal that(%v)", *this.Cache, *that1.Cache) + } + } else if this.Cache != nil { + return fmt.Errorf("this.Cache == nil && that.Cache != nil") + } else if that1.Cache != nil { + return fmt.Errorf("Cache this(%v) Not Equal that(%v)", this.Cache, that1.Cache) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *CommandInfo_URI) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*CommandInfo_URI) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if this.Executable != nil && that1.Executable != nil { + if *this.Executable != *that1.Executable { + return false + } + } else if this.Executable != nil { + return false + } else if that1.Executable != nil { + return false + } + if this.Extract != nil && that1.Extract != nil { + if *this.Extract != *that1.Extract { + return false + } + } else if this.Extract != nil { + return false + } else if that1.Extract != nil { + return false + } + if this.Cache != nil && that1.Cache != nil { + if *this.Cache != *that1.Cache { + return false + } + } else if this.Cache != nil { + return false + } else if that1.Cache != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *CommandInfo_ContainerInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*CommandInfo_ContainerInfo) + if !ok { + return fmt.Errorf("that is not of type *CommandInfo_ContainerInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *CommandInfo_ContainerInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *CommandInfo_ContainerInfobut is not nil && this == nil") + } + if this.Image != nil && that1.Image != nil { + if *this.Image != *that1.Image { + return fmt.Errorf("Image this(%v) Not Equal that(%v)", *this.Image, *that1.Image) + } + } else if this.Image != nil { + return fmt.Errorf("this.Image == nil && that.Image != nil") + } else if that1.Image != nil { + return fmt.Errorf("Image this(%v) Not Equal that(%v)", this.Image, that1.Image) + } + if len(this.Options) != len(that1.Options) { + return fmt.Errorf("Options this(%v) Not Equal that(%v)", len(this.Options), len(that1.Options)) + } + for i := range this.Options { + if this.Options[i] != that1.Options[i] { + return fmt.Errorf("Options this[%v](%v) Not Equal that[%v](%v)", i, this.Options[i], i, that1.Options[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *CommandInfo_ContainerInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*CommandInfo_ContainerInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Image != nil && that1.Image != nil { + if *this.Image != *that1.Image { + return false + } + } else if this.Image != nil { + return false + } else if that1.Image != nil { + return false + } + if len(this.Options) != len(that1.Options) { + return false + } + for i := range this.Options { + if this.Options[i] != that1.Options[i] { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *ExecutorInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ExecutorInfo) + if !ok { + return fmt.Errorf("that is not of type *ExecutorInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ExecutorInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ExecutorInfobut is not nil && this == nil") + } + if !this.ExecutorId.Equal(that1.ExecutorId) { + return fmt.Errorf("ExecutorId this(%v) Not Equal that(%v)", this.ExecutorId, that1.ExecutorId) + } + if !this.FrameworkId.Equal(that1.FrameworkId) { + return fmt.Errorf("FrameworkId this(%v) Not Equal that(%v)", this.FrameworkId, that1.FrameworkId) + } + if !this.Command.Equal(that1.Command) { + return fmt.Errorf("Command this(%v) Not Equal that(%v)", this.Command, that1.Command) + } + if !this.Container.Equal(that1.Container) { + return fmt.Errorf("Container this(%v) Not Equal that(%v)", this.Container, that1.Container) + } + if len(this.Resources) != len(that1.Resources) { + return fmt.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return fmt.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) + } + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) + } + } else if this.Name != nil { + return fmt.Errorf("this.Name == nil && that.Name != nil") + } else if that1.Name != nil { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + } + if this.Source != nil && that1.Source != nil { + if *this.Source != *that1.Source { + return fmt.Errorf("Source this(%v) Not Equal that(%v)", *this.Source, *that1.Source) + } + } else if this.Source != nil { + return fmt.Errorf("this.Source == nil && that.Source != nil") + } else if that1.Source != nil { + return fmt.Errorf("Source this(%v) Not Equal that(%v)", this.Source, that1.Source) + } + if !bytes.Equal(this.Data, that1.Data) { + return fmt.Errorf("Data this(%v) Not Equal that(%v)", this.Data, that1.Data) + } + if !this.Discovery.Equal(that1.Discovery) { + return fmt.Errorf("Discovery this(%v) Not Equal that(%v)", this.Discovery, that1.Discovery) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *ExecutorInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*ExecutorInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !this.ExecutorId.Equal(that1.ExecutorId) { + return false + } + if !this.FrameworkId.Equal(that1.FrameworkId) { + return false + } + if !this.Command.Equal(that1.Command) { + return false + } + if !this.Container.Equal(that1.Container) { + return false + } + if len(this.Resources) != len(that1.Resources) { + return false + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return false + } + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return false + } + } else if this.Name != nil { + return false + } else if that1.Name != nil { + return false + } + if this.Source != nil && that1.Source != nil { + if *this.Source != *that1.Source { + return false + } + } else if this.Source != nil { + return false + } else if that1.Source != nil { + return false + } + if !bytes.Equal(this.Data, that1.Data) { + return false + } + if !this.Discovery.Equal(that1.Discovery) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *MasterInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*MasterInfo) + if !ok { + return fmt.Errorf("that is not of type *MasterInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *MasterInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *MasterInfobut is not nil && this == nil") + } + if this.Id != nil && that1.Id != nil { + if *this.Id != *that1.Id { + return fmt.Errorf("Id this(%v) Not Equal that(%v)", *this.Id, *that1.Id) + } + } else if this.Id != nil { + return fmt.Errorf("this.Id == nil && that.Id != nil") + } else if that1.Id != nil { + return fmt.Errorf("Id this(%v) Not Equal that(%v)", this.Id, that1.Id) + } + if this.Ip != nil && that1.Ip != nil { + if *this.Ip != *that1.Ip { + return fmt.Errorf("Ip this(%v) Not Equal that(%v)", *this.Ip, *that1.Ip) + } + } else if this.Ip != nil { + return fmt.Errorf("this.Ip == nil && that.Ip != nil") + } else if that1.Ip != nil { + return fmt.Errorf("Ip this(%v) Not Equal that(%v)", this.Ip, that1.Ip) + } + if this.Port != nil && that1.Port != nil { + if *this.Port != *that1.Port { + return fmt.Errorf("Port this(%v) Not Equal that(%v)", *this.Port, *that1.Port) + } + } else if this.Port != nil { + return fmt.Errorf("this.Port == nil && that.Port != nil") + } else if that1.Port != nil { + return fmt.Errorf("Port this(%v) Not Equal that(%v)", this.Port, that1.Port) + } + if this.Pid != nil && that1.Pid != nil { + if *this.Pid != *that1.Pid { + return fmt.Errorf("Pid this(%v) Not Equal that(%v)", *this.Pid, *that1.Pid) + } + } else if this.Pid != nil { + return fmt.Errorf("this.Pid == nil && that.Pid != nil") + } else if that1.Pid != nil { + return fmt.Errorf("Pid this(%v) Not Equal that(%v)", this.Pid, that1.Pid) + } + if this.Hostname != nil && that1.Hostname != nil { + if *this.Hostname != *that1.Hostname { + return fmt.Errorf("Hostname this(%v) Not Equal that(%v)", *this.Hostname, *that1.Hostname) + } + } else if this.Hostname != nil { + return fmt.Errorf("this.Hostname == nil && that.Hostname != nil") + } else if that1.Hostname != nil { + return fmt.Errorf("Hostname this(%v) Not Equal that(%v)", this.Hostname, that1.Hostname) + } + if this.Version != nil && that1.Version != nil { + if *this.Version != *that1.Version { + return fmt.Errorf("Version this(%v) Not Equal that(%v)", *this.Version, *that1.Version) + } + } else if this.Version != nil { + return fmt.Errorf("this.Version == nil && that.Version != nil") + } else if that1.Version != nil { + return fmt.Errorf("Version this(%v) Not Equal that(%v)", this.Version, that1.Version) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *MasterInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*MasterInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Id != nil && that1.Id != nil { + if *this.Id != *that1.Id { + return false + } + } else if this.Id != nil { + return false + } else if that1.Id != nil { + return false + } + if this.Ip != nil && that1.Ip != nil { + if *this.Ip != *that1.Ip { + return false + } + } else if this.Ip != nil { + return false + } else if that1.Ip != nil { + return false + } + if this.Port != nil && that1.Port != nil { + if *this.Port != *that1.Port { + return false + } + } else if this.Port != nil { + return false + } else if that1.Port != nil { + return false + } + if this.Pid != nil && that1.Pid != nil { + if *this.Pid != *that1.Pid { + return false + } + } else if this.Pid != nil { + return false + } else if that1.Pid != nil { + return false + } + if this.Hostname != nil && that1.Hostname != nil { + if *this.Hostname != *that1.Hostname { + return false + } + } else if this.Hostname != nil { + return false + } else if that1.Hostname != nil { + return false + } + if this.Version != nil && that1.Version != nil { + if *this.Version != *that1.Version { + return false + } + } else if this.Version != nil { + return false + } else if that1.Version != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *SlaveInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*SlaveInfo) + if !ok { + return fmt.Errorf("that is not of type *SlaveInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *SlaveInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *SlaveInfobut is not nil && this == nil") + } + if this.Hostname != nil && that1.Hostname != nil { + if *this.Hostname != *that1.Hostname { + return fmt.Errorf("Hostname this(%v) Not Equal that(%v)", *this.Hostname, *that1.Hostname) + } + } else if this.Hostname != nil { + return fmt.Errorf("this.Hostname == nil && that.Hostname != nil") + } else if that1.Hostname != nil { + return fmt.Errorf("Hostname this(%v) Not Equal that(%v)", this.Hostname, that1.Hostname) + } + if this.Port != nil && that1.Port != nil { + if *this.Port != *that1.Port { + return fmt.Errorf("Port this(%v) Not Equal that(%v)", *this.Port, *that1.Port) + } + } else if this.Port != nil { + return fmt.Errorf("this.Port == nil && that.Port != nil") + } else if that1.Port != nil { + return fmt.Errorf("Port this(%v) Not Equal that(%v)", this.Port, that1.Port) + } + if len(this.Resources) != len(that1.Resources) { + return fmt.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return fmt.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) + } + } + if len(this.Attributes) != len(that1.Attributes) { + return fmt.Errorf("Attributes this(%v) Not Equal that(%v)", len(this.Attributes), len(that1.Attributes)) + } + for i := range this.Attributes { + if !this.Attributes[i].Equal(that1.Attributes[i]) { + return fmt.Errorf("Attributes this[%v](%v) Not Equal that[%v](%v)", i, this.Attributes[i], i, that1.Attributes[i]) + } + } + if !this.Id.Equal(that1.Id) { + return fmt.Errorf("Id this(%v) Not Equal that(%v)", this.Id, that1.Id) + } + if this.Checkpoint != nil && that1.Checkpoint != nil { + if *this.Checkpoint != *that1.Checkpoint { + return fmt.Errorf("Checkpoint this(%v) Not Equal that(%v)", *this.Checkpoint, *that1.Checkpoint) + } + } else if this.Checkpoint != nil { + return fmt.Errorf("this.Checkpoint == nil && that.Checkpoint != nil") + } else if that1.Checkpoint != nil { + return fmt.Errorf("Checkpoint this(%v) Not Equal that(%v)", this.Checkpoint, that1.Checkpoint) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *SlaveInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*SlaveInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Hostname != nil && that1.Hostname != nil { + if *this.Hostname != *that1.Hostname { + return false + } + } else if this.Hostname != nil { + return false + } else if that1.Hostname != nil { + return false + } + if this.Port != nil && that1.Port != nil { + if *this.Port != *that1.Port { + return false + } + } else if this.Port != nil { + return false + } else if that1.Port != nil { + return false + } + if len(this.Resources) != len(that1.Resources) { + return false + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return false + } + } + if len(this.Attributes) != len(that1.Attributes) { + return false + } + for i := range this.Attributes { + if !this.Attributes[i].Equal(that1.Attributes[i]) { + return false + } + } + if !this.Id.Equal(that1.Id) { + return false + } + if this.Checkpoint != nil && that1.Checkpoint != nil { + if *this.Checkpoint != *that1.Checkpoint { + return false + } + } else if this.Checkpoint != nil { + return false + } else if that1.Checkpoint != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Value) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Value) + if !ok { + return fmt.Errorf("that is not of type *Value") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Value but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Valuebut is not nil && this == nil") + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) + } + } else if this.Type != nil { + return fmt.Errorf("this.Type == nil && that.Type != nil") + } else if that1.Type != nil { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + } + if !this.Scalar.Equal(that1.Scalar) { + return fmt.Errorf("Scalar this(%v) Not Equal that(%v)", this.Scalar, that1.Scalar) + } + if !this.Ranges.Equal(that1.Ranges) { + return fmt.Errorf("Ranges this(%v) Not Equal that(%v)", this.Ranges, that1.Ranges) + } + if !this.Set.Equal(that1.Set) { + return fmt.Errorf("Set this(%v) Not Equal that(%v)", this.Set, that1.Set) + } + if !this.Text.Equal(that1.Text) { + return fmt.Errorf("Text this(%v) Not Equal that(%v)", this.Text, that1.Text) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Value) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Value) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return false + } + } else if this.Type != nil { + return false + } else if that1.Type != nil { + return false + } + if !this.Scalar.Equal(that1.Scalar) { + return false + } + if !this.Ranges.Equal(that1.Ranges) { + return false + } + if !this.Set.Equal(that1.Set) { + return false + } + if !this.Text.Equal(that1.Text) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Value_Scalar) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Value_Scalar) + if !ok { + return fmt.Errorf("that is not of type *Value_Scalar") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Value_Scalar but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Value_Scalarbut is not nil && this == nil") + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Value_Scalar) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Value_Scalar) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Value_Range) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Value_Range) + if !ok { + return fmt.Errorf("that is not of type *Value_Range") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Value_Range but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Value_Rangebut is not nil && this == nil") + } + if this.Begin != nil && that1.Begin != nil { + if *this.Begin != *that1.Begin { + return fmt.Errorf("Begin this(%v) Not Equal that(%v)", *this.Begin, *that1.Begin) + } + } else if this.Begin != nil { + return fmt.Errorf("this.Begin == nil && that.Begin != nil") + } else if that1.Begin != nil { + return fmt.Errorf("Begin this(%v) Not Equal that(%v)", this.Begin, that1.Begin) + } + if this.End != nil && that1.End != nil { + if *this.End != *that1.End { + return fmt.Errorf("End this(%v) Not Equal that(%v)", *this.End, *that1.End) + } + } else if this.End != nil { + return fmt.Errorf("this.End == nil && that.End != nil") + } else if that1.End != nil { + return fmt.Errorf("End this(%v) Not Equal that(%v)", this.End, that1.End) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Value_Range) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Value_Range) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Begin != nil && that1.Begin != nil { + if *this.Begin != *that1.Begin { + return false + } + } else if this.Begin != nil { + return false + } else if that1.Begin != nil { + return false + } + if this.End != nil && that1.End != nil { + if *this.End != *that1.End { + return false + } + } else if this.End != nil { + return false + } else if that1.End != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Value_Ranges) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Value_Ranges) + if !ok { + return fmt.Errorf("that is not of type *Value_Ranges") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Value_Ranges but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Value_Rangesbut is not nil && this == nil") + } + if len(this.Range) != len(that1.Range) { + return fmt.Errorf("Range this(%v) Not Equal that(%v)", len(this.Range), len(that1.Range)) + } + for i := range this.Range { + if !this.Range[i].Equal(that1.Range[i]) { + return fmt.Errorf("Range this[%v](%v) Not Equal that[%v](%v)", i, this.Range[i], i, that1.Range[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Value_Ranges) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Value_Ranges) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.Range) != len(that1.Range) { + return false + } + for i := range this.Range { + if !this.Range[i].Equal(that1.Range[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Value_Set) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Value_Set) + if !ok { + return fmt.Errorf("that is not of type *Value_Set") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Value_Set but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Value_Setbut is not nil && this == nil") + } + if len(this.Item) != len(that1.Item) { + return fmt.Errorf("Item this(%v) Not Equal that(%v)", len(this.Item), len(that1.Item)) + } + for i := range this.Item { + if this.Item[i] != that1.Item[i] { + return fmt.Errorf("Item this[%v](%v) Not Equal that[%v](%v)", i, this.Item[i], i, that1.Item[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Value_Set) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Value_Set) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.Item) != len(that1.Item) { + return false + } + for i := range this.Item { + if this.Item[i] != that1.Item[i] { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Value_Text) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Value_Text) + if !ok { + return fmt.Errorf("that is not of type *Value_Text") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Value_Text but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Value_Textbut is not nil && this == nil") + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Value_Text) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Value_Text) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Attribute) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Attribute) + if !ok { + return fmt.Errorf("that is not of type *Attribute") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Attribute but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Attributebut is not nil && this == nil") + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) + } + } else if this.Name != nil { + return fmt.Errorf("this.Name == nil && that.Name != nil") + } else if that1.Name != nil { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) + } + } else if this.Type != nil { + return fmt.Errorf("this.Type == nil && that.Type != nil") + } else if that1.Type != nil { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + } + if !this.Scalar.Equal(that1.Scalar) { + return fmt.Errorf("Scalar this(%v) Not Equal that(%v)", this.Scalar, that1.Scalar) + } + if !this.Ranges.Equal(that1.Ranges) { + return fmt.Errorf("Ranges this(%v) Not Equal that(%v)", this.Ranges, that1.Ranges) + } + if !this.Set.Equal(that1.Set) { + return fmt.Errorf("Set this(%v) Not Equal that(%v)", this.Set, that1.Set) + } + if !this.Text.Equal(that1.Text) { + return fmt.Errorf("Text this(%v) Not Equal that(%v)", this.Text, that1.Text) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Attribute) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Attribute) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return false + } + } else if this.Name != nil { + return false + } else if that1.Name != nil { + return false + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return false + } + } else if this.Type != nil { + return false + } else if that1.Type != nil { + return false + } + if !this.Scalar.Equal(that1.Scalar) { + return false + } + if !this.Ranges.Equal(that1.Ranges) { + return false + } + if !this.Set.Equal(that1.Set) { + return false + } + if !this.Text.Equal(that1.Text) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Resource) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Resource) + if !ok { + return fmt.Errorf("that is not of type *Resource") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Resource but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Resourcebut is not nil && this == nil") + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) + } + } else if this.Name != nil { + return fmt.Errorf("this.Name == nil && that.Name != nil") + } else if that1.Name != nil { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) + } + } else if this.Type != nil { + return fmt.Errorf("this.Type == nil && that.Type != nil") + } else if that1.Type != nil { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + } + if !this.Scalar.Equal(that1.Scalar) { + return fmt.Errorf("Scalar this(%v) Not Equal that(%v)", this.Scalar, that1.Scalar) + } + if !this.Ranges.Equal(that1.Ranges) { + return fmt.Errorf("Ranges this(%v) Not Equal that(%v)", this.Ranges, that1.Ranges) + } + if !this.Set.Equal(that1.Set) { + return fmt.Errorf("Set this(%v) Not Equal that(%v)", this.Set, that1.Set) + } + if this.Role != nil && that1.Role != nil { + if *this.Role != *that1.Role { + return fmt.Errorf("Role this(%v) Not Equal that(%v)", *this.Role, *that1.Role) + } + } else if this.Role != nil { + return fmt.Errorf("this.Role == nil && that.Role != nil") + } else if that1.Role != nil { + return fmt.Errorf("Role this(%v) Not Equal that(%v)", this.Role, that1.Role) + } + if !this.Reservation.Equal(that1.Reservation) { + return fmt.Errorf("Reservation this(%v) Not Equal that(%v)", this.Reservation, that1.Reservation) + } + if !this.Disk.Equal(that1.Disk) { + return fmt.Errorf("Disk this(%v) Not Equal that(%v)", this.Disk, that1.Disk) + } + if !this.Revocable.Equal(that1.Revocable) { + return fmt.Errorf("Revocable this(%v) Not Equal that(%v)", this.Revocable, that1.Revocable) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Resource) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Resource) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return false + } + } else if this.Name != nil { + return false + } else if that1.Name != nil { + return false + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return false + } + } else if this.Type != nil { + return false + } else if that1.Type != nil { + return false + } + if !this.Scalar.Equal(that1.Scalar) { + return false + } + if !this.Ranges.Equal(that1.Ranges) { + return false + } + if !this.Set.Equal(that1.Set) { + return false + } + if this.Role != nil && that1.Role != nil { + if *this.Role != *that1.Role { + return false + } + } else if this.Role != nil { + return false + } else if that1.Role != nil { + return false + } + if !this.Reservation.Equal(that1.Reservation) { + return false + } + if !this.Disk.Equal(that1.Disk) { + return false + } + if !this.Revocable.Equal(that1.Revocable) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Resource_ReservationInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Resource_ReservationInfo) + if !ok { + return fmt.Errorf("that is not of type *Resource_ReservationInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Resource_ReservationInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Resource_ReservationInfobut is not nil && this == nil") + } + if this.Principal != nil && that1.Principal != nil { + if *this.Principal != *that1.Principal { + return fmt.Errorf("Principal this(%v) Not Equal that(%v)", *this.Principal, *that1.Principal) + } + } else if this.Principal != nil { + return fmt.Errorf("this.Principal == nil && that.Principal != nil") + } else if that1.Principal != nil { + return fmt.Errorf("Principal this(%v) Not Equal that(%v)", this.Principal, that1.Principal) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Resource_ReservationInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Resource_ReservationInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Principal != nil && that1.Principal != nil { + if *this.Principal != *that1.Principal { + return false + } + } else if this.Principal != nil { + return false + } else if that1.Principal != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Resource_DiskInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Resource_DiskInfo) + if !ok { + return fmt.Errorf("that is not of type *Resource_DiskInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Resource_DiskInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Resource_DiskInfobut is not nil && this == nil") + } + if !this.Persistence.Equal(that1.Persistence) { + return fmt.Errorf("Persistence this(%v) Not Equal that(%v)", this.Persistence, that1.Persistence) + } + if !this.Volume.Equal(that1.Volume) { + return fmt.Errorf("Volume this(%v) Not Equal that(%v)", this.Volume, that1.Volume) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Resource_DiskInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Resource_DiskInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !this.Persistence.Equal(that1.Persistence) { + return false + } + if !this.Volume.Equal(that1.Volume) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Resource_DiskInfo_Persistence) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Resource_DiskInfo_Persistence) + if !ok { + return fmt.Errorf("that is not of type *Resource_DiskInfo_Persistence") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Resource_DiskInfo_Persistence but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Resource_DiskInfo_Persistencebut is not nil && this == nil") + } + if this.Id != nil && that1.Id != nil { + if *this.Id != *that1.Id { + return fmt.Errorf("Id this(%v) Not Equal that(%v)", *this.Id, *that1.Id) + } + } else if this.Id != nil { + return fmt.Errorf("this.Id == nil && that.Id != nil") + } else if that1.Id != nil { + return fmt.Errorf("Id this(%v) Not Equal that(%v)", this.Id, that1.Id) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Resource_DiskInfo_Persistence) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Resource_DiskInfo_Persistence) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Id != nil && that1.Id != nil { + if *this.Id != *that1.Id { + return false + } + } else if this.Id != nil { + return false + } else if that1.Id != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Resource_RevocableInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Resource_RevocableInfo) + if !ok { + return fmt.Errorf("that is not of type *Resource_RevocableInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Resource_RevocableInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Resource_RevocableInfobut is not nil && this == nil") + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Resource_RevocableInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Resource_RevocableInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *TrafficControlStatistics) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*TrafficControlStatistics) + if !ok { + return fmt.Errorf("that is not of type *TrafficControlStatistics") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *TrafficControlStatistics but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *TrafficControlStatisticsbut is not nil && this == nil") + } + if this.Id != nil && that1.Id != nil { + if *this.Id != *that1.Id { + return fmt.Errorf("Id this(%v) Not Equal that(%v)", *this.Id, *that1.Id) + } + } else if this.Id != nil { + return fmt.Errorf("this.Id == nil && that.Id != nil") + } else if that1.Id != nil { + return fmt.Errorf("Id this(%v) Not Equal that(%v)", this.Id, that1.Id) + } + if this.Backlog != nil && that1.Backlog != nil { + if *this.Backlog != *that1.Backlog { + return fmt.Errorf("Backlog this(%v) Not Equal that(%v)", *this.Backlog, *that1.Backlog) + } + } else if this.Backlog != nil { + return fmt.Errorf("this.Backlog == nil && that.Backlog != nil") + } else if that1.Backlog != nil { + return fmt.Errorf("Backlog this(%v) Not Equal that(%v)", this.Backlog, that1.Backlog) + } + if this.Bytes != nil && that1.Bytes != nil { + if *this.Bytes != *that1.Bytes { + return fmt.Errorf("Bytes this(%v) Not Equal that(%v)", *this.Bytes, *that1.Bytes) + } + } else if this.Bytes != nil { + return fmt.Errorf("this.Bytes == nil && that.Bytes != nil") + } else if that1.Bytes != nil { + return fmt.Errorf("Bytes this(%v) Not Equal that(%v)", this.Bytes, that1.Bytes) + } + if this.Drops != nil && that1.Drops != nil { + if *this.Drops != *that1.Drops { + return fmt.Errorf("Drops this(%v) Not Equal that(%v)", *this.Drops, *that1.Drops) + } + } else if this.Drops != nil { + return fmt.Errorf("this.Drops == nil && that.Drops != nil") + } else if that1.Drops != nil { + return fmt.Errorf("Drops this(%v) Not Equal that(%v)", this.Drops, that1.Drops) + } + if this.Overlimits != nil && that1.Overlimits != nil { + if *this.Overlimits != *that1.Overlimits { + return fmt.Errorf("Overlimits this(%v) Not Equal that(%v)", *this.Overlimits, *that1.Overlimits) + } + } else if this.Overlimits != nil { + return fmt.Errorf("this.Overlimits == nil && that.Overlimits != nil") + } else if that1.Overlimits != nil { + return fmt.Errorf("Overlimits this(%v) Not Equal that(%v)", this.Overlimits, that1.Overlimits) + } + if this.Packets != nil && that1.Packets != nil { + if *this.Packets != *that1.Packets { + return fmt.Errorf("Packets this(%v) Not Equal that(%v)", *this.Packets, *that1.Packets) + } + } else if this.Packets != nil { + return fmt.Errorf("this.Packets == nil && that.Packets != nil") + } else if that1.Packets != nil { + return fmt.Errorf("Packets this(%v) Not Equal that(%v)", this.Packets, that1.Packets) + } + if this.Qlen != nil && that1.Qlen != nil { + if *this.Qlen != *that1.Qlen { + return fmt.Errorf("Qlen this(%v) Not Equal that(%v)", *this.Qlen, *that1.Qlen) + } + } else if this.Qlen != nil { + return fmt.Errorf("this.Qlen == nil && that.Qlen != nil") + } else if that1.Qlen != nil { + return fmt.Errorf("Qlen this(%v) Not Equal that(%v)", this.Qlen, that1.Qlen) + } + if this.Ratebps != nil && that1.Ratebps != nil { + if *this.Ratebps != *that1.Ratebps { + return fmt.Errorf("Ratebps this(%v) Not Equal that(%v)", *this.Ratebps, *that1.Ratebps) + } + } else if this.Ratebps != nil { + return fmt.Errorf("this.Ratebps == nil && that.Ratebps != nil") + } else if that1.Ratebps != nil { + return fmt.Errorf("Ratebps this(%v) Not Equal that(%v)", this.Ratebps, that1.Ratebps) + } + if this.Ratepps != nil && that1.Ratepps != nil { + if *this.Ratepps != *that1.Ratepps { + return fmt.Errorf("Ratepps this(%v) Not Equal that(%v)", *this.Ratepps, *that1.Ratepps) + } + } else if this.Ratepps != nil { + return fmt.Errorf("this.Ratepps == nil && that.Ratepps != nil") + } else if that1.Ratepps != nil { + return fmt.Errorf("Ratepps this(%v) Not Equal that(%v)", this.Ratepps, that1.Ratepps) + } + if this.Requeues != nil && that1.Requeues != nil { + if *this.Requeues != *that1.Requeues { + return fmt.Errorf("Requeues this(%v) Not Equal that(%v)", *this.Requeues, *that1.Requeues) + } + } else if this.Requeues != nil { + return fmt.Errorf("this.Requeues == nil && that.Requeues != nil") + } else if that1.Requeues != nil { + return fmt.Errorf("Requeues this(%v) Not Equal that(%v)", this.Requeues, that1.Requeues) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *TrafficControlStatistics) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*TrafficControlStatistics) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Id != nil && that1.Id != nil { + if *this.Id != *that1.Id { + return false + } + } else if this.Id != nil { + return false + } else if that1.Id != nil { + return false + } + if this.Backlog != nil && that1.Backlog != nil { + if *this.Backlog != *that1.Backlog { + return false + } + } else if this.Backlog != nil { + return false + } else if that1.Backlog != nil { + return false + } + if this.Bytes != nil && that1.Bytes != nil { + if *this.Bytes != *that1.Bytes { + return false + } + } else if this.Bytes != nil { + return false + } else if that1.Bytes != nil { + return false + } + if this.Drops != nil && that1.Drops != nil { + if *this.Drops != *that1.Drops { + return false + } + } else if this.Drops != nil { + return false + } else if that1.Drops != nil { + return false + } + if this.Overlimits != nil && that1.Overlimits != nil { + if *this.Overlimits != *that1.Overlimits { + return false + } + } else if this.Overlimits != nil { + return false + } else if that1.Overlimits != nil { + return false + } + if this.Packets != nil && that1.Packets != nil { + if *this.Packets != *that1.Packets { + return false + } + } else if this.Packets != nil { + return false + } else if that1.Packets != nil { + return false + } + if this.Qlen != nil && that1.Qlen != nil { + if *this.Qlen != *that1.Qlen { + return false + } + } else if this.Qlen != nil { + return false + } else if that1.Qlen != nil { + return false + } + if this.Ratebps != nil && that1.Ratebps != nil { + if *this.Ratebps != *that1.Ratebps { + return false + } + } else if this.Ratebps != nil { + return false + } else if that1.Ratebps != nil { + return false + } + if this.Ratepps != nil && that1.Ratepps != nil { + if *this.Ratepps != *that1.Ratepps { + return false + } + } else if this.Ratepps != nil { + return false + } else if that1.Ratepps != nil { + return false + } + if this.Requeues != nil && that1.Requeues != nil { + if *this.Requeues != *that1.Requeues { + return false + } + } else if this.Requeues != nil { + return false + } else if that1.Requeues != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *ResourceStatistics) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ResourceStatistics) + if !ok { + return fmt.Errorf("that is not of type *ResourceStatistics") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ResourceStatistics but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ResourceStatisticsbut is not nil && this == nil") + } + if this.Timestamp != nil && that1.Timestamp != nil { + if *this.Timestamp != *that1.Timestamp { + return fmt.Errorf("Timestamp this(%v) Not Equal that(%v)", *this.Timestamp, *that1.Timestamp) + } + } else if this.Timestamp != nil { + return fmt.Errorf("this.Timestamp == nil && that.Timestamp != nil") + } else if that1.Timestamp != nil { + return fmt.Errorf("Timestamp this(%v) Not Equal that(%v)", this.Timestamp, that1.Timestamp) + } + if this.Processes != nil && that1.Processes != nil { + if *this.Processes != *that1.Processes { + return fmt.Errorf("Processes this(%v) Not Equal that(%v)", *this.Processes, *that1.Processes) + } + } else if this.Processes != nil { + return fmt.Errorf("this.Processes == nil && that.Processes != nil") + } else if that1.Processes != nil { + return fmt.Errorf("Processes this(%v) Not Equal that(%v)", this.Processes, that1.Processes) + } + if this.Threads != nil && that1.Threads != nil { + if *this.Threads != *that1.Threads { + return fmt.Errorf("Threads this(%v) Not Equal that(%v)", *this.Threads, *that1.Threads) + } + } else if this.Threads != nil { + return fmt.Errorf("this.Threads == nil && that.Threads != nil") + } else if that1.Threads != nil { + return fmt.Errorf("Threads this(%v) Not Equal that(%v)", this.Threads, that1.Threads) + } + if this.CpusUserTimeSecs != nil && that1.CpusUserTimeSecs != nil { + if *this.CpusUserTimeSecs != *that1.CpusUserTimeSecs { + return fmt.Errorf("CpusUserTimeSecs this(%v) Not Equal that(%v)", *this.CpusUserTimeSecs, *that1.CpusUserTimeSecs) + } + } else if this.CpusUserTimeSecs != nil { + return fmt.Errorf("this.CpusUserTimeSecs == nil && that.CpusUserTimeSecs != nil") + } else if that1.CpusUserTimeSecs != nil { + return fmt.Errorf("CpusUserTimeSecs this(%v) Not Equal that(%v)", this.CpusUserTimeSecs, that1.CpusUserTimeSecs) + } + if this.CpusSystemTimeSecs != nil && that1.CpusSystemTimeSecs != nil { + if *this.CpusSystemTimeSecs != *that1.CpusSystemTimeSecs { + return fmt.Errorf("CpusSystemTimeSecs this(%v) Not Equal that(%v)", *this.CpusSystemTimeSecs, *that1.CpusSystemTimeSecs) + } + } else if this.CpusSystemTimeSecs != nil { + return fmt.Errorf("this.CpusSystemTimeSecs == nil && that.CpusSystemTimeSecs != nil") + } else if that1.CpusSystemTimeSecs != nil { + return fmt.Errorf("CpusSystemTimeSecs this(%v) Not Equal that(%v)", this.CpusSystemTimeSecs, that1.CpusSystemTimeSecs) + } + if this.CpusLimit != nil && that1.CpusLimit != nil { + if *this.CpusLimit != *that1.CpusLimit { + return fmt.Errorf("CpusLimit this(%v) Not Equal that(%v)", *this.CpusLimit, *that1.CpusLimit) + } + } else if this.CpusLimit != nil { + return fmt.Errorf("this.CpusLimit == nil && that.CpusLimit != nil") + } else if that1.CpusLimit != nil { + return fmt.Errorf("CpusLimit this(%v) Not Equal that(%v)", this.CpusLimit, that1.CpusLimit) + } + if this.CpusNrPeriods != nil && that1.CpusNrPeriods != nil { + if *this.CpusNrPeriods != *that1.CpusNrPeriods { + return fmt.Errorf("CpusNrPeriods this(%v) Not Equal that(%v)", *this.CpusNrPeriods, *that1.CpusNrPeriods) + } + } else if this.CpusNrPeriods != nil { + return fmt.Errorf("this.CpusNrPeriods == nil && that.CpusNrPeriods != nil") + } else if that1.CpusNrPeriods != nil { + return fmt.Errorf("CpusNrPeriods this(%v) Not Equal that(%v)", this.CpusNrPeriods, that1.CpusNrPeriods) + } + if this.CpusNrThrottled != nil && that1.CpusNrThrottled != nil { + if *this.CpusNrThrottled != *that1.CpusNrThrottled { + return fmt.Errorf("CpusNrThrottled this(%v) Not Equal that(%v)", *this.CpusNrThrottled, *that1.CpusNrThrottled) + } + } else if this.CpusNrThrottled != nil { + return fmt.Errorf("this.CpusNrThrottled == nil && that.CpusNrThrottled != nil") + } else if that1.CpusNrThrottled != nil { + return fmt.Errorf("CpusNrThrottled this(%v) Not Equal that(%v)", this.CpusNrThrottled, that1.CpusNrThrottled) + } + if this.CpusThrottledTimeSecs != nil && that1.CpusThrottledTimeSecs != nil { + if *this.CpusThrottledTimeSecs != *that1.CpusThrottledTimeSecs { + return fmt.Errorf("CpusThrottledTimeSecs this(%v) Not Equal that(%v)", *this.CpusThrottledTimeSecs, *that1.CpusThrottledTimeSecs) + } + } else if this.CpusThrottledTimeSecs != nil { + return fmt.Errorf("this.CpusThrottledTimeSecs == nil && that.CpusThrottledTimeSecs != nil") + } else if that1.CpusThrottledTimeSecs != nil { + return fmt.Errorf("CpusThrottledTimeSecs this(%v) Not Equal that(%v)", this.CpusThrottledTimeSecs, that1.CpusThrottledTimeSecs) + } + if this.MemTotalBytes != nil && that1.MemTotalBytes != nil { + if *this.MemTotalBytes != *that1.MemTotalBytes { + return fmt.Errorf("MemTotalBytes this(%v) Not Equal that(%v)", *this.MemTotalBytes, *that1.MemTotalBytes) + } + } else if this.MemTotalBytes != nil { + return fmt.Errorf("this.MemTotalBytes == nil && that.MemTotalBytes != nil") + } else if that1.MemTotalBytes != nil { + return fmt.Errorf("MemTotalBytes this(%v) Not Equal that(%v)", this.MemTotalBytes, that1.MemTotalBytes) + } + if this.MemTotalMemswBytes != nil && that1.MemTotalMemswBytes != nil { + if *this.MemTotalMemswBytes != *that1.MemTotalMemswBytes { + return fmt.Errorf("MemTotalMemswBytes this(%v) Not Equal that(%v)", *this.MemTotalMemswBytes, *that1.MemTotalMemswBytes) + } + } else if this.MemTotalMemswBytes != nil { + return fmt.Errorf("this.MemTotalMemswBytes == nil && that.MemTotalMemswBytes != nil") + } else if that1.MemTotalMemswBytes != nil { + return fmt.Errorf("MemTotalMemswBytes this(%v) Not Equal that(%v)", this.MemTotalMemswBytes, that1.MemTotalMemswBytes) + } + if this.MemLimitBytes != nil && that1.MemLimitBytes != nil { + if *this.MemLimitBytes != *that1.MemLimitBytes { + return fmt.Errorf("MemLimitBytes this(%v) Not Equal that(%v)", *this.MemLimitBytes, *that1.MemLimitBytes) + } + } else if this.MemLimitBytes != nil { + return fmt.Errorf("this.MemLimitBytes == nil && that.MemLimitBytes != nil") + } else if that1.MemLimitBytes != nil { + return fmt.Errorf("MemLimitBytes this(%v) Not Equal that(%v)", this.MemLimitBytes, that1.MemLimitBytes) + } + if this.MemSoftLimitBytes != nil && that1.MemSoftLimitBytes != nil { + if *this.MemSoftLimitBytes != *that1.MemSoftLimitBytes { + return fmt.Errorf("MemSoftLimitBytes this(%v) Not Equal that(%v)", *this.MemSoftLimitBytes, *that1.MemSoftLimitBytes) + } + } else if this.MemSoftLimitBytes != nil { + return fmt.Errorf("this.MemSoftLimitBytes == nil && that.MemSoftLimitBytes != nil") + } else if that1.MemSoftLimitBytes != nil { + return fmt.Errorf("MemSoftLimitBytes this(%v) Not Equal that(%v)", this.MemSoftLimitBytes, that1.MemSoftLimitBytes) + } + if this.MemFileBytes != nil && that1.MemFileBytes != nil { + if *this.MemFileBytes != *that1.MemFileBytes { + return fmt.Errorf("MemFileBytes this(%v) Not Equal that(%v)", *this.MemFileBytes, *that1.MemFileBytes) + } + } else if this.MemFileBytes != nil { + return fmt.Errorf("this.MemFileBytes == nil && that.MemFileBytes != nil") + } else if that1.MemFileBytes != nil { + return fmt.Errorf("MemFileBytes this(%v) Not Equal that(%v)", this.MemFileBytes, that1.MemFileBytes) + } + if this.MemAnonBytes != nil && that1.MemAnonBytes != nil { + if *this.MemAnonBytes != *that1.MemAnonBytes { + return fmt.Errorf("MemAnonBytes this(%v) Not Equal that(%v)", *this.MemAnonBytes, *that1.MemAnonBytes) + } + } else if this.MemAnonBytes != nil { + return fmt.Errorf("this.MemAnonBytes == nil && that.MemAnonBytes != nil") + } else if that1.MemAnonBytes != nil { + return fmt.Errorf("MemAnonBytes this(%v) Not Equal that(%v)", this.MemAnonBytes, that1.MemAnonBytes) + } + if this.MemCacheBytes != nil && that1.MemCacheBytes != nil { + if *this.MemCacheBytes != *that1.MemCacheBytes { + return fmt.Errorf("MemCacheBytes this(%v) Not Equal that(%v)", *this.MemCacheBytes, *that1.MemCacheBytes) + } + } else if this.MemCacheBytes != nil { + return fmt.Errorf("this.MemCacheBytes == nil && that.MemCacheBytes != nil") + } else if that1.MemCacheBytes != nil { + return fmt.Errorf("MemCacheBytes this(%v) Not Equal that(%v)", this.MemCacheBytes, that1.MemCacheBytes) + } + if this.MemRssBytes != nil && that1.MemRssBytes != nil { + if *this.MemRssBytes != *that1.MemRssBytes { + return fmt.Errorf("MemRssBytes this(%v) Not Equal that(%v)", *this.MemRssBytes, *that1.MemRssBytes) + } + } else if this.MemRssBytes != nil { + return fmt.Errorf("this.MemRssBytes == nil && that.MemRssBytes != nil") + } else if that1.MemRssBytes != nil { + return fmt.Errorf("MemRssBytes this(%v) Not Equal that(%v)", this.MemRssBytes, that1.MemRssBytes) + } + if this.MemMappedFileBytes != nil && that1.MemMappedFileBytes != nil { + if *this.MemMappedFileBytes != *that1.MemMappedFileBytes { + return fmt.Errorf("MemMappedFileBytes this(%v) Not Equal that(%v)", *this.MemMappedFileBytes, *that1.MemMappedFileBytes) + } + } else if this.MemMappedFileBytes != nil { + return fmt.Errorf("this.MemMappedFileBytes == nil && that.MemMappedFileBytes != nil") + } else if that1.MemMappedFileBytes != nil { + return fmt.Errorf("MemMappedFileBytes this(%v) Not Equal that(%v)", this.MemMappedFileBytes, that1.MemMappedFileBytes) + } + if this.MemSwapBytes != nil && that1.MemSwapBytes != nil { + if *this.MemSwapBytes != *that1.MemSwapBytes { + return fmt.Errorf("MemSwapBytes this(%v) Not Equal that(%v)", *this.MemSwapBytes, *that1.MemSwapBytes) + } + } else if this.MemSwapBytes != nil { + return fmt.Errorf("this.MemSwapBytes == nil && that.MemSwapBytes != nil") + } else if that1.MemSwapBytes != nil { + return fmt.Errorf("MemSwapBytes this(%v) Not Equal that(%v)", this.MemSwapBytes, that1.MemSwapBytes) + } + if this.MemLowPressureCounter != nil && that1.MemLowPressureCounter != nil { + if *this.MemLowPressureCounter != *that1.MemLowPressureCounter { + return fmt.Errorf("MemLowPressureCounter this(%v) Not Equal that(%v)", *this.MemLowPressureCounter, *that1.MemLowPressureCounter) + } + } else if this.MemLowPressureCounter != nil { + return fmt.Errorf("this.MemLowPressureCounter == nil && that.MemLowPressureCounter != nil") + } else if that1.MemLowPressureCounter != nil { + return fmt.Errorf("MemLowPressureCounter this(%v) Not Equal that(%v)", this.MemLowPressureCounter, that1.MemLowPressureCounter) + } + if this.MemMediumPressureCounter != nil && that1.MemMediumPressureCounter != nil { + if *this.MemMediumPressureCounter != *that1.MemMediumPressureCounter { + return fmt.Errorf("MemMediumPressureCounter this(%v) Not Equal that(%v)", *this.MemMediumPressureCounter, *that1.MemMediumPressureCounter) + } + } else if this.MemMediumPressureCounter != nil { + return fmt.Errorf("this.MemMediumPressureCounter == nil && that.MemMediumPressureCounter != nil") + } else if that1.MemMediumPressureCounter != nil { + return fmt.Errorf("MemMediumPressureCounter this(%v) Not Equal that(%v)", this.MemMediumPressureCounter, that1.MemMediumPressureCounter) + } + if this.MemCriticalPressureCounter != nil && that1.MemCriticalPressureCounter != nil { + if *this.MemCriticalPressureCounter != *that1.MemCriticalPressureCounter { + return fmt.Errorf("MemCriticalPressureCounter this(%v) Not Equal that(%v)", *this.MemCriticalPressureCounter, *that1.MemCriticalPressureCounter) + } + } else if this.MemCriticalPressureCounter != nil { + return fmt.Errorf("this.MemCriticalPressureCounter == nil && that.MemCriticalPressureCounter != nil") + } else if that1.MemCriticalPressureCounter != nil { + return fmt.Errorf("MemCriticalPressureCounter this(%v) Not Equal that(%v)", this.MemCriticalPressureCounter, that1.MemCriticalPressureCounter) + } + if this.DiskLimitBytes != nil && that1.DiskLimitBytes != nil { + if *this.DiskLimitBytes != *that1.DiskLimitBytes { + return fmt.Errorf("DiskLimitBytes this(%v) Not Equal that(%v)", *this.DiskLimitBytes, *that1.DiskLimitBytes) + } + } else if this.DiskLimitBytes != nil { + return fmt.Errorf("this.DiskLimitBytes == nil && that.DiskLimitBytes != nil") + } else if that1.DiskLimitBytes != nil { + return fmt.Errorf("DiskLimitBytes this(%v) Not Equal that(%v)", this.DiskLimitBytes, that1.DiskLimitBytes) + } + if this.DiskUsedBytes != nil && that1.DiskUsedBytes != nil { + if *this.DiskUsedBytes != *that1.DiskUsedBytes { + return fmt.Errorf("DiskUsedBytes this(%v) Not Equal that(%v)", *this.DiskUsedBytes, *that1.DiskUsedBytes) + } + } else if this.DiskUsedBytes != nil { + return fmt.Errorf("this.DiskUsedBytes == nil && that.DiskUsedBytes != nil") + } else if that1.DiskUsedBytes != nil { + return fmt.Errorf("DiskUsedBytes this(%v) Not Equal that(%v)", this.DiskUsedBytes, that1.DiskUsedBytes) + } + if !this.Perf.Equal(that1.Perf) { + return fmt.Errorf("Perf this(%v) Not Equal that(%v)", this.Perf, that1.Perf) + } + if this.NetRxPackets != nil && that1.NetRxPackets != nil { + if *this.NetRxPackets != *that1.NetRxPackets { + return fmt.Errorf("NetRxPackets this(%v) Not Equal that(%v)", *this.NetRxPackets, *that1.NetRxPackets) + } + } else if this.NetRxPackets != nil { + return fmt.Errorf("this.NetRxPackets == nil && that.NetRxPackets != nil") + } else if that1.NetRxPackets != nil { + return fmt.Errorf("NetRxPackets this(%v) Not Equal that(%v)", this.NetRxPackets, that1.NetRxPackets) + } + if this.NetRxBytes != nil && that1.NetRxBytes != nil { + if *this.NetRxBytes != *that1.NetRxBytes { + return fmt.Errorf("NetRxBytes this(%v) Not Equal that(%v)", *this.NetRxBytes, *that1.NetRxBytes) + } + } else if this.NetRxBytes != nil { + return fmt.Errorf("this.NetRxBytes == nil && that.NetRxBytes != nil") + } else if that1.NetRxBytes != nil { + return fmt.Errorf("NetRxBytes this(%v) Not Equal that(%v)", this.NetRxBytes, that1.NetRxBytes) + } + if this.NetRxErrors != nil && that1.NetRxErrors != nil { + if *this.NetRxErrors != *that1.NetRxErrors { + return fmt.Errorf("NetRxErrors this(%v) Not Equal that(%v)", *this.NetRxErrors, *that1.NetRxErrors) + } + } else if this.NetRxErrors != nil { + return fmt.Errorf("this.NetRxErrors == nil && that.NetRxErrors != nil") + } else if that1.NetRxErrors != nil { + return fmt.Errorf("NetRxErrors this(%v) Not Equal that(%v)", this.NetRxErrors, that1.NetRxErrors) + } + if this.NetRxDropped != nil && that1.NetRxDropped != nil { + if *this.NetRxDropped != *that1.NetRxDropped { + return fmt.Errorf("NetRxDropped this(%v) Not Equal that(%v)", *this.NetRxDropped, *that1.NetRxDropped) + } + } else if this.NetRxDropped != nil { + return fmt.Errorf("this.NetRxDropped == nil && that.NetRxDropped != nil") + } else if that1.NetRxDropped != nil { + return fmt.Errorf("NetRxDropped this(%v) Not Equal that(%v)", this.NetRxDropped, that1.NetRxDropped) + } + if this.NetTxPackets != nil && that1.NetTxPackets != nil { + if *this.NetTxPackets != *that1.NetTxPackets { + return fmt.Errorf("NetTxPackets this(%v) Not Equal that(%v)", *this.NetTxPackets, *that1.NetTxPackets) + } + } else if this.NetTxPackets != nil { + return fmt.Errorf("this.NetTxPackets == nil && that.NetTxPackets != nil") + } else if that1.NetTxPackets != nil { + return fmt.Errorf("NetTxPackets this(%v) Not Equal that(%v)", this.NetTxPackets, that1.NetTxPackets) + } + if this.NetTxBytes != nil && that1.NetTxBytes != nil { + if *this.NetTxBytes != *that1.NetTxBytes { + return fmt.Errorf("NetTxBytes this(%v) Not Equal that(%v)", *this.NetTxBytes, *that1.NetTxBytes) + } + } else if this.NetTxBytes != nil { + return fmt.Errorf("this.NetTxBytes == nil && that.NetTxBytes != nil") + } else if that1.NetTxBytes != nil { + return fmt.Errorf("NetTxBytes this(%v) Not Equal that(%v)", this.NetTxBytes, that1.NetTxBytes) + } + if this.NetTxErrors != nil && that1.NetTxErrors != nil { + if *this.NetTxErrors != *that1.NetTxErrors { + return fmt.Errorf("NetTxErrors this(%v) Not Equal that(%v)", *this.NetTxErrors, *that1.NetTxErrors) + } + } else if this.NetTxErrors != nil { + return fmt.Errorf("this.NetTxErrors == nil && that.NetTxErrors != nil") + } else if that1.NetTxErrors != nil { + return fmt.Errorf("NetTxErrors this(%v) Not Equal that(%v)", this.NetTxErrors, that1.NetTxErrors) + } + if this.NetTxDropped != nil && that1.NetTxDropped != nil { + if *this.NetTxDropped != *that1.NetTxDropped { + return fmt.Errorf("NetTxDropped this(%v) Not Equal that(%v)", *this.NetTxDropped, *that1.NetTxDropped) + } + } else if this.NetTxDropped != nil { + return fmt.Errorf("this.NetTxDropped == nil && that.NetTxDropped != nil") + } else if that1.NetTxDropped != nil { + return fmt.Errorf("NetTxDropped this(%v) Not Equal that(%v)", this.NetTxDropped, that1.NetTxDropped) + } + if this.NetTcpRttMicrosecsP50 != nil && that1.NetTcpRttMicrosecsP50 != nil { + if *this.NetTcpRttMicrosecsP50 != *that1.NetTcpRttMicrosecsP50 { + return fmt.Errorf("NetTcpRttMicrosecsP50 this(%v) Not Equal that(%v)", *this.NetTcpRttMicrosecsP50, *that1.NetTcpRttMicrosecsP50) + } + } else if this.NetTcpRttMicrosecsP50 != nil { + return fmt.Errorf("this.NetTcpRttMicrosecsP50 == nil && that.NetTcpRttMicrosecsP50 != nil") + } else if that1.NetTcpRttMicrosecsP50 != nil { + return fmt.Errorf("NetTcpRttMicrosecsP50 this(%v) Not Equal that(%v)", this.NetTcpRttMicrosecsP50, that1.NetTcpRttMicrosecsP50) + } + if this.NetTcpRttMicrosecsP90 != nil && that1.NetTcpRttMicrosecsP90 != nil { + if *this.NetTcpRttMicrosecsP90 != *that1.NetTcpRttMicrosecsP90 { + return fmt.Errorf("NetTcpRttMicrosecsP90 this(%v) Not Equal that(%v)", *this.NetTcpRttMicrosecsP90, *that1.NetTcpRttMicrosecsP90) + } + } else if this.NetTcpRttMicrosecsP90 != nil { + return fmt.Errorf("this.NetTcpRttMicrosecsP90 == nil && that.NetTcpRttMicrosecsP90 != nil") + } else if that1.NetTcpRttMicrosecsP90 != nil { + return fmt.Errorf("NetTcpRttMicrosecsP90 this(%v) Not Equal that(%v)", this.NetTcpRttMicrosecsP90, that1.NetTcpRttMicrosecsP90) + } + if this.NetTcpRttMicrosecsP95 != nil && that1.NetTcpRttMicrosecsP95 != nil { + if *this.NetTcpRttMicrosecsP95 != *that1.NetTcpRttMicrosecsP95 { + return fmt.Errorf("NetTcpRttMicrosecsP95 this(%v) Not Equal that(%v)", *this.NetTcpRttMicrosecsP95, *that1.NetTcpRttMicrosecsP95) + } + } else if this.NetTcpRttMicrosecsP95 != nil { + return fmt.Errorf("this.NetTcpRttMicrosecsP95 == nil && that.NetTcpRttMicrosecsP95 != nil") + } else if that1.NetTcpRttMicrosecsP95 != nil { + return fmt.Errorf("NetTcpRttMicrosecsP95 this(%v) Not Equal that(%v)", this.NetTcpRttMicrosecsP95, that1.NetTcpRttMicrosecsP95) + } + if this.NetTcpRttMicrosecsP99 != nil && that1.NetTcpRttMicrosecsP99 != nil { + if *this.NetTcpRttMicrosecsP99 != *that1.NetTcpRttMicrosecsP99 { + return fmt.Errorf("NetTcpRttMicrosecsP99 this(%v) Not Equal that(%v)", *this.NetTcpRttMicrosecsP99, *that1.NetTcpRttMicrosecsP99) + } + } else if this.NetTcpRttMicrosecsP99 != nil { + return fmt.Errorf("this.NetTcpRttMicrosecsP99 == nil && that.NetTcpRttMicrosecsP99 != nil") + } else if that1.NetTcpRttMicrosecsP99 != nil { + return fmt.Errorf("NetTcpRttMicrosecsP99 this(%v) Not Equal that(%v)", this.NetTcpRttMicrosecsP99, that1.NetTcpRttMicrosecsP99) + } + if this.NetTcpActiveConnections != nil && that1.NetTcpActiveConnections != nil { + if *this.NetTcpActiveConnections != *that1.NetTcpActiveConnections { + return fmt.Errorf("NetTcpActiveConnections this(%v) Not Equal that(%v)", *this.NetTcpActiveConnections, *that1.NetTcpActiveConnections) + } + } else if this.NetTcpActiveConnections != nil { + return fmt.Errorf("this.NetTcpActiveConnections == nil && that.NetTcpActiveConnections != nil") + } else if that1.NetTcpActiveConnections != nil { + return fmt.Errorf("NetTcpActiveConnections this(%v) Not Equal that(%v)", this.NetTcpActiveConnections, that1.NetTcpActiveConnections) + } + if this.NetTcpTimeWaitConnections != nil && that1.NetTcpTimeWaitConnections != nil { + if *this.NetTcpTimeWaitConnections != *that1.NetTcpTimeWaitConnections { + return fmt.Errorf("NetTcpTimeWaitConnections this(%v) Not Equal that(%v)", *this.NetTcpTimeWaitConnections, *that1.NetTcpTimeWaitConnections) + } + } else if this.NetTcpTimeWaitConnections != nil { + return fmt.Errorf("this.NetTcpTimeWaitConnections == nil && that.NetTcpTimeWaitConnections != nil") + } else if that1.NetTcpTimeWaitConnections != nil { + return fmt.Errorf("NetTcpTimeWaitConnections this(%v) Not Equal that(%v)", this.NetTcpTimeWaitConnections, that1.NetTcpTimeWaitConnections) + } + if len(this.NetTrafficControlStatistics) != len(that1.NetTrafficControlStatistics) { + return fmt.Errorf("NetTrafficControlStatistics this(%v) Not Equal that(%v)", len(this.NetTrafficControlStatistics), len(that1.NetTrafficControlStatistics)) + } + for i := range this.NetTrafficControlStatistics { + if !this.NetTrafficControlStatistics[i].Equal(that1.NetTrafficControlStatistics[i]) { + return fmt.Errorf("NetTrafficControlStatistics this[%v](%v) Not Equal that[%v](%v)", i, this.NetTrafficControlStatistics[i], i, that1.NetTrafficControlStatistics[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *ResourceStatistics) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*ResourceStatistics) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Timestamp != nil && that1.Timestamp != nil { + if *this.Timestamp != *that1.Timestamp { + return false + } + } else if this.Timestamp != nil { + return false + } else if that1.Timestamp != nil { + return false + } + if this.Processes != nil && that1.Processes != nil { + if *this.Processes != *that1.Processes { + return false + } + } else if this.Processes != nil { + return false + } else if that1.Processes != nil { + return false + } + if this.Threads != nil && that1.Threads != nil { + if *this.Threads != *that1.Threads { + return false + } + } else if this.Threads != nil { + return false + } else if that1.Threads != nil { + return false + } + if this.CpusUserTimeSecs != nil && that1.CpusUserTimeSecs != nil { + if *this.CpusUserTimeSecs != *that1.CpusUserTimeSecs { + return false + } + } else if this.CpusUserTimeSecs != nil { + return false + } else if that1.CpusUserTimeSecs != nil { + return false + } + if this.CpusSystemTimeSecs != nil && that1.CpusSystemTimeSecs != nil { + if *this.CpusSystemTimeSecs != *that1.CpusSystemTimeSecs { + return false + } + } else if this.CpusSystemTimeSecs != nil { + return false + } else if that1.CpusSystemTimeSecs != nil { + return false + } + if this.CpusLimit != nil && that1.CpusLimit != nil { + if *this.CpusLimit != *that1.CpusLimit { + return false + } + } else if this.CpusLimit != nil { + return false + } else if that1.CpusLimit != nil { + return false + } + if this.CpusNrPeriods != nil && that1.CpusNrPeriods != nil { + if *this.CpusNrPeriods != *that1.CpusNrPeriods { + return false + } + } else if this.CpusNrPeriods != nil { + return false + } else if that1.CpusNrPeriods != nil { + return false + } + if this.CpusNrThrottled != nil && that1.CpusNrThrottled != nil { + if *this.CpusNrThrottled != *that1.CpusNrThrottled { + return false + } + } else if this.CpusNrThrottled != nil { + return false + } else if that1.CpusNrThrottled != nil { + return false + } + if this.CpusThrottledTimeSecs != nil && that1.CpusThrottledTimeSecs != nil { + if *this.CpusThrottledTimeSecs != *that1.CpusThrottledTimeSecs { + return false + } + } else if this.CpusThrottledTimeSecs != nil { + return false + } else if that1.CpusThrottledTimeSecs != nil { + return false + } + if this.MemTotalBytes != nil && that1.MemTotalBytes != nil { + if *this.MemTotalBytes != *that1.MemTotalBytes { + return false + } + } else if this.MemTotalBytes != nil { + return false + } else if that1.MemTotalBytes != nil { + return false + } + if this.MemTotalMemswBytes != nil && that1.MemTotalMemswBytes != nil { + if *this.MemTotalMemswBytes != *that1.MemTotalMemswBytes { + return false + } + } else if this.MemTotalMemswBytes != nil { + return false + } else if that1.MemTotalMemswBytes != nil { + return false + } + if this.MemLimitBytes != nil && that1.MemLimitBytes != nil { + if *this.MemLimitBytes != *that1.MemLimitBytes { + return false + } + } else if this.MemLimitBytes != nil { + return false + } else if that1.MemLimitBytes != nil { + return false + } + if this.MemSoftLimitBytes != nil && that1.MemSoftLimitBytes != nil { + if *this.MemSoftLimitBytes != *that1.MemSoftLimitBytes { + return false + } + } else if this.MemSoftLimitBytes != nil { + return false + } else if that1.MemSoftLimitBytes != nil { + return false + } + if this.MemFileBytes != nil && that1.MemFileBytes != nil { + if *this.MemFileBytes != *that1.MemFileBytes { + return false + } + } else if this.MemFileBytes != nil { + return false + } else if that1.MemFileBytes != nil { + return false + } + if this.MemAnonBytes != nil && that1.MemAnonBytes != nil { + if *this.MemAnonBytes != *that1.MemAnonBytes { + return false + } + } else if this.MemAnonBytes != nil { + return false + } else if that1.MemAnonBytes != nil { + return false + } + if this.MemCacheBytes != nil && that1.MemCacheBytes != nil { + if *this.MemCacheBytes != *that1.MemCacheBytes { + return false + } + } else if this.MemCacheBytes != nil { + return false + } else if that1.MemCacheBytes != nil { + return false + } + if this.MemRssBytes != nil && that1.MemRssBytes != nil { + if *this.MemRssBytes != *that1.MemRssBytes { + return false + } + } else if this.MemRssBytes != nil { + return false + } else if that1.MemRssBytes != nil { + return false + } + if this.MemMappedFileBytes != nil && that1.MemMappedFileBytes != nil { + if *this.MemMappedFileBytes != *that1.MemMappedFileBytes { + return false + } + } else if this.MemMappedFileBytes != nil { + return false + } else if that1.MemMappedFileBytes != nil { + return false + } + if this.MemSwapBytes != nil && that1.MemSwapBytes != nil { + if *this.MemSwapBytes != *that1.MemSwapBytes { + return false + } + } else if this.MemSwapBytes != nil { + return false + } else if that1.MemSwapBytes != nil { + return false + } + if this.MemLowPressureCounter != nil && that1.MemLowPressureCounter != nil { + if *this.MemLowPressureCounter != *that1.MemLowPressureCounter { + return false + } + } else if this.MemLowPressureCounter != nil { + return false + } else if that1.MemLowPressureCounter != nil { + return false + } + if this.MemMediumPressureCounter != nil && that1.MemMediumPressureCounter != nil { + if *this.MemMediumPressureCounter != *that1.MemMediumPressureCounter { + return false + } + } else if this.MemMediumPressureCounter != nil { + return false + } else if that1.MemMediumPressureCounter != nil { + return false + } + if this.MemCriticalPressureCounter != nil && that1.MemCriticalPressureCounter != nil { + if *this.MemCriticalPressureCounter != *that1.MemCriticalPressureCounter { + return false + } + } else if this.MemCriticalPressureCounter != nil { + return false + } else if that1.MemCriticalPressureCounter != nil { + return false + } + if this.DiskLimitBytes != nil && that1.DiskLimitBytes != nil { + if *this.DiskLimitBytes != *that1.DiskLimitBytes { + return false + } + } else if this.DiskLimitBytes != nil { + return false + } else if that1.DiskLimitBytes != nil { + return false + } + if this.DiskUsedBytes != nil && that1.DiskUsedBytes != nil { + if *this.DiskUsedBytes != *that1.DiskUsedBytes { + return false + } + } else if this.DiskUsedBytes != nil { + return false + } else if that1.DiskUsedBytes != nil { + return false + } + if !this.Perf.Equal(that1.Perf) { + return false + } + if this.NetRxPackets != nil && that1.NetRxPackets != nil { + if *this.NetRxPackets != *that1.NetRxPackets { + return false + } + } else if this.NetRxPackets != nil { + return false + } else if that1.NetRxPackets != nil { + return false + } + if this.NetRxBytes != nil && that1.NetRxBytes != nil { + if *this.NetRxBytes != *that1.NetRxBytes { + return false + } + } else if this.NetRxBytes != nil { + return false + } else if that1.NetRxBytes != nil { + return false + } + if this.NetRxErrors != nil && that1.NetRxErrors != nil { + if *this.NetRxErrors != *that1.NetRxErrors { + return false + } + } else if this.NetRxErrors != nil { + return false + } else if that1.NetRxErrors != nil { + return false + } + if this.NetRxDropped != nil && that1.NetRxDropped != nil { + if *this.NetRxDropped != *that1.NetRxDropped { + return false + } + } else if this.NetRxDropped != nil { + return false + } else if that1.NetRxDropped != nil { + return false + } + if this.NetTxPackets != nil && that1.NetTxPackets != nil { + if *this.NetTxPackets != *that1.NetTxPackets { + return false + } + } else if this.NetTxPackets != nil { + return false + } else if that1.NetTxPackets != nil { + return false + } + if this.NetTxBytes != nil && that1.NetTxBytes != nil { + if *this.NetTxBytes != *that1.NetTxBytes { + return false + } + } else if this.NetTxBytes != nil { + return false + } else if that1.NetTxBytes != nil { + return false + } + if this.NetTxErrors != nil && that1.NetTxErrors != nil { + if *this.NetTxErrors != *that1.NetTxErrors { + return false + } + } else if this.NetTxErrors != nil { + return false + } else if that1.NetTxErrors != nil { + return false + } + if this.NetTxDropped != nil && that1.NetTxDropped != nil { + if *this.NetTxDropped != *that1.NetTxDropped { + return false + } + } else if this.NetTxDropped != nil { + return false + } else if that1.NetTxDropped != nil { + return false + } + if this.NetTcpRttMicrosecsP50 != nil && that1.NetTcpRttMicrosecsP50 != nil { + if *this.NetTcpRttMicrosecsP50 != *that1.NetTcpRttMicrosecsP50 { + return false + } + } else if this.NetTcpRttMicrosecsP50 != nil { + return false + } else if that1.NetTcpRttMicrosecsP50 != nil { + return false + } + if this.NetTcpRttMicrosecsP90 != nil && that1.NetTcpRttMicrosecsP90 != nil { + if *this.NetTcpRttMicrosecsP90 != *that1.NetTcpRttMicrosecsP90 { + return false + } + } else if this.NetTcpRttMicrosecsP90 != nil { + return false + } else if that1.NetTcpRttMicrosecsP90 != nil { + return false + } + if this.NetTcpRttMicrosecsP95 != nil && that1.NetTcpRttMicrosecsP95 != nil { + if *this.NetTcpRttMicrosecsP95 != *that1.NetTcpRttMicrosecsP95 { + return false + } + } else if this.NetTcpRttMicrosecsP95 != nil { + return false + } else if that1.NetTcpRttMicrosecsP95 != nil { + return false + } + if this.NetTcpRttMicrosecsP99 != nil && that1.NetTcpRttMicrosecsP99 != nil { + if *this.NetTcpRttMicrosecsP99 != *that1.NetTcpRttMicrosecsP99 { + return false + } + } else if this.NetTcpRttMicrosecsP99 != nil { + return false + } else if that1.NetTcpRttMicrosecsP99 != nil { + return false + } + if this.NetTcpActiveConnections != nil && that1.NetTcpActiveConnections != nil { + if *this.NetTcpActiveConnections != *that1.NetTcpActiveConnections { + return false + } + } else if this.NetTcpActiveConnections != nil { + return false + } else if that1.NetTcpActiveConnections != nil { + return false + } + if this.NetTcpTimeWaitConnections != nil && that1.NetTcpTimeWaitConnections != nil { + if *this.NetTcpTimeWaitConnections != *that1.NetTcpTimeWaitConnections { + return false + } + } else if this.NetTcpTimeWaitConnections != nil { + return false + } else if that1.NetTcpTimeWaitConnections != nil { + return false + } + if len(this.NetTrafficControlStatistics) != len(that1.NetTrafficControlStatistics) { + return false + } + for i := range this.NetTrafficControlStatistics { + if !this.NetTrafficControlStatistics[i].Equal(that1.NetTrafficControlStatistics[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *ResourceUsage) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ResourceUsage) + if !ok { + return fmt.Errorf("that is not of type *ResourceUsage") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ResourceUsage but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ResourceUsagebut is not nil && this == nil") + } + if len(this.Executors) != len(that1.Executors) { + return fmt.Errorf("Executors this(%v) Not Equal that(%v)", len(this.Executors), len(that1.Executors)) + } + for i := range this.Executors { + if !this.Executors[i].Equal(that1.Executors[i]) { + return fmt.Errorf("Executors this[%v](%v) Not Equal that[%v](%v)", i, this.Executors[i], i, that1.Executors[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *ResourceUsage) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*ResourceUsage) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.Executors) != len(that1.Executors) { + return false + } + for i := range this.Executors { + if !this.Executors[i].Equal(that1.Executors[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *ResourceUsage_Executor) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ResourceUsage_Executor) + if !ok { + return fmt.Errorf("that is not of type *ResourceUsage_Executor") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ResourceUsage_Executor but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ResourceUsage_Executorbut is not nil && this == nil") + } + if !this.ExecutorInfo.Equal(that1.ExecutorInfo) { + return fmt.Errorf("ExecutorInfo this(%v) Not Equal that(%v)", this.ExecutorInfo, that1.ExecutorInfo) + } + if len(this.Allocated) != len(that1.Allocated) { + return fmt.Errorf("Allocated this(%v) Not Equal that(%v)", len(this.Allocated), len(that1.Allocated)) + } + for i := range this.Allocated { + if !this.Allocated[i].Equal(that1.Allocated[i]) { + return fmt.Errorf("Allocated this[%v](%v) Not Equal that[%v](%v)", i, this.Allocated[i], i, that1.Allocated[i]) + } + } + if !this.Statistics.Equal(that1.Statistics) { + return fmt.Errorf("Statistics this(%v) Not Equal that(%v)", this.Statistics, that1.Statistics) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *ResourceUsage_Executor) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*ResourceUsage_Executor) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !this.ExecutorInfo.Equal(that1.ExecutorInfo) { + return false + } + if len(this.Allocated) != len(that1.Allocated) { + return false + } + for i := range this.Allocated { + if !this.Allocated[i].Equal(that1.Allocated[i]) { + return false + } + } + if !this.Statistics.Equal(that1.Statistics) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *PerfStatistics) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*PerfStatistics) + if !ok { + return fmt.Errorf("that is not of type *PerfStatistics") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *PerfStatistics but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *PerfStatisticsbut is not nil && this == nil") + } + if this.Timestamp != nil && that1.Timestamp != nil { + if *this.Timestamp != *that1.Timestamp { + return fmt.Errorf("Timestamp this(%v) Not Equal that(%v)", *this.Timestamp, *that1.Timestamp) + } + } else if this.Timestamp != nil { + return fmt.Errorf("this.Timestamp == nil && that.Timestamp != nil") + } else if that1.Timestamp != nil { + return fmt.Errorf("Timestamp this(%v) Not Equal that(%v)", this.Timestamp, that1.Timestamp) + } + if this.Duration != nil && that1.Duration != nil { + if *this.Duration != *that1.Duration { + return fmt.Errorf("Duration this(%v) Not Equal that(%v)", *this.Duration, *that1.Duration) + } + } else if this.Duration != nil { + return fmt.Errorf("this.Duration == nil && that.Duration != nil") + } else if that1.Duration != nil { + return fmt.Errorf("Duration this(%v) Not Equal that(%v)", this.Duration, that1.Duration) + } + if this.Cycles != nil && that1.Cycles != nil { + if *this.Cycles != *that1.Cycles { + return fmt.Errorf("Cycles this(%v) Not Equal that(%v)", *this.Cycles, *that1.Cycles) + } + } else if this.Cycles != nil { + return fmt.Errorf("this.Cycles == nil && that.Cycles != nil") + } else if that1.Cycles != nil { + return fmt.Errorf("Cycles this(%v) Not Equal that(%v)", this.Cycles, that1.Cycles) + } + if this.StalledCyclesFrontend != nil && that1.StalledCyclesFrontend != nil { + if *this.StalledCyclesFrontend != *that1.StalledCyclesFrontend { + return fmt.Errorf("StalledCyclesFrontend this(%v) Not Equal that(%v)", *this.StalledCyclesFrontend, *that1.StalledCyclesFrontend) + } + } else if this.StalledCyclesFrontend != nil { + return fmt.Errorf("this.StalledCyclesFrontend == nil && that.StalledCyclesFrontend != nil") + } else if that1.StalledCyclesFrontend != nil { + return fmt.Errorf("StalledCyclesFrontend this(%v) Not Equal that(%v)", this.StalledCyclesFrontend, that1.StalledCyclesFrontend) + } + if this.StalledCyclesBackend != nil && that1.StalledCyclesBackend != nil { + if *this.StalledCyclesBackend != *that1.StalledCyclesBackend { + return fmt.Errorf("StalledCyclesBackend this(%v) Not Equal that(%v)", *this.StalledCyclesBackend, *that1.StalledCyclesBackend) + } + } else if this.StalledCyclesBackend != nil { + return fmt.Errorf("this.StalledCyclesBackend == nil && that.StalledCyclesBackend != nil") + } else if that1.StalledCyclesBackend != nil { + return fmt.Errorf("StalledCyclesBackend this(%v) Not Equal that(%v)", this.StalledCyclesBackend, that1.StalledCyclesBackend) + } + if this.Instructions != nil && that1.Instructions != nil { + if *this.Instructions != *that1.Instructions { + return fmt.Errorf("Instructions this(%v) Not Equal that(%v)", *this.Instructions, *that1.Instructions) + } + } else if this.Instructions != nil { + return fmt.Errorf("this.Instructions == nil && that.Instructions != nil") + } else if that1.Instructions != nil { + return fmt.Errorf("Instructions this(%v) Not Equal that(%v)", this.Instructions, that1.Instructions) + } + if this.CacheReferences != nil && that1.CacheReferences != nil { + if *this.CacheReferences != *that1.CacheReferences { + return fmt.Errorf("CacheReferences this(%v) Not Equal that(%v)", *this.CacheReferences, *that1.CacheReferences) + } + } else if this.CacheReferences != nil { + return fmt.Errorf("this.CacheReferences == nil && that.CacheReferences != nil") + } else if that1.CacheReferences != nil { + return fmt.Errorf("CacheReferences this(%v) Not Equal that(%v)", this.CacheReferences, that1.CacheReferences) + } + if this.CacheMisses != nil && that1.CacheMisses != nil { + if *this.CacheMisses != *that1.CacheMisses { + return fmt.Errorf("CacheMisses this(%v) Not Equal that(%v)", *this.CacheMisses, *that1.CacheMisses) + } + } else if this.CacheMisses != nil { + return fmt.Errorf("this.CacheMisses == nil && that.CacheMisses != nil") + } else if that1.CacheMisses != nil { + return fmt.Errorf("CacheMisses this(%v) Not Equal that(%v)", this.CacheMisses, that1.CacheMisses) + } + if this.Branches != nil && that1.Branches != nil { + if *this.Branches != *that1.Branches { + return fmt.Errorf("Branches this(%v) Not Equal that(%v)", *this.Branches, *that1.Branches) + } + } else if this.Branches != nil { + return fmt.Errorf("this.Branches == nil && that.Branches != nil") + } else if that1.Branches != nil { + return fmt.Errorf("Branches this(%v) Not Equal that(%v)", this.Branches, that1.Branches) + } + if this.BranchMisses != nil && that1.BranchMisses != nil { + if *this.BranchMisses != *that1.BranchMisses { + return fmt.Errorf("BranchMisses this(%v) Not Equal that(%v)", *this.BranchMisses, *that1.BranchMisses) + } + } else if this.BranchMisses != nil { + return fmt.Errorf("this.BranchMisses == nil && that.BranchMisses != nil") + } else if that1.BranchMisses != nil { + return fmt.Errorf("BranchMisses this(%v) Not Equal that(%v)", this.BranchMisses, that1.BranchMisses) + } + if this.BusCycles != nil && that1.BusCycles != nil { + if *this.BusCycles != *that1.BusCycles { + return fmt.Errorf("BusCycles this(%v) Not Equal that(%v)", *this.BusCycles, *that1.BusCycles) + } + } else if this.BusCycles != nil { + return fmt.Errorf("this.BusCycles == nil && that.BusCycles != nil") + } else if that1.BusCycles != nil { + return fmt.Errorf("BusCycles this(%v) Not Equal that(%v)", this.BusCycles, that1.BusCycles) + } + if this.RefCycles != nil && that1.RefCycles != nil { + if *this.RefCycles != *that1.RefCycles { + return fmt.Errorf("RefCycles this(%v) Not Equal that(%v)", *this.RefCycles, *that1.RefCycles) + } + } else if this.RefCycles != nil { + return fmt.Errorf("this.RefCycles == nil && that.RefCycles != nil") + } else if that1.RefCycles != nil { + return fmt.Errorf("RefCycles this(%v) Not Equal that(%v)", this.RefCycles, that1.RefCycles) + } + if this.CpuClock != nil && that1.CpuClock != nil { + if *this.CpuClock != *that1.CpuClock { + return fmt.Errorf("CpuClock this(%v) Not Equal that(%v)", *this.CpuClock, *that1.CpuClock) + } + } else if this.CpuClock != nil { + return fmt.Errorf("this.CpuClock == nil && that.CpuClock != nil") + } else if that1.CpuClock != nil { + return fmt.Errorf("CpuClock this(%v) Not Equal that(%v)", this.CpuClock, that1.CpuClock) + } + if this.TaskClock != nil && that1.TaskClock != nil { + if *this.TaskClock != *that1.TaskClock { + return fmt.Errorf("TaskClock this(%v) Not Equal that(%v)", *this.TaskClock, *that1.TaskClock) + } + } else if this.TaskClock != nil { + return fmt.Errorf("this.TaskClock == nil && that.TaskClock != nil") + } else if that1.TaskClock != nil { + return fmt.Errorf("TaskClock this(%v) Not Equal that(%v)", this.TaskClock, that1.TaskClock) + } + if this.PageFaults != nil && that1.PageFaults != nil { + if *this.PageFaults != *that1.PageFaults { + return fmt.Errorf("PageFaults this(%v) Not Equal that(%v)", *this.PageFaults, *that1.PageFaults) + } + } else if this.PageFaults != nil { + return fmt.Errorf("this.PageFaults == nil && that.PageFaults != nil") + } else if that1.PageFaults != nil { + return fmt.Errorf("PageFaults this(%v) Not Equal that(%v)", this.PageFaults, that1.PageFaults) + } + if this.MinorFaults != nil && that1.MinorFaults != nil { + if *this.MinorFaults != *that1.MinorFaults { + return fmt.Errorf("MinorFaults this(%v) Not Equal that(%v)", *this.MinorFaults, *that1.MinorFaults) + } + } else if this.MinorFaults != nil { + return fmt.Errorf("this.MinorFaults == nil && that.MinorFaults != nil") + } else if that1.MinorFaults != nil { + return fmt.Errorf("MinorFaults this(%v) Not Equal that(%v)", this.MinorFaults, that1.MinorFaults) + } + if this.MajorFaults != nil && that1.MajorFaults != nil { + if *this.MajorFaults != *that1.MajorFaults { + return fmt.Errorf("MajorFaults this(%v) Not Equal that(%v)", *this.MajorFaults, *that1.MajorFaults) + } + } else if this.MajorFaults != nil { + return fmt.Errorf("this.MajorFaults == nil && that.MajorFaults != nil") + } else if that1.MajorFaults != nil { + return fmt.Errorf("MajorFaults this(%v) Not Equal that(%v)", this.MajorFaults, that1.MajorFaults) + } + if this.ContextSwitches != nil && that1.ContextSwitches != nil { + if *this.ContextSwitches != *that1.ContextSwitches { + return fmt.Errorf("ContextSwitches this(%v) Not Equal that(%v)", *this.ContextSwitches, *that1.ContextSwitches) + } + } else if this.ContextSwitches != nil { + return fmt.Errorf("this.ContextSwitches == nil && that.ContextSwitches != nil") + } else if that1.ContextSwitches != nil { + return fmt.Errorf("ContextSwitches this(%v) Not Equal that(%v)", this.ContextSwitches, that1.ContextSwitches) + } + if this.CpuMigrations != nil && that1.CpuMigrations != nil { + if *this.CpuMigrations != *that1.CpuMigrations { + return fmt.Errorf("CpuMigrations this(%v) Not Equal that(%v)", *this.CpuMigrations, *that1.CpuMigrations) + } + } else if this.CpuMigrations != nil { + return fmt.Errorf("this.CpuMigrations == nil && that.CpuMigrations != nil") + } else if that1.CpuMigrations != nil { + return fmt.Errorf("CpuMigrations this(%v) Not Equal that(%v)", this.CpuMigrations, that1.CpuMigrations) + } + if this.AlignmentFaults != nil && that1.AlignmentFaults != nil { + if *this.AlignmentFaults != *that1.AlignmentFaults { + return fmt.Errorf("AlignmentFaults this(%v) Not Equal that(%v)", *this.AlignmentFaults, *that1.AlignmentFaults) + } + } else if this.AlignmentFaults != nil { + return fmt.Errorf("this.AlignmentFaults == nil && that.AlignmentFaults != nil") + } else if that1.AlignmentFaults != nil { + return fmt.Errorf("AlignmentFaults this(%v) Not Equal that(%v)", this.AlignmentFaults, that1.AlignmentFaults) + } + if this.EmulationFaults != nil && that1.EmulationFaults != nil { + if *this.EmulationFaults != *that1.EmulationFaults { + return fmt.Errorf("EmulationFaults this(%v) Not Equal that(%v)", *this.EmulationFaults, *that1.EmulationFaults) + } + } else if this.EmulationFaults != nil { + return fmt.Errorf("this.EmulationFaults == nil && that.EmulationFaults != nil") + } else if that1.EmulationFaults != nil { + return fmt.Errorf("EmulationFaults this(%v) Not Equal that(%v)", this.EmulationFaults, that1.EmulationFaults) + } + if this.L1DcacheLoads != nil && that1.L1DcacheLoads != nil { + if *this.L1DcacheLoads != *that1.L1DcacheLoads { + return fmt.Errorf("L1DcacheLoads this(%v) Not Equal that(%v)", *this.L1DcacheLoads, *that1.L1DcacheLoads) + } + } else if this.L1DcacheLoads != nil { + return fmt.Errorf("this.L1DcacheLoads == nil && that.L1DcacheLoads != nil") + } else if that1.L1DcacheLoads != nil { + return fmt.Errorf("L1DcacheLoads this(%v) Not Equal that(%v)", this.L1DcacheLoads, that1.L1DcacheLoads) + } + if this.L1DcacheLoadMisses != nil && that1.L1DcacheLoadMisses != nil { + if *this.L1DcacheLoadMisses != *that1.L1DcacheLoadMisses { + return fmt.Errorf("L1DcacheLoadMisses this(%v) Not Equal that(%v)", *this.L1DcacheLoadMisses, *that1.L1DcacheLoadMisses) + } + } else if this.L1DcacheLoadMisses != nil { + return fmt.Errorf("this.L1DcacheLoadMisses == nil && that.L1DcacheLoadMisses != nil") + } else if that1.L1DcacheLoadMisses != nil { + return fmt.Errorf("L1DcacheLoadMisses this(%v) Not Equal that(%v)", this.L1DcacheLoadMisses, that1.L1DcacheLoadMisses) + } + if this.L1DcacheStores != nil && that1.L1DcacheStores != nil { + if *this.L1DcacheStores != *that1.L1DcacheStores { + return fmt.Errorf("L1DcacheStores this(%v) Not Equal that(%v)", *this.L1DcacheStores, *that1.L1DcacheStores) + } + } else if this.L1DcacheStores != nil { + return fmt.Errorf("this.L1DcacheStores == nil && that.L1DcacheStores != nil") + } else if that1.L1DcacheStores != nil { + return fmt.Errorf("L1DcacheStores this(%v) Not Equal that(%v)", this.L1DcacheStores, that1.L1DcacheStores) + } + if this.L1DcacheStoreMisses != nil && that1.L1DcacheStoreMisses != nil { + if *this.L1DcacheStoreMisses != *that1.L1DcacheStoreMisses { + return fmt.Errorf("L1DcacheStoreMisses this(%v) Not Equal that(%v)", *this.L1DcacheStoreMisses, *that1.L1DcacheStoreMisses) + } + } else if this.L1DcacheStoreMisses != nil { + return fmt.Errorf("this.L1DcacheStoreMisses == nil && that.L1DcacheStoreMisses != nil") + } else if that1.L1DcacheStoreMisses != nil { + return fmt.Errorf("L1DcacheStoreMisses this(%v) Not Equal that(%v)", this.L1DcacheStoreMisses, that1.L1DcacheStoreMisses) + } + if this.L1DcachePrefetches != nil && that1.L1DcachePrefetches != nil { + if *this.L1DcachePrefetches != *that1.L1DcachePrefetches { + return fmt.Errorf("L1DcachePrefetches this(%v) Not Equal that(%v)", *this.L1DcachePrefetches, *that1.L1DcachePrefetches) + } + } else if this.L1DcachePrefetches != nil { + return fmt.Errorf("this.L1DcachePrefetches == nil && that.L1DcachePrefetches != nil") + } else if that1.L1DcachePrefetches != nil { + return fmt.Errorf("L1DcachePrefetches this(%v) Not Equal that(%v)", this.L1DcachePrefetches, that1.L1DcachePrefetches) + } + if this.L1DcachePrefetchMisses != nil && that1.L1DcachePrefetchMisses != nil { + if *this.L1DcachePrefetchMisses != *that1.L1DcachePrefetchMisses { + return fmt.Errorf("L1DcachePrefetchMisses this(%v) Not Equal that(%v)", *this.L1DcachePrefetchMisses, *that1.L1DcachePrefetchMisses) + } + } else if this.L1DcachePrefetchMisses != nil { + return fmt.Errorf("this.L1DcachePrefetchMisses == nil && that.L1DcachePrefetchMisses != nil") + } else if that1.L1DcachePrefetchMisses != nil { + return fmt.Errorf("L1DcachePrefetchMisses this(%v) Not Equal that(%v)", this.L1DcachePrefetchMisses, that1.L1DcachePrefetchMisses) + } + if this.L1IcacheLoads != nil && that1.L1IcacheLoads != nil { + if *this.L1IcacheLoads != *that1.L1IcacheLoads { + return fmt.Errorf("L1IcacheLoads this(%v) Not Equal that(%v)", *this.L1IcacheLoads, *that1.L1IcacheLoads) + } + } else if this.L1IcacheLoads != nil { + return fmt.Errorf("this.L1IcacheLoads == nil && that.L1IcacheLoads != nil") + } else if that1.L1IcacheLoads != nil { + return fmt.Errorf("L1IcacheLoads this(%v) Not Equal that(%v)", this.L1IcacheLoads, that1.L1IcacheLoads) + } + if this.L1IcacheLoadMisses != nil && that1.L1IcacheLoadMisses != nil { + if *this.L1IcacheLoadMisses != *that1.L1IcacheLoadMisses { + return fmt.Errorf("L1IcacheLoadMisses this(%v) Not Equal that(%v)", *this.L1IcacheLoadMisses, *that1.L1IcacheLoadMisses) + } + } else if this.L1IcacheLoadMisses != nil { + return fmt.Errorf("this.L1IcacheLoadMisses == nil && that.L1IcacheLoadMisses != nil") + } else if that1.L1IcacheLoadMisses != nil { + return fmt.Errorf("L1IcacheLoadMisses this(%v) Not Equal that(%v)", this.L1IcacheLoadMisses, that1.L1IcacheLoadMisses) + } + if this.L1IcachePrefetches != nil && that1.L1IcachePrefetches != nil { + if *this.L1IcachePrefetches != *that1.L1IcachePrefetches { + return fmt.Errorf("L1IcachePrefetches this(%v) Not Equal that(%v)", *this.L1IcachePrefetches, *that1.L1IcachePrefetches) + } + } else if this.L1IcachePrefetches != nil { + return fmt.Errorf("this.L1IcachePrefetches == nil && that.L1IcachePrefetches != nil") + } else if that1.L1IcachePrefetches != nil { + return fmt.Errorf("L1IcachePrefetches this(%v) Not Equal that(%v)", this.L1IcachePrefetches, that1.L1IcachePrefetches) + } + if this.L1IcachePrefetchMisses != nil && that1.L1IcachePrefetchMisses != nil { + if *this.L1IcachePrefetchMisses != *that1.L1IcachePrefetchMisses { + return fmt.Errorf("L1IcachePrefetchMisses this(%v) Not Equal that(%v)", *this.L1IcachePrefetchMisses, *that1.L1IcachePrefetchMisses) + } + } else if this.L1IcachePrefetchMisses != nil { + return fmt.Errorf("this.L1IcachePrefetchMisses == nil && that.L1IcachePrefetchMisses != nil") + } else if that1.L1IcachePrefetchMisses != nil { + return fmt.Errorf("L1IcachePrefetchMisses this(%v) Not Equal that(%v)", this.L1IcachePrefetchMisses, that1.L1IcachePrefetchMisses) + } + if this.LlcLoads != nil && that1.LlcLoads != nil { + if *this.LlcLoads != *that1.LlcLoads { + return fmt.Errorf("LlcLoads this(%v) Not Equal that(%v)", *this.LlcLoads, *that1.LlcLoads) + } + } else if this.LlcLoads != nil { + return fmt.Errorf("this.LlcLoads == nil && that.LlcLoads != nil") + } else if that1.LlcLoads != nil { + return fmt.Errorf("LlcLoads this(%v) Not Equal that(%v)", this.LlcLoads, that1.LlcLoads) + } + if this.LlcLoadMisses != nil && that1.LlcLoadMisses != nil { + if *this.LlcLoadMisses != *that1.LlcLoadMisses { + return fmt.Errorf("LlcLoadMisses this(%v) Not Equal that(%v)", *this.LlcLoadMisses, *that1.LlcLoadMisses) + } + } else if this.LlcLoadMisses != nil { + return fmt.Errorf("this.LlcLoadMisses == nil && that.LlcLoadMisses != nil") + } else if that1.LlcLoadMisses != nil { + return fmt.Errorf("LlcLoadMisses this(%v) Not Equal that(%v)", this.LlcLoadMisses, that1.LlcLoadMisses) + } + if this.LlcStores != nil && that1.LlcStores != nil { + if *this.LlcStores != *that1.LlcStores { + return fmt.Errorf("LlcStores this(%v) Not Equal that(%v)", *this.LlcStores, *that1.LlcStores) + } + } else if this.LlcStores != nil { + return fmt.Errorf("this.LlcStores == nil && that.LlcStores != nil") + } else if that1.LlcStores != nil { + return fmt.Errorf("LlcStores this(%v) Not Equal that(%v)", this.LlcStores, that1.LlcStores) + } + if this.LlcStoreMisses != nil && that1.LlcStoreMisses != nil { + if *this.LlcStoreMisses != *that1.LlcStoreMisses { + return fmt.Errorf("LlcStoreMisses this(%v) Not Equal that(%v)", *this.LlcStoreMisses, *that1.LlcStoreMisses) + } + } else if this.LlcStoreMisses != nil { + return fmt.Errorf("this.LlcStoreMisses == nil && that.LlcStoreMisses != nil") + } else if that1.LlcStoreMisses != nil { + return fmt.Errorf("LlcStoreMisses this(%v) Not Equal that(%v)", this.LlcStoreMisses, that1.LlcStoreMisses) + } + if this.LlcPrefetches != nil && that1.LlcPrefetches != nil { + if *this.LlcPrefetches != *that1.LlcPrefetches { + return fmt.Errorf("LlcPrefetches this(%v) Not Equal that(%v)", *this.LlcPrefetches, *that1.LlcPrefetches) + } + } else if this.LlcPrefetches != nil { + return fmt.Errorf("this.LlcPrefetches == nil && that.LlcPrefetches != nil") + } else if that1.LlcPrefetches != nil { + return fmt.Errorf("LlcPrefetches this(%v) Not Equal that(%v)", this.LlcPrefetches, that1.LlcPrefetches) + } + if this.LlcPrefetchMisses != nil && that1.LlcPrefetchMisses != nil { + if *this.LlcPrefetchMisses != *that1.LlcPrefetchMisses { + return fmt.Errorf("LlcPrefetchMisses this(%v) Not Equal that(%v)", *this.LlcPrefetchMisses, *that1.LlcPrefetchMisses) + } + } else if this.LlcPrefetchMisses != nil { + return fmt.Errorf("this.LlcPrefetchMisses == nil && that.LlcPrefetchMisses != nil") + } else if that1.LlcPrefetchMisses != nil { + return fmt.Errorf("LlcPrefetchMisses this(%v) Not Equal that(%v)", this.LlcPrefetchMisses, that1.LlcPrefetchMisses) + } + if this.DtlbLoads != nil && that1.DtlbLoads != nil { + if *this.DtlbLoads != *that1.DtlbLoads { + return fmt.Errorf("DtlbLoads this(%v) Not Equal that(%v)", *this.DtlbLoads, *that1.DtlbLoads) + } + } else if this.DtlbLoads != nil { + return fmt.Errorf("this.DtlbLoads == nil && that.DtlbLoads != nil") + } else if that1.DtlbLoads != nil { + return fmt.Errorf("DtlbLoads this(%v) Not Equal that(%v)", this.DtlbLoads, that1.DtlbLoads) + } + if this.DtlbLoadMisses != nil && that1.DtlbLoadMisses != nil { + if *this.DtlbLoadMisses != *that1.DtlbLoadMisses { + return fmt.Errorf("DtlbLoadMisses this(%v) Not Equal that(%v)", *this.DtlbLoadMisses, *that1.DtlbLoadMisses) + } + } else if this.DtlbLoadMisses != nil { + return fmt.Errorf("this.DtlbLoadMisses == nil && that.DtlbLoadMisses != nil") + } else if that1.DtlbLoadMisses != nil { + return fmt.Errorf("DtlbLoadMisses this(%v) Not Equal that(%v)", this.DtlbLoadMisses, that1.DtlbLoadMisses) + } + if this.DtlbStores != nil && that1.DtlbStores != nil { + if *this.DtlbStores != *that1.DtlbStores { + return fmt.Errorf("DtlbStores this(%v) Not Equal that(%v)", *this.DtlbStores, *that1.DtlbStores) + } + } else if this.DtlbStores != nil { + return fmt.Errorf("this.DtlbStores == nil && that.DtlbStores != nil") + } else if that1.DtlbStores != nil { + return fmt.Errorf("DtlbStores this(%v) Not Equal that(%v)", this.DtlbStores, that1.DtlbStores) + } + if this.DtlbStoreMisses != nil && that1.DtlbStoreMisses != nil { + if *this.DtlbStoreMisses != *that1.DtlbStoreMisses { + return fmt.Errorf("DtlbStoreMisses this(%v) Not Equal that(%v)", *this.DtlbStoreMisses, *that1.DtlbStoreMisses) + } + } else if this.DtlbStoreMisses != nil { + return fmt.Errorf("this.DtlbStoreMisses == nil && that.DtlbStoreMisses != nil") + } else if that1.DtlbStoreMisses != nil { + return fmt.Errorf("DtlbStoreMisses this(%v) Not Equal that(%v)", this.DtlbStoreMisses, that1.DtlbStoreMisses) + } + if this.DtlbPrefetches != nil && that1.DtlbPrefetches != nil { + if *this.DtlbPrefetches != *that1.DtlbPrefetches { + return fmt.Errorf("DtlbPrefetches this(%v) Not Equal that(%v)", *this.DtlbPrefetches, *that1.DtlbPrefetches) + } + } else if this.DtlbPrefetches != nil { + return fmt.Errorf("this.DtlbPrefetches == nil && that.DtlbPrefetches != nil") + } else if that1.DtlbPrefetches != nil { + return fmt.Errorf("DtlbPrefetches this(%v) Not Equal that(%v)", this.DtlbPrefetches, that1.DtlbPrefetches) + } + if this.DtlbPrefetchMisses != nil && that1.DtlbPrefetchMisses != nil { + if *this.DtlbPrefetchMisses != *that1.DtlbPrefetchMisses { + return fmt.Errorf("DtlbPrefetchMisses this(%v) Not Equal that(%v)", *this.DtlbPrefetchMisses, *that1.DtlbPrefetchMisses) + } + } else if this.DtlbPrefetchMisses != nil { + return fmt.Errorf("this.DtlbPrefetchMisses == nil && that.DtlbPrefetchMisses != nil") + } else if that1.DtlbPrefetchMisses != nil { + return fmt.Errorf("DtlbPrefetchMisses this(%v) Not Equal that(%v)", this.DtlbPrefetchMisses, that1.DtlbPrefetchMisses) + } + if this.ItlbLoads != nil && that1.ItlbLoads != nil { + if *this.ItlbLoads != *that1.ItlbLoads { + return fmt.Errorf("ItlbLoads this(%v) Not Equal that(%v)", *this.ItlbLoads, *that1.ItlbLoads) + } + } else if this.ItlbLoads != nil { + return fmt.Errorf("this.ItlbLoads == nil && that.ItlbLoads != nil") + } else if that1.ItlbLoads != nil { + return fmt.Errorf("ItlbLoads this(%v) Not Equal that(%v)", this.ItlbLoads, that1.ItlbLoads) + } + if this.ItlbLoadMisses != nil && that1.ItlbLoadMisses != nil { + if *this.ItlbLoadMisses != *that1.ItlbLoadMisses { + return fmt.Errorf("ItlbLoadMisses this(%v) Not Equal that(%v)", *this.ItlbLoadMisses, *that1.ItlbLoadMisses) + } + } else if this.ItlbLoadMisses != nil { + return fmt.Errorf("this.ItlbLoadMisses == nil && that.ItlbLoadMisses != nil") + } else if that1.ItlbLoadMisses != nil { + return fmt.Errorf("ItlbLoadMisses this(%v) Not Equal that(%v)", this.ItlbLoadMisses, that1.ItlbLoadMisses) + } + if this.BranchLoads != nil && that1.BranchLoads != nil { + if *this.BranchLoads != *that1.BranchLoads { + return fmt.Errorf("BranchLoads this(%v) Not Equal that(%v)", *this.BranchLoads, *that1.BranchLoads) + } + } else if this.BranchLoads != nil { + return fmt.Errorf("this.BranchLoads == nil && that.BranchLoads != nil") + } else if that1.BranchLoads != nil { + return fmt.Errorf("BranchLoads this(%v) Not Equal that(%v)", this.BranchLoads, that1.BranchLoads) + } + if this.BranchLoadMisses != nil && that1.BranchLoadMisses != nil { + if *this.BranchLoadMisses != *that1.BranchLoadMisses { + return fmt.Errorf("BranchLoadMisses this(%v) Not Equal that(%v)", *this.BranchLoadMisses, *that1.BranchLoadMisses) + } + } else if this.BranchLoadMisses != nil { + return fmt.Errorf("this.BranchLoadMisses == nil && that.BranchLoadMisses != nil") + } else if that1.BranchLoadMisses != nil { + return fmt.Errorf("BranchLoadMisses this(%v) Not Equal that(%v)", this.BranchLoadMisses, that1.BranchLoadMisses) + } + if this.NodeLoads != nil && that1.NodeLoads != nil { + if *this.NodeLoads != *that1.NodeLoads { + return fmt.Errorf("NodeLoads this(%v) Not Equal that(%v)", *this.NodeLoads, *that1.NodeLoads) + } + } else if this.NodeLoads != nil { + return fmt.Errorf("this.NodeLoads == nil && that.NodeLoads != nil") + } else if that1.NodeLoads != nil { + return fmt.Errorf("NodeLoads this(%v) Not Equal that(%v)", this.NodeLoads, that1.NodeLoads) + } + if this.NodeLoadMisses != nil && that1.NodeLoadMisses != nil { + if *this.NodeLoadMisses != *that1.NodeLoadMisses { + return fmt.Errorf("NodeLoadMisses this(%v) Not Equal that(%v)", *this.NodeLoadMisses, *that1.NodeLoadMisses) + } + } else if this.NodeLoadMisses != nil { + return fmt.Errorf("this.NodeLoadMisses == nil && that.NodeLoadMisses != nil") + } else if that1.NodeLoadMisses != nil { + return fmt.Errorf("NodeLoadMisses this(%v) Not Equal that(%v)", this.NodeLoadMisses, that1.NodeLoadMisses) + } + if this.NodeStores != nil && that1.NodeStores != nil { + if *this.NodeStores != *that1.NodeStores { + return fmt.Errorf("NodeStores this(%v) Not Equal that(%v)", *this.NodeStores, *that1.NodeStores) + } + } else if this.NodeStores != nil { + return fmt.Errorf("this.NodeStores == nil && that.NodeStores != nil") + } else if that1.NodeStores != nil { + return fmt.Errorf("NodeStores this(%v) Not Equal that(%v)", this.NodeStores, that1.NodeStores) + } + if this.NodeStoreMisses != nil && that1.NodeStoreMisses != nil { + if *this.NodeStoreMisses != *that1.NodeStoreMisses { + return fmt.Errorf("NodeStoreMisses this(%v) Not Equal that(%v)", *this.NodeStoreMisses, *that1.NodeStoreMisses) + } + } else if this.NodeStoreMisses != nil { + return fmt.Errorf("this.NodeStoreMisses == nil && that.NodeStoreMisses != nil") + } else if that1.NodeStoreMisses != nil { + return fmt.Errorf("NodeStoreMisses this(%v) Not Equal that(%v)", this.NodeStoreMisses, that1.NodeStoreMisses) + } + if this.NodePrefetches != nil && that1.NodePrefetches != nil { + if *this.NodePrefetches != *that1.NodePrefetches { + return fmt.Errorf("NodePrefetches this(%v) Not Equal that(%v)", *this.NodePrefetches, *that1.NodePrefetches) + } + } else if this.NodePrefetches != nil { + return fmt.Errorf("this.NodePrefetches == nil && that.NodePrefetches != nil") + } else if that1.NodePrefetches != nil { + return fmt.Errorf("NodePrefetches this(%v) Not Equal that(%v)", this.NodePrefetches, that1.NodePrefetches) + } + if this.NodePrefetchMisses != nil && that1.NodePrefetchMisses != nil { + if *this.NodePrefetchMisses != *that1.NodePrefetchMisses { + return fmt.Errorf("NodePrefetchMisses this(%v) Not Equal that(%v)", *this.NodePrefetchMisses, *that1.NodePrefetchMisses) + } + } else if this.NodePrefetchMisses != nil { + return fmt.Errorf("this.NodePrefetchMisses == nil && that.NodePrefetchMisses != nil") + } else if that1.NodePrefetchMisses != nil { + return fmt.Errorf("NodePrefetchMisses this(%v) Not Equal that(%v)", this.NodePrefetchMisses, that1.NodePrefetchMisses) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *PerfStatistics) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*PerfStatistics) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Timestamp != nil && that1.Timestamp != nil { + if *this.Timestamp != *that1.Timestamp { + return false + } + } else if this.Timestamp != nil { + return false + } else if that1.Timestamp != nil { + return false + } + if this.Duration != nil && that1.Duration != nil { + if *this.Duration != *that1.Duration { + return false + } + } else if this.Duration != nil { + return false + } else if that1.Duration != nil { + return false + } + if this.Cycles != nil && that1.Cycles != nil { + if *this.Cycles != *that1.Cycles { + return false + } + } else if this.Cycles != nil { + return false + } else if that1.Cycles != nil { + return false + } + if this.StalledCyclesFrontend != nil && that1.StalledCyclesFrontend != nil { + if *this.StalledCyclesFrontend != *that1.StalledCyclesFrontend { + return false + } + } else if this.StalledCyclesFrontend != nil { + return false + } else if that1.StalledCyclesFrontend != nil { + return false + } + if this.StalledCyclesBackend != nil && that1.StalledCyclesBackend != nil { + if *this.StalledCyclesBackend != *that1.StalledCyclesBackend { + return false + } + } else if this.StalledCyclesBackend != nil { + return false + } else if that1.StalledCyclesBackend != nil { + return false + } + if this.Instructions != nil && that1.Instructions != nil { + if *this.Instructions != *that1.Instructions { + return false + } + } else if this.Instructions != nil { + return false + } else if that1.Instructions != nil { + return false + } + if this.CacheReferences != nil && that1.CacheReferences != nil { + if *this.CacheReferences != *that1.CacheReferences { + return false + } + } else if this.CacheReferences != nil { + return false + } else if that1.CacheReferences != nil { + return false + } + if this.CacheMisses != nil && that1.CacheMisses != nil { + if *this.CacheMisses != *that1.CacheMisses { + return false + } + } else if this.CacheMisses != nil { + return false + } else if that1.CacheMisses != nil { + return false + } + if this.Branches != nil && that1.Branches != nil { + if *this.Branches != *that1.Branches { + return false + } + } else if this.Branches != nil { + return false + } else if that1.Branches != nil { + return false + } + if this.BranchMisses != nil && that1.BranchMisses != nil { + if *this.BranchMisses != *that1.BranchMisses { + return false + } + } else if this.BranchMisses != nil { + return false + } else if that1.BranchMisses != nil { + return false + } + if this.BusCycles != nil && that1.BusCycles != nil { + if *this.BusCycles != *that1.BusCycles { + return false + } + } else if this.BusCycles != nil { + return false + } else if that1.BusCycles != nil { + return false + } + if this.RefCycles != nil && that1.RefCycles != nil { + if *this.RefCycles != *that1.RefCycles { + return false + } + } else if this.RefCycles != nil { + return false + } else if that1.RefCycles != nil { + return false + } + if this.CpuClock != nil && that1.CpuClock != nil { + if *this.CpuClock != *that1.CpuClock { + return false + } + } else if this.CpuClock != nil { + return false + } else if that1.CpuClock != nil { + return false + } + if this.TaskClock != nil && that1.TaskClock != nil { + if *this.TaskClock != *that1.TaskClock { + return false + } + } else if this.TaskClock != nil { + return false + } else if that1.TaskClock != nil { + return false + } + if this.PageFaults != nil && that1.PageFaults != nil { + if *this.PageFaults != *that1.PageFaults { + return false + } + } else if this.PageFaults != nil { + return false + } else if that1.PageFaults != nil { + return false + } + if this.MinorFaults != nil && that1.MinorFaults != nil { + if *this.MinorFaults != *that1.MinorFaults { + return false + } + } else if this.MinorFaults != nil { + return false + } else if that1.MinorFaults != nil { + return false + } + if this.MajorFaults != nil && that1.MajorFaults != nil { + if *this.MajorFaults != *that1.MajorFaults { + return false + } + } else if this.MajorFaults != nil { + return false + } else if that1.MajorFaults != nil { + return false + } + if this.ContextSwitches != nil && that1.ContextSwitches != nil { + if *this.ContextSwitches != *that1.ContextSwitches { + return false + } + } else if this.ContextSwitches != nil { + return false + } else if that1.ContextSwitches != nil { + return false + } + if this.CpuMigrations != nil && that1.CpuMigrations != nil { + if *this.CpuMigrations != *that1.CpuMigrations { + return false + } + } else if this.CpuMigrations != nil { + return false + } else if that1.CpuMigrations != nil { + return false + } + if this.AlignmentFaults != nil && that1.AlignmentFaults != nil { + if *this.AlignmentFaults != *that1.AlignmentFaults { + return false + } + } else if this.AlignmentFaults != nil { + return false + } else if that1.AlignmentFaults != nil { + return false + } + if this.EmulationFaults != nil && that1.EmulationFaults != nil { + if *this.EmulationFaults != *that1.EmulationFaults { + return false + } + } else if this.EmulationFaults != nil { + return false + } else if that1.EmulationFaults != nil { + return false + } + if this.L1DcacheLoads != nil && that1.L1DcacheLoads != nil { + if *this.L1DcacheLoads != *that1.L1DcacheLoads { + return false + } + } else if this.L1DcacheLoads != nil { + return false + } else if that1.L1DcacheLoads != nil { + return false + } + if this.L1DcacheLoadMisses != nil && that1.L1DcacheLoadMisses != nil { + if *this.L1DcacheLoadMisses != *that1.L1DcacheLoadMisses { + return false + } + } else if this.L1DcacheLoadMisses != nil { + return false + } else if that1.L1DcacheLoadMisses != nil { + return false + } + if this.L1DcacheStores != nil && that1.L1DcacheStores != nil { + if *this.L1DcacheStores != *that1.L1DcacheStores { + return false + } + } else if this.L1DcacheStores != nil { + return false + } else if that1.L1DcacheStores != nil { + return false + } + if this.L1DcacheStoreMisses != nil && that1.L1DcacheStoreMisses != nil { + if *this.L1DcacheStoreMisses != *that1.L1DcacheStoreMisses { + return false + } + } else if this.L1DcacheStoreMisses != nil { + return false + } else if that1.L1DcacheStoreMisses != nil { + return false + } + if this.L1DcachePrefetches != nil && that1.L1DcachePrefetches != nil { + if *this.L1DcachePrefetches != *that1.L1DcachePrefetches { + return false + } + } else if this.L1DcachePrefetches != nil { + return false + } else if that1.L1DcachePrefetches != nil { + return false + } + if this.L1DcachePrefetchMisses != nil && that1.L1DcachePrefetchMisses != nil { + if *this.L1DcachePrefetchMisses != *that1.L1DcachePrefetchMisses { + return false + } + } else if this.L1DcachePrefetchMisses != nil { + return false + } else if that1.L1DcachePrefetchMisses != nil { + return false + } + if this.L1IcacheLoads != nil && that1.L1IcacheLoads != nil { + if *this.L1IcacheLoads != *that1.L1IcacheLoads { + return false + } + } else if this.L1IcacheLoads != nil { + return false + } else if that1.L1IcacheLoads != nil { + return false + } + if this.L1IcacheLoadMisses != nil && that1.L1IcacheLoadMisses != nil { + if *this.L1IcacheLoadMisses != *that1.L1IcacheLoadMisses { + return false + } + } else if this.L1IcacheLoadMisses != nil { + return false + } else if that1.L1IcacheLoadMisses != nil { + return false + } + if this.L1IcachePrefetches != nil && that1.L1IcachePrefetches != nil { + if *this.L1IcachePrefetches != *that1.L1IcachePrefetches { + return false + } + } else if this.L1IcachePrefetches != nil { + return false + } else if that1.L1IcachePrefetches != nil { + return false + } + if this.L1IcachePrefetchMisses != nil && that1.L1IcachePrefetchMisses != nil { + if *this.L1IcachePrefetchMisses != *that1.L1IcachePrefetchMisses { + return false + } + } else if this.L1IcachePrefetchMisses != nil { + return false + } else if that1.L1IcachePrefetchMisses != nil { + return false + } + if this.LlcLoads != nil && that1.LlcLoads != nil { + if *this.LlcLoads != *that1.LlcLoads { + return false + } + } else if this.LlcLoads != nil { + return false + } else if that1.LlcLoads != nil { + return false + } + if this.LlcLoadMisses != nil && that1.LlcLoadMisses != nil { + if *this.LlcLoadMisses != *that1.LlcLoadMisses { + return false + } + } else if this.LlcLoadMisses != nil { + return false + } else if that1.LlcLoadMisses != nil { + return false + } + if this.LlcStores != nil && that1.LlcStores != nil { + if *this.LlcStores != *that1.LlcStores { + return false + } + } else if this.LlcStores != nil { + return false + } else if that1.LlcStores != nil { + return false + } + if this.LlcStoreMisses != nil && that1.LlcStoreMisses != nil { + if *this.LlcStoreMisses != *that1.LlcStoreMisses { + return false + } + } else if this.LlcStoreMisses != nil { + return false + } else if that1.LlcStoreMisses != nil { + return false + } + if this.LlcPrefetches != nil && that1.LlcPrefetches != nil { + if *this.LlcPrefetches != *that1.LlcPrefetches { + return false + } + } else if this.LlcPrefetches != nil { + return false + } else if that1.LlcPrefetches != nil { + return false + } + if this.LlcPrefetchMisses != nil && that1.LlcPrefetchMisses != nil { + if *this.LlcPrefetchMisses != *that1.LlcPrefetchMisses { + return false + } + } else if this.LlcPrefetchMisses != nil { + return false + } else if that1.LlcPrefetchMisses != nil { + return false + } + if this.DtlbLoads != nil && that1.DtlbLoads != nil { + if *this.DtlbLoads != *that1.DtlbLoads { + return false + } + } else if this.DtlbLoads != nil { + return false + } else if that1.DtlbLoads != nil { + return false + } + if this.DtlbLoadMisses != nil && that1.DtlbLoadMisses != nil { + if *this.DtlbLoadMisses != *that1.DtlbLoadMisses { + return false + } + } else if this.DtlbLoadMisses != nil { + return false + } else if that1.DtlbLoadMisses != nil { + return false + } + if this.DtlbStores != nil && that1.DtlbStores != nil { + if *this.DtlbStores != *that1.DtlbStores { + return false + } + } else if this.DtlbStores != nil { + return false + } else if that1.DtlbStores != nil { + return false + } + if this.DtlbStoreMisses != nil && that1.DtlbStoreMisses != nil { + if *this.DtlbStoreMisses != *that1.DtlbStoreMisses { + return false + } + } else if this.DtlbStoreMisses != nil { + return false + } else if that1.DtlbStoreMisses != nil { + return false + } + if this.DtlbPrefetches != nil && that1.DtlbPrefetches != nil { + if *this.DtlbPrefetches != *that1.DtlbPrefetches { + return false + } + } else if this.DtlbPrefetches != nil { + return false + } else if that1.DtlbPrefetches != nil { + return false + } + if this.DtlbPrefetchMisses != nil && that1.DtlbPrefetchMisses != nil { + if *this.DtlbPrefetchMisses != *that1.DtlbPrefetchMisses { + return false + } + } else if this.DtlbPrefetchMisses != nil { + return false + } else if that1.DtlbPrefetchMisses != nil { + return false + } + if this.ItlbLoads != nil && that1.ItlbLoads != nil { + if *this.ItlbLoads != *that1.ItlbLoads { + return false + } + } else if this.ItlbLoads != nil { + return false + } else if that1.ItlbLoads != nil { + return false + } + if this.ItlbLoadMisses != nil && that1.ItlbLoadMisses != nil { + if *this.ItlbLoadMisses != *that1.ItlbLoadMisses { + return false + } + } else if this.ItlbLoadMisses != nil { + return false + } else if that1.ItlbLoadMisses != nil { + return false + } + if this.BranchLoads != nil && that1.BranchLoads != nil { + if *this.BranchLoads != *that1.BranchLoads { + return false + } + } else if this.BranchLoads != nil { + return false + } else if that1.BranchLoads != nil { + return false + } + if this.BranchLoadMisses != nil && that1.BranchLoadMisses != nil { + if *this.BranchLoadMisses != *that1.BranchLoadMisses { + return false + } + } else if this.BranchLoadMisses != nil { + return false + } else if that1.BranchLoadMisses != nil { + return false + } + if this.NodeLoads != nil && that1.NodeLoads != nil { + if *this.NodeLoads != *that1.NodeLoads { + return false + } + } else if this.NodeLoads != nil { + return false + } else if that1.NodeLoads != nil { + return false + } + if this.NodeLoadMisses != nil && that1.NodeLoadMisses != nil { + if *this.NodeLoadMisses != *that1.NodeLoadMisses { + return false + } + } else if this.NodeLoadMisses != nil { + return false + } else if that1.NodeLoadMisses != nil { + return false + } + if this.NodeStores != nil && that1.NodeStores != nil { + if *this.NodeStores != *that1.NodeStores { + return false + } + } else if this.NodeStores != nil { + return false + } else if that1.NodeStores != nil { + return false + } + if this.NodeStoreMisses != nil && that1.NodeStoreMisses != nil { + if *this.NodeStoreMisses != *that1.NodeStoreMisses { + return false + } + } else if this.NodeStoreMisses != nil { + return false + } else if that1.NodeStoreMisses != nil { + return false + } + if this.NodePrefetches != nil && that1.NodePrefetches != nil { + if *this.NodePrefetches != *that1.NodePrefetches { + return false + } + } else if this.NodePrefetches != nil { + return false + } else if that1.NodePrefetches != nil { + return false + } + if this.NodePrefetchMisses != nil && that1.NodePrefetchMisses != nil { + if *this.NodePrefetchMisses != *that1.NodePrefetchMisses { + return false + } + } else if this.NodePrefetchMisses != nil { + return false + } else if that1.NodePrefetchMisses != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Request) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Request) + if !ok { + return fmt.Errorf("that is not of type *Request") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Request but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Requestbut is not nil && this == nil") + } + if !this.SlaveId.Equal(that1.SlaveId) { + return fmt.Errorf("SlaveId this(%v) Not Equal that(%v)", this.SlaveId, that1.SlaveId) + } + if len(this.Resources) != len(that1.Resources) { + return fmt.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return fmt.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Request) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Request) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !this.SlaveId.Equal(that1.SlaveId) { + return false + } + if len(this.Resources) != len(that1.Resources) { + return false + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Offer) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Offer) + if !ok { + return fmt.Errorf("that is not of type *Offer") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Offer but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Offerbut is not nil && this == nil") + } + if !this.Id.Equal(that1.Id) { + return fmt.Errorf("Id this(%v) Not Equal that(%v)", this.Id, that1.Id) + } + if !this.FrameworkId.Equal(that1.FrameworkId) { + return fmt.Errorf("FrameworkId this(%v) Not Equal that(%v)", this.FrameworkId, that1.FrameworkId) + } + if !this.SlaveId.Equal(that1.SlaveId) { + return fmt.Errorf("SlaveId this(%v) Not Equal that(%v)", this.SlaveId, that1.SlaveId) + } + if this.Hostname != nil && that1.Hostname != nil { + if *this.Hostname != *that1.Hostname { + return fmt.Errorf("Hostname this(%v) Not Equal that(%v)", *this.Hostname, *that1.Hostname) + } + } else if this.Hostname != nil { + return fmt.Errorf("this.Hostname == nil && that.Hostname != nil") + } else if that1.Hostname != nil { + return fmt.Errorf("Hostname this(%v) Not Equal that(%v)", this.Hostname, that1.Hostname) + } + if len(this.Resources) != len(that1.Resources) { + return fmt.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return fmt.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) + } + } + if len(this.Attributes) != len(that1.Attributes) { + return fmt.Errorf("Attributes this(%v) Not Equal that(%v)", len(this.Attributes), len(that1.Attributes)) + } + for i := range this.Attributes { + if !this.Attributes[i].Equal(that1.Attributes[i]) { + return fmt.Errorf("Attributes this[%v](%v) Not Equal that[%v](%v)", i, this.Attributes[i], i, that1.Attributes[i]) + } + } + if len(this.ExecutorIds) != len(that1.ExecutorIds) { + return fmt.Errorf("ExecutorIds this(%v) Not Equal that(%v)", len(this.ExecutorIds), len(that1.ExecutorIds)) + } + for i := range this.ExecutorIds { + if !this.ExecutorIds[i].Equal(that1.ExecutorIds[i]) { + return fmt.Errorf("ExecutorIds this[%v](%v) Not Equal that[%v](%v)", i, this.ExecutorIds[i], i, that1.ExecutorIds[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Offer) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Offer) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !this.Id.Equal(that1.Id) { + return false + } + if !this.FrameworkId.Equal(that1.FrameworkId) { + return false + } + if !this.SlaveId.Equal(that1.SlaveId) { + return false + } + if this.Hostname != nil && that1.Hostname != nil { + if *this.Hostname != *that1.Hostname { + return false + } + } else if this.Hostname != nil { + return false + } else if that1.Hostname != nil { + return false + } + if len(this.Resources) != len(that1.Resources) { + return false + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return false + } + } + if len(this.Attributes) != len(that1.Attributes) { + return false + } + for i := range this.Attributes { + if !this.Attributes[i].Equal(that1.Attributes[i]) { + return false + } + } + if len(this.ExecutorIds) != len(that1.ExecutorIds) { + return false + } + for i := range this.ExecutorIds { + if !this.ExecutorIds[i].Equal(that1.ExecutorIds[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Offer_Operation) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Offer_Operation) + if !ok { + return fmt.Errorf("that is not of type *Offer_Operation") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Offer_Operation but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Offer_Operationbut is not nil && this == nil") + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) + } + } else if this.Type != nil { + return fmt.Errorf("this.Type == nil && that.Type != nil") + } else if that1.Type != nil { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + } + if !this.Launch.Equal(that1.Launch) { + return fmt.Errorf("Launch this(%v) Not Equal that(%v)", this.Launch, that1.Launch) + } + if !this.Reserve.Equal(that1.Reserve) { + return fmt.Errorf("Reserve this(%v) Not Equal that(%v)", this.Reserve, that1.Reserve) + } + if !this.Unreserve.Equal(that1.Unreserve) { + return fmt.Errorf("Unreserve this(%v) Not Equal that(%v)", this.Unreserve, that1.Unreserve) + } + if !this.Create.Equal(that1.Create) { + return fmt.Errorf("Create this(%v) Not Equal that(%v)", this.Create, that1.Create) + } + if !this.Destroy.Equal(that1.Destroy) { + return fmt.Errorf("Destroy this(%v) Not Equal that(%v)", this.Destroy, that1.Destroy) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Offer_Operation) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Offer_Operation) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return false + } + } else if this.Type != nil { + return false + } else if that1.Type != nil { + return false + } + if !this.Launch.Equal(that1.Launch) { + return false + } + if !this.Reserve.Equal(that1.Reserve) { + return false + } + if !this.Unreserve.Equal(that1.Unreserve) { + return false + } + if !this.Create.Equal(that1.Create) { + return false + } + if !this.Destroy.Equal(that1.Destroy) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Offer_Operation_Launch) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Offer_Operation_Launch) + if !ok { + return fmt.Errorf("that is not of type *Offer_Operation_Launch") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Offer_Operation_Launch but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Offer_Operation_Launchbut is not nil && this == nil") + } + if len(this.TaskInfos) != len(that1.TaskInfos) { + return fmt.Errorf("TaskInfos this(%v) Not Equal that(%v)", len(this.TaskInfos), len(that1.TaskInfos)) + } + for i := range this.TaskInfos { + if !this.TaskInfos[i].Equal(that1.TaskInfos[i]) { + return fmt.Errorf("TaskInfos this[%v](%v) Not Equal that[%v](%v)", i, this.TaskInfos[i], i, that1.TaskInfos[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Offer_Operation_Launch) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Offer_Operation_Launch) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.TaskInfos) != len(that1.TaskInfos) { + return false + } + for i := range this.TaskInfos { + if !this.TaskInfos[i].Equal(that1.TaskInfos[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Offer_Operation_Reserve) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Offer_Operation_Reserve) + if !ok { + return fmt.Errorf("that is not of type *Offer_Operation_Reserve") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Offer_Operation_Reserve but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Offer_Operation_Reservebut is not nil && this == nil") + } + if len(this.Resources) != len(that1.Resources) { + return fmt.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return fmt.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Offer_Operation_Reserve) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Offer_Operation_Reserve) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.Resources) != len(that1.Resources) { + return false + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Offer_Operation_Unreserve) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Offer_Operation_Unreserve) + if !ok { + return fmt.Errorf("that is not of type *Offer_Operation_Unreserve") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Offer_Operation_Unreserve but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Offer_Operation_Unreservebut is not nil && this == nil") + } + if len(this.Resources) != len(that1.Resources) { + return fmt.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return fmt.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Offer_Operation_Unreserve) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Offer_Operation_Unreserve) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.Resources) != len(that1.Resources) { + return false + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Offer_Operation_Create) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Offer_Operation_Create) + if !ok { + return fmt.Errorf("that is not of type *Offer_Operation_Create") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Offer_Operation_Create but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Offer_Operation_Createbut is not nil && this == nil") + } + if len(this.Volumes) != len(that1.Volumes) { + return fmt.Errorf("Volumes this(%v) Not Equal that(%v)", len(this.Volumes), len(that1.Volumes)) + } + for i := range this.Volumes { + if !this.Volumes[i].Equal(that1.Volumes[i]) { + return fmt.Errorf("Volumes this[%v](%v) Not Equal that[%v](%v)", i, this.Volumes[i], i, that1.Volumes[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Offer_Operation_Create) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Offer_Operation_Create) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.Volumes) != len(that1.Volumes) { + return false + } + for i := range this.Volumes { + if !this.Volumes[i].Equal(that1.Volumes[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Offer_Operation_Destroy) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Offer_Operation_Destroy) + if !ok { + return fmt.Errorf("that is not of type *Offer_Operation_Destroy") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Offer_Operation_Destroy but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Offer_Operation_Destroybut is not nil && this == nil") + } + if len(this.Volumes) != len(that1.Volumes) { + return fmt.Errorf("Volumes this(%v) Not Equal that(%v)", len(this.Volumes), len(that1.Volumes)) + } + for i := range this.Volumes { + if !this.Volumes[i].Equal(that1.Volumes[i]) { + return fmt.Errorf("Volumes this[%v](%v) Not Equal that[%v](%v)", i, this.Volumes[i], i, that1.Volumes[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Offer_Operation_Destroy) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Offer_Operation_Destroy) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.Volumes) != len(that1.Volumes) { + return false + } + for i := range this.Volumes { + if !this.Volumes[i].Equal(that1.Volumes[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *TaskInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*TaskInfo) + if !ok { + return fmt.Errorf("that is not of type *TaskInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *TaskInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *TaskInfobut is not nil && this == nil") + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) + } + } else if this.Name != nil { + return fmt.Errorf("this.Name == nil && that.Name != nil") + } else if that1.Name != nil { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + } + if !this.TaskId.Equal(that1.TaskId) { + return fmt.Errorf("TaskId this(%v) Not Equal that(%v)", this.TaskId, that1.TaskId) + } + if !this.SlaveId.Equal(that1.SlaveId) { + return fmt.Errorf("SlaveId this(%v) Not Equal that(%v)", this.SlaveId, that1.SlaveId) + } + if len(this.Resources) != len(that1.Resources) { + return fmt.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return fmt.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) + } + } + if !this.Executor.Equal(that1.Executor) { + return fmt.Errorf("Executor this(%v) Not Equal that(%v)", this.Executor, that1.Executor) + } + if !this.Command.Equal(that1.Command) { + return fmt.Errorf("Command this(%v) Not Equal that(%v)", this.Command, that1.Command) + } + if !this.Container.Equal(that1.Container) { + return fmt.Errorf("Container this(%v) Not Equal that(%v)", this.Container, that1.Container) + } + if !bytes.Equal(this.Data, that1.Data) { + return fmt.Errorf("Data this(%v) Not Equal that(%v)", this.Data, that1.Data) + } + if !this.HealthCheck.Equal(that1.HealthCheck) { + return fmt.Errorf("HealthCheck this(%v) Not Equal that(%v)", this.HealthCheck, that1.HealthCheck) + } + if !this.Labels.Equal(that1.Labels) { + return fmt.Errorf("Labels this(%v) Not Equal that(%v)", this.Labels, that1.Labels) + } + if !this.Discovery.Equal(that1.Discovery) { + return fmt.Errorf("Discovery this(%v) Not Equal that(%v)", this.Discovery, that1.Discovery) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *TaskInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*TaskInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return false + } + } else if this.Name != nil { + return false + } else if that1.Name != nil { + return false + } + if !this.TaskId.Equal(that1.TaskId) { + return false + } + if !this.SlaveId.Equal(that1.SlaveId) { + return false + } + if len(this.Resources) != len(that1.Resources) { + return false + } + for i := range this.Resources { + if !this.Resources[i].Equal(that1.Resources[i]) { + return false + } + } + if !this.Executor.Equal(that1.Executor) { + return false + } + if !this.Command.Equal(that1.Command) { + return false + } + if !this.Container.Equal(that1.Container) { + return false + } + if !bytes.Equal(this.Data, that1.Data) { + return false + } + if !this.HealthCheck.Equal(that1.HealthCheck) { + return false + } + if !this.Labels.Equal(that1.Labels) { + return false + } + if !this.Discovery.Equal(that1.Discovery) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *TaskStatus) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*TaskStatus) + if !ok { + return fmt.Errorf("that is not of type *TaskStatus") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *TaskStatus but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *TaskStatusbut is not nil && this == nil") + } + if !this.TaskId.Equal(that1.TaskId) { + return fmt.Errorf("TaskId this(%v) Not Equal that(%v)", this.TaskId, that1.TaskId) + } + if this.State != nil && that1.State != nil { + if *this.State != *that1.State { + return fmt.Errorf("State this(%v) Not Equal that(%v)", *this.State, *that1.State) + } + } else if this.State != nil { + return fmt.Errorf("this.State == nil && that.State != nil") + } else if that1.State != nil { + return fmt.Errorf("State this(%v) Not Equal that(%v)", this.State, that1.State) + } + if this.Message != nil && that1.Message != nil { + if *this.Message != *that1.Message { + return fmt.Errorf("Message this(%v) Not Equal that(%v)", *this.Message, *that1.Message) + } + } else if this.Message != nil { + return fmt.Errorf("this.Message == nil && that.Message != nil") + } else if that1.Message != nil { + return fmt.Errorf("Message this(%v) Not Equal that(%v)", this.Message, that1.Message) + } + if this.Source != nil && that1.Source != nil { + if *this.Source != *that1.Source { + return fmt.Errorf("Source this(%v) Not Equal that(%v)", *this.Source, *that1.Source) + } + } else if this.Source != nil { + return fmt.Errorf("this.Source == nil && that.Source != nil") + } else if that1.Source != nil { + return fmt.Errorf("Source this(%v) Not Equal that(%v)", this.Source, that1.Source) + } + if this.Reason != nil && that1.Reason != nil { + if *this.Reason != *that1.Reason { + return fmt.Errorf("Reason this(%v) Not Equal that(%v)", *this.Reason, *that1.Reason) + } + } else if this.Reason != nil { + return fmt.Errorf("this.Reason == nil && that.Reason != nil") + } else if that1.Reason != nil { + return fmt.Errorf("Reason this(%v) Not Equal that(%v)", this.Reason, that1.Reason) + } + if !bytes.Equal(this.Data, that1.Data) { + return fmt.Errorf("Data this(%v) Not Equal that(%v)", this.Data, that1.Data) + } + if !this.SlaveId.Equal(that1.SlaveId) { + return fmt.Errorf("SlaveId this(%v) Not Equal that(%v)", this.SlaveId, that1.SlaveId) + } + if !this.ExecutorId.Equal(that1.ExecutorId) { + return fmt.Errorf("ExecutorId this(%v) Not Equal that(%v)", this.ExecutorId, that1.ExecutorId) + } + if this.Timestamp != nil && that1.Timestamp != nil { + if *this.Timestamp != *that1.Timestamp { + return fmt.Errorf("Timestamp this(%v) Not Equal that(%v)", *this.Timestamp, *that1.Timestamp) + } + } else if this.Timestamp != nil { + return fmt.Errorf("this.Timestamp == nil && that.Timestamp != nil") + } else if that1.Timestamp != nil { + return fmt.Errorf("Timestamp this(%v) Not Equal that(%v)", this.Timestamp, that1.Timestamp) + } + if !bytes.Equal(this.Uuid, that1.Uuid) { + return fmt.Errorf("Uuid this(%v) Not Equal that(%v)", this.Uuid, that1.Uuid) + } + if this.Healthy != nil && that1.Healthy != nil { + if *this.Healthy != *that1.Healthy { + return fmt.Errorf("Healthy this(%v) Not Equal that(%v)", *this.Healthy, *that1.Healthy) + } + } else if this.Healthy != nil { + return fmt.Errorf("this.Healthy == nil && that.Healthy != nil") + } else if that1.Healthy != nil { + return fmt.Errorf("Healthy this(%v) Not Equal that(%v)", this.Healthy, that1.Healthy) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *TaskStatus) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*TaskStatus) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !this.TaskId.Equal(that1.TaskId) { + return false + } + if this.State != nil && that1.State != nil { + if *this.State != *that1.State { + return false + } + } else if this.State != nil { + return false + } else if that1.State != nil { + return false + } + if this.Message != nil && that1.Message != nil { + if *this.Message != *that1.Message { + return false + } + } else if this.Message != nil { + return false + } else if that1.Message != nil { + return false + } + if this.Source != nil && that1.Source != nil { + if *this.Source != *that1.Source { + return false + } + } else if this.Source != nil { + return false + } else if that1.Source != nil { + return false + } + if this.Reason != nil && that1.Reason != nil { + if *this.Reason != *that1.Reason { + return false + } + } else if this.Reason != nil { + return false + } else if that1.Reason != nil { + return false + } + if !bytes.Equal(this.Data, that1.Data) { + return false + } + if !this.SlaveId.Equal(that1.SlaveId) { + return false + } + if !this.ExecutorId.Equal(that1.ExecutorId) { + return false + } + if this.Timestamp != nil && that1.Timestamp != nil { + if *this.Timestamp != *that1.Timestamp { + return false + } + } else if this.Timestamp != nil { + return false + } else if that1.Timestamp != nil { + return false + } + if !bytes.Equal(this.Uuid, that1.Uuid) { + return false + } + if this.Healthy != nil && that1.Healthy != nil { + if *this.Healthy != *that1.Healthy { + return false + } + } else if this.Healthy != nil { + return false + } else if that1.Healthy != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Filters) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Filters) + if !ok { + return fmt.Errorf("that is not of type *Filters") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Filters but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Filtersbut is not nil && this == nil") + } + if this.RefuseSeconds != nil && that1.RefuseSeconds != nil { + if *this.RefuseSeconds != *that1.RefuseSeconds { + return fmt.Errorf("RefuseSeconds this(%v) Not Equal that(%v)", *this.RefuseSeconds, *that1.RefuseSeconds) + } + } else if this.RefuseSeconds != nil { + return fmt.Errorf("this.RefuseSeconds == nil && that.RefuseSeconds != nil") + } else if that1.RefuseSeconds != nil { + return fmt.Errorf("RefuseSeconds this(%v) Not Equal that(%v)", this.RefuseSeconds, that1.RefuseSeconds) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Filters) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Filters) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.RefuseSeconds != nil && that1.RefuseSeconds != nil { + if *this.RefuseSeconds != *that1.RefuseSeconds { + return false + } + } else if this.RefuseSeconds != nil { + return false + } else if that1.RefuseSeconds != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Environment) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Environment) + if !ok { + return fmt.Errorf("that is not of type *Environment") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Environment but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Environmentbut is not nil && this == nil") + } + if len(this.Variables) != len(that1.Variables) { + return fmt.Errorf("Variables this(%v) Not Equal that(%v)", len(this.Variables), len(that1.Variables)) + } + for i := range this.Variables { + if !this.Variables[i].Equal(that1.Variables[i]) { + return fmt.Errorf("Variables this[%v](%v) Not Equal that[%v](%v)", i, this.Variables[i], i, that1.Variables[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Environment) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Environment) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.Variables) != len(that1.Variables) { + return false + } + for i := range this.Variables { + if !this.Variables[i].Equal(that1.Variables[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Environment_Variable) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Environment_Variable) + if !ok { + return fmt.Errorf("that is not of type *Environment_Variable") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Environment_Variable but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Environment_Variablebut is not nil && this == nil") + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) + } + } else if this.Name != nil { + return fmt.Errorf("this.Name == nil && that.Name != nil") + } else if that1.Name != nil { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Environment_Variable) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Environment_Variable) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return false + } + } else if this.Name != nil { + return false + } else if that1.Name != nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Parameter) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Parameter) + if !ok { + return fmt.Errorf("that is not of type *Parameter") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Parameter but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Parameterbut is not nil && this == nil") + } + if this.Key != nil && that1.Key != nil { + if *this.Key != *that1.Key { + return fmt.Errorf("Key this(%v) Not Equal that(%v)", *this.Key, *that1.Key) + } + } else if this.Key != nil { + return fmt.Errorf("this.Key == nil && that.Key != nil") + } else if that1.Key != nil { + return fmt.Errorf("Key this(%v) Not Equal that(%v)", this.Key, that1.Key) + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Parameter) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Parameter) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Key != nil && that1.Key != nil { + if *this.Key != *that1.Key { + return false + } + } else if this.Key != nil { + return false + } else if that1.Key != nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Parameters) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Parameters) + if !ok { + return fmt.Errorf("that is not of type *Parameters") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Parameters but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Parametersbut is not nil && this == nil") + } + if len(this.Parameter) != len(that1.Parameter) { + return fmt.Errorf("Parameter this(%v) Not Equal that(%v)", len(this.Parameter), len(that1.Parameter)) + } + for i := range this.Parameter { + if !this.Parameter[i].Equal(that1.Parameter[i]) { + return fmt.Errorf("Parameter this[%v](%v) Not Equal that[%v](%v)", i, this.Parameter[i], i, that1.Parameter[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Parameters) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Parameters) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.Parameter) != len(that1.Parameter) { + return false + } + for i := range this.Parameter { + if !this.Parameter[i].Equal(that1.Parameter[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Credential) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Credential) + if !ok { + return fmt.Errorf("that is not of type *Credential") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Credential but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Credentialbut is not nil && this == nil") + } + if this.Principal != nil && that1.Principal != nil { + if *this.Principal != *that1.Principal { + return fmt.Errorf("Principal this(%v) Not Equal that(%v)", *this.Principal, *that1.Principal) + } + } else if this.Principal != nil { + return fmt.Errorf("this.Principal == nil && that.Principal != nil") + } else if that1.Principal != nil { + return fmt.Errorf("Principal this(%v) Not Equal that(%v)", this.Principal, that1.Principal) + } + if !bytes.Equal(this.Secret, that1.Secret) { + return fmt.Errorf("Secret this(%v) Not Equal that(%v)", this.Secret, that1.Secret) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Credential) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Credential) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Principal != nil && that1.Principal != nil { + if *this.Principal != *that1.Principal { + return false + } + } else if this.Principal != nil { + return false + } else if that1.Principal != nil { + return false + } + if !bytes.Equal(this.Secret, that1.Secret) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Credentials) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Credentials) + if !ok { + return fmt.Errorf("that is not of type *Credentials") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Credentials but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Credentialsbut is not nil && this == nil") + } + if len(this.Credentials) != len(that1.Credentials) { + return fmt.Errorf("Credentials this(%v) Not Equal that(%v)", len(this.Credentials), len(that1.Credentials)) + } + for i := range this.Credentials { + if !this.Credentials[i].Equal(that1.Credentials[i]) { + return fmt.Errorf("Credentials this[%v](%v) Not Equal that[%v](%v)", i, this.Credentials[i], i, that1.Credentials[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *Credentials) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*Credentials) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.Credentials) != len(that1.Credentials) { + return false + } + for i := range this.Credentials { + if !this.Credentials[i].Equal(that1.Credentials[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *ACL) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ACL) + if !ok { + return fmt.Errorf("that is not of type *ACL") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ACL but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ACLbut is not nil && this == nil") + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *ACL) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*ACL) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *ACL_Entity) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ACL_Entity) + if !ok { + return fmt.Errorf("that is not of type *ACL_Entity") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ACL_Entity but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ACL_Entitybut is not nil && this == nil") + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) + } + } else if this.Type != nil { + return fmt.Errorf("this.Type == nil && that.Type != nil") + } else if that1.Type != nil { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + } + if len(this.Values) != len(that1.Values) { + return fmt.Errorf("Values this(%v) Not Equal that(%v)", len(this.Values), len(that1.Values)) + } + for i := range this.Values { + if this.Values[i] != that1.Values[i] { + return fmt.Errorf("Values this[%v](%v) Not Equal that[%v](%v)", i, this.Values[i], i, that1.Values[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *ACL_Entity) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*ACL_Entity) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return false + } + } else if this.Type != nil { + return false + } else if that1.Type != nil { + return false + } + if len(this.Values) != len(that1.Values) { + return false + } + for i := range this.Values { + if this.Values[i] != that1.Values[i] { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *ACL_RegisterFramework) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ACL_RegisterFramework) + if !ok { + return fmt.Errorf("that is not of type *ACL_RegisterFramework") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ACL_RegisterFramework but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ACL_RegisterFrameworkbut is not nil && this == nil") + } + if !this.Principals.Equal(that1.Principals) { + return fmt.Errorf("Principals this(%v) Not Equal that(%v)", this.Principals, that1.Principals) + } + if !this.Roles.Equal(that1.Roles) { + return fmt.Errorf("Roles this(%v) Not Equal that(%v)", this.Roles, that1.Roles) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *ACL_RegisterFramework) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*ACL_RegisterFramework) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !this.Principals.Equal(that1.Principals) { + return false + } + if !this.Roles.Equal(that1.Roles) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *ACL_RunTask) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ACL_RunTask) + if !ok { + return fmt.Errorf("that is not of type *ACL_RunTask") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ACL_RunTask but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ACL_RunTaskbut is not nil && this == nil") + } + if !this.Principals.Equal(that1.Principals) { + return fmt.Errorf("Principals this(%v) Not Equal that(%v)", this.Principals, that1.Principals) + } + if !this.Users.Equal(that1.Users) { + return fmt.Errorf("Users this(%v) Not Equal that(%v)", this.Users, that1.Users) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *ACL_RunTask) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*ACL_RunTask) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !this.Principals.Equal(that1.Principals) { + return false + } + if !this.Users.Equal(that1.Users) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *ACL_ShutdownFramework) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ACL_ShutdownFramework) + if !ok { + return fmt.Errorf("that is not of type *ACL_ShutdownFramework") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ACL_ShutdownFramework but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ACL_ShutdownFrameworkbut is not nil && this == nil") + } + if !this.Principals.Equal(that1.Principals) { + return fmt.Errorf("Principals this(%v) Not Equal that(%v)", this.Principals, that1.Principals) + } + if !this.FrameworkPrincipals.Equal(that1.FrameworkPrincipals) { + return fmt.Errorf("FrameworkPrincipals this(%v) Not Equal that(%v)", this.FrameworkPrincipals, that1.FrameworkPrincipals) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *ACL_ShutdownFramework) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*ACL_ShutdownFramework) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if !this.Principals.Equal(that1.Principals) { + return false + } + if !this.FrameworkPrincipals.Equal(that1.FrameworkPrincipals) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *ACLs) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ACLs) + if !ok { + return fmt.Errorf("that is not of type *ACLs") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ACLs but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ACLsbut is not nil && this == nil") + } + if this.Permissive != nil && that1.Permissive != nil { + if *this.Permissive != *that1.Permissive { + return fmt.Errorf("Permissive this(%v) Not Equal that(%v)", *this.Permissive, *that1.Permissive) + } + } else if this.Permissive != nil { + return fmt.Errorf("this.Permissive == nil && that.Permissive != nil") + } else if that1.Permissive != nil { + return fmt.Errorf("Permissive this(%v) Not Equal that(%v)", this.Permissive, that1.Permissive) + } + if len(this.RegisterFrameworks) != len(that1.RegisterFrameworks) { + return fmt.Errorf("RegisterFrameworks this(%v) Not Equal that(%v)", len(this.RegisterFrameworks), len(that1.RegisterFrameworks)) + } + for i := range this.RegisterFrameworks { + if !this.RegisterFrameworks[i].Equal(that1.RegisterFrameworks[i]) { + return fmt.Errorf("RegisterFrameworks this[%v](%v) Not Equal that[%v](%v)", i, this.RegisterFrameworks[i], i, that1.RegisterFrameworks[i]) + } + } + if len(this.RunTasks) != len(that1.RunTasks) { + return fmt.Errorf("RunTasks this(%v) Not Equal that(%v)", len(this.RunTasks), len(that1.RunTasks)) + } + for i := range this.RunTasks { + if !this.RunTasks[i].Equal(that1.RunTasks[i]) { + return fmt.Errorf("RunTasks this[%v](%v) Not Equal that[%v](%v)", i, this.RunTasks[i], i, that1.RunTasks[i]) + } + } + if len(this.ShutdownFrameworks) != len(that1.ShutdownFrameworks) { + return fmt.Errorf("ShutdownFrameworks this(%v) Not Equal that(%v)", len(this.ShutdownFrameworks), len(that1.ShutdownFrameworks)) + } + for i := range this.ShutdownFrameworks { + if !this.ShutdownFrameworks[i].Equal(that1.ShutdownFrameworks[i]) { + return fmt.Errorf("ShutdownFrameworks this[%v](%v) Not Equal that[%v](%v)", i, this.ShutdownFrameworks[i], i, that1.ShutdownFrameworks[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *ACLs) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } + + that1, ok := that.(*ACLs) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Permissive != nil && that1.Permissive != nil { + if *this.Permissive != *that1.Permissive { + return false + } + } else if this.Permissive != nil { + return false + } else if that1.Permissive != nil { + return false + } + if len(this.RegisterFrameworks) != len(that1.RegisterFrameworks) { + return false + } + for i := range this.RegisterFrameworks { + if !this.RegisterFrameworks[i].Equal(that1.RegisterFrameworks[i]) { + return false + } + } + if len(this.RunTasks) != len(that1.RunTasks) { + return false + } + for i := range this.RunTasks { + if !this.RunTasks[i].Equal(that1.RunTasks[i]) { + return false + } + } + if len(this.ShutdownFrameworks) != len(that1.ShutdownFrameworks) { + return false + } + for i := range this.ShutdownFrameworks { + if !this.ShutdownFrameworks[i].Equal(that1.ShutdownFrameworks[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *RateLimit) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*RateLimit) + if !ok { + return fmt.Errorf("that is not of type *RateLimit") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *RateLimit but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *RateLimitbut is not nil && this == nil") + } + if this.Qps != nil && that1.Qps != nil { + if *this.Qps != *that1.Qps { + return fmt.Errorf("Qps this(%v) Not Equal that(%v)", *this.Qps, *that1.Qps) + } + } else if this.Qps != nil { + return fmt.Errorf("this.Qps == nil && that.Qps != nil") + } else if that1.Qps != nil { + return fmt.Errorf("Qps this(%v) Not Equal that(%v)", this.Qps, that1.Qps) + } + if this.Principal != nil && that1.Principal != nil { + if *this.Principal != *that1.Principal { + return fmt.Errorf("Principal this(%v) Not Equal that(%v)", *this.Principal, *that1.Principal) + } + } else if this.Principal != nil { + return fmt.Errorf("this.Principal == nil && that.Principal != nil") + } else if that1.Principal != nil { + return fmt.Errorf("Principal this(%v) Not Equal that(%v)", this.Principal, that1.Principal) + } + if this.Capacity != nil && that1.Capacity != nil { + if *this.Capacity != *that1.Capacity { + return fmt.Errorf("Capacity this(%v) Not Equal that(%v)", *this.Capacity, *that1.Capacity) + } + } else if this.Capacity != nil { + return fmt.Errorf("this.Capacity == nil && that.Capacity != nil") + } else if that1.Capacity != nil { + return fmt.Errorf("Capacity this(%v) Not Equal that(%v)", this.Capacity, that1.Capacity) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *RateLimit) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } + return false } - return nil -} -func (m *Request) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + + that1, ok := that.(*RateLimit) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SlaveId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.SlaveId == nil { - m.SlaveId = &SlaveID{} - } - if err := m.SlaveId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resources = append(m.Resources, &Resource{}) - m.Resources[len(m.Resources)-1].Unmarshal(data[index:postIndex]) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } else if this == nil { + return false + } + if this.Qps != nil && that1.Qps != nil { + if *this.Qps != *that1.Qps { + return false } + } else if this.Qps != nil { + return false + } else if that1.Qps != nil { + return false } - return nil -} -func (m *Offer) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if this.Principal != nil && that1.Principal != nil { + if *this.Principal != *that1.Principal { + return false } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Id == nil { - m.Id = &OfferID{} - } - if err := m.Id.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FrameworkId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.FrameworkId == nil { - m.FrameworkId = &FrameworkID{} - } - if err := m.FrameworkId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SlaveId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.SlaveId == nil { - m.SlaveId = &SlaveID{} - } - if err := m.SlaveId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Hostname = &s - index = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resources = append(m.Resources, &Resource{}) - m.Resources[len(m.Resources)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Attributes = append(m.Attributes, &Attribute{}) - m.Attributes[len(m.Attributes)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExecutorIds", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ExecutorIds = append(m.ExecutorIds, &ExecutorID{}) - m.ExecutorIds[len(m.ExecutorIds)-1].Unmarshal(data[index:postIndex]) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } else if this.Principal != nil { + return false + } else if that1.Principal != nil { + return false + } + if this.Capacity != nil && that1.Capacity != nil { + if *this.Capacity != *that1.Capacity { + return false + } + } else if this.Capacity != nil { + return false + } else if that1.Capacity != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *RateLimits) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*RateLimits) + if !ok { + return fmt.Errorf("that is not of type *RateLimits") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *RateLimits but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *RateLimitsbut is not nil && this == nil") + } + if len(this.Limits) != len(that1.Limits) { + return fmt.Errorf("Limits this(%v) Not Equal that(%v)", len(this.Limits), len(that1.Limits)) + } + for i := range this.Limits { + if !this.Limits[i].Equal(that1.Limits[i]) { + return fmt.Errorf("Limits this[%v](%v) Not Equal that[%v](%v)", i, this.Limits[i], i, that1.Limits[i]) + } + } + if this.AggregateDefaultQps != nil && that1.AggregateDefaultQps != nil { + if *this.AggregateDefaultQps != *that1.AggregateDefaultQps { + return fmt.Errorf("AggregateDefaultQps this(%v) Not Equal that(%v)", *this.AggregateDefaultQps, *that1.AggregateDefaultQps) + } + } else if this.AggregateDefaultQps != nil { + return fmt.Errorf("this.AggregateDefaultQps == nil && that.AggregateDefaultQps != nil") + } else if that1.AggregateDefaultQps != nil { + return fmt.Errorf("AggregateDefaultQps this(%v) Not Equal that(%v)", this.AggregateDefaultQps, that1.AggregateDefaultQps) + } + if this.AggregateDefaultCapacity != nil && that1.AggregateDefaultCapacity != nil { + if *this.AggregateDefaultCapacity != *that1.AggregateDefaultCapacity { + return fmt.Errorf("AggregateDefaultCapacity this(%v) Not Equal that(%v)", *this.AggregateDefaultCapacity, *that1.AggregateDefaultCapacity) } + } else if this.AggregateDefaultCapacity != nil { + return fmt.Errorf("this.AggregateDefaultCapacity == nil && that.AggregateDefaultCapacity != nil") + } else if that1.AggregateDefaultCapacity != nil { + return fmt.Errorf("AggregateDefaultCapacity this(%v) Not Equal that(%v)", this.AggregateDefaultCapacity, that1.AggregateDefaultCapacity) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *TaskInfo) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *RateLimits) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Name = &s - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TaskId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TaskId == nil { - m.TaskId = &TaskID{} - } - if err := m.TaskId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SlaveId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.SlaveId == nil { - m.SlaveId = &SlaveID{} - } - if err := m.SlaveId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resources = append(m.Resources, &Resource{}) - m.Resources[len(m.Resources)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Executor", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Executor == nil { - m.Executor = &ExecutorInfo{} - } - if err := m.Executor.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Command", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Command == nil { - m.Command = &CommandInfo{} - } - if err := m.Command.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Container == nil { - m.Container = &ContainerInfo{} - } - if err := m.Container.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append([]byte{}, data[index:postIndex]...) - index = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HealthCheck", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.HealthCheck == nil { - m.HealthCheck = &HealthCheck{} - } - if err := m.HealthCheck.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*RateLimits) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false } - return nil + if len(this.Limits) != len(that1.Limits) { + return false + } + for i := range this.Limits { + if !this.Limits[i].Equal(that1.Limits[i]) { + return false + } + } + if this.AggregateDefaultQps != nil && that1.AggregateDefaultQps != nil { + if *this.AggregateDefaultQps != *that1.AggregateDefaultQps { + return false + } + } else if this.AggregateDefaultQps != nil { + return false + } else if that1.AggregateDefaultQps != nil { + return false + } + if this.AggregateDefaultCapacity != nil && that1.AggregateDefaultCapacity != nil { + if *this.AggregateDefaultCapacity != *that1.AggregateDefaultCapacity { + return false + } + } else if this.AggregateDefaultCapacity != nil { + return false + } else if that1.AggregateDefaultCapacity != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *TaskStatus) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Volume) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TaskId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TaskId == nil { - m.TaskId = &TaskID{} - } - if err := m.TaskId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) - } - var v TaskState - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (TaskState(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.State = &v - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Message = &s - index = postIndex - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) - } - var v TaskStatus_Source - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (TaskStatus_Source(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Source = &v - case 10: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) - } - var v TaskStatus_Reason - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (TaskStatus_Reason(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Reason = &v - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append([]byte{}, data[index:postIndex]...) - index = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SlaveId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.SlaveId == nil { - m.SlaveId = &SlaveID{} - } - if err := m.SlaveId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExecutorId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ExecutorId == nil { - m.ExecutorId = &ExecutorID{} - } - if err := m.ExecutorId.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 6: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.Timestamp = &v2 - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Healthy", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Healthy = &b - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Volume) + if !ok { + return fmt.Errorf("that is not of type *Volume") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Volume but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Volumebut is not nil && this == nil") + } + if this.ContainerPath != nil && that1.ContainerPath != nil { + if *this.ContainerPath != *that1.ContainerPath { + return fmt.Errorf("ContainerPath this(%v) Not Equal that(%v)", *this.ContainerPath, *that1.ContainerPath) + } + } else if this.ContainerPath != nil { + return fmt.Errorf("this.ContainerPath == nil && that.ContainerPath != nil") + } else if that1.ContainerPath != nil { + return fmt.Errorf("ContainerPath this(%v) Not Equal that(%v)", this.ContainerPath, that1.ContainerPath) + } + if this.HostPath != nil && that1.HostPath != nil { + if *this.HostPath != *that1.HostPath { + return fmt.Errorf("HostPath this(%v) Not Equal that(%v)", *this.HostPath, *that1.HostPath) + } + } else if this.HostPath != nil { + return fmt.Errorf("this.HostPath == nil && that.HostPath != nil") + } else if that1.HostPath != nil { + return fmt.Errorf("HostPath this(%v) Not Equal that(%v)", this.HostPath, that1.HostPath) + } + if this.Mode != nil && that1.Mode != nil { + if *this.Mode != *that1.Mode { + return fmt.Errorf("Mode this(%v) Not Equal that(%v)", *this.Mode, *that1.Mode) } + } else if this.Mode != nil { + return fmt.Errorf("this.Mode == nil && that.Mode != nil") + } else if that1.Mode != nil { + return fmt.Errorf("Mode this(%v) Not Equal that(%v)", this.Mode, that1.Mode) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *Filters) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - 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) - switch fieldNum { - case 1: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field RefuseSeconds", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.RefuseSeconds = &v2 - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy +func (this *Volume) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } + return false } - return nil -} -func (m *Environment) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + + that1, ok := that.(*Volume) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Variables", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Variables = append(m.Variables, &Environment_Variable{}) - m.Variables[len(m.Variables)-1].Unmarshal(data[index:postIndex]) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } else if this == nil { + return false + } + if this.ContainerPath != nil && that1.ContainerPath != nil { + if *this.ContainerPath != *that1.ContainerPath { + return false } + } else if this.ContainerPath != nil { + return false + } else if that1.ContainerPath != nil { + return false } - return nil -} -func (m *Environment_Variable) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if this.HostPath != nil && that1.HostPath != nil { + if *this.HostPath != *that1.HostPath { + return false } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Name = &s - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Value = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } else if this.HostPath != nil { + return false + } else if that1.HostPath != nil { + return false + } + if this.Mode != nil && that1.Mode != nil { + if *this.Mode != *that1.Mode { + return false } + } else if this.Mode != nil { + return false + } else if that1.Mode != nil { + return false } - return nil + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *Parameter) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - 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) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Key = &s - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Value = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy +func (this *ContainerInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } + return fmt.Errorf("that == nil && this != nil") } - return nil -} -func (m *Parameters) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + + that1, ok := that.(*ContainerInfo) + if !ok { + return fmt.Errorf("that is not of type *ContainerInfo") + } + if that1 == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Parameter", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Parameter = append(m.Parameter, &Parameter{}) - m.Parameter[len(m.Parameter)-1].Unmarshal(data[index:postIndex]) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that is type *ContainerInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ContainerInfobut is not nil && this == nil") + } + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) } + } else if this.Type != nil { + return fmt.Errorf("this.Type == nil && that.Type != nil") + } else if that1.Type != nil { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) } - return nil -} -func (m *Credential) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if len(this.Volumes) != len(that1.Volumes) { + return fmt.Errorf("Volumes this(%v) Not Equal that(%v)", len(this.Volumes), len(that1.Volumes)) + } + for i := range this.Volumes { + if !this.Volumes[i].Equal(that1.Volumes[i]) { + return fmt.Errorf("Volumes this[%v](%v) Not Equal that[%v](%v)", i, this.Volumes[i], i, that1.Volumes[i]) } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Principal", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Principal = &s - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Secret", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Secret = append([]byte{}, data[index:postIndex]...) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } + if this.Hostname != nil && that1.Hostname != nil { + if *this.Hostname != *that1.Hostname { + return fmt.Errorf("Hostname this(%v) Not Equal that(%v)", *this.Hostname, *that1.Hostname) } + } else if this.Hostname != nil { + return fmt.Errorf("this.Hostname == nil && that.Hostname != nil") + } else if that1.Hostname != nil { + return fmt.Errorf("Hostname this(%v) Not Equal that(%v)", this.Hostname, that1.Hostname) + } + if !this.Docker.Equal(that1.Docker) { + return fmt.Errorf("Docker this(%v) Not Equal that(%v)", this.Docker, that1.Docker) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *Credentials) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *ContainerInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Credentials", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Credentials = append(m.Credentials, &Credential{}) - m.Credentials[len(m.Credentials)-1].Unmarshal(data[index:postIndex]) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*ContainerInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false } - return nil + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return false + } + } else if this.Type != nil { + return false + } else if that1.Type != nil { + return false + } + if len(this.Volumes) != len(that1.Volumes) { + return false + } + for i := range this.Volumes { + if !this.Volumes[i].Equal(that1.Volumes[i]) { + return false + } + } + if this.Hostname != nil && that1.Hostname != nil { + if *this.Hostname != *that1.Hostname { + return false + } + } else if this.Hostname != nil { + return false + } else if that1.Hostname != nil { + return false + } + if !this.Docker.Equal(that1.Docker) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *ACL) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *ContainerInfo_DockerInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ContainerInfo_DockerInfo) + if !ok { + return fmt.Errorf("that is not of type *ContainerInfo_DockerInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ContainerInfo_DockerInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ContainerInfo_DockerInfobut is not nil && this == nil") + } + if this.Image != nil && that1.Image != nil { + if *this.Image != *that1.Image { + return fmt.Errorf("Image this(%v) Not Equal that(%v)", *this.Image, *that1.Image) } - fieldNum := int32(wire >> 3) - switch fieldNum { - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } else if this.Image != nil { + return fmt.Errorf("this.Image == nil && that.Image != nil") + } else if that1.Image != nil { + return fmt.Errorf("Image this(%v) Not Equal that(%v)", this.Image, that1.Image) + } + if this.Network != nil && that1.Network != nil { + if *this.Network != *that1.Network { + return fmt.Errorf("Network this(%v) Not Equal that(%v)", *this.Network, *that1.Network) } + } else if this.Network != nil { + return fmt.Errorf("this.Network == nil && that.Network != nil") + } else if that1.Network != nil { + return fmt.Errorf("Network this(%v) Not Equal that(%v)", this.Network, that1.Network) } - return nil -} -func (m *ACL_Entity) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if len(this.PortMappings) != len(that1.PortMappings) { + return fmt.Errorf("PortMappings this(%v) Not Equal that(%v)", len(this.PortMappings), len(that1.PortMappings)) + } + for i := range this.PortMappings { + if !this.PortMappings[i].Equal(that1.PortMappings[i]) { + return fmt.Errorf("PortMappings this[%v](%v) Not Equal that[%v](%v)", i, this.PortMappings[i], i, that1.PortMappings[i]) } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var v ACL_Entity_Type - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (ACL_Entity_Type(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Type = &v - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Values = append(m.Values, string(data[index:postIndex])) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } + if this.Privileged != nil && that1.Privileged != nil { + if *this.Privileged != *that1.Privileged { + return fmt.Errorf("Privileged this(%v) Not Equal that(%v)", *this.Privileged, *that1.Privileged) } + } else if this.Privileged != nil { + return fmt.Errorf("this.Privileged == nil && that.Privileged != nil") + } else if that1.Privileged != nil { + return fmt.Errorf("Privileged this(%v) Not Equal that(%v)", this.Privileged, that1.Privileged) } - return nil -} -func (m *ACL_RegisterFramework) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + if len(this.Parameters) != len(that1.Parameters) { + return fmt.Errorf("Parameters this(%v) Not Equal that(%v)", len(this.Parameters), len(that1.Parameters)) + } + for i := range this.Parameters { + if !this.Parameters[i].Equal(that1.Parameters[i]) { + return fmt.Errorf("Parameters this[%v](%v) Not Equal that[%v](%v)", i, this.Parameters[i], i, that1.Parameters[i]) } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Principals", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Principals == nil { - m.Principals = &ACL_Entity{} - } - if err := m.Principals.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Roles == nil { - m.Roles = &ACL_Entity{} - } - if err := m.Roles.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + } + if this.ForcePullImage != nil && that1.ForcePullImage != nil { + if *this.ForcePullImage != *that1.ForcePullImage { + return fmt.Errorf("ForcePullImage this(%v) Not Equal that(%v)", *this.ForcePullImage, *that1.ForcePullImage) } + } else if this.ForcePullImage != nil { + return fmt.Errorf("this.ForcePullImage == nil && that.ForcePullImage != nil") + } else if that1.ForcePullImage != nil { + return fmt.Errorf("ForcePullImage this(%v) Not Equal that(%v)", this.ForcePullImage, that1.ForcePullImage) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *ACL_RunTask) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *ContainerInfo_DockerInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Principals", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Principals == nil { - m.Principals = &ACL_Entity{} - } - if err := m.Principals.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Users", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Users == nil { - m.Users = &ACL_Entity{} - } - if err := m.Users.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*ContainerInfo_DockerInfo) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false } - return nil + if this.Image != nil && that1.Image != nil { + if *this.Image != *that1.Image { + return false + } + } else if this.Image != nil { + return false + } else if that1.Image != nil { + return false + } + if this.Network != nil && that1.Network != nil { + if *this.Network != *that1.Network { + return false + } + } else if this.Network != nil { + return false + } else if that1.Network != nil { + return false + } + if len(this.PortMappings) != len(that1.PortMappings) { + return false + } + for i := range this.PortMappings { + if !this.PortMappings[i].Equal(that1.PortMappings[i]) { + return false + } + } + if this.Privileged != nil && that1.Privileged != nil { + if *this.Privileged != *that1.Privileged { + return false + } + } else if this.Privileged != nil { + return false + } else if that1.Privileged != nil { + return false + } + if len(this.Parameters) != len(that1.Parameters) { + return false + } + for i := range this.Parameters { + if !this.Parameters[i].Equal(that1.Parameters[i]) { + return false + } + } + if this.ForcePullImage != nil && that1.ForcePullImage != nil { + if *this.ForcePullImage != *that1.ForcePullImage { + return false + } + } else if this.ForcePullImage != nil { + return false + } else if that1.ForcePullImage != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *ACL_ShutdownFramework) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *ContainerInfo_DockerInfo_PortMapping) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Principals", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Principals == nil { - m.Principals = &ACL_Entity{} - } - if err := m.Principals.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FrameworkPrincipals", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.FrameworkPrincipals == nil { - m.FrameworkPrincipals = &ACL_Entity{} - } - if err := m.FrameworkPrincipals.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*ContainerInfo_DockerInfo_PortMapping) + if !ok { + return fmt.Errorf("that is not of type *ContainerInfo_DockerInfo_PortMapping") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *ContainerInfo_DockerInfo_PortMapping but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *ContainerInfo_DockerInfo_PortMappingbut is not nil && this == nil") + } + if this.HostPort != nil && that1.HostPort != nil { + if *this.HostPort != *that1.HostPort { + return fmt.Errorf("HostPort this(%v) Not Equal that(%v)", *this.HostPort, *that1.HostPort) + } + } else if this.HostPort != nil { + return fmt.Errorf("this.HostPort == nil && that.HostPort != nil") + } else if that1.HostPort != nil { + return fmt.Errorf("HostPort this(%v) Not Equal that(%v)", this.HostPort, that1.HostPort) + } + if this.ContainerPort != nil && that1.ContainerPort != nil { + if *this.ContainerPort != *that1.ContainerPort { + return fmt.Errorf("ContainerPort this(%v) Not Equal that(%v)", *this.ContainerPort, *that1.ContainerPort) + } + } else if this.ContainerPort != nil { + return fmt.Errorf("this.ContainerPort == nil && that.ContainerPort != nil") + } else if that1.ContainerPort != nil { + return fmt.Errorf("ContainerPort this(%v) Not Equal that(%v)", this.ContainerPort, that1.ContainerPort) + } + if this.Protocol != nil && that1.Protocol != nil { + if *this.Protocol != *that1.Protocol { + return fmt.Errorf("Protocol this(%v) Not Equal that(%v)", *this.Protocol, *that1.Protocol) } + } else if this.Protocol != nil { + return fmt.Errorf("this.Protocol == nil && that.Protocol != nil") + } else if that1.Protocol != nil { + return fmt.Errorf("Protocol this(%v) Not Equal that(%v)", this.Protocol, that1.Protocol) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *ACLs) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - 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) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Permissive", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Permissive = &b - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RegisterFrameworks", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.RegisterFrameworks = append(m.RegisterFrameworks, &ACL_RegisterFramework{}) - m.RegisterFrameworks[len(m.RegisterFrameworks)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RunTasks", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.RunTasks = append(m.RunTasks, &ACL_RunTask{}) - m.RunTasks[len(m.RunTasks)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ShutdownFrameworks", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ShutdownFrameworks = append(m.ShutdownFrameworks, &ACL_ShutdownFramework{}) - m.ShutdownFrameworks[len(m.ShutdownFrameworks)-1].Unmarshal(data[index:postIndex]) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy +func (this *ContainerInfo_DockerInfo_PortMapping) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } + return false + } + + that1, ok := that.(*ContainerInfo_DockerInfo_PortMapping) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.HostPort != nil && that1.HostPort != nil { + if *this.HostPort != *that1.HostPort { + return false + } + } else if this.HostPort != nil { + return false + } else if that1.HostPort != nil { + return false + } + if this.ContainerPort != nil && that1.ContainerPort != nil { + if *this.ContainerPort != *that1.ContainerPort { + return false + } + } else if this.ContainerPort != nil { + return false + } else if that1.ContainerPort != nil { + return false + } + if this.Protocol != nil && that1.Protocol != nil { + if *this.Protocol != *that1.Protocol { + return false + } + } else if this.Protocol != nil { + return false + } else if that1.Protocol != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Labels) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Labels) + if !ok { + return fmt.Errorf("that is not of type *Labels") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Labels but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Labelsbut is not nil && this == nil") + } + if len(this.Labels) != len(that1.Labels) { + return fmt.Errorf("Labels this(%v) Not Equal that(%v)", len(this.Labels), len(that1.Labels)) + } + for i := range this.Labels { + if !this.Labels[i].Equal(that1.Labels[i]) { + return fmt.Errorf("Labels this[%v](%v) Not Equal that[%v](%v)", i, this.Labels[i], i, that1.Labels[i]) + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *RateLimit) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Labels) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field Qps", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.Qps = &v2 - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Principal", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Principal = &s - index = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Capacity", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Capacity = &v - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*Labels) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if len(this.Labels) != len(that1.Labels) { + return false + } + for i := range this.Labels { + if !this.Labels[i].Equal(that1.Labels[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Label) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Label) + if !ok { + return fmt.Errorf("that is not of type *Label") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Label but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Labelbut is not nil && this == nil") + } + if this.Key != nil && that1.Key != nil { + if *this.Key != *that1.Key { + return fmt.Errorf("Key this(%v) Not Equal that(%v)", *this.Key, *that1.Key) + } + } else if this.Key != nil { + return fmt.Errorf("this.Key == nil && that.Key != nil") + } else if that1.Key != nil { + return fmt.Errorf("Key this(%v) Not Equal that(%v)", this.Key, that1.Key) + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) } + } else if this.Value != nil { + return fmt.Errorf("this.Value == nil && that.Value != nil") + } else if that1.Value != nil { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *RateLimits) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Label) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Limits", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Limits = append(m.Limits, &RateLimit{}) - m.Limits[len(m.Limits)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 2: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field AggregateDefaultQps", wireType) - } - var v uint64 - i := index + 8 - if i > l { - return io.ErrUnexpectedEOF - } - index = i - v = uint64(data[i-8]) - v |= uint64(data[i-7]) << 8 - v |= uint64(data[i-6]) << 16 - v |= uint64(data[i-5]) << 24 - v |= uint64(data[i-4]) << 32 - v |= uint64(data[i-3]) << 40 - v |= uint64(data[i-2]) << 48 - v |= uint64(data[i-1]) << 56 - v2 := math1.Float64frombits(v) - m.AggregateDefaultQps = &v2 - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AggregateDefaultCapacity", wireType) - } - var v uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.AggregateDefaultCapacity = &v - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*Label) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false } - return nil + if this.Key != nil && that1.Key != nil { + if *this.Key != *that1.Key { + return false + } + } else if this.Key != nil { + return false + } else if that1.Key != nil { + return false + } + if this.Value != nil && that1.Value != nil { + if *this.Value != *that1.Value { + return false + } + } else if this.Value != nil { + return false + } else if that1.Value != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *Volume) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Port) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContainerPath", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.ContainerPath = &s - index = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HostPath", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.HostPath = &s - index = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) - } - var v Volume_Mode - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (Volume_Mode(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Mode = &v - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Port) + if !ok { + return fmt.Errorf("that is not of type *Port") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Port but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Portbut is not nil && this == nil") + } + if this.Number != nil && that1.Number != nil { + if *this.Number != *that1.Number { + return fmt.Errorf("Number this(%v) Not Equal that(%v)", *this.Number, *that1.Number) + } + } else if this.Number != nil { + return fmt.Errorf("this.Number == nil && that.Number != nil") + } else if that1.Number != nil { + return fmt.Errorf("Number this(%v) Not Equal that(%v)", this.Number, that1.Number) + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) } + } else if this.Name != nil { + return fmt.Errorf("this.Name == nil && that.Name != nil") + } else if that1.Name != nil { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + } + if this.Protocol != nil && that1.Protocol != nil { + if *this.Protocol != *that1.Protocol { + return fmt.Errorf("Protocol this(%v) Not Equal that(%v)", *this.Protocol, *that1.Protocol) + } + } else if this.Protocol != nil { + return fmt.Errorf("this.Protocol == nil && that.Protocol != nil") + } else if that1.Protocol != nil { + return fmt.Errorf("Protocol this(%v) Not Equal that(%v)", this.Protocol, that1.Protocol) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *ContainerInfo) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Port) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var v ContainerInfo_Type - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (ContainerInfo_Type(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Type = &v - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Volumes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Volumes = append(m.Volumes, &Volume{}) - m.Volumes[len(m.Volumes)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Hostname = &s - index = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Docker", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Docker == nil { - m.Docker = &ContainerInfo_DockerInfo{} - } - if err := m.Docker.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*Port) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false + } + if this.Number != nil && that1.Number != nil { + if *this.Number != *that1.Number { + return false + } + } else if this.Number != nil { + return false + } else if that1.Number != nil { + return false + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return false + } + } else if this.Name != nil { + return false + } else if that1.Name != nil { + return false + } + if this.Protocol != nil && that1.Protocol != nil { + if *this.Protocol != *that1.Protocol { + return false } + } else if this.Protocol != nil { + return false + } else if that1.Protocol != nil { + return false } - return nil + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (m *ContainerInfo_DockerInfo) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Ports) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Image", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Image = &s - index = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Network", wireType) - } - var v ContainerInfo_DockerInfo_Network - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (ContainerInfo_DockerInfo_Network(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Network = &v - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PortMappings", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.PortMappings = append(m.PortMappings, &ContainerInfo_DockerInfo_PortMapping{}) - m.PortMappings[len(m.PortMappings)-1].Unmarshal(data[index:postIndex]) - index = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Privileged", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Privileged = &b - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Parameters = append(m.Parameters, &Parameter{}) - m.Parameters[len(m.Parameters)-1].Unmarshal(data[index:postIndex]) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*Ports) + if !ok { + return fmt.Errorf("that is not of type *Ports") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Ports but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Portsbut is not nil && this == nil") + } + if len(this.Ports) != len(that1.Ports) { + return fmt.Errorf("Ports this(%v) Not Equal that(%v)", len(this.Ports), len(that1.Ports)) + } + for i := range this.Ports { + if !this.Ports[i].Equal(that1.Ports[i]) { + return fmt.Errorf("Ports this[%v](%v) Not Equal that[%v](%v)", i, this.Ports[i], i, that1.Ports[i]) } } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } return nil } -func (m *ContainerInfo_DockerInfo_PortMapping) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Ports) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field HostPort", wireType) - } - var v uint32 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.HostPort = &v - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ContainerPort", wireType) - } - var v uint32 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (uint32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.ContainerPort = &v - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Protocol = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*Ports) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false } - return nil + if len(this.Ports) != len(that1.Ports) { + return false + } + for i := range this.Ports { + if !this.Ports[i].Equal(that1.Ports[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } -func (this *FrameworkID) String() string { - if this == nil { - return "nil" +func (this *DiscoveryInfo) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*DiscoveryInfo) + if !ok { + return fmt.Errorf("that is not of type *DiscoveryInfo") + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *DiscoveryInfo but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *DiscoveryInfobut is not nil && this == nil") + } + if this.Visibility != nil && that1.Visibility != nil { + if *this.Visibility != *that1.Visibility { + return fmt.Errorf("Visibility this(%v) Not Equal that(%v)", *this.Visibility, *that1.Visibility) + } + } else if this.Visibility != nil { + return fmt.Errorf("this.Visibility == nil && that.Visibility != nil") + } else if that1.Visibility != nil { + return fmt.Errorf("Visibility this(%v) Not Equal that(%v)", this.Visibility, that1.Visibility) + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) + } + } else if this.Name != nil { + return fmt.Errorf("this.Name == nil && that.Name != nil") + } else if that1.Name != nil { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) } - s := strings.Join([]string{`&FrameworkID{`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *OfferID) String() string { - if this == nil { - return "nil" + if this.Environment != nil && that1.Environment != nil { + if *this.Environment != *that1.Environment { + return fmt.Errorf("Environment this(%v) Not Equal that(%v)", *this.Environment, *that1.Environment) + } + } else if this.Environment != nil { + return fmt.Errorf("this.Environment == nil && that.Environment != nil") + } else if that1.Environment != nil { + return fmt.Errorf("Environment this(%v) Not Equal that(%v)", this.Environment, that1.Environment) } - s := strings.Join([]string{`&OfferID{`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *SlaveID) String() string { - if this == nil { - return "nil" + if this.Location != nil && that1.Location != nil { + if *this.Location != *that1.Location { + return fmt.Errorf("Location this(%v) Not Equal that(%v)", *this.Location, *that1.Location) + } + } else if this.Location != nil { + return fmt.Errorf("this.Location == nil && that.Location != nil") + } else if that1.Location != nil { + return fmt.Errorf("Location this(%v) Not Equal that(%v)", this.Location, that1.Location) } - s := strings.Join([]string{`&SlaveID{`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *TaskID) String() string { - if this == nil { - return "nil" + if this.Version != nil && that1.Version != nil { + if *this.Version != *that1.Version { + return fmt.Errorf("Version this(%v) Not Equal that(%v)", *this.Version, *that1.Version) + } + } else if this.Version != nil { + return fmt.Errorf("this.Version == nil && that.Version != nil") + } else if that1.Version != nil { + return fmt.Errorf("Version this(%v) Not Equal that(%v)", this.Version, that1.Version) } - s := strings.Join([]string{`&TaskID{`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *ExecutorID) String() string { - if this == nil { - return "nil" + if !this.Ports.Equal(that1.Ports) { + return fmt.Errorf("Ports this(%v) Not Equal that(%v)", this.Ports, that1.Ports) } - s := strings.Join([]string{`&ExecutorID{`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *ContainerID) String() string { - if this == nil { - return "nil" + if !this.Labels.Equal(that1.Labels) { + return fmt.Errorf("Labels this(%v) Not Equal that(%v)", this.Labels, that1.Labels) } - s := strings.Join([]string{`&ContainerID{`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *FrameworkInfo) String() string { - if this == nil { - return "nil" + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } - s := strings.Join([]string{`&FrameworkInfo{`, - `User:` + valueToStringMesos(this.User) + `,`, - `Name:` + valueToStringMesos(this.Name) + `,`, - `Id:` + strings.Replace(fmt1.Sprintf("%v", this.Id), "FrameworkID", "FrameworkID", 1) + `,`, - `FailoverTimeout:` + valueToStringMesos(this.FailoverTimeout) + `,`, - `Checkpoint:` + valueToStringMesos(this.Checkpoint) + `,`, - `Role:` + valueToStringMesos(this.Role) + `,`, - `Hostname:` + valueToStringMesos(this.Hostname) + `,`, - `Principal:` + valueToStringMesos(this.Principal) + `,`, - `WebuiUrl:` + valueToStringMesos(this.WebuiUrl) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + return nil } -func (this *HealthCheck) String() string { - if this == nil { - return "nil" +func (this *DiscoveryInfo) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false } - s := strings.Join([]string{`&HealthCheck{`, - `Http:` + strings.Replace(fmt1.Sprintf("%v", this.Http), "HealthCheck_HTTP", "HealthCheck_HTTP", 1) + `,`, - `DelaySeconds:` + valueToStringMesos(this.DelaySeconds) + `,`, - `IntervalSeconds:` + valueToStringMesos(this.IntervalSeconds) + `,`, - `TimeoutSeconds:` + valueToStringMesos(this.TimeoutSeconds) + `,`, - `ConsecutiveFailures:` + valueToStringMesos(this.ConsecutiveFailures) + `,`, - `GracePeriodSeconds:` + valueToStringMesos(this.GracePeriodSeconds) + `,`, - `Command:` + strings.Replace(fmt1.Sprintf("%v", this.Command), "CommandInfo", "CommandInfo", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *HealthCheck_HTTP) String() string { - if this == nil { - return "nil" + + that1, ok := that.(*DiscoveryInfo) + if !ok { + return false } - s := strings.Join([]string{`&HealthCheck_HTTP{`, - `Port:` + valueToStringMesos(this.Port) + `,`, - `Path:` + valueToStringMesos(this.Path) + `,`, - `Statuses:` + fmt1.Sprintf("%v", this.Statuses) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *CommandInfo) String() string { - if this == nil { - return "nil" + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false } - s := strings.Join([]string{`&CommandInfo{`, - `Container:` + strings.Replace(fmt1.Sprintf("%v", this.Container), "CommandInfo_ContainerInfo", "CommandInfo_ContainerInfo", 1) + `,`, - `Uris:` + strings.Replace(fmt1.Sprintf("%v", this.Uris), "CommandInfo_URI", "CommandInfo_URI", 1) + `,`, - `Environment:` + strings.Replace(fmt1.Sprintf("%v", this.Environment), "Environment", "Environment", 1) + `,`, - `Shell:` + valueToStringMesos(this.Shell) + `,`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `Arguments:` + fmt1.Sprintf("%v", this.Arguments) + `,`, - `User:` + valueToStringMesos(this.User) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *CommandInfo_URI) String() string { - if this == nil { - return "nil" + if this.Visibility != nil && that1.Visibility != nil { + if *this.Visibility != *that1.Visibility { + return false + } + } else if this.Visibility != nil { + return false + } else if that1.Visibility != nil { + return false } - s := strings.Join([]string{`&CommandInfo_URI{`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `Executable:` + valueToStringMesos(this.Executable) + `,`, - `Extract:` + valueToStringMesos(this.Extract) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *CommandInfo_ContainerInfo) String() string { - if this == nil { - return "nil" + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return false + } + } else if this.Name != nil { + return false + } else if that1.Name != nil { + return false } - s := strings.Join([]string{`&CommandInfo_ContainerInfo{`, - `Image:` + valueToStringMesos(this.Image) + `,`, - `Options:` + fmt1.Sprintf("%v", this.Options) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *ExecutorInfo) String() string { - if this == nil { - return "nil" + if this.Environment != nil && that1.Environment != nil { + if *this.Environment != *that1.Environment { + return false + } + } else if this.Environment != nil { + return false + } else if that1.Environment != nil { + return false } - s := strings.Join([]string{`&ExecutorInfo{`, - `ExecutorId:` + strings.Replace(fmt1.Sprintf("%v", this.ExecutorId), "ExecutorID", "ExecutorID", 1) + `,`, - `FrameworkId:` + strings.Replace(fmt1.Sprintf("%v", this.FrameworkId), "FrameworkID", "FrameworkID", 1) + `,`, - `Command:` + strings.Replace(fmt1.Sprintf("%v", this.Command), "CommandInfo", "CommandInfo", 1) + `,`, - `Container:` + strings.Replace(fmt1.Sprintf("%v", this.Container), "ContainerInfo", "ContainerInfo", 1) + `,`, - `Resources:` + strings.Replace(fmt1.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, - `Name:` + valueToStringMesos(this.Name) + `,`, - `Source:` + valueToStringMesos(this.Source) + `,`, - `Data:` + valueToStringMesos(this.Data) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *MasterInfo) String() string { - if this == nil { - return "nil" + if this.Location != nil && that1.Location != nil { + if *this.Location != *that1.Location { + return false + } + } else if this.Location != nil { + return false + } else if that1.Location != nil { + return false } - s := strings.Join([]string{`&MasterInfo{`, - `Id:` + valueToStringMesos(this.Id) + `,`, - `Ip:` + valueToStringMesos(this.Ip) + `,`, - `Port:` + valueToStringMesos(this.Port) + `,`, - `Pid:` + valueToStringMesos(this.Pid) + `,`, - `Hostname:` + valueToStringMesos(this.Hostname) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *SlaveInfo) String() string { - if this == nil { - return "nil" + if this.Version != nil && that1.Version != nil { + if *this.Version != *that1.Version { + return false + } + } else if this.Version != nil { + return false + } else if that1.Version != nil { + return false } - s := strings.Join([]string{`&SlaveInfo{`, - `Hostname:` + valueToStringMesos(this.Hostname) + `,`, - `Port:` + valueToStringMesos(this.Port) + `,`, - `Resources:` + strings.Replace(fmt1.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, - `Attributes:` + strings.Replace(fmt1.Sprintf("%v", this.Attributes), "Attribute", "Attribute", 1) + `,`, - `Id:` + strings.Replace(fmt1.Sprintf("%v", this.Id), "SlaveID", "SlaveID", 1) + `,`, - `Checkpoint:` + valueToStringMesos(this.Checkpoint) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Value) String() string { - if this == nil { - return "nil" + if !this.Ports.Equal(that1.Ports) { + return false } - s := strings.Join([]string{`&Value{`, - `Type:` + valueToStringMesos(this.Type) + `,`, - `Scalar:` + strings.Replace(fmt1.Sprintf("%v", this.Scalar), "Value_Scalar", "Value_Scalar", 1) + `,`, - `Ranges:` + strings.Replace(fmt1.Sprintf("%v", this.Ranges), "Value_Ranges", "Value_Ranges", 1) + `,`, - `Set:` + strings.Replace(fmt1.Sprintf("%v", this.Set), "Value_Set", "Value_Set", 1) + `,`, - `Text:` + strings.Replace(fmt1.Sprintf("%v", this.Text), "Value_Text", "Value_Text", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Value_Scalar) String() string { - if this == nil { - return "nil" + if !this.Labels.Equal(that1.Labels) { + return false } - s := strings.Join([]string{`&Value_Scalar{`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Value_Range) String() string { - if this == nil { - return "nil" + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false } - s := strings.Join([]string{`&Value_Range{`, - `Begin:` + valueToStringMesos(this.Begin) + `,`, - `End:` + valueToStringMesos(this.End) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + return true } -func (this *Value_Ranges) String() string { +func (this *FrameworkID) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Value_Ranges{`, - `Range:` + strings.Replace(fmt1.Sprintf("%v", this.Range), "Value_Range", "Value_Range", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Value_Set) String() string { - if this == nil { - return "nil" + s := make([]string, 0, 5) + s = append(s, "&mesosproto.FrameworkID{") + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") } - s := strings.Join([]string{`&Value_Set{`, - `Item:` + fmt1.Sprintf("%v", this.Item) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Value_Text) String() string { +func (this *OfferID) GoString() string { if this == nil { - return "nil" - } - s := strings.Join([]string{`&Value_Text{`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&mesosproto.OfferID{") + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Attribute) String() string { +func (this *SlaveID) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Attribute{`, - `Name:` + valueToStringMesos(this.Name) + `,`, - `Type:` + valueToStringMesos(this.Type) + `,`, - `Scalar:` + strings.Replace(fmt1.Sprintf("%v", this.Scalar), "Value_Scalar", "Value_Scalar", 1) + `,`, - `Ranges:` + strings.Replace(fmt1.Sprintf("%v", this.Ranges), "Value_Ranges", "Value_Ranges", 1) + `,`, - `Set:` + strings.Replace(fmt1.Sprintf("%v", this.Set), "Value_Set", "Value_Set", 1) + `,`, - `Text:` + strings.Replace(fmt1.Sprintf("%v", this.Text), "Value_Text", "Value_Text", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 5) + s = append(s, "&mesosproto.SlaveID{") + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Resource) String() string { +func (this *TaskID) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Resource{`, - `Name:` + valueToStringMesos(this.Name) + `,`, - `Type:` + valueToStringMesos(this.Type) + `,`, - `Scalar:` + strings.Replace(fmt1.Sprintf("%v", this.Scalar), "Value_Scalar", "Value_Scalar", 1) + `,`, - `Ranges:` + strings.Replace(fmt1.Sprintf("%v", this.Ranges), "Value_Ranges", "Value_Ranges", 1) + `,`, - `Set:` + strings.Replace(fmt1.Sprintf("%v", this.Set), "Value_Set", "Value_Set", 1) + `,`, - `Role:` + valueToStringMesos(this.Role) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 5) + s = append(s, "&mesosproto.TaskID{") + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *ResourceStatistics) String() string { +func (this *ExecutorID) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&ResourceStatistics{`, - `Timestamp:` + valueToStringMesos(this.Timestamp) + `,`, - `CpusUserTimeSecs:` + valueToStringMesos(this.CpusUserTimeSecs) + `,`, - `CpusSystemTimeSecs:` + valueToStringMesos(this.CpusSystemTimeSecs) + `,`, - `CpusLimit:` + valueToStringMesos(this.CpusLimit) + `,`, - `CpusNrPeriods:` + valueToStringMesos(this.CpusNrPeriods) + `,`, - `CpusNrThrottled:` + valueToStringMesos(this.CpusNrThrottled) + `,`, - `CpusThrottledTimeSecs:` + valueToStringMesos(this.CpusThrottledTimeSecs) + `,`, - `MemRssBytes:` + valueToStringMesos(this.MemRssBytes) + `,`, - `MemLimitBytes:` + valueToStringMesos(this.MemLimitBytes) + `,`, - `MemFileBytes:` + valueToStringMesos(this.MemFileBytes) + `,`, - `MemAnonBytes:` + valueToStringMesos(this.MemAnonBytes) + `,`, - `MemMappedFileBytes:` + valueToStringMesos(this.MemMappedFileBytes) + `,`, - `Perf:` + strings.Replace(fmt1.Sprintf("%v", this.Perf), "PerfStatistics", "PerfStatistics", 1) + `,`, - `NetRxPackets:` + valueToStringMesos(this.NetRxPackets) + `,`, - `NetRxBytes:` + valueToStringMesos(this.NetRxBytes) + `,`, - `NetRxErrors:` + valueToStringMesos(this.NetRxErrors) + `,`, - `NetRxDropped:` + valueToStringMesos(this.NetRxDropped) + `,`, - `NetTxPackets:` + valueToStringMesos(this.NetTxPackets) + `,`, - `NetTxBytes:` + valueToStringMesos(this.NetTxBytes) + `,`, - `NetTxErrors:` + valueToStringMesos(this.NetTxErrors) + `,`, - `NetTxDropped:` + valueToStringMesos(this.NetTxDropped) + `,`, - `NetTcpRttMicrosecsP50:` + valueToStringMesos(this.NetTcpRttMicrosecsP50) + `,`, - `NetTcpRttMicrosecsP90:` + valueToStringMesos(this.NetTcpRttMicrosecsP90) + `,`, - `NetTcpRttMicrosecsP95:` + valueToStringMesos(this.NetTcpRttMicrosecsP95) + `,`, - `NetTcpRttMicrosecsP99:` + valueToStringMesos(this.NetTcpRttMicrosecsP99) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 5) + s = append(s, "&mesosproto.ExecutorID{") + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *ResourceUsage) String() string { +func (this *ContainerID) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&ResourceUsage{`, - `SlaveId:` + strings.Replace(fmt1.Sprintf("%v", this.SlaveId), "SlaveID", "SlaveID", 1) + `,`, - `FrameworkId:` + strings.Replace(fmt1.Sprintf("%v", this.FrameworkId), "FrameworkID", "FrameworkID", 1) + `,`, - `ExecutorId:` + strings.Replace(fmt1.Sprintf("%v", this.ExecutorId), "ExecutorID", "ExecutorID", 1) + `,`, - `ExecutorName:` + valueToStringMesos(this.ExecutorName) + `,`, - `TaskId:` + strings.Replace(fmt1.Sprintf("%v", this.TaskId), "TaskID", "TaskID", 1) + `,`, - `Statistics:` + strings.Replace(fmt1.Sprintf("%v", this.Statistics), "ResourceStatistics", "ResourceStatistics", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 5) + s = append(s, "&mesosproto.ContainerID{") + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *PerfStatistics) String() string { +func (this *FrameworkInfo) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&PerfStatistics{`, - `Timestamp:` + valueToStringMesos(this.Timestamp) + `,`, - `Duration:` + valueToStringMesos(this.Duration) + `,`, - `Cycles:` + valueToStringMesos(this.Cycles) + `,`, - `StalledCyclesFrontend:` + valueToStringMesos(this.StalledCyclesFrontend) + `,`, - `StalledCyclesBackend:` + valueToStringMesos(this.StalledCyclesBackend) + `,`, - `Instructions:` + valueToStringMesos(this.Instructions) + `,`, - `CacheReferences:` + valueToStringMesos(this.CacheReferences) + `,`, - `CacheMisses:` + valueToStringMesos(this.CacheMisses) + `,`, - `Branches:` + valueToStringMesos(this.Branches) + `,`, - `BranchMisses:` + valueToStringMesos(this.BranchMisses) + `,`, - `BusCycles:` + valueToStringMesos(this.BusCycles) + `,`, - `RefCycles:` + valueToStringMesos(this.RefCycles) + `,`, - `CpuClock:` + valueToStringMesos(this.CpuClock) + `,`, - `TaskClock:` + valueToStringMesos(this.TaskClock) + `,`, - `PageFaults:` + valueToStringMesos(this.PageFaults) + `,`, - `MinorFaults:` + valueToStringMesos(this.MinorFaults) + `,`, - `MajorFaults:` + valueToStringMesos(this.MajorFaults) + `,`, - `ContextSwitches:` + valueToStringMesos(this.ContextSwitches) + `,`, - `CpuMigrations:` + valueToStringMesos(this.CpuMigrations) + `,`, - `AlignmentFaults:` + valueToStringMesos(this.AlignmentFaults) + `,`, - `EmulationFaults:` + valueToStringMesos(this.EmulationFaults) + `,`, - `L1DcacheLoads:` + valueToStringMesos(this.L1DcacheLoads) + `,`, - `L1DcacheLoadMisses:` + valueToStringMesos(this.L1DcacheLoadMisses) + `,`, - `L1DcacheStores:` + valueToStringMesos(this.L1DcacheStores) + `,`, - `L1DcacheStoreMisses:` + valueToStringMesos(this.L1DcacheStoreMisses) + `,`, - `L1DcachePrefetches:` + valueToStringMesos(this.L1DcachePrefetches) + `,`, - `L1DcachePrefetchMisses:` + valueToStringMesos(this.L1DcachePrefetchMisses) + `,`, - `L1IcacheLoads:` + valueToStringMesos(this.L1IcacheLoads) + `,`, - `L1IcacheLoadMisses:` + valueToStringMesos(this.L1IcacheLoadMisses) + `,`, - `L1IcachePrefetches:` + valueToStringMesos(this.L1IcachePrefetches) + `,`, - `L1IcachePrefetchMisses:` + valueToStringMesos(this.L1IcachePrefetchMisses) + `,`, - `LlcLoads:` + valueToStringMesos(this.LlcLoads) + `,`, - `LlcLoadMisses:` + valueToStringMesos(this.LlcLoadMisses) + `,`, - `LlcStores:` + valueToStringMesos(this.LlcStores) + `,`, - `LlcStoreMisses:` + valueToStringMesos(this.LlcStoreMisses) + `,`, - `LlcPrefetches:` + valueToStringMesos(this.LlcPrefetches) + `,`, - `LlcPrefetchMisses:` + valueToStringMesos(this.LlcPrefetchMisses) + `,`, - `DtlbLoads:` + valueToStringMesos(this.DtlbLoads) + `,`, - `DtlbLoadMisses:` + valueToStringMesos(this.DtlbLoadMisses) + `,`, - `DtlbStores:` + valueToStringMesos(this.DtlbStores) + `,`, - `DtlbStoreMisses:` + valueToStringMesos(this.DtlbStoreMisses) + `,`, - `DtlbPrefetches:` + valueToStringMesos(this.DtlbPrefetches) + `,`, - `DtlbPrefetchMisses:` + valueToStringMesos(this.DtlbPrefetchMisses) + `,`, - `ItlbLoads:` + valueToStringMesos(this.ItlbLoads) + `,`, - `ItlbLoadMisses:` + valueToStringMesos(this.ItlbLoadMisses) + `,`, - `BranchLoads:` + valueToStringMesos(this.BranchLoads) + `,`, - `BranchLoadMisses:` + valueToStringMesos(this.BranchLoadMisses) + `,`, - `NodeLoads:` + valueToStringMesos(this.NodeLoads) + `,`, - `NodeLoadMisses:` + valueToStringMesos(this.NodeLoadMisses) + `,`, - `NodeStores:` + valueToStringMesos(this.NodeStores) + `,`, - `NodeStoreMisses:` + valueToStringMesos(this.NodeStoreMisses) + `,`, - `NodePrefetches:` + valueToStringMesos(this.NodePrefetches) + `,`, - `NodePrefetchMisses:` + valueToStringMesos(this.NodePrefetchMisses) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 14) + s = append(s, "&mesosproto.FrameworkInfo{") + if this.User != nil { + s = append(s, "User: "+valueToGoStringMesos(this.User, "string")+",\n") + } + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringMesos(this.Name, "string")+",\n") + } + if this.Id != nil { + s = append(s, "Id: "+fmt.Sprintf("%#v", this.Id)+",\n") + } + if this.FailoverTimeout != nil { + s = append(s, "FailoverTimeout: "+valueToGoStringMesos(this.FailoverTimeout, "float64")+",\n") + } + if this.Checkpoint != nil { + s = append(s, "Checkpoint: "+valueToGoStringMesos(this.Checkpoint, "bool")+",\n") + } + if this.Role != nil { + s = append(s, "Role: "+valueToGoStringMesos(this.Role, "string")+",\n") + } + if this.Hostname != nil { + s = append(s, "Hostname: "+valueToGoStringMesos(this.Hostname, "string")+",\n") + } + if this.Principal != nil { + s = append(s, "Principal: "+valueToGoStringMesos(this.Principal, "string")+",\n") + } + if this.WebuiUrl != nil { + s = append(s, "WebuiUrl: "+valueToGoStringMesos(this.WebuiUrl, "string")+",\n") + } + if this.Capabilities != nil { + s = append(s, "Capabilities: "+fmt.Sprintf("%#v", this.Capabilities)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Request) String() string { +func (this *FrameworkInfo_Capability) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Request{`, - `SlaveId:` + strings.Replace(fmt1.Sprintf("%v", this.SlaveId), "SlaveID", "SlaveID", 1) + `,`, - `Resources:` + strings.Replace(fmt1.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 5) + s = append(s, "&mesosproto.FrameworkInfo_Capability{") + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringMesos(this.Type, "mesosproto.FrameworkInfo_Capability_Type")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Offer) String() string { +func (this *HealthCheck) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Offer{`, - `Id:` + strings.Replace(fmt1.Sprintf("%v", this.Id), "OfferID", "OfferID", 1) + `,`, - `FrameworkId:` + strings.Replace(fmt1.Sprintf("%v", this.FrameworkId), "FrameworkID", "FrameworkID", 1) + `,`, - `SlaveId:` + strings.Replace(fmt1.Sprintf("%v", this.SlaveId), "SlaveID", "SlaveID", 1) + `,`, - `Hostname:` + valueToStringMesos(this.Hostname) + `,`, - `Resources:` + strings.Replace(fmt1.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, - `Attributes:` + strings.Replace(fmt1.Sprintf("%v", this.Attributes), "Attribute", "Attribute", 1) + `,`, - `ExecutorIds:` + strings.Replace(fmt1.Sprintf("%v", this.ExecutorIds), "ExecutorID", "ExecutorID", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 11) + s = append(s, "&mesosproto.HealthCheck{") + if this.Http != nil { + s = append(s, "Http: "+fmt.Sprintf("%#v", this.Http)+",\n") + } + if this.DelaySeconds != nil { + s = append(s, "DelaySeconds: "+valueToGoStringMesos(this.DelaySeconds, "float64")+",\n") + } + if this.IntervalSeconds != nil { + s = append(s, "IntervalSeconds: "+valueToGoStringMesos(this.IntervalSeconds, "float64")+",\n") + } + if this.TimeoutSeconds != nil { + s = append(s, "TimeoutSeconds: "+valueToGoStringMesos(this.TimeoutSeconds, "float64")+",\n") + } + if this.ConsecutiveFailures != nil { + s = append(s, "ConsecutiveFailures: "+valueToGoStringMesos(this.ConsecutiveFailures, "uint32")+",\n") + } + if this.GracePeriodSeconds != nil { + s = append(s, "GracePeriodSeconds: "+valueToGoStringMesos(this.GracePeriodSeconds, "float64")+",\n") + } + if this.Command != nil { + s = append(s, "Command: "+fmt.Sprintf("%#v", this.Command)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *TaskInfo) String() string { +func (this *HealthCheck_HTTP) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&TaskInfo{`, - `Name:` + valueToStringMesos(this.Name) + `,`, - `TaskId:` + strings.Replace(fmt1.Sprintf("%v", this.TaskId), "TaskID", "TaskID", 1) + `,`, - `SlaveId:` + strings.Replace(fmt1.Sprintf("%v", this.SlaveId), "SlaveID", "SlaveID", 1) + `,`, - `Resources:` + strings.Replace(fmt1.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, - `Executor:` + strings.Replace(fmt1.Sprintf("%v", this.Executor), "ExecutorInfo", "ExecutorInfo", 1) + `,`, - `Command:` + strings.Replace(fmt1.Sprintf("%v", this.Command), "CommandInfo", "CommandInfo", 1) + `,`, - `Container:` + strings.Replace(fmt1.Sprintf("%v", this.Container), "ContainerInfo", "ContainerInfo", 1) + `,`, - `Data:` + valueToStringMesos(this.Data) + `,`, - `HealthCheck:` + strings.Replace(fmt1.Sprintf("%v", this.HealthCheck), "HealthCheck", "HealthCheck", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 7) + s = append(s, "&mesosproto.HealthCheck_HTTP{") + if this.Port != nil { + s = append(s, "Port: "+valueToGoStringMesos(this.Port, "uint32")+",\n") + } + if this.Path != nil { + s = append(s, "Path: "+valueToGoStringMesos(this.Path, "string")+",\n") + } + if this.Statuses != nil { + s = append(s, "Statuses: "+fmt.Sprintf("%#v", this.Statuses)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *TaskStatus) String() string { +func (this *CommandInfo) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&TaskStatus{`, - `TaskId:` + strings.Replace(fmt1.Sprintf("%v", this.TaskId), "TaskID", "TaskID", 1) + `,`, - `State:` + valueToStringMesos(this.State) + `,`, - `Message:` + valueToStringMesos(this.Message) + `,`, - `Source:` + valueToStringMesos(this.Source) + `,`, - `Reason:` + valueToStringMesos(this.Reason) + `,`, - `Data:` + valueToStringMesos(this.Data) + `,`, - `SlaveId:` + strings.Replace(fmt1.Sprintf("%v", this.SlaveId), "SlaveID", "SlaveID", 1) + `,`, - `ExecutorId:` + strings.Replace(fmt1.Sprintf("%v", this.ExecutorId), "ExecutorID", "ExecutorID", 1) + `,`, - `Timestamp:` + valueToStringMesos(this.Timestamp) + `,`, - `Healthy:` + valueToStringMesos(this.Healthy) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 11) + s = append(s, "&mesosproto.CommandInfo{") + if this.Container != nil { + s = append(s, "Container: "+fmt.Sprintf("%#v", this.Container)+",\n") + } + if this.Uris != nil { + s = append(s, "Uris: "+fmt.Sprintf("%#v", this.Uris)+",\n") + } + if this.Environment != nil { + s = append(s, "Environment: "+fmt.Sprintf("%#v", this.Environment)+",\n") + } + if this.Shell != nil { + s = append(s, "Shell: "+valueToGoStringMesos(this.Shell, "bool")+",\n") + } + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") + } + if this.Arguments != nil { + s = append(s, "Arguments: "+fmt.Sprintf("%#v", this.Arguments)+",\n") + } + if this.User != nil { + s = append(s, "User: "+valueToGoStringMesos(this.User, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Filters) String() string { +func (this *CommandInfo_URI) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Filters{`, - `RefuseSeconds:` + valueToStringMesos(this.RefuseSeconds) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 8) + s = append(s, "&mesosproto.CommandInfo_URI{") + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") + } + if this.Executable != nil { + s = append(s, "Executable: "+valueToGoStringMesos(this.Executable, "bool")+",\n") + } + if this.Extract != nil { + s = append(s, "Extract: "+valueToGoStringMesos(this.Extract, "bool")+",\n") + } + if this.Cache != nil { + s = append(s, "Cache: "+valueToGoStringMesos(this.Cache, "bool")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Environment) String() string { +func (this *CommandInfo_ContainerInfo) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Environment{`, - `Variables:` + strings.Replace(fmt1.Sprintf("%v", this.Variables), "Environment_Variable", "Environment_Variable", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 6) + s = append(s, "&mesosproto.CommandInfo_ContainerInfo{") + if this.Image != nil { + s = append(s, "Image: "+valueToGoStringMesos(this.Image, "string")+",\n") + } + if this.Options != nil { + s = append(s, "Options: "+fmt.Sprintf("%#v", this.Options)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Environment_Variable) String() string { +func (this *ExecutorInfo) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Environment_Variable{`, - `Name:` + valueToStringMesos(this.Name) + `,`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 13) + s = append(s, "&mesosproto.ExecutorInfo{") + if this.ExecutorId != nil { + s = append(s, "ExecutorId: "+fmt.Sprintf("%#v", this.ExecutorId)+",\n") + } + if this.FrameworkId != nil { + s = append(s, "FrameworkId: "+fmt.Sprintf("%#v", this.FrameworkId)+",\n") + } + if this.Command != nil { + s = append(s, "Command: "+fmt.Sprintf("%#v", this.Command)+",\n") + } + if this.Container != nil { + s = append(s, "Container: "+fmt.Sprintf("%#v", this.Container)+",\n") + } + if this.Resources != nil { + s = append(s, "Resources: "+fmt.Sprintf("%#v", this.Resources)+",\n") + } + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringMesos(this.Name, "string")+",\n") + } + if this.Source != nil { + s = append(s, "Source: "+valueToGoStringMesos(this.Source, "string")+",\n") + } + if this.Data != nil { + s = append(s, "Data: "+valueToGoStringMesos(this.Data, "byte")+",\n") + } + if this.Discovery != nil { + s = append(s, "Discovery: "+fmt.Sprintf("%#v", this.Discovery)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Parameter) String() string { +func (this *MasterInfo) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Parameter{`, - `Key:` + valueToStringMesos(this.Key) + `,`, - `Value:` + valueToStringMesos(this.Value) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 10) + s = append(s, "&mesosproto.MasterInfo{") + if this.Id != nil { + s = append(s, "Id: "+valueToGoStringMesos(this.Id, "string")+",\n") + } + if this.Ip != nil { + s = append(s, "Ip: "+valueToGoStringMesos(this.Ip, "uint32")+",\n") + } + if this.Port != nil { + s = append(s, "Port: "+valueToGoStringMesos(this.Port, "uint32")+",\n") + } + if this.Pid != nil { + s = append(s, "Pid: "+valueToGoStringMesos(this.Pid, "string")+",\n") + } + if this.Hostname != nil { + s = append(s, "Hostname: "+valueToGoStringMesos(this.Hostname, "string")+",\n") + } + if this.Version != nil { + s = append(s, "Version: "+valueToGoStringMesos(this.Version, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Parameters) String() string { +func (this *SlaveInfo) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Parameters{`, - `Parameter:` + strings.Replace(fmt1.Sprintf("%v", this.Parameter), "Parameter", "Parameter", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 10) + s = append(s, "&mesosproto.SlaveInfo{") + if this.Hostname != nil { + s = append(s, "Hostname: "+valueToGoStringMesos(this.Hostname, "string")+",\n") + } + if this.Port != nil { + s = append(s, "Port: "+valueToGoStringMesos(this.Port, "int32")+",\n") + } + if this.Resources != nil { + s = append(s, "Resources: "+fmt.Sprintf("%#v", this.Resources)+",\n") + } + if this.Attributes != nil { + s = append(s, "Attributes: "+fmt.Sprintf("%#v", this.Attributes)+",\n") + } + if this.Id != nil { + s = append(s, "Id: "+fmt.Sprintf("%#v", this.Id)+",\n") + } + if this.Checkpoint != nil { + s = append(s, "Checkpoint: "+valueToGoStringMesos(this.Checkpoint, "bool")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Credential) String() string { +func (this *Value) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Credential{`, - `Principal:` + valueToStringMesos(this.Principal) + `,`, - `Secret:` + valueToStringMesos(this.Secret) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 9) + s = append(s, "&mesosproto.Value{") + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringMesos(this.Type, "mesosproto.Value_Type")+",\n") + } + if this.Scalar != nil { + s = append(s, "Scalar: "+fmt.Sprintf("%#v", this.Scalar)+",\n") + } + if this.Ranges != nil { + s = append(s, "Ranges: "+fmt.Sprintf("%#v", this.Ranges)+",\n") + } + if this.Set != nil { + s = append(s, "Set: "+fmt.Sprintf("%#v", this.Set)+",\n") + } + if this.Text != nil { + s = append(s, "Text: "+fmt.Sprintf("%#v", this.Text)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Credentials) String() string { +func (this *Value_Scalar) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Credentials{`, - `Credentials:` + strings.Replace(fmt1.Sprintf("%v", this.Credentials), "Credential", "Credential", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Value_Scalar{") + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "float64")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *ACL) String() string { +func (this *Value_Range) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&ACL{`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 6) + s = append(s, "&mesosproto.Value_Range{") + if this.Begin != nil { + s = append(s, "Begin: "+valueToGoStringMesos(this.Begin, "uint64")+",\n") + } + if this.End != nil { + s = append(s, "End: "+valueToGoStringMesos(this.End, "uint64")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *ACL_Entity) String() string { +func (this *Value_Ranges) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&ACL_Entity{`, - `Type:` + valueToStringMesos(this.Type) + `,`, - `Values:` + fmt1.Sprintf("%v", this.Values) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Value_Ranges{") + if this.Range != nil { + s = append(s, "Range: "+fmt.Sprintf("%#v", this.Range)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *ACL_RegisterFramework) String() string { +func (this *Value_Set) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&ACL_RegisterFramework{`, - `Principals:` + strings.Replace(fmt1.Sprintf("%v", this.Principals), "ACL_Entity", "ACL_Entity", 1) + `,`, - `Roles:` + strings.Replace(fmt1.Sprintf("%v", this.Roles), "ACL_Entity", "ACL_Entity", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Value_Set{") + if this.Item != nil { + s = append(s, "Item: "+fmt.Sprintf("%#v", this.Item)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *ACL_RunTask) String() string { +func (this *Value_Text) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&ACL_RunTask{`, - `Principals:` + strings.Replace(fmt1.Sprintf("%v", this.Principals), "ACL_Entity", "ACL_Entity", 1) + `,`, - `Users:` + strings.Replace(fmt1.Sprintf("%v", this.Users), "ACL_Entity", "ACL_Entity", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Value_Text{") + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *ACL_ShutdownFramework) String() string { +func (this *Attribute) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&ACL_ShutdownFramework{`, - `Principals:` + strings.Replace(fmt1.Sprintf("%v", this.Principals), "ACL_Entity", "ACL_Entity", 1) + `,`, - `FrameworkPrincipals:` + strings.Replace(fmt1.Sprintf("%v", this.FrameworkPrincipals), "ACL_Entity", "ACL_Entity", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 10) + s = append(s, "&mesosproto.Attribute{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringMesos(this.Name, "string")+",\n") + } + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringMesos(this.Type, "mesosproto.Value_Type")+",\n") + } + if this.Scalar != nil { + s = append(s, "Scalar: "+fmt.Sprintf("%#v", this.Scalar)+",\n") + } + if this.Ranges != nil { + s = append(s, "Ranges: "+fmt.Sprintf("%#v", this.Ranges)+",\n") + } + if this.Set != nil { + s = append(s, "Set: "+fmt.Sprintf("%#v", this.Set)+",\n") + } + if this.Text != nil { + s = append(s, "Text: "+fmt.Sprintf("%#v", this.Text)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *ACLs) String() string { +func (this *Resource) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&ACLs{`, - `Permissive:` + valueToStringMesos(this.Permissive) + `,`, - `RegisterFrameworks:` + strings.Replace(fmt1.Sprintf("%v", this.RegisterFrameworks), "ACL_RegisterFramework", "ACL_RegisterFramework", 1) + `,`, - `RunTasks:` + strings.Replace(fmt1.Sprintf("%v", this.RunTasks), "ACL_RunTask", "ACL_RunTask", 1) + `,`, - `ShutdownFrameworks:` + strings.Replace(fmt1.Sprintf("%v", this.ShutdownFrameworks), "ACL_ShutdownFramework", "ACL_ShutdownFramework", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 13) + s = append(s, "&mesosproto.Resource{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringMesos(this.Name, "string")+",\n") + } + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringMesos(this.Type, "mesosproto.Value_Type")+",\n") + } + if this.Scalar != nil { + s = append(s, "Scalar: "+fmt.Sprintf("%#v", this.Scalar)+",\n") + } + if this.Ranges != nil { + s = append(s, "Ranges: "+fmt.Sprintf("%#v", this.Ranges)+",\n") + } + if this.Set != nil { + s = append(s, "Set: "+fmt.Sprintf("%#v", this.Set)+",\n") + } + if this.Role != nil { + s = append(s, "Role: "+valueToGoStringMesos(this.Role, "string")+",\n") + } + if this.Reservation != nil { + s = append(s, "Reservation: "+fmt.Sprintf("%#v", this.Reservation)+",\n") + } + if this.Disk != nil { + s = append(s, "Disk: "+fmt.Sprintf("%#v", this.Disk)+",\n") + } + if this.Revocable != nil { + s = append(s, "Revocable: "+fmt.Sprintf("%#v", this.Revocable)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *RateLimit) String() string { +func (this *Resource_ReservationInfo) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&RateLimit{`, - `Qps:` + valueToStringMesos(this.Qps) + `,`, - `Principal:` + valueToStringMesos(this.Principal) + `,`, - `Capacity:` + valueToStringMesos(this.Capacity) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Resource_ReservationInfo{") + if this.Principal != nil { + s = append(s, "Principal: "+valueToGoStringMesos(this.Principal, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *RateLimits) String() string { +func (this *Resource_DiskInfo) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&RateLimits{`, - `Limits:` + strings.Replace(fmt1.Sprintf("%v", this.Limits), "RateLimit", "RateLimit", 1) + `,`, - `AggregateDefaultQps:` + valueToStringMesos(this.AggregateDefaultQps) + `,`, - `AggregateDefaultCapacity:` + valueToStringMesos(this.AggregateDefaultCapacity) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 6) + s = append(s, "&mesosproto.Resource_DiskInfo{") + if this.Persistence != nil { + s = append(s, "Persistence: "+fmt.Sprintf("%#v", this.Persistence)+",\n") + } + if this.Volume != nil { + s = append(s, "Volume: "+fmt.Sprintf("%#v", this.Volume)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *Volume) String() string { +func (this *Resource_DiskInfo_Persistence) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Volume{`, - `ContainerPath:` + valueToStringMesos(this.ContainerPath) + `,`, - `HostPath:` + valueToStringMesos(this.HostPath) + `,`, - `Mode:` + valueToStringMesos(this.Mode) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Resource_DiskInfo_Persistence{") + if this.Id != nil { + s = append(s, "Id: "+valueToGoStringMesos(this.Id, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *ContainerInfo) String() string { +func (this *Resource_RevocableInfo) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&ContainerInfo{`, - `Type:` + valueToStringMesos(this.Type) + `,`, - `Volumes:` + strings.Replace(fmt1.Sprintf("%v", this.Volumes), "Volume", "Volume", 1) + `,`, - `Hostname:` + valueToStringMesos(this.Hostname) + `,`, - `Docker:` + strings.Replace(fmt1.Sprintf("%v", this.Docker), "ContainerInfo_DockerInfo", "ContainerInfo_DockerInfo", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 4) + s = append(s, "&mesosproto.Resource_RevocableInfo{") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *ContainerInfo_DockerInfo) String() string { +func (this *TrafficControlStatistics) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&ContainerInfo_DockerInfo{`, - `Image:` + valueToStringMesos(this.Image) + `,`, - `Network:` + valueToStringMesos(this.Network) + `,`, - `PortMappings:` + strings.Replace(fmt1.Sprintf("%v", this.PortMappings), "ContainerInfo_DockerInfo_PortMapping", "ContainerInfo_DockerInfo_PortMapping", 1) + `,`, - `Privileged:` + valueToStringMesos(this.Privileged) + `,`, - `Parameters:` + strings.Replace(fmt1.Sprintf("%v", this.Parameters), "Parameter", "Parameter", 1) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + s := make([]string, 0, 14) + s = append(s, "&mesosproto.TrafficControlStatistics{") + if this.Id != nil { + s = append(s, "Id: "+valueToGoStringMesos(this.Id, "string")+",\n") + } + if this.Backlog != nil { + s = append(s, "Backlog: "+valueToGoStringMesos(this.Backlog, "uint64")+",\n") + } + if this.Bytes != nil { + s = append(s, "Bytes: "+valueToGoStringMesos(this.Bytes, "uint64")+",\n") + } + if this.Drops != nil { + s = append(s, "Drops: "+valueToGoStringMesos(this.Drops, "uint64")+",\n") + } + if this.Overlimits != nil { + s = append(s, "Overlimits: "+valueToGoStringMesos(this.Overlimits, "uint64")+",\n") + } + if this.Packets != nil { + s = append(s, "Packets: "+valueToGoStringMesos(this.Packets, "uint64")+",\n") + } + if this.Qlen != nil { + s = append(s, "Qlen: "+valueToGoStringMesos(this.Qlen, "uint64")+",\n") + } + if this.Ratebps != nil { + s = append(s, "Ratebps: "+valueToGoStringMesos(this.Ratebps, "uint64")+",\n") + } + if this.Ratepps != nil { + s = append(s, "Ratepps: "+valueToGoStringMesos(this.Ratepps, "uint64")+",\n") + } + if this.Requeues != nil { + s = append(s, "Requeues: "+valueToGoStringMesos(this.Requeues, "uint64")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } -func (this *ContainerInfo_DockerInfo_PortMapping) String() string { +func (this *ResourceStatistics) GoString() string { if this == nil { return "nil" } - s := strings.Join([]string{`&ContainerInfo_DockerInfo_PortMapping{`, - `HostPort:` + valueToStringMesos(this.HostPort) + `,`, - `ContainerPort:` + valueToStringMesos(this.ContainerPort) + `,`, - `Protocol:` + valueToStringMesos(this.Protocol) + `,`, - `XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func valueToStringMesos(v interface{}) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" + s := make([]string, 0, 44) + s = append(s, "&mesosproto.ResourceStatistics{") + if this.Timestamp != nil { + s = append(s, "Timestamp: "+valueToGoStringMesos(this.Timestamp, "float64")+",\n") } - pv := reflect.Indirect(rv).Interface() - return fmt1.Sprintf("*%v", pv) -} -func (m *FrameworkID) Size() (n int) { - var l int - _ = l - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovMesos(uint64(l)) + if this.Processes != nil { + s = append(s, "Processes: "+valueToGoStringMesos(this.Processes, "uint32")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.Threads != nil { + s = append(s, "Threads: "+valueToGoStringMesos(this.Threads, "uint32")+",\n") } - return n -} - -func (m *OfferID) Size() (n int) { - var l int - _ = l - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovMesos(uint64(l)) + if this.CpusUserTimeSecs != nil { + s = append(s, "CpusUserTimeSecs: "+valueToGoStringMesos(this.CpusUserTimeSecs, "float64")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.CpusSystemTimeSecs != nil { + s = append(s, "CpusSystemTimeSecs: "+valueToGoStringMesos(this.CpusSystemTimeSecs, "float64")+",\n") } - return n + if this.CpusLimit != nil { + s = append(s, "CpusLimit: "+valueToGoStringMesos(this.CpusLimit, "float64")+",\n") + } + if this.CpusNrPeriods != nil { + s = append(s, "CpusNrPeriods: "+valueToGoStringMesos(this.CpusNrPeriods, "uint32")+",\n") + } + if this.CpusNrThrottled != nil { + s = append(s, "CpusNrThrottled: "+valueToGoStringMesos(this.CpusNrThrottled, "uint32")+",\n") + } + if this.CpusThrottledTimeSecs != nil { + s = append(s, "CpusThrottledTimeSecs: "+valueToGoStringMesos(this.CpusThrottledTimeSecs, "float64")+",\n") + } + if this.MemTotalBytes != nil { + s = append(s, "MemTotalBytes: "+valueToGoStringMesos(this.MemTotalBytes, "uint64")+",\n") + } + if this.MemTotalMemswBytes != nil { + s = append(s, "MemTotalMemswBytes: "+valueToGoStringMesos(this.MemTotalMemswBytes, "uint64")+",\n") + } + if this.MemLimitBytes != nil { + s = append(s, "MemLimitBytes: "+valueToGoStringMesos(this.MemLimitBytes, "uint64")+",\n") + } + if this.MemSoftLimitBytes != nil { + s = append(s, "MemSoftLimitBytes: "+valueToGoStringMesos(this.MemSoftLimitBytes, "uint64")+",\n") + } + if this.MemFileBytes != nil { + s = append(s, "MemFileBytes: "+valueToGoStringMesos(this.MemFileBytes, "uint64")+",\n") + } + if this.MemAnonBytes != nil { + s = append(s, "MemAnonBytes: "+valueToGoStringMesos(this.MemAnonBytes, "uint64")+",\n") + } + if this.MemCacheBytes != nil { + s = append(s, "MemCacheBytes: "+valueToGoStringMesos(this.MemCacheBytes, "uint64")+",\n") + } + if this.MemRssBytes != nil { + s = append(s, "MemRssBytes: "+valueToGoStringMesos(this.MemRssBytes, "uint64")+",\n") + } + if this.MemMappedFileBytes != nil { + s = append(s, "MemMappedFileBytes: "+valueToGoStringMesos(this.MemMappedFileBytes, "uint64")+",\n") + } + if this.MemSwapBytes != nil { + s = append(s, "MemSwapBytes: "+valueToGoStringMesos(this.MemSwapBytes, "uint64")+",\n") + } + if this.MemLowPressureCounter != nil { + s = append(s, "MemLowPressureCounter: "+valueToGoStringMesos(this.MemLowPressureCounter, "uint64")+",\n") + } + if this.MemMediumPressureCounter != nil { + s = append(s, "MemMediumPressureCounter: "+valueToGoStringMesos(this.MemMediumPressureCounter, "uint64")+",\n") + } + if this.MemCriticalPressureCounter != nil { + s = append(s, "MemCriticalPressureCounter: "+valueToGoStringMesos(this.MemCriticalPressureCounter, "uint64")+",\n") + } + if this.DiskLimitBytes != nil { + s = append(s, "DiskLimitBytes: "+valueToGoStringMesos(this.DiskLimitBytes, "uint64")+",\n") + } + if this.DiskUsedBytes != nil { + s = append(s, "DiskUsedBytes: "+valueToGoStringMesos(this.DiskUsedBytes, "uint64")+",\n") + } + if this.Perf != nil { + s = append(s, "Perf: "+fmt.Sprintf("%#v", this.Perf)+",\n") + } + if this.NetRxPackets != nil { + s = append(s, "NetRxPackets: "+valueToGoStringMesos(this.NetRxPackets, "uint64")+",\n") + } + if this.NetRxBytes != nil { + s = append(s, "NetRxBytes: "+valueToGoStringMesos(this.NetRxBytes, "uint64")+",\n") + } + if this.NetRxErrors != nil { + s = append(s, "NetRxErrors: "+valueToGoStringMesos(this.NetRxErrors, "uint64")+",\n") + } + if this.NetRxDropped != nil { + s = append(s, "NetRxDropped: "+valueToGoStringMesos(this.NetRxDropped, "uint64")+",\n") + } + if this.NetTxPackets != nil { + s = append(s, "NetTxPackets: "+valueToGoStringMesos(this.NetTxPackets, "uint64")+",\n") + } + if this.NetTxBytes != nil { + s = append(s, "NetTxBytes: "+valueToGoStringMesos(this.NetTxBytes, "uint64")+",\n") + } + if this.NetTxErrors != nil { + s = append(s, "NetTxErrors: "+valueToGoStringMesos(this.NetTxErrors, "uint64")+",\n") + } + if this.NetTxDropped != nil { + s = append(s, "NetTxDropped: "+valueToGoStringMesos(this.NetTxDropped, "uint64")+",\n") + } + if this.NetTcpRttMicrosecsP50 != nil { + s = append(s, "NetTcpRttMicrosecsP50: "+valueToGoStringMesos(this.NetTcpRttMicrosecsP50, "float64")+",\n") + } + if this.NetTcpRttMicrosecsP90 != nil { + s = append(s, "NetTcpRttMicrosecsP90: "+valueToGoStringMesos(this.NetTcpRttMicrosecsP90, "float64")+",\n") + } + if this.NetTcpRttMicrosecsP95 != nil { + s = append(s, "NetTcpRttMicrosecsP95: "+valueToGoStringMesos(this.NetTcpRttMicrosecsP95, "float64")+",\n") + } + if this.NetTcpRttMicrosecsP99 != nil { + s = append(s, "NetTcpRttMicrosecsP99: "+valueToGoStringMesos(this.NetTcpRttMicrosecsP99, "float64")+",\n") + } + if this.NetTcpActiveConnections != nil { + s = append(s, "NetTcpActiveConnections: "+valueToGoStringMesos(this.NetTcpActiveConnections, "float64")+",\n") + } + if this.NetTcpTimeWaitConnections != nil { + s = append(s, "NetTcpTimeWaitConnections: "+valueToGoStringMesos(this.NetTcpTimeWaitConnections, "float64")+",\n") + } + if this.NetTrafficControlStatistics != nil { + s = append(s, "NetTrafficControlStatistics: "+fmt.Sprintf("%#v", this.NetTrafficControlStatistics)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func (m *SlaveID) Size() (n int) { - var l int - _ = l - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovMesos(uint64(l)) +func (this *ResourceUsage) GoString() string { + if this == nil { + return "nil" } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.ResourceUsage{") + if this.Executors != nil { + s = append(s, "Executors: "+fmt.Sprintf("%#v", this.Executors)+",\n") } - return n + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func (m *TaskID) Size() (n int) { - var l int - _ = l - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovMesos(uint64(l)) +func (this *ResourceUsage_Executor) GoString() string { + if this == nil { + return "nil" } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + s := make([]string, 0, 7) + s = append(s, "&mesosproto.ResourceUsage_Executor{") + if this.ExecutorInfo != nil { + s = append(s, "ExecutorInfo: "+fmt.Sprintf("%#v", this.ExecutorInfo)+",\n") } - return n + if this.Allocated != nil { + s = append(s, "Allocated: "+fmt.Sprintf("%#v", this.Allocated)+",\n") + } + if this.Statistics != nil { + s = append(s, "Statistics: "+fmt.Sprintf("%#v", this.Statistics)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func (m *ExecutorID) Size() (n int) { - var l int - _ = l - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovMesos(uint64(l)) +func (this *PerfStatistics) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 57) + s = append(s, "&mesosproto.PerfStatistics{") + if this.Timestamp != nil { + s = append(s, "Timestamp: "+valueToGoStringMesos(this.Timestamp, "float64")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.Duration != nil { + s = append(s, "Duration: "+valueToGoStringMesos(this.Duration, "float64")+",\n") } - return n -} - -func (m *ContainerID) Size() (n int) { - var l int - _ = l - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovMesos(uint64(l)) + if this.Cycles != nil { + s = append(s, "Cycles: "+valueToGoStringMesos(this.Cycles, "uint64")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.StalledCyclesFrontend != nil { + s = append(s, "StalledCyclesFrontend: "+valueToGoStringMesos(this.StalledCyclesFrontend, "uint64")+",\n") } - return n -} - -func (m *FrameworkInfo) Size() (n int) { - var l int - _ = l - if m.User != nil { - l = len(*m.User) - n += 1 + l + sovMesos(uint64(l)) + if this.StalledCyclesBackend != nil { + s = append(s, "StalledCyclesBackend: "+valueToGoStringMesos(this.StalledCyclesBackend, "uint64")+",\n") } - if m.Name != nil { - l = len(*m.Name) - n += 1 + l + sovMesos(uint64(l)) + if this.Instructions != nil { + s = append(s, "Instructions: "+valueToGoStringMesos(this.Instructions, "uint64")+",\n") } - if m.Id != nil { - l = m.Id.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.CacheReferences != nil { + s = append(s, "CacheReferences: "+valueToGoStringMesos(this.CacheReferences, "uint64")+",\n") } - if m.FailoverTimeout != nil { - n += 9 + if this.CacheMisses != nil { + s = append(s, "CacheMisses: "+valueToGoStringMesos(this.CacheMisses, "uint64")+",\n") } - if m.Checkpoint != nil { - n += 2 + if this.Branches != nil { + s = append(s, "Branches: "+valueToGoStringMesos(this.Branches, "uint64")+",\n") } - if m.Role != nil { - l = len(*m.Role) - n += 1 + l + sovMesos(uint64(l)) + if this.BranchMisses != nil { + s = append(s, "BranchMisses: "+valueToGoStringMesos(this.BranchMisses, "uint64")+",\n") } - if m.Hostname != nil { - l = len(*m.Hostname) - n += 1 + l + sovMesos(uint64(l)) + if this.BusCycles != nil { + s = append(s, "BusCycles: "+valueToGoStringMesos(this.BusCycles, "uint64")+",\n") } - if m.Principal != nil { - l = len(*m.Principal) - n += 1 + l + sovMesos(uint64(l)) + if this.RefCycles != nil { + s = append(s, "RefCycles: "+valueToGoStringMesos(this.RefCycles, "uint64")+",\n") } - if m.WebuiUrl != nil { - l = len(*m.WebuiUrl) - n += 1 + l + sovMesos(uint64(l)) + if this.CpuClock != nil { + s = append(s, "CpuClock: "+valueToGoStringMesos(this.CpuClock, "float64")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.TaskClock != nil { + s = append(s, "TaskClock: "+valueToGoStringMesos(this.TaskClock, "float64")+",\n") } - return n -} - -func (m *HealthCheck) Size() (n int) { - var l int - _ = l - if m.Http != nil { - l = m.Http.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.PageFaults != nil { + s = append(s, "PageFaults: "+valueToGoStringMesos(this.PageFaults, "uint64")+",\n") } - if m.DelaySeconds != nil { - n += 9 + if this.MinorFaults != nil { + s = append(s, "MinorFaults: "+valueToGoStringMesos(this.MinorFaults, "uint64")+",\n") } - if m.IntervalSeconds != nil { - n += 9 + if this.MajorFaults != nil { + s = append(s, "MajorFaults: "+valueToGoStringMesos(this.MajorFaults, "uint64")+",\n") } - if m.TimeoutSeconds != nil { - n += 9 + if this.ContextSwitches != nil { + s = append(s, "ContextSwitches: "+valueToGoStringMesos(this.ContextSwitches, "uint64")+",\n") } - if m.ConsecutiveFailures != nil { - n += 1 + sovMesos(uint64(*m.ConsecutiveFailures)) + if this.CpuMigrations != nil { + s = append(s, "CpuMigrations: "+valueToGoStringMesos(this.CpuMigrations, "uint64")+",\n") } - if m.GracePeriodSeconds != nil { - n += 9 + if this.AlignmentFaults != nil { + s = append(s, "AlignmentFaults: "+valueToGoStringMesos(this.AlignmentFaults, "uint64")+",\n") } - if m.Command != nil { - l = m.Command.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.EmulationFaults != nil { + s = append(s, "EmulationFaults: "+valueToGoStringMesos(this.EmulationFaults, "uint64")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.L1DcacheLoads != nil { + s = append(s, "L1DcacheLoads: "+valueToGoStringMesos(this.L1DcacheLoads, "uint64")+",\n") } - return n -} - -func (m *HealthCheck_HTTP) Size() (n int) { - var l int - _ = l - if m.Port != nil { - n += 1 + sovMesos(uint64(*m.Port)) + if this.L1DcacheLoadMisses != nil { + s = append(s, "L1DcacheLoadMisses: "+valueToGoStringMesos(this.L1DcacheLoadMisses, "uint64")+",\n") } - if m.Path != nil { - l = len(*m.Path) - n += 1 + l + sovMesos(uint64(l)) + if this.L1DcacheStores != nil { + s = append(s, "L1DcacheStores: "+valueToGoStringMesos(this.L1DcacheStores, "uint64")+",\n") } - if len(m.Statuses) > 0 { - for _, e := range m.Statuses { - n += 1 + sovMesos(uint64(e)) - } + if this.L1DcacheStoreMisses != nil { + s = append(s, "L1DcacheStoreMisses: "+valueToGoStringMesos(this.L1DcacheStoreMisses, "uint64")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.L1DcachePrefetches != nil { + s = append(s, "L1DcachePrefetches: "+valueToGoStringMesos(this.L1DcachePrefetches, "uint64")+",\n") } - return n -} - -func (m *CommandInfo) Size() (n int) { - var l int - _ = l - if m.Container != nil { - l = m.Container.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.L1DcachePrefetchMisses != nil { + s = append(s, "L1DcachePrefetchMisses: "+valueToGoStringMesos(this.L1DcachePrefetchMisses, "uint64")+",\n") } - if len(m.Uris) > 0 { - for _, e := range m.Uris { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + if this.L1IcacheLoads != nil { + s = append(s, "L1IcacheLoads: "+valueToGoStringMesos(this.L1IcacheLoads, "uint64")+",\n") } - if m.Environment != nil { - l = m.Environment.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.L1IcacheLoadMisses != nil { + s = append(s, "L1IcacheLoadMisses: "+valueToGoStringMesos(this.L1IcacheLoadMisses, "uint64")+",\n") } - if m.Shell != nil { - n += 2 + if this.L1IcachePrefetches != nil { + s = append(s, "L1IcachePrefetches: "+valueToGoStringMesos(this.L1IcachePrefetches, "uint64")+",\n") } - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovMesos(uint64(l)) + if this.L1IcachePrefetchMisses != nil { + s = append(s, "L1IcachePrefetchMisses: "+valueToGoStringMesos(this.L1IcachePrefetchMisses, "uint64")+",\n") } - if len(m.Arguments) > 0 { - for _, s := range m.Arguments { - l = len(s) - n += 1 + l + sovMesos(uint64(l)) - } + if this.LlcLoads != nil { + s = append(s, "LlcLoads: "+valueToGoStringMesos(this.LlcLoads, "uint64")+",\n") } - if m.User != nil { - l = len(*m.User) - n += 1 + l + sovMesos(uint64(l)) + if this.LlcLoadMisses != nil { + s = append(s, "LlcLoadMisses: "+valueToGoStringMesos(this.LlcLoadMisses, "uint64")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.LlcStores != nil { + s = append(s, "LlcStores: "+valueToGoStringMesos(this.LlcStores, "uint64")+",\n") } - return n -} - -func (m *CommandInfo_URI) Size() (n int) { - var l int - _ = l - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovMesos(uint64(l)) + if this.LlcStoreMisses != nil { + s = append(s, "LlcStoreMisses: "+valueToGoStringMesos(this.LlcStoreMisses, "uint64")+",\n") } - if m.Executable != nil { - n += 2 + if this.LlcPrefetches != nil { + s = append(s, "LlcPrefetches: "+valueToGoStringMesos(this.LlcPrefetches, "uint64")+",\n") } - if m.Extract != nil { - n += 2 + if this.LlcPrefetchMisses != nil { + s = append(s, "LlcPrefetchMisses: "+valueToGoStringMesos(this.LlcPrefetchMisses, "uint64")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.DtlbLoads != nil { + s = append(s, "DtlbLoads: "+valueToGoStringMesos(this.DtlbLoads, "uint64")+",\n") } - return n -} - -func (m *CommandInfo_ContainerInfo) Size() (n int) { - var l int - _ = l - if m.Image != nil { - l = len(*m.Image) - n += 1 + l + sovMesos(uint64(l)) + if this.DtlbLoadMisses != nil { + s = append(s, "DtlbLoadMisses: "+valueToGoStringMesos(this.DtlbLoadMisses, "uint64")+",\n") } - if len(m.Options) > 0 { - for _, s := range m.Options { - l = len(s) - n += 1 + l + sovMesos(uint64(l)) - } + if this.DtlbStores != nil { + s = append(s, "DtlbStores: "+valueToGoStringMesos(this.DtlbStores, "uint64")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.DtlbStoreMisses != nil { + s = append(s, "DtlbStoreMisses: "+valueToGoStringMesos(this.DtlbStoreMisses, "uint64")+",\n") } - return n -} - -func (m *ExecutorInfo) Size() (n int) { - var l int - _ = l - if m.ExecutorId != nil { - l = m.ExecutorId.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.DtlbPrefetches != nil { + s = append(s, "DtlbPrefetches: "+valueToGoStringMesos(this.DtlbPrefetches, "uint64")+",\n") } - if m.FrameworkId != nil { - l = m.FrameworkId.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.DtlbPrefetchMisses != nil { + s = append(s, "DtlbPrefetchMisses: "+valueToGoStringMesos(this.DtlbPrefetchMisses, "uint64")+",\n") } - if m.Command != nil { - l = m.Command.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.ItlbLoads != nil { + s = append(s, "ItlbLoads: "+valueToGoStringMesos(this.ItlbLoads, "uint64")+",\n") } - if m.Container != nil { - l = m.Container.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.ItlbLoadMisses != nil { + s = append(s, "ItlbLoadMisses: "+valueToGoStringMesos(this.ItlbLoadMisses, "uint64")+",\n") } - if len(m.Resources) > 0 { - for _, e := range m.Resources { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + if this.BranchLoads != nil { + s = append(s, "BranchLoads: "+valueToGoStringMesos(this.BranchLoads, "uint64")+",\n") } - if m.Name != nil { - l = len(*m.Name) - n += 1 + l + sovMesos(uint64(l)) + if this.BranchLoadMisses != nil { + s = append(s, "BranchLoadMisses: "+valueToGoStringMesos(this.BranchLoadMisses, "uint64")+",\n") } - if m.Source != nil { - l = len(*m.Source) - n += 1 + l + sovMesos(uint64(l)) + if this.NodeLoads != nil { + s = append(s, "NodeLoads: "+valueToGoStringMesos(this.NodeLoads, "uint64")+",\n") } - if m.Data != nil { - l = len(m.Data) - n += 1 + l + sovMesos(uint64(l)) + if this.NodeLoadMisses != nil { + s = append(s, "NodeLoadMisses: "+valueToGoStringMesos(this.NodeLoadMisses, "uint64")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.NodeStores != nil { + s = append(s, "NodeStores: "+valueToGoStringMesos(this.NodeStores, "uint64")+",\n") } - return n -} - -func (m *MasterInfo) Size() (n int) { - var l int - _ = l - if m.Id != nil { - l = len(*m.Id) - n += 1 + l + sovMesos(uint64(l)) + if this.NodeStoreMisses != nil { + s = append(s, "NodeStoreMisses: "+valueToGoStringMesos(this.NodeStoreMisses, "uint64")+",\n") } - if m.Ip != nil { - n += 1 + sovMesos(uint64(*m.Ip)) + if this.NodePrefetches != nil { + s = append(s, "NodePrefetches: "+valueToGoStringMesos(this.NodePrefetches, "uint64")+",\n") } - if m.Port != nil { - n += 1 + sovMesos(uint64(*m.Port)) + if this.NodePrefetchMisses != nil { + s = append(s, "NodePrefetchMisses: "+valueToGoStringMesos(this.NodePrefetchMisses, "uint64")+",\n") } - if m.Pid != nil { - l = len(*m.Pid) - n += 1 + l + sovMesos(uint64(l)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.Hostname != nil { - l = len(*m.Hostname) - n += 1 + l + sovMesos(uint64(l)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Request) GoString() string { + if this == nil { + return "nil" } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + s := make([]string, 0, 6) + s = append(s, "&mesosproto.Request{") + if this.SlaveId != nil { + s = append(s, "SlaveId: "+fmt.Sprintf("%#v", this.SlaveId)+",\n") } - return n + if this.Resources != nil { + s = append(s, "Resources: "+fmt.Sprintf("%#v", this.Resources)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func (m *SlaveInfo) Size() (n int) { - var l int - _ = l - if m.Hostname != nil { - l = len(*m.Hostname) - n += 1 + l + sovMesos(uint64(l)) +func (this *Offer) GoString() string { + if this == nil { + return "nil" } - if m.Port != nil { - n += 1 + sovMesos(uint64(*m.Port)) + s := make([]string, 0, 11) + s = append(s, "&mesosproto.Offer{") + if this.Id != nil { + s = append(s, "Id: "+fmt.Sprintf("%#v", this.Id)+",\n") } - if len(m.Resources) > 0 { - for _, e := range m.Resources { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + if this.FrameworkId != nil { + s = append(s, "FrameworkId: "+fmt.Sprintf("%#v", this.FrameworkId)+",\n") } - if len(m.Attributes) > 0 { - for _, e := range m.Attributes { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + if this.SlaveId != nil { + s = append(s, "SlaveId: "+fmt.Sprintf("%#v", this.SlaveId)+",\n") } - if m.Id != nil { - l = m.Id.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Hostname != nil { + s = append(s, "Hostname: "+valueToGoStringMesos(this.Hostname, "string")+",\n") } - if m.Checkpoint != nil { - n += 2 + if this.Resources != nil { + s = append(s, "Resources: "+fmt.Sprintf("%#v", this.Resources)+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.Attributes != nil { + s = append(s, "Attributes: "+fmt.Sprintf("%#v", this.Attributes)+",\n") } - return n + if this.ExecutorIds != nil { + s = append(s, "ExecutorIds: "+fmt.Sprintf("%#v", this.ExecutorIds)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func (m *Value) Size() (n int) { - var l int - _ = l - if m.Type != nil { - n += 1 + sovMesos(uint64(*m.Type)) +func (this *Offer_Operation) GoString() string { + if this == nil { + return "nil" } - if m.Scalar != nil { - l = m.Scalar.Size() - n += 1 + l + sovMesos(uint64(l)) + s := make([]string, 0, 10) + s = append(s, "&mesosproto.Offer_Operation{") + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringMesos(this.Type, "mesosproto.Offer_Operation_Type")+",\n") + } + if this.Launch != nil { + s = append(s, "Launch: "+fmt.Sprintf("%#v", this.Launch)+",\n") } - if m.Ranges != nil { - l = m.Ranges.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Reserve != nil { + s = append(s, "Reserve: "+fmt.Sprintf("%#v", this.Reserve)+",\n") } - if m.Set != nil { - l = m.Set.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Unreserve != nil { + s = append(s, "Unreserve: "+fmt.Sprintf("%#v", this.Unreserve)+",\n") } - if m.Text != nil { - l = m.Text.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Create != nil { + s = append(s, "Create: "+fmt.Sprintf("%#v", this.Create)+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.Destroy != nil { + s = append(s, "Destroy: "+fmt.Sprintf("%#v", this.Destroy)+",\n") } - return n + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func (m *Value_Scalar) Size() (n int) { - var l int - _ = l - if m.Value != nil { - n += 9 +func (this *Offer_Operation_Launch) GoString() string { + if this == nil { + return "nil" } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Offer_Operation_Launch{") + if this.TaskInfos != nil { + s = append(s, "TaskInfos: "+fmt.Sprintf("%#v", this.TaskInfos)+",\n") } - return n + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func (m *Value_Range) Size() (n int) { - var l int - _ = l - if m.Begin != nil { - n += 1 + sovMesos(uint64(*m.Begin)) +func (this *Offer_Operation_Reserve) GoString() string { + if this == nil { + return "nil" } - if m.End != nil { - n += 1 + sovMesos(uint64(*m.End)) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Offer_Operation_Reserve{") + if this.Resources != nil { + s = append(s, "Resources: "+fmt.Sprintf("%#v", this.Resources)+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - return n + s = append(s, "}") + return strings.Join(s, "") } - -func (m *Value_Ranges) Size() (n int) { - var l int - _ = l - if len(m.Range) > 0 { - for _, e := range m.Range { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } +func (this *Offer_Operation_Unreserve) GoString() string { + if this == nil { + return "nil" } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Offer_Operation_Unreserve{") + if this.Resources != nil { + s = append(s, "Resources: "+fmt.Sprintf("%#v", this.Resources)+",\n") } - return n + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func (m *Value_Set) Size() (n int) { - var l int - _ = l - if len(m.Item) > 0 { - for _, s := range m.Item { - l = len(s) - n += 1 + l + sovMesos(uint64(l)) - } +func (this *Offer_Operation_Create) GoString() string { + if this == nil { + return "nil" } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Offer_Operation_Create{") + if this.Volumes != nil { + s = append(s, "Volumes: "+fmt.Sprintf("%#v", this.Volumes)+",\n") } - return n + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func (m *Value_Text) Size() (n int) { - var l int - _ = l - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovMesos(uint64(l)) +func (this *Offer_Operation_Destroy) GoString() string { + if this == nil { + return "nil" } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Offer_Operation_Destroy{") + if this.Volumes != nil { + s = append(s, "Volumes: "+fmt.Sprintf("%#v", this.Volumes)+",\n") } - return n -} - -func (m *Attribute) Size() (n int) { - var l int - _ = l - if m.Name != nil { - l = len(*m.Name) - n += 1 + l + sovMesos(uint64(l)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.Type != nil { - n += 1 + sovMesos(uint64(*m.Type)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *TaskInfo) GoString() string { + if this == nil { + return "nil" } - if m.Scalar != nil { - l = m.Scalar.Size() - n += 1 + l + sovMesos(uint64(l)) + s := make([]string, 0, 15) + s = append(s, "&mesosproto.TaskInfo{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringMesos(this.Name, "string")+",\n") } - if m.Ranges != nil { - l = m.Ranges.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.TaskId != nil { + s = append(s, "TaskId: "+fmt.Sprintf("%#v", this.TaskId)+",\n") } - if m.Set != nil { - l = m.Set.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.SlaveId != nil { + s = append(s, "SlaveId: "+fmt.Sprintf("%#v", this.SlaveId)+",\n") } - if m.Text != nil { - l = m.Text.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Resources != nil { + s = append(s, "Resources: "+fmt.Sprintf("%#v", this.Resources)+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.Executor != nil { + s = append(s, "Executor: "+fmt.Sprintf("%#v", this.Executor)+",\n") } - return n -} - -func (m *Resource) Size() (n int) { - var l int - _ = l - if m.Name != nil { - l = len(*m.Name) - n += 1 + l + sovMesos(uint64(l)) + if this.Command != nil { + s = append(s, "Command: "+fmt.Sprintf("%#v", this.Command)+",\n") } - if m.Type != nil { - n += 1 + sovMesos(uint64(*m.Type)) + if this.Container != nil { + s = append(s, "Container: "+fmt.Sprintf("%#v", this.Container)+",\n") } - if m.Scalar != nil { - l = m.Scalar.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Data != nil { + s = append(s, "Data: "+valueToGoStringMesos(this.Data, "byte")+",\n") } - if m.Ranges != nil { - l = m.Ranges.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.HealthCheck != nil { + s = append(s, "HealthCheck: "+fmt.Sprintf("%#v", this.HealthCheck)+",\n") } - if m.Set != nil { - l = m.Set.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Labels != nil { + s = append(s, "Labels: "+fmt.Sprintf("%#v", this.Labels)+",\n") } - if m.Role != nil { - l = len(*m.Role) - n += 1 + l + sovMesos(uint64(l)) + if this.Discovery != nil { + s = append(s, "Discovery: "+fmt.Sprintf("%#v", this.Discovery)+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - return n + s = append(s, "}") + return strings.Join(s, "") } - -func (m *ResourceStatistics) Size() (n int) { - var l int - _ = l - if m.Timestamp != nil { - n += 9 +func (this *TaskStatus) GoString() string { + if this == nil { + return "nil" } - if m.CpusUserTimeSecs != nil { - n += 9 + s := make([]string, 0, 15) + s = append(s, "&mesosproto.TaskStatus{") + if this.TaskId != nil { + s = append(s, "TaskId: "+fmt.Sprintf("%#v", this.TaskId)+",\n") } - if m.CpusSystemTimeSecs != nil { - n += 9 + if this.State != nil { + s = append(s, "State: "+valueToGoStringMesos(this.State, "mesosproto.TaskState")+",\n") } - if m.CpusLimit != nil { - n += 9 + if this.Message != nil { + s = append(s, "Message: "+valueToGoStringMesos(this.Message, "string")+",\n") } - if m.CpusNrPeriods != nil { - n += 1 + sovMesos(uint64(*m.CpusNrPeriods)) + if this.Source != nil { + s = append(s, "Source: "+valueToGoStringMesos(this.Source, "mesosproto.TaskStatus_Source")+",\n") } - if m.CpusNrThrottled != nil { - n += 1 + sovMesos(uint64(*m.CpusNrThrottled)) + if this.Reason != nil { + s = append(s, "Reason: "+valueToGoStringMesos(this.Reason, "mesosproto.TaskStatus_Reason")+",\n") } - if m.CpusThrottledTimeSecs != nil { - n += 9 + if this.Data != nil { + s = append(s, "Data: "+valueToGoStringMesos(this.Data, "byte")+",\n") } - if m.MemRssBytes != nil { - n += 1 + sovMesos(uint64(*m.MemRssBytes)) + if this.SlaveId != nil { + s = append(s, "SlaveId: "+fmt.Sprintf("%#v", this.SlaveId)+",\n") } - if m.MemLimitBytes != nil { - n += 1 + sovMesos(uint64(*m.MemLimitBytes)) + if this.ExecutorId != nil { + s = append(s, "ExecutorId: "+fmt.Sprintf("%#v", this.ExecutorId)+",\n") } - if m.MemFileBytes != nil { - n += 1 + sovMesos(uint64(*m.MemFileBytes)) + if this.Timestamp != nil { + s = append(s, "Timestamp: "+valueToGoStringMesos(this.Timestamp, "float64")+",\n") } - if m.MemAnonBytes != nil { - n += 1 + sovMesos(uint64(*m.MemAnonBytes)) + if this.Uuid != nil { + s = append(s, "Uuid: "+valueToGoStringMesos(this.Uuid, "byte")+",\n") } - if m.MemMappedFileBytes != nil { - n += 1 + sovMesos(uint64(*m.MemMappedFileBytes)) + if this.Healthy != nil { + s = append(s, "Healthy: "+valueToGoStringMesos(this.Healthy, "bool")+",\n") } - if m.Perf != nil { - l = m.Perf.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.NetRxPackets != nil { - n += 1 + sovMesos(uint64(*m.NetRxPackets)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Filters) GoString() string { + if this == nil { + return "nil" } - if m.NetRxBytes != nil { - n += 1 + sovMesos(uint64(*m.NetRxBytes)) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Filters{") + if this.RefuseSeconds != nil { + s = append(s, "RefuseSeconds: "+valueToGoStringMesos(this.RefuseSeconds, "float64")+",\n") } - if m.NetRxErrors != nil { - n += 2 + sovMesos(uint64(*m.NetRxErrors)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.NetRxDropped != nil { - n += 2 + sovMesos(uint64(*m.NetRxDropped)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Environment) GoString() string { + if this == nil { + return "nil" } - if m.NetTxPackets != nil { - n += 2 + sovMesos(uint64(*m.NetTxPackets)) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Environment{") + if this.Variables != nil { + s = append(s, "Variables: "+fmt.Sprintf("%#v", this.Variables)+",\n") } - if m.NetTxBytes != nil { - n += 2 + sovMesos(uint64(*m.NetTxBytes)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.NetTxErrors != nil { - n += 2 + sovMesos(uint64(*m.NetTxErrors)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Environment_Variable) GoString() string { + if this == nil { + return "nil" } - if m.NetTxDropped != nil { - n += 2 + sovMesos(uint64(*m.NetTxDropped)) + s := make([]string, 0, 6) + s = append(s, "&mesosproto.Environment_Variable{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringMesos(this.Name, "string")+",\n") } - if m.NetTcpRttMicrosecsP50 != nil { - n += 10 + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") } - if m.NetTcpRttMicrosecsP90 != nil { - n += 10 + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.NetTcpRttMicrosecsP95 != nil { - n += 10 + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Parameter) GoString() string { + if this == nil { + return "nil" } - if m.NetTcpRttMicrosecsP99 != nil { - n += 10 + s := make([]string, 0, 6) + s = append(s, "&mesosproto.Parameter{") + if this.Key != nil { + s = append(s, "Key: "+valueToGoStringMesos(this.Key, "string")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") } - return n + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") } - -func (m *ResourceUsage) Size() (n int) { - var l int - _ = l - if m.SlaveId != nil { - l = m.SlaveId.Size() - n += 1 + l + sovMesos(uint64(l)) +func (this *Parameters) GoString() string { + if this == nil { + return "nil" } - if m.FrameworkId != nil { - l = m.FrameworkId.Size() - n += 1 + l + sovMesos(uint64(l)) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Parameters{") + if this.Parameter != nil { + s = append(s, "Parameter: "+fmt.Sprintf("%#v", this.Parameter)+",\n") } - if m.ExecutorId != nil { - l = m.ExecutorId.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.ExecutorName != nil { - l = len(*m.ExecutorName) - n += 1 + l + sovMesos(uint64(l)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Credential) GoString() string { + if this == nil { + return "nil" } - if m.TaskId != nil { - l = m.TaskId.Size() - n += 1 + l + sovMesos(uint64(l)) + s := make([]string, 0, 6) + s = append(s, "&mesosproto.Credential{") + if this.Principal != nil { + s = append(s, "Principal: "+valueToGoStringMesos(this.Principal, "string")+",\n") } - if m.Statistics != nil { - l = m.Statistics.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Secret != nil { + s = append(s, "Secret: "+valueToGoStringMesos(this.Secret, "byte")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - return n + s = append(s, "}") + return strings.Join(s, "") } - -func (m *PerfStatistics) Size() (n int) { - var l int - _ = l - if m.Timestamp != nil { - n += 9 - } - if m.Duration != nil { - n += 9 +func (this *Credentials) GoString() string { + if this == nil { + return "nil" } - if m.Cycles != nil { - n += 1 + sovMesos(uint64(*m.Cycles)) + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Credentials{") + if this.Credentials != nil { + s = append(s, "Credentials: "+fmt.Sprintf("%#v", this.Credentials)+",\n") } - if m.StalledCyclesFrontend != nil { - n += 1 + sovMesos(uint64(*m.StalledCyclesFrontend)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.StalledCyclesBackend != nil { - n += 1 + sovMesos(uint64(*m.StalledCyclesBackend)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *ACL) GoString() string { + if this == nil { + return "nil" } - if m.Instructions != nil { - n += 1 + sovMesos(uint64(*m.Instructions)) + s := make([]string, 0, 4) + s = append(s, "&mesosproto.ACL{") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.CacheReferences != nil { - n += 1 + sovMesos(uint64(*m.CacheReferences)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *ACL_Entity) GoString() string { + if this == nil { + return "nil" } - if m.CacheMisses != nil { - n += 1 + sovMesos(uint64(*m.CacheMisses)) + s := make([]string, 0, 6) + s = append(s, "&mesosproto.ACL_Entity{") + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringMesos(this.Type, "mesosproto.ACL_Entity_Type")+",\n") } - if m.Branches != nil { - n += 1 + sovMesos(uint64(*m.Branches)) + if this.Values != nil { + s = append(s, "Values: "+fmt.Sprintf("%#v", this.Values)+",\n") } - if m.BranchMisses != nil { - n += 1 + sovMesos(uint64(*m.BranchMisses)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.BusCycles != nil { - n += 1 + sovMesos(uint64(*m.BusCycles)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *ACL_RegisterFramework) GoString() string { + if this == nil { + return "nil" } - if m.RefCycles != nil { - n += 1 + sovMesos(uint64(*m.RefCycles)) + s := make([]string, 0, 6) + s = append(s, "&mesosproto.ACL_RegisterFramework{") + if this.Principals != nil { + s = append(s, "Principals: "+fmt.Sprintf("%#v", this.Principals)+",\n") } - if m.CpuClock != nil { - n += 9 + if this.Roles != nil { + s = append(s, "Roles: "+fmt.Sprintf("%#v", this.Roles)+",\n") } - if m.TaskClock != nil { - n += 9 + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.PageFaults != nil { - n += 1 + sovMesos(uint64(*m.PageFaults)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *ACL_RunTask) GoString() string { + if this == nil { + return "nil" } - if m.MinorFaults != nil { - n += 2 + sovMesos(uint64(*m.MinorFaults)) + s := make([]string, 0, 6) + s = append(s, "&mesosproto.ACL_RunTask{") + if this.Principals != nil { + s = append(s, "Principals: "+fmt.Sprintf("%#v", this.Principals)+",\n") } - if m.MajorFaults != nil { - n += 2 + sovMesos(uint64(*m.MajorFaults)) + if this.Users != nil { + s = append(s, "Users: "+fmt.Sprintf("%#v", this.Users)+",\n") } - if m.ContextSwitches != nil { - n += 2 + sovMesos(uint64(*m.ContextSwitches)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.CpuMigrations != nil { - n += 2 + sovMesos(uint64(*m.CpuMigrations)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *ACL_ShutdownFramework) GoString() string { + if this == nil { + return "nil" } - if m.AlignmentFaults != nil { - n += 2 + sovMesos(uint64(*m.AlignmentFaults)) + s := make([]string, 0, 6) + s = append(s, "&mesosproto.ACL_ShutdownFramework{") + if this.Principals != nil { + s = append(s, "Principals: "+fmt.Sprintf("%#v", this.Principals)+",\n") } - if m.EmulationFaults != nil { - n += 2 + sovMesos(uint64(*m.EmulationFaults)) + if this.FrameworkPrincipals != nil { + s = append(s, "FrameworkPrincipals: "+fmt.Sprintf("%#v", this.FrameworkPrincipals)+",\n") } - if m.L1DcacheLoads != nil { - n += 2 + sovMesos(uint64(*m.L1DcacheLoads)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.L1DcacheLoadMisses != nil { - n += 2 + sovMesos(uint64(*m.L1DcacheLoadMisses)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *ACLs) GoString() string { + if this == nil { + return "nil" } - if m.L1DcacheStores != nil { - n += 2 + sovMesos(uint64(*m.L1DcacheStores)) + s := make([]string, 0, 8) + s = append(s, "&mesosproto.ACLs{") + if this.Permissive != nil { + s = append(s, "Permissive: "+valueToGoStringMesos(this.Permissive, "bool")+",\n") } - if m.L1DcacheStoreMisses != nil { - n += 2 + sovMesos(uint64(*m.L1DcacheStoreMisses)) + if this.RegisterFrameworks != nil { + s = append(s, "RegisterFrameworks: "+fmt.Sprintf("%#v", this.RegisterFrameworks)+",\n") } - if m.L1DcachePrefetches != nil { - n += 2 + sovMesos(uint64(*m.L1DcachePrefetches)) + if this.RunTasks != nil { + s = append(s, "RunTasks: "+fmt.Sprintf("%#v", this.RunTasks)+",\n") } - if m.L1DcachePrefetchMisses != nil { - n += 2 + sovMesos(uint64(*m.L1DcachePrefetchMisses)) + if this.ShutdownFrameworks != nil { + s = append(s, "ShutdownFrameworks: "+fmt.Sprintf("%#v", this.ShutdownFrameworks)+",\n") } - if m.L1IcacheLoads != nil { - n += 2 + sovMesos(uint64(*m.L1IcacheLoads)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.L1IcacheLoadMisses != nil { - n += 2 + sovMesos(uint64(*m.L1IcacheLoadMisses)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *RateLimit) GoString() string { + if this == nil { + return "nil" } - if m.L1IcachePrefetches != nil { - n += 2 + sovMesos(uint64(*m.L1IcachePrefetches)) + s := make([]string, 0, 7) + s = append(s, "&mesosproto.RateLimit{") + if this.Qps != nil { + s = append(s, "Qps: "+valueToGoStringMesos(this.Qps, "float64")+",\n") } - if m.L1IcachePrefetchMisses != nil { - n += 2 + sovMesos(uint64(*m.L1IcachePrefetchMisses)) + if this.Principal != nil { + s = append(s, "Principal: "+valueToGoStringMesos(this.Principal, "string")+",\n") } - if m.LlcLoads != nil { - n += 2 + sovMesos(uint64(*m.LlcLoads)) + if this.Capacity != nil { + s = append(s, "Capacity: "+valueToGoStringMesos(this.Capacity, "uint64")+",\n") } - if m.LlcLoadMisses != nil { - n += 2 + sovMesos(uint64(*m.LlcLoadMisses)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.LlcStores != nil { - n += 2 + sovMesos(uint64(*m.LlcStores)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *RateLimits) GoString() string { + if this == nil { + return "nil" } - if m.LlcStoreMisses != nil { - n += 2 + sovMesos(uint64(*m.LlcStoreMisses)) + s := make([]string, 0, 7) + s = append(s, "&mesosproto.RateLimits{") + if this.Limits != nil { + s = append(s, "Limits: "+fmt.Sprintf("%#v", this.Limits)+",\n") } - if m.LlcPrefetches != nil { - n += 2 + sovMesos(uint64(*m.LlcPrefetches)) + if this.AggregateDefaultQps != nil { + s = append(s, "AggregateDefaultQps: "+valueToGoStringMesos(this.AggregateDefaultQps, "float64")+",\n") } - if m.LlcPrefetchMisses != nil { - n += 2 + sovMesos(uint64(*m.LlcPrefetchMisses)) + if this.AggregateDefaultCapacity != nil { + s = append(s, "AggregateDefaultCapacity: "+valueToGoStringMesos(this.AggregateDefaultCapacity, "uint64")+",\n") } - if m.DtlbLoads != nil { - n += 2 + sovMesos(uint64(*m.DtlbLoads)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.DtlbLoadMisses != nil { - n += 2 + sovMesos(uint64(*m.DtlbLoadMisses)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Volume) GoString() string { + if this == nil { + return "nil" } - if m.DtlbStores != nil { - n += 2 + sovMesos(uint64(*m.DtlbStores)) + s := make([]string, 0, 7) + s = append(s, "&mesosproto.Volume{") + if this.ContainerPath != nil { + s = append(s, "ContainerPath: "+valueToGoStringMesos(this.ContainerPath, "string")+",\n") } - if m.DtlbStoreMisses != nil { - n += 2 + sovMesos(uint64(*m.DtlbStoreMisses)) + if this.HostPath != nil { + s = append(s, "HostPath: "+valueToGoStringMesos(this.HostPath, "string")+",\n") } - if m.DtlbPrefetches != nil { - n += 2 + sovMesos(uint64(*m.DtlbPrefetches)) + if this.Mode != nil { + s = append(s, "Mode: "+valueToGoStringMesos(this.Mode, "mesosproto.Volume_Mode")+",\n") } - if m.DtlbPrefetchMisses != nil { - n += 2 + sovMesos(uint64(*m.DtlbPrefetchMisses)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.ItlbLoads != nil { - n += 2 + sovMesos(uint64(*m.ItlbLoads)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *ContainerInfo) GoString() string { + if this == nil { + return "nil" } - if m.ItlbLoadMisses != nil { - n += 2 + sovMesos(uint64(*m.ItlbLoadMisses)) + s := make([]string, 0, 8) + s = append(s, "&mesosproto.ContainerInfo{") + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringMesos(this.Type, "mesosproto.ContainerInfo_Type")+",\n") } - if m.BranchLoads != nil { - n += 2 + sovMesos(uint64(*m.BranchLoads)) + if this.Volumes != nil { + s = append(s, "Volumes: "+fmt.Sprintf("%#v", this.Volumes)+",\n") } - if m.BranchLoadMisses != nil { - n += 2 + sovMesos(uint64(*m.BranchLoadMisses)) + if this.Hostname != nil { + s = append(s, "Hostname: "+valueToGoStringMesos(this.Hostname, "string")+",\n") } - if m.NodeLoads != nil { - n += 2 + sovMesos(uint64(*m.NodeLoads)) + if this.Docker != nil { + s = append(s, "Docker: "+fmt.Sprintf("%#v", this.Docker)+",\n") } - if m.NodeLoadMisses != nil { - n += 2 + sovMesos(uint64(*m.NodeLoadMisses)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.NodeStores != nil { - n += 2 + sovMesos(uint64(*m.NodeStores)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *ContainerInfo_DockerInfo) GoString() string { + if this == nil { + return "nil" } - if m.NodeStoreMisses != nil { - n += 2 + sovMesos(uint64(*m.NodeStoreMisses)) + s := make([]string, 0, 10) + s = append(s, "&mesosproto.ContainerInfo_DockerInfo{") + if this.Image != nil { + s = append(s, "Image: "+valueToGoStringMesos(this.Image, "string")+",\n") } - if m.NodePrefetches != nil { - n += 2 + sovMesos(uint64(*m.NodePrefetches)) + if this.Network != nil { + s = append(s, "Network: "+valueToGoStringMesos(this.Network, "mesosproto.ContainerInfo_DockerInfo_Network")+",\n") } - if m.NodePrefetchMisses != nil { - n += 2 + sovMesos(uint64(*m.NodePrefetchMisses)) + if this.PortMappings != nil { + s = append(s, "PortMappings: "+fmt.Sprintf("%#v", this.PortMappings)+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.Privileged != nil { + s = append(s, "Privileged: "+valueToGoStringMesos(this.Privileged, "bool")+",\n") } - return n -} - -func (m *Request) Size() (n int) { - var l int - _ = l - if m.SlaveId != nil { - l = m.SlaveId.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Parameters != nil { + s = append(s, "Parameters: "+fmt.Sprintf("%#v", this.Parameters)+",\n") } - if len(m.Resources) > 0 { - for _, e := range m.Resources { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + if this.ForcePullImage != nil { + s = append(s, "ForcePullImage: "+valueToGoStringMesos(this.ForcePullImage, "bool")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - return n + s = append(s, "}") + return strings.Join(s, "") } - -func (m *Offer) Size() (n int) { - var l int - _ = l - if m.Id != nil { - l = m.Id.Size() - n += 1 + l + sovMesos(uint64(l)) +func (this *ContainerInfo_DockerInfo_PortMapping) GoString() string { + if this == nil { + return "nil" } - if m.FrameworkId != nil { - l = m.FrameworkId.Size() - n += 1 + l + sovMesos(uint64(l)) + s := make([]string, 0, 7) + s = append(s, "&mesosproto.ContainerInfo_DockerInfo_PortMapping{") + if this.HostPort != nil { + s = append(s, "HostPort: "+valueToGoStringMesos(this.HostPort, "uint32")+",\n") } - if m.SlaveId != nil { - l = m.SlaveId.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.ContainerPort != nil { + s = append(s, "ContainerPort: "+valueToGoStringMesos(this.ContainerPort, "uint32")+",\n") } - if m.Hostname != nil { - l = len(*m.Hostname) - n += 1 + l + sovMesos(uint64(l)) + if this.Protocol != nil { + s = append(s, "Protocol: "+valueToGoStringMesos(this.Protocol, "string")+",\n") } - if len(m.Resources) > 0 { - for _, e := range m.Resources { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if len(m.Attributes) > 0 { - for _, e := range m.Attributes { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Labels) GoString() string { + if this == nil { + return "nil" } - if len(m.ExecutorIds) > 0 { - for _, e := range m.ExecutorIds { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Labels{") + if this.Labels != nil { + s = append(s, "Labels: "+fmt.Sprintf("%#v", this.Labels)+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - return n + s = append(s, "}") + return strings.Join(s, "") } - -func (m *TaskInfo) Size() (n int) { - var l int - _ = l - if m.Name != nil { - l = len(*m.Name) - n += 1 + l + sovMesos(uint64(l)) - } - if m.TaskId != nil { - l = m.TaskId.Size() - n += 1 + l + sovMesos(uint64(l)) +func (this *Label) GoString() string { + if this == nil { + return "nil" } - if m.SlaveId != nil { - l = m.SlaveId.Size() - n += 1 + l + sovMesos(uint64(l)) + s := make([]string, 0, 6) + s = append(s, "&mesosproto.Label{") + if this.Key != nil { + s = append(s, "Key: "+valueToGoStringMesos(this.Key, "string")+",\n") } - if len(m.Resources) > 0 { - for _, e := range m.Resources { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringMesos(this.Value, "string")+",\n") } - if m.Executor != nil { - l = m.Executor.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.Command != nil { - l = m.Command.Size() - n += 1 + l + sovMesos(uint64(l)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Port) GoString() string { + if this == nil { + return "nil" } - if m.Container != nil { - l = m.Container.Size() - n += 1 + l + sovMesos(uint64(l)) + s := make([]string, 0, 7) + s = append(s, "&mesosproto.Port{") + if this.Number != nil { + s = append(s, "Number: "+valueToGoStringMesos(this.Number, "uint32")+",\n") } - if m.Data != nil { - l = len(m.Data) - n += 1 + l + sovMesos(uint64(l)) + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringMesos(this.Name, "string")+",\n") } - if m.HealthCheck != nil { - l = m.HealthCheck.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Protocol != nil { + s = append(s, "Protocol: "+valueToGoStringMesos(this.Protocol, "string")+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - return n + s = append(s, "}") + return strings.Join(s, "") } - -func (m *TaskStatus) Size() (n int) { - var l int - _ = l - if m.TaskId != nil { - l = m.TaskId.Size() - n += 1 + l + sovMesos(uint64(l)) +func (this *Ports) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Ports{") + if this.Ports != nil { + s = append(s, "Ports: "+fmt.Sprintf("%#v", this.Ports)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.State != nil { - n += 1 + sovMesos(uint64(*m.State)) + s = append(s, "}") + return strings.Join(s, "") +} +func (this *DiscoveryInfo) GoString() string { + if this == nil { + return "nil" } - if m.Message != nil { - l = len(*m.Message) - n += 1 + l + sovMesos(uint64(l)) + s := make([]string, 0, 11) + s = append(s, "&mesosproto.DiscoveryInfo{") + if this.Visibility != nil { + s = append(s, "Visibility: "+valueToGoStringMesos(this.Visibility, "mesosproto.DiscoveryInfo_Visibility")+",\n") } - if m.Source != nil { - n += 1 + sovMesos(uint64(*m.Source)) + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringMesos(this.Name, "string")+",\n") } - if m.Reason != nil { - n += 1 + sovMesos(uint64(*m.Reason)) + if this.Environment != nil { + s = append(s, "Environment: "+valueToGoStringMesos(this.Environment, "string")+",\n") } - if m.Data != nil { - l = len(m.Data) - n += 1 + l + sovMesos(uint64(l)) + if this.Location != nil { + s = append(s, "Location: "+valueToGoStringMesos(this.Location, "string")+",\n") } - if m.SlaveId != nil { - l = m.SlaveId.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Version != nil { + s = append(s, "Version: "+valueToGoStringMesos(this.Version, "string")+",\n") } - if m.ExecutorId != nil { - l = m.ExecutorId.Size() - n += 1 + l + sovMesos(uint64(l)) + if this.Ports != nil { + s = append(s, "Ports: "+fmt.Sprintf("%#v", this.Ports)+",\n") } - if m.Timestamp != nil { - n += 9 + if this.Labels != nil { + s = append(s, "Labels: "+fmt.Sprintf("%#v", this.Labels)+",\n") } - if m.Healthy != nil { - n += 2 + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + s = append(s, "}") + return strings.Join(s, "") +} +func valueToGoStringMesos(v interface{}, typ string) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" } - return n + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) } - -func (m *Filters) Size() (n int) { - var l int - _ = l - if m.RefuseSeconds != nil { - n += 9 +func extensionToGoStringMesos(e map[int32]github_com_gogo_protobuf_proto.Extension) string { + if e == nil { + return "nil" } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + s := "map[int32]proto.Extension{" + keys := make([]int, 0, len(e)) + for k := range e { + keys = append(keys, int(k)) } - return n -} - -func (m *Environment) Size() (n int) { - var l int - _ = l - if len(m.Variables) > 0 { - for _, e := range m.Variables { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + sort.Ints(keys) + ss := []string{} + for _, k := range keys { + ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString()) } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + s += strings.Join(ss, ",") + "}" + return s +} +func (m *FrameworkID) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return n + return data[:n], nil } -func (m *Environment_Variable) Size() (n int) { +func (m *FrameworkID) MarshalTo(data []byte) (int, error) { + var i int + _ = i var l int _ = l - if m.Name != nil { - l = len(*m.Name) - n += 1 + l + sovMesos(uint64(l)) - } - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovMesos(uint64(l)) + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i += copy(data[i:], m.XXX_unrecognized) } - return n + return i, nil } -func (m *Parameter) Size() (n int) { - var l int - _ = l - if m.Key != nil { - l = len(*m.Key) - n += 1 + l + sovMesos(uint64(l)) - } - if m.Value != nil { - l = len(*m.Value) - n += 1 + l + sovMesos(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) +func (m *OfferID) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return n + return data[:n], nil } -func (m *Parameters) Size() (n int) { +func (m *OfferID) MarshalTo(data []byte) (int, error) { + var i int + _ = i var l int _ = l - if len(m.Parameter) > 0 { - for _, e := range m.Parameter { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i += copy(data[i:], m.XXX_unrecognized) } - return n + return i, nil } -func (m *Credential) Size() (n int) { - var l int - _ = l - if m.Principal != nil { - l = len(*m.Principal) - n += 1 + l + sovMesos(uint64(l)) - } - if m.Secret != nil { - l = len(m.Secret) - n += 1 + l + sovMesos(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) +func (m *SlaveID) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return n + return data[:n], nil } -func (m *Credentials) Size() (n int) { +func (m *SlaveID) MarshalTo(data []byte) (int, error) { + var i int + _ = i var l int _ = l - if len(m.Credentials) > 0 { - for _, e := range m.Credentials { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i += copy(data[i:], m.XXX_unrecognized) } - return n + return i, nil } -func (m *ACL) Size() (n int) { - var l int - _ = l - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) +func (m *TaskID) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return n + return data[:n], nil } -func (m *ACL_Entity) Size() (n int) { +func (m *TaskID) MarshalTo(data []byte) (int, error) { + var i int + _ = i var l int _ = l - if m.Type != nil { - n += 1 + sovMesos(uint64(*m.Type)) - } - if len(m.Values) > 0 { - for _, s := range m.Values { - l = len(s) - n += 1 + l + sovMesos(uint64(l)) - } + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i += copy(data[i:], m.XXX_unrecognized) } - return n + return i, nil } -func (m *ACL_RegisterFramework) Size() (n int) { - var l int - _ = l - if m.Principals != nil { - l = m.Principals.Size() - n += 1 + l + sovMesos(uint64(l)) - } - if m.Roles != nil { - l = m.Roles.Size() - n += 1 + l + sovMesos(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) +func (m *ExecutorID) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return n + return data[:n], nil } -func (m *ACL_RunTask) Size() (n int) { +func (m *ExecutorID) MarshalTo(data []byte) (int, error) { + var i int + _ = i var l int _ = l - if m.Principals != nil { - l = m.Principals.Size() - n += 1 + l + sovMesos(uint64(l)) - } - if m.Users != nil { - l = m.Users.Size() - n += 1 + l + sovMesos(uint64(l)) + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i += copy(data[i:], m.XXX_unrecognized) } - return n + return i, nil } -func (m *ACL_ShutdownFramework) Size() (n int) { - var l int - _ = l - if m.Principals != nil { - l = m.Principals.Size() - n += 1 + l + sovMesos(uint64(l)) +func (m *ContainerID) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if m.FrameworkPrincipals != nil { - l = m.FrameworkPrincipals.Size() - n += 1 + l + sovMesos(uint64(l)) + return data[:n], nil +} + +func (m *ContainerID) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i += copy(data[i:], m.XXX_unrecognized) } - return n + return i, nil } -func (m *ACLs) Size() (n int) { +func (m *FrameworkInfo) 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 *FrameworkInfo) MarshalTo(data []byte) (int, error) { + var i int + _ = i var l int _ = l - if m.Permissive != nil { - n += 2 + if m.User == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("user") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.User))) + i += copy(data[i:], *m.User) } - if len(m.RegisterFrameworks) > 0 { - for _, e := range m.RegisterFrameworks { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } + if m.Name == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } else { + data[i] = 0x12 + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Name))) + i += copy(data[i:], *m.Name) } - if len(m.RunTasks) > 0 { - for _, e := range m.RunTasks { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) + if m.Id != nil { + data[i] = 0x1a + i++ + i = encodeVarintMesos(data, i, uint64(m.Id.Size())) + n1, err := m.Id.MarshalTo(data[i:]) + if err != nil { + return 0, err } + i += n1 } - if len(m.ShutdownFrameworks) > 0 { - for _, e := range m.ShutdownFrameworks { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) + if m.FailoverTimeout != nil { + data[i] = 0x21 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.FailoverTimeout))) + } + if m.Checkpoint != nil { + data[i] = 0x28 + i++ + if *m.Checkpoint { + data[i] = 1 + } else { + data[i] = 0 } + i++ } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if m.Role != nil { + data[i] = 0x32 + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Role))) + i += copy(data[i:], *m.Role) } - return n -} - -func (m *RateLimit) Size() (n int) { - var l int - _ = l - if m.Qps != nil { - n += 9 + if m.Hostname != nil { + data[i] = 0x3a + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Hostname))) + i += copy(data[i:], *m.Hostname) } if m.Principal != nil { - l = len(*m.Principal) - n += 1 + l + sovMesos(uint64(l)) + data[i] = 0x42 + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Principal))) + i += copy(data[i:], *m.Principal) } - if m.Capacity != nil { - n += 1 + sovMesos(uint64(*m.Capacity)) + if m.WebuiUrl != nil { + data[i] = 0x4a + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.WebuiUrl))) + i += copy(data[i:], *m.WebuiUrl) + } + if len(m.Capabilities) > 0 { + for _, msg := range m.Capabilities { + data[i] = 0x52 + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i += copy(data[i:], m.XXX_unrecognized) } - return n + return i, nil } -func (m *RateLimits) Size() (n int) { - var l int - _ = l - if len(m.Limits) > 0 { - for _, e := range m.Limits { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } - } - if m.AggregateDefaultQps != nil { - n += 9 - } - if m.AggregateDefaultCapacity != nil { - n += 1 + sovMesos(uint64(*m.AggregateDefaultCapacity)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) +func (m *FrameworkInfo_Capability) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return n + return data[:n], nil } -func (m *Volume) Size() (n int) { +func (m *FrameworkInfo_Capability) MarshalTo(data []byte) (int, error) { + var i int + _ = i var l int _ = l - if m.ContainerPath != nil { - l = len(*m.ContainerPath) - n += 1 + l + sovMesos(uint64(l)) - } - if m.HostPath != nil { - l = len(*m.HostPath) - n += 1 + l + sovMesos(uint64(l)) - } - if m.Mode != nil { - n += 1 + sovMesos(uint64(*m.Mode)) + if m.Type == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } else { + data[i] = 0x8 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Type)) } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i += copy(data[i:], m.XXX_unrecognized) } - return n + return i, nil } -func (m *ContainerInfo) Size() (n int) { +func (m *HealthCheck) 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 *HealthCheck) MarshalTo(data []byte) (int, error) { + var i int + _ = i var l int _ = l - if m.Type != nil { - n += 1 + sovMesos(uint64(*m.Type)) - } - if len(m.Volumes) > 0 { - for _, e := range m.Volumes { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) + if m.Http != nil { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(m.Http.Size())) + n2, err := m.Http.MarshalTo(data[i:]) + if err != nil { + return 0, err } + i += n2 } - if m.Hostname != nil { - l = len(*m.Hostname) - n += 1 + l + sovMesos(uint64(l)) + if m.DelaySeconds != nil { + data[i] = 0x11 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.DelaySeconds))) } - if m.Docker != nil { - l = m.Docker.Size() - n += 1 + l + sovMesos(uint64(l)) + if m.IntervalSeconds != nil { + data[i] = 0x19 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.IntervalSeconds))) + } + if m.TimeoutSeconds != nil { + data[i] = 0x21 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.TimeoutSeconds))) + } + if m.ConsecutiveFailures != nil { + data[i] = 0x28 + i++ + i = encodeVarintMesos(data, i, uint64(*m.ConsecutiveFailures)) + } + if m.GracePeriodSeconds != nil { + data[i] = 0x31 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.GracePeriodSeconds))) + } + if m.Command != nil { + data[i] = 0x3a + i++ + i = encodeVarintMesos(data, i, uint64(m.Command.Size())) + n3, err := m.Command.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n3 } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i += copy(data[i:], m.XXX_unrecognized) } - return n + return i, nil } -func (m *ContainerInfo_DockerInfo) Size() (n int) { +func (m *HealthCheck_HTTP) 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 *HealthCheck_HTTP) MarshalTo(data []byte) (int, error) { + var i int + _ = i var l int _ = l - if m.Image != nil { - l = len(*m.Image) - n += 1 + l + sovMesos(uint64(l)) - } - if m.Network != nil { - n += 1 + sovMesos(uint64(*m.Network)) - } - if len(m.PortMappings) > 0 { - for _, e := range m.PortMappings { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) - } - } - if m.Privileged != nil { - n += 2 + if m.Port == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("port") + } else { + data[i] = 0x8 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Port)) } - if len(m.Parameters) > 0 { - for _, e := range m.Parameters { - l = e.Size() - n += 1 + l + sovMesos(uint64(l)) + if m.Path != nil { + data[i] = 0x12 + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Path))) + i += copy(data[i:], *m.Path) + } + if len(m.Statuses) > 0 { + for _, num := range m.Statuses { + data[i] = 0x20 + i++ + i = encodeVarintMesos(data, i, uint64(num)) } } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i += copy(data[i:], m.XXX_unrecognized) } - return n + return i, nil } -func (m *ContainerInfo_DockerInfo_PortMapping) Size() (n int) { +func (m *CommandInfo) 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 *CommandInfo) MarshalTo(data []byte) (int, error) { + var i int + _ = i var l int _ = l - if m.HostPort != nil { - n += 1 + sovMesos(uint64(*m.HostPort)) - } - if m.ContainerPort != nil { - n += 1 + sovMesos(uint64(*m.ContainerPort)) + if len(m.Uris) > 0 { + for _, msg := range m.Uris { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } } - if m.Protocol != nil { - l = len(*m.Protocol) - n += 1 + l + sovMesos(uint64(l)) + if m.Environment != nil { + data[i] = 0x12 + i++ + i = encodeVarintMesos(data, i, uint64(m.Environment.Size())) + n4, err := m.Environment.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n4 } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if m.Value != nil { + data[i] = 0x1a + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } - return n -} - -func sovMesos(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break + if m.Container != nil { + data[i] = 0x22 + i++ + i = encodeVarintMesos(data, i, uint64(m.Container.Size())) + n5, err := m.Container.MarshalTo(data[i:]) + if err != nil { + return 0, err } + i += n5 } - return n -} -func sozMesos(x uint64) (n int) { - return sovMesos(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func NewPopulatedFrameworkID(r randyMesos, easy bool) *FrameworkID { - this := &FrameworkID{} - v1 := randStringMesos(r) - this.Value = &v1 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + if m.User != nil { + data[i] = 0x2a + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.User))) + i += copy(data[i:], *m.User) } - return this -} - -func NewPopulatedOfferID(r randyMesos, easy bool) *OfferID { - this := &OfferID{} - v2 := randStringMesos(r) - this.Value = &v2 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + if m.Shell != nil { + data[i] = 0x30 + i++ + if *m.Shell { + data[i] = 1 + } else { + data[i] = 0 + } + i++ } - return this -} - -func NewPopulatedSlaveID(r randyMesos, easy bool) *SlaveID { - this := &SlaveID{} - v3 := randStringMesos(r) - this.Value = &v3 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + if len(m.Arguments) > 0 { + for _, s := range m.Arguments { + data[i] = 0x3a + 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 this -} - -func NewPopulatedTaskID(r randyMesos, easy bool) *TaskID { - this := &TaskID{} - v4 := randStringMesos(r) - this.Value = &v4 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - return this + return i, nil } -func NewPopulatedExecutorID(r randyMesos, easy bool) *ExecutorID { - this := &ExecutorID{} - v5 := randStringMesos(r) - this.Value = &v5 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) +func (m *CommandInfo_URI) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedContainerID(r randyMesos, easy bool) *ContainerID { - this := &ContainerID{} - v6 := randStringMesos(r) - this.Value = &v6 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) +func (m *CommandInfo_URI) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } - return this -} - -func NewPopulatedFrameworkInfo(r randyMesos, easy bool) *FrameworkInfo { - this := &FrameworkInfo{} - v7 := randStringMesos(r) - this.User = &v7 - v8 := randStringMesos(r) - this.Name = &v8 - if r.Intn(10) != 0 { - this.Id = NewPopulatedFrameworkID(r, easy) + if m.Executable != nil { + data[i] = 0x10 + i++ + if *m.Executable { + data[i] = 1 + } else { + data[i] = 0 + } + i++ } - if r.Intn(10) != 0 { - v9 := r.Float64() - if r.Intn(2) == 0 { - v9 *= -1 + if m.Extract != nil { + data[i] = 0x18 + i++ + if *m.Extract { + data[i] = 1 + } else { + data[i] = 0 } - this.FailoverTimeout = &v9 + i++ } - if r.Intn(10) != 0 { - v10 := bool(r.Intn(2) == 0) - this.Checkpoint = &v10 + if m.Cache != nil { + data[i] = 0x20 + i++ + if *m.Cache { + data[i] = 1 + } else { + data[i] = 0 + } + i++ } - if r.Intn(10) != 0 { - v11 := randStringMesos(r) - this.Role = &v11 + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if r.Intn(10) != 0 { - v12 := randStringMesos(r) - this.Hostname = &v12 + return i, nil +} + +func (m *CommandInfo_ContainerInfo) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if r.Intn(10) != 0 { - v13 := randStringMesos(r) - this.Principal = &v13 + return data[:n], nil +} + +func (m *CommandInfo_ContainerInfo) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Image == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("image") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Image))) + i += copy(data[i:], *m.Image) } - if r.Intn(10) != 0 { - v14 := randStringMesos(r) - this.WebuiUrl = &v14 + if len(m.Options) > 0 { + for _, s := range m.Options { + data[i] = 0x12 + 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) + } } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 10) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - return this + return i, nil } -func NewPopulatedHealthCheck(r randyMesos, easy bool) *HealthCheck { - this := &HealthCheck{} - if r.Intn(10) != 0 { - this.Http = NewPopulatedHealthCheck_HTTP(r, easy) +func (m *ExecutorInfo) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if r.Intn(10) != 0 { - v15 := r.Float64() - if r.Intn(2) == 0 { - v15 *= -1 + return data[:n], nil +} + +func (m *ExecutorInfo) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.ExecutorId == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("executor_id") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(m.ExecutorId.Size())) + n6, err := m.ExecutorId.MarshalTo(data[i:]) + if err != nil { + return 0, err } - this.DelaySeconds = &v15 + i += n6 } - if r.Intn(10) != 0 { - v16 := r.Float64() - if r.Intn(2) == 0 { - v16 *= -1 - } - this.IntervalSeconds = &v16 + if m.Data != nil { + data[i] = 0x22 + i++ + i = encodeVarintMesos(data, i, uint64(len(m.Data))) + i += copy(data[i:], m.Data) } - if r.Intn(10) != 0 { - v17 := r.Float64() - if r.Intn(2) == 0 { - v17 *= -1 + if len(m.Resources) > 0 { + for _, msg := range m.Resources { + data[i] = 0x2a + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n } - this.TimeoutSeconds = &v17 } - if r.Intn(10) != 0 { - v18 := r.Uint32() - this.ConsecutiveFailures = &v18 + if m.Command == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("command") + } else { + data[i] = 0x3a + i++ + i = encodeVarintMesos(data, i, uint64(m.Command.Size())) + n7, err := m.Command.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n7 } - if r.Intn(10) != 0 { - v19 := r.Float64() - if r.Intn(2) == 0 { - v19 *= -1 + if m.FrameworkId != nil { + data[i] = 0x42 + i++ + i = encodeVarintMesos(data, i, uint64(m.FrameworkId.Size())) + n8, err := m.FrameworkId.MarshalTo(data[i:]) + if err != nil { + return 0, err } - this.GracePeriodSeconds = &v19 + i += n8 } - if r.Intn(10) != 0 { - this.Command = NewPopulatedCommandInfo(r, easy) + if m.Name != nil { + data[i] = 0x4a + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Name))) + i += copy(data[i:], *m.Name) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 8) + if m.Source != nil { + data[i] = 0x52 + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Source))) + i += copy(data[i:], *m.Source) } - return this -} - -func NewPopulatedHealthCheck_HTTP(r randyMesos, easy bool) *HealthCheck_HTTP { - this := &HealthCheck_HTTP{} - v20 := r.Uint32() - this.Port = &v20 - if r.Intn(10) != 0 { - v21 := randStringMesos(r) - this.Path = &v21 + if m.Container != nil { + data[i] = 0x5a + i++ + i = encodeVarintMesos(data, i, uint64(m.Container.Size())) + n9, err := m.Container.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n9 } - if r.Intn(10) != 0 { - v22 := r.Intn(100) - this.Statuses = make([]uint32, v22) - for i := 0; i < v22; i++ { - this.Statuses[i] = r.Uint32() + if m.Discovery != nil { + data[i] = 0x62 + i++ + i = encodeVarintMesos(data, i, uint64(m.Discovery.Size())) + n10, err := m.Discovery.MarshalTo(data[i:]) + if err != nil { + return 0, err } + i += n10 } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 5) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - return this + return i, nil } -func NewPopulatedCommandInfo(r randyMesos, easy bool) *CommandInfo { - this := &CommandInfo{} - if r.Intn(10) != 0 { - this.Container = NewPopulatedCommandInfo_ContainerInfo(r, easy) - } - if r.Intn(10) != 0 { - v23 := r.Intn(10) - this.Uris = make([]*CommandInfo_URI, v23) - for i := 0; i < v23; i++ { - this.Uris[i] = NewPopulatedCommandInfo_URI(r, easy) - } - } - if r.Intn(10) != 0 { - this.Environment = NewPopulatedEnvironment(r, easy) - } - if r.Intn(10) != 0 { - v24 := bool(r.Intn(2) == 0) - this.Shell = &v24 +func (m *MasterInfo) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if r.Intn(10) != 0 { - v25 := randStringMesos(r) - this.Value = &v25 + return data[:n], nil +} + +func (m *MasterInfo) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Id == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Id))) + i += copy(data[i:], *m.Id) } - if r.Intn(10) != 0 { - v26 := r.Intn(10) - this.Arguments = make([]string, v26) - for i := 0; i < v26; i++ { - this.Arguments[i] = randStringMesos(r) - } + if m.Ip == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("ip") + } else { + data[i] = 0x10 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Ip)) } - if r.Intn(10) != 0 { - v27 := randStringMesos(r) - this.User = &v27 + if m.Port == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("port") + } else { + data[i] = 0x18 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Port)) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 8) + if m.Pid != nil { + data[i] = 0x22 + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Pid))) + i += copy(data[i:], *m.Pid) } - return this -} - -func NewPopulatedCommandInfo_URI(r randyMesos, easy bool) *CommandInfo_URI { - this := &CommandInfo_URI{} - v28 := randStringMesos(r) - this.Value = &v28 - if r.Intn(10) != 0 { - v29 := bool(r.Intn(2) == 0) - this.Executable = &v29 + if m.Hostname != nil { + data[i] = 0x2a + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Hostname))) + i += copy(data[i:], *m.Hostname) } - if r.Intn(10) != 0 { - v30 := bool(r.Intn(2) == 0) - this.Extract = &v30 + if m.Version != nil { + data[i] = 0x32 + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Version))) + i += copy(data[i:], *m.Version) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 4) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - return this + return i, nil } -func NewPopulatedCommandInfo_ContainerInfo(r randyMesos, easy bool) *CommandInfo_ContainerInfo { - this := &CommandInfo_ContainerInfo{} - v31 := randStringMesos(r) - this.Image = &v31 - if r.Intn(10) != 0 { - v32 := r.Intn(10) - this.Options = make([]string, v32) - for i := 0; i < v32; i++ { - this.Options[i] = randStringMesos(r) - } - } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 3) +func (m *SlaveInfo) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedExecutorInfo(r randyMesos, easy bool) *ExecutorInfo { - this := &ExecutorInfo{} - this.ExecutorId = NewPopulatedExecutorID(r, easy) - if r.Intn(10) != 0 { - this.FrameworkId = NewPopulatedFrameworkID(r, easy) - } - this.Command = NewPopulatedCommandInfo(r, easy) - if r.Intn(10) != 0 { - this.Container = NewPopulatedContainerInfo(r, easy) +func (m *SlaveInfo) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Hostname == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("hostname") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Hostname))) + i += copy(data[i:], *m.Hostname) } - if r.Intn(10) != 0 { - v33 := r.Intn(10) - this.Resources = make([]*Resource, v33) - for i := 0; i < v33; i++ { - this.Resources[i] = NewPopulatedResource(r, easy) + if len(m.Resources) > 0 { + for _, msg := range m.Resources { + data[i] = 0x1a + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n } } - if r.Intn(10) != 0 { - v34 := randStringMesos(r) - this.Name = &v34 + if len(m.Attributes) > 0 { + for _, msg := range m.Attributes { + data[i] = 0x2a + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } } - if r.Intn(10) != 0 { - v35 := randStringMesos(r) - this.Source = &v35 + if m.Id != nil { + data[i] = 0x32 + i++ + i = encodeVarintMesos(data, i, uint64(m.Id.Size())) + n11, err := m.Id.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n11 } - if r.Intn(10) != 0 { - v36 := r.Intn(100) - this.Data = make([]byte, v36) - for i := 0; i < v36; i++ { - this.Data[i] = byte(r.Intn(256)) + if m.Checkpoint != nil { + data[i] = 0x38 + i++ + if *m.Checkpoint { + data[i] = 1 + } else { + data[i] = 0 } + i++ } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 12) + if m.Port != nil { + data[i] = 0x40 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Port)) } - return this + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil } -func NewPopulatedMasterInfo(r randyMesos, easy bool) *MasterInfo { - this := &MasterInfo{} - v37 := randStringMesos(r) - this.Id = &v37 - v38 := r.Uint32() - this.Ip = &v38 - v39 := r.Uint32() - this.Port = &v39 - if r.Intn(10) != 0 { - v40 := randStringMesos(r) - this.Pid = &v40 - } - if r.Intn(10) != 0 { - v41 := randStringMesos(r) - this.Hostname = &v41 - } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 6) +func (m *Value) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedSlaveInfo(r randyMesos, easy bool) *SlaveInfo { - this := &SlaveInfo{} - v42 := randStringMesos(r) - this.Hostname = &v42 - if r.Intn(10) != 0 { - v43 := r.Int31() - if r.Intn(2) == 0 { - v43 *= -1 - } - this.Port = &v43 +func (m *Value) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Type == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } else { + data[i] = 0x8 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Type)) } - if r.Intn(10) != 0 { - v44 := r.Intn(10) - this.Resources = make([]*Resource, v44) - for i := 0; i < v44; i++ { - this.Resources[i] = NewPopulatedResource(r, easy) + if m.Scalar != nil { + data[i] = 0x12 + i++ + i = encodeVarintMesos(data, i, uint64(m.Scalar.Size())) + n12, err := m.Scalar.MarshalTo(data[i:]) + if err != nil { + return 0, err } + i += n12 } - if r.Intn(10) != 0 { - v45 := r.Intn(10) - this.Attributes = make([]*Attribute, v45) - for i := 0; i < v45; i++ { - this.Attributes[i] = NewPopulatedAttribute(r, easy) + if m.Ranges != nil { + data[i] = 0x1a + i++ + i = encodeVarintMesos(data, i, uint64(m.Ranges.Size())) + n13, err := m.Ranges.MarshalTo(data[i:]) + if err != nil { + return 0, err } + i += n13 } - if r.Intn(10) != 0 { - this.Id = NewPopulatedSlaveID(r, easy) + if m.Set != nil { + data[i] = 0x22 + i++ + i = encodeVarintMesos(data, i, uint64(m.Set.Size())) + n14, err := m.Set.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n14 } - if r.Intn(10) != 0 { - v46 := bool(r.Intn(2) == 0) - this.Checkpoint = &v46 + if m.Text != nil { + data[i] = 0x2a + i++ + i = encodeVarintMesos(data, i, uint64(m.Text.Size())) + n15, err := m.Text.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n15 } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 9) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - return this + return i, nil } -func NewPopulatedValue(r randyMesos, easy bool) *Value { - this := &Value{} - v47 := Value_Type([]int32{0, 1, 2, 3}[r.Intn(4)]) - this.Type = &v47 - if r.Intn(10) != 0 { - this.Scalar = NewPopulatedValue_Scalar(r, easy) - } - if r.Intn(10) != 0 { - this.Ranges = NewPopulatedValue_Ranges(r, easy) - } - if r.Intn(10) != 0 { - this.Set = NewPopulatedValue_Set(r, easy) - } - if r.Intn(10) != 0 { - this.Text = NewPopulatedValue_Text(r, easy) - } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 6) +func (m *Value_Scalar) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedValue_Scalar(r randyMesos, easy bool) *Value_Scalar { - this := &Value_Scalar{} - v48 := r.Float64() - if r.Intn(2) == 0 { - v48 *= -1 +func (m *Value_Scalar) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0x9 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.Value))) } - this.Value = &v48 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - return this + return i, nil } -func NewPopulatedValue_Range(r randyMesos, easy bool) *Value_Range { - this := &Value_Range{} - v49 := uint64(r.Uint32()) - this.Begin = &v49 - v50 := uint64(r.Uint32()) - this.End = &v50 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 3) +func (m *Value_Range) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedValue_Ranges(r randyMesos, easy bool) *Value_Ranges { - this := &Value_Ranges{} - if r.Intn(10) != 0 { - v51 := r.Intn(10) - this.Range = make([]*Value_Range, v51) - for i := 0; i < v51; i++ { - this.Range[i] = NewPopulatedValue_Range(r, easy) - } +func (m *Value_Range) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Begin == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("begin") + } else { + data[i] = 0x8 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Begin)) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + if m.End == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("end") + } else { + data[i] = 0x10 + i++ + i = encodeVarintMesos(data, i, uint64(*m.End)) } - return this + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil } -func NewPopulatedValue_Set(r randyMesos, easy bool) *Value_Set { - this := &Value_Set{} - if r.Intn(10) != 0 { - v52 := r.Intn(10) - this.Item = make([]string, v52) - for i := 0; i < v52; i++ { - this.Item[i] = randStringMesos(r) +func (m *Value_Ranges) 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 *Value_Ranges) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Range) > 0 { + for _, msg := range m.Range { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n } } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - return this + return i, nil } -func NewPopulatedValue_Text(r randyMesos, easy bool) *Value_Text { - this := &Value_Text{} - v53 := randStringMesos(r) - this.Value = &v53 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) +func (m *Value_Set) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedAttribute(r randyMesos, easy bool) *Attribute { - this := &Attribute{} - v54 := randStringMesos(r) - this.Name = &v54 - v55 := Value_Type([]int32{0, 1, 2, 3}[r.Intn(4)]) - this.Type = &v55 - if r.Intn(10) != 0 { - this.Scalar = NewPopulatedValue_Scalar(r, easy) - } - if r.Intn(10) != 0 { - this.Ranges = NewPopulatedValue_Ranges(r, easy) - } - if r.Intn(10) != 0 { - this.Set = NewPopulatedValue_Set(r, easy) +func (m *Value_Set) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Item) > 0 { + for _, s := range m.Item { + data[i] = 0xa + 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) + } } - if r.Intn(10) != 0 { - this.Text = NewPopulatedValue_Text(r, easy) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 7) + return i, nil +} + +func (m *Value_Text) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedResource(r randyMesos, easy bool) *Resource { - this := &Resource{} - v56 := randStringMesos(r) - this.Name = &v56 - v57 := Value_Type([]int32{0, 1, 2, 3}[r.Intn(4)]) - this.Type = &v57 - if r.Intn(10) != 0 { - this.Scalar = NewPopulatedValue_Scalar(r, easy) - } - if r.Intn(10) != 0 { - this.Ranges = NewPopulatedValue_Ranges(r, easy) - } - if r.Intn(10) != 0 { - this.Set = NewPopulatedValue_Set(r, easy) +func (m *Value_Text) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } - if r.Intn(10) != 0 { - v58 := randStringMesos(r) - this.Role = &v58 + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 7) + return i, nil +} + +func (m *Attribute) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedResourceStatistics(r randyMesos, easy bool) *ResourceStatistics { - this := &ResourceStatistics{} - v59 := r.Float64() - if r.Intn(2) == 0 { - v59 *= -1 +func (m *Attribute) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Name == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Name))) + i += copy(data[i:], *m.Name) } - this.Timestamp = &v59 - if r.Intn(10) != 0 { - v60 := r.Float64() - if r.Intn(2) == 0 { - v60 *= -1 - } - this.CpusUserTimeSecs = &v60 + if m.Type == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } else { + data[i] = 0x10 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Type)) } - if r.Intn(10) != 0 { - v61 := r.Float64() - if r.Intn(2) == 0 { - v61 *= -1 + if m.Scalar != nil { + data[i] = 0x1a + i++ + i = encodeVarintMesos(data, i, uint64(m.Scalar.Size())) + n16, err := m.Scalar.MarshalTo(data[i:]) + if err != nil { + return 0, err } - this.CpusSystemTimeSecs = &v61 + i += n16 } - if r.Intn(10) != 0 { - v62 := r.Float64() - if r.Intn(2) == 0 { - v62 *= -1 + if m.Ranges != nil { + data[i] = 0x22 + i++ + i = encodeVarintMesos(data, i, uint64(m.Ranges.Size())) + n17, err := m.Ranges.MarshalTo(data[i:]) + if err != nil { + return 0, err } - this.CpusLimit = &v62 - } - if r.Intn(10) != 0 { - v63 := r.Uint32() - this.CpusNrPeriods = &v63 - } - if r.Intn(10) != 0 { - v64 := r.Uint32() - this.CpusNrThrottled = &v64 + i += n17 } - if r.Intn(10) != 0 { - v65 := r.Float64() - if r.Intn(2) == 0 { - v65 *= -1 + if m.Text != nil { + data[i] = 0x2a + i++ + i = encodeVarintMesos(data, i, uint64(m.Text.Size())) + n18, err := m.Text.MarshalTo(data[i:]) + if err != nil { + return 0, err } - this.CpusThrottledTimeSecs = &v65 - } - if r.Intn(10) != 0 { - v66 := uint64(r.Uint32()) - this.MemRssBytes = &v66 - } - if r.Intn(10) != 0 { - v67 := uint64(r.Uint32()) - this.MemLimitBytes = &v67 - } - if r.Intn(10) != 0 { - v68 := uint64(r.Uint32()) - this.MemFileBytes = &v68 - } - if r.Intn(10) != 0 { - v69 := uint64(r.Uint32()) - this.MemAnonBytes = &v69 - } - if r.Intn(10) != 0 { - v70 := uint64(r.Uint32()) - this.MemMappedFileBytes = &v70 - } - if r.Intn(10) != 0 { - this.Perf = NewPopulatedPerfStatistics(r, easy) - } - if r.Intn(10) != 0 { - v71 := uint64(r.Uint32()) - this.NetRxPackets = &v71 + i += n18 } - if r.Intn(10) != 0 { - v72 := uint64(r.Uint32()) - this.NetRxBytes = &v72 + if m.Set != nil { + data[i] = 0x32 + i++ + i = encodeVarintMesos(data, i, uint64(m.Set.Size())) + n19, err := m.Set.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n19 } - if r.Intn(10) != 0 { - v73 := uint64(r.Uint32()) - this.NetRxErrors = &v73 + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if r.Intn(10) != 0 { - v74 := uint64(r.Uint32()) - this.NetRxDropped = &v74 + return i, nil +} + +func (m *Resource) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if r.Intn(10) != 0 { - v75 := uint64(r.Uint32()) - this.NetTxPackets = &v75 + return data[:n], nil +} + +func (m *Resource) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Name == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Name))) + i += copy(data[i:], *m.Name) } - if r.Intn(10) != 0 { - v76 := uint64(r.Uint32()) - this.NetTxBytes = &v76 + if m.Type == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } else { + data[i] = 0x10 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Type)) } - if r.Intn(10) != 0 { - v77 := uint64(r.Uint32()) - this.NetTxErrors = &v77 + if m.Scalar != nil { + data[i] = 0x1a + i++ + i = encodeVarintMesos(data, i, uint64(m.Scalar.Size())) + n20, err := m.Scalar.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n20 } - if r.Intn(10) != 0 { - v78 := uint64(r.Uint32()) - this.NetTxDropped = &v78 + if m.Ranges != nil { + data[i] = 0x22 + i++ + i = encodeVarintMesos(data, i, uint64(m.Ranges.Size())) + n21, err := m.Ranges.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n21 } - if r.Intn(10) != 0 { - v79 := r.Float64() - if r.Intn(2) == 0 { - v79 *= -1 + if m.Set != nil { + data[i] = 0x2a + i++ + i = encodeVarintMesos(data, i, uint64(m.Set.Size())) + n22, err := m.Set.MarshalTo(data[i:]) + if err != nil { + return 0, err } - this.NetTcpRttMicrosecsP50 = &v79 + i += n22 } - if r.Intn(10) != 0 { - v80 := r.Float64() - if r.Intn(2) == 0 { - v80 *= -1 + if m.Role != nil { + data[i] = 0x32 + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Role))) + i += copy(data[i:], *m.Role) + } + if m.Disk != nil { + data[i] = 0x3a + i++ + i = encodeVarintMesos(data, i, uint64(m.Disk.Size())) + n23, err := m.Disk.MarshalTo(data[i:]) + if err != nil { + return 0, err } - this.NetTcpRttMicrosecsP90 = &v80 + i += n23 } - if r.Intn(10) != 0 { - v81 := r.Float64() - if r.Intn(2) == 0 { - v81 *= -1 + if m.Reservation != nil { + data[i] = 0x42 + i++ + i = encodeVarintMesos(data, i, uint64(m.Reservation.Size())) + n24, err := m.Reservation.MarshalTo(data[i:]) + if err != nil { + return 0, err } - this.NetTcpRttMicrosecsP95 = &v81 + i += n24 } - if r.Intn(10) != 0 { - v82 := r.Float64() - if r.Intn(2) == 0 { - v82 *= -1 + if m.Revocable != nil { + data[i] = 0x4a + i++ + i = encodeVarintMesos(data, i, uint64(m.Revocable.Size())) + n25, err := m.Revocable.MarshalTo(data[i:]) + if err != nil { + return 0, err } - this.NetTcpRttMicrosecsP99 = &v82 + i += n25 } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 26) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - return this + return i, nil } -func NewPopulatedResourceUsage(r randyMesos, easy bool) *ResourceUsage { - this := &ResourceUsage{} - this.SlaveId = NewPopulatedSlaveID(r, easy) - this.FrameworkId = NewPopulatedFrameworkID(r, easy) - if r.Intn(10) != 0 { - this.ExecutorId = NewPopulatedExecutorID(r, easy) - } - if r.Intn(10) != 0 { - v83 := randStringMesos(r) - this.ExecutorName = &v83 - } - if r.Intn(10) != 0 { - this.TaskId = NewPopulatedTaskID(r, easy) - } - if r.Intn(10) != 0 { - this.Statistics = NewPopulatedResourceStatistics(r, easy) - } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 7) +func (m *Resource_ReservationInfo) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedPerfStatistics(r randyMesos, easy bool) *PerfStatistics { - this := &PerfStatistics{} - v84 := r.Float64() - if r.Intn(2) == 0 { - v84 *= -1 - } - this.Timestamp = &v84 - v85 := r.Float64() - if r.Intn(2) == 0 { - v85 *= -1 - } - this.Duration = &v85 - if r.Intn(10) != 0 { - v86 := uint64(r.Uint32()) - this.Cycles = &v86 - } - if r.Intn(10) != 0 { - v87 := uint64(r.Uint32()) - this.StalledCyclesFrontend = &v87 - } - if r.Intn(10) != 0 { - v88 := uint64(r.Uint32()) - this.StalledCyclesBackend = &v88 - } - if r.Intn(10) != 0 { - v89 := uint64(r.Uint32()) - this.Instructions = &v89 - } - if r.Intn(10) != 0 { - v90 := uint64(r.Uint32()) - this.CacheReferences = &v90 - } - if r.Intn(10) != 0 { - v91 := uint64(r.Uint32()) - this.CacheMisses = &v91 - } - if r.Intn(10) != 0 { - v92 := uint64(r.Uint32()) - this.Branches = &v92 - } - if r.Intn(10) != 0 { - v93 := uint64(r.Uint32()) - this.BranchMisses = &v93 +func (m *Resource_ReservationInfo) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Principal == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("principal") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Principal))) + i += copy(data[i:], *m.Principal) } - if r.Intn(10) != 0 { - v94 := uint64(r.Uint32()) - this.BusCycles = &v94 + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if r.Intn(10) != 0 { - v95 := uint64(r.Uint32()) - this.RefCycles = &v95 + return i, nil +} + +func (m *Resource_DiskInfo) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if r.Intn(10) != 0 { - v96 := r.Float64() - if r.Intn(2) == 0 { - v96 *= -1 + return data[:n], nil +} + +func (m *Resource_DiskInfo) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Persistence != nil { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(m.Persistence.Size())) + n26, err := m.Persistence.MarshalTo(data[i:]) + if err != nil { + return 0, err } - this.CpuClock = &v96 + i += n26 } - if r.Intn(10) != 0 { - v97 := r.Float64() - if r.Intn(2) == 0 { - v97 *= -1 + if m.Volume != nil { + data[i] = 0x12 + i++ + i = encodeVarintMesos(data, i, uint64(m.Volume.Size())) + n27, err := m.Volume.MarshalTo(data[i:]) + if err != nil { + return 0, err } - this.TaskClock = &v97 - } - if r.Intn(10) != 0 { - v98 := uint64(r.Uint32()) - this.PageFaults = &v98 - } - if r.Intn(10) != 0 { - v99 := uint64(r.Uint32()) - this.MinorFaults = &v99 - } - if r.Intn(10) != 0 { - v100 := uint64(r.Uint32()) - this.MajorFaults = &v100 - } - if r.Intn(10) != 0 { - v101 := uint64(r.Uint32()) - this.ContextSwitches = &v101 + i += n27 } - if r.Intn(10) != 0 { - v102 := uint64(r.Uint32()) - this.CpuMigrations = &v102 + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if r.Intn(10) != 0 { - v103 := uint64(r.Uint32()) - this.AlignmentFaults = &v103 + return i, nil +} + +func (m *Resource_DiskInfo_Persistence) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if r.Intn(10) != 0 { - v104 := uint64(r.Uint32()) - this.EmulationFaults = &v104 + return data[:n], nil +} + +func (m *Resource_DiskInfo_Persistence) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Id == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Id))) + i += copy(data[i:], *m.Id) } - if r.Intn(10) != 0 { - v105 := uint64(r.Uint32()) - this.L1DcacheLoads = &v105 + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if r.Intn(10) != 0 { - v106 := uint64(r.Uint32()) - this.L1DcacheLoadMisses = &v106 + return i, nil +} + +func (m *Resource_RevocableInfo) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if r.Intn(10) != 0 { - v107 := uint64(r.Uint32()) - this.L1DcacheStores = &v107 + return data[:n], nil +} + +func (m *Resource_RevocableInfo) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if r.Intn(10) != 0 { - v108 := uint64(r.Uint32()) - this.L1DcacheStoreMisses = &v108 + return i, nil +} + +func (m *TrafficControlStatistics) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if r.Intn(10) != 0 { - v109 := uint64(r.Uint32()) - this.L1DcachePrefetches = &v109 + return data[:n], nil +} + +func (m *TrafficControlStatistics) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Id == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Id))) + i += copy(data[i:], *m.Id) } - if r.Intn(10) != 0 { - v110 := uint64(r.Uint32()) - this.L1DcachePrefetchMisses = &v110 + if m.Backlog != nil { + data[i] = 0x10 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Backlog)) } - if r.Intn(10) != 0 { - v111 := uint64(r.Uint32()) - this.L1IcacheLoads = &v111 + if m.Bytes != nil { + data[i] = 0x18 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Bytes)) } - if r.Intn(10) != 0 { - v112 := uint64(r.Uint32()) - this.L1IcacheLoadMisses = &v112 + if m.Drops != nil { + data[i] = 0x20 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Drops)) } - if r.Intn(10) != 0 { - v113 := uint64(r.Uint32()) - this.L1IcachePrefetches = &v113 + if m.Overlimits != nil { + data[i] = 0x28 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Overlimits)) } - if r.Intn(10) != 0 { - v114 := uint64(r.Uint32()) - this.L1IcachePrefetchMisses = &v114 + if m.Packets != nil { + data[i] = 0x30 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Packets)) } - if r.Intn(10) != 0 { - v115 := uint64(r.Uint32()) - this.LlcLoads = &v115 + if m.Qlen != nil { + data[i] = 0x38 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Qlen)) } - if r.Intn(10) != 0 { - v116 := uint64(r.Uint32()) - this.LlcLoadMisses = &v116 + if m.Ratebps != nil { + data[i] = 0x40 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Ratebps)) } - if r.Intn(10) != 0 { - v117 := uint64(r.Uint32()) - this.LlcStores = &v117 + if m.Ratepps != nil { + data[i] = 0x48 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Ratepps)) } - if r.Intn(10) != 0 { - v118 := uint64(r.Uint32()) - this.LlcStoreMisses = &v118 + if m.Requeues != nil { + data[i] = 0x50 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Requeues)) } - if r.Intn(10) != 0 { - v119 := uint64(r.Uint32()) - this.LlcPrefetches = &v119 + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if r.Intn(10) != 0 { - v120 := uint64(r.Uint32()) - this.LlcPrefetchMisses = &v120 + return i, nil +} + +func (m *ResourceStatistics) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if r.Intn(10) != 0 { - v121 := uint64(r.Uint32()) - this.DtlbLoads = &v121 + return data[:n], nil +} + +func (m *ResourceStatistics) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Timestamp == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("timestamp") + } else { + data[i] = 0x9 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.Timestamp))) } - if r.Intn(10) != 0 { - v122 := uint64(r.Uint32()) - this.DtlbLoadMisses = &v122 + if m.CpusUserTimeSecs != nil { + data[i] = 0x11 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.CpusUserTimeSecs))) } - if r.Intn(10) != 0 { - v123 := uint64(r.Uint32()) - this.DtlbStores = &v123 + if m.CpusSystemTimeSecs != nil { + data[i] = 0x19 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.CpusSystemTimeSecs))) } - if r.Intn(10) != 0 { - v124 := uint64(r.Uint32()) - this.DtlbStoreMisses = &v124 + if m.CpusLimit != nil { + data[i] = 0x21 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.CpusLimit))) } - if r.Intn(10) != 0 { - v125 := uint64(r.Uint32()) - this.DtlbPrefetches = &v125 + if m.MemRssBytes != nil { + data[i] = 0x28 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemRssBytes)) } - if r.Intn(10) != 0 { - v126 := uint64(r.Uint32()) - this.DtlbPrefetchMisses = &v126 + if m.MemLimitBytes != nil { + data[i] = 0x30 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemLimitBytes)) } - if r.Intn(10) != 0 { - v127 := uint64(r.Uint32()) - this.ItlbLoads = &v127 + if m.CpusNrPeriods != nil { + data[i] = 0x38 + i++ + i = encodeVarintMesos(data, i, uint64(*m.CpusNrPeriods)) } - if r.Intn(10) != 0 { - v128 := uint64(r.Uint32()) - this.ItlbLoadMisses = &v128 + if m.CpusNrThrottled != nil { + data[i] = 0x40 + i++ + i = encodeVarintMesos(data, i, uint64(*m.CpusNrThrottled)) } - if r.Intn(10) != 0 { - v129 := uint64(r.Uint32()) - this.BranchLoads = &v129 + if m.CpusThrottledTimeSecs != nil { + data[i] = 0x49 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.CpusThrottledTimeSecs))) } - if r.Intn(10) != 0 { - v130 := uint64(r.Uint32()) - this.BranchLoadMisses = &v130 + if m.MemFileBytes != nil { + data[i] = 0x50 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemFileBytes)) } - if r.Intn(10) != 0 { - v131 := uint64(r.Uint32()) - this.NodeLoads = &v131 + if m.MemAnonBytes != nil { + data[i] = 0x58 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemAnonBytes)) } - if r.Intn(10) != 0 { - v132 := uint64(r.Uint32()) - this.NodeLoadMisses = &v132 + if m.MemMappedFileBytes != nil { + data[i] = 0x60 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemMappedFileBytes)) } - if r.Intn(10) != 0 { - v133 := uint64(r.Uint32()) - this.NodeStores = &v133 + if m.Perf != nil { + data[i] = 0x6a + i++ + i = encodeVarintMesos(data, i, uint64(m.Perf.Size())) + n28, err := m.Perf.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n28 } - if r.Intn(10) != 0 { - v134 := uint64(r.Uint32()) - this.NodeStoreMisses = &v134 + if m.NetRxPackets != nil { + data[i] = 0x70 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NetRxPackets)) } - if r.Intn(10) != 0 { - v135 := uint64(r.Uint32()) - this.NodePrefetches = &v135 + if m.NetRxBytes != nil { + data[i] = 0x78 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NetRxBytes)) } - if r.Intn(10) != 0 { - v136 := uint64(r.Uint32()) - this.NodePrefetchMisses = &v136 + if m.NetRxErrors != nil { + data[i] = 0x80 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NetRxErrors)) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 54) + if m.NetRxDropped != nil { + data[i] = 0x88 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NetRxDropped)) } - return this -} - -func NewPopulatedRequest(r randyMesos, easy bool) *Request { - this := &Request{} - if r.Intn(10) != 0 { - this.SlaveId = NewPopulatedSlaveID(r, easy) + if m.NetTxPackets != nil { + data[i] = 0x90 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NetTxPackets)) } - if r.Intn(10) != 0 { - v137 := r.Intn(10) - this.Resources = make([]*Resource, v137) - for i := 0; i < v137; i++ { - this.Resources[i] = NewPopulatedResource(r, easy) - } + if m.NetTxBytes != nil { + data[i] = 0x98 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NetTxBytes)) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 3) + if m.NetTxErrors != nil { + data[i] = 0xa0 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NetTxErrors)) } - return this -} - -func NewPopulatedOffer(r randyMesos, easy bool) *Offer { - this := &Offer{} - this.Id = NewPopulatedOfferID(r, easy) - this.FrameworkId = NewPopulatedFrameworkID(r, easy) - this.SlaveId = NewPopulatedSlaveID(r, easy) - v138 := randStringMesos(r) - this.Hostname = &v138 - if r.Intn(10) != 0 { - v139 := r.Intn(10) - this.Resources = make([]*Resource, v139) - for i := 0; i < v139; i++ { - this.Resources[i] = NewPopulatedResource(r, easy) - } + if m.NetTxDropped != nil { + data[i] = 0xa8 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NetTxDropped)) } - if r.Intn(10) != 0 { - v140 := r.Intn(10) - this.Attributes = make([]*Attribute, v140) - for i := 0; i < v140; i++ { - this.Attributes[i] = NewPopulatedAttribute(r, easy) - } + if m.NetTcpRttMicrosecsP50 != nil { + data[i] = 0xb1 + i++ + data[i] = 0x1 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.NetTcpRttMicrosecsP50))) } - if r.Intn(10) != 0 { - v141 := r.Intn(10) - this.ExecutorIds = make([]*ExecutorID, v141) - for i := 0; i < v141; i++ { - this.ExecutorIds[i] = NewPopulatedExecutorID(r, easy) - } + if m.NetTcpRttMicrosecsP90 != nil { + data[i] = 0xb9 + i++ + data[i] = 0x1 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.NetTcpRttMicrosecsP90))) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 8) + if m.NetTcpRttMicrosecsP95 != nil { + data[i] = 0xc1 + i++ + data[i] = 0x1 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.NetTcpRttMicrosecsP95))) } - return this -} - -func NewPopulatedTaskInfo(r randyMesos, easy bool) *TaskInfo { - this := &TaskInfo{} - v142 := randStringMesos(r) - this.Name = &v142 - this.TaskId = NewPopulatedTaskID(r, easy) - this.SlaveId = NewPopulatedSlaveID(r, easy) - if r.Intn(10) != 0 { - v143 := r.Intn(10) - this.Resources = make([]*Resource, v143) - for i := 0; i < v143; i++ { - this.Resources[i] = NewPopulatedResource(r, easy) - } + if m.NetTcpRttMicrosecsP99 != nil { + data[i] = 0xc9 + i++ + data[i] = 0x1 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.NetTcpRttMicrosecsP99))) } - if r.Intn(10) != 0 { - this.Executor = NewPopulatedExecutorInfo(r, easy) + if m.DiskLimitBytes != nil { + data[i] = 0xd0 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.DiskLimitBytes)) } - if r.Intn(10) != 0 { - this.Command = NewPopulatedCommandInfo(r, easy) + if m.DiskUsedBytes != nil { + data[i] = 0xd8 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.DiskUsedBytes)) } - if r.Intn(10) != 0 { - this.Container = NewPopulatedContainerInfo(r, easy) + if m.NetTcpActiveConnections != nil { + data[i] = 0xe1 + i++ + data[i] = 0x1 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.NetTcpActiveConnections))) } - if r.Intn(10) != 0 { - v144 := r.Intn(100) - this.Data = make([]byte, v144) - for i := 0; i < v144; i++ { - this.Data[i] = byte(r.Intn(256)) - } + if m.NetTcpTimeWaitConnections != nil { + data[i] = 0xe9 + i++ + data[i] = 0x1 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.NetTcpTimeWaitConnections))) } - if r.Intn(10) != 0 { - this.HealthCheck = NewPopulatedHealthCheck(r, easy) + if m.Processes != nil { + data[i] = 0xf0 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Processes)) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 10) + if m.Threads != nil { + data[i] = 0xf8 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Threads)) } - return this -} - -func NewPopulatedTaskStatus(r randyMesos, easy bool) *TaskStatus { - this := &TaskStatus{} - this.TaskId = NewPopulatedTaskID(r, easy) - v145 := TaskState([]int32{6, 0, 1, 2, 3, 4, 5, 7}[r.Intn(8)]) - this.State = &v145 - if r.Intn(10) != 0 { - v146 := randStringMesos(r) - this.Message = &v146 + if m.MemLowPressureCounter != nil { + data[i] = 0x80 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemLowPressureCounter)) } - if r.Intn(10) != 0 { - v147 := TaskStatus_Source([]int32{0, 1, 2}[r.Intn(3)]) - this.Source = &v147 + if m.MemMediumPressureCounter != nil { + data[i] = 0x88 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemMediumPressureCounter)) } - if r.Intn(10) != 0 { - v148 := TaskStatus_Reason([]int32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}[r.Intn(17)]) - this.Reason = &v148 + if m.MemCriticalPressureCounter != nil { + data[i] = 0x90 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemCriticalPressureCounter)) } - if r.Intn(10) != 0 { - v149 := r.Intn(100) - this.Data = make([]byte, v149) - for i := 0; i < v149; i++ { - this.Data[i] = byte(r.Intn(256)) + if len(m.NetTrafficControlStatistics) > 0 { + for _, msg := range m.NetTrafficControlStatistics { + data[i] = 0x9a + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n } } - if r.Intn(10) != 0 { - this.SlaveId = NewPopulatedSlaveID(r, easy) + if m.MemTotalBytes != nil { + data[i] = 0xa0 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemTotalBytes)) } - if r.Intn(10) != 0 { - this.ExecutorId = NewPopulatedExecutorID(r, easy) + if m.MemTotalMemswBytes != nil { + data[i] = 0xa8 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemTotalMemswBytes)) } - if r.Intn(10) != 0 { - v150 := r.Float64() - if r.Intn(2) == 0 { - v150 *= -1 - } - this.Timestamp = &v150 + if m.MemSoftLimitBytes != nil { + data[i] = 0xb0 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemSoftLimitBytes)) } - if r.Intn(10) != 0 { - v151 := bool(r.Intn(2) == 0) - this.Healthy = &v151 + if m.MemCacheBytes != nil { + data[i] = 0xb8 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemCacheBytes)) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 11) + if m.MemSwapBytes != nil { + data[i] = 0xc0 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MemSwapBytes)) } - return this + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil } -func NewPopulatedFilters(r randyMesos, easy bool) *Filters { - this := &Filters{} - if r.Intn(10) != 0 { - v152 := r.Float64() - if r.Intn(2) == 0 { - v152 *= -1 - } - this.RefuseSeconds = &v152 - } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) +func (m *ResourceUsage) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedEnvironment(r randyMesos, easy bool) *Environment { - this := &Environment{} - if r.Intn(10) != 0 { - v153 := r.Intn(10) - this.Variables = make([]*Environment_Variable, v153) - for i := 0; i < v153; i++ { - this.Variables[i] = NewPopulatedEnvironment_Variable(r, easy) +func (m *ResourceUsage) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Executors) > 0 { + for _, msg := range m.Executors { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n } } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) - } - return this -} - -func NewPopulatedEnvironment_Variable(r randyMesos, easy bool) *Environment_Variable { - this := &Environment_Variable{} - v154 := randStringMesos(r) - this.Name = &v154 - v155 := randStringMesos(r) - this.Value = &v155 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 3) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - return this + return i, nil } -func NewPopulatedParameter(r randyMesos, easy bool) *Parameter { - this := &Parameter{} - v156 := randStringMesos(r) - this.Key = &v156 - v157 := randStringMesos(r) - this.Value = &v157 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 3) +func (m *ResourceUsage_Executor) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedParameters(r randyMesos, easy bool) *Parameters { - this := &Parameters{} - if r.Intn(10) != 0 { - v158 := r.Intn(10) - this.Parameter = make([]*Parameter, v158) - for i := 0; i < v158; i++ { - this.Parameter[i] = NewPopulatedParameter(r, easy) +func (m *ResourceUsage_Executor) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.ExecutorInfo == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("executor_info") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(m.ExecutorInfo.Size())) + n29, err := m.ExecutorInfo.MarshalTo(data[i:]) + if err != nil { + return 0, err } + i += n29 } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) - } - return this -} - -func NewPopulatedCredential(r randyMesos, easy bool) *Credential { - this := &Credential{} - v159 := randStringMesos(r) - this.Principal = &v159 - if r.Intn(10) != 0 { - v160 := r.Intn(100) - this.Secret = make([]byte, v160) - for i := 0; i < v160; i++ { - this.Secret[i] = byte(r.Intn(256)) + if len(m.Allocated) > 0 { + for _, msg := range m.Allocated { + data[i] = 0x12 + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n } } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 3) - } - return this -} - -func NewPopulatedCredentials(r randyMesos, easy bool) *Credentials { - this := &Credentials{} - if r.Intn(10) != 0 { - v161 := r.Intn(10) - this.Credentials = make([]*Credential, v161) - for i := 0; i < v161; i++ { - this.Credentials[i] = NewPopulatedCredential(r, easy) + if m.Statistics != nil { + data[i] = 0x1a + i++ + i = encodeVarintMesos(data, i, uint64(m.Statistics.Size())) + n30, err := m.Statistics.MarshalTo(data[i:]) + if err != nil { + return 0, err } + i += n30 } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - return this + return i, nil } -func NewPopulatedACL(r randyMesos, easy bool) *ACL { - this := &ACL{} - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 1) +func (m *PerfStatistics) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - return this + return data[:n], nil } -func NewPopulatedACL_Entity(r randyMesos, easy bool) *ACL_Entity { - this := &ACL_Entity{} - if r.Intn(10) != 0 { - v162 := ACL_Entity_Type([]int32{0, 1, 2}[r.Intn(3)]) - this.Type = &v162 +func (m *PerfStatistics) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Timestamp == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("timestamp") + } else { + data[i] = 0x9 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.Timestamp))) } - if r.Intn(10) != 0 { - v163 := r.Intn(10) - this.Values = make([]string, v163) - for i := 0; i < v163; i++ { - this.Values[i] = randStringMesos(r) - } + if m.Duration == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("duration") + } else { + data[i] = 0x11 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.Duration))) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 3) + if m.Cycles != nil { + data[i] = 0x18 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Cycles)) } - return this -} - -func NewPopulatedACL_RegisterFramework(r randyMesos, easy bool) *ACL_RegisterFramework { - this := &ACL_RegisterFramework{} - this.Principals = NewPopulatedACL_Entity(r, easy) - this.Roles = NewPopulatedACL_Entity(r, easy) - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 3) + if m.StalledCyclesFrontend != nil { + data[i] = 0x20 + i++ + i = encodeVarintMesos(data, i, uint64(*m.StalledCyclesFrontend)) } - return this -} - -func NewPopulatedACL_RunTask(r randyMesos, easy bool) *ACL_RunTask { - this := &ACL_RunTask{} - this.Principals = NewPopulatedACL_Entity(r, easy) - this.Users = NewPopulatedACL_Entity(r, easy) - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 3) + if m.StalledCyclesBackend != nil { + data[i] = 0x28 + i++ + i = encodeVarintMesos(data, i, uint64(*m.StalledCyclesBackend)) } - return this -} - -func NewPopulatedACL_ShutdownFramework(r randyMesos, easy bool) *ACL_ShutdownFramework { - this := &ACL_ShutdownFramework{} - this.Principals = NewPopulatedACL_Entity(r, easy) - this.FrameworkPrincipals = NewPopulatedACL_Entity(r, easy) - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 3) + if m.Instructions != nil { + data[i] = 0x30 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Instructions)) } - return this -} - -func NewPopulatedACLs(r randyMesos, easy bool) *ACLs { - this := &ACLs{} - if r.Intn(10) != 0 { - v164 := bool(r.Intn(2) == 0) - this.Permissive = &v164 + if m.CacheReferences != nil { + data[i] = 0x38 + i++ + i = encodeVarintMesos(data, i, uint64(*m.CacheReferences)) } - if r.Intn(10) != 0 { - v165 := r.Intn(10) - this.RegisterFrameworks = make([]*ACL_RegisterFramework, v165) - for i := 0; i < v165; i++ { - this.RegisterFrameworks[i] = NewPopulatedACL_RegisterFramework(r, easy) - } + if m.CacheMisses != nil { + data[i] = 0x40 + i++ + i = encodeVarintMesos(data, i, uint64(*m.CacheMisses)) } - if r.Intn(10) != 0 { - v166 := r.Intn(10) - this.RunTasks = make([]*ACL_RunTask, v166) - for i := 0; i < v166; i++ { - this.RunTasks[i] = NewPopulatedACL_RunTask(r, easy) - } + if m.Branches != nil { + data[i] = 0x48 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Branches)) } - if r.Intn(10) != 0 { - v167 := r.Intn(10) - this.ShutdownFrameworks = make([]*ACL_ShutdownFramework, v167) - for i := 0; i < v167; i++ { - this.ShutdownFrameworks[i] = NewPopulatedACL_ShutdownFramework(r, easy) - } + if m.BranchMisses != nil { + data[i] = 0x50 + i++ + i = encodeVarintMesos(data, i, uint64(*m.BranchMisses)) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 5) + if m.BusCycles != nil { + data[i] = 0x58 + i++ + i = encodeVarintMesos(data, i, uint64(*m.BusCycles)) } - return this -} - -func NewPopulatedRateLimit(r randyMesos, easy bool) *RateLimit { - this := &RateLimit{} - if r.Intn(10) != 0 { - v168 := r.Float64() - if r.Intn(2) == 0 { - v168 *= -1 - } - this.Qps = &v168 + if m.RefCycles != nil { + data[i] = 0x60 + i++ + i = encodeVarintMesos(data, i, uint64(*m.RefCycles)) } - v169 := randStringMesos(r) - this.Principal = &v169 - if r.Intn(10) != 0 { - v170 := uint64(r.Uint32()) - this.Capacity = &v170 + if m.CpuClock != nil { + data[i] = 0x69 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.CpuClock))) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 4) + if m.TaskClock != nil { + data[i] = 0x71 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.TaskClock))) } - return this -} - -func NewPopulatedRateLimits(r randyMesos, easy bool) *RateLimits { - this := &RateLimits{} - if r.Intn(10) != 0 { - v171 := r.Intn(10) - this.Limits = make([]*RateLimit, v171) - for i := 0; i < v171; i++ { - this.Limits[i] = NewPopulatedRateLimit(r, easy) - } + if m.PageFaults != nil { + data[i] = 0x78 + i++ + i = encodeVarintMesos(data, i, uint64(*m.PageFaults)) } - if r.Intn(10) != 0 { - v172 := r.Float64() - if r.Intn(2) == 0 { - v172 *= -1 - } - this.AggregateDefaultQps = &v172 + if m.MinorFaults != nil { + data[i] = 0x80 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MinorFaults)) } - if r.Intn(10) != 0 { - v173 := uint64(r.Uint32()) - this.AggregateDefaultCapacity = &v173 + if m.MajorFaults != nil { + data[i] = 0x88 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.MajorFaults)) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 4) + if m.ContextSwitches != nil { + data[i] = 0x90 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.ContextSwitches)) } - return this -} - -func NewPopulatedVolume(r randyMesos, easy bool) *Volume { - this := &Volume{} - v174 := randStringMesos(r) - this.ContainerPath = &v174 - if r.Intn(10) != 0 { - v175 := randStringMesos(r) - this.HostPath = &v175 + if m.CpuMigrations != nil { + data[i] = 0x98 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.CpuMigrations)) } - v176 := Volume_Mode([]int32{1, 2}[r.Intn(2)]) - this.Mode = &v176 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 4) + if m.AlignmentFaults != nil { + data[i] = 0xa0 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.AlignmentFaults)) } - return this -} - -func NewPopulatedContainerInfo(r randyMesos, easy bool) *ContainerInfo { - this := &ContainerInfo{} - v177 := ContainerInfo_Type([]int32{1, 2}[r.Intn(2)]) - this.Type = &v177 - if r.Intn(10) != 0 { - v178 := r.Intn(10) - this.Volumes = make([]*Volume, v178) - for i := 0; i < v178; i++ { - this.Volumes[i] = NewPopulatedVolume(r, easy) - } + if m.EmulationFaults != nil { + data[i] = 0xa8 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.EmulationFaults)) } - if r.Intn(10) != 0 { - v179 := randStringMesos(r) - this.Hostname = &v179 + if m.L1DcacheLoads != nil { + data[i] = 0xb0 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.L1DcacheLoads)) } - if r.Intn(10) != 0 { - this.Docker = NewPopulatedContainerInfo_DockerInfo(r, easy) + if m.L1DcacheLoadMisses != nil { + data[i] = 0xb8 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.L1DcacheLoadMisses)) + } + if m.L1DcacheStores != nil { + data[i] = 0xc0 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.L1DcacheStores)) + } + if m.L1DcacheStoreMisses != nil { + data[i] = 0xc8 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.L1DcacheStoreMisses)) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 5) + if m.L1DcachePrefetches != nil { + data[i] = 0xd0 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.L1DcachePrefetches)) } - return this -} - -func NewPopulatedContainerInfo_DockerInfo(r randyMesos, easy bool) *ContainerInfo_DockerInfo { - this := &ContainerInfo_DockerInfo{} - v180 := randStringMesos(r) - this.Image = &v180 - if r.Intn(10) != 0 { - v181 := ContainerInfo_DockerInfo_Network([]int32{1, 2, 3}[r.Intn(3)]) - this.Network = &v181 + if m.L1DcachePrefetchMisses != nil { + data[i] = 0xd8 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.L1DcachePrefetchMisses)) } - if r.Intn(10) != 0 { - v182 := r.Intn(10) - this.PortMappings = make([]*ContainerInfo_DockerInfo_PortMapping, v182) - for i := 0; i < v182; i++ { - this.PortMappings[i] = NewPopulatedContainerInfo_DockerInfo_PortMapping(r, easy) - } + if m.L1IcacheLoads != nil { + data[i] = 0xe0 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.L1IcacheLoads)) } - if r.Intn(10) != 0 { - v183 := bool(r.Intn(2) == 0) - this.Privileged = &v183 + if m.L1IcacheLoadMisses != nil { + data[i] = 0xe8 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.L1IcacheLoadMisses)) } - if r.Intn(10) != 0 { - v184 := r.Intn(10) - this.Parameters = make([]*Parameter, v184) - for i := 0; i < v184; i++ { - this.Parameters[i] = NewPopulatedParameter(r, easy) - } + if m.L1IcachePrefetches != nil { + data[i] = 0xf0 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.L1IcachePrefetches)) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 6) + if m.L1IcachePrefetchMisses != nil { + data[i] = 0xf8 + i++ + data[i] = 0x1 + i++ + i = encodeVarintMesos(data, i, uint64(*m.L1IcachePrefetchMisses)) } - return this -} - -func NewPopulatedContainerInfo_DockerInfo_PortMapping(r randyMesos, easy bool) *ContainerInfo_DockerInfo_PortMapping { - this := &ContainerInfo_DockerInfo_PortMapping{} - v185 := r.Uint32() - this.HostPort = &v185 - v186 := r.Uint32() - this.ContainerPort = &v186 - if r.Intn(10) != 0 { - v187 := randStringMesos(r) - this.Protocol = &v187 + if m.LlcLoads != nil { + data[i] = 0x80 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.LlcLoads)) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedMesos(r, 4) + if m.LlcLoadMisses != nil { + data[i] = 0x88 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.LlcLoadMisses)) } - return this -} - -type randyMesos interface { - Float32() float32 - Float64() float64 - Int63() int64 - Int31() int32 - Uint32() uint32 - Intn(n int) int -} - -func randUTF8RuneMesos(r randyMesos) rune { - res := rune(r.Uint32() % 1112064) - if 55296 <= res { - res += 2047 + if m.LlcStores != nil { + data[i] = 0x90 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.LlcStores)) } - return res -} -func randStringMesos(r randyMesos) string { - v188 := r.Intn(100) - tmps := make([]rune, v188) - for i := 0; i < v188; i++ { - tmps[i] = randUTF8RuneMesos(r) + if m.LlcStoreMisses != nil { + data[i] = 0x98 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.LlcStoreMisses)) } - return string(tmps) -} -func randUnrecognizedMesos(r randyMesos, maxFieldNumber int) (data []byte) { - l := r.Intn(5) - for i := 0; i < l; i++ { - wire := r.Intn(4) - if wire == 3 { - wire = 5 - } - fieldNumber := maxFieldNumber + r.Intn(100) - data = randFieldMesos(data, r, fieldNumber, wire) + if m.LlcPrefetches != nil { + data[i] = 0xa0 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.LlcPrefetches)) } - return data -} -func randFieldMesos(data []byte, r randyMesos, fieldNumber int, wire int) []byte { - key := uint32(fieldNumber)<<3 | uint32(wire) - switch wire { - case 0: - data = encodeVarintPopulateMesos(data, uint64(key)) - v189 := r.Int63() - if r.Intn(2) == 0 { - v189 *= -1 - } - data = encodeVarintPopulateMesos(data, uint64(v189)) - case 1: - data = encodeVarintPopulateMesos(data, uint64(key)) - data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) - case 2: - data = encodeVarintPopulateMesos(data, uint64(key)) - ll := r.Intn(100) - data = encodeVarintPopulateMesos(data, uint64(ll)) - for j := 0; j < ll; j++ { - data = append(data, byte(r.Intn(256))) - } - default: - data = encodeVarintPopulateMesos(data, uint64(key)) - data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) + if m.LlcPrefetchMisses != nil { + data[i] = 0xa8 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.LlcPrefetchMisses)) } - return data -} -func encodeVarintPopulateMesos(data []byte, v uint64) []byte { - for v >= 1<<7 { - data = append(data, uint8(uint64(v)&0x7f|0x80)) - v >>= 7 + if m.DtlbLoads != nil { + data[i] = 0xb0 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.DtlbLoads)) } - data = append(data, uint8(v)) - return data -} -func (m *FrameworkID) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if m.DtlbLoadMisses != nil { + data[i] = 0xb8 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.DtlbLoadMisses)) } - return data[:n], nil -} - -func (m *FrameworkID) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Value != nil { - data[i] = 0xa + if m.DtlbStores != nil { + data[i] = 0xc0 i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Value))) - i += copy(data[i:], *m.Value) + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.DtlbStores)) } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if m.DtlbStoreMisses != nil { + data[i] = 0xc8 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.DtlbStoreMisses)) } - return i, nil -} - -func (m *OfferID) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if m.DtlbPrefetches != nil { + data[i] = 0xd0 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.DtlbPrefetches)) } - return data[:n], nil -} - -func (m *OfferID) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Value != nil { - data[i] = 0xa + if m.DtlbPrefetchMisses != nil { + data[i] = 0xd8 i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Value))) - i += copy(data[i:], *m.Value) + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.DtlbPrefetchMisses)) } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if m.ItlbLoads != nil { + data[i] = 0xe0 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.ItlbLoads)) } - return i, nil -} - -func (m *SlaveID) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if m.ItlbLoadMisses != nil { + data[i] = 0xe8 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.ItlbLoadMisses)) } - return data[:n], nil -} - -func (m *SlaveID) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Value != nil { - data[i] = 0xa + if m.BranchLoads != nil { + data[i] = 0xf0 i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Value))) - i += copy(data[i:], *m.Value) + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.BranchLoads)) } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if m.BranchLoadMisses != nil { + data[i] = 0xf8 + i++ + data[i] = 0x2 + i++ + i = encodeVarintMesos(data, i, uint64(*m.BranchLoadMisses)) } - return i, nil -} - -func (m *TaskID) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if m.NodeLoads != nil { + data[i] = 0x80 + i++ + data[i] = 0x3 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NodeLoads)) } - return data[:n], nil -} - -func (m *TaskID) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Value != nil { - data[i] = 0xa + if m.NodeLoadMisses != nil { + data[i] = 0x88 i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Value))) - i += copy(data[i:], *m.Value) + data[i] = 0x3 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NodeLoadMisses)) } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if m.NodeStores != nil { + data[i] = 0x90 + i++ + data[i] = 0x3 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NodeStores)) } - return i, nil -} - -func (m *ExecutorID) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if m.NodeStoreMisses != nil { + data[i] = 0x98 + i++ + data[i] = 0x3 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NodeStoreMisses)) } - return data[:n], nil -} - -func (m *ExecutorID) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Value != nil { - data[i] = 0xa + if m.NodePrefetches != nil { + data[i] = 0xa0 i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Value))) - i += copy(data[i:], *m.Value) + data[i] = 0x3 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NodePrefetches)) + } + if m.NodePrefetchMisses != nil { + data[i] = 0xa8 + i++ + data[i] = 0x3 + i++ + i = encodeVarintMesos(data, i, uint64(*m.NodePrefetchMisses)) } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -13564,7 +15672,7 @@ func (m *ExecutorID) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *ContainerID) Marshal() (data []byte, err error) { +func (m *Request) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -13574,16 +15682,32 @@ func (m *ContainerID) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *ContainerID) MarshalTo(data []byte) (n int, err error) { +func (m *Request) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Value != nil { + if m.SlaveId != nil { data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Value))) - i += copy(data[i:], *m.Value) + i = encodeVarintMesos(data, i, uint64(m.SlaveId.Size())) + n31, err := m.SlaveId.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n31 + } + if len(m.Resources) > 0 { + for _, msg := range m.Resources { + data[i] = 0x12 + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -13591,7 +15715,7 @@ func (m *ContainerID) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *FrameworkInfo) Marshal() (data []byte, err error) { +func (m *Offer) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -13601,71 +15725,90 @@ func (m *FrameworkInfo) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *FrameworkInfo) MarshalTo(data []byte) (n int, err error) { +func (m *Offer) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.User != nil { + if m.Id == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") + } else { data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(len(*m.User))) - i += copy(data[i:], *m.User) - } - if m.Name != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Name))) - i += copy(data[i:], *m.Name) - } - if m.Id != nil { - data[i] = 0x1a - i++ i = encodeVarintMesos(data, i, uint64(m.Id.Size())) - n1, err := m.Id.MarshalTo(data[i:]) + n32, err := m.Id.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n1 - } - if m.FailoverTimeout != nil { - data[i] = 0x21 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.FailoverTimeout))) + i += n32 } - if m.Checkpoint != nil { - data[i] = 0x28 + if m.FrameworkId == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("framework_id") + } else { + data[i] = 0x12 i++ - if *m.Checkpoint { - data[i] = 1 - } else { - data[i] = 0 + i = encodeVarintMesos(data, i, uint64(m.FrameworkId.Size())) + n33, err := m.FrameworkId.MarshalTo(data[i:]) + if err != nil { + return 0, err } - i++ + i += n33 } - if m.Role != nil { - data[i] = 0x32 + if m.SlaveId == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("slave_id") + } else { + data[i] = 0x1a i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Role))) - i += copy(data[i:], *m.Role) + i = encodeVarintMesos(data, i, uint64(m.SlaveId.Size())) + n34, err := m.SlaveId.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n34 } - if m.Hostname != nil { - data[i] = 0x3a + if m.Hostname == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("hostname") + } else { + data[i] = 0x22 i++ i = encodeVarintMesos(data, i, uint64(len(*m.Hostname))) i += copy(data[i:], *m.Hostname) } - if m.Principal != nil { - data[i] = 0x42 - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Principal))) - i += copy(data[i:], *m.Principal) + if len(m.Resources) > 0 { + for _, msg := range m.Resources { + data[i] = 0x2a + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } } - if m.WebuiUrl != nil { - data[i] = 0x4a - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.WebuiUrl))) - i += copy(data[i:], *m.WebuiUrl) + if len(m.ExecutorIds) > 0 { + for _, msg := range m.ExecutorIds { + data[i] = 0x32 + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.Attributes) > 0 { + for _, msg := range m.Attributes { + data[i] = 0x3a + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -13673,7 +15816,7 @@ func (m *FrameworkInfo) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *HealthCheck) Marshal() (data []byte, err error) { +func (m *Offer_Operation) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -13683,55 +15826,67 @@ func (m *HealthCheck) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *HealthCheck) MarshalTo(data []byte) (n int, err error) { +func (m *Offer_Operation) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Http != nil { - data[i] = 0xa + if m.Type == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } else { + data[i] = 0x8 i++ - i = encodeVarintMesos(data, i, uint64(m.Http.Size())) - n2, err := m.Http.MarshalTo(data[i:]) + i = encodeVarintMesos(data, i, uint64(*m.Type)) + } + if m.Launch != nil { + data[i] = 0x12 + i++ + i = encodeVarintMesos(data, i, uint64(m.Launch.Size())) + n35, err := m.Launch.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n2 - } - if m.DelaySeconds != nil { - data[i] = 0x11 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.DelaySeconds))) - } - if m.IntervalSeconds != nil { - data[i] = 0x19 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.IntervalSeconds))) + i += n35 } - if m.TimeoutSeconds != nil { - data[i] = 0x21 + if m.Reserve != nil { + data[i] = 0x1a i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.TimeoutSeconds))) + i = encodeVarintMesos(data, i, uint64(m.Reserve.Size())) + n36, err := m.Reserve.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n36 } - if m.ConsecutiveFailures != nil { - data[i] = 0x28 + if m.Unreserve != nil { + data[i] = 0x22 i++ - i = encodeVarintMesos(data, i, uint64(*m.ConsecutiveFailures)) + i = encodeVarintMesos(data, i, uint64(m.Unreserve.Size())) + n37, err := m.Unreserve.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n37 } - if m.GracePeriodSeconds != nil { - data[i] = 0x31 + if m.Create != nil { + data[i] = 0x2a i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.GracePeriodSeconds))) + i = encodeVarintMesos(data, i, uint64(m.Create.Size())) + n38, err := m.Create.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n38 } - if m.Command != nil { - data[i] = 0x3a + if m.Destroy != nil { + data[i] = 0x32 i++ - i = encodeVarintMesos(data, i, uint64(m.Command.Size())) - n3, err := m.Command.MarshalTo(data[i:]) + i = encodeVarintMesos(data, i, uint64(m.Destroy.Size())) + n39, err := m.Destroy.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n3 + i += n39 } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -13739,7 +15894,7 @@ func (m *HealthCheck) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *HealthCheck_HTTP) Marshal() (data []byte, err error) { +func (m *Offer_Operation_Launch) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -13749,27 +15904,21 @@ func (m *HealthCheck_HTTP) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *HealthCheck_HTTP) MarshalTo(data []byte) (n int, err error) { +func (m *Offer_Operation_Launch) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Port != nil { - data[i] = 0x8 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Port)) - } - if m.Path != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Path))) - i += copy(data[i:], *m.Path) - } - if len(m.Statuses) > 0 { - for _, num := range m.Statuses { - data[i] = 0x20 + if len(m.TaskInfos) > 0 { + for _, msg := range m.TaskInfos { + data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(num)) + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n } } if m.XXX_unrecognized != nil { @@ -13778,7 +15927,7 @@ func (m *HealthCheck_HTTP) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *CommandInfo) Marshal() (data []byte, err error) { +func (m *Offer_Operation_Reserve) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -13788,23 +15937,13 @@ func (m *CommandInfo) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *CommandInfo) MarshalTo(data []byte) (n int, err error) { +func (m *Offer_Operation_Reserve) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Container != nil { - data[i] = 0x22 - i++ - i = encodeVarintMesos(data, i, uint64(m.Container.Size())) - n4, err := m.Container.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n4 - } - if len(m.Uris) > 0 { - for _, msg := range m.Uris { + if len(m.Resources) > 0 { + for _, msg := range m.Resources { data[i] = 0xa i++ i = encodeVarintMesos(data, i, uint64(msg.Size())) @@ -13815,60 +15954,46 @@ func (m *CommandInfo) MarshalTo(data []byte) (n int, err error) { i += n } } - if m.Environment != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(m.Environment.Size())) - n5, err := m.Environment.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n5 - } - if m.Shell != nil { - data[i] = 0x30 - i++ - if *m.Shell { - data[i] = 1 - } else { - data[i] = 0 - } - i++ + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if m.Value != nil { - data[i] = 0x1a - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Value))) - i += copy(data[i:], *m.Value) + return i, nil +} + +func (m *Offer_Operation_Unreserve) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if len(m.Arguments) > 0 { - for _, s := range m.Arguments { - data[i] = 0x3a + return data[:n], nil +} + +func (m *Offer_Operation_Unreserve) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Resources) > 0 { + for _, msg := range m.Resources { + data[i] = 0xa i++ - l = len(s) - for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err } - data[i] = uint8(l) - i++ - i += copy(data[i:], s) + i += n } } - if m.User != nil { - data[i] = 0x2a - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.User))) - i += copy(data[i:], *m.User) - } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) } return i, nil } -func (m *CommandInfo_URI) Marshal() (data []byte, err error) { +func (m *Offer_Operation_Create) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -13878,36 +16003,22 @@ func (m *CommandInfo_URI) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *CommandInfo_URI) MarshalTo(data []byte) (n int, err error) { +func (m *Offer_Operation_Create) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Value != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Value))) - i += copy(data[i:], *m.Value) - } - if m.Executable != nil { - data[i] = 0x10 - i++ - if *m.Executable { - data[i] = 1 - } else { - data[i] = 0 - } - i++ - } - if m.Extract != nil { - data[i] = 0x18 - i++ - if *m.Extract { - data[i] = 1 - } else { - data[i] = 0 + if len(m.Volumes) > 0 { + for _, msg := range m.Volumes { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n } - i++ } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -13915,7 +16026,7 @@ func (m *CommandInfo_URI) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *CommandInfo_ContainerInfo) Marshal() (data []byte, err error) { +func (m *Offer_Operation_Destroy) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -13925,30 +16036,21 @@ func (m *CommandInfo_ContainerInfo) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *CommandInfo_ContainerInfo) MarshalTo(data []byte) (n int, err error) { +func (m *Offer_Operation_Destroy) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Image != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Image))) - i += copy(data[i:], *m.Image) - } - if len(m.Options) > 0 { - for _, s := range m.Options { - data[i] = 0x12 + if len(m.Volumes) > 0 { + for _, msg := range m.Volumes { + data[i] = 0xa i++ - l = len(s) - for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err } - data[i] = uint8(l) - i++ - i += copy(data[i:], s) + i += n } } if m.XXX_unrecognized != nil { @@ -13957,7 +16059,7 @@ func (m *CommandInfo_ContainerInfo) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *ExecutorInfo) Marshal() (data []byte, err error) { +func (m *TaskInfo) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -13967,54 +16069,46 @@ func (m *ExecutorInfo) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *ExecutorInfo) MarshalTo(data []byte) (n int, err error) { +func (m *TaskInfo) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.ExecutorId != nil { + if m.Name == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } else { data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(m.ExecutorId.Size())) - n6, err := m.ExecutorId.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n6 - } - if m.FrameworkId != nil { - data[i] = 0x42 - i++ - i = encodeVarintMesos(data, i, uint64(m.FrameworkId.Size())) - n7, err := m.FrameworkId.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n7 + i = encodeVarintMesos(data, i, uint64(len(*m.Name))) + i += copy(data[i:], *m.Name) } - if m.Command != nil { - data[i] = 0x3a + if m.TaskId == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("task_id") + } else { + data[i] = 0x12 i++ - i = encodeVarintMesos(data, i, uint64(m.Command.Size())) - n8, err := m.Command.MarshalTo(data[i:]) + i = encodeVarintMesos(data, i, uint64(m.TaskId.Size())) + n40, err := m.TaskId.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n8 + i += n40 } - if m.Container != nil { - data[i] = 0x5a + if m.SlaveId == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("slave_id") + } else { + data[i] = 0x1a i++ - i = encodeVarintMesos(data, i, uint64(m.Container.Size())) - n9, err := m.Container.MarshalTo(data[i:]) + i = encodeVarintMesos(data, i, uint64(m.SlaveId.Size())) + n41, err := m.SlaveId.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n9 + i += n41 } if len(m.Resources) > 0 { for _, msg := range m.Resources { - data[i] = 0x2a + data[i] = 0x22 i++ i = encodeVarintMesos(data, i, uint64(msg.Size())) n, err := msg.MarshalTo(data[i:]) @@ -14024,23 +16118,71 @@ func (m *ExecutorInfo) MarshalTo(data []byte) (n int, err error) { i += n } } - if m.Name != nil { + if m.Executor != nil { + data[i] = 0x2a + i++ + i = encodeVarintMesos(data, i, uint64(m.Executor.Size())) + n42, err := m.Executor.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n42 + } + if m.Data != nil { + data[i] = 0x32 + i++ + i = encodeVarintMesos(data, i, uint64(len(m.Data))) + i += copy(data[i:], m.Data) + } + if m.Command != nil { + data[i] = 0x3a + i++ + i = encodeVarintMesos(data, i, uint64(m.Command.Size())) + n43, err := m.Command.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n43 + } + if m.HealthCheck != nil { + data[i] = 0x42 + i++ + i = encodeVarintMesos(data, i, uint64(m.HealthCheck.Size())) + n44, err := m.HealthCheck.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n44 + } + if m.Container != nil { data[i] = 0x4a i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Name))) - i += copy(data[i:], *m.Name) + i = encodeVarintMesos(data, i, uint64(m.Container.Size())) + n45, err := m.Container.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n45 } - if m.Source != nil { + if m.Labels != nil { data[i] = 0x52 i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Source))) - i += copy(data[i:], *m.Source) + i = encodeVarintMesos(data, i, uint64(m.Labels.Size())) + n46, err := m.Labels.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n46 } - if m.Data != nil { - data[i] = 0x22 + if m.Discovery != nil { + data[i] = 0x5a i++ - i = encodeVarintMesos(data, i, uint64(len(m.Data))) - i += copy(data[i:], m.Data) + i = encodeVarintMesos(data, i, uint64(m.Discovery.Size())) + n47, err := m.Discovery.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n47 } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -14048,7 +16190,7 @@ func (m *ExecutorInfo) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *MasterInfo) Marshal() (data []byte, err error) { +func (m *TaskStatus) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14058,122 +16200,100 @@ func (m *MasterInfo) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *MasterInfo) MarshalTo(data []byte) (n int, err error) { +func (m *TaskStatus) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Id != nil { + if m.TaskId == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("task_id") + } else { data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Id))) - i += copy(data[i:], *m.Id) + i = encodeVarintMesos(data, i, uint64(m.TaskId.Size())) + n48, err := m.TaskId.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n48 } - if m.Ip != nil { + if m.State == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("state") + } else { data[i] = 0x10 i++ - i = encodeVarintMesos(data, i, uint64(*m.Ip)) + i = encodeVarintMesos(data, i, uint64(*m.State)) } - if m.Port != nil { - data[i] = 0x18 + if m.Data != nil { + data[i] = 0x1a i++ - i = encodeVarintMesos(data, i, uint64(*m.Port)) + i = encodeVarintMesos(data, i, uint64(len(m.Data))) + i += copy(data[i:], m.Data) } - if m.Pid != nil { + if m.Message != nil { data[i] = 0x22 i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Pid))) - i += copy(data[i:], *m.Pid) + i = encodeVarintMesos(data, i, uint64(len(*m.Message))) + i += copy(data[i:], *m.Message) } - if m.Hostname != nil { + if m.SlaveId != nil { data[i] = 0x2a i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Hostname))) - i += copy(data[i:], *m.Hostname) - } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) - } - return i, nil -} - -func (m *SlaveInfo) 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 *SlaveInfo) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Hostname != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Hostname))) - i += copy(data[i:], *m.Hostname) - } - if m.Port != nil { - data[i] = 0x40 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Port)) - } - if len(m.Resources) > 0 { - for _, msg := range m.Resources { - data[i] = 0x1a - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n + i = encodeVarintMesos(data, i, uint64(m.SlaveId.Size())) + n49, err := m.SlaveId.MarshalTo(data[i:]) + if err != nil { + return 0, err } + i += n49 } - if len(m.Attributes) > 0 { - for _, msg := range m.Attributes { - data[i] = 0x2a - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n - } + if m.Timestamp != nil { + data[i] = 0x31 + i++ + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.Timestamp))) } - if m.Id != nil { - data[i] = 0x32 + if m.ExecutorId != nil { + data[i] = 0x3a i++ - i = encodeVarintMesos(data, i, uint64(m.Id.Size())) - n10, err := m.Id.MarshalTo(data[i:]) + i = encodeVarintMesos(data, i, uint64(m.ExecutorId.Size())) + n50, err := m.ExecutorId.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n10 + i += n50 } - if m.Checkpoint != nil { - data[i] = 0x38 + if m.Healthy != nil { + data[i] = 0x40 i++ - if *m.Checkpoint { + if *m.Healthy { data[i] = 1 } else { data[i] = 0 } i++ } + if m.Source != nil { + data[i] = 0x48 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Source)) + } + if m.Reason != nil { + data[i] = 0x50 + i++ + i = encodeVarintMesos(data, i, uint64(*m.Reason)) + } + if m.Uuid != nil { + data[i] = 0x5a + i++ + i = encodeVarintMesos(data, i, uint64(len(m.Uuid))) + i += copy(data[i:], m.Uuid) + } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) } return i, nil } -func (m *Value) Marshal() (data []byte, err error) { +func (m *Filters) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14183,55 +16303,15 @@ func (m *Value) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Value) MarshalTo(data []byte) (n int, err error) { +func (m *Filters) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Type != nil { - data[i] = 0x8 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Type)) - } - if m.Scalar != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(m.Scalar.Size())) - n11, err := m.Scalar.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n11 - } - if m.Ranges != nil { - data[i] = 0x1a - i++ - i = encodeVarintMesos(data, i, uint64(m.Ranges.Size())) - n12, err := m.Ranges.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n12 - } - if m.Set != nil { - data[i] = 0x22 - i++ - i = encodeVarintMesos(data, i, uint64(m.Set.Size())) - n13, err := m.Set.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n13 - } - if m.Text != nil { - data[i] = 0x2a + if m.RefuseSeconds != nil { + data[i] = 0x9 i++ - i = encodeVarintMesos(data, i, uint64(m.Text.Size())) - n14, err := m.Text.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n14 + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.RefuseSeconds))) } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -14239,7 +16319,7 @@ func (m *Value) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *Value_Scalar) Marshal() (data []byte, err error) { +func (m *Environment) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14249,15 +16329,22 @@ func (m *Value_Scalar) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Value_Scalar) MarshalTo(data []byte) (n int, err error) { +func (m *Environment) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Value != nil { - data[i] = 0x9 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.Value))) + if len(m.Variables) > 0 { + for _, msg := range m.Variables { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -14265,7 +16352,7 @@ func (m *Value_Scalar) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *Value_Range) Marshal() (data []byte, err error) { +func (m *Environment_Variable) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14275,20 +16362,26 @@ func (m *Value_Range) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Value_Range) MarshalTo(data []byte) (n int, err error) { +func (m *Environment_Variable) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Begin != nil { - data[i] = 0x8 + if m.Name == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } else { + data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(*m.Begin)) + i = encodeVarintMesos(data, i, uint64(len(*m.Name))) + i += copy(data[i:], *m.Name) } - if m.End != nil { - data[i] = 0x10 + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0x12 i++ - i = encodeVarintMesos(data, i, uint64(*m.End)) + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -14296,7 +16389,7 @@ func (m *Value_Range) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *Value_Ranges) Marshal() (data []byte, err error) { +func (m *Parameter) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14306,22 +16399,26 @@ func (m *Value_Ranges) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Value_Ranges) MarshalTo(data []byte) (n int, err error) { +func (m *Parameter) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if len(m.Range) > 0 { - for _, msg := range m.Range { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n - } + if m.Key == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("key") + } else { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Key))) + i += copy(data[i:], *m.Key) + } + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0x12 + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -14329,7 +16426,7 @@ func (m *Value_Ranges) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *Value_Set) Marshal() (data []byte, err error) { +func (m *Parameters) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14339,24 +16436,21 @@ func (m *Value_Set) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Value_Set) MarshalTo(data []byte) (n int, err error) { +func (m *Parameters) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if len(m.Item) > 0 { - for _, s := range m.Item { + if len(m.Parameter) > 0 { + for _, msg := range m.Parameter { data[i] = 0xa i++ - l = len(s) - for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err } - data[i] = uint8(l) - i++ - i += copy(data[i:], s) + i += n } } if m.XXX_unrecognized != nil { @@ -14365,7 +16459,7 @@ func (m *Value_Set) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *Value_Text) Marshal() (data []byte, err error) { +func (m *Credential) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14375,16 +16469,24 @@ func (m *Value_Text) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Value_Text) MarshalTo(data []byte) (n int, err error) { +func (m *Credential) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Value != nil { + if m.Principal == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("principal") + } else { data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Value))) - i += copy(data[i:], *m.Value) + i = encodeVarintMesos(data, i, uint64(len(*m.Principal))) + i += copy(data[i:], *m.Principal) + } + if m.Secret != nil { + data[i] = 0x12 + i++ + i = encodeVarintMesos(data, i, uint64(len(m.Secret))) + i += copy(data[i:], m.Secret) } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -14392,7 +16494,7 @@ func (m *Value_Text) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *Attribute) Marshal() (data []byte, err error) { +func (m *Credentials) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14402,61 +16504,22 @@ func (m *Attribute) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Attribute) MarshalTo(data []byte) (n int, err error) { +func (m *Credentials) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Name != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Name))) - i += copy(data[i:], *m.Name) - } - if m.Type != nil { - data[i] = 0x10 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Type)) - } - if m.Scalar != nil { - data[i] = 0x1a - i++ - i = encodeVarintMesos(data, i, uint64(m.Scalar.Size())) - n15, err := m.Scalar.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n15 - } - if m.Ranges != nil { - data[i] = 0x22 - i++ - i = encodeVarintMesos(data, i, uint64(m.Ranges.Size())) - n16, err := m.Ranges.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n16 - } - if m.Set != nil { - data[i] = 0x32 - i++ - i = encodeVarintMesos(data, i, uint64(m.Set.Size())) - n17, err := m.Set.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n17 - } - if m.Text != nil { - data[i] = 0x2a - i++ - i = encodeVarintMesos(data, i, uint64(m.Text.Size())) - n18, err := m.Text.MarshalTo(data[i:]) - if err != nil { - return 0, err + if len(m.Credentials) > 0 { + for _, msg := range m.Credentials { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n } - i += n18 } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -14464,7 +16527,7 @@ func (m *Attribute) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *Resource) Marshal() (data []byte, err error) { +func (m *ACL) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14474,65 +16537,18 @@ func (m *Resource) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Resource) MarshalTo(data []byte) (n int, err error) { +func (m *ACL) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Name != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Name))) - i += copy(data[i:], *m.Name) - } - if m.Type != nil { - data[i] = 0x10 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Type)) - } - if m.Scalar != nil { - data[i] = 0x1a - i++ - i = encodeVarintMesos(data, i, uint64(m.Scalar.Size())) - n19, err := m.Scalar.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n19 - } - if m.Ranges != nil { - data[i] = 0x22 - i++ - i = encodeVarintMesos(data, i, uint64(m.Ranges.Size())) - n20, err := m.Ranges.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n20 - } - if m.Set != nil { - data[i] = 0x2a - i++ - i = encodeVarintMesos(data, i, uint64(m.Set.Size())) - n21, err := m.Set.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n21 - } - if m.Role != nil { - data[i] = 0x32 - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Role))) - i += copy(data[i:], *m.Role) - } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) } return i, nil } -func (m *ResourceStatistics) Marshal() (data []byte, err error) { +func (m *ACL_Entity) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14542,160 +16558,30 @@ func (m *ResourceStatistics) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *ResourceStatistics) MarshalTo(data []byte) (n int, err error) { +func (m *ACL_Entity) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Timestamp != nil { - data[i] = 0x9 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.Timestamp))) - } - if m.CpusUserTimeSecs != nil { - data[i] = 0x11 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.CpusUserTimeSecs))) - } - if m.CpusSystemTimeSecs != nil { - data[i] = 0x19 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.CpusSystemTimeSecs))) - } - if m.CpusLimit != nil { - data[i] = 0x21 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.CpusLimit))) - } - if m.CpusNrPeriods != nil { - data[i] = 0x38 - i++ - i = encodeVarintMesos(data, i, uint64(*m.CpusNrPeriods)) - } - if m.CpusNrThrottled != nil { - data[i] = 0x40 - i++ - i = encodeVarintMesos(data, i, uint64(*m.CpusNrThrottled)) - } - if m.CpusThrottledTimeSecs != nil { - data[i] = 0x49 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.CpusThrottledTimeSecs))) - } - if m.MemRssBytes != nil { - data[i] = 0x28 - i++ - i = encodeVarintMesos(data, i, uint64(*m.MemRssBytes)) - } - if m.MemLimitBytes != nil { - data[i] = 0x30 - i++ - i = encodeVarintMesos(data, i, uint64(*m.MemLimitBytes)) - } - if m.MemFileBytes != nil { - data[i] = 0x50 - i++ - i = encodeVarintMesos(data, i, uint64(*m.MemFileBytes)) - } - if m.MemAnonBytes != nil { - data[i] = 0x58 - i++ - i = encodeVarintMesos(data, i, uint64(*m.MemAnonBytes)) - } - if m.MemMappedFileBytes != nil { - data[i] = 0x60 - i++ - i = encodeVarintMesos(data, i, uint64(*m.MemMappedFileBytes)) - } - if m.Perf != nil { - data[i] = 0x6a - i++ - i = encodeVarintMesos(data, i, uint64(m.Perf.Size())) - n22, err := m.Perf.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n22 - } - if m.NetRxPackets != nil { - data[i] = 0x70 - i++ - i = encodeVarintMesos(data, i, uint64(*m.NetRxPackets)) - } - if m.NetRxBytes != nil { - data[i] = 0x78 - i++ - i = encodeVarintMesos(data, i, uint64(*m.NetRxBytes)) - } - if m.NetRxErrors != nil { - data[i] = 0x80 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.NetRxErrors)) - } - if m.NetRxDropped != nil { - data[i] = 0x88 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.NetRxDropped)) - } - if m.NetTxPackets != nil { - data[i] = 0x90 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.NetTxPackets)) - } - if m.NetTxBytes != nil { - data[i] = 0x98 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.NetTxBytes)) - } - if m.NetTxErrors != nil { - data[i] = 0xa0 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.NetTxErrors)) - } - if m.NetTxDropped != nil { - data[i] = 0xa8 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.NetTxDropped)) - } - if m.NetTcpRttMicrosecsP50 != nil { - data[i] = 0xb1 - i++ - data[i] = 0x1 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.NetTcpRttMicrosecsP50))) - } - if m.NetTcpRttMicrosecsP90 != nil { - data[i] = 0xb9 - i++ - data[i] = 0x1 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.NetTcpRttMicrosecsP90))) - } - if m.NetTcpRttMicrosecsP95 != nil { - data[i] = 0xc1 - i++ - data[i] = 0x1 + if m.Type != nil { + data[i] = 0x8 i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.NetTcpRttMicrosecsP95))) + i = encodeVarintMesos(data, i, uint64(*m.Type)) } - if m.NetTcpRttMicrosecsP99 != nil { - data[i] = 0xc9 - i++ - data[i] = 0x1 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.NetTcpRttMicrosecsP99))) + if len(m.Values) > 0 { + for _, s := range m.Values { + data[i] = 0x12 + 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) + } } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -14703,7 +16589,7 @@ func (m *ResourceStatistics) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *ResourceUsage) Marshal() (data []byte, err error) { +func (m *ACL_RegisterFramework) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14713,66 +16599,79 @@ func (m *ResourceUsage) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *ResourceUsage) MarshalTo(data []byte) (n int, err error) { +func (m *ACL_RegisterFramework) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.SlaveId != nil { + if m.Principals == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("principals") + } else { data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(m.SlaveId.Size())) - n23, err := m.SlaveId.MarshalTo(data[i:]) + i = encodeVarintMesos(data, i, uint64(m.Principals.Size())) + n51, err := m.Principals.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n23 + i += n51 } - if m.FrameworkId != nil { + if m.Roles == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("roles") + } else { data[i] = 0x12 i++ - i = encodeVarintMesos(data, i, uint64(m.FrameworkId.Size())) - n24, err := m.FrameworkId.MarshalTo(data[i:]) + i = encodeVarintMesos(data, i, uint64(m.Roles.Size())) + n52, err := m.Roles.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n24 + i += n52 } - if m.ExecutorId != nil { - data[i] = 0x1a - i++ - i = encodeVarintMesos(data, i, uint64(m.ExecutorId.Size())) - n25, err := m.ExecutorId.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n25 + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if m.ExecutorName != nil { - data[i] = 0x22 - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.ExecutorName))) - i += copy(data[i:], *m.ExecutorName) + return i, nil +} + +func (m *ACL_RunTask) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if m.TaskId != nil { - data[i] = 0x2a + return data[:n], nil +} + +func (m *ACL_RunTask) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Principals == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("principals") + } else { + data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(m.TaskId.Size())) - n26, err := m.TaskId.MarshalTo(data[i:]) + i = encodeVarintMesos(data, i, uint64(m.Principals.Size())) + n53, err := m.Principals.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n26 + i += n53 } - if m.Statistics != nil { - data[i] = 0x32 + if m.Users == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("users") + } else { + data[i] = 0x12 i++ - i = encodeVarintMesos(data, i, uint64(m.Statistics.Size())) - n27, err := m.Statistics.MarshalTo(data[i:]) + i = encodeVarintMesos(data, i, uint64(m.Users.Size())) + n54, err := m.Users.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n27 + i += n54 } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -14780,7 +16679,7 @@ func (m *ResourceUsage) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *PerfStatistics) Marshal() (data []byte, err error) { +func (m *ACL_ShutdownFramework) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -14790,351 +16689,225 @@ func (m *PerfStatistics) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *PerfStatistics) MarshalTo(data []byte) (n int, err error) { +func (m *ACL_ShutdownFramework) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Timestamp != nil { - data[i] = 0x9 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.Timestamp))) - } - if m.Duration != nil { - data[i] = 0x11 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.Duration))) - } - if m.Cycles != nil { - data[i] = 0x18 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Cycles)) - } - if m.StalledCyclesFrontend != nil { - data[i] = 0x20 - i++ - i = encodeVarintMesos(data, i, uint64(*m.StalledCyclesFrontend)) - } - if m.StalledCyclesBackend != nil { - data[i] = 0x28 - i++ - i = encodeVarintMesos(data, i, uint64(*m.StalledCyclesBackend)) - } - if m.Instructions != nil { - data[i] = 0x30 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Instructions)) - } - if m.CacheReferences != nil { - data[i] = 0x38 - i++ - i = encodeVarintMesos(data, i, uint64(*m.CacheReferences)) - } - if m.CacheMisses != nil { - data[i] = 0x40 - i++ - i = encodeVarintMesos(data, i, uint64(*m.CacheMisses)) - } - if m.Branches != nil { - data[i] = 0x48 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Branches)) - } - if m.BranchMisses != nil { - data[i] = 0x50 - i++ - i = encodeVarintMesos(data, i, uint64(*m.BranchMisses)) - } - if m.BusCycles != nil { - data[i] = 0x58 - i++ - i = encodeVarintMesos(data, i, uint64(*m.BusCycles)) - } - if m.RefCycles != nil { - data[i] = 0x60 - i++ - i = encodeVarintMesos(data, i, uint64(*m.RefCycles)) - } - if m.CpuClock != nil { - data[i] = 0x69 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.CpuClock))) - } - if m.TaskClock != nil { - data[i] = 0x71 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.TaskClock))) - } - if m.PageFaults != nil { - data[i] = 0x78 - i++ - i = encodeVarintMesos(data, i, uint64(*m.PageFaults)) - } - if m.MinorFaults != nil { - data[i] = 0x80 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.MinorFaults)) - } - if m.MajorFaults != nil { - data[i] = 0x88 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.MajorFaults)) - } - if m.ContextSwitches != nil { - data[i] = 0x90 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.ContextSwitches)) - } - if m.CpuMigrations != nil { - data[i] = 0x98 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.CpuMigrations)) - } - if m.AlignmentFaults != nil { - data[i] = 0xa0 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.AlignmentFaults)) - } - if m.EmulationFaults != nil { - data[i] = 0xa8 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.EmulationFaults)) - } - if m.L1DcacheLoads != nil { - data[i] = 0xb0 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.L1DcacheLoads)) - } - if m.L1DcacheLoadMisses != nil { - data[i] = 0xb8 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.L1DcacheLoadMisses)) - } - if m.L1DcacheStores != nil { - data[i] = 0xc0 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.L1DcacheStores)) - } - if m.L1DcacheStoreMisses != nil { - data[i] = 0xc8 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.L1DcacheStoreMisses)) - } - if m.L1DcachePrefetches != nil { - data[i] = 0xd0 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.L1DcachePrefetches)) - } - if m.L1DcachePrefetchMisses != nil { - data[i] = 0xd8 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.L1DcachePrefetchMisses)) - } - if m.L1IcacheLoads != nil { - data[i] = 0xe0 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.L1IcacheLoads)) - } - if m.L1IcacheLoadMisses != nil { - data[i] = 0xe8 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.L1IcacheLoadMisses)) - } - if m.L1IcachePrefetches != nil { - data[i] = 0xf0 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.L1IcachePrefetches)) - } - if m.L1IcachePrefetchMisses != nil { - data[i] = 0xf8 - i++ - data[i] = 0x1 - i++ - i = encodeVarintMesos(data, i, uint64(*m.L1IcachePrefetchMisses)) - } - if m.LlcLoads != nil { - data[i] = 0x80 - i++ - data[i] = 0x2 - i++ - i = encodeVarintMesos(data, i, uint64(*m.LlcLoads)) - } - if m.LlcLoadMisses != nil { - data[i] = 0x88 - i++ - data[i] = 0x2 - i++ - i = encodeVarintMesos(data, i, uint64(*m.LlcLoadMisses)) - } - if m.LlcStores != nil { - data[i] = 0x90 - i++ - data[i] = 0x2 + if m.Principals == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("principals") + } else { + data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(*m.LlcStores)) + i = encodeVarintMesos(data, i, uint64(m.Principals.Size())) + n55, err := m.Principals.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n55 } - if m.LlcStoreMisses != nil { - data[i] = 0x98 - i++ - data[i] = 0x2 + if m.FrameworkPrincipals == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("framework_principals") + } else { + data[i] = 0x12 i++ - i = encodeVarintMesos(data, i, uint64(*m.LlcStoreMisses)) + i = encodeVarintMesos(data, i, uint64(m.FrameworkPrincipals.Size())) + n56, err := m.FrameworkPrincipals.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n56 } - if m.LlcPrefetches != nil { - data[i] = 0xa0 - i++ - data[i] = 0x2 - i++ - i = encodeVarintMesos(data, i, uint64(*m.LlcPrefetches)) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if m.LlcPrefetchMisses != nil { - data[i] = 0xa8 - i++ - data[i] = 0x2 - i++ - i = encodeVarintMesos(data, i, uint64(*m.LlcPrefetchMisses)) + return i, nil +} + +func (m *ACLs) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if m.DtlbLoads != nil { - data[i] = 0xb0 + return data[:n], nil +} + +func (m *ACLs) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Permissive != nil { + data[i] = 0x8 i++ - data[i] = 0x2 + if *m.Permissive { + data[i] = 1 + } else { + data[i] = 0 + } i++ - i = encodeVarintMesos(data, i, uint64(*m.DtlbLoads)) } - if m.DtlbLoadMisses != nil { - data[i] = 0xb8 - i++ - data[i] = 0x2 - i++ - i = encodeVarintMesos(data, i, uint64(*m.DtlbLoadMisses)) + if len(m.RegisterFrameworks) > 0 { + for _, msg := range m.RegisterFrameworks { + data[i] = 0x12 + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } } - if m.DtlbStores != nil { - data[i] = 0xc0 - i++ - data[i] = 0x2 - i++ - i = encodeVarintMesos(data, i, uint64(*m.DtlbStores)) + if len(m.RunTasks) > 0 { + for _, msg := range m.RunTasks { + data[i] = 0x1a + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } } - if m.DtlbStoreMisses != nil { - data[i] = 0xc8 - i++ - data[i] = 0x2 - i++ - i = encodeVarintMesos(data, i, uint64(*m.DtlbStoreMisses)) + if len(m.ShutdownFrameworks) > 0 { + for _, msg := range m.ShutdownFrameworks { + data[i] = 0x22 + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } } - if m.DtlbPrefetches != nil { - data[i] = 0xd0 - i++ - data[i] = 0x2 - i++ - i = encodeVarintMesos(data, i, uint64(*m.DtlbPrefetches)) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if m.DtlbPrefetchMisses != nil { - data[i] = 0xd8 - i++ - data[i] = 0x2 - i++ - i = encodeVarintMesos(data, i, uint64(*m.DtlbPrefetchMisses)) + return i, nil +} + +func (m *RateLimit) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if m.ItlbLoads != nil { - data[i] = 0xe0 - i++ - data[i] = 0x2 + return data[:n], nil +} + +func (m *RateLimit) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Qps != nil { + data[i] = 0x9 i++ - i = encodeVarintMesos(data, i, uint64(*m.ItlbLoads)) + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.Qps))) } - if m.ItlbLoadMisses != nil { - data[i] = 0xe8 - i++ - data[i] = 0x2 + if m.Principal == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("principal") + } else { + data[i] = 0x12 i++ - i = encodeVarintMesos(data, i, uint64(*m.ItlbLoadMisses)) + i = encodeVarintMesos(data, i, uint64(len(*m.Principal))) + i += copy(data[i:], *m.Principal) } - if m.BranchLoads != nil { - data[i] = 0xf0 - i++ - data[i] = 0x2 + if m.Capacity != nil { + data[i] = 0x18 i++ - i = encodeVarintMesos(data, i, uint64(*m.BranchLoads)) + i = encodeVarintMesos(data, i, uint64(*m.Capacity)) } - if m.BranchLoadMisses != nil { - data[i] = 0xf8 - i++ - data[i] = 0x2 - i++ - i = encodeVarintMesos(data, i, uint64(*m.BranchLoadMisses)) + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } - if m.NodeLoads != nil { - data[i] = 0x80 - i++ - data[i] = 0x3 - i++ - i = encodeVarintMesos(data, i, uint64(*m.NodeLoads)) + return i, nil +} + +func (m *RateLimits) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err } - if m.NodeLoadMisses != nil { - data[i] = 0x88 - i++ - data[i] = 0x3 - i++ - i = encodeVarintMesos(data, i, uint64(*m.NodeLoadMisses)) + return data[:n], nil +} + +func (m *RateLimits) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Limits) > 0 { + for _, msg := range m.Limits { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } } - if m.NodeStores != nil { - data[i] = 0x90 - i++ - data[i] = 0x3 + if m.AggregateDefaultQps != nil { + data[i] = 0x11 i++ - i = encodeVarintMesos(data, i, uint64(*m.NodeStores)) + i = encodeFixed64Mesos(data, i, uint64(math.Float64bits(*m.AggregateDefaultQps))) } - if m.NodeStoreMisses != nil { - data[i] = 0x98 - i++ - data[i] = 0x3 + if m.AggregateDefaultCapacity != nil { + data[i] = 0x18 i++ - i = encodeVarintMesos(data, i, uint64(*m.NodeStoreMisses)) + i = encodeVarintMesos(data, i, uint64(*m.AggregateDefaultCapacity)) } - if m.NodePrefetches != nil { - data[i] = 0xa0 - i++ - data[i] = 0x3 + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Volume) 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 *Volume) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.ContainerPath == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("container_path") + } else { + data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(*m.NodePrefetches)) + i = encodeVarintMesos(data, i, uint64(len(*m.ContainerPath))) + i += copy(data[i:], *m.ContainerPath) } - if m.NodePrefetchMisses != nil { - data[i] = 0xa8 + if m.HostPath != nil { + data[i] = 0x12 i++ - data[i] = 0x3 + i = encodeVarintMesos(data, i, uint64(len(*m.HostPath))) + i += copy(data[i:], *m.HostPath) + } + if m.Mode == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("mode") + } else { + data[i] = 0x18 i++ - i = encodeVarintMesos(data, i, uint64(*m.NodePrefetchMisses)) + i = encodeVarintMesos(data, i, uint64(*m.Mode)) } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -15142,7 +16915,7 @@ func (m *PerfStatistics) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *Request) Marshal() (data []byte, err error) { +func (m *ContainerInfo) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -15152,23 +16925,20 @@ func (m *Request) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Request) MarshalTo(data []byte) (n int, err error) { +func (m *ContainerInfo) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.SlaveId != nil { - data[i] = 0xa + if m.Type == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } else { + data[i] = 0x8 i++ - i = encodeVarintMesos(data, i, uint64(m.SlaveId.Size())) - n28, err := m.SlaveId.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n28 + i = encodeVarintMesos(data, i, uint64(*m.Type)) } - if len(m.Resources) > 0 { - for _, msg := range m.Resources { + if len(m.Volumes) > 0 { + for _, msg := range m.Volumes { data[i] = 0x12 i++ i = encodeVarintMesos(data, i, uint64(msg.Size())) @@ -15179,13 +16949,29 @@ func (m *Request) MarshalTo(data []byte) (n int, err error) { i += n } } + if m.Docker != nil { + data[i] = 0x1a + i++ + i = encodeVarintMesos(data, i, uint64(m.Docker.Size())) + n57, err := m.Docker.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n57 + } + if m.Hostname != nil { + data[i] = 0x22 + i++ + i = encodeVarintMesos(data, i, uint64(len(*m.Hostname))) + i += copy(data[i:], *m.Hostname) + } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) } return i, nil } -func (m *Offer) Marshal() (data []byte, err error) { +func (m *ContainerInfo_DockerInfo) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -15195,50 +16981,27 @@ func (m *Offer) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Offer) MarshalTo(data []byte) (n int, err error) { +func (m *ContainerInfo_DockerInfo) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Id != nil { + if m.Image == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("image") + } else { data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(m.Id.Size())) - n29, err := m.Id.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n29 - } - if m.FrameworkId != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(m.FrameworkId.Size())) - n30, err := m.FrameworkId.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n30 - } - if m.SlaveId != nil { - data[i] = 0x1a - i++ - i = encodeVarintMesos(data, i, uint64(m.SlaveId.Size())) - n31, err := m.SlaveId.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n31 + i = encodeVarintMesos(data, i, uint64(len(*m.Image))) + i += copy(data[i:], *m.Image) } - if m.Hostname != nil { - data[i] = 0x22 + if m.Network != nil { + data[i] = 0x10 i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Hostname))) - i += copy(data[i:], *m.Hostname) + i = encodeVarintMesos(data, i, uint64(*m.Network)) } - if len(m.Resources) > 0 { - for _, msg := range m.Resources { - data[i] = 0x2a + if len(m.PortMappings) > 0 { + for _, msg := range m.PortMappings { + data[i] = 0x1a i++ i = encodeVarintMesos(data, i, uint64(msg.Size())) n, err := msg.MarshalTo(data[i:]) @@ -15248,21 +17011,19 @@ func (m *Offer) MarshalTo(data []byte) (n int, err error) { i += n } } - if len(m.Attributes) > 0 { - for _, msg := range m.Attributes { - data[i] = 0x3a - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n + if m.Privileged != nil { + data[i] = 0x20 + i++ + if *m.Privileged { + data[i] = 1 + } else { + data[i] = 0 } + i++ } - if len(m.ExecutorIds) > 0 { - for _, msg := range m.ExecutorIds { - data[i] = 0x32 + if len(m.Parameters) > 0 { + for _, msg := range m.Parameters { + data[i] = 0x2a i++ i = encodeVarintMesos(data, i, uint64(msg.Size())) n, err := msg.MarshalTo(data[i:]) @@ -15272,13 +17033,23 @@ func (m *Offer) MarshalTo(data []byte) (n int, err error) { i += n } } + if m.ForcePullImage != nil { + data[i] = 0x30 + i++ + if *m.ForcePullImage { + data[i] = 1 + } else { + data[i] = 0 + } + i++ + } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) } return i, nil } -func (m *TaskInfo) Marshal() (data []byte, err error) { +func (m *ContainerInfo_DockerInfo_PortMapping) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -15288,40 +17059,55 @@ func (m *TaskInfo) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *TaskInfo) MarshalTo(data []byte) (n int, err error) { +func (m *ContainerInfo_DockerInfo_PortMapping) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Name != nil { - data[i] = 0xa + if m.HostPort == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("host_port") + } else { + data[i] = 0x8 i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Name))) - i += copy(data[i:], *m.Name) + i = encodeVarintMesos(data, i, uint64(*m.HostPort)) } - if m.TaskId != nil { - data[i] = 0x12 + if m.ContainerPort == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("container_port") + } else { + data[i] = 0x10 i++ - i = encodeVarintMesos(data, i, uint64(m.TaskId.Size())) - n32, err := m.TaskId.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n32 + i = encodeVarintMesos(data, i, uint64(*m.ContainerPort)) } - if m.SlaveId != nil { + if m.Protocol != nil { data[i] = 0x1a i++ - i = encodeVarintMesos(data, i, uint64(m.SlaveId.Size())) - n33, err := m.SlaveId.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n33 + i = encodeVarintMesos(data, i, uint64(len(*m.Protocol))) + i += copy(data[i:], *m.Protocol) } - if len(m.Resources) > 0 { - for _, msg := range m.Resources { - data[i] = 0x22 + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Labels) 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 *Labels) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Labels) > 0 { + for _, msg := range m.Labels { + data[i] = 0xa i++ i = encodeVarintMesos(data, i, uint64(msg.Size())) n, err := msg.MarshalTo(data[i:]) @@ -15331,51 +17117,113 @@ func (m *TaskInfo) MarshalTo(data []byte) (n int, err error) { i += n } } - if m.Executor != nil { - data[i] = 0x2a + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Label) 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 *Label) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Key == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("key") + } else { + data[i] = 0xa i++ - i = encodeVarintMesos(data, i, uint64(m.Executor.Size())) - n34, err := m.Executor.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n34 + i = encodeVarintMesos(data, i, uint64(len(*m.Key))) + i += copy(data[i:], *m.Key) } - if m.Command != nil { - data[i] = 0x3a + if m.Value != nil { + data[i] = 0x12 i++ - i = encodeVarintMesos(data, i, uint64(m.Command.Size())) - n35, err := m.Command.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n35 + i = encodeVarintMesos(data, i, uint64(len(*m.Value))) + i += copy(data[i:], *m.Value) } - if m.Container != nil { - data[i] = 0x4a + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Port) 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 *Port) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Number == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("number") + } else { + data[i] = 0x8 i++ - i = encodeVarintMesos(data, i, uint64(m.Container.Size())) - n36, err := m.Container.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n36 + i = encodeVarintMesos(data, i, uint64(*m.Number)) } - if m.Data != nil { - data[i] = 0x32 + if m.Name != nil { + data[i] = 0x12 i++ - i = encodeVarintMesos(data, i, uint64(len(m.Data))) - i += copy(data[i:], m.Data) + i = encodeVarintMesos(data, i, uint64(len(*m.Name))) + i += copy(data[i:], *m.Name) } - if m.HealthCheck != nil { - data[i] = 0x42 + if m.Protocol != nil { + data[i] = 0x1a i++ - i = encodeVarintMesos(data, i, uint64(m.HealthCheck.Size())) - n37, err := m.HealthCheck.MarshalTo(data[i:]) - if err != nil { - return 0, err + i = encodeVarintMesos(data, i, uint64(len(*m.Protocol))) + i += copy(data[i:], *m.Protocol) + } + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Ports) 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 *Ports) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Ports) > 0 { + for _, msg := range m.Ports { + data[i] = 0xa + i++ + i = encodeVarintMesos(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n } - i += n37 } if m.XXX_unrecognized != nil { i += copy(data[i:], m.XXX_unrecognized) @@ -15383,7 +17231,7 @@ func (m *TaskInfo) MarshalTo(data []byte) (n int, err error) { return i, nil } -func (m *TaskStatus) Marshal() (data []byte, err error) { +func (m *DiscoveryInfo) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -15393,7515 +17241,14929 @@ func (m *TaskStatus) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *TaskStatus) MarshalTo(data []byte) (n int, err error) { +func (m *DiscoveryInfo) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.TaskId != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(m.TaskId.Size())) - n38, err := m.TaskId.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n38 - } - if m.State != nil { - data[i] = 0x10 + if m.Visibility == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("visibility") + } else { + data[i] = 0x8 i++ - i = encodeVarintMesos(data, i, uint64(*m.State)) + i = encodeVarintMesos(data, i, uint64(*m.Visibility)) } - if m.Message != nil { - data[i] = 0x22 + if m.Name != nil { + data[i] = 0x12 i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Message))) - i += copy(data[i:], *m.Message) + i = encodeVarintMesos(data, i, uint64(len(*m.Name))) + i += copy(data[i:], *m.Name) } - if m.Source != nil { - data[i] = 0x48 + if m.Environment != nil { + data[i] = 0x1a i++ - i = encodeVarintMesos(data, i, uint64(*m.Source)) + i = encodeVarintMesos(data, i, uint64(len(*m.Environment))) + i += copy(data[i:], *m.Environment) } - if m.Reason != nil { - data[i] = 0x50 + if m.Location != nil { + data[i] = 0x22 i++ - i = encodeVarintMesos(data, i, uint64(*m.Reason)) + i = encodeVarintMesos(data, i, uint64(len(*m.Location))) + i += copy(data[i:], *m.Location) } - if m.Data != nil { - data[i] = 0x1a + if m.Version != nil { + data[i] = 0x2a i++ - i = encodeVarintMesos(data, i, uint64(len(m.Data))) - i += copy(data[i:], m.Data) + i = encodeVarintMesos(data, i, uint64(len(*m.Version))) + i += copy(data[i:], *m.Version) } - if m.SlaveId != nil { - data[i] = 0x2a + if m.Ports != nil { + data[i] = 0x32 i++ - i = encodeVarintMesos(data, i, uint64(m.SlaveId.Size())) - n39, err := m.SlaveId.MarshalTo(data[i:]) + i = encodeVarintMesos(data, i, uint64(m.Ports.Size())) + n58, err := m.Ports.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n39 + i += n58 } - if m.ExecutorId != nil { + if m.Labels != nil { data[i] = 0x3a i++ - i = encodeVarintMesos(data, i, uint64(m.ExecutorId.Size())) - n40, err := m.ExecutorId.MarshalTo(data[i:]) + i = encodeVarintMesos(data, i, uint64(m.Labels.Size())) + n59, err := m.Labels.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n40 + i += n59 + } + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeFixed64Mesos(data []byte, offset int, v uint64) int { + data[offset] = uint8(v) + data[offset+1] = uint8(v >> 8) + data[offset+2] = uint8(v >> 16) + data[offset+3] = uint8(v >> 24) + data[offset+4] = uint8(v >> 32) + data[offset+5] = uint8(v >> 40) + data[offset+6] = uint8(v >> 48) + data[offset+7] = uint8(v >> 56) + return offset + 8 +} +func encodeFixed32Mesos(data []byte, offset int, v uint32) int { + data[offset] = uint8(v) + data[offset+1] = uint8(v >> 8) + data[offset+2] = uint8(v >> 16) + data[offset+3] = uint8(v >> 24) + return offset + 4 +} +func encodeVarintMesos(data []byte, offset int, v uint64) int { + for v >= 1<<7 { + data[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + data[offset] = uint8(v) + return offset + 1 +} +func NewPopulatedFrameworkID(r randyMesos, easy bool) *FrameworkID { + this := &FrameworkID{} + v1 := randStringMesos(r) + this.Value = &v1 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + } + return this +} + +func NewPopulatedOfferID(r randyMesos, easy bool) *OfferID { + this := &OfferID{} + v2 := randStringMesos(r) + this.Value = &v2 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + } + return this +} + +func NewPopulatedSlaveID(r randyMesos, easy bool) *SlaveID { + this := &SlaveID{} + v3 := randStringMesos(r) + this.Value = &v3 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + } + return this +} + +func NewPopulatedTaskID(r randyMesos, easy bool) *TaskID { + this := &TaskID{} + v4 := randStringMesos(r) + this.Value = &v4 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + } + return this +} + +func NewPopulatedExecutorID(r randyMesos, easy bool) *ExecutorID { + this := &ExecutorID{} + v5 := randStringMesos(r) + this.Value = &v5 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + } + return this +} + +func NewPopulatedContainerID(r randyMesos, easy bool) *ContainerID { + this := &ContainerID{} + v6 := randStringMesos(r) + this.Value = &v6 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + } + return this +} + +func NewPopulatedFrameworkInfo(r randyMesos, easy bool) *FrameworkInfo { + this := &FrameworkInfo{} + v7 := randStringMesos(r) + this.User = &v7 + v8 := randStringMesos(r) + this.Name = &v8 + if r.Intn(10) != 0 { + this.Id = NewPopulatedFrameworkID(r, easy) + } + if r.Intn(10) != 0 { + v9 := float64(r.Float64()) + if r.Intn(2) == 0 { + v9 *= -1 + } + this.FailoverTimeout = &v9 + } + if r.Intn(10) != 0 { + v10 := bool(bool(r.Intn(2) == 0)) + this.Checkpoint = &v10 + } + if r.Intn(10) != 0 { + v11 := randStringMesos(r) + this.Role = &v11 + } + if r.Intn(10) != 0 { + v12 := randStringMesos(r) + this.Hostname = &v12 + } + if r.Intn(10) != 0 { + v13 := randStringMesos(r) + this.Principal = &v13 + } + if r.Intn(10) != 0 { + v14 := randStringMesos(r) + this.WebuiUrl = &v14 + } + if r.Intn(10) != 0 { + v15 := r.Intn(10) + this.Capabilities = make([]*FrameworkInfo_Capability, v15) + for i := 0; i < v15; i++ { + this.Capabilities[i] = NewPopulatedFrameworkInfo_Capability(r, easy) + } + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 11) + } + return this +} + +func NewPopulatedFrameworkInfo_Capability(r randyMesos, easy bool) *FrameworkInfo_Capability { + this := &FrameworkInfo_Capability{} + v16 := FrameworkInfo_Capability_Type([]int32{1}[r.Intn(1)]) + this.Type = &v16 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + } + return this +} + +func NewPopulatedHealthCheck(r randyMesos, easy bool) *HealthCheck { + this := &HealthCheck{} + if r.Intn(10) != 0 { + this.Http = NewPopulatedHealthCheck_HTTP(r, easy) + } + if r.Intn(10) != 0 { + v17 := float64(r.Float64()) + if r.Intn(2) == 0 { + v17 *= -1 + } + this.DelaySeconds = &v17 + } + if r.Intn(10) != 0 { + v18 := float64(r.Float64()) + if r.Intn(2) == 0 { + v18 *= -1 + } + this.IntervalSeconds = &v18 + } + if r.Intn(10) != 0 { + v19 := float64(r.Float64()) + if r.Intn(2) == 0 { + v19 *= -1 + } + this.TimeoutSeconds = &v19 + } + if r.Intn(10) != 0 { + v20 := uint32(r.Uint32()) + this.ConsecutiveFailures = &v20 + } + if r.Intn(10) != 0 { + v21 := float64(r.Float64()) + if r.Intn(2) == 0 { + v21 *= -1 + } + this.GracePeriodSeconds = &v21 + } + if r.Intn(10) != 0 { + this.Command = NewPopulatedCommandInfo(r, easy) + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 8) + } + return this +} + +func NewPopulatedHealthCheck_HTTP(r randyMesos, easy bool) *HealthCheck_HTTP { + this := &HealthCheck_HTTP{} + v22 := uint32(r.Uint32()) + this.Port = &v22 + if r.Intn(10) != 0 { + v23 := randStringMesos(r) + this.Path = &v23 + } + if r.Intn(10) != 0 { + v24 := r.Intn(100) + this.Statuses = make([]uint32, v24) + for i := 0; i < v24; i++ { + this.Statuses[i] = uint32(r.Uint32()) + } + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 5) + } + return this +} + +func NewPopulatedCommandInfo(r randyMesos, easy bool) *CommandInfo { + this := &CommandInfo{} + if r.Intn(10) != 0 { + v25 := r.Intn(10) + this.Uris = make([]*CommandInfo_URI, v25) + for i := 0; i < v25; i++ { + this.Uris[i] = NewPopulatedCommandInfo_URI(r, easy) + } + } + if r.Intn(10) != 0 { + this.Environment = NewPopulatedEnvironment(r, easy) } - if m.Timestamp != nil { - data[i] = 0x31 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.Timestamp))) + if r.Intn(10) != 0 { + v26 := randStringMesos(r) + this.Value = &v26 } - if m.Healthy != nil { - data[i] = 0x40 - i++ - if *m.Healthy { - data[i] = 1 - } else { - data[i] = 0 + if r.Intn(10) != 0 { + this.Container = NewPopulatedCommandInfo_ContainerInfo(r, easy) + } + if r.Intn(10) != 0 { + v27 := randStringMesos(r) + this.User = &v27 + } + if r.Intn(10) != 0 { + v28 := bool(bool(r.Intn(2) == 0)) + this.Shell = &v28 + } + if r.Intn(10) != 0 { + v29 := r.Intn(10) + this.Arguments = make([]string, v29) + for i := 0; i < v29; i++ { + this.Arguments[i] = randStringMesos(r) } - i++ } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 8) } - return i, nil + return this } -func (m *Filters) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err +func NewPopulatedCommandInfo_URI(r randyMesos, easy bool) *CommandInfo_URI { + this := &CommandInfo_URI{} + v30 := randStringMesos(r) + this.Value = &v30 + if r.Intn(10) != 0 { + v31 := bool(bool(r.Intn(2) == 0)) + this.Executable = &v31 } - return data[:n], nil -} - -func (m *Filters) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.RefuseSeconds != nil { - data[i] = 0x9 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.RefuseSeconds))) + if r.Intn(10) != 0 { + v32 := bool(bool(r.Intn(2) == 0)) + this.Extract = &v32 } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + v33 := bool(bool(r.Intn(2) == 0)) + this.Cache = &v33 } - return i, nil -} - -func (m *Environment) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 5) } - return data[:n], nil + return this } -func (m *Environment) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if len(m.Variables) > 0 { - for _, msg := range m.Variables { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n +func NewPopulatedCommandInfo_ContainerInfo(r randyMesos, easy bool) *CommandInfo_ContainerInfo { + this := &CommandInfo_ContainerInfo{} + v34 := randStringMesos(r) + this.Image = &v34 + if r.Intn(10) != 0 { + v35 := r.Intn(10) + this.Options = make([]string, v35) + for i := 0; i < v35; i++ { + this.Options[i] = randStringMesos(r) } } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) } - return i, nil + return this } -func (m *Environment_Variable) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err +func NewPopulatedExecutorInfo(r randyMesos, easy bool) *ExecutorInfo { + this := &ExecutorInfo{} + this.ExecutorId = NewPopulatedExecutorID(r, easy) + if r.Intn(10) != 0 { + v36 := r.Intn(100) + this.Data = make([]byte, v36) + for i := 0; i < v36; i++ { + this.Data[i] = byte(r.Intn(256)) + } } - return data[:n], nil -} - -func (m *Environment_Variable) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Name != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Name))) - i += copy(data[i:], *m.Name) + if r.Intn(10) != 0 { + v37 := r.Intn(10) + this.Resources = make([]*Resource, v37) + for i := 0; i < v37; i++ { + this.Resources[i] = NewPopulatedResource(r, easy) + } } - if m.Value != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Value))) - i += copy(data[i:], *m.Value) + this.Command = NewPopulatedCommandInfo(r, easy) + if r.Intn(10) != 0 { + this.FrameworkId = NewPopulatedFrameworkID(r, easy) } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + v38 := randStringMesos(r) + this.Name = &v38 } - return i, nil -} - -func (m *Parameter) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if r.Intn(10) != 0 { + v39 := randStringMesos(r) + this.Source = &v39 } - return data[:n], nil -} - -func (m *Parameter) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Key != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Key))) - i += copy(data[i:], *m.Key) + if r.Intn(10) != 0 { + this.Container = NewPopulatedContainerInfo(r, easy) } - if m.Value != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Value))) - i += copy(data[i:], *m.Value) + if r.Intn(10) != 0 { + this.Discovery = NewPopulatedDiscoveryInfo(r, easy) } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 13) } - return i, nil + return this } -func (m *Parameters) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err +func NewPopulatedMasterInfo(r randyMesos, easy bool) *MasterInfo { + this := &MasterInfo{} + v40 := randStringMesos(r) + this.Id = &v40 + v41 := uint32(r.Uint32()) + this.Ip = &v41 + v42 := uint32(r.Uint32()) + this.Port = &v42 + if r.Intn(10) != 0 { + v43 := randStringMesos(r) + this.Pid = &v43 } - return data[:n], nil + if r.Intn(10) != 0 { + v44 := randStringMesos(r) + this.Hostname = &v44 + } + if r.Intn(10) != 0 { + v45 := randStringMesos(r) + this.Version = &v45 + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 7) + } + return this } -func (m *Parameters) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if len(m.Parameter) > 0 { - for _, msg := range m.Parameter { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n +func NewPopulatedSlaveInfo(r randyMesos, easy bool) *SlaveInfo { + this := &SlaveInfo{} + v46 := randStringMesos(r) + this.Hostname = &v46 + if r.Intn(10) != 0 { + v47 := r.Intn(10) + this.Resources = make([]*Resource, v47) + for i := 0; i < v47; i++ { + this.Resources[i] = NewPopulatedResource(r, easy) } } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + v48 := r.Intn(10) + this.Attributes = make([]*Attribute, v48) + for i := 0; i < v48; i++ { + this.Attributes[i] = NewPopulatedAttribute(r, easy) + } } - return i, nil -} - -func (m *Credential) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if r.Intn(10) != 0 { + this.Id = NewPopulatedSlaveID(r, easy) } - return data[:n], nil + if r.Intn(10) != 0 { + v49 := bool(bool(r.Intn(2) == 0)) + this.Checkpoint = &v49 + } + if r.Intn(10) != 0 { + v50 := int32(r.Int31()) + if r.Intn(2) == 0 { + v50 *= -1 + } + this.Port = &v50 + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 9) + } + return this } -func (m *Credential) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Principal != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Principal))) - i += copy(data[i:], *m.Principal) +func NewPopulatedValue(r randyMesos, easy bool) *Value { + this := &Value{} + v51 := Value_Type([]int32{0, 1, 2, 3}[r.Intn(4)]) + this.Type = &v51 + if r.Intn(10) != 0 { + this.Scalar = NewPopulatedValue_Scalar(r, easy) } - if m.Secret != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(len(m.Secret))) - i += copy(data[i:], m.Secret) + if r.Intn(10) != 0 { + this.Ranges = NewPopulatedValue_Ranges(r, easy) + } + if r.Intn(10) != 0 { + this.Set = NewPopulatedValue_Set(r, easy) + } + if r.Intn(10) != 0 { + this.Text = NewPopulatedValue_Text(r, easy) + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 6) } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + return this +} + +func NewPopulatedValue_Scalar(r randyMesos, easy bool) *Value_Scalar { + this := &Value_Scalar{} + v52 := float64(r.Float64()) + if r.Intn(2) == 0 { + v52 *= -1 } - return i, nil + this.Value = &v52 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + } + return this } -func (m *Credentials) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err +func NewPopulatedValue_Range(r randyMesos, easy bool) *Value_Range { + this := &Value_Range{} + v53 := uint64(uint64(r.Uint32())) + this.Begin = &v53 + v54 := uint64(uint64(r.Uint32())) + this.End = &v54 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) } - return data[:n], nil + return this } -func (m *Credentials) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if len(m.Credentials) > 0 { - for _, msg := range m.Credentials { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n +func NewPopulatedValue_Ranges(r randyMesos, easy bool) *Value_Ranges { + this := &Value_Ranges{} + if r.Intn(10) != 0 { + v55 := r.Intn(10) + this.Range = make([]*Value_Range, v55) + for i := 0; i < v55; i++ { + this.Range[i] = NewPopulatedValue_Range(r, easy) } } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - return i, nil + return this } -func (m *ACL) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err +func NewPopulatedValue_Set(r randyMesos, easy bool) *Value_Set { + this := &Value_Set{} + if r.Intn(10) != 0 { + v56 := r.Intn(10) + this.Item = make([]string, v56) + for i := 0; i < v56; i++ { + this.Item[i] = randStringMesos(r) + } } - return data[:n], nil -} - -func (m *ACL) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - return i, nil + return this } -func (m *ACL_Entity) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err +func NewPopulatedValue_Text(r randyMesos, easy bool) *Value_Text { + this := &Value_Text{} + v57 := randStringMesos(r) + this.Value = &v57 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - return data[:n], nil + return this } -func (m *ACL_Entity) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Type != nil { - data[i] = 0x8 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Type)) +func NewPopulatedAttribute(r randyMesos, easy bool) *Attribute { + this := &Attribute{} + v58 := randStringMesos(r) + this.Name = &v58 + v59 := Value_Type([]int32{0, 1, 2, 3}[r.Intn(4)]) + this.Type = &v59 + if r.Intn(10) != 0 { + this.Scalar = NewPopulatedValue_Scalar(r, easy) } - if len(m.Values) > 0 { - for _, s := range m.Values { - data[i] = 0x12 - 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) - } + if r.Intn(10) != 0 { + this.Ranges = NewPopulatedValue_Ranges(r, easy) } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + this.Text = NewPopulatedValue_Text(r, easy) } - return i, nil -} - -func (m *ACL_RegisterFramework) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if r.Intn(10) != 0 { + this.Set = NewPopulatedValue_Set(r, easy) } - return data[:n], nil + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 7) + } + return this } -func (m *ACL_RegisterFramework) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Principals != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(m.Principals.Size())) - n41, err := m.Principals.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n41 +func NewPopulatedResource(r randyMesos, easy bool) *Resource { + this := &Resource{} + v60 := randStringMesos(r) + this.Name = &v60 + v61 := Value_Type([]int32{0, 1, 2, 3}[r.Intn(4)]) + this.Type = &v61 + if r.Intn(10) != 0 { + this.Scalar = NewPopulatedValue_Scalar(r, easy) } - if m.Roles != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(m.Roles.Size())) - n42, err := m.Roles.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n42 + if r.Intn(10) != 0 { + this.Ranges = NewPopulatedValue_Ranges(r, easy) } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + this.Set = NewPopulatedValue_Set(r, easy) } - return i, nil + if r.Intn(10) != 0 { + v62 := randStringMesos(r) + this.Role = &v62 + } + if r.Intn(10) != 0 { + this.Disk = NewPopulatedResource_DiskInfo(r, easy) + } + if r.Intn(10) != 0 { + this.Reservation = NewPopulatedResource_ReservationInfo(r, easy) + } + if r.Intn(10) != 0 { + this.Revocable = NewPopulatedResource_RevocableInfo(r, easy) + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 10) + } + return this } -func (m *ACL_RunTask) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err +func NewPopulatedResource_ReservationInfo(r randyMesos, easy bool) *Resource_ReservationInfo { + this := &Resource_ReservationInfo{} + v63 := randStringMesos(r) + this.Principal = &v63 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - return data[:n], nil + return this } -func (m *ACL_RunTask) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Principals != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(m.Principals.Size())) - n43, err := m.Principals.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n43 +func NewPopulatedResource_DiskInfo(r randyMesos, easy bool) *Resource_DiskInfo { + this := &Resource_DiskInfo{} + if r.Intn(10) != 0 { + this.Persistence = NewPopulatedResource_DiskInfo_Persistence(r, easy) } - if m.Users != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(m.Users.Size())) - n44, err := m.Users.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n44 + if r.Intn(10) != 0 { + this.Volume = NewPopulatedVolume(r, easy) } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) } - return i, nil + return this } -func (m *ACL_ShutdownFramework) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err +func NewPopulatedResource_DiskInfo_Persistence(r randyMesos, easy bool) *Resource_DiskInfo_Persistence { + this := &Resource_DiskInfo_Persistence{} + v64 := randStringMesos(r) + this.Id = &v64 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - return data[:n], nil + return this } -func (m *ACL_ShutdownFramework) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Principals != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(m.Principals.Size())) - n45, err := m.Principals.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n45 +func NewPopulatedResource_RevocableInfo(r randyMesos, easy bool) *Resource_RevocableInfo { + this := &Resource_RevocableInfo{} + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 1) + } + return this +} + +func NewPopulatedTrafficControlStatistics(r randyMesos, easy bool) *TrafficControlStatistics { + this := &TrafficControlStatistics{} + v65 := randStringMesos(r) + this.Id = &v65 + if r.Intn(10) != 0 { + v66 := uint64(uint64(r.Uint32())) + this.Backlog = &v66 + } + if r.Intn(10) != 0 { + v67 := uint64(uint64(r.Uint32())) + this.Bytes = &v67 + } + if r.Intn(10) != 0 { + v68 := uint64(uint64(r.Uint32())) + this.Drops = &v68 + } + if r.Intn(10) != 0 { + v69 := uint64(uint64(r.Uint32())) + this.Overlimits = &v69 + } + if r.Intn(10) != 0 { + v70 := uint64(uint64(r.Uint32())) + this.Packets = &v70 + } + if r.Intn(10) != 0 { + v71 := uint64(uint64(r.Uint32())) + this.Qlen = &v71 + } + if r.Intn(10) != 0 { + v72 := uint64(uint64(r.Uint32())) + this.Ratebps = &v72 } - if m.FrameworkPrincipals != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(m.FrameworkPrincipals.Size())) - n46, err := m.FrameworkPrincipals.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n46 + if r.Intn(10) != 0 { + v73 := uint64(uint64(r.Uint32())) + this.Ratepps = &v73 } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + v74 := uint64(uint64(r.Uint32())) + this.Requeues = &v74 } - return i, nil -} - -func (m *ACLs) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 11) } - return data[:n], nil + return this } -func (m *ACLs) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Permissive != nil { - data[i] = 0x8 - i++ - if *m.Permissive { - data[i] = 1 - } else { - data[i] = 0 +func NewPopulatedResourceStatistics(r randyMesos, easy bool) *ResourceStatistics { + this := &ResourceStatistics{} + v75 := float64(r.Float64()) + if r.Intn(2) == 0 { + v75 *= -1 + } + this.Timestamp = &v75 + if r.Intn(10) != 0 { + v76 := float64(r.Float64()) + if r.Intn(2) == 0 { + v76 *= -1 } - i++ + this.CpusUserTimeSecs = &v76 } - if len(m.RegisterFrameworks) > 0 { - for _, msg := range m.RegisterFrameworks { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n + if r.Intn(10) != 0 { + v77 := float64(r.Float64()) + if r.Intn(2) == 0 { + v77 *= -1 } + this.CpusSystemTimeSecs = &v77 } - if len(m.RunTasks) > 0 { - for _, msg := range m.RunTasks { - data[i] = 0x1a - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n + if r.Intn(10) != 0 { + v78 := float64(r.Float64()) + if r.Intn(2) == 0 { + v78 *= -1 } + this.CpusLimit = &v78 } - if len(m.ShutdownFrameworks) > 0 { - for _, msg := range m.ShutdownFrameworks { - data[i] = 0x22 - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n + if r.Intn(10) != 0 { + v79 := uint64(uint64(r.Uint32())) + this.MemRssBytes = &v79 + } + if r.Intn(10) != 0 { + v80 := uint64(uint64(r.Uint32())) + this.MemLimitBytes = &v80 + } + if r.Intn(10) != 0 { + v81 := uint32(r.Uint32()) + this.CpusNrPeriods = &v81 + } + if r.Intn(10) != 0 { + v82 := uint32(r.Uint32()) + this.CpusNrThrottled = &v82 + } + if r.Intn(10) != 0 { + v83 := float64(r.Float64()) + if r.Intn(2) == 0 { + v83 *= -1 } + this.CpusThrottledTimeSecs = &v83 } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + v84 := uint64(uint64(r.Uint32())) + this.MemFileBytes = &v84 } - return i, nil -} - -func (m *RateLimit) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if r.Intn(10) != 0 { + v85 := uint64(uint64(r.Uint32())) + this.MemAnonBytes = &v85 } - return data[:n], nil -} - -func (m *RateLimit) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Qps != nil { - data[i] = 0x9 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.Qps))) + if r.Intn(10) != 0 { + v86 := uint64(uint64(r.Uint32())) + this.MemMappedFileBytes = &v86 } - if m.Principal != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Principal))) - i += copy(data[i:], *m.Principal) + if r.Intn(10) != 0 { + this.Perf = NewPopulatedPerfStatistics(r, easy) } - if m.Capacity != nil { - data[i] = 0x18 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Capacity)) + if r.Intn(10) != 0 { + v87 := uint64(uint64(r.Uint32())) + this.NetRxPackets = &v87 } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + v88 := uint64(uint64(r.Uint32())) + this.NetRxBytes = &v88 } - return i, nil -} - -func (m *RateLimits) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if r.Intn(10) != 0 { + v89 := uint64(uint64(r.Uint32())) + this.NetRxErrors = &v89 } - return data[:n], nil -} - -func (m *RateLimits) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if len(m.Limits) > 0 { - for _, msg := range m.Limits { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n - } + if r.Intn(10) != 0 { + v90 := uint64(uint64(r.Uint32())) + this.NetRxDropped = &v90 } - if m.AggregateDefaultQps != nil { - data[i] = 0x11 - i++ - i = encodeFixed64Mesos(data, i, uint64(math2.Float64bits(*m.AggregateDefaultQps))) + if r.Intn(10) != 0 { + v91 := uint64(uint64(r.Uint32())) + this.NetTxPackets = &v91 } - if m.AggregateDefaultCapacity != nil { - data[i] = 0x18 - i++ - i = encodeVarintMesos(data, i, uint64(*m.AggregateDefaultCapacity)) + if r.Intn(10) != 0 { + v92 := uint64(uint64(r.Uint32())) + this.NetTxBytes = &v92 } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + v93 := uint64(uint64(r.Uint32())) + this.NetTxErrors = &v93 } - return i, nil -} - -func (m *Volume) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if r.Intn(10) != 0 { + v94 := uint64(uint64(r.Uint32())) + this.NetTxDropped = &v94 } - return data[:n], nil -} - -func (m *Volume) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.ContainerPath != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.ContainerPath))) - i += copy(data[i:], *m.ContainerPath) + if r.Intn(10) != 0 { + v95 := float64(r.Float64()) + if r.Intn(2) == 0 { + v95 *= -1 + } + this.NetTcpRttMicrosecsP50 = &v95 } - if m.HostPath != nil { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.HostPath))) - i += copy(data[i:], *m.HostPath) + if r.Intn(10) != 0 { + v96 := float64(r.Float64()) + if r.Intn(2) == 0 { + v96 *= -1 + } + this.NetTcpRttMicrosecsP90 = &v96 } - if m.Mode != nil { - data[i] = 0x18 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Mode)) + if r.Intn(10) != 0 { + v97 := float64(r.Float64()) + if r.Intn(2) == 0 { + v97 *= -1 + } + this.NetTcpRttMicrosecsP95 = &v97 } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + v98 := float64(r.Float64()) + if r.Intn(2) == 0 { + v98 *= -1 + } + this.NetTcpRttMicrosecsP99 = &v98 } - return i, nil -} - -func (m *ContainerInfo) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if r.Intn(10) != 0 { + v99 := uint64(uint64(r.Uint32())) + this.DiskLimitBytes = &v99 } - return data[:n], nil -} - -func (m *ContainerInfo) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Type != nil { - data[i] = 0x8 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Type)) + if r.Intn(10) != 0 { + v100 := uint64(uint64(r.Uint32())) + this.DiskUsedBytes = &v100 } - if len(m.Volumes) > 0 { - for _, msg := range m.Volumes { - data[i] = 0x12 - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n + if r.Intn(10) != 0 { + v101 := float64(r.Float64()) + if r.Intn(2) == 0 { + v101 *= -1 } + this.NetTcpActiveConnections = &v101 + } + if r.Intn(10) != 0 { + v102 := float64(r.Float64()) + if r.Intn(2) == 0 { + v102 *= -1 + } + this.NetTcpTimeWaitConnections = &v102 + } + if r.Intn(10) != 0 { + v103 := uint32(r.Uint32()) + this.Processes = &v103 + } + if r.Intn(10) != 0 { + v104 := uint32(r.Uint32()) + this.Threads = &v104 } - if m.Hostname != nil { - data[i] = 0x22 - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Hostname))) - i += copy(data[i:], *m.Hostname) + if r.Intn(10) != 0 { + v105 := uint64(uint64(r.Uint32())) + this.MemLowPressureCounter = &v105 } - if m.Docker != nil { - data[i] = 0x1a - i++ - i = encodeVarintMesos(data, i, uint64(m.Docker.Size())) - n47, err := m.Docker.MarshalTo(data[i:]) - if err != nil { - return 0, err + if r.Intn(10) != 0 { + v106 := uint64(uint64(r.Uint32())) + this.MemMediumPressureCounter = &v106 + } + if r.Intn(10) != 0 { + v107 := uint64(uint64(r.Uint32())) + this.MemCriticalPressureCounter = &v107 + } + if r.Intn(10) != 0 { + v108 := r.Intn(10) + this.NetTrafficControlStatistics = make([]*TrafficControlStatistics, v108) + for i := 0; i < v108; i++ { + this.NetTrafficControlStatistics[i] = NewPopulatedTrafficControlStatistics(r, easy) } - i += n47 } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + v109 := uint64(uint64(r.Uint32())) + this.MemTotalBytes = &v109 } - return i, nil -} - -func (m *ContainerInfo_DockerInfo) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err + if r.Intn(10) != 0 { + v110 := uint64(uint64(r.Uint32())) + this.MemTotalMemswBytes = &v110 } - return data[:n], nil -} - -func (m *ContainerInfo_DockerInfo) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Image != nil { - data[i] = 0xa - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Image))) - i += copy(data[i:], *m.Image) + if r.Intn(10) != 0 { + v111 := uint64(uint64(r.Uint32())) + this.MemSoftLimitBytes = &v111 } - if m.Network != nil { - data[i] = 0x10 - i++ - i = encodeVarintMesos(data, i, uint64(*m.Network)) + if r.Intn(10) != 0 { + v112 := uint64(uint64(r.Uint32())) + this.MemCacheBytes = &v112 } - if len(m.PortMappings) > 0 { - for _, msg := range m.PortMappings { - data[i] = 0x1a - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n - } + if r.Intn(10) != 0 { + v113 := uint64(uint64(r.Uint32())) + this.MemSwapBytes = &v113 } - if m.Privileged != nil { - data[i] = 0x20 - i++ - if *m.Privileged { - data[i] = 1 - } else { - data[i] = 0 - } - i++ + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 41) } - if len(m.Parameters) > 0 { - for _, msg := range m.Parameters { - data[i] = 0x2a - i++ - i = encodeVarintMesos(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n + return this +} + +func NewPopulatedResourceUsage(r randyMesos, easy bool) *ResourceUsage { + this := &ResourceUsage{} + if r.Intn(10) != 0 { + v114 := r.Intn(10) + this.Executors = make([]*ResourceUsage_Executor, v114) + for i := 0; i < v114; i++ { + this.Executors[i] = NewPopulatedResourceUsage_Executor(r, easy) } } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - return i, nil + return this } -func (m *ContainerInfo_DockerInfo_PortMapping) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err +func NewPopulatedResourceUsage_Executor(r randyMesos, easy bool) *ResourceUsage_Executor { + this := &ResourceUsage_Executor{} + this.ExecutorInfo = NewPopulatedExecutorInfo(r, easy) + if r.Intn(10) != 0 { + v115 := r.Intn(10) + this.Allocated = make([]*Resource, v115) + for i := 0; i < v115; i++ { + this.Allocated[i] = NewPopulatedResource(r, easy) + } } - return data[:n], nil + if r.Intn(10) != 0 { + this.Statistics = NewPopulatedResourceStatistics(r, easy) + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 4) + } + return this } -func (m *ContainerInfo_DockerInfo_PortMapping) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.HostPort != nil { - data[i] = 0x8 - i++ - i = encodeVarintMesos(data, i, uint64(*m.HostPort)) +func NewPopulatedPerfStatistics(r randyMesos, easy bool) *PerfStatistics { + this := &PerfStatistics{} + v116 := float64(r.Float64()) + if r.Intn(2) == 0 { + v116 *= -1 } - if m.ContainerPort != nil { - data[i] = 0x10 - i++ - i = encodeVarintMesos(data, i, uint64(*m.ContainerPort)) + this.Timestamp = &v116 + v117 := float64(r.Float64()) + if r.Intn(2) == 0 { + v117 *= -1 } - if m.Protocol != nil { - data[i] = 0x1a - i++ - i = encodeVarintMesos(data, i, uint64(len(*m.Protocol))) - i += copy(data[i:], *m.Protocol) + this.Duration = &v117 + if r.Intn(10) != 0 { + v118 := uint64(uint64(r.Uint32())) + this.Cycles = &v118 } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if r.Intn(10) != 0 { + v119 := uint64(uint64(r.Uint32())) + this.StalledCyclesFrontend = &v119 } - return i, nil -} - -func encodeFixed64Mesos(data []byte, offset int, v uint64) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - data[offset+4] = uint8(v >> 32) - data[offset+5] = uint8(v >> 40) - data[offset+6] = uint8(v >> 48) - data[offset+7] = uint8(v >> 56) - return offset + 8 -} -func encodeFixed32Mesos(data []byte, offset int, v uint32) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - return offset + 4 -} -func encodeVarintMesos(data []byte, offset int, v uint64) int { - for v >= 1<<7 { - data[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ + if r.Intn(10) != 0 { + v120 := uint64(uint64(r.Uint32())) + this.StalledCyclesBackend = &v120 } - data[offset] = uint8(v) - return offset + 1 -} -func (this *FrameworkID) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v121 := uint64(uint64(r.Uint32())) + this.Instructions = &v121 } - s := strings1.Join([]string{`&mesosproto.FrameworkID{` + - `Value:` + valueToGoStringMesos(this.Value, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *OfferID) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v122 := uint64(uint64(r.Uint32())) + this.CacheReferences = &v122 } - s := strings1.Join([]string{`&mesosproto.OfferID{` + - `Value:` + valueToGoStringMesos(this.Value, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *SlaveID) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v123 := uint64(uint64(r.Uint32())) + this.CacheMisses = &v123 } - s := strings1.Join([]string{`&mesosproto.SlaveID{` + - `Value:` + valueToGoStringMesos(this.Value, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *TaskID) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v124 := uint64(uint64(r.Uint32())) + this.Branches = &v124 } - s := strings1.Join([]string{`&mesosproto.TaskID{` + - `Value:` + valueToGoStringMesos(this.Value, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ExecutorID) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v125 := uint64(uint64(r.Uint32())) + this.BranchMisses = &v125 } - s := strings1.Join([]string{`&mesosproto.ExecutorID{` + - `Value:` + valueToGoStringMesos(this.Value, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ContainerID) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v126 := uint64(uint64(r.Uint32())) + this.BusCycles = &v126 } - s := strings1.Join([]string{`&mesosproto.ContainerID{` + - `Value:` + valueToGoStringMesos(this.Value, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *FrameworkInfo) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v127 := uint64(uint64(r.Uint32())) + this.RefCycles = &v127 } - s := strings1.Join([]string{`&mesosproto.FrameworkInfo{` + - `User:` + valueToGoStringMesos(this.User, "string"), - `Name:` + valueToGoStringMesos(this.Name, "string"), - `Id:` + fmt2.Sprintf("%#v", this.Id), - `FailoverTimeout:` + valueToGoStringMesos(this.FailoverTimeout, "float64"), - `Checkpoint:` + valueToGoStringMesos(this.Checkpoint, "bool"), - `Role:` + valueToGoStringMesos(this.Role, "string"), - `Hostname:` + valueToGoStringMesos(this.Hostname, "string"), - `Principal:` + valueToGoStringMesos(this.Principal, "string"), - `WebuiUrl:` + valueToGoStringMesos(this.WebuiUrl, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *HealthCheck) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v128 := float64(r.Float64()) + if r.Intn(2) == 0 { + v128 *= -1 + } + this.CpuClock = &v128 } - s := strings1.Join([]string{`&mesosproto.HealthCheck{` + - `Http:` + fmt2.Sprintf("%#v", this.Http), - `DelaySeconds:` + valueToGoStringMesos(this.DelaySeconds, "float64"), - `IntervalSeconds:` + valueToGoStringMesos(this.IntervalSeconds, "float64"), - `TimeoutSeconds:` + valueToGoStringMesos(this.TimeoutSeconds, "float64"), - `ConsecutiveFailures:` + valueToGoStringMesos(this.ConsecutiveFailures, "uint32"), - `GracePeriodSeconds:` + valueToGoStringMesos(this.GracePeriodSeconds, "float64"), - `Command:` + fmt2.Sprintf("%#v", this.Command), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *HealthCheck_HTTP) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v129 := float64(r.Float64()) + if r.Intn(2) == 0 { + v129 *= -1 + } + this.TaskClock = &v129 } - s := strings1.Join([]string{`&mesosproto.HealthCheck_HTTP{` + - `Port:` + valueToGoStringMesos(this.Port, "uint32"), - `Path:` + valueToGoStringMesos(this.Path, "string"), - `Statuses:` + fmt2.Sprintf("%#v", this.Statuses), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *CommandInfo) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v130 := uint64(uint64(r.Uint32())) + this.PageFaults = &v130 } - s := strings1.Join([]string{`&mesosproto.CommandInfo{` + - `Container:` + fmt2.Sprintf("%#v", this.Container), - `Uris:` + fmt2.Sprintf("%#v", this.Uris), - `Environment:` + fmt2.Sprintf("%#v", this.Environment), - `Shell:` + valueToGoStringMesos(this.Shell, "bool"), - `Value:` + valueToGoStringMesos(this.Value, "string"), - `Arguments:` + fmt2.Sprintf("%#v", this.Arguments), - `User:` + valueToGoStringMesos(this.User, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *CommandInfo_URI) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v131 := uint64(uint64(r.Uint32())) + this.MinorFaults = &v131 } - s := strings1.Join([]string{`&mesosproto.CommandInfo_URI{` + - `Value:` + valueToGoStringMesos(this.Value, "string"), - `Executable:` + valueToGoStringMesos(this.Executable, "bool"), - `Extract:` + valueToGoStringMesos(this.Extract, "bool"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *CommandInfo_ContainerInfo) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v132 := uint64(uint64(r.Uint32())) + this.MajorFaults = &v132 + } + if r.Intn(10) != 0 { + v133 := uint64(uint64(r.Uint32())) + this.ContextSwitches = &v133 + } + if r.Intn(10) != 0 { + v134 := uint64(uint64(r.Uint32())) + this.CpuMigrations = &v134 + } + if r.Intn(10) != 0 { + v135 := uint64(uint64(r.Uint32())) + this.AlignmentFaults = &v135 + } + if r.Intn(10) != 0 { + v136 := uint64(uint64(r.Uint32())) + this.EmulationFaults = &v136 + } + if r.Intn(10) != 0 { + v137 := uint64(uint64(r.Uint32())) + this.L1DcacheLoads = &v137 + } + if r.Intn(10) != 0 { + v138 := uint64(uint64(r.Uint32())) + this.L1DcacheLoadMisses = &v138 + } + if r.Intn(10) != 0 { + v139 := uint64(uint64(r.Uint32())) + this.L1DcacheStores = &v139 + } + if r.Intn(10) != 0 { + v140 := uint64(uint64(r.Uint32())) + this.L1DcacheStoreMisses = &v140 + } + if r.Intn(10) != 0 { + v141 := uint64(uint64(r.Uint32())) + this.L1DcachePrefetches = &v141 } - s := strings1.Join([]string{`&mesosproto.CommandInfo_ContainerInfo{` + - `Image:` + valueToGoStringMesos(this.Image, "string"), - `Options:` + fmt2.Sprintf("%#v", this.Options), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ExecutorInfo) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v142 := uint64(uint64(r.Uint32())) + this.L1DcachePrefetchMisses = &v142 } - s := strings1.Join([]string{`&mesosproto.ExecutorInfo{` + - `ExecutorId:` + fmt2.Sprintf("%#v", this.ExecutorId), - `FrameworkId:` + fmt2.Sprintf("%#v", this.FrameworkId), - `Command:` + fmt2.Sprintf("%#v", this.Command), - `Container:` + fmt2.Sprintf("%#v", this.Container), - `Resources:` + fmt2.Sprintf("%#v", this.Resources), - `Name:` + valueToGoStringMesos(this.Name, "string"), - `Source:` + valueToGoStringMesos(this.Source, "string"), - `Data:` + valueToGoStringMesos(this.Data, "byte"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *MasterInfo) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v143 := uint64(uint64(r.Uint32())) + this.L1IcacheLoads = &v143 } - s := strings1.Join([]string{`&mesosproto.MasterInfo{` + - `Id:` + valueToGoStringMesos(this.Id, "string"), - `Ip:` + valueToGoStringMesos(this.Ip, "uint32"), - `Port:` + valueToGoStringMesos(this.Port, "uint32"), - `Pid:` + valueToGoStringMesos(this.Pid, "string"), - `Hostname:` + valueToGoStringMesos(this.Hostname, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *SlaveInfo) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v144 := uint64(uint64(r.Uint32())) + this.L1IcacheLoadMisses = &v144 } - s := strings1.Join([]string{`&mesosproto.SlaveInfo{` + - `Hostname:` + valueToGoStringMesos(this.Hostname, "string"), - `Port:` + valueToGoStringMesos(this.Port, "int32"), - `Resources:` + fmt2.Sprintf("%#v", this.Resources), - `Attributes:` + fmt2.Sprintf("%#v", this.Attributes), - `Id:` + fmt2.Sprintf("%#v", this.Id), - `Checkpoint:` + valueToGoStringMesos(this.Checkpoint, "bool"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Value) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v145 := uint64(uint64(r.Uint32())) + this.L1IcachePrefetches = &v145 } - s := strings1.Join([]string{`&mesosproto.Value{` + - `Type:` + valueToGoStringMesos(this.Type, "mesosproto.Value_Type"), - `Scalar:` + fmt2.Sprintf("%#v", this.Scalar), - `Ranges:` + fmt2.Sprintf("%#v", this.Ranges), - `Set:` + fmt2.Sprintf("%#v", this.Set), - `Text:` + fmt2.Sprintf("%#v", this.Text), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Value_Scalar) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v146 := uint64(uint64(r.Uint32())) + this.L1IcachePrefetchMisses = &v146 } - s := strings1.Join([]string{`&mesosproto.Value_Scalar{` + - `Value:` + valueToGoStringMesos(this.Value, "float64"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Value_Range) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v147 := uint64(uint64(r.Uint32())) + this.LlcLoads = &v147 } - s := strings1.Join([]string{`&mesosproto.Value_Range{` + - `Begin:` + valueToGoStringMesos(this.Begin, "uint64"), - `End:` + valueToGoStringMesos(this.End, "uint64"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Value_Ranges) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v148 := uint64(uint64(r.Uint32())) + this.LlcLoadMisses = &v148 } - s := strings1.Join([]string{`&mesosproto.Value_Ranges{` + - `Range:` + fmt2.Sprintf("%#v", this.Range), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Value_Set) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v149 := uint64(uint64(r.Uint32())) + this.LlcStores = &v149 } - s := strings1.Join([]string{`&mesosproto.Value_Set{` + - `Item:` + fmt2.Sprintf("%#v", this.Item), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Value_Text) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v150 := uint64(uint64(r.Uint32())) + this.LlcStoreMisses = &v150 } - s := strings1.Join([]string{`&mesosproto.Value_Text{` + - `Value:` + valueToGoStringMesos(this.Value, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Attribute) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v151 := uint64(uint64(r.Uint32())) + this.LlcPrefetches = &v151 } - s := strings1.Join([]string{`&mesosproto.Attribute{` + - `Name:` + valueToGoStringMesos(this.Name, "string"), - `Type:` + valueToGoStringMesos(this.Type, "mesosproto.Value_Type"), - `Scalar:` + fmt2.Sprintf("%#v", this.Scalar), - `Ranges:` + fmt2.Sprintf("%#v", this.Ranges), - `Set:` + fmt2.Sprintf("%#v", this.Set), - `Text:` + fmt2.Sprintf("%#v", this.Text), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Resource) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v152 := uint64(uint64(r.Uint32())) + this.LlcPrefetchMisses = &v152 } - s := strings1.Join([]string{`&mesosproto.Resource{` + - `Name:` + valueToGoStringMesos(this.Name, "string"), - `Type:` + valueToGoStringMesos(this.Type, "mesosproto.Value_Type"), - `Scalar:` + fmt2.Sprintf("%#v", this.Scalar), - `Ranges:` + fmt2.Sprintf("%#v", this.Ranges), - `Set:` + fmt2.Sprintf("%#v", this.Set), - `Role:` + valueToGoStringMesos(this.Role, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ResourceStatistics) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v153 := uint64(uint64(r.Uint32())) + this.DtlbLoads = &v153 } - s := strings1.Join([]string{`&mesosproto.ResourceStatistics{` + - `Timestamp:` + valueToGoStringMesos(this.Timestamp, "float64"), - `CpusUserTimeSecs:` + valueToGoStringMesos(this.CpusUserTimeSecs, "float64"), - `CpusSystemTimeSecs:` + valueToGoStringMesos(this.CpusSystemTimeSecs, "float64"), - `CpusLimit:` + valueToGoStringMesos(this.CpusLimit, "float64"), - `CpusNrPeriods:` + valueToGoStringMesos(this.CpusNrPeriods, "uint32"), - `CpusNrThrottled:` + valueToGoStringMesos(this.CpusNrThrottled, "uint32"), - `CpusThrottledTimeSecs:` + valueToGoStringMesos(this.CpusThrottledTimeSecs, "float64"), - `MemRssBytes:` + valueToGoStringMesos(this.MemRssBytes, "uint64"), - `MemLimitBytes:` + valueToGoStringMesos(this.MemLimitBytes, "uint64"), - `MemFileBytes:` + valueToGoStringMesos(this.MemFileBytes, "uint64"), - `MemAnonBytes:` + valueToGoStringMesos(this.MemAnonBytes, "uint64"), - `MemMappedFileBytes:` + valueToGoStringMesos(this.MemMappedFileBytes, "uint64"), - `Perf:` + fmt2.Sprintf("%#v", this.Perf), - `NetRxPackets:` + valueToGoStringMesos(this.NetRxPackets, "uint64"), - `NetRxBytes:` + valueToGoStringMesos(this.NetRxBytes, "uint64"), - `NetRxErrors:` + valueToGoStringMesos(this.NetRxErrors, "uint64"), - `NetRxDropped:` + valueToGoStringMesos(this.NetRxDropped, "uint64"), - `NetTxPackets:` + valueToGoStringMesos(this.NetTxPackets, "uint64"), - `NetTxBytes:` + valueToGoStringMesos(this.NetTxBytes, "uint64"), - `NetTxErrors:` + valueToGoStringMesos(this.NetTxErrors, "uint64"), - `NetTxDropped:` + valueToGoStringMesos(this.NetTxDropped, "uint64"), - `NetTcpRttMicrosecsP50:` + valueToGoStringMesos(this.NetTcpRttMicrosecsP50, "float64"), - `NetTcpRttMicrosecsP90:` + valueToGoStringMesos(this.NetTcpRttMicrosecsP90, "float64"), - `NetTcpRttMicrosecsP95:` + valueToGoStringMesos(this.NetTcpRttMicrosecsP95, "float64"), - `NetTcpRttMicrosecsP99:` + valueToGoStringMesos(this.NetTcpRttMicrosecsP99, "float64"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ResourceUsage) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v154 := uint64(uint64(r.Uint32())) + this.DtlbLoadMisses = &v154 } - s := strings1.Join([]string{`&mesosproto.ResourceUsage{` + - `SlaveId:` + fmt2.Sprintf("%#v", this.SlaveId), - `FrameworkId:` + fmt2.Sprintf("%#v", this.FrameworkId), - `ExecutorId:` + fmt2.Sprintf("%#v", this.ExecutorId), - `ExecutorName:` + valueToGoStringMesos(this.ExecutorName, "string"), - `TaskId:` + fmt2.Sprintf("%#v", this.TaskId), - `Statistics:` + fmt2.Sprintf("%#v", this.Statistics), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *PerfStatistics) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v155 := uint64(uint64(r.Uint32())) + this.DtlbStores = &v155 } - s := strings1.Join([]string{`&mesosproto.PerfStatistics{` + - `Timestamp:` + valueToGoStringMesos(this.Timestamp, "float64"), - `Duration:` + valueToGoStringMesos(this.Duration, "float64"), - `Cycles:` + valueToGoStringMesos(this.Cycles, "uint64"), - `StalledCyclesFrontend:` + valueToGoStringMesos(this.StalledCyclesFrontend, "uint64"), - `StalledCyclesBackend:` + valueToGoStringMesos(this.StalledCyclesBackend, "uint64"), - `Instructions:` + valueToGoStringMesos(this.Instructions, "uint64"), - `CacheReferences:` + valueToGoStringMesos(this.CacheReferences, "uint64"), - `CacheMisses:` + valueToGoStringMesos(this.CacheMisses, "uint64"), - `Branches:` + valueToGoStringMesos(this.Branches, "uint64"), - `BranchMisses:` + valueToGoStringMesos(this.BranchMisses, "uint64"), - `BusCycles:` + valueToGoStringMesos(this.BusCycles, "uint64"), - `RefCycles:` + valueToGoStringMesos(this.RefCycles, "uint64"), - `CpuClock:` + valueToGoStringMesos(this.CpuClock, "float64"), - `TaskClock:` + valueToGoStringMesos(this.TaskClock, "float64"), - `PageFaults:` + valueToGoStringMesos(this.PageFaults, "uint64"), - `MinorFaults:` + valueToGoStringMesos(this.MinorFaults, "uint64"), - `MajorFaults:` + valueToGoStringMesos(this.MajorFaults, "uint64"), - `ContextSwitches:` + valueToGoStringMesos(this.ContextSwitches, "uint64"), - `CpuMigrations:` + valueToGoStringMesos(this.CpuMigrations, "uint64"), - `AlignmentFaults:` + valueToGoStringMesos(this.AlignmentFaults, "uint64"), - `EmulationFaults:` + valueToGoStringMesos(this.EmulationFaults, "uint64"), - `L1DcacheLoads:` + valueToGoStringMesos(this.L1DcacheLoads, "uint64"), - `L1DcacheLoadMisses:` + valueToGoStringMesos(this.L1DcacheLoadMisses, "uint64"), - `L1DcacheStores:` + valueToGoStringMesos(this.L1DcacheStores, "uint64"), - `L1DcacheStoreMisses:` + valueToGoStringMesos(this.L1DcacheStoreMisses, "uint64"), - `L1DcachePrefetches:` + valueToGoStringMesos(this.L1DcachePrefetches, "uint64"), - `L1DcachePrefetchMisses:` + valueToGoStringMesos(this.L1DcachePrefetchMisses, "uint64"), - `L1IcacheLoads:` + valueToGoStringMesos(this.L1IcacheLoads, "uint64"), - `L1IcacheLoadMisses:` + valueToGoStringMesos(this.L1IcacheLoadMisses, "uint64"), - `L1IcachePrefetches:` + valueToGoStringMesos(this.L1IcachePrefetches, "uint64"), - `L1IcachePrefetchMisses:` + valueToGoStringMesos(this.L1IcachePrefetchMisses, "uint64"), - `LlcLoads:` + valueToGoStringMesos(this.LlcLoads, "uint64"), - `LlcLoadMisses:` + valueToGoStringMesos(this.LlcLoadMisses, "uint64"), - `LlcStores:` + valueToGoStringMesos(this.LlcStores, "uint64"), - `LlcStoreMisses:` + valueToGoStringMesos(this.LlcStoreMisses, "uint64"), - `LlcPrefetches:` + valueToGoStringMesos(this.LlcPrefetches, "uint64"), - `LlcPrefetchMisses:` + valueToGoStringMesos(this.LlcPrefetchMisses, "uint64"), - `DtlbLoads:` + valueToGoStringMesos(this.DtlbLoads, "uint64"), - `DtlbLoadMisses:` + valueToGoStringMesos(this.DtlbLoadMisses, "uint64"), - `DtlbStores:` + valueToGoStringMesos(this.DtlbStores, "uint64"), - `DtlbStoreMisses:` + valueToGoStringMesos(this.DtlbStoreMisses, "uint64"), - `DtlbPrefetches:` + valueToGoStringMesos(this.DtlbPrefetches, "uint64"), - `DtlbPrefetchMisses:` + valueToGoStringMesos(this.DtlbPrefetchMisses, "uint64"), - `ItlbLoads:` + valueToGoStringMesos(this.ItlbLoads, "uint64"), - `ItlbLoadMisses:` + valueToGoStringMesos(this.ItlbLoadMisses, "uint64"), - `BranchLoads:` + valueToGoStringMesos(this.BranchLoads, "uint64"), - `BranchLoadMisses:` + valueToGoStringMesos(this.BranchLoadMisses, "uint64"), - `NodeLoads:` + valueToGoStringMesos(this.NodeLoads, "uint64"), - `NodeLoadMisses:` + valueToGoStringMesos(this.NodeLoadMisses, "uint64"), - `NodeStores:` + valueToGoStringMesos(this.NodeStores, "uint64"), - `NodeStoreMisses:` + valueToGoStringMesos(this.NodeStoreMisses, "uint64"), - `NodePrefetches:` + valueToGoStringMesos(this.NodePrefetches, "uint64"), - `NodePrefetchMisses:` + valueToGoStringMesos(this.NodePrefetchMisses, "uint64"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Request) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v156 := uint64(uint64(r.Uint32())) + this.DtlbStoreMisses = &v156 } - s := strings1.Join([]string{`&mesosproto.Request{` + - `SlaveId:` + fmt2.Sprintf("%#v", this.SlaveId), - `Resources:` + fmt2.Sprintf("%#v", this.Resources), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Offer) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v157 := uint64(uint64(r.Uint32())) + this.DtlbPrefetches = &v157 } - s := strings1.Join([]string{`&mesosproto.Offer{` + - `Id:` + fmt2.Sprintf("%#v", this.Id), - `FrameworkId:` + fmt2.Sprintf("%#v", this.FrameworkId), - `SlaveId:` + fmt2.Sprintf("%#v", this.SlaveId), - `Hostname:` + valueToGoStringMesos(this.Hostname, "string"), - `Resources:` + fmt2.Sprintf("%#v", this.Resources), - `Attributes:` + fmt2.Sprintf("%#v", this.Attributes), - `ExecutorIds:` + fmt2.Sprintf("%#v", this.ExecutorIds), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *TaskInfo) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v158 := uint64(uint64(r.Uint32())) + this.DtlbPrefetchMisses = &v158 } - s := strings1.Join([]string{`&mesosproto.TaskInfo{` + - `Name:` + valueToGoStringMesos(this.Name, "string"), - `TaskId:` + fmt2.Sprintf("%#v", this.TaskId), - `SlaveId:` + fmt2.Sprintf("%#v", this.SlaveId), - `Resources:` + fmt2.Sprintf("%#v", this.Resources), - `Executor:` + fmt2.Sprintf("%#v", this.Executor), - `Command:` + fmt2.Sprintf("%#v", this.Command), - `Container:` + fmt2.Sprintf("%#v", this.Container), - `Data:` + valueToGoStringMesos(this.Data, "byte"), - `HealthCheck:` + fmt2.Sprintf("%#v", this.HealthCheck), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *TaskStatus) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v159 := uint64(uint64(r.Uint32())) + this.ItlbLoads = &v159 } - s := strings1.Join([]string{`&mesosproto.TaskStatus{` + - `TaskId:` + fmt2.Sprintf("%#v", this.TaskId), - `State:` + valueToGoStringMesos(this.State, "mesosproto.TaskState"), - `Message:` + valueToGoStringMesos(this.Message, "string"), - `Source:` + valueToGoStringMesos(this.Source, "mesosproto.TaskStatus_Source"), - `Reason:` + valueToGoStringMesos(this.Reason, "mesosproto.TaskStatus_Reason"), - `Data:` + valueToGoStringMesos(this.Data, "byte"), - `SlaveId:` + fmt2.Sprintf("%#v", this.SlaveId), - `ExecutorId:` + fmt2.Sprintf("%#v", this.ExecutorId), - `Timestamp:` + valueToGoStringMesos(this.Timestamp, "float64"), - `Healthy:` + valueToGoStringMesos(this.Healthy, "bool"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Filters) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v160 := uint64(uint64(r.Uint32())) + this.ItlbLoadMisses = &v160 } - s := strings1.Join([]string{`&mesosproto.Filters{` + - `RefuseSeconds:` + valueToGoStringMesos(this.RefuseSeconds, "float64"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Environment) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v161 := uint64(uint64(r.Uint32())) + this.BranchLoads = &v161 } - s := strings1.Join([]string{`&mesosproto.Environment{` + - `Variables:` + fmt2.Sprintf("%#v", this.Variables), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Environment_Variable) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v162 := uint64(uint64(r.Uint32())) + this.BranchLoadMisses = &v162 } - s := strings1.Join([]string{`&mesosproto.Environment_Variable{` + - `Name:` + valueToGoStringMesos(this.Name, "string"), - `Value:` + valueToGoStringMesos(this.Value, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Parameter) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v163 := uint64(uint64(r.Uint32())) + this.NodeLoads = &v163 } - s := strings1.Join([]string{`&mesosproto.Parameter{` + - `Key:` + valueToGoStringMesos(this.Key, "string"), - `Value:` + valueToGoStringMesos(this.Value, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Parameters) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v164 := uint64(uint64(r.Uint32())) + this.NodeLoadMisses = &v164 } - s := strings1.Join([]string{`&mesosproto.Parameters{` + - `Parameter:` + fmt2.Sprintf("%#v", this.Parameter), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Credential) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v165 := uint64(uint64(r.Uint32())) + this.NodeStores = &v165 } - s := strings1.Join([]string{`&mesosproto.Credential{` + - `Principal:` + valueToGoStringMesos(this.Principal, "string"), - `Secret:` + valueToGoStringMesos(this.Secret, "byte"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Credentials) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v166 := uint64(uint64(r.Uint32())) + this.NodeStoreMisses = &v166 } - s := strings1.Join([]string{`&mesosproto.Credentials{` + - `Credentials:` + fmt2.Sprintf("%#v", this.Credentials), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ACL) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v167 := uint64(uint64(r.Uint32())) + this.NodePrefetches = &v167 } - s := strings1.Join([]string{`&mesosproto.ACL{` + - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ACL_Entity) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v168 := uint64(uint64(r.Uint32())) + this.NodePrefetchMisses = &v168 } - s := strings1.Join([]string{`&mesosproto.ACL_Entity{` + - `Type:` + valueToGoStringMesos(this.Type, "mesosproto.ACL_Entity_Type"), - `Values:` + fmt2.Sprintf("%#v", this.Values), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ACL_RegisterFramework) GoString() string { - if this == nil { - return "nil" + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 54) } - s := strings1.Join([]string{`&mesosproto.ACL_RegisterFramework{` + - `Principals:` + fmt2.Sprintf("%#v", this.Principals), - `Roles:` + fmt2.Sprintf("%#v", this.Roles), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + return this } -func (this *ACL_RunTask) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedRequest(r randyMesos, easy bool) *Request { + this := &Request{} + if r.Intn(10) != 0 { + this.SlaveId = NewPopulatedSlaveID(r, easy) } - s := strings1.Join([]string{`&mesosproto.ACL_RunTask{` + - `Principals:` + fmt2.Sprintf("%#v", this.Principals), - `Users:` + fmt2.Sprintf("%#v", this.Users), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ACL_ShutdownFramework) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v169 := r.Intn(10) + this.Resources = make([]*Resource, v169) + for i := 0; i < v169; i++ { + this.Resources[i] = NewPopulatedResource(r, easy) + } } - s := strings1.Join([]string{`&mesosproto.ACL_ShutdownFramework{` + - `Principals:` + fmt2.Sprintf("%#v", this.Principals), - `FrameworkPrincipals:` + fmt2.Sprintf("%#v", this.FrameworkPrincipals), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ACLs) GoString() string { - if this == nil { - return "nil" + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) } - s := strings1.Join([]string{`&mesosproto.ACLs{` + - `Permissive:` + valueToGoStringMesos(this.Permissive, "bool"), - `RegisterFrameworks:` + fmt2.Sprintf("%#v", this.RegisterFrameworks), - `RunTasks:` + fmt2.Sprintf("%#v", this.RunTasks), - `ShutdownFrameworks:` + fmt2.Sprintf("%#v", this.ShutdownFrameworks), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + return this } -func (this *RateLimit) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedOffer(r randyMesos, easy bool) *Offer { + this := &Offer{} + this.Id = NewPopulatedOfferID(r, easy) + this.FrameworkId = NewPopulatedFrameworkID(r, easy) + this.SlaveId = NewPopulatedSlaveID(r, easy) + v170 := randStringMesos(r) + this.Hostname = &v170 + if r.Intn(10) != 0 { + v171 := r.Intn(10) + this.Resources = make([]*Resource, v171) + for i := 0; i < v171; i++ { + this.Resources[i] = NewPopulatedResource(r, easy) + } } - s := strings1.Join([]string{`&mesosproto.RateLimit{` + - `Qps:` + valueToGoStringMesos(this.Qps, "float64"), - `Principal:` + valueToGoStringMesos(this.Principal, "string"), - `Capacity:` + valueToGoStringMesos(this.Capacity, "uint64"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *RateLimits) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v172 := r.Intn(10) + this.ExecutorIds = make([]*ExecutorID, v172) + for i := 0; i < v172; i++ { + this.ExecutorIds[i] = NewPopulatedExecutorID(r, easy) + } } - s := strings1.Join([]string{`&mesosproto.RateLimits{` + - `Limits:` + fmt2.Sprintf("%#v", this.Limits), - `AggregateDefaultQps:` + valueToGoStringMesos(this.AggregateDefaultQps, "float64"), - `AggregateDefaultCapacity:` + valueToGoStringMesos(this.AggregateDefaultCapacity, "uint64"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Volume) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + v173 := r.Intn(10) + this.Attributes = make([]*Attribute, v173) + for i := 0; i < v173; i++ { + this.Attributes[i] = NewPopulatedAttribute(r, easy) + } } - s := strings1.Join([]string{`&mesosproto.Volume{` + - `ContainerPath:` + valueToGoStringMesos(this.ContainerPath, "string"), - `HostPath:` + valueToGoStringMesos(this.HostPath, "string"), - `Mode:` + valueToGoStringMesos(this.Mode, "mesosproto.Volume_Mode"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ContainerInfo) GoString() string { - if this == nil { - return "nil" + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 8) } - s := strings1.Join([]string{`&mesosproto.ContainerInfo{` + - `Type:` + valueToGoStringMesos(this.Type, "mesosproto.ContainerInfo_Type"), - `Volumes:` + fmt2.Sprintf("%#v", this.Volumes), - `Hostname:` + valueToGoStringMesos(this.Hostname, "string"), - `Docker:` + fmt2.Sprintf("%#v", this.Docker), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + return this } -func (this *ContainerInfo_DockerInfo) GoString() string { - if this == nil { - return "nil" + +func NewPopulatedOffer_Operation(r randyMesos, easy bool) *Offer_Operation { + this := &Offer_Operation{} + v174 := Offer_Operation_Type([]int32{1, 2, 3, 4, 5}[r.Intn(5)]) + this.Type = &v174 + if r.Intn(10) != 0 { + this.Launch = NewPopulatedOffer_Operation_Launch(r, easy) } - s := strings1.Join([]string{`&mesosproto.ContainerInfo_DockerInfo{` + - `Image:` + valueToGoStringMesos(this.Image, "string"), - `Network:` + valueToGoStringMesos(this.Network, "mesosproto.ContainerInfo_DockerInfo_Network"), - `PortMappings:` + fmt2.Sprintf("%#v", this.PortMappings), - `Privileged:` + valueToGoStringMesos(this.Privileged, "bool"), - `Parameters:` + fmt2.Sprintf("%#v", this.Parameters), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *ContainerInfo_DockerInfo_PortMapping) GoString() string { - if this == nil { - return "nil" + if r.Intn(10) != 0 { + this.Reserve = NewPopulatedOffer_Operation_Reserve(r, easy) } - s := strings1.Join([]string{`&mesosproto.ContainerInfo_DockerInfo_PortMapping{` + - `HostPort:` + valueToGoStringMesos(this.HostPort, "uint32"), - `ContainerPort:` + valueToGoStringMesos(this.ContainerPort, "uint32"), - `Protocol:` + valueToGoStringMesos(this.Protocol, "string"), - `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func valueToGoStringMesos(v interface{}, typ string) string { - rv := reflect1.ValueOf(v) - if rv.IsNil() { - return "nil" + if r.Intn(10) != 0 { + this.Unreserve = NewPopulatedOffer_Operation_Unreserve(r, easy) } - pv := reflect1.Indirect(rv).Interface() - return fmt2.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) -} -func extensionToGoStringMesos(e map[int32]github_com_gogo_protobuf_proto1.Extension) string { - if e == nil { - return "nil" + if r.Intn(10) != 0 { + this.Create = NewPopulatedOffer_Operation_Create(r, easy) } - s := "map[int32]proto.Extension{" - keys := make([]int, 0, len(e)) - for k := range e { - keys = append(keys, int(k)) + if r.Intn(10) != 0 { + this.Destroy = NewPopulatedOffer_Operation_Destroy(r, easy) } - sort.Ints(keys) - ss := []string{} - for _, k := range keys { - ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString()) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 7) } - s += strings1.Join(ss, ",") + "}" - return s + return this } -func (this *FrameworkID) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") - } - that1, ok := that.(*FrameworkID) - if !ok { - return fmt3.Errorf("that is not of type *FrameworkID") - } - if that1 == nil { - if this == nil { - return nil +func NewPopulatedOffer_Operation_Launch(r randyMesos, easy bool) *Offer_Operation_Launch { + this := &Offer_Operation_Launch{} + if r.Intn(10) != 0 { + v175 := r.Intn(10) + this.TaskInfos = make([]*TaskInfo, v175) + for i := 0; i < v175; i++ { + this.TaskInfos[i] = NewPopulatedTaskInfo(r, easy) } - return fmt3.Errorf("that is type *FrameworkID but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *FrameworkIDbut is not nil && this == nil") } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + } + return this +} + +func NewPopulatedOffer_Operation_Reserve(r randyMesos, easy bool) *Offer_Operation_Reserve { + this := &Offer_Operation_Reserve{} + if r.Intn(10) != 0 { + v176 := r.Intn(10) + this.Resources = make([]*Resource, v176) + for i := 0; i < v176; i++ { + this.Resources[i] = NewPopulatedResource(r, easy) } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - return nil + return this } -func (this *FrameworkID) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true + +func NewPopulatedOffer_Operation_Unreserve(r randyMesos, easy bool) *Offer_Operation_Unreserve { + this := &Offer_Operation_Unreserve{} + if r.Intn(10) != 0 { + v177 := r.Intn(10) + this.Resources = make([]*Resource, v177) + for i := 0; i < v177; i++ { + this.Resources[i] = NewPopulatedResource(r, easy) } - return false } - - that1, ok := that.(*FrameworkID) - if !ok { - return false + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - if that1 == nil { - if this == nil { - return true + return this +} + +func NewPopulatedOffer_Operation_Create(r randyMesos, easy bool) *Offer_Operation_Create { + this := &Offer_Operation_Create{} + if r.Intn(10) != 0 { + v178 := r.Intn(10) + this.Volumes = make([]*Resource, v178) + for i := 0; i < v178; i++ { + this.Volumes[i] = NewPopulatedResource(r, easy) } - return false - } else if this == nil { - return false } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + } + return this +} + +func NewPopulatedOffer_Operation_Destroy(r randyMesos, easy bool) *Offer_Operation_Destroy { + this := &Offer_Operation_Destroy{} + if r.Intn(10) != 0 { + v179 := r.Intn(10) + this.Volumes = make([]*Resource, v179) + for i := 0; i < v179; i++ { + this.Volumes[i] = NewPopulatedResource(r, easy) } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - return true + return this } -func (this *OfferID) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil + +func NewPopulatedTaskInfo(r randyMesos, easy bool) *TaskInfo { + this := &TaskInfo{} + v180 := randStringMesos(r) + this.Name = &v180 + this.TaskId = NewPopulatedTaskID(r, easy) + this.SlaveId = NewPopulatedSlaveID(r, easy) + if r.Intn(10) != 0 { + v181 := r.Intn(10) + this.Resources = make([]*Resource, v181) + for i := 0; i < v181; i++ { + this.Resources[i] = NewPopulatedResource(r, easy) } - return fmt3.Errorf("that == nil && this != nil") } - - that1, ok := that.(*OfferID) - if !ok { - return fmt3.Errorf("that is not of type *OfferID") + if r.Intn(10) != 0 { + this.Executor = NewPopulatedExecutorInfo(r, easy) } - if that1 == nil { - if this == nil { - return nil + if r.Intn(10) != 0 { + v182 := r.Intn(100) + this.Data = make([]byte, v182) + for i := 0; i < v182; i++ { + this.Data[i] = byte(r.Intn(256)) } - return fmt3.Errorf("that is type *OfferID but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *OfferIDbut is not nil && this == nil") } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) - } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + if r.Intn(10) != 0 { + this.Command = NewPopulatedCommandInfo(r, easy) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if r.Intn(10) != 0 { + this.HealthCheck = NewPopulatedHealthCheck(r, easy) } - return nil + if r.Intn(10) != 0 { + this.Container = NewPopulatedContainerInfo(r, easy) + } + if r.Intn(10) != 0 { + this.Labels = NewPopulatedLabels(r, easy) + } + if r.Intn(10) != 0 { + this.Discovery = NewPopulatedDiscoveryInfo(r, easy) + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 12) + } + return this } -func (this *OfferID) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true + +func NewPopulatedTaskStatus(r randyMesos, easy bool) *TaskStatus { + this := &TaskStatus{} + this.TaskId = NewPopulatedTaskID(r, easy) + v183 := TaskState([]int32{6, 0, 1, 2, 3, 4, 5, 7}[r.Intn(8)]) + this.State = &v183 + if r.Intn(10) != 0 { + v184 := r.Intn(100) + this.Data = make([]byte, v184) + for i := 0; i < v184; i++ { + this.Data[i] = byte(r.Intn(256)) } - return false } - - that1, ok := that.(*OfferID) - if !ok { - return false + if r.Intn(10) != 0 { + v185 := randStringMesos(r) + this.Message = &v185 } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if r.Intn(10) != 0 { + this.SlaveId = NewPopulatedSlaveID(r, easy) } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false + if r.Intn(10) != 0 { + v186 := float64(r.Float64()) + if r.Intn(2) == 0 { + v186 *= -1 } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false + this.Timestamp = &v186 } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if r.Intn(10) != 0 { + this.ExecutorId = NewPopulatedExecutorID(r, easy) } - return true -} -func (this *SlaveID) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if r.Intn(10) != 0 { + v187 := bool(bool(r.Intn(2) == 0)) + this.Healthy = &v187 } - - that1, ok := that.(*SlaveID) - if !ok { - return fmt3.Errorf("that is not of type *SlaveID") + if r.Intn(10) != 0 { + v188 := TaskStatus_Source([]int32{0, 1, 2}[r.Intn(3)]) + this.Source = &v188 } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *SlaveID but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *SlaveIDbut is not nil && this == nil") + if r.Intn(10) != 0 { + v189 := TaskStatus_Reason([]int32{0, 17, 1, 2, 3, 4, 5, 6, 7, 8, 9, 18, 10, 11, 12, 13, 14, 15, 16}[r.Intn(19)]) + this.Reason = &v189 } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + if r.Intn(10) != 0 { + v190 := r.Intn(100) + this.Uuid = make([]byte, v190) + for i := 0; i < v190; i++ { + this.Uuid[i] = byte(r.Intn(256)) } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 12) } - return nil + return this } -func (this *SlaveID) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true + +func NewPopulatedFilters(r randyMesos, easy bool) *Filters { + this := &Filters{} + if r.Intn(10) != 0 { + v191 := float64(r.Float64()) + if r.Intn(2) == 0 { + v191 *= -1 } - return false + this.RefuseSeconds = &v191 } - - that1, ok := that.(*SlaveID) - if !ok { - return false + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - if that1 == nil { - if this == nil { - return true + return this +} + +func NewPopulatedEnvironment(r randyMesos, easy bool) *Environment { + this := &Environment{} + if r.Intn(10) != 0 { + v192 := r.Intn(10) + this.Variables = make([]*Environment_Variable, v192) + for i := 0; i < v192; i++ { + this.Variables[i] = NewPopulatedEnvironment_Variable(r, easy) } - return false - } else if this == nil { - return false } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false - } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + return this +} + +func NewPopulatedEnvironment_Variable(r randyMesos, easy bool) *Environment_Variable { + this := &Environment_Variable{} + v193 := randStringMesos(r) + this.Name = &v193 + v194 := randStringMesos(r) + this.Value = &v194 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) + } + return this +} + +func NewPopulatedParameter(r randyMesos, easy bool) *Parameter { + this := &Parameter{} + v195 := randStringMesos(r) + this.Key = &v195 + v196 := randStringMesos(r) + this.Value = &v196 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) } - return true + return this } -func (this *TaskID) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil + +func NewPopulatedParameters(r randyMesos, easy bool) *Parameters { + this := &Parameters{} + if r.Intn(10) != 0 { + v197 := r.Intn(10) + this.Parameter = make([]*Parameter, v197) + for i := 0; i < v197; i++ { + this.Parameter[i] = NewPopulatedParameter(r, easy) } - return fmt3.Errorf("that == nil && this != nil") } - - that1, ok := that.(*TaskID) - if !ok { - return fmt3.Errorf("that is not of type *TaskID") + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - if that1 == nil { - if this == nil { - return nil + return this +} + +func NewPopulatedCredential(r randyMesos, easy bool) *Credential { + this := &Credential{} + v198 := randStringMesos(r) + this.Principal = &v198 + if r.Intn(10) != 0 { + v199 := r.Intn(100) + this.Secret = make([]byte, v199) + for i := 0; i < v199; i++ { + this.Secret[i] = byte(r.Intn(256)) } - return fmt3.Errorf("that is type *TaskID but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *TaskIDbut is not nil && this == nil") } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) + } + return this +} + +func NewPopulatedCredentials(r randyMesos, easy bool) *Credentials { + this := &Credentials{} + if r.Intn(10) != 0 { + v200 := r.Intn(10) + this.Credentials = make([]*Credential, v200) + for i := 0; i < v200; i++ { + this.Credentials[i] = NewPopulatedCredential(r, easy) } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - return nil + return this } -func (this *TaskID) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + +func NewPopulatedACL(r randyMesos, easy bool) *ACL { + this := &ACL{} + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 1) } + return this +} - that1, ok := that.(*TaskID) - if !ok { - return false +func NewPopulatedACL_Entity(r randyMesos, easy bool) *ACL_Entity { + this := &ACL_Entity{} + if r.Intn(10) != 0 { + v201 := ACL_Entity_Type([]int32{0, 1, 2}[r.Intn(3)]) + this.Type = &v201 } - if that1 == nil { - if this == nil { - return true + if r.Intn(10) != 0 { + v202 := r.Intn(10) + this.Values = make([]string, v202) + for i := 0; i < v202; i++ { + this.Values[i] = randStringMesos(r) } - return false - } else if this == nil { - return false } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false - } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + return this +} + +func NewPopulatedACL_RegisterFramework(r randyMesos, easy bool) *ACL_RegisterFramework { + this := &ACL_RegisterFramework{} + this.Principals = NewPopulatedACL_Entity(r, easy) + this.Roles = NewPopulatedACL_Entity(r, easy) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) } - return true + return this } -func (this *ExecutorID) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + +func NewPopulatedACL_RunTask(r randyMesos, easy bool) *ACL_RunTask { + this := &ACL_RunTask{} + this.Principals = NewPopulatedACL_Entity(r, easy) + this.Users = NewPopulatedACL_Entity(r, easy) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) } + return this +} - that1, ok := that.(*ExecutorID) - if !ok { - return fmt3.Errorf("that is not of type *ExecutorID") +func NewPopulatedACL_ShutdownFramework(r randyMesos, easy bool) *ACL_ShutdownFramework { + this := &ACL_ShutdownFramework{} + this.Principals = NewPopulatedACL_Entity(r, easy) + this.FrameworkPrincipals = NewPopulatedACL_Entity(r, easy) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *ExecutorID but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ExecutorIDbut is not nil && this == nil") + return this +} + +func NewPopulatedACLs(r randyMesos, easy bool) *ACLs { + this := &ACLs{} + if r.Intn(10) != 0 { + v203 := bool(bool(r.Intn(2) == 0)) + this.Permissive = &v203 } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + if r.Intn(10) != 0 { + v204 := r.Intn(10) + this.RegisterFrameworks = make([]*ACL_RegisterFramework, v204) + for i := 0; i < v204; i++ { + this.RegisterFrameworks[i] = NewPopulatedACL_RegisterFramework(r, easy) } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if r.Intn(10) != 0 { + v205 := r.Intn(10) + this.RunTasks = make([]*ACL_RunTask, v205) + for i := 0; i < v205; i++ { + this.RunTasks[i] = NewPopulatedACL_RunTask(r, easy) + } } - return nil -} -func (this *ExecutorID) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true + if r.Intn(10) != 0 { + v206 := r.Intn(10) + this.ShutdownFrameworks = make([]*ACL_ShutdownFramework, v206) + for i := 0; i < v206; i++ { + this.ShutdownFrameworks[i] = NewPopulatedACL_ShutdownFramework(r, easy) } - return false } - - that1, ok := that.(*ExecutorID) - if !ok { - return false + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 5) } - if that1 == nil { - if this == nil { - return true + return this +} + +func NewPopulatedRateLimit(r randyMesos, easy bool) *RateLimit { + this := &RateLimit{} + if r.Intn(10) != 0 { + v207 := float64(r.Float64()) + if r.Intn(2) == 0 { + v207 *= -1 } - return false - } else if this == nil { - return false + this.Qps = &v207 } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false - } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false + v208 := randStringMesos(r) + this.Principal = &v208 + if r.Intn(10) != 0 { + v209 := uint64(uint64(r.Uint32())) + this.Capacity = &v209 } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 4) } - return true + return this } -func (this *ContainerID) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") - } - that1, ok := that.(*ContainerID) - if !ok { - return fmt3.Errorf("that is not of type *ContainerID") - } - if that1 == nil { - if this == nil { - return nil +func NewPopulatedRateLimits(r randyMesos, easy bool) *RateLimits { + this := &RateLimits{} + if r.Intn(10) != 0 { + v210 := r.Intn(10) + this.Limits = make([]*RateLimit, v210) + for i := 0; i < v210; i++ { + this.Limits[i] = NewPopulatedRateLimit(r, easy) } - return fmt3.Errorf("that is type *ContainerID but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ContainerIDbut is not nil && this == nil") } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + if r.Intn(10) != 0 { + v211 := float64(r.Float64()) + if r.Intn(2) == 0 { + v211 *= -1 } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + this.AggregateDefaultQps = &v211 } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if r.Intn(10) != 0 { + v212 := uint64(uint64(r.Uint32())) + this.AggregateDefaultCapacity = &v212 } - return nil -} -func (this *ContainerID) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 4) } + return this +} - that1, ok := that.(*ContainerID) - if !ok { - return false +func NewPopulatedVolume(r randyMesos, easy bool) *Volume { + this := &Volume{} + v213 := randStringMesos(r) + this.ContainerPath = &v213 + if r.Intn(10) != 0 { + v214 := randStringMesos(r) + this.HostPath = &v214 } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + v215 := Volume_Mode([]int32{1, 2}[r.Intn(2)]) + this.Mode = &v215 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 4) } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false + return this +} + +func NewPopulatedContainerInfo(r randyMesos, easy bool) *ContainerInfo { + this := &ContainerInfo{} + v216 := ContainerInfo_Type([]int32{1, 2}[r.Intn(2)]) + this.Type = &v216 + if r.Intn(10) != 0 { + v217 := r.Intn(10) + this.Volumes = make([]*Volume, v217) + for i := 0; i < v217; i++ { + this.Volumes[i] = NewPopulatedVolume(r, easy) } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if r.Intn(10) != 0 { + this.Docker = NewPopulatedContainerInfo_DockerInfo(r, easy) + } + if r.Intn(10) != 0 { + v218 := randStringMesos(r) + this.Hostname = &v218 + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 5) } - return true + return this } -func (this *FrameworkInfo) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") - } - that1, ok := that.(*FrameworkInfo) - if !ok { - return fmt3.Errorf("that is not of type *FrameworkInfo") +func NewPopulatedContainerInfo_DockerInfo(r randyMesos, easy bool) *ContainerInfo_DockerInfo { + this := &ContainerInfo_DockerInfo{} + v219 := randStringMesos(r) + this.Image = &v219 + if r.Intn(10) != 0 { + v220 := ContainerInfo_DockerInfo_Network([]int32{1, 2, 3}[r.Intn(3)]) + this.Network = &v220 } - if that1 == nil { - if this == nil { - return nil + if r.Intn(10) != 0 { + v221 := r.Intn(10) + this.PortMappings = make([]*ContainerInfo_DockerInfo_PortMapping, v221) + for i := 0; i < v221; i++ { + this.PortMappings[i] = NewPopulatedContainerInfo_DockerInfo_PortMapping(r, easy) } - return fmt3.Errorf("that is type *FrameworkInfo but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *FrameworkInfobut is not nil && this == nil") } - if this.User != nil && that1.User != nil { - if *this.User != *that1.User { - return fmt3.Errorf("User this(%v) Not Equal that(%v)", *this.User, *that1.User) - } - } else if this.User != nil { - return fmt3.Errorf("this.User == nil && that.User != nil") - } else if that1.User != nil { - return fmt3.Errorf("User this(%v) Not Equal that(%v)", this.User, that1.User) + if r.Intn(10) != 0 { + v222 := bool(bool(r.Intn(2) == 0)) + this.Privileged = &v222 } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) + if r.Intn(10) != 0 { + v223 := r.Intn(10) + this.Parameters = make([]*Parameter, v223) + for i := 0; i < v223; i++ { + this.Parameters[i] = NewPopulatedParameter(r, easy) } - } else if this.Name != nil { - return fmt3.Errorf("this.Name == nil && that.Name != nil") - } else if that1.Name != nil { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) } - if !this.Id.Equal(that1.Id) { - return fmt3.Errorf("Id this(%v) Not Equal that(%v)", this.Id, that1.Id) + if r.Intn(10) != 0 { + v224 := bool(bool(r.Intn(2) == 0)) + this.ForcePullImage = &v224 } - if this.FailoverTimeout != nil && that1.FailoverTimeout != nil { - if *this.FailoverTimeout != *that1.FailoverTimeout { - return fmt3.Errorf("FailoverTimeout this(%v) Not Equal that(%v)", *this.FailoverTimeout, *that1.FailoverTimeout) - } - } else if this.FailoverTimeout != nil { - return fmt3.Errorf("this.FailoverTimeout == nil && that.FailoverTimeout != nil") - } else if that1.FailoverTimeout != nil { - return fmt3.Errorf("FailoverTimeout this(%v) Not Equal that(%v)", this.FailoverTimeout, that1.FailoverTimeout) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 7) } - if this.Checkpoint != nil && that1.Checkpoint != nil { - if *this.Checkpoint != *that1.Checkpoint { - return fmt3.Errorf("Checkpoint this(%v) Not Equal that(%v)", *this.Checkpoint, *that1.Checkpoint) - } - } else if this.Checkpoint != nil { - return fmt3.Errorf("this.Checkpoint == nil && that.Checkpoint != nil") - } else if that1.Checkpoint != nil { - return fmt3.Errorf("Checkpoint this(%v) Not Equal that(%v)", this.Checkpoint, that1.Checkpoint) + return this +} + +func NewPopulatedContainerInfo_DockerInfo_PortMapping(r randyMesos, easy bool) *ContainerInfo_DockerInfo_PortMapping { + this := &ContainerInfo_DockerInfo_PortMapping{} + v225 := uint32(r.Uint32()) + this.HostPort = &v225 + v226 := uint32(r.Uint32()) + this.ContainerPort = &v226 + if r.Intn(10) != 0 { + v227 := randStringMesos(r) + this.Protocol = &v227 } - if this.Role != nil && that1.Role != nil { - if *this.Role != *that1.Role { - return fmt3.Errorf("Role this(%v) Not Equal that(%v)", *this.Role, *that1.Role) - } - } else if this.Role != nil { - return fmt3.Errorf("this.Role == nil && that.Role != nil") - } else if that1.Role != nil { - return fmt3.Errorf("Role this(%v) Not Equal that(%v)", this.Role, that1.Role) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 4) } - if this.Hostname != nil && that1.Hostname != nil { - if *this.Hostname != *that1.Hostname { - return fmt3.Errorf("Hostname this(%v) Not Equal that(%v)", *this.Hostname, *that1.Hostname) + return this +} + +func NewPopulatedLabels(r randyMesos, easy bool) *Labels { + this := &Labels{} + if r.Intn(10) != 0 { + v228 := r.Intn(10) + this.Labels = make([]*Label, v228) + for i := 0; i < v228; i++ { + this.Labels[i] = NewPopulatedLabel(r, easy) } - } else if this.Hostname != nil { - return fmt3.Errorf("this.Hostname == nil && that.Hostname != nil") - } else if that1.Hostname != nil { - return fmt3.Errorf("Hostname this(%v) Not Equal that(%v)", this.Hostname, that1.Hostname) } - if this.Principal != nil && that1.Principal != nil { - if *this.Principal != *that1.Principal { - return fmt3.Errorf("Principal this(%v) Not Equal that(%v)", *this.Principal, *that1.Principal) - } - } else if this.Principal != nil { - return fmt3.Errorf("this.Principal == nil && that.Principal != nil") - } else if that1.Principal != nil { - return fmt3.Errorf("Principal this(%v) Not Equal that(%v)", this.Principal, that1.Principal) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) } - if this.WebuiUrl != nil && that1.WebuiUrl != nil { - if *this.WebuiUrl != *that1.WebuiUrl { - return fmt3.Errorf("WebuiUrl this(%v) Not Equal that(%v)", *this.WebuiUrl, *that1.WebuiUrl) - } - } else if this.WebuiUrl != nil { - return fmt3.Errorf("this.WebuiUrl == nil && that.WebuiUrl != nil") - } else if that1.WebuiUrl != nil { - return fmt3.Errorf("WebuiUrl this(%v) Not Equal that(%v)", this.WebuiUrl, that1.WebuiUrl) + return this +} + +func NewPopulatedLabel(r randyMesos, easy bool) *Label { + this := &Label{} + v229 := randStringMesos(r) + this.Key = &v229 + if r.Intn(10) != 0 { + v230 := randStringMesos(r) + this.Value = &v230 } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 3) } - return nil + return this } -func (this *FrameworkInfo) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true + +func NewPopulatedPort(r randyMesos, easy bool) *Port { + this := &Port{} + v231 := uint32(r.Uint32()) + this.Number = &v231 + if r.Intn(10) != 0 { + v232 := randStringMesos(r) + this.Name = &v232 + } + if r.Intn(10) != 0 { + v233 := randStringMesos(r) + this.Protocol = &v233 + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 4) + } + return this +} + +func NewPopulatedPorts(r randyMesos, easy bool) *Ports { + this := &Ports{} + if r.Intn(10) != 0 { + v234 := r.Intn(10) + this.Ports = make([]*Port, v234) + for i := 0; i < v234; i++ { + this.Ports[i] = NewPopulatedPort(r, easy) } - return false } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 2) + } + return this +} - that1, ok := that.(*FrameworkInfo) - if !ok { - return false +func NewPopulatedDiscoveryInfo(r randyMesos, easy bool) *DiscoveryInfo { + this := &DiscoveryInfo{} + v235 := DiscoveryInfo_Visibility([]int32{0, 1, 2}[r.Intn(3)]) + this.Visibility = &v235 + if r.Intn(10) != 0 { + v236 := randStringMesos(r) + this.Name = &v236 } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if r.Intn(10) != 0 { + v237 := randStringMesos(r) + this.Environment = &v237 } - if this.User != nil && that1.User != nil { - if *this.User != *that1.User { - return false - } - } else if this.User != nil { - return false - } else if that1.User != nil { - return false + if r.Intn(10) != 0 { + v238 := randStringMesos(r) + this.Location = &v238 } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return false - } - } else if this.Name != nil { - return false - } else if that1.Name != nil { - return false + if r.Intn(10) != 0 { + v239 := randStringMesos(r) + this.Version = &v239 } - if !this.Id.Equal(that1.Id) { - return false + if r.Intn(10) != 0 { + this.Ports = NewPopulatedPorts(r, easy) } - if this.FailoverTimeout != nil && that1.FailoverTimeout != nil { - if *this.FailoverTimeout != *that1.FailoverTimeout { - return false - } - } else if this.FailoverTimeout != nil { - return false - } else if that1.FailoverTimeout != nil { - return false + if r.Intn(10) != 0 { + this.Labels = NewPopulatedLabels(r, easy) } - if this.Checkpoint != nil && that1.Checkpoint != nil { - if *this.Checkpoint != *that1.Checkpoint { - return false - } - } else if this.Checkpoint != nil { - return false - } else if that1.Checkpoint != nil { - return false + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMesos(r, 8) } - if this.Role != nil && that1.Role != nil { - if *this.Role != *that1.Role { - return false - } - } else if this.Role != nil { - return false - } else if that1.Role != nil { - return false + return this +} + +type randyMesos interface { + Float32() float32 + Float64() float64 + Int63() int64 + Int31() int32 + Uint32() uint32 + Intn(n int) int +} + +func randUTF8RuneMesos(r randyMesos) rune { + ru := r.Intn(62) + if ru < 10 { + return rune(ru + 48) + } else if ru < 36 { + return rune(ru + 55) } - if this.Hostname != nil && that1.Hostname != nil { - if *this.Hostname != *that1.Hostname { - return false - } - } else if this.Hostname != nil { - return false - } else if that1.Hostname != nil { - return false + return rune(ru + 61) +} +func randStringMesos(r randyMesos) string { + v240 := r.Intn(100) + tmps := make([]rune, v240) + for i := 0; i < v240; i++ { + tmps[i] = randUTF8RuneMesos(r) } - if this.Principal != nil && that1.Principal != nil { - if *this.Principal != *that1.Principal { - return false + return string(tmps) +} +func randUnrecognizedMesos(r randyMesos, maxFieldNumber int) (data []byte) { + l := r.Intn(5) + for i := 0; i < l; i++ { + wire := r.Intn(4) + if wire == 3 { + wire = 5 } - } else if this.Principal != nil { - return false - } else if that1.Principal != nil { - return false + fieldNumber := maxFieldNumber + r.Intn(100) + data = randFieldMesos(data, r, fieldNumber, wire) } - if this.WebuiUrl != nil && that1.WebuiUrl != nil { - if *this.WebuiUrl != *that1.WebuiUrl { - return false + return data +} +func randFieldMesos(data []byte, r randyMesos, fieldNumber int, wire int) []byte { + key := uint32(fieldNumber)<<3 | uint32(wire) + switch wire { + case 0: + data = encodeVarintPopulateMesos(data, uint64(key)) + v241 := r.Int63() + if r.Intn(2) == 0 { + v241 *= -1 } - } else if this.WebuiUrl != nil { - return false - } else if that1.WebuiUrl != nil { - return false + data = encodeVarintPopulateMesos(data, uint64(v241)) + case 1: + data = encodeVarintPopulateMesos(data, uint64(key)) + data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) + case 2: + data = encodeVarintPopulateMesos(data, uint64(key)) + ll := r.Intn(100) + data = encodeVarintPopulateMesos(data, uint64(ll)) + for j := 0; j < ll; j++ { + data = append(data, byte(r.Intn(256))) + } + default: + data = encodeVarintPopulateMesos(data, uint64(key)) + data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) + } + return data +} +func encodeVarintPopulateMesos(data []byte, v uint64) []byte { + for v >= 1<<7 { + data = append(data, uint8(uint64(v)&0x7f|0x80)) + v >>= 7 + } + data = append(data, uint8(v)) + return data +} +func (m *FrameworkID) Size() (n int) { + var l int + _ = l + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *HealthCheck) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") - } - that1, ok := that.(*HealthCheck) - if !ok { - return fmt3.Errorf("that is not of type *HealthCheck") +func (m *OfferID) Size() (n int) { + var l int + _ = l + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *HealthCheck but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *HealthCheckbut is not nil && this == nil") + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.Http.Equal(that1.Http) { - return fmt3.Errorf("Http this(%v) Not Equal that(%v)", this.Http, that1.Http) + return n +} + +func (m *SlaveID) Size() (n int) { + var l int + _ = l + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) } - if this.DelaySeconds != nil && that1.DelaySeconds != nil { - if *this.DelaySeconds != *that1.DelaySeconds { - return fmt3.Errorf("DelaySeconds this(%v) Not Equal that(%v)", *this.DelaySeconds, *that1.DelaySeconds) - } - } else if this.DelaySeconds != nil { - return fmt3.Errorf("this.DelaySeconds == nil && that.DelaySeconds != nil") - } else if that1.DelaySeconds != nil { - return fmt3.Errorf("DelaySeconds this(%v) Not Equal that(%v)", this.DelaySeconds, that1.DelaySeconds) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.IntervalSeconds != nil && that1.IntervalSeconds != nil { - if *this.IntervalSeconds != *that1.IntervalSeconds { - return fmt3.Errorf("IntervalSeconds this(%v) Not Equal that(%v)", *this.IntervalSeconds, *that1.IntervalSeconds) - } - } else if this.IntervalSeconds != nil { - return fmt3.Errorf("this.IntervalSeconds == nil && that.IntervalSeconds != nil") - } else if that1.IntervalSeconds != nil { - return fmt3.Errorf("IntervalSeconds this(%v) Not Equal that(%v)", this.IntervalSeconds, that1.IntervalSeconds) + return n +} + +func (m *TaskID) Size() (n int) { + var l int + _ = l + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) } - if this.TimeoutSeconds != nil && that1.TimeoutSeconds != nil { - if *this.TimeoutSeconds != *that1.TimeoutSeconds { - return fmt3.Errorf("TimeoutSeconds this(%v) Not Equal that(%v)", *this.TimeoutSeconds, *that1.TimeoutSeconds) - } - } else if this.TimeoutSeconds != nil { - return fmt3.Errorf("this.TimeoutSeconds == nil && that.TimeoutSeconds != nil") - } else if that1.TimeoutSeconds != nil { - return fmt3.Errorf("TimeoutSeconds this(%v) Not Equal that(%v)", this.TimeoutSeconds, that1.TimeoutSeconds) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.ConsecutiveFailures != nil && that1.ConsecutiveFailures != nil { - if *this.ConsecutiveFailures != *that1.ConsecutiveFailures { - return fmt3.Errorf("ConsecutiveFailures this(%v) Not Equal that(%v)", *this.ConsecutiveFailures, *that1.ConsecutiveFailures) - } - } else if this.ConsecutiveFailures != nil { - return fmt3.Errorf("this.ConsecutiveFailures == nil && that.ConsecutiveFailures != nil") - } else if that1.ConsecutiveFailures != nil { - return fmt3.Errorf("ConsecutiveFailures this(%v) Not Equal that(%v)", this.ConsecutiveFailures, that1.ConsecutiveFailures) + return n +} + +func (m *ExecutorID) Size() (n int) { + var l int + _ = l + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) } - if this.GracePeriodSeconds != nil && that1.GracePeriodSeconds != nil { - if *this.GracePeriodSeconds != *that1.GracePeriodSeconds { - return fmt3.Errorf("GracePeriodSeconds this(%v) Not Equal that(%v)", *this.GracePeriodSeconds, *that1.GracePeriodSeconds) - } - } else if this.GracePeriodSeconds != nil { - return fmt3.Errorf("this.GracePeriodSeconds == nil && that.GracePeriodSeconds != nil") - } else if that1.GracePeriodSeconds != nil { - return fmt3.Errorf("GracePeriodSeconds this(%v) Not Equal that(%v)", this.GracePeriodSeconds, that1.GracePeriodSeconds) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.Command.Equal(that1.Command) { - return fmt3.Errorf("Command this(%v) Not Equal that(%v)", this.Command, that1.Command) + return n +} + +func (m *ContainerID) Size() (n int) { + var l int + _ = l + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *HealthCheck) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - that1, ok := that.(*HealthCheck) - if !ok { - return false +func (m *FrameworkInfo) Size() (n int) { + var l int + _ = l + if m.User != nil { + l = len(*m.User) + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovMesos(uint64(l)) } - if !this.Http.Equal(that1.Http) { - return false + if m.Id != nil { + l = m.Id.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.DelaySeconds != nil && that1.DelaySeconds != nil { - if *this.DelaySeconds != *that1.DelaySeconds { - return false - } - } else if this.DelaySeconds != nil { - return false - } else if that1.DelaySeconds != nil { - return false + if m.FailoverTimeout != nil { + n += 9 } - if this.IntervalSeconds != nil && that1.IntervalSeconds != nil { - if *this.IntervalSeconds != *that1.IntervalSeconds { - return false - } - } else if this.IntervalSeconds != nil { - return false - } else if that1.IntervalSeconds != nil { - return false + if m.Checkpoint != nil { + n += 2 } - if this.TimeoutSeconds != nil && that1.TimeoutSeconds != nil { - if *this.TimeoutSeconds != *that1.TimeoutSeconds { - return false - } - } else if this.TimeoutSeconds != nil { - return false - } else if that1.TimeoutSeconds != nil { - return false + if m.Role != nil { + l = len(*m.Role) + n += 1 + l + sovMesos(uint64(l)) } - if this.ConsecutiveFailures != nil && that1.ConsecutiveFailures != nil { - if *this.ConsecutiveFailures != *that1.ConsecutiveFailures { - return false - } - } else if this.ConsecutiveFailures != nil { - return false - } else if that1.ConsecutiveFailures != nil { - return false + if m.Hostname != nil { + l = len(*m.Hostname) + n += 1 + l + sovMesos(uint64(l)) } - if this.GracePeriodSeconds != nil && that1.GracePeriodSeconds != nil { - if *this.GracePeriodSeconds != *that1.GracePeriodSeconds { - return false - } - } else if this.GracePeriodSeconds != nil { - return false - } else if that1.GracePeriodSeconds != nil { - return false + if m.Principal != nil { + l = len(*m.Principal) + n += 1 + l + sovMesos(uint64(l)) } - if !this.Command.Equal(that1.Command) { - return false + if m.WebuiUrl != nil { + l = len(*m.WebuiUrl) + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if len(m.Capabilities) > 0 { + for _, e := range m.Capabilities { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) + } } - return true + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n } -func (this *HealthCheck_HTTP) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + +func (m *FrameworkInfo_Capability) Size() (n int) { + var l int + _ = l + if m.Type != nil { + n += 1 + sovMesos(uint64(*m.Type)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } + return n +} - that1, ok := that.(*HealthCheck_HTTP) - if !ok { - return fmt3.Errorf("that is not of type *HealthCheck_HTTP") +func (m *HealthCheck) Size() (n int) { + var l int + _ = l + if m.Http != nil { + l = m.Http.Size() + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *HealthCheck_HTTP but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *HealthCheck_HTTPbut is not nil && this == nil") + if m.DelaySeconds != nil { + n += 9 } - if this.Port != nil && that1.Port != nil { - if *this.Port != *that1.Port { - return fmt3.Errorf("Port this(%v) Not Equal that(%v)", *this.Port, *that1.Port) - } - } else if this.Port != nil { - return fmt3.Errorf("this.Port == nil && that.Port != nil") - } else if that1.Port != nil { - return fmt3.Errorf("Port this(%v) Not Equal that(%v)", this.Port, that1.Port) + if m.IntervalSeconds != nil { + n += 9 + } + if m.TimeoutSeconds != nil { + n += 9 + } + if m.ConsecutiveFailures != nil { + n += 1 + sovMesos(uint64(*m.ConsecutiveFailures)) + } + if m.GracePeriodSeconds != nil { + n += 9 + } + if m.Command != nil { + l = m.Command.Size() + n += 1 + l + sovMesos(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.Path != nil && that1.Path != nil { - if *this.Path != *that1.Path { - return fmt3.Errorf("Path this(%v) Not Equal that(%v)", *this.Path, *that1.Path) - } - } else if this.Path != nil { - return fmt3.Errorf("this.Path == nil && that.Path != nil") - } else if that1.Path != nil { - return fmt3.Errorf("Path this(%v) Not Equal that(%v)", this.Path, that1.Path) + return n +} + +func (m *HealthCheck_HTTP) Size() (n int) { + var l int + _ = l + if m.Port != nil { + n += 1 + sovMesos(uint64(*m.Port)) } - if len(this.Statuses) != len(that1.Statuses) { - return fmt3.Errorf("Statuses this(%v) Not Equal that(%v)", len(this.Statuses), len(that1.Statuses)) + if m.Path != nil { + l = len(*m.Path) + n += 1 + l + sovMesos(uint64(l)) } - for i := range this.Statuses { - if this.Statuses[i] != that1.Statuses[i] { - return fmt3.Errorf("Statuses this[%v](%v) Not Equal that[%v](%v)", i, this.Statuses[i], i, that1.Statuses[i]) + if len(m.Statuses) > 0 { + for _, e := range m.Statuses { + n += 1 + sovMesos(uint64(e)) } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *HealthCheck_HTTP) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true + +func (m *CommandInfo) Size() (n int) { + var l int + _ = l + if len(m.Uris) > 0 { + for _, e := range m.Uris { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - return false } - - that1, ok := that.(*HealthCheck_HTTP) - if !ok { - return false + if m.Environment != nil { + l = m.Environment.Size() + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) } - if this.Port != nil && that1.Port != nil { - if *this.Port != *that1.Port { - return false - } - } else if this.Port != nil { - return false - } else if that1.Port != nil { - return false + if m.Container != nil { + l = m.Container.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Path != nil && that1.Path != nil { - if *this.Path != *that1.Path { - return false - } - } else if this.Path != nil { - return false - } else if that1.Path != nil { - return false + if m.User != nil { + l = len(*m.User) + n += 1 + l + sovMesos(uint64(l)) } - if len(this.Statuses) != len(that1.Statuses) { - return false + if m.Shell != nil { + n += 2 } - for i := range this.Statuses { - if this.Statuses[i] != that1.Statuses[i] { - return false + if len(m.Arguments) > 0 { + for _, s := range m.Arguments { + l = len(s) + n += 1 + l + sovMesos(uint64(l)) } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *CommandInfo) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") - } - that1, ok := that.(*CommandInfo) - if !ok { - return fmt3.Errorf("that is not of type *CommandInfo") +func (m *CommandInfo_URI) Size() (n int) { + var l int + _ = l + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *CommandInfo but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *CommandInfobut is not nil && this == nil") + if m.Executable != nil { + n += 2 } - if !this.Container.Equal(that1.Container) { - return fmt3.Errorf("Container this(%v) Not Equal that(%v)", this.Container, that1.Container) + if m.Extract != nil { + n += 2 } - if len(this.Uris) != len(that1.Uris) { - return fmt3.Errorf("Uris this(%v) Not Equal that(%v)", len(this.Uris), len(that1.Uris)) + if m.Cache != nil { + n += 2 } - for i := range this.Uris { - if !this.Uris[i].Equal(that1.Uris[i]) { - return fmt3.Errorf("Uris this[%v](%v) Not Equal that[%v](%v)", i, this.Uris[i], i, that1.Uris[i]) - } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.Environment.Equal(that1.Environment) { - return fmt3.Errorf("Environment this(%v) Not Equal that(%v)", this.Environment, that1.Environment) + return n +} + +func (m *CommandInfo_ContainerInfo) Size() (n int) { + var l int + _ = l + if m.Image != nil { + l = len(*m.Image) + n += 1 + l + sovMesos(uint64(l)) } - if this.Shell != nil && that1.Shell != nil { - if *this.Shell != *that1.Shell { - return fmt3.Errorf("Shell this(%v) Not Equal that(%v)", *this.Shell, *that1.Shell) + if len(m.Options) > 0 { + for _, s := range m.Options { + l = len(s) + n += 1 + l + sovMesos(uint64(l)) } - } else if this.Shell != nil { - return fmt3.Errorf("this.Shell == nil && that.Shell != nil") - } else if that1.Shell != nil { - return fmt3.Errorf("Shell this(%v) Not Equal that(%v)", this.Shell, that1.Shell) } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) - } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if len(this.Arguments) != len(that1.Arguments) { - return fmt3.Errorf("Arguments this(%v) Not Equal that(%v)", len(this.Arguments), len(that1.Arguments)) + return n +} + +func (m *ExecutorInfo) Size() (n int) { + var l int + _ = l + if m.ExecutorId != nil { + l = m.ExecutorId.Size() + n += 1 + l + sovMesos(uint64(l)) } - for i := range this.Arguments { - if this.Arguments[i] != that1.Arguments[i] { - return fmt3.Errorf("Arguments this[%v](%v) Not Equal that[%v](%v)", i, this.Arguments[i], i, that1.Arguments[i]) - } + if m.Data != nil { + l = len(m.Data) + n += 1 + l + sovMesos(uint64(l)) } - if this.User != nil && that1.User != nil { - if *this.User != *that1.User { - return fmt3.Errorf("User this(%v) Not Equal that(%v)", *this.User, *that1.User) + if len(m.Resources) > 0 { + for _, e := range m.Resources { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.User != nil { - return fmt3.Errorf("this.User == nil && that.User != nil") - } else if that1.User != nil { - return fmt3.Errorf("User this(%v) Not Equal that(%v)", this.User, that1.User) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } - return nil -} -func (this *CommandInfo) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + if m.Command != nil { + l = m.Command.Size() + n += 1 + l + sovMesos(uint64(l)) } - - that1, ok := that.(*CommandInfo) - if !ok { - return false + if m.FrameworkId != nil { + l = m.FrameworkId.Size() + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovMesos(uint64(l)) } - if !this.Container.Equal(that1.Container) { - return false + if m.Source != nil { + l = len(*m.Source) + n += 1 + l + sovMesos(uint64(l)) } - if len(this.Uris) != len(that1.Uris) { - return false + if m.Container != nil { + l = m.Container.Size() + n += 1 + l + sovMesos(uint64(l)) } - for i := range this.Uris { - if !this.Uris[i].Equal(that1.Uris[i]) { - return false - } + if m.Discovery != nil { + l = m.Discovery.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !this.Environment.Equal(that1.Environment) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.Shell != nil && that1.Shell != nil { - if *this.Shell != *that1.Shell { - return false - } - } else if this.Shell != nil { - return false - } else if that1.Shell != nil { - return false + return n +} + +func (m *MasterInfo) Size() (n int) { + var l int + _ = l + if m.Id != nil { + l = len(*m.Id) + n += 1 + l + sovMesos(uint64(l)) } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false - } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false + if m.Ip != nil { + n += 1 + sovMesos(uint64(*m.Ip)) } - if len(this.Arguments) != len(that1.Arguments) { - return false + if m.Port != nil { + n += 1 + sovMesos(uint64(*m.Port)) } - for i := range this.Arguments { - if this.Arguments[i] != that1.Arguments[i] { - return false - } + if m.Pid != nil { + l = len(*m.Pid) + n += 1 + l + sovMesos(uint64(l)) } - if this.User != nil && that1.User != nil { - if *this.User != *that1.User { - return false - } - } else if this.User != nil { - return false - } else if that1.User != nil { - return false + if m.Hostname != nil { + l = len(*m.Hostname) + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.Version != nil { + l = len(*m.Version) + n += 1 + l + sovMesos(uint64(l)) } - return true -} -func (this *CommandInfo_URI) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } + return n +} - that1, ok := that.(*CommandInfo_URI) - if !ok { - return fmt3.Errorf("that is not of type *CommandInfo_URI") +func (m *SlaveInfo) Size() (n int) { + var l int + _ = l + if m.Hostname != nil { + l = len(*m.Hostname) + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return nil + if len(m.Resources) > 0 { + for _, e := range m.Resources { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - return fmt3.Errorf("that is type *CommandInfo_URI but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *CommandInfo_URIbut is not nil && this == nil") } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + if len(m.Attributes) > 0 { + for _, e := range m.Attributes { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) } - if this.Executable != nil && that1.Executable != nil { - if *this.Executable != *that1.Executable { - return fmt3.Errorf("Executable this(%v) Not Equal that(%v)", *this.Executable, *that1.Executable) - } - } else if this.Executable != nil { - return fmt3.Errorf("this.Executable == nil && that.Executable != nil") - } else if that1.Executable != nil { - return fmt3.Errorf("Executable this(%v) Not Equal that(%v)", this.Executable, that1.Executable) + if m.Id != nil { + l = m.Id.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Extract != nil && that1.Extract != nil { - if *this.Extract != *that1.Extract { - return fmt3.Errorf("Extract this(%v) Not Equal that(%v)", *this.Extract, *that1.Extract) - } - } else if this.Extract != nil { - return fmt3.Errorf("this.Extract == nil && that.Extract != nil") - } else if that1.Extract != nil { - return fmt3.Errorf("Extract this(%v) Not Equal that(%v)", this.Extract, that1.Extract) + if m.Checkpoint != nil { + n += 2 } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.Port != nil { + n += 1 + sovMesos(uint64(*m.Port)) } - return nil -} -func (this *CommandInfo_URI) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } + return n +} - that1, ok := that.(*CommandInfo_URI) - if !ok { - return false +func (m *Value) Size() (n int) { + var l int + _ = l + if m.Type != nil { + n += 1 + sovMesos(uint64(*m.Type)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.Scalar != nil { + l = m.Scalar.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false - } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false + if m.Ranges != nil { + l = m.Ranges.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Executable != nil && that1.Executable != nil { - if *this.Executable != *that1.Executable { - return false - } - } else if this.Executable != nil { - return false - } else if that1.Executable != nil { - return false + if m.Set != nil { + l = m.Set.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Extract != nil && that1.Extract != nil { - if *this.Extract != *that1.Extract { - return false - } - } else if this.Extract != nil { - return false - } else if that1.Extract != nil { - return false + if m.Text != nil { + l = m.Text.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *CommandInfo_ContainerInfo) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + +func (m *Value_Scalar) Size() (n int) { + var l int + _ = l + if m.Value != nil { + n += 9 + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } + return n +} - that1, ok := that.(*CommandInfo_ContainerInfo) - if !ok { - return fmt3.Errorf("that is not of type *CommandInfo_ContainerInfo") +func (m *Value_Range) Size() (n int) { + var l int + _ = l + if m.Begin != nil { + n += 1 + sovMesos(uint64(*m.Begin)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *CommandInfo_ContainerInfo but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *CommandInfo_ContainerInfobut is not nil && this == nil") + if m.End != nil { + n += 1 + sovMesos(uint64(*m.End)) } - if this.Image != nil && that1.Image != nil { - if *this.Image != *that1.Image { - return fmt3.Errorf("Image this(%v) Not Equal that(%v)", *this.Image, *that1.Image) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Value_Ranges) Size() (n int) { + var l int + _ = l + if len(m.Range) > 0 { + for _, e := range m.Range { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.Image != nil { - return fmt3.Errorf("this.Image == nil && that.Image != nil") - } else if that1.Image != nil { - return fmt3.Errorf("Image this(%v) Not Equal that(%v)", this.Image, that1.Image) } - if len(this.Options) != len(that1.Options) { - return fmt3.Errorf("Options this(%v) Not Equal that(%v)", len(this.Options), len(that1.Options)) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - for i := range this.Options { - if this.Options[i] != that1.Options[i] { - return fmt3.Errorf("Options this[%v](%v) Not Equal that[%v](%v)", i, this.Options[i], i, that1.Options[i]) + return n +} + +func (m *Value_Set) Size() (n int) { + var l int + _ = l + if len(m.Item) > 0 { + for _, s := range m.Item { + l = len(s) + n += 1 + l + sovMesos(uint64(l)) } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *CommandInfo_ContainerInfo) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + +func (m *Value_Text) Size() (n int) { + var l int + _ = l + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } + return n +} - that1, ok := that.(*CommandInfo_ContainerInfo) - if !ok { - return false +func (m *Attribute) Size() (n int) { + var l int + _ = l + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.Type != nil { + n += 1 + sovMesos(uint64(*m.Type)) } - if this.Image != nil && that1.Image != nil { - if *this.Image != *that1.Image { - return false - } - } else if this.Image != nil { - return false - } else if that1.Image != nil { - return false + if m.Scalar != nil { + l = m.Scalar.Size() + n += 1 + l + sovMesos(uint64(l)) } - if len(this.Options) != len(that1.Options) { - return false + if m.Ranges != nil { + l = m.Ranges.Size() + n += 1 + l + sovMesos(uint64(l)) } - for i := range this.Options { - if this.Options[i] != that1.Options[i] { - return false - } + if m.Text != nil { + l = m.Text.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.Set != nil { + l = m.Set.Size() + n += 1 + l + sovMesos(uint64(l)) } - return true -} -func (this *ExecutorInfo) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } + return n +} - that1, ok := that.(*ExecutorInfo) - if !ok { - return fmt3.Errorf("that is not of type *ExecutorInfo") +func (m *Resource) Size() (n int) { + var l int + _ = l + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *ExecutorInfo but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ExecutorInfobut is not nil && this == nil") + if m.Type != nil { + n += 1 + sovMesos(uint64(*m.Type)) } - if !this.ExecutorId.Equal(that1.ExecutorId) { - return fmt3.Errorf("ExecutorId this(%v) Not Equal that(%v)", this.ExecutorId, that1.ExecutorId) + if m.Scalar != nil { + l = m.Scalar.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !this.FrameworkId.Equal(that1.FrameworkId) { - return fmt3.Errorf("FrameworkId this(%v) Not Equal that(%v)", this.FrameworkId, that1.FrameworkId) + if m.Ranges != nil { + l = m.Ranges.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !this.Command.Equal(that1.Command) { - return fmt3.Errorf("Command this(%v) Not Equal that(%v)", this.Command, that1.Command) + if m.Set != nil { + l = m.Set.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !this.Container.Equal(that1.Container) { - return fmt3.Errorf("Container this(%v) Not Equal that(%v)", this.Container, that1.Container) + if m.Role != nil { + l = len(*m.Role) + n += 1 + l + sovMesos(uint64(l)) } - if len(this.Resources) != len(that1.Resources) { - return fmt3.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) + if m.Disk != nil { + l = m.Disk.Size() + n += 1 + l + sovMesos(uint64(l)) } - for i := range this.Resources { - if !this.Resources[i].Equal(that1.Resources[i]) { - return fmt3.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) - } + if m.Reservation != nil { + l = m.Reservation.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) - } - } else if this.Name != nil { - return fmt3.Errorf("this.Name == nil && that.Name != nil") - } else if that1.Name != nil { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + if m.Revocable != nil { + l = m.Revocable.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Source != nil && that1.Source != nil { - if *this.Source != *that1.Source { - return fmt3.Errorf("Source this(%v) Not Equal that(%v)", *this.Source, *that1.Source) - } - } else if this.Source != nil { - return fmt3.Errorf("this.Source == nil && that.Source != nil") - } else if that1.Source != nil { - return fmt3.Errorf("Source this(%v) Not Equal that(%v)", this.Source, that1.Source) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !bytes.Equal(this.Data, that1.Data) { - return fmt3.Errorf("Data this(%v) Not Equal that(%v)", this.Data, that1.Data) + return n +} + +func (m *Resource_ReservationInfo) Size() (n int) { + var l int + _ = l + if m.Principal != nil { + l = len(*m.Principal) + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *ExecutorInfo) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + +func (m *Resource_DiskInfo) Size() (n int) { + var l int + _ = l + if m.Persistence != nil { + l = m.Persistence.Size() + n += 1 + l + sovMesos(uint64(l)) + } + if m.Volume != nil { + l = m.Volume.Size() + n += 1 + l + sovMesos(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } + return n +} - that1, ok := that.(*ExecutorInfo) - if !ok { - return false +func (m *Resource_DiskInfo_Persistence) Size() (n int) { + var l int + _ = l + if m.Id != nil { + l = len(*m.Id) + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.ExecutorId.Equal(that1.ExecutorId) { - return false + return n +} + +func (m *Resource_RevocableInfo) Size() (n int) { + var l int + _ = l + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.FrameworkId.Equal(that1.FrameworkId) { - return false + return n +} + +func (m *TrafficControlStatistics) Size() (n int) { + var l int + _ = l + if m.Id != nil { + l = len(*m.Id) + n += 1 + l + sovMesos(uint64(l)) } - if !this.Command.Equal(that1.Command) { - return false + if m.Backlog != nil { + n += 1 + sovMesos(uint64(*m.Backlog)) } - if !this.Container.Equal(that1.Container) { - return false + if m.Bytes != nil { + n += 1 + sovMesos(uint64(*m.Bytes)) } - if len(this.Resources) != len(that1.Resources) { - return false + if m.Drops != nil { + n += 1 + sovMesos(uint64(*m.Drops)) } - for i := range this.Resources { - if !this.Resources[i].Equal(that1.Resources[i]) { - return false - } + if m.Overlimits != nil { + n += 1 + sovMesos(uint64(*m.Overlimits)) } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return false - } - } else if this.Name != nil { - return false - } else if that1.Name != nil { - return false + if m.Packets != nil { + n += 1 + sovMesos(uint64(*m.Packets)) } - if this.Source != nil && that1.Source != nil { - if *this.Source != *that1.Source { - return false - } - } else if this.Source != nil { - return false - } else if that1.Source != nil { - return false + if m.Qlen != nil { + n += 1 + sovMesos(uint64(*m.Qlen)) } - if !bytes.Equal(this.Data, that1.Data) { - return false + if m.Ratebps != nil { + n += 1 + sovMesos(uint64(*m.Ratebps)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.Ratepps != nil { + n += 1 + sovMesos(uint64(*m.Ratepps)) } - return true -} -func (this *MasterInfo) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if m.Requeues != nil { + n += 1 + sovMesos(uint64(*m.Requeues)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } + return n +} - that1, ok := that.(*MasterInfo) - if !ok { - return fmt3.Errorf("that is not of type *MasterInfo") +func (m *ResourceStatistics) Size() (n int) { + var l int + _ = l + if m.Timestamp != nil { + n += 9 } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *MasterInfo but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *MasterInfobut is not nil && this == nil") + if m.CpusUserTimeSecs != nil { + n += 9 } - if this.Id != nil && that1.Id != nil { - if *this.Id != *that1.Id { - return fmt3.Errorf("Id this(%v) Not Equal that(%v)", *this.Id, *that1.Id) - } - } else if this.Id != nil { - return fmt3.Errorf("this.Id == nil && that.Id != nil") - } else if that1.Id != nil { - return fmt3.Errorf("Id this(%v) Not Equal that(%v)", this.Id, that1.Id) + if m.CpusSystemTimeSecs != nil { + n += 9 } - if this.Ip != nil && that1.Ip != nil { - if *this.Ip != *that1.Ip { - return fmt3.Errorf("Ip this(%v) Not Equal that(%v)", *this.Ip, *that1.Ip) - } - } else if this.Ip != nil { - return fmt3.Errorf("this.Ip == nil && that.Ip != nil") - } else if that1.Ip != nil { - return fmt3.Errorf("Ip this(%v) Not Equal that(%v)", this.Ip, that1.Ip) + if m.CpusLimit != nil { + n += 9 } - if this.Port != nil && that1.Port != nil { - if *this.Port != *that1.Port { - return fmt3.Errorf("Port this(%v) Not Equal that(%v)", *this.Port, *that1.Port) - } - } else if this.Port != nil { - return fmt3.Errorf("this.Port == nil && that.Port != nil") - } else if that1.Port != nil { - return fmt3.Errorf("Port this(%v) Not Equal that(%v)", this.Port, that1.Port) + if m.MemRssBytes != nil { + n += 1 + sovMesos(uint64(*m.MemRssBytes)) } - if this.Pid != nil && that1.Pid != nil { - if *this.Pid != *that1.Pid { - return fmt3.Errorf("Pid this(%v) Not Equal that(%v)", *this.Pid, *that1.Pid) - } - } else if this.Pid != nil { - return fmt3.Errorf("this.Pid == nil && that.Pid != nil") - } else if that1.Pid != nil { - return fmt3.Errorf("Pid this(%v) Not Equal that(%v)", this.Pid, that1.Pid) + if m.MemLimitBytes != nil { + n += 1 + sovMesos(uint64(*m.MemLimitBytes)) } - if this.Hostname != nil && that1.Hostname != nil { - if *this.Hostname != *that1.Hostname { - return fmt3.Errorf("Hostname this(%v) Not Equal that(%v)", *this.Hostname, *that1.Hostname) - } - } else if this.Hostname != nil { - return fmt3.Errorf("this.Hostname == nil && that.Hostname != nil") - } else if that1.Hostname != nil { - return fmt3.Errorf("Hostname this(%v) Not Equal that(%v)", this.Hostname, that1.Hostname) + if m.CpusNrPeriods != nil { + n += 1 + sovMesos(uint64(*m.CpusNrPeriods)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.CpusNrThrottled != nil { + n += 1 + sovMesos(uint64(*m.CpusNrThrottled)) } - return nil -} -func (this *MasterInfo) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + if m.CpusThrottledTimeSecs != nil { + n += 9 + } + if m.MemFileBytes != nil { + n += 1 + sovMesos(uint64(*m.MemFileBytes)) + } + if m.MemAnonBytes != nil { + n += 1 + sovMesos(uint64(*m.MemAnonBytes)) } - - that1, ok := that.(*MasterInfo) - if !ok { - return false + if m.MemMappedFileBytes != nil { + n += 1 + sovMesos(uint64(*m.MemMappedFileBytes)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.Perf != nil { + l = m.Perf.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Id != nil && that1.Id != nil { - if *this.Id != *that1.Id { - return false - } - } else if this.Id != nil { - return false - } else if that1.Id != nil { - return false + if m.NetRxPackets != nil { + n += 1 + sovMesos(uint64(*m.NetRxPackets)) } - if this.Ip != nil && that1.Ip != nil { - if *this.Ip != *that1.Ip { - return false - } - } else if this.Ip != nil { - return false - } else if that1.Ip != nil { - return false + if m.NetRxBytes != nil { + n += 1 + sovMesos(uint64(*m.NetRxBytes)) } - if this.Port != nil && that1.Port != nil { - if *this.Port != *that1.Port { - return false - } - } else if this.Port != nil { - return false - } else if that1.Port != nil { - return false + if m.NetRxErrors != nil { + n += 2 + sovMesos(uint64(*m.NetRxErrors)) } - if this.Pid != nil && that1.Pid != nil { - if *this.Pid != *that1.Pid { - return false - } - } else if this.Pid != nil { - return false - } else if that1.Pid != nil { - return false + if m.NetRxDropped != nil { + n += 2 + sovMesos(uint64(*m.NetRxDropped)) } - if this.Hostname != nil && that1.Hostname != nil { - if *this.Hostname != *that1.Hostname { - return false - } - } else if this.Hostname != nil { - return false - } else if that1.Hostname != nil { - return false + if m.NetTxPackets != nil { + n += 2 + sovMesos(uint64(*m.NetTxPackets)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.NetTxBytes != nil { + n += 2 + sovMesos(uint64(*m.NetTxBytes)) } - return true -} -func (this *SlaveInfo) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if m.NetTxErrors != nil { + n += 2 + sovMesos(uint64(*m.NetTxErrors)) } - - that1, ok := that.(*SlaveInfo) - if !ok { - return fmt3.Errorf("that is not of type *SlaveInfo") + if m.NetTxDropped != nil { + n += 2 + sovMesos(uint64(*m.NetTxDropped)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *SlaveInfo but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *SlaveInfobut is not nil && this == nil") + if m.NetTcpRttMicrosecsP50 != nil { + n += 10 } - if this.Hostname != nil && that1.Hostname != nil { - if *this.Hostname != *that1.Hostname { - return fmt3.Errorf("Hostname this(%v) Not Equal that(%v)", *this.Hostname, *that1.Hostname) - } - } else if this.Hostname != nil { - return fmt3.Errorf("this.Hostname == nil && that.Hostname != nil") - } else if that1.Hostname != nil { - return fmt3.Errorf("Hostname this(%v) Not Equal that(%v)", this.Hostname, that1.Hostname) + if m.NetTcpRttMicrosecsP90 != nil { + n += 10 } - if this.Port != nil && that1.Port != nil { - if *this.Port != *that1.Port { - return fmt3.Errorf("Port this(%v) Not Equal that(%v)", *this.Port, *that1.Port) - } - } else if this.Port != nil { - return fmt3.Errorf("this.Port == nil && that.Port != nil") - } else if that1.Port != nil { - return fmt3.Errorf("Port this(%v) Not Equal that(%v)", this.Port, that1.Port) + if m.NetTcpRttMicrosecsP95 != nil { + n += 10 } - if len(this.Resources) != len(that1.Resources) { - return fmt3.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) + if m.NetTcpRttMicrosecsP99 != nil { + n += 10 } - for i := range this.Resources { - if !this.Resources[i].Equal(that1.Resources[i]) { - return fmt3.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) - } + if m.DiskLimitBytes != nil { + n += 2 + sovMesos(uint64(*m.DiskLimitBytes)) } - if len(this.Attributes) != len(that1.Attributes) { - return fmt3.Errorf("Attributes this(%v) Not Equal that(%v)", len(this.Attributes), len(that1.Attributes)) + if m.DiskUsedBytes != nil { + n += 2 + sovMesos(uint64(*m.DiskUsedBytes)) } - for i := range this.Attributes { - if !this.Attributes[i].Equal(that1.Attributes[i]) { - return fmt3.Errorf("Attributes this[%v](%v) Not Equal that[%v](%v)", i, this.Attributes[i], i, that1.Attributes[i]) - } + if m.NetTcpActiveConnections != nil { + n += 10 } - if !this.Id.Equal(that1.Id) { - return fmt3.Errorf("Id this(%v) Not Equal that(%v)", this.Id, that1.Id) + if m.NetTcpTimeWaitConnections != nil { + n += 10 } - if this.Checkpoint != nil && that1.Checkpoint != nil { - if *this.Checkpoint != *that1.Checkpoint { - return fmt3.Errorf("Checkpoint this(%v) Not Equal that(%v)", *this.Checkpoint, *that1.Checkpoint) - } - } else if this.Checkpoint != nil { - return fmt3.Errorf("this.Checkpoint == nil && that.Checkpoint != nil") - } else if that1.Checkpoint != nil { - return fmt3.Errorf("Checkpoint this(%v) Not Equal that(%v)", this.Checkpoint, that1.Checkpoint) + if m.Processes != nil { + n += 2 + sovMesos(uint64(*m.Processes)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.Threads != nil { + n += 2 + sovMesos(uint64(*m.Threads)) } - return nil -} -func (this *SlaveInfo) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + if m.MemLowPressureCounter != nil { + n += 2 + sovMesos(uint64(*m.MemLowPressureCounter)) } - - that1, ok := that.(*SlaveInfo) - if !ok { - return false + if m.MemMediumPressureCounter != nil { + n += 2 + sovMesos(uint64(*m.MemMediumPressureCounter)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.MemCriticalPressureCounter != nil { + n += 2 + sovMesos(uint64(*m.MemCriticalPressureCounter)) } - if this.Hostname != nil && that1.Hostname != nil { - if *this.Hostname != *that1.Hostname { - return false + if len(m.NetTrafficControlStatistics) > 0 { + for _, e := range m.NetTrafficControlStatistics { + l = e.Size() + n += 2 + l + sovMesos(uint64(l)) } - } else if this.Hostname != nil { - return false - } else if that1.Hostname != nil { - return false } - if this.Port != nil && that1.Port != nil { - if *this.Port != *that1.Port { - return false - } - } else if this.Port != nil { - return false - } else if that1.Port != nil { - return false + if m.MemTotalBytes != nil { + n += 2 + sovMesos(uint64(*m.MemTotalBytes)) } - if len(this.Resources) != len(that1.Resources) { - return false + if m.MemTotalMemswBytes != nil { + n += 2 + sovMesos(uint64(*m.MemTotalMemswBytes)) } - for i := range this.Resources { - if !this.Resources[i].Equal(that1.Resources[i]) { - return false - } + if m.MemSoftLimitBytes != nil { + n += 2 + sovMesos(uint64(*m.MemSoftLimitBytes)) } - if len(this.Attributes) != len(that1.Attributes) { - return false + if m.MemCacheBytes != nil { + n += 2 + sovMesos(uint64(*m.MemCacheBytes)) } - for i := range this.Attributes { - if !this.Attributes[i].Equal(that1.Attributes[i]) { - return false - } + if m.MemSwapBytes != nil { + n += 2 + sovMesos(uint64(*m.MemSwapBytes)) } - if !this.Id.Equal(that1.Id) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.Checkpoint != nil && that1.Checkpoint != nil { - if *this.Checkpoint != *that1.Checkpoint { - return false + return n +} + +func (m *ResourceUsage) Size() (n int) { + var l int + _ = l + if len(m.Executors) > 0 { + for _, e := range m.Executors { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.Checkpoint != nil { - return false - } else if that1.Checkpoint != nil { - return false } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *Value) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") - } - that1, ok := that.(*Value) - if !ok { - return fmt3.Errorf("that is not of type *Value") +func (m *ResourceUsage_Executor) Size() (n int) { + var l int + _ = l + if m.ExecutorInfo != nil { + l = m.ExecutorInfo.Size() + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return nil + if len(m.Allocated) > 0 { + for _, e := range m.Allocated { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - return fmt3.Errorf("that is type *Value but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Valuebut is not nil && this == nil") } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return fmt3.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) - } - } else if this.Type != nil { - return fmt3.Errorf("this.Type == nil && that.Type != nil") - } else if that1.Type != nil { - return fmt3.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + if m.Statistics != nil { + l = m.Statistics.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !this.Scalar.Equal(that1.Scalar) { - return fmt3.Errorf("Scalar this(%v) Not Equal that(%v)", this.Scalar, that1.Scalar) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.Ranges.Equal(that1.Ranges) { - return fmt3.Errorf("Ranges this(%v) Not Equal that(%v)", this.Ranges, that1.Ranges) + return n +} + +func (m *PerfStatistics) Size() (n int) { + var l int + _ = l + if m.Timestamp != nil { + n += 9 } - if !this.Set.Equal(that1.Set) { - return fmt3.Errorf("Set this(%v) Not Equal that(%v)", this.Set, that1.Set) + if m.Duration != nil { + n += 9 } - if !this.Text.Equal(that1.Text) { - return fmt3.Errorf("Text this(%v) Not Equal that(%v)", this.Text, that1.Text) + if m.Cycles != nil { + n += 1 + sovMesos(uint64(*m.Cycles)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.StalledCyclesFrontend != nil { + n += 1 + sovMesos(uint64(*m.StalledCyclesFrontend)) } - return nil -} -func (this *Value) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + if m.StalledCyclesBackend != nil { + n += 1 + sovMesos(uint64(*m.StalledCyclesBackend)) } - - that1, ok := that.(*Value) - if !ok { - return false + if m.Instructions != nil { + n += 1 + sovMesos(uint64(*m.Instructions)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.CacheReferences != nil { + n += 1 + sovMesos(uint64(*m.CacheReferences)) } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return false - } - } else if this.Type != nil { - return false - } else if that1.Type != nil { - return false + if m.CacheMisses != nil { + n += 1 + sovMesos(uint64(*m.CacheMisses)) } - if !this.Scalar.Equal(that1.Scalar) { - return false + if m.Branches != nil { + n += 1 + sovMesos(uint64(*m.Branches)) } - if !this.Ranges.Equal(that1.Ranges) { - return false + if m.BranchMisses != nil { + n += 1 + sovMesos(uint64(*m.BranchMisses)) } - if !this.Set.Equal(that1.Set) { - return false + if m.BusCycles != nil { + n += 1 + sovMesos(uint64(*m.BusCycles)) } - if !this.Text.Equal(that1.Text) { - return false + if m.RefCycles != nil { + n += 1 + sovMesos(uint64(*m.RefCycles)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.CpuClock != nil { + n += 9 } - return true -} -func (this *Value_Scalar) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if m.TaskClock != nil { + n += 9 } - - that1, ok := that.(*Value_Scalar) - if !ok { - return fmt3.Errorf("that is not of type *Value_Scalar") + if m.PageFaults != nil { + n += 1 + sovMesos(uint64(*m.PageFaults)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Value_Scalar but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Value_Scalarbut is not nil && this == nil") + if m.MinorFaults != nil { + n += 2 + sovMesos(uint64(*m.MinorFaults)) } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) - } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + if m.MajorFaults != nil { + n += 2 + sovMesos(uint64(*m.MajorFaults)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.ContextSwitches != nil { + n += 2 + sovMesos(uint64(*m.ContextSwitches)) } - return nil -} -func (this *Value_Scalar) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + if m.CpuMigrations != nil { + n += 2 + sovMesos(uint64(*m.CpuMigrations)) } - - that1, ok := that.(*Value_Scalar) - if !ok { - return false + if m.AlignmentFaults != nil { + n += 2 + sovMesos(uint64(*m.AlignmentFaults)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.EmulationFaults != nil { + n += 2 + sovMesos(uint64(*m.EmulationFaults)) } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false - } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false + if m.L1DcacheLoads != nil { + n += 2 + sovMesos(uint64(*m.L1DcacheLoads)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.L1DcacheLoadMisses != nil { + n += 2 + sovMesos(uint64(*m.L1DcacheLoadMisses)) } - return true -} -func (this *Value_Range) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if m.L1DcacheStores != nil { + n += 2 + sovMesos(uint64(*m.L1DcacheStores)) } - - that1, ok := that.(*Value_Range) - if !ok { - return fmt3.Errorf("that is not of type *Value_Range") + if m.L1DcacheStoreMisses != nil { + n += 2 + sovMesos(uint64(*m.L1DcacheStoreMisses)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Value_Range but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Value_Rangebut is not nil && this == nil") + if m.L1DcachePrefetches != nil { + n += 2 + sovMesos(uint64(*m.L1DcachePrefetches)) } - if this.Begin != nil && that1.Begin != nil { - if *this.Begin != *that1.Begin { - return fmt3.Errorf("Begin this(%v) Not Equal that(%v)", *this.Begin, *that1.Begin) - } - } else if this.Begin != nil { - return fmt3.Errorf("this.Begin == nil && that.Begin != nil") - } else if that1.Begin != nil { - return fmt3.Errorf("Begin this(%v) Not Equal that(%v)", this.Begin, that1.Begin) + if m.L1DcachePrefetchMisses != nil { + n += 2 + sovMesos(uint64(*m.L1DcachePrefetchMisses)) } - if this.End != nil && that1.End != nil { - if *this.End != *that1.End { - return fmt3.Errorf("End this(%v) Not Equal that(%v)", *this.End, *that1.End) - } - } else if this.End != nil { - return fmt3.Errorf("this.End == nil && that.End != nil") - } else if that1.End != nil { - return fmt3.Errorf("End this(%v) Not Equal that(%v)", this.End, that1.End) + if m.L1IcacheLoads != nil { + n += 2 + sovMesos(uint64(*m.L1IcacheLoads)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.L1IcacheLoadMisses != nil { + n += 2 + sovMesos(uint64(*m.L1IcacheLoadMisses)) } - return nil -} -func (this *Value_Range) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + if m.L1IcachePrefetches != nil { + n += 2 + sovMesos(uint64(*m.L1IcachePrefetches)) } - - that1, ok := that.(*Value_Range) - if !ok { - return false + if m.L1IcachePrefetchMisses != nil { + n += 2 + sovMesos(uint64(*m.L1IcachePrefetchMisses)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.LlcLoads != nil { + n += 2 + sovMesos(uint64(*m.LlcLoads)) } - if this.Begin != nil && that1.Begin != nil { - if *this.Begin != *that1.Begin { - return false - } - } else if this.Begin != nil { - return false - } else if that1.Begin != nil { - return false + if m.LlcLoadMisses != nil { + n += 2 + sovMesos(uint64(*m.LlcLoadMisses)) } - if this.End != nil && that1.End != nil { - if *this.End != *that1.End { - return false - } - } else if this.End != nil { - return false - } else if that1.End != nil { - return false + if m.LlcStores != nil { + n += 2 + sovMesos(uint64(*m.LlcStores)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.LlcStoreMisses != nil { + n += 2 + sovMesos(uint64(*m.LlcStoreMisses)) } - return true -} -func (this *Value_Ranges) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if m.LlcPrefetches != nil { + n += 2 + sovMesos(uint64(*m.LlcPrefetches)) } - - that1, ok := that.(*Value_Ranges) - if !ok { - return fmt3.Errorf("that is not of type *Value_Ranges") + if m.LlcPrefetchMisses != nil { + n += 2 + sovMesos(uint64(*m.LlcPrefetchMisses)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Value_Ranges but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Value_Rangesbut is not nil && this == nil") + if m.DtlbLoads != nil { + n += 2 + sovMesos(uint64(*m.DtlbLoads)) } - if len(this.Range) != len(that1.Range) { - return fmt3.Errorf("Range this(%v) Not Equal that(%v)", len(this.Range), len(that1.Range)) + if m.DtlbLoadMisses != nil { + n += 2 + sovMesos(uint64(*m.DtlbLoadMisses)) } - for i := range this.Range { - if !this.Range[i].Equal(that1.Range[i]) { - return fmt3.Errorf("Range this[%v](%v) Not Equal that[%v](%v)", i, this.Range[i], i, that1.Range[i]) - } + if m.DtlbStores != nil { + n += 2 + sovMesos(uint64(*m.DtlbStores)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.DtlbStoreMisses != nil { + n += 2 + sovMesos(uint64(*m.DtlbStoreMisses)) } - return nil -} -func (this *Value_Ranges) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + if m.DtlbPrefetches != nil { + n += 2 + sovMesos(uint64(*m.DtlbPrefetches)) } - - that1, ok := that.(*Value_Ranges) - if !ok { - return false + if m.DtlbPrefetchMisses != nil { + n += 2 + sovMesos(uint64(*m.DtlbPrefetchMisses)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.ItlbLoads != nil { + n += 2 + sovMesos(uint64(*m.ItlbLoads)) + } + if m.ItlbLoadMisses != nil { + n += 2 + sovMesos(uint64(*m.ItlbLoadMisses)) } - if len(this.Range) != len(that1.Range) { - return false + if m.BranchLoads != nil { + n += 2 + sovMesos(uint64(*m.BranchLoads)) } - for i := range this.Range { - if !this.Range[i].Equal(that1.Range[i]) { - return false - } + if m.BranchLoadMisses != nil { + n += 2 + sovMesos(uint64(*m.BranchLoadMisses)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.NodeLoads != nil { + n += 2 + sovMesos(uint64(*m.NodeLoads)) } - return true -} -func (this *Value_Set) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if m.NodeLoadMisses != nil { + n += 2 + sovMesos(uint64(*m.NodeLoadMisses)) } - - that1, ok := that.(*Value_Set) - if !ok { - return fmt3.Errorf("that is not of type *Value_Set") + if m.NodeStores != nil { + n += 2 + sovMesos(uint64(*m.NodeStores)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Value_Set but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Value_Setbut is not nil && this == nil") + if m.NodeStoreMisses != nil { + n += 2 + sovMesos(uint64(*m.NodeStoreMisses)) } - if len(this.Item) != len(that1.Item) { - return fmt3.Errorf("Item this(%v) Not Equal that(%v)", len(this.Item), len(that1.Item)) + if m.NodePrefetches != nil { + n += 2 + sovMesos(uint64(*m.NodePrefetches)) } - for i := range this.Item { - if this.Item[i] != that1.Item[i] { - return fmt3.Errorf("Item this[%v](%v) Not Equal that[%v](%v)", i, this.Item[i], i, that1.Item[i]) - } + if m.NodePrefetchMisses != nil { + n += 2 + sovMesos(uint64(*m.NodePrefetchMisses)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *Value_Set) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - that1, ok := that.(*Value_Set) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if len(this.Item) != len(that1.Item) { - return false +func (m *Request) Size() (n int) { + var l int + _ = l + if m.SlaveId != nil { + l = m.SlaveId.Size() + n += 1 + l + sovMesos(uint64(l)) } - for i := range this.Item { - if this.Item[i] != that1.Item[i] { - return false + if len(m.Resources) > 0 { + for _, e := range m.Resources { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *Value_Text) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") - } - that1, ok := that.(*Value_Text) - if !ok { - return fmt3.Errorf("that is not of type *Value_Text") +func (m *Offer) Size() (n int) { + var l int + _ = l + if m.Id != nil { + l = m.Id.Size() + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Value_Text but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Value_Textbut is not nil && this == nil") + if m.FrameworkId != nil { + l = m.FrameworkId.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) - } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + if m.SlaveId != nil { + l = m.SlaveId.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.Hostname != nil { + l = len(*m.Hostname) + n += 1 + l + sovMesos(uint64(l)) } - return nil -} -func (this *Value_Text) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true + if len(m.Resources) > 0 { + for _, e := range m.Resources { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - return false - } - - that1, ok := that.(*Value_Text) - if !ok { - return false } - if that1 == nil { - if this == nil { - return true + if len(m.ExecutorIds) > 0 { + for _, e := range m.ExecutorIds { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - return false - } else if this == nil { - return false } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false + if len(m.Attributes) > 0 { + for _, e := range m.Attributes { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *Attribute) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") - } - that1, ok := that.(*Attribute) - if !ok { - return fmt3.Errorf("that is not of type *Attribute") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Attribute but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Attributebut is not nil && this == nil") - } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) - } - } else if this.Name != nil { - return fmt3.Errorf("this.Name == nil && that.Name != nil") - } else if that1.Name != nil { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) +func (m *Offer_Operation) Size() (n int) { + var l int + _ = l + if m.Type != nil { + n += 1 + sovMesos(uint64(*m.Type)) } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return fmt3.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) - } - } else if this.Type != nil { - return fmt3.Errorf("this.Type == nil && that.Type != nil") - } else if that1.Type != nil { - return fmt3.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + if m.Launch != nil { + l = m.Launch.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !this.Scalar.Equal(that1.Scalar) { - return fmt3.Errorf("Scalar this(%v) Not Equal that(%v)", this.Scalar, that1.Scalar) + if m.Reserve != nil { + l = m.Reserve.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !this.Ranges.Equal(that1.Ranges) { - return fmt3.Errorf("Ranges this(%v) Not Equal that(%v)", this.Ranges, that1.Ranges) + if m.Unreserve != nil { + l = m.Unreserve.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !this.Set.Equal(that1.Set) { - return fmt3.Errorf("Set this(%v) Not Equal that(%v)", this.Set, that1.Set) + if m.Create != nil { + l = m.Create.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !this.Text.Equal(that1.Text) { - return fmt3.Errorf("Text this(%v) Not Equal that(%v)", this.Text, that1.Text) + if m.Destroy != nil { + l = m.Destroy.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *Attribute) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - that1, ok := that.(*Attribute) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true +func (m *Offer_Operation_Launch) Size() (n int) { + var l int + _ = l + if len(m.TaskInfos) > 0 { + for _, e := range m.TaskInfos { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - return false - } else if this == nil { - return false } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return false - } - } else if this.Name != nil { - return false - } else if that1.Name != nil { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return false - } - } else if this.Type != nil { - return false - } else if that1.Type != nil { - return false + return n +} + +func (m *Offer_Operation_Reserve) Size() (n int) { + var l int + _ = l + if len(m.Resources) > 0 { + for _, e := range m.Resources { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) + } } - if !this.Scalar.Equal(that1.Scalar) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.Ranges.Equal(that1.Ranges) { - return false + return n +} + +func (m *Offer_Operation_Unreserve) Size() (n int) { + var l int + _ = l + if len(m.Resources) > 0 { + for _, e := range m.Resources { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) + } } - if !this.Set.Equal(that1.Set) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.Text.Equal(that1.Text) { - return false + return n +} + +func (m *Offer_Operation_Create) Size() (n int) { + var l int + _ = l + if len(m.Volumes) > 0 { + for _, e := range m.Volumes { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) + } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *Resource) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil + +func (m *Offer_Operation_Destroy) Size() (n int) { + var l int + _ = l + if len(m.Volumes) > 0 { + for _, e := range m.Volumes { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - return fmt3.Errorf("that == nil && this != nil") } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} - that1, ok := that.(*Resource) - if !ok { - return fmt3.Errorf("that is not of type *Resource") +func (m *TaskInfo) Size() (n int) { + var l int + _ = l + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Resource but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Resourcebut is not nil && this == nil") + if m.TaskId != nil { + l = m.TaskId.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) - } - } else if this.Name != nil { - return fmt3.Errorf("this.Name == nil && that.Name != nil") - } else if that1.Name != nil { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + if m.SlaveId != nil { + l = m.SlaveId.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return fmt3.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) + if len(m.Resources) > 0 { + for _, e := range m.Resources { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.Type != nil { - return fmt3.Errorf("this.Type == nil && that.Type != nil") - } else if that1.Type != nil { - return fmt3.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) } - if !this.Scalar.Equal(that1.Scalar) { - return fmt3.Errorf("Scalar this(%v) Not Equal that(%v)", this.Scalar, that1.Scalar) + if m.Executor != nil { + l = m.Executor.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !this.Ranges.Equal(that1.Ranges) { - return fmt3.Errorf("Ranges this(%v) Not Equal that(%v)", this.Ranges, that1.Ranges) + if m.Data != nil { + l = len(m.Data) + n += 1 + l + sovMesos(uint64(l)) } - if !this.Set.Equal(that1.Set) { - return fmt3.Errorf("Set this(%v) Not Equal that(%v)", this.Set, that1.Set) + if m.Command != nil { + l = m.Command.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Role != nil && that1.Role != nil { - if *this.Role != *that1.Role { - return fmt3.Errorf("Role this(%v) Not Equal that(%v)", *this.Role, *that1.Role) - } - } else if this.Role != nil { - return fmt3.Errorf("this.Role == nil && that.Role != nil") - } else if that1.Role != nil { - return fmt3.Errorf("Role this(%v) Not Equal that(%v)", this.Role, that1.Role) + if m.HealthCheck != nil { + l = m.HealthCheck.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.Container != nil { + l = m.Container.Size() + n += 1 + l + sovMesos(uint64(l)) } - return nil -} -func (this *Resource) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false + if m.Labels != nil { + l = m.Labels.Size() + n += 1 + l + sovMesos(uint64(l)) + } + if m.Discovery != nil { + l = m.Discovery.Size() + n += 1 + l + sovMesos(uint64(l)) } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} - that1, ok := that.(*Resource) - if !ok { - return false +func (m *TaskStatus) Size() (n int) { + var l int + _ = l + if m.TaskId != nil { + l = m.TaskId.Size() + n += 1 + l + sovMesos(uint64(l)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.State != nil { + n += 1 + sovMesos(uint64(*m.State)) } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return false - } - } else if this.Name != nil { - return false - } else if that1.Name != nil { - return false + if m.Data != nil { + l = len(m.Data) + n += 1 + l + sovMesos(uint64(l)) } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return false - } - } else if this.Type != nil { - return false - } else if that1.Type != nil { - return false + if m.Message != nil { + l = len(*m.Message) + n += 1 + l + sovMesos(uint64(l)) } - if !this.Scalar.Equal(that1.Scalar) { - return false + if m.SlaveId != nil { + l = m.SlaveId.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !this.Ranges.Equal(that1.Ranges) { - return false + if m.Timestamp != nil { + n += 9 } - if !this.Set.Equal(that1.Set) { - return false + if m.ExecutorId != nil { + l = m.ExecutorId.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.Role != nil && that1.Role != nil { - if *this.Role != *that1.Role { - return false - } - } else if this.Role != nil { - return false - } else if that1.Role != nil { - return false + if m.Healthy != nil { + n += 2 } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.Source != nil { + n += 1 + sovMesos(uint64(*m.Source)) } - return true -} -func (this *ResourceStatistics) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if m.Reason != nil { + n += 1 + sovMesos(uint64(*m.Reason)) + } + if m.Uuid != nil { + l = len(m.Uuid) + n += 1 + l + sovMesos(uint64(l)) } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} - that1, ok := that.(*ResourceStatistics) - if !ok { - return fmt3.Errorf("that is not of type *ResourceStatistics") +func (m *Filters) Size() (n int) { + var l int + _ = l + if m.RefuseSeconds != nil { + n += 9 } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *ResourceStatistics but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ResourceStatisticsbut is not nil && this == nil") + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.Timestamp != nil && that1.Timestamp != nil { - if *this.Timestamp != *that1.Timestamp { - return fmt3.Errorf("Timestamp this(%v) Not Equal that(%v)", *this.Timestamp, *that1.Timestamp) + return n +} + +func (m *Environment) Size() (n int) { + var l int + _ = l + if len(m.Variables) > 0 { + for _, e := range m.Variables { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.Timestamp != nil { - return fmt3.Errorf("this.Timestamp == nil && that.Timestamp != nil") - } else if that1.Timestamp != nil { - return fmt3.Errorf("Timestamp this(%v) Not Equal that(%v)", this.Timestamp, that1.Timestamp) } - if this.CpusUserTimeSecs != nil && that1.CpusUserTimeSecs != nil { - if *this.CpusUserTimeSecs != *that1.CpusUserTimeSecs { - return fmt3.Errorf("CpusUserTimeSecs this(%v) Not Equal that(%v)", *this.CpusUserTimeSecs, *that1.CpusUserTimeSecs) - } - } else if this.CpusUserTimeSecs != nil { - return fmt3.Errorf("this.CpusUserTimeSecs == nil && that.CpusUserTimeSecs != nil") - } else if that1.CpusUserTimeSecs != nil { - return fmt3.Errorf("CpusUserTimeSecs this(%v) Not Equal that(%v)", this.CpusUserTimeSecs, that1.CpusUserTimeSecs) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Environment_Variable) Size() (n int) { + var l int + _ = l + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovMesos(uint64(l)) } - if this.CpusSystemTimeSecs != nil && that1.CpusSystemTimeSecs != nil { - if *this.CpusSystemTimeSecs != *that1.CpusSystemTimeSecs { - return fmt3.Errorf("CpusSystemTimeSecs this(%v) Not Equal that(%v)", *this.CpusSystemTimeSecs, *that1.CpusSystemTimeSecs) - } - } else if this.CpusSystemTimeSecs != nil { - return fmt3.Errorf("this.CpusSystemTimeSecs == nil && that.CpusSystemTimeSecs != nil") - } else if that1.CpusSystemTimeSecs != nil { - return fmt3.Errorf("CpusSystemTimeSecs this(%v) Not Equal that(%v)", this.CpusSystemTimeSecs, that1.CpusSystemTimeSecs) + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) } - if this.CpusLimit != nil && that1.CpusLimit != nil { - if *this.CpusLimit != *that1.CpusLimit { - return fmt3.Errorf("CpusLimit this(%v) Not Equal that(%v)", *this.CpusLimit, *that1.CpusLimit) - } - } else if this.CpusLimit != nil { - return fmt3.Errorf("this.CpusLimit == nil && that.CpusLimit != nil") - } else if that1.CpusLimit != nil { - return fmt3.Errorf("CpusLimit this(%v) Not Equal that(%v)", this.CpusLimit, that1.CpusLimit) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.CpusNrPeriods != nil && that1.CpusNrPeriods != nil { - if *this.CpusNrPeriods != *that1.CpusNrPeriods { - return fmt3.Errorf("CpusNrPeriods this(%v) Not Equal that(%v)", *this.CpusNrPeriods, *that1.CpusNrPeriods) - } - } else if this.CpusNrPeriods != nil { - return fmt3.Errorf("this.CpusNrPeriods == nil && that.CpusNrPeriods != nil") - } else if that1.CpusNrPeriods != nil { - return fmt3.Errorf("CpusNrPeriods this(%v) Not Equal that(%v)", this.CpusNrPeriods, that1.CpusNrPeriods) + return n +} + +func (m *Parameter) Size() (n int) { + var l int + _ = l + if m.Key != nil { + l = len(*m.Key) + n += 1 + l + sovMesos(uint64(l)) } - if this.CpusNrThrottled != nil && that1.CpusNrThrottled != nil { - if *this.CpusNrThrottled != *that1.CpusNrThrottled { - return fmt3.Errorf("CpusNrThrottled this(%v) Not Equal that(%v)", *this.CpusNrThrottled, *that1.CpusNrThrottled) - } - } else if this.CpusNrThrottled != nil { - return fmt3.Errorf("this.CpusNrThrottled == nil && that.CpusNrThrottled != nil") - } else if that1.CpusNrThrottled != nil { - return fmt3.Errorf("CpusNrThrottled this(%v) Not Equal that(%v)", this.CpusNrThrottled, that1.CpusNrThrottled) + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) } - if this.CpusThrottledTimeSecs != nil && that1.CpusThrottledTimeSecs != nil { - if *this.CpusThrottledTimeSecs != *that1.CpusThrottledTimeSecs { - return fmt3.Errorf("CpusThrottledTimeSecs this(%v) Not Equal that(%v)", *this.CpusThrottledTimeSecs, *that1.CpusThrottledTimeSecs) - } - } else if this.CpusThrottledTimeSecs != nil { - return fmt3.Errorf("this.CpusThrottledTimeSecs == nil && that.CpusThrottledTimeSecs != nil") - } else if that1.CpusThrottledTimeSecs != nil { - return fmt3.Errorf("CpusThrottledTimeSecs this(%v) Not Equal that(%v)", this.CpusThrottledTimeSecs, that1.CpusThrottledTimeSecs) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.MemRssBytes != nil && that1.MemRssBytes != nil { - if *this.MemRssBytes != *that1.MemRssBytes { - return fmt3.Errorf("MemRssBytes this(%v) Not Equal that(%v)", *this.MemRssBytes, *that1.MemRssBytes) + return n +} + +func (m *Parameters) Size() (n int) { + var l int + _ = l + if len(m.Parameter) > 0 { + for _, e := range m.Parameter { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.MemRssBytes != nil { - return fmt3.Errorf("this.MemRssBytes == nil && that.MemRssBytes != nil") - } else if that1.MemRssBytes != nil { - return fmt3.Errorf("MemRssBytes this(%v) Not Equal that(%v)", this.MemRssBytes, that1.MemRssBytes) } - if this.MemLimitBytes != nil && that1.MemLimitBytes != nil { - if *this.MemLimitBytes != *that1.MemLimitBytes { - return fmt3.Errorf("MemLimitBytes this(%v) Not Equal that(%v)", *this.MemLimitBytes, *that1.MemLimitBytes) - } - } else if this.MemLimitBytes != nil { - return fmt3.Errorf("this.MemLimitBytes == nil && that.MemLimitBytes != nil") - } else if that1.MemLimitBytes != nil { - return fmt3.Errorf("MemLimitBytes this(%v) Not Equal that(%v)", this.MemLimitBytes, that1.MemLimitBytes) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.MemFileBytes != nil && that1.MemFileBytes != nil { - if *this.MemFileBytes != *that1.MemFileBytes { - return fmt3.Errorf("MemFileBytes this(%v) Not Equal that(%v)", *this.MemFileBytes, *that1.MemFileBytes) - } - } else if this.MemFileBytes != nil { - return fmt3.Errorf("this.MemFileBytes == nil && that.MemFileBytes != nil") - } else if that1.MemFileBytes != nil { - return fmt3.Errorf("MemFileBytes this(%v) Not Equal that(%v)", this.MemFileBytes, that1.MemFileBytes) + return n +} + +func (m *Credential) Size() (n int) { + var l int + _ = l + if m.Principal != nil { + l = len(*m.Principal) + n += 1 + l + sovMesos(uint64(l)) } - if this.MemAnonBytes != nil && that1.MemAnonBytes != nil { - if *this.MemAnonBytes != *that1.MemAnonBytes { - return fmt3.Errorf("MemAnonBytes this(%v) Not Equal that(%v)", *this.MemAnonBytes, *that1.MemAnonBytes) - } - } else if this.MemAnonBytes != nil { - return fmt3.Errorf("this.MemAnonBytes == nil && that.MemAnonBytes != nil") - } else if that1.MemAnonBytes != nil { - return fmt3.Errorf("MemAnonBytes this(%v) Not Equal that(%v)", this.MemAnonBytes, that1.MemAnonBytes) + if m.Secret != nil { + l = len(m.Secret) + n += 1 + l + sovMesos(uint64(l)) } - if this.MemMappedFileBytes != nil && that1.MemMappedFileBytes != nil { - if *this.MemMappedFileBytes != *that1.MemMappedFileBytes { - return fmt3.Errorf("MemMappedFileBytes this(%v) Not Equal that(%v)", *this.MemMappedFileBytes, *that1.MemMappedFileBytes) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Credentials) Size() (n int) { + var l int + _ = l + if len(m.Credentials) > 0 { + for _, e := range m.Credentials { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.MemMappedFileBytes != nil { - return fmt3.Errorf("this.MemMappedFileBytes == nil && that.MemMappedFileBytes != nil") - } else if that1.MemMappedFileBytes != nil { - return fmt3.Errorf("MemMappedFileBytes this(%v) Not Equal that(%v)", this.MemMappedFileBytes, that1.MemMappedFileBytes) } - if !this.Perf.Equal(that1.Perf) { - return fmt3.Errorf("Perf this(%v) Not Equal that(%v)", this.Perf, that1.Perf) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.NetRxPackets != nil && that1.NetRxPackets != nil { - if *this.NetRxPackets != *that1.NetRxPackets { - return fmt3.Errorf("NetRxPackets this(%v) Not Equal that(%v)", *this.NetRxPackets, *that1.NetRxPackets) - } - } else if this.NetRxPackets != nil { - return fmt3.Errorf("this.NetRxPackets == nil && that.NetRxPackets != nil") - } else if that1.NetRxPackets != nil { - return fmt3.Errorf("NetRxPackets this(%v) Not Equal that(%v)", this.NetRxPackets, that1.NetRxPackets) + return n +} + +func (m *ACL) Size() (n int) { + var l int + _ = l + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.NetRxBytes != nil && that1.NetRxBytes != nil { - if *this.NetRxBytes != *that1.NetRxBytes { - return fmt3.Errorf("NetRxBytes this(%v) Not Equal that(%v)", *this.NetRxBytes, *that1.NetRxBytes) - } - } else if this.NetRxBytes != nil { - return fmt3.Errorf("this.NetRxBytes == nil && that.NetRxBytes != nil") - } else if that1.NetRxBytes != nil { - return fmt3.Errorf("NetRxBytes this(%v) Not Equal that(%v)", this.NetRxBytes, that1.NetRxBytes) + return n +} + +func (m *ACL_Entity) Size() (n int) { + var l int + _ = l + if m.Type != nil { + n += 1 + sovMesos(uint64(*m.Type)) } - if this.NetRxErrors != nil && that1.NetRxErrors != nil { - if *this.NetRxErrors != *that1.NetRxErrors { - return fmt3.Errorf("NetRxErrors this(%v) Not Equal that(%v)", *this.NetRxErrors, *that1.NetRxErrors) + if len(m.Values) > 0 { + for _, s := range m.Values { + l = len(s) + n += 1 + l + sovMesos(uint64(l)) } - } else if this.NetRxErrors != nil { - return fmt3.Errorf("this.NetRxErrors == nil && that.NetRxErrors != nil") - } else if that1.NetRxErrors != nil { - return fmt3.Errorf("NetRxErrors this(%v) Not Equal that(%v)", this.NetRxErrors, that1.NetRxErrors) } - if this.NetRxDropped != nil && that1.NetRxDropped != nil { - if *this.NetRxDropped != *that1.NetRxDropped { - return fmt3.Errorf("NetRxDropped this(%v) Not Equal that(%v)", *this.NetRxDropped, *that1.NetRxDropped) - } - } else if this.NetRxDropped != nil { - return fmt3.Errorf("this.NetRxDropped == nil && that.NetRxDropped != nil") - } else if that1.NetRxDropped != nil { - return fmt3.Errorf("NetRxDropped this(%v) Not Equal that(%v)", this.NetRxDropped, that1.NetRxDropped) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.NetTxPackets != nil && that1.NetTxPackets != nil { - if *this.NetTxPackets != *that1.NetTxPackets { - return fmt3.Errorf("NetTxPackets this(%v) Not Equal that(%v)", *this.NetTxPackets, *that1.NetTxPackets) - } - } else if this.NetTxPackets != nil { - return fmt3.Errorf("this.NetTxPackets == nil && that.NetTxPackets != nil") - } else if that1.NetTxPackets != nil { - return fmt3.Errorf("NetTxPackets this(%v) Not Equal that(%v)", this.NetTxPackets, that1.NetTxPackets) + return n +} + +func (m *ACL_RegisterFramework) Size() (n int) { + var l int + _ = l + if m.Principals != nil { + l = m.Principals.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.NetTxBytes != nil && that1.NetTxBytes != nil { - if *this.NetTxBytes != *that1.NetTxBytes { - return fmt3.Errorf("NetTxBytes this(%v) Not Equal that(%v)", *this.NetTxBytes, *that1.NetTxBytes) - } - } else if this.NetTxBytes != nil { - return fmt3.Errorf("this.NetTxBytes == nil && that.NetTxBytes != nil") - } else if that1.NetTxBytes != nil { - return fmt3.Errorf("NetTxBytes this(%v) Not Equal that(%v)", this.NetTxBytes, that1.NetTxBytes) + if m.Roles != nil { + l = m.Roles.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.NetTxErrors != nil && that1.NetTxErrors != nil { - if *this.NetTxErrors != *that1.NetTxErrors { - return fmt3.Errorf("NetTxErrors this(%v) Not Equal that(%v)", *this.NetTxErrors, *that1.NetTxErrors) - } - } else if this.NetTxErrors != nil { - return fmt3.Errorf("this.NetTxErrors == nil && that.NetTxErrors != nil") - } else if that1.NetTxErrors != nil { - return fmt3.Errorf("NetTxErrors this(%v) Not Equal that(%v)", this.NetTxErrors, that1.NetTxErrors) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.NetTxDropped != nil && that1.NetTxDropped != nil { - if *this.NetTxDropped != *that1.NetTxDropped { - return fmt3.Errorf("NetTxDropped this(%v) Not Equal that(%v)", *this.NetTxDropped, *that1.NetTxDropped) - } - } else if this.NetTxDropped != nil { - return fmt3.Errorf("this.NetTxDropped == nil && that.NetTxDropped != nil") - } else if that1.NetTxDropped != nil { - return fmt3.Errorf("NetTxDropped this(%v) Not Equal that(%v)", this.NetTxDropped, that1.NetTxDropped) + return n +} + +func (m *ACL_RunTask) Size() (n int) { + var l int + _ = l + if m.Principals != nil { + l = m.Principals.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.NetTcpRttMicrosecsP50 != nil && that1.NetTcpRttMicrosecsP50 != nil { - if *this.NetTcpRttMicrosecsP50 != *that1.NetTcpRttMicrosecsP50 { - return fmt3.Errorf("NetTcpRttMicrosecsP50 this(%v) Not Equal that(%v)", *this.NetTcpRttMicrosecsP50, *that1.NetTcpRttMicrosecsP50) - } - } else if this.NetTcpRttMicrosecsP50 != nil { - return fmt3.Errorf("this.NetTcpRttMicrosecsP50 == nil && that.NetTcpRttMicrosecsP50 != nil") - } else if that1.NetTcpRttMicrosecsP50 != nil { - return fmt3.Errorf("NetTcpRttMicrosecsP50 this(%v) Not Equal that(%v)", this.NetTcpRttMicrosecsP50, that1.NetTcpRttMicrosecsP50) + if m.Users != nil { + l = m.Users.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.NetTcpRttMicrosecsP90 != nil && that1.NetTcpRttMicrosecsP90 != nil { - if *this.NetTcpRttMicrosecsP90 != *that1.NetTcpRttMicrosecsP90 { - return fmt3.Errorf("NetTcpRttMicrosecsP90 this(%v) Not Equal that(%v)", *this.NetTcpRttMicrosecsP90, *that1.NetTcpRttMicrosecsP90) - } - } else if this.NetTcpRttMicrosecsP90 != nil { - return fmt3.Errorf("this.NetTcpRttMicrosecsP90 == nil && that.NetTcpRttMicrosecsP90 != nil") - } else if that1.NetTcpRttMicrosecsP90 != nil { - return fmt3.Errorf("NetTcpRttMicrosecsP90 this(%v) Not Equal that(%v)", this.NetTcpRttMicrosecsP90, that1.NetTcpRttMicrosecsP90) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.NetTcpRttMicrosecsP95 != nil && that1.NetTcpRttMicrosecsP95 != nil { - if *this.NetTcpRttMicrosecsP95 != *that1.NetTcpRttMicrosecsP95 { - return fmt3.Errorf("NetTcpRttMicrosecsP95 this(%v) Not Equal that(%v)", *this.NetTcpRttMicrosecsP95, *that1.NetTcpRttMicrosecsP95) - } - } else if this.NetTcpRttMicrosecsP95 != nil { - return fmt3.Errorf("this.NetTcpRttMicrosecsP95 == nil && that.NetTcpRttMicrosecsP95 != nil") - } else if that1.NetTcpRttMicrosecsP95 != nil { - return fmt3.Errorf("NetTcpRttMicrosecsP95 this(%v) Not Equal that(%v)", this.NetTcpRttMicrosecsP95, that1.NetTcpRttMicrosecsP95) + return n +} + +func (m *ACL_ShutdownFramework) Size() (n int) { + var l int + _ = l + if m.Principals != nil { + l = m.Principals.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.NetTcpRttMicrosecsP99 != nil && that1.NetTcpRttMicrosecsP99 != nil { - if *this.NetTcpRttMicrosecsP99 != *that1.NetTcpRttMicrosecsP99 { - return fmt3.Errorf("NetTcpRttMicrosecsP99 this(%v) Not Equal that(%v)", *this.NetTcpRttMicrosecsP99, *that1.NetTcpRttMicrosecsP99) - } - } else if this.NetTcpRttMicrosecsP99 != nil { - return fmt3.Errorf("this.NetTcpRttMicrosecsP99 == nil && that.NetTcpRttMicrosecsP99 != nil") - } else if that1.NetTcpRttMicrosecsP99 != nil { - return fmt3.Errorf("NetTcpRttMicrosecsP99 this(%v) Not Equal that(%v)", this.NetTcpRttMicrosecsP99, that1.NetTcpRttMicrosecsP99) + if m.FrameworkPrincipals != nil { + l = m.FrameworkPrincipals.Size() + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *ResourceStatistics) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - that1, ok := that.(*ResourceStatistics) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false +func (m *ACLs) Size() (n int) { + var l int + _ = l + if m.Permissive != nil { + n += 2 } - if this.Timestamp != nil && that1.Timestamp != nil { - if *this.Timestamp != *that1.Timestamp { - return false + if len(m.RegisterFrameworks) > 0 { + for _, e := range m.RegisterFrameworks { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.Timestamp != nil { - return false - } else if that1.Timestamp != nil { - return false } - if this.CpusUserTimeSecs != nil && that1.CpusUserTimeSecs != nil { - if *this.CpusUserTimeSecs != *that1.CpusUserTimeSecs { - return false + if len(m.RunTasks) > 0 { + for _, e := range m.RunTasks { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.CpusUserTimeSecs != nil { - return false - } else if that1.CpusUserTimeSecs != nil { - return false } - if this.CpusSystemTimeSecs != nil && that1.CpusSystemTimeSecs != nil { - if *this.CpusSystemTimeSecs != *that1.CpusSystemTimeSecs { - return false + if len(m.ShutdownFrameworks) > 0 { + for _, e := range m.ShutdownFrameworks { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.CpusSystemTimeSecs != nil { - return false - } else if that1.CpusSystemTimeSecs != nil { - return false } - if this.CpusLimit != nil && that1.CpusLimit != nil { - if *this.CpusLimit != *that1.CpusLimit { - return false - } - } else if this.CpusLimit != nil { - return false - } else if that1.CpusLimit != nil { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.CpusNrPeriods != nil && that1.CpusNrPeriods != nil { - if *this.CpusNrPeriods != *that1.CpusNrPeriods { - return false - } - } else if this.CpusNrPeriods != nil { - return false - } else if that1.CpusNrPeriods != nil { - return false + return n +} + +func (m *RateLimit) Size() (n int) { + var l int + _ = l + if m.Qps != nil { + n += 9 } - if this.CpusNrThrottled != nil && that1.CpusNrThrottled != nil { - if *this.CpusNrThrottled != *that1.CpusNrThrottled { - return false - } - } else if this.CpusNrThrottled != nil { - return false - } else if that1.CpusNrThrottled != nil { - return false + if m.Principal != nil { + l = len(*m.Principal) + n += 1 + l + sovMesos(uint64(l)) } - if this.CpusThrottledTimeSecs != nil && that1.CpusThrottledTimeSecs != nil { - if *this.CpusThrottledTimeSecs != *that1.CpusThrottledTimeSecs { - return false - } - } else if this.CpusThrottledTimeSecs != nil { - return false - } else if that1.CpusThrottledTimeSecs != nil { - return false + if m.Capacity != nil { + n += 1 + sovMesos(uint64(*m.Capacity)) } - if this.MemRssBytes != nil && that1.MemRssBytes != nil { - if *this.MemRssBytes != *that1.MemRssBytes { - return false - } - } else if this.MemRssBytes != nil { - return false - } else if that1.MemRssBytes != nil { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.MemLimitBytes != nil && that1.MemLimitBytes != nil { - if *this.MemLimitBytes != *that1.MemLimitBytes { - return false + return n +} + +func (m *RateLimits) Size() (n int) { + var l int + _ = l + if len(m.Limits) > 0 { + for _, e := range m.Limits { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.MemLimitBytes != nil { - return false - } else if that1.MemLimitBytes != nil { - return false } - if this.MemFileBytes != nil && that1.MemFileBytes != nil { - if *this.MemFileBytes != *that1.MemFileBytes { - return false - } - } else if this.MemFileBytes != nil { - return false - } else if that1.MemFileBytes != nil { - return false + if m.AggregateDefaultQps != nil { + n += 9 } - if this.MemAnonBytes != nil && that1.MemAnonBytes != nil { - if *this.MemAnonBytes != *that1.MemAnonBytes { - return false - } - } else if this.MemAnonBytes != nil { - return false - } else if that1.MemAnonBytes != nil { - return false + if m.AggregateDefaultCapacity != nil { + n += 1 + sovMesos(uint64(*m.AggregateDefaultCapacity)) } - if this.MemMappedFileBytes != nil && that1.MemMappedFileBytes != nil { - if *this.MemMappedFileBytes != *that1.MemMappedFileBytes { - return false - } - } else if this.MemMappedFileBytes != nil { - return false - } else if that1.MemMappedFileBytes != nil { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.Perf.Equal(that1.Perf) { - return false + return n +} + +func (m *Volume) Size() (n int) { + var l int + _ = l + if m.ContainerPath != nil { + l = len(*m.ContainerPath) + n += 1 + l + sovMesos(uint64(l)) } - if this.NetRxPackets != nil && that1.NetRxPackets != nil { - if *this.NetRxPackets != *that1.NetRxPackets { - return false - } - } else if this.NetRxPackets != nil { - return false - } else if that1.NetRxPackets != nil { - return false + if m.HostPath != nil { + l = len(*m.HostPath) + n += 1 + l + sovMesos(uint64(l)) } - if this.NetRxBytes != nil && that1.NetRxBytes != nil { - if *this.NetRxBytes != *that1.NetRxBytes { - return false - } - } else if this.NetRxBytes != nil { - return false - } else if that1.NetRxBytes != nil { - return false + if m.Mode != nil { + n += 1 + sovMesos(uint64(*m.Mode)) } - if this.NetRxErrors != nil && that1.NetRxErrors != nil { - if *this.NetRxErrors != *that1.NetRxErrors { - return false - } - } else if this.NetRxErrors != nil { - return false - } else if that1.NetRxErrors != nil { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.NetRxDropped != nil && that1.NetRxDropped != nil { - if *this.NetRxDropped != *that1.NetRxDropped { - return false - } - } else if this.NetRxDropped != nil { - return false - } else if that1.NetRxDropped != nil { - return false + return n +} + +func (m *ContainerInfo) Size() (n int) { + var l int + _ = l + if m.Type != nil { + n += 1 + sovMesos(uint64(*m.Type)) } - if this.NetTxPackets != nil && that1.NetTxPackets != nil { - if *this.NetTxPackets != *that1.NetTxPackets { - return false + if len(m.Volumes) > 0 { + for _, e := range m.Volumes { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.NetTxPackets != nil { - return false - } else if that1.NetTxPackets != nil { - return false } - if this.NetTxBytes != nil && that1.NetTxBytes != nil { - if *this.NetTxBytes != *that1.NetTxBytes { - return false - } - } else if this.NetTxBytes != nil { - return false - } else if that1.NetTxBytes != nil { - return false + if m.Docker != nil { + l = m.Docker.Size() + n += 1 + l + sovMesos(uint64(l)) } - if this.NetTxErrors != nil && that1.NetTxErrors != nil { - if *this.NetTxErrors != *that1.NetTxErrors { - return false - } - } else if this.NetTxErrors != nil { - return false - } else if that1.NetTxErrors != nil { - return false + if m.Hostname != nil { + l = len(*m.Hostname) + n += 1 + l + sovMesos(uint64(l)) } - if this.NetTxDropped != nil && that1.NetTxDropped != nil { - if *this.NetTxDropped != *that1.NetTxDropped { - return false - } - } else if this.NetTxDropped != nil { - return false - } else if that1.NetTxDropped != nil { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if this.NetTcpRttMicrosecsP50 != nil && that1.NetTcpRttMicrosecsP50 != nil { - if *this.NetTcpRttMicrosecsP50 != *that1.NetTcpRttMicrosecsP50 { - return false - } - } else if this.NetTcpRttMicrosecsP50 != nil { - return false - } else if that1.NetTcpRttMicrosecsP50 != nil { - return false + return n +} + +func (m *ContainerInfo_DockerInfo) Size() (n int) { + var l int + _ = l + if m.Image != nil { + l = len(*m.Image) + n += 1 + l + sovMesos(uint64(l)) } - if this.NetTcpRttMicrosecsP90 != nil && that1.NetTcpRttMicrosecsP90 != nil { - if *this.NetTcpRttMicrosecsP90 != *that1.NetTcpRttMicrosecsP90 { - return false - } - } else if this.NetTcpRttMicrosecsP90 != nil { - return false - } else if that1.NetTcpRttMicrosecsP90 != nil { - return false + if m.Network != nil { + n += 1 + sovMesos(uint64(*m.Network)) } - if this.NetTcpRttMicrosecsP95 != nil && that1.NetTcpRttMicrosecsP95 != nil { - if *this.NetTcpRttMicrosecsP95 != *that1.NetTcpRttMicrosecsP95 { - return false + if len(m.PortMappings) > 0 { + for _, e := range m.PortMappings { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.NetTcpRttMicrosecsP95 != nil { - return false - } else if that1.NetTcpRttMicrosecsP95 != nil { - return false } - if this.NetTcpRttMicrosecsP99 != nil && that1.NetTcpRttMicrosecsP99 != nil { - if *this.NetTcpRttMicrosecsP99 != *that1.NetTcpRttMicrosecsP99 { - return false + if m.Privileged != nil { + n += 2 + } + if len(m.Parameters) > 0 { + for _, e := range m.Parameters { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - } else if this.NetTcpRttMicrosecsP99 != nil { - return false - } else if that1.NetTcpRttMicrosecsP99 != nil { - return false } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.ForcePullImage != nil { + n += 2 } - return true -} -func (this *ResourceUsage) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } + return n +} - that1, ok := that.(*ResourceUsage) - if !ok { - return fmt3.Errorf("that is not of type *ResourceUsage") +func (m *ContainerInfo_DockerInfo_PortMapping) Size() (n int) { + var l int + _ = l + if m.HostPort != nil { + n += 1 + sovMesos(uint64(*m.HostPort)) } - if that1 == nil { - if this == nil { - return nil + if m.ContainerPort != nil { + n += 1 + sovMesos(uint64(*m.ContainerPort)) + } + if m.Protocol != nil { + l = len(*m.Protocol) + n += 1 + l + sovMesos(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Labels) Size() (n int) { + var l int + _ = l + if len(m.Labels) > 0 { + for _, e := range m.Labels { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - return fmt3.Errorf("that is type *ResourceUsage but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ResourceUsagebut is not nil && this == nil") } - if !this.SlaveId.Equal(that1.SlaveId) { - return fmt3.Errorf("SlaveId this(%v) Not Equal that(%v)", this.SlaveId, that1.SlaveId) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.FrameworkId.Equal(that1.FrameworkId) { - return fmt3.Errorf("FrameworkId this(%v) Not Equal that(%v)", this.FrameworkId, that1.FrameworkId) + return n +} + +func (m *Label) Size() (n int) { + var l int + _ = l + if m.Key != nil { + l = len(*m.Key) + n += 1 + l + sovMesos(uint64(l)) } - if !this.ExecutorId.Equal(that1.ExecutorId) { - return fmt3.Errorf("ExecutorId this(%v) Not Equal that(%v)", this.ExecutorId, that1.ExecutorId) + if m.Value != nil { + l = len(*m.Value) + n += 1 + l + sovMesos(uint64(l)) } - if this.ExecutorName != nil && that1.ExecutorName != nil { - if *this.ExecutorName != *that1.ExecutorName { - return fmt3.Errorf("ExecutorName this(%v) Not Equal that(%v)", *this.ExecutorName, *that1.ExecutorName) - } - } else if this.ExecutorName != nil { - return fmt3.Errorf("this.ExecutorName == nil && that.ExecutorName != nil") - } else if that1.ExecutorName != nil { - return fmt3.Errorf("ExecutorName this(%v) Not Equal that(%v)", this.ExecutorName, that1.ExecutorName) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.TaskId.Equal(that1.TaskId) { - return fmt3.Errorf("TaskId this(%v) Not Equal that(%v)", this.TaskId, that1.TaskId) + return n +} + +func (m *Port) Size() (n int) { + var l int + _ = l + if m.Number != nil { + n += 1 + sovMesos(uint64(*m.Number)) } - if !this.Statistics.Equal(that1.Statistics) { - return fmt3.Errorf("Statistics this(%v) Not Equal that(%v)", this.Statistics, that1.Statistics) + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovMesos(uint64(l)) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.Protocol != nil { + l = len(*m.Protocol) + n += 1 + l + sovMesos(uint64(l)) } - return nil + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n } -func (this *ResourceUsage) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true + +func (m *Ports) Size() (n int) { + var l int + _ = l + if len(m.Ports) > 0 { + for _, e := range m.Ports { + l = e.Size() + n += 1 + l + sovMesos(uint64(l)) } - return false } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} - that1, ok := that.(*ResourceUsage) - if !ok { - return false +func (m *DiscoveryInfo) Size() (n int) { + var l int + _ = l + if m.Visibility != nil { + n += 1 + sovMesos(uint64(*m.Visibility)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovMesos(uint64(l)) } - if !this.SlaveId.Equal(that1.SlaveId) { - return false + if m.Environment != nil { + l = len(*m.Environment) + n += 1 + l + sovMesos(uint64(l)) } - if !this.FrameworkId.Equal(that1.FrameworkId) { - return false + if m.Location != nil { + l = len(*m.Location) + n += 1 + l + sovMesos(uint64(l)) } - if !this.ExecutorId.Equal(that1.ExecutorId) { - return false + if m.Version != nil { + l = len(*m.Version) + n += 1 + l + sovMesos(uint64(l)) } - if this.ExecutorName != nil && that1.ExecutorName != nil { - if *this.ExecutorName != *that1.ExecutorName { - return false + if m.Ports != nil { + l = m.Ports.Size() + n += 1 + l + sovMesos(uint64(l)) + } + if m.Labels != nil { + l = m.Labels.Size() + n += 1 + l + sovMesos(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovMesos(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break } - } else if this.ExecutorName != nil { - return false - } else if that1.ExecutorName != nil { - return false } - if !this.TaskId.Equal(that1.TaskId) { - return false + return n +} +func sozMesos(x uint64) (n int) { + return sovMesos(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *FrameworkID) String() string { + if this == nil { + return "nil" } - if !this.Statistics.Equal(that1.Statistics) { - return false + s := strings.Join([]string{`&FrameworkID{`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *OfferID) String() string { + if this == nil { + return "nil" } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + s := strings.Join([]string{`&OfferID{`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *SlaveID) String() string { + if this == nil { + return "nil" } - return true + s := strings.Join([]string{`&SlaveID{`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s } -func (this *PerfStatistics) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") +func (this *TaskID) String() string { + if this == nil { + return "nil" } - - that1, ok := that.(*PerfStatistics) - if !ok { - return fmt3.Errorf("that is not of type *PerfStatistics") + s := strings.Join([]string{`&TaskID{`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ExecutorID) String() string { + if this == nil { + return "nil" } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *PerfStatistics but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *PerfStatisticsbut is not nil && this == nil") + s := strings.Join([]string{`&ExecutorID{`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ContainerID) String() string { + if this == nil { + return "nil" } - if this.Timestamp != nil && that1.Timestamp != nil { - if *this.Timestamp != *that1.Timestamp { - return fmt3.Errorf("Timestamp this(%v) Not Equal that(%v)", *this.Timestamp, *that1.Timestamp) - } - } else if this.Timestamp != nil { - return fmt3.Errorf("this.Timestamp == nil && that.Timestamp != nil") - } else if that1.Timestamp != nil { - return fmt3.Errorf("Timestamp this(%v) Not Equal that(%v)", this.Timestamp, that1.Timestamp) + s := strings.Join([]string{`&ContainerID{`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *FrameworkInfo) String() string { + if this == nil { + return "nil" } - if this.Duration != nil && that1.Duration != nil { - if *this.Duration != *that1.Duration { - return fmt3.Errorf("Duration this(%v) Not Equal that(%v)", *this.Duration, *that1.Duration) - } - } else if this.Duration != nil { - return fmt3.Errorf("this.Duration == nil && that.Duration != nil") - } else if that1.Duration != nil { - return fmt3.Errorf("Duration this(%v) Not Equal that(%v)", this.Duration, that1.Duration) + s := strings.Join([]string{`&FrameworkInfo{`, + `User:` + valueToStringMesos(this.User) + `,`, + `Name:` + valueToStringMesos(this.Name) + `,`, + `Id:` + strings.Replace(fmt.Sprintf("%v", this.Id), "FrameworkID", "FrameworkID", 1) + `,`, + `FailoverTimeout:` + valueToStringMesos(this.FailoverTimeout) + `,`, + `Checkpoint:` + valueToStringMesos(this.Checkpoint) + `,`, + `Role:` + valueToStringMesos(this.Role) + `,`, + `Hostname:` + valueToStringMesos(this.Hostname) + `,`, + `Principal:` + valueToStringMesos(this.Principal) + `,`, + `WebuiUrl:` + valueToStringMesos(this.WebuiUrl) + `,`, + `Capabilities:` + strings.Replace(fmt.Sprintf("%v", this.Capabilities), "FrameworkInfo_Capability", "FrameworkInfo_Capability", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *FrameworkInfo_Capability) String() string { + if this == nil { + return "nil" } - if this.Cycles != nil && that1.Cycles != nil { - if *this.Cycles != *that1.Cycles { - return fmt3.Errorf("Cycles this(%v) Not Equal that(%v)", *this.Cycles, *that1.Cycles) - } - } else if this.Cycles != nil { - return fmt3.Errorf("this.Cycles == nil && that.Cycles != nil") - } else if that1.Cycles != nil { - return fmt3.Errorf("Cycles this(%v) Not Equal that(%v)", this.Cycles, that1.Cycles) + s := strings.Join([]string{`&FrameworkInfo_Capability{`, + `Type:` + valueToStringMesos(this.Type) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *HealthCheck) String() string { + if this == nil { + return "nil" } - if this.StalledCyclesFrontend != nil && that1.StalledCyclesFrontend != nil { - if *this.StalledCyclesFrontend != *that1.StalledCyclesFrontend { - return fmt3.Errorf("StalledCyclesFrontend this(%v) Not Equal that(%v)", *this.StalledCyclesFrontend, *that1.StalledCyclesFrontend) - } - } else if this.StalledCyclesFrontend != nil { - return fmt3.Errorf("this.StalledCyclesFrontend == nil && that.StalledCyclesFrontend != nil") - } else if that1.StalledCyclesFrontend != nil { - return fmt3.Errorf("StalledCyclesFrontend this(%v) Not Equal that(%v)", this.StalledCyclesFrontend, that1.StalledCyclesFrontend) + s := strings.Join([]string{`&HealthCheck{`, + `Http:` + strings.Replace(fmt.Sprintf("%v", this.Http), "HealthCheck_HTTP", "HealthCheck_HTTP", 1) + `,`, + `DelaySeconds:` + valueToStringMesos(this.DelaySeconds) + `,`, + `IntervalSeconds:` + valueToStringMesos(this.IntervalSeconds) + `,`, + `TimeoutSeconds:` + valueToStringMesos(this.TimeoutSeconds) + `,`, + `ConsecutiveFailures:` + valueToStringMesos(this.ConsecutiveFailures) + `,`, + `GracePeriodSeconds:` + valueToStringMesos(this.GracePeriodSeconds) + `,`, + `Command:` + strings.Replace(fmt.Sprintf("%v", this.Command), "CommandInfo", "CommandInfo", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *HealthCheck_HTTP) String() string { + if this == nil { + return "nil" } - if this.StalledCyclesBackend != nil && that1.StalledCyclesBackend != nil { - if *this.StalledCyclesBackend != *that1.StalledCyclesBackend { - return fmt3.Errorf("StalledCyclesBackend this(%v) Not Equal that(%v)", *this.StalledCyclesBackend, *that1.StalledCyclesBackend) - } - } else if this.StalledCyclesBackend != nil { - return fmt3.Errorf("this.StalledCyclesBackend == nil && that.StalledCyclesBackend != nil") - } else if that1.StalledCyclesBackend != nil { - return fmt3.Errorf("StalledCyclesBackend this(%v) Not Equal that(%v)", this.StalledCyclesBackend, that1.StalledCyclesBackend) + s := strings.Join([]string{`&HealthCheck_HTTP{`, + `Port:` + valueToStringMesos(this.Port) + `,`, + `Path:` + valueToStringMesos(this.Path) + `,`, + `Statuses:` + fmt.Sprintf("%v", this.Statuses) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *CommandInfo) String() string { + if this == nil { + return "nil" } - if this.Instructions != nil && that1.Instructions != nil { - if *this.Instructions != *that1.Instructions { - return fmt3.Errorf("Instructions this(%v) Not Equal that(%v)", *this.Instructions, *that1.Instructions) - } - } else if this.Instructions != nil { - return fmt3.Errorf("this.Instructions == nil && that.Instructions != nil") - } else if that1.Instructions != nil { - return fmt3.Errorf("Instructions this(%v) Not Equal that(%v)", this.Instructions, that1.Instructions) + s := strings.Join([]string{`&CommandInfo{`, + `Uris:` + strings.Replace(fmt.Sprintf("%v", this.Uris), "CommandInfo_URI", "CommandInfo_URI", 1) + `,`, + `Environment:` + strings.Replace(fmt.Sprintf("%v", this.Environment), "Environment", "Environment", 1) + `,`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `Container:` + strings.Replace(fmt.Sprintf("%v", this.Container), "CommandInfo_ContainerInfo", "CommandInfo_ContainerInfo", 1) + `,`, + `User:` + valueToStringMesos(this.User) + `,`, + `Shell:` + valueToStringMesos(this.Shell) + `,`, + `Arguments:` + fmt.Sprintf("%v", this.Arguments) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *CommandInfo_URI) String() string { + if this == nil { + return "nil" } - if this.CacheReferences != nil && that1.CacheReferences != nil { - if *this.CacheReferences != *that1.CacheReferences { - return fmt3.Errorf("CacheReferences this(%v) Not Equal that(%v)", *this.CacheReferences, *that1.CacheReferences) - } - } else if this.CacheReferences != nil { - return fmt3.Errorf("this.CacheReferences == nil && that.CacheReferences != nil") - } else if that1.CacheReferences != nil { - return fmt3.Errorf("CacheReferences this(%v) Not Equal that(%v)", this.CacheReferences, that1.CacheReferences) + s := strings.Join([]string{`&CommandInfo_URI{`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `Executable:` + valueToStringMesos(this.Executable) + `,`, + `Extract:` + valueToStringMesos(this.Extract) + `,`, + `Cache:` + valueToStringMesos(this.Cache) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *CommandInfo_ContainerInfo) String() string { + if this == nil { + return "nil" } - if this.CacheMisses != nil && that1.CacheMisses != nil { - if *this.CacheMisses != *that1.CacheMisses { - return fmt3.Errorf("CacheMisses this(%v) Not Equal that(%v)", *this.CacheMisses, *that1.CacheMisses) - } - } else if this.CacheMisses != nil { - return fmt3.Errorf("this.CacheMisses == nil && that.CacheMisses != nil") - } else if that1.CacheMisses != nil { - return fmt3.Errorf("CacheMisses this(%v) Not Equal that(%v)", this.CacheMisses, that1.CacheMisses) + s := strings.Join([]string{`&CommandInfo_ContainerInfo{`, + `Image:` + valueToStringMesos(this.Image) + `,`, + `Options:` + fmt.Sprintf("%v", this.Options) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ExecutorInfo) String() string { + if this == nil { + return "nil" } - if this.Branches != nil && that1.Branches != nil { - if *this.Branches != *that1.Branches { - return fmt3.Errorf("Branches this(%v) Not Equal that(%v)", *this.Branches, *that1.Branches) - } - } else if this.Branches != nil { - return fmt3.Errorf("this.Branches == nil && that.Branches != nil") - } else if that1.Branches != nil { - return fmt3.Errorf("Branches this(%v) Not Equal that(%v)", this.Branches, that1.Branches) + s := strings.Join([]string{`&ExecutorInfo{`, + `ExecutorId:` + strings.Replace(fmt.Sprintf("%v", this.ExecutorId), "ExecutorID", "ExecutorID", 1) + `,`, + `Data:` + valueToStringMesos(this.Data) + `,`, + `Resources:` + strings.Replace(fmt.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, + `Command:` + strings.Replace(fmt.Sprintf("%v", this.Command), "CommandInfo", "CommandInfo", 1) + `,`, + `FrameworkId:` + strings.Replace(fmt.Sprintf("%v", this.FrameworkId), "FrameworkID", "FrameworkID", 1) + `,`, + `Name:` + valueToStringMesos(this.Name) + `,`, + `Source:` + valueToStringMesos(this.Source) + `,`, + `Container:` + strings.Replace(fmt.Sprintf("%v", this.Container), "ContainerInfo", "ContainerInfo", 1) + `,`, + `Discovery:` + strings.Replace(fmt.Sprintf("%v", this.Discovery), "DiscoveryInfo", "DiscoveryInfo", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *MasterInfo) String() string { + if this == nil { + return "nil" } - if this.BranchMisses != nil && that1.BranchMisses != nil { - if *this.BranchMisses != *that1.BranchMisses { - return fmt3.Errorf("BranchMisses this(%v) Not Equal that(%v)", *this.BranchMisses, *that1.BranchMisses) - } - } else if this.BranchMisses != nil { - return fmt3.Errorf("this.BranchMisses == nil && that.BranchMisses != nil") - } else if that1.BranchMisses != nil { - return fmt3.Errorf("BranchMisses this(%v) Not Equal that(%v)", this.BranchMisses, that1.BranchMisses) + s := strings.Join([]string{`&MasterInfo{`, + `Id:` + valueToStringMesos(this.Id) + `,`, + `Ip:` + valueToStringMesos(this.Ip) + `,`, + `Port:` + valueToStringMesos(this.Port) + `,`, + `Pid:` + valueToStringMesos(this.Pid) + `,`, + `Hostname:` + valueToStringMesos(this.Hostname) + `,`, + `Version:` + valueToStringMesos(this.Version) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *SlaveInfo) String() string { + if this == nil { + return "nil" } - if this.BusCycles != nil && that1.BusCycles != nil { - if *this.BusCycles != *that1.BusCycles { - return fmt3.Errorf("BusCycles this(%v) Not Equal that(%v)", *this.BusCycles, *that1.BusCycles) - } - } else if this.BusCycles != nil { - return fmt3.Errorf("this.BusCycles == nil && that.BusCycles != nil") - } else if that1.BusCycles != nil { - return fmt3.Errorf("BusCycles this(%v) Not Equal that(%v)", this.BusCycles, that1.BusCycles) + s := strings.Join([]string{`&SlaveInfo{`, + `Hostname:` + valueToStringMesos(this.Hostname) + `,`, + `Resources:` + strings.Replace(fmt.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, + `Attributes:` + strings.Replace(fmt.Sprintf("%v", this.Attributes), "Attribute", "Attribute", 1) + `,`, + `Id:` + strings.Replace(fmt.Sprintf("%v", this.Id), "SlaveID", "SlaveID", 1) + `,`, + `Checkpoint:` + valueToStringMesos(this.Checkpoint) + `,`, + `Port:` + valueToStringMesos(this.Port) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Value) String() string { + if this == nil { + return "nil" } - if this.RefCycles != nil && that1.RefCycles != nil { - if *this.RefCycles != *that1.RefCycles { - return fmt3.Errorf("RefCycles this(%v) Not Equal that(%v)", *this.RefCycles, *that1.RefCycles) - } - } else if this.RefCycles != nil { - return fmt3.Errorf("this.RefCycles == nil && that.RefCycles != nil") - } else if that1.RefCycles != nil { - return fmt3.Errorf("RefCycles this(%v) Not Equal that(%v)", this.RefCycles, that1.RefCycles) + s := strings.Join([]string{`&Value{`, + `Type:` + valueToStringMesos(this.Type) + `,`, + `Scalar:` + strings.Replace(fmt.Sprintf("%v", this.Scalar), "Value_Scalar", "Value_Scalar", 1) + `,`, + `Ranges:` + strings.Replace(fmt.Sprintf("%v", this.Ranges), "Value_Ranges", "Value_Ranges", 1) + `,`, + `Set:` + strings.Replace(fmt.Sprintf("%v", this.Set), "Value_Set", "Value_Set", 1) + `,`, + `Text:` + strings.Replace(fmt.Sprintf("%v", this.Text), "Value_Text", "Value_Text", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Value_Scalar) String() string { + if this == nil { + return "nil" } - if this.CpuClock != nil && that1.CpuClock != nil { - if *this.CpuClock != *that1.CpuClock { - return fmt3.Errorf("CpuClock this(%v) Not Equal that(%v)", *this.CpuClock, *that1.CpuClock) - } - } else if this.CpuClock != nil { - return fmt3.Errorf("this.CpuClock == nil && that.CpuClock != nil") - } else if that1.CpuClock != nil { - return fmt3.Errorf("CpuClock this(%v) Not Equal that(%v)", this.CpuClock, that1.CpuClock) + s := strings.Join([]string{`&Value_Scalar{`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Value_Range) String() string { + if this == nil { + return "nil" } - if this.TaskClock != nil && that1.TaskClock != nil { - if *this.TaskClock != *that1.TaskClock { - return fmt3.Errorf("TaskClock this(%v) Not Equal that(%v)", *this.TaskClock, *that1.TaskClock) - } - } else if this.TaskClock != nil { - return fmt3.Errorf("this.TaskClock == nil && that.TaskClock != nil") - } else if that1.TaskClock != nil { - return fmt3.Errorf("TaskClock this(%v) Not Equal that(%v)", this.TaskClock, that1.TaskClock) + s := strings.Join([]string{`&Value_Range{`, + `Begin:` + valueToStringMesos(this.Begin) + `,`, + `End:` + valueToStringMesos(this.End) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Value_Ranges) String() string { + if this == nil { + return "nil" } - if this.PageFaults != nil && that1.PageFaults != nil { - if *this.PageFaults != *that1.PageFaults { - return fmt3.Errorf("PageFaults this(%v) Not Equal that(%v)", *this.PageFaults, *that1.PageFaults) - } - } else if this.PageFaults != nil { - return fmt3.Errorf("this.PageFaults == nil && that.PageFaults != nil") - } else if that1.PageFaults != nil { - return fmt3.Errorf("PageFaults this(%v) Not Equal that(%v)", this.PageFaults, that1.PageFaults) + s := strings.Join([]string{`&Value_Ranges{`, + `Range:` + strings.Replace(fmt.Sprintf("%v", this.Range), "Value_Range", "Value_Range", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Value_Set) String() string { + if this == nil { + return "nil" } - if this.MinorFaults != nil && that1.MinorFaults != nil { - if *this.MinorFaults != *that1.MinorFaults { - return fmt3.Errorf("MinorFaults this(%v) Not Equal that(%v)", *this.MinorFaults, *that1.MinorFaults) - } - } else if this.MinorFaults != nil { - return fmt3.Errorf("this.MinorFaults == nil && that.MinorFaults != nil") - } else if that1.MinorFaults != nil { - return fmt3.Errorf("MinorFaults this(%v) Not Equal that(%v)", this.MinorFaults, that1.MinorFaults) + s := strings.Join([]string{`&Value_Set{`, + `Item:` + fmt.Sprintf("%v", this.Item) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Value_Text) String() string { + if this == nil { + return "nil" } - if this.MajorFaults != nil && that1.MajorFaults != nil { - if *this.MajorFaults != *that1.MajorFaults { - return fmt3.Errorf("MajorFaults this(%v) Not Equal that(%v)", *this.MajorFaults, *that1.MajorFaults) - } - } else if this.MajorFaults != nil { - return fmt3.Errorf("this.MajorFaults == nil && that.MajorFaults != nil") - } else if that1.MajorFaults != nil { - return fmt3.Errorf("MajorFaults this(%v) Not Equal that(%v)", this.MajorFaults, that1.MajorFaults) + s := strings.Join([]string{`&Value_Text{`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Attribute) String() string { + if this == nil { + return "nil" } - if this.ContextSwitches != nil && that1.ContextSwitches != nil { - if *this.ContextSwitches != *that1.ContextSwitches { - return fmt3.Errorf("ContextSwitches this(%v) Not Equal that(%v)", *this.ContextSwitches, *that1.ContextSwitches) - } - } else if this.ContextSwitches != nil { - return fmt3.Errorf("this.ContextSwitches == nil && that.ContextSwitches != nil") - } else if that1.ContextSwitches != nil { - return fmt3.Errorf("ContextSwitches this(%v) Not Equal that(%v)", this.ContextSwitches, that1.ContextSwitches) + s := strings.Join([]string{`&Attribute{`, + `Name:` + valueToStringMesos(this.Name) + `,`, + `Type:` + valueToStringMesos(this.Type) + `,`, + `Scalar:` + strings.Replace(fmt.Sprintf("%v", this.Scalar), "Value_Scalar", "Value_Scalar", 1) + `,`, + `Ranges:` + strings.Replace(fmt.Sprintf("%v", this.Ranges), "Value_Ranges", "Value_Ranges", 1) + `,`, + `Text:` + strings.Replace(fmt.Sprintf("%v", this.Text), "Value_Text", "Value_Text", 1) + `,`, + `Set:` + strings.Replace(fmt.Sprintf("%v", this.Set), "Value_Set", "Value_Set", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Resource) String() string { + if this == nil { + return "nil" } - if this.CpuMigrations != nil && that1.CpuMigrations != nil { - if *this.CpuMigrations != *that1.CpuMigrations { - return fmt3.Errorf("CpuMigrations this(%v) Not Equal that(%v)", *this.CpuMigrations, *that1.CpuMigrations) - } - } else if this.CpuMigrations != nil { - return fmt3.Errorf("this.CpuMigrations == nil && that.CpuMigrations != nil") - } else if that1.CpuMigrations != nil { - return fmt3.Errorf("CpuMigrations this(%v) Not Equal that(%v)", this.CpuMigrations, that1.CpuMigrations) + s := strings.Join([]string{`&Resource{`, + `Name:` + valueToStringMesos(this.Name) + `,`, + `Type:` + valueToStringMesos(this.Type) + `,`, + `Scalar:` + strings.Replace(fmt.Sprintf("%v", this.Scalar), "Value_Scalar", "Value_Scalar", 1) + `,`, + `Ranges:` + strings.Replace(fmt.Sprintf("%v", this.Ranges), "Value_Ranges", "Value_Ranges", 1) + `,`, + `Set:` + strings.Replace(fmt.Sprintf("%v", this.Set), "Value_Set", "Value_Set", 1) + `,`, + `Role:` + valueToStringMesos(this.Role) + `,`, + `Disk:` + strings.Replace(fmt.Sprintf("%v", this.Disk), "Resource_DiskInfo", "Resource_DiskInfo", 1) + `,`, + `Reservation:` + strings.Replace(fmt.Sprintf("%v", this.Reservation), "Resource_ReservationInfo", "Resource_ReservationInfo", 1) + `,`, + `Revocable:` + strings.Replace(fmt.Sprintf("%v", this.Revocable), "Resource_RevocableInfo", "Resource_RevocableInfo", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Resource_ReservationInfo) String() string { + if this == nil { + return "nil" } - if this.AlignmentFaults != nil && that1.AlignmentFaults != nil { - if *this.AlignmentFaults != *that1.AlignmentFaults { - return fmt3.Errorf("AlignmentFaults this(%v) Not Equal that(%v)", *this.AlignmentFaults, *that1.AlignmentFaults) - } - } else if this.AlignmentFaults != nil { - return fmt3.Errorf("this.AlignmentFaults == nil && that.AlignmentFaults != nil") - } else if that1.AlignmentFaults != nil { - return fmt3.Errorf("AlignmentFaults this(%v) Not Equal that(%v)", this.AlignmentFaults, that1.AlignmentFaults) + s := strings.Join([]string{`&Resource_ReservationInfo{`, + `Principal:` + valueToStringMesos(this.Principal) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Resource_DiskInfo) String() string { + if this == nil { + return "nil" } - if this.EmulationFaults != nil && that1.EmulationFaults != nil { - if *this.EmulationFaults != *that1.EmulationFaults { - return fmt3.Errorf("EmulationFaults this(%v) Not Equal that(%v)", *this.EmulationFaults, *that1.EmulationFaults) - } - } else if this.EmulationFaults != nil { - return fmt3.Errorf("this.EmulationFaults == nil && that.EmulationFaults != nil") - } else if that1.EmulationFaults != nil { - return fmt3.Errorf("EmulationFaults this(%v) Not Equal that(%v)", this.EmulationFaults, that1.EmulationFaults) + s := strings.Join([]string{`&Resource_DiskInfo{`, + `Persistence:` + strings.Replace(fmt.Sprintf("%v", this.Persistence), "Resource_DiskInfo_Persistence", "Resource_DiskInfo_Persistence", 1) + `,`, + `Volume:` + strings.Replace(fmt.Sprintf("%v", this.Volume), "Volume", "Volume", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Resource_DiskInfo_Persistence) String() string { + if this == nil { + return "nil" } - if this.L1DcacheLoads != nil && that1.L1DcacheLoads != nil { - if *this.L1DcacheLoads != *that1.L1DcacheLoads { - return fmt3.Errorf("L1DcacheLoads this(%v) Not Equal that(%v)", *this.L1DcacheLoads, *that1.L1DcacheLoads) - } - } else if this.L1DcacheLoads != nil { - return fmt3.Errorf("this.L1DcacheLoads == nil && that.L1DcacheLoads != nil") - } else if that1.L1DcacheLoads != nil { - return fmt3.Errorf("L1DcacheLoads this(%v) Not Equal that(%v)", this.L1DcacheLoads, that1.L1DcacheLoads) + s := strings.Join([]string{`&Resource_DiskInfo_Persistence{`, + `Id:` + valueToStringMesos(this.Id) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Resource_RevocableInfo) String() string { + if this == nil { + return "nil" } - if this.L1DcacheLoadMisses != nil && that1.L1DcacheLoadMisses != nil { - if *this.L1DcacheLoadMisses != *that1.L1DcacheLoadMisses { - return fmt3.Errorf("L1DcacheLoadMisses this(%v) Not Equal that(%v)", *this.L1DcacheLoadMisses, *that1.L1DcacheLoadMisses) - } - } else if this.L1DcacheLoadMisses != nil { - return fmt3.Errorf("this.L1DcacheLoadMisses == nil && that.L1DcacheLoadMisses != nil") - } else if that1.L1DcacheLoadMisses != nil { - return fmt3.Errorf("L1DcacheLoadMisses this(%v) Not Equal that(%v)", this.L1DcacheLoadMisses, that1.L1DcacheLoadMisses) + s := strings.Join([]string{`&Resource_RevocableInfo{`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *TrafficControlStatistics) String() string { + if this == nil { + return "nil" } - if this.L1DcacheStores != nil && that1.L1DcacheStores != nil { - if *this.L1DcacheStores != *that1.L1DcacheStores { - return fmt3.Errorf("L1DcacheStores this(%v) Not Equal that(%v)", *this.L1DcacheStores, *that1.L1DcacheStores) - } - } else if this.L1DcacheStores != nil { - return fmt3.Errorf("this.L1DcacheStores == nil && that.L1DcacheStores != nil") - } else if that1.L1DcacheStores != nil { - return fmt3.Errorf("L1DcacheStores this(%v) Not Equal that(%v)", this.L1DcacheStores, that1.L1DcacheStores) + s := strings.Join([]string{`&TrafficControlStatistics{`, + `Id:` + valueToStringMesos(this.Id) + `,`, + `Backlog:` + valueToStringMesos(this.Backlog) + `,`, + `Bytes:` + valueToStringMesos(this.Bytes) + `,`, + `Drops:` + valueToStringMesos(this.Drops) + `,`, + `Overlimits:` + valueToStringMesos(this.Overlimits) + `,`, + `Packets:` + valueToStringMesos(this.Packets) + `,`, + `Qlen:` + valueToStringMesos(this.Qlen) + `,`, + `Ratebps:` + valueToStringMesos(this.Ratebps) + `,`, + `Ratepps:` + valueToStringMesos(this.Ratepps) + `,`, + `Requeues:` + valueToStringMesos(this.Requeues) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceStatistics) String() string { + if this == nil { + return "nil" } - if this.L1DcacheStoreMisses != nil && that1.L1DcacheStoreMisses != nil { - if *this.L1DcacheStoreMisses != *that1.L1DcacheStoreMisses { - return fmt3.Errorf("L1DcacheStoreMisses this(%v) Not Equal that(%v)", *this.L1DcacheStoreMisses, *that1.L1DcacheStoreMisses) - } - } else if this.L1DcacheStoreMisses != nil { - return fmt3.Errorf("this.L1DcacheStoreMisses == nil && that.L1DcacheStoreMisses != nil") - } else if that1.L1DcacheStoreMisses != nil { - return fmt3.Errorf("L1DcacheStoreMisses this(%v) Not Equal that(%v)", this.L1DcacheStoreMisses, that1.L1DcacheStoreMisses) + s := strings.Join([]string{`&ResourceStatistics{`, + `Timestamp:` + valueToStringMesos(this.Timestamp) + `,`, + `CpusUserTimeSecs:` + valueToStringMesos(this.CpusUserTimeSecs) + `,`, + `CpusSystemTimeSecs:` + valueToStringMesos(this.CpusSystemTimeSecs) + `,`, + `CpusLimit:` + valueToStringMesos(this.CpusLimit) + `,`, + `MemRssBytes:` + valueToStringMesos(this.MemRssBytes) + `,`, + `MemLimitBytes:` + valueToStringMesos(this.MemLimitBytes) + `,`, + `CpusNrPeriods:` + valueToStringMesos(this.CpusNrPeriods) + `,`, + `CpusNrThrottled:` + valueToStringMesos(this.CpusNrThrottled) + `,`, + `CpusThrottledTimeSecs:` + valueToStringMesos(this.CpusThrottledTimeSecs) + `,`, + `MemFileBytes:` + valueToStringMesos(this.MemFileBytes) + `,`, + `MemAnonBytes:` + valueToStringMesos(this.MemAnonBytes) + `,`, + `MemMappedFileBytes:` + valueToStringMesos(this.MemMappedFileBytes) + `,`, + `Perf:` + strings.Replace(fmt.Sprintf("%v", this.Perf), "PerfStatistics", "PerfStatistics", 1) + `,`, + `NetRxPackets:` + valueToStringMesos(this.NetRxPackets) + `,`, + `NetRxBytes:` + valueToStringMesos(this.NetRxBytes) + `,`, + `NetRxErrors:` + valueToStringMesos(this.NetRxErrors) + `,`, + `NetRxDropped:` + valueToStringMesos(this.NetRxDropped) + `,`, + `NetTxPackets:` + valueToStringMesos(this.NetTxPackets) + `,`, + `NetTxBytes:` + valueToStringMesos(this.NetTxBytes) + `,`, + `NetTxErrors:` + valueToStringMesos(this.NetTxErrors) + `,`, + `NetTxDropped:` + valueToStringMesos(this.NetTxDropped) + `,`, + `NetTcpRttMicrosecsP50:` + valueToStringMesos(this.NetTcpRttMicrosecsP50) + `,`, + `NetTcpRttMicrosecsP90:` + valueToStringMesos(this.NetTcpRttMicrosecsP90) + `,`, + `NetTcpRttMicrosecsP95:` + valueToStringMesos(this.NetTcpRttMicrosecsP95) + `,`, + `NetTcpRttMicrosecsP99:` + valueToStringMesos(this.NetTcpRttMicrosecsP99) + `,`, + `DiskLimitBytes:` + valueToStringMesos(this.DiskLimitBytes) + `,`, + `DiskUsedBytes:` + valueToStringMesos(this.DiskUsedBytes) + `,`, + `NetTcpActiveConnections:` + valueToStringMesos(this.NetTcpActiveConnections) + `,`, + `NetTcpTimeWaitConnections:` + valueToStringMesos(this.NetTcpTimeWaitConnections) + `,`, + `Processes:` + valueToStringMesos(this.Processes) + `,`, + `Threads:` + valueToStringMesos(this.Threads) + `,`, + `MemLowPressureCounter:` + valueToStringMesos(this.MemLowPressureCounter) + `,`, + `MemMediumPressureCounter:` + valueToStringMesos(this.MemMediumPressureCounter) + `,`, + `MemCriticalPressureCounter:` + valueToStringMesos(this.MemCriticalPressureCounter) + `,`, + `NetTrafficControlStatistics:` + strings.Replace(fmt.Sprintf("%v", this.NetTrafficControlStatistics), "TrafficControlStatistics", "TrafficControlStatistics", 1) + `,`, + `MemTotalBytes:` + valueToStringMesos(this.MemTotalBytes) + `,`, + `MemTotalMemswBytes:` + valueToStringMesos(this.MemTotalMemswBytes) + `,`, + `MemSoftLimitBytes:` + valueToStringMesos(this.MemSoftLimitBytes) + `,`, + `MemCacheBytes:` + valueToStringMesos(this.MemCacheBytes) + `,`, + `MemSwapBytes:` + valueToStringMesos(this.MemSwapBytes) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceUsage) String() string { + if this == nil { + return "nil" } - if this.L1DcachePrefetches != nil && that1.L1DcachePrefetches != nil { - if *this.L1DcachePrefetches != *that1.L1DcachePrefetches { - return fmt3.Errorf("L1DcachePrefetches this(%v) Not Equal that(%v)", *this.L1DcachePrefetches, *that1.L1DcachePrefetches) - } - } else if this.L1DcachePrefetches != nil { - return fmt3.Errorf("this.L1DcachePrefetches == nil && that.L1DcachePrefetches != nil") - } else if that1.L1DcachePrefetches != nil { - return fmt3.Errorf("L1DcachePrefetches this(%v) Not Equal that(%v)", this.L1DcachePrefetches, that1.L1DcachePrefetches) + s := strings.Join([]string{`&ResourceUsage{`, + `Executors:` + strings.Replace(fmt.Sprintf("%v", this.Executors), "ResourceUsage_Executor", "ResourceUsage_Executor", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceUsage_Executor) String() string { + if this == nil { + return "nil" } - if this.L1DcachePrefetchMisses != nil && that1.L1DcachePrefetchMisses != nil { - if *this.L1DcachePrefetchMisses != *that1.L1DcachePrefetchMisses { - return fmt3.Errorf("L1DcachePrefetchMisses this(%v) Not Equal that(%v)", *this.L1DcachePrefetchMisses, *that1.L1DcachePrefetchMisses) - } - } else if this.L1DcachePrefetchMisses != nil { - return fmt3.Errorf("this.L1DcachePrefetchMisses == nil && that.L1DcachePrefetchMisses != nil") - } else if that1.L1DcachePrefetchMisses != nil { - return fmt3.Errorf("L1DcachePrefetchMisses this(%v) Not Equal that(%v)", this.L1DcachePrefetchMisses, that1.L1DcachePrefetchMisses) + s := strings.Join([]string{`&ResourceUsage_Executor{`, + `ExecutorInfo:` + strings.Replace(fmt.Sprintf("%v", this.ExecutorInfo), "ExecutorInfo", "ExecutorInfo", 1) + `,`, + `Allocated:` + strings.Replace(fmt.Sprintf("%v", this.Allocated), "Resource", "Resource", 1) + `,`, + `Statistics:` + strings.Replace(fmt.Sprintf("%v", this.Statistics), "ResourceStatistics", "ResourceStatistics", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *PerfStatistics) String() string { + if this == nil { + return "nil" } - if this.L1IcacheLoads != nil && that1.L1IcacheLoads != nil { - if *this.L1IcacheLoads != *that1.L1IcacheLoads { - return fmt3.Errorf("L1IcacheLoads this(%v) Not Equal that(%v)", *this.L1IcacheLoads, *that1.L1IcacheLoads) - } - } else if this.L1IcacheLoads != nil { - return fmt3.Errorf("this.L1IcacheLoads == nil && that.L1IcacheLoads != nil") - } else if that1.L1IcacheLoads != nil { - return fmt3.Errorf("L1IcacheLoads this(%v) Not Equal that(%v)", this.L1IcacheLoads, that1.L1IcacheLoads) + s := strings.Join([]string{`&PerfStatistics{`, + `Timestamp:` + valueToStringMesos(this.Timestamp) + `,`, + `Duration:` + valueToStringMesos(this.Duration) + `,`, + `Cycles:` + valueToStringMesos(this.Cycles) + `,`, + `StalledCyclesFrontend:` + valueToStringMesos(this.StalledCyclesFrontend) + `,`, + `StalledCyclesBackend:` + valueToStringMesos(this.StalledCyclesBackend) + `,`, + `Instructions:` + valueToStringMesos(this.Instructions) + `,`, + `CacheReferences:` + valueToStringMesos(this.CacheReferences) + `,`, + `CacheMisses:` + valueToStringMesos(this.CacheMisses) + `,`, + `Branches:` + valueToStringMesos(this.Branches) + `,`, + `BranchMisses:` + valueToStringMesos(this.BranchMisses) + `,`, + `BusCycles:` + valueToStringMesos(this.BusCycles) + `,`, + `RefCycles:` + valueToStringMesos(this.RefCycles) + `,`, + `CpuClock:` + valueToStringMesos(this.CpuClock) + `,`, + `TaskClock:` + valueToStringMesos(this.TaskClock) + `,`, + `PageFaults:` + valueToStringMesos(this.PageFaults) + `,`, + `MinorFaults:` + valueToStringMesos(this.MinorFaults) + `,`, + `MajorFaults:` + valueToStringMesos(this.MajorFaults) + `,`, + `ContextSwitches:` + valueToStringMesos(this.ContextSwitches) + `,`, + `CpuMigrations:` + valueToStringMesos(this.CpuMigrations) + `,`, + `AlignmentFaults:` + valueToStringMesos(this.AlignmentFaults) + `,`, + `EmulationFaults:` + valueToStringMesos(this.EmulationFaults) + `,`, + `L1DcacheLoads:` + valueToStringMesos(this.L1DcacheLoads) + `,`, + `L1DcacheLoadMisses:` + valueToStringMesos(this.L1DcacheLoadMisses) + `,`, + `L1DcacheStores:` + valueToStringMesos(this.L1DcacheStores) + `,`, + `L1DcacheStoreMisses:` + valueToStringMesos(this.L1DcacheStoreMisses) + `,`, + `L1DcachePrefetches:` + valueToStringMesos(this.L1DcachePrefetches) + `,`, + `L1DcachePrefetchMisses:` + valueToStringMesos(this.L1DcachePrefetchMisses) + `,`, + `L1IcacheLoads:` + valueToStringMesos(this.L1IcacheLoads) + `,`, + `L1IcacheLoadMisses:` + valueToStringMesos(this.L1IcacheLoadMisses) + `,`, + `L1IcachePrefetches:` + valueToStringMesos(this.L1IcachePrefetches) + `,`, + `L1IcachePrefetchMisses:` + valueToStringMesos(this.L1IcachePrefetchMisses) + `,`, + `LlcLoads:` + valueToStringMesos(this.LlcLoads) + `,`, + `LlcLoadMisses:` + valueToStringMesos(this.LlcLoadMisses) + `,`, + `LlcStores:` + valueToStringMesos(this.LlcStores) + `,`, + `LlcStoreMisses:` + valueToStringMesos(this.LlcStoreMisses) + `,`, + `LlcPrefetches:` + valueToStringMesos(this.LlcPrefetches) + `,`, + `LlcPrefetchMisses:` + valueToStringMesos(this.LlcPrefetchMisses) + `,`, + `DtlbLoads:` + valueToStringMesos(this.DtlbLoads) + `,`, + `DtlbLoadMisses:` + valueToStringMesos(this.DtlbLoadMisses) + `,`, + `DtlbStores:` + valueToStringMesos(this.DtlbStores) + `,`, + `DtlbStoreMisses:` + valueToStringMesos(this.DtlbStoreMisses) + `,`, + `DtlbPrefetches:` + valueToStringMesos(this.DtlbPrefetches) + `,`, + `DtlbPrefetchMisses:` + valueToStringMesos(this.DtlbPrefetchMisses) + `,`, + `ItlbLoads:` + valueToStringMesos(this.ItlbLoads) + `,`, + `ItlbLoadMisses:` + valueToStringMesos(this.ItlbLoadMisses) + `,`, + `BranchLoads:` + valueToStringMesos(this.BranchLoads) + `,`, + `BranchLoadMisses:` + valueToStringMesos(this.BranchLoadMisses) + `,`, + `NodeLoads:` + valueToStringMesos(this.NodeLoads) + `,`, + `NodeLoadMisses:` + valueToStringMesos(this.NodeLoadMisses) + `,`, + `NodeStores:` + valueToStringMesos(this.NodeStores) + `,`, + `NodeStoreMisses:` + valueToStringMesos(this.NodeStoreMisses) + `,`, + `NodePrefetches:` + valueToStringMesos(this.NodePrefetches) + `,`, + `NodePrefetchMisses:` + valueToStringMesos(this.NodePrefetchMisses) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Request) String() string { + if this == nil { + return "nil" } - if this.L1IcacheLoadMisses != nil && that1.L1IcacheLoadMisses != nil { - if *this.L1IcacheLoadMisses != *that1.L1IcacheLoadMisses { - return fmt3.Errorf("L1IcacheLoadMisses this(%v) Not Equal that(%v)", *this.L1IcacheLoadMisses, *that1.L1IcacheLoadMisses) - } - } else if this.L1IcacheLoadMisses != nil { - return fmt3.Errorf("this.L1IcacheLoadMisses == nil && that.L1IcacheLoadMisses != nil") - } else if that1.L1IcacheLoadMisses != nil { - return fmt3.Errorf("L1IcacheLoadMisses this(%v) Not Equal that(%v)", this.L1IcacheLoadMisses, that1.L1IcacheLoadMisses) + s := strings.Join([]string{`&Request{`, + `SlaveId:` + strings.Replace(fmt.Sprintf("%v", this.SlaveId), "SlaveID", "SlaveID", 1) + `,`, + `Resources:` + strings.Replace(fmt.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Offer) String() string { + if this == nil { + return "nil" } - if this.L1IcachePrefetches != nil && that1.L1IcachePrefetches != nil { - if *this.L1IcachePrefetches != *that1.L1IcachePrefetches { - return fmt3.Errorf("L1IcachePrefetches this(%v) Not Equal that(%v)", *this.L1IcachePrefetches, *that1.L1IcachePrefetches) - } - } else if this.L1IcachePrefetches != nil { - return fmt3.Errorf("this.L1IcachePrefetches == nil && that.L1IcachePrefetches != nil") - } else if that1.L1IcachePrefetches != nil { - return fmt3.Errorf("L1IcachePrefetches this(%v) Not Equal that(%v)", this.L1IcachePrefetches, that1.L1IcachePrefetches) + s := strings.Join([]string{`&Offer{`, + `Id:` + strings.Replace(fmt.Sprintf("%v", this.Id), "OfferID", "OfferID", 1) + `,`, + `FrameworkId:` + strings.Replace(fmt.Sprintf("%v", this.FrameworkId), "FrameworkID", "FrameworkID", 1) + `,`, + `SlaveId:` + strings.Replace(fmt.Sprintf("%v", this.SlaveId), "SlaveID", "SlaveID", 1) + `,`, + `Hostname:` + valueToStringMesos(this.Hostname) + `,`, + `Resources:` + strings.Replace(fmt.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, + `ExecutorIds:` + strings.Replace(fmt.Sprintf("%v", this.ExecutorIds), "ExecutorID", "ExecutorID", 1) + `,`, + `Attributes:` + strings.Replace(fmt.Sprintf("%v", this.Attributes), "Attribute", "Attribute", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Offer_Operation) String() string { + if this == nil { + return "nil" } - if this.L1IcachePrefetchMisses != nil && that1.L1IcachePrefetchMisses != nil { - if *this.L1IcachePrefetchMisses != *that1.L1IcachePrefetchMisses { - return fmt3.Errorf("L1IcachePrefetchMisses this(%v) Not Equal that(%v)", *this.L1IcachePrefetchMisses, *that1.L1IcachePrefetchMisses) - } - } else if this.L1IcachePrefetchMisses != nil { - return fmt3.Errorf("this.L1IcachePrefetchMisses == nil && that.L1IcachePrefetchMisses != nil") - } else if that1.L1IcachePrefetchMisses != nil { - return fmt3.Errorf("L1IcachePrefetchMisses this(%v) Not Equal that(%v)", this.L1IcachePrefetchMisses, that1.L1IcachePrefetchMisses) + s := strings.Join([]string{`&Offer_Operation{`, + `Type:` + valueToStringMesos(this.Type) + `,`, + `Launch:` + strings.Replace(fmt.Sprintf("%v", this.Launch), "Offer_Operation_Launch", "Offer_Operation_Launch", 1) + `,`, + `Reserve:` + strings.Replace(fmt.Sprintf("%v", this.Reserve), "Offer_Operation_Reserve", "Offer_Operation_Reserve", 1) + `,`, + `Unreserve:` + strings.Replace(fmt.Sprintf("%v", this.Unreserve), "Offer_Operation_Unreserve", "Offer_Operation_Unreserve", 1) + `,`, + `Create:` + strings.Replace(fmt.Sprintf("%v", this.Create), "Offer_Operation_Create", "Offer_Operation_Create", 1) + `,`, + `Destroy:` + strings.Replace(fmt.Sprintf("%v", this.Destroy), "Offer_Operation_Destroy", "Offer_Operation_Destroy", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Offer_Operation_Launch) String() string { + if this == nil { + return "nil" } - if this.LlcLoads != nil && that1.LlcLoads != nil { - if *this.LlcLoads != *that1.LlcLoads { - return fmt3.Errorf("LlcLoads this(%v) Not Equal that(%v)", *this.LlcLoads, *that1.LlcLoads) - } - } else if this.LlcLoads != nil { - return fmt3.Errorf("this.LlcLoads == nil && that.LlcLoads != nil") - } else if that1.LlcLoads != nil { - return fmt3.Errorf("LlcLoads this(%v) Not Equal that(%v)", this.LlcLoads, that1.LlcLoads) + s := strings.Join([]string{`&Offer_Operation_Launch{`, + `TaskInfos:` + strings.Replace(fmt.Sprintf("%v", this.TaskInfos), "TaskInfo", "TaskInfo", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Offer_Operation_Reserve) String() string { + if this == nil { + return "nil" } - if this.LlcLoadMisses != nil && that1.LlcLoadMisses != nil { - if *this.LlcLoadMisses != *that1.LlcLoadMisses { - return fmt3.Errorf("LlcLoadMisses this(%v) Not Equal that(%v)", *this.LlcLoadMisses, *that1.LlcLoadMisses) - } - } else if this.LlcLoadMisses != nil { - return fmt3.Errorf("this.LlcLoadMisses == nil && that.LlcLoadMisses != nil") - } else if that1.LlcLoadMisses != nil { - return fmt3.Errorf("LlcLoadMisses this(%v) Not Equal that(%v)", this.LlcLoadMisses, that1.LlcLoadMisses) + s := strings.Join([]string{`&Offer_Operation_Reserve{`, + `Resources:` + strings.Replace(fmt.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Offer_Operation_Unreserve) String() string { + if this == nil { + return "nil" } - if this.LlcStores != nil && that1.LlcStores != nil { - if *this.LlcStores != *that1.LlcStores { - return fmt3.Errorf("LlcStores this(%v) Not Equal that(%v)", *this.LlcStores, *that1.LlcStores) - } - } else if this.LlcStores != nil { - return fmt3.Errorf("this.LlcStores == nil && that.LlcStores != nil") - } else if that1.LlcStores != nil { - return fmt3.Errorf("LlcStores this(%v) Not Equal that(%v)", this.LlcStores, that1.LlcStores) + s := strings.Join([]string{`&Offer_Operation_Unreserve{`, + `Resources:` + strings.Replace(fmt.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Offer_Operation_Create) String() string { + if this == nil { + return "nil" } - if this.LlcStoreMisses != nil && that1.LlcStoreMisses != nil { - if *this.LlcStoreMisses != *that1.LlcStoreMisses { - return fmt3.Errorf("LlcStoreMisses this(%v) Not Equal that(%v)", *this.LlcStoreMisses, *that1.LlcStoreMisses) - } - } else if this.LlcStoreMisses != nil { - return fmt3.Errorf("this.LlcStoreMisses == nil && that.LlcStoreMisses != nil") - } else if that1.LlcStoreMisses != nil { - return fmt3.Errorf("LlcStoreMisses this(%v) Not Equal that(%v)", this.LlcStoreMisses, that1.LlcStoreMisses) + s := strings.Join([]string{`&Offer_Operation_Create{`, + `Volumes:` + strings.Replace(fmt.Sprintf("%v", this.Volumes), "Resource", "Resource", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Offer_Operation_Destroy) String() string { + if this == nil { + return "nil" } - if this.LlcPrefetches != nil && that1.LlcPrefetches != nil { - if *this.LlcPrefetches != *that1.LlcPrefetches { - return fmt3.Errorf("LlcPrefetches this(%v) Not Equal that(%v)", *this.LlcPrefetches, *that1.LlcPrefetches) - } - } else if this.LlcPrefetches != nil { - return fmt3.Errorf("this.LlcPrefetches == nil && that.LlcPrefetches != nil") - } else if that1.LlcPrefetches != nil { - return fmt3.Errorf("LlcPrefetches this(%v) Not Equal that(%v)", this.LlcPrefetches, that1.LlcPrefetches) + s := strings.Join([]string{`&Offer_Operation_Destroy{`, + `Volumes:` + strings.Replace(fmt.Sprintf("%v", this.Volumes), "Resource", "Resource", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *TaskInfo) String() string { + if this == nil { + return "nil" } - if this.LlcPrefetchMisses != nil && that1.LlcPrefetchMisses != nil { - if *this.LlcPrefetchMisses != *that1.LlcPrefetchMisses { - return fmt3.Errorf("LlcPrefetchMisses this(%v) Not Equal that(%v)", *this.LlcPrefetchMisses, *that1.LlcPrefetchMisses) - } - } else if this.LlcPrefetchMisses != nil { - return fmt3.Errorf("this.LlcPrefetchMisses == nil && that.LlcPrefetchMisses != nil") - } else if that1.LlcPrefetchMisses != nil { - return fmt3.Errorf("LlcPrefetchMisses this(%v) Not Equal that(%v)", this.LlcPrefetchMisses, that1.LlcPrefetchMisses) + s := strings.Join([]string{`&TaskInfo{`, + `Name:` + valueToStringMesos(this.Name) + `,`, + `TaskId:` + strings.Replace(fmt.Sprintf("%v", this.TaskId), "TaskID", "TaskID", 1) + `,`, + `SlaveId:` + strings.Replace(fmt.Sprintf("%v", this.SlaveId), "SlaveID", "SlaveID", 1) + `,`, + `Resources:` + strings.Replace(fmt.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`, + `Executor:` + strings.Replace(fmt.Sprintf("%v", this.Executor), "ExecutorInfo", "ExecutorInfo", 1) + `,`, + `Data:` + valueToStringMesos(this.Data) + `,`, + `Command:` + strings.Replace(fmt.Sprintf("%v", this.Command), "CommandInfo", "CommandInfo", 1) + `,`, + `HealthCheck:` + strings.Replace(fmt.Sprintf("%v", this.HealthCheck), "HealthCheck", "HealthCheck", 1) + `,`, + `Container:` + strings.Replace(fmt.Sprintf("%v", this.Container), "ContainerInfo", "ContainerInfo", 1) + `,`, + `Labels:` + strings.Replace(fmt.Sprintf("%v", this.Labels), "Labels", "Labels", 1) + `,`, + `Discovery:` + strings.Replace(fmt.Sprintf("%v", this.Discovery), "DiscoveryInfo", "DiscoveryInfo", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *TaskStatus) String() string { + if this == nil { + return "nil" } - if this.DtlbLoads != nil && that1.DtlbLoads != nil { - if *this.DtlbLoads != *that1.DtlbLoads { - return fmt3.Errorf("DtlbLoads this(%v) Not Equal that(%v)", *this.DtlbLoads, *that1.DtlbLoads) - } - } else if this.DtlbLoads != nil { - return fmt3.Errorf("this.DtlbLoads == nil && that.DtlbLoads != nil") - } else if that1.DtlbLoads != nil { - return fmt3.Errorf("DtlbLoads this(%v) Not Equal that(%v)", this.DtlbLoads, that1.DtlbLoads) + s := strings.Join([]string{`&TaskStatus{`, + `TaskId:` + strings.Replace(fmt.Sprintf("%v", this.TaskId), "TaskID", "TaskID", 1) + `,`, + `State:` + valueToStringMesos(this.State) + `,`, + `Data:` + valueToStringMesos(this.Data) + `,`, + `Message:` + valueToStringMesos(this.Message) + `,`, + `SlaveId:` + strings.Replace(fmt.Sprintf("%v", this.SlaveId), "SlaveID", "SlaveID", 1) + `,`, + `Timestamp:` + valueToStringMesos(this.Timestamp) + `,`, + `ExecutorId:` + strings.Replace(fmt.Sprintf("%v", this.ExecutorId), "ExecutorID", "ExecutorID", 1) + `,`, + `Healthy:` + valueToStringMesos(this.Healthy) + `,`, + `Source:` + valueToStringMesos(this.Source) + `,`, + `Reason:` + valueToStringMesos(this.Reason) + `,`, + `Uuid:` + valueToStringMesos(this.Uuid) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Filters) String() string { + if this == nil { + return "nil" } - if this.DtlbLoadMisses != nil && that1.DtlbLoadMisses != nil { - if *this.DtlbLoadMisses != *that1.DtlbLoadMisses { - return fmt3.Errorf("DtlbLoadMisses this(%v) Not Equal that(%v)", *this.DtlbLoadMisses, *that1.DtlbLoadMisses) - } - } else if this.DtlbLoadMisses != nil { - return fmt3.Errorf("this.DtlbLoadMisses == nil && that.DtlbLoadMisses != nil") - } else if that1.DtlbLoadMisses != nil { - return fmt3.Errorf("DtlbLoadMisses this(%v) Not Equal that(%v)", this.DtlbLoadMisses, that1.DtlbLoadMisses) + s := strings.Join([]string{`&Filters{`, + `RefuseSeconds:` + valueToStringMesos(this.RefuseSeconds) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Environment) String() string { + if this == nil { + return "nil" } - if this.DtlbStores != nil && that1.DtlbStores != nil { - if *this.DtlbStores != *that1.DtlbStores { - return fmt3.Errorf("DtlbStores this(%v) Not Equal that(%v)", *this.DtlbStores, *that1.DtlbStores) - } - } else if this.DtlbStores != nil { - return fmt3.Errorf("this.DtlbStores == nil && that.DtlbStores != nil") - } else if that1.DtlbStores != nil { - return fmt3.Errorf("DtlbStores this(%v) Not Equal that(%v)", this.DtlbStores, that1.DtlbStores) + s := strings.Join([]string{`&Environment{`, + `Variables:` + strings.Replace(fmt.Sprintf("%v", this.Variables), "Environment_Variable", "Environment_Variable", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Environment_Variable) String() string { + if this == nil { + return "nil" } - if this.DtlbStoreMisses != nil && that1.DtlbStoreMisses != nil { - if *this.DtlbStoreMisses != *that1.DtlbStoreMisses { - return fmt3.Errorf("DtlbStoreMisses this(%v) Not Equal that(%v)", *this.DtlbStoreMisses, *that1.DtlbStoreMisses) - } - } else if this.DtlbStoreMisses != nil { - return fmt3.Errorf("this.DtlbStoreMisses == nil && that.DtlbStoreMisses != nil") - } else if that1.DtlbStoreMisses != nil { - return fmt3.Errorf("DtlbStoreMisses this(%v) Not Equal that(%v)", this.DtlbStoreMisses, that1.DtlbStoreMisses) + s := strings.Join([]string{`&Environment_Variable{`, + `Name:` + valueToStringMesos(this.Name) + `,`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Parameter) String() string { + if this == nil { + return "nil" } - if this.DtlbPrefetches != nil && that1.DtlbPrefetches != nil { - if *this.DtlbPrefetches != *that1.DtlbPrefetches { - return fmt3.Errorf("DtlbPrefetches this(%v) Not Equal that(%v)", *this.DtlbPrefetches, *that1.DtlbPrefetches) - } - } else if this.DtlbPrefetches != nil { - return fmt3.Errorf("this.DtlbPrefetches == nil && that.DtlbPrefetches != nil") - } else if that1.DtlbPrefetches != nil { - return fmt3.Errorf("DtlbPrefetches this(%v) Not Equal that(%v)", this.DtlbPrefetches, that1.DtlbPrefetches) + s := strings.Join([]string{`&Parameter{`, + `Key:` + valueToStringMesos(this.Key) + `,`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Parameters) String() string { + if this == nil { + return "nil" } - if this.DtlbPrefetchMisses != nil && that1.DtlbPrefetchMisses != nil { - if *this.DtlbPrefetchMisses != *that1.DtlbPrefetchMisses { - return fmt3.Errorf("DtlbPrefetchMisses this(%v) Not Equal that(%v)", *this.DtlbPrefetchMisses, *that1.DtlbPrefetchMisses) - } - } else if this.DtlbPrefetchMisses != nil { - return fmt3.Errorf("this.DtlbPrefetchMisses == nil && that.DtlbPrefetchMisses != nil") - } else if that1.DtlbPrefetchMisses != nil { - return fmt3.Errorf("DtlbPrefetchMisses this(%v) Not Equal that(%v)", this.DtlbPrefetchMisses, that1.DtlbPrefetchMisses) + s := strings.Join([]string{`&Parameters{`, + `Parameter:` + strings.Replace(fmt.Sprintf("%v", this.Parameter), "Parameter", "Parameter", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Credential) String() string { + if this == nil { + return "nil" } - if this.ItlbLoads != nil && that1.ItlbLoads != nil { - if *this.ItlbLoads != *that1.ItlbLoads { - return fmt3.Errorf("ItlbLoads this(%v) Not Equal that(%v)", *this.ItlbLoads, *that1.ItlbLoads) - } - } else if this.ItlbLoads != nil { - return fmt3.Errorf("this.ItlbLoads == nil && that.ItlbLoads != nil") - } else if that1.ItlbLoads != nil { - return fmt3.Errorf("ItlbLoads this(%v) Not Equal that(%v)", this.ItlbLoads, that1.ItlbLoads) + s := strings.Join([]string{`&Credential{`, + `Principal:` + valueToStringMesos(this.Principal) + `,`, + `Secret:` + valueToStringMesos(this.Secret) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Credentials) String() string { + if this == nil { + return "nil" } - if this.ItlbLoadMisses != nil && that1.ItlbLoadMisses != nil { - if *this.ItlbLoadMisses != *that1.ItlbLoadMisses { - return fmt3.Errorf("ItlbLoadMisses this(%v) Not Equal that(%v)", *this.ItlbLoadMisses, *that1.ItlbLoadMisses) - } - } else if this.ItlbLoadMisses != nil { - return fmt3.Errorf("this.ItlbLoadMisses == nil && that.ItlbLoadMisses != nil") - } else if that1.ItlbLoadMisses != nil { - return fmt3.Errorf("ItlbLoadMisses this(%v) Not Equal that(%v)", this.ItlbLoadMisses, that1.ItlbLoadMisses) + s := strings.Join([]string{`&Credentials{`, + `Credentials:` + strings.Replace(fmt.Sprintf("%v", this.Credentials), "Credential", "Credential", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ACL) String() string { + if this == nil { + return "nil" } - if this.BranchLoads != nil && that1.BranchLoads != nil { - if *this.BranchLoads != *that1.BranchLoads { - return fmt3.Errorf("BranchLoads this(%v) Not Equal that(%v)", *this.BranchLoads, *that1.BranchLoads) - } - } else if this.BranchLoads != nil { - return fmt3.Errorf("this.BranchLoads == nil && that.BranchLoads != nil") - } else if that1.BranchLoads != nil { - return fmt3.Errorf("BranchLoads this(%v) Not Equal that(%v)", this.BranchLoads, that1.BranchLoads) + s := strings.Join([]string{`&ACL{`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ACL_Entity) String() string { + if this == nil { + return "nil" } - if this.BranchLoadMisses != nil && that1.BranchLoadMisses != nil { - if *this.BranchLoadMisses != *that1.BranchLoadMisses { - return fmt3.Errorf("BranchLoadMisses this(%v) Not Equal that(%v)", *this.BranchLoadMisses, *that1.BranchLoadMisses) - } - } else if this.BranchLoadMisses != nil { - return fmt3.Errorf("this.BranchLoadMisses == nil && that.BranchLoadMisses != nil") - } else if that1.BranchLoadMisses != nil { - return fmt3.Errorf("BranchLoadMisses this(%v) Not Equal that(%v)", this.BranchLoadMisses, that1.BranchLoadMisses) + s := strings.Join([]string{`&ACL_Entity{`, + `Type:` + valueToStringMesos(this.Type) + `,`, + `Values:` + fmt.Sprintf("%v", this.Values) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ACL_RegisterFramework) String() string { + if this == nil { + return "nil" } - if this.NodeLoads != nil && that1.NodeLoads != nil { - if *this.NodeLoads != *that1.NodeLoads { - return fmt3.Errorf("NodeLoads this(%v) Not Equal that(%v)", *this.NodeLoads, *that1.NodeLoads) - } - } else if this.NodeLoads != nil { - return fmt3.Errorf("this.NodeLoads == nil && that.NodeLoads != nil") - } else if that1.NodeLoads != nil { - return fmt3.Errorf("NodeLoads this(%v) Not Equal that(%v)", this.NodeLoads, that1.NodeLoads) + s := strings.Join([]string{`&ACL_RegisterFramework{`, + `Principals:` + strings.Replace(fmt.Sprintf("%v", this.Principals), "ACL_Entity", "ACL_Entity", 1) + `,`, + `Roles:` + strings.Replace(fmt.Sprintf("%v", this.Roles), "ACL_Entity", "ACL_Entity", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ACL_RunTask) String() string { + if this == nil { + return "nil" } - if this.NodeLoadMisses != nil && that1.NodeLoadMisses != nil { - if *this.NodeLoadMisses != *that1.NodeLoadMisses { - return fmt3.Errorf("NodeLoadMisses this(%v) Not Equal that(%v)", *this.NodeLoadMisses, *that1.NodeLoadMisses) - } - } else if this.NodeLoadMisses != nil { - return fmt3.Errorf("this.NodeLoadMisses == nil && that.NodeLoadMisses != nil") - } else if that1.NodeLoadMisses != nil { - return fmt3.Errorf("NodeLoadMisses this(%v) Not Equal that(%v)", this.NodeLoadMisses, that1.NodeLoadMisses) + s := strings.Join([]string{`&ACL_RunTask{`, + `Principals:` + strings.Replace(fmt.Sprintf("%v", this.Principals), "ACL_Entity", "ACL_Entity", 1) + `,`, + `Users:` + strings.Replace(fmt.Sprintf("%v", this.Users), "ACL_Entity", "ACL_Entity", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ACL_ShutdownFramework) String() string { + if this == nil { + return "nil" } - if this.NodeStores != nil && that1.NodeStores != nil { - if *this.NodeStores != *that1.NodeStores { - return fmt3.Errorf("NodeStores this(%v) Not Equal that(%v)", *this.NodeStores, *that1.NodeStores) - } - } else if this.NodeStores != nil { - return fmt3.Errorf("this.NodeStores == nil && that.NodeStores != nil") - } else if that1.NodeStores != nil { - return fmt3.Errorf("NodeStores this(%v) Not Equal that(%v)", this.NodeStores, that1.NodeStores) + s := strings.Join([]string{`&ACL_ShutdownFramework{`, + `Principals:` + strings.Replace(fmt.Sprintf("%v", this.Principals), "ACL_Entity", "ACL_Entity", 1) + `,`, + `FrameworkPrincipals:` + strings.Replace(fmt.Sprintf("%v", this.FrameworkPrincipals), "ACL_Entity", "ACL_Entity", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ACLs) String() string { + if this == nil { + return "nil" } - if this.NodeStoreMisses != nil && that1.NodeStoreMisses != nil { - if *this.NodeStoreMisses != *that1.NodeStoreMisses { - return fmt3.Errorf("NodeStoreMisses this(%v) Not Equal that(%v)", *this.NodeStoreMisses, *that1.NodeStoreMisses) - } - } else if this.NodeStoreMisses != nil { - return fmt3.Errorf("this.NodeStoreMisses == nil && that.NodeStoreMisses != nil") - } else if that1.NodeStoreMisses != nil { - return fmt3.Errorf("NodeStoreMisses this(%v) Not Equal that(%v)", this.NodeStoreMisses, that1.NodeStoreMisses) + s := strings.Join([]string{`&ACLs{`, + `Permissive:` + valueToStringMesos(this.Permissive) + `,`, + `RegisterFrameworks:` + strings.Replace(fmt.Sprintf("%v", this.RegisterFrameworks), "ACL_RegisterFramework", "ACL_RegisterFramework", 1) + `,`, + `RunTasks:` + strings.Replace(fmt.Sprintf("%v", this.RunTasks), "ACL_RunTask", "ACL_RunTask", 1) + `,`, + `ShutdownFrameworks:` + strings.Replace(fmt.Sprintf("%v", this.ShutdownFrameworks), "ACL_ShutdownFramework", "ACL_ShutdownFramework", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *RateLimit) String() string { + if this == nil { + return "nil" } - if this.NodePrefetches != nil && that1.NodePrefetches != nil { - if *this.NodePrefetches != *that1.NodePrefetches { - return fmt3.Errorf("NodePrefetches this(%v) Not Equal that(%v)", *this.NodePrefetches, *that1.NodePrefetches) - } - } else if this.NodePrefetches != nil { - return fmt3.Errorf("this.NodePrefetches == nil && that.NodePrefetches != nil") - } else if that1.NodePrefetches != nil { - return fmt3.Errorf("NodePrefetches this(%v) Not Equal that(%v)", this.NodePrefetches, that1.NodePrefetches) + s := strings.Join([]string{`&RateLimit{`, + `Qps:` + valueToStringMesos(this.Qps) + `,`, + `Principal:` + valueToStringMesos(this.Principal) + `,`, + `Capacity:` + valueToStringMesos(this.Capacity) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *RateLimits) String() string { + if this == nil { + return "nil" } - if this.NodePrefetchMisses != nil && that1.NodePrefetchMisses != nil { - if *this.NodePrefetchMisses != *that1.NodePrefetchMisses { - return fmt3.Errorf("NodePrefetchMisses this(%v) Not Equal that(%v)", *this.NodePrefetchMisses, *that1.NodePrefetchMisses) - } - } else if this.NodePrefetchMisses != nil { - return fmt3.Errorf("this.NodePrefetchMisses == nil && that.NodePrefetchMisses != nil") - } else if that1.NodePrefetchMisses != nil { - return fmt3.Errorf("NodePrefetchMisses this(%v) Not Equal that(%v)", this.NodePrefetchMisses, that1.NodePrefetchMisses) + s := strings.Join([]string{`&RateLimits{`, + `Limits:` + strings.Replace(fmt.Sprintf("%v", this.Limits), "RateLimit", "RateLimit", 1) + `,`, + `AggregateDefaultQps:` + valueToStringMesos(this.AggregateDefaultQps) + `,`, + `AggregateDefaultCapacity:` + valueToStringMesos(this.AggregateDefaultCapacity) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Volume) String() string { + if this == nil { + return "nil" } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + s := strings.Join([]string{`&Volume{`, + `ContainerPath:` + valueToStringMesos(this.ContainerPath) + `,`, + `HostPath:` + valueToStringMesos(this.HostPath) + `,`, + `Mode:` + valueToStringMesos(this.Mode) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ContainerInfo) String() string { + if this == nil { + return "nil" } - return nil + s := strings.Join([]string{`&ContainerInfo{`, + `Type:` + valueToStringMesos(this.Type) + `,`, + `Volumes:` + strings.Replace(fmt.Sprintf("%v", this.Volumes), "Volume", "Volume", 1) + `,`, + `Docker:` + strings.Replace(fmt.Sprintf("%v", this.Docker), "ContainerInfo_DockerInfo", "ContainerInfo_DockerInfo", 1) + `,`, + `Hostname:` + valueToStringMesos(this.Hostname) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s } -func (this *PerfStatistics) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false +func (this *ContainerInfo_DockerInfo) String() string { + if this == nil { + return "nil" } - - that1, ok := that.(*PerfStatistics) - if !ok { - return false + s := strings.Join([]string{`&ContainerInfo_DockerInfo{`, + `Image:` + valueToStringMesos(this.Image) + `,`, + `Network:` + valueToStringMesos(this.Network) + `,`, + `PortMappings:` + strings.Replace(fmt.Sprintf("%v", this.PortMappings), "ContainerInfo_DockerInfo_PortMapping", "ContainerInfo_DockerInfo_PortMapping", 1) + `,`, + `Privileged:` + valueToStringMesos(this.Privileged) + `,`, + `Parameters:` + strings.Replace(fmt.Sprintf("%v", this.Parameters), "Parameter", "Parameter", 1) + `,`, + `ForcePullImage:` + valueToStringMesos(this.ForcePullImage) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *ContainerInfo_DockerInfo_PortMapping) String() string { + if this == nil { + return "nil" } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + s := strings.Join([]string{`&ContainerInfo_DockerInfo_PortMapping{`, + `HostPort:` + valueToStringMesos(this.HostPort) + `,`, + `ContainerPort:` + valueToStringMesos(this.ContainerPort) + `,`, + `Protocol:` + valueToStringMesos(this.Protocol) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Labels) String() string { + if this == nil { + return "nil" } - if this.Timestamp != nil && that1.Timestamp != nil { - if *this.Timestamp != *that1.Timestamp { - return false - } - } else if this.Timestamp != nil { - return false - } else if that1.Timestamp != nil { - return false + s := strings.Join([]string{`&Labels{`, + `Labels:` + strings.Replace(fmt.Sprintf("%v", this.Labels), "Label", "Label", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Label) String() string { + if this == nil { + return "nil" } - if this.Duration != nil && that1.Duration != nil { - if *this.Duration != *that1.Duration { - return false - } - } else if this.Duration != nil { - return false - } else if that1.Duration != nil { - return false + s := strings.Join([]string{`&Label{`, + `Key:` + valueToStringMesos(this.Key) + `,`, + `Value:` + valueToStringMesos(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Port) String() string { + if this == nil { + return "nil" } - if this.Cycles != nil && that1.Cycles != nil { - if *this.Cycles != *that1.Cycles { - return false - } - } else if this.Cycles != nil { - return false - } else if that1.Cycles != nil { - return false + s := strings.Join([]string{`&Port{`, + `Number:` + valueToStringMesos(this.Number) + `,`, + `Name:` + valueToStringMesos(this.Name) + `,`, + `Protocol:` + valueToStringMesos(this.Protocol) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Ports) String() string { + if this == nil { + return "nil" } - if this.StalledCyclesFrontend != nil && that1.StalledCyclesFrontend != nil { - if *this.StalledCyclesFrontend != *that1.StalledCyclesFrontend { - return false - } - } else if this.StalledCyclesFrontend != nil { - return false - } else if that1.StalledCyclesFrontend != nil { - return false + s := strings.Join([]string{`&Ports{`, + `Ports:` + strings.Replace(fmt.Sprintf("%v", this.Ports), "Port", "Port", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *DiscoveryInfo) String() string { + if this == nil { + return "nil" } - if this.StalledCyclesBackend != nil && that1.StalledCyclesBackend != nil { - if *this.StalledCyclesBackend != *that1.StalledCyclesBackend { - return false - } - } else if this.StalledCyclesBackend != nil { - return false - } else if that1.StalledCyclesBackend != nil { - return false + s := strings.Join([]string{`&DiscoveryInfo{`, + `Visibility:` + valueToStringMesos(this.Visibility) + `,`, + `Name:` + valueToStringMesos(this.Name) + `,`, + `Environment:` + valueToStringMesos(this.Environment) + `,`, + `Location:` + valueToStringMesos(this.Location) + `,`, + `Version:` + valueToStringMesos(this.Version) + `,`, + `Ports:` + strings.Replace(fmt.Sprintf("%v", this.Ports), "Ports", "Ports", 1) + `,`, + `Labels:` + strings.Replace(fmt.Sprintf("%v", this.Labels), "Labels", "Labels", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func valueToStringMesos(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" } - if this.Instructions != nil && that1.Instructions != nil { - if *this.Instructions != *that1.Instructions { - return false + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *FrameworkID) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Instructions != nil { - return false - } else if that1.Instructions != nil { - return false - } - if this.CacheReferences != nil && that1.CacheReferences != nil { - if *this.CacheReferences != *that1.CacheReferences { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.CacheReferences != nil { - return false - } else if that1.CacheReferences != nil { - return false } - if this.CacheMisses != nil && that1.CacheMisses != nil { - if *this.CacheMisses != *that1.CacheMisses { - return false - } - } else if this.CacheMisses != nil { - return false - } else if that1.CacheMisses != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") } - if this.Branches != nil && that1.Branches != nil { - if *this.Branches != *that1.Branches { - return false + + return nil +} +func (m *OfferID) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Branches != nil { - return false - } else if that1.Branches != nil { - return false - } - if this.BranchMisses != nil && that1.BranchMisses != nil { - if *this.BranchMisses != *that1.BranchMisses { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.BranchMisses != nil { - return false - } else if that1.BranchMisses != nil { - return false } - if this.BusCycles != nil && that1.BusCycles != nil { - if *this.BusCycles != *that1.BusCycles { - return false - } - } else if this.BusCycles != nil { - return false - } else if that1.BusCycles != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") } - if this.RefCycles != nil && that1.RefCycles != nil { - if *this.RefCycles != *that1.RefCycles { - return false + + return nil +} +func (m *SlaveID) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.RefCycles != nil { - return false - } else if that1.RefCycles != nil { - return false - } - if this.CpuClock != nil && that1.CpuClock != nil { - if *this.CpuClock != *that1.CpuClock { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.CpuClock != nil { - return false - } else if that1.CpuClock != nil { - return false } - if this.TaskClock != nil && that1.TaskClock != nil { - if *this.TaskClock != *that1.TaskClock { - return false - } - } else if this.TaskClock != nil { - return false - } else if that1.TaskClock != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") } - if this.PageFaults != nil && that1.PageFaults != nil { - if *this.PageFaults != *that1.PageFaults { - return false + + return nil +} +func (m *TaskID) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.PageFaults != nil { - return false - } else if that1.PageFaults != nil { - return false - } - if this.MinorFaults != nil && that1.MinorFaults != nil { - if *this.MinorFaults != *that1.MinorFaults { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.MinorFaults != nil { - return false - } else if that1.MinorFaults != nil { - return false } - if this.MajorFaults != nil && that1.MajorFaults != nil { - if *this.MajorFaults != *that1.MajorFaults { - return false - } - } else if this.MajorFaults != nil { - return false - } else if that1.MajorFaults != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") } - if this.ContextSwitches != nil && that1.ContextSwitches != nil { - if *this.ContextSwitches != *that1.ContextSwitches { - return false + + return nil +} +func (m *ExecutorID) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.ContextSwitches != nil { - return false - } else if that1.ContextSwitches != nil { - return false - } - if this.CpuMigrations != nil && that1.CpuMigrations != nil { - if *this.CpuMigrations != *that1.CpuMigrations { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.CpuMigrations != nil { - return false - } else if that1.CpuMigrations != nil { - return false } - if this.AlignmentFaults != nil && that1.AlignmentFaults != nil { - if *this.AlignmentFaults != *that1.AlignmentFaults { - return false - } - } else if this.AlignmentFaults != nil { - return false - } else if that1.AlignmentFaults != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") } - if this.EmulationFaults != nil && that1.EmulationFaults != nil { - if *this.EmulationFaults != *that1.EmulationFaults { - return false + + return nil +} +func (m *ContainerID) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.EmulationFaults != nil { - return false - } else if that1.EmulationFaults != nil { - return false - } - if this.L1DcacheLoads != nil && that1.L1DcacheLoads != nil { - if *this.L1DcacheLoads != *that1.L1DcacheLoads { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.L1DcacheLoads != nil { - return false - } else if that1.L1DcacheLoads != nil { - return false } - if this.L1DcacheLoadMisses != nil && that1.L1DcacheLoadMisses != nil { - if *this.L1DcacheLoadMisses != *that1.L1DcacheLoadMisses { - return false - } - } else if this.L1DcacheLoadMisses != nil { - return false - } else if that1.L1DcacheLoadMisses != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") } - if this.L1DcacheStores != nil && that1.L1DcacheStores != nil { - if *this.L1DcacheStores != *that1.L1DcacheStores { - return false + + return nil +} +func (m *FrameworkInfo) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.L1DcacheStores != nil { - return false - } else if that1.L1DcacheStores != nil { - return false - } - if this.L1DcacheStoreMisses != nil && that1.L1DcacheStoreMisses != nil { - if *this.L1DcacheStoreMisses != *that1.L1DcacheStoreMisses { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.User = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Id == nil { + m.Id = &FrameworkID{} + } + if err := m.Id.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field FailoverTimeout", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.FailoverTimeout = &v2 + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Checkpoint", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Checkpoint = &b + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Role = &s + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Hostname = &s + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Principal", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Principal = &s + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WebuiUrl", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.WebuiUrl = &s + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Capabilities", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Capabilities = append(m.Capabilities, &FrameworkInfo_Capability{}) + if err := m.Capabilities[len(m.Capabilities)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.L1DcacheStoreMisses != nil { - return false - } else if that1.L1DcacheStoreMisses != nil { - return false } - if this.L1DcachePrefetches != nil && that1.L1DcachePrefetches != nil { - if *this.L1DcachePrefetches != *that1.L1DcachePrefetches { - return false - } - } else if this.L1DcachePrefetches != nil { - return false - } else if that1.L1DcachePrefetches != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("user") } - if this.L1DcachePrefetchMisses != nil && that1.L1DcachePrefetchMisses != nil { - if *this.L1DcachePrefetchMisses != *that1.L1DcachePrefetchMisses { - return false - } - } else if this.L1DcachePrefetchMisses != nil { - return false - } else if that1.L1DcachePrefetchMisses != nil { - return false + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") } - if this.L1IcacheLoads != nil && that1.L1IcacheLoads != nil { - if *this.L1IcacheLoads != *that1.L1IcacheLoads { - return false + + return nil +} +func (m *FrameworkInfo_Capability) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.L1IcacheLoads != nil { - return false - } else if that1.L1IcacheLoads != nil { - return false - } - if this.L1IcacheLoadMisses != nil && that1.L1IcacheLoadMisses != nil { - if *this.L1IcacheLoadMisses != *that1.L1IcacheLoadMisses { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v FrameworkInfo_Capability_Type + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (FrameworkInfo_Capability_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.L1IcacheLoadMisses != nil { - return false - } else if that1.L1IcacheLoadMisses != nil { - return false } - if this.L1IcachePrefetches != nil && that1.L1IcachePrefetches != nil { - if *this.L1IcachePrefetches != *that1.L1IcachePrefetches { - return false - } - } else if this.L1IcachePrefetches != nil { - return false - } else if that1.L1IcachePrefetches != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") } - if this.L1IcachePrefetchMisses != nil && that1.L1IcachePrefetchMisses != nil { - if *this.L1IcachePrefetchMisses != *that1.L1IcachePrefetchMisses { - return false + + return nil +} +func (m *HealthCheck) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.L1IcachePrefetchMisses != nil { - return false - } else if that1.L1IcachePrefetchMisses != nil { - return false - } - if this.LlcLoads != nil && that1.LlcLoads != nil { - if *this.LlcLoads != *that1.LlcLoads { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Http", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Http == nil { + m.Http = &HealthCheck_HTTP{} + } + if err := m.Http.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field DelaySeconds", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.DelaySeconds = &v2 + case 3: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field IntervalSeconds", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.IntervalSeconds = &v2 + case 4: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeoutSeconds", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.TimeoutSeconds = &v2 + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsecutiveFailures", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.ConsecutiveFailures = &v + case 6: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field GracePeriodSeconds", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.GracePeriodSeconds = &v2 + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Command", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Command == nil { + m.Command = &CommandInfo{} + } + if err := m.Command.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.LlcLoads != nil { - return false - } else if that1.LlcLoads != nil { - return false } - if this.LlcLoadMisses != nil && that1.LlcLoadMisses != nil { - if *this.LlcLoadMisses != *that1.LlcLoadMisses { - return false + + return nil +} +func (m *HealthCheck_HTTP) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.LlcLoadMisses != nil { - return false - } else if that1.LlcLoadMisses != nil { - return false - } - if this.LlcStores != nil && that1.LlcStores != nil { - if *this.LlcStores != *that1.LlcStores { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Port = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Path = &s + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Statuses", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Statuses = append(m.Statuses, v) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.LlcStores != nil { - return false - } else if that1.LlcStores != nil { - return false } - if this.LlcStoreMisses != nil && that1.LlcStoreMisses != nil { - if *this.LlcStoreMisses != *that1.LlcStoreMisses { - return false - } - } else if this.LlcStoreMisses != nil { - return false - } else if that1.LlcStoreMisses != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("port") } - if this.LlcPrefetches != nil && that1.LlcPrefetches != nil { - if *this.LlcPrefetches != *that1.LlcPrefetches { - return false + + return nil +} +func (m *CommandInfo) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.LlcPrefetches != nil { - return false - } else if that1.LlcPrefetches != nil { - return false - } - if this.LlcPrefetchMisses != nil && that1.LlcPrefetchMisses != nil { - if *this.LlcPrefetchMisses != *that1.LlcPrefetchMisses { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Uris", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Uris = append(m.Uris, &CommandInfo_URI{}) + if err := m.Uris[len(m.Uris)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Environment", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Environment == nil { + m.Environment = &Environment{} + } + if err := m.Environment.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Container == nil { + m.Container = &CommandInfo_ContainerInfo{} + } + if err := m.Container.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.User = &s + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Shell", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Shell = &b + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Arguments", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Arguments = append(m.Arguments, string(data[iNdEx:postIndex])) + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.LlcPrefetchMisses != nil { - return false - } else if that1.LlcPrefetchMisses != nil { - return false } - if this.DtlbLoads != nil && that1.DtlbLoads != nil { - if *this.DtlbLoads != *that1.DtlbLoads { - return false + + return nil +} +func (m *CommandInfo_URI) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.DtlbLoads != nil { - return false - } else if that1.DtlbLoads != nil { - return false - } - if this.DtlbLoadMisses != nil && that1.DtlbLoadMisses != nil { - if *this.DtlbLoadMisses != *that1.DtlbLoadMisses { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Executable", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Executable = &b + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Extract", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Extract = &b + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Cache", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Cache = &b + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.DtlbLoadMisses != nil { - return false - } else if that1.DtlbLoadMisses != nil { - return false } - if this.DtlbStores != nil && that1.DtlbStores != nil { - if *this.DtlbStores != *that1.DtlbStores { - return false - } - } else if this.DtlbStores != nil { - return false - } else if that1.DtlbStores != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") } - if this.DtlbStoreMisses != nil && that1.DtlbStoreMisses != nil { - if *this.DtlbStoreMisses != *that1.DtlbStoreMisses { - return false + + return nil +} +func (m *CommandInfo_ContainerInfo) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.DtlbStoreMisses != nil { - return false - } else if that1.DtlbStoreMisses != nil { - return false - } - if this.DtlbPrefetches != nil && that1.DtlbPrefetches != nil { - if *this.DtlbPrefetches != *that1.DtlbPrefetches { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Image", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Image = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Options", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Options = append(m.Options, string(data[iNdEx:postIndex])) + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.DtlbPrefetches != nil { - return false - } else if that1.DtlbPrefetches != nil { - return false } - if this.DtlbPrefetchMisses != nil && that1.DtlbPrefetchMisses != nil { - if *this.DtlbPrefetchMisses != *that1.DtlbPrefetchMisses { - return false - } - } else if this.DtlbPrefetchMisses != nil { - return false - } else if that1.DtlbPrefetchMisses != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("image") } - if this.ItlbLoads != nil && that1.ItlbLoads != nil { - if *this.ItlbLoads != *that1.ItlbLoads { - return false + + return nil +} +func (m *ExecutorInfo) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.ItlbLoads != nil { - return false - } else if that1.ItlbLoads != nil { - return false - } - if this.ItlbLoadMisses != nil && that1.ItlbLoadMisses != nil { - if *this.ItlbLoadMisses != *that1.ItlbLoadMisses { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecutorId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ExecutorId == nil { + m.ExecutorId = &ExecutorID{} + } + if err := m.ExecutorId.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append([]byte{}, data[iNdEx:postIndex]...) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resources = append(m.Resources, &Resource{}) + if err := m.Resources[len(m.Resources)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Command", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Command == nil { + m.Command = &CommandInfo{} + } + if err := m.Command.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FrameworkId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.FrameworkId == nil { + m.FrameworkId = &FrameworkID{} + } + if err := m.FrameworkId.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Source = &s + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Container == nil { + m.Container = &ContainerInfo{} + } + if err := m.Container.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Discovery", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Discovery == nil { + m.Discovery = &DiscoveryInfo{} + } + if err := m.Discovery.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.ItlbLoadMisses != nil { - return false - } else if that1.ItlbLoadMisses != nil { - return false } - if this.BranchLoads != nil && that1.BranchLoads != nil { - if *this.BranchLoads != *that1.BranchLoads { - return false - } - } else if this.BranchLoads != nil { - return false - } else if that1.BranchLoads != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("executor_id") } - if this.BranchLoadMisses != nil && that1.BranchLoadMisses != nil { - if *this.BranchLoadMisses != *that1.BranchLoadMisses { - return false - } - } else if this.BranchLoadMisses != nil { - return false - } else if that1.BranchLoadMisses != nil { - return false + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("command") } - if this.NodeLoads != nil && that1.NodeLoads != nil { - if *this.NodeLoads != *that1.NodeLoads { - return false + + return nil +} +func (m *MasterInfo) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Id = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ip", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Ip = &v + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Port = &v + hasFields[0] |= uint64(0x00000004) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pid", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Pid = &s + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Hostname = &s + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Version = &s + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.NodeLoads != nil { - return false - } else if that1.NodeLoads != nil { - return false } - if this.NodeLoadMisses != nil && that1.NodeLoadMisses != nil { - if *this.NodeLoadMisses != *that1.NodeLoadMisses { - return false - } - } else if this.NodeLoadMisses != nil { - return false - } else if that1.NodeLoadMisses != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") } - if this.NodeStores != nil && that1.NodeStores != nil { - if *this.NodeStores != *that1.NodeStores { - return false - } - } else if this.NodeStores != nil { - return false - } else if that1.NodeStores != nil { - return false + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("ip") } - if this.NodeStoreMisses != nil && that1.NodeStoreMisses != nil { - if *this.NodeStoreMisses != *that1.NodeStoreMisses { - return false - } - } else if this.NodeStoreMisses != nil { - return false - } else if that1.NodeStoreMisses != nil { - return false + if hasFields[0]&uint64(0x00000004) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("port") } - if this.NodePrefetches != nil && that1.NodePrefetches != nil { - if *this.NodePrefetches != *that1.NodePrefetches { - return false + + return nil +} +func (m *SlaveInfo) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.NodePrefetches != nil { - return false - } else if that1.NodePrefetches != nil { - return false - } - if this.NodePrefetchMisses != nil && that1.NodePrefetchMisses != nil { - if *this.NodePrefetchMisses != *that1.NodePrefetchMisses { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Hostname = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resources = append(m.Resources, &Resource{}) + if err := m.Resources[len(m.Resources)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Attributes = append(m.Attributes, &Attribute{}) + if err := m.Attributes[len(m.Attributes)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Id == nil { + m.Id = &SlaveID{} + } + if err := m.Id.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Checkpoint", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Checkpoint = &b + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Port = &v + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.NodePrefetchMisses != nil { - return false - } else if that1.NodePrefetchMisses != nil { - return false - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false } - return true -} -func (this *Request) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("hostname") } - that1, ok := that.(*Request) - if !ok { - return fmt3.Errorf("that is not of type *Request") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Request but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Requestbut is not nil && this == nil") - } - if !this.SlaveId.Equal(that1.SlaveId) { - return fmt3.Errorf("SlaveId this(%v) Not Equal that(%v)", this.SlaveId, that1.SlaveId) - } - if len(this.Resources) != len(that1.Resources) { - return fmt3.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) - } - for i := range this.Resources { - if !this.Resources[i].Equal(that1.Resources[i]) { - return fmt3.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) - } - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *Request) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*Request) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if !this.SlaveId.Equal(that1.SlaveId) { - return false - } - if len(this.Resources) != len(that1.Resources) { - return false - } - for i := range this.Resources { - if !this.Resources[i].Equal(that1.Resources[i]) { - return false - } - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true -} -func (this *Offer) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") - } - - that1, ok := that.(*Offer) - if !ok { - return fmt3.Errorf("that is not of type *Offer") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Offer but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Offerbut is not nil && this == nil") - } - if !this.Id.Equal(that1.Id) { - return fmt3.Errorf("Id this(%v) Not Equal that(%v)", this.Id, that1.Id) - } - if !this.FrameworkId.Equal(that1.FrameworkId) { - return fmt3.Errorf("FrameworkId this(%v) Not Equal that(%v)", this.FrameworkId, that1.FrameworkId) - } - if !this.SlaveId.Equal(that1.SlaveId) { - return fmt3.Errorf("SlaveId this(%v) Not Equal that(%v)", this.SlaveId, that1.SlaveId) - } - if this.Hostname != nil && that1.Hostname != nil { - if *this.Hostname != *that1.Hostname { - return fmt3.Errorf("Hostname this(%v) Not Equal that(%v)", *this.Hostname, *that1.Hostname) +func (m *Value) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Hostname != nil { - return fmt3.Errorf("this.Hostname == nil && that.Hostname != nil") - } else if that1.Hostname != nil { - return fmt3.Errorf("Hostname this(%v) Not Equal that(%v)", this.Hostname, that1.Hostname) - } - if len(this.Resources) != len(that1.Resources) { - return fmt3.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) - } - for i := range this.Resources { - if !this.Resources[i].Equal(that1.Resources[i]) { - return fmt3.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v Value_Type + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (Value_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Scalar", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Scalar == nil { + m.Scalar = &Value_Scalar{} + } + if err := m.Scalar.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Ranges == nil { + m.Ranges = &Value_Ranges{} + } + if err := m.Ranges.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Set", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Set == nil { + m.Set = &Value_Set{} + } + if err := m.Set.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Text", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Text == nil { + m.Text = &Value_Text{} + } + if err := m.Text.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if len(this.Attributes) != len(that1.Attributes) { - return fmt3.Errorf("Attributes this(%v) Not Equal that(%v)", len(this.Attributes), len(that1.Attributes)) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") } - for i := range this.Attributes { - if !this.Attributes[i].Equal(that1.Attributes[i]) { - return fmt3.Errorf("Attributes this[%v](%v) Not Equal that[%v](%v)", i, this.Attributes[i], i, that1.Attributes[i]) + + return nil +} +func (m *Value_Scalar) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } - if len(this.ExecutorIds) != len(that1.ExecutorIds) { - return fmt3.Errorf("ExecutorIds this(%v) Not Equal that(%v)", len(this.ExecutorIds), len(that1.ExecutorIds)) - } - for i := range this.ExecutorIds { - if !this.ExecutorIds[i].Equal(that1.ExecutorIds[i]) { - return fmt3.Errorf("ExecutorIds this[%v](%v) Not Equal that[%v](%v)", i, this.ExecutorIds[i], i, that1.ExecutorIds[i]) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.Value = &v2 + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") } + return nil } -func (this *Offer) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*Offer) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true +func (m *Value_Range) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } else if this == nil { - return false - } - if !this.Id.Equal(that1.Id) { - return false - } - if !this.FrameworkId.Equal(that1.FrameworkId) { - return false - } - if !this.SlaveId.Equal(that1.SlaveId) { - return false - } - if this.Hostname != nil && that1.Hostname != nil { - if *this.Hostname != *that1.Hostname { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Begin", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Begin = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field End", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.End = &v + hasFields[0] |= uint64(0x00000002) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Hostname != nil { - return false - } else if that1.Hostname != nil { - return false } - if len(this.Resources) != len(that1.Resources) { - return false - } - for i := range this.Resources { - if !this.Resources[i].Equal(that1.Resources[i]) { - return false - } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("begin") } - if len(this.Attributes) != len(that1.Attributes) { - return false + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("end") } - for i := range this.Attributes { - if !this.Attributes[i].Equal(that1.Attributes[i]) { - return false + + return nil +} +func (m *Value_Ranges) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } - if len(this.ExecutorIds) != len(that1.ExecutorIds) { - return false - } - for i := range this.ExecutorIds { - if !this.ExecutorIds[i].Equal(that1.ExecutorIds[i]) { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Range", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Range = append(m.Range, &Value_Range{}) + if err := m.Range[len(m.Range)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true + + return nil } -func (this *TaskInfo) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func (m *Value_Set) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Item", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Item = append(m.Item, string(data[iNdEx:postIndex])) + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that == nil && this != nil") } - that1, ok := that.(*TaskInfo) - if !ok { - return fmt3.Errorf("that is not of type *TaskInfo") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *TaskInfo but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *TaskInfobut is not nil && this == nil") - } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) + return nil +} +func (m *Value_Text) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Name != nil { - return fmt3.Errorf("this.Name == nil && that.Name != nil") - } else if that1.Name != nil { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) - } - if !this.TaskId.Equal(that1.TaskId) { - return fmt3.Errorf("TaskId this(%v) Not Equal that(%v)", this.TaskId, that1.TaskId) - } - if !this.SlaveId.Equal(that1.SlaveId) { - return fmt3.Errorf("SlaveId this(%v) Not Equal that(%v)", this.SlaveId, that1.SlaveId) - } - if len(this.Resources) != len(that1.Resources) { - return fmt3.Errorf("Resources this(%v) Not Equal that(%v)", len(this.Resources), len(that1.Resources)) - } - for i := range this.Resources { - if !this.Resources[i].Equal(that1.Resources[i]) { - return fmt3.Errorf("Resources this[%v](%v) Not Equal that[%v](%v)", i, this.Resources[i], i, that1.Resources[i]) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if !this.Executor.Equal(that1.Executor) { - return fmt3.Errorf("Executor this(%v) Not Equal that(%v)", this.Executor, that1.Executor) - } - if !this.Command.Equal(that1.Command) { - return fmt3.Errorf("Command this(%v) Not Equal that(%v)", this.Command, that1.Command) - } - if !this.Container.Equal(that1.Container) { - return fmt3.Errorf("Container this(%v) Not Equal that(%v)", this.Container, that1.Container) - } - if !bytes.Equal(this.Data, that1.Data) { - return fmt3.Errorf("Data this(%v) Not Equal that(%v)", this.Data, that1.Data) - } - if !this.HealthCheck.Equal(that1.HealthCheck) { - return fmt3.Errorf("HealthCheck this(%v) Not Equal that(%v)", this.HealthCheck, that1.HealthCheck) - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") } + return nil } -func (this *TaskInfo) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*TaskInfo) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return false +func (m *Attribute) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Name != nil { - return false - } else if that1.Name != nil { - return false - } - if !this.TaskId.Equal(that1.TaskId) { - return false - } - if !this.SlaveId.Equal(that1.SlaveId) { - return false - } - if len(this.Resources) != len(that1.Resources) { - return false - } - for i := range this.Resources { - if !this.Resources[i].Equal(that1.Resources[i]) { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v Value_Type + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (Value_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Scalar", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Scalar == nil { + m.Scalar = &Value_Scalar{} + } + if err := m.Scalar.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Ranges == nil { + m.Ranges = &Value_Ranges{} + } + if err := m.Ranges.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Text", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Text == nil { + m.Text = &Value_Text{} + } + if err := m.Text.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Set", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Set == nil { + m.Set = &Value_Set{} + } + if err := m.Set.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if !this.Executor.Equal(that1.Executor) { - return false - } - if !this.Command.Equal(that1.Command) { - return false - } - if !this.Container.Equal(that1.Container) { - return false - } - if !bytes.Equal(this.Data, that1.Data) { - return false - } - if !this.HealthCheck.Equal(that1.HealthCheck) { - return false - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") } - return true -} -func (this *TaskStatus) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") } - that1, ok := that.(*TaskStatus) - if !ok { - return fmt3.Errorf("that is not of type *TaskStatus") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *TaskStatus but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *TaskStatusbut is not nil && this == nil") - } - if !this.TaskId.Equal(that1.TaskId) { - return fmt3.Errorf("TaskId this(%v) Not Equal that(%v)", this.TaskId, that1.TaskId) - } - if this.State != nil && that1.State != nil { - if *this.State != *that1.State { - return fmt3.Errorf("State this(%v) Not Equal that(%v)", *this.State, *that1.State) - } - } else if this.State != nil { - return fmt3.Errorf("this.State == nil && that.State != nil") - } else if that1.State != nil { - return fmt3.Errorf("State this(%v) Not Equal that(%v)", this.State, that1.State) - } - if this.Message != nil && that1.Message != nil { - if *this.Message != *that1.Message { - return fmt3.Errorf("Message this(%v) Not Equal that(%v)", *this.Message, *that1.Message) - } - } else if this.Message != nil { - return fmt3.Errorf("this.Message == nil && that.Message != nil") - } else if that1.Message != nil { - return fmt3.Errorf("Message this(%v) Not Equal that(%v)", this.Message, that1.Message) - } - if this.Source != nil && that1.Source != nil { - if *this.Source != *that1.Source { - return fmt3.Errorf("Source this(%v) Not Equal that(%v)", *this.Source, *that1.Source) - } - } else if this.Source != nil { - return fmt3.Errorf("this.Source == nil && that.Source != nil") - } else if that1.Source != nil { - return fmt3.Errorf("Source this(%v) Not Equal that(%v)", this.Source, that1.Source) - } - if this.Reason != nil && that1.Reason != nil { - if *this.Reason != *that1.Reason { - return fmt3.Errorf("Reason this(%v) Not Equal that(%v)", *this.Reason, *that1.Reason) + return nil +} +func (m *Resource) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Reason != nil { - return fmt3.Errorf("this.Reason == nil && that.Reason != nil") - } else if that1.Reason != nil { - return fmt3.Errorf("Reason this(%v) Not Equal that(%v)", this.Reason, that1.Reason) - } - if !bytes.Equal(this.Data, that1.Data) { - return fmt3.Errorf("Data this(%v) Not Equal that(%v)", this.Data, that1.Data) - } - if !this.SlaveId.Equal(that1.SlaveId) { - return fmt3.Errorf("SlaveId this(%v) Not Equal that(%v)", this.SlaveId, that1.SlaveId) - } - if !this.ExecutorId.Equal(that1.ExecutorId) { - return fmt3.Errorf("ExecutorId this(%v) Not Equal that(%v)", this.ExecutorId, that1.ExecutorId) - } - if this.Timestamp != nil && that1.Timestamp != nil { - if *this.Timestamp != *that1.Timestamp { - return fmt3.Errorf("Timestamp this(%v) Not Equal that(%v)", *this.Timestamp, *that1.Timestamp) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v Value_Type + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (Value_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Scalar", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Scalar == nil { + m.Scalar = &Value_Scalar{} + } + if err := m.Scalar.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Ranges == nil { + m.Ranges = &Value_Ranges{} + } + if err := m.Ranges.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Set", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Set == nil { + m.Set = &Value_Set{} + } + if err := m.Set.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Role = &s + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Disk", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Disk == nil { + m.Disk = &Resource_DiskInfo{} + } + if err := m.Disk.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reservation", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Reservation == nil { + m.Reservation = &Resource_ReservationInfo{} + } + if err := m.Reservation.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Revocable", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Revocable == nil { + m.Revocable = &Resource_RevocableInfo{} + } + if err := m.Revocable.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Timestamp != nil { - return fmt3.Errorf("this.Timestamp == nil && that.Timestamp != nil") - } else if that1.Timestamp != nil { - return fmt3.Errorf("Timestamp this(%v) Not Equal that(%v)", this.Timestamp, that1.Timestamp) } - if this.Healthy != nil && that1.Healthy != nil { - if *this.Healthy != *that1.Healthy { - return fmt3.Errorf("Healthy this(%v) Not Equal that(%v)", *this.Healthy, *that1.Healthy) - } - } else if this.Healthy != nil { - return fmt3.Errorf("this.Healthy == nil && that.Healthy != nil") - } else if that1.Healthy != nil { - return fmt3.Errorf("Healthy this(%v) Not Equal that(%v)", this.Healthy, that1.Healthy) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") } + return nil } -func (this *TaskStatus) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*TaskStatus) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if !this.TaskId.Equal(that1.TaskId) { - return false - } - if this.State != nil && that1.State != nil { - if *this.State != *that1.State { - return false - } - } else if this.State != nil { - return false - } else if that1.State != nil { - return false - } - if this.Message != nil && that1.Message != nil { - if *this.Message != *that1.Message { - return false - } - } else if this.Message != nil { - return false - } else if that1.Message != nil { - return false - } - if this.Source != nil && that1.Source != nil { - if *this.Source != *that1.Source { - return false - } - } else if this.Source != nil { - return false - } else if that1.Source != nil { - return false - } - if this.Reason != nil && that1.Reason != nil { - if *this.Reason != *that1.Reason { - return false - } - } else if this.Reason != nil { - return false - } else if that1.Reason != nil { - return false - } - if !bytes.Equal(this.Data, that1.Data) { - return false - } - if !this.SlaveId.Equal(that1.SlaveId) { - return false - } - if !this.ExecutorId.Equal(that1.ExecutorId) { - return false - } - if this.Timestamp != nil && that1.Timestamp != nil { - if *this.Timestamp != *that1.Timestamp { - return false +func (m *Resource_ReservationInfo) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Timestamp != nil { - return false - } else if that1.Timestamp != nil { - return false - } - if this.Healthy != nil && that1.Healthy != nil { - if *this.Healthy != *that1.Healthy { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Principal", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Principal = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Healthy != nil { - return false - } else if that1.Healthy != nil { - return false } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("principal") } - return true + + return nil } -func (this *Filters) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func (m *Resource_DiskInfo) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return fmt3.Errorf("that == nil && this != nil") - } - - that1, ok := that.(*Filters) - if !ok { - return fmt3.Errorf("that is not of type *Filters") - } - if that1 == nil { - if this == nil { - return nil + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Persistence", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Persistence == nil { + m.Persistence = &Resource_DiskInfo_Persistence{} + } + if err := m.Persistence.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Volume", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Volume == nil { + m.Volume = &Volume{} + } + if err := m.Volume.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that is type *Filters but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Filtersbut is not nil && this == nil") } - if this.RefuseSeconds != nil && that1.RefuseSeconds != nil { - if *this.RefuseSeconds != *that1.RefuseSeconds { - return fmt3.Errorf("RefuseSeconds this(%v) Not Equal that(%v)", *this.RefuseSeconds, *that1.RefuseSeconds) + + return nil +} +func (m *Resource_DiskInfo_Persistence) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Id = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.RefuseSeconds != nil { - return fmt3.Errorf("this.RefuseSeconds == nil && that.RefuseSeconds != nil") - } else if that1.RefuseSeconds != nil { - return fmt3.Errorf("RefuseSeconds this(%v) Not Equal that(%v)", this.RefuseSeconds, that1.RefuseSeconds) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") } + return nil } -func (this *Filters) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *Resource_RevocableInfo) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + switch fieldNum { + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false } - that1, ok := that.(*Filters) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + return nil +} +func (m *TrafficControlStatistics) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } else if this == nil { - return false - } - if this.RefuseSeconds != nil && that1.RefuseSeconds != nil { - if *this.RefuseSeconds != *that1.RefuseSeconds { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Id = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Backlog", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Backlog = &v + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Bytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Bytes = &v + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Drops", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Drops = &v + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Overlimits", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Overlimits = &v + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Packets", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Packets = &v + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Qlen", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Qlen = &v + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ratebps", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Ratebps = &v + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ratepps", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Ratepps = &v + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Requeues", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Requeues = &v + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.RefuseSeconds != nil { - return false - } else if that1.RefuseSeconds != nil { - return false - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false } - return true -} -func (this *Environment) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") } - that1, ok := that.(*Environment) - if !ok { - return fmt3.Errorf("that is not of type *Environment") - } - if that1 == nil { - if this == nil { - return nil + return nil +} +func (m *ResourceStatistics) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return fmt3.Errorf("that is type *Environment but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Environmentbut is not nil && this == nil") - } - if len(this.Variables) != len(that1.Variables) { - return fmt3.Errorf("Variables this(%v) Not Equal that(%v)", len(this.Variables), len(that1.Variables)) - } - for i := range this.Variables { - if !this.Variables[i].Equal(that1.Variables[i]) { - return fmt3.Errorf("Variables this[%v](%v) Not Equal that[%v](%v)", i, this.Variables[i], i, that1.Variables[i]) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.Timestamp = &v2 + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field CpusUserTimeSecs", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.CpusUserTimeSecs = &v2 + case 3: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field CpusSystemTimeSecs", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.CpusSystemTimeSecs = &v2 + case 4: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field CpusLimit", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.CpusLimit = &v2 + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemRssBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemRssBytes = &v + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemLimitBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemLimitBytes = &v + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CpusNrPeriods", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.CpusNrPeriods = &v + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CpusNrThrottled", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.CpusNrThrottled = &v + case 9: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field CpusThrottledTimeSecs", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.CpusThrottledTimeSecs = &v2 + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemFileBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemFileBytes = &v + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemAnonBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemAnonBytes = &v + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemMappedFileBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemMappedFileBytes = &v + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Perf", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Perf == nil { + m.Perf = &PerfStatistics{} + } + if err := m.Perf.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NetRxPackets", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NetRxPackets = &v + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NetRxBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NetRxBytes = &v + case 16: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NetRxErrors", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NetRxErrors = &v + case 17: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NetRxDropped", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NetRxDropped = &v + case 18: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NetTxPackets", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NetTxPackets = &v + case 19: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NetTxBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NetTxBytes = &v + case 20: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NetTxErrors", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NetTxErrors = &v + case 21: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NetTxDropped", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NetTxDropped = &v + case 22: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field NetTcpRttMicrosecsP50", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.NetTcpRttMicrosecsP50 = &v2 + case 23: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field NetTcpRttMicrosecsP90", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.NetTcpRttMicrosecsP90 = &v2 + case 24: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field NetTcpRttMicrosecsP95", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.NetTcpRttMicrosecsP95 = &v2 + case 25: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field NetTcpRttMicrosecsP99", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.NetTcpRttMicrosecsP99 = &v2 + case 26: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DiskLimitBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.DiskLimitBytes = &v + case 27: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DiskUsedBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.DiskUsedBytes = &v + case 28: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field NetTcpActiveConnections", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.NetTcpActiveConnections = &v2 + case 29: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field NetTcpTimeWaitConnections", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.NetTcpTimeWaitConnections = &v2 + case 30: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Processes", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Processes = &v + case 31: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Threads", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Threads = &v + case 32: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemLowPressureCounter", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemLowPressureCounter = &v + case 33: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemMediumPressureCounter", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemMediumPressureCounter = &v + case 34: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemCriticalPressureCounter", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemCriticalPressureCounter = &v + case 35: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NetTrafficControlStatistics", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NetTrafficControlStatistics = append(m.NetTrafficControlStatistics, &TrafficControlStatistics{}) + if err := m.NetTrafficControlStatistics[len(m.NetTrafficControlStatistics)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 36: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemTotalBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemTotalBytes = &v + case 37: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemTotalMemswBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemTotalMemswBytes = &v + case 38: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemSoftLimitBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemSoftLimitBytes = &v + case 39: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemCacheBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemCacheBytes = &v + case 40: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemSwapBytes", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MemSwapBytes = &v + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("timestamp") } + return nil } -func (this *Environment) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*Environment) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if len(this.Variables) != len(that1.Variables) { - return false - } - for i := range this.Variables { - if !this.Variables[i].Equal(that1.Variables[i]) { - return false +func (m *ResourceUsage) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true -} -func (this *Environment_Variable) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Executors", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Executors = append(m.Executors, &ResourceUsage_Executor{}) + if err := m.Executors[len(m.Executors)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that == nil && this != nil") } - that1, ok := that.(*Environment_Variable) - if !ok { - return fmt3.Errorf("that is not of type *Environment_Variable") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Environment_Variable but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Environment_Variablebut is not nil && this == nil") - } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) - } - } else if this.Name != nil { - return fmt3.Errorf("this.Name == nil && that.Name != nil") - } else if that1.Name != nil { - return fmt3.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) - } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) - } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *Environment_Variable) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*Environment_Variable) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return false - } - } else if this.Name != nil { - return false - } else if that1.Name != nil { - return false - } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false +func (m *ResourceUsage_Executor) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true -} -func (this *Parameter) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecutorInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ExecutorInfo == nil { + m.ExecutorInfo = &ExecutorInfo{} + } + if err := m.ExecutorInfo.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allocated", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Allocated = append(m.Allocated, &Resource{}) + if err := m.Allocated[len(m.Allocated)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Statistics", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Statistics == nil { + m.Statistics = &ResourceStatistics{} + } + if err := m.Statistics.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that == nil && this != nil") - } - - that1, ok := that.(*Parameter) - if !ok { - return fmt3.Errorf("that is not of type *Parameter") } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Parameter but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Parameterbut is not nil && this == nil") + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("executor_info") } - if this.Key != nil && that1.Key != nil { - if *this.Key != *that1.Key { - return fmt3.Errorf("Key this(%v) Not Equal that(%v)", *this.Key, *that1.Key) + + return nil +} +func (m *PerfStatistics) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Key != nil { - return fmt3.Errorf("this.Key == nil && that.Key != nil") - } else if that1.Key != nil { - return fmt3.Errorf("Key this(%v) Not Equal that(%v)", this.Key, that1.Key) - } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", *this.Value, *that1.Value) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.Timestamp = &v2 + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.Duration = &v2 + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Cycles", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Cycles = &v + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StalledCyclesFrontend", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.StalledCyclesFrontend = &v + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StalledCyclesBackend", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.StalledCyclesBackend = &v + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Instructions", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Instructions = &v + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CacheReferences", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.CacheReferences = &v + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CacheMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.CacheMisses = &v + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Branches", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Branches = &v + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BranchMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.BranchMisses = &v + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BusCycles", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.BusCycles = &v + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RefCycles", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.RefCycles = &v + case 13: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field CpuClock", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.CpuClock = &v2 + case 14: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field TaskClock", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.TaskClock = &v2 + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PageFaults", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.PageFaults = &v + case 16: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinorFaults", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MinorFaults = &v + case 17: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MajorFaults", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.MajorFaults = &v + case 18: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ContextSwitches", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.ContextSwitches = &v + case 19: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CpuMigrations", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.CpuMigrations = &v + case 20: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AlignmentFaults", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.AlignmentFaults = &v + case 21: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EmulationFaults", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.EmulationFaults = &v + case 22: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field L1DcacheLoads", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.L1DcacheLoads = &v + case 23: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field L1DcacheLoadMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.L1DcacheLoadMisses = &v + case 24: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field L1DcacheStores", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.L1DcacheStores = &v + case 25: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field L1DcacheStoreMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.L1DcacheStoreMisses = &v + case 26: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field L1DcachePrefetches", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.L1DcachePrefetches = &v + case 27: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field L1DcachePrefetchMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.L1DcachePrefetchMisses = &v + case 28: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field L1IcacheLoads", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.L1IcacheLoads = &v + case 29: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field L1IcacheLoadMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.L1IcacheLoadMisses = &v + case 30: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field L1IcachePrefetches", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.L1IcachePrefetches = &v + case 31: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field L1IcachePrefetchMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.L1IcachePrefetchMisses = &v + case 32: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LlcLoads", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.LlcLoads = &v + case 33: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LlcLoadMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.LlcLoadMisses = &v + case 34: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LlcStores", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.LlcStores = &v + case 35: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LlcStoreMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.LlcStoreMisses = &v + case 36: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LlcPrefetches", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.LlcPrefetches = &v + case 37: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LlcPrefetchMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.LlcPrefetchMisses = &v + case 38: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DtlbLoads", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.DtlbLoads = &v + case 39: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DtlbLoadMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.DtlbLoadMisses = &v + case 40: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DtlbStores", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.DtlbStores = &v + case 41: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DtlbStoreMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.DtlbStoreMisses = &v + case 42: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DtlbPrefetches", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.DtlbPrefetches = &v + case 43: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DtlbPrefetchMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.DtlbPrefetchMisses = &v + case 44: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ItlbLoads", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.ItlbLoads = &v + case 45: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ItlbLoadMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.ItlbLoadMisses = &v + case 46: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BranchLoads", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.BranchLoads = &v + case 47: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BranchLoadMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.BranchLoadMisses = &v + case 48: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeLoads", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NodeLoads = &v + case 49: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeLoadMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NodeLoadMisses = &v + case 50: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeStores", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NodeStores = &v + case 51: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeStoreMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NodeStoreMisses = &v + case 52: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NodePrefetches", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NodePrefetches = &v + case 53: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NodePrefetchMisses", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NodePrefetchMisses = &v + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Value != nil { - return fmt3.Errorf("this.Value == nil && that.Value != nil") - } else if that1.Value != nil { - return fmt3.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("timestamp") } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("duration") + } + return nil } -func (this *Parameter) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *Request) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlaveId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SlaveId == nil { + m.SlaveId = &SlaveID{} + } + if err := m.SlaveId.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resources = append(m.Resources, &Resource{}) + if err := m.Resources[len(m.Resources)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false } - that1, ok := that.(*Parameter) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + return nil +} +func (m *Offer) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Id == nil { + m.Id = &OfferID{} + } + if err := m.Id.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FrameworkId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.FrameworkId == nil { + m.FrameworkId = &FrameworkID{} + } + if err := m.FrameworkId.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlaveId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SlaveId == nil { + m.SlaveId = &SlaveID{} + } + if err := m.SlaveId.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000004) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Hostname = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000008) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resources = append(m.Resources, &Resource{}) + if err := m.Resources[len(m.Resources)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecutorIds", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExecutorIds = append(m.ExecutorIds, &ExecutorID{}) + if err := m.ExecutorIds[len(m.ExecutorIds)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Attributes = append(m.Attributes, &Attribute{}) + if err := m.Attributes[len(m.Attributes)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false - } else if this == nil { - return false } - if this.Key != nil && that1.Key != nil { - if *this.Key != *that1.Key { - return false - } - } else if this.Key != nil { - return false - } else if that1.Key != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") } - if this.Value != nil && that1.Value != nil { - if *this.Value != *that1.Value { - return false - } - } else if this.Value != nil { - return false - } else if that1.Value != nil { - return false + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("framework_id") } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000004) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("slave_id") } - return true -} -func (this *Parameters) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000008) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("hostname") } - that1, ok := that.(*Parameters) - if !ok { - return fmt3.Errorf("that is not of type *Parameters") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Parameters but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Parametersbut is not nil && this == nil") - } - if len(this.Parameter) != len(that1.Parameter) { - return fmt3.Errorf("Parameter this(%v) Not Equal that(%v)", len(this.Parameter), len(that1.Parameter)) - } - for i := range this.Parameter { - if !this.Parameter[i].Equal(that1.Parameter[i]) { - return fmt3.Errorf("Parameter this[%v](%v) Not Equal that[%v](%v)", i, this.Parameter[i], i, that1.Parameter[i]) - } - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *Parameters) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*Parameters) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true +func (m *Offer_Operation) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } else if this == nil { - return false - } - if len(this.Parameter) != len(that1.Parameter) { - return false - } - for i := range this.Parameter { - if !this.Parameter[i].Equal(that1.Parameter[i]) { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v Offer_Operation_Type + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (Offer_Operation_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Launch", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Launch == nil { + m.Launch = &Offer_Operation_Launch{} + } + if err := m.Launch.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reserve", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Reserve == nil { + m.Reserve = &Offer_Operation_Reserve{} + } + if err := m.Reserve.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Unreserve", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Unreserve == nil { + m.Unreserve = &Offer_Operation_Unreserve{} + } + if err := m.Unreserve.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Create", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Create == nil { + m.Create = &Offer_Operation_Create{} + } + if err := m.Create.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Destroy", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Destroy == nil { + m.Destroy = &Offer_Operation_Destroy{} + } + if err := m.Destroy.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") } - return true + + return nil } -func (this *Credential) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func (m *Offer_Operation_Launch) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TaskInfos", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TaskInfos = append(m.TaskInfos, &TaskInfo{}) + if err := m.TaskInfos[len(m.TaskInfos)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that == nil && this != nil") } - that1, ok := that.(*Credential) - if !ok { - return fmt3.Errorf("that is not of type *Credential") - } - if that1 == nil { - if this == nil { - return nil + return nil +} +func (m *Offer_Operation_Reserve) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return fmt3.Errorf("that is type *Credential but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Credentialbut is not nil && this == nil") - } - if this.Principal != nil && that1.Principal != nil { - if *this.Principal != *that1.Principal { - return fmt3.Errorf("Principal this(%v) Not Equal that(%v)", *this.Principal, *that1.Principal) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resources = append(m.Resources, &Resource{}) + if err := m.Resources[len(m.Resources)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Principal != nil { - return fmt3.Errorf("this.Principal == nil && that.Principal != nil") - } else if that1.Principal != nil { - return fmt3.Errorf("Principal this(%v) Not Equal that(%v)", this.Principal, that1.Principal) - } - if !bytes.Equal(this.Secret, that1.Secret) { - return fmt3.Errorf("Secret this(%v) Not Equal that(%v)", this.Secret, that1.Secret) - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } + return nil } -func (this *Credential) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *Offer_Operation_Unreserve) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resources = append(m.Resources, &Resource{}) + if err := m.Resources[len(m.Resources)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false } - that1, ok := that.(*Credential) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + return nil +} +func (m *Offer_Operation_Create) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } else if this == nil { - return false - } - if this.Principal != nil && that1.Principal != nil { - if *this.Principal != *that1.Principal { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Volumes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Volumes = append(m.Volumes, &Resource{}) + if err := m.Volumes[len(m.Volumes)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Principal != nil { - return false - } else if that1.Principal != nil { - return false - } - if !bytes.Equal(this.Secret, that1.Secret) { - return false - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false } - return true + + return nil } -func (this *Credentials) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func (m *Offer_Operation_Destroy) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Volumes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Volumes = append(m.Volumes, &Resource{}) + if err := m.Volumes[len(m.Volumes)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that == nil && this != nil") } - that1, ok := that.(*Credentials) - if !ok { - return fmt3.Errorf("that is not of type *Credentials") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Credentials but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Credentialsbut is not nil && this == nil") - } - if len(this.Credentials) != len(that1.Credentials) { - return fmt3.Errorf("Credentials this(%v) Not Equal that(%v)", len(this.Credentials), len(that1.Credentials)) - } - for i := range this.Credentials { - if !this.Credentials[i].Equal(that1.Credentials[i]) { - return fmt3.Errorf("Credentials this[%v](%v) Not Equal that[%v](%v)", i, this.Credentials[i], i, that1.Credentials[i]) - } - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *Credentials) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *TaskInfo) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } - - that1, ok := that.(*Credentials) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TaskId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TaskId == nil { + m.TaskId = &TaskID{} + } + if err := m.TaskId.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlaveId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SlaveId == nil { + m.SlaveId = &SlaveID{} + } + if err := m.SlaveId.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000004) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resources = append(m.Resources, &Resource{}) + if err := m.Resources[len(m.Resources)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Executor", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Executor == nil { + m.Executor = &ExecutorInfo{} + } + if err := m.Executor.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append([]byte{}, data[iNdEx:postIndex]...) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Command", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Command == nil { + m.Command = &CommandInfo{} + } + if err := m.Command.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HealthCheck", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.HealthCheck == nil { + m.HealthCheck = &HealthCheck{} + } + if err := m.HealthCheck.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Container == nil { + m.Container = &ContainerInfo{} + } + if err := m.Container.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Labels == nil { + m.Labels = &Labels{} + } + if err := m.Labels.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Discovery", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Discovery == nil { + m.Discovery = &DiscoveryInfo{} + } + if err := m.Discovery.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false - } else if this == nil { - return false - } - if len(this.Credentials) != len(that1.Credentials) { - return false } - for i := range this.Credentials { - if !this.Credentials[i].Equal(that1.Credentials[i]) { - return false - } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("task_id") } - return true -} -func (this *ACL) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000004) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("slave_id") } - that1, ok := that.(*ACL) - if !ok { - return fmt3.Errorf("that is not of type *ACL") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *ACL but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ACLbut is not nil && this == nil") - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *ACL) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *TaskStatus) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } - - that1, ok := that.(*ACL) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TaskId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TaskId == nil { + m.TaskId = &TaskID{} + } + if err := m.TaskId.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) + } + var v TaskState + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (TaskState(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.State = &v + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append([]byte{}, data[iNdEx:postIndex]...) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Message = &s + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlaveId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SlaveId == nil { + m.SlaveId = &SlaveID{} + } + if err := m.SlaveId.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.Timestamp = &v2 + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecutorId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ExecutorId == nil { + m.ExecutorId = &ExecutorID{} + } + if err := m.ExecutorId.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Healthy", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Healthy = &b + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var v TaskStatus_Source + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (TaskStatus_Source(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Source = &v + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + } + var v TaskStatus_Reason + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (TaskStatus_Reason(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Reason = &v + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Uuid", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Uuid = append([]byte{}, data[iNdEx:postIndex]...) + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false - } else if this == nil { - return false } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("task_id") } - return true -} -func (this *ACL_Entity) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("state") } - that1, ok := that.(*ACL_Entity) - if !ok { - return fmt3.Errorf("that is not of type *ACL_Entity") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *ACL_Entity but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ACL_Entitybut is not nil && this == nil") - } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return fmt3.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) - } - } else if this.Type != nil { - return fmt3.Errorf("this.Type == nil && that.Type != nil") - } else if that1.Type != nil { - return fmt3.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) - } - if len(this.Values) != len(that1.Values) { - return fmt3.Errorf("Values this(%v) Not Equal that(%v)", len(this.Values), len(that1.Values)) - } - for i := range this.Values { - if this.Values[i] != that1.Values[i] { - return fmt3.Errorf("Values this[%v](%v) Not Equal that[%v](%v)", i, this.Values[i], i, that1.Values[i]) - } - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *ACL_Entity) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*ACL_Entity) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return false - } - } else if this.Type != nil { - return false - } else if that1.Type != nil { - return false - } - if len(this.Values) != len(that1.Values) { - return false - } - for i := range this.Values { - if this.Values[i] != that1.Values[i] { - return false +func (m *Filters) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true -} -func (this *ACL_RegisterFramework) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field RefuseSeconds", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.RefuseSeconds = &v2 + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that == nil && this != nil") } - that1, ok := that.(*ACL_RegisterFramework) - if !ok { - return fmt3.Errorf("that is not of type *ACL_RegisterFramework") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *ACL_RegisterFramework but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ACL_RegisterFrameworkbut is not nil && this == nil") - } - if !this.Principals.Equal(that1.Principals) { - return fmt3.Errorf("Principals this(%v) Not Equal that(%v)", this.Principals, that1.Principals) - } - if !this.Roles.Equal(that1.Roles) { - return fmt3.Errorf("Roles this(%v) Not Equal that(%v)", this.Roles, that1.Roles) - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *ACL_RegisterFramework) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*ACL_RegisterFramework) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if !this.Principals.Equal(that1.Principals) { - return false - } - if !this.Roles.Equal(that1.Roles) { - return false - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true -} -func (this *ACL_RunTask) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") - } - - that1, ok := that.(*ACL_RunTask) - if !ok { - return fmt3.Errorf("that is not of type *ACL_RunTask") - } - if that1 == nil { - if this == nil { - return nil +func (m *Environment) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return fmt3.Errorf("that is type *ACL_RunTask but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ACL_RunTaskbut is not nil && this == nil") - } - if !this.Principals.Equal(that1.Principals) { - return fmt3.Errorf("Principals this(%v) Not Equal that(%v)", this.Principals, that1.Principals) - } - if !this.Users.Equal(that1.Users) { - return fmt3.Errorf("Users this(%v) Not Equal that(%v)", this.Users, that1.Users) - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } - return nil -} -func (this *ACL_RunTask) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Variables", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Variables = append(m.Variables, &Environment_Variable{}) + if err := m.Variables[len(m.Variables)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false } - that1, ok := that.(*ACL_RunTask) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if !this.Principals.Equal(that1.Principals) { - return false - } - if !this.Users.Equal(that1.Users) { - return false - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true + return nil } -func (this *ACL_ShutdownFramework) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func (m *Environment_Variable) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return fmt3.Errorf("that == nil && this != nil") - } - - that1, ok := that.(*ACL_ShutdownFramework) - if !ok { - return fmt3.Errorf("that is not of type *ACL_ShutdownFramework") - } - if that1 == nil { - if this == nil { - return nil + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that is type *ACL_ShutdownFramework but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ACL_ShutdownFrameworkbut is not nil && this == nil") - } - if !this.Principals.Equal(that1.Principals) { - return fmt3.Errorf("Principals this(%v) Not Equal that(%v)", this.Principals, that1.Principals) } - if !this.FrameworkPrincipals.Equal(that1.FrameworkPrincipals) { - return fmt3.Errorf("FrameworkPrincipals this(%v) Not Equal that(%v)", this.FrameworkPrincipals, that1.FrameworkPrincipals) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") } + return nil } -func (this *ACL_ShutdownFramework) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *Parameter) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } - - that1, ok := that.(*ACL_ShutdownFramework) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Key = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false - } else if this == nil { - return false } - if !this.Principals.Equal(that1.Principals) { - return false - } - if !this.FrameworkPrincipals.Equal(that1.FrameworkPrincipals) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("key") } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") } - return true + + return nil } -func (this *ACLs) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func (m *Parameters) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Parameter", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Parameter = append(m.Parameter, &Parameter{}) + if err := m.Parameter[len(m.Parameter)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that == nil && this != nil") } - that1, ok := that.(*ACLs) - if !ok { - return fmt3.Errorf("that is not of type *ACLs") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *ACLs but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ACLsbut is not nil && this == nil") - } - if this.Permissive != nil && that1.Permissive != nil { - if *this.Permissive != *that1.Permissive { - return fmt3.Errorf("Permissive this(%v) Not Equal that(%v)", *this.Permissive, *that1.Permissive) + return nil +} +func (m *Credential) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Permissive != nil { - return fmt3.Errorf("this.Permissive == nil && that.Permissive != nil") - } else if that1.Permissive != nil { - return fmt3.Errorf("Permissive this(%v) Not Equal that(%v)", this.Permissive, that1.Permissive) - } - if len(this.RegisterFrameworks) != len(that1.RegisterFrameworks) { - return fmt3.Errorf("RegisterFrameworks this(%v) Not Equal that(%v)", len(this.RegisterFrameworks), len(that1.RegisterFrameworks)) - } - for i := range this.RegisterFrameworks { - if !this.RegisterFrameworks[i].Equal(that1.RegisterFrameworks[i]) { - return fmt3.Errorf("RegisterFrameworks this[%v](%v) Not Equal that[%v](%v)", i, this.RegisterFrameworks[i], i, that1.RegisterFrameworks[i]) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Principal", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Principal = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Secret", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Secret = append([]byte{}, data[iNdEx:postIndex]...) + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if len(this.RunTasks) != len(that1.RunTasks) { - return fmt3.Errorf("RunTasks this(%v) Not Equal that(%v)", len(this.RunTasks), len(that1.RunTasks)) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("principal") } - for i := range this.RunTasks { - if !this.RunTasks[i].Equal(that1.RunTasks[i]) { - return fmt3.Errorf("RunTasks this[%v](%v) Not Equal that[%v](%v)", i, this.RunTasks[i], i, that1.RunTasks[i]) + + return nil +} +func (m *Credentials) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } - if len(this.ShutdownFrameworks) != len(that1.ShutdownFrameworks) { - return fmt3.Errorf("ShutdownFrameworks this(%v) Not Equal that(%v)", len(this.ShutdownFrameworks), len(that1.ShutdownFrameworks)) - } - for i := range this.ShutdownFrameworks { - if !this.ShutdownFrameworks[i].Equal(that1.ShutdownFrameworks[i]) { - return fmt3.Errorf("ShutdownFrameworks this[%v](%v) Not Equal that[%v](%v)", i, this.ShutdownFrameworks[i], i, that1.ShutdownFrameworks[i]) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Credentials", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Credentials = append(m.Credentials, &Credential{}) + if err := m.Credentials[len(m.Credentials)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } + return nil } -func (this *ACLs) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *ACL) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + switch fieldNum { + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false } - that1, ok := that.(*ACLs) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + return nil +} +func (m *ACL_Entity) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } else if this == nil { - return false - } - if this.Permissive != nil && that1.Permissive != nil { - if *this.Permissive != *that1.Permissive { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v ACL_Entity_Type + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (ACL_Entity_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Values = append(m.Values, string(data[iNdEx:postIndex])) + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Permissive != nil { - return false - } else if that1.Permissive != nil { - return false } - if len(this.RegisterFrameworks) != len(that1.RegisterFrameworks) { - return false - } - for i := range this.RegisterFrameworks { - if !this.RegisterFrameworks[i].Equal(that1.RegisterFrameworks[i]) { - return false + + return nil +} +func (m *ACL_RegisterFramework) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } - if len(this.RunTasks) != len(that1.RunTasks) { - return false - } - for i := range this.RunTasks { - if !this.RunTasks[i].Equal(that1.RunTasks[i]) { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Principals", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Principals == nil { + m.Principals = &ACL_Entity{} + } + if err := m.Principals.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Roles == nil { + m.Roles = &ACL_Entity{} + } + if err := m.Roles.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if len(this.ShutdownFrameworks) != len(that1.ShutdownFrameworks) { - return false - } - for i := range this.ShutdownFrameworks { - if !this.ShutdownFrameworks[i].Equal(that1.ShutdownFrameworks[i]) { - return false - } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("principals") } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("roles") } - return true + + return nil } -func (this *RateLimit) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func (m *ACL_RunTask) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Principals", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Principals == nil { + m.Principals = &ACL_Entity{} + } + if err := m.Principals.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Users", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Users == nil { + m.Users = &ACL_Entity{} + } + if err := m.Users.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that == nil && this != nil") } - - that1, ok := that.(*RateLimit) - if !ok { - return fmt3.Errorf("that is not of type *RateLimit") + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("principals") } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *RateLimit but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *RateLimitbut is not nil && this == nil") + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("users") } - if this.Qps != nil && that1.Qps != nil { - if *this.Qps != *that1.Qps { - return fmt3.Errorf("Qps this(%v) Not Equal that(%v)", *this.Qps, *that1.Qps) + + return nil +} +func (m *ACL_ShutdownFramework) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Qps != nil { - return fmt3.Errorf("this.Qps == nil && that.Qps != nil") - } else if that1.Qps != nil { - return fmt3.Errorf("Qps this(%v) Not Equal that(%v)", this.Qps, that1.Qps) - } - if this.Principal != nil && that1.Principal != nil { - if *this.Principal != *that1.Principal { - return fmt3.Errorf("Principal this(%v) Not Equal that(%v)", *this.Principal, *that1.Principal) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Principals", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Principals == nil { + m.Principals = &ACL_Entity{} + } + if err := m.Principals.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FrameworkPrincipals", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.FrameworkPrincipals == nil { + m.FrameworkPrincipals = &ACL_Entity{} + } + if err := m.FrameworkPrincipals.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Principal != nil { - return fmt3.Errorf("this.Principal == nil && that.Principal != nil") - } else if that1.Principal != nil { - return fmt3.Errorf("Principal this(%v) Not Equal that(%v)", this.Principal, that1.Principal) } - if this.Capacity != nil && that1.Capacity != nil { - if *this.Capacity != *that1.Capacity { - return fmt3.Errorf("Capacity this(%v) Not Equal that(%v)", *this.Capacity, *that1.Capacity) - } - } else if this.Capacity != nil { - return fmt3.Errorf("this.Capacity == nil && that.Capacity != nil") - } else if that1.Capacity != nil { - return fmt3.Errorf("Capacity this(%v) Not Equal that(%v)", this.Capacity, that1.Capacity) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("principals") } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("framework_principals") } + return nil } -func (this *RateLimit) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*RateLimit) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Qps != nil && that1.Qps != nil { - if *this.Qps != *that1.Qps { - return false - } - } else if this.Qps != nil { - return false - } else if that1.Qps != nil { - return false - } - if this.Principal != nil && that1.Principal != nil { - if *this.Principal != *that1.Principal { - return false +func (m *ACLs) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Principal != nil { - return false - } else if that1.Principal != nil { - return false - } - if this.Capacity != nil && that1.Capacity != nil { - if *this.Capacity != *that1.Capacity { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Permissive", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Permissive = &b + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RegisterFrameworks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RegisterFrameworks = append(m.RegisterFrameworks, &ACL_RegisterFramework{}) + if err := m.RegisterFrameworks[len(m.RegisterFrameworks)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RunTasks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RunTasks = append(m.RunTasks, &ACL_RunTask{}) + if err := m.RunTasks[len(m.RunTasks)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ShutdownFrameworks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ShutdownFrameworks = append(m.ShutdownFrameworks, &ACL_ShutdownFramework{}) + if err := m.ShutdownFrameworks[len(m.ShutdownFrameworks)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Capacity != nil { - return false - } else if that1.Capacity != nil { - return false - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false } - return true + + return nil } -func (this *RateLimits) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func (m *RateLimit) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return fmt3.Errorf("that == nil && this != nil") - } - - that1, ok := that.(*RateLimits) - if !ok { - return fmt3.Errorf("that is not of type *RateLimits") - } - if that1 == nil { - if this == nil { - return nil + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field Qps", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.Qps = &v2 + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Principal", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Principal = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Capacity", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Capacity = &v + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that is type *RateLimits but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *RateLimitsbut is not nil && this == nil") - } - if len(this.Limits) != len(that1.Limits) { - return fmt3.Errorf("Limits this(%v) Not Equal that(%v)", len(this.Limits), len(that1.Limits)) } - for i := range this.Limits { - if !this.Limits[i].Equal(that1.Limits[i]) { - return fmt3.Errorf("Limits this[%v](%v) Not Equal that[%v](%v)", i, this.Limits[i], i, that1.Limits[i]) - } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("principal") } - if this.AggregateDefaultQps != nil && that1.AggregateDefaultQps != nil { - if *this.AggregateDefaultQps != *that1.AggregateDefaultQps { - return fmt3.Errorf("AggregateDefaultQps this(%v) Not Equal that(%v)", *this.AggregateDefaultQps, *that1.AggregateDefaultQps) + + return nil +} +func (m *RateLimits) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.AggregateDefaultQps != nil { - return fmt3.Errorf("this.AggregateDefaultQps == nil && that.AggregateDefaultQps != nil") - } else if that1.AggregateDefaultQps != nil { - return fmt3.Errorf("AggregateDefaultQps this(%v) Not Equal that(%v)", this.AggregateDefaultQps, that1.AggregateDefaultQps) - } - if this.AggregateDefaultCapacity != nil && that1.AggregateDefaultCapacity != nil { - if *this.AggregateDefaultCapacity != *that1.AggregateDefaultCapacity { - return fmt3.Errorf("AggregateDefaultCapacity this(%v) Not Equal that(%v)", *this.AggregateDefaultCapacity, *that1.AggregateDefaultCapacity) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Limits", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Limits = append(m.Limits, &RateLimit{}) + if err := m.Limits[len(m.Limits)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field AggregateDefaultQps", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + iNdEx += 8 + v = uint64(data[iNdEx-8]) + v |= uint64(data[iNdEx-7]) << 8 + v |= uint64(data[iNdEx-6]) << 16 + v |= uint64(data[iNdEx-5]) << 24 + v |= uint64(data[iNdEx-4]) << 32 + v |= uint64(data[iNdEx-3]) << 40 + v |= uint64(data[iNdEx-2]) << 48 + v |= uint64(data[iNdEx-1]) << 56 + v2 := float64(math.Float64frombits(v)) + m.AggregateDefaultQps = &v2 + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AggregateDefaultCapacity", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.AggregateDefaultCapacity = &v + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.AggregateDefaultCapacity != nil { - return fmt3.Errorf("this.AggregateDefaultCapacity == nil && that.AggregateDefaultCapacity != nil") - } else if that1.AggregateDefaultCapacity != nil { - return fmt3.Errorf("AggregateDefaultCapacity this(%v) Not Equal that(%v)", this.AggregateDefaultCapacity, that1.AggregateDefaultCapacity) - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } + return nil } -func (this *RateLimits) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *Volume) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } - - that1, ok := that.(*RateLimits) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.ContainerPath = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HostPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.HostPath = &s + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) + } + var v Volume_Mode + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (Volume_Mode(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Mode = &v + hasFields[0] |= uint64(0x00000002) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false - } else if this == nil { - return false } - if len(this.Limits) != len(that1.Limits) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("container_path") } - for i := range this.Limits { - if !this.Limits[i].Equal(that1.Limits[i]) { - return false - } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("mode") } - if this.AggregateDefaultQps != nil && that1.AggregateDefaultQps != nil { - if *this.AggregateDefaultQps != *that1.AggregateDefaultQps { - return false + + return nil +} +func (m *ContainerInfo) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.AggregateDefaultQps != nil { - return false - } else if that1.AggregateDefaultQps != nil { - return false - } - if this.AggregateDefaultCapacity != nil && that1.AggregateDefaultCapacity != nil { - if *this.AggregateDefaultCapacity != *that1.AggregateDefaultCapacity { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v ContainerInfo_Type + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (ContainerInfo_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Volumes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Volumes = append(m.Volumes, &Volume{}) + if err := m.Volumes[len(m.Volumes)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Docker", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Docker == nil { + m.Docker = &ContainerInfo_DockerInfo{} + } + if err := m.Docker.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Hostname = &s + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.AggregateDefaultCapacity != nil { - return false - } else if that1.AggregateDefaultCapacity != nil { - return false - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false } - return true -} -func (this *Volume) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") } - that1, ok := that.(*Volume) - if !ok { - return fmt3.Errorf("that is not of type *Volume") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *Volume but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *Volumebut is not nil && this == nil") - } - if this.ContainerPath != nil && that1.ContainerPath != nil { - if *this.ContainerPath != *that1.ContainerPath { - return fmt3.Errorf("ContainerPath this(%v) Not Equal that(%v)", *this.ContainerPath, *that1.ContainerPath) - } - } else if this.ContainerPath != nil { - return fmt3.Errorf("this.ContainerPath == nil && that.ContainerPath != nil") - } else if that1.ContainerPath != nil { - return fmt3.Errorf("ContainerPath this(%v) Not Equal that(%v)", this.ContainerPath, that1.ContainerPath) - } - if this.HostPath != nil && that1.HostPath != nil { - if *this.HostPath != *that1.HostPath { - return fmt3.Errorf("HostPath this(%v) Not Equal that(%v)", *this.HostPath, *that1.HostPath) - } - } else if this.HostPath != nil { - return fmt3.Errorf("this.HostPath == nil && that.HostPath != nil") - } else if that1.HostPath != nil { - return fmt3.Errorf("HostPath this(%v) Not Equal that(%v)", this.HostPath, that1.HostPath) - } - if this.Mode != nil && that1.Mode != nil { - if *this.Mode != *that1.Mode { - return fmt3.Errorf("Mode this(%v) Not Equal that(%v)", *this.Mode, *that1.Mode) - } - } else if this.Mode != nil { - return fmt3.Errorf("this.Mode == nil && that.Mode != nil") - } else if that1.Mode != nil { - return fmt3.Errorf("Mode this(%v) Not Equal that(%v)", this.Mode, that1.Mode) - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *Volume) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*Volume) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.ContainerPath != nil && that1.ContainerPath != nil { - if *this.ContainerPath != *that1.ContainerPath { - return false - } - } else if this.ContainerPath != nil { - return false - } else if that1.ContainerPath != nil { - return false - } - if this.HostPath != nil && that1.HostPath != nil { - if *this.HostPath != *that1.HostPath { - return false +func (m *ContainerInfo_DockerInfo) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.HostPath != nil { - return false - } else if that1.HostPath != nil { - return false - } - if this.Mode != nil && that1.Mode != nil { - if *this.Mode != *that1.Mode { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Image", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Image = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Network", wireType) + } + var v ContainerInfo_DockerInfo_Network + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (ContainerInfo_DockerInfo_Network(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Network = &v + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PortMappings", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PortMappings = append(m.PortMappings, &ContainerInfo_DockerInfo_PortMapping{}) + if err := m.PortMappings[len(m.PortMappings)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Privileged", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Privileged = &b + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Parameters = append(m.Parameters, &Parameter{}) + if err := m.Parameters[len(m.Parameters)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ForcePullImage", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.ForcePullImage = &b + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Mode != nil { - return false - } else if that1.Mode != nil { - return false } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true -} -func (this *ContainerInfo) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("image") } - that1, ok := that.(*ContainerInfo) - if !ok { - return fmt3.Errorf("that is not of type *ContainerInfo") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *ContainerInfo but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ContainerInfobut is not nil && this == nil") - } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return fmt3.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) - } - } else if this.Type != nil { - return fmt3.Errorf("this.Type == nil && that.Type != nil") - } else if that1.Type != nil { - return fmt3.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) - } - if len(this.Volumes) != len(that1.Volumes) { - return fmt3.Errorf("Volumes this(%v) Not Equal that(%v)", len(this.Volumes), len(that1.Volumes)) - } - for i := range this.Volumes { - if !this.Volumes[i].Equal(that1.Volumes[i]) { - return fmt3.Errorf("Volumes this[%v](%v) Not Equal that[%v](%v)", i, this.Volumes[i], i, that1.Volumes[i]) - } - } - if this.Hostname != nil && that1.Hostname != nil { - if *this.Hostname != *that1.Hostname { - return fmt3.Errorf("Hostname this(%v) Not Equal that(%v)", *this.Hostname, *that1.Hostname) - } - } else if this.Hostname != nil { - return fmt3.Errorf("this.Hostname == nil && that.Hostname != nil") - } else if that1.Hostname != nil { - return fmt3.Errorf("Hostname this(%v) Not Equal that(%v)", this.Hostname, that1.Hostname) - } - if !this.Docker.Equal(that1.Docker) { - return fmt3.Errorf("Docker this(%v) Not Equal that(%v)", this.Docker, that1.Docker) - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *ContainerInfo) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*ContainerInfo) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return false - } - } else if this.Type != nil { - return false - } else if that1.Type != nil { - return false - } - if len(this.Volumes) != len(that1.Volumes) { - return false - } - for i := range this.Volumes { - if !this.Volumes[i].Equal(that1.Volumes[i]) { - return false +func (m *ContainerInfo_DockerInfo_PortMapping) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } - if this.Hostname != nil && that1.Hostname != nil { - if *this.Hostname != *that1.Hostname { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HostPort", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.HostPort = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerPort", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.ContainerPort = &v + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Protocol = &s + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Hostname != nil { - return false - } else if that1.Hostname != nil { - return false - } - if !this.Docker.Equal(that1.Docker) { - return false } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("host_port") } - return true -} -func (this *ContainerInfo_DockerInfo) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that == nil && this != nil") + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("container_port") } - that1, ok := that.(*ContainerInfo_DockerInfo) - if !ok { - return fmt3.Errorf("that is not of type *ContainerInfo_DockerInfo") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *ContainerInfo_DockerInfo but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ContainerInfo_DockerInfobut is not nil && this == nil") - } - if this.Image != nil && that1.Image != nil { - if *this.Image != *that1.Image { - return fmt3.Errorf("Image this(%v) Not Equal that(%v)", *this.Image, *that1.Image) - } - } else if this.Image != nil { - return fmt3.Errorf("this.Image == nil && that.Image != nil") - } else if that1.Image != nil { - return fmt3.Errorf("Image this(%v) Not Equal that(%v)", this.Image, that1.Image) - } - if this.Network != nil && that1.Network != nil { - if *this.Network != *that1.Network { - return fmt3.Errorf("Network this(%v) Not Equal that(%v)", *this.Network, *that1.Network) - } - } else if this.Network != nil { - return fmt3.Errorf("this.Network == nil && that.Network != nil") - } else if that1.Network != nil { - return fmt3.Errorf("Network this(%v) Not Equal that(%v)", this.Network, that1.Network) - } - if len(this.PortMappings) != len(that1.PortMappings) { - return fmt3.Errorf("PortMappings this(%v) Not Equal that(%v)", len(this.PortMappings), len(that1.PortMappings)) - } - for i := range this.PortMappings { - if !this.PortMappings[i].Equal(that1.PortMappings[i]) { - return fmt3.Errorf("PortMappings this[%v](%v) Not Equal that[%v](%v)", i, this.PortMappings[i], i, that1.PortMappings[i]) - } - } - if this.Privileged != nil && that1.Privileged != nil { - if *this.Privileged != *that1.Privileged { - return fmt3.Errorf("Privileged this(%v) Not Equal that(%v)", *this.Privileged, *that1.Privileged) + return nil +} +func (m *Labels) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Privileged != nil { - return fmt3.Errorf("this.Privileged == nil && that.Privileged != nil") - } else if that1.Privileged != nil { - return fmt3.Errorf("Privileged this(%v) Not Equal that(%v)", this.Privileged, that1.Privileged) - } - if len(this.Parameters) != len(that1.Parameters) { - return fmt3.Errorf("Parameters this(%v) Not Equal that(%v)", len(this.Parameters), len(that1.Parameters)) - } - for i := range this.Parameters { - if !this.Parameters[i].Equal(that1.Parameters[i]) { - return fmt3.Errorf("Parameters this[%v](%v) Not Equal that[%v](%v)", i, this.Parameters[i], i, that1.Parameters[i]) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Labels = append(m.Labels, &Label{}) + if err := m.Labels[len(m.Labels)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } + return nil } -func (this *ContainerInfo_DockerInfo) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - - that1, ok := that.(*ContainerInfo_DockerInfo) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Image != nil && that1.Image != nil { - if *this.Image != *that1.Image { - return false +func (m *Label) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Image != nil { - return false - } else if that1.Image != nil { - return false - } - if this.Network != nil && that1.Network != nil { - if *this.Network != *that1.Network { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Key = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Value = &s + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Network != nil { - return false - } else if that1.Network != nil { - return false - } - if len(this.PortMappings) != len(that1.PortMappings) { - return false } - for i := range this.PortMappings { - if !this.PortMappings[i].Equal(that1.PortMappings[i]) { - return false - } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("key") } - if this.Privileged != nil && that1.Privileged != nil { - if *this.Privileged != *that1.Privileged { - return false + + return nil +} +func (m *Port) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.Privileged != nil { - return false - } else if that1.Privileged != nil { - return false - } - if len(this.Parameters) != len(that1.Parameters) { - return false - } - for i := range this.Parameters { - if !this.Parameters[i].Equal(that1.Parameters[i]) { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Number", wireType) + } + var v uint32 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Number = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Protocol = &s + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("number") } - return true + + return nil } -func (this *ContainerInfo_DockerInfo_PortMapping) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func (m *Ports) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ports = append(m.Ports, &Port{}) + if err := m.Ports[len(m.Ports)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt3.Errorf("that == nil && this != nil") } - that1, ok := that.(*ContainerInfo_DockerInfo_PortMapping) - if !ok { - return fmt3.Errorf("that is not of type *ContainerInfo_DockerInfo_PortMapping") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt3.Errorf("that is type *ContainerInfo_DockerInfo_PortMapping but is nil && this != nil") - } else if this == nil { - return fmt3.Errorf("that is type *ContainerInfo_DockerInfo_PortMappingbut is not nil && this == nil") - } - if this.HostPort != nil && that1.HostPort != nil { - if *this.HostPort != *that1.HostPort { - return fmt3.Errorf("HostPort this(%v) Not Equal that(%v)", *this.HostPort, *that1.HostPort) - } - } else if this.HostPort != nil { - return fmt3.Errorf("this.HostPort == nil && that.HostPort != nil") - } else if that1.HostPort != nil { - return fmt3.Errorf("HostPort this(%v) Not Equal that(%v)", this.HostPort, that1.HostPort) - } - if this.ContainerPort != nil && that1.ContainerPort != nil { - if *this.ContainerPort != *that1.ContainerPort { - return fmt3.Errorf("ContainerPort this(%v) Not Equal that(%v)", *this.ContainerPort, *that1.ContainerPort) - } - } else if this.ContainerPort != nil { - return fmt3.Errorf("this.ContainerPort == nil && that.ContainerPort != nil") - } else if that1.ContainerPort != nil { - return fmt3.Errorf("ContainerPort this(%v) Not Equal that(%v)", this.ContainerPort, that1.ContainerPort) - } - if this.Protocol != nil && that1.Protocol != nil { - if *this.Protocol != *that1.Protocol { - return fmt3.Errorf("Protocol this(%v) Not Equal that(%v)", *this.Protocol, *that1.Protocol) - } - } else if this.Protocol != nil { - return fmt3.Errorf("this.Protocol == nil && that.Protocol != nil") - } else if that1.Protocol != nil { - return fmt3.Errorf("Protocol this(%v) Not Equal that(%v)", this.Protocol, that1.Protocol) - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) - } return nil } -func (this *ContainerInfo_DockerInfo_PortMapping) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *DiscoveryInfo) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } - - that1, ok := that.(*ContainerInfo_DockerInfo_PortMapping) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Visibility", wireType) + } + var v DiscoveryInfo_Visibility + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (DiscoveryInfo_Visibility(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Visibility = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Environment", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Environment = &s + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Location", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Location = &s + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthMesos + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Version = &s + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Ports == nil { + m.Ports = &Ports{} + } + if err := m.Ports.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMesos + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Labels == nil { + m.Labels = &Labels{} + } + if err := m.Labels.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipMesos(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMesos + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false - } else if this == nil { - return false } - if this.HostPort != nil && that1.HostPort != nil { - if *this.HostPort != *that1.HostPort { - return false - } - } else if this.HostPort != nil { - return false - } else if that1.HostPort != nil { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("visibility") } - if this.ContainerPort != nil && that1.ContainerPort != nil { - if *this.ContainerPort != *that1.ContainerPort { - return false + + return nil +} +func skipMesos(data []byte) (n int, err error) { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - } else if this.ContainerPort != nil { - return false - } else if that1.ContainerPort != nil { - return false - } - if this.Protocol != nil && that1.Protocol != nil { - if *this.Protocol != *that1.Protocol { - return false + wireType := int(wire & 0x7) + switch wireType { + case 0: + for { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if data[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthMesos + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipMesos(data[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) } - } else if this.Protocol != nil { - return false - } else if that1.Protocol != nil { - return false - } - if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false } - return true + panic("unreachable") } + +var ( + ErrInvalidLengthMesos = fmt.Errorf("proto: negative length found during unmarshaling") +) diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesos.proto b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesos.proto index 545879ede879..2d00b43fdec2 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesos.proto +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesos.proto @@ -105,52 +105,83 @@ message ContainerID { /** - * Describes a framework. The user field is used to determine the - * Unix user that an executor/task should be launched as. If the user - * field is set to an empty string Mesos will automagically set it - * to the current user. Note that the ID is only available after a - * framework has registered, however, it is included here in order to - * facilitate scheduler failover (i.e., if it is set then the - * MesosSchedulerDriver expects the scheduler is performing failover). - * The amount of time that the master will wait for the scheduler to - * failover before removing the framework is specified by - * failover_timeout. If checkpoint is set, framework pid, executor - * pids and status updates are checkpointed to disk by the slaves. - * Checkpointing allows a restarted slave to reconnect with old - * executors and recover status updates, at the cost of disk I/O. - * The role field is used to group frameworks for allocation - * decisions, depending on the allocation policy being used. - * If the hostname field is set to an empty string Mesos will - * automagically set it to the current hostname. - * The principal field should match the credential the framework uses - * in authentication. This field is used for framework API rate - * exporting and limiting and should be set even if authentication is - * not enabled if these features are desired. - * The webui_url field allows a framework to advertise its web UI, so - * that the Mesos web UI can link to it. It is expected to be a full - * URL, for example http://my-scheduler.example.com:8080/. + * Describes a framework. */ message FrameworkInfo { + // Used to determine the Unix user that an executor or task should + // be launched as. If the user field is set to an empty string Mesos + // will automagically set it to the current user. required string user = 1; + + // Name of the framework that shows up in the Mesos Web UI. required string name = 2; + + // Note that 'id' is only available after a framework has + // registered, however, it is included here in order to facilitate + // scheduler failover (i.e., if it is set then the + // MesosSchedulerDriver expects the scheduler is performing + // failover). optional FrameworkID id = 3; + + // The amount of time that the master will wait for the scheduler to + // failover before it tears down the framework by killing all its + // tasks/executors. This should be non-zero if a framework expects + // to reconnect after a failover and not lose its tasks/executors. optional double failover_timeout = 4 [default = 0.0]; + + // If set, framework pid, executor pids and status updates are + // checkpointed to disk by the slaves. Checkpointing allows a + // restarted slave to reconnect with old executors and recover + // status updates, at the cost of disk I/O. optional bool checkpoint = 5 [default = false]; + + // Used to group frameworks for allocation decisions, depending on + // the allocation policy being used. optional string role = 6 [default = "*"]; + + // Used to indicate the current host from which the scheduler is + // registered in the Mesos Web UI. If set to an empty string Mesos + // will automagically set it to the current hostname. optional string hostname = 7; + + // This field should match the credential's principal the framework + // uses for authentication. This field is used for framework API + // rate limiting and dynamic reservations. It should be set even + // if authentication is not enabled if these features are desired. optional string principal = 8; + + // This field allows a framework to advertise its web UI, so that + // the Mesos web UI can link to it. It is expected to be a full URL, + // for example http://my-scheduler.example.com:8080/. optional string webui_url = 9; + + message Capability { + enum Type { + // Receive offers with revocable resources. See 'Resource' + // message for details. + // TODO(vinod): This is currently a no-op. + REVOCABLE_RESOURCES = 1; + } + + required Type type = 1; + } + + // This field allows a framework to advertise its set of + // capabilities (e.g., ability to receive offers for revocable + // resources). + repeated Capability capabilities = 10; } /** * Describes a health check for a task or executor (or any arbitrary * process/command). A "strategy" is picked by specifying one of the - * optional fields, currently only 'http' and 'command' are - * supported. Specifying more than one strategy is an error. + * optional fields; currently only 'command' is supported. + * Specifying more than one strategy is an error. */ message HealthCheck { - // Describes an HTTP health check. + // Describes an HTTP health check. This is not fully implemented and not + // recommended for use - see MESOS-2533. message HTTP { // Port to send the HTTP request. required uint32 port = 1; @@ -170,6 +201,7 @@ message HealthCheck { // for specific data in the response. } + // HTTP health check - not yet recommended for use, see MESOS-2533. optional HTTP http = 1; // TODO(benh): Consider adding a URL health check strategy which @@ -177,12 +209,7 @@ message HealthCheck { // encapsulates all the details in a single string field. // TODO(benh): Other possible health check strategies could include - // one for TCP/UDP or a "command". A "command" could be running a - // (shell) command to check the healthiness. We'd need to determine - // what arguments (or environment variables) we'd want to set so - // that the command could do it's job (i.e., do we want to expose - // the stdout/stderr and/or the pid to make checking for healthiness - // easier). + // one for TCP/UDP. // Amount of time to wait until starting the health checks. optional double delay_seconds = 2 [default = 15.0]; @@ -218,7 +245,24 @@ message CommandInfo { message URI { required string value = 1; optional bool executable = 2; + + // In case the fetched file is recognized as an archive, extract + // its contents into the sandbox. Note that a cached archive is + // not copied from the cache to the sandbox in case extraction + // originates from an archive in the cache. optional bool extract = 3 [default = true]; + + // If this field is "true", the fetcher cache will be used. If not, + // fetching bypasses the cache and downloads directly into the + // sandbox directory, no matter whether a suitable cache file is + // available or not. The former directs the fetcher to download to + // the file cache, then copy from there to the sandbox. Subsequent + // fetch attempts with the same URI will omit downloading and copy + // from the cache as long as the file is resident there. Cache files + // may get evicted at any time, which then leads to renewed + // downloading. See also "docs/fetcher.md" and + // "docs/fetcher-cache-internals.md". + optional bool cache = 4; } // Describes a container. @@ -293,6 +337,12 @@ message ExecutorInfo { // usage information into a time series database for monitoring. optional string source = 10; optional bytes data = 4; + + // Service discovery information for the executor. It is not + // interpreted or acted upon by Mesos. It is up to a service + // discovery system to use this information as needed and to handle + // executors without service discovery information. + optional DiscoveryInfo discovery = 12; } @@ -307,6 +357,7 @@ message MasterInfo { required uint32 port = 3 [default = 5050]; optional string pid = 4; optional string hostname = 5; + optional string version = 6; } @@ -323,6 +374,8 @@ message SlaveInfo { repeated Resource resources = 3; repeated Attribute attributes = 5; optional SlaveID id = 6; + // TODO(joerg84): Remove checkpoint field as with 0.22.0 + // slave checkpointing is enabled for all slaves (MESOS-2317). optional bool checkpoint = 7 [default = false]; } @@ -399,15 +452,122 @@ message Resource { optional Value.Ranges ranges = 4; optional Value.Set set = 5; optional string role = 6 [default = "*"]; + + message ReservationInfo { + // Describes a dynamic reservation. A dynamic reservation is + // acquired by an operator via the '/reserve' HTTP endpoint or by + // a framework via the offer cycle by sending back an + // 'Offer::Operation::Reserve' message. + // NOTE: We currently do not allow frameworks with role "*" to + // make dynamic reservations. + + // This field indicates the principal of the operator or framework + // that reserved this resource. It is used in conjunction with the + // "unreserve" ACL to determine whether the entity attempting to + // unreserve this resource is permitted to do so. + // NOTE: This field should match the FrameworkInfo.principal of + // the framework that reserved this resource. + required string principal = 1; + } + + // If this is set, this resource was dynamically reserved by an + // operator or a framework. Otherwise, this resource is either unreserved + // or statically reserved by an operator via the --resources flag. + optional ReservationInfo reservation = 8; + + message DiskInfo { + // Describes a persistent disk volume. + // A persistent disk volume will not be automatically garbage + // collected if the task/executor/slave terminates, but is + // re-offered to the framework(s) belonging to the 'role'. + // A framework can set the ID (if it is not set yet) to express + // the intention to create a new persistent disk volume from a + // regular disk resource. To reuse a previously created volume, a + // framework can launch a task/executor when it receives an offer + // with a persistent volume, i.e., ID is set. + // NOTE: Currently, we do not allow a persistent disk volume + // without a reservation (i.e., 'role' should not be '*'). + message Persistence { + // A unique ID for the persistent disk volume. + // NOTE: The ID needs to be unique per role on each slave. + required string id = 1; + } + + optional Persistence persistence = 1; + + // Describes how this disk resource will be mounted in the + // container. If not set, the disk resource will be used as the + // sandbox. Otherwise, it will be mounted according to the + // 'container_path' inside 'volume'. The 'host_path' inside + // 'volume' is ignored. + // NOTE: If 'volume' is set but 'persistence' is not set, the + // volume will be automatically garbage collected after + // task/executor terminates. Currently, if 'persistence' is set, + // 'volume' must be set. + optional Volume volume = 2; + } + + optional DiskInfo disk = 7; + + message RevocableInfo {} + + // If this is set, the resources are revocable, i.e., any tasks or + // executors launched using these resources could get preempted or + // throttled at any time. This could be used by frameworks to run + // best effort tasks that do not need strict uptime or performance + // guarantees. Note that if this is set, 'disk' or 'reservation' + // cannot be set. + optional RevocableInfo revocable = 9; +} + +/** + * When the network bandwidth caps are enabled and the container + * is over its limit, outbound packets may be either delayed or + * dropped completely either because it exceeds the maximum bandwidth + * allocation for a single container (the cap) or because the combined + * network traffic of multiple containers on the host exceeds the + * transmit capacity of the host (the share). We can report the + * following statistics for each of these conditions exported directly + * from the Linux Traffic Control Queueing Discipline. + * + * id : name of the limiter, e.g. 'tx_bw_cap' + * backlog : number of packets currently delayed + * bytes : total bytes seen + * drops : number of packets dropped in total + * overlimits : number of packets which exceeded allocation + * packets : total packets seen + * qlen : number of packets currently queued + * rate_bps : throughput in bytes/sec + * rate_pps : throughput in packets/sec + * requeues : number of times a packet has been delayed due to + * locking or device contention issues + * + * More information on the operation of Linux Traffic Control can be + * found at http://www.lartc.org/lartc.html. + */ +message TrafficControlStatistics { + required string id = 1; + optional uint64 backlog = 2; + optional uint64 bytes = 3; + optional uint64 drops = 4; + optional uint64 overlimits = 5; + optional uint64 packets = 6; + optional uint64 qlen = 7; + optional uint64 ratebps = 8; + optional uint64 ratepps = 9; + optional uint64 requeues = 10; } -/* +/** * A snapshot of resource usage statistics. */ message ResourceStatistics { required double timestamp = 1; // Snapshot time, in seconds since the Epoch. + optional uint32 processes = 30; + optional uint32 threads = 31; + // CPU Usage Information: // Total CPU time spent in user mode, and kernel mode. optional double cpus_user_time_secs = 2; @@ -422,17 +582,55 @@ message ResourceStatistics { optional double cpus_throttled_time_secs = 9; // Memory Usage Information: - optional uint64 mem_rss_bytes = 5; // Resident Set Size. - // Amount of memory resources allocated. + // mem_total_bytes was added in 0.23.0 to represent the total memory + // of a process in RAM (as opposed to in Swap). This was previously + // reported as mem_rss_bytes, which was also changed in 0.23.0 to + // represent only the anonymous memory usage, to keep in sync with + // Linux kernel's (arguably erroneous) use of terminology. + optional uint64 mem_total_bytes = 36; + + // Total memory + swap usage. This is set if swap is enabled. + optional uint64 mem_total_memsw_bytes = 37; + + // Hard memory limit for a container. optional uint64 mem_limit_bytes = 6; - // Broken out memory usage information (files, anonymous, and mmaped files) + // Soft memory limit for a container. + optional uint64 mem_soft_limit_bytes = 38; + + // Broken out memory usage information: pagecache, rss (anonymous), + // mmaped files and swap. + + // TODO(chzhcn) mem_file_bytes and mem_anon_bytes are deprecated in + // 0.23.0 and will be removed in 0.24.0. optional uint64 mem_file_bytes = 10; optional uint64 mem_anon_bytes = 11; - optional uint64 mem_mapped_file_bytes = 12; - // TODO(bmahler): Add disk usage. + // mem_cache_bytes is added in 0.23.0 to represent page cache usage. + optional uint64 mem_cache_bytes = 39; + + // Since 0.23.0, mem_rss_bytes is changed to represent only + // anonymous memory usage. Note that neither its requiredness, type, + // name nor numeric tag has been changed. + optional uint64 mem_rss_bytes = 5; + + optional uint64 mem_mapped_file_bytes = 12; + // This is only set if swap is enabled. + optional uint64 mem_swap_bytes = 40; + + // Number of occurrences of different levels of memory pressure + // events reported by memory cgroup. Pressure listening (re)starts + // with these values set to 0 when slave (re)starts. See + // https://www.kernel.org/doc/Documentation/cgroups/memory.txt for + // more details. + optional uint64 mem_low_pressure_counter = 32; + optional uint64 mem_medium_pressure_counter = 33; + optional uint64 mem_critical_pressure_counter = 34; + + // Disk Usage Information for executor working directory. + optional uint64 disk_limit_bytes = 26; + optional uint64 disk_used_bytes = 27; // Perf statistics. optional PerfStatistics perf = 13; @@ -453,34 +651,36 @@ message ResourceStatistics { optional double net_tcp_rtt_microsecs_p90 = 23; optional double net_tcp_rtt_microsecs_p95 = 24; optional double net_tcp_rtt_microsecs_p99 = 25; + + optional double net_tcp_active_connections = 28; + optional double net_tcp_time_wait_connections = 29; + + // Network traffic flowing into or out of a container can be delayed + // or dropped due to congestion or policy inside and outside the + // container. + repeated TrafficControlStatistics net_traffic_control_statistics = 35; } /** - * Describes a snapshot of the resource usage for an executor. - * - * TODO(bmahler): Note that we want to be sending this information - * to the master, and subsequently to the relevant scheduler. So - * this proto is designed to be easy for the scheduler to use, this - * is why we provide the slave id, executor info / task info. + * Describes a snapshot of the resource usage for executors. */ message ResourceUsage { - required SlaveID slave_id = 1; - required FrameworkID framework_id = 2; + message Executor { + required ExecutorInfo executor_info = 1; - // Resource usage is for an executor. For tasks launched with - // an explicit executor, the executor id is provided. For tasks - // launched without an executor, our internal executor will be - // used. In this case, we provide the task id here instead, in - // order to make this message easier for schedulers to work with. + // This includes resources used by the executor itself + // as well as its active tasks. + repeated Resource allocated = 2; - optional ExecutorID executor_id = 3; // If present, this executor was - optional string executor_name = 4; // explicitly specified. + // Current resource usage. If absent, the containerizer + // cannot provide resource usage. + optional ResourceStatistics statistics = 3; + } - optional TaskID task_id = 5; // If present, the task did not have an executor. + repeated Executor executors = 1; - // If missing, the isolation module cannot provide resource usage. - optional ResourceStatistics statistics = 6; + // TODO(jieyu): Include slave's total resources here. } @@ -564,6 +764,8 @@ message PerfStatistics { * to proactively influence the allocator. If 'slave_id' is provided * then this request is assumed to only apply to resources on that * slave. + * + * TODO(vinod): Remove this once the old driver is removed. */ message Request { optional SlaveID slave_id = 1; @@ -583,6 +785,44 @@ message Offer { repeated Resource resources = 5; repeated Attribute attributes = 7; repeated ExecutorID executor_ids = 6; + + // Defines an operation that can be performed against offers. + message Operation { + enum Type { + LAUNCH = 1; + RESERVE = 2; + UNRESERVE = 3; + CREATE = 4; + DESTROY = 5; + } + + message Launch { + repeated TaskInfo task_infos = 1; + } + + message Reserve { + repeated Resource resources = 1; + } + + message Unreserve { + repeated Resource resources = 1; + } + + message Create { + repeated Resource volumes = 1; + } + + message Destroy { + repeated Resource volumes = 1; + } + + required Type type = 1; + optional Launch launch = 2; + optional Reserve reserve = 3; + optional Unreserve unreserve = 4; + optional Create create = 5; + optional Destroy destroy = 6; + } } @@ -607,6 +847,19 @@ message TaskInfo { // A health check for the task (currently in *alpha* and initial // support will only be for TaskInfo's that have a CommandInfo). optional HealthCheck health_check = 8; + + // Labels are free-form key value pairs which are exposed through + // master and slave endpoints. Labels will not be interpreted or + // acted upon by Mesos itself. As opposed to the data field, labels + // will be kept in memory on master and slave processes. Therefore, + // labels should be used to tag tasks with light-weight meta-data. + optional Labels labels = 10; + + // Service discovery information for the task. It is not interpreted + // or acted upon by Mesos. It is up to a service discovery system + // to use this information as needed and to handle tasks without + // service discovery information. + optional DiscoveryInfo discovery = 11; } @@ -625,8 +878,6 @@ enum TaskState { TASK_FAILED = 3; // TERMINAL. The task failed to finish successfully. TASK_KILLED = 4; // TERMINAL. The task was killed by the executor. TASK_LOST = 5; // TERMINAL. The task failed but can be rescheduled. - // TASK_ERROR is currently unused but will be introduced in 0.22.0. - // TODO(dhamon): Start using TASK_ERROR. TASK_ERROR = 7; // TERMINAL. The task description contains an error. } @@ -635,16 +886,20 @@ enum TaskState { * Describes the current status of a task. */ message TaskStatus { - /** Describes the source of the task status update. */ + // Describes the source of the task status update. enum Source { SOURCE_MASTER = 0; SOURCE_SLAVE = 1; SOURCE_EXECUTOR = 2; } - /** Detailed reason for the task status update. */ + // Detailed reason for the task status update. + // + // TODO(bmahler): Differentiate between slave removal reasons + // (e.g. unhealthy vs. unregistered for maintenance). enum Reason { REASON_COMMAND_EXECUTOR_FAILED = 0; + REASON_EXECUTOR_PREEMPTED = 17; REASON_EXECUTOR_TERMINATED = 1; REASON_EXECUTOR_UNREGISTERED = 2; REASON_FRAMEWORK_REMOVED = 3; @@ -654,6 +909,7 @@ message TaskStatus { REASON_MASTER_DISCONNECTED = 7; REASON_MEMORY_LIMIT = 8; REASON_RECONCILIATION = 9; + REASON_RESOURCES_UNKNOWN = 18; REASON_SLAVE_DISCONNECTED = 10; REASON_SLAVE_REMOVED = 11; REASON_SLAVE_RESTARTED = 12; @@ -673,6 +929,17 @@ message TaskStatus { optional ExecutorID executor_id = 7; // TODO(benh): Use in master/slave. optional double timestamp = 6; + // Statuses that are delivered reliably to the scheduler will + // include a 'uuid'. The status is considered delivered once + // it is acknowledged by the scheduler. Schedulers can choose + // to either explicitly acknowledge statuses or let the scheduler + // driver implicitly acknowledge (default). + // + // TODO(bmahler): This is currently overwritten in the scheduler + // driver and executor driver, but executors will need to set this + // to a valid RFC-4122 UUID if using the HTTP API. + optional bytes uuid = 11; + // Describes whether the task has been determined to be healthy // (true) or unhealthy (false) according to the HealthCheck field in // the command info. @@ -928,10 +1195,15 @@ message ContainerInfo { optional bool privileged = 4 [default = false]; // Allowing arbitrary parameters to be passed to docker CLI. - // Note that anything passed to this field is not guranteed + // Note that anything passed to this field is not guaranteed // to be supported moving forward, as we might move away from // the docker CLI. repeated Parameter parameters = 5; + + // With this flag set to true, the docker containerizer will + // pull the docker image from the registry even if the image + // is already downloaded on the slave. + optional bool force_pull_image = 6; } required Type type = 1; @@ -940,3 +1212,68 @@ message ContainerInfo { optional DockerInfo docker = 3; } + + +/** + * Collection of labels. + */ +message Labels { + repeated Label labels = 1; +} + + +/** + * Key, value pair used to store free form user-data. + */ +message Label { + required string key = 1; + optional string value = 2; +} + + +/** + * Named port used for service discovery. + */ +message Port { + required uint32 number = 1; + optional string name = 2; + optional string protocol = 3; +} + + +/** + * Collection of ports. + */ +message Ports { + repeated Port ports = 1; +} + + +/** +* Service discovery information. +* The visibility field restricts discovery within a framework +* (FRAMEWORK), within a Mesos cluster (CLUSTER), or places no +* restrictions (EXTERNAL). +* The environment, location, and version fields provide first class +* support for common attributes used to differentiate between +* similar services. The environment may receive values such as +* PROD/QA/DEV, the location field may receive values like +* EAST-US/WEST-US/EUROPE/AMEA, and the version field may receive +* values like v2.0/v0.9. The exact use of these fields is up to each +* service discovery system. +*/ +message DiscoveryInfo { + enum Visibility { + FRAMEWORK = 0; + CLUSTER = 1; + EXTERNAL = 2; + } + + required Visibility visibility = 1; + optional string name = 2; + optional string environment = 3; + optional string location = 4; + optional string version = 5; + optional Ports ports = 6; + optional Labels labels = 7; +} diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesospb_test.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesospb_test.go index da57cf921fcb..aef9eac80105 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesospb_test.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/mesospb_test.go @@ -8,56 +8,56 @@ import testing "testing" import math_rand "math/rand" import time "time" import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" -import testing1 "testing" -import math_rand1 "math/rand" -import time1 "time" -import encoding_json "encoding/json" -import testing2 "testing" -import math_rand2 "math/rand" -import time2 "time" -import github_com_gogo_protobuf_proto1 "github.com/gogo/protobuf/proto" -import math_rand3 "math/rand" -import time3 "time" -import testing3 "testing" +import github_com_gogo_protobuf_jsonpb "github.com/gogo/protobuf/jsonpb" import fmt "fmt" -import math_rand4 "math/rand" -import time4 "time" -import testing4 "testing" -import github_com_gogo_protobuf_proto2 "github.com/gogo/protobuf/proto" -import math_rand5 "math/rand" -import time5 "time" -import testing5 "testing" -import fmt1 "fmt" import go_parser "go/parser" -import math_rand6 "math/rand" -import time6 "time" -import testing6 "testing" -import github_com_gogo_protobuf_proto3 "github.com/gogo/protobuf/proto" +import proto "github.com/gogo/protobuf/proto" +import math "math" + +// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf func TestFrameworkIDProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedFrameworkID(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &FrameworkID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestFrameworkIDMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedFrameworkID(popr, false) size := p.Size() data := make([]byte, size) @@ -66,20 +66,20 @@ func TestFrameworkIDMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &FrameworkID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -124,29 +124,42 @@ func BenchmarkFrameworkIDProtoUnmarshal(b *testing.B) { } func TestOfferIDProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOfferID(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &OfferID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestOfferIDMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOfferID(popr, false) size := p.Size() data := make([]byte, size) @@ -155,20 +168,20 @@ func TestOfferIDMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &OfferID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -213,29 +226,42 @@ func BenchmarkOfferIDProtoUnmarshal(b *testing.B) { } func TestSlaveIDProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedSlaveID(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &SlaveID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestSlaveIDMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedSlaveID(popr, false) size := p.Size() data := make([]byte, size) @@ -244,20 +270,20 @@ func TestSlaveIDMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &SlaveID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -302,29 +328,42 @@ func BenchmarkSlaveIDProtoUnmarshal(b *testing.B) { } func TestTaskIDProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedTaskID(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &TaskID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestTaskIDMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedTaskID(popr, false) size := p.Size() data := make([]byte, size) @@ -333,20 +372,20 @@ func TestTaskIDMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &TaskID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -391,29 +430,42 @@ func BenchmarkTaskIDProtoUnmarshal(b *testing.B) { } func TestExecutorIDProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedExecutorID(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &ExecutorID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestExecutorIDMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedExecutorID(popr, false) size := p.Size() data := make([]byte, size) @@ -422,20 +474,20 @@ func TestExecutorIDMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &ExecutorID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -480,29 +532,42 @@ func BenchmarkExecutorIDProtoUnmarshal(b *testing.B) { } func TestContainerIDProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedContainerID(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &ContainerID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestContainerIDMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedContainerID(popr, false) size := p.Size() data := make([]byte, size) @@ -511,20 +576,20 @@ func TestContainerIDMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &ContainerID{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -569,29 +634,42 @@ func BenchmarkContainerIDProtoUnmarshal(b *testing.B) { } func TestFrameworkInfoProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedFrameworkInfo(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &FrameworkInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestFrameworkInfoMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedFrameworkInfo(popr, false) size := p.Size() data := make([]byte, size) @@ -600,20 +678,20 @@ func TestFrameworkInfoMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &FrameworkInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -657,30 +735,145 @@ func BenchmarkFrameworkInfoProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } +func TestFrameworkInfo_CapabilityProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkInfo_Capability(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &FrameworkInfo_Capability{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) + } +} + +func TestFrameworkInfo_CapabilityMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkInfo_Capability(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) + } + _, err := p.MarshalTo(data) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &FrameworkInfo_Capability{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + for i := range data { + data[i] = byte(popr.Intn(256)) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } +} + +func BenchmarkFrameworkInfo_CapabilityProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*FrameworkInfo_Capability, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedFrameworkInfo_Capability(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) + } + b.SetBytes(int64(total / b.N)) +} + +func BenchmarkFrameworkInfo_CapabilityProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedFrameworkInfo_Capability(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data + } + msg := &FrameworkInfo_Capability{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } + } + b.SetBytes(int64(total / b.N)) +} + func TestHealthCheckProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedHealthCheck(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &HealthCheck{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestHealthCheckMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedHealthCheck(popr, false) size := p.Size() data := make([]byte, size) @@ -689,20 +882,20 @@ func TestHealthCheckMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &HealthCheck{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -747,29 +940,42 @@ func BenchmarkHealthCheckProtoUnmarshal(b *testing.B) { } func TestHealthCheck_HTTPProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedHealthCheck_HTTP(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &HealthCheck_HTTP{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestHealthCheck_HTTPMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedHealthCheck_HTTP(popr, false) size := p.Size() data := make([]byte, size) @@ -778,20 +984,20 @@ func TestHealthCheck_HTTPMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &HealthCheck_HTTP{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -836,29 +1042,42 @@ func BenchmarkHealthCheck_HTTPProtoUnmarshal(b *testing.B) { } func TestCommandInfoProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedCommandInfo(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &CommandInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestCommandInfoMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedCommandInfo(popr, false) size := p.Size() data := make([]byte, size) @@ -867,20 +1086,20 @@ func TestCommandInfoMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &CommandInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -925,29 +1144,42 @@ func BenchmarkCommandInfoProtoUnmarshal(b *testing.B) { } func TestCommandInfo_URIProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedCommandInfo_URI(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &CommandInfo_URI{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestCommandInfo_URIMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedCommandInfo_URI(popr, false) size := p.Size() data := make([]byte, size) @@ -956,20 +1188,20 @@ func TestCommandInfo_URIMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &CommandInfo_URI{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1014,29 +1246,42 @@ func BenchmarkCommandInfo_URIProtoUnmarshal(b *testing.B) { } func TestCommandInfo_ContainerInfoProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedCommandInfo_ContainerInfo(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &CommandInfo_ContainerInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestCommandInfo_ContainerInfoMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedCommandInfo_ContainerInfo(popr, false) size := p.Size() data := make([]byte, size) @@ -1045,20 +1290,20 @@ func TestCommandInfo_ContainerInfoMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &CommandInfo_ContainerInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1103,29 +1348,42 @@ func BenchmarkCommandInfo_ContainerInfoProtoUnmarshal(b *testing.B) { } func TestExecutorInfoProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedExecutorInfo(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &ExecutorInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestExecutorInfoMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedExecutorInfo(popr, false) size := p.Size() data := make([]byte, size) @@ -1134,20 +1392,20 @@ func TestExecutorInfoMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &ExecutorInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1192,29 +1450,42 @@ func BenchmarkExecutorInfoProtoUnmarshal(b *testing.B) { } func TestMasterInfoProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedMasterInfo(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &MasterInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestMasterInfoMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedMasterInfo(popr, false) size := p.Size() data := make([]byte, size) @@ -1223,20 +1494,20 @@ func TestMasterInfoMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &MasterInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1281,29 +1552,42 @@ func BenchmarkMasterInfoProtoUnmarshal(b *testing.B) { } func TestSlaveInfoProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedSlaveInfo(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &SlaveInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestSlaveInfoMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedSlaveInfo(popr, false) size := p.Size() data := make([]byte, size) @@ -1312,20 +1596,20 @@ func TestSlaveInfoMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &SlaveInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1370,29 +1654,42 @@ func BenchmarkSlaveInfoProtoUnmarshal(b *testing.B) { } func TestValueProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestValueMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue(popr, false) size := p.Size() data := make([]byte, size) @@ -1401,20 +1698,20 @@ func TestValueMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1459,29 +1756,42 @@ func BenchmarkValueProtoUnmarshal(b *testing.B) { } func TestValue_ScalarProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue_Scalar(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value_Scalar{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestValue_ScalarMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue_Scalar(popr, false) size := p.Size() data := make([]byte, size) @@ -1490,20 +1800,20 @@ func TestValue_ScalarMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value_Scalar{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1548,29 +1858,42 @@ func BenchmarkValue_ScalarProtoUnmarshal(b *testing.B) { } func TestValue_RangeProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue_Range(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value_Range{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestValue_RangeMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue_Range(popr, false) size := p.Size() data := make([]byte, size) @@ -1579,20 +1902,20 @@ func TestValue_RangeMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value_Range{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1637,29 +1960,42 @@ func BenchmarkValue_RangeProtoUnmarshal(b *testing.B) { } func TestValue_RangesProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue_Ranges(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value_Ranges{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestValue_RangesMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue_Ranges(popr, false) size := p.Size() data := make([]byte, size) @@ -1668,20 +2004,20 @@ func TestValue_RangesMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value_Ranges{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1726,29 +2062,42 @@ func BenchmarkValue_RangesProtoUnmarshal(b *testing.B) { } func TestValue_SetProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue_Set(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value_Set{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestValue_SetMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue_Set(popr, false) size := p.Size() data := make([]byte, size) @@ -1757,20 +2106,20 @@ func TestValue_SetMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value_Set{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1815,29 +2164,42 @@ func BenchmarkValue_SetProtoUnmarshal(b *testing.B) { } func TestValue_TextProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue_Text(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value_Text{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestValue_TextMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedValue_Text(popr, false) size := p.Size() data := make([]byte, size) @@ -1846,20 +2208,20 @@ func TestValue_TextMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Value_Text{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1904,29 +2266,42 @@ func BenchmarkValue_TextProtoUnmarshal(b *testing.B) { } func TestAttributeProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAttribute(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Attribute{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestAttributeMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedAttribute(popr, false) size := p.Size() data := make([]byte, size) @@ -1935,20 +2310,20 @@ func TestAttributeMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Attribute{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -1993,29 +2368,42 @@ func BenchmarkAttributeProtoUnmarshal(b *testing.B) { } func TestResourceProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedResource(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Resource{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } func TestResourceMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedResource(popr, false) size := p.Size() data := make([]byte, size) @@ -2024,20 +2412,20 @@ func TestResourceMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Resource{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } @@ -2081,31 +2469,44 @@ func BenchmarkResourceProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestResourceStatisticsProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedResourceStatistics(popr, false) +func TestResource_ReservationInfoProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_ReservationInfo(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ResourceStatistics{} + msg := &Resource_ReservationInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestResourceStatisticsMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedResourceStatistics(popr, false) +func TestResource_ReservationInfoMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_ReservationInfo(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -2113,29 +2514,29 @@ func TestResourceStatisticsMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ResourceStatistics{} + msg := &Resource_ReservationInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkResourceStatisticsProtoMarshal(b *testing.B) { +func BenchmarkResource_ReservationInfoProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*ResourceStatistics, 10000) + pops := make([]*Resource_ReservationInfo, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedResourceStatistics(popr, false) + pops[i] = NewPopulatedResource_ReservationInfo(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -2148,18 +2549,18 @@ func BenchmarkResourceStatisticsProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkResourceStatisticsProtoUnmarshal(b *testing.B) { +func BenchmarkResource_ReservationInfoProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedResourceStatistics(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedResource_ReservationInfo(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &ResourceStatistics{} + msg := &Resource_ReservationInfo{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -2170,31 +2571,44 @@ func BenchmarkResourceStatisticsProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestResourceUsageProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedResourceUsage(popr, false) +func TestResource_DiskInfoProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ResourceUsage{} + msg := &Resource_DiskInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestResourceUsageMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedResourceUsage(popr, false) +func TestResource_DiskInfoMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -2202,29 +2616,29 @@ func TestResourceUsageMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ResourceUsage{} + msg := &Resource_DiskInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkResourceUsageProtoMarshal(b *testing.B) { +func BenchmarkResource_DiskInfoProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*ResourceUsage, 10000) + pops := make([]*Resource_DiskInfo, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedResourceUsage(popr, false) + pops[i] = NewPopulatedResource_DiskInfo(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -2237,18 +2651,18 @@ func BenchmarkResourceUsageProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkResourceUsageProtoUnmarshal(b *testing.B) { +func BenchmarkResource_DiskInfoProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedResourceUsage(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedResource_DiskInfo(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &ResourceUsage{} + msg := &Resource_DiskInfo{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -2259,31 +2673,44 @@ func BenchmarkResourceUsageProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestPerfStatisticsProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedPerfStatistics(popr, false) +func TestResource_DiskInfo_PersistenceProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo_Persistence(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &PerfStatistics{} + msg := &Resource_DiskInfo_Persistence{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestPerfStatisticsMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedPerfStatistics(popr, false) +func TestResource_DiskInfo_PersistenceMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo_Persistence(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -2291,29 +2718,29 @@ func TestPerfStatisticsMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &PerfStatistics{} + msg := &Resource_DiskInfo_Persistence{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkPerfStatisticsProtoMarshal(b *testing.B) { +func BenchmarkResource_DiskInfo_PersistenceProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*PerfStatistics, 10000) + pops := make([]*Resource_DiskInfo_Persistence, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedPerfStatistics(popr, false) + pops[i] = NewPopulatedResource_DiskInfo_Persistence(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -2326,18 +2753,18 @@ func BenchmarkPerfStatisticsProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkPerfStatisticsProtoUnmarshal(b *testing.B) { +func BenchmarkResource_DiskInfo_PersistenceProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedPerfStatistics(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedResource_DiskInfo_Persistence(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &PerfStatistics{} + msg := &Resource_DiskInfo_Persistence{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -2348,31 +2775,44 @@ func BenchmarkPerfStatisticsProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestRequestProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedRequest(popr, false) +func TestResource_RevocableInfoProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_RevocableInfo(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Request{} + msg := &Resource_RevocableInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestRequestMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedRequest(popr, false) +func TestResource_RevocableInfoMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_RevocableInfo(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -2380,29 +2820,29 @@ func TestRequestMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Request{} + msg := &Resource_RevocableInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkRequestProtoMarshal(b *testing.B) { +func BenchmarkResource_RevocableInfoProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*Request, 10000) + pops := make([]*Resource_RevocableInfo, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedRequest(popr, false) + pops[i] = NewPopulatedResource_RevocableInfo(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -2415,18 +2855,18 @@ func BenchmarkRequestProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkRequestProtoUnmarshal(b *testing.B) { +func BenchmarkResource_RevocableInfoProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedRequest(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedResource_RevocableInfo(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &Request{} + msg := &Resource_RevocableInfo{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -2437,31 +2877,44 @@ func BenchmarkRequestProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestOfferProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedOffer(popr, false) +func TestTrafficControlStatisticsProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTrafficControlStatistics(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Offer{} + msg := &TrafficControlStatistics{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestOfferMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedOffer(popr, false) +func TestTrafficControlStatisticsMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTrafficControlStatistics(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -2469,29 +2922,29 @@ func TestOfferMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Offer{} + msg := &TrafficControlStatistics{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkOfferProtoMarshal(b *testing.B) { +func BenchmarkTrafficControlStatisticsProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*Offer, 10000) + pops := make([]*TrafficControlStatistics, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedOffer(popr, false) + pops[i] = NewPopulatedTrafficControlStatistics(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -2504,18 +2957,18 @@ func BenchmarkOfferProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkOfferProtoUnmarshal(b *testing.B) { +func BenchmarkTrafficControlStatisticsProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOffer(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedTrafficControlStatistics(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &Offer{} + msg := &TrafficControlStatistics{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -2526,31 +2979,44 @@ func BenchmarkOfferProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestTaskInfoProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedTaskInfo(popr, false) +func TestResourceStatisticsProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceStatistics(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &TaskInfo{} + msg := &ResourceStatistics{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestTaskInfoMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedTaskInfo(popr, false) +func TestResourceStatisticsMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceStatistics(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -2558,29 +3024,29 @@ func TestTaskInfoMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &TaskInfo{} + msg := &ResourceStatistics{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkTaskInfoProtoMarshal(b *testing.B) { +func BenchmarkResourceStatisticsProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*TaskInfo, 10000) + pops := make([]*ResourceStatistics, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedTaskInfo(popr, false) + pops[i] = NewPopulatedResourceStatistics(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -2593,18 +3059,18 @@ func BenchmarkTaskInfoProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkTaskInfoProtoUnmarshal(b *testing.B) { +func BenchmarkResourceStatisticsProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedTaskInfo(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedResourceStatistics(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &TaskInfo{} + msg := &ResourceStatistics{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -2615,31 +3081,44 @@ func BenchmarkTaskInfoProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestTaskStatusProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedTaskStatus(popr, false) +func TestResourceUsageProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &TaskStatus{} + msg := &ResourceUsage{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestTaskStatusMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedTaskStatus(popr, false) +func TestResourceUsageMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -2647,29 +3126,29 @@ func TestTaskStatusMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &TaskStatus{} + msg := &ResourceUsage{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkTaskStatusProtoMarshal(b *testing.B) { +func BenchmarkResourceUsageProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*TaskStatus, 10000) + pops := make([]*ResourceUsage, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedTaskStatus(popr, false) + pops[i] = NewPopulatedResourceUsage(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -2682,18 +3161,18 @@ func BenchmarkTaskStatusProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkTaskStatusProtoUnmarshal(b *testing.B) { +func BenchmarkResourceUsageProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedTaskStatus(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedResourceUsage(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &TaskStatus{} + msg := &ResourceUsage{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -2704,31 +3183,44 @@ func BenchmarkTaskStatusProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestFiltersProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedFilters(popr, false) +func TestResourceUsage_ExecutorProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage_Executor(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Filters{} + msg := &ResourceUsage_Executor{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestFiltersMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedFilters(popr, false) +func TestResourceUsage_ExecutorMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage_Executor(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -2736,29 +3228,29 @@ func TestFiltersMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Filters{} + msg := &ResourceUsage_Executor{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkFiltersProtoMarshal(b *testing.B) { +func BenchmarkResourceUsage_ExecutorProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*Filters, 10000) + pops := make([]*ResourceUsage_Executor, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedFilters(popr, false) + pops[i] = NewPopulatedResourceUsage_Executor(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -2771,18 +3263,18 @@ func BenchmarkFiltersProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkFiltersProtoUnmarshal(b *testing.B) { +func BenchmarkResourceUsage_ExecutorProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedFilters(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedResourceUsage_Executor(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &Filters{} + msg := &ResourceUsage_Executor{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -2793,31 +3285,44 @@ func BenchmarkFiltersProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestEnvironmentProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedEnvironment(popr, false) +func TestPerfStatisticsProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPerfStatistics(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Environment{} + msg := &PerfStatistics{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestEnvironmentMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedEnvironment(popr, false) +func TestPerfStatisticsMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPerfStatistics(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -2825,29 +3330,29 @@ func TestEnvironmentMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Environment{} + msg := &PerfStatistics{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkEnvironmentProtoMarshal(b *testing.B) { +func BenchmarkPerfStatisticsProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*Environment, 10000) + pops := make([]*PerfStatistics, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedEnvironment(popr, false) + pops[i] = NewPopulatedPerfStatistics(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -2860,18 +3365,18 @@ func BenchmarkEnvironmentProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkEnvironmentProtoUnmarshal(b *testing.B) { +func BenchmarkPerfStatisticsProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedEnvironment(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedPerfStatistics(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &Environment{} + msg := &PerfStatistics{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -2882,31 +3387,44 @@ func BenchmarkEnvironmentProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestEnvironment_VariableProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedEnvironment_Variable(popr, false) +func TestRequestProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRequest(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Environment_Variable{} + msg := &Request{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestEnvironment_VariableMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedEnvironment_Variable(popr, false) +func TestRequestMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRequest(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -2914,29 +3432,29 @@ func TestEnvironment_VariableMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Environment_Variable{} + msg := &Request{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkEnvironment_VariableProtoMarshal(b *testing.B) { +func BenchmarkRequestProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*Environment_Variable, 10000) + pops := make([]*Request, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedEnvironment_Variable(popr, false) + pops[i] = NewPopulatedRequest(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -2949,18 +3467,18 @@ func BenchmarkEnvironment_VariableProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkEnvironment_VariableProtoUnmarshal(b *testing.B) { +func BenchmarkRequestProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedEnvironment_Variable(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedRequest(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &Environment_Variable{} + msg := &Request{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -2971,31 +3489,44 @@ func BenchmarkEnvironment_VariableProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestParameterProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedParameter(popr, false) +func TestOfferProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Parameter{} + msg := &Offer{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestParameterMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedParameter(popr, false) +func TestOfferMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3003,29 +3534,29 @@ func TestParameterMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Parameter{} + msg := &Offer{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkParameterProtoMarshal(b *testing.B) { +func BenchmarkOfferProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*Parameter, 10000) + pops := make([]*Offer, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedParameter(popr, false) + pops[i] = NewPopulatedOffer(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -3038,18 +3569,18 @@ func BenchmarkParameterProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkParameterProtoUnmarshal(b *testing.B) { +func BenchmarkOfferProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedParameter(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOffer(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &Parameter{} + msg := &Offer{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -3060,31 +3591,44 @@ func BenchmarkParameterProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestParametersProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedParameters(popr, false) +func TestOffer_OperationProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Parameters{} + msg := &Offer_Operation{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestParametersMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedParameters(popr, false) +func TestOffer_OperationMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3092,29 +3636,29 @@ func TestParametersMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Parameters{} + msg := &Offer_Operation{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkParametersProtoMarshal(b *testing.B) { +func BenchmarkOffer_OperationProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*Parameters, 10000) + pops := make([]*Offer_Operation, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedParameters(popr, false) + pops[i] = NewPopulatedOffer_Operation(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -3127,18 +3671,18 @@ func BenchmarkParametersProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkParametersProtoUnmarshal(b *testing.B) { +func BenchmarkOffer_OperationProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedParameters(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOffer_Operation(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &Parameters{} + msg := &Offer_Operation{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -3149,31 +3693,44 @@ func BenchmarkParametersProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestCredentialProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedCredential(popr, false) +func TestOffer_Operation_LaunchProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Launch(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Credential{} + msg := &Offer_Operation_Launch{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestCredentialMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedCredential(popr, false) +func TestOffer_Operation_LaunchMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Launch(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3181,29 +3738,29 @@ func TestCredentialMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Credential{} + msg := &Offer_Operation_Launch{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkCredentialProtoMarshal(b *testing.B) { +func BenchmarkOffer_Operation_LaunchProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*Credential, 10000) + pops := make([]*Offer_Operation_Launch, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedCredential(popr, false) + pops[i] = NewPopulatedOffer_Operation_Launch(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -3216,18 +3773,18 @@ func BenchmarkCredentialProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkCredentialProtoUnmarshal(b *testing.B) { +func BenchmarkOffer_Operation_LaunchProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedCredential(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOffer_Operation_Launch(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &Credential{} + msg := &Offer_Operation_Launch{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -3238,31 +3795,44 @@ func BenchmarkCredentialProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestCredentialsProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedCredentials(popr, false) +func TestOffer_Operation_ReserveProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Reserve(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Credentials{} + msg := &Offer_Operation_Reserve{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestCredentialsMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedCredentials(popr, false) +func TestOffer_Operation_ReserveMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Reserve(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3270,29 +3840,29 @@ func TestCredentialsMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Credentials{} + msg := &Offer_Operation_Reserve{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkCredentialsProtoMarshal(b *testing.B) { +func BenchmarkOffer_Operation_ReserveProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*Credentials, 10000) + pops := make([]*Offer_Operation_Reserve, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedCredentials(popr, false) + pops[i] = NewPopulatedOffer_Operation_Reserve(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -3305,18 +3875,18 @@ func BenchmarkCredentialsProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkCredentialsProtoUnmarshal(b *testing.B) { +func BenchmarkOffer_Operation_ReserveProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedCredentials(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOffer_Operation_Reserve(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &Credentials{} + msg := &Offer_Operation_Reserve{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -3327,31 +3897,44 @@ func BenchmarkCredentialsProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestACLProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACL(popr, false) +func TestOffer_Operation_UnreserveProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Unreserve(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACL{} + msg := &Offer_Operation_Unreserve{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestACLMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACL(popr, false) +func TestOffer_Operation_UnreserveMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Unreserve(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3359,29 +3942,29 @@ func TestACLMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACL{} + msg := &Offer_Operation_Unreserve{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACLProtoMarshal(b *testing.B) { +func BenchmarkOffer_Operation_UnreserveProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*ACL, 10000) + pops := make([]*Offer_Operation_Unreserve, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedACL(popr, false) + pops[i] = NewPopulatedOffer_Operation_Unreserve(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -3394,18 +3977,18 @@ func BenchmarkACLProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkACLProtoUnmarshal(b *testing.B) { +func BenchmarkOffer_Operation_UnreserveProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACL(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOffer_Operation_Unreserve(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &ACL{} + msg := &Offer_Operation_Unreserve{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -3416,31 +3999,44 @@ func BenchmarkACLProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestACL_EntityProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACL_Entity(popr, false) +func TestOffer_Operation_CreateProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Create(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACL_Entity{} + msg := &Offer_Operation_Create{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestACL_EntityMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACL_Entity(popr, false) +func TestOffer_Operation_CreateMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Create(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3448,29 +4044,29 @@ func TestACL_EntityMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACL_Entity{} + msg := &Offer_Operation_Create{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACL_EntityProtoMarshal(b *testing.B) { +func BenchmarkOffer_Operation_CreateProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*ACL_Entity, 10000) + pops := make([]*Offer_Operation_Create, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedACL_Entity(popr, false) + pops[i] = NewPopulatedOffer_Operation_Create(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -3483,18 +4079,18 @@ func BenchmarkACL_EntityProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkACL_EntityProtoUnmarshal(b *testing.B) { +func BenchmarkOffer_Operation_CreateProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACL_Entity(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOffer_Operation_Create(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &ACL_Entity{} + msg := &Offer_Operation_Create{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -3505,31 +4101,44 @@ func BenchmarkACL_EntityProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestACL_RegisterFrameworkProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACL_RegisterFramework(popr, false) +func TestOffer_Operation_DestroyProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Destroy(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACL_RegisterFramework{} + msg := &Offer_Operation_Destroy{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestACL_RegisterFrameworkMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACL_RegisterFramework(popr, false) +func TestOffer_Operation_DestroyMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Destroy(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3537,29 +4146,29 @@ func TestACL_RegisterFrameworkMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACL_RegisterFramework{} + msg := &Offer_Operation_Destroy{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACL_RegisterFrameworkProtoMarshal(b *testing.B) { +func BenchmarkOffer_Operation_DestroyProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*ACL_RegisterFramework, 10000) + pops := make([]*Offer_Operation_Destroy, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedACL_RegisterFramework(popr, false) + pops[i] = NewPopulatedOffer_Operation_Destroy(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -3572,18 +4181,18 @@ func BenchmarkACL_RegisterFrameworkProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkACL_RegisterFrameworkProtoUnmarshal(b *testing.B) { +func BenchmarkOffer_Operation_DestroyProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACL_RegisterFramework(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOffer_Operation_Destroy(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &ACL_RegisterFramework{} + msg := &Offer_Operation_Destroy{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -3594,31 +4203,44 @@ func BenchmarkACL_RegisterFrameworkProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestACL_RunTaskProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACL_RunTask(popr, false) +func TestTaskInfoProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskInfo(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACL_RunTask{} + msg := &TaskInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestACL_RunTaskMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACL_RunTask(popr, false) +func TestTaskInfoMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskInfo(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3626,29 +4248,29 @@ func TestACL_RunTaskMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACL_RunTask{} + msg := &TaskInfo{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACL_RunTaskProtoMarshal(b *testing.B) { +func BenchmarkTaskInfoProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*ACL_RunTask, 10000) + pops := make([]*TaskInfo, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedACL_RunTask(popr, false) + pops[i] = NewPopulatedTaskInfo(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -3661,18 +4283,18 @@ func BenchmarkACL_RunTaskProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkACL_RunTaskProtoUnmarshal(b *testing.B) { +func BenchmarkTaskInfoProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACL_RunTask(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedTaskInfo(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &ACL_RunTask{} + msg := &TaskInfo{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -3683,31 +4305,44 @@ func BenchmarkACL_RunTaskProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestACL_ShutdownFrameworkProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACL_ShutdownFramework(popr, false) +func TestTaskStatusProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskStatus(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACL_ShutdownFramework{} + msg := &TaskStatus{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestACL_ShutdownFrameworkMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACL_ShutdownFramework(popr, false) +func TestTaskStatusMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskStatus(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3715,29 +4350,29 @@ func TestACL_ShutdownFrameworkMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACL_ShutdownFramework{} + msg := &TaskStatus{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACL_ShutdownFrameworkProtoMarshal(b *testing.B) { +func BenchmarkTaskStatusProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*ACL_ShutdownFramework, 10000) + pops := make([]*TaskStatus, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedACL_ShutdownFramework(popr, false) + pops[i] = NewPopulatedTaskStatus(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -3750,18 +4385,18 @@ func BenchmarkACL_ShutdownFrameworkProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkACL_ShutdownFrameworkProtoUnmarshal(b *testing.B) { +func BenchmarkTaskStatusProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACL_ShutdownFramework(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedTaskStatus(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &ACL_ShutdownFramework{} + msg := &TaskStatus{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -3772,31 +4407,44 @@ func BenchmarkACL_ShutdownFrameworkProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestACLsProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACLs(popr, false) +func TestFiltersProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFilters(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACLs{} + msg := &Filters{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestACLsMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedACLs(popr, false) +func TestFiltersMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFilters(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3804,29 +4452,29 @@ func TestACLsMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACLs{} + msg := &Filters{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACLsProtoMarshal(b *testing.B) { +func BenchmarkFiltersProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*ACLs, 10000) + pops := make([]*Filters, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedACLs(popr, false) + pops[i] = NewPopulatedFilters(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -3839,18 +4487,18 @@ func BenchmarkACLsProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkACLsProtoUnmarshal(b *testing.B) { +func BenchmarkFiltersProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACLs(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedFilters(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &ACLs{} + msg := &Filters{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -3861,31 +4509,44 @@ func BenchmarkACLsProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestRateLimitProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedRateLimit(popr, false) +func TestEnvironmentProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &RateLimit{} + msg := &Environment{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestRateLimitMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedRateLimit(popr, false) +func TestEnvironmentMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3893,29 +4554,29 @@ func TestRateLimitMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &RateLimit{} + msg := &Environment{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkRateLimitProtoMarshal(b *testing.B) { +func BenchmarkEnvironmentProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*RateLimit, 10000) + pops := make([]*Environment, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedRateLimit(popr, false) + pops[i] = NewPopulatedEnvironment(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -3928,18 +4589,18 @@ func BenchmarkRateLimitProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkRateLimitProtoUnmarshal(b *testing.B) { +func BenchmarkEnvironmentProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedRateLimit(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedEnvironment(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &RateLimit{} + msg := &Environment{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -3950,31 +4611,44 @@ func BenchmarkRateLimitProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestRateLimitsProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedRateLimits(popr, false) +func TestEnvironment_VariableProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment_Variable(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &RateLimits{} + msg := &Environment_Variable{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestRateLimitsMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedRateLimits(popr, false) +func TestEnvironment_VariableMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment_Variable(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -3982,29 +4656,29 @@ func TestRateLimitsMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &RateLimits{} + msg := &Environment_Variable{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkRateLimitsProtoMarshal(b *testing.B) { +func BenchmarkEnvironment_VariableProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*RateLimits, 10000) + pops := make([]*Environment_Variable, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedRateLimits(popr, false) + pops[i] = NewPopulatedEnvironment_Variable(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -4017,18 +4691,18 @@ func BenchmarkRateLimitsProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkRateLimitsProtoUnmarshal(b *testing.B) { +func BenchmarkEnvironment_VariableProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedRateLimits(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedEnvironment_Variable(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &RateLimits{} + msg := &Environment_Variable{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -4039,31 +4713,44 @@ func BenchmarkRateLimitsProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestVolumeProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedVolume(popr, false) +func TestParameterProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameter(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Volume{} + msg := &Parameter{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestVolumeMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedVolume(popr, false) +func TestParameterMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameter(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -4071,29 +4758,29 @@ func TestVolumeMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Volume{} + msg := &Parameter{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkVolumeProtoMarshal(b *testing.B) { +func BenchmarkParameterProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*Volume, 10000) + pops := make([]*Parameter, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedVolume(popr, false) + pops[i] = NewPopulatedParameter(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -4106,18 +4793,18 @@ func BenchmarkVolumeProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkVolumeProtoUnmarshal(b *testing.B) { +func BenchmarkParameterProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedVolume(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedParameter(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &Volume{} + msg := &Parameter{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -4128,31 +4815,44 @@ func BenchmarkVolumeProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestContainerInfoProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedContainerInfo(popr, false) +func TestParametersProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameters(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ContainerInfo{} + msg := &Parameters{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestContainerInfoMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedContainerInfo(popr, false) +func TestParametersMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameters(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -4160,29 +4860,29 @@ func TestContainerInfoMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ContainerInfo{} + msg := &Parameters{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkContainerInfoProtoMarshal(b *testing.B) { +func BenchmarkParametersProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*ContainerInfo, 10000) + pops := make([]*Parameters, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedContainerInfo(popr, false) + pops[i] = NewPopulatedParameters(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -4195,18 +4895,18 @@ func BenchmarkContainerInfoProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkContainerInfoProtoUnmarshal(b *testing.B) { +func BenchmarkParametersProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedContainerInfo(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedParameters(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &ContainerInfo{} + msg := &Parameters{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -4217,31 +4917,44 @@ func BenchmarkContainerInfoProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestContainerInfo_DockerInfoProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo(popr, false) +func TestCredentialProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredential(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ContainerInfo_DockerInfo{} + msg := &Credential{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestContainerInfo_DockerInfoMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo(popr, false) +func TestCredentialMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredential(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -4249,29 +4962,29 @@ func TestContainerInfo_DockerInfoMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ContainerInfo_DockerInfo{} + msg := &Credential{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkContainerInfo_DockerInfoProtoMarshal(b *testing.B) { +func BenchmarkCredentialProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*ContainerInfo_DockerInfo, 10000) + pops := make([]*Credential, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedContainerInfo_DockerInfo(popr, false) + pops[i] = NewPopulatedCredential(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -4284,18 +4997,18 @@ func BenchmarkContainerInfo_DockerInfoProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkContainerInfo_DockerInfoProtoUnmarshal(b *testing.B) { +func BenchmarkCredentialProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedContainerInfo_DockerInfo(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedCredential(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &ContainerInfo_DockerInfo{} + msg := &Credential{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -4306,31 +5019,44 @@ func BenchmarkContainerInfo_DockerInfoProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestContainerInfo_DockerInfo_PortMappingProto(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) +func TestCredentialsProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredentials(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ContainerInfo_DockerInfo_PortMapping{} + msg := &Credentials{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestContainerInfo_DockerInfo_PortMappingMarshalTo(t *testing.T) { - popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) +func TestCredentialsMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredentials(popr, false) size := p.Size() data := make([]byte, size) for i := range data { @@ -4338,29 +5064,29 @@ func TestContainerInfo_DockerInfo_PortMappingMarshalTo(t *testing.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ContainerInfo_DockerInfo_PortMapping{} + msg := &Credentials{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkContainerInfo_DockerInfo_PortMappingProtoMarshal(b *testing.B) { +func BenchmarkCredentialsProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 - pops := make([]*ContainerInfo_DockerInfo_PortMapping, 10000) + pops := make([]*Credentials, 10000) for i := 0; i < 10000; i++ { - pops[i] = NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) + pops[i] = NewPopulatedCredentials(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -4373,18 +5099,18 @@ func BenchmarkContainerInfo_DockerInfo_PortMappingProtoMarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkContainerInfo_DockerInfo_PortMappingProtoUnmarshal(b *testing.B) { +func BenchmarkCredentialsProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedCredentials(popr, false)) if err != nil { panic(err) } datas[i] = data } - msg := &ContainerInfo_DockerInfo_PortMapping{} + msg := &Credentials{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) @@ -4395,6031 +5121,10314 @@ func BenchmarkContainerInfo_DockerInfo_PortMappingProtoUnmarshal(b *testing.B) { b.SetBytes(int64(total / b.N)) } -func TestFrameworkIDJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedFrameworkID(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) - } - msg := &FrameworkID{} - err = encoding_json.Unmarshal(jsondata, msg) +func TestACLProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) - } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) - } -} -func TestOfferIDJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedOfferID(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + msg := &ACL{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &OfferID{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestSlaveIDJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedSlaveID(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func TestACLMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - msg := &SlaveID{} - err = encoding_json.Unmarshal(jsondata, msg) + _, err := p.MarshalTo(data) if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, err = %v", seed, err) } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) - } -} -func TestTaskIDJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedTaskID(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + msg := &ACL{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &TaskID{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestExecutorIDJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedExecutorID(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) - } - msg := &ExecutorID{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + +func BenchmarkACLProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACL, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedACL(popr, false) } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } + b.SetBytes(int64(total / b.N)) } -func TestContainerIDJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedContainerID(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) - } - msg := &ContainerID{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + +func BenchmarkACLProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACL(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + msg := &ACL{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestFrameworkInfoJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedFrameworkInfo(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) - } - msg := &FrameworkInfo{} - err = encoding_json.Unmarshal(jsondata, msg) + +func TestACL_EntityProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_Entity(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) - } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestHealthCheckJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedHealthCheck(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + msg := &ACL_Entity{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &HealthCheck{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestHealthCheck_HTTPJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedHealthCheck_HTTP(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func TestACL_EntityMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_Entity(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - msg := &HealthCheck_HTTP{} - err = encoding_json.Unmarshal(jsondata, msg) + _, err := p.MarshalTo(data) if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) - } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestCommandInfoJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedCommandInfo(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + msg := &ACL_Entity{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &CommandInfo{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestCommandInfo_URIJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedCommandInfo_URI(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func BenchmarkACL_EntityProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACL_Entity, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedACL_Entity(popr, false) } - msg := &CommandInfo_URI{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + b.SetBytes(int64(total / b.N)) +} + +func BenchmarkACL_EntityProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACL_Entity(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + msg := &ACL_Entity{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestCommandInfo_ContainerInfoJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedCommandInfo_ContainerInfo(popr, true) - jsondata, err := encoding_json.Marshal(p) + +func TestACL_RegisterFrameworkProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_RegisterFramework(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &CommandInfo_ContainerInfo{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + msg := &ACL_RegisterFramework{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestExecutorInfoJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedExecutorInfo(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func TestACL_RegisterFrameworkMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_RegisterFramework(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - msg := &ExecutorInfo{} - err = encoding_json.Unmarshal(jsondata, msg) + _, err := p.MarshalTo(data) if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, err = %v", seed, err) } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) - } -} -func TestMasterInfoJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedMasterInfo(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + msg := &ACL_RegisterFramework{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &MasterInfo{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestSlaveInfoJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedSlaveInfo(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func BenchmarkACL_RegisterFrameworkProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACL_RegisterFramework, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedACL_RegisterFramework(popr, false) } - msg := &SlaveInfo{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + b.SetBytes(int64(total / b.N)) +} + +func BenchmarkACL_RegisterFrameworkProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACL_RegisterFramework(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + msg := &ACL_RegisterFramework{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestValueJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedValue(popr, true) - jsondata, err := encoding_json.Marshal(p) + +func TestACL_RunTaskProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_RunTask(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Value{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + msg := &ACL_RunTask{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestValue_ScalarJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedValue_Scalar(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func TestACL_RunTaskMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_RunTask(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - msg := &Value_Scalar{} - err = encoding_json.Unmarshal(jsondata, msg) + _, err := p.MarshalTo(data) if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) - } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestValue_RangeJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedValue_Range(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + msg := &ACL_RunTask{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Value_Range{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestValue_RangesJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedValue_Ranges(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func BenchmarkACL_RunTaskProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACL_RunTask, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedACL_RunTask(popr, false) } - msg := &Value_Ranges{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + b.SetBytes(int64(total / b.N)) +} + +func BenchmarkACL_RunTaskProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACL_RunTask(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + msg := &ACL_RunTask{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestValue_SetJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedValue_Set(popr, true) - jsondata, err := encoding_json.Marshal(p) + +func TestACL_ShutdownFrameworkProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_ShutdownFramework(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Value_Set{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + msg := &ACL_ShutdownFramework{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestValue_TextJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedValue_Text(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func TestACL_ShutdownFrameworkMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_ShutdownFramework(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - msg := &Value_Text{} - err = encoding_json.Unmarshal(jsondata, msg) + _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) - } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) - } -} -func TestAttributeJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedAttribute(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + msg := &ACL_ShutdownFramework{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Attribute{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestResourceJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedResource(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func BenchmarkACL_ShutdownFrameworkProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACL_ShutdownFramework, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedACL_ShutdownFramework(popr, false) } - msg := &Resource{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + b.SetBytes(int64(total / b.N)) +} + +func BenchmarkACL_ShutdownFrameworkProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACL_ShutdownFramework(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + msg := &ACL_ShutdownFramework{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestResourceStatisticsJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedResourceStatistics(popr, true) - jsondata, err := encoding_json.Marshal(p) + +func TestACLsProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACLs(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ResourceStatistics{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + msg := &ACLs{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestResourceUsageJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedResourceUsage(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func TestACLsMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACLs(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - msg := &ResourceUsage{} - err = encoding_json.Unmarshal(jsondata, msg) + _, err := p.MarshalTo(data) if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) - } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestPerfStatisticsJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedPerfStatistics(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + msg := &ACLs{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &PerfStatistics{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestRequestJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedRequest(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func BenchmarkACLsProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACLs, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedACLs(popr, false) } - msg := &Request{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + b.SetBytes(int64(total / b.N)) +} + +func BenchmarkACLsProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedACLs(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + msg := &ACLs{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestOfferJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedOffer(popr, true) - jsondata, err := encoding_json.Marshal(p) + +func TestRateLimitProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimit(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Offer{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + msg := &RateLimit{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestTaskInfoJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedTaskInfo(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func TestRateLimitMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimit(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - msg := &TaskInfo{} - err = encoding_json.Unmarshal(jsondata, msg) + _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &RateLimit{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestTaskStatusJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedTaskStatus(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) - } - msg := &TaskStatus{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + +func BenchmarkRateLimitProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*RateLimit, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedRateLimit(popr, false) } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } + b.SetBytes(int64(total / b.N)) } -func TestFiltersJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedFilters(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) - } - msg := &Filters{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + +func BenchmarkRateLimitProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedRateLimit(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + msg := &RateLimit{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestEnvironmentJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedEnvironment(popr, true) - jsondata, err := encoding_json.Marshal(p) + +func TestRateLimitsProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimits(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Environment{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + msg := &RateLimits{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestEnvironment_VariableJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedEnvironment_Variable(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func TestRateLimitsMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimits(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - msg := &Environment_Variable{} - err = encoding_json.Unmarshal(jsondata, msg) + _, err := p.MarshalTo(data) if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) - } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestParameterJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedParameter(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + msg := &RateLimits{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Parameter{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestParametersJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedParameters(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func BenchmarkRateLimitsProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*RateLimits, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedRateLimits(popr, false) } - msg := &Parameters{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + b.SetBytes(int64(total / b.N)) +} + +func BenchmarkRateLimitsProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedRateLimits(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + msg := &RateLimits{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestCredentialJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedCredential(popr, true) - jsondata, err := encoding_json.Marshal(p) + +func TestVolumeProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedVolume(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Credential{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + msg := &Volume{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestCredentialsJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedCredentials(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func TestVolumeMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedVolume(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - msg := &Credentials{} - err = encoding_json.Unmarshal(jsondata, msg) + _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Volume{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestACLJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedACL(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func BenchmarkVolumeProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Volume, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedVolume(popr, false) } - msg := &ACL{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + b.SetBytes(int64(total / b.N)) +} + +func BenchmarkVolumeProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedVolume(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + msg := &Volume{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestACL_EntityJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedACL_Entity(popr, true) - jsondata, err := encoding_json.Marshal(p) + +func TestContainerInfoProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ACL_Entity{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + msg := &ContainerInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestACL_RegisterFrameworkJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedACL_RegisterFramework(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func TestContainerInfoMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - msg := &ACL_RegisterFramework{} - err = encoding_json.Unmarshal(jsondata, msg) + _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ContainerInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestACL_RunTaskJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedACL_RunTask(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) - } - msg := &ACL_RunTask{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + +func BenchmarkContainerInfoProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ContainerInfo, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedContainerInfo(popr, false) } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } + b.SetBytes(int64(total / b.N)) } -func TestACL_ShutdownFrameworkJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedACL_ShutdownFramework(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) - } - msg := &ACL_ShutdownFramework{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + +func BenchmarkContainerInfoProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedContainerInfo(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + msg := &ContainerInfo{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestACLsJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedACLs(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) - } - msg := &ACLs{} - err = encoding_json.Unmarshal(jsondata, msg) + +func TestContainerInfo_DockerInfoProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, err = %v", seed, err) } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) - } -} -func TestRateLimitJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedRateLimit(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + msg := &ContainerInfo_DockerInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &RateLimit{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestRateLimitsJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedRateLimits(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func TestContainerInfo_DockerInfoMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - msg := &RateLimits{} - err = encoding_json.Unmarshal(jsondata, msg) + _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) - } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) - } -} -func TestVolumeJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedVolume(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + msg := &ContainerInfo_DockerInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &Volume{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestContainerInfoJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedContainerInfo(popr, true) - jsondata, err := encoding_json.Marshal(p) - if err != nil { - panic(err) + +func BenchmarkContainerInfo_DockerInfoProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ContainerInfo_DockerInfo, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedContainerInfo_DockerInfo(popr, false) } - msg := &ContainerInfo{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + b.SetBytes(int64(total / b.N)) +} + +func BenchmarkContainerInfo_DockerInfoProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedContainerInfo_DockerInfo(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + msg := &ContainerInfo_DockerInfo{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestContainerInfo_DockerInfoJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo(popr, true) - jsondata, err := encoding_json.Marshal(p) + +func TestContainerInfo_DockerInfo_PortMappingProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } - msg := &ContainerInfo_DockerInfo{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + msg := &ContainerInfo_DockerInfo_PortMapping{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestContainerInfo_DockerInfo_PortMappingJSON(t *testing1.T) { - popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, true) - jsondata, err := encoding_json.Marshal(p) + +func TestContainerInfo_DockerInfo_PortMappingMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) + } + _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &ContainerInfo_DockerInfo_PortMapping{} - err = encoding_json.Unmarshal(jsondata, msg) - if err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestFrameworkIDProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedFrameworkID(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &FrameworkID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + +func BenchmarkContainerInfo_DockerInfo_PortMappingProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ContainerInfo_DockerInfo_PortMapping, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } + b.SetBytes(int64(total / b.N)) } -func TestFrameworkIDProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedFrameworkID(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &FrameworkID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) +func BenchmarkContainerInfo_DockerInfo_PortMappingProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + msg := &ContainerInfo_DockerInfo_PortMapping{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestOfferIDProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedOfferID(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &OfferID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestLabelsProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabels(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Labels{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestOfferIDProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedOfferID(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &OfferID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestLabelsMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabels(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + _, err := p.MarshalTo(data) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + msg := &Labels{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} - -func TestSlaveIDProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedSlaveID(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &SlaveID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestSlaveIDProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedSlaveID(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &SlaveID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) +func BenchmarkLabelsProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Labels, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedLabels(popr, false) } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } + b.SetBytes(int64(total / b.N)) } -func TestTaskIDProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedTaskID(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &TaskID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) +func BenchmarkLabelsProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedLabels(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + msg := &Labels{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestTaskIDProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedTaskID(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &TaskID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestLabelProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabel(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Label{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestExecutorIDProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedExecutorID(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ExecutorID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestLabelMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabel(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + _, err := p.MarshalTo(data) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + msg := &Label{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} - -func TestExecutorIDProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedExecutorID(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ExecutorID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestContainerIDProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedContainerID(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ContainerID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) +func BenchmarkLabelProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Label, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedLabel(popr, false) } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } + b.SetBytes(int64(total / b.N)) } -func TestContainerIDProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedContainerID(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ContainerID{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) +func BenchmarkLabelProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedLabel(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + msg := &Label{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestFrameworkInfoProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedFrameworkInfo(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &FrameworkInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestPortProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPort(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Port{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestFrameworkInfoProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedFrameworkInfo(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &FrameworkInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestPortMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPort(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + _, err := p.MarshalTo(data) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + msg := &Port{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} - -func TestHealthCheckProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedHealthCheck(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &HealthCheck{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestHealthCheckProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedHealthCheck(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &HealthCheck{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) +func BenchmarkPortProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Port, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedPort(popr, false) } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } + b.SetBytes(int64(total / b.N)) } -func TestHealthCheck_HTTPProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedHealthCheck_HTTP(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &HealthCheck_HTTP{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) +func BenchmarkPortProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedPort(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + msg := &Port{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestHealthCheck_HTTPProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedHealthCheck_HTTP(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &HealthCheck_HTTP{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestPortsProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPorts(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Ports{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestCommandInfoProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedCommandInfo(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &CommandInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestPortsMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPorts(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + _, err := p.MarshalTo(data) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + msg := &Ports{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} - -func TestCommandInfoProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedCommandInfo(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &CommandInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestCommandInfo_URIProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedCommandInfo_URI(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &CommandInfo_URI{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) +func BenchmarkPortsProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Ports, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedPorts(popr, false) } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } + b.SetBytes(int64(total / b.N)) } -func TestCommandInfo_URIProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedCommandInfo_URI(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &CommandInfo_URI{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) +func BenchmarkPortsProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedPorts(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + msg := &Ports{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestCommandInfo_ContainerInfoProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedCommandInfo_ContainerInfo(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &CommandInfo_ContainerInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestDiscoveryInfoProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedDiscoveryInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &DiscoveryInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestCommandInfo_ContainerInfoProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedCommandInfo_ContainerInfo(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &CommandInfo_ContainerInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestDiscoveryInfoMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedDiscoveryInfo(popr, false) + size := p.Size() + data := make([]byte, size) + for i := range data { + data[i] = byte(popr.Intn(256)) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + _, err := p.MarshalTo(data) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + msg := &DiscoveryInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} - -func TestExecutorInfoProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedExecutorInfo(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ExecutorInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) + for i := range data { + data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestExecutorInfoProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedExecutorInfo(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ExecutorInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) +func BenchmarkDiscoveryInfoProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*DiscoveryInfo, 10000) + for i := 0; i < 10000; i++ { + pops[i] = NewPopulatedDiscoveryInfo(popr, false) } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + b.ResetTimer() + for i := 0; i < b.N; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) + if err != nil { + panic(err) + } + total += len(data) } + b.SetBytes(int64(total / b.N)) } -func TestMasterInfoProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedMasterInfo(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &MasterInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) +func BenchmarkDiscoveryInfoProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + datas := make([][]byte, 10000) + for i := 0; i < 10000; i++ { + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedDiscoveryInfo(popr, false)) + if err != nil { + panic(err) + } + datas[i] = data } - if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + msg := &DiscoveryInfo{} + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += len(datas[i%10000]) + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { + panic(err) + } } + b.SetBytes(int64(total / b.N)) } -func TestMasterInfoProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedMasterInfo(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &MasterInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestFrameworkIDJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkID(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &FrameworkID{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestSlaveInfoProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedSlaveInfo(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &SlaveInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestOfferIDJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOfferID(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &OfferID{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestSlaveInfoProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedSlaveInfo(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &SlaveInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestSlaveIDJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedSlaveID(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &SlaveID{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValueProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Value{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestTaskIDJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskID(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &TaskID{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValueProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Value{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestExecutorIDJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedExecutorID(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ExecutorID{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValue_ScalarProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue_Scalar(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Value_Scalar{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestContainerIDJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerID(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ContainerID{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValue_ScalarProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue_Scalar(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Value_Scalar{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestFrameworkInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &FrameworkInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValue_RangeProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue_Range(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Value_Range{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestFrameworkInfo_CapabilityJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkInfo_Capability(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &FrameworkInfo_Capability{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValue_RangeProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue_Range(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Value_Range{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestHealthCheckJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedHealthCheck(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &HealthCheck{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValue_RangesProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue_Ranges(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Value_Ranges{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestHealthCheck_HTTPJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedHealthCheck_HTTP(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &HealthCheck_HTTP{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValue_RangesProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue_Ranges(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Value_Ranges{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestCommandInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &CommandInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValue_SetProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue_Set(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Value_Set{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestCommandInfo_URIJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo_URI(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &CommandInfo_URI{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValue_SetProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue_Set(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Value_Set{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestCommandInfo_ContainerInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo_ContainerInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &CommandInfo_ContainerInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValue_TextProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue_Text(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Value_Text{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestExecutorInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedExecutorInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ExecutorInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestValue_TextProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedValue_Text(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Value_Text{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestMasterInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedMasterInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &MasterInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestAttributeProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedAttribute(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Attribute{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestSlaveInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedSlaveInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &SlaveInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestAttributeProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedAttribute(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Attribute{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestValueJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Value{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestResourceProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedResource(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Resource{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestValue_ScalarJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Scalar(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Value_Scalar{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestResourceProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedResource(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Resource{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestValue_RangeJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Range(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Value_Range{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestResourceStatisticsProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedResourceStatistics(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ResourceStatistics{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestValue_RangesJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Ranges(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Value_Ranges{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestResourceStatisticsProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedResourceStatistics(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ResourceStatistics{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestValue_SetJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Set(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Value_Set{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestResourceUsageProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedResourceUsage(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ResourceUsage{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestValue_TextJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Text(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Value_Text{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestResourceUsageProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedResourceUsage(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ResourceUsage{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestAttributeJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedAttribute(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Attribute{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestPerfStatisticsProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedPerfStatistics(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &PerfStatistics{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestResourceJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Resource{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestPerfStatisticsProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedPerfStatistics(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &PerfStatistics{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestResource_ReservationInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_ReservationInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Resource_ReservationInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestRequestProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedRequest(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Request{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestResource_DiskInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Resource_DiskInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestRequestProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedRequest(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Request{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestResource_DiskInfo_PersistenceJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo_Persistence(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Resource_DiskInfo_Persistence{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestOfferProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedOffer(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Offer{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestResource_RevocableInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_RevocableInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Resource_RevocableInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestOfferProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedOffer(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Offer{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestTrafficControlStatisticsJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTrafficControlStatistics(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &TrafficControlStatistics{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestTaskInfoProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedTaskInfo(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &TaskInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestResourceStatisticsJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceStatistics(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ResourceStatistics{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestTaskInfoProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedTaskInfo(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &TaskInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestResourceUsageJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ResourceUsage{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestTaskStatusProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedTaskStatus(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &TaskStatus{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestResourceUsage_ExecutorJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage_Executor(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ResourceUsage_Executor{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestTaskStatusProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedTaskStatus(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &TaskStatus{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestPerfStatisticsJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPerfStatistics(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &PerfStatistics{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestFiltersProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedFilters(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Filters{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestRequestJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRequest(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Request{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestFiltersProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedFilters(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Filters{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestOfferJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Offer{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestEnvironmentProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedEnvironment(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Environment{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestOffer_OperationJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Offer_Operation{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestEnvironmentProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedEnvironment(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Environment{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestOffer_Operation_LaunchJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Launch(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Offer_Operation_Launch{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestEnvironment_VariableProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedEnvironment_Variable(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Environment_Variable{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestOffer_Operation_ReserveJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Reserve(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Offer_Operation_Reserve{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestEnvironment_VariableProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedEnvironment_Variable(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Environment_Variable{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestOffer_Operation_UnreserveJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Unreserve(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Offer_Operation_Unreserve{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestParameterProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedParameter(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Parameter{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestOffer_Operation_CreateJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Create(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Offer_Operation_Create{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestParameterProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedParameter(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Parameter{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestOffer_Operation_DestroyJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Destroy(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Offer_Operation_Destroy{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestParametersProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedParameters(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Parameters{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestTaskInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &TaskInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestParametersProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedParameters(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Parameters{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestTaskStatusJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskStatus(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &TaskStatus{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestCredentialProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedCredential(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Credential{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestFiltersJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFilters(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Filters{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestCredentialProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedCredential(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Credential{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestEnvironmentJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Environment{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestCredentialsProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedCredentials(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Credentials{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestEnvironment_VariableJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment_Variable(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Environment_Variable{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestCredentialsProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedCredentials(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Credentials{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestParameterJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameter(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Parameter{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACLProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedACL(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ACL{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestParametersJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameters(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Parameters{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACLProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedACL(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ACL{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestCredentialJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredential(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Credential{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACL_EntityProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedACL_Entity(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ACL_Entity{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestCredentialsJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredentials(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Credentials{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACL_EntityProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedACL_Entity(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ACL_Entity{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestACLJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ACL{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACL_RegisterFrameworkProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedACL_RegisterFramework(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ACL_RegisterFramework{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestACL_EntityJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_Entity(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ACL_Entity{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACL_RegisterFrameworkProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) +func TestACL_RegisterFrameworkJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedACL_RegisterFramework(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } msg := &ACL_RegisterFramework{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACL_RunTaskProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) +func TestACL_RunTaskJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedACL_RunTask(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } msg := &ACL_RunTask{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACL_RunTaskProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedACL_RunTask(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ACL_RunTask{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestACL_ShutdownFrameworkJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_ShutdownFramework(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ACL_ShutdownFramework{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACL_ShutdownFrameworkProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedACL_ShutdownFramework(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ACL_ShutdownFramework{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestACLsJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACLs(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ACLs{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACL_ShutdownFrameworkProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedACL_ShutdownFramework(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ACL_ShutdownFramework{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestRateLimitJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimit(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &RateLimit{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACLsProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedACLs(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ACLs{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestRateLimitsJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimits(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &RateLimits{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestACLsProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedACLs(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ACLs{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestVolumeJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedVolume(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Volume{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestRateLimitProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedRateLimit(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &RateLimit{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestContainerInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ContainerInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestRateLimitProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedRateLimit(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &RateLimit{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestContainerInfo_DockerInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ContainerInfo_DockerInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestRateLimitsProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedRateLimits(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &RateLimits{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestContainerInfo_DockerInfo_PortMappingJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &ContainerInfo_DockerInfo_PortMapping{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestRateLimitsProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedRateLimits(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &RateLimits{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestLabelsJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabels(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Labels{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestVolumeProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedVolume(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &Volume{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestLabelJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabel(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Label{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestVolumeProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedVolume(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &Volume{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestPortJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPort(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Port{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestContainerInfoProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedContainerInfo(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ContainerInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestPortsJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPorts(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &Ports{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestContainerInfoProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedContainerInfo(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ContainerInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestDiscoveryInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedDiscoveryInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &DiscoveryInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } - -func TestContainerInfo_DockerInfoProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ContainerInfo_DockerInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestFrameworkIDProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkID(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &FrameworkID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestContainerInfo_DockerInfoProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ContainerInfo_DockerInfo{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestFrameworkIDProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkID(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &FrameworkID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestContainerInfo_DockerInfo_PortMappingProtoText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, true) - data := github_com_gogo_protobuf_proto1.MarshalTextString(p) - msg := &ContainerInfo_DockerInfo_PortMapping{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestOfferIDProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOfferID(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &OfferID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestContainerInfo_DockerInfo_PortMappingProtoCompactText(t *testing2.T) { - popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, true) - data := github_com_gogo_protobuf_proto1.CompactTextString(p) - msg := &ContainerInfo_DockerInfo_PortMapping{} - if err := github_com_gogo_protobuf_proto1.UnmarshalText(data, msg); err != nil { - panic(err) +func TestOfferIDProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOfferID(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &OfferID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestFrameworkIDStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedFrameworkID(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) +func TestSlaveIDProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedSlaveID(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &SlaveID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestOfferIDStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedOfferID(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestSlaveIDStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedSlaveID(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestTaskIDStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedTaskID(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestSlaveIDProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedSlaveID(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &SlaveID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestExecutorIDStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedExecutorID(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestContainerIDStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedContainerID(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestFrameworkInfoStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedFrameworkInfo(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestTaskIDProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskID(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &TaskID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestHealthCheckStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedHealthCheck(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestHealthCheck_HTTPStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedHealthCheck_HTTP(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestCommandInfoStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedCommandInfo(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestTaskIDProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskID(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &TaskID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestCommandInfo_URIStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedCommandInfo_URI(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestCommandInfo_ContainerInfoStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedCommandInfo_ContainerInfo(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestExecutorInfoStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedExecutorInfo(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestExecutorIDProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedExecutorID(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ExecutorID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestMasterInfoStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedMasterInfo(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestSlaveInfoStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedSlaveInfo(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestValueStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedValue(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestExecutorIDProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedExecutorID(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ExecutorID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestValue_ScalarStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedValue_Scalar(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestValue_RangeStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedValue_Range(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestValue_RangesStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedValue_Ranges(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) - } -} -func TestValue_SetStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedValue_Set(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestContainerIDProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerID(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ContainerID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestValue_TextStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedValue_Text(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestAttributeStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedAttribute(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestResourceStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedResource(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestContainerIDProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerID(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ContainerID{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestResourceStatisticsStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedResourceStatistics(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestResourceUsageStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedResourceUsage(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestPerfStatisticsStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedPerfStatistics(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestFrameworkInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &FrameworkInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestRequestStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedRequest(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestOfferStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedOffer(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestTaskInfoStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedTaskInfo(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestFrameworkInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &FrameworkInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestTaskStatusStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedTaskStatus(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestFiltersStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedFilters(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestEnvironmentStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedEnvironment(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestFrameworkInfo_CapabilityProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkInfo_Capability(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &FrameworkInfo_Capability{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestEnvironment_VariableStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedEnvironment_Variable(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestParameterStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedParameter(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestParametersStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedParameters(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestFrameworkInfo_CapabilityProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkInfo_Capability(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &FrameworkInfo_Capability{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestCredentialStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedCredential(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestCredentialsStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedCredentials(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestACLStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedACL(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestHealthCheckProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedHealthCheck(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &HealthCheck{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestACL_EntityStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedACL_Entity(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestACL_RegisterFrameworkStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedACL_RegisterFramework(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestACL_RunTaskStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedACL_RunTask(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestHealthCheckProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedHealthCheck(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &HealthCheck{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestACL_ShutdownFrameworkStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedACL_ShutdownFramework(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestACLsStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedACLs(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestRateLimitStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedRateLimit(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestHealthCheck_HTTPProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedHealthCheck_HTTP(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &HealthCheck_HTTP{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestRateLimitsStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedRateLimits(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestVolumeStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedVolume(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestContainerInfoStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedContainerInfo(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + +func TestHealthCheck_HTTPProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedHealthCheck_HTTP(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &HealthCheck_HTTP{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } -} -func TestContainerInfo_DockerInfoStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestContainerInfo_DockerInfo_PortMappingStringer(t *testing3.T) { - popr := math_rand3.New(math_rand3.NewSource(time3.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) - s1 := p.String() - s2 := fmt.Sprintf("%v", p) - if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestFrameworkIDSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedFrameworkID(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + +func TestCommandInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &CommandInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkFrameworkIDSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*FrameworkID, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedFrameworkID(popr, false) +func TestCommandInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &CommandInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestOfferIDSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedOfferID(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) +func TestCommandInfo_URIProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo_URI(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &CommandInfo_URI{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) - } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkOfferIDSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*OfferID, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedOfferID(popr, false) +func TestCommandInfo_URIProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo_URI(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &CommandInfo_URI{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestSlaveIDSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedSlaveID(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestCommandInfo_ContainerInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo_ContainerInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &CommandInfo_ContainerInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkSlaveIDSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*SlaveID, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedSlaveID(popr, false) +func TestCommandInfo_ContainerInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo_ContainerInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &CommandInfo_ContainerInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestTaskIDSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedTaskID(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestExecutorInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedExecutorInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ExecutorInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkTaskIDSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*TaskID, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedTaskID(popr, false) +func TestExecutorInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedExecutorInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ExecutorInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestExecutorIDSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedExecutorID(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestMasterInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedMasterInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &MasterInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkExecutorIDSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ExecutorID, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedExecutorID(popr, false) +func TestMasterInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedMasterInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &MasterInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestContainerIDSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedContainerID(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestSlaveInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedSlaveInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &SlaveInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkContainerIDSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ContainerID, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedContainerID(popr, false) +func TestSlaveInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedSlaveInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &SlaveInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestFrameworkInfoSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedFrameworkInfo(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestValueProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Value{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkFrameworkInfoSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*FrameworkInfo, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedFrameworkInfo(popr, false) +func TestValueProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Value{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestHealthCheckSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedHealthCheck(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestValue_ScalarProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Scalar(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Value_Scalar{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkHealthCheckSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*HealthCheck, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedHealthCheck(popr, false) +func TestValue_ScalarProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Scalar(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Value_Scalar{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestHealthCheck_HTTPSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedHealthCheck_HTTP(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestValue_RangeProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Range(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Value_Range{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkHealthCheck_HTTPSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*HealthCheck_HTTP, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedHealthCheck_HTTP(popr, false) +func TestValue_RangeProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Range(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Value_Range{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestCommandInfoSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedCommandInfo(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestValue_RangesProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Ranges(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Value_Ranges{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkCommandInfoSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*CommandInfo, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedCommandInfo(popr, false) +func TestValue_RangesProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Ranges(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Value_Ranges{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestCommandInfo_URISize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedCommandInfo_URI(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestValue_SetProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Set(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Value_Set{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkCommandInfo_URISize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*CommandInfo_URI, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedCommandInfo_URI(popr, false) +func TestValue_SetProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Set(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Value_Set{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestCommandInfo_ContainerInfoSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedCommandInfo_ContainerInfo(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestValue_TextProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Text(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Value_Text{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkCommandInfo_ContainerInfoSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*CommandInfo_ContainerInfo, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedCommandInfo_ContainerInfo(popr, false) +func TestValue_TextProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Text(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Value_Text{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestExecutorInfoSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedExecutorInfo(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestAttributeProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedAttribute(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Attribute{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkExecutorInfoSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ExecutorInfo, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedExecutorInfo(popr, false) +func TestAttributeProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedAttribute(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Attribute{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestMasterInfoSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedMasterInfo(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestResourceProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Resource{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkMasterInfoSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*MasterInfo, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedMasterInfo(popr, false) +func TestResourceProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Resource{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestSlaveInfoSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedSlaveInfo(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) +func TestResource_ReservationInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_ReservationInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Resource_ReservationInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) - } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkSlaveInfoSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*SlaveInfo, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedSlaveInfo(popr, false) +func TestResource_ReservationInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_ReservationInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Resource_ReservationInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestValueSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedValue(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestResource_DiskInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Resource_DiskInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkValueSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Value, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedValue(popr, false) +func TestResource_DiskInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Resource_DiskInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestValue_ScalarSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedValue_Scalar(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestResource_DiskInfo_PersistenceProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo_Persistence(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Resource_DiskInfo_Persistence{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkValue_ScalarSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Value_Scalar, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedValue_Scalar(popr, false) +func TestResource_DiskInfo_PersistenceProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo_Persistence(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Resource_DiskInfo_Persistence{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestValue_RangeSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedValue_Range(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestResource_RevocableInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_RevocableInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Resource_RevocableInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkValue_RangeSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Value_Range, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedValue_Range(popr, false) +func TestResource_RevocableInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_RevocableInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Resource_RevocableInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestValue_RangesSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedValue_Ranges(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) +func TestTrafficControlStatisticsProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTrafficControlStatistics(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &TrafficControlStatistics{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) - } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkValue_RangesSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Value_Ranges, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedValue_Ranges(popr, false) +func TestTrafficControlStatisticsProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTrafficControlStatistics(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &TrafficControlStatistics{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestValue_SetSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedValue_Set(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestResourceStatisticsProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceStatistics(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ResourceStatistics{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkValue_SetSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Value_Set, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedValue_Set(popr, false) +func TestResourceStatisticsProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceStatistics(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ResourceStatistics{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestValue_TextSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedValue_Text(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestResourceUsageProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ResourceUsage{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkValue_TextSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Value_Text, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedValue_Text(popr, false) +func TestResourceUsageProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ResourceUsage{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestAttributeSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedAttribute(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestResourceUsage_ExecutorProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage_Executor(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ResourceUsage_Executor{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkAttributeSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Attribute, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedAttribute(popr, false) +func TestResourceUsage_ExecutorProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage_Executor(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ResourceUsage_Executor{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestResourceSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedResource(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestPerfStatisticsProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPerfStatistics(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &PerfStatistics{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkResourceSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Resource, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedResource(popr, false) +func TestPerfStatisticsProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPerfStatistics(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &PerfStatistics{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestResourceStatisticsSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedResourceStatistics(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestRequestProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRequest(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Request{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkResourceStatisticsSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ResourceStatistics, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedResourceStatistics(popr, false) +func TestRequestProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRequest(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Request{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestResourceUsageSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedResourceUsage(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestOfferProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Offer{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkResourceUsageSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ResourceUsage, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedResourceUsage(popr, false) +func TestOfferProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Offer{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestPerfStatisticsSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedPerfStatistics(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestOffer_OperationProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Offer_Operation{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkPerfStatisticsSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*PerfStatistics, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedPerfStatistics(popr, false) +func TestOffer_OperationProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Offer_Operation{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestRequestSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedRequest(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) +func TestOffer_Operation_LaunchProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Launch(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Offer_Operation_Launch{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) - } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkRequestSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Request, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedRequest(popr, false) +func TestOffer_Operation_LaunchProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Launch(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Offer_Operation_Launch{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestOfferSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedOffer(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestOffer_Operation_ReserveProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Reserve(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Offer_Operation_Reserve{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkOfferSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Offer, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedOffer(popr, false) +func TestOffer_Operation_ReserveProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Reserve(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Offer_Operation_Reserve{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestTaskInfoSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedTaskInfo(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestOffer_Operation_UnreserveProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Unreserve(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Offer_Operation_Unreserve{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkTaskInfoSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*TaskInfo, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedTaskInfo(popr, false) +func TestOffer_Operation_UnreserveProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Unreserve(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Offer_Operation_Unreserve{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestTaskStatusSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedTaskStatus(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestOffer_Operation_CreateProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Create(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Offer_Operation_Create{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkTaskStatusSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*TaskStatus, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedTaskStatus(popr, false) +func TestOffer_Operation_CreateProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Create(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Offer_Operation_Create{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestFiltersSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedFilters(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) +func TestOffer_Operation_DestroyProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Destroy(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Offer_Operation_Destroy{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) - } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkFiltersSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Filters, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedFilters(popr, false) +func TestOffer_Operation_DestroyProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Destroy(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Offer_Operation_Destroy{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestEnvironmentSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedEnvironment(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestTaskInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &TaskInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkEnvironmentSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Environment, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedEnvironment(popr, false) +func TestTaskInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &TaskInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestEnvironment_VariableSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedEnvironment_Variable(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestTaskStatusProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskStatus(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &TaskStatus{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkEnvironment_VariableSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Environment_Variable, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedEnvironment_Variable(popr, false) +func TestTaskStatusProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskStatus(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &TaskStatus{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestParameterSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedParameter(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestFiltersProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFilters(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Filters{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkParameterSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Parameter, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedParameter(popr, false) +func TestFiltersProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFilters(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Filters{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - b.SetBytes(int64(total / b.N)) -} - -func TestParametersSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedParameters(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +} + +func TestEnvironmentProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Environment{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkParametersSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Parameters, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedParameters(popr, false) +func TestEnvironmentProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Environment{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestCredentialSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedCredential(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestEnvironment_VariableProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment_Variable(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Environment_Variable{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkCredentialSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Credential, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedCredential(popr, false) +func TestEnvironment_VariableProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment_Variable(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Environment_Variable{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestCredentialsSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedCredentials(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestParameterProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameter(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Parameter{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkCredentialsSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Credentials, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedCredentials(popr, false) +func TestParameterProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameter(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Parameter{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestACLSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedACL(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestParametersProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameters(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Parameters{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACLSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ACL, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedACL(popr, false) +func TestParametersProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameters(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Parameters{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestACL_EntitySize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedACL_Entity(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestCredentialProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredential(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Credential{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACL_EntitySize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ACL_Entity, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedACL_Entity(popr, false) +func TestCredentialProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredential(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Credential{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestACL_RegisterFrameworkSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedACL_RegisterFramework(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestCredentialsProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredentials(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Credentials{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACL_RegisterFrameworkSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ACL_RegisterFramework, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedACL_RegisterFramework(popr, false) +func TestCredentialsProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredentials(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Credentials{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestACL_RunTaskSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedACL_RunTask(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestACLProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ACL{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACL_RunTaskSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ACL_RunTask, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedACL_RunTask(popr, false) +func TestACLProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ACL{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestACL_ShutdownFrameworkSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedACL_ShutdownFramework(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestACL_EntityProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_Entity(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ACL_Entity{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACL_ShutdownFrameworkSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ACL_ShutdownFramework, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedACL_ShutdownFramework(popr, false) +func TestACL_EntityProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_Entity(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ACL_Entity{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestACLsSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedACLs(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestACL_RegisterFrameworkProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_RegisterFramework(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ACL_RegisterFramework{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkACLsSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ACLs, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedACLs(popr, false) +func TestACL_RegisterFrameworkProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_RegisterFramework(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ACL_RegisterFramework{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestRateLimitSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedRateLimit(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestACL_RunTaskProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_RunTask(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ACL_RunTask{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkRateLimitSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*RateLimit, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedRateLimit(popr, false) +func TestACL_RunTaskProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_RunTask(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ACL_RunTask{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestRateLimitsSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedRateLimits(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestACL_ShutdownFrameworkProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_ShutdownFramework(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ACL_ShutdownFramework{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkRateLimitsSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*RateLimits, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedRateLimits(popr, false) +func TestACL_ShutdownFrameworkProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_ShutdownFramework(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ACL_ShutdownFramework{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestVolumeSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedVolume(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestACLsProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACLs(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ACLs{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkVolumeSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*Volume, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedVolume(popr, false) +func TestACLsProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACLs(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ACLs{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestContainerInfoSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedContainerInfo(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestRateLimitProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimit(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &RateLimit{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkContainerInfoSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ContainerInfo, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedContainerInfo(popr, false) +func TestRateLimitProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimit(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &RateLimit{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestContainerInfo_DockerInfoSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestRateLimitsProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimits(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &RateLimits{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkContainerInfo_DockerInfoSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ContainerInfo_DockerInfo, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedContainerInfo_DockerInfo(popr, false) +func TestRateLimitsProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimits(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &RateLimits{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestContainerInfo_DockerInfo_PortMappingSize(t *testing4.T) { - popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, true) - size2 := github_com_gogo_protobuf_proto2.Size(p) - data, err := github_com_gogo_protobuf_proto2.Marshal(p) - if err != nil { - panic(err) - } - size := p.Size() - if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) +func TestVolumeProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedVolume(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Volume{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } - size3 := github_com_gogo_protobuf_proto2.Size(p) - if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkContainerInfo_DockerInfo_PortMappingSize(b *testing4.B) { - popr := math_rand4.New(math_rand4.NewSource(616)) - total := 0 - pops := make([]*ContainerInfo_DockerInfo_PortMapping, 1000) - for i := 0; i < 1000; i++ { - pops[i] = NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) +func TestVolumeProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedVolume(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Volume{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - total += pops[i%1000].Size() + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - b.SetBytes(int64(total / b.N)) } -func TestFrameworkIDGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedFrameworkID(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) +func TestContainerInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ContainerInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestOfferIDGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedOfferID(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestContainerInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ContainerInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestSlaveIDGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedSlaveID(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestContainerInfo_DockerInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ContainerInfo_DockerInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestTaskIDGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedTaskID(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestContainerInfo_DockerInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ContainerInfo_DockerInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestExecutorIDGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedExecutorID(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestContainerInfo_DockerInfo_PortMappingProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &ContainerInfo_DockerInfo_PortMapping{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestContainerIDGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedContainerID(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestContainerInfo_DockerInfo_PortMappingProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &ContainerInfo_DockerInfo_PortMapping{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestFrameworkInfoGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedFrameworkInfo(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestLabelsProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabels(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Labels{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestHealthCheckGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedHealthCheck(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestLabelsProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabels(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Labels{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestHealthCheck_HTTPGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedHealthCheck_HTTP(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestLabelProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabel(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Label{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestCommandInfoGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedCommandInfo(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestLabelProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabel(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Label{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestCommandInfo_URIGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedCommandInfo_URI(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestPortProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPort(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Port{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestCommandInfo_ContainerInfoGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedCommandInfo_ContainerInfo(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestPortProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPort(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Port{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestExecutorInfoGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedExecutorInfo(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestPortsProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPorts(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &Ports{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestMasterInfoGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedMasterInfo(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestPortsProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPorts(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &Ports{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestSlaveInfoGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedSlaveInfo(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestDiscoveryInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedDiscoveryInfo(popr, true) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &DiscoveryInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestValueGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedValue(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + +func TestDiscoveryInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedDiscoveryInfo(popr, true) + data := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &DiscoveryInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } -} -func TestValue_ScalarGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedValue_Scalar(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } - _, err := go_parser.ParseExpr(s1) +} + +func TestFrameworkIDVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFrameworkID(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestValue_RangeGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedValue_Range(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &FrameworkID{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestValue_RangesGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedValue_Ranges(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } - _, err := go_parser.ParseExpr(s1) +} +func TestOfferIDVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOfferID(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestValue_SetGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedValue_Set(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &OfferID{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestValue_TextGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedValue_Text(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } - _, err := go_parser.ParseExpr(s1) +} +func TestSlaveIDVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedSlaveID(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestAttributeGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedAttribute(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &SlaveID{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestResourceGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedResource(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } - _, err := go_parser.ParseExpr(s1) +} +func TestTaskIDVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTaskID(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestResourceStatisticsGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedResourceStatistics(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &TaskID{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestResourceUsageGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedResourceUsage(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } - _, err := go_parser.ParseExpr(s1) +} +func TestExecutorIDVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedExecutorID(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestPerfStatisticsGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedPerfStatistics(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &ExecutorID{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestRequestGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedRequest(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } - _, err := go_parser.ParseExpr(s1) +} +func TestContainerIDVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedContainerID(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestOfferGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedOffer(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &ContainerID{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestTaskInfoGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedTaskInfo(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } - _, err := go_parser.ParseExpr(s1) +} +func TestFrameworkInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFrameworkInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestTaskStatusGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedTaskStatus(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &FrameworkInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestFiltersGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedFilters(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } - _, err := go_parser.ParseExpr(s1) +} +func TestFrameworkInfo_CapabilityVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFrameworkInfo_Capability(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestEnvironmentGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedEnvironment(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &FrameworkInfo_Capability{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestEnvironment_VariableGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedEnvironment_Variable(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } - _, err := go_parser.ParseExpr(s1) +} +func TestHealthCheckVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedHealthCheck(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestParameterGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedParameter(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + msg := &HealthCheck{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) } - _, err := go_parser.ParseExpr(s1) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestHealthCheck_HTTPVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedHealthCheck_HTTP(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestParametersGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedParameters(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &HealthCheck_HTTP{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestCredentialGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedCredential(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestCredentialsGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedCredentials(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) +func TestCommandInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCommandInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestACLGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedACL(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &CommandInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestACL_EntityGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedACL_Entity(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestACL_RegisterFrameworkGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedACL_RegisterFramework(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) +func TestCommandInfo_URIVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCommandInfo_URI(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestACL_RunTaskGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedACL_RunTask(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &CommandInfo_URI{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestACL_ShutdownFrameworkGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedACL_ShutdownFramework(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestACLsGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedACLs(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) +func TestCommandInfo_ContainerInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCommandInfo_ContainerInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestRateLimitGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedRateLimit(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &CommandInfo_ContainerInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestRateLimitsGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedRateLimits(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { - panic(err) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestVolumeGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedVolume(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) +func TestExecutorInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedExecutorInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestContainerInfoGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedContainerInfo(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &ExecutorInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } -} -func TestContainerInfo_DockerInfoGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } - _, err := go_parser.ParseExpr(s1) +} +func TestMasterInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedMasterInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } -} -func TestContainerInfo_DockerInfo_PortMappingGoString(t *testing5.T) { - popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) - s1 := p.GoString() - s2 := fmt1.Sprintf("%#v", p) - if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser.ParseExpr(s1) - if err != nil { + msg := &MasterInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } } -func TestFrameworkIDVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedFrameworkID(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestSlaveInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedSlaveInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &FrameworkID{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &SlaveInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestOfferIDVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedOfferID(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestValueVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &OfferID{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Value{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestSlaveIDVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedSlaveID(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestValue_ScalarVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Scalar(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &SlaveID{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Value_Scalar{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestTaskIDVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedTaskID(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestValue_RangeVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Range(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &TaskID{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Value_Range{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestExecutorIDVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedExecutorID(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestValue_RangesVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Ranges(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &ExecutorID{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Value_Ranges{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestContainerIDVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedContainerID(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestValue_SetVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Set(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &ContainerID{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Value_Set{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestFrameworkInfoVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedFrameworkInfo(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestValue_TextVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Text(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &FrameworkInfo{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Value_Text{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestHealthCheckVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedHealthCheck(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestAttributeVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedAttribute(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &HealthCheck{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Attribute{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestHealthCheck_HTTPVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedHealthCheck_HTTP(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestResourceVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &HealthCheck_HTTP{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Resource{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestCommandInfoVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedCommandInfo(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestResource_ReservationInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_ReservationInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &CommandInfo{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Resource_ReservationInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestCommandInfo_URIVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedCommandInfo_URI(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestResource_DiskInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_DiskInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &CommandInfo_URI{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Resource_DiskInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestCommandInfo_ContainerInfoVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedCommandInfo_ContainerInfo(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestResource_DiskInfo_PersistenceVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_DiskInfo_Persistence(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &CommandInfo_ContainerInfo{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Resource_DiskInfo_Persistence{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestExecutorInfoVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedExecutorInfo(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestResource_RevocableInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_RevocableInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &ExecutorInfo{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Resource_RevocableInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestMasterInfoVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedMasterInfo(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestTrafficControlStatisticsVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTrafficControlStatistics(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &MasterInfo{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &TrafficControlStatistics{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestSlaveInfoVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedSlaveInfo(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestResourceStatisticsVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResourceStatistics(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &SlaveInfo{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &ResourceStatistics{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestValueVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedValue(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestResourceUsageVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResourceUsage(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &Value{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &ResourceUsage{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestValue_ScalarVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedValue_Scalar(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { +func TestResourceUsage_ExecutorVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResourceUsage_Executor(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { panic(err) } - msg := &Value_Scalar{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &ResourceUsage_Executor{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestValue_RangeVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedValue_Range(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestPerfStatisticsVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPerfStatistics(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &Value_Range{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &PerfStatistics{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestValue_RangesVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedValue_Ranges(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestRequestVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedRequest(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &Value_Ranges{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Request{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestValue_SetVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedValue_Set(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestOfferVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &Value_Set{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Offer{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestValue_TextVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedValue_Text(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestOffer_OperationVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &Value_Text{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Offer_Operation{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestAttributeVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedAttribute(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestOffer_Operation_LaunchVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Launch(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &Attribute{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Offer_Operation_Launch{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestResourceVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedResource(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestOffer_Operation_ReserveVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Reserve(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &Resource{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Offer_Operation_Reserve{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestResourceStatisticsVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedResourceStatistics(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestOffer_Operation_UnreserveVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Unreserve(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &ResourceStatistics{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Offer_Operation_Unreserve{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestResourceUsageVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedResourceUsage(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestOffer_Operation_CreateVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Create(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &ResourceUsage{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Offer_Operation_Create{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestPerfStatisticsVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedPerfStatistics(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestOffer_Operation_DestroyVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Destroy(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &PerfStatistics{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Offer_Operation_Destroy{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestRequestVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedRequest(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestTaskInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTaskInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &Request{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &TaskInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestOfferVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedOffer(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestTaskStatusVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTaskStatus(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &Offer{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &TaskStatus{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestTaskInfoVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedTaskInfo(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestFiltersVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFilters(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &TaskInfo{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Filters{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestTaskStatusVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedTaskStatus(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestEnvironmentVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedEnvironment(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &TaskStatus{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Environment{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestFiltersVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedFilters(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestEnvironment_VariableVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedEnvironment_Variable(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &Filters{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Environment_Variable{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestEnvironmentVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedEnvironment(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) +func TestParameterVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedParameter(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } - msg := &Environment{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { + msg := &Parameter{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestParametersVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedParameters(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Parameters{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestCredentialVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCredential(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Credential{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestCredentialsVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCredentials(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Credentials{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestACLVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACL(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &ACL{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestACL_EntityVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACL_Entity(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &ACL_Entity{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestACL_RegisterFrameworkVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACL_RegisterFramework(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &ACL_RegisterFramework{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestACL_RunTaskVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACL_RunTask(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &ACL_RunTask{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestACL_ShutdownFrameworkVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACL_ShutdownFramework(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &ACL_ShutdownFramework{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestACLsVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACLs(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &ACLs{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } } -func TestEnvironment_VariableVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestRateLimitVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedRateLimit(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &RateLimit{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestRateLimitsVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedRateLimits(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &RateLimits{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestVolumeVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedVolume(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Volume{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestContainerInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedContainerInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &ContainerInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestContainerInfo_DockerInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedContainerInfo_DockerInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &ContainerInfo_DockerInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestContainerInfo_DockerInfo_PortMappingVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &ContainerInfo_DockerInfo_PortMapping{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestLabelsVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedLabels(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Labels{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestLabelVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedLabel(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Label{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestPortVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPort(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Port{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestPortsVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPorts(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Ports{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestDiscoveryInfoVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedDiscoveryInfo(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &DiscoveryInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestFrameworkIDGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFrameworkID(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestOfferIDGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOfferID(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestSlaveIDGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedSlaveID(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestTaskIDGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTaskID(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestExecutorIDGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedExecutorID(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestContainerIDGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedContainerID(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestFrameworkInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFrameworkInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestFrameworkInfo_CapabilityGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFrameworkInfo_Capability(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestHealthCheckGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedHealthCheck(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestHealthCheck_HTTPGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedHealthCheck_HTTP(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestCommandInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCommandInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestCommandInfo_URIGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCommandInfo_URI(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestCommandInfo_ContainerInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCommandInfo_ContainerInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestExecutorInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedExecutorInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestMasterInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedMasterInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestSlaveInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedSlaveInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestValueGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestValue_ScalarGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Scalar(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestValue_RangeGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Range(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestValue_RangesGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Ranges(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestValue_SetGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Set(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestValue_TextGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Text(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestAttributeGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedAttribute(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestResourceGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestResource_ReservationInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_ReservationInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestResource_DiskInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_DiskInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestResource_DiskInfo_PersistenceGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_DiskInfo_Persistence(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestResource_RevocableInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_RevocableInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestTrafficControlStatisticsGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTrafficControlStatistics(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestResourceStatisticsGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResourceStatistics(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestResourceUsageGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResourceUsage(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestResourceUsage_ExecutorGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResourceUsage_Executor(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestPerfStatisticsGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPerfStatistics(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestRequestGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedRequest(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestOfferGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestOffer_OperationGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestOffer_Operation_LaunchGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Launch(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestOffer_Operation_ReserveGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Reserve(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestOffer_Operation_UnreserveGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Unreserve(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestOffer_Operation_CreateGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Create(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestOffer_Operation_DestroyGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Destroy(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestTaskInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTaskInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestTaskStatusGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTaskStatus(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestFiltersGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFilters(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestEnvironmentGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedEnvironment(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestEnvironment_VariableGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedEnvironment_Variable(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestParameterGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedParameter(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestParametersGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedParameters(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestCredentialGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCredential(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestCredentialsGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCredentials(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestACLGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACL(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestACL_EntityGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACL_Entity(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestACL_RegisterFrameworkGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACL_RegisterFramework(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestACL_RunTaskGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACL_RunTask(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestACL_ShutdownFrameworkGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACL_ShutdownFramework(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestACLsGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedACLs(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestRateLimitGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedRateLimit(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestRateLimitsGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedRateLimits(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestVolumeGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedVolume(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestContainerInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedContainerInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestContainerInfo_DockerInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedContainerInfo_DockerInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestContainerInfo_DockerInfo_PortMappingGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestLabelsGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedLabels(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestLabelGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedLabel(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestPortGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPort(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestPortsGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPorts(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestDiscoveryInfoGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedDiscoveryInfo(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) + if s1 != s2 { + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) + } +} +func TestFrameworkIDSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkID(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkFrameworkIDSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*FrameworkID, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedFrameworkID(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestOfferIDSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOfferID(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkOfferIDSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*OfferID, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedOfferID(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestSlaveIDSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedSlaveID(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkSlaveIDSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*SlaveID, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedSlaveID(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestTaskIDSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskID(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkTaskIDSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*TaskID, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedTaskID(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestExecutorIDSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedExecutorID(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkExecutorIDSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ExecutorID, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedExecutorID(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestContainerIDSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerID(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkContainerIDSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ContainerID, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedContainerID(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestFrameworkInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkFrameworkInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*FrameworkInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedFrameworkInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestFrameworkInfo_CapabilitySize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFrameworkInfo_Capability(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkFrameworkInfo_CapabilitySize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*FrameworkInfo_Capability, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedFrameworkInfo_Capability(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestHealthCheckSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedHealthCheck(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkHealthCheckSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*HealthCheck, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedHealthCheck(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestHealthCheck_HTTPSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedHealthCheck_HTTP(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkHealthCheck_HTTPSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*HealthCheck_HTTP, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedHealthCheck_HTTP(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestCommandInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkCommandInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*CommandInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedCommandInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestCommandInfo_URISize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo_URI(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkCommandInfo_URISize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*CommandInfo_URI, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedCommandInfo_URI(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestCommandInfo_ContainerInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCommandInfo_ContainerInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkCommandInfo_ContainerInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*CommandInfo_ContainerInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedCommandInfo_ContainerInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestExecutorInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedExecutorInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkExecutorInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ExecutorInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedExecutorInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestMasterInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedMasterInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkMasterInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*MasterInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedMasterInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestSlaveInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedSlaveInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkSlaveInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*SlaveInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedSlaveInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestValueSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkValueSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Value, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedValue(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestValue_ScalarSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Scalar(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkValue_ScalarSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Value_Scalar, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedValue_Scalar(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestValue_RangeSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Range(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkValue_RangeSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Value_Range, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedValue_Range(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestValue_RangesSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Ranges(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkValue_RangesSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Value_Ranges, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedValue_Ranges(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestValue_SetSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Set(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkValue_SetSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Value_Set, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedValue_Set(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestValue_TextSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedValue_Text(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkValue_TextSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Value_Text, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedValue_Text(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestAttributeSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedAttribute(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkAttributeSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Attribute, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedAttribute(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestResourceSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkResourceSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Resource, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedResource(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestResource_ReservationInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_ReservationInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkResource_ReservationInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Resource_ReservationInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedResource_ReservationInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestResource_DiskInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkResource_DiskInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Resource_DiskInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedResource_DiskInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestResource_DiskInfo_PersistenceSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_DiskInfo_Persistence(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkResource_DiskInfo_PersistenceSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Resource_DiskInfo_Persistence, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedResource_DiskInfo_Persistence(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestResource_RevocableInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResource_RevocableInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkResource_RevocableInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Resource_RevocableInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedResource_RevocableInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestTrafficControlStatisticsSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTrafficControlStatistics(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkTrafficControlStatisticsSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*TrafficControlStatistics, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedTrafficControlStatistics(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestResourceStatisticsSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceStatistics(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkResourceStatisticsSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ResourceStatistics, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedResourceStatistics(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestResourceUsageSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkResourceUsageSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ResourceUsage, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedResourceUsage(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestResourceUsage_ExecutorSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedResourceUsage_Executor(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkResourceUsage_ExecutorSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ResourceUsage_Executor, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedResourceUsage_Executor(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestPerfStatisticsSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPerfStatistics(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkPerfStatisticsSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*PerfStatistics, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedPerfStatistics(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestRequestSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRequest(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkRequestSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Request, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedRequest(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestOfferSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkOfferSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Offer, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedOffer(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestOffer_OperationSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkOffer_OperationSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Offer_Operation, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedOffer_Operation(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestOffer_Operation_LaunchSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Launch(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkOffer_Operation_LaunchSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Offer_Operation_Launch, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedOffer_Operation_Launch(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestOffer_Operation_ReserveSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Reserve(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkOffer_Operation_ReserveSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Offer_Operation_Reserve, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedOffer_Operation_Reserve(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestOffer_Operation_UnreserveSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Unreserve(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkOffer_Operation_UnreserveSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Offer_Operation_Unreserve, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedOffer_Operation_Unreserve(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestOffer_Operation_CreateSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Create(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkOffer_Operation_CreateSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Offer_Operation_Create, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedOffer_Operation_Create(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestOffer_Operation_DestroySize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedOffer_Operation_Destroy(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkOffer_Operation_DestroySize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Offer_Operation_Destroy, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedOffer_Operation_Destroy(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestTaskInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkTaskInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*TaskInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedTaskInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestTaskStatusSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedTaskStatus(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkTaskStatusSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*TaskStatus, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedTaskStatus(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestFiltersSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedFilters(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkFiltersSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Filters, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedFilters(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestEnvironmentSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkEnvironmentSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Environment, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedEnvironment(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestEnvironment_VariableSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedEnvironment_Variable(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkEnvironment_VariableSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Environment_Variable, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedEnvironment_Variable(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestParameterSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameter(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkParameterSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Parameter, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedParameter(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestParametersSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedParameters(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkParametersSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Parameters, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedParameters(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestCredentialSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredential(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkCredentialSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Credential, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedCredential(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestCredentialsSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedCredentials(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkCredentialsSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Credentials, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedCredentials(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestACLSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkACLSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACL, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedACL(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestACL_EntitySize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_Entity(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkACL_EntitySize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACL_Entity, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedACL_Entity(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestACL_RegisterFrameworkSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_RegisterFramework(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkACL_RegisterFrameworkSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACL_RegisterFramework, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedACL_RegisterFramework(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestACL_RunTaskSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_RunTask(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkACL_RunTaskSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACL_RunTask, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedACL_RunTask(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestACL_ShutdownFrameworkSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACL_ShutdownFramework(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkACL_ShutdownFrameworkSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACL_ShutdownFramework, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedACL_ShutdownFramework(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestACLsSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedACLs(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkACLsSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ACLs, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedACLs(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestRateLimitSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimit(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkRateLimitSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*RateLimit, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedRateLimit(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestRateLimitsSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedRateLimits(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkRateLimitsSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*RateLimits, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedRateLimits(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestVolumeSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedVolume(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkVolumeSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Volume, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedVolume(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestContainerInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkContainerInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ContainerInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedContainerInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestContainerInfo_DockerInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkContainerInfo_DockerInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ContainerInfo_DockerInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedContainerInfo_DockerInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestContainerInfo_DockerInfo_PortMappingSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkContainerInfo_DockerInfo_PortMappingSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*ContainerInfo_DockerInfo_PortMapping, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestLabelsSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabels(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkLabelsSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Labels, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedLabels(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestLabelSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLabel(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkLabelSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Label, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedLabel(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestPortSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPort(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkPortSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Port, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedPort(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestPortsSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedPorts(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkPortsSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*Ports, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedPorts(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestDiscoveryInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedDiscoveryInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(data) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + +func BenchmarkDiscoveryInfoSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) + total := 0 + pops := make([]*DiscoveryInfo, 1000) + for i := 0; i < 1000; i++ { + pops[i] = NewPopulatedDiscoveryInfo(popr, false) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + total += pops[i%1000].Size() + } + b.SetBytes(int64(total / b.N)) +} + +func TestFrameworkIDStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFrameworkID(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestOfferIDStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOfferID(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestSlaveIDStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedSlaveID(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestTaskIDStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTaskID(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestExecutorIDStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedExecutorID(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestContainerIDStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedContainerID(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestFrameworkInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFrameworkInfo(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestFrameworkInfo_CapabilityStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFrameworkInfo_Capability(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestHealthCheckStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedHealthCheck(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestHealthCheck_HTTPStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedHealthCheck_HTTP(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestCommandInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCommandInfo(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestCommandInfo_URIStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCommandInfo_URI(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestCommandInfo_ContainerInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedCommandInfo_ContainerInfo(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestExecutorInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedExecutorInfo(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestMasterInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedMasterInfo(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestSlaveInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedSlaveInfo(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestValueStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestValue_ScalarStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Scalar(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestValue_RangeStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Range(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestValue_RangesStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Ranges(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestValue_SetStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Set(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestValue_TextStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedValue_Text(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestAttributeStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedAttribute(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestResourceStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestResource_ReservationInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_ReservationInfo(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestResource_DiskInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_DiskInfo(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestResource_DiskInfo_PersistenceStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_DiskInfo_Persistence(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestResource_RevocableInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResource_RevocableInfo(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestTrafficControlStatisticsStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTrafficControlStatistics(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestResourceStatisticsStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResourceStatistics(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestResourceUsageStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResourceUsage(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestResourceUsage_ExecutorStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedResourceUsage_Executor(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestPerfStatisticsStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPerfStatistics(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestRequestStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedRequest(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestOfferStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestOffer_OperationStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestOffer_Operation_LaunchStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Launch(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestOffer_Operation_ReserveStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Reserve(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestOffer_Operation_UnreserveStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Unreserve(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestOffer_Operation_CreateStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Create(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestOffer_Operation_DestroyStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOffer_Operation_Destroy(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestTaskInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTaskInfo(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestTaskStatusStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedTaskStatus(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestFiltersStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedFilters(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestEnvironmentStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedEnvironment(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestEnvironment_VariableStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedEnvironment_Variable(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &Environment_Variable{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestParameterVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestParameterStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedParameter(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &Parameter{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestParametersVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestParametersStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedParameters(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &Parameters{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestCredentialVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestCredentialStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedCredential(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &Credential{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestCredentialsVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestCredentialsStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedCredentials(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &Credentials{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestACLVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestACLStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedACL(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &ACL{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestACL_EntityVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestACL_EntityStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedACL_Entity(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &ACL_Entity{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestACL_RegisterFrameworkVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestACL_RegisterFrameworkStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedACL_RegisterFramework(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &ACL_RegisterFramework{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestACL_RunTaskVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestACL_RunTaskStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedACL_RunTask(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &ACL_RunTask{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestACL_ShutdownFrameworkVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestACL_ShutdownFrameworkStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedACL_ShutdownFramework(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &ACL_ShutdownFramework{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestACLsVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestACLsStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedACLs(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &ACLs{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestRateLimitVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestRateLimitStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedRateLimit(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &RateLimit{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestRateLimitsVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestRateLimitsStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedRateLimits(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &RateLimits{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestVolumeVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestVolumeStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedVolume(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &Volume{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestContainerInfoVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestContainerInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedContainerInfo(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) - } - msg := &ContainerInfo{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestContainerInfo_DockerInfoVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) +func TestContainerInfo_DockerInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedContainerInfo_DockerInfo(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } - msg := &ContainerInfo_DockerInfo{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) +} +func TestContainerInfo_DockerInfo_PortMappingStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) +} +func TestLabelsStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedLabels(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } -func TestContainerInfo_DockerInfo_PortMappingVerboseEqual(t *testing6.T) { - popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano())) - p := NewPopulatedContainerInfo_DockerInfo_PortMapping(popr, false) - data, err := github_com_gogo_protobuf_proto3.Marshal(p) - if err != nil { - panic(err) +func TestLabelStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedLabel(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } - msg := &ContainerInfo_DockerInfo_PortMapping{} - if err := github_com_gogo_protobuf_proto3.Unmarshal(data, msg); err != nil { - panic(err) +} +func TestPortStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPort(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) +} +func TestPortsStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedPorts(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) + } +} +func TestDiscoveryInfoStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedDiscoveryInfo(popr, false) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) + if s1 != s2 { + t.Fatalf("String want %v got %v", s1, s2) } } diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/messages.pb.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/messages.pb.go index 72d1ef70f2a0..7b62a9524f11 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/messages.pb.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/messages.pb.go @@ -5,12 +5,14 @@ package mesosproto import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" import math "math" -// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb" +// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf type StatusUpdateRecord_Type int32 @@ -71,7 +73,13 @@ type Task struct { // NOTE: Either both the fields must be set or both must be unset. StatusUpdateState *TaskState `protobuf:"varint,9,opt,name=status_update_state,enum=mesosproto.TaskState" json:"status_update_state,omitempty"` StatusUpdateUuid []byte `protobuf:"bytes,10,opt,name=status_update_uuid" json:"status_update_uuid,omitempty"` - XXX_unrecognized []byte `json:"-"` + Labels *Labels `protobuf:"bytes,11,opt,name=labels" json:"labels,omitempty"` + // Service discovery information for the task. It is not interpreted + // or acted upon by Mesos. It is up to a service discovery system + // to use this information as needed and to handle tasks without + // service discovery information. + Discovery *DiscoveryInfo `protobuf:"bytes,12,opt,name=discovery" json:"discovery,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *Task) Reset() { *m = Task{} } @@ -148,33 +156,18 @@ func (m *Task) GetStatusUpdateUuid() []byte { return nil } -// Describes a role, which are used to group frameworks for allocation -// decisions, depending on the allocation policy being used. -// The weight field can be used to indicate forms of priority. -type RoleInfo struct { - Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` - Weight *float64 `protobuf:"fixed64,2,opt,name=weight,def=1" json:"weight,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *RoleInfo) Reset() { *m = RoleInfo{} } -func (m *RoleInfo) String() string { return proto.CompactTextString(m) } -func (*RoleInfo) ProtoMessage() {} - -const Default_RoleInfo_Weight float64 = 1 - -func (m *RoleInfo) GetName() string { - if m != nil && m.Name != nil { - return *m.Name +func (m *Task) GetLabels() *Labels { + if m != nil { + return m.Labels } - return "" + return nil } -func (m *RoleInfo) GetWeight() float64 { - if m != nil && m.Weight != nil { - return *m.Weight +func (m *Task) GetDiscovery() *DiscoveryInfo { + if m != nil { + return m.Discovery } - return Default_RoleInfo_Weight + return nil } // TODO(vinod): Create a new UUID message type. @@ -184,7 +177,10 @@ type StatusUpdate struct { SlaveId *SlaveID `protobuf:"bytes,3,opt,name=slave_id" json:"slave_id,omitempty"` Status *TaskStatus `protobuf:"bytes,4,req,name=status" json:"status,omitempty"` Timestamp *float64 `protobuf:"fixed64,5,req,name=timestamp" json:"timestamp,omitempty"` - Uuid []byte `protobuf:"bytes,6,req,name=uuid" json:"uuid,omitempty"` + // This is being deprecated in favor of TaskStatus.uuid. In 0.23.0, + // we set the TaskStatus 'uuid' in the executor driver for all + // retryable status updates. + Uuid []byte `protobuf:"bytes,6,opt,name=uuid" json:"uuid,omitempty"` // This corresponds to the latest state of the task according to the // slave. Note that this state might be different than the state in // 'status' because status update manager queues updates. In other @@ -635,7 +631,8 @@ func (m *ReviveOffersMessage) GetFrameworkId() *FrameworkID { } type RunTaskMessage struct { - FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"` + // TODO(karya): Remove framework_id after MESOS-2559 has shipped. + FrameworkId *FrameworkID `protobuf:"bytes,1,opt,name=framework_id" json:"framework_id,omitempty"` Framework *FrameworkInfo `protobuf:"bytes,2,req,name=framework" json:"framework,omitempty"` Pid *string `protobuf:"bytes,3,req,name=pid" json:"pid,omitempty"` Task *TaskInfo `protobuf:"bytes,4,req,name=task" json:"task,omitempty"` @@ -830,6 +827,10 @@ func (m *FrameworkErrorMessage) GetMessage() string { type RegisterSlaveMessage struct { Slave *SlaveInfo `protobuf:"bytes,1,req,name=slave" json:"slave,omitempty"` + // Resources that are checkpointed by the slave (e.g., persistent + // volume or dynamic reservation). Frameworks need to release + // checkpointed resources explicitly. + CheckpointedResources []*Resource `protobuf:"bytes,3,rep,name=checkpointed_resources" json:"checkpointed_resources,omitempty"` // NOTE: This is a hack for the master to detect the slave's // version. If unset the slave is < 0.21.0. // TODO(bmahler): Do proper versioning: MESOS-986. @@ -848,6 +849,13 @@ func (m *RegisterSlaveMessage) GetSlave() *SlaveInfo { return nil } +func (m *RegisterSlaveMessage) GetCheckpointedResources() []*Resource { + if m != nil { + return m.CheckpointedResources + } + return nil +} + func (m *RegisterSlaveMessage) GetVersion() string { if m != nil && m.Version != nil { return *m.Version @@ -856,14 +864,14 @@ func (m *RegisterSlaveMessage) GetVersion() string { } type ReregisterSlaveMessage struct { - // TODO(bmahler): slave_id is deprecated. - // 0.21.0: Now an optional field. Always written, never read. - // 0.22.0: Remove this field. - SlaveId *SlaveID `protobuf:"bytes,1,opt,name=slave_id" json:"slave_id,omitempty"` - Slave *SlaveInfo `protobuf:"bytes,2,req,name=slave" json:"slave,omitempty"` - ExecutorInfos []*ExecutorInfo `protobuf:"bytes,4,rep,name=executor_infos" json:"executor_infos,omitempty"` - Tasks []*Task `protobuf:"bytes,3,rep,name=tasks" json:"tasks,omitempty"` - CompletedFrameworks []*Archive_Framework `protobuf:"bytes,5,rep,name=completed_frameworks" json:"completed_frameworks,omitempty"` + Slave *SlaveInfo `protobuf:"bytes,2,req,name=slave" json:"slave,omitempty"` + // Resources that are checkpointed by the slave (e.g., persistent + // volume or dynamic reservation). Frameworks need to release + // checkpointed resources explicitly. + CheckpointedResources []*Resource `protobuf:"bytes,7,rep,name=checkpointed_resources" json:"checkpointed_resources,omitempty"` + ExecutorInfos []*ExecutorInfo `protobuf:"bytes,4,rep,name=executor_infos" json:"executor_infos,omitempty"` + Tasks []*Task `protobuf:"bytes,3,rep,name=tasks" json:"tasks,omitempty"` + CompletedFrameworks []*Archive_Framework `protobuf:"bytes,5,rep,name=completed_frameworks" json:"completed_frameworks,omitempty"` // NOTE: This is a hack for the master to detect the slave's // version. If unset the slave is < 0.21.0. // TODO(bmahler): Do proper versioning: MESOS-986. @@ -875,16 +883,16 @@ func (m *ReregisterSlaveMessage) Reset() { *m = ReregisterSlaveMessage{} func (m *ReregisterSlaveMessage) String() string { return proto.CompactTextString(m) } func (*ReregisterSlaveMessage) ProtoMessage() {} -func (m *ReregisterSlaveMessage) GetSlaveId() *SlaveID { +func (m *ReregisterSlaveMessage) GetSlave() *SlaveInfo { if m != nil { - return m.SlaveId + return m.Slave } return nil } -func (m *ReregisterSlaveMessage) GetSlave() *SlaveInfo { +func (m *ReregisterSlaveMessage) GetCheckpointedResources() []*Resource { if m != nil { - return m.Slave + return m.CheckpointedResources } return nil } @@ -918,8 +926,9 @@ func (m *ReregisterSlaveMessage) GetVersion() string { } type SlaveRegisteredMessage struct { - SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"` - XXX_unrecognized []byte `json:"-"` + SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"` + Connection *MasterSlaveConnection `protobuf:"bytes,2,opt,name=connection" json:"connection,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *SlaveRegisteredMessage) Reset() { *m = SlaveRegisteredMessage{} } @@ -933,9 +942,17 @@ func (m *SlaveRegisteredMessage) GetSlaveId() *SlaveID { return nil } +func (m *SlaveRegisteredMessage) GetConnection() *MasterSlaveConnection { + if m != nil { + return m.Connection + } + return nil +} + type SlaveReregisteredMessage struct { SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"` Reconciliations []*ReconcileTasksMessage `protobuf:"bytes,2,rep,name=reconciliations" json:"reconciliations,omitempty"` + Connection *MasterSlaveConnection `protobuf:"bytes,3,opt,name=connection" json:"connection,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -957,6 +974,13 @@ func (m *SlaveReregisteredMessage) GetReconciliations() []*ReconcileTasksMessage return nil } +func (m *SlaveReregisteredMessage) GetConnection() *MasterSlaveConnection { + if m != nil { + return m.Connection + } + return nil +} + type UnregisterSlaveMessage struct { SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"` XXX_unrecognized []byte `json:"-"` @@ -973,6 +997,25 @@ func (m *UnregisterSlaveMessage) GetSlaveId() *SlaveID { return nil } +type MasterSlaveConnection struct { + // Product of max_slave_ping_timeouts * slave_ping_timeout. + // If no pings are received within the total timeout, + // the master will remove the slave. + TotalPingTimeoutSeconds *float64 `protobuf:"fixed64,1,opt,name=total_ping_timeout_seconds" json:"total_ping_timeout_seconds,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MasterSlaveConnection) Reset() { *m = MasterSlaveConnection{} } +func (m *MasterSlaveConnection) String() string { return proto.CompactTextString(m) } +func (*MasterSlaveConnection) ProtoMessage() {} + +func (m *MasterSlaveConnection) GetTotalPingTimeoutSeconds() float64 { + if m != nil && m.TotalPingTimeoutSeconds != nil { + return *m.TotalPingTimeoutSeconds + } + return 0 +} + // This message is periodically sent by the master to the slave. // If the slave is connected to the master, "connected" is true. type PingSlaveMessage struct { @@ -1018,16 +1061,34 @@ func (m *ShutdownFrameworkMessage) GetFrameworkId() *FrameworkID { return nil } -// Tells the executor to initiate a shut down by invoking -// Executor::shutdown. +// Tells a slave (and consequently executor) to shutdown an executor. type ShutdownExecutorMessage struct { - XXX_unrecognized []byte `json:"-"` + // TODO(vinod): Make these fields required. These are made optional + // for backwards compatibility between 0.23.0 slave and pre 0.23.0 + // executor driver. + ExecutorId *ExecutorID `protobuf:"bytes,1,opt,name=executor_id" json:"executor_id,omitempty"` + FrameworkId *FrameworkID `protobuf:"bytes,2,opt,name=framework_id" json:"framework_id,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *ShutdownExecutorMessage) Reset() { *m = ShutdownExecutorMessage{} } func (m *ShutdownExecutorMessage) String() string { return proto.CompactTextString(m) } func (*ShutdownExecutorMessage) ProtoMessage() {} +func (m *ShutdownExecutorMessage) GetExecutorId() *ExecutorID { + if m != nil { + return m.ExecutorId + } + return nil +} + +func (m *ShutdownExecutorMessage) GetFrameworkId() *FrameworkID { + if m != nil { + return m.FrameworkId + } + return nil +} + type UpdateFrameworkMessage struct { FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"` Pid *string `protobuf:"bytes,2,req,name=pid" json:"pid,omitempty"` @@ -1052,6 +1113,52 @@ func (m *UpdateFrameworkMessage) GetPid() string { return "" } +// This message is sent to the slave whenever there is an update of +// the resources that need to be checkpointed (e.g., persistent volume +// or dynamic reservation). +type CheckpointResourcesMessage struct { + Resources []*Resource `protobuf:"bytes,1,rep,name=resources" json:"resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *CheckpointResourcesMessage) Reset() { *m = CheckpointResourcesMessage{} } +func (m *CheckpointResourcesMessage) String() string { return proto.CompactTextString(m) } +func (*CheckpointResourcesMessage) ProtoMessage() {} + +func (m *CheckpointResourcesMessage) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +// This message is sent by the slave to the master to inform the +// master about the total amount of oversubscribed (allocated and +// allocatable) resources. +type UpdateSlaveMessage struct { + SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"` + OversubscribedResources []*Resource `protobuf:"bytes,2,rep,name=oversubscribed_resources" json:"oversubscribed_resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *UpdateSlaveMessage) Reset() { *m = UpdateSlaveMessage{} } +func (m *UpdateSlaveMessage) String() string { return proto.CompactTextString(m) } +func (*UpdateSlaveMessage) ProtoMessage() {} + +func (m *UpdateSlaveMessage) GetSlaveId() *SlaveID { + if m != nil { + return m.SlaveId + } + return nil +} + +func (m *UpdateSlaveMessage) GetOversubscribedResources() []*Resource { + if m != nil { + return m.OversubscribedResources + } + return nil +} + type RegisterExecutorMessage struct { FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"` ExecutorId *ExecutorID `protobuf:"bytes,2,req,name=executor_id" json:"executor_id,omitempty"` @@ -1260,110 +1367,6 @@ func (m *ShutdownMessage) GetMessage() string { return "" } -type AuthenticateMessage struct { - Pid *string `protobuf:"bytes,1,req,name=pid" json:"pid,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *AuthenticateMessage) Reset() { *m = AuthenticateMessage{} } -func (m *AuthenticateMessage) String() string { return proto.CompactTextString(m) } -func (*AuthenticateMessage) ProtoMessage() {} - -func (m *AuthenticateMessage) GetPid() string { - if m != nil && m.Pid != nil { - return *m.Pid - } - return "" -} - -type AuthenticationMechanismsMessage struct { - Mechanisms []string `protobuf:"bytes,1,rep,name=mechanisms" json:"mechanisms,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *AuthenticationMechanismsMessage) Reset() { *m = AuthenticationMechanismsMessage{} } -func (m *AuthenticationMechanismsMessage) String() string { return proto.CompactTextString(m) } -func (*AuthenticationMechanismsMessage) ProtoMessage() {} - -func (m *AuthenticationMechanismsMessage) GetMechanisms() []string { - if m != nil { - return m.Mechanisms - } - return nil -} - -type AuthenticationStartMessage struct { - Mechanism *string `protobuf:"bytes,1,req,name=mechanism" json:"mechanism,omitempty"` - Data *string `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *AuthenticationStartMessage) Reset() { *m = AuthenticationStartMessage{} } -func (m *AuthenticationStartMessage) String() string { return proto.CompactTextString(m) } -func (*AuthenticationStartMessage) ProtoMessage() {} - -func (m *AuthenticationStartMessage) GetMechanism() string { - if m != nil && m.Mechanism != nil { - return *m.Mechanism - } - return "" -} - -func (m *AuthenticationStartMessage) GetData() string { - if m != nil && m.Data != nil { - return *m.Data - } - return "" -} - -type AuthenticationStepMessage struct { - Data []byte `protobuf:"bytes,1,req,name=data" json:"data,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *AuthenticationStepMessage) Reset() { *m = AuthenticationStepMessage{} } -func (m *AuthenticationStepMessage) String() string { return proto.CompactTextString(m) } -func (*AuthenticationStepMessage) ProtoMessage() {} - -func (m *AuthenticationStepMessage) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -type AuthenticationCompletedMessage struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *AuthenticationCompletedMessage) Reset() { *m = AuthenticationCompletedMessage{} } -func (m *AuthenticationCompletedMessage) String() string { return proto.CompactTextString(m) } -func (*AuthenticationCompletedMessage) ProtoMessage() {} - -type AuthenticationFailedMessage struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *AuthenticationFailedMessage) Reset() { *m = AuthenticationFailedMessage{} } -func (m *AuthenticationFailedMessage) String() string { return proto.CompactTextString(m) } -func (*AuthenticationFailedMessage) ProtoMessage() {} - -type AuthenticationErrorMessage struct { - Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *AuthenticationErrorMessage) Reset() { *m = AuthenticationErrorMessage{} } -func (m *AuthenticationErrorMessage) String() string { return proto.CompactTextString(m) } -func (*AuthenticationErrorMessage) ProtoMessage() {} - -func (m *AuthenticationErrorMessage) GetError() string { - if m != nil && m.Error != nil { - return *m.Error - } - return "" -} - // * // Describes Completed Frameworks, etc. for archival. type Archive struct { @@ -1465,86 +1468,24 @@ func (m *TaskHealthStatus) GetConsecutiveFailures() int32 { return 0 } -// Collection of Modules. -type Modules struct { - Libraries []*Modules_Library `protobuf:"bytes,1,rep,name=libraries" json:"libraries,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Modules) Reset() { *m = Modules{} } -func (m *Modules) String() string { return proto.CompactTextString(m) } -func (*Modules) ProtoMessage() {} - -func (m *Modules) GetLibraries() []*Modules_Library { - if m != nil { - return m.Libraries - } - return nil -} - -type Modules_Library struct { - // If "file" contains a slash ("/"), then it is interpreted as a - // (relative or absolute) pathname. Otherwise a standard library - // search is performed. - File *string `protobuf:"bytes,1,opt,name=file" json:"file,omitempty"` - // We will add the proper prefix ("lib") and suffix (".so" for - // Linux and ".dylib" for OS X) to the "name". - Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` - Modules []*Modules_Library_Module `protobuf:"bytes,3,rep,name=modules" json:"modules,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Modules_Library) Reset() { *m = Modules_Library{} } -func (m *Modules_Library) String() string { return proto.CompactTextString(m) } -func (*Modules_Library) ProtoMessage() {} - -func (m *Modules_Library) GetFile() string { - if m != nil && m.File != nil { - return *m.File - } - return "" -} - -func (m *Modules_Library) GetName() string { - if m != nil && m.Name != nil { - return *m.Name - } - return "" -} - -func (m *Modules_Library) GetModules() []*Modules_Library_Module { - if m != nil { - return m.Modules - } - return nil -} - -type Modules_Library_Module struct { - // Module name. - Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Module-specific parameters. - Parameters []*Parameter `protobuf:"bytes,2,rep,name=parameters" json:"parameters,omitempty"` - XXX_unrecognized []byte `json:"-"` +// * +// Message to signal completion of an event within a module. +type HookExecuted struct { + Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"` + XXX_unrecognized []byte `json:"-"` } -func (m *Modules_Library_Module) Reset() { *m = Modules_Library_Module{} } -func (m *Modules_Library_Module) String() string { return proto.CompactTextString(m) } -func (*Modules_Library_Module) ProtoMessage() {} +func (m *HookExecuted) Reset() { *m = HookExecuted{} } +func (m *HookExecuted) String() string { return proto.CompactTextString(m) } +func (*HookExecuted) ProtoMessage() {} -func (m *Modules_Library_Module) GetName() string { - if m != nil && m.Name != nil { - return *m.Name +func (m *HookExecuted) GetModule() string { + if m != nil && m.Module != nil { + return *m.Module } return "" } -func (m *Modules_Library_Module) GetParameters() []*Parameter { - if m != nil { - return m.Parameters - } - return nil -} - func init() { proto.RegisterEnum("mesosproto.StatusUpdateRecord_Type", StatusUpdateRecord_Type_name, StatusUpdateRecord_Type_value) } diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/messages.proto b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/messages.proto index 0182f419e88c..d58c99e9da16 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/messages.proto +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/messages.proto @@ -54,15 +54,14 @@ message Task { // NOTE: Either both the fields must be set or both must be unset. optional TaskState status_update_state = 9; optional bytes status_update_uuid = 10; -} + optional Labels labels = 11; -// Describes a role, which are used to group frameworks for allocation -// decisions, depending on the allocation policy being used. -// The weight field can be used to indicate forms of priority. -message RoleInfo { - required string name = 1; - optional double weight = 2 [default = 1]; + // Service discovery information for the task. It is not interpreted + // or acted upon by Mesos. It is up to a service discovery system + // to use this information as needed and to handle tasks without + // service discovery information. + optional DiscoveryInfo discovery = 12; } @@ -73,7 +72,11 @@ message StatusUpdate { optional SlaveID slave_id = 3; required TaskStatus status = 4; required double timestamp = 5; - required bytes uuid = 6; + + // This is being deprecated in favor of TaskStatus.uuid. In 0.23.0, + // we set the TaskStatus 'uuid' in the executor driver for all + // retryable status updates. + optional bytes uuid = 6; // This corresponds to the latest state of the task according to the // slave. Note that this state might be different than the state in @@ -188,7 +191,8 @@ message ReviveOffersMessage { message RunTaskMessage { - required FrameworkID framework_id = 1; + // TODO(karya): Remove framework_id after MESOS-2559 has shipped. + optional FrameworkID framework_id = 1 [deprecated = true]; required FrameworkInfo framework = 2; required string pid = 3; required TaskInfo task = 4; @@ -244,6 +248,11 @@ message FrameworkErrorMessage { message RegisterSlaveMessage { required SlaveInfo slave = 1; + // Resources that are checkpointed by the slave (e.g., persistent + // volume or dynamic reservation). Frameworks need to release + // checkpointed resources explicitly. + repeated Resource checkpointed_resources = 3; + // NOTE: This is a hack for the master to detect the slave's // version. If unset the slave is < 0.21.0. // TODO(bmahler): Do proper versioning: MESOS-986. @@ -252,11 +261,13 @@ message RegisterSlaveMessage { message ReregisterSlaveMessage { - // TODO(bmahler): slave_id is deprecated. - // 0.21.0: Now an optional field. Always written, never read. - // 0.22.0: Remove this field. - optional SlaveID slave_id = 1; required SlaveInfo slave = 2; + + // Resources that are checkpointed by the slave (e.g., persistent + // volume or dynamic reservation). Frameworks need to release + // checkpointed resources explicitly. + repeated Resource checkpointed_resources = 7; + repeated ExecutorInfo executor_infos = 4; repeated Task tasks = 3; repeated Archive.Framework completed_frameworks = 5; @@ -270,6 +281,7 @@ message ReregisterSlaveMessage { message SlaveRegisteredMessage { required SlaveID slave_id = 1; + optional MasterSlaveConnection connection = 2; } @@ -277,6 +289,7 @@ message SlaveReregisteredMessage { required SlaveID slave_id = 1; repeated ReconcileTasksMessage reconciliations = 2; + optional MasterSlaveConnection connection = 3; } @@ -285,6 +298,14 @@ message UnregisterSlaveMessage { } +message MasterSlaveConnection { + // Product of max_slave_ping_timeouts * slave_ping_timeout. + // If no pings are received within the total timeout, + // the master will remove the slave. + optional double total_ping_timeout_seconds = 1; +} + + // This message is periodically sent by the master to the slave. // If the slave is connected to the master, "connected" is true. message PingSlaveMessage { @@ -303,9 +324,14 @@ message ShutdownFrameworkMessage { } -// Tells the executor to initiate a shut down by invoking -// Executor::shutdown. -message ShutdownExecutorMessage {} +// Tells a slave (and consequently executor) to shutdown an executor. +message ShutdownExecutorMessage { + // TODO(vinod): Make these fields required. These are made optional + // for backwards compatibility between 0.23.0 slave and pre 0.23.0 + // executor driver. + optional ExecutorID executor_id = 1; + optional FrameworkID framework_id = 2; +} message UpdateFrameworkMessage { @@ -314,6 +340,23 @@ message UpdateFrameworkMessage { } +// This message is sent to the slave whenever there is an update of +// the resources that need to be checkpointed (e.g., persistent volume +// or dynamic reservation). +message CheckpointResourcesMessage { + repeated Resource resources = 1; +} + + +// This message is sent by the slave to the master to inform the +// master about the total amount of oversubscribed (allocated and +// allocatable) resources. +message UpdateSlaveMessage { + required SlaveID slave_id = 1; + repeated Resource oversubscribed_resources = 2; +} + + message RegisterExecutorMessage { required FrameworkID framework_id = 1; required ExecutorID executor_id = 2; @@ -361,38 +404,6 @@ message ShutdownMessage { } -message AuthenticateMessage { - required string pid = 1; // PID that needs to be authenticated. -} - - -message AuthenticationMechanismsMessage { - repeated string mechanisms = 1; // List of available SASL mechanisms. -} - - -message AuthenticationStartMessage { - required string mechanism = 1; - optional string data = 2; -} - - -message AuthenticationStepMessage { - required bytes data = 1; -} - - -message AuthenticationCompletedMessage {} - - -message AuthenticationFailedMessage {} - - -message AuthenticationErrorMessage { - optional string error = 1; -} - - // TODO(adam-mesos): Move this to an 'archive' package. /** * Describes Completed Frameworks, etc. for archival. @@ -426,28 +437,9 @@ message TaskHealthStatus { } -// Collection of Modules. -message Modules { - message Library { - // If "file" contains a slash ("/"), then it is interpreted as a - // (relative or absolute) pathname. Otherwise a standard library - // search is performed. - optional string file = 1; - - // We will add the proper prefix ("lib") and suffix (".so" for - // Linux and ".dylib" for OS X) to the "name". - optional string name = 2; - - message Module { - // Module name. - optional string name = 1; - - // Module-specific parameters. - repeated Parameter parameters = 2; - } - - repeated Module modules = 3; - } - - repeated Library libraries = 1; +/** + * Message to signal completion of an event within a module. + */ +message HookExecuted { + optional string module = 1; } diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/registry.pb.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/registry.pb.go index 77e782234698..0157ec37670c 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/registry.pb.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/registry.pb.go @@ -5,12 +5,14 @@ package mesosproto import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" import math "math" -// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb" +// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf type Registry struct { @@ -86,6 +88,3 @@ func (m *Registry_Slaves) GetSlaves() []*Registry_Slave { } return nil } - -func init() { -} diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/scheduler.pb.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/scheduler.pb.go index f90c727ae0bf..29a56ce181ae 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/scheduler.pb.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/scheduler.pb.go @@ -5,12 +5,14 @@ package mesosproto import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" import math "math" -// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb" +// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf // Possible event types, followed by message definitions if @@ -18,35 +20,32 @@ var _ = math.Inf type Event_Type int32 const ( - Event_REGISTERED Event_Type = 1 - Event_REREGISTERED Event_Type = 2 - Event_OFFERS Event_Type = 3 - Event_RESCIND Event_Type = 4 - Event_UPDATE Event_Type = 5 - Event_MESSAGE Event_Type = 6 - Event_FAILURE Event_Type = 7 - Event_ERROR Event_Type = 8 + Event_SUBSCRIBED Event_Type = 1 + Event_OFFERS Event_Type = 2 + Event_RESCIND Event_Type = 3 + Event_UPDATE Event_Type = 4 + Event_MESSAGE Event_Type = 5 + Event_FAILURE Event_Type = 6 + Event_ERROR Event_Type = 7 ) var Event_Type_name = map[int32]string{ - 1: "REGISTERED", - 2: "REREGISTERED", - 3: "OFFERS", - 4: "RESCIND", - 5: "UPDATE", - 6: "MESSAGE", - 7: "FAILURE", - 8: "ERROR", + 1: "SUBSCRIBED", + 2: "OFFERS", + 3: "RESCIND", + 4: "UPDATE", + 5: "MESSAGE", + 6: "FAILURE", + 7: "ERROR", } var Event_Type_value = map[string]int32{ - "REGISTERED": 1, - "REREGISTERED": 2, - "OFFERS": 3, - "RESCIND": 4, - "UPDATE": 5, - "MESSAGE": 6, - "FAILURE": 7, - "ERROR": 8, + "SUBSCRIBED": 1, + "OFFERS": 2, + "RESCIND": 3, + "UPDATE": 4, + "MESSAGE": 5, + "FAILURE": 6, + "ERROR": 7, } func (x Event_Type) Enum() *Event_Type { @@ -71,44 +70,41 @@ func (x *Event_Type) UnmarshalJSON(data []byte) error { type Call_Type int32 const ( - Call_REGISTER Call_Type = 1 - Call_REREGISTER Call_Type = 2 - Call_UNREGISTER Call_Type = 3 - Call_REQUEST Call_Type = 4 - Call_DECLINE Call_Type = 5 - Call_REVIVE Call_Type = 6 - Call_LAUNCH Call_Type = 7 - Call_KILL Call_Type = 8 - Call_ACKNOWLEDGE Call_Type = 9 - Call_RECONCILE Call_Type = 10 - Call_MESSAGE Call_Type = 11 + Call_SUBSCRIBE Call_Type = 1 + Call_TEARDOWN Call_Type = 2 + Call_ACCEPT Call_Type = 3 + Call_DECLINE Call_Type = 4 + Call_REVIVE Call_Type = 5 + Call_KILL Call_Type = 6 + Call_SHUTDOWN Call_Type = 7 + Call_ACKNOWLEDGE Call_Type = 8 + Call_RECONCILE Call_Type = 9 + Call_MESSAGE Call_Type = 10 ) var Call_Type_name = map[int32]string{ - 1: "REGISTER", - 2: "REREGISTER", - 3: "UNREGISTER", - 4: "REQUEST", - 5: "DECLINE", - 6: "REVIVE", - 7: "LAUNCH", - 8: "KILL", - 9: "ACKNOWLEDGE", - 10: "RECONCILE", - 11: "MESSAGE", + 1: "SUBSCRIBE", + 2: "TEARDOWN", + 3: "ACCEPT", + 4: "DECLINE", + 5: "REVIVE", + 6: "KILL", + 7: "SHUTDOWN", + 8: "ACKNOWLEDGE", + 9: "RECONCILE", + 10: "MESSAGE", } var Call_Type_value = map[string]int32{ - "REGISTER": 1, - "REREGISTER": 2, - "UNREGISTER": 3, - "REQUEST": 4, - "DECLINE": 5, - "REVIVE": 6, - "LAUNCH": 7, - "KILL": 8, - "ACKNOWLEDGE": 9, - "RECONCILE": 10, - "MESSAGE": 11, + "SUBSCRIBE": 1, + "TEARDOWN": 2, + "ACCEPT": 3, + "DECLINE": 4, + "REVIVE": 5, + "KILL": 6, + "SHUTDOWN": 7, + "ACKNOWLEDGE": 8, + "RECONCILE": 9, + "MESSAGE": 10, } func (x Call_Type) Enum() *Call_Type { @@ -129,23 +125,23 @@ func (x *Call_Type) UnmarshalJSON(data []byte) error { } // * -// Low-level scheduler event API. +// Scheduler event API. // // An event is described using the standard protocol buffer "union" -// trick, see https://developers.google.com/protocol-buffers/docs/techniques#union. +// trick, see: +// https://developers.google.com/protocol-buffers/docs/techniques#union. type Event struct { // Type of the event, indicates which optional field below should be // present if that type has a nested message definition. - Type *Event_Type `protobuf:"varint,1,req,name=type,enum=mesosproto.Event_Type" json:"type,omitempty"` - Registered *Event_Registered `protobuf:"bytes,2,opt,name=registered" json:"registered,omitempty"` - Reregistered *Event_Reregistered `protobuf:"bytes,3,opt,name=reregistered" json:"reregistered,omitempty"` - Offers *Event_Offers `protobuf:"bytes,4,opt,name=offers" json:"offers,omitempty"` - Rescind *Event_Rescind `protobuf:"bytes,5,opt,name=rescind" json:"rescind,omitempty"` - Update *Event_Update `protobuf:"bytes,6,opt,name=update" json:"update,omitempty"` - Message *Event_Message `protobuf:"bytes,7,opt,name=message" json:"message,omitempty"` - Failure *Event_Failure `protobuf:"bytes,8,opt,name=failure" json:"failure,omitempty"` - Error *Event_Error `protobuf:"bytes,9,opt,name=error" json:"error,omitempty"` - XXX_unrecognized []byte `json:"-"` + Type *Event_Type `protobuf:"varint,1,req,name=type,enum=mesosproto.Event_Type" json:"type,omitempty"` + Subscribed *Event_Subscribed `protobuf:"bytes,2,opt,name=subscribed" json:"subscribed,omitempty"` + Offers *Event_Offers `protobuf:"bytes,3,opt,name=offers" json:"offers,omitempty"` + Rescind *Event_Rescind `protobuf:"bytes,4,opt,name=rescind" json:"rescind,omitempty"` + Update *Event_Update `protobuf:"bytes,5,opt,name=update" json:"update,omitempty"` + Message *Event_Message `protobuf:"bytes,6,opt,name=message" json:"message,omitempty"` + Failure *Event_Failure `protobuf:"bytes,7,opt,name=failure" json:"failure,omitempty"` + Error *Event_Error `protobuf:"bytes,8,opt,name=error" json:"error,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *Event) Reset() { *m = Event{} } @@ -156,19 +152,12 @@ func (m *Event) GetType() Event_Type { if m != nil && m.Type != nil { return *m.Type } - return Event_REGISTERED -} - -func (m *Event) GetRegistered() *Event_Registered { - if m != nil { - return m.Registered - } - return nil + return Event_SUBSCRIBED } -func (m *Event) GetReregistered() *Event_Reregistered { +func (m *Event) GetSubscribed() *Event_Subscribed { if m != nil { - return m.Reregistered + return m.Subscribed } return nil } @@ -215,54 +204,27 @@ func (m *Event) GetError() *Event_Error { return nil } -type Event_Registered struct { +// First event received when the scheduler subscribes. +type Event_Subscribed struct { FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"` - MasterInfo *MasterInfo `protobuf:"bytes,2,req,name=master_info" json:"master_info,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (m *Event_Registered) Reset() { *m = Event_Registered{} } -func (m *Event_Registered) String() string { return proto.CompactTextString(m) } -func (*Event_Registered) ProtoMessage() {} +func (m *Event_Subscribed) Reset() { *m = Event_Subscribed{} } +func (m *Event_Subscribed) String() string { return proto.CompactTextString(m) } +func (*Event_Subscribed) ProtoMessage() {} -func (m *Event_Registered) GetFrameworkId() *FrameworkID { +func (m *Event_Subscribed) GetFrameworkId() *FrameworkID { if m != nil { return m.FrameworkId } return nil } -func (m *Event_Registered) GetMasterInfo() *MasterInfo { - if m != nil { - return m.MasterInfo - } - return nil -} - -type Event_Reregistered struct { - FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"` - MasterInfo *MasterInfo `protobuf:"bytes,2,req,name=master_info" json:"master_info,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Event_Reregistered) Reset() { *m = Event_Reregistered{} } -func (m *Event_Reregistered) String() string { return proto.CompactTextString(m) } -func (*Event_Reregistered) ProtoMessage() {} - -func (m *Event_Reregistered) GetFrameworkId() *FrameworkID { - if m != nil { - return m.FrameworkId - } - return nil -} - -func (m *Event_Reregistered) GetMasterInfo() *MasterInfo { - if m != nil { - return m.MasterInfo - } - return nil -} - +// Received whenever there are new resources that are offered to the +// scheduler. Each offer corresponds to a set of resources on a +// slave. Until the scheduler accepts or declines an offer the +// resources are considered allocated to the scheduler. type Event_Offers struct { Offers []*Offer `protobuf:"bytes,1,rep,name=offers" json:"offers,omitempty"` XXX_unrecognized []byte `json:"-"` @@ -279,6 +241,10 @@ func (m *Event_Offers) GetOffers() []*Offer { return nil } +// Received when a particular offer is no longer valid (e.g., the +// slave corresponding to the offer has been removed) and hence +// needs to be rescinded. Any future calls ('Accept' / 'Decline') made +// by the scheduler regarding this offer will be invalid. type Event_Rescind struct { OfferId *OfferID `protobuf:"bytes,1,req,name=offer_id" json:"offer_id,omitempty"` XXX_unrecognized []byte `json:"-"` @@ -295,9 +261,17 @@ func (m *Event_Rescind) GetOfferId() *OfferID { return nil } +// Received whenever there is a status update that is generated by +// the executor or slave or master. Status updates should be used by +// executors to reliably communicate the status of the tasks that +// they manage. It is crucial that a terminal update (see TaskState +// in mesos.proto) is sent by the executor as soon as the task +// terminates, in order for Mesos to release the resources allocated +// to the task. It is also the responsibility of the scheduler to +// explicitly acknowledge the receipt of a status update. See +// 'Acknowledge' in the 'Call' section below for the semantics. type Event_Update struct { - Uuid []byte `protobuf:"bytes,1,req,name=uuid" json:"uuid,omitempty"` - Status *TaskStatus `protobuf:"bytes,2,req,name=status" json:"status,omitempty"` + Status *TaskStatus `protobuf:"bytes,1,req,name=status" json:"status,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -305,13 +279,6 @@ func (m *Event_Update) Reset() { *m = Event_Update{} } func (m *Event_Update) String() string { return proto.CompactTextString(m) } func (*Event_Update) ProtoMessage() {} -func (m *Event_Update) GetUuid() []byte { - if m != nil { - return m.Uuid - } - return nil -} - func (m *Event_Update) GetStatus() *TaskStatus { if m != nil { return m.Status @@ -319,6 +286,11 @@ func (m *Event_Update) GetStatus() *TaskStatus { return nil } +// Received when a custom message generated by the executor is +// forwarded by the master. Note that this message is not +// interpreted by Mesos and is only forwarded (without reliability +// guarantees) to the scheduler. It is up to the executor to retry +// if the message is dropped for any reason. type Event_Message struct { SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"` ExecutorId *ExecutorID `protobuf:"bytes,2,req,name=executor_id" json:"executor_id,omitempty"` @@ -351,6 +323,16 @@ func (m *Event_Message) GetData() []byte { return nil } +// Received when a slave is removed from the cluster (e.g., failed +// health checks) or when an executor is terminated. Note that, this +// event coincides with receipt of terminal UPDATE events for any +// active tasks belonging to the slave or executor and receipt of +// 'Rescind' events for any outstanding offers belonging to the +// slave. Note that there is no guaranteed order between the +// 'Failure', 'Update' and 'Rescind' events when a slave or executor +// is removed. +// TODO(vinod): Consider splitting the lost slave and terminated +// executor into separate events and ensure it's reliably generated. type Event_Failure struct { SlaveId *SlaveID `protobuf:"bytes,1,opt,name=slave_id" json:"slave_id,omitempty"` // If this was just a failure of an executor on a slave then @@ -386,6 +368,13 @@ func (m *Event_Failure) GetStatus() int32 { return 0 } +// Received when an invalid framework (e.g., unauthenticated, +// unauthorized) attempts to subscribe with the master. Error can +// also be received if scheduler sends invalid Calls (e.g., not +// properly initialized). +// TODO(vinod): Remove this once the old scheduler driver is no +// longer supported. With HTTP API all errors will be signaled via +// HTTP response codes. type Event_Error struct { Message *string `protobuf:"bytes,1,req,name=message" json:"message,omitempty"` XXX_unrecognized []byte `json:"-"` @@ -403,25 +392,29 @@ func (m *Event_Error) GetMessage() string { } // * -// Low-level scheduler call API. +// Scheduler call API. // // Like Event, a Call is described using the standard protocol buffer // "union" trick (see above). type Call struct { - // Identifies who generated this call. Always necessary, but the - // only thing that needs to be set for certain calls, e.g., - // REGISTER, REREGISTER, and UNREGISTER. - FrameworkInfo *FrameworkInfo `protobuf:"bytes,1,req,name=framework_info" json:"framework_info,omitempty"` + // Identifies who generated this call. Master assigns a framework id + // when a new scheduler subscribes for the first time. Once assigned, + // the scheduler must set the 'framework_id' here and within its + // FrameworkInfo (in any further 'Subscribe' calls). This allows the + // master to identify a scheduler correctly across disconnections, + // failovers, etc. + FrameworkId *FrameworkID `protobuf:"bytes,1,opt,name=framework_id" json:"framework_id,omitempty"` // Type of the call, indicates which optional field below should be // present if that type has a nested message definition. Type *Call_Type `protobuf:"varint,2,req,name=type,enum=mesosproto.Call_Type" json:"type,omitempty"` - Request *Call_Request `protobuf:"bytes,3,opt,name=request" json:"request,omitempty"` - Decline *Call_Decline `protobuf:"bytes,4,opt,name=decline" json:"decline,omitempty"` - Launch *Call_Launch `protobuf:"bytes,5,opt,name=launch" json:"launch,omitempty"` + Subscribe *Call_Subscribe `protobuf:"bytes,3,opt,name=subscribe" json:"subscribe,omitempty"` + Accept *Call_Accept `protobuf:"bytes,4,opt,name=accept" json:"accept,omitempty"` + Decline *Call_Decline `protobuf:"bytes,5,opt,name=decline" json:"decline,omitempty"` Kill *Call_Kill `protobuf:"bytes,6,opt,name=kill" json:"kill,omitempty"` - Acknowledge *Call_Acknowledge `protobuf:"bytes,7,opt,name=acknowledge" json:"acknowledge,omitempty"` - Reconcile *Call_Reconcile `protobuf:"bytes,8,opt,name=reconcile" json:"reconcile,omitempty"` - Message *Call_Message `protobuf:"bytes,9,opt,name=message" json:"message,omitempty"` + Shutdown *Call_Shutdown `protobuf:"bytes,7,opt,name=shutdown" json:"shutdown,omitempty"` + Acknowledge *Call_Acknowledge `protobuf:"bytes,8,opt,name=acknowledge" json:"acknowledge,omitempty"` + Reconcile *Call_Reconcile `protobuf:"bytes,9,opt,name=reconcile" json:"reconcile,omitempty"` + Message *Call_Message `protobuf:"bytes,10,opt,name=message" json:"message,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -429,9 +422,9 @@ func (m *Call) Reset() { *m = Call{} } func (m *Call) String() string { return proto.CompactTextString(m) } func (*Call) ProtoMessage() {} -func (m *Call) GetFrameworkInfo() *FrameworkInfo { +func (m *Call) GetFrameworkId() *FrameworkID { if m != nil { - return m.FrameworkInfo + return m.FrameworkId } return nil } @@ -440,26 +433,26 @@ func (m *Call) GetType() Call_Type { if m != nil && m.Type != nil { return *m.Type } - return Call_REGISTER + return Call_SUBSCRIBE } -func (m *Call) GetRequest() *Call_Request { +func (m *Call) GetSubscribe() *Call_Subscribe { if m != nil { - return m.Request + return m.Subscribe } return nil } -func (m *Call) GetDecline() *Call_Decline { +func (m *Call) GetAccept() *Call_Accept { if m != nil { - return m.Decline + return m.Accept } return nil } -func (m *Call) GetLaunch() *Call_Launch { +func (m *Call) GetDecline() *Call_Decline { if m != nil { - return m.Launch + return m.Decline } return nil } @@ -471,6 +464,13 @@ func (m *Call) GetKill() *Call_Kill { return nil } +func (m *Call) GetShutdown() *Call_Shutdown { + if m != nil { + return m.Shutdown + } + return nil +} + func (m *Call) GetAcknowledge() *Call_Acknowledge { if m != nil { return m.Acknowledge @@ -492,22 +492,105 @@ func (m *Call) GetMessage() *Call_Message { return nil } -type Call_Request struct { - Requests []*Request `protobuf:"bytes,1,rep,name=requests" json:"requests,omitempty"` - XXX_unrecognized []byte `json:"-"` +// Subscribes the scheduler with the master to receive events. A +// scheduler must send other calls only after it has received the +// SUBCRIBED event. +type Call_Subscribe struct { + // See the comments below on 'framework_id' on the semantics for + // 'framework_info.id'. + FrameworkInfo *FrameworkInfo `protobuf:"bytes,1,req,name=framework_info" json:"framework_info,omitempty"` + // 'force' field is only relevant when 'framework_info.id' is set. + // It tells the master what to do in case an instance of the + // scheduler attempts to subscribe when another instance of it is + // already connected (e.g., split brain due to network partition). + // If 'force' is true, this scheduler instance is allowed and the + // old connected scheduler instance is disconnected. If false, + // this scheduler instance is disallowed subscription in favor of + // the already connected scheduler instance. + // + // It is recommended to set this to true only when a newly elected + // scheduler instance is attempting to subscribe but not when a + // scheduler is retrying subscription (e.g., disconnection or + // master failover; see sched/sched.cpp for an example). + Force *bool `protobuf:"varint,2,opt,name=force" json:"force,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Subscribe) Reset() { *m = Call_Subscribe{} } +func (m *Call_Subscribe) String() string { return proto.CompactTextString(m) } +func (*Call_Subscribe) ProtoMessage() {} + +func (m *Call_Subscribe) GetFrameworkInfo() *FrameworkInfo { + if m != nil { + return m.FrameworkInfo + } + return nil +} + +func (m *Call_Subscribe) GetForce() bool { + if m != nil && m.Force != nil { + return *m.Force + } + return false +} + +// Accepts an offer, performing the specified operations +// in a sequential manner. +// +// E.g. Launch a task with a newly reserved persistent volume: +// +// Accept { +// offer_ids: [ ... ] +// operations: [ +// { type: RESERVE, +// reserve: { resources: [ disk(role):2 ] } } +// { type: CREATE, +// create: { volumes: [ disk(role):1+persistence ] } } +// { type: LAUNCH, +// launch: { task_infos ... disk(role):1;disk(role):1+persistence } } +// ] +// } +// +// Note that any of the offer’s resources not used in the 'Accept' +// call (e.g., to launch a task) are considered unused and might be +// reoffered to other frameworks. In other words, the same OfferID +// cannot be used in more than one 'Accept' call. +type Call_Accept struct { + OfferIds []*OfferID `protobuf:"bytes,1,rep,name=offer_ids" json:"offer_ids,omitempty"` + Operations []*Offer_Operation `protobuf:"bytes,2,rep,name=operations" json:"operations,omitempty"` + Filters *Filters `protobuf:"bytes,3,opt,name=filters" json:"filters,omitempty"` + XXX_unrecognized []byte `json:"-"` } -func (m *Call_Request) Reset() { *m = Call_Request{} } -func (m *Call_Request) String() string { return proto.CompactTextString(m) } -func (*Call_Request) ProtoMessage() {} +func (m *Call_Accept) Reset() { *m = Call_Accept{} } +func (m *Call_Accept) String() string { return proto.CompactTextString(m) } +func (*Call_Accept) ProtoMessage() {} + +func (m *Call_Accept) GetOfferIds() []*OfferID { + if m != nil { + return m.OfferIds + } + return nil +} -func (m *Call_Request) GetRequests() []*Request { +func (m *Call_Accept) GetOperations() []*Offer_Operation { if m != nil { - return m.Requests + return m.Operations } return nil } +func (m *Call_Accept) GetFilters() *Filters { + if m != nil { + return m.Filters + } + return nil +} + +// Declines an offer, signaling the master to potentially reoffer +// the resources to a different framework. Note that this is same +// as sending an Accept call with no operations. See comments on +// top of 'Accept' for semantics. type Call_Decline struct { OfferIds []*OfferID `protobuf:"bytes,1,rep,name=offer_ids" json:"offer_ids,omitempty"` Filters *Filters `protobuf:"bytes,2,opt,name=filters" json:"filters,omitempty"` @@ -532,54 +615,73 @@ func (m *Call_Decline) GetFilters() *Filters { return nil } -type Call_Launch struct { - TaskInfos []*TaskInfo `protobuf:"bytes,1,rep,name=task_infos" json:"task_infos,omitempty"` - OfferIds []*OfferID `protobuf:"bytes,2,rep,name=offer_ids" json:"offer_ids,omitempty"` - Filters *Filters `protobuf:"bytes,3,opt,name=filters" json:"filters,omitempty"` - XXX_unrecognized []byte `json:"-"` +// Kills a specific task. If the scheduler has a custom executor, +// the kill is forwarded to the executor and it is up to the +// executor to kill the task and send a TASK_KILLED (or TASK_FAILED) +// update. Note that Mesos releases the resources for a task once it +// receives a terminal update (See TaskState in mesos.proto) for it. +// If the task is unknown to the master, a TASK_LOST update is +// generated. +type Call_Kill struct { + TaskId *TaskID `protobuf:"bytes,1,req,name=task_id" json:"task_id,omitempty"` + SlaveId *SlaveID `protobuf:"bytes,2,opt,name=slave_id" json:"slave_id,omitempty"` + XXX_unrecognized []byte `json:"-"` } -func (m *Call_Launch) Reset() { *m = Call_Launch{} } -func (m *Call_Launch) String() string { return proto.CompactTextString(m) } -func (*Call_Launch) ProtoMessage() {} +func (m *Call_Kill) Reset() { *m = Call_Kill{} } +func (m *Call_Kill) String() string { return proto.CompactTextString(m) } +func (*Call_Kill) ProtoMessage() {} -func (m *Call_Launch) GetTaskInfos() []*TaskInfo { +func (m *Call_Kill) GetTaskId() *TaskID { if m != nil { - return m.TaskInfos + return m.TaskId } return nil } -func (m *Call_Launch) GetOfferIds() []*OfferID { +func (m *Call_Kill) GetSlaveId() *SlaveID { if m != nil { - return m.OfferIds + return m.SlaveId } return nil } -func (m *Call_Launch) GetFilters() *Filters { +// Shuts down a custom executor. When the executor gets a shutdown +// event, it is expected to kill all its tasks (and send TASK_KILLED +// updates) and terminate. If the executor doesn’t terminate within +// a certain timeout (configurable via +// '--executor_shutdown_grace_period' slave flag), the slave will +// forcefully destroy the container (executor and its tasks) and +// transition its active tasks to TASK_LOST. +type Call_Shutdown struct { + ExecutorId *ExecutorID `protobuf:"bytes,1,req,name=executor_id" json:"executor_id,omitempty"` + SlaveId *SlaveID `protobuf:"bytes,2,req,name=slave_id" json:"slave_id,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Shutdown) Reset() { *m = Call_Shutdown{} } +func (m *Call_Shutdown) String() string { return proto.CompactTextString(m) } +func (*Call_Shutdown) ProtoMessage() {} + +func (m *Call_Shutdown) GetExecutorId() *ExecutorID { if m != nil { - return m.Filters + return m.ExecutorId } return nil } -type Call_Kill struct { - TaskId *TaskID `protobuf:"bytes,1,req,name=task_id" json:"task_id,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Call_Kill) Reset() { *m = Call_Kill{} } -func (m *Call_Kill) String() string { return proto.CompactTextString(m) } -func (*Call_Kill) ProtoMessage() {} - -func (m *Call_Kill) GetTaskId() *TaskID { +func (m *Call_Shutdown) GetSlaveId() *SlaveID { if m != nil { - return m.TaskId + return m.SlaveId } return nil } +// Acknowledges the receipt of status update. Schedulers are +// responsible for explicitly acknowledging the receipt of status +// updates that have 'Update.status().uuid()' field set. Such status +// updates are retried by the slave until they are acknowledged by +// the scheduler. type Call_Acknowledge struct { SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"` TaskId *TaskID `protobuf:"bytes,2,req,name=task_id" json:"task_id,omitempty"` @@ -612,30 +714,56 @@ func (m *Call_Acknowledge) GetUuid() []byte { return nil } -// Allows the framework to query the status for non-terminal tasks. +// Allows the scheduler to query the status for non-terminal tasks. // This causes the master to send back the latest task status for -// each task in 'statuses', if possible. Tasks that are no longer -// known will result in a TASK_LOST update. If statuses is empty, -// then the master will send the latest status for each task -// currently known. -// TODO(bmahler): Add a guiding document for reconciliation or -// document reconciliation in-depth here. +// each task in 'tasks', if possible. Tasks that are no longer known +// will result in a TASK_LOST update. If 'statuses' is empty, then +// the master will send the latest status for each task currently +// known. type Call_Reconcile struct { - Statuses []*TaskStatus `protobuf:"bytes,1,rep,name=statuses" json:"statuses,omitempty"` - XXX_unrecognized []byte `json:"-"` + Tasks []*Call_Reconcile_Task `protobuf:"bytes,1,rep,name=tasks" json:"tasks,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *Call_Reconcile) Reset() { *m = Call_Reconcile{} } func (m *Call_Reconcile) String() string { return proto.CompactTextString(m) } func (*Call_Reconcile) ProtoMessage() {} -func (m *Call_Reconcile) GetStatuses() []*TaskStatus { +func (m *Call_Reconcile) GetTasks() []*Call_Reconcile_Task { + if m != nil { + return m.Tasks + } + return nil +} + +// TODO(vinod): Support arbitrary queries than just state of tasks. +type Call_Reconcile_Task struct { + TaskId *TaskID `protobuf:"bytes,1,req,name=task_id" json:"task_id,omitempty"` + SlaveId *SlaveID `protobuf:"bytes,2,opt,name=slave_id" json:"slave_id,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Reconcile_Task) Reset() { *m = Call_Reconcile_Task{} } +func (m *Call_Reconcile_Task) String() string { return proto.CompactTextString(m) } +func (*Call_Reconcile_Task) ProtoMessage() {} + +func (m *Call_Reconcile_Task) GetTaskId() *TaskID { if m != nil { - return m.Statuses + return m.TaskId + } + return nil +} + +func (m *Call_Reconcile_Task) GetSlaveId() *SlaveID { + if m != nil { + return m.SlaveId } return nil } +// Sends arbitrary binary data to the executor. Note that Mesos +// neither interprets this data nor makes any guarantees about the +// delivery of this message to the executor. type Call_Message struct { SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"` ExecutorId *ExecutorID `protobuf:"bytes,2,req,name=executor_id" json:"executor_id,omitempty"` diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/scheduler.proto b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/scheduler.proto index 6117bb1211f4..dfa20500f976 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/scheduler.proto +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/scheduler.proto @@ -23,54 +23,80 @@ import "github.com/gogo/protobuf/gogoproto/gogo.proto"; /** - * Low-level scheduler event API. + * Scheduler event API. * * An event is described using the standard protocol buffer "union" - * trick, see https://developers.google.com/protocol-buffers/docs/techniques#union. + * trick, see: + * https://developers.google.com/protocol-buffers/docs/techniques#union. */ message Event { // Possible event types, followed by message definitions if // applicable. enum Type { - REGISTERED = 1; - REREGISTERED = 2; - OFFERS = 3; - RESCIND = 4; - UPDATE = 5; - MESSAGE = 6; - FAILURE = 7; - ERROR = 8; + SUBSCRIBED = 1; // See 'Subscribed' below. + OFFERS = 2; // See 'Offers' below. + RESCIND = 3; // See 'Rescind' below. + UPDATE = 4; // See 'Update' below. + MESSAGE = 5; // See 'Message' below. + FAILURE = 6; // See 'Failure' below. + ERROR = 7; // See 'Error' below. } - message Registered { + // First event received when the scheduler subscribes. + message Subscribed { required FrameworkID framework_id = 1; - required MasterInfo master_info = 2; - } - - message Reregistered { - required FrameworkID framework_id = 1; - required MasterInfo master_info = 2; } + // Received whenever there are new resources that are offered to the + // scheduler. Each offer corresponds to a set of resources on a + // slave. Until the scheduler accepts or declines an offer the + // resources are considered allocated to the scheduler. message Offers { repeated Offer offers = 1; } + // Received when a particular offer is no longer valid (e.g., the + // slave corresponding to the offer has been removed) and hence + // needs to be rescinded. Any future calls ('Accept' / 'Decline') made + // by the scheduler regarding this offer will be invalid. message Rescind { required OfferID offer_id = 1; } + // Received whenever there is a status update that is generated by + // the executor or slave or master. Status updates should be used by + // executors to reliably communicate the status of the tasks that + // they manage. It is crucial that a terminal update (see TaskState + // in mesos.proto) is sent by the executor as soon as the task + // terminates, in order for Mesos to release the resources allocated + // to the task. It is also the responsibility of the scheduler to + // explicitly acknowledge the receipt of a status update. See + // 'Acknowledge' in the 'Call' section below for the semantics. message Update { - required bytes uuid = 1; // TODO(benh): Replace with UpdateID. - required TaskStatus status = 2; + required TaskStatus status = 1; } + // Received when a custom message generated by the executor is + // forwarded by the master. Note that this message is not + // interpreted by Mesos and is only forwarded (without reliability + // guarantees) to the scheduler. It is up to the executor to retry + // if the message is dropped for any reason. message Message { required SlaveID slave_id = 1; required ExecutorID executor_id = 2; required bytes data = 3; } + // Received when a slave is removed from the cluster (e.g., failed + // health checks) or when an executor is terminated. Note that, this + // event coincides with receipt of terminal UPDATE events for any + // active tasks belonging to the slave or executor and receipt of + // 'Rescind' events for any outstanding offers belonging to the + // slave. Note that there is no guaranteed order between the + // 'Failure', 'Update' and 'Rescind' events when a slave or executor + // is removed. + // TODO(vinod): Consider splitting the lost slave and terminated + // executor into separate events and ensure it's reliably generated. message Failure { optional SlaveID slave_id = 1; @@ -81,29 +107,33 @@ message Event { optional int32 status = 3; } + // Received when an invalid framework (e.g., unauthenticated, + // unauthorized) attempts to subscribe with the master. Error can + // also be received if scheduler sends invalid Calls (e.g., not + // properly initialized). + // TODO(vinod): Remove this once the old scheduler driver is no + // longer supported. With HTTP API all errors will be signaled via + // HTTP response codes. message Error { required string message = 1; } - // TODO(benh): Add a 'from' or 'sender'. - // Type of the event, indicates which optional field below should be // present if that type has a nested message definition. required Type type = 1; - optional Registered registered = 2; - optional Reregistered reregistered = 3; - optional Offers offers = 4; - optional Rescind rescind = 5; - optional Update update = 6; - optional Message message = 7; - optional Failure failure = 8; - optional Error error = 9; + optional Subscribed subscribed = 2; + optional Offers offers = 3; + optional Rescind rescind = 4; + optional Update update = 5; + optional Message message = 6; + optional Failure failure = 7; + optional Error error = 8; } /** - * Low-level scheduler call API. + * Scheduler call API. * * Like Event, a Call is described using the standard protocol buffer * "union" trick (see above). @@ -112,20 +142,19 @@ message Call { // Possible call types, followed by message definitions if // applicable. enum Type { - REGISTER = 1; - REREGISTER = 2; - UNREGISTER = 3; - REQUEST = 4; - DECLINE = 5; - REVIVE = 6; - LAUNCH = 7; - KILL = 8; - ACKNOWLEDGE = 9; - RECONCILE = 10; - MESSAGE = 11; + SUBSCRIBE = 1; // See 'Subscribe' below. + TEARDOWN = 2; // Shuts down all tasks/executors and removes framework. + ACCEPT = 3; // See 'Accept' below. + DECLINE = 4; // See 'Decline' below. + REVIVE = 5; // Removes any previous filters set via ACCEPT or DECLINE. + KILL = 6; // See 'Kill' below. + SHUTDOWN = 7; // See 'Shutdown' below. + ACKNOWLEDGE = 8; // See 'Acknowledge' below. + RECONCILE = 9; // See 'Reconcile' below. + MESSAGE = 10; // See 'Message' below. // TODO(benh): Consider adding an 'ACTIVATE' and 'DEACTIVATE' for - // already registered frameworks as a way of stopping offers from + // already subscribed frameworks as a way of stopping offers from // being generated and other events from being sent by the master. // Note that this functionality existed originally to support // SchedulerDriver::abort which was only necessary to handle @@ -133,63 +162,144 @@ message Call { // something that is not an issue with the Event/Call API. } - message Request { - repeated mesosproto.Request requests = 1; + // Subscribes the scheduler with the master to receive events. A + // scheduler must send other calls only after it has received the + // SUBCRIBED event. + message Subscribe { + // See the comments below on 'framework_id' on the semantics for + // 'framework_info.id'. + required FrameworkInfo framework_info = 1; + + // 'force' field is only relevant when 'framework_info.id' is set. + // It tells the master what to do in case an instance of the + // scheduler attempts to subscribe when another instance of it is + // already connected (e.g., split brain due to network partition). + // If 'force' is true, this scheduler instance is allowed and the + // old connected scheduler instance is disconnected. If false, + // this scheduler instance is disallowed subscription in favor of + // the already connected scheduler instance. + // + // It is recommended to set this to true only when a newly elected + // scheduler instance is attempting to subscribe but not when a + // scheduler is retrying subscription (e.g., disconnection or + // master failover; see sched/sched.cpp for an example). + optional bool force = 2; } - message Decline { + // Accepts an offer, performing the specified operations + // in a sequential manner. + // + // E.g. Launch a task with a newly reserved persistent volume: + // + // Accept { + // offer_ids: [ ... ] + // operations: [ + // { type: RESERVE, + // reserve: { resources: [ disk(role):2 ] } } + // { type: CREATE, + // create: { volumes: [ disk(role):1+persistence ] } } + // { type: LAUNCH, + // launch: { task_infos ... disk(role):1;disk(role):1+persistence } } + // ] + // } + // + // Note that any of the offer’s resources not used in the 'Accept' + // call (e.g., to launch a task) are considered unused and might be + // reoffered to other frameworks. In other words, the same OfferID + // cannot be used in more than one 'Accept' call. + message Accept { repeated OfferID offer_ids = 1; - optional Filters filters = 2; + repeated Offer.Operation operations = 2; + optional Filters filters = 3; } - message Launch { - repeated TaskInfo task_infos = 1; - repeated OfferID offer_ids = 2; - optional Filters filters = 3; + // Declines an offer, signaling the master to potentially reoffer + // the resources to a different framework. Note that this is same + // as sending an Accept call with no operations. See comments on + // top of 'Accept' for semantics. + message Decline { + repeated OfferID offer_ids = 1; + optional Filters filters = 2; } + // Kills a specific task. If the scheduler has a custom executor, + // the kill is forwarded to the executor and it is up to the + // executor to kill the task and send a TASK_KILLED (or TASK_FAILED) + // update. Note that Mesos releases the resources for a task once it + // receives a terminal update (See TaskState in mesos.proto) for it. + // If the task is unknown to the master, a TASK_LOST update is + // generated. message Kill { required TaskID task_id = 1; + optional SlaveID slave_id = 2; } + // Shuts down a custom executor. When the executor gets a shutdown + // event, it is expected to kill all its tasks (and send TASK_KILLED + // updates) and terminate. If the executor doesn’t terminate within + // a certain timeout (configurable via + // '--executor_shutdown_grace_period' slave flag), the slave will + // forcefully destroy the container (executor and its tasks) and + // transition its active tasks to TASK_LOST. + message Shutdown { + required ExecutorID executor_id = 1; + required SlaveID slave_id = 2; + } + + // Acknowledges the receipt of status update. Schedulers are + // responsible for explicitly acknowledging the receipt of status + // updates that have 'Update.status().uuid()' field set. Such status + // updates are retried by the slave until they are acknowledged by + // the scheduler. message Acknowledge { required SlaveID slave_id = 1; required TaskID task_id = 2; required bytes uuid = 3; } - // Allows the framework to query the status for non-terminal tasks. + // Allows the scheduler to query the status for non-terminal tasks. // This causes the master to send back the latest task status for - // each task in 'statuses', if possible. Tasks that are no longer - // known will result in a TASK_LOST update. If statuses is empty, - // then the master will send the latest status for each task - // currently known. - // TODO(bmahler): Add a guiding document for reconciliation or - // document reconciliation in-depth here. + // each task in 'tasks', if possible. Tasks that are no longer known + // will result in a TASK_LOST update. If 'statuses' is empty, then + // the master will send the latest status for each task currently + // known. message Reconcile { - repeated TaskStatus statuses = 1; // Should be non-terminal only. + // TODO(vinod): Support arbitrary queries than just state of tasks. + message Task { + required TaskID task_id = 1; + optional SlaveID slave_id = 2; + } + + repeated Task tasks = 1; } + // Sends arbitrary binary data to the executor. Note that Mesos + // neither interprets this data nor makes any guarantees about the + // delivery of this message to the executor. message Message { required SlaveID slave_id = 1; required ExecutorID executor_id = 2; required bytes data = 3; } - // Identifies who generated this call. Always necessary, but the - // only thing that needs to be set for certain calls, e.g., - // REGISTER, REREGISTER, and UNREGISTER. - required FrameworkInfo framework_info = 1; + // Identifies who generated this call. Master assigns a framework id + // when a new scheduler subscribes for the first time. Once assigned, + // the scheduler must set the 'framework_id' here and within its + // FrameworkInfo (in any further 'Subscribe' calls). This allows the + // master to identify a scheduler correctly across disconnections, + // failovers, etc. + optional FrameworkID framework_id = 1; // Type of the call, indicates which optional field below should be // present if that type has a nested message definition. required Type type = 2; - optional Request request = 3; - optional Decline decline = 4; - optional Launch launch = 5; + optional Subscribe subscribe = 3; + optional Accept accept = 4; + optional Decline decline = 5; optional Kill kill = 6; - optional Acknowledge acknowledge = 7; - optional Reconcile reconcile = 8; - optional Message message = 9; + optional Shutdown shutdown = 7; + optional Acknowledge acknowledge = 8; + optional Reconcile reconcile = 9; + optional Message message = 10; } diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/state.pb.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/state.pb.go index b584062be002..db42a71b36fe 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/state.pb.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/state.pb.go @@ -5,30 +5,24 @@ package mesosproto import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" import math "math" -// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb" +// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto" -import io2 "io" -import fmt8 "fmt" -import github_com_gogo_protobuf_proto4 "github.com/gogo/protobuf/proto" +import bytes "bytes" -import fmt9 "fmt" -import strings4 "strings" -import reflect4 "reflect" +import strings "strings" +import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" +import sort "sort" +import strconv "strconv" +import reflect "reflect" -import fmt10 "fmt" -import strings5 "strings" -import github_com_gogo_protobuf_proto5 "github.com/gogo/protobuf/proto" -import sort2 "sort" -import strconv2 "strconv" -import reflect5 "reflect" - -import fmt11 "fmt" -import bytes2 "bytes" +import io "io" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = fmt.Errorf var _ = math.Inf type Operation_Type int32 @@ -192,795 +186,508 @@ func (m *Operation_Expunge) GetName() string { func init() { proto.RegisterEnum("mesosproto.Operation_Type", Operation_Type_name, Operation_Type_value) } -func (m *Entry) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt8.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io2.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Name = &s - index = postIndex - case 2: - if wireType != 2 { - return fmt8.Errorf("proto: wrong wireType = %d for field Uuid", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + byteLen - if postIndex > l { - return io2.ErrUnexpectedEOF - } - m.Uuid = append([]byte{}, data[index:postIndex]...) - index = postIndex - case 3: - if wireType != 2 { - return fmt8.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + byteLen - if postIndex > l { - return io2.ErrUnexpectedEOF - } - m.Value = append([]byte{}, data[index:postIndex]...) - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto4.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io2.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy +func (this *Entry) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } + return fmt.Errorf("that == nil && this != nil") } - return nil -} -func (m *Operation) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } + + that1, ok := that.(*Entry) + if !ok { + return fmt.Errorf("that is not of type *Entry") + } + if that1 == nil { + if this == nil { + return nil } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 0 { - return fmt8.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var v Operation_Type - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - v |= (Operation_Type(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Type = &v - case 2: - if wireType != 2 { - return fmt8.Errorf("proto: wrong wireType = %d for field Snapshot", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io2.ErrUnexpectedEOF - } - if m.Snapshot == nil { - m.Snapshot = &Operation_Snapshot{} - } - if err := m.Snapshot.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 4: - if wireType != 2 { - return fmt8.Errorf("proto: wrong wireType = %d for field Diff", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io2.ErrUnexpectedEOF - } - if m.Diff == nil { - m.Diff = &Operation_Diff{} - } - if err := m.Diff.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - case 3: - if wireType != 2 { - return fmt8.Errorf("proto: wrong wireType = %d for field Expunge", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io2.ErrUnexpectedEOF - } - if m.Expunge == nil { - m.Expunge = &Operation_Expunge{} - } - if err := m.Expunge.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto4.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io2.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return fmt.Errorf("that is type *Entry but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Entrybut is not nil && this == nil") + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) } + } else if this.Name != nil { + return fmt.Errorf("this.Name == nil && that.Name != nil") + } else if that1.Name != nil { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + } + if !bytes.Equal(this.Uuid, that1.Uuid) { + return fmt.Errorf("Uuid this(%v) Not Equal that(%v)", this.Uuid, that1.Uuid) + } + if !bytes.Equal(this.Value, that1.Value) { + return fmt.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } return nil } -func (m *Operation_Snapshot) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } +func (this *Entry) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt8.Errorf("proto: wrong wireType = %d for field Entry", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io2.ErrUnexpectedEOF - } - if m.Entry == nil { - m.Entry = &Entry{} - } - if err := m.Entry.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto4.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io2.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + return false + } + + that1, ok := that.(*Entry) + if !ok { + return false + } + if that1 == nil { + if this == nil { + return true } + return false + } else if this == nil { + return false } - return nil -} -func (m *Operation_Diff) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt8.Errorf("proto: wrong wireType = %d for field Entry", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + msglen - if postIndex > l { - return io2.ErrUnexpectedEOF - } - if m.Entry == nil { - m.Entry = &Entry{} - } - if err := m.Entry.Unmarshal(data[index:postIndex]); err != nil { - return err - } - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto4.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io2.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return false } + } else if this.Name != nil { + return false + } else if that1.Name != nil { + return false } - return nil -} -func (m *Operation_Expunge) Unmarshal(data []byte) error { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - switch fieldNum { - case 1: - if wireType != 2 { - return fmt8.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return io2.ErrUnexpectedEOF - } - b := data[index] - index++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - postIndex := index + int(stringLen) - if postIndex > l { - return io2.ErrUnexpectedEOF - } - s := string(data[index:postIndex]) - m.Name = &s - index = postIndex - default: - var sizeOfWire int - for { - sizeOfWire++ - wire >>= 7 - if wire == 0 { - break - } - } - index -= sizeOfWire - skippy, err := github_com_gogo_protobuf_proto4.Skip(data[index:]) - if err != nil { - return err - } - if (index + skippy) > l { - return io2.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) - index += skippy - } + if !bytes.Equal(this.Uuid, that1.Uuid) { + return false } - return nil -} -func (this *Entry) String() string { - if this == nil { - return "nil" + if !bytes.Equal(this.Value, that1.Value) { + return false } - s := strings4.Join([]string{`&Entry{`, - `Name:` + valueToStringState(this.Name) + `,`, - `Uuid:` + valueToStringState(this.Uuid) + `,`, - `Value:` + valueToStringState(this.Value) + `,`, - `XXX_unrecognized:` + fmt9.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Operation) String() string { - if this == nil { - return "nil" + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false } - s := strings4.Join([]string{`&Operation{`, - `Type:` + valueToStringState(this.Type) + `,`, - `Snapshot:` + strings4.Replace(fmt9.Sprintf("%v", this.Snapshot), "Operation_Snapshot", "Operation_Snapshot", 1) + `,`, - `Diff:` + strings4.Replace(fmt9.Sprintf("%v", this.Diff), "Operation_Diff", "Operation_Diff", 1) + `,`, - `Expunge:` + strings4.Replace(fmt9.Sprintf("%v", this.Expunge), "Operation_Expunge", "Operation_Expunge", 1) + `,`, - `XXX_unrecognized:` + fmt9.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s + return true } -func (this *Operation_Snapshot) String() string { - if this == nil { - return "nil" +func (this *Operation) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") } - s := strings4.Join([]string{`&Operation_Snapshot{`, - `Entry:` + strings4.Replace(fmt9.Sprintf("%v", this.Entry), "Entry", "Entry", 1) + `,`, - `XXX_unrecognized:` + fmt9.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Operation_Diff) String() string { - if this == nil { - return "nil" + + that1, ok := that.(*Operation) + if !ok { + return fmt.Errorf("that is not of type *Operation") } - s := strings4.Join([]string{`&Operation_Diff{`, - `Entry:` + strings4.Replace(fmt9.Sprintf("%v", this.Entry), "Entry", "Entry", 1) + `,`, - `XXX_unrecognized:` + fmt9.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *Operation_Expunge) String() string { - if this == nil { - return "nil" + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Operation but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Operationbut is not nil && this == nil") } - s := strings4.Join([]string{`&Operation_Expunge{`, - `Name:` + valueToStringState(this.Name) + `,`, - `XXX_unrecognized:` + fmt9.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func valueToStringState(v interface{}) string { - rv := reflect4.ValueOf(v) - if rv.IsNil() { - return "nil" + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) + } + } else if this.Type != nil { + return fmt.Errorf("this.Type == nil && that.Type != nil") + } else if that1.Type != nil { + return fmt.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) } - pv := reflect4.Indirect(rv).Interface() - return fmt9.Sprintf("*%v", pv) -} -func (m *Entry) Size() (n int) { - var l int - _ = l - if m.Name != nil { - l = len(*m.Name) - n += 1 + l + sovState(uint64(l)) + if !this.Snapshot.Equal(that1.Snapshot) { + return fmt.Errorf("Snapshot this(%v) Not Equal that(%v)", this.Snapshot, that1.Snapshot) } - if m.Uuid != nil { - l = len(m.Uuid) - n += 1 + l + sovState(uint64(l)) + if !this.Diff.Equal(that1.Diff) { + return fmt.Errorf("Diff this(%v) Not Equal that(%v)", this.Diff, that1.Diff) } - if m.Value != nil { - l = len(m.Value) - n += 1 + l + sovState(uint64(l)) + if !this.Expunge.Equal(that1.Expunge) { + return fmt.Errorf("Expunge this(%v) Not Equal that(%v)", this.Expunge, that1.Expunge) } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } - return n + return nil } +func (this *Operation) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false + } -func (m *Operation) Size() (n int) { - var l int - _ = l - if m.Type != nil { - n += 1 + sovState(uint64(*m.Type)) + that1, ok := that.(*Operation) + if !ok { + return false } - if m.Snapshot != nil { - l = m.Snapshot.Size() - n += 1 + l + sovState(uint64(l)) + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false } - if m.Diff != nil { - l = m.Diff.Size() - n += 1 + l + sovState(uint64(l)) + if this.Type != nil && that1.Type != nil { + if *this.Type != *that1.Type { + return false + } + } else if this.Type != nil { + return false + } else if that1.Type != nil { + return false } - if m.Expunge != nil { - l = m.Expunge.Size() - n += 1 + l + sovState(uint64(l)) + if !this.Snapshot.Equal(that1.Snapshot) { + return false } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if !this.Diff.Equal(that1.Diff) { + return false } - return n -} - -func (m *Operation_Snapshot) Size() (n int) { - var l int - _ = l - if m.Entry != nil { - l = m.Entry.Size() - n += 1 + l + sovState(uint64(l)) + if !this.Expunge.Equal(that1.Expunge) { + return false } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false } - return n + return true } +func (this *Operation_Snapshot) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } -func (m *Operation_Diff) Size() (n int) { - var l int - _ = l - if m.Entry != nil { - l = m.Entry.Size() - n += 1 + l + sovState(uint64(l)) + that1, ok := that.(*Operation_Snapshot) + if !ok { + return fmt.Errorf("that is not of type *Operation_Snapshot") } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Operation_Snapshot but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Operation_Snapshotbut is not nil && this == nil") } - return n + if !this.Entry.Equal(that1.Entry) { + return fmt.Errorf("Entry this(%v) Not Equal that(%v)", this.Entry, that1.Entry) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil } - -func (m *Operation_Expunge) Size() (n int) { - var l int - _ = l - if m.Name != nil { - l = len(*m.Name) - n += 1 + l + sovState(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) +func (this *Operation_Snapshot) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false } - return n -} -func sovState(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } + that1, ok := that.(*Operation_Snapshot) + if !ok { + return false } - return n -} -func sozState(x uint64) (n int) { - return sovState(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func NewPopulatedEntry(r randyState, easy bool) *Entry { - this := &Entry{} - v1 := randStringState(r) - this.Name = &v1 - v2 := r.Intn(100) - this.Uuid = make([]byte, v2) - for i := 0; i < v2; i++ { - this.Uuid[i] = byte(r.Intn(256)) + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false } - v3 := r.Intn(100) - this.Value = make([]byte, v3) - for i := 0; i < v3; i++ { - this.Value[i] = byte(r.Intn(256)) + if !this.Entry.Equal(that1.Entry) { + return false } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedState(r, 4) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false } - return this + return true } +func (this *Operation_Diff) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } -func NewPopulatedOperation(r randyState, easy bool) *Operation { - this := &Operation{} - v4 := Operation_Type([]int32{1, 3, 2}[r.Intn(3)]) - this.Type = &v4 - if r.Intn(10) != 0 { - this.Snapshot = NewPopulatedOperation_Snapshot(r, easy) + that1, ok := that.(*Operation_Diff) + if !ok { + return fmt.Errorf("that is not of type *Operation_Diff") } - if r.Intn(10) != 0 { - this.Diff = NewPopulatedOperation_Diff(r, easy) + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *Operation_Diff but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Operation_Diffbut is not nil && this == nil") } - if r.Intn(10) != 0 { - this.Expunge = NewPopulatedOperation_Expunge(r, easy) + if !this.Entry.Equal(that1.Entry) { + return fmt.Errorf("Entry this(%v) Not Equal that(%v)", this.Entry, that1.Entry) } - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedState(r, 5) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } - return this + return nil } - -func NewPopulatedOperation_Snapshot(r randyState, easy bool) *Operation_Snapshot { - this := &Operation_Snapshot{} - this.Entry = NewPopulatedEntry(r, easy) - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedState(r, 2) +func (this *Operation_Diff) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false } - return this -} -func NewPopulatedOperation_Diff(r randyState, easy bool) *Operation_Diff { - this := &Operation_Diff{} - this.Entry = NewPopulatedEntry(r, easy) - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedState(r, 2) + that1, ok := that.(*Operation_Diff) + if !ok { + return false } - return this -} - -func NewPopulatedOperation_Expunge(r randyState, easy bool) *Operation_Expunge { - this := &Operation_Expunge{} - v5 := randStringState(r) - this.Name = &v5 - if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedState(r, 2) + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false } - return this -} - -type randyState interface { - Float32() float32 - Float64() float64 - Int63() int64 - Int31() int32 - Uint32() uint32 - Intn(n int) int -} - -func randUTF8RuneState(r randyState) rune { - res := rune(r.Uint32() % 1112064) - if 55296 <= res { - res += 2047 + if !this.Entry.Equal(that1.Entry) { + return false } - return res -} -func randStringState(r randyState) string { - v6 := r.Intn(100) - tmps := make([]rune, v6) - for i := 0; i < v6; i++ { - tmps[i] = randUTF8RuneState(r) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false } - return string(tmps) + return true } -func randUnrecognizedState(r randyState, maxFieldNumber int) (data []byte) { - l := r.Intn(5) - for i := 0; i < l; i++ { - wire := r.Intn(4) - if wire == 3 { - wire = 5 +func (this *Operation_Expunge) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil } - fieldNumber := maxFieldNumber + r.Intn(100) - data = randFieldState(data, r, fieldNumber, wire) + return fmt.Errorf("that == nil && this != nil") } - return data -} -func randFieldState(data []byte, r randyState, fieldNumber int, wire int) []byte { - key := uint32(fieldNumber)<<3 | uint32(wire) - switch wire { - case 0: - data = encodeVarintPopulateState(data, uint64(key)) - v7 := r.Int63() - if r.Intn(2) == 0 { - v7 *= -1 + + that1, ok := that.(*Operation_Expunge) + if !ok { + return fmt.Errorf("that is not of type *Operation_Expunge") + } + if that1 == nil { + if this == nil { + return nil } - data = encodeVarintPopulateState(data, uint64(v7)) - case 1: - data = encodeVarintPopulateState(data, uint64(key)) - data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) - case 2: - data = encodeVarintPopulateState(data, uint64(key)) - ll := r.Intn(100) - data = encodeVarintPopulateState(data, uint64(ll)) - for j := 0; j < ll; j++ { - data = append(data, byte(r.Intn(256))) + return fmt.Errorf("that is type *Operation_Expunge but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *Operation_Expungebut is not nil && this == nil") + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) } - default: - data = encodeVarintPopulateState(data, uint64(key)) - data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) + } else if this.Name != nil { + return fmt.Errorf("this.Name == nil && that.Name != nil") + } else if that1.Name != nil { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) } - return data -} -func encodeVarintPopulateState(data []byte, v uint64) []byte { - for v >= 1<<7 { - data = append(data, uint8(uint64(v)&0x7f|0x80)) - v >>= 7 + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) } - data = append(data, uint8(v)) - return data + return nil } -func (m *Entry) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err +func (this *Operation_Expunge) Equal(that interface{}) bool { + if that == nil { + if this == nil { + return true + } + return false } - return data[:n], nil -} -func (m *Entry) MarshalTo(data []byte) (n int, err error) { - var i int - _ = i - var l int - _ = l - if m.Name != nil { - data[i] = 0xa - i++ - i = encodeVarintState(data, i, uint64(len(*m.Name))) - i += copy(data[i:], *m.Name) + that1, ok := that.(*Operation_Expunge) + if !ok { + return false } - if m.Uuid != nil { - data[i] = 0x12 - i++ - i = encodeVarintState(data, i, uint64(len(m.Uuid))) - i += copy(data[i:], m.Uuid) + if that1 == nil { + if this == nil { + return true + } + return false + } else if this == nil { + return false } - if m.Value != nil { - data[i] = 0x1a - i++ - i = encodeVarintState(data, i, uint64(len(m.Value))) - i += copy(data[i:], m.Value) + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return false + } + } else if this.Name != nil { + return false + } else if that1.Name != nil { + return false } - if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *Entry) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&mesosproto.Entry{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringState(this.Name, "string")+",\n") + } + if this.Uuid != nil { + s = append(s, "Uuid: "+valueToGoStringState(this.Uuid, "byte")+",\n") + } + if this.Value != nil { + s = append(s, "Value: "+valueToGoStringState(this.Value, "byte")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Operation) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 8) + s = append(s, "&mesosproto.Operation{") + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringState(this.Type, "mesosproto.Operation_Type")+",\n") + } + if this.Snapshot != nil { + s = append(s, "Snapshot: "+fmt.Sprintf("%#v", this.Snapshot)+",\n") + } + if this.Diff != nil { + s = append(s, "Diff: "+fmt.Sprintf("%#v", this.Diff)+",\n") + } + if this.Expunge != nil { + s = append(s, "Expunge: "+fmt.Sprintf("%#v", this.Expunge)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Operation_Snapshot) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Operation_Snapshot{") + if this.Entry != nil { + s = append(s, "Entry: "+fmt.Sprintf("%#v", this.Entry)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Operation_Diff) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Operation_Diff{") + if this.Entry != nil { + s = append(s, "Entry: "+fmt.Sprintf("%#v", this.Entry)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Operation_Expunge) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&mesosproto.Operation_Expunge{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringState(this.Name, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func valueToGoStringState(v interface{}, typ string) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) +} +func extensionToGoStringState(e map[int32]github_com_gogo_protobuf_proto.Extension) string { + if e == nil { + return "nil" + } + s := "map[int32]proto.Extension{" + keys := make([]int, 0, len(e)) + for k := range e { + keys = append(keys, int(k)) + } + sort.Ints(keys) + ss := []string{} + for _, k := range keys { + ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString()) + } + s += strings.Join(ss, ",") + "}" + return s +} +func (m *Entry) 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 *Entry) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Name == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } else { + data[i] = 0xa + i++ + i = encodeVarintState(data, i, uint64(len(*m.Name))) + i += copy(data[i:], *m.Name) + } + if m.Uuid == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("uuid") + } else { + data[i] = 0x12 + i++ + i = encodeVarintState(data, i, uint64(len(m.Uuid))) + i += copy(data[i:], m.Uuid) + } + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + data[i] = 0x1a + i++ + i = encodeVarintState(data, i, uint64(len(m.Value))) + i += copy(data[i:], m.Value) + } + if m.XXX_unrecognized != nil { + i += copy(data[i:], m.XXX_unrecognized) } return i, nil } @@ -995,12 +702,14 @@ func (m *Operation) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Operation) MarshalTo(data []byte) (n int, err error) { +func (m *Operation) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Type != nil { + if m.Type == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } else { data[i] = 0x8 i++ i = encodeVarintState(data, i, uint64(*m.Type)) @@ -1015,21 +724,21 @@ func (m *Operation) MarshalTo(data []byte) (n int, err error) { } i += n1 } - if m.Diff != nil { - data[i] = 0x22 + if m.Expunge != nil { + data[i] = 0x1a i++ - i = encodeVarintState(data, i, uint64(m.Diff.Size())) - n2, err := m.Diff.MarshalTo(data[i:]) + i = encodeVarintState(data, i, uint64(m.Expunge.Size())) + n2, err := m.Expunge.MarshalTo(data[i:]) if err != nil { return 0, err } i += n2 } - if m.Expunge != nil { - data[i] = 0x1a + if m.Diff != nil { + data[i] = 0x22 i++ - i = encodeVarintState(data, i, uint64(m.Expunge.Size())) - n3, err := m.Expunge.MarshalTo(data[i:]) + i = encodeVarintState(data, i, uint64(m.Diff.Size())) + n3, err := m.Diff.MarshalTo(data[i:]) if err != nil { return 0, err } @@ -1051,12 +760,14 @@ func (m *Operation_Snapshot) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Operation_Snapshot) MarshalTo(data []byte) (n int, err error) { +func (m *Operation_Snapshot) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Entry != nil { + if m.Entry == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("entry") + } else { data[i] = 0xa i++ i = encodeVarintState(data, i, uint64(m.Entry.Size())) @@ -1082,12 +793,14 @@ func (m *Operation_Diff) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Operation_Diff) MarshalTo(data []byte) (n int, err error) { +func (m *Operation_Diff) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Entry != nil { + if m.Entry == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("entry") + } else { data[i] = 0xa i++ i = encodeVarintState(data, i, uint64(m.Entry.Size())) @@ -1113,12 +826,14 @@ func (m *Operation_Expunge) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *Operation_Expunge) MarshalTo(data []byte) (n int, err error) { +func (m *Operation_Expunge) MarshalTo(data []byte) (int, error) { var i int _ = i var l int _ = l - if m.Name != nil { + if m.Name == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } else { data[i] = 0xa i++ i = encodeVarintState(data, i, uint64(len(*m.Name))) @@ -1157,424 +872,932 @@ func encodeVarintState(data []byte, offset int, v uint64) int { data[offset] = uint8(v) return offset + 1 } -func (this *Entry) GoString() string { - if this == nil { - return "nil" - } - s := strings5.Join([]string{`&mesosproto.Entry{` + - `Name:` + valueToGoStringState(this.Name, "string"), - `Uuid:` + valueToGoStringState(this.Uuid, "byte"), - `Value:` + valueToGoStringState(this.Value, "byte"), - `XXX_unrecognized:` + fmt10.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Operation) GoString() string { - if this == nil { - return "nil" - } - s := strings5.Join([]string{`&mesosproto.Operation{` + - `Type:` + valueToGoStringState(this.Type, "mesosproto.Operation_Type"), - `Snapshot:` + fmt10.Sprintf("%#v", this.Snapshot), - `Diff:` + fmt10.Sprintf("%#v", this.Diff), - `Expunge:` + fmt10.Sprintf("%#v", this.Expunge), - `XXX_unrecognized:` + fmt10.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Operation_Snapshot) GoString() string { - if this == nil { - return "nil" +func NewPopulatedEntry(r randyState, easy bool) *Entry { + this := &Entry{} + v1 := randStringState(r) + this.Name = &v1 + v2 := r.Intn(100) + this.Uuid = make([]byte, v2) + for i := 0; i < v2; i++ { + this.Uuid[i] = byte(r.Intn(256)) } - s := strings5.Join([]string{`&mesosproto.Operation_Snapshot{` + - `Entry:` + fmt10.Sprintf("%#v", this.Entry), - `XXX_unrecognized:` + fmt10.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Operation_Diff) GoString() string { - if this == nil { - return "nil" + v3 := r.Intn(100) + this.Value = make([]byte, v3) + for i := 0; i < v3; i++ { + this.Value[i] = byte(r.Intn(256)) } - s := strings5.Join([]string{`&mesosproto.Operation_Diff{` + - `Entry:` + fmt10.Sprintf("%#v", this.Entry), - `XXX_unrecognized:` + fmt10.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s -} -func (this *Operation_Expunge) GoString() string { - if this == nil { - return "nil" + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedState(r, 4) } - s := strings5.Join([]string{`&mesosproto.Operation_Expunge{` + - `Name:` + valueToGoStringState(this.Name, "string"), - `XXX_unrecognized:` + fmt10.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ") - return s + return this } -func valueToGoStringState(v interface{}, typ string) string { - rv := reflect5.ValueOf(v) - if rv.IsNil() { - return "nil" + +func NewPopulatedOperation(r randyState, easy bool) *Operation { + this := &Operation{} + v4 := Operation_Type([]int32{1, 3, 2}[r.Intn(3)]) + this.Type = &v4 + if r.Intn(10) != 0 { + this.Snapshot = NewPopulatedOperation_Snapshot(r, easy) } - pv := reflect5.Indirect(rv).Interface() - return fmt10.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) -} -func extensionToGoStringState(e map[int32]github_com_gogo_protobuf_proto5.Extension) string { - if e == nil { - return "nil" + if r.Intn(10) != 0 { + this.Expunge = NewPopulatedOperation_Expunge(r, easy) } - s := "map[int32]proto.Extension{" - keys := make([]int, 0, len(e)) - for k := range e { - keys = append(keys, int(k)) + if r.Intn(10) != 0 { + this.Diff = NewPopulatedOperation_Diff(r, easy) } - sort2.Ints(keys) - ss := []string{} - for _, k := range keys { - ss = append(ss, strconv2.Itoa(k)+": "+e[int32(k)].GoString()) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedState(r, 5) } - s += strings5.Join(ss, ",") + "}" - return s + return this } -func (this *Entry) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt11.Errorf("that == nil && this != nil") - } - that1, ok := that.(*Entry) - if !ok { - return fmt11.Errorf("that is not of type *Entry") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt11.Errorf("that is type *Entry but is nil && this != nil") - } else if this == nil { - return fmt11.Errorf("that is type *Entrybut is not nil && this == nil") +func NewPopulatedOperation_Snapshot(r randyState, easy bool) *Operation_Snapshot { + this := &Operation_Snapshot{} + this.Entry = NewPopulatedEntry(r, easy) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedState(r, 2) } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return fmt11.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) - } - } else if this.Name != nil { - return fmt11.Errorf("this.Name == nil && that.Name != nil") - } else if that1.Name != nil { - return fmt11.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + return this +} + +func NewPopulatedOperation_Diff(r randyState, easy bool) *Operation_Diff { + this := &Operation_Diff{} + this.Entry = NewPopulatedEntry(r, easy) + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedState(r, 2) } - if !bytes2.Equal(this.Uuid, that1.Uuid) { - return fmt11.Errorf("Uuid this(%v) Not Equal that(%v)", this.Uuid, that1.Uuid) + return this +} + +func NewPopulatedOperation_Expunge(r randyState, easy bool) *Operation_Expunge { + this := &Operation_Expunge{} + v5 := randStringState(r) + this.Name = &v5 + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedState(r, 2) } - if !bytes2.Equal(this.Value, that1.Value) { - return fmt11.Errorf("Value this(%v) Not Equal that(%v)", this.Value, that1.Value) + return this +} + +type randyState interface { + Float32() float32 + Float64() float64 + Int63() int64 + Int31() int32 + Uint32() uint32 + Intn(n int) int +} + +func randUTF8RuneState(r randyState) rune { + ru := r.Intn(62) + if ru < 10 { + return rune(ru + 48) + } else if ru < 36 { + return rune(ru + 55) } - if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt11.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + return rune(ru + 61) +} +func randStringState(r randyState) string { + v6 := r.Intn(100) + tmps := make([]rune, v6) + for i := 0; i < v6; i++ { + tmps[i] = randUTF8RuneState(r) } - return nil + return string(tmps) } -func (this *Entry) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func randUnrecognizedState(r randyState, maxFieldNumber int) (data []byte) { + l := r.Intn(5) + for i := 0; i < l; i++ { + wire := r.Intn(4) + if wire == 3 { + wire = 5 } - return false + fieldNumber := maxFieldNumber + r.Intn(100) + data = randFieldState(data, r, fieldNumber, wire) } - - that1, ok := that.(*Entry) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return false - } - } else if this.Name != nil { - return false - } else if that1.Name != nil { - return false - } - if !bytes2.Equal(this.Uuid, that1.Uuid) { - return false - } - if !bytes2.Equal(this.Value, that1.Value) { - return false - } - if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false - } - return true + return data } -func (this *Operation) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func randFieldState(data []byte, r randyState, fieldNumber int, wire int) []byte { + key := uint32(fieldNumber)<<3 | uint32(wire) + switch wire { + case 0: + data = encodeVarintPopulateState(data, uint64(key)) + v7 := r.Int63() + if r.Intn(2) == 0 { + v7 *= -1 } - return fmt11.Errorf("that == nil && this != nil") - } - - that1, ok := that.(*Operation) - if !ok { - return fmt11.Errorf("that is not of type *Operation") - } - if that1 == nil { - if this == nil { - return nil + data = encodeVarintPopulateState(data, uint64(v7)) + case 1: + data = encodeVarintPopulateState(data, uint64(key)) + data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) + case 2: + data = encodeVarintPopulateState(data, uint64(key)) + ll := r.Intn(100) + data = encodeVarintPopulateState(data, uint64(ll)) + for j := 0; j < ll; j++ { + data = append(data, byte(r.Intn(256))) } - return fmt11.Errorf("that is type *Operation but is nil && this != nil") - } else if this == nil { - return fmt11.Errorf("that is type *Operationbut is not nil && this == nil") + default: + data = encodeVarintPopulateState(data, uint64(key)) + data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return fmt11.Errorf("Type this(%v) Not Equal that(%v)", *this.Type, *that1.Type) - } - } else if this.Type != nil { - return fmt11.Errorf("this.Type == nil && that.Type != nil") - } else if that1.Type != nil { - return fmt11.Errorf("Type this(%v) Not Equal that(%v)", this.Type, that1.Type) + return data +} +func encodeVarintPopulateState(data []byte, v uint64) []byte { + for v >= 1<<7 { + data = append(data, uint8(uint64(v)&0x7f|0x80)) + v >>= 7 } - if !this.Snapshot.Equal(that1.Snapshot) { - return fmt11.Errorf("Snapshot this(%v) Not Equal that(%v)", this.Snapshot, that1.Snapshot) + data = append(data, uint8(v)) + return data +} +func (m *Entry) Size() (n int) { + var l int + _ = l + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovState(uint64(l)) } - if !this.Diff.Equal(that1.Diff) { - return fmt11.Errorf("Diff this(%v) Not Equal that(%v)", this.Diff, that1.Diff) + if m.Uuid != nil { + l = len(m.Uuid) + n += 1 + l + sovState(uint64(l)) } - if !this.Expunge.Equal(that1.Expunge) { - return fmt11.Errorf("Expunge this(%v) Not Equal that(%v)", this.Expunge, that1.Expunge) + if m.Value != nil { + l = len(m.Value) + n += 1 + l + sovState(uint64(l)) } - if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt11.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *Operation) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - that1, ok := that.(*Operation) - if !ok { - return false - } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false - } - if this.Type != nil && that1.Type != nil { - if *this.Type != *that1.Type { - return false - } - } else if this.Type != nil { - return false - } else if that1.Type != nil { - return false +func (m *Operation) Size() (n int) { + var l int + _ = l + if m.Type != nil { + n += 1 + sovState(uint64(*m.Type)) } - if !this.Snapshot.Equal(that1.Snapshot) { - return false + if m.Snapshot != nil { + l = m.Snapshot.Size() + n += 1 + l + sovState(uint64(l)) } - if !this.Diff.Equal(that1.Diff) { - return false + if m.Expunge != nil { + l = m.Expunge.Size() + n += 1 + l + sovState(uint64(l)) } - if !this.Expunge.Equal(that1.Expunge) { - return false + if m.Diff != nil { + l = m.Diff.Size() + n += 1 + l + sovState(uint64(l)) } - if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *Operation_Snapshot) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt11.Errorf("that == nil && this != nil") - } - that1, ok := that.(*Operation_Snapshot) - if !ok { - return fmt11.Errorf("that is not of type *Operation_Snapshot") - } - if that1 == nil { - if this == nil { - return nil - } - return fmt11.Errorf("that is type *Operation_Snapshot but is nil && this != nil") - } else if this == nil { - return fmt11.Errorf("that is type *Operation_Snapshotbut is not nil && this == nil") - } - if !this.Entry.Equal(that1.Entry) { - return fmt11.Errorf("Entry this(%v) Not Equal that(%v)", this.Entry, that1.Entry) +func (m *Operation_Snapshot) Size() (n int) { + var l int + _ = l + if m.Entry != nil { + l = m.Entry.Size() + n += 1 + l + sovState(uint64(l)) } - if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt11.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return nil + return n } -func (this *Operation_Snapshot) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false - } - that1, ok := that.(*Operation_Snapshot) - if !ok { - return false +func (m *Operation_Diff) Size() (n int) { + var l int + _ = l + if m.Entry != nil { + l = m.Entry.Size() + n += 1 + l + sovState(uint64(l)) } - if that1 == nil { - if this == nil { - return true - } - return false - } else if this == nil { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - if !this.Entry.Equal(that1.Entry) { - return false + return n +} + +func (m *Operation_Expunge) Size() (n int) { + var l int + _ = l + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovState(uint64(l)) } - if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) } - return true + return n } -func (this *Operation_Diff) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil - } - return fmt11.Errorf("that == nil && this != nil") - } - that1, ok := that.(*Operation_Diff) - if !ok { - return fmt11.Errorf("that is not of type *Operation_Diff") - } - if that1 == nil { - if this == nil { - return nil +func sovState(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break } - return fmt11.Errorf("that is type *Operation_Diff but is nil && this != nil") - } else if this == nil { - return fmt11.Errorf("that is type *Operation_Diffbut is not nil && this == nil") } - if !this.Entry.Equal(that1.Entry) { - return fmt11.Errorf("Entry this(%v) Not Equal that(%v)", this.Entry, that1.Entry) + return n +} +func sozState(x uint64) (n int) { + return sovState(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *Entry) String() string { + if this == nil { + return "nil" } - if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt11.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + s := strings.Join([]string{`&Entry{`, + `Name:` + valueToStringState(this.Name) + `,`, + `Uuid:` + valueToStringState(this.Uuid) + `,`, + `Value:` + valueToStringState(this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Operation) String() string { + if this == nil { + return "nil" } - return nil + s := strings.Join([]string{`&Operation{`, + `Type:` + valueToStringState(this.Type) + `,`, + `Snapshot:` + strings.Replace(fmt.Sprintf("%v", this.Snapshot), "Operation_Snapshot", "Operation_Snapshot", 1) + `,`, + `Expunge:` + strings.Replace(fmt.Sprintf("%v", this.Expunge), "Operation_Expunge", "Operation_Expunge", 1) + `,`, + `Diff:` + strings.Replace(fmt.Sprintf("%v", this.Diff), "Operation_Diff", "Operation_Diff", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s } -func (this *Operation_Diff) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true - } - return false +func (this *Operation_Snapshot) String() string { + if this == nil { + return "nil" } - - that1, ok := that.(*Operation_Diff) - if !ok { - return false + s := strings.Join([]string{`&Operation_Snapshot{`, + `Entry:` + strings.Replace(fmt.Sprintf("%v", this.Entry), "Entry", "Entry", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Operation_Diff) String() string { + if this == nil { + return "nil" } - if that1 == nil { - if this == nil { - return true + s := strings.Join([]string{`&Operation_Diff{`, + `Entry:` + strings.Replace(fmt.Sprintf("%v", this.Entry), "Entry", "Entry", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Operation_Expunge) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Operation_Expunge{`, + `Name:` + valueToStringState(this.Name) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func valueToStringState(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *Entry) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthState + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Uuid", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Uuid = append([]byte{}, data[iNdEx:postIndex]...) + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = append([]byte{}, data[iNdEx:postIndex]...) + iNdEx = postIndex + hasFields[0] |= uint64(0x00000004) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipState(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthState + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false - } else if this == nil { - return false } - if !this.Entry.Equal(that1.Entry) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") } - if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("uuid") } - return true + if hasFields[0]&uint64(0x00000004) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } + + return nil } -func (this *Operation_Expunge) VerboseEqual(that interface{}) error { - if that == nil { - if this == nil { - return nil +func (m *Operation) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v Operation_Type + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (Operation_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Snapshot", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Snapshot == nil { + m.Snapshot = &Operation_Snapshot{} + } + if err := m.Snapshot.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Expunge", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Expunge == nil { + m.Expunge = &Operation_Expunge{} + } + if err := m.Expunge.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Diff", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Diff == nil { + m.Diff = &Operation_Diff{} + } + if err := m.Diff.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipState(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthState + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return fmt11.Errorf("that == nil && this != nil") } - - that1, ok := that.(*Operation_Expunge) - if !ok { - return fmt11.Errorf("that is not of type *Operation_Expunge") + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") } - if that1 == nil { - if this == nil { - return nil + + return nil +} +func (m *Operation_Snapshot) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return fmt11.Errorf("that is type *Operation_Expunge but is nil && this != nil") - } else if this == nil { - return fmt11.Errorf("that is type *Operation_Expungebut is not nil && this == nil") - } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return fmt11.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entry", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Entry == nil { + m.Entry = &Entry{} + } + if err := m.Entry.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipState(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthState + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Name != nil { - return fmt11.Errorf("this.Name == nil && that.Name != nil") - } else if that1.Name != nil { - return fmt11.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) } - if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return fmt11.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("entry") } + return nil } -func (this *Operation_Expunge) Equal(that interface{}) bool { - if that == nil { - if this == nil { - return true +func (m *Operation_Diff) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + 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) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entry", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Entry == nil { + m.Entry = &Entry{} + } + if err := m.Entry.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipState(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthState + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - return false } - - that1, ok := that.(*Operation_Expunge) - if !ok { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("entry") } - if that1 == nil { - if this == nil { - return true + + return nil +} +func (m *Operation_Expunge) Unmarshal(data []byte) error { + var hasFields [1]uint64 + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } } - return false - } else if this == nil { - return false - } - if this.Name != nil && that1.Name != nil { - if *this.Name != *that1.Name { - return false + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + 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 ErrInvalidLengthState + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + var sizeOfWire int + for { + sizeOfWire++ + wire >>= 7 + if wire == 0 { + break + } + } + iNdEx -= sizeOfWire + skippy, err := skipState(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthState + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + iNdEx += skippy } - } else if this.Name != nil { - return false - } else if that1.Name != nil { - return false } - if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { - return false + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") } - return true + + return nil +} +func skipState(data []byte) (n int, err error) { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if data[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthState + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipState(data[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") } + +var ( + ErrInvalidLengthState = fmt.Errorf("proto: negative length found during unmarshaling") +) diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/statepb_test.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/statepb_test.go index 56d626beaa51..89870c024c44 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/statepb_test.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/statepb_test.go @@ -4,60 +4,60 @@ package mesosproto -import testing14 "testing" -import math_rand14 "math/rand" -import time14 "time" -import github_com_gogo_protobuf_proto8 "github.com/gogo/protobuf/proto" -import testing15 "testing" -import math_rand15 "math/rand" -import time15 "time" -import encoding_json2 "encoding/json" -import testing16 "testing" -import math_rand16 "math/rand" -import time16 "time" -import github_com_gogo_protobuf_proto9 "github.com/gogo/protobuf/proto" -import math_rand17 "math/rand" -import time17 "time" -import testing17 "testing" -import fmt4 "fmt" -import math_rand18 "math/rand" -import time18 "time" -import testing18 "testing" -import github_com_gogo_protobuf_proto10 "github.com/gogo/protobuf/proto" -import math_rand19 "math/rand" -import time19 "time" -import testing19 "testing" -import fmt5 "fmt" -import go_parser2 "go/parser" -import math_rand20 "math/rand" -import time20 "time" -import testing20 "testing" -import github_com_gogo_protobuf_proto11 "github.com/gogo/protobuf/proto" +import testing "testing" +import math_rand "math/rand" +import time "time" +import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" +import github_com_gogo_protobuf_jsonpb "github.com/gogo/protobuf/jsonpb" +import fmt "fmt" +import go_parser "go/parser" +import proto "github.com/gogo/protobuf/proto" +import math "math" -func TestEntryProto(t *testing14.T) { - popr := math_rand14.New(math_rand14.NewSource(time14.Now().UnixNano())) +// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +func TestEntryProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedEntry(popr, false) - data, err := github_com_gogo_protobuf_proto8.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Entry{} - if err := github_com_gogo_protobuf_proto8.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestEntryMarshalTo(t *testing14.T) { - popr := math_rand14.New(math_rand14.NewSource(time14.Now().UnixNano())) +func TestEntryMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedEntry(popr, false) size := p.Size() data := make([]byte, size) @@ -66,25 +66,25 @@ func TestEntryMarshalTo(t *testing14.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Entry{} - if err := github_com_gogo_protobuf_proto8.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkEntryProtoMarshal(b *testing14.B) { - popr := math_rand14.New(math_rand14.NewSource(616)) +func BenchmarkEntryProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Entry, 10000) for i := 0; i < 10000; i++ { @@ -92,7 +92,7 @@ func BenchmarkEntryProtoMarshal(b *testing14.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto8.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -101,12 +101,12 @@ func BenchmarkEntryProtoMarshal(b *testing14.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkEntryProtoUnmarshal(b *testing14.B) { - popr := math_rand14.New(math_rand14.NewSource(616)) +func BenchmarkEntryProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto8.Marshal(NewPopulatedEntry(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedEntry(popr, false)) if err != nil { panic(err) } @@ -116,37 +116,50 @@ func BenchmarkEntryProtoUnmarshal(b *testing14.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto8.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestOperationProto(t *testing14.T) { - popr := math_rand14.New(math_rand14.NewSource(time14.Now().UnixNano())) +func TestOperationProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation(popr, false) - data, err := github_com_gogo_protobuf_proto8.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation{} - if err := github_com_gogo_protobuf_proto8.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestOperationMarshalTo(t *testing14.T) { - popr := math_rand14.New(math_rand14.NewSource(time14.Now().UnixNano())) +func TestOperationMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation(popr, false) size := p.Size() data := make([]byte, size) @@ -155,25 +168,25 @@ func TestOperationMarshalTo(t *testing14.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation{} - if err := github_com_gogo_protobuf_proto8.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkOperationProtoMarshal(b *testing14.B) { - popr := math_rand14.New(math_rand14.NewSource(616)) +func BenchmarkOperationProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Operation, 10000) for i := 0; i < 10000; i++ { @@ -181,7 +194,7 @@ func BenchmarkOperationProtoMarshal(b *testing14.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto8.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -190,12 +203,12 @@ func BenchmarkOperationProtoMarshal(b *testing14.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkOperationProtoUnmarshal(b *testing14.B) { - popr := math_rand14.New(math_rand14.NewSource(616)) +func BenchmarkOperationProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto8.Marshal(NewPopulatedOperation(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOperation(popr, false)) if err != nil { panic(err) } @@ -205,37 +218,50 @@ func BenchmarkOperationProtoUnmarshal(b *testing14.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto8.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestOperation_SnapshotProto(t *testing14.T) { - popr := math_rand14.New(math_rand14.NewSource(time14.Now().UnixNano())) +func TestOperation_SnapshotProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Snapshot(popr, false) - data, err := github_com_gogo_protobuf_proto8.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation_Snapshot{} - if err := github_com_gogo_protobuf_proto8.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestOperation_SnapshotMarshalTo(t *testing14.T) { - popr := math_rand14.New(math_rand14.NewSource(time14.Now().UnixNano())) +func TestOperation_SnapshotMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Snapshot(popr, false) size := p.Size() data := make([]byte, size) @@ -244,25 +270,25 @@ func TestOperation_SnapshotMarshalTo(t *testing14.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation_Snapshot{} - if err := github_com_gogo_protobuf_proto8.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkOperation_SnapshotProtoMarshal(b *testing14.B) { - popr := math_rand14.New(math_rand14.NewSource(616)) +func BenchmarkOperation_SnapshotProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Operation_Snapshot, 10000) for i := 0; i < 10000; i++ { @@ -270,7 +296,7 @@ func BenchmarkOperation_SnapshotProtoMarshal(b *testing14.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto8.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -279,12 +305,12 @@ func BenchmarkOperation_SnapshotProtoMarshal(b *testing14.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkOperation_SnapshotProtoUnmarshal(b *testing14.B) { - popr := math_rand14.New(math_rand14.NewSource(616)) +func BenchmarkOperation_SnapshotProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto8.Marshal(NewPopulatedOperation_Snapshot(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOperation_Snapshot(popr, false)) if err != nil { panic(err) } @@ -294,37 +320,50 @@ func BenchmarkOperation_SnapshotProtoUnmarshal(b *testing14.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto8.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestOperation_DiffProto(t *testing14.T) { - popr := math_rand14.New(math_rand14.NewSource(time14.Now().UnixNano())) +func TestOperation_DiffProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Diff(popr, false) - data, err := github_com_gogo_protobuf_proto8.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation_Diff{} - if err := github_com_gogo_protobuf_proto8.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestOperation_DiffMarshalTo(t *testing14.T) { - popr := math_rand14.New(math_rand14.NewSource(time14.Now().UnixNano())) +func TestOperation_DiffMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Diff(popr, false) size := p.Size() data := make([]byte, size) @@ -333,25 +372,25 @@ func TestOperation_DiffMarshalTo(t *testing14.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation_Diff{} - if err := github_com_gogo_protobuf_proto8.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkOperation_DiffProtoMarshal(b *testing14.B) { - popr := math_rand14.New(math_rand14.NewSource(616)) +func BenchmarkOperation_DiffProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Operation_Diff, 10000) for i := 0; i < 10000; i++ { @@ -359,7 +398,7 @@ func BenchmarkOperation_DiffProtoMarshal(b *testing14.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto8.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -368,12 +407,12 @@ func BenchmarkOperation_DiffProtoMarshal(b *testing14.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkOperation_DiffProtoUnmarshal(b *testing14.B) { - popr := math_rand14.New(math_rand14.NewSource(616)) +func BenchmarkOperation_DiffProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto8.Marshal(NewPopulatedOperation_Diff(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOperation_Diff(popr, false)) if err != nil { panic(err) } @@ -383,37 +422,50 @@ func BenchmarkOperation_DiffProtoUnmarshal(b *testing14.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto8.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestOperation_ExpungeProto(t *testing14.T) { - popr := math_rand14.New(math_rand14.NewSource(time14.Now().UnixNano())) +func TestOperation_ExpungeProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Expunge(popr, false) - data, err := github_com_gogo_protobuf_proto8.Marshal(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation_Expunge{} - if err := github_com_gogo_protobuf_proto8.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } + littlefuzz := make([]byte, len(data)) + copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } } -func TestOperation_ExpungeMarshalTo(t *testing14.T) { - popr := math_rand14.New(math_rand14.NewSource(time14.Now().UnixNano())) +func TestOperation_ExpungeMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Expunge(popr, false) size := p.Size() data := make([]byte, size) @@ -422,25 +474,25 @@ func TestOperation_ExpungeMarshalTo(t *testing14.T) { } _, err := p.MarshalTo(data) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation_Expunge{} - if err := github_com_gogo_protobuf_proto8.Unmarshal(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func BenchmarkOperation_ExpungeProtoMarshal(b *testing14.B) { - popr := math_rand14.New(math_rand14.NewSource(616)) +func BenchmarkOperation_ExpungeProtoMarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Operation_Expunge, 10000) for i := 0; i < 10000; i++ { @@ -448,7 +500,7 @@ func BenchmarkOperation_ExpungeProtoMarshal(b *testing14.B) { } b.ResetTimer() for i := 0; i < b.N; i++ { - data, err := github_com_gogo_protobuf_proto8.Marshal(pops[i%10000]) + data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } @@ -457,12 +509,12 @@ func BenchmarkOperation_ExpungeProtoMarshal(b *testing14.B) { b.SetBytes(int64(total / b.N)) } -func BenchmarkOperation_ExpungeProtoUnmarshal(b *testing14.B) { - popr := math_rand14.New(math_rand14.NewSource(616)) +func BenchmarkOperation_ExpungeProtoUnmarshal(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { - data, err := github_com_gogo_protobuf_proto8.Marshal(NewPopulatedOperation_Expunge(popr, false)) + data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedOperation_Expunge(popr, false)) if err != nil { panic(err) } @@ -472,336 +524,452 @@ func BenchmarkOperation_ExpungeProtoUnmarshal(b *testing14.B) { b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) - if err := github_com_gogo_protobuf_proto8.Unmarshal(datas[i%10000], msg); err != nil { + if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) } -func TestEntryJSON(t *testing15.T) { - popr := math_rand15.New(math_rand15.NewSource(time15.Now().UnixNano())) +func TestEntryJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedEntry(popr, true) - jsondata, err := encoding_json2.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Entry{} - err = encoding_json2.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestOperationJSON(t *testing15.T) { - popr := math_rand15.New(math_rand15.NewSource(time15.Now().UnixNano())) +func TestOperationJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation(popr, true) - jsondata, err := encoding_json2.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation{} - err = encoding_json2.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestOperation_SnapshotJSON(t *testing15.T) { - popr := math_rand15.New(math_rand15.NewSource(time15.Now().UnixNano())) +func TestOperation_SnapshotJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Snapshot(popr, true) - jsondata, err := encoding_json2.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation_Snapshot{} - err = encoding_json2.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestOperation_DiffJSON(t *testing15.T) { - popr := math_rand15.New(math_rand15.NewSource(time15.Now().UnixNano())) +func TestOperation_DiffJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Diff(popr, true) - jsondata, err := encoding_json2.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation_Diff{} - err = encoding_json2.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestOperation_ExpungeJSON(t *testing15.T) { - popr := math_rand15.New(math_rand15.NewSource(time15.Now().UnixNano())) +func TestOperation_ExpungeJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Expunge(popr, true) - jsondata, err := encoding_json2.Marshal(p) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Operation_Expunge{} - err = encoding_json2.Unmarshal(jsondata, msg) + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Json Equal %#v", msg, p) + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } -func TestEntryProtoText(t *testing16.T) { - popr := math_rand16.New(math_rand16.NewSource(time16.Now().UnixNano())) +func TestEntryProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedEntry(popr, true) - data := github_com_gogo_protobuf_proto9.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Entry{} - if err := github_com_gogo_protobuf_proto9.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestEntryProtoCompactText(t *testing16.T) { - popr := math_rand16.New(math_rand16.NewSource(time16.Now().UnixNano())) +func TestEntryProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedEntry(popr, true) - data := github_com_gogo_protobuf_proto9.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Entry{} - if err := github_com_gogo_protobuf_proto9.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestOperationProtoText(t *testing16.T) { - popr := math_rand16.New(math_rand16.NewSource(time16.Now().UnixNano())) +func TestOperationProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation(popr, true) - data := github_com_gogo_protobuf_proto9.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Operation{} - if err := github_com_gogo_protobuf_proto9.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestOperationProtoCompactText(t *testing16.T) { - popr := math_rand16.New(math_rand16.NewSource(time16.Now().UnixNano())) +func TestOperationProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation(popr, true) - data := github_com_gogo_protobuf_proto9.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Operation{} - if err := github_com_gogo_protobuf_proto9.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestOperation_SnapshotProtoText(t *testing16.T) { - popr := math_rand16.New(math_rand16.NewSource(time16.Now().UnixNano())) +func TestOperation_SnapshotProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Snapshot(popr, true) - data := github_com_gogo_protobuf_proto9.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Operation_Snapshot{} - if err := github_com_gogo_protobuf_proto9.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestOperation_SnapshotProtoCompactText(t *testing16.T) { - popr := math_rand16.New(math_rand16.NewSource(time16.Now().UnixNano())) +func TestOperation_SnapshotProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Snapshot(popr, true) - data := github_com_gogo_protobuf_proto9.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Operation_Snapshot{} - if err := github_com_gogo_protobuf_proto9.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestOperation_DiffProtoText(t *testing16.T) { - popr := math_rand16.New(math_rand16.NewSource(time16.Now().UnixNano())) +func TestOperation_DiffProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Diff(popr, true) - data := github_com_gogo_protobuf_proto9.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Operation_Diff{} - if err := github_com_gogo_protobuf_proto9.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestOperation_DiffProtoCompactText(t *testing16.T) { - popr := math_rand16.New(math_rand16.NewSource(time16.Now().UnixNano())) +func TestOperation_DiffProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Diff(popr, true) - data := github_com_gogo_protobuf_proto9.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Operation_Diff{} - if err := github_com_gogo_protobuf_proto9.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestOperation_ExpungeProtoText(t *testing16.T) { - popr := math_rand16.New(math_rand16.NewSource(time16.Now().UnixNano())) +func TestOperation_ExpungeProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Expunge(popr, true) - data := github_com_gogo_protobuf_proto9.MarshalTextString(p) + data := github_com_gogo_protobuf_proto.MarshalTextString(p) msg := &Operation_Expunge{} - if err := github_com_gogo_protobuf_proto9.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestOperation_ExpungeProtoCompactText(t *testing16.T) { - popr := math_rand16.New(math_rand16.NewSource(time16.Now().UnixNano())) +func TestOperation_ExpungeProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Expunge(popr, true) - data := github_com_gogo_protobuf_proto9.CompactTextString(p) + data := github_com_gogo_protobuf_proto.CompactTextString(p) msg := &Operation_Expunge{} - if err := github_com_gogo_protobuf_proto9.UnmarshalText(data, msg); err != nil { - panic(err) + if err := github_com_gogo_protobuf_proto.UnmarshalText(data, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) } if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) + t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { - t.Fatalf("%#v !Proto %#v", msg, p) + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } } -func TestEntryStringer(t *testing17.T) { - popr := math_rand17.New(math_rand17.NewSource(time17.Now().UnixNano())) +func TestEntryVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedEntry(popr, false) - s1 := p.String() - s2 := fmt4.Sprintf("%v", p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Entry{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestOperationVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOperation(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Operation{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestOperation_SnapshotVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOperation_Snapshot(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Operation_Snapshot{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestOperation_DiffVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOperation_Diff(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Operation_Diff{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestOperation_ExpungeVerboseEqual(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedOperation_Expunge(popr, false) + data, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + panic(err) + } + msg := &Operation_Expunge{} + if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { + panic(err) + } + if err := p.VerboseEqual(msg); err != nil { + t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + } +} +func TestEntryGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) + p := NewPopulatedEntry(popr, false) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) } } -func TestOperationStringer(t *testing17.T) { - popr := math_rand17.New(math_rand17.NewSource(time17.Now().UnixNano())) +func TestOperationGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedOperation(popr, false) - s1 := p.String() - s2 := fmt4.Sprintf("%v", p) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) } } -func TestOperation_SnapshotStringer(t *testing17.T) { - popr := math_rand17.New(math_rand17.NewSource(time17.Now().UnixNano())) +func TestOperation_SnapshotGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedOperation_Snapshot(popr, false) - s1 := p.String() - s2 := fmt4.Sprintf("%v", p) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) } } -func TestOperation_DiffStringer(t *testing17.T) { - popr := math_rand17.New(math_rand17.NewSource(time17.Now().UnixNano())) +func TestOperation_DiffGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedOperation_Diff(popr, false) - s1 := p.String() - s2 := fmt4.Sprintf("%v", p) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) } } -func TestOperation_ExpungeStringer(t *testing17.T) { - popr := math_rand17.New(math_rand17.NewSource(time17.Now().UnixNano())) +func TestOperation_ExpungeGoString(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedOperation_Expunge(popr, false) - s1 := p.String() - s2 := fmt4.Sprintf("%v", p) + s1 := p.GoString() + s2 := fmt.Sprintf("%#v", p) if s1 != s2 { - t.Fatalf("String want %v got %v", s1, s2) + t.Fatalf("GoString want %v got %v", s1, s2) + } + _, err := go_parser.ParseExpr(s1) + if err != nil { + panic(err) } } -func TestEntrySize(t *testing18.T) { - popr := math_rand18.New(math_rand18.NewSource(time18.Now().UnixNano())) +func TestEntrySize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedEntry(popr, true) - size2 := github_com_gogo_protobuf_proto10.Size(p) - data, err := github_com_gogo_protobuf_proto10.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto10.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkEntrySize(b *testing18.B) { - popr := math_rand18.New(math_rand18.NewSource(616)) +func BenchmarkEntrySize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Entry, 1000) for i := 0; i < 1000; i++ { @@ -814,29 +982,30 @@ func BenchmarkEntrySize(b *testing18.B) { b.SetBytes(int64(total / b.N)) } -func TestOperationSize(t *testing18.T) { - popr := math_rand18.New(math_rand18.NewSource(time18.Now().UnixNano())) +func TestOperationSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation(popr, true) - size2 := github_com_gogo_protobuf_proto10.Size(p) - data, err := github_com_gogo_protobuf_proto10.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto10.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkOperationSize(b *testing18.B) { - popr := math_rand18.New(math_rand18.NewSource(616)) +func BenchmarkOperationSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Operation, 1000) for i := 0; i < 1000; i++ { @@ -849,29 +1018,30 @@ func BenchmarkOperationSize(b *testing18.B) { b.SetBytes(int64(total / b.N)) } -func TestOperation_SnapshotSize(t *testing18.T) { - popr := math_rand18.New(math_rand18.NewSource(time18.Now().UnixNano())) +func TestOperation_SnapshotSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Snapshot(popr, true) - size2 := github_com_gogo_protobuf_proto10.Size(p) - data, err := github_com_gogo_protobuf_proto10.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto10.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkOperation_SnapshotSize(b *testing18.B) { - popr := math_rand18.New(math_rand18.NewSource(616)) +func BenchmarkOperation_SnapshotSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Operation_Snapshot, 1000) for i := 0; i < 1000; i++ { @@ -884,29 +1054,30 @@ func BenchmarkOperation_SnapshotSize(b *testing18.B) { b.SetBytes(int64(total / b.N)) } -func TestOperation_DiffSize(t *testing18.T) { - popr := math_rand18.New(math_rand18.NewSource(time18.Now().UnixNano())) +func TestOperation_DiffSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Diff(popr, true) - size2 := github_com_gogo_protobuf_proto10.Size(p) - data, err := github_com_gogo_protobuf_proto10.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto10.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkOperation_DiffSize(b *testing18.B) { - popr := math_rand18.New(math_rand18.NewSource(616)) +func BenchmarkOperation_DiffSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Operation_Diff, 1000) for i := 0; i < 1000; i++ { @@ -919,29 +1090,30 @@ func BenchmarkOperation_DiffSize(b *testing18.B) { b.SetBytes(int64(total / b.N)) } -func TestOperation_ExpungeSize(t *testing18.T) { - popr := math_rand18.New(math_rand18.NewSource(time18.Now().UnixNano())) +func TestOperation_ExpungeSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedOperation_Expunge(popr, true) - size2 := github_com_gogo_protobuf_proto10.Size(p) - data, err := github_com_gogo_protobuf_proto10.Marshal(p) + size2 := github_com_gogo_protobuf_proto.Size(p) + data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { - panic(err) + t.Fatalf("seed = %d, err = %v", seed, err) } size := p.Size() if len(data) != size { - t.Fatalf("size %v != marshalled size %v", size, len(data)) + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data)) } if size2 != size { - t.Fatalf("size %v != before marshal proto.Size %v", size, size2) + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) } - size3 := github_com_gogo_protobuf_proto10.Size(p) + size3 := github_com_gogo_protobuf_proto.Size(p) if size3 != size { - t.Fatalf("size %v != after marshal proto.Size %v", size, size3) + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) } } -func BenchmarkOperation_ExpungeSize(b *testing18.B) { - popr := math_rand18.New(math_rand18.NewSource(616)) +func BenchmarkOperation_ExpungeSize(b *testing.B) { + popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Operation_Expunge, 1000) for i := 0; i < 1000; i++ { @@ -954,144 +1126,49 @@ func BenchmarkOperation_ExpungeSize(b *testing18.B) { b.SetBytes(int64(total / b.N)) } -func TestEntryGoString(t *testing19.T) { - popr := math_rand19.New(math_rand19.NewSource(time19.Now().UnixNano())) +func TestEntryStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedEntry(popr, false) - s1 := p.GoString() - s2 := fmt5.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser2.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestOperationGoString(t *testing19.T) { - popr := math_rand19.New(math_rand19.NewSource(time19.Now().UnixNano())) +func TestOperationStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedOperation(popr, false) - s1 := p.GoString() - s2 := fmt5.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser2.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestOperation_SnapshotGoString(t *testing19.T) { - popr := math_rand19.New(math_rand19.NewSource(time19.Now().UnixNano())) +func TestOperation_SnapshotStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedOperation_Snapshot(popr, false) - s1 := p.GoString() - s2 := fmt5.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser2.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestOperation_DiffGoString(t *testing19.T) { - popr := math_rand19.New(math_rand19.NewSource(time19.Now().UnixNano())) +func TestOperation_DiffStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedOperation_Diff(popr, false) - s1 := p.GoString() - s2 := fmt5.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser2.ParseExpr(s1) - if err != nil { - panic(err) + t.Fatalf("String want %v got %v", s1, s2) } } -func TestOperation_ExpungeGoString(t *testing19.T) { - popr := math_rand19.New(math_rand19.NewSource(time19.Now().UnixNano())) +func TestOperation_ExpungeStringer(t *testing.T) { + popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedOperation_Expunge(popr, false) - s1 := p.GoString() - s2 := fmt5.Sprintf("%#v", p) + s1 := p.String() + s2 := fmt.Sprintf("%v", p) if s1 != s2 { - t.Fatalf("GoString want %v got %v", s1, s2) - } - _, err := go_parser2.ParseExpr(s1) - if err != nil { - panic(err) - } -} -func TestEntryVerboseEqual(t *testing20.T) { - popr := math_rand20.New(math_rand20.NewSource(time20.Now().UnixNano())) - p := NewPopulatedEntry(popr, false) - data, err := github_com_gogo_protobuf_proto11.Marshal(p) - if err != nil { - panic(err) - } - msg := &Entry{} - if err := github_com_gogo_protobuf_proto11.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestOperationVerboseEqual(t *testing20.T) { - popr := math_rand20.New(math_rand20.NewSource(time20.Now().UnixNano())) - p := NewPopulatedOperation(popr, false) - data, err := github_com_gogo_protobuf_proto11.Marshal(p) - if err != nil { - panic(err) - } - msg := &Operation{} - if err := github_com_gogo_protobuf_proto11.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestOperation_SnapshotVerboseEqual(t *testing20.T) { - popr := math_rand20.New(math_rand20.NewSource(time20.Now().UnixNano())) - p := NewPopulatedOperation_Snapshot(popr, false) - data, err := github_com_gogo_protobuf_proto11.Marshal(p) - if err != nil { - panic(err) - } - msg := &Operation_Snapshot{} - if err := github_com_gogo_protobuf_proto11.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestOperation_DiffVerboseEqual(t *testing20.T) { - popr := math_rand20.New(math_rand20.NewSource(time20.Now().UnixNano())) - p := NewPopulatedOperation_Diff(popr, false) - data, err := github_com_gogo_protobuf_proto11.Marshal(p) - if err != nil { - panic(err) - } - msg := &Operation_Diff{} - if err := github_com_gogo_protobuf_proto11.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) - } -} -func TestOperation_ExpungeVerboseEqual(t *testing20.T) { - popr := math_rand20.New(math_rand20.NewSource(time20.Now().UnixNano())) - p := NewPopulatedOperation_Expunge(popr, false) - data, err := github_com_gogo_protobuf_proto11.Marshal(p) - if err != nil { - panic(err) - } - msg := &Operation_Expunge{} - if err := github_com_gogo_protobuf_proto11.Unmarshal(data, msg); err != nil { - panic(err) - } - if err := p.VerboseEqual(msg); err != nil { - t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) + t.Fatalf("String want %v got %v", s1, s2) } } diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosutil/constants.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosutil/constants.go index 849c26baa00e..a1a3085f8e31 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosutil/constants.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/mesosutil/constants.go @@ -2,5 +2,5 @@ package mesosutil const ( // MesosVersion indicates the supported mesos version. - MesosVersion = "0.20.0" + MesosVersion = "0.24.0" ) diff --git a/Godeps/_workspace/src/github.com/mesos/mesos-go/upid/upid.go b/Godeps/_workspace/src/github.com/mesos/mesos-go/upid/upid.go index ca69106ef189..74f9ebbd8065 100644 --- a/Godeps/_workspace/src/github.com/mesos/mesos-go/upid/upid.go +++ b/Godeps/_workspace/src/github.com/mesos/mesos-go/upid/upid.go @@ -49,10 +49,7 @@ func Parse(input string) (*UPID, error) { } // String returns the string representation. -func (u *UPID) String() string { - if u == nil { - return "" - } +func (u UPID) String() string { return fmt.Sprintf("%s@%s:%s", u.ID, u.Host, u.Port) } diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/bench_test.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/bench_test.go new file mode 100644 index 000000000000..92b16a028aad --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/bench_test.go @@ -0,0 +1,171 @@ +// Copyright 2015 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expfmt + +import ( + "bytes" + "compress/gzip" + "io" + "io/ioutil" + "testing" + + "github.com/matttproud/golang_protobuf_extensions/pbutil" + + dto "github.com/prometheus/client_model/go" +) + +var parser TextParser + +// Benchmarks to show how much penalty text format parsing actually inflicts. +// +// Example results on Linux 3.13.0, Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz, go1.4. +// +// BenchmarkParseText 1000 1188535 ns/op 205085 B/op 6135 allocs/op +// BenchmarkParseTextGzip 1000 1376567 ns/op 246224 B/op 6151 allocs/op +// BenchmarkParseProto 10000 172790 ns/op 52258 B/op 1160 allocs/op +// BenchmarkParseProtoGzip 5000 324021 ns/op 94931 B/op 1211 allocs/op +// BenchmarkParseProtoMap 10000 187946 ns/op 58714 B/op 1203 allocs/op +// +// CONCLUSION: The overhead for the map is negligible. Text format needs ~5x more allocations. +// Without compression, it needs ~7x longer, but with compression (the more relevant scenario), +// the difference becomes less relevant, only ~4x. +// +// The test data contains 248 samples. +// +// BenchmarkProcessor002ParseOnly in the extraction package is not quite +// comparable to the benchmarks here, but it gives an idea: JSON parsing is even +// slower than text parsing and needs a comparable amount of allocs. + +// BenchmarkParseText benchmarks the parsing of a text-format scrape into metric +// family DTOs. +func BenchmarkParseText(b *testing.B) { + b.StopTimer() + data, err := ioutil.ReadFile("testdata/text") + if err != nil { + b.Fatal(err) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + if _, err := parser.TextToMetricFamilies(bytes.NewReader(data)); err != nil { + b.Fatal(err) + } + } +} + +// BenchmarkParseTextGzip benchmarks the parsing of a gzipped text-format scrape +// into metric family DTOs. +func BenchmarkParseTextGzip(b *testing.B) { + b.StopTimer() + data, err := ioutil.ReadFile("testdata/text.gz") + if err != nil { + b.Fatal(err) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + in, err := gzip.NewReader(bytes.NewReader(data)) + if err != nil { + b.Fatal(err) + } + if _, err := parser.TextToMetricFamilies(in); err != nil { + b.Fatal(err) + } + } +} + +// BenchmarkParseProto benchmarks the parsing of a protobuf-format scrape into +// metric family DTOs. Note that this does not build a map of metric families +// (as the text version does), because it is not required for Prometheus +// ingestion either. (However, it is required for the text-format parsing, as +// the metric family might be sprinkled all over the text, while the +// protobuf-format guarantees bundling at one place.) +func BenchmarkParseProto(b *testing.B) { + b.StopTimer() + data, err := ioutil.ReadFile("testdata/protobuf") + if err != nil { + b.Fatal(err) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + family := &dto.MetricFamily{} + in := bytes.NewReader(data) + for { + family.Reset() + if _, err := pbutil.ReadDelimited(in, family); err != nil { + if err == io.EOF { + break + } + b.Fatal(err) + } + } + } +} + +// BenchmarkParseProtoGzip is like BenchmarkParseProto above, but parses gzipped +// protobuf format. +func BenchmarkParseProtoGzip(b *testing.B) { + b.StopTimer() + data, err := ioutil.ReadFile("testdata/protobuf.gz") + if err != nil { + b.Fatal(err) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + family := &dto.MetricFamily{} + in, err := gzip.NewReader(bytes.NewReader(data)) + if err != nil { + b.Fatal(err) + } + for { + family.Reset() + if _, err := pbutil.ReadDelimited(in, family); err != nil { + if err == io.EOF { + break + } + b.Fatal(err) + } + } + } +} + +// BenchmarkParseProtoMap is like BenchmarkParseProto but DOES put the parsed +// metric family DTOs into a map. This is not happening during Prometheus +// ingestion. It is just here to measure the overhead of that map creation and +// separate it from the overhead of the text format parsing. +func BenchmarkParseProtoMap(b *testing.B) { + b.StopTimer() + data, err := ioutil.ReadFile("testdata/protobuf") + if err != nil { + b.Fatal(err) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + families := map[string]*dto.MetricFamily{} + in := bytes.NewReader(data) + for { + family := &dto.MetricFamily{} + if _, err := pbutil.ReadDelimited(in, family); err != nil { + if err == io.EOF { + break + } + b.Fatal(err) + } + families[family.GetName()] = family + } + } +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode.go new file mode 100644 index 000000000000..d36f0ecebcbb --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode.go @@ -0,0 +1,410 @@ +// Copyright 2015 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expfmt + +import ( + "fmt" + "io" + "math" + "mime" + "net/http" + + dto "github.com/prometheus/client_model/go" + + "github.com/matttproud/golang_protobuf_extensions/pbutil" + "github.com/prometheus/common/model" +) + +// Decoder types decode an input stream into metric families. +type Decoder interface { + Decode(*dto.MetricFamily) error +} + +type DecodeOptions struct { + // Timestamp is added to each value from the stream that has no explicit timestamp set. + Timestamp model.Time +} + +// ResponseFormat extracts the correct format from a HTTP response header. +func ResponseFormat(h http.Header) (Format, error) { + ct := h.Get(hdrContentType) + + mediatype, params, err := mime.ParseMediaType(ct) + if err != nil { + return "", fmt.Errorf("invalid Content-Type header %q: %s", ct, err) + } + + const ( + textType = "text/plain" + jsonType = "application/json" + ) + + switch mediatype { + case ProtoType: + if p := params["proto"]; p != ProtoProtocol { + return "", fmt.Errorf("unrecognized protocol message %s", p) + } + if e := params["encoding"]; e != "delimited" { + return "", fmt.Errorf("unsupported encoding %s", e) + } + return FmtProtoDelim, nil + + case textType: + if v, ok := params["version"]; ok && v != TextVersion { + return "", fmt.Errorf("unrecognized protocol version %s", v) + } + return FmtText, nil + + case jsonType: + var prometheusAPIVersion string + + if params["schema"] == "prometheus/telemetry" && params["version"] != "" { + prometheusAPIVersion = params["version"] + } else { + prometheusAPIVersion = h.Get("X-Prometheus-API-Version") + } + + switch prometheusAPIVersion { + case "0.0.2": + return FmtJSON2, nil + default: + return "", fmt.Errorf("unrecognized API version %s", prometheusAPIVersion) + } + } + + return "", fmt.Errorf("unsupported media type %q, expected %q or %q", mediatype, ProtoType, textType) +} + +// NewDecoder returns a new decoder based on the HTTP header. +func NewDecoder(r io.Reader, format Format) (Decoder, error) { + switch format { + case FmtProtoDelim: + return &protoDecoder{r: r}, nil + case FmtText: + return &textDecoder{r: r}, nil + case FmtJSON2: + return newJSON2Decoder(r), nil + } + return nil, fmt.Errorf("unsupported decoding format %q", format) +} + +// protoDecoder implements the Decoder interface for protocol buffers. +type protoDecoder struct { + r io.Reader +} + +// Decode implements the Decoder interface. +func (d *protoDecoder) Decode(v *dto.MetricFamily) error { + _, err := pbutil.ReadDelimited(d.r, v) + return err +} + +// textDecoder implements the Decoder interface for the text protcol. +type textDecoder struct { + r io.Reader + p TextParser + fams []*dto.MetricFamily +} + +// Decode implements the Decoder interface. +func (d *textDecoder) Decode(v *dto.MetricFamily) error { + // TODO(fabxc): Wrap this as a line reader to make streaming safer. + if len(d.fams) == 0 { + // No cached metric families, read everything and parse metrics. + fams, err := d.p.TextToMetricFamilies(d.r) + if err != nil { + return err + } + if len(fams) == 0 { + return io.EOF + } + for _, f := range fams { + d.fams = append(d.fams, f) + } + } + + *v = *d.fams[len(d.fams)-1] + d.fams = d.fams[:len(d.fams)-1] + + return nil +} + +type SampleDecoder struct { + Dec Decoder + Opts *DecodeOptions + + f dto.MetricFamily +} + +func (sd *SampleDecoder) Decode(s *model.Vector) error { + if err := sd.Dec.Decode(&sd.f); err != nil { + return err + } + *s = extractSamples(&sd.f, sd.Opts) + return nil +} + +// Extract samples builds a slice of samples from the provided metric families. +func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) model.Vector { + var all model.Vector + for _, f := range fams { + all = append(all, extractSamples(f, o)...) + } + return all +} + +func extractSamples(f *dto.MetricFamily, o *DecodeOptions) model.Vector { + switch f.GetType() { + case dto.MetricType_COUNTER: + return extractCounter(o, f) + case dto.MetricType_GAUGE: + return extractGauge(o, f) + case dto.MetricType_SUMMARY: + return extractSummary(o, f) + case dto.MetricType_UNTYPED: + return extractUntyped(o, f) + case dto.MetricType_HISTOGRAM: + return extractHistogram(o, f) + } + panic("expfmt.extractSamples: unknown metric family type") +} + +func extractCounter(o *DecodeOptions, f *dto.MetricFamily) model.Vector { + samples := make(model.Vector, 0, len(f.Metric)) + + for _, m := range f.Metric { + if m.Counter == nil { + continue + } + + lset := make(model.LabelSet, len(m.Label)+1) + for _, p := range m.Label { + lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) + } + lset[model.MetricNameLabel] = model.LabelValue(f.GetName()) + + smpl := &model.Sample{ + Metric: model.Metric(lset), + Value: model.SampleValue(m.Counter.GetValue()), + } + + if m.TimestampMs != nil { + smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000) + } else { + smpl.Timestamp = o.Timestamp + } + + samples = append(samples, smpl) + } + + return samples +} + +func extractGauge(o *DecodeOptions, f *dto.MetricFamily) model.Vector { + samples := make(model.Vector, 0, len(f.Metric)) + + for _, m := range f.Metric { + if m.Gauge == nil { + continue + } + + lset := make(model.LabelSet, len(m.Label)+1) + for _, p := range m.Label { + lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) + } + lset[model.MetricNameLabel] = model.LabelValue(f.GetName()) + + smpl := &model.Sample{ + Metric: model.Metric(lset), + Value: model.SampleValue(m.Gauge.GetValue()), + } + + if m.TimestampMs != nil { + smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000) + } else { + smpl.Timestamp = o.Timestamp + } + + samples = append(samples, smpl) + } + + return samples +} + +func extractUntyped(o *DecodeOptions, f *dto.MetricFamily) model.Vector { + samples := make(model.Vector, 0, len(f.Metric)) + + for _, m := range f.Metric { + if m.Untyped == nil { + continue + } + + lset := make(model.LabelSet, len(m.Label)+1) + for _, p := range m.Label { + lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) + } + lset[model.MetricNameLabel] = model.LabelValue(f.GetName()) + + smpl := &model.Sample{ + Metric: model.Metric(lset), + Value: model.SampleValue(m.Untyped.GetValue()), + } + + if m.TimestampMs != nil { + smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000) + } else { + smpl.Timestamp = o.Timestamp + } + + samples = append(samples, smpl) + } + + return samples +} + +func extractSummary(o *DecodeOptions, f *dto.MetricFamily) model.Vector { + samples := make(model.Vector, 0, len(f.Metric)) + + for _, m := range f.Metric { + if m.Summary == nil { + continue + } + + timestamp := o.Timestamp + if m.TimestampMs != nil { + timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000) + } + + for _, q := range m.Summary.Quantile { + lset := make(model.LabelSet, len(m.Label)+2) + for _, p := range m.Label { + lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) + } + // BUG(matt): Update other names to "quantile". + lset[model.LabelName(model.QuantileLabel)] = model.LabelValue(fmt.Sprint(q.GetQuantile())) + lset[model.MetricNameLabel] = model.LabelValue(f.GetName()) + + samples = append(samples, &model.Sample{ + Metric: model.Metric(lset), + Value: model.SampleValue(q.GetValue()), + Timestamp: timestamp, + }) + } + + lset := make(model.LabelSet, len(m.Label)+1) + for _, p := range m.Label { + lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) + } + lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum") + + samples = append(samples, &model.Sample{ + Metric: model.Metric(lset), + Value: model.SampleValue(m.Summary.GetSampleSum()), + Timestamp: timestamp, + }) + + lset = make(model.LabelSet, len(m.Label)+1) + for _, p := range m.Label { + lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) + } + lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count") + + samples = append(samples, &model.Sample{ + Metric: model.Metric(lset), + Value: model.SampleValue(m.Summary.GetSampleCount()), + Timestamp: timestamp, + }) + } + + return samples +} + +func extractHistogram(o *DecodeOptions, f *dto.MetricFamily) model.Vector { + samples := make(model.Vector, 0, len(f.Metric)) + + for _, m := range f.Metric { + if m.Histogram == nil { + continue + } + + timestamp := o.Timestamp + if m.TimestampMs != nil { + timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000) + } + + infSeen := false + + for _, q := range m.Histogram.Bucket { + lset := make(model.LabelSet, len(m.Label)+2) + for _, p := range m.Label { + lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) + } + lset[model.LabelName(model.BucketLabel)] = model.LabelValue(fmt.Sprint(q.GetUpperBound())) + lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket") + + if math.IsInf(q.GetUpperBound(), +1) { + infSeen = true + } + + samples = append(samples, &model.Sample{ + Metric: model.Metric(lset), + Value: model.SampleValue(q.GetCumulativeCount()), + Timestamp: timestamp, + }) + } + + lset := make(model.LabelSet, len(m.Label)+1) + for _, p := range m.Label { + lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) + } + lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum") + + samples = append(samples, &model.Sample{ + Metric: model.Metric(lset), + Value: model.SampleValue(m.Histogram.GetSampleSum()), + Timestamp: timestamp, + }) + + lset = make(model.LabelSet, len(m.Label)+1) + for _, p := range m.Label { + lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) + } + lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count") + + count := &model.Sample{ + Metric: model.Metric(lset), + Value: model.SampleValue(m.Histogram.GetSampleCount()), + Timestamp: timestamp, + } + samples = append(samples, count) + + if !infSeen { + // Append an infinity bucket sample. + lset := make(model.LabelSet, len(m.Label)+2) + for _, p := range m.Label { + lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) + } + lset[model.LabelName(model.BucketLabel)] = model.LabelValue("+Inf") + lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket") + + samples = append(samples, &model.Sample{ + Metric: model.Metric(lset), + Value: count.Value, + Timestamp: timestamp, + }) + } + } + + return samples +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode_test.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode_test.go new file mode 100644 index 000000000000..307fcd21fed8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/decode_test.go @@ -0,0 +1,373 @@ +// Copyright 2015 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expfmt + +import ( + "errors" + "io" + "net/http" + "reflect" + "sort" + "strings" + "testing" + + "github.com/prometheus/common/model" +) + +func TestTextDecoder(t *testing.T) { + var ( + ts = model.Now() + in = ` +# Only a quite simple scenario with two metric families. +# More complicated tests of the parser itself can be found in the text package. +# TYPE mf2 counter +mf2 3 +mf1{label="value1"} -3.14 123456 +mf1{label="value2"} 42 +mf2 4 +` + out = model.Vector{ + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "mf1", + "label": "value1", + }, + Value: -3.14, + Timestamp: 123456, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "mf1", + "label": "value2", + }, + Value: 42, + Timestamp: ts, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "mf2", + }, + Value: 3, + Timestamp: ts, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "mf2", + }, + Value: 4, + Timestamp: ts, + }, + } + ) + + dec := &SampleDecoder{ + Dec: &textDecoder{r: strings.NewReader(in)}, + Opts: &DecodeOptions{ + Timestamp: ts, + }, + } + var all model.Vector + for { + var smpls model.Vector + err := dec.Decode(&smpls) + if err == io.EOF { + break + } + if err != nil { + t.Fatal(err) + } + all = append(all, smpls...) + } + sort.Sort(all) + sort.Sort(out) + if !reflect.DeepEqual(all, out) { + t.Fatalf("output does not match") + } +} + +func TestProtoDecoder(t *testing.T) { + + var testTime = model.Now() + + scenarios := []struct { + in string + expected model.Vector + }{ + { + in: "", + }, + { + in: "\x8f\x01\n\rrequest_count\x12\x12Number of requests\x18\x00\"0\n#\n\x0fsome_label_name\x12\x10some_label_value\x1a\t\t\x00\x00\x00\x00\x00\x00E\xc0\"6\n)\n\x12another_label_name\x12\x13another_label_value\x1a\t\t\x00\x00\x00\x00\x00\x00U@", + expected: model.Vector{ + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_count", + "some_label_name": "some_label_value", + }, + Value: -42, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_count", + "another_label_name": "another_label_value", + }, + Value: 84, + Timestamp: testTime, + }, + }, + }, + { + in: "\xb9\x01\n\rrequest_count\x12\x12Number of requests\x18\x02\"O\n#\n\x0fsome_label_name\x12\x10some_label_value\"(\x1a\x12\t\xaeG\xe1z\x14\xae\xef?\x11\x00\x00\x00\x00\x00\x00E\xc0\x1a\x12\t+\x87\x16\xd9\xce\xf7\xef?\x11\x00\x00\x00\x00\x00\x00U\xc0\"A\n)\n\x12another_label_name\x12\x13another_label_value\"\x14\x1a\x12\t\x00\x00\x00\x00\x00\x00\xe0?\x11\x00\x00\x00\x00\x00\x00$@", + expected: model.Vector{ + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_count_count", + "some_label_name": "some_label_value", + }, + Value: 0, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_count_sum", + "some_label_name": "some_label_value", + }, + Value: 0, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_count", + "some_label_name": "some_label_value", + "quantile": "0.99", + }, + Value: -42, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_count", + "some_label_name": "some_label_value", + "quantile": "0.999", + }, + Value: -84, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_count_count", + "another_label_name": "another_label_value", + }, + Value: 0, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_count_sum", + "another_label_name": "another_label_value", + }, + Value: 0, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_count", + "another_label_name": "another_label_value", + "quantile": "0.5", + }, + Value: 10, + Timestamp: testTime, + }, + }, + }, + { + in: "\x8d\x01\n\x1drequest_duration_microseconds\x12\x15The response latency.\x18\x04\"S:Q\b\x85\x15\x11\xcd\xcc\xccL\x8f\xcb:A\x1a\v\b{\x11\x00\x00\x00\x00\x00\x00Y@\x1a\f\b\x9c\x03\x11\x00\x00\x00\x00\x00\x00^@\x1a\f\b\xd0\x04\x11\x00\x00\x00\x00\x00\x00b@\x1a\f\b\xf4\v\x11\x9a\x99\x99\x99\x99\x99e@\x1a\f\b\x85\x15\x11\x00\x00\x00\x00\x00\x00\xf0\u007f", + expected: model.Vector{ + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_duration_microseconds_bucket", + "le": "100", + }, + Value: 123, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_duration_microseconds_bucket", + "le": "120", + }, + Value: 412, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_duration_microseconds_bucket", + "le": "144", + }, + Value: 592, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_duration_microseconds_bucket", + "le": "172.8", + }, + Value: 1524, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_duration_microseconds_bucket", + "le": "+Inf", + }, + Value: 2693, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_duration_microseconds_sum", + }, + Value: 1756047.3, + Timestamp: testTime, + }, + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_duration_microseconds_count", + }, + Value: 2693, + Timestamp: testTime, + }, + }, + }, + { + // The metric type is unset in this protobuf, which needs to be handled + // correctly by the decoder. + in: "\x1c\n\rrequest_count\"\v\x1a\t\t\x00\x00\x00\x00\x00\x00\xf0?", + expected: model.Vector{ + &model.Sample{ + Metric: model.Metric{ + model.MetricNameLabel: "request_count", + }, + Value: 1, + Timestamp: testTime, + }, + }, + }, + } + + for i, scenario := range scenarios { + dec := &SampleDecoder{ + Dec: &protoDecoder{r: strings.NewReader(scenario.in)}, + Opts: &DecodeOptions{ + Timestamp: testTime, + }, + } + + var all model.Vector + for { + var smpls model.Vector + err := dec.Decode(&smpls) + if err == io.EOF { + break + } + if err != nil { + t.Fatal(err) + } + all = append(all, smpls...) + } + sort.Sort(all) + sort.Sort(scenario.expected) + if !reflect.DeepEqual(all, scenario.expected) { + t.Fatalf("%d. output does not match, want: %#v, got %#v", i, scenario.expected, all) + } + } +} + +func testDiscriminatorHTTPHeader(t testing.TB) { + var scenarios = []struct { + input map[string]string + output Format + err error + }{ + { + input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="io.prometheus.client.MetricFamily"; encoding="delimited"`}, + output: FmtProtoDelim, + err: nil, + }, + { + input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="illegal"; encoding="delimited"`}, + output: "", + err: errors.New("unrecognized protocol message illegal"), + }, + { + input: map[string]string{"Content-Type": `application/vnd.google.protobuf; proto="io.prometheus.client.MetricFamily"; encoding="illegal"`}, + output: "", + err: errors.New("unsupported encoding illegal"), + }, + { + input: map[string]string{"Content-Type": `text/plain; version=0.0.4`}, + output: FmtText, + err: nil, + }, + { + input: map[string]string{"Content-Type": `text/plain`}, + output: FmtText, + err: nil, + }, + { + input: map[string]string{"Content-Type": `text/plain; version=0.0.3`}, + output: "", + err: errors.New("unrecognized protocol version 0.0.3"), + }, + } + + for i, scenario := range scenarios { + var header http.Header + + if len(scenario.input) > 0 { + header = http.Header{} + } + + for key, value := range scenario.input { + header.Add(key, value) + } + + actual, err := ResponseFormat(header) + + if scenario.err != err { + if scenario.err != nil && err != nil { + if scenario.err.Error() != err.Error() { + t.Errorf("%d. expected %s, got %s", i, scenario.err, err) + } + } else if scenario.err != nil || err != nil { + t.Errorf("%d. expected %s, got %s", i, scenario.err, err) + } + } + + if !reflect.DeepEqual(scenario.output, actual) { + t.Errorf("%d. expected %s, got %s", i, scenario.output, actual) + } + } +} + +func TestDiscriminatorHTTPHeader(t *testing.T) { + testDiscriminatorHTTPHeader(t) +} + +func BenchmarkDiscriminatorHTTPHeader(b *testing.B) { + for i := 0; i < b.N; i++ { + testDiscriminatorHTTPHeader(b) + } +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/encode.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/encode.go new file mode 100644 index 000000000000..392ca90ee257 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/encode.go @@ -0,0 +1,88 @@ +// Copyright 2015 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expfmt + +import ( + "fmt" + "io" + "net/http" + + "bitbucket.org/ww/goautoneg" + "github.com/golang/protobuf/proto" + "github.com/matttproud/golang_protobuf_extensions/pbutil" + + dto "github.com/prometheus/client_model/go" +) + +// Encoder types encode metric families into an underlying wire protocol. +type Encoder interface { + Encode(*dto.MetricFamily) error +} + +type encoder func(*dto.MetricFamily) error + +func (e encoder) Encode(v *dto.MetricFamily) error { + return e(v) +} + +// Negotiate returns the Content-Type based on the given Accept header. +// If no appropriate accepted type is found, FmtText is returned. +func Negotiate(h http.Header) Format { + for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) { + // Check for protocol buffer + if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol { + switch ac.Params["encoding"] { + case "delimited": + return FmtProtoDelim + case "text": + return FmtProtoText + case "compact-text": + return FmtProtoCompact + } + } + // Check for text format. + ver := ac.Params["version"] + if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") { + return FmtText + } + } + return FmtText +} + +// NewEncoder returns a new encoder based on content type negotiation. +func NewEncoder(w io.Writer, format Format) Encoder { + switch format { + case FmtProtoDelim: + return encoder(func(v *dto.MetricFamily) error { + _, err := pbutil.WriteDelimited(w, v) + return err + }) + case FmtProtoCompact: + return encoder(func(v *dto.MetricFamily) error { + _, err := fmt.Fprintln(w, v.String()) + return err + }) + case FmtProtoText: + return encoder(func(v *dto.MetricFamily) error { + _, err := fmt.Fprintln(w, proto.MarshalTextString(v)) + return err + }) + case FmtText: + return encoder(func(v *dto.MetricFamily) error { + _, err := MetricFamilyToText(w, v) + return err + }) + } + panic("expfmt.NewEncoder: unknown format") +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/expfmt.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/expfmt.go new file mode 100644 index 000000000000..3637dd7661d7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/expfmt.go @@ -0,0 +1,37 @@ +// Copyright 2015 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// A package for reading and writing Prometheus metrics. +package expfmt + +type Format string + +const ( + TextVersion = "0.0.4" + + ProtoType = `application/vnd.google.protobuf` + ProtoProtocol = `io.prometheus.client.MetricFamily` + ProtoFmt = ProtoType + "; proto=" + ProtoProtocol + ";" + + // The Content-Type values for the different wire protocols. + FmtText Format = `text/plain; version=` + TextVersion + FmtProtoDelim Format = ProtoFmt + ` encoding=delimited` + FmtProtoText Format = ProtoFmt + ` encoding=text` + FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text` + FmtJSON2 Format = `application/json; version=0.0.2` +) + +const ( + hdrContentType = "Content-Type" + hdrAccept = "Accept" +) diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz.go new file mode 100644 index 000000000000..14f920146921 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz.go @@ -0,0 +1,36 @@ +// Copyright 2014 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Build only when actually fuzzing +// +build gofuzz + +package expfmt + +import "bytes" + +// Fuzz text metric parser with with github.com/dvyukov/go-fuzz: +// +// go-fuzz-build github.com/prometheus/client_golang/text +// go-fuzz -bin text-fuzz.zip -workdir fuzz +// +// Further input samples should go in the folder fuzz/corpus. +func Fuzz(in []byte) int { + parser := TextParser{} + _, err := parser.TextToMetricFamilies(bytes.NewReader(in)) + + if err != nil { + return 0 + } + + return 1 +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_0 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_0 new file mode 100644 index 000000000000..139597f9cb07 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_0 @@ -0,0 +1,2 @@ + + diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_1 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_1 new file mode 100644 index 000000000000..2ae8706797b3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_1 @@ -0,0 +1,6 @@ + +minimal_metric 1.234 +another_metric -3e3 103948 +# Even that: +no_labels{} 3 +# HELP line for non-existing metric will be ignored. diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_2 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_2 new file mode 100644 index 000000000000..5c351db36d3c --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_2 @@ -0,0 +1,12 @@ + +# A normal comment. +# +# TYPE name counter +name{labelname="val1",basename="basevalue"} NaN +name {labelname="val2",basename="base\"v\\al\nue"} 0.23 1234567890 +# HELP name two-line\n doc str\\ing + + # HELP name2 doc str"ing 2 + # TYPE name2 gauge +name2{labelname="val2" ,basename = "basevalue2" } +Inf 54321 +name2{ labelname = "val1" , }-Inf diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_3 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_3 new file mode 100644 index 000000000000..0b3c345aa9c4 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_3 @@ -0,0 +1,22 @@ + +# TYPE my_summary summary +my_summary{n1="val1",quantile="0.5"} 110 +decoy -1 -2 +my_summary{n1="val1",quantile="0.9"} 140 1 +my_summary_count{n1="val1"} 42 +# Latest timestamp wins in case of a summary. +my_summary_sum{n1="val1"} 4711 2 +fake_sum{n1="val1"} 2001 +# TYPE another_summary summary +another_summary_count{n2="val2",n1="val1"} 20 +my_summary_count{n2="val2",n1="val1"} 5 5 +another_summary{n1="val1",n2="val2",quantile=".3"} -1.2 +my_summary_sum{n1="val2"} 08 15 +my_summary{n1="val3", quantile="0.2"} 4711 + my_summary{n1="val1",n2="val2",quantile="-12.34",} NaN +# some +# funny comments +# HELP +# HELP +# HELP my_summary +# HELP my_summary diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_4 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_4 new file mode 100644 index 000000000000..bde0a387aa2a --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_4 @@ -0,0 +1,10 @@ + +# HELP request_duration_microseconds The response latency. +# TYPE request_duration_microseconds histogram +request_duration_microseconds_bucket{le="100"} 123 +request_duration_microseconds_bucket{le="120"} 412 +request_duration_microseconds_bucket{le="144"} 592 +request_duration_microseconds_bucket{le="172.8"} 1524 +request_duration_microseconds_bucket{le="+Inf"} 2693 +request_duration_microseconds_sum 1.7560473e+06 +request_duration_microseconds_count 2693 diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_0 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_0 new file mode 100644 index 000000000000..4c67f9a198a8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_0 @@ -0,0 +1 @@ +bla 3.14 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_1 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_1 new file mode 100644 index 000000000000..b853478ee2f5 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_1 @@ -0,0 +1 @@ +metric{label="\t"} 3.14 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_10 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_10 new file mode 100644 index 000000000000..b5fe5f5a68cd --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_10 @@ -0,0 +1 @@ +metric{label="bla"} 3.14 2 3 diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_11 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_11 new file mode 100644 index 000000000000..57c7fbc0bc40 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_11 @@ -0,0 +1 @@ +metric{label="bla"} blubb diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_12 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_12 new file mode 100644 index 000000000000..0a9df79a1e67 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_12 @@ -0,0 +1,3 @@ + +# HELP metric one +# HELP metric two diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_13 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_13 new file mode 100644 index 000000000000..5bc7427813e1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_13 @@ -0,0 +1,3 @@ + +# TYPE metric counter +# TYPE metric untyped diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_14 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_14 new file mode 100644 index 000000000000..a9a24265b295 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_14 @@ -0,0 +1,3 @@ + +metric 4.12 +# TYPE metric counter diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_15 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_15 new file mode 100644 index 000000000000..7e95ca8f4c1d --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_15 @@ -0,0 +1,2 @@ + +# TYPE metric bla diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_16 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_16 new file mode 100644 index 000000000000..7825f8887233 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_16 @@ -0,0 +1,2 @@ + +# TYPE met-ric diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_17 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_17 new file mode 100644 index 000000000000..8f35cae0cf09 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_17 @@ -0,0 +1 @@ +@invalidmetric{label="bla"} 3.14 2 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_18 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_18 new file mode 100644 index 000000000000..7ca2cc268b0b --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_18 @@ -0,0 +1 @@ +{label="bla"} 3.14 2 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_19 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_19 new file mode 100644 index 000000000000..7a6ccc0dd47c --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_19 @@ -0,0 +1,3 @@ + +# TYPE metric histogram +metric_bucket{le="bla"} 3.14 diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_2 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_2 new file mode 100644 index 000000000000..726d0017cb06 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_2 @@ -0,0 +1,3 @@ + +metric{label="new +line"} 3.14 diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_3 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_3 new file mode 100644 index 000000000000..6aa9e3081409 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_3 @@ -0,0 +1 @@ +metric{@="bla"} 3.14 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_4 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_4 new file mode 100644 index 000000000000..d112cb902526 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_4 @@ -0,0 +1 @@ +metric{__name__="bla"} 3.14 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_5 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_5 new file mode 100644 index 000000000000..b34554a8d6bd --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_5 @@ -0,0 +1 @@ +metric{label+="bla"} 3.14 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_6 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_6 new file mode 100644 index 000000000000..c4d7df3d1110 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_6 @@ -0,0 +1 @@ +metric{label=bla} 3.14 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_7 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_7 new file mode 100644 index 000000000000..97eafc4a6532 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_7 @@ -0,0 +1,3 @@ + +# TYPE metric summary +metric{quantile="bla"} 3.14 diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_8 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_8 new file mode 100644 index 000000000000..fc706496b7cd --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_8 @@ -0,0 +1 @@ +metric{label="bla"+} 3.14 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_9 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_9 new file mode 100644 index 000000000000..57b4879c0598 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_9 @@ -0,0 +1 @@ +metric{label="bla"} 3.14 2.72 diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/minimal b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/minimal new file mode 100644 index 000000000000..be1e6a369ddb --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/fuzz/corpus/minimal @@ -0,0 +1 @@ +m{} 0 diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/json_decode.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/json_decode.go new file mode 100644 index 000000000000..67e3a0d4d65e --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/json_decode.go @@ -0,0 +1,162 @@ +// Copyright 2015 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expfmt + +import ( + "encoding/json" + "fmt" + "io" + "sort" + + "github.com/golang/protobuf/proto" + dto "github.com/prometheus/client_model/go" + + "github.com/prometheus/common/model" +) + +type json2Decoder struct { + dec *json.Decoder + fams []*dto.MetricFamily +} + +func newJSON2Decoder(r io.Reader) Decoder { + return &json2Decoder{ + dec: json.NewDecoder(r), + } +} + +type histogram002 struct { + Labels model.LabelSet `json:"labels"` + Values map[string]float64 `json:"value"` +} + +type counter002 struct { + Labels model.LabelSet `json:"labels"` + Value float64 `json:"value"` +} + +func protoLabelSet(base, ext model.LabelSet) []*dto.LabelPair { + labels := base.Clone().Merge(ext) + delete(labels, model.MetricNameLabel) + + names := make([]string, 0, len(labels)) + for ln := range labels { + names = append(names, string(ln)) + } + sort.Strings(names) + + pairs := make([]*dto.LabelPair, 0, len(labels)) + + for _, ln := range names { + lv := labels[model.LabelName(ln)] + + pairs = append(pairs, &dto.LabelPair{ + Name: proto.String(ln), + Value: proto.String(string(lv)), + }) + } + + return pairs +} + +func (d *json2Decoder) more() error { + var entities []struct { + BaseLabels model.LabelSet `json:"baseLabels"` + Docstring string `json:"docstring"` + Metric struct { + Type string `json:"type"` + Values json.RawMessage `json:"value"` + } `json:"metric"` + } + + if err := d.dec.Decode(&entities); err != nil { + return err + } + for _, e := range entities { + f := &dto.MetricFamily{ + Name: proto.String(string(e.BaseLabels[model.MetricNameLabel])), + Help: proto.String(e.Docstring), + Type: dto.MetricType_UNTYPED.Enum(), + Metric: []*dto.Metric{}, + } + + d.fams = append(d.fams, f) + + switch e.Metric.Type { + case "counter", "gauge": + var values []counter002 + + if err := json.Unmarshal(e.Metric.Values, &values); err != nil { + return fmt.Errorf("could not extract %s value: %s", e.Metric.Type, err) + } + + for _, ctr := range values { + f.Metric = append(f.Metric, &dto.Metric{ + Label: protoLabelSet(e.BaseLabels, ctr.Labels), + Untyped: &dto.Untyped{ + Value: proto.Float64(ctr.Value), + }, + }) + } + + case "histogram": + var values []histogram002 + + if err := json.Unmarshal(e.Metric.Values, &values); err != nil { + return fmt.Errorf("could not extract %s value: %s", e.Metric.Type, err) + } + + for _, hist := range values { + quants := make([]string, 0, len(values)) + for q := range hist.Values { + quants = append(quants, q) + } + + sort.Strings(quants) + + for _, q := range quants { + value := hist.Values[q] + // The correct label is "quantile" but to not break old expressions + // this remains "percentile" + hist.Labels["percentile"] = model.LabelValue(q) + + f.Metric = append(f.Metric, &dto.Metric{ + Label: protoLabelSet(e.BaseLabels, hist.Labels), + Untyped: &dto.Untyped{ + Value: proto.Float64(value), + }, + }) + } + } + + default: + return fmt.Errorf("unknown metric type %q", e.Metric.Type) + } + } + return nil +} + +// Decode implements the Decoder interface. +func (d *json2Decoder) Decode(v *dto.MetricFamily) error { + if len(d.fams) == 0 { + if err := d.more(); err != nil { + return err + } + } + + *v = *d.fams[0] + d.fams = d.fams[1:] + + return nil +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/json_decode_test.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/json_decode_test.go new file mode 100644 index 000000000000..c98ea29e1768 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/json_decode_test.go @@ -0,0 +1,124 @@ +// Copyright 2015 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expfmt + +import ( + "os" + "reflect" + "testing" + + "github.com/golang/protobuf/proto" + dto "github.com/prometheus/client_model/go" +) + +func TestJSON2Decode(t *testing.T) { + f, err := os.Open("testdata/json2") + if err != nil { + t.Fatal(err) + } + defer f.Close() + + dec := newJSON2Decoder(f) + + var v1 dto.MetricFamily + if err := dec.Decode(&v1); err != nil { + t.Fatal(err) + } + + exp1 := dto.MetricFamily{ + Type: dto.MetricType_UNTYPED.Enum(), + Help: proto.String("RPC calls."), + Name: proto.String("rpc_calls_total"), + Metric: []*dto.Metric{ + { + Label: []*dto.LabelPair{ + { + Name: proto.String("job"), + Value: proto.String("batch_job"), + }, { + Name: proto.String("service"), + Value: proto.String("zed"), + }, + }, + Untyped: &dto.Untyped{ + Value: proto.Float64(25), + }, + }, + { + Label: []*dto.LabelPair{ + { + Name: proto.String("job"), + Value: proto.String("batch_job"), + }, { + Name: proto.String("service"), + Value: proto.String("bar"), + }, + }, + Untyped: &dto.Untyped{ + Value: proto.Float64(24), + }, + }, + }, + } + + if !reflect.DeepEqual(v1, exp1) { + t.Fatalf("Expected %v, got %v", exp1, v1) + } + + var v2 dto.MetricFamily + if err := dec.Decode(&v2); err != nil { + t.Fatal(err) + } + + exp2 := dto.MetricFamily{ + Type: dto.MetricType_UNTYPED.Enum(), + Help: proto.String("RPC latency."), + Name: proto.String("rpc_latency_microseconds"), + Metric: []*dto.Metric{ + { + Label: []*dto.LabelPair{ + { + Name: proto.String("percentile"), + Value: proto.String("0.010000"), + }, { + Name: proto.String("service"), + Value: proto.String("foo"), + }, + }, + Untyped: &dto.Untyped{ + Value: proto.Float64(15), + }, + }, + { + Label: []*dto.LabelPair{ + { + Name: proto.String("percentile"), + Value: proto.String("0.990000"), + }, { + Name: proto.String("service"), + Value: proto.String("foo"), + }, + }, + Untyped: &dto.Untyped{ + Value: proto.Float64(17), + }, + }, + }, + } + + if !reflect.DeepEqual(v2, exp2) { + t.Fatalf("Expected %v, got %v", exp2, v2) + } + +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/json2 b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/json2 new file mode 100644 index 000000000000..b914c9386595 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/json2 @@ -0,0 +1,46 @@ +[ + { + "baseLabels": { + "__name__": "rpc_calls_total", + "job": "batch_job" + }, + "docstring": "RPC calls.", + "metric": { + "type": "counter", + "value": [ + { + "labels": { + "service": "zed" + }, + "value": 25 + }, + { + "labels": { + "service": "bar" + }, + "value": 24 + } + ] + } + }, + { + "baseLabels": { + "__name__": "rpc_latency_microseconds" + }, + "docstring": "RPC latency.", + "metric": { + "type": "histogram", + "value": [ + { + "labels": { + "service": "foo" + }, + "value": { + "0.010000": 15, + "0.990000": 17 + } + } + ] + } + } +] diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf new file mode 100644 index 000000000000..d5aae5091508 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf @@ -0,0 +1,516 @@ +fc08 0a22 6874 7470 5f72 6571 7565 7374 +5f64 7572 6174 696f 6e5f 6d69 6372 6f73 +6563 6f6e 6473 122b 5468 6520 4854 5450 +2072 6571 7565 7374 206c 6174 656e 6369 +6573 2069 6e20 6d69 6372 6f73 6563 6f6e +6473 2e18 0222 570a 0c0a 0768 616e 646c +6572 1201 2f22 4708 0011 0000 0000 0000 +0000 1a12 0900 0000 0000 00e0 3f11 0000 +0000 0000 0000 1a12 09cd cccc cccc ccec +3f11 0000 0000 0000 0000 1a12 09ae 47e1 +7a14 aeef 3f11 0000 0000 0000 0000 225d +0a12 0a07 6861 6e64 6c65 7212 072f 616c +6572 7473 2247 0800 1100 0000 0000 0000 +001a 1209 0000 0000 0000 e03f 1100 0000 +0000 0000 001a 1209 cdcc cccc cccc ec3f +1100 0000 0000 0000 001a 1209 ae47 e17a +14ae ef3f 1100 0000 0000 0000 0022 620a +170a 0768 616e 646c 6572 120c 2f61 7069 +2f6d 6574 7269 6373 2247 0800 1100 0000 +0000 0000 001a 1209 0000 0000 0000 e03f +1100 0000 0000 0000 001a 1209 cdcc cccc +cccc ec3f 1100 0000 0000 0000 001a 1209 +ae47 e17a 14ae ef3f 1100 0000 0000 0000 +0022 600a 150a 0768 616e 646c 6572 120a +2f61 7069 2f71 7565 7279 2247 0800 1100 +0000 0000 0000 001a 1209 0000 0000 0000 +e03f 1100 0000 0000 0000 001a 1209 cdcc +cccc cccc ec3f 1100 0000 0000 0000 001a +1209 ae47 e17a 14ae ef3f 1100 0000 0000 +0000 0022 660a 1b0a 0768 616e 646c 6572 +1210 2f61 7069 2f71 7565 7279 5f72 616e +6765 2247 0800 1100 0000 0000 0000 001a +1209 0000 0000 0000 e03f 1100 0000 0000 +0000 001a 1209 cdcc cccc cccc ec3f 1100 +0000 0000 0000 001a 1209 ae47 e17a 14ae +ef3f 1100 0000 0000 0000 0022 620a 170a +0768 616e 646c 6572 120c 2f61 7069 2f74 +6172 6765 7473 2247 0800 1100 0000 0000 +0000 001a 1209 0000 0000 0000 e03f 1100 +0000 0000 0000 001a 1209 cdcc cccc cccc +ec3f 1100 0000 0000 0000 001a 1209 ae47 +e17a 14ae ef3f 1100 0000 0000 0000 0022 +600a 150a 0768 616e 646c 6572 120a 2f63 +6f6e 736f 6c65 732f 2247 0800 1100 0000 +0000 0000 001a 1209 0000 0000 0000 e03f +1100 0000 0000 0000 001a 1209 cdcc cccc +cccc ec3f 1100 0000 0000 0000 001a 1209 +ae47 e17a 14ae ef3f 1100 0000 0000 0000 +0022 5c0a 110a 0768 616e 646c 6572 1206 +2f67 7261 7068 2247 0800 1100 0000 0000 +0000 001a 1209 0000 0000 0000 e03f 1100 +0000 0000 0000 001a 1209 cdcc cccc cccc +ec3f 1100 0000 0000 0000 001a 1209 ae47 +e17a 14ae ef3f 1100 0000 0000 0000 0022 +5b0a 100a 0768 616e 646c 6572 1205 2f68 +6561 7022 4708 0011 0000 0000 0000 0000 +1a12 0900 0000 0000 00e0 3f11 0000 0000 +0000 0000 1a12 09cd cccc cccc ccec 3f11 +0000 0000 0000 0000 1a12 09ae 47e1 7a14 +aeef 3f11 0000 0000 0000 0000 225e 0a13 +0a07 6861 6e64 6c65 7212 082f 7374 6174 +6963 2f22 4708 0011 0000 0000 0000 0000 +1a12 0900 0000 0000 00e0 3f11 0000 0000 +0000 0000 1a12 09cd cccc cccc ccec 3f11 +0000 0000 0000 0000 1a12 09ae 47e1 7a14 +aeef 3f11 0000 0000 0000 0000 2260 0a15 +0a07 6861 6e64 6c65 7212 0a70 726f 6d65 +7468 6575 7322 4708 3b11 5b8f c2f5 083f +f440 1a12 0900 0000 0000 00e0 3f11 e17a +14ae c7af 9340 1a12 09cd cccc cccc ccec +3f11 2fdd 2406 81f0 9640 1a12 09ae 47e1 +7a14 aeef 3f11 3d0a d7a3 b095 a740 e608 +0a17 6874 7470 5f72 6571 7565 7374 5f73 +697a 655f 6279 7465 7312 2054 6865 2048 +5454 5020 7265 7175 6573 7420 7369 7a65 +7320 696e 2062 7974 6573 2e18 0222 570a +0c0a 0768 616e 646c 6572 1201 2f22 4708 +0011 0000 0000 0000 0000 1a12 0900 0000 +0000 00e0 3f11 0000 0000 0000 0000 1a12 +09cd cccc cccc ccec 3f11 0000 0000 0000 +0000 1a12 09ae 47e1 7a14 aeef 3f11 0000 +0000 0000 0000 225d 0a12 0a07 6861 6e64 +6c65 7212 072f 616c 6572 7473 2247 0800 +1100 0000 0000 0000 001a 1209 0000 0000 +0000 e03f 1100 0000 0000 0000 001a 1209 +cdcc cccc cccc ec3f 1100 0000 0000 0000 +001a 1209 ae47 e17a 14ae ef3f 1100 0000 +0000 0000 0022 620a 170a 0768 616e 646c +6572 120c 2f61 7069 2f6d 6574 7269 6373 +2247 0800 1100 0000 0000 0000 001a 1209 +0000 0000 0000 e03f 1100 0000 0000 0000 +001a 1209 cdcc cccc cccc ec3f 1100 0000 +0000 0000 001a 1209 ae47 e17a 14ae ef3f +1100 0000 0000 0000 0022 600a 150a 0768 +616e 646c 6572 120a 2f61 7069 2f71 7565 +7279 2247 0800 1100 0000 0000 0000 001a +1209 0000 0000 0000 e03f 1100 0000 0000 +0000 001a 1209 cdcc cccc cccc ec3f 1100 +0000 0000 0000 001a 1209 ae47 e17a 14ae +ef3f 1100 0000 0000 0000 0022 660a 1b0a +0768 616e 646c 6572 1210 2f61 7069 2f71 +7565 7279 5f72 616e 6765 2247 0800 1100 +0000 0000 0000 001a 1209 0000 0000 0000 +e03f 1100 0000 0000 0000 001a 1209 cdcc +cccc cccc ec3f 1100 0000 0000 0000 001a +1209 ae47 e17a 14ae ef3f 1100 0000 0000 +0000 0022 620a 170a 0768 616e 646c 6572 +120c 2f61 7069 2f74 6172 6765 7473 2247 +0800 1100 0000 0000 0000 001a 1209 0000 +0000 0000 e03f 1100 0000 0000 0000 001a +1209 cdcc cccc cccc ec3f 1100 0000 0000 +0000 001a 1209 ae47 e17a 14ae ef3f 1100 +0000 0000 0000 0022 600a 150a 0768 616e +646c 6572 120a 2f63 6f6e 736f 6c65 732f +2247 0800 1100 0000 0000 0000 001a 1209 +0000 0000 0000 e03f 1100 0000 0000 0000 +001a 1209 cdcc cccc cccc ec3f 1100 0000 +0000 0000 001a 1209 ae47 e17a 14ae ef3f +1100 0000 0000 0000 0022 5c0a 110a 0768 +616e 646c 6572 1206 2f67 7261 7068 2247 +0800 1100 0000 0000 0000 001a 1209 0000 +0000 0000 e03f 1100 0000 0000 0000 001a +1209 cdcc cccc cccc ec3f 1100 0000 0000 +0000 001a 1209 ae47 e17a 14ae ef3f 1100 +0000 0000 0000 0022 5b0a 100a 0768 616e +646c 6572 1205 2f68 6561 7022 4708 0011 +0000 0000 0000 0000 1a12 0900 0000 0000 +00e0 3f11 0000 0000 0000 0000 1a12 09cd +cccc cccc ccec 3f11 0000 0000 0000 0000 +1a12 09ae 47e1 7a14 aeef 3f11 0000 0000 +0000 0000 225e 0a13 0a07 6861 6e64 6c65 +7212 082f 7374 6174 6963 2f22 4708 0011 +0000 0000 0000 0000 1a12 0900 0000 0000 +00e0 3f11 0000 0000 0000 0000 1a12 09cd +cccc cccc ccec 3f11 0000 0000 0000 0000 +1a12 09ae 47e1 7a14 aeef 3f11 0000 0000 +0000 0000 2260 0a15 0a07 6861 6e64 6c65 +7212 0a70 726f 6d65 7468 6575 7322 4708 +3b11 0000 0000 40c4 d040 1a12 0900 0000 +0000 00e0 3f11 0000 0000 0030 7240 1a12 +09cd cccc cccc ccec 3f11 0000 0000 0030 +7240 1a12 09ae 47e1 7a14 aeef 3f11 0000 +0000 0030 7240 7c0a 1368 7474 705f 7265 +7175 6573 7473 5f74 6f74 616c 1223 546f +7461 6c20 6e75 6d62 6572 206f 6620 4854 +5450 2072 6571 7565 7374 7320 6d61 6465 +2e18 0022 3e0a 0b0a 0463 6f64 6512 0332 +3030 0a15 0a07 6861 6e64 6c65 7212 0a70 +726f 6d65 7468 6575 730a 0d0a 066d 6574 +686f 6412 0367 6574 1a09 0900 0000 0000 +804d 40e8 080a 1868 7474 705f 7265 7370 +6f6e 7365 5f73 697a 655f 6279 7465 7312 +2154 6865 2048 5454 5020 7265 7370 6f6e +7365 2073 697a 6573 2069 6e20 6279 7465 +732e 1802 2257 0a0c 0a07 6861 6e64 6c65 +7212 012f 2247 0800 1100 0000 0000 0000 +001a 1209 0000 0000 0000 e03f 1100 0000 +0000 0000 001a 1209 cdcc cccc cccc ec3f +1100 0000 0000 0000 001a 1209 ae47 e17a +14ae ef3f 1100 0000 0000 0000 0022 5d0a +120a 0768 616e 646c 6572 1207 2f61 6c65 +7274 7322 4708 0011 0000 0000 0000 0000 +1a12 0900 0000 0000 00e0 3f11 0000 0000 +0000 0000 1a12 09cd cccc cccc ccec 3f11 +0000 0000 0000 0000 1a12 09ae 47e1 7a14 +aeef 3f11 0000 0000 0000 0000 2262 0a17 +0a07 6861 6e64 6c65 7212 0c2f 6170 692f +6d65 7472 6963 7322 4708 0011 0000 0000 +0000 0000 1a12 0900 0000 0000 00e0 3f11 +0000 0000 0000 0000 1a12 09cd cccc cccc +ccec 3f11 0000 0000 0000 0000 1a12 09ae +47e1 7a14 aeef 3f11 0000 0000 0000 0000 +2260 0a15 0a07 6861 6e64 6c65 7212 0a2f +6170 692f 7175 6572 7922 4708 0011 0000 +0000 0000 0000 1a12 0900 0000 0000 00e0 +3f11 0000 0000 0000 0000 1a12 09cd cccc +cccc ccec 3f11 0000 0000 0000 0000 1a12 +09ae 47e1 7a14 aeef 3f11 0000 0000 0000 +0000 2266 0a1b 0a07 6861 6e64 6c65 7212 +102f 6170 692f 7175 6572 795f 7261 6e67 +6522 4708 0011 0000 0000 0000 0000 1a12 +0900 0000 0000 00e0 3f11 0000 0000 0000 +0000 1a12 09cd cccc cccc ccec 3f11 0000 +0000 0000 0000 1a12 09ae 47e1 7a14 aeef +3f11 0000 0000 0000 0000 2262 0a17 0a07 +6861 6e64 6c65 7212 0c2f 6170 692f 7461 +7267 6574 7322 4708 0011 0000 0000 0000 +0000 1a12 0900 0000 0000 00e0 3f11 0000 +0000 0000 0000 1a12 09cd cccc cccc ccec +3f11 0000 0000 0000 0000 1a12 09ae 47e1 +7a14 aeef 3f11 0000 0000 0000 0000 2260 +0a15 0a07 6861 6e64 6c65 7212 0a2f 636f +6e73 6f6c 6573 2f22 4708 0011 0000 0000 +0000 0000 1a12 0900 0000 0000 00e0 3f11 +0000 0000 0000 0000 1a12 09cd cccc cccc +ccec 3f11 0000 0000 0000 0000 1a12 09ae +47e1 7a14 aeef 3f11 0000 0000 0000 0000 +225c 0a11 0a07 6861 6e64 6c65 7212 062f +6772 6170 6822 4708 0011 0000 0000 0000 +0000 1a12 0900 0000 0000 00e0 3f11 0000 +0000 0000 0000 1a12 09cd cccc cccc ccec +3f11 0000 0000 0000 0000 1a12 09ae 47e1 +7a14 aeef 3f11 0000 0000 0000 0000 225b +0a10 0a07 6861 6e64 6c65 7212 052f 6865 +6170 2247 0800 1100 0000 0000 0000 001a +1209 0000 0000 0000 e03f 1100 0000 0000 +0000 001a 1209 cdcc cccc cccc ec3f 1100 +0000 0000 0000 001a 1209 ae47 e17a 14ae +ef3f 1100 0000 0000 0000 0022 5e0a 130a +0768 616e 646c 6572 1208 2f73 7461 7469 +632f 2247 0800 1100 0000 0000 0000 001a +1209 0000 0000 0000 e03f 1100 0000 0000 +0000 001a 1209 cdcc cccc cccc ec3f 1100 +0000 0000 0000 001a 1209 ae47 e17a 14ae +ef3f 1100 0000 0000 0000 0022 600a 150a +0768 616e 646c 6572 120a 7072 6f6d 6574 +6865 7573 2247 083b 1100 0000 00e0 b4fc +401a 1209 0000 0000 0000 e03f 1100 0000 +0000 349f 401a 1209 cdcc cccc cccc ec3f +1100 0000 0000 08a0 401a 1209 ae47 e17a +14ae ef3f 1100 0000 0000 0aa0 405c 0a19 +7072 6f63 6573 735f 6370 755f 7365 636f +6e64 735f 746f 7461 6c12 3054 6f74 616c +2075 7365 7220 616e 6420 7379 7374 656d +2043 5055 2074 696d 6520 7370 656e 7420 +696e 2073 6563 6f6e 6473 2e18 0022 0b1a +0909 a470 3d0a d7a3 d03f 4f0a 1270 726f +6365 7373 5f67 6f72 6f75 7469 6e65 7312 +2a4e 756d 6265 7220 6f66 2067 6f72 6f75 +7469 6e65 7320 7468 6174 2063 7572 7265 +6e74 6c79 2065 7869 7374 2e18 0122 0b12 +0909 0000 0000 0000 5140 4a0a 0f70 726f +6365 7373 5f6d 6178 5f66 6473 1228 4d61 +7869 6d75 6d20 6e75 6d62 6572 206f 6620 +6f70 656e 2066 696c 6520 6465 7363 7269 +7074 6f72 732e 1801 220b 1209 0900 0000 +0000 00c0 4043 0a10 7072 6f63 6573 735f +6f70 656e 5f66 6473 1220 4e75 6d62 6572 +206f 6620 6f70 656e 2066 696c 6520 6465 +7363 7269 7074 6f72 732e 1801 220b 1209 +0900 0000 0000 003d 404e 0a1d 7072 6f63 +6573 735f 7265 7369 6465 6e74 5f6d 656d +6f72 795f 6279 7465 7312 1e52 6573 6964 +656e 7420 6d65 6d6f 7279 2073 697a 6520 +696e 2062 7974 6573 2e18 0122 0b12 0909 +0000 0000 004b 8841 630a 1a70 726f 6365 +7373 5f73 7461 7274 5f74 696d 655f 7365 +636f 6e64 7312 3653 7461 7274 2074 696d +6520 6f66 2074 6865 2070 726f 6365 7373 +2073 696e 6365 2075 6e69 7820 6570 6f63 +6820 696e 2073 6563 6f6e 6473 2e18 0122 +0b12 0909 3d0a 172d e831 d541 4c0a 1c70 +726f 6365 7373 5f76 6972 7475 616c 5f6d +656d 6f72 795f 6279 7465 7312 1d56 6972 +7475 616c 206d 656d 6f72 7920 7369 7a65 +2069 6e20 6279 7465 732e 1801 220b 1209 +0900 0000 0020 12c0 415f 0a27 7072 6f6d +6574 6865 7573 5f64 6e73 5f73 645f 6c6f +6f6b 7570 5f66 6169 6c75 7265 735f 746f +7461 6c12 2554 6865 206e 756d 6265 7220 +6f66 2044 4e53 2d53 4420 6c6f 6f6b 7570 +2066 6169 6c75 7265 732e 1800 220b 1a09 +0900 0000 0000 0000 004f 0a1f 7072 6f6d +6574 6865 7573 5f64 6e73 5f73 645f 6c6f +6f6b 7570 735f 746f 7461 6c12 1d54 6865 +206e 756d 6265 7220 6f66 2044 4e53 2d53 +4420 6c6f 6f6b 7570 732e 1800 220b 1a09 +0900 0000 0000 0008 40cf 010a 2a70 726f +6d65 7468 6575 735f 6576 616c 7561 746f +725f 6475 7261 7469 6f6e 5f6d 696c 6c69 +7365 636f 6e64 7312 2c54 6865 2064 7572 +6174 696f 6e20 666f 7220 616c 6c20 6576 +616c 7561 7469 6f6e 7320 746f 2065 7865 +6375 7465 2e18 0222 7122 6f08 0b11 0000 +0000 0000 2240 1a12 097b 14ae 47e1 7a84 +3f11 0000 0000 0000 0000 1a12 099a 9999 +9999 99a9 3f11 0000 0000 0000 0000 1a12 +0900 0000 0000 00e0 3f11 0000 0000 0000 +0000 1a12 09cd cccc cccc ccec 3f11 0000 +0000 0000 f03f 1a12 09ae 47e1 7a14 aeef +3f11 0000 0000 0000 f03f a301 0a39 7072 +6f6d 6574 6865 7573 5f6c 6f63 616c 5f73 +746f 7261 6765 5f63 6865 636b 706f 696e +745f 6475 7261 7469 6f6e 5f6d 696c 6c69 +7365 636f 6e64 7312 5754 6865 2064 7572 +6174 696f 6e20 2869 6e20 6d69 6c6c 6973 +6563 6f6e 6473 2920 6974 2074 6f6f 6b20 +746f 2063 6865 636b 706f 696e 7420 696e +2d6d 656d 6f72 7920 6d65 7472 6963 7320 +616e 6420 6865 6164 2063 6875 6e6b 732e +1801 220b 1209 0900 0000 0000 0000 00f2 +010a 2870 726f 6d65 7468 6575 735f 6c6f +6361 6c5f 7374 6f72 6167 655f 6368 756e +6b5f 6f70 735f 746f 7461 6c12 3354 6865 +2074 6f74 616c 206e 756d 6265 7220 6f66 +2063 6875 6e6b 206f 7065 7261 7469 6f6e +7320 6279 2074 6865 6972 2074 7970 652e +1800 221b 0a0e 0a04 7479 7065 1206 6372 +6561 7465 1a09 0900 0000 0000 b880 4022 +1c0a 0f0a 0474 7970 6512 0770 6572 7369 +7374 1a09 0900 0000 0000 c05b 4022 180a +0b0a 0474 7970 6512 0370 696e 1a09 0900 +0000 0000 807b 4022 1e0a 110a 0474 7970 +6512 0974 7261 6e73 636f 6465 1a09 0900 +0000 0000 a06b 4022 1a0a 0d0a 0474 7970 +6512 0575 6e70 696e 1a09 0900 0000 0000 +807b 40c4 010a 3c70 726f 6d65 7468 6575 +735f 6c6f 6361 6c5f 7374 6f72 6167 655f +696e 6465 7869 6e67 5f62 6174 6368 5f6c +6174 656e 6379 5f6d 696c 6c69 7365 636f +6e64 7312 3751 7561 6e74 696c 6573 2066 +6f72 2062 6174 6368 2069 6e64 6578 696e +6720 6c61 7465 6e63 6965 7320 696e 206d +696c 6c69 7365 636f 6e64 732e 1802 2249 +2247 0801 1100 0000 0000 0000 001a 1209 +0000 0000 0000 e03f 1100 0000 0000 0000 +001a 1209 cdcc cccc cccc ec3f 1100 0000 +0000 0000 001a 1209 ae47 e17a 14ae ef3f +1100 0000 0000 0000 00bf 010a 2d70 726f +6d65 7468 6575 735f 6c6f 6361 6c5f 7374 +6f72 6167 655f 696e 6465 7869 6e67 5f62 +6174 6368 5f73 697a 6573 1241 5175 616e +7469 6c65 7320 666f 7220 696e 6465 7869 +6e67 2062 6174 6368 2073 697a 6573 2028 +6e75 6d62 6572 206f 6620 6d65 7472 6963 +7320 7065 7220 6261 7463 6829 2e18 0222 +4922 4708 0111 0000 0000 0000 0040 1a12 +0900 0000 0000 00e0 3f11 0000 0000 0000 +0040 1a12 09cd cccc cccc ccec 3f11 0000 +0000 0000 0040 1a12 09ae 47e1 7a14 aeef +3f11 0000 0000 0000 0040 660a 3070 726f +6d65 7468 6575 735f 6c6f 6361 6c5f 7374 +6f72 6167 655f 696e 6465 7869 6e67 5f71 +7565 7565 5f63 6170 6163 6974 7912 2354 +6865 2063 6170 6163 6974 7920 6f66 2074 +6865 2069 6e64 6578 696e 6720 7175 6575 +652e 1801 220b 1209 0900 0000 0000 00d0 +406d 0a2e 7072 6f6d 6574 6865 7573 5f6c +6f63 616c 5f73 746f 7261 6765 5f69 6e64 +6578 696e 675f 7175 6575 655f 6c65 6e67 +7468 122c 5468 6520 6e75 6d62 6572 206f +6620 6d65 7472 6963 7320 7761 6974 696e +6720 746f 2062 6520 696e 6465 7865 642e +1801 220b 1209 0900 0000 0000 0000 0067 +0a2f 7072 6f6d 6574 6865 7573 5f6c 6f63 +616c 5f73 746f 7261 6765 5f69 6e67 6573 +7465 645f 7361 6d70 6c65 735f 746f 7461 +6c12 2554 6865 2074 6f74 616c 206e 756d +6265 7220 6f66 2073 616d 706c 6573 2069 +6e67 6573 7465 642e 1800 220b 1a09 0900 +0000 0080 27cd 40c3 010a 3770 726f 6d65 +7468 6575 735f 6c6f 6361 6c5f 7374 6f72 +6167 655f 696e 7661 6c69 645f 7072 656c +6f61 645f 7265 7175 6573 7473 5f74 6f74 +616c 1279 5468 6520 746f 7461 6c20 6e75 +6d62 6572 206f 6620 7072 656c 6f61 6420 +7265 7175 6573 7473 2072 6566 6572 7269 +6e67 2074 6f20 6120 6e6f 6e2d 6578 6973 +7465 6e74 2073 6572 6965 732e 2054 6869 +7320 6973 2061 6e20 696e 6469 6361 7469 +6f6e 206f 6620 6f75 7464 6174 6564 206c +6162 656c 2069 6e64 6578 6573 2e18 0022 +0b1a 0909 0000 0000 0000 0000 6f0a 2a70 +726f 6d65 7468 6575 735f 6c6f 6361 6c5f +7374 6f72 6167 655f 6d65 6d6f 7279 5f63 +6875 6e6b 6465 7363 7312 3254 6865 2063 +7572 7265 6e74 206e 756d 6265 7220 6f66 +2063 6875 6e6b 2064 6573 6372 6970 746f +7273 2069 6e20 6d65 6d6f 7279 2e18 0122 +0b12 0909 0000 0000 0020 8f40 9c01 0a26 +7072 6f6d 6574 6865 7573 5f6c 6f63 616c +5f73 746f 7261 6765 5f6d 656d 6f72 795f +6368 756e 6b73 1263 5468 6520 6375 7272 +656e 7420 6e75 6d62 6572 206f 6620 6368 +756e 6b73 2069 6e20 6d65 6d6f 7279 2c20 +6578 636c 7564 696e 6720 636c 6f6e 6564 +2063 6875 6e6b 7320 2869 2e65 2e20 6368 +756e 6b73 2077 6974 686f 7574 2061 2064 +6573 6372 6970 746f 7229 2e18 0122 0b12 +0909 0000 0000 00e8 8d40 600a 2670 726f +6d65 7468 6575 735f 6c6f 6361 6c5f 7374 +6f72 6167 655f 6d65 6d6f 7279 5f73 6572 +6965 7312 2754 6865 2063 7572 7265 6e74 +206e 756d 6265 7220 6f66 2073 6572 6965 +7320 696e 206d 656d 6f72 792e 1801 220b +1209 0900 0000 0000 807a 40b7 010a 3570 +726f 6d65 7468 6575 735f 6c6f 6361 6c5f +7374 6f72 6167 655f 7065 7273 6973 745f +6c61 7465 6e63 795f 6d69 6372 6f73 6563 +6f6e 6473 1231 4120 7375 6d6d 6172 7920 +6f66 206c 6174 656e 6369 6573 2066 6f72 +2070 6572 7369 7374 696e 6720 6561 6368 +2063 6875 6e6b 2e18 0222 4922 4708 6f11 +1c2f dd24 e68c cc40 1a12 0900 0000 0000 +00e0 3f11 8d97 6e12 8360 3e40 1a12 09cd +cccc cccc ccec 3f11 0ad7 a370 3d62 6b40 +1a12 09ae 47e1 7a14 aeef 3f11 7b14 ae47 +e1b6 7240 6a0a 2f70 726f 6d65 7468 6575 +735f 6c6f 6361 6c5f 7374 6f72 6167 655f +7065 7273 6973 745f 7175 6575 655f 6361 +7061 6369 7479 1228 5468 6520 746f 7461 +6c20 6361 7061 6369 7479 206f 6620 7468 +6520 7065 7273 6973 7420 7175 6575 652e +1801 220b 1209 0900 0000 0000 0090 407a +0a2d 7072 6f6d 6574 6865 7573 5f6c 6f63 +616c 5f73 746f 7261 6765 5f70 6572 7369 +7374 5f71 7565 7565 5f6c 656e 6774 6812 +3a54 6865 2063 7572 7265 6e74 206e 756d +6265 7220 6f66 2063 6875 6e6b 7320 7761 +6974 696e 6720 696e 2074 6865 2070 6572 +7369 7374 2071 7565 7565 2e18 0122 0b12 +0909 0000 0000 0000 0000 ac01 0a29 7072 +6f6d 6574 6865 7573 5f6c 6f63 616c 5f73 +746f 7261 6765 5f73 6572 6965 735f 6f70 +735f 746f 7461 6c12 3454 6865 2074 6f74 +616c 206e 756d 6265 7220 6f66 2073 6572 +6965 7320 6f70 6572 6174 696f 6e73 2062 +7920 7468 6569 7220 7479 7065 2e18 0022 +1b0a 0e0a 0474 7970 6512 0663 7265 6174 +651a 0909 0000 0000 0000 0040 222a 0a1d +0a04 7479 7065 1215 6d61 696e 7465 6e61 +6e63 655f 696e 5f6d 656d 6f72 791a 0909 +0000 0000 0000 1440 d601 0a2d 7072 6f6d +6574 6865 7573 5f6e 6f74 6966 6963 6174 +696f 6e73 5f6c 6174 656e 6379 5f6d 696c +6c69 7365 636f 6e64 7312 584c 6174 656e +6379 2071 7561 6e74 696c 6573 2066 6f72 +2073 656e 6469 6e67 2061 6c65 7274 206e +6f74 6966 6963 6174 696f 6e73 2028 6e6f +7420 696e 636c 7564 696e 6720 6472 6f70 +7065 6420 6e6f 7469 6669 6361 7469 6f6e +7329 2e18 0222 4922 4708 0011 0000 0000 +0000 0000 1a12 0900 0000 0000 00e0 3f11 +0000 0000 0000 0000 1a12 09cd cccc cccc +ccec 3f11 0000 0000 0000 0000 1a12 09ae +47e1 7a14 aeef 3f11 0000 0000 0000 0000 +680a 2770 726f 6d65 7468 6575 735f 6e6f +7469 6669 6361 7469 6f6e 735f 7175 6575 +655f 6361 7061 6369 7479 122e 5468 6520 +6361 7061 6369 7479 206f 6620 7468 6520 +616c 6572 7420 6e6f 7469 6669 6361 7469 +6f6e 7320 7175 6575 652e 1801 220b 1209 +0900 0000 0000 0059 4067 0a25 7072 6f6d +6574 6865 7573 5f6e 6f74 6966 6963 6174 +696f 6e73 5f71 7565 7565 5f6c 656e 6774 +6812 2f54 6865 206e 756d 6265 7220 6f66 +2061 6c65 7274 206e 6f74 6966 6963 6174 +696f 6e73 2069 6e20 7468 6520 7175 6575 +652e 1801 220b 1209 0900 0000 0000 0000 +009e 020a 3070 726f 6d65 7468 6575 735f +7275 6c65 5f65 7661 6c75 6174 696f 6e5f +6475 7261 7469 6f6e 5f6d 696c 6c69 7365 +636f 6e64 7312 2354 6865 2064 7572 6174 +696f 6e20 666f 7220 6120 7275 6c65 2074 +6f20 6578 6563 7574 652e 1802 2260 0a15 +0a09 7275 6c65 5f74 7970 6512 0861 6c65 +7274 696e 6722 4708 3711 0000 0000 0000 +2840 1a12 0900 0000 0000 00e0 3f11 0000 +0000 0000 0000 1a12 09cd cccc cccc ccec +3f11 0000 0000 0000 0000 1a12 09ae 47e1 +7a14 aeef 3f11 0000 0000 0000 0840 2261 +0a16 0a09 7275 6c65 5f74 7970 6512 0972 +6563 6f72 6469 6e67 2247 0837 1100 0000 +0000 002e 401a 1209 0000 0000 0000 e03f +1100 0000 0000 0000 001a 1209 cdcc cccc +cccc ec3f 1100 0000 0000 0000 001a 1209 +ae47 e17a 14ae ef3f 1100 0000 0000 0008 +4069 0a29 7072 6f6d 6574 6865 7573 5f72 +756c 655f 6576 616c 7561 7469 6f6e 5f66 +6169 6c75 7265 735f 746f 7461 6c12 2d54 +6865 2074 6f74 616c 206e 756d 6265 7220 +6f66 2072 756c 6520 6576 616c 7561 7469 +6f6e 2066 6169 6c75 7265 732e 1800 220b +1a09 0900 0000 0000 0000 0060 0a21 7072 +6f6d 6574 6865 7573 5f73 616d 706c 6573 +5f71 7565 7565 5f63 6170 6163 6974 7912 +2c43 6170 6163 6974 7920 6f66 2074 6865 +2071 7565 7565 2066 6f72 2075 6e77 7269 +7474 656e 2073 616d 706c 6573 2e18 0122 +0b12 0909 0000 0000 0000 b040 da01 0a1f +7072 6f6d 6574 6865 7573 5f73 616d 706c +6573 5f71 7565 7565 5f6c 656e 6774 6812 +a701 4375 7272 656e 7420 6e75 6d62 6572 +206f 6620 6974 656d 7320 696e 2074 6865 +2071 7565 7565 2066 6f72 2075 6e77 7269 +7474 656e 2073 616d 706c 6573 2e20 4561 +6368 2069 7465 6d20 636f 6d70 7269 7365 +7320 616c 6c20 7361 6d70 6c65 7320 6578 +706f 7365 6420 6279 206f 6e65 2074 6172 +6765 7420 6173 206f 6e65 206d 6574 7269 +6320 6661 6d69 6c79 2028 692e 652e 206d +6574 7269 6373 206f 6620 7468 6520 7361 +6d65 206e 616d 6529 2e18 0122 0b12 0909 +0000 0000 0000 0000 d902 0a29 7072 6f6d +6574 6865 7573 5f74 6172 6765 745f 696e +7465 7276 616c 5f6c 656e 6774 685f 7365 +636f 6e64 7312 2141 6374 7561 6c20 696e +7465 7276 616c 7320 6265 7477 6565 6e20 +7363 7261 7065 732e 1802 2282 010a 0f0a +0869 6e74 6572 7661 6c12 0331 3573 226f +0804 1100 0000 0000 804d 401a 1209 7b14 +ae47 e17a 843f 1100 0000 0000 002c 401a +1209 9a99 9999 9999 a93f 1100 0000 0000 +002c 401a 1209 0000 0000 0000 e03f 1100 +0000 0000 002e 401a 1209 cdcc cccc cccc +ec3f 1100 0000 0000 002e 401a 1209 ae47 +e17a 14ae ef3f 1100 0000 0000 002e 4022 +8101 0a0e 0a08 696e 7465 7276 616c 1202 +3173 226f 083a 1100 0000 0000 003c 401a +1209 7b14 ae47 e17a 843f 1100 0000 0000 +0000 001a 1209 9a99 9999 9999 a93f 1100 +0000 0000 0000 001a 1209 0000 0000 0000 +e03f 1100 0000 0000 0000 001a 1209 cdcc +cccc cccc ec3f 1100 0000 0000 00f0 3f1a +1209 ae47 e17a 14ae ef3f 1100 0000 0000 +00f0 3f \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf.gz b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf.gz new file mode 100644 index 000000000000..62fccb616501 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/protobuf.gz @@ -0,0 +1,129 @@ +1f8b 0808 efa0 c754 0003 7072 6f74 6f62 +7566 00ed 594d 8c1c c515 9eb1 8d3d 5b86 +6037 265e 8c4d ca03 c4bb ceee cc9a 9f58 +01cc f6ca 4424 041b 8837 21c8 24ed daee +9a99 cef6 1f55 d578 c7e4 b004 0e39 8088 +8448 048a 124b 4442 9110 e110 25b9 c54a +9072 01c5 9724 4a24 2472 413e 448a 8592 +1b87 bcea aeda eeea 99d9 3530 49a4 68e7 +b0bb 5355 fdde abf7 bef7 bdf7 7a3f 6ca0 +664f 88c4 61f4 8994 72e1 7829 23c2 8f23 +27f4 5d16 73ea c691 c7ad cf2d f628 fed2 +e2e2 c358 9dc3 0111 3472 7dca b11f e1f2 +d9d6 e496 e6a3 e86a b4a3 4722 2fa0 ccaa +b79b f737 6abb 6bea b3cf 9ac8 ff78 6fbe +bcf6 cedb f2f3 7763 ed8d fbff 766e cf1b +ff28 d69a df44 5621 7847 9bc0 2fc1 c727 +7e09 ed2d c45f dd26 89df 0ea9 60be 3b46 +1d67 d0f5 850e 94e9 008f b2fe f834 74d0 +8d85 865d 8506 8791 a84b ffa3 de12 8475 +e938 2352 f116 208c c701 e563 84d4 e368 +77a1 617b bbcb 48d2 1b9f f4d3 6857 21fd +aa76 8f92 647c c2bf 85ae 2b84 37da 5c40 +e6ba 6374 8de9 fc84 c590 0c3d 9aca f0de +bdfb f40b bffd 5763 fe9f 7659 8314 f0fb +9fbf 6897 35b4 dfbd 65fb d397 7f60 9735 +1c43 7f7e f5cd 975e b3df 6fa0 bd06 fb70 +ff1c 7596 fa82 720b 0f50 8edc cce8 263b +b0c9 339b 3cb3 c933 5afa ff2f cfc8 13f6 +5b17 ed01 0d73 cc1e d090 af99 1a60 ed3b +e8ba 32cd 7047 c482 04d6 cd8b f217 8ed2 +7089 321c 770c bae1 3824 1e6d 4dd6 9af7 +a29d 689b 1b7b d4da 7adb dcdc 085b d135 +68bb fc33 f6ac ad00 cd7d 13b9 b5ab 27ec +4b0d 34a9 b4f3 0470 45cb 2c77 b0c4 72f9 +ee26 cd7d 02ec 6cd2 dc26 cd7d 6ce1 ff73 +9a7b ef17 1f0e d2dc 1d3f 19a4 b9c6 f941 +9a43 e7ed c7d1 0d20 d5a5 9c3b 6e92 3a6a +2053 6437 9793 5dca 81ea c006 ccfb 5cd0 +101f 7ff8 6b58 f821 d04e 4223 2169 676d +8eab 3577 028d fd34 91dd dac5 f987 90a5 +8577 6316 a7c2 8f80 bf0e 9f5c 23cf 6215 +8b1e 11d8 4d19 0391 411f d315 9f8b d664 +bdb9 d352 b458 7bc4 7e00 5dab e585 64c5 +e9c0 9439 7582 acf8 611a 9618 3906 ab70 +c70f 28f6 2877 999f 8898 7153 d405 fb38 +daa5 45c9 f399 2c7c f2a3 c838 669f 4407 +b40c 6062 df03 cb9d 9086 31e4 79ce d437 +7d55 2de3 7c39 e3e9 124d 97c4 7de5 7b0b +2eda a7c5 018e 9870 a48f 7544 accf 9f92 +6bb9 dfc1 4040 0156 a741 6ae4 529c 46fe +0aa6 49ec f68c 88e4 3a8e a1bd b397 8efc +71e1 41b4 5feb 78d2 6722 2581 69f1 81af +e7ab 1b1a 8cad 0b0b 0e3a 5420 d2f1 22b0 +db73 8238 5e4e 13a7 43fc 2005 af28 24dd +2a6b 5611 a2fb 4e9e 9a3d 751f cecf 627d +56c3 47a3 ff21 f499 51f2 b5dc 03eb c8ad +c86b d87f a8a3 c325 81f4 4912 a404 025b +7e81 1104 bef6 f88c 94ad b770 2786 1c08 +02ac 9e82 25c0 6c0c 38a5 6e2a a82c b94f +34e3 c64e 95ba 4d99 6c4f ed91 e9f6 ac91 +e2af bc2c 3f3f 9bff 88f4 7079 7e90 1e2e +cfbf 5a47 5f28 5d28 885d 8827 871b 912e +75dc 1e75 9793 d88f c488 fb3d 6adc 6f2a +7b27 536c 4f63 1fd0 068e 94b7 2c64 0118 +6615 3654 5dce 9801 58d5 8353 69b4 5cc9 +925a ed83 3a9a 5ac7 4878 0432 50c7 f376 +6993 a8b4 58d9 2199 924c f97d a92f f1ef +332c fa49 d66e dd88 3e85 b6c9 2fd6 7697 +5122 a88e faaf 57ed e67e 74ad dadc 0122 +38f0 8ade bd70 da6e 4eca 4e2d dbdd 9af8 +d15a 0ff6 94dd bc09 ca52 be33 21a0 6e73 +d9ce e9fd f3cb 7673 1ff4 6ff9 fe55 6964 +3efb 561d dd33 f2ce 7ee4 01bb 455d 6789 +08b7 e7e4 6fc5 fa66 6c8e 3e92 9248 00ff +f00c 78d9 49ac 1fac be48 2b9e 9330 fc32 +d486 fa58 aacf 6fea 68f6 4a6f 9175 a0d6 +8269 f69a c1b9 fd79 973a 5504 5623 08c2 +921f 991e b8c0 6071 cbd7 aa17 182c 6eb0 +d641 731b db0f 8d59 0a40 2409 717d d187 +061f 10a8 bf69 a65d bb48 76d8 44f8 453b +44ad 2b55 13d0 a82b 7a39 b50c fae1 2cf1 +85d4 0219 b7a4 9452 af9a 4f5d d45e 475b +17c6 10ea 399c 8449 60b2 6f35 abd4 11ac +9f29 b3e5 eaa1 77ec dfd5 d1d1 7514 010d +fa9e 9330 1ac4 c4ab 4e49 fd61 0ad5 d962 +5862 b443 1953 1726 388a a3d9 acec cb82 +092d 07e0 bb85 177b 3e98 2849 46fa c377 +73b2 9215 3a15 1ea4 8107 c9b0 4403 e5ac +8112 121b 8c6f de41 15be 8c5d 6495 e7d6 +6d59 ecf3 1e64 807f 4a8d 4096 76d9 d346 +70f0 0bf6 8fea e8b3 57a4 905b ee3a ca4a +1a66 a0c4 b841 ea49 37b9 411c 51cd b3c0 +d82d dad2 5fce fa30 47a6 02dc 58d8 396d +5877 e979 fbcc c6c6 e57e b70e 0d37 2edf +1d71 fdd5 73f6 afea e8ce 911a 14f9 9608 +aff4 df82 230b 98a7 6148 5896 7305 c149 +1a51 0f4a 0f50 023c 925d 5933 45bc 7b7f +fbdd 5bde 7fee 6d83 299e ff61 643d 73e6 +5e83 29a0 254d 8e2d 2d1b 4c91 95e8 5f32 +fbdb eb24 95b6 bb42 1453 05c6 ab74 a19e +18c6 16df b7cf ad43 aaa6 2a45 1677 ad0b +14cd 1910 930d 54d7 6aaf d7d1 f448 dd79 +6c4b b5f8 8ea1 ac91 23e0 6315 6360 e4e6 +6174 406d 5e1f 12e8 2768 44a0 7905 3e51 +005c 3bbb c7fe 9359 7ea2 58f8 1d45 007c +78d5 fcc6 83f9 2adc be5c 8638 8db2 f4c9 +de55 6043 0e54 a358 f634 3ac3 3c16 2709 +a498 7168 ad2a 8d67 a8eb 196d b379 ad0a +c65a c38a d1b0 6b0c 09f7 6376 17dd ba81 +2285 b0b6 598e 8629 50f0 1a0a ab1f 6f31 +ea2c 4b03 ea14 6df2 88ee f3e6 c1ee 1acb +272b 4db5 1c80 2732 8919 681a 996d 1029 +88c6 51e5 d1a9 613d c215 46a3 6137 09fa +7459 c304 0303 9967 aa68 7d22 15be 9175 +55f7 5426 a5d9 6159 9739 a678 66e4 c474 +061d 2c69 d24d 4005 5433 c72b 80ca f6b3 +10a4 d159 e60b c821 dd1d 98a1 7ed3 fe6b +dd98 c94c 0d0a 4daf d58f 0f90 952f 6868 +8268 843e fc45 c9f0 f238 76e3 3061 8017 +9ecd 5dba 5da1 2b09 140d 4fd2 0e14 439c +bfee c284 67df f246 0adc 0350 ebab 02a9 +9b2b 7559 9003 5887 1fd3 5518 ff65 8b11 +a75c b223 398a 81e7 d5ed d6e6 f183 0b6e +3628 eb7d 2042 2ace 5279 1597 9124 7f0b +fbdd 3acc 1e0d 7dc4 da7a e44e 0e43 e2b6 +1c19 ab27 860c 8933 f6e0 9038 3304 7dad +214d 706b 4813 dcb2 9b4f d781 900b 23b6 +1c91 36dc a5f6 eff9 af0c aaff 06f1 48e5 +4433 2000 00 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/test.gz b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/test.gz new file mode 100644 index 000000000000..3f8199dfb26e --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/test.gz @@ -0,0 +1,163 @@ +1f8b 0808 2aa1 c754 0003 7465 7874 00b5 +5b5d 939b 3816 7def 5fa1 ea79 99a9 4d3c +601b db3c f4c3 5426 55f3 309b ca6e 7ab7 +6a9e 281a d436 150c 04c4 a4bd 5df3 dff7 +4a88 361f 025d 094f 1e92 34e8 1cae 8ea4 +ab7b 04fd 03f9 ede3 ef9f c989 b122 28e9 +b79a 562c 88eb 3264 499e 05e7 242a f38a +4679 1657 e4f1 44c9 6f8f 8f9f 896c 46d2 +90d1 2c4a 6845 928c 749b aeee 7e20 8f7f +7cfe 8861 adea f339 2c2f 77fa a6af a730 +8b53 5a3e dcff 7cff ee5b 1d66 2c49 e9c3 +bdb3 f2ee ff22 ce12 027f 3101 9621 80ee +7659 90a8 28af 3366 8eeb 2042 f887 558b +7553 d158 a8a7 a4b1 d450 7259 2a69 84ee +e28a e4e7 3365 6512 dd40 d429 2e1b 6527 +b96c e5ed 10da 6a6c 4c31 0043 cbf2 7213 +9915 4c96 22ab 9816 48dc d02d 10d8 8440 +050d ca30 3bd2 db89 ace2 5b22 b592 6fa9 +e092 74a9 ec46 3403 0216 9647 7a8b cc3c +c565 29ba 9a6b 81e0 2de1 02b1 cd28 3a60 +f8b9 ca53 5a2d 2f1c 2698 2c44 9e62 b294 +f84a 6729 b029 4107 7a2c c3e2 b458 5a05 +8b85 ac2a 164b 491b 2a4b 394d c01d d889 +86c5 6225 c724 1642 2a48 2c75 144c 9632 +1a60 3ba8 8ac1 ed68 f96a 57f2 5868 a9e6 +b194 b325 b354 d40c 7e05 1665 0e45 dc89 +d68a bdca dd38 fbd5 7aef dd84 90cb e21e +bcc3 6ab7 59df 8690 336e 9cc3 7eb5 396c +8df5 eeb0 425c 7bff 70d8 ad3c 47fe 712d +46a0 4fe8 fa60 96c7 16bc 4afe 4783 a70b +a30a dfcd ef09 cf2d eeab cd76 07af 74d8 +d7fb 26b6 1a81 524c 6a0c 6a16 a675 cd9d +a67a abac 0c07 e98f d158 ac0c 5827 3c29 +c694 819d 9144 0fb1 34ba 6604 6889 4c2c +edb4 4e73 2674 4e2c 1cce cab1 9ac0 4dd4 +427a d359 ad26 fca4 4629 2d6a 81f5 3427 +31d6 0c6b 32f5 ca4d 5942 8c7e 7aac a587 +3423 3051 0fed 1667 959b f477 1ad5 1038 +2b33 6802 c7aa 6560 fb26 b59a b16a 334a +a150 c6ae 0e0b c5ea 83f4 6f93 da4c f8ae +195d b408 537b 8644 6215 c119 b149 41d4 +0e6a 460f 1dc0 c267 e1c1 5851 d08e 6a52 +9749 1f34 230d 0283 334c 6bdf b527 f017 +1368 1866 0cd0 66bb 3d1c b07a 619c 4e15 +b09c 8529 7914 7f67 f5f9 8996 247f ee39 +9e8a 9cc3 982a 8d4e 0b17 4fa6 e59d e2de +6b94 c7d0 edb5 e3dc bf53 4ac3 ff93 c70f +f7b0 8728 e3ac 0ac8 9c74 c292 3537 359e +6ccc 3030 65a3 0638 5786 87f9 96b0 79dc +8c31 1bb7 9d73 6673 1169 ad99 2918 ad85 +de9c e914 195b 2dbd 2e08 8cb1 3fb3 62c0 +eb84 7368 5ab1 d456 0ba1 1812 6868 d22c +f046 9269 6d1a 46b0 91e3 c2c9 a587 5939 +356b 1673 e1f4 5e0d 2ddf d870 1988 8800 +1bdb 352b 0623 0911 860d 239f c279 e1a4 +c300 0d3d 9b05 1e2d 19ca b5e9 0453 1a30 +bd5c 3898 8171 33c4 a245 d25a 379d 4023 +27a6 1747 0fc1 bb37 3328 5a16 9d7f d3a9 +32f4 637a 51b4 0823 0b67 8c46 2b83 3071 +3a71 148e 4caf 0f06 84f4 71ce d65f 4021 +7c98 e31d 9650 341c bb2d 52b1 9e27 5b6f +f79d 7758 5ae1 a6fc 1c5c 8f68 05cd 8b3a +685f 7a75 5d5d 5d81 a703 1252 5d2a 46cf +e4c3 e7ff 1096 9cc1 3515 3463 dc35 0d3f +1c9d 666c 8dde 740b 1819 6f18 d931 2ff3 +9a25 1938 af4f 6f16 b373 919d 4246 a2ba +2c21 9ef4 42e8 4b52 b151 309d f6c7 b03e +d23b c58d bd33 7cf4 397c 099e e38a fc33 +7c49 cef5 b963 7173 e83d 7986 7124 31ad +a232 2958 5e8e 2568 f1fd 47b6 570f aebf +1e3e 91f3 8a9b 9f0c 1ff5 06ec 3feb edf2 +7a34 e230 6992 1834 0bce f49c 432d d498 +db7f cbab a4b9 2acc f1d8 1bcf 73f4 4350 +b7f1 569b c3de f1fc 35fd 87b3 1f86 068b +bc64 019f 66ed fc20 5ff8 a566 e681 2630 +91db c610 6116 5152 67c9 0ba1 451e 9de6 +e6a4 82b8 1fac a281 bbda aed7 9bdd c1df +1e36 3b88 7624 e49f 49c9 ea30 edf7 efbf +cd45 9c8c 4a86 7e60 ca26 de6a eb6e f707 +dfe5 2a1e 3a71 c9a5 1ec4 1974 290e d23c +ff5a 17c1 7398 a435 0c47 bbc0 41c4 eb8c +fef5 d397 f75f 7e25 4d53 d236 ed86 8a22 +edac 7154 7b47 1735 225a 7d94 d8e8 da76 +7b45 54f4 cf30 ad43 587c dd4f 05d2 34e9 +7e63 dfde 21cf 3964 cd34 2512 0497 2051 +e590 9c68 5433 aa8a 5747 df9e 3ae1 21af +ddbd c671 c596 698b f696 a017 81c5 2725 +d660 5334 df70 89bb 3641 8839 45d6 1bc5 +9449 f308 966c 05d8 f048 83e8 44a3 af45 +9e64 0c33 837e 14bf 9871 bdfb 1349 20ff +c12c e5f3 e84a 0549 e5bd cc31 f218 45ec +d650 46c6 d0aa cebe 2a17 8761 606f a9c8 +12af 5ae4 430a 0815 76ab ee6a 6783 6365 +d186 6f87 a55c 504f 17be 1124 2561 9742 +b9a6 e69f a148 06b3 8057 fe98 87fb a8a4 +21e3 8706 9e7f 30c5 42ec 1594 27e2 6ba4 +ad31 38c9 00e8 af1d 5320 2bc3 ace2 27e9 +00df ba9e 29bc ceae 4fd6 8d63 92c5 5080 +65c7 e029 64d1 2968 7ecd e8d2 9f0d ff92 +0bb4 1259 5234 242d 6ef8 8b49 5798 7e7c +31cf 5664 5163 92f9 dcb6 8cce bf31 dd72 +3e91 1117 5234 29d2 359d 3dcd 8b99 fe74 +799b 28cd bc69 9afc 784d 126d 1284 95d6 +34f9 c978 e234 9ca6 3345 a046 5363 bd00 +ef2f c55b 1088 d136 c518 0fef b79a d690 +6dc2 228c 1276 11c9 feed 0759 ddbf 8db3 +686b 3086 036e cdd6 3505 7377 fc7b 53c3 +0ea5 343b b2d3 a052 6d27 e4f7 3061 bc3f +b07b 3fc9 eed1 d8b8 5ff2 1166 bd92 204c +f63e 5270 f971 5085 e722 a573 9bb1 6c41 +5a08 a627 4a72 ed2e 3c81 db38 dbbd bee6 +4a32 a8de 9238 284a 9ae6 613c 7a73 ade8 +996c 7a7d 815d d267 5a96 72ec 4292 e5d9 +7b71 c8c0 5d72 454b d8ab 5640 9480 16bc +f6e2 439b 444d 0dc7 dd7b cd62 4889 316c +6c4f 3495 e38e dacc 6603 47a8 368b d7cf +0569 3445 49c0 0f1e 9af2 549e b38c aab2 +ced1 84d8 b805 58df cbf1 4334 337b 0c70 +1dcf 37ea cc6c 473a d1bf 03b7 16a5 75cc +073e 4af3 8cb6 0535 94e6 2bba 6a7f f89e +b013 0c32 4c8c ab06 883d a71f 9141 af79 +8f11 8598 8434 f373 a2c7 f2a6 f978 4920 +2e6a d978 bbd6 e753 591e 778a 88ce 6f9b +ffd2 6ec9 3cf4 6b99 c88b 0289 e323 4543 +a80a 8450 fade cc3e 4ebb ffcf a147 75c0 +c659 6df6 fb1b 9035 47c6 9b95 b7f1 6fc1 +26e8 76eb dd6a bbdb d8f1 3515 8303 c3bb +9af5 16b3 1cb2 82d8 e3a7 88a2 8490 9971 +5048 4800 b68e 98e0 d74c f509 14ac 54d3 +1e75 6a88 c914 d596 12b0 7017 f710 5750 +2831 fa24 d42c 7d8d ad97 f9c1 ded7 8f9e +a2dd 1c87 88a1 b39f 2980 27a0 e730 8147 +6661 16f1 ad57 a63e f1a6 4521 5296 b3e4 +59d6 0895 daa7 fede 5c24 df7a e6a7 a299 +d88e c467 46a4 4703 1e28 e787 41ed 8e15 +9779 51c0 96d5 6ba4 dc97 10d1 2872 a11e +356f 930d f123 1f6b 8ab7 2018 3b5f 04a6 +c964 aaa5 d107 232c 906a 9427 d7f8 2cfb +6875 cfb6 761d 6cf8 4ac3 a30a 5b66 2aa3 +e8a7 32d3 4c5b 55dc 659d d2e0 7a0c 8f3e +bc27 1ca8 39b3 c771 2b56 0f0a f82a 5a35 +f945 880a eb5a f5ae fff6 bca3 c572 2bde +d189 048a 58bc 0557 91ff 3538 aac7 b135 +6fc6 27f8 fa25 8c71 bf4b b854 c67f c340 +4d10 2f1f a929 62f1 8bb7 8b87 eaca 0eda +9a4b 3b1e ab1e a1eb 2116 bce2 ade7 b004 +114b fd0a 997d fba9 a157 d41e 1a84 2a69 +b547 1d83 ccfc 61b0 4388 db22 5dd5 d9f7 +3261 b01f b507 33aa d027 5847 1976 a2dd +d6f1 77da 5865 26fe 30aa 5d13 46cf fd8d +6022 70f2 915b 38de 1cc4 3c17 25cc 854a +bc4b 6d8f 9ce8 4b01 c621 e665 22b8 72d2 +7c8e 48c2 4afc d41c b7c1 08c2 34ba 48a7 +de1e c149 d580 07f6 2bf8 4b59 0e29 bba3 +9168 66fb 69a2 0b78 7558 c214 904d df3e +2ef8 2512 5f09 b4b7 a1f6 a5ec 3be5 6a44 +6558 a887 5143 a9d8 6ee6 11af edf5 877b +d71b 7ca2 245e 1bbb db1b 9179 3724 f346 +19c5 9ecb bf25 9729 9948 997d 42fe 7ad0 +84a1 c992 238e b55d 8f54 53c0 b90d d568 +1fb4 a6ba 1dd3 e813 017b 2643 aae1 c8f3 +41f3 168d 7bf3 71df feee ff2d f9e8 431a +5200 00 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/text b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/text new file mode 100644 index 000000000000..f3d8c3784436 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/testdata/text @@ -0,0 +1,322 @@ +# HELP http_request_duration_microseconds The HTTP request latencies in microseconds. +# TYPE http_request_duration_microseconds summary +http_request_duration_microseconds{handler="/",quantile="0.5"} 0 +http_request_duration_microseconds{handler="/",quantile="0.9"} 0 +http_request_duration_microseconds{handler="/",quantile="0.99"} 0 +http_request_duration_microseconds_sum{handler="/"} 0 +http_request_duration_microseconds_count{handler="/"} 0 +http_request_duration_microseconds{handler="/alerts",quantile="0.5"} 0 +http_request_duration_microseconds{handler="/alerts",quantile="0.9"} 0 +http_request_duration_microseconds{handler="/alerts",quantile="0.99"} 0 +http_request_duration_microseconds_sum{handler="/alerts"} 0 +http_request_duration_microseconds_count{handler="/alerts"} 0 +http_request_duration_microseconds{handler="/api/metrics",quantile="0.5"} 0 +http_request_duration_microseconds{handler="/api/metrics",quantile="0.9"} 0 +http_request_duration_microseconds{handler="/api/metrics",quantile="0.99"} 0 +http_request_duration_microseconds_sum{handler="/api/metrics"} 0 +http_request_duration_microseconds_count{handler="/api/metrics"} 0 +http_request_duration_microseconds{handler="/api/query",quantile="0.5"} 0 +http_request_duration_microseconds{handler="/api/query",quantile="0.9"} 0 +http_request_duration_microseconds{handler="/api/query",quantile="0.99"} 0 +http_request_duration_microseconds_sum{handler="/api/query"} 0 +http_request_duration_microseconds_count{handler="/api/query"} 0 +http_request_duration_microseconds{handler="/api/query_range",quantile="0.5"} 0 +http_request_duration_microseconds{handler="/api/query_range",quantile="0.9"} 0 +http_request_duration_microseconds{handler="/api/query_range",quantile="0.99"} 0 +http_request_duration_microseconds_sum{handler="/api/query_range"} 0 +http_request_duration_microseconds_count{handler="/api/query_range"} 0 +http_request_duration_microseconds{handler="/api/targets",quantile="0.5"} 0 +http_request_duration_microseconds{handler="/api/targets",quantile="0.9"} 0 +http_request_duration_microseconds{handler="/api/targets",quantile="0.99"} 0 +http_request_duration_microseconds_sum{handler="/api/targets"} 0 +http_request_duration_microseconds_count{handler="/api/targets"} 0 +http_request_duration_microseconds{handler="/consoles/",quantile="0.5"} 0 +http_request_duration_microseconds{handler="/consoles/",quantile="0.9"} 0 +http_request_duration_microseconds{handler="/consoles/",quantile="0.99"} 0 +http_request_duration_microseconds_sum{handler="/consoles/"} 0 +http_request_duration_microseconds_count{handler="/consoles/"} 0 +http_request_duration_microseconds{handler="/graph",quantile="0.5"} 0 +http_request_duration_microseconds{handler="/graph",quantile="0.9"} 0 +http_request_duration_microseconds{handler="/graph",quantile="0.99"} 0 +http_request_duration_microseconds_sum{handler="/graph"} 0 +http_request_duration_microseconds_count{handler="/graph"} 0 +http_request_duration_microseconds{handler="/heap",quantile="0.5"} 0 +http_request_duration_microseconds{handler="/heap",quantile="0.9"} 0 +http_request_duration_microseconds{handler="/heap",quantile="0.99"} 0 +http_request_duration_microseconds_sum{handler="/heap"} 0 +http_request_duration_microseconds_count{handler="/heap"} 0 +http_request_duration_microseconds{handler="/static/",quantile="0.5"} 0 +http_request_duration_microseconds{handler="/static/",quantile="0.9"} 0 +http_request_duration_microseconds{handler="/static/",quantile="0.99"} 0 +http_request_duration_microseconds_sum{handler="/static/"} 0 +http_request_duration_microseconds_count{handler="/static/"} 0 +http_request_duration_microseconds{handler="prometheus",quantile="0.5"} 1307.275 +http_request_duration_microseconds{handler="prometheus",quantile="0.9"} 1858.632 +http_request_duration_microseconds{handler="prometheus",quantile="0.99"} 3087.384 +http_request_duration_microseconds_sum{handler="prometheus"} 179886.5000000001 +http_request_duration_microseconds_count{handler="prometheus"} 119 +# HELP http_request_size_bytes The HTTP request sizes in bytes. +# TYPE http_request_size_bytes summary +http_request_size_bytes{handler="/",quantile="0.5"} 0 +http_request_size_bytes{handler="/",quantile="0.9"} 0 +http_request_size_bytes{handler="/",quantile="0.99"} 0 +http_request_size_bytes_sum{handler="/"} 0 +http_request_size_bytes_count{handler="/"} 0 +http_request_size_bytes{handler="/alerts",quantile="0.5"} 0 +http_request_size_bytes{handler="/alerts",quantile="0.9"} 0 +http_request_size_bytes{handler="/alerts",quantile="0.99"} 0 +http_request_size_bytes_sum{handler="/alerts"} 0 +http_request_size_bytes_count{handler="/alerts"} 0 +http_request_size_bytes{handler="/api/metrics",quantile="0.5"} 0 +http_request_size_bytes{handler="/api/metrics",quantile="0.9"} 0 +http_request_size_bytes{handler="/api/metrics",quantile="0.99"} 0 +http_request_size_bytes_sum{handler="/api/metrics"} 0 +http_request_size_bytes_count{handler="/api/metrics"} 0 +http_request_size_bytes{handler="/api/query",quantile="0.5"} 0 +http_request_size_bytes{handler="/api/query",quantile="0.9"} 0 +http_request_size_bytes{handler="/api/query",quantile="0.99"} 0 +http_request_size_bytes_sum{handler="/api/query"} 0 +http_request_size_bytes_count{handler="/api/query"} 0 +http_request_size_bytes{handler="/api/query_range",quantile="0.5"} 0 +http_request_size_bytes{handler="/api/query_range",quantile="0.9"} 0 +http_request_size_bytes{handler="/api/query_range",quantile="0.99"} 0 +http_request_size_bytes_sum{handler="/api/query_range"} 0 +http_request_size_bytes_count{handler="/api/query_range"} 0 +http_request_size_bytes{handler="/api/targets",quantile="0.5"} 0 +http_request_size_bytes{handler="/api/targets",quantile="0.9"} 0 +http_request_size_bytes{handler="/api/targets",quantile="0.99"} 0 +http_request_size_bytes_sum{handler="/api/targets"} 0 +http_request_size_bytes_count{handler="/api/targets"} 0 +http_request_size_bytes{handler="/consoles/",quantile="0.5"} 0 +http_request_size_bytes{handler="/consoles/",quantile="0.9"} 0 +http_request_size_bytes{handler="/consoles/",quantile="0.99"} 0 +http_request_size_bytes_sum{handler="/consoles/"} 0 +http_request_size_bytes_count{handler="/consoles/"} 0 +http_request_size_bytes{handler="/graph",quantile="0.5"} 0 +http_request_size_bytes{handler="/graph",quantile="0.9"} 0 +http_request_size_bytes{handler="/graph",quantile="0.99"} 0 +http_request_size_bytes_sum{handler="/graph"} 0 +http_request_size_bytes_count{handler="/graph"} 0 +http_request_size_bytes{handler="/heap",quantile="0.5"} 0 +http_request_size_bytes{handler="/heap",quantile="0.9"} 0 +http_request_size_bytes{handler="/heap",quantile="0.99"} 0 +http_request_size_bytes_sum{handler="/heap"} 0 +http_request_size_bytes_count{handler="/heap"} 0 +http_request_size_bytes{handler="/static/",quantile="0.5"} 0 +http_request_size_bytes{handler="/static/",quantile="0.9"} 0 +http_request_size_bytes{handler="/static/",quantile="0.99"} 0 +http_request_size_bytes_sum{handler="/static/"} 0 +http_request_size_bytes_count{handler="/static/"} 0 +http_request_size_bytes{handler="prometheus",quantile="0.5"} 291 +http_request_size_bytes{handler="prometheus",quantile="0.9"} 291 +http_request_size_bytes{handler="prometheus",quantile="0.99"} 291 +http_request_size_bytes_sum{handler="prometheus"} 34488 +http_request_size_bytes_count{handler="prometheus"} 119 +# HELP http_requests_total Total number of HTTP requests made. +# TYPE http_requests_total counter +http_requests_total{code="200",handler="prometheus",method="get"} 119 +# HELP http_response_size_bytes The HTTP response sizes in bytes. +# TYPE http_response_size_bytes summary +http_response_size_bytes{handler="/",quantile="0.5"} 0 +http_response_size_bytes{handler="/",quantile="0.9"} 0 +http_response_size_bytes{handler="/",quantile="0.99"} 0 +http_response_size_bytes_sum{handler="/"} 0 +http_response_size_bytes_count{handler="/"} 0 +http_response_size_bytes{handler="/alerts",quantile="0.5"} 0 +http_response_size_bytes{handler="/alerts",quantile="0.9"} 0 +http_response_size_bytes{handler="/alerts",quantile="0.99"} 0 +http_response_size_bytes_sum{handler="/alerts"} 0 +http_response_size_bytes_count{handler="/alerts"} 0 +http_response_size_bytes{handler="/api/metrics",quantile="0.5"} 0 +http_response_size_bytes{handler="/api/metrics",quantile="0.9"} 0 +http_response_size_bytes{handler="/api/metrics",quantile="0.99"} 0 +http_response_size_bytes_sum{handler="/api/metrics"} 0 +http_response_size_bytes_count{handler="/api/metrics"} 0 +http_response_size_bytes{handler="/api/query",quantile="0.5"} 0 +http_response_size_bytes{handler="/api/query",quantile="0.9"} 0 +http_response_size_bytes{handler="/api/query",quantile="0.99"} 0 +http_response_size_bytes_sum{handler="/api/query"} 0 +http_response_size_bytes_count{handler="/api/query"} 0 +http_response_size_bytes{handler="/api/query_range",quantile="0.5"} 0 +http_response_size_bytes{handler="/api/query_range",quantile="0.9"} 0 +http_response_size_bytes{handler="/api/query_range",quantile="0.99"} 0 +http_response_size_bytes_sum{handler="/api/query_range"} 0 +http_response_size_bytes_count{handler="/api/query_range"} 0 +http_response_size_bytes{handler="/api/targets",quantile="0.5"} 0 +http_response_size_bytes{handler="/api/targets",quantile="0.9"} 0 +http_response_size_bytes{handler="/api/targets",quantile="0.99"} 0 +http_response_size_bytes_sum{handler="/api/targets"} 0 +http_response_size_bytes_count{handler="/api/targets"} 0 +http_response_size_bytes{handler="/consoles/",quantile="0.5"} 0 +http_response_size_bytes{handler="/consoles/",quantile="0.9"} 0 +http_response_size_bytes{handler="/consoles/",quantile="0.99"} 0 +http_response_size_bytes_sum{handler="/consoles/"} 0 +http_response_size_bytes_count{handler="/consoles/"} 0 +http_response_size_bytes{handler="/graph",quantile="0.5"} 0 +http_response_size_bytes{handler="/graph",quantile="0.9"} 0 +http_response_size_bytes{handler="/graph",quantile="0.99"} 0 +http_response_size_bytes_sum{handler="/graph"} 0 +http_response_size_bytes_count{handler="/graph"} 0 +http_response_size_bytes{handler="/heap",quantile="0.5"} 0 +http_response_size_bytes{handler="/heap",quantile="0.9"} 0 +http_response_size_bytes{handler="/heap",quantile="0.99"} 0 +http_response_size_bytes_sum{handler="/heap"} 0 +http_response_size_bytes_count{handler="/heap"} 0 +http_response_size_bytes{handler="/static/",quantile="0.5"} 0 +http_response_size_bytes{handler="/static/",quantile="0.9"} 0 +http_response_size_bytes{handler="/static/",quantile="0.99"} 0 +http_response_size_bytes_sum{handler="/static/"} 0 +http_response_size_bytes_count{handler="/static/"} 0 +http_response_size_bytes{handler="prometheus",quantile="0.5"} 2049 +http_response_size_bytes{handler="prometheus",quantile="0.9"} 2058 +http_response_size_bytes{handler="prometheus",quantile="0.99"} 2064 +http_response_size_bytes_sum{handler="prometheus"} 247001 +http_response_size_bytes_count{handler="prometheus"} 119 +# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds. +# TYPE process_cpu_seconds_total counter +process_cpu_seconds_total 0.55 +# HELP go_goroutines Number of goroutines that currently exist. +# TYPE go_goroutines gauge +go_goroutines 70 +# HELP process_max_fds Maximum number of open file descriptors. +# TYPE process_max_fds gauge +process_max_fds 8192 +# HELP process_open_fds Number of open file descriptors. +# TYPE process_open_fds gauge +process_open_fds 29 +# HELP process_resident_memory_bytes Resident memory size in bytes. +# TYPE process_resident_memory_bytes gauge +process_resident_memory_bytes 5.3870592e+07 +# HELP process_start_time_seconds Start time of the process since unix epoch in seconds. +# TYPE process_start_time_seconds gauge +process_start_time_seconds 1.42236894836e+09 +# HELP process_virtual_memory_bytes Virtual memory size in bytes. +# TYPE process_virtual_memory_bytes gauge +process_virtual_memory_bytes 5.41478912e+08 +# HELP prometheus_dns_sd_lookup_failures_total The number of DNS-SD lookup failures. +# TYPE prometheus_dns_sd_lookup_failures_total counter +prometheus_dns_sd_lookup_failures_total 0 +# HELP prometheus_dns_sd_lookups_total The number of DNS-SD lookups. +# TYPE prometheus_dns_sd_lookups_total counter +prometheus_dns_sd_lookups_total 7 +# HELP prometheus_evaluator_duration_milliseconds The duration for all evaluations to execute. +# TYPE prometheus_evaluator_duration_milliseconds summary +prometheus_evaluator_duration_milliseconds{quantile="0.01"} 0 +prometheus_evaluator_duration_milliseconds{quantile="0.05"} 0 +prometheus_evaluator_duration_milliseconds{quantile="0.5"} 0 +prometheus_evaluator_duration_milliseconds{quantile="0.9"} 1 +prometheus_evaluator_duration_milliseconds{quantile="0.99"} 1 +prometheus_evaluator_duration_milliseconds_sum 12 +prometheus_evaluator_duration_milliseconds_count 23 +# HELP prometheus_local_storage_checkpoint_duration_milliseconds The duration (in milliseconds) it took to checkpoint in-memory metrics and head chunks. +# TYPE prometheus_local_storage_checkpoint_duration_milliseconds gauge +prometheus_local_storage_checkpoint_duration_milliseconds 0 +# HELP prometheus_local_storage_chunk_ops_total The total number of chunk operations by their type. +# TYPE prometheus_local_storage_chunk_ops_total counter +prometheus_local_storage_chunk_ops_total{type="create"} 598 +prometheus_local_storage_chunk_ops_total{type="persist"} 174 +prometheus_local_storage_chunk_ops_total{type="pin"} 920 +prometheus_local_storage_chunk_ops_total{type="transcode"} 415 +prometheus_local_storage_chunk_ops_total{type="unpin"} 920 +# HELP prometheus_local_storage_indexing_batch_latency_milliseconds Quantiles for batch indexing latencies in milliseconds. +# TYPE prometheus_local_storage_indexing_batch_latency_milliseconds summary +prometheus_local_storage_indexing_batch_latency_milliseconds{quantile="0.5"} 0 +prometheus_local_storage_indexing_batch_latency_milliseconds{quantile="0.9"} 0 +prometheus_local_storage_indexing_batch_latency_milliseconds{quantile="0.99"} 0 +prometheus_local_storage_indexing_batch_latency_milliseconds_sum 0 +prometheus_local_storage_indexing_batch_latency_milliseconds_count 1 +# HELP prometheus_local_storage_indexing_batch_sizes Quantiles for indexing batch sizes (number of metrics per batch). +# TYPE prometheus_local_storage_indexing_batch_sizes summary +prometheus_local_storage_indexing_batch_sizes{quantile="0.5"} 2 +prometheus_local_storage_indexing_batch_sizes{quantile="0.9"} 2 +prometheus_local_storage_indexing_batch_sizes{quantile="0.99"} 2 +prometheus_local_storage_indexing_batch_sizes_sum 2 +prometheus_local_storage_indexing_batch_sizes_count 1 +# HELP prometheus_local_storage_indexing_queue_capacity The capacity of the indexing queue. +# TYPE prometheus_local_storage_indexing_queue_capacity gauge +prometheus_local_storage_indexing_queue_capacity 16384 +# HELP prometheus_local_storage_indexing_queue_length The number of metrics waiting to be indexed. +# TYPE prometheus_local_storage_indexing_queue_length gauge +prometheus_local_storage_indexing_queue_length 0 +# HELP prometheus_local_storage_ingested_samples_total The total number of samples ingested. +# TYPE prometheus_local_storage_ingested_samples_total counter +prometheus_local_storage_ingested_samples_total 30473 +# HELP prometheus_local_storage_invalid_preload_requests_total The total number of preload requests referring to a non-existent series. This is an indication of outdated label indexes. +# TYPE prometheus_local_storage_invalid_preload_requests_total counter +prometheus_local_storage_invalid_preload_requests_total 0 +# HELP prometheus_local_storage_memory_chunkdescs The current number of chunk descriptors in memory. +# TYPE prometheus_local_storage_memory_chunkdescs gauge +prometheus_local_storage_memory_chunkdescs 1059 +# HELP prometheus_local_storage_memory_chunks The current number of chunks in memory, excluding cloned chunks (i.e. chunks without a descriptor). +# TYPE prometheus_local_storage_memory_chunks gauge +prometheus_local_storage_memory_chunks 1020 +# HELP prometheus_local_storage_memory_series The current number of series in memory. +# TYPE prometheus_local_storage_memory_series gauge +prometheus_local_storage_memory_series 424 +# HELP prometheus_local_storage_persist_latency_microseconds A summary of latencies for persisting each chunk. +# TYPE prometheus_local_storage_persist_latency_microseconds summary +prometheus_local_storage_persist_latency_microseconds{quantile="0.5"} 30.377 +prometheus_local_storage_persist_latency_microseconds{quantile="0.9"} 203.539 +prometheus_local_storage_persist_latency_microseconds{quantile="0.99"} 2626.463 +prometheus_local_storage_persist_latency_microseconds_sum 20424.415 +prometheus_local_storage_persist_latency_microseconds_count 174 +# HELP prometheus_local_storage_persist_queue_capacity The total capacity of the persist queue. +# TYPE prometheus_local_storage_persist_queue_capacity gauge +prometheus_local_storage_persist_queue_capacity 1024 +# HELP prometheus_local_storage_persist_queue_length The current number of chunks waiting in the persist queue. +# TYPE prometheus_local_storage_persist_queue_length gauge +prometheus_local_storage_persist_queue_length 0 +# HELP prometheus_local_storage_series_ops_total The total number of series operations by their type. +# TYPE prometheus_local_storage_series_ops_total counter +prometheus_local_storage_series_ops_total{type="create"} 2 +prometheus_local_storage_series_ops_total{type="maintenance_in_memory"} 11 +# HELP prometheus_notifications_latency_milliseconds Latency quantiles for sending alert notifications (not including dropped notifications). +# TYPE prometheus_notifications_latency_milliseconds summary +prometheus_notifications_latency_milliseconds{quantile="0.5"} 0 +prometheus_notifications_latency_milliseconds{quantile="0.9"} 0 +prometheus_notifications_latency_milliseconds{quantile="0.99"} 0 +prometheus_notifications_latency_milliseconds_sum 0 +prometheus_notifications_latency_milliseconds_count 0 +# HELP prometheus_notifications_queue_capacity The capacity of the alert notifications queue. +# TYPE prometheus_notifications_queue_capacity gauge +prometheus_notifications_queue_capacity 100 +# HELP prometheus_notifications_queue_length The number of alert notifications in the queue. +# TYPE prometheus_notifications_queue_length gauge +prometheus_notifications_queue_length 0 +# HELP prometheus_rule_evaluation_duration_milliseconds The duration for a rule to execute. +# TYPE prometheus_rule_evaluation_duration_milliseconds summary +prometheus_rule_evaluation_duration_milliseconds{rule_type="alerting",quantile="0.5"} 0 +prometheus_rule_evaluation_duration_milliseconds{rule_type="alerting",quantile="0.9"} 0 +prometheus_rule_evaluation_duration_milliseconds{rule_type="alerting",quantile="0.99"} 2 +prometheus_rule_evaluation_duration_milliseconds_sum{rule_type="alerting"} 12 +prometheus_rule_evaluation_duration_milliseconds_count{rule_type="alerting"} 115 +prometheus_rule_evaluation_duration_milliseconds{rule_type="recording",quantile="0.5"} 0 +prometheus_rule_evaluation_duration_milliseconds{rule_type="recording",quantile="0.9"} 0 +prometheus_rule_evaluation_duration_milliseconds{rule_type="recording",quantile="0.99"} 3 +prometheus_rule_evaluation_duration_milliseconds_sum{rule_type="recording"} 15 +prometheus_rule_evaluation_duration_milliseconds_count{rule_type="recording"} 115 +# HELP prometheus_rule_evaluation_failures_total The total number of rule evaluation failures. +# TYPE prometheus_rule_evaluation_failures_total counter +prometheus_rule_evaluation_failures_total 0 +# HELP prometheus_samples_queue_capacity Capacity of the queue for unwritten samples. +# TYPE prometheus_samples_queue_capacity gauge +prometheus_samples_queue_capacity 4096 +# HELP prometheus_samples_queue_length Current number of items in the queue for unwritten samples. Each item comprises all samples exposed by one target as one metric family (i.e. metrics of the same name). +# TYPE prometheus_samples_queue_length gauge +prometheus_samples_queue_length 0 +# HELP prometheus_target_interval_length_seconds Actual intervals between scrapes. +# TYPE prometheus_target_interval_length_seconds summary +prometheus_target_interval_length_seconds{interval="15s",quantile="0.01"} 14 +prometheus_target_interval_length_seconds{interval="15s",quantile="0.05"} 14 +prometheus_target_interval_length_seconds{interval="15s",quantile="0.5"} 15 +prometheus_target_interval_length_seconds{interval="15s",quantile="0.9"} 15 +prometheus_target_interval_length_seconds{interval="15s",quantile="0.99"} 15 +prometheus_target_interval_length_seconds_sum{interval="15s"} 175 +prometheus_target_interval_length_seconds_count{interval="15s"} 12 +prometheus_target_interval_length_seconds{interval="1s",quantile="0.01"} 0 +prometheus_target_interval_length_seconds{interval="1s",quantile="0.05"} 0 +prometheus_target_interval_length_seconds{interval="1s",quantile="0.5"} 0 +prometheus_target_interval_length_seconds{interval="1s",quantile="0.9"} 1 +prometheus_target_interval_length_seconds{interval="1s",quantile="0.99"} 1 +prometheus_target_interval_length_seconds_sum{interval="1s"} 55 +prometheus_target_interval_length_seconds_count{interval="1s"} 117 diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create.go new file mode 100644 index 000000000000..0bb9c14cc2b6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create.go @@ -0,0 +1,305 @@ +// Copyright 2014 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expfmt + +import ( + "bytes" + "fmt" + "io" + "math" + "strings" + + dto "github.com/prometheus/client_model/go" + "github.com/prometheus/common/model" +) + +// MetricFamilyToText converts a MetricFamily proto message into text format and +// writes the resulting lines to 'out'. It returns the number of bytes written +// and any error encountered. This function does not perform checks on the +// content of the metric and label names, i.e. invalid metric or label names +// will result in invalid text format output. +// This method fulfills the type 'prometheus.encoder'. +func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) { + var written int + + // Fail-fast checks. + if len(in.Metric) == 0 { + return written, fmt.Errorf("MetricFamily has no metrics: %s", in) + } + name := in.GetName() + if name == "" { + return written, fmt.Errorf("MetricFamily has no name: %s", in) + } + + // Comments, first HELP, then TYPE. + if in.Help != nil { + n, err := fmt.Fprintf( + out, "# HELP %s %s\n", + name, escapeString(*in.Help, false), + ) + written += n + if err != nil { + return written, err + } + } + metricType := in.GetType() + n, err := fmt.Fprintf( + out, "# TYPE %s %s\n", + name, strings.ToLower(metricType.String()), + ) + written += n + if err != nil { + return written, err + } + + // Finally the samples, one line for each. + for _, metric := range in.Metric { + switch metricType { + case dto.MetricType_COUNTER: + if metric.Counter == nil { + return written, fmt.Errorf( + "expected counter in metric %s %s", name, metric, + ) + } + n, err = writeSample( + name, metric, "", "", + metric.Counter.GetValue(), + out, + ) + case dto.MetricType_GAUGE: + if metric.Gauge == nil { + return written, fmt.Errorf( + "expected gauge in metric %s %s", name, metric, + ) + } + n, err = writeSample( + name, metric, "", "", + metric.Gauge.GetValue(), + out, + ) + case dto.MetricType_UNTYPED: + if metric.Untyped == nil { + return written, fmt.Errorf( + "expected untyped in metric %s %s", name, metric, + ) + } + n, err = writeSample( + name, metric, "", "", + metric.Untyped.GetValue(), + out, + ) + case dto.MetricType_SUMMARY: + if metric.Summary == nil { + return written, fmt.Errorf( + "expected summary in metric %s %s", name, metric, + ) + } + for _, q := range metric.Summary.Quantile { + n, err = writeSample( + name, metric, + model.QuantileLabel, fmt.Sprint(q.GetQuantile()), + q.GetValue(), + out, + ) + written += n + if err != nil { + return written, err + } + } + n, err = writeSample( + name+"_sum", metric, "", "", + metric.Summary.GetSampleSum(), + out, + ) + if err != nil { + return written, err + } + written += n + n, err = writeSample( + name+"_count", metric, "", "", + float64(metric.Summary.GetSampleCount()), + out, + ) + case dto.MetricType_HISTOGRAM: + if metric.Histogram == nil { + return written, fmt.Errorf( + "expected histogram in metric %s %s", name, metric, + ) + } + infSeen := false + for _, q := range metric.Histogram.Bucket { + n, err = writeSample( + name+"_bucket", metric, + model.BucketLabel, fmt.Sprint(q.GetUpperBound()), + float64(q.GetCumulativeCount()), + out, + ) + written += n + if err != nil { + return written, err + } + if math.IsInf(q.GetUpperBound(), +1) { + infSeen = true + } + } + if !infSeen { + n, err = writeSample( + name+"_bucket", metric, + model.BucketLabel, "+Inf", + float64(metric.Histogram.GetSampleCount()), + out, + ) + if err != nil { + return written, err + } + written += n + } + n, err = writeSample( + name+"_sum", metric, "", "", + metric.Histogram.GetSampleSum(), + out, + ) + if err != nil { + return written, err + } + written += n + n, err = writeSample( + name+"_count", metric, "", "", + float64(metric.Histogram.GetSampleCount()), + out, + ) + default: + return written, fmt.Errorf( + "unexpected type in metric %s %s", name, metric, + ) + } + written += n + if err != nil { + return written, err + } + } + return written, nil +} + +// writeSample writes a single sample in text format to out, given the metric +// name, the metric proto message itself, optionally an additional label name +// and value (use empty strings if not required), and the value. The function +// returns the number of bytes written and any error encountered. +func writeSample( + name string, + metric *dto.Metric, + additionalLabelName, additionalLabelValue string, + value float64, + out io.Writer, +) (int, error) { + var written int + n, err := fmt.Fprint(out, name) + written += n + if err != nil { + return written, err + } + n, err = labelPairsToText( + metric.Label, + additionalLabelName, additionalLabelValue, + out, + ) + written += n + if err != nil { + return written, err + } + n, err = fmt.Fprintf(out, " %v", value) + written += n + if err != nil { + return written, err + } + if metric.TimestampMs != nil { + n, err = fmt.Fprintf(out, " %v", *metric.TimestampMs) + written += n + if err != nil { + return written, err + } + } + n, err = out.Write([]byte{'\n'}) + written += n + if err != nil { + return written, err + } + return written, nil +} + +// labelPairsToText converts a slice of LabelPair proto messages plus the +// explicitly given additional label pair into text formatted as required by the +// text format and writes it to 'out'. An empty slice in combination with an +// empty string 'additionalLabelName' results in nothing being +// written. Otherwise, the label pairs are written, escaped as required by the +// text format, and enclosed in '{...}'. The function returns the number of +// bytes written and any error encountered. +func labelPairsToText( + in []*dto.LabelPair, + additionalLabelName, additionalLabelValue string, + out io.Writer, +) (int, error) { + if len(in) == 0 && additionalLabelName == "" { + return 0, nil + } + var written int + separator := '{' + for _, lp := range in { + n, err := fmt.Fprintf( + out, `%c%s="%s"`, + separator, lp.GetName(), escapeString(lp.GetValue(), true), + ) + written += n + if err != nil { + return written, err + } + separator = ',' + } + if additionalLabelName != "" { + n, err := fmt.Fprintf( + out, `%c%s="%s"`, + separator, additionalLabelName, + escapeString(additionalLabelValue, true), + ) + written += n + if err != nil { + return written, err + } + } + n, err := out.Write([]byte{'}'}) + written += n + if err != nil { + return written, err + } + return written, nil +} + +// escapeString replaces '\' by '\\', new line character by '\n', and - if +// includeDoubleQuote is true - '"' by '\"'. +func escapeString(v string, includeDoubleQuote bool) string { + result := bytes.NewBuffer(make([]byte, 0, len(v))) + for _, c := range v { + switch { + case c == '\\': + result.WriteString(`\\`) + case includeDoubleQuote && c == '"': + result.WriteString(`\"`) + case c == '\n': + result.WriteString(`\n`) + default: + result.WriteRune(c) + } + } + return result.String() +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create_test.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create_test.go new file mode 100644 index 000000000000..e4cc5d803bb8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_create_test.go @@ -0,0 +1,443 @@ +// Copyright 2014 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expfmt + +import ( + "bytes" + "math" + "strings" + "testing" + + "github.com/golang/protobuf/proto" + + dto "github.com/prometheus/client_model/go" +) + +func testCreate(t testing.TB) { + var scenarios = []struct { + in *dto.MetricFamily + out string + }{ + // 0: Counter, NaN as value, timestamp given. + { + in: &dto.MetricFamily{ + Name: proto.String("name"), + Help: proto.String("two-line\n doc str\\ing"), + Type: dto.MetricType_COUNTER.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("labelname"), + Value: proto.String("val1"), + }, + &dto.LabelPair{ + Name: proto.String("basename"), + Value: proto.String("basevalue"), + }, + }, + Counter: &dto.Counter{ + Value: proto.Float64(math.NaN()), + }, + }, + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("labelname"), + Value: proto.String("val2"), + }, + &dto.LabelPair{ + Name: proto.String("basename"), + Value: proto.String("basevalue"), + }, + }, + Counter: &dto.Counter{ + Value: proto.Float64(.23), + }, + TimestampMs: proto.Int64(1234567890), + }, + }, + }, + out: `# HELP name two-line\n doc str\\ing +# TYPE name counter +name{labelname="val1",basename="basevalue"} NaN +name{labelname="val2",basename="basevalue"} 0.23 1234567890 +`, + }, + // 1: Gauge, some escaping required, +Inf as value, multi-byte characters in label values. + { + in: &dto.MetricFamily{ + Name: proto.String("gauge_name"), + Help: proto.String("gauge\ndoc\nstr\"ing"), + Type: dto.MetricType_GAUGE.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("name_1"), + Value: proto.String("val with\nnew line"), + }, + &dto.LabelPair{ + Name: proto.String("name_2"), + Value: proto.String("val with \\backslash and \"quotes\""), + }, + }, + Gauge: &dto.Gauge{ + Value: proto.Float64(math.Inf(+1)), + }, + }, + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("name_1"), + Value: proto.String("Björn"), + }, + &dto.LabelPair{ + Name: proto.String("name_2"), + Value: proto.String("佖佥"), + }, + }, + Gauge: &dto.Gauge{ + Value: proto.Float64(3.14E42), + }, + }, + }, + }, + out: `# HELP gauge_name gauge\ndoc\nstr"ing +# TYPE gauge_name gauge +gauge_name{name_1="val with\nnew line",name_2="val with \\backslash and \"quotes\""} +Inf +gauge_name{name_1="Björn",name_2="佖佥"} 3.14e+42 +`, + }, + // 2: Untyped, no help, one sample with no labels and -Inf as value, another sample with one label. + { + in: &dto.MetricFamily{ + Name: proto.String("untyped_name"), + Type: dto.MetricType_UNTYPED.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Untyped: &dto.Untyped{ + Value: proto.Float64(math.Inf(-1)), + }, + }, + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("name_1"), + Value: proto.String("value 1"), + }, + }, + Untyped: &dto.Untyped{ + Value: proto.Float64(-1.23e-45), + }, + }, + }, + }, + out: `# TYPE untyped_name untyped +untyped_name -Inf +untyped_name{name_1="value 1"} -1.23e-45 +`, + }, + // 3: Summary. + { + in: &dto.MetricFamily{ + Name: proto.String("summary_name"), + Help: proto.String("summary docstring"), + Type: dto.MetricType_SUMMARY.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Summary: &dto.Summary{ + SampleCount: proto.Uint64(42), + SampleSum: proto.Float64(-3.4567), + Quantile: []*dto.Quantile{ + &dto.Quantile{ + Quantile: proto.Float64(0.5), + Value: proto.Float64(-1.23), + }, + &dto.Quantile{ + Quantile: proto.Float64(0.9), + Value: proto.Float64(.2342354), + }, + &dto.Quantile{ + Quantile: proto.Float64(0.99), + Value: proto.Float64(0), + }, + }, + }, + }, + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("name_1"), + Value: proto.String("value 1"), + }, + &dto.LabelPair{ + Name: proto.String("name_2"), + Value: proto.String("value 2"), + }, + }, + Summary: &dto.Summary{ + SampleCount: proto.Uint64(4711), + SampleSum: proto.Float64(2010.1971), + Quantile: []*dto.Quantile{ + &dto.Quantile{ + Quantile: proto.Float64(0.5), + Value: proto.Float64(1), + }, + &dto.Quantile{ + Quantile: proto.Float64(0.9), + Value: proto.Float64(2), + }, + &dto.Quantile{ + Quantile: proto.Float64(0.99), + Value: proto.Float64(3), + }, + }, + }, + }, + }, + }, + out: `# HELP summary_name summary docstring +# TYPE summary_name summary +summary_name{quantile="0.5"} -1.23 +summary_name{quantile="0.9"} 0.2342354 +summary_name{quantile="0.99"} 0 +summary_name_sum -3.4567 +summary_name_count 42 +summary_name{name_1="value 1",name_2="value 2",quantile="0.5"} 1 +summary_name{name_1="value 1",name_2="value 2",quantile="0.9"} 2 +summary_name{name_1="value 1",name_2="value 2",quantile="0.99"} 3 +summary_name_sum{name_1="value 1",name_2="value 2"} 2010.1971 +summary_name_count{name_1="value 1",name_2="value 2"} 4711 +`, + }, + // 4: Histogram + { + in: &dto.MetricFamily{ + Name: proto.String("request_duration_microseconds"), + Help: proto.String("The response latency."), + Type: dto.MetricType_HISTOGRAM.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Histogram: &dto.Histogram{ + SampleCount: proto.Uint64(2693), + SampleSum: proto.Float64(1756047.3), + Bucket: []*dto.Bucket{ + &dto.Bucket{ + UpperBound: proto.Float64(100), + CumulativeCount: proto.Uint64(123), + }, + &dto.Bucket{ + UpperBound: proto.Float64(120), + CumulativeCount: proto.Uint64(412), + }, + &dto.Bucket{ + UpperBound: proto.Float64(144), + CumulativeCount: proto.Uint64(592), + }, + &dto.Bucket{ + UpperBound: proto.Float64(172.8), + CumulativeCount: proto.Uint64(1524), + }, + &dto.Bucket{ + UpperBound: proto.Float64(math.Inf(+1)), + CumulativeCount: proto.Uint64(2693), + }, + }, + }, + }, + }, + }, + out: `# HELP request_duration_microseconds The response latency. +# TYPE request_duration_microseconds histogram +request_duration_microseconds_bucket{le="100"} 123 +request_duration_microseconds_bucket{le="120"} 412 +request_duration_microseconds_bucket{le="144"} 592 +request_duration_microseconds_bucket{le="172.8"} 1524 +request_duration_microseconds_bucket{le="+Inf"} 2693 +request_duration_microseconds_sum 1.7560473e+06 +request_duration_microseconds_count 2693 +`, + }, + // 5: Histogram with missing +Inf bucket. + { + in: &dto.MetricFamily{ + Name: proto.String("request_duration_microseconds"), + Help: proto.String("The response latency."), + Type: dto.MetricType_HISTOGRAM.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Histogram: &dto.Histogram{ + SampleCount: proto.Uint64(2693), + SampleSum: proto.Float64(1756047.3), + Bucket: []*dto.Bucket{ + &dto.Bucket{ + UpperBound: proto.Float64(100), + CumulativeCount: proto.Uint64(123), + }, + &dto.Bucket{ + UpperBound: proto.Float64(120), + CumulativeCount: proto.Uint64(412), + }, + &dto.Bucket{ + UpperBound: proto.Float64(144), + CumulativeCount: proto.Uint64(592), + }, + &dto.Bucket{ + UpperBound: proto.Float64(172.8), + CumulativeCount: proto.Uint64(1524), + }, + }, + }, + }, + }, + }, + out: `# HELP request_duration_microseconds The response latency. +# TYPE request_duration_microseconds histogram +request_duration_microseconds_bucket{le="100"} 123 +request_duration_microseconds_bucket{le="120"} 412 +request_duration_microseconds_bucket{le="144"} 592 +request_duration_microseconds_bucket{le="172.8"} 1524 +request_duration_microseconds_bucket{le="+Inf"} 2693 +request_duration_microseconds_sum 1.7560473e+06 +request_duration_microseconds_count 2693 +`, + }, + // 6: No metric type, should result in default type Counter. + { + in: &dto.MetricFamily{ + Name: proto.String("name"), + Help: proto.String("doc string"), + Metric: []*dto.Metric{ + &dto.Metric{ + Counter: &dto.Counter{ + Value: proto.Float64(math.Inf(-1)), + }, + }, + }, + }, + out: `# HELP name doc string +# TYPE name counter +name -Inf +`, + }, + } + + for i, scenario := range scenarios { + out := bytes.NewBuffer(make([]byte, 0, len(scenario.out))) + n, err := MetricFamilyToText(out, scenario.in) + if err != nil { + t.Errorf("%d. error: %s", i, err) + continue + } + if expected, got := len(scenario.out), n; expected != got { + t.Errorf( + "%d. expected %d bytes written, got %d", + i, expected, got, + ) + } + if expected, got := scenario.out, out.String(); expected != got { + t.Errorf( + "%d. expected out=%q, got %q", + i, expected, got, + ) + } + } + +} + +func TestCreate(t *testing.T) { + testCreate(t) +} + +func BenchmarkCreate(b *testing.B) { + for i := 0; i < b.N; i++ { + testCreate(b) + } +} + +func testCreateError(t testing.TB) { + var scenarios = []struct { + in *dto.MetricFamily + err string + }{ + // 0: No metric. + { + in: &dto.MetricFamily{ + Name: proto.String("name"), + Help: proto.String("doc string"), + Type: dto.MetricType_COUNTER.Enum(), + Metric: []*dto.Metric{}, + }, + err: "MetricFamily has no metrics", + }, + // 1: No metric name. + { + in: &dto.MetricFamily{ + Help: proto.String("doc string"), + Type: dto.MetricType_UNTYPED.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Untyped: &dto.Untyped{ + Value: proto.Float64(math.Inf(-1)), + }, + }, + }, + }, + err: "MetricFamily has no name", + }, + // 2: Wrong type. + { + in: &dto.MetricFamily{ + Name: proto.String("name"), + Help: proto.String("doc string"), + Type: dto.MetricType_COUNTER.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Untyped: &dto.Untyped{ + Value: proto.Float64(math.Inf(-1)), + }, + }, + }, + }, + err: "expected counter in metric", + }, + } + + for i, scenario := range scenarios { + var out bytes.Buffer + _, err := MetricFamilyToText(&out, scenario.in) + if err == nil { + t.Errorf("%d. expected error, got nil", i) + continue + } + if expected, got := scenario.err, err.Error(); strings.Index(got, expected) != 0 { + t.Errorf( + "%d. expected error starting with %q, got %q", + i, expected, got, + ) + } + } + +} + +func TestCreateError(t *testing.T) { + testCreateError(t) +} + +func BenchmarkCreateError(b *testing.B) { + for i := 0; i < b.N; i++ { + testCreateError(b) + } +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse.go new file mode 100644 index 000000000000..84433bc4f6ef --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse.go @@ -0,0 +1,746 @@ +// Copyright 2014 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expfmt + +import ( + "bufio" + "bytes" + "fmt" + "io" + "math" + "strconv" + "strings" + + dto "github.com/prometheus/client_model/go" + + "github.com/golang/protobuf/proto" + "github.com/prometheus/common/model" +) + +// A stateFn is a function that represents a state in a state machine. By +// executing it, the state is progressed to the next state. The stateFn returns +// another stateFn, which represents the new state. The end state is represented +// by nil. +type stateFn func() stateFn + +// ParseError signals errors while parsing the simple and flat text-based +// exchange format. +type ParseError struct { + Line int + Msg string +} + +// Error implements the error interface. +func (e ParseError) Error() string { + return fmt.Sprintf("text format parsing error in line %d: %s", e.Line, e.Msg) +} + +// TextParser is used to parse the simple and flat text-based exchange format. Its +// nil value is ready to use. +type TextParser struct { + metricFamiliesByName map[string]*dto.MetricFamily + buf *bufio.Reader // Where the parsed input is read through. + err error // Most recent error. + lineCount int // Tracks the line count for error messages. + currentByte byte // The most recent byte read. + currentToken bytes.Buffer // Re-used each time a token has to be gathered from multiple bytes. + currentMF *dto.MetricFamily + currentMetric *dto.Metric + currentLabelPair *dto.LabelPair + + // The remaining member variables are only used for summaries/histograms. + currentLabels map[string]string // All labels including '__name__' but excluding 'quantile'/'le' + // Summary specific. + summaries map[uint64]*dto.Metric // Key is created with LabelsToSignature. + currentQuantile float64 + // Histogram specific. + histograms map[uint64]*dto.Metric // Key is created with LabelsToSignature. + currentBucket float64 + // These tell us if the currently processed line ends on '_count' or + // '_sum' respectively and belong to a summary/histogram, representing the sample + // count and sum of that summary/histogram. + currentIsSummaryCount, currentIsSummarySum bool + currentIsHistogramCount, currentIsHistogramSum bool +} + +// TextToMetricFamilies reads 'in' as the simple and flat text-based exchange +// format and creates MetricFamily proto messages. It returns the MetricFamily +// proto messages in a map where the metric names are the keys, along with any +// error encountered. +// +// If the input contains duplicate metrics (i.e. lines with the same metric name +// and exactly the same label set), the resulting MetricFamily will contain +// duplicate Metric proto messages. Similar is true for duplicate label +// names. Checks for duplicates have to be performed separately, if required. +// Also note that neither the metrics within each MetricFamily are sorted nor +// the label pairs within each Metric. Sorting is not required for the most +// frequent use of this method, which is sample ingestion in the Prometheus +// server. However, for presentation purposes, you might want to sort the +// metrics, and in some cases, you must sort the labels, e.g. for consumption by +// the metric family injection hook of the Prometheus registry. +// +// Summaries and histograms are rather special beasts. You would probably not +// use them in the simple text format anyway. This method can deal with +// summaries and histograms if they are presented in exactly the way the +// text.Create function creates them. +// +// This method must not be called concurrently. If you want to parse different +// input concurrently, instantiate a separate Parser for each goroutine. +func (p *TextParser) TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricFamily, error) { + p.reset(in) + for nextState := p.startOfLine; nextState != nil; nextState = nextState() { + // Magic happens here... + } + // Get rid of empty metric families. + for k, mf := range p.metricFamiliesByName { + if len(mf.GetMetric()) == 0 { + delete(p.metricFamiliesByName, k) + } + } + return p.metricFamiliesByName, p.err +} + +func (p *TextParser) reset(in io.Reader) { + p.metricFamiliesByName = map[string]*dto.MetricFamily{} + if p.buf == nil { + p.buf = bufio.NewReader(in) + } else { + p.buf.Reset(in) + } + p.err = nil + p.lineCount = 0 + if p.summaries == nil || len(p.summaries) > 0 { + p.summaries = map[uint64]*dto.Metric{} + } + if p.histograms == nil || len(p.histograms) > 0 { + p.histograms = map[uint64]*dto.Metric{} + } + p.currentQuantile = math.NaN() + p.currentBucket = math.NaN() +} + +// startOfLine represents the state where the next byte read from p.buf is the +// start of a line (or whitespace leading up to it). +func (p *TextParser) startOfLine() stateFn { + p.lineCount++ + if p.skipBlankTab(); p.err != nil { + // End of input reached. This is the only case where + // that is not an error but a signal that we are done. + p.err = nil + return nil + } + switch p.currentByte { + case '#': + return p.startComment + case '\n': + return p.startOfLine // Empty line, start the next one. + } + return p.readingMetricName +} + +// startComment represents the state where the next byte read from p.buf is the +// start of a comment (or whitespace leading up to it). +func (p *TextParser) startComment() stateFn { + if p.skipBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + if p.currentByte == '\n' { + return p.startOfLine + } + if p.readTokenUntilWhitespace(); p.err != nil { + return nil // Unexpected end of input. + } + // If we have hit the end of line already, there is nothing left + // to do. This is not considered a syntax error. + if p.currentByte == '\n' { + return p.startOfLine + } + keyword := p.currentToken.String() + if keyword != "HELP" && keyword != "TYPE" { + // Generic comment, ignore by fast forwarding to end of line. + for p.currentByte != '\n' { + if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil { + return nil // Unexpected end of input. + } + } + return p.startOfLine + } + // There is something. Next has to be a metric name. + if p.skipBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + if p.readTokenAsMetricName(); p.err != nil { + return nil // Unexpected end of input. + } + if p.currentByte == '\n' { + // At the end of the line already. + // Again, this is not considered a syntax error. + return p.startOfLine + } + if !isBlankOrTab(p.currentByte) { + p.parseError("invalid metric name in comment") + return nil + } + p.setOrCreateCurrentMF() + if p.skipBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + if p.currentByte == '\n' { + // At the end of the line already. + // Again, this is not considered a syntax error. + return p.startOfLine + } + switch keyword { + case "HELP": + return p.readingHelp + case "TYPE": + return p.readingType + } + panic(fmt.Sprintf("code error: unexpected keyword %q", keyword)) +} + +// readingMetricName represents the state where the last byte read (now in +// p.currentByte) is the first byte of a metric name. +func (p *TextParser) readingMetricName() stateFn { + if p.readTokenAsMetricName(); p.err != nil { + return nil + } + if p.currentToken.Len() == 0 { + p.parseError("invalid metric name") + return nil + } + p.setOrCreateCurrentMF() + // Now is the time to fix the type if it hasn't happened yet. + if p.currentMF.Type == nil { + p.currentMF.Type = dto.MetricType_UNTYPED.Enum() + } + p.currentMetric = &dto.Metric{} + // Do not append the newly created currentMetric to + // currentMF.Metric right now. First wait if this is a summary, + // and the metric exists already, which we can only know after + // having read all the labels. + if p.skipBlankTabIfCurrentBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + return p.readingLabels +} + +// readingLabels represents the state where the last byte read (now in +// p.currentByte) is either the first byte of the label set (i.e. a '{'), or the +// first byte of the value (otherwise). +func (p *TextParser) readingLabels() stateFn { + // Summaries/histograms are special. We have to reset the + // currentLabels map, currentQuantile and currentBucket before starting to + // read labels. + if p.currentMF.GetType() == dto.MetricType_SUMMARY || p.currentMF.GetType() == dto.MetricType_HISTOGRAM { + p.currentLabels = map[string]string{} + p.currentLabels[string(model.MetricNameLabel)] = p.currentMF.GetName() + p.currentQuantile = math.NaN() + p.currentBucket = math.NaN() + } + if p.currentByte != '{' { + return p.readingValue + } + return p.startLabelName +} + +// startLabelName represents the state where the next byte read from p.buf is +// the start of a label name (or whitespace leading up to it). +func (p *TextParser) startLabelName() stateFn { + if p.skipBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + if p.currentByte == '}' { + if p.skipBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + return p.readingValue + } + if p.readTokenAsLabelName(); p.err != nil { + return nil // Unexpected end of input. + } + if p.currentToken.Len() == 0 { + p.parseError(fmt.Sprintf("invalid label name for metric %q", p.currentMF.GetName())) + return nil + } + p.currentLabelPair = &dto.LabelPair{Name: proto.String(p.currentToken.String())} + if p.currentLabelPair.GetName() == string(model.MetricNameLabel) { + p.parseError(fmt.Sprintf("label name %q is reserved", model.MetricNameLabel)) + return nil + } + // Special summary/histogram treatment. Don't add 'quantile' and 'le' + // labels to 'real' labels. + if !(p.currentMF.GetType() == dto.MetricType_SUMMARY && p.currentLabelPair.GetName() == model.QuantileLabel) && + !(p.currentMF.GetType() == dto.MetricType_HISTOGRAM && p.currentLabelPair.GetName() == model.BucketLabel) { + p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPair) + } + if p.skipBlankTabIfCurrentBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + if p.currentByte != '=' { + p.parseError(fmt.Sprintf("expected '=' after label name, found %q", p.currentByte)) + return nil + } + return p.startLabelValue +} + +// startLabelValue represents the state where the next byte read from p.buf is +// the start of a (quoted) label value (or whitespace leading up to it). +func (p *TextParser) startLabelValue() stateFn { + if p.skipBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + if p.currentByte != '"' { + p.parseError(fmt.Sprintf("expected '\"' at start of label value, found %q", p.currentByte)) + return nil + } + if p.readTokenAsLabelValue(); p.err != nil { + return nil + } + p.currentLabelPair.Value = proto.String(p.currentToken.String()) + // Special treatment of summaries: + // - Quantile labels are special, will result in dto.Quantile later. + // - Other labels have to be added to currentLabels for signature calculation. + if p.currentMF.GetType() == dto.MetricType_SUMMARY { + if p.currentLabelPair.GetName() == model.QuantileLabel { + if p.currentQuantile, p.err = strconv.ParseFloat(p.currentLabelPair.GetValue(), 64); p.err != nil { + // Create a more helpful error message. + p.parseError(fmt.Sprintf("expected float as value for 'quantile' label, got %q", p.currentLabelPair.GetValue())) + return nil + } + } else { + p.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue() + } + } + // Similar special treatment of histograms. + if p.currentMF.GetType() == dto.MetricType_HISTOGRAM { + if p.currentLabelPair.GetName() == model.BucketLabel { + if p.currentBucket, p.err = strconv.ParseFloat(p.currentLabelPair.GetValue(), 64); p.err != nil { + // Create a more helpful error message. + p.parseError(fmt.Sprintf("expected float as value for 'le' label, got %q", p.currentLabelPair.GetValue())) + return nil + } + } else { + p.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue() + } + } + if p.skipBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + switch p.currentByte { + case ',': + return p.startLabelName + + case '}': + if p.skipBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + return p.readingValue + default: + p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.Value)) + return nil + } +} + +// readingValue represents the state where the last byte read (now in +// p.currentByte) is the first byte of the sample value (i.e. a float). +func (p *TextParser) readingValue() stateFn { + // When we are here, we have read all the labels, so for the + // special case of a summary/histogram, we can finally find out + // if the metric already exists. + if p.currentMF.GetType() == dto.MetricType_SUMMARY { + signature := model.LabelsToSignature(p.currentLabels) + if summary := p.summaries[signature]; summary != nil { + p.currentMetric = summary + } else { + p.summaries[signature] = p.currentMetric + p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric) + } + } else if p.currentMF.GetType() == dto.MetricType_HISTOGRAM { + signature := model.LabelsToSignature(p.currentLabels) + if histogram := p.histograms[signature]; histogram != nil { + p.currentMetric = histogram + } else { + p.histograms[signature] = p.currentMetric + p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric) + } + } else { + p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric) + } + if p.readTokenUntilWhitespace(); p.err != nil { + return nil // Unexpected end of input. + } + value, err := strconv.ParseFloat(p.currentToken.String(), 64) + if err != nil { + // Create a more helpful error message. + p.parseError(fmt.Sprintf("expected float as value, got %q", p.currentToken.String())) + return nil + } + switch p.currentMF.GetType() { + case dto.MetricType_COUNTER: + p.currentMetric.Counter = &dto.Counter{Value: proto.Float64(value)} + case dto.MetricType_GAUGE: + p.currentMetric.Gauge = &dto.Gauge{Value: proto.Float64(value)} + case dto.MetricType_UNTYPED: + p.currentMetric.Untyped = &dto.Untyped{Value: proto.Float64(value)} + case dto.MetricType_SUMMARY: + // *sigh* + if p.currentMetric.Summary == nil { + p.currentMetric.Summary = &dto.Summary{} + } + switch { + case p.currentIsSummaryCount: + p.currentMetric.Summary.SampleCount = proto.Uint64(uint64(value)) + case p.currentIsSummarySum: + p.currentMetric.Summary.SampleSum = proto.Float64(value) + case !math.IsNaN(p.currentQuantile): + p.currentMetric.Summary.Quantile = append( + p.currentMetric.Summary.Quantile, + &dto.Quantile{ + Quantile: proto.Float64(p.currentQuantile), + Value: proto.Float64(value), + }, + ) + } + case dto.MetricType_HISTOGRAM: + // *sigh* + if p.currentMetric.Histogram == nil { + p.currentMetric.Histogram = &dto.Histogram{} + } + switch { + case p.currentIsHistogramCount: + p.currentMetric.Histogram.SampleCount = proto.Uint64(uint64(value)) + case p.currentIsHistogramSum: + p.currentMetric.Histogram.SampleSum = proto.Float64(value) + case !math.IsNaN(p.currentBucket): + p.currentMetric.Histogram.Bucket = append( + p.currentMetric.Histogram.Bucket, + &dto.Bucket{ + UpperBound: proto.Float64(p.currentBucket), + CumulativeCount: proto.Uint64(uint64(value)), + }, + ) + } + default: + p.err = fmt.Errorf("unexpected type for metric name %q", p.currentMF.GetName()) + } + if p.currentByte == '\n' { + return p.startOfLine + } + return p.startTimestamp +} + +// startTimestamp represents the state where the next byte read from p.buf is +// the start of the timestamp (or whitespace leading up to it). +func (p *TextParser) startTimestamp() stateFn { + if p.skipBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + if p.readTokenUntilWhitespace(); p.err != nil { + return nil // Unexpected end of input. + } + timestamp, err := strconv.ParseInt(p.currentToken.String(), 10, 64) + if err != nil { + // Create a more helpful error message. + p.parseError(fmt.Sprintf("expected integer as timestamp, got %q", p.currentToken.String())) + return nil + } + p.currentMetric.TimestampMs = proto.Int64(timestamp) + if p.readTokenUntilNewline(false); p.err != nil { + return nil // Unexpected end of input. + } + if p.currentToken.Len() > 0 { + p.parseError(fmt.Sprintf("spurious string after timestamp: %q", p.currentToken.String())) + return nil + } + return p.startOfLine +} + +// readingHelp represents the state where the last byte read (now in +// p.currentByte) is the first byte of the docstring after 'HELP'. +func (p *TextParser) readingHelp() stateFn { + if p.currentMF.Help != nil { + p.parseError(fmt.Sprintf("second HELP line for metric name %q", p.currentMF.GetName())) + return nil + } + // Rest of line is the docstring. + if p.readTokenUntilNewline(true); p.err != nil { + return nil // Unexpected end of input. + } + p.currentMF.Help = proto.String(p.currentToken.String()) + return p.startOfLine +} + +// readingType represents the state where the last byte read (now in +// p.currentByte) is the first byte of the type hint after 'HELP'. +func (p *TextParser) readingType() stateFn { + if p.currentMF.Type != nil { + p.parseError(fmt.Sprintf("second TYPE line for metric name %q, or TYPE reported after samples", p.currentMF.GetName())) + return nil + } + // Rest of line is the type. + if p.readTokenUntilNewline(false); p.err != nil { + return nil // Unexpected end of input. + } + metricType, ok := dto.MetricType_value[strings.ToUpper(p.currentToken.String())] + if !ok { + p.parseError(fmt.Sprintf("unknown metric type %q", p.currentToken.String())) + return nil + } + p.currentMF.Type = dto.MetricType(metricType).Enum() + return p.startOfLine +} + +// parseError sets p.err to a ParseError at the current line with the given +// message. +func (p *TextParser) parseError(msg string) { + p.err = ParseError{ + Line: p.lineCount, + Msg: msg, + } +} + +// skipBlankTab reads (and discards) bytes from p.buf until it encounters a byte +// that is neither ' ' nor '\t'. That byte is left in p.currentByte. +func (p *TextParser) skipBlankTab() { + for { + if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil || !isBlankOrTab(p.currentByte) { + return + } + } +} + +// skipBlankTabIfCurrentBlankTab works exactly as skipBlankTab but doesn't do +// anything if p.currentByte is neither ' ' nor '\t'. +func (p *TextParser) skipBlankTabIfCurrentBlankTab() { + if isBlankOrTab(p.currentByte) { + p.skipBlankTab() + } +} + +// readTokenUntilWhitespace copies bytes from p.buf into p.currentToken. The +// first byte considered is the byte already read (now in p.currentByte). The +// first whitespace byte encountered is still copied into p.currentByte, but not +// into p.currentToken. +func (p *TextParser) readTokenUntilWhitespace() { + p.currentToken.Reset() + for p.err == nil && !isBlankOrTab(p.currentByte) && p.currentByte != '\n' { + p.currentToken.WriteByte(p.currentByte) + p.currentByte, p.err = p.buf.ReadByte() + } +} + +// readTokenUntilNewline copies bytes from p.buf into p.currentToken. The first +// byte considered is the byte already read (now in p.currentByte). The first +// newline byte encountered is still copied into p.currentByte, but not into +// p.currentToken. If recognizeEscapeSequence is true, two escape sequences are +// recognized: '\\' tranlates into '\', and '\n' into a line-feed character. All +// other escape sequences are invalid and cause an error. +func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) { + p.currentToken.Reset() + escaped := false + for p.err == nil { + if recognizeEscapeSequence && escaped { + switch p.currentByte { + case '\\': + p.currentToken.WriteByte(p.currentByte) + case 'n': + p.currentToken.WriteByte('\n') + default: + p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) + return + } + escaped = false + } else { + switch p.currentByte { + case '\n': + return + case '\\': + escaped = true + default: + p.currentToken.WriteByte(p.currentByte) + } + } + p.currentByte, p.err = p.buf.ReadByte() + } +} + +// readTokenAsMetricName copies a metric name from p.buf into p.currentToken. +// The first byte considered is the byte already read (now in p.currentByte). +// The first byte not part of a metric name is still copied into p.currentByte, +// but not into p.currentToken. +func (p *TextParser) readTokenAsMetricName() { + p.currentToken.Reset() + if !isValidMetricNameStart(p.currentByte) { + return + } + for { + p.currentToken.WriteByte(p.currentByte) + p.currentByte, p.err = p.buf.ReadByte() + if p.err != nil || !isValidMetricNameContinuation(p.currentByte) { + return + } + } +} + +// readTokenAsLabelName copies a label name from p.buf into p.currentToken. +// The first byte considered is the byte already read (now in p.currentByte). +// The first byte not part of a label name is still copied into p.currentByte, +// but not into p.currentToken. +func (p *TextParser) readTokenAsLabelName() { + p.currentToken.Reset() + if !isValidLabelNameStart(p.currentByte) { + return + } + for { + p.currentToken.WriteByte(p.currentByte) + p.currentByte, p.err = p.buf.ReadByte() + if p.err != nil || !isValidLabelNameContinuation(p.currentByte) { + return + } + } +} + +// readTokenAsLabelValue copies a label value from p.buf into p.currentToken. +// In contrast to the other 'readTokenAs...' functions, which start with the +// last read byte in p.currentByte, this method ignores p.currentByte and starts +// with reading a new byte from p.buf. The first byte not part of a label value +// is still copied into p.currentByte, but not into p.currentToken. +func (p *TextParser) readTokenAsLabelValue() { + p.currentToken.Reset() + escaped := false + for { + if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil { + return + } + if escaped { + switch p.currentByte { + case '"', '\\': + p.currentToken.WriteByte(p.currentByte) + case 'n': + p.currentToken.WriteByte('\n') + default: + p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) + return + } + escaped = false + continue + } + switch p.currentByte { + case '"': + return + case '\n': + p.parseError(fmt.Sprintf("label value %q contains unescaped new-line", p.currentToken.String())) + return + case '\\': + escaped = true + default: + p.currentToken.WriteByte(p.currentByte) + } + } +} + +func (p *TextParser) setOrCreateCurrentMF() { + p.currentIsSummaryCount = false + p.currentIsSummarySum = false + p.currentIsHistogramCount = false + p.currentIsHistogramSum = false + name := p.currentToken.String() + if p.currentMF = p.metricFamiliesByName[name]; p.currentMF != nil { + return + } + // Try out if this is a _sum or _count for a summary/histogram. + summaryName := summaryMetricName(name) + if p.currentMF = p.metricFamiliesByName[summaryName]; p.currentMF != nil { + if p.currentMF.GetType() == dto.MetricType_SUMMARY { + if isCount(name) { + p.currentIsSummaryCount = true + } + if isSum(name) { + p.currentIsSummarySum = true + } + return + } + } + histogramName := histogramMetricName(name) + if p.currentMF = p.metricFamiliesByName[histogramName]; p.currentMF != nil { + if p.currentMF.GetType() == dto.MetricType_HISTOGRAM { + if isCount(name) { + p.currentIsHistogramCount = true + } + if isSum(name) { + p.currentIsHistogramSum = true + } + return + } + } + p.currentMF = &dto.MetricFamily{Name: proto.String(name)} + p.metricFamiliesByName[name] = p.currentMF +} + +func isValidLabelNameStart(b byte) bool { + return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' +} + +func isValidLabelNameContinuation(b byte) bool { + return isValidLabelNameStart(b) || (b >= '0' && b <= '9') +} + +func isValidMetricNameStart(b byte) bool { + return isValidLabelNameStart(b) || b == ':' +} + +func isValidMetricNameContinuation(b byte) bool { + return isValidLabelNameContinuation(b) || b == ':' +} + +func isBlankOrTab(b byte) bool { + return b == ' ' || b == '\t' +} + +func isCount(name string) bool { + return len(name) > 6 && name[len(name)-6:] == "_count" +} + +func isSum(name string) bool { + return len(name) > 4 && name[len(name)-4:] == "_sum" +} + +func isBucket(name string) bool { + return len(name) > 7 && name[len(name)-7:] == "_bucket" +} + +func summaryMetricName(name string) string { + switch { + case isCount(name): + return name[:len(name)-6] + case isSum(name): + return name[:len(name)-4] + default: + return name + } +} + +func histogramMetricName(name string) string { + switch { + case isCount(name): + return name[:len(name)-6] + case isSum(name): + return name[:len(name)-4] + case isBucket(name): + return name[:len(name)-7] + default: + return name + } +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse_test.go b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse_test.go new file mode 100644 index 000000000000..589c87a9d5fd --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/expfmt/text_parse_test.go @@ -0,0 +1,586 @@ +// Copyright 2014 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expfmt + +import ( + "math" + "strings" + "testing" + + "github.com/golang/protobuf/proto" + dto "github.com/prometheus/client_model/go" +) + +func testTextParse(t testing.TB) { + var scenarios = []struct { + in string + out []*dto.MetricFamily + }{ + // 0: Empty lines as input. + { + in: ` + +`, + out: []*dto.MetricFamily{}, + }, + // 1: Minimal case. + { + in: ` +minimal_metric 1.234 +another_metric -3e3 103948 +# Even that: +no_labels{} 3 +# HELP line for non-existing metric will be ignored. +`, + out: []*dto.MetricFamily{ + &dto.MetricFamily{ + Name: proto.String("minimal_metric"), + Type: dto.MetricType_UNTYPED.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Untyped: &dto.Untyped{ + Value: proto.Float64(1.234), + }, + }, + }, + }, + &dto.MetricFamily{ + Name: proto.String("another_metric"), + Type: dto.MetricType_UNTYPED.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Untyped: &dto.Untyped{ + Value: proto.Float64(-3e3), + }, + TimestampMs: proto.Int64(103948), + }, + }, + }, + &dto.MetricFamily{ + Name: proto.String("no_labels"), + Type: dto.MetricType_UNTYPED.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Untyped: &dto.Untyped{ + Value: proto.Float64(3), + }, + }, + }, + }, + }, + }, + // 2: Counters & gauges, docstrings, various whitespace, escape sequences. + { + in: ` +# A normal comment. +# +# TYPE name counter +name{labelname="val1",basename="basevalue"} NaN +name {labelname="val2",basename="base\"v\\al\nue"} 0.23 1234567890 +# HELP name two-line\n doc str\\ing + + # HELP name2 doc str"ing 2 + # TYPE name2 gauge +name2{labelname="val2" ,basename = "basevalue2" } +Inf 54321 +name2{ labelname = "val1" , }-Inf +`, + out: []*dto.MetricFamily{ + &dto.MetricFamily{ + Name: proto.String("name"), + Help: proto.String("two-line\n doc str\\ing"), + Type: dto.MetricType_COUNTER.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("labelname"), + Value: proto.String("val1"), + }, + &dto.LabelPair{ + Name: proto.String("basename"), + Value: proto.String("basevalue"), + }, + }, + Counter: &dto.Counter{ + Value: proto.Float64(math.NaN()), + }, + }, + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("labelname"), + Value: proto.String("val2"), + }, + &dto.LabelPair{ + Name: proto.String("basename"), + Value: proto.String("base\"v\\al\nue"), + }, + }, + Counter: &dto.Counter{ + Value: proto.Float64(.23), + }, + TimestampMs: proto.Int64(1234567890), + }, + }, + }, + &dto.MetricFamily{ + Name: proto.String("name2"), + Help: proto.String("doc str\"ing 2"), + Type: dto.MetricType_GAUGE.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("labelname"), + Value: proto.String("val2"), + }, + &dto.LabelPair{ + Name: proto.String("basename"), + Value: proto.String("basevalue2"), + }, + }, + Gauge: &dto.Gauge{ + Value: proto.Float64(math.Inf(+1)), + }, + TimestampMs: proto.Int64(54321), + }, + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("labelname"), + Value: proto.String("val1"), + }, + }, + Gauge: &dto.Gauge{ + Value: proto.Float64(math.Inf(-1)), + }, + }, + }, + }, + }, + }, + // 3: The evil summary, mixed with other types and funny comments. + { + in: ` +# TYPE my_summary summary +my_summary{n1="val1",quantile="0.5"} 110 +decoy -1 -2 +my_summary{n1="val1",quantile="0.9"} 140 1 +my_summary_count{n1="val1"} 42 +# Latest timestamp wins in case of a summary. +my_summary_sum{n1="val1"} 4711 2 +fake_sum{n1="val1"} 2001 +# TYPE another_summary summary +another_summary_count{n2="val2",n1="val1"} 20 +my_summary_count{n2="val2",n1="val1"} 5 5 +another_summary{n1="val1",n2="val2",quantile=".3"} -1.2 +my_summary_sum{n1="val2"} 08 15 +my_summary{n1="val3", quantile="0.2"} 4711 + my_summary{n1="val1",n2="val2",quantile="-12.34",} NaN +# some +# funny comments +# HELP +# HELP +# HELP my_summary +# HELP my_summary +`, + out: []*dto.MetricFamily{ + &dto.MetricFamily{ + Name: proto.String("fake_sum"), + Type: dto.MetricType_UNTYPED.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("n1"), + Value: proto.String("val1"), + }, + }, + Untyped: &dto.Untyped{ + Value: proto.Float64(2001), + }, + }, + }, + }, + &dto.MetricFamily{ + Name: proto.String("decoy"), + Type: dto.MetricType_UNTYPED.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Untyped: &dto.Untyped{ + Value: proto.Float64(-1), + }, + TimestampMs: proto.Int64(-2), + }, + }, + }, + &dto.MetricFamily{ + Name: proto.String("my_summary"), + Type: dto.MetricType_SUMMARY.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("n1"), + Value: proto.String("val1"), + }, + }, + Summary: &dto.Summary{ + SampleCount: proto.Uint64(42), + SampleSum: proto.Float64(4711), + Quantile: []*dto.Quantile{ + &dto.Quantile{ + Quantile: proto.Float64(0.5), + Value: proto.Float64(110), + }, + &dto.Quantile{ + Quantile: proto.Float64(0.9), + Value: proto.Float64(140), + }, + }, + }, + TimestampMs: proto.Int64(2), + }, + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("n2"), + Value: proto.String("val2"), + }, + &dto.LabelPair{ + Name: proto.String("n1"), + Value: proto.String("val1"), + }, + }, + Summary: &dto.Summary{ + SampleCount: proto.Uint64(5), + Quantile: []*dto.Quantile{ + &dto.Quantile{ + Quantile: proto.Float64(-12.34), + Value: proto.Float64(math.NaN()), + }, + }, + }, + TimestampMs: proto.Int64(5), + }, + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("n1"), + Value: proto.String("val2"), + }, + }, + Summary: &dto.Summary{ + SampleSum: proto.Float64(8), + }, + TimestampMs: proto.Int64(15), + }, + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("n1"), + Value: proto.String("val3"), + }, + }, + Summary: &dto.Summary{ + Quantile: []*dto.Quantile{ + &dto.Quantile{ + Quantile: proto.Float64(0.2), + Value: proto.Float64(4711), + }, + }, + }, + }, + }, + }, + &dto.MetricFamily{ + Name: proto.String("another_summary"), + Type: dto.MetricType_SUMMARY.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Label: []*dto.LabelPair{ + &dto.LabelPair{ + Name: proto.String("n2"), + Value: proto.String("val2"), + }, + &dto.LabelPair{ + Name: proto.String("n1"), + Value: proto.String("val1"), + }, + }, + Summary: &dto.Summary{ + SampleCount: proto.Uint64(20), + Quantile: []*dto.Quantile{ + &dto.Quantile{ + Quantile: proto.Float64(0.3), + Value: proto.Float64(-1.2), + }, + }, + }, + }, + }, + }, + }, + }, + // 4: The histogram. + { + in: ` +# HELP request_duration_microseconds The response latency. +# TYPE request_duration_microseconds histogram +request_duration_microseconds_bucket{le="100"} 123 +request_duration_microseconds_bucket{le="120"} 412 +request_duration_microseconds_bucket{le="144"} 592 +request_duration_microseconds_bucket{le="172.8"} 1524 +request_duration_microseconds_bucket{le="+Inf"} 2693 +request_duration_microseconds_sum 1.7560473e+06 +request_duration_microseconds_count 2693 +`, + out: []*dto.MetricFamily{ + { + Name: proto.String("request_duration_microseconds"), + Help: proto.String("The response latency."), + Type: dto.MetricType_HISTOGRAM.Enum(), + Metric: []*dto.Metric{ + &dto.Metric{ + Histogram: &dto.Histogram{ + SampleCount: proto.Uint64(2693), + SampleSum: proto.Float64(1756047.3), + Bucket: []*dto.Bucket{ + &dto.Bucket{ + UpperBound: proto.Float64(100), + CumulativeCount: proto.Uint64(123), + }, + &dto.Bucket{ + UpperBound: proto.Float64(120), + CumulativeCount: proto.Uint64(412), + }, + &dto.Bucket{ + UpperBound: proto.Float64(144), + CumulativeCount: proto.Uint64(592), + }, + &dto.Bucket{ + UpperBound: proto.Float64(172.8), + CumulativeCount: proto.Uint64(1524), + }, + &dto.Bucket{ + UpperBound: proto.Float64(math.Inf(+1)), + CumulativeCount: proto.Uint64(2693), + }, + }, + }, + }, + }, + }, + }, + }, + } + + for i, scenario := range scenarios { + out, err := parser.TextToMetricFamilies(strings.NewReader(scenario.in)) + if err != nil { + t.Errorf("%d. error: %s", i, err) + continue + } + if expected, got := len(scenario.out), len(out); expected != got { + t.Errorf( + "%d. expected %d MetricFamilies, got %d", + i, expected, got, + ) + } + for _, expected := range scenario.out { + got, ok := out[expected.GetName()] + if !ok { + t.Errorf( + "%d. expected MetricFamily %q, found none", + i, expected.GetName(), + ) + continue + } + if expected.String() != got.String() { + t.Errorf( + "%d. expected MetricFamily %s, got %s", + i, expected, got, + ) + } + } + } +} + +func TestTextParse(t *testing.T) { + testTextParse(t) +} + +func BenchmarkTextParse(b *testing.B) { + for i := 0; i < b.N; i++ { + testTextParse(b) + } +} + +func testTextParseError(t testing.TB) { + var scenarios = []struct { + in string + err string + }{ + // 0: No new-line at end of input. + { + in: `bla 3.14`, + err: "EOF", + }, + // 1: Invalid escape sequence in label value. + { + in: `metric{label="\t"} 3.14`, + err: "text format parsing error in line 1: invalid escape sequence", + }, + // 2: Newline in label value. + { + in: ` +metric{label="new +line"} 3.14 +`, + err: `text format parsing error in line 2: label value "new" contains unescaped new-line`, + }, + // 3: + { + in: `metric{@="bla"} 3.14`, + err: "text format parsing error in line 1: invalid label name for metric", + }, + // 4: + { + in: `metric{__name__="bla"} 3.14`, + err: `text format parsing error in line 1: label name "__name__" is reserved`, + }, + // 5: + { + in: `metric{label+="bla"} 3.14`, + err: "text format parsing error in line 1: expected '=' after label name", + }, + // 6: + { + in: `metric{label=bla} 3.14`, + err: "text format parsing error in line 1: expected '\"' at start of label value", + }, + // 7: + { + in: ` +# TYPE metric summary +metric{quantile="bla"} 3.14 +`, + err: "text format parsing error in line 3: expected float as value for 'quantile' label", + }, + // 8: + { + in: `metric{label="bla"+} 3.14`, + err: "text format parsing error in line 1: unexpected end of label value", + }, + // 9: + { + in: `metric{label="bla"} 3.14 2.72 +`, + err: "text format parsing error in line 1: expected integer as timestamp", + }, + // 10: + { + in: `metric{label="bla"} 3.14 2 3 +`, + err: "text format parsing error in line 1: spurious string after timestamp", + }, + // 11: + { + in: `metric{label="bla"} blubb +`, + err: "text format parsing error in line 1: expected float as value", + }, + // 12: + { + in: ` +# HELP metric one +# HELP metric two +`, + err: "text format parsing error in line 3: second HELP line for metric name", + }, + // 13: + { + in: ` +# TYPE metric counter +# TYPE metric untyped +`, + err: `text format parsing error in line 3: second TYPE line for metric name "metric", or TYPE reported after samples`, + }, + // 14: + { + in: ` +metric 4.12 +# TYPE metric counter +`, + err: `text format parsing error in line 3: second TYPE line for metric name "metric", or TYPE reported after samples`, + }, + // 14: + { + in: ` +# TYPE metric bla +`, + err: "text format parsing error in line 2: unknown metric type", + }, + // 15: + { + in: ` +# TYPE met-ric +`, + err: "text format parsing error in line 2: invalid metric name in comment", + }, + // 16: + { + in: `@invalidmetric{label="bla"} 3.14 2`, + err: "text format parsing error in line 1: invalid metric name", + }, + // 17: + { + in: `{label="bla"} 3.14 2`, + err: "text format parsing error in line 1: invalid metric name", + }, + // 18: + { + in: ` +# TYPE metric histogram +metric_bucket{le="bla"} 3.14 +`, + err: "text format parsing error in line 3: expected float as value for 'le' label", + }, + } + + for i, scenario := range scenarios { + _, err := parser.TextToMetricFamilies(strings.NewReader(scenario.in)) + if err == nil { + t.Errorf("%d. expected error, got nil", i) + continue + } + if expected, got := scenario.err, err.Error(); strings.Index(got, expected) != 0 { + t.Errorf( + "%d. expected error starting with %q, got %q", + i, expected, got, + ) + } + } + +} + +func TestTextParseError(t *testing.T) { + testTextParseError(t) +} + +func BenchmarkParseError(b *testing.B) { + for i := 0; i < b.N; i++ { + testTextParseError(b) + } +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/fingerprinting.go b/Godeps/_workspace/src/github.com/prometheus/common/model/fingerprinting.go new file mode 100644 index 000000000000..fc4de4106e85 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/fingerprinting.go @@ -0,0 +1,105 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "fmt" + "strconv" +) + +// Fingerprint provides a hash-capable representation of a Metric. +// For our purposes, FNV-1A 64-bit is used. +type Fingerprint uint64 + +// FingerprintFromString transforms a string representation into a Fingerprint. +func FingerprintFromString(s string) (Fingerprint, error) { + num, err := strconv.ParseUint(s, 16, 64) + return Fingerprint(num), err +} + +// ParseFingerprint parses the input string into a fingerprint. +func ParseFingerprint(s string) (Fingerprint, error) { + num, err := strconv.ParseUint(s, 16, 64) + if err != nil { + return 0, err + } + return Fingerprint(num), nil +} + +func (f Fingerprint) String() string { + return fmt.Sprintf("%016x", uint64(f)) +} + +// Fingerprints represents a collection of Fingerprint subject to a given +// natural sorting scheme. It implements sort.Interface. +type Fingerprints []Fingerprint + +// Len implements sort.Interface. +func (f Fingerprints) Len() int { + return len(f) +} + +// Less implements sort.Interface. +func (f Fingerprints) Less(i, j int) bool { + return f[i] < f[j] +} + +// Swap implements sort.Interface. +func (f Fingerprints) Swap(i, j int) { + f[i], f[j] = f[j], f[i] +} + +// FingerprintSet is a set of Fingerprints. +type FingerprintSet map[Fingerprint]struct{} + +// Equal returns true if both sets contain the same elements (and not more). +func (s FingerprintSet) Equal(o FingerprintSet) bool { + if len(s) != len(o) { + return false + } + + for k := range s { + if _, ok := o[k]; !ok { + return false + } + } + + return true +} + +// Intersection returns the elements contained in both sets. +func (s FingerprintSet) Intersection(o FingerprintSet) FingerprintSet { + myLength, otherLength := len(s), len(o) + if myLength == 0 || otherLength == 0 { + return FingerprintSet{} + } + + subSet := s + superSet := o + + if otherLength < myLength { + subSet = o + superSet = s + } + + out := FingerprintSet{} + + for k := range subSet { + if _, ok := superSet[k]; ok { + out[k] = struct{}{} + } + } + + return out +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/labels.go b/Godeps/_workspace/src/github.com/prometheus/common/model/labels.go new file mode 100644 index 000000000000..6459c8f791b5 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/labels.go @@ -0,0 +1,188 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "encoding/json" + "fmt" + "regexp" + "sort" + "strings" +) + +const ( + // AlertNameLabel is the name of the label containing the an alert's name. + AlertNameLabel = "alertname" + + // ExportedLabelPrefix is the prefix to prepend to the label names present in + // exported metrics if a label of the same name is added by the server. + ExportedLabelPrefix = "exported_" + + // MetricNameLabel is the label name indicating the metric name of a + // timeseries. + MetricNameLabel = "__name__" + + // SchemeLabel is the name of the label that holds the scheme on which to + // scrape a target. + SchemeLabel = "__scheme__" + + // AddressLabel is the name of the label that holds the address of + // a scrape target. + AddressLabel = "__address__" + + // MetricsPathLabel is the name of the label that holds the path on which to + // scrape a target. + MetricsPathLabel = "__metrics_path__" + + // ReservedLabelPrefix is a prefix which is not legal in user-supplied + // label names. + ReservedLabelPrefix = "__" + + // MetaLabelPrefix is a prefix for labels that provide meta information. + // Labels with this prefix are used for intermediate label processing and + // will not be attached to time series. + MetaLabelPrefix = "__meta_" + + // TmpLabelPrefix is a prefix for temporary labels as part of relabelling. + // Labels with this prefix are used for intermediate label processing and + // will not be attached to time series. This is reserved for use in + // Prometheus configuration files by users. + TmpLabelPrefix = "__tmp_" + + // ParamLabelPrefix is a prefix for labels that provide URL parameters + // used to scrape a target. + ParamLabelPrefix = "__param_" + + // JobLabel is the label name indicating the job from which a timeseries + // was scraped. + JobLabel = "job" + + // InstanceLabel is the label name used for the instance label. + InstanceLabel = "instance" + + // BucketLabel is used for the label that defines the upper bound of a + // bucket of a histogram ("le" -> "less or equal"). + BucketLabel = "le" + + // QuantileLabel is used for the label that defines the quantile in a + // summary. + QuantileLabel = "quantile" +) + +// LabelNameRE is a regular expression matching valid label names. +var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$") + +// A LabelName is a key for a LabelSet or Metric. It has a value associated +// therewith. +type LabelName string + +// UnmarshalYAML implements the yaml.Unmarshaler interface. +func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error { + var s string + if err := unmarshal(&s); err != nil { + return err + } + if !LabelNameRE.MatchString(s) { + return fmt.Errorf("%q is not a valid label name", s) + } + *ln = LabelName(s) + return nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (ln *LabelName) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + if !LabelNameRE.MatchString(s) { + return fmt.Errorf("%q is not a valid label name", s) + } + *ln = LabelName(s) + return nil +} + +// LabelNames is a sortable LabelName slice. In implements sort.Interface. +type LabelNames []LabelName + +func (l LabelNames) Len() int { + return len(l) +} + +func (l LabelNames) Less(i, j int) bool { + return l[i] < l[j] +} + +func (l LabelNames) Swap(i, j int) { + l[i], l[j] = l[j], l[i] +} + +func (l LabelNames) String() string { + labelStrings := make([]string, 0, len(l)) + for _, label := range l { + labelStrings = append(labelStrings, string(label)) + } + return strings.Join(labelStrings, ", ") +} + +// A LabelValue is an associated value for a LabelName. +type LabelValue string + +// LabelValues is a sortable LabelValue slice. It implements sort.Interface. +type LabelValues []LabelValue + +func (l LabelValues) Len() int { + return len(l) +} + +func (l LabelValues) Less(i, j int) bool { + return sort.StringsAreSorted([]string{string(l[i]), string(l[j])}) +} + +func (l LabelValues) Swap(i, j int) { + l[i], l[j] = l[j], l[i] +} + +// LabelPair pairs a name with a value. +type LabelPair struct { + Name LabelName + Value LabelValue +} + +// LabelPairs is a sortable slice of LabelPair pointers. It implements +// sort.Interface. +type LabelPairs []*LabelPair + +func (l LabelPairs) Len() int { + return len(l) +} + +func (l LabelPairs) Less(i, j int) bool { + switch { + case l[i].Name > l[j].Name: + return false + case l[i].Name < l[j].Name: + return true + case l[i].Value > l[j].Value: + return false + case l[i].Value < l[j].Value: + return true + default: + return false + } +} + +func (l LabelPairs) Swap(i, j int) { + l[i], l[j] = l[j], l[i] +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/labels_test.go b/Godeps/_workspace/src/github.com/prometheus/common/model/labels_test.go new file mode 100644 index 000000000000..ab17025c76aa --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/labels_test.go @@ -0,0 +1,91 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "sort" + "testing" +) + +func testLabelNames(t testing.TB) { + var scenarios = []struct { + in LabelNames + out LabelNames + }{ + { + in: LabelNames{"ZZZ", "zzz"}, + out: LabelNames{"ZZZ", "zzz"}, + }, + { + in: LabelNames{"aaa", "AAA"}, + out: LabelNames{"AAA", "aaa"}, + }, + } + + for i, scenario := range scenarios { + sort.Sort(scenario.in) + + for j, expected := range scenario.out { + if expected != scenario.in[j] { + t.Errorf("%d.%d expected %s, got %s", i, j, expected, scenario.in[j]) + } + } + } +} + +func TestLabelNames(t *testing.T) { + testLabelNames(t) +} + +func BenchmarkLabelNames(b *testing.B) { + for i := 0; i < b.N; i++ { + testLabelNames(b) + } +} + +func testLabelValues(t testing.TB) { + var scenarios = []struct { + in LabelValues + out LabelValues + }{ + { + in: LabelValues{"ZZZ", "zzz"}, + out: LabelValues{"ZZZ", "zzz"}, + }, + { + in: LabelValues{"aaa", "AAA"}, + out: LabelValues{"AAA", "aaa"}, + }, + } + + for i, scenario := range scenarios { + sort.Sort(scenario.in) + + for j, expected := range scenario.out { + if expected != scenario.in[j] { + t.Errorf("%d.%d expected %s, got %s", i, j, expected, scenario.in[j]) + } + } + } +} + +func TestLabelValues(t *testing.T) { + testLabelValues(t) +} + +func BenchmarkLabelValues(b *testing.B) { + for i := 0; i < b.N; i++ { + testLabelValues(b) + } +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/labelset.go b/Godeps/_workspace/src/github.com/prometheus/common/model/labelset.go new file mode 100644 index 000000000000..142b9d1e2d3a --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/labelset.go @@ -0,0 +1,153 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "encoding/json" + "fmt" + "sort" + "strings" +) + +// A LabelSet is a collection of LabelName and LabelValue pairs. The LabelSet +// may be fully-qualified down to the point where it may resolve to a single +// Metric in the data store or not. All operations that occur within the realm +// of a LabelSet can emit a vector of Metric entities to which the LabelSet may +// match. +type LabelSet map[LabelName]LabelValue + +func (ls LabelSet) Equal(o LabelSet) bool { + if len(ls) != len(o) { + return false + } + for ln, lv := range ls { + olv, ok := o[ln] + if !ok { + return false + } + if olv != lv { + return false + } + } + return true +} + +// Before compares the metrics, using the following criteria: +// +// If m has fewer labels than o, it is before o. If it has more, it is not. +// +// If the number of labels is the same, the superset of all label names is +// sorted alphanumerically. The first differing label pair found in that order +// determines the outcome: If the label does not exist at all in m, then m is +// before o, and vice versa. Otherwise the label value is compared +// alphanumerically. +// +// If m and o are equal, the method returns false. +func (ls LabelSet) Before(o LabelSet) bool { + if len(ls) < len(o) { + return true + } + if len(ls) > len(o) { + return false + } + + lns := make(LabelNames, 0, len(ls)+len(o)) + for ln := range ls { + lns = append(lns, ln) + } + for ln := range o { + lns = append(lns, ln) + } + // It's probably not worth it to de-dup lns. + sort.Sort(lns) + for _, ln := range lns { + mlv, ok := ls[ln] + if !ok { + return true + } + olv, ok := o[ln] + if !ok { + return false + } + if mlv < olv { + return true + } + if mlv > olv { + return false + } + } + return false +} + +func (ls LabelSet) Clone() LabelSet { + lsn := make(LabelSet, len(ls)) + for ln, lv := range ls { + lsn[ln] = lv + } + return lsn +} + +// Merge is a helper function to non-destructively merge two label sets. +func (l LabelSet) Merge(other LabelSet) LabelSet { + result := make(LabelSet, len(l)) + + for k, v := range l { + result[k] = v + } + + for k, v := range other { + result[k] = v + } + + return result +} + +func (l LabelSet) String() string { + lstrs := make([]string, 0, len(l)) + for l, v := range l { + lstrs = append(lstrs, fmt.Sprintf("%s=%q", l, v)) + } + + sort.Strings(lstrs) + return fmt.Sprintf("{%s}", strings.Join(lstrs, ", ")) +} + +// Fingerprint returns the LabelSet's fingerprint. +func (ls LabelSet) Fingerprint() Fingerprint { + return labelSetToFingerprint(ls) +} + +// FastFingerprint returns the LabelSet's Fingerprint calculated by a faster hashing +// algorithm, which is, however, more susceptible to hash collisions. +func (ls LabelSet) FastFingerprint() Fingerprint { + return labelSetToFastFingerprint(ls) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (l *LabelSet) UnmarshalJSON(b []byte) error { + var m map[LabelName]LabelValue + if err := json.Unmarshal(b, &m); err != nil { + return err + } + // encoding/json only unmarshals maps of the form map[string]T. It treats + // LabelName as a string and does not call its UnmarshalJSON method. + // Thus, we have to replicate the behavior here. + for ln := range m { + if !LabelNameRE.MatchString(string(ln)) { + return fmt.Errorf("%q is not a valid label name", ln) + } + } + *l = LabelSet(m) + return nil +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/metric.go b/Godeps/_workspace/src/github.com/prometheus/common/model/metric.go new file mode 100644 index 000000000000..25fc3c942585 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/metric.go @@ -0,0 +1,81 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "fmt" + "sort" + "strings" +) + +var separator = []byte{0} + +// A Metric is similar to a LabelSet, but the key difference is that a Metric is +// a singleton and refers to one and only one stream of samples. +type Metric LabelSet + +// Equal compares the metrics. +func (m Metric) Equal(o Metric) bool { + return LabelSet(m).Equal(LabelSet(o)) +} + +// Before compares the metrics' underlying label sets. +func (m Metric) Before(o Metric) bool { + return LabelSet(m).Before(LabelSet(o)) +} + +// Clone returns a copy of the Metric. +func (m Metric) Clone() Metric { + clone := Metric{} + for k, v := range m { + clone[k] = v + } + return clone +} + +func (m Metric) String() string { + metricName, hasName := m[MetricNameLabel] + numLabels := len(m) - 1 + if !hasName { + numLabels = len(m) + } + labelStrings := make([]string, 0, numLabels) + for label, value := range m { + if label != MetricNameLabel { + labelStrings = append(labelStrings, fmt.Sprintf("%s=%q", label, value)) + } + } + + switch numLabels { + case 0: + if hasName { + return string(metricName) + } + return "{}" + default: + sort.Strings(labelStrings) + return fmt.Sprintf("%s{%s}", metricName, strings.Join(labelStrings, ", ")) + } +} + +// Fingerprint returns a Metric's Fingerprint. +func (m Metric) Fingerprint() Fingerprint { + return LabelSet(m).Fingerprint() +} + +// FastFingerprint returns a Metric's Fingerprint calculated by a faster hashing +// algorithm, which is, however, more susceptible to hash collisions. +func (m Metric) FastFingerprint() Fingerprint { + return LabelSet(m).FastFingerprint() +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/metric_test.go b/Godeps/_workspace/src/github.com/prometheus/common/model/metric_test.go new file mode 100644 index 000000000000..5c7cfceafe96 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/metric_test.go @@ -0,0 +1,83 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import "testing" + +func testMetric(t testing.TB) { + var scenarios = []struct { + input LabelSet + fingerprint Fingerprint + fastFingerprint Fingerprint + }{ + { + input: LabelSet{}, + fingerprint: 14695981039346656037, + fastFingerprint: 14695981039346656037, + }, + { + input: LabelSet{ + "first_name": "electro", + "occupation": "robot", + "manufacturer": "westinghouse", + }, + fingerprint: 5911716720268894962, + fastFingerprint: 11310079640881077873, + }, + { + input: LabelSet{ + "x": "y", + }, + fingerprint: 8241431561484471700, + fastFingerprint: 13948396922932177635, + }, + { + input: LabelSet{ + "a": "bb", + "b": "c", + }, + fingerprint: 3016285359649981711, + fastFingerprint: 3198632812309449502, + }, + { + input: LabelSet{ + "a": "b", + "bb": "c", + }, + fingerprint: 7122421792099404749, + fastFingerprint: 5774953389407657638, + }, + } + + for i, scenario := range scenarios { + input := Metric(scenario.input) + + if scenario.fingerprint != input.Fingerprint() { + t.Errorf("%d. expected %d, got %d", i, scenario.fingerprint, input.Fingerprint()) + } + if scenario.fastFingerprint != input.FastFingerprint() { + t.Errorf("%d. expected %d, got %d", i, scenario.fastFingerprint, input.FastFingerprint()) + } + } +} + +func TestMetric(t *testing.T) { + testMetric(t) +} + +func BenchmarkMetric(b *testing.B) { + for i := 0; i < b.N; i++ { + testMetric(b) + } +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/model.go b/Godeps/_workspace/src/github.com/prometheus/common/model/model.go new file mode 100644 index 000000000000..88f013a47a41 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/model.go @@ -0,0 +1,16 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package model contains common data structures that are shared across +// Prometheus componenets and libraries. +package model diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/signature.go b/Godeps/_workspace/src/github.com/prometheus/common/model/signature.go new file mode 100644 index 000000000000..28f370065a9e --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/signature.go @@ -0,0 +1,190 @@ +// Copyright 2014 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "bytes" + "hash" + "hash/fnv" + "sort" + "sync" +) + +// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is +// used to separate label names, label values, and other strings from each other +// when calculating their combined hash value (aka signature aka fingerprint). +const SeparatorByte byte = 255 + +var ( + // cache the signature of an empty label set. + emptyLabelSignature = fnv.New64a().Sum64() + + hashAndBufPool sync.Pool +) + +type hashAndBuf struct { + h hash.Hash64 + b bytes.Buffer +} + +func getHashAndBuf() *hashAndBuf { + hb := hashAndBufPool.Get() + if hb == nil { + return &hashAndBuf{h: fnv.New64a()} + } + return hb.(*hashAndBuf) +} + +func putHashAndBuf(hb *hashAndBuf) { + hb.h.Reset() + hb.b.Reset() + hashAndBufPool.Put(hb) +} + +// LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a +// given label set. (Collisions are possible but unlikely if the number of label +// sets the function is applied to is small.) +func LabelsToSignature(labels map[string]string) uint64 { + if len(labels) == 0 { + return emptyLabelSignature + } + + labelNames := make([]string, 0, len(labels)) + for labelName := range labels { + labelNames = append(labelNames, labelName) + } + sort.Strings(labelNames) + + hb := getHashAndBuf() + defer putHashAndBuf(hb) + + for _, labelName := range labelNames { + hb.b.WriteString(labelName) + hb.b.WriteByte(SeparatorByte) + hb.b.WriteString(labels[labelName]) + hb.b.WriteByte(SeparatorByte) + hb.h.Write(hb.b.Bytes()) + hb.b.Reset() + } + return hb.h.Sum64() +} + +// labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as +// parameter (rather than a label map) and returns a Fingerprint. +func labelSetToFingerprint(ls LabelSet) Fingerprint { + if len(ls) == 0 { + return Fingerprint(emptyLabelSignature) + } + + labelNames := make(LabelNames, 0, len(ls)) + for labelName := range ls { + labelNames = append(labelNames, labelName) + } + sort.Sort(labelNames) + + hb := getHashAndBuf() + defer putHashAndBuf(hb) + + for _, labelName := range labelNames { + hb.b.WriteString(string(labelName)) + hb.b.WriteByte(SeparatorByte) + hb.b.WriteString(string(ls[labelName])) + hb.b.WriteByte(SeparatorByte) + hb.h.Write(hb.b.Bytes()) + hb.b.Reset() + } + return Fingerprint(hb.h.Sum64()) +} + +// labelSetToFastFingerprint works similar to labelSetToFingerprint but uses a +// faster and less allocation-heavy hash function, which is more susceptible to +// create hash collisions. Therefore, collision detection should be applied. +func labelSetToFastFingerprint(ls LabelSet) Fingerprint { + if len(ls) == 0 { + return Fingerprint(emptyLabelSignature) + } + + var result uint64 + hb := getHashAndBuf() + defer putHashAndBuf(hb) + + for labelName, labelValue := range ls { + hb.b.WriteString(string(labelName)) + hb.b.WriteByte(SeparatorByte) + hb.b.WriteString(string(labelValue)) + hb.h.Write(hb.b.Bytes()) + result ^= hb.h.Sum64() + hb.h.Reset() + hb.b.Reset() + } + return Fingerprint(result) +} + +// SignatureForLabels works like LabelsToSignature but takes a Metric as +// parameter (rather than a label map) and only includes the labels with the +// specified LabelNames into the signature calculation. The labels passed in +// will be sorted by this function. +func SignatureForLabels(m Metric, labels ...LabelName) uint64 { + if len(m) == 0 || len(labels) == 0 { + return emptyLabelSignature + } + + sort.Sort(LabelNames(labels)) + + hb := getHashAndBuf() + defer putHashAndBuf(hb) + + for _, label := range labels { + hb.b.WriteString(string(label)) + hb.b.WriteByte(SeparatorByte) + hb.b.WriteString(string(m[label])) + hb.b.WriteByte(SeparatorByte) + hb.h.Write(hb.b.Bytes()) + hb.b.Reset() + } + return hb.h.Sum64() +} + +// SignatureWithoutLabels works like LabelsToSignature but takes a Metric as +// parameter (rather than a label map) and excludes the labels with any of the +// specified LabelNames from the signature calculation. +func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 { + if len(m) == 0 { + return emptyLabelSignature + } + + labelNames := make(LabelNames, 0, len(m)) + for labelName := range m { + if _, exclude := labels[labelName]; !exclude { + labelNames = append(labelNames, labelName) + } + } + if len(labelNames) == 0 { + return emptyLabelSignature + } + sort.Sort(labelNames) + + hb := getHashAndBuf() + defer putHashAndBuf(hb) + + for _, labelName := range labelNames { + hb.b.WriteString(string(labelName)) + hb.b.WriteByte(SeparatorByte) + hb.b.WriteString(string(m[labelName])) + hb.b.WriteByte(SeparatorByte) + hb.h.Write(hb.b.Bytes()) + hb.b.Reset() + } + return hb.h.Sum64() +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/signature_test.go b/Godeps/_workspace/src/github.com/prometheus/common/model/signature_test.go new file mode 100644 index 000000000000..d9c665f8c79e --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/signature_test.go @@ -0,0 +1,304 @@ +// Copyright 2014 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "runtime" + "sync" + "testing" +) + +func TestLabelsToSignature(t *testing.T) { + var scenarios = []struct { + in map[string]string + out uint64 + }{ + { + in: map[string]string{}, + out: 14695981039346656037, + }, + { + in: map[string]string{"name": "garland, briggs", "fear": "love is not enough"}, + out: 5799056148416392346, + }, + } + + for i, scenario := range scenarios { + actual := LabelsToSignature(scenario.in) + + if actual != scenario.out { + t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) + } + } +} + +func TestMetricToFingerprint(t *testing.T) { + var scenarios = []struct { + in LabelSet + out Fingerprint + }{ + { + in: LabelSet{}, + out: 14695981039346656037, + }, + { + in: LabelSet{"name": "garland, briggs", "fear": "love is not enough"}, + out: 5799056148416392346, + }, + } + + for i, scenario := range scenarios { + actual := labelSetToFingerprint(scenario.in) + + if actual != scenario.out { + t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) + } + } +} + +func TestMetricToFastFingerprint(t *testing.T) { + var scenarios = []struct { + in LabelSet + out Fingerprint + }{ + { + in: LabelSet{}, + out: 14695981039346656037, + }, + { + in: LabelSet{"name": "garland, briggs", "fear": "love is not enough"}, + out: 12952432476264840823, + }, + } + + for i, scenario := range scenarios { + actual := labelSetToFastFingerprint(scenario.in) + + if actual != scenario.out { + t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) + } + } +} + +func TestSignatureForLabels(t *testing.T) { + var scenarios = []struct { + in Metric + labels LabelNames + out uint64 + }{ + { + in: Metric{}, + labels: nil, + out: 14695981039346656037, + }, + { + in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, + labels: LabelNames{"fear", "name"}, + out: 5799056148416392346, + }, + { + in: Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"}, + labels: LabelNames{"fear", "name"}, + out: 5799056148416392346, + }, + { + in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, + labels: LabelNames{}, + out: 14695981039346656037, + }, + { + in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, + labels: nil, + out: 14695981039346656037, + }, + } + + for i, scenario := range scenarios { + actual := SignatureForLabels(scenario.in, scenario.labels...) + + if actual != scenario.out { + t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) + } + } +} + +func TestSignatureWithoutLabels(t *testing.T) { + var scenarios = []struct { + in Metric + labels map[LabelName]struct{} + out uint64 + }{ + { + in: Metric{}, + labels: nil, + out: 14695981039346656037, + }, + { + in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, + labels: map[LabelName]struct{}{"fear": struct{}{}, "name": struct{}{}}, + out: 14695981039346656037, + }, + { + in: Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"}, + labels: map[LabelName]struct{}{"foo": struct{}{}}, + out: 5799056148416392346, + }, + { + in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, + labels: map[LabelName]struct{}{}, + out: 5799056148416392346, + }, + { + in: Metric{"name": "garland, briggs", "fear": "love is not enough"}, + labels: nil, + out: 5799056148416392346, + }, + } + + for i, scenario := range scenarios { + actual := SignatureWithoutLabels(scenario.in, scenario.labels) + + if actual != scenario.out { + t.Errorf("%d. expected %d, got %d", i, scenario.out, actual) + } + } +} + +func benchmarkLabelToSignature(b *testing.B, l map[string]string, e uint64) { + for i := 0; i < b.N; i++ { + if a := LabelsToSignature(l); a != e { + b.Fatalf("expected signature of %d for %s, got %d", e, l, a) + } + } +} + +func BenchmarkLabelToSignatureScalar(b *testing.B) { + benchmarkLabelToSignature(b, nil, 14695981039346656037) +} + +func BenchmarkLabelToSignatureSingle(b *testing.B) { + benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value"}, 5146282821936882169) +} + +func BenchmarkLabelToSignatureDouble(b *testing.B) { + benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value"}, 3195800080984914717) +} + +func BenchmarkLabelToSignatureTriple(b *testing.B) { + benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 13843036195897128121) +} + +func benchmarkMetricToFingerprint(b *testing.B, ls LabelSet, e Fingerprint) { + for i := 0; i < b.N; i++ { + if a := labelSetToFingerprint(ls); a != e { + b.Fatalf("expected signature of %d for %s, got %d", e, ls, a) + } + } +} + +func BenchmarkMetricToFingerprintScalar(b *testing.B) { + benchmarkMetricToFingerprint(b, nil, 14695981039346656037) +} + +func BenchmarkMetricToFingerprintSingle(b *testing.B) { + benchmarkMetricToFingerprint(b, LabelSet{"first-label": "first-label-value"}, 5146282821936882169) +} + +func BenchmarkMetricToFingerprintDouble(b *testing.B) { + benchmarkMetricToFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value"}, 3195800080984914717) +} + +func BenchmarkMetricToFingerprintTriple(b *testing.B) { + benchmarkMetricToFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 13843036195897128121) +} + +func benchmarkMetricToFastFingerprint(b *testing.B, ls LabelSet, e Fingerprint) { + for i := 0; i < b.N; i++ { + if a := labelSetToFastFingerprint(ls); a != e { + b.Fatalf("expected signature of %d for %s, got %d", e, ls, a) + } + } +} + +func BenchmarkMetricToFastFingerprintScalar(b *testing.B) { + benchmarkMetricToFastFingerprint(b, nil, 14695981039346656037) +} + +func BenchmarkMetricToFastFingerprintSingle(b *testing.B) { + benchmarkMetricToFastFingerprint(b, LabelSet{"first-label": "first-label-value"}, 5147259542624943964) +} + +func BenchmarkMetricToFastFingerprintDouble(b *testing.B) { + benchmarkMetricToFastFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value"}, 18269973311206963528) +} + +func BenchmarkMetricToFastFingerprintTriple(b *testing.B) { + benchmarkMetricToFastFingerprint(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676) +} + +func BenchmarkEmptyLabelSignature(b *testing.B) { + input := []map[string]string{nil, {}} + + var ms runtime.MemStats + runtime.ReadMemStats(&ms) + + alloc := ms.Alloc + + for _, labels := range input { + LabelsToSignature(labels) + } + + runtime.ReadMemStats(&ms) + + if got := ms.Alloc; alloc != got { + b.Fatal("expected LabelsToSignature with empty labels not to perform allocations") + } +} + +func benchmarkMetricToFastFingerprintConc(b *testing.B, ls LabelSet, e Fingerprint, concLevel int) { + var start, end sync.WaitGroup + start.Add(1) + end.Add(concLevel) + + for i := 0; i < concLevel; i++ { + go func() { + start.Wait() + for j := b.N / concLevel; j >= 0; j-- { + if a := labelSetToFastFingerprint(ls); a != e { + b.Fatalf("expected signature of %d for %s, got %d", e, ls, a) + } + } + end.Done() + }() + } + b.ResetTimer() + start.Done() + end.Wait() +} + +func BenchmarkMetricToFastFingerprintTripleConc1(b *testing.B) { + benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 1) +} + +func BenchmarkMetricToFastFingerprintTripleConc2(b *testing.B) { + benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 2) +} + +func BenchmarkMetricToFastFingerprintTripleConc4(b *testing.B) { + benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 4) +} + +func BenchmarkMetricToFastFingerprintTripleConc8(b *testing.B) { + benchmarkMetricToFastFingerprintConc(b, LabelSet{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 8) +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/time.go b/Godeps/_workspace/src/github.com/prometheus/common/model/time.go new file mode 100644 index 000000000000..ebc8bf6cc841 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/time.go @@ -0,0 +1,230 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "fmt" + "math" + "regexp" + "strconv" + "strings" + "time" +) + +const ( + // MinimumTick is the minimum supported time resolution. This has to be + // at least time.Second in order for the code below to work. + minimumTick = time.Millisecond + // second is the Time duration equivalent to one second. + second = int64(time.Second / minimumTick) + // The number of nanoseconds per minimum tick. + nanosPerTick = int64(minimumTick / time.Nanosecond) + + // Earliest is the earliest Time representable. Handy for + // initializing a high watermark. + Earliest = Time(math.MinInt64) + // Latest is the latest Time representable. Handy for initializing + // a low watermark. + Latest = Time(math.MaxInt64) +) + +// Time is the number of milliseconds since the epoch +// (1970-01-01 00:00 UTC) excluding leap seconds. +type Time int64 + +// Interval describes and interval between two timestamps. +type Interval struct { + Start, End Time +} + +// Now returns the current time as a Time. +func Now() Time { + return TimeFromUnixNano(time.Now().UnixNano()) +} + +// TimeFromUnix returns the Time equivalent to the Unix Time t +// provided in seconds. +func TimeFromUnix(t int64) Time { + return Time(t * second) +} + +// TimeFromUnixNano returns the Time equivalent to the Unix Time +// t provided in nanoseconds. +func TimeFromUnixNano(t int64) Time { + return Time(t / nanosPerTick) +} + +// Equal reports whether two Times represent the same instant. +func (t Time) Equal(o Time) bool { + return t == o +} + +// Before reports whether the Time t is before o. +func (t Time) Before(o Time) bool { + return t < o +} + +// After reports whether the Time t is after o. +func (t Time) After(o Time) bool { + return t > o +} + +// Add returns the Time t + d. +func (t Time) Add(d time.Duration) Time { + return t + Time(d/minimumTick) +} + +// Sub returns the Duration t - o. +func (t Time) Sub(o Time) time.Duration { + return time.Duration(t-o) * minimumTick +} + +// Time returns the time.Time representation of t. +func (t Time) Time() time.Time { + return time.Unix(int64(t)/second, (int64(t)%second)*nanosPerTick) +} + +// Unix returns t as a Unix time, the number of seconds elapsed +// since January 1, 1970 UTC. +func (t Time) Unix() int64 { + return int64(t) / second +} + +// UnixNano returns t as a Unix time, the number of nanoseconds elapsed +// since January 1, 1970 UTC. +func (t Time) UnixNano() int64 { + return int64(t) * nanosPerTick +} + +// The number of digits after the dot. +var dotPrecision = int(math.Log10(float64(second))) + +// String returns a string representation of the Time. +func (t Time) String() string { + return strconv.FormatFloat(float64(t)/float64(second), 'f', -1, 64) +} + +// MarshalJSON implements the json.Marshaler interface. +func (t Time) MarshalJSON() ([]byte, error) { + return []byte(t.String()), nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (t *Time) UnmarshalJSON(b []byte) error { + p := strings.Split(string(b), ".") + switch len(p) { + case 1: + v, err := strconv.ParseInt(string(p[0]), 10, 64) + if err != nil { + return err + } + *t = Time(v * second) + + case 2: + v, err := strconv.ParseInt(string(p[0]), 10, 64) + if err != nil { + return err + } + v *= second + + prec := dotPrecision - len(p[1]) + if prec < 0 { + p[1] = p[1][:dotPrecision] + } else if prec > 0 { + p[1] = p[1] + strings.Repeat("0", prec) + } + + va, err := strconv.ParseInt(p[1], 10, 32) + if err != nil { + return err + } + + *t = Time(v + va) + + default: + return fmt.Errorf("invalid time %q", string(b)) + } + return nil +} + +// Duration wraps time.Duration. It is used to parse the custom duration format +// from YAML. +// This type should not propagate beyond the scope of input/output processing. +type Duration time.Duration + +// StringToDuration parses a string into a time.Duration, assuming that a year +// a day always has 24h. +func ParseDuration(durationStr string) (Duration, error) { + matches := durationRE.FindStringSubmatch(durationStr) + if len(matches) != 3 { + return 0, fmt.Errorf("not a valid duration string: %q", durationStr) + } + durSeconds, _ := strconv.Atoi(matches[1]) + dur := time.Duration(durSeconds) * time.Second + unit := matches[2] + switch unit { + case "d": + dur *= 60 * 60 * 24 + case "h": + dur *= 60 * 60 + case "m": + dur *= 60 + case "s": + dur *= 1 + default: + return 0, fmt.Errorf("invalid time unit in duration string: %q", unit) + } + return Duration(dur), nil +} + +var durationRE = regexp.MustCompile("^([0-9]+)([ywdhms]+)$") + +func (d Duration) String() string { + seconds := int64(time.Duration(d) / time.Second) + factors := map[string]int64{ + "d": 60 * 60 * 24, + "h": 60 * 60, + "m": 60, + "s": 1, + } + unit := "s" + switch int64(0) { + case seconds % factors["d"]: + unit = "d" + case seconds % factors["h"]: + unit = "h" + case seconds % factors["m"]: + unit = "m" + } + return fmt.Sprintf("%v%v", seconds/factors[unit], unit) +} + +// MarshalYAML implements the yaml.Marshaler interface. +func (d Duration) MarshalYAML() (interface{}, error) { + return d.String(), nil +} + +// UnmarshalYAML implements the yaml.Unmarshaler interface. +func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error { + var s string + if err := unmarshal(&s); err != nil { + return err + } + dur, err := ParseDuration(s) + if err != nil { + return err + } + *d = dur + return nil +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/time_test.go b/Godeps/_workspace/src/github.com/prometheus/common/model/time_test.go new file mode 100644 index 000000000000..9013a62775b1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/time_test.go @@ -0,0 +1,86 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "testing" + "time" +) + +func TestComparators(t *testing.T) { + t1a := TimeFromUnix(0) + t1b := TimeFromUnix(0) + t2 := TimeFromUnix(2*second - 1) + + if !t1a.Equal(t1b) { + t.Fatalf("Expected %s to be equal to %s", t1a, t1b) + } + if t1a.Equal(t2) { + t.Fatalf("Expected %s to not be equal to %s", t1a, t2) + } + + if !t1a.Before(t2) { + t.Fatalf("Expected %s to be before %s", t1a, t2) + } + if t1a.Before(t1b) { + t.Fatalf("Expected %s to not be before %s", t1a, t1b) + } + + if !t2.After(t1a) { + t.Fatalf("Expected %s to be after %s", t2, t1a) + } + if t1b.After(t1a) { + t.Fatalf("Expected %s to not be after %s", t1b, t1a) + } +} + +func TestTimeConversions(t *testing.T) { + unixSecs := int64(1136239445) + unixNsecs := int64(123456789) + unixNano := unixSecs*1e9 + unixNsecs + + t1 := time.Unix(unixSecs, unixNsecs-unixNsecs%nanosPerTick) + t2 := time.Unix(unixSecs, unixNsecs) + + ts := TimeFromUnixNano(unixNano) + if !ts.Time().Equal(t1) { + t.Fatalf("Expected %s, got %s", t1, ts.Time()) + } + + // Test available precision. + ts = TimeFromUnixNano(t2.UnixNano()) + if !ts.Time().Equal(t1) { + t.Fatalf("Expected %s, got %s", t1, ts.Time()) + } + + if ts.UnixNano() != unixNano-unixNano%nanosPerTick { + t.Fatalf("Expected %d, got %d", unixNano, ts.UnixNano()) + } +} + +func TestDuration(t *testing.T) { + duration := time.Second + time.Minute + time.Hour + goTime := time.Unix(1136239445, 0) + + ts := TimeFromUnix(goTime.Unix()) + if !goTime.Add(duration).Equal(ts.Add(duration).Time()) { + t.Fatalf("Expected %s to be equal to %s", goTime.Add(duration), ts.Add(duration)) + } + + earlier := ts.Add(-duration) + delta := ts.Sub(earlier) + if delta != duration { + t.Fatalf("Expected %s to be equal to %s", delta, duration) + } +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/value.go b/Godeps/_workspace/src/github.com/prometheus/common/model/value.go new file mode 100644 index 000000000000..10ffb0bd6114 --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/value.go @@ -0,0 +1,395 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "encoding/json" + "fmt" + "sort" + "strconv" + "strings" +) + +// A SampleValue is a representation of a value for a given sample at a given +// time. +type SampleValue float64 + +// MarshalJSON implements json.Marshaler. +func (v SampleValue) MarshalJSON() ([]byte, error) { + return json.Marshal(v.String()) +} + +// UnmarshalJSON implements json.Unmarshaler. +func (v *SampleValue) UnmarshalJSON(b []byte) error { + if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { + return fmt.Errorf("sample value must be a quoted string") + } + f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64) + if err != nil { + return err + } + *v = SampleValue(f) + return nil +} + +func (v SampleValue) Equal(o SampleValue) bool { + return v == o +} + +func (v SampleValue) String() string { + return strconv.FormatFloat(float64(v), 'f', -1, 64) +} + +// SamplePair pairs a SampleValue with a Timestamp. +type SamplePair struct { + Timestamp Time + Value SampleValue +} + +// MarshalJSON implements json.Marshaler. +func (s SamplePair) MarshalJSON() ([]byte, error) { + t, err := json.Marshal(s.Timestamp) + if err != nil { + return nil, err + } + v, err := json.Marshal(s.Value) + if err != nil { + return nil, err + } + return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (s *SamplePair) UnmarshalJSON(b []byte) error { + v := [...]json.Unmarshaler{&s.Timestamp, &s.Value} + return json.Unmarshal(b, &v) +} + +// Equal returns true if this SamplePair and o have equal Values and equal +// Timestamps. +func (s *SamplePair) Equal(o *SamplePair) bool { + return s == o || (s.Value == o.Value && s.Timestamp.Equal(o.Timestamp)) +} + +func (s SamplePair) String() string { + return fmt.Sprintf("%s @[%s]", s.Value, s.Timestamp) +} + +// Sample is a sample pair associated with a metric. +type Sample struct { + Metric Metric `json:"metric"` + Value SampleValue `json:"value"` + Timestamp Time `json:"timestamp"` +} + +// Equal compares first the metrics, then the timestamp, then the value. +func (s *Sample) Equal(o *Sample) bool { + if s == o { + return true + } + + if !s.Metric.Equal(o.Metric) { + return false + } + if !s.Timestamp.Equal(o.Timestamp) { + return false + } + if s.Value != o.Value { + return false + } + + return true +} + +func (s Sample) String() string { + return fmt.Sprintf("%s => %s", s.Metric, SamplePair{ + Timestamp: s.Timestamp, + Value: s.Value, + }) +} + +// MarshalJSON implements json.Marshaler. +func (s Sample) MarshalJSON() ([]byte, error) { + v := struct { + Metric Metric `json:"metric"` + Value SamplePair `json:"value"` + }{ + Metric: s.Metric, + Value: SamplePair{ + Timestamp: s.Timestamp, + Value: s.Value, + }, + } + + return json.Marshal(&v) +} + +// UnmarshalJSON implements json.Unmarshaler. +func (s *Sample) UnmarshalJSON(b []byte) error { + v := struct { + Metric Metric `json:"metric"` + Value SamplePair `json:"value"` + }{ + Metric: s.Metric, + Value: SamplePair{ + Timestamp: s.Timestamp, + Value: s.Value, + }, + } + + if err := json.Unmarshal(b, &v); err != nil { + return err + } + + s.Metric = v.Metric + s.Timestamp = v.Value.Timestamp + s.Value = v.Value.Value + + return nil +} + +// Samples is a sortable Sample slice. It implements sort.Interface. +type Samples []*Sample + +func (s Samples) Len() int { + return len(s) +} + +// Less compares first the metrics, then the timestamp. +func (s Samples) Less(i, j int) bool { + switch { + case s[i].Metric.Before(s[j].Metric): + return true + case s[j].Metric.Before(s[i].Metric): + return false + case s[i].Timestamp.Before(s[j].Timestamp): + return true + default: + return false + } +} + +func (s Samples) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +// Equal compares two sets of samples and returns true if they are equal. +func (s Samples) Equal(o Samples) bool { + if len(s) != len(o) { + return false + } + + for i, sample := range s { + if !sample.Equal(o[i]) { + return false + } + } + return true +} + +// SampleStream is a stream of Values belonging to an attached COWMetric. +type SampleStream struct { + Metric Metric `json:"metric"` + Values []SamplePair `json:"values"` +} + +func (ss SampleStream) String() string { + vals := make([]string, len(ss.Values)) + for i, v := range ss.Values { + vals[i] = v.String() + } + return fmt.Sprintf("%s =>\n%s", ss.Metric, strings.Join(vals, "\n")) +} + +// Value is a generic interface for values resulting from a query evaluation. +type Value interface { + Type() ValueType + String() string +} + +func (Matrix) Type() ValueType { return ValMatrix } +func (Vector) Type() ValueType { return ValVector } +func (*Scalar) Type() ValueType { return ValScalar } +func (*String) Type() ValueType { return ValString } + +type ValueType int + +const ( + ValNone ValueType = iota + ValScalar + ValVector + ValMatrix + ValString +) + +// MarshalJSON implements json.Marshaler. +func (et ValueType) MarshalJSON() ([]byte, error) { + return json.Marshal(et.String()) +} + +func (et *ValueType) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + switch s { + case "": + *et = ValNone + case "scalar": + *et = ValScalar + case "vector": + *et = ValVector + case "matrix": + *et = ValMatrix + case "string": + *et = ValString + default: + return fmt.Errorf("unknown value type %q", s) + } + return nil +} + +func (e ValueType) String() string { + switch e { + case ValNone: + return "" + case ValScalar: + return "scalar" + case ValVector: + return "vector" + case ValMatrix: + return "matrix" + case ValString: + return "string" + } + panic("ValueType.String: unhandled value type") +} + +// Scalar is a scalar value evaluated at the set timestamp. +type Scalar struct { + Value SampleValue `json:"value"` + Timestamp Time `json:"timestamp"` +} + +func (s Scalar) String() string { + return fmt.Sprintf("scalar: %v @[%v]", s.Value, s.Timestamp) +} + +// MarshalJSON implements json.Marshaler. +func (s Scalar) MarshalJSON() ([]byte, error) { + v := strconv.FormatFloat(float64(s.Value), 'f', -1, 64) + return json.Marshal([...]interface{}{s.Timestamp, string(v)}) +} + +// UnmarshalJSON implements json.Unmarshaler. +func (s *Scalar) UnmarshalJSON(b []byte) error { + var f string + v := [...]interface{}{&s.Timestamp, &f} + + if err := json.Unmarshal(b, &v); err != nil { + return err + } + + value, err := strconv.ParseFloat(f, 64) + if err != nil { + return fmt.Errorf("error parsing sample value: %s", err) + } + s.Value = SampleValue(value) + return nil +} + +// String is a string value evaluated at the set timestamp. +type String struct { + Value string `json:"value"` + Timestamp Time `json:"timestamp"` +} + +func (s *String) String() string { + return s.Value +} + +// MarshalJSON implements json.Marshaler. +func (s String) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{s.Timestamp, s.Value}) +} + +// UnmarshalJSON implements json.Unmarshaler. +func (s *String) UnmarshalJSON(b []byte) error { + v := [...]interface{}{&s.Timestamp, &s.Value} + return json.Unmarshal(b, &v) +} + +// Vector is basically only an alias for Samples, but the +// contract is that in a Vector, all Samples have the same timestamp. +type Vector []*Sample + +func (vec Vector) String() string { + entries := make([]string, len(vec)) + for i, s := range vec { + entries[i] = s.String() + } + return strings.Join(entries, "\n") +} + +func (vec Vector) Len() int { return len(vec) } +func (vec Vector) Swap(i, j int) { vec[i], vec[j] = vec[j], vec[i] } + +// Less compares first the metrics, then the timestamp. +func (vec Vector) Less(i, j int) bool { + switch { + case vec[i].Metric.Before(vec[j].Metric): + return true + case vec[j].Metric.Before(vec[i].Metric): + return false + case vec[i].Timestamp.Before(vec[j].Timestamp): + return true + default: + return false + } +} + +// Equal compares two sets of samples and returns true if they are equal. +func (vec Vector) Equal(o Vector) bool { + if len(vec) != len(o) { + return false + } + + for i, sample := range vec { + if !sample.Equal(o[i]) { + return false + } + } + return true +} + +// Matrix is a list of time series. +type Matrix []*SampleStream + +func (m Matrix) Len() int { return len(m) } +func (m Matrix) Less(i, j int) bool { return m[i].Metric.Before(m[j].Metric) } +func (m Matrix) Swap(i, j int) { m[i], m[j] = m[j], m[i] } + +func (mat Matrix) String() string { + matCp := make(Matrix, len(mat)) + copy(matCp, mat) + sort.Sort(matCp) + + strs := make([]string, len(matCp)) + + for i, ss := range matCp { + strs[i] = ss.String() + } + + return strings.Join(strs, "\n") +} diff --git a/Godeps/_workspace/src/github.com/prometheus/common/model/value_test.go b/Godeps/_workspace/src/github.com/prometheus/common/model/value_test.go new file mode 100644 index 000000000000..2e9c7eb09d1a --- /dev/null +++ b/Godeps/_workspace/src/github.com/prometheus/common/model/value_test.go @@ -0,0 +1,362 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "encoding/json" + "math" + "reflect" + "sort" + "testing" +) + +func TestSamplePairJSON(t *testing.T) { + input := []struct { + plain string + value SamplePair + }{ + { + plain: `[1234.567,"123.1"]`, + value: SamplePair{ + Value: 123.1, + Timestamp: 1234567, + }, + }, + } + + for _, test := range input { + b, err := json.Marshal(test.value) + if err != nil { + t.Error(err) + continue + } + + if string(b) != test.plain { + t.Errorf("encoding error: expected %q, got %q", test.plain, b) + continue + } + + var sp SamplePair + err = json.Unmarshal(b, &sp) + if err != nil { + t.Error(err) + continue + } + + if sp != test.value { + t.Errorf("decoding error: expected %v, got %v", test.value, sp) + } + } +} + +func TestSampleJSON(t *testing.T) { + input := []struct { + plain string + value Sample + }{ + { + plain: `{"metric":{"__name__":"test_metric"},"value":[1234.567,"123.1"]}`, + value: Sample{ + Metric: Metric{ + MetricNameLabel: "test_metric", + }, + Value: 123.1, + Timestamp: 1234567, + }, + }, + } + + for _, test := range input { + b, err := json.Marshal(test.value) + if err != nil { + t.Error(err) + continue + } + + if string(b) != test.plain { + t.Errorf("encoding error: expected %q, got %q", test.plain, b) + continue + } + + var sv Sample + err = json.Unmarshal(b, &sv) + if err != nil { + t.Error(err) + continue + } + + if !reflect.DeepEqual(sv, test.value) { + t.Errorf("decoding error: expected %v, got %v", test.value, sv) + } + } +} + +func TestVectorJSON(t *testing.T) { + input := []struct { + plain string + value Vector + }{ + { + plain: `[]`, + value: Vector{}, + }, + { + plain: `[{"metric":{"__name__":"test_metric"},"value":[1234.567,"123.1"]}]`, + value: Vector{&Sample{ + Metric: Metric{ + MetricNameLabel: "test_metric", + }, + Value: 123.1, + Timestamp: 1234567, + }}, + }, + { + plain: `[{"metric":{"__name__":"test_metric"},"value":[1234.567,"123.1"]},{"metric":{"foo":"bar"},"value":[1.234,"+Inf"]}]`, + value: Vector{ + &Sample{ + Metric: Metric{ + MetricNameLabel: "test_metric", + }, + Value: 123.1, + Timestamp: 1234567, + }, + &Sample{ + Metric: Metric{ + "foo": "bar", + }, + Value: SampleValue(math.Inf(1)), + Timestamp: 1234, + }, + }, + }, + } + + for _, test := range input { + b, err := json.Marshal(test.value) + if err != nil { + t.Error(err) + continue + } + + if string(b) != test.plain { + t.Errorf("encoding error: expected %q, got %q", test.plain, b) + continue + } + + var vec Vector + err = json.Unmarshal(b, &vec) + if err != nil { + t.Error(err) + continue + } + + if !reflect.DeepEqual(vec, test.value) { + t.Errorf("decoding error: expected %v, got %v", test.value, vec) + } + } +} + +func TestScalarJSON(t *testing.T) { + input := []struct { + plain string + value Scalar + }{ + { + plain: `[123.456,"456"]`, + value: Scalar{ + Timestamp: 123456, + Value: 456, + }, + }, + { + plain: `[123123.456,"+Inf"]`, + value: Scalar{ + Timestamp: 123123456, + Value: SampleValue(math.Inf(1)), + }, + }, + { + plain: `[123123.456,"-Inf"]`, + value: Scalar{ + Timestamp: 123123456, + Value: SampleValue(math.Inf(-1)), + }, + }, + } + + for _, test := range input { + b, err := json.Marshal(test.value) + if err != nil { + t.Error(err) + continue + } + + if string(b) != test.plain { + t.Errorf("encoding error: expected %q, got %q", test.plain, b) + continue + } + + var sv Scalar + err = json.Unmarshal(b, &sv) + if err != nil { + t.Error(err) + continue + } + + if sv != test.value { + t.Errorf("decoding error: expected %v, got %v", test.value, sv) + } + } +} + +func TestStringJSON(t *testing.T) { + input := []struct { + plain string + value String + }{ + { + plain: `[123.456,"test"]`, + value: String{ + Timestamp: 123456, + Value: "test", + }, + }, + { + plain: `[123123.456,"台北"]`, + value: String{ + Timestamp: 123123456, + Value: "台北", + }, + }, + } + + for _, test := range input { + b, err := json.Marshal(test.value) + if err != nil { + t.Error(err) + continue + } + + if string(b) != test.plain { + t.Errorf("encoding error: expected %q, got %q", test.plain, b) + continue + } + + var sv String + err = json.Unmarshal(b, &sv) + if err != nil { + t.Error(err) + continue + } + + if sv != test.value { + t.Errorf("decoding error: expected %v, got %v", test.value, sv) + } + } +} + +func TestVectorSort(t *testing.T) { + input := Vector{ + &Sample{ + Metric: Metric{ + MetricNameLabel: "A", + }, + Timestamp: 1, + }, + &Sample{ + Metric: Metric{ + MetricNameLabel: "A", + }, + Timestamp: 2, + }, + &Sample{ + Metric: Metric{ + MetricNameLabel: "C", + }, + Timestamp: 1, + }, + &Sample{ + Metric: Metric{ + MetricNameLabel: "C", + }, + Timestamp: 2, + }, + &Sample{ + Metric: Metric{ + MetricNameLabel: "B", + }, + Timestamp: 1, + }, + &Sample{ + Metric: Metric{ + MetricNameLabel: "B", + }, + Timestamp: 2, + }, + } + + expected := Vector{ + &Sample{ + Metric: Metric{ + MetricNameLabel: "A", + }, + Timestamp: 1, + }, + &Sample{ + Metric: Metric{ + MetricNameLabel: "A", + }, + Timestamp: 2, + }, + &Sample{ + Metric: Metric{ + MetricNameLabel: "B", + }, + Timestamp: 1, + }, + &Sample{ + Metric: Metric{ + MetricNameLabel: "B", + }, + Timestamp: 2, + }, + &Sample{ + Metric: Metric{ + MetricNameLabel: "C", + }, + Timestamp: 1, + }, + &Sample{ + Metric: Metric{ + MetricNameLabel: "C", + }, + Timestamp: 2, + }, + } + + sort.Sort(input) + + for i, actual := range input { + actualFp := actual.Metric.Fingerprint() + expectedFp := expected[i].Metric.Fingerprint() + + if actualFp != expectedFp { + t.Fatalf("%d. Incorrect fingerprint. Got %s; want %s", i, actualFp.String(), expectedFp.String()) + } + + if actual.Timestamp != expected[i].Timestamp { + t.Fatalf("%d. Incorrect timestamp. Got %s; want %s", i, actual.Timestamp, expected[i].Timestamp) + } + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/CONTRIBUTING.md b/Godeps/_workspace/src/github.com/rackspace/gophercloud/CONTRIBUTING.md index 9748c1ad2b11..6ba5beb85438 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/CONTRIBUTING.md +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/CONTRIBUTING.md @@ -28,11 +28,10 @@ fork as `origin` instead: git remote add origin git@github.com//gophercloud ``` -4. Checkout the latest development branch ([click here](/branches) to see all -the branches): +4. Checkout the latest development branch: ```bash - git checkout release/v1.0.1 + git checkout master ``` 5. If you're working on something (discussed more in detail below), you will diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/network_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/network_test.go new file mode 100644 index 000000000000..7ebe7ec7bba9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/network_test.go @@ -0,0 +1,78 @@ +// +build acceptance compute servers + +package v2 + +import ( + "os" + "testing" + + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks" + "github.com/rackspace/gophercloud/openstack/compute/v2/servers" + th "github.com/rackspace/gophercloud/testhelper" +) + +func getNetworkIDFromNetworkExtension(t *testing.T, client *gophercloud.ServiceClient, networkName string) (string, error) { + allPages, err := networks.List(client).AllPages() + if err != nil { + t.Fatalf("Unable to list networks: %v", err) + } + + networkList, err := networks.ExtractNetworks(allPages) + if err != nil { + t.Fatalf("Unable to list networks: %v", err) + } + + networkID := "" + for _, network := range networkList { + t.Logf("Network: %v", network) + if network.Label == networkName { + networkID = network.ID + } + } + + t.Logf("Found network ID for %s: %s\n", networkName, networkID) + + return networkID, nil +} + +func TestNetworks(t *testing.T) { + networkName := os.Getenv("OS_NETWORK_NAME") + if networkName == "" { + t.Fatalf("OS_NETWORK_NAME must be set") + } + + choices, err := ComputeChoicesFromEnv() + if err != nil { + t.Fatal(err) + } + + client, err := newClient() + if err != nil { + t.Fatalf("Unable to create a compute client: %v", err) + } + + networkID, err := getNetworkIDFromNetworkExtension(t, client, networkName) + if err != nil { + t.Fatalf("Unable to get network ID: %v", err) + } + + // createNetworkServer is defined in tenantnetworks_test.go + server, err := createNetworkServer(t, client, choices, networkID) + if err != nil { + t.Fatalf("Unable to create server: %v", err) + } + defer func() { + servers.Delete(client, server.ID) + t.Logf("Server deleted.") + }() + + if err = waitForStatus(client, server, "ACTIVE"); err != nil { + t.Fatalf("Unable to wait for server: %v", err) + } + + allPages, err := networks.List(client).AllPages() + allNetworks, err := networks.ExtractNetworks(allPages) + th.AssertNoErr(t, err) + t.Logf("Retrieved all %d networks: %+v", len(allNetworks), allNetworks) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servergroup_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servergroup_test.go index 80015e143f52..945854e3b27f 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servergroup_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servergroup_test.go @@ -3,10 +3,15 @@ package v2 import ( + "fmt" "testing" "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/acceptance/tools" + "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints" "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/servergroups" + "github.com/rackspace/gophercloud/openstack/compute/v2/servers" + th "github.com/rackspace/gophercloud/testhelper" ) func createServerGroup(t *testing.T, computeClient *gophercloud.ServiceClient) (*servergroups.ServerGroup, error) { @@ -36,7 +41,53 @@ func getServerGroup(t *testing.T, computeClient *gophercloud.ServiceClient, sgID return nil } +func createServerInGroup(t *testing.T, computeClient *gophercloud.ServiceClient, choices *ComputeChoices, serverGroup *servergroups.ServerGroup) (*servers.Server, error) { + if testing.Short() { + t.Skip("Skipping test that requires server creation in short mode.") + } + + name := tools.RandomString("ACPTTEST", 16) + t.Logf("Attempting to create server: %s\n", name) + + pwd := tools.MakeNewPassword("") + + serverCreateOpts := servers.CreateOpts{ + Name: name, + FlavorRef: choices.FlavorID, + ImageRef: choices.ImageID, + AdminPass: pwd, + } + server, err := servers.Create(computeClient, schedulerhints.CreateOptsExt{ + serverCreateOpts, + schedulerhints.SchedulerHints{ + Group: serverGroup.ID, + }, + }).Extract() + if err != nil { + t.Fatalf("Unable to create server: %v", err) + } + + th.AssertEquals(t, pwd, server.AdminPass) + + return server, err +} + +func verifySchedulerWorked(t *testing.T, firstServer, secondServer *servers.Server) error { + t.Logf("First server hostID: %v", firstServer.HostID) + t.Logf("Second server hostID: %v", secondServer.HostID) + if firstServer.HostID == secondServer.HostID { + return nil + } + + return fmt.Errorf("%s and %s were not scheduled on the same host.", firstServer.ID, secondServer.ID) +} + func TestServerGroups(t *testing.T) { + choices, err := ComputeChoicesFromEnv() + if err != nil { + t.Fatal(err) + } + computeClient, err := newClient() if err != nil { t.Fatalf("Unable to create a compute client: %v", err) @@ -48,11 +99,45 @@ func TestServerGroups(t *testing.T) { } defer func() { servergroups.Delete(computeClient, sg.ID) - t.Logf("ServerGroup deleted.") + t.Logf("Server Group deleted.") }() err = getServerGroup(t, computeClient, sg.ID) if err != nil { t.Fatalf("Unable to get server group: %v", err) } + + firstServer, err := createServerInGroup(t, computeClient, choices, sg) + if err != nil { + t.Fatalf("Unable to create server: %v", err) + } + defer func() { + servers.Delete(computeClient, firstServer.ID) + t.Logf("Server deleted.") + }() + + if err = waitForStatus(computeClient, firstServer, "ACTIVE"); err != nil { + t.Fatalf("Unable to wait for server: %v", err) + } + + firstServer, err = servers.Get(computeClient, firstServer.ID).Extract() + + secondServer, err := createServerInGroup(t, computeClient, choices, sg) + if err != nil { + t.Fatalf("Unable to create server: %v", err) + } + defer func() { + servers.Delete(computeClient, secondServer.ID) + t.Logf("Server deleted.") + }() + + if err = waitForStatus(computeClient, secondServer, "ACTIVE"); err != nil { + t.Fatalf("Unable to wait for server: %v", err) + } + + secondServer, err = servers.Get(computeClient, secondServer.ID).Extract() + + if err = verifySchedulerWorked(t, firstServer, secondServer); err != nil { + t.Fatalf("Scheduling did not work: %v", err) + } } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servers_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servers_test.go index 7b928e9ef509..f6c7c052458a 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servers_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/openstack/compute/v2/servers_test.go @@ -107,6 +107,12 @@ func createServer(t *testing.T, client *gophercloud.ServiceClient, choices *Comp servers.Network{UUID: network.ID}, }, AdminPass: pwd, + Personality: servers.Personality{ + &servers.File{ + Path: "/etc/test", + Contents: []byte("hello world"), + }, + }, }).Extract() if err != nil { t.Fatalf("Unable to create server: %v", err) diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/tokens_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/tokens_test.go new file mode 100644 index 000000000000..95ee7e660cd5 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/acceptance/rackspace/identity/v2/tokens_test.go @@ -0,0 +1,61 @@ +// +build acceptance + +package v2 + +import ( + "os" + "testing" + + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/acceptance/tools" + "github.com/rackspace/gophercloud/rackspace" + "github.com/rackspace/gophercloud/rackspace/identity/v2/tokens" + th "github.com/rackspace/gophercloud/testhelper" +) + +func rackspaceAuthOptions(t *testing.T) gophercloud.AuthOptions { + // Obtain credentials from the environment. + options, err := rackspace.AuthOptionsFromEnv() + th.AssertNoErr(t, err) + options = tools.OnlyRS(options) + + if options.Username == "" { + t.Fatal("Please provide a Rackspace username as RS_USERNAME.") + } + if options.APIKey == "" { + t.Fatal("Please provide a Rackspace API key as RS_API_KEY.") + } + + return options +} + +func createClient(t *testing.T, auth bool) *gophercloud.ServiceClient { + ao := rackspaceAuthOptions(t) + + provider, err := rackspace.NewClient(ao.IdentityEndpoint) + th.AssertNoErr(t, err) + + if auth { + err = rackspace.Authenticate(provider, ao) + th.AssertNoErr(t, err) + } + + return rackspace.NewIdentityV2(provider) +} + +func TestTokenAuth(t *testing.T) { + authedClient := createClient(t, true) + token := authedClient.TokenID + + tenantID := os.Getenv("RS_TENANT_ID") + if tenantID == "" { + t.Skip("You must set RS_TENANT_ID environment variable to run this test") + } + + authOpts := tokens.AuthOptions{} + authOpts.TenantID = tenantID + authOpts.Token = token + + _, err := tokens.Create(authedClient, authOpts).ExtractToken() + th.AssertNoErr(t, err) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/auth_options.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/auth_options.go index 9819e45f2d75..d26e16ac1c43 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/auth_options.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/auth_options.go @@ -43,4 +43,8 @@ type AuthOptions struct { // false, it will not cache these settings, but re-authentication will not be // possible. This setting defaults to false. AllowReauth bool + + // TokenID allows users to authenticate (possibly as another user) with an + // authentication token ID. + TokenID string } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/requests.go index d2f10aa6b592..71936e51b643 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots/requests.go @@ -171,3 +171,36 @@ func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMet }) return res } + +// IDFromName is a convienience function that returns a snapshot's ID given its name. +func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { + snapshotCount := 0 + snapshotID := "" + if name == "" { + return "", fmt.Errorf("A snapshot name must be provided.") + } + pager := List(client, nil) + pager.EachPage(func(page pagination.Page) (bool, error) { + snapshotList, err := ExtractSnapshots(page) + if err != nil { + return false, err + } + + for _, s := range snapshotList { + if s.Name == name { + snapshotCount++ + snapshotID = s.ID + } + } + return true, nil + }) + + switch snapshotCount { + case 0: + return "", fmt.Errorf("Unable to find snapshot: %s", name) + case 1: + return snapshotID, nil + default: + return "", fmt.Errorf("Found %d snapshots matching %s", snapshotCount, name) + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests.go index 253aaf7c5450..3e9243ac4957 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests.go @@ -201,3 +201,36 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder }) return res } + +// IDFromName is a convienience function that returns a server's ID given its name. +func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { + volumeCount := 0 + volumeID := "" + if name == "" { + return "", fmt.Errorf("A volume name must be provided.") + } + pager := List(client, nil) + pager.EachPage(func(page pagination.Page) (bool, error) { + volumeList, err := ExtractVolumes(page) + if err != nil { + return false, err + } + + for _, s := range volumeList { + if s.Name == name { + volumeCount++ + volumeID = s.ID + } + } + return true, nil + }) + + switch volumeCount { + case 0: + return "", fmt.Errorf("Unable to find volume: %s", name) + case 1: + return volumeID, nil + default: + return "", fmt.Errorf("Found %d volumes matching %s", volumeCount, name) + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests_test.go index c484cf08df3a..75c2bbc59657 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/requests_test.go @@ -3,6 +3,7 @@ package volumes import ( "testing" + fixtures "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing" "github.com/rackspace/gophercloud/pagination" th "github.com/rackspace/gophercloud/testhelper" "github.com/rackspace/gophercloud/testhelper/client" @@ -12,7 +13,7 @@ func TestList(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - MockListResponse(t) + fixtures.MockListResponse(t) count := 0 @@ -49,7 +50,7 @@ func TestListAll(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - MockListResponse(t) + fixtures.MockListResponse(t) allPages, err := List(client.ServiceClient(), &ListOpts{}).AllPages() th.AssertNoErr(t, err) @@ -75,7 +76,7 @@ func TestGet(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - MockGetResponse(t) + fixtures.MockGetResponse(t) v, err := Get(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract() th.AssertNoErr(t, err) @@ -89,7 +90,7 @@ func TestCreate(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - MockCreateResponse(t) + fixtures.MockCreateResponse(t) options := &CreateOpts{Size: 75} n, err := Create(client.ServiceClient(), options).Extract() @@ -103,7 +104,7 @@ func TestDelete(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - MockDeleteResponse(t) + fixtures.MockDeleteResponse(t) res := Delete(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22") th.AssertNoErr(t, res.Err) @@ -113,7 +114,7 @@ func TestUpdate(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - MockUpdateResponse(t) + fixtures.MockUpdateResponse(t) options := UpdateOpts{Name: "vol-002"} v, err := Update(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract() diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing/doc.go new file mode 100644 index 000000000000..2f66ba5e45a0 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing/doc.go @@ -0,0 +1,7 @@ +/* +This is package created is to hold fixtures (which imports testing), +so that importing volumes package does not inadvertently import testing into production code +More information here: +https://github.com/rackspace/gophercloud/issues/473 +*/ +package testing diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/fixtures_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing/fixtures.go similarity index 99% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/fixtures_test.go rename to Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing/fixtures.go index a1b8697c2a73..3df7653f7634 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/fixtures_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing/fixtures.go @@ -1,4 +1,4 @@ -package volumes +package testing import ( "fmt" diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests_test.go index 5bf9137906c1..8a7fa7467534 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests_test.go @@ -32,6 +32,8 @@ func TestCreateOpts(t *testing.T) { "name": "createdserver", "imageRef": "asdfasdfasdf", "flavorRef": "performance1-1", + "flavorName": "", + "imageName": "", "block_device_mapping_v2":[ { "uuid":"123456", diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/requests_test.go index e3c26d49a552..17418a3ce3ac 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/diskconfig/requests_test.go @@ -25,6 +25,8 @@ func TestCreateOpts(t *testing.T) { "name": "createdserver", "imageRef": "asdfasdfasdf", "flavorRef": "performance1-1", + "flavorName": "", + "imageName": "", "OS-DCF:diskConfig": "MANUAL" } } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/doc.go new file mode 100644 index 000000000000..fafe4a04d745 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/doc.go @@ -0,0 +1,2 @@ +// Package network provides the ability to manage nova-networks +package networks diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/fixtures.go new file mode 100644 index 000000000000..12b94859b16b --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/fixtures.go @@ -0,0 +1,209 @@ +// +build fixtures + +package networks + +import ( + "fmt" + "net/http" + "testing" + "time" + + th "github.com/rackspace/gophercloud/testhelper" + "github.com/rackspace/gophercloud/testhelper/client" +) + +// ListOutput is a sample response to a List call. +const ListOutput = ` +{ + "networks": [ + { + "bridge": "br100", + "bridge_interface": "eth0", + "broadcast": "10.0.0.7", + "cidr": "10.0.0.0/29", + "cidr_v6": null, + "created_at": "2011-08-15 06:19:19.387525", + "deleted": false, + "deleted_at": null, + "dhcp_start": "10.0.0.3", + "dns1": null, + "dns2": null, + "gateway": "10.0.0.1", + "gateway_v6": null, + "host": "nsokolov-desktop", + "id": "20c8acc0-f747-4d71-a389-46d078ebf047", + "injected": false, + "label": "mynet_0", + "multi_host": false, + "netmask": "255.255.255.248", + "netmask_v6": null, + "priority": null, + "project_id": "1234", + "rxtx_base": null, + "updated_at": "2011-08-16 09:26:13.048257", + "vlan": 100, + "vpn_private_address": "10.0.0.2", + "vpn_public_address": "127.0.0.1", + "vpn_public_port": 1000 + }, + { + "bridge": "br101", + "bridge_interface": "eth0", + "broadcast": "10.0.0.15", + "cidr": "10.0.0.10/29", + "cidr_v6": null, + "created_at": "2011-08-15 06:19:19.885495", + "deleted": false, + "deleted_at": null, + "dhcp_start": "10.0.0.11", + "dns1": null, + "dns2": null, + "gateway": "10.0.0.9", + "gateway_v6": null, + "host": null, + "id": "20c8acc0-f747-4d71-a389-46d078ebf000", + "injected": false, + "label": "mynet_1", + "multi_host": false, + "netmask": "255.255.255.248", + "netmask_v6": null, + "priority": null, + "project_id": null, + "rxtx_base": null, + "updated_at": null, + "vlan": 101, + "vpn_private_address": "10.0.0.10", + "vpn_public_address": null, + "vpn_public_port": 1001 + } + ] +} +` + +// GetOutput is a sample response to a Get call. +const GetOutput = ` +{ + "network": { + "bridge": "br101", + "bridge_interface": "eth0", + "broadcast": "10.0.0.15", + "cidr": "10.0.0.10/29", + "cidr_v6": null, + "created_at": "2011-08-15 06:19:19.885495", + "deleted": false, + "deleted_at": null, + "dhcp_start": "10.0.0.11", + "dns1": null, + "dns2": null, + "gateway": "10.0.0.9", + "gateway_v6": null, + "host": null, + "id": "20c8acc0-f747-4d71-a389-46d078ebf000", + "injected": false, + "label": "mynet_1", + "multi_host": false, + "netmask": "255.255.255.248", + "netmask_v6": null, + "priority": null, + "project_id": null, + "rxtx_base": null, + "updated_at": null, + "vlan": 101, + "vpn_private_address": "10.0.0.10", + "vpn_public_address": null, + "vpn_public_port": 1001 + } +} +` + +// FirstNetwork is the first result in ListOutput. +var nilTime time.Time +var FirstNetwork = Network{ + Bridge: "br100", + BridgeInterface: "eth0", + Broadcast: "10.0.0.7", + CIDR: "10.0.0.0/29", + CIDRv6: "", + CreatedAt: time.Date(2011, 8, 15, 6, 19, 19, 387525000, time.UTC), + Deleted: false, + DeletedAt: nilTime, + DHCPStart: "10.0.0.3", + DNS1: "", + DNS2: "", + Gateway: "10.0.0.1", + Gatewayv6: "", + Host: "nsokolov-desktop", + ID: "20c8acc0-f747-4d71-a389-46d078ebf047", + Injected: false, + Label: "mynet_0", + MultiHost: false, + Netmask: "255.255.255.248", + Netmaskv6: "", + Priority: 0, + ProjectID: "1234", + RXTXBase: 0, + UpdatedAt: time.Date(2011, 8, 16, 9, 26, 13, 48257000, time.UTC), + VLAN: 100, + VPNPrivateAddress: "10.0.0.2", + VPNPublicAddress: "127.0.0.1", + VPNPublicPort: 1000, +} + +// SecondNetwork is the second result in ListOutput. +var SecondNetwork = Network{ + Bridge: "br101", + BridgeInterface: "eth0", + Broadcast: "10.0.0.15", + CIDR: "10.0.0.10/29", + CIDRv6: "", + CreatedAt: time.Date(2011, 8, 15, 6, 19, 19, 885495000, time.UTC), + Deleted: false, + DeletedAt: nilTime, + DHCPStart: "10.0.0.11", + DNS1: "", + DNS2: "", + Gateway: "10.0.0.9", + Gatewayv6: "", + Host: "", + ID: "20c8acc0-f747-4d71-a389-46d078ebf000", + Injected: false, + Label: "mynet_1", + MultiHost: false, + Netmask: "255.255.255.248", + Netmaskv6: "", + Priority: 0, + ProjectID: "", + RXTXBase: 0, + UpdatedAt: nilTime, + VLAN: 101, + VPNPrivateAddress: "10.0.0.10", + VPNPublicAddress: "", + VPNPublicPort: 1001, +} + +// ExpectedNetworkSlice is the slice of results that should be parsed +// from ListOutput, in the expected order. +var ExpectedNetworkSlice = []Network{FirstNetwork, SecondNetwork} + +// HandleListSuccessfully configures the test server to respond to a List request. +func HandleListSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/os-networks", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, ListOutput) + }) +} + +// HandleGetSuccessfully configures the test server to respond to a Get request +// for an existing network. +func HandleGetSuccessfully(t *testing.T) { + th.Mux.HandleFunc("/os-networks/20c8acc0-f747-4d71-a389-46d078ebf000", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, GetOutput) + }) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/requests.go new file mode 100644 index 000000000000..eb203878ba0a --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/requests.go @@ -0,0 +1,22 @@ +package networks + +import ( + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +// List returns a Pager that allows you to iterate over a collection of Network. +func List(client *gophercloud.ServiceClient) pagination.Pager { + url := listURL(client) + createPage := func(r pagination.PageResult) pagination.Page { + return NetworkPage{pagination.SinglePageBase(r)} + } + return pagination.NewPager(client, url, createPage) +} + +// Get returns data about a previously created Network. +func Get(client *gophercloud.ServiceClient, id string) GetResult { + var res GetResult + _, res.Err = client.Get(getURL(client, id), &res.Body, nil) + return res +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/requests_test.go new file mode 100644 index 000000000000..722b3f0bd073 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/requests_test.go @@ -0,0 +1,37 @@ +package networks + +import ( + "testing" + + "github.com/rackspace/gophercloud/pagination" + th "github.com/rackspace/gophercloud/testhelper" + "github.com/rackspace/gophercloud/testhelper/client" +) + +func TestList(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleListSuccessfully(t) + + count := 0 + err := List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) { + count++ + actual, err := ExtractNetworks(page) + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, ExpectedNetworkSlice, actual) + + return true, nil + }) + th.AssertNoErr(t, err) + th.CheckEquals(t, 1, count) +} + +func TestGet(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + HandleGetSuccessfully(t) + + actual, err := Get(client.ServiceClient(), "20c8acc0-f747-4d71-a389-46d078ebf000").Extract() + th.AssertNoErr(t, err) + th.CheckDeepEquals(t, &SecondNetwork, actual) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/results.go new file mode 100644 index 000000000000..55b361d7fc98 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/results.go @@ -0,0 +1,222 @@ +package networks + +import ( + "fmt" + "time" + + "github.com/mitchellh/mapstructure" + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +// A Network represents a nova-network that an instance communicates on +type Network struct { + // The Bridge that VIFs on this network are connected to + Bridge string `mapstructure:"bridge"` + + // BridgeInterface is what interface is connected to the Bridge + BridgeInterface string `mapstructure:"bridge_interface"` + + // The Broadcast address of the network. + Broadcast string `mapstructure:"broadcast"` + + // CIDR is the IPv4 subnet. + CIDR string `mapstructure:"cidr"` + + // CIDRv6 is the IPv6 subnet. + CIDRv6 string `mapstructure:"cidr_v6"` + + // CreatedAt is when the network was created.. + CreatedAt time.Time `mapstructure:"-"` + + // Deleted shows if the network has been deleted. + Deleted bool `mapstructure:"deleted"` + + // DeletedAt is the time when the network was deleted. + DeletedAt time.Time `mapstructure:"-"` + + // DHCPStart is the start of the DHCP address range. + DHCPStart string `mapstructure:"dhcp_start"` + + // DNS1 is the first DNS server to use through DHCP. + DNS1 string `mapstructure:"dns_1"` + + // DNS2 is the first DNS server to use through DHCP. + DNS2 string `mapstructure:"dns_2"` + + // Gateway is the network gateway. + Gateway string `mapstructure:"gateway"` + + // Gatewayv6 is the IPv6 network gateway. + Gatewayv6 string `mapstructure:"gateway_v6"` + + // Host is the host that the network service is running on. + Host string `mapstructure:"host"` + + // ID is the UUID of the network. + ID string `mapstructure:"id"` + + // Injected determines if network information is injected into the host. + Injected bool `mapstructure:"injected"` + + // Label is the common name that the network has.. + Label string `mapstructure:"label"` + + // MultiHost is if multi-host networking is enablec.. + MultiHost bool `mapstructure:"multi_host"` + + // Netmask is the network netmask. + Netmask string `mapstructure:"netmask"` + + // Netmaskv6 is the IPv6 netmask. + Netmaskv6 string `mapstructure:"netmask_v6"` + + // Priority is the network interface priority. + Priority int `mapstructure:"priority"` + + // ProjectID is the project associated with this network. + ProjectID string `mapstructure:"project_id"` + + // RXTXBase configures bandwidth entitlement. + RXTXBase int `mapstructure:"rxtx_base"` + + // UpdatedAt is the time when the network was last updated. + UpdatedAt time.Time `mapstructure:"-"` + + // VLAN is the vlan this network runs on. + VLAN int `mapstructure:"vlan"` + + // VPNPrivateAddress is the private address of the CloudPipe VPN. + VPNPrivateAddress string `mapstructure:"vpn_private_address"` + + // VPNPublicAddress is the public address of the CloudPipe VPN. + VPNPublicAddress string `mapstructure:"vpn_public_address"` + + // VPNPublicPort is the port of the CloudPipe VPN. + VPNPublicPort int `mapstructure:"vpn_public_port"` +} + +// NetworkPage stores a single, only page of Networks +// results from a List call. +type NetworkPage struct { + pagination.SinglePageBase +} + +// IsEmpty determines whether or not a NetworkPage is empty. +func (page NetworkPage) IsEmpty() (bool, error) { + va, err := ExtractNetworks(page) + return len(va) == 0, err +} + +// ExtractNetworks interprets a page of results as a slice of Networks +func ExtractNetworks(page pagination.Page) ([]Network, error) { + var res struct { + Networks []Network `mapstructure:"networks"` + } + + err := mapstructure.Decode(page.(NetworkPage).Body, &res) + + var rawNetworks []interface{} + body := page.(NetworkPage).Body + switch body.(type) { + case map[string]interface{}: + rawNetworks = body.(map[string]interface{})["networks"].([]interface{}) + case map[string][]interface{}: + rawNetworks = body.(map[string][]interface{})["networks"] + default: + return res.Networks, fmt.Errorf("Unknown type") + } + + for i := range rawNetworks { + thisNetwork := rawNetworks[i].(map[string]interface{}) + if t, ok := thisNetwork["created_at"].(string); ok && t != "" { + createdAt, err := time.Parse("2006-01-02 15:04:05.000000", t) + if err != nil { + return res.Networks, err + } + res.Networks[i].CreatedAt = createdAt + } + + if t, ok := thisNetwork["updated_at"].(string); ok && t != "" { + updatedAt, err := time.Parse("2006-01-02 15:04:05.000000", t) + if err != nil { + return res.Networks, err + } + res.Networks[i].UpdatedAt = updatedAt + } + + if t, ok := thisNetwork["deleted_at"].(string); ok && t != "" { + deletedAt, err := time.Parse("2006-01-02 15:04:05.000000", t) + if err != nil { + return res.Networks, err + } + res.Networks[i].DeletedAt = deletedAt + } + } + + return res.Networks, err +} + +type NetworkResult struct { + gophercloud.Result +} + +// Extract is a method that attempts to interpret any Network resource +// response as a Network struct. +func (r NetworkResult) Extract() (*Network, error) { + if r.Err != nil { + return nil, r.Err + } + + var res struct { + Network *Network `json:"network" mapstructure:"network"` + } + + config := &mapstructure.DecoderConfig{ + Result: &res, + WeaklyTypedInput: true, + } + decoder, err := mapstructure.NewDecoder(config) + if err != nil { + return nil, err + } + + if err := decoder.Decode(r.Body); err != nil { + return nil, err + } + + b := r.Body.(map[string]interface{})["network"].(map[string]interface{}) + + if t, ok := b["created_at"].(string); ok && t != "" { + createdAt, err := time.Parse("2006-01-02 15:04:05.000000", t) + if err != nil { + return res.Network, err + } + res.Network.CreatedAt = createdAt + } + + if t, ok := b["updated_at"].(string); ok && t != "" { + updatedAt, err := time.Parse("2006-01-02 15:04:05.000000", t) + if err != nil { + return res.Network, err + } + res.Network.UpdatedAt = updatedAt + } + + if t, ok := b["deleted_at"].(string); ok && t != "" { + deletedAt, err := time.Parse("2006-01-02 15:04:05.000000", t) + if err != nil { + return res.Network, err + } + res.Network.DeletedAt = deletedAt + } + + return res.Network, err + +} + +// GetResult is the response from a Get operation. Call its Extract method to interpret it +// as a Network. +type GetResult struct { + NetworkResult +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/urls.go new file mode 100644 index 000000000000..69664620aff9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/urls.go @@ -0,0 +1,17 @@ +package networks + +import "github.com/rackspace/gophercloud" + +const resourcePath = "os-networks" + +func resourceURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL(resourcePath) +} + +func listURL(c *gophercloud.ServiceClient) string { + return resourceURL(c) +} + +func getURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(resourcePath, id) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/urls_test.go new file mode 100644 index 000000000000..be54c90a566a --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/networks/urls_test.go @@ -0,0 +1,25 @@ +package networks + +import ( + "testing" + + th "github.com/rackspace/gophercloud/testhelper" + "github.com/rackspace/gophercloud/testhelper/client" +) + +func TestListURL(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + c := client.ServiceClient() + + th.CheckEquals(t, c.Endpoint+"os-networks", listURL(c)) +} + +func TestGetURL(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + c := client.ServiceClient() + id := "1" + + th.CheckEquals(t, c.Endpoint+"os-networks/"+id, getURL(c, id)) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/doc.go new file mode 100644 index 000000000000..0bd45661b562 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/doc.go @@ -0,0 +1,3 @@ +// Package schedulerhints enables instances to provide the OpenStack scheduler +// hints about where they should be placed in the cloud. +package schedulerhints diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/requests.go new file mode 100644 index 000000000000..567eef41a11d --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/requests.go @@ -0,0 +1,134 @@ +package schedulerhints + +import ( + "fmt" + "net" + "regexp" + "strings" + + "github.com/rackspace/gophercloud/openstack/compute/v2/servers" +) + +// SchedulerHints represents a set of scheduling hints that are passed to the +// OpenStack scheduler +type SchedulerHints struct { + // Group specifies a Server Group to place the instance in. + Group string + + // DifferentHost will place the instance on a compute node that does not + // host the given instances. + DifferentHost []string + + // SameHost will place the instance on a compute node that hosts the given + // instances. + SameHost []string + + // Query is a conditional statement that results in compute nodes able to + // host the instance. + Query []interface{} + + // TargetCell specifies a cell name where the instance will be placed. + TargetCell string + + // BuildNearHostIP specifies a subnet of compute nodes to host the instance. + BuildNearHostIP string +} + +// SchedulerHintsBuilder builds the scheduler hints into a serializable format. +type SchedulerHintsBuilder interface { + ToServerSchedulerHintsMap() (map[string]interface{}, error) +} + +// ToServerSchedulerHintsMap builds the scheduler hints into a serializable format. +func (opts SchedulerHints) ToServerSchedulerHintsMap() (map[string]interface{}, error) { + sh := make(map[string]interface{}) + + uuidRegex, _ := regexp.Compile("^[a-z0-9]{8}-[a-z0-9]{4}-[1-5][a-z0-9]{3}-[a-z0-9]{4}-[a-z0-9]{12}$") + + if opts.Group != "" { + if !uuidRegex.MatchString(opts.Group) { + return nil, fmt.Errorf("Group must be a UUID") + } + sh["group"] = opts.Group + } + + if len(opts.DifferentHost) > 0 { + for _, diffHost := range opts.DifferentHost { + if !uuidRegex.MatchString(diffHost) { + return nil, fmt.Errorf("The hosts in DifferentHost must be in UUID format.") + } + } + sh["different_host"] = opts.DifferentHost + } + + if len(opts.SameHost) > 0 { + for _, sameHost := range opts.SameHost { + if !uuidRegex.MatchString(sameHost) { + return nil, fmt.Errorf("The hosts in SameHost must be in UUID format.") + } + } + sh["same_host"] = opts.SameHost + } + + /* Query can be something simple like: + [">=", "$free_ram_mb", 1024] + + Or more complex like: + ['and', + ['>=', '$free_ram_mb', 1024], + ['>=', '$free_disk_mb', 200 * 1024] + ] + + Because of the possible complexity, just make sure the length is a minimum of 3. + */ + if len(opts.Query) > 0 { + if len(opts.Query) < 3 { + return nil, fmt.Errorf("Query must be a conditional statement in the format of [op,variable,value]") + } + sh["query"] = opts.Query + } + + if opts.TargetCell != "" { + sh["target_cell"] = opts.TargetCell + } + + if opts.BuildNearHostIP != "" { + if _, _, err := net.ParseCIDR(opts.BuildNearHostIP); err != nil { + return nil, fmt.Errorf("BuildNearHostIP must be a valid subnet in the form 192.168.1.1/24") + } + ipParts := strings.Split(opts.BuildNearHostIP, "/") + sh["build_near_host_ip"] = ipParts[0] + sh["cidr"] = "/" + ipParts[1] + } + + return sh, nil +} + +// CreateOptsExt adds a SchedulerHints option to the base CreateOpts. +type CreateOptsExt struct { + servers.CreateOptsBuilder + + // SchedulerHints provides a set of hints to the scheduler. + SchedulerHints SchedulerHintsBuilder +} + +// ToServerCreateMap adds the SchedulerHints option to the base server creation options. +func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) { + base, err := opts.CreateOptsBuilder.ToServerCreateMap() + if err != nil { + return nil, err + } + + schedulerHints, err := opts.SchedulerHints.ToServerSchedulerHintsMap() + if err != nil { + return nil, err + } + + if len(schedulerHints) == 0 { + return base, nil + } + + base["os:scheduler_hints"] = schedulerHints + + return base, nil +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/requests_test.go new file mode 100644 index 000000000000..9b38b35d9c4c --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints/requests_test.go @@ -0,0 +1,130 @@ +package schedulerhints + +import ( + "testing" + + "github.com/rackspace/gophercloud/openstack/compute/v2/servers" + th "github.com/rackspace/gophercloud/testhelper" +) + +func TestCreateOpts(t *testing.T) { + base := servers.CreateOpts{ + Name: "createdserver", + ImageRef: "asdfasdfasdf", + FlavorRef: "performance1-1", + } + + schedulerHints := SchedulerHints{ + Group: "101aed42-22d9-4a3e-9ba1-21103b0d1aba", + DifferentHost: []string{ + "a0cf03a5-d921-4877-bb5c-86d26cf818e1", + "8c19174f-4220-44f0-824a-cd1eeef10287", + }, + SameHost: []string{ + "a0cf03a5-d921-4877-bb5c-86d26cf818e1", + "8c19174f-4220-44f0-824a-cd1eeef10287", + }, + Query: []interface{}{">=", "$free_ram_mb", "1024"}, + TargetCell: "foobar", + BuildNearHostIP: "192.168.1.1/24", + } + + ext := CreateOptsExt{ + CreateOptsBuilder: base, + SchedulerHints: schedulerHints, + } + + expected := ` + { + "server": { + "name": "createdserver", + "imageRef": "asdfasdfasdf", + "flavorRef": "performance1-1", + "flavorName": "", + "imageName": "" + }, + "os:scheduler_hints": { + "group": "101aed42-22d9-4a3e-9ba1-21103b0d1aba", + "different_host": [ + "a0cf03a5-d921-4877-bb5c-86d26cf818e1", + "8c19174f-4220-44f0-824a-cd1eeef10287" + ], + "same_host": [ + "a0cf03a5-d921-4877-bb5c-86d26cf818e1", + "8c19174f-4220-44f0-824a-cd1eeef10287" + ], + "query": [ + ">=", "$free_ram_mb", "1024" + ], + "target_cell": "foobar", + "build_near_host_ip": "192.168.1.1", + "cidr": "/24" + } + } + ` + actual, err := ext.ToServerCreateMap() + th.AssertNoErr(t, err) + th.CheckJSONEquals(t, expected, actual) +} + +func TestCreateOptsWithComplexQuery(t *testing.T) { + base := servers.CreateOpts{ + Name: "createdserver", + ImageRef: "asdfasdfasdf", + FlavorRef: "performance1-1", + } + + schedulerHints := SchedulerHints{ + Group: "101aed42-22d9-4a3e-9ba1-21103b0d1aba", + DifferentHost: []string{ + "a0cf03a5-d921-4877-bb5c-86d26cf818e1", + "8c19174f-4220-44f0-824a-cd1eeef10287", + }, + SameHost: []string{ + "a0cf03a5-d921-4877-bb5c-86d26cf818e1", + "8c19174f-4220-44f0-824a-cd1eeef10287", + }, + Query: []interface{}{"and", []string{">=", "$free_ram_mb", "1024"}, []string{">=", "$free_disk_mb", "204800"}}, + TargetCell: "foobar", + BuildNearHostIP: "192.168.1.1/24", + } + + ext := CreateOptsExt{ + CreateOptsBuilder: base, + SchedulerHints: schedulerHints, + } + + expected := ` + { + "server": { + "name": "createdserver", + "imageRef": "asdfasdfasdf", + "flavorRef": "performance1-1", + "flavorName": "", + "imageName": "" + }, + "os:scheduler_hints": { + "group": "101aed42-22d9-4a3e-9ba1-21103b0d1aba", + "different_host": [ + "a0cf03a5-d921-4877-bb5c-86d26cf818e1", + "8c19174f-4220-44f0-824a-cd1eeef10287" + ], + "same_host": [ + "a0cf03a5-d921-4877-bb5c-86d26cf818e1", + "8c19174f-4220-44f0-824a-cd1eeef10287" + ], + "query": [ + "and", + [">=", "$free_ram_mb", "1024"], + [">=", "$free_disk_mb", "204800"] + ], + "target_cell": "foobar", + "build_near_host_ip": "192.168.1.1", + "cidr": "/24" + } + } + ` + actual, err := ext.ToServerCreateMap() + th.AssertNoErr(t, err) + th.CheckJSONEquals(t, expected, actual) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/fixtures.go index 1c6ba394920f..8c42e48e4edf 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/fixtures.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups/fixtures.go @@ -242,6 +242,7 @@ func mockAddServerToGroupResponse(t *testing.T, serverID string) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) + fmt.Fprintf(w, `{}`) }) } @@ -261,5 +262,6 @@ func mockRemoveServerFromGroupResponse(t *testing.T, serverID string) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) + fmt.Fprintf(w, `{}`) }) } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/requests_test.go index e17f7e00637d..b0a765befa95 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/requests_test.go @@ -3,15 +3,44 @@ package volumeattach import ( "testing" + fixtures "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing" "github.com/rackspace/gophercloud/pagination" th "github.com/rackspace/gophercloud/testhelper" "github.com/rackspace/gophercloud/testhelper/client" ) +// FirstVolumeAttachment is the first result in ListOutput. +var FirstVolumeAttachment = VolumeAttachment{ + Device: "/dev/vdd", + ID: "a26887c6-c47b-4654-abb5-dfadf7d3f803", + ServerID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", + VolumeID: "a26887c6-c47b-4654-abb5-dfadf7d3f803", +} + +// SecondVolumeAttachment is the first result in ListOutput. +var SecondVolumeAttachment = VolumeAttachment{ + Device: "/dev/vdc", + ID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", + ServerID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", + VolumeID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", +} + +// ExpectedVolumeAttachmentSlide is the slice of results that should be parsed +// from ListOutput, in the expected order. +var ExpectedVolumeAttachmentSlice = []VolumeAttachment{FirstVolumeAttachment, SecondVolumeAttachment} + +//CreatedVolumeAttachment is the parsed result from CreatedOutput. +var CreatedVolumeAttachment = VolumeAttachment{ + Device: "/dev/vdc", + ID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", + ServerID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", + VolumeID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", +} + func TestList(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - HandleListSuccessfully(t) + fixtures.HandleListSuccessfully(t) serverId := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" count := 0 @@ -30,7 +59,7 @@ func TestList(t *testing.T) { func TestCreate(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - HandleCreateSuccessfully(t) + fixtures.HandleCreateSuccessfully(t) serverId := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" actual, err := Create(client.ServiceClient(), serverId, CreateOpts{ @@ -44,7 +73,7 @@ func TestCreate(t *testing.T) { func TestGet(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - HandleGetSuccessfully(t) + fixtures.HandleGetSuccessfully(t) aId := "a26887c6-c47b-4654-abb5-dfadf7d3f804" serverId := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" @@ -56,7 +85,7 @@ func TestGet(t *testing.T) { func TestDelete(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - HandleDeleteSuccessfully(t) + fixtures.HandleDeleteSuccessfully(t) aId := "a26887c6-c47b-4654-abb5-dfadf7d3f804" serverId := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing/doc.go new file mode 100644 index 000000000000..183391a6291f --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing/doc.go @@ -0,0 +1,7 @@ +/* +This is package created is to hold fixtures (which imports testing), +so that importing volumeattach package does not inadvertently import testing into production code +More information here: +https://github.com/rackspace/gophercloud/issues/473 +*/ +package testing diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing/fixtures.go similarity index 74% rename from Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/fixtures.go rename to Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing/fixtures.go index a7f03b322c89..c469bfbc8593 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/fixtures.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing/fixtures.go @@ -1,6 +1,6 @@ // +build fixtures -package volumeattach +package testing import ( "fmt" @@ -55,34 +55,6 @@ const CreateOutput = ` } ` -// FirstVolumeAttachment is the first result in ListOutput. -var FirstVolumeAttachment = VolumeAttachment{ - Device: "/dev/vdd", - ID: "a26887c6-c47b-4654-abb5-dfadf7d3f803", - ServerID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", - VolumeID: "a26887c6-c47b-4654-abb5-dfadf7d3f803", -} - -// SecondVolumeAttachment is the first result in ListOutput. -var SecondVolumeAttachment = VolumeAttachment{ - Device: "/dev/vdc", - ID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", - ServerID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", - VolumeID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", -} - -// ExpectedVolumeAttachmentSlide is the slice of results that should be parsed -// from ListOutput, in the expected order. -var ExpectedVolumeAttachmentSlice = []VolumeAttachment{FirstVolumeAttachment, SecondVolumeAttachment} - -// CreatedVolumeAttachment is the parsed result from CreatedOutput. -var CreatedVolumeAttachment = VolumeAttachment{ - Device: "/dev/vdc", - ID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", - ServerID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", - VolumeID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", -} - // HandleListSuccessfully configures the test server to respond to a List request. func HandleListSuccessfully(t *testing.T) { th.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/os-volume_attachments", func(w http.ResponseWriter, r *http.Request) { diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests.go index 586be67ac258..59123aaf76f3 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/flavors/requests.go @@ -1,6 +1,8 @@ package flavors import ( + "fmt" + "github.com/rackspace/gophercloud" "github.com/rackspace/gophercloud/pagination" ) @@ -66,3 +68,36 @@ func Get(client *gophercloud.ServiceClient, id string) GetResult { _, res.Err = client.Get(getURL(client, id), &res.Body, nil) return res } + +// IDFromName is a convienience function that returns a flavor's ID given its name. +func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { + flavorCount := 0 + flavorID := "" + if name == "" { + return "", fmt.Errorf("A flavor name must be provided.") + } + pager := ListDetail(client, nil) + pager.EachPage(func(page pagination.Page) (bool, error) { + flavorList, err := ExtractFlavors(page) + if err != nil { + return false, err + } + + for _, f := range flavorList { + if f.Name == name { + flavorCount++ + flavorID = f.ID + } + } + return true, nil + }) + + switch flavorCount { + case 0: + return "", fmt.Errorf("Unable to find flavor: %s", name) + case 1: + return flavorID, nil + default: + return "", fmt.Errorf("Found %d flavors matching %s", flavorCount, name) + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests.go index 7ce5139519c7..1e021ad4cd05 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/images/requests.go @@ -1,6 +1,8 @@ package images import ( + "fmt" + "github.com/rackspace/gophercloud" "github.com/rackspace/gophercloud/pagination" ) @@ -70,3 +72,38 @@ func Delete(client *gophercloud.ServiceClient, id string) DeleteResult { _, result.Err = client.Delete(deleteURL(client, id), nil) return result } + +// IDFromName is a convienience function that returns an image's ID given its name. +func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { + imageCount := 0 + imageID := "" + if name == "" { + return "", fmt.Errorf("An image name must be provided.") + } + pager := ListDetail(client, &ListOpts{ + Name: name, + }) + pager.EachPage(func(page pagination.Page) (bool, error) { + imageList, err := ExtractImages(page) + if err != nil { + return false, err + } + + for _, i := range imageList { + if i.Name == name { + imageCount++ + imageID = i.ID + } + } + return true, nil + }) + + switch imageCount { + case 0: + return "", fmt.Errorf("Unable to find image: %s", name) + case 1: + return imageID, nil + default: + return "", fmt.Errorf("Found %d images matching %s", imageCount, name) + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests.go index aa8c1a87b277..f9839d9f287a 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests.go @@ -2,10 +2,13 @@ package servers import ( "encoding/base64" + "encoding/json" "errors" "fmt" "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/openstack/compute/v2/flavors" + "github.com/rackspace/gophercloud/openstack/compute/v2/images" "github.com/rackspace/gophercloud/pagination" ) @@ -14,6 +17,7 @@ import ( type ListOptsBuilder interface { ToServerListQuery() (string, error) } + // ListOpts allows the filtering and sorting of paginated collections through // the API. Filtering is achieved by passing in struct field values that map to // the server attributes you want to see returned. Marker and Limit are used @@ -45,6 +49,9 @@ type ListOpts struct { // Integer value for the limit of values to return. Limit int `q:"limit"` + + // Bool to show all tenants + AllTenants bool `q:"all_tenants"` } // ToServerListQuery formats a ListOpts into a query string. @@ -95,18 +102,54 @@ type Network struct { FixedIP string } +// Personality is an array of files that are injected into the server at launch. +type Personality []*File + +// File is used within CreateOpts and RebuildOpts to inject a file into the server at launch. +// File implements the json.Marshaler interface, so when a Create or Rebuild operation is requested, +// json.Marshal will call File's MarshalJSON method. +type File struct { + // Path of the file + Path string + // Contents of the file. Maximum content size is 255 bytes. + Contents []byte +} + +// MarshalJSON marshals the escaped file, base64 encoding the contents. +func (f *File) MarshalJSON() ([]byte, error) { + file := struct { + Path string `json:"path"` + Contents string `json:"contents"` + }{ + Path: f.Path, + Contents: base64.StdEncoding.EncodeToString(f.Contents), + } + return json.Marshal(file) +} + // CreateOpts specifies server creation parameters. type CreateOpts struct { // Name [required] is the name to assign to the newly launched server. Name string - // ImageRef [required] is the ID or full URL to the image that contains the server's OS and initial state. - // Optional if using the boot-from-volume extension. + // ImageRef [optional; required if ImageName is not provided] is the ID or full + // URL to the image that contains the server's OS and initial state. + // Also optional if using the boot-from-volume extension. ImageRef string - // FlavorRef [required] is the ID or full URL to the flavor that describes the server's specs. + // ImageName [optional; required if ImageRef is not provided] is the name of the + // image that contains the server's OS and initial state. + // Also optional if using the boot-from-volume extension. + ImageName string + + // FlavorRef [optional; required if FlavorName is not provided] is the ID or + // full URL to the flavor that describes the server's specs. FlavorRef string + // FlavorName [optional; required if FlavorRef is not provided] is the name of + // the flavor that describes the server's specs. + FlavorName string + // SecurityGroups [optional] lists the names of the security groups to which this server should belong. SecurityGroups []string @@ -124,9 +167,9 @@ type CreateOpts struct { // Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server. Metadata map[string]string - // Personality [optional] includes the path and contents of a file to inject into the server at launch. - // The maximum size of the file is 255 bytes (decoded). - Personality []byte + // Personality [optional] includes files to inject into the server at launch. + // Create will base64-encode file contents for you. + Personality Personality // ConfigDrive [optional] enables metadata injection through a configuration drive. ConfigDrive bool @@ -148,16 +191,14 @@ func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) { server["name"] = opts.Name server["imageRef"] = opts.ImageRef + server["imageName"] = opts.ImageName server["flavorRef"] = opts.FlavorRef + server["flavorName"] = opts.FlavorName if opts.UserData != nil { encoded := base64.StdEncoding.EncodeToString(opts.UserData) server["user_data"] = &encoded } - if opts.Personality != nil { - encoded := base64.StdEncoding.EncodeToString(opts.Personality) - server["personality"] = &encoded - } if opts.ConfigDrive { server["config_drive"] = "true" } @@ -202,6 +243,10 @@ func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) { server["networks"] = networks } + if len(opts.Personality) > 0 { + server["personality"] = opts.Personality + } + return map[string]interface{}{"server": server}, nil } @@ -215,6 +260,38 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateRes return res } + // If ImageRef isn't provided, use ImageName to ascertain the image ID. + if reqBody["server"].(map[string]interface{})["imageRef"].(string) == "" { + imageName := reqBody["server"].(map[string]interface{})["imageName"].(string) + if imageName == "" { + res.Err = errors.New("One and only one of ImageRef and ImageName must be provided.") + return res + } + imageID, err := images.IDFromName(client, imageName) + if err != nil { + res.Err = err + return res + } + reqBody["server"].(map[string]interface{})["imageRef"] = imageID + } + delete(reqBody["server"].(map[string]interface{}), "imageName") + + // If FlavorRef isn't provided, use FlavorName to ascertain the flavor ID. + if reqBody["server"].(map[string]interface{})["flavorRef"].(string) == "" { + flavorName := reqBody["server"].(map[string]interface{})["flavorName"].(string) + if flavorName == "" { + res.Err = errors.New("One and only one of FlavorRef and FlavorName must be provided.") + return res + } + flavorID, err := flavors.IDFromName(client, flavorName) + if err != nil { + res.Err = err + return res + } + reqBody["server"].(map[string]interface{})["flavorRef"] = flavorID + } + delete(reqBody["server"].(map[string]interface{}), "flavorName") + _, res.Err = client.Post(listURL(client), reqBody, &res.Body, nil) return res } @@ -391,9 +468,9 @@ type RebuildOpts struct { // Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server. Metadata map[string]string - // Personality [optional] includes the path and contents of a file to inject into the server at launch. - // The maximum size of the file is 255 bytes (decoded). - Personality []byte + // Personality [optional] includes files to inject into the server at launch. + // Rebuild will base64-encode file contents for you. + Personality Personality } // ToServerRebuildMap formats a RebuildOpts struct into a map for use in JSON @@ -429,9 +506,8 @@ func (opts RebuildOpts) ToServerRebuildMap() (map[string]interface{}, error) { server["metadata"] = opts.Metadata } - if opts.Personality != nil { - encoded := base64.StdEncoding.EncodeToString(opts.Personality) - server["personality"] = &encoded + if len(opts.Personality) > 0 { + server["personality"] = opts.Personality } return map[string]interface{}{"rebuild": server}, nil @@ -678,9 +754,7 @@ func Metadatum(client *gophercloud.ServiceClient, id, key string) GetMetadatumRe // DeleteMetadatum will delete the key-value pair with the given key for the given server ID. func DeleteMetadatum(client *gophercloud.ServiceClient, id, key string) DeleteMetadatumResult { var res DeleteMetadatumResult - _, res.Err = client.Delete(metadatumURL(client, id, key), &gophercloud.RequestOpts{ - JSONResponse: &res.Body, - }) + _, res.Err = client.Delete(metadatumURL(client, id, key), nil) return res } @@ -741,5 +815,38 @@ func CreateImage(client *gophercloud.ServiceClient, serverId string, opts Create }) res.Err = err res.Header = response.Header - return res + return res +} + +// IDFromName is a convienience function that returns a server's ID given its name. +func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { + serverCount := 0 + serverID := "" + if name == "" { + return "", fmt.Errorf("A server name must be provided.") + } + pager := List(client, nil) + pager.EachPage(func(page pagination.Page) (bool, error) { + serverList, err := ExtractServers(page) + if err != nil { + return false, err + } + + for _, s := range serverList { + if s.Name == name { + serverCount++ + serverID = s.ID + } + } + return true, nil + }) + + switch serverCount { + case 0: + return "", fmt.Errorf("Unable to find server: %s", name) + case 1: + return serverID, nil + default: + return "", fmt.Errorf("Found %d servers matching %s", serverCount, name) + } } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests_test.go index 1f39fe143bd0..88cb54dd7bd0 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/compute/v2/servers/requests_test.go @@ -1,6 +1,8 @@ package servers import ( + "encoding/base64" + "encoding/json" "net/http" "testing" @@ -334,3 +336,38 @@ func TestCreateServerImage(t *testing.T) { _, err := CreateImage(client.ServiceClient(), "serverimage", CreateImageOpts{Name: "test"}).ExtractImageID() th.AssertNoErr(t, err) } + +func TestMarshalPersonality(t *testing.T) { + name := "/etc/test" + contents := []byte("asdfasdf") + + personality := Personality{ + &File{ + Path: name, + Contents: contents, + }, + } + + data, err := json.Marshal(personality) + if err != nil { + t.Fatal(err) + } + + var actual []map[string]string + err = json.Unmarshal(data, &actual) + if err != nil { + t.Fatal(err) + } + + if len(actual) != 1 { + t.Fatal("expected personality length 1") + } + + if actual[0]["path"] != name { + t.Fatal("file path incorrect") + } + + if actual[0]["contents"] != base64.StdEncoding.EncodeToString(contents) { + t.Fatal("file contents incorrect") + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/errors.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/errors.go index 3a9172e0cc79..3dfdc08dbedd 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/errors.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/errors.go @@ -18,7 +18,7 @@ var ( // ErrDomainNameProvided is returned if you attempt to authenticate with a DomainName. ErrDomainNameProvided = unacceptedAttributeErr("DomainName") - // ErrUsernameRequired is returned if you attempt ot authenticate without a Username. + // ErrUsernameRequired is returned if you attempt to authenticate without a Username. ErrUsernameRequired = errors.New("You must supply a Username in your AuthOptions.") // ErrPasswordRequired is returned if you don't provide a password. diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go index efa054fb3994..074a89e69c32 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go @@ -1,6 +1,10 @@ package tokens -import "github.com/rackspace/gophercloud" +import ( + "fmt" + + "github.com/rackspace/gophercloud" +) // AuthOptionsBuilder describes any argument that may be passed to the Create call. type AuthOptionsBuilder interface { @@ -38,20 +42,24 @@ func (auth AuthOptions) ToTokenCreateMap() (map[string]interface{}, error) { return nil, ErrDomainNameProvided } - // Username and Password are always required. - if auth.Username == "" { - return nil, ErrUsernameRequired - } - if auth.Password == "" { - return nil, ErrPasswordRequired - } - // Populate the request map. authMap := make(map[string]interface{}) - authMap["passwordCredentials"] = map[string]interface{}{ - "username": auth.Username, - "password": auth.Password, + if auth.Username != "" { + if auth.Password != "" { + authMap["passwordCredentials"] = map[string]interface{}{ + "username": auth.Username, + "password": auth.Password, + } + } else { + return nil, ErrPasswordRequired + } + } else if auth.TokenID != "" { + authMap["token"] = map[string]interface{}{ + "id": auth.TokenID, + } + } else { + return nil, fmt.Errorf("You must provide either username/password or tenantID/token values.") } if auth.TenantID != "" { diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests_test.go index 2f02825a47aa..8b78c855048a 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests_test.go @@ -1,6 +1,7 @@ package tokens import ( + "fmt" "testing" "github.com/rackspace/gophercloud" @@ -22,7 +23,7 @@ func tokenPostErr(t *testing.T, options gophercloud.AuthOptions, expectedErr err HandleTokenPost(t, "") actualErr := Create(client.ServiceClient(), AuthOptions{options}).Err - th.CheckEquals(t, expectedErr, actualErr) + th.CheckDeepEquals(t, expectedErr, actualErr) } func TestCreateWithPassword(t *testing.T) { @@ -128,7 +129,7 @@ func TestRequireUsername(t *testing.T) { Password: "thing", } - tokenPostErr(t, options, ErrUsernameRequired) + tokenPostErr(t, options, fmt.Errorf("You must provide either username/password or tenantID/token values.")) } func TestRequirePassword(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/doc.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/doc.go new file mode 100644 index 000000000000..bdbc674d659b --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/doc.go @@ -0,0 +1,3 @@ +// Package roles provides information and interaction with the roles API +// resource for the OpenStack Identity service. +package roles diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests.go new file mode 100644 index 000000000000..d95c1e52f6f8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests.go @@ -0,0 +1,50 @@ +package roles + +import ( + "github.com/rackspace/gophercloud" + "github.com/rackspace/gophercloud/pagination" +) + +// ListAssignmentsOptsBuilder allows extensions to add additional parameters to +// the ListAssignments request. +type ListAssignmentsOptsBuilder interface { + ToRolesListAssignmentsQuery() (string, error) +} + +// ListAssignmentsOpts allows you to query the ListAssignments method. +// Specify one of or a combination of GroupId, RoleId, ScopeDomainId, ScopeProjectId, +// and/or UserId to search for roles assigned to corresponding entities. +// Effective lists effective assignments at the user, project, and domain level, +// allowing for the effects of group membership. +type ListAssignmentsOpts struct { + GroupId string `q:"group.id"` + RoleId string `q:"role.id"` + ScopeDomainId string `q:"scope.domain.id"` + ScopeProjectId string `q:"scope.project.id"` + UserId string `q:"user.id"` + Effective bool `q:"effective"` +} + +// ToRolesListAssignmentsQuery formats a ListAssignmentsOpts into a query string. +func (opts ListAssignmentsOpts) ToRolesListAssignmentsQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + if err != nil { + return "", err + } + return q.String(), nil +} + +// ListAssignments enumerates the roles assigned to a specified resource. +func ListAssignments(client *gophercloud.ServiceClient, opts ListAssignmentsOptsBuilder) pagination.Pager { + url := listAssignmentsURL(client) + query, err := opts.ToRolesListAssignmentsQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + createPage := func(r pagination.PageResult) pagination.Page { + return RoleAssignmentsPage{pagination.LinkedPageBase{PageResult: r}} + } + + return pagination.NewPager(client, url, createPage) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests_test.go new file mode 100644 index 000000000000..d62dbff9a2f7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests_test.go @@ -0,0 +1,104 @@ +package roles + +import ( + "fmt" + "net/http" + "reflect" + "testing" + + "github.com/rackspace/gophercloud/pagination" + "github.com/rackspace/gophercloud/testhelper" + "github.com/rackspace/gophercloud/testhelper/client" +) + +func TestListSinglePage(t *testing.T) { + testhelper.SetupHTTP() + defer testhelper.TeardownHTTP() + + testhelper.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) { + testhelper.TestMethod(t, r, "GET") + testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID) + + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, ` + { + "role_assignments": [ + { + "links": { + "assignment": "http://identity:35357/v3/domains/161718/users/313233/roles/123456" + }, + "role": { + "id": "123456" + }, + "scope": { + "domain": { + "id": "161718" + } + }, + "user": { + "id": "313233" + } + }, + { + "links": { + "assignment": "http://identity:35357/v3/projects/456789/groups/101112/roles/123456", + "membership": "http://identity:35357/v3/groups/101112/users/313233" + }, + "role": { + "id": "123456" + }, + "scope": { + "project": { + "id": "456789" + } + }, + "user": { + "id": "313233" + } + } + ], + "links": { + "self": "http://identity:35357/v3/role_assignments?effective", + "previous": null, + "next": null + } + } + `) + }) + + count := 0 + err := ListAssignments(client.ServiceClient(), ListAssignmentsOpts{}).EachPage(func(page pagination.Page) (bool, error) { + count++ + actual, err := ExtractRoleAssignments(page) + if err != nil { + return false, err + } + + expected := []RoleAssignment{ + RoleAssignment{ + Role: Role{ID: "123456"}, + Scope: Scope{Domain: Domain{ID: "161718"}}, + User: User{ID: "313233"}, + Group: Group{}, + }, + RoleAssignment{ + Role: Role{ID: "123456"}, + Scope: Scope{Project: Project{ID: "456789"}}, + User: User{ID: "313233"}, + Group: Group{}, + }, + } + + if !reflect.DeepEqual(expected, actual) { + t.Errorf("Expected %#v, got %#v", expected, actual) + } + + return true, nil + }) + if err != nil { + t.Errorf("Unexpected error while paging: %v", err) + } + if count != 1 { + t.Errorf("Expected 1 page, got %d", count) + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/results.go new file mode 100644 index 000000000000..d25abd25d773 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/results.go @@ -0,0 +1,81 @@ +package roles + +import ( + "github.com/rackspace/gophercloud/pagination" + + "github.com/mitchellh/mapstructure" +) + +// RoleAssignment is the result of a role assignments query. +type RoleAssignment struct { + Role Role `json:"role,omitempty"` + Scope Scope `json:"scope,omitempty"` + User User `json:"user,omitempty"` + Group Group `json:"group,omitempty"` +} + +type Role struct { + ID string `json:"id,omitempty"` +} + +type Scope struct { + Domain Domain `json:"domain,omitempty"` + Project Project `json:"domain,omitempty"` +} + +type Domain struct { + ID string `json:"id,omitempty"` +} + +type Project struct { + ID string `json:"id,omitempty"` +} + +type User struct { + ID string `json:"id,omitempty"` +} + +type Group struct { + ID string `json:"id,omitempty"` +} + +// RoleAssignmentsPage is a single page of RoleAssignments results. +type RoleAssignmentsPage struct { + pagination.LinkedPageBase +} + +// IsEmpty returns true if the page contains no results. +func (p RoleAssignmentsPage) IsEmpty() (bool, error) { + roleAssignments, err := ExtractRoleAssignments(p) + if err != nil { + return true, err + } + return len(roleAssignments) == 0, nil +} + +// NextPageURL uses the response's embedded link reference to navigate to the next page of results. +func (page RoleAssignmentsPage) NextPageURL() (string, error) { + type resp struct { + Links struct { + Next string `mapstructure:"next"` + } `mapstructure:"links"` + } + + var r resp + err := mapstructure.Decode(page.Body, &r) + if err != nil { + return "", err + } + + return r.Links.Next, nil +} + +// ExtractRoleAssignments extracts a slice of RoleAssignments from a Collection acquired from List. +func ExtractRoleAssignments(page pagination.Page) ([]RoleAssignment, error) { + var response struct { + RoleAssignments []RoleAssignment `mapstructure:"role_assignments"` + } + + err := mapstructure.Decode(page.(RoleAssignmentsPage).Body, &response) + return response.RoleAssignments, err +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls.go new file mode 100644 index 000000000000..b009340d0963 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls.go @@ -0,0 +1,7 @@ +package roles + +import "github.com/rackspace/gophercloud" + +func listAssignmentsURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL("role_assignments") +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls_test.go new file mode 100644 index 000000000000..04679dae4031 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls_test.go @@ -0,0 +1,15 @@ +package roles + +import ( + "testing" + + "github.com/rackspace/gophercloud" +) + +func TestListAssignmentsURL(t *testing.T) { + client := gophercloud.ServiceClient{Endpoint: "http://localhost:5000/v3/"} + url := listAssignmentsURL(&client) + if url != "http://localhost:5000/v3/role_assignments" { + t.Errorf("Unexpected list URL generated: [%s]", url) + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/fwaas/firewalls/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/fwaas/firewalls/requests_test.go index f24e2835ea9c..19d32c5ac306 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/fwaas/firewalls/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/fwaas/firewalls/requests_test.go @@ -212,9 +212,9 @@ func TestUpdate(t *testing.T) { "name": "fw", "admin_state_up": false, "tenant_id": "b4eedccc6fb74fa8a7ad6b08382b852b", - "firewall_policy_id": "19ab8c87-4a32-4e6a-a74e-b77fffb89a0c" + "firewall_policy_id": "19ab8c87-4a32-4e6a-a74e-b77fffb89a0c", "id": "ea5b5315-64f6-4ea3-8e58-981cc37c6576", - "description": "OpenStack firewall", + "description": "OpenStack firewall" } } `) diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/requests_test.go index 6da29a6b8e64..3b5c7c7105bb 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/pools/requests_test.go @@ -296,6 +296,7 @@ func TestAssociateHealthMonitor(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) + fmt.Fprintf(w, `{}`) }) _, err := AssociateMonitor(fake.ServiceClient(), "332abe93-f488-41ba-870b-2ac66be7f853", "b624decf-d5d3-4c66-9a3d-f047e7786181").Extract() diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go index 55e4b3b8043c..2712ac1621f9 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go @@ -45,6 +45,9 @@ type CreateOpts struct { // Required. Human-readable name for the VIP. Does not have to be unique. Name string + // Required for admins. Indicates the owner of the VIP. + TenantID string + // Optional. Describes the security group. Description string } @@ -62,6 +65,7 @@ func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { type secgroup struct { Name string `json:"name"` + TenantID string `json:"tenant_id,omitempty"` Description string `json:"description,omitempty"` } @@ -71,6 +75,7 @@ func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { reqBody := request{SecGroup: secgroup{ Name: opts.Name, + TenantID: opts.TenantID, Description: opts.Description, }} @@ -91,3 +96,36 @@ func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { _, res.Err = c.Delete(resourceURL(c, id), nil) return res } + +// IDFromName is a convenience function that returns a security group's ID given its name. +func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { + securityGroupCount := 0 + securityGroupID := "" + if name == "" { + return "", fmt.Errorf("A security group name must be provided.") + } + pager := List(client, ListOpts{}) + pager.EachPage(func(page pagination.Page) (bool, error) { + securityGroupList, err := ExtractGroups(page) + if err != nil { + return false, err + } + + for _, s := range securityGroupList { + if s.Name == name { + securityGroupCount++ + securityGroupID = s.ID + } + } + return true, nil + }) + + switch securityGroupCount { + case 0: + return "", fmt.Errorf("Unable to find security group: %s", name) + case 1: + return securityGroupID, nil + default: + return "", fmt.Errorf("Found %d security groups matching %s", securityGroupCount, name) + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go index 0b2d10b0efeb..a80ceb309995 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go @@ -99,6 +99,9 @@ type CreateOpts struct { // attribute matches the specified IP prefix as the source IP address of the // IP packet. RemoteIPPrefix string + + // Required for admins. Indicates the owner of the VIP. + TenantID string } // Create is an operation which provisions a new security group with default @@ -133,6 +136,7 @@ func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { Protocol string `json:"protocol,omitempty"` RemoteGroupID string `json:"remote_group_id,omitempty"` RemoteIPPrefix string `json:"remote_ip_prefix,omitempty"` + TenantID string `json:"tenant_id,omitempty"` } type request struct { @@ -148,6 +152,7 @@ func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { Protocol: opts.Protocol, RemoteGroupID: opts.RemoteGroupID, RemoteIPPrefix: opts.RemoteIPPrefix, + TenantID: opts.TenantID, }} _, res.Err = c.Post(rootURL(c), reqBody, &res.Body, nil) diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests.go index 7be322740068..25ab7a8b6457 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests.go @@ -1,6 +1,8 @@ package networks import ( + "fmt" + "github.com/rackspace/gophercloud" "github.com/rackspace/gophercloud/pagination" ) @@ -189,3 +191,36 @@ func Delete(c *gophercloud.ServiceClient, networkID string) DeleteResult { _, res.Err = c.Delete(deleteURL(c, networkID), nil) return res } + +// IDFromName is a convenience function that returns a network's ID given its name. +func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { + networkCount := 0 + networkID := "" + if name == "" { + return "", fmt.Errorf("A network name must be provided.") + } + pager := List(client, nil) + pager.EachPage(func(page pagination.Page) (bool, error) { + networkList, err := ExtractNetworks(page) + if err != nil { + return false, err + } + + for _, n := range networkList { + if n.Name == name { + networkCount++ + networkID = n.ID + } + } + return true, nil + }) + + switch networkCount { + case 0: + return "", fmt.Errorf("Unable to find network: %s", name) + case 1: + return networkID, nil + default: + return "", fmt.Errorf("Found %d networks matching %s", networkCount, name) + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests_test.go index a263b7b16b2c..81eb79cb5416 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/networks/requests_test.go @@ -204,6 +204,7 @@ func TestCreateWithOptionalFields(t *testing.T) { `) w.WriteHeader(http.StatusCreated) + fmt.Fprintf(w, `{}`) }) iTrue := true diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go index 781a3c3e745a..2caf1cace44b 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go @@ -1,6 +1,8 @@ package ports import ( + "fmt" + "github.com/rackspace/gophercloud" "github.com/rackspace/gophercloud/pagination" ) @@ -223,3 +225,36 @@ func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { _, res.Err = c.Delete(deleteURL(c, id), nil) return res } + +// IDFromName is a convenience function that returns a port's ID given its name. +func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { + portCount := 0 + portID := "" + if name == "" { + return "", fmt.Errorf("A port name must be provided.") + } + pager := List(client, nil) + pager.EachPage(func(page pagination.Page) (bool, error) { + portList, err := ExtractPorts(page) + if err != nil { + return false, err + } + + for _, p := range portList { + if p.Name == name { + portCount++ + portID = p.ID + } + } + return true, nil + }) + + switch portCount { + case 0: + return "", fmt.Errorf("Unable to find port: %s", name) + case 1: + return portID, nil + default: + return "", fmt.Errorf("Found %d ports matching %s", portCount, name) + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/requests.go index 6e01f059d754..6cde048ed04c 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/requests.go @@ -1,6 +1,8 @@ package subnets import ( + "fmt" + "github.com/rackspace/gophercloud" "github.com/rackspace/gophercloud/pagination" ) @@ -200,10 +202,10 @@ func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) { if opts.GatewayIP != "" { s["gateway_ip"] = opts.GatewayIP } - if len(opts.DNSNameservers) != 0 { + if opts.DNSNameservers != nil { s["dns_nameservers"] = opts.DNSNameservers } - if len(opts.HostRoutes) != 0 { + if opts.HostRoutes != nil { s["host_routes"] = opts.HostRoutes } @@ -234,3 +236,36 @@ func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { _, res.Err = c.Delete(deleteURL(c, id), nil) return res } + +// IDFromName is a convenience function that returns a subnet's ID given its name. +func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { + subnetCount := 0 + subnetID := "" + if name == "" { + return "", fmt.Errorf("A subnet name must be provided.") + } + pager := List(client, nil) + pager.EachPage(func(page pagination.Page) (bool, error) { + subnetList, err := ExtractSubnets(page) + if err != nil { + return false, err + } + + for _, s := range subnetList { + if s.Name == name { + subnetCount++ + subnetID = s.ID + } + } + return true, nil + }) + + switch subnetCount { + case 0: + return "", fmt.Errorf("Unable to find subnet: %s", name) + case 1: + return subnetID, nil + default: + return "", fmt.Errorf("Found %d subnets matching %s", subnetCount, name) + } +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results.go index 1910f17dd96f..77b956a17eff 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results.go @@ -55,8 +55,8 @@ type AllocationPool struct { // HostRoute represents a route that should be used by devices with IPs from // a subnet (not including local subnet route). type HostRoute struct { - DestinationCIDR string `json:"destination"` - NextHop string `json:"nexthop"` + DestinationCIDR string `mapstructure:"destination" json:"destination"` + NextHop string `mapstructure:"nexthop" json:"nexthop"` } // Subnet represents a subnet. See package documentation for a top-level diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results_test.go new file mode 100644 index 000000000000..d4048388cdbc --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/networking/v2/subnets/results_test.go @@ -0,0 +1,54 @@ +package subnets + +import ( + "encoding/json" + "github.com/rackspace/gophercloud" + th "github.com/rackspace/gophercloud/testhelper" + "testing" +) + +func TestHostRoute(t *testing.T) { + sejson := []byte(` + {"subnet": { + "name": "test-subnet", + "enable_dhcp": false, + "network_id": "3e66c41e-cbbd-4019-9aab-740b7e4150a0", + "tenant_id": "f86e123198cf42d19c8854c5f80c2f06", + "dns_nameservers": [], + "gateway_ip": "172.16.0.1", + "ipv6_ra_mode": null, + "allocation_pools": [ + { + "start": "172.16.0.2", + "end": "172.16.255.254" + } + ], + "host_routes": [ + { + "destination": "172.20.1.0/24", + "nexthop": "172.16.0.2" + } + ], + "ip_version": 4, + "ipv6_address_mode": null, + "cidr": "172.16.0.0/16", + "id": "6dcaa873-7115-41af-9ef5-915f73636e43", + "subnetpool_id": null + }} +`) + + var dejson interface{} + err := json.Unmarshal(sejson, &dejson) + if err != nil { + t.Fatalf("%s", err) + } + + resp := commonResult{gophercloud.Result{Body: dejson}} + subnet, err := resp.Extract() + if err != nil { + t.Fatalf("%s", err) + } + route := subnet.HostRoutes[0] + th.AssertEquals(t, route.NextHop, "172.16.0.2") + th.AssertEquals(t, route.DestinationCIDR, "172.20.1.0/24") +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/requests.go index a6451157050f..66c46a9787bb 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/accounts/requests.go @@ -43,7 +43,9 @@ func Get(c *gophercloud.ServiceClient, opts GetOptsBuilder) GetResult { MoreHeaders: h, OkCodes: []int{204}, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } @@ -97,7 +99,9 @@ func Update(c *gophercloud.ServiceClient, opts UpdateOptsBuilder) UpdateResult { MoreHeaders: h, OkCodes: []int{201, 202, 204}, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/requests.go index bbf8cdb952cc..50ff9f48f3b3 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers/requests.go @@ -114,7 +114,9 @@ func Create(c *gophercloud.ServiceClient, containerName string, opts CreateOptsB MoreHeaders: h, OkCodes: []int{201, 202, 204}, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } @@ -180,7 +182,9 @@ func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsB MoreHeaders: h, OkCodes: []int{201, 202, 204}, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } @@ -193,7 +197,9 @@ func Get(c *gophercloud.ServiceClient, containerName string) GetResult { resp, err := c.Request("HEAD", getURL(c, containerName), gophercloud.RequestOpts{ OkCodes: []int{200, 204}, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/fixtures.go index ec616371a3c5..7a6e6e1ee776 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/fixtures.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/fixtures.go @@ -3,7 +3,9 @@ package objects import ( + "crypto/md5" "fmt" + "io" "net/http" "testing" @@ -107,12 +109,18 @@ func HandleListObjectNamesSuccessfully(t *testing.T) { // HandleCreateTextObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux // that responds with a `Create` response. A Content-Type of "text/plain" is expected. -func HandleCreateTextObjectSuccessfully(t *testing.T) { +func HandleCreateTextObjectSuccessfully(t *testing.T, content string) { th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) th.TestHeader(t, r, "Content-Type", "text/plain") th.TestHeader(t, r, "Accept", "application/json") + + hash := md5.New() + io.WriteString(hash, content) + localChecksum := hash.Sum(nil) + + w.Header().Set("ETag", fmt.Sprintf("%x", localChecksum)) w.WriteHeader(http.StatusCreated) }) } @@ -120,7 +128,7 @@ func HandleCreateTextObjectSuccessfully(t *testing.T) { // HandleCreateTypelessObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler // mux that responds with a `Create` response. No Content-Type header may be present in the request, so that server- // side content-type detection will be triggered properly. -func HandleCreateTypelessObjectSuccessfully(t *testing.T) { +func HandleCreateTypelessObjectSuccessfully(t *testing.T, content string) { th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "PUT") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) @@ -130,6 +138,11 @@ func HandleCreateTypelessObjectSuccessfully(t *testing.T) { t.Errorf("Expected Content-Type header to be omitted, but was %#v", contentType) } + hash := md5.New() + io.WriteString(hash, content) + localChecksum := hash.Sum(nil) + + w.Header().Set("ETag", fmt.Sprintf("%x", localChecksum)) w.WriteHeader(http.StatusCreated) }) } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests.go index 7eedde25509f..c2fbaae27235 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests.go @@ -1,7 +1,9 @@ package objects import ( + "bytes" "crypto/hmac" + "crypto/md5" "crypto/sha1" "fmt" "io" @@ -134,10 +136,11 @@ func Download(c *gophercloud.ServiceClient, containerName, objectName string, op MoreHeaders: h, OkCodes: []int{200, 304}, }) - - res.Body = resp.Body + if resp != nil { + res.Header = resp.Header + res.Body = resp.Body + } res.Err = err - res.Header = resp.Header return res } @@ -187,8 +190,9 @@ func (opts CreateOpts) ToObjectCreateParams() (map[string]string, string, error) return h, q.String(), nil } -// Create is a function that creates a new object or replaces an existing object. -func Create(c *gophercloud.ServiceClient, containerName, objectName string, content io.Reader, opts CreateOptsBuilder) CreateResult { +// Create is a function that creates a new object or replaces an existing object. If the returned response's ETag +// header fails to match the local checksum, the failed request will automatically be retried up to a maximum of 3 times. +func Create(c *gophercloud.ServiceClient, containerName, objectName string, content io.ReadSeeker, opts CreateOptsBuilder) CreateResult { var res CreateResult url := createURL(c, containerName, objectName) @@ -208,14 +212,37 @@ func Create(c *gophercloud.ServiceClient, containerName, objectName string, cont url += query } + hash := md5.New() + + contentBuffer := bytes.NewBuffer([]byte{}) + _, err := io.Copy(contentBuffer, io.TeeReader(content, hash)) + if err != nil { + res.Err = err + return res + } + + localChecksum := hash.Sum(nil) + h["ETag"] = fmt.Sprintf("%x", localChecksum) + ropts := gophercloud.RequestOpts{ - RawBody: content, + RawBody: strings.NewReader(contentBuffer.String()), MoreHeaders: h, } resp, err := c.Request("PUT", url, ropts) - res.Header = resp.Header - res.Err = err + if err != nil { + res.Err = err + return res + } + if resp != nil { + res.Header = resp.Header + if resp.Header.Get("ETag") == fmt.Sprintf("%x", localChecksum) { + res.Err = err + return res + } + res.Err = fmt.Errorf("Local checksum does not match API ETag header") + } + return res } @@ -270,7 +297,9 @@ func Copy(c *gophercloud.ServiceClient, containerName, objectName string, opts C MoreHeaders: h, OkCodes: []int{201}, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } @@ -310,7 +339,9 @@ func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts } resp, err := c.Delete(url, nil) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } @@ -354,7 +385,9 @@ func Get(c *gophercloud.ServiceClient, containerName, objectName string, opts Ge resp, err := c.Request("HEAD", url, gophercloud.RequestOpts{ OkCodes: []int{200, 204}, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } @@ -410,7 +443,9 @@ func Update(c *gophercloud.ServiceClient, containerName, objectName string, opts resp, err := c.Request("POST", url, gophercloud.RequestOpts{ MoreHeaders: h, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests_test.go index 6be3534205ff..f7d6822913ef 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects/requests_test.go @@ -2,7 +2,10 @@ package objects import ( "bytes" + "fmt" "io" + "net/http" + "strings" "testing" "github.com/rackspace/gophercloud/pagination" @@ -83,24 +86,44 @@ func TestListObjectNames(t *testing.T) { func TestCreateObject(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - HandleCreateTextObjectSuccessfully(t) - content := bytes.NewBufferString("Did gyre and gimble in the wabe") + content := "Did gyre and gimble in the wabe" + + HandleCreateTextObjectSuccessfully(t, content) + options := &CreateOpts{ContentType: "text/plain"} - res := Create(fake.ServiceClient(), "testContainer", "testObject", content, options) + res := Create(fake.ServiceClient(), "testContainer", "testObject", strings.NewReader(content), options) th.AssertNoErr(t, res.Err) } func TestCreateObjectWithoutContentType(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - HandleCreateTypelessObjectSuccessfully(t) - content := bytes.NewBufferString("The sky was the color of television, tuned to a dead channel.") - res := Create(fake.ServiceClient(), "testContainer", "testObject", content, &CreateOpts{}) + content := "The sky was the color of television, tuned to a dead channel." + + HandleCreateTypelessObjectSuccessfully(t, content) + + res := Create(fake.ServiceClient(), "testContainer", "testObject", strings.NewReader(content), &CreateOpts{}) th.AssertNoErr(t, res.Err) } +func TestErrorIsRaisedForChecksumMismatch(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("ETag", "acbd18db4cc2f85cedef654fccc4a4d8") + w.WriteHeader(http.StatusCreated) + }) + + content := strings.NewReader("The sky was the color of television, tuned to a dead channel.") + res := Create(fake.ServiceClient(), "testContainer", "testObject", content, &CreateOpts{}) + + err := fmt.Errorf("Local checksum does not match API ETag header") + th.AssertDeepEquals(t, err, res.Err) +} + func TestCopyObject(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackevents/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackevents/fixtures.go index 016ae003b32f..235787a51457 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackevents/fixtures.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackevents/fixtures.go @@ -67,7 +67,7 @@ const FindOutput = ` "events": [ { "resource_name": "hello_world", - "event_time": "2015-02-05T21:33:11Z", + "event_time": "2015-02-05T21:33:11", "links": [ { "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a", @@ -90,7 +90,7 @@ const FindOutput = ` }, { "resource_name": "hello_world", - "event_time": "2015-02-05T21:33:27Z", + "event_time": "2015-02-05T21:33:27", "links": [ { "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18", @@ -184,7 +184,7 @@ const ListOutput = ` "events": [ { "resource_name": "hello_world", - "event_time": "2015-02-05T21:33:11Z", + "event_time": "2015-02-05T21:33:11", "links": [ { "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a", @@ -207,7 +207,7 @@ const ListOutput = ` }, { "resource_name": "hello_world", - "event_time": "2015-02-05T21:33:27Z", + "event_time": "2015-02-05T21:33:27", "links": [ { "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18", @@ -309,7 +309,7 @@ const ListResourceEventsOutput = ` "events": [ { "resource_name": "hello_world", - "event_time": "2015-02-05T21:33:11Z", + "event_time": "2015-02-05T21:33:11", "links": [ { "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a", @@ -332,7 +332,7 @@ const ListResourceEventsOutput = ` }, { "resource_name": "hello_world", - "event_time": "2015-02-05T21:33:27Z", + "event_time": "2015-02-05T21:33:27", "links": [ { "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18", @@ -408,7 +408,7 @@ const GetOutput = ` { "event":{ "resource_name": "hello_world", - "event_time": "2015-02-05T21:33:27Z", + "event_time": "2015-02-05T21:33:27", "links": [ { "href": "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18", diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackevents/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackevents/results.go index 3c8f1da49106..cf9e240982df 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackevents/results.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackevents/results.go @@ -57,7 +57,7 @@ func (r FindResult) Extract() ([]Event, error) { for i, eventRaw := range events { event := eventRaw.(map[string]interface{}) if date, ok := event["event_time"]; ok && date != nil { - t, err := time.Parse(time.RFC3339, date.(string)) + t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string)) if err != nil { return nil, err } @@ -121,7 +121,7 @@ func ExtractEvents(page pagination.Page) ([]Event, error) { for i, eventRaw := range events { event := eventRaw.(map[string]interface{}) if date, ok := event["event_time"]; ok && date != nil { - t, err := time.Parse(time.RFC3339, date.(string)) + t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string)) if err != nil { return nil, err } @@ -161,7 +161,7 @@ func (r GetResult) Extract() (*Event, error) { event := r.Body.(map[string]interface{})["event"].(map[string]interface{}) if date, ok := event["event_time"]; ok && date != nil { - t, err := time.Parse(time.RFC3339, date.(string)) + t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string)) if err != nil { return nil, err } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/fixtures.go index 0b930f4841a2..c3c3d3fbc962 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/fixtures.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/fixtures.go @@ -53,7 +53,7 @@ const FindOutput = ` ], "logical_resource_id": "hello_world", "resource_status_reason": "state changed", - "updated_time": "2015-02-05T21:33:11Z", + "updated_time": "2015-02-05T21:33:11", "required_by": [], "resource_status": "CREATE_IN_PROGRESS", "physical_resource_id": "49181cd6-169a-4130-9455-31185bbfc5bf", @@ -117,7 +117,7 @@ const ListOutput = `{ ], "logical_resource_id": "hello_world", "resource_status_reason": "state changed", - "updated_time": "2015-02-05T21:33:11Z", + "updated_time": "2015-02-05T21:33:11", "required_by": [], "resource_status": "CREATE_IN_PROGRESS", "physical_resource_id": "49181cd6-169a-4130-9455-31185bbfc5bf", @@ -188,7 +188,7 @@ const GetOutput = ` ], "logical_resource_id": "wordpress_instance", "resource_status": "CREATE_COMPLETE", - "updated_time": "2014-12-10T18:34:35Z", + "updated_time": "2014-12-10T18:34:35", "required_by": [], "resource_status_reason": "state changed", "physical_resource_id": "00e3a2fe-c65d-403c-9483-4db9930dd194", diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/requests.go index ee9c3c250cc1..fcb8d8a2f82e 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/requests.go @@ -25,12 +25,6 @@ type ListOptsBuilder interface { // ListOpts allows the filtering and sorting of paginated collections through // the API. Marker and Limit are used for pagination. type ListOpts struct { - // The stack resource ID with which to start the listing. - Marker string `q:"marker"` - - // Integer value for the limit of values to return. - Limit int `q:"limit"` - // Include resources from nest stacks up to Depth levels of recursion. Depth int `q:"nested_depth"` } @@ -57,9 +51,7 @@ func List(client *gophercloud.ServiceClient, stackName, stackID string, opts Lis } createPageFn := func(r pagination.PageResult) pagination.Page { - p := ResourcePage{pagination.MarkerPageBase{PageResult: r}} - p.MarkerPageBase.Owner = p - return p + return ResourcePage{pagination.SinglePageBase(r)} } return pagination.NewPager(client, url, createPageFn) diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/results.go index 69f21daef39a..df79d582a968 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/results.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stackresources/results.go @@ -48,7 +48,7 @@ func (r FindResult) Extract() ([]Resource, error) { for i, resourceRaw := range resources { resource := resourceRaw.(map[string]interface{}) if date, ok := resource["updated_time"]; ok && date != nil { - t, err := time.Parse(time.RFC3339, date.(string)) + t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string)) if err != nil { return nil, err } @@ -63,7 +63,7 @@ func (r FindResult) Extract() ([]Resource, error) { // As OpenStack extensions may freely alter the response bodies of structures returned to the client, you may only safely access the // data provided through the ExtractResources call. type ResourcePage struct { - pagination.MarkerPageBase + pagination.SinglePageBase } // IsEmpty returns true if a page contains no Server results. @@ -109,7 +109,7 @@ func ExtractResources(page pagination.Page) ([]Resource, error) { for i, resourceRaw := range resources { resource := resourceRaw.(map[string]interface{}) if date, ok := resource["updated_time"]; ok && date != nil { - t, err := time.Parse(time.RFC3339, date.(string)) + t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string)) if err != nil { return nil, err } @@ -143,7 +143,7 @@ func (r GetResult) Extract() (*Resource, error) { resource := r.Body.(map[string]interface{})["resource"].(map[string]interface{}) if date, ok := resource["updated_time"]; ok && date != nil { - t, err := time.Parse(time.RFC3339, date.(string)) + t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string)) if err != nil { return nil, err } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stacks/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stacks/fixtures.go index 6d3e9597a21b..3a621dab6c10 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stacks/fixtures.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stacks/fixtures.go @@ -95,7 +95,7 @@ const FullListOutput = ` ], "stack_status_reason": "Stack CREATE completed successfully", "stack_name": "postman_stack", - "creation_time": "2015-02-03T20:07:39Z", + "creation_time": "2015-02-03T20:07:39", "updated_time": null, "stack_status": "CREATE_COMPLETE", "id": "16ef0584-4458-41eb-87c8-0dc8d5f66c87" @@ -110,8 +110,8 @@ const FullListOutput = ` ], "stack_status_reason": "Stack successfully updated", "stack_name": "gophercloud-test-stack-2", - "creation_time": "2014-12-11T17:39:16Z", - "updated_time": "2014-12-11T17:40:37Z", + "creation_time": "2014-12-11T17:39:16", + "updated_time": "2014-12-11T17:40:37", "stack_status": "UPDATE_COMPLETE", "id": "db6977b2-27aa-4775-9ae7-6213212d4ada" } @@ -181,7 +181,7 @@ const GetOutput = ` "stack_status_reason": "Stack CREATE completed successfully", "stack_name": "postman_stack", "outputs": [], - "creation_time": "2015-02-03T20:07:39Z", + "creation_time": "2015-02-03T20:07:39", "links": [ { "href": "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87", diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stacks/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stacks/results.go index 04d3f8ea964a..dca06e4e0d06 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stacks/results.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/openstack/orchestration/v1/stacks/results.go @@ -100,7 +100,7 @@ func ExtractStacks(page pagination.Page) ([]ListedStack, error) { thisStack := (rawStacks[i]).(map[string]interface{}) if t, ok := thisStack["creation_time"].(string); ok && t != "" { - creationTime, err := time.Parse(time.RFC3339, t) + creationTime, err := time.Parse(gophercloud.STACK_TIME_FMT, t) if err != nil { return res.Stacks, err } @@ -108,7 +108,7 @@ func ExtractStacks(page pagination.Page) ([]ListedStack, error) { } if t, ok := thisStack["updated_time"].(string); ok && t != "" { - updatedTime, err := time.Parse(time.RFC3339, t) + updatedTime, err := time.Parse(gophercloud.STACK_TIME_FMT, t) if err != nil { return res.Stacks, err } @@ -170,7 +170,7 @@ func (r GetResult) Extract() (*RetrievedStack, error) { b := r.Body.(map[string]interface{})["stack"].(map[string]interface{}) if date, ok := b["creation_time"]; ok && date != nil { - t, err := time.Parse(time.RFC3339, date.(string)) + t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string)) if err != nil { return nil, err } @@ -178,7 +178,7 @@ func (r GetResult) Extract() (*RetrievedStack, error) { } if date, ok := b["updated_time"]; ok && date != nil { - t, err := time.Parse(time.RFC3339, date.(string)) + t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string)) if err != nil { return nil, err } @@ -249,7 +249,7 @@ func (r PreviewResult) Extract() (*PreviewedStack, error) { b := r.Body.(map[string]interface{})["stack"].(map[string]interface{}) if date, ok := b["creation_time"]; ok && date != nil { - t, err := time.Parse(time.RFC3339, date.(string)) + t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string)) if err != nil { return nil, err } @@ -257,7 +257,7 @@ func (r PreviewResult) Extract() (*PreviewedStack, error) { } if date, ok := b["updated_time"]; ok && date != nil { - t, err := time.Parse(time.RFC3339, date.(string)) + t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string)) if err != nil { return nil, err } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/http.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/http.go index cabcccd79f39..1b3fe94ab9f2 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/http.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/http.go @@ -36,13 +36,19 @@ func PageResultFrom(resp *http.Response) (PageResult, error) { parsedBody = rawBody } + return PageResultFromParsed(resp, parsedBody), err +} + +// PageResultFromParsed constructs a PageResult from an HTTP response that has already had its +// body parsed as JSON (and closed). +func PageResultFromParsed(resp *http.Response, body interface{}) PageResult { return PageResult{ Result: gophercloud.Result{ - Body: parsedBody, + Body: body, Header: resp.Header, }, URL: *resp.Request.URL, - }, err + } } // Request performs an HTTP request and extracts the http.Response from the result. diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pager.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pager.go index ea47c695dc3d..a7593ac883dd 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pager.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/pagination/pager.go @@ -174,8 +174,10 @@ func (p Pager) AllPages() (Page, error) { if err != nil { return nil, err } - // Remove the trailing comma. - pagesSlice = pagesSlice[:len(pagesSlice)-1] + if len(pagesSlice) > 0 { + // Remove the trailing comma. + pagesSlice = pagesSlice[:len(pagesSlice)-1] + } var b []byte // Combine the slice of slices in to a single slice. for _, slice := range pagesSlice { diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/provider_client.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/provider_client.go index 0dff2cfc3033..d920913e76c8 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/provider_client.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/provider_client.go @@ -85,9 +85,9 @@ type RequestOpts struct { // content type of the request will default to "application/json" unless overridden by MoreHeaders. // It's an error to specify both a JSONBody and a RawBody. JSONBody interface{} - // RawBody contains an io.Reader that will be consumed by the request directly. No content-type + // RawBody contains an io.ReadSeeker that will be consumed by the request directly. No content-type // will be set unless one is provided explicitly by MoreHeaders. - RawBody io.Reader + RawBody io.ReadSeeker // JSONResponse, if provided, will be populated with the contents of the response body parsed as // JSON. @@ -124,11 +124,11 @@ var applicationJSON = "application/json" // Request performs an HTTP request using the ProviderClient's current HTTPClient. An authentication // header will automatically be provided. func (client *ProviderClient) Request(method, url string, options RequestOpts) (*http.Response, error) { - var body io.Reader + var body io.ReadSeeker var contentType *string // Derive the content body by either encoding an arbitrary object as JSON, or by taking a provided - // io.Reader as-is. Default the content-type to application/json. + // io.ReadSeeker as-is. Default the content-type to application/json. if options.JSONBody != nil { if options.RawBody != nil { panic("Please provide only one of JSONBody or RawBody to gophercloud.Request().") @@ -189,6 +189,9 @@ func (client *ProviderClient) Request(method, url string, options RequestOpts) ( if err != nil { return nil, fmt.Errorf("Error trying to re-authenticate: %s", err) } + if options.RawBody != nil { + options.RawBody.Seek(0, 0) + } resp, err = client.Request(method, url, options) if err != nil { return nil, fmt.Errorf("Successfully re-authenticated, but got error executing request: %s", err) @@ -224,7 +227,9 @@ func (client *ProviderClient) Request(method, url string, options RequestOpts) ( // Parse the response body as JSON, if requested to do so. if options.JSONResponse != nil { defer resp.Body.Close() - json.NewDecoder(resp.Body).Decode(options.JSONResponse) + if err := json.NewDecoder(resp.Body).Decode(options.JSONResponse); err != nil { + return nil, err + } } return resp, nil @@ -260,7 +265,7 @@ func (client *ProviderClient) Post(url string, JSONBody interface{}, JSONRespons opts = &RequestOpts{} } - if v, ok := (JSONBody).(io.Reader); ok { + if v, ok := (JSONBody).(io.ReadSeeker); ok { opts.RawBody = v } else if JSONBody != nil { opts.JSONBody = JSONBody @@ -278,7 +283,7 @@ func (client *ProviderClient) Put(url string, JSONBody interface{}, JSONResponse opts = &RequestOpts{} } - if v, ok := (JSONBody).(io.Reader); ok { + if v, ok := (JSONBody).(io.ReadSeeker); ok { opts.RawBody = v } else if JSONBody != nil { opts.JSONBody = JSONBody diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/delegate_test.go index b44564cc1f6e..b6831f211489 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/delegate_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/blockstorage/v1/volumes/delegate_test.go @@ -3,7 +3,8 @@ package volumes import ( "testing" - os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes" + "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes" + os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes/testing" "github.com/rackspace/gophercloud/pagination" th "github.com/rackspace/gophercloud/testhelper" fake "github.com/rackspace/gophercloud/testhelper/client" @@ -64,7 +65,7 @@ func TestCreate(t *testing.T) { os.MockCreateResponse(t) - n, err := Create(fake.ServiceClient(), CreateOpts{os.CreateOpts{Size: 75}}).Extract() + n, err := Create(fake.ServiceClient(), CreateOpts{volumes.CreateOpts{Size: 75}}).Extract() th.AssertNoErr(t, err) th.AssertEquals(t, n.Size, 4) @@ -72,12 +73,12 @@ func TestCreate(t *testing.T) { } func TestSizeRange(t *testing.T) { - _, err := Create(fake.ServiceClient(), CreateOpts{os.CreateOpts{Size: 1}}).Extract() + _, err := Create(fake.ServiceClient(), CreateOpts{volumes.CreateOpts{Size: 1}}).Extract() if err == nil { t.Fatalf("Expected error, got none") } - _, err = Create(fake.ServiceClient(), CreateOpts{os.CreateOpts{Size: 2000}}).Extract() + _, err = Create(fake.ServiceClient(), CreateOpts{volumes.CreateOpts{Size: 2000}}).Extract() if err == nil { t.Fatalf("Expected error, got none") } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume/delegate_test.go index 0b5352751b4c..571a1bed2b79 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume/delegate_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/bootfromvolume/delegate_test.go @@ -33,6 +33,8 @@ func TestCreateOpts(t *testing.T) { "name": "createdserver", "imageRef": "asdfasdfasdf", "flavorRef": "performance1-1", + "flavorName": "", + "imageName": "", "block_device_mapping_v2":[ { "uuid":"123456", diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/delegate.go index 6bfc20c5644f..081ea478cd81 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/delegate.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/delegate.go @@ -36,11 +36,8 @@ func ListDetail(client *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagi } // Get returns details about a single flavor, identity by ID. -func Get(client *gophercloud.ServiceClient, id string) os.GetResult { - return os.Get(client, id) -} - -// ExtractFlavors interprets a page of List results as Flavors. -func ExtractFlavors(page pagination.Page) ([]os.Flavor, error) { - return os.ExtractFlavors(page) +func Get(client *gophercloud.ServiceClient, id string) GetResult { + var res GetResult + _, res.Err = client.Get(getURL(client, id), &res.Body, nil) + return res } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/fixtures.go index 894f916f6759..957dccfd7dd2 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/fixtures.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/fixtures.go @@ -2,10 +2,6 @@ package flavors -import ( - os "github.com/rackspace/gophercloud/openstack/compute/v2/flavors" -) - // ListOutput is a sample response of a flavor List request. const ListOutput = ` { @@ -103,7 +99,7 @@ const GetOutput = ` // Performance1Flavor is the expected result of parsing GetOutput, or the first element of // ListOutput. -var Performance1Flavor = os.Flavor{ +var Performance1Flavor = Flavor{ ID: "performance1-1", Disk: 20, RAM: 1024, @@ -111,10 +107,16 @@ var Performance1Flavor = os.Flavor{ RxTxFactor: 200.0, Swap: 0, VCPUs: 1, + ExtraSpecs: ExtraSpecs{ + NumDataDisks: 0, + Class: "performance1", + DiskIOIndex: 0, + PolicyClass: "performance_flavor", + }, } // Performance2Flavor is the second result expected from parsing ListOutput. -var Performance2Flavor = os.Flavor{ +var Performance2Flavor = Flavor{ ID: "performance1-2", Disk: 40, RAM: 2048, @@ -122,8 +124,14 @@ var Performance2Flavor = os.Flavor{ RxTxFactor: 400.0, Swap: 0, VCPUs: 2, + ExtraSpecs: ExtraSpecs{ + NumDataDisks: 0, + Class: "performance1", + DiskIOIndex: 0, + PolicyClass: "performance_flavor", + }, } // ExpectedFlavorSlice is the slice of Flavor structs that are expected to be parsed from // ListOutput. -var ExpectedFlavorSlice = []os.Flavor{Performance1Flavor, Performance2Flavor} +var ExpectedFlavorSlice = []Flavor{Performance1Flavor, Performance2Flavor} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/results.go new file mode 100644 index 000000000000..af444a766d34 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/results.go @@ -0,0 +1,104 @@ +package flavors + +import ( + "reflect" + + "github.com/rackspace/gophercloud" + "github.com/mitchellh/mapstructure" + os "github.com/rackspace/gophercloud/openstack/compute/v2/flavors" + "github.com/rackspace/gophercloud/pagination" +) + +// ExtraSpecs provide additional information about the flavor. +type ExtraSpecs struct { + // The number of data disks + NumDataDisks int `mapstructure:"number_of_data_disks"` + // The flavor class + Class string `mapstructure:"class"` + // Relative measure of disk I/O performance from 0-99, where higher is faster + DiskIOIndex int `mapstructure:"disk_io_index"` + PolicyClass string `mapstructure:"policy_class"` +} + +// Flavor records represent (virtual) hardware configurations for server resources in a region. +type Flavor struct { + // The Id field contains the flavor's unique identifier. + // For example, this identifier will be useful when specifying which hardware configuration to use for a new server instance. + ID string `mapstructure:"id"` + + // The Disk and RA< fields provide a measure of storage space offered by the flavor, in GB and MB, respectively. + Disk int `mapstructure:"disk"` + RAM int `mapstructure:"ram"` + + // The Name field provides a human-readable moniker for the flavor. + Name string `mapstructure:"name"` + + RxTxFactor float64 `mapstructure:"rxtx_factor"` + + // Swap indicates how much space is reserved for swap. + // If not provided, this field will be set to 0. + Swap int `mapstructure:"swap"` + + // VCPUs indicates how many (virtual) CPUs are available for this flavor. + VCPUs int `mapstructure:"vcpus"` + + // ExtraSpecs provides extra information about the flavor + ExtraSpecs ExtraSpecs `mapstructure:"OS-FLV-WITH-EXT-SPECS:extra_specs"` +} + +// GetResult temporarily holds the response from a Get call. +type GetResult struct { + gophercloud.Result +} + +// Extract provides access to the individual Flavor returned by the Get function. +func (gr GetResult) Extract() (*Flavor, error) { + if gr.Err != nil { + return nil, gr.Err + } + + var result struct { + Flavor Flavor `mapstructure:"flavor"` + } + + cfg := &mapstructure.DecoderConfig{ + DecodeHook: defaulter, + Result: &result, + } + decoder, err := mapstructure.NewDecoder(cfg) + if err != nil { + return nil, err + } + err = decoder.Decode(gr.Body) + return &result.Flavor, err +} + +func defaulter(from, to reflect.Kind, v interface{}) (interface{}, error) { + if (from == reflect.String) && (to == reflect.Int) { + return 0, nil + } + return v, nil +} + +// ExtractFlavors provides access to the list of flavors in a page acquired from the List operation. +func ExtractFlavors(page pagination.Page) ([]Flavor, error) { + casted := page.(os.FlavorPage).Body + var container struct { + Flavors []Flavor `mapstructure:"flavors"` + } + + cfg := &mapstructure.DecoderConfig{ + DecodeHook: defaulter, + Result: &container, + } + decoder, err := mapstructure.NewDecoder(cfg) + if err != nil { + return container.Flavors, err + } + err = decoder.Decode(casted) + if err != nil { + return container.Flavors, err + } + + return container.Flavors, nil +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/urls.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/urls.go new file mode 100644 index 000000000000..f4e2c3dac421 --- /dev/null +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/flavors/urls.go @@ -0,0 +1,9 @@ +package flavors + +import ( + "github.com/rackspace/gophercloud" +) + +func getURL(client *gophercloud.ServiceClient, id string) string { + return client.ServiceURL("flavors", id) +} diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests.go index 809183ec7c03..d4472a08088f 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests.go @@ -12,13 +12,24 @@ type CreateOpts struct { // Name [required] is the name to assign to the newly launched server. Name string - // ImageRef [required] is the ID or full URL to the image that contains the server's OS and initial state. - // Optional if using the boot-from-volume extension. + // ImageRef [optional; required if ImageName is not provided] is the ID or full + // URL to the image that contains the server's OS and initial state. + // Also optional if using the boot-from-volume extension. ImageRef string - // FlavorRef [required] is the ID or full URL to the flavor that describes the server's specs. + // ImageName [optional; required if ImageRef is not provided] is the name of the + // image that contains the server's OS and initial state. + // Also optional if using the boot-from-volume extension. + ImageName string + + // FlavorRef [optional; required if FlavorName is not provided] is the ID or + // full URL to the flavor that describes the server's specs. FlavorRef string + // FlavorName [optional; required if FlavorRef is not provided] is the name of + // the flavor that describes the server's specs. + FlavorName string + // SecurityGroups [optional] lists the names of the security groups to which this server should belong. SecurityGroups []string @@ -36,9 +47,9 @@ type CreateOpts struct { // Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server. Metadata map[string]string - // Personality [optional] includes the path and contents of a file to inject into the server at launch. - // The maximum size of the file is 255 bytes (decoded). - Personality []byte + // Personality [optional] includes files to inject into the server at launch. + // Create will base64-encode file contents for you. + Personality os.Personality // ConfigDrive [optional] enables metadata injection through a configuration drive. ConfigDrive bool @@ -58,7 +69,7 @@ type CreateOpts struct { DiskConfig diskconfig.DiskConfig // BlockDevice [optional] will create the server from a volume, which is created from an image, - // a snapshot, or an another volume. + // a snapshot, or another volume. BlockDevice []bootfromvolume.BlockDevice } @@ -68,7 +79,9 @@ func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) { base := os.CreateOpts{ Name: opts.Name, ImageRef: opts.ImageRef, + ImageName: opts.ImageName, FlavorRef: opts.FlavorRef, + FlavorName: opts.FlavorName, SecurityGroups: opts.SecurityGroups, UserData: opts.UserData, AvailabilityZone: opts.AvailabilityZone, @@ -104,7 +117,9 @@ func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) { // key_name doesn't actually come from the extension (or at least isn't documented there) so // we need to add it manually. serverMap := res["server"].(map[string]interface{}) - serverMap["key_name"] = opts.KeyPair + if opts.KeyPair != "" { + serverMap["key_name"] = opts.KeyPair + } return res, nil } @@ -130,9 +145,9 @@ type RebuildOpts struct { // Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the server. Metadata map[string]string - // Personality [optional] includes the path and contents of a file to inject into the server at launch. - // The maximum size of the file is 255 bytes (decoded). - Personality []byte + // Personality [optional] includes files to inject into the server at launch. + // Rebuild will base64-encode file contents for you. + Personality os.Personality // Rackspace-specific stuff begins here. diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests_test.go index 3c0f806936f0..828b5dc491e0 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/servers/requests_test.go @@ -22,6 +22,8 @@ func TestCreateOpts(t *testing.T) { "name": "createdserver", "imageRef": "image-id", "flavorRef": "flavor-id", + "flavorName": "", + "imageName": "", "key_name": "mykey", "OS-DCF:diskConfig": "MANUAL" } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/volumeattach/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/volumeattach/delegate_test.go index e26416cba0de..f7ef45e621a8 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/volumeattach/delegate_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/compute/v2/volumeattach/delegate_test.go @@ -3,24 +3,53 @@ package volumeattach import ( "testing" - os "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach" + "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach" + fixtures "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach/testing" "github.com/rackspace/gophercloud/pagination" th "github.com/rackspace/gophercloud/testhelper" "github.com/rackspace/gophercloud/testhelper/client" ) +// FirstVolumeAttachment is the first result in ListOutput. +var FirstVolumeAttachment = volumeattach.VolumeAttachment{ + Device: "/dev/vdd", + ID: "a26887c6-c47b-4654-abb5-dfadf7d3f803", + ServerID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", + VolumeID: "a26887c6-c47b-4654-abb5-dfadf7d3f803", +} + +// SecondVolumeAttachment is the first result in ListOutput. +var SecondVolumeAttachment = volumeattach.VolumeAttachment{ + Device: "/dev/vdc", + ID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", + ServerID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", + VolumeID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", +} + +// ExpectedVolumeAttachmentSlide is the slice of results that should be parsed +// from ListOutput, in the expected order. +var ExpectedVolumeAttachmentSlice = []volumeattach.VolumeAttachment{FirstVolumeAttachment, SecondVolumeAttachment} + +//CreatedVolumeAttachment is the parsed result from CreatedOutput. +var CreatedVolumeAttachment = volumeattach.VolumeAttachment{ + Device: "/dev/vdc", + ID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", + ServerID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0", + VolumeID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", +} + func TestList(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - os.HandleListSuccessfully(t) + fixtures.HandleListSuccessfully(t) serverId := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" count := 0 err := List(client.ServiceClient(), serverId).EachPage(func(page pagination.Page) (bool, error) { count++ - actual, err := os.ExtractVolumeAttachments(page) + actual, err := volumeattach.ExtractVolumeAttachments(page) th.AssertNoErr(t, err) - th.CheckDeepEquals(t, os.ExpectedVolumeAttachmentSlice, actual) + th.CheckDeepEquals(t, ExpectedVolumeAttachmentSlice, actual) return true, nil }) @@ -31,33 +60,33 @@ func TestList(t *testing.T) { func TestCreate(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - os.HandleCreateSuccessfully(t) + fixtures.HandleCreateSuccessfully(t) serverId := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" - actual, err := Create(client.ServiceClient(), serverId, os.CreateOpts{ + actual, err := Create(client.ServiceClient(), serverId, volumeattach.CreateOpts{ Device: "/dev/vdc", VolumeID: "a26887c6-c47b-4654-abb5-dfadf7d3f804", }).Extract() th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &os.CreatedVolumeAttachment, actual) + th.CheckDeepEquals(t, &CreatedVolumeAttachment, actual) } func TestGet(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - os.HandleGetSuccessfully(t) + fixtures.HandleGetSuccessfully(t) aId := "a26887c6-c47b-4654-abb5-dfadf7d3f804" serverId := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" actual, err := Get(client.ServiceClient(), serverId, aId).Extract() th.AssertNoErr(t, err) - th.CheckDeepEquals(t, &os.SecondVolumeAttachment, actual) + th.CheckDeepEquals(t, &SecondVolumeAttachment, actual) } func TestDelete(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - os.HandleDeleteSuccessfully(t) + fixtures.HandleDeleteSuccessfully(t) aId := "a26887c6-c47b-4654-abb5-dfadf7d3f804" serverId := "4d8c3732-a248-40ed-bebc-539a6ffd25c0" diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/fixtures.go index 7c85945cafe1..8899fc5e975c 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/fixtures.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/fixtures.go @@ -107,6 +107,42 @@ func mockCreateResponse(t *testing.T, lbID int) { }) } +func mockCreateErrResponse(t *testing.T, lbID int) { + th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + th.TestJSONRequest(t, r, ` +{ + "nodes": [ + { + "address": "10.2.2.3", + "port": 80, + "condition": "ENABLED", + "type": "PRIMARY" + }, + { + "address": "10.2.2.4", + "port": 81, + "condition": "ENABLED", + "type": "SECONDARY" + } + ] +} + `) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(422) // Unprocessable Entity + + fmt.Fprintf(w, ` +{ + "code": 422, + "message": "Load Balancer '%d' has a status of 'PENDING_UPDATE' and is considered immutable." +} + `, lbID) + }) +} + func mockBatchDeleteResponse(t *testing.T, lbID int, ids []int) { th.Mux.HandleFunc(_rootURL(lbID), func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests.go index 02af86b5c1e2..dc2d46c8913a 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests.go @@ -119,12 +119,7 @@ func Create(client *gophercloud.ServiceClient, loadBalancerID int, opts CreateOp return res } - pr, err := pagination.PageResultFrom(resp) - if err != nil { - res.Err = err - return res - } - + pr := pagination.PageResultFromParsed(resp, res.Body) return CreateResult{pagination.SinglePageBase(pr)} } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests_test.go index 003d347c073b..a964af8f90d4 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/requests_test.go @@ -108,6 +108,38 @@ func TestCreate(t *testing.T) { th.CheckDeepEquals(t, expected, actual) } +func TestCreateErr(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + mockCreateErrResponse(t, lbID) + + opts := CreateOpts{ + CreateOpt{ + Address: "10.2.2.3", + Port: 80, + Condition: ENABLED, + Type: PRIMARY, + }, + CreateOpt{ + Address: "10.2.2.4", + Port: 81, + Condition: ENABLED, + Type: SECONDARY, + }, + } + + page := Create(client.ServiceClient(), lbID, opts) + + actual, err := page.ExtractNodes() + if err == nil { + t.Fatal("Did not receive expected error from ExtractNodes") + } + if actual != nil { + t.Fatalf("Received non-nil result from failed ExtractNodes: %#v", actual) + } +} + func TestBulkDelete(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/results.go index 916485f2fcba..57835dc4b5d2 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/results.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/nodes/results.go @@ -126,6 +126,9 @@ type CreateResult struct { // ExtractNodes extracts a slice of Node structs from a CreateResult. func (res CreateResult) ExtractNodes() ([]Node, error) { + if res.Err != nil { + return nil, res.Err + } return commonExtractNodes(res.Body) } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/fixtures.go index 9596819d16d5..077ef0470191 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/fixtures.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/sessions/fixtures.go @@ -46,6 +46,7 @@ func mockEnableResponse(t *testing.T, lbID int) { `) w.WriteHeader(http.StatusAccepted) + fmt.Fprintf(w, `{}`) }) } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/fixtures.go index 1d401001250b..5a52962d49ab 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/fixtures.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/ssl/fixtures.go @@ -63,6 +63,7 @@ func mockUpdateResponse(t *testing.T, lbID int) { `) w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, `{}`) }) } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/fixtures.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/fixtures.go index 40223f60a672..f3e49fa6884e 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/fixtures.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/lb/v1/throttle/fixtures.go @@ -49,6 +49,7 @@ func mockCreateResponse(t *testing.T, lbID int) { `) w.WriteHeader(http.StatusAccepted) + fmt.Fprintf(w, `{}`) }) } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/networks/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/networks/delegate_test.go index f51c732d4367..0b3a6b15eb4f 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/networks/delegate_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/networking/v2/networks/delegate_test.go @@ -203,8 +203,17 @@ func TestCreateWithOptionalFields(t *testing.T) { } } `) - w.WriteHeader(http.StatusCreated) + fmt.Fprintf(w, ` +{ + "network": { + "name": "sample_network", + "admin_state_up": true, + "shared": true, + "tenant_id": "12345" + } +} + `) }) iTrue := true diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/requests.go index 898b73b0bd84..0aeec155b778 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/bulk/requests.go @@ -43,7 +43,9 @@ func Delete(c *gophercloud.ServiceClient, opts DeleteOptsBuilder) DeleteResult { JSONBody: reqBody, JSONResponse: &res.Body, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/requests.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/requests.go index 8e4abbe436c2..6acebb0aad23 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/requests.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/cdncontainers/requests.go @@ -53,7 +53,9 @@ func Enable(c *gophercloud.ServiceClient, containerName string, opts EnableOptsB MoreHeaders: h, OkCodes: []int{201, 202, 204}, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } @@ -66,7 +68,9 @@ func Get(c *gophercloud.ServiceClient, containerName string) GetResult { resp, err := c.Request("HEAD", getURL(c, containerName), gophercloud.RequestOpts{ OkCodes: []int{200, 204}, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } @@ -149,7 +153,9 @@ func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsB MoreHeaders: h, OkCodes: []int{202, 204}, }) - res.Header = resp.Header + if resp != nil { + res.Header = resp.Header + } res.Err = err return res } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate.go index 028d66a0ab77..94c820ba7bdd 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate.go @@ -33,7 +33,7 @@ func Download(c *gophercloud.ServiceClient, containerName, objectName string, op } // Create is a function that creates a new object or replaces an existing object. -func Create(c *gophercloud.ServiceClient, containerName, objectName string, content io.Reader, opts os.CreateOptsBuilder) os.CreateResult { +func Create(c *gophercloud.ServiceClient, containerName, objectName string, content io.ReadSeeker, opts os.CreateOptsBuilder) os.CreateResult { return os.Create(c, containerName, objectName, content, opts) } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate_test.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate_test.go index 8ab8029c37b5..21cd4179a5d2 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate_test.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/rackspace/objectstorage/v1/objects/delegate_test.go @@ -1,7 +1,7 @@ package objects import ( - "bytes" + "strings" "testing" os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects" @@ -66,21 +66,23 @@ func TestListObjectNames(t *testing.T) { func TestCreateObject(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - os.HandleCreateTextObjectSuccessfully(t) + + content := "Did gyre and gimble in the wabe" + os.HandleCreateTextObjectSuccessfully(t, content) - content := bytes.NewBufferString("Did gyre and gimble in the wabe") options := &os.CreateOpts{ContentType: "text/plain"} - res := Create(fake.ServiceClient(), "testContainer", "testObject", content, options) + res := Create(fake.ServiceClient(), "testContainer", "testObject", strings.NewReader(content), options) th.AssertNoErr(t, res.Err) } func TestCreateObjectWithoutContentType(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() - os.HandleCreateTypelessObjectSuccessfully(t) - content := bytes.NewBufferString("The sky was the color of television, tuned to a dead channel.") - res := Create(fake.ServiceClient(), "testContainer", "testObject", content, &os.CreateOpts{}) + content := "The sky was the color of television, tuned to a dead channel." + os.HandleCreateTypelessObjectSuccessfully(t, content) + + res := Create(fake.ServiceClient(), "testContainer", "testObject", strings.NewReader(content), &os.CreateOpts{}) th.AssertNoErr(t, res.Err) } diff --git a/Godeps/_workspace/src/github.com/rackspace/gophercloud/results.go b/Godeps/_workspace/src/github.com/rackspace/gophercloud/results.go index 7c86ce46230c..27fd1b60fa21 100644 --- a/Godeps/_workspace/src/github.com/rackspace/gophercloud/results.go +++ b/Godeps/_workspace/src/github.com/rackspace/gophercloud/results.go @@ -113,6 +113,9 @@ func DecodeHeader(from, to interface{}) error { // RFC3339Milli describes a common time format used by some API responses. const RFC3339Milli = "2006-01-02T15:04:05.999999Z" +// Time format used in cloud orchestration +const STACK_TIME_FMT = "2006-01-02T15:04:05" + /* Link is an internal type to be used in packages of collection resources that are paginated in a certain way. diff --git a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/conn.go b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/conn.go index 47d5534a89fc..b46467025a7f 100644 --- a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/conn.go +++ b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/conn.go @@ -1,3 +1,4 @@ +// Package zk is a native Go client library for the ZooKeeper orchestration service. package zk /* @@ -14,7 +15,6 @@ import ( "errors" "fmt" "io" - "log" "net" "strconv" "strings" @@ -23,8 +23,17 @@ import ( "time" ) +// ErrNoServer indicates that an operation cannot be completed +// because attempts to connect to all servers in the list failed. var ErrNoServer = errors.New("zk: could not connect to a server") +// ErrInvalidPath indicates that an operation was being attempted on +// an invalid path. (e.g. empty path) +var ErrInvalidPath = errors.New("zk: invalid path") + +// DefaultLogger uses the stdlib log package for logging. +var DefaultLogger Logger = defaultLogger{} + const ( bufferSize = 1536 * 1024 eventChanSize = 6 @@ -47,6 +56,11 @@ type watchPathType struct { type Dialer func(network, address string, timeout time.Duration) (net.Conn, error) +// Logger is an interface that can be implemented to provide custom log output. +type Logger interface { + Printf(string, ...interface{}) +} + type Conn struct { lastZxid int64 sessionID int64 @@ -74,6 +88,8 @@ type Conn struct { // Debug (used by unit tests) reconnectDelay time.Duration + + logger Logger } type request struct { @@ -160,6 +176,7 @@ func ConnectWithDialer(servers []string, sessionTimeout time.Duration, dialer Di watchers: make(map[watchPathType][]chan Event), passwd: emptyPassword, timeout: int32(sessionTimeout.Nanoseconds() / 1e6), + logger: DefaultLogger, // Debug reconnectDelay: 0, @@ -182,10 +199,17 @@ func (c *Conn) Close() { } } +// States returns the current state of the connection. func (c *Conn) State() State { return State(atomic.LoadInt32((*int32)(&c.state))) } +// SetLogger sets the logger to be used for printing errors. +// Logger is an interface provided by this package. +func (c *Conn) SetLogger(l Logger) { + c.logger = l +} + func (c *Conn) setState(state State) { atomic.StoreInt32((*int32)(&c.state), int32(state)) select { @@ -221,7 +245,7 @@ func (c *Conn) connect() error { return nil } - log.Printf("Failed to connect to %s: %+v", c.servers[c.serverIndex], err) + c.logger.Printf("Failed to connect to %s: %+v", c.servers[c.serverIndex], err) } } @@ -267,7 +291,7 @@ func (c *Conn) loop() { // Yeesh if err != io.EOF && err != ErrSessionExpired && !strings.Contains(err.Error(), "use of closed network connection") { - log.Println(err) + c.logger.Printf(err.Error()) } select { @@ -367,7 +391,7 @@ func (c *Conn) sendSetWatches() { res := &setWatchesResponse{} _, err := c.request(opSetWatches, req, res, nil) if err != nil { - log.Printf("Failed to set previous watches: %s", err.Error()) + c.logger.Printf("Failed to set previous watches: %s", err.Error()) } }() } @@ -439,9 +463,6 @@ func (c *Conn) authenticate() error { return ErrSessionExpired } - if c.sessionID != r.SessionID { - atomic.StoreUint32(&c.xid, 0) - } c.timeout = r.TimeOut c.sessionID = r.SessionID c.passwd = r.Passwd @@ -582,7 +603,7 @@ func (c *Conn) recvLoop(conn net.Conn) error { } else if res.Xid == -2 { // Ping response. Ignore. } else if res.Xid < 0 { - log.Printf("Xid < 0 (%d) but not ping or watcher event", res.Xid) + c.logger.Printf("Xid < 0 (%d) but not ping or watcher event", res.Xid) } else { if res.Zxid > 0 { c.lastZxid = res.Zxid @@ -596,7 +617,7 @@ func (c *Conn) recvLoop(conn net.Conn) error { c.requestsLock.Unlock() if !ok { - log.Printf("Response for unknown request with xid %d", res.Xid) + c.logger.Printf("Response for unknown request with xid %d", res.Xid) } else { if res.Err != 0 { err = res.Err.toError() @@ -694,6 +715,9 @@ func (c *Conn) GetW(path string) ([]byte, *Stat, <-chan Event, error) { } func (c *Conn) Set(path string, data []byte, version int32) (*Stat, error) { + if path == "" { + return nil, ErrInvalidPath + } res := &setDataResponse{} _, err := c.request(opSetData, &SetDataRequest{path, data, version}, res, nil) return &res.Stat, err diff --git a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/constants.go b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/constants.go index 0546af2efae4..f9b39b904f74 100644 --- a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/constants.go +++ b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/constants.go @@ -57,7 +57,6 @@ const ( StateUnknown = State(-1) StateDisconnected = State(0) StateConnecting = State(1) - StateSyncConnected = State(3) StateAuthFailed = State(4) StateConnectedReadOnly = State(5) StateSaslAuthenticated = State(6) @@ -77,7 +76,6 @@ var ( stateNames = map[State]string{ StateUnknown: "StateUnknown", StateDisconnected: "StateDisconnected", - StateSyncConnected: "StateSyncConnected", StateConnectedReadOnly: "StateConnectedReadOnly", StateSaslAuthenticated: "StateSaslAuthenticated", StateExpired: "StateExpired", diff --git a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/flw.go b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/flw.go index c1225ffa25ab..1045c98cfdb3 100644 --- a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/flw.go +++ b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/flw.go @@ -49,15 +49,17 @@ func FLWSrvr(servers []string, timeout time.Duration) ([]*ServerStats, bool) { continue } - match := re.FindAllStringSubmatch(string(response), -1)[0][1:] + matches := re.FindAllStringSubmatch(string(response), -1) - if match == nil { + if matches == nil { err := fmt.Errorf("unable to parse fields from zookeeper response (no regex matches)") ss[i] = &ServerStats{Error: err} imOk = false continue } + match := matches[0][1:] + // determine current server var srvrMode Mode switch match[10] { diff --git a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/lock.go b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/lock.go index fb77e4a5383d..f13a8b0ba6ea 100644 --- a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/lock.go +++ b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/lock.go @@ -8,10 +8,13 @@ import ( ) var ( - ErrDeadlock = errors.New("zk: trying to acquire a lock twice") + // ErrDeadlock is returned by Lock when trying to lock twice without unlocking first + ErrDeadlock = errors.New("zk: trying to acquire a lock twice") + // ErrNotLocked is returned by Unlock when trying to release a lock that has not first be acquired. ErrNotLocked = errors.New("zk: not locked") ) +// Lock is a mutual exclusion lock. type Lock struct { c *Conn path string @@ -20,6 +23,9 @@ type Lock struct { seq int } +// NewLock creates a new lock instance using the provided connection, path, and acl. +// The path must be a node that is only used by this lock. A lock instances starts +// unlocked until Lock() is called. func NewLock(c *Conn, path string, acl []ACL) *Lock { return &Lock{ c: c, @@ -33,6 +39,9 @@ func parseSeq(path string) (int, error) { return strconv.Atoi(parts[len(parts)-1]) } +// Lock attempts to acquire the lock. It will wait to return until the lock +// is acquired or an error occurs. If this instance already has the lock +// then ErrDeadlock is returned. func (l *Lock) Lock() error { if l.lockPath != "" { return ErrDeadlock @@ -118,6 +127,8 @@ func (l *Lock) Lock() error { return nil } +// Unlock releases an acquired lock. If the lock is not currently acquired by +// this Lock instance than ErrNotLocked is returned. func (l *Lock) Unlock() error { if l.lockPath == "" { return ErrNotLocked diff --git a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/structs.go b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/structs.go index 3c9058adb7d7..8fbc069ee1f5 100644 --- a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/structs.go +++ b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/structs.go @@ -3,6 +3,7 @@ package zk import ( "encoding/binary" "errors" + "log" "reflect" "runtime" "time" @@ -14,6 +15,12 @@ var ( ErrShortBuffer = errors.New("zk: buffer too small") ) +type defaultLogger struct{} + +func (defaultLogger) Printf(format string, a ...interface{}) { + log.Printf(format, a...) +} + type ACL struct { Perms int32 Scheme string diff --git a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/structs_test.go b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/structs_test.go index 64f18e8d3efc..cafbbd95c261 100644 --- a/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/structs_test.go +++ b/Godeps/_workspace/src/github.com/samuel/go-zookeeper/zk/structs_test.go @@ -58,3 +58,14 @@ func TestDecodeShortBuffer(t *testing.T) { return } } + +func BenchmarkEncode(b *testing.B) { + buf := make([]byte, 4096) + st := &connectRequest{Passwd: []byte("1234567890")} + b.ReportAllocs() + for i := 0; i < b.N; i++ { + if _, err := encodePacket(buf, st); err != nil { + b.Fatal(err) + } + } +} diff --git a/Godeps/_workspace/src/github.com/spf13/pflag/.travis.yml b/Godeps/_workspace/src/github.com/spf13/pflag/.travis.yml new file mode 100644 index 000000000000..c40fb69818b0 --- /dev/null +++ b/Godeps/_workspace/src/github.com/spf13/pflag/.travis.yml @@ -0,0 +1,17 @@ +sudo: false + +language: go + +go: + - 1.3 + - 1.4 + - tip + +install: + - go get github.com/golang/lint/golint + - export PATH=$GOPATH/bin:$PATH + - go install ./... + +script: + - verify/all.sh + - go test ./... diff --git a/Godeps/_workspace/src/github.com/spf13/pflag/LICENSE b/Godeps/_workspace/src/github.com/spf13/pflag/LICENSE new file mode 100644 index 000000000000..63ed1cfea1fb --- /dev/null +++ b/Godeps/_workspace/src/github.com/spf13/pflag/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2012 Alex Ogier. All rights reserved. +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/spf13/pflag/verify/all.sh b/Godeps/_workspace/src/github.com/spf13/pflag/verify/all.sh new file mode 100644 index 000000000000..739f89c0b4ba --- /dev/null +++ b/Godeps/_workspace/src/github.com/spf13/pflag/verify/all.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +ROOT=$(dirname "${BASH_SOURCE}")/.. + +# Some useful colors. +if [[ -z "${color_start-}" ]]; then + declare -r color_start="\033[" + declare -r color_red="${color_start}0;31m" + declare -r color_yellow="${color_start}0;33m" + declare -r color_green="${color_start}0;32m" + declare -r color_norm="${color_start}0m" +fi + +SILENT=true + +function is-excluded { + for e in $EXCLUDE; do + if [[ $1 -ef ${BASH_SOURCE} ]]; then + return + fi + if [[ $1 -ef "$ROOT/hack/$e" ]]; then + return + fi + done + return 1 +} + +while getopts ":v" opt; do + case $opt in + v) + SILENT=false + ;; + \?) + echo "Invalid flag: -$OPTARG" >&2 + exit 1 + ;; + esac +done + +if $SILENT ; then + echo "Running in the silent mode, run with -v if you want to see script logs." +fi + +EXCLUDE="all.sh" + +ret=0 +for t in `ls $ROOT/verify/*.sh` +do + if is-excluded $t ; then + echo "Skipping $t" + continue + fi + if $SILENT ; then + echo -e "Verifying $t" + if bash "$t" &> /dev/null; then + echo -e "${color_green}SUCCESS${color_norm}" + else + echo -e "${color_red}FAILED${color_norm}" + ret=1 + fi + else + bash "$t" || ret=1 + fi +done +exit $ret diff --git a/Godeps/_workspace/src/github.com/spf13/pflag/verify/gofmt.sh b/Godeps/_workspace/src/github.com/spf13/pflag/verify/gofmt.sh new file mode 100644 index 000000000000..f66acf803b54 --- /dev/null +++ b/Godeps/_workspace/src/github.com/spf13/pflag/verify/gofmt.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +ROOT=$(dirname "${BASH_SOURCE}")/.. + +pushd "${ROOT}" > /dev/null + +GOFMT=${GOFMT:-"gofmt"} +bad_files=$(find . -name '*.go' | xargs $GOFMT -s -l) +if [[ -n "${bad_files}" ]]; then + echo "!!! '$GOFMT' needs to be run on the following files: " + echo "${bad_files}" + exit 1 +fi + +# ex: ts=2 sw=2 et filetype=sh diff --git a/Godeps/_workspace/src/github.com/spf13/pflag/verify/golint.sh b/Godeps/_workspace/src/github.com/spf13/pflag/verify/golint.sh new file mode 100644 index 000000000000..685c1778e598 --- /dev/null +++ b/Godeps/_workspace/src/github.com/spf13/pflag/verify/golint.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +ROOT=$(dirname "${BASH_SOURCE}")/.. +GOLINT=${GOLINT:-"golint"} + +pushd "${ROOT}" > /dev/null + bad_files=$($GOLINT -min_confidence=0.9 ./...) + if [[ -n "${bad_files}" ]]; then + echo "!!! '$GOLINT' problems: " + echo "${bad_files}" + exit 1 + fi +popd > /dev/null + +# ex: ts=2 sw=2 et filetype=sh diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/0doc.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/0doc.go index 0f33922b730d..dd8b589de070 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/0doc.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/0doc.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. /* High Performance, Feature-Rich Idiomatic Go codec/encoding library for diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/binc.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/binc.go index dc3aa80a9510..645376479ae1 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/binc.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/binc.go @@ -1,10 +1,11 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec import ( "math" + "reflect" "time" ) @@ -69,7 +70,15 @@ func (e *bincEncDriver) IsBuiltinType(rt uintptr) bool { func (e *bincEncDriver) EncodeBuiltin(rt uintptr, v interface{}) { if rt == timeTypId { - bs := encodeTime(v.(time.Time)) + var bs []byte + switch x := v.(type) { + case time.Time: + bs = encodeTime(x) + case *time.Time: + bs = encodeTime(*x) + default: + e.e.errorf("binc error encoding builtin: expect time.Time, received %T", v) + } e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs))) e.w.writeb(bs) } @@ -897,5 +906,9 @@ func (h *BincHandle) newDecDriver(d *Decoder) decDriver { return &bincDecDriver{d: d, r: d.r, h: h, br: d.bytes} } +func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) { + return h.SetExt(rt, tag, &setExtWrapper{b: ext}) +} + var _ decDriver = (*bincDecDriver)(nil) var _ encDriver = (*bincEncDriver)(nil) diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor.go index b56bcef9bab0..8b6e13a89e98 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor.go @@ -1,9 +1,12 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec -import "math" +import ( + "math" + "reflect" +) const ( cborMajorUint byte = iota @@ -98,7 +101,7 @@ func (e *cborEncDriver) encUint(v uint64, bd byte) { } else if v <= math.MaxUint32 { e.w.writen1(bd + 0x1a) bigenHelper{e.x[:4], e.w}.writeUint32(uint32(v)) - } else if v <= math.MaxUint64 { + } else { // if v <= math.MaxUint64 { e.w.writen1(bd + 0x1b) bigenHelper{e.x[:8], e.w}.writeUint64(v) } @@ -158,7 +161,11 @@ func (e *cborEncDriver) EncodeSymbol(v string) { } func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) { - e.encLen(cborBaseBytes, len(v)) + if c == c_RAW { + e.encLen(cborBaseBytes, len(v)) + } else { + e.encLen(cborBaseString, len(v)) + } e.w.writeb(v) } @@ -562,5 +569,9 @@ func (h *CborHandle) newDecDriver(d *Decoder) decDriver { return &cborDecDriver{d: d, r: d.r, h: h, br: d.bytes} } +func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) { + return h.SetExt(rt, tag, &setExtWrapper{i: ext}) +} + var _ decDriver = (*cborDecDriver)(nil) var _ encDriver = (*cborEncDriver)(nil) diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor_test.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor_test.go index b03a9da078a4..205dffa7d15b 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor_test.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/codec_test.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/codec_test.go index 205af445a24a..d9583a9b139d 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/codec_test.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/codec_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec @@ -860,6 +860,60 @@ func testCodecRpcOne(t *testing.T, rr Rpc, h Handle, doRequest bool, exitSleepMs return } +func doTestMapEncodeForCanonical(t *testing.T, name string, h Handle) { + v1 := map[string]interface{}{ + "a": 1, + "b": "hello", + "c": map[string]interface{}{ + "c/a": 1, + "c/b": "world", + "c/c": []int{1, 2, 3, 4}, + "c/d": map[string]interface{}{ + "c/d/a": "fdisajfoidsajfopdjsaopfjdsapofda", + "c/d/b": "fdsafjdposakfodpsakfopdsakfpodsakfpodksaopfkdsopafkdopsa", + "c/d/c": "poir02 ir30qif4p03qir0pogjfpoaerfgjp ofke[padfk[ewapf kdp[afep[aw", + "c/d/d": "fdsopafkd[sa f-32qor-=4qeof -afo-erfo r-eafo 4e- o r4-qwo ag", + "c/d/e": "kfep[a sfkr0[paf[a foe-[wq ewpfao-q ro3-q ro-4qof4-qor 3-e orfkropzjbvoisdb", + "c/d/f": "", + }, + "c/e": map[int]string{ + 1: "1", + 22: "22", + 333: "333", + 4444: "4444", + 55555: "55555", + }, + "c/f": map[string]int{ + "1": 1, + "22": 22, + "333": 333, + "4444": 4444, + "55555": 55555, + }, + }, + } + var v2 map[string]interface{} + var b1, b2 []byte + + // encode v1 into b1, decode b1 into v2, encode v2 into b2, compare b1 and b2 + + bh := h.getBasicHandle() + canonical0 := bh.Canonical + bh.Canonical = true + defer func() { bh.Canonical = canonical0 }() + + e1 := NewEncoderBytes(&b1, h) + e1.MustEncode(v1) + d1 := NewDecoderBytes(b1, h) + d1.MustDecode(&v2) + e2 := NewEncoderBytes(&b2, h) + e2.MustEncode(v2) + if !bytes.Equal(b1, b2) { + logT(t, "Unequal bytes: %v VS %v", b1, b2) + t.FailNow() + } +} + // Comprehensive testing that generates data encoded from python handle (cbor, msgpack), // and validates that our code can read and write it out accordingly. // We keep this unexported here, and put actual test in ext_dep_test.go. @@ -1048,6 +1102,10 @@ func TestCborCodecsEmbeddedPointer(t *testing.T) { testCodecEmbeddedPointer(t, testCborH) } +func TestCborMapEncodeForCanonical(t *testing.T) { + doTestMapEncodeForCanonical(t, "cbor", testCborH) +} + func TestJsonCodecsTable(t *testing.T) { testCodecTableOne(t, testJsonH) } diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen/gen.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen/gen.go index 0a32b6cb3daa..582ba4443491 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen/gen.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen/gen.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. // codecgen generates codec.Selfer implementations for a set of types. package main @@ -14,6 +14,7 @@ import ( "go/build" "go/parser" "go/token" + "math/rand" "os" "os/exec" "path/filepath" @@ -23,6 +24,8 @@ import ( "time" ) +const genCodecPkg = "codec1978" // keep this in sync with codec.genCodecPkg + const genFrunMainTmpl = `//+build ignore package main @@ -45,6 +48,7 @@ import ( "os" "reflect" "bytes" + "strings" "go/format" ) @@ -69,7 +73,7 @@ func CodecGenTempWrite{{ .RandString }}() { var t{{ $index }} {{ . }} typs = append(typs, reflect.TypeOf(t{{ $index }})) {{ end }} - {{ if not .CodecPkgFiles }}{{ .CodecPkgName }}.{{ end }}Gen(&out, "{{ .BuildTag }}", "{{ .PackageName }}", {{ .UseUnsafe }}, typs...) + {{ if not .CodecPkgFiles }}{{ .CodecPkgName }}.{{ end }}Gen(&out, "{{ .BuildTag }}", "{{ .PackageName }}", "{{ .RandString }}", {{ .UseUnsafe }}, {{ if not .CodecPkgFiles }}{{ .CodecPkgName }}.{{ end }}NewTypeInfos(strings.Split("{{ .StructTags }}", ",")), typs...) bout, err := format.Source(out.Bytes()) if err != nil { fout.Write(out.Bytes()) @@ -89,8 +93,8 @@ func CodecGenTempWrite{{ .RandString }}() { // Tool then executes: "go run __frun__" which creates fout. // fout contains Codec(En|De)codeSelf implementations for every type T. // -func Generate(outfile, buildTag, codecPkgPath string, useUnsafe bool, goRunTag string, - regexName *regexp.Regexp, deleteTempFile bool, infiles ...string) (err error) { +func Generate(outfile, buildTag, codecPkgPath string, uid int64, useUnsafe bool, goRunTag string, + st string, regexName *regexp.Regexp, deleteTempFile bool, infiles ...string) (err error) { // For each file, grab AST, find each type, and write a call to it. if len(infiles) == 0 { return @@ -99,6 +103,13 @@ func Generate(outfile, buildTag, codecPkgPath string, useUnsafe bool, goRunTag s err = errors.New("outfile and codec package path cannot be blank") return } + if uid < 0 { + uid = -uid + } + if uid == 0 { + rr := rand.New(rand.NewSource(time.Now().UnixNano())) + uid = 101 + rr.Int63n(9777) + } // We have to parse dir for package, before opening the temp file for writing (else ImportDir fails). // Also, ImportDir(...) must take an absolute path. lastdir := filepath.Dir(outfile) @@ -118,17 +129,19 @@ func Generate(outfile, buildTag, codecPkgPath string, useUnsafe bool, goRunTag s PackageName string RandString string BuildTag string + StructTags string Types []string CodecPkgFiles bool UseUnsafe bool } tv := tmplT{ - CodecPkgName: "codec1978", + CodecPkgName: genCodecPkg, OutFile: outfile, CodecImportPath: codecPkgPath, BuildTag: buildTag, UseUnsafe: useUnsafe, - RandString: strconv.FormatInt(time.Now().UnixNano(), 10), + RandString: strconv.FormatInt(uid, 10), + StructTags: st, } tv.ImportPath = pkg.ImportPath if tv.ImportPath == tv.CodecImportPath { @@ -259,11 +272,12 @@ func main() { t := flag.String("t", "", "build tag to put in file") r := flag.String("r", ".*", "regex for type name to match") rt := flag.String("rt", "", "tags for go run") + st := flag.String("st", "codec,json", "struct tag keys to introspect") x := flag.Bool("x", false, "keep temp file") u := flag.Bool("u", false, "Use unsafe, e.g. to avoid unnecessary allocation on []byte->string") - + d := flag.Int64("d", 0, "random identifier for use in generated code") flag.Parse() - if err := Generate(*o, *t, *c, *u, *rt, + if err := Generate(*o, *t, *c, *d, *u, *rt, *st, regexp.MustCompile(*r), !*x, flag.Args()...); err != nil { fmt.Fprintf(os.Stderr, "codecgen error: %v\n", err) os.Exit(1) diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen_test.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen_test.go index 2fdfd161d151..bb7e0bfcfeb3 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen_test.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen_test.go @@ -8,6 +8,7 @@ import ( ) func TestCodecgenJson1(t *testing.T) { + // This is just a simplistic test for codecgen. const callCodecgenDirect bool = true v := newTestStruc(2, false, !testSkipIntf, false) var bs []byte diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/decode.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/decode.go index d6c0c6d18e0d..d068cf61e274 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/decode.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/decode.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec @@ -25,10 +25,6 @@ var ( // decReader abstracts the reading source, allowing implementations that can // read from an io.Reader or directly off a byte slice with zero-copying. type decReader interface { - // TODO: - // Add method to get num bytes read. - // This will be used to annotate errors, so user knows at what point the error occurred. - unreadn1() // readx will use the implementation scratch buffer if possible i.e. n < len(scratchbuf), OR @@ -38,6 +34,9 @@ type decReader interface { readb([]byte) readn1() uint8 readn1eof() (v uint8, eof bool) + numread() int // number of bytes read + track() + stopTrack() []byte } type decReaderByteScanner interface { @@ -79,20 +78,13 @@ type decDriver interface { // decodeExt(verifyTag bool, tag byte) (xtag byte, xbs []byte) ReadMapStart() int ReadArrayStart() int - ReadMapEnd() - ReadArrayEnd() - ReadArrayEntrySeparator() - ReadMapEntrySeparator() - ReadMapKVSeparator() + // ReadEnd registers the end of a map or array. + ReadEnd() } type decNoSeparator struct{} -func (_ decNoSeparator) ReadMapEnd() {} -func (_ decNoSeparator) ReadArrayEnd() {} -func (_ decNoSeparator) ReadArrayEntrySeparator() {} -func (_ decNoSeparator) ReadMapEntrySeparator() {} -func (_ decNoSeparator) ReadMapKVSeparator() {} +func (_ decNoSeparator) ReadEnd() {} type DecodeOptions struct { // MapType specifies type to use during schema-less decoding of a map in the stream. @@ -114,6 +106,14 @@ type DecodeOptions struct { // If SignedInteger, use the int64 during schema-less decoding of unsigned values (not uint64). SignedInteger bool + + // MaxInitLen defines the initial length that we "make" a collection (slice, chan or map) with. + // If 0 or negative, we default to a sensible value based on the size of an element in the collection. + // + // For example, when decoding, a stream may say that it has MAX_UINT elements. + // We should not auto-matically provision a slice of that length, to prevent Out-Of-Memory crash. + // Instead, we provision up to MaxInitLen, fill that up, and start appending after that. + MaxInitLen int } // ------------------------------------ @@ -181,8 +181,15 @@ type ioDecReader struct { br decReaderByteScanner // temp byte array re-used internally for efficiency during read. // shares buffer with Decoder, so we keep size of struct within 8 words. - x *[scratchByteArrayLen]byte - bs ioDecByteScanner + x *[scratchByteArrayLen]byte + bs ioDecByteScanner + n int // num read + tr []byte // tracking bytes read + trb bool +} + +func (z *ioDecReader) numread() int { + return z.n } func (z *ioDecReader) readx(n int) (bs []byte) { @@ -197,6 +204,10 @@ func (z *ioDecReader) readx(n int) (bs []byte) { if _, err := io.ReadAtLeast(z.br, bs, n); err != nil { panic(err) } + z.n += len(bs) + if z.trb { + z.tr = append(z.tr, bs...) + } return } @@ -204,9 +215,14 @@ func (z *ioDecReader) readb(bs []byte) { if len(bs) == 0 { return } - if _, err := io.ReadAtLeast(z.br, bs, len(bs)); err != nil { + n, err := io.ReadAtLeast(z.br, bs, len(bs)) + z.n += n + if err != nil { panic(err) } + if z.trb { + z.tr = append(z.tr, bs...) + } } func (z *ioDecReader) readn1() (b uint8) { @@ -214,12 +230,20 @@ func (z *ioDecReader) readn1() (b uint8) { if err != nil { panic(err) } + z.n++ + if z.trb { + z.tr = append(z.tr, b) + } return b } func (z *ioDecReader) readn1eof() (b uint8, eof bool) { b, err := z.br.ReadByte() if err == nil { + z.n++ + if z.trb { + z.tr = append(z.tr, b) + } } else if err == io.EOF { eof = true } else { @@ -229,9 +253,28 @@ func (z *ioDecReader) readn1eof() (b uint8, eof bool) { } func (z *ioDecReader) unreadn1() { - if err := z.br.UnreadByte(); err != nil { + err := z.br.UnreadByte() + if err != nil { panic(err) } + z.n-- + if z.trb { + if l := len(z.tr) - 1; l >= 0 { + z.tr = z.tr[:l] + } + } +} + +func (z *ioDecReader) track() { + if z.tr != nil { + z.tr = z.tr[:0] + } + z.trb = true +} + +func (z *ioDecReader) stopTrack() (bs []byte) { + z.trb = false + return z.tr } // ------------------------------------ @@ -243,6 +286,11 @@ type bytesDecReader struct { b []byte // data c int // cursor a int // available + t int // track start +} + +func (z *bytesDecReader) numread() int { + return z.c } func (z *bytesDecReader) unreadn1() { @@ -298,9 +346,17 @@ func (z *bytesDecReader) readb(bs []byte) { copy(bs, z.readx(len(bs))) } +func (z *bytesDecReader) track() { + z.t = z.c +} + +func (z *bytesDecReader) stopTrack() (bs []byte) { + return z.b[z.t:z.c] +} + // ------------------------------------ -type decFnInfoX struct { +type decFnInfo struct { d *Decoder ti *typeInfo xfFn Ext @@ -308,40 +364,26 @@ type decFnInfoX struct { seq seqType } -// decFnInfo has methods for handling decoding of a specific type -// based on some characteristics (builtin, extension, reflect Kind, etc) -type decFnInfo struct { - // use decFnInfo as a value receiver. - // keep most of it less-used variables accessible via a pointer (*decFnInfoX). - // As sweet spot for value-receiver is 3 words, keep everything except - // decDriver (which everyone needs) directly accessible. - // ensure decFnInfoX is set for everyone who needs it i.e. - // rawExt, ext, builtin, (selfer|binary|text)Marshal, kSlice, kStruct, kMap, kInterface, fastpath - - dd decDriver - *decFnInfoX -} - // ---------------------------------------- type decFn struct { i decFnInfo - f func(decFnInfo, reflect.Value) + f func(*decFnInfo, reflect.Value) } -func (f decFnInfo) builtin(rv reflect.Value) { - f.dd.DecodeBuiltin(f.ti.rtid, rv.Addr().Interface()) +func (f *decFnInfo) builtin(rv reflect.Value) { + f.d.d.DecodeBuiltin(f.ti.rtid, rv.Addr().Interface()) } -func (f decFnInfo) rawExt(rv reflect.Value) { - f.dd.DecodeExt(rv.Addr().Interface(), 0, nil) +func (f *decFnInfo) rawExt(rv reflect.Value) { + f.d.d.DecodeExt(rv.Addr().Interface(), 0, nil) } -func (f decFnInfo) ext(rv reflect.Value) { - f.dd.DecodeExt(rv.Addr().Interface(), f.xfTag, f.xfFn) +func (f *decFnInfo) ext(rv reflect.Value) { + f.d.d.DecodeExt(rv.Addr().Interface(), f.xfTag, f.xfFn) } -func (f decFnInfo) getValueForUnmarshalInterface(rv reflect.Value, indir int8) (v interface{}) { +func (f *decFnInfo) getValueForUnmarshalInterface(rv reflect.Value, indir int8) (v interface{}) { if indir == -1 { v = rv.Addr().Interface() } else if indir == 0 { @@ -358,95 +400,105 @@ func (f decFnInfo) getValueForUnmarshalInterface(rv reflect.Value, indir int8) ( return } -func (f decFnInfo) selferUnmarshal(rv reflect.Value) { +func (f *decFnInfo) selferUnmarshal(rv reflect.Value) { f.getValueForUnmarshalInterface(rv, f.ti.csIndir).(Selfer).CodecDecodeSelf(f.d) } -func (f decFnInfo) binaryUnmarshal(rv reflect.Value) { +func (f *decFnInfo) binaryUnmarshal(rv reflect.Value) { bm := f.getValueForUnmarshalInterface(rv, f.ti.bunmIndir).(encoding.BinaryUnmarshaler) - xbs := f.dd.DecodeBytes(nil, false, true) + xbs := f.d.d.DecodeBytes(nil, false, true) if fnerr := bm.UnmarshalBinary(xbs); fnerr != nil { panic(fnerr) } } -func (f decFnInfo) textUnmarshal(rv reflect.Value) { +func (f *decFnInfo) textUnmarshal(rv reflect.Value) { tm := f.getValueForUnmarshalInterface(rv, f.ti.tunmIndir).(encoding.TextUnmarshaler) - fnerr := tm.UnmarshalText(f.dd.DecodeBytes(f.d.b[:], true, true)) - // fnerr := tm.UnmarshalText(f.dd.DecodeStringAsBytes(f.d.b[:])) + fnerr := tm.UnmarshalText(f.d.d.DecodeBytes(f.d.b[:], true, true)) + if fnerr != nil { + panic(fnerr) + } +} - // var fnerr error - // if sb, sbok := f.dd.(decDriverStringAsBytes); sbok { - // fnerr = tm.UnmarshalText(sb.decStringAsBytes(f.d.b[:0])) - // } else { - // fnerr = tm.UnmarshalText([]byte(f.dd.decodeString())) - // } +func (f *decFnInfo) jsonUnmarshal(rv reflect.Value) { + tm := f.getValueForUnmarshalInterface(rv, f.ti.junmIndir).(jsonUnmarshaler) + // bs := f.d.d.DecodeBytes(f.d.b[:], true, true) + // grab the bytes to be read, as UnmarshalJSON wants the full JSON to unmarshal it itself. + f.d.r.track() + f.d.swallow() + bs := f.d.r.stopTrack() + // fmt.Printf(">>>>>> REFLECTION JSON: %s\n", bs) + fnerr := tm.UnmarshalJSON(bs) if fnerr != nil { panic(fnerr) } } -func (f decFnInfo) kErr(rv reflect.Value) { +func (f *decFnInfo) kErr(rv reflect.Value) { f.d.errorf("no decoding function defined for kind %v", rv.Kind()) } -func (f decFnInfo) kString(rv reflect.Value) { - rv.SetString(f.dd.DecodeString()) +func (f *decFnInfo) kString(rv reflect.Value) { + rv.SetString(f.d.d.DecodeString()) +} + +func (f *decFnInfo) kBool(rv reflect.Value) { + rv.SetBool(f.d.d.DecodeBool()) } -func (f decFnInfo) kBool(rv reflect.Value) { - rv.SetBool(f.dd.DecodeBool()) +func (f *decFnInfo) kInt(rv reflect.Value) { + rv.SetInt(f.d.d.DecodeInt(intBitsize)) } -func (f decFnInfo) kInt(rv reflect.Value) { - rv.SetInt(f.dd.DecodeInt(intBitsize)) +func (f *decFnInfo) kInt64(rv reflect.Value) { + rv.SetInt(f.d.d.DecodeInt(64)) } -func (f decFnInfo) kInt64(rv reflect.Value) { - rv.SetInt(f.dd.DecodeInt(64)) +func (f *decFnInfo) kInt32(rv reflect.Value) { + rv.SetInt(f.d.d.DecodeInt(32)) } -func (f decFnInfo) kInt32(rv reflect.Value) { - rv.SetInt(f.dd.DecodeInt(32)) +func (f *decFnInfo) kInt8(rv reflect.Value) { + rv.SetInt(f.d.d.DecodeInt(8)) } -func (f decFnInfo) kInt8(rv reflect.Value) { - rv.SetInt(f.dd.DecodeInt(8)) +func (f *decFnInfo) kInt16(rv reflect.Value) { + rv.SetInt(f.d.d.DecodeInt(16)) } -func (f decFnInfo) kInt16(rv reflect.Value) { - rv.SetInt(f.dd.DecodeInt(16)) +func (f *decFnInfo) kFloat32(rv reflect.Value) { + rv.SetFloat(f.d.d.DecodeFloat(true)) } -func (f decFnInfo) kFloat32(rv reflect.Value) { - rv.SetFloat(f.dd.DecodeFloat(true)) +func (f *decFnInfo) kFloat64(rv reflect.Value) { + rv.SetFloat(f.d.d.DecodeFloat(false)) } -func (f decFnInfo) kFloat64(rv reflect.Value) { - rv.SetFloat(f.dd.DecodeFloat(false)) +func (f *decFnInfo) kUint8(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(8)) } -func (f decFnInfo) kUint8(rv reflect.Value) { - rv.SetUint(f.dd.DecodeUint(8)) +func (f *decFnInfo) kUint64(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(64)) } -func (f decFnInfo) kUint64(rv reflect.Value) { - rv.SetUint(f.dd.DecodeUint(64)) +func (f *decFnInfo) kUint(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(uintBitsize)) } -func (f decFnInfo) kUint(rv reflect.Value) { - rv.SetUint(f.dd.DecodeUint(uintBitsize)) +func (f *decFnInfo) kUintptr(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(uintBitsize)) } -func (f decFnInfo) kUint32(rv reflect.Value) { - rv.SetUint(f.dd.DecodeUint(32)) +func (f *decFnInfo) kUint32(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(32)) } -func (f decFnInfo) kUint16(rv reflect.Value) { - rv.SetUint(f.dd.DecodeUint(16)) +func (f *decFnInfo) kUint16(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(16)) } -// func (f decFnInfo) kPtr(rv reflect.Value) { +// func (f *decFnInfo) kPtr(rv reflect.Value) { // debugf(">>>>>>> ??? decode kPtr called - shouldn't get called") // if rv.IsNil() { // rv.Set(reflect.New(rv.Type().Elem())) @@ -456,11 +508,11 @@ func (f decFnInfo) kUint16(rv reflect.Value) { // var kIntfCtr uint64 -func (f decFnInfo) kInterfaceNaked() (rvn reflect.Value) { +func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) { // nil interface: // use some hieristics to decode it appropriately // based on the detected next value in the stream. - v, vt, decodeFurther := f.dd.DecodeNaked() + v, vt, decodeFurther := f.d.d.DecodeNaked() if vt == valueTypeNil { return } @@ -506,7 +558,7 @@ func (f decFnInfo) kInterfaceNaked() (rvn reflect.Value) { } if decodeFurther { if useRvn { - f.d.decodeValue(rvn, decFn{}) + f.d.decodeValue(rvn, nil) } else if v != nil { // this v is a pointer, so we need to dereference it when done f.d.decode(v) @@ -521,7 +573,7 @@ func (f decFnInfo) kInterfaceNaked() (rvn reflect.Value) { return } -func (f decFnInfo) kInterface(rv reflect.Value) { +func (f *decFnInfo) kInterface(rv reflect.Value) { // debugf("\t===> kInterface") // Note: @@ -543,69 +595,66 @@ func (f decFnInfo) kInterface(rv reflect.Value) { // we just decode into it. // Else we create a settable value, decode into it, and set on the interface. if rve.CanSet() { - f.d.decodeValue(rve, decFn{}) + f.d.decodeValue(rve, nil) } else { rve2 := reflect.New(rve.Type()).Elem() rve2.Set(rve) - f.d.decodeValue(rve2, decFn{}) + f.d.decodeValue(rve2, nil) rv.Set(rve2) } } } -func (f decFnInfo) kStruct(rv reflect.Value) { +func (f *decFnInfo) kStruct(rv reflect.Value) { fti := f.ti d := f.d - if f.dd.IsContainerType(valueTypeMap) { - containerLen := f.dd.ReadMapStart() + dd := d.d + if dd.IsContainerType(valueTypeMap) { + containerLen := dd.ReadMapStart() if containerLen == 0 { - f.dd.ReadMapEnd() + dd.ReadEnd() return } tisfi := fti.sfi hasLen := containerLen >= 0 if hasLen { for j := 0; j < containerLen; j++ { - // rvkencname := f.dd.DecodeString() - rvkencname := stringView(f.dd.DecodeBytes(f.d.b[:], true, true)) + // rvkencname := dd.DecodeString() + rvkencname := stringView(dd.DecodeBytes(f.d.b[:], true, true)) // rvksi := ti.getForEncName(rvkencname) if k := fti.indexForEncName(rvkencname); k > -1 { si := tisfi[k] - if f.dd.TryDecodeAsNil() { + if dd.TryDecodeAsNil() { si.setToZeroValue(rv) } else { - d.decodeValue(si.field(rv, true), decFn{}) + d.decodeValue(si.field(rv, true), nil) } } else { d.structFieldNotFound(-1, rvkencname) } } } else { - for j := 0; !f.dd.CheckBreak(); j++ { - if j > 0 { - f.dd.ReadMapEntrySeparator() - } - // rvkencname := f.dd.DecodeString() - rvkencname := stringView(f.dd.DecodeBytes(f.d.b[:], true, true)) - f.dd.ReadMapKVSeparator() + for j := 0; !dd.CheckBreak(); j++ { + // rvkencname := dd.DecodeString() + rvkencname := stringView(dd.DecodeBytes(f.d.b[:], true, true)) // rvksi := ti.getForEncName(rvkencname) if k := fti.indexForEncName(rvkencname); k > -1 { si := tisfi[k] - if f.dd.TryDecodeAsNil() { + if dd.TryDecodeAsNil() { si.setToZeroValue(rv) } else { - d.decodeValue(si.field(rv, true), decFn{}) + d.decodeValue(si.field(rv, true), nil) } } else { d.structFieldNotFound(-1, rvkencname) } } - f.dd.ReadMapEnd() + dd.ReadEnd() } - } else if f.dd.IsContainerType(valueTypeArray) { - containerLen := f.dd.ReadArrayStart() + } else if dd.IsContainerType(valueTypeArray) { + containerLen := dd.ReadArrayStart() if containerLen == 0 { - f.dd.ReadArrayEnd() + dd.ReadEnd() return } // Not much gain from doing it two ways for array. @@ -616,55 +665,47 @@ func (f decFnInfo) kStruct(rv reflect.Value) { if j == containerLen { break } - } else if f.dd.CheckBreak() { + } else if dd.CheckBreak() { break } - if j > 0 { - f.dd.ReadArrayEntrySeparator() - } - if f.dd.TryDecodeAsNil() { + if dd.TryDecodeAsNil() { si.setToZeroValue(rv) } else { - d.decodeValue(si.field(rv, true), decFn{}) + d.decodeValue(si.field(rv, true), nil) } - // if si.i != -1 { - // d.decodeValue(rv.Field(int(si.i)), decFn{}) - // } else { - // d.decEmbeddedField(rv, si.is) - // } } if containerLen > len(fti.sfip) { // read remaining values and throw away for j := len(fti.sfip); j < containerLen; j++ { - if j > 0 { - f.dd.ReadArrayEntrySeparator() - } d.structFieldNotFound(j, "") } } - f.dd.ReadArrayEnd() + dd.ReadEnd() } else { f.d.error(onlyMapOrArrayCanDecodeIntoStructErr) return } } -func (f decFnInfo) kSlice(rv reflect.Value) { +func (f *decFnInfo) kSlice(rv reflect.Value) { // A slice can be set from a map or array in stream. // This way, the order can be kept (as order is lost with map). ti := f.ti d := f.d - if f.dd.IsContainerType(valueTypeBytes) || f.dd.IsContainerType(valueTypeString) { - if ti.rtid == uint8SliceTypId || ti.rt.Elem().Kind() == reflect.Uint8 { + dd := d.d + rtelem0 := ti.rt.Elem() + + if dd.IsContainerType(valueTypeBytes) || dd.IsContainerType(valueTypeString) { + if ti.rtid == uint8SliceTypId || rtelem0.Kind() == reflect.Uint8 { if f.seq == seqTypeChan { - bs2 := f.dd.DecodeBytes(nil, false, true) + bs2 := dd.DecodeBytes(nil, false, true) ch := rv.Interface().(chan<- byte) for _, b := range bs2 { ch <- b } } else { rvbs := rv.Bytes() - bs2 := f.dd.DecodeBytes(rvbs, false, false) + bs2 := dd.DecodeBytes(rvbs, false, false) if rvbs == nil && bs2 != nil || rvbs != nil && bs2 == nil || len(bs2) != len(rvbs) { if rv.CanSet() { rv.SetBytes(bs2) @@ -681,88 +722,102 @@ func (f decFnInfo) kSlice(rv reflect.Value) { slh, containerLenS := d.decSliceHelperStart() + var rvlen, numToRead int + var truncated bool // says that the len of the sequence is not same as the expected number of elements. + + numToRead = containerLenS // if truncated, reset numToRead + // an array can never return a nil slice. so no need to check f.array here. if rv.IsNil() { // either chan or slice + if rvlen, truncated = decInferLen(containerLenS, f.d.h.MaxInitLen, int(rtelem0.Size())); truncated { + numToRead = rvlen + } if f.seq == seqTypeSlice { - if containerLenS <= 0 { - rv.Set(reflect.MakeSlice(ti.rt, 0, 0)) - } else { - rv.Set(reflect.MakeSlice(ti.rt, containerLenS, containerLenS)) - } + rv.Set(reflect.MakeSlice(ti.rt, rvlen, rvlen)) } else if f.seq == seqTypeChan { - if containerLenS <= 0 { - rv.Set(reflect.MakeChan(ti.rt, 0)) - } else { - rv.Set(reflect.MakeChan(ti.rt, containerLenS)) - } + rv.Set(reflect.MakeChan(ti.rt, rvlen)) } + } else { + rvlen = rv.Len() } - rvlen := rv.Len() if containerLenS == 0 { if f.seq == seqTypeSlice && rvlen != 0 { rv.SetLen(0) } - // slh.End() // f.dd.ReadArrayEnd() + // dd.ReadEnd() return } - rtelem0 := ti.rt.Elem() rtelem := rtelem0 for rtelem.Kind() == reflect.Ptr { rtelem = rtelem.Elem() } fn := d.getDecFn(rtelem, true, true) - rv0 := rv + var rv0, rv9 reflect.Value + rv0 = rv rvChanged := false rvcap := rv.Cap() // for j := 0; j < containerLenS; j++ { - hasLen := containerLenS >= 0 - if hasLen { + if containerLenS >= 0 { // hasLen if f.seq == seqTypeChan { // handle chan specially: for j := 0; j < containerLenS; j++ { - rv0 := reflect.New(rtelem0).Elem() - d.decodeValue(rv0, fn) - rv.Send(rv0) + rv9 = reflect.New(rtelem0).Elem() + d.decodeValue(rv9, fn) + rv.Send(rv9) } - } else { - numToRead := containerLenS + } else { // slice or array if containerLenS > rvcap { if f.seq == seqTypeArray { - d.arrayCannotExpand(rv.Len(), containerLenS) - numToRead = rvlen + d.arrayCannotExpand(rvlen, containerLenS) } else { - rv = reflect.MakeSlice(ti.rt, containerLenS, containerLenS) - if rvlen > 0 && !isMutableKind(ti.rt.Kind()) { - rv1 := rv0 - rv1.SetLen(rvcap) - reflect.Copy(rv, rv1) + oldRvlenGtZero := rvlen > 0 + rvlen, truncated = decInferLen(containerLenS, f.d.h.MaxInitLen, int(rtelem0.Size())) + rv = reflect.MakeSlice(ti.rt, rvlen, rvlen) + if oldRvlenGtZero && !isImmutableKind(rtelem0.Kind()) { + reflect.Copy(rv, rv0) // only copy up to length NOT cap i.e. rv0.Slice(0, rvcap) } rvChanged = true - rvlen = containerLenS } + numToRead = rvlen } else if containerLenS != rvlen { - rv.SetLen(containerLenS) - rvlen = containerLenS + if f.seq == seqTypeSlice { + rv.SetLen(containerLenS) + rvlen = containerLenS + } } j := 0 + // we read up to the numToRead for ; j < numToRead; j++ { d.decodeValue(rv.Index(j), fn) } + + // if slice, expand and read up to containerLenS (or EOF) iff truncated + // if array, swallow all the rest. + if f.seq == seqTypeArray { for ; j < containerLenS; j++ { d.swallow() } + } else if truncated { // slice was truncated, as chan NOT in this block + for ; j < containerLenS; j++ { + rv = expandSliceValue(rv, 1) + rv9 = rv.Index(j) + if resetSliceElemToZeroValue { + rv9.Set(reflect.Zero(rtelem0)) + } + d.decodeValue(rv9, fn) + } } } } else { - for j := 0; !f.dd.CheckBreak(); j++ { + for j := 0; !dd.CheckBreak(); j++ { var decodeIntoBlank bool // if indefinite, etc, then expand the slice if necessary if j >= rvlen { @@ -770,22 +825,27 @@ func (f decFnInfo) kSlice(rv reflect.Value) { d.arrayCannotExpand(rvlen, j+1) decodeIntoBlank = true } else if f.seq == seqTypeSlice { - rv = reflect.Append(rv, reflect.Zero(rtelem0)) + // rv = reflect.Append(rv, reflect.Zero(rtelem0)) // uses append logic, plus varargs + rv = expandSliceValue(rv, 1) + rv9 = rv.Index(j) + // rv.Index(rv.Len() - 1).Set(reflect.Zero(rtelem0)) + if resetSliceElemToZeroValue { + rv9.Set(reflect.Zero(rtelem0)) + } rvlen++ rvChanged = true } - } - if j > 0 { - slh.Sep(j) + } else if f.seq != seqTypeChan { // slice or array + rv9 = rv.Index(j) } if f.seq == seqTypeChan { - rv0 := reflect.New(rtelem0).Elem() - d.decodeValue(rv0, fn) - rv.Send(rv0) + rv9 = reflect.New(rtelem0).Elem() + d.decodeValue(rv9, fn) + rv.Send(rv9) } else if decodeIntoBlank { d.swallow() - } else { - d.decodeValue(rv.Index(j), fn) + } else { // seqTypeSlice + d.decodeValue(rv9, fn) } } slh.End() @@ -796,13 +856,15 @@ func (f decFnInfo) kSlice(rv reflect.Value) { } } -func (f decFnInfo) kArray(rv reflect.Value) { +func (f *decFnInfo) kArray(rv reflect.Value) { // f.d.decodeValue(rv.Slice(0, rv.Len())) f.kSlice(rv.Slice(0, rv.Len())) } -func (f decFnInfo) kMap(rv reflect.Value) { - containerLen := f.dd.ReadMapStart() +func (f *decFnInfo) kMap(rv reflect.Value) { + d := f.d + dd := d.d + containerLen := dd.ReadMapStart() ti := f.ti if rv.IsNil() { @@ -810,15 +872,14 @@ func (f decFnInfo) kMap(rv reflect.Value) { } if containerLen == 0 { - // f.dd.ReadMapEnd() + // It is not length-prefix style container. They have no End marker. + // dd.ReadMapEnd() return } - d := f.d - ktype, vtype := ti.rt.Key(), ti.rt.Elem() ktypeId := reflect.ValueOf(ktype).Pointer() - var keyFn, valFn decFn + var keyFn, valFn *decFn var xtyp reflect.Type for xtyp = ktype; xtyp.Kind() == reflect.Ptr; xtyp = xtyp.Elem() { } @@ -848,10 +909,7 @@ func (f decFnInfo) kMap(rv reflect.Value) { rv.SetMapIndex(rvk, rvv) } } else { - for j := 0; !f.dd.CheckBreak(); j++ { - if j > 0 { - f.dd.ReadMapEntrySeparator() - } + for j := 0; !dd.CheckBreak(); j++ { rvk := reflect.New(ktype).Elem() d.decodeValue(rvk, keyFn) @@ -866,15 +924,14 @@ func (f decFnInfo) kMap(rv reflect.Value) { if !rvv.IsValid() { rvv = reflect.New(vtype).Elem() } - f.dd.ReadMapKVSeparator() d.decodeValue(rvv, valFn) rv.SetMapIndex(rvk, rvv) } - f.dd.ReadMapEnd() + dd.ReadEnd() } } -type rtidDecFn struct { +type decRtidFn struct { rtid uintptr fn decFn } @@ -885,19 +942,22 @@ type Decoder struct { // Try to put things that go together to fit within a cache line (8 words). d decDriver + // NOTE: Decoder shouldn't call it's read methods, + // as the handler MAY need to do some coordination. r decReader - //sa [32]rtidDecFn - s []rtidDecFn + // sa [initCollectionCap]decRtidFn + s []decRtidFn h *BasicHandle rb bytesDecReader hh Handle be bool // is binary encoding bytes bool // is bytes reader + js bool // is json handle ri ioDecReader - f map[uintptr]decFn - _ uintptr // for alignment purposes, so next one starts from a cache line + f map[uintptr]*decFn + // _ uintptr // for alignment purposes, so next one starts from a cache line b [scratchByteArrayLen]byte } @@ -908,7 +968,7 @@ type Decoder struct { // (eg bufio.Reader, bytes.Buffer). func NewDecoder(r io.Reader, h Handle) (d *Decoder) { d = &Decoder{hh: h, h: h.getBasicHandle(), be: h.isBinary()} - //d.s = d.sa[:0] + // d.s = d.sa[:0] d.ri.x = &d.b d.ri.bs.r = r var ok bool @@ -917,6 +977,7 @@ func NewDecoder(r io.Reader, h Handle) (d *Decoder) { d.ri.br = &d.ri.bs } d.r = &d.ri + _, d.js = h.(*JsonHandle) d.d = h.newDecDriver(d) return } @@ -925,10 +986,11 @@ func NewDecoder(r io.Reader, h Handle) (d *Decoder) { // from a byte slice with zero copying. func NewDecoderBytes(in []byte, h Handle) (d *Decoder) { d = &Decoder{hh: h, h: h.getBasicHandle(), be: h.isBinary(), bytes: true} - //d.s = d.sa[:0] + // d.s = d.sa[:0] d.rb.b = in d.rb.a = len(in) d.r = &d.rb + _, d.js = h.(*JsonHandle) d.d = h.newDecDriver(d) // d.d = h.newDecDriver(decReaderT{true, &d.rb, &d.ri}) return @@ -993,7 +1055,7 @@ func (d *Decoder) Decode(v interface{}) (err error) { // this is not a smart swallow, as it allocates objects and does unnecessary work. func (d *Decoder) swallowViaHammer() { var blank interface{} - d.decodeValue(reflect.ValueOf(&blank).Elem(), decFn{}) + d.decodeValue(reflect.ValueOf(&blank).Elem(), nil) } func (d *Decoder) swallow() { @@ -1012,14 +1074,10 @@ func (d *Decoder) swallow() { } else if dd.CheckBreak() { break } - if j > 0 { - dd.ReadMapEntrySeparator() - } d.swallow() - dd.ReadMapKVSeparator() d.swallow() } - dd.ReadMapEnd() + dd.ReadEnd() case dd.IsContainerType(valueTypeArray): containerLenS := dd.ReadArrayStart() clenGtEqualZero := containerLenS >= 0 @@ -1031,12 +1089,9 @@ func (d *Decoder) swallow() { } else if dd.CheckBreak() { break } - if j > 0 { - dd.ReadArrayEntrySeparator() - } d.swallow() } - dd.ReadArrayEnd() + dd.ReadEnd() case dd.IsContainerType(valueTypeBytes): dd.DecodeBytes(d.b[:], false, true) case dd.IsContainerType(valueTypeString): @@ -1120,7 +1175,7 @@ func (d *Decoder) decode(iv interface{}) { case reflect.Value: d.chkPtrValue(v) - d.decodeValueNotNil(v.Elem(), decFn{}) + d.decodeValueNotNil(v.Elem(), nil) case *string: @@ -1155,7 +1210,7 @@ func (d *Decoder) decode(iv interface{}) { *v = d.d.DecodeBytes(*v, false, false) case *interface{}: - d.decodeValueNotNil(reflect.ValueOf(iv).Elem(), decFn{}) + d.decodeValueNotNil(reflect.ValueOf(iv).Elem(), nil) default: if !fastpathDecodeTypeSwitch(iv, d) { @@ -1194,29 +1249,29 @@ func (d *Decoder) decodeI(iv interface{}, checkPtr, tryNil, checkFastpath, check rv, proceed := d.preDecodeValue(rv, tryNil) if proceed { fn := d.getDecFn(rv.Type(), checkFastpath, checkCodecSelfer) - fn.f(fn.i, rv) + fn.f(&fn.i, rv) } } -func (d *Decoder) decodeValue(rv reflect.Value, fn decFn) { +func (d *Decoder) decodeValue(rv reflect.Value, fn *decFn) { if rv, proceed := d.preDecodeValue(rv, true); proceed { - if fn.f == nil { + if fn == nil { fn = d.getDecFn(rv.Type(), true, true) } - fn.f(fn.i, rv) + fn.f(&fn.i, rv) } } -func (d *Decoder) decodeValueNotNil(rv reflect.Value, fn decFn) { +func (d *Decoder) decodeValueNotNil(rv reflect.Value, fn *decFn) { if rv, proceed := d.preDecodeValue(rv, false); proceed { - if fn.f == nil { + if fn == nil { fn = d.getDecFn(rv.Type(), true, true) } - fn.f(fn.i, rv) + fn.f(&fn.i, rv) } } -func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn decFn) { +func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn *decFn) { rtid := reflect.ValueOf(rt).Pointer() // retrieve or register a focus'ed function for this type @@ -1227,9 +1282,10 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool if useMapForCodecCache { fn, ok = d.f[rtid] } else { - for _, v := range d.s { + for i := range d.s { + v := &(d.s[i]) if v.rtid == rtid { - fn, ok = v.fn, true + fn, ok = &(v.fn), true break } } @@ -1238,11 +1294,25 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool return } + if useMapForCodecCache { + if d.f == nil { + d.f = make(map[uintptr]*decFn, initCollectionCap) + } + fn = new(decFn) + d.f[rtid] = fn + } else { + if d.s == nil { + d.s = make([]decRtidFn, 0, initCollectionCap) + } + d.s = append(d.s, decRtidFn{rtid: rtid}) + fn = &(d.s[len(d.s)-1]).fn + } + // debugf("\tCreating new dec fn for type: %v\n", rt) - ti := getTypeInfo(rtid, rt) - var fi decFnInfo - fi.dd = d.d - // fi.decFnInfoX = new(decFnInfoX) + ti := d.h.getTypeInfo(rtid, rt) + fi := &(fn.i) + fi.d = d + fi.ti = ti // An extension can be registered for any type, regardless of the Kind // (e.g. type BitSet int64, type MyStruct { / * unexported fields * / }, type X []int, etc. @@ -1254,31 +1324,26 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool // NOTE: if decoding into a nil interface{}, we return a non-nil // value except even if the container registers a length of 0. if checkCodecSelfer && ti.cs { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).selferUnmarshal + fn.f = (*decFnInfo).selferUnmarshal } else if rtid == rawExtTypId { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).rawExt + fn.f = (*decFnInfo).rawExt } else if d.d.IsBuiltinType(rtid) { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).builtin + fn.f = (*decFnInfo).builtin } else if xfFn := d.h.getExt(rtid); xfFn != nil { - // fi.decFnInfoX = &decFnInfoX{xfTag: xfFn.tag, xfFn: xfFn.ext} - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} fi.xfTag, fi.xfFn = xfFn.tag, xfFn.ext - fn.f = (decFnInfo).ext + fn.f = (*decFnInfo).ext } else if supportMarshalInterfaces && d.be && ti.bunm { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).binaryUnmarshal + fn.f = (*decFnInfo).binaryUnmarshal + } else if supportMarshalInterfaces && !d.be && d.js && ti.junm { + //If JSON, we should check JSONUnmarshal before textUnmarshal + fn.f = (*decFnInfo).jsonUnmarshal } else if supportMarshalInterfaces && !d.be && ti.tunm { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).textUnmarshal + fn.f = (*decFnInfo).textUnmarshal } else { rk := rt.Kind() if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) { if rt.PkgPath() == "" { if idx := fastpathAV.index(rtid); idx != -1 { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} fn.f = fastpathAV[idx].decfn } } else { @@ -1294,8 +1359,7 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool if idx := fastpathAV.index(rtuid); idx != -1 { xfnf := fastpathAV[idx].decfn xrt := fastpathAV[idx].rt - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = func(xf decFnInfo, xrv reflect.Value) { + fn.f = func(xf *decFnInfo, xrv reflect.Value) { // xfnf(xf, xrv.Convert(xrt)) xfnf(xf, xrv.Addr().Convert(reflect.PtrTo(xrt)).Elem()) } @@ -1305,72 +1369,58 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool if fn.f == nil { switch rk { case reflect.String: - fn.f = (decFnInfo).kString + fn.f = (*decFnInfo).kString case reflect.Bool: - fn.f = (decFnInfo).kBool + fn.f = (*decFnInfo).kBool case reflect.Int: - fn.f = (decFnInfo).kInt + fn.f = (*decFnInfo).kInt case reflect.Int64: - fn.f = (decFnInfo).kInt64 + fn.f = (*decFnInfo).kInt64 case reflect.Int32: - fn.f = (decFnInfo).kInt32 + fn.f = (*decFnInfo).kInt32 case reflect.Int8: - fn.f = (decFnInfo).kInt8 + fn.f = (*decFnInfo).kInt8 case reflect.Int16: - fn.f = (decFnInfo).kInt16 + fn.f = (*decFnInfo).kInt16 case reflect.Float32: - fn.f = (decFnInfo).kFloat32 + fn.f = (*decFnInfo).kFloat32 case reflect.Float64: - fn.f = (decFnInfo).kFloat64 + fn.f = (*decFnInfo).kFloat64 case reflect.Uint8: - fn.f = (decFnInfo).kUint8 + fn.f = (*decFnInfo).kUint8 case reflect.Uint64: - fn.f = (decFnInfo).kUint64 + fn.f = (*decFnInfo).kUint64 case reflect.Uint: - fn.f = (decFnInfo).kUint + fn.f = (*decFnInfo).kUint case reflect.Uint32: - fn.f = (decFnInfo).kUint32 + fn.f = (*decFnInfo).kUint32 case reflect.Uint16: - fn.f = (decFnInfo).kUint16 + fn.f = (*decFnInfo).kUint16 // case reflect.Ptr: - // fn.f = (decFnInfo).kPtr + // fn.f = (*decFnInfo).kPtr + case reflect.Uintptr: + fn.f = (*decFnInfo).kUintptr case reflect.Interface: - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).kInterface + fn.f = (*decFnInfo).kInterface case reflect.Struct: - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).kStruct + fn.f = (*decFnInfo).kStruct case reflect.Chan: - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti, seq: seqTypeChan} - fn.f = (decFnInfo).kSlice + fi.seq = seqTypeChan + fn.f = (*decFnInfo).kSlice case reflect.Slice: - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti, seq: seqTypeSlice} - fn.f = (decFnInfo).kSlice + fi.seq = seqTypeSlice + fn.f = (*decFnInfo).kSlice case reflect.Array: - // fi.decFnInfoX = &decFnInfoX{array: true} - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti, seq: seqTypeArray} - fn.f = (decFnInfo).kArray + fi.seq = seqTypeArray + fn.f = (*decFnInfo).kArray case reflect.Map: - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).kMap + fn.f = (*decFnInfo).kMap default: - fn.f = (decFnInfo).kErr + fn.f = (*decFnInfo).kErr } } } - fn.i = fi - if useMapForCodecCache { - if d.f == nil { - d.f = make(map[uintptr]decFn, 32) - } - d.f[rtid] = fn - } else { - if d.s == nil { - d.s = make([]rtidDecFn, 0, 32) - } - d.s = append(d.s, rtidDecFn{rtid, fn}) - } return } @@ -1415,7 +1465,10 @@ func (d *Decoder) error(err error) { } func (d *Decoder) errorf(format string, params ...interface{}) { - err := fmt.Errorf(format, params...) + params2 := make([]interface{}, len(params)+1) + params2[0] = d.r.numread() + copy(params2[1:], params) + err := fmt.Errorf("[pos %d]: "+format, params2...) panic(err) } @@ -1442,30 +1495,10 @@ func (d *Decoder) decSliceHelperStart() (x decSliceHelper, clen int) { return } -func (x decSliceHelper) Sep(index int) { - if x.ct == valueTypeArray { - x.dd.ReadArrayEntrySeparator() - } else { - if index%2 == 0 { - x.dd.ReadMapEntrySeparator() - } else { - x.dd.ReadMapKVSeparator() - } - } -} - func (x decSliceHelper) End() { - if x.ct == valueTypeArray { - x.dd.ReadArrayEnd() - } else { - x.dd.ReadMapEnd() - } + x.dd.ReadEnd() } -// func decErr(format string, params ...interface{}) { -// doPanic(msgTagDec, format, params...) -// } - func decByteSlice(r decReader, clen int, bs []byte) (bsOut []byte) { if clen == 0 { return zeroByteSlice @@ -1496,6 +1529,46 @@ func detachZeroCopyBytes(isBytesReader bool, dest []byte, in []byte) (out []byte return in } +// decInferLen will infer a sensible length, given the following: +// - clen: length wanted. +// - maxlen: max length to be returned. +// if <= 0, it is unset, and we infer it based on the unit size +// - unit: number of bytes for each element of the collection +func decInferLen(clen, maxlen, unit int) (rvlen int, truncated bool) { + // handle when maxlen is not set i.e. <= 0 + if clen <= 0 { + return + } + if maxlen <= 0 { + // no maxlen defined. Use maximum of 256K memory, with a floor of 4K items. + // maxlen = 256 * 1024 / unit + // if maxlen < (4 * 1024) { + // maxlen = 4 * 1024 + // } + if unit < (256 / 4) { + maxlen = 256 * 1024 / unit + } else { + maxlen = 4 * 1024 + } + } + if clen > maxlen { + rvlen = maxlen + truncated = true + } else { + rvlen = clen + } + return + // if clen <= 0 { + // rvlen = 0 + // } else if maxlen > 0 && clen > maxlen { + // rvlen = maxlen + // truncated = true + // } else { + // rvlen = clen + // } + // return +} + // // implement overall decReader wrapping both, for possible use inline: // type decReaderT struct { // bytes bool @@ -1514,37 +1587,5 @@ func detachZeroCopyBytes(isBytesReader bool, dest []byte, in []byte) (out []byte // d.ri.unreadn1() // } // } - -// func (d *Decoder) readb(b []byte) { -// if d.bytes { -// d.rb.readb(b) -// } else { -// d.ri.readb(b) -// } -// } - -// func (d *Decoder) readx(n int) []byte { -// if d.bytes { -// return d.rb.readx(n) -// } else { -// return d.ri.readx(n) -// } -// } - -// func (d *Decoder) readn1() uint8 { -// if d.bytes { -// return d.rb.readn1() -// } else { -// return d.ri.readn1() -// } -// } - -// func (d *Decoder) readn1eof() (v uint8, eof bool) { -// if d.bytes { -// return d.rb.readn1eof() -// } else { -// return d.ri.readn1eof() -// } -// } - -// var _ decReader = (*Decoder)(nil) // decReaderT{} // +// ... for other methods of decReader. +// Testing showed that performance improvement was negligible. diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/encode.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/encode.go index 803c9d1827db..9f1def5dc7ce 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/encode.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/encode.go @@ -1,12 +1,11 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec import ( "bytes" "encoding" - "errors" "fmt" "io" "reflect" @@ -63,12 +62,8 @@ type encDriver interface { EncodeRawExt(re *RawExt, e *Encoder) EncodeExt(v interface{}, xtag uint64, ext Ext, e *Encoder) EncodeArrayStart(length int) - EncodeArrayEnd() - EncodeArrayEntrySeparator() EncodeMapStart(length int) - EncodeMapEnd() - EncodeMapEntrySeparator() - EncodeMapKVSeparator() + EncodeEnd() EncodeString(c charEncoding, v string) EncodeSymbol(v string) EncodeStringBytes(c charEncoding, v []byte) @@ -77,13 +72,13 @@ type encDriver interface { //encStringRunes(c charEncoding, v []rune) } +type encDriverAsis interface { + EncodeAsis(v []byte) +} + type encNoSeparator struct{} -func (_ encNoSeparator) EncodeMapEnd() {} -func (_ encNoSeparator) EncodeArrayEnd() {} -func (_ encNoSeparator) EncodeArrayEntrySeparator() {} -func (_ encNoSeparator) EncodeMapEntrySeparator() {} -func (_ encNoSeparator) EncodeMapKVSeparator() {} +func (_ encNoSeparator) EncodeEnd() {} type encStructFieldBytesV struct { b []byte @@ -113,8 +108,9 @@ type EncodeOptions struct { // Canonical representation means that encoding a value will always result in the same // sequence of bytes. // - // This mostly will apply to maps. In this case, codec will do more work to encode the - // map keys out of band, and then sort them, before writing out the map to the stream. + // This only affects maps, as the iteration order for maps is random. + // In this case, the map keys will first be encoded into []byte, and then sorted, + // before writing the sorted keys and the corresponding map values to the stream. Canonical bool // AsSymbols defines what should be encoded as symbols. @@ -249,10 +245,10 @@ func (z *bytesEncWriter) grow(n int) (oldcursor int) { z.c = oldcursor + n if z.c > len(z.b) { if z.c > cap(z.b) { - // Tried using appendslice logic: (if cap < 1024, *2, else *1.25). - // However, it was too expensive, causing too many iterations of copy. - // Using bytes.Buffer model was much better (2*cap + n) - bs := make([]byte, 2*cap(z.b)+n) + // appendslice logic (if cap < 1024, *2, else *1.25): more expensive. many copy calls. + // bytes.Buffer model (2*cap + n): much better + // bs := make([]byte, 2*cap(z.b)+n) + bs := make([]byte, growCap(cap(z.b), 1, n)) copy(bs, z.b[:oldcursor]) z.b = bs } else { @@ -264,7 +260,7 @@ func (z *bytesEncWriter) grow(n int) (oldcursor int) { // --------------------------------------------- -type encFnInfoX struct { +type encFnInfo struct { e *Encoder ti *typeInfo xfFn Ext @@ -272,25 +268,13 @@ type encFnInfoX struct { seq seqType } -type encFnInfo struct { - // use encFnInfo as a value receiver. - // keep most of it less-used variables accessible via a pointer (*encFnInfoX). - // As sweet spot for value-receiver is 3 words, keep everything except - // encDriver (which everyone needs) directly accessible. - // ensure encFnInfoX is set for everyone who needs it i.e. - // rawExt, ext, builtin, (selfer|binary|text)Marshal, kSlice, kStruct, kMap, kInterface, fastpath - - ee encDriver - *encFnInfoX +func (f *encFnInfo) builtin(rv reflect.Value) { + f.e.e.EncodeBuiltin(f.ti.rtid, rv.Interface()) } -func (f encFnInfo) builtin(rv reflect.Value) { - f.ee.EncodeBuiltin(f.ti.rtid, rv.Interface()) -} - -func (f encFnInfo) rawExt(rv reflect.Value) { +func (f *encFnInfo) rawExt(rv reflect.Value) { // rev := rv.Interface().(RawExt) - // f.ee.EncodeRawExt(&rev, f.e) + // f.e.e.EncodeRawExt(&rev, f.e) var re *RawExt if rv.CanAddr() { re = rv.Addr().Interface().(*RawExt) @@ -298,26 +282,35 @@ func (f encFnInfo) rawExt(rv reflect.Value) { rev := rv.Interface().(RawExt) re = &rev } - f.ee.EncodeRawExt(re, f.e) + f.e.e.EncodeRawExt(re, f.e) } -func (f encFnInfo) ext(rv reflect.Value) { - // if this is a struct and it was addressable, then pass the address directly (not the value) - if rv.CanAddr() && rv.Kind() == reflect.Struct { +func (f *encFnInfo) ext(rv reflect.Value) { + // if this is a struct|array and it was addressable, then pass the address directly (not the value) + if k := rv.Kind(); (k == reflect.Struct || k == reflect.Array) && rv.CanAddr() { rv = rv.Addr() } - f.ee.EncodeExt(rv.Interface(), f.xfTag, f.xfFn, f.e) + f.e.e.EncodeExt(rv.Interface(), f.xfTag, f.xfFn, f.e) } -func (f encFnInfo) getValueForMarshalInterface(rv reflect.Value, indir int8) (v interface{}, proceed bool) { +func (f *encFnInfo) getValueForMarshalInterface(rv reflect.Value, indir int8) (v interface{}, proceed bool) { if indir == 0 { v = rv.Interface() } else if indir == -1 { - v = rv.Addr().Interface() + // If a non-pointer was passed to Encode(), then that value is not addressable. + // Take addr if addresable, else copy value to an addressable value. + if rv.CanAddr() { + v = rv.Addr().Interface() + } else { + rv2 := reflect.New(rv.Type()) + rv2.Elem().Set(rv) + v = rv2.Interface() + // fmt.Printf("rv.Type: %v, rv2.Type: %v, v: %v\n", rv.Type(), rv2.Type(), v) + } } else { for j := int8(0); j < indir; j++ { if rv.IsNil() { - f.ee.EncodeNil() + f.e.e.EncodeNil() return } rv = rv.Elem() @@ -327,74 +320,67 @@ func (f encFnInfo) getValueForMarshalInterface(rv reflect.Value, indir int8) (v return v, true } -func (f encFnInfo) selferMarshal(rv reflect.Value) { +func (f *encFnInfo) selferMarshal(rv reflect.Value) { if v, proceed := f.getValueForMarshalInterface(rv, f.ti.csIndir); proceed { v.(Selfer).CodecEncodeSelf(f.e) } } -func (f encFnInfo) binaryMarshal(rv reflect.Value) { +func (f *encFnInfo) binaryMarshal(rv reflect.Value) { if v, proceed := f.getValueForMarshalInterface(rv, f.ti.bmIndir); proceed { bs, fnerr := v.(encoding.BinaryMarshaler).MarshalBinary() - if fnerr != nil { - panic(fnerr) - } - if bs == nil { - f.ee.EncodeNil() - } else { - f.ee.EncodeStringBytes(c_RAW, bs) - } + f.e.marshal(bs, fnerr, false, c_RAW) } } -func (f encFnInfo) textMarshal(rv reflect.Value) { +func (f *encFnInfo) textMarshal(rv reflect.Value) { if v, proceed := f.getValueForMarshalInterface(rv, f.ti.tmIndir); proceed { // debugf(">>>> encoding.TextMarshaler: %T", rv.Interface()) bs, fnerr := v.(encoding.TextMarshaler).MarshalText() - if fnerr != nil { - panic(fnerr) - } - if bs == nil { - f.ee.EncodeNil() - } else { - f.ee.EncodeStringBytes(c_UTF8, bs) - } + f.e.marshal(bs, fnerr, false, c_UTF8) } } -func (f encFnInfo) kBool(rv reflect.Value) { - f.ee.EncodeBool(rv.Bool()) +func (f *encFnInfo) jsonMarshal(rv reflect.Value) { + if v, proceed := f.getValueForMarshalInterface(rv, f.ti.jmIndir); proceed { + bs, fnerr := v.(jsonMarshaler).MarshalJSON() + f.e.marshal(bs, fnerr, true, c_UTF8) + } +} + +func (f *encFnInfo) kBool(rv reflect.Value) { + f.e.e.EncodeBool(rv.Bool()) } -func (f encFnInfo) kString(rv reflect.Value) { - f.ee.EncodeString(c_UTF8, rv.String()) +func (f *encFnInfo) kString(rv reflect.Value) { + f.e.e.EncodeString(c_UTF8, rv.String()) } -func (f encFnInfo) kFloat64(rv reflect.Value) { - f.ee.EncodeFloat64(rv.Float()) +func (f *encFnInfo) kFloat64(rv reflect.Value) { + f.e.e.EncodeFloat64(rv.Float()) } -func (f encFnInfo) kFloat32(rv reflect.Value) { - f.ee.EncodeFloat32(float32(rv.Float())) +func (f *encFnInfo) kFloat32(rv reflect.Value) { + f.e.e.EncodeFloat32(float32(rv.Float())) } -func (f encFnInfo) kInt(rv reflect.Value) { - f.ee.EncodeInt(rv.Int()) +func (f *encFnInfo) kInt(rv reflect.Value) { + f.e.e.EncodeInt(rv.Int()) } -func (f encFnInfo) kUint(rv reflect.Value) { - f.ee.EncodeUint(rv.Uint()) +func (f *encFnInfo) kUint(rv reflect.Value) { + f.e.e.EncodeUint(rv.Uint()) } -func (f encFnInfo) kInvalid(rv reflect.Value) { - f.ee.EncodeNil() +func (f *encFnInfo) kInvalid(rv reflect.Value) { + f.e.e.EncodeNil() } -func (f encFnInfo) kErr(rv reflect.Value) { +func (f *encFnInfo) kErr(rv reflect.Value) { f.e.errorf("unsupported kind %s, for %#v", rv.Kind(), rv) } -func (f encFnInfo) kSlice(rv reflect.Value) { +func (f *encFnInfo) kSlice(rv reflect.Value) { ti := f.ti // array may be non-addressable, so we have to manage with care // (don't call rv.Bytes, rv.Slice, etc). @@ -402,13 +388,13 @@ func (f encFnInfo) kSlice(rv reflect.Value) { // Encode(S{}) will bomb on "panic: slice of unaddressable array". if f.seq != seqTypeArray { if rv.IsNil() { - f.ee.EncodeNil() + f.e.e.EncodeNil() return } // If in this method, then there was no extension function defined. // So it's okay to treat as []byte. if ti.rtid == uint8SliceTypId { - f.ee.EncodeStringBytes(c_RAW, rv.Bytes()) + f.e.e.EncodeStringBytes(c_RAW, rv.Bytes()) return } } @@ -417,9 +403,9 @@ func (f encFnInfo) kSlice(rv reflect.Value) { if rtelem.Kind() == reflect.Uint8 { switch f.seq { case seqTypeArray: - // if l == 0 { f.ee.encodeStringBytes(c_RAW, nil) } else + // if l == 0 { f.e.e.encodeStringBytes(c_RAW, nil) } else if rv.CanAddr() { - f.ee.EncodeStringBytes(c_RAW, rv.Slice(0, l).Bytes()) + f.e.e.EncodeStringBytes(c_RAW, rv.Slice(0, l).Bytes()) } else { var bs []byte if l <= cap(f.e.b) { @@ -432,10 +418,10 @@ func (f encFnInfo) kSlice(rv reflect.Value) { // for i := 0; i < l; i++ { // bs[i] = byte(rv.Index(i).Uint()) // } - f.ee.EncodeStringBytes(c_RAW, bs) + f.e.e.EncodeStringBytes(c_RAW, bs) } case seqTypeSlice: - f.ee.EncodeStringBytes(c_RAW, rv.Bytes()) + f.e.e.EncodeStringBytes(c_RAW, rv.Bytes()) case seqTypeChan: bs := f.e.b[:0] // do not use range, so that the number of elements encoded @@ -447,7 +433,7 @@ func (f encFnInfo) kSlice(rv reflect.Value) { for i := 0; i < l; i++ { bs = append(bs, <-ch) } - f.ee.EncodeStringBytes(c_RAW, bs) + f.e.e.EncodeStringBytes(c_RAW, bs) } return } @@ -457,13 +443,12 @@ func (f encFnInfo) kSlice(rv reflect.Value) { f.e.errorf("mapBySlice requires even slice length, but got %v", l) return } - f.ee.EncodeMapStart(l / 2) + f.e.e.EncodeMapStart(l / 2) } else { - f.ee.EncodeArrayStart(l) + f.e.e.EncodeArrayStart(l) } e := f.e - sep := !e.be if l > 0 { for rtelem.Kind() == reflect.Ptr { rtelem = rtelem.Elem() @@ -471,88 +456,38 @@ func (f encFnInfo) kSlice(rv reflect.Value) { // if kind is reflect.Interface, do not pre-determine the // encoding type, because preEncodeValue may break it down to // a concrete type and kInterface will bomb. - var fn encFn + var fn *encFn if rtelem.Kind() != reflect.Interface { rtelemid := reflect.ValueOf(rtelem).Pointer() fn = e.getEncFn(rtelemid, rtelem, true, true) } // TODO: Consider perf implication of encoding odd index values as symbols if type is string - if sep { - for j := 0; j < l; j++ { - if j > 0 { - if ti.mbs { - if j%2 == 0 { - f.ee.EncodeMapEntrySeparator() - } else { - f.ee.EncodeMapKVSeparator() - } - } else { - f.ee.EncodeArrayEntrySeparator() - } - } - if f.seq == seqTypeChan { - if rv2, ok2 := rv.Recv(); ok2 { - e.encodeValue(rv2, fn) - } - } else { - e.encodeValue(rv.Index(j), fn) - } - } - } else { - for j := 0; j < l; j++ { - if f.seq == seqTypeChan { - if rv2, ok2 := rv.Recv(); ok2 { - e.encodeValue(rv2, fn) - } - } else { - e.encodeValue(rv.Index(j), fn) + for j := 0; j < l; j++ { + if f.seq == seqTypeChan { + if rv2, ok2 := rv.Recv(); ok2 { + e.encodeValue(rv2, fn) } + } else { + e.encodeValue(rv.Index(j), fn) } } - } - if sep { - if ti.mbs { - f.ee.EncodeMapEnd() - } else { - f.ee.EncodeArrayEnd() - } } + + f.e.e.EncodeEnd() } -func (f encFnInfo) kStruct(rv reflect.Value) { +func (f *encFnInfo) kStruct(rv reflect.Value) { fti := f.ti e := f.e tisfi := fti.sfip toMap := !(fti.toArray || e.h.StructToArray) newlen := len(fti.sfi) + // Use sync.Pool to reduce allocating slices unnecessarily. // The cost of the occasional locking is less than the cost of locking. + pool, poolv, fkvs := encStructPoolGet(newlen) - var fkvs []encStructFieldKV - var pool *sync.Pool - var poolv interface{} - idxpool := newlen / 8 - if encStructPoolLen != 4 { - panic(errors.New("encStructPoolLen must be equal to 4")) // defensive, in case it is changed - } - if idxpool < encStructPoolLen { - pool = &encStructPool[idxpool] - poolv = pool.Get() - switch vv := poolv.(type) { - case *[8]encStructFieldKV: - fkvs = vv[:newlen] - case *[16]encStructFieldKV: - fkvs = vv[:newlen] - case *[32]encStructFieldKV: - fkvs = vv[:newlen] - case *[64]encStructFieldKV: - fkvs = vv[:newlen] - } - } - if fkvs == nil { - fkvs = make([]encStructFieldKV, newlen) - } // if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct) if toMap { tisfi = fti.sfi @@ -587,60 +522,30 @@ func (f encFnInfo) kStruct(rv reflect.Value) { } // debugf(">>>> kStruct: newlen: %v", newlen) - sep := !e.be - ee := f.ee //don't dereference everytime - if sep { - if toMap { - ee.EncodeMapStart(newlen) - // asSymbols := e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 - asSymbols := e.h.AsSymbols == AsSymbolDefault || e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 - for j := 0; j < newlen; j++ { - kv = fkvs[j] - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(kv.k) - } else { - ee.EncodeString(c_UTF8, kv.k) - } - ee.EncodeMapKVSeparator() - e.encodeValue(kv.v, encFn{}) - } - ee.EncodeMapEnd() - } else { - ee.EncodeArrayStart(newlen) - for j := 0; j < newlen; j++ { - kv = fkvs[j] - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - e.encodeValue(kv.v, encFn{}) + // sep := !e.be + ee := f.e.e //don't dereference everytime + + if toMap { + ee.EncodeMapStart(newlen) + // asSymbols := e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 + asSymbols := e.h.AsSymbols == AsSymbolDefault || e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 + for j := 0; j < newlen; j++ { + kv = fkvs[j] + if asSymbols { + ee.EncodeSymbol(kv.k) + } else { + ee.EncodeString(c_UTF8, kv.k) } - ee.EncodeArrayEnd() + e.encodeValue(kv.v, nil) } } else { - if toMap { - ee.EncodeMapStart(newlen) - // asSymbols := e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 - asSymbols := e.h.AsSymbols == AsSymbolDefault || e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 - for j := 0; j < newlen; j++ { - kv = fkvs[j] - if asSymbols { - ee.EncodeSymbol(kv.k) - } else { - ee.EncodeString(c_UTF8, kv.k) - } - e.encodeValue(kv.v, encFn{}) - } - } else { - ee.EncodeArrayStart(newlen) - for j := 0; j < newlen; j++ { - kv = fkvs[j] - e.encodeValue(kv.v, encFn{}) - } + ee.EncodeArrayStart(newlen) + for j := 0; j < newlen; j++ { + kv = fkvs[j] + e.encodeValue(kv.v, nil) } } + ee.EncodeEnd() // do not use defer. Instead, use explicit pool return at end of function. // defer has a cost we are trying to avoid. @@ -650,37 +555,35 @@ func (f encFnInfo) kStruct(rv reflect.Value) { } } -// func (f encFnInfo) kPtr(rv reflect.Value) { +// func (f *encFnInfo) kPtr(rv reflect.Value) { // debugf(">>>>>>> ??? encode kPtr called - shouldn't get called") // if rv.IsNil() { -// f.ee.encodeNil() +// f.e.e.encodeNil() // return // } // f.e.encodeValue(rv.Elem()) // } -func (f encFnInfo) kInterface(rv reflect.Value) { +func (f *encFnInfo) kInterface(rv reflect.Value) { if rv.IsNil() { - f.ee.EncodeNil() + f.e.e.EncodeNil() return } - f.e.encodeValue(rv.Elem(), encFn{}) + f.e.encodeValue(rv.Elem(), nil) } -func (f encFnInfo) kMap(rv reflect.Value) { +func (f *encFnInfo) kMap(rv reflect.Value) { + ee := f.e.e if rv.IsNil() { - f.ee.EncodeNil() + ee.EncodeNil() return } l := rv.Len() - f.ee.EncodeMapStart(l) + ee.EncodeMapStart(l) e := f.e - sep := !e.be if l == 0 { - if sep { - f.ee.EncodeMapEnd() - } + ee.EncodeEnd() return } var asSymbols bool @@ -691,7 +594,7 @@ func (f encFnInfo) kMap(rv reflect.Value) { // However, if kind is reflect.Interface, do not pre-determine the // encoding type, because preEncodeValue may break it down to // a concrete type and kInterface will bomb. - var keyFn, valFn encFn + var keyFn, valFn *encFn ti := f.ti rtkey := ti.rt.Key() rtval := ti.rt.Elem() @@ -718,11 +621,10 @@ func (f encFnInfo) kMap(rv reflect.Value) { } mks := rv.MapKeys() // for j, lmks := 0, len(mks); j < lmks; j++ { - ee := f.ee //don't dereference everytime if e.h.Canonical { // first encode each key to a []byte first, then sort them, then record // println(">>>>>>>> CANONICAL <<<<<<<<") - var mksv []byte // temporary byte slice for the encoding + var mksv []byte = make([]byte, 0, len(mks)*16) // temporary byte slice for the encoding e2 := NewEncoderBytes(&mksv, e.hh) mksbv := make([]encStructFieldBytesV, len(mks)) for i, k := range mks { @@ -730,35 +632,13 @@ func (f encFnInfo) kMap(rv reflect.Value) { e2.MustEncode(k) mksbv[i].v = k mksbv[i].b = mksv[l:] + // fmt.Printf(">>>>> %s\n", mksv[l:]) } sort.Sort(encStructFieldBytesVslice(mksbv)) for j := range mksbv { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.w.writeb(mksbv[j].b) - ee.EncodeMapKVSeparator() + e.asis(mksbv[j].b) e.encodeValue(rv.MapIndex(mksbv[j].v), valFn) } - ee.EncodeMapEnd() - } else if sep { - for j := range mks { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if keyTypeIsString { - if asSymbols { - ee.EncodeSymbol(mks[j].String()) - } else { - ee.EncodeString(c_UTF8, mks[j].String()) - } - } else { - e.encodeValue(mks[j], keyFn) - } - ee.EncodeMapKVSeparator() - e.encodeValue(rv.MapIndex(mks[j]), valFn) - } - ee.EncodeMapEnd() } else { for j := range mks { if keyTypeIsString { @@ -773,6 +653,7 @@ func (f encFnInfo) kMap(rv reflect.Value) { e.encodeValue(rv.MapIndex(mks[j]), valFn) } } + ee.EncodeEnd() } // -------------------------------------------------- @@ -783,12 +664,12 @@ func (f encFnInfo) kMap(rv reflect.Value) { // instead of executing the checks every time. type encFn struct { i encFnInfo - f func(encFnInfo, reflect.Value) + f func(*encFnInfo, reflect.Value) } // -------------------------------------------------- -type rtidEncFn struct { +type encRtidFn struct { rtid uintptr fn encFn } @@ -796,17 +677,21 @@ type rtidEncFn struct { // An Encoder writes an object to an output stream in the codec format. type Encoder struct { // hopefully, reduce derefencing cost by laying the encWriter inside the Encoder - e encDriver + e encDriver + // NOTE: Encoder shouldn't call it's write methods, + // as the handler MAY need to do some coordination. w encWriter - s []rtidEncFn + s []encRtidFn be bool // is binary encoding + js bool // is json handle wi ioEncWriter wb bytesEncWriter h *BasicHandle + as encDriverAsis hh Handle - f map[uintptr]encFn + f map[uintptr]*encFn b [scratchByteArrayLen]byte } @@ -826,7 +711,9 @@ func NewEncoder(w io.Writer, h Handle) *Encoder { } e.wi.w = ww e.w = &e.wi + _, e.js = h.(*JsonHandle) e.e = h.newEncDriver(e) + e.as, _ = e.e.(encDriverAsis) return e } @@ -843,7 +730,9 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder { } e.wb.b, e.wb.out = in, out e.w = &e.wb + _, e.js = h.(*JsonHandle) e.e = h.newEncDriver(e) + e.as, _ = e.e.(encDriverAsis) return e } @@ -873,8 +762,9 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder { // The empty values (for omitempty option) are false, 0, any nil pointer // or interface value, and any array, slice, map, or string of length zero. // -// Anonymous fields are encoded inline if no struct tag is present. -// Else they are encoded as regular fields. +// Anonymous fields are encoded inline except: +// - the struct tag specifies a replacement name (first value) +// - the field is of an interface type // // Examples: // @@ -885,6 +775,9 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder { // Field2 int `codec:"myName"` //Use key "myName" in encode stream // Field3 int32 `codec:",omitempty"` //use key "Field3". Omit if empty. // Field4 bool `codec:"f4,omitempty"` //use key "f4". Omit if empty. +// io.Reader //use key "Reader". +// MyStruct `codec:"my1" //use key "my1". +// MyStruct //inline it // ... // } // @@ -894,8 +787,9 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder { // } // // The mode of encoding is based on the type of the value. When a value is seen: +// - If a Selfer, call its CodecEncodeSelf method // - If an extension is registered for it, call that extension function -// - If it implements BinaryMarshaler, call its MarshalBinary() (data []byte, err error) +// - If it implements encoding.(Binary|Text|JSON)Marshaler, call its Marshal(Binary|Text|JSON) method // - Else encode it based on its reflect.Kind // // Note that struct field names and keys in map[string]XXX will be treated as symbols. @@ -942,7 +836,7 @@ func (e *Encoder) encode(iv interface{}) { v.CodecEncodeSelf(e) case reflect.Value: - e.encodeValue(v, encFn{}) + e.encodeValue(v, nil) case string: e.e.EncodeString(c_UTF8, v) @@ -1010,12 +904,15 @@ func (e *Encoder) encode(iv interface{}) { default: // canonical mode is not supported for fastpath of maps (but is fine for slices) + const checkCodecSelfer1 = true // in case T is passed, where *T is a Selfer, still checkCodecSelfer if e.h.Canonical { if !fastpathEncodeTypeSwitchSlice(iv, e) { - e.encodeI(iv, false, false) + e.encodeI(iv, false, checkCodecSelfer1) + } + } else { + if !fastpathEncodeTypeSwitch(iv, e) { + e.encodeI(iv, false, checkCodecSelfer1) } - } else if !fastpathEncodeTypeSwitch(iv, e) { - e.encodeI(iv, false, false) } } } @@ -1025,7 +922,7 @@ func (e *Encoder) encodeI(iv interface{}, checkFastpath, checkCodecSelfer bool) rt := rv.Type() rtid := reflect.ValueOf(rt).Pointer() fn := e.getEncFn(rtid, rt, checkFastpath, checkCodecSelfer) - fn.f(fn.i, rv) + fn.f(&fn.i, rv) } } @@ -1055,27 +952,28 @@ LOOP: return rv, true } -func (e *Encoder) encodeValue(rv reflect.Value, fn encFn) { +func (e *Encoder) encodeValue(rv reflect.Value, fn *encFn) { // if a valid fn is passed, it MUST BE for the dereferenced type of rv if rv, proceed := e.preEncodeValue(rv); proceed { - if fn.f == nil { + if fn == nil { rt := rv.Type() rtid := reflect.ValueOf(rt).Pointer() fn = e.getEncFn(rtid, rt, true, true) } - fn.f(fn.i, rv) + fn.f(&fn.i, rv) } } -func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn encFn) { +func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn *encFn) { // rtid := reflect.ValueOf(rt).Pointer() var ok bool if useMapForCodecCache { fn, ok = e.f[rtid] } else { - for _, v := range e.s { + for i := range e.s { + v := &(e.s[i]) if v.rtid == rtid { - fn, ok = v.fn, true + fn, ok = &(v.fn), true break } } @@ -1083,37 +981,48 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo if ok { return } - // fi.encFnInfoX = new(encFnInfoX) - ti := getTypeInfo(rtid, rt) - var fi encFnInfo - fi.ee = e.e + + if useMapForCodecCache { + if e.f == nil { + e.f = make(map[uintptr]*encFn, initCollectionCap) + } + fn = new(encFn) + e.f[rtid] = fn + } else { + if e.s == nil { + e.s = make([]encRtidFn, 0, initCollectionCap) + } + e.s = append(e.s, encRtidFn{rtid: rtid}) + fn = &(e.s[len(e.s)-1]).fn + } + + ti := e.h.getTypeInfo(rtid, rt) + fi := &(fn.i) + fi.e = e + fi.ti = ti if checkCodecSelfer && ti.cs { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).selferMarshal + fn.f = (*encFnInfo).selferMarshal } else if rtid == rawExtTypId { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).rawExt + fn.f = (*encFnInfo).rawExt } else if e.e.IsBuiltinType(rtid) { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).builtin + fn.f = (*encFnInfo).builtin } else if xfFn := e.h.getExt(rtid); xfFn != nil { - // fi.encFnInfoX = new(encFnInfoX) - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} fi.xfTag, fi.xfFn = xfFn.tag, xfFn.ext - fn.f = (encFnInfo).ext + fn.f = (*encFnInfo).ext } else if supportMarshalInterfaces && e.be && ti.bm { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).binaryMarshal + fn.f = (*encFnInfo).binaryMarshal + } else if supportMarshalInterfaces && !e.be && e.js && ti.jm { + //If JSON, we should check JSONMarshal before textMarshal + fn.f = (*encFnInfo).jsonMarshal } else if supportMarshalInterfaces && !e.be && ti.tm { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).textMarshal + fn.f = (*encFnInfo).textMarshal } else { rk := rt.Kind() - if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) { + // if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) { + if fastpathEnabled && checkFastpath && (rk == reflect.Slice || (rk == reflect.Map && !e.h.Canonical)) { if rt.PkgPath() == "" { if idx := fastpathAV.index(rtid); idx != -1 { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} fn.f = fastpathAV[idx].encfn } } else { @@ -1129,8 +1038,7 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo if idx := fastpathAV.index(rtuid); idx != -1 { xfnf := fastpathAV[idx].encfn xrt := fastpathAV[idx].rt - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = func(xf encFnInfo, xrv reflect.Value) { + fn.f = func(xf *encFnInfo, xrv reflect.Value) { xfnf(xf, xrv.Convert(xrt)) } } @@ -1139,58 +1047,64 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo if fn.f == nil { switch rk { case reflect.Bool: - fn.f = (encFnInfo).kBool + fn.f = (*encFnInfo).kBool case reflect.String: - fn.f = (encFnInfo).kString + fn.f = (*encFnInfo).kString case reflect.Float64: - fn.f = (encFnInfo).kFloat64 + fn.f = (*encFnInfo).kFloat64 case reflect.Float32: - fn.f = (encFnInfo).kFloat32 + fn.f = (*encFnInfo).kFloat32 case reflect.Int, reflect.Int8, reflect.Int64, reflect.Int32, reflect.Int16: - fn.f = (encFnInfo).kInt - case reflect.Uint8, reflect.Uint64, reflect.Uint, reflect.Uint32, reflect.Uint16: - fn.f = (encFnInfo).kUint + fn.f = (*encFnInfo).kInt + case reflect.Uint8, reflect.Uint64, reflect.Uint, reflect.Uint32, reflect.Uint16, reflect.Uintptr: + fn.f = (*encFnInfo).kUint case reflect.Invalid: - fn.f = (encFnInfo).kInvalid + fn.f = (*encFnInfo).kInvalid case reflect.Chan: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti, seq: seqTypeChan} - fn.f = (encFnInfo).kSlice + fi.seq = seqTypeChan + fn.f = (*encFnInfo).kSlice case reflect.Slice: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti, seq: seqTypeSlice} - fn.f = (encFnInfo).kSlice + fi.seq = seqTypeSlice + fn.f = (*encFnInfo).kSlice case reflect.Array: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti, seq: seqTypeArray} - fn.f = (encFnInfo).kSlice + fi.seq = seqTypeArray + fn.f = (*encFnInfo).kSlice case reflect.Struct: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).kStruct + fn.f = (*encFnInfo).kStruct // case reflect.Ptr: - // fn.f = (encFnInfo).kPtr + // fn.f = (*encFnInfo).kPtr case reflect.Interface: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).kInterface + fn.f = (*encFnInfo).kInterface case reflect.Map: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).kMap + fn.f = (*encFnInfo).kMap default: - fn.f = (encFnInfo).kErr + fn.f = (*encFnInfo).kErr } } } - fn.i = fi - if useMapForCodecCache { - if e.f == nil { - e.f = make(map[uintptr]encFn, 32) - } - e.f[rtid] = fn + return +} + +func (e *Encoder) marshal(bs []byte, fnerr error, asis bool, c charEncoding) { + if fnerr != nil { + panic(fnerr) + } + if bs == nil { + e.e.EncodeNil() + } else if asis { + e.asis(bs) } else { - if e.s == nil { - e.s = make([]rtidEncFn, 0, 32) - } - e.s = append(e.s, rtidEncFn{rtid, fn}) + e.e.EncodeStringBytes(c, bs) + } +} + +func (e *Encoder) asis(v []byte) { + if e.as == nil { + e.w.writeb(v) + } else { + e.as.EncodeAsis(v) } - return } func (e *Encoder) errorf(format string, params ...interface{}) { @@ -1205,7 +1119,7 @@ type encStructFieldKV struct { v reflect.Value } -const encStructPoolLen = 4 +const encStructPoolLen = 5 // encStructPool is an array of sync.Pool. // Each element of the array pools one of encStructPool(8|16|32|64). @@ -1223,6 +1137,57 @@ func init() { encStructPool[1].New = func() interface{} { return new([16]encStructFieldKV) } encStructPool[2].New = func() interface{} { return new([32]encStructFieldKV) } encStructPool[3].New = func() interface{} { return new([64]encStructFieldKV) } + encStructPool[4].New = func() interface{} { return new([128]encStructFieldKV) } +} + +func encStructPoolGet(newlen int) (p *sync.Pool, v interface{}, s []encStructFieldKV) { + // if encStructPoolLen != 5 { // constant chec, so removed at build time. + // panic(errors.New("encStructPoolLen must be equal to 4")) // defensive, in case it is changed + // } + // idxpool := newlen / 8 + + // if pool == nil { + // fkvs = make([]encStructFieldKV, newlen) + // } else { + // poolv = pool.Get() + // switch vv := poolv.(type) { + // case *[8]encStructFieldKV: + // fkvs = vv[:newlen] + // case *[16]encStructFieldKV: + // fkvs = vv[:newlen] + // case *[32]encStructFieldKV: + // fkvs = vv[:newlen] + // case *[64]encStructFieldKV: + // fkvs = vv[:newlen] + // case *[128]encStructFieldKV: + // fkvs = vv[:newlen] + // } + // } + + if newlen <= 8 { + p = &encStructPool[0] + v = p.Get() + s = v.(*[8]encStructFieldKV)[:newlen] + } else if newlen <= 16 { + p = &encStructPool[1] + v = p.Get() + s = v.(*[16]encStructFieldKV)[:newlen] + } else if newlen <= 32 { + p = &encStructPool[2] + v = p.Get() + s = v.(*[32]encStructFieldKV)[:newlen] + } else if newlen <= 64 { + p = &encStructPool[3] + v = p.Get() + s = v.(*[64]encStructFieldKV)[:newlen] + } else if newlen <= 128 { + p = &encStructPool[4] + v = p.Get() + s = v.(*[128]encStructFieldKV)[:newlen] + } else { + s = make([]encStructFieldKV, newlen) + } + return } // ---------------------------------------- diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.generated.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.generated.go index efd81da29fa0..554e80b613bd 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.generated.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.generated.go @@ -1,7 +1,7 @@ // //+build ignore // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. // ************************************************************ // DO NOT EDIT. @@ -48,8 +48,8 @@ var fastpathTV fastpathT type fastpathE struct { rtid uintptr rt reflect.Type - encfn func(encFnInfo, reflect.Value) - decfn func(decFnInfo, reflect.Value) + encfn func(*encFnInfo, reflect.Value) + decfn func(*decFnInfo, reflect.Value) } type fastpathA [239]fastpathE @@ -85,7 +85,7 @@ func init() { return } i := 0 - fn := func(v interface{}, fe func(encFnInfo, reflect.Value), fd func(decFnInfo, reflect.Value)) (f fastpathE) { + fn := func(v interface{}, fe func(*encFnInfo, reflect.Value), fd func(*decFnInfo, reflect.Value)) (f fastpathE) { xrt := reflect.TypeOf(v) xptr := reflect.ValueOf(xrt).Pointer() fastpathAV[i] = fastpathE{xptr, xrt, fe, fd} @@ -93,246 +93,246 @@ func init() { return } - fn([]interface{}(nil), (encFnInfo).fastpathEncSliceIntfR, (decFnInfo).fastpathDecSliceIntfR) - fn([]string(nil), (encFnInfo).fastpathEncSliceStringR, (decFnInfo).fastpathDecSliceStringR) - fn([]float32(nil), (encFnInfo).fastpathEncSliceFloat32R, (decFnInfo).fastpathDecSliceFloat32R) - fn([]float64(nil), (encFnInfo).fastpathEncSliceFloat64R, (decFnInfo).fastpathDecSliceFloat64R) - fn([]uint(nil), (encFnInfo).fastpathEncSliceUintR, (decFnInfo).fastpathDecSliceUintR) - fn([]uint16(nil), (encFnInfo).fastpathEncSliceUint16R, (decFnInfo).fastpathDecSliceUint16R) - fn([]uint32(nil), (encFnInfo).fastpathEncSliceUint32R, (decFnInfo).fastpathDecSliceUint32R) - fn([]uint64(nil), (encFnInfo).fastpathEncSliceUint64R, (decFnInfo).fastpathDecSliceUint64R) - fn([]int(nil), (encFnInfo).fastpathEncSliceIntR, (decFnInfo).fastpathDecSliceIntR) - fn([]int8(nil), (encFnInfo).fastpathEncSliceInt8R, (decFnInfo).fastpathDecSliceInt8R) - fn([]int16(nil), (encFnInfo).fastpathEncSliceInt16R, (decFnInfo).fastpathDecSliceInt16R) - fn([]int32(nil), (encFnInfo).fastpathEncSliceInt32R, (decFnInfo).fastpathDecSliceInt32R) - fn([]int64(nil), (encFnInfo).fastpathEncSliceInt64R, (decFnInfo).fastpathDecSliceInt64R) - fn([]bool(nil), (encFnInfo).fastpathEncSliceBoolR, (decFnInfo).fastpathDecSliceBoolR) - - fn(map[interface{}]interface{}(nil), (encFnInfo).fastpathEncMapIntfIntfR, (decFnInfo).fastpathDecMapIntfIntfR) - fn(map[interface{}]string(nil), (encFnInfo).fastpathEncMapIntfStringR, (decFnInfo).fastpathDecMapIntfStringR) - fn(map[interface{}]uint(nil), (encFnInfo).fastpathEncMapIntfUintR, (decFnInfo).fastpathDecMapIntfUintR) - fn(map[interface{}]uint8(nil), (encFnInfo).fastpathEncMapIntfUint8R, (decFnInfo).fastpathDecMapIntfUint8R) - fn(map[interface{}]uint16(nil), (encFnInfo).fastpathEncMapIntfUint16R, (decFnInfo).fastpathDecMapIntfUint16R) - fn(map[interface{}]uint32(nil), (encFnInfo).fastpathEncMapIntfUint32R, (decFnInfo).fastpathDecMapIntfUint32R) - fn(map[interface{}]uint64(nil), (encFnInfo).fastpathEncMapIntfUint64R, (decFnInfo).fastpathDecMapIntfUint64R) - fn(map[interface{}]int(nil), (encFnInfo).fastpathEncMapIntfIntR, (decFnInfo).fastpathDecMapIntfIntR) - fn(map[interface{}]int8(nil), (encFnInfo).fastpathEncMapIntfInt8R, (decFnInfo).fastpathDecMapIntfInt8R) - fn(map[interface{}]int16(nil), (encFnInfo).fastpathEncMapIntfInt16R, (decFnInfo).fastpathDecMapIntfInt16R) - fn(map[interface{}]int32(nil), (encFnInfo).fastpathEncMapIntfInt32R, (decFnInfo).fastpathDecMapIntfInt32R) - fn(map[interface{}]int64(nil), (encFnInfo).fastpathEncMapIntfInt64R, (decFnInfo).fastpathDecMapIntfInt64R) - fn(map[interface{}]float32(nil), (encFnInfo).fastpathEncMapIntfFloat32R, (decFnInfo).fastpathDecMapIntfFloat32R) - fn(map[interface{}]float64(nil), (encFnInfo).fastpathEncMapIntfFloat64R, (decFnInfo).fastpathDecMapIntfFloat64R) - fn(map[interface{}]bool(nil), (encFnInfo).fastpathEncMapIntfBoolR, (decFnInfo).fastpathDecMapIntfBoolR) - fn(map[string]interface{}(nil), (encFnInfo).fastpathEncMapStringIntfR, (decFnInfo).fastpathDecMapStringIntfR) - fn(map[string]string(nil), (encFnInfo).fastpathEncMapStringStringR, (decFnInfo).fastpathDecMapStringStringR) - fn(map[string]uint(nil), (encFnInfo).fastpathEncMapStringUintR, (decFnInfo).fastpathDecMapStringUintR) - fn(map[string]uint8(nil), (encFnInfo).fastpathEncMapStringUint8R, (decFnInfo).fastpathDecMapStringUint8R) - fn(map[string]uint16(nil), (encFnInfo).fastpathEncMapStringUint16R, (decFnInfo).fastpathDecMapStringUint16R) - fn(map[string]uint32(nil), (encFnInfo).fastpathEncMapStringUint32R, (decFnInfo).fastpathDecMapStringUint32R) - fn(map[string]uint64(nil), (encFnInfo).fastpathEncMapStringUint64R, (decFnInfo).fastpathDecMapStringUint64R) - fn(map[string]int(nil), (encFnInfo).fastpathEncMapStringIntR, (decFnInfo).fastpathDecMapStringIntR) - fn(map[string]int8(nil), (encFnInfo).fastpathEncMapStringInt8R, (decFnInfo).fastpathDecMapStringInt8R) - fn(map[string]int16(nil), (encFnInfo).fastpathEncMapStringInt16R, (decFnInfo).fastpathDecMapStringInt16R) - fn(map[string]int32(nil), (encFnInfo).fastpathEncMapStringInt32R, (decFnInfo).fastpathDecMapStringInt32R) - fn(map[string]int64(nil), (encFnInfo).fastpathEncMapStringInt64R, (decFnInfo).fastpathDecMapStringInt64R) - fn(map[string]float32(nil), (encFnInfo).fastpathEncMapStringFloat32R, (decFnInfo).fastpathDecMapStringFloat32R) - fn(map[string]float64(nil), (encFnInfo).fastpathEncMapStringFloat64R, (decFnInfo).fastpathDecMapStringFloat64R) - fn(map[string]bool(nil), (encFnInfo).fastpathEncMapStringBoolR, (decFnInfo).fastpathDecMapStringBoolR) - fn(map[float32]interface{}(nil), (encFnInfo).fastpathEncMapFloat32IntfR, (decFnInfo).fastpathDecMapFloat32IntfR) - fn(map[float32]string(nil), (encFnInfo).fastpathEncMapFloat32StringR, (decFnInfo).fastpathDecMapFloat32StringR) - fn(map[float32]uint(nil), (encFnInfo).fastpathEncMapFloat32UintR, (decFnInfo).fastpathDecMapFloat32UintR) - fn(map[float32]uint8(nil), (encFnInfo).fastpathEncMapFloat32Uint8R, (decFnInfo).fastpathDecMapFloat32Uint8R) - fn(map[float32]uint16(nil), (encFnInfo).fastpathEncMapFloat32Uint16R, (decFnInfo).fastpathDecMapFloat32Uint16R) - fn(map[float32]uint32(nil), (encFnInfo).fastpathEncMapFloat32Uint32R, (decFnInfo).fastpathDecMapFloat32Uint32R) - fn(map[float32]uint64(nil), (encFnInfo).fastpathEncMapFloat32Uint64R, (decFnInfo).fastpathDecMapFloat32Uint64R) - fn(map[float32]int(nil), (encFnInfo).fastpathEncMapFloat32IntR, (decFnInfo).fastpathDecMapFloat32IntR) - fn(map[float32]int8(nil), (encFnInfo).fastpathEncMapFloat32Int8R, (decFnInfo).fastpathDecMapFloat32Int8R) - fn(map[float32]int16(nil), (encFnInfo).fastpathEncMapFloat32Int16R, (decFnInfo).fastpathDecMapFloat32Int16R) - fn(map[float32]int32(nil), (encFnInfo).fastpathEncMapFloat32Int32R, (decFnInfo).fastpathDecMapFloat32Int32R) - fn(map[float32]int64(nil), (encFnInfo).fastpathEncMapFloat32Int64R, (decFnInfo).fastpathDecMapFloat32Int64R) - fn(map[float32]float32(nil), (encFnInfo).fastpathEncMapFloat32Float32R, (decFnInfo).fastpathDecMapFloat32Float32R) - fn(map[float32]float64(nil), (encFnInfo).fastpathEncMapFloat32Float64R, (decFnInfo).fastpathDecMapFloat32Float64R) - fn(map[float32]bool(nil), (encFnInfo).fastpathEncMapFloat32BoolR, (decFnInfo).fastpathDecMapFloat32BoolR) - fn(map[float64]interface{}(nil), (encFnInfo).fastpathEncMapFloat64IntfR, (decFnInfo).fastpathDecMapFloat64IntfR) - fn(map[float64]string(nil), (encFnInfo).fastpathEncMapFloat64StringR, (decFnInfo).fastpathDecMapFloat64StringR) - fn(map[float64]uint(nil), (encFnInfo).fastpathEncMapFloat64UintR, (decFnInfo).fastpathDecMapFloat64UintR) - fn(map[float64]uint8(nil), (encFnInfo).fastpathEncMapFloat64Uint8R, (decFnInfo).fastpathDecMapFloat64Uint8R) - fn(map[float64]uint16(nil), (encFnInfo).fastpathEncMapFloat64Uint16R, (decFnInfo).fastpathDecMapFloat64Uint16R) - fn(map[float64]uint32(nil), (encFnInfo).fastpathEncMapFloat64Uint32R, (decFnInfo).fastpathDecMapFloat64Uint32R) - fn(map[float64]uint64(nil), (encFnInfo).fastpathEncMapFloat64Uint64R, (decFnInfo).fastpathDecMapFloat64Uint64R) - fn(map[float64]int(nil), (encFnInfo).fastpathEncMapFloat64IntR, (decFnInfo).fastpathDecMapFloat64IntR) - fn(map[float64]int8(nil), (encFnInfo).fastpathEncMapFloat64Int8R, (decFnInfo).fastpathDecMapFloat64Int8R) - fn(map[float64]int16(nil), (encFnInfo).fastpathEncMapFloat64Int16R, (decFnInfo).fastpathDecMapFloat64Int16R) - fn(map[float64]int32(nil), (encFnInfo).fastpathEncMapFloat64Int32R, (decFnInfo).fastpathDecMapFloat64Int32R) - fn(map[float64]int64(nil), (encFnInfo).fastpathEncMapFloat64Int64R, (decFnInfo).fastpathDecMapFloat64Int64R) - fn(map[float64]float32(nil), (encFnInfo).fastpathEncMapFloat64Float32R, (decFnInfo).fastpathDecMapFloat64Float32R) - fn(map[float64]float64(nil), (encFnInfo).fastpathEncMapFloat64Float64R, (decFnInfo).fastpathDecMapFloat64Float64R) - fn(map[float64]bool(nil), (encFnInfo).fastpathEncMapFloat64BoolR, (decFnInfo).fastpathDecMapFloat64BoolR) - fn(map[uint]interface{}(nil), (encFnInfo).fastpathEncMapUintIntfR, (decFnInfo).fastpathDecMapUintIntfR) - fn(map[uint]string(nil), (encFnInfo).fastpathEncMapUintStringR, (decFnInfo).fastpathDecMapUintStringR) - fn(map[uint]uint(nil), (encFnInfo).fastpathEncMapUintUintR, (decFnInfo).fastpathDecMapUintUintR) - fn(map[uint]uint8(nil), (encFnInfo).fastpathEncMapUintUint8R, (decFnInfo).fastpathDecMapUintUint8R) - fn(map[uint]uint16(nil), (encFnInfo).fastpathEncMapUintUint16R, (decFnInfo).fastpathDecMapUintUint16R) - fn(map[uint]uint32(nil), (encFnInfo).fastpathEncMapUintUint32R, (decFnInfo).fastpathDecMapUintUint32R) - fn(map[uint]uint64(nil), (encFnInfo).fastpathEncMapUintUint64R, (decFnInfo).fastpathDecMapUintUint64R) - fn(map[uint]int(nil), (encFnInfo).fastpathEncMapUintIntR, (decFnInfo).fastpathDecMapUintIntR) - fn(map[uint]int8(nil), (encFnInfo).fastpathEncMapUintInt8R, (decFnInfo).fastpathDecMapUintInt8R) - fn(map[uint]int16(nil), (encFnInfo).fastpathEncMapUintInt16R, (decFnInfo).fastpathDecMapUintInt16R) - fn(map[uint]int32(nil), (encFnInfo).fastpathEncMapUintInt32R, (decFnInfo).fastpathDecMapUintInt32R) - fn(map[uint]int64(nil), (encFnInfo).fastpathEncMapUintInt64R, (decFnInfo).fastpathDecMapUintInt64R) - fn(map[uint]float32(nil), (encFnInfo).fastpathEncMapUintFloat32R, (decFnInfo).fastpathDecMapUintFloat32R) - fn(map[uint]float64(nil), (encFnInfo).fastpathEncMapUintFloat64R, (decFnInfo).fastpathDecMapUintFloat64R) - fn(map[uint]bool(nil), (encFnInfo).fastpathEncMapUintBoolR, (decFnInfo).fastpathDecMapUintBoolR) - fn(map[uint8]interface{}(nil), (encFnInfo).fastpathEncMapUint8IntfR, (decFnInfo).fastpathDecMapUint8IntfR) - fn(map[uint8]string(nil), (encFnInfo).fastpathEncMapUint8StringR, (decFnInfo).fastpathDecMapUint8StringR) - fn(map[uint8]uint(nil), (encFnInfo).fastpathEncMapUint8UintR, (decFnInfo).fastpathDecMapUint8UintR) - fn(map[uint8]uint8(nil), (encFnInfo).fastpathEncMapUint8Uint8R, (decFnInfo).fastpathDecMapUint8Uint8R) - fn(map[uint8]uint16(nil), (encFnInfo).fastpathEncMapUint8Uint16R, (decFnInfo).fastpathDecMapUint8Uint16R) - fn(map[uint8]uint32(nil), (encFnInfo).fastpathEncMapUint8Uint32R, (decFnInfo).fastpathDecMapUint8Uint32R) - fn(map[uint8]uint64(nil), (encFnInfo).fastpathEncMapUint8Uint64R, (decFnInfo).fastpathDecMapUint8Uint64R) - fn(map[uint8]int(nil), (encFnInfo).fastpathEncMapUint8IntR, (decFnInfo).fastpathDecMapUint8IntR) - fn(map[uint8]int8(nil), (encFnInfo).fastpathEncMapUint8Int8R, (decFnInfo).fastpathDecMapUint8Int8R) - fn(map[uint8]int16(nil), (encFnInfo).fastpathEncMapUint8Int16R, (decFnInfo).fastpathDecMapUint8Int16R) - fn(map[uint8]int32(nil), (encFnInfo).fastpathEncMapUint8Int32R, (decFnInfo).fastpathDecMapUint8Int32R) - fn(map[uint8]int64(nil), (encFnInfo).fastpathEncMapUint8Int64R, (decFnInfo).fastpathDecMapUint8Int64R) - fn(map[uint8]float32(nil), (encFnInfo).fastpathEncMapUint8Float32R, (decFnInfo).fastpathDecMapUint8Float32R) - fn(map[uint8]float64(nil), (encFnInfo).fastpathEncMapUint8Float64R, (decFnInfo).fastpathDecMapUint8Float64R) - fn(map[uint8]bool(nil), (encFnInfo).fastpathEncMapUint8BoolR, (decFnInfo).fastpathDecMapUint8BoolR) - fn(map[uint16]interface{}(nil), (encFnInfo).fastpathEncMapUint16IntfR, (decFnInfo).fastpathDecMapUint16IntfR) - fn(map[uint16]string(nil), (encFnInfo).fastpathEncMapUint16StringR, (decFnInfo).fastpathDecMapUint16StringR) - fn(map[uint16]uint(nil), (encFnInfo).fastpathEncMapUint16UintR, (decFnInfo).fastpathDecMapUint16UintR) - fn(map[uint16]uint8(nil), (encFnInfo).fastpathEncMapUint16Uint8R, (decFnInfo).fastpathDecMapUint16Uint8R) - fn(map[uint16]uint16(nil), (encFnInfo).fastpathEncMapUint16Uint16R, (decFnInfo).fastpathDecMapUint16Uint16R) - fn(map[uint16]uint32(nil), (encFnInfo).fastpathEncMapUint16Uint32R, (decFnInfo).fastpathDecMapUint16Uint32R) - fn(map[uint16]uint64(nil), (encFnInfo).fastpathEncMapUint16Uint64R, (decFnInfo).fastpathDecMapUint16Uint64R) - fn(map[uint16]int(nil), (encFnInfo).fastpathEncMapUint16IntR, (decFnInfo).fastpathDecMapUint16IntR) - fn(map[uint16]int8(nil), (encFnInfo).fastpathEncMapUint16Int8R, (decFnInfo).fastpathDecMapUint16Int8R) - fn(map[uint16]int16(nil), (encFnInfo).fastpathEncMapUint16Int16R, (decFnInfo).fastpathDecMapUint16Int16R) - fn(map[uint16]int32(nil), (encFnInfo).fastpathEncMapUint16Int32R, (decFnInfo).fastpathDecMapUint16Int32R) - fn(map[uint16]int64(nil), (encFnInfo).fastpathEncMapUint16Int64R, (decFnInfo).fastpathDecMapUint16Int64R) - fn(map[uint16]float32(nil), (encFnInfo).fastpathEncMapUint16Float32R, (decFnInfo).fastpathDecMapUint16Float32R) - fn(map[uint16]float64(nil), (encFnInfo).fastpathEncMapUint16Float64R, (decFnInfo).fastpathDecMapUint16Float64R) - fn(map[uint16]bool(nil), (encFnInfo).fastpathEncMapUint16BoolR, (decFnInfo).fastpathDecMapUint16BoolR) - fn(map[uint32]interface{}(nil), (encFnInfo).fastpathEncMapUint32IntfR, (decFnInfo).fastpathDecMapUint32IntfR) - fn(map[uint32]string(nil), (encFnInfo).fastpathEncMapUint32StringR, (decFnInfo).fastpathDecMapUint32StringR) - fn(map[uint32]uint(nil), (encFnInfo).fastpathEncMapUint32UintR, (decFnInfo).fastpathDecMapUint32UintR) - fn(map[uint32]uint8(nil), (encFnInfo).fastpathEncMapUint32Uint8R, (decFnInfo).fastpathDecMapUint32Uint8R) - fn(map[uint32]uint16(nil), (encFnInfo).fastpathEncMapUint32Uint16R, (decFnInfo).fastpathDecMapUint32Uint16R) - fn(map[uint32]uint32(nil), (encFnInfo).fastpathEncMapUint32Uint32R, (decFnInfo).fastpathDecMapUint32Uint32R) - fn(map[uint32]uint64(nil), (encFnInfo).fastpathEncMapUint32Uint64R, (decFnInfo).fastpathDecMapUint32Uint64R) - fn(map[uint32]int(nil), (encFnInfo).fastpathEncMapUint32IntR, (decFnInfo).fastpathDecMapUint32IntR) - fn(map[uint32]int8(nil), (encFnInfo).fastpathEncMapUint32Int8R, (decFnInfo).fastpathDecMapUint32Int8R) - fn(map[uint32]int16(nil), (encFnInfo).fastpathEncMapUint32Int16R, (decFnInfo).fastpathDecMapUint32Int16R) - fn(map[uint32]int32(nil), (encFnInfo).fastpathEncMapUint32Int32R, (decFnInfo).fastpathDecMapUint32Int32R) - fn(map[uint32]int64(nil), (encFnInfo).fastpathEncMapUint32Int64R, (decFnInfo).fastpathDecMapUint32Int64R) - fn(map[uint32]float32(nil), (encFnInfo).fastpathEncMapUint32Float32R, (decFnInfo).fastpathDecMapUint32Float32R) - fn(map[uint32]float64(nil), (encFnInfo).fastpathEncMapUint32Float64R, (decFnInfo).fastpathDecMapUint32Float64R) - fn(map[uint32]bool(nil), (encFnInfo).fastpathEncMapUint32BoolR, (decFnInfo).fastpathDecMapUint32BoolR) - fn(map[uint64]interface{}(nil), (encFnInfo).fastpathEncMapUint64IntfR, (decFnInfo).fastpathDecMapUint64IntfR) - fn(map[uint64]string(nil), (encFnInfo).fastpathEncMapUint64StringR, (decFnInfo).fastpathDecMapUint64StringR) - fn(map[uint64]uint(nil), (encFnInfo).fastpathEncMapUint64UintR, (decFnInfo).fastpathDecMapUint64UintR) - fn(map[uint64]uint8(nil), (encFnInfo).fastpathEncMapUint64Uint8R, (decFnInfo).fastpathDecMapUint64Uint8R) - fn(map[uint64]uint16(nil), (encFnInfo).fastpathEncMapUint64Uint16R, (decFnInfo).fastpathDecMapUint64Uint16R) - fn(map[uint64]uint32(nil), (encFnInfo).fastpathEncMapUint64Uint32R, (decFnInfo).fastpathDecMapUint64Uint32R) - fn(map[uint64]uint64(nil), (encFnInfo).fastpathEncMapUint64Uint64R, (decFnInfo).fastpathDecMapUint64Uint64R) - fn(map[uint64]int(nil), (encFnInfo).fastpathEncMapUint64IntR, (decFnInfo).fastpathDecMapUint64IntR) - fn(map[uint64]int8(nil), (encFnInfo).fastpathEncMapUint64Int8R, (decFnInfo).fastpathDecMapUint64Int8R) - fn(map[uint64]int16(nil), (encFnInfo).fastpathEncMapUint64Int16R, (decFnInfo).fastpathDecMapUint64Int16R) - fn(map[uint64]int32(nil), (encFnInfo).fastpathEncMapUint64Int32R, (decFnInfo).fastpathDecMapUint64Int32R) - fn(map[uint64]int64(nil), (encFnInfo).fastpathEncMapUint64Int64R, (decFnInfo).fastpathDecMapUint64Int64R) - fn(map[uint64]float32(nil), (encFnInfo).fastpathEncMapUint64Float32R, (decFnInfo).fastpathDecMapUint64Float32R) - fn(map[uint64]float64(nil), (encFnInfo).fastpathEncMapUint64Float64R, (decFnInfo).fastpathDecMapUint64Float64R) - fn(map[uint64]bool(nil), (encFnInfo).fastpathEncMapUint64BoolR, (decFnInfo).fastpathDecMapUint64BoolR) - fn(map[int]interface{}(nil), (encFnInfo).fastpathEncMapIntIntfR, (decFnInfo).fastpathDecMapIntIntfR) - fn(map[int]string(nil), (encFnInfo).fastpathEncMapIntStringR, (decFnInfo).fastpathDecMapIntStringR) - fn(map[int]uint(nil), (encFnInfo).fastpathEncMapIntUintR, (decFnInfo).fastpathDecMapIntUintR) - fn(map[int]uint8(nil), (encFnInfo).fastpathEncMapIntUint8R, (decFnInfo).fastpathDecMapIntUint8R) - fn(map[int]uint16(nil), (encFnInfo).fastpathEncMapIntUint16R, (decFnInfo).fastpathDecMapIntUint16R) - fn(map[int]uint32(nil), (encFnInfo).fastpathEncMapIntUint32R, (decFnInfo).fastpathDecMapIntUint32R) - fn(map[int]uint64(nil), (encFnInfo).fastpathEncMapIntUint64R, (decFnInfo).fastpathDecMapIntUint64R) - fn(map[int]int(nil), (encFnInfo).fastpathEncMapIntIntR, (decFnInfo).fastpathDecMapIntIntR) - fn(map[int]int8(nil), (encFnInfo).fastpathEncMapIntInt8R, (decFnInfo).fastpathDecMapIntInt8R) - fn(map[int]int16(nil), (encFnInfo).fastpathEncMapIntInt16R, (decFnInfo).fastpathDecMapIntInt16R) - fn(map[int]int32(nil), (encFnInfo).fastpathEncMapIntInt32R, (decFnInfo).fastpathDecMapIntInt32R) - fn(map[int]int64(nil), (encFnInfo).fastpathEncMapIntInt64R, (decFnInfo).fastpathDecMapIntInt64R) - fn(map[int]float32(nil), (encFnInfo).fastpathEncMapIntFloat32R, (decFnInfo).fastpathDecMapIntFloat32R) - fn(map[int]float64(nil), (encFnInfo).fastpathEncMapIntFloat64R, (decFnInfo).fastpathDecMapIntFloat64R) - fn(map[int]bool(nil), (encFnInfo).fastpathEncMapIntBoolR, (decFnInfo).fastpathDecMapIntBoolR) - fn(map[int8]interface{}(nil), (encFnInfo).fastpathEncMapInt8IntfR, (decFnInfo).fastpathDecMapInt8IntfR) - fn(map[int8]string(nil), (encFnInfo).fastpathEncMapInt8StringR, (decFnInfo).fastpathDecMapInt8StringR) - fn(map[int8]uint(nil), (encFnInfo).fastpathEncMapInt8UintR, (decFnInfo).fastpathDecMapInt8UintR) - fn(map[int8]uint8(nil), (encFnInfo).fastpathEncMapInt8Uint8R, (decFnInfo).fastpathDecMapInt8Uint8R) - fn(map[int8]uint16(nil), (encFnInfo).fastpathEncMapInt8Uint16R, (decFnInfo).fastpathDecMapInt8Uint16R) - fn(map[int8]uint32(nil), (encFnInfo).fastpathEncMapInt8Uint32R, (decFnInfo).fastpathDecMapInt8Uint32R) - fn(map[int8]uint64(nil), (encFnInfo).fastpathEncMapInt8Uint64R, (decFnInfo).fastpathDecMapInt8Uint64R) - fn(map[int8]int(nil), (encFnInfo).fastpathEncMapInt8IntR, (decFnInfo).fastpathDecMapInt8IntR) - fn(map[int8]int8(nil), (encFnInfo).fastpathEncMapInt8Int8R, (decFnInfo).fastpathDecMapInt8Int8R) - fn(map[int8]int16(nil), (encFnInfo).fastpathEncMapInt8Int16R, (decFnInfo).fastpathDecMapInt8Int16R) - fn(map[int8]int32(nil), (encFnInfo).fastpathEncMapInt8Int32R, (decFnInfo).fastpathDecMapInt8Int32R) - fn(map[int8]int64(nil), (encFnInfo).fastpathEncMapInt8Int64R, (decFnInfo).fastpathDecMapInt8Int64R) - fn(map[int8]float32(nil), (encFnInfo).fastpathEncMapInt8Float32R, (decFnInfo).fastpathDecMapInt8Float32R) - fn(map[int8]float64(nil), (encFnInfo).fastpathEncMapInt8Float64R, (decFnInfo).fastpathDecMapInt8Float64R) - fn(map[int8]bool(nil), (encFnInfo).fastpathEncMapInt8BoolR, (decFnInfo).fastpathDecMapInt8BoolR) - fn(map[int16]interface{}(nil), (encFnInfo).fastpathEncMapInt16IntfR, (decFnInfo).fastpathDecMapInt16IntfR) - fn(map[int16]string(nil), (encFnInfo).fastpathEncMapInt16StringR, (decFnInfo).fastpathDecMapInt16StringR) - fn(map[int16]uint(nil), (encFnInfo).fastpathEncMapInt16UintR, (decFnInfo).fastpathDecMapInt16UintR) - fn(map[int16]uint8(nil), (encFnInfo).fastpathEncMapInt16Uint8R, (decFnInfo).fastpathDecMapInt16Uint8R) - fn(map[int16]uint16(nil), (encFnInfo).fastpathEncMapInt16Uint16R, (decFnInfo).fastpathDecMapInt16Uint16R) - fn(map[int16]uint32(nil), (encFnInfo).fastpathEncMapInt16Uint32R, (decFnInfo).fastpathDecMapInt16Uint32R) - fn(map[int16]uint64(nil), (encFnInfo).fastpathEncMapInt16Uint64R, (decFnInfo).fastpathDecMapInt16Uint64R) - fn(map[int16]int(nil), (encFnInfo).fastpathEncMapInt16IntR, (decFnInfo).fastpathDecMapInt16IntR) - fn(map[int16]int8(nil), (encFnInfo).fastpathEncMapInt16Int8R, (decFnInfo).fastpathDecMapInt16Int8R) - fn(map[int16]int16(nil), (encFnInfo).fastpathEncMapInt16Int16R, (decFnInfo).fastpathDecMapInt16Int16R) - fn(map[int16]int32(nil), (encFnInfo).fastpathEncMapInt16Int32R, (decFnInfo).fastpathDecMapInt16Int32R) - fn(map[int16]int64(nil), (encFnInfo).fastpathEncMapInt16Int64R, (decFnInfo).fastpathDecMapInt16Int64R) - fn(map[int16]float32(nil), (encFnInfo).fastpathEncMapInt16Float32R, (decFnInfo).fastpathDecMapInt16Float32R) - fn(map[int16]float64(nil), (encFnInfo).fastpathEncMapInt16Float64R, (decFnInfo).fastpathDecMapInt16Float64R) - fn(map[int16]bool(nil), (encFnInfo).fastpathEncMapInt16BoolR, (decFnInfo).fastpathDecMapInt16BoolR) - fn(map[int32]interface{}(nil), (encFnInfo).fastpathEncMapInt32IntfR, (decFnInfo).fastpathDecMapInt32IntfR) - fn(map[int32]string(nil), (encFnInfo).fastpathEncMapInt32StringR, (decFnInfo).fastpathDecMapInt32StringR) - fn(map[int32]uint(nil), (encFnInfo).fastpathEncMapInt32UintR, (decFnInfo).fastpathDecMapInt32UintR) - fn(map[int32]uint8(nil), (encFnInfo).fastpathEncMapInt32Uint8R, (decFnInfo).fastpathDecMapInt32Uint8R) - fn(map[int32]uint16(nil), (encFnInfo).fastpathEncMapInt32Uint16R, (decFnInfo).fastpathDecMapInt32Uint16R) - fn(map[int32]uint32(nil), (encFnInfo).fastpathEncMapInt32Uint32R, (decFnInfo).fastpathDecMapInt32Uint32R) - fn(map[int32]uint64(nil), (encFnInfo).fastpathEncMapInt32Uint64R, (decFnInfo).fastpathDecMapInt32Uint64R) - fn(map[int32]int(nil), (encFnInfo).fastpathEncMapInt32IntR, (decFnInfo).fastpathDecMapInt32IntR) - fn(map[int32]int8(nil), (encFnInfo).fastpathEncMapInt32Int8R, (decFnInfo).fastpathDecMapInt32Int8R) - fn(map[int32]int16(nil), (encFnInfo).fastpathEncMapInt32Int16R, (decFnInfo).fastpathDecMapInt32Int16R) - fn(map[int32]int32(nil), (encFnInfo).fastpathEncMapInt32Int32R, (decFnInfo).fastpathDecMapInt32Int32R) - fn(map[int32]int64(nil), (encFnInfo).fastpathEncMapInt32Int64R, (decFnInfo).fastpathDecMapInt32Int64R) - fn(map[int32]float32(nil), (encFnInfo).fastpathEncMapInt32Float32R, (decFnInfo).fastpathDecMapInt32Float32R) - fn(map[int32]float64(nil), (encFnInfo).fastpathEncMapInt32Float64R, (decFnInfo).fastpathDecMapInt32Float64R) - fn(map[int32]bool(nil), (encFnInfo).fastpathEncMapInt32BoolR, (decFnInfo).fastpathDecMapInt32BoolR) - fn(map[int64]interface{}(nil), (encFnInfo).fastpathEncMapInt64IntfR, (decFnInfo).fastpathDecMapInt64IntfR) - fn(map[int64]string(nil), (encFnInfo).fastpathEncMapInt64StringR, (decFnInfo).fastpathDecMapInt64StringR) - fn(map[int64]uint(nil), (encFnInfo).fastpathEncMapInt64UintR, (decFnInfo).fastpathDecMapInt64UintR) - fn(map[int64]uint8(nil), (encFnInfo).fastpathEncMapInt64Uint8R, (decFnInfo).fastpathDecMapInt64Uint8R) - fn(map[int64]uint16(nil), (encFnInfo).fastpathEncMapInt64Uint16R, (decFnInfo).fastpathDecMapInt64Uint16R) - fn(map[int64]uint32(nil), (encFnInfo).fastpathEncMapInt64Uint32R, (decFnInfo).fastpathDecMapInt64Uint32R) - fn(map[int64]uint64(nil), (encFnInfo).fastpathEncMapInt64Uint64R, (decFnInfo).fastpathDecMapInt64Uint64R) - fn(map[int64]int(nil), (encFnInfo).fastpathEncMapInt64IntR, (decFnInfo).fastpathDecMapInt64IntR) - fn(map[int64]int8(nil), (encFnInfo).fastpathEncMapInt64Int8R, (decFnInfo).fastpathDecMapInt64Int8R) - fn(map[int64]int16(nil), (encFnInfo).fastpathEncMapInt64Int16R, (decFnInfo).fastpathDecMapInt64Int16R) - fn(map[int64]int32(nil), (encFnInfo).fastpathEncMapInt64Int32R, (decFnInfo).fastpathDecMapInt64Int32R) - fn(map[int64]int64(nil), (encFnInfo).fastpathEncMapInt64Int64R, (decFnInfo).fastpathDecMapInt64Int64R) - fn(map[int64]float32(nil), (encFnInfo).fastpathEncMapInt64Float32R, (decFnInfo).fastpathDecMapInt64Float32R) - fn(map[int64]float64(nil), (encFnInfo).fastpathEncMapInt64Float64R, (decFnInfo).fastpathDecMapInt64Float64R) - fn(map[int64]bool(nil), (encFnInfo).fastpathEncMapInt64BoolR, (decFnInfo).fastpathDecMapInt64BoolR) - fn(map[bool]interface{}(nil), (encFnInfo).fastpathEncMapBoolIntfR, (decFnInfo).fastpathDecMapBoolIntfR) - fn(map[bool]string(nil), (encFnInfo).fastpathEncMapBoolStringR, (decFnInfo).fastpathDecMapBoolStringR) - fn(map[bool]uint(nil), (encFnInfo).fastpathEncMapBoolUintR, (decFnInfo).fastpathDecMapBoolUintR) - fn(map[bool]uint8(nil), (encFnInfo).fastpathEncMapBoolUint8R, (decFnInfo).fastpathDecMapBoolUint8R) - fn(map[bool]uint16(nil), (encFnInfo).fastpathEncMapBoolUint16R, (decFnInfo).fastpathDecMapBoolUint16R) - fn(map[bool]uint32(nil), (encFnInfo).fastpathEncMapBoolUint32R, (decFnInfo).fastpathDecMapBoolUint32R) - fn(map[bool]uint64(nil), (encFnInfo).fastpathEncMapBoolUint64R, (decFnInfo).fastpathDecMapBoolUint64R) - fn(map[bool]int(nil), (encFnInfo).fastpathEncMapBoolIntR, (decFnInfo).fastpathDecMapBoolIntR) - fn(map[bool]int8(nil), (encFnInfo).fastpathEncMapBoolInt8R, (decFnInfo).fastpathDecMapBoolInt8R) - fn(map[bool]int16(nil), (encFnInfo).fastpathEncMapBoolInt16R, (decFnInfo).fastpathDecMapBoolInt16R) - fn(map[bool]int32(nil), (encFnInfo).fastpathEncMapBoolInt32R, (decFnInfo).fastpathDecMapBoolInt32R) - fn(map[bool]int64(nil), (encFnInfo).fastpathEncMapBoolInt64R, (decFnInfo).fastpathDecMapBoolInt64R) - fn(map[bool]float32(nil), (encFnInfo).fastpathEncMapBoolFloat32R, (decFnInfo).fastpathDecMapBoolFloat32R) - fn(map[bool]float64(nil), (encFnInfo).fastpathEncMapBoolFloat64R, (decFnInfo).fastpathDecMapBoolFloat64R) - fn(map[bool]bool(nil), (encFnInfo).fastpathEncMapBoolBoolR, (decFnInfo).fastpathDecMapBoolBoolR) + fn([]interface{}(nil), (*encFnInfo).fastpathEncSliceIntfR, (*decFnInfo).fastpathDecSliceIntfR) + fn([]string(nil), (*encFnInfo).fastpathEncSliceStringR, (*decFnInfo).fastpathDecSliceStringR) + fn([]float32(nil), (*encFnInfo).fastpathEncSliceFloat32R, (*decFnInfo).fastpathDecSliceFloat32R) + fn([]float64(nil), (*encFnInfo).fastpathEncSliceFloat64R, (*decFnInfo).fastpathDecSliceFloat64R) + fn([]uint(nil), (*encFnInfo).fastpathEncSliceUintR, (*decFnInfo).fastpathDecSliceUintR) + fn([]uint16(nil), (*encFnInfo).fastpathEncSliceUint16R, (*decFnInfo).fastpathDecSliceUint16R) + fn([]uint32(nil), (*encFnInfo).fastpathEncSliceUint32R, (*decFnInfo).fastpathDecSliceUint32R) + fn([]uint64(nil), (*encFnInfo).fastpathEncSliceUint64R, (*decFnInfo).fastpathDecSliceUint64R) + fn([]int(nil), (*encFnInfo).fastpathEncSliceIntR, (*decFnInfo).fastpathDecSliceIntR) + fn([]int8(nil), (*encFnInfo).fastpathEncSliceInt8R, (*decFnInfo).fastpathDecSliceInt8R) + fn([]int16(nil), (*encFnInfo).fastpathEncSliceInt16R, (*decFnInfo).fastpathDecSliceInt16R) + fn([]int32(nil), (*encFnInfo).fastpathEncSliceInt32R, (*decFnInfo).fastpathDecSliceInt32R) + fn([]int64(nil), (*encFnInfo).fastpathEncSliceInt64R, (*decFnInfo).fastpathDecSliceInt64R) + fn([]bool(nil), (*encFnInfo).fastpathEncSliceBoolR, (*decFnInfo).fastpathDecSliceBoolR) + + fn(map[interface{}]interface{}(nil), (*encFnInfo).fastpathEncMapIntfIntfR, (*decFnInfo).fastpathDecMapIntfIntfR) + fn(map[interface{}]string(nil), (*encFnInfo).fastpathEncMapIntfStringR, (*decFnInfo).fastpathDecMapIntfStringR) + fn(map[interface{}]uint(nil), (*encFnInfo).fastpathEncMapIntfUintR, (*decFnInfo).fastpathDecMapIntfUintR) + fn(map[interface{}]uint8(nil), (*encFnInfo).fastpathEncMapIntfUint8R, (*decFnInfo).fastpathDecMapIntfUint8R) + fn(map[interface{}]uint16(nil), (*encFnInfo).fastpathEncMapIntfUint16R, (*decFnInfo).fastpathDecMapIntfUint16R) + fn(map[interface{}]uint32(nil), (*encFnInfo).fastpathEncMapIntfUint32R, (*decFnInfo).fastpathDecMapIntfUint32R) + fn(map[interface{}]uint64(nil), (*encFnInfo).fastpathEncMapIntfUint64R, (*decFnInfo).fastpathDecMapIntfUint64R) + fn(map[interface{}]int(nil), (*encFnInfo).fastpathEncMapIntfIntR, (*decFnInfo).fastpathDecMapIntfIntR) + fn(map[interface{}]int8(nil), (*encFnInfo).fastpathEncMapIntfInt8R, (*decFnInfo).fastpathDecMapIntfInt8R) + fn(map[interface{}]int16(nil), (*encFnInfo).fastpathEncMapIntfInt16R, (*decFnInfo).fastpathDecMapIntfInt16R) + fn(map[interface{}]int32(nil), (*encFnInfo).fastpathEncMapIntfInt32R, (*decFnInfo).fastpathDecMapIntfInt32R) + fn(map[interface{}]int64(nil), (*encFnInfo).fastpathEncMapIntfInt64R, (*decFnInfo).fastpathDecMapIntfInt64R) + fn(map[interface{}]float32(nil), (*encFnInfo).fastpathEncMapIntfFloat32R, (*decFnInfo).fastpathDecMapIntfFloat32R) + fn(map[interface{}]float64(nil), (*encFnInfo).fastpathEncMapIntfFloat64R, (*decFnInfo).fastpathDecMapIntfFloat64R) + fn(map[interface{}]bool(nil), (*encFnInfo).fastpathEncMapIntfBoolR, (*decFnInfo).fastpathDecMapIntfBoolR) + fn(map[string]interface{}(nil), (*encFnInfo).fastpathEncMapStringIntfR, (*decFnInfo).fastpathDecMapStringIntfR) + fn(map[string]string(nil), (*encFnInfo).fastpathEncMapStringStringR, (*decFnInfo).fastpathDecMapStringStringR) + fn(map[string]uint(nil), (*encFnInfo).fastpathEncMapStringUintR, (*decFnInfo).fastpathDecMapStringUintR) + fn(map[string]uint8(nil), (*encFnInfo).fastpathEncMapStringUint8R, (*decFnInfo).fastpathDecMapStringUint8R) + fn(map[string]uint16(nil), (*encFnInfo).fastpathEncMapStringUint16R, (*decFnInfo).fastpathDecMapStringUint16R) + fn(map[string]uint32(nil), (*encFnInfo).fastpathEncMapStringUint32R, (*decFnInfo).fastpathDecMapStringUint32R) + fn(map[string]uint64(nil), (*encFnInfo).fastpathEncMapStringUint64R, (*decFnInfo).fastpathDecMapStringUint64R) + fn(map[string]int(nil), (*encFnInfo).fastpathEncMapStringIntR, (*decFnInfo).fastpathDecMapStringIntR) + fn(map[string]int8(nil), (*encFnInfo).fastpathEncMapStringInt8R, (*decFnInfo).fastpathDecMapStringInt8R) + fn(map[string]int16(nil), (*encFnInfo).fastpathEncMapStringInt16R, (*decFnInfo).fastpathDecMapStringInt16R) + fn(map[string]int32(nil), (*encFnInfo).fastpathEncMapStringInt32R, (*decFnInfo).fastpathDecMapStringInt32R) + fn(map[string]int64(nil), (*encFnInfo).fastpathEncMapStringInt64R, (*decFnInfo).fastpathDecMapStringInt64R) + fn(map[string]float32(nil), (*encFnInfo).fastpathEncMapStringFloat32R, (*decFnInfo).fastpathDecMapStringFloat32R) + fn(map[string]float64(nil), (*encFnInfo).fastpathEncMapStringFloat64R, (*decFnInfo).fastpathDecMapStringFloat64R) + fn(map[string]bool(nil), (*encFnInfo).fastpathEncMapStringBoolR, (*decFnInfo).fastpathDecMapStringBoolR) + fn(map[float32]interface{}(nil), (*encFnInfo).fastpathEncMapFloat32IntfR, (*decFnInfo).fastpathDecMapFloat32IntfR) + fn(map[float32]string(nil), (*encFnInfo).fastpathEncMapFloat32StringR, (*decFnInfo).fastpathDecMapFloat32StringR) + fn(map[float32]uint(nil), (*encFnInfo).fastpathEncMapFloat32UintR, (*decFnInfo).fastpathDecMapFloat32UintR) + fn(map[float32]uint8(nil), (*encFnInfo).fastpathEncMapFloat32Uint8R, (*decFnInfo).fastpathDecMapFloat32Uint8R) + fn(map[float32]uint16(nil), (*encFnInfo).fastpathEncMapFloat32Uint16R, (*decFnInfo).fastpathDecMapFloat32Uint16R) + fn(map[float32]uint32(nil), (*encFnInfo).fastpathEncMapFloat32Uint32R, (*decFnInfo).fastpathDecMapFloat32Uint32R) + fn(map[float32]uint64(nil), (*encFnInfo).fastpathEncMapFloat32Uint64R, (*decFnInfo).fastpathDecMapFloat32Uint64R) + fn(map[float32]int(nil), (*encFnInfo).fastpathEncMapFloat32IntR, (*decFnInfo).fastpathDecMapFloat32IntR) + fn(map[float32]int8(nil), (*encFnInfo).fastpathEncMapFloat32Int8R, (*decFnInfo).fastpathDecMapFloat32Int8R) + fn(map[float32]int16(nil), (*encFnInfo).fastpathEncMapFloat32Int16R, (*decFnInfo).fastpathDecMapFloat32Int16R) + fn(map[float32]int32(nil), (*encFnInfo).fastpathEncMapFloat32Int32R, (*decFnInfo).fastpathDecMapFloat32Int32R) + fn(map[float32]int64(nil), (*encFnInfo).fastpathEncMapFloat32Int64R, (*decFnInfo).fastpathDecMapFloat32Int64R) + fn(map[float32]float32(nil), (*encFnInfo).fastpathEncMapFloat32Float32R, (*decFnInfo).fastpathDecMapFloat32Float32R) + fn(map[float32]float64(nil), (*encFnInfo).fastpathEncMapFloat32Float64R, (*decFnInfo).fastpathDecMapFloat32Float64R) + fn(map[float32]bool(nil), (*encFnInfo).fastpathEncMapFloat32BoolR, (*decFnInfo).fastpathDecMapFloat32BoolR) + fn(map[float64]interface{}(nil), (*encFnInfo).fastpathEncMapFloat64IntfR, (*decFnInfo).fastpathDecMapFloat64IntfR) + fn(map[float64]string(nil), (*encFnInfo).fastpathEncMapFloat64StringR, (*decFnInfo).fastpathDecMapFloat64StringR) + fn(map[float64]uint(nil), (*encFnInfo).fastpathEncMapFloat64UintR, (*decFnInfo).fastpathDecMapFloat64UintR) + fn(map[float64]uint8(nil), (*encFnInfo).fastpathEncMapFloat64Uint8R, (*decFnInfo).fastpathDecMapFloat64Uint8R) + fn(map[float64]uint16(nil), (*encFnInfo).fastpathEncMapFloat64Uint16R, (*decFnInfo).fastpathDecMapFloat64Uint16R) + fn(map[float64]uint32(nil), (*encFnInfo).fastpathEncMapFloat64Uint32R, (*decFnInfo).fastpathDecMapFloat64Uint32R) + fn(map[float64]uint64(nil), (*encFnInfo).fastpathEncMapFloat64Uint64R, (*decFnInfo).fastpathDecMapFloat64Uint64R) + fn(map[float64]int(nil), (*encFnInfo).fastpathEncMapFloat64IntR, (*decFnInfo).fastpathDecMapFloat64IntR) + fn(map[float64]int8(nil), (*encFnInfo).fastpathEncMapFloat64Int8R, (*decFnInfo).fastpathDecMapFloat64Int8R) + fn(map[float64]int16(nil), (*encFnInfo).fastpathEncMapFloat64Int16R, (*decFnInfo).fastpathDecMapFloat64Int16R) + fn(map[float64]int32(nil), (*encFnInfo).fastpathEncMapFloat64Int32R, (*decFnInfo).fastpathDecMapFloat64Int32R) + fn(map[float64]int64(nil), (*encFnInfo).fastpathEncMapFloat64Int64R, (*decFnInfo).fastpathDecMapFloat64Int64R) + fn(map[float64]float32(nil), (*encFnInfo).fastpathEncMapFloat64Float32R, (*decFnInfo).fastpathDecMapFloat64Float32R) + fn(map[float64]float64(nil), (*encFnInfo).fastpathEncMapFloat64Float64R, (*decFnInfo).fastpathDecMapFloat64Float64R) + fn(map[float64]bool(nil), (*encFnInfo).fastpathEncMapFloat64BoolR, (*decFnInfo).fastpathDecMapFloat64BoolR) + fn(map[uint]interface{}(nil), (*encFnInfo).fastpathEncMapUintIntfR, (*decFnInfo).fastpathDecMapUintIntfR) + fn(map[uint]string(nil), (*encFnInfo).fastpathEncMapUintStringR, (*decFnInfo).fastpathDecMapUintStringR) + fn(map[uint]uint(nil), (*encFnInfo).fastpathEncMapUintUintR, (*decFnInfo).fastpathDecMapUintUintR) + fn(map[uint]uint8(nil), (*encFnInfo).fastpathEncMapUintUint8R, (*decFnInfo).fastpathDecMapUintUint8R) + fn(map[uint]uint16(nil), (*encFnInfo).fastpathEncMapUintUint16R, (*decFnInfo).fastpathDecMapUintUint16R) + fn(map[uint]uint32(nil), (*encFnInfo).fastpathEncMapUintUint32R, (*decFnInfo).fastpathDecMapUintUint32R) + fn(map[uint]uint64(nil), (*encFnInfo).fastpathEncMapUintUint64R, (*decFnInfo).fastpathDecMapUintUint64R) + fn(map[uint]int(nil), (*encFnInfo).fastpathEncMapUintIntR, (*decFnInfo).fastpathDecMapUintIntR) + fn(map[uint]int8(nil), (*encFnInfo).fastpathEncMapUintInt8R, (*decFnInfo).fastpathDecMapUintInt8R) + fn(map[uint]int16(nil), (*encFnInfo).fastpathEncMapUintInt16R, (*decFnInfo).fastpathDecMapUintInt16R) + fn(map[uint]int32(nil), (*encFnInfo).fastpathEncMapUintInt32R, (*decFnInfo).fastpathDecMapUintInt32R) + fn(map[uint]int64(nil), (*encFnInfo).fastpathEncMapUintInt64R, (*decFnInfo).fastpathDecMapUintInt64R) + fn(map[uint]float32(nil), (*encFnInfo).fastpathEncMapUintFloat32R, (*decFnInfo).fastpathDecMapUintFloat32R) + fn(map[uint]float64(nil), (*encFnInfo).fastpathEncMapUintFloat64R, (*decFnInfo).fastpathDecMapUintFloat64R) + fn(map[uint]bool(nil), (*encFnInfo).fastpathEncMapUintBoolR, (*decFnInfo).fastpathDecMapUintBoolR) + fn(map[uint8]interface{}(nil), (*encFnInfo).fastpathEncMapUint8IntfR, (*decFnInfo).fastpathDecMapUint8IntfR) + fn(map[uint8]string(nil), (*encFnInfo).fastpathEncMapUint8StringR, (*decFnInfo).fastpathDecMapUint8StringR) + fn(map[uint8]uint(nil), (*encFnInfo).fastpathEncMapUint8UintR, (*decFnInfo).fastpathDecMapUint8UintR) + fn(map[uint8]uint8(nil), (*encFnInfo).fastpathEncMapUint8Uint8R, (*decFnInfo).fastpathDecMapUint8Uint8R) + fn(map[uint8]uint16(nil), (*encFnInfo).fastpathEncMapUint8Uint16R, (*decFnInfo).fastpathDecMapUint8Uint16R) + fn(map[uint8]uint32(nil), (*encFnInfo).fastpathEncMapUint8Uint32R, (*decFnInfo).fastpathDecMapUint8Uint32R) + fn(map[uint8]uint64(nil), (*encFnInfo).fastpathEncMapUint8Uint64R, (*decFnInfo).fastpathDecMapUint8Uint64R) + fn(map[uint8]int(nil), (*encFnInfo).fastpathEncMapUint8IntR, (*decFnInfo).fastpathDecMapUint8IntR) + fn(map[uint8]int8(nil), (*encFnInfo).fastpathEncMapUint8Int8R, (*decFnInfo).fastpathDecMapUint8Int8R) + fn(map[uint8]int16(nil), (*encFnInfo).fastpathEncMapUint8Int16R, (*decFnInfo).fastpathDecMapUint8Int16R) + fn(map[uint8]int32(nil), (*encFnInfo).fastpathEncMapUint8Int32R, (*decFnInfo).fastpathDecMapUint8Int32R) + fn(map[uint8]int64(nil), (*encFnInfo).fastpathEncMapUint8Int64R, (*decFnInfo).fastpathDecMapUint8Int64R) + fn(map[uint8]float32(nil), (*encFnInfo).fastpathEncMapUint8Float32R, (*decFnInfo).fastpathDecMapUint8Float32R) + fn(map[uint8]float64(nil), (*encFnInfo).fastpathEncMapUint8Float64R, (*decFnInfo).fastpathDecMapUint8Float64R) + fn(map[uint8]bool(nil), (*encFnInfo).fastpathEncMapUint8BoolR, (*decFnInfo).fastpathDecMapUint8BoolR) + fn(map[uint16]interface{}(nil), (*encFnInfo).fastpathEncMapUint16IntfR, (*decFnInfo).fastpathDecMapUint16IntfR) + fn(map[uint16]string(nil), (*encFnInfo).fastpathEncMapUint16StringR, (*decFnInfo).fastpathDecMapUint16StringR) + fn(map[uint16]uint(nil), (*encFnInfo).fastpathEncMapUint16UintR, (*decFnInfo).fastpathDecMapUint16UintR) + fn(map[uint16]uint8(nil), (*encFnInfo).fastpathEncMapUint16Uint8R, (*decFnInfo).fastpathDecMapUint16Uint8R) + fn(map[uint16]uint16(nil), (*encFnInfo).fastpathEncMapUint16Uint16R, (*decFnInfo).fastpathDecMapUint16Uint16R) + fn(map[uint16]uint32(nil), (*encFnInfo).fastpathEncMapUint16Uint32R, (*decFnInfo).fastpathDecMapUint16Uint32R) + fn(map[uint16]uint64(nil), (*encFnInfo).fastpathEncMapUint16Uint64R, (*decFnInfo).fastpathDecMapUint16Uint64R) + fn(map[uint16]int(nil), (*encFnInfo).fastpathEncMapUint16IntR, (*decFnInfo).fastpathDecMapUint16IntR) + fn(map[uint16]int8(nil), (*encFnInfo).fastpathEncMapUint16Int8R, (*decFnInfo).fastpathDecMapUint16Int8R) + fn(map[uint16]int16(nil), (*encFnInfo).fastpathEncMapUint16Int16R, (*decFnInfo).fastpathDecMapUint16Int16R) + fn(map[uint16]int32(nil), (*encFnInfo).fastpathEncMapUint16Int32R, (*decFnInfo).fastpathDecMapUint16Int32R) + fn(map[uint16]int64(nil), (*encFnInfo).fastpathEncMapUint16Int64R, (*decFnInfo).fastpathDecMapUint16Int64R) + fn(map[uint16]float32(nil), (*encFnInfo).fastpathEncMapUint16Float32R, (*decFnInfo).fastpathDecMapUint16Float32R) + fn(map[uint16]float64(nil), (*encFnInfo).fastpathEncMapUint16Float64R, (*decFnInfo).fastpathDecMapUint16Float64R) + fn(map[uint16]bool(nil), (*encFnInfo).fastpathEncMapUint16BoolR, (*decFnInfo).fastpathDecMapUint16BoolR) + fn(map[uint32]interface{}(nil), (*encFnInfo).fastpathEncMapUint32IntfR, (*decFnInfo).fastpathDecMapUint32IntfR) + fn(map[uint32]string(nil), (*encFnInfo).fastpathEncMapUint32StringR, (*decFnInfo).fastpathDecMapUint32StringR) + fn(map[uint32]uint(nil), (*encFnInfo).fastpathEncMapUint32UintR, (*decFnInfo).fastpathDecMapUint32UintR) + fn(map[uint32]uint8(nil), (*encFnInfo).fastpathEncMapUint32Uint8R, (*decFnInfo).fastpathDecMapUint32Uint8R) + fn(map[uint32]uint16(nil), (*encFnInfo).fastpathEncMapUint32Uint16R, (*decFnInfo).fastpathDecMapUint32Uint16R) + fn(map[uint32]uint32(nil), (*encFnInfo).fastpathEncMapUint32Uint32R, (*decFnInfo).fastpathDecMapUint32Uint32R) + fn(map[uint32]uint64(nil), (*encFnInfo).fastpathEncMapUint32Uint64R, (*decFnInfo).fastpathDecMapUint32Uint64R) + fn(map[uint32]int(nil), (*encFnInfo).fastpathEncMapUint32IntR, (*decFnInfo).fastpathDecMapUint32IntR) + fn(map[uint32]int8(nil), (*encFnInfo).fastpathEncMapUint32Int8R, (*decFnInfo).fastpathDecMapUint32Int8R) + fn(map[uint32]int16(nil), (*encFnInfo).fastpathEncMapUint32Int16R, (*decFnInfo).fastpathDecMapUint32Int16R) + fn(map[uint32]int32(nil), (*encFnInfo).fastpathEncMapUint32Int32R, (*decFnInfo).fastpathDecMapUint32Int32R) + fn(map[uint32]int64(nil), (*encFnInfo).fastpathEncMapUint32Int64R, (*decFnInfo).fastpathDecMapUint32Int64R) + fn(map[uint32]float32(nil), (*encFnInfo).fastpathEncMapUint32Float32R, (*decFnInfo).fastpathDecMapUint32Float32R) + fn(map[uint32]float64(nil), (*encFnInfo).fastpathEncMapUint32Float64R, (*decFnInfo).fastpathDecMapUint32Float64R) + fn(map[uint32]bool(nil), (*encFnInfo).fastpathEncMapUint32BoolR, (*decFnInfo).fastpathDecMapUint32BoolR) + fn(map[uint64]interface{}(nil), (*encFnInfo).fastpathEncMapUint64IntfR, (*decFnInfo).fastpathDecMapUint64IntfR) + fn(map[uint64]string(nil), (*encFnInfo).fastpathEncMapUint64StringR, (*decFnInfo).fastpathDecMapUint64StringR) + fn(map[uint64]uint(nil), (*encFnInfo).fastpathEncMapUint64UintR, (*decFnInfo).fastpathDecMapUint64UintR) + fn(map[uint64]uint8(nil), (*encFnInfo).fastpathEncMapUint64Uint8R, (*decFnInfo).fastpathDecMapUint64Uint8R) + fn(map[uint64]uint16(nil), (*encFnInfo).fastpathEncMapUint64Uint16R, (*decFnInfo).fastpathDecMapUint64Uint16R) + fn(map[uint64]uint32(nil), (*encFnInfo).fastpathEncMapUint64Uint32R, (*decFnInfo).fastpathDecMapUint64Uint32R) + fn(map[uint64]uint64(nil), (*encFnInfo).fastpathEncMapUint64Uint64R, (*decFnInfo).fastpathDecMapUint64Uint64R) + fn(map[uint64]int(nil), (*encFnInfo).fastpathEncMapUint64IntR, (*decFnInfo).fastpathDecMapUint64IntR) + fn(map[uint64]int8(nil), (*encFnInfo).fastpathEncMapUint64Int8R, (*decFnInfo).fastpathDecMapUint64Int8R) + fn(map[uint64]int16(nil), (*encFnInfo).fastpathEncMapUint64Int16R, (*decFnInfo).fastpathDecMapUint64Int16R) + fn(map[uint64]int32(nil), (*encFnInfo).fastpathEncMapUint64Int32R, (*decFnInfo).fastpathDecMapUint64Int32R) + fn(map[uint64]int64(nil), (*encFnInfo).fastpathEncMapUint64Int64R, (*decFnInfo).fastpathDecMapUint64Int64R) + fn(map[uint64]float32(nil), (*encFnInfo).fastpathEncMapUint64Float32R, (*decFnInfo).fastpathDecMapUint64Float32R) + fn(map[uint64]float64(nil), (*encFnInfo).fastpathEncMapUint64Float64R, (*decFnInfo).fastpathDecMapUint64Float64R) + fn(map[uint64]bool(nil), (*encFnInfo).fastpathEncMapUint64BoolR, (*decFnInfo).fastpathDecMapUint64BoolR) + fn(map[int]interface{}(nil), (*encFnInfo).fastpathEncMapIntIntfR, (*decFnInfo).fastpathDecMapIntIntfR) + fn(map[int]string(nil), (*encFnInfo).fastpathEncMapIntStringR, (*decFnInfo).fastpathDecMapIntStringR) + fn(map[int]uint(nil), (*encFnInfo).fastpathEncMapIntUintR, (*decFnInfo).fastpathDecMapIntUintR) + fn(map[int]uint8(nil), (*encFnInfo).fastpathEncMapIntUint8R, (*decFnInfo).fastpathDecMapIntUint8R) + fn(map[int]uint16(nil), (*encFnInfo).fastpathEncMapIntUint16R, (*decFnInfo).fastpathDecMapIntUint16R) + fn(map[int]uint32(nil), (*encFnInfo).fastpathEncMapIntUint32R, (*decFnInfo).fastpathDecMapIntUint32R) + fn(map[int]uint64(nil), (*encFnInfo).fastpathEncMapIntUint64R, (*decFnInfo).fastpathDecMapIntUint64R) + fn(map[int]int(nil), (*encFnInfo).fastpathEncMapIntIntR, (*decFnInfo).fastpathDecMapIntIntR) + fn(map[int]int8(nil), (*encFnInfo).fastpathEncMapIntInt8R, (*decFnInfo).fastpathDecMapIntInt8R) + fn(map[int]int16(nil), (*encFnInfo).fastpathEncMapIntInt16R, (*decFnInfo).fastpathDecMapIntInt16R) + fn(map[int]int32(nil), (*encFnInfo).fastpathEncMapIntInt32R, (*decFnInfo).fastpathDecMapIntInt32R) + fn(map[int]int64(nil), (*encFnInfo).fastpathEncMapIntInt64R, (*decFnInfo).fastpathDecMapIntInt64R) + fn(map[int]float32(nil), (*encFnInfo).fastpathEncMapIntFloat32R, (*decFnInfo).fastpathDecMapIntFloat32R) + fn(map[int]float64(nil), (*encFnInfo).fastpathEncMapIntFloat64R, (*decFnInfo).fastpathDecMapIntFloat64R) + fn(map[int]bool(nil), (*encFnInfo).fastpathEncMapIntBoolR, (*decFnInfo).fastpathDecMapIntBoolR) + fn(map[int8]interface{}(nil), (*encFnInfo).fastpathEncMapInt8IntfR, (*decFnInfo).fastpathDecMapInt8IntfR) + fn(map[int8]string(nil), (*encFnInfo).fastpathEncMapInt8StringR, (*decFnInfo).fastpathDecMapInt8StringR) + fn(map[int8]uint(nil), (*encFnInfo).fastpathEncMapInt8UintR, (*decFnInfo).fastpathDecMapInt8UintR) + fn(map[int8]uint8(nil), (*encFnInfo).fastpathEncMapInt8Uint8R, (*decFnInfo).fastpathDecMapInt8Uint8R) + fn(map[int8]uint16(nil), (*encFnInfo).fastpathEncMapInt8Uint16R, (*decFnInfo).fastpathDecMapInt8Uint16R) + fn(map[int8]uint32(nil), (*encFnInfo).fastpathEncMapInt8Uint32R, (*decFnInfo).fastpathDecMapInt8Uint32R) + fn(map[int8]uint64(nil), (*encFnInfo).fastpathEncMapInt8Uint64R, (*decFnInfo).fastpathDecMapInt8Uint64R) + fn(map[int8]int(nil), (*encFnInfo).fastpathEncMapInt8IntR, (*decFnInfo).fastpathDecMapInt8IntR) + fn(map[int8]int8(nil), (*encFnInfo).fastpathEncMapInt8Int8R, (*decFnInfo).fastpathDecMapInt8Int8R) + fn(map[int8]int16(nil), (*encFnInfo).fastpathEncMapInt8Int16R, (*decFnInfo).fastpathDecMapInt8Int16R) + fn(map[int8]int32(nil), (*encFnInfo).fastpathEncMapInt8Int32R, (*decFnInfo).fastpathDecMapInt8Int32R) + fn(map[int8]int64(nil), (*encFnInfo).fastpathEncMapInt8Int64R, (*decFnInfo).fastpathDecMapInt8Int64R) + fn(map[int8]float32(nil), (*encFnInfo).fastpathEncMapInt8Float32R, (*decFnInfo).fastpathDecMapInt8Float32R) + fn(map[int8]float64(nil), (*encFnInfo).fastpathEncMapInt8Float64R, (*decFnInfo).fastpathDecMapInt8Float64R) + fn(map[int8]bool(nil), (*encFnInfo).fastpathEncMapInt8BoolR, (*decFnInfo).fastpathDecMapInt8BoolR) + fn(map[int16]interface{}(nil), (*encFnInfo).fastpathEncMapInt16IntfR, (*decFnInfo).fastpathDecMapInt16IntfR) + fn(map[int16]string(nil), (*encFnInfo).fastpathEncMapInt16StringR, (*decFnInfo).fastpathDecMapInt16StringR) + fn(map[int16]uint(nil), (*encFnInfo).fastpathEncMapInt16UintR, (*decFnInfo).fastpathDecMapInt16UintR) + fn(map[int16]uint8(nil), (*encFnInfo).fastpathEncMapInt16Uint8R, (*decFnInfo).fastpathDecMapInt16Uint8R) + fn(map[int16]uint16(nil), (*encFnInfo).fastpathEncMapInt16Uint16R, (*decFnInfo).fastpathDecMapInt16Uint16R) + fn(map[int16]uint32(nil), (*encFnInfo).fastpathEncMapInt16Uint32R, (*decFnInfo).fastpathDecMapInt16Uint32R) + fn(map[int16]uint64(nil), (*encFnInfo).fastpathEncMapInt16Uint64R, (*decFnInfo).fastpathDecMapInt16Uint64R) + fn(map[int16]int(nil), (*encFnInfo).fastpathEncMapInt16IntR, (*decFnInfo).fastpathDecMapInt16IntR) + fn(map[int16]int8(nil), (*encFnInfo).fastpathEncMapInt16Int8R, (*decFnInfo).fastpathDecMapInt16Int8R) + fn(map[int16]int16(nil), (*encFnInfo).fastpathEncMapInt16Int16R, (*decFnInfo).fastpathDecMapInt16Int16R) + fn(map[int16]int32(nil), (*encFnInfo).fastpathEncMapInt16Int32R, (*decFnInfo).fastpathDecMapInt16Int32R) + fn(map[int16]int64(nil), (*encFnInfo).fastpathEncMapInt16Int64R, (*decFnInfo).fastpathDecMapInt16Int64R) + fn(map[int16]float32(nil), (*encFnInfo).fastpathEncMapInt16Float32R, (*decFnInfo).fastpathDecMapInt16Float32R) + fn(map[int16]float64(nil), (*encFnInfo).fastpathEncMapInt16Float64R, (*decFnInfo).fastpathDecMapInt16Float64R) + fn(map[int16]bool(nil), (*encFnInfo).fastpathEncMapInt16BoolR, (*decFnInfo).fastpathDecMapInt16BoolR) + fn(map[int32]interface{}(nil), (*encFnInfo).fastpathEncMapInt32IntfR, (*decFnInfo).fastpathDecMapInt32IntfR) + fn(map[int32]string(nil), (*encFnInfo).fastpathEncMapInt32StringR, (*decFnInfo).fastpathDecMapInt32StringR) + fn(map[int32]uint(nil), (*encFnInfo).fastpathEncMapInt32UintR, (*decFnInfo).fastpathDecMapInt32UintR) + fn(map[int32]uint8(nil), (*encFnInfo).fastpathEncMapInt32Uint8R, (*decFnInfo).fastpathDecMapInt32Uint8R) + fn(map[int32]uint16(nil), (*encFnInfo).fastpathEncMapInt32Uint16R, (*decFnInfo).fastpathDecMapInt32Uint16R) + fn(map[int32]uint32(nil), (*encFnInfo).fastpathEncMapInt32Uint32R, (*decFnInfo).fastpathDecMapInt32Uint32R) + fn(map[int32]uint64(nil), (*encFnInfo).fastpathEncMapInt32Uint64R, (*decFnInfo).fastpathDecMapInt32Uint64R) + fn(map[int32]int(nil), (*encFnInfo).fastpathEncMapInt32IntR, (*decFnInfo).fastpathDecMapInt32IntR) + fn(map[int32]int8(nil), (*encFnInfo).fastpathEncMapInt32Int8R, (*decFnInfo).fastpathDecMapInt32Int8R) + fn(map[int32]int16(nil), (*encFnInfo).fastpathEncMapInt32Int16R, (*decFnInfo).fastpathDecMapInt32Int16R) + fn(map[int32]int32(nil), (*encFnInfo).fastpathEncMapInt32Int32R, (*decFnInfo).fastpathDecMapInt32Int32R) + fn(map[int32]int64(nil), (*encFnInfo).fastpathEncMapInt32Int64R, (*decFnInfo).fastpathDecMapInt32Int64R) + fn(map[int32]float32(nil), (*encFnInfo).fastpathEncMapInt32Float32R, (*decFnInfo).fastpathDecMapInt32Float32R) + fn(map[int32]float64(nil), (*encFnInfo).fastpathEncMapInt32Float64R, (*decFnInfo).fastpathDecMapInt32Float64R) + fn(map[int32]bool(nil), (*encFnInfo).fastpathEncMapInt32BoolR, (*decFnInfo).fastpathDecMapInt32BoolR) + fn(map[int64]interface{}(nil), (*encFnInfo).fastpathEncMapInt64IntfR, (*decFnInfo).fastpathDecMapInt64IntfR) + fn(map[int64]string(nil), (*encFnInfo).fastpathEncMapInt64StringR, (*decFnInfo).fastpathDecMapInt64StringR) + fn(map[int64]uint(nil), (*encFnInfo).fastpathEncMapInt64UintR, (*decFnInfo).fastpathDecMapInt64UintR) + fn(map[int64]uint8(nil), (*encFnInfo).fastpathEncMapInt64Uint8R, (*decFnInfo).fastpathDecMapInt64Uint8R) + fn(map[int64]uint16(nil), (*encFnInfo).fastpathEncMapInt64Uint16R, (*decFnInfo).fastpathDecMapInt64Uint16R) + fn(map[int64]uint32(nil), (*encFnInfo).fastpathEncMapInt64Uint32R, (*decFnInfo).fastpathDecMapInt64Uint32R) + fn(map[int64]uint64(nil), (*encFnInfo).fastpathEncMapInt64Uint64R, (*decFnInfo).fastpathDecMapInt64Uint64R) + fn(map[int64]int(nil), (*encFnInfo).fastpathEncMapInt64IntR, (*decFnInfo).fastpathDecMapInt64IntR) + fn(map[int64]int8(nil), (*encFnInfo).fastpathEncMapInt64Int8R, (*decFnInfo).fastpathDecMapInt64Int8R) + fn(map[int64]int16(nil), (*encFnInfo).fastpathEncMapInt64Int16R, (*decFnInfo).fastpathDecMapInt64Int16R) + fn(map[int64]int32(nil), (*encFnInfo).fastpathEncMapInt64Int32R, (*decFnInfo).fastpathDecMapInt64Int32R) + fn(map[int64]int64(nil), (*encFnInfo).fastpathEncMapInt64Int64R, (*decFnInfo).fastpathDecMapInt64Int64R) + fn(map[int64]float32(nil), (*encFnInfo).fastpathEncMapInt64Float32R, (*decFnInfo).fastpathDecMapInt64Float32R) + fn(map[int64]float64(nil), (*encFnInfo).fastpathEncMapInt64Float64R, (*decFnInfo).fastpathDecMapInt64Float64R) + fn(map[int64]bool(nil), (*encFnInfo).fastpathEncMapInt64BoolR, (*decFnInfo).fastpathDecMapInt64BoolR) + fn(map[bool]interface{}(nil), (*encFnInfo).fastpathEncMapBoolIntfR, (*decFnInfo).fastpathDecMapBoolIntfR) + fn(map[bool]string(nil), (*encFnInfo).fastpathEncMapBoolStringR, (*decFnInfo).fastpathDecMapBoolStringR) + fn(map[bool]uint(nil), (*encFnInfo).fastpathEncMapBoolUintR, (*decFnInfo).fastpathDecMapBoolUintR) + fn(map[bool]uint8(nil), (*encFnInfo).fastpathEncMapBoolUint8R, (*decFnInfo).fastpathDecMapBoolUint8R) + fn(map[bool]uint16(nil), (*encFnInfo).fastpathEncMapBoolUint16R, (*decFnInfo).fastpathDecMapBoolUint16R) + fn(map[bool]uint32(nil), (*encFnInfo).fastpathEncMapBoolUint32R, (*decFnInfo).fastpathDecMapBoolUint32R) + fn(map[bool]uint64(nil), (*encFnInfo).fastpathEncMapBoolUint64R, (*decFnInfo).fastpathDecMapBoolUint64R) + fn(map[bool]int(nil), (*encFnInfo).fastpathEncMapBoolIntR, (*decFnInfo).fastpathDecMapBoolIntR) + fn(map[bool]int8(nil), (*encFnInfo).fastpathEncMapBoolInt8R, (*decFnInfo).fastpathDecMapBoolInt8R) + fn(map[bool]int16(nil), (*encFnInfo).fastpathEncMapBoolInt16R, (*decFnInfo).fastpathDecMapBoolInt16R) + fn(map[bool]int32(nil), (*encFnInfo).fastpathEncMapBoolInt32R, (*decFnInfo).fastpathDecMapBoolInt32R) + fn(map[bool]int64(nil), (*encFnInfo).fastpathEncMapBoolInt64R, (*decFnInfo).fastpathDecMapBoolInt64R) + fn(map[bool]float32(nil), (*encFnInfo).fastpathEncMapBoolFloat32R, (*decFnInfo).fastpathDecMapBoolFloat32R) + fn(map[bool]float64(nil), (*encFnInfo).fastpathEncMapBoolFloat64R, (*decFnInfo).fastpathDecMapBoolFloat64R) + fn(map[bool]bool(nil), (*encFnInfo).fastpathEncMapBoolBoolR, (*decFnInfo).fastpathDecMapBoolBoolR) sort.Sort(fastpathAslice(fastpathAV[:])) } @@ -2759,7 +2759,7 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { // -- -- fast path functions -func (f encFnInfo) fastpathEncSliceIntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceIntfR(rv reflect.Value) { fastpathTV.EncSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceIntfV(v []interface{}, checkNil bool, e *Encoder) { @@ -2769,22 +2769,13 @@ func (_ fastpathT) EncSliceIntfV(v []interface{}, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - e.encode(v2) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - e.encode(v2) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceStringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceStringR(rv reflect.Value) { fastpathTV.EncSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceStringV(v []string, checkNil bool, e *Encoder) { @@ -2794,22 +2785,13 @@ func (_ fastpathT) EncSliceStringV(v []string, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeString(c_UTF8, v2) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeString(c_UTF8, v2) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceFloat32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceFloat32R(rv reflect.Value) { fastpathTV.EncSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceFloat32V(v []float32, checkNil bool, e *Encoder) { @@ -2819,22 +2801,13 @@ func (_ fastpathT) EncSliceFloat32V(v []float32, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeFloat32(v2) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeFloat32(v2) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceFloat64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceFloat64R(rv reflect.Value) { fastpathTV.EncSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceFloat64V(v []float64, checkNil bool, e *Encoder) { @@ -2844,22 +2817,13 @@ func (_ fastpathT) EncSliceFloat64V(v []float64, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeFloat64(v2) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeFloat64(v2) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceUintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceUintR(rv reflect.Value) { fastpathTV.EncSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceUintV(v []uint, checkNil bool, e *Encoder) { @@ -2869,22 +2833,13 @@ func (_ fastpathT) EncSliceUintV(v []uint, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeUint(uint64(v2)) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeUint(uint64(v2)) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceUint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceUint16R(rv reflect.Value) { fastpathTV.EncSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceUint16V(v []uint16, checkNil bool, e *Encoder) { @@ -2894,22 +2849,13 @@ func (_ fastpathT) EncSliceUint16V(v []uint16, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeUint(uint64(v2)) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeUint(uint64(v2)) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceUint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceUint32R(rv reflect.Value) { fastpathTV.EncSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceUint32V(v []uint32, checkNil bool, e *Encoder) { @@ -2919,22 +2865,13 @@ func (_ fastpathT) EncSliceUint32V(v []uint32, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeUint(uint64(v2)) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeUint(uint64(v2)) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceUint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceUint64R(rv reflect.Value) { fastpathTV.EncSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceUint64V(v []uint64, checkNil bool, e *Encoder) { @@ -2944,22 +2881,13 @@ func (_ fastpathT) EncSliceUint64V(v []uint64, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeUint(uint64(v2)) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeUint(uint64(v2)) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceIntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceIntR(rv reflect.Value) { fastpathTV.EncSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceIntV(v []int, checkNil bool, e *Encoder) { @@ -2969,22 +2897,13 @@ func (_ fastpathT) EncSliceIntV(v []int, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeInt(int64(v2)) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeInt(int64(v2)) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceInt8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceInt8R(rv reflect.Value) { fastpathTV.EncSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceInt8V(v []int8, checkNil bool, e *Encoder) { @@ -2994,22 +2913,13 @@ func (_ fastpathT) EncSliceInt8V(v []int8, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeInt(int64(v2)) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeInt(int64(v2)) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceInt16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceInt16R(rv reflect.Value) { fastpathTV.EncSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceInt16V(v []int16, checkNil bool, e *Encoder) { @@ -3019,22 +2929,13 @@ func (_ fastpathT) EncSliceInt16V(v []int16, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeInt(int64(v2)) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeInt(int64(v2)) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceInt32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceInt32R(rv reflect.Value) { fastpathTV.EncSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceInt32V(v []int32, checkNil bool, e *Encoder) { @@ -3044,22 +2945,13 @@ func (_ fastpathT) EncSliceInt32V(v []int32, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeInt(int64(v2)) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeInt(int64(v2)) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceInt64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceInt64R(rv reflect.Value) { fastpathTV.EncSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceInt64V(v []int64, checkNil bool, e *Encoder) { @@ -3069,22 +2961,13 @@ func (_ fastpathT) EncSliceInt64V(v []int64, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeInt(int64(v2)) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeInt(int64(v2)) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncSliceBoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncSliceBoolR(rv reflect.Value) { fastpathTV.EncSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceBoolV(v []bool, checkNil bool, e *Encoder) { @@ -3094,22 +2977,13 @@ func (_ fastpathT) EncSliceBoolV(v []bool, checkNil bool, e *Encoder) { return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeBool(v2) - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeBool(v2) - } - ee.EncodeArrayEnd() + for _, v2 := range v { + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfIntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfIntfR(rv reflect.Value) { fastpathTV.EncMapIntfIntfV(rv.Interface().(map[interface{}]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, e *Encoder) { @@ -3120,27 +2994,14 @@ func (_ fastpathT) EncMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfStringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfStringR(rv reflect.Value) { fastpathTV.EncMapIntfStringV(rv.Interface().(map[interface{}]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfStringV(v map[interface{}]string, checkNil bool, e *Encoder) { @@ -3151,27 +3012,14 @@ func (_ fastpathT) EncMapIntfStringV(v map[interface{}]string, checkNil bool, e } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfUintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfUintR(rv reflect.Value) { fastpathTV.EncMapIntfUintV(rv.Interface().(map[interface{}]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfUintV(v map[interface{}]uint, checkNil bool, e *Encoder) { @@ -3182,27 +3030,14 @@ func (_ fastpathT) EncMapIntfUintV(v map[interface{}]uint, checkNil bool, e *Enc } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfUint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfUint8R(rv reflect.Value) { fastpathTV.EncMapIntfUint8V(rv.Interface().(map[interface{}]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfUint8V(v map[interface{}]uint8, checkNil bool, e *Encoder) { @@ -3213,27 +3048,14 @@ func (_ fastpathT) EncMapIntfUint8V(v map[interface{}]uint8, checkNil bool, e *E } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfUint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfUint16R(rv reflect.Value) { fastpathTV.EncMapIntfUint16V(rv.Interface().(map[interface{}]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfUint16V(v map[interface{}]uint16, checkNil bool, e *Encoder) { @@ -3244,27 +3066,14 @@ func (_ fastpathT) EncMapIntfUint16V(v map[interface{}]uint16, checkNil bool, e } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfUint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfUint32R(rv reflect.Value) { fastpathTV.EncMapIntfUint32V(rv.Interface().(map[interface{}]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfUint32V(v map[interface{}]uint32, checkNil bool, e *Encoder) { @@ -3275,27 +3084,14 @@ func (_ fastpathT) EncMapIntfUint32V(v map[interface{}]uint32, checkNil bool, e } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfUint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfUint64R(rv reflect.Value) { fastpathTV.EncMapIntfUint64V(rv.Interface().(map[interface{}]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfUint64V(v map[interface{}]uint64, checkNil bool, e *Encoder) { @@ -3306,27 +3102,14 @@ func (_ fastpathT) EncMapIntfUint64V(v map[interface{}]uint64, checkNil bool, e } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfIntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfIntR(rv reflect.Value) { fastpathTV.EncMapIntfIntV(rv.Interface().(map[interface{}]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfIntV(v map[interface{}]int, checkNil bool, e *Encoder) { @@ -3337,27 +3120,14 @@ func (_ fastpathT) EncMapIntfIntV(v map[interface{}]int, checkNil bool, e *Encod } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfInt8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfInt8R(rv reflect.Value) { fastpathTV.EncMapIntfInt8V(rv.Interface().(map[interface{}]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfInt8V(v map[interface{}]int8, checkNil bool, e *Encoder) { @@ -3368,27 +3138,14 @@ func (_ fastpathT) EncMapIntfInt8V(v map[interface{}]int8, checkNil bool, e *Enc } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfInt16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfInt16R(rv reflect.Value) { fastpathTV.EncMapIntfInt16V(rv.Interface().(map[interface{}]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfInt16V(v map[interface{}]int16, checkNil bool, e *Encoder) { @@ -3399,27 +3156,14 @@ func (_ fastpathT) EncMapIntfInt16V(v map[interface{}]int16, checkNil bool, e *E } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfInt32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfInt32R(rv reflect.Value) { fastpathTV.EncMapIntfInt32V(rv.Interface().(map[interface{}]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfInt32V(v map[interface{}]int32, checkNil bool, e *Encoder) { @@ -3430,27 +3174,14 @@ func (_ fastpathT) EncMapIntfInt32V(v map[interface{}]int32, checkNil bool, e *E } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfInt64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfInt64R(rv reflect.Value) { fastpathTV.EncMapIntfInt64V(rv.Interface().(map[interface{}]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfInt64V(v map[interface{}]int64, checkNil bool, e *Encoder) { @@ -3461,27 +3192,14 @@ func (_ fastpathT) EncMapIntfInt64V(v map[interface{}]int64, checkNil bool, e *E } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfFloat32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfFloat32R(rv reflect.Value) { fastpathTV.EncMapIntfFloat32V(rv.Interface().(map[interface{}]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfFloat32V(v map[interface{}]float32, checkNil bool, e *Encoder) { @@ -3492,27 +3210,14 @@ func (_ fastpathT) EncMapIntfFloat32V(v map[interface{}]float32, checkNil bool, } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfFloat64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfFloat64R(rv reflect.Value) { fastpathTV.EncMapIntfFloat64V(rv.Interface().(map[interface{}]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfFloat64V(v map[interface{}]float64, checkNil bool, e *Encoder) { @@ -3523,27 +3228,14 @@ func (_ fastpathT) EncMapIntfFloat64V(v map[interface{}]float64, checkNil bool, } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntfBoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfBoolR(rv reflect.Value) { fastpathTV.EncMapIntfBoolV(rv.Interface().(map[interface{}]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfBoolV(v map[interface{}]bool, checkNil bool, e *Encoder) { @@ -3554,27 +3246,14 @@ func (_ fastpathT) EncMapIntfBoolV(v map[interface{}]bool, checkNil bool, e *Enc } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.encode(k2) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + e.encode(k2) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringIntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringIntfR(rv reflect.Value) { fastpathTV.EncMapStringIntfV(rv.Interface().(map[string]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringIntfV(v map[string]interface{}, checkNil bool, e *Encoder) { @@ -3585,35 +3264,18 @@ func (_ fastpathT) EncMapStringIntfV(v map[string]interface{}, checkNil bool, e } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringStringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringStringR(rv reflect.Value) { fastpathTV.EncMapStringStringV(rv.Interface().(map[string]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringStringV(v map[string]string, checkNil bool, e *Encoder) { @@ -3624,35 +3286,18 @@ func (_ fastpathT) EncMapStringStringV(v map[string]string, checkNil bool, e *En } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringUintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringUintR(rv reflect.Value) { fastpathTV.EncMapStringUintV(rv.Interface().(map[string]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringUintV(v map[string]uint, checkNil bool, e *Encoder) { @@ -3663,35 +3308,18 @@ func (_ fastpathT) EncMapStringUintV(v map[string]uint, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringUint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringUint8R(rv reflect.Value) { fastpathTV.EncMapStringUint8V(rv.Interface().(map[string]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringUint8V(v map[string]uint8, checkNil bool, e *Encoder) { @@ -3702,35 +3330,18 @@ func (_ fastpathT) EncMapStringUint8V(v map[string]uint8, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringUint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringUint16R(rv reflect.Value) { fastpathTV.EncMapStringUint16V(rv.Interface().(map[string]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringUint16V(v map[string]uint16, checkNil bool, e *Encoder) { @@ -3741,35 +3352,18 @@ func (_ fastpathT) EncMapStringUint16V(v map[string]uint16, checkNil bool, e *En } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringUint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringUint32R(rv reflect.Value) { fastpathTV.EncMapStringUint32V(rv.Interface().(map[string]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringUint32V(v map[string]uint32, checkNil bool, e *Encoder) { @@ -3780,35 +3374,18 @@ func (_ fastpathT) EncMapStringUint32V(v map[string]uint32, checkNil bool, e *En } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringUint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringUint64R(rv reflect.Value) { fastpathTV.EncMapStringUint64V(rv.Interface().(map[string]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringUint64V(v map[string]uint64, checkNil bool, e *Encoder) { @@ -3819,35 +3396,18 @@ func (_ fastpathT) EncMapStringUint64V(v map[string]uint64, checkNil bool, e *En } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringIntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringIntR(rv reflect.Value) { fastpathTV.EncMapStringIntV(rv.Interface().(map[string]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringIntV(v map[string]int, checkNil bool, e *Encoder) { @@ -3858,35 +3418,18 @@ func (_ fastpathT) EncMapStringIntV(v map[string]int, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringInt8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringInt8R(rv reflect.Value) { fastpathTV.EncMapStringInt8V(rv.Interface().(map[string]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringInt8V(v map[string]int8, checkNil bool, e *Encoder) { @@ -3897,35 +3440,18 @@ func (_ fastpathT) EncMapStringInt8V(v map[string]int8, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringInt16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringInt16R(rv reflect.Value) { fastpathTV.EncMapStringInt16V(rv.Interface().(map[string]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringInt16V(v map[string]int16, checkNil bool, e *Encoder) { @@ -3936,35 +3462,18 @@ func (_ fastpathT) EncMapStringInt16V(v map[string]int16, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringInt32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringInt32R(rv reflect.Value) { fastpathTV.EncMapStringInt32V(rv.Interface().(map[string]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringInt32V(v map[string]int32, checkNil bool, e *Encoder) { @@ -3975,35 +3484,18 @@ func (_ fastpathT) EncMapStringInt32V(v map[string]int32, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringInt64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringInt64R(rv reflect.Value) { fastpathTV.EncMapStringInt64V(rv.Interface().(map[string]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringInt64V(v map[string]int64, checkNil bool, e *Encoder) { @@ -4014,35 +3506,18 @@ func (_ fastpathT) EncMapStringInt64V(v map[string]int64, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringFloat32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringFloat32R(rv reflect.Value) { fastpathTV.EncMapStringFloat32V(rv.Interface().(map[string]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringFloat32V(v map[string]float32, checkNil bool, e *Encoder) { @@ -4053,35 +3528,18 @@ func (_ fastpathT) EncMapStringFloat32V(v map[string]float32, checkNil bool, e * } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringFloat64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringFloat64R(rv reflect.Value) { fastpathTV.EncMapStringFloat64V(rv.Interface().(map[string]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringFloat64V(v map[string]float64, checkNil bool, e *Encoder) { @@ -4092,35 +3550,18 @@ func (_ fastpathT) EncMapStringFloat64V(v map[string]float64, checkNil bool, e * } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapStringBoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringBoolR(rv reflect.Value) { fastpathTV.EncMapStringBoolV(rv.Interface().(map[string]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringBoolV(v map[string]bool, checkNil bool, e *Encoder) { @@ -4131,35 +3572,18 @@ func (_ fastpathT) EncMapStringBoolV(v map[string]bool, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - } - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ + for k2, v2 := range v { + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapEnd() + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32IntfR(rv reflect.Value) { fastpathTV.EncMapFloat32IntfV(rv.Interface().(map[float32]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32IntfV(v map[float32]interface{}, checkNil bool, e *Encoder) { @@ -4170,27 +3594,14 @@ func (_ fastpathT) EncMapFloat32IntfV(v map[float32]interface{}, checkNil bool, } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32StringR(rv reflect.Value) { fastpathTV.EncMapFloat32StringV(rv.Interface().(map[float32]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32StringV(v map[float32]string, checkNil bool, e *Encoder) { @@ -4201,27 +3612,14 @@ func (_ fastpathT) EncMapFloat32StringV(v map[float32]string, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32UintR(rv reflect.Value) { fastpathTV.EncMapFloat32UintV(rv.Interface().(map[float32]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32UintV(v map[float32]uint, checkNil bool, e *Encoder) { @@ -4232,27 +3630,14 @@ func (_ fastpathT) EncMapFloat32UintV(v map[float32]uint, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Uint8R(rv reflect.Value) { fastpathTV.EncMapFloat32Uint8V(rv.Interface().(map[float32]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Uint8V(v map[float32]uint8, checkNil bool, e *Encoder) { @@ -4263,27 +3648,14 @@ func (_ fastpathT) EncMapFloat32Uint8V(v map[float32]uint8, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Uint16R(rv reflect.Value) { fastpathTV.EncMapFloat32Uint16V(rv.Interface().(map[float32]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Uint16V(v map[float32]uint16, checkNil bool, e *Encoder) { @@ -4294,27 +3666,14 @@ func (_ fastpathT) EncMapFloat32Uint16V(v map[float32]uint16, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Uint32R(rv reflect.Value) { fastpathTV.EncMapFloat32Uint32V(rv.Interface().(map[float32]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Uint32V(v map[float32]uint32, checkNil bool, e *Encoder) { @@ -4325,27 +3684,14 @@ func (_ fastpathT) EncMapFloat32Uint32V(v map[float32]uint32, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Uint64R(rv reflect.Value) { fastpathTV.EncMapFloat32Uint64V(rv.Interface().(map[float32]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Uint64V(v map[float32]uint64, checkNil bool, e *Encoder) { @@ -4356,27 +3702,14 @@ func (_ fastpathT) EncMapFloat32Uint64V(v map[float32]uint64, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32IntR(rv reflect.Value) { fastpathTV.EncMapFloat32IntV(rv.Interface().(map[float32]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32IntV(v map[float32]int, checkNil bool, e *Encoder) { @@ -4387,27 +3720,14 @@ func (_ fastpathT) EncMapFloat32IntV(v map[float32]int, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Int8R(rv reflect.Value) { fastpathTV.EncMapFloat32Int8V(rv.Interface().(map[float32]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Int8V(v map[float32]int8, checkNil bool, e *Encoder) { @@ -4418,27 +3738,14 @@ func (_ fastpathT) EncMapFloat32Int8V(v map[float32]int8, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Int16R(rv reflect.Value) { fastpathTV.EncMapFloat32Int16V(rv.Interface().(map[float32]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Int16V(v map[float32]int16, checkNil bool, e *Encoder) { @@ -4449,27 +3756,14 @@ func (_ fastpathT) EncMapFloat32Int16V(v map[float32]int16, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Int32R(rv reflect.Value) { fastpathTV.EncMapFloat32Int32V(rv.Interface().(map[float32]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Int32V(v map[float32]int32, checkNil bool, e *Encoder) { @@ -4480,27 +3774,14 @@ func (_ fastpathT) EncMapFloat32Int32V(v map[float32]int32, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Int64R(rv reflect.Value) { fastpathTV.EncMapFloat32Int64V(rv.Interface().(map[float32]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Int64V(v map[float32]int64, checkNil bool, e *Encoder) { @@ -4511,27 +3792,14 @@ func (_ fastpathT) EncMapFloat32Int64V(v map[float32]int64, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Float32R(rv reflect.Value) { fastpathTV.EncMapFloat32Float32V(rv.Interface().(map[float32]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Float32V(v map[float32]float32, checkNil bool, e *Encoder) { @@ -4542,27 +3810,14 @@ func (_ fastpathT) EncMapFloat32Float32V(v map[float32]float32, checkNil bool, e } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Float64R(rv reflect.Value) { fastpathTV.EncMapFloat32Float64V(rv.Interface().(map[float32]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Float64V(v map[float32]float64, checkNil bool, e *Encoder) { @@ -4573,27 +3828,14 @@ func (_ fastpathT) EncMapFloat32Float64V(v map[float32]float64, checkNil bool, e } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat32BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32BoolR(rv reflect.Value) { fastpathTV.EncMapFloat32BoolV(rv.Interface().(map[float32]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32BoolV(v map[float32]bool, checkNil bool, e *Encoder) { @@ -4604,27 +3846,14 @@ func (_ fastpathT) EncMapFloat32BoolV(v map[float32]bool, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat32(k2) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64IntfR(rv reflect.Value) { fastpathTV.EncMapFloat64IntfV(rv.Interface().(map[float64]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64IntfV(v map[float64]interface{}, checkNil bool, e *Encoder) { @@ -4635,27 +3864,14 @@ func (_ fastpathT) EncMapFloat64IntfV(v map[float64]interface{}, checkNil bool, } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64StringR(rv reflect.Value) { fastpathTV.EncMapFloat64StringV(rv.Interface().(map[float64]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64StringV(v map[float64]string, checkNil bool, e *Encoder) { @@ -4666,27 +3882,14 @@ func (_ fastpathT) EncMapFloat64StringV(v map[float64]string, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64UintR(rv reflect.Value) { fastpathTV.EncMapFloat64UintV(rv.Interface().(map[float64]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64UintV(v map[float64]uint, checkNil bool, e *Encoder) { @@ -4697,27 +3900,14 @@ func (_ fastpathT) EncMapFloat64UintV(v map[float64]uint, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Uint8R(rv reflect.Value) { fastpathTV.EncMapFloat64Uint8V(rv.Interface().(map[float64]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Uint8V(v map[float64]uint8, checkNil bool, e *Encoder) { @@ -4728,27 +3918,14 @@ func (_ fastpathT) EncMapFloat64Uint8V(v map[float64]uint8, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Uint16R(rv reflect.Value) { fastpathTV.EncMapFloat64Uint16V(rv.Interface().(map[float64]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Uint16V(v map[float64]uint16, checkNil bool, e *Encoder) { @@ -4759,27 +3936,14 @@ func (_ fastpathT) EncMapFloat64Uint16V(v map[float64]uint16, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Uint32R(rv reflect.Value) { fastpathTV.EncMapFloat64Uint32V(rv.Interface().(map[float64]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Uint32V(v map[float64]uint32, checkNil bool, e *Encoder) { @@ -4790,27 +3954,14 @@ func (_ fastpathT) EncMapFloat64Uint32V(v map[float64]uint32, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Uint64R(rv reflect.Value) { fastpathTV.EncMapFloat64Uint64V(rv.Interface().(map[float64]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Uint64V(v map[float64]uint64, checkNil bool, e *Encoder) { @@ -4821,27 +3972,14 @@ func (_ fastpathT) EncMapFloat64Uint64V(v map[float64]uint64, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64IntR(rv reflect.Value) { fastpathTV.EncMapFloat64IntV(rv.Interface().(map[float64]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64IntV(v map[float64]int, checkNil bool, e *Encoder) { @@ -4852,27 +3990,14 @@ func (_ fastpathT) EncMapFloat64IntV(v map[float64]int, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Int8R(rv reflect.Value) { fastpathTV.EncMapFloat64Int8V(rv.Interface().(map[float64]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Int8V(v map[float64]int8, checkNil bool, e *Encoder) { @@ -4883,27 +4008,14 @@ func (_ fastpathT) EncMapFloat64Int8V(v map[float64]int8, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Int16R(rv reflect.Value) { fastpathTV.EncMapFloat64Int16V(rv.Interface().(map[float64]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Int16V(v map[float64]int16, checkNil bool, e *Encoder) { @@ -4914,27 +4026,14 @@ func (_ fastpathT) EncMapFloat64Int16V(v map[float64]int16, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Int32R(rv reflect.Value) { fastpathTV.EncMapFloat64Int32V(rv.Interface().(map[float64]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Int32V(v map[float64]int32, checkNil bool, e *Encoder) { @@ -4945,27 +4044,14 @@ func (_ fastpathT) EncMapFloat64Int32V(v map[float64]int32, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Int64R(rv reflect.Value) { fastpathTV.EncMapFloat64Int64V(rv.Interface().(map[float64]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Int64V(v map[float64]int64, checkNil bool, e *Encoder) { @@ -4976,27 +4062,14 @@ func (_ fastpathT) EncMapFloat64Int64V(v map[float64]int64, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Float32R(rv reflect.Value) { fastpathTV.EncMapFloat64Float32V(rv.Interface().(map[float64]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Float32V(v map[float64]float32, checkNil bool, e *Encoder) { @@ -5007,27 +4080,14 @@ func (_ fastpathT) EncMapFloat64Float32V(v map[float64]float32, checkNil bool, e } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Float64R(rv reflect.Value) { fastpathTV.EncMapFloat64Float64V(rv.Interface().(map[float64]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Float64V(v map[float64]float64, checkNil bool, e *Encoder) { @@ -5038,27 +4098,14 @@ func (_ fastpathT) EncMapFloat64Float64V(v map[float64]float64, checkNil bool, e } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapFloat64BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64BoolR(rv reflect.Value) { fastpathTV.EncMapFloat64BoolV(rv.Interface().(map[float64]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64BoolV(v map[float64]bool, checkNil bool, e *Encoder) { @@ -5069,27 +4116,14 @@ func (_ fastpathT) EncMapFloat64BoolV(v map[float64]bool, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeFloat64(k2) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintIntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintIntfR(rv reflect.Value) { fastpathTV.EncMapUintIntfV(rv.Interface().(map[uint]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintIntfV(v map[uint]interface{}, checkNil bool, e *Encoder) { @@ -5100,27 +4134,14 @@ func (_ fastpathT) EncMapUintIntfV(v map[uint]interface{}, checkNil bool, e *Enc } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintStringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintStringR(rv reflect.Value) { fastpathTV.EncMapUintStringV(rv.Interface().(map[uint]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintStringV(v map[uint]string, checkNil bool, e *Encoder) { @@ -5131,27 +4152,14 @@ func (_ fastpathT) EncMapUintStringV(v map[uint]string, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintUintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintUintR(rv reflect.Value) { fastpathTV.EncMapUintUintV(rv.Interface().(map[uint]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintUintV(v map[uint]uint, checkNil bool, e *Encoder) { @@ -5162,27 +4170,14 @@ func (_ fastpathT) EncMapUintUintV(v map[uint]uint, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintUint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintUint8R(rv reflect.Value) { fastpathTV.EncMapUintUint8V(rv.Interface().(map[uint]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintUint8V(v map[uint]uint8, checkNil bool, e *Encoder) { @@ -5193,27 +4188,14 @@ func (_ fastpathT) EncMapUintUint8V(v map[uint]uint8, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintUint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintUint16R(rv reflect.Value) { fastpathTV.EncMapUintUint16V(rv.Interface().(map[uint]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintUint16V(v map[uint]uint16, checkNil bool, e *Encoder) { @@ -5224,27 +4206,14 @@ func (_ fastpathT) EncMapUintUint16V(v map[uint]uint16, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintUint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintUint32R(rv reflect.Value) { fastpathTV.EncMapUintUint32V(rv.Interface().(map[uint]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintUint32V(v map[uint]uint32, checkNil bool, e *Encoder) { @@ -5255,27 +4224,14 @@ func (_ fastpathT) EncMapUintUint32V(v map[uint]uint32, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintUint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintUint64R(rv reflect.Value) { fastpathTV.EncMapUintUint64V(rv.Interface().(map[uint]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintUint64V(v map[uint]uint64, checkNil bool, e *Encoder) { @@ -5286,27 +4242,14 @@ func (_ fastpathT) EncMapUintUint64V(v map[uint]uint64, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintIntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintIntR(rv reflect.Value) { fastpathTV.EncMapUintIntV(rv.Interface().(map[uint]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintIntV(v map[uint]int, checkNil bool, e *Encoder) { @@ -5317,27 +4260,14 @@ func (_ fastpathT) EncMapUintIntV(v map[uint]int, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintInt8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintInt8R(rv reflect.Value) { fastpathTV.EncMapUintInt8V(rv.Interface().(map[uint]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintInt8V(v map[uint]int8, checkNil bool, e *Encoder) { @@ -5348,27 +4278,14 @@ func (_ fastpathT) EncMapUintInt8V(v map[uint]int8, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintInt16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintInt16R(rv reflect.Value) { fastpathTV.EncMapUintInt16V(rv.Interface().(map[uint]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintInt16V(v map[uint]int16, checkNil bool, e *Encoder) { @@ -5379,27 +4296,14 @@ func (_ fastpathT) EncMapUintInt16V(v map[uint]int16, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintInt32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintInt32R(rv reflect.Value) { fastpathTV.EncMapUintInt32V(rv.Interface().(map[uint]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintInt32V(v map[uint]int32, checkNil bool, e *Encoder) { @@ -5410,27 +4314,14 @@ func (_ fastpathT) EncMapUintInt32V(v map[uint]int32, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintInt64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintInt64R(rv reflect.Value) { fastpathTV.EncMapUintInt64V(rv.Interface().(map[uint]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintInt64V(v map[uint]int64, checkNil bool, e *Encoder) { @@ -5441,58 +4332,32 @@ func (_ fastpathT) EncMapUintInt64V(v map[uint]int64, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintFloat32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintFloat32R(rv reflect.Value) { fastpathTV.EncMapUintFloat32V(rv.Interface().(map[uint]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintFloat32V(v map[uint]float32, checkNil bool, e *Encoder) { ee := e.e if checkNil && v == nil { ee.EncodeNil() - return - } - ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + return + } + ee.EncodeMapStart(len(v)) + + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintFloat64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintFloat64R(rv reflect.Value) { fastpathTV.EncMapUintFloat64V(rv.Interface().(map[uint]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintFloat64V(v map[uint]float64, checkNil bool, e *Encoder) { @@ -5503,27 +4368,14 @@ func (_ fastpathT) EncMapUintFloat64V(v map[uint]float64, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUintBoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintBoolR(rv reflect.Value) { fastpathTV.EncMapUintBoolV(rv.Interface().(map[uint]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintBoolV(v map[uint]bool, checkNil bool, e *Encoder) { @@ -5534,27 +4386,14 @@ func (_ fastpathT) EncMapUintBoolV(v map[uint]bool, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8IntfR(rv reflect.Value) { fastpathTV.EncMapUint8IntfV(rv.Interface().(map[uint8]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8IntfV(v map[uint8]interface{}, checkNil bool, e *Encoder) { @@ -5565,27 +4404,14 @@ func (_ fastpathT) EncMapUint8IntfV(v map[uint8]interface{}, checkNil bool, e *E } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8StringR(rv reflect.Value) { fastpathTV.EncMapUint8StringV(rv.Interface().(map[uint8]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8StringV(v map[uint8]string, checkNil bool, e *Encoder) { @@ -5596,27 +4422,14 @@ func (_ fastpathT) EncMapUint8StringV(v map[uint8]string, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8UintR(rv reflect.Value) { fastpathTV.EncMapUint8UintV(rv.Interface().(map[uint8]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8UintV(v map[uint8]uint, checkNil bool, e *Encoder) { @@ -5627,27 +4440,14 @@ func (_ fastpathT) EncMapUint8UintV(v map[uint8]uint, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Uint8R(rv reflect.Value) { fastpathTV.EncMapUint8Uint8V(rv.Interface().(map[uint8]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Uint8V(v map[uint8]uint8, checkNil bool, e *Encoder) { @@ -5658,27 +4458,14 @@ func (_ fastpathT) EncMapUint8Uint8V(v map[uint8]uint8, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Uint16R(rv reflect.Value) { fastpathTV.EncMapUint8Uint16V(rv.Interface().(map[uint8]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Uint16V(v map[uint8]uint16, checkNil bool, e *Encoder) { @@ -5689,27 +4476,14 @@ func (_ fastpathT) EncMapUint8Uint16V(v map[uint8]uint16, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Uint32R(rv reflect.Value) { fastpathTV.EncMapUint8Uint32V(rv.Interface().(map[uint8]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Uint32V(v map[uint8]uint32, checkNil bool, e *Encoder) { @@ -5720,27 +4494,14 @@ func (_ fastpathT) EncMapUint8Uint32V(v map[uint8]uint32, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Uint64R(rv reflect.Value) { fastpathTV.EncMapUint8Uint64V(rv.Interface().(map[uint8]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Uint64V(v map[uint8]uint64, checkNil bool, e *Encoder) { @@ -5751,27 +4512,14 @@ func (_ fastpathT) EncMapUint8Uint64V(v map[uint8]uint64, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8IntR(rv reflect.Value) { fastpathTV.EncMapUint8IntV(rv.Interface().(map[uint8]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8IntV(v map[uint8]int, checkNil bool, e *Encoder) { @@ -5782,27 +4530,14 @@ func (_ fastpathT) EncMapUint8IntV(v map[uint8]int, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Int8R(rv reflect.Value) { fastpathTV.EncMapUint8Int8V(rv.Interface().(map[uint8]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Int8V(v map[uint8]int8, checkNil bool, e *Encoder) { @@ -5813,27 +4548,14 @@ func (_ fastpathT) EncMapUint8Int8V(v map[uint8]int8, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Int16R(rv reflect.Value) { fastpathTV.EncMapUint8Int16V(rv.Interface().(map[uint8]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Int16V(v map[uint8]int16, checkNil bool, e *Encoder) { @@ -5844,27 +4566,14 @@ func (_ fastpathT) EncMapUint8Int16V(v map[uint8]int16, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Int32R(rv reflect.Value) { fastpathTV.EncMapUint8Int32V(rv.Interface().(map[uint8]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Int32V(v map[uint8]int32, checkNil bool, e *Encoder) { @@ -5875,27 +4584,14 @@ func (_ fastpathT) EncMapUint8Int32V(v map[uint8]int32, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Int64R(rv reflect.Value) { fastpathTV.EncMapUint8Int64V(rv.Interface().(map[uint8]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Int64V(v map[uint8]int64, checkNil bool, e *Encoder) { @@ -5906,27 +4602,14 @@ func (_ fastpathT) EncMapUint8Int64V(v map[uint8]int64, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Float32R(rv reflect.Value) { fastpathTV.EncMapUint8Float32V(rv.Interface().(map[uint8]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Float32V(v map[uint8]float32, checkNil bool, e *Encoder) { @@ -5937,27 +4620,14 @@ func (_ fastpathT) EncMapUint8Float32V(v map[uint8]float32, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Float64R(rv reflect.Value) { fastpathTV.EncMapUint8Float64V(rv.Interface().(map[uint8]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Float64V(v map[uint8]float64, checkNil bool, e *Encoder) { @@ -5968,27 +4638,14 @@ func (_ fastpathT) EncMapUint8Float64V(v map[uint8]float64, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint8BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8BoolR(rv reflect.Value) { fastpathTV.EncMapUint8BoolV(rv.Interface().(map[uint8]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8BoolV(v map[uint8]bool, checkNil bool, e *Encoder) { @@ -5999,27 +4656,14 @@ func (_ fastpathT) EncMapUint8BoolV(v map[uint8]bool, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16IntfR(rv reflect.Value) { fastpathTV.EncMapUint16IntfV(rv.Interface().(map[uint16]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16IntfV(v map[uint16]interface{}, checkNil bool, e *Encoder) { @@ -6030,27 +4674,14 @@ func (_ fastpathT) EncMapUint16IntfV(v map[uint16]interface{}, checkNil bool, e } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16StringR(rv reflect.Value) { fastpathTV.EncMapUint16StringV(rv.Interface().(map[uint16]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16StringV(v map[uint16]string, checkNil bool, e *Encoder) { @@ -6061,27 +4692,14 @@ func (_ fastpathT) EncMapUint16StringV(v map[uint16]string, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16UintR(rv reflect.Value) { fastpathTV.EncMapUint16UintV(rv.Interface().(map[uint16]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16UintV(v map[uint16]uint, checkNil bool, e *Encoder) { @@ -6092,27 +4710,14 @@ func (_ fastpathT) EncMapUint16UintV(v map[uint16]uint, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Uint8R(rv reflect.Value) { fastpathTV.EncMapUint16Uint8V(rv.Interface().(map[uint16]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Uint8V(v map[uint16]uint8, checkNil bool, e *Encoder) { @@ -6123,27 +4728,14 @@ func (_ fastpathT) EncMapUint16Uint8V(v map[uint16]uint8, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Uint16R(rv reflect.Value) { fastpathTV.EncMapUint16Uint16V(rv.Interface().(map[uint16]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Uint16V(v map[uint16]uint16, checkNil bool, e *Encoder) { @@ -6154,27 +4746,14 @@ func (_ fastpathT) EncMapUint16Uint16V(v map[uint16]uint16, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Uint32R(rv reflect.Value) { fastpathTV.EncMapUint16Uint32V(rv.Interface().(map[uint16]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Uint32V(v map[uint16]uint32, checkNil bool, e *Encoder) { @@ -6185,27 +4764,14 @@ func (_ fastpathT) EncMapUint16Uint32V(v map[uint16]uint32, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Uint64R(rv reflect.Value) { fastpathTV.EncMapUint16Uint64V(rv.Interface().(map[uint16]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Uint64V(v map[uint16]uint64, checkNil bool, e *Encoder) { @@ -6216,27 +4782,14 @@ func (_ fastpathT) EncMapUint16Uint64V(v map[uint16]uint64, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16IntR(rv reflect.Value) { fastpathTV.EncMapUint16IntV(rv.Interface().(map[uint16]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16IntV(v map[uint16]int, checkNil bool, e *Encoder) { @@ -6247,27 +4800,14 @@ func (_ fastpathT) EncMapUint16IntV(v map[uint16]int, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Int8R(rv reflect.Value) { fastpathTV.EncMapUint16Int8V(rv.Interface().(map[uint16]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Int8V(v map[uint16]int8, checkNil bool, e *Encoder) { @@ -6278,27 +4818,14 @@ func (_ fastpathT) EncMapUint16Int8V(v map[uint16]int8, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Int16R(rv reflect.Value) { fastpathTV.EncMapUint16Int16V(rv.Interface().(map[uint16]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Int16V(v map[uint16]int16, checkNil bool, e *Encoder) { @@ -6309,27 +4836,14 @@ func (_ fastpathT) EncMapUint16Int16V(v map[uint16]int16, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Int32R(rv reflect.Value) { fastpathTV.EncMapUint16Int32V(rv.Interface().(map[uint16]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Int32V(v map[uint16]int32, checkNil bool, e *Encoder) { @@ -6340,27 +4854,14 @@ func (_ fastpathT) EncMapUint16Int32V(v map[uint16]int32, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Int64R(rv reflect.Value) { fastpathTV.EncMapUint16Int64V(rv.Interface().(map[uint16]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Int64V(v map[uint16]int64, checkNil bool, e *Encoder) { @@ -6371,27 +4872,14 @@ func (_ fastpathT) EncMapUint16Int64V(v map[uint16]int64, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Float32R(rv reflect.Value) { fastpathTV.EncMapUint16Float32V(rv.Interface().(map[uint16]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Float32V(v map[uint16]float32, checkNil bool, e *Encoder) { @@ -6402,27 +4890,14 @@ func (_ fastpathT) EncMapUint16Float32V(v map[uint16]float32, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Float64R(rv reflect.Value) { fastpathTV.EncMapUint16Float64V(rv.Interface().(map[uint16]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Float64V(v map[uint16]float64, checkNil bool, e *Encoder) { @@ -6433,27 +4908,14 @@ func (_ fastpathT) EncMapUint16Float64V(v map[uint16]float64, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint16BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16BoolR(rv reflect.Value) { fastpathTV.EncMapUint16BoolV(rv.Interface().(map[uint16]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16BoolV(v map[uint16]bool, checkNil bool, e *Encoder) { @@ -6464,27 +4926,14 @@ func (_ fastpathT) EncMapUint16BoolV(v map[uint16]bool, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32IntfR(rv reflect.Value) { fastpathTV.EncMapUint32IntfV(rv.Interface().(map[uint32]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32IntfV(v map[uint32]interface{}, checkNil bool, e *Encoder) { @@ -6495,27 +4944,14 @@ func (_ fastpathT) EncMapUint32IntfV(v map[uint32]interface{}, checkNil bool, e } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32StringR(rv reflect.Value) { fastpathTV.EncMapUint32StringV(rv.Interface().(map[uint32]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32StringV(v map[uint32]string, checkNil bool, e *Encoder) { @@ -6526,27 +4962,14 @@ func (_ fastpathT) EncMapUint32StringV(v map[uint32]string, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32UintR(rv reflect.Value) { fastpathTV.EncMapUint32UintV(rv.Interface().(map[uint32]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32UintV(v map[uint32]uint, checkNil bool, e *Encoder) { @@ -6557,27 +4980,14 @@ func (_ fastpathT) EncMapUint32UintV(v map[uint32]uint, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Uint8R(rv reflect.Value) { fastpathTV.EncMapUint32Uint8V(rv.Interface().(map[uint32]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Uint8V(v map[uint32]uint8, checkNil bool, e *Encoder) { @@ -6588,27 +4998,14 @@ func (_ fastpathT) EncMapUint32Uint8V(v map[uint32]uint8, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Uint16R(rv reflect.Value) { fastpathTV.EncMapUint32Uint16V(rv.Interface().(map[uint32]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Uint16V(v map[uint32]uint16, checkNil bool, e *Encoder) { @@ -6619,27 +5016,14 @@ func (_ fastpathT) EncMapUint32Uint16V(v map[uint32]uint16, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Uint32R(rv reflect.Value) { fastpathTV.EncMapUint32Uint32V(rv.Interface().(map[uint32]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Uint32V(v map[uint32]uint32, checkNil bool, e *Encoder) { @@ -6650,27 +5034,14 @@ func (_ fastpathT) EncMapUint32Uint32V(v map[uint32]uint32, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Uint64R(rv reflect.Value) { fastpathTV.EncMapUint32Uint64V(rv.Interface().(map[uint32]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Uint64V(v map[uint32]uint64, checkNil bool, e *Encoder) { @@ -6681,27 +5052,14 @@ func (_ fastpathT) EncMapUint32Uint64V(v map[uint32]uint64, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32IntR(rv reflect.Value) { fastpathTV.EncMapUint32IntV(rv.Interface().(map[uint32]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32IntV(v map[uint32]int, checkNil bool, e *Encoder) { @@ -6712,27 +5070,14 @@ func (_ fastpathT) EncMapUint32IntV(v map[uint32]int, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Int8R(rv reflect.Value) { fastpathTV.EncMapUint32Int8V(rv.Interface().(map[uint32]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Int8V(v map[uint32]int8, checkNil bool, e *Encoder) { @@ -6743,27 +5088,14 @@ func (_ fastpathT) EncMapUint32Int8V(v map[uint32]int8, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Int16R(rv reflect.Value) { fastpathTV.EncMapUint32Int16V(rv.Interface().(map[uint32]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Int16V(v map[uint32]int16, checkNil bool, e *Encoder) { @@ -6774,27 +5106,14 @@ func (_ fastpathT) EncMapUint32Int16V(v map[uint32]int16, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Int32R(rv reflect.Value) { fastpathTV.EncMapUint32Int32V(rv.Interface().(map[uint32]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Int32V(v map[uint32]int32, checkNil bool, e *Encoder) { @@ -6805,27 +5124,14 @@ func (_ fastpathT) EncMapUint32Int32V(v map[uint32]int32, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Int64R(rv reflect.Value) { fastpathTV.EncMapUint32Int64V(rv.Interface().(map[uint32]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Int64V(v map[uint32]int64, checkNil bool, e *Encoder) { @@ -6836,27 +5142,14 @@ func (_ fastpathT) EncMapUint32Int64V(v map[uint32]int64, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Float32R(rv reflect.Value) { fastpathTV.EncMapUint32Float32V(rv.Interface().(map[uint32]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Float32V(v map[uint32]float32, checkNil bool, e *Encoder) { @@ -6867,27 +5160,14 @@ func (_ fastpathT) EncMapUint32Float32V(v map[uint32]float32, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Float64R(rv reflect.Value) { fastpathTV.EncMapUint32Float64V(rv.Interface().(map[uint32]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Float64V(v map[uint32]float64, checkNil bool, e *Encoder) { @@ -6898,27 +5178,14 @@ func (_ fastpathT) EncMapUint32Float64V(v map[uint32]float64, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint32BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32BoolR(rv reflect.Value) { fastpathTV.EncMapUint32BoolV(rv.Interface().(map[uint32]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32BoolV(v map[uint32]bool, checkNil bool, e *Encoder) { @@ -6929,27 +5196,14 @@ func (_ fastpathT) EncMapUint32BoolV(v map[uint32]bool, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64IntfR(rv reflect.Value) { fastpathTV.EncMapUint64IntfV(rv.Interface().(map[uint64]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64IntfV(v map[uint64]interface{}, checkNil bool, e *Encoder) { @@ -6960,27 +5214,14 @@ func (_ fastpathT) EncMapUint64IntfV(v map[uint64]interface{}, checkNil bool, e } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64StringR(rv reflect.Value) { fastpathTV.EncMapUint64StringV(rv.Interface().(map[uint64]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64StringV(v map[uint64]string, checkNil bool, e *Encoder) { @@ -6991,27 +5232,14 @@ func (_ fastpathT) EncMapUint64StringV(v map[uint64]string, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64UintR(rv reflect.Value) { fastpathTV.EncMapUint64UintV(rv.Interface().(map[uint64]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64UintV(v map[uint64]uint, checkNil bool, e *Encoder) { @@ -7020,29 +5248,16 @@ func (_ fastpathT) EncMapUint64UintV(v map[uint64]uint, checkNil bool, e *Encode ee.EncodeNil() return } - ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + ee.EncodeMapStart(len(v)) + + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Uint8R(rv reflect.Value) { fastpathTV.EncMapUint64Uint8V(rv.Interface().(map[uint64]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Uint8V(v map[uint64]uint8, checkNil bool, e *Encoder) { @@ -7053,27 +5268,14 @@ func (_ fastpathT) EncMapUint64Uint8V(v map[uint64]uint8, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Uint16R(rv reflect.Value) { fastpathTV.EncMapUint64Uint16V(rv.Interface().(map[uint64]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Uint16V(v map[uint64]uint16, checkNil bool, e *Encoder) { @@ -7084,27 +5286,14 @@ func (_ fastpathT) EncMapUint64Uint16V(v map[uint64]uint16, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Uint32R(rv reflect.Value) { fastpathTV.EncMapUint64Uint32V(rv.Interface().(map[uint64]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Uint32V(v map[uint64]uint32, checkNil bool, e *Encoder) { @@ -7115,27 +5304,14 @@ func (_ fastpathT) EncMapUint64Uint32V(v map[uint64]uint32, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Uint64R(rv reflect.Value) { fastpathTV.EncMapUint64Uint64V(rv.Interface().(map[uint64]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Uint64V(v map[uint64]uint64, checkNil bool, e *Encoder) { @@ -7146,27 +5322,14 @@ func (_ fastpathT) EncMapUint64Uint64V(v map[uint64]uint64, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64IntR(rv reflect.Value) { fastpathTV.EncMapUint64IntV(rv.Interface().(map[uint64]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64IntV(v map[uint64]int, checkNil bool, e *Encoder) { @@ -7177,27 +5340,14 @@ func (_ fastpathT) EncMapUint64IntV(v map[uint64]int, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Int8R(rv reflect.Value) { fastpathTV.EncMapUint64Int8V(rv.Interface().(map[uint64]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Int8V(v map[uint64]int8, checkNil bool, e *Encoder) { @@ -7208,27 +5358,14 @@ func (_ fastpathT) EncMapUint64Int8V(v map[uint64]int8, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Int16R(rv reflect.Value) { fastpathTV.EncMapUint64Int16V(rv.Interface().(map[uint64]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Int16V(v map[uint64]int16, checkNil bool, e *Encoder) { @@ -7239,27 +5376,14 @@ func (_ fastpathT) EncMapUint64Int16V(v map[uint64]int16, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Int32R(rv reflect.Value) { fastpathTV.EncMapUint64Int32V(rv.Interface().(map[uint64]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Int32V(v map[uint64]int32, checkNil bool, e *Encoder) { @@ -7270,27 +5394,14 @@ func (_ fastpathT) EncMapUint64Int32V(v map[uint64]int32, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Int64R(rv reflect.Value) { fastpathTV.EncMapUint64Int64V(rv.Interface().(map[uint64]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Int64V(v map[uint64]int64, checkNil bool, e *Encoder) { @@ -7301,27 +5412,14 @@ func (_ fastpathT) EncMapUint64Int64V(v map[uint64]int64, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Float32R(rv reflect.Value) { fastpathTV.EncMapUint64Float32V(rv.Interface().(map[uint64]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Float32V(v map[uint64]float32, checkNil bool, e *Encoder) { @@ -7332,27 +5430,14 @@ func (_ fastpathT) EncMapUint64Float32V(v map[uint64]float32, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Float64R(rv reflect.Value) { fastpathTV.EncMapUint64Float64V(rv.Interface().(map[uint64]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Float64V(v map[uint64]float64, checkNil bool, e *Encoder) { @@ -7363,27 +5448,14 @@ func (_ fastpathT) EncMapUint64Float64V(v map[uint64]float64, checkNil bool, e * } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapUint64BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64BoolR(rv reflect.Value) { fastpathTV.EncMapUint64BoolV(rv.Interface().(map[uint64]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64BoolV(v map[uint64]bool, checkNil bool, e *Encoder) { @@ -7394,27 +5466,14 @@ func (_ fastpathT) EncMapUint64BoolV(v map[uint64]bool, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeUint(uint64(k2)) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntIntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntIntfR(rv reflect.Value) { fastpathTV.EncMapIntIntfV(rv.Interface().(map[int]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntIntfV(v map[int]interface{}, checkNil bool, e *Encoder) { @@ -7425,27 +5484,14 @@ func (_ fastpathT) EncMapIntIntfV(v map[int]interface{}, checkNil bool, e *Encod } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntStringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntStringR(rv reflect.Value) { fastpathTV.EncMapIntStringV(rv.Interface().(map[int]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntStringV(v map[int]string, checkNil bool, e *Encoder) { @@ -7456,27 +5502,14 @@ func (_ fastpathT) EncMapIntStringV(v map[int]string, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntUintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntUintR(rv reflect.Value) { fastpathTV.EncMapIntUintV(rv.Interface().(map[int]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntUintV(v map[int]uint, checkNil bool, e *Encoder) { @@ -7487,27 +5520,14 @@ func (_ fastpathT) EncMapIntUintV(v map[int]uint, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntUint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntUint8R(rv reflect.Value) { fastpathTV.EncMapIntUint8V(rv.Interface().(map[int]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntUint8V(v map[int]uint8, checkNil bool, e *Encoder) { @@ -7518,27 +5538,14 @@ func (_ fastpathT) EncMapIntUint8V(v map[int]uint8, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntUint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntUint16R(rv reflect.Value) { fastpathTV.EncMapIntUint16V(rv.Interface().(map[int]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntUint16V(v map[int]uint16, checkNil bool, e *Encoder) { @@ -7549,27 +5556,14 @@ func (_ fastpathT) EncMapIntUint16V(v map[int]uint16, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntUint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntUint32R(rv reflect.Value) { fastpathTV.EncMapIntUint32V(rv.Interface().(map[int]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntUint32V(v map[int]uint32, checkNil bool, e *Encoder) { @@ -7580,27 +5574,14 @@ func (_ fastpathT) EncMapIntUint32V(v map[int]uint32, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntUint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntUint64R(rv reflect.Value) { fastpathTV.EncMapIntUint64V(rv.Interface().(map[int]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntUint64V(v map[int]uint64, checkNil bool, e *Encoder) { @@ -7611,27 +5592,14 @@ func (_ fastpathT) EncMapIntUint64V(v map[int]uint64, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntIntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntIntR(rv reflect.Value) { fastpathTV.EncMapIntIntV(rv.Interface().(map[int]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntIntV(v map[int]int, checkNil bool, e *Encoder) { @@ -7642,27 +5610,14 @@ func (_ fastpathT) EncMapIntIntV(v map[int]int, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntInt8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntInt8R(rv reflect.Value) { fastpathTV.EncMapIntInt8V(rv.Interface().(map[int]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntInt8V(v map[int]int8, checkNil bool, e *Encoder) { @@ -7673,27 +5628,14 @@ func (_ fastpathT) EncMapIntInt8V(v map[int]int8, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntInt16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntInt16R(rv reflect.Value) { fastpathTV.EncMapIntInt16V(rv.Interface().(map[int]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntInt16V(v map[int]int16, checkNil bool, e *Encoder) { @@ -7704,27 +5646,14 @@ func (_ fastpathT) EncMapIntInt16V(v map[int]int16, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntInt32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntInt32R(rv reflect.Value) { fastpathTV.EncMapIntInt32V(rv.Interface().(map[int]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntInt32V(v map[int]int32, checkNil bool, e *Encoder) { @@ -7735,27 +5664,14 @@ func (_ fastpathT) EncMapIntInt32V(v map[int]int32, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntInt64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntInt64R(rv reflect.Value) { fastpathTV.EncMapIntInt64V(rv.Interface().(map[int]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntInt64V(v map[int]int64, checkNil bool, e *Encoder) { @@ -7766,27 +5682,14 @@ func (_ fastpathT) EncMapIntInt64V(v map[int]int64, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntFloat32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntFloat32R(rv reflect.Value) { fastpathTV.EncMapIntFloat32V(rv.Interface().(map[int]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntFloat32V(v map[int]float32, checkNil bool, e *Encoder) { @@ -7797,27 +5700,14 @@ func (_ fastpathT) EncMapIntFloat32V(v map[int]float32, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntFloat64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntFloat64R(rv reflect.Value) { fastpathTV.EncMapIntFloat64V(rv.Interface().(map[int]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntFloat64V(v map[int]float64, checkNil bool, e *Encoder) { @@ -7828,27 +5718,14 @@ func (_ fastpathT) EncMapIntFloat64V(v map[int]float64, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapIntBoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntBoolR(rv reflect.Value) { fastpathTV.EncMapIntBoolV(rv.Interface().(map[int]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntBoolV(v map[int]bool, checkNil bool, e *Encoder) { @@ -7859,27 +5736,14 @@ func (_ fastpathT) EncMapIntBoolV(v map[int]bool, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8IntfR(rv reflect.Value) { fastpathTV.EncMapInt8IntfV(rv.Interface().(map[int8]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8IntfV(v map[int8]interface{}, checkNil bool, e *Encoder) { @@ -7890,27 +5754,14 @@ func (_ fastpathT) EncMapInt8IntfV(v map[int8]interface{}, checkNil bool, e *Enc } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8StringR(rv reflect.Value) { fastpathTV.EncMapInt8StringV(rv.Interface().(map[int8]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8StringV(v map[int8]string, checkNil bool, e *Encoder) { @@ -7921,27 +5772,14 @@ func (_ fastpathT) EncMapInt8StringV(v map[int8]string, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8UintR(rv reflect.Value) { fastpathTV.EncMapInt8UintV(rv.Interface().(map[int8]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8UintV(v map[int8]uint, checkNil bool, e *Encoder) { @@ -7952,27 +5790,14 @@ func (_ fastpathT) EncMapInt8UintV(v map[int8]uint, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Uint8R(rv reflect.Value) { fastpathTV.EncMapInt8Uint8V(rv.Interface().(map[int8]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Uint8V(v map[int8]uint8, checkNil bool, e *Encoder) { @@ -7983,27 +5808,14 @@ func (_ fastpathT) EncMapInt8Uint8V(v map[int8]uint8, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Uint16R(rv reflect.Value) { fastpathTV.EncMapInt8Uint16V(rv.Interface().(map[int8]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Uint16V(v map[int8]uint16, checkNil bool, e *Encoder) { @@ -8014,27 +5826,14 @@ func (_ fastpathT) EncMapInt8Uint16V(v map[int8]uint16, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Uint32R(rv reflect.Value) { fastpathTV.EncMapInt8Uint32V(rv.Interface().(map[int8]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Uint32V(v map[int8]uint32, checkNil bool, e *Encoder) { @@ -8045,27 +5844,14 @@ func (_ fastpathT) EncMapInt8Uint32V(v map[int8]uint32, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Uint64R(rv reflect.Value) { fastpathTV.EncMapInt8Uint64V(rv.Interface().(map[int8]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Uint64V(v map[int8]uint64, checkNil bool, e *Encoder) { @@ -8076,27 +5862,14 @@ func (_ fastpathT) EncMapInt8Uint64V(v map[int8]uint64, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8IntR(rv reflect.Value) { fastpathTV.EncMapInt8IntV(rv.Interface().(map[int8]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8IntV(v map[int8]int, checkNil bool, e *Encoder) { @@ -8107,27 +5880,14 @@ func (_ fastpathT) EncMapInt8IntV(v map[int8]int, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Int8R(rv reflect.Value) { fastpathTV.EncMapInt8Int8V(rv.Interface().(map[int8]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Int8V(v map[int8]int8, checkNil bool, e *Encoder) { @@ -8138,27 +5898,14 @@ func (_ fastpathT) EncMapInt8Int8V(v map[int8]int8, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Int16R(rv reflect.Value) { fastpathTV.EncMapInt8Int16V(rv.Interface().(map[int8]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Int16V(v map[int8]int16, checkNil bool, e *Encoder) { @@ -8169,27 +5916,14 @@ func (_ fastpathT) EncMapInt8Int16V(v map[int8]int16, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Int32R(rv reflect.Value) { fastpathTV.EncMapInt8Int32V(rv.Interface().(map[int8]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Int32V(v map[int8]int32, checkNil bool, e *Encoder) { @@ -8200,27 +5934,14 @@ func (_ fastpathT) EncMapInt8Int32V(v map[int8]int32, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Int64R(rv reflect.Value) { fastpathTV.EncMapInt8Int64V(rv.Interface().(map[int8]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Int64V(v map[int8]int64, checkNil bool, e *Encoder) { @@ -8231,27 +5952,14 @@ func (_ fastpathT) EncMapInt8Int64V(v map[int8]int64, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Float32R(rv reflect.Value) { fastpathTV.EncMapInt8Float32V(rv.Interface().(map[int8]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Float32V(v map[int8]float32, checkNil bool, e *Encoder) { @@ -8262,27 +5970,14 @@ func (_ fastpathT) EncMapInt8Float32V(v map[int8]float32, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Float64R(rv reflect.Value) { fastpathTV.EncMapInt8Float64V(rv.Interface().(map[int8]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Float64V(v map[int8]float64, checkNil bool, e *Encoder) { @@ -8293,27 +5988,14 @@ func (_ fastpathT) EncMapInt8Float64V(v map[int8]float64, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt8BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8BoolR(rv reflect.Value) { fastpathTV.EncMapInt8BoolV(rv.Interface().(map[int8]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8BoolV(v map[int8]bool, checkNil bool, e *Encoder) { @@ -8324,27 +6006,14 @@ func (_ fastpathT) EncMapInt8BoolV(v map[int8]bool, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16IntfR(rv reflect.Value) { fastpathTV.EncMapInt16IntfV(rv.Interface().(map[int16]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16IntfV(v map[int16]interface{}, checkNil bool, e *Encoder) { @@ -8355,27 +6024,14 @@ func (_ fastpathT) EncMapInt16IntfV(v map[int16]interface{}, checkNil bool, e *E } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16StringR(rv reflect.Value) { fastpathTV.EncMapInt16StringV(rv.Interface().(map[int16]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16StringV(v map[int16]string, checkNil bool, e *Encoder) { @@ -8386,27 +6042,14 @@ func (_ fastpathT) EncMapInt16StringV(v map[int16]string, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16UintR(rv reflect.Value) { fastpathTV.EncMapInt16UintV(rv.Interface().(map[int16]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16UintV(v map[int16]uint, checkNil bool, e *Encoder) { @@ -8417,27 +6060,14 @@ func (_ fastpathT) EncMapInt16UintV(v map[int16]uint, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Uint8R(rv reflect.Value) { fastpathTV.EncMapInt16Uint8V(rv.Interface().(map[int16]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Uint8V(v map[int16]uint8, checkNil bool, e *Encoder) { @@ -8448,27 +6078,14 @@ func (_ fastpathT) EncMapInt16Uint8V(v map[int16]uint8, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Uint16R(rv reflect.Value) { fastpathTV.EncMapInt16Uint16V(rv.Interface().(map[int16]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Uint16V(v map[int16]uint16, checkNil bool, e *Encoder) { @@ -8479,27 +6096,14 @@ func (_ fastpathT) EncMapInt16Uint16V(v map[int16]uint16, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Uint32R(rv reflect.Value) { fastpathTV.EncMapInt16Uint32V(rv.Interface().(map[int16]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Uint32V(v map[int16]uint32, checkNil bool, e *Encoder) { @@ -8510,27 +6114,14 @@ func (_ fastpathT) EncMapInt16Uint32V(v map[int16]uint32, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Uint64R(rv reflect.Value) { fastpathTV.EncMapInt16Uint64V(rv.Interface().(map[int16]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Uint64V(v map[int16]uint64, checkNil bool, e *Encoder) { @@ -8541,58 +6132,32 @@ func (_ fastpathT) EncMapInt16Uint64V(v map[int16]uint64, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16IntR(rv reflect.Value) { fastpathTV.EncMapInt16IntV(rv.Interface().(map[int16]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16IntV(v map[int16]int, checkNil bool, e *Encoder) { ee := e.e if checkNil && v == nil { ee.EncodeNil() - return - } - ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + return + } + ee.EncodeMapStart(len(v)) + + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Int8R(rv reflect.Value) { fastpathTV.EncMapInt16Int8V(rv.Interface().(map[int16]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Int8V(v map[int16]int8, checkNil bool, e *Encoder) { @@ -8603,27 +6168,14 @@ func (_ fastpathT) EncMapInt16Int8V(v map[int16]int8, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Int16R(rv reflect.Value) { fastpathTV.EncMapInt16Int16V(rv.Interface().(map[int16]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Int16V(v map[int16]int16, checkNil bool, e *Encoder) { @@ -8634,27 +6186,14 @@ func (_ fastpathT) EncMapInt16Int16V(v map[int16]int16, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Int32R(rv reflect.Value) { fastpathTV.EncMapInt16Int32V(rv.Interface().(map[int16]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Int32V(v map[int16]int32, checkNil bool, e *Encoder) { @@ -8665,27 +6204,14 @@ func (_ fastpathT) EncMapInt16Int32V(v map[int16]int32, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Int64R(rv reflect.Value) { fastpathTV.EncMapInt16Int64V(rv.Interface().(map[int16]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Int64V(v map[int16]int64, checkNil bool, e *Encoder) { @@ -8696,27 +6222,14 @@ func (_ fastpathT) EncMapInt16Int64V(v map[int16]int64, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Float32R(rv reflect.Value) { fastpathTV.EncMapInt16Float32V(rv.Interface().(map[int16]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Float32V(v map[int16]float32, checkNil bool, e *Encoder) { @@ -8727,27 +6240,14 @@ func (_ fastpathT) EncMapInt16Float32V(v map[int16]float32, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Float64R(rv reflect.Value) { fastpathTV.EncMapInt16Float64V(rv.Interface().(map[int16]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Float64V(v map[int16]float64, checkNil bool, e *Encoder) { @@ -8758,27 +6258,14 @@ func (_ fastpathT) EncMapInt16Float64V(v map[int16]float64, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt16BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16BoolR(rv reflect.Value) { fastpathTV.EncMapInt16BoolV(rv.Interface().(map[int16]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16BoolV(v map[int16]bool, checkNil bool, e *Encoder) { @@ -8789,27 +6276,14 @@ func (_ fastpathT) EncMapInt16BoolV(v map[int16]bool, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32IntfR(rv reflect.Value) { fastpathTV.EncMapInt32IntfV(rv.Interface().(map[int32]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32IntfV(v map[int32]interface{}, checkNil bool, e *Encoder) { @@ -8820,27 +6294,14 @@ func (_ fastpathT) EncMapInt32IntfV(v map[int32]interface{}, checkNil bool, e *E } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32StringR(rv reflect.Value) { fastpathTV.EncMapInt32StringV(rv.Interface().(map[int32]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32StringV(v map[int32]string, checkNil bool, e *Encoder) { @@ -8851,27 +6312,14 @@ func (_ fastpathT) EncMapInt32StringV(v map[int32]string, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32UintR(rv reflect.Value) { fastpathTV.EncMapInt32UintV(rv.Interface().(map[int32]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32UintV(v map[int32]uint, checkNil bool, e *Encoder) { @@ -8882,27 +6330,14 @@ func (_ fastpathT) EncMapInt32UintV(v map[int32]uint, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Uint8R(rv reflect.Value) { fastpathTV.EncMapInt32Uint8V(rv.Interface().(map[int32]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Uint8V(v map[int32]uint8, checkNil bool, e *Encoder) { @@ -8913,27 +6348,14 @@ func (_ fastpathT) EncMapInt32Uint8V(v map[int32]uint8, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Uint16R(rv reflect.Value) { fastpathTV.EncMapInt32Uint16V(rv.Interface().(map[int32]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Uint16V(v map[int32]uint16, checkNil bool, e *Encoder) { @@ -8944,27 +6366,14 @@ func (_ fastpathT) EncMapInt32Uint16V(v map[int32]uint16, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Uint32R(rv reflect.Value) { fastpathTV.EncMapInt32Uint32V(rv.Interface().(map[int32]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Uint32V(v map[int32]uint32, checkNil bool, e *Encoder) { @@ -8975,27 +6384,14 @@ func (_ fastpathT) EncMapInt32Uint32V(v map[int32]uint32, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Uint64R(rv reflect.Value) { fastpathTV.EncMapInt32Uint64V(rv.Interface().(map[int32]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Uint64V(v map[int32]uint64, checkNil bool, e *Encoder) { @@ -9006,27 +6402,14 @@ func (_ fastpathT) EncMapInt32Uint64V(v map[int32]uint64, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32IntR(rv reflect.Value) { fastpathTV.EncMapInt32IntV(rv.Interface().(map[int32]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32IntV(v map[int32]int, checkNil bool, e *Encoder) { @@ -9037,27 +6420,14 @@ func (_ fastpathT) EncMapInt32IntV(v map[int32]int, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Int8R(rv reflect.Value) { fastpathTV.EncMapInt32Int8V(rv.Interface().(map[int32]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Int8V(v map[int32]int8, checkNil bool, e *Encoder) { @@ -9068,27 +6438,14 @@ func (_ fastpathT) EncMapInt32Int8V(v map[int32]int8, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Int16R(rv reflect.Value) { fastpathTV.EncMapInt32Int16V(rv.Interface().(map[int32]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Int16V(v map[int32]int16, checkNil bool, e *Encoder) { @@ -9099,27 +6456,14 @@ func (_ fastpathT) EncMapInt32Int16V(v map[int32]int16, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Int32R(rv reflect.Value) { fastpathTV.EncMapInt32Int32V(rv.Interface().(map[int32]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Int32V(v map[int32]int32, checkNil bool, e *Encoder) { @@ -9130,27 +6474,14 @@ func (_ fastpathT) EncMapInt32Int32V(v map[int32]int32, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Int64R(rv reflect.Value) { fastpathTV.EncMapInt32Int64V(rv.Interface().(map[int32]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Int64V(v map[int32]int64, checkNil bool, e *Encoder) { @@ -9161,27 +6492,14 @@ func (_ fastpathT) EncMapInt32Int64V(v map[int32]int64, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Float32R(rv reflect.Value) { fastpathTV.EncMapInt32Float32V(rv.Interface().(map[int32]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Float32V(v map[int32]float32, checkNil bool, e *Encoder) { @@ -9192,27 +6510,14 @@ func (_ fastpathT) EncMapInt32Float32V(v map[int32]float32, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Float64R(rv reflect.Value) { fastpathTV.EncMapInt32Float64V(rv.Interface().(map[int32]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Float64V(v map[int32]float64, checkNil bool, e *Encoder) { @@ -9223,27 +6528,14 @@ func (_ fastpathT) EncMapInt32Float64V(v map[int32]float64, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt32BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32BoolR(rv reflect.Value) { fastpathTV.EncMapInt32BoolV(rv.Interface().(map[int32]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32BoolV(v map[int32]bool, checkNil bool, e *Encoder) { @@ -9254,27 +6546,14 @@ func (_ fastpathT) EncMapInt32BoolV(v map[int32]bool, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64IntfR(rv reflect.Value) { fastpathTV.EncMapInt64IntfV(rv.Interface().(map[int64]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64IntfV(v map[int64]interface{}, checkNil bool, e *Encoder) { @@ -9285,27 +6564,14 @@ func (_ fastpathT) EncMapInt64IntfV(v map[int64]interface{}, checkNil bool, e *E } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64StringR(rv reflect.Value) { fastpathTV.EncMapInt64StringV(rv.Interface().(map[int64]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64StringV(v map[int64]string, checkNil bool, e *Encoder) { @@ -9316,27 +6582,14 @@ func (_ fastpathT) EncMapInt64StringV(v map[int64]string, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64UintR(rv reflect.Value) { fastpathTV.EncMapInt64UintV(rv.Interface().(map[int64]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64UintV(v map[int64]uint, checkNil bool, e *Encoder) { @@ -9347,27 +6600,14 @@ func (_ fastpathT) EncMapInt64UintV(v map[int64]uint, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Uint8R(rv reflect.Value) { fastpathTV.EncMapInt64Uint8V(rv.Interface().(map[int64]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Uint8V(v map[int64]uint8, checkNil bool, e *Encoder) { @@ -9378,27 +6618,14 @@ func (_ fastpathT) EncMapInt64Uint8V(v map[int64]uint8, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Uint16R(rv reflect.Value) { fastpathTV.EncMapInt64Uint16V(rv.Interface().(map[int64]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Uint16V(v map[int64]uint16, checkNil bool, e *Encoder) { @@ -9409,27 +6636,14 @@ func (_ fastpathT) EncMapInt64Uint16V(v map[int64]uint16, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Uint32R(rv reflect.Value) { fastpathTV.EncMapInt64Uint32V(rv.Interface().(map[int64]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Uint32V(v map[int64]uint32, checkNil bool, e *Encoder) { @@ -9440,27 +6654,14 @@ func (_ fastpathT) EncMapInt64Uint32V(v map[int64]uint32, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Uint64R(rv reflect.Value) { fastpathTV.EncMapInt64Uint64V(rv.Interface().(map[int64]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Uint64V(v map[int64]uint64, checkNil bool, e *Encoder) { @@ -9471,27 +6672,14 @@ func (_ fastpathT) EncMapInt64Uint64V(v map[int64]uint64, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64IntR(rv reflect.Value) { fastpathTV.EncMapInt64IntV(rv.Interface().(map[int64]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64IntV(v map[int64]int, checkNil bool, e *Encoder) { @@ -9502,27 +6690,14 @@ func (_ fastpathT) EncMapInt64IntV(v map[int64]int, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Int8R(rv reflect.Value) { fastpathTV.EncMapInt64Int8V(rv.Interface().(map[int64]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Int8V(v map[int64]int8, checkNil bool, e *Encoder) { @@ -9533,27 +6708,14 @@ func (_ fastpathT) EncMapInt64Int8V(v map[int64]int8, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Int16R(rv reflect.Value) { fastpathTV.EncMapInt64Int16V(rv.Interface().(map[int64]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Int16V(v map[int64]int16, checkNil bool, e *Encoder) { @@ -9564,27 +6726,14 @@ func (_ fastpathT) EncMapInt64Int16V(v map[int64]int16, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Int32R(rv reflect.Value) { fastpathTV.EncMapInt64Int32V(rv.Interface().(map[int64]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Int32V(v map[int64]int32, checkNil bool, e *Encoder) { @@ -9595,27 +6744,14 @@ func (_ fastpathT) EncMapInt64Int32V(v map[int64]int32, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Int64R(rv reflect.Value) { fastpathTV.EncMapInt64Int64V(rv.Interface().(map[int64]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Int64V(v map[int64]int64, checkNil bool, e *Encoder) { @@ -9626,27 +6762,14 @@ func (_ fastpathT) EncMapInt64Int64V(v map[int64]int64, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Float32R(rv reflect.Value) { fastpathTV.EncMapInt64Float32V(rv.Interface().(map[int64]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Float32V(v map[int64]float32, checkNil bool, e *Encoder) { @@ -9657,27 +6780,14 @@ func (_ fastpathT) EncMapInt64Float32V(v map[int64]float32, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Float64R(rv reflect.Value) { fastpathTV.EncMapInt64Float64V(rv.Interface().(map[int64]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Float64V(v map[int64]float64, checkNil bool, e *Encoder) { @@ -9688,27 +6798,14 @@ func (_ fastpathT) EncMapInt64Float64V(v map[int64]float64, checkNil bool, e *En } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapInt64BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64BoolR(rv reflect.Value) { fastpathTV.EncMapInt64BoolV(rv.Interface().(map[int64]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64BoolV(v map[int64]bool, checkNil bool, e *Encoder) { @@ -9719,27 +6816,14 @@ func (_ fastpathT) EncMapInt64BoolV(v map[int64]bool, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeInt(int64(k2)) + ee.EncodeBool(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolIntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolIntfR(rv reflect.Value) { fastpathTV.EncMapBoolIntfV(rv.Interface().(map[bool]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolIntfV(v map[bool]interface{}, checkNil bool, e *Encoder) { @@ -9750,27 +6834,14 @@ func (_ fastpathT) EncMapBoolIntfV(v map[bool]interface{}, checkNil bool, e *Enc } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - e.encode(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - e.encode(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + e.encode(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolStringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolStringR(rv reflect.Value) { fastpathTV.EncMapBoolStringV(rv.Interface().(map[bool]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolStringV(v map[bool]string, checkNil bool, e *Encoder) { @@ -9781,27 +6852,14 @@ func (_ fastpathT) EncMapBoolStringV(v map[bool]string, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeString(c_UTF8, v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeString(c_UTF8, v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeString(c_UTF8, v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolUintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolUintR(rv reflect.Value) { fastpathTV.EncMapBoolUintV(rv.Interface().(map[bool]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolUintV(v map[bool]uint, checkNil bool, e *Encoder) { @@ -9812,27 +6870,14 @@ func (_ fastpathT) EncMapBoolUintV(v map[bool]uint, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolUint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolUint8R(rv reflect.Value) { fastpathTV.EncMapBoolUint8V(rv.Interface().(map[bool]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolUint8V(v map[bool]uint8, checkNil bool, e *Encoder) { @@ -9843,27 +6888,14 @@ func (_ fastpathT) EncMapBoolUint8V(v map[bool]uint8, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolUint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolUint16R(rv reflect.Value) { fastpathTV.EncMapBoolUint16V(rv.Interface().(map[bool]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolUint16V(v map[bool]uint16, checkNil bool, e *Encoder) { @@ -9874,27 +6906,14 @@ func (_ fastpathT) EncMapBoolUint16V(v map[bool]uint16, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolUint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolUint32R(rv reflect.Value) { fastpathTV.EncMapBoolUint32V(rv.Interface().(map[bool]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolUint32V(v map[bool]uint32, checkNil bool, e *Encoder) { @@ -9905,27 +6924,14 @@ func (_ fastpathT) EncMapBoolUint32V(v map[bool]uint32, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolUint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolUint64R(rv reflect.Value) { fastpathTV.EncMapBoolUint64V(rv.Interface().(map[bool]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolUint64V(v map[bool]uint64, checkNil bool, e *Encoder) { @@ -9936,27 +6942,14 @@ func (_ fastpathT) EncMapBoolUint64V(v map[bool]uint64, checkNil bool, e *Encode } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeUint(uint64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeUint(uint64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeUint(uint64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolIntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolIntR(rv reflect.Value) { fastpathTV.EncMapBoolIntV(rv.Interface().(map[bool]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolIntV(v map[bool]int, checkNil bool, e *Encoder) { @@ -9967,27 +6960,14 @@ func (_ fastpathT) EncMapBoolIntV(v map[bool]int, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolInt8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolInt8R(rv reflect.Value) { fastpathTV.EncMapBoolInt8V(rv.Interface().(map[bool]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolInt8V(v map[bool]int8, checkNil bool, e *Encoder) { @@ -9998,27 +6978,14 @@ func (_ fastpathT) EncMapBoolInt8V(v map[bool]int8, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolInt16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolInt16R(rv reflect.Value) { fastpathTV.EncMapBoolInt16V(rv.Interface().(map[bool]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolInt16V(v map[bool]int16, checkNil bool, e *Encoder) { @@ -10029,27 +6996,14 @@ func (_ fastpathT) EncMapBoolInt16V(v map[bool]int16, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolInt32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolInt32R(rv reflect.Value) { fastpathTV.EncMapBoolInt32V(rv.Interface().(map[bool]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolInt32V(v map[bool]int32, checkNil bool, e *Encoder) { @@ -10060,27 +7014,14 @@ func (_ fastpathT) EncMapBoolInt32V(v map[bool]int32, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolInt64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolInt64R(rv reflect.Value) { fastpathTV.EncMapBoolInt64V(rv.Interface().(map[bool]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolInt64V(v map[bool]int64, checkNil bool, e *Encoder) { @@ -10091,27 +7032,14 @@ func (_ fastpathT) EncMapBoolInt64V(v map[bool]int64, checkNil bool, e *Encoder) } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeInt(int64(v2)) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeInt(int64(v2)) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeInt(int64(v2)) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolFloat32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolFloat32R(rv reflect.Value) { fastpathTV.EncMapBoolFloat32V(rv.Interface().(map[bool]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolFloat32V(v map[bool]float32, checkNil bool, e *Encoder) { @@ -10120,29 +7048,16 @@ func (_ fastpathT) EncMapBoolFloat32V(v map[bool]float32, checkNil bool, e *Enco ee.EncodeNil() return } - ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeFloat32(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeFloat32(v2) - j++ - } - ee.EncodeMapEnd() + ee.EncodeMapStart(len(v)) + + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeFloat32(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolFloat64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolFloat64R(rv reflect.Value) { fastpathTV.EncMapBoolFloat64V(rv.Interface().(map[bool]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolFloat64V(v map[bool]float64, checkNil bool, e *Encoder) { @@ -10153,27 +7068,14 @@ func (_ fastpathT) EncMapBoolFloat64V(v map[bool]float64, checkNil bool, e *Enco } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeFloat64(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeFloat64(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeFloat64(v2) } + ee.EncodeEnd() } -func (f encFnInfo) fastpathEncMapBoolBoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolBoolR(rv reflect.Value) { fastpathTV.EncMapBoolBoolV(rv.Interface().(map[bool]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolBoolV(v map[bool]bool, checkNil bool, e *Encoder) { @@ -10184,24 +7086,11 @@ func (_ fastpathT) EncMapBoolBoolV(v map[bool]bool, checkNil bool, e *Encoder) { } ee.EncodeMapStart(len(v)) - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeBool(v2) - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() - ee.EncodeBool(v2) - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + ee.EncodeBool(k2) + ee.EncodeBool(v2) } + ee.EncodeEnd() } // -- decode @@ -12130,9 +9019,9 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { // -- -- fast path functions -func (f decFnInfo) fastpathDecSliceIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceIntfR(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]interface{}) v, changed := fastpathTV.DecSliceIntfV(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12153,7 +9042,7 @@ func (f fastpathT) DecSliceIntfX(vp *[]interface{}, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, d *Decoder) (_ []interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12162,12 +9051,14 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []interface{}{} - } else { - v = make([]interface{}, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 16); xtrunc { + x2read = xlen } + v = make([]interface{}, xlen) changed = true } if containerLenS == 0 { @@ -12178,29 +9069,34 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]interface{}, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 16); xtrunc { + x2read = xlen + } + v = make([]interface{}, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { d.decode(&v[j]) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, nil) + d.decode(&v[j]) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -12216,10 +9112,7 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { d.decode(&v[j]) } else { @@ -12231,9 +9124,9 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceStringR(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]string) v, changed := fastpathTV.DecSliceStringV(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12254,7 +9147,7 @@ func (f fastpathT) DecSliceStringX(vp *[]string, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d *Decoder) (_ []string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12263,12 +9156,14 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []string{} - } else { - v = make([]string, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 16); xtrunc { + x2read = xlen } + v = make([]string, xlen) changed = true } if containerLenS == 0 { @@ -12279,29 +9174,34 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]string, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 16); xtrunc { + x2read = xlen + } + v = make([]string, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = dd.DecodeString() } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, "") + v[j] = dd.DecodeString() + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -12317,10 +9217,7 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = dd.DecodeString() } else { d.swallow() @@ -12331,9 +9228,9 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceFloat32R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]float32) v, changed := fastpathTV.DecSliceFloat32V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12354,7 +9251,7 @@ func (f fastpathT) DecSliceFloat32X(vp *[]float32, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, d *Decoder) (_ []float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12363,12 +9260,14 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []float32{} - } else { - v = make([]float32, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4); xtrunc { + x2read = xlen } + v = make([]float32, xlen) changed = true } if containerLenS == 0 { @@ -12379,29 +9278,34 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]float32, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4); xtrunc { + x2read = xlen + } + v = make([]float32, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = float32(dd.DecodeFloat(true)) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + v[j] = float32(dd.DecodeFloat(true)) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -12417,10 +9321,7 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = float32(dd.DecodeFloat(true)) } else { d.swallow() @@ -12431,9 +9332,9 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceFloat64R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]float64) v, changed := fastpathTV.DecSliceFloat64V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12454,7 +9355,7 @@ func (f fastpathT) DecSliceFloat64X(vp *[]float64, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, d *Decoder) (_ []float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12463,12 +9364,14 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []float64{} - } else { - v = make([]float64, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8); xtrunc { + x2read = xlen } + v = make([]float64, xlen) changed = true } if containerLenS == 0 { @@ -12479,29 +9382,34 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]float64, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8); xtrunc { + x2read = xlen + } + v = make([]float64, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = dd.DecodeFloat(false) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + v[j] = dd.DecodeFloat(false) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -12517,10 +9425,7 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = dd.DecodeFloat(false) } else { d.swallow() @@ -12531,9 +9436,9 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceUintR(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]uint) v, changed := fastpathTV.DecSliceUintV(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12554,7 +9459,7 @@ func (f fastpathT) DecSliceUintX(vp *[]uint, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d *Decoder) (_ []uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12563,12 +9468,14 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []uint{} - } else { - v = make([]uint, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8); xtrunc { + x2read = xlen } + v = make([]uint, xlen) changed = true } if containerLenS == 0 { @@ -12579,29 +9486,34 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]uint, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8); xtrunc { + x2read = xlen + } + v = make([]uint, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = uint(dd.DecodeUint(uintBitsize)) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + v[j] = uint(dd.DecodeUint(uintBitsize)) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -12617,10 +9529,7 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = uint(dd.DecodeUint(uintBitsize)) } else { d.swallow() @@ -12631,9 +9540,9 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceUint16R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]uint16) v, changed := fastpathTV.DecSliceUint16V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12654,7 +9563,7 @@ func (f fastpathT) DecSliceUint16X(vp *[]uint16, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d *Decoder) (_ []uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12663,12 +9572,14 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []uint16{} - } else { - v = make([]uint16, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 2); xtrunc { + x2read = xlen } + v = make([]uint16, xlen) changed = true } if containerLenS == 0 { @@ -12679,29 +9590,34 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]uint16, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 2); xtrunc { + x2read = xlen + } + v = make([]uint16, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = uint16(dd.DecodeUint(16)) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + v[j] = uint16(dd.DecodeUint(16)) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -12717,10 +9633,7 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = uint16(dd.DecodeUint(16)) } else { d.swallow() @@ -12731,9 +9644,9 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceUint32R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]uint32) v, changed := fastpathTV.DecSliceUint32V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12754,7 +9667,7 @@ func (f fastpathT) DecSliceUint32X(vp *[]uint32, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d *Decoder) (_ []uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12763,12 +9676,14 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []uint32{} - } else { - v = make([]uint32, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4); xtrunc { + x2read = xlen } + v = make([]uint32, xlen) changed = true } if containerLenS == 0 { @@ -12779,29 +9694,34 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]uint32, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4); xtrunc { + x2read = xlen + } + v = make([]uint32, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = uint32(dd.DecodeUint(32)) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + v[j] = uint32(dd.DecodeUint(32)) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -12817,10 +9737,7 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = uint32(dd.DecodeUint(32)) } else { d.swallow() @@ -12831,9 +9748,9 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceUint64R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]uint64) v, changed := fastpathTV.DecSliceUint64V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12854,7 +9771,7 @@ func (f fastpathT) DecSliceUint64X(vp *[]uint64, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d *Decoder) (_ []uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12863,12 +9780,14 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []uint64{} - } else { - v = make([]uint64, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8); xtrunc { + x2read = xlen } + v = make([]uint64, xlen) changed = true } if containerLenS == 0 { @@ -12879,29 +9798,34 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]uint64, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8); xtrunc { + x2read = xlen + } + v = make([]uint64, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = dd.DecodeUint(64) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + v[j] = dd.DecodeUint(64) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -12917,10 +9841,7 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = dd.DecodeUint(64) } else { d.swallow() @@ -12931,9 +9852,9 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceIntR(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]int) v, changed := fastpathTV.DecSliceIntV(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12954,7 +9875,7 @@ func (f fastpathT) DecSliceIntX(vp *[]int, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d *Decoder) (_ []int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12963,12 +9884,14 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []int{} - } else { - v = make([]int, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8); xtrunc { + x2read = xlen } + v = make([]int, xlen) changed = true } if containerLenS == 0 { @@ -12979,29 +9902,34 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]int, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8); xtrunc { + x2read = xlen + } + v = make([]int, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = int(dd.DecodeInt(intBitsize)) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + v[j] = int(dd.DecodeInt(intBitsize)) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -13017,10 +9945,7 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = int(dd.DecodeInt(intBitsize)) } else { d.swallow() @@ -13031,9 +9956,9 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceInt8R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]int8) v, changed := fastpathTV.DecSliceInt8V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -13054,7 +9979,7 @@ func (f fastpathT) DecSliceInt8X(vp *[]int8, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d *Decoder) (_ []int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13063,12 +9988,14 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []int8{} - } else { - v = make([]int8, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 1); xtrunc { + x2read = xlen } + v = make([]int8, xlen) changed = true } if containerLenS == 0 { @@ -13079,29 +10006,34 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]int8, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 1); xtrunc { + x2read = xlen + } + v = make([]int8, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = int8(dd.DecodeInt(8)) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + v[j] = int8(dd.DecodeInt(8)) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -13117,10 +10049,7 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = int8(dd.DecodeInt(8)) } else { d.swallow() @@ -13131,9 +10060,9 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceInt16R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]int16) v, changed := fastpathTV.DecSliceInt16V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -13154,7 +10083,7 @@ func (f fastpathT) DecSliceInt16X(vp *[]int16, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d *Decoder) (_ []int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13163,12 +10092,14 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []int16{} - } else { - v = make([]int16, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 2); xtrunc { + x2read = xlen } + v = make([]int16, xlen) changed = true } if containerLenS == 0 { @@ -13179,29 +10110,34 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]int16, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 2); xtrunc { + x2read = xlen + } + v = make([]int16, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = int16(dd.DecodeInt(16)) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + v[j] = int16(dd.DecodeInt(16)) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -13217,10 +10153,7 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = int16(dd.DecodeInt(16)) } else { d.swallow() @@ -13231,9 +10164,9 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceInt32R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]int32) v, changed := fastpathTV.DecSliceInt32V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -13254,7 +10187,7 @@ func (f fastpathT) DecSliceInt32X(vp *[]int32, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d *Decoder) (_ []int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13263,12 +10196,14 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []int32{} - } else { - v = make([]int32, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4); xtrunc { + x2read = xlen } + v = make([]int32, xlen) changed = true } if containerLenS == 0 { @@ -13279,29 +10214,34 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]int32, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4); xtrunc { + x2read = xlen + } + v = make([]int32, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = int32(dd.DecodeInt(32)) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + v[j] = int32(dd.DecodeInt(32)) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -13317,10 +10257,7 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = int32(dd.DecodeInt(32)) } else { d.swallow() @@ -13331,9 +10268,9 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceInt64R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]int64) v, changed := fastpathTV.DecSliceInt64V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -13354,7 +10291,7 @@ func (f fastpathT) DecSliceInt64X(vp *[]int64, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d *Decoder) (_ []int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13363,12 +10300,14 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []int64{} - } else { - v = make([]int64, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8); xtrunc { + x2read = xlen } + v = make([]int64, xlen) changed = true } if containerLenS == 0 { @@ -13379,29 +10318,34 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]int64, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8); xtrunc { + x2read = xlen + } + v = make([]int64, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = dd.DecodeInt(64) } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + v[j] = dd.DecodeInt(64) + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -13417,10 +10361,7 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = dd.DecodeInt(64) } else { d.swallow() @@ -13431,9 +10372,9 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecSliceBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceBoolR(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]bool) v, changed := fastpathTV.DecSliceBoolV(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -13454,7 +10395,7 @@ func (f fastpathT) DecSliceBoolX(vp *[]bool, checkNil bool, d *Decoder) { func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d *Decoder) (_ []bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13463,12 +10404,14 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []bool{} - } else { - v = make([]bool, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 1); xtrunc { + x2read = xlen } + v = make([]bool, xlen) changed = true } if containerLenS == 0 { @@ -13479,29 +10422,34 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { if canChange { - s := make([]bool, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 1); xtrunc { + x2read = xlen + } + v = make([]bool, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { v[j] = dd.DecodeBool() } - if !canChange { + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, false) + v[j] = dd.DecodeBool() + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -13517,10 +10465,7 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { v[j] = dd.DecodeBool() } else { d.swallow() @@ -13531,7 +10476,7 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, return v, changed } -func (f decFnInfo) fastpathDecMapIntfIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfIntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]interface{}) v, changed := fastpathTV.DecMapIntfIntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -13552,7 +10497,7 @@ func (f fastpathT) DecMapIntfIntfX(vp *map[interface{}]interface{}, checkNil boo func (_ fastpathT) DecMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13562,11 +10507,8 @@ func (_ fastpathT) DecMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]interface{}, containerLen) - } else { - v = make(map[interface{}]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32) + v = make(map[interface{}]interface{}, xlen) changed = true } if containerLen > 0 { @@ -13574,7 +10516,7 @@ func (_ fastpathT) DecMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] d.decode(&mv) @@ -13585,15 +10527,11 @@ func (_ fastpathT) DecMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -13601,12 +10539,12 @@ func (_ fastpathT) DecMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfStringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]string) v, changed := fastpathTV.DecMapIntfStringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -13627,7 +10565,7 @@ func (f fastpathT) DecMapIntfStringX(vp *map[interface{}]string, checkNil bool, func (_ fastpathT) DecMapIntfStringV(v map[interface{}]string, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13637,11 +10575,8 @@ func (_ fastpathT) DecMapIntfStringV(v map[interface{}]string, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]string, containerLen) - } else { - v = make(map[interface{}]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32) + v = make(map[interface{}]string, xlen) changed = true } if containerLen > 0 { @@ -13649,7 +10584,7 @@ func (_ fastpathT) DecMapIntfStringV(v map[interface{}]string, checkNil bool, ca var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = dd.DecodeString() @@ -13659,27 +10594,23 @@ func (_ fastpathT) DecMapIntfStringV(v map[interface{}]string, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfUintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]uint) v, changed := fastpathTV.DecMapIntfUintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -13700,7 +10631,7 @@ func (f fastpathT) DecMapIntfUintX(vp *map[interface{}]uint, checkNil bool, d *D func (_ fastpathT) DecMapIntfUintV(v map[interface{}]uint, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13710,11 +10641,8 @@ func (_ fastpathT) DecMapIntfUintV(v map[interface{}]uint, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]uint, containerLen) - } else { - v = make(map[interface{}]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[interface{}]uint, xlen) changed = true } if containerLen > 0 { @@ -13722,7 +10650,7 @@ func (_ fastpathT) DecMapIntfUintV(v map[interface{}]uint, checkNil bool, canCha var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) @@ -13732,27 +10660,23 @@ func (_ fastpathT) DecMapIntfUintV(v map[interface{}]uint, checkNil bool, canCha } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfUint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfUint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]uint8) v, changed := fastpathTV.DecMapIntfUint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -13773,7 +10697,7 @@ func (f fastpathT) DecMapIntfUint8X(vp *map[interface{}]uint8, checkNil bool, d func (_ fastpathT) DecMapIntfUint8V(v map[interface{}]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13783,11 +10707,8 @@ func (_ fastpathT) DecMapIntfUint8V(v map[interface{}]uint8, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]uint8, containerLen) - } else { - v = make(map[interface{}]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[interface{}]uint8, xlen) changed = true } if containerLen > 0 { @@ -13795,7 +10716,7 @@ func (_ fastpathT) DecMapIntfUint8V(v map[interface{}]uint8, checkNil bool, canC var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = uint8(dd.DecodeUint(8)) @@ -13805,27 +10726,23 @@ func (_ fastpathT) DecMapIntfUint8V(v map[interface{}]uint8, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfUint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]uint16) v, changed := fastpathTV.DecMapIntfUint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -13846,7 +10763,7 @@ func (f fastpathT) DecMapIntfUint16X(vp *map[interface{}]uint16, checkNil bool, func (_ fastpathT) DecMapIntfUint16V(v map[interface{}]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13856,11 +10773,8 @@ func (_ fastpathT) DecMapIntfUint16V(v map[interface{}]uint16, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]uint16, containerLen) - } else { - v = make(map[interface{}]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[interface{}]uint16, xlen) changed = true } if containerLen > 0 { @@ -13868,7 +10782,7 @@ func (_ fastpathT) DecMapIntfUint16V(v map[interface{}]uint16, checkNil bool, ca var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = uint16(dd.DecodeUint(16)) @@ -13878,27 +10792,23 @@ func (_ fastpathT) DecMapIntfUint16V(v map[interface{}]uint16, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfUint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]uint32) v, changed := fastpathTV.DecMapIntfUint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -13919,7 +10829,7 @@ func (f fastpathT) DecMapIntfUint32X(vp *map[interface{}]uint32, checkNil bool, func (_ fastpathT) DecMapIntfUint32V(v map[interface{}]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13929,11 +10839,8 @@ func (_ fastpathT) DecMapIntfUint32V(v map[interface{}]uint32, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]uint32, containerLen) - } else { - v = make(map[interface{}]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[interface{}]uint32, xlen) changed = true } if containerLen > 0 { @@ -13941,7 +10848,7 @@ func (_ fastpathT) DecMapIntfUint32V(v map[interface{}]uint32, checkNil bool, ca var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = uint32(dd.DecodeUint(32)) @@ -13951,27 +10858,23 @@ func (_ fastpathT) DecMapIntfUint32V(v map[interface{}]uint32, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfUint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]uint64) v, changed := fastpathTV.DecMapIntfUint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -13992,7 +10895,7 @@ func (f fastpathT) DecMapIntfUint64X(vp *map[interface{}]uint64, checkNil bool, func (_ fastpathT) DecMapIntfUint64V(v map[interface{}]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14002,11 +10905,8 @@ func (_ fastpathT) DecMapIntfUint64V(v map[interface{}]uint64, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]uint64, containerLen) - } else { - v = make(map[interface{}]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[interface{}]uint64, xlen) changed = true } if containerLen > 0 { @@ -14014,7 +10914,7 @@ func (_ fastpathT) DecMapIntfUint64V(v map[interface{}]uint64, checkNil bool, ca var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = dd.DecodeUint(64) @@ -14024,27 +10924,23 @@ func (_ fastpathT) DecMapIntfUint64V(v map[interface{}]uint64, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfIntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]int) v, changed := fastpathTV.DecMapIntfIntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -14065,7 +10961,7 @@ func (f fastpathT) DecMapIntfIntX(vp *map[interface{}]int, checkNil bool, d *Dec func (_ fastpathT) DecMapIntfIntV(v map[interface{}]int, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14075,11 +10971,8 @@ func (_ fastpathT) DecMapIntfIntV(v map[interface{}]int, checkNil bool, canChang containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]int, containerLen) - } else { - v = make(map[interface{}]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[interface{}]int, xlen) changed = true } if containerLen > 0 { @@ -14087,7 +10980,7 @@ func (_ fastpathT) DecMapIntfIntV(v map[interface{}]int, checkNil bool, canChang var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) @@ -14097,27 +10990,23 @@ func (_ fastpathT) DecMapIntfIntV(v map[interface{}]int, checkNil bool, canChang } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfInt8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]int8) v, changed := fastpathTV.DecMapIntfInt8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14138,7 +11027,7 @@ func (f fastpathT) DecMapIntfInt8X(vp *map[interface{}]int8, checkNil bool, d *D func (_ fastpathT) DecMapIntfInt8V(v map[interface{}]int8, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14148,11 +11037,8 @@ func (_ fastpathT) DecMapIntfInt8V(v map[interface{}]int8, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]int8, containerLen) - } else { - v = make(map[interface{}]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[interface{}]int8, xlen) changed = true } if containerLen > 0 { @@ -14160,7 +11046,7 @@ func (_ fastpathT) DecMapIntfInt8V(v map[interface{}]int8, checkNil bool, canCha var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = int8(dd.DecodeInt(8)) @@ -14170,27 +11056,23 @@ func (_ fastpathT) DecMapIntfInt8V(v map[interface{}]int8, checkNil bool, canCha } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfInt16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]int16) v, changed := fastpathTV.DecMapIntfInt16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14211,7 +11093,7 @@ func (f fastpathT) DecMapIntfInt16X(vp *map[interface{}]int16, checkNil bool, d func (_ fastpathT) DecMapIntfInt16V(v map[interface{}]int16, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14221,11 +11103,8 @@ func (_ fastpathT) DecMapIntfInt16V(v map[interface{}]int16, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]int16, containerLen) - } else { - v = make(map[interface{}]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[interface{}]int16, xlen) changed = true } if containerLen > 0 { @@ -14233,7 +11112,7 @@ func (_ fastpathT) DecMapIntfInt16V(v map[interface{}]int16, checkNil bool, canC var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = int16(dd.DecodeInt(16)) @@ -14243,27 +11122,23 @@ func (_ fastpathT) DecMapIntfInt16V(v map[interface{}]int16, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfInt32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]int32) v, changed := fastpathTV.DecMapIntfInt32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14284,7 +11159,7 @@ func (f fastpathT) DecMapIntfInt32X(vp *map[interface{}]int32, checkNil bool, d func (_ fastpathT) DecMapIntfInt32V(v map[interface{}]int32, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14294,11 +11169,8 @@ func (_ fastpathT) DecMapIntfInt32V(v map[interface{}]int32, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]int32, containerLen) - } else { - v = make(map[interface{}]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[interface{}]int32, xlen) changed = true } if containerLen > 0 { @@ -14306,7 +11178,7 @@ func (_ fastpathT) DecMapIntfInt32V(v map[interface{}]int32, checkNil bool, canC var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = int32(dd.DecodeInt(32)) @@ -14316,27 +11188,23 @@ func (_ fastpathT) DecMapIntfInt32V(v map[interface{}]int32, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfInt64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]int64) v, changed := fastpathTV.DecMapIntfInt64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14357,7 +11225,7 @@ func (f fastpathT) DecMapIntfInt64X(vp *map[interface{}]int64, checkNil bool, d func (_ fastpathT) DecMapIntfInt64V(v map[interface{}]int64, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14367,11 +11235,8 @@ func (_ fastpathT) DecMapIntfInt64V(v map[interface{}]int64, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]int64, containerLen) - } else { - v = make(map[interface{}]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[interface{}]int64, xlen) changed = true } if containerLen > 0 { @@ -14379,7 +11244,7 @@ func (_ fastpathT) DecMapIntfInt64V(v map[interface{}]int64, checkNil bool, canC var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = dd.DecodeInt(64) @@ -14389,27 +11254,23 @@ func (_ fastpathT) DecMapIntfInt64V(v map[interface{}]int64, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfFloat32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]float32) v, changed := fastpathTV.DecMapIntfFloat32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14430,7 +11291,7 @@ func (f fastpathT) DecMapIntfFloat32X(vp *map[interface{}]float32, checkNil bool func (_ fastpathT) DecMapIntfFloat32V(v map[interface{}]float32, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14440,11 +11301,8 @@ func (_ fastpathT) DecMapIntfFloat32V(v map[interface{}]float32, checkNil bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]float32, containerLen) - } else { - v = make(map[interface{}]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[interface{}]float32, xlen) changed = true } if containerLen > 0 { @@ -14452,7 +11310,7 @@ func (_ fastpathT) DecMapIntfFloat32V(v map[interface{}]float32, checkNil bool, var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = float32(dd.DecodeFloat(true)) @@ -14462,27 +11320,23 @@ func (_ fastpathT) DecMapIntfFloat32V(v map[interface{}]float32, checkNil bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfFloat64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]float64) v, changed := fastpathTV.DecMapIntfFloat64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14503,7 +11357,7 @@ func (f fastpathT) DecMapIntfFloat64X(vp *map[interface{}]float64, checkNil bool func (_ fastpathT) DecMapIntfFloat64V(v map[interface{}]float64, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14513,11 +11367,8 @@ func (_ fastpathT) DecMapIntfFloat64V(v map[interface{}]float64, checkNil bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]float64, containerLen) - } else { - v = make(map[interface{}]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[interface{}]float64, xlen) changed = true } if containerLen > 0 { @@ -14525,7 +11376,7 @@ func (_ fastpathT) DecMapIntfFloat64V(v map[interface{}]float64, checkNil bool, var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = dd.DecodeFloat(false) @@ -14535,27 +11386,23 @@ func (_ fastpathT) DecMapIntfFloat64V(v map[interface{}]float64, checkNil bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntfBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfBoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]bool) v, changed := fastpathTV.DecMapIntfBoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -14576,7 +11423,7 @@ func (f fastpathT) DecMapIntfBoolX(vp *map[interface{}]bool, checkNil bool, d *D func (_ fastpathT) DecMapIntfBoolV(v map[interface{}]bool, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14586,11 +11433,8 @@ func (_ fastpathT) DecMapIntfBoolV(v map[interface{}]bool, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]bool, containerLen) - } else { - v = make(map[interface{}]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[interface{}]bool, xlen) changed = true } if containerLen > 0 { @@ -14598,7 +11442,7 @@ func (_ fastpathT) DecMapIntfBoolV(v map[interface{}]bool, checkNil bool, canCha var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } mv := v[mk] mv = dd.DecodeBool() @@ -14608,27 +11452,23 @@ func (_ fastpathT) DecMapIntfBoolV(v map[interface{}]bool, checkNil bool, canCha } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) } - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringIntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]interface{}) v, changed := fastpathTV.DecMapStringIntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -14649,7 +11489,7 @@ func (f fastpathT) DecMapStringIntfX(vp *map[string]interface{}, checkNil bool, func (_ fastpathT) DecMapStringIntfV(v map[string]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[string]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14659,11 +11499,8 @@ func (_ fastpathT) DecMapStringIntfV(v map[string]interface{}, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]interface{}, containerLen) - } else { - v = make(map[string]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32) + v = make(map[string]interface{}, xlen) changed = true } if containerLen > 0 { @@ -14678,11 +11515,7 @@ func (_ fastpathT) DecMapStringIntfV(v map[string]interface{}, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -14690,12 +11523,12 @@ func (_ fastpathT) DecMapStringIntfV(v map[string]interface{}, checkNil bool, ca v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringStringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]string) v, changed := fastpathTV.DecMapStringStringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -14716,7 +11549,7 @@ func (f fastpathT) DecMapStringStringX(vp *map[string]string, checkNil bool, d * func (_ fastpathT) DecMapStringStringV(v map[string]string, checkNil bool, canChange bool, d *Decoder) (_ map[string]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14726,11 +11559,8 @@ func (_ fastpathT) DecMapStringStringV(v map[string]string, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]string, containerLen) - } else { - v = make(map[string]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32) + v = make(map[string]string, xlen) changed = true } if containerLen > 0 { @@ -14744,23 +11574,19 @@ func (_ fastpathT) DecMapStringStringV(v map[string]string, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringUintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]uint) v, changed := fastpathTV.DecMapStringUintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -14781,7 +11607,7 @@ func (f fastpathT) DecMapStringUintX(vp *map[string]uint, checkNil bool, d *Deco func (_ fastpathT) DecMapStringUintV(v map[string]uint, checkNil bool, canChange bool, d *Decoder) (_ map[string]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14791,11 +11617,8 @@ func (_ fastpathT) DecMapStringUintV(v map[string]uint, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]uint, containerLen) - } else { - v = make(map[string]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[string]uint, xlen) changed = true } if containerLen > 0 { @@ -14809,23 +11632,19 @@ func (_ fastpathT) DecMapStringUintV(v map[string]uint, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringUint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringUint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]uint8) v, changed := fastpathTV.DecMapStringUint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14846,7 +11665,7 @@ func (f fastpathT) DecMapStringUint8X(vp *map[string]uint8, checkNil bool, d *De func (_ fastpathT) DecMapStringUint8V(v map[string]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[string]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14856,11 +11675,8 @@ func (_ fastpathT) DecMapStringUint8V(v map[string]uint8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]uint8, containerLen) - } else { - v = make(map[string]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[string]uint8, xlen) changed = true } if containerLen > 0 { @@ -14874,23 +11690,19 @@ func (_ fastpathT) DecMapStringUint8V(v map[string]uint8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringUint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]uint16) v, changed := fastpathTV.DecMapStringUint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14911,7 +11723,7 @@ func (f fastpathT) DecMapStringUint16X(vp *map[string]uint16, checkNil bool, d * func (_ fastpathT) DecMapStringUint16V(v map[string]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[string]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14921,11 +11733,8 @@ func (_ fastpathT) DecMapStringUint16V(v map[string]uint16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]uint16, containerLen) - } else { - v = make(map[string]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[string]uint16, xlen) changed = true } if containerLen > 0 { @@ -14939,23 +11748,19 @@ func (_ fastpathT) DecMapStringUint16V(v map[string]uint16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringUint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]uint32) v, changed := fastpathTV.DecMapStringUint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14976,7 +11781,7 @@ func (f fastpathT) DecMapStringUint32X(vp *map[string]uint32, checkNil bool, d * func (_ fastpathT) DecMapStringUint32V(v map[string]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[string]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14986,11 +11791,8 @@ func (_ fastpathT) DecMapStringUint32V(v map[string]uint32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]uint32, containerLen) - } else { - v = make(map[string]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[string]uint32, xlen) changed = true } if containerLen > 0 { @@ -15004,23 +11806,19 @@ func (_ fastpathT) DecMapStringUint32V(v map[string]uint32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringUint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]uint64) v, changed := fastpathTV.DecMapStringUint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15041,7 +11839,7 @@ func (f fastpathT) DecMapStringUint64X(vp *map[string]uint64, checkNil bool, d * func (_ fastpathT) DecMapStringUint64V(v map[string]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[string]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15051,11 +11849,8 @@ func (_ fastpathT) DecMapStringUint64V(v map[string]uint64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]uint64, containerLen) - } else { - v = make(map[string]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[string]uint64, xlen) changed = true } if containerLen > 0 { @@ -15069,23 +11864,19 @@ func (_ fastpathT) DecMapStringUint64V(v map[string]uint64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringIntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]int) v, changed := fastpathTV.DecMapStringIntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -15106,7 +11897,7 @@ func (f fastpathT) DecMapStringIntX(vp *map[string]int, checkNil bool, d *Decode func (_ fastpathT) DecMapStringIntV(v map[string]int, checkNil bool, canChange bool, d *Decoder) (_ map[string]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15116,11 +11907,8 @@ func (_ fastpathT) DecMapStringIntV(v map[string]int, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]int, containerLen) - } else { - v = make(map[string]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[string]int, xlen) changed = true } if containerLen > 0 { @@ -15134,23 +11922,19 @@ func (_ fastpathT) DecMapStringIntV(v map[string]int, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringInt8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]int8) v, changed := fastpathTV.DecMapStringInt8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15171,7 +11955,7 @@ func (f fastpathT) DecMapStringInt8X(vp *map[string]int8, checkNil bool, d *Deco func (_ fastpathT) DecMapStringInt8V(v map[string]int8, checkNil bool, canChange bool, d *Decoder) (_ map[string]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15181,11 +11965,8 @@ func (_ fastpathT) DecMapStringInt8V(v map[string]int8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]int8, containerLen) - } else { - v = make(map[string]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[string]int8, xlen) changed = true } if containerLen > 0 { @@ -15199,23 +11980,19 @@ func (_ fastpathT) DecMapStringInt8V(v map[string]int8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringInt16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]int16) v, changed := fastpathTV.DecMapStringInt16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15236,7 +12013,7 @@ func (f fastpathT) DecMapStringInt16X(vp *map[string]int16, checkNil bool, d *De func (_ fastpathT) DecMapStringInt16V(v map[string]int16, checkNil bool, canChange bool, d *Decoder) (_ map[string]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15246,11 +12023,8 @@ func (_ fastpathT) DecMapStringInt16V(v map[string]int16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]int16, containerLen) - } else { - v = make(map[string]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[string]int16, xlen) changed = true } if containerLen > 0 { @@ -15264,23 +12038,19 @@ func (_ fastpathT) DecMapStringInt16V(v map[string]int16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringInt32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]int32) v, changed := fastpathTV.DecMapStringInt32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15301,7 +12071,7 @@ func (f fastpathT) DecMapStringInt32X(vp *map[string]int32, checkNil bool, d *De func (_ fastpathT) DecMapStringInt32V(v map[string]int32, checkNil bool, canChange bool, d *Decoder) (_ map[string]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15311,11 +12081,8 @@ func (_ fastpathT) DecMapStringInt32V(v map[string]int32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]int32, containerLen) - } else { - v = make(map[string]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[string]int32, xlen) changed = true } if containerLen > 0 { @@ -15329,23 +12096,19 @@ func (_ fastpathT) DecMapStringInt32V(v map[string]int32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringInt64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]int64) v, changed := fastpathTV.DecMapStringInt64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15366,7 +12129,7 @@ func (f fastpathT) DecMapStringInt64X(vp *map[string]int64, checkNil bool, d *De func (_ fastpathT) DecMapStringInt64V(v map[string]int64, checkNil bool, canChange bool, d *Decoder) (_ map[string]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15376,11 +12139,8 @@ func (_ fastpathT) DecMapStringInt64V(v map[string]int64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]int64, containerLen) - } else { - v = make(map[string]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[string]int64, xlen) changed = true } if containerLen > 0 { @@ -15394,23 +12154,19 @@ func (_ fastpathT) DecMapStringInt64V(v map[string]int64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringFloat32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]float32) v, changed := fastpathTV.DecMapStringFloat32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15431,7 +12187,7 @@ func (f fastpathT) DecMapStringFloat32X(vp *map[string]float32, checkNil bool, d func (_ fastpathT) DecMapStringFloat32V(v map[string]float32, checkNil bool, canChange bool, d *Decoder) (_ map[string]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15441,11 +12197,8 @@ func (_ fastpathT) DecMapStringFloat32V(v map[string]float32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]float32, containerLen) - } else { - v = make(map[string]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[string]float32, xlen) changed = true } if containerLen > 0 { @@ -15459,23 +12212,19 @@ func (_ fastpathT) DecMapStringFloat32V(v map[string]float32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringFloat64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]float64) v, changed := fastpathTV.DecMapStringFloat64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15496,7 +12245,7 @@ func (f fastpathT) DecMapStringFloat64X(vp *map[string]float64, checkNil bool, d func (_ fastpathT) DecMapStringFloat64V(v map[string]float64, checkNil bool, canChange bool, d *Decoder) (_ map[string]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15506,11 +12255,8 @@ func (_ fastpathT) DecMapStringFloat64V(v map[string]float64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]float64, containerLen) - } else { - v = make(map[string]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[string]float64, xlen) changed = true } if containerLen > 0 { @@ -15524,23 +12270,19 @@ func (_ fastpathT) DecMapStringFloat64V(v map[string]float64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapStringBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringBoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]bool) v, changed := fastpathTV.DecMapStringBoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -15561,7 +12303,7 @@ func (f fastpathT) DecMapStringBoolX(vp *map[string]bool, checkNil bool, d *Deco func (_ fastpathT) DecMapStringBoolV(v map[string]bool, checkNil bool, canChange bool, d *Decoder) (_ map[string]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15571,11 +12313,8 @@ func (_ fastpathT) DecMapStringBoolV(v map[string]bool, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]bool, containerLen) - } else { - v = make(map[string]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[string]bool, xlen) changed = true } if containerLen > 0 { @@ -15589,23 +12328,19 @@ func (_ fastpathT) DecMapStringBoolV(v map[string]bool, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeString() - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]interface{}) v, changed := fastpathTV.DecMapFloat32IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -15626,7 +12361,7 @@ func (f fastpathT) DecMapFloat32IntfX(vp *map[float32]interface{}, checkNil bool func (_ fastpathT) DecMapFloat32IntfV(v map[float32]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[float32]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15636,11 +12371,8 @@ func (_ fastpathT) DecMapFloat32IntfV(v map[float32]interface{}, checkNil bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]interface{}, containerLen) - } else { - v = make(map[float32]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[float32]interface{}, xlen) changed = true } if containerLen > 0 { @@ -15655,11 +12387,7 @@ func (_ fastpathT) DecMapFloat32IntfV(v map[float32]interface{}, checkNil bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -15667,12 +12395,12 @@ func (_ fastpathT) DecMapFloat32IntfV(v map[float32]interface{}, checkNil bool, v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]string) v, changed := fastpathTV.DecMapFloat32StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -15693,7 +12421,7 @@ func (f fastpathT) DecMapFloat32StringX(vp *map[float32]string, checkNil bool, d func (_ fastpathT) DecMapFloat32StringV(v map[float32]string, checkNil bool, canChange bool, d *Decoder) (_ map[float32]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15703,11 +12431,8 @@ func (_ fastpathT) DecMapFloat32StringV(v map[float32]string, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]string, containerLen) - } else { - v = make(map[float32]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[float32]string, xlen) changed = true } if containerLen > 0 { @@ -15721,23 +12446,19 @@ func (_ fastpathT) DecMapFloat32StringV(v map[float32]string, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]uint) v, changed := fastpathTV.DecMapFloat32UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -15758,7 +12479,7 @@ func (f fastpathT) DecMapFloat32UintX(vp *map[float32]uint, checkNil bool, d *De func (_ fastpathT) DecMapFloat32UintV(v map[float32]uint, checkNil bool, canChange bool, d *Decoder) (_ map[float32]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15768,11 +12489,8 @@ func (_ fastpathT) DecMapFloat32UintV(v map[float32]uint, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]uint, containerLen) - } else { - v = make(map[float32]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float32]uint, xlen) changed = true } if containerLen > 0 { @@ -15786,23 +12504,19 @@ func (_ fastpathT) DecMapFloat32UintV(v map[float32]uint, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]uint8) v, changed := fastpathTV.DecMapFloat32Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15823,7 +12537,7 @@ func (f fastpathT) DecMapFloat32Uint8X(vp *map[float32]uint8, checkNil bool, d * func (_ fastpathT) DecMapFloat32Uint8V(v map[float32]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[float32]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15833,11 +12547,8 @@ func (_ fastpathT) DecMapFloat32Uint8V(v map[float32]uint8, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]uint8, containerLen) - } else { - v = make(map[float32]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[float32]uint8, xlen) changed = true } if containerLen > 0 { @@ -15851,23 +12562,19 @@ func (_ fastpathT) DecMapFloat32Uint8V(v map[float32]uint8, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]uint16) v, changed := fastpathTV.DecMapFloat32Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15888,7 +12595,7 @@ func (f fastpathT) DecMapFloat32Uint16X(vp *map[float32]uint16, checkNil bool, d func (_ fastpathT) DecMapFloat32Uint16V(v map[float32]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[float32]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15898,11 +12605,8 @@ func (_ fastpathT) DecMapFloat32Uint16V(v map[float32]uint16, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]uint16, containerLen) - } else { - v = make(map[float32]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[float32]uint16, xlen) changed = true } if containerLen > 0 { @@ -15916,23 +12620,19 @@ func (_ fastpathT) DecMapFloat32Uint16V(v map[float32]uint16, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]uint32) v, changed := fastpathTV.DecMapFloat32Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15953,7 +12653,7 @@ func (f fastpathT) DecMapFloat32Uint32X(vp *map[float32]uint32, checkNil bool, d func (_ fastpathT) DecMapFloat32Uint32V(v map[float32]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[float32]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15963,11 +12663,8 @@ func (_ fastpathT) DecMapFloat32Uint32V(v map[float32]uint32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]uint32, containerLen) - } else { - v = make(map[float32]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[float32]uint32, xlen) changed = true } if containerLen > 0 { @@ -15981,23 +12678,19 @@ func (_ fastpathT) DecMapFloat32Uint32V(v map[float32]uint32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]uint64) v, changed := fastpathTV.DecMapFloat32Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16018,7 +12711,7 @@ func (f fastpathT) DecMapFloat32Uint64X(vp *map[float32]uint64, checkNil bool, d func (_ fastpathT) DecMapFloat32Uint64V(v map[float32]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[float32]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16028,11 +12721,8 @@ func (_ fastpathT) DecMapFloat32Uint64V(v map[float32]uint64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]uint64, containerLen) - } else { - v = make(map[float32]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float32]uint64, xlen) changed = true } if containerLen > 0 { @@ -16046,23 +12736,19 @@ func (_ fastpathT) DecMapFloat32Uint64V(v map[float32]uint64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]int) v, changed := fastpathTV.DecMapFloat32IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -16083,7 +12769,7 @@ func (f fastpathT) DecMapFloat32IntX(vp *map[float32]int, checkNil bool, d *Deco func (_ fastpathT) DecMapFloat32IntV(v map[float32]int, checkNil bool, canChange bool, d *Decoder) (_ map[float32]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16093,11 +12779,8 @@ func (_ fastpathT) DecMapFloat32IntV(v map[float32]int, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]int, containerLen) - } else { - v = make(map[float32]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float32]int, xlen) changed = true } if containerLen > 0 { @@ -16111,23 +12794,19 @@ func (_ fastpathT) DecMapFloat32IntV(v map[float32]int, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]int8) v, changed := fastpathTV.DecMapFloat32Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16148,7 +12827,7 @@ func (f fastpathT) DecMapFloat32Int8X(vp *map[float32]int8, checkNil bool, d *De func (_ fastpathT) DecMapFloat32Int8V(v map[float32]int8, checkNil bool, canChange bool, d *Decoder) (_ map[float32]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16158,11 +12837,8 @@ func (_ fastpathT) DecMapFloat32Int8V(v map[float32]int8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]int8, containerLen) - } else { - v = make(map[float32]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[float32]int8, xlen) changed = true } if containerLen > 0 { @@ -16176,23 +12852,19 @@ func (_ fastpathT) DecMapFloat32Int8V(v map[float32]int8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]int16) v, changed := fastpathTV.DecMapFloat32Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16213,7 +12885,7 @@ func (f fastpathT) DecMapFloat32Int16X(vp *map[float32]int16, checkNil bool, d * func (_ fastpathT) DecMapFloat32Int16V(v map[float32]int16, checkNil bool, canChange bool, d *Decoder) (_ map[float32]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16223,11 +12895,8 @@ func (_ fastpathT) DecMapFloat32Int16V(v map[float32]int16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]int16, containerLen) - } else { - v = make(map[float32]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[float32]int16, xlen) changed = true } if containerLen > 0 { @@ -16241,23 +12910,19 @@ func (_ fastpathT) DecMapFloat32Int16V(v map[float32]int16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]int32) v, changed := fastpathTV.DecMapFloat32Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16278,7 +12943,7 @@ func (f fastpathT) DecMapFloat32Int32X(vp *map[float32]int32, checkNil bool, d * func (_ fastpathT) DecMapFloat32Int32V(v map[float32]int32, checkNil bool, canChange bool, d *Decoder) (_ map[float32]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16288,11 +12953,8 @@ func (_ fastpathT) DecMapFloat32Int32V(v map[float32]int32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]int32, containerLen) - } else { - v = make(map[float32]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[float32]int32, xlen) changed = true } if containerLen > 0 { @@ -16306,23 +12968,19 @@ func (_ fastpathT) DecMapFloat32Int32V(v map[float32]int32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]int64) v, changed := fastpathTV.DecMapFloat32Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16343,7 +13001,7 @@ func (f fastpathT) DecMapFloat32Int64X(vp *map[float32]int64, checkNil bool, d * func (_ fastpathT) DecMapFloat32Int64V(v map[float32]int64, checkNil bool, canChange bool, d *Decoder) (_ map[float32]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16353,11 +13011,8 @@ func (_ fastpathT) DecMapFloat32Int64V(v map[float32]int64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]int64, containerLen) - } else { - v = make(map[float32]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float32]int64, xlen) changed = true } if containerLen > 0 { @@ -16371,23 +13026,19 @@ func (_ fastpathT) DecMapFloat32Int64V(v map[float32]int64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]float32) v, changed := fastpathTV.DecMapFloat32Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16408,7 +13059,7 @@ func (f fastpathT) DecMapFloat32Float32X(vp *map[float32]float32, checkNil bool, func (_ fastpathT) DecMapFloat32Float32V(v map[float32]float32, checkNil bool, canChange bool, d *Decoder) (_ map[float32]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16418,11 +13069,8 @@ func (_ fastpathT) DecMapFloat32Float32V(v map[float32]float32, checkNil bool, c containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]float32, containerLen) - } else { - v = make(map[float32]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[float32]float32, xlen) changed = true } if containerLen > 0 { @@ -16436,23 +13084,19 @@ func (_ fastpathT) DecMapFloat32Float32V(v map[float32]float32, checkNil bool, c } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]float64) v, changed := fastpathTV.DecMapFloat32Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16473,7 +13117,7 @@ func (f fastpathT) DecMapFloat32Float64X(vp *map[float32]float64, checkNil bool, func (_ fastpathT) DecMapFloat32Float64V(v map[float32]float64, checkNil bool, canChange bool, d *Decoder) (_ map[float32]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16483,11 +13127,8 @@ func (_ fastpathT) DecMapFloat32Float64V(v map[float32]float64, checkNil bool, c containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]float64, containerLen) - } else { - v = make(map[float32]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float32]float64, xlen) changed = true } if containerLen > 0 { @@ -16501,23 +13142,19 @@ func (_ fastpathT) DecMapFloat32Float64V(v map[float32]float64, checkNil bool, c } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]bool) v, changed := fastpathTV.DecMapFloat32BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -16538,7 +13175,7 @@ func (f fastpathT) DecMapFloat32BoolX(vp *map[float32]bool, checkNil bool, d *De func (_ fastpathT) DecMapFloat32BoolV(v map[float32]bool, checkNil bool, canChange bool, d *Decoder) (_ map[float32]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16548,11 +13185,8 @@ func (_ fastpathT) DecMapFloat32BoolV(v map[float32]bool, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]bool, containerLen) - } else { - v = make(map[float32]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[float32]bool, xlen) changed = true } if containerLen > 0 { @@ -16566,23 +13200,19 @@ func (_ fastpathT) DecMapFloat32BoolV(v map[float32]bool, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]interface{}) v, changed := fastpathTV.DecMapFloat64IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -16603,7 +13233,7 @@ func (f fastpathT) DecMapFloat64IntfX(vp *map[float64]interface{}, checkNil bool func (_ fastpathT) DecMapFloat64IntfV(v map[float64]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[float64]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16613,11 +13243,8 @@ func (_ fastpathT) DecMapFloat64IntfV(v map[float64]interface{}, checkNil bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]interface{}, containerLen) - } else { - v = make(map[float64]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[float64]interface{}, xlen) changed = true } if containerLen > 0 { @@ -16632,11 +13259,7 @@ func (_ fastpathT) DecMapFloat64IntfV(v map[float64]interface{}, checkNil bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -16644,12 +13267,12 @@ func (_ fastpathT) DecMapFloat64IntfV(v map[float64]interface{}, checkNil bool, v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]string) v, changed := fastpathTV.DecMapFloat64StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -16670,7 +13293,7 @@ func (f fastpathT) DecMapFloat64StringX(vp *map[float64]string, checkNil bool, d func (_ fastpathT) DecMapFloat64StringV(v map[float64]string, checkNil bool, canChange bool, d *Decoder) (_ map[float64]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16680,11 +13303,8 @@ func (_ fastpathT) DecMapFloat64StringV(v map[float64]string, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]string, containerLen) - } else { - v = make(map[float64]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[float64]string, xlen) changed = true } if containerLen > 0 { @@ -16698,23 +13318,19 @@ func (_ fastpathT) DecMapFloat64StringV(v map[float64]string, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]uint) v, changed := fastpathTV.DecMapFloat64UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -16735,7 +13351,7 @@ func (f fastpathT) DecMapFloat64UintX(vp *map[float64]uint, checkNil bool, d *De func (_ fastpathT) DecMapFloat64UintV(v map[float64]uint, checkNil bool, canChange bool, d *Decoder) (_ map[float64]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16745,11 +13361,8 @@ func (_ fastpathT) DecMapFloat64UintV(v map[float64]uint, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]uint, containerLen) - } else { - v = make(map[float64]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[float64]uint, xlen) changed = true } if containerLen > 0 { @@ -16763,23 +13376,19 @@ func (_ fastpathT) DecMapFloat64UintV(v map[float64]uint, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]uint8) v, changed := fastpathTV.DecMapFloat64Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16800,7 +13409,7 @@ func (f fastpathT) DecMapFloat64Uint8X(vp *map[float64]uint8, checkNil bool, d * func (_ fastpathT) DecMapFloat64Uint8V(v map[float64]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[float64]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16810,11 +13419,8 @@ func (_ fastpathT) DecMapFloat64Uint8V(v map[float64]uint8, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]uint8, containerLen) - } else { - v = make(map[float64]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[float64]uint8, xlen) changed = true } if containerLen > 0 { @@ -16828,23 +13434,19 @@ func (_ fastpathT) DecMapFloat64Uint8V(v map[float64]uint8, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]uint16) v, changed := fastpathTV.DecMapFloat64Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16865,7 +13467,7 @@ func (f fastpathT) DecMapFloat64Uint16X(vp *map[float64]uint16, checkNil bool, d func (_ fastpathT) DecMapFloat64Uint16V(v map[float64]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[float64]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16875,11 +13477,8 @@ func (_ fastpathT) DecMapFloat64Uint16V(v map[float64]uint16, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]uint16, containerLen) - } else { - v = make(map[float64]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[float64]uint16, xlen) changed = true } if containerLen > 0 { @@ -16893,23 +13492,19 @@ func (_ fastpathT) DecMapFloat64Uint16V(v map[float64]uint16, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]uint32) v, changed := fastpathTV.DecMapFloat64Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16930,7 +13525,7 @@ func (f fastpathT) DecMapFloat64Uint32X(vp *map[float64]uint32, checkNil bool, d func (_ fastpathT) DecMapFloat64Uint32V(v map[float64]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[float64]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16940,11 +13535,8 @@ func (_ fastpathT) DecMapFloat64Uint32V(v map[float64]uint32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]uint32, containerLen) - } else { - v = make(map[float64]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float64]uint32, xlen) changed = true } if containerLen > 0 { @@ -16958,23 +13550,19 @@ func (_ fastpathT) DecMapFloat64Uint32V(v map[float64]uint32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]uint64) v, changed := fastpathTV.DecMapFloat64Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16995,7 +13583,7 @@ func (f fastpathT) DecMapFloat64Uint64X(vp *map[float64]uint64, checkNil bool, d func (_ fastpathT) DecMapFloat64Uint64V(v map[float64]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[float64]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17005,11 +13593,8 @@ func (_ fastpathT) DecMapFloat64Uint64V(v map[float64]uint64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]uint64, containerLen) - } else { - v = make(map[float64]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[float64]uint64, xlen) changed = true } if containerLen > 0 { @@ -17023,23 +13608,19 @@ func (_ fastpathT) DecMapFloat64Uint64V(v map[float64]uint64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]int) v, changed := fastpathTV.DecMapFloat64IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -17060,7 +13641,7 @@ func (f fastpathT) DecMapFloat64IntX(vp *map[float64]int, checkNil bool, d *Deco func (_ fastpathT) DecMapFloat64IntV(v map[float64]int, checkNil bool, canChange bool, d *Decoder) (_ map[float64]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17070,11 +13651,8 @@ func (_ fastpathT) DecMapFloat64IntV(v map[float64]int, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]int, containerLen) - } else { - v = make(map[float64]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[float64]int, xlen) changed = true } if containerLen > 0 { @@ -17088,23 +13666,19 @@ func (_ fastpathT) DecMapFloat64IntV(v map[float64]int, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]int8) v, changed := fastpathTV.DecMapFloat64Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17125,7 +13699,7 @@ func (f fastpathT) DecMapFloat64Int8X(vp *map[float64]int8, checkNil bool, d *De func (_ fastpathT) DecMapFloat64Int8V(v map[float64]int8, checkNil bool, canChange bool, d *Decoder) (_ map[float64]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17135,11 +13709,8 @@ func (_ fastpathT) DecMapFloat64Int8V(v map[float64]int8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]int8, containerLen) - } else { - v = make(map[float64]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[float64]int8, xlen) changed = true } if containerLen > 0 { @@ -17153,23 +13724,19 @@ func (_ fastpathT) DecMapFloat64Int8V(v map[float64]int8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]int16) v, changed := fastpathTV.DecMapFloat64Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17190,7 +13757,7 @@ func (f fastpathT) DecMapFloat64Int16X(vp *map[float64]int16, checkNil bool, d * func (_ fastpathT) DecMapFloat64Int16V(v map[float64]int16, checkNil bool, canChange bool, d *Decoder) (_ map[float64]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17200,11 +13767,8 @@ func (_ fastpathT) DecMapFloat64Int16V(v map[float64]int16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]int16, containerLen) - } else { - v = make(map[float64]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[float64]int16, xlen) changed = true } if containerLen > 0 { @@ -17218,23 +13782,19 @@ func (_ fastpathT) DecMapFloat64Int16V(v map[float64]int16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]int32) v, changed := fastpathTV.DecMapFloat64Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17255,7 +13815,7 @@ func (f fastpathT) DecMapFloat64Int32X(vp *map[float64]int32, checkNil bool, d * func (_ fastpathT) DecMapFloat64Int32V(v map[float64]int32, checkNil bool, canChange bool, d *Decoder) (_ map[float64]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17265,11 +13825,8 @@ func (_ fastpathT) DecMapFloat64Int32V(v map[float64]int32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]int32, containerLen) - } else { - v = make(map[float64]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float64]int32, xlen) changed = true } if containerLen > 0 { @@ -17283,23 +13840,19 @@ func (_ fastpathT) DecMapFloat64Int32V(v map[float64]int32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]int64) v, changed := fastpathTV.DecMapFloat64Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17320,7 +13873,7 @@ func (f fastpathT) DecMapFloat64Int64X(vp *map[float64]int64, checkNil bool, d * func (_ fastpathT) DecMapFloat64Int64V(v map[float64]int64, checkNil bool, canChange bool, d *Decoder) (_ map[float64]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17330,11 +13883,8 @@ func (_ fastpathT) DecMapFloat64Int64V(v map[float64]int64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]int64, containerLen) - } else { - v = make(map[float64]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[float64]int64, xlen) changed = true } if containerLen > 0 { @@ -17348,23 +13898,19 @@ func (_ fastpathT) DecMapFloat64Int64V(v map[float64]int64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]float32) v, changed := fastpathTV.DecMapFloat64Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17385,7 +13931,7 @@ func (f fastpathT) DecMapFloat64Float32X(vp *map[float64]float32, checkNil bool, func (_ fastpathT) DecMapFloat64Float32V(v map[float64]float32, checkNil bool, canChange bool, d *Decoder) (_ map[float64]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17395,11 +13941,8 @@ func (_ fastpathT) DecMapFloat64Float32V(v map[float64]float32, checkNil bool, c containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]float32, containerLen) - } else { - v = make(map[float64]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float64]float32, xlen) changed = true } if containerLen > 0 { @@ -17413,23 +13956,19 @@ func (_ fastpathT) DecMapFloat64Float32V(v map[float64]float32, checkNil bool, c } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]float64) v, changed := fastpathTV.DecMapFloat64Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17450,7 +13989,7 @@ func (f fastpathT) DecMapFloat64Float64X(vp *map[float64]float64, checkNil bool, func (_ fastpathT) DecMapFloat64Float64V(v map[float64]float64, checkNil bool, canChange bool, d *Decoder) (_ map[float64]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17460,11 +13999,8 @@ func (_ fastpathT) DecMapFloat64Float64V(v map[float64]float64, checkNil bool, c containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]float64, containerLen) - } else { - v = make(map[float64]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[float64]float64, xlen) changed = true } if containerLen > 0 { @@ -17478,23 +14014,19 @@ func (_ fastpathT) DecMapFloat64Float64V(v map[float64]float64, checkNil bool, c } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]bool) v, changed := fastpathTV.DecMapFloat64BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -17515,7 +14047,7 @@ func (f fastpathT) DecMapFloat64BoolX(vp *map[float64]bool, checkNil bool, d *De func (_ fastpathT) DecMapFloat64BoolV(v map[float64]bool, checkNil bool, canChange bool, d *Decoder) (_ map[float64]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17525,11 +14057,8 @@ func (_ fastpathT) DecMapFloat64BoolV(v map[float64]bool, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]bool, containerLen) - } else { - v = make(map[float64]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[float64]bool, xlen) changed = true } if containerLen > 0 { @@ -17543,23 +14072,19 @@ func (_ fastpathT) DecMapFloat64BoolV(v map[float64]bool, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintIntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]interface{}) v, changed := fastpathTV.DecMapUintIntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -17580,7 +14105,7 @@ func (f fastpathT) DecMapUintIntfX(vp *map[uint]interface{}, checkNil bool, d *D func (_ fastpathT) DecMapUintIntfV(v map[uint]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[uint]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17590,11 +14115,8 @@ func (_ fastpathT) DecMapUintIntfV(v map[uint]interface{}, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]interface{}, containerLen) - } else { - v = make(map[uint]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[uint]interface{}, xlen) changed = true } if containerLen > 0 { @@ -17609,11 +14131,7 @@ func (_ fastpathT) DecMapUintIntfV(v map[uint]interface{}, checkNil bool, canCha } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -17621,12 +14139,12 @@ func (_ fastpathT) DecMapUintIntfV(v map[uint]interface{}, checkNil bool, canCha v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintStringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]string) v, changed := fastpathTV.DecMapUintStringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -17647,7 +14165,7 @@ func (f fastpathT) DecMapUintStringX(vp *map[uint]string, checkNil bool, d *Deco func (_ fastpathT) DecMapUintStringV(v map[uint]string, checkNil bool, canChange bool, d *Decoder) (_ map[uint]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17657,11 +14175,8 @@ func (_ fastpathT) DecMapUintStringV(v map[uint]string, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]string, containerLen) - } else { - v = make(map[uint]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[uint]string, xlen) changed = true } if containerLen > 0 { @@ -17675,23 +14190,19 @@ func (_ fastpathT) DecMapUintStringV(v map[uint]string, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintUintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]uint) v, changed := fastpathTV.DecMapUintUintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -17712,7 +14223,7 @@ func (f fastpathT) DecMapUintUintX(vp *map[uint]uint, checkNil bool, d *Decoder) func (_ fastpathT) DecMapUintUintV(v map[uint]uint, checkNil bool, canChange bool, d *Decoder) (_ map[uint]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17722,11 +14233,8 @@ func (_ fastpathT) DecMapUintUintV(v map[uint]uint, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]uint, containerLen) - } else { - v = make(map[uint]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint]uint, xlen) changed = true } if containerLen > 0 { @@ -17740,23 +14248,19 @@ func (_ fastpathT) DecMapUintUintV(v map[uint]uint, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintUint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintUint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]uint8) v, changed := fastpathTV.DecMapUintUint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17777,7 +14281,7 @@ func (f fastpathT) DecMapUintUint8X(vp *map[uint]uint8, checkNil bool, d *Decode func (_ fastpathT) DecMapUintUint8V(v map[uint]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[uint]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17787,11 +14291,8 @@ func (_ fastpathT) DecMapUintUint8V(v map[uint]uint8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]uint8, containerLen) - } else { - v = make(map[uint]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint]uint8, xlen) changed = true } if containerLen > 0 { @@ -17805,23 +14306,19 @@ func (_ fastpathT) DecMapUintUint8V(v map[uint]uint8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintUint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]uint16) v, changed := fastpathTV.DecMapUintUint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17842,7 +14339,7 @@ func (f fastpathT) DecMapUintUint16X(vp *map[uint]uint16, checkNil bool, d *Deco func (_ fastpathT) DecMapUintUint16V(v map[uint]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[uint]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17852,11 +14349,8 @@ func (_ fastpathT) DecMapUintUint16V(v map[uint]uint16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]uint16, containerLen) - } else { - v = make(map[uint]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint]uint16, xlen) changed = true } if containerLen > 0 { @@ -17870,23 +14364,19 @@ func (_ fastpathT) DecMapUintUint16V(v map[uint]uint16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintUint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]uint32) v, changed := fastpathTV.DecMapUintUint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17907,7 +14397,7 @@ func (f fastpathT) DecMapUintUint32X(vp *map[uint]uint32, checkNil bool, d *Deco func (_ fastpathT) DecMapUintUint32V(v map[uint]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[uint]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17917,11 +14407,8 @@ func (_ fastpathT) DecMapUintUint32V(v map[uint]uint32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]uint32, containerLen) - } else { - v = make(map[uint]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint]uint32, xlen) changed = true } if containerLen > 0 { @@ -17935,23 +14422,19 @@ func (_ fastpathT) DecMapUintUint32V(v map[uint]uint32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintUint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]uint64) v, changed := fastpathTV.DecMapUintUint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17972,7 +14455,7 @@ func (f fastpathT) DecMapUintUint64X(vp *map[uint]uint64, checkNil bool, d *Deco func (_ fastpathT) DecMapUintUint64V(v map[uint]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[uint]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17982,11 +14465,8 @@ func (_ fastpathT) DecMapUintUint64V(v map[uint]uint64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]uint64, containerLen) - } else { - v = make(map[uint]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint]uint64, xlen) changed = true } if containerLen > 0 { @@ -18000,23 +14480,19 @@ func (_ fastpathT) DecMapUintUint64V(v map[uint]uint64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintIntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]int) v, changed := fastpathTV.DecMapUintIntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -18037,7 +14513,7 @@ func (f fastpathT) DecMapUintIntX(vp *map[uint]int, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapUintIntV(v map[uint]int, checkNil bool, canChange bool, d *Decoder) (_ map[uint]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18047,11 +14523,8 @@ func (_ fastpathT) DecMapUintIntV(v map[uint]int, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]int, containerLen) - } else { - v = make(map[uint]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint]int, xlen) changed = true } if containerLen > 0 { @@ -18065,23 +14538,19 @@ func (_ fastpathT) DecMapUintIntV(v map[uint]int, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintInt8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]int8) v, changed := fastpathTV.DecMapUintInt8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18102,7 +14571,7 @@ func (f fastpathT) DecMapUintInt8X(vp *map[uint]int8, checkNil bool, d *Decoder) func (_ fastpathT) DecMapUintInt8V(v map[uint]int8, checkNil bool, canChange bool, d *Decoder) (_ map[uint]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18112,11 +14581,8 @@ func (_ fastpathT) DecMapUintInt8V(v map[uint]int8, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]int8, containerLen) - } else { - v = make(map[uint]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint]int8, xlen) changed = true } if containerLen > 0 { @@ -18130,23 +14596,19 @@ func (_ fastpathT) DecMapUintInt8V(v map[uint]int8, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintInt16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]int16) v, changed := fastpathTV.DecMapUintInt16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18167,7 +14629,7 @@ func (f fastpathT) DecMapUintInt16X(vp *map[uint]int16, checkNil bool, d *Decode func (_ fastpathT) DecMapUintInt16V(v map[uint]int16, checkNil bool, canChange bool, d *Decoder) (_ map[uint]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18177,11 +14639,8 @@ func (_ fastpathT) DecMapUintInt16V(v map[uint]int16, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]int16, containerLen) - } else { - v = make(map[uint]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint]int16, xlen) changed = true } if containerLen > 0 { @@ -18195,23 +14654,19 @@ func (_ fastpathT) DecMapUintInt16V(v map[uint]int16, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintInt32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]int32) v, changed := fastpathTV.DecMapUintInt32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18232,7 +14687,7 @@ func (f fastpathT) DecMapUintInt32X(vp *map[uint]int32, checkNil bool, d *Decode func (_ fastpathT) DecMapUintInt32V(v map[uint]int32, checkNil bool, canChange bool, d *Decoder) (_ map[uint]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18242,11 +14697,8 @@ func (_ fastpathT) DecMapUintInt32V(v map[uint]int32, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]int32, containerLen) - } else { - v = make(map[uint]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint]int32, xlen) changed = true } if containerLen > 0 { @@ -18260,23 +14712,19 @@ func (_ fastpathT) DecMapUintInt32V(v map[uint]int32, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintInt64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]int64) v, changed := fastpathTV.DecMapUintInt64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18297,7 +14745,7 @@ func (f fastpathT) DecMapUintInt64X(vp *map[uint]int64, checkNil bool, d *Decode func (_ fastpathT) DecMapUintInt64V(v map[uint]int64, checkNil bool, canChange bool, d *Decoder) (_ map[uint]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18307,11 +14755,8 @@ func (_ fastpathT) DecMapUintInt64V(v map[uint]int64, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]int64, containerLen) - } else { - v = make(map[uint]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint]int64, xlen) changed = true } if containerLen > 0 { @@ -18325,23 +14770,19 @@ func (_ fastpathT) DecMapUintInt64V(v map[uint]int64, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintFloat32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]float32) v, changed := fastpathTV.DecMapUintFloat32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18362,7 +14803,7 @@ func (f fastpathT) DecMapUintFloat32X(vp *map[uint]float32, checkNil bool, d *De func (_ fastpathT) DecMapUintFloat32V(v map[uint]float32, checkNil bool, canChange bool, d *Decoder) (_ map[uint]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18372,11 +14813,8 @@ func (_ fastpathT) DecMapUintFloat32V(v map[uint]float32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]float32, containerLen) - } else { - v = make(map[uint]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint]float32, xlen) changed = true } if containerLen > 0 { @@ -18390,23 +14828,19 @@ func (_ fastpathT) DecMapUintFloat32V(v map[uint]float32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintFloat64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]float64) v, changed := fastpathTV.DecMapUintFloat64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18427,7 +14861,7 @@ func (f fastpathT) DecMapUintFloat64X(vp *map[uint]float64, checkNil bool, d *De func (_ fastpathT) DecMapUintFloat64V(v map[uint]float64, checkNil bool, canChange bool, d *Decoder) (_ map[uint]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18437,11 +14871,8 @@ func (_ fastpathT) DecMapUintFloat64V(v map[uint]float64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]float64, containerLen) - } else { - v = make(map[uint]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint]float64, xlen) changed = true } if containerLen > 0 { @@ -18455,23 +14886,19 @@ func (_ fastpathT) DecMapUintFloat64V(v map[uint]float64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUintBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintBoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]bool) v, changed := fastpathTV.DecMapUintBoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -18492,7 +14919,7 @@ func (f fastpathT) DecMapUintBoolX(vp *map[uint]bool, checkNil bool, d *Decoder) func (_ fastpathT) DecMapUintBoolV(v map[uint]bool, checkNil bool, canChange bool, d *Decoder) (_ map[uint]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18502,11 +14929,8 @@ func (_ fastpathT) DecMapUintBoolV(v map[uint]bool, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]bool, containerLen) - } else { - v = make(map[uint]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint]bool, xlen) changed = true } if containerLen > 0 { @@ -18520,23 +14944,19 @@ func (_ fastpathT) DecMapUintBoolV(v map[uint]bool, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]interface{}) v, changed := fastpathTV.DecMapUint8IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -18557,7 +14977,7 @@ func (f fastpathT) DecMapUint8IntfX(vp *map[uint8]interface{}, checkNil bool, d func (_ fastpathT) DecMapUint8IntfV(v map[uint8]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18567,11 +14987,8 @@ func (_ fastpathT) DecMapUint8IntfV(v map[uint8]interface{}, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]interface{}, containerLen) - } else { - v = make(map[uint8]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[uint8]interface{}, xlen) changed = true } if containerLen > 0 { @@ -18586,11 +15003,7 @@ func (_ fastpathT) DecMapUint8IntfV(v map[uint8]interface{}, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -18598,12 +15011,12 @@ func (_ fastpathT) DecMapUint8IntfV(v map[uint8]interface{}, checkNil bool, canC v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]string) v, changed := fastpathTV.DecMapUint8StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -18624,7 +15037,7 @@ func (f fastpathT) DecMapUint8StringX(vp *map[uint8]string, checkNil bool, d *De func (_ fastpathT) DecMapUint8StringV(v map[uint8]string, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18634,11 +15047,8 @@ func (_ fastpathT) DecMapUint8StringV(v map[uint8]string, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]string, containerLen) - } else { - v = make(map[uint8]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[uint8]string, xlen) changed = true } if containerLen > 0 { @@ -18652,23 +15062,19 @@ func (_ fastpathT) DecMapUint8StringV(v map[uint8]string, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]uint) v, changed := fastpathTV.DecMapUint8UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -18689,7 +15095,7 @@ func (f fastpathT) DecMapUint8UintX(vp *map[uint8]uint, checkNil bool, d *Decode func (_ fastpathT) DecMapUint8UintV(v map[uint8]uint, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18699,11 +15105,8 @@ func (_ fastpathT) DecMapUint8UintV(v map[uint8]uint, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]uint, containerLen) - } else { - v = make(map[uint8]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint8]uint, xlen) changed = true } if containerLen > 0 { @@ -18717,23 +15120,19 @@ func (_ fastpathT) DecMapUint8UintV(v map[uint8]uint, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]uint8) v, changed := fastpathTV.DecMapUint8Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18754,7 +15153,7 @@ func (f fastpathT) DecMapUint8Uint8X(vp *map[uint8]uint8, checkNil bool, d *Deco func (_ fastpathT) DecMapUint8Uint8V(v map[uint8]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18764,11 +15163,8 @@ func (_ fastpathT) DecMapUint8Uint8V(v map[uint8]uint8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]uint8, containerLen) - } else { - v = make(map[uint8]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[uint8]uint8, xlen) changed = true } if containerLen > 0 { @@ -18782,23 +15178,19 @@ func (_ fastpathT) DecMapUint8Uint8V(v map[uint8]uint8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]uint16) v, changed := fastpathTV.DecMapUint8Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18819,7 +15211,7 @@ func (f fastpathT) DecMapUint8Uint16X(vp *map[uint8]uint16, checkNil bool, d *De func (_ fastpathT) DecMapUint8Uint16V(v map[uint8]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18829,11 +15221,8 @@ func (_ fastpathT) DecMapUint8Uint16V(v map[uint8]uint16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]uint16, containerLen) - } else { - v = make(map[uint8]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[uint8]uint16, xlen) changed = true } if containerLen > 0 { @@ -18847,23 +15236,19 @@ func (_ fastpathT) DecMapUint8Uint16V(v map[uint8]uint16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]uint32) v, changed := fastpathTV.DecMapUint8Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18884,7 +15269,7 @@ func (f fastpathT) DecMapUint8Uint32X(vp *map[uint8]uint32, checkNil bool, d *De func (_ fastpathT) DecMapUint8Uint32V(v map[uint8]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18894,11 +15279,8 @@ func (_ fastpathT) DecMapUint8Uint32V(v map[uint8]uint32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]uint32, containerLen) - } else { - v = make(map[uint8]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint8]uint32, xlen) changed = true } if containerLen > 0 { @@ -18912,23 +15294,19 @@ func (_ fastpathT) DecMapUint8Uint32V(v map[uint8]uint32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]uint64) v, changed := fastpathTV.DecMapUint8Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18949,7 +15327,7 @@ func (f fastpathT) DecMapUint8Uint64X(vp *map[uint8]uint64, checkNil bool, d *De func (_ fastpathT) DecMapUint8Uint64V(v map[uint8]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18959,11 +15337,8 @@ func (_ fastpathT) DecMapUint8Uint64V(v map[uint8]uint64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]uint64, containerLen) - } else { - v = make(map[uint8]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint8]uint64, xlen) changed = true } if containerLen > 0 { @@ -18977,23 +15352,19 @@ func (_ fastpathT) DecMapUint8Uint64V(v map[uint8]uint64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]int) v, changed := fastpathTV.DecMapUint8IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19014,7 +15385,7 @@ func (f fastpathT) DecMapUint8IntX(vp *map[uint8]int, checkNil bool, d *Decoder) func (_ fastpathT) DecMapUint8IntV(v map[uint8]int, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19024,11 +15395,8 @@ func (_ fastpathT) DecMapUint8IntV(v map[uint8]int, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]int, containerLen) - } else { - v = make(map[uint8]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint8]int, xlen) changed = true } if containerLen > 0 { @@ -19042,23 +15410,19 @@ func (_ fastpathT) DecMapUint8IntV(v map[uint8]int, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]int8) v, changed := fastpathTV.DecMapUint8Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19079,7 +15443,7 @@ func (f fastpathT) DecMapUint8Int8X(vp *map[uint8]int8, checkNil bool, d *Decode func (_ fastpathT) DecMapUint8Int8V(v map[uint8]int8, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19089,11 +15453,8 @@ func (_ fastpathT) DecMapUint8Int8V(v map[uint8]int8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]int8, containerLen) - } else { - v = make(map[uint8]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[uint8]int8, xlen) changed = true } if containerLen > 0 { @@ -19107,23 +15468,19 @@ func (_ fastpathT) DecMapUint8Int8V(v map[uint8]int8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]int16) v, changed := fastpathTV.DecMapUint8Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19144,7 +15501,7 @@ func (f fastpathT) DecMapUint8Int16X(vp *map[uint8]int16, checkNil bool, d *Deco func (_ fastpathT) DecMapUint8Int16V(v map[uint8]int16, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19154,11 +15511,8 @@ func (_ fastpathT) DecMapUint8Int16V(v map[uint8]int16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]int16, containerLen) - } else { - v = make(map[uint8]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[uint8]int16, xlen) changed = true } if containerLen > 0 { @@ -19172,23 +15526,19 @@ func (_ fastpathT) DecMapUint8Int16V(v map[uint8]int16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]int32) v, changed := fastpathTV.DecMapUint8Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19209,7 +15559,7 @@ func (f fastpathT) DecMapUint8Int32X(vp *map[uint8]int32, checkNil bool, d *Deco func (_ fastpathT) DecMapUint8Int32V(v map[uint8]int32, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19219,11 +15569,8 @@ func (_ fastpathT) DecMapUint8Int32V(v map[uint8]int32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]int32, containerLen) - } else { - v = make(map[uint8]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint8]int32, xlen) changed = true } if containerLen > 0 { @@ -19237,23 +15584,19 @@ func (_ fastpathT) DecMapUint8Int32V(v map[uint8]int32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]int64) v, changed := fastpathTV.DecMapUint8Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19274,7 +15617,7 @@ func (f fastpathT) DecMapUint8Int64X(vp *map[uint8]int64, checkNil bool, d *Deco func (_ fastpathT) DecMapUint8Int64V(v map[uint8]int64, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19284,11 +15627,8 @@ func (_ fastpathT) DecMapUint8Int64V(v map[uint8]int64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]int64, containerLen) - } else { - v = make(map[uint8]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint8]int64, xlen) changed = true } if containerLen > 0 { @@ -19302,23 +15642,19 @@ func (_ fastpathT) DecMapUint8Int64V(v map[uint8]int64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]float32) v, changed := fastpathTV.DecMapUint8Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19339,7 +15675,7 @@ func (f fastpathT) DecMapUint8Float32X(vp *map[uint8]float32, checkNil bool, d * func (_ fastpathT) DecMapUint8Float32V(v map[uint8]float32, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19349,11 +15685,8 @@ func (_ fastpathT) DecMapUint8Float32V(v map[uint8]float32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]float32, containerLen) - } else { - v = make(map[uint8]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint8]float32, xlen) changed = true } if containerLen > 0 { @@ -19367,23 +15700,19 @@ func (_ fastpathT) DecMapUint8Float32V(v map[uint8]float32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]float64) v, changed := fastpathTV.DecMapUint8Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19404,7 +15733,7 @@ func (f fastpathT) DecMapUint8Float64X(vp *map[uint8]float64, checkNil bool, d * func (_ fastpathT) DecMapUint8Float64V(v map[uint8]float64, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19414,11 +15743,8 @@ func (_ fastpathT) DecMapUint8Float64V(v map[uint8]float64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]float64, containerLen) - } else { - v = make(map[uint8]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint8]float64, xlen) changed = true } if containerLen > 0 { @@ -19432,23 +15758,19 @@ func (_ fastpathT) DecMapUint8Float64V(v map[uint8]float64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint8BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]bool) v, changed := fastpathTV.DecMapUint8BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19469,7 +15791,7 @@ func (f fastpathT) DecMapUint8BoolX(vp *map[uint8]bool, checkNil bool, d *Decode func (_ fastpathT) DecMapUint8BoolV(v map[uint8]bool, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19479,11 +15801,8 @@ func (_ fastpathT) DecMapUint8BoolV(v map[uint8]bool, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]bool, containerLen) - } else { - v = make(map[uint8]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[uint8]bool, xlen) changed = true } if containerLen > 0 { @@ -19497,23 +15816,19 @@ func (_ fastpathT) DecMapUint8BoolV(v map[uint8]bool, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]interface{}) v, changed := fastpathTV.DecMapUint16IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19534,7 +15849,7 @@ func (f fastpathT) DecMapUint16IntfX(vp *map[uint16]interface{}, checkNil bool, func (_ fastpathT) DecMapUint16IntfV(v map[uint16]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19544,11 +15859,8 @@ func (_ fastpathT) DecMapUint16IntfV(v map[uint16]interface{}, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]interface{}, containerLen) - } else { - v = make(map[uint16]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[uint16]interface{}, xlen) changed = true } if containerLen > 0 { @@ -19563,11 +15875,7 @@ func (_ fastpathT) DecMapUint16IntfV(v map[uint16]interface{}, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -19575,12 +15883,12 @@ func (_ fastpathT) DecMapUint16IntfV(v map[uint16]interface{}, checkNil bool, ca v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]string) v, changed := fastpathTV.DecMapUint16StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19601,7 +15909,7 @@ func (f fastpathT) DecMapUint16StringX(vp *map[uint16]string, checkNil bool, d * func (_ fastpathT) DecMapUint16StringV(v map[uint16]string, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19611,11 +15919,8 @@ func (_ fastpathT) DecMapUint16StringV(v map[uint16]string, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]string, containerLen) - } else { - v = make(map[uint16]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[uint16]string, xlen) changed = true } if containerLen > 0 { @@ -19629,23 +15934,19 @@ func (_ fastpathT) DecMapUint16StringV(v map[uint16]string, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]uint) v, changed := fastpathTV.DecMapUint16UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19666,7 +15967,7 @@ func (f fastpathT) DecMapUint16UintX(vp *map[uint16]uint, checkNil bool, d *Deco func (_ fastpathT) DecMapUint16UintV(v map[uint16]uint, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19676,11 +15977,8 @@ func (_ fastpathT) DecMapUint16UintV(v map[uint16]uint, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]uint, containerLen) - } else { - v = make(map[uint16]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint16]uint, xlen) changed = true } if containerLen > 0 { @@ -19694,23 +15992,19 @@ func (_ fastpathT) DecMapUint16UintV(v map[uint16]uint, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]uint8) v, changed := fastpathTV.DecMapUint16Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19731,7 +16025,7 @@ func (f fastpathT) DecMapUint16Uint8X(vp *map[uint16]uint8, checkNil bool, d *De func (_ fastpathT) DecMapUint16Uint8V(v map[uint16]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19741,11 +16035,8 @@ func (_ fastpathT) DecMapUint16Uint8V(v map[uint16]uint8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]uint8, containerLen) - } else { - v = make(map[uint16]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[uint16]uint8, xlen) changed = true } if containerLen > 0 { @@ -19759,23 +16050,19 @@ func (_ fastpathT) DecMapUint16Uint8V(v map[uint16]uint8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]uint16) v, changed := fastpathTV.DecMapUint16Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19796,7 +16083,7 @@ func (f fastpathT) DecMapUint16Uint16X(vp *map[uint16]uint16, checkNil bool, d * func (_ fastpathT) DecMapUint16Uint16V(v map[uint16]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19806,11 +16093,8 @@ func (_ fastpathT) DecMapUint16Uint16V(v map[uint16]uint16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]uint16, containerLen) - } else { - v = make(map[uint16]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4) + v = make(map[uint16]uint16, xlen) changed = true } if containerLen > 0 { @@ -19824,23 +16108,19 @@ func (_ fastpathT) DecMapUint16Uint16V(v map[uint16]uint16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]uint32) v, changed := fastpathTV.DecMapUint16Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19861,7 +16141,7 @@ func (f fastpathT) DecMapUint16Uint32X(vp *map[uint16]uint32, checkNil bool, d * func (_ fastpathT) DecMapUint16Uint32V(v map[uint16]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19871,11 +16151,8 @@ func (_ fastpathT) DecMapUint16Uint32V(v map[uint16]uint32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]uint32, containerLen) - } else { - v = make(map[uint16]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[uint16]uint32, xlen) changed = true } if containerLen > 0 { @@ -19889,23 +16166,19 @@ func (_ fastpathT) DecMapUint16Uint32V(v map[uint16]uint32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]uint64) v, changed := fastpathTV.DecMapUint16Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19926,7 +16199,7 @@ func (f fastpathT) DecMapUint16Uint64X(vp *map[uint16]uint64, checkNil bool, d * func (_ fastpathT) DecMapUint16Uint64V(v map[uint16]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19936,11 +16209,8 @@ func (_ fastpathT) DecMapUint16Uint64V(v map[uint16]uint64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]uint64, containerLen) - } else { - v = make(map[uint16]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint16]uint64, xlen) changed = true } if containerLen > 0 { @@ -19954,23 +16224,19 @@ func (_ fastpathT) DecMapUint16Uint64V(v map[uint16]uint64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]int) v, changed := fastpathTV.DecMapUint16IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19991,7 +16257,7 @@ func (f fastpathT) DecMapUint16IntX(vp *map[uint16]int, checkNil bool, d *Decode func (_ fastpathT) DecMapUint16IntV(v map[uint16]int, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20001,11 +16267,8 @@ func (_ fastpathT) DecMapUint16IntV(v map[uint16]int, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]int, containerLen) - } else { - v = make(map[uint16]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint16]int, xlen) changed = true } if containerLen > 0 { @@ -20019,23 +16282,19 @@ func (_ fastpathT) DecMapUint16IntV(v map[uint16]int, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]int8) v, changed := fastpathTV.DecMapUint16Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20056,7 +16315,7 @@ func (f fastpathT) DecMapUint16Int8X(vp *map[uint16]int8, checkNil bool, d *Deco func (_ fastpathT) DecMapUint16Int8V(v map[uint16]int8, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20066,11 +16325,8 @@ func (_ fastpathT) DecMapUint16Int8V(v map[uint16]int8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]int8, containerLen) - } else { - v = make(map[uint16]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[uint16]int8, xlen) changed = true } if containerLen > 0 { @@ -20084,23 +16340,19 @@ func (_ fastpathT) DecMapUint16Int8V(v map[uint16]int8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]int16) v, changed := fastpathTV.DecMapUint16Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20121,7 +16373,7 @@ func (f fastpathT) DecMapUint16Int16X(vp *map[uint16]int16, checkNil bool, d *De func (_ fastpathT) DecMapUint16Int16V(v map[uint16]int16, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20131,11 +16383,8 @@ func (_ fastpathT) DecMapUint16Int16V(v map[uint16]int16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]int16, containerLen) - } else { - v = make(map[uint16]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4) + v = make(map[uint16]int16, xlen) changed = true } if containerLen > 0 { @@ -20149,23 +16398,19 @@ func (_ fastpathT) DecMapUint16Int16V(v map[uint16]int16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]int32) v, changed := fastpathTV.DecMapUint16Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20186,7 +16431,7 @@ func (f fastpathT) DecMapUint16Int32X(vp *map[uint16]int32, checkNil bool, d *De func (_ fastpathT) DecMapUint16Int32V(v map[uint16]int32, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20196,11 +16441,8 @@ func (_ fastpathT) DecMapUint16Int32V(v map[uint16]int32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]int32, containerLen) - } else { - v = make(map[uint16]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[uint16]int32, xlen) changed = true } if containerLen > 0 { @@ -20214,23 +16456,19 @@ func (_ fastpathT) DecMapUint16Int32V(v map[uint16]int32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]int64) v, changed := fastpathTV.DecMapUint16Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20251,7 +16489,7 @@ func (f fastpathT) DecMapUint16Int64X(vp *map[uint16]int64, checkNil bool, d *De func (_ fastpathT) DecMapUint16Int64V(v map[uint16]int64, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20261,11 +16499,8 @@ func (_ fastpathT) DecMapUint16Int64V(v map[uint16]int64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]int64, containerLen) - } else { - v = make(map[uint16]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint16]int64, xlen) changed = true } if containerLen > 0 { @@ -20279,23 +16514,19 @@ func (_ fastpathT) DecMapUint16Int64V(v map[uint16]int64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]float32) v, changed := fastpathTV.DecMapUint16Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20316,7 +16547,7 @@ func (f fastpathT) DecMapUint16Float32X(vp *map[uint16]float32, checkNil bool, d func (_ fastpathT) DecMapUint16Float32V(v map[uint16]float32, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20326,11 +16557,8 @@ func (_ fastpathT) DecMapUint16Float32V(v map[uint16]float32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]float32, containerLen) - } else { - v = make(map[uint16]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[uint16]float32, xlen) changed = true } if containerLen > 0 { @@ -20344,23 +16572,19 @@ func (_ fastpathT) DecMapUint16Float32V(v map[uint16]float32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]float64) v, changed := fastpathTV.DecMapUint16Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20381,7 +16605,7 @@ func (f fastpathT) DecMapUint16Float64X(vp *map[uint16]float64, checkNil bool, d func (_ fastpathT) DecMapUint16Float64V(v map[uint16]float64, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20391,11 +16615,8 @@ func (_ fastpathT) DecMapUint16Float64V(v map[uint16]float64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]float64, containerLen) - } else { - v = make(map[uint16]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint16]float64, xlen) changed = true } if containerLen > 0 { @@ -20409,23 +16630,19 @@ func (_ fastpathT) DecMapUint16Float64V(v map[uint16]float64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint16BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]bool) v, changed := fastpathTV.DecMapUint16BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -20446,7 +16663,7 @@ func (f fastpathT) DecMapUint16BoolX(vp *map[uint16]bool, checkNil bool, d *Deco func (_ fastpathT) DecMapUint16BoolV(v map[uint16]bool, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20456,11 +16673,8 @@ func (_ fastpathT) DecMapUint16BoolV(v map[uint16]bool, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]bool, containerLen) - } else { - v = make(map[uint16]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[uint16]bool, xlen) changed = true } if containerLen > 0 { @@ -20474,23 +16688,19 @@ func (_ fastpathT) DecMapUint16BoolV(v map[uint16]bool, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]interface{}) v, changed := fastpathTV.DecMapUint32IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -20511,7 +16721,7 @@ func (f fastpathT) DecMapUint32IntfX(vp *map[uint32]interface{}, checkNil bool, func (_ fastpathT) DecMapUint32IntfV(v map[uint32]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20521,11 +16731,8 @@ func (_ fastpathT) DecMapUint32IntfV(v map[uint32]interface{}, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]interface{}, containerLen) - } else { - v = make(map[uint32]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[uint32]interface{}, xlen) changed = true } if containerLen > 0 { @@ -20540,11 +16747,7 @@ func (_ fastpathT) DecMapUint32IntfV(v map[uint32]interface{}, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -20552,12 +16755,12 @@ func (_ fastpathT) DecMapUint32IntfV(v map[uint32]interface{}, checkNil bool, ca v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]string) v, changed := fastpathTV.DecMapUint32StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -20578,7 +16781,7 @@ func (f fastpathT) DecMapUint32StringX(vp *map[uint32]string, checkNil bool, d * func (_ fastpathT) DecMapUint32StringV(v map[uint32]string, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20588,11 +16791,8 @@ func (_ fastpathT) DecMapUint32StringV(v map[uint32]string, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]string, containerLen) - } else { - v = make(map[uint32]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[uint32]string, xlen) changed = true } if containerLen > 0 { @@ -20606,23 +16806,19 @@ func (_ fastpathT) DecMapUint32StringV(v map[uint32]string, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]uint) v, changed := fastpathTV.DecMapUint32UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -20643,7 +16839,7 @@ func (f fastpathT) DecMapUint32UintX(vp *map[uint32]uint, checkNil bool, d *Deco func (_ fastpathT) DecMapUint32UintV(v map[uint32]uint, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20653,11 +16849,8 @@ func (_ fastpathT) DecMapUint32UintV(v map[uint32]uint, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]uint, containerLen) - } else { - v = make(map[uint32]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint32]uint, xlen) changed = true } if containerLen > 0 { @@ -20671,23 +16864,19 @@ func (_ fastpathT) DecMapUint32UintV(v map[uint32]uint, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]uint8) v, changed := fastpathTV.DecMapUint32Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20708,7 +16897,7 @@ func (f fastpathT) DecMapUint32Uint8X(vp *map[uint32]uint8, checkNil bool, d *De func (_ fastpathT) DecMapUint32Uint8V(v map[uint32]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20718,11 +16907,8 @@ func (_ fastpathT) DecMapUint32Uint8V(v map[uint32]uint8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]uint8, containerLen) - } else { - v = make(map[uint32]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint32]uint8, xlen) changed = true } if containerLen > 0 { @@ -20736,23 +16922,19 @@ func (_ fastpathT) DecMapUint32Uint8V(v map[uint32]uint8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]uint16) v, changed := fastpathTV.DecMapUint32Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20773,7 +16955,7 @@ func (f fastpathT) DecMapUint32Uint16X(vp *map[uint32]uint16, checkNil bool, d * func (_ fastpathT) DecMapUint32Uint16V(v map[uint32]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20783,11 +16965,8 @@ func (_ fastpathT) DecMapUint32Uint16V(v map[uint32]uint16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]uint16, containerLen) - } else { - v = make(map[uint32]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[uint32]uint16, xlen) changed = true } if containerLen > 0 { @@ -20801,23 +16980,19 @@ func (_ fastpathT) DecMapUint32Uint16V(v map[uint32]uint16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]uint32) v, changed := fastpathTV.DecMapUint32Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20838,7 +17013,7 @@ func (f fastpathT) DecMapUint32Uint32X(vp *map[uint32]uint32, checkNil bool, d * func (_ fastpathT) DecMapUint32Uint32V(v map[uint32]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20848,11 +17023,8 @@ func (_ fastpathT) DecMapUint32Uint32V(v map[uint32]uint32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]uint32, containerLen) - } else { - v = make(map[uint32]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[uint32]uint32, xlen) changed = true } if containerLen > 0 { @@ -20866,23 +17038,19 @@ func (_ fastpathT) DecMapUint32Uint32V(v map[uint32]uint32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]uint64) v, changed := fastpathTV.DecMapUint32Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20903,7 +17071,7 @@ func (f fastpathT) DecMapUint32Uint64X(vp *map[uint32]uint64, checkNil bool, d * func (_ fastpathT) DecMapUint32Uint64V(v map[uint32]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20913,11 +17081,8 @@ func (_ fastpathT) DecMapUint32Uint64V(v map[uint32]uint64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]uint64, containerLen) - } else { - v = make(map[uint32]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint32]uint64, xlen) changed = true } if containerLen > 0 { @@ -20931,23 +17096,19 @@ func (_ fastpathT) DecMapUint32Uint64V(v map[uint32]uint64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]int) v, changed := fastpathTV.DecMapUint32IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -20968,7 +17129,7 @@ func (f fastpathT) DecMapUint32IntX(vp *map[uint32]int, checkNil bool, d *Decode func (_ fastpathT) DecMapUint32IntV(v map[uint32]int, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20978,11 +17139,8 @@ func (_ fastpathT) DecMapUint32IntV(v map[uint32]int, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]int, containerLen) - } else { - v = make(map[uint32]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint32]int, xlen) changed = true } if containerLen > 0 { @@ -20996,23 +17154,19 @@ func (_ fastpathT) DecMapUint32IntV(v map[uint32]int, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]int8) v, changed := fastpathTV.DecMapUint32Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21033,7 +17187,7 @@ func (f fastpathT) DecMapUint32Int8X(vp *map[uint32]int8, checkNil bool, d *Deco func (_ fastpathT) DecMapUint32Int8V(v map[uint32]int8, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21043,11 +17197,8 @@ func (_ fastpathT) DecMapUint32Int8V(v map[uint32]int8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]int8, containerLen) - } else { - v = make(map[uint32]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint32]int8, xlen) changed = true } if containerLen > 0 { @@ -21061,23 +17212,19 @@ func (_ fastpathT) DecMapUint32Int8V(v map[uint32]int8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]int16) v, changed := fastpathTV.DecMapUint32Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21098,7 +17245,7 @@ func (f fastpathT) DecMapUint32Int16X(vp *map[uint32]int16, checkNil bool, d *De func (_ fastpathT) DecMapUint32Int16V(v map[uint32]int16, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21108,11 +17255,8 @@ func (_ fastpathT) DecMapUint32Int16V(v map[uint32]int16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]int16, containerLen) - } else { - v = make(map[uint32]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[uint32]int16, xlen) changed = true } if containerLen > 0 { @@ -21126,23 +17270,19 @@ func (_ fastpathT) DecMapUint32Int16V(v map[uint32]int16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]int32) v, changed := fastpathTV.DecMapUint32Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21163,7 +17303,7 @@ func (f fastpathT) DecMapUint32Int32X(vp *map[uint32]int32, checkNil bool, d *De func (_ fastpathT) DecMapUint32Int32V(v map[uint32]int32, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21173,11 +17313,8 @@ func (_ fastpathT) DecMapUint32Int32V(v map[uint32]int32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]int32, containerLen) - } else { - v = make(map[uint32]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[uint32]int32, xlen) changed = true } if containerLen > 0 { @@ -21191,23 +17328,19 @@ func (_ fastpathT) DecMapUint32Int32V(v map[uint32]int32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]int64) v, changed := fastpathTV.DecMapUint32Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21228,7 +17361,7 @@ func (f fastpathT) DecMapUint32Int64X(vp *map[uint32]int64, checkNil bool, d *De func (_ fastpathT) DecMapUint32Int64V(v map[uint32]int64, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21238,11 +17371,8 @@ func (_ fastpathT) DecMapUint32Int64V(v map[uint32]int64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]int64, containerLen) - } else { - v = make(map[uint32]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint32]int64, xlen) changed = true } if containerLen > 0 { @@ -21256,23 +17386,19 @@ func (_ fastpathT) DecMapUint32Int64V(v map[uint32]int64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]float32) v, changed := fastpathTV.DecMapUint32Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21293,7 +17419,7 @@ func (f fastpathT) DecMapUint32Float32X(vp *map[uint32]float32, checkNil bool, d func (_ fastpathT) DecMapUint32Float32V(v map[uint32]float32, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21303,11 +17429,8 @@ func (_ fastpathT) DecMapUint32Float32V(v map[uint32]float32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]float32, containerLen) - } else { - v = make(map[uint32]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[uint32]float32, xlen) changed = true } if containerLen > 0 { @@ -21321,23 +17444,19 @@ func (_ fastpathT) DecMapUint32Float32V(v map[uint32]float32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]float64) v, changed := fastpathTV.DecMapUint32Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21358,7 +17477,7 @@ func (f fastpathT) DecMapUint32Float64X(vp *map[uint32]float64, checkNil bool, d func (_ fastpathT) DecMapUint32Float64V(v map[uint32]float64, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21368,11 +17487,8 @@ func (_ fastpathT) DecMapUint32Float64V(v map[uint32]float64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]float64, containerLen) - } else { - v = make(map[uint32]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint32]float64, xlen) changed = true } if containerLen > 0 { @@ -21386,23 +17502,19 @@ func (_ fastpathT) DecMapUint32Float64V(v map[uint32]float64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint32BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]bool) v, changed := fastpathTV.DecMapUint32BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -21423,7 +17535,7 @@ func (f fastpathT) DecMapUint32BoolX(vp *map[uint32]bool, checkNil bool, d *Deco func (_ fastpathT) DecMapUint32BoolV(v map[uint32]bool, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21433,11 +17545,8 @@ func (_ fastpathT) DecMapUint32BoolV(v map[uint32]bool, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]bool, containerLen) - } else { - v = make(map[uint32]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint32]bool, xlen) changed = true } if containerLen > 0 { @@ -21451,23 +17560,19 @@ func (_ fastpathT) DecMapUint32BoolV(v map[uint32]bool, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]interface{}) v, changed := fastpathTV.DecMapUint64IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -21488,7 +17593,7 @@ func (f fastpathT) DecMapUint64IntfX(vp *map[uint64]interface{}, checkNil bool, func (_ fastpathT) DecMapUint64IntfV(v map[uint64]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21498,11 +17603,8 @@ func (_ fastpathT) DecMapUint64IntfV(v map[uint64]interface{}, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]interface{}, containerLen) - } else { - v = make(map[uint64]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[uint64]interface{}, xlen) changed = true } if containerLen > 0 { @@ -21517,11 +17619,7 @@ func (_ fastpathT) DecMapUint64IntfV(v map[uint64]interface{}, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -21529,12 +17627,12 @@ func (_ fastpathT) DecMapUint64IntfV(v map[uint64]interface{}, checkNil bool, ca v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]string) v, changed := fastpathTV.DecMapUint64StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -21555,7 +17653,7 @@ func (f fastpathT) DecMapUint64StringX(vp *map[uint64]string, checkNil bool, d * func (_ fastpathT) DecMapUint64StringV(v map[uint64]string, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21565,11 +17663,8 @@ func (_ fastpathT) DecMapUint64StringV(v map[uint64]string, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]string, containerLen) - } else { - v = make(map[uint64]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[uint64]string, xlen) changed = true } if containerLen > 0 { @@ -21583,23 +17678,19 @@ func (_ fastpathT) DecMapUint64StringV(v map[uint64]string, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]uint) v, changed := fastpathTV.DecMapUint64UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -21620,7 +17711,7 @@ func (f fastpathT) DecMapUint64UintX(vp *map[uint64]uint, checkNil bool, d *Deco func (_ fastpathT) DecMapUint64UintV(v map[uint64]uint, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21630,11 +17721,8 @@ func (_ fastpathT) DecMapUint64UintV(v map[uint64]uint, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]uint, containerLen) - } else { - v = make(map[uint64]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint64]uint, xlen) changed = true } if containerLen > 0 { @@ -21648,23 +17736,19 @@ func (_ fastpathT) DecMapUint64UintV(v map[uint64]uint, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]uint8) v, changed := fastpathTV.DecMapUint64Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21685,7 +17769,7 @@ func (f fastpathT) DecMapUint64Uint8X(vp *map[uint64]uint8, checkNil bool, d *De func (_ fastpathT) DecMapUint64Uint8V(v map[uint64]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21695,11 +17779,8 @@ func (_ fastpathT) DecMapUint64Uint8V(v map[uint64]uint8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]uint8, containerLen) - } else { - v = make(map[uint64]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint64]uint8, xlen) changed = true } if containerLen > 0 { @@ -21713,23 +17794,19 @@ func (_ fastpathT) DecMapUint64Uint8V(v map[uint64]uint8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]uint16) v, changed := fastpathTV.DecMapUint64Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21750,7 +17827,7 @@ func (f fastpathT) DecMapUint64Uint16X(vp *map[uint64]uint16, checkNil bool, d * func (_ fastpathT) DecMapUint64Uint16V(v map[uint64]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21760,11 +17837,8 @@ func (_ fastpathT) DecMapUint64Uint16V(v map[uint64]uint16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]uint16, containerLen) - } else { - v = make(map[uint64]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint64]uint16, xlen) changed = true } if containerLen > 0 { @@ -21778,23 +17852,19 @@ func (_ fastpathT) DecMapUint64Uint16V(v map[uint64]uint16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]uint32) v, changed := fastpathTV.DecMapUint64Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21815,7 +17885,7 @@ func (f fastpathT) DecMapUint64Uint32X(vp *map[uint64]uint32, checkNil bool, d * func (_ fastpathT) DecMapUint64Uint32V(v map[uint64]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21825,11 +17895,8 @@ func (_ fastpathT) DecMapUint64Uint32V(v map[uint64]uint32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]uint32, containerLen) - } else { - v = make(map[uint64]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint64]uint32, xlen) changed = true } if containerLen > 0 { @@ -21843,23 +17910,19 @@ func (_ fastpathT) DecMapUint64Uint32V(v map[uint64]uint32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]uint64) v, changed := fastpathTV.DecMapUint64Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21880,7 +17943,7 @@ func (f fastpathT) DecMapUint64Uint64X(vp *map[uint64]uint64, checkNil bool, d * func (_ fastpathT) DecMapUint64Uint64V(v map[uint64]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21890,11 +17953,8 @@ func (_ fastpathT) DecMapUint64Uint64V(v map[uint64]uint64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]uint64, containerLen) - } else { - v = make(map[uint64]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint64]uint64, xlen) changed = true } if containerLen > 0 { @@ -21908,23 +17968,19 @@ func (_ fastpathT) DecMapUint64Uint64V(v map[uint64]uint64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]int) v, changed := fastpathTV.DecMapUint64IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -21945,7 +18001,7 @@ func (f fastpathT) DecMapUint64IntX(vp *map[uint64]int, checkNil bool, d *Decode func (_ fastpathT) DecMapUint64IntV(v map[uint64]int, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21955,11 +18011,8 @@ func (_ fastpathT) DecMapUint64IntV(v map[uint64]int, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]int, containerLen) - } else { - v = make(map[uint64]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint64]int, xlen) changed = true } if containerLen > 0 { @@ -21973,23 +18026,19 @@ func (_ fastpathT) DecMapUint64IntV(v map[uint64]int, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]int8) v, changed := fastpathTV.DecMapUint64Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22010,7 +18059,7 @@ func (f fastpathT) DecMapUint64Int8X(vp *map[uint64]int8, checkNil bool, d *Deco func (_ fastpathT) DecMapUint64Int8V(v map[uint64]int8, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22020,11 +18069,8 @@ func (_ fastpathT) DecMapUint64Int8V(v map[uint64]int8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]int8, containerLen) - } else { - v = make(map[uint64]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint64]int8, xlen) changed = true } if containerLen > 0 { @@ -22038,23 +18084,19 @@ func (_ fastpathT) DecMapUint64Int8V(v map[uint64]int8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]int16) v, changed := fastpathTV.DecMapUint64Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22075,7 +18117,7 @@ func (f fastpathT) DecMapUint64Int16X(vp *map[uint64]int16, checkNil bool, d *De func (_ fastpathT) DecMapUint64Int16V(v map[uint64]int16, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22085,11 +18127,8 @@ func (_ fastpathT) DecMapUint64Int16V(v map[uint64]int16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]int16, containerLen) - } else { - v = make(map[uint64]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint64]int16, xlen) changed = true } if containerLen > 0 { @@ -22103,23 +18142,19 @@ func (_ fastpathT) DecMapUint64Int16V(v map[uint64]int16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]int32) v, changed := fastpathTV.DecMapUint64Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22140,7 +18175,7 @@ func (f fastpathT) DecMapUint64Int32X(vp *map[uint64]int32, checkNil bool, d *De func (_ fastpathT) DecMapUint64Int32V(v map[uint64]int32, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22150,11 +18185,8 @@ func (_ fastpathT) DecMapUint64Int32V(v map[uint64]int32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]int32, containerLen) - } else { - v = make(map[uint64]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint64]int32, xlen) changed = true } if containerLen > 0 { @@ -22168,23 +18200,19 @@ func (_ fastpathT) DecMapUint64Int32V(v map[uint64]int32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]int64) v, changed := fastpathTV.DecMapUint64Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22205,7 +18233,7 @@ func (f fastpathT) DecMapUint64Int64X(vp *map[uint64]int64, checkNil bool, d *De func (_ fastpathT) DecMapUint64Int64V(v map[uint64]int64, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22215,11 +18243,8 @@ func (_ fastpathT) DecMapUint64Int64V(v map[uint64]int64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]int64, containerLen) - } else { - v = make(map[uint64]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint64]int64, xlen) changed = true } if containerLen > 0 { @@ -22233,23 +18258,19 @@ func (_ fastpathT) DecMapUint64Int64V(v map[uint64]int64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]float32) v, changed := fastpathTV.DecMapUint64Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22270,7 +18291,7 @@ func (f fastpathT) DecMapUint64Float32X(vp *map[uint64]float32, checkNil bool, d func (_ fastpathT) DecMapUint64Float32V(v map[uint64]float32, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22280,11 +18301,8 @@ func (_ fastpathT) DecMapUint64Float32V(v map[uint64]float32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]float32, containerLen) - } else { - v = make(map[uint64]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint64]float32, xlen) changed = true } if containerLen > 0 { @@ -22298,23 +18316,19 @@ func (_ fastpathT) DecMapUint64Float32V(v map[uint64]float32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]float64) v, changed := fastpathTV.DecMapUint64Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22335,7 +18349,7 @@ func (f fastpathT) DecMapUint64Float64X(vp *map[uint64]float64, checkNil bool, d func (_ fastpathT) DecMapUint64Float64V(v map[uint64]float64, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22345,11 +18359,8 @@ func (_ fastpathT) DecMapUint64Float64V(v map[uint64]float64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]float64, containerLen) - } else { - v = make(map[uint64]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint64]float64, xlen) changed = true } if containerLen > 0 { @@ -22363,23 +18374,19 @@ func (_ fastpathT) DecMapUint64Float64V(v map[uint64]float64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapUint64BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]bool) v, changed := fastpathTV.DecMapUint64BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -22400,7 +18407,7 @@ func (f fastpathT) DecMapUint64BoolX(vp *map[uint64]bool, checkNil bool, d *Deco func (_ fastpathT) DecMapUint64BoolV(v map[uint64]bool, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22410,11 +18417,8 @@ func (_ fastpathT) DecMapUint64BoolV(v map[uint64]bool, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]bool, containerLen) - } else { - v = make(map[uint64]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint64]bool, xlen) changed = true } if containerLen > 0 { @@ -22428,23 +18432,19 @@ func (_ fastpathT) DecMapUint64BoolV(v map[uint64]bool, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntIntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]interface{}) v, changed := fastpathTV.DecMapIntIntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -22465,7 +18465,7 @@ func (f fastpathT) DecMapIntIntfX(vp *map[int]interface{}, checkNil bool, d *Dec func (_ fastpathT) DecMapIntIntfV(v map[int]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[int]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22475,11 +18475,8 @@ func (_ fastpathT) DecMapIntIntfV(v map[int]interface{}, checkNil bool, canChang containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]interface{}, containerLen) - } else { - v = make(map[int]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[int]interface{}, xlen) changed = true } if containerLen > 0 { @@ -22494,11 +18491,7 @@ func (_ fastpathT) DecMapIntIntfV(v map[int]interface{}, checkNil bool, canChang } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -22506,12 +18499,12 @@ func (_ fastpathT) DecMapIntIntfV(v map[int]interface{}, checkNil bool, canChang v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntStringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]string) v, changed := fastpathTV.DecMapIntStringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -22532,7 +18525,7 @@ func (f fastpathT) DecMapIntStringX(vp *map[int]string, checkNil bool, d *Decode func (_ fastpathT) DecMapIntStringV(v map[int]string, checkNil bool, canChange bool, d *Decoder) (_ map[int]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22542,11 +18535,8 @@ func (_ fastpathT) DecMapIntStringV(v map[int]string, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]string, containerLen) - } else { - v = make(map[int]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[int]string, xlen) changed = true } if containerLen > 0 { @@ -22560,23 +18550,19 @@ func (_ fastpathT) DecMapIntStringV(v map[int]string, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntUintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]uint) v, changed := fastpathTV.DecMapIntUintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -22597,7 +18583,7 @@ func (f fastpathT) DecMapIntUintX(vp *map[int]uint, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapIntUintV(v map[int]uint, checkNil bool, canChange bool, d *Decoder) (_ map[int]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22607,11 +18593,8 @@ func (_ fastpathT) DecMapIntUintV(v map[int]uint, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]uint, containerLen) - } else { - v = make(map[int]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int]uint, xlen) changed = true } if containerLen > 0 { @@ -22625,23 +18608,19 @@ func (_ fastpathT) DecMapIntUintV(v map[int]uint, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntUint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntUint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]uint8) v, changed := fastpathTV.DecMapIntUint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22662,7 +18641,7 @@ func (f fastpathT) DecMapIntUint8X(vp *map[int]uint8, checkNil bool, d *Decoder) func (_ fastpathT) DecMapIntUint8V(v map[int]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[int]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22672,11 +18651,8 @@ func (_ fastpathT) DecMapIntUint8V(v map[int]uint8, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]uint8, containerLen) - } else { - v = make(map[int]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int]uint8, xlen) changed = true } if containerLen > 0 { @@ -22690,23 +18666,19 @@ func (_ fastpathT) DecMapIntUint8V(v map[int]uint8, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntUint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]uint16) v, changed := fastpathTV.DecMapIntUint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22727,7 +18699,7 @@ func (f fastpathT) DecMapIntUint16X(vp *map[int]uint16, checkNil bool, d *Decode func (_ fastpathT) DecMapIntUint16V(v map[int]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[int]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22737,11 +18709,8 @@ func (_ fastpathT) DecMapIntUint16V(v map[int]uint16, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]uint16, containerLen) - } else { - v = make(map[int]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int]uint16, xlen) changed = true } if containerLen > 0 { @@ -22755,23 +18724,19 @@ func (_ fastpathT) DecMapIntUint16V(v map[int]uint16, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntUint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]uint32) v, changed := fastpathTV.DecMapIntUint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22792,7 +18757,7 @@ func (f fastpathT) DecMapIntUint32X(vp *map[int]uint32, checkNil bool, d *Decode func (_ fastpathT) DecMapIntUint32V(v map[int]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[int]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22802,11 +18767,8 @@ func (_ fastpathT) DecMapIntUint32V(v map[int]uint32, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]uint32, containerLen) - } else { - v = make(map[int]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int]uint32, xlen) changed = true } if containerLen > 0 { @@ -22820,23 +18782,19 @@ func (_ fastpathT) DecMapIntUint32V(v map[int]uint32, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntUint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]uint64) v, changed := fastpathTV.DecMapIntUint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22857,7 +18815,7 @@ func (f fastpathT) DecMapIntUint64X(vp *map[int]uint64, checkNil bool, d *Decode func (_ fastpathT) DecMapIntUint64V(v map[int]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[int]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22867,11 +18825,8 @@ func (_ fastpathT) DecMapIntUint64V(v map[int]uint64, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]uint64, containerLen) - } else { - v = make(map[int]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int]uint64, xlen) changed = true } if containerLen > 0 { @@ -22885,23 +18840,19 @@ func (_ fastpathT) DecMapIntUint64V(v map[int]uint64, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntIntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]int) v, changed := fastpathTV.DecMapIntIntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -22922,7 +18873,7 @@ func (f fastpathT) DecMapIntIntX(vp *map[int]int, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapIntIntV(v map[int]int, checkNil bool, canChange bool, d *Decoder) (_ map[int]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22932,11 +18883,8 @@ func (_ fastpathT) DecMapIntIntV(v map[int]int, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]int, containerLen) - } else { - v = make(map[int]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int]int, xlen) changed = true } if containerLen > 0 { @@ -22950,23 +18898,19 @@ func (_ fastpathT) DecMapIntIntV(v map[int]int, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntInt8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]int8) v, changed := fastpathTV.DecMapIntInt8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22987,7 +18931,7 @@ func (f fastpathT) DecMapIntInt8X(vp *map[int]int8, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapIntInt8V(v map[int]int8, checkNil bool, canChange bool, d *Decoder) (_ map[int]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22997,11 +18941,8 @@ func (_ fastpathT) DecMapIntInt8V(v map[int]int8, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]int8, containerLen) - } else { - v = make(map[int]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int]int8, xlen) changed = true } if containerLen > 0 { @@ -23015,23 +18956,19 @@ func (_ fastpathT) DecMapIntInt8V(v map[int]int8, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntInt16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]int16) v, changed := fastpathTV.DecMapIntInt16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23052,7 +18989,7 @@ func (f fastpathT) DecMapIntInt16X(vp *map[int]int16, checkNil bool, d *Decoder) func (_ fastpathT) DecMapIntInt16V(v map[int]int16, checkNil bool, canChange bool, d *Decoder) (_ map[int]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23062,11 +18999,8 @@ func (_ fastpathT) DecMapIntInt16V(v map[int]int16, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]int16, containerLen) - } else { - v = make(map[int]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int]int16, xlen) changed = true } if containerLen > 0 { @@ -23080,23 +19014,19 @@ func (_ fastpathT) DecMapIntInt16V(v map[int]int16, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntInt32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]int32) v, changed := fastpathTV.DecMapIntInt32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23117,7 +19047,7 @@ func (f fastpathT) DecMapIntInt32X(vp *map[int]int32, checkNil bool, d *Decoder) func (_ fastpathT) DecMapIntInt32V(v map[int]int32, checkNil bool, canChange bool, d *Decoder) (_ map[int]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23127,11 +19057,8 @@ func (_ fastpathT) DecMapIntInt32V(v map[int]int32, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]int32, containerLen) - } else { - v = make(map[int]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int]int32, xlen) changed = true } if containerLen > 0 { @@ -23145,23 +19072,19 @@ func (_ fastpathT) DecMapIntInt32V(v map[int]int32, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntInt64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]int64) v, changed := fastpathTV.DecMapIntInt64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23182,7 +19105,7 @@ func (f fastpathT) DecMapIntInt64X(vp *map[int]int64, checkNil bool, d *Decoder) func (_ fastpathT) DecMapIntInt64V(v map[int]int64, checkNil bool, canChange bool, d *Decoder) (_ map[int]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23192,11 +19115,8 @@ func (_ fastpathT) DecMapIntInt64V(v map[int]int64, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]int64, containerLen) - } else { - v = make(map[int]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int]int64, xlen) changed = true } if containerLen > 0 { @@ -23210,23 +19130,19 @@ func (_ fastpathT) DecMapIntInt64V(v map[int]int64, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntFloat32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]float32) v, changed := fastpathTV.DecMapIntFloat32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23247,7 +19163,7 @@ func (f fastpathT) DecMapIntFloat32X(vp *map[int]float32, checkNil bool, d *Deco func (_ fastpathT) DecMapIntFloat32V(v map[int]float32, checkNil bool, canChange bool, d *Decoder) (_ map[int]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23257,11 +19173,8 @@ func (_ fastpathT) DecMapIntFloat32V(v map[int]float32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]float32, containerLen) - } else { - v = make(map[int]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int]float32, xlen) changed = true } if containerLen > 0 { @@ -23275,23 +19188,19 @@ func (_ fastpathT) DecMapIntFloat32V(v map[int]float32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntFloat64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]float64) v, changed := fastpathTV.DecMapIntFloat64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23312,7 +19221,7 @@ func (f fastpathT) DecMapIntFloat64X(vp *map[int]float64, checkNil bool, d *Deco func (_ fastpathT) DecMapIntFloat64V(v map[int]float64, checkNil bool, canChange bool, d *Decoder) (_ map[int]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23322,11 +19231,8 @@ func (_ fastpathT) DecMapIntFloat64V(v map[int]float64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]float64, containerLen) - } else { - v = make(map[int]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int]float64, xlen) changed = true } if containerLen > 0 { @@ -23340,23 +19246,19 @@ func (_ fastpathT) DecMapIntFloat64V(v map[int]float64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapIntBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntBoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]bool) v, changed := fastpathTV.DecMapIntBoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -23377,7 +19279,7 @@ func (f fastpathT) DecMapIntBoolX(vp *map[int]bool, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapIntBoolV(v map[int]bool, checkNil bool, canChange bool, d *Decoder) (_ map[int]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23387,11 +19289,8 @@ func (_ fastpathT) DecMapIntBoolV(v map[int]bool, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]bool, containerLen) - } else { - v = make(map[int]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int]bool, xlen) changed = true } if containerLen > 0 { @@ -23405,23 +19304,19 @@ func (_ fastpathT) DecMapIntBoolV(v map[int]bool, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]interface{}) v, changed := fastpathTV.DecMapInt8IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -23442,7 +19337,7 @@ func (f fastpathT) DecMapInt8IntfX(vp *map[int8]interface{}, checkNil bool, d *D func (_ fastpathT) DecMapInt8IntfV(v map[int8]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[int8]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23452,11 +19347,8 @@ func (_ fastpathT) DecMapInt8IntfV(v map[int8]interface{}, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]interface{}, containerLen) - } else { - v = make(map[int8]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[int8]interface{}, xlen) changed = true } if containerLen > 0 { @@ -23471,11 +19363,7 @@ func (_ fastpathT) DecMapInt8IntfV(v map[int8]interface{}, checkNil bool, canCha } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -23483,12 +19371,12 @@ func (_ fastpathT) DecMapInt8IntfV(v map[int8]interface{}, checkNil bool, canCha v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]string) v, changed := fastpathTV.DecMapInt8StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -23509,7 +19397,7 @@ func (f fastpathT) DecMapInt8StringX(vp *map[int8]string, checkNil bool, d *Deco func (_ fastpathT) DecMapInt8StringV(v map[int8]string, checkNil bool, canChange bool, d *Decoder) (_ map[int8]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23519,11 +19407,8 @@ func (_ fastpathT) DecMapInt8StringV(v map[int8]string, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]string, containerLen) - } else { - v = make(map[int8]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[int8]string, xlen) changed = true } if containerLen > 0 { @@ -23537,23 +19422,19 @@ func (_ fastpathT) DecMapInt8StringV(v map[int8]string, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]uint) v, changed := fastpathTV.DecMapInt8UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -23574,7 +19455,7 @@ func (f fastpathT) DecMapInt8UintX(vp *map[int8]uint, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt8UintV(v map[int8]uint, checkNil bool, canChange bool, d *Decoder) (_ map[int8]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23584,11 +19465,8 @@ func (_ fastpathT) DecMapInt8UintV(v map[int8]uint, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]uint, containerLen) - } else { - v = make(map[int8]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int8]uint, xlen) changed = true } if containerLen > 0 { @@ -23602,23 +19480,19 @@ func (_ fastpathT) DecMapInt8UintV(v map[int8]uint, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]uint8) v, changed := fastpathTV.DecMapInt8Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23639,7 +19513,7 @@ func (f fastpathT) DecMapInt8Uint8X(vp *map[int8]uint8, checkNil bool, d *Decode func (_ fastpathT) DecMapInt8Uint8V(v map[int8]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[int8]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23649,11 +19523,8 @@ func (_ fastpathT) DecMapInt8Uint8V(v map[int8]uint8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]uint8, containerLen) - } else { - v = make(map[int8]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[int8]uint8, xlen) changed = true } if containerLen > 0 { @@ -23667,23 +19538,19 @@ func (_ fastpathT) DecMapInt8Uint8V(v map[int8]uint8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]uint16) v, changed := fastpathTV.DecMapInt8Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23704,7 +19571,7 @@ func (f fastpathT) DecMapInt8Uint16X(vp *map[int8]uint16, checkNil bool, d *Deco func (_ fastpathT) DecMapInt8Uint16V(v map[int8]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[int8]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23714,11 +19581,8 @@ func (_ fastpathT) DecMapInt8Uint16V(v map[int8]uint16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]uint16, containerLen) - } else { - v = make(map[int8]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[int8]uint16, xlen) changed = true } if containerLen > 0 { @@ -23732,23 +19596,19 @@ func (_ fastpathT) DecMapInt8Uint16V(v map[int8]uint16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]uint32) v, changed := fastpathTV.DecMapInt8Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23769,7 +19629,7 @@ func (f fastpathT) DecMapInt8Uint32X(vp *map[int8]uint32, checkNil bool, d *Deco func (_ fastpathT) DecMapInt8Uint32V(v map[int8]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[int8]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23779,11 +19639,8 @@ func (_ fastpathT) DecMapInt8Uint32V(v map[int8]uint32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]uint32, containerLen) - } else { - v = make(map[int8]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int8]uint32, xlen) changed = true } if containerLen > 0 { @@ -23797,23 +19654,19 @@ func (_ fastpathT) DecMapInt8Uint32V(v map[int8]uint32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]uint64) v, changed := fastpathTV.DecMapInt8Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23834,7 +19687,7 @@ func (f fastpathT) DecMapInt8Uint64X(vp *map[int8]uint64, checkNil bool, d *Deco func (_ fastpathT) DecMapInt8Uint64V(v map[int8]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[int8]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23844,11 +19697,8 @@ func (_ fastpathT) DecMapInt8Uint64V(v map[int8]uint64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]uint64, containerLen) - } else { - v = make(map[int8]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int8]uint64, xlen) changed = true } if containerLen > 0 { @@ -23862,23 +19712,19 @@ func (_ fastpathT) DecMapInt8Uint64V(v map[int8]uint64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]int) v, changed := fastpathTV.DecMapInt8IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -23899,7 +19745,7 @@ func (f fastpathT) DecMapInt8IntX(vp *map[int8]int, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapInt8IntV(v map[int8]int, checkNil bool, canChange bool, d *Decoder) (_ map[int8]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23909,11 +19755,8 @@ func (_ fastpathT) DecMapInt8IntV(v map[int8]int, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]int, containerLen) - } else { - v = make(map[int8]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int8]int, xlen) changed = true } if containerLen > 0 { @@ -23927,23 +19770,19 @@ func (_ fastpathT) DecMapInt8IntV(v map[int8]int, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]int8) v, changed := fastpathTV.DecMapInt8Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23964,7 +19803,7 @@ func (f fastpathT) DecMapInt8Int8X(vp *map[int8]int8, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt8Int8V(v map[int8]int8, checkNil bool, canChange bool, d *Decoder) (_ map[int8]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23974,11 +19813,8 @@ func (_ fastpathT) DecMapInt8Int8V(v map[int8]int8, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]int8, containerLen) - } else { - v = make(map[int8]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[int8]int8, xlen) changed = true } if containerLen > 0 { @@ -23992,23 +19828,19 @@ func (_ fastpathT) DecMapInt8Int8V(v map[int8]int8, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]int16) v, changed := fastpathTV.DecMapInt8Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24029,7 +19861,7 @@ func (f fastpathT) DecMapInt8Int16X(vp *map[int8]int16, checkNil bool, d *Decode func (_ fastpathT) DecMapInt8Int16V(v map[int8]int16, checkNil bool, canChange bool, d *Decoder) (_ map[int8]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24039,11 +19871,8 @@ func (_ fastpathT) DecMapInt8Int16V(v map[int8]int16, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]int16, containerLen) - } else { - v = make(map[int8]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[int8]int16, xlen) changed = true } if containerLen > 0 { @@ -24057,23 +19886,19 @@ func (_ fastpathT) DecMapInt8Int16V(v map[int8]int16, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]int32) v, changed := fastpathTV.DecMapInt8Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24094,7 +19919,7 @@ func (f fastpathT) DecMapInt8Int32X(vp *map[int8]int32, checkNil bool, d *Decode func (_ fastpathT) DecMapInt8Int32V(v map[int8]int32, checkNil bool, canChange bool, d *Decoder) (_ map[int8]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24104,11 +19929,8 @@ func (_ fastpathT) DecMapInt8Int32V(v map[int8]int32, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]int32, containerLen) - } else { - v = make(map[int8]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int8]int32, xlen) changed = true } if containerLen > 0 { @@ -24122,23 +19944,19 @@ func (_ fastpathT) DecMapInt8Int32V(v map[int8]int32, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]int64) v, changed := fastpathTV.DecMapInt8Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24159,7 +19977,7 @@ func (f fastpathT) DecMapInt8Int64X(vp *map[int8]int64, checkNil bool, d *Decode func (_ fastpathT) DecMapInt8Int64V(v map[int8]int64, checkNil bool, canChange bool, d *Decoder) (_ map[int8]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24169,11 +19987,8 @@ func (_ fastpathT) DecMapInt8Int64V(v map[int8]int64, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]int64, containerLen) - } else { - v = make(map[int8]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int8]int64, xlen) changed = true } if containerLen > 0 { @@ -24187,23 +20002,19 @@ func (_ fastpathT) DecMapInt8Int64V(v map[int8]int64, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]float32) v, changed := fastpathTV.DecMapInt8Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24224,7 +20035,7 @@ func (f fastpathT) DecMapInt8Float32X(vp *map[int8]float32, checkNil bool, d *De func (_ fastpathT) DecMapInt8Float32V(v map[int8]float32, checkNil bool, canChange bool, d *Decoder) (_ map[int8]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24234,11 +20045,8 @@ func (_ fastpathT) DecMapInt8Float32V(v map[int8]float32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]float32, containerLen) - } else { - v = make(map[int8]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int8]float32, xlen) changed = true } if containerLen > 0 { @@ -24252,23 +20060,19 @@ func (_ fastpathT) DecMapInt8Float32V(v map[int8]float32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]float64) v, changed := fastpathTV.DecMapInt8Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24289,7 +20093,7 @@ func (f fastpathT) DecMapInt8Float64X(vp *map[int8]float64, checkNil bool, d *De func (_ fastpathT) DecMapInt8Float64V(v map[int8]float64, checkNil bool, canChange bool, d *Decoder) (_ map[int8]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24299,11 +20103,8 @@ func (_ fastpathT) DecMapInt8Float64V(v map[int8]float64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]float64, containerLen) - } else { - v = make(map[int8]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int8]float64, xlen) changed = true } if containerLen > 0 { @@ -24317,23 +20118,19 @@ func (_ fastpathT) DecMapInt8Float64V(v map[int8]float64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt8BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]bool) v, changed := fastpathTV.DecMapInt8BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -24354,7 +20151,7 @@ func (f fastpathT) DecMapInt8BoolX(vp *map[int8]bool, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt8BoolV(v map[int8]bool, checkNil bool, canChange bool, d *Decoder) (_ map[int8]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24364,11 +20161,8 @@ func (_ fastpathT) DecMapInt8BoolV(v map[int8]bool, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]bool, containerLen) - } else { - v = make(map[int8]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[int8]bool, xlen) changed = true } if containerLen > 0 { @@ -24382,23 +20176,19 @@ func (_ fastpathT) DecMapInt8BoolV(v map[int8]bool, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]interface{}) v, changed := fastpathTV.DecMapInt16IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -24419,7 +20209,7 @@ func (f fastpathT) DecMapInt16IntfX(vp *map[int16]interface{}, checkNil bool, d func (_ fastpathT) DecMapInt16IntfV(v map[int16]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[int16]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24429,11 +20219,8 @@ func (_ fastpathT) DecMapInt16IntfV(v map[int16]interface{}, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]interface{}, containerLen) - } else { - v = make(map[int16]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[int16]interface{}, xlen) changed = true } if containerLen > 0 { @@ -24448,11 +20235,7 @@ func (_ fastpathT) DecMapInt16IntfV(v map[int16]interface{}, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -24460,12 +20243,12 @@ func (_ fastpathT) DecMapInt16IntfV(v map[int16]interface{}, checkNil bool, canC v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]string) v, changed := fastpathTV.DecMapInt16StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -24486,7 +20269,7 @@ func (f fastpathT) DecMapInt16StringX(vp *map[int16]string, checkNil bool, d *De func (_ fastpathT) DecMapInt16StringV(v map[int16]string, checkNil bool, canChange bool, d *Decoder) (_ map[int16]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24496,11 +20279,8 @@ func (_ fastpathT) DecMapInt16StringV(v map[int16]string, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]string, containerLen) - } else { - v = make(map[int16]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[int16]string, xlen) changed = true } if containerLen > 0 { @@ -24514,23 +20294,19 @@ func (_ fastpathT) DecMapInt16StringV(v map[int16]string, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]uint) v, changed := fastpathTV.DecMapInt16UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -24551,7 +20327,7 @@ func (f fastpathT) DecMapInt16UintX(vp *map[int16]uint, checkNil bool, d *Decode func (_ fastpathT) DecMapInt16UintV(v map[int16]uint, checkNil bool, canChange bool, d *Decoder) (_ map[int16]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24561,11 +20337,8 @@ func (_ fastpathT) DecMapInt16UintV(v map[int16]uint, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]uint, containerLen) - } else { - v = make(map[int16]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int16]uint, xlen) changed = true } if containerLen > 0 { @@ -24579,23 +20352,19 @@ func (_ fastpathT) DecMapInt16UintV(v map[int16]uint, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]uint8) v, changed := fastpathTV.DecMapInt16Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24616,7 +20385,7 @@ func (f fastpathT) DecMapInt16Uint8X(vp *map[int16]uint8, checkNil bool, d *Deco func (_ fastpathT) DecMapInt16Uint8V(v map[int16]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[int16]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24626,11 +20395,8 @@ func (_ fastpathT) DecMapInt16Uint8V(v map[int16]uint8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]uint8, containerLen) - } else { - v = make(map[int16]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[int16]uint8, xlen) changed = true } if containerLen > 0 { @@ -24644,23 +20410,19 @@ func (_ fastpathT) DecMapInt16Uint8V(v map[int16]uint8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]uint16) v, changed := fastpathTV.DecMapInt16Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24681,7 +20443,7 @@ func (f fastpathT) DecMapInt16Uint16X(vp *map[int16]uint16, checkNil bool, d *De func (_ fastpathT) DecMapInt16Uint16V(v map[int16]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[int16]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24691,11 +20453,8 @@ func (_ fastpathT) DecMapInt16Uint16V(v map[int16]uint16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]uint16, containerLen) - } else { - v = make(map[int16]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4) + v = make(map[int16]uint16, xlen) changed = true } if containerLen > 0 { @@ -24709,23 +20468,19 @@ func (_ fastpathT) DecMapInt16Uint16V(v map[int16]uint16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]uint32) v, changed := fastpathTV.DecMapInt16Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24746,7 +20501,7 @@ func (f fastpathT) DecMapInt16Uint32X(vp *map[int16]uint32, checkNil bool, d *De func (_ fastpathT) DecMapInt16Uint32V(v map[int16]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[int16]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24756,11 +20511,8 @@ func (_ fastpathT) DecMapInt16Uint32V(v map[int16]uint32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]uint32, containerLen) - } else { - v = make(map[int16]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[int16]uint32, xlen) changed = true } if containerLen > 0 { @@ -24774,23 +20526,19 @@ func (_ fastpathT) DecMapInt16Uint32V(v map[int16]uint32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]uint64) v, changed := fastpathTV.DecMapInt16Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24811,7 +20559,7 @@ func (f fastpathT) DecMapInt16Uint64X(vp *map[int16]uint64, checkNil bool, d *De func (_ fastpathT) DecMapInt16Uint64V(v map[int16]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[int16]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24821,11 +20569,8 @@ func (_ fastpathT) DecMapInt16Uint64V(v map[int16]uint64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]uint64, containerLen) - } else { - v = make(map[int16]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int16]uint64, xlen) changed = true } if containerLen > 0 { @@ -24839,23 +20584,19 @@ func (_ fastpathT) DecMapInt16Uint64V(v map[int16]uint64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]int) v, changed := fastpathTV.DecMapInt16IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -24876,7 +20617,7 @@ func (f fastpathT) DecMapInt16IntX(vp *map[int16]int, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt16IntV(v map[int16]int, checkNil bool, canChange bool, d *Decoder) (_ map[int16]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24886,11 +20627,8 @@ func (_ fastpathT) DecMapInt16IntV(v map[int16]int, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]int, containerLen) - } else { - v = make(map[int16]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int16]int, xlen) changed = true } if containerLen > 0 { @@ -24904,23 +20642,19 @@ func (_ fastpathT) DecMapInt16IntV(v map[int16]int, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]int8) v, changed := fastpathTV.DecMapInt16Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24941,7 +20675,7 @@ func (f fastpathT) DecMapInt16Int8X(vp *map[int16]int8, checkNil bool, d *Decode func (_ fastpathT) DecMapInt16Int8V(v map[int16]int8, checkNil bool, canChange bool, d *Decoder) (_ map[int16]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24951,11 +20685,8 @@ func (_ fastpathT) DecMapInt16Int8V(v map[int16]int8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]int8, containerLen) - } else { - v = make(map[int16]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[int16]int8, xlen) changed = true } if containerLen > 0 { @@ -24969,23 +20700,19 @@ func (_ fastpathT) DecMapInt16Int8V(v map[int16]int8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]int16) v, changed := fastpathTV.DecMapInt16Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25006,7 +20733,7 @@ func (f fastpathT) DecMapInt16Int16X(vp *map[int16]int16, checkNil bool, d *Deco func (_ fastpathT) DecMapInt16Int16V(v map[int16]int16, checkNil bool, canChange bool, d *Decoder) (_ map[int16]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25016,11 +20743,8 @@ func (_ fastpathT) DecMapInt16Int16V(v map[int16]int16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]int16, containerLen) - } else { - v = make(map[int16]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4) + v = make(map[int16]int16, xlen) changed = true } if containerLen > 0 { @@ -25034,23 +20758,19 @@ func (_ fastpathT) DecMapInt16Int16V(v map[int16]int16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]int32) v, changed := fastpathTV.DecMapInt16Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25071,7 +20791,7 @@ func (f fastpathT) DecMapInt16Int32X(vp *map[int16]int32, checkNil bool, d *Deco func (_ fastpathT) DecMapInt16Int32V(v map[int16]int32, checkNil bool, canChange bool, d *Decoder) (_ map[int16]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25081,11 +20801,8 @@ func (_ fastpathT) DecMapInt16Int32V(v map[int16]int32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]int32, containerLen) - } else { - v = make(map[int16]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[int16]int32, xlen) changed = true } if containerLen > 0 { @@ -25099,23 +20816,19 @@ func (_ fastpathT) DecMapInt16Int32V(v map[int16]int32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]int64) v, changed := fastpathTV.DecMapInt16Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25136,7 +20849,7 @@ func (f fastpathT) DecMapInt16Int64X(vp *map[int16]int64, checkNil bool, d *Deco func (_ fastpathT) DecMapInt16Int64V(v map[int16]int64, checkNil bool, canChange bool, d *Decoder) (_ map[int16]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25146,11 +20859,8 @@ func (_ fastpathT) DecMapInt16Int64V(v map[int16]int64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]int64, containerLen) - } else { - v = make(map[int16]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int16]int64, xlen) changed = true } if containerLen > 0 { @@ -25164,23 +20874,19 @@ func (_ fastpathT) DecMapInt16Int64V(v map[int16]int64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]float32) v, changed := fastpathTV.DecMapInt16Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25201,7 +20907,7 @@ func (f fastpathT) DecMapInt16Float32X(vp *map[int16]float32, checkNil bool, d * func (_ fastpathT) DecMapInt16Float32V(v map[int16]float32, checkNil bool, canChange bool, d *Decoder) (_ map[int16]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25211,11 +20917,8 @@ func (_ fastpathT) DecMapInt16Float32V(v map[int16]float32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]float32, containerLen) - } else { - v = make(map[int16]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[int16]float32, xlen) changed = true } if containerLen > 0 { @@ -25229,23 +20932,19 @@ func (_ fastpathT) DecMapInt16Float32V(v map[int16]float32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]float64) v, changed := fastpathTV.DecMapInt16Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25266,7 +20965,7 @@ func (f fastpathT) DecMapInt16Float64X(vp *map[int16]float64, checkNil bool, d * func (_ fastpathT) DecMapInt16Float64V(v map[int16]float64, checkNil bool, canChange bool, d *Decoder) (_ map[int16]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25276,11 +20975,8 @@ func (_ fastpathT) DecMapInt16Float64V(v map[int16]float64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]float64, containerLen) - } else { - v = make(map[int16]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int16]float64, xlen) changed = true } if containerLen > 0 { @@ -25294,23 +20990,19 @@ func (_ fastpathT) DecMapInt16Float64V(v map[int16]float64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt16BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]bool) v, changed := fastpathTV.DecMapInt16BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -25331,7 +21023,7 @@ func (f fastpathT) DecMapInt16BoolX(vp *map[int16]bool, checkNil bool, d *Decode func (_ fastpathT) DecMapInt16BoolV(v map[int16]bool, checkNil bool, canChange bool, d *Decoder) (_ map[int16]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25341,11 +21033,8 @@ func (_ fastpathT) DecMapInt16BoolV(v map[int16]bool, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]bool, containerLen) - } else { - v = make(map[int16]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[int16]bool, xlen) changed = true } if containerLen > 0 { @@ -25359,23 +21048,19 @@ func (_ fastpathT) DecMapInt16BoolV(v map[int16]bool, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]interface{}) v, changed := fastpathTV.DecMapInt32IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -25396,7 +21081,7 @@ func (f fastpathT) DecMapInt32IntfX(vp *map[int32]interface{}, checkNil bool, d func (_ fastpathT) DecMapInt32IntfV(v map[int32]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[int32]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25406,11 +21091,8 @@ func (_ fastpathT) DecMapInt32IntfV(v map[int32]interface{}, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]interface{}, containerLen) - } else { - v = make(map[int32]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[int32]interface{}, xlen) changed = true } if containerLen > 0 { @@ -25425,11 +21107,7 @@ func (_ fastpathT) DecMapInt32IntfV(v map[int32]interface{}, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -25437,12 +21115,12 @@ func (_ fastpathT) DecMapInt32IntfV(v map[int32]interface{}, checkNil bool, canC v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]string) v, changed := fastpathTV.DecMapInt32StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -25463,7 +21141,7 @@ func (f fastpathT) DecMapInt32StringX(vp *map[int32]string, checkNil bool, d *De func (_ fastpathT) DecMapInt32StringV(v map[int32]string, checkNil bool, canChange bool, d *Decoder) (_ map[int32]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25473,11 +21151,8 @@ func (_ fastpathT) DecMapInt32StringV(v map[int32]string, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]string, containerLen) - } else { - v = make(map[int32]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[int32]string, xlen) changed = true } if containerLen > 0 { @@ -25491,23 +21166,19 @@ func (_ fastpathT) DecMapInt32StringV(v map[int32]string, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]uint) v, changed := fastpathTV.DecMapInt32UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -25528,7 +21199,7 @@ func (f fastpathT) DecMapInt32UintX(vp *map[int32]uint, checkNil bool, d *Decode func (_ fastpathT) DecMapInt32UintV(v map[int32]uint, checkNil bool, canChange bool, d *Decoder) (_ map[int32]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25538,11 +21209,8 @@ func (_ fastpathT) DecMapInt32UintV(v map[int32]uint, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]uint, containerLen) - } else { - v = make(map[int32]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int32]uint, xlen) changed = true } if containerLen > 0 { @@ -25556,23 +21224,19 @@ func (_ fastpathT) DecMapInt32UintV(v map[int32]uint, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]uint8) v, changed := fastpathTV.DecMapInt32Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25593,7 +21257,7 @@ func (f fastpathT) DecMapInt32Uint8X(vp *map[int32]uint8, checkNil bool, d *Deco func (_ fastpathT) DecMapInt32Uint8V(v map[int32]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[int32]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25603,11 +21267,8 @@ func (_ fastpathT) DecMapInt32Uint8V(v map[int32]uint8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]uint8, containerLen) - } else { - v = make(map[int32]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int32]uint8, xlen) changed = true } if containerLen > 0 { @@ -25621,23 +21282,19 @@ func (_ fastpathT) DecMapInt32Uint8V(v map[int32]uint8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]uint16) v, changed := fastpathTV.DecMapInt32Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25658,7 +21315,7 @@ func (f fastpathT) DecMapInt32Uint16X(vp *map[int32]uint16, checkNil bool, d *De func (_ fastpathT) DecMapInt32Uint16V(v map[int32]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[int32]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25668,11 +21325,8 @@ func (_ fastpathT) DecMapInt32Uint16V(v map[int32]uint16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]uint16, containerLen) - } else { - v = make(map[int32]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[int32]uint16, xlen) changed = true } if containerLen > 0 { @@ -25686,23 +21340,19 @@ func (_ fastpathT) DecMapInt32Uint16V(v map[int32]uint16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]uint32) v, changed := fastpathTV.DecMapInt32Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25723,7 +21373,7 @@ func (f fastpathT) DecMapInt32Uint32X(vp *map[int32]uint32, checkNil bool, d *De func (_ fastpathT) DecMapInt32Uint32V(v map[int32]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[int32]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25733,11 +21383,8 @@ func (_ fastpathT) DecMapInt32Uint32V(v map[int32]uint32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]uint32, containerLen) - } else { - v = make(map[int32]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[int32]uint32, xlen) changed = true } if containerLen > 0 { @@ -25751,23 +21398,19 @@ func (_ fastpathT) DecMapInt32Uint32V(v map[int32]uint32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]uint64) v, changed := fastpathTV.DecMapInt32Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25788,7 +21431,7 @@ func (f fastpathT) DecMapInt32Uint64X(vp *map[int32]uint64, checkNil bool, d *De func (_ fastpathT) DecMapInt32Uint64V(v map[int32]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[int32]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25798,11 +21441,8 @@ func (_ fastpathT) DecMapInt32Uint64V(v map[int32]uint64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]uint64, containerLen) - } else { - v = make(map[int32]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int32]uint64, xlen) changed = true } if containerLen > 0 { @@ -25816,23 +21456,19 @@ func (_ fastpathT) DecMapInt32Uint64V(v map[int32]uint64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]int) v, changed := fastpathTV.DecMapInt32IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -25853,7 +21489,7 @@ func (f fastpathT) DecMapInt32IntX(vp *map[int32]int, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt32IntV(v map[int32]int, checkNil bool, canChange bool, d *Decoder) (_ map[int32]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25863,11 +21499,8 @@ func (_ fastpathT) DecMapInt32IntV(v map[int32]int, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]int, containerLen) - } else { - v = make(map[int32]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int32]int, xlen) changed = true } if containerLen > 0 { @@ -25881,23 +21514,19 @@ func (_ fastpathT) DecMapInt32IntV(v map[int32]int, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]int8) v, changed := fastpathTV.DecMapInt32Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25918,7 +21547,7 @@ func (f fastpathT) DecMapInt32Int8X(vp *map[int32]int8, checkNil bool, d *Decode func (_ fastpathT) DecMapInt32Int8V(v map[int32]int8, checkNil bool, canChange bool, d *Decoder) (_ map[int32]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25928,11 +21557,8 @@ func (_ fastpathT) DecMapInt32Int8V(v map[int32]int8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]int8, containerLen) - } else { - v = make(map[int32]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int32]int8, xlen) changed = true } if containerLen > 0 { @@ -25946,23 +21572,19 @@ func (_ fastpathT) DecMapInt32Int8V(v map[int32]int8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]int16) v, changed := fastpathTV.DecMapInt32Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25983,7 +21605,7 @@ func (f fastpathT) DecMapInt32Int16X(vp *map[int32]int16, checkNil bool, d *Deco func (_ fastpathT) DecMapInt32Int16V(v map[int32]int16, checkNil bool, canChange bool, d *Decoder) (_ map[int32]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25993,11 +21615,8 @@ func (_ fastpathT) DecMapInt32Int16V(v map[int32]int16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]int16, containerLen) - } else { - v = make(map[int32]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[int32]int16, xlen) changed = true } if containerLen > 0 { @@ -26011,23 +21630,19 @@ func (_ fastpathT) DecMapInt32Int16V(v map[int32]int16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]int32) v, changed := fastpathTV.DecMapInt32Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26048,7 +21663,7 @@ func (f fastpathT) DecMapInt32Int32X(vp *map[int32]int32, checkNil bool, d *Deco func (_ fastpathT) DecMapInt32Int32V(v map[int32]int32, checkNil bool, canChange bool, d *Decoder) (_ map[int32]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26058,11 +21673,8 @@ func (_ fastpathT) DecMapInt32Int32V(v map[int32]int32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]int32, containerLen) - } else { - v = make(map[int32]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[int32]int32, xlen) changed = true } if containerLen > 0 { @@ -26076,23 +21688,19 @@ func (_ fastpathT) DecMapInt32Int32V(v map[int32]int32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]int64) v, changed := fastpathTV.DecMapInt32Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26113,7 +21721,7 @@ func (f fastpathT) DecMapInt32Int64X(vp *map[int32]int64, checkNil bool, d *Deco func (_ fastpathT) DecMapInt32Int64V(v map[int32]int64, checkNil bool, canChange bool, d *Decoder) (_ map[int32]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26123,11 +21731,8 @@ func (_ fastpathT) DecMapInt32Int64V(v map[int32]int64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]int64, containerLen) - } else { - v = make(map[int32]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int32]int64, xlen) changed = true } if containerLen > 0 { @@ -26141,23 +21746,19 @@ func (_ fastpathT) DecMapInt32Int64V(v map[int32]int64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]float32) v, changed := fastpathTV.DecMapInt32Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26178,7 +21779,7 @@ func (f fastpathT) DecMapInt32Float32X(vp *map[int32]float32, checkNil bool, d * func (_ fastpathT) DecMapInt32Float32V(v map[int32]float32, checkNil bool, canChange bool, d *Decoder) (_ map[int32]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26188,11 +21789,8 @@ func (_ fastpathT) DecMapInt32Float32V(v map[int32]float32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]float32, containerLen) - } else { - v = make(map[int32]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[int32]float32, xlen) changed = true } if containerLen > 0 { @@ -26206,23 +21804,19 @@ func (_ fastpathT) DecMapInt32Float32V(v map[int32]float32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]float64) v, changed := fastpathTV.DecMapInt32Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26243,7 +21837,7 @@ func (f fastpathT) DecMapInt32Float64X(vp *map[int32]float64, checkNil bool, d * func (_ fastpathT) DecMapInt32Float64V(v map[int32]float64, checkNil bool, canChange bool, d *Decoder) (_ map[int32]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26253,11 +21847,8 @@ func (_ fastpathT) DecMapInt32Float64V(v map[int32]float64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]float64, containerLen) - } else { - v = make(map[int32]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int32]float64, xlen) changed = true } if containerLen > 0 { @@ -26271,23 +21862,19 @@ func (_ fastpathT) DecMapInt32Float64V(v map[int32]float64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt32BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]bool) v, changed := fastpathTV.DecMapInt32BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -26308,7 +21895,7 @@ func (f fastpathT) DecMapInt32BoolX(vp *map[int32]bool, checkNil bool, d *Decode func (_ fastpathT) DecMapInt32BoolV(v map[int32]bool, checkNil bool, canChange bool, d *Decoder) (_ map[int32]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26318,11 +21905,8 @@ func (_ fastpathT) DecMapInt32BoolV(v map[int32]bool, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]bool, containerLen) - } else { - v = make(map[int32]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int32]bool, xlen) changed = true } if containerLen > 0 { @@ -26336,23 +21920,19 @@ func (_ fastpathT) DecMapInt32BoolV(v map[int32]bool, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]interface{}) v, changed := fastpathTV.DecMapInt64IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -26373,7 +21953,7 @@ func (f fastpathT) DecMapInt64IntfX(vp *map[int64]interface{}, checkNil bool, d func (_ fastpathT) DecMapInt64IntfV(v map[int64]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[int64]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26383,11 +21963,8 @@ func (_ fastpathT) DecMapInt64IntfV(v map[int64]interface{}, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]interface{}, containerLen) - } else { - v = make(map[int64]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[int64]interface{}, xlen) changed = true } if containerLen > 0 { @@ -26402,11 +21979,7 @@ func (_ fastpathT) DecMapInt64IntfV(v map[int64]interface{}, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -26414,12 +21987,12 @@ func (_ fastpathT) DecMapInt64IntfV(v map[int64]interface{}, checkNil bool, canC v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]string) v, changed := fastpathTV.DecMapInt64StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -26440,7 +22013,7 @@ func (f fastpathT) DecMapInt64StringX(vp *map[int64]string, checkNil bool, d *De func (_ fastpathT) DecMapInt64StringV(v map[int64]string, checkNil bool, canChange bool, d *Decoder) (_ map[int64]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26450,11 +22023,8 @@ func (_ fastpathT) DecMapInt64StringV(v map[int64]string, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]string, containerLen) - } else { - v = make(map[int64]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[int64]string, xlen) changed = true } if containerLen > 0 { @@ -26468,23 +22038,19 @@ func (_ fastpathT) DecMapInt64StringV(v map[int64]string, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]uint) v, changed := fastpathTV.DecMapInt64UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -26505,7 +22071,7 @@ func (f fastpathT) DecMapInt64UintX(vp *map[int64]uint, checkNil bool, d *Decode func (_ fastpathT) DecMapInt64UintV(v map[int64]uint, checkNil bool, canChange bool, d *Decoder) (_ map[int64]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26515,11 +22081,8 @@ func (_ fastpathT) DecMapInt64UintV(v map[int64]uint, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]uint, containerLen) - } else { - v = make(map[int64]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int64]uint, xlen) changed = true } if containerLen > 0 { @@ -26533,23 +22096,19 @@ func (_ fastpathT) DecMapInt64UintV(v map[int64]uint, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]uint8) v, changed := fastpathTV.DecMapInt64Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26570,7 +22129,7 @@ func (f fastpathT) DecMapInt64Uint8X(vp *map[int64]uint8, checkNil bool, d *Deco func (_ fastpathT) DecMapInt64Uint8V(v map[int64]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[int64]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26580,11 +22139,8 @@ func (_ fastpathT) DecMapInt64Uint8V(v map[int64]uint8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]uint8, containerLen) - } else { - v = make(map[int64]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int64]uint8, xlen) changed = true } if containerLen > 0 { @@ -26598,23 +22154,19 @@ func (_ fastpathT) DecMapInt64Uint8V(v map[int64]uint8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]uint16) v, changed := fastpathTV.DecMapInt64Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26635,7 +22187,7 @@ func (f fastpathT) DecMapInt64Uint16X(vp *map[int64]uint16, checkNil bool, d *De func (_ fastpathT) DecMapInt64Uint16V(v map[int64]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[int64]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26645,11 +22197,8 @@ func (_ fastpathT) DecMapInt64Uint16V(v map[int64]uint16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]uint16, containerLen) - } else { - v = make(map[int64]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int64]uint16, xlen) changed = true } if containerLen > 0 { @@ -26663,23 +22212,19 @@ func (_ fastpathT) DecMapInt64Uint16V(v map[int64]uint16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]uint32) v, changed := fastpathTV.DecMapInt64Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26700,7 +22245,7 @@ func (f fastpathT) DecMapInt64Uint32X(vp *map[int64]uint32, checkNil bool, d *De func (_ fastpathT) DecMapInt64Uint32V(v map[int64]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[int64]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26710,11 +22255,8 @@ func (_ fastpathT) DecMapInt64Uint32V(v map[int64]uint32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]uint32, containerLen) - } else { - v = make(map[int64]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int64]uint32, xlen) changed = true } if containerLen > 0 { @@ -26728,23 +22270,19 @@ func (_ fastpathT) DecMapInt64Uint32V(v map[int64]uint32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]uint64) v, changed := fastpathTV.DecMapInt64Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26765,7 +22303,7 @@ func (f fastpathT) DecMapInt64Uint64X(vp *map[int64]uint64, checkNil bool, d *De func (_ fastpathT) DecMapInt64Uint64V(v map[int64]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[int64]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26775,11 +22313,8 @@ func (_ fastpathT) DecMapInt64Uint64V(v map[int64]uint64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]uint64, containerLen) - } else { - v = make(map[int64]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int64]uint64, xlen) changed = true } if containerLen > 0 { @@ -26793,23 +22328,19 @@ func (_ fastpathT) DecMapInt64Uint64V(v map[int64]uint64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]int) v, changed := fastpathTV.DecMapInt64IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -26830,7 +22361,7 @@ func (f fastpathT) DecMapInt64IntX(vp *map[int64]int, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt64IntV(v map[int64]int, checkNil bool, canChange bool, d *Decoder) (_ map[int64]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26840,11 +22371,8 @@ func (_ fastpathT) DecMapInt64IntV(v map[int64]int, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]int, containerLen) - } else { - v = make(map[int64]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int64]int, xlen) changed = true } if containerLen > 0 { @@ -26858,23 +22386,19 @@ func (_ fastpathT) DecMapInt64IntV(v map[int64]int, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]int8) v, changed := fastpathTV.DecMapInt64Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26895,7 +22419,7 @@ func (f fastpathT) DecMapInt64Int8X(vp *map[int64]int8, checkNil bool, d *Decode func (_ fastpathT) DecMapInt64Int8V(v map[int64]int8, checkNil bool, canChange bool, d *Decoder) (_ map[int64]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26905,11 +22429,8 @@ func (_ fastpathT) DecMapInt64Int8V(v map[int64]int8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]int8, containerLen) - } else { - v = make(map[int64]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int64]int8, xlen) changed = true } if containerLen > 0 { @@ -26923,23 +22444,19 @@ func (_ fastpathT) DecMapInt64Int8V(v map[int64]int8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]int16) v, changed := fastpathTV.DecMapInt64Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26960,7 +22477,7 @@ func (f fastpathT) DecMapInt64Int16X(vp *map[int64]int16, checkNil bool, d *Deco func (_ fastpathT) DecMapInt64Int16V(v map[int64]int16, checkNil bool, canChange bool, d *Decoder) (_ map[int64]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26970,11 +22487,8 @@ func (_ fastpathT) DecMapInt64Int16V(v map[int64]int16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]int16, containerLen) - } else { - v = make(map[int64]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int64]int16, xlen) changed = true } if containerLen > 0 { @@ -26988,23 +22502,19 @@ func (_ fastpathT) DecMapInt64Int16V(v map[int64]int16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]int32) v, changed := fastpathTV.DecMapInt64Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27025,7 +22535,7 @@ func (f fastpathT) DecMapInt64Int32X(vp *map[int64]int32, checkNil bool, d *Deco func (_ fastpathT) DecMapInt64Int32V(v map[int64]int32, checkNil bool, canChange bool, d *Decoder) (_ map[int64]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27035,11 +22545,8 @@ func (_ fastpathT) DecMapInt64Int32V(v map[int64]int32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]int32, containerLen) - } else { - v = make(map[int64]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int64]int32, xlen) changed = true } if containerLen > 0 { @@ -27053,23 +22560,19 @@ func (_ fastpathT) DecMapInt64Int32V(v map[int64]int32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]int64) v, changed := fastpathTV.DecMapInt64Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27090,7 +22593,7 @@ func (f fastpathT) DecMapInt64Int64X(vp *map[int64]int64, checkNil bool, d *Deco func (_ fastpathT) DecMapInt64Int64V(v map[int64]int64, checkNil bool, canChange bool, d *Decoder) (_ map[int64]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27100,11 +22603,8 @@ func (_ fastpathT) DecMapInt64Int64V(v map[int64]int64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]int64, containerLen) - } else { - v = make(map[int64]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int64]int64, xlen) changed = true } if containerLen > 0 { @@ -27118,23 +22618,19 @@ func (_ fastpathT) DecMapInt64Int64V(v map[int64]int64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]float32) v, changed := fastpathTV.DecMapInt64Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27155,7 +22651,7 @@ func (f fastpathT) DecMapInt64Float32X(vp *map[int64]float32, checkNil bool, d * func (_ fastpathT) DecMapInt64Float32V(v map[int64]float32, checkNil bool, canChange bool, d *Decoder) (_ map[int64]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27165,11 +22661,8 @@ func (_ fastpathT) DecMapInt64Float32V(v map[int64]float32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]float32, containerLen) - } else { - v = make(map[int64]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int64]float32, xlen) changed = true } if containerLen > 0 { @@ -27183,23 +22676,19 @@ func (_ fastpathT) DecMapInt64Float32V(v map[int64]float32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]float64) v, changed := fastpathTV.DecMapInt64Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27220,7 +22709,7 @@ func (f fastpathT) DecMapInt64Float64X(vp *map[int64]float64, checkNil bool, d * func (_ fastpathT) DecMapInt64Float64V(v map[int64]float64, checkNil bool, canChange bool, d *Decoder) (_ map[int64]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27230,11 +22719,8 @@ func (_ fastpathT) DecMapInt64Float64V(v map[int64]float64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]float64, containerLen) - } else { - v = make(map[int64]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int64]float64, xlen) changed = true } if containerLen > 0 { @@ -27248,23 +22734,19 @@ func (_ fastpathT) DecMapInt64Float64V(v map[int64]float64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapInt64BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]bool) v, changed := fastpathTV.DecMapInt64BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -27285,7 +22767,7 @@ func (f fastpathT) DecMapInt64BoolX(vp *map[int64]bool, checkNil bool, d *Decode func (_ fastpathT) DecMapInt64BoolV(v map[int64]bool, checkNil bool, canChange bool, d *Decoder) (_ map[int64]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27295,11 +22777,8 @@ func (_ fastpathT) DecMapInt64BoolV(v map[int64]bool, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]bool, containerLen) - } else { - v = make(map[int64]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int64]bool, xlen) changed = true } if containerLen > 0 { @@ -27313,23 +22792,19 @@ func (_ fastpathT) DecMapInt64BoolV(v map[int64]bool, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolIntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]interface{}) v, changed := fastpathTV.DecMapBoolIntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -27350,7 +22825,7 @@ func (f fastpathT) DecMapBoolIntfX(vp *map[bool]interface{}, checkNil bool, d *D func (_ fastpathT) DecMapBoolIntfV(v map[bool]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[bool]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27360,11 +22835,8 @@ func (_ fastpathT) DecMapBoolIntfV(v map[bool]interface{}, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]interface{}, containerLen) - } else { - v = make(map[bool]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[bool]interface{}, xlen) changed = true } if containerLen > 0 { @@ -27379,11 +22851,7 @@ func (_ fastpathT) DecMapBoolIntfV(v map[bool]interface{}, checkNil bool, canCha } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] d.decode(&mv) @@ -27391,12 +22859,12 @@ func (_ fastpathT) DecMapBoolIntfV(v map[bool]interface{}, checkNil bool, canCha v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolStringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]string) v, changed := fastpathTV.DecMapBoolStringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -27417,7 +22885,7 @@ func (f fastpathT) DecMapBoolStringX(vp *map[bool]string, checkNil bool, d *Deco func (_ fastpathT) DecMapBoolStringV(v map[bool]string, checkNil bool, canChange bool, d *Decoder) (_ map[bool]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27427,11 +22895,8 @@ func (_ fastpathT) DecMapBoolStringV(v map[bool]string, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]string, containerLen) - } else { - v = make(map[bool]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[bool]string, xlen) changed = true } if containerLen > 0 { @@ -27445,23 +22910,19 @@ func (_ fastpathT) DecMapBoolStringV(v map[bool]string, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolUintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]uint) v, changed := fastpathTV.DecMapBoolUintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -27482,7 +22943,7 @@ func (f fastpathT) DecMapBoolUintX(vp *map[bool]uint, checkNil bool, d *Decoder) func (_ fastpathT) DecMapBoolUintV(v map[bool]uint, checkNil bool, canChange bool, d *Decoder) (_ map[bool]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27492,11 +22953,8 @@ func (_ fastpathT) DecMapBoolUintV(v map[bool]uint, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]uint, containerLen) - } else { - v = make(map[bool]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[bool]uint, xlen) changed = true } if containerLen > 0 { @@ -27510,23 +22968,19 @@ func (_ fastpathT) DecMapBoolUintV(v map[bool]uint, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolUint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolUint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]uint8) v, changed := fastpathTV.DecMapBoolUint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27547,7 +23001,7 @@ func (f fastpathT) DecMapBoolUint8X(vp *map[bool]uint8, checkNil bool, d *Decode func (_ fastpathT) DecMapBoolUint8V(v map[bool]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[bool]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27557,11 +23011,8 @@ func (_ fastpathT) DecMapBoolUint8V(v map[bool]uint8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]uint8, containerLen) - } else { - v = make(map[bool]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[bool]uint8, xlen) changed = true } if containerLen > 0 { @@ -27575,23 +23026,19 @@ func (_ fastpathT) DecMapBoolUint8V(v map[bool]uint8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolUint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]uint16) v, changed := fastpathTV.DecMapBoolUint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27612,7 +23059,7 @@ func (f fastpathT) DecMapBoolUint16X(vp *map[bool]uint16, checkNil bool, d *Deco func (_ fastpathT) DecMapBoolUint16V(v map[bool]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[bool]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27622,11 +23069,8 @@ func (_ fastpathT) DecMapBoolUint16V(v map[bool]uint16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]uint16, containerLen) - } else { - v = make(map[bool]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[bool]uint16, xlen) changed = true } if containerLen > 0 { @@ -27640,23 +23084,19 @@ func (_ fastpathT) DecMapBoolUint16V(v map[bool]uint16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolUint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]uint32) v, changed := fastpathTV.DecMapBoolUint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27677,7 +23117,7 @@ func (f fastpathT) DecMapBoolUint32X(vp *map[bool]uint32, checkNil bool, d *Deco func (_ fastpathT) DecMapBoolUint32V(v map[bool]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[bool]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27687,11 +23127,8 @@ func (_ fastpathT) DecMapBoolUint32V(v map[bool]uint32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]uint32, containerLen) - } else { - v = make(map[bool]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[bool]uint32, xlen) changed = true } if containerLen > 0 { @@ -27705,23 +23142,19 @@ func (_ fastpathT) DecMapBoolUint32V(v map[bool]uint32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolUint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]uint64) v, changed := fastpathTV.DecMapBoolUint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27742,7 +23175,7 @@ func (f fastpathT) DecMapBoolUint64X(vp *map[bool]uint64, checkNil bool, d *Deco func (_ fastpathT) DecMapBoolUint64V(v map[bool]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[bool]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27752,11 +23185,8 @@ func (_ fastpathT) DecMapBoolUint64V(v map[bool]uint64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]uint64, containerLen) - } else { - v = make(map[bool]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[bool]uint64, xlen) changed = true } if containerLen > 0 { @@ -27770,23 +23200,19 @@ func (_ fastpathT) DecMapBoolUint64V(v map[bool]uint64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolIntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]int) v, changed := fastpathTV.DecMapBoolIntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -27807,7 +23233,7 @@ func (f fastpathT) DecMapBoolIntX(vp *map[bool]int, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapBoolIntV(v map[bool]int, checkNil bool, canChange bool, d *Decoder) (_ map[bool]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27817,11 +23243,8 @@ func (_ fastpathT) DecMapBoolIntV(v map[bool]int, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]int, containerLen) - } else { - v = make(map[bool]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[bool]int, xlen) changed = true } if containerLen > 0 { @@ -27835,23 +23258,19 @@ func (_ fastpathT) DecMapBoolIntV(v map[bool]int, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolInt8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]int8) v, changed := fastpathTV.DecMapBoolInt8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27872,7 +23291,7 @@ func (f fastpathT) DecMapBoolInt8X(vp *map[bool]int8, checkNil bool, d *Decoder) func (_ fastpathT) DecMapBoolInt8V(v map[bool]int8, checkNil bool, canChange bool, d *Decoder) (_ map[bool]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27882,11 +23301,8 @@ func (_ fastpathT) DecMapBoolInt8V(v map[bool]int8, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]int8, containerLen) - } else { - v = make(map[bool]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[bool]int8, xlen) changed = true } if containerLen > 0 { @@ -27900,23 +23316,19 @@ func (_ fastpathT) DecMapBoolInt8V(v map[bool]int8, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolInt16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]int16) v, changed := fastpathTV.DecMapBoolInt16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27937,7 +23349,7 @@ func (f fastpathT) DecMapBoolInt16X(vp *map[bool]int16, checkNil bool, d *Decode func (_ fastpathT) DecMapBoolInt16V(v map[bool]int16, checkNil bool, canChange bool, d *Decoder) (_ map[bool]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27947,11 +23359,8 @@ func (_ fastpathT) DecMapBoolInt16V(v map[bool]int16, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]int16, containerLen) - } else { - v = make(map[bool]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[bool]int16, xlen) changed = true } if containerLen > 0 { @@ -27965,23 +23374,19 @@ func (_ fastpathT) DecMapBoolInt16V(v map[bool]int16, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolInt32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]int32) v, changed := fastpathTV.DecMapBoolInt32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -28002,7 +23407,7 @@ func (f fastpathT) DecMapBoolInt32X(vp *map[bool]int32, checkNil bool, d *Decode func (_ fastpathT) DecMapBoolInt32V(v map[bool]int32, checkNil bool, canChange bool, d *Decoder) (_ map[bool]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -28012,11 +23417,8 @@ func (_ fastpathT) DecMapBoolInt32V(v map[bool]int32, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]int32, containerLen) - } else { - v = make(map[bool]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[bool]int32, xlen) changed = true } if containerLen > 0 { @@ -28030,23 +23432,19 @@ func (_ fastpathT) DecMapBoolInt32V(v map[bool]int32, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolInt64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]int64) v, changed := fastpathTV.DecMapBoolInt64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -28067,7 +23465,7 @@ func (f fastpathT) DecMapBoolInt64X(vp *map[bool]int64, checkNil bool, d *Decode func (_ fastpathT) DecMapBoolInt64V(v map[bool]int64, checkNil bool, canChange bool, d *Decoder) (_ map[bool]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -28077,11 +23475,8 @@ func (_ fastpathT) DecMapBoolInt64V(v map[bool]int64, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]int64, containerLen) - } else { - v = make(map[bool]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[bool]int64, xlen) changed = true } if containerLen > 0 { @@ -28095,23 +23490,19 @@ func (_ fastpathT) DecMapBoolInt64V(v map[bool]int64, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolFloat32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]float32) v, changed := fastpathTV.DecMapBoolFloat32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -28132,7 +23523,7 @@ func (f fastpathT) DecMapBoolFloat32X(vp *map[bool]float32, checkNil bool, d *De func (_ fastpathT) DecMapBoolFloat32V(v map[bool]float32, checkNil bool, canChange bool, d *Decoder) (_ map[bool]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -28142,11 +23533,8 @@ func (_ fastpathT) DecMapBoolFloat32V(v map[bool]float32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]float32, containerLen) - } else { - v = make(map[bool]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[bool]float32, xlen) changed = true } if containerLen > 0 { @@ -28160,23 +23548,19 @@ func (_ fastpathT) DecMapBoolFloat32V(v map[bool]float32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolFloat64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]float64) v, changed := fastpathTV.DecMapBoolFloat64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -28197,7 +23581,7 @@ func (f fastpathT) DecMapBoolFloat64X(vp *map[bool]float64, checkNil bool, d *De func (_ fastpathT) DecMapBoolFloat64V(v map[bool]float64, checkNil bool, canChange bool, d *Decoder) (_ map[bool]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -28207,11 +23591,8 @@ func (_ fastpathT) DecMapBoolFloat64V(v map[bool]float64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]float64, containerLen) - } else { - v = make(map[bool]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[bool]float64, xlen) changed = true } if containerLen > 0 { @@ -28225,23 +23606,19 @@ func (_ fastpathT) DecMapBoolFloat64V(v map[bool]float64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } -func (f decFnInfo) fastpathDecMapBoolBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolBoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]bool) v, changed := fastpathTV.DecMapBoolBoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -28262,7 +23639,7 @@ func (f fastpathT) DecMapBoolBoolX(vp *map[bool]bool, checkNil bool, d *Decoder) func (_ fastpathT) DecMapBoolBoolV(v map[bool]bool, checkNil bool, canChange bool, d *Decoder) (_ map[bool]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -28272,11 +23649,8 @@ func (_ fastpathT) DecMapBoolBoolV(v map[bool]bool, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]bool, containerLen) - } else { - v = make(map[bool]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[bool]bool, xlen) changed = true } if containerLen > 0 { @@ -28290,18 +23664,14 @@ func (_ fastpathT) DecMapBoolBoolV(v map[bool]bool, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } mk := dd.DecodeBool() - dd.ReadMapKVSeparator() mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.go.tmpl b/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.go.tmpl index 19138c87ab85..5fecafd21cbf 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.go.tmpl +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.go.tmpl @@ -1,7 +1,7 @@ // //+build ignore // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. // ************************************************************ // DO NOT EDIT. @@ -48,8 +48,8 @@ var fastpathTV fastpathT type fastpathE struct { rtid uintptr rt reflect.Type - encfn func(encFnInfo, reflect.Value) - decfn func(decFnInfo, reflect.Value) + encfn func(*encFnInfo, reflect.Value) + decfn func(*decFnInfo, reflect.Value) } type fastpathA [{{ .FastpathLen }}]fastpathE @@ -85,7 +85,7 @@ func init() { return } i := 0 - fn := func(v interface{}, fe func(encFnInfo, reflect.Value), fd func(decFnInfo, reflect.Value)) (f fastpathE) { + fn := func(v interface{}, fe func(*encFnInfo, reflect.Value), fd func(*decFnInfo, reflect.Value)) (f fastpathE) { xrt := reflect.TypeOf(v) xptr := reflect.ValueOf(xrt).Pointer() fastpathAV[i] = fastpathE{xptr, xrt, fe, fd} @@ -93,11 +93,11 @@ func init() { return } - {{range .Values}}{{if not .Primitive}}{{if .Slice }} - fn([]{{ .Elem }}(nil), (encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}} + {{range .Values}}{{if not .Primitive}}{{if not .MapKey }} + fn([]{{ .Elem }}(nil), (*encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (*decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}} - {{range .Values}}{{if not .Primitive}}{{if not .Slice }} - fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}} + {{range .Values}}{{if not .Primitive}}{{if .MapKey }} + fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (*decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}} sort.Sort(fastpathAslice(fastpathAV[:])) } @@ -107,10 +107,10 @@ func init() { // -- -- fast path type switch func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { switch v := iv.(type) { -{{range .Values}}{{if not .Primitive}}{{if .Slice }} +{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} case []{{ .Elem }}:{{else}} case map[{{ .MapKey }}]{{ .Elem }}:{{end}} - fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e){{if .Slice }} + fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e){{if not .MapKey }} case *[]{{ .Elem }}:{{else}} case *map[{{ .MapKey }}]{{ .Elem }}:{{end}} fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, fastpathCheckNilTrue, e) @@ -123,7 +123,7 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { switch v := iv.(type) { -{{range .Values}}{{if not .Primitive}}{{if .Slice }} +{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} case []{{ .Elem }}: fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e) case *[]{{ .Elem }}: @@ -137,7 +137,7 @@ func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { switch v := iv.(type) { -{{range .Values}}{{if not .Primitive}}{{if not .Slice }} +{{range .Values}}{{if not .Primitive}}{{if .MapKey }} case map[{{ .MapKey }}]{{ .Elem }}: fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e) case *map[{{ .MapKey }}]{{ .Elem }}: @@ -150,9 +150,9 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { } // -- -- fast path functions -{{range .Values}}{{if not .Primitive}}{{if .Slice }} +{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} -func (f encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) { +func (f *encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) { fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, checkNil bool, e *Encoder) { @@ -162,26 +162,17 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, checkNil b return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - {{ encmd .Elem "v2"}} - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - {{ encmd .Elem "v2"}} - } - ee.EncodeArrayEnd() + for _, v2 := range v { + {{ encmd .Elem "v2"}} } + ee.EncodeEnd() } {{end}}{{end}}{{end}} -{{range .Values}}{{if not .Primitive}}{{if not .Slice }} +{{range .Values}}{{if not .Primitive}}{{if .MapKey }} -func (f encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) { +func (f *encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) { fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().(map[{{ .MapKey }}]{{ .Elem }}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, checkNil bool, e *Encoder) { @@ -192,32 +183,15 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Ele } ee.EncodeMapStart(len(v)) {{if eq .MapKey "string"}}asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0{{end}} - if e.be { - for k2, v2 := range v { - {{if eq .MapKey "string"}}if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - }{{else}}{{ encmd .MapKey "k2"}}{{end}} - {{ encmd .Elem "v2"}} - } - } else { - j := 0 - for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - {{if eq .MapKey "string"}}if asSymbols { - ee.EncodeSymbol(k2) - } else { - ee.EncodeString(c_UTF8, k2) - }{{else}}{{ encmd .MapKey "k2"}}{{end}} - ee.EncodeMapKVSeparator() - {{ encmd .Elem "v2"}} - j++ - } - ee.EncodeMapEnd() + for k2, v2 := range v { + {{if eq .MapKey "string"}}if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) + }{{else}}{{ encmd .MapKey "k2"}}{{end}} + {{ encmd .Elem "v2"}} } + ee.EncodeEnd() } {{end}}{{end}}{{end}} @@ -227,10 +201,10 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Ele // -- -- fast path type switch func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { switch v := iv.(type) { -{{range .Values}}{{if not .Primitive}}{{if .Slice }} +{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} case []{{ .Elem }}:{{else}} case map[{{ .MapKey }}]{{ .Elem }}:{{end}} - fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, fastpathCheckNilFalse, false, d){{if .Slice }} + fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, fastpathCheckNilFalse, false, d){{if not .MapKey }} case *[]{{ .Elem }}:{{else}} case *map[{{ .MapKey }}]{{ .Elem }}:{{end}} v2, changed2 := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, fastpathCheckNilFalse, true, d) @@ -245,16 +219,16 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { } // -- -- fast path functions -{{range .Values}}{{if not .Primitive}}{{if .Slice }} +{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{/* Slices can change if they - did not come from an array - are addressable (from a ptr) - are settable (e.g. contained in an interface{}) */}} -func (f decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { +func (f *decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { {{/* // CanSet => CanAddr + Exported */}} vp := rv.Addr().Interface().(*[]{{ .Elem }}) v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -275,7 +249,7 @@ func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, checkNil func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil bool, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + {{/* // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() */}} if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -284,47 +258,59 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil b } slh, containerLenS := d.decSliceHelperStart() + x2read := containerLenS + var xtrunc bool if canChange && v == nil { - if containerLenS <= 0 { - v = []{{ .Elem }}{} - } else { - v = make([]{{ .Elem }}, containerLenS, containerLenS) + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }}); xtrunc { + x2read = xlen } + v = make([]{{ .Elem }}, xlen) changed = true - } + } if containerLenS == 0 { if canChange && len(v) != 0 { v = v[:0] changed = true }{{/* - // slh.End() // dd.ReadArrayEnd() + // slh.End() // dd.ReadArrayEnd() */}} return v, changed } - // for j := 0; j < containerLenS; j++ { + {{/* // for j := 0; j < containerLenS; j++ { */}} if containerLenS > 0 { - decLen := containerLenS if containerLenS > cap(v) { - if canChange { - s := make([]{{ .Elem }}, containerLenS, containerLenS) + if canChange { {{/* + // fast-path is for "basic" immutable types, so no need to copy them over + // s := make([]{{ .Elem }}, decInferLen(containerLenS, d.h.MaxInitLen)) // copy(s, v[:cap(v)]) - v = s + // v = s */}} + var xlen int + if xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }}); xtrunc { + x2read = xlen + } + v = make([]{{ .Elem }}, xlen) changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) + x2read = len(v) } } else if containerLenS != len(v) { v = v[:containerLenS] changed = true } - // all checks done. cannot go past len. + {{/* // all checks done. cannot go past len. */}} j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { {{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }} } - if !canChange { + if xtrunc { {{/* // means canChange=true, changed=true already. */}} + for ; j < containerLenS; j++ { + v = append(v, {{ zerocmd .Elem }}) + {{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }} + } + } else if !canChange { for ; j < containerLenS; j++ { d.swallow() } @@ -340,10 +326,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil b d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + if j < len(v) { {{/* // all checks done. cannot go past len. */}} {{ if eq .Elem "interface{}" }}d.decode(&v[j]) {{ else }}v[j] = {{ decmd .Elem }}{{ end }} } else { @@ -358,13 +341,13 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil b {{end}}{{end}}{{end}} -{{range .Values}}{{if not .Primitive}}{{if not .Slice }} +{{range .Values}}{{if not .Primitive}}{{if .MapKey }} {{/* Maps can change if they are - addressable (from a ptr) - settable (e.g. contained in an interface{}) */}} -func (f decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { +func (f *decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[{{ .MapKey }}]{{ .Elem }}) v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, fastpathCheckNilFalse, true, f.d) @@ -385,7 +368,7 @@ func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .E func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, checkNil bool, canChange bool, d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + {{/* // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() */}} if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -395,11 +378,8 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Ele containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[{{ .MapKey }}]{{ .Elem }}, containerLen) - } else { - v = make(map[{{ .MapKey }}]{{ .Elem }}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }}) + v = make(map[{{ .MapKey }}]{{ .Elem }}, xlen) changed = true } if containerLen > 0 { @@ -407,7 +387,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Ele {{ if eq .MapKey "interface{}" }}var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) {{/* // maps cannot have []byte as key. switch to string. */}} }{{ else }}mk := {{ decmd .MapKey }}{{ end }} mv := v[mk] {{ if eq .Elem "interface{}" }}d.decode(&mv) @@ -418,15 +398,11 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Ele } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } {{ if eq .MapKey "interface{}" }}var mk interface{} d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = string(bv) {{/* // maps cannot have []byte as key. switch to string. */}} }{{ else }}mk := {{ decmd .MapKey }}{{ end }} - dd.ReadMapKVSeparator() mv := v[mk] {{ if eq .Elem "interface{}" }}d.decode(&mv) {{ else }}mv = {{ decmd .Elem }}{{ end }} @@ -434,7 +410,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Ele v[mk] = mv } } - dd.ReadMapEnd() + dd.ReadEnd() } return v, changed } diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-array.go.tmpl b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-array.go.tmpl index ffb2cc4f249e..eb31a9a963a6 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-array.go.tmpl +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-array.go.tmpl @@ -1,13 +1,17 @@ -{{var "v"}} := *{{ .Varname }} -{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() +{{var "v"}} := {{ if not isArray}}*{{ end }}{{ .Varname }} +{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}} + +var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}} +var {{var "c"}}, {{var "rt"}} bool {{/* // changed, truncated */}} +_, _, _ = {{var "c"}}, {{var "rt"}}, {{var "rl"}} +{{var "rr"}} = {{var "l"}} +{{/* rl is NOT used. Only used for getting DecInferLen. len(r) used directly in code */}} -var {{var "c"}} bool {{ if not isArray }}if {{var "v"}} == nil { - if {{var "l"}} <= 0 { - {{var "v"}} = make({{ .CTyp }}, 0) - } else { - {{var "v"}} = make({{ .CTyp }}, {{var "l"}}) + if {{var "rl"}}, {{var "rt"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }}); {{var "rt"}} { + {{var "rr"}} = {{var "rl"}} } + {{var "v"}} = make({{ .CTyp }}, {{var "rl"}}) {{var "c"}} = true } {{ end }} @@ -23,41 +27,45 @@ if {{var "l"}} == 0 { {{ if isSlice }} {{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} {{var "v"}} <- {{var "t"}} {{ else }} - {{var "n"}} := {{var "l"}} if {{var "l"}} > cap({{var "v"}}) { - {{ if isArray }}r.ReadArrayCannotExpand(len({{var "v"}}), {{var "l"}}) - {{var "n"}} = len({{var "v"}}) - {{ else }}{{ if .Immutable }} + {{ if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}}) + {{ else }}{{var "rl"}}, {{var "rt"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }}) + {{ if .Immutable }} {{var "v2"}} := {{var "v"}} - {{var "v"}} = make([]{{ .Typ }}, {{var "l"}}, {{var "l"}}) + {{var "v"}} = make([]{{ .Typ }}, {{var "rl"}}) if len({{var "v"}}) > 0 { copy({{var "v"}}, {{var "v2"}}[:cap({{var "v2"}})]) } - {{ else }}{{var "v"}} = make([]{{ .Typ }}, {{var "l"}}, {{var "l"}}) + {{ else }}{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}}) {{ end }}{{var "c"}} = true {{ end }} + {{var "rr"}} = len({{var "v"}}) } else if {{var "l"}} != len({{var "v"}}) { - {{var "v"}} = {{var "v"}}[:{{var "l"}}] - {{var "c"}} = true + {{ if isSlice }}{{var "v"}} = {{var "v"}}[:{{var "l"}}] + {{var "c"}} = true {{ end }} } {{var "j"}} := 0 - for ; {{var "j"}} < {{var "n"}} ; {{var "j"}}++ { + for ; {{var "j"}} < {{var "rr"}} ; {{var "j"}}++ { {{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }} - } {{ if isArray }} - for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { + } + {{ if isArray }}for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { z.DecSwallow() - }{{ end }} - {{ end }}{{/* closing if not chan */}} + } + {{ else }}if {{var "rt"}} { {{/* means that it is mutable and slice */}} + for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { + {{var "v"}} = append({{var "v"}}, {{ zero}}) + {{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }} + } + } + {{ end }} + {{ end }}{{/* closing 'if not chan' */}} } else { for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { if {{var "j"}} >= len({{var "v"}}) { - {{ if isArray }}r.ReadArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1) + {{ if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1) {{ else if isSlice}}{{var "v"}} = append({{var "v"}}, {{zero}})// var {{var "z"}} {{ .Typ }} {{var "c"}} = true {{ end }} } - if {{var "j"}} > 0 { - {{var "h"}}.Sep({{var "j"}}) - } {{ if isChan}} var {{var "t"}} {{ .Typ }} {{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} @@ -72,6 +80,7 @@ if {{var "l"}} == 0 { {{ if isSlice }} } {{var "h"}}.End() } -if {{var "c"}} { +{{ if not isArray }}if {{var "c"}} { *{{ .Varname }} = {{var "v"}} -} +}{{ end }} + diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-map.go.tmpl b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-map.go.tmpl index 9f8dafa548c1..d1535f4a69b7 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-map.go.tmpl +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-map.go.tmpl @@ -1,11 +1,8 @@ {{var "v"}} := *{{ .Varname }} {{var "l"}} := r.ReadMapStart() if {{var "v"}} == nil { - if {{var "l"}} > 0 { - {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "l"}}) - } else { - {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}) // supports indefinite-length, etc - } + {{var "rl"}}, _ := z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }}) + {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}}) *{{ .Varname }} = {{var "v"}} } if {{var "l"}} > 0 { @@ -25,9 +22,6 @@ for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ { } } else if {{var "l"}} < 0 { for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { - if {{var "j"}} > 0 { - r.ReadMapEntrySeparator() - } var {{var "mk"}} {{ .KTyp }} {{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }} {{ if eq .KTyp "interface{}" }}// special case if a byte array. @@ -35,12 +29,11 @@ for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { {{var "mk"}} = string({{var "bv"}}) } {{ end }} - r.ReadMapKVSeparator() {{var "mv"}} := {{var "v"}}[{{var "mk"}}] {{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }} if {{var "v"}} != nil { {{var "v"}}[{{var "mk"}}] = {{var "mv"}} } } -r.ReadMapEnd() +r.ReadEnd() } // else len==0: TODO: Should we clear map entries? diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.generated.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.generated.go index 1811a4877c87..9710eca501a0 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.generated.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.generated.go @@ -1,7 +1,7 @@ // //+build ignore // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. // ************************************************************ // DO NOT EDIT. @@ -10,6 +10,11 @@ package codec +import ( + "encoding" + "reflect" +) + // This file is used to generate helper code for codecgen. // The values here i.e. genHelper(En|De)coder are not to be used directly by // library users. They WILL change continously and without notice. @@ -60,6 +65,56 @@ func (f genHelperEncoder) EncFallback(iv interface{}) { f.e.encodeI(iv, false, false) } +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) { + bs, fnerr := iv.MarshalText() + f.e.marshal(bs, fnerr, false, c_UTF8) +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) { + bs, fnerr := iv.MarshalJSON() + f.e.marshal(bs, fnerr, true, c_UTF8) +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) { + bs, fnerr := iv.MarshalBinary() + f.e.marshal(bs, fnerr, false, c_RAW) +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) TimeRtidIfBinc() uintptr { + if _, ok := f.e.hh.(*BincHandle); ok { + return timeTypId + } + return 0 +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) IsJSONHandle() bool { + return f.e.js +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) HasExtensions() bool { + return len(f.e.h.extHandle) != 0 +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) EncExt(v interface{}) (r bool) { + rt := reflect.TypeOf(v) + if rt.Kind() == reflect.Ptr { + rt = rt.Elem() + } + rtid := reflect.ValueOf(rt).Pointer() + if xfFn := f.e.h.getExt(rtid); xfFn != nil { + f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e) + return true + } + return false +} + // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* func (f genHelperDecoder) DecBasicHandle() *BasicHandle { return f.d.h @@ -100,3 +155,66 @@ func (f genHelperDecoder) DecStructFieldNotFound(index int, name string) { func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) { f.d.arrayCannotExpand(sliceLen, streamLen) } + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) { + fnerr := tm.UnmarshalText(f.d.d.DecodeBytes(f.d.b[:], true, true)) + if fnerr != nil { + panic(fnerr) + } +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) { + // bs := f.dd.DecodeBytes(f.d.b[:], true, true) + f.d.r.track() + f.d.swallow() + bs := f.d.r.stopTrack() + // fmt.Printf(">>>>>> CODECGEN JSON: %s\n", bs) + fnerr := tm.UnmarshalJSON(bs) + if fnerr != nil { + panic(fnerr) + } +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) { + fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, false, true)) + if fnerr != nil { + panic(fnerr) + } +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) TimeRtidIfBinc() uintptr { + if _, ok := f.d.hh.(*BincHandle); ok { + return timeTypId + } + return 0 +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) IsJSONHandle() bool { + return f.d.js +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) HasExtensions() bool { + return len(f.d.h.extHandle) != 0 +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecExt(v interface{}) (r bool) { + rt := reflect.TypeOf(v).Elem() + rtid := reflect.ValueOf(rt).Pointer() + if xfFn := f.d.h.getExt(rtid); xfFn != nil { + f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext) + return true + } + return false +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int, truncated bool) { + return decInferLen(clen, maxlen, unit) +} diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.go.tmpl b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.go.tmpl index 50c029975f4b..8bc5061126f2 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.go.tmpl +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.go.tmpl @@ -1,7 +1,7 @@ // //+build ignore // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. // ************************************************************ // DO NOT EDIT. @@ -10,6 +10,11 @@ package codec +import ( + "encoding" + "reflect" +) + // This file is used to generate helper code for codecgen. // The values here i.e. genHelper(En|De)coder are not to be used directly by // library users. They WILL change continously and without notice. @@ -48,6 +53,7 @@ type genHelperDecoder struct { func (f genHelperEncoder) EncBasicHandle() *BasicHandle { return f.e.h } + // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* func (f genHelperEncoder) EncBinary() bool { return f.e.be // f.e.hh.isBinaryEncoding() @@ -57,6 +63,49 @@ func (f genHelperEncoder) EncFallback(iv interface{}) { // println(">>>>>>>>> EncFallback") f.e.encodeI(iv, false, false) } +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) { + bs, fnerr := iv.MarshalText() + f.e.marshal(bs, fnerr, false, c_UTF8) +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) { + bs, fnerr := iv.MarshalJSON() + f.e.marshal(bs, fnerr, true, c_UTF8) +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) { + bs, fnerr := iv.MarshalBinary() + f.e.marshal(bs, fnerr, false, c_RAW) +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) TimeRtidIfBinc() uintptr { + if _, ok := f.e.hh.(*BincHandle); ok { + return timeTypId + } + return 0 +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) IsJSONHandle() bool { + return f.e.js +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) HasExtensions() bool { + return len(f.e.h.extHandle) != 0 +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) EncExt(v interface{}) (r bool) { + rt := reflect.TypeOf(v) + if rt.Kind() == reflect.Ptr { + rt = rt.Elem() + } + rtid := reflect.ValueOf(rt).Pointer() + if xfFn := f.e.h.getExt(rtid); xfFn != nil { + f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e) + return true + } + return false +} // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* func (f genHelperDecoder) DecBasicHandle() *BasicHandle { @@ -91,7 +140,61 @@ func (f genHelperDecoder) DecStructFieldNotFound(index int, name string) { func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) { f.d.arrayCannotExpand(sliceLen, streamLen) } - +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) { + fnerr := tm.UnmarshalText(f.d.d.DecodeBytes(f.d.b[:], true, true)) + if fnerr != nil { + panic(fnerr) + } +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) { + // bs := f.dd.DecodeBytes(f.d.b[:], true, true) + f.d.r.track() + f.d.swallow() + bs := f.d.r.stopTrack() + // fmt.Printf(">>>>>> CODECGEN JSON: %s\n", bs) + fnerr := tm.UnmarshalJSON(bs) + if fnerr != nil { + panic(fnerr) + } +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) { + fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, false, true)) + if fnerr != nil { + panic(fnerr) + } +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) TimeRtidIfBinc() uintptr { + if _, ok := f.d.hh.(*BincHandle); ok { + return timeTypId + } + return 0 +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) IsJSONHandle() bool { + return f.d.js +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) HasExtensions() bool { + return len(f.d.h.extHandle) != 0 +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecExt(v interface{}) (r bool) { + rt := reflect.TypeOf(v).Elem() + rtid := reflect.ValueOf(rt).Pointer() + if xfFn := f.d.h.getExt(rtid); xfFn != nil { + f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext) + return true + } + return false +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int, truncated bool) { + return decInferLen(clen, maxlen, unit) +} {{/* diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.generated.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.generated.go index f035401d80e5..9a35f02fae31 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.generated.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.generated.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec @@ -9,11 +9,8 @@ const genDecMapTmpl = ` {{var "v"}} := *{{ .Varname }} {{var "l"}} := r.ReadMapStart() if {{var "v"}} == nil { - if {{var "l"}} > 0 { - {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "l"}}) - } else { - {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}) // supports indefinite-length, etc - } + {{var "rl"}}, _ := z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }}) + {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}}) *{{ .Varname }} = {{var "v"}} } if {{var "l"}} > 0 { @@ -33,9 +30,6 @@ for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ { } } else if {{var "l"}} < 0 { for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { - if {{var "j"}} > 0 { - r.ReadMapEntrySeparator() - } var {{var "mk"}} {{ .KTyp }} {{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }} {{ if eq .KTyp "interface{}" }}// special case if a byte array. @@ -43,28 +37,31 @@ for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { {{var "mk"}} = string({{var "bv"}}) } {{ end }} - r.ReadMapKVSeparator() {{var "mv"}} := {{var "v"}}[{{var "mk"}}] {{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }} if {{var "v"}} != nil { {{var "v"}}[{{var "mk"}}] = {{var "mv"}} } } -r.ReadMapEnd() +r.ReadEnd() } // else len==0: TODO: Should we clear map entries? ` const genDecListTmpl = ` -{{var "v"}} := *{{ .Varname }} -{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() +{{var "v"}} := {{ if not isArray}}*{{ end }}{{ .Varname }} +{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}} + +var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}} +var {{var "c"}}, {{var "rt"}} bool {{/* // changed, truncated */}} +_, _, _ = {{var "c"}}, {{var "rt"}}, {{var "rl"}} +{{var "rr"}} = {{var "l"}} +{{/* rl is NOT used. Only used for getting DecInferLen. len(r) used directly in code */}} -var {{var "c"}} bool {{ if not isArray }}if {{var "v"}} == nil { - if {{var "l"}} <= 0 { - {{var "v"}} = make({{ .CTyp }}, 0) - } else { - {{var "v"}} = make({{ .CTyp }}, {{var "l"}}) + if {{var "rl"}}, {{var "rt"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }}); {{var "rt"}} { + {{var "rr"}} = {{var "rl"}} } + {{var "v"}} = make({{ .CTyp }}, {{var "rl"}}) {{var "c"}} = true } {{ end }} @@ -80,41 +77,45 @@ if {{var "l"}} == 0 { {{ if isSlice }} {{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} {{var "v"}} <- {{var "t"}} {{ else }} - {{var "n"}} := {{var "l"}} if {{var "l"}} > cap({{var "v"}}) { - {{ if isArray }}r.ReadArrayCannotExpand(len({{var "v"}}), {{var "l"}}) - {{var "n"}} = len({{var "v"}}) - {{ else }}{{ if .Immutable }} + {{ if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}}) + {{ else }}{{var "rl"}}, {{var "rt"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }}) + {{ if .Immutable }} {{var "v2"}} := {{var "v"}} - {{var "v"}} = make([]{{ .Typ }}, {{var "l"}}, {{var "l"}}) + {{var "v"}} = make([]{{ .Typ }}, {{var "rl"}}) if len({{var "v"}}) > 0 { copy({{var "v"}}, {{var "v2"}}[:cap({{var "v2"}})]) } - {{ else }}{{var "v"}} = make([]{{ .Typ }}, {{var "l"}}, {{var "l"}}) + {{ else }}{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}}) {{ end }}{{var "c"}} = true {{ end }} + {{var "rr"}} = len({{var "v"}}) } else if {{var "l"}} != len({{var "v"}}) { - {{var "v"}} = {{var "v"}}[:{{var "l"}}] - {{var "c"}} = true + {{ if isSlice }}{{var "v"}} = {{var "v"}}[:{{var "l"}}] + {{var "c"}} = true {{ end }} } {{var "j"}} := 0 - for ; {{var "j"}} < {{var "n"}} ; {{var "j"}}++ { + for ; {{var "j"}} < {{var "rr"}} ; {{var "j"}}++ { {{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }} - } {{ if isArray }} - for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { + } + {{ if isArray }}for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { z.DecSwallow() - }{{ end }} - {{ end }}{{/* closing if not chan */}} + } + {{ else }}if {{var "rt"}} { {{/* means that it is mutable and slice */}} + for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { + {{var "v"}} = append({{var "v"}}, {{ zero}}) + {{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }} + } + } + {{ end }} + {{ end }}{{/* closing 'if not chan' */}} } else { for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { if {{var "j"}} >= len({{var "v"}}) { - {{ if isArray }}r.ReadArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1) + {{ if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1) {{ else if isSlice}}{{var "v"}} = append({{var "v"}}, {{zero}})// var {{var "z"}} {{ .Typ }} {{var "c"}} = true {{ end }} } - if {{var "j"}} > 0 { - {{var "h"}}.Sep({{var "j"}}) - } {{ if isChan}} var {{var "t"}} {{ .Typ }} {{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} @@ -129,8 +130,9 @@ if {{var "l"}} == 0 { {{ if isSlice }} } {{var "h"}}.End() } -if {{var "c"}} { +{{ if not isArray }}if {{var "c"}} { *{{ .Varname }} = {{var "v"}} -} +}{{ end }} + ` diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.go index 618eb5740c4c..762f25cd54a2 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec @@ -12,8 +12,10 @@ import ( "io" "io/ioutil" "math/rand" + "os" "reflect" "regexp" + "sort" "strconv" "strings" "sync" @@ -22,14 +24,25 @@ import ( ) // --------------------------------------------------- -// codecgen only works in the following: -// - extensions are not supported. Do not make a type a Selfer and an extension. -// - Selfer takes precedence. -// Any type that implements it knows how to encode/decode itself statically. -// Extensions are only known at runtime. -// codecgen only looks at the Kind of the type. +// codecgen supports the full cycle of reflection-based codec: +// - RawExt +// - Builtins +// - Extensions +// - (Binary|Text|JSON)(Unm|M)arshal +// - generic by-kind // -// - the following types are supported: +// This means that, for dynamic things, we MUST use reflection to at least get the reflect.Type. +// In those areas, we try to only do reflection or interface-conversion when NECESSARY: +// - Extensions, only if Extensions are configured. +// +// However, codecgen doesn't support the following: +// - Canonical option. (codecgen IGNORES it currently) +// This is just because it has not been implemented. +// +// During encode/decode, Selfer takes precedence. +// A type implementing Selfer will know how to encode/decode itself statically. +// +// The following field types are supported: // array: [n]T // slice: []T // map: map[K]V @@ -66,11 +79,24 @@ import ( // It was a concious decision to have gen.go always explicitly call EncodeNil or TryDecodeAsNil. // This way, there isn't a function call overhead just to see that we should not enter a block of code. -const GenVersion = 2 // increment this value each time codecgen changes fundamentally. +// GenVersion is the current version of codecgen. +// +// NOTE: Increment this value each time codecgen changes fundamentally. +// Fundamental changes are: +// - helper methods change (signature change, new ones added, some removed, etc) +// - codecgen command line changes +// +// v1: Initial Version +// v2: +// v3: Changes for Kubernetes: +// changes in signature of some unpublished helper methods and codecgen cmdline arguments. +// v4: Removed separator support from (en|de)cDriver, and refactored codec(gen) +const GenVersion = 4 const ( - genCodecPkg = "codec1978" - genTempVarPfx = "yy" + genCodecPkg = "codec1978" + genTempVarPfx = "yy" + genTopLevelVarName = "x" // ignore canBeNil parameter, and always set to true. // This is because nil can appear anywhere, so we should always check. @@ -94,30 +120,39 @@ var ( // genRunner holds some state used during a Gen run. type genRunner struct { w io.Writer // output - c uint64 // ctr used for generating varsfx + c uint64 // counter used for generating varsfx t []reflect.Type // list of types to run selfer on - tc reflect.Type // currently running selfer on this type - te map[uintptr]bool // types for which the encoder has been created - td map[uintptr]bool // types for which the decoder has been created - cp string // codec import path - im map[string]reflect.Type // imports to add + tc reflect.Type // currently running selfer on this type + te map[uintptr]bool // types for which the encoder has been created + td map[uintptr]bool // types for which the decoder has been created + cp string // codec import path + + im map[string]reflect.Type // imports to add + imn map[string]string // package names of imports to add + imc uint64 // counter for import numbers + is map[reflect.Type]struct{} // types seen during import search bp string // base PkgPath, for which we are generating for cpfx string // codec package prefix unsafe bool // is unsafe to be used in generated code? - ts map[reflect.Type]struct{} // types for which enc/dec must be generated - xs string // top level variable/constant suffix - hn string // fn helper type name + tm map[reflect.Type]struct{} // types for which enc/dec must be generated + ts []reflect.Type // types for which enc/dec must be generated - rr *rand.Rand // random generator for file-specific types + xs string // top level variable/constant suffix + hn string // fn helper type name + + ti *TypeInfos + // rr *rand.Rand // random generator for file-specific types } // Gen will write a complete go file containing Selfer implementations for each // type passed. All the types must be in the same package. -func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect.Type) { +// +// Library users: *DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.* +func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeInfos, typ ...reflect.Type) { if len(typ) == 0 { return } @@ -128,17 +163,28 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. te: make(map[uintptr]bool), td: make(map[uintptr]bool), im: make(map[string]reflect.Type), + imn: make(map[string]string), is: make(map[reflect.Type]struct{}), - ts: make(map[reflect.Type]struct{}), - bp: typ[0].PkgPath(), - rr: rand.New(rand.NewSource(time.Now().UnixNano())), + tm: make(map[reflect.Type]struct{}), + ts: []reflect.Type{}, + bp: genImportPath(typ[0]), + xs: uid, + ti: ti, //TODO: make it configurable + } + if x.ti == nil { + x.ti = defTypeInfos + } + if x.xs == "" { + rr := rand.New(rand.NewSource(time.Now().UnixNano())) + x.xs = strconv.FormatInt(rr.Int63n(9999), 10) } // gather imports first: - x.cp = reflect.TypeOf(x).PkgPath() + x.cp = genImportPath(reflect.TypeOf(x)) + x.imn[x.cp] = genCodecPkg for _, t := range typ { - // fmt.Printf("###########: PkgPath: '%v', Name: '%s'\n", t.PkgPath(), t.Name()) - if t.PkgPath() != x.bp { + // fmt.Printf("###########: PkgPath: '%v', Name: '%s'\n", genImportPath(t), t.Name()) + if genImportPath(t) != x.bp { panic(genAllTypesSamePkgErr) } x.genRefPkgs(t) @@ -162,8 +208,14 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. x.cpfx = genCodecPkg + "." x.linef("%s \"%s\"", genCodecPkg, x.cp) } + // use a sorted set of im keys, so that we can get consistent output + imKeys := make([]string, 0, len(x.im)) for k, _ := range x.im { - x.line("\"" + k + "\"") + imKeys = append(imKeys, k) + } + sort.Strings(imKeys) + for _, k := range imKeys { // for k, _ := range x.im { + x.linef("%s \"%s\"", x.imn[k], k) } // add required packages for _, k := range [...]string{"reflect", "unsafe", "runtime", "fmt", "errors"} { @@ -177,13 +229,11 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. x.line(")") x.line("") - x.xs = strconv.FormatInt(x.rr.Int63n(9999), 10) - x.line("const (") x.linef("codecSelferC_UTF8%s = %v", x.xs, int64(c_UTF8)) x.linef("codecSelferC_RAW%s = %v", x.xs, int64(c_RAW)) - x.linef("codecSelverValueTypeArray%s = %v", x.xs, int64(valueTypeArray)) - x.linef("codecSelverValueTypeMap%s = %v", x.xs, int64(valueTypeMap)) + x.linef("codecSelferValueTypeArray%s = %v", x.xs, int64(valueTypeArray)) + x.linef("codecSelferValueTypeMap%s = %v", x.xs, int64(valueTypeMap)) x.line(")") x.line("var (") x.line("codecSelferBitsize" + x.xs + " = uint8(reflect.TypeOf(uint(0)).Bits())") @@ -210,8 +260,10 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. x.linef("}") x.line("if false { // reference the types, but skip this branch at build/run time") var n int - for _, t := range x.im { - x.linef("var v%v %s", n, t.String()) + // for k, t := range x.im { + for _, k := range imKeys { + t := x.im[k] + x.linef("var v%v %s.%s", n, x.imn[k], t.Name()) n++ } if x.unsafe { @@ -239,16 +291,16 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. x.selfer(false) } - for t, _ := range x.ts { + for _, t := range x.ts { rtid := reflect.ValueOf(t).Pointer() // generate enc functions for all these slice/map types. - x.linef("func (x %s) enc%s(v %s, e *%sEncoder) {", x.hn, x.genMethodNameT(t), x.genTypeName(t), x.cpfx) + x.linef("func (x %s) enc%s(v %s%s, e *%sEncoder) {", x.hn, x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), x.cpfx) x.genRequiredMethodVars(true) switch t.Kind() { case reflect.Array, reflect.Slice, reflect.Chan: - x.encListFallback("v", rtid, t) + x.encListFallback("v", t) case reflect.Map: - x.encMapFallback("v", rtid, t) + x.encMapFallback("v", t) default: panic(genExpectArrayOrMapErr) } @@ -273,6 +325,19 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. x.line("") } +func (x *genRunner) checkForSelfer(t reflect.Type, varname string) bool { + // return varname != genTopLevelVarName && t != x.tc + // the only time we checkForSelfer is if we are not at the TOP of the generated code. + return varname != genTopLevelVarName +} + +func (x *genRunner) arr2str(t reflect.Type, s string) string { + if t.Kind() == reflect.Array { + return s + } + return "" +} + func (x *genRunner) genRequiredMethodVars(encode bool) { x.line("var h " + x.hn) if encode { @@ -287,11 +352,19 @@ func (x *genRunner) genRefPkgs(t reflect.Type) { if _, ok := x.is[t]; ok { return } - // fmt.Printf(">>>>>>: PkgPath: '%v', Name: '%s'\n", t.PkgPath(), t.Name()) + // fmt.Printf(">>>>>>: PkgPath: '%v', Name: '%s'\n", genImportPath(t), t.Name()) x.is[t] = struct{}{} - tpkg, tname := t.PkgPath(), t.Name() + tpkg, tname := genImportPath(t), t.Name() if tpkg != "" && tpkg != x.bp && tpkg != x.cp && tname != "" && tname[0] >= 'A' && tname[0] <= 'Z' { - x.im[tpkg] = t + if _, ok := x.im[tpkg]; !ok { + x.im[tpkg] = t + if idx := strings.LastIndex(tpkg, "/"); idx < 0 { + x.imn[tpkg] = tpkg + } else { + x.imc++ + x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + tpkg[idx+1:] + } + } } switch t.Kind() { case reflect.Array, reflect.Slice, reflect.Ptr, reflect.Chan: @@ -335,7 +408,65 @@ func (x *genRunner) outf(s string, params ...interface{}) { } func (x *genRunner) genTypeName(t reflect.Type) (n string) { - return genTypeName(t, x.tc) + // defer func() { fmt.Printf(">>>> ####: genTypeName: t: %v, name: '%s'\n", t, n) }() + + // if the type has a PkgPath, which doesn't match the current package, + // then include it. + // We cannot depend on t.String() because it includes current package, + // or t.PkgPath because it includes full import path, + // + var ptrPfx string + for t.Kind() == reflect.Ptr { + ptrPfx += "*" + t = t.Elem() + } + if tn := t.Name(); tn != "" { + return ptrPfx + x.genTypeNamePrim(t) + } + switch t.Kind() { + case reflect.Map: + return ptrPfx + "map[" + x.genTypeName(t.Key()) + "]" + x.genTypeName(t.Elem()) + case reflect.Slice: + return ptrPfx + "[]" + x.genTypeName(t.Elem()) + case reflect.Array: + return ptrPfx + "[" + strconv.FormatInt(int64(t.Len()), 10) + "]" + x.genTypeName(t.Elem()) + case reflect.Chan: + return ptrPfx + t.ChanDir().String() + " " + x.genTypeName(t.Elem()) + default: + if t == intfTyp { + return ptrPfx + "interface{}" + } else { + return ptrPfx + x.genTypeNamePrim(t) + } + } +} + +func (x *genRunner) genTypeNamePrim(t reflect.Type) (n string) { + if t.Name() == "" { + return t.String() + } else if genImportPath(t) == "" || genImportPath(t) == genImportPath(x.tc) { + return t.Name() + } else { + return x.imn[genImportPath(t)] + "." + t.Name() + // return t.String() // best way to get the package name inclusive + } +} + +func (x *genRunner) genZeroValueR(t reflect.Type) string { + // if t is a named type, w + switch t.Kind() { + case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func, + reflect.Slice, reflect.Map, reflect.Invalid: + return "nil" + case reflect.Bool: + return "false" + case reflect.String: + return `""` + case reflect.Struct, reflect.Array: + return x.genTypeName(t) + "{}" + default: // all numbers + return "0" + } } func (x *genRunner) genMethodNameT(t reflect.Type) (s string) { @@ -361,16 +492,16 @@ func (x *genRunner) selfer(encode bool) { if encode { x.line(") CodecEncodeSelf(e *" + x.cpfx + "Encoder) {") x.genRequiredMethodVars(true) - // x.enc("x", t) - x.encVar("x", t) + // x.enc(genTopLevelVarName, t) + x.encVar(genTopLevelVarName, t) } else { x.line(") CodecDecodeSelf(d *" + x.cpfx + "Decoder) {") x.genRequiredMethodVars(false) // do not use decVar, as there is no need to check TryDecodeAsNil // or way to elegantly handle that, and also setting it to a // non-nil value doesn't affect the pointer passed. - // x.decVar("x", t, false) - x.dec("x", t0) + // x.decVar(genTopLevelVarName, t, false) + x.dec(genTopLevelVarName, t0) } x.line("}") x.line("") @@ -384,21 +515,21 @@ func (x *genRunner) selfer(encode bool) { x.out(fnSigPfx) x.line(") codecDecodeSelfFromMap(l int, d *" + x.cpfx + "Decoder) {") x.genRequiredMethodVars(false) - x.decStructMap("x", "l", reflect.ValueOf(t0).Pointer(), t0, 0) + x.decStructMap(genTopLevelVarName, "l", reflect.ValueOf(t0).Pointer(), t0, 0) x.line("}") x.line("") } else { x.out(fnSigPfx) x.line(") codecDecodeSelfFromMapLenPrefix(l int, d *" + x.cpfx + "Decoder) {") x.genRequiredMethodVars(false) - x.decStructMap("x", "l", reflect.ValueOf(t0).Pointer(), t0, 1) + x.decStructMap(genTopLevelVarName, "l", reflect.ValueOf(t0).Pointer(), t0, 1) x.line("}") x.line("") x.out(fnSigPfx) x.line(") codecDecodeSelfFromMapCheckBreak(l int, d *" + x.cpfx + "Decoder) {") x.genRequiredMethodVars(false) - x.decStructMap("x", "l", reflect.ValueOf(t0).Pointer(), t0, 2) + x.decStructMap(genTopLevelVarName, "l", reflect.ValueOf(t0).Pointer(), t0, 2) x.line("}") x.line("") } @@ -407,24 +538,31 @@ func (x *genRunner) selfer(encode bool) { x.out(fnSigPfx) x.line(") codecDecodeSelfFromArray(l int, d *" + x.cpfx + "Decoder) {") x.genRequiredMethodVars(false) - x.decStructArray("x", "l", "return", reflect.ValueOf(t0).Pointer(), t0) + x.decStructArray(genTopLevelVarName, "l", "return", reflect.ValueOf(t0).Pointer(), t0) x.line("}") x.line("") } +// used for chan, array, slice, map func (x *genRunner) xtraSM(varname string, encode bool, t reflect.Type) { if encode { - x.linef("h.enc%s(%s(%s), e)", x.genMethodNameT(t), x.genTypeName(t), varname) + x.linef("h.enc%s((%s%s)(%s), e)", x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), varname) // x.line("h.enc" + x.genMethodNameT(t) + "(" + x.genTypeName(t) + "(" + varname + "), e)") } else { x.linef("h.dec%s((*%s)(%s), d)", x.genMethodNameT(t), x.genTypeName(t), varname) // x.line("h.dec" + x.genMethodNameT(t) + "((*" + x.genTypeName(t) + ")(" + varname + "), d)") } - x.ts[t] = struct{}{} + if _, ok := x.tm[t]; !ok { + x.tm[t] = struct{}{} + x.ts = append(x.ts, t) + } } +// encVar will encode a variable. +// The parameter, t, is the reflect.Type of the variable itself func (x *genRunner) encVar(varname string, t reflect.Type) { + // fmt.Printf(">>>>>> varname: %s, t: %v\n", varname, t) var checkNil bool switch t.Kind() { case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Chan: @@ -435,15 +573,20 @@ func (x *genRunner) encVar(varname string, t reflect.Type) { } switch t.Kind() { case reflect.Ptr: - if t.Elem().Kind() == reflect.Struct { + switch t.Elem().Kind() { + case reflect.Struct, reflect.Array: x.enc(varname, genNonPtr(t)) - } else { + default: i := x.varsfx() x.line(genTempVarPfx + i + " := *" + varname) x.enc(genTempVarPfx+i, genNonPtr(t)) } + case reflect.Struct, reflect.Array: + i := x.varsfx() + x.line(genTempVarPfx + i + " := &" + varname) + x.enc(genTempVarPfx+i, t) default: - x.enc(varname, genNonPtr(t)) + x.enc(varname, t) } if checkNil { @@ -452,47 +595,89 @@ func (x *genRunner) encVar(varname string, t reflect.Type) { } +// enc will encode a variable (varname) of type T, +// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type *T (to prevent copying) func (x *genRunner) enc(varname string, t reflect.Type) { - // varName here must be to a pointer to a struct, or to a value directly. + // varName here must be to a pointer to a struct/array, or to a value directly. rtid := reflect.ValueOf(t).Pointer() // We call CodecEncodeSelf if one of the following are honored: // - the type already implements Selfer, call that // - the type has a Selfer implementation just created, use that // - the type is in the list of the ones we will generate for, but it is not currently being generated - if t.Implements(selferTyp) { - x.line(varname + ".CodecEncodeSelf(e)") - return - } - if t.Kind() == reflect.Struct && reflect.PtrTo(t).Implements(selferTyp) { - x.line(varname + ".CodecEncodeSelf(e)") - return - } - if _, ok := x.te[rtid]; ok { - x.line(varname + ".CodecEncodeSelf(e)") - return + + tptr := reflect.PtrTo(t) + tk := t.Kind() + if x.checkForSelfer(t, varname) { + if t.Implements(selferTyp) || (tptr.Implements(selferTyp) && (tk == reflect.Array || tk == reflect.Struct)) { + x.line(varname + ".CodecEncodeSelf(e)") + return + } + + if _, ok := x.te[rtid]; ok { + x.line(varname + ".CodecEncodeSelf(e)") + return + } } inlist := false for _, t0 := range x.t { if t == t0 { inlist = true - if t != x.tc { + if x.checkForSelfer(t, varname) { x.line(varname + ".CodecEncodeSelf(e)") return } break } } + var rtidAdded bool if t == x.tc { x.te[rtid] = true rtidAdded = true } + // check if + // - type is RawExt + // - the type implements (Text|JSON|Binary)(Unm|M)arshal + mi := x.varsfx() + x.linef("%sm%s := z.EncBinary()", genTempVarPfx, mi) + x.linef("_ = %sm%s", genTempVarPfx, mi) + x.line("if false {") //start if block + defer func() { x.line("}") }() //end if block + + if t == rawExtTyp { + x.linef("} else { r.EncodeRawExt(%v, e)", varname) + return + } + // HACK: Support for Builtins. + // Currently, only Binc supports builtins, and the only builtin type is time.Time. + // Have a method that returns the rtid for time.Time if Handle is Binc. + if t == timeTyp { + vrtid := genTempVarPfx + "m" + x.varsfx() + x.linef("} else if %s := z.TimeRtidIfBinc(); %s != 0 { ", vrtid, vrtid) + x.linef("r.EncodeBuiltin(%s, %s)", vrtid, varname) + } + // only check for extensions if the type is named, and has a packagePath. + if genImportPath(t) != "" && t.Name() != "" { + // first check if extensions are configued, before doing the interface conversion + x.linef("} else if z.HasExtensions() && z.EncExt(%s) {", varname) + } + if t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) { + x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname) + } + if t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) { + x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname) + } else if t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) { + x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname) + } + + x.line("} else {") + switch t.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: x.line("r.EncodeInt(int64(" + varname + "))") - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: x.line("r.EncodeUint(uint64(" + varname + "))") case reflect.Float32: x.line("r.EncodeFloat32(float32(" + varname + "))") @@ -502,9 +687,11 @@ func (x *genRunner) enc(varname string, t reflect.Type) { x.line("r.EncodeBool(bool(" + varname + "))") case reflect.String: x.line("r.EncodeString(codecSelferC_UTF8" + x.xs + ", string(" + varname + "))") - case reflect.Array, reflect.Chan: + case reflect.Chan: x.xtraSM(varname, true, t) // x.encListFallback(varname, rtid, t) + case reflect.Array: + x.xtraSM(varname, true, t) case reflect.Slice: // if nil, call dedicated function // if a []uint8, call dedicated function @@ -515,7 +702,7 @@ func (x *genRunner) enc(varname string, t reflect.Type) { if rtid == uint8SliceTypId { x.line("r.EncodeStringBytes(codecSelferC_RAW" + x.xs + ", []byte(" + varname + "))") } else if fastpathAV.index(rtid) != -1 { - g := genV{Slice: true, Elem: x.genTypeName(t.Elem())} + g := x.newGenV(t) x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", false, e)") } else { x.xtraSM(varname, true, t) @@ -529,9 +716,7 @@ func (x *genRunner) enc(varname string, t reflect.Type) { // - else call Encoder.encode(XXX) on it. // x.line("if " + varname + " == nil { \nr.EncodeNil()\n } else { ") if fastpathAV.index(rtid) != -1 { - g := genV{Slice: false, - Elem: x.genTypeName(t.Elem()), - MapKey: x.genTypeName(t.Key())} + g := x.newGenV(t) x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", false, e)") } else { x.xtraSM(varname, true, t) @@ -556,7 +741,7 @@ func (x *genRunner) encZero(t reflect.Type) { switch t.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: x.line("r.EncodeInt(0)") - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: x.line("r.EncodeUint(0)") case reflect.Float32: x.line("r.EncodeFloat32(0)") @@ -576,24 +761,22 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { // replicate code in kStruct i.e. for each field, deref type to non-pointer, and call x.enc on it // if t === type currently running selfer on, do for all - ti := getTypeInfo(rtid, t) + ti := x.ti.get(rtid, t) i := x.varsfx() sepVarname := genTempVarPfx + "sep" + i - firstVarname := genTempVarPfx + "first" + i numfieldsvar := genTempVarPfx + "q" + i ti2arrayvar := genTempVarPfx + "r" + i struct2arrvar := genTempVarPfx + "2arr" + i x.line(sepVarname + " := !z.EncBinary()") x.linef("%s := z.EncBasicHandle().StructToArray", struct2arrvar) - x.line("var " + firstVarname + " bool") tisfi := ti.sfip // always use sequence from file. decStruct expects same thing. // due to omitEmpty, we need to calculate the // number of non-empty things we write out first. // This is required as we need to pre-determine the size of the container, // to support length-prefixing. x.linef("var %s [%v]bool", numfieldsvar, len(tisfi)) - x.linef("_, _, _, _ = %s, %s, %s, %s", sepVarname, firstVarname, numfieldsvar, struct2arrvar) + x.linef("_, _, _ = %s, %s, %s", sepVarname, numfieldsvar, struct2arrvar) x.linef("const %s bool = %v", ti2arrayvar, ti.toArray) nn := 0 for j, si := range tisfi { @@ -628,7 +811,7 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { case reflect.Map, reflect.Slice, reflect.Array, reflect.Chan: omitline += "len(" + varname + "." + t2.Name + ") != 0" default: - omitline += varname + "." + t2.Name + " != " + genZeroValueR(t2.Type, x.tc) + omitline += varname + "." + t2.Name + " != " + x.genZeroValueR(t2.Type) } x.linef("%s[%v] = %s", numfieldsvar, j, omitline) } @@ -678,11 +861,6 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { // if the type of the field is a Selfer, or one of the ones x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray - if j > 0 { - x.line("if " + sepVarname + " {") - x.line("r.EncodeArrayEntrySeparator()") - x.line("}") - } if labelUsed { x.line("if " + isNilVarName + " { r.EncodeNil() } else { ") } @@ -714,17 +892,8 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { // } // x.line(varname + "." + t2.Name + " != " + genZeroValueR(t2.Type, x.tc) + " {") } - if j == 0 { - x.linef("%s = true", firstVarname) - } else { - x.linef("if %s { r.EncodeMapEntrySeparator() } else { %s = true }", firstVarname, firstVarname) - } - // x.line("r.EncodeString(codecSelferC_UTF8" + x.xs + ", string(\"" + t2.Name + "\"))") x.line("r.EncodeString(codecSelferC_UTF8" + x.xs + ", string(\"" + si.encName + "\"))") - x.line("if " + sepVarname + " {") - x.line("r.EncodeMapKVSeparator()") - x.line("}") if labelUsed { x.line("if " + isNilVarName + " { r.EncodeNil() } else { ") x.encVar(varname+"."+t2.Name, t2.Type) @@ -738,68 +907,35 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { x.linef("} ") // end if/else ti.toArray } x.line("if " + sepVarname + " {") - x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray { - x.line("r.EncodeArrayEnd()") - x.linef("} else {") // if not ti.toArray - x.line("r.EncodeMapEnd()") - x.linef("} ") // end if/else ti.toArray + x.line("r.EncodeEnd()") x.line("}") } -func (x *genRunner) encListFallback(varname string, rtid uintptr, t reflect.Type) { +func (x *genRunner) encListFallback(varname string, t reflect.Type) { i := x.varsfx() g := genTempVarPfx x.line("r.EncodeArrayStart(len(" + varname + "))") - x.line(genTempVarPfx + "s" + i + " := !z.EncBinary()") - x.line("if " + genTempVarPfx + "s" + i + " {") - if t.Kind() == reflect.Chan { - x.linef("for %si%s, %si2%s := 0, len(%s); %si%s < %si2%s; %si%s++ {", g, i, g, i, varname, g, i, g, i, g, i) - x.linef("%sv%s := <-%s", g, i, varname) - } else { - x.linef("for %si%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname) - } - x.linef("if %si%s > 0 { r.EncodeArrayEntrySeparator() }", genTempVarPfx, i) - x.encVar(genTempVarPfx+"v"+i, t.Elem()) - x.line("}") - x.line("r.EncodeArrayEnd()") - x.line("} else {") if t.Kind() == reflect.Chan { x.linef("for %si%s, %si2%s := 0, len(%s); %si%s < %si2%s; %si%s++ {", g, i, g, i, varname, g, i, g, i, g, i) x.linef("%sv%s := <-%s", g, i, varname) } else { - x.line("for _, " + genTempVarPfx + "v" + i + " := range " + varname + " {") + // x.linef("for %si%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname) + x.linef("for _, %sv%s := range %s {", genTempVarPfx, i, varname) } x.encVar(genTempVarPfx+"v"+i, t.Elem()) x.line("}") - x.line("}") + x.line("r.EncodeEnd()") } -func (x *genRunner) encMapFallback(varname string, rtid uintptr, t reflect.Type) { +func (x *genRunner) encMapFallback(varname string, t reflect.Type) { i := x.varsfx() x.line("r.EncodeMapStart(len(" + varname + "))") - x.line(genTempVarPfx + "s" + i + " := !z.EncBinary()") - - x.line(genTempVarPfx + "j" + i + " := 0") - - x.line("if " + genTempVarPfx + "s" + i + " {") - - x.line("for " + genTempVarPfx + "k" + i + ", " + - genTempVarPfx + "v" + i + " := range " + varname + " {") - x.line("if " + genTempVarPfx + "j" + i + " > 0 { r.EncodeMapEntrySeparator() }") - x.encVar(genTempVarPfx+"k"+i, t.Key()) - x.line("r.EncodeMapKVSeparator()") - x.encVar(genTempVarPfx+"v"+i, t.Elem()) - x.line(genTempVarPfx + "j" + i + "++") - x.line("}") - x.line("r.EncodeMapEnd()") - - x.line("} else {") x.linef("for %sk%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname) + // x.line("for " + genTempVarPfx + "k" + i + ", " + genTempVarPfx + "v" + i + " := range " + varname + " {") x.encVar(genTempVarPfx+"k"+i, t.Key()) x.encVar(genTempVarPfx+"v"+i, t.Elem()) x.line("}") - - x.line("}") + x.line("r.EncodeEnd()") } func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) { @@ -825,7 +961,7 @@ func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) { if strings.IndexByte(varname, '.') != -1 { x.line(varname + " = nil") } else { - x.line("*" + varname + " = " + genZeroValueR(t.Elem(), x.tc)) + x.line("*" + varname + " = " + x.genZeroValueR(t.Elem())) } // x.line("*" + varname + " = nil") x.line("}") @@ -833,7 +969,7 @@ func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) { } else { // x.line("var " + genTempVarPfx + i + " " + x.genTypeName(t)) // x.line(varname + " = " + genTempVarPfx + i) - x.line(varname + " = " + genZeroValueR(t, x.tc)) + x.line(varname + " = " + x.genZeroValueR(t)) } x.line("} else {") } else { @@ -878,35 +1014,77 @@ func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) { func (x *genRunner) dec(varname string, t reflect.Type) { // assumptions: // - the varname is to a pointer already. No need to take address of it - + // - t is always a baseType T (not a *T, etc). rtid := reflect.ValueOf(t).Pointer() - if t.Implements(selferTyp) || (t.Kind() == reflect.Struct && - reflect.PtrTo(t).Implements(selferTyp)) { - x.line(varname + ".CodecDecodeSelf(d)") - return - } - if _, ok := x.td[rtid]; ok { - x.line(varname + ".CodecDecodeSelf(d)") - return + tptr := reflect.PtrTo(t) + if x.checkForSelfer(t, varname) { + if t.Implements(selferTyp) || tptr.Implements(selferTyp) { + x.line(varname + ".CodecDecodeSelf(d)") + return + } + if _, ok := x.td[rtid]; ok { + x.line(varname + ".CodecDecodeSelf(d)") + return + } } inlist := false for _, t0 := range x.t { if t == t0 { inlist = true - if t != x.tc { + if x.checkForSelfer(t, varname) { x.line(varname + ".CodecDecodeSelf(d)") return } break } } + var rtidAdded bool if t == x.tc { x.td[rtid] = true rtidAdded = true } + // check if + // - type is RawExt + // - the type implements (Text|JSON|Binary)(Unm|M)arshal + mi := x.varsfx() + x.linef("%sm%s := z.DecBinary()", genTempVarPfx, mi) + x.linef("_ = %sm%s", genTempVarPfx, mi) + x.line("if false {") //start if block + defer func() { x.line("}") }() //end if block + + if t == rawExtTyp { + x.linef("} else { r.DecodeExt(%v, 0, nil)", varname) + return + } + + // HACK: Support for Builtins. + // Currently, only Binc supports builtins, and the only builtin type is time.Time. + // Have a method that returns the rtid for time.Time if Handle is Binc. + if t == timeTyp { + vrtid := genTempVarPfx + "m" + x.varsfx() + x.linef("} else if %s := z.TimeRtidIfBinc(); %s != 0 { ", vrtid, vrtid) + x.linef("r.DecodeBuiltin(%s, %s)", vrtid, varname) + } + // only check for extensions if the type is named, and has a packagePath. + if genImportPath(t) != "" && t.Name() != "" { + // first check if extensions are configued, before doing the interface conversion + x.linef("} else if z.HasExtensions() && z.DecExt(%s) {", varname) + } + + if t.Implements(binaryUnmarshalerTyp) || tptr.Implements(binaryUnmarshalerTyp) { + x.linef("} else if %sm%s { z.DecBinaryUnmarshal(%v) ", genTempVarPfx, mi, varname) + } + if t.Implements(jsonUnmarshalerTyp) || tptr.Implements(jsonUnmarshalerTyp) { + x.linef("} else if !%sm%s && z.IsJSONHandle() { z.DecJSONUnmarshal(%v)", genTempVarPfx, mi, varname) + } else if t.Implements(textUnmarshalerTyp) || tptr.Implements(textUnmarshalerTyp) { + x.linef("} else if !%sm%s { z.DecTextUnmarshal(%v)", genTempVarPfx, mi, varname) + } + + x.line("} else {") + // Since these are pointers, we cannot share, and have to use them one by one switch t.Kind() { case reflect.Int: @@ -940,6 +1118,8 @@ func (x *genRunner) dec(varname string, t reflect.Type) { case reflect.Uint64: x.line("*((*uint64)(" + varname + ")) = uint64(r.DecodeUint(64))") //x.line("z.DecUint64((*uint64)(" + varname + "))") + case reflect.Uintptr: + x.line("*((*uintptr)(" + varname + ")) = uintptr(r.DecodeUint(codecSelferBitsize" + x.xs + "))") case reflect.Float32: x.line("*((*float32)(" + varname + ")) = float32(r.DecodeFloat(true))") @@ -966,7 +1146,7 @@ func (x *genRunner) dec(varname string, t reflect.Type) { if rtid == uint8SliceTypId { x.line("*" + varname + " = r.DecodeBytes(*(*[]byte)(" + varname + "), false, false)") } else if fastpathAV.index(rtid) != -1 { - g := genV{Slice: true, Elem: x.genTypeName(t.Elem())} + g := x.newGenV(t) x.line("z.F." + g.MethodNamePfx("Dec", false) + "X(" + varname + ", false, d)") // x.line("z." + g.MethodNamePfx("Dec", false) + "(" + varname + ")") // x.line(g.FastpathName(false) + "(" + varname + ", d)") @@ -980,7 +1160,7 @@ func (x *genRunner) dec(varname string, t reflect.Type) { // - if elements are primitives or Selfers, call dedicated function on each member. // - else call Encoder.encode(XXX) on it. if fastpathAV.index(rtid) != -1 { - g := genV{Slice: false, Elem: x.genTypeName(t.Elem()), MapKey: x.genTypeName(t.Key())} + g := x.newGenV(t) x.line("z.F." + g.MethodNamePfx("Dec", false) + "X(" + varname + ", false, d)") // x.line("z." + g.MethodNamePfx("Dec", false) + "(" + varname + ")") // x.line(g.FastpathName(false) + "(" + varname + ", d)") @@ -1018,10 +1198,10 @@ func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type) (tryAs // Consequently, we replace: // case reflect.Uint32: x.line(varname + " = uint32(r.DecodeUint(32))") // with: - // case reflect.Uint32: x.line(varname + " = " + genTypeNamePrimitiveKind(t, x.tc) + "(r.DecodeUint(32))") + // case reflect.Uint32: x.line(varname + " = " + genTypeNamePrim(t, x.tc) + "(r.DecodeUint(32))") xfn := func(t reflect.Type) string { - return genTypeNamePrimitiveKind(t, x.tc) + return x.genTypeNamePrim(t) } switch t.Kind() { case reflect.Int: @@ -1045,6 +1225,8 @@ func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type) (tryAs x.linef("%s = %s(r.DecodeUint(32))", varname, xfn(t)) case reflect.Uint64: x.linef("%s = %s(r.DecodeUint(64))", varname, xfn(t)) + case reflect.Uintptr: + x.linef("%s = %s(r.DecodeUint(codecSelferBitsize%s))", varname, xfn(t), x.xs) case reflect.Float32: x.linef("%s = %s(r.DecodeFloat(true))", varname, xfn(t)) @@ -1069,11 +1251,13 @@ func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type CTyp string Typ string Immutable bool + Size int } telem := t.Elem() - ts := tstruc{genTempVarPfx, x.varsfx(), varname, x.genTypeName(t), x.genTypeName(telem), genIsImmutable(telem)} + ts := tstruc{genTempVarPfx, x.varsfx(), varname, x.genTypeName(t), x.genTypeName(telem), genIsImmutable(telem), int(telem.Size())} funcs := make(template.FuncMap) + funcs["decLineVar"] = func(varname string) string { x.decVar(varname, telem, false) return "" @@ -1086,7 +1270,7 @@ func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type return ts.TempVar + s + ts.Rand } funcs["zero"] = func() string { - return genZeroValueR(telem, x.tc) + return x.genZeroValueR(telem) } funcs["isArray"] = func() bool { return t.Kind() == reflect.Array @@ -1113,10 +1297,11 @@ func (x *genRunner) decMapFallback(varname string, rtid uintptr, t reflect.Type) Varname string KTyp string Typ string + Size int } telem := t.Elem() tkey := t.Key() - ts := tstruc{genTempVarPfx, x.varsfx(), varname, x.genTypeName(tkey), x.genTypeName(telem)} + ts := tstruc{genTempVarPfx, x.varsfx(), varname, x.genTypeName(tkey), x.genTypeName(telem), int(telem.Size() + tkey.Size())} funcs := make(template.FuncMap) funcs["decLineVarK"] = func(varname string) string { x.decVar(varname, tkey, false) @@ -1148,7 +1333,7 @@ func (x *genRunner) decMapFallback(varname string, rtid uintptr, t reflect.Type) } func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintptr, t reflect.Type) { - ti := getTypeInfo(rtid, t) + ti := x.ti.get(rtid, t) tisfi := ti.sfip // always use sequence from file. decStruct expects same thing. x.line("switch (" + kName + ") {") for _, si := range tisfi { @@ -1213,13 +1398,11 @@ func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t ref x.linef("for %sj%s := 0; %sj%s < %s; %sj%s++ {", tpfx, i, tpfx, i, lenvarname, tpfx, i) case 2: x.linef("for %sj%s := 0; !r.CheckBreak(); %sj%s++ {", tpfx, i, tpfx, i) - x.linef("if %sj%s > 0 { r.ReadMapEntrySeparator() }", tpfx, i) default: // 0, otherwise. x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length x.linef("for %sj%s := 0; ; %sj%s++ {", tpfx, i, tpfx, i) x.linef("if %shl%s { if %sj%s >= %s { break }", tpfx, i, tpfx, i, lenvarname) - x.linef("} else { if r.CheckBreak() { break }; if %sj%s > 0 { r.ReadMapEntrySeparator() } }", - tpfx, i) + x.line("} else { if r.CheckBreak() { break }; }") } // x.line(kName + " = z.ReadStringAsBytes(" + kName + ")") // x.line(kName + " = z.ReadString()") @@ -1233,35 +1416,28 @@ func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t ref } else { x.line(kName + " := string(" + kName + "Slc)") } - switch style { - case 1: - case 2: - x.line("r.ReadMapKVSeparator()") - default: - x.linef("if !%shl%s { r.ReadMapKVSeparator() }", tpfx, i) - } x.decStructMapSwitch(kName, varname, rtid, t) x.line("} // end for " + tpfx + "j" + i) switch style { case 1: case 2: - x.line("r.ReadMapEnd()") + x.line("r.ReadEnd()") default: - x.linef("if !%shl%s { r.ReadMapEnd() }", tpfx, i) + x.linef("if !%shl%s { r.ReadEnd() }", tpfx, i) } } func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid uintptr, t reflect.Type) { tpfx := genTempVarPfx i := x.varsfx() - ti := getTypeInfo(rtid, t) + ti := x.ti.get(rtid, t) tisfi := ti.sfip // always use sequence from file. decStruct expects same thing. x.linef("var %sj%s int", tpfx, i) x.linef("var %sb%s bool", tpfx, i) // break // x.linef("var %sl%s := r.ReadArrayStart()", tpfx, i) x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length - for j, si := range tisfi { + for _, si := range tisfi { var t2 reflect.StructField if si.i != -1 { t2 = t.Field(int(si.i)) @@ -1274,10 +1450,7 @@ func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid tpfx, i, lenvarname, tpfx, i) // x.line("if " + tpfx + "j" + i + "++; " + tpfx + "j" + // i + " <= " + tpfx + "l" + i + " {") - x.linef("if %sb%s { r.ReadArrayEnd(); %s }", tpfx, i, breakString) - if j > 0 { - x.line("r.ReadArrayEntrySeparator()") - } + x.linef("if %sb%s { r.ReadEnd(); %s }", tpfx, i, breakString) x.decVar(varname+"."+t2.Name, t2.Type, true) // x.line("} // end if " + tpfx + "j" + i + " <= " + tpfx + "l" + i) } @@ -1287,20 +1460,19 @@ func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid tpfx, i, tpfx, i, tpfx, i, tpfx, i, lenvarname, tpfx, i) x.linef("if %sb%s { break }", tpfx, i) - x.linef("if %sj%s > 1 { r.ReadArrayEntrySeparator() }", tpfx, i) x.linef(`z.DecStructFieldNotFound(%sj%s - 1, "")`, tpfx, i) x.line("}") - x.line("r.ReadArrayEnd()") + x.line("r.ReadEnd()") } func (x *genRunner) decStruct(varname string, rtid uintptr, t reflect.Type) { // if container is map // x.line("if z.DecContainerIsMap() { ") i := x.varsfx() - x.line("if r.IsContainerType(codecSelverValueTypeMap" + x.xs + ") {") + x.line("if r.IsContainerType(codecSelferValueTypeMap" + x.xs + ") {") x.line(genTempVarPfx + "l" + i + " := r.ReadMapStart()") x.linef("if %sl%s == 0 {", genTempVarPfx, i) - x.line("r.ReadMapEnd()") + x.line("r.ReadEnd()") if genUseOneFunctionForDecStructMap { x.line("} else { ") x.linef("x.codecDecodeSelfFromMap(%sl%s, d)", genTempVarPfx, i) @@ -1314,10 +1486,10 @@ func (x *genRunner) decStruct(varname string, rtid uintptr, t reflect.Type) { // else if container is array // x.line("} else if z.DecContainerIsArray() { ") - x.line("} else if r.IsContainerType(codecSelverValueTypeArray" + x.xs + ") {") + x.line("} else if r.IsContainerType(codecSelferValueTypeArray" + x.xs + ") {") x.line(genTempVarPfx + "l" + i + " := r.ReadArrayStart()") x.linef("if %sl%s == 0 {", genTempVarPfx, i) - x.line("r.ReadArrayEnd()") + x.line("r.ReadEnd()") x.line("} else { ") x.linef("x.codecDecodeSelfFromArray(%sl%s, d)", genTempVarPfx, i) x.line("}") @@ -1331,11 +1503,28 @@ func (x *genRunner) decStruct(varname string, rtid uintptr, t reflect.Type) { // -------- type genV struct { - // genV is either a primitive (Primitive != "") or a slice (Slice = true) or a map. - Slice bool + // genV is either a primitive (Primitive != "") or a map (MapKey != "") or a slice MapKey string Elem string Primitive string + Size int +} + +func (x *genRunner) newGenV(t reflect.Type) (v genV) { + switch t.Kind() { + case reflect.Slice, reflect.Array: + te := t.Elem() + v.Elem = x.genTypeName(te) + v.Size = int(te.Size()) + case reflect.Map: + te, tk := t.Elem(), t.Key() + v.Elem = x.genTypeName(te) + v.MapKey = x.genTypeName(tk) + v.Size = int(te.Size() + tk.Size()) + default: + panic("unexpected type for newGenV. Requires map or slice type") + } + return } func (x *genV) MethodNamePfx(prefix string, prim bool) string { @@ -1346,7 +1535,7 @@ func (x *genV) MethodNamePfx(prefix string, prim bool) string { if prim { name = append(name, genTitleCaseName(x.Primitive)...) } else { - if x.Slice { + if x.MapKey == "" { name = append(name, "Slice"...) } else { name = append(name, "Map"...) @@ -1358,6 +1547,29 @@ func (x *genV) MethodNamePfx(prefix string, prim bool) string { } +var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") == "1" + +// genImportPath returns import path of a non-predeclared named typed, or an empty string otherwise. +// +// This handles the misbehaviour that occurs when 1.5-style vendoring is enabled, +// where PkgPath returns the full path, including the vendoring pre-fix that should have been stripped. +// We strip it here. +func genImportPath(t reflect.Type) (s string) { + s = t.PkgPath() + if genCheckVendor { + // HACK: Misbehaviour occurs in go 1.5. May have to re-visit this later. + // if s contains /vendor/ OR startsWith vendor/, then return everything after it. + const vendorStart = "vendor/" + const vendorInline = "/vendor/" + if i := strings.LastIndex(s, vendorInline); i >= 0 { + s = s[i+len(vendorInline):] + } else if strings.HasPrefix(s, vendorStart) { + s = s[len(vendorStart):] + } + } + return +} + func genNonPtr(t reflect.Type) reflect.Type { for t.Kind() == reflect.Ptr { t = t.Elem() @@ -1374,59 +1586,17 @@ func genTitleCaseName(s string) string { } } -func genTypeNamePrimitiveKind(t reflect.Type, tRef reflect.Type) (n string) { - if tRef != nil && t.PkgPath() == tRef.PkgPath() && t.Name() != "" { - return t.Name() - } else { - return t.String() // best way to get the package name inclusive - } -} - -func genTypeName(t reflect.Type, tRef reflect.Type) (n string) { - // defer func() { fmt.Printf(">>>> ####: genTypeName: t: %v, name: '%s'\n", t, n) }() - - // if the type has a PkgPath, which doesn't match the current package, - // then include it. - // We cannot depend on t.String() because it includes current package, - // or t.PkgPath because it includes full import path, - // - var ptrPfx string - for t.Kind() == reflect.Ptr { - ptrPfx += "*" - t = t.Elem() - } - if tn := t.Name(); tn != "" { - return ptrPfx + genTypeNamePrimitiveKind(t, tRef) - } - switch t.Kind() { - case reflect.Map: - return ptrPfx + "map[" + genTypeName(t.Key(), tRef) + "]" + genTypeName(t.Elem(), tRef) - case reflect.Slice: - return ptrPfx + "[]" + genTypeName(t.Elem(), tRef) - case reflect.Array: - return ptrPfx + "[" + strconv.FormatInt(int64(t.Len()), 10) + "]" + genTypeName(t.Elem(), tRef) - case reflect.Chan: - return ptrPfx + t.ChanDir().String() + " " + genTypeName(t.Elem(), tRef) - default: - if t == intfTyp { - return ptrPfx + "interface{}" - } else { - return ptrPfx + genTypeNamePrimitiveKind(t, tRef) - } - } -} - func genMethodNameT(t reflect.Type, tRef reflect.Type) (n string) { var ptrPfx string for t.Kind() == reflect.Ptr { ptrPfx += "Ptrto" t = t.Elem() } + tstr := t.String() if tn := t.Name(); tn != "" { - if tRef != nil && t.PkgPath() == tRef.PkgPath() { + if tRef != nil && genImportPath(t) == genImportPath(tRef) { return ptrPfx + tn } else { - tstr := t.String() if genQNameRegex.MatchString(tstr) { return ptrPfx + strings.Replace(tstr, ".", "_", 1000) } else { @@ -1456,17 +1626,16 @@ func genMethodNameT(t reflect.Type, tRef reflect.Type) (n string) { if t == intfTyp { return ptrPfx + "Interface" } else { - if tRef != nil && t.PkgPath() == tRef.PkgPath() { + if tRef != nil && genImportPath(t) == genImportPath(tRef) { if t.Name() != "" { return ptrPfx + t.Name() } else { - return ptrPfx + genCustomTypeName(t.String()) + return ptrPfx + genCustomTypeName(tstr) } } else { // best way to get the package name inclusive - // return ptrPfx + strings.Replace(t.String(), ".", "_", 1000) - // return ptrPfx + genBase64enc.EncodeToString([]byte(t.String())) - tstr := t.String() + // return ptrPfx + strings.Replace(tstr, ".", "_", 1000) + // return ptrPfx + genBase64enc.EncodeToString([]byte(tstr)) if t.Name() != "" && genQNameRegex.MatchString(tstr) { return ptrPfx + strings.Replace(tstr, ".", "_", 1000) } else { @@ -1494,24 +1663,7 @@ func genCustomTypeName(tstr string) string { } func genIsImmutable(t reflect.Type) (v bool) { - return isMutableKind(t.Kind()) -} - -func genZeroValueR(t reflect.Type, tRef reflect.Type) string { - // if t is a named type, w - switch t.Kind() { - case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func, - reflect.Slice, reflect.Map, reflect.Invalid: - return "nil" - case reflect.Bool: - return "false" - case reflect.String: - return `""` - case reflect.Struct, reflect.Array: - return genTypeName(t, tRef) + "{}" - default: // all numbers - return "0" - } + return isImmutableKind(t.Kind()) } type genInternal struct { @@ -1641,23 +1793,42 @@ func genInternalInit() { "float64", "bool", } - mapvaltypes2 := make(map[string]bool) - for _, s := range mapvaltypes { - mapvaltypes2[s] = true - } + wordSizeBytes := int(intBitsize) / 8 + + mapvaltypes2 := map[string]int{ + "interface{}": 2 * wordSizeBytes, + "string": 2 * wordSizeBytes, + "uint": 1 * wordSizeBytes, + "uint8": 1, + "uint16": 2, + "uint32": 4, + "uint64": 8, + "int": 1 * wordSizeBytes, + "int8": 1, + "int16": 2, + "int32": 4, + "int64": 8, + "float32": 4, + "float64": 8, + "bool": 1, + } + // mapvaltypes2 := make(map[string]bool) + // for _, s := range mapvaltypes { + // mapvaltypes2[s] = true + // } var gt genInternal // For each slice or map type, there must be a (symetrical) Encode and Decode fast-path function for _, s := range types { - gt.Values = append(gt.Values, genV{false, "", "", s}) + gt.Values = append(gt.Values, genV{Primitive: s, Size: mapvaltypes2[s]}) if s != "uint8" { // do not generate fast path for slice of bytes. Treat specially already. - gt.Values = append(gt.Values, genV{true, "", s, ""}) + gt.Values = append(gt.Values, genV{Elem: s, Size: mapvaltypes2[s]}) } - if !mapvaltypes2[s] { - gt.Values = append(gt.Values, genV{false, s, s, ""}) + if _, ok := mapvaltypes2[s]; !ok { + gt.Values = append(gt.Values, genV{MapKey: s, Elem: s, Size: 2 * mapvaltypes2[s]}) } for _, ms := range mapvaltypes { - gt.Values = append(gt.Values, genV{false, s, ms, ""}) + gt.Values = append(gt.Values, genV{MapKey: s, Elem: ms, Size: mapvaltypes2[s] + mapvaltypes2[ms]}) } } diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper.go index 945b4c4987cf..9c00ba562d73 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec @@ -117,6 +117,7 @@ import ( const ( scratchByteArrayLen = 32 + initCollectionCap = 32 // 32 is defensive. 16 is preferred. // Support encoding.(Binary|Text)(Unm|M)arshaler. // This constant flag will enable or disable it. @@ -147,6 +148,12 @@ const ( // if derefForIsEmptyValue, deref pointers and interfaces when checking isEmptyValue derefForIsEmptyValue = false + + // if resetSliceElemToZeroValue, then on decoding a slice, reset the element to a zero value first. + // Only concern is that, if the slice already contained some garbage, we will decode into that garbage. + // The chances of this are slim, so leave this "optimization". + // TODO: should this be true, to ensure that we always decode into a "zero" "empty" value? + resetSliceElemToZeroValue bool = false ) var oneByteArr = [1]byte{0} @@ -186,6 +193,14 @@ const ( type seqType uint8 +// mirror json.Marshaler and json.Unmarshaler here, so we don't import the encoding/json package +type jsonMarshaler interface { + MarshalJSON() ([]byte, error) +} +type jsonUnmarshaler interface { + UnmarshalJSON([]byte) error +} + const ( _ seqType = iota seqTypeArray @@ -197,9 +212,6 @@ var ( bigen = binary.BigEndian structInfoFieldName = "_struct" - cachedTypeInfo = make(map[uintptr]*typeInfo, 64) - cachedTypeInfoMutex sync.RWMutex - // mapStrIntfTyp = reflect.TypeOf(map[string]interface{}(nil)) intfSliceTyp = reflect.TypeOf([]interface{}(nil)) intfTyp = intfSliceTyp.Elem() @@ -217,6 +229,9 @@ var ( textMarshalerTyp = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() textUnmarshalerTyp = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() + jsonMarshalerTyp = reflect.TypeOf((*jsonMarshaler)(nil)).Elem() + jsonUnmarshalerTyp = reflect.TypeOf((*jsonUnmarshaler)(nil)).Elem() + selferTyp = reflect.TypeOf((*Selfer)(nil)).Elem() uint8SliceTypId = reflect.ValueOf(uint8SliceTyp).Pointer() @@ -238,6 +253,8 @@ var ( noFieldNameToStructFieldInfoErr = errors.New("no field name passed to parseStructFieldInfo") ) +var defTypeInfos = NewTypeInfos([]string{"codec", "json"}) + // Selfer defines methods by which a value can encode or decode itself. // // Any type which implements Selfer will be able to encode or decode itself. @@ -263,6 +280,11 @@ type MapBySlice interface { // // BasicHandle encapsulates the common options and extension functions. type BasicHandle struct { + // TypeInfos is used to get the type info for any type. + // + // If not configure, the default TypeInfos is used, which uses struct tag keys: codec, json + TypeInfos *TypeInfos + extHandle EncodeOptions DecodeOptions @@ -272,6 +294,13 @@ func (x *BasicHandle) getBasicHandle() *BasicHandle { return x } +func (x *BasicHandle) getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) { + if x.TypeInfos != nil { + return x.TypeInfos.get(rtid, rt) + } + return defTypeInfos.get(rtid, rt) +} + // Handle is the interface for a specific encoding format. // // Typically, a Handle is pre-configured before first time use, @@ -298,32 +327,41 @@ type RawExt struct { Value interface{} } -// Ext handles custom (de)serialization of custom types / extensions. -type Ext interface { +// BytesExt handles custom (de)serialization of types to/from []byte. +// It is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of the types. +type BytesExt interface { // WriteExt converts a value to a []byte. - // It is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of the types. WriteExt(v interface{}) []byte // ReadExt updates a value from a []byte. - // It is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of the types. ReadExt(dst interface{}, src []byte) +} +// InterfaceExt handles custom (de)serialization of types to/from another interface{} value. +// The Encoder or Decoder will then handle the further (de)serialization of that known type. +// +// It is used by codecs (e.g. cbor, json) which use the format to do custom serialization of the types. +type InterfaceExt interface { // ConvertExt converts a value into a simpler interface for easy encoding e.g. convert time.Time to int64. - // It is used by codecs (e.g. cbor) which use the format to do custom serialization of the types. ConvertExt(v interface{}) interface{} // UpdateExt updates a value from a simpler interface for easy decoding e.g. convert int64 to time.Time. - // It is used by codecs (e.g. cbor) which use the format to do custom serialization of the types. UpdateExt(dst interface{}, src interface{}) } -// bytesExt is a wrapper implementation to support former AddExt exported method. -type bytesExt struct { +// Ext handles custom (de)serialization of custom types / extensions. +type Ext interface { + BytesExt + InterfaceExt +} + +// addExtWrapper is a wrapper implementation to support former AddExt exported method. +type addExtWrapper struct { encFn func(reflect.Value) ([]byte, error) decFn func(reflect.Value, []byte) error } -func (x bytesExt) WriteExt(v interface{}) []byte { +func (x addExtWrapper) WriteExt(v interface{}) []byte { // fmt.Printf(">>>>>>>>>> WriteExt: %T, %v\n", v, v) bs, err := x.encFn(reflect.ValueOf(v)) if err != nil { @@ -332,21 +370,57 @@ func (x bytesExt) WriteExt(v interface{}) []byte { return bs } -func (x bytesExt) ReadExt(v interface{}, bs []byte) { +func (x addExtWrapper) ReadExt(v interface{}, bs []byte) { // fmt.Printf(">>>>>>>>>> ReadExt: %T, %v\n", v, v) if err := x.decFn(reflect.ValueOf(v), bs); err != nil { panic(err) } } -func (x bytesExt) ConvertExt(v interface{}) interface{} { +func (x addExtWrapper) ConvertExt(v interface{}) interface{} { return x.WriteExt(v) } -func (x bytesExt) UpdateExt(dest interface{}, v interface{}) { +func (x addExtWrapper) UpdateExt(dest interface{}, v interface{}) { x.ReadExt(dest, v.([]byte)) } +type setExtWrapper struct { + b BytesExt + i InterfaceExt +} + +func (x *setExtWrapper) WriteExt(v interface{}) []byte { + if x.b == nil { + panic("BytesExt.WriteExt is not supported") + } + return x.b.WriteExt(v) +} + +func (x *setExtWrapper) ReadExt(v interface{}, bs []byte) { + if x.b == nil { + panic("BytesExt.WriteExt is not supported") + + } + x.b.ReadExt(v, bs) +} + +func (x *setExtWrapper) ConvertExt(v interface{}) interface{} { + if x.i == nil { + panic("InterfaceExt.ConvertExt is not supported") + + } + return x.i.ConvertExt(v) +} + +func (x *setExtWrapper) UpdateExt(dest interface{}, v interface{}) { + if x.i == nil { + panic("InterfaceExxt.UpdateExt is not supported") + + } + x.i.UpdateExt(dest, v) +} + // type errorString string // func (x errorString) Error() string { return string(x) } @@ -401,7 +475,7 @@ type extTypeTagFn struct { type extHandle []*extTypeTagFn -// DEPRECATED: AddExt is deprecated in favor of SetExt. It exists for compatibility only. +// DEPRECATED: Use SetBytesExt or SetInterfaceExt on the Handle instead. // // AddExt registes an encode and decode function for a reflect.Type. // AddExt internally calls SetExt. @@ -413,10 +487,10 @@ func (o *extHandle) AddExt( if encfn == nil || decfn == nil { return o.SetExt(rt, uint64(tag), nil) } - return o.SetExt(rt, uint64(tag), bytesExt{encfn, decfn}) + return o.SetExt(rt, uint64(tag), addExtWrapper{encfn, decfn}) } -// SetExt registers a tag and Ext for a reflect.Type. +// DEPRECATED: Use SetBytesExt or SetInterfaceExt on the Handle instead. // // Note that the type must be a named type, and specifically not // a pointer or Interface. An error is returned if that is not honored. @@ -471,6 +545,10 @@ type structFieldInfo struct { toArray bool // if field is _struct, is the toArray set? } +// func (si *structFieldInfo) isZero() bool { +// return si.encName == "" && len(si.is) == 0 && si.i == 0 && !si.omitEmpty && !si.toArray +// } + // rv returns the field of the struct. // If anonymous, it returns an Invalid func (si *structFieldInfo) field(v reflect.Value, update bool) (rv2 reflect.Value) { @@ -516,9 +594,9 @@ func (si *structFieldInfo) setToZeroValue(v reflect.Value) { } func parseStructFieldInfo(fname string, stag string) *structFieldInfo { - if fname == "" { - panic(noFieldNameToStructFieldInfoErr) - } + // if fname == "" { + // panic(noFieldNameToStructFieldInfoErr) + // } si := structFieldInfo{ encName: fname, } @@ -589,6 +667,11 @@ type typeInfo struct { tmIndir int8 // number of indirections to get to textMarshaler type tunmIndir int8 // number of indirections to get to textUnmarshaler type + jm bool // base type (T or *T) is a jsonMarshaler + junm bool // base type (T or *T) is a jsonUnmarshaler + jmIndir int8 // number of indirections to get to jsonMarshaler type + junmIndir int8 // number of indirections to get to jsonUnmarshaler type + cs bool // base type (T or *T) is a Selfer csIndir int8 // number of indirections to get to Selfer type @@ -623,28 +706,48 @@ func (ti *typeInfo) indexForEncName(name string) int { return -1 } -func getStructTag(t reflect.StructTag) (s string) { +// TypeInfos caches typeInfo for each type on first inspection. +// +// It is configured with a set of tag keys, which are used to get +// configuration for the type. +type TypeInfos struct { + infos map[uintptr]*typeInfo + mu sync.RWMutex + tags []string +} + +// NewTypeInfos creates a TypeInfos given a set of struct tags keys. +// +// This allows users customize the struct tag keys which contain configuration +// of their types. +func NewTypeInfos(tags []string) *TypeInfos { + return &TypeInfos{tags: tags, infos: make(map[uintptr]*typeInfo, 64)} +} + +func (x *TypeInfos) structTag(t reflect.StructTag) (s string) { // check for tags: codec, json, in that order. // this allows seamless support for many configured structs. - s = t.Get("codec") - if s == "" { - s = t.Get("json") + for _, x := range x.tags { + s = t.Get(x) + if s != "" { + return s + } } return } -func getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) { +func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) { var ok bool - cachedTypeInfoMutex.RLock() - pti, ok = cachedTypeInfo[rtid] - cachedTypeInfoMutex.RUnlock() + x.mu.RLock() + pti, ok = x.infos[rtid] + x.mu.RUnlock() if ok { return } - cachedTypeInfoMutex.Lock() - defer cachedTypeInfoMutex.Unlock() - if pti, ok = cachedTypeInfo[rtid]; ok { + x.mu.Lock() + defer x.mu.Unlock() + if pti, ok = x.infos[rtid]; ok { return } @@ -664,6 +767,12 @@ func getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) { if ok, indir = implementsIntf(rt, textUnmarshalerTyp); ok { ti.tunm, ti.tunmIndir = true, indir } + if ok, indir = implementsIntf(rt, jsonMarshalerTyp); ok { + ti.jm, ti.jmIndir = true, indir + } + if ok, indir = implementsIntf(rt, jsonUnmarshalerTyp); ok { + ti.junm, ti.junmIndir = true, indir + } if ok, indir = implementsIntf(rt, selferTyp); ok { ti.cs, ti.csIndir = true, indir } @@ -690,11 +799,11 @@ func getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) { if rt.Kind() == reflect.Struct { var siInfo *structFieldInfo if f, ok := rt.FieldByName(structInfoFieldName); ok { - siInfo = parseStructFieldInfo(structInfoFieldName, getStructTag(f.Tag)) + siInfo = parseStructFieldInfo(structInfoFieldName, x.structTag(f.Tag)) ti.toArray = siInfo.toArray } sfip := make([]*structFieldInfo, 0, rt.NumField()) - rgetTypeInfo(rt, nil, make(map[string]bool, 16), &sfip, siInfo) + x.rget(rt, nil, make(map[string]bool, 16), &sfip, siInfo) ti.sfip = make([]*structFieldInfo, len(sfip)) ti.sfi = make([]*structFieldInfo, len(sfip)) @@ -703,11 +812,11 @@ func getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) { copy(ti.sfi, sfip) } // sfi = sfip - cachedTypeInfo[rtid] = pti + x.infos[rtid] = pti return } -func rgetTypeInfo(rt reflect.Type, indexstack []int, fnameToHastag map[string]bool, +func (x *TypeInfos) rget(rt reflect.Type, indexstack []int, fnameToHastag map[string]bool, sfi *[]*structFieldInfo, siInfo *structFieldInfo, ) { for j := 0; j < rt.NumField(); j++ { @@ -716,15 +825,28 @@ func rgetTypeInfo(rt reflect.Type, indexstack []int, fnameToHastag map[string]bo if tk := f.Type.Kind(); tk == reflect.Func { continue } - stag := getStructTag(f.Tag) + stag := x.structTag(f.Tag) if stag == "-" { continue } if r1, _ := utf8.DecodeRuneInString(f.Name); r1 == utf8.RuneError || !unicode.IsUpper(r1) { continue } - // if anonymous and there is no struct tag and its a struct (or pointer to struct), inline it. - if f.Anonymous && stag == "" { + var si *structFieldInfo + // if anonymous and there is no struct tag (or it's blank) + // and its a struct (or pointer to struct), inline it. + var doInline bool + if f.Anonymous && f.Type.Kind() != reflect.Interface { + doInline = stag == "" + if !doInline { + si = parseStructFieldInfo("", stag) + doInline = si.encName == "" + // doInline = si.isZero() + // fmt.Printf(">>>> doInline for si.isZero: %s: %v\n", f.Name, doInline) + } + } + + if doInline { ft := f.Type for ft.Kind() == reflect.Ptr { ft = ft.Elem() @@ -734,7 +856,7 @@ func rgetTypeInfo(rt reflect.Type, indexstack []int, fnameToHastag map[string]bo copy(indexstack2, indexstack) indexstack2[len(indexstack)] = j // indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) - rgetTypeInfo(ft, indexstack2, fnameToHastag, sfi, siInfo) + x.rget(ft, indexstack2, fnameToHastag, sfi, siInfo) continue } } @@ -744,7 +866,14 @@ func rgetTypeInfo(rt reflect.Type, indexstack []int, fnameToHastag map[string]bo if _, ok := fnameToHastag[f.Name]; ok { continue } - si := parseStructFieldInfo(f.Name, stag) + if f.Name == "" { + panic(noFieldNameToStructFieldInfoErr) + } + if si == nil { + si = parseStructFieldInfo(f.Name, stag) + } else if si.encName == "" { + si.encName = f.Name + } // si.ikind = int(f.Type.Kind()) if len(indexstack) == 0 { si.i = int16(j) @@ -779,8 +908,9 @@ func panicToErr(err *error) { // panic(fmt.Errorf("%s: "+format, params2...)) // } -func isMutableKind(k reflect.Kind) (v bool) { - return k == reflect.Int || +func isImmutableKind(k reflect.Kind) (v bool) { + return false || + k == reflect.Int || k == reflect.Int8 || k == reflect.Int16 || k == reflect.Int32 || @@ -790,6 +920,7 @@ func isMutableKind(k reflect.Kind) (v bool) { k == reflect.Uint16 || k == reflect.Uint32 || k == reflect.Uint64 || + k == reflect.Uintptr || k == reflect.Float32 || k == reflect.Float64 || k == reflect.Bool || diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_internal.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_internal.go index 7d4e9326a25c..dea981fbb7be 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_internal.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_internal.go @@ -1,5 +1,5 @@ -// Copyright (c) 2012, 2013 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec @@ -149,3 +149,94 @@ func halfFloatToFloatBits(yy uint16) (d uint32) { m = m << 13 return (s << 31) | (e << 23) | m } + +// GrowCap will return a new capacity for a slice, given the following: +// - oldCap: current capacity +// - unit: in-memory size of an element +// - num: number of elements to add +func growCap(oldCap, unit, num int) (newCap int) { + // appendslice logic (if cap < 1024, *2, else *1.25): + // leads to many copy calls, especially when copying bytes. + // bytes.Buffer model (2*cap + n): much better for bytes. + // smarter way is to take the byte-size of the appended element(type) into account + + // maintain 3 thresholds: + // t1: if cap <= t1, newcap = 2x + // t2: if cap <= t2, newcap = 1.75x + // t3: if cap <= t3, newcap = 1.5x + // else newcap = 1.25x + // + // t1, t2, t3 >= 1024 always. + // i.e. if unit size >= 16, then always do 2x or 1.25x (ie t1, t2, t3 are all same) + // + // With this, appending for bytes increase by: + // 100% up to 4K + // 75% up to 8K + // 50% up to 16K + // 25% beyond that + + // unit can be 0 e.g. for struct{}{}; handle that appropriately + var t1, t2, t3 int // thresholds + if unit <= 1 { + t1, t2, t3 = 4*1024, 8*1024, 16*1024 + } else if unit < 16 { + t3 = 16 / unit * 1024 + t1 = t3 * 1 / 4 + t2 = t3 * 2 / 4 + } else { + t1, t2, t3 = 1024, 1024, 1024 + } + + var x int // temporary variable + + // x is multiplier here: one of 5, 6, 7 or 8; incr of 25%, 50%, 75% or 100% respectively + if oldCap <= t1 { // [0,t1] + x = 8 + } else if oldCap > t3 { // (t3,infinity] + x = 5 + } else if oldCap <= t2 { // (t1,t2] + x = 7 + } else { // (t2,t3] + x = 6 + } + newCap = x * oldCap / 4 + + if num > 0 { + newCap += num + } + + // ensure newCap is a multiple of 64 (if it is > 64) or 16. + if newCap > 64 { + if x = newCap % 64; x != 0 { + x = newCap / 64 + newCap = 64 * (x + 1) + } + } else { + if x = newCap % 16; x != 0 { + x = newCap / 16 + newCap = 16 * (x + 1) + } + } + return +} + +func expandSliceValue(s reflect.Value, num int) reflect.Value { + if num <= 0 { + return s + } + l0 := s.Len() + l1 := l0 + num // new slice length + if l1 < l0 { + panic("ExpandSlice: slice overflow") + } + c0 := s.Cap() + if l1 <= c0 { + return s.Slice(0, l1) + } + st := s.Type() + c1 := growCap(c0, int(st.Elem().Size()), num) + s2 := reflect.MakeSlice(st, l1, c1) + // println("expandslicevalue: cap-old: ", c0, ", cap-new: ", c1, ", len-new: ", l1) + reflect.Copy(s2, s) + return s2 +} diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_not_unsafe.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_not_unsafe.go index df0503880f93..7c2ffc0fde6e 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_not_unsafe.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_not_unsafe.go @@ -1,7 +1,7 @@ //+build !unsafe // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_test.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_test.go index 8ea6cc5e7234..685c576c4e3c 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_test.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_unsafe.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_unsafe.go index 3526d4452a6b..373b2b1027dc 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_unsafe.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_unsafe.go @@ -1,7 +1,7 @@ //+build unsafe // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec @@ -26,6 +26,9 @@ type unsafeBytes struct { // In unsafe mode, it doesn't incur allocation and copying caused by conversion. // In regular safe mode, it is an allocation and copy. func stringView(v []byte) string { + if len(v) == 0 { + return "" + } x := unsafeString{uintptr(unsafe.Pointer(&v[0])), len(v)} return *(*string)(unsafe.Pointer(&x)) } @@ -34,6 +37,9 @@ func stringView(v []byte) string { // In unsafe mode, it doesn't incur allocation and copying caused by conversion. // In regular safe mode, it is an allocation and copy. func bytesView(v string) []byte { + if len(v) == 0 { + return zeroByteSlice + } x := unsafeBytes{uintptr(unsafe.Pointer(&v)), len(v), len(v)} return *(*[]byte)(unsafe.Pointer(&x)) } diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/json.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/json.go index c112a79716c8..59e0bc24a12e 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/json.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/json.go @@ -1,10 +1,11 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec -// This json support uses base64 encoding for bytes, because you cannot +// By default, this json support uses base64 encoding for bytes, because you cannot // store and read any arbitrary string in json (only unicode). +// However, the user can configre how to encode/decode bytes. // // This library specifically supports UTF-8 for encoding and decoding only. // @@ -27,11 +28,18 @@ package codec // - encode does not beautify. There is no whitespace when encoding. // - rpc calls which take single integer arguments or write single numeric arguments will need care. +// Top-level methods of json(End|Dec)Driver (which are implementations of (en|de)cDriver +// MUST not call one-another. +// They all must call sep(), and sep() MUST NOT be called more than once for each read. +// If sep() is called and read is not done, you MUST call retryRead so separator wouldn't be read/written twice. + import ( "bytes" "encoding/base64" "fmt" + "reflect" "strconv" + "sync" "unicode/utf16" "unicode/utf8" ) @@ -81,20 +89,122 @@ const ( // jsonNumDigitsUint64Largest = 19 ) +// A stack is used to keep track of where we are in the tree. +// This is necessary, as the Handle must know whether to consume or emit a separator. + +type jsonStackElem struct { + st byte // top of stack (either '}' or ']' or 0 for map, array or neither). + sf bool // NOT first time in that container at top of stack + so bool // stack ctr odd + sr bool // value has NOT been read, so do not re-send separator +} + +func (x *jsonStackElem) retryRead() { + if x != nil && !x.sr { + x.sr = true + } +} + +func (x *jsonStackElem) sep() (c byte) { + // do not use switch, so it's a candidate for inlining. + // to inline effectively, this must not be called from within another method. + // v := j.st + if x == nil || x.st == 0 { + return + } + if x.sr { + x.sr = false + return + } + // v == '}' OR ']' + if x.st == '}' { + // put , or : depending on if even or odd respectively + if x.so { + c = ':' + if !x.sf { + x.sf = true + } + } else if x.sf { + c = ',' + } + } else { + if x.sf { + c = ',' + } else { + x.sf = true + } + } + x.so = !x.so + // Note: Anything more, and this function doesn't inline. Keep it tight. + // if x.sr { + // x.sr = false + // } + return +} + +const jsonStackPoolArrayLen = 32 + +// pool used to prevent constant allocation of stacks. +var jsonStackPool = sync.Pool{ + New: func() interface{} { + return new([jsonStackPoolArrayLen]jsonStackElem) + }, +} + +// jsonStack contains the stack for tracking the state of the container (branch). +// The same data structure is used during encode and decode, as it is similar functionality. +type jsonStack struct { + s []jsonStackElem // stack for map or array end tag. map=}, array=] + sc *jsonStackElem // pointer to current (top) element on the stack. + sp *[jsonStackPoolArrayLen]jsonStackElem +} + +func (j *jsonStack) start(c byte) { + if j.s == nil { + // j.s = make([]jsonStackElem, 0, 8) + j.sp = jsonStackPool.Get().(*[jsonStackPoolArrayLen]jsonStackElem) + j.s = j.sp[:0] + } + j.s = append(j.s, jsonStackElem{st: c}) + j.sc = &(j.s[len(j.s)-1]) +} + +func (j *jsonStack) end() { + l := len(j.s) - 1 // length of new stack after pop'ing + if l == 0 { + jsonStackPool.Put(j.sp) + j.s = nil + j.sp = nil + j.sc = nil + } else { + j.s = j.s[:l] + j.sc = &(j.s[l-1]) + } + //j.sc = &(j.s[len(j.s)-1]) +} + type jsonEncDriver struct { e *Encoder w encWriter h *JsonHandle b [64]byte // scratch bs []byte // scratch + se setExtWrapper + s jsonStack noBuiltInTypes } func (e *jsonEncDriver) EncodeNil() { + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } e.w.writeb(jsonLiterals[9:13]) // null } func (e *jsonEncDriver) EncodeBool(b bool) { + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } if b { e.w.writeb(jsonLiterals[0:4]) // true } else { @@ -103,78 +213,106 @@ func (e *jsonEncDriver) EncodeBool(b bool) { } func (e *jsonEncDriver) EncodeFloat32(f float32) { + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } e.w.writeb(strconv.AppendFloat(e.b[:0], float64(f), 'E', -1, 32)) } func (e *jsonEncDriver) EncodeFloat64(f float64) { + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } // e.w.writestr(strconv.FormatFloat(f, 'E', -1, 64)) e.w.writeb(strconv.AppendFloat(e.b[:0], f, 'E', -1, 64)) } func (e *jsonEncDriver) EncodeInt(v int64) { + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } e.w.writeb(strconv.AppendInt(e.b[:0], v, 10)) } func (e *jsonEncDriver) EncodeUint(v uint64) { + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } e.w.writeb(strconv.AppendUint(e.b[:0], v, 10)) } func (e *jsonEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) { + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } if v := ext.ConvertExt(rv); v == nil { - e.EncodeNil() + e.w.writeb(jsonLiterals[9:13]) // null // e.EncodeNil() } else { + e.s.sc.retryRead() en.encode(v) } } func (e *jsonEncDriver) EncodeRawExt(re *RawExt, en *Encoder) { + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } // only encodes re.Value (never re.Data) if re.Value == nil { - e.EncodeNil() + e.w.writeb(jsonLiterals[9:13]) // null // e.EncodeNil() } else { + e.s.sc.retryRead() en.encode(re.Value) } } func (e *jsonEncDriver) EncodeArrayStart(length int) { + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } + e.s.start(']') e.w.writen1('[') } -func (e *jsonEncDriver) EncodeArrayEntrySeparator() { - e.w.writen1(',') -} - -func (e *jsonEncDriver) EncodeArrayEnd() { - e.w.writen1(']') -} - func (e *jsonEncDriver) EncodeMapStart(length int) { + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } + e.s.start('}') e.w.writen1('{') } -func (e *jsonEncDriver) EncodeMapEntrySeparator() { - e.w.writen1(',') -} - -func (e *jsonEncDriver) EncodeMapKVSeparator() { - e.w.writen1(':') -} - -func (e *jsonEncDriver) EncodeMapEnd() { - e.w.writen1('}') +func (e *jsonEncDriver) EncodeEnd() { + b := e.s.sc.st + e.s.end() + e.w.writen1(b) } func (e *jsonEncDriver) EncodeString(c charEncoding, v string) { // e.w.writestr(strconv.Quote(v)) + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } e.quoteStr(v) } func (e *jsonEncDriver) EncodeSymbol(v string) { // e.EncodeString(c_UTF8, v) + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } e.quoteStr(v) } func (e *jsonEncDriver) EncodeStringBytes(c charEncoding, v []byte) { + // if encoding raw bytes and RawBytesExt is configured, use it to encode + if c == c_RAW && e.se.i != nil { + e.EncodeExt(v, 0, &e.se, e.e) + return + } + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } if c == c_RAW { slen := base64.StdEncoding.EncodedLen(len(v)) if e.bs == nil { @@ -195,6 +333,13 @@ func (e *jsonEncDriver) EncodeStringBytes(c charEncoding, v []byte) { } } +func (e *jsonEncDriver) EncodeAsis(v []byte) { + if c := e.s.sc.sep(); c != 0 { + e.w.writen1(c) + } + e.w.writeb(v) +} + func (e *jsonEncDriver) quoteStr(s string) { // adapted from std pkg encoding/json const hex = "0123456789abcdef" @@ -356,9 +501,14 @@ type jsonDecDriver struct { ct valueType // container type. one of unset, array or map. bstr [8]byte // scratch used for string \UXXX parsing b [64]byte // scratch + b2 [64]byte wsSkipped bool // whitespace skipped + se setExtWrapper + + s jsonStack + n jsonNum noBuiltInTypes } @@ -402,16 +552,27 @@ func (d *jsonDecDriver) readStrIdx(fromIdx, toIdx uint8) { } func (d *jsonDecDriver) TryDecodeAsNil() bool { - b := d.skipWhitespace(true) + // we mustn't consume the state here, and end up trying to read separator twice. + // Instead, we keep track of the state and restore it if we couldn't decode as nil. + + if c := d.s.sc.sep(); c != 0 { + d.expectChar(c) + } + b := d.skipWhitespace(false) if b == 'n' { - d.readStrIdx(9, 13) // null + d.readStrIdx(10, 13) // ull d.ct = valueTypeNil return true } + d.r.unreadn1() + d.s.sc.retryRead() return false } func (d *jsonDecDriver) DecodeBool() bool { + if c := d.s.sc.sep(); c != 0 { + d.expectChar(c) + } b := d.skipWhitespace(false) if b == 'f' { d.readStrIdx(5, 9) // alse @@ -426,35 +587,35 @@ func (d *jsonDecDriver) DecodeBool() bool { } func (d *jsonDecDriver) ReadMapStart() int { + if c := d.s.sc.sep(); c != 0 { + d.expectChar(c) + } + d.s.start('}') d.expectChar('{') d.ct = valueTypeMap return -1 } func (d *jsonDecDriver) ReadArrayStart() int { + if c := d.s.sc.sep(); c != 0 { + d.expectChar(c) + } + d.s.start(']') d.expectChar('[') d.ct = valueTypeArray return -1 } -func (d *jsonDecDriver) ReadMapEnd() { - d.expectChar('}') -} -func (d *jsonDecDriver) ReadArrayEnd() { - d.expectChar(']') -} -func (d *jsonDecDriver) ReadArrayEntrySeparator() { - d.expectChar(',') -} -func (d *jsonDecDriver) ReadMapEntrySeparator() { - d.expectChar(',') -} -func (d *jsonDecDriver) ReadMapKVSeparator() { - d.expectChar(':') + +func (d *jsonDecDriver) ReadEnd() { + b := d.s.sc.st + d.s.end() + d.expectChar(b) } + func (d *jsonDecDriver) expectChar(c uint8) { b := d.skipWhitespace(false) if b != c { - d.d.errorf("json: expect char %c but got char %c", c, b) + d.d.errorf("json: expect char '%c' but got char '%c'", c, b) return } if jsonTrackSkipWhitespace { @@ -462,6 +623,17 @@ func (d *jsonDecDriver) expectChar(c uint8) { } } +// func (d *jsonDecDriver) maybeChar(c uint8) { +// b := d.skipWhitespace(false) +// if b != c { +// d.r.unreadn1() +// return +// } +// if jsonTrackSkipWhitespace { +// d.wsSkipped = false +// } +// } + func (d *jsonDecDriver) IsContainerType(vt valueType) bool { // check container type by checking the first char if d.ct == valueTypeUnset { @@ -635,6 +807,9 @@ LOOP: } func (d *jsonDecDriver) DecodeInt(bitsize uint8) (i int64) { + if c := d.s.sc.sep(); c != 0 { + d.expectChar(c) + } d.decNum(false) n := &d.n if n.manOverflow { @@ -667,6 +842,9 @@ func (d *jsonDecDriver) DecodeInt(bitsize uint8) (i int64) { } func (d *jsonDecDriver) DecodeUint(bitsize uint8) (u uint64) { + if c := d.s.sc.sep(); c != 0 { + d.expectChar(c) + } d.decNum(false) n := &d.n if n.neg { @@ -698,6 +876,9 @@ func (d *jsonDecDriver) DecodeUint(bitsize uint8) (u uint64) { } func (d *jsonDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) { + if c := d.s.sc.sep(); c != 0 { + d.expectChar(c) + } d.decNum(true) n := &d.n f = n.floatVal() @@ -709,6 +890,10 @@ func (d *jsonDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) { } func (d *jsonDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) { + // No need to call sep here, as d.d.decode() handles it + // if c := d.s.sc.sep(); c != 0 { + // d.expectChar(c) + // } if ext == nil { re := rv.(*RawExt) re.Tag = xtag @@ -722,14 +907,26 @@ func (d *jsonDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxta } func (d *jsonDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte) { - // zerocopy doesn't matter for json, as the bytes must be parsed. + // if decoding into raw bytes, and the RawBytesExt is configured, use it to decode. + if !isstring && d.se.i != nil { + bsOut = bs + d.DecodeExt(&bsOut, 0, &d.se) + return + } + if c := d.s.sc.sep(); c != 0 { + d.expectChar(c) + } bs0 := d.appendStringAsBytes(d.b[:0]) + // if isstring, then just return the bytes, even if it is using the scratch buffer. + // the bytes will be converted to a string as needed. if isstring { return bs0 } slen := base64.StdEncoding.DecodedLen(len(bs0)) - if cap(bs) >= slen { + if slen <= cap(bs) { bsOut = bs[:slen] + } else if zerocopy && slen <= cap(d.b2) { + bsOut = d.b2[:slen] } else { bsOut = make([]byte, slen) } @@ -745,6 +942,9 @@ func (d *jsonDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut [ } func (d *jsonDecDriver) DecodeString() (s string) { + if c := d.s.sc.sep(); c != 0 { + d.expectChar(c) + } return string(d.appendStringAsBytes(d.b[:0])) } @@ -816,6 +1016,9 @@ func (d *jsonDecDriver) jsonU4(checkSlashU bool) rune { } func (d *jsonDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurther bool) { + if c := d.s.sc.sep(); c != 0 { + d.expectChar(c) + } n := d.skipWhitespace(true) switch n { case 'n': @@ -837,7 +1040,7 @@ func (d *jsonDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurthe decodeFurther = true case '"': vt = valueTypeString - v = d.DecodeString() + v = string(d.appendStringAsBytes(d.b[:0])) // same as d.DecodeString(), but skipping sep() call. default: // number d.decNum(true) n := &d.n @@ -878,6 +1081,9 @@ func (d *jsonDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurthe } // fmt.Printf("DecodeNaked: Number: %T, %v\n", v, v) } + if decodeFurther { + d.s.sc.retryRead() + } return } @@ -887,7 +1093,8 @@ func (d *jsonDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurthe // // Json is comprehensively supported: // - decodes numbers into interface{} as int, uint or float64 -// - encodes and decodes []byte using base64 Std Encoding +// - configurable way to encode/decode []byte . +// by default, encodes and decodes []byte using base64 Std Encoding // - UTF-8 support for encoding and decoding // // It has better performance than the json library in the standard library, @@ -901,19 +1108,29 @@ func (d *jsonDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurthe type JsonHandle struct { BasicHandle textEncodingType + // RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way. + // If not configured, raw bytes are encoded to/from base64 text. + RawBytesExt InterfaceExt } func (h *JsonHandle) newEncDriver(e *Encoder) encDriver { - return &jsonEncDriver{e: e, w: e.w, h: h} + hd := jsonEncDriver{e: e, w: e.w, h: h} + hd.se.i = h.RawBytesExt + return &hd } func (h *JsonHandle) newDecDriver(d *Decoder) decDriver { // d := jsonDecDriver{r: r.(*bytesDecReader), h: h} hd := jsonDecDriver{d: d, r: d.r, h: h} + hd.se.i = h.RawBytesExt hd.n.bytes = d.b[:] return &hd } +func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) { + return h.SetExt(rt, tag, &setExtWrapper{i: ext}) +} + var jsonEncodeTerminate = []byte{' '} func (h *JsonHandle) rpcEncodeTerminate() []byte { diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/msgpack.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/msgpack.go index a5812ba145d7..fd5f3895d81e 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/msgpack.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/msgpack.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. /* MSGPACK @@ -24,6 +24,7 @@ import ( "io" "math" "net/rpc" + "reflect" ) const ( @@ -536,15 +537,11 @@ func (d *msgpackDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOu d.readNextBd() } var clen int - if isstring { - clen = d.readContainerLen(msgpackContainerStr) + // ignore isstring. Expect that the bytes may be found from msgpackContainerStr or msgpackContainerBin + if bd := d.bd; bd == mpBin8 || bd == mpBin16 || bd == mpBin32 { + clen = d.readContainerLen(msgpackContainerBin) } else { - // bytes can be decoded from msgpackContainerStr or msgpackContainerBin - if bd := d.bd; bd == mpBin8 || bd == mpBin16 || bd == mpBin32 { - clen = d.readContainerLen(msgpackContainerBin) - } else { - clen = d.readContainerLen(msgpackContainerStr) - } + clen = d.readContainerLen(msgpackContainerStr) } // println("DecodeBytes: clen: ", clen) d.bdRead = false @@ -617,7 +614,7 @@ func (d *msgpackDecDriver) readContainerLen(ct msgpackContainerType) (clen int) } else if (ct.bFixMin & bd) == ct.bFixMin { clen = int(ct.bFixMin ^ bd) } else { - d.d.errorf("readContainerLen: %s: hex: %x, dec: %d", msgBadDesc, bd, bd) + d.d.errorf("readContainerLen: %s: hex: %x, decimal: %d", msgBadDesc, bd, bd) return } d.bdRead = false @@ -730,6 +727,10 @@ func (h *MsgpackHandle) newDecDriver(d *Decoder) decDriver { return &msgpackDecDriver{d: d, r: d.r, h: h, br: d.bytes} } +func (h *MsgpackHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) { + return h.SetExt(rt, tag, &setExtWrapper{b: ext}) +} + //-------------------------------------------------- type msgpackSpecRpcCodec struct { @@ -781,7 +782,7 @@ func (c *msgpackSpecRpcCodec) ReadRequestBody(body interface{}) error { func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) { - if c.cls { + if c.isClosed() { return io.EOF } diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/noop.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/noop.go index 76c01e4d3c8b..ca02c6a7e8f0 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/noop.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/noop.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec @@ -11,6 +11,7 @@ import ( // NoopHandle returns a no-op handle. It basically does nothing. // It is only useful for benchmarking, as it gives an idea of the // overhead from the codec framework. +// // LIBRARY USERS: *** DO NOT USE *** func NoopHandle(slen int) *noopHandle { h := noopHandle{} @@ -40,7 +41,8 @@ type noopDrv struct { i int S []string B [][]byte - mk bool // are we about to read a map key? + mks []bool // stack. if map (true), else if array (false) + mk bool // top of stack. what container are we on? map or array? ct valueType // last request for IsContainerType. cb bool // last response for IsContainerType. rand *rand.Rand @@ -54,21 +56,34 @@ func (h *noopDrv) newDecDriver(_ *Decoder) decDriver { return h } // --- encDriver -func (h *noopDrv) EncodeBuiltin(rt uintptr, v interface{}) {} -func (h *noopDrv) EncodeNil() {} -func (h *noopDrv) EncodeInt(i int64) {} -func (h *noopDrv) EncodeUint(i uint64) {} -func (h *noopDrv) EncodeBool(b bool) {} -func (h *noopDrv) EncodeFloat32(f float32) {} -func (h *noopDrv) EncodeFloat64(f float64) {} -func (h *noopDrv) EncodeRawExt(re *RawExt, e *Encoder) {} -func (h *noopDrv) EncodeArrayStart(length int) {} -func (h *noopDrv) EncodeArrayEnd() {} -func (h *noopDrv) EncodeArrayEntrySeparator() {} -func (h *noopDrv) EncodeMapStart(length int) {} -func (h *noopDrv) EncodeMapEnd() {} -func (h *noopDrv) EncodeMapEntrySeparator() {} -func (h *noopDrv) EncodeMapKVSeparator() {} +// stack functions (for map and array) +func (h *noopDrv) start(b bool) { + // println("start", len(h.mks)+1) + h.mks = append(h.mks, b) + h.mk = b +} +func (h *noopDrv) end() { + // println("end: ", len(h.mks)-1) + h.mks = h.mks[:len(h.mks)-1] + if len(h.mks) > 0 { + h.mk = h.mks[len(h.mks)-1] + } else { + h.mk = false + } +} + +func (h *noopDrv) EncodeBuiltin(rt uintptr, v interface{}) {} +func (h *noopDrv) EncodeNil() {} +func (h *noopDrv) EncodeInt(i int64) {} +func (h *noopDrv) EncodeUint(i uint64) {} +func (h *noopDrv) EncodeBool(b bool) {} +func (h *noopDrv) EncodeFloat32(f float32) {} +func (h *noopDrv) EncodeFloat64(f float64) {} +func (h *noopDrv) EncodeRawExt(re *RawExt, e *Encoder) {} +func (h *noopDrv) EncodeArrayStart(length int) { h.start(true) } +func (h *noopDrv) EncodeMapStart(length int) { h.start(false) } +func (h *noopDrv) EncodeEnd() { h.end() } + func (h *noopDrv) EncodeString(c charEncoding, v string) {} func (h *noopDrv) EncodeSymbol(v string) {} func (h *noopDrv) EncodeStringBytes(c charEncoding, v []byte) {} @@ -90,15 +105,11 @@ func (h *noopDrv) DecodeString() (s string) { return h.S[h.m(8 func (h *noopDrv) DecodeBytes(bs []byte, isstring, zerocopy bool) []byte { return h.B[h.m(len(h.B))] } -func (h *noopDrv) ReadMapEnd() { h.mk = false } -func (h *noopDrv) ReadArrayEnd() {} -func (h *noopDrv) ReadArrayEntrySeparator() {} -func (h *noopDrv) ReadMapEntrySeparator() { h.mk = true } -func (h *noopDrv) ReadMapKVSeparator() { h.mk = false } +func (h *noopDrv) ReadEnd() { h.end() } // toggle map/slice -func (h *noopDrv) ReadMapStart() int { h.mk = true; return h.m(10) } -func (h *noopDrv) ReadArrayStart() int { return h.m(10) } +func (h *noopDrv) ReadMapStart() int { h.start(true); return h.m(10) } +func (h *noopDrv) ReadArrayStart() int { h.start(false); return h.m(10) } func (h *noopDrv) IsContainerType(vt valueType) bool { // return h.m(2) == 0 diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/prebuild.sh b/Godeps/_workspace/src/github.com/ugorji/go/codec/prebuild.sh index a10e74bdc416..d548b88cbf60 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/prebuild.sh +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/prebuild.sh @@ -54,7 +54,7 @@ _build() { cat > gen.generated.go <>>>>>> TAGS: $ztags" + + OPTIND=1 + while getopts "xurtcinsvg" flag + do + case "x$flag" in + 'xt') printf ">>>>>>> REGULAR : "; go test "-tags=$ztags" "$zverbose" ; sleep 2 ;; + 'xc') printf ">>>>>>> CANONICAL : "; go test "-tags=$ztags" "$zverbose" -tc; sleep 2 ;; + 'xi') printf ">>>>>>> I/O : "; go test "-tags=$ztags" "$zverbose" -ti; sleep 2 ;; + 'xn') printf ">>>>>>> NO_SYMBOLS : "; go test "-tags=$ztags" "$zverbose" -tn; sleep 2 ;; + 'xs') printf ">>>>>>> TO_ARRAY : "; go test "-tags=$ztags" "$zverbose" -ts; sleep 2 ;; + *) ;; + esac + done + shift $((OPTIND-1)) + + OPTIND=1 +} + +# echo ">>>>>>> RUNNING VARIATIONS OF TESTS" +if [[ "x$@" = x ]]; then + # r, x, g, gu + _run "-rtcins" + _run "-xtcins" + _run "-gtcins" + _run "-gutcins" +else + _run "$@" +fi diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/time.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/time.go index a6344ed779b4..733fc3fb75a5 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/time.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/time.go @@ -1,5 +1,5 @@ // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/values_test.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/values_test.go index a3d1f399b3ec..4ec28e131c84 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/values_test.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/values_test.go @@ -1,7 +1,7 @@ // // +build testing // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -// Use of this source code is governed by a BSD-style license found in the LICENSE file. +// Use of this source code is governed by a MIT license found in the LICENSE file. package codec @@ -57,6 +57,11 @@ type TestStruc struct { Iptrslice []*int64 + // TODO: test these separately, specifically for reflection and codecgen. + // Unfortunately, ffjson doesn't support these. Its compilation even fails. + // Ui64array [4]uint64 + // Ui64slicearray [][4]uint64 + AnonInTestStruc //M map[interface{}]interface{} `json:"-",bson:"-"` diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/doc.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/doc.go new file mode 100644 index 000000000000..ae7bd8b89ec7 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/doc.go @@ -0,0 +1,8 @@ +// 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. + +// This package contains test data shared between the various subpackages of +// the golang.org/x/crypto/ssh package. Under no circumstance should +// this data be used for production code. +package testdata diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/keys.go b/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/keys.go new file mode 100644 index 000000000000..5ff1c0e0358f --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/crypto/ssh/testdata/keys.go @@ -0,0 +1,43 @@ +// 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 testdata + +var PEMBytes = map[string][]byte{ + "dsa": []byte(`-----BEGIN DSA PRIVATE KEY----- +MIIBuwIBAAKBgQD6PDSEyXiI9jfNs97WuM46MSDCYlOqWw80ajN16AohtBncs1YB +lHk//dQOvCYOsYaE+gNix2jtoRjwXhDsc25/IqQbU1ahb7mB8/rsaILRGIbA5WH3 +EgFtJmXFovDz3if6F6TzvhFpHgJRmLYVR8cqsezL3hEZOvvs2iH7MorkxwIVAJHD +nD82+lxh2fb4PMsIiaXudAsBAoGAQRf7Q/iaPRn43ZquUhd6WwvirqUj+tkIu6eV +2nZWYmXLlqFQKEy4Tejl7Wkyzr2OSYvbXLzo7TNxLKoWor6ips0phYPPMyXld14r +juhT24CrhOzuLMhDduMDi032wDIZG4Y+K7ElU8Oufn8Sj5Wge8r6ANmmVgmFfynr +FhdYCngCgYEA3ucGJ93/Mx4q4eKRDxcWD3QzWyqpbRVRRV1Vmih9Ha/qC994nJFz +DQIdjxDIT2Rk2AGzMqFEB68Zc3O+Wcsmz5eWWzEwFxaTwOGWTyDqsDRLm3fD+QYj +nOwuxb0Kce+gWI8voWcqC9cyRm09jGzu2Ab3Bhtpg8JJ8L7gS3MRZK4CFEx4UAfY +Fmsr0W6fHB9nhS4/UXM8 +-----END DSA PRIVATE KEY----- +`), + "ecdsa": []byte(`-----BEGIN EC PRIVATE KEY----- +MHcCAQEEINGWx0zo6fhJ/0EAfrPzVFyFC9s18lBt3cRoEDhS3ARooAoGCCqGSM49 +AwEHoUQDQgAEi9Hdw6KvZcWxfg2IDhA7UkpDtzzt6ZqJXSsFdLd+Kx4S3Sx4cVO+ +6/ZOXRnPmNAlLUqjShUsUBBngG0u2fqEqA== +-----END EC PRIVATE KEY----- +`), + "rsa": []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIBOwIBAAJBALdGZxkXDAjsYk10ihwU6Id2KeILz1TAJuoq4tOgDWxEEGeTrcld +r/ZwVaFzjWzxaf6zQIJbfaSEAhqD5yo72+sCAwEAAQJBAK8PEVU23Wj8mV0QjwcJ +tZ4GcTUYQL7cF4+ezTCE9a1NrGnCP2RuQkHEKxuTVrxXt+6OF15/1/fuXnxKjmJC +nxkCIQDaXvPPBi0c7vAxGwNY9726x01/dNbHCE0CBtcotobxpwIhANbbQbh3JHVW +2haQh4fAG5mhesZKAGcxTyv4mQ7uMSQdAiAj+4dzMpJWdSzQ+qGHlHMIBvVHLkqB +y2VdEyF7DPCZewIhAI7GOI/6LDIFOvtPo6Bj2nNmyQ1HU6k/LRtNIXi4c9NJAiAr +rrxx26itVhJmcvoUhOjwuzSlP2bE5VHAvkGB352YBg== +-----END RSA PRIVATE KEY----- +`), + "user": []byte(`-----BEGIN EC PRIVATE KEY----- +MHcCAQEEILYCAeq8f7V4vSSypRw7pxy8yz3V5W4qg8kSC3zJhqpQoAoGCCqGSM49 +AwEHoUQDQgAEYcO2xNKiRUYOLEHM7VYAp57HNyKbOdYtHD83Z4hzNPVC4tM5mdGD +PLL8IEwvYu2wq+lpXfGQnNMbzYf9gspG0w== +-----END EC PRIVATE KEY----- +`), +} diff --git a/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-charset.html b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-charset.html new file mode 100644 index 000000000000..9915fa0ee4f5 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-charset.html @@ -0,0 +1,48 @@ + + + + HTTP charset + + + + + + + + + + + +

HTTP charset

+ + +
+ + +
 
+ + + + + +
+

The character encoding of a page can be set using the HTTP header charset declaration.

+

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ÜÀÚ. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.

The only character encoding declaration for this HTML file is in the HTTP header, which sets the encoding to ISO 8859-15.

+
+
+
HTML5
+

the-input-byte-stream-001
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-UTF-8-BOM.html b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-UTF-8-BOM.html new file mode 100644 index 000000000000..26e5d8b4ebf6 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-UTF-8-BOM.html @@ -0,0 +1,48 @@ + + + + HTTP vs UTF-8 BOM + + + + + + + + + + + +

HTTP vs UTF-8 BOM

+ + +
+ + +
 
+ + + + + +
+

A character encoding set in the HTTP header has lower precedence than the UTF-8 signature.

+

The HTTP header attempts to set the character encoding to ISO 8859-15. The page starts with a UTF-8 signature.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ýäè. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.

If the test is unsuccessful, the characters  should appear at the top of the page. These represent the bytes that make up the UTF-8 signature when encountered in the ISO 8859-15 encoding.

+
+
+
HTML5
+

the-input-byte-stream-034
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-charset.html b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-charset.html new file mode 100644 index 000000000000..2f07e95158ea --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-charset.html @@ -0,0 +1,49 @@ + + + + HTTP vs meta charset + + + + + + + + + + + +

HTTP vs meta charset

+ + +
+ + +
 
+ + + + + +
+

The HTTP header has a higher precedence than an encoding declaration in a meta charset attribute.

+

The HTTP header attempts to set the character encoding to ISO 8859-15. The page contains an encoding declaration in a meta charset attribute that attempts to set the character encoding to ISO 8859-1.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ÜÀÚ. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-018
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-content.html b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-content.html new file mode 100644 index 000000000000..6853cddecccb --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-content.html @@ -0,0 +1,49 @@ + + + + HTTP vs meta content + + + + + + + + + + + +

HTTP vs meta content

+ + +
+ + +
 
+ + + + + +
+

The HTTP header has a higher precedence than an encoding declaration in a meta content attribute.

+

The HTTP header attempts to set the character encoding to ISO 8859-15. The page contains an encoding declaration in a meta content attribute that attempts to set the character encoding to ISO 8859-1.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ÜÀÚ. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-016
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/No-encoding-declaration.html b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/No-encoding-declaration.html new file mode 100644 index 000000000000..612e26c6c521 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/No-encoding-declaration.html @@ -0,0 +1,47 @@ + + + + No encoding declaration + + + + + + + + + + + +

No encoding declaration

+ + +
+ + +
 
+ + + + + +
+

A page with no encoding information in HTTP, BOM, XML declaration or meta element will be treated as UTF-8.

+

The test on this page contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ýäè. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-015
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/README b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/README new file mode 100644 index 000000000000..38ef0f9f121f --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/README @@ -0,0 +1,9 @@ +These test cases come from +http://www.w3.org/International/tests/repository/html5/the-input-byte-stream/results-basics + +Distributed under both the W3C Test Suite License +(http://www.w3.org/Consortium/Legal/2008/04-testsuite-license) +and the W3C 3-clause BSD License +(http://www.w3.org/Consortium/Legal/2008/03-bsd-license). +To contribute to a W3C Test Suite, see the policies and contribution +forms (http://www.w3.org/2004/10/27-testcases). diff --git a/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-16BE-BOM.html b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-16BE-BOM.html new file mode 100644 index 0000000000000000000000000000000000000000..3abf7a9343c20518e57dfea58b374fb0f4fb58a1 GIT binary patch literal 2670 zcmcJR?QRoS5Qc}JAoU&=BQ-(7b^;2j8i*i3RV1JlO@;VXIsPurV!WHiDdLW}i`*CO z^UnC>tih=KsVr;H&Y7?C&O3AV(?534uG?e##U9y_y|!QNi4``n+D>d{2lky^LnFNx z?9HrarH$>rwQR_$g)Hk0*&STI*EYq|47~&U9sfUB+ji})9eR{QqCUra7oDsZ5obtB zdxP%<)-$4Q;rSHJiM>U(#ZI=;?n^BC?Dp6lu=~_1-lnX3u03&2BlmQIY>L+!Uq7XoytKw^Q#oZSM?3*J?)&ojG&yzQRkC!Ml5JE?ax;lp_NYEcdUht`ZswOviB~L5hmJ|pXI71nn20w;>vG! zQGB$EE9&wC``&J#_Ym~PgRu-Bd>1!pOp0||k`kr=VJ zfH6I6rmRaeHA7U-A^OTsT+|d2a^i(>DePzZ{)ibXoCBvJnuYrd-3kkN$uy{qQK;=*Y;S87ro12aTgu^i*%f8zC3>a}9DIe4cfxOzsCw&(cqvP9{ud{N6f` z#TNDY(B6@Gpr|uN+%&x^XZjBHdc@2vsM(Tyc2=vshHQ5w+obmp>tuWT(t4BTUGAQw zxeI$UGSLUBg=WFbF;4f@4=^P2AgY@CFn8A`bcC=_&~)fiDe)#cUARRBzJ^k|%X)69 z+{Cb`wq}Rsg%B62CC_tK!AV(W{(MV?#mndR46CU#BUN<{8e?*oT+!pE5wF#O#TR#a z$9qRT)tpbw8zAI~QQJg2C3|6$I%(T(;`zOMy6SO+&;pG=c#2P|P-WZn$$DpWJlC3U z3*nvmz zwP{u~r$L?-m3uqp9I1+#3yE|3M$(s-BEtih=LQ>`qYoiktOop(wi%!;yh%+Rm z{e|xntY<{q!1F1Z6MKtngPm-p-4|H&+3m4AVE3_AyiHm6Tzlf4M(*ht*%YrezJ6kr zHGj45pc?64*$Cm%-zseWMA`x;)v*~jA=i}szqts9xmQkS`M11|(H7bTXAycsXU53+ zJ?120SRZeyiFjW7enPN`bxk$IaWV3o48oJF7D&2ysoY;6(s6%6vVfaYd&mC=erK!) zNGI^7upQgN)53OHe_VE<@J+G8*Y|p*)zB2Thdi}+YR<5QWHm!|a_*AoZXuv7)$xe| zm3Q$D7{|#}{m4X&UY!6(ZhyYi2(5JLzGE$H)W6BQklnjPMwn<Yvv7Z*TVWwD*=E3QpH37* z#lqXJA0A~J9T_<^W5smspmDg2p6ac5Bjn+~LAoow%1TCdZ*$K8`O zw_$HaCi+0N&@7la#_7KL5r$+QL{)Pi=I&aDjt~|Knht#`CEi4*3%97i_fSfASlwUz0=3V0GCxY}z81UC-nP=CGt2OqYV$ zoRCo+qM9YX*3FFORLC=E3B~S@+KROyk4r5 yX7?DaslDfIebqXgC!KKp4IYy+W~X?ddE6o=`A+x#x0AK&6MF#W&AXxbRrv+SX}PNa literal 0 HcmV?d00001 diff --git a/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-charset.html b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-charset.html new file mode 100644 index 000000000000..83de43338ecb --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-charset.html @@ -0,0 +1,49 @@ + + + + UTF-8 BOM vs meta charset + + + + + + + + + + + +

UTF-8 BOM vs meta charset

+ + +
+ + +
 
+ + + + + +
+

A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta charset attribute declares a different encoding.

+

The page contains an encoding declaration in a meta charset attribute that attempts to set the character encoding to ISO 8859-15, but the file starts with a UTF-8 signature.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ýäè. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-038
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-content.html b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-content.html new file mode 100644 index 000000000000..501aac2d6a5d --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-content.html @@ -0,0 +1,48 @@ + + + + UTF-8 BOM vs meta content + + + + + + + + + + + +

UTF-8 BOM vs meta content

+ + +
+ + +
 
+ + + + + +
+

A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta content attribute declares a different encoding.

+

The page contains an encoding declaration in a meta content attribute that attempts to set the character encoding to ISO 8859-15, but the file starts with a UTF-8 signature.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ýäè. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-037
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/meta-charset-attribute.html b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/meta-charset-attribute.html new file mode 100644 index 000000000000..2d7d25aba14d --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/meta-charset-attribute.html @@ -0,0 +1,48 @@ + + + + meta charset attribute + + + + + + + + + + + +

meta charset attribute

+ + +
+ + +
 
+ + + + + +
+

The character encoding of the page can be set by a meta element with charset attribute.

+

The only character encoding declaration for this HTML file is in the charset attribute of the meta element, which declares the encoding to be ISO 8859-15.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ÜÀÚ. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-009
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/meta-content-attribute.html b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/meta-content-attribute.html new file mode 100644 index 000000000000..1c3f228e7c99 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/meta-content-attribute.html @@ -0,0 +1,48 @@ + + + + meta content attribute + + + + + + + + + + + +

meta content attribute

+ + +
+ + +
 
+ + + + + +
+

The character encoding of the page can be set by a meta element with http-equiv and content attributes.

+

The only character encoding declaration for this HTML file is in the content attribute of the meta element, which declares the encoding to be ISO 8859-15.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ÜÀÚ. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-007
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/go1.html b/Godeps/_workspace/src/golang.org/x/net/html/testdata/go1.html new file mode 100644 index 000000000000..a782cc71d209 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/go1.html @@ -0,0 +1,2237 @@ + + + + + + Go 1 Release Notes - The Go Programming Language + + + + + + + + + + + + +
+ + +
+

Go 1 Release Notes

+ + + + + + + + + +

Introduction to Go 1

+ +

+Go version 1, Go 1 for short, defines a language and a set of core libraries +that provide a stable foundation for creating reliable products, projects, and +publications. +

+ +

+The driving motivation for Go 1 is stability for its users. People should be able to +write Go programs and expect that they will continue to compile and run without +change, on a time scale of years, including in production environments such as +Google App Engine. Similarly, people should be able to write books about Go, be +able to say which version of Go the book is describing, and have that version +number still be meaningful much later. +

+ +

+Code that compiles in Go 1 should, with few exceptions, continue to compile and +run throughout the lifetime of that version, even as we issue updates and bug +fixes such as Go version 1.1, 1.2, and so on. Other than critical fixes, changes +made to the language and library for subsequent releases of Go 1 may +add functionality but will not break existing Go 1 programs. +The Go 1 compatibility document +explains the compatibility guidelines in more detail. +

+ +

+Go 1 is a representation of Go as it used today, not a wholesale rethinking of +the language. We avoided designing new features and instead focused on cleaning +up problems and inconsistencies and improving portability. There are a number +changes to the Go language and packages that we had considered for some time and +prototyped but not released primarily because they are significant and +backwards-incompatible. Go 1 was an opportunity to get them out, which is +helpful for the long term, but also means that Go 1 introduces incompatibilities +for old programs. Fortunately, the go fix tool can +automate much of the work needed to bring programs up to the Go 1 standard. +

+ +

+This document outlines the major changes in Go 1 that will affect programmers +updating existing code; its reference point is the prior release, r60 (tagged as +r60.3). It also explains how to update code from r60 to run under Go 1. +

+ +

Changes to the language

+ +

Append

+ +

+The append predeclared variadic function makes it easy to grow a slice +by adding elements to the end. +A common use is to add bytes to the end of a byte slice when generating output. +However, append did not provide a way to append a string to a []byte, +which is another common case. +

+ +
    greeting := []byte{}
+    greeting = append(greeting, []byte("hello ")...)
+ +

+By analogy with the similar property of copy, Go 1 +permits a string to be appended (byte-wise) directly to a byte +slice, reducing the friction between strings and byte slices. +The conversion is no longer necessary: +

+ +
    greeting = append(greeting, "world"...)
+ +

+Updating: +This is a new feature, so existing code needs no changes. +

+ +

Close

+ +

+The close predeclared function provides a mechanism +for a sender to signal that no more values will be sent. +It is important to the implementation of for range +loops over channels and is helpful in other situations. +Partly by design and partly because of race conditions that can occur otherwise, +it is intended for use only by the goroutine sending on the channel, +not by the goroutine receiving data. +However, before Go 1 there was no compile-time checking that close +was being used correctly. +

+ +

+To close this gap, at least in part, Go 1 disallows close on receive-only channels. +Attempting to close such a channel is a compile-time error. +

+ +
+    var c chan int
+    var csend chan<- int = c
+    var crecv <-chan int = c
+    close(c)     // legal
+    close(csend) // legal
+    close(crecv) // illegal
+
+ +

+Updating: +Existing code that attempts to close a receive-only channel was +erroneous even before Go 1 and should be fixed. The compiler will +now reject such code. +

+ +

Composite literals

+ +

+In Go 1, a composite literal of array, slice, or map type can elide the +type specification for the elements' initializers if they are of pointer type. +All four of the initializations in this example are legal; the last one was illegal before Go 1. +

+ +
    type Date struct {
+        month string
+        day   int
+    }
+    // Struct values, fully qualified; always legal.
+    holiday1 := []Date{
+        Date{"Feb", 14},
+        Date{"Nov", 11},
+        Date{"Dec", 25},
+    }
+    // Struct values, type name elided; always legal.
+    holiday2 := []Date{
+        {"Feb", 14},
+        {"Nov", 11},
+        {"Dec", 25},
+    }
+    // Pointers, fully qualified, always legal.
+    holiday3 := []*Date{
+        &Date{"Feb", 14},
+        &Date{"Nov", 11},
+        &Date{"Dec", 25},
+    }
+    // Pointers, type name elided; legal in Go 1.
+    holiday4 := []*Date{
+        {"Feb", 14},
+        {"Nov", 11},
+        {"Dec", 25},
+    }
+ +

+Updating: +This change has no effect on existing code, but the command +gofmt -s applied to existing source +will, among other things, elide explicit element types wherever permitted. +

+ + +

Goroutines during init

+ +

+The old language defined that go statements executed during initialization created goroutines but that they did not begin to run until initialization of the entire program was complete. +This introduced clumsiness in many places and, in effect, limited the utility +of the init construct: +if it was possible for another package to use the library during initialization, the library +was forced to avoid goroutines. +This design was done for reasons of simplicity and safety but, +as our confidence in the language grew, it seemed unnecessary. +Running goroutines during initialization is no more complex or unsafe than running them during normal execution. +

+ +

+In Go 1, code that uses goroutines can be called from +init routines and global initialization expressions +without introducing a deadlock. +

+ +
var PackageGlobal int
+
+func init() {
+    c := make(chan int)
+    go initializationFunction(c)
+    PackageGlobal = <-c
+}
+ +

+Updating: +This is a new feature, so existing code needs no changes, +although it's possible that code that depends on goroutines not starting before main will break. +There was no such code in the standard repository. +

+ +

The rune type

+ +

+The language spec allows the int type to be 32 or 64 bits wide, but current implementations set int to 32 bits even on 64-bit platforms. +It would be preferable to have int be 64 bits on 64-bit platforms. +(There are important consequences for indexing large slices.) +However, this change would waste space when processing Unicode characters with +the old language because the int type was also used to hold Unicode code points: each code point would waste an extra 32 bits of storage if int grew from 32 bits to 64. +

+ +

+To make changing to 64-bit int feasible, +Go 1 introduces a new basic type, rune, to represent +individual Unicode code points. +It is an alias for int32, analogous to byte +as an alias for uint8. +

+ +

+Character literals such as 'a', '語', and '\u0345' +now have default type rune, +analogous to 1.0 having default type float64. +A variable initialized to a character constant will therefore +have type rune unless otherwise specified. +

+ +

+Libraries have been updated to use rune rather than int +when appropriate. For instance, the functions unicode.ToLower and +relatives now take and return a rune. +

+ +
    delta := 'δ' // delta has type rune.
+    var DELTA rune
+    DELTA = unicode.ToUpper(delta)
+    epsilon := unicode.ToLower(DELTA + 1)
+    if epsilon != 'δ'+1 {
+        log.Fatal("inconsistent casing for Greek")
+    }
+ +

+Updating: +Most source code will be unaffected by this because the type inference from +:= initializers introduces the new type silently, and it propagates +from there. +Some code may get type errors that a trivial conversion will resolve. +

+ +

The error type

+ +

+Go 1 introduces a new built-in type, error, which has the following definition: +

+ +
+    type error interface {
+        Error() string
+    }
+
+ +

+Since the consequences of this type are all in the package library, +it is discussed below. +

+ +

Deleting from maps

+ +

+In the old language, to delete the entry with key k from map m, one wrote the statement, +

+ +
+    m[k] = value, false
+
+ +

+This syntax was a peculiar special case, the only two-to-one assignment. +It required passing a value (usually ignored) that is evaluated but discarded, +plus a boolean that was nearly always the constant false. +It did the job but was odd and a point of contention. +

+ +

+In Go 1, that syntax has gone; instead there is a new built-in +function, delete. The call +

+ +
    delete(m, k)
+ +

+will delete the map entry retrieved by the expression m[k]. +There is no return value. Deleting a non-existent entry is a no-op. +

+ +

+Updating: +Running go fix will convert expressions of the form m[k] = value, +false into delete(m, k) when it is clear that +the ignored value can be safely discarded from the program and +false refers to the predefined boolean constant. +The fix tool +will flag other uses of the syntax for inspection by the programmer. +

+ +

Iterating in maps

+ +

+The old language specification did not define the order of iteration for maps, +and in practice it differed across hardware platforms. +This caused tests that iterated over maps to be fragile and non-portable, with the +unpleasant property that a test might always pass on one machine but break on another. +

+ +

+In Go 1, the order in which elements are visited when iterating +over a map using a for range statement +is defined to be unpredictable, even if the same loop is run multiple +times with the same map. +Code should not assume that the elements are visited in any particular order. +

+ +

+This change means that code that depends on iteration order is very likely to break early and be fixed long before it becomes a problem. +Just as important, it allows the map implementation to ensure better map balancing even when programs are using range loops to select an element from a map. +

+ +
    m := map[string]int{"Sunday": 0, "Monday": 1}
+    for name, value := range m {
+        // This loop should not assume Sunday will be visited first.
+        f(name, value)
+    }
+ +

+Updating: +This is one change where tools cannot help. Most existing code +will be unaffected, but some programs may break or misbehave; we +recommend manual checking of all range statements over maps to +verify they do not depend on iteration order. There were a few such +examples in the standard repository; they have been fixed. +Note that it was already incorrect to depend on the iteration order, which +was unspecified. This change codifies the unpredictability. +

+ +

Multiple assignment

+ +

+The language specification has long guaranteed that in assignments +the right-hand-side expressions are all evaluated before any left-hand-side expressions are assigned. +To guarantee predictable behavior, +Go 1 refines the specification further. +

+ +

+If the left-hand side of the assignment +statement contains expressions that require evaluation, such as +function calls or array indexing operations, these will all be done +using the usual left-to-right rule before any variables are assigned +their value. Once everything is evaluated, the actual assignments +proceed in left-to-right order. +

+ +

+These examples illustrate the behavior. +

+ +
    sa := []int{1, 2, 3}
+    i := 0
+    i, sa[i] = 1, 2 // sets i = 1, sa[0] = 2
+
+    sb := []int{1, 2, 3}
+    j := 0
+    sb[j], j = 2, 1 // sets sb[0] = 2, j = 1
+
+    sc := []int{1, 2, 3}
+    sc[0], sc[0] = 1, 2 // sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)
+ +

+Updating: +This is one change where tools cannot help, but breakage is unlikely. +No code in the standard repository was broken by this change, and code +that depended on the previous unspecified behavior was already incorrect. +

+ +

Returns and shadowed variables

+ +

+A common mistake is to use return (without arguments) after an assignment to a variable that has the same name as a result variable but is not the same variable. +This situation is called shadowing: the result variable has been shadowed by another variable with the same name declared in an inner scope. +

+ +

+In functions with named return values, +the Go 1 compilers disallow return statements without arguments if any of the named return values is shadowed at the point of the return statement. +(It isn't part of the specification, because this is one area we are still exploring; +the situation is analogous to the compilers rejecting functions that do not end with an explicit return statement.) +

+ +

+This function implicitly returns a shadowed return value and will be rejected by the compiler: +

+ +
+    func Bug() (i, j, k int) {
+        for i = 0; i < 5; i++ {
+            for j := 0; j < 5; j++ { // Redeclares j.
+                k += i*j
+                if k > 100 {
+                    return // Rejected: j is shadowed here.
+                }
+            }
+        }
+        return // OK: j is not shadowed here.
+    }
+
+ +

+Updating: +Code that shadows return values in this way will be rejected by the compiler and will need to be fixed by hand. +The few cases that arose in the standard repository were mostly bugs. +

+ +

Copying structs with unexported fields

+ +

+The old language did not allow a package to make a copy of a struct value containing unexported fields belonging to a different package. +There was, however, a required exception for a method receiver; +also, the implementations of copy and append have never honored the restriction. +

+ +

+Go 1 will allow packages to copy struct values containing unexported fields from other packages. +Besides resolving the inconsistency, +this change admits a new kind of API: a package can return an opaque value without resorting to a pointer or interface. +The new implementations of time.Time and +reflect.Value are examples of types taking advantage of this new property. +

+ +

+As an example, if package p includes the definitions, +

+ +
+    type Struct struct {
+        Public int
+        secret int
+    }
+    func NewStruct(a int) Struct {  // Note: not a pointer.
+        return Struct{a, f(a)}
+    }
+    func (s Struct) String() string {
+        return fmt.Sprintf("{%d (secret %d)}", s.Public, s.secret)
+    }
+
+ +

+a package that imports p can assign and copy values of type +p.Struct at will. +Behind the scenes the unexported fields will be assigned and copied just +as if they were exported, +but the client code will never be aware of them. The code +

+ +
+    import "p"
+
+    myStruct := p.NewStruct(23)
+    copyOfMyStruct := myStruct
+    fmt.Println(myStruct, copyOfMyStruct)
+
+ +

+will show that the secret field of the struct has been copied to the new value. +

+ +

+Updating: +This is a new feature, so existing code needs no changes. +

+ +

Equality

+ +

+Before Go 1, the language did not define equality on struct and array values. +This meant, +among other things, that structs and arrays could not be used as map keys. +On the other hand, Go did define equality on function and map values. +Function equality was problematic in the presence of closures +(when are two closures equal?) +while map equality compared pointers, not the maps' content, which was usually +not what the user would want. +

+ +

+Go 1 addressed these issues. +First, structs and arrays can be compared for equality and inequality +(== and !=), +and therefore be used as map keys, +provided they are composed from elements for which equality is also defined, +using element-wise comparison. +

+ +
    type Day struct {
+        long  string
+        short string
+    }
+    Christmas := Day{"Christmas", "XMas"}
+    Thanksgiving := Day{"Thanksgiving", "Turkey"}
+    holiday := map[Day]bool{
+        Christmas:    true,
+        Thanksgiving: true,
+    }
+    fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])
+ +

+Second, Go 1 removes the definition of equality for function values, +except for comparison with nil. +Finally, map equality is gone too, also except for comparison with nil. +

+ +

+Note that equality is still undefined for slices, for which the +calculation is in general infeasible. Also note that the ordered +comparison operators (< <= +> >=) are still undefined for +structs and arrays. + +

+Updating: +Struct and array equality is a new feature, so existing code needs no changes. +Existing code that depends on function or map equality will be +rejected by the compiler and will need to be fixed by hand. +Few programs will be affected, but the fix may require some +redesign. +

+ +

The package hierarchy

+ +

+Go 1 addresses many deficiencies in the old standard library and +cleans up a number of packages, making them more internally consistent +and portable. +

+ +

+This section describes how the packages have been rearranged in Go 1. +Some have moved, some have been renamed, some have been deleted. +New packages are described in later sections. +

+ +

The package hierarchy

+ +

+Go 1 has a rearranged package hierarchy that groups related items +into subdirectories. For instance, utf8 and +utf16 now occupy subdirectories of unicode. +Also, some packages have moved into +subrepositories of +code.google.com/p/go +while others have been deleted outright. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Old pathNew path

asn1 encoding/asn1
csv encoding/csv
gob encoding/gob
json encoding/json
xml encoding/xml

exp/template/html html/template

big math/big
cmath math/cmplx
rand math/rand

http net/http
http/cgi net/http/cgi
http/fcgi net/http/fcgi
http/httptest net/http/httptest
http/pprof net/http/pprof
mail net/mail
rpc net/rpc
rpc/jsonrpc net/rpc/jsonrpc
smtp net/smtp
url net/url

exec os/exec

scanner text/scanner
tabwriter text/tabwriter
template text/template
template/parse text/template/parse

utf8 unicode/utf8
utf16 unicode/utf16
+ +

+Note that the package names for the old cmath and +exp/template/html packages have changed to cmplx +and template. +

+ +

+Updating: +Running go fix will update all imports and package renames for packages that +remain inside the standard repository. Programs that import packages +that are no longer in the standard repository will need to be edited +by hand. +

+ +

The package tree exp

+ +

+Because they are not standardized, the packages under the exp directory will not be available in the +standard Go 1 release distributions, although they will be available in source code form +in the repository for +developers who wish to use them. +

+ +

+Several packages have moved under exp at the time of Go 1's release: +

+ +
    +
  • ebnf
  • +
  • html
  • +
  • go/types
  • +
+ +

+(The EscapeString and UnescapeString types remain +in package html.) +

+ +

+All these packages are available under the same names, with the prefix exp/: exp/ebnf etc. +

+ +

+Also, the utf8.String type has been moved to its own package, exp/utf8string. +

+ +

+Finally, the gotype command now resides in exp/gotype, while +ebnflint is now in exp/ebnflint. +If they are installed, they now reside in $GOROOT/bin/tool. +

+ +

+Updating: +Code that uses packages in exp will need to be updated by hand, +or else compiled from an installation that has exp available. +The go fix tool or the compiler will complain about such uses. +

+ +

The package tree old

+ +

+Because they are deprecated, the packages under the old directory will not be available in the +standard Go 1 release distributions, although they will be available in source code form for +developers who wish to use them. +

+ +

+The packages in their new locations are: +

+ +
    +
  • old/netchan
  • +
  • old/regexp
  • +
  • old/template
  • +
+ +

+Updating: +Code that uses packages now in old will need to be updated by hand, +or else compiled from an installation that has old available. +The go fix tool will warn about such uses. +

+ +

Deleted packages

+ +

+Go 1 deletes several packages outright: +

+ +
    +
  • container/vector
  • +
  • exp/datafmt
  • +
  • go/typechecker
  • +
  • try
  • +
+ +

+and also the command gotry. +

+ +

+Updating: +Code that uses container/vector should be updated to use +slices directly. See +the Go +Language Community Wiki for some suggestions. +Code that uses the other packages (there should be almost zero) will need to be rethought. +

+ +

Packages moving to subrepositories

+ +

+Go 1 has moved a number of packages into other repositories, usually sub-repositories of +the main Go repository. +This table lists the old and new import paths: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OldNew

crypto/bcrypt code.google.com/p/go.crypto/bcrypt
crypto/blowfish code.google.com/p/go.crypto/blowfish
crypto/cast5 code.google.com/p/go.crypto/cast5
crypto/md4 code.google.com/p/go.crypto/md4
crypto/ocsp code.google.com/p/go.crypto/ocsp
crypto/openpgp code.google.com/p/go.crypto/openpgp
crypto/openpgp/armor code.google.com/p/go.crypto/openpgp/armor
crypto/openpgp/elgamal code.google.com/p/go.crypto/openpgp/elgamal
crypto/openpgp/errors code.google.com/p/go.crypto/openpgp/errors
crypto/openpgp/packet code.google.com/p/go.crypto/openpgp/packet
crypto/openpgp/s2k code.google.com/p/go.crypto/openpgp/s2k
crypto/ripemd160 code.google.com/p/go.crypto/ripemd160
crypto/twofish code.google.com/p/go.crypto/twofish
crypto/xtea code.google.com/p/go.crypto/xtea
exp/ssh code.google.com/p/go.crypto/ssh

image/bmp code.google.com/p/go.image/bmp
image/tiff code.google.com/p/go.image/tiff

net/dict code.google.com/p/go.net/dict
net/websocket code.google.com/p/go.net/websocket
exp/spdy code.google.com/p/go.net/spdy

encoding/git85 code.google.com/p/go.codereview/git85
patch code.google.com/p/go.codereview/patch

exp/wingui code.google.com/p/gowingui
+ +

+Updating: +Running go fix will update imports of these packages to use the new import paths. +Installations that depend on these packages will need to install them using +a go get command. +

+ +

Major changes to the library

+ +

+This section describes significant changes to the core libraries, the ones that +affect the most programs. +

+ +

The error type and errors package

+ +

+The placement of os.Error in package os is mostly historical: errors first came up when implementing package os, and they seemed system-related at the time. +Since then it has become clear that errors are more fundamental than the operating system. For example, it would be nice to use Errors in packages that os depends on, like syscall. +Also, having Error in os introduces many dependencies on os that would otherwise not exist. +

+ +

+Go 1 solves these problems by introducing a built-in error interface type and a separate errors package (analogous to bytes and strings) that contains utility functions. +It replaces os.NewError with +errors.New, +giving errors a more central place in the environment. +

+ +

+So the widely-used String method does not cause accidental satisfaction +of the error interface, the error interface uses instead +the name Error for that method: +

+ +
+    type error interface {
+        Error() string
+    }
+
+ +

+The fmt library automatically invokes Error, as it already +does for String, for easy printing of error values. +

+ +
type SyntaxError struct {
+    File    string
+    Line    int
+    Message string
+}
+
+func (se *SyntaxError) Error() string {
+    return fmt.Sprintf("%s:%d: %s", se.File, se.Line, se.Message)
+}
+ +

+All standard packages have been updated to use the new interface; the old os.Error is gone. +

+ +

+A new package, errors, contains the function +

+ +
+func New(text string) error
+
+ +

+to turn a string into an error. It replaces the old os.NewError. +

+ +
    var ErrSyntax = errors.New("syntax error")
+ +

+Updating: +Running go fix will update almost all code affected by the change. +Code that defines error types with a String method will need to be updated +by hand to rename the methods to Error. +

+ +

System call errors

+ +

+The old syscall package, which predated os.Error +(and just about everything else), +returned errors as int values. +In turn, the os package forwarded many of these errors, such +as EINVAL, but using a different set of errors on each platform. +This behavior was unpleasant and unportable. +

+ +

+In Go 1, the +syscall +package instead returns an error for system call errors. +On Unix, the implementation is done by a +syscall.Errno type +that satisfies error and replaces the old os.Errno. +

+ +

+The changes affecting os.EINVAL and relatives are +described elsewhere. + +

+Updating: +Running go fix will update almost all code affected by the change. +Regardless, most code should use the os package +rather than syscall and so will be unaffected. +

+ +

Time

+ +

+Time is always a challenge to support well in a programming language. +The old Go time package had int64 units, no +real type safety, +and no distinction between absolute times and durations. +

+ +

+One of the most sweeping changes in the Go 1 library is therefore a +complete redesign of the +time package. +Instead of an integer number of nanoseconds as an int64, +and a separate *time.Time type to deal with human +units such as hours and years, +there are now two fundamental types: +time.Time +(a value, so the * is gone), which represents a moment in time; +and time.Duration, +which represents an interval. +Both have nanosecond resolution. +A Time can represent any time into the ancient +past and remote future, while a Duration can +span plus or minus only about 290 years. +There are methods on these types, plus a number of helpful +predefined constant durations such as time.Second. +

+ +

+Among the new methods are things like +Time.Add, +which adds a Duration to a Time, and +Time.Sub, +which subtracts two Times to yield a Duration. +

+ +

+The most important semantic change is that the Unix epoch (Jan 1, 1970) is now +relevant only for those functions and methods that mention Unix: +time.Unix +and the Unix +and UnixNano methods +of the Time type. +In particular, +time.Now +returns a time.Time value rather than, in the old +API, an integer nanosecond count since the Unix epoch. +

+ +
// sleepUntil sleeps until the specified time. It returns immediately if it's too late.
+func sleepUntil(wakeup time.Time) {
+    now := time.Now() // A Time.
+    if !wakeup.After(now) {
+        return
+    }
+    delta := wakeup.Sub(now) // A Duration.
+    fmt.Printf("Sleeping for %.3fs\n", delta.Seconds())
+    time.Sleep(delta)
+}
+ +

+The new types, methods, and constants have been propagated through +all the standard packages that use time, such as os and +its representation of file time stamps. +

+ +

+Updating: +The go fix tool will update many uses of the old time package to use the new +types and methods, although it does not replace values such as 1e9 +representing nanoseconds per second. +Also, because of type changes in some of the values that arise, +some of the expressions rewritten by the fix tool may require +further hand editing; in such cases the rewrite will include +the correct function or method for the old functionality, but +may have the wrong type or require further analysis. +

+ +

Minor changes to the library

+ +

+This section describes smaller changes, such as those to less commonly +used packages or that affect +few programs beyond the need to run go fix. +This category includes packages that are new in Go 1. +Collectively they improve portability, regularize behavior, and +make the interfaces more modern and Go-like. +

+ +

The archive/zip package

+ +

+In Go 1, *zip.Writer no +longer has a Write method. Its presence was a mistake. +

+ +

+Updating: +What little code is affected will be caught by the compiler and must be updated by hand. +

+ +

The bufio package

+ +

+In Go 1, bufio.NewReaderSize +and +bufio.NewWriterSize +functions no longer return an error for invalid sizes. +If the argument size is too small or invalid, it is adjusted. +

+ +

+Updating: +Running go fix will update calls that assign the error to _. +Calls that aren't fixed will be caught by the compiler and must be updated by hand. +

+ +

The compress/flate, compress/gzip and compress/zlib packages

+ +

+In Go 1, the NewWriterXxx functions in +compress/flate, +compress/gzip and +compress/zlib +all return (*Writer, error) if they take a compression level, +and *Writer otherwise. Package gzip's +Compressor and Decompressor types have been renamed +to Writer and Reader. Package flate's +WrongValueError type has been removed. +

+ +

+Updating +Running go fix will update old names and calls that assign the error to _. +Calls that aren't fixed will be caught by the compiler and must be updated by hand. +

+ +

The crypto/aes and crypto/des packages

+ +

+In Go 1, the Reset method has been removed. Go does not guarantee +that memory is not copied and therefore this method was misleading. +

+ +

+The cipher-specific types *aes.Cipher, *des.Cipher, +and *des.TripleDESCipher have been removed in favor of +cipher.Block. +

+ +

+Updating: +Remove the calls to Reset. Replace uses of the specific cipher types with +cipher.Block. +

+ +

The crypto/elliptic package

+ +

+In Go 1, elliptic.Curve +has been made an interface to permit alternative implementations. The curve +parameters have been moved to the +elliptic.CurveParams +structure. +

+ +

+Updating: +Existing users of *elliptic.Curve will need to change to +simply elliptic.Curve. Calls to Marshal, +Unmarshal and GenerateKey are now functions +in crypto/elliptic that take an elliptic.Curve +as their first argument. +

+ +

The crypto/hmac package

+ +

+In Go 1, the hash-specific functions, such as hmac.NewMD5, have +been removed from crypto/hmac. Instead, hmac.New takes +a function that returns a hash.Hash, such as md5.New. +

+ +

+Updating: +Running go fix will perform the needed changes. +

+ +

The crypto/x509 package

+ +

+In Go 1, the +CreateCertificate +and +CreateCRL +functions in crypto/x509 have been altered to take an +interface{} where they previously took a *rsa.PublicKey +or *rsa.PrivateKey. This will allow other public key algorithms +to be implemented in the future. +

+ +

+Updating: +No changes will be needed. +

+ +

The encoding/binary package

+ +

+In Go 1, the binary.TotalSize function has been replaced by +Size, +which takes an interface{} argument rather than +a reflect.Value. +

+ +

+Updating: +What little code is affected will be caught by the compiler and must be updated by hand. +

+ +

The encoding/xml package

+ +

+In Go 1, the xml package +has been brought closer in design to the other marshaling packages such +as encoding/gob. +

+ +

+The old Parser type is renamed +Decoder and has a new +Decode method. An +Encoder type was also introduced. +

+ +

+The functions Marshal +and Unmarshal +work with []byte values now. To work with streams, +use the new Encoder +and Decoder types. +

+ +

+When marshaling or unmarshaling values, the format of supported flags in +field tags has changed to be closer to the +json package +(`xml:"name,flag"`). The matching done between field tags, field +names, and the XML attribute and element names is now case-sensitive. +The XMLName field tag, if present, must also match the name +of the XML element being marshaled. +

+ +

+Updating: +Running go fix will update most uses of the package except for some calls to +Unmarshal. Special care must be taken with field tags, +since the fix tool will not update them and if not fixed by hand they will +misbehave silently in some cases. For example, the old +"attr" is now written ",attr" while plain +"attr" remains valid but with a different meaning. +

+ +

The expvar package

+ +

+In Go 1, the RemoveAll function has been removed. +The Iter function and Iter method on *Map have +been replaced by +Do +and +(*Map).Do. +

+ +

+Updating: +Most code using expvar will not need changing. The rare code that used +Iter can be updated to pass a closure to Do to achieve the same effect. +

+ +

The flag package

+ +

+In Go 1, the interface flag.Value has changed slightly. +The Set method now returns an error instead of +a bool to indicate success or failure. +

+ +

+There is also a new kind of flag, Duration, to support argument +values specifying time intervals. +Values for such flags must be given units, just as time.Duration +formats them: 10s, 1h30m, etc. +

+ +
var timeout = flag.Duration("timeout", 30*time.Second, "how long to wait for completion")
+ +

+Updating: +Programs that implement their own flags will need minor manual fixes to update their +Set methods. +The Duration flag is new and affects no existing code. +

+ + +

The go/* packages

+ +

+Several packages under go have slightly revised APIs. +

+ +

+A concrete Mode type was introduced for configuration mode flags +in the packages +go/scanner, +go/parser, +go/printer, and +go/doc. +

+ +

+The modes AllowIllegalChars and InsertSemis have been removed +from the go/scanner package. They were mostly +useful for scanning text other then Go source files. Instead, the +text/scanner package should be used +for that purpose. +

+ +

+The ErrorHandler provided +to the scanner's Init method is +now simply a function rather than an interface. The ErrorVector type has +been removed in favor of the (existing) ErrorList +type, and the ErrorVector methods have been migrated. Instead of embedding +an ErrorVector in a client of the scanner, now a client should maintain +an ErrorList. +

+ +

+The set of parse functions provided by the go/parser +package has been reduced to the primary parse function +ParseFile, and a couple of +convenience functions ParseDir +and ParseExpr. +

+ +

+The go/printer package supports an additional +configuration mode SourcePos; +if set, the printer will emit //line comments such that the generated +output contains the original source code position information. The new type +CommentedNode can be +used to provide comments associated with an arbitrary +ast.Node (until now only +ast.File carried comment information). +

+ +

+The type names of the go/doc package have been +streamlined by removing the Doc suffix: PackageDoc +is now Package, ValueDoc is Value, etc. +Also, all types now consistently have a Name field (or Names, +in the case of type Value) and Type.Factories has become +Type.Funcs. +Instead of calling doc.NewPackageDoc(pkg, importpath), +documentation for a package is created with: +

+ +
+    doc.New(pkg, importpath, mode)
+
+ +

+where the new mode parameter specifies the operation mode: +if set to AllDecls, all declarations +(not just exported ones) are considered. +The function NewFileDoc was removed, and the function +CommentText has become the method +Text of +ast.CommentGroup. +

+ +

+In package go/token, the +token.FileSet method Files +(which originally returned a channel of *token.Files) has been replaced +with the iterator Iterate that +accepts a function argument instead. +

+ +

+In package go/build, the API +has been nearly completely replaced. +The package still computes Go package information +but it does not run the build: the Cmd and Script +types are gone. +(To build code, use the new +go command instead.) +The DirInfo type is now named +Package. +FindTree and ScanDir are replaced by +Import +and +ImportDir. +

+ +

+Updating: +Code that uses packages in go will have to be updated by hand; the +compiler will reject incorrect uses. Templates used in conjunction with any of the +go/doc types may need manual fixes; the renamed fields will lead +to run-time errors. +

+ +

The hash package

+ +

+In Go 1, the definition of hash.Hash includes +a new method, BlockSize. This new method is used primarily in the +cryptographic libraries. +

+ +

+The Sum method of the +hash.Hash interface now takes a +[]byte argument, to which the hash value will be appended. +The previous behavior can be recreated by adding a nil argument to the call. +

+ +

+Updating: +Existing implementations of hash.Hash will need to add a +BlockSize method. Hashes that process the input one byte at +a time can implement BlockSize to return 1. +Running go fix will update calls to the Sum methods of the various +implementations of hash.Hash. +

+ +

+Updating: +Since the package's functionality is new, no updating is necessary. +

+ +

The http package

+ +

+In Go 1 the http package is refactored, +putting some of the utilities into a +httputil subdirectory. +These pieces are only rarely needed by HTTP clients. +The affected items are: +

+ +
    +
  • ClientConn
  • +
  • DumpRequest
  • +
  • DumpRequestOut
  • +
  • DumpResponse
  • +
  • NewChunkedReader
  • +
  • NewChunkedWriter
  • +
  • NewClientConn
  • +
  • NewProxyClientConn
  • +
  • NewServerConn
  • +
  • NewSingleHostReverseProxy
  • +
  • ReverseProxy
  • +
  • ServerConn
  • +
+ +

+The Request.RawURL field has been removed; it was a +historical artifact. +

+ +

+The Handle and HandleFunc +functions, and the similarly-named methods of ServeMux, +now panic if an attempt is made to register the same pattern twice. +

+ +

+Updating: +Running go fix will update the few programs that are affected except for +uses of RawURL, which must be fixed by hand. +

+ +

The image package

+ +

+The image package has had a number of +minor changes, rearrangements and renamings. +

+ +

+Most of the color handling code has been moved into its own package, +image/color. +For the elements that moved, a symmetry arises; for instance, +each pixel of an +image.RGBA +is a +color.RGBA. +

+ +

+The old image/ycbcr package has been folded, with some +renamings, into the +image +and +image/color +packages. +

+ +

+The old image.ColorImage type is still in the image +package but has been renamed +image.Uniform, +while image.Tiled has been removed. +

+ +

+This table lists the renamings. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OldNew

image.Color color.Color
image.ColorModel color.Model
image.ColorModelFunc color.ModelFunc
image.PalettedColorModel color.Palette

image.RGBAColor color.RGBA
image.RGBA64Color color.RGBA64
image.NRGBAColor color.NRGBA
image.NRGBA64Color color.NRGBA64
image.AlphaColor color.Alpha
image.Alpha16Color color.Alpha16
image.GrayColor color.Gray
image.Gray16Color color.Gray16

image.RGBAColorModel color.RGBAModel
image.RGBA64ColorModel color.RGBA64Model
image.NRGBAColorModel color.NRGBAModel
image.NRGBA64ColorModel color.NRGBA64Model
image.AlphaColorModel color.AlphaModel
image.Alpha16ColorModel color.Alpha16Model
image.GrayColorModel color.GrayModel
image.Gray16ColorModel color.Gray16Model

ycbcr.RGBToYCbCr color.RGBToYCbCr
ycbcr.YCbCrToRGB color.YCbCrToRGB
ycbcr.YCbCrColorModel color.YCbCrModel
ycbcr.YCbCrColor color.YCbCr
ycbcr.YCbCr image.YCbCr

ycbcr.SubsampleRatio444 image.YCbCrSubsampleRatio444
ycbcr.SubsampleRatio422 image.YCbCrSubsampleRatio422
ycbcr.SubsampleRatio420 image.YCbCrSubsampleRatio420

image.ColorImage image.Uniform
+ +

+The image package's New functions +(NewRGBA, +NewRGBA64, etc.) +take an image.Rectangle as an argument +instead of four integers. +

+ +

+Finally, there are new predefined color.Color variables +color.Black, +color.White, +color.Opaque +and +color.Transparent. +

+ +

+Updating: +Running go fix will update almost all code affected by the change. +

+ +

The log/syslog package

+ +

+In Go 1, the syslog.NewLogger +function returns an error as well as a log.Logger. +

+ +

+Updating: +What little code is affected will be caught by the compiler and must be updated by hand. +

+ +

The mime package

+ +

+In Go 1, the FormatMediaType function +of the mime package has been simplified to make it +consistent with +ParseMediaType. +It now takes "text/html" rather than "text" and "html". +

+ +

+Updating: +What little code is affected will be caught by the compiler and must be updated by hand. +

+ +

The net package

+ +

+In Go 1, the various SetTimeout, +SetReadTimeout, and SetWriteTimeout methods +have been replaced with +SetDeadline, +SetReadDeadline, and +SetWriteDeadline, +respectively. Rather than taking a timeout value in nanoseconds that +apply to any activity on the connection, the new methods set an +absolute deadline (as a time.Time value) after which +reads and writes will time out and no longer block. +

+ +

+There are also new functions +net.DialTimeout +to simplify timing out dialing a network address and +net.ListenMulticastUDP +to allow multicast UDP to listen concurrently across multiple listeners. +The net.ListenMulticastUDP function replaces the old +JoinGroup and LeaveGroup methods. +

+ +

+Updating: +Code that uses the old methods will fail to compile and must be updated by hand. +The semantic change makes it difficult for the fix tool to update automatically. +

+ +

The os package

+ +

+The Time function has been removed; callers should use +the Time type from the +time package. +

+ +

+The Exec function has been removed; callers should use +Exec from the syscall package, where available. +

+ +

+The ShellExpand function has been renamed to ExpandEnv. +

+ +

+The NewFile function +now takes a uintptr fd, instead of an int. +The Fd method on files now +also returns a uintptr. +

+ +

+There are no longer error constants such as EINVAL +in the os package, since the set of values varied with +the underlying operating system. There are new portable functions like +IsPermission +to test common error properties, plus a few new error values +with more Go-like names, such as +ErrPermission +and +ErrNoEnv. +

+ +

+The Getenverror function has been removed. To distinguish +between a non-existent environment variable and an empty string, +use os.Environ or +syscall.Getenv. +

+ + +

+The Process.Wait method has +dropped its option argument and the associated constants are gone +from the package. +Also, the function Wait is gone; only the method of +the Process type persists. +

+ +

+The Waitmsg type returned by +Process.Wait +has been replaced with a more portable +ProcessState +type with accessor methods to recover information about the +process. +Because of changes to Wait, the ProcessState +value always describes an exited process. +Portability concerns simplified the interface in other ways, but the values returned by the +ProcessState.Sys and +ProcessState.SysUsage +methods can be type-asserted to underlying system-specific data structures such as +syscall.WaitStatus and +syscall.Rusage on Unix. +

+ +

+Updating: +Running go fix will drop a zero argument to Process.Wait. +All other changes will be caught by the compiler and must be updated by hand. +

+ +

The os.FileInfo type

+ +

+Go 1 redefines the os.FileInfo type, +changing it from a struct to an interface: +

+ +
+    type FileInfo interface {
+        Name() string       // base name of the file
+        Size() int64        // length in bytes
+        Mode() FileMode     // file mode bits
+        ModTime() time.Time // modification time
+        IsDir() bool        // abbreviation for Mode().IsDir()
+        Sys() interface{}   // underlying data source (can return nil)
+    }
+
+ +

+The file mode information has been moved into a subtype called +os.FileMode, +a simple integer type with IsDir, Perm, and String +methods. +

+ +

+The system-specific details of file modes and properties such as (on Unix) +i-number have been removed from FileInfo altogether. +Instead, each operating system's os package provides an +implementation of the FileInfo interface, which +has a Sys method that returns the +system-specific representation of file metadata. +For instance, to discover the i-number of a file on a Unix system, unpack +the FileInfo like this: +

+ +
+    fi, err := os.Stat("hello.go")
+    if err != nil {
+        log.Fatal(err)
+    }
+    // Check that it's a Unix file.
+    unixStat, ok := fi.Sys().(*syscall.Stat_t)
+    if !ok {
+        log.Fatal("hello.go: not a Unix file")
+    }
+    fmt.Printf("file i-number: %d\n", unixStat.Ino)
+
+ +

+Assuming (which is unwise) that "hello.go" is a Unix file, +the i-number expression could be contracted to +

+ +
+    fi.Sys().(*syscall.Stat_t).Ino
+
+ +

+The vast majority of uses of FileInfo need only the methods +of the standard interface. +

+ +

+The os package no longer contains wrappers for the POSIX errors +such as ENOENT. +For the few programs that need to verify particular error conditions, there are +now the boolean functions +IsExist, +IsNotExist +and +IsPermission. +

+ +
    f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
+    if os.IsExist(err) {
+        log.Printf("%s already exists", name)
+    }
+ +

+Updating: +Running go fix will update code that uses the old equivalent of the current os.FileInfo +and os.FileMode API. +Code that needs system-specific file details will need to be updated by hand. +Code that uses the old POSIX error values from the os package +will fail to compile and will also need to be updated by hand. +

+ +

The os/signal package

+ +

+The os/signal package in Go 1 replaces the +Incoming function, which returned a channel +that received all incoming signals, +with the selective Notify function, which asks +for delivery of specific signals on an existing channel. +

+ +

+Updating: +Code must be updated by hand. +A literal translation of +

+
+c := signal.Incoming()
+
+

+is +

+
+c := make(chan os.Signal)
+signal.Notify(c) // ask for all signals
+
+

+but most code should list the specific signals it wants to handle instead: +

+
+c := make(chan os.Signal)
+signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT)
+
+ +

The path/filepath package

+ +

+In Go 1, the Walk function of the +path/filepath package +has been changed to take a function value of type +WalkFunc +instead of a Visitor interface value. +WalkFunc unifies the handling of both files and directories. +

+ +
+    type WalkFunc func(path string, info os.FileInfo, err error) error
+
+ +

+The WalkFunc function will be called even for files or directories that could not be opened; +in such cases the error argument will describe the failure. +If a directory's contents are to be skipped, +the function should return the value filepath.SkipDir +

+ +
    markFn := func(path string, info os.FileInfo, err error) error {
+        if path == "pictures" { // Will skip walking of directory pictures and its contents.
+            return filepath.SkipDir
+        }
+        if err != nil {
+            return err
+        }
+        log.Println(path)
+        return nil
+    }
+    err := filepath.Walk(".", markFn)
+    if err != nil {
+        log.Fatal(err)
+    }
+ +

+Updating: +The change simplifies most code but has subtle consequences, so affected programs +will need to be updated by hand. +The compiler will catch code using the old interface. +

+ +

The regexp package

+ +

+The regexp package has been rewritten. +It has the same interface but the specification of the regular expressions +it supports has changed from the old "egrep" form to that of +RE2. +

+ +

+Updating: +Code that uses the package should have its regular expressions checked by hand. +

+ +

The runtime package

+ +

+In Go 1, much of the API exported by package +runtime has been removed in favor of +functionality provided by other packages. +Code using the runtime.Type interface +or its specific concrete type implementations should +now use package reflect. +Code using runtime.Semacquire or runtime.Semrelease +should use channels or the abstractions in package sync. +The runtime.Alloc, runtime.Free, +and runtime.Lookup functions, an unsafe API created for +debugging the memory allocator, have no replacement. +

+ +

+Before, runtime.MemStats was a global variable holding +statistics about memory allocation, and calls to runtime.UpdateMemStats +ensured that it was up to date. +In Go 1, runtime.MemStats is a struct type, and code should use +runtime.ReadMemStats +to obtain the current statistics. +

+ +

+The package adds a new function, +runtime.NumCPU, that returns the number of CPUs available +for parallel execution, as reported by the operating system kernel. +Its value can inform the setting of GOMAXPROCS. +The runtime.Cgocalls and runtime.Goroutines functions +have been renamed to runtime.NumCgoCall and runtime.NumGoroutine. +

+ +

+Updating: +Running go fix will update code for the function renamings. +Other code will need to be updated by hand. +

+ +

The strconv package

+ +

+In Go 1, the +strconv +package has been significantly reworked to make it more Go-like and less C-like, +although Atoi lives on (it's similar to +int(ParseInt(x, 10, 0)), as does +Itoa(x) (FormatInt(int64(x), 10)). +There are also new variants of some of the functions that append to byte slices rather than +return strings, to allow control over allocation. +

+ +

+This table summarizes the renamings; see the +package documentation +for full details. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Old callNew call

Atob(x) ParseBool(x)

Atof32(x) ParseFloat(x, 32)§
Atof64(x) ParseFloat(x, 64)
AtofN(x, n) ParseFloat(x, n)

Atoi(x) Atoi(x)
Atoi(x) ParseInt(x, 10, 0)§
Atoi64(x) ParseInt(x, 10, 64)

Atoui(x) ParseUint(x, 10, 0)§
Atoui64(x) ParseUint(x, 10, 64)

Btoi64(x, b) ParseInt(x, b, 64)
Btoui64(x, b) ParseUint(x, b, 64)

Btoa(x) FormatBool(x)

Ftoa32(x, f, p) FormatFloat(float64(x), f, p, 32)
Ftoa64(x, f, p) FormatFloat(x, f, p, 64)
FtoaN(x, f, p, n) FormatFloat(x, f, p, n)

Itoa(x) Itoa(x)
Itoa(x) FormatInt(int64(x), 10)
Itoa64(x) FormatInt(x, 10)

Itob(x, b) FormatInt(int64(x), b)
Itob64(x, b) FormatInt(x, b)

Uitoa(x) FormatUint(uint64(x), 10)
Uitoa64(x) FormatUint(x, 10)

Uitob(x, b) FormatUint(uint64(x), b)
Uitob64(x, b) FormatUint(x, b)
+ +

+Updating: +Running go fix will update almost all code affected by the change. +
Atoi persists but Atoui and Atof32 do not, so +they may require +a cast that must be added by hand; the go fix tool will warn about it. +

+ + +

The template packages

+ +

+The template and exp/template/html packages have moved to +text/template and +html/template. +More significant, the interface to these packages has been simplified. +The template language is the same, but the concept of "template set" is gone +and the functions and methods of the packages have changed accordingly, +often by elimination. +

+ +

+Instead of sets, a Template object +may contain multiple named template definitions, +in effect constructing +name spaces for template invocation. +A template can invoke any other template associated with it, but only those +templates associated with it. +The simplest way to associate templates is to parse them together, something +made easier with the new structure of the packages. +

+ +

+Updating: +The imports will be updated by fix tool. +Single-template uses will be otherwise be largely unaffected. +Code that uses multiple templates in concert will need to be updated by hand. +The examples in +the documentation for text/template can provide guidance. +

+ +

The testing package

+ +

+The testing package has a type, B, passed as an argument to benchmark functions. +In Go 1, B has new methods, analogous to those of T, enabling +logging and failure reporting. +

+ +
func BenchmarkSprintf(b *testing.B) {
+    // Verify correctness before running benchmark.
+    b.StopTimer()
+    got := fmt.Sprintf("%x", 23)
+    const expect = "17"
+    if expect != got {
+        b.Fatalf("expected %q; got %q", expect, got)
+    }
+    b.StartTimer()
+    for i := 0; i < b.N; i++ {
+        fmt.Sprintf("%x", 23)
+    }
+}
+ +

+Updating: +Existing code is unaffected, although benchmarks that use println +or panic should be updated to use the new methods. +

+ +

The testing/script package

+ +

+The testing/script package has been deleted. It was a dreg. +

+ +

+Updating: +No code is likely to be affected. +

+ +

The unsafe package

+ +

+In Go 1, the functions +unsafe.Typeof, unsafe.Reflect, +unsafe.Unreflect, unsafe.New, and +unsafe.NewArray have been removed; +they duplicated safer functionality provided by +package reflect. +

+ +

+Updating: +Code using these functions must be rewritten to use +package reflect. +The changes to encoding/gob and the protocol buffer library +may be helpful as examples. +

+ +

The url package

+ +

+In Go 1 several fields from the url.URL type +were removed or replaced. +

+ +

+The String method now +predictably rebuilds an encoded URL string using all of URL's +fields as necessary. The resulting string will also no longer have +passwords escaped. +

+ +

+The Raw field has been removed. In most cases the String +method may be used in its place. +

+ +

+The old RawUserinfo field is replaced by the User +field, of type *net.Userinfo. +Values of this type may be created using the new net.User +and net.UserPassword +functions. The EscapeUserinfo and UnescapeUserinfo +functions are also gone. +

+ +

+The RawAuthority field has been removed. The same information is +available in the Host and User fields. +

+ +

+The RawPath field and the EncodedPath method have +been removed. The path information in rooted URLs (with a slash following the +schema) is now available only in decoded form in the Path field. +Occasionally, the encoded data may be required to obtain information that +was lost in the decoding process. These cases must be handled by accessing +the data the URL was built from. +

+ +

+URLs with non-rooted paths, such as "mailto:dev@golang.org?subject=Hi", +are also handled differently. The OpaquePath boolean field has been +removed and a new Opaque string field introduced to hold the encoded +path for such URLs. In Go 1, the cited URL parses as: +

+ +
+    URL{
+        Scheme: "mailto",
+        Opaque: "dev@golang.org",
+        RawQuery: "subject=Hi",
+    }
+
+ +

+A new RequestURI method was +added to URL. +

+ +

+The ParseWithReference function has been renamed to ParseWithFragment. +

+ +

+Updating: +Code that uses the old fields will fail to compile and must be updated by hand. +The semantic changes make it difficult for the fix tool to update automatically. +

+ +

The go command

+ +

+Go 1 introduces the go command, a tool for fetching, +building, and installing Go packages and commands. The go command +does away with makefiles, instead using Go source code to find dependencies and +determine build conditions. Most existing Go programs will no longer require +makefiles to be built. +

+ +

+See How to Write Go Code for a primer on the +go command and the go command documentation +for the full details. +

+ +

+Updating: +Projects that depend on the Go project's old makefile-based build +infrastructure (Make.pkg, Make.cmd, and so on) should +switch to using the go command for building Go code and, if +necessary, rewrite their makefiles to perform any auxiliary build tasks. +

+ +

The cgo command

+ +

+In Go 1, the cgo command +uses a different _cgo_export.h +file, which is generated for packages containing //export lines. +The _cgo_export.h file now begins with the C preamble comment, +so that exported function definitions can use types defined there. +This has the effect of compiling the preamble multiple times, so a +package using //export must not put function definitions +or variable initializations in the C preamble. +

+ +

Packaged releases

+ +

+One of the most significant changes associated with Go 1 is the availability +of prepackaged, downloadable distributions. +They are available for many combinations of architecture and operating system +(including Windows) and the list will grow. +Installation details are described on the +Getting Started page, while +the distributions themselves are listed on the +downloads page. + + +

+ + + + + + + + diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/README b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/README new file mode 100644 index 000000000000..9b4c2d8be0a2 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/README @@ -0,0 +1,28 @@ +The *.dat files in this directory are copied from The WebKit Open Source +Project, specifically $WEBKITROOT/LayoutTests/html5lib/resources. +WebKit is licensed under a BSD style license. +http://webkit.org/coding/bsd-license.html says: + +Copyright (C) 2009 Apple Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/adoption01.dat b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/adoption01.dat new file mode 100644 index 000000000000..787e1b01e193 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/adoption01.dat @@ -0,0 +1,194 @@ +#data +

+#errors +#document +| +| +| +| +|

+| + +#data +1

23

+#errors +#document +| +| +| +| +| "1" +|

+| +| "2" +| "3" + +#data +1 +#errors +#document +| +| +| +| +| "1" +| +#errors +Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE. +Line: 1 Col: 20 Unexpected end tag (strong) in table context caused voodoo mode. +Line: 1 Col: 20 End tag (strong) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 24 Unexpected end tag (b) in table context caused voodoo mode. +Line: 1 Col: 24 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 29 Unexpected end tag (em) in table context caused voodoo mode. +Line: 1 Col: 29 End tag (em) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 33 Unexpected end tag (i) in table context caused voodoo mode. +Line: 1 Col: 33 End tag (i) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 37 Unexpected end tag (u) in table context caused voodoo mode. +Line: 1 Col: 37 End tag (u) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 46 Unexpected end tag (strike) in table context caused voodoo mode. +Line: 1 Col: 46 End tag (strike) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 50 Unexpected end tag (s) in table context caused voodoo mode. +Line: 1 Col: 50 End tag (s) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 58 Unexpected end tag (blink) in table context caused voodoo mode. +Line: 1 Col: 58 Unexpected end tag (blink). Ignored. +Line: 1 Col: 63 Unexpected end tag (tt) in table context caused voodoo mode. +Line: 1 Col: 63 End tag (tt) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 69 Unexpected end tag (pre) in table context caused voodoo mode. +Line: 1 Col: 69 End tag (pre) seen too early. Expected other end tag. +Line: 1 Col: 75 Unexpected end tag (big) in table context caused voodoo mode. +Line: 1 Col: 75 End tag (big) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 83 Unexpected end tag (small) in table context caused voodoo mode. +Line: 1 Col: 83 End tag (small) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 90 Unexpected end tag (font) in table context caused voodoo mode. +Line: 1 Col: 90 End tag (font) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 99 Unexpected end tag (select) in table context caused voodoo mode. +Line: 1 Col: 99 Unexpected end tag (select). Ignored. +Line: 1 Col: 104 Unexpected end tag (h1) in table context caused voodoo mode. +Line: 1 Col: 104 End tag (h1) seen too early. Expected other end tag. +Line: 1 Col: 109 Unexpected end tag (h2) in table context caused voodoo mode. +Line: 1 Col: 109 End tag (h2) seen too early. Expected other end tag. +Line: 1 Col: 114 Unexpected end tag (h3) in table context caused voodoo mode. +Line: 1 Col: 114 End tag (h3) seen too early. Expected other end tag. +Line: 1 Col: 119 Unexpected end tag (h4) in table context caused voodoo mode. +Line: 1 Col: 119 End tag (h4) seen too early. Expected other end tag. +Line: 1 Col: 124 Unexpected end tag (h5) in table context caused voodoo mode. +Line: 1 Col: 124 End tag (h5) seen too early. Expected other end tag. +Line: 1 Col: 129 Unexpected end tag (h6) in table context caused voodoo mode. +Line: 1 Col: 129 End tag (h6) seen too early. Expected other end tag. +Line: 1 Col: 136 Unexpected end tag (body) in the table row phase. Ignored. +Line: 1 Col: 141 Unexpected end tag (br) in table context caused voodoo mode. +Line: 1 Col: 141 Unexpected end tag (br). Treated as br element. +Line: 1 Col: 145 Unexpected end tag (a) in table context caused voodoo mode. +Line: 1 Col: 145 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 151 Unexpected end tag (img) in table context caused voodoo mode. +Line: 1 Col: 151 This element (img) has no end tag. +Line: 1 Col: 159 Unexpected end tag (title) in table context caused voodoo mode. +Line: 1 Col: 159 Unexpected end tag (title). Ignored. +Line: 1 Col: 166 Unexpected end tag (span) in table context caused voodoo mode. +Line: 1 Col: 166 Unexpected end tag (span). Ignored. +Line: 1 Col: 174 Unexpected end tag (style) in table context caused voodoo mode. +Line: 1 Col: 174 Unexpected end tag (style). Ignored. +Line: 1 Col: 183 Unexpected end tag (script) in table context caused voodoo mode. +Line: 1 Col: 183 Unexpected end tag (script). Ignored. +Line: 1 Col: 196 Unexpected end tag (th). Ignored. +Line: 1 Col: 201 Unexpected end tag (td). Ignored. +Line: 1 Col: 206 Unexpected end tag (tr). Ignored. +Line: 1 Col: 214 This element (frame) has no end tag. +Line: 1 Col: 221 This element (area) has no end tag. +Line: 1 Col: 228 Unexpected end tag (link). Ignored. +Line: 1 Col: 236 This element (param) has no end tag. +Line: 1 Col: 241 This element (hr) has no end tag. +Line: 1 Col: 249 This element (input) has no end tag. +Line: 1 Col: 255 Unexpected end tag (col). Ignored. +Line: 1 Col: 262 Unexpected end tag (base). Ignored. +Line: 1 Col: 269 Unexpected end tag (meta). Ignored. +Line: 1 Col: 280 This element (basefont) has no end tag. +Line: 1 Col: 290 This element (bgsound) has no end tag. +Line: 1 Col: 298 This element (embed) has no end tag. +Line: 1 Col: 307 This element (spacer) has no end tag. +Line: 1 Col: 311 Unexpected end tag (p). Ignored. +Line: 1 Col: 316 End tag (dd) seen too early. Expected other end tag. +Line: 1 Col: 321 End tag (dt) seen too early. Expected other end tag. +Line: 1 Col: 331 Unexpected end tag (caption). Ignored. +Line: 1 Col: 342 Unexpected end tag (colgroup). Ignored. +Line: 1 Col: 350 Unexpected end tag (tbody). Ignored. +Line: 1 Col: 358 Unexpected end tag (tfoot). Ignored. +Line: 1 Col: 366 Unexpected end tag (thead). Ignored. +Line: 1 Col: 376 End tag (address) seen too early. Expected other end tag. +Line: 1 Col: 389 End tag (blockquote) seen too early. Expected other end tag. +Line: 1 Col: 398 End tag (center) seen too early. Expected other end tag. +Line: 1 Col: 404 Unexpected end tag (dir). Ignored. +Line: 1 Col: 410 End tag (div) seen too early. Expected other end tag. +Line: 1 Col: 415 End tag (dl) seen too early. Expected other end tag. +Line: 1 Col: 426 End tag (fieldset) seen too early. Expected other end tag. +Line: 1 Col: 436 End tag (listing) seen too early. Expected other end tag. +Line: 1 Col: 443 End tag (menu) seen too early. Expected other end tag. +Line: 1 Col: 448 End tag (ol) seen too early. Expected other end tag. +Line: 1 Col: 453 End tag (ul) seen too early. Expected other end tag. +Line: 1 Col: 458 End tag (li) seen too early. Expected other end tag. +Line: 1 Col: 465 End tag (nobr) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 471 This element (wbr) has no end tag. +Line: 1 Col: 487 End tag (button) seen too early. Expected other end tag. +Line: 1 Col: 497 End tag (marquee) seen too early. Expected other end tag. +Line: 1 Col: 506 End tag (object) seen too early. Expected other end tag. +Line: 1 Col: 524 Unexpected end tag (html). Ignored. +Line: 1 Col: 524 Unexpected end tag (frameset). Ignored. +Line: 1 Col: 531 Unexpected end tag (head). Ignored. +Line: 1 Col: 540 Unexpected end tag (iframe). Ignored. +Line: 1 Col: 548 This element (image) has no end tag. +Line: 1 Col: 558 This element (isindex) has no end tag. +Line: 1 Col: 568 Unexpected end tag (noembed). Ignored. +Line: 1 Col: 579 Unexpected end tag (noframes). Ignored. +Line: 1 Col: 590 Unexpected end tag (noscript). Ignored. +Line: 1 Col: 601 Unexpected end tag (optgroup). Ignored. +Line: 1 Col: 610 Unexpected end tag (option). Ignored. +Line: 1 Col: 622 Unexpected end tag (plaintext). Ignored. +Line: 1 Col: 633 Unexpected end tag (textarea). Ignored. +#document +| +| +| +|
+| +| +| +|

+ +#data + +#errors +Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE. +Line: 1 Col: 10 Expected closing tag. Unexpected end of file. +#document +| +| +| diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests10.dat b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests10.dat new file mode 100644 index 000000000000..4f8df86f208a --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests10.dat @@ -0,0 +1,799 @@ +#data + +#errors +#document +| +| +| +| +| + +#data +a +#errors +29: Bogus comment +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| + +#data + +#errors +35: Stray “svg” start tag. +42: Stray end tag “svg” +#document +| +| +| +| +| +#errors +43: Stray “svg” start tag. +50: Stray end tag “svg” +#document +| +| +| +| +|

+#errors +34: Start tag “svg” seen in “table”. +41: Stray end tag “svg”. +#document +| +| +| +| +| +| + +#data +
foo
+#errors +34: Start tag “svg” seen in “table”. +46: Stray end tag “g”. +53: Stray end tag “svg”. +#document +| +| +| +| +| +| +| "foo" +| + +#data +
foobar
+#errors +34: Start tag “svg” seen in “table”. +46: Stray end tag “g”. +58: Stray end tag “g”. +65: Stray end tag “svg”. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +| + +#data +
foobar
+#errors +41: Start tag “svg” seen in “table”. +53: Stray end tag “g”. +65: Stray end tag “g”. +72: Stray end tag “svg”. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +| +| + +#data +
foobar
+#errors +45: Start tag “svg” seen in “table”. +57: Stray end tag “g”. +69: Stray end tag “g”. +76: Stray end tag “svg”. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +| +| +| + +#data +
foobar
+#errors +#document +| +| +| +| +| +| +| +|
+| +| +| "foo" +| +| "bar" + +#data +
foobar

baz

+#errors +#document +| +| +| +| +| +| +| +|
+| +| +| "foo" +| +| "bar" +|

+| "baz" + +#data +
foobar

baz

+#errors +#document +| +| +| +| +| +|
+| +| +| "foo" +| +| "bar" +|

+| "baz" + +#data +
foobar

baz

quux +#errors +70: HTML start tag “p” in a foreign namespace context. +81: “table” closed but “caption” was still open. +#document +| +| +| +| +| +|
+| +| +| "foo" +| +| "bar" +|

+| "baz" +|

+| "quux" + +#data +
foobarbaz

quux +#errors +78: “table” closed but “caption” was still open. +78: Unclosed elements on stack. +#document +| +| +| +| +| +|
+| +| +| "foo" +| +| "bar" +| "baz" +|

+| "quux" + +#data +foobar

baz

quux +#errors +44: Start tag “svg” seen in “table”. +56: Stray end tag “g”. +68: Stray end tag “g”. +71: HTML start tag “p” in a foreign namespace context. +71: Start tag “p” seen in “table”. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +|

+| "baz" +| +| +|

+| "quux" + +#data +

quux +#errors +50: Stray “svg” start tag. +54: Stray “g” start tag. +62: Stray end tag “g” +66: Stray “g” start tag. +74: Stray end tag “g” +77: Stray “p” start tag. +88: “table” end tag with “select” open. +#document +| +| +| +| +| +| +| +|
+|

quux +#errors +36: Start tag “select” seen in “table”. +42: Stray “svg” start tag. +46: Stray “g” start tag. +54: Stray end tag “g” +58: Stray “g” start tag. +66: Stray end tag “g” +69: Stray “p” start tag. +80: “table” end tag with “select” open. +#document +| +| +| +| +| +|

+| "quux" + +#data +foobar

baz +#errors +41: Stray “svg” start tag. +68: HTML start tag “p” in a foreign namespace context. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +|

+| "baz" + +#data +foobar

baz +#errors +34: Stray “svg” start tag. +61: HTML start tag “p” in a foreign namespace context. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +|

+| "baz" + +#data +

+#errors +31: Stray “svg” start tag. +35: Stray “g” start tag. +40: Stray end tag “g” +44: Stray “g” start tag. +49: Stray end tag “g” +52: Stray “p” start tag. +58: Stray “span” start tag. +58: End of file seen and there were open elements. +#document +| +| +| +| + +#data +

+#errors +42: Stray “svg” start tag. +46: Stray “g” start tag. +51: Stray end tag “g” +55: Stray “g” start tag. +60: Stray end tag “g” +63: Stray “p” start tag. +69: Stray “span” start tag. +#document +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| xlink:href="foo" +| +| xlink href="foo" + +#data + +#errors +#document +| +| +| +| +| xlink:href="foo" +| xml:lang="en" +| +| +| xlink href="foo" +| xml lang="en" + +#data + +#errors +#document +| +| +| +| +| xlink:href="foo" +| xml:lang="en" +| +| +| xlink href="foo" +| xml lang="en" + +#data +bar +#errors +#document +| +| +| +| +| xlink:href="foo" +| xml:lang="en" +| +| +| xlink href="foo" +| xml lang="en" +| "bar" + +#data + +#errors +#document +| +| +| +| + +#data +

a +#errors +#document +| +| +| +|
+| +| "a" + +#data +
a +#errors +#document +| +| +| +|
+| +| +| "a" + +#data +
+#errors +#document +| +| +| +|
+| +| +| + +#data +
a +#errors +#document +| +| +| +|
+| +| +| +| +| "a" + +#data +

a +#errors +#document +| +| +| +|

+| +| +| +|

+| "a" + +#data +
    a +#errors +40: HTML start tag “ul” in a foreign namespace context. +41: End of file in a foreign namespace context. +#document +| +| +| +| +| +| +|
    +| +|
      +| "a" + +#data +
        a +#errors +35: HTML start tag “ul” in a foreign namespace context. +36: End of file in a foreign namespace context. +#document +| +| +| +| +| +| +| +|
          +| "a" + +#data +

          +#errors +#document +| +| +| +| +|

          +| +| +|

          + +#data +

          +#errors +#document +| +| +| +| +|

          +| +| +|

          + +#data +

          +#errors +#document +| +| +| +|

          +| +| +| +|

          +|

          + +#data +
          +#errors +#document +| +| +| +| +| +|
          +| +|
          +| +| + +#data +
          +#errors +#document +| +| +| +| +| +| +| +|
          +|
          +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data +

+#errors +#document +| +| +| +| +|
+| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| + +#data +
+#errors +#document +| +| +| +| +| +| +| +|
+| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests11.dat b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests11.dat new file mode 100644 index 000000000000..638cde479f76 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests11.dat @@ -0,0 +1,482 @@ +#data + +#errors +#document +| +| +| +| +| +| attributeName="" +| attributeType="" +| baseFrequency="" +| baseProfile="" +| calcMode="" +| clipPathUnits="" +| contentScriptType="" +| contentStyleType="" +| diffuseConstant="" +| edgeMode="" +| externalResourcesRequired="" +| filterRes="" +| filterUnits="" +| glyphRef="" +| gradientTransform="" +| gradientUnits="" +| kernelMatrix="" +| kernelUnitLength="" +| keyPoints="" +| keySplines="" +| keyTimes="" +| lengthAdjust="" +| limitingConeAngle="" +| markerHeight="" +| markerUnits="" +| markerWidth="" +| maskContentUnits="" +| maskUnits="" +| numOctaves="" +| pathLength="" +| patternContentUnits="" +| patternTransform="" +| patternUnits="" +| pointsAtX="" +| pointsAtY="" +| pointsAtZ="" +| preserveAlpha="" +| preserveAspectRatio="" +| primitiveUnits="" +| refX="" +| refY="" +| repeatCount="" +| repeatDur="" +| requiredExtensions="" +| requiredFeatures="" +| specularConstant="" +| specularExponent="" +| spreadMethod="" +| startOffset="" +| stdDeviation="" +| stitchTiles="" +| surfaceScale="" +| systemLanguage="" +| tableValues="" +| targetX="" +| targetY="" +| textLength="" +| viewBox="" +| viewTarget="" +| xChannelSelector="" +| yChannelSelector="" +| zoomAndPan="" + +#data + +#errors +#document +| +| +| +| +| +| attributeName="" +| attributeType="" +| baseFrequency="" +| baseProfile="" +| calcMode="" +| clipPathUnits="" +| contentScriptType="" +| contentStyleType="" +| diffuseConstant="" +| edgeMode="" +| externalResourcesRequired="" +| filterRes="" +| filterUnits="" +| glyphRef="" +| gradientTransform="" +| gradientUnits="" +| kernelMatrix="" +| kernelUnitLength="" +| keyPoints="" +| keySplines="" +| keyTimes="" +| lengthAdjust="" +| limitingConeAngle="" +| markerHeight="" +| markerUnits="" +| markerWidth="" +| maskContentUnits="" +| maskUnits="" +| numOctaves="" +| pathLength="" +| patternContentUnits="" +| patternTransform="" +| patternUnits="" +| pointsAtX="" +| pointsAtY="" +| pointsAtZ="" +| preserveAlpha="" +| preserveAspectRatio="" +| primitiveUnits="" +| refX="" +| refY="" +| repeatCount="" +| repeatDur="" +| requiredExtensions="" +| requiredFeatures="" +| specularConstant="" +| specularExponent="" +| spreadMethod="" +| startOffset="" +| stdDeviation="" +| stitchTiles="" +| surfaceScale="" +| systemLanguage="" +| tableValues="" +| targetX="" +| targetY="" +| textLength="" +| viewBox="" +| viewTarget="" +| xChannelSelector="" +| yChannelSelector="" +| zoomAndPan="" + +#data + +#errors +#document +| +| +| +| +| +| attributeName="" +| attributeType="" +| baseFrequency="" +| baseProfile="" +| calcMode="" +| clipPathUnits="" +| contentScriptType="" +| contentStyleType="" +| diffuseConstant="" +| edgeMode="" +| externalResourcesRequired="" +| filterRes="" +| filterUnits="" +| glyphRef="" +| gradientTransform="" +| gradientUnits="" +| kernelMatrix="" +| kernelUnitLength="" +| keyPoints="" +| keySplines="" +| keyTimes="" +| lengthAdjust="" +| limitingConeAngle="" +| markerHeight="" +| markerUnits="" +| markerWidth="" +| maskContentUnits="" +| maskUnits="" +| numOctaves="" +| pathLength="" +| patternContentUnits="" +| patternTransform="" +| patternUnits="" +| pointsAtX="" +| pointsAtY="" +| pointsAtZ="" +| preserveAlpha="" +| preserveAspectRatio="" +| primitiveUnits="" +| refX="" +| refY="" +| repeatCount="" +| repeatDur="" +| requiredExtensions="" +| requiredFeatures="" +| specularConstant="" +| specularExponent="" +| spreadMethod="" +| startOffset="" +| stdDeviation="" +| stitchTiles="" +| surfaceScale="" +| systemLanguage="" +| tableValues="" +| targetX="" +| targetY="" +| textLength="" +| viewBox="" +| viewTarget="" +| xChannelSelector="" +| yChannelSelector="" +| zoomAndPan="" + +#data + +#errors +#document +| +| +| +| +| +| attributename="" +| attributetype="" +| basefrequency="" +| baseprofile="" +| calcmode="" +| clippathunits="" +| contentscripttype="" +| contentstyletype="" +| diffuseconstant="" +| edgemode="" +| externalresourcesrequired="" +| filterres="" +| filterunits="" +| glyphref="" +| gradienttransform="" +| gradientunits="" +| kernelmatrix="" +| kernelunitlength="" +| keypoints="" +| keysplines="" +| keytimes="" +| lengthadjust="" +| limitingconeangle="" +| markerheight="" +| markerunits="" +| markerwidth="" +| maskcontentunits="" +| maskunits="" +| numoctaves="" +| pathlength="" +| patterncontentunits="" +| patterntransform="" +| patternunits="" +| pointsatx="" +| pointsaty="" +| pointsatz="" +| preservealpha="" +| preserveaspectratio="" +| primitiveunits="" +| refx="" +| refy="" +| repeatcount="" +| repeatdur="" +| requiredextensions="" +| requiredfeatures="" +| specularconstant="" +| specularexponent="" +| spreadmethod="" +| startoffset="" +| stddeviation="" +| stitchtiles="" +| surfacescale="" +| systemlanguage="" +| tablevalues="" +| targetx="" +| targety="" +| textlength="" +| viewbox="" +| viewtarget="" +| xchannelselector="" +| ychannelselector="" +| zoomandpan="" + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests12.dat b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests12.dat new file mode 100644 index 000000000000..63107d277b6a --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests12.dat @@ -0,0 +1,62 @@ +#data +

foobazeggs

spam

quuxbar +#errors +#document +| +| +| +| +|

+| "foo" +| +| +| +| "baz" +| +| +| +| +| "eggs" +| +| +|

+| "spam" +| +| +| +|
+| +| +| "quux" +| "bar" + +#data +foobazeggs

spam
quuxbar +#errors +#document +| +| +| +| +| "foo" +| +| +| +| "baz" +| +| +| +| +| "eggs" +| +| +|

+| "spam" +| +| +| +|
+| +| +| "quux" +| "bar" diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests14.dat b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests14.dat new file mode 100644 index 000000000000..b8713f88582c --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests14.dat @@ -0,0 +1,74 @@ +#data + +#errors +#document +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +15: Unexpected start tag html +#document +| +| +| abc:def="gh" +| +| +| + +#data + +#errors +15: Unexpected start tag html +#document +| +| +| xml:lang="bar" +| +| + +#data + +#errors +#document +| +| +| 123="456" +| +| + +#data + +#errors +#document +| +| +| 123="456" +| 789="012" +| +| + +#data + +#errors +#document +| +| +| +| +| 789="012" diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests15.dat b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests15.dat new file mode 100644 index 000000000000..6ce1c0d16632 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests15.dat @@ -0,0 +1,208 @@ +#data +

X +#errors +Line: 1 Col: 31 Unexpected end tag (p). Ignored. +Line: 1 Col: 36 Expected closing tag. Unexpected end of file. +#document +| +| +| +| +|

+| +| +| +| +| +| +| " " +|

+| "X" + +#data +

+

X +#errors +Line: 1 Col: 3 Unexpected start tag (p). Expected DOCTYPE. +Line: 1 Col: 16 Unexpected end tag (p). Ignored. +Line: 2 Col: 4 Expected closing tag. Unexpected end of file. +#document +| +| +| +|

+| +| +| +| +| +| +| " +" +|

+| "X" + +#data + +#errors +Line: 1 Col: 22 Unexpected end tag (html) after the (implied) root element. +#document +| +| +| +| +| " " + +#data + +#errors +Line: 1 Col: 22 Unexpected end tag (body) after the (implied) root element. +#document +| +| +| +| +| + +#data + +#errors +Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE. +Line: 1 Col: 13 Unexpected end tag (html) after the (implied) root element. +#document +| +| +| +| + +#data +X +#errors +Line: 1 Col: 22 Unexpected end tag (body) after the (implied) root element. +#document +| +| +| +| +| +| "X" + +#data +<!doctype html><table> X<meta></table> +#errors +Line: 1 Col: 24 Unexpected non-space characters in table context caused voodoo mode. +Line: 1 Col: 30 Unexpected start tag (meta) in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " X" +| <meta> +| <table> + +#data +<!doctype html><table> x</table> +#errors +Line: 1 Col: 24 Unexpected non-space characters in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " x" +| <table> + +#data +<!doctype html><table> x </table> +#errors +Line: 1 Col: 25 Unexpected non-space characters in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " x " +| <table> + +#data +<!doctype html><table><tr> x</table> +#errors +Line: 1 Col: 28 Unexpected non-space characters in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " x" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table>X<style> <tr>x </style> </table> +#errors +Line: 1 Col: 23 Unexpected non-space characters in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "X" +| <table> +| <style> +| " <tr>x " +| " " + +#data +<!doctype html><div><table><a>foo</a> <tr><td>bar</td> </tr></table></div> +#errors +Line: 1 Col: 30 Unexpected start tag (a) in table context caused voodoo mode. +Line: 1 Col: 37 Unexpected end tag (a) in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> +| <a> +| "foo" +| <table> +| " " +| <tbody> +| <tr> +| <td> +| "bar" +| " " + +#data +<frame></frame></frame><frameset><frame><frameset><frame></frameset><noframes></frameset><noframes> +#errors +6: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”. +13: Stray start tag “frame”. +21: Stray end tag “frame”. +29: Stray end tag “frame”. +39: “frameset” start tag after “body” already open. +105: End of file seen inside an [R]CDATA element. +105: End of file seen and there were open elements. +XXX: These errors are wrong, please fix me! +#document +| <html> +| <head> +| <frameset> +| <frame> +| <frameset> +| <frame> +| <noframes> +| "</frameset><noframes>" + +#data +<!DOCTYPE html><object></html> +#errors +1: Expected closing tag. Unexpected end of file +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <object> diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests16.dat b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests16.dat new file mode 100644 index 000000000000..c8ef66f0e6e1 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests16.dat @@ -0,0 +1,2299 @@ +#data +<!doctype html><script> +#errors +Line: 1 Col: 23 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| <body> + +#data +<!doctype html><script>a +#errors +Line: 1 Col: 24 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "a" +| <body> + +#data +<!doctype html><script>< +#errors +Line: 1 Col: 24 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<" +| <body> + +#data +<!doctype html><script></ +#errors +Line: 1 Col: 25 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</" +| <body> + +#data +<!doctype html><script></S +#errors +Line: 1 Col: 26 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</S" +| <body> + +#data +<!doctype html><script></SC +#errors +Line: 1 Col: 27 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SC" +| <body> + +#data +<!doctype html><script></SCR +#errors +Line: 1 Col: 28 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCR" +| <body> + +#data +<!doctype html><script></SCRI +#errors +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCRI" +| <body> + +#data +<!doctype html><script></SCRIP +#errors +Line: 1 Col: 30 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCRIP" +| <body> + +#data +<!doctype html><script></SCRIPT +#errors +Line: 1 Col: 31 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCRIPT" +| <body> + +#data +<!doctype html><script></SCRIPT +#errors +Line: 1 Col: 32 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| <body> + +#data +<!doctype html><script></s +#errors +Line: 1 Col: 26 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</s" +| <body> + +#data +<!doctype html><script></sc +#errors +Line: 1 Col: 27 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</sc" +| <body> + +#data +<!doctype html><script></scr +#errors +Line: 1 Col: 28 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</scr" +| <body> + +#data +<!doctype html><script></scri +#errors +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</scri" +| <body> + +#data +<!doctype html><script></scrip +#errors +Line: 1 Col: 30 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</scrip" +| <body> + +#data +<!doctype html><script></script +#errors +Line: 1 Col: 31 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</script" +| <body> + +#data +<!doctype html><script></script +#errors +Line: 1 Col: 32 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| <body> + +#data +<!doctype html><script><! +#errors +Line: 1 Col: 25 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!" +| <body> + +#data +<!doctype html><script><!a +#errors +Line: 1 Col: 26 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!a" +| <body> + +#data +<!doctype html><script><!- +#errors +Line: 1 Col: 26 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!-" +| <body> + +#data +<!doctype html><script><!-a +#errors +Line: 1 Col: 27 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!-a" +| <body> + +#data +<!doctype html><script><!-- +#errors +Line: 1 Col: 27 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<!doctype html><script><!--a +#errors +Line: 1 Col: 28 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--a" +| <body> + +#data +<!doctype html><script><!--< +#errors +Line: 1 Col: 28 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<" +| <body> + +#data +<!doctype html><script><!--<a +#errors +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<a" +| <body> + +#data +<!doctype html><script><!--</ +#errors +Line: 1 Col: 27 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--</" +| <body> + +#data +<!doctype html><script><!--</script +#errors +Line: 1 Col: 35 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--</script" +| <body> + +#data +<!doctype html><script><!--</script +#errors +Line: 1 Col: 36 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<!doctype html><script><!--<s +#errors +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<s" +| <body> + +#data +<!doctype html><script><!--<script +#errors +Line: 1 Col: 34 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script" +| <body> + +#data +<!doctype html><script><!--<script +#errors +Line: 1 Col: 35 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script " +| <body> + +#data +<!doctype html><script><!--<script < +#errors +Line: 1 Col: 36 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script <" +| <body> + +#data +<!doctype html><script><!--<script <a +#errors +Line: 1 Col: 37 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script <a" +| <body> + +#data +<!doctype html><script><!--<script </ +#errors +Line: 1 Col: 37 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </" +| <body> + +#data +<!doctype html><script><!--<script </s +#errors +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </s" +| <body> + +#data +<!doctype html><script><!--<script </script +#errors +Line: 1 Col: 43 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script" +| <body> + +#data +<!doctype html><script><!--<script </scripta +#errors +Line: 1 Col: 44 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </scripta" +| <body> + +#data +<!doctype html><script><!--<script </script +#errors +Line: 1 Col: 44 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script </script> +#errors +Line: 1 Col: 44 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script>" +| <body> + +#data +<!doctype html><script><!--<script </script/ +#errors +Line: 1 Col: 44 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script/" +| <body> + +#data +<!doctype html><script><!--<script </script < +#errors +Line: 1 Col: 45 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script <" +| <body> + +#data +<!doctype html><script><!--<script </script <a +#errors +Line: 1 Col: 46 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script <a" +| <body> + +#data +<!doctype html><script><!--<script </script </ +#errors +Line: 1 Col: 46 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script </" +| <body> + +#data +<!doctype html><script><!--<script </script </script +#errors +Line: 1 Col: 52 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script </script" +| <body> + +#data +<!doctype html><script><!--<script </script </script +#errors +Line: 1 Col: 53 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script </script </script/ +#errors +Line: 1 Col: 53 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script </script </script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script - +#errors +Line: 1 Col: 36 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -" +| <body> + +#data +<!doctype html><script><!--<script -a +#errors +Line: 1 Col: 37 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -a" +| <body> + +#data +<!doctype html><script><!--<script -< +#errors +Line: 1 Col: 37 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -<" +| <body> + +#data +<!doctype html><script><!--<script -- +#errors +Line: 1 Col: 37 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --" +| <body> + +#data +<!doctype html><script><!--<script --a +#errors +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --a" +| <body> + +#data +<!doctype html><script><!--<script --< +#errors +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --<" +| <body> + +#data +<!doctype html><script><!--<script --> +#errors +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script -->< +#errors +Line: 1 Col: 39 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --><" +| <body> + +#data +<!doctype html><script><!--<script --></ +#errors +Line: 1 Col: 40 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --></" +| <body> + +#data +<!doctype html><script><!--<script --></script +#errors +Line: 1 Col: 46 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --></script" +| <body> + +#data +<!doctype html><script><!--<script --></script +#errors +Line: 1 Col: 47 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script --></script/ +#errors +Line: 1 Col: 47 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script --></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script><\/script>--></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script><\/script>-->" +| <body> + +#data +<!doctype html><script><!--<script></scr'+'ipt>--></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt>-->" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>--><!--</script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>--><!--" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>-- ></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>-- >" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>- -></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- ->" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>- - ></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- - >" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>-></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>->" +| <body> + +#data +<!doctype html><script><!--<script>--!></script>X +#errors +Line: 1 Col: 49 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script>--!></script>X" +| <body> + +#data +<!doctype html><script><!--<scr'+'ipt></script>--></script> +#errors +Line: 1 Col: 59 Unexpected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<scr'+'ipt>" +| <body> +| "-->" + +#data +<!doctype html><script><!--<script></scr'+'ipt></script>X +#errors +Line: 1 Col: 57 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt></script>X" +| <body> + +#data +<!doctype html><style><!--<style></style>--></style> +#errors +Line: 1 Col: 52 Unexpected end tag (style). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--<style>" +| <body> +| "-->" + +#data +<!doctype html><style><!--</style>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--" +| <body> +| "X" + +#data +<!doctype html><style><!--...</style>...--></style> +#errors +Line: 1 Col: 51 Unexpected end tag (style). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--..." +| <body> +| "...-->" + +#data +<!doctype html><style><!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style></style>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style>" +| <body> +| "X" + +#data +<!doctype html><style><!--...<style><!--...--!></style>--></style> +#errors +Line: 1 Col: 66 Unexpected end tag (style). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--...<style><!--...--!>" +| <body> +| "-->" + +#data +<!doctype html><style><!--...</style><!-- --><style>@import ...</style> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--..." +| <!-- --> +| <style> +| "@import ..." +| <body> + +#data +<!doctype html><style>...<style><!--...</style><!-- --></style> +#errors +Line: 1 Col: 63 Unexpected end tag (style). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "...<style><!--..." +| <!-- --> +| <body> + +#data +<!doctype html><style>...<!--[if IE]><style>...</style>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "...<!--[if IE]><style>..." +| <body> +| "X" + +#data +<!doctype html><title><!--<title>--> +#errors +Line: 1 Col: 52 Unexpected end tag (title). +#document +| +| +| +| +| "<!--<title>" +| <body> +| "-->" + +#data +<!doctype html><title></title> +#errors +#document +| +| +| +| +| "" +| + +#data +foo/title><link></head><body>X +#errors +Line: 1 Col: 52 Unexpected end of file. Expected end tag (title). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <title> +| "foo/title><link></head><body>X" +| <body> + +#data +<!doctype html><noscript><!--<noscript></noscript>--></noscript> +#errors +Line: 1 Col: 64 Unexpected end tag (noscript). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noscript> +| "<!--<noscript>" +| <body> +| "-->" + +#data +<!doctype html><noscript><!--</noscript>X<noscript>--></noscript> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noscript> +| "<!--" +| <body> +| "X" +| <noscript> +| "-->" + +#data +<!doctype html><noscript><iframe></noscript>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noscript> +| "<iframe>" +| <body> +| "X" + +#data +<!doctype html><noframes><!--<noframes></noframes>--></noframes> +#errors +Line: 1 Col: 64 Unexpected end tag (noframes). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noframes> +| "<!--<noframes>" +| <body> +| "-->" + +#data +<!doctype html><noframes><body><script><!--...</script></body></noframes></html> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noframes> +| "<body><script><!--...</script></body>" +| <body> + +#data +<!doctype html><textarea><!--<textarea></textarea>--></textarea> +#errors +Line: 1 Col: 64 Unexpected end tag (textarea). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "<!--<textarea>" +| "-->" + +#data +<!doctype html><textarea></textarea></textarea> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "</textarea>" + +#data +<!doctype html><textarea><</textarea> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "<" + +#data +<!doctype html><textarea>a<b</textarea> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "a<b" + +#data +<!doctype html><iframe><!--<iframe></iframe>--></iframe> +#errors +Line: 1 Col: 56 Unexpected end tag (iframe). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <iframe> +| "<!--<iframe>" +| "-->" + +#data +<!doctype html><iframe>...<!--X->...<!--/X->...</iframe> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <iframe> +| "...<!--X->...<!--/X->..." + +#data +<!doctype html><xmp><!--<xmp></xmp>--></xmp> +#errors +Line: 1 Col: 44 Unexpected end tag (xmp). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <xmp> +| "<!--<xmp>" +| "-->" + +#data +<!doctype html><noembed><!--<noembed></noembed>--></noembed> +#errors +Line: 1 Col: 60 Unexpected end tag (noembed). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <noembed> +| "<!--<noembed>" +| "-->" + +#data +<script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 8 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| <body> + +#data +<script>a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 9 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "a" +| <body> + +#data +<script>< +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 9 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<" +| <body> + +#data +<script></ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 10 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</" +| <body> + +#data +<script></S +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</S" +| <body> + +#data +<script></SC +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 12 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</SC" +| <body> + +#data +<script></SCR +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 13 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</SCR" +| <body> + +#data +<script></SCRI +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 14 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</SCRI" +| <body> + +#data +<script></SCRIP +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 15 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</SCRIP" +| <body> + +#data +<script></SCRIPT +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 16 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</SCRIPT" +| <body> + +#data +<script></SCRIPT +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 17 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| <body> + +#data +<script></s +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</s" +| <body> + +#data +<script></sc +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 12 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</sc" +| <body> + +#data +<script></scr +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 13 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</scr" +| <body> + +#data +<script></scri +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 14 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</scri" +| <body> + +#data +<script></scrip +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 15 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</scrip" +| <body> + +#data +<script></script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 16 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</script" +| <body> + +#data +<script></script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 17 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| <body> + +#data +<script><! +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 10 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!" +| <body> + +#data +<script><!a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!a" +| <body> + +#data +<script><!- +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!-" +| <body> + +#data +<script><!-a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 12 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!-a" +| <body> + +#data +<script><!-- +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 12 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<script><!--a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 13 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--a" +| <body> + +#data +<script><!--< +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 13 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<" +| <body> + +#data +<script><!--<a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 14 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<a" +| <body> + +#data +<script><!--</ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 14 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--</" +| <body> + +#data +<script><!--</script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 20 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--</script" +| <body> + +#data +<script><!--</script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 21 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<script><!--<s +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 14 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<s" +| <body> + +#data +<script><!--<script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 19 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script" +| <body> + +#data +<script><!--<script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 20 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script " +| <body> + +#data +<script><!--<script < +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 21 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script <" +| <body> + +#data +<script><!--<script <a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 22 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script <a" +| <body> + +#data +<script><!--<script </ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 22 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </" +| <body> + +#data +<script><!--<script </s +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 23 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </s" +| <body> + +#data +<script><!--<script </script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 28 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script" +| <body> + +#data +<script><!--<script </scripta +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </scripta" +| <body> + +#data +<script><!--<script </script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script </script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script>" +| <body> + +#data +<script><!--<script </script/ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script/" +| <body> + +#data +<script><!--<script </script < +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 30 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script <" +| <body> + +#data +<script><!--<script </script <a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 31 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script <a" +| <body> + +#data +<script><!--<script </script </ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 31 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script </" +| <body> + +#data +<script><!--<script </script </script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script </script" +| <body> + +#data +<script><!--<script </script </script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script </script </script/ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script </script </script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script - +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 21 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script -" +| <body> + +#data +<script><!--<script -a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 22 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script -a" +| <body> + +#data +<script><!--<script -- +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 22 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script --" +| <body> + +#data +<script><!--<script --a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 23 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script --a" +| <body> + +#data +<script><!--<script --> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 23 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script -->< +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 24 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script --><" +| <body> + +#data +<script><!--<script --></ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 25 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script --></" +| <body> + +#data +<script><!--<script --></script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 31 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script --></script" +| <body> + +#data +<script><!--<script --></script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 32 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script --></script/ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 32 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script --></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script><\/script>--></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script><\/script>-->" +| <body> + +#data +<script><!--<script></scr'+'ipt>--></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt>-->" +| <body> + +#data +<script><!--<script></script><script></script></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>" +| <body> + +#data +<script><!--<script></script><script></script>--><!--</script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>--><!--" +| <body> + +#data +<script><!--<script></script><script></script>-- ></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>-- >" +| <body> + +#data +<script><!--<script></script><script></script>- -></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- ->" +| <body> + +#data +<script><!--<script></script><script></script>- - ></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- - >" +| <body> + +#data +<script><!--<script></script><script></script>-></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>->" +| <body> + +#data +<script><!--<script>--!></script>X +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 34 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script>--!></script>X" +| <body> + +#data +<script><!--<scr'+'ipt></script>--></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 44 Unexpected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<scr'+'ipt>" +| <body> +| "-->" + +#data +<script><!--<script></scr'+'ipt></script>X +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 42 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt></script>X" +| <body> + +#data +<style><!--<style></style>--></style> +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +Line: 1 Col: 37 Unexpected end tag (style). +#document +| <html> +| <head> +| <style> +| "<!--<style>" +| <body> +| "-->" + +#data +<style><!--</style>X +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| <html> +| <head> +| <style> +| "<!--" +| <body> +| "X" + +#data +<style><!--...</style>...--></style> +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +Line: 1 Col: 36 Unexpected end tag (style). +#document +| <html> +| <head> +| <style> +| "<!--..." +| <body> +| "...-->" + +#data +<style><!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style></style>X +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| <html> +| <head> +| <style> +| "<!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style>" +| <body> +| "X" + +#data +<style><!--...<style><!--...--!></style>--></style> +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +Line: 1 Col: 51 Unexpected end tag (style). +#document +| <html> +| <head> +| <style> +| "<!--...<style><!--...--!>" +| <body> +| "-->" + +#data +<style><!--...</style><!-- --><style>@import ...</style> +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| <html> +| <head> +| <style> +| "<!--..." +| <!-- --> +| <style> +| "@import ..." +| <body> + +#data +<style>...<style><!--...</style><!-- --></style> +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +Line: 1 Col: 48 Unexpected end tag (style). +#document +| <html> +| <head> +| <style> +| "...<style><!--..." +| <!-- --> +| <body> + +#data +<style>...<!--[if IE]><style>...</style>X +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| <html> +| <head> +| <style> +| "...<!--[if IE]><style>..." +| <body> +| "X" + +#data +<title><!--<title>--> +#errors +Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE. +Line: 1 Col: 37 Unexpected end tag (title). +#document +| +| +| +| "<!--<title>" +| <body> +| "-->" + +#data +<title></title> +#errors +Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE. +#document +| +| +| +| "" +| + +#data +foo/title><link></head><body>X +#errors +Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE. +Line: 1 Col: 37 Unexpected end of file. Expected end tag (title). +#document +| <html> +| <head> +| <title> +| "foo/title><link></head><body>X" +| <body> + +#data +<noscript><!--<noscript></noscript>--></noscript> +#errors +Line: 1 Col: 10 Unexpected start tag (noscript). Expected DOCTYPE. +Line: 1 Col: 49 Unexpected end tag (noscript). +#document +| <html> +| <head> +| <noscript> +| "<!--<noscript>" +| <body> +| "-->" + +#data +<noscript><!--</noscript>X<noscript>--></noscript> +#errors +Line: 1 Col: 10 Unexpected start tag (noscript). Expected DOCTYPE. +#document +| <html> +| <head> +| <noscript> +| "<!--" +| <body> +| "X" +| <noscript> +| "-->" + +#data +<noscript><iframe></noscript>X +#errors +Line: 1 Col: 10 Unexpected start tag (noscript). Expected DOCTYPE. +#document +| <html> +| <head> +| <noscript> +| "<iframe>" +| <body> +| "X" + +#data +<noframes><!--<noframes></noframes>--></noframes> +#errors +Line: 1 Col: 10 Unexpected start tag (noframes). Expected DOCTYPE. +Line: 1 Col: 49 Unexpected end tag (noframes). +#document +| <html> +| <head> +| <noframes> +| "<!--<noframes>" +| <body> +| "-->" + +#data +<noframes><body><script><!--...</script></body></noframes></html> +#errors +Line: 1 Col: 10 Unexpected start tag (noframes). Expected DOCTYPE. +#document +| <html> +| <head> +| <noframes> +| "<body><script><!--...</script></body>" +| <body> + +#data +<textarea><!--<textarea></textarea>--></textarea> +#errors +Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE. +Line: 1 Col: 49 Unexpected end tag (textarea). +#document +| <html> +| <head> +| <body> +| <textarea> +| "<!--<textarea>" +| "-->" + +#data +<textarea></textarea></textarea> +#errors +Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| <textarea> +| "</textarea>" + +#data +<iframe><!--<iframe></iframe>--></iframe> +#errors +Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE. +Line: 1 Col: 41 Unexpected end tag (iframe). +#document +| <html> +| <head> +| <body> +| <iframe> +| "<!--<iframe>" +| "-->" + +#data +<iframe>...<!--X->...<!--/X->...</iframe> +#errors +Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| <iframe> +| "...<!--X->...<!--/X->..." + +#data +<xmp><!--<xmp></xmp>--></xmp> +#errors +Line: 1 Col: 5 Unexpected start tag (xmp). Expected DOCTYPE. +Line: 1 Col: 29 Unexpected end tag (xmp). +#document +| <html> +| <head> +| <body> +| <xmp> +| "<!--<xmp>" +| "-->" + +#data +<noembed><!--<noembed></noembed>--></noembed> +#errors +Line: 1 Col: 9 Unexpected start tag (noembed). Expected DOCTYPE. +Line: 1 Col: 45 Unexpected end tag (noembed). +#document +| <html> +| <head> +| <body> +| <noembed> +| "<!--<noembed>" +| "-->" + +#data +<!doctype html><table> + +#errors +Line 2 Col 0 Unexpected end of file. Expected table content. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| " +" + +#data +<!doctype html><table><td><span><font></span><span> +#errors +Line 1 Col 26 Unexpected table cell start tag (td) in the table body phase. +Line 1 Col 45 Unexpected end tag (span). +Line 1 Col 51 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <span> +| <font> +| <font> +| <span> + +#data +<!doctype html><form><table></form><form></table></form> +#errors +35: Stray end tag “form”. +41: Start tag “form” seen in “table”. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> +| <table> +| <form> diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests17.dat b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests17.dat new file mode 100644 index 000000000000..7b555f888ded --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests17.dat @@ -0,0 +1,153 @@ +#data +<!doctype html><table><tbody><select><tr> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table><tr><select><td> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <table> +| <tbody> +| <tr> +| <td> + +#data +<!doctype html><table><tr><td><select><td> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <select> +| <td> + +#data +<!doctype html><table><tr><th><select><td> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <th> +| <select> +| <td> + +#data +<!doctype html><table><caption><select><tr> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| <select> +| <tbody> +| <tr> + +#data +<!doctype html><select><tr> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><td> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><th> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><tbody> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><thead> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><tfoot> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><caption> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><table><tr></table>a +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| "a" diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests18.dat b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests18.dat new file mode 100644 index 000000000000..680e1f068a65 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests18.dat @@ -0,0 +1,269 @@ +#data +<!doctype html><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" + +#data +<!doctype html><table><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" +| <table> + +#data +<!doctype html><table><tbody><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" +| <table> +| <tbody> + +#data +<!doctype html><table><tbody><tr><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table><tbody><tr><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table><td><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <plaintext> +| "</plaintext>" + +#data +<!doctype html><table><caption><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| <plaintext> +| "</plaintext>" + +#data +<!doctype html><table><tr><style></script></style>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "abc" +| <table> +| <tbody> +| <tr> +| <style> +| "</script>" + +#data +<!doctype html><table><tr><script></style></script>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "abc" +| <table> +| <tbody> +| <tr> +| <script> +| "</style>" + +#data +<!doctype html><table><caption><style></script></style>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| <style> +| "</script>" +| "abc" + +#data +<!doctype html><table><td><style></script></style>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <style> +| "</script>" +| "abc" + +#data +<!doctype html><select><script></style></script>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <script> +| "</style>" +| "abc" + +#data +<!doctype html><table><select><script></style></script>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <script> +| "</style>" +| "abc" +| <table> + +#data +<!doctype html><table><tr><select><script></style></script>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <script> +| "</style>" +| "abc" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><frameset></frameset><noframes>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" + +#data +<!doctype html><frameset></frameset><noframes>abc</noframes><!--abc--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" +| <!-- abc --> + +#data +<!doctype html><frameset></frameset></html><noframes>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" + +#data +<!doctype html><frameset></frameset></html><noframes>abc</noframes><!--abc--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" +| <!-- abc --> + +#data +<!doctype html><table><tr></tbody><tfoot> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <tfoot> + +#data +<!doctype html><table><td><svg></svg>abc<td> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <svg svg> +| "abc" +| <td> diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests19.dat b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests19.dat new file mode 100644 index 000000000000..0d62f5a5b02b --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests19.dat @@ -0,0 +1,1237 @@ +#data +<!doctype html><math><mn DefinitionUrl="foo"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <math math> +| <math mn> +| definitionURL="foo" + +#data +<!doctype html><html></p><!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <!-- foo --> +| <head> +| <body> + +#data +<!doctype html><head></head></p><!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <!-- foo --> +| <body> + +#data +<!doctype html><body><p><pre> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <pre> + +#data +<!doctype html><body><p><listing> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <listing> + +#data +<!doctype html><p><plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <plaintext> + +#data +<!doctype html><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <h1> + +#data +<!doctype html><form><isindex> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> + +#data +<!doctype html><isindex action="POST"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> +| action="POST" +| <hr> +| <label> +| "This is a searchable index. Enter search keywords: " +| <input> +| name="isindex" +| <hr> + +#data +<!doctype html><isindex prompt="this is isindex"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> +| <hr> +| <label> +| "this is isindex" +| <input> +| name="isindex" +| <hr> + +#data +<!doctype html><isindex type="hidden"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> +| <hr> +| <label> +| "This is a searchable index. Enter search keywords: " +| <input> +| name="isindex" +| type="hidden" +| <hr> + +#data +<!doctype html><isindex name="foo"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> +| <hr> +| <label> +| "This is a searchable index. Enter search keywords: " +| <input> +| name="isindex" +| <hr> + +#data +<!doctype html><ruby><p><rp> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <p> +| <rp> + +#data +<!doctype html><ruby><div><span><rp> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <span> +| <rp> + +#data +<!doctype html><ruby><div><p><rp> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <p> +| <rp> + +#data +<!doctype html><ruby><p><rt> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <p> +| <rt> + +#data +<!doctype html><ruby><div><span><rt> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <span> +| <rt> + +#data +<!doctype html><ruby><div><p><rt> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <p> +| <rt> + +#data +<!doctype html><math/><foo> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <math math> +| <foo> + +#data +<!doctype html><svg/><foo> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <svg svg> +| <foo> + +#data +<!doctype html><div></body><!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> +| <!-- foo --> + +#data +<!doctype html><h1><div><h3><span></h1>foo +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <h1> +| <div> +| <h3> +| <span> +| "foo" + +#data +<!doctype html><p></h3>foo +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| "foo" + +#data +<!doctype html><h3><li>abc</h2>foo +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <h3> +| <li> +| "abc" +| "foo" + +#data +<!doctype html><table>abc<!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "abc" +| <table> +| <!-- foo --> + +#data +<!doctype html><table> <!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| " " +| <!-- foo --> + +#data +<!doctype html><table> b <!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " b " +| <table> +| <!-- foo --> + +#data +<!doctype html><select><option><option> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> +| <option> + +#data +<!doctype html><select><option></optgroup> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> + +#data +<!doctype html><select><option></optgroup> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> + +#data +<!doctype html><p><math><mi><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mi> +| <p> +| <h1> + +#data +<!doctype html><p><math><mo><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mo> +| <p> +| <h1> + +#data +<!doctype html><p><math><mn><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mn> +| <p> +| <h1> + +#data +<!doctype html><p><math><ms><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math ms> +| <p> +| <h1> + +#data +<!doctype html><p><math><mtext><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mtext> +| <p> +| <h1> + +#data +<!doctype html><frameset></noframes> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><html c=d><body></html><html a=b> +#errors +#document +| <!DOCTYPE html> +| <html> +| a="b" +| c="d" +| <head> +| <body> + +#data +<!doctype html><html c=d><frameset></frameset></html><html a=b> +#errors +#document +| <!DOCTYPE html> +| <html> +| a="b" +| c="d" +| <head> +| <frameset> + +#data +<!doctype html><html><frameset></frameset></html><!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <!-- foo --> + +#data +<!doctype html><html><frameset></frameset></html> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| " " + +#data +<!doctype html><html><frameset></frameset></html>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><html><frameset></frameset></html><p> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><html><frameset></frameset></html></p> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<html><frameset></frameset></html><!doctype html> +#errors +#document +| <html> +| <head> +| <frameset> + +#data +<!doctype html><body><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> + +#data +<!doctype html><p><frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><p>a<frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| "a" + +#data +<!doctype html><p> <frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><pre><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <pre> + +#data +<!doctype html><listing><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <listing> + +#data +<!doctype html><li><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <li> + +#data +<!doctype html><dd><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <dd> + +#data +<!doctype html><dt><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <dt> + +#data +<!doctype html><button><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <button> + +#data +<!doctype html><applet><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <applet> + +#data +<!doctype html><marquee><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <marquee> + +#data +<!doctype html><object><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <object> + +#data +<!doctype html><table><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> + +#data +<!doctype html><area><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <area> + +#data +<!doctype html><basefont><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <basefont> +| <frameset> + +#data +<!doctype html><bgsound><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <bgsound> +| <frameset> + +#data +<!doctype html><br><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <br> + +#data +<!doctype html><embed><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <embed> + +#data +<!doctype html><img><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <img> + +#data +<!doctype html><input><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <input> + +#data +<!doctype html><keygen><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <keygen> + +#data +<!doctype html><wbr><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <wbr> + +#data +<!doctype html><hr><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <hr> + +#data +<!doctype html><textarea></textarea><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> + +#data +<!doctype html><xmp></xmp><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <xmp> + +#data +<!doctype html><iframe></iframe><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <iframe> + +#data +<!doctype html><select></select><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><svg></svg><frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><math></math><frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><svg><foreignObject><div> <frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><svg>a</svg><frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <svg svg> +| "a" + +#data +<!doctype html><svg> </svg><frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<html>aaa<frameset></frameset> +#errors +#document +| <html> +| <head> +| <body> +| "aaa" + +#data +<html> a <frameset></frameset> +#errors +#document +| <html> +| <head> +| <body> +| "a " + +#data +<!doctype html><div><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><div><body><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> + +#data +<!doctype html><p><math></p>a +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| "a" + +#data +<!doctype html><p><math><mn><span></p>a +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mn> +| <span> +| <p> +| "a" + +#data +<!doctype html><math></html> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <math math> + +#data +<!doctype html><meta charset="ascii"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <meta> +| charset="ascii" +| <body> + +#data +<!doctype html><meta http-equiv="content-type" content="text/html;charset=ascii"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <meta> +| content="text/html;charset=ascii" +| http-equiv="content-type" +| <body> + +#data +<!doctype html><head><!--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--><meta charset="utf8"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <!-- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --> +| <meta> +| charset="utf8" +| <body> + +#data +<!doctype html><html a=b><head></head><html c=d> +#errors +#document +| <!DOCTYPE html> +| <html> +| a="b" +| c="d" +| <head> +| <body> + +#data +<!doctype html><image/> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <img> + +#data +<!doctype html>a<i>b<table>c<b>d</i>e</b>f +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "a" +| <i> +| "bc" +| <b> +| "de" +| "f" +| <table> + +#data +<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <b> +| <i> +| "c" +| <a> +| "d" +| <a> +| "e" +| <a> +| "f" +| <table> + +#data +<!doctype html><i>a<b>b<div>c<a>d</i>e</b>f +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <b> +| <i> +| "c" +| <a> +| "d" +| <a> +| "e" +| <a> +| "f" + +#data +<!doctype html><table><i>a<b>b<div>c</i> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <i> +| "c" +| <table> + +#data +<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <b> +| <i> +| "c" +| <a> +| "d" +| <a> +| "e" +| <a> +| "f" +| <table> + +#data +<!doctype html><table><i>a<div>b<tr>c<b>d</i>e +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <div> +| "b" +| <i> +| "c" +| <b> +| "d" +| <b> +| "e" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table><td><table><i>a<div>b<b>c</i>d +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <i> +| "a" +| <div> +| <i> +| "b" +| <b> +| "c" +| <b> +| "d" +| <table> + +#data +<!doctype html><body><bgsound> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <bgsound> + +#data +<!doctype html><body><basefont> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <basefont> + +#data +<!doctype html><a><b></a><basefont> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <a> +| <b> +| <basefont> + +#data +<!doctype html><a><b></a><bgsound> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <a> +| <b> +| <bgsound> + +#data +<!doctype html><figcaption><article></figcaption>a +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <figcaption> +| <article> +| "a" + +#data +<!doctype html><summary><article></summary>a +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <summary> +| <article> +| "a" + +#data +<!doctype html><p><a><plaintext>b +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <a> +| <plaintext> +| <a> +| "b" + +#data +<!DOCTYPE html><div>a<a></div>b<p>c</p>d +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> +| "a" +| <a> +| <a> +| "b" +| <p> +| "c" +| "d" diff --git a/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests2.dat b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests2.dat new file mode 100644 index 000000000000..60d859221624 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/html/testdata/webkit/tests2.dat @@ -0,0 +1,763 @@ +#data +<!DOCTYPE html>Test +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "Test" + +#data +<textarea>test</div>test +#errors +Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE. +Line: 1 Col: 24 Expected closing tag. Unexpected end of file. +#document +| <html> +| <head> +| <body> +| <textarea> +| "test</div>test" + +#data +<table><td> +#errors +Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected table cell start tag (td) in the table body phase. +Line: 1 Col: 11 Expected closing tag. Unexpected end of file. +#document +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> + +#data +<table><td>test</tbody></table> +#errors +Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected table cell start tag (td) in the table body phase. +#document +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| "test" + +#data +<frame>test +#errors +Line: 1 Col: 7 Unexpected start tag (frame). Expected DOCTYPE. +Line: 1 Col: 7 Unexpected start tag frame. Ignored. +#document +| <html> +| <head> +| <body> +| "test" + +#data +<!DOCTYPE html><frameset>test +#errors +Line: 1 Col: 29 Unepxected characters in the frameset phase. Characters ignored. +Line: 1 Col: 29 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!DOCTYPE html><frameset><!DOCTYPE html> +#errors +Line: 1 Col: 40 Unexpected DOCTYPE. Ignored. +Line: 1 Col: 40 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!DOCTYPE html><font><p><b>test</font> +#errors +Line: 1 Col: 38 End tag (font) violates step 1, paragraph 3 of the adoption agency algorithm. +Line: 1 Col: 38 End tag (font) violates step 1, paragraph 3 of the adoption agency algorithm. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <font> +| <p> +| <font> +| <b> +| "test" + +#data +<!DOCTYPE html><dt><div><dd> +#errors +Line: 1 Col: 28 Missing end tag (div, dt). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <dt> +| <div> +| <dd> + +#data +<script></x +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</x" +| <body> + +#data +<table><plaintext><td> +#errors +Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE. +Line: 1 Col: 18 Unexpected start tag (plaintext) in table context caused voodoo mode. +Line: 1 Col: 22 Unexpected end of file. Expected table content. +#document +| <html> +| <head> +| <body> +| <plaintext> +| "<td>" +| <table> + +#data +<plaintext></plaintext> +#errors +Line: 1 Col: 11 Unexpected start tag (plaintext). Expected DOCTYPE. +Line: 1 Col: 23 Expected closing tag. Unexpected end of file. +#document +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" + +#data +<!DOCTYPE html><table><tr>TEST +#errors +Line: 1 Col: 30 Unexpected non-space characters in table context caused voodoo mode. +Line: 1 Col: 30 Unexpected end of file. Expected table content. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "TEST" +| <table> +| <tbody> +| <tr> + +#data +<!DOCTYPE html><body t1=1><body t2=2><body t3=3 t4=4> +#errors +Line: 1 Col: 37 Unexpected start tag (body). +Line: 1 Col: 53 Unexpected start tag (body). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| t1="1" +| t2="2" +| t3="3" +| t4="4" + +#data +</b test +#errors +Line: 1 Col: 8 Unexpected end of file in attribute name. +Line: 1 Col: 8 End tag contains unexpected attributes. +Line: 1 Col: 8 Unexpected end tag (b). Expected DOCTYPE. +Line: 1 Col: 8 Unexpected end tag (b) after the (implied) root element. +#document +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html></b test<b &=&>X +#errors +Line: 1 Col: 32 Named entity didn't end with ';'. +Line: 1 Col: 33 End tag contains unexpected attributes. +Line: 1 Col: 33 Unexpected end tag (b) after the (implied) root element. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "X" + +#data +<!doctypehtml><scrIPt type=text/x-foobar;baz>X</SCRipt +#errors +Line: 1 Col: 9 No space after literal string 'DOCTYPE'. +Line: 1 Col: 54 Unexpected end of file in the tag name. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| type="text/x-foobar;baz" +| "X</SCRipt" +| <body> + +#data +& +#errors +Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&" + +#data +&# +#errors +Line: 1 Col: 1 Numeric entity expected. Got end of file instead. +Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&#" + +#data +&#X +#errors +Line: 1 Col: 3 Numeric entity expected but none found. +Line: 1 Col: 3 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&#X" + +#data +&#x +#errors +Line: 1 Col: 3 Numeric entity expected but none found. +Line: 1 Col: 3 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&#x" + +#data +- +#errors +Line: 1 Col: 4 Numeric entity didn't end with ';'. +Line: 1 Col: 4 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "-" + +#data +&x-test +#errors +Line: 1 Col: 1 Named entity expected. Got none. +Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&x-test" + +#data +<!doctypehtml><p><li> +#errors +Line: 1 Col: 9 No space after literal string 'DOCTYPE'. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <li> + +#data +<!doctypehtml><p><dt> +#errors +Line: 1 Col: 9 No space after literal string 'DOCTYPE'. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <dt> + +#data +<!doctypehtml><p><dd> +#errors +Line: 1 Col: 9 No space after literal string 'DOCTYPE'. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <dd> + +#data +<!doctypehtml><p><form> +#errors +Line: 1 Col: 9 No space after literal string 'DOCTYPE'. +Line: 1 Col: 23 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <form> + +#data +<!DOCTYPE html><p></P>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| "X" + +#data +& +#errors +Line: 1 Col: 4 Named entity didn't end with ';'. +Line: 1 Col: 4 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&" + +#data +&AMp; +#errors +Line: 1 Col: 1 Named entity expected. Got none. +Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&AMp;" + +#data +<!DOCTYPE html><html><head></head><body><thisISasillyTESTelementNameToMakeSureCrazyTagNamesArePARSEDcorrectLY> +#errors +Line: 1 Col: 110 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly> + +#data +<!DOCTYPE html>X</body>X +#errors +Line: 1 Col: 24 Unexpected non-space characters in the after body phase. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "XX" + +#data +<!DOCTYPE html><!-- X +#errors +Line: 1 Col: 21 Unexpected end of file in comment. +#document +| <!DOCTYPE html> +| <!-- X --> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><table><caption>test TEST</caption><td>test +#errors +Line: 1 Col: 54 Unexpected table cell start tag (td) in the table body phase. +Line: 1 Col: 58 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| "test TEST" +| <tbody> +| <tr> +| <td> +| "test" + +#data +<!DOCTYPE html><select><option><optgroup> +#errors +Line: 1 Col: 41 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> +| <optgroup> + +#data +<!DOCTYPE html><select><optgroup><option></optgroup><option><select><option> +#errors +Line: 1 Col: 68 Unexpected select start tag in the select phase treated as select end tag. +Line: 1 Col: 76 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <optgroup> +| <option> +| <option> +| <option> + +#data +<!DOCTYPE html><select><optgroup><option><optgroup> +#errors +Line: 1 Col: 51 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <optgroup> +| <option> +| <optgroup> + +#data +<!DOCTYPE html><datalist><option>foo</datalist>bar +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <datalist> +| <option> +| "foo" +| "bar" + +#data +<!DOCTYPE html><font><input><input></font> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <font> +| <input> +| <input> + +#data +<!DOCTYPE html><!-- XXX - XXX --> +#errors +#document +| <!DOCTYPE html> +| <!-- XXX - XXX --> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><!-- XXX - XXX +#errors +Line: 1 Col: 29 Unexpected end of file in comment (-) +#document +| <!DOCTYPE html> +| <!-- XXX - XXX --> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><!-- XXX - XXX - XXX --> +#errors +#document +| <!DOCTYPE html> +| <!-- XXX - XXX - XXX --> +| <html> +| <head> +| <body> + +#data +<isindex test=x name=x> +#errors +Line: 1 Col: 23 Unexpected start tag (isindex). Expected DOCTYPE. +Line: 1 Col: 23 Unexpected start tag isindex. Don't use it! +#document +| <html> +| <head> +| <body> +| <form> +| <hr> +| <label> +| "This is a searchable index. Enter search keywords: " +| <input> +| name="isindex" +| test="x" +| <hr> + +#data +test +test +#errors +Line: 2 Col: 4 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "test +test" + +#data +<!DOCTYPE html><body><title>test</body> +#errors +#document +| +| +| +| +| +| "test</body>" + +#data +<!DOCTYPE html><body><title>X +#errors +#document +| +| +| +| +| +| "X" +| <meta> +| name="z" +| <link> +| rel="foo" +| <style> +| " +x { content:"</style" } " + +#data +<!DOCTYPE html><select><optgroup></optgroup></select> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <optgroup> + +#data + + +#errors +Line: 2 Col: 1 Unexpected End of file. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html> <html> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><script> +</script> <title>x +#errors +#document +| +| +| +| +#errors +Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE. +Line: 1 Col: 21 Unexpected start tag (script) that can be in head. Moved. +#document +| +| +| +#errors +Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE. +Line: 1 Col: 28 Unexpected start tag (style) that can be in head. Moved. +#document +| +| +| +#errors +Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE. +#document +| +| +| +| +| "x" +| x +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +Line: 1 Col: 22 Unexpected end of file. Expected end tag (style). +#document +| +| +| --> x +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| +| +| x +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| +| +| x +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| +| +| x +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| +| +|

+#errors +#document +| +| +| +| +| +| ddd +#errors +#document +| +| +| +#errors +#document +| +| +| +| +|
  • +| +| - - - -
  • ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    spec

    specification of a node; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.NodeSpec

    status

    most recently observed status of the node; populated by the system, read-only; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.NodeStatus

    - - -

    -

    v1.PersistentVolumeClaimList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    v1.ListMeta

    items

    a list of persistent volume claims; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#persistentvolumeclaims

    false

    v1.PersistentVolumeClaim array

    - -
    -
    -

    v1.ObjectFieldSelector

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    apiVersion

    version of the schema that fieldPath is written in terms of; defaults to v1

    false

    string

    fieldPath

    path of the field to select in the specified API version

    true

    string

    - -
    -
    -

    v1.SELinuxOptions

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    user

    the user label to apply to the container; see http://kubernetes.io/v1.0/docs/user-guide/labels.html

    false

    string

    role

    the role label to apply to the container; see http://kubernetes.io/v1.0/docs/user-guide/labels.html

    false

    string

    type

    the type label to apply to the container; see http://kubernetes.io/v1.0/docs/user-guide/labels.html

    false

    string

    level

    the level label to apply to the container; see http://kubernetes.io/v1.0/docs/user-guide/labels.html

    false

    string

    - -
    -
    -

    v1.ContainerStateRunning

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    startedAt

    time at which the container was last (re-)started

    false

    string

    - -
    -
    -

    v1.VolumeMount

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    name

    name of the volume to mount

    true

    string

    readOnly

    mounted read-only if true, read-write otherwise (false or unspecified)

    false

    boolean

    false

    mountPath

    path within the container at which the volume should be mounted

    true

    string

    - -
    -
    -

    v1.PersistentVolumeClaimSpec

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    accessModes

    the desired access modes the volume should have; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#access-modes-1

    false

    v1.PersistentVolumeAccessMode array

    resources

    the desired resources the volume should have; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#resources

    false

    v1.ResourceRequirements

    volumeName

    the binding reference to the persistent volume backing this claim

    false

    string

    - -
    -
    -

    v1.GCEPersistentDiskVolumeSource

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    pdName

    unique name of the PD resource in GCE; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#gcepersistentdisk

    true

    string

    fsType

    file system type to mount, such as ext4, xfs, ntfs; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#gcepersistentdisk

    true

    string

    partition

    partition on the disk to mount (e.g., 1 for /dev/sda1); if omitted the plain device name (e.g., /dev/sda) will be mounted; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#gcepersistentdisk

    false

    integer (int32)

    readOnly

    read-only if true, read-write otherwise (false or unspecified); see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#gcepersistentdisk

    false

    boolean

    false

    - -
    -
    -

    v1.NamespaceStatus

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    phase

    phase is the current lifecycle phase of the namespace; see http://kubernetes.io/v1.0/docs/design/namespaces.html#phases

    false

    string

    - -
    -
    -

    v1.ResourceQuotaSpec

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    hard

    hard is the set of desired hard limits for each named resource; see http://kubernetes.io/v1.0/docs/design/admission_control_resource_quota.html#admissioncontrol-plugin-resourcequota

    false

    any

    - -
    -
    -

    v1.NamespaceSpec

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    finalizers

    an opaque list of values that must be empty to permanently remove object from storage; see http://kubernetes.io/v1.0/docs/design/namespaces.html#finalizers

    false

    v1.FinalizerName array

    - -
    -
    -

    v1.PersistentVolume

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    spec

    specification of a persistent volume as provisioned by an administrator; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#persistent-volumes

    false

    v1.PersistentVolumeSpec

    status

    current status of a persistent volume; populated by the system, read-only; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#persistent-volumes

    false

    v1.PersistentVolumeStatus

    - -
    -
    -

    v1.PersistentVolumeStatus

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    phase

    the current phase of a persistent volume; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#phase

    false

    string

    message

    human-readable message indicating details about why the volume is in this state

    false

    string

    reason

    (brief) reason the volume is not is not available

    false

    string

    - -
    -
    -

    v1.EndpointsList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    list of endpoints

    true

    v1.Endpoints array

    - -
    -
    -

    v1.GitRepoVolumeSource

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    repository

    repository URL

    true

    string

    revision

    commit hash for the specified revision

    true

    string

    - -
    -
    -

    v1.Capabilities

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    add

    added capabilities

    false

    v1.Capability array

    drop

    droped capabilities

    false

    v1.Capability array

    - -
    -
    -

    v1.NodeCondition

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    type

    type of node condition, currently only Ready

    true

    string

    status

    status of the condition, one of True, False, Unknown

    true

    string

    lastHeartbeatTime

    last time we got an update on a given condition

    false

    string

    lastTransitionTime

    last time the condition transit from one status to another

    false

    string

    reason

    (brief) reason for the condition’s last transition

    false

    string

    message

    human readable message indicating details about last transition

    false

    string

    - -
    -
    -

    v1.PodTemplateList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    list of pod templates

    true

    v1.PodTemplate array

    - -
    -
    -

    v1.LocalObjectReference

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    name

    name of the referent; see http://kubernetes.io/v1.0/docs/user-guide/identifiers.html#names

    false

    string

    - -
    -
    -

    v1.ResourceQuotaStatus

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    hard

    hard is the set of enforced hard limits for each named resource; see http://kubernetes.io/v1.0/docs/design/admission_control_resource_quota.html#admissioncontrol-plugin-resourcequota

    false

    any

    used

    used is the current observed total usage of the resource in the namespace

    false

    any

    - -
    -
    -

    v1.ExecAction

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    command

    command line to execute inside the container; working directory for the command is root (/) in the container’s file system; the command is exec’d, not run inside a shell; exit status of 0 is treated as live/healthy and non-zero is unhealthy

    false

    string array

    - -
    -
    -

    v1.ObjectMeta

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    name

    string that identifies an object. Must be unique within a namespace; cannot be updated; see http://kubernetes.io/v1.0/docs/user-guide/identifiers.html#names

    false

    string

    generateName

    an optional prefix to use to generate a unique name; has the same validation rules as name; optional, and is applied only name if is not specified; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#idempotency

    false

    string

    namespace

    namespace of the object; must be a DNS_LABEL; cannot be updated; see http://kubernetes.io/v1.0/docs/user-guide/namespaces.html

    false

    string

    selfLink

    URL for the object; populated by the system, read-only

    false

    string

    uid

    unique UUID across space and time; populated by the system; read-only; see http://kubernetes.io/v1.0/docs/user-guide/identifiers.html#uids

    false

    string

    resourceVersion

    string that identifies the internal version of this object that can be used by clients to determine when objects have changed; populated by the system, read-only; value must be treated as opaque by clients and passed unmodified back to the server: http://kubernetes.io/v1.0/docs/devel/api-conventions.html#concurrency-control-and-consistency

    false

    string

    generation

    a sequence number representing a specific generation of the desired state; populated by the system; read-only

    false

    integer (int64)

    creationTimestamp

    RFC 3339 date and time at which the object was created; populated by the system, read-only; null for lists; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    string

    deletionTimestamp

    RFC 3339 date and time at which the object will be deleted; populated by the system when a graceful deletion is requested, read-only; if not set, graceful deletion of the object has not been requested; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    string

    labels

    map of string keys and values that can be used to organize and categorize objects; may match selectors of replication controllers and services; see http://kubernetes.io/v1.0/docs/user-guide/labels.html

    false

    any

    annotations

    map of string keys and values that can be used by external tooling to store and retrieve arbitrary metadata about objects; see http://kubernetes.io/v1.0/docs/user-guide/annotations.html

    false

    any

    - -
    -
    -

    api.Patch

    - -
    -
    -

    v1.LimitRangeSpec

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    limits

    limits is the list of LimitRangeItem objects that are enforced

    true

    v1.LimitRangeItem array

    - -
    -
    -

    v1.ISCSIVolumeSource

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    targetPortal

    iSCSI target portal

    true

    string

    iqn

    iSCSI Qualified Name

    true

    string

    lun

    iscsi target lun number

    true

    integer (int32)

    fsType

    file system type to mount, such as ext4, xfs, ntfs

    true

    string

    readOnly

    read-only if true, read-write otherwise (false or unspecified)

    false

    boolean

    false

    - -
    -
    -

    v1.EmptyDirVolumeSource

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    medium

    type of storage used to back the volume; must be an empty string (default) or Memory; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#emptydir

    false

    string

    - -
    -
    -

    v1.NodeList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    list of nodes

    true

    v1.Node array

    - -
    -
    -

    v1.PersistentVolumeClaim

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    spec

    the desired characteristics of a volume; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#persistentvolumeclaims

    false

    v1.PersistentVolumeClaimSpec

    status

    the current status of a persistent volume claim; read-only; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#persistentvolumeclaims

    false

    v1.PersistentVolumeClaimStatus

    - -
    -
    -

    v1.NamespaceList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    items is the list of Namespace objects in the list; see http://kubernetes.io/v1.0/docs/user-guide/namespaces.html

    true

    v1.Namespace array

    - -
    -
    -

    v1.ServiceAccount

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    secrets

    list of secrets that can be used by pods running as this service account; see http://kubernetes.io/v1.0/docs/user-guide/secrets.html

    false

    v1.ObjectReference array

    imagePullSecrets

    list of references to secrets in the same namespace available for pulling container images; see http://kubernetes.io/v1.0/docs/user-guide/secrets.html#manually-specifying-an-imagepullsecret

    false

    v1.LocalObjectReference array

    - -
    -
    -

    v1.NodeAddress

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    type

    node address type, one of Hostname, ExternalIP or InternalIP

    true

    string

    address

    the node address

    true

    string

    - -
    -
    -

    v1.Namespace

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    spec

    spec defines the behavior of the Namespace; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.NamespaceSpec

    status

    status describes the current status of a Namespace; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.NamespaceStatus

    - -
    -
    -

    v1.ListMeta

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    selfLink

    URL for the object; populated by the system, read-only

    false

    string

    resourceVersion

    string that identifies the internal version of this object that can be used by clients to determine when objects have changed; populated by the system, read-only; value must be treated as opaque by clients and passed unmodified back to the server: http://kubernetes.io/v1.0/docs/devel/api-conventions.html#concurrency-control-and-consistency

    false

    string

    - -
    -
    -

    v1.PersistentVolumeClaimVolumeSource

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    claimName

    the name of the claim in the same namespace to be mounted as a volume; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#persistentvolumeclaims

    true

    string

    readOnly

    mount volume as read-only when true; default false

    false

    boolean

    false

    - -
    -
    -

    v1.PersistentVolumeClaimStatus

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    phase

    the current phase of the claim

    false

    string

    accessModes

    the actual access modes the volume has; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#access-modes-1

    false

    v1.PersistentVolumeAccessMode array

    capacity

    the actual resources the volume has

    false

    any

    - -
    -
    -

    v1.ResourceQuotaList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    items is a list of ResourceQuota objects; see http://kubernetes.io/v1.0/docs/design/admission_control_resource_quota.html#admissioncontrol-plugin-resourcequota

    true

    v1.ResourceQuota array

    - -
    -
    -

    v1.EndpointSubset

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    addresses

    IP addresses which offer the related ports

    false

    v1.EndpointAddress array

    ports

    port numbers available on the related IP addresses

    false

    v1.EndpointPort array

    - -
    -
    -

    v1.SecretVolumeSource

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    secretName

    secretName is the name of a secret in the pod’s namespace; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#secrets

    true

    string

    - -
    -
    -

    v1.EnvVarSource

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    fieldRef

    selects a field of the pod; only name and namespace are supported

    true

    v1.ObjectFieldSelector

    - -
    -
    -

    v1.LoadBalancerIngress

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    ip

    IP address of ingress point

    false

    string

    hostname

    hostname of ingress point

    false

    string

    - -
    -
    -

    v1.Service

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    spec

    specification of the desired behavior of the service; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.ServiceSpec

    status

    most recently observed status of the service; populated by the system, read-only; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.ServiceStatus

    - -
    -
    -

    v1.ServiceAccountList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    list of ServiceAccounts; see http://kubernetes.io/v1.0/docs/design/service_accounts.html#service-accounts

    true

    v1.ServiceAccount array

    - -
    -
    -

    v1.LimitRangeList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    items is a list of LimitRange objects; see http://kubernetes.io/v1.0/docs/design/admission_control_limit_range.html

    true

    v1.LimitRange array

    - -
    -
    -

    v1.Endpoints

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    subsets

    sets of addresses and ports that comprise a service

    true

    v1.EndpointSubset array

    - -
    -
    -

    v1.DeleteOptions

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    gracePeriodSeconds

    the duration in seconds to wait before deleting this object; defaults to a per object value if not specified; zero means delete immediately

    true

    integer (int64)

    - -
    -
    -

    v1.Volume

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    name

    volume name; must be a DNS_LABEL and unique within the pod; see http://kubernetes.io/v1.0/docs/user-guide/identifiers.html#names

    true

    string

    hostPath

    pre-existing host file or directory; generally for privileged system daemons or other agents tied to the host; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#hostpath

    false

    v1.HostPathVolumeSource

    emptyDir

    temporary directory that shares a pod’s lifetime; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#emptydir

    false

    v1.EmptyDirVolumeSource

    gcePersistentDisk

    GCE disk resource attached to the host machine on demand; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#gcepersistentdisk

    false

    v1.GCEPersistentDiskVolumeSource

    awsElasticBlockStore

    AWS disk resource attached to the host machine on demand; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#awselasticblockstore

    false

    v1.AWSElasticBlockStoreVolumeSource

    gitRepo

    git repository at a particular revision

    false

    v1.GitRepoVolumeSource

    secret

    secret to populate volume; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#secrets

    false

    v1.SecretVolumeSource

    nfs

    NFS volume that will be mounted in the host machine; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#nfs

    false

    v1.NFSVolumeSource

    iscsi

    iSCSI disk attached to host machine on demand; see http://kubernetes.io/v1.0/examples/iscsi/README.html

    false

    v1.ISCSIVolumeSource

    glusterfs

    Glusterfs volume that will be mounted on the host machine; see http://kubernetes.io/v1.0/examples/glusterfs/README.html

    false

    v1.GlusterfsVolumeSource

    persistentVolumeClaim

    a reference to a PersistentVolumeClaim in the same namespace; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#persistentvolumeclaims

    false

    v1.PersistentVolumeClaimVolumeSource

    rbd

    rados block volume that will be mounted on the host machine; see http://kubernetes.io/v1.0/examples/rbd/README.html

    false

    v1.RBDVolumeSource

    - -
    -
    -

    v1.Probe

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    exec

    exec-based handler

    false

    v1.ExecAction

    httpGet

    HTTP-based handler

    false

    v1.HTTPGetAction

    tcpSocket

    TCP-based handler; TCP hooks not yet supported

    false

    v1.TCPSocketAction

    initialDelaySeconds

    number of seconds after the container has started before liveness probes are initiated; see http://kubernetes.io/v1.0/docs/user-guide/pod-states.html#container-probes

    false

    integer (int64)

    timeoutSeconds

    number of seconds after which liveness probes timeout; defaults to 1 second; see http://kubernetes.io/v1.0/docs/user-guide/pod-states.html#container-probes

    false

    integer (int64)

    - -
    -
    -

    v1.Capability

    - -
    -
    -

    v1.ReplicationController

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    spec

    specification of the desired behavior of the replication controller; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.ReplicationControllerSpec

    status

    most recently observed status of the replication controller; populated by the system, read-only; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.ReplicationControllerStatus

    - -
    -
    -

    v1.LimitRange

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    spec

    spec defines the limits enforced; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.LimitRangeSpec

    - -
    -
    -

    v1.PodStatus

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    phase

    current condition of the pod; see http://kubernetes.io/v1.0/docs/user-guide/pod-states.html#pod-phase

    false

    string

    conditions

    current service state of pod; see http://kubernetes.io/v1.0/docs/user-guide/pod-states.html#pod-conditions

    false

    v1.PodCondition array

    message

    human readable message indicating details about why the pod is in this condition

    false

    string

    reason

    (brief-CamelCase) reason indicating details about why the pod is in this condition

    false

    string

    hostIP

    IP address of the host to which the pod is assigned; empty if not yet scheduled

    false

    string

    podIP

    IP address allocated to the pod; routable at least within the cluster; empty if not yet allocated

    false

    string

    startTime

    RFC 3339 date and time at which the object was acknowledged by the Kubelet. This is before the Kubelet pulled the container image(s) for the pod.

    false

    string

    containerStatuses

    list of container statuses; see http://kubernetes.io/v1.0/docs/user-guide/pod-states.html#container-statuses

    false

    v1.ContainerStatus array

    - -
    -
    -

    v1.PodSpec

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    volumes

    list of volumes that can be mounted by containers belonging to the pod; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html

    false

    v1.Volume array

    containers

    list of containers belonging to the pod; cannot be updated; containers cannot currently be added or removed; there must be at least one container in a Pod; see http://kubernetes.io/v1.0/docs/user-guide/containers.html

    true

    v1.Container array

    restartPolicy

    restart policy for all containers within the pod; one of Always, OnFailure, Never; defaults to Always; see http://kubernetes.io/v1.0/docs/user-guide/pod-states.html#restartpolicy

    false

    string

    terminationGracePeriodSeconds

    optional duration in seconds the pod needs to terminate gracefully; may be decreased in delete request; value must be non-negative integer; the value zero indicates delete immediately; if this value is not set, the default grace period will be used instead; the grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal; set this value longer than the expected cleanup time for your process

    false

    integer (int64)

    activeDeadlineSeconds

    false

    integer (int64)

    dnsPolicy

    DNS policy for containers within the pod; one of ClusterFirst or Default

    false

    string

    nodeSelector

    selector which must match a node’s labels for the pod to be scheduled on that node; see http://kubernetes.io/v1.0/docs/user-guide/node-selection/README.html

    false

    any

    serviceAccountName

    name of the ServiceAccount to use to run this pod; see http://kubernetes.io/v1.0/docs/design/service_accounts.html

    false

    string

    nodeName

    node requested for this pod

    false

    string

    hostNetwork

    host networking requested for this pod

    false

    boolean

    false

    imagePullSecrets

    list of references to secrets in the same namespace available for pulling the container images; see http://kubernetes.io/v1.0/docs/user-guide/images.html#specifying-imagepullsecrets-on-a-pod

    false

    v1.LocalObjectReference array

    - -
    -
    -

    v1.ContainerPort

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    name

    name for the port that can be referred to by services; must be an IANA_SVC_NAME and unique within the pod

    false

    string

    hostPort

    number of port to expose on the host; most containers do not need this

    false

    integer (int32)

    containerPort

    number of port to expose on the pod’s IP address

    true

    integer (int32)

    protocol

    protocol for port; must be UDP or TCP; TCP if unspecified

    false

    string

    hostIP

    host IP to bind the port to

    false

    string

    - -
    -
    -

    v1.EventList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    list of events

    true

    v1.Event array

    - -
    -
    -

    v1.ResourceQuota

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    spec

    spec defines the desired quota; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.ResourceQuotaSpec

    status

    status defines the actual enforced quota and current usage; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.ResourceQuotaStatus

    - -
    -
    -

    v1.Lifecycle

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    postStart

    called immediately after a container is started; if the handler fails, the container is terminated and restarted according to its restart policy; other management of the container blocks until the hook completes; see http://kubernetes.io/v1.0/docs/user-guide/container-environment.html#hook-details

    false

    v1.Handler

    preStop

    called before a container is terminated; the container is terminated after the handler completes; other management of the container blocks until the hook completes; see http://kubernetes.io/v1.0/docs/user-guide/container-environment.html#hook-details

    false

    v1.Handler

    - -
    -
    -

    v1.NodeStatus

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    capacity

    compute resource capacity of the node; see http://kubernetes.io/v1.0/docs/user-guide/compute-resources.html

    false

    any

    phase

    most recently observed lifecycle phase of the node; see http://kubernetes.io/v1.0/docs/admin/node.html#node-phase

    false

    string

    conditions

    list of node conditions observed; see http://kubernetes.io/v1.0/docs/admin/node.html#node-condition

    false

    v1.NodeCondition array

    addresses

    list of addresses reachable to the node; see http://kubernetes.io/v1.0/docs/admin/node.html#node-addresses

    false

    v1.NodeAddress array

    nodeInfo

    set of ids/uuids to uniquely identify the node; see http://kubernetes.io/v1.0/docs/admin/node.html#node-info

    false

    v1.NodeSystemInfo

    - -
    -
    -

    v1.GlusterfsVolumeSource

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    endpoints

    gluster hosts endpoints name; see http://kubernetes.io/v1.0/examples/glusterfs/README.html#create-a-pod

    true

    string

    path

    path to gluster volume; see http://kubernetes.io/v1.0/examples/glusterfs/README.html#create-a-pod

    true

    string

    readOnly

    glusterfs volume to be mounted with read-only permissions; see http://kubernetes.io/v1.0/examples/glusterfs/README.html#create-a-pod

    false

    boolean

    false

    - -
    -
    -

    v1.Handler

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    exec

    exec-based handler

    false

    v1.ExecAction

    httpGet

    HTTP-based handler

    false

    v1.HTTPGetAction

    tcpSocket

    TCP-based handler; TCP hooks not yet supported

    false

    v1.TCPSocketAction

    - -
    -
    -

    v1.ReplicationControllerSpec

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    replicas

    number of replicas desired; defaults to 1; see http://kubernetes.io/v1.0/docs/user-guide/replication-controller.html#what-is-a-replication-controller

    false

    integer (int32)

    selector

    label keys and values that must match in order to be controlled by this replication controller, if empty defaulted to labels on Pod template; see http://kubernetes.io/v1.0/docs/user-guide/labels.html#label-selectors

    false

    any

    template

    object that describes the pod that will be created if insufficient replicas are detected; takes precendence over templateRef; see http://kubernetes.io/v1.0/docs/user-guide/replication-controller.html#pod-template

    false

    v1.PodTemplateSpec

    - -
    -
    -

    v1.EventSource

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    component

    component that generated the event

    false

    string

    host

    name of the host where the event is generated

    false

    string

    - -
    -
    -

    v1.StatusCause

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    reason

    machine-readable description of the cause of the error; if this value is empty there is no information available

    false

    string

    message

    human-readable description of the cause of the error; this field may be presented as-is to a reader

    false

    string

    field

    field of the resource that has caused this error, as named by its JSON serialization; may include dot and postfix notation for nested attributes; arrays are zero-indexed; fields may appear more than once in an array of causes due to fields having multiple errors

    false

    string

    - -
    -
    -

    v1.PodCondition

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    type

    kind of the condition, currently only Ready; see http://kubernetes.io/v1.0/docs/user-guide/pod-states.html#pod-conditions

    true

    string

    status

    status of the condition, one of True, False, Unknown; see http://kubernetes.io/v1.0/docs/user-guide/pod-states.html#pod-conditions

    true

    string

    - -
    -
    -

    v1.RBDVolumeSource

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    monitors

    a collection of Ceph monitors; see http://kubernetes.io/v1.0/examples/rbd/README.html#how-to-use-it

    true

    string array

    image

    rados image name; see http://kubernetes.io/v1.0/examples/rbd/README.html#how-to-use-it

    true

    string

    fsType

    file system type to mount, such as ext4, xfs, ntfs; see http://kubernetes.io/v1.0/examples/rbd/README.html#how-to-use-it

    false

    string

    pool

    rados pool name; default is rbd; optional; see http://kubernetes.io/v1.0/examples/rbd/README.html#how-to-use-it

    true

    string

    user

    rados user name; default is admin; optional; see http://kubernetes.io/v1.0/examples/rbd/README.html#how-to-use-it

    true

    string

    keyring

    keyring is the path to key ring for rados user; default is /etc/ceph/keyring; optional; see http://kubernetes.io/v1.0/examples/rbd/README.html#how-to-use-it

    true

    string

    secretRef

    name of a secret to authenticate the RBD user; if provided overrides keyring; optional; see http://kubernetes.io/v1.0/examples/rbd/README.html#how-to-use-it

    true

    v1.LocalObjectReference

    readOnly

    rbd volume to be mounted with read-only permissions; see http://kubernetes.io/v1.0/examples/rbd/README.html#how-to-use-it

    false

    boolean

    false

    - -
    -
    -

    v1.Status

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    status

    status of the operation; either Success, or Failure; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    string

    message

    human-readable description of the status of this operation

    false

    string

    reason

    machine-readable description of why this operation is in the Failure status; if this value is empty there is no information available; a reason clarifies an HTTP status code but does not override it

    false

    string

    details

    extended data associated with the reason; each reason may define its own extended details; this field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type

    false

    v1.StatusDetails

    code

    suggested HTTP return code for this status; 0 if not set

    false

    integer (int32)

    - -
    -
    -

    v1.PodTemplate

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    template

    the template of the desired behavior of the pod; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.PodTemplateSpec

    - -
    -
    -

    v1.ServiceStatus

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    loadBalancer

    status of load-balancer

    false

    v1.LoadBalancerStatus

    - -
    -
    -

    v1.NFSVolumeSource

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    server

    the hostname or IP address of the NFS server; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#nfs

    true

    string

    path

    the path that is exported by the NFS server; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#nfs

    true

    string

    readOnly

    forces the NFS export to be mounted with read-only permissions; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#nfs

    false

    boolean

    false

    - -
    -
    -

    v1.EndpointPort

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    name

    name of this port

    false

    string

    port

    port number of the endpoint

    true

    integer (int32)

    protocol

    protocol for this port; must be UDP or TCP; TCP if unspecified

    false

    string

    - -
    -
    -

    v1.TCPSocketAction

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    port

    number of name of the port to access on the container; number must be in the range 1 to 65535; name must be an IANA_SVC_NAME

    true

    string

    - -
    -
    -

    v1.HTTPGetAction

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    path

    path to access on the HTTP server

    false

    string

    port

    number or name of the port to access on the container; number must be in the range 1 to 65535; name must be an IANA_SVC_NAME

    true

    string

    host

    hostname to connect to; defaults to pod IP

    false

    string

    scheme

    scheme to connect with, must be HTTP or HTTPS, defaults to HTTP

    false

    string

    - -
    -
    -

    v1.StatusDetails

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    name

    the name attribute of the resource associated with the status StatusReason (when there is a single name which can be described)

    false

    string

    kind

    the kind attribute of the resource associated with the status StatusReason; on some operations may differ from the requested resource Kind; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    causes

    the Causes array includes more details associated with the StatusReason failure; not all StatusReasons may provide detailed causes

    false

    v1.StatusCause array

    retryAfterSeconds

    the number of seconds before the client should attempt to retry this operation

    false

    integer (int32)

    - -
    -
    -

    v1.LoadBalancerStatus

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    ingress

    load-balancer ingress points

    false

    v1.LoadBalancerIngress array

    - -
    -
    -

    v1.SecretList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    items is a list of secret objects; see http://kubernetes.io/v1.0/docs/user-guide/secrets.html

    true

    v1.Secret array

    - -
    -
    -

    v1.Container

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    name

    name of the container; must be a DNS_LABEL and unique within the pod; cannot be updated

    true

    string

    image

    Docker image name; see http://kubernetes.io/v1.0/docs/user-guide/images.html

    false

    string

    command

    entrypoint array; not executed within a shell; the docker image’s entrypoint is used if this is not provided; cannot be updated; variable references $(VAR_NAME) are expanded using the container’s environment variables; if a variable cannot be resolved, the reference in the input string will be unchanged; the $(VAR_NAME) syntax can be escaped with a double , ie: (VAR_NAME) ; escaped references will never be expanded, regardless of whether the variable exists or not; see http://kubernetes.io/v1.0/docs/user-guide/containers.html#containers-and-commands

    false

    string array

    args

    command array; the docker image’s .html is used if this is not provided; arguments to the entrypoint; cannot be updated; variable references $(VAR_NAME) are expanded using the container’s environment variables; if a variable cannot be resolved, the reference in the input string will be unchanged; the $(VAR_NAME) syntax can be escaped with a double , ie: (VAR_NAME) ; escaped references will never be expanded, regardless of whether the variable exists or not; see http://kubernetes.io/v1.0/docs/user-guide/containers.html#containers-and-commands

    false

    string array

    workingDir

    container’s working directory; defaults to image’s default; cannot be updated

    false

    string

    ports

    list of ports to expose from the container; cannot be updated

    false

    v1.ContainerPort array

    env

    list of environment variables to set in the container; cannot be updated

    false

    v1.EnvVar array

    resources

    Compute Resources required by this container; cannot be updated; see http://kubernetes.io/v1.0/docs/user-guide/compute-resources.html

    false

    v1.ResourceRequirements

    volumeMounts

    pod volumes to mount into the container’s filesyste; cannot be updated

    false

    v1.VolumeMount array

    livenessProbe

    periodic probe of container liveness; container will be restarted if the probe fails; cannot be updated; see http://kubernetes.io/v1.0/docs/user-guide/pod-states.html#container-probes

    false

    v1.Probe

    readinessProbe

    periodic probe of container service readiness; container will be removed from service endpoints if the probe fails; cannot be updated; see http://kubernetes.io/v1.0/docs/user-guide/pod-states.html#container-probes

    false

    v1.Probe

    lifecycle

    actions that the management system should take in response to container lifecycle events; cannot be updated

    false

    v1.Lifecycle

    terminationMessagePath

    path at which the file to which the container’s termination message will be written is mounted into the container’s filesystem; message written is intended to be brief final status, such as an assertion failure message; defaults to /dev/termination-log; cannot be updated

    false

    string

    imagePullPolicy

    image pull policy; one of Always, Never, IfNotPresent; defaults to Always if :latest tag is specified, or IfNotPresent otherwise; cannot be updated; see http://kubernetes.io/v1.0/docs/user-guide/images.html#updating-images

    false

    string

    securityContext

    security options the pod should run with; see http://kubernetes.io/v1.0/docs/design/security_context.html

    false

    v1.SecurityContext

    - -
    -
    -

    v1.PersistentVolumeSpec

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    capacity

    a description of the persistent volume’s resources and capacityr; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#capacity

    false

    any

    gcePersistentDisk

    GCE disk resource provisioned by an admin; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#gcepersistentdisk

    false

    v1.GCEPersistentDiskVolumeSource

    awsElasticBlockStore

    AWS disk resource provisioned by an admin; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#awselasticblockstore

    false

    v1.AWSElasticBlockStoreVolumeSource

    hostPath

    a HostPath provisioned by a developer or tester; for develment use only; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#hostpath

    false

    v1.HostPathVolumeSource

    glusterfs

    Glusterfs volume resource provisioned by an admin; see http://kubernetes.io/v1.0/examples/glusterfs/README.html

    false

    v1.GlusterfsVolumeSource

    nfs

    NFS volume resource provisioned by an admin; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#nfs

    false

    v1.NFSVolumeSource

    rbd

    rados block volume that will be mounted on the host machine; see http://kubernetes.io/v1.0/examples/rbd/README.html

    false

    v1.RBDVolumeSource

    iscsi

    an iSCSI disk resource provisioned by an admin

    false

    v1.ISCSIVolumeSource

    accessModes

    all ways the volume can be mounted; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#access-modes

    false

    v1.PersistentVolumeAccessMode array

    claimRef

    when bound, a reference to the bound claim; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#binding

    false

    v1.ObjectReference

    persistentVolumeReclaimPolicy

    what happens to a volume when released from its claim; Valid options are Retain (default) and Recycle. Recyling must be supported by the volume plugin underlying this persistent volume. See http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html#recycling-policy

    false

    string

    - -
    -
    -

    v1.ReplicationControllerStatus

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    replicas

    most recently oberved number of replicas; see http://kubernetes.io/v1.0/docs/user-guide/replication-controller.html#what-is-a-replication-controller

    true

    integer (int32)

    observedGeneration

    reflects the generation of the most recently observed replication controller

    false

    integer (int64)

    - -
    -
    -

    v1.FinalizerName

    - -
    -
    -

    v1.ServicePort

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    name

    the name of this port; optional if only one port is defined

    false

    string

    protocol

    the protocol used by this port; must be UDP or TCP; TCP if unspecified

    false

    string

    port

    the port number that is exposed

    true

    integer (int32)

    targetPort

    number or name of the port to access on the pods targeted by the service; defaults to the service port; number must be in the range 1 to 65535; name must be an IANA_SVC_NAME; see http://kubernetes.io/v1.0/docs/user-guide/services.html#defining-a-service

    false

    string

    nodePort

    the port on each node on which this service is exposed when type=NodePort or LoadBalancer; usually assigned by the system; if specified, it will be allocated to the service if unused or else creation of the service will fail; see http://kubernetes.io/v1.0/docs/user-guide/services.html#type—nodeport

    true

    integer (int32)

    - -
    -
    -

    v1.ComponentCondition

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    type

    type of component condition, currently only Healthy

    true

    string

    status

    current status of this component condition, one of True, False, Unknown

    true

    string

    message

    health check message received from the component

    false

    string

    error

    error code from health check attempt (if any)

    false

    string

    - -
    -
    -

    v1.ComponentStatusList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    list of component status objects

    true

    v1.ComponentStatus array

    - -
    -
    -

    v1.HostPathVolumeSource

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    path

    path of the directory on the host; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#hostpath

    true

    string

    - -
    -
    -

    json.WatchEvent

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    type

    the type of watch event; may be ADDED, MODIFIED, DELETED, or ERROR

    false

    string

    object

    the object being watched; will match the type of the resource endpoint or be a Status object if the type is ERROR

    false

    string

    - -
    -
    -

    v1.Binding

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    target

    an object to bind to

    true

    v1.ObjectReference

    - -
    -
    -

    v1.ContainerStateTerminated

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    exitCode

    exit status from the last termination of the container

    true

    integer (int32)

    signal

    signal from the last termination of the container

    false

    integer (int32)

    reason

    (brief) reason from the last termination of the container

    false

    string

    message

    message regarding the last termination of the container

    false

    string

    startedAt

    time at which previous execution of the container started

    false

    string

    finishedAt

    time at which the container last terminated

    false

    string

    containerID

    container’s ID in the format docker://<container_id>

    false

    string

    - -
    -
    -

    v1.SecurityContext

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    capabilities

    the linux capabilites that should be added or removed; see http://kubernetes.io/v1.0/docs/design/security_context.html#security-context

    false

    v1.Capabilities

    privileged

    run the container in privileged mode; see http://kubernetes.io/v1.0/docs/design/security_context.html#security-context

    false

    boolean

    false

    seLinuxOptions

    options that control the SELinux labels applied; see http://kubernetes.io/v1.0/docs/design/security_context.html#security-context

    false

    v1.SELinuxOptions

    runAsUser

    the user id that runs the first process in the container; see http://kubernetes.io/v1.0/docs/design/security_context.html#security-context

    false

    integer (int64)

    - -
    -
    -

    v1.ContainerState

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    waiting

    details about a waiting container

    false

    v1.ContainerStateWaiting

    running

    details about a running container

    false

    v1.ContainerStateRunning

    terminated

    details about a terminated container

    false

    v1.ContainerStateTerminated

    - -
    -
    -

    v1.AWSElasticBlockStoreVolumeSource

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    volumeID

    unique id of the PD resource in AWS; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#awselasticblockstore

    true

    string

    fsType

    file system type to mount, such as ext4, xfs, ntfs; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#awselasticblockstore

    true

    string

    partition

    partition on the disk to mount (e.g., 1 for /dev/sda1); if omitted the plain device name (e.g., /dev/sda) will be mounted; see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#awselasticblockstore

    false

    integer (int32)

    readOnly

    read-only if true, read-write otherwise (false or unspecified); see http://kubernetes.io/v1.0/docs/user-guide/volumes.html#awselasticblockstore

    false

    boolean

    false

    - -
    -
    -

    v1.ContainerStatus

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    name

    name of the container; must be a DNS_LABEL and unique within the pod; cannot be updated

    true

    string

    state

    details about the container’s current condition

    false

    v1.ContainerState

    lastState

    details about the container’s last termination condition

    false

    v1.ContainerState

    ready

    specifies whether the container has passed its readiness probe

    true

    boolean

    false

    restartCount

    the number of times the container has been restarted, currently based on the number of dead containers that have not yet been removed

    true

    integer (int32)

    image

    image of the container; see http://kubernetes.io/v1.0/docs/user-guide/images.html

    true

    string

    imageID

    ID of the container’s image

    true

    string

    containerID

    container’s ID in the format docker://<container_id>; see http://kubernetes.io/v1.0/docs/user-guide/container-environment.html#container-information

    false

    string

    - -
    -
    -

    v1.ReplicationControllerList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    list of replication controllers; see http://kubernetes.io/v1.0/docs/user-guide/replication-controller.html

    true

    v1.ReplicationController array

    - -
    -
    -

    v1.Secret

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    data

    data contains the secret data. Each key must be a valid DNS_SUBDOMAIN or leading dot followed by valid DNS_SUBDOMAIN. Each value must be a base64 encoded string as described in https://tools.ietf.org/html/rfc4648#section-4

    false

    any

    type

    type facilitates programmatic handling of secret data

    false

    string

    - -
    -
    -

    v1.Event

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    true

    v1.ObjectMeta

    involvedObject

    object this event is about

    true

    v1.ObjectReference

    reason

    short, machine understandable string that gives the reason for the transition into the object’s current status

    false

    string

    message

    human-readable description of the status of this operation

    false

    string

    source

    component reporting this event

    false

    v1.EventSource

    firstTimestamp

    the time at which the event was first recorded

    false

    string

    lastTimestamp

    the time at which the most recent occurance of this event was recorded

    false

    string

    count

    the number of times this event has occurred

    false

    integer (int32)

    - -
    -
    -

    v1.EnvVar

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    name

    name of the environment variable; must be a C_IDENTIFIER

    true

    string

    value

    value of the environment variable; defaults to empty string; variable references $(VAR_NAME) are expanded using the previously defined environment varibles in the container and any service environment variables; if a variable cannot be resolved, the reference in the input string will be unchanged; the $(VAR_NAME) syntax can be escaped with a double , ie: (VAR_NAME) ; escaped references will never be expanded, regardless of whether the variable exists or not

    false

    string

    valueFrom

    source for the environment variable’s value; cannot be used if value is not empty

    false

    v1.EnvVarSource

    - -
    -
    -

    v1.ResourceRequirements

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    limits

    Maximum amount of compute resources allowed; see http://kubernetes.io/v1.0/docs/design/resources.html#resource-specifications

    false

    any

    requests

    Minimum amount of resources requested; requests are honored only for persistent volumes as of now; see http://kubernetes.io/v1.0/docs/design/resources.html#resource-specifications

    false

    any

    - -
    -
    -

    v1.PersistentVolumeAccessMode

    - -
    -
    -

    v1.ComponentStatus

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    conditions

    list of component conditions observed

    false

    v1.ComponentCondition array

    - -
    -
    -

    v1.LimitRangeItem

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    type

    type of resource that this limit applies to

    false

    string

    max

    max usage constraints on this kind by resource name

    false

    any

    min

    min usage constraints on this kind by resource name

    false

    any

    default

    default values on this kind by resource name if omitted

    false

    any

    - -
    -
    -

    v1.PodTemplateSpec

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    spec

    specification of the desired behavior of the pod; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.PodSpec

    - -
    -
    -

    v1.PodList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    v1.ListMeta

    items

    list of pods; see http://kubernetes.io/v1.0/docs/user-guide/pods.html

    true

    v1.Pod array

    - -
    -
    -

    v1.ServiceList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ListMeta

    items

    list of services

    true

    v1.Service array

    - -
    -
    -

    v1.PersistentVolumeList

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard list metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    v1.ListMeta

    items

    list of persistent volumes; see http://kubernetes.io/v1.0/docs/user-guide/persistent-volumes.html

    false

    v1.PersistentVolume array

    - -
    -
    -

    v1.ObjectReference

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of the referent; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    namespace

    namespace of the referent; see http://kubernetes.io/v1.0/docs/user-guide/namespaces.html

    false

    string

    name

    name of the referent; see http://kubernetes.io/v1.0/docs/user-guide/identifiers.html#names

    false

    string

    uid

    uid of the referent; see http://kubernetes.io/v1.0/docs/user-guide/identifiers.html#uids

    false

    string

    apiVersion

    API version of the referent

    false

    string

    resourceVersion

    specific resourceVersion to which this reference is made, if any: http://kubernetes.io/v1.0/docs/devel/api-conventions.html#concurrency-control-and-consistency

    false

    string

    fieldPath

    if referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]

    false

    string

    - -
    -
    -

    v1.ContainerStateWaiting

    - ------- - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    reason

    (brief) reason the container is not yet running, such as pulling its image

    false

    string

    - -
    -
    -

    v1.NodeSystemInfo

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    machineID

    machine-id reported by the node

    true

    string

    systemUUID

    system-uuid reported by the node

    true

    string

    bootID

    boot id is the boot-id reported by the node

    true

    string

    kernelVersion

    Kernel version reported by the node from uname -r (e.g. 3.16.0-0.bpo.4-.html64)

    true

    string

    osImage

    OS image used reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy))

    true

    string

    containerRuntimeVersion

    Container runtime version reported by the node through runtime remote API (e.g. docker://1.5.0)

    true

    string

    kubeletVersion

    Kubelet version reported by the node

    true

    string

    kubeProxyVersion

    Kube-proxy version reported by the node

    true

    string

    - -
    -
    -

    v1.ServiceSpec

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    ports

    ports exposed by the service; see http://kubernetes.io/v1.0/docs/user-guide/services.html#virtual-ips-and-service-proxies

    true

    v1.ServicePort array

    selector

    label keys and values that must match in order to receive traffic for this service; if empty, all pods are selected, if not specified, endpoints must be manually specified; see http://kubernetes.io/v1.0/docs/user-guide/services.html#overview

    false

    any

    clusterIP

    IP address of the service; usually assigned by the system; if specified, it will be allocated to the service if unused or else creation of the service will fail; cannot be updated; None can be specified for a headless service when proxying is not required; see http://kubernetes.io/v1.0/docs/user-guide/services.html#virtual-ips-and-service-proxies

    false

    string

    type

    type of this service; must be ClusterIP, NodePort, or LoadBalancer; defaults to ClusterIP; see http://kubernetes.io/v1.0/docs/user-guide/services.html#external-services

    false

    string

    deprecatedPublicIPs

    deprecated. externally visible IPs (e.g. load balancers) that should be proxied to this service

    false

    string array

    sessionAffinity

    enable client IP based session affinity; must be ClientIP or None; defaults to None; see http://kubernetes.io/v1.0/docs/user-guide/services.html#virtual-ips-and-service-proxies

    false

    string

    - -
    -
    -

    v1.Pod

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    kind

    kind of object, in CamelCase; cannot be updated; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#types-kinds

    false

    string

    apiVersion

    version of the schema the object should have; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#resources

    false

    string

    metadata

    standard object metadata; see http://kubernetes.io/v1.0/docs/devel/api-conventions.html#metadata

    false

    v1.ObjectMeta

    spec

    specification of the desired behavior of the pod; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.PodSpec

    status

    most recently observed status of the pod; populated by the system, read-only; http://kubernetes.io/v1.0/docs/devel/api-conventions.html#spec-and-status

    false

    v1.PodStatus

    - -
    -
    -

    v1.NodeSpec

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    podCIDR

    pod IP range assigned to the node

    false

    string

    externalID

    deprecated. External ID assigned to the node by some machine database (e.g. a cloud provider). Defaults to node name when empty.

    false

    string

    providerID

    ID of the node assigned by the cloud provider in the format: <ProviderName>://<ProviderSpecificNodeID>

    false

    string

    unschedulable

    disable pod scheduling on the node; see http://kubernetes.io/v1.0/docs/admin/node.html#manual-node-administration

    false

    boolean

    false

    - -
    -
    -

    v1.EndpointAddress

    - ------- - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescriptionRequiredSchemaDefault

    ip

    IP address of the endpoint

    true

    string

    targetRef

    reference to object providing the endpoint

    false

    v1.ObjectReference

    - -
    -
    -

    any

    -
    -

    Represents an untyped JSON map - see the description of the field for more info about the structure of this object.

    -
    -
    - - - - - - \ No newline at end of file diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/definitions.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/definitions.md deleted file mode 100644 index da32a9b795e2..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/definitions.md +++ /dev/null @@ -1,39 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/api-reference/definitions.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -{% include definitions.html %} - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/api-reference/definitions.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/operations.html b/Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/operations.html deleted file mode 100644 index 191972c603aa..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/operations.html +++ /dev/null @@ -1,23842 +0,0 @@ - - - - - - -Paths - - - - -
    -
    -

    Paths

    -
    -
    -

    create a Binding

    -
    -
    -
    POST /api/v1/bindings
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Binding

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Binding

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list objects of kind ComponentStatus

    -
    -
    -
    GET /api/v1/componentstatuses
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ComponentStatusList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Endpoints

    -
    -
    -
    GET /api/v1/endpoints
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.EndpointsList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Endpoints

    -
    -
    -
    POST /api/v1/endpoints
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Endpoints

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Endpoints

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Event

    -
    -
    -
    GET /api/v1/events
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.EventList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Event

    -
    -
    -
    POST /api/v1/events
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Event

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Event

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind LimitRange

    -
    -
    -
    GET /api/v1/limitranges
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.LimitRangeList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a LimitRange

    -
    -
    -
    POST /api/v1/limitranges
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.LimitRange

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.LimitRange

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Namespace

    -
    -
    -
    GET /api/v1/namespaces
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.NamespaceList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Namespace

    -
    -
    -
    POST /api/v1/namespaces
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Namespace

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Namespace

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Binding

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/bindings
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Binding

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Binding

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list objects of kind ComponentStatus

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/componentstatuses
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ComponentStatusList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified ComponentStatus

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/componentstatuses/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ComponentStatus

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ComponentStatus

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Endpoints

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/endpoints
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.EndpointsList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Endpoints

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/endpoints
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Endpoints

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Endpoints

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified Endpoints

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/endpoints/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Endpoints

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Endpoints

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified Endpoints

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/endpoints/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Endpoints

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Endpoints

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Endpoints

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a Endpoints

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/endpoints/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.DeleteOptions

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Endpoints

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified Endpoints

    -
    -
    -
    PATCH /api/v1/namespaces/{namespace}/endpoints/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Endpoints

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Endpoints

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Event

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/events
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.EventList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Event

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/events
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Event

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Event

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified Event

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/events/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Event

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Event

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified Event

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/events/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Event

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Event

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Event

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a Event

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/events/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Event

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified Event

    -
    -
    -
    PATCH /api/v1/namespaces/{namespace}/events/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Event

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Event

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind LimitRange

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/limitranges
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.LimitRangeList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a LimitRange

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/limitranges
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.LimitRange

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.LimitRange

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified LimitRange

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/limitranges/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the LimitRange

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.LimitRange

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified LimitRange

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/limitranges/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.LimitRange

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the LimitRange

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.LimitRange

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a LimitRange

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/limitranges/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the LimitRange

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified LimitRange

    -
    -
    -
    PATCH /api/v1/namespaces/{namespace}/limitranges/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the LimitRange

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.LimitRange

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind PersistentVolumeClaim

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/persistentvolumeclaims
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolumeClaimList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a PersistentVolumeClaim

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/persistentvolumeclaims
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.PersistentVolumeClaim

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolumeClaim

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified PersistentVolumeClaim

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/persistentvolumeclaims/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the PersistentVolumeClaim

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolumeClaim

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified PersistentVolumeClaim

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/persistentvolumeclaims/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.PersistentVolumeClaim

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the PersistentVolumeClaim

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolumeClaim

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a PersistentVolumeClaim

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/persistentvolumeclaims/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.DeleteOptions

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the PersistentVolumeClaim

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified PersistentVolumeClaim

    -
    -
    -
    PATCH /api/v1/namespaces/{namespace}/persistentvolumeclaims/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the PersistentVolumeClaim

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolumeClaim

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace status of the specified PersistentVolumeClaim

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/persistentvolumeclaims/{name}/status
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.PersistentVolumeClaim

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the PersistentVolumeClaim

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolumeClaim

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Pod

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/pods
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PodList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Pod

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/pods
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Pod

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Pod

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified Pod

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/pods/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Pod

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified Pod

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/pods/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Pod

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Pod

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a Pod

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/pods/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.DeleteOptions

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified Pod

    -
    -
    -
    PATCH /api/v1/namespaces/{namespace}/pods/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Pod

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create binding of a Binding

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/pods/{name}/binding
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Binding

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Binding

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Binding

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect GET requests to exec of Pod

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/pods/{name}/exec
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect POST requests to exec of Pod

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/pods/{name}/exec
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read log of the specified Pod

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/pods/{name}/log
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Pod

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect GET requests to portforward of Pod

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/pods/{name}/portforward
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect POST requests to portforward of Pod

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/pods/{name}/portforward
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect GET requests to proxy of Pod

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/pods/{name}/proxy
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect PUT requests to proxy of Pod

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/pods/{name}/proxy
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect DELETE requests to proxy of Pod

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/pods/{name}/proxy
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect POST requests to proxy of Pod

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/pods/{name}/proxy
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect GET requests to proxy of Pod

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/pods/{name}/proxy/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect PUT requests to proxy of Pod

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/pods/{name}/proxy/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect DELETE requests to proxy of Pod

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/pods/{name}/proxy/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    connect POST requests to proxy of Pod

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/pods/{name}/proxy/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace status of the specified Pod

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/pods/{name}/status
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Pod

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Pod

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind PodTemplate

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/podtemplates
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PodTemplateList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a PodTemplate

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/podtemplates
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.PodTemplate

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PodTemplate

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified PodTemplate

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/podtemplates/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the PodTemplate

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PodTemplate

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified PodTemplate

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/podtemplates/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.PodTemplate

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the PodTemplate

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PodTemplate

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a PodTemplate

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/podtemplates/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.DeleteOptions

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the PodTemplate

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified PodTemplate

    -
    -
    -
    PATCH /api/v1/namespaces/{namespace}/podtemplates/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the PodTemplate

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PodTemplate

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind ReplicationController

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/replicationcontrollers
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ReplicationControllerList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a ReplicationController

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/replicationcontrollers
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.ReplicationController

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ReplicationController

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified ReplicationController

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/replicationcontrollers/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ReplicationController

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ReplicationController

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified ReplicationController

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/replicationcontrollers/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.ReplicationController

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ReplicationController

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ReplicationController

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a ReplicationController

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/replicationcontrollers/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.DeleteOptions

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ReplicationController

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified ReplicationController

    -
    -
    -
    PATCH /api/v1/namespaces/{namespace}/replicationcontrollers/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ReplicationController

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ReplicationController

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind ResourceQuota

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/resourcequotas
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ResourceQuotaList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a ResourceQuota

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/resourcequotas
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.ResourceQuota

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ResourceQuota

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified ResourceQuota

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/resourcequotas/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ResourceQuota

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ResourceQuota

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified ResourceQuota

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/resourcequotas/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.ResourceQuota

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ResourceQuota

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ResourceQuota

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a ResourceQuota

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/resourcequotas/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.DeleteOptions

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ResourceQuota

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified ResourceQuota

    -
    -
    -
    PATCH /api/v1/namespaces/{namespace}/resourcequotas/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ResourceQuota

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ResourceQuota

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace status of the specified ResourceQuota

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/resourcequotas/{name}/status
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.ResourceQuota

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ResourceQuota

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ResourceQuota

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Secret

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/secrets
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.SecretList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Secret

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/secrets
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Secret

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Secret

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified Secret

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/secrets/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Secret

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Secret

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified Secret

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/secrets/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Secret

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Secret

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Secret

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a Secret

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/secrets/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.DeleteOptions

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Secret

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified Secret

    -
    -
    -
    PATCH /api/v1/namespaces/{namespace}/secrets/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Secret

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Secret

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind ServiceAccount

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/serviceaccounts
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ServiceAccountList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a ServiceAccount

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/serviceaccounts
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.ServiceAccount

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ServiceAccount

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified ServiceAccount

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/serviceaccounts/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ServiceAccount

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ServiceAccount

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified ServiceAccount

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/serviceaccounts/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.ServiceAccount

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ServiceAccount

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ServiceAccount

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a ServiceAccount

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/serviceaccounts/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.DeleteOptions

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ServiceAccount

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified ServiceAccount

    -
    -
    -
    PATCH /api/v1/namespaces/{namespace}/serviceaccounts/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ServiceAccount

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ServiceAccount

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Service

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/services
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ServiceList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Service

    -
    -
    -
    POST /api/v1/namespaces/{namespace}/services
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Service

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Service

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified Service

    -
    -
    -
    GET /api/v1/namespaces/{namespace}/services/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Service

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified Service

    -
    -
    -
    PUT /api/v1/namespaces/{namespace}/services/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Service

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Service

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a Service

    -
    -
    -
    DELETE /api/v1/namespaces/{namespace}/services/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified Service

    -
    -
    -
    PATCH /api/v1/namespaces/{namespace}/services/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Service

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified Namespace

    -
    -
    -
    GET /api/v1/namespaces/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    name

    name of the Namespace

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Namespace

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified Namespace

    -
    -
    -
    PUT /api/v1/namespaces/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Namespace

    PathParameter

    name

    name of the Namespace

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Namespace

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a Namespace

    -
    -
    -
    DELETE /api/v1/namespaces/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.DeleteOptions

    PathParameter

    name

    name of the Namespace

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified Namespace

    -
    -
    -
    PATCH /api/v1/namespaces/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    name

    name of the Namespace

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Namespace

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace finalize of the specified Namespace

    -
    -
    -
    PUT /api/v1/namespaces/{name}/finalize
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Namespace

    PathParameter

    name

    name of the Namespace

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Namespace

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace status of the specified Namespace

    -
    -
    -
    PUT /api/v1/namespaces/{name}/status
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Namespace

    PathParameter

    name

    name of the Namespace

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Namespace

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Node

    -
    -
    -
    GET /api/v1/nodes
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.NodeList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Node

    -
    -
    -
    POST /api/v1/nodes
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Node

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Node

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified Node

    -
    -
    -
    GET /api/v1/nodes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    name

    name of the Node

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Node

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified Node

    -
    -
    -
    PUT /api/v1/nodes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Node

    PathParameter

    name

    name of the Node

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Node

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a Node

    -
    -
    -
    DELETE /api/v1/nodes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.DeleteOptions

    PathParameter

    name

    name of the Node

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified Node

    -
    -
    -
    PATCH /api/v1/nodes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    name

    name of the Node

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Node

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace status of the specified Node

    -
    -
    -
    PUT /api/v1/nodes/{name}/status
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Node

    PathParameter

    name

    name of the Node

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Node

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind PersistentVolumeClaim

    -
    -
    -
    GET /api/v1/persistentvolumeclaims
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolumeClaimList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a PersistentVolumeClaim

    -
    -
    -
    POST /api/v1/persistentvolumeclaims
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.PersistentVolumeClaim

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolumeClaim

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind PersistentVolume

    -
    -
    -
    GET /api/v1/persistentvolumes
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolumeList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a PersistentVolume

    -
    -
    -
    POST /api/v1/persistentvolumes
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.PersistentVolume

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolume

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    read the specified PersistentVolume

    -
    -
    -
    GET /api/v1/persistentvolumes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    PathParameter

    name

    name of the PersistentVolume

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolume

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace the specified PersistentVolume

    -
    -
    -
    PUT /api/v1/persistentvolumes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.PersistentVolume

    PathParameter

    name

    name of the PersistentVolume

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolume

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    delete a PersistentVolume

    -
    -
    -
    DELETE /api/v1/persistentvolumes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.DeleteOptions

    PathParameter

    name

    name of the PersistentVolume

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Status

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    partially update the specified PersistentVolume

    -
    -
    -
    PATCH /api/v1/persistentvolumes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    api.Patch

    PathParameter

    name

    name of the PersistentVolume

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolume

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      application/json-patch+json

      -
    • -
    • -

      application/merge-patch+json

      -
    • -
    • -

      application/strategic-merge-patch+json

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    replace status of the specified PersistentVolume

    -
    -
    -
    PUT /api/v1/persistentvolumes/{name}/status
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.PersistentVolume

    PathParameter

    name

    name of the PersistentVolume

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PersistentVolume

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Pod

    -
    -
    -
    GET /api/v1/pods
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PodList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Pod

    -
    -
    -
    POST /api/v1/pods
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Pod

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Pod

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind PodTemplate

    -
    -
    -
    GET /api/v1/podtemplates
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PodTemplateList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a PodTemplate

    -
    -
    -
    POST /api/v1/podtemplates
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.PodTemplate

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.PodTemplate

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy GET requests to Pod

    -
    -
    -
    GET /api/v1/proxy/namespaces/{namespace}/pods/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy PUT requests to Pod

    -
    -
    -
    PUT /api/v1/proxy/namespaces/{namespace}/pods/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy DELETE requests to Pod

    -
    -
    -
    DELETE /api/v1/proxy/namespaces/{namespace}/pods/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy POST requests to Pod

    -
    -
    -
    POST /api/v1/proxy/namespaces/{namespace}/pods/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy GET requests to Pod

    -
    -
    -
    GET /api/v1/proxy/namespaces/{namespace}/pods/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy PUT requests to Pod

    -
    -
    -
    PUT /api/v1/proxy/namespaces/{namespace}/pods/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy DELETE requests to Pod

    -
    -
    -
    DELETE /api/v1/proxy/namespaces/{namespace}/pods/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy POST requests to Pod

    -
    -
    -
    POST /api/v1/proxy/namespaces/{namespace}/pods/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy GET requests to Service

    -
    -
    -
    GET /api/v1/proxy/namespaces/{namespace}/services/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy PUT requests to Service

    -
    -
    -
    PUT /api/v1/proxy/namespaces/{namespace}/services/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy DELETE requests to Service

    -
    -
    -
    DELETE /api/v1/proxy/namespaces/{namespace}/services/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy POST requests to Service

    -
    -
    -
    POST /api/v1/proxy/namespaces/{namespace}/services/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy GET requests to Service

    -
    -
    -
    GET /api/v1/proxy/namespaces/{namespace}/services/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy PUT requests to Service

    -
    -
    -
    PUT /api/v1/proxy/namespaces/{namespace}/services/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy DELETE requests to Service

    -
    -
    -
    DELETE /api/v1/proxy/namespaces/{namespace}/services/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy POST requests to Service

    -
    -
    -
    POST /api/v1/proxy/namespaces/{namespace}/services/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy GET requests to Node

    -
    -
    -
    GET /api/v1/proxy/nodes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    name

    name of the Node

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy PUT requests to Node

    -
    -
    -
    PUT /api/v1/proxy/nodes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    name

    name of the Node

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy DELETE requests to Node

    -
    -
    -
    DELETE /api/v1/proxy/nodes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    name

    name of the Node

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy POST requests to Node

    -
    -
    -
    POST /api/v1/proxy/nodes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    name

    name of the Node

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy GET requests to Node

    -
    -
    -
    GET /api/v1/proxy/nodes/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    name

    name of the Node

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy PUT requests to Node

    -
    -
    -
    PUT /api/v1/proxy/nodes/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    name

    name of the Node

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy DELETE requests to Node

    -
    -
    -
    DELETE /api/v1/proxy/nodes/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    name

    name of the Node

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    proxy POST requests to Node

    -
    -
    -
    POST /api/v1/proxy/nodes/{name}/{path:*}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    PathParameter

    name

    name of the Node

    true

    string

    PathParameter

    path:*

    path to the resource

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    default

    success

    string

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind ReplicationController

    -
    -
    -
    GET /api/v1/replicationcontrollers
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ReplicationControllerList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a ReplicationController

    -
    -
    -
    POST /api/v1/replicationcontrollers
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.ReplicationController

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ReplicationController

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind ResourceQuota

    -
    -
    -
    GET /api/v1/resourcequotas
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ResourceQuotaList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a ResourceQuota

    -
    -
    -
    POST /api/v1/resourcequotas
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.ResourceQuota

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ResourceQuota

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Secret

    -
    -
    -
    GET /api/v1/secrets
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.SecretList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Secret

    -
    -
    -
    POST /api/v1/secrets
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Secret

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Secret

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind ServiceAccount

    -
    -
    -
    GET /api/v1/serviceaccounts
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ServiceAccountList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a ServiceAccount

    -
    -
    -
    POST /api/v1/serviceaccounts
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.ServiceAccount

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ServiceAccount

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    list or watch objects of kind Service

    -
    -
    -
    GET /api/v1/services
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.ServiceList

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    create a Service

    -
    -
    -
    POST /api/v1/services
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    BodyParameter

    body

    true

    v1.Service

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    v1.Service

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Endpoints

    -
    -
    -
    GET /api/v1/watch/endpoints
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Event

    -
    -
    -
    GET /api/v1/watch/events
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of LimitRange

    -
    -
    -
    GET /api/v1/watch/limitranges
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Namespace

    -
    -
    -
    GET /api/v1/watch/namespaces
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Endpoints

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/endpoints
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind Endpoints

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/endpoints/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Endpoints

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Event

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/events
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind Event

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/events/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Event

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of LimitRange

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/limitranges
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind LimitRange

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/limitranges/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the LimitRange

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of PersistentVolumeClaim

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/persistentvolumeclaims
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind PersistentVolumeClaim

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/persistentvolumeclaims/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the PersistentVolumeClaim

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Pod

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/pods
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind Pod

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/pods/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Pod

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of PodTemplate

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/podtemplates
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind PodTemplate

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/podtemplates/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the PodTemplate

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of ReplicationController

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/replicationcontrollers
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind ReplicationController

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/replicationcontrollers/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ReplicationController

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of ResourceQuota

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/resourcequotas
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind ResourceQuota

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/resourcequotas/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ResourceQuota

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Secret

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/secrets
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind Secret

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/secrets/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Secret

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of ServiceAccount

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/serviceaccounts
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind ServiceAccount

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/serviceaccounts/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the ServiceAccount

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Service

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/services
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind Service

    -
    -
    -
    GET /api/v1/watch/namespaces/{namespace}/services/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    namespace

    object name and auth scope, such as for teams and projects

    true

    string

    PathParameter

    name

    name of the Service

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind Namespace

    -
    -
    -
    GET /api/v1/watch/namespaces/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    name

    name of the Namespace

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Node

    -
    -
    -
    GET /api/v1/watch/nodes
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind Node

    -
    -
    -
    GET /api/v1/watch/nodes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    name

    name of the Node

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of PersistentVolumeClaim

    -
    -
    -
    GET /api/v1/watch/persistentvolumeclaims
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of PersistentVolume

    -
    -
    -
    GET /api/v1/watch/persistentvolumes
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch changes to an object of kind PersistentVolume

    -
    -
    -
    GET /api/v1/watch/persistentvolumes/{name}
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    PathParameter

    name

    name of the PersistentVolume

    true

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Pod

    -
    -
    -
    GET /api/v1/watch/pods
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of PodTemplate

    -
    -
    -
    GET /api/v1/watch/podtemplates
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of ReplicationController

    -
    -
    -
    GET /api/v1/watch/replicationcontrollers
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of ResourceQuota

    -
    -
    -
    GET /api/v1/watch/resourcequotas
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Secret

    -
    -
    -
    GET /api/v1/watch/secrets
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of ServiceAccount

    -
    -
    -
    GET /api/v1/watch/serviceaccounts
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -

    watch individual changes to a list of Service

    -
    -
    -
    GET /api/v1/watch/services
    -
    -
    -
    -

    Parameters

    - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeNameDescriptionRequiredSchemaDefault

    QueryParameter

    pretty

    If true, then the output is pretty printed.

    false

    string

    QueryParameter

    labelSelector

    a selector to restrict the list of returned objects by their labels; defaults to everything

    false

    string

    QueryParameter

    fieldSelector

    a selector to restrict the list of returned objects by their fields; defaults to everything

    false

    string

    QueryParameter

    watch

    watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion

    false

    boolean

    QueryParameter

    resourceVersion

    when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history

    false

    string

    - -
    -
    -

    Responses

    - ----- - - - - - - - - - - - - - - -
    HTTP CodeDescriptionSchema

    200

    success

    json.WatchEvent

    - -
    -
    -

    Consumes

    -
    -
      -
    • -

      /

      -
    • -
    -
    -
    -
    -

    Produces

    -
    -
      -
    • -

      application/json

      -
    • -
    -
    -
    -
    -

    Tags

    -
    -
      -
    • -

      apiv1

      -
    • -
    -
    -
    -
    -
    -
    -
    - - - \ No newline at end of file diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/operations.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/operations.md deleted file mode 100644 index f1b4d27abbe5..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/api-reference/operations.md +++ /dev/null @@ -1,39 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/api-reference/operations.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -{% include operations.html %} - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/api-reference/operations.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/api.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/api.md deleted file mode 100644 index 55aaa3e86e97..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/api.md +++ /dev/null @@ -1,110 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/api.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# The Kubernetes API - -Primary system and API concepts are documented in the [User guide](user-guide/README.md). - -Overall API conventions are described in the [API conventions doc](devel/api-conventions.md). - -Complete API details are documented via [Swagger](http://swagger.io/). The Kubernetes apiserver (aka "master") exports an API that can be used to retrieve the [Swagger spec](https://github.com/swagger-api/swagger-spec/tree/master/schemas/v1.2) for the Kubernetes API, by default at `/swaggerapi`, and a UI you can use to browse the API documentation at `/swagger-ui`. We also periodically update a [statically generated UI](http://kubernetes.io/third_party/swagger-ui/). - -Remote access to the API is discussed in the [access doc](admin/accessing-the-api.md). - -The Kubernetes API also serves as the foundation for the declarative configuration schema for the system. The [Kubectl](user-guide/kubectl/kubectl.md) command-line tool can be used to create, update, delete, and get API objects. - -Kubernetes also stores its serialized state (currently in [etcd](https://coreos.com/docs/distributed-configuration/getting-started-with-etcd/)) in terms of the API resources. - -Kubernetes itself is decomposed into multiple components, which interact through its API. - -## API changes - -In our experience, any system that is successful needs to grow and change as new use cases emerge or existing ones change. Therefore, we expect the Kubernetes API to continuously change and grow. However, we intend to not break compatibility with existing clients, for an extended period of time. In general, new API resources and new resource fields can be expected to be added frequently. Elimination of resources or fields will require following a deprecation process. The precise deprecation policy for eliminating features is TBD, but once we reach our 1.0 milestone, there will be a specific policy. - -What constitutes a compatible change and how to change the API are detailed by the [API change document](devel/api_changes.md). - -## API versioning - -To make it easier to eliminate fields or restructure resource representations, Kubernetes supports multiple API versions, each at a different API path prefix, such as `/api/v1beta3`. These are simply different interfaces to read and/or modify the same underlying resources. In general, all API resources are accessible via all API versions, though there may be some cases in the future where that is not true. - -We chose to version at the API level rather than at the resource or field level to ensure that the API presents a clear, consistent view of system resources and behavior, and to enable controlling access to end-of-lifed and/or experimental APIs. - -The [API and release versioning proposal](design/versioning.md) describes the current thinking on the API version evolution process. - -## v1beta1, v1beta2, and v1beta3 are deprecated; please move to v1 ASAP - -As of June 4, 2015, the Kubernetes v1 API has been enabled by default. The v1beta1 and v1beta2 APIs were deleted on June 1, 2015. v1beta3 is planned to be deleted on July 6, 2015. - -### v1 conversion tips (from v1beta3) - -We're working to convert all documentation and examples to v1. A simple [API conversion tool](admin/cluster-management.md#switching-your-config-files-to-a-new-api-version) has been written to simplify the translation process. Use `kubectl create --validate` in order to validate your json or yaml against our Swagger spec. - -Changes to services are the most significant difference between v1beta3 and v1. - -* The `service.spec.portalIP` property is renamed to `service.spec.clusterIP`. -* The `service.spec.createExternalLoadBalancer` property is removed. Specify `service.spec.type: "LoadBalancer"` to create an external load balancer instead. -* The `service.spec.publicIPs` property is deprecated and now called `service.spec.deprecatedPublicIPs`. This property will be removed entirely when v1beta3 is removed. The vast majority of users of this field were using it to expose services on ports on the node. Those users should specify `service.spec.type: "NodePort"` instead. Read [External Services](user-guide/services.md#external-services) for more info. If this is not sufficient for your use case, please file an issue or contact @thockin. - -Some other difference between v1beta3 and v1: - -* The `pod.spec.containers[*].privileged` and `pod.spec.containers[*].capabilities` properties are now nested under the `pod.spec.containers[*].securityContext` property. See [Security Contexts](user-guide/security-context.md). -* The `pod.spec.host` property is renamed to `pod.spec.nodeName`. -* The `endpoints.subsets[*].addresses.IP` property is renamed to `endpoints.subsets[*].addresses.ip`. -* The `pod.status.containerStatuses[*].state.termination` and `pod.status.containerStatuses[*].lastState.termination` properties are renamed to `pod.status.containerStatuses[*].state.terminated` and `pod.status.containerStatuses[*].lastState.terminated` respectively. -* The `pod.status.Condition` property is renamed to `pod.status.conditions`. -* The `status.details.id` property is renamed to `status.details.name`. - -### v1beta3 conversion tips (from v1beta1/2) - -Some important differences between v1beta1/2 and v1beta3: - -* The resource `id` is now called `name`. -* `name`, `labels`, `annotations`, and other metadata are now nested in a map called `metadata` -* `desiredState` is now called `spec`, and `currentState` is now called `status` -* `/minions` has been moved to `/nodes`, and the resource has kind `Node` -* The namespace is required (for all namespaced resources) and has moved from a URL parameter to the path: `/api/v1beta3/namespaces/{namespace}/{resource_collection}/{resource_name}`. If you were not using a namespace before, use `default` here. -* The names of all resource collections are now lower cased - instead of `replicationControllers`, use `replicationcontrollers`. -* To watch for changes to a resource, open an HTTP or Websocket connection to the collection query and provide the `?watch=true` query parameter along with the desired `resourceVersion` parameter to watch from. -* The `labels` query parameter has been renamed to `labelSelector`. -* The `fields` query parameter has been renamed to `fieldSelector`. -* The container `entrypoint` has been renamed to `command`, and `command` has been renamed to `args`. -* Container, volume, and node resources are expressed as nested maps (e.g., `resources{cpu:1}`) rather than as individual fields, and resource values support [scaling suffixes](user-guide/compute-resources.md#specifying-resource-quantities) rather than fixed scales (e.g., milli-cores). -* Restart policy is represented simply as a string (e.g., `"Always"`) rather than as a nested map (`always{}`). -* Pull policies changed from `PullAlways`, `PullNever`, and `PullIfNotPresent` to `Always`, `Never`, and `IfNotPresent`. -* The volume `source` is inlined into `volume` rather than nested. -* Host volumes have been changed from `hostDir` to `hostPath` to better reflect that they can be files or directories. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/api.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/README.md deleted file mode 100644 index 72d2c662afc8..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/README.md +++ /dev/null @@ -1,55 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes Design Overview - -Kubernetes is a system for managing containerized applications across multiple hosts, providing basic mechanisms for deployment, maintenance, and scaling of applications. - -Kubernetes establishes robust declarative primitives for maintaining the desired state requested by the user. We see these primitives as the main value added by Kubernetes. Self-healing mechanisms, such as auto-restarting, re-scheduling, and replicating containers require active controllers, not just imperative orchestration. - -Kubernetes is primarily targeted at applications composed of multiple containers, such as elastic, distributed micro-services. It is also designed to facilitate migration of non-containerized application stacks to Kubernetes. It therefore includes abstractions for grouping containers in both loosely coupled and tightly coupled formations, and provides ways for containers to find and communicate with each other in relatively familiar ways. - -Kubernetes enables users to ask a cluster to run a set of containers. The system automatically chooses hosts to run those containers on. While Kubernetes's scheduler is currently very simple, we expect it to grow in sophistication over time. Scheduling is a policy-rich, topology-aware, workload-specific function that significantly impacts availability, performance, and capacity. The scheduler needs to take into account individual and collective resource requirements, quality of service requirements, hardware/software/policy constraints, affinity and anti-affinity specifications, data locality, inter-workload interference, deadlines, and so on. Workload-specific requirements will be exposed through the API as necessary. - -Kubernetes is intended to run on a number of cloud providers, as well as on physical hosts. - -A single Kubernetes cluster is not intended to span multiple availability zones. Instead, we recommend building a higher-level layer to replicate complete deployments of highly available applications across multiple zones (see [the multi-cluster doc](../admin/multi-cluster.md) and [cluster federation proposal](../proposals/federation.md) for more details). - -Finally, Kubernetes aspires to be an extensible, pluggable, building-block OSS platform and toolkit. Therefore, architecturally, we want Kubernetes to be built as a collection of pluggable components and layers, with the ability to use alternative schedulers, controllers, storage systems, and distribution mechanisms, and we're evolving its current code in that direction. Furthermore, we want others to be able to extend Kubernetes functionality, such as with higher-level PaaS functionality or multi-cluster layers, without modification of core Kubernetes source. Therefore, its API isn't just (or even necessarily mainly) targeted at end users, but at tool and extension developers. Its APIs are intended to serve as the foundation for an open ecosystem of tools, automation systems, and higher-level API layers. Consequently, there are no "internal" inter-component APIs. All APIs are visible and available, including the APIs used by the scheduler, the node controller, the replication-controller manager, Kubelet's API, etc. There's no glass to break -- in order to handle more complex use cases, one can just access the lower-level APIs in a fully transparent, composable manner. - -For more about the Kubernetes architecture, see [architecture](architecture.md). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/access.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/access.md deleted file mode 100644 index e2f1d66c1f03..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/access.md +++ /dev/null @@ -1,294 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/access.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# K8s Identity and Access Management Sketch - -This document suggests a direction for identity and access management in the Kubernetes system. - - -## Background - -High level goals are: - - Have a plan for how identity, authentication, and authorization will fit in to the API. - - Have a plan for partitioning resources within a cluster between independent organizational units. - - Ease integration with existing enterprise and hosted scenarios. - -### Actors - -Each of these can act as normal users or attackers. - - External Users: People who are accessing applications running on K8s (e.g. a web site served by webserver running in a container on K8s), but who do not have K8s API access. - - K8s Users : People who access the K8s API (e.g. create K8s API objects like Pods) - - K8s Project Admins: People who manage access for some K8s Users - - K8s Cluster Admins: People who control the machines, networks, or binaries that make up a K8s cluster. - - K8s Admin means K8s Cluster Admins and K8s Project Admins taken together. - -### Threats - -Both intentional attacks and accidental use of privilege are concerns. - -For both cases it may be useful to think about these categories differently: - - Application Path - attack by sending network messages from the internet to the IP/port of any application running on K8s. May exploit weakness in application or misconfiguration of K8s. - - K8s API Path - attack by sending network messages to any K8s API endpoint. - - Insider Path - attack on K8s system components. Attacker may have privileged access to networks, machines or K8s software and data. Software errors in K8s system components and administrator error are some types of threat in this category. - -This document is primarily concerned with K8s API paths, and secondarily with Internal paths. The Application path also needs to be secure, but is not the focus of this document. - -### Assets to protect - -External User assets: - - Personal information like private messages, or images uploaded by External Users - - web server logs - -K8s User assets: - - External User assets of each K8s User - - things private to the K8s app, like: - - credentials for accessing other services (docker private repos, storage services, facebook, etc) - - SSL certificates for web servers - - proprietary data and code - -K8s Cluster assets: - - Assets of each K8s User - - Machine Certificates or secrets. - - The value of K8s cluster computing resources (cpu, memory, etc). - -This document is primarily about protecting K8s User assets and K8s cluster assets from other K8s Users and K8s Project and Cluster Admins. - -### Usage environments - -Cluster in Small organization: - - K8s Admins may be the same people as K8s Users. - - few K8s Admins. - - prefer ease of use to fine-grained access control/precise accounting, etc. - - Product requirement that it be easy for potential K8s Cluster Admin to try out setting up a simple cluster. - -Cluster in Large organization: - - K8s Admins typically distinct people from K8s Users. May need to divide K8s Cluster Admin access by roles. - - K8s Users need to be protected from each other. - - Auditing of K8s User and K8s Admin actions important. - - flexible accurate usage accounting and resource controls important. - - Lots of automated access to APIs. - - Need to integrate with existing enterprise directory, authentication, accounting, auditing, and security policy infrastructure. - -Org-run cluster: - - organization that runs K8s master components is same as the org that runs apps on K8s. - - Nodes may be on-premises VMs or physical machines; Cloud VMs; or a mix. - -Hosted cluster: - - Offering K8s API as a service, or offering a Paas or Saas built on K8s - - May already offer web services, and need to integrate with existing customer account concept, and existing authentication, accounting, auditing, and security policy infrastructure. - - May want to leverage K8s User accounts and accounting to manage their User accounts (not a priority to support this use case.) - - Precise and accurate accounting of resources needed. Resource controls needed for hard limits (Users given limited slice of data) and soft limits (Users can grow up to some limit and then be expanded). - -K8s ecosystem services: - - There may be companies that want to offer their existing services (Build, CI, A/B-test, release automation, etc) for use with K8s. There should be some story for this case. - -Pods configs should be largely portable between Org-run and hosted configurations. - - -# Design - -Related discussion: -- https://k8s.io/kubernetes/issues/442 -- https://k8s.io/kubernetes/issues/443 - -This doc describes two security profiles: - - Simple profile: like single-user mode. Make it easy to evaluate K8s without lots of configuring accounts and policies. Protects from unauthorized users, but does not partition authorized users. - - Enterprise profile: Provide mechanisms needed for large numbers of users. Defense in depth. Should integrate with existing enterprise security infrastructure. - -K8s distribution should include templates of config, and documentation, for simple and enterprise profiles. System should be flexible enough for knowledgeable users to create intermediate profiles, but K8s developers should only reason about those two Profiles, not a matrix. - -Features in this doc are divided into "Initial Feature", and "Improvements". Initial features would be candidates for version 1.00. - -## Identity - -### userAccount - -K8s will have a `userAccount` API object. -- `userAccount` has a UID which is immutable. This is used to associate users with objects and to record actions in audit logs. -- `userAccount` has a name which is a string and human readable and unique among userAccounts. It is used to refer to users in Policies, to ensure that the Policies are human readable. It can be changed only when there are no Policy objects or other objects which refer to that name. An email address is a suggested format for this field. -- `userAccount` is not related to the unix username of processes in Pods created by that userAccount. -- `userAccount` API objects can have labels - -The system may associate one or more Authentication Methods with a -`userAccount` (but they are not formally part of the userAccount object.) -In a simple deployment, the authentication method for a -user might be an authentication token which is verified by a K8s server. In a -more complex deployment, the authentication might be delegated to -another system which is trusted by the K8s API to authenticate users, but where -the authentication details are unknown to K8s. - -Initial Features: -- there is no superuser `userAccount` -- `userAccount` objects are statically populated in the K8s API store by reading a config file. Only a K8s Cluster Admin can do this. -- `userAccount` can have a default `namespace`. If API call does not specify a `namespace`, the default `namespace` for that caller is assumed. -- `userAccount` is global. A single human with access to multiple namespaces is recommended to only have one userAccount. - -Improvements: -- Make `userAccount` part of a separate API group from core K8s objects like `pod`. Facilitates plugging in alternate Access Management. - -Simple Profile: - - single `userAccount`, used by all K8s Users and Project Admins. One access token shared by all. - -Enterprise Profile: - - every human user has own `userAccount`. - - `userAccount`s have labels that indicate both membership in groups, and ability to act in certain roles. - - each service using the API has own `userAccount` too. (e.g. `scheduler`, `repcontroller`) - - automated jobs to denormalize the ldap group info into the local system list of users into the K8s userAccount file. - -### Unix accounts - -A `userAccount` is not a Unix user account. The fact that a pod is started by a `userAccount` does not mean that the processes in that pod's containers run as a Unix user with a corresponding name or identity. - -Initially: -- The unix accounts available in a container, and used by the processes running in a container are those that are provided by the combination of the base operating system and the Docker manifest. -- Kubernetes doesn't enforce any relation between `userAccount` and unix accounts. - -Improvements: -- Kubelet allocates disjoint blocks of root-namespace uids for each container. This may provide some defense-in-depth against container escapes. (https://github.com/docker/docker/pull/4572) -- requires docker to integrate user namespace support, and deciding what getpwnam() does for these uids. -- any features that help users avoid use of privileged containers (https://k8s.io/kubernetes/issues/391) - -### Namespaces - -K8s will have a have a `namespace` API object. It is similar to a Google Compute Engine `project`. It provides a namespace for objects created by a group of people co-operating together, preventing name collisions with non-cooperating groups. It also serves as a reference point for authorization policies. - -Namespaces are described in [namespaces.md](namespaces.md). - -In the Enterprise Profile: - - a `userAccount` may have permission to access several `namespace`s. - -In the Simple Profile: - - There is a single `namespace` used by the single user. - -Namespaces versus userAccount vs Labels: -- `userAccount`s are intended for audit logging (both name and UID should be logged), and to define who has access to `namespace`s. -- `labels` (see [docs/user-guide/labels.md](../../docs/user-guide/labels.md)) should be used to distinguish pods, users, and other objects that cooperate towards a common goal but are different in some way, such as version, or responsibilities. -- `namespace`s prevent name collisions between uncoordinated groups of people, and provide a place to attach common policies for co-operating groups of people. - - -## Authentication - -Goals for K8s authentication: -- Include a built-in authentication system with no configuration required to use in single-user mode, and little configuration required to add several user accounts, and no https proxy required. -- Allow for authentication to be handled by a system external to Kubernetes, to allow integration with existing to enterprise authorization systems. The Kubernetes namespace itself should avoid taking contributions of multiple authorization schemes. Instead, a trusted proxy in front of the apiserver can be used to authenticate users. - - For organizations whose security requirements only allow FIPS compliant implementations (e.g. apache) for authentication. - - So the proxy can terminate SSL, and isolate the CA-signed certificate from less trusted, higher-touch APIserver. - - For organizations that already have existing SaaS web services (e.g. storage, VMs) and want a common authentication portal. -- Avoid mixing authentication and authorization, so that authorization policies be centrally managed, and to allow changes in authentication methods without affecting authorization code. - -Initially: -- Tokens used to authenticate a user. -- Long lived tokens identify a particular `userAccount`. -- Administrator utility generates tokens at cluster setup. -- OAuth2.0 Bearer tokens protocol, http://tools.ietf.org/html/rfc6750 -- No scopes for tokens. Authorization happens in the API server -- Tokens dynamically generated by apiserver to identify pods which are making API calls. -- Tokens checked in a module of the APIserver. -- Authentication in apiserver can be disabled by flag, to allow testing without authorization enabled, and to allow use of an authenticating proxy. In this mode, a query parameter or header added by the proxy will identify the caller. - -Improvements: -- Refresh of tokens. -- SSH keys to access inside containers. - -To be considered for subsequent versions: -- Fuller use of OAuth (http://tools.ietf.org/html/rfc6749) -- Scoped tokens. -- Tokens that are bound to the channel between the client and the api server - - http://www.ietf.org/proceedings/90/slides/slides-90-uta-0.pdf - - http://www.browserauth.net - - -## Authorization - -K8s authorization should: -- Allow for a range of maturity levels, from single-user for those test driving the system, to integration with existing to enterprise authorization systems. -- Allow for centralized management of users and policies. In some organizations, this will mean that the definition of users and access policies needs to reside on a system other than k8s and encompass other web services (such as a storage service). -- Allow processes running in K8s Pods to take on identity, and to allow narrow scoping of permissions for those identities in order to limit damage from software faults. -- Have Authorization Policies exposed as API objects so that a single config file can create or delete Pods, Replication Controllers, Services, and the identities and policies for those Pods and Replication Controllers. -- Be separate as much as practical from Authentication, to allow Authentication methods to change over time and space, without impacting Authorization policies. - -K8s will implement a relatively simple -[Attribute-Based Access Control](http://en.wikipedia.org/wiki/Attribute_Based_Access_Control) model. -The model will be described in more detail in a forthcoming document. The model will -- Be less complex than XACML -- Be easily recognizable to those familiar with Amazon IAM Policies. -- Have a subset/aliases/defaults which allow it to be used in a way comfortable to those users more familiar with Role-Based Access Control. - -Authorization policy is set by creating a set of Policy objects. - -The API Server will be the Enforcement Point for Policy. For each API call that it receives, it will construct the Attributes needed to evaluate the policy (what user is making the call, what resource they are accessing, what they are trying to do that resource, etc) and pass those attributes to a Decision Point. The Decision Point code evaluates the Attributes against all the Policies and allows or denies the API call. The system will be modular enough that the Decision Point code can either be linked into the APIserver binary, or be another service that the apiserver calls for each Decision (with appropriate time-limited caching as needed for performance). - -Policy objects may be applicable only to a single namespace or to all namespaces; K8s Project Admins would be able to create those as needed. Other Policy objects may be applicable to all namespaces; a K8s Cluster Admin might create those in order to authorize a new type of controller to be used by all namespaces, or to make a K8s User into a K8s Project Admin.) - - -## Accounting - -The API should have a `quota` concept (see https://k8s.io/kubernetes/issues/442). A quota object relates a namespace (and optionally a label selector) to a maximum quantity of resources that may be used (see [resources design doc](resources.md)). - -Initially: -- a `quota` object is immutable. -- for hosted K8s systems that do billing, Project is recommended level for billing accounts. -- Every object that consumes resources should have a `namespace` so that Resource usage stats are roll-up-able to `namespace`. -- K8s Cluster Admin sets quota objects by writing a config file. - -Improvements: -- allow one namespace to charge the quota for one or more other namespaces. This would be controlled by a policy which allows changing a billing_namespace= label on an object. -- allow quota to be set by namespace owners for (namespace x label) combinations (e.g. let "webserver" namespace use 100 cores, but to prevent accidents, don't allow "webserver" namespace and "instance=test" use more than 10 cores. -- tools to help write consistent quota config files based on number of nodes, historical namespace usages, QoS needs, etc. -- way for K8s Cluster Admin to incrementally adjust Quota objects. - -Simple profile: - - a single `namespace` with infinite resource limits. - -Enterprise profile: - - multiple namespaces each with their own limits. - -Issues: -- need for locking or "eventual consistency" when multiple apiserver goroutines are accessing the object store and handling pod creations. - - -## Audit Logging - -API actions can be logged. - -Initial implementation: -- All API calls logged to nginx logs. - -Improvements: -- API server does logging instead. -- Policies to drop logging for high rate trusted API calls, or by users performing audit or other sensitive functions. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/access.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control.md deleted file mode 100644 index 77e8b398a7da..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control.md +++ /dev/null @@ -1,117 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/admission_control.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes Proposal - Admission Control - -**Related PR:** - -| Topic | Link | -| ----- | ---- | -| Separate validation from RESTStorage | https://k8s.io/kubernetes/issues/2977 | - -## Background - -High level goals: - -* Enable an easy-to-use mechanism to provide admission control to cluster -* Enable a provider to support multiple admission control strategies or author their own -* Ensure any rejected request can propagate errors back to the caller with why the request failed - -Authorization via policy is focused on answering if a user is authorized to perform an action. - -Admission Control is focused on if the system will accept an authorized action. - -Kubernetes may choose to dismiss an authorized action based on any number of admission control strategies. - -This proposal documents the basic design, and describes how any number of admission control plug-ins could be injected. - -Implementation of specific admission control strategies are handled in separate documents. - -## kube-apiserver - -The kube-apiserver takes the following OPTIONAL arguments to enable admission control - -| Option | Behavior | -| ------ | -------- | -| admission_control | Comma-delimited, ordered list of admission control choices to invoke prior to modifying or deleting an object. | -| admission_control_config_file | File with admission control configuration parameters to boot-strap plug-in. | - -An **AdmissionControl** plug-in is an implementation of the following interface: - -```go -package admission - -// Attributes is an interface used by a plug-in to make an admission decision on a individual request. -type Attributes interface { - GetNamespace() string - GetKind() string - GetOperation() string - GetObject() runtime.Object -} - -// Interface is an abstract, pluggable interface for Admission Control decisions. -type Interface interface { - // Admit makes an admission decision based on the request attributes - // An error is returned if it denies the request. - Admit(a Attributes) (err error) -} -``` - -A **plug-in** must be compiled with the binary, and is registered as an available option by providing a name, and implementation -of admission.Interface. - -```go -func init() { - admission.RegisterPlugin("AlwaysDeny", func(client client.Interface, config io.Reader) (admission.Interface, error) { return NewAlwaysDeny(), nil }) -} -``` - -Invocation of admission control is handled by the **APIServer** and not individual **RESTStorage** implementations. - -This design assumes that **Issue 297** is adopted, and as a consequence, the general framework of the APIServer request/response flow -will ensure the following: - -1. Incoming request -2. Authenticate user -3. Authorize user -4. If operation=create|update, then validate(object) -5. If operation=create|update|delete, then admission.Admit(requestAttributes) - a. invoke each admission.Interface object in sequence -6. Object is persisted - -If at any step, there is an error, the request is canceled. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/admission_control.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control_limit_range.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control_limit_range.md deleted file mode 100644 index b1baf1f0f346..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control_limit_range.md +++ /dev/null @@ -1,174 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/admission_control_limit_range.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Admission control plugin: LimitRanger - -## Background - -This document proposes a system for enforcing min/max limits per resource as part of admission control. - -## Model Changes - -A new resource, **LimitRange**, is introduced to enumerate min/max limits for a resource type scoped to a -Kubernetes namespace. - -```go -const ( - // Limit that applies to all pods in a namespace - LimitTypePod string = "Pod" - // Limit that applies to all containers in a namespace - LimitTypeContainer string = "Container" -) - -// LimitRangeItem defines a min/max usage limit for any resource that matches on kind -type LimitRangeItem struct { - // Type of resource that this limit applies to - Type string `json:"type,omitempty"` - // Max usage constraints on this kind by resource name - Max ResourceList `json:"max,omitempty"` - // Min usage constraints on this kind by resource name - Min ResourceList `json:"min,omitempty"` - // Default usage constraints on this kind by resource name - Default ResourceList `json:"default,omitempty"` -} - -// LimitRangeSpec defines a min/max usage limit for resources that match on kind -type LimitRangeSpec struct { - // Limits is the list of LimitRangeItem objects that are enforced - Limits []LimitRangeItem `json:"limits"` -} - -// LimitRange sets resource usage limits for each kind of resource in a Namespace -type LimitRange struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` - - // Spec defines the limits enforced - Spec LimitRangeSpec `json:"spec,omitempty"` -} - -// LimitRangeList is a list of LimitRange items. -type LimitRangeList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` - - // Items is a list of LimitRange objects - Items []LimitRange `json:"items"` -} -``` - -## AdmissionControl plugin: LimitRanger - -The **LimitRanger** plug-in introspects all incoming admission requests. - -It makes decisions by evaluating the incoming object against all defined **LimitRange** objects in the request context namespace. - -The following min/max limits are imposed: - -**Type: Container** - -| ResourceName | Description | -| ------------ | ----------- | -| cpu | Min/Max amount of cpu per container | -| memory | Min/Max amount of memory per container | - -**Type: Pod** - -| ResourceName | Description | -| ------------ | ----------- | -| cpu | Min/Max amount of cpu per pod | -| memory | Min/Max amount of memory per pod | - -If a resource specifies a default value, it may get applied on the incoming resource. For example, if a default -value is provided for container cpu, it is set on the incoming container if and only if the incoming container -does not specify a resource requirements limit field. - -If a resource specifies a min value, it may get applied on the incoming resource. For example, if a min -value is provided for container cpu, it is set on the incoming container if and only if the incoming container does -not specify a resource requirements requests field. - -If the incoming object would cause a violation of the enumerated constraints, the request is denied with a set of -messages explaining what constraints were the source of the denial. - -If a constraint is not enumerated by a **LimitRange** it is not tracked. - -## kube-apiserver - -The server is updated to be aware of **LimitRange** objects. - -The constraints are only enforced if the kube-apiserver is started as follows: - -```console -$ kube-apiserver -admission_control=LimitRanger -``` - -## kubectl - -kubectl is modified to support the **LimitRange** resource. - -`kubectl describe` provides a human-readable output of limits. - -For example, - -```console -$ kubectl namespace myspace -$ kubectl create -f docs/user-guide/limitrange/limits.yaml -$ kubectl get limits -NAME -limits -$ kubectl describe limits limits -Name: limits -Type Resource Min Max Default ----- -------- --- --- --- -Pod memory 1Mi 1Gi - -Pod cpu 250m 2 - -Container memory 1Mi 1Gi 1Mi -Container cpu 250m 250m 250m -``` - -## Future Enhancements: Define limits for a particular pod or container. - -In the current proposal, the **LimitRangeItem** matches purely on **LimitRangeItem.Type** - -It is expected we will want to define limits for particular pods or containers by name/uid and label/field selector. - -To make a **LimitRangeItem** more restrictive, we will intend to add these additional restrictions at a future point in time. - -## Example - -See the [example of Limit Range](../user-guide/limitrange/) for more information. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/admission_control_limit_range.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control_resource_quota.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control_resource_quota.md deleted file mode 100644 index 136603d2c368..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/admission_control_resource_quota.md +++ /dev/null @@ -1,194 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/admission_control_resource_quota.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Admission control plugin: ResourceQuota - -## Background - -This document proposes a system for enforcing hard resource usage limits per namespace as part of admission control. - -## Model Changes - -A new resource, **ResourceQuota**, is introduced to enumerate hard resource limits in a Kubernetes namespace. - -A new resource, **ResourceQuotaUsage**, is introduced to support atomic updates of a **ResourceQuota** status. - -```go -// The following identify resource constants for Kubernetes object types -const ( - // Pods, number - ResourcePods ResourceName = "pods" - // Services, number - ResourceServices ResourceName = "services" - // ReplicationControllers, number - ResourceReplicationControllers ResourceName = "replicationcontrollers" - // ResourceQuotas, number - ResourceQuotas ResourceName = "resourcequotas" -) - -// ResourceQuotaSpec defines the desired hard limits to enforce for Quota -type ResourceQuotaSpec struct { - // Hard is the set of desired hard limits for each named resource - Hard ResourceList `json:"hard,omitempty"` -} - -// ResourceQuotaStatus defines the enforced hard limits and observed use -type ResourceQuotaStatus struct { - // Hard is the set of enforced hard limits for each named resource - Hard ResourceList `json:"hard,omitempty"` - // Used is the current observed total usage of the resource in the namespace - Used ResourceList `json:"used,omitempty"` -} - -// ResourceQuota sets aggregate quota restrictions enforced per namespace -type ResourceQuota struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` - - // Spec defines the desired quota - Spec ResourceQuotaSpec `json:"spec,omitempty"` - - // Status defines the actual enforced quota and its current usage - Status ResourceQuotaStatus `json:"status,omitempty"` -} - -// ResourceQuotaUsage captures system observed quota status per namespace -// It is used to enforce atomic updates of a backing ResourceQuota.Status field in storage -type ResourceQuotaUsage struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` - - // Status defines the actual enforced quota and its current usage - Status ResourceQuotaStatus `json:"status,omitempty"` -} - -// ResourceQuotaList is a list of ResourceQuota items -type ResourceQuotaList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` - - // Items is a list of ResourceQuota objects - Items []ResourceQuota `json:"items"` -} -``` - -## AdmissionControl plugin: ResourceQuota - -The **ResourceQuota** plug-in introspects all incoming admission requests. - -It makes decisions by evaluating the incoming object against all defined **ResourceQuota.Status.Hard** resource limits in the request -namespace. If acceptance of the resource would cause the total usage of a named resource to exceed its hard limit, the request is denied. - -The following resource limits are imposed as part of core Kubernetes at the namespace level: - -| ResourceName | Description | -| ------------ | ----------- | -| cpu | Total cpu usage | -| memory | Total memory usage | -| pods | Total number of pods | -| services | Total number of services | -| replicationcontrollers | Total number of replication controllers | -| resourcequotas | Total number of resource quotas | - -Any resource that is not part of core Kubernetes must follow the resource naming convention prescribed by Kubernetes. - -This means the resource must have a fully-qualified name (i.e. mycompany.org/shinynewresource) - -If the incoming request does not cause the total usage to exceed any of the enumerated hard resource limits, the plug-in will post a -**ResourceQuotaUsage** document to the server to atomically update the observed usage based on the previously read -**ResourceQuota.ResourceVersion**. This keeps incremental usage atomically consistent, but does introduce a bottleneck (intentionally) -into the system. - -To optimize system performance, it is encouraged that all resource quotas are tracked on the same **ResourceQuota** document. As a result, -its encouraged to actually impose a cap on the total number of individual quotas that are tracked in the **Namespace** to 1 by explicitly -capping it in **ResourceQuota** document. - -## kube-apiserver - -The server is updated to be aware of **ResourceQuota** objects. - -The quota is only enforced if the kube-apiserver is started as follows: - -```console -$ kube-apiserver -admission_control=ResourceQuota -``` - -## kube-controller-manager - -A new controller is defined that runs a synch loop to calculate quota usage across the namespace. - -**ResourceQuota** usage is only calculated if a namespace has a **ResourceQuota** object. - -If the observed usage is different than the recorded usage, the controller sends a **ResourceQuotaUsage** resource -to the server to atomically update. - -The synchronization loop frequency will control how quickly DELETE actions are recorded in the system and usage is ticked down. - -To optimize the synchronization loop, this controller will WATCH on Pod resources to track DELETE events, and in response, recalculate -usage. This is because a Pod deletion will have the most impact on observed cpu and memory usage in the system, and we anticipate -this being the resource most closely running at the prescribed quota limits. - -## kubectl - -kubectl is modified to support the **ResourceQuota** resource. - -`kubectl describe` provides a human-readable output of quota. - -For example, - -```console -$ kubectl namespace myspace -$ kubectl create -f docs/user-guide/resourcequota/quota.yaml -$ kubectl get quota -NAME -quota -$ kubectl describe quota quota -Name: quota -Resource Used Hard --------- ---- ---- -cpu 0m 20 -memory 0 1Gi -pods 5 10 -replicationcontrollers 5 20 -resourcequotas 1 1 -services 3 5 -``` - -## More information - -See [resource quota document](../admin/resource-quota.md) and the [example of Resource Quota](../user-guide/resourcequota/) for more information. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/admission_control_resource_quota.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/architecture.dia b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/architecture.dia deleted file mode 100644 index 26e0eed22e6ffdc7781055de4dfcc1e8d2b968d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6522 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 g - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/architecture.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes architecture - -A running Kubernetes cluster contains node agents (kubelet) and master components (APIs, scheduler, etc), on top of a distributed storage solution. This diagram shows our desired eventual state, though we're still working on a few things, like making kubelet itself (all our components, really) run within containers, and making the scheduler 100% pluggable. - -![Architecture Diagram](architecture.png?raw=true "Architecture overview") - -## The Kubernetes Node - -When looking at the architecture of the system, we'll break it down to services that run on the worker node and services that compose the cluster-level control plane. - -The Kubernetes node has the services necessary to run application containers and be managed from the master systems. - -Each node runs Docker, of course. Docker takes care of the details of downloading images and running containers. - -### Kubelet - -The **Kubelet** manages [pods](../user-guide/pods.md) and their containers, their images, their volumes, etc. - -### Kube-Proxy - -Each node also runs a simple network proxy and load balancer (see the [services FAQ](https://k8s.io/kubernetes/wiki/Services-FAQ) for more details). This reflects `services` (see [the services doc](../user-guide/services.md) for more details) as defined in the Kubernetes API on each node and can do simple TCP and UDP stream forwarding (round robin) across a set of backends. - -Service endpoints are currently found via [DNS](../admin/dns.md) or through environment variables (both [Docker-links-compatible](https://docs.docker.com/userguide/dockerlinks/) and Kubernetes {FOO}_SERVICE_HOST and {FOO}_SERVICE_PORT variables are supported). These variables resolve to ports managed by the service proxy. - -## The Kubernetes Control Plane - -The Kubernetes control plane is split into a set of components. Currently they all run on a single _master_ node, but that is expected to change soon in order to support high-availability clusters. These components work together to provide a unified view of the cluster. - -### etcd - -All persistent master state is stored in an instance of `etcd`. This provides a great way to store configuration data reliably. With `watch` support, coordinating components can be notified very quickly of changes. - -### Kubernetes API Server - -The apiserver serves up the [Kubernetes API](../api.md). It is intended to be a CRUD-y server, with most/all business logic implemented in separate components or in plug-ins. It mainly processes REST operations, validates them, and updates the corresponding objects in `etcd` (and eventually other stores). - -### Scheduler - -The scheduler binds unscheduled pods to nodes via the `/binding` API. The scheduler is pluggable, and we expect to support multiple cluster schedulers and even user-provided schedulers in the future. - -### Kubernetes Controller Manager Server - -All other cluster-level functions are currently performed by the Controller Manager. For instance, `Endpoints` objects are created and updated by the endpoints controller, and nodes are discovered, managed, and monitored by the node controller. These could eventually be split into separate components to make them independently pluggable. - -The [`replicationcontroller`](../user-guide/replication-controller.md) is a mechanism that is layered on top of the simple [`pod`](../user-guide/pods.md) API. We eventually plan to port it to a generic plug-in mechanism, once one is implemented. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/architecture.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/architecture.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/architecture.png deleted file mode 100644 index fa39039aaff07ee732a917394740cb79a4a60a64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 222407 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¬^&ndFqLoL?s9fg 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 - - - - - - - - - - - - Node - - - - - - kubelet - - - - - - - - - - - container - - - - - - - container - - - - - - - cAdvisor - - - - - - - Pod - - - - - - - - - - - container - - - - - - - container - - - - - - - container - - - - - - - Pod - - - - - - - - - - - - container - - - - - - - container - - - - - - - container - - - - - - - Pod - - - - - - - Proxy - - - - - - - kubectl (user commands) - - - - - - - - - - - - - - - Firewall - - - - - - - Internet - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - replication controller - - - - - - - Scheduler - - - - - - - Scheduler - - - - Master components - Colocated, or spread across machines, - as dictated by cluster size. - - - - - - - - - - - - REST - (pods, services, - rep. controllers) - - - - - - - authorization - authentication - - - - - - - scheduling - actuator - - - - APIs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - docker - - - - - - - - .. - - - ... - - - - - - - - - - - - - - - - - - - - - - - - Node - - - - - - kubelet - - - - - - - - - - - container - - - - - - - container - - - - - - - cAdvisor - - - - - - - Pod - - - - - - - - - - - container - - - - - - - container - - - - - - - container - - - - - - - Pod - - - - - - - - - - - - container - - - - - - - container - - - - - - - container - - - - - - - Pod - - - - - - - Proxy - - - - - - - - - - - - - - - - - - - docker - - - - - - - - .. - - - ... - - - - - - - - - - - - - - - - - - - - - - - - - - Distributed - Watchable - Storage - - (implemented via etcd) - - - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering.md deleted file mode 100644 index 757c1f0b1109..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering.md +++ /dev/null @@ -1,99 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/clustering.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Clustering in Kubernetes - - -## Overview - -The term "clustering" refers to the process of having all members of the Kubernetes cluster find and trust each other. There are multiple different ways to achieve clustering with different security and usability profiles. This document attempts to lay out the user experiences for clustering that Kubernetes aims to address. - -Once a cluster is established, the following is true: - -1. **Master -> Node** The master needs to know which nodes can take work and what their current status is wrt capacity. - 1. **Location** The master knows the name and location of all of the nodes in the cluster. - * For the purposes of this doc, location and name should be enough information so that the master can open a TCP connection to the Node. Most probably we will make this either an IP address or a DNS name. It is going to be important to be consistent here (master must be able to reach kubelet on that DNS name) so that we can verify certificates appropriately. - 2. **Target AuthN** A way to securely talk to the kubelet on that node. Currently we call out to the kubelet over HTTP. This should be over HTTPS and the master should know what CA to trust for that node. - 3. **Caller AuthN/Z** This would be the master verifying itself (and permissions) when calling the node. Currently, this is only used to collect statistics as authorization isn't critical. This may change in the future though. -2. **Node -> Master** The nodes currently talk to the master to know which pods have been assigned to them and to publish events. - 1. **Location** The nodes must know where the master is at. - 2. **Target AuthN** Since the master is assigning work to the nodes, it is critical that they verify whom they are talking to. - 3. **Caller AuthN/Z** The nodes publish events and so must be authenticated to the master. Ideally this authentication is specific to each node so that authorization can be narrowly scoped. The details of the work to run (including things like environment variables) might be considered sensitive and should be locked down also. - -**Note:** While the description here refers to a singular Master, in the future we should enable multiple Masters operating in an HA mode. While the "Master" is currently the combination of the API Server, Scheduler and Controller Manager, we will restrict ourselves to thinking about the main API and policy engine -- the API Server. - -## Current Implementation - -A central authority (generally the master) is responsible for determining the set of machines which are members of the cluster. Calls to create and remove worker nodes in the cluster are restricted to this single authority, and any other requests to add or remove worker nodes are rejected. (1.i). - -Communication from the master to nodes is currently over HTTP and is not secured or authenticated in any way. (1.ii, 1.iii). - -The location of the master is communicated out of band to the nodes. For GCE, this is done via Salt. Other cluster instructions/scripts use other methods. (2.i) - -Currently most communication from the node to the master is over HTTP. When it is done over HTTPS there is currently no verification of the cert of the master (2.ii). - -Currently, the node/kubelet is authenticated to the master via a token shared across all nodes. This token is distributed out of band (using Salt for GCE) and is optional. If it is not present then the kubelet is unable to publish events to the master. (2.iii) - -Our current mix of out of band communication doesn't meet all of our needs from a security point of view and is difficult to set up and configure. - -## Proposed Solution - -The proposed solution will provide a range of options for setting up and maintaining a secure Kubernetes cluster. We want to both allow for centrally controlled systems (leveraging pre-existing trust and configuration systems) or more ad-hoc automagic systems that are incredibly easy to set up. - -The building blocks of an easier solution: - -* **Move to TLS** We will move to using TLS for all intra-cluster communication. We will explicitly identify the trust chain (the set of trusted CAs) as opposed to trusting the system CAs. We will also use client certificates for all AuthN. -* [optional] **API driven CA** Optionally, we will run a CA in the master that will mint certificates for the nodes/kubelets. There will be pluggable policies that will automatically approve certificate requests here as appropriate. - * **CA approval policy** This is a pluggable policy object that can automatically approve CA signing requests. Stock policies will include `always-reject`, `queue` and `insecure-always-approve`. With `queue` there would be an API for evaluating and accepting/rejecting requests. Cloud providers could implement a policy here that verifies other out of band information and automatically approves/rejects based on other external factors. -* **Scoped Kubelet Accounts** These accounts are per-node and (optionally) give a node permission to register itself. - * To start with, we'd have the kubelets generate a cert/account in the form of `kubelet:`. To start we would then hard code policy such that we give that particular account appropriate permissions. Over time, we can make the policy engine more generic. -* [optional] **Bootstrap API endpoint** This is a helper service hosted outside of the Kubernetes cluster that helps with initial discovery of the master. - -### Static Clustering - -In this sequence diagram there is out of band admin entity that is creating all certificates and distributing them. It is also making sure that the kubelets know where to find the master. This provides for a lot of control but is more difficult to set up as lots of information must be communicated outside of Kubernetes. - -![Static Sequence Diagram](clustering/static.png) - -### Dynamic Clustering - -This diagram dynamic clustering using the bootstrap API endpoint. That API endpoint is used to both find the location of the master and communicate the root CA for the master. - -This flow has the admin manually approving the kubelet signing requests. This is the `queue` policy defined above.This manual intervention could be replaced by code that can verify the signing requests via other means. - -![Dynamic Sequence Diagram](clustering/dynamic.png) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/clustering.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/.gitignore b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/.gitignore deleted file mode 100644 index 67bcd6cb58a6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/.gitignore +++ /dev/null @@ -1 +0,0 @@ -DroidSansMono.ttf diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/Dockerfile b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/Dockerfile deleted file mode 100644 index 3353419d8434..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM debian:jessie - -RUN apt-get update -RUN apt-get -qy install python-seqdiag make curl - -WORKDIR /diagrams - -RUN curl -sLo DroidSansMono.ttf https://googlefontdirectory.googlecode.com/hg/apache/droidsansmono/DroidSansMono.ttf - -ADD . /diagrams - -CMD bash -c 'make >/dev/stderr && tar cf - *.png' \ No newline at end of file diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/Makefile b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/Makefile deleted file mode 100644 index f6aa53ed442e..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -FONT := DroidSansMono.ttf - -PNGS := $(patsubst %.seqdiag,%.png,$(wildcard *.seqdiag)) - -.PHONY: all -all: $(PNGS) - -.PHONY: watch -watch: - fswatch *.seqdiag | xargs -n 1 sh -c "make || true" - -$(FONT): - curl -sLo $@ https://googlefontdirectory.googlecode.com/hg/apache/droidsansmono/$(FONT) - -%.png: %.seqdiag $(FONT) - seqdiag --no-transparency -a -f '$(FONT)' $< - -# Build the stuff via a docker image -.PHONY: docker -docker: - docker build -t clustering-seqdiag . - docker run --rm clustering-seqdiag | tar xvf - - -docker-clean: - docker rmi clustering-seqdiag || true - docker images -q --filter "dangling=true" | xargs docker rmi - -fix-clock-skew: - boot2docker ssh sudo date -u -D "%Y%m%d%H%M.%S" --set "$(shell date -u +%Y%m%d%H%M.%S)" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/README.md deleted file mode 100644 index d02b7d50e2a0..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/README.md +++ /dev/null @@ -1,64 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/clustering/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -This directory contains diagrams for the clustering design doc. - -This depends on the `seqdiag` [utility](http://blockdiag.com/en/seqdiag/index.html). Assuming you have a non-borked python install, this should be installable with - -```sh -pip install seqdiag -``` - -Just call `make` to regenerate the diagrams. - -## Building with Docker - -If you are on a Mac or your pip install is messed up, you can easily build with docker. - -```sh -make docker -``` - -The first run will be slow but things should be fast after that. - -To clean up the docker containers that are created (and other cruft that is left around) you can run `make docker-clean`. - -If you are using boot2docker and get warnings about clock skew (or if things aren't building for some reason) then you can fix that up with `make fix-clock-skew`. - -## Automatically rebuild on file changes - -If you have the fswatch utility installed, you can have it monitor the file system and automatically rebuild when files have changed. Just do a `make watch`. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/clustering/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/dynamic.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/dynamic.png deleted file mode 100644 index 92b40fee36281ad3bdb474a52c12d2150eb40b53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72373 zcmeFZcR1GZ+deK)q7afzQYbSsdl!YsmXR$xBbiYWZpny{y>BZra+@W$viDtNC7UFB zf3LUttmk;1?{WN&-*No@`91ePm2U6x8rOAR=XqYQkXvfkP7%`)lO?8#!)OJ*UkrQX zK(J>j7ie~xkF}2wO{Ddem^G1}>cX=?Rvw38DK32KCr=8Sf|?2k2gr0n4boZh0}7(Q z{#@Ug*uBqO8BHEl6Y0%flkETN`crX%2N&5ztUDy9eF=?lwD1sknWWuwjL2Ue4anjj zhd*DKy=Z`^!po##b4Gs7dF%uO{2>$i|F{3f-d!X8rAeh2#g@PEy)6rkZjAh(@no}v z`ulND7QaW=(9IF4^O*h}WRUO*Uwo)yH|L@Y=P|6X|M=`QQ^fK38QY6Qa$MAgC1y?U zTqbIai~Fm4sh=^Eob!8h9IjFJc=K+aVL-3D5&4t3xj9q5FL}4wgBv5$dD+}g1g3Jd zj5h}7qtRCc1ZLUI*3`Tc;R4cm~>1qpIzI^%o`Nlcl ztCUw6NVT-;WiYPwT7yyWkxJ?J#t|=`3!o$j zkYldL%ZXmDXr6FU)R^JB6l&J8M@23jE3=D7_L1xtIl=pJ=RO?H#Cx%vG*~`%vN4!! z)E#FemBJeoHM{m$1+ zbak8W1qHnHo3M77iJVC{qvHI0lHf+FpM5vs-Bf&@UA?fJVN197fpRX_rvH2{dN8U* zmPEu(!0Vh^PVX+auR{%on5`m;`ytFcGI>OSFJ8VpLqw3v{9H(Ds$irzRwbU%fnpE; z%fZ=l#$NYY3`UHc$WwwzIcjFc_BGX;s@oLO=^S+JA`U~x=TaQ@)zwHuCL&kmqUy4k zGHyqe#s66qq8eoBT&)S&d%qgVqS*RzxcX%*J!dyr+~5g@_tP}_UF^fKR!AAe_^{s` zD;vjOuyJ0H+NT?2kVd0bqE<(|mtMYnshFXmt$j40;e3RI+|r|LTR~>)m|~c0sv!Q0 zq3QgqY(yWbm+HKm&ggFL`I-CM2(0+hJ6ZV{XAYAqmV6e!6v|2@*OM%`CFim5rNnn< zeQRa9x3Om)U0nR2>W+X_+ozV6&?d9DR_*B#Iicwi>tD>v@N5(P2dq7J@z`PFGTcVT zofTLk0|W7MdgJBxoEOK<);;|Eha`<~cK7bV3z(JA_&!svn$Sp`2rf+*8SykclHSj|AzF73c@y&C7V=<|I?~JNF_Eu63zSVj^sB|1g&06I@D7>0y6mX+zw152? zZf$#e+eR=UHa44sm{I2T?`bx!+qxV8d^Nd|^qlS@DQc_Z_-`;lp?j)~q@q>|? zhdgm%{IS>BtU6xPhASOENyF#)%M|G6Y?0UB z4gVx0p%zW*a2DMiv@5o>vidnvD^5i$`K#e*xb*EgjGE#8-jYAFgy%2j{a?XXU8nf4 z1hOpdlVMUn>RlnF1OR=qxn|lI-M-( z?IUHvMo~2xYsjYj+pD(QrmUvsHNVGF?M8ygil+psWO1nS?3pvZzdy5Mzx3_z?aaDb zutsw5@H}sxNXQPS7jgVrYMIVar2lqmJeXNH#p=T9Y1h5&wW_MB2+8#?KZmPrvpZ`P z?y*LuzSSz_(mnj#o*+7?4u;_Rj9D}Yhsa;PB0(5GjAqU?XBBeAF3SjY8`j}=GrM~;=kw4M`M8+_L?tjjpa5+g`{ux+~DO$ zUZ1Dt*9W`eT45?;OH0dcc4>ofNs5pf`1J?F?zmLh$1}_BMjKwWU%!6ET7@VC?%TD! z;&+|y5L(YPsfT5?)+@N!l_oFgwfd}iB8ts@w#TwJTQxu?wW30poqamsI8*BUI*l~r zcHZLGw>jP$KLc4lnw9+i{X6AgcY1bq7H(R~bt8%@qS?CRHD_z73no@fQSCFm=hJ2~ zXSv;mJhS9SY0=M1UO;(B!KCF)vvo;Au$P@mq)Ojx@CG1%fpXCnmB{z8F z?;k_f*4Esr9}1*%gbpq0P+g!1xwRE=@4o!glMnaSa7H|5lZeO(WHn-J1XUR2l(`w* z_O*J;V8VHgYeYpvDr;(X3oA#=PW6(Z(Z*i0S(kN-GIcE^K5>2?`Lkf9DQfTf%8Hc@ z3S({s95tS*qojYj8KK%+ma_YUol)Gw0(FW>Vl&zMXQX9(hg=Vpm!hH~uE=PXL~MsP zqWOH}vyxmxRaI3*MZ!}h#DQITw{xNnKTMKdGnoC=UiDr|+Qjb0p0cFI@h-t|x+NtP z&2q8--eqy|ME>i3`0JHEQ=n#~a!Ov;#W z)%D_{g@#7=lK+9Xxw!@vBk46OtBdAsvu+oYLMI;{?fkKMMC}>#CO-ty>uhq<45;%t z!kQNq`9ocnvKBH*6_~Fr1PH&0Mi^aXAgMB9l2iQ(2zUyCK>KZ>>|7tD0 zx7u63-CxX8^&?7;ODWt2RnnbtErM16JF&blT>StxN_>1g8l9b!voVk3g^z&1N=Ag# z{p#VBsdjPCU#X)@ORy`Ajgt}Vum$<&t_sr&`_#NzR zxOJTfZWQ_E+?W+-jDh5F`n-~bl~qstElftXZ6Hg{@0QDF?>HZEuezGl(Vi%xtF6r$ z`g{1nX!r43l|$S_auQ7bV*$rUd{$Jk5Mw+y$AcM3gNL8n;C0DyZ|(H|Zl^KFUQu3` z82=(y_ES@op{Tfc!&8DZ__36I@1@5&OT+%M_&8Sf?UHh~?4dUWZ?|R_sQFD(ANTzl zZ`||qmtcys+^XC8S-mxtct(*HVrcK|w>n>MKAJlf_Oz;Lb?bw6f~^W8+Rx-_G({g3Z3C~}9 zo_UujrE>#I@3b&le=uO^RG6PHkT8N`r<3v#HAf97UoCVJ*|k}aus$xGOubKBxhoQuynG%2yMR%M!3urqy$%S6hpGOwKY1KXZ<4|H_7a3hO? zx6?;FX@Eh(ldtg12Rc6`o;bVl4?%7ug-Lebg0PIAU`s;8tL(uk`|GzSo}s2rc<`7% z_T@`U38@gJ3?U(*`u(-yCCog}1U57Gm!|~f#hZNVulcPOJbEU)C6Zx-Wr`f(w>m!c zxIuY-Ls>*qF*bqD*7E&Dk;Z^5$+QV|eSKQ-_oKYqfd*VQZz1{hRAL{qDPEUgI%s6x zzhz`JoTHusiGV)%U1mGV%b1Hg!Q%1K)S6UbRz%T7=Qq%LF~c`T6<9uwr4YV_XIb^a1ji zp_(RKChDf1l3|)`u3wSH<@t)FD))7(qsko=H8Nj5v0)wF%%e@b;F~MN%z_f{(I}5^ zkBaRPlCI;IK6CPzZGVIn^?vFNQTovy8Iv9%;}H9vK@nm&<4CI$QII+jb$?P+8TcDSNi*oOzp5&j>| z_~Tj?6(d7KiDCIgr|h!PgXn)7P5`t+?v*Apq>n-Ns`lX~-j* zY0Y=m7ri0lbzYrj$auZ}ky8B*q%#COdap0&8yKKPxZWpx+&$jEX=h+y;00j)$JCUu z-`3<(%?hbG7exr*$y7-5SFc_LNS>N&@W%AL5bloa#_)rUg|Dt#zb6aQN~k(y1izZ5 zG@g2GuzD>kJNx47ro822h)Ijz!+1MBf2O@+aa~n49F2B&cW-KHf`qU%Qo95Aj3R`f z>FMZFPTy%tNCwu!JHQ#j!Mrkjs*Gmpvu?_g7L@ ze*fmFUG0HAs>$iNI9LwP2e|9u!-sHft5ZR{3aoegM(CWBO4vfpyu2`{NDPjN`P!=u zFI=5M5q~=|i}~p$Ha|aqu)k3+z46Vp+h%nQXX3xweNDH}08q#pq#2bcH-JnU$B^O(ku*QhDolfA6kz<_MT|+qivsb9ZCZ{{Y~ami8h9VzhRCXjm9L&*e*( zjD6Sop%l8^YwUfGOH!cRfuid3b7dQUHzR3yl9f(rCkFp}c6LyB^<>=;cbiF_-+sk! z&gAp!y>*JO2OuAagTZ9X08+I~quKH@GcC4PXE8<6%O5FG{0w>>458_6KfgT$Fj8E< zzl{y2H{#KSeD1Q(4jAcq5l3kA#8-?vPy$GHU0)ocHRr9{G<*24icJ|H?`y#IQ|*b6 zEVph=+^-raGTOUr%OsXW>eK$({Un zh8`a$)6vo*3j7rZ%Wy8g_-9`prMZ2>qa$T~Xx#iFycGx499#va&86i4Hqg`?2(A!$ z;1+ImjWiFgd)=E$RZ-cp2IvZ_IAwn|hfLy^jEBei@lwcb3Dmz&!qxVW=aPZlJ{6w#bKZsDj|>3|=6JC|MIOke%p zqLZ$PZ#hRO%zXuO2>Z8bI0Bmxc&4!uf8BS*)d zFr#6ip}Fo!JWZ!h9`luAR?K+#@yPL5kDD4X1qB5owcfWgDqP4@-;39ej(YZVwB>3@ z?r%;&HR1N%IEqcRcjmEdbfU&{j!?5W9wT75B;QtQ1rXoqo!PY&r1RaHj3Z-`xGtjh zif{ZgdkO4Xs zDSP8&{xrh&dZG*?u)7z&zI8V`m`ZdCd_VTRDXbpwoAkj}C&Y%meq9qu(}qV-7GuSo zm;{d+hBQyW$ZbQhLSv380)WxXZQYSGnaZ&Y8 z3@o+p4fikR=H+cQ@%k+TXe6WIGo5UC2~g_tg&7ES3E8koG`@J&jsS#HPZUB867-%t2hc6(?e%w+d_D{uYHK@_RWxU=W#On2I?naFEQCDY{c zDl+&uK{0;})Y;#@eFJJLuJuCbcgPkiu**9Vg!17(;!OM==BOpHDW|u%vXH-E`@9*q zZ_Hy-x4T$5s>Vj4F0uRsH($F{x6{+xJDb6$8gL`fks2rkC5Jf$JIKID@KT{*_D#fr30Y0AUZzk6s%A@o(Cw|ZlC~=apOCN zOXBaxa@dr$e!@;zt^B&^A+q&Ki8g|oBh3l0jSD7{G<%g-@^q4Lc#|0fQYKhW9ZBME z-@diwT5f(g`|EuA;}DnKS*VhIefJ7PB6C*hzs-&{V2U&H_p3+UGtRK_Aee7+RTf$^(FTznNmCwC7i(voU-kDq7c{a&P19uK)9<1yDJd? zM~!`!o07!b=lb$)TUl8Fc$=*D*q_`jnaEMb&YgscauPB;^NPR2Fs2-X@dB(+US1A6 zE#1Nn*bb-KHJ#??jDUW~i3no3^fdvu=;~HN+MQ^Q0KVo76%`*AfQ8Z6T_mR*bAs}2 zHY*P3K*)pgVJC6Gc5ct*zc+P;6j-K3U~a$sy@}*3PeD-;>9NNUlbL;2PlrEEdYVG_ zeVPj9dTVoH&5QGPaY2Dw^{}n2t=lUz)CF$Ez8@L-o~E|vK6Y~6-H-2Cz*kg+`mJ&N zy1KduYs>UXP~%zNegMF)=r6Z2@4 zybDB1B-8-w${_7mW8Im&>JD^>;#ng>*QvIYy#;GVF}GB*%5~IbpD{a1jQgQe=9(W0BdB4sv36OcCfYbJ)U+qeDoGa zOk`vl2eD)Z3(x0^ghR(FhWI3Sa&7A>`x4vj4%(C}aZ3`#(MbVCke8 z!noVHxbV9do?@1gh`i1q>E+g!s}Y*sHvmYWI(BMb*lENEO04rI zP@H0aE$5)t^ZS(6G0K~l6DczktoP%D=!{P9d*`iMN!{1LS~+Ik7-V)eh%Ylx7>a%U zs26)EB5W*;rWC!KT=uNnp1Ukd?zfUS%4JaYj6XIq5-R9qpWmMoo$BJLzoGNZbk-d6YDru3!C4%mel4>jX2Bo@F1YQKDsI4~7`55{5?YF|@6QOlN?Q}n{$ z+s8=9)Y48%n79&ebvoig#0jQU{nxD=Kb{_#qEb}8abu{& z{CE;7HJW7E^V_1wkfCwuBXQs@6BDPK!dp4ZBPP@Sg09eEw7 zD{e!t!y&vAGL%BSeLfTN;?K2oFR5t2&t4c!T`s1lIkdaL@Ncm(_}&hQ)x zLAYETkR}!uK%Yl>g`SW61i{00^8kvK&XyK4RP8@_B(?;(y-xrAw@|8m|Nh;S@7>+T zr}@Qo7~Nvy2&ruj$xlG5%6ZFm*1@AdV88doT6FXX-V0V_c#mQp!;HDv`Rv_x6|HTsnvOuaa6Fk`kjnMj-24 zb*BO&@iqR@hy&rVb2Y^;c`f6*tmB)m6eP|JHqQz{_ZvMN1YF4hv0 zO@5>NX>umX%S_^XFNzBbvu>0NyDpzdl;73EUpA+F#%%Yw)Mw!fKb>3@o3eJl)~-t? z!?puN{F@2vH?HO-HC$yNRgNmE+rEeKcu_RJ>V&4cZmUbbk(fhZzTZ80UjygU;`>}- zSC44f{OZSua@1zpxn(`BSoj$5o^$VBD(IcHm(Yxr(-aEG7&WdRJ=mx}s4Xfgs;H<) zPyY@pPI~v3Jh03F*nNF{C73{m(@C*j7f)7+(lRvk-uyL=Q1l@RANK1jr&?*m8AuKK zSubA>D;fqKrR@w+Vm-sh&e`D25|5N<7C$bF=P5wQTxa`@Fvm~VCf|SA;G* zsF4$_91#={=$%-8cZX+NF#b}G0J*e|?CuwW@6B>kn^4$CUe7Eo?OF7AFx%6#=wVp< zz&ahf=j`#ESss1SS%I8DKlY4bn#nOhCCi?`{uk;eTxXl9U${CU&q(HWGE^yp(}h*u zX3Sai4o@6zUiHR}m7P5ZlF!rf+*ywU*`a_&pX1mxrxieNPX zuTDnNIY79?J8^(Gr{5x z2@An*T}P~7+&VS|fqtts=57Binxs}gs?O~1Ak`;-qONiL&5D}vMIwAgH&ngh>bWno zZek42`?d*Cn^*V9rG*1PH($JDq|8f2j1c~SK>;9*`t2-Is!Ig;z3ZKTm+@*OJhsT7 z#+lO4%}yis=n9sBG`M+!|9Nsnq5mA_r$;qX+CXTS0gUesO2h;S!`Im5ieCP{iDl1P zW3fjU%hSFv9Bz$P7`I1PG>mW{m3B_g_hf~QE=4G?MzKAtHC}DhZ_+dA+TV-eeBD4h z{bm+VrM`bP(R3w)-TWrb9mb9{SdvK{l6bAL6G)n0{h8%w`R=WrCduO?#DWShx2s12 zBb8AV{ymuPg0EBxn=(Y45QXo+1p;WLGN1C+uWUVN`cjf9dDC{)0D?P}V#)MSGFuR( zsFj!D>_%*MblI_jyJ_cdY?RnS9acMnLY;&g69?tm_0J{UvG4rv$B{fX;+z1X*@5 zwUMA9UuUC;XtvbP-geY1-kY6v6N_ND`WqMuC}ZJy);L94+vtpXMmA4Qc~rynC@Cp% zP_=Y)kOs-Y-~&|kc|LMcb5j?0(`M!xe|^=uG%7SbH|KYjy_(kz^dI{LtO|QMDn+Qy zkKZk@NE1$-Ox4!T;s(Yt-km>t9@9E`Uo6S7a%l4Y=hD}q8kr&mM{^R7skKM*mkEa_ z;m+E#pJ1?C9kN^LP!V%v5_L{3D|7qs^-v!%5a@PY4i(gPh`-5eV_Yd`vMVg~MZ2dS`2%2C6ZQ6dV_%OUB{ zvgp#<5A{TIdAL8Is<2FmjVnax$;Fp~O?Qlp7VlR9I^|MvDHzVG;8#oTsZ=7pR{W`^ zF0~}Ua%V8c<4RCMx|@;u8YkZy^20o5A66;VuoN4JOc$jZpUk3lY`d2?>*i;9}6KmXs^hlmnH0=6T~;a8NeCZTt8 zlS-M5Q0ov6Y0Ww6^$AbBe#u984DN*7@I?>c1aO$$NDH*1gjMl`3IFdM#{%HGd_ngv z+zdE^ID%w$Wrj?N`!9m9duUiA#NCJQ2mIUjIkggH@U1Vbk{>#VV01DC4{dB+nz>_x z1TeR0!FY&!3-R!z2HIV{nPza}pRe5|{7SC;gw`00f2#Yf_vH)}qIRkO`aW`Jc*zrz z1b>GKkMq=_H?EB8(mUY*f)16Lb9i7MIDGirF$2=uxjG-HXyB=lhbcRieaiv=j3`{( zhEdCzJD8w@?%%$T+_`2+r__P$2;=B%WsDHRsGl!Y*!&H+lW^zJxWe}BI()ZwG`_1U&yR5BEVe~zH{*b86RudQ zOf+jz1^vuL&yBr*d;q$11iweS5N>x?-M`0u57CkYZ8bTlwn4j-xvGC-z2bs;=+p_O zSF8jud^Yqq(*_Af+!9qTJ$)#_RE*2FHQ=IN+46xW#1vUuS`Sg^)vr` z($+Q7*41SX{hlCXcOO2kt{|0o{QUNr2CBJc5LO1?T6Y3Hr0RL z*pC*=mq;DAf=TWJ>|V-$-Cy(^Ux!9V3Jijd*a(E@e@T-w@ueg}i) zb|#=u{r-JlIZD{^8^Q|$JqkmDgpDXRZ7nU(u=YVJBR=-{!i5XHIqEp~y%6?fQ+L- zm5#2Ew^oG8t(n=s#&6FnuGMlkj;j@%EQny#JyQWPDG2j7Q>2VEsAS1Ud^d(YB}UTZ zgZuM!fqgmfs2)b6HMcLc-beHXA&L;NVCiwKg9k6ke}Bt=tJQ>o^qQ(_JJ`-(6yOoR zMJ0iXp%o9-$8~2=nn1q!4z#xS+MIjiDUlfrNIcoL?Gm;?*#n#9;^G3jHeyzTBx?Rl z7UwRu;js1`4^J?hv=728$R{A9%aFa+b|&suY2P3hOg;n78SQ>p>PEP{pNcbVdD*u0 z2YXAyjvFB9?SrB={o}_sAS-y{T1D6LYz_EmR=0en=IG3C_LhO&0j3tbHo(~GQ7OV; z6tKxfpNhGnsb;m1%t8c2jqv6Fq8wQ0QxlA5s*8E8+IZz+Fqq7pnZg3+%=<6UG83F4F(CfYFn+xhH zGv|kC4gE6WOpJ`cYBl4%R9l&v`pB=29gR&pjDmQBM|MXBNf`}cQ~}i^Iu~%?pGzek z{)W<=Js+JA8Tp=0?JXLO=)p#~YLCTBL~^W=um13=({1stKzd#Zy+87BdT%vH8mP(b zeyg@uz(Uzjxndk^n-*1Tu(=c zn!{k(EIPl)pvC%#7Ci^U=hxadLC3;?`i#BWt&m3z!S{`2j-wBL)eX zTkMF%6nJ{KkE3IR^p zn+V(iEJRSg)j8a61+-^9ifRY97aEPNY=5Sdf#NsFW1CgNzQWA|;RNUxXi(sR;Qc^k zk1f%=8N~*4kYEw`C@zsFuU29{vj-`#c7yrZ;QUkm*pw7$m+v0~0|T*!6%u}Ubn?4+ z(go*juGXySh-r`oWZObHRmjx}mX6}%Lh0S{w=>eM?CsfZmVt{YhK4g#E`O75h+bDH ztLHfj5wNmP&sDB!VtHGC5kZRTF{O z7GKuRX`?d{ZGDGRo))7Yt%L-eiPpv~-RqAABY1{I+(pH2jt?Z5c)7X3?}&q40RB8@ zo-=q{!2nzu5*@QB*T~=9DLO%U@%8@Rkyc5NhJoQ5cm7lg;Y~iR>thIIa|AOpaS)BU z@>hDVTmQf@RRY_nmy-#z=NblQtf{sY40UxM>~Br$>gZg-0-Fl6zcDnrAFC;{vgXjf zAxB1BM*IEv;4vHmI%b7~MuP>28OaqjfCUFC;kBqsdL*Ws&uL=e6kdZIf@J*96a?6v zmNVyx%g@aG0W#BT@du6^ROu(kf*W1Zi>@K?1`w4gqikZsjw1rU(vGI%=92&>+T~)B zR^L23G*&{;C1!XOE_mDhDBhc+TFwX_LJ(P0*_;KzA2R6pUySiDcTm{|j(p zbJmd~JMtH3$*9O5HZpJr0UlxrcuV0$bT~{1>ih36E<*?v1D?TgBvJ*uJ@#+kM<5$u z)h>Cw|HZ2R!nO!j{of(~|GYf-e?R1@XJ(E@fS*ELN_iC24D=;)F6yw)rS^5^J=kz& zRj01ahs*jTcne4Wxf3*FScuSQ;y@W!JruucFUm69cud2w`z(H`P`5*2c1HA3bjE8=22y}LHxmSBLoXM-n?vV= z*r=d!=dG2hnwpxUqoc9$2)MyHM=2EfB_)$OyhGFVZr?scoZ=n}H0JhGhxpk71;Cv? z0+I9exTr%EyddR6IRjXhlwPj$%_B(g{9ARhOfp=( z&jvocb2M$9gT4H;2uXzr2q(AMH#@I2uPHYU9A8VT~MY$eOFcvX&fhS zIyk^l9~Slv$jpvYp@q8SUxZrdcXV{rfe3j)xkpfystJGxeR zH8j#}2SH?nv;$%(3lVs2iSGxp+&X6EC+G!!u5L(-hEBEp6U%N3Um{7LH$FY(z1(yb zbkboMF?z>$?>)(%ZU$7y?c$Xk&22bRM%B)srK2;4aYV(HKAofyRP_c+IWTzOpA^$S zG?MVziB62Ui4n^F+Svmepd_7YVGnm7MGi-3>!cY9@Lz#pC69;*(9u~yte0|`vm!YZ z$bw(*Tj{hEI6(;K=1$_fi$Bne22o~cPlSIsVF4{uw08WfJ)@X zNAp_RAIM!G=K!x9`YtA?r`aVFTpnm^Lm5sW+bh_z^56M7u#Du=T~?y|cw|U6TdIas z@xp)rDXiUorN7OU4<@xlxi1cCQ#C2D@&iJg?acuG?;qt_ekCe)o6e#o1t78~z8Qi!G<``X7r zYh})RfwBM;*u&GJbXT%mQvsZH#0!H*FSNAs(6UJ{ov=l1UVa*@=k6{fsR4VirU!N4s$0!Qb z@!*T=E7|ND2^5vTa63Ce?Hc;kQ^0(}gF*V2xjaxiP)<{N_KrVkvtBj`^J{F!QH*_E z&`Pt0_dpjFb+ojk82&Ae$4(~E) zVUy1Z1D{?A*$u!3KBEX835 zc9Lxb6g5!Rw!fbjj0Y}p_h`8KS_0nPEMoEF#Nj%?m!a>otxy zcv53uZ9R88*1Id(etqyRCQCgGAerO5eL~(VUxPzrk;mSbyQ~Qz4M)!P9%nL$O1PP$zlKqy;~ReF2pe zH5C=Ky8V|Pra3<-UJ(akt??4bf523qkGwuw=L_M;5CmAD(V-AhPnOV+$^=2&ey9SB z!(ex!K700BhQ^9j^hH&KBXV$9WIotz2BRpl$WbLwMS;imw8 zwtPyt5EE6bWn8Ne>_l)yNP)i;Xb8wNdpjGQpFV9uMI>ST*J)U&?XD-tY{d z@POL(frOWa_bzzy!0h)8FUK~4O<7sp3wWN)tgM%@u_{qe27sw8G&J-WDFaQo(gD*_}4*QD0^ZUfboEtj-R(RLy$pd0!!NQ@8eU)wNzulW+b7vL!G&7X8j?UDNA7H<>14mYh|NcV`Dl-%^gnmCFuOXff zQ@-nD^u$4CC9jI+AsvGdNJ7oUr-t8BYCnQfvjOWnlxbjv`Ksskn13Bv9@zBm87QYJ zVKjlT;taiyn9AxvJOUEQr#oFS#;(UZF*X*|E2f7(PRF&b!Mb^6;yqC&L{4<80zA(! z$woYJ*|y-2TZia#{1lzVx9<5hD{E^Kq^DHT+8b<68j2dwp>!4d1$Kwm#!pGtshe@F z{aH8SGULd@VVHAEoM7<{=v&jem-Cxr+mgg_?=ry4hLG%%8+TkYDE`!jsf;p&KilMJ z!4T&Q8`Smi!?|Ts8m5n10~>sc#2p@8K{}|@5Bs-JPg%ixsimFe21ujpKq*6G;EgDe z_-g#S;?5EP#*VztRY7?OM&@zy%D7_OH}Br0mKr_hq}Vsd_b6LIRcWB!;2okk-5!urNK%CGAy^KNDWM7 zPF5%RZ$16tCPo?ZgoOxT7`mWf7cd&FIXJYk2sFqE#9Wkjly1yE2k#VEqo*$Ef?fp- zHpsrkVV8;IpdSpRdE9(fxSgFHv^n(7X3nvkX#~bdOB4C@WLzUN!ln3a+j>1oNJxNZ z)z*Ie-c*9A9$Y4)(9F8>xY>-~{MmbsO|WOJuMatiEEz&W>Xvf&Ww&l|r-JZnwO#=- zEYxANt@s)LB=ZmPxy~9nQJ|?*HLlGH%uRCeV8A;5_qLjxWG^(huhk{j`XKB8J9av( z34$f??KWeGa~>MYI@;TlL|wjv_hb}y2{3n!vuBoZRX%>^< zX0)-h2MKaKhVwS;Drlb+x%+|OKm9$3Gon-a;115c#neBf;^HmR?vsR8Z-nsJ@M$O{RBQN-~MAS$j_=qzdL>{RzU@zDnj9SBCa z=;WB5@`MDs75oc7Po&;^0>1P4>q9UiY=ySuwk41moA?PuiH zt>{<@NKlp>eC)FQoGVr_qZSqxFa!~E56jx+$t3&WF&u^}lH3RMk-o_O2Y+lykkddG zf!@;rcrc8kcF#QGl>l0v30$?8OaO$U@7dbULeK}~0qL6*G9)mPiH?}h|oRZwHxqZ(IiVxp~mfhe$Z8rpyn@c~-+W~kVcLey^D z5HOaDUb>oOrRt>_*V;r=4Q;(B<|CH2h>0J@EG#VS@%u5L!VnYaiEo@FAY~265aKR6 zb8_3wUZM|&Uo%^?jkgBOWrJ-#EUM2qTL=#W9K8v z$8(aG2)}#_lpk7oJRrH^-F@3TZwyoNzs z-RIMb3hFKU-r*+ZgOAsBz}~4+fFLSvn0E0;qlThs7vH8|*>F-S^?G*jMc9%kJHC>OySeN90Rd_2?dFU2)AnMvtJW&TwKdL>(%jFhGbFdE3-s!1G9zz#oYjPm_*9^tv*8Eh!Bi-YyLQafGM2 zr%e`6rO)&T`0LGokYHC>b<*v`lF9-aYT~(C+35%$38<1x98Xn7^f#{aW|X-NU+J`m zXYf@3@d98=ClO1d0^OKe?vLi`(!+%BItRdP3zDLV^Ls)F3R=)f)Lrl7_@f!OxHHct z1}W$$LJERx`m4?`FP;hiyt^UBZ8qw{4dC}@sUw=r1((@Rokz3qj!omja#JX2<| zqM&nH*q~M5-15hKj;1U*dKN5PNGax>5 z=f7z3P%Co-;eGio@yWkh{NOQ!Eh0t^nkgd%l2#ty`qaNPd@@9a{15G(B@0ZNU;&7Q z<@leP{2{|}7X&e|Km5_+11jD_&6Rq{2^T*8V^lc$PYwSMPxT+#{dL>xWAGrUS%3G> zzo_M35SQ))`$>`A@Rw3fMK&l5A>v<{N915O=K-02QqhOi-hWWghdUH5Zo`T21^+=U zAJ)y;w+jE=aDlw|CFB^ME-{3LKk*ufn}1Nz63CtZ!!Gf^L;knG{(m~;ZV5RJf~u5? znG1`@vxx%09P(#DN>5j0i=;Y1-KG5!s_G^SeYHWZ+2_iYt)*N@kAEqbU4ln~G0acd zwZHRY&?BE}o6z-0lV2HFQaYh~F++pK+2T>7OSXWi0C zLTZF!UlyFsZYUdqOj0t#NU-Ere!F5%i;+ zHwtSq14aHP6H?0jhyURPl+mCq=b|qu_t^SWIfwogF*WHf@q1(<5dn~F_4m-rU`Ie2 zApxM?x(~+|AuWDS1)<9w+-d)66?JgnHixDGp8qg4oC#52Q|@seUfM{U_kf`&M06L# zhXMiE%_wKkP*(OmpfW&ly8xP0W}(3VK9vqb>(C?HjfDebpieXH)^*$(Qpv;%Oy}h! zg98A3v(P$v*l`VRMs4l0+y;Wa+in1ZJ-?s8@U}SRkxFtL8gY<72u>YA2!up|K%0V- z8@R{4-jsbei2X6?wh7Rl3FLL%!Tt^~Y#!CnBZ)@e&QV(&C>(+&J$DeKuVDYlhK5tA z;@tIP!Rm=dgOQzoYGq4p!|v(r<9}|~MLI@>UhFFApLLUhlW+dnp$9QOkmXrAhjJ80 zC}gN*uiA8uy0rnre{a51V~sRDMR^j+iI|n{MmXR`wKwp6YUi~4`Y}Ab!~GBM@wzNn zrnd|ltw8E^fDRah-+^Y(S!2@R^9-aQU3!7gj4A<#1KjduOboc#p~j}+b`(rCy_ptu zi=zzATmc2KE2BGplKRlBUl0g zS!@!(zwxf6r3Eoz%;VH?YcebiG?WDA$cbLv7TG5BhC#meoZ)lV-hlBRcMuZUti>q^ z-cQ~~yzfALlt~fU(Kwo-fJ%i=FE>~^c!eDXwV*%TqZ;bW^llDwE@-ZT)>A|1HL}~x zRXBh%2_#p$sxs)q0Se;PT6G#PEf04gv6XTbLJfS6W_GS@R ztD96MaynCwr+R{gy;AkruqK!w4O@LIpPbp7iPKzZn5_I0Hm@)V(~ ze{xZ1D>F2mrZ_Gc{2gGbfEg`@29CW4s;kY9IOPrvYlx@^2DI->=epc$K^g)-`0ix| zyJxR-mn~5z0!@uA6sVf?xWG9v4jMX~2_hgaE>2F=1&*7^3O6IC`vMd1!+T?tAF!3_ zvM0p?JBfYOJIes*3iuO!sHInJrj7%ZJo`K}{Ym3EbSuNbCeU8@Y1|o#7(qXumB)hq z+2za8bRu-caraW7rx@5lX_R4t|K}WnKXe9?_TLJ*o+|i!%I0n)Y~3|DPUBRN95fj} z>YR>dvjyp4sL}~e(SgHDT&wP&z>LZdJz8*30Q84~!$kla%WG2SJpKXn8i+~O78X9x z>4)Wg+L_=7!?|G-9|7E2z$#IRy>=U{eR~5NL@-4_>`D4YO`f8^?h! z1XTl7FWG7;+yM<}#n#*05F%C-e5&Y;GV-@E`CXrM(5%o`AT=!AfX59P1$T>cKU z*c?U*;wp$ngpc1RK{5UHZS(YsB5S0fV-=j4SB#?%S88o-r8S4+0*W6BL^LD2w+Jb*dOgua#4ba6S@E9uUgp~9id>F2j9Z1O5>VK^5mAshIpT%ehjJ?}(i@)%+4 z2g^d%x&Isp^{K55937dN%}C?G2vD$4v%{eVqj~~apG6eNpSJL-OShZQj zpgzzPo{$5B>`f=qJwmVVA?z2`UW;0MdI4+@RC&Ekmr#o*!ZW6zMa5GN&1Wiww zH=yS|m^)YMN}gWWK(Px=vAwdjY4qFxNe7ghp0`Kw%5ETlkh!Ly+lTCkuOtj4%(0tUU1 zpvvYwfW~w16hcFx9b-N0W~~5oRQC?7shJC1tehx*Ofr{UZbP?mJcwTwr;eTiVy@Q+mmjgbuypPh9I^8{8}Kosgr{>?sw~p(3>7*2h8J>V)z*(_I1LP; zqrfwzB#8Y2dl=gL;D+nK7XcsD)^-yP3Fz(JS(^uN5Emc61sWSP%7KCeSL|BafTJd^ z^72NsnEKU^ezAuRO~=Y=3}&!qios~-E^MDDHs9^p9LSKh93Y24;0BR;9MI@6s8k>& z%qWM?EAe5e6i*P~g8`I_i)#V&4hbe^L7Q6;zd-H={sQ{<5Vappjt~RufX5nQ$Az=b zpi9vis0)59*!z+|e}w)aEUI7g=dFl1|pPo^1~@0`aggE+%4EX zz0#g6naFSDcLGbopMvcdT(JD54?)q68Cc0g;S?f{J8Nk({efz#Y!H zw^eJe>eYL%)!~nOJzJ3PTi;r9j@d`=zp;vn3B;-?M6qMBgsxiZg|<)3^?jj#miC)O z^u&5-;LZ;5AAsW*$}HI+*?d9U0GJRA6ohx7>Iq((1TL_KrWYRCl~hcb77Vl{e=2!p z?Hi8{qIZ#*mWHl)d#V4Eo|GsC+pycWs}>}@?Wg=mY!aP&7)D)KHqk=}wa)v9vjfYf zo)3?Qwx9nnh;_NP2ri9evG${CDAyqL#S|u_f;x(Ouib|}oEtA$RpA-vtX0cWhrzkd7eeNc3$NUxE zT;5||v+d5<(q;j2C=ajAUOBUr?4xDlD`Z743l}k+SW7h+QuyeCFg|x;+9iAH@SF|n zz=f%);L*fVsw6hu)X0PPh2|=5!047A5=M+?wd{|##3!(!GA)+mDtxB6^{KE8UzV}$ z$?Hw;fS>$Ke_p)Dw7;qOM{@W*lSX`Gg9OLyht{*tY z6K0ciF6O~+Znf>K$#+ZJA70OTf}XRSe{4wWP*Nd$6AWj(d4D63#_Vk{^1b+tTHDjr|w~PDLtjn<~F^wf+7~5IR4!TPK^}*XbH&s0Mx8P3BF zA?ZeOpQuwY=4;?Bwk?{t-dHSkeLd?>&?FFt%Ojw~DXX7X_9w2qj$8CRlrE%>E~DLiY0&74PcfeQCqAodWE}B9mCQK1@P&&ffHqSETad(_d}3%ke#Tee0!a(HnjbJZJh0u^ae3c>er3UWh=Q zTMoVJtpy>-rOtXyF_oSA__B4T85y%M=>h{PVAKz+8|aT~dt}-RE>NUW6C0x0c`Mb= z520dmM+Ueu=B)X$iXqr!0+$D$7aW*h=5x;+23>itn;Bt_(EF_W%TGlzCcH324X+B# zuwjikF|V4E)Jn6DX@(6&>Kc+pS@X-a_+>({~l3%|3?j+TYm<= zT+%Z*Am>$d`s&tl`SC5JJ?umjCmPY|28T~7HUUc`+;}von#5oaa4WI-S(JPK+#hdL?h&udd9_<0GQXPvNl9tM;8bK_LstK|Mpe`Uzc?u_Jlsb5oXZ!$C839BR zWMwlybX7GVO2H~dTKR(f50e<-+Dfs&`i{d_yK}(`c&mu!>(X|2AtLu+nNr;mwGZ&( zpk7;ks2fLLd;14$zQ|z1xQN~aw)gFV=D$~T=oYz6pnm}R(B#;6B%=st1yUI4STCPp zgC7CDpR}}FFu`$F*yLSAt3SjESk5PHGs^$&ml-z4ff;?<(=syGC**9O4$64H*ywYF z@Nxb$^MI3ZQJhJBWYLRBacRH0mKOC@92*aUND7jsRs$iJ_#8>d$mk6a`<4cZr)weU zETfH?)HjKw;Q4`O@DfqVO$?SX&znuM9(P6(TJp9HHxgXFJ?<*chRpyjm)hD|7$cFF zK``OJbfZ{_H>2ALsxU;CnDea`;yv>;slZofh!<(UHA9T-qw$%`&P#|$w&GWguR?9Y z8b^5?@zcWiN+GHxXY}IWUPdQo_em=DpnHmP48xjh*#4Fu0uj6Xk3UZN^&pz|1zQW+ z`1nG87x5p^snF>>0i_te0qm+EE~eH!Mu!=m9V=A7!{hVO=>Gn*Ly3g40-;8w8I>iH zTLt=AIMO|x{#gMK%sXq*71vQ+kaGp?uVCWY=RJ6f9z_`$ktqf^-a=I1+YfmW;Uwx`1d#PBuK;rXl~wXF-W+u2iaroPApGK~fM#A# zsD8L0rSI@c70!Q$oj`8>3+kt%fhTJB9_OLNSM7u7X^$cy6*re4lLx%*1bs(j>d0L$ zXJYv{ye4=j^CK0c$MR`v>#kHl_c(2LRo_Q1x7FxUOGhu1@sF) zm3U1|Ow3FB=*YXFz=c#ZHTIo+JD4u8?3qg(k zh`dmd$V)UjP4i)dvU4F+Bva;?rBRmyCn6#uzz3ntj!S^sNhd75LXUcRUJJpGBke;t zF%&&$j(ZR%LJ+10gCWae8AM)7sP)2pPZ2p}?bi(G-ktpxqHq5BNLqi{P!fs0Li_)u zl(+b@_g04UC2KjXI230kfcUkY2#Xwls{ZhUh}_d4W6LTmsbiLIuQ{TY^hBUE?ddV$ z$W>drb<+^-3630l=~BCS#{KBx>iuUqllsBOSI^n5d~E&TGHZ16@Y_~h8hycL^I+~^ zvUySAYkztpB%NZEb**0L3n(=ACx!o>s@OL(*4FmWEHEPjKIY<^B!K$t9n=R zPNq%}k1;%8dlbTO$aA=RW4}PF@z98zN)8o_#?xJr#hsB>Sckz`z}*^LJ5jxN?5euN zkg3u)Mr&A=-aN77JRUUshtffI(r@acMCkSWVm>*@JQAwd5jDrh`u)WUCiBTxGEsN#H!5xAe<6$X-_qP!eGCjz70 zV6$3^Ge|{|v^sj{Bo5xLc!SwtvX;f52|UzMz(m{NjKPtH5oS4fDtAz87dWzW8HvGE z1IOwQxRYR#I)l9dN;-7U(3dQ79PI3%9TjBt0kpTA3=%=KpdZ35G>6|aGH}iZrC1AF z9E^NNkG?|AQPgwRjpLP2E1&#GWtTSGs&DY3@#x;uey|H#ErPjx`ypf@w}yN4uJ!|H zNv=6CQ%(aB9LACkhPANp7&Zw|_Z6FkOK-IdFfC~H7toR@y;afSihnGeQ|Bk_HWM?m zI97q1?gH`Pvz>NW2d;eH-;t_G>R%$ZNZMKAqWo%sizI$2%V((vH5t<$j56<&uWIua zVcVV&*C&oWh<+efC&Mc7uiZEhI0Q=J2O1@P$J-K5AhZB@y6kRIJeec%-v(`QB>UIU zEMw{!#_v%VxC6^+k?$mcJCX}O_ZS38NR>r!O6@#+oiqSIuGg2gZ1r{jfj)3DS0Sw(Sd@&aAAf`U@b1zlUL^N5;-e-swp zI~5%X4%rYvDmbbKLT;;%zW>^OBf-4i`cA9drB3qcxc$gp>Ar!Rho?-wv3jMM=CtY- zP|=_+R_3vWwoxX_58H|}fvCRkcqXbE+?H_PlVmyuub}dA8^8bJGl6pAvF3&nGCApL z`2z%07|*iq+<_%BA1CR_(E+gq9%qsnAC>R^$F`+`aEKe5ncYZ$@s1F+Nlk<}0{{ka zHTGb2eoHs?{;kI-2#M<$_d|pRYfGCm_slC_w5v3>2Pl89Jxo6(b9miw-a|B?>DJZm zhd&tRmAc_=?Gkz{88ytBp?B_6=o(2p16{$7)P^K&f>kQ6ITF zS(%^XDIN$EqW4kj2(q~*xF_!0b0o2bP!!4MTJKyd!P+d@$X7DCwdruU*;x5C# zm~iw4Dy)Qz-e8r32jE0SnOu=A4saZ*H_~a%uHe?7>43hC#Un~hSKvFN(OE2Hkc2q6 zxC)V9BBtei_nro2*~Ny3r?SbTAcCe?LMJd9*1B!zcC5wVvg)c&^6MH)2^B&?4%=h1KFx`Qj0EP6x@wny=r#E7Qxc|}iMn8_$}uy?0vWQsdh z0B~Zyk7<-Q+|?5{Qi(K_xymP#n2mCE z=E`?^t_~>7{jO<}b5{Nq#2$Xt1*|?$p-&0SDdzSL|-Aq*KOFl zJfFwnpwsRIHYlTyhn;ZBfI~QuUL`W;q95N;HS>wQq%Qg9JhUlN-Qo4rF^e&I8kUqQ z!1T<;p;F9e+-v_~9K^`d+(dv9v88NQd~;SGY|a`LsV)&4TtQnI_z=+q9# z^qN*>x!g{OD72nXSSbQO50|&ekxZ}9O!!C2j+@6*KU(q;z6*n>XKo!=k{H=7#Gv1! z9cNpW<@d&qfl(qm#X{-iZ_g|9d8}pD{>CD~@RwO`fiYsVS!s4jFw1N0?yC$RyMLy1 zHmE?8_I`nmCS1;24IDSF7p@jRTf2+BG*4-RARR+ncw?T`Iim&F=_(34X;$md8%K8G zf%DDCAm6Wa3-r@B1zGoW9}#e&-vjtdvEtpFyo$T%KKfyYsPXXX>FaOvm%&mGp{~tU z{5Hx|MCdHaL)ho%Sa{%XP~T$d!(SNt{Vn{kay^5lsw#|TH!Ew3)Gia$9qgqJ^h@VaZpyZh@@f~OI^=XEIV{YSkX?CoQDA{mB<0q;P6#O$B0xO z=2O5r38yjb(F;g+zaj0pqfZX4{R7cNL!7*EKuPU5S}CZ6NPjgBbw6?Jbn32tcB}U2 zv=rknXpXF@zE=@iVe>7x#{^O$cBr_RvjQ~T<60wVO$?W178Q9^MIV5LMdzu@Ae!W2 zPQ5SbF8*t4%qkN1>@CTobzdBiGepe^ZY-7-pbC~r-1{}y<-uLVw%+A|2(aZ09S-Z{eSLvbv{JxCx6<+qyuH@D9~JWCNFQhkLt*8v7cVTv}ltc zoI_*hw4kJX_OB7AZ5EJ^J-wXbNcoRVp>rNi9- zoI7qUc<*ueeRt1LGO$eG{5O5MAR?}y(2m?^2MvB6eKZhuzzMv|3y5^#{^3WWKvQ4$ zTarc^ilspDpR!=HW4sF(%3W_`nK2va?QQq>CgIj_(`P=c(tUhxk3nu9+Cb>AW^=B+ zd>_ypqaA{hl5^l%WBwC|8G1@gf!=%NfHX6s$EcElOBd)j4i%}1j{nu|L8rK39xx9H z3XXK##IO$eXrz@;L2oIcz9MADcj}XU?Kod7F903nKF4FLr>4dS<=`08h2>898fn+U zg=Gu;Xa$lDHN6FF1U;i1+k%<07$sl%beh>ud+mQgeT8f=B)nfH*X}LPA5y@jlMQNN zkPY~Smv?~PwbpsEva#~f)1bzW*7__~1AB5K-PCopuS%~dW4`1}QJhCH;19e6q6H|E z6}3x}D=mX25DrF%KCMdTW!IC4T?seGCu(DaKpcQ~Ha^I4#Q z^2zug_f3!uO3LU3YA7}~R%NSx_AqUUg>?9jUNCPU9d-MjTvx^{Ld*NkhJY;yCCZ%N zqkCNs1daXJCXU|NVvQLsLi*GiS`Byx5vF_Z8?&NskHIloyjWtbjWdWJ-3x9dR3vC8 zHYgZ~dWHlV!c03TVFys7S;rS`aYRkAyp^JP9kCV)lQcF3)0;9XgMM*I^5uyiTW}bI zdYnVYxgq~jJ1|?=KD!sd3C9$^c-M+>RDfpK+CGR08*!^P&;>|VAJ>+7x%WrPvK+IJ zG&P3vbxOh!w#zBZ(Lm$!&Z1oCY`CG>-@p9CA1g&}HkJmm$X(u%mLcDC$Xj4r0OH|) zJMZS~_fU0NCa}#D9;DO~uKx)2|2q&6s+Cpsq8ctP8QAs@1{<#i%~9&*azVPc zO8;%+mNMt~0eutheajXt*8@PomYNB;xnFl17<7ScQ4s7K z$lDk#m#ozwa;b4K2oay?O(7C3=&}4zoE)E<`(8IL-(5zES`AV=FfIa5BPo4URZk_^ z_ZNR2UnagB|NOE=nJ1dfLr`f72Lw7JQlL#v$Sh@$ znH%u`>S}5V!bgG%WBHXs4$WnD(@SLSNuFNVHvzUE3pD9TEnZ;XF5~vGsJJ!9A{ayW z&ZPkJ;HPYhG7Yq@b6~a;cc-a|zVt;R)}8w88ACzV+RNnKp(sg-|V-^$C#7pZu9hyf6-@Y6+9549jdAF~it_Op4 zpn5uBz9_vBMiF4H#uQja3h7ZP7WJ%6&&QXTuiPX8=*@=e4H1E<Jsyw^=UI_~J0KNK0M)CywGcGzrtJQ8TIfY$h?_bYok(*>A627Fd;vb5?Y;8uc&Vq{hUttIT`}D(qI5Gbn z)9^p5mmX?^UW;JKkn89F)f|vIAXQHnTnkX{~zbJVMHFjVd20KMr4sm zx|<|1LPIm--vL9xvgsy^&$lW%gdfm1jo~*bN8Kh4p9dy@W?y$@O4_v$!TgoNsr7NC z)YNKla!2F=K*pmO>p)~c{iS5T@sSz+tFrhUF&0EKaagdkArF>=Qc*N>PFsYsyaGy z2bd*5O@|wtZr!BYLE}HO9Mv0OPGUz?11L%yy)l%+(5XR7&>4faUwo$Yet|vvw)h2p zqq7YeS~zpUfbCK234u)JMpQ;d5DUFV8VktVIuBPKUWefK>IJ{O%#g;ZNU#t1ak*jG zIp154SSzP~zAAc>bxXZU%0u^oZoPwYespXW`neDU$-Gr32?7+Ihq-jt`yV__#$vz@ zXx#0g;J$z=U1)c?=aD;W9$$}kq^^?_%m*No3au07EnNuZ^@L$K&sMPY5DZ@!Rg!aG z_W1F}w%O4N1CarvgFCwZ)H zdGVh3MCs3u2>zy~`h-U}?zY}&lzY5=C51T`F>C>^7L(&$lD{SF0ApewA6;O{te7n? z_v>mAFANJG6t#n&JK>#6d#<(fnnCfcdpuL;E^kg9nmLUZfGFd943Oj`1`Thh&W}LG zhmxDTLFRUo@$;tUH_AJ~Ae!i8jD5Rx-AcVD<3D=Z^x7}LC=paZ<=Joc@)0MYC@-pi zG?p0&m9Sw>;+_NYSR{r~sMfw+@Q(cr``LPNH;(zC)QlUv{i9#Jt8{BCjUw2W49Ih< z-|zhnOisImMbHEK0nBzJiv!RXy933a(*6($@ex=r%0i2M^$({bjN3;E-`Shm9 z`me;D@${stx>6l{U#)OVBZ73@A)TVSm1yCbpE3_!C`DD*{4_{NLK;VYxQnNuMn`>D zM)D!gc+TB9u*w@ySs*T81-J-WI;3LK5~qWD31lC0%00HMNiX&=G0HF0r6( zK;F2GTLVK9#=msL2*c+Xy9e7b+dZN0 zCxcaV4Grhe0zy;n2Sgb7W01Bw82cTc4&1O~^hRh5NLt6r*UV!^vHGT}S}U2`C9MBo zGX`z`2kd}167sQ}!ia7enF~AV|I9hm!#n->a{p;Y5oby@>BR{ELMod5b)}tKkB&iG zTt9GsVmJ#_uB&s!(wzS*BMm5-Khtnfk4^%zn*6T&1SH zui)E=E955sH{F)dpBLdJ?}Fi6z#vbRx*X`T5F&Ro1u6v919(Dc$VJ#Y#4*eqiXVy2 z4Z9F3H24-0a1#>;^p!*HH4Nb$D-MbDWj;)kmN7d@Z-kZ!XfB#R65kl>z+s#dy{2#( ziU-(kW*|&q@RE4xJ6K?d35my`KvOLwDI78Cj{F?k9NlbiGlEV-9|z3X#K_ypfNJFx z>>J2D4fSk``o%^jQpcKTp-7;n4pxJ1A}&n62rCNB#?17BfD{YvaE19n*6T-*O-WXU z^vSuUqN*wYQ*pMIhW1-5d5me8MW5XNZANx!aHO!nXf+w_180-@rAvPskR6T*X=epS z{gqWg?#6>v+Xr{o;~kXP7_@j8{A&|y`uNuvm0q?Jw3D*kQ0Rq*@=KiCyw}kOg@@-| z7&0x;K3co0#;{6^6WNmU1BXbC|;jEG>iXa)C^vsk}zPfGw~0I<<(beu7o5A)^Jb~6~A#UD|W zK%fMc8|fe&aM?04FkTT41F}=ZCxn|73);UzOH2SQu|12_4tHLQfq{Xwad16f=hzgs zr+sp@KtN4mmAruo>t{r^6@9+WNCvW^5fezqclmZm)!9u))ll}}?ne$6@M+q>GEj&> z^#H!_0gPW&n^c1t5Tt?;ynzb*0Syel2cTn{0YOfDjY*_Mx=CIx2>p7Z zTLNE>PNwp0@rekt+hqO&Dq2A$P@b`TnEFK+ULKULOtlBZQ9+>(r1`-lEas9QJutn> z!FO-PPnbmT{LBLSVm3EBgKZYFhh*;uD}^tsJ{=)UNun2nFFVVwiI^>83%pJ+KQg&| zTB1e+jtC5Eh>@U)pKVfMzGejYu0-~Fx!}DpF5KGk3AhGqIQKF#kWpsVGry1LD!58F@Rnl67yNPUFnEb?^6_JqoQ0DL0oYAGaNSJ6vN(=e@D^>* zeQIL{6WBUj(e)uH2^=TdJuz);4wD^dwr&N>1(#+Rbte`E1lFSWTSva_(u0{}2lXjG z1H1^Eyr?V=bh_6hvH*HEhYIA6Y(;uII5}}6vY%*A>cZsm9s?nj+mU1bzL(KyM^9mm zgaw%v&nY3{j>2rh~G#V4cOKsJFn|<%^Xb3GX5Ck^hx*UzGj!u zN5?JB`4`mfws_mpwsZBq_+<#Y3d;0F*R7iEq?*+}Rt=R`uP0=fn$1`G#3Qry3bxf0 zUK7C3W%bqj@c5ol-)~g)!%ytCqd=pohrn!;ib2fNi|TWFIug zVQEY|oia$jj#R_81xk;uB$b)py26YObn0}rsa>bk^rdIob~*X^+Ve>Un7Q`(sd>uB{E;Rj_vAm2Q46djxD$*to{p7~%9`VaU>>CuTHA%;2%$YpBF{N8q<`KAhz z4vFUA5C~m9U`w#@i7kt$4ua8F3xUdZWS7_S4UzVE+;9h{q^3FqM3qFW9$coBP}&CZ zYc1?}ILbc7^8@AY*w*Gl3AX!WKlT67aZc$L@3Y=QiYIr{(zH=a+#Om~tqavs2A&{T z_wJz?fGVeMX+&qmC}7ND1SyTfn%#v{<}0^L;ba}UQsj~}2E@ei={~!}H+s)=<_`90 zzT?{3@6fI^jl3s}0S_H^*ME6nNi-PoW8xQ{r=B3ZPbg6ZHTmBXmdy7Qwo_1iQe>_8 ziFjK~NP$q@@O5_0ig@rlGL6?S1`XbrXZJSJk%IT@&BZ=1*+t~YVcZ}n$@xBYPXxvM zB#rx9QfwT*;CxGZ2kUm9Z#?vmVIK2FZl=Ev@%X<1hx7)EL0T;h*j_<*c;XGme`pzh zy0aFBlKhfJ{$gbR2T<~hUHtzU6XvXPo#37GOU}*@lPT#*jAHp{?zXQ2acl$Fy}oWB*FP39A-V;yt~7g4$i-_3tEC=73lg zntT|7mhf)a(6apyC@CT9+!0NVX5cw7M4P ze_fmo{^H$asv~^uF9Smne2wrFvq@t8096TzfP$=JyKdsJm4#Me-^fYWGhw5KbMFdK zW+Iqb8T^rjII0GO$pWi(a6A$jP#VhRl`0t)k!-%G?hCSPv75maN2DnP2sctLC!j1c zt@zJ@FW-{;Lwy4`%`VN+OQaQm$ z+S%D@gJ5+pEQ9|_OW^|Cba>d2;|sh#zF)wLbog_&%lFndba&u@c>Ov;(4rO=HG52@ z2Vn5w^`MYfk1>ruwERcBdGsv2v6Yhc6N2m zjph}TT*tgG6j8(}kqBnP6r*1v`zJ&=c;9ehd7Etpw<#%}<}C!FVJF{9#( zod~=l!q&|M3|Ns3ONW-0|B+pOV1xr|fipWTnZ5(hFP*r{{RB2t|Jj_7m3_|uUTl^*xI%1x$iOA$t^P}wFZDv*H;rSWezq}kqX@y9LwUZ*Xc4&|TtRq| z?qu{jiV7*MU3moqfgqE1^U(qnz2~MZU2qaS5rowUvocP}y#z{mlcfhtbG;n%o17Im z?jY`;_%J7A)CuDh`$iZ7<(z<3-vUb%+$nu9c$ZK3S<^vRr&t(|umH*G5=?wwi`dPx z9>~?bBHnxc?;;!|{?!?QeTh`wG~6F?$>u4>{_X#kwEY&>)5foG36{xD&q_ zbBP7XSQF2muUQ2pCZSi0##G@0RWrq4IyKWe!8ZfW0AFJyvz-Xr#d(AW?)j4-FZ(7$ z79SWEqFb;+-h|7de^Eak;IUoRnN`1fPaRZn`W)01AtgBi}Ht@bY zwP#vs1rwJa^N?vaC+nL>&*;~d#n$4VVD<}hvp z!p6fvr!rFLM&!-G*8_^CoHKa9BA@neiiQke83~^_wOkPB!O&n$!VPjyJzLuTb9HH8 ziGCk{ZQ@=}DYLsvchA+jz`0|cVnUg(-OmayOfJyvaeodOoqn(H43vLWr zxAW-E!pUUiwl>)j=V%0+*4h@#4~SEyK>`kjob&Ll^J{&iGpg_8toVt?4~YV+ZFX<% zO4;klUV*c!jhp}8@xkg3Yyw)v{eI;x_*^ilg?8F*JiUGUwv74gDUn&Jwbc=A=(1xyE$jaM#Uu2$Y(=G>NSnzTBF%(f&V$Yj z05gt==_RclQG_?A*M0e=`e03-m-H<2wJ+w?1%{QqMfD!*+M5n&4Cy1>!dec#)q`7q z&~GSXHV@tVb~FJZH2gpFZnA?O=I<}VkBKidXSiWrf^Bfy1~Lxz>Wt$zj(2PJ*kLf6 z=cSEQ6zpZ+wuewu?{^$w1V+RFFCD!58Mr0gJ~}l$kV%zB1at$L?&8*)O=>%0H!v6zMfr+dwTKUyz+8b_*TeiqFJ%;9HUowoe#W)6xn`s;yN= zk$n_7zlw$K3dWxld(14r`@egPJplx0-{G!T0GUyP&A}9h)jg2U(^Kx^Y!9I6feuAdseDPEaX9Wh5qpt%`aDvf{ zg{SSOuP`gkH~Ujn?~-|)HEz?@>{ZYtx6;zOqZTO0+UJ|lHwiELV5PuY4AO(-jKTx` z-pP5q-QS2#0II&CyNJROB@OE9J9nafA)!#1b{;eGgLCq6e!d8qm2wjSD>U?7#1DcG zA{T_&vp5N$&8B_$3GKTzxc&na9=1!G?=G|AD0Zlp#bH>~P^!&op9 z;SLpn>cpeFHj3Ip(yi!Fr|Ce9Kt)C6gjNIU+LpZU(4sI2r2;BH!XES-cDYvgJ8tg5_t4(VLxofzacPyqe@pP68X9)qU1^|K=uzp zmHC^EL#A@)&;E3N=ptT(D}r)GI{c^)>l}88GXCeDe3X%R`_2!B=F7LQF%?f( zS;7@V;6dOgP0ls77M2~;in%doc#-?H;x_?(zjGUHC1`mmn{_p%?}q4Pgy;7c{ZAMthj!1WZxP8b8?r{R^5G<(bhORoKx(OX700<<9Fkr*VcO- z-uI1_O=iCpT)p#kZPxbjr*l6Z2_XA#<`yJ=VRR^SKwNmpTv;ac!rqwH-%4P|=|`n0BV0i7%XOo7l&QtB))iV5KwhLQSb4Ye<& ze^c&qMq!Npf-DOb<#Ra1X1GU3<;d*Xh)G-c#&h`~qERjf6JaQ!thZ2qVqzKQ4*MrA zHCu^yQWG`)z*_8rc9W+T6^Yj%9aMuQ-V>2`+~QaVx7-H|NQk{JQm5O}(jq@<*roMGUw{HYVt(=DL3Km>Y$A9BEw znqCp!<5x^3Bj!xb!HBAO_UW|+sUz#k8!9iy zPUby4U(K2`|D_%F2rxf(6AcZG!-ua}xAckti*FY&amR2b9yw2>*^`A0`l15mFF4SAB!+S7308FlGVdZ3Ni5jERF0;tl)%*Vaff-+o3|7 zuOb_J&R)e^yk}lg?tGb7G;$Y%2jnOR!DB$$rZ4jlq@VFrV3+Oka)u$i&ZMDm`NM#LI706B0%Sd`kqi#D)}`0V=` z6~W(PC99!s?#aJux%gm*nIx;HYjR*Ra`c@DVgbW+YF^xTpvt8)zPni1N>mKP;)4;2 z&;@f-QcANqAJs;cwbLUF%S-1Nz@Dsm=h;WRwr8hQt?yVy2(VQTTvX#p+8>Z())};? z9E_H%f?kfDFPn;I3FojbijWO{nZO2JKL zpR^Ne15n@LtFr9L{`Ncl_FDj%L+a5#MUFdGd4=D}8Q{CHT%PfV8M;N*OYJ(W1s zP+Ot9ufPte*2=06$s3Fh4fLFD$8CaA(>6rOvLNyLWzYrxCPveIKq>VTDOZddBG=ar@Kw+Rs{|>hw zd5-aL=;{_Y59o$|z=8|G7J_hj`(ToKI@XSsTnW^Gfn~w6EFM3uFvGC%A$I`DZRN*C zosZMi-=mZL7+rW!GC`L_7Vn!F3YUf&fX6h_>tUjV0Y6eXwRq6qc6u<-lhC|0(lsIR z#lj>{;3dR!DaRTk2rXsjkwb^Ps8KA4bnPX(Ltz-;z;NfcrS2hgmC5j7?Y zSuuW}`@uGZ;Z3Webqo#fT~}%FcF3%X<(QuK0t~;@o<}p7Wo*~gl{4c$W$h6Me6jGH zNz+XQ4Z5t|-bru8M4*C`qjlB^@r4dQO<cYXQMs}W}6q$_iT67(KCNO)P;jygv^R60ySn8SZTi3Or1R|Ug?b4eK@ zrrf*F=!7}sW-L(-T^T4hJ$-0S_S?1I4J>wh2ba-^9!wlR&>PrZ*{@`9)k(MR;77)H zW=wA`)F`Jmz1Zh0ns>YHkJO8u%a%%dR!jCWngRBwFD=wJKIzrL6a+`_=Q>~J_a7zh zfzs2NM$=hX6oRk#>a)8$H`DltYTO| z*&`H9O-yD!t&*g}*#{CD?%x6s8&uhl(ES0p@KzccM@L684SdjLdY|D$ITlK+6&Ei~ z70yM77Vjy? z!J$<%=pQTmh+kHg$yAVkwq?|{5Gm6SWQ>m{#|V~ma@c$G<_(g46ZhsO?_s@-ifUvZx7?Y?l zd*cTNj!okSOWSmuOxT z4JY%E1CaD@Zz1>+&G&G;YF-yg$~zgZu#l-7oG@+@X1wtV_!L+64pJB>Piaij1RCNd zKSaf9jA^hA(2}Y)8|Gum8=qLV&irdt$pe`gC1i-dVCYeK z`Z=F(S!p;zKgx_O2n{RfD?#iOM`i;jvkY=~SiZ&lRO}=uVQe5Qs+Z%4p(?@TF9SPT zZI2@xO>cMic=?H<1P;3|b`e0i);jD^JXb|v z#o*jBwN8?sLRywx%i)#U`Sz1(HYMIRWWTR*m`)SZ8F5=KboqD1y;@7R`paCS#%4!G z(7G0Sj=x|&I6DsGSh##L@wS4LCBnn=Jt56vC+}PY~8)OeK zcO>w9qca!DyjApb7ZrcHxZ+3Qd%_mmX!YB>y##!imUdUiO5X*Vos&~Bwa#+I?|^^2 z-V?q})X^MK_<@0et@?H_aK=b_df>UhNOBJlPvqG_Lglw=# zuDlOHihHeFKmtJ^)fE;`)DH#5uQxdv)>qQDi^jlU`BBAlQbXukf$NAR&J>6=!&Hlc zc-U~Z!w^AO9Uc0^>tc6#%u1=X-NGG9#tCK{zXq-AXkdc~S%#Nav3OjPK1MZI*K=I$ zSo62GH!C$q_ZBej9r(P_Y)ZDPPT`ouhL*w)Vd@!%h1>_2bCs;`JpPVF4ql&@Tu1}( zm}WE8id;XXkAG`j(Go1_e#}C~aiv@N`}EQ^Z&@ouFAZwk=> z8p&L1GCxB4HykZi@3geC3M?oD4(1V8a{s7(V3|Xbdw{DVx>IMzM%-LQgmb3~xst^@ zLNvsg-X3Fi&w$#p$Iqi1*x!Eu`1NbkFqT4B#&jP4=5r35t@+HW@Xeze&?w4nBRkb}i)Y9wo zHBX#)8!I^nh`|jLoeW)`{H+;QcB>oKamPzzDy%z!(}EA=iV4L@^y|H-vD)I4Vs2r9 zBHFUB)J{ZSP0b!>k!vqLS4z;Iv0J@KB)EI$r2wWctPg|ztaG1y3{&45EC(B8(9r3Y z`rMG(?_)5w#-1x@zbT7aVS_h0vww$kmcyy9-b;RI*Ctc|H%kuTmv4VbMHBiv79FUA z_`;w%RwspI^^^BtEI5}%L3fNQntqsCYT-Kza6Hz6q*db~T0- z0Ru0$&<}Nvv$i`3`><T`rjD^F3=&fqdl z3(L2olz0t})RNsvDq6x=B>7&R+NAWd`p`6f>6KZq?@{rup`e(&z9!3_#m*GeiG}a4 z#*iR|-%BEnP%XhvqO#1tKhy!-bUNJuMB@Nxe zrHb<;KT49@akgon7>+F{42xGwF}`5=>S(z?KXu-?o8(QkCS30O$9o{BF{~L%XV$D+ zxKz~u_!cY&PK=^j7`yXsFM%sq0vE5=;^Ok>i>Iq5Gn=Gr$?;*~eqQ_lz<1rIk+zp_ z#mdF|f|>j%nKaeSh)aI6B;wGoPh4u1M%q6=>UHKUh5yNdUPhS-Yt;452l#cM$HW zZEI#xe@;~M!@BTYyDx$ywG{Z}G*1|$ASsmfGTx)~|jvseMS6v*K3|y2@`Sct`a`?fS0|jD6E&eU+-Wg@+ z_rt|QSe5(s5gZ315MVqmsBJ1^mpLc>$+fbH=MF6zu2q1tr7S1+`s(VP}mqw)`o|1>YQt~NRNVPJ6?oE9BAxexoZK$tz1jiEN zm#4l4s}zAN@ntZdIw3xOXQ(_G=~H7qe8X`1%;Cc?iUIug9K2zeV=WdcKQZIsbaaHV zZM+mcCg>$Ml~Z}Z$b|4oCRM;D26hQ**{?)=`0zoWy#uKzd>hesB;c>ElFK+7_%DmG zjj7IYlrZSg+ddh{1&HqW8Yo9bLSCc!gzR?VHPTD ze_dX_N&4&8uOec1mh&+MBCRszCs5^r8Bh3>SvI9-W!=V!bh)tdF8JP3*Hz{YDDV_Ietv$f*9rAA ze{3I|R44EK5|Jw1xc_DK(67oJfcc0GtUk07CE)S^^OT?yQ~3m9Jl`H7Rmcthpxr+L#|K84|i{o15|s z1c@CUC6uvVAwNmK5vL>A`te1;stqR)G8DL%mvJWzbu+@0)f$VPGe{H|tzGjwT zigf*Mj?;Kgy*HsMZB`aJL^%j^+z6t4Q1&tM0!dYP)V!ohCOk8)@2tmAI2?|Zxx2Rs z3~jXkTF(`ud}rhc|7Ibq&}yg*E^Z{%-1e7&73pnN5hu6=JPq&Ax?*fvu0xmd&X+{1 z$35-rDxXSwUf_Fo^}uce!$DbAnH5dz$E%l6*u`Y|Xm;+#YMMJhGRDydhGbQGCMsI{ ztCx{I;N_{63#CSx{U*uS$*FVS`m=`46@F0i=O2Fhu&iA!wGJOngyN{(nOM=rjgG4i zo+nizxyS(%;}i9p*E-Fqz6tN^ut9rbC}l(<8UVw>_nXU@X74Sd&_5>M<7jSTV|=jn zMHQ9+1RtR1_kHduJP?_%X92+{_rbViqkFo!ZO%X{2a|kd$`0)0u zzSQ~wv4LS6jQ_TUIj8EmY#*Z4A8X%~@vHD%w#y@0=ymi+Wl{(_)YO#dQllBf?^j7% zRe#1b%miBMeqrG@(1dzbt85^b%I%;=GXQaC$Pv(LWRD?FgIiQNOyk6f@ZeyFS~=GA zppz%UOlY@m6;sH^2qq-$U=hYiPtV-iTI+@@y64g#Jp>`#7pB`73ev3chc)5lW);Vu z3T7Sq&45lO`AFE5mS1@W6D$s{1_(h|zWTk=p>LRd#nL5RDcTXo9&%Rb2rI{&M8gVP zSA=CTQfV{gazp|MG4auJ{n*m&Kj`C8iH@hrGc^uqNjjx}J0>|<0~aL6RS>=Iz(ExFiR zc^-eo1lcg+1|;1fxO4G%%gOmTFLI+lz(iN$yXp#iNQmQRS%@J6=o)nvTWlM z6L({N8B?H21b@eTuZn0}ReB;=4DmZq0N_;;R1>B9AEuIH4}P80Bk){GdRof6qMh}otSmbytl2Ju zXV^Q?IZ+Y$d=(R?ZoEQ*3q3PN28Pb67~oXZ**ne`4aFeJC(n)wqHS*W{G+d#A^b7Q zTeog)YHGS;1Ph@4g^tke+qYwdp83#qFkF@eQ$nH>4eVdhl1@>`Pb}NrS1dSw$Qr z6~+g;U_TNR6vO~OF&mMBDL3N0P9w$#hlM zVsLk|W@r-gO!u+gHN;YZuckX5Uw(+1smnh)bJs)%1t^At!N7-}2Y!Q*MWna|$~X2x(~1*2s0j#_lM|tzxXAr~h(}sBv>~^HC1e6oc1#>AEiHu_ zYe30o|K%kLHgtH3Mui$~q7?o1bVzw*3#6F+7+uMpjD23r`K*r4`@G^AYbUPkmOSb; z*Rt}z_@Xt11{FFRc=(GTCz(atUw5sMWdStb2{<+r5A$AHVB9}CWOg@o|C6-u6R2A7p}?vhQ*Sw%yfOY0)wY+=VM%J>HY) zY~9V;tvCt5j)Z3huHfqGIMLSyMb~z3Kg4uf5-xiMh(~G4aswZnghb5p97VCdTDNSt zCS4`b|D>UZ!7A^V#*;@mIkN0A3doTISPd{G_>u==9D>+2&&U0FLNAk)^r*i#2RkrU zXY|Yr4B{V3TMBv{(4@fK^dpnQt z()AB-xk}9x*!9_)nIK>bU?jqs3ZpR1%*>cY>`E@I<+yZx6WAtpMCl_y8`qhAv+4agmXRgf(^RqfV{&mFww!|c>p&u zHtpbGEXxHa(WeF-!|dNvHSeoPQ(oj=mUq>=`Z08SQAaZ3`gxO&>_7C$9pdP z26E#2T=%l==g}_1y3Bgp<;>SVZd$tgLyB|y$+32$^t9((+Z^%El1Xq0H@E?_;N;+d zMmA6G{rKGjA3kW$rihz_nGm->k`2&0BQd)gDNWL#gQIJD+RZ5kG0{`JY*$GF6X8uS zD8KkZH?i>X;|r)%u+MGYs|b@k?9<4QNKe01C`bvX$SG5L zm5!o6tI?i<<7+Fwm;%dZvv>V^$WZwQJd8`rw_ zK35J&2WJhdl;M#Vj$s>nhLsy?MBO(?Fx#OkhY}t{>JHP<6v$!Egei!|!?)whu~C}` z4=O)uGBi2GqF%twj3{&3)gD9$`;fGaxeQgJm_$}VwdO-zDxUgO zhl(WAi(D1uew&5ome@sq+LZB24&n}EPBlEKMpe!|=Bge(LBo3NwZ7%E+yPu@*Z^^g zLyJn5eQuy_R>{QnBh%f!8_uGiZYpa#KW1&X*(#m7`CzY&L~N9ajz@8Eml$7~XSv%M zDxT(%9@M?x$Aa%XUOy*ELBZXSE+2B?Uh3|Fx`EdY4>u$dHI` zy}6;G_~Yc)wC{IRnvBtT`l$a*g6T(m)JvM3o!n z(f?Ehugt2^<|EAPSrNtsJIQWZ5smSE%OMB7vDbR$#0pK2WuMMr*jTsE{KhP_{zpVC z{mP~7eU#EW{}cfe!;#F*(GBYubiuAVx0-cjoG=l!KH8}Z-)lmd{GIr8NT28$b;y?h z2mK{>t2ttSokE7GC9B-7H1!d}y)LnG+(MtH>)_adhLWn`7W?Fuj-&ZYPi<@S{w0NN z6Y?Og5u9f$vdb$fu%QmV6&KD2LWldA_Xdh_W+>q>0N_Xle;`1s6VJC6{VtzOR>R6r zTl;9$hDMaF->M_&DHhk0b2~oVpe73n^nRljXa0z%m@5s3X&V>d2sCS8q``*m#OkyS zfbl@<7I=I>c{`KJm~n1JiO50MU&o6Af948eh9TMrPL+MA9vNUsyu4zqUo_K)>n$hp zNl@<7oLbW#_%8J473Ae1)f~^%wr|ui3k?s)nS8a(hCl^8OBw_I7vl?-Fc8{>+{2c60N71Uu<-B1kVu#n``lo=>tu!rSt%CLn98maDqrMh)fT>6%NxNanxS7N zLAQfw^*$?w;KFF^ILO}E39RiN7)f12pP^1wR0e!~fudH_-feOR2N$q0BT<)Vsu#aWm zz5C|E5y$i_CwGugHqOJLF;Zm0OF^`#KGmg_2}JH0mkDf?u5 z*TQcks{e;9WCllZ2S{Jt!ql=7&_V|oPVA<|u$PQ5;!$Er@XHLY~u#w6; zVw}?Vu{(!#!a^?yvT{{S^CJql6T=}qAfXC2;6ZTRug23>TwOcsm8`P%Gxa~E#VhO zosKRX>LU0ZrGJxU`7$&C&QVgx18o8_L)pH1)*F_N}2YONIQw5PO?N&3XwrVXgLx!BYXB1qK(Q@Q)J&p6fw3?N97cekTRB} zsF5UV*5`c0E%EpGl#~>Z7{N=@ zo8&av;h!)8Ffv9_gg8v9k0ZMUmG1e%MnKD7zqz4gi>qp((dk+-)P`fPTDsK56os{2 zT@lbF;8TFD3AEJITPzj}=xk9c!F+*A#Ls=^HYM0R!O4ovDr^)(J_YqvbR z;LLI7&M_n~;~(Ypu)$%GjHpQy$k>LATV~73xO^7f9#>9%ifO*bM-4M0Ooc7uLc3Ad zESqt5k3=_sF^3WF6T_4P-sJTZ$h;W-nl9?GI;G9wAZ6h=xKg zlpct(ls{Ol7!V`R1n2DbG8 z17NvA`0J}zyQ6PeUE~5BjrfybDttfIOu!0l`r*T}!vh_dNX$E{dJ`lN zSi+>5pYK~h2h2`=3jF2FnTcI|+ev%g;3k12 zV+@EsH@WRDOrkeV`hcvk!6=U}L$HB$g&%ozpz38Yy*I^|a$7`^T(k?UO$A}=qeo|{ zd;(~XyP5!#i##`Hfc7wLQCS-B1os`SE?@%)Fb#Lp>2!clU>g8=-(_l=oR@QyoqYRt z+d6Lw?|7630H#3vggqoRp#n%RMk{lt`2fUVCcB6n@2 z!+8Qt9|$mr&drI4XaMi#<_2rim9w%@&49{?v@}Q%zqyH*cu}zYTa1z2jW$Do z5D*_z|326WqtiK_YszL-W*CYGVPf)cT6Keq@))G;5YtTvbjbpQ0k9wsR7BXSd4fpx zupw-Ss;>Xa7~Cs#>`iSv&Y2Iicq1M!2XZB! zSe?5YAO8V7Bx0llj0H_1tj6>|e`r6hcjUUde}&r?S)n?7LO4N@0oBLyIFe?KRd1J? z289q%M&LAxSGb#0v`H7;XOOijM0C&IB{vqXG; zj@IYpg8!}lvEv(#3;-GPK!62>^wXzL*pD;A!x!0YSRdJ5I$$=Ar*LD}3K#BFtP4r% zSu;{`0416LS|iL;d^02;!IC~7n-?5z zB#hFwtIt3G=r`*+1t3?XGrxp(QD3j<*)y02h&PbX2hv6ZW{t_sbw_Tc)nFE&5KMpG z;w%cmSOF#tpnv;<>w%~8nCv|e`OiycZ=afm$aFqYL_$u`m$$DYu;ADCMMOUPgQHuy zPiN1bOwgo2XbPg^fG2r%<@CaD+EZhB%g!n&9Iv|(dUoVQX|ZH1&B>X&Uz&k9y(&}J zB+6SZIT6S)n$S=6`JMpu$iW(E3m#kKlJzG+L9v$$#S3gY(|8u^H-No}MuZsy*Tp^r z)M2o~^^z;lf8xcyci^mDx^i;==Gcm$mSrnprt#Lv1O zrvdQwgh6SzX(?q~bZ}fepPsvw;35rf755>OcJ;RP*Fj$W&2Pxlo{GRt3&{&EB@4 z^4i$}8{ULGNv-}VqI%u2c^&e(6N*wpYNg9l?d6i@wCO7?^h;ZCEJU|{8o>3R+^tH^ zh0b|z?h-1C__0IrBAKX6T39~H<|d%#)n?hnnH!SU4OyXrWBjt1If+F-X2f2$j}!b*k&5cjACf(NL~G=QgT(z1yZ~r*ilFsrapY~D*I;Z<(sY* zA-AsPEbMUc6A`l3Q%Ga6K&gApQgq-{V5#j4mD3lB5L6pb7Qq-2G%Y!*z)7Qo3~3{#&85&q3$o)xeB@T%h_TaJ0Q8# z*-wkjLu`a>50%3I3}aE^^$Tu$3LFa~BUSVpv)$(?Y7$CK^R^K-7QBIdRAL3`z8_=*3sT5z~v&Y~qoYSnWw?(pfC#R*}lo&Cq&-;MfceIbn|4yj87a zKMhlUj#dur*crr^X9BxkG|6*(bTfoK@@FXF zGU_bknfROjJ~(9%oecybIB>FWtdWW9m586>1n>(nB);Jdg+f1gJE5Io4okrI0xO{N z7e>~9Ni*V%CF2NWcuRPN4;-5OH{<9Bu5`NhKg&4!4}%L+=TX(gD|vV}kk$h%Id_ie zt^^>0IKCO0LjhXTCASGoCNRt>!Oy-z_*8KP!XoRA6-*V_)EoY0lB5@WC9uA}qj%hu5=h<&;2}c0pVf@i-tr~-4GDfw8dWg`ekc`VK#?B1Bm0>E(&f{xKrEOjq2%B zyM5jZ6@i(@_<^dnykdoFE;j%WhK{15vJ%W3E`#|fdyWc3k8#=AM(PZ$IAT$XH-MRC zcY79%?FeHV*AgFE1`P~f8|Nuu)A9VLObeM$RWC}#G|<4rB-j4qi(&`+ieb#=$svwn zukBUJ7T*1ayRknh2oFEe_JC_*1_1W_dh4%K?@z$*_1vf*ID|ni`sbFe>zfwx&x1N+ zjLVKxzi>;?lTh(0r>}F)twWMfW^8N|w%`ys2WFtOu)lFIh&>GhJ3`fCUTxZxQE4Up z(cT4BH1^?TgOVFJuuL**SG!yTm$K${E=aMs%CLl9wTg`m7mXaiKvZF&m2aenJNNfz zR_~sFU;2mEvbJ*E} zFC+42H>-GTc~_o~a*U0d$y}bo*)F?4mmC$oxP2IRTKA$IYYfjCZ|qfj&&ou3t}=AZ zHBH^XyIaLa7?21I6#v4V{G0#zH~;fL%K!Yn8%K{>HzD?|YWgPGz71~gy!OULMckga zYv8`OugG`us#-%d-J~OF$i3XiCx$9E>b592WbK$N-}XF_7}NvDyXuAjS$h{?9aMRk2ikcfr1hqSW#u_5;RjXGo1p5qv{HWn=J&(#rEdz{MfzR$JTWfhh?U1fC<0wFpez#`%`fqhT zc`IV>L26xiVZI%{GhyC>wfh!e-#)e@aH^m599X(wU4Tr)KT*W>QwnSyP`RTKhb#ly zc~2zPUf%u=!qt9|7sO-kf%nr?8WyG=gY`qGKrwC@-{afI9-0E~@^0kaR#(G49%f}L zG_OG$lu)9!Od0fq%*@QZJk!u)u&4#5_qwbs1x%Jw_s@1`RU?yxoP13fw@uu#g?mz6~b-veJ5id-@AX)oZ0Jmg zc;?;Zxcho)!~Z0g=Q|-hEoeu2Wvr8*cegQ>8+owEYwSxa*f_GE#4I6m3 z0)FE-;BY=Af$-W^^qsRb;q>OB)B%rSi0NgVW{%^`utM)4G#lgqqIe0**-_g~i7vOq z(BE^Yba*~^XAp-&#!V8;A<>^K3VeqI(&M_qcrd^H@dAW(U!rb{Dg&rpioFUX1RQrp zsLhRyZ^-$Y8(J+7ho>@jS!BxU0L}$&J~!{ng!Nloz|kXW2rQ0}wFl1x5(^4zybs<` z`iKr-uqVI2NWBH4P<@k>**^IPAshshUU6@$j!qdltsu|C3)CHxTo(|UG3H*sGe*rS zPgH0cI)sDRfQYdOP!N5wI_I+g2bA>(yDBNr7NtM1VUqiS`*a7b%h#{A`eitFO^~w< zhkI}%K-eT^?J(UguC4HWY|)=Tpu3g3S8{ z379)D(SR^dy~Z7oC=%S{mI)g5(iwOtaC@LA9r^-}l!5uV{DJpU9UUF)>S_;YD9Ba- z02`m{!9MO9#NWWDnX}qxX$+oMh;VL#C4r+r?jorq3_P$vVNk$83VaPPYqki7n1FFD=FzW;KooUm!b*@SDL?ftIy(rkA{s2J_#IPTb za=?unIoMbLu!4*ZZ7WWp-RVbuSShH-+`uRSkMzg11)gdL!UKHN9_SI-(fe;HQ*tHn;4(5Y z0&_I_Yf-VcQpi+?16alwFM8zHJC~75cpFsW+W zAdQV?OpQp8ctO!8Y}xk>6OICbML$Y%VS?)IU0z(GnBqRD^Txn>?QlZUmD6~~D# z{(Suso6k9yoCU_&^qv`S;xu!lTClVhXECX=sd-_QRHTchob|pf( z`r1yyI3YQemD`%m%f&U^+bm{YRU4um+j82ZJ^@w~vFlu3(RggmJi)5q*IkPm+C*PJ z9f}38k|ify-oV3hQeNT@4^m0Wdx6nttBZ%zPdz&-95wBy=ny^{q zw>&Zz@~PO_9UW+8Zwc``AlVSudcJ*h9`JR1wvJ5xT87GmiR(P1vUS9Rn90ez6RW6; zA6Eyb#+?FmHV2_yl? z^k&poD28FCeEMVzh|buDt!B?w=1sxI0%s$DF`CQe<>dZoAjJ^efa10#$(vhuuGvg< znk&CttJoqi=15dy{7`-Cm-yU;J$hTCV`APTX97nm!FAm*uO`>a>GSfc^;#eHt8nF< zZXYBc^^Eg7XLf&Ag_NFuA^ff}!9;@)Qn9o4k)MP}m>dwDb`#n}n23Ox8VVsOo|tez_w6_s?L-nsN3d&5!hBTV(i~a*8govR`=^;5B|;{N}2Iv8HgVn zcOp zcKHwiL=_~XuI-B`yF3Sd3p^*LxC_zc&2Xr^J=q#X9~Xue-P{mI%LoHDW>U#4I1%|( zY=Nu~;{HwuW(EeDm2M{{&Q$4j+fH=t5%Ob@-Uy;hHu28VRVinp=N~lgM+HM0{{%sK_TG? zip5|m+A70bQ_pR&&iO$5Mc~`Wb_?&NX8Sd4i{} z-Ql?5v6Mi@1|r`?Fi7AH?K* z62cVlccEJ{Boqy`n`3nsYT?L)abhy!~ z-%FD>H`3p%lYhd*mLRq{#`rqp1ZT_kz?y@Zu|wSuziDDJ2=>WdjP6u?mpCjN$Mc0j z6y*e1em3h`Rm*IjM4P*Zo;`J=6mE>=jUWg{$)M!_d+`tu5q3>KjH{?Z2b8L!CXiQR`xX6s%QvIG;;ScKSzYZyRFN4O z!$tW6=ONg~tLDMC%DS$@jGT=iO7#y8dTQKn_k!!i7bVPUAiGFT#_uQSamd66SRJrH zMd4BeC7MFh0e26e9--jJLFovCv|-e9<4)d3CxZWh03xU+pEY-Yso#LLn&x}ts&|3@wR1ylpyqO*pLFO-A<@!*Co_2YjY#~k*k87L zNt7)kZV)!ny*gKAk^lFe(1dWDhfZ?AzcFkZ#Q4aSh>EKM3!;!KMxQ z8?jvv50nlMlsM%r@j4EG4VaIF7ra-p;7kO;H`=b;PHIz`7X=6l{NU;6%;30%7~-4T zm&(b>N#+mOLhsK%@nFg;pbaagnYDUPu>l=D_0abn$z{G0D1*BfyRdPiq(oQ4k;oL7FJYv73{Y; zKJ{{PDKKyq-(t&&4r$Qn>9b(EfIkYjX{37x;ysTa?vc%44+5jwgKipsFMMqC0iqs& z56Q?T?N|5EUr-v^r#O;QC4veFyai{WNz;UURTmQ{$>jmT=1>g-20@obP3EGPgC6;U zYP%})ilY)DjjGhVDA1*Y*2PAw$*SA;QZbfT61t%H?c@_0Uw%^W?FLk%bkZYIGr$pr zc~>uNuz*Zops_*Lg-hpE^*=zPy$iA=#84oj41V!ZBC8eleaLI*BW{0S2JU`hxK6Nj z-FXTcRADIIa8w3_0#LSWW)|}@mw2&+6;2K|HOE0|qR_(ne zmTd{0laI+N{Nr#^a?V=0`;pGsv7OQ)nL>7JcazRjpGOgp~P2 zMQ*YXGT^z;xZwWxC4&9$K*}rVP>>a)`q*VLW6JsXsTLW@NBm^{EKT;gpKdxI9{Q`>|B!?` zI_%szXzKLa!-o1!z!pTuZf$Ka98HyMW+s|rc|T2+5POgL{Wn17h|FmPgO4Hg?o+H5 zyRF9>Xf-f5hQ=kKk4t4r<66p8w|(2CC>f(S`{9Hsb70+IXT3Xf&RH3ra3zT%Te<=2 zDb>X=3^?fOigc6K(U(+Lc@%+_?_maCOIcr#O1&NB0O9OLEv^o>2Qtux!y5+pFg<~!HNHRN&`skejrb0*%}vZIzEi%tjsvFomzwU+ z`_}wvV#oz0XLCKGMsGEn72wl#?2@0KAGeU)gdrSR8Y;e!%@e_niZ5mfaA?IAy&gR? zsDsGT0Iw9KYA<$jz3O%N4Wjgh5y+!+v$g26&OZtiPAWk9iAZO#C4VT95(#>C%XuP(0$tfO?Qj`@En(+()Ag66Nvu**3KPv2hJpw4 zkqZCqq@F#8+Ap+MX9xA4CCgzjWcg=lHQ?1S5TD_x2s$Hi{*H)<0DOvan4ALZ|4S)z zy?yykHM!go9r~|=W-!AX6{~SdMF$c;WC#mE?l3kmsH&?=uDc#+i#t5nf6ULBv&02E zIDGI{#Jr2UBo?SRhG%$-iQlaR@|vy!NgsS@6Ez}3lSP>>uYj=vXwMsLwN5;88C%NW zDTAUfM!_(#9Rcex83DMT0d+qnwHa8Tqh2T#F_oC9AfB{%W2%C};2lW9lXI4F8P?F^ z*VRdSfnNx>QKape1>;3S z;k-FV*^V&frLp^a+MqEwseIymoC(=8aKef*U}cIuV^b25MFCjF{l=sbV+Lk`X3}a4 z!`(VMm#bQWhBH<7R+ZnO^@HmNpf@6r8hZBnnh*B7OECSdZtG#Q7Ebnt*AHHP_AZLW zBC>x`2&>h49)QqXtGUKTesf1}b(%&EmQ zoSvMlWv&B32Ek(CS3okI{eIh@ohz>=XUdGb3^ZDZIu57w{W!9?zTZ4owz z-TV#wYJvNZSvb_&d*CR&cdr|MA7S)h*@q2&vLJHu5wluS?trC(@f#Uly#{fLdEpqm z5;~eo=lYcI)K@CnJ6}>>-W4t|m=qUd#Eu7j_|GN&@RBea4a3u-WjIYYcY1u1(ZR;|)Ve*gnZykF4jjT2B+MVhV^nx-L!eQ+-CcnobI z>-VM*+u#+kj=ERPD~C)1m|9gCsUuojnJH) z=#HtvdaJ;|7tYDzLkZ1tg&W~K=tbeQ-wbOx3WI8`ey3VkB9zf4tlW$SoR|jsaRBy{_oLCUhloi^e$F1Z zTIg|m**Kn|lguXx_0NuqD6yYn;$#dmfqD!PtojSD&Q2SrP8^7Tn(=f}lo70oM#0=&C#+EOB$SRbFNATDV)y;Z;TlD=ev*`PW{vJgZ*F^b0=qOpbR*EpPK9+uX zGdh9(Zr514wwRDNC%82cE6O*LTCOf}n;gW;(u`;eB;OmZdc}1;% zaE+|dG>I*)*=30smSFRZ8v{TYnb<6b(W)@|WslODoiPU>8fxj1+;eA#mdA+h(wZ3o0Bu$PdBu)iwVM7-lJscGx8zHmTpa{Zk3gWNQPUTiw~ zp2*y2f*wQ`=1Qa>f!4()bIx``5Sn?E9ZdbHw!EC2!B4^Yjan1v1rTy2rR@4 z3l|gK5%JJip|t*4={kVmLw}tb6BTt3ES7&1EMk5g9f;vJ5SS#e)mpbNJz)3}Uam2L zxWuUD#Cf6vNj!#Wk3oK)J_fMjL071BI76nTtwW|xR2fVjULEv@^&VdG+InisZHps6 zabs4vxMSlXG+dAvDUd_Zp%nEiSSDdMkLTaM_w`(9Gu$X~V8CG}A<*`D_-6FYnCXI- zL@nJ(OafILSg%>3fQiukv*|fBl-HQTqe!5t!}LW3Gg;#G$3L+iZnB^~Ny4IlOeIJV z;EEZ1MX3`7gx$bMlX=Ne;aUNjpt3{#7AS3}s+U4@MbC`c?IkMOneHE2JiYR#y6Nq}2)r!+>=L9sHdc)q^?q7gn|2x+$D%1MTUC|arcR4jW9prc2-)!IxeG}ml=Ml zWh@2&`<5LUIrMDu@laukZX@dh`y|i}^rdTZ& zWoS-=lo;5~Y!wBdg(|+-4`8c_I}T;~nKNeq*x)(Db=b9X)-=>Oe%qqp61B^q}uu)0`$E4pa z4-;#kwFug&!P>BLI9uFk@494CvsvZfybvicG&?$rSJ?7Zh7y;MV^^2F*JSh*L2nA& zirJOaY|%BKt=RUmYkJU&%9k&x57wU-sQqDD9CwwWCgr3XFy^hU;N*|b%CIK0Co)<6 zDS9`ooLcGyt%)E0q@U)rg@K#WuV;PPx~xaVVN&pP4DFnLU@#9GjMWd(eG7ITETNmQ zi$c`&rhbCyB#D^=Pf8Dam@GpZT29y)!3iK>hlOR0rn{U`hJaj#5vO4*hB1M*&^V&I zn&YEkqbS5|Igd|EFu_q*N576<9qatu+`*T|)-=E`T}zvXJ~MV6vdS3s={v$X=PAUy zYs1YeR1f&0gef?GZOy2!gHaY#XLRBlH|Q~pmKt-qH(>RyKHJrFIFx?wl5=$l+s3h_ zdu!!197K%f@a0sQxMjEaOU^^2@C#UI6H@4JZU|ISy!JA6+joDxbgSgRR6rb3Qrf&& zn7j`CWxzwgaVcK*dc;xosRO$34`oq^1yEfvhMJ|*ME?iLKU51j@2+T6Bu$gn)>L<{ zh%#SpY-N)P%{BkT)kRP;q|(?eT}YOiEc&*+mwc&@TWM?}p~Lu%8GIeIVU8dP6cG=Cc6@FPj#~z7q+J4*(+ebctL@x>;t$P5c zy(xfM!4aVYaRMF$P@2S_`im&J^?rdE+AtVvh_J1Hfo-~w8@TcIVZ&fK+a|g=ABdm2 zPS>4eEp9mLq_=SKctY51e5?ox6*l~sH=G9u8*BksmPL76KRj4Z`cM2kC@@e@Uq3;s zFj=a)tV{=NNLux}E)NhTV2ImMs&v~=35*ng%1|16_LY-Jsu$5a@K7OJd$*c=$*RoH zBz$AEbvY>OfnU>E&>a)VX@yTZEFZpEtp!#!EpEP6ZT9`P9vnR+_z*`6#Op=4rXE1` zrC<<%kVJ5kVO#*tnhq#(=&F|w**v<4S?NV)AO@*2tBjEMB#$1^%A(aLs};@8;F328M>t5P#gy_C`Ix&z8Q{LI`zC)~Z^0@Yv!F4c@^VvM(V z)@0%ah-eS&-5`fp9X(21FUh1GBH*niMu;Dv@`b$BRDwi5r-crf0S^GI)Mgj}L4**f z%-Q%_1fFbXiWy2y|Bk?|yvW>D2X z|K?V4PbIGO>1%M`M)mcV>~i|(UB}WiL$9>$k#NMJMi{^Iutq?J1x8=7{&lhxM?(6l zRvgA7869^@;+DpIa#`CqFZs>1S%oDcrsJl-^@+5&?&m}-vSddHKkLk|#jk`M@H%}P$D<42qs95`EpvkQLz20V{| zP=6QR<$h*F1J8Ae)A~^zICW#V|BHlv>$91^bGbjsEfLcG!B?+3!P=3441kXeL4qfe zUCcW8L`juuHuUu>nsNLEd>l;Upr?m7#4ZQf_3h!)DnD-3|6KXv#SGZqZUTUZkxnnd zO)8dEz!gJ{H-dADaXRhoHCzV?w;v-!SWb=bJ0MSkH^3+4c}4UO@4Evb|Eo{i=f`o? za(xgvkO#_axUcFe04+RnNC$90ngOcf5XWjug56A-ztQ#`<}X-5gro_C8!A?^fKZoV zI(Ct=7-=1lQ5;-EISvym5;vy0IK{EG8oM)$I1#{xA;&?`=d3c|j-qzaJ9%#wVh&J< zCfdu~&5NPO!}DUOYPioV)UW%mIZbf-gV_k`J5t1;vTP;6Gw`}1EL?GMl86Ey5j}AS zgxL5AZG0h?v{8!r;x^$0BHMHu>L1)VV!9lPVjjY8;5Dd+gVZl#aEa|jg?If+agrHz z=gy@Yk=c{y-hDP&dNszk2RH|u*}n8E80Ui{Jd}PsZua1SX5~+-T0m8=?1}Z@8#RFw zkFvte(l{4imkQDg|3pv`AsqpC)K23x0mq)BKIBqXsy8p&K`yCC_+4XAMXNq~(Q}@< zY`R|Byh=hsZ;-~YxRP~YyIiPa-Ko1@jGNjaSix%~P6{mmY~{d|tZKQqEef+f6yjDJ z^iPtqwlJpTW$G=EbpiWIfJZax&*|a|cQ3vA!7T!cY4FZXFTPgVj6xDE;p&cY*Ub&F z)=I9DS;pO@7grG=mZ!IX1Jb8VJx3wZ&ygep(ew|s*ry3=ZL!b#gMA~)d|I-j%UP)Y zi)Grnx5Cv@R_Jq|Hbcq+QB~t%fy+EjEVO=R5~!8Joa{TFC!TrZr|1%#!LV~h?OQ6@ zAn2`}C2c#!p!0;a3eWxFsNnl1DF+C>-;3grZ}!Z9>4Kfg6^ZH9A4|r_o=JFrifd-} z_F?ky!`VD{5!W)BRS@OVYqPuXIBeD7E|gEeD6eeGLq8Rh*AyHww;hUFdf`pfcWgR} z-K%3@kZan8c^^@xw?P>K6Y1mlXJdP&Icak+VSF|3fO1<`Q^}m(W|Goi9~-=bNFe_~ z1PPCVz$@8B?H3$YV$jCT#6qzOcu&nC%RJVGI1h~ zSIv4E0qbXb9%bzitB~Hp_l3t48YiEy(fi}sF7HwZK8W+YP@eVL=Nhm(?3D7jXDao2 z!T6S4*%SYj0-KCrf6dtVnNRT@Qu`bH`u`OC3ZLnqU)yOIo2AM+)Cey)dS&0a^E~wyo-Z5BwUCV9z_f{! zCoRudi!*&w4*hh&l$zJchvS=T8wica$q|B|Z*{d1%fEGmb|=k98+@fXY7$)FqF!!8T?xtMlAl2{Wghg#Yxvsw0`JaphXJ!CG654y9SA0n&@?m8!7c*R>vImVS)70(Y+#M?zt}D) z> +yv|6E`_j>YNEB1=maaprJU;QvWa1SGn0(c$BN%oY!2SUS504rul6;CUtl}X? z_CG>fHVb4YWjhd&4^m!6Kh+|S=Vv)S@H1C?R`+Hi30qO_ly*Q)*I#p3xVg2zbffy8d&g5`?=4z0^bHf4AMf_J{Q7VC_5XA7?`6@H31G4;p%u z-j8QJh~dcyNtHD0Jfl%kJUl1HoY9Eq;o%v_PvWTV^K2m_r8W020gmV4Uqc?5|L%{9 bhXv-PK3X(=MY$aQ2+xkKTB^w^`%e8Ic1I?; diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/dynamic.seqdiag b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/dynamic.seqdiag deleted file mode 100644 index 95bb395e8868..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/dynamic.seqdiag +++ /dev/null @@ -1,24 +0,0 @@ -seqdiag { - activation = none; - - - user[label = "Admin User"]; - bootstrap[label = "Bootstrap API\nEndpoint"]; - master; - kubelet[stacked]; - - user -> bootstrap [label="createCluster", return="cluster ID"]; - user <-- bootstrap [label="returns\n- bootstrap-cluster-uri"]; - - user ->> master [label="start\n- bootstrap-cluster-uri"]; - master => bootstrap [label="setMaster\n- master-location\n- master-ca"]; - - user ->> kubelet [label="start\n- bootstrap-cluster-uri"]; - kubelet => bootstrap [label="get-master", return="returns\n- master-location\n- master-ca"]; - kubelet ->> master [label="signCert\n- unsigned-kubelet-cert", return="retuns\n- kubelet-cert"]; - user => master [label="getSignRequests"]; - user => master [label="approveSignRequests"]; - kubelet <<-- master [label="returns\n- kubelet-cert"]; - - kubelet => master [label="register\n- kubelet-location"] -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/static.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/static.png deleted file mode 100644 index bcdeca7e6f56222e00e8e6f23d9ea1ef3bf23a34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36583 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� 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 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/static.seqdiag b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/static.seqdiag deleted file mode 100644 index bdc54b764e25..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/clustering/static.seqdiag +++ /dev/null @@ -1,16 +0,0 @@ -seqdiag { - activation = none; - - admin[label = "Manual Admin"]; - ca[label = "Manual CA"] - master; - kubelet[stacked]; - - admin => ca [label="create\n- master-cert"]; - admin ->> master [label="start\n- ca-root\n- master-cert"]; - - admin => ca [label="create\n- kubelet-cert"]; - admin ->> kubelet [label="start\n- ca-root\n- kubelet-cert\n- master-location"]; - - kubelet => master [label="register\n- kubelet-location"]; -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/command_execution_port_forwarding.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/command_execution_port_forwarding.md deleted file mode 100644 index fa52d4e5248f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/command_execution_port_forwarding.md +++ /dev/null @@ -1,184 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/command_execution_port_forwarding.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Container Command Execution & Port Forwarding in Kubernetes - -## Abstract - -This describes an approach for providing support for: - -- executing commands in containers, with stdin/stdout/stderr streams attached -- port forwarding to containers - -## Background - -There are several related issues/PRs: - -- [Support attach](https://k8s.io/kubernetes/issues/1521) -- [Real container ssh](https://k8s.io/kubernetes/issues/1513) -- [Provide easy debug network access to services](https://k8s.io/kubernetes/issues/1863) -- [OpenShift container command execution proposal](https://github.com/openshift/origin/pull/576) - -## Motivation - -Users and administrators are accustomed to being able to access their systems -via SSH to run remote commands, get shell access, and do port forwarding. - -Supporting SSH to containers in Kubernetes is a difficult task. You must -specify a "user" and a hostname to make an SSH connection, and `sshd` requires -real users (resolvable by NSS and PAM). Because a container belongs to a pod, -and the pod belongs to a namespace, you need to specify namespace/pod/container -to uniquely identify the target container. Unfortunately, a -namespace/pod/container is not a real user as far as SSH is concerned. Also, -most Linux systems limit user names to 32 characters, which is unlikely to be -large enough to contain namespace/pod/container. We could devise some scheme to -map each namespace/pod/container to a 32-character user name, adding entries to -`/etc/passwd` (or LDAP, etc.) and keeping those entries fully in sync all the -time. Alternatively, we could write custom NSS and PAM modules that allow the -host to resolve a namespace/pod/container to a user without needing to keep -files or LDAP in sync. - -As an alternative to SSH, we are using a multiplexed streaming protocol that -runs on top of HTTP. There are no requirements about users being real users, -nor is there any limitation on user name length, as the protocol is under our -control. The only downside is that standard tooling that expects to use SSH -won't be able to work with this mechanism, unless adapters can be written. - -## Constraints and Assumptions - -- SSH support is not currently in scope -- CGroup confinement is ultimately desired, but implementing that support is not currently in scope -- SELinux confinement is ultimately desired, but implementing that support is not currently in scope - -## Use Cases - -- As a user of a Kubernetes cluster, I want to run arbitrary commands in a container, attaching my local stdin/stdout/stderr to the container -- As a user of a Kubernetes cluster, I want to be able to connect to local ports on my computer and have them forwarded to ports in the container - -## Process Flow - -### Remote Command Execution Flow - -1. The client connects to the Kubernetes Master to initiate a remote command execution -request -2. The Master proxies the request to the Kubelet where the container lives -3. The Kubelet executes nsenter + the requested command and streams stdin/stdout/stderr back and forth between the client and the container - -### Port Forwarding Flow - -1. The client connects to the Kubernetes Master to initiate a remote command execution -request -2. The Master proxies the request to the Kubelet where the container lives -3. The client listens on each specified local port, awaiting local connections -4. The client connects to one of the local listening ports -4. The client notifies the Kubelet of the new connection -5. The Kubelet executes nsenter + socat and streams data back and forth between the client and the port in the container - - -## Design Considerations - -### Streaming Protocol - -The current multiplexed streaming protocol used is SPDY. This is not the -long-term desire, however. As soon as there is viable support for HTTP/2 in Go, -we will switch to that. - -### Master as First Level Proxy - -Clients should not be allowed to communicate directly with the Kubelet for -security reasons. Therefore, the Master is currently the only suggested entry -point to be used for remote command execution and port forwarding. This is not -necessarily desirable, as it means that all remote command execution and port -forwarding traffic must travel through the Master, potentially impacting other -API requests. - -In the future, it might make more sense to retrieve an authorization token from -the Master, and then use that token to initiate a remote command execution or -port forwarding request with a load balanced proxy service dedicated to this -functionality. This would keep the streaming traffic out of the Master. - -### Kubelet as Backend Proxy - -The kubelet is currently responsible for handling remote command execution and -port forwarding requests. Just like with the Master described above, this means -that all remote command execution and port forwarding streaming traffic must -travel through the Kubelet, which could result in a degraded ability to service -other requests. - -In the future, it might make more sense to use a separate service on the node. - -Alternatively, we could possibly inject a process into the container that only -listens for a single request, expose that process's listening port on the node, -and then issue a redirect to the client such that it would connect to the first -level proxy, which would then proxy directly to the injected process's exposed -port. This would minimize the amount of proxying that takes place. - -### Scalability - -There are at least 2 different ways to execute a command in a container: -`docker exec` and `nsenter`. While `docker exec` might seem like an easier and -more obvious choice, it has some drawbacks. - -#### `docker exec` - -We could expose `docker exec` (i.e. have Docker listen on an exposed TCP port -on the node), but this would require proxying from the edge and securing the -Docker API. `docker exec` calls go through the Docker daemon, meaning that all -stdin/stdout/stderr traffic is proxied through the Daemon, adding an extra hop. -Additionally, you can't isolate 1 malicious `docker exec` call from normal -usage, meaning an attacker could initiate a denial of service or other attack -and take down the Docker daemon, or the node itself. - -We expect remote command execution and port forwarding requests to be long -running and/or high bandwidth operations, and routing all the streaming data -through the Docker daemon feels like a bottleneck we can avoid. - -#### `nsenter` - -The implementation currently uses `nsenter` to run commands in containers, -joining the appropriate container namespaces. `nsenter` runs directly on the -node and is not proxied through any single daemon process. - -### Security - -Authentication and authorization hasn't specifically been tested yet with this -functionality. We need to make sure that users are not allowed to execute -remote commands or do port forwarding to containers they aren't allowed to -access. - -Additional work is required to ensure that multiple command execution or port forwarding connections from different clients are not able to see each other's data. This can most likely be achieved via SELinux labeling and unique process contexts. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/command_execution_port_forwarding.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/event_compression.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/event_compression.md deleted file mode 100644 index 6d29b9957fc7..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/event_compression.md +++ /dev/null @@ -1,121 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/event_compression.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes Event Compression - -This document captures the design of event compression. - - -## Background - -Kubernetes components can get into a state where they generate tons of events which are identical except for the timestamp. For example, when pulling a non-existing image, Kubelet will repeatedly generate `image_not_existing` and `container_is_waiting` events until upstream components correct the image. When this happens, the spam from the repeated events makes the entire event mechanism useless. It also appears to cause memory pressure in etcd (see [#3853](https://k8s.io/kubernetes/issues/3853)). - -## Proposal - -Each binary that generates events (for example, `kubelet`) should keep track of previously generated events so that it can collapse recurring events into a single event instead of creating a new instance for each new event. - -Event compression should be best effort (not guaranteed). Meaning, in the worst case, `n` identical (minus timestamp) events may still result in `n` event entries. - -## Design - -Instead of a single Timestamp, each event object [contains](http://releases.k8s.io/HEAD/pkg/api/types.go#L1111) the following fields: - * `FirstTimestamp util.Time` - * The date/time of the first occurrence of the event. - * `LastTimestamp util.Time` - * The date/time of the most recent occurrence of the event. - * On first occurrence, this is equal to the FirstTimestamp. - * `Count int` - * The number of occurrences of this event between FirstTimestamp and LastTimestamp - * On first occurrence, this is 1. - -Each binary that generates events: - * Maintains a historical record of previously generated events: - * Implemented with ["Least Recently Used Cache"](https://github.com/golang/groupcache/blob/master/lru/lru.go) in [`pkg/client/record/events_cache.go`](../../pkg/client/record/events_cache.go). - * The key in the cache is generated from the event object minus timestamps/count/transient fields, specifically the following events fields are used to construct a unique key for an event: - * `event.Source.Component` - * `event.Source.Host` - * `event.InvolvedObject.Kind` - * `event.InvolvedObject.Namespace` - * `event.InvolvedObject.Name` - * `event.InvolvedObject.UID` - * `event.InvolvedObject.APIVersion` - * `event.Reason` - * `event.Message` - * The LRU cache is capped at 4096 events. That means if a component (e.g. kubelet) runs for a long period of time and generates tons of unique events, the previously generated events cache will not grow unchecked in memory. Instead, after 4096 unique events are generated, the oldest events are evicted from the cache. - * When an event is generated, the previously generated events cache is checked (see [`pkg/client/record/event.go`](http://releases.k8s.io/HEAD/pkg/client/record/event.go)). - * If the key for the new event matches the key for a previously generated event (meaning all of the above fields match between the new event and some previously generated event), then the event is considered to be a duplicate and the existing event entry is updated in etcd: - * The new PUT (update) event API is called to update the existing event entry in etcd with the new last seen timestamp and count. - * The event is also updated in the previously generated events cache with an incremented count, updated last seen timestamp, name, and new resource version (all required to issue a future event update). - * If the key for the new event does not match the key for any previously generated event (meaning none of the above fields match between the new event and any previously generated events), then the event is considered to be new/unique and a new event entry is created in etcd: - * The usual POST/create event API is called to create a new event entry in etcd. - * An entry for the event is also added to the previously generated events cache. - -## Issues/Risks - - * Compression is not guaranteed, because each component keeps track of event history in memory - * An application restart causes event history to be cleared, meaning event history is not preserved across application restarts and compression will not occur across component restarts. - * Because an LRU cache is used to keep track of previously generated events, if too many unique events are generated, old events will be evicted from the cache, so events will only be compressed until they age out of the events cache, at which point any new instance of the event will cause a new entry to be created in etcd. - -## Example - -Sample kubectl output - -```console -FIRSTSEEN LASTSEEN COUNT NAME KIND SUBOBJECT REASON SOURCE MESSAGE -Thu, 12 Feb 2015 01:13:02 +0000 Thu, 12 Feb 2015 01:13:02 +0000 1 kubernetes-minion-4.c.saad-dev-vms.internal Minion starting {kubelet kubernetes-minion-4.c.saad-dev-vms.internal} Starting kubelet. -Thu, 12 Feb 2015 01:13:09 +0000 Thu, 12 Feb 2015 01:13:09 +0000 1 kubernetes-minion-1.c.saad-dev-vms.internal Minion starting {kubelet kubernetes-minion-1.c.saad-dev-vms.internal} Starting kubelet. -Thu, 12 Feb 2015 01:13:09 +0000 Thu, 12 Feb 2015 01:13:09 +0000 1 kubernetes-minion-3.c.saad-dev-vms.internal Minion starting {kubelet kubernetes-minion-3.c.saad-dev-vms.internal} Starting kubelet. -Thu, 12 Feb 2015 01:13:09 +0000 Thu, 12 Feb 2015 01:13:09 +0000 1 kubernetes-minion-2.c.saad-dev-vms.internal Minion starting {kubelet kubernetes-minion-2.c.saad-dev-vms.internal} Starting kubelet. -Thu, 12 Feb 2015 01:13:05 +0000 Thu, 12 Feb 2015 01:13:12 +0000 4 monitoring-influx-grafana-controller-0133o Pod failedScheduling {scheduler } Error scheduling: no minions available to schedule pods -Thu, 12 Feb 2015 01:13:05 +0000 Thu, 12 Feb 2015 01:13:12 +0000 4 elasticsearch-logging-controller-fplln Pod failedScheduling {scheduler } Error scheduling: no minions available to schedule pods -Thu, 12 Feb 2015 01:13:05 +0000 Thu, 12 Feb 2015 01:13:12 +0000 4 kibana-logging-controller-gziey Pod failedScheduling {scheduler } Error scheduling: no minions available to schedule pods -Thu, 12 Feb 2015 01:13:05 +0000 Thu, 12 Feb 2015 01:13:12 +0000 4 skydns-ls6k1 Pod failedScheduling {scheduler } Error scheduling: no minions available to schedule pods -Thu, 12 Feb 2015 01:13:05 +0000 Thu, 12 Feb 2015 01:13:12 +0000 4 monitoring-heapster-controller-oh43e Pod failedScheduling {scheduler } Error scheduling: no minions available to schedule pods -Thu, 12 Feb 2015 01:13:20 +0000 Thu, 12 Feb 2015 01:13:20 +0000 1 kibana-logging-controller-gziey BoundPod implicitly required container POD pulled {kubelet kubernetes-minion-4.c.saad-dev-vms.internal} Successfully pulled image "kubernetes/pause:latest" -Thu, 12 Feb 2015 01:13:20 +0000 Thu, 12 Feb 2015 01:13:20 +0000 1 kibana-logging-controller-gziey Pod scheduled {scheduler } Successfully assigned kibana-logging-controller-gziey to kubernetes-minion-4.c.saad-dev-vms.internal -``` - -This demonstrates what would have been 20 separate entries (indicating scheduling failure) collapsed/compressed down to 5 entries. - -## Related Pull Requests/Issues - - * Issue [#4073](https://k8s.io/kubernetes/issues/4073): Compress duplicate events - * PR [#4157](https://k8s.io/kubernetes/issues/4157): Add "Update Event" to Kubernetes API - * PR [#4206](https://k8s.io/kubernetes/issues/4206): Modify Event struct to allow compressing multiple recurring events in to a single event - * PR [#4306](https://k8s.io/kubernetes/issues/4306): Compress recurring events in to a single event to optimize etcd storage - * PR [#4444](https://k8s.io/kubernetes/pull/4444): Switch events history to use LRU cache instead of map - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/event_compression.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/expansion.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/expansion.md deleted file mode 100644 index 24a07f0d19fe..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/expansion.md +++ /dev/null @@ -1,424 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/expansion.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Variable expansion in pod command, args, and env - -## Abstract - -A proposal for the expansion of environment variables using a simple `$(var)` syntax. - -## Motivation - -It is extremely common for users to need to compose environment variables or pass arguments to -their commands using the values of environment variables. Kubernetes should provide a facility for -the 80% cases in order to decrease coupling and the use of workarounds. - -## Goals - -1. Define the syntax format -2. Define the scoping and ordering of substitutions -3. Define the behavior for unmatched variables -4. Define the behavior for unexpected/malformed input - -## Constraints and Assumptions - -* This design should describe the simplest possible syntax to accomplish the use-cases -* Expansion syntax will not support more complicated shell-like behaviors such as default values - (viz: `$(VARIABLE_NAME:"default")`), inline substitution, etc. - -## Use Cases - -1. As a user, I want to compose new environment variables for a container using a substitution - syntax to reference other variables in the container's environment and service environment - variables -1. As a user, I want to substitute environment variables into a container's command -1. As a user, I want to do the above without requiring the container's image to have a shell -1. As a user, I want to be able to specify a default value for a service variable which may - not exist -1. As a user, I want to see an event associated with the pod if an expansion fails (ie, references - variable names that cannot be expanded) - -### Use Case: Composition of environment variables - -Currently, containers are injected with docker-style environment variables for the services in -their pod's namespace. There are several variables for each service, but users routinely need -to compose URLs based on these variables because there is not a variable for the exact format -they need. Users should be able to build new environment variables with the exact format they need. -Eventually, it should also be possible to turn off the automatic injection of the docker-style -variables into pods and let the users consume the exact information they need via the downward API -and composition. - -#### Expanding expanded variables - -It should be possible to reference an variable which is itself the result of an expansion, if the -referenced variable is declared in the container's environment prior to the one referencing it. -Put another way -- a container's environment is expanded in order, and expanded variables are -available to subsequent expansions. - -### Use Case: Variable expansion in command - -Users frequently need to pass the values of environment variables to a container's command. -Currently, Kubernetes does not perform any expansion of variables. The workaround is to invoke a -shell in the container's command and have the shell perform the substitution, or to write a wrapper -script that sets up the environment and runs the command. This has a number of drawbacks: - -1. Solutions that require a shell are unfriendly to images that do not contain a shell -2. Wrapper scripts make it harder to use images as base images -3. Wrapper scripts increase coupling to Kubernetes - -Users should be able to do the 80% case of variable expansion in command without writing a wrapper -script or adding a shell invocation to their containers' commands. - -### Use Case: Images without shells - -The current workaround for variable expansion in a container's command requires the container's -image to have a shell. This is unfriendly to images that do not contain a shell (`scratch` images, -for example). Users should be able to perform the other use-cases in this design without regard to -the content of their images. - -### Use Case: See an event for incomplete expansions - -It is possible that a container with incorrect variable values or command line may continue to run -for a long period of time, and that the end-user would have no visual or obvious warning of the -incorrect configuration. If the kubelet creates an event when an expansion references a variable -that cannot be expanded, it will help users quickly detect problems with expansions. - -## Design Considerations - -### What features should be supported? - -In order to limit complexity, we want to provide the right amount of functionality so that the 80% -cases can be realized and nothing more. We felt that the essentials boiled down to: - -1. Ability to perform direct expansion of variables in a string -2. Ability to specify default values via a prioritized mapping function but without support for - defaults as a syntax-level feature - -### What should the syntax be? - -The exact syntax for variable expansion has a large impact on how users perceive and relate to the -feature. We considered implementing a very restrictive subset of the shell `${var}` syntax. This -syntax is an attractive option on some level, because many people are familiar with it. However, -this syntax also has a large number of lesser known features such as the ability to provide -default values for unset variables, perform inline substitution, etc. - -In the interest of preventing conflation of the expansion feature in Kubernetes with the shell -feature, we chose a different syntax similar to the one in Makefiles, `$(var)`. We also chose not -to support the bar `$var` format, since it is not required to implement the required use-cases. - -Nested references, ie, variable expansion within variable names, are not supported. - -#### How should unmatched references be treated? - -Ideally, it should be extremely clear when a variable reference couldn't be expanded. We decided -the best experience for unmatched variable references would be to have the entire reference, syntax -included, show up in the output. As an example, if the reference `$(VARIABLE_NAME)` cannot be -expanded, then `$(VARIABLE_NAME)` should be present in the output. - -#### Escaping the operator - -Although the `$(var)` syntax does overlap with the `$(command)` form of command substitution -supported by many shells, because unexpanded variables are present verbatim in the output, we -expect this will not present a problem to many users. If there is a collision between a variable -name and command substitution syntax, the syntax can be escaped with the form `$$(VARIABLE_NAME)`, -which will evaluate to `$(VARIABLE_NAME)` whether `VARIABLE_NAME` can be expanded or not. - -## Design - -This design encompasses the variable expansion syntax and specification and the changes needed to -incorporate the expansion feature into the container's environment and command. - -### Syntax and expansion mechanics - -This section describes the expansion syntax, evaluation of variable values, and how unexpected or -malformed inputs are handled. - -#### Syntax - -The inputs to the expansion feature are: - -1. A utf-8 string (the input string) which may contain variable references -2. A function (the mapping function) that maps the name of a variable to the variable's value, of - type `func(string) string` - -Variable references in the input string are indicated exclusively with the syntax -`$()`. The syntax tokens are: - -- `$`: the operator -- `(`: the reference opener -- `)`: the reference closer - -The operator has no meaning unless accompanied by the reference opener and closer tokens. The -operator can be escaped using `$$`. One literal `$` will be emitted for each `$$` in the input. - -The reference opener and closer characters have no meaning when not part of a variable reference. -If a variable reference is malformed, viz: `$(VARIABLE_NAME` without a closing expression, the -operator and expression opening characters are treated as ordinary characters without special -meanings. - -#### Scope and ordering of substitutions - -The scope in which variable references are expanded is defined by the mapping function. Within the -mapping function, any arbitrary strategy may be used to determine the value of a variable name. -The most basic implementation of a mapping function is to use a `map[string]string` to lookup the -value of a variable. - -In order to support default values for variables like service variables presented by the kubelet, -which may not be bound because the service that provides them does not yet exist, there should be a -mapping function that uses a list of `map[string]string` like: - -```go -func MakeMappingFunc(maps ...map[string]string) func(string) string { - return func(input string) string { - for _, context := range maps { - val, ok := context[input] - if ok { - return val - } - } - - return "" - } -} - -// elsewhere -containerEnv := map[string]string{ - "FOO": "BAR", - "ZOO": "ZAB", - "SERVICE2_HOST": "some-host", -} - -serviceEnv := map[string]string{ - "SERVICE_HOST": "another-host", - "SERVICE_PORT": "8083", -} - -// single-map variation -mapping := MakeMappingFunc(containerEnv) - -// default variables not found in serviceEnv -mappingWithDefaults := MakeMappingFunc(serviceEnv, containerEnv) -``` - -### Implementation changes - -The necessary changes to implement this functionality are: - -1. Add a new interface, `ObjectEventRecorder`, which is like the `EventRecorder` interface, but - scoped to a single object, and a function that returns an `ObjectEventRecorder` given an - `ObjectReference` and an `EventRecorder` -2. Introduce `third_party/golang/expansion` package that provides: - 1. An `Expand(string, func(string) string) string` function - 2. A `MappingFuncFor(ObjectEventRecorder, ...map[string]string) string` function -3. Make the kubelet expand environment correctly -4. Make the kubelet expand command correctly - -#### Event Recording - -In order to provide an event when an expansion references undefined variables, the mapping function -must be able to create an event. In order to facilitate this, we should create a new interface in -the `api/client/record` package which is similar to `EventRecorder`, but scoped to a single object: - -```go -// ObjectEventRecorder knows how to record events about a single object. -type ObjectEventRecorder interface { - // Event constructs an event from the given information and puts it in the queue for sending. - // 'reason' is the reason this event is generated. 'reason' should be short and unique; it will - // be used to automate handling of events, so imagine people writing switch statements to - // handle them. You want to make that easy. - // 'message' is intended to be human readable. - // - // The resulting event will be created in the same namespace as the reference object. - Event(reason, message string) - - // Eventf is just like Event, but with Sprintf for the message field. - Eventf(reason, messageFmt string, args ...interface{}) - - // PastEventf is just like Eventf, but with an option to specify the event's 'timestamp' field. - PastEventf(timestamp util.Time, reason, messageFmt string, args ...interface{}) -} -``` - -There should also be a function that can construct an `ObjectEventRecorder` from a `runtime.Object` -and an `EventRecorder`: - -```go -type objectRecorderImpl struct { - object runtime.Object - recorder EventRecorder -} - -func (r *objectRecorderImpl) Event(reason, message string) { - r.recorder.Event(r.object, reason, message) -} - -func ObjectEventRecorderFor(object runtime.Object, recorder EventRecorder) ObjectEventRecorder { - return &objectRecorderImpl{object, recorder} -} -``` - -#### Expansion package - -The expansion package should provide two methods: - -```go -// MappingFuncFor returns a mapping function for use with Expand that -// implements the expansion semantics defined in the expansion spec; it -// returns the input string wrapped in the expansion syntax if no mapping -// for the input is found. If no expansion is found for a key, an event -// is raised on the given recorder. -func MappingFuncFor(recorder record.ObjectEventRecorder, context ...map[string]string) func(string) string { - // ... -} - -// Expand replaces variable references in the input string according to -// the expansion spec using the given mapping function to resolve the -// values of variables. -func Expand(input string, mapping func(string) string) string { - // ... -} -``` - -#### Kubelet changes - -The Kubelet should be made to correctly expand variables references in a container's environment, -command, and args. Changes will need to be made to: - -1. The `makeEnvironmentVariables` function in the kubelet; this is used by - `GenerateRunContainerOptions`, which is used by both the docker and rkt container runtimes -2. The docker manager `setEntrypointAndCommand` func has to be changed to perform variable - expansion -3. The rkt runtime should be made to support expansion in command and args when support for it is - implemented - -### Examples - -#### Inputs and outputs - -These examples are in the context of the mapping: - -| Name | Value | -|-------------|------------| -| `VAR_A` | `"A"` | -| `VAR_B` | `"B"` | -| `VAR_C` | `"C"` | -| `VAR_REF` | `$(VAR_A)` | -| `VAR_EMPTY` | `""` | - -No other variables are defined. - -| Input | Result | -|--------------------------------|----------------------------| -| `"$(VAR_A)"` | `"A"` | -| `"___$(VAR_B)___"` | `"___B___"` | -| `"___$(VAR_C)"` | `"___C"` | -| `"$(VAR_A)-$(VAR_A)"` | `"A-A"` | -| `"$(VAR_A)-1"` | `"A-1"` | -| `"$(VAR_A)_$(VAR_B)_$(VAR_C)"` | `"A_B_C"` | -| `"$$(VAR_B)_$(VAR_A)"` | `"$(VAR_B)_A"` | -| `"$$(VAR_A)_$$(VAR_B)"` | `"$(VAR_A)_$(VAR_B)"` | -| `"f000-$$VAR_A"` | `"f000-$VAR_A"` | -| `"foo\\$(VAR_C)bar"` | `"foo\Cbar"` | -| `"foo\\\\$(VAR_C)bar"` | `"foo\\Cbar"` | -| `"foo\\\\\\\\$(VAR_A)bar"` | `"foo\\\\Abar"` | -| `"$(VAR_A$(VAR_B))"` | `"$(VAR_A$(VAR_B))"` | -| `"$(VAR_A$(VAR_B)"` | `"$(VAR_A$(VAR_B)"` | -| `"$(VAR_REF)"` | `"$(VAR_A)"` | -| `"%%$(VAR_REF)--$(VAR_REF)%%"` | `"%%$(VAR_A)--$(VAR_A)%%"` | -| `"foo$(VAR_EMPTY)bar"` | `"foobar"` | -| `"foo$(VAR_Awhoops!"` | `"foo$(VAR_Awhoops!"` | -| `"f00__(VAR_A)__"` | `"f00__(VAR_A)__"` | -| `"$?_boo_$!"` | `"$?_boo_$!"` | -| `"$VAR_A"` | `"$VAR_A"` | -| `"$(VAR_DNE)"` | `"$(VAR_DNE)"` | -| `"$$$$$$(BIG_MONEY)"` | `"$$$(BIG_MONEY)"` | -| `"$$$$$$(VAR_A)"` | `"$$$(VAR_A)"` | -| `"$$$$$$$(GOOD_ODDS)"` | `"$$$$(GOOD_ODDS)"` | -| `"$$$$$$$(VAR_A)"` | `"$$$A"` | -| `"$VAR_A)"` | `"$VAR_A)"` | -| `"${VAR_A}"` | `"${VAR_A}"` | -| `"$(VAR_B)_______$(A"` | `"B_______$(A"` | -| `"$(VAR_C)_______$("` | `"C_______$("` | -| `"$(VAR_A)foobarzab$"` | `"Afoobarzab$"` | -| `"foo-\\$(VAR_A"` | `"foo-\$(VAR_A"` | -| `"--$($($($($--"` | `"--$($($($($--"` | -| `"$($($($($--foo$("` | `"$($($($($--foo$("` | -| `"foo0--$($($($("` | `"foo0--$($($($("` | -| `"$(foo$$var)` | `$(foo$$var)` | - -#### In a pod: building a URL - -Notice the `$(var)` syntax. - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: expansion-pod -spec: - containers: - - name: test-container - image: gcr.io/google_containers/busybox - command: [ "/bin/sh", "-c", "env" ] - env: - - name: PUBLIC_URL - value: "http://$(GITSERVER_SERVICE_HOST):$(GITSERVER_SERVICE_PORT)" - restartPolicy: Never -``` - -#### In a pod: building a URL using downward API - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: expansion-pod -spec: - containers: - - name: test-container - image: gcr.io/google_containers/busybox - command: [ "/bin/sh", "-c", "env" ] - env: - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: "metadata.namespace" - - name: PUBLIC_URL - value: "http://gitserver.$(POD_NAMESPACE):$(SERVICE_PORT)" - restartPolicy: Never -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/expansion.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/identifiers.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/identifiers.md deleted file mode 100644 index 14b5452b14aa..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/identifiers.md +++ /dev/null @@ -1,130 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/identifiers.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Identifiers and Names in Kubernetes - -A summarization of the goals and recommendations for identifiers in Kubernetes. Described in [GitHub issue #199](https://k8s.io/kubernetes/issues/199). - - -## Definitions - -UID -: A non-empty, opaque, system-generated value guaranteed to be unique in time and space; intended to distinguish between historical occurrences of similar entities. - -Name -: A non-empty string guaranteed to be unique within a given scope at a particular time; used in resource URLs; provided by clients at creation time and encouraged to be human friendly; intended to facilitate creation idempotence and space-uniqueness of singleton objects, distinguish distinct entities, and reference particular entities across operations. - -[rfc1035](http://www.ietf.org/rfc/rfc1035.txt)/[rfc1123](http://www.ietf.org/rfc/rfc1123.txt) label (DNS_LABEL) -: An alphanumeric (a-z, and 0-9) string, with a maximum length of 63 characters, with the '-' character allowed anywhere except the first or last character, suitable for use as a hostname or segment in a domain name - -[rfc1035](http://www.ietf.org/rfc/rfc1035.txt)/[rfc1123](http://www.ietf.org/rfc/rfc1123.txt) subdomain (DNS_SUBDOMAIN) -: One or more lowercase rfc1035/rfc1123 labels separated by '.' with a maximum length of 253 characters - -[rfc4122](http://www.ietf.org/rfc/rfc4122.txt) universally unique identifier (UUID) -: A 128 bit generated value that is extremely unlikely to collide across time and space and requires no central coordination - -[rfc6335](https://tools.ietf.org/rfc/rfc6335.txt) port name (IANA_SVC_NAME) -: An alphanumeric (a-z, and 0-9) string, with a maximum length of 15 characters, with the '-' character allowed anywhere except the first or the last character or adjacent to another '-' character, it must contain at least a (a-z) character - -## Objectives for names and UIDs - -1. Uniquely identify (via a UID) an object across space and time - -2. Uniquely name (via a name) an object across space - -3. Provide human-friendly names in API operations and/or configuration files - -4. Allow idempotent creation of API resources (#148) and enforcement of space-uniqueness of singleton objects - -5. Allow DNS names to be automatically generated for some objects - - -## General design - -1. When an object is created via an API, a Name string (a DNS_SUBDOMAIN) must be specified. Name must be non-empty and unique within the apiserver. This enables idempotent and space-unique creation operations. Parts of the system (e.g. replication controller) may join strings (e.g. a base name and a random suffix) to create a unique Name. For situations where generating a name is impractical, some or all objects may support a param to auto-generate a name. Generating random names will defeat idempotency. - * Examples: "guestbook.user", "backend-x4eb1" - -2. When an object is created via an API, a Namespace string (a DNS_SUBDOMAIN? format TBD via #1114) may be specified. Depending on the API receiver, namespaces might be validated (e.g. apiserver might ensure that the namespace actually exists). If a namespace is not specified, one will be assigned by the API receiver. This assignment policy might vary across API receivers (e.g. apiserver might have a default, kubelet might generate something semi-random). - * Example: "api.k8s.example.com" - -3. Upon acceptance of an object via an API, the object is assigned a UID (a UUID). UID must be non-empty and unique across space and time. - * Example: "01234567-89ab-cdef-0123-456789abcdef" - - -## Case study: Scheduling a pod - -Pods can be placed onto a particular node in a number of ways. This case -study demonstrates how the above design can be applied to satisfy the -objectives. - -### A pod scheduled by a user through the apiserver - -1. A user submits a pod with Namespace="" and Name="guestbook" to the apiserver. - -2. The apiserver validates the input. - 1. A default Namespace is assigned. - 2. The pod name must be space-unique within the Namespace. - 3. Each container within the pod has a name which must be space-unique within the pod. - -3. The pod is accepted. - 1. A new UID is assigned. - -4. The pod is bound to a node. - 1. The kubelet on the node is passed the pod's UID, Namespace, and Name. - -5. Kubelet validates the input. - -6. Kubelet runs the pod. - 1. Each container is started up with enough metadata to distinguish the pod from whence it came. - 2. Each attempt to run a container is assigned a UID (a string) that is unique across time. - * This may correspond to Docker's container ID. - -### A pod placed by a config file on the node - -1. A config file is stored on the node, containing a pod with UID="", Namespace="", and Name="cadvisor". - -2. Kubelet validates the input. - 1. Since UID is not provided, kubelet generates one. - 2. Since Namespace is not provided, kubelet generates one. - 1. The generated namespace should be deterministic and cluster-unique for the source, such as a hash of the hostname and file path. - * E.g. Namespace="file-f4231812554558a718a01ca942782d81" - -3. Kubelet runs the pod. - 1. Each container is started up with enough metadata to distinguish the pod from whence it came. - 2. Each attempt to run a container is assigned a UID (a string) that is unique across time. - 1. This may correspond to Docker's container ID. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/identifiers.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/namespaces.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/namespaces.md deleted file mode 100644 index 596f6f4389e6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/namespaces.md +++ /dev/null @@ -1,373 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/namespaces.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Namespaces - -## Abstract - -A Namespace is a mechanism to partition resources created by users into -a logically named group. - -## Motivation - -A single cluster should be able to satisfy the needs of multiple user communities. - -Each user community wants to be able to work in isolation from other communities. - -Each user community has its own: - -1. resources (pods, services, replication controllers, etc.) -2. policies (who can or cannot perform actions in their community) -3. constraints (this community is allowed this much quota, etc.) - -A cluster operator may create a Namespace for each unique user community. - -The Namespace provides a unique scope for: - -1. named resources (to avoid basic naming collisions) -2. delegated management authority to trusted users -3. ability to limit community resource consumption - -## Use cases - -1. As a cluster operator, I want to support multiple user communities on a single cluster. -2. As a cluster operator, I want to delegate authority to partitions of the cluster to trusted users - in those communities. -3. As a cluster operator, I want to limit the amount of resources each community can consume in order - to limit the impact to other communities using the cluster. -4. As a cluster user, I want to interact with resources that are pertinent to my user community in - isolation of what other user communities are doing on the cluster. - -## Design - -### Data Model - -A *Namespace* defines a logically named group for multiple *Kind*s of resources. - -```go -type Namespace struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` - - Spec NamespaceSpec `json:"spec,omitempty"` - Status NamespaceStatus `json:"status,omitempty"` -} -``` - -A *Namespace* name is a DNS compatible label. - -A *Namespace* must exist prior to associating content with it. - -A *Namespace* must not be deleted if there is content associated with it. - -To associate a resource with a *Namespace* the following conditions must be satisfied: - -1. The resource's *Kind* must be registered as having *RESTScopeNamespace* with the server -2. The resource's *TypeMeta.Namespace* field must have a value that references an existing *Namespace* - -The *Name* of a resource associated with a *Namespace* is unique to that *Kind* in that *Namespace*. - -It is intended to be used in resource URLs; provided by clients at creation time, and encouraged to be -human friendly; intended to facilitate idempotent creation, space-uniqueness of singleton objects, -distinguish distinct entities, and reference particular entities across operations. - -### Authorization - -A *Namespace* provides an authorization scope for accessing content associated with the *Namespace*. - -See [Authorization plugins](../admin/authorization.md) - -### Limit Resource Consumption - -A *Namespace* provides a scope to limit resource consumption. - -A *LimitRange* defines min/max constraints on the amount of resources a single entity can consume in -a *Namespace*. - -See [Admission control: Limit Range](admission_control_limit_range.md) - -A *ResourceQuota* tracks aggregate usage of resources in the *Namespace* and allows cluster operators -to define *Hard* resource usage limits that a *Namespace* may consume. - -See [Admission control: Resource Quota](admission_control_resource_quota.md) - -### Finalizers - -Upon creation of a *Namespace*, the creator may provide a list of *Finalizer* objects. - -```go -type FinalizerName string - -// These are internal finalizers to Kubernetes, must be qualified name unless defined here -const ( - FinalizerKubernetes FinalizerName = "kubernetes" -) - -// NamespaceSpec describes the attributes on a Namespace -type NamespaceSpec struct { - // Finalizers is an opaque list of values that must be empty to permanently remove object from storage - Finalizers []FinalizerName -} -``` - -A *FinalizerName* is a qualified name. - -The API Server enforces that a *Namespace* can only be deleted from storage if and only if -it's *Namespace.Spec.Finalizers* is empty. - -A *finalize* operation is the only mechanism to modify the *Namespace.Spec.Finalizers* field post creation. - -Each *Namespace* created has *kubernetes* as an item in its list of initial *Namespace.Spec.Finalizers* -set by default. - -### Phases - -A *Namespace* may exist in the following phases. - -```go -type NamespacePhase string -const( - NamespaceActive NamespacePhase = "Active" - NamespaceTerminating NamespaceTerminating = "Terminating" -) - -type NamespaceStatus struct { - ... - Phase NamespacePhase -} -``` - -A *Namespace* is in the **Active** phase if it does not have a *ObjectMeta.DeletionTimestamp*. - -A *Namespace* is in the **Terminating** phase if it has a *ObjectMeta.DeletionTimestamp*. - -**Active** - -Upon creation, a *Namespace* goes in the *Active* phase. This means that content may be associated with -a namespace, and all normal interactions with the namespace are allowed to occur in the cluster. - -If a DELETE request occurs for a *Namespace*, the *Namespace.ObjectMeta.DeletionTimestamp* is set -to the current server time. A *namespace controller* observes the change, and sets the *Namespace.Status.Phase* -to *Terminating*. - -**Terminating** - -A *namespace controller* watches for *Namespace* objects that have a *Namespace.ObjectMeta.DeletionTimestamp* -value set in order to know when to initiate graceful termination of the *Namespace* associated content that -are known to the cluster. - -The *namespace controller* enumerates each known resource type in that namespace and deletes it one by one. - -Admission control blocks creation of new resources in that namespace in order to prevent a race-condition -where the controller could believe all of a given resource type had been deleted from the namespace, -when in fact some other rogue client agent had created new objects. Using admission control in this -scenario allows each of registry implementations for the individual objects to not need to take into account Namespace life-cycle. - -Once all objects known to the *namespace controller* have been deleted, the *namespace controller* -executes a *finalize* operation on the namespace that removes the *kubernetes* value from -the *Namespace.Spec.Finalizers* list. - -If the *namespace controller* sees a *Namespace* whose *ObjectMeta.DeletionTimestamp* is set, and -whose *Namespace.Spec.Finalizers* list is empty, it will signal the server to permanently remove -the *Namespace* from storage by sending a final DELETE action to the API server. - -### REST API - -To interact with the Namespace API: - -| Action | HTTP Verb | Path | Description | -| ------ | --------- | ---- | ----------- | -| CREATE | POST | /api/{version}/namespaces | Create a namespace | -| LIST | GET | /api/{version}/namespaces | List all namespaces | -| UPDATE | PUT | /api/{version}/namespaces/{namespace} | Update namespace {namespace} | -| DELETE | DELETE | /api/{version}/namespaces/{namespace} | Delete namespace {namespace} | -| FINALIZE | POST | /api/{version}/namespaces/{namespace}/finalize | Finalize namespace {namespace} | -| WATCH | GET | /api/{version}/watch/namespaces | Watch all namespaces | - -This specification reserves the name *finalize* as a sub-resource to namespace. - -As a consequence, it is invalid to have a *resourceType* managed by a namespace whose kind is *finalize*. - -To interact with content associated with a Namespace: - -| Action | HTTP Verb | Path | Description | -| ---- | ---- | ---- | ---- | -| CREATE | POST | /api/{version}/namespaces/{namespace}/{resourceType}/ | Create instance of {resourceType} in namespace {namespace} | -| GET | GET | /api/{version}/namespaces/{namespace}/{resourceType}/{name} | Get instance of {resourceType} in namespace {namespace} with {name} | -| UPDATE | PUT | /api/{version}/namespaces/{namespace}/{resourceType}/{name} | Update instance of {resourceType} in namespace {namespace} with {name} | -| DELETE | DELETE | /api/{version}/namespaces/{namespace}/{resourceType}/{name} | Delete instance of {resourceType} in namespace {namespace} with {name} | -| LIST | GET | /api/{version}/namespaces/{namespace}/{resourceType} | List instances of {resourceType} in namespace {namespace} | -| WATCH | GET | /api/{version}/watch/namespaces/{namespace}/{resourceType} | Watch for changes to a {resourceType} in namespace {namespace} | -| WATCH | GET | /api/{version}/watch/{resourceType} | Watch for changes to a {resourceType} across all namespaces | -| LIST | GET | /api/{version}/list/{resourceType} | List instances of {resourceType} across all namespaces | - -The API server verifies the *Namespace* on resource creation matches the *{namespace}* on the path. - -The API server will associate a resource with a *Namespace* if not populated by the end-user based on the *Namespace* context -of the incoming request. If the *Namespace* of the resource being created, or updated does not match the *Namespace* on the request, -then the API server will reject the request. - -### Storage - -A namespace provides a unique identifier space and therefore must be in the storage path of a resource. - -In etcd, we want to continue to still support efficient WATCH across namespaces. - -Resources that persist content in etcd will have storage paths as follows: - -/{k8s_storage_prefix}/{resourceType}/{resource.Namespace}/{resource.Name} - -This enables consumers to WATCH /registry/{resourceType} for changes across namespace of a particular {resourceType}. - -### Kubelet - -The kubelet will register pod's it sources from a file or http source with a namespace associated with the -*cluster-id* - -### Example: OpenShift Origin managing a Kubernetes Namespace - -In this example, we demonstrate how the design allows for agents built on-top of -Kubernetes that manage their own set of resource types associated with a *Namespace* -to take part in Namespace termination. - -OpenShift creates a Namespace in Kubernetes - -```json -{ - "apiVersion":"v1", - "kind": "Namespace", - "metadata": { - "name": "development", - }, - "spec": { - "finalizers": ["openshift.com/origin", "kubernetes"], - }, - "status": { - "phase": "Active", - }, - "labels": { - "name": "development" - }, -} -``` - -OpenShift then goes and creates a set of resources (pods, services, etc) associated -with the "development" namespace. It also creates its own set of resources in its -own storage associated with the "development" namespace unknown to Kubernetes. - -User deletes the Namespace in Kubernetes, and Namespace now has following state: - -```json -{ - "apiVersion":"v1", - "kind": "Namespace", - "metadata": { - "name": "development", - "deletionTimestamp": "..." - }, - "spec": { - "finalizers": ["openshift.com/origin", "kubernetes"], - }, - "status": { - "phase": "Terminating", - }, - "labels": { - "name": "development" - }, -} -``` - -The Kubernetes *namespace controller* observes the namespace has a *deletionTimestamp* -and begins to terminate all of the content in the namespace that it knows about. Upon -success, it executes a *finalize* action that modifies the *Namespace* by -removing *kubernetes* from the list of finalizers: - -```json -{ - "apiVersion":"v1", - "kind": "Namespace", - "metadata": { - "name": "development", - "deletionTimestamp": "..." - }, - "spec": { - "finalizers": ["openshift.com/origin"], - }, - "status": { - "phase": "Terminating", - }, - "labels": { - "name": "development" - }, -} -``` - -OpenShift Origin has its own *namespace controller* that is observing cluster state, and -it observes the same namespace had a *deletionTimestamp* assigned to it. It too will go -and purge resources from its own storage that it manages associated with that namespace. -Upon completion, it executes a *finalize* action and removes the reference to "openshift.com/origin" -from the list of finalizers. - -This results in the following state: - -```json -{ - "apiVersion":"v1", - "kind": "Namespace", - "metadata": { - "name": "development", - "deletionTimestamp": "..." - }, - "spec": { - "finalizers": [], - }, - "status": { - "phase": "Terminating", - }, - "labels": { - "name": "development" - }, -} -``` - -At this point, the Kubernetes *namespace controller* in its sync loop will see that the namespace -has a deletion timestamp and that its list of finalizers is empty. As a result, it knows all -content associated from that namespace has been purged. It performs a final DELETE action -to remove that Namespace from the storage. - -At this point, all content associated with that Namespace, and the Namespace itself are gone. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/namespaces.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/networking.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/networking.md deleted file mode 100644 index dfe0f93e2990..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/networking.md +++ /dev/null @@ -1,214 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/networking.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Networking - -There are 4 distinct networking problems to solve: - -1. Highly-coupled container-to-container communications -2. Pod-to-Pod communications -3. Pod-to-Service communications -4. External-to-internal communications - -## Model and motivation - -Kubernetes deviates from the default Docker networking model (though as of -Docker 1.8 their network plugins are getting closer). The goal is for each pod -to have an IP in a flat shared networking namespace that has full communication -with other physical computers and containers across the network. IP-per-pod -creates a clean, backward-compatible model where pods can be treated much like -VMs or physical hosts from the perspectives of port allocation, networking, -naming, service discovery, load balancing, application configuration, and -migration. - -Dynamic port allocation, on the other hand, requires supporting both static -ports (e.g., for externally accessible services) and dynamically allocated -ports, requires partitioning centrally allocated and locally acquired dynamic -ports, complicates scheduling (since ports are a scarce resource), is -inconvenient for users, complicates application configuration, is plagued by -port conflicts and reuse and exhaustion, requires non-standard approaches to -naming (e.g. consul or etcd rather than DNS), requires proxies and/or -redirection for programs using standard naming/addressing mechanisms (e.g. web -browsers), requires watching and cache invalidation for address/port changes -for instances in addition to watching group membership changes, and obstructs -container/pod migration (e.g. using CRIU). NAT introduces additional complexity -by fragmenting the addressing space, which breaks self-registration mechanisms, -among other problems. - -## Container to container - -All containers within a pod behave as if they are on the same host with regard -to networking. They can all reach each other’s ports on localhost. This offers -simplicity (static ports know a priori), security (ports bound to localhost -are visible within the pod but never outside it), and performance. This also -reduces friction for applications moving from the world of uncontainerized apps -on physical or virtual hosts. People running application stacks together on -the same host have already figured out how to make ports not conflict and have -arranged for clients to find them. - -The approach does reduce isolation between containers within a pod — -ports could conflict, and there can be no container-private ports, but these -seem to be relatively minor issues with plausible future workarounds. Besides, -the premise of pods is that containers within a pod share some resources -(volumes, cpu, ram, etc.) and therefore expect and tolerate reduced isolation. -Additionally, the user can control what containers belong to the same pod -whereas, in general, they don't control what pods land together on a host. - -## Pod to pod - -Because every pod gets a "real" (not machine-private) IP address, pods can -communicate without proxies or translations. The pod can use well-known port -numbers and can avoid the use of higher-level service discovery systems like -DNS-SD, Consul, or Etcd. - -When any container calls ioctl(SIOCGIFADDR) (get the address of an interface), -it sees the same IP that any peer container would see them coming from — -each pod has its own IP address that other pods can know. By making IP addresses -and ports the same both inside and outside the pods, we create a NAT-less, flat -address space. Running "ip addr show" should work as expected. This would enable -all existing naming/discovery mechanisms to work out of the box, including -self-registration mechanisms and applications that distribute IP addresses. We -should be optimizing for inter-pod network communication. Within a pod, -containers are more likely to use communication through volumes (e.g., tmpfs) or -IPC. - -This is different from the standard Docker model. In that mode, each container -gets an IP in the 172-dot space and would only see that 172-dot address from -SIOCGIFADDR. If these containers connect to another container the peer would see -the connect coming from a different IP than the container itself knows. In short -— you can never self-register anything from a container, because a -container can not be reached on its private IP. - -An alternative we considered was an additional layer of addressing: pod-centric -IP per container. Each container would have its own local IP address, visible -only within that pod. This would perhaps make it easier for containerized -applications to move from physical/virtual hosts to pods, but would be more -complex to implement (e.g., requiring a bridge per pod, split-horizon/VP DNS) -and to reason about, due to the additional layer of address translation, and -would break self-registration and IP distribution mechanisms. - -Like Docker, ports can still be published to the host node's interface(s), but -the need for this is radically diminished. - -## Implementation - -For the Google Compute Engine cluster configuration scripts, we use [advanced -routing rules](https://developers.google.com/compute/docs/networking#routing) -and ip-forwarding-enabled VMs so that each VM has an extra 256 IP addresses that -get routed to it. This is in addition to the 'main' IP address assigned to the -VM that is NAT-ed for Internet access. The container bridge (called `cbr0` to -differentiate it from `docker0`) is set up outside of Docker proper. - -Example of GCE's advanced routing rules: - -```sh -gcloud compute routes add "${MINION_NAMES[$i]}" \ - --project "${PROJECT}" \ - --destination-range "${MINION_IP_RANGES[$i]}" \ - --network "${NETWORK}" \ - --next-hop-instance "${MINION_NAMES[$i]}" \ - --next-hop-instance-zone "${ZONE}" & -``` - -GCE itself does not know anything about these IPs, though. This means that when -a pod tries to egress beyond GCE's project the packets must be SNAT'ed -(masqueraded) to the VM's IP, which GCE recognizes and allows. - -### Other implementations - -With the primary aim of providing IP-per-pod-model, other implementations exist -to serve the purpose outside of GCE. - - [OpenVSwitch with GRE/VxLAN](../admin/ovs-networking.md) - - [Flannel](https://github.com/coreos/flannel#flannel) - - [L2 networks](http://blog.oddbit.com/2014/08/11/four-ways-to-connect-a-docker/) - ("With Linux Bridge devices" section) - - [Weave](https://github.com/zettio/weave) is yet another way to build an - overlay network, primarily aiming at Docker integration. - - [Calico](https://github.com/Metaswitch/calico) uses BGP to enable real - container IPs. - -## Pod to service - -The [service](../user-guide/services.md) abstraction provides a way to group pods under a -common access policy (e.g. load-balanced). The implementation of this creates a -virtual IP which clients can access and which is transparently proxied to the -pods in a Service. Each node runs a kube-proxy process which programs -`iptables` rules to trap access to service IPs and redirect them to the correct -backends. This provides a highly-available load-balancing solution with low -performance overhead by balancing client traffic from a node on that same node. - -## External to internal - -So far the discussion has been about how to access a pod or service from within -the cluster. Accessing a pod from outside the cluster is a bit more tricky. We -want to offer highly-available, high-performance load balancing to target -Kubernetes Services. Most public cloud providers are simply not flexible enough -yet. - -The way this is generally implemented is to set up external load balancers (e.g. -GCE's ForwardingRules or AWS's ELB) which target all nodes in a cluster. When -traffic arrives at a node it is recognized as being part of a particular Service -and routed to an appropriate backend Pod. This does mean that some traffic will -get double-bounced on the network. Once cloud providers have better offerings -we can take advantage of those. - -## Challenges and future work - -### Docker API - -Right now, docker inspect doesn't show the networking configuration of the -containers, since they derive it from another container. That information should -be exposed somehow. - -### External IP assignment - -We want to be able to assign IP addresses externally from Docker -[#6743](https://github.com/dotcloud/docker/issues/6743) so that we don't need -to statically allocate fixed-size IP ranges to each node, so that IP addresses -can be made stable across pod infra container restarts -([#2801](https://github.com/dotcloud/docker/issues/2801)), and to facilitate -pod migration. Right now, if the pod infra container dies, all the user -containers must be stopped and restarted because the netns of the pod infra -container will change on restart, and any subsequent user container restart -will join that new netns, thereby not being able to see its peers. -Additionally, a change in IP address would encounter DNS caching/TTL problems. -External IP assignment would also simplify DNS support (see below). - -### IPv6 - -IPv6 would be a nice option, also, but we can't depend on it yet. Docker support is in progress: [Docker issue #2974](https://github.com/dotcloud/docker/issues/2974), [Docker issue #6923](https://github.com/dotcloud/docker/issues/6923), [Docker issue #6975](https://github.com/dotcloud/docker/issues/6975). Additionally, direct ipv6 assignment to instances doesn't appear to be supported by major cloud providers (e.g., AWS EC2, GCE) yet. We'd happily take pull requests from people running Kubernetes on bare metal, though. :-) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/networking.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/persistent-storage.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/persistent-storage.md deleted file mode 100644 index bb2008118a99..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/persistent-storage.md +++ /dev/null @@ -1,242 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/persistent-storage.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Persistent Storage - -This document proposes a model for managing persistent, cluster-scoped storage for applications requiring long lived data. - -### tl;dr - -Two new API kinds: - -A `PersistentVolume` (PV) is a storage resource provisioned by an administrator. It is analogous to a node. See [Persistent Volume Guide](../user-guide/persistent-volumes/) for how to use it. - -A `PersistentVolumeClaim` (PVC) is a user's request for a persistent volume to use in a pod. It is analogous to a pod. - -One new system component: - -`PersistentVolumeClaimBinder` is a singleton running in master that watches all PersistentVolumeClaims in the system and binds them to the closest matching available PersistentVolume. The volume manager watches the API for newly created volumes to manage. - -One new volume: - -`PersistentVolumeClaimVolumeSource` references the user's PVC in the same namespace. This volume finds the bound PV and mounts that volume for the pod. A `PersistentVolumeClaimVolumeSource` is, essentially, a wrapper around another type of volume that is owned by someone else (the system). - -Kubernetes makes no guarantees at runtime that the underlying storage exists or is available. High availability is left to the storage provider. - -### Goals - -* Allow administrators to describe available storage -* Allow pod authors to discover and request persistent volumes to use with pods -* Enforce security through access control lists and securing storage to the same namespace as the pod volume -* Enforce quotas through admission control -* Enforce scheduler rules by resource counting -* Ensure developers can rely on storage being available without being closely bound to a particular disk, server, network, or storage device. - - -#### Describe available storage - -Cluster administrators use the API to manage *PersistentVolumes*. A custom store `NewPersistentVolumeOrderedIndex` will index volumes by access modes and sort by storage capacity. The `PersistentVolumeClaimBinder` watches for new claims for storage and binds them to an available volume by matching the volume's characteristics (AccessModes and storage size) to the user's request. - -PVs are system objects and, thus, have no namespace. - -Many means of dynamic provisioning will be eventually be implemented for various storage types. - - -##### PersistentVolume API - -| Action | HTTP Verb | Path | Description | -| ---- | ---- | ---- | ---- | -| CREATE | POST | /api/{version}/persistentvolumes/ | Create instance of PersistentVolume | -| GET | GET | /api/{version}persistentvolumes/{name} | Get instance of PersistentVolume with {name} | -| UPDATE | PUT | /api/{version}/persistentvolumes/{name} | Update instance of PersistentVolume with {name} | -| DELETE | DELETE | /api/{version}/persistentvolumes/{name} | Delete instance of PersistentVolume with {name} | -| LIST | GET | /api/{version}/persistentvolumes | List instances of PersistentVolume | -| WATCH | GET | /api/{version}/watch/persistentvolumes | Watch for changes to a PersistentVolume | - - -#### Request Storage - -Kubernetes users request persistent storage for their pod by creating a ```PersistentVolumeClaim```. Their request for storage is described by their requirements for resources and mount capabilities. - -Requests for volumes are bound to available volumes by the volume manager, if a suitable match is found. Requests for resources can go unfulfilled. - -Users attach their claim to their pod using a new ```PersistentVolumeClaimVolumeSource``` volume source. - - -##### PersistentVolumeClaim API - - -| Action | HTTP Verb | Path | Description | -| ---- | ---- | ---- | ---- | -| CREATE | POST | /api/{version}/namespaces/{ns}/persistentvolumeclaims/ | Create instance of PersistentVolumeClaim in namespace {ns} | -| GET | GET | /api/{version}/namespaces/{ns}/persistentvolumeclaims/{name} | Get instance of PersistentVolumeClaim in namespace {ns} with {name} | -| UPDATE | PUT | /api/{version}/namespaces/{ns}/persistentvolumeclaims/{name} | Update instance of PersistentVolumeClaim in namespace {ns} with {name} | -| DELETE | DELETE | /api/{version}/namespaces/{ns}/persistentvolumeclaims/{name} | Delete instance of PersistentVolumeClaim in namespace {ns} with {name} | -| LIST | GET | /api/{version}/namespaces/{ns}/persistentvolumeclaims | List instances of PersistentVolumeClaim in namespace {ns} | -| WATCH | GET | /api/{version}/watch/namespaces/{ns}/persistentvolumeclaims | Watch for changes to PersistentVolumeClaim in namespace {ns} | - - - -#### Scheduling constraints - -Scheduling constraints are to be handled similar to pod resource constraints. Pods will need to be annotated or decorated with the number of resources it requires on a node. Similarly, a node will need to list how many it has used or available. - -TBD - - -#### Events - -The implementation of persistent storage will not require events to communicate to the user the state of their claim. The CLI for bound claims contains a reference to the backing persistent volume. This is always present in the API and CLI, making an event to communicate the same unnecessary. - -Events that communicate the state of a mounted volume are left to the volume plugins. - - -### Example - -#### Admin provisions storage - -An administrator provisions storage by posting PVs to the API. Various way to automate this task can be scripted. Dynamic provisioning is a future feature that can maintain levels of PVs. - -```yaml -POST: - -kind: PersistentVolume -apiVersion: v1 -metadata: - name: pv0001 -spec: - capacity: - storage: 10 - persistentDisk: - pdName: "abc123" - fsType: "ext4" -``` - -```console -$ kubectl get pv - -NAME LABELS CAPACITY ACCESSMODES STATUS CLAIM REASON -pv0001 map[] 10737418240 RWO Pending -``` - -#### Users request storage - -A user requests storage by posting a PVC to the API. Their request contains the AccessModes they wish their volume to have and the minimum size needed. - -The user must be within a namespace to create PVCs. - -```yaml -POST: - -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: myclaim-1 -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 3 -``` - -```console -$ kubectl get pvc - -NAME LABELS STATUS VOLUME -myclaim-1 map[] pending -``` - - -#### Matching and binding - - The ```PersistentVolumeClaimBinder``` attempts to find an available volume that most closely matches the user's request. If one exists, they are bound by putting a reference on the PV to the PVC. Requests can go unfulfilled if a suitable match is not found. - -```console -$ kubectl get pv - -NAME LABELS CAPACITY ACCESSMODES STATUS CLAIM REASON -pv0001 map[] 10737418240 RWO Bound myclaim-1 / f4b3d283-c0ef-11e4-8be4-80e6500a981e - - -kubectl get pvc - -NAME LABELS STATUS VOLUME -myclaim-1 map[] Bound b16e91d6-c0ef-11e4-8be4-80e6500a981e -``` - -#### Claim usage - -The claim holder can use their claim as a volume. The ```PersistentVolumeClaimVolumeSource``` knows to fetch the PV backing the claim and mount its volume for a pod. - -The claim holder owns the claim and its data for as long as the claim exists. The pod using the claim can be deleted, but the claim remains in the user's namespace. It can be used again and again by many pods. - -```yaml -POST: - -kind: Pod -apiVersion: v1 -metadata: - name: mypod -spec: - containers: - - image: nginx - name: myfrontend - volumeMounts: - - mountPath: "/var/www/html" - name: mypd - volumes: - - name: mypd - source: - persistentVolumeClaim: - accessMode: ReadWriteOnce - claimRef: - name: myclaim-1 -``` - -#### Releasing a claim and Recycling a volume - -When a claim holder is finished with their data, they can delete their claim. - -```console -$ kubectl delete pvc myclaim-1 -``` - -The ```PersistentVolumeClaimBinder``` will reconcile this by removing the claim reference from the PV and change the PVs status to 'Released'. - -Admins can script the recycling of released volumes. Future dynamic provisioners will understand how a volume should be recycled. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/persistent-storage.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/principles.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/principles.md deleted file mode 100644 index 9791858de39a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/principles.md +++ /dev/null @@ -1,93 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/principles.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Design Principles - -Principles to follow when extending Kubernetes. - -## API - -See also the [API conventions](../devel/api-conventions.md). - -* All APIs should be declarative. -* API objects should be complementary and composable, not opaque wrappers. -* The control plane should be transparent -- there are no hidden internal APIs. -* The cost of API operations should be proportional to the number of objects intentionally operated upon. Therefore, common filtered lookups must be indexed. Beware of patterns of multiple API calls that would incur quadratic behavior. -* Object status must be 100% reconstructable by observation. Any history kept must be just an optimization and not required for correct operation. -* Cluster-wide invariants are difficult to enforce correctly. Try not to add them. If you must have them, don't enforce them atomically in master components, that is contention-prone and doesn't provide a recovery path in the case of a bug allowing the invariant to be violated. Instead, provide a series of checks to reduce the probability of a violation, and make every component involved able to recover from an invariant violation. -* Low-level APIs should be designed for control by higher-level systems. Higher-level APIs should be intent-oriented (think SLOs) rather than implementation-oriented (think control knobs). - -## Control logic - -* Functionality must be *level-based*, meaning the system must operate correctly given the desired state and the current/observed state, regardless of how many intermediate state updates may have been missed. Edge-triggered behavior must be just an optimization. -* Assume an open world: continually verify assumptions and gracefully adapt to external events and/or actors. Example: we allow users to kill pods under control of a replication controller; it just replaces them. -* Do not define comprehensive state machines for objects with behaviors associated with state transitions and/or "assumed" states that cannot be ascertained by observation. -* Don't assume a component's decisions will not be overridden or rejected, nor for the component to always understand why. For example, etcd may reject writes. Kubelet may reject pods. The scheduler may not be able to schedule pods. Retry, but back off and/or make alternative decisions. -* Components should be self-healing. For example, if you must keep some state (e.g., cache) the content needs to be periodically refreshed, so that if an item does get erroneously stored or a deletion event is missed etc, it will be soon fixed, ideally on timescales that are shorter than what will attract attention from humans. -* Component behavior should degrade gracefully. Prioritize actions so that the most important activities can continue to function even when overloaded and/or in states of partial failure. - -## Architecture - -* Only the apiserver should communicate with etcd/store, and not other components (scheduler, kubelet, etc.). -* Compromising a single node shouldn't compromise the cluster. -* Components should continue to do what they were last told in the absence of new instructions (e.g., due to network partition or component outage). -* All components should keep all relevant state in memory all the time. The apiserver should write through to etcd/store, other components should write through to the apiserver, and they should watch for updates made by other clients. -* Watch is preferred over polling. - -## Extensibility - -TODO: pluggability - -## Bootstrapping - -* [Self-hosting](https://k8s.io/kubernetes/issues/246) of all components is a goal. -* Minimize the number of dependencies, particularly those required for steady-state operation. -* Stratify the dependencies that remain via principled layering. -* Break any circular dependencies by converting hard dependencies to soft dependencies. - * Also accept that data from other components from another source, such as local files, which can then be manually populated at bootstrap time and then continuously updated once those other components are available. - * State should be rediscoverable and/or reconstructable. - * Make it easy to run temporary, bootstrap instances of all components in order to create the runtime state needed to run the components in the steady state; use a lock (master election for distributed components, file lock for local components like Kubelet) to coordinate handoff. We call this technique "pivoting". - * Have a solution to restart dead components. For distributed components, replication works well. For local components such as Kubelet, a process manager or even a simple shell loop works. - -## Availability - -TODO - -## General principles - -* [Eric Raymond's 17 UNIX rules](https://en.wikipedia.org/wiki/Unix_philosophy#Eric_Raymond.E2.80.99s_17_Unix_Rules) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/principles.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/resources.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/resources.md deleted file mode 100644 index 272f036c9054..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/resources.md +++ /dev/null @@ -1,268 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/resources.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -**Note: this is a design doc, which describes features that have not been completely implemented. -User documentation of the current state is [here](../user-guide/compute-resources.md). The tracking issue for -implementation of this model is -[#168](https://k8s.io/kubernetes/issues/168). Currently, only memory and -cpu limits on containers (not pods) are supported. "memory" is in bytes and "cpu" is in -milli-cores.** - -# The Kubernetes resource model - -To do good pod placement, Kubernetes needs to know how big pods are, as well as the sizes of the nodes onto which they are being placed. The definition of "how big" is given by the Kubernetes resource model — the subject of this document. - -The resource model aims to be: -* simple, for common cases; -* extensible, to accommodate future growth; -* regular, with few special cases; and -* precise, to avoid misunderstandings and promote pod portability. - -## The resource model - -A Kubernetes _resource_ is something that can be requested by, allocated to, or consumed by a pod or container. Examples include memory (RAM), CPU, disk-time, and network bandwidth. - -Once resources on a node have been allocated to one pod, they should not be allocated to another until that pod is removed or exits. This means that Kubernetes schedulers should ensure that the sum of the resources allocated (requested and granted) to its pods never exceeds the usable capacity of the node. Testing whether a pod will fit on a node is called _feasibility checking_. - -Note that the resource model currently prohibits over-committing resources; we will want to relax that restriction later. - -### Resource types - -All resources have a _type_ that is identified by their _typename_ (a string, e.g., "memory"). Several resource types are predefined by Kubernetes (a full list is below), although only two will be supported at first: CPU and memory. Users and system administrators can define their own resource types if they wish (e.g., Hadoop slots). - -A fully-qualified resource typename is constructed from a DNS-style _subdomain_, followed by a slash `/`, followed by a name. -* The subdomain must conform to [RFC 1123](http://www.ietf.org/rfc/rfc1123.txt) (e.g., `kubernetes.io`, `example.com`). -* The name must be not more than 63 characters, consisting of upper- or lower-case alphanumeric characters, with the `-`, `_`, and `.` characters allowed anywhere except the first or last character. -* As a shorthand, any resource typename that does not start with a subdomain and a slash will automatically be prefixed with the built-in Kubernetes _namespace_, `kubernetes.io/` in order to fully-qualify it. This namespace is reserved for code in the open source Kubernetes repository; as a result, all user typenames MUST be fully qualified, and cannot be created in this namespace. - -Some example typenames include `memory` (which will be fully-qualified as `kubernetes.io/memory`), and `example.com/Shiny_New-Resource.Type`. - -For future reference, note that some resources, such as CPU and network bandwidth, are _compressible_, which means that their usage can potentially be throttled in a relatively benign manner. All other resources are _incompressible_, which means that any attempt to throttle them is likely to cause grief. This distinction will be important if a Kubernetes implementation supports over-committing of resources. - -### Resource quantities - -Initially, all Kubernetes resource types are _quantitative_, and have an associated _unit_ for quantities of the associated resource (e.g., bytes for memory, bytes per seconds for bandwidth, instances for software licences). The units will always be a resource type's natural base units (e.g., bytes, not MB), to avoid confusion between binary and decimal multipliers and the underlying unit multiplier (e.g., is memory measured in MiB, MB, or GB?). - -Resource quantities can be added and subtracted: for example, a node has a fixed quantity of each resource type that can be allocated to pods/containers; once such an allocation has been made, the allocated resources cannot be made available to other pods/containers without over-committing the resources. - -To make life easier for people, quantities can be represented externally as unadorned integers, or as fixed-point integers with one of these SI suffices (E, P, T, G, M, K, m) or their power-of-two equivalents (Ei, Pi, Ti, Gi, Mi, Ki). For example, the following represent roughly the same value: 128974848, "129e6", "129M" , "123Mi". Small quantities can be represented directly as decimals (e.g., 0.3), or using milli-units (e.g., "300m"). - * "Externally" means in user interfaces, reports, graphs, and in JSON or YAML resource specifications that might be generated or read by people. - * Case is significant: "m" and "M" are not the same, so "k" is not a valid SI suffix. There are no power-of-two equivalents for SI suffixes that represent multipliers less than 1. - * These conventions only apply to resource quantities, not arbitrary values. - -Internally (i.e., everywhere else), Kubernetes will represent resource quantities as integers so it can avoid problems with rounding errors, and will not use strings to represent numeric values. To achieve this, quantities that naturally have fractional parts (e.g., CPU seconds/second) will be scaled to integral numbers of milli-units (e.g., milli-CPUs) as soon as they are read in. Internal APIs, data structures, and protobufs will use these scaled integer units. Raw measurement data such as usage may still need to be tracked and calculated using floating point values, but internally they should be rescaled to avoid some values being in milli-units and some not. - * Note that reading in a resource quantity and writing it out again may change the way its values are represented, and truncate precision (e.g., 1.0001 may become 1.000), so comparison and difference operations (e.g., by an updater) must be done on the internal representations. - * Avoiding milli-units in external representations has advantages for people who will use Kubernetes, but runs the risk of developers forgetting to rescale or accidentally using floating-point representations. That seems like the right choice. We will try to reduce the risk by providing libraries that automatically do the quantization for JSON/YAML inputs. - -### Resource specifications - -Both users and a number of system components, such as schedulers, (horizontal) auto-scalers, (vertical) auto-sizers, load balancers, and worker-pool managers need to reason about resource requirements of workloads, resource capacities of nodes, and resource usage. Kubernetes divides specifications of *desired state*, aka the Spec, and representations of *current state*, aka the Status. Resource requirements and total node capacity fall into the specification category, while resource usage, characterizations derived from usage (e.g., maximum usage, histograms), and other resource demand signals (e.g., CPU load) clearly fall into the status category and are discussed in the Appendix for now. - -Resource requirements for a container or pod should have the following form: - -```yaml -resourceRequirementSpec: [ - request: [ cpu: 2.5, memory: "40Mi" ], - limit: [ cpu: 4.0, memory: "99Mi" ], -] -``` - -Where: -* _request_ [optional]: the amount of resources being requested, or that were requested and have been allocated. Scheduler algorithms will use these quantities to test feasibility (whether a pod will fit onto a node). If a container (or pod) tries to use more resources than its _request_, any associated SLOs are voided — e.g., the program it is running may be throttled (compressible resource types), or the attempt may be denied. If _request_ is omitted for a container, it defaults to _limit_ if that is explicitly specified, otherwise to an implementation-defined value; this will always be 0 for a user-defined resource type. If _request_ is omitted for a pod, it defaults to the sum of the (explicit or implicit) _request_ values for the containers it encloses. - -* _limit_ [optional]: an upper bound or cap on the maximum amount of resources that will be made available to a container or pod; if a container or pod uses more resources than its _limit_, it may be terminated. The _limit_ defaults to "unbounded"; in practice, this probably means the capacity of an enclosing container, pod, or node, but may result in non-deterministic behavior, especially for memory. - -Total capacity for a node should have a similar structure: - -```yaml -resourceCapacitySpec: [ - total: [ cpu: 12, memory: "128Gi" ] -] -``` - -Where: -* _total_: the total allocatable resources of a node. Initially, the resources at a given scope will bound the resources of the sum of inner scopes. - -#### Notes - - * It is an error to specify the same resource type more than once in each list. - - * It is an error for the _request_ or _limit_ values for a pod to be less than the sum of the (explicit or defaulted) values for the containers it encloses. (We may relax this later.) - - * If multiple pods are running on the same node and attempting to use more resources than they have requested, the result is implementation-defined. For example: unallocated or unused resources might be spread equally across claimants, or the assignment might be weighted by the size of the original request, or as a function of limits, or priority, or the phase of the moon, perhaps modulated by the direction of the tide. Thus, although it's not mandatory to provide a _request_, it's probably a good idea. (Note that the _request_ could be filled in by an automated system that is observing actual usage and/or historical data.) - - * Internally, the Kubernetes master can decide the defaulting behavior and the kubelet implementation may expected an absolute specification. For example, if the master decided that "the default is unbounded" it would pass 2^64 to the kubelet. - - - -## Kubernetes-defined resource types - -The following resource types are predefined ("reserved") by Kubernetes in the `kubernetes.io` namespace, and so cannot be used for user-defined resources. Note that the syntax of all resource types in the resource spec is deliberately similar, but some resource types (e.g., CPU) may receive significantly more support than simply tracking quantities in the schedulers and/or the Kubelet. - -### Processor cycles - - * Name: `cpu` (or `kubernetes.io/cpu`) - * Units: Kubernetes Compute Unit seconds/second (i.e., CPU cores normalized to a canonical "Kubernetes CPU") - * Internal representation: milli-KCUs - * Compressible? yes - * Qualities: this is a placeholder for the kind of thing that may be supported in the future — see [#147](https://k8s.io/kubernetes/issues/147) - * [future] `schedulingLatency`: as per lmctfy - * [future] `cpuConversionFactor`: property of a node: the speed of a CPU core on the node's processor divided by the speed of the canonical Kubernetes CPU (a floating point value; default = 1.0). - -To reduce performance portability problems for pods, and to avoid worse-case provisioning behavior, the units of CPU will be normalized to a canonical "Kubernetes Compute Unit" (KCU, pronounced ˈko͝oko͞o), which will roughly be equivalent to a single CPU hyperthreaded core for some recent x86 processor. The normalization may be implementation-defined, although some reasonable defaults will be provided in the open-source Kubernetes code. - -Note that requesting 2 KCU won't guarantee that precisely 2 physical cores will be allocated — control of aspects like this will be handled by resource _qualities_ (a future feature). - - -### Memory - - * Name: `memory` (or `kubernetes.io/memory`) - * Units: bytes - * Compressible? no (at least initially) - -The precise meaning of what "memory" means is implementation dependent, but the basic idea is to rely on the underlying `memcg` mechanisms, support, and definitions. - -Note that most people will want to use power-of-two suffixes (Mi, Gi) for memory quantities -rather than decimal ones: "64MiB" rather than "64MB". - - -## Resource metadata - -A resource type may have an associated read-only ResourceType structure, that contains metadata about the type. For example: - -```yaml -resourceTypes: [ - "kubernetes.io/memory": [ - isCompressible: false, ... - ] - "kubernetes.io/cpu": [ - isCompressible: true, - internalScaleExponent: 3, ... - ] - "kubernetes.io/disk-space": [ ... ] -] -``` - -Kubernetes will provide ResourceType metadata for its predefined types. If no resource metadata can be found for a resource type, Kubernetes will assume that it is a quantified, incompressible resource that is not specified in milli-units, and has no default value. - -The defined properties are as follows: - -| field name | type | contents | -| ---------- | ---- | -------- | -| name | string, required | the typename, as a fully-qualified string (e.g., `kubernetes.io/cpu`) | -| internalScaleExponent | int, default=0 | external values are multiplied by 10 to this power for internal storage (e.g., 3 for milli-units) | -| units | string, required | format: `unit* [per unit+]` (e.g., `second`, `byte per second`). An empty unit field means "dimensionless". | -| isCompressible | bool, default=false | true if the resource type is compressible | -| defaultRequest | string, default=none | in the same format as a user-supplied value | -| _[future]_ quantization | number, default=1 | smallest granularity of allocation: requests may be rounded up to a multiple of this unit; implementation-defined unit (e.g., the page size for RAM). | - - -# Appendix: future extensions - -The following are planned future extensions to the resource model, included here to encourage comments. - -## Usage data - -Because resource usage and related metrics change continuously, need to be tracked over time (i.e., historically), can be characterized in a variety of ways, and are fairly voluminous, we will not include usage in core API objects, such as [Pods](../user-guide/pods.md) and Nodes, but will provide separate APIs for accessing and managing that data. See the Appendix for possible representations of usage data, but the representation we'll use is TBD. - -Singleton values for observed and predicted future usage will rapidly prove inadequate, so we will support the following structure for extended usage information: - -```yaml -resourceStatus: [ - usage: [ cpu: , memory: ], - maxusage: [ cpu: , memory: ], - predicted: [ cpu: , memory: ], -] -``` - -where a `` or `` structure looks like this: - -```yaml -{ - mean: # arithmetic mean - max: # minimum value - min: # maximum value - count: # number of data points - percentiles: [ # map from %iles to values - "10": <10th-percentile-value>, - "50": , - "99": <99th-percentile-value>, - "99.9": <99.9th-percentile-value>, - ... - ] -} -``` - -All parts of this structure are optional, although we strongly encourage including quantities for 50, 90, 95, 99, 99.5, and 99.9 percentiles. _[In practice, it will be important to include additional info such as the length of the time window over which the averages are calculated, the confidence level, and information-quality metrics such as the number of dropped or discarded data points.]_ -and predicted - -## Future resource types - -### _[future] Network bandwidth_ - - * Name: "network-bandwidth" (or `kubernetes.io/network-bandwidth`) - * Units: bytes per second - * Compressible? yes - -### _[future] Network operations_ - - * Name: "network-iops" (or `kubernetes.io/network-iops`) - * Units: operations (messages) per second - * Compressible? yes - -### _[future] Storage space_ - - * Name: "storage-space" (or `kubernetes.io/storage-space`) - * Units: bytes - * Compressible? no - -The amount of secondary storage space available to a container. The main target is local disk drives and SSDs, although this could also be used to qualify remotely-mounted volumes. Specifying whether a resource is a raw disk, an SSD, a disk array, or a file system fronting any of these, is left for future work. - -### _[future] Storage time_ - - * Name: storage-time (or `kubernetes.io/storage-time`) - * Units: seconds per second of disk time - * Internal representation: milli-units - * Compressible? yes - -This is the amount of time a container spends accessing disk, including actuator and transfer time. A standard disk drive provides 1.0 diskTime seconds per second. - -### _[future] Storage operations_ - - * Name: "storage-iops" (or `kubernetes.io/storage-iops`) - * Units: operations per second - * Compressible? yes - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/resources.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/secrets.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/secrets.md deleted file mode 100644 index d3d1226ec7ac..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/secrets.md +++ /dev/null @@ -1,613 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/secrets.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Abstract - -A proposal for the distribution of [secrets](../user-guide/secrets.md) (passwords, keys, etc) to the Kubelet and to -containers inside Kubernetes using a custom [volume](../user-guide/volumes.md#secrets) type. See the [secrets example](../user-guide/secrets/) for more information. - -## Motivation - -Secrets are needed in containers to access internal resources like the Kubernetes master or -external resources such as git repositories, databases, etc. Users may also want behaviors in the -kubelet that depend on secret data (credentials for image pull from a docker registry) associated -with pods. - -Goals of this design: - -1. Describe a secret resource -2. Define the various challenges attendant to managing secrets on the node -3. Define a mechanism for consuming secrets in containers without modification - -## Constraints and Assumptions - -* This design does not prescribe a method for storing secrets; storage of secrets should be - pluggable to accommodate different use-cases -* Encryption of secret data and node security are orthogonal concerns -* It is assumed that node and master are secure and that compromising their security could also - compromise secrets: - * If a node is compromised, the only secrets that could potentially be exposed should be the - secrets belonging to containers scheduled onto it - * If the master is compromised, all secrets in the cluster may be exposed -* Secret rotation is an orthogonal concern, but it should be facilitated by this proposal -* A user who can consume a secret in a container can know the value of the secret; secrets must - be provisioned judiciously - -## Use Cases - -1. As a user, I want to store secret artifacts for my applications and consume them securely in - containers, so that I can keep the configuration for my applications separate from the images - that use them: - 1. As a cluster operator, I want to allow a pod to access the Kubernetes master using a custom - `.kubeconfig` file, so that I can securely reach the master - 2. As a cluster operator, I want to allow a pod to access a Docker registry using credentials - from a `.dockercfg` file, so that containers can push images - 3. As a cluster operator, I want to allow a pod to access a git repository using SSH keys, - so that I can push and fetch to and from the repository -2. As a user, I want to allow containers to consume supplemental information about services such - as username and password which should be kept secret, so that I can share secrets about a - service amongst the containers in my application securely -3. As a user, I want to associate a pod with a `ServiceAccount` that consumes a secret and have - the kubelet implement some reserved behaviors based on the types of secrets the service account - consumes: - 1. Use credentials for a docker registry to pull the pod's docker image - 2. Present Kubernetes auth token to the pod or transparently decorate traffic between the pod - and master service -4. As a user, I want to be able to indicate that a secret expires and for that secret's value to - be rotated once it expires, so that the system can help me follow good practices - -### Use-Case: Configuration artifacts - -Many configuration files contain secrets intermixed with other configuration information. For -example, a user's application may contain a properties file than contains database credentials, -SaaS API tokens, etc. Users should be able to consume configuration artifacts in their containers -and be able to control the path on the container's filesystems where the artifact will be -presented. - -### Use-Case: Metadata about services - -Most pieces of information about how to use a service are secrets. For example, a service that -provides a MySQL database needs to provide the username, password, and database name to consumers -so that they can authenticate and use the correct database. Containers in pods consuming the MySQL -service would also consume the secrets associated with the MySQL service. - -### Use-Case: Secrets associated with service accounts - -[Service Accounts](service_accounts.md) are proposed as a -mechanism to decouple capabilities and security contexts from individual human users. A -`ServiceAccount` contains references to some number of secrets. A `Pod` can specify that it is -associated with a `ServiceAccount`. Secrets should have a `Type` field to allow the Kubelet and -other system components to take action based on the secret's type. - -#### Example: service account consumes auth token secret - -As an example, the service account proposal discusses service accounts consuming secrets which -contain Kubernetes auth tokens. When a Kubelet starts a pod associated with a service account -which consumes this type of secret, the Kubelet may take a number of actions: - -1. Expose the secret in a `.kubernetes_auth` file in a well-known location in the container's - file system -2. Configure that node's `kube-proxy` to decorate HTTP requests from that pod to the - `kubernetes-master` service with the auth token, e. g. by adding a header to the request - (see the [LOAS Daemon](https://k8s.io/kubernetes/issues/2209) proposal) - -#### Example: service account consumes docker registry credentials - -Another example use case is where a pod is associated with a secret containing docker registry -credentials. The Kubelet could use these credentials for the docker pull to retrieve the image. - -### Use-Case: Secret expiry and rotation - -Rotation is considered a good practice for many types of secret data. It should be possible to -express that a secret has an expiry date; this would make it possible to implement a system -component that could regenerate expired secrets. As an example, consider a component that rotates -expired secrets. The rotator could periodically regenerate the values for expired secrets of -common types and update their expiry dates. - -## Deferral: Consuming secrets as environment variables - -Some images will expect to receive configuration items as environment variables instead of files. -We should consider what the best way to allow this is; there are a few different options: - -1. Force the user to adapt files into environment variables. Users can store secrets that need to - be presented as environment variables in a format that is easy to consume from a shell: - - $ cat /etc/secrets/my-secret.txt - export MY_SECRET_ENV=MY_SECRET_VALUE - - The user could `source` the file at `/etc/secrets/my-secret` prior to executing the command for - the image either inline in the command or in an init script, - -2. Give secrets an attribute that allows users to express the intent that the platform should - generate the above syntax in the file used to present a secret. The user could consume these - files in the same manner as the above option. - -3. Give secrets attributes that allow the user to express that the secret should be presented to - the container as an environment variable. The container's environment would contain the - desired values and the software in the container could use them without accommodation the - command or setup script. - -For our initial work, we will treat all secrets as files to narrow the problem space. There will -be a future proposal that handles exposing secrets as environment variables. - -## Flow analysis of secret data with respect to the API server - -There are two fundamentally different use-cases for access to secrets: - -1. CRUD operations on secrets by their owners -2. Read-only access to the secrets needed for a particular node by the kubelet - -### Use-Case: CRUD operations by owners - -In use cases for CRUD operations, the user experience for secrets should be no different than for -other API resources. - -#### Data store backing the REST API - -The data store backing the REST API should be pluggable because different cluster operators will -have different preferences for the central store of secret data. Some possibilities for storage: - -1. An etcd collection alongside the storage for other API resources -2. A collocated [HSM](http://en.wikipedia.org/wiki/Hardware_security_module) -3. A secrets server like [Vault](https://www.vaultproject.io/) or [Keywhiz](https://square.github.io/keywhiz/) -4. An external datastore such as an external etcd, RDBMS, etc. - -#### Size limit for secrets - -There should be a size limit for secrets in order to: - -1. Prevent DOS attacks against the API server -2. Allow kubelet implementations that prevent secret data from touching the node's filesystem - -The size limit should satisfy the following conditions: - -1. Large enough to store common artifact types (encryption keypairs, certificates, small - configuration files) -2. Small enough to avoid large impact on node resource consumption (storage, RAM for tmpfs, etc) - -To begin discussion, we propose an initial value for this size limit of **1MB**. - -#### Other limitations on secrets - -Defining a policy for limitations on how a secret may be referenced by another API resource and how -constraints should be applied throughout the cluster is tricky due to the number of variables -involved: - -1. Should there be a maximum number of secrets a pod can reference via a volume? -2. Should there be a maximum number of secrets a service account can reference? -3. Should there be a total maximum number of secrets a pod can reference via its own spec and its - associated service account? -4. Should there be a total size limit on the amount of secret data consumed by a pod? -5. How will cluster operators want to be able to configure these limits? -6. How will these limits impact API server validations? -7. How will these limits affect scheduling? - -For now, we will not implement validations around these limits. Cluster operators will decide how -much node storage is allocated to secrets. It will be the operator's responsibility to ensure that -the allocated storage is sufficient for the workload scheduled onto a node. - -For now, kubelets will only attach secrets to api-sourced pods, and not file- or http-sourced -ones. Doing so would: - - confuse the secrets admission controller in the case of mirror pods. - - create an apiserver-liveness dependency -- avoiding this dependency is a main reason to use non-api-source pods. - -### Use-Case: Kubelet read of secrets for node - -The use-case where the kubelet reads secrets has several additional requirements: - -1. Kubelets should only be able to receive secret data which is required by pods scheduled onto - the kubelet's node -2. Kubelets should have read-only access to secret data -3. Secret data should not be transmitted over the wire insecurely -4. Kubelets must ensure pods do not have access to each other's secrets - -#### Read of secret data by the Kubelet - -The Kubelet should only be allowed to read secrets which are consumed by pods scheduled onto that -Kubelet's node and their associated service accounts. Authorization of the Kubelet to read this -data would be delegated to an authorization plugin and associated policy rule. - -#### Secret data on the node: data at rest - -Consideration must be given to whether secret data should be allowed to be at rest on the node: - -1. If secret data is not allowed to be at rest, the size of secret data becomes another draw on - the node's RAM - should it affect scheduling? -2. If secret data is allowed to be at rest, should it be encrypted? - 1. If so, how should be this be done? - 2. If not, what threats exist? What types of secret are appropriate to store this way? - -For the sake of limiting complexity, we propose that initially secret data should not be allowed -to be at rest on a node; secret data should be stored on a node-level tmpfs filesystem. This -filesystem can be subdivided into directories for use by the kubelet and by the volume plugin. - -#### Secret data on the node: resource consumption - -The Kubelet will be responsible for creating the per-node tmpfs file system for secret storage. -It is hard to make a prescriptive declaration about how much storage is appropriate to reserve for -secrets because different installations will vary widely in available resources, desired pod to -node density, overcommit policy, and other operation dimensions. That being the case, we propose -for simplicity that the amount of secret storage be controlled by a new parameter to the kubelet -with a default value of **64MB**. It is the cluster operator's responsibility to handle choosing -the right storage size for their installation and configuring their Kubelets correctly. - -Configuring each Kubelet is not the ideal story for operator experience; it is more intuitive that -the cluster-wide storage size be readable from a central configuration store like the one proposed -in [#1553](https://k8s.io/kubernetes/issues/1553). When such a store -exists, the Kubelet could be modified to read this configuration item from the store. - -When the Kubelet is modified to advertise node resources (as proposed in -[#4441](https://k8s.io/kubernetes/issues/4441)), the capacity calculation -for available memory should factor in the potential size of the node-level tmpfs in order to avoid -memory overcommit on the node. - -#### Secret data on the node: isolation - -Every pod will have a [security context](security_context.md). -Secret data on the node should be isolated according to the security context of the container. The -Kubelet volume plugin API will be changed so that a volume plugin receives the security context of -a volume along with the volume spec. This will allow volume plugins to implement setting the -security context of volumes they manage. - -## Community work - -Several proposals / upstream patches are notable as background for this proposal: - -1. [Docker vault proposal](https://github.com/docker/docker/issues/10310) -2. [Specification for image/container standardization based on volumes](https://github.com/docker/docker/issues/9277) -3. [Kubernetes service account proposal](service_accounts.md) -4. [Secrets proposal for docker (1)](https://github.com/docker/docker/pull/6075) -5. [Secrets proposal for docker (2)](https://github.com/docker/docker/pull/6697) - -## Proposed Design - -We propose a new `Secret` resource which is mounted into containers with a new volume type. Secret -volumes will be handled by a volume plugin that does the actual work of fetching the secret and -storing it. Secrets contain multiple pieces of data that are presented as different files within -the secret volume (example: SSH key pair). - -In order to remove the burden from the end user in specifying every file that a secret consists of, -it should be possible to mount all files provided by a secret with a single `VolumeMount` entry -in the container specification. - -### Secret API Resource - -A new resource for secrets will be added to the API: - -```go -type Secret struct { - TypeMeta - ObjectMeta - - // Data contains the secret data. Each key must be a valid DNS_SUBDOMAIN. - // The serialized form of the secret data is a base64 encoded string, - // representing the arbitrary (possibly non-string) data value here. - Data map[string][]byte `json:"data,omitempty"` - - // Used to facilitate programmatic handling of secret data. - Type SecretType `json:"type,omitempty"` -} - -type SecretType string - -const ( - SecretTypeOpaque SecretType = "Opaque" // Opaque (arbitrary data; default) - SecretTypeKubernetesAuthToken SecretType = "KubernetesAuth" // Kubernetes auth token - SecretTypeDockerRegistryAuth SecretType = "DockerRegistryAuth" // Docker registry auth - // FUTURE: other type values -) - -const MaxSecretSize = 1 * 1024 * 1024 -``` - -A Secret can declare a type in order to provide type information to system components that work -with secrets. The default type is `opaque`, which represents arbitrary user-owned data. - -Secrets are validated against `MaxSecretSize`. The keys in the `Data` field must be valid DNS -subdomains. - -A new REST API and registry interface will be added to accompany the `Secret` resource. The -default implementation of the registry will store `Secret` information in etcd. Future registry -implementations could store the `TypeMeta` and `ObjectMeta` fields in etcd and store the secret -data in another data store entirely, or store the whole object in another data store. - -#### Other validations related to secrets - -Initially there will be no validations for the number of secrets a pod references, or the number of -secrets that can be associated with a service account. These may be added in the future as the -finer points of secrets and resource allocation are fleshed out. - -### Secret Volume Source - -A new `SecretSource` type of volume source will be added to the `VolumeSource` struct in the -API: - -```go -type VolumeSource struct { - // Other fields omitted - - // SecretSource represents a secret that should be presented in a volume - SecretSource *SecretSource `json:"secret"` -} - -type SecretSource struct { - Target ObjectReference -} -``` - -Secret volume sources are validated to ensure that the specified object reference actually points -to an object of type `Secret`. - -In the future, the `SecretSource` will be extended to allow: - -1. Fine-grained control over which pieces of secret data are exposed in the volume -2. The paths and filenames for how secret data are exposed - -### Secret Volume Plugin - -A new Kubelet volume plugin will be added to handle volumes with a secret source. This plugin will -require access to the API server to retrieve secret data and therefore the volume `Host` interface -will have to change to expose a client interface: - -```go -type Host interface { - // Other methods omitted - - // GetKubeClient returns a client interface - GetKubeClient() client.Interface -} -``` - -The secret volume plugin will be responsible for: - -1. Returning a `volume.Builder` implementation from `NewBuilder` that: - 1. Retrieves the secret data for the volume from the API server - 2. Places the secret data onto the container's filesystem - 3. Sets the correct security attributes for the volume based on the pod's `SecurityContext` -2. Returning a `volume.Cleaner` implementation from `NewClear` that cleans the volume from the - container's filesystem - -### Kubelet: Node-level secret storage - -The Kubelet must be modified to accept a new parameter for the secret storage size and to create -a tmpfs file system of that size to store secret data. Rough accounting of specific changes: - -1. The Kubelet should have a new field added called `secretStorageSize`; units are megabytes -2. `NewMainKubelet` should accept a value for secret storage size -3. The Kubelet server should have a new flag added for secret storage size -4. The Kubelet's `setupDataDirs` method should be changed to create the secret storage - -### Kubelet: New behaviors for secrets associated with service accounts - -For use-cases where the Kubelet's behavior is affected by the secrets associated with a pod's -`ServiceAccount`, the Kubelet will need to be changed. For example, if secrets of type -`docker-reg-auth` affect how the pod's images are pulled, the Kubelet will need to be changed -to accommodate this. Subsequent proposals can address this on a type-by-type basis. - -## Examples - -For clarity, let's examine some detailed examples of some common use-cases in terms of the -suggested changes. All of these examples are assumed to be created in a namespace called -`example`. - -### Use-Case: Pod with ssh keys - -To create a pod that uses an ssh key stored as a secret, we first need to create a secret: - -```json -{ - "kind": "Secret", - "apiVersion": "v1", - "metadata": { - "name": "ssh-key-secret" - }, - "data": { - "id-rsa": "dmFsdWUtMg0KDQo=", - "id-rsa.pub": "dmFsdWUtMQ0K" - } -} -``` - -**Note:** The serialized JSON and YAML values of secret data are encoded as -base64 strings. Newlines are not valid within these strings and must be -omitted. - -Now we can create a pod which references the secret with the ssh key and consumes it in a volume: - -```json -{ - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "secret-test-pod", - "labels": { - "name": "secret-test" - } - }, - "spec": { - "volumes": [ - { - "name": "secret-volume", - "secret": { - "secretName": "ssh-key-secret" - } - } - ], - "containers": [ - { - "name": "ssh-test-container", - "image": "mySshImage", - "volumeMounts": [ - { - "name": "secret-volume", - "readOnly": true, - "mountPath": "/etc/secret-volume" - } - ] - } - ] - } -} -``` - -When the container's command runs, the pieces of the key will be available in: - - /etc/secret-volume/id-rsa.pub - /etc/secret-volume/id-rsa - -The container is then free to use the secret data to establish an ssh connection. - -### Use-Case: Pods with pod / test credentials - -This example illustrates a pod which consumes a secret containing prod -credentials and another pod which consumes a secret with test environment -credentials. - -The secrets: - -```json -{ - "apiVersion": "v1", - "kind": "List", - "items": - [{ - "kind": "Secret", - "apiVersion": "v1", - "metadata": { - "name": "prod-db-secret" - }, - "data": { - "password": "dmFsdWUtMg0KDQo=", - "username": "dmFsdWUtMQ0K" - } - }, - { - "kind": "Secret", - "apiVersion": "v1", - "metadata": { - "name": "test-db-secret" - }, - "data": { - "password": "dmFsdWUtMg0KDQo=", - "username": "dmFsdWUtMQ0K" - } - }] -} -``` - -The pods: - -```json -{ - "apiVersion": "v1", - "kind": "List", - "items": - [{ - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "prod-db-client-pod", - "labels": { - "name": "prod-db-client" - } - }, - "spec": { - "volumes": [ - { - "name": "secret-volume", - "secret": { - "secretName": "prod-db-secret" - } - } - ], - "containers": [ - { - "name": "db-client-container", - "image": "myClientImage", - "volumeMounts": [ - { - "name": "secret-volume", - "readOnly": true, - "mountPath": "/etc/secret-volume" - } - ] - } - ] - } - }, - { - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "test-db-client-pod", - "labels": { - "name": "test-db-client" - } - }, - "spec": { - "volumes": [ - { - "name": "secret-volume", - "secret": { - "secretName": "test-db-secret" - } - } - ], - "containers": [ - { - "name": "db-client-container", - "image": "myClientImage", - "volumeMounts": [ - { - "name": "secret-volume", - "readOnly": true, - "mountPath": "/etc/secret-volume" - } - ] - } - ] - } - }] -} -``` - -The specs for the two pods differ only in the value of the object referred to by the secret volume -source. Both containers will have the following files present on their filesystems: - - /etc/secret-volume/username - /etc/secret-volume/password - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/secrets.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/security.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/security.md deleted file mode 100644 index daf5c9e53c44..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/security.md +++ /dev/null @@ -1,155 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/security.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Security in Kubernetes - -Kubernetes should define a reasonable set of security best practices that allows processes to be isolated from each other, from the cluster infrastructure, and which preserves important boundaries between those who manage the cluster, and those who use the cluster. - -While Kubernetes today is not primarily a multi-tenant system, the long term evolution of Kubernetes will increasingly rely on proper boundaries between users and administrators. The code running on the cluster must be appropriately isolated and secured to prevent malicious parties from affecting the entire cluster. - - -## High Level Goals - -1. Ensure a clear isolation between the container and the underlying host it runs on -2. Limit the ability of the container to negatively impact the infrastructure or other containers -3. [Principle of Least Privilege](http://en.wikipedia.org/wiki/Principle_of_least_privilege) - ensure components are only authorized to perform the actions they need, and limit the scope of a compromise by limiting the capabilities of individual components -4. Reduce the number of systems that have to be hardened and secured by defining clear boundaries between components -5. Allow users of the system to be cleanly separated from administrators -6. Allow administrative functions to be delegated to users where necessary -7. Allow applications to be run on the cluster that have "secret" data (keys, certs, passwords) which is properly abstracted from "public" data. - - -## Use cases - -### Roles - -We define "user" as a unique identity accessing the Kubernetes API server, which may be a human or an automated process. Human users fall into the following categories: - -1. k8s admin - administers a Kubernetes cluster and has access to the underlying components of the system -2. k8s project administrator - administrates the security of a small subset of the cluster -3. k8s developer - launches pods on a Kubernetes cluster and consumes cluster resources - -Automated process users fall into the following categories: - -1. k8s container user - a user that processes running inside a container (on the cluster) can use to access other cluster resources independent of the human users attached to a project -2. k8s infrastructure user - the user that Kubernetes infrastructure components use to perform cluster functions with clearly defined roles - - -### Description of roles - -* Developers: - * write pod specs. - * making some of their own images, and using some "community" docker images - * know which pods need to talk to which other pods - * decide which pods should share files with other pods, and which should not. - * reason about application level security, such as containing the effects of a local-file-read exploit in a webserver pod. - * do not often reason about operating system or organizational security. - * are not necessarily comfortable reasoning about the security properties of a system at the level of detail of Linux Capabilities, SELinux, AppArmor, etc. - -* Project Admins: - * allocate identity and roles within a namespace - * reason about organizational security within a namespace - * don't give a developer permissions that are not needed for role. - * protect files on shared storage from unnecessary cross-team access - * are less focused about application security - -* Administrators: - * are less focused on application security. Focused on operating system security. - * protect the node from bad actors in containers, and properly-configured innocent containers from bad actors in other containers. - * comfortable reasoning about the security properties of a system at the level of detail of Linux Capabilities, SELinux, AppArmor, etc. - * decides who can use which Linux Capabilities, run privileged containers, use hostPath, etc. - * e.g. a team that manages Ceph or a mysql server might be trusted to have raw access to storage devices in some organizations, but teams that develop the applications at higher layers would not. - - -## Proposed Design - -A pod runs in a *security context* under a *service account* that is defined by an administrator or project administrator, and the *secrets* a pod has access to is limited by that *service account*. - - -1. The API should authenticate and authorize user actions [authn and authz](access.md) -2. All infrastructure components (kubelets, kube-proxies, controllers, scheduler) should have an infrastructure user that they can authenticate with and be authorized to perform only the functions they require against the API. -3. Most infrastructure components should use the API as a way of exchanging data and changing the system, and only the API should have access to the underlying data store (etcd) -4. When containers run on the cluster and need to talk to other containers or the API server, they should be identified and authorized clearly as an autonomous process via a [service account](service_accounts.md) - 1. If the user who started a long-lived process is removed from access to the cluster, the process should be able to continue without interruption - 2. If the user who started processes are removed from the cluster, administrators may wish to terminate their processes in bulk - 3. When containers run with a service account, the user that created / triggered the service account behavior must be associated with the container's action -5. When container processes run on the cluster, they should run in a [security context](security_context.md) that isolates those processes via Linux user security, user namespaces, and permissions. - 1. Administrators should be able to configure the cluster to automatically confine all container processes as a non-root, randomly assigned UID - 2. Administrators should be able to ensure that container processes within the same namespace are all assigned the same unix user UID - 3. Administrators should be able to limit which developers and project administrators have access to higher privilege actions - 4. Project administrators should be able to run pods within a namespace under different security contexts, and developers must be able to specify which of the available security contexts they may use - 5. Developers should be able to run their own images or images from the community and expect those images to run correctly - 6. Developers may need to ensure their images work within higher security requirements specified by administrators - 7. When available, Linux kernel user namespaces can be used to ensure 5.2 and 5.4 are met. - 8. When application developers want to share filesystem data via distributed filesystems, the Unix user ids on those filesystems must be consistent across different container processes -6. Developers should be able to define [secrets](secrets.md) that are automatically added to the containers when pods are run - 1. Secrets are files injected into the container whose values should not be displayed within a pod. Examples: - 1. An SSH private key for git cloning remote data - 2. A client certificate for accessing a remote system - 3. A private key and certificate for a web server - 4. A .kubeconfig file with embedded cert / token data for accessing the Kubernetes master - 5. A .dockercfg file for pulling images from a protected registry - 2. Developers should be able to define the pod spec so that a secret lands in a specific location - 3. Project administrators should be able to limit developers within a namespace from viewing or modifying secrets (anyone who can launch an arbitrary pod can view secrets) - 4. Secrets are generally not copied from one namespace to another when a developer's application definitions are copied - - -### Related design discussion - -* [Authorization and authentication](access.md) -* [Secret distribution via files](https://k8s.io/kubernetes/pull/2030) -* [Docker secrets](https://github.com/docker/docker/pull/6697) -* [Docker vault](https://github.com/docker/docker/issues/10310) -* [Service Accounts:](service_accounts.md) -* [Secret volumes](https://k8s.io/kubernetes/pull/4126) - -## Specific Design Points - -### TODO: authorization, authentication - -### Isolate the data store from the nodes and supporting infrastructure - -Access to the central data store (etcd) in Kubernetes allows an attacker to run arbitrary containers on hosts, to gain access to any protected information stored in either volumes or in pods (such as access tokens or shared secrets provided as environment variables), to intercept and redirect traffic from running services by inserting middlemen, or to simply delete the entire history of the custer. - -As a general principle, access to the central data store should be restricted to the components that need full control over the system and which can apply appropriate authorization and authentication of change requests. In the future, etcd may offer granular access control, but that granularity will require an administrator to understand the schema of the data to properly apply security. An administrator must be able to properly secure Kubernetes at a policy level, rather than at an implementation level, and schema changes over time should not risk unintended security leaks. - -Both the Kubelet and Kube Proxy need information related to their specific roles - for the Kubelet, the set of pods it should be running, and for the Proxy, the set of services and endpoints to load balance. The Kubelet also needs to provide information about running pods and historical termination data. The access pattern for both Kubelet and Proxy to load their configuration is an efficient "wait for changes" request over HTTP. It should be possible to limit the Kubelet and Proxy to only access the information they need to perform their roles and no more. - -The controller manager for Replication Controllers and other future controllers act on behalf of a user via delegation to perform automated maintenance on Kubernetes resources. Their ability to access or modify resource state should be strictly limited to their intended duties and they should be prevented from accessing information not pertinent to their role. For example, a replication controller needs only to create a copy of a known pod configuration, to determine the running state of an existing pod, or to delete an existing pod that it created - it does not need to know the contents or current state of a pod, nor have access to any data in the pods attached volumes. - -The Kubernetes pod scheduler is responsible for reading data from the pod to fit it onto a node in the cluster. At a minimum, it needs access to view the ID of a pod (to craft the binding), its current state, any resource information necessary to identify placement, and other data relevant to concerns like anti-affinity, zone or region preference, or custom logic. It does not need the ability to modify pods or see other resources, only to create bindings. It should not need the ability to delete bindings unless the scheduler takes control of relocating components on failed hosts (which could be implemented by a separate component that can delete bindings but not create them). The scheduler may need read access to user or project-container information to determine preferential location (underspecified at this time). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/security.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/security_context.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/security_context.md deleted file mode 100644 index 6ee426c5d5af..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/security_context.md +++ /dev/null @@ -1,200 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/security_context.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Security Contexts - -## Abstract - -A security context is a set of constraints that are applied to a container in order to achieve the following goals (from [security design](security.md)): - -1. Ensure a clear isolation between container and the underlying host it runs on -2. Limit the ability of the container to negatively impact the infrastructure or other containers - -## Background - -The problem of securing containers in Kubernetes has come up [before](https://k8s.io/kubernetes/issues/398) and the potential problems with container security are [well known](http://opensource.com/business/14/7/docker-security-selinux). Although it is not possible to completely isolate Docker containers from their hosts, new features like [user namespaces](https://github.com/docker/libcontainer/pull/304) make it possible to greatly reduce the attack surface. - -## Motivation - -### Container isolation - -In order to improve container isolation from host and other containers running on the host, containers should only be -granted the access they need to perform their work. To this end it should be possible to take advantage of Docker -features such as the ability to [add or remove capabilities](https://docs.docker.com/reference/run/#runtime-privilege-linux-capabilities-and-lxc-configuration) and [assign MCS labels](https://docs.docker.com/reference/run/#security-configuration) -to the container process. - -Support for user namespaces has recently been [merged](https://github.com/docker/libcontainer/pull/304) into Docker's libcontainer project and should soon surface in Docker itself. It will make it possible to assign a range of unprivileged uids and gids from the host to each container, improving the isolation between host and container and between containers. - -### External integration with shared storage - -In order to support external integration with shared storage, processes running in a Kubernetes cluster -should be able to be uniquely identified by their Unix UID, such that a chain of ownership can be established. -Processes in pods will need to have consistent UID/GID/SELinux category labels in order to access shared disks. - -## Constraints and Assumptions - -* It is out of the scope of this document to prescribe a specific set - of constraints to isolate containers from their host. Different use cases need different - settings. -* The concept of a security context should not be tied to a particular security mechanism or platform - (ie. SELinux, AppArmor) -* Applying a different security context to a scope (namespace or pod) requires a solution such as the one proposed for - [service accounts](service_accounts.md). - -## Use Cases - -In order of increasing complexity, following are example use cases that would -be addressed with security contexts: - -1. Kubernetes is used to run a single cloud application. In order to protect - nodes from containers: - * All containers run as a single non-root user - * Privileged containers are disabled - * All containers run with a particular MCS label - * Kernel capabilities like CHOWN and MKNOD are removed from containers - -2. Just like case #1, except that I have more than one application running on - the Kubernetes cluster. - * Each application is run in its own namespace to avoid name collisions - * For each application a different uid and MCS label is used - -3. Kubernetes is used as the base for a PAAS with - multiple projects, each project represented by a namespace. - * Each namespace is associated with a range of uids/gids on the node that - are mapped to uids/gids on containers using linux user namespaces. - * Certain pods in each namespace have special privileges to perform system - actions such as talking back to the server for deployment, run docker - builds, etc. - * External NFS storage is assigned to each namespace and permissions set - using the range of uids/gids assigned to that namespace. - -## Proposed Design - -### Overview - -A *security context* consists of a set of constraints that determine how a container -is secured before getting created and run. A security context resides on the container and represents the runtime parameters that will -be used to create and run the container via container APIs. A *security context provider* is passed to the Kubelet so it can have a chance -to mutate Docker API calls in order to apply the security context. - -It is recommended that this design be implemented in two phases: - -1. Implement the security context provider extension point in the Kubelet - so that a default security context can be applied on container run and creation. -2. Implement a security context structure that is part of a service account. The - default context provider can then be used to apply a security context based - on the service account associated with the pod. - -### Security Context Provider - -The Kubelet will have an interface that points to a `SecurityContextProvider`. The `SecurityContextProvider` is invoked before creating and running a given container: - -```go -type SecurityContextProvider interface { - // ModifyContainerConfig is called before the Docker createContainer call. - // The security context provider can make changes to the Config with which - // the container is created. - // An error is returned if it's not possible to secure the container as - // requested with a security context. - ModifyContainerConfig(pod *api.Pod, container *api.Container, config *docker.Config) - - // ModifyHostConfig is called before the Docker runContainer call. - // The security context provider can make changes to the HostConfig, affecting - // security options, whether the container is privileged, volume binds, etc. - // An error is returned if it's not possible to secure the container as requested - // with a security context. - ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *docker.HostConfig) -} -``` - -If the value of the SecurityContextProvider field on the Kubelet is nil, the kubelet will create and run the container as it does today. - -### Security Context - -A security context resides on the container and represents the runtime parameters that will -be used to create and run the container via container APIs. Following is an example of an initial implementation: - -```go -type type Container struct { - ... other fields omitted ... - // Optional: SecurityContext defines the security options the pod should be run with - SecurityContext *SecurityContext -} - -// SecurityContext holds security configuration that will be applied to a container. SecurityContext -// contains duplication of some existing fields from the Container resource. These duplicate fields -// will be populated based on the Container configuration if they are not set. Defining them on -// both the Container AND the SecurityContext will result in an error. -type SecurityContext struct { - // Capabilities are the capabilities to add/drop when running the container - Capabilities *Capabilities - - // Run the container in privileged mode - Privileged *bool - - // SELinuxOptions are the labels to be applied to the container - // and volumes - SELinuxOptions *SELinuxOptions - - // RunAsUser is the UID to run the entrypoint of the container process. - RunAsUser *int64 -} - -// SELinuxOptions are the labels to be applied to the container. -type SELinuxOptions struct { - // SELinux user label - User string - - // SELinux role label - Role string - - // SELinux type label - Type string - - // SELinux level label. - Level string -} -``` - -### Admission - -It is up to an admission plugin to determine if the security context is acceptable or not. At the -time of writing, the admission control plugin for security contexts will only allow a context that -has defined capabilities or privileged. Contexts that attempt to define a UID or SELinux options -will be denied by default. In the future the admission plugin will base this decision upon -configurable policies that reside within the [service account](https://k8s.io/kubernetes/pull/2297). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/security_context.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/service_accounts.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/service_accounts.md deleted file mode 100644 index 8e63e0454b58..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/service_accounts.md +++ /dev/null @@ -1,205 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/service_accounts.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Service Accounts - -## Motivation - -Processes in Pods may need to call the Kubernetes API. For example: - - scheduler - - replication controller - - node controller - - a map-reduce type framework which has a controller that then tries to make a dynamically determined number of workers and watch them - - continuous build and push system - - monitoring system - -They also may interact with services other than the Kubernetes API, such as: - - an image repository, such as docker -- both when the images are pulled to start the containers, and for writing - images in the case of pods that generate images. - - accessing other cloud services, such as blob storage, in the context of a large, integrated, cloud offering (hosted - or private). - - accessing files in an NFS volume attached to the pod - -## Design Overview - -A service account binds together several things: - - a *name*, understood by users, and perhaps by peripheral systems, for an identity - - a *principal* that can be authenticated and [authorized](../admin/authorization.md) - - a [security context](security_context.md), which defines the Linux Capabilities, User IDs, Groups IDs, and other - capabilities and controls on interaction with the file system and OS. - - a set of [secrets](secrets.md), which a container may use to - access various networked resources. - -## Design Discussion - -A new object Kind is added: - -```go -type ServiceAccount struct { - TypeMeta `json:",inline" yaml:",inline"` - ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` - - username string - securityContext ObjectReference // (reference to a securityContext object) - secrets []ObjectReference // (references to secret objects -} -``` - -The name ServiceAccount is chosen because it is widely used already (e.g. by Kerberos and LDAP) -to refer to this type of account. Note that it has no relation to Kubernetes Service objects. - -The ServiceAccount object does not include any information that could not be defined separately: - - username can be defined however users are defined. - - securityContext and secrets are only referenced and are created using the REST API. - -The purpose of the serviceAccount object is twofold: - - to bind usernames to securityContexts and secrets, so that the username can be used to refer succinctly - in contexts where explicitly naming securityContexts and secrets would be inconvenient - - to provide an interface to simplify allocation of new securityContexts and secrets. -These features are explained later. - -### Names - -From the standpoint of the Kubernetes API, a `user` is any principal which can authenticate to Kubernetes API. -This includes a human running `kubectl` on her desktop and a container in a Pod on a Node making API calls. - -There is already a notion of a username in Kubernetes, which is populated into a request context after authentication. -However, there is no API object representing a user. While this may evolve, it is expected that in mature installations, -the canonical storage of user identifiers will be handled by a system external to Kubernetes. - -Kubernetes does not dictate how to divide up the space of user identifier strings. User names can be -simple Unix-style short usernames, (e.g. `alice`), or may be qualified to allow for federated identity ( -`alice@example.com` vs `alice@example.org`.) Naming convention may distinguish service accounts from user -accounts (e.g. `alice@example.com` vs `build-service-account-a3b7f0@foo-namespace.service-accounts.example.com`), -but Kubernetes does not require this. - -Kubernetes also does not require that there be a distinction between human and Pod users. It will be possible -to setup a cluster where Alice the human talks to the Kubernetes API as username `alice` and starts pods that -also talk to the API as user `alice` and write files to NFS as user `alice`. But, this is not recommended. - -Instead, it is recommended that Pods and Humans have distinct identities, and reference implementations will -make this distinction. - -The distinction is useful for a number of reasons: - - the requirements for humans and automated processes are different: - - Humans need a wide range of capabilities to do their daily activities. Automated processes often have more narrowly-defined activities. - - Humans may better tolerate the exceptional conditions created by expiration of a token. Remembering to handle - this in a program is more annoying. So, either long-lasting credentials or automated rotation of credentials is - needed. - - A Human typically keeps credentials on a machine that is not part of the cluster and so not subject to automatic - management. A VM with a role/service-account can have its credentials automatically managed. - - the identity of a Pod cannot in general be mapped to a single human. - - If policy allows, it may be created by one human, and then updated by another, and another, until its behavior cannot be attributed to a single human. - -**TODO**: consider getting rid of separate serviceAccount object and just rolling its parts into the SecurityContext or -Pod Object. - -The `secrets` field is a list of references to /secret objects that an process started as that service account should -have access to be able to assert that role. - -The secrets are not inline with the serviceAccount object. This way, most or all users can have permission to `GET /serviceAccounts` so they can remind themselves -what serviceAccounts are available for use. - -Nothing will prevent creation of a serviceAccount with two secrets of type `SecretTypeKubernetesAuth`, or secrets of two -different types. Kubelet and client libraries will have some behavior, TBD, to handle the case of multiple secrets of a -given type (pick first or provide all and try each in order, etc). - -When a serviceAccount and a matching secret exist, then a `User.Info` for the serviceAccount and a `BearerToken` from the secret -are added to the map of tokens used by the authentication process in the apiserver, and similarly for other types. (We -might have some types that do not do anything on apiserver but just get pushed to the kubelet.) - -### Pods - -The `PodSpec` is extended to have a `Pods.Spec.ServiceAccountUsername` field. If this is unset, then a -default value is chosen. If it is set, then the corresponding value of `Pods.Spec.SecurityContext` is set by the -Service Account Finalizer (see below). - -TBD: how policy limits which users can make pods with which service accounts. - -### Authorization - -Kubernetes API Authorization Policies refer to users. Pods created with a `Pods.Spec.ServiceAccountUsername` typically -get a `Secret` which allows them to authenticate to the Kubernetes APIserver as a particular user. So any -policy that is desired can be applied to them. - -A higher level workflow is needed to coordinate creation of serviceAccounts, secrets and relevant policy objects. -Users are free to extend Kubernetes to put this business logic wherever is convenient for them, though the -Service Account Finalizer is one place where this can happen (see below). - -### Kubelet - -The kubelet will treat as "not ready to run" (needing a finalizer to act on it) any Pod which has an empty -SecurityContext. - -The kubelet will set a default, restrictive, security context for any pods created from non-Apiserver config -sources (http, file). - -Kubelet watches apiserver for secrets which are needed by pods bound to it. - -**TODO**: how to only let kubelet see secrets it needs to know. - -### The service account finalizer - -There are several ways to use Pods with SecurityContexts and Secrets. - -One way is to explicitly specify the securityContext and all secrets of a Pod when the pod is initially created, -like this: - -**TODO**: example of pod with explicit refs. - -Another way is with the *Service Account Finalizer*, a plugin process which is optional, and which handles -business logic around service accounts. - -The Service Account Finalizer watches Pods, Namespaces, and ServiceAccount definitions. - -First, if it finds pods which have a `Pod.Spec.ServiceAccountUsername` but no `Pod.Spec.SecurityContext` set, -then it copies in the referenced securityContext and secrets references for the corresponding `serviceAccount`. - -Second, if ServiceAccount definitions change, it may take some actions. -**TODO**: decide what actions it takes when a serviceAccount definition changes. Does it stop pods, or just -allow someone to list ones that are out of spec? In general, people may want to customize this? - -Third, if a new namespace is created, it may create a new serviceAccount for that namespace. This may include -a new username (e.g. `NAMESPACE-default-service-account@serviceaccounts.$CLUSTERID.kubernetes.io`), a new -securityContext, a newly generated secret to authenticate that serviceAccount to the Kubernetes API, and default -policies for that service account. -**TODO**: more concrete example. What are typical default permissions for default service account (e.g. readonly access -to services in the same namespace and read-write access to events in that namespace?) - -Finally, it may provide an interface to automate creation of new serviceAccounts. In that case, the user may want -to GET serviceAccounts to see what has been created. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/service_accounts.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/simple-rolling-update.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/simple-rolling-update.md deleted file mode 100644 index 720f4cbf4e5b..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/simple-rolling-update.md +++ /dev/null @@ -1,137 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/simple-rolling-update.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Simple rolling update - -This is a lightweight design document for simple [rolling update](../user-guide/kubectl/kubectl_rolling-update.md) in `kubectl`. - -Complete execution flow can be found [here](#execution-details). See the [example of rolling update](../user-guide/update-demo/) for more information. - -### Lightweight rollout - -Assume that we have a current replication controller named `foo` and it is running image `image:v1` - -`kubectl rolling-update foo [foo-v2] --image=myimage:v2` - -If the user doesn't specify a name for the 'next' replication controller, then the 'next' replication controller is renamed to -the name of the original replication controller. - -Obviously there is a race here, where if you kill the client between delete foo, and creating the new version of 'foo' you might be surprised about what is there, but I think that's ok. -See [Recovery](#recovery) below - -If the user does specify a name for the 'next' replication controller, then the 'next' replication controller is retained with its existing name, -and the old 'foo' replication controller is deleted. For the purposes of the rollout, we add a unique-ifying label `kubernetes.io/deployment` to both the `foo` and `foo-next` replication controllers. -The value of that label is the hash of the complete JSON representation of the`foo-next` or`foo` replication controller. The name of this label can be overridden by the user with the `--deployment-label-key` flag. - -#### Recovery - -If a rollout fails or is terminated in the middle, it is important that the user be able to resume the roll out. -To facilitate recovery in the case of a crash of the updating process itself, we add the following annotations to each replication controller in the `kubernetes.io/` annotation namespace: - * `desired-replicas` The desired number of replicas for this replication controller (either N or zero) - * `update-partner` A pointer to the replication controller resource that is the other half of this update (syntax `` the namespace is assumed to be identical to the namespace of this replication controller.) - -Recovery is achieved by issuing the same command again: - -```sh -kubectl rolling-update foo [foo-v2] --image=myimage:v2 -``` - -Whenever the rolling update command executes, the kubectl client looks for replication controllers called `foo` and `foo-next`, if they exist, an attempt is -made to roll `foo` to `foo-next`. If `foo-next` does not exist, then it is created, and the rollout is a new rollout. If `foo` doesn't exist, then -it is assumed that the rollout is nearly completed, and `foo-next` is renamed to `foo`. Details of the execution flow are given below. - - -### Aborting a rollout - -Abort is assumed to want to reverse a rollout in progress. - -`kubectl rolling-update foo [foo-v2] --rollback` - -This is really just semantic sugar for: - -`kubectl rolling-update foo-v2 foo` - -With the added detail that it moves the `desired-replicas` annotation from `foo-v2` to `foo` - - -### Execution Details - -For the purposes of this example, assume that we are rolling from `foo` to `foo-next` where the only change is an image update from `v1` to `v2` - -If the user doesn't specify a `foo-next` name, then it is either discovered from the `update-partner` annotation on `foo`. If that annotation doesn't exist, -then `foo-next` is synthesized using the pattern `-` - -#### Initialization - - * If `foo` and `foo-next` do not exist: - * Exit, and indicate an error to the user, that the specified controller doesn't exist. - * If `foo` exists, but `foo-next` does not: - * Create `foo-next` populate it with the `v2` image, set `desired-replicas` to `foo.Spec.Replicas` - * Goto Rollout - * If `foo-next` exists, but `foo` does not: - * Assume that we are in the rename phase. - * Goto Rename - * If both `foo` and `foo-next` exist: - * Assume that we are in a partial rollout - * If `foo-next` is missing the `desired-replicas` annotation - * Populate the `desired-replicas` annotation to `foo-next` using the current size of `foo` - * Goto Rollout - -#### Rollout - - * While size of `foo-next` < `desired-replicas` annotation on `foo-next` - * increase size of `foo-next` - * if size of `foo` > 0 - decrease size of `foo` - * Goto Rename - -#### Rename - - * delete `foo` - * create `foo` that is identical to `foo-next` - * delete `foo-next` - -#### Abort - - * If `foo-next` doesn't exist - * Exit and indicate to the user that they may want to simply do a new rollout with the old version - * If `foo` doesn't exist - * Exit and indicate not found to the user - * Otherwise, `foo-next` and `foo` both exist - * Set `desired-replicas` annotation on `foo` to match the annotation on `foo-next` - * Goto Rollout with `foo` and `foo-next` trading places. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/simple-rolling-update.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/versioning.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/versioning.md deleted file mode 100644 index 9009dc59c096..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/design/versioning.md +++ /dev/null @@ -1,82 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/design/versioning.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes API and Release Versioning - -Legend: - -* **Kube <major>.<minor>.<patch>** refers to the version of Kubernetes that is released. This versions all components: apiserver, kubelet, kubectl, etc. -* **API vX[betaY]** refers to the version of the HTTP API. - -## Release Timeline - -### Minor version scheme and timeline - -* Kube 1.0.0, 1.0.1 -- DONE! -* Kube 1.0.X (X>1): Standard operating procedure. We patch the release-1.0 branch as needed and increment the patch number. -* Kube 1.1.0-alpha.X: Released roughly every two weeks by cutting from HEAD. No cherrypick releases. If there is a critical bugfix, a new release from HEAD can be created ahead of schedule. (This applies to the beta releases as well.) -* Kube 1.1.0-beta.X: When HEAD is feature-complete, we go into code freeze 2 weeks prior to the desired 1.1.0 date and only merge PRs essential to 1.1. Releases continue to be cut from HEAD until we're essentially done. -* Kube 1.1.0: Final release. Should occur between 3 and 4 months after 1.0. - -### Major version timeline - -There is no mandated timeline for major versions. They only occur when we need to start the clock on deprecating features. A given major version should be the latest major version for at least one year from its original release date. - -## Release versions as related to API versions - -Here is an example major release cycle: - -* **Kube 1.0 should have API v1 without v1beta\* API versions** - * The last version of Kube before 1.0 (e.g. 0.14 or whatever it is) will have the stable v1 API. This enables you to migrate all your objects off of the beta API versions of the API and allows us to remove those beta API versions in Kube 1.0 with no effect. There will be tooling to help you detect and migrate any v1beta\* data versions or calls to v1 before you do the upgrade. -* **Kube 1.x may have API v2beta*** - * The first incarnation of a new (backwards-incompatible) API in HEAD is v2beta1. By default this will be unregistered in apiserver, so it can change freely. Once it is available by default in apiserver (which may not happen for several minor releases), it cannot change ever again because we serialize objects in versioned form, and we always need to be able to deserialize any objects that are saved in etcd, even between alpha versions. If further changes to v2beta1 need to be made, v2beta2 is created, and so on, in subsequent 1.x versions. -* **Kube 1.y (where y is the last version of the 1.x series) must have final API v2** - * Before Kube 2.0 is cut, API v2 must be released in 1.x. This enables two things: (1) users can upgrade to API v2 when running Kube 1.x and then switch over to Kube 2.x transparently, and (2) in the Kube 2.0 release itself we can cleanup and remove all API v2beta\* versions because no one should have v2beta\* objects left in their database. As mentioned above, tooling will exist to make sure there are no calls or references to a given API version anywhere inside someone's kube installation before someone upgrades. - * Kube 2.0 must include the v1 API, but Kube 3.0 must include the v2 API only. It *may* include the v1 API as well if the burden is not high - this will be determined on a per-major-version basis. - -## Rationale for API v2 being complete before v2.0's release - -It may seem a bit strange to complete the v2 API before v2.0 is released, but *adding* a v2 API is not a breaking change. *Removing* the v2beta\* APIs *is* a breaking change, which is what necessitates the major version bump. There are other ways to do this, but having the major release be the fresh start of that release's API without the baggage of its beta versions seems most intuitive out of the available options. - -# Upgrades - -* Users can upgrade from any Kube 1.x release to any other Kube 1.x release as a rolling upgrade across their cluster. (Rolling upgrade means being able to upgrade the master first, then one node at a time. See #4855 for details.) -* No hard breaking changes over version boundaries. - * For example, if a user is at Kube 1.x, we may require them to upgrade to Kube 1.x+y before upgrading to Kube 2.x. In others words, an upgrade across major versions (e.g. Kube 1.x to Kube 2.x) should effectively be a no-op and as graceful as an upgrade from Kube 1.x to Kube 1.x+1. But you can require someone to go from 1.x to 1.x+y before they go to 2.x. - -There is a separate question of how to track the capabilities of a kubelet to facilitate rolling upgrades. That is not addressed here. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/versioning.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/README.md deleted file mode 100644 index 267bca238ac9..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/README.md +++ /dev/null @@ -1,110 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes Developer Guide - -The developer guide is for anyone wanting to either write code which directly accesses the -Kubernetes API, or to contribute directly to the Kubernetes project. -It assumes some familiarity with concepts in the [User Guide](../user-guide/README.md) and the [Cluster Admin -Guide](../admin/README.md). - - -## The process of developing and contributing code to the Kubernetes project - -* **On Collaborative Development** ([collab.md](collab.md)): Info on pull requests and code reviews. - -* **GitHub Issues** ([issues.md](issues.md)): How incoming issues are reviewed and prioritized. - -* **Pull Request Process** ([pull-requests.md](pull-requests.md)): When and why pull requests are closed. - -* **Faster PR reviews** ([faster_reviews.md](faster_reviews.md)): How to get faster PR reviews. - -* **Getting Recent Builds** ([getting-builds.md](getting-builds.md)): How to get recent builds including the latest builds that pass CI. - - -## Setting up your dev environment, coding, and debugging - -* **Development Guide** ([development.md](development.md)): Setting up your development environment. - -* **Hunting flaky tests** ([flaky-tests.md](flaky-tests.md)): We have a goal of 99.9% flake free tests. - Here's how to run your tests many times. - -* **Logging Conventions** ([logging.md](logging.md)]: Glog levels. - -* **Profiling Kubernetes** ([profiling.md](profiling.md)): How to plug in go pprof profiler to Kubernetes. - -* **Instrumenting Kubernetes with a new metric** - ([instrumentation.md](instrumentation.md)): How to add a new metrics to the - Kubernetes code base. - -* **Coding Conventions** ([coding-conventions.md](coding-conventions.md)): - Coding style advice for contributors. - - -## Developing against the Kubernetes API - -* API objects are explained at [http://kubernetes.io/third_party/swagger-ui/](http://kubernetes.io/third_party/swagger-ui/). - -* **Annotations** ([docs/user-guide/annotations.md](../user-guide/annotations.md)): are for attaching arbitrary non-identifying metadata to objects. - Programs that automate Kubernetes objects may use annotations to store small amounts of their state. - -* **API Conventions** ([api-conventions.md](api-conventions.md)): - Defining the verbs and resources used in the Kubernetes API. - -* **API Client Libraries** ([client-libraries.md](client-libraries.md)): - A list of existing client libraries, both supported and user-contributed. - - -## Writing plugins - -* **Authentication Plugins** ([docs/admin/authentication.md](../admin/authentication.md)): - The current and planned states of authentication tokens. - -* **Authorization Plugins** ([docs/admin/authorization.md](../admin/authorization.md)): - Authorization applies to all HTTP requests on the main apiserver port. - This doc explains the available authorization implementations. - -* **Admission Control Plugins** ([admission_control](../design/admission_control.md)) - - -## Building releases - -* **Making release notes** ([making-release-notes.md](making-release-notes.md)): Generating release nodes for a new release. - -* **Releasing Kubernetes** ([releasing.md](releasing.md)): How to create a Kubernetes release (as in version) - and how the version information gets embedded into the built binaries. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/api-conventions.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/api-conventions.md deleted file mode 100644 index f2558cbb02c1..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/api-conventions.md +++ /dev/null @@ -1,654 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/api-conventions.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -API Conventions -=============== - -Updated: 4/16/2015 - -*This document is oriented at users who want a deeper understanding of the Kubernetes -API structure, and developers wanting to extend the Kubernetes API. An introduction to -using resources with kubectl can be found in (working_with_resources.md).* - -**Table of Contents** - - - - [Types (Kinds)](#types-kinds) - - [Resources](#resources) - - [Objects](#objects) - - [Metadata](#metadata) - - [Spec and Status](#spec-and-status) - - [Typical status properties](#typical-status-properties) - - [References to related objects](#references-to-related-objects) - - [Lists of named subobjects preferred over maps](#lists-of-named-subobjects-preferred-over-maps) - - [Constants](#constants) - - [Lists and Simple kinds](#lists-and-simple-kinds) - - [Differing Representations](#differing-representations) - - [Verbs on Resources](#verbs-on-resources) - - [PATCH operations](#patch-operations) - - [Strategic Merge Patch](#strategic-merge-patch) - - [List Operations](#list-operations) - - [Map Operations](#map-operations) - - [Idempotency](#idempotency) - - [Defaulting](#defaulting) - - [Late Initialization](#late-initialization) - - [Concurrency Control and Consistency](#concurrency-control-and-consistency) - - [Serialization Format](#serialization-format) - - [Units](#units) - - [Selecting Fields](#selecting-fields) - - [HTTP Status codes](#http-status-codes) - - [Success codes](#success-codes) - - [Error codes](#error-codes) - - [Response Status Kind](#response-status-kind) - - [Events](#events) - - - -The conventions of the [Kubernetes API](../api.md) (and related APIs in the ecosystem) are intended to ease client development and ensure that configuration mechanisms can be implemented that work across a diverse set of use cases consistently. - -The general style of the Kubernetes API is RESTful - clients create, update, delete, or retrieve a description of an object via the standard HTTP verbs (POST, PUT, DELETE, and GET) - and those APIs preferentially accept and return JSON. Kubernetes also exposes additional endpoints for non-standard verbs and allows alternative content types. All of the JSON accepted and returned by the server has a schema, identified by the "kind" and "apiVersion" fields. Where relevant HTTP header fields exist, they should mirror the content of JSON fields, but the information should not be represented only in the HTTP header. - -The following terms are defined: - -* **Kind** the name of a particular object schema (e.g. the "Cat" and "Dog" kinds would have different attributes and properties) -* **Resource** a representation of a system entity, sent or retrieved as JSON via HTTP to the server. Resources are exposed via: - * Collections - a list of resources of the same type, which may be queryable - * Elements - an individual resource, addressable via a URL - -Each resource typically accepts and returns data of a single kind. A kind may be accepted or returned by multiple resources that reflect specific use cases. For instance, the kind "pod" is exposed as a "pods" resource that allows end users to create, update, and delete pods, while a separate "pod status" resource (that acts on "pod" kind) allows automated processes to update a subset of the fields in that resource. A "restart" resource might be exposed for a number of different resources to allow the same action to have different results for each object. - -Resource collections should be all lowercase and plural, whereas kinds are CamelCase and singular. - - -## Types (Kinds) - -Kinds are grouped into three categories: - -1. **Objects** represent a persistent entity in the system. - - Creating an API object is a record of intent - once created, the system will work to ensure that resource exists. All API objects have common metadata. - - An object may have multiple resources that clients can use to perform specific actions that create, update, delete, or get. - - Examples: `Pods`, `ReplicationControllers`, `Services`, `Namespaces`, `Nodes` - -2. **Lists** are collections of **resources** of one (usually) or more (occasionally) kinds. - - Lists have a limited set of common metadata. All lists use the "items" field to contain the array of objects they return. - - Most objects defined in the system should have an endpoint that returns the full set of resources, as well as zero or more endpoints that return subsets of the full list. Some objects may be singletons (the current user, the system defaults) and may not have lists. - - In addition, all lists that return objects with labels should support label filtering (see [docs/user-guide/labels.md](../user-guide/labels.md), and most lists should support filtering by fields. - - Examples: PodLists, ServiceLists, NodeLists - - TODO: Describe field filtering below or in a separate doc. - -3. **Simple** kinds are used for specific actions on objects and for non-persistent entities. - - Given their limited scope, they have the same set of limited common metadata as lists. - - The "size" action may accept a simple resource that has only a single field as input (the number of things). The "status" kind is returned when errors occur and is not persisted in the system. - - Examples: Binding, Status - -The standard REST verbs (defined below) MUST return singular JSON objects. Some API endpoints may deviate from the strict REST pattern and return resources that are not singular JSON objects, such as streams of JSON objects or unstructured text log data. - -The term "kind" is reserved for these "top-level" API types. The term "type" should be used for distinguishing sub-categories within objects or subobjects. - -### Resources - -All JSON objects returned by an API MUST have the following fields: - -* kind: a string that identifies the schema this object should have -* apiVersion: a string that identifies the version of the schema the object should have - -These fields are required for proper decoding of the object. They may be populated by the server by default from the specified URL path, but the client likely needs to know the values in order to construct the URL path. - -### Objects - -#### Metadata - -Every object kind MUST have the following metadata in a nested object field called "metadata": - -* namespace: a namespace is a DNS compatible subdomain that objects are subdivided into. The default namespace is 'default'. See [docs/user-guide/namespaces.md](../user-guide/namespaces.md) for more. -* name: a string that uniquely identifies this object within the current namespace (see [docs/user-guide/identifiers.md](../user-guide/identifiers.md)). This value is used in the path when retrieving an individual object. -* uid: a unique in time and space value (typically an RFC 4122 generated identifier, see [docs/user-guide/identifiers.md](../user-guide/identifiers.md)) used to distinguish between objects with the same name that have been deleted and recreated - -Every object SHOULD have the following metadata in a nested object field called "metadata": - -* resourceVersion: a string that identifies the internal version of this object that can be used by clients to determine when objects have changed. This value MUST be treated as opaque by clients and passed unmodified back to the server. Clients should not assume that the resource version has meaning across namespaces, different kinds of resources, or different servers. (see [concurrency control](#concurrency-control-and-consistency), below, for more details) -* creationTimestamp: a string representing an RFC 3339 date of the date and time an object was created -* deletionTimestamp: a string representing an RFC 3339 date of the date and time after which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource will be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field. Once set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. -* labels: a map of string keys and values that can be used to organize and categorize objects (see [docs/user-guide/labels.md](../user-guide/labels.md)) -* annotations: a map of string keys and values that can be used by external tooling to store and retrieve arbitrary metadata about this object (see [docs/user-guide/annotations.md](../user-guide/annotations.md)) - -Labels are intended for organizational purposes by end users (select the pods that match this label query). Annotations enable third-party automation and tooling to decorate objects with additional metadata for their own use. - -#### Spec and Status - -By convention, the Kubernetes API makes a distinction between the specification of the desired state of an object (a nested object field called "spec") and the status of the object at the current time (a nested object field called "status"). The specification is a complete description of the desired state, including configuration settings provided by the user, [default values](#defaulting) expanded by the system, and properties initialized or otherwise changed after creation by other ecosystem components (e.g., schedulers, auto-scalers), and is persisted in stable storage with the API object. If the specification is deleted, the object will be purged from the system. The status summarizes the current state of the object in the system, and is usually persisted with the object by an automated processes but may be generated on the fly. At some cost and perhaps some temporary degradation in behavior, the status could be reconstructed by observation if it were lost. - -When a new version of an object is POSTed or PUT, the "spec" is updated and available immediately. Over time the system will work to bring the "status" into line with the "spec". The system will drive toward the most recent "spec" regardless of previous versions of that stanza. In other words, if a value is changed from 2 to 5 in one PUT and then back down to 3 in another PUT the system is not required to 'touch base' at 5 before changing the "status" to 3. In other words, the system's behavior is *level-based* rather than *edge-based*. This enables robust behavior in the presence of missed intermediate state changes. - -The Kubernetes API also serves as the foundation for the declarative configuration schema for the system. In order to facilitate level-based operation and expression of declarative configuration, fields in the specification should have declarative rather than imperative names and semantics -- they represent the desired state, not actions intended to yield the desired state. - -The PUT and POST verbs on objects will ignore the "status" values. A `/status` subresource is provided to enable system components to update statuses of resources they manage. - -Otherwise, PUT expects the whole object to be specified. Therefore, if a field is omitted it is assumed that the client wants to clear that field's value. The PUT verb does not accept partial updates. Modification of just part of an object may be achieved by GETting the resource, modifying part of the spec, labels, or annotations, and then PUTting it back. See [concurrency control](#concurrency-control-and-consistency), below, regarding read-modify-write consistency when using this pattern. Some objects may expose alternative resource representations that allow mutation of the status, or performing custom actions on the object. - -All objects that represent a physical resource whose state may vary from the user's desired intent SHOULD have a "spec" and a "status". Objects whose state cannot vary from the user's desired intent MAY have only "spec", and MAY rename "spec" to a more appropriate name. - -Objects that contain both spec and status should not contain additional top-level fields other than the standard metadata fields. - -##### Typical status properties - -* **phase**: The phase is a simple, high-level summary of the phase of the lifecycle of an object. The phase should progress monotonically. Typical phase values are `Pending` (not yet fully physically realized), `Running` or `Active` (fully realized and active, but not necessarily operating correctly), and `Terminated` (no longer active), but may vary slightly for different types of objects. New phase values should not be added to existing objects in the future. Like other status fields, it must be possible to ascertain the lifecycle phase by observation. Additional details regarding the current phase may be contained in other fields. -* **conditions**: Conditions represent orthogonal observations of an object's current state. Objects may report multiple conditions, and new types of conditions may be added in the future. Condition status values may be `True`, `False`, or `Unknown`. Unlike the phase, conditions are not expected to be monotonic -- their values may change back and forth. A typical condition type is `Ready`, which indicates the object was believed to be fully operational at the time it was last probed. Conditions may carry additional information, such as the last probe time or last transition time. - -TODO(@vishh): Reason and Message. - -Phases and conditions are observations and not, themselves, state machines, nor do we define comprehensive state machines for objects with behaviors associated with state transitions. The system is level-based and should assume an Open World. Additionally, new observations and details about these observations may be added over time. - -In order to preserve extensibility, in the future, we intend to explicitly convey properties that users and components care about rather than requiring those properties to be inferred from observations. - -Note that historical information status (e.g., last transition time, failure counts) is only provided at best effort, and is not guaranteed to not be lost. - -Status information that may be large (especially unbounded in size, such as lists of references to other objects -- see below) and/or rapidly changing, such as [resource usage](../design/resources.md#usage-data), should be put into separate objects, with possibly a reference from the original object. This helps to ensure that GETs and watch remain reasonably efficient for the majority of clients, which may not need that data. - -#### References to related objects - -References to loosely coupled sets of objects, such as [pods](../user-guide/pods.md) overseen by a [replication controller](../user-guide/replication-controller.md), are usually best referred to using a [label selector](../user-guide/labels.md). In order to ensure that GETs of individual objects remain bounded in time and space, these sets may be queried via separate API queries, but will not be expanded in the referring object's status. - -References to specific objects, especially specific resource versions and/or specific fields of those objects, are specified using the `ObjectReference` type. Unlike partial URLs, the ObjectReference type facilitates flexible defaulting of fields from the referring object or other contextual information. - -References in the status of the referee to the referrer may be permitted, when the references are one-to-one and do not need to be frequently updated, particularly in an edge-based manner. - -#### Lists of named subobjects preferred over maps - -Discussed in [#2004](https://k8s.io/kubernetes/issues/2004) and elsewhere. There are no maps of subobjects in any API objects. Instead, the convention is to use a list of subobjects containing name fields. - -For example: - -```yaml -ports: - - name: www - containerPort: 80 -``` - -vs. - -```yaml -ports: - www: - containerPort: 80 -``` - -This rule maintains the invariant that all JSON/YAML keys are fields in API objects. The only exceptions are pure maps in the API (currently, labels, selectors, and annotations), as opposed to sets of subobjects. - -#### Constants - -Some fields will have a list of allowed values (enumerations). These values will be strings, and they will be in CamelCase, with an initial uppercase letter. Examples: "ClusterFirst", "Pending", "ClientIP". - -### Lists and Simple kinds - -Every list or simple kind SHOULD have the following metadata in a nested object field called "metadata": - -* resourceVersion: a string that identifies the common version of the objects returned by in a list. This value MUST be treated as opaque by clients and passed unmodified back to the server. A resource version is only valid within a single namespace on a single kind of resource. - -Every simple kind returned by the server, and any simple kind sent to the server that must support idempotency or optimistic concurrency should return this value.Since simple resources are often used as input alternate actions that modify objects, the resource version of the simple resource should correspond to the resource version of the object. - - -## Differing Representations - -An API may represent a single entity in different ways for different clients, or transform an object after certain transitions in the system occur. In these cases, one request object may have two representations available as different resources, or different kinds. - -An example is a Service, which represents the intent of the user to group a set of pods with common behavior on common ports. When Kubernetes detects a pod matches the service selector, the IP address and port of the pod are added to an Endpoints resource for that Service. The Endpoints resource exists only if the Service exists, but exposes only the IPs and ports of the selected pods. The full service is represented by two distinct resources - under the original Service resource the user created, as well as in the Endpoints resource. - -As another example, a "pod status" resource may accept a PUT with the "pod" kind, with different rules about what fields may be changed. - -Future versions of Kubernetes may allow alternative encodings of objects beyond JSON. - - -## Verbs on Resources - -API resources should use the traditional REST pattern: - -* GET /<resourceNamePlural> - Retrieve a list of type <resourceName>, e.g. GET /pods returns a list of Pods. -* POST /<resourceNamePlural> - Create a new resource from the JSON object provided by the client. -* GET /<resourceNamePlural>/<name> - Retrieves a single resource with the given name, e.g. GET /pods/first returns a Pod named 'first'. Should be constant time, and the resource should be bounded in size. -* DELETE /<resourceNamePlural>/<name> - Delete the single resource with the given name. DeleteOptions may specify gracePeriodSeconds, the optional duration in seconds before the object should be deleted. Individual kinds may declare fields which provide a default grace period, and different kinds may have differing kind-wide default grace periods. A user provided grace period overrides a default grace period, including the zero grace period ("now"). -* PUT /<resourceNamePlural>/<name> - Update or create the resource with the given name with the JSON object provided by the client. -* PATCH /<resourceNamePlural>/<name> - Selectively modify the specified fields of the resource. See more information [below](#patch). - -Kubernetes by convention exposes additional verbs as new root endpoints with singular names. Examples: - -* GET /watch/<resourceNamePlural> - Receive a stream of JSON objects corresponding to changes made to any resource of the given kind over time. -* GET /watch/<resourceNamePlural>/<name> - Receive a stream of JSON objects corresponding to changes made to the named resource of the given kind over time. - -These are verbs which change the fundamental type of data returned (watch returns a stream of JSON instead of a single JSON object). Support of additional verbs is not required for all object types. - -Two additional verbs `redirect` and `proxy` provide access to cluster resources as described in [docs/user-guide/accessing-the-cluster.md](../user-guide/accessing-the-cluster.md). - -When resources wish to expose alternative actions that are closely coupled to a single resource, they should do so using new sub-resources. An example is allowing automated processes to update the "status" field of a Pod. The `/pods` endpoint only allows updates to "metadata" and "spec", since those reflect end-user intent. An automated process should be able to modify status for users to see by sending an updated Pod kind to the server to the "/pods/<name>/status" endpoint - the alternate endpoint allows different rules to be applied to the update, and access to be appropriately restricted. Likewise, some actions like "stop" or "scale" are best represented as REST sub-resources that are POSTed to. The POST action may require a simple kind to be provided if the action requires parameters, or function without a request body. - -TODO: more documentation of Watch - -### PATCH operations - -The API supports three different PATCH operations, determined by their corresponding Content-Type header: - -* JSON Patch, `Content-Type: application/json-patch+json` - * As defined in [RFC6902](https://tools.ietf.org/html/rfc6902), a JSON Patch is a sequence of operations that are executed on the resource, e.g. `{"op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ]}`. For more details on how to use JSON Patch, see the RFC. -* Merge Patch, `Content-Type: application/merge-json-patch+json` - * As defined in [RFC7386](https://tools.ietf.org/html/rfc7386), a Merge Patch is essentially a partial representation of the resource. The submitted JSON is "merged" with the current resource to create a new one, then the new one is saved. For more details on how to use Merge Patch, see the RFC. -* Strategic Merge Patch, `Content-Type: application/strategic-merge-patch+json` - * Strategic Merge Patch is a custom implementation of Merge Patch. For a detailed explanation of how it works and why it needed to be introduced, see below. - -#### Strategic Merge Patch - -In the standard JSON merge patch, JSON objects are always merged but lists are always replaced. Often that isn't what we want. Let's say we start with the following Pod: - -```yaml -spec: - containers: - - name: nginx - image: nginx-1.0 -``` - -...and we POST that to the server (as JSON). Then let's say we want to *add* a container to this Pod. - -```yaml -PATCH /api/v1/namespaces/default/pods/pod-name -spec: - containers: - - name: log-tailer - image: log-tailer-1.0 -``` - -If we were to use standard Merge Patch, the entire container list would be replaced with the single log-tailer container. However, our intent is for the container lists to merge together based on the `name` field. - -To solve this problem, Strategic Merge Patch uses metadata attached to the API objects to determine what lists should be merged and which ones should not. Currently the metadata is available as struct tags on the API objects themselves, but will become available to clients as Swagger annotations in the future. In the above example, the `patchStrategy` metadata for the `containers` field would be `merge` and the `patchMergeKey` would be `name`. - -Note: If the patch results in merging two lists of scalars, the scalars are first deduplicated and then merged. - -Strategic Merge Patch also supports special operations as listed below. - -### List Operations - -To override the container list to be strictly replaced, regardless of the default: - -```yaml -containers: - - name: nginx - image: nginx-1.0 - - $patch: replace # any further $patch operations nested in this list will be ignored -``` - -To delete an element of a list that should be merged: - -```yaml -containers: - - name: nginx - image: nginx-1.0 - - $patch: delete - name: log-tailer # merge key and value goes here -``` - -### Map Operations - -To indicate that a map should not be merged and instead should be taken literally: - -```yaml -$patch: replace # recursive and applies to all fields of the map it's in -containers: -- name: nginx - image: nginx-1.0 -``` - -To delete a field of a map: - -```yaml -name: nginx -image: nginx-1.0 -labels: - live: null # set the value of the map key to null -``` - - -## Idempotency - -All compatible Kubernetes APIs MUST support "name idempotency" and respond with an HTTP status code 409 when a request is made to POST an object that has the same name as an existing object in the system. See [docs/user-guide/identifiers.md](../user-guide/identifiers.md) for details. - -Names generated by the system may be requested using `metadata.generateName`. GenerateName indicates that the name should be made unique by the server prior to persisting it. A non-empty value for the field indicates the name will be made unique (and the name returned to the client will be different than the name passed). The value of this field will be combined with a unique suffix on the server if the Name field has not been provided. The provided value must be valid within the rules for Name, and may be truncated by the length of the suffix required to make the value unique on the server. If this field is specified, and Name is not present, the server will NOT return a 409 if the generated name exists - instead, it will either return 201 Created or 504 with Reason `ServerTimeout` indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header). - -## Defaulting - -Default resource values are API version-specific, and they are applied during -the conversion from API-versioned declarative configuration to internal objects -representing the desired state (`Spec`) of the resource. Subsequent GETs of the -resource will include the default values explicitly. - -Incorporating the default values into the `Spec` ensures that `Spec` depicts the -full desired state so that it is easier for the system to determine how to -achieve the state, and for the user to know what to anticipate. - -API version-specific default values are set by the API server. - -## Late Initialization - -Late initialization is when resource fields are set by a system controller -after an object is created/updated. - -For example, the scheduler sets the `pod.spec.nodeName` field after the pod is created. - -Late-initializers should only make the following types of modifications: - - Setting previously unset fields - - Adding keys to maps - - Adding values to arrays which have mergeable semantics (`patchStrategy:"merge"` attribute in - the type definition). - -These conventions: - 1. allow a user (with sufficient privilege) to override any system-default behaviors by setting - the fields that would otherwise have been defaulted. - 1. enables updates from users to be merged with changes made during late initialization, using - strategic merge patch, as opposed to clobbering the change. - 1. allow the component which does the late-initialization to use strategic merge patch, which - facilitates composition and concurrency of such components. - -Although the apiserver Admission Control stage acts prior to object creation, -Admission Control plugins should follow the Late Initialization conventions -too, to allow their implementation to be later moved to a 'controller', or to client libraries. - -## Concurrency Control and Consistency - -Kubernetes leverages the concept of *resource versions* to achieve optimistic concurrency. All Kubernetes resources have a "resourceVersion" field as part of their metadata. This resourceVersion is a string that identifies the internal version of an object that can be used by clients to determine when objects have changed. When a record is about to be updated, it's version is checked against a pre-saved value, and if it doesn't match, the update fails with a StatusConflict (HTTP status code 409). - -The resourceVersion is changed by the server every time an object is modified. If resourceVersion is included with the PUT operation the system will verify that there have not been other successful mutations to the resource during a read/modify/write cycle, by verifying that the current value of resourceVersion matches the specified value. - -The resourceVersion is currently backed by [etcd's modifiedIndex](https://coreos.com/docs/distributed-configuration/etcd-api/). However, it's important to note that the application should *not* rely on the implementation details of the versioning system maintained by Kubernetes. We may change the implementation of resourceVersion in the future, such as to change it to a timestamp or per-object counter. - -The only way for a client to know the expected value of resourceVersion is to have received it from the server in response to a prior operation, typically a GET. This value MUST be treated as opaque by clients and passed unmodified back to the server. Clients should not assume that the resource version has meaning across namespaces, different kinds of resources, or different servers. Currently, the value of resourceVersion is set to match etcd's sequencer. You could think of it as a logical clock the API server can use to order requests. However, we expect the implementation of resourceVersion to change in the future, such as in the case we shard the state by kind and/or namespace, or port to another storage system. - -In the case of a conflict, the correct client action at this point is to GET the resource again, apply the changes afresh, and try submitting again. This mechanism can be used to prevent races like the following: - -``` -Client #1 Client #2 -GET Foo GET Foo -Set Foo.Bar = "one" Set Foo.Baz = "two" -PUT Foo PUT Foo -``` - -When these sequences occur in parallel, either the change to Foo.Bar or the change to Foo.Baz can be lost. - -On the other hand, when specifying the resourceVersion, one of the PUTs will fail, since whichever write succeeds changes the resourceVersion for Foo. - -resourceVersion may be used as a precondition for other operations (e.g., GET, DELETE) in the future, such as for read-after-write consistency in the presence of caching. - -"Watch" operations specify resourceVersion using a query parameter. It is used to specify the point at which to begin watching the specified resources. This may be used to ensure that no mutations are missed between a GET of a resource (or list of resources) and a subsequent Watch, even if the current version of the resource is more recent. This is currently the main reason that list operations (GET on a collection) return resourceVersion. - - -## Serialization Format - -APIs may return alternative representations of any resource in response to an Accept header or under alternative endpoints, but the default serialization for input and output of API responses MUST be JSON. - -All dates should be serialized as RFC3339 strings. - - -## Units - -Units must either be explicit in the field name (e.g., `timeoutSeconds`), or must be specified as part of the value (e.g., `resource.Quantity`). Which approach is preferred is TBD. - - -## Selecting Fields - -Some APIs may need to identify which field in a JSON object is invalid, or to reference a value to extract from a separate resource. The current recommendation is to use standard JavaScript syntax for accessing that field, assuming the JSON object was transformed into a JavaScript object. - -Examples: - -* Find the field "current" in the object "state" in the second item in the array "fields": `fields[0].state.current` - -TODO: Plugins, extensions, nested kinds, headers - - -## HTTP Status codes - -The server will respond with HTTP status codes that match the HTTP spec. See the section below for a breakdown of the types of status codes the server will send. - -The following HTTP status codes may be returned by the API. - -#### Success codes - -* `200 StatusOK` - * Indicates that the request completed successfully. -* `201 StatusCreated` - * Indicates that the request to create kind completed successfully. -* `204 StatusNoContent` - * Indicates that the request completed successfully, and the response contains no body. - * Returned in response to HTTP OPTIONS requests. - -#### Error codes - -* `307 StatusTemporaryRedirect` - * Indicates that the address for the requested resource has changed. - * Suggested client recovery behavior - * Follow the redirect. -* `400 StatusBadRequest` - * Indicates the requested is invalid. - * Suggested client recovery behavior: - * Do not retry. Fix the request. -* `401 StatusUnauthorized` - * Indicates that the server can be reached and understood the request, but refuses to take any further action, because the client must provide authorization. If the client has provided authorization, the server is indicating the provided authorization is unsuitable or invalid. - * Suggested client recovery behavior - * If the user has not supplied authorization information, prompt them for the appropriate credentials - * If the user has supplied authorization information, inform them their credentials were rejected and optionally prompt them again. -* `403 StatusForbidden` - * Indicates that the server can be reached and understood the request, but refuses to take any further action, because it is configured to deny access for some reason to the requested resource by the client. - * Suggested client recovery behavior - * Do not retry. Fix the request. -* `404 StatusNotFound` - * Indicates that the requested resource does not exist. - * Suggested client recovery behavior - * Do not retry. Fix the request. -* `405 StatusMethodNotAllowed` - * Indicates that the action the client attempted to perform on the resource was not supported by the code. - * Suggested client recovery behavior - * Do not retry. Fix the request. -* `409 StatusConflict` - * Indicates that either the resource the client attempted to create already exists or the requested update operation cannot be completed due to a conflict. - * Suggested client recovery behavior - * * If creating a new resource - * * Either change the identifier and try again, or GET and compare the fields in the pre-existing object and issue a PUT/update to modify the existing object. - * * If updating an existing resource: - * See `Conflict` from the `status` response section below on how to retrieve more information about the nature of the conflict. - * GET and compare the fields in the pre-existing object, merge changes (if still valid according to preconditions), and retry with the updated request (including `ResourceVersion`). -* `422 StatusUnprocessableEntity` - * Indicates that the requested create or update operation cannot be completed due to invalid data provided as part of the request. - * Suggested client recovery behavior - * Do not retry. Fix the request. -* `429 StatusTooManyRequests` - * Indicates that the either the client rate limit has been exceeded or the server has received more requests then it can process. - * Suggested client recovery behavior: - * Read the `Retry-After` HTTP header from the response, and wait at least that long before retrying. -* `500 StatusInternalServerError` - * Indicates that the server can be reached and understood the request, but either an unexpected internal error occurred and the outcome of the call is unknown, or the server cannot complete the action in a reasonable time (this maybe due to temporary server load or a transient communication issue with another server). - * Suggested client recovery behavior: - * Retry with exponential backoff. -* `503 StatusServiceUnavailable` - * Indicates that required service is unavailable. - * Suggested client recovery behavior: - * Retry with exponential backoff. -* `504 StatusServerTimeout` - * Indicates that the request could not be completed within the given time. Clients can get this response ONLY when they specified a timeout param in the request. - * Suggested client recovery behavior: - * Increase the value of the timeout param and retry with exponential backoff - -## Response Status Kind - -Kubernetes will always return the `Status` kind from any API endpoint when an error occurs. -Clients SHOULD handle these types of objects when appropriate. - -A `Status` kind will be returned by the API in two cases: - * When an operation is not successful (i.e. when the server would return a non 2xx HTTP status code). - * When a HTTP `DELETE` call is successful. - -The status object is encoded as JSON and provided as the body of the response. The status object contains fields for humans and machine consumers of the API to get more detailed information for the cause of the failure. The information in the status object supplements, but does not override, the HTTP status code's meaning. When fields in the status object have the same meaning as generally defined HTTP headers and that header is returned with the response, the header should be considered as having higher priority. - -**Example:** - -```console -$ curl -v -k -H "Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc" https://10.240.122.184:443/api/v1/namespaces/default/pods/grafana - -> GET /api/v1/namespaces/default/pods/grafana HTTP/1.1 -> User-Agent: curl/7.26.0 -> Host: 10.240.122.184 -> Accept: */* -> Authorization: Bearer WhCDvq4VPpYhrcfmF6ei7V9qlbqTubUc -> - -< HTTP/1.1 404 Not Found -< Content-Type: application/json -< Date: Wed, 20 May 2015 18:10:42 GMT -< Content-Length: 232 -< -{ - "kind": "Status", - "apiVersion": "v1", - "metadata": {}, - "status": "Failure", - "message": "pods \"grafana\" not found", - "reason": "NotFound", - "details": { - "name": "grafana", - "kind": "pods" - }, - "code": 404 -} -``` - -`status` field contains one of two possible values: -* `Success` -* `Failure` - -`message` may contain human-readable description of the error - -`reason` may contain a machine-readable description of why this operation is in the `Failure` status. If this value is empty there is no information available. The `reason` clarifies an HTTP status code but does not override it. - -`details` may contain extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type. - -Possible values for the `reason` and `details` fields: -* `BadRequest` - * Indicates that the request itself was invalid, because the request doesn't make any sense, for example deleting a read-only object. - * This is different than `status reason` `Invalid` above which indicates that the API call could possibly succeed, but the data was invalid. - * API calls that return BadRequest can never succeed. - * Http status code: `400 StatusBadRequest` -* `Unauthorized` - * Indicates that the server can be reached and understood the request, but refuses to take any further action without the client providing appropriate authorization. If the client has provided authorization, this error indicates the provided credentials are insufficient or invalid. - * Details (optional): - * `kind string` - * The kind attribute of the unauthorized resource (on some operations may differ from the requested resource). - * `name string` - * The identifier of the unauthorized resource. - * HTTP status code: `401 StatusUnauthorized` -* `Forbidden` - * Indicates that the server can be reached and understood the request, but refuses to take any further action, because it is configured to deny access for some reason to the requested resource by the client. - * Details (optional): - * `kind string` - * The kind attribute of the forbidden resource (on some operations may differ from the requested resource). - * `name string` - * The identifier of the forbidden resource. - * HTTP status code: `403 StatusForbidden` -* `NotFound` - * Indicates that one or more resources required for this operation could not be found. - * Details (optional): - * `kind string` - * The kind attribute of the missing resource (on some operations may differ from the requested resource). - * `name string` - * The identifier of the missing resource. - * HTTP status code: `404 StatusNotFound` -* `AlreadyExists` - * Indicates that the resource you are creating already exists. - * Details (optional): - * `kind string` - * The kind attribute of the conflicting resource. - * `name string` - * The identifier of the conflicting resource. - * HTTP status code: `409 StatusConflict` -* `Conflict` - * Indicates that the requested update operation cannot be completed due to a conflict. The client may need to alter the request. Each resource may define custom details that indicate the nature of the conflict. - * HTTP status code: `409 StatusConflict` -* `Invalid` - * Indicates that the requested create or update operation cannot be completed due to invalid data provided as part of the request. - * Details (optional): - * `kind string` - * the kind attribute of the invalid resource - * `name string` - * the identifier of the invalid resource - * `causes` - * One or more `StatusCause` entries indicating the data in the provided resource that was invalid. The `reason`, `message`, and `field` attributes will be set. - * HTTP status code: `422 StatusUnprocessableEntity` -* `Timeout` - * Indicates that the request could not be completed within the given time. Clients may receive this response if the server has decided to rate limit the client, or if the server is overloaded and cannot process the request at this time. - * Http status code: `429 TooManyRequests` - * The server should set the `Retry-After` HTTP header and return `retryAfterSeconds` in the details field of the object. A value of `0` is the default. -* `ServerTimeout` - * Indicates that the server can be reached and understood the request, but cannot complete the action in a reasonable time. This maybe due to temporary server load or a transient communication issue with another server. - * Details (optional): - * `kind string` - * The kind attribute of the resource being acted on. - * `name string` - * The operation that is being attempted. - * The server should set the `Retry-After` HTTP header and return `retryAfterSeconds` in the details field of the object. A value of `0` is the default. - * Http status code: `504 StatusServerTimeout` -* `MethodNotAllowed` - * Indicates that the action the client attempted to perform on the resource was not supported by the code. - * For instance, attempting to delete a resource that can only be created. - * API calls that return MethodNotAllowed can never succeed. - * Http status code: `405 StatusMethodNotAllowed` -* `InternalError` - * Indicates that an internal error occurred, it is unexpected and the outcome of the call is unknown. - * Details (optional): - * `causes` - * The original error. - * Http status code: `500 StatusInternalServerError` - -`code` may contain the suggested HTTP return code for this status. - - -## Events - -TODO: Document events (refer to another doc for details) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/api-conventions.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/api_changes.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/api_changes.md deleted file mode 100644 index 687af00af506..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/api_changes.md +++ /dev/null @@ -1,382 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/api_changes.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# So you want to change the API? - -The Kubernetes API has two major components - the internal structures and -the versioned APIs. The versioned APIs are intended to be stable, while the -internal structures are implemented to best reflect the needs of the Kubernetes -code itself. - -What this means for API changes is that you have to be somewhat thoughtful in -how you approach changes, and that you have to touch a number of pieces to make -a complete change. This document aims to guide you through the process, though -not all API changes will need all of these steps. - -## Operational overview - -It is important to have a high level understanding of the API system used in -Kubernetes in order to navigate the rest of this document. - -As mentioned above, the internal representation of an API object is decoupled -from any one API version. This provides a lot of freedom to evolve the code, -but it requires robust infrastructure to convert between representations. There -are multiple steps in processing an API operation - even something as simple as -a GET involves a great deal of machinery. - -The conversion process is logically a "star" with the internal form at the -center. Every versioned API can be converted to the internal form (and -vice-versa), but versioned APIs do not convert to other versioned APIs directly. -This sounds like a heavy process, but in reality we do not intend to keep more -than a small number of versions alive at once. While all of the Kubernetes code -operates on the internal structures, they are always converted to a versioned -form before being written to storage (disk or etcd) or being sent over a wire. -Clients should consume and operate on the versioned APIs exclusively. - -To demonstrate the general process, here is a (hypothetical) example: - - 1. A user POSTs a `Pod` object to `/api/v7beta1/...` - 2. The JSON is unmarshalled into a `v7beta1.Pod` structure - 3. Default values are applied to the `v7beta1.Pod` - 4. The `v7beta1.Pod` is converted to an `api.Pod` structure - 5. The `api.Pod` is validated, and any errors are returned to the user - 6. The `api.Pod` is converted to a `v6.Pod` (because v6 is the latest stable - version) - 7. The `v6.Pod` is marshalled into JSON and written to etcd - -Now that we have the `Pod` object stored, a user can GET that object in any -supported api version. For example: - - 1. A user GETs the `Pod` from `/api/v5/...` - 2. The JSON is read from etcd and unmarshalled into a `v6.Pod` structure - 3. Default values are applied to the `v6.Pod` - 4. The `v6.Pod` is converted to an `api.Pod` structure - 5. The `api.Pod` is converted to a `v5.Pod` structure - 6. The `v5.Pod` is marshalled into JSON and sent to the user - -The implication of this process is that API changes must be done carefully and -backward-compatibly. - -## On compatibility - -Before talking about how to make API changes, it is worthwhile to clarify what -we mean by API compatibility. An API change is considered backward-compatible -if it: - * adds new functionality that is not required for correct behavior - * does not change existing semantics - * does not change existing defaults - -Put another way: - -1. Any API call (e.g. a structure POSTed to a REST endpoint) that worked before - your change must work the same after your change. -2. Any API call that uses your change must not cause problems (e.g. crash or - degrade behavior) when issued against servers that do not include your change. -3. It must be possible to round-trip your change (convert to different API - versions and back) with no loss of information. - -If your change does not meet these criteria, it is not considered strictly -compatible. There are times when this might be OK, but mostly we want changes -that meet this definition. If you think you need to break compatibility, you -should talk to the Kubernetes team first. - -Let's consider some examples. In a hypothetical API (assume we're at version -v6), the `Frobber` struct looks something like this: - -```go -// API v6. -type Frobber struct { - Height int `json:"height"` - Param string `json:"param"` -} -``` - -You want to add a new `Width` field. It is generally safe to add new fields -without changing the API version, so you can simply change it to: - -```go -// Still API v6. -type Frobber struct { - Height int `json:"height"` - Width int `json:"width"` - Param string `json:"param"` -} -``` - -The onus is on you to define a sane default value for `Width` such that rule #1 -above is true - API calls and stored objects that used to work must continue to -work. - -For your next change you want to allow multiple `Param` values. You can not -simply change `Param string` to `Params []string` (without creating a whole new -API version) - that fails rules #1 and #2. You can instead do something like: - -```go -// Still API v6, but kind of clumsy. -type Frobber struct { - Height int `json:"height"` - Width int `json:"width"` - Param string `json:"param"` // the first param - ExtraParams []string `json:"params"` // additional params -} -``` - -Now you can satisfy the rules: API calls that provide the old style `Param` -will still work, while servers that don't understand `ExtraParams` can ignore -it. This is somewhat unsatisfying as an API, but it is strictly compatible. - -Part of the reason for versioning APIs and for using internal structs that are -distinct from any one version is to handle growth like this. The internal -representation can be implemented as: - -```go -// Internal, soon to be v7beta1. -type Frobber struct { - Height int - Width int - Params []string -} -``` - -The code that converts to/from versioned APIs can decode this into the somewhat -uglier (but compatible!) structures. Eventually, a new API version, let's call -it v7beta1, will be forked and it can use the clean internal structure. - -We've seen how to satisfy rules #1 and #2. Rule #3 means that you can not -extend one versioned API without also extending the others. For example, an -API call might POST an object in API v7beta1 format, which uses the cleaner -`Params` field, but the API server might store that object in trusty old v6 -form (since v7beta1 is "beta"). When the user reads the object back in the -v7beta1 API it would be unacceptable to have lost all but `Params[0]`. This -means that, even though it is ugly, a compatible change must be made to the v6 -API. - -As another interesting example, enumerated values provide a unique challenge. -Adding a new value to an enumerated set is *not* a compatible change. Clients -which assume they know how to handle all possible values of a given field will -not be able to handle the new values. However, removing value from an -enumerated set *can* be a compatible change, if handled properly (treat the -removed value as deprecated but allowed). - -## Changing versioned APIs - -For most changes, you will probably find it easiest to change the versioned -APIs first. This forces you to think about how to make your change in a -compatible way. Rather than doing each step in every version, it's usually -easier to do each versioned API one at a time, or to do all of one version -before starting "all the rest". - -### Edit types.go - -The struct definitions for each API are in `pkg/api//types.go`. Edit -those files to reflect the change you want to make. Note that all non-online -fields in versioned APIs must have description tags - these are used to generate -documentation. - -### Edit defaults.go - -If your change includes new fields for which you will need default values, you -need to add cases to `pkg/api//defaults.go`. Of course, since you -have added code, you have to add a test: `pkg/api//defaults_test.go`. - -Do use pointers to scalars when you need to distinguish between an unset value -and an automatic zero value. For example, -`PodSpec.TerminationGracePeriodSeconds` is defined as `*int64` the go type -definition. A zero value means 0 seconds, and a nil value asks the system to -pick a default. - -Don't forget to run the tests! - -### Edit conversion.go - -Given that you have not yet changed the internal structs, this might feel -premature, and that's because it is. You don't yet have anything to convert to -or from. We will revisit this in the "internal" section. If you're doing this -all in a different order (i.e. you started with the internal structs), then you -should jump to that topic below. In the very rare case that you are making an -incompatible change you might or might not want to do this now, but you will -have to do more later. The files you want are -`pkg/api//conversion.go` and `pkg/api//conversion_test.go`. - -## Changing the internal structures - -Now it is time to change the internal structs so your versioned changes can be -used. - -### Edit types.go - -Similar to the versioned APIs, the definitions for the internal structs are in -`pkg/api/types.go`. Edit those files to reflect the change you want to make. -Keep in mind that the internal structs must be able to express *all* of the -versioned APIs. - -## Edit validation.go - -Most changes made to the internal structs need some form of input validation. -Validation is currently done on internal objects in -`pkg/api/validation/validation.go`. This validation is the one of the first -opportunities we have to make a great user experience - good error messages and -thorough validation help ensure that users are giving you what you expect and, -when they don't, that they know why and how to fix it. Think hard about the -contents of `string` fields, the bounds of `int` fields and the -requiredness/optionalness of fields. - -Of course, code needs tests - `pkg/api/validation/validation_test.go`. - -## Edit version conversions - -At this point you have both the versioned API changes and the internal -structure changes done. If there are any notable differences - field names, -types, structural change in particular - you must add some logic to convert -versioned APIs to and from the internal representation. If you see errors from -the `serialization_test`, it may indicate the need for explicit conversions. - -Performance of conversions very heavily influence performance of apiserver. -Thus, we are auto-generating conversion functions that are much more efficient -than the generic ones (which are based on reflections and thus are highly -inefficient). - -The conversion code resides with each versioned API. There are two files: - - `pkg/api//conversion.go` containing manually written conversion - functions - - `pkg/api//conversion_generated.go` containing auto-generated - conversion functions - -Since auto-generated conversion functions are using manually written ones, -those manually written should be named with a defined convention, i.e. a function -converting type X in pkg a to type Y in pkg b, should be named: -`convert_a_X_To_b_Y`. - -Also note that you can (and for efficiency reasons should) use auto-generated -conversion functions when writing your conversion functions. - -Once all the necessary manually written conversions are added, you need to -regenerate auto-generated ones. To regenerate them: - - run - -```sh -hack/update-generated-conversions.sh -``` - -If running the above script is impossible due to compile errors, the easiest -workaround is to comment out the code causing errors and let the script to -regenerate it. If the auto-generated conversion methods are not used by the -manually-written ones, it's fine to just remove the whole file and let the -generator to create it from scratch. - -Unsurprisingly, adding manually written conversion also requires you to add tests to -`pkg/api//conversion_test.go`. - -## Update the fuzzer - -Part of our testing regimen for APIs is to "fuzz" (fill with random values) API -objects and then convert them to and from the different API versions. This is -a great way of exposing places where you lost information or made bad -assumptions. If you have added any fields which need very careful formatting -(the test does not run validation) or if you have made assumptions such as -"this slice will always have at least 1 element", you may get an error or even -a panic from the `serialization_test`. If so, look at the diff it produces (or -the backtrace in case of a panic) and figure out what you forgot. Encode that -into the fuzzer's custom fuzz functions. Hint: if you added defaults for a field, -that field will need to have a custom fuzz function that ensures that the field is -fuzzed to a non-empty value. - -The fuzzer can be found in `pkg/api/testing/fuzzer.go`. - -## Update the semantic comparisons - -VERY VERY rarely is this needed, but when it hits, it hurts. In some rare -cases we end up with objects (e.g. resource quantities) that have morally -equivalent values with different bitwise representations (e.g. value 10 with a -base-2 formatter is the same as value 0 with a base-10 formatter). The only way -Go knows how to do deep-equality is through field-by-field bitwise comparisons. -This is a problem for us. - -The first thing you should do is try not to do that. If you really can't avoid -this, I'd like to introduce you to our semantic DeepEqual routine. It supports -custom overrides for specific types - you can find that in `pkg/api/helpers.go`. - -There's one other time when you might have to touch this: unexported fields. -You see, while Go's `reflect` package is allowed to touch unexported fields, us -mere mortals are not - this includes semantic DeepEqual. Fortunately, most of -our API objects are "dumb structs" all the way down - all fields are exported -(start with a capital letter) and there are no unexported fields. But sometimes -you want to include an object in our API that does have unexported fields -somewhere in it (for example, `time.Time` has unexported fields). If this hits -you, you may have to touch the semantic DeepEqual customization functions. - -## Implement your change - -Now you have the API all changed - go implement whatever it is that you're -doing! - -## Write end-to-end tests - -This is, sadly, still sort of painful. Talk to us and we'll try to help you -figure out the best way to make sure your cool feature keeps working forever. - -## Examples and docs - -At last, your change is done, all unit tests pass, e2e passes, you're done, -right? Actually, no. You just changed the API. If you are touching an -existing facet of the API, you have to try *really* hard to make sure that -*all* the examples and docs are updated. There's no easy way to do this, due -in part to JSON and YAML silently dropping unknown fields. You're clever - -you'll figure it out. Put `grep` or `ack` to good use. - -If you added functionality, you should consider documenting it and/or writing -an example to illustrate your change. - -Make sure you update the swagger API spec by running: - -```sh -hack/update-swagger-spec.sh -``` - -The API spec changes should be in a commit separate from your other changes. - -## Incompatible API changes - -If your change is going to be backward incompatible or might be a breaking change for API -consumers, please send an announcement to `kubernetes-dev@googlegroups.com` before -the change gets in. If you are unsure, ask. Also make sure that the change gets documented in -`CHANGELOG.md` for the next release. - -## Adding new REST objects - -TODO(smarterclayton): write this. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/api_changes.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/cherry-picks.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/cherry-picks.md deleted file mode 100644 index b589d56c4f8e..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/cherry-picks.md +++ /dev/null @@ -1,70 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/cherry-picks.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Overview - -This document explains cherry picks are managed on release branches within the -Kubernetes projects. - -## Propose a Cherry Pick - -Any contributor can propose a cherry pick of any pull request, like so: - -```sh -hack/cherry_pick_pull.sh upstream/release-3.14 98765 -``` - -This will walk you through the steps to propose an automated cherry pick of pull - #98765 for remote branch `upstream/release-3.14`. - -## Cherry Pick Review - -Cherry pick pull requests are reviewed differently than normal pull requests. In -particular, they may be self-merged by the release branch owner without fanfare, -in the case the release branch owner knows the cherry pick was already -requested - this should not be the norm, but it may happen. - -[Contributor License Agreements](http://releases.k8s.io/HEAD/CONTRIBUTING.md) is considered implicit -for all code within cherry-pick pull requests, ***unless there is a large -conflict***. - -## Searching for Cherry Picks - -Now that we've structured cherry picks as PRs, searching for all cherry-picks -against a release is a GitHub query: For example, -[this query is all of the v0.21.x cherry-picks](https://k8s.io/kubernetes/pulls?utf8=%E2%9C%93&q=is%3Apr+%22automated+cherry+pick%22+base%3Arelease-0.21) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/cherry-picks.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/cli-roadmap.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/cli-roadmap.md deleted file mode 100644 index 8eb59e3b1f46..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/cli-roadmap.md +++ /dev/null @@ -1,44 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/cli-roadmap.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes CLI/Configuration Roadmap - -See github issues with the following labels: -* [area/app-config-deployment](https://k8s.io/kubernetes/labels/area/app-config-deployment) -* [component/CLI](https://k8s.io/kubernetes/labels/component/CLI) -* [component/client](https://k8s.io/kubernetes/labels/component/client) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/cli-roadmap.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/client-libraries.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/client-libraries.md deleted file mode 100644 index 9e41688cf27d..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/client-libraries.md +++ /dev/null @@ -1,56 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/client-libraries.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Kubernetes API client libraries - -### Supported - - * [Go](http://releases.k8s.io/HEAD/pkg/client/) - -### User Contributed - -*Note: Libraries provided by outside parties are supported by their authors, not the core Kubernetes team* - - * [Java (OSGI)](https://bitbucket.org/amdatulabs/amdatu-kubernetes) - * [Java (Fabric8)](https://github.com/fabric8io/fabric8/tree/master/components/kubernetes-api) - * [Ruby](https://github.com/Ch00k/kuber) - * [Ruby](https://github.com/abonas/kubeclient) - * [PHP](https://github.com/devstub/kubernetes-api-php-client) - * [PHP](https://github.com/maclof/kubernetes-client) - * [Node.js](https://github.com/tenxcloud/node-kubernetes-client) - * [Perl](https://metacpan.org/pod/Net::Kubernetes) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/client-libraries.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/coding-conventions.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/coding-conventions.md deleted file mode 100644 index ac3d353f4a2c..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/coding-conventions.md +++ /dev/null @@ -1,43 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/coding-conventions.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Coding style advice for contributors - - Bash - - https://google-styleguide.googlecode.com/svn/trunk/shell.xml - - Go - - https://github.com/golang/go/wiki/CodeReviewComments - - https://gist.github.com/lavalamp/4bd23295a9f32706a48f - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/coding-conventions.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/collab.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/collab.md deleted file mode 100644 index 624b3bcbb168..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/collab.md +++ /dev/null @@ -1,78 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/collab.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# On Collaborative Development - -Kubernetes is open source, but many of the people working on it do so as their day job. In order to avoid forcing people to be "at work" effectively 24/7, we want to establish some semi-formal protocols around development. Hopefully these rules make things go more smoothly. If you find that this is not the case, please complain loudly. - -## Patches welcome - -First and foremost: as a potential contributor, your changes and ideas are welcome at any hour of the day or night, weekdays, weekends, and holidays. Please do not ever hesitate to ask a question or send a PR. - -## Code reviews - -All changes must be code reviewed. For non-maintainers this is obvious, since you can't commit anyway. But even for maintainers, we want all changes to get at least one review, preferably (for non-trivial changes obligatorily) from someone who knows the areas the change touches. For non-trivial changes we may want two reviewers. The primary reviewer will make this decision and nominate a second reviewer, if needed. Except for trivial changes, PRs should not be committed until relevant parties (e.g. owners of the subsystem affected by the PR) have had a reasonable chance to look at PR in their local business hours. - -Most PRs will find reviewers organically. If a maintainer intends to be the primary reviewer of a PR they should set themselves as the assignee on GitHub and say so in a reply to the PR. Only the primary reviewer of a change should actually do the merge, except in rare cases (e.g. they are unavailable in a reasonable timeframe). - -If a PR has gone 2 work days without an owner emerging, please poke the PR thread and ask for a reviewer to be assigned. - -Except for rare cases, such as trivial changes (e.g. typos, comments) or emergencies (e.g. broken builds), maintainers should not merge their own changes. - -Expect reviewers to request that you avoid [common go style mistakes](https://github.com/golang/go/wiki/CodeReviewComments) in your PRs. - -## Assigned reviews - -Maintainers can assign reviews to other maintainers, when appropriate. The assignee becomes the shepherd for that PR and is responsible for merging the PR once they are satisfied with it or else closing it. The assignee might request reviews from non-maintainers. - -## Merge hours - -Maintainers will do merges of appropriately reviewed-and-approved changes during their local "business hours" (typically 7:00 am Monday to 5:00 pm (17:00h) Friday). PRs that arrive over the weekend or on holidays will only be merged if there is a very good reason for it and if the code review requirements have been met. Concretely this means that nobody should merge changes immediately before going to bed for the night. - -There may be discussion an even approvals granted outside of the above hours, but merges will generally be deferred. - -If a PR is considered complex or controversial, the merge of that PR should be delayed to give all interested parties in all timezones the opportunity to provide feedback. Concretely, this means that such PRs should be held for 24 -hours before merging. Of course "complex" and "controversial" are left to the judgment of the people involved, but we trust that part of being a committer is the judgment required to evaluate such things honestly, and not be -motivated by your desire (or your cube-mate's desire) to get their code merged. Also see "Holds" below, any reviewer can issue a "hold" to indicate that the PR is in fact complicated or complex and deserves further review. - -PRs that are incorrectly judged to be merge-able, may be reverted and subject to re-review, if subsequent reviewers believe that they in fact are controversial or complex. - - -## Holds - -Any maintainer or core contributor who wants to review a PR but does not have time immediately may put a hold on a PR simply by saying so on the PR discussion and offering an ETA measured in single-digit days at most. Any PR that has a hold shall not be merged until the person who requested the hold acks the review, withdraws their hold, or is overruled by a preponderance of maintainers. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/collab.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/developer-guides/vagrant.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/developer-guides/vagrant.md deleted file mode 100644 index f451d755b3c7..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/developer-guides/vagrant.md +++ /dev/null @@ -1,382 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/developer-guides/vagrant.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Getting started with Vagrant - -Running kubernetes with Vagrant (and VirtualBox) is an easy way to run/test/develop on your local machine (Linux, Mac OS X). - -### Prerequisites - -1. Install latest version >= 1.6.2 of vagrant from http://www.vagrantup.com/downloads.html -2. Install one of: - 1. The latest version of Virtual Box from https://www.virtualbox.org/wiki/Downloads - 2. [VMWare Fusion](https://www.vmware.com/products/fusion/) version 5 or greater as well as the appropriate [Vagrant VMWare Fusion provider](https://www.vagrantup.com/vmware) - 3. [VMWare Workstation](https://www.vmware.com/products/workstation/) version 9 or greater as well as the [Vagrant VMWare Workstation provider](https://www.vagrantup.com/vmware) - 4. [Parallels Desktop](https://www.parallels.com/products/desktop/) version 9 or greater as well as the [Vagrant Parallels provider](https://parallels.github.io/vagrant-parallels/) -3. Get or build a [binary release](../../../docs/getting-started-guides/binary_release.md) - -### Setup - -By default, the Vagrant setup will create a single master VM (called kubernetes-master) and one node (called kubernetes-minion-1). Each VM will take 1 GB, so make sure you have at least 2GB to 4GB of free memory (plus appropriate free disk space). To start your local cluster, open a shell and run: - -```sh -cd kubernetes - -export KUBERNETES_PROVIDER=vagrant -./cluster/kube-up.sh -``` - -The `KUBERNETES_PROVIDER` environment variable tells all of the various cluster management scripts which variant to use. If you forget to set this, the assumption is you are running on Google Compute Engine. - -If you installed more than one Vagrant provider, Kubernetes will usually pick the appropriate one. However, you can override which one Kubernetes will use by setting the [`VAGRANT_DEFAULT_PROVIDER`](https://docs.vagrantup.com/v2/providers/default.html) environment variable: - -```sh -export VAGRANT_DEFAULT_PROVIDER=parallels -export KUBERNETES_PROVIDER=vagrant -./cluster/kube-up.sh -``` - -Vagrant will provision each machine in the cluster with all the necessary components to run Kubernetes. The initial setup can take a few minutes to complete on each machine. - -By default, each VM in the cluster is running Fedora, and all of the Kubernetes services are installed into systemd. - -To access the master or any node: - -```sh -vagrant ssh master -vagrant ssh minion-1 -``` - -If you are running more than one nodes, you can access the others by: - -```sh -vagrant ssh minion-2 -vagrant ssh minion-3 -``` - -To view the service status and/or logs on the kubernetes-master: - -```console -$ vagrant ssh master -[vagrant@kubernetes-master ~] $ sudo systemctl status kube-apiserver -[vagrant@kubernetes-master ~] $ sudo journalctl -r -u kube-apiserver - -[vagrant@kubernetes-master ~] $ sudo systemctl status kube-controller-manager -[vagrant@kubernetes-master ~] $ sudo journalctl -r -u kube-controller-manager - -[vagrant@kubernetes-master ~] $ sudo systemctl status etcd -[vagrant@kubernetes-master ~] $ sudo systemctl status nginx -``` - -To view the services on any of the nodes: - -```console -$ vagrant ssh minion-1 -[vagrant@kubernetes-minion-1] $ sudo systemctl status docker -[vagrant@kubernetes-minion-1] $ sudo journalctl -r -u docker -[vagrant@kubernetes-minion-1] $ sudo systemctl status kubelet -[vagrant@kubernetes-minion-1] $ sudo journalctl -r -u kubelet -``` - -### Interacting with your Kubernetes cluster with Vagrant. - -With your Kubernetes cluster up, you can manage the nodes in your cluster with the regular Vagrant commands. - -To push updates to new Kubernetes code after making source changes: - -```sh -./cluster/kube-push.sh -``` - -To stop and then restart the cluster: - -```sh -vagrant halt -./cluster/kube-up.sh -``` - -To destroy the cluster: - -```sh -vagrant destroy -``` - -Once your Vagrant machines are up and provisioned, the first thing to do is to check that you can use the `kubectl.sh` script. - -You may need to build the binaries first, you can do this with `make` - -```console -$ ./cluster/kubectl.sh get nodes - -NAME LABELS STATUS -kubernetes-minion-0whl kubernetes.io/hostname=kubernetes-minion-0whl Ready -kubernetes-minion-4jdf kubernetes.io/hostname=kubernetes-minion-4jdf Ready -kubernetes-minion-epbe kubernetes.io/hostname=kubernetes-minion-epbe Ready -``` - -### Interacting with your Kubernetes cluster with the `kube-*` scripts. - -Alternatively to using the vagrant commands, you can also use the `cluster/kube-*.sh` scripts to interact with the vagrant based provider just like any other hosting platform for kubernetes. - -All of these commands assume you have set `KUBERNETES_PROVIDER` appropriately: - -```sh -export KUBERNETES_PROVIDER=vagrant -``` - -Bring up a vagrant cluster - -```sh -./cluster/kube-up.sh -``` - -Destroy the vagrant cluster - -```sh -./cluster/kube-down.sh -``` - -Update the vagrant cluster after you make changes (only works when building your own releases locally): - -```sh -./cluster/kube-push.sh -``` - -Interact with the cluster - -```sh -./cluster/kubectl.sh -``` - -### Authenticating with your master - -When using the vagrant provider in Kubernetes, the `cluster/kubectl.sh` script will cache your credentials in a `~/.kubernetes_vagrant_auth` file so you will not be prompted for them in the future. - -```console -$ cat ~/.kubernetes_vagrant_auth -{ "User": "vagrant", - "Password": "vagrant" - "CAFile": "/home/k8s_user/.kubernetes.vagrant.ca.crt", - "CertFile": "/home/k8s_user/.kubecfg.vagrant.crt", - "KeyFile": "/home/k8s_user/.kubecfg.vagrant.key" -} -``` - -You should now be set to use the `cluster/kubectl.sh` script. For example try to list the nodes that you have started with: - -```sh -./cluster/kubectl.sh get nodes -``` - -### Running containers - -Your cluster is running, you can list the nodes in your cluster: - -```console -$ ./cluster/kubectl.sh get nodes - -NAME LABELS STATUS -kubernetes-minion-0whl kubernetes.io/hostname=kubernetes-minion-0whl Ready -kubernetes-minion-4jdf kubernetes.io/hostname=kubernetes-minion-4jdf Ready -kubernetes-minion-epbe kubernetes.io/hostname=kubernetes-minion-epbe Ready -``` - -Now start running some containers! - -You can now use any of the cluster/kube-*.sh commands to interact with your VM machines. -Before starting a container there will be no pods, services and replication controllers. - -```console -$ cluster/kubectl.sh get pods -NAME READY STATUS RESTARTS AGE - -$ cluster/kubectl.sh get services -NAME LABELS SELECTOR IP(S) PORT(S) - -$ cluster/kubectl.sh get rc -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -``` - -Start a container running nginx with a replication controller and three replicas - -```console -$ cluster/kubectl.sh run my-nginx --image=nginx --replicas=3 --port=80 -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -my-nginx my-nginx nginx run=my-nginx 3 -``` - -When listing the pods, you will see that three containers have been started and are in Waiting state: - -```console -$ cluster/kubectl.sh get pods -NAME READY STATUS RESTARTS AGE -my-nginx-389da 1/1 Waiting 0 33s -my-nginx-kqdjk 1/1 Waiting 0 33s -my-nginx-nyj3x 1/1 Waiting 0 33s -``` - -You need to wait for the provisioning to complete, you can monitor the minions by doing: - -```console -$ sudo salt '*minion-1' cmd.run 'docker images' -kubernetes-minion-1: - REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE - 96864a7d2df3 26 hours ago 204.4 MB - kubernetes/pause latest 6c4579af347b 8 weeks ago 239.8 kB -``` - -Once the docker image for nginx has been downloaded, the container will start and you can list it: - -```console -$ sudo salt '*minion-1' cmd.run 'docker ps' -kubernetes-minion-1: - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - dbe79bf6e25b nginx:latest "nginx" 21 seconds ago Up 19 seconds k8s--mynginx.8c5b8a3a--7813c8bd_-_3ffe_-_11e4_-_9036_-_0800279696e1.etcd--7813c8bd_-_3ffe_-_11e4_-_9036_-_0800279696e1--fcfa837f - fa0e29c94501 kubernetes/pause:latest "/pause" 8 minutes ago Up 8 minutes 0.0.0.0:8080->80/tcp k8s--net.a90e7ce4--7813c8bd_-_3ffe_-_11e4_-_9036_-_0800279696e1.etcd--7813c8bd_-_3ffe_-_11e4_-_9036_-_0800279696e1--baf5b21b -``` - -Going back to listing the pods, services and replicationcontrollers, you now have: - -```console -$ cluster/kubectl.sh get pods -NAME READY STATUS RESTARTS AGE -my-nginx-389da 1/1 Running 0 33s -my-nginx-kqdjk 1/1 Running 0 33s -my-nginx-nyj3x 1/1 Running 0 33s - -$ cluster/kubectl.sh get services -NAME LABELS SELECTOR IP(S) PORT(S) - -$ cluster/kubectl.sh get rc -NAME IMAGE(S) SELECTOR REPLICAS -my-nginx nginx run=my-nginx 3 -``` - -We did not start any services, hence there are none listed. But we see three replicas displayed properly. -Check the [guestbook](../../../examples/guestbook/README.md) application to learn how to create a service. -You can already play with scaling the replicas with: - -```console -$ ./cluster/kubectl.sh scale rc my-nginx --replicas=2 -$ ./cluster/kubectl.sh get pods -NAME READY STATUS RESTARTS AGE -my-nginx-kqdjk 1/1 Running 0 13m -my-nginx-nyj3x 1/1 Running 0 13m -``` - -Congratulations! - -### Testing - -The following will run all of the end-to-end testing scenarios assuming you set your environment in `cluster/kube-env.sh`: - -```sh -NUM_MINIONS=3 hack/e2e-test.sh -``` - -### Troubleshooting - -#### I keep downloading the same (large) box all the time! - -By default the Vagrantfile will download the box from S3. You can change this (and cache the box locally) by providing a name and an alternate URL when calling `kube-up.sh` - -```sh -export KUBERNETES_BOX_NAME=choose_your_own_name_for_your_kuber_box -export KUBERNETES_BOX_URL=path_of_your_kuber_box -export KUBERNETES_PROVIDER=vagrant -./cluster/kube-up.sh -``` - -#### I just created the cluster, but I am getting authorization errors! - -You probably have an incorrect ~/.kubernetes_vagrant_auth file for the cluster you are attempting to contact. - -```sh -rm ~/.kubernetes_vagrant_auth -``` - -After using kubectl.sh make sure that the correct credentials are set: - -```console -$ cat ~/.kubernetes_vagrant_auth -{ - "User": "vagrant", - "Password": "vagrant" -} -``` - -#### I just created the cluster, but I do not see my container running! - -If this is your first time creating the cluster, the kubelet on each node schedules a number of docker pull requests to fetch prerequisite images. This can take some time and as a result may delay your initial pod getting provisioned. - -#### I changed Kubernetes code, but it's not running! - -Are you sure there was no build error? After running `$ vagrant provision`, scroll up and ensure that each Salt state was completed successfully on each box in the cluster. -It's very likely you see a build error due to an error in your source files! - -#### I have brought Vagrant up but the nodes won't validate! - -Are you sure you built a release first? Did you install `net-tools`? For more clues, login to one of the nodes (`vagrant ssh minion-1`) and inspect the salt minion log (`sudo cat /var/log/salt/minion`). - -#### I want to change the number of nodes! - -You can control the number of nodes that are instantiated via the environment variable `NUM_MINIONS` on your host machine. If you plan to work with replicas, we strongly encourage you to work with enough nodes to satisfy your largest intended replica size. If you do not plan to work with replicas, you can save some system resources by running with a single node. You do this, by setting `NUM_MINIONS` to 1 like so: - -```sh -export NUM_MINIONS=1 -``` - -#### I want my VMs to have more memory! - -You can control the memory allotted to virtual machines with the `KUBERNETES_MEMORY` environment variable. -Just set it to the number of megabytes you would like the machines to have. For example: - -```sh -export KUBERNETES_MEMORY=2048 -``` - -If you need more granular control, you can set the amount of memory for the master and nodes independently. For example: - -```sh -export KUBERNETES_MASTER_MEMORY=1536 -export KUBERNETES_MINION_MEMORY=2048 -``` - -#### I ran vagrant suspend and nothing works! - -`vagrant suspend` seems to mess up the network. It's not supported at this time. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/developer-guides/vagrant.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/development.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/development.md deleted file mode 100644 index 7049590fe3ca..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/development.md +++ /dev/null @@ -1,353 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/development.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Development Guide - -# Releases and Official Builds - -Official releases are built in Docker containers. Details are [here](http://releases.k8s.io/HEAD/build/README.md). You can do simple builds and development with just a local Docker installation. If want to build go locally outside of docker, please continue below. - -## Go development environment - -Kubernetes is written in [Go](http://golang.org) programming language. If you haven't set up Go development environment, please follow [this instruction](http://golang.org/doc/code.html) to install go tool and set up GOPATH. Ensure your version of Go is at least 1.3. - -## Git Setup - -Below, we outline one of the more common git workflows that core developers use. Other git workflows are also valid. - -### Visual overview - -![Git workflow](git_workflow.png) - -### Fork the main repository - -1. Go to https://k8s.io/kubernetes -2. Click the "Fork" button (at the top right) - -### Clone your fork - -The commands below require that you have $GOPATH set ([$GOPATH docs](https://golang.org/doc/code.html#GOPATH)). We highly recommend you put Kubernetes' code into your GOPATH. Note: the commands below will not work if there is more than one directory in your `$GOPATH`. - -```sh -mkdir -p $GOPATH/src/github.com/GoogleCloudPlatform/ -cd $GOPATH/src/github.com/GoogleCloudPlatform/ -# Replace "$YOUR_GITHUB_USERNAME" below with your github username -git clone https://github.com/$YOUR_GITHUB_USERNAME/kubernetes.git -cd kubernetes -git remote add upstream 'https://k8s.io/kubernetes.git' -``` - -### Create a branch and make changes - -```sh -git checkout -b myfeature -# Make your code changes -``` - -### Keeping your development fork in sync - -```sh -git fetch upstream -git rebase upstream/master -``` - -Note: If you have write access to the main repository at k8s.io/kubernetes, you should modify your git configuration so that you can't accidentally push to upstream: - -```sh -git remote set-url --push upstream no_push -``` - -### Commiting changes to your fork - -```sh -git commit -git push -f origin myfeature -``` - -### Creating a pull request - -1. Visit http://github.com/$YOUR_GITHUB_USERNAME/kubernetes -2. Click the "Compare and pull request" button next to your "myfeature" branch. - -### When to retain commits and when to squash - -Upon merge, all git commits should represent meaningful milestones or units of -work. Use commits to add clarity to the development and review process. - -Before merging a PR, squash any "fix review feedback", "typo", and "rebased" -sorts of commits. It is not imperative that every commit in a PR compile and -pass tests independently, but it is worth striving for. For mass automated -fixups (e.g. automated doc formatting), use one or more commits for the -changes to tooling and a final commit to apply the fixup en masse. This makes -reviews much easier. - -## godep and dependency management - -Kubernetes uses [godep](https://github.com/tools/godep) to manage dependencies. It is not strictly required for building Kubernetes but it is required when managing dependencies under the Godeps/ tree, and is required by a number of the build and test scripts. Please make sure that ``godep`` is installed and in your ``$PATH``. - -### Installing godep - -There are many ways to build and host go binaries. Here is an easy way to get utilities like `godep` installed: - -1) Ensure that [mercurial](http://mercurial.selenic.com/wiki/Download) is installed on your system. (some of godep's dependencies use the mercurial -source control system). Use `apt-get install mercurial` or `yum install mercurial` on Linux, or [brew.sh](http://brew.sh) on OS X, or download -directly from mercurial. - -2) Create a new GOPATH for your tools and install godep: - -```sh -export GOPATH=$HOME/go-tools -mkdir -p $GOPATH -go get github.com/tools/godep -``` - -3) Add $GOPATH/bin to your path. Typically you'd add this to your ~/.profile: - -```sh -export GOPATH=$HOME/go-tools -export PATH=$PATH:$GOPATH/bin -``` - -### Using godep - -Here's a quick walkthrough of one way to use godeps to add or update a Kubernetes dependency into Godeps/_workspace. For more details, please see the instructions in [godep's documentation](https://github.com/tools/godep). - -1) Devote a directory to this endeavor: - -```sh -export KPATH=$HOME/code/kubernetes -mkdir -p $KPATH/src/k8s.io/kubernetes -cd $KPATH/src/k8s.io/kubernetes -git clone https://path/to/your/fork . -# Or copy your existing local repo here. IMPORTANT: making a symlink doesn't work. -``` - -2) Set up your GOPATH. - -```sh -# Option A: this will let your builds see packages that exist elsewhere on your system. -export GOPATH=$KPATH:$GOPATH -# Option B: This will *not* let your local builds see packages that exist elsewhere on your system. -export GOPATH=$KPATH -# Option B is recommended if you're going to mess with the dependencies. -``` - -3) Populate your new GOPATH. - -```sh -cd $KPATH/src/k8s.io/kubernetes -godep restore -``` - -4) Next, you can either add a new dependency or update an existing one. - -```sh -# To add a new dependency, do: -cd $KPATH/src/k8s.io/kubernetes -go get path/to/dependency -# Change code in Kubernetes to use the dependency. -godep save ./... - -# To update an existing dependency, do: -cd $KPATH/src/k8s.io/kubernetes -go get -u path/to/dependency -# Change code in Kubernetes accordingly if necessary. -godep update path/to/dependency -``` - -5) Before sending your PR, it's a good idea to sanity check that your Godeps.json file is ok by re-restoring: `godep restore` - -It is sometimes expedient to manually fix the /Godeps/godeps.json file to minimize the changes. - -Please send dependency updates in separate commits within your PR, for easier reviewing. - -## Hooks - -Before committing any changes, please link/copy these hooks into your .git -directory. This will keep you from accidentally committing non-gofmt'd go code. - -```sh -cd kubernetes/.git/hooks/ -ln -s ../../hooks/pre-commit . -``` - -## Unit tests - -```sh -cd kubernetes -hack/test-go.sh -``` - -Alternatively, you could also run: - -```sh -cd kubernetes -godep go test ./... -``` - -If you only want to run unit tests in one package, you could run ``godep go test`` under the package directory. For example, the following commands will run all unit tests in package kubelet: - -```console -$ cd kubernetes # step into the kubernetes directory. -$ cd pkg/kubelet -$ godep go test -# some output from unit tests -PASS -ok k8s.io/kubernetes/pkg/kubelet 0.317s -``` - -## Coverage - -Currently, collecting coverage is only supported for the Go unit tests. - -To run all unit tests and generate an HTML coverage report, run the following: - -```sh -cd kubernetes -KUBE_COVER=y hack/test-go.sh -``` - -At the end of the run, an the HTML report will be generated with the path printed to stdout. - -To run tests and collect coverage in only one package, pass its relative path under the `kubernetes` directory as an argument, for example: - -```sh -cd kubernetes -KUBE_COVER=y hack/test-go.sh pkg/kubectl -``` - -Multiple arguments can be passed, in which case the coverage results will be combined for all tests run. - -Coverage results for the project can also be viewed on [Coveralls](https://coveralls.io/r/GoogleCloudPlatform/kubernetes), and are continuously updated as commits are merged. Additionally, all pull requests which spawn a Travis build will report unit test coverage results to Coveralls. - -## Integration tests - -You need an [etcd](https://github.com/coreos/etcd/releases/tag/v2.0.0) in your path, please make sure it is installed and in your ``$PATH``. - -```sh -cd kubernetes -hack/test-integration.sh -``` - -## End-to-End tests - -You can run an end-to-end test which will bring up a master and two nodes, perform some tests, and then tear everything down. Make sure you have followed the getting started steps for your chosen cloud platform (which might involve changing the `KUBERNETES_PROVIDER` environment variable to something other than "gce". - -```sh -cd kubernetes -hack/e2e-test.sh -``` - -Pressing control-C should result in an orderly shutdown but if something goes wrong and you still have some VMs running you can force a cleanup with this command: - -```sh -go run hack/e2e.go --down -``` - -### Flag options - -See the flag definitions in `hack/e2e.go` for more options, such as reusing an existing cluster, here is an overview: - -```sh -# Build binaries for testing -go run hack/e2e.go --build - -# Create a fresh cluster. Deletes a cluster first, if it exists -go run hack/e2e.go --up - -# Create a fresh cluster at a specific release version. -go run hack/e2e.go --up --version=0.7.0 - -# Test if a cluster is up. -go run hack/e2e.go --isup - -# Push code to an existing cluster -go run hack/e2e.go --push - -# Push to an existing cluster, or bring up a cluster if it's down. -go run hack/e2e.go --pushup - -# Run all tests -go run hack/e2e.go --test - -# Run tests matching the regex "Pods.*env" -go run hack/e2e.go -v -test --test_args="--ginkgo.focus=Pods.*env" - -# Alternately, if you have the e2e cluster up and no desire to see the event stream, you can run ginkgo-e2e.sh directly: -hack/ginkgo-e2e.sh --ginkgo.focus=Pods.*env -``` - -### Combining flags - -```sh -# Flags can be combined, and their actions will take place in this order: -# -build, -push|-up|-pushup, -test|-tests=..., -down -# e.g.: -go run hack/e2e.go -build -pushup -test -down - -# -v (verbose) can be added if you want streaming output instead of only -# seeing the output of failed commands. - -# -ctl can be used to quickly call kubectl against your e2e cluster. Useful for -# cleaning up after a failed test or viewing logs. Use -v to avoid suppressing -# kubectl output. -go run hack/e2e.go -v -ctl='get events' -go run hack/e2e.go -v -ctl='delete pod foobar' -``` - -## Conformance testing - -End-to-end testing, as described above, is for [development -distributions](writing-a-getting-started-guide.md). A conformance test is used on -a [versioned distro](writing-a-getting-started-guide.md). - -The conformance test runs a subset of the e2e-tests against a manually-created cluster. It does not -require support for up/push/down and other operations. To run a conformance test, you need to know the -IP of the master for your cluster and the authorization arguments to use. The conformance test is -intended to run against a cluster at a specific binary release of Kubernetes. -See [conformance-test.sh](http://releases.k8s.io/HEAD/hack/conformance-test.sh). - -## Testing out flaky tests - -[Instructions here](flaky-tests.md) - -## Regenerating the CLI documentation - -```sh -hack/run-gendocs.sh -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/development.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/faster_reviews.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/faster_reviews.md deleted file mode 100644 index d28e9b55447c..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/faster_reviews.md +++ /dev/null @@ -1,214 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/faster_reviews.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# How to get faster PR reviews - -Most of what is written here is not at all specific to Kubernetes, but it bears -being written down in the hope that it will occasionally remind people of "best -practices" around code reviews. - -You've just had a brilliant idea on how to make Kubernetes better. Let's call -that idea "FeatureX". Feature X is not even that complicated. You have a -pretty good idea of how to implement it. You jump in and implement it, fixing a -bunch of stuff along the way. You send your PR - this is awesome! And it sits. -And sits. A week goes by and nobody reviews it. Finally someone offers a few -comments, which you fix up and wait for more review. And you wait. Another -week or two goes by. This is horrible. - -What went wrong? One particular problem that comes up frequently is this - your -PR is too big to review. You've touched 39 files and have 8657 insertions. -When your would-be reviewers pull up the diffs they run away - this PR is going -to take 4 hours to review and they don't have 4 hours right now. They'll get to it -later, just as soon as they have more free time (ha!). - -Let's talk about how to avoid this. - -## 1. Don't build a cathedral in one PR - -Are you sure FeatureX is something the Kubernetes team wants or will accept, or -that it is implemented to fit with other changes in flight? Are you willing to -bet a few days or weeks of work on it? If you have any doubt at all about the -usefulness of your feature or the design - make a proposal doc or a sketch PR -or both. Write or code up just enough to express the idea and the design and -why you made those choices, then get feedback on this. Now, when we ask you to -change a bunch of facets of the design, you don't have to re-write it all. - -## 2. Smaller diffs are exponentially better - -Small PRs get reviewed faster and are more likely to be correct than big ones. -Let's face it - attention wanes over time. If your PR takes 60 minutes to -review, I almost guarantee that the reviewer's eye for details is not as keen in -the last 30 minutes as it was in the first. This leads to multiple rounds of -review when one might have sufficed. In some cases the review is delayed in its -entirety by the need for a large contiguous block of time to sit and read your -code. - -Whenever possible, break up your PRs into multiple commits. Making a series of -discrete commits is a powerful way to express the evolution of an idea or the -different ideas that make up a single feature. There's a balance to be struck, -obviously. If your commits are too small they become more cumbersome to deal -with. Strive to group logically distinct ideas into commits. - -For example, if you found that FeatureX needed some "prefactoring" to fit in, -make a commit that JUST does that prefactoring. Then make a new commit for -FeatureX. Don't lump unrelated things together just because you didn't think -about prefactoring. If you need to, fork a new branch, do the prefactoring -there and send a PR for that. If you can explain why you are doing seemingly -no-op work ("it makes the FeatureX change easier, I promise") we'll probably be -OK with it. - -Obviously, a PR with 25 commits is still very cumbersome to review, so use -common sense. - -## 3. Multiple small PRs are often better than multiple commits - -If you can extract whole ideas from your PR and send those as PRs of their own, -you can avoid the painful problem of continually rebasing. Kubernetes is a -fast-moving codebase - lock in your changes ASAP, and make merges be someone -else's problem. - -Obviously, we want every PR to be useful on its own, so you'll have to use -common sense in deciding what can be a PR vs what should be a commit in a larger -PR. Rule of thumb - if this commit or set of commits is directly related to -FeatureX and nothing else, it should probably be part of the FeatureX PR. If -you can plausibly imagine someone finding value in this commit outside of -FeatureX, try it as a PR. - -Don't worry about flooding us with PRs. We'd rather have 100 small, obvious PRs -than 10 unreviewable monoliths. - -## 4. Don't rename, reformat, comment, etc in the same PR - -Often, as you are implementing FeatureX, you find things that are just wrong. -Bad comments, poorly named functions, bad structure, weak type-safety. You -should absolutely fix those things (or at least file issues, please) - but not -in this PR. See the above points - break unrelated changes out into different -PRs or commits. Otherwise your diff will have WAY too many changes, and your -reviewer won't see the forest because of all the trees. - -## 5. Comments matter - -Read up on GoDoc - follow those general rules. If you're writing code and you -think there is any possible chance that someone might not understand why you did -something (or that you won't remember what you yourself did), comment it. If -you think there's something pretty obvious that we could follow up on, add a -TODO. Many code-review comments are about this exact issue. - -## 5. Tests are almost always required - -Nothing is more frustrating than doing a review, only to find that the tests are -inadequate or even entirely absent. Very few PRs can touch code and NOT touch -tests. If you don't know how to test FeatureX - ask! We'll be happy to help -you design things for easy testing or to suggest appropriate test cases. - -## 6. Look for opportunities to generify - -If you find yourself writing something that touches a lot of modules, think hard -about the dependencies you are introducing between packages. Can some of what -you're doing be made more generic and moved up and out of the FeatureX package? -Do you need to use a function or type from an otherwise unrelated package? If -so, promote! We have places specifically for hosting more generic code. - -Likewise if FeatureX is similar in form to FeatureW which was checked in last -month and it happens to exactly duplicate some tricky stuff from FeatureW, -consider prefactoring core logic out and using it in both FeatureW and FeatureX. -But do that in a different commit or PR, please. - -## 7. Fix feedback in a new commit - -Your reviewer has finally sent you some feedback on FeatureX. You make a bunch -of changes and ... what? You could patch those into your commits with git -"squash" or "fixup" logic. But that makes your changes hard to verify. Unless -your whole PR is pretty trivial, you should instead put your fixups into a new -commit and re-push. Your reviewer can then look at that commit on its own - so -much faster to review than starting over. - -We might still ask you to clean up your commits at the very end, for the sake -of a more readable history. - -## 8. KISS, YAGNI, MVP, etc - -Sometimes we need to remind each other of core tenets of software design - Keep -It Simple, You Aren't Gonna Need It, Minimum Viable Product, and so on. Adding -features "because we might need it later" is antithetical to software that -ships. Add the things you need NOW and (ideally) leave room for things you -might need later - but don't implement them now. - -## 9. Push back - -We understand that it is hard to imagine, but sometimes we make mistakes. It's -OK to push back on changes requested during a review. If you have a good reason -for doing something a certain way, you are absolutely allowed to debate the -merits of a requested change. You might be overruled, but you might also -prevail. We're mostly pretty reasonable people. Mostly. - -## 10. I'm still getting stalled - help?! - -So, you've done all that and you still aren't getting any PR love? Here's some -things you can do that might help kick a stalled process along: - - * Make sure that your PR has an assigned reviewer (assignee in GitHub). If - this is not the case, reply to the PR comment stream asking for one to be - assigned. - - * Ping the assignee (@username) on the PR comment stream asking for an - estimate of when they can get to it. - - * Ping the assignee by email (many of us have email addresses that are well - published or are the same as our GitHub handle @google.com or @redhat.com). - -If you think you have fixed all the issues in a round of review, and you haven't -heard back, you should ping the reviewer (assignee) on the comment stream with a -"please take another look" (PTAL) or similar comment indicating you are done and -you think it is ready for re-review. In fact, this is probably a good habit for -all PRs. - -One phenomenon of open-source projects (where anyone can comment on any issue) -is the dog-pile - your PR gets so many comments from so many people it becomes -hard to follow. In this situation you can ask the primary reviewer -(assignee) whether they want you to fork a new PR to clear out all the comments. -Remember: you don't HAVE to fix every issue raised by every person who feels -like commenting, but you should at least answer reasonable comments with an -explanation. - -## Final: Use common sense - -Obviously, none of these points are hard rules. There is no document that can -take the place of common sense and good taste. Use your best judgment, but put -a bit of thought into how your work can be made easier to review. If you do -these things your PRs will flow much more easily. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/faster_reviews.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/flaky-tests.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/flaky-tests.md deleted file mode 100644 index 36f893834e5a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/flaky-tests.md +++ /dev/null @@ -1,103 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/flaky-tests.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Hunting flaky tests in Kubernetes - -Sometimes unit tests are flaky. This means that due to (usually) race conditions, they will occasionally fail, even though most of the time they pass. - -We have a goal of 99.9% flake free tests. This means that there is only one flake in one thousand runs of a test. - -Running a test 1000 times on your own machine can be tedious and time consuming. Fortunately, there is a better way to achieve this using Kubernetes. - -_Note: these instructions are mildly hacky for now, as we get run once semantics and logging they will get better_ - -There is a testing image `brendanburns/flake` up on the docker hub. We will use this image to test our fix. - -Create a replication controller with the following config: - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: flakecontroller -spec: - replicas: 24 - template: - metadata: - labels: - name: flake - spec: - containers: - - name: flake - image: brendanburns/flake - env: - - name: TEST_PACKAGE - value: pkg/tools - - name: REPO_SPEC - value: https://k8s.io/kubernetes -``` - -Note that we omit the labels and the selector fields of the replication controller, because they will be populated from the labels field of the pod template by default. - -```sh -kubectl create -f ./controller.yaml -``` - -This will spin up 24 instances of the test. They will run to completion, then exit, and the kubelet will restart them, accumulating more and more runs of the test. -You can examine the recent runs of the test by calling `docker ps -a` and looking for tasks that exited with non-zero exit codes. Unfortunately, docker ps -a only keeps around the exit status of the last 15-20 containers with the same image, so you have to check them frequently. -You can use this script to automate checking for failures, assuming your cluster is running on GCE and has four nodes: - -```sh -echo "" > output.txt -for i in {1..4}; do - echo "Checking kubernetes-minion-${i}" - echo "kubernetes-minion-${i}:" >> output.txt - gcloud compute ssh "kubernetes-minion-${i}" --command="sudo docker ps -a" >> output.txt -done -grep "Exited ([^0])" output.txt -``` - -Eventually you will have sufficient runs for your purposes. At that point you can stop and delete the replication controller by running: - -```sh -kubectl stop replicationcontroller flakecontroller -``` - -If you do a final check for flakes with `docker ps -a`, ignore tasks that exited -1, since that's what happens when you stop the replication controller. - -Happy flake hunting! - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/flaky-tests.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/getting-builds.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/getting-builds.md deleted file mode 100644 index bcb981c44723..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/getting-builds.md +++ /dev/null @@ -1,60 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/getting-builds.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Getting Kubernetes Builds - -You can use [hack/get-build.sh](http://releases.k8s.io/HEAD/hack/get-build.sh) to or use as a reference on how to get the most recent builds with curl. With `get-build.sh` you can grab the most recent stable build, the most recent release candidate, or the most recent build to pass our ci and gce e2e tests (essentially a nightly build). - -```console -usage: - ./hack/get-build.sh [stable|release|latest|latest-green] - - stable: latest stable version - release: latest release candidate - latest: latest ci build - latest-green: latest ci build to pass gce e2e -``` - -You can also use the gsutil tool to explore the Google Cloud Storage release bucket. Here are some examples: - -```sh -gsutil cat gs://kubernetes-release/ci/latest.txt # output the latest ci version number -gsutil cat gs://kubernetes-release/ci/latest-green.txt # output the latest ci version number that passed gce e2e -gsutil ls gs://kubernetes-release/ci/v0.20.0-29-g29a55cc/ # list the contents of a ci release -gsutil ls gs://kubernetes-release/release # list all official releases and rcs -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/getting-builds.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/git_workflow.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/git_workflow.png deleted file mode 100644 index e3bd70da02c847da17fa1d645e81d22be9fce0bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90004 zcmZs@by!th&_29r1O%iT0g*U_bazR2r_$XZjS5oI-5}E49fEXscefx72foeoKF|C9 z{`lrP7l*UYUcs!rX3fk!Hz7(2QZG@6PyhgUDg9nt1pwe@0RYwv85X?qXY?!?e1mfq zl~zMWMqXT3TmwH6x=3ibsM?#kxPNdm1=jh{6oJAa8D*LJ*V3`Ks zO{sqkHcHgc*~@YXUqiz*?_Xa~%GSakL#fpG5CA((j;Z^thVq?1ad4eSwfX6Zkb$rh z!1MOY_3pXVdcRkLv!}<&H4k)SH`5Q1A^=kq8T|1P>&fHeAABflgqD)oQg@WusV z{d12fG7IT|=!<{vNs92rONo6Jwz@ZTbcIb#o)@zb5fMLs{da z;}~Z8mYrgjsO^!TS2@`E$@xR4yVViXg~Ir3)QVo~--%g=8Tah+Y)dz70(+)CYi`9A zx;rAKH7*)jHJhVNY0=66IRvF@R5-%xLcp&l?kFRxFQi{0U8 zn0@o&b^g=DP+d|I0kFTn@43yZy|>;K6dMym%lw~iSfzY-4E;CDI- z&RhSd_>}bE|5+)~;Qg@%rT^bfXF+An%~@zE2sr(>N<)HfUzQFItXiGY8Q5uPXt=np zCvs)qqJ96jvp!?-b}1%~@c#x%=9{8Q{J(*Y#Q%K?MCF32{&&!7=C{w%Q<3(6*Ya}M zm@fXTcS%c2v#Z4Y*E`AW_MG9|w%&j0jN%b>-WrL&zdo(6qicV93_5LpTJI(IdpPUO z^lk82ToQS8{vP{BQ$= zGStQ$w}4l-QWu^Goky3(udYi)#)|n*huz;QO%X z8Sse!e~3!^(e1)PEo+w=9y%0Fn@8&M^F^#e^|j2){hJx`G0_ ze{e8zt5XVPZ2 zm}&3Tlc~A6bx#4fE{_v~q910&Yuef$g!)82sD0> zMf=`7^@3Yf%CEAn&dte*RhQwfyv9|gRCz|2U-ee~gnL4B`Ig|B^&HU+i-=Eap2gYt(=Ifs+L-6O+uDb+FD;@Nw<7!@Qe zQ91wX-?6Dr$Je5o%vZBQP@ej>wqGq2uSEM=uHa8+*C`f{ZEgYI35y6)MfJkA%tmiF!rQTBVTXt@C?auJuods@Vj|xDm^XLw^tvA+#-a!qvd)te zXMR-N-t&0?N4jP{f$Z*qwn?moCIby+b@1(vqeLjUlbn4fz)jX=s*{!YY*_W0TrA7P zl4rqgsz$degi!Tc_YS0kwOclbTW+{yfrp>t4-{0BOY4}TeGg_S;%d2fj}N!3SG%A} zRH;KTtLOeKlIFx0jJNb$xKxdSdnKokp73&Y7iI4DH))1v#9b8TM<$!uB}2zg0BFDN zH=fi|_$a}3T9u0mj?nlKP-ZX{{~gnLUEpl1$={(4>(bRYwh@tQykU&a!qU=IiuED1 zYY`k|2R$gNm*_NvhUKmLWZ{i=4=676H3 zn-{8GxUN4Meex+AV~D365Y1nUjkbGZ$6T7dAB@b>oU70|UitD#RoV2!0ols?nK!!kB}SDA_CK)~e6Y4;OEv>7Y(W%t09B3NkWxx4W70 zZHCJhl;`^Z%)uuU&wpW@7m7Crz;dU!`U(6;=(0o zo7XnmdZt8LPA)BMa@76V0($-|OgUKxj}pS;R3+`(TQm#_I$DaYvtOHnEWdK9=O`Bz z7r7QvZ3<%@Jdwbs3*kD^dyf2|J)=vZQF6Z~uuQw!Y&eDEZG@45g{`fzxvR62BZoUf z04Ay1l_E5>>)x*>h1_nn&F|?kR&k`J7&fSDdy!{I2DHTI7FAU>cmmDd8@6V}5;bk> z)>lE)ip_E~8lrt^gisA%fkZK}@Vo6UE(&4U;uz?!{_f?LXiQNw0V)^Ol>)f2g$2&P zk8iyBkSuBCzsMs~RL2I_)zwxCaibb0eI!?reI@R=$V;V;Kc7G zFRw0Dz*`s}S5{SJ!_Ut=jT_KC!eD29MG^TL{d)EYqtsUBuOxV|p^lFJ_r77&Oji=EcOSI3} zZXv`%R`!r2ND?`j)W=yhBt;F6=+!I7{fXR0ZfMID^gX%I$$KwUimmbAWm4A##CIDV zI&BuMC4nsNZ%o#2ypEI8v#m4n8qXx`9`MCX!mI!8-+7&#-cWKqhTWHq<;M?INW=|p z4r^NkMD4T94o&lF7sSS5*9I#1Gi3$vSAiR-x=}3Y=V=(WTY^$7W3qfo!bMgoxzEIu zP#S$v@~W28Ffo>Pl37gf!h_kq-ZyZfh2(O4jflev>KHwuO#X8~XY_4k`*R?AV-S^@(zX9R_2GlF=Puo@oE$omrR= z5Pl)$Zz*?Jt;M}n3J{!|uW+kipdlQNr@iOn%1$fv!5GF zgT5;$-?r}{wPVlj9P8j6Q#zBC5?ozzPBoLkCwGoo)oATbZwlAVFawlFJygJzMKqe& zaH}r6#op!XsWs|mj_>tGn4LFxvF5IOthLJ7588a9%+AF~k;BJN^k)?jU#|dHnZidIN?k{kFoO%D}sKmOwEuY6>3@bOdOAPtM zDs+3lb=Mriyt>D)$FFWzFRFCw3K$u~)0Ca>A4bOFWUV?_-sQhGg{wUh8u@1u#Nnva z&LM?!kgbrw7X5fQj~vhjA8s%f4enmLCcdfu-b}gAtjUB2btFXsTCkY(7+RgqnEj%( zV8t|779UTkNr4OunYKUMhF%LPUMWHl!InoJpj6`3#O9^v>|$Hki(B`G(UNd)^VMIa zhqH)*&c#i`cC z&XU1N)&=7;Y~lvbDQja36UV`OG z*G&&t<1Je`e+(=U<^%lhWxaj#9}PxZJk}qi=01qtmYSYo1=o_J zoX-O^=@6(Hy2NYh>rb=2qAjy!rb>Ru#7S@cBLoRg6I;%O*iIR-o>03l0up~st?Mk*cT z20SeC)z7{Wee1uj!|9c)L+F+BKDZ>~?U`o(KSvT4mIs={a(ym-GG8!)Tn>GC3+g9C z5A7sA9ML{1lfA`3QlP>cibA#j<9M)*a;kRSUbBr9#qaJHA}1takw_?`iRZ&%cWOGY z)_5#0BNEb974|gC#b{V9)PCDu_X1u~u|*&`&O8^1HFpR7BTSA=TnIt>YkW`by%Y{> zxmTzZCT;~~1{yF1Fk~}35#Sb}RepL059lpYOJYkxr0PaEF5J_zv+)$QBW7Pa?C!ij zUH*2Bb>8}fQ|FRENsa1nfI@#}V7u}OIhmwLJUMx!VGN8tNd&#;ZBiN`O**rz-r7mVPAA=g3cU@uq58&J@qi75uhhuzylqU0~ z#5xV@uuwfdQV6m0vub8f6w+J{tm2&i7Huoh@T29KBxqFV!$xftW%Y zx0mepS(vk}7>94N#~C!Cup`#<=#mPKRd=6jP=gp&OhLV_Qc+_$$m5FwmCsbKth9Pq@!F$65+THHF@zj!)(hT4X9y!E3DJ*$aBzhobNsiQ3 z1%*42(akfcb22&CI^{Px=frm~!1toZrHq?(nejg%q1KlQ>?FHQ&|0*drWEW(YXQH8 zo(7-M{4QL!@G5R5L5G{|WfIEaX(40)Tp)7L;!KYDTt@lHwK-i}d!@U^lLu%d$bNlG zRMN4@jiR46K3&#?)FJx1V$&%NA&o`XVzK(VG||xOUE!~+B83cXO|8Fn%e}9D?7J_J z7s;W@H_Qm07wfoIA8ZX5m7Kfd?!P+05VEn~XR)-9zE8rcJ=h7H3P3#{Fb>83^<`Z& zuaKMb&nNZKq+PaxBFI27WMDKzRw(x47)x3HPL!ru|K4EVk}c!lqJB2N20rS18JwxR z6j{S;8Li?)8$&+v`zlqSjv{;FyqL zM%9}WE&g#{7>si9%S0(z*-*8dcI){jneOn;(0cQUC9Z0jxF(G{cdvtCmP;{P^J+>i z6=jA<0bL?aRz^(c=07(PrQ4parA4t^#R_;qxV|oL#w4E_T=P3k5iksTM5ecowg!ix zyW0vpkM}Z?hKPB^g|wSeJ-gbty!d|s98bFTn+`*=J98^KgUo~yxf+Ze+`?7LP~+IH5go4jUWU(t`K z{*AW=F2iyflBcSA*1Ll3r4?&Uc^ZYv-WpBQgD6HsE2#2p7D^mr3GM0fB7rc{9QbYH zQ}i66%rZGGCH`dHpQ9d5=Z2fCKSColFM*}q`tAO53#<5)g+uxM(;G&_8u>!yMK<1x z$0nBnHrco^pV(EQRpm?h>%dO5t9}E%*U@COlb*-YOg6=LdH0>SEm@{O)`0w&&nrZ` zI4+nk@mMfm9KbNR+ma4sZGUY2;01TrMt=$by@?sATgw6`4sCZX4o+2kz;W*HfQMwg z_yJR&)^cc!J$tRpaNu8Uk-;(bcpv9Zk03Ig5S4hGLK|pZ-gKNE zxsskepR*i2;J@=l?3|D7g~!|Y0)xiy@*<>M-2;m_GV-M=YN@~#mI1}DUipqtu_4` zNOZ>`Cr87rYUN{)D0WLomtU+w7LH{o9mo<3_UcI<`jokSg{Nmt9N8x(?Mng>O!4;m zc)y)q6*Kx(Tc=G%8wO-IDOwZG$vmW6dOC^*li{z9-5xSx@z z{mf^F>G-Rwq3DA`*vl1h>_g^%HPH5Sb97pbNtc{Si;zy1N6k@cg}LTQrkWNU#jp4r=!^+oAV!jiNH zbpCi(>EC*6y7?;E>8%2g#RjQ&1B81U1*p@(ZP5ooM~IxMee-KS^y0N3pl;{VZwt*q zT`77mL~zhFl`>e1k7#m)Q3VTJu5DyhMMl1#ccN*J3;1dW4(4WkB)|ijN+t1U3HZ>c z@SIc@!^VjYVF}mPoCX4-9X(sAj(j#unArH6{$`XmL8%)C#q@cAq(_A=k)+t3vqjR< z$wXYe>k5k(NW!W;9A6I?2;jKRAvHik_wm?Ew1gN^q}ckl*jL0x7#4P*pNiTcN@P98 z*ZuajX)znHv%n+KK0>t=Zy)%*HOz9I!4Uu&Y{E$REV*Z+8Oe{xJ(W^TbV7-0w6>^S zv-i94<4y-7ProlTGhW@8PmPJ2b@FUME2x3CVJ~OnjoUi|M9@6mIah^8=e7bQeu*R( zL+t27&gf5KKe2%wCmC;^Qj}Y*A2=>e>_r<@OhDblGE9@aLqbd+cRyNW8@KRI4&U!_ z5e98E0IvSKOK4J!rRI;Myp19<09{w*!3A!UX%+k4PET#3-$;sVOhfete8-vKE4rCO z9-CHrrfzH?C9GJj3B$v7nX|5^+c_o}0KUvpy6m*nYM-lbW3E? zXH^zAF_5i=SrGie<^aFq{0JZ zZne%28XA(WwdpVwb6v82!mt%@Ui)5;y!Wg04`#Q-9tf-9->;fq@kfH8yl+`n(& zGe(*;b;~%AfRePd+otUn36i~uf&s|M=R=}3$=OkaKtijQi~ik2CW8j2!9H)b0J)6q z1NTwy8pjt|t;v}cXYq+(tk%$=Ywp@0 zXi;#St?tj_jO`Bv;iN7HSVlJ8ID8=(d`$aJsUw*Zy3w(AY9#23MRX3XQ?@HxPV>A| zNsl9HA)ascOtKXe6sGWG-sahzA_BVOlwHhBiKpzs0q|LF@<15vybM2{6;!VkhSo&MUS*pb}HGI5rJIxoQJ^xYY0IYm4X(7+iXSF@|{)6lVyA+eQaMJ$L!6s27|8Uhh+QOPAPl$~(Nj=1h z_p>QQ8GGvue+~PCjP4D0q@zBD!4Z$eghSs$uYS5mt9e>bMnXVl)c0!-;vU_$C(lLS z91Q5&8)kuDJ#J_38&(qD)xPWZmZIAmvNU&)^}#Yz%S?8#`spaI7m_lWFB@NQ`=he* zl|L9l8t@E9%jWfTj*|g*3nxSdI!PJmldhEP2@b4qlI7V8D;Zwja>a^#fr_fi^fg#s zZ=|wzpN_uxIOXL=fev6zr#igjninY?A**qA0`B_?cNzjTF-*<>wXo=97&e%&fRPa~ zhnZdI#{=&8!k0OT?6A_DH`ysf`Ai-(9%~@VRM5}O&ELaiOg+`z=hz}Ri-|H}Oe(_k zwFfL>k7|^t2Y!G2N6-dctHurv4u1Z8qZ%l_LzVHho)}5kFg^Nq#`BPfcUKUeDG?Qr zYyY)fRV-oppkUw?_()GD?5CfM0*FIslE}g#TI*mWr&{xP{&2OKA5btWOJ2YI7}e*?=Yb za<-VDYkK+xn2ul8h=)Cg87cJ2Zxb?}#ZIeik}7dn6dM~`9v3&+kAa`khhczzdbp7g z7p525%YO25DpR46BZR5~PNvp}2r+2{ArRtF0Zi=`SZUl#lfl1Ji%u+NZwqVMo8p=8 zePvu`C>C0Rh5$s&W~gId_ExwpZ}b)xPt|1%6~~hi@VOGJre+qySM>2s1rBy4$cM>R zofd89k96;+A@4CKZr8&3n^*jH2+i3iD1z9-+d#c7JkJ_g*x9oh?iw3&UV|aT?|NrU zfota2`52Y4`7Y;qtc@tYs$#Z7HT5Mam@5pj4=Lw@1!;1bbA%c{8tN#C<6N^#^9uPs z?SBQ55@J2%H;>qkWpHL8eX~VXCKbip+Y7o9ynnBKHRCivBSN@l2IH0a`oj*A%(1Dq zM$XeBneibfoTjQN7fc7^oL54OBzVrHeK6EZP{8xN0im)Wj8sYzRzK}KscsMTw=>I( zFP6H8d2twV7hqcDaS5Ye+;+K-_Z%LrBZcXvDE1`R8qvw5yuJeMHCY_Zg zLKt35?9kft8o0B1fLrSHsupRjX4^!m%}+YN>b2evftXi>uj|&o?3XeshVvUtz;%4k zwd$x=^~~7(Au|PHQ8bjQbtbYOJj1|9?Oen6C%ceSO z({M&yMAJk&FSns>--6?Vz$)F2k6{9pzo-&j%Pba?%Ojy)|J4FaFj*Q&d+CdmG`!Y0 zMGpMcg)P5upRc|Yjw08*H0i*r=Bcy$Kyoc`YTiSv``eU=y*?E8x+5Nb@?xXfeqW_` zv0i?xG!0X9$lhV^DdQ8IjL5Ek>r>@~?z*5yY0-fA(*R2=2EvK~^yuR!Y!;1>l!@EM zjlQ2zDa#V>wXO)28(+qq7Ul0ZKjow25WX-1UH9CH>(QFy)@l})AX%X z@W5E(_Ph<~|55jcbyj0#;)^lQ;}^)BKA7DvKJtx>+1zl#|1EBrVMLzU`$1bdwsu9r+d2q{-9gh9>Dx8IuC>r3iNO`cyKhjUu6+h)1H! zrMSA+$6YAvwMA#VI9h>aN}+H&shKJ`{GPE)W$B0nv~Tm)@uwN2?j#`sdPsXEV$;5epxi=s5)IBQnWOHY+lbDb&vq>We zU-9wMv+_;H(mH?VHyQU#^gW1|W;y4#Yi%%Y*`p^C z4iyNEIh1XX`J1Ndff-KJ!B5Ux2mkm`f`Wp1C?P|NvQYiTq1KUs%}OtNou;7jA7Bzj zZ>tOrg|UMBJ?DB!^>bN*hd6l5<>N6X&KXq{Gr6ulmfS6Np^mV$*5U@iUh5OUH$dFK zjZr3Sv1GF`xqx^Mh!U}=zA?#IlW`-DvY%-@*edMgtV@9b`Hv!cEV zV*V2&nLF+4^wu-M?8|eBNbtTAiWSxj1bs$7%DiR$kh+4P?46@cUbcw;YL2h>P?zvKe)j94_QVhNk9WJP4kWl9JNL zhkpC^Pr(NNTTp!gL!@0CI$B`l3p$}HDp;k<{}hLub7$dz`TzX4@qv=!;{T-n!RwKr zO?W}E^CLEpm*-iM>Heqk<0Iv4d)t6T5WZdx*y`g)(BXToRp~PhQW--iZ`Y!9TXu$lTRlhWJ zU^04fRz_iZWM%S}3F2EyyVE-1o30YhIxTeY^+&2tm!I{C#fu9KmzjiAdunpEkh6K=WB)6JYj~-ymjKv9FRo z>=P6)m%+gcVtsC;qL|!We-;qyo20r1{g=4Flmy9S>;|YnARf@b)D~TiaMR3-is#6F zedozbBn$alUGDm$nBJgCpGt_B+55sNgiwWRz%4Lu1r|VVxrRrI0f6zLO~*$1C)kCM6h`L{HrcW1ri2w(Dt zNl}wctpZDalKQWOSBKUMe1dlKJ2arj^chtOH*;2~l+sHxF1v9~^(;9m%qZ!bQW+iY zZp!(D;J+rqw^Fc@xG>;EaE*IwV&1}8*Zx@TfP3Fwr>c=jMBv&)DE~rg1R*0FGnsLw zaZHzXF~buT=(Rpfo><;s@z|+8DZ{e-gEzl2HkGP`C*FOpH>AVDOf=j8o2_+ZqSP|L zY%=W>a`DxyAWR`Xzhr^c-Te~r6dla**!LU!t;npd9*Qc;)_c*=x^vkl`5r`N6VlU5 z8^vBbi{um)O~Pv7;qPRp)@jSsA^wFpdvS}oLgfmE`7Ni7bhcjVFr1^fCey&g(q;2F z4F?qt%fziB7**0WzB}aD6ze(G{Ed5j4ePI)&qmfg?lZ~daA|SD!2yUw8KCfXc2aHs zW&yJ+nGb4>15+>~tQihrHq=OfT|8Ie?ztQq9H18_b<^{qd}C6hgXgz%A^5m}<^vDK zH4_nFC`G#?JPUA?N6Fp!J27=TS*hS$tmlZKH)>Sxfz8VD7OYF7q3M0DCaYG4sL1fb zIB1gf|EW(k5)%==h}d0*!hWF+yC9!%p=FJ*xn5Y~k1V_1i9ZGMm#<) zcYo%ujHRg_~_gKD@?;V*g%6I4UhhSFNUnq_KF8|<{^DyQ6gyhWe z;x-kIi$7#D#>L1JPnkmc zR`~J^@BH_nq6=EBPt&S3Y4f(5HZ&@aN}c@yi>0WT2Sh5WU!9B9pWeEBB4Ydpe^6R` zwxt@WVm}*u1dR`RI(7ZO*0*=D8$4t90R+aI7B2xtQ^_6db)CZsAL zlSiX!#8XmY*uEA0Kpef=ynN6bRU)N}u*uY<8^*@GM29g?rt9W@!^PCGbXcOg1)fFKD^Z#)0(m^2E&CVh1@0D-JRmhb!!N19 z7Y(&^E}ibu<>Q6*qUv=U7r#VsU3Fn5-}%jPXo^CIKCcj>N%R?E*?8xKC912F6Ig4@ zBEcPC*}TvRbeu<74!>H^$3FCHDMDHkY-d#Tl~667nliAL@$0o`$+DFRU&t6g%UYI; zerw9cUhi-GzqrOTiUQjZPu_I6_ti^ZZZO0LTt2{jK4a_ea;=Q~F_-N#t}!zcZ}`a~ zQ!AV`US0$t#$5)r%o;>JbWGiU6>=-0W?h;LU13uxTQ)IO$J&K?Cyd_U&8lUr#Vz%} zFmZQCcSpz%+OUMCDN`bJ{Cd#Ce9iF!iP z0@AnXOKLJL%x39E>7uAN(3rD{1f$VeD*W``t9`FAG&AqLHzO{_|Y`vQ0_y$ z%=AIq#^d?VK=;o$S8E*c(a3A8O86Z3#^{!6$vg>kHk0ie$g1FoZ-EnoU~l8VREGSQ zI(hBxJ%2aQB$k*C|&!~ZfzI8wfDwZm_8igmS>H7HWU5Ddpw9;I* zQiNLnmjK~N%5kAa6~A2nZ`UgJA{DF*JXh%gzAM?fQVV7$Q@DjdBGBKGEE^&ht$^1A zmLR84&59FDzlS9FvxT=3t4655gmv(cIy?KNM6uXmL8nt&ePpwcCjq3GSgLmkQ1Fc$ z)9u5*{v>ALNUJr3F1^bX51$X2_<94VHI7r)&)YUztEk$+I4u1=n^*JW6xu@3IA-9B zedF;dt$w>#feTI}rX~fO51Rh1+S(e#03t^-KamMr4>({UT)1BWfYjQ%OT|nbb|8BHBeyju9c3}sHHHZsXT)Tgi)d5 zci_Et+|t!r^e+T6@QqOYl?^gRJ{qdtb?~ocP%y`wt`N50zaI}t=RHpNQcpjD@vVue zcE{;B5QgynYY8AM(7;`Av`M8>x75!}y`Du3)FdnuO>zWV(zO&J_EMQVqRBrWYdZ*D znV^GP|3Cs*fKldGf680+L)SwtQoj7X%##aBIoa`-j6na%*X+)9E8@`}Dpm^lCW5th z@?77Z2CNTMH*u{xcut1qW6M3}s{M8wWvPGl&eP8uZF?0WhNb<5+o~le4Z&DUPH}o` zZSv~#$+vSe;f8_K84K+S3%!EmcVCZ;_?c!ac-}i3KkfMor~9q**r2BE%rsUt0}MYa zU)_-s+rX;S@xmFErK?`R3G2#-V1cKb_|L~bvWM!9bQ!>yo?b4jzkx)*DWbo*OPT@d zam*UFNCbw5f_qVw9c;zRkPD7I;}$id9Rz>NKFtCc;T+R)k-Hq6ybtuC1x@NHDYgPS zOUECZfDs9?dlF z6#)6;0uLOIu|Iy3+lTwR76(~H8OJbAnw_yVj_h)dsi@{cH3%Ei_UJZiyr%>R_WYs( zt(uDHPhrb`)kvZ~M@NT8n%(g}POWqTbR+ije^w8?jzKg1NG!HdreF{CD8oepQbGq^ z?E;;KWSWHqZ;jH zsgk~(suVK!v8fDzc}Gx|31;RRba7o2-m$v~yEYO6cUAS}QN)5J)3E+^)n(+L@zxlt zwqVhcJ|~ad^RWlgaOc+K7gz3+0jOsvUm>sEJ+dG)y4f66vo|+PZ4;&Aj*r-v!aMW) z5bevOq%YYg5#SM&yDw=gA&(8n9jA4H2aZR@=Z;B_G$mUJg(faKZjvjr(2i;4>oSzY zLEn+yfMw@W8H7)_jgv%-&q3W%1y1Qg4CNL*J;oUpYwo~O+?PT6nv5m*rAa{zJif3YPl2t4u;|)LFZJ@eMayfEM?y5B~8LY2NbtyhoQtfVx-QEr*E-ms> z4f7y*wj4&bYzF3*Onzx6^Li1FvFsKH?fS~&=-fdiKbupZ)tR=r5S(i-EBc_?T9>I| zb*SQ`E4q?#(1NCSy?oAZt7ak%`PybC;ag2f4$S@%7_*l((ee*y4II8Gl;l-sSva%S zw_0B4p_GDrm1i$<3dCEAXAfKdvId4)HF|y#OCX~r)9-Qq4TZo;gJ{2#+6)Y%Dc3hq z&3%pQM%iWk-kI?r&%CK%t~6K$;}$x0Ua2Iq^3I~_&loS~el1#$TTTnq=-ZMb8}N$! z&C1)l8G)SrW8Ye70k5qgxBq=K3+qyNEdu4TB|NL^d zew8T05${&)4Da%$g15?*A0m0u3qcXY`5lu>F5G2!5^tzw6%6RB{8sx^X5Y`RXm9IZ zlwFB5NJD00`BU<@K9Oe@`@5>jnyQwP9VZE~``3Kfz6Pqw1|u14=BmBlx3F3q+bjn{ z%0_M%=?@Tpoq2_Wh7OaGlJa}PQ|yXlja*paT=^U&4B)Dqv0m~HdsBx`8|Y{q5ixd8 zVZYV^5fBw4mOI0D(Db|57#IMt`3~?m?lpvWu$eE6X=?U-SwD5L%IO)PtkETJp6;q2 z`+l!sFgJq)7^>Cl77sILwe8N|j=z1;f7%~T?nbYO34EKR>53R5svRlr*Zp0Gc~$iN z`;K`Jx=WgXoUM+U=vTaoKVbuQMJnjNZj~pSLnZa@GCurA`Occ3IdU&`;42@Tuct92@Q6a2+og{mx`Q|GkH>Jn3?u>;)Tk{D8 zc#kuftjn!vXWNcFQ5X97aS3snQ@8P21tX8W8ja}Jf4@D-F#b;-E0UDhP& z$hbKiuyFbNy3K)y+`q1}&nSZhC@OXp0M-~B*I*NV#E$?D#VsT6t7eM}ERX;s=2!S@ zy!Xw3|G7@_ugfsY<{9=g&+HjkdkVlM!GMF6!dBP!wcoN%xqcy4Se}+l9l~E23+7&P zj)>IN6}m{~eRx1b>*pDrdj2^)jKkc1)|9~Yg+UXA`d7O-bh48$py1GI;pIyDVkj|o z?#Sftnm%hVs-y1RT6{y9o))FdQ9L4qmAfvM_$h)z;E z^5O{dP#9_!#pc$_<;^RIN@zIxSCX#&M13xmD!WJ01hK3~UdNkG*c(o(+|nqXdkB22i6;x4pVQ9n3zkgl!Yv=l992gKjE#Dx8K@ z(LC{I-W0(;1PLIK^+E?^%ip~q7WPgsXpOL>_bo4wUCueEaUych1!n#bG5Q+RNDjh| z|CbNcF5uCA&nl?!aS~2q1wGoNwEf6J($Vol_>Y<&+>mRfzEo!2_DU*|@fSc?Ypn6t zp!O&|4DFI~T>sQl>5nS1@iwPQlIoe*RRVQKU~0I(5~j;Jir1Eha0^*j8{|Atj3>ZtBm0sdBXN3V*Qf>%_Bts0(~ts!@BaI3jtWga?(=`-c(AuHMkP-$ zuz|4|3Ax4n9Mgiq>8f@Rh1m;fRqa-b}tjAeOI&5_-~Yva%N79GjI zYl>fUp_G6HJyV%d9lPuIRq0PM;HJn?j)$DUmWf2}6ESMf`w2ciA_ZYZCh>tG0|jc# zWvIpcUqC7GZT!xx8^)?TnTkHtc&%(w1_?t}_rmdpCW&qr;LjHr2Nozrg=T*`m6yl}WM zl&B_P!U3z#kJuYM!Sd0fva+(mLXc^}uC5laTa#Nb#) zlWWk3_=l@UOI-IH*h!{q_B8bPjG6hg&9+_W&<)bCd_s(t$BclbiK)4BKTKu}94|5I zm-7h>8Odtclk>O>W7|cHxMf@3M*FUQq($xbZxT=>Xuc15-uYjKe#Pw z+vfe44<1GTJe_B_5nfEJQ=>3mszWJ;zU#cD>-=3%&1Kkd9I^I$tCB)~5q{!EAvv=6 za`9$<9<>a9m7y~k1&0xZky*>lniqX{dv0rG7za&E;!^s-Jzv9fA&c9g+V+!Gs3ATy zvUeh+I*L6dg8h}-%pW~ZieQW?-IsiKCpH^pE^05~jwaW6?_ThnBOb5SUc;8dd~shy zq3UUN5V~+IXfl1~71sN@j9TxA@ez6qhr| z>m(oo!P){#soyu_AI2S@_NRi6e$w?qI*r3l>YmYxbikqKJEoHdSmn}WbU)E|J&JyW zs%SArq|x6n+OF=o_o2RJn(>^t~@A5;UxdMYrb^7Tk) zqs?t!o_no$n7l-bnEq(aEUo1v>ZUrKTebYnS>1WLYorD@O$PmslkU)o@h|*O(m4}W z%s9Da6UWCL`t0?x$h{Pw+;Tv8+?S_5|DH9z{7e6c;l-!?inSk0t8=!DsE!X(iM*_l z-3XtWd9=Rs%c8G#Lre}ULt|u3F{DNEAK*(hNeUtF!~QzsSNz3gbV`74(LL**w=n*? zR;uq#FGx4!*)<#P!%HH?+zzG@Sg(hMF=a9w%q98@O*lDi4M+8n^;+D2o7MX`y`_FF z+(IDS+_KXgJ$x*x%DSmhC1BMdVSX(x;GBQ{IT^biLca(Wwq(5Jo~1Hl2T>L&v%bNt?uolaT@U#$4ZFI=2$S(pn+qM>t?L3je!S4J zaQXgs2+QP8oV6fhn+zK)aLwV{ZTS*$K6yB(q1+lSNBdVO$m=1w3QJ;Bw4XrkI6Bc| zg}J#OZTIG}tfm3iKfai&^tD`{Nw~ZS&!mBA{BweWmnqTgCru>N0N6q=deo_`PEotj z@33&7E?T<|i5G|PY~n^2NTaIv9K#Kdk|s?3Vt0YMvB;CeMF!fc$ao2Zs;$kpN!OpF zLjI2`P!Y`EQ{oe&AR|hJ>l50teB$AW!Tarv$>5%jWS_}iZWdV?r0sUqFqP}gb0@eb zDtL7($4ly?iY=}&OAyJJDvLKJ1AvN%$3F|XIK1y2{WR*R4oRRb_1YIDJ79>xb zS;^4tT?;MsF#CRpX#npo!E6k zAdt9hBg67vEr22SwFo$5+TiV^rE`!lvd7dv8M@5$J&?eiha3cE*8}?Vvp}Ml>N9aX z59IDyonV4o*?0wAkoEK|$&?g-U#eDK2X4KobyH`>V7 zu|>q&+hV>Su)Lg+M0bA2>4>yymey9)%)Apye!~u~KVrTYSj2xM%H%io2 zA95VC1BRkM7fV5}w>kM*CdKi`5G;#G9W&RUIxQbBmwLeoIUn9Hl7dA5Jd*JRfjMCP zR*z(m3Z6_K$-ZTQ)l3Q>GOLt@q~5bKN5C%EjcA^kK{L<6VsUY?wUreXSXqRJ2a@x^ zYCZ*j%SY(JAJ|K=I?vlKW?5JUd90}ZcdL+4ruje{-4PD=HyG}RE^82SmyR>{OuxF- zc+@Orp^NEO`HH1aJE=8^c%o8m+MJmy;D8=AKlAg68D~Kkt*Pk_#IgQS<_-;5`PD62 zJoLoKWd)UuKJ}ZiJ`wIa%Heum(T=XJuDy?p|MM>ZER*qA*_LrxU_lB6-uY&jIvP;3 zUA7CdiiV|930iHFL-j>LCc|Rx7y*gYEz%IuOv|o)aSK7BLRwly*`+0e9JzXyw8HhZ`=uS$1EamR_8su~w7m;-Qzhn(f zk-e+;UpLVX%ZKmY$$)T2q)%R|n5ZB_+3~DUx|abBP$1}lkLs~eTNP2M2z8Tq%$D!k z#nLI&J!O_Vpqb1U?~Zn$A~8FL69jJ-Ue0`=8k9sBnQTCm8%bJmhJzJcSJbOl(s@fvpYb4`>t+4nA_`@9`if`^xTYLgj zfr)(7Kw=JK{>f`N{k*SW?nfERhh=L`wG0iljKK(A)rMhXm$H`6#X-MWZt2sVYc&$; zHHbXu`j&EVTvQqqy&44mKepaFEUNE&13e&uw4ih;ARQ{*2qTSjw{#@AC zFgOM7>od#ABjkyfLzsnq?@;$*X=8NU(v_H^)-X^pG*Eft5hJYDu##R%7jJrVw5ND4 zK5C~h;PNy&4``l$)*eKrFM^U+@bHvU^7SeeR(6i&|Y_f4`fO=N36X@tfrSA`kgW-)ROb@{`YQ z46#0$vi|PZR5?Ry6hCX3(8iOrAk|C-^HL~kw@~)o@mqGhxS|oPtIxeV==t0NiFsm} zsRo&x49Wfx20U^vtlE2hIQdiN#51=f)KpFRN5_|+oanby{pxrBmL|TLdS%wJ5ECzv3EFe3SboF4 z?eDX{YbghA5o8gyCtKfi*7MnV%VqpTwossaWZt??KD|29sHbyHNfNxw!M z!~lSxZR3~Jk3U60n`HI7lsSkb002FPnb9;E_113an%ZmMTF>K<|8`_TnOBQVi9<`~kI zJoaCn_+QQTj~Mw3;6NF`U8*yN?9|rkCe1hxZg&E|(73=Ds>+2kf&CxLt=gn=uXu)2 z<9!lv$FW)PQpefFgNJ_Wd;Gvu?%prL=d9rJtd~PP3>$QjOh;WPTZP2A(`T;*d*k(( z#-c17k5>;Bdq>8r-|j-Fe7CLp;3b4O?8k-rP2NmIq2>24r73=rkOH`aOHgPj+jjzS zC3C!Kw=ATMLp<@qS;x6ZA-plvu_^qnUxU(SgDcG&Y-|@kAKxLJ292UhJ8rjg21da6 z0{OW#=>O%}wHs{mxqo5U$h1jof$Q z7s)B@l2g1ox<@?TA~qks;uHN9ummlfmtoFpqZJp3GpHM?ab9(kd?_4ymlU?zg2C;D9AE*&Nf<7uc3#Z(?IJcUS~cTcf|9Jd5V~Pm%ox3h+BHo zY{QR{ve)-y<;HT?ur;x0820|A5=`+-41aux#rxDqr2!pp z=tjvtmq}++leYYp*?)>gm3_}9_<2=DC-KbGqktS*ZRJOIXBC6*FlP@=5qp(=L!81c zeB6hpD0Qdk6+O>xIK+g7WycyK*~#hNW(EId}UvC3KPlJ$o)sM3kbUP{hw9@#ok59hHoK;;g-EQ^9gMlQec)G?{LsqP`5i^l;&5|b!afwkPx%d2C^7N7GB%y^>7ZvF3%7Y{oGPe@6H z39V4=#v#Y6(*1z=c9^tf^Sn+tdo<&QQ>p3a$zPqr543sri(}l2J^#Z=Ap-gKxnkI*kpxnaiNs}a!Fn~b~}#7Ph~&8F-#Y({d_yfRD7vJMBvcp zykq@^n?e4_HXB6d65FwPFHRWk`)TLA&N-63(*|4XW^GLGq~Nlw>!hvM5qR*61M0q0 zw~K4U#}Nd_6kpcbq&7@6!c>s+1b5w=moE~2S9Qr**j6lbOA$Gl+Kqbbb@++--S^Yf zB7^1;w1r25eIFoK)GGF? zz6jo4du}Tq5_0ot+Q+T}-%`CT@Kv+V=ems{!`A4U)RBhY1fj?5$<1gn4Tq!ligj4i z@AR(1C9s#ZU=_>wTvDjtHJ0Bi%^4maU8%T9NeQ2|Mbfycx`j1uW;VeTUWk~B)I&F! z0m-FQFNI%2Qc-);uJI9|iE#}JXzW+|B$C^HX{zjvtcXK)r;FgEeV z-kpD+BWzenmJ}MhdbT}8!siHu&M|%W+}S31r-}MlUhHCTwQ9m?+WF(4wS0=#=?IZ( z+UkV7Uig$0V`wS-9Re$Gt@&$gyzom>{fA1r6^qHU@*jjY%PBnXe_Xv>G_3|QQao$6 zZ=O7QBzV5s2TufmSfzJ|$&U~2b7nL^2}Uc4KajxS$4b~AfVA|>wv?GzY9CqwySbk_ zg*TT{L-0DLDkbAk{ezjfyNRdlXP0xihXn($8rrq~ff1ikn5|-=UZHK(%t&cd%wACg^ua}96#jVt)v^+Bzo ze|`3td;Ns7PiYC^_pT@+*^>b%;!;fbVzVh0?#h{$()Ne|Tb^1$AT>qSV=H!zHb@g{ zuUbDY7UAViFe*7~|9CGZnudgp59+aZbtl#PWHo|I3xzwGx!5dL|KaYzEMH@)m*-?aD|c3-&Aek)smtyyyH!!Lm_znqi|6!@~+b*u|q)-s$YZ( zT^nG>B~n7kS<7*n7o}f&7Y%!yCz`QDdzWhcRqQu{$U8tPLDjr3 z@X?p}Ep{b6r7T4uj)angg3O{-rY93;SLeNJ{fW&y-mYg0I%&`t9TJq&w8oOz3Z@?B z0i1Y`+=ovrlEf~OdFqA4Y&=H3%2sYyzUEH&^rLmxP*-?gV+~^>h9XI59<9D^{}SBM z6e#!QU9iy6*!kkw7trby|kY$~Lebibs#wJ79l_qre2BkBX!gHw(QgS8G{p3`*R}5-4GP*pHsQ-EOsZ(J5u@&QXbDX zku%~yB{*)&&J>UW;vxinGj_dbhP&4!PcF4`xJHw&+}_DI?eQ1x9|!!J-#5~84v%9= zc!U>m?Wws`5uoMharjXwHFVFiejRj$WX zYkPik>1yE6Kkv5kwg#a|Dg3Fj+Z&QO#E<`}rCw0Q#3a2`BI7;d7GHd6Kj8Nuk!#9L z3a`n0NEpcTK3=bOOlnehtR6Gs^*;NRiMbi}_WFU(HnITYW>3dj1kmnPvWXRKxIQE{ zZksL5dO6+91A3=}G8~{E#=E-@_t9qXUgS*(zV<9-$)yw@{05(2Q}>;rgX@;_@_>^b zL=-N1(Gy!Ux_xX;bG5iX?|Vt-*R52dgSd{Sdg^=+&=;tHbt$WA>N?zg6lPGqm_h&~ zoCrg2Bn3MC;mk3DttV?Vx~>IxzZVe=%<&KcErgovR48d?(Kg%2c|?`{-f`)`oc>{e z8t|D-CV90_3?D(pkg;=d{b@%Jv@FT1>(uE0YKy-~A$BMS2Xhe#r^Y*8f#Oj2sHg7Q z=dSI?(hWt7MyglG5bUSV_mv!>`=jw8(x+5DzP+0RA_<;rRf7)nJ|bHswu(d?DV4{_ zVL{+tbPaoPl|f^Dovm6a{{ z4<#EDGuCoN&YkDxS~j@urZ%5n2G=hGY0mR%rOAu@nCGON86|E6qgTXIee!zLC~245 zUa8|gK9eU@R`uSOp>Q*AP;hZX{d$P6;gja+s`={a%4f`kiQA5%ugJUDP} z5h!5eLXo?(9xYf9j;W?Aj)7p9^64`I*MQ^1kCuS3>ag7auN4Xq$k_G@)o+TcGYKP~ zV_U~Z+Igj_Ef>ciOK*wUB^ww#((uVYoV9VGmP>kmGxuZ@-xvS8O^<*(ncrC$NsS1v zW$-M*(6$|Ov2RzfdQ;YIeCVL>aiyA+y4O~lIq+KN5^YgWn(eY={s?B;KRH3{k*`LYi%?%{Op;kWI7$p6Z{1~-`(!S6sf;XY?| zdLyCq+Un`UrmKydT*IrS*iH90XFr8@ecyCq=vknME3U^oH1R;@+QH?m4{?Rx?Pgcn z@uro+QTM$bHjvMed+mrB7>c8RFsPO~j{5ktXu2ubocc0sQ=+>!tJmHrB=@>uiOxi@ znV(_%PUJ5o{J#4(hmVZyehxFval;O0KD=sPXj7v`vbl9)W54deK>^-;-AXZ!?>wB> zAy|K^#d=h7GiB++c!-bvnpS$khaEpKuKH-PuViP7XeqFf`-#UcynLl!$JBl(N#qM@!I(!OB}-k>-_H4%_-js#0@!$0a7GApZfLzpzS{-T|QBc`g!$oP75Dv{p+j`YK?3TRsV5T<7VEuRbeaI(C2~LW(TyV z&+Cgdi|HYxm`&aj#(acU0`T2vI`-f8OL4Hgy?y#+x5 zW<~V0m#0(INUe?w#gj49F!lfi%)5TOc$2yQn#p4%m_LaMn9L5`@WEc1s1nJk<-Ig9RA{?*Z+-&B)Et}mYQ1%)MFhUz5}vuj ztYT|h2siz`DJLJAXn0QH7r!rCen@;SL`m!Xc=sc_7EAM;H0bH}+-7!ty~lEn7NTkbDCObsq_N}A8DlPvV*G1751yKJ zv~o68u$;%J_*EY`orJI&2~FMmsZ8>a4IhL2kUAmK2X#qkj@fII7l~dx-*mA+HLVD= zJ;S$~+&laBTSa`i{-fSaoyB-Q@uQWwa4f?wGk$OjPPOdWJuo_J#iT8iAXBTs9K>tTDI!%J{O;E_Siemmptmj=x0dFsoB_Sh*@ zYLDGqX`_b)>nUEyIf2r6g6r?;AF68uQ4qgo#C%;brDm`CC;Mt$_c`=`8hTF4GkjvZ zI@%NLY-!>N82P5rzyK_(ra%|#5z`F8Ciw!9$l(zsUr(~{Uo5e)rpC;4aT0g5Yc_?9 z5k>Q`=EeP$?$_F!ls?P;(bI6^5^i7E{+`M74ewawX5>zPekE)-ybtc7uI9hEH_Zua z8euXUU)Ci0osv4!N=gpb7PtwzWH26v={?tAKDdwR*MS`{@AIPm%9iyr{k39jB~#WR zpPQ4{O)C{qv;|;xj*GWe7n4OQVE%e3GY!)hX9vj)w%sL1Q3mT&j+A6K2Vt)E0wyv& zm4%gRHAx?=k-_KF0cZhXHu?GXsD5A1GL}YfqyY159H1X7p3CYcD-#R=KaO#cWvcrY{OLXL& zXIJrneNxq7ya>_kM$et}!&=zQWzUVbik6qaO}6x*QAOkaFGOv{h>yod`h#i@M_%^x ztLEKTO@#_Rr?E(XC0PBzmfJggqJhiShNzDPms2rnLgRDgl~>+Q-*lgN*c6Z)%PbiM*N{%N&m@poJ)J0tCkRI6cmfU)qZ$*ZH^v1?G9_$1r?o{h|*uEY&Q8 z65tW2+_dG_&zf2n*#mwN51IrV9zOSNO{o-0^>ueZpiLi@FC<#dB4_M1~gqV!Y(DbM;?6j34`)m*}ui9{*=#ZZ%E!rD%Xpb7n;s+L*^X2n@R zDs;23RWB9J>0xmXaM}5B^5n~7`Rg1V9xa<*Srr}AZ5=m*#4?D>+qIEii%^QY03Bl& zp_bj{!X~~3o~)htR)gf-L`}?RcSxC&VJqw5cyMIg%yeO+;NzfXG31`%cIu8|RH&_< z!_%E{m)PdAk#>r=Bgvf9f=6R6Zu2YEuIm9iNW(}EYXPrr=>4@kAbK3 zXW$bK-Lr|%dHOZ2GUPL~pL%Y;2lY6!I&K7;?7LgL-f-<`U$lVZk3STesjTFS4Ge5} z!4ccL>b!QC6yXI;QjkELo?A#c2)*iiLSvPPJ!Rs#Ap=LbWs=d0H!)J7ok~rH%*;|s^29yX4BSJUYBkBk^+;!m7U3| zinDQZh+HM?1K|)bl4+}X9i@ceGk6|*Y=hJ-)|7!z%`7C=X?_z4Rvo-nV@sA${Gw)>vUtf&BjhW{EuNFW$H3>L)y#eP=y=9rBpqm>|Zs@0ZIw@KuJMfZzdilBaUeAzr}cvvSjf_YOsGwS{khBm`b( z#$jt+4g`Kl8cu#G2MY*dB8aH`T{DkSs=tz@503MyHl2)X1%~jK%LYMo|608NJ1wMF ztI2jgyPDBzdc-*p{et?}l2G%&Y=f)5DsJo2s+TiOz5~fBx zKjMZiF)cu!fvfmaBFJhlfsd~l`fAdozxT;OAt(-0j2mW3u`=&?qu0j7Q(PcL#qhAV zxG-P%XdmMmFTm<+g}yDv+1k5w?wzy!MOkc;Ga=e>L52(n!H2n}w~2f$M2- ze7LHh7Bu+o+~>$xIk1M+(yFH^Gd;xeKlEs1L)h_>5D^{QP+rY~bsJixo)Y}LP?s5} z%QD~P$K*+Pz7_IuQnV2=nxz*oc`$hEXnrdqA2^>&GtFec|?^meWtI zj|&(jBqc8?hFx71AWsNo-&Xyc2anJ?@4TI)B?jO^$?X}zlY=L{)xTz_;;DQ)Pk(%1 zsMqI+ZJcNqM}QwRn1>VJjuf`tnY|7TuzKoL7pRLw_@19yzOhK( z**v2nrzEHLU4t%XM_l6uSph7?hOoQ+qhDz$BMyo~WinUFcxZvB&ElDjQA zY`?kYQy`F)pzwo}9pu@AMfa}z-Bmh4BMyoSKcCa?I@bkafztIH-GvIU%NLHKDzil6 zfy)p)2J~_%hHtLP^Elvy3vBsSaFU<^OGmg00WJW}dMu}prLb2Ml!(c%tBbi%OJoS+ z)ci4RMhXi%kAufDdq_KPw|UonSwxlgBw}K)4D%ZIixt2mqGl)P(j;<&_9#|KZ~r%) zXmcQ80p9wtXTTvyMQIlH_4jkIu^pKh-+^?_AEHTqmSK3=@g=0r!%Y0C-#&rbFIx~Ac`VG|LvyIo6K^NkN}syudmPJoQ6i&tae@8$?B{wFtL^K z6&WpA2P;#CgUw}nN%_8w!Ets^$Qnm%s;yDmryA!vs10?zDRIH5O){ujVF?LSSE*E& zOTWucQjY?=SU-G_ny+5yuXnLx9-#6V@3e9FB@Q?>rW>ov>$q$-+0lM+t zgv3Opl;=r;&?#g7zutN{?&c~$AkY^sE{74EVbC{66Cf{q9p<0s zyNM)G`6=Nw)E$}I!>NfF8yy`RLjgZnuwCaJ6(~q92A&#QW&$w0ihF7|F=(Zuo|?cX z0fC5)%*@zvCxB1r7v-I;=h`m3e5evDXbAEDgeKjaadBPa1R4PF$dN$Mv;N1vUe8|= z;DGA@yl_?DnWo!Rd$xYYrKEZSZsMS&%`kM9?DV}iU4Q@YEysi<*nj__onLHF{&NrQ z0hLAipCbSvD^M)|mem5KM%Q$U%KD}z;m41ENWUOB*8_)0A`QP>&rKD!h7c2VC$sl;pL*2DOAo_cxMW^CD-1YU$6Yn=$&aO6{jtv0#ZQ0S^vx^uIY2Jd+o9YY?P^SqRs$FxD1_H~9< z!bWbKKjH23Dn{kYRK-qTNx69Fjia2J-u7>?d);7sZw?oW7h)8xTBF$V$OFUI5mw(r zOCyjY&8)-OG6v1@J8Xr*v$850Zq4YO1MuEr8i?_w}SnyjqR~p2NB!v-5LHwaNNO zMy0+afz~w?)bDi*kJcs{90y1`ImU4_9wIy*svF<>Xe^^Pa4~?F*)C0^i+={B60BPa z!*{E5t%DrUxLEA6u%YgS&(idmseo0Sr_ishZLilRJdd0>(MNnI`?@rk9@-p2v9rPsY(Tm~gwiry>C!*tKd3y(fVj=`y3|32Cue;qd>ft0c9)ev zy@1{)Jx2exFhJ`cLOAnZh`BA2SSMtgo&}f2Mp6+xBO3Y0qs%uj6kf`Oy56OVuUQSOT?hS*YSATo#Q+8AN zQ9>mnu`@LJYPW(~gqPk}{h*lZ)AFsp`#7!OqJR8h{FFb{lK8I*H;;-s`FBYN(B|)6>Yll|1BFLa6Gpwr&EMoZl%aHK4Vxl zQ#vA|)X9M9&$>B(Wq92=&PH6P0ZI`XpMfue8|M8%=ii?)9_Q^J1Msjrw_D?=Z8+7` z->iRgxIrnck~JJE-uNpA2rL(>6}_To`3ddIfm|Zk)qq`@hhe8XS8?XS7oz_GQeXeS z%6VsEO*#zgWsp=jX$mRVXb8J>7=9{C^1X$G_KJ|{fD^J?)H%eT3Qu1a163uwhgIn4VQ3X^8e` ziSB7>k)V0`SG0F#OJ?gq70VwEidb%i4w}k*&uer{WTvbgK+6$r=fDQbCn*2;?9C7F6Px(J86m0}-!lFLR-8{eerpAPlkIKIH8;5}nw_@mO~d9RY+J-hcy!N_@R znvz=C~S9Vl%@}0qC z?h3APUAu6qzgQr7*1qFy{j|YX#uexB(k27qDV@g#f1b;r4hoDrv+GbZn0ayD*x58X zey2C~rF3u8DETq3CgY!bXldt7{w+?(T<$1nSc(rl#=8DF`dycLMQq9r3GjCr`U6?v ze}?L-YoSz$MEafz|GyuY1T4~TCs_t3vrtOIHsu|Mm*k`+uXFvwV81{fFliNlJhJB=C@7`dau$na$HZVa<7Y zR#z9tqS*hY2%R3x;vY24{vU$v&vUp|&h;~^7VLjg%D;Ho{|W}-^`FHK^bYuEUkN-? zHE#uY8}9$@cEqVGD>nE`P*Bi+MkWxQ10+qGKvlf$e8ShS3z`2kqR9kA!`FE4J-<7^ zmHj2sm6N2QVm<`=yG zDP@=BZT~$Q%auX z3t%MjQ(wFORilH%y#-@@JyJ2z8PBsMcQ<1tAZ2w8un?l4c=z z%e?9TdMx8+i)~O)eCR;G!u2nZ=o)948uRz$&?R0i&heb)u?>Ms?lBkN&Svre*FTeN z)M!x-kb-i5hwZAUIEURS&9aF;er8`=p!`bkIpn?Lla~6A3t{BQ`J$!7N?EC zp%I-CGI9L~K730qY7E%J#xGMNBdVILWpYExP{yL zFiWEC?>bA)*uTFF{5R>|xpJw|DfF@E!4QxJA!JZv;&Qdvjp15H_Vo0le4TM$b_!~P z5!+DMX9r1mS12FmrurPb;Jg$5r;XBYZ~n5M1~PPn}+en2C?Ql5^J;99razI5A zqx*$SRm&a~*a$r*V|IQ#CvL4DET^Zx>Rrl_;#kg0$J2lE>E-+3I>Z-B5_vs#sbr~m zvrTDw%qZrhUCR(IWgWZnI9Kv)2?pV5aUIo$v3EuxFABj@P1;cTKEx@L?yUq5f>{h2 z?Ch47r%z&|_yC}2G$&)r@*89K2sjxRML9W|{G>D+*KLSGP+WB0&*^GsypTOOEY7#g zjL92*XL=^HaCmm-z@A7n;jVU`I(V$S z%a<_yJr=I5alT$rUMp6?d|J1SnVEj+zLT>$V$Q64$mv!|TA`XX)NNaFI(_lJ`iFW{ zqxJbwSsf1SkSmX~U%BhsxEV?OC(CK$Dfo88x@EWJ_JT;5J#6kz6BUIS+RZYDx?qkK|NbU0r?Lvwo`Ck>k6rgCgMVW_<;vHsao-3V{mYpu2w(=UUzsZ>0HnbwTE zjJ`xFE=`PjWQ$eR)YKTVvTG;a2ed=Rvht3`uV{MnWOXb0&>peaZ^mksRNvmws9g5! zF_1ThlnL(O-P4UuEpYdC zODy*8uzywWd5nM7=vxbe$YIpL-x*-Z{pTTs)=xwE=d

    u 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 AlK=n! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/instrumentation.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/instrumentation.md deleted file mode 100644 index ed51ebc05d53..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/instrumentation.md +++ /dev/null @@ -1,70 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/instrumentation.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Instrumenting Kubernetes with a new metric -=================== - -The following is a step-by-step guide for adding a new metric to the Kubernetes code base. - -We use the Prometheus monitoring system's golang client library for instrumenting our code. Once you've picked out a file that you want to add a metric to, you should: - -1. Import "github.com/prometheus/client_golang/prometheus". - -2. Create a top-level var to define the metric. For this, you have to: - 1. Pick the type of metric. Use a Gauge for things you want to set to a particular value, a Counter for things you want to increment, or a Histogram or Summary for histograms/distributions of values (typically for latency). Histograms are better if you're going to aggregate the values across jobs, while summaries are better if you just want the job to give you a useful summary of the values. - 2. Give the metric a name and description. - 3. Pick whether you want to distinguish different categories of things using labels on the metric. If so, add "Vec" to the name of the type of metric you want and add a slice of the label names to the definition. - - https://k8s.io/kubernetes/blob/cd3299307d44665564e1a5c77d0daa0286603ff5/pkg/apiserver/apiserver.go#L53 - https://k8s.io/kubernetes/blob/cd3299307d44665564e1a5c77d0daa0286603ff5/pkg/kubelet/metrics/metrics.go#L31 - -3. Register the metric so that prometheus will know to export it. - - https://k8s.io/kubernetes/blob/cd3299307d44665564e1a5c77d0daa0286603ff5/pkg/kubelet/metrics/metrics.go#L74 - https://k8s.io/kubernetes/blob/cd3299307d44665564e1a5c77d0daa0286603ff5/pkg/apiserver/apiserver.go#L78 - -4. Use the metric by calling the appropriate method for your metric type (Set, Inc/Add, or Observe, respectively for Gauge, Counter, or Histogram/Summary), first calling WithLabelValues if your metric has any labels - - https://k8s.io/kubernetes/blob/3ce7fe8310ff081dbbd3d95490193e1d5250d2c9/pkg/kubelet/kubelet.go#L1384 - https://k8s.io/kubernetes/blob/cd3299307d44665564e1a5c77d0daa0286603ff5/pkg/apiserver/apiserver.go#L87 - - -These are the metric type definitions if you're curious to learn about them or need more information: -https://github.com/prometheus/client_golang/blob/master/prometheus/gauge.go -https://github.com/prometheus/client_golang/blob/master/prometheus/counter.go -https://github.com/prometheus/client_golang/blob/master/prometheus/histogram.go -https://github.com/prometheus/client_golang/blob/master/prometheus/summary.go - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/instrumentation.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/issues.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/issues.md deleted file mode 100644 index a44bbb68aef2..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/issues.md +++ /dev/null @@ -1,56 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/issues.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -GitHub Issues for the Kubernetes Project -======================================== - -A list quick overview of how we will review and prioritize incoming issues at https://k8s.io/kubernetes/issues - -Priorities ----------- - -We will use GitHub issue labels for prioritization. The absence of a priority label means the bug has not been reviewed and prioritized yet. - -Definitions ------------ -* P0 - something broken for users, build broken, or critical security issue. Someone must drop everything and work on it. -* P1 - must fix for earliest possible binary release (every two weeks) -* P2 - should be fixed in next major release version -* P3 - default priority for lower importance bugs that we still want to track and plan to fix at some point -* design - priority/design is for issues that are used to track design discussions -* support - priority/support is used for issues tracking user support requests -* untriaged - anything without a priority/X label will be considered untriaged - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/issues.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/logging.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/logging.md deleted file mode 100644 index 3870c4c32ac1..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/logging.md +++ /dev/null @@ -1,63 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/logging.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Logging Conventions -=================== - -The following conventions for the glog levels to use. [glog](http://godoc.org/github.com/golang/glog) is globally preferred to [log](http://golang.org/pkg/log/) for better runtime control. - -* glog.Errorf() - Always an error -* glog.Warningf() - Something unexpected, but probably not an error -* glog.Infof() has multiple levels: - * glog.V(0) - Generally useful for this to ALWAYS be visible to an operator - * Programmer errors - * Logging extra info about a panic - * CLI argument handling - * glog.V(1) - A reasonable default log level if you don't want verbosity. - * Information about config (listening on X, watching Y) - * Errors that repeat frequently that relate to conditions that can be corrected (pod detected as unhealthy) - * glog.V(2) - Useful steady state information about the service and important log messages that may correlate to significant changes in the system. This is the recommended default log level for most systems. - * Logging HTTP requests and their exit code - * System state changing (killing pod) - * Controller state change events (starting pods) - * Scheduler log messages - * glog.V(3) - Extended information about changes - * More info about system state changes - * glog.V(4) - Debug level verbosity (for now) - * Logging in particularly thorny parts of code where you may want to come back later and check it - -As per the comments, the practical default level is V(2). Developers and QE environments may wish to run at V(3) or V(4). If you wish to change the log level, you can pass in `-v=X` where X is the desired maximum level to log. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/logging.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/making-release-notes.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/making-release-notes.md deleted file mode 100644 index c72a61f84601..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/making-release-notes.md +++ /dev/null @@ -1,77 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/making-release-notes.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Making release notes - -This documents the process for making release notes for a release. - -### 1) Note the PR number of the previous release - -Find the most-recent PR that was merged with the previous .0 release. Remember this as $LASTPR. -_TODO_: Figure out a way to record this somewhere to save the next release engineer time. - -Find the most-recent PR that was merged with the current .0 release. Remeber this as $CURRENTPR. - -### 2) Run the release-notes tool - -```bash -${KUBERNETES_ROOT}/build/make-release-notes.sh $LASTPR $CURRENTPR -``` - -### 3) Trim the release notes - -This generates a list of the entire set of PRs merged since the last minor -release. It is likely long and many PRs aren't worth mentioning. If any of the -PRs were cherrypicked into patches on the last minor release, you should exclude -them from the current release's notes. - -Open up `candidate-notes.md` in your favorite editor. - -Remove, regroup, organize to your hearts content. - - -### 4) Update CHANGELOG.md - -With the final markdown all set, cut and paste it to the top of `CHANGELOG.md` - -### 5) Update the Release page - - * Switch to the [releases](https://k8s.io/kubernetes/releases) page. - * Open up the release you are working on. - * Cut and paste the final markdown from above into the release notes - * Press Save. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/making-release-notes.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/profiling.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/profiling.md deleted file mode 100644 index f563ce0a4752..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/profiling.md +++ /dev/null @@ -1,79 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/profiling.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Profiling Kubernetes - -This document explain how to plug in profiler and how to profile Kubernetes services. - -## Profiling library - -Go comes with inbuilt 'net/http/pprof' profiling library and profiling web service. The way service works is binding debug/pprof/ subtree on a running webserver to the profiler. Reading from subpages of debug/pprof returns pprof-formatted profiles of the running binary. The output can be processed offline by the tool of choice, or used as an input to handy 'go tool pprof', which can graphically represent the result. - -## Adding profiling to services to APIserver. - -TL;DR: Add lines: - -```go -m.mux.HandleFunc("/debug/pprof/", pprof.Index) -m.mux.HandleFunc("/debug/pprof/profile", pprof.Profile) -m.mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) -``` - -to the init(c *Config) method in 'pkg/master/master.go' and import 'net/http/pprof' package. - -In most use cases to use profiler service it's enough to do 'import _ net/http/pprof', which automatically registers a handler in the default http.Server. Slight inconvenience is that APIserver uses default server for intra-cluster communication, so plugging profiler to it is not really useful. In 'pkg/master/server/server.go' more servers are created and started as separate goroutines. The one that is usually serving external traffic is secureServer. The handler for this traffic is defined in 'pkg/master/master.go' and stored in Handler variable. It is created from HTTP multiplexer, so the only thing that needs to be done is adding profiler handler functions to this multiplexer. This is exactly what lines after TL;DR do. - -## Connecting to the profiler - -Even when running profiler I found not really straightforward to use 'go tool pprof' with it. The problem is that at least for dev purposes certificates generated for APIserver are not signed by anyone trusted and because secureServer serves only secure traffic it isn't straightforward to connect to the service. The best workaround I found is by creating an ssh tunnel from the kubernetes_master open unsecured port to some external server, and use this server as a proxy. To save everyone looking for correct ssh flags, it is done by running: - -```sh -ssh kubernetes_master -L:localhost:8080 -``` - -or analogous one for you Cloud provider. Afterwards you can e.g. run - -```sh -go tool pprof http://localhost:/debug/pprof/profile -``` - -to get 30 sec. CPU profile. - -## Contention profiling - -To enable contention profiling you need to add line `rt.SetBlockProfileRate(1)` in addition to `m.mux.HandleFunc(...)` added before (`rt` stands for `runtime` in `master.go`). This enables 'debug/pprof/block' subpage, which can be used as an input to `go tool pprof`. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/profiling.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/pull-requests.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/pull-requests.md deleted file mode 100644 index 7cebaf482b34..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/pull-requests.md +++ /dev/null @@ -1,66 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/pull-requests.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Pull Request Process -==================== - -An overview of how we will manage old or out-of-date pull requests. - -Process -------- - -We will close any pull requests older than two weeks. - -Exceptions can be made for PRs that have active review comments, or that are awaiting other dependent PRs. Closed pull requests are easy to recreate, and little work is lost by closing a pull request that subsequently needs to be reopened. - -We want to limit the total number of PRs in flight to: -* Maintain a clean project -* Remove old PRs that would be difficult to rebase as the underlying code has changed over time -* Encourage code velocity - -RC to v1.0 Pull Requests ------------------------- - -Between the first RC build (~6/22) and v1.0, we will adopt a higher bar for PR merges. For v1.0 to be a stable release, we need to ensure that any fixes going in are very well tested and have a low risk of breaking anything. Refactors and complex changes will be rejected in favor of more strategic and smaller workarounds. - -These PRs require: -* A risk assessment by the code author in the PR. This should outline which parts of the code are being touched, the risk of regression, and complexity of the code. -* Two LGTMs from experienced reviewers. - -Once those requirements are met, they will be labeled [ok-to-merge](https://k8s.io/kubernetes/pulls?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr+label%3Aok-to-merge) and can be merged. - -These restrictions will be relaxed after v1.0 is released. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/pull-requests.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.dot b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.dot deleted file mode 100644 index fe8124c36da7..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.dot +++ /dev/null @@ -1,113 +0,0 @@ -// Build it with: -// $ dot -Tsvg releasing.dot >releasing.svg - -digraph tagged_release { - size = "5,5" - // Arrows go up. - rankdir = BT - subgraph left { - // Group the left nodes together. - ci012abc -> pr101 -> ci345cde -> pr102 - style = invis - } - subgraph right { - // Group the right nodes together. - version_commit -> dev_commit - style = invis - } - { // Align the version commit and the info about it. - rank = same - // Align them with pr101 - pr101 - version_commit - // release_info shows the change in the commit. - release_info - } - { // Align the dev commit and the info about it. - rank = same - // Align them with 345cde - ci345cde - dev_commit - dev_info - } - // Join the nodes from subgraph left. - pr99 -> ci012abc - pr102 -> pr100 - // Do the version node. - pr99 -> version_commit - dev_commit -> pr100 - tag -> version_commit - pr99 [ - label = "Merge PR #99" - shape = box - fillcolor = "#ccccff" - style = "filled" - fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" - ]; - ci012abc [ - label = "012abc" - shape = circle - fillcolor = "#ffffcc" - style = "filled" - fontname = "Consolas, Liberation Mono, Menlo, Courier, monospace" - ]; - pr101 [ - label = "Merge PR #101" - shape = box - fillcolor = "#ccccff" - style = "filled" - fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" - ]; - ci345cde [ - label = "345cde" - shape = circle - fillcolor = "#ffffcc" - style = "filled" - fontname = "Consolas, Liberation Mono, Menlo, Courier, monospace" - ]; - pr102 [ - label = "Merge PR #102" - shape = box - fillcolor = "#ccccff" - style = "filled" - fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" - ]; - version_commit [ - label = "678fed" - shape = circle - fillcolor = "#ccffcc" - style = "filled" - fontname = "Consolas, Liberation Mono, Menlo, Courier, monospace" - ]; - dev_commit [ - label = "456dcb" - shape = circle - fillcolor = "#ffffcc" - style = "filled" - fontname = "Consolas, Liberation Mono, Menlo, Courier, monospace" - ]; - pr100 [ - label = "Merge PR #100" - shape = box - fillcolor = "#ccccff" - style = "filled" - fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" - ]; - release_info [ - label = "pkg/version/base.go:\ngitVersion = \"v0.5\";" - shape = none - fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" - ]; - dev_info [ - label = "pkg/version/base.go:\ngitVersion = \"v0.5-dev\";" - shape = none - fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" - ]; - tag [ - label = "$ git tag -a v0.5" - fillcolor = "#ffcccc" - style = "filled" - fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" - ]; -} - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.md deleted file mode 100644 index 9950e6e4f05f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.md +++ /dev/null @@ -1,343 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/releasing.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Releasing Kubernetes - -This document explains how to cut a release, and the theory behind it. If you -just want to cut a release and move on with your life, you can stop reading -after the first section. - -## How to cut a Kubernetes release - -Regardless of whether you are cutting a major or minor version, cutting a -release breaks down into four pieces: - -1. Selecting release components. -1. Tagging and merging the release in Git. -1. Building and pushing the binaries. -1. Writing release notes. - -You should progress in this strict order. - -### Building a New Major/Minor Version (`vX.Y.0`) - -#### Selecting Release Components - -When cutting a major/minor release, your first job is to find the branch -point. We cut `vX.Y.0` releases directly from `master`, which is also the -branch that we have most continuous validation on. Go first to [the main GCE -Jenkins end-to-end job](http://go/k8s-test/job/kubernetes-e2e-gce) and next to [the -Critical Builds page](http://go/k8s-test/view/Critical%20Builds) and hopefully find a -recent Git hash that looks stable across at least `kubernetes-e2e-gce` and -`kubernetes-e2e-gke-ci`. First glance through builds and look for nice solid -rows of green builds, and then check temporally with the other Critical Builds -to make sure they're solid around then as well. Once you find some greens, you -can find the Git hash for a build by looking at the "Console Log", then look for -`githash=`. You should see a line line: - -```console -+ githash=v0.20.2-322-g974377b -``` - -Because Jenkins builds frequently, if you're looking between jobs -(e.g. `kubernetes-e2e-gke-ci` and `kubernetes-e2e-gce`), there may be no single -`githash` that's been run on both jobs. In that case, take the a green -`kubernetes-e2e-gce` build (but please check that it corresponds to a temporally -similar build that's green on `kubernetes-e2e-gke-ci`). Lastly, if you're having -trouble understanding why the GKE continuous integration clusters are failing -and you're trying to cut a release, don't hesitate to contact the GKE -oncall. - -Before proceeding to the next step: - -```sh -export BRANCHPOINT=v0.20.2-322-g974377b -``` - -Where `v0.20.2-322-g974377b` is the git hash you decided on. This will become -our (retroactive) branch point. - -#### Branching, Tagging and Merging - -Do the following: - -1. `export VER=x.y` (e.g. `0.20` for v0.20) -1. cd to the base of the repo -1. `git fetch upstream && git checkout -b release-${VER} ${BRANCHPOINT}` (you did set `${BRANCHPOINT}`, right?) -1. Make sure you don't have any files you care about littering your repo (they - better be checked in or outside the repo, or the next step will delete them). -1. `make clean && git reset --hard HEAD && git clean -xdf` -1. `make` (TBD: you really shouldn't have to do this, but the swagger output step requires it right now) -1. `./build/mark-new-version.sh v${VER}.0` to mark the new release and get further - instructions. This creates a series of commits on the branch you're working - on (`release-${VER}`), including forking our documentation for the release, - the release version commit (which is then tagged), and the post-release - version commit. -1. Follow the instructions given to you by that script. They are canon for the - remainder of the Git process. If you don't understand something in that - process, please ask! - -**TODO**: how to fix tags, etc., if you have to shift the release branchpoint. - -#### Building and Pushing Binaries - -In your git repo (you still have `${VER}` set from above right?): - -1. `git checkout upstream/master && build/build-official-release.sh v${VER}.0` (the `build-official-release.sh` script is version agnostic, so it's best to run it off `master` directly). -1. Follow the instructions given to you by that script. -1. At this point, you've done all the Git bits, you've got all the binary bits pushed, and you've got the template for the release started on GitHub. - -#### Writing Release Notes - -[This helpful guide](making-release-notes.md) describes how to write release -notes for a major/minor release. In the release template on GitHub, leave the -last PR number that the tool finds for the `.0` release, so the next releaser -doesn't have to hunt. - -### Building a New Patch Release (`vX.Y.Z` for `Z > 0`) - -#### Selecting Release Components - -We cut `vX.Y.Z` releases from the `release-vX.Y` branch after all cherry picks -to the branch have been resolved. You should ensure all outstanding cherry picks -have been reviewed and merged and the branch validated on Jenkins (validation -TBD). See the [Cherry Picks](cherry-picks.md) for more information on how to -manage cherry picks prior to cutting the release. - -#### Tagging and Merging - -1. `export VER=x.y` (e.g. `0.20` for v0.20) -1. `export PATCH=Z` where `Z` is the patch level of `vX.Y.Z` -1. cd to the base of the repo -1. `git fetch upstream && git checkout -b upstream/release-${VER}` -1. Make sure you don't have any files you care about littering your repo (they - better be checked in or outside the repo, or the next step will delete them). -1. `make clean && git reset --hard HEAD && git clean -xdf` -1. `make` (TBD: you really shouldn't have to do this, but the swagger output step requires it right now) -1. `./build/mark-new-version.sh v${VER}.${PATCH}` to mark the new release and get further - instructions. This creates a series of commits on the branch you're working - on (`release-${VER}`), including forking our documentation for the release, - the release version commit (which is then tagged), and the post-release - version commit. -1. Follow the instructions given to you by that script. They are canon for the - remainder of the Git process. If you don't understand something in that - process, please ask! When proposing PRs, you can pre-fill the body with - `hack/cherry_pick_list.sh upstream/release-${VER}` to inform people of what - is already on the branch. - -**TODO**: how to fix tags, etc., if the release is changed. - -#### Building and Pushing Binaries - -In your git repo (you still have `${VER}` and `${PATCH}` set from above right?): - -1. `git checkout upstream/master && build/build-official-release.sh - v${VER}.${PATCH}` (the `build-official-release.sh` script is version - agnostic, so it's best to run it off `master` directly). -1. Follow the instructions given to you by that script. At this point, you've - done all the Git bits, you've got all the binary bits pushed, and you've got - the template for the release started on GitHub. - -#### Writing Release Notes - -Run `hack/cherry_pick_list.sh ${VER}.${PATCH}~1` to get the release notes for -the patch release you just created. Feel free to prune anything internal, like -you would for a major release, but typically for patch releases we tend to -include everything in the release notes. - -## Origin of the Sources - -Kubernetes may be built from either a git tree (using `hack/build-go.sh`) or -from a tarball (using either `hack/build-go.sh` or `go install`) or directly by -the Go native build system (using `go get`). - -When building from git, we want to be able to insert specific information about -the build tree at build time. In particular, we want to use the output of `git -describe` to generate the version of Kubernetes and the status of the build -tree (add a `-dirty` prefix if the tree was modified.) - -When building from a tarball or using the Go build system, we will not have -access to the information about the git tree, but we still want to be able to -tell whether this build corresponds to an exact release (e.g. v0.3) or is -between releases (e.g. at some point in development between v0.3 and v0.4). - -## Version Number Format - -In order to account for these use cases, there are some specific formats that -may end up representing the Kubernetes version. Here are a few examples: - -- **v0.5**: This is official version 0.5 and this version will only be used - when building from a clean git tree at the v0.5 git tag, or from a tree - extracted from the tarball corresponding to that specific release. -- **v0.5-15-g0123abcd4567**: This is the `git describe` output and it indicates - that we are 15 commits past the v0.5 release and that the SHA1 of the commit - where the binaries were built was `0123abcd4567`. It is only possible to have - this level of detail in the version information when building from git, not - when building from a tarball. -- **v0.5-15-g0123abcd4567-dirty** or **v0.5-dirty**: The extra `-dirty` prefix - means that the tree had local modifications or untracked files at the time of - the build, so there's no guarantee that the source code matches exactly the - state of the tree at the `0123abcd4567` commit or at the `v0.5` git tag - (resp.) -- **v0.5-dev**: This means we are building from a tarball or using `go get` or, - if we have a git tree, we are using `go install` directly, so it is not - possible to inject the git version into the build information. Additionally, - this is not an official release, so the `-dev` prefix indicates that the - version we are building is after `v0.5` but before `v0.6`. (There is actually - an exception where a commit with `v0.5-dev` is not present on `v0.6`, see - later for details.) - -## Injecting Version into Binaries - -In order to cover the different build cases, we start by providing information -that can be used when using only Go build tools or when we do not have the git -version information available. - -To be able to provide a meaningful version in those cases, we set the contents -of variables in a Go source file that will be used when no overrides are -present. - -We are using `pkg/version/base.go` as the source of versioning in absence of -information from git. Here is a sample of that file's contents: - -```go -var ( - gitVersion string = "v0.4-dev" // version from git, output of $(git describe) - gitCommit string = "" // sha1 from git, output of $(git rev-parse HEAD) -) -``` - -This means a build with `go install` or `go get` or a build from a tarball will -yield binaries that will identify themselves as `v0.4-dev` and will not be able -to provide you with a SHA1. - -To add the extra versioning information when building from git, the -`hack/build-go.sh` script will gather that information (using `git describe` and -`git rev-parse`) and then create a `-ldflags` string to pass to `go install` and -tell the Go linker to override the contents of those variables at build time. It -can, for instance, tell it to override `gitVersion` and set it to -`v0.4-13-g4567bcdef6789-dirty` and set `gitCommit` to `4567bcdef6789...` which -is the complete SHA1 of the (dirty) tree used at build time. - -## Handling Official Versions - -Handling official versions from git is easy, as long as there is an annotated -git tag pointing to a specific version then `git describe` will return that tag -exactly which will match the idea of an official version (e.g. `v0.5`). - -Handling it on tarballs is a bit harder since the exact version string must be -present in `pkg/version/base.go` for it to get embedded into the binaries. But -simply creating a commit with `v0.5` on its own would mean that the commits -coming after it would also get the `v0.5` version when built from tarball or `go -get` while in fact they do not match `v0.5` (the one that was tagged) exactly. - -To handle that case, creating a new release should involve creating two adjacent -commits where the first of them will set the version to `v0.5` and the second -will set it to `v0.5-dev`. In that case, even in the presence of merges, there -will be a single commit where the exact `v0.5` version will be used and all -others around it will either have `v0.4-dev` or `v0.5-dev`. - -The diagram below illustrates it. - -![Diagram of git commits involved in the release](releasing.png) - -After working on `v0.4-dev` and merging PR 99 we decide it is time to release -`v0.5`. So we start a new branch, create one commit to update -`pkg/version/base.go` to include `gitVersion = "v0.5"` and `git commit` it. - -We test it and make sure everything is working as expected. - -Before sending a PR for it, we create a second commit on that same branch, -updating `pkg/version/base.go` to include `gitVersion = "v0.5-dev"`. That will -ensure that further builds (from tarball or `go install`) on that tree will -always include the `-dev` prefix and will not have a `v0.5` version (since they -do not match the official `v0.5` exactly.) - -We then send PR 100 with both commits in it. - -Once the PR is accepted, we can use `git tag -a` to create an annotated tag -*pointing to the one commit* that has `v0.5` in `pkg/version/base.go` and push -it to GitHub. (Unfortunately GitHub tags/releases are not annotated tags, so -this needs to be done from a git client and pushed to GitHub using SSH or -HTTPS.) - -## Parallel Commits - -While we are working on releasing `v0.5`, other development takes place and -other PRs get merged. For instance, in the example above, PRs 101 and 102 get -merged to the master branch before the versioning PR gets merged. - -This is not a problem, it is only slightly inaccurate that checking out the tree -at commit `012abc` or commit `345cde` or at the commit of the merges of PR 101 -or 102 will yield a version of `v0.4-dev` *but* those commits are not present in -`v0.5`. - -In that sense, there is a small window in which commits will get a -`v0.4-dev` or `v0.4-N-gXXX` label and while they're indeed later than `v0.4` -but they are not really before `v0.5` in that `v0.5` does not contain those -commits. - -Unfortunately, there is not much we can do about it. On the other hand, other -projects seem to live with that and it does not really become a large problem. - -As an example, Docker commit a327d9b91edf has a `v1.1.1-N-gXXX` label but it is -not present in Docker `v1.2.0`: - -```console -$ git describe a327d9b91edf -v1.1.1-822-ga327d9b91edf - -$ git log --oneline v1.2.0..a327d9b91edf -a327d9b91edf Fix data space reporting from Kb/Mb to KB/MB - -(Non-empty output here means the commit is not present on v1.2.0.) -``` - -## Release Notes - -No official release should be made final without properly matching release notes. - -There should be made available, per release, a small summary, preamble, of the -major changes, both in terms of feature improvements/bug fixes and notes about -functional feature changes (if any) regarding the previous released version so -that the BOM regarding updating to it gets as obvious and trouble free as possible. - -After this summary, preamble, all the relevant PRs/issues that got in that -version should be listed and linked together with a small summary understandable -by plain mortals (in a perfect world PR/issue's title would be enough but often -it is just too cryptic/geeky/domain-specific that it isn't). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/releasing.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.png deleted file mode 100644 index 935628deddc5ba9c608cd7f97d7c587bf519e333..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30693 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 A2LJ#7 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.svg b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.svg deleted file mode 100644 index f703e6e2ac96..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/releasing.svg +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - -tagged_release - - -ci012abc - -012abc - - -pr101 - -Merge PR #101 - - -ci012abc->pr101 - - - - -ci345cde - -345cde - - -pr101->ci345cde - - - - -pr102 - -Merge PR #102 - - -ci345cde->pr102 - - - - -pr100 - -Merge PR #100 - - -pr102->pr100 - - - - -version_commit - -678fed - - -dev_commit - -456dcb - - -version_commit->dev_commit - - - - -dev_commit->pr100 - - - - -release_info -pkg/version/base.go: -gitVersion = "v0.5"; - - -dev_info -pkg/version/base.go: -gitVersion = "v0.5-dev"; - - -pr99 - -Merge PR #99 - - -pr99->ci012abc - - - - -pr99->version_commit - - - - -tag - -$ git tag -a v0.5 - - -tag->version_commit - - - - - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/scheduler.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/scheduler.md deleted file mode 100644 index b2a137d510d7..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/scheduler.md +++ /dev/null @@ -1,84 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/scheduler.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# The Kubernetes Scheduler - -The Kubernetes scheduler runs as a process alongside the other master -components such as the API server. Its interface to the API server is to watch -for Pods with an empty PodSpec.NodeName, and for each Pod, it posts a Binding -indicating where the Pod should be scheduled. - -## The scheduling process - -The scheduler tries to find a node for each Pod, one at a time, as it notices -these Pods via watch. There are three steps. First it applies a set of "predicates" that filter out -inappropriate nodes. For example, if the PodSpec specifies resource limits, then the scheduler -will filter out nodes that don't have at least that much resources available (computed -as the capacity of the node minus the sum of the resource limits of the containers that -are already running on the node). Second, it applies a set of "priority functions" -that rank the nodes that weren't filtered out by the predicate check. For example, -it tries to spread Pods across nodes while at the same time favoring the least-loaded -nodes (where "load" here is sum of the resource limits of the containers running on the node, -divided by the node's capacity). -Finally, the node with the highest priority is chosen -(or, if there are multiple such nodes, then one of them is chosen at random). The code -for this main scheduling loop is in the function `Schedule()` in -[plugin/pkg/scheduler/generic_scheduler.go](http://releases.k8s.io/HEAD/plugin/pkg/scheduler/generic_scheduler.go) - -## Scheduler extensibility - -The scheduler is extensible: the cluster administrator can choose which of the pre-defined -scheduling policies to apply, and can add new ones. The built-in predicates and priorities are -defined in [plugin/pkg/scheduler/algorithm/predicates/predicates.go](http://releases.k8s.io/HEAD/plugin/pkg/scheduler/algorithm/predicates/predicates.go) and -[plugin/pkg/scheduler/algorithm/priorities/priorities.go](http://releases.k8s.io/HEAD/plugin/pkg/scheduler/algorithm/priorities/priorities.go), respectively. -The policies that are applied when scheduling can be chosen in one of two ways. Normally, -the policies used are selected by the functions `defaultPredicates()` and `defaultPriorities()` in -[plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go](http://releases.k8s.io/HEAD/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go). -However, the choice of policies -can be overridden by passing the command-line flag `--policy-config-file` to the scheduler, pointing to a JSON -file specifying which scheduling policies to use. See -[examples/scheduler-policy-config.json](../../examples/scheduler-policy-config.json) for an example -config file. (Note that the config file format is versioned; the API is defined in -[plugin/pkg/scheduler/api](http://releases.k8s.io/HEAD/plugin/pkg/scheduler/api/)). -Thus to add a new scheduling policy, you should modify predicates.go or priorities.go, -and either register the policy in `defaultPredicates()` or `defaultPriorities()`, or use a policy config file. - -## Exploring the code - -If you want to get a global picture of how the scheduler works, you can start in -[plugin/cmd/kube-scheduler/app/server.go](http://releases.k8s.io/HEAD/plugin/cmd/kube-scheduler/app/server.go) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/scheduler.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/scheduler_algorithm.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/scheduler_algorithm.md deleted file mode 100644 index ab8e69ef8e2a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/scheduler_algorithm.md +++ /dev/null @@ -1,72 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/scheduler_algorithm.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Scheduler Algorithm in Kubernetes - -For each unscheduled Pod, the Kubernetes scheduler tries to find a node across the cluster according to a set of rules. A general introduction to the Kubernetes scheduler can be found at [scheduler.md](scheduler.md). In this document, the algorithm of how to select a node for the Pod is explained. There are two steps before a destination node of a Pod is chosen. The first step is filtering all the nodes and the second is ranking the remaining nodes to find a best fit for the Pod. - -## Filtering the nodes - -The purpose of filtering the nodes is to filter out the nodes that do not meet certain requirements of the Pod. For example, if the free resource on a node (measured by the capacity minus the sum of the resource limits of all the Pods that already run on the node) is less than the Pod's required resource, the node should not be considered in the ranking phase so it is filtered out. Currently, there are several "predicates" implementing different filtering policies, including: - -- `NoDiskConflict`: Evaluate if a pod can fit due to the volumes it requests, and those that are already mounted. -- `PodFitsResources`: Check if the free resource (CPU and Memory) meets the requirement of the Pod. The free resource is measured by the capacity minus the sum of limits of all Pods on the node. -- `PodFitsPorts`: Check if any HostPort required by the Pod is already occupied on the node. -- `PodFitsHost`: Filter out all nodes except the one specified in the PodSpec's NodeName field. -- `PodSelectorMatches`: Check if the labels of the node match the labels specified in the Pod's `nodeSelector` field ([Here](../user-guide/node-selection/) is an example of how to use `nodeSelector` field). -- `CheckNodeLabelPresence`: Check if all the specified labels exist on a node or not, regardless of the value. - -The details of the above predicates can be found in [plugin/pkg/scheduler/algorithm/predicates/predicates.go](http://releases.k8s.io/HEAD/plugin/pkg/scheduler/algorithm/predicates/predicates.go). All predicates mentioned above can be used in combination to perform a sophisticated filtering policy. Kubernetes uses some, but not all, of these predicates by default. You can see which ones are used by default in [plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go](http://releases.k8s.io/HEAD/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go). - -## Ranking the nodes - -The filtered nodes are considered suitable to host the Pod, and it is often that there are more than one nodes remaining. Kubernetes prioritizes the remaining nodes to find the "best" one for the Pod. The prioritization is performed by a set of priority functions. For each remaining node, a priority function gives a score which scales from 0-10 with 10 representing for "most preferred" and 0 for "least preferred". Each priority function is weighted by a positive number and the final score of each node is calculated by adding up all the weighted scores. For example, suppose there are two priority functions, `priorityFunc1` and `priorityFunc2` with weighting factors `weight1` and `weight2` respectively, the final score of some NodeA is: - - finalScoreNodeA = (weight1 * priorityFunc1) + (weight2 * priorityFunc2) - -After the scores of all nodes are calculated, the node with highest score is chosen as the host of the Pod. If there are more than one nodes with equal highest scores, a random one among them is chosen. - -Currently, Kubernetes scheduler provides some practical priority functions, including: - -- `LeastRequestedPriority`: The node is prioritized based on the fraction of the node that would be free if the new Pod were scheduled onto the node. (In other words, (capacity - sum of limits of all Pods already on the node - limit of Pod that is being scheduled) / capacity). CPU and memory are equally weighted. The node with the highest free fraction is the most preferred. Note that this priority function has the effect of spreading Pods across the nodes with respect to resource consumption. -- `CalculateNodeLabelPriority`: Prefer nodes that have the specified label. -- `BalancedResourceAllocation`: This priority function tries to put the Pod on a node such that the CPU and Memory utilization rate is balanced after the Pod is deployed. -- `CalculateSpreadPriority`: Spread Pods by minimizing the number of Pods belonging to the same service on the same node. -- `CalculateAntiAffinityPriority`: Spread Pods by minimizing the number of Pods belonging to the same service on nodes with the same value for a particular label. - -The details of the above priority functions can be found in [plugin/pkg/scheduler/algorithm/priorities](http://releases.k8s.io/HEAD/plugin/pkg/scheduler/algorithm/priorities/). Kubernetes uses some, but not all, of these priority functions by default. You can see which ones are used by default in [plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go](http://releases.k8s.io/HEAD/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go). Similar as predicates, you can combine the above priority functions and assign weight factors (positive number) to them as you want (check [scheduler.md](scheduler.md) for how to customize). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/scheduler_algorithm.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/writing-a-getting-started-guide.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/writing-a-getting-started-guide.md deleted file mode 100644 index 04d0d67f6a98..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/devel/writing-a-getting-started-guide.md +++ /dev/null @@ -1,134 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/devel/writing-a-getting-started-guide.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Writing a Getting Started Guide - -This page gives some advice for anyone planning to write or update a Getting Started Guide for Kubernetes. -It also gives some guidelines which reviewers should follow when reviewing a pull request for a -guide. - -A Getting Started Guide is instructions on how to create a Kubernetes cluster on top of a particular -type(s) of infrastructure. Infrastructure includes: the IaaS provider for VMs; -the node OS; inter-node networking; and node Configuration Management system. -A guide refers to scripts, Configuration Management files, and/or binary assets such as RPMs. We call -the combination of all these things needed to run on a particular type of infrastructure a -**distro**. - -[The Matrix](../../docs/getting-started-guides/README.md) lists the distros. If there is already a guide -which is similar to the one you have planned, consider improving that one. - - -Distros fall into two categories: - - **versioned distros** are tested to work with a particular binary release of Kubernetes. These - come in a wide variety, reflecting a wide range of ideas and preferences in how to run a cluster. - - **development distros** are tested work with the latest Kubernetes source code. But, there are - relatively few of these and the bar is much higher for creating one. They must support - fully automated cluster creation, deletion, and upgrade. - -There are different guidelines for each. - -## Versioned Distro Guidelines - -These guidelines say *what* to do. See the Rationale section for *why*. - - Send us a PR. - - Put the instructions in `docs/getting-started-guides/...`. Scripts go there too. This helps devs easily - search for uses of flags by guides. - - We may ask that you host binary assets or large amounts of code in our `contrib` directory or on your - own repo. - - Add or update a row in [The Matrix](../../docs/getting-started-guides/README.md). - - State the binary version of Kubernetes that you tested clearly in your Guide doc. - - Setup a cluster and run the [conformance test](development.md#conformance-testing) against it, and report the - results in your PR. - - Versioned distros should typically not modify or add code in `cluster/`. That is just scripts for developer - distros. - - When a new major or minor release of Kubernetes comes out, we may also release a new - conformance test, and require a new conformance test run to earn a conformance checkmark. - -If you have a cluster partially working, but doing all the above steps seems like too much work, -we still want to hear from you. We suggest you write a blog post or a Gist, and we will link to it on our wiki page. -Just file an issue or chat us on IRC and one of the committers will link to it from the wiki. - -## Development Distro Guidelines - -These guidelines say *what* to do. See the Rationale section for *why*. - - the main reason to add a new development distro is to support a new IaaS provider (VM and - network management). This means implementing a new `pkg/cloudprovider/$IAAS_NAME`. - - Development distros should use Saltstack for Configuration Management. - - development distros need to support automated cluster creation, deletion, upgrading, etc. - This mean writing scripts in `cluster/$IAAS_NAME`. - - all commits to the tip of this repo need to not break any of the development distros - - the author of the change is responsible for making changes necessary on all the cloud-providers if the - change affects any of them, and reverting the change if it breaks any of the CIs. - - a development distro needs to have an organization which owns it. This organization needs to: - - Setting up and maintaining Continuous Integration that runs e2e frequently (multiple times per day) against the - Distro at head, and which notifies all devs of breakage. - - being reasonably available for questions and assisting with - refactoring and feature additions that affect code for their IaaS. - -## Rationale - - - We want people to create Kubernetes clusters with whatever IaaS, Node OS, - configuration management tools, and so on, which they are familiar with. The - guidelines for **versioned distros** are designed for flexibility. - - We want developers to be able to work without understanding all the permutations of - IaaS, NodeOS, and configuration management. The guidelines for **developer distros** are designed - for consistency. - - We want users to have a uniform experience with Kubernetes whenever they follow instructions anywhere - in our Github repository. So, we ask that versioned distros pass a **conformance test** to make sure - really work. - - We want to **limit the number of development distros** for several reasons. Developers should - only have to change a limited number of places to add a new feature. Also, since we will - gate commits on passing CI for all distros, and since end-to-end tests are typically somewhat - flaky, it would be highly likely for there to be false positives and CI backlogs with many CI pipelines. - - We do not require versioned distros to do **CI** for several reasons. It is a steep - learning curve to understand our automated testing scripts. And it is considerable effort - to fully automate setup and teardown of a cluster, which is needed for CI. And, not everyone - has the time and money to run CI. We do not want to - discourage people from writing and sharing guides because of this. - - Versioned distro authors are free to run their own CI and let us know if there is breakage, but we - will not include them as commit hooks -- there cannot be so many commit checks that it is impossible - to pass them all. - - We prefer a single Configuration Management tool for development distros. If there were more - than one, the core developers would have to learn multiple tools and update config in multiple - places. **Saltstack** happens to be the one we picked when we started the project. We - welcome versioned distros that use any tool; there are already examples of - CoreOS Fleet, Ansible, and others. - - You can still run code from head or your own branch - if you use another Configuration Management tool -- you just have to do some manual steps - during testing and deployment. - - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/writing-a-getting-started-guide.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/README.md deleted file mode 100644 index d9c279f6e09a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/README.md +++ /dev/null @@ -1,198 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Creating a Kubernetes Cluster - -Kubernetes can run on a range of platforms, from your laptop, to VMs on a cloud provider, to rack of -bare metal servers. The effort required to set up a cluster varies from running a single command to -crafting your own customized cluster. We'll guide you in picking a solution that fits for your needs. - -## Picking the Right Solution - -If you just want to "kick the tires" on Kubernetes, we recommend the [local Docker-based](docker.md) solution. - -The local Docker-based solution is one of several [Local cluster](#local-machine-solutions) solutions -that are quick to set up, but are limited to running on one machine. - -When you are ready to scale up to more machines and higher availability, a [Hosted](#hosted-solutions) -solution is the easiest to create and maintain. - -[Turn-key cloud solutions](#turn-key-cloud-solutions) require only a few commands to create -and cover a wider range of cloud providers. - -[Custom solutions](#custom-solutions) require more effort to setup but cover and even -they vary from step-by-step instructions to general advice for setting up -a Kubernetes cluster from scratch. - -### Local-machine Solutions - -Local-machine solutions create a single cluster with one or more Kubernetes nodes on a single -physical machine. Setup is completely automated and doesn't require a cloud provider account. -But their size and availability is limited to that of a single machine. - -The local-machine solutions are: - - [Local Docker-based](docker.md) (recommended starting point) - - [Vagrant](vagrant.md) (works on any platform with Vagrant: Linux, MacOS, or Windows.) - - [No-VM local cluster](locally.md) (Linux only) - - -### Hosted Solutions - -[Google Container Engine](https://cloud.google.com/container-engine) offers managed Kubernetes -clusters. - -### Turn-key Cloud Solutions - -These solutions allow you to create Kubernetes clusters on a range of Cloud IaaS providers with only a -few commands, and have active community support. -- [GCE](gce.md) -- [AWS](aws.md) -- [Azure](coreos/azure/README.md) - -### Custom Solutions - -Kubernetes can run on a wide range of Cloud providers and bare-metal environments, and with many -base operating systems. - -If you can find a guide below that matches your needs, use it. It may be a little out of date, but -it will be easier than starting from scratch. If you do want to start from scratch because you -have special requirements or just because you want to understand what is underneath a Kubernetes -cluster, try the [Getting Started from Scratch](scratch.md) guide. - -If you are interested in supporting Kubernetes on a new platform, check out our [advice for -writing a new solution](../../docs/devel/writing-a-getting-started-guide.md). - -#### Cloud - -These solutions are combinations of cloud provider and OS not covered by the above solutions. -- [AWS + coreos](coreos.md) -- [GCE + CoreOS](coreos.md) -- [AWS + Ubuntu](juju.md) -- [Joyent + Ubuntu](juju.md) -- [Rackspace + CoreOS](rackspace.md) - -#### On-Premises VMs - -- [Vagrant](coreos.md) (uses CoreOS and flannel) -- [CloudStack](cloudstack.md) (uses Ansible, CoreOS and flannel) -- [Vmware](vsphere.md) (uses Debian) -- [juju.md](juju.md) (uses Juju, Ubuntu and flannel) -- [Vmware](coreos.md) (uses CoreOS and flannel) -- [libvirt-coreos.md](libvirt-coreos.md) (uses CoreOS) -- [oVirt](ovirt.md) -- [libvirt](fedora/flannel_multi_node_cluster.md) (uses Fedora and flannel) -- [KVM](fedora/flannel_multi_node_cluster.md) (uses Fedora and flannel) - -#### Bare Metal - -- [Offline](coreos/bare_metal_offline.md) (no internet required. Uses CoreOS and Flannel) -- [fedora/fedora_ansible_config.md](fedora/fedora_ansible_config.md) -- [Fedora single node](fedora/fedora_manual_config.md) -- [Fedora multi node](fedora/flannel_multi_node_cluster.md) -- [Centos](centos/centos_manual_config.md) -- [Ubuntu](ubuntu.md) -- [Docker Multi Node](docker-multinode.md) - -#### Integrations - -- [Kubernetes on Mesos](mesos.md) (Uses GCE) - -## Table of Solutions - -Here are all the solutions mentioned above in table form. - -IaaS Provider | Config. Mgmt | OS | Networking | Docs | Conforms | Support Level --------------------- | ------------ | ------ | ---------- | --------------------------------------------- | ---------| ---------------------------- -GKE | | | GCE | [docs](https://cloud.google.com/container-engine) | | Commercial -Vagrant | Saltstack | Fedora | OVS | [docs](vagrant.md) | [✓][2] | Project -GCE | Saltstack | Debian | GCE | [docs](gce.md) | [✓][1] | Project -Azure | CoreOS | CoreOS | Weave | [docs](coreos/azure/README.md) | | Community ([@errordeveloper](https://github.com/errordeveloper), [@squillace](https://github.com/squillace), [@chanezon](https://github.com/chanezon), [@crossorigin](https://github.com/crossorigin)) -Docker Single Node | custom | N/A | local | [docs](docker.md) | | Project (@brendandburns) -Docker Multi Node | Flannel | N/A | local | [docs](docker-multinode.md) | | Project (@brendandburns) -Bare-metal | Ansible | Fedora | flannel | [docs](fedora/fedora_ansible_config.md) | | Project -Bare-metal | custom | Fedora | _none_ | [docs](fedora/fedora_manual_config.md) | | Project -Bare-metal | custom | Fedora | flannel | [docs](fedora/flannel_multi_node_cluster.md) | | Community ([@aveshagarwal](https://github.com/aveshagarwal)) -libvirt | custom | Fedora | flannel | [docs](fedora/flannel_multi_node_cluster.md) | | Community ([@aveshagarwal](https://github.com/aveshagarwal)) -KVM | custom | Fedora | flannel | [docs](fedora/flannel_multi_node_cluster.md) | | Community ([@aveshagarwal](https://github.com/aveshagarwal)) -Mesos/GCE | | | | [docs](mesos.md) | | [Community](https://github.com/mesosphere/kubernetes-mesos) ([@jdef](https://github.com/jdef)) -AWS | CoreOS | CoreOS | flannel | [docs](coreos.md) | | Community -GCE | CoreOS | CoreOS | flannel | [docs](coreos.md) | | Community [@pires](https://github.com/pires) -Vagrant | CoreOS | CoreOS | flannel | [docs](coreos.md) | | Community ( [@pires](https://github.com/pires), [@AntonioMeireles](https://github.com/AntonioMeireles) ) -Bare-metal (Offline) | CoreOS | CoreOS | flannel | [docs](coreos/bare_metal_offline.md) | | Community([@jeffbean](https://github.com/jeffbean)) -CloudStack | Ansible | CoreOS | flannel | [docs](cloudstack.md) | | Community (@runseb) -Vmware | | Debian | OVS | [docs](vsphere.md) | | Community (@pietern) -Bare-metal | custom | CentOS | _none_ | [docs](centos/centos_manual_config.md) | | Community(@coolsvap) -AWS | Juju | Ubuntu | flannel | [docs](juju.md) | | [Community](https://github.com/whitmo/bundle-kubernetes) ( [@whit](https://github.com/whitmo), [@matt](https://github.com/mbruzek), [@chuck](https://github.com/chuckbutler) ) -OpenStack/HPCloud | Juju | Ubuntu | flannel | [docs](juju.md) | | [Community](https://github.com/whitmo/bundle-kubernetes) ( [@whit](https://github.com/whitmo), [@matt](https://github.com/mbruzek), [@chuck](https://github.com/chuckbutler) ) -Joyent | Juju | Ubuntu | flannel | [docs](juju.md) | | [Community](https://github.com/whitmo/bundle-kubernetes) ( [@whit](https://github.com/whitmo), [@matt](https://github.com/mbruzek), [@chuck](https://github.com/chuckbutler) ) -AWS | Saltstack | Ubuntu | OVS | [docs](aws.md) | | Community (@justinsb) -Vmware | CoreOS | CoreOS | flannel | [docs](coreos.md) | | Community (@kelseyhightower) -Azure | Saltstack | Ubuntu | OpenVPN | [docs](azure.md) | | Community -Bare-metal | custom | Ubuntu | calico | [docs](ubuntu-calico.md) | | Community (@djosborne) -Bare-metal | custom | Ubuntu | flannel | [docs](ubuntu.md) | | Community (@resouer @WIZARD-CXY) -Local | | | _none_ | [docs](locally.md) | | Community (@preillyme) -libvirt/KVM | CoreOS | CoreOS | libvirt/KVM | [docs](libvirt-coreos.md) | | Community (@lhuard1A) -oVirt | | | | [docs](ovirt.md) | | Community (@simon3z) -Rackspace | CoreOS | CoreOS | flannel | [docs](rackspace.md) | | Community (@doublerr) -any | any | any | any | [docs](scratch.md) | | Community (@erictune) - - -*Note*: The above table is ordered by version test/used in notes followed by support level. - -Definition of columns: - - **IaaS Provider** is who/what provides the virtual or physical machines (nodes) that Kubernetes runs on. - - **OS** is the base operating system of the nodes. - - **Config. Mgmt** is the configuration management system that helps install and maintain Kubernetes software on the - nodes. - - **Networking** is what implements the [networking model](../../docs/admin/networking.md). Those with networking type - _none_ may not support more than one node, or may support multiple VM nodes only in the same physical node. - - **Conformance** indicates whether a cluster created with this configuration has passed the project's conformance - tests for supporting the API and base features of Kubernetes v1.0.0. - - Support Levels - - **Project**: Kubernetes Committers regularly use this configuration, so it usually works with the latest release - of Kubernetes. - - **Commercial**: A commercial offering with its own support arrangements. - - **Community**: Actively supported by community contributions. May not work with more recent releases of Kubernetes. - - **Inactive**: No active maintainer. Not recommended for first-time Kubernetes users, and may be deleted soon. - - **Notes** is relevant information such as the version of Kubernetes used. - - - -[1]: https://gist.github.com/erictune/4cabc010906afbcc5061 - -[2]: https://gist.github.com/derekwaynecarr/505e56036cdf010bf6b6 - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/all-lines.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/all-lines.png deleted file mode 100644 index 7de0438af632ee64e1efbb4e857f69b902cd1f35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 226552 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≥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

    #9~@#s#afj=TayG~ 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�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%0A$YL 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 a;;&9#zjgMJhlLpb%$nh7cf!VN>wf`%>059B diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws-coreos.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws-coreos.md deleted file mode 100644 index 2b14c2c49bb6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws-coreos.md +++ /dev/null @@ -1,250 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/aws-coreos.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Getting started on Amazon EC2 with CoreOS - -The example below creates an elastic Kubernetes cluster with a custom number of worker nodes and a master. - -**Warning:** contrary to the [supported procedure](aws.md), the examples below provision Kubernetes with an insecure API server (plain HTTP, -no security tokens, no basic auth). For demonstration purposes only. - -## Highlights - -* Cluster bootstrapping using [cloud-config](https://coreos.com/docs/cluster-management/setup/cloudinit-cloud-config/) -* Cross container networking with [flannel](https://github.com/coreos/flannel#flannel) -* Auto worker registration with [kube-register](https://github.com/kelseyhightower/kube-register#kube-register) -* Kubernetes v0.19.3 [official binaries](https://k8s.io/kubernetes/releases/tag/v0.19.3) - -## Prerequisites - -* [aws CLI](http://aws.amazon.com/cli) -* [CoreOS image for AWS](https://coreos.com/docs/running-coreos/cloud-providers/ec2/) -* [kubectl CLI](aws/kubectl.md) ([installation](aws.md#command-line-administration-tool-kubectl)) - -## Starting a Cluster - -### CloudFormation - -The [cloudformation-template.json](aws/cloudformation-template.json) can be used to bootstrap a Kubernetes cluster with a single command: - -```bash -aws cloudformation create-stack --stack-name kubernetes --region us-west-2 \ ---template-body file://aws/cloudformation-template.json \ ---parameters ParameterKey=KeyPair,ParameterValue= \ - ParameterKey=ClusterSize,ParameterValue= \ - ParameterKey=VpcId,ParameterValue= \ - ParameterKey=SubnetId,ParameterValue= \ - ParameterKey=SubnetAZ,ParameterValue= -``` - -It will take a few minutes for the entire stack to come up. You can monitor the stack progress with the following command: - -```bash -aws cloudformation describe-stack-events --stack-name kubernetes -``` - -Record the Kubernetes Master IP address: - -```bash -aws cloudformation describe-stacks --stack-name kubernetes -``` - -[Skip to kubectl client configuration](#configure-the-kubectl-ssh-tunnel) - -### AWS CLI - -The following commands shall use the latest CoreOS alpha AMI for the `us-west-2` region. For a list of different regions and corresponding AMI IDs see the [CoreOS EC2 cloud provider documentation](https://coreos.com/docs/running-coreos/cloud-providers/ec2/#choosing-a-channel). - -#### Create the Kubernetes Security Group - -```bash -aws ec2 create-security-group --group-name kubernetes --description "Kubernetes Security Group" -aws ec2 authorize-security-group-ingress --group-name kubernetes --protocol tcp --port 22 --cidr 0.0.0.0/0 -aws ec2 authorize-security-group-ingress --group-name kubernetes --protocol tcp --port 80 --cidr 0.0.0.0/0 -aws ec2 authorize-security-group-ingress --group-name kubernetes --source-security-group-name kubernetes -``` - -#### Save the master and node cloud-configs - -* [master.yaml](aws/cloud-configs/master.yaml) -* [node.yaml](aws/cloud-configs/node.yaml) - -#### Launch the master - -*Attention:* replace `` below for a [suitable version of CoreOS image for AWS](https://coreos.com/docs/running-coreos/cloud-providers/ec2/). - -```bash -aws ec2 run-instances --image-id --key-name \ ---region us-west-2 --security-groups kubernetes --instance-type m3.medium \ ---user-data file://master.yaml -``` - -Record the `InstanceId` for the master. - -Gather the public and private IPs for the master node: - -```bash -aws ec2 describe-instances --instance-id -``` - -```json -{ - "Reservations": [ - { - "Instances": [ - { - "PublicDnsName": "ec2-54-68-97-117.us-west-2.compute.amazonaws.com", - "RootDeviceType": "ebs", - "State": { - "Code": 16, - "Name": "running" - }, - "PublicIpAddress": "54.68.97.117", - "PrivateIpAddress": "172.31.9.9", -``` - -#### Update the node.yaml cloud-config - -Edit `node.yaml` and replace all instances of `` with the **private** IP address of the master node. - -### Launch 3 worker nodes - -*Attention:* Replace `` below for a [suitable version of CoreOS image for AWS](https://coreos.com/docs/running-coreos/cloud-providers/ec2/#choosing-a-channel). - -```bash -aws ec2 run-instances --count 3 --image-id --key-name \ ---region us-west-2 --security-groups kubernetes --instance-type m3.medium \ ---user-data file://node.yaml -``` - -### Add additional worker nodes - -*Attention:* replace `` below for a [suitable version of CoreOS image for AWS](https://coreos.com/docs/running-coreos/cloud-providers/ec2/#choosing-a-channel). - -```bash -aws ec2 run-instances --count 1 --image-id --key-name \ ---region us-west-2 --security-groups kubernetes --instance-type m3.medium \ ---user-data file://node.yaml -``` - -### Configure the kubectl SSH tunnel - -This command enables secure communication between the kubectl client and the Kubernetes API. - -```bash -ssh -f -nNT -L 8080:127.0.0.1:8080 core@ -``` - -### Listing worker nodes - -Once the worker instances have fully booted, they will be automatically registered with the Kubernetes API server by the kube-register service running on the master node. It may take a few mins. - -```bash -kubectl get nodes -``` - -## Starting a simple pod - -Create a pod manifest: `pod.json` - -```json -{ - "apiVersion": "v1", - "kind": "Pod", - "metadata": { - "name": "hello", - "labels": { - "name": "hello", - "environment": "testing" - } - }, - "spec": { - "containers": [{ - "name": "hello", - "image": "quay.io/kelseyhightower/hello", - "ports": [{ - "containerPort": 80, - "hostPort": 80 - }] - }] - } -} -``` - -### Create the pod using the kubectl command line tool - -```bash -kubectl create -f ./pod.json -``` - -### Testing - -```bash -kubectl get pods -``` - -Record the **Host** of the pod, which should be the private IP address. - -Gather the public IP address for the worker node. - -```bash -aws ec2 describe-instances --filters 'Name=private-ip-address,Values=' -``` - -```json -{ - "Reservations": [ - { - "Instances": [ - { - "PublicDnsName": "ec2-54-68-97-117.us-west-2.compute.amazonaws.com", - "RootDeviceType": "ebs", - "State": { - "Code": 16, - "Name": "running" - }, - "PublicIpAddress": "54.68.97.117", -``` - -Visit the public IP address in your browser to view the running pod. - -### Delete the pod - -```bash -kubectl delete pods hello -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/aws-coreos.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws.md deleted file mode 100644 index 988f9cb9814f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws.md +++ /dev/null @@ -1,144 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/aws.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started on AWS EC2 --------------------------- - -**Table of Contents** - -- [Prerequisites](#prerequisites) -- [Cluster turnup](#cluster-turnup) - - [Supported procedure: `get-kube`](#supported-procedure-get-kube) - - [Alternatives](#alternatives) -- [Getting started with your cluster](#getting-started-with-your-cluster) - - [Command line administration tool: `kubectl`](#command-line-administration-tool-kubectl) - - [Examples](#examples) -- [Tearing down the cluster](#tearing-down-the-cluster) -- [Further reading](#further-reading) - -## Prerequisites - -1. You need an AWS account. Visit [http://aws.amazon.com](http://aws.amazon.com) to get started -2. Install and configure [AWS Command Line Interface](http://aws.amazon.com/cli) -3. You need an AWS [instance profile and role](http://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html) with EC2 full access. - -## Cluster turnup - -### Supported procedure: `get-kube` - -```bash -#Using wget -export KUBERNETES_PROVIDER=aws; wget -q -O - https://get.k8s.io | bash - -#Using cURL -export KUBERNETES_PROVIDER=aws; curl -sS https://get.k8s.io | bash -``` - -NOTE: This script calls [cluster/kube-up.sh](http://releases.k8s.io/HEAD/cluster/kube-up.sh) -which in turn calls [cluster/aws/util.sh](http://releases.k8s.io/HEAD/cluster/aws/util.sh) -using [cluster/aws/config-default.sh](http://releases.k8s.io/HEAD/cluster/aws/config-default.sh). - -This process takes about 5 to 10 minutes. Once the cluster is up, the IP addresses of your master and node(s) will be printed, -as well as information about the default services running in the cluster (monitoring, logging, dns). User credentials and security -tokens are written in `~/.kube/kubeconfig`, they will be necessary to use the CLI or the HTTP Basic Auth. - -By default, the script will provision a new VPC and a 4 node k8s cluster in us-west-2a (Oregon) with `t2.micro` instances running on Ubuntu. -You can override the variables defined in [config-default.sh](http://releases.k8s.io/HEAD/cluster/aws/config-default.sh) to change this behavior as follows: - -```bash -export KUBE_AWS_ZONE=eu-west-1c -export NUM_MINIONS=2 -export MINION_SIZE=m3.medium -export AWS_S3_REGION=eu-west-1 -export AWS_S3_BUCKET=mycompany-kubernetes-artifacts -export INSTANCE_PREFIX=k8s -... -``` - -It will also try to create or reuse a keypair called "kubernetes", and IAM profiles called "kubernetes-master" and "kubernetes-minion". -If these already exist, make sure you want them to be used here. - -NOTE: If using an existing keypair named "kubernetes" then you must set the `AWS_SSH_KEY` key to point to your private key. - -### Alternatives - -A contributed [example](aws-coreos.md) allows you to setup a Kubernetes cluster based on [CoreOS](http://www.coreos.com), either using -AWS CloudFormation or EC2 with user data (cloud-config). - -## Getting started with your cluster - -### Command line administration tool: `kubectl` - -The cluster startup script will leave you with a `kubernetes` directory on your workstation. -Alternately, you can download the latest Kubernetes release from [this page](https://k8s.io/kubernetes/releases). - -Next, add the appropriate binary folder to your `PATH` to access kubectl: - -```bash -# OS X -export PATH=/platforms/darwin/amd64:$PATH - -# Linux -export PATH=/platforms/linux/amd64:$PATH -``` - -An up-to-date documentation page for this tool is available here: [kubectl manual](../../docs/user-guide/kubectl/kubectl.md) - -By default, `kubectl` will use the `kubeconfig` file generated during the cluster startup for authenticating against the API. -For more information, please read [kubeconfig files](../../docs/user-guide/kubeconfig-file.md) - -### Examples - -See [a simple nginx example](../../docs/user-guide/simple-nginx.md) to try out your new cluster. - -The "Guestbook" application is another popular example to get started with Kubernetes: [guestbook example](../../examples/guestbook/) - -For more complete applications, please look in the [examples directory](../../examples/) - -## Tearing down the cluster - -Make sure the environment variables you used to provision your cluster are still exported, then call the following script inside the -`kubernetes` directory: - -```bash -cluster/kube-down.sh -``` - -## Further reading - -Please see the [Kubernetes docs](../../docs/) for more details on administering -and using a Kubernetes cluster. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/aws.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloud-configs/master.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloud-configs/master.yaml deleted file mode 100644 index ae5880d86cd3..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloud-configs/master.yaml +++ /dev/null @@ -1,177 +0,0 @@ -#cloud-config - -write_files: - - path: /opt/bin/waiter.sh - owner: root - permissions: 0755 - content: | - #! /usr/bin/bash - until curl http://127.0.0.1:2379/v2/machines; do sleep 2; done - -coreos: - etcd2: - name: master - initial-cluster-token: k8s_etcd - initial-cluster: master=http://$private_ipv4:2380 - listen-peer-urls: http://$private_ipv4:2380,http://localhost:2380 - initial-advertise-peer-urls: http://$private_ipv4:2380 - listen-client-urls: http://$private_ipv4:2379,http://localhost:2379 - advertise-client-urls: http://$private_ipv4:2379 - fleet: - etcd_servers: http://localhost:2379 - metadata: k8srole=master - flannel: - etcd_endpoints: http://localhost:2379 - locksmithd: - endpoint: http://localhost:2379 - units: - - name: etcd2.service - command: start - - name: fleet.service - command: start - - name: etcd2-waiter.service - command: start - content: | - [Unit] - Description=etcd waiter - Wants=network-online.target - Wants=etcd2.service - After=etcd2.service - After=network-online.target - Before=flanneld.service fleet.service locksmithd.service - - [Service] - ExecStart=/usr/bin/bash /opt/bin/waiter.sh - RemainAfterExit=true - Type=oneshot - - name: flanneld.service - command: start - drop-ins: - - name: 50-network-config.conf - content: | - [Service] - ExecStartPre=-/usr/bin/etcdctl mk /coreos.com/network/config '{"Network": "10.244.0.0/16", "Backend": {"Type": "vxlan"}}' - - name: docker-cache.service - command: start - content: | - [Unit] - Description=Docker cache proxy - Requires=early-docker.service - After=early-docker.service - Before=early-docker.target - - [Service] - Restart=always - TimeoutStartSec=0 - RestartSec=5 - Environment=TMPDIR=/var/tmp/ - Environment=DOCKER_HOST=unix:///var/run/early-docker.sock - ExecStartPre=-/usr/bin/docker kill docker-registry - ExecStartPre=-/usr/bin/docker rm docker-registry - ExecStartPre=/usr/bin/docker pull quay.io/devops/docker-registry:latest - # GUNICORN_OPTS is an workaround for - # https://github.com/docker/docker-registry/issues/892 - ExecStart=/usr/bin/docker run --rm --net host --name docker-registry \ - -e STANDALONE=false \ - -e GUNICORN_OPTS=[--preload] \ - -e MIRROR_SOURCE=https://registry-1.docker.io \ - -e MIRROR_SOURCE_INDEX=https://index.docker.io \ - -e MIRROR_TAGS_CACHE_TTL=1800 \ - quay.io/devops/docker-registry:latest - - name: docker.service - drop-ins: - - name: 51-docker-mirror.conf - content: | - [Unit] - # making sure that docker-cache is up and that flanneld finished - # startup, otherwise containers won't land in flannel's network... - Requires=docker-cache.service - After=docker-cache.service - - [Service] - Environment=DOCKER_OPTS='--registry-mirror=http://$private_ipv4:5000' - - name: get-kubectl.service - command: start - content: | - [Unit] - Description=Get kubectl client tool - Documentation=https://k8s.io/kubernetes - Requires=network-online.target - After=network-online.target - - [Service] - ExecStart=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kubectl - ExecStart=/usr/bin/chmod +x /opt/bin/kubectl - Type=oneshot - RemainAfterExit=true - - name: kube-apiserver.service - command: start - content: | - [Unit] - Description=Kubernetes API Server - Documentation=https://k8s.io/kubernetes - Requires=etcd2-waiter.service - After=etcd2-waiter.service - - [Service] - ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kube-apiserver - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-apiserver - ExecStart=/opt/bin/kube-apiserver \ - --insecure-bind-address=0.0.0.0 \ - --service-cluster-ip-range=10.100.0.0/16 \ - --etcd-servers=http://localhost:2379 - Restart=always - RestartSec=10 - - name: kube-controller-manager.service - command: start - content: | - [Unit] - Description=Kubernetes Controller Manager - Documentation=https://k8s.io/kubernetes - Requires=kube-apiserver.service - After=kube-apiserver.service - - [Service] - ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kube-controller-manager - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-controller-manager - ExecStart=/opt/bin/kube-controller-manager \ - --master=127.0.0.1:8080 - Restart=always - RestartSec=10 - - name: kube-scheduler.service - command: start - content: | - [Unit] - Description=Kubernetes Scheduler - Documentation=https://k8s.io/kubernetes - Requires=kube-apiserver.service - After=kube-apiserver.service - - [Service] - ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kube-scheduler - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-scheduler - ExecStart=/opt/bin/kube-scheduler \ - --master=127.0.0.1:8080 - Restart=always - RestartSec=10 - - name: kube-register.service - command: start - content: | - [Unit] - Description=Kubernetes Registration Service - Documentation=https://github.com/kelseyhightower/kube-register - Requires=kube-apiserver.service fleet.service - After=kube-apiserver.service fleet.service - - [Service] - ExecStartPre=-/usr/bin/wget -nc -O /opt/bin/kube-register https://github.com/kelseyhightower/kube-register/releases/download/v0.0.4/kube-register-0.0.4-linux-amd64 - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-register - ExecStart=/opt/bin/kube-register \ - --metadata=k8srole=node \ - --fleet-endpoint=unix:///var/run/fleet.sock \ - --api-endpoint=http://127.0.0.1:8080 - Restart=always - RestartSec=10 - update: - group: alpha - reboot-strategy: off diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloud-configs/node.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloud-configs/node.yaml deleted file mode 100644 index 5554479c631e..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloud-configs/node.yaml +++ /dev/null @@ -1,81 +0,0 @@ -#cloud-config - -write_files: - - path: /opt/bin/wupiao - owner: root - permissions: 0755 - content: | - #!/bin/bash - # [w]ait [u]ntil [p]ort [i]s [a]ctually [o]pen - [ -n "$1" ] && [ -n "$2" ] && while ! curl --output /dev/null \ - --silent --head --fail \ - http://${1}:${2}; do sleep 1 && echo -n .; done; - exit $? - -coreos: - etcd2: - listen-client-urls: http://localhost:2379 - advertise-client-urls: http://0.0.0.0:2379 - initial-cluster: master=http://:2380 - proxy: on - fleet: - etcd_servers: http://localhost:2379 - metadata: k8srole=node - flannel: - etcd_endpoints: http://localhost:2379 - locksmithd: - endpoint: http://localhost:2379 - units: - - name: etcd2.service - command: start - - name: fleet.service - command: start - - name: flanneld.service - command: start - - name: docker.service - command: start - drop-ins: - - name: 50-docker-mirror.conf - content: | - [Service] - Environment=DOCKER_OPTS='--registry-mirror=http://:5000' - - name: kubelet.service - command: start - content: | - [Unit] - Description=Kubernetes Kubelet - Documentation=https://k8s.io/kubernetes - Requires=network-online.target - After=network-online.target - - [Service] - ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kubelet - ExecStartPre=/usr/bin/chmod +x /opt/bin/kubelet - # wait for kubernetes master to be up and ready - ExecStartPre=/opt/bin/wupiao 8080 - ExecStart=/opt/bin/kubelet \ - --api-servers=:8080 \ - --hostname-override=$private_ipv4 - Restart=always - RestartSec=10 - - name: kube-proxy.service - command: start - content: | - [Unit] - Description=Kubernetes Proxy - Documentation=https://k8s.io/kubernetes - Requires=network-online.target - After=network-online.target - - [Service] - ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kube-proxy - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-proxy - # wait for kubernetes master to be up and ready - ExecStartPre=/opt/bin/wupiao 8080 - ExecStart=/opt/bin/kube-proxy \ - --master=http://:8080 - Restart=always - RestartSec=10 - update: - group: alpha - reboot-strategy: off diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloudformation-template.json b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloudformation-template.json deleted file mode 100644 index d6303adcd561..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/cloudformation-template.json +++ /dev/null @@ -1,421 +0,0 @@ -{ - "AWSTemplateFormatVersion": "2010-09-09", - "Description": "Kubernetes 0.19.3 on EC2 powered by CoreOS 681.2.0 (stable)", - "Mappings": { - "RegionMap": { - "eu-central-1" : { - "AMI" : "ami-eae5ddf7" - }, - "ap-northeast-1" : { - "AMI" : "ami-1a6fca1a" - }, - "us-gov-west-1" : { - "AMI" : "ami-e99fffca" - }, - "sa-east-1" : { - "AMI" : "ami-b1cb49ac" - }, - "ap-southeast-2" : { - "AMI" : "ami-23641e19" - }, - "ap-southeast-1" : { - "AMI" : "ami-da030788" - }, - "us-east-1" : { - "AMI" : "ami-93ea17f8" - }, - "us-west-2" : { - "AMI" : "ami-5d4d486d" - }, - "us-west-1" : { - "AMI" : "ami-c967938d" - }, - "eu-west-1" : { - "AMI" : "ami-5f2f5528" - } - } - }, - "Parameters": { - "InstanceType": { - "Description": "EC2 HVM instance type (m3.medium, etc).", - "Type": "String", - "Default": "m3.medium", - "AllowedValues": [ - "m3.medium", - "m3.large", - "m3.xlarge", - "m3.2xlarge", - "c3.large", - "c3.xlarge", - "c3.2xlarge", - "c3.4xlarge", - "c3.8xlarge", - "cc2.8xlarge", - "cr1.8xlarge", - "hi1.4xlarge", - "hs1.8xlarge", - "i2.xlarge", - "i2.2xlarge", - "i2.4xlarge", - "i2.8xlarge", - "r3.large", - "r3.xlarge", - "r3.2xlarge", - "r3.4xlarge", - "r3.8xlarge", - "t2.micro", - "t2.small", - "t2.medium" - ], - "ConstraintDescription": "Must be a valid EC2 HVM instance type." - }, - "ClusterSize": { - "Description": "Number of nodes in cluster (2-12).", - "Default": "2", - "MinValue": "2", - "MaxValue": "12", - "Type": "Number" - }, - "AllowSSHFrom": { - "Description": "The net block (CIDR) that SSH is available to.", - "Default": "0.0.0.0/0", - "Type": "String" - }, - "KeyPair": { - "Description": "The name of an EC2 Key Pair to allow SSH access to the instance.", - "Type": "AWS::EC2::KeyPair::KeyName" - }, - "VpcId": { - "Description": "The ID of the VPC to launch into.", - "Type": "AWS::EC2::VPC::Id" - }, - "SubnetId": { - "Description": "The ID of the subnet to launch into (that must be within the supplied VPC)", - "Type": "AWS::EC2::Subnet::Id" - }, - "SubnetAZ": { - "Description": "The availability zone of the subnet supplied (for example eu-west-1a)", - "Type": "String" - } - }, - "Conditions": { - "UseEC2Classic": {"Fn::Equals": [{"Ref": "VpcId"}, ""]} - }, - "Resources": { - "KubernetesSecurityGroup": { - "Type": "AWS::EC2::SecurityGroup", - "Properties": { - "VpcId": {"Fn::If": ["UseEC2Classic", {"Ref": "AWS::NoValue"}, {"Ref": "VpcId"}]}, - "GroupDescription": "Kubernetes SecurityGroup", - "SecurityGroupIngress": [ - { - "IpProtocol": "tcp", - "FromPort": "22", - "ToPort": "22", - "CidrIp": {"Ref": "AllowSSHFrom"} - } - ] - } - }, - "KubernetesIngress": { - "Type": "AWS::EC2::SecurityGroupIngress", - "Properties": { - "GroupId": {"Fn::GetAtt": ["KubernetesSecurityGroup", "GroupId"]}, - "IpProtocol": "tcp", - "FromPort": "1", - "ToPort": "65535", - "SourceSecurityGroupId": { - "Fn::GetAtt" : [ "KubernetesSecurityGroup", "GroupId" ] - } - } - }, - "KubernetesIngressUDP": { - "Type": "AWS::EC2::SecurityGroupIngress", - "Properties": { - "GroupId": {"Fn::GetAtt": ["KubernetesSecurityGroup", "GroupId"]}, - "IpProtocol": "udp", - "FromPort": "1", - "ToPort": "65535", - "SourceSecurityGroupId": { - "Fn::GetAtt" : [ "KubernetesSecurityGroup", "GroupId" ] - } - } - }, - "KubernetesMasterInstance": { - "Type": "AWS::EC2::Instance", - "Properties": { - "NetworkInterfaces" : [{ - "GroupSet" : [{"Fn::GetAtt": ["KubernetesSecurityGroup", "GroupId"]}], - "AssociatePublicIpAddress" : "true", - "DeviceIndex" : "0", - "DeleteOnTermination" : "true", - "SubnetId" : {"Fn::If": ["UseEC2Classic", {"Ref": "AWS::NoValue"}, {"Ref": "SubnetId"}]} - }], - "ImageId": {"Fn::FindInMap" : ["RegionMap", {"Ref": "AWS::Region" }, "AMI"]}, - "InstanceType": {"Ref": "InstanceType"}, - "KeyName": {"Ref": "KeyPair"}, - "Tags" : [ - {"Key" : "Name", "Value" : {"Fn::Join" : [ "-", [ {"Ref" : "AWS::StackName"}, "k8s-master" ] ]}}, - {"Key" : "KubernetesRole", "Value" : "node"} - ], - "UserData": { "Fn::Base64": {"Fn::Join" : ["", [ - "#cloud-config\n\n", - "write_files:\n", - "- path: /opt/bin/waiter.sh\n", - " owner: root\n", - " content: |\n", - " #! /usr/bin/bash\n", - " until curl http://127.0.0.1:2379/v2/machines; do sleep 2; done\n", - "coreos:\n", - " etcd2:\n", - " name: master\n", - " initial-cluster-token: k8s_etcd\n", - " initial-cluster: master=http://$private_ipv4:2380\n", - " listen-peer-urls: http://$private_ipv4:2380,http://localhost:2380\n", - " initial-advertise-peer-urls: http://$private_ipv4:2380\n", - " listen-client-urls: http://$private_ipv4:2379,http://localhost:2379\n", - " advertise-client-urls: http://$private_ipv4:2379\n", - " fleet:\n", - " etcd_servers: http://localhost:2379\n", - " metadata: k8srole=master\n", - " flannel:\n", - " etcd_endpoints: http://localhost:2379\n", - " locksmithd:\n", - " endpoint: http://localhost:2379\n", - " units:\n", - " - name: etcd2.service\n", - " command: start\n", - " - name: fleet.service\n", - " command: start\n", - " - name: etcd2-waiter.service\n", - " command: start\n", - " content: |\n", - " [Unit]\n", - " Description=etcd waiter\n", - " Wants=network-online.target\n", - " Wants=etcd2.service\n", - " After=etcd2.service\n", - " After=network-online.target\n", - " Before=flanneld.service fleet.service locksmithd.service\n\n", - " [Service]\n", - " ExecStart=/usr/bin/bash /opt/bin/waiter.sh\n", - " RemainAfterExit=true\n", - " Type=oneshot\n", - " - name: flanneld.service\n", - " command: start\n", - " drop-ins:\n", - " - name: 50-network-config.conf\n", - " content: |\n", - " [Service]\n", - " ExecStartPre=-/usr/bin/etcdctl mk /coreos.com/network/config '{\"Network\": \"10.244.0.0/16\", \"Backend\": {\"Type\": \"vxlan\"}}'\n", - " - name: docker-cache.service\n", - " command: start\n", - " content: |\n", - " [Unit]\n", - " Description=Docker cache proxy\n", - " Requires=early-docker.service\n", - " After=early-docker.service\n", - " Before=early-docker.target\n\n", - " [Service]\n", - " Restart=always\n", - " TimeoutStartSec=0\n", - " RestartSec=5\n", - " Environment=TMPDIR=/var/tmp/\n", - " Environment=DOCKER_HOST=unix:///var/run/early-docker.sock\n", - " ExecStartPre=-/usr/bin/docker kill docker-registry\n", - " ExecStartPre=-/usr/bin/docker rm docker-registry\n", - " ExecStartPre=/usr/bin/docker pull quay.io/devops/docker-registry:latest\n", - " # GUNICORN_OPTS is an workaround for\n", - " # https://github.com/docker/docker-registry/issues/892\n", - " ExecStart=/usr/bin/docker run --rm --net host --name docker-registry \\\n", - " -e STANDALONE=false \\\n", - " -e GUNICORN_OPTS=[--preload] \\\n", - " -e MIRROR_SOURCE=https://registry-1.docker.io \\\n", - " -e MIRROR_SOURCE_INDEX=https://index.docker.io \\\n", - " -e MIRROR_TAGS_CACHE_TTL=1800 \\\n", - " quay.io/devops/docker-registry:latest\n", - " - name: get-kubectl.service\n", - " command: start\n", - " content: |\n", - " [Unit]\n", - " Description=Get kubectl client tool\n", - " Documentation=https://k8s.io/kubernetes\n", - " Requires=network-online.target\n", - " After=network-online.target\n\n", - " [Service]\n", - " ExecStart=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kubectl\n", - " ExecStart=/usr/bin/chmod +x /opt/bin/kubectl\n", - " Type=oneshot\n", - " RemainAfterExit=true\n", - " - name: kube-apiserver.service\n", - " command: start\n", - " content: |\n", - " [Unit]\n", - " Description=Kubernetes API Server\n", - " Documentation=https://k8s.io/kubernetes\n", - " Requires=etcd2-waiter.service\n", - " After=etcd2-waiter.service\n\n", - " [Service]\n", - " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kube-apiserver\n", - " ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-apiserver\n", - " ExecStart=/opt/bin/kube-apiserver \\\n", - " --insecure-bind-address=0.0.0.0 \\\n", - " --service-cluster-ip-range=10.100.0.0/16 \\\n", - " --etcd-servers=http://localhost:2379\n", - " Restart=always\n", - " RestartSec=10\n", - " - name: kube-controller-manager.service\n", - " command: start\n", - " content: |\n", - " [Unit]\n", - " Description=Kubernetes Controller Manager\n", - " Documentation=https://k8s.io/kubernetes\n", - " Requires=kube-apiserver.service\n", - " After=kube-apiserver.service\n\n", - " [Service]\n", - " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kube-controller-manager\n", - " ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-controller-manager\n", - " ExecStart=/opt/bin/kube-controller-manager \\\n", - " --master=127.0.0.1:8080\n", - " Restart=always\n", - " RestartSec=10\n", - " - name: kube-scheduler.service\n", - " command: start\n", - " content: |\n", - " [Unit]\n", - " Description=Kubernetes Scheduler\n", - " Documentation=https://k8s.io/kubernetes\n", - " Requires=kube-apiserver.service\n", - " After=kube-apiserver.service\n\n", - " [Service]\n", - " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kube-scheduler\n", - " ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-scheduler\n", - " ExecStart=/opt/bin/kube-scheduler \\\n", - " --master=127.0.0.1:8080\n", - " Restart=always\n", - " RestartSec=10\n", - " - name: kube-register.service\n", - " command: start\n", - " content: |\n", - " [Unit]\n", - " Description=Kubernetes Registration Service\n", - " Documentation=https://github.com/kelseyhightower/kube-register\n", - " Requires=kube-apiserver.service fleet.service\n", - " After=kube-apiserver.service fleet.service\n\n", - " [Service]\n", - " ExecStartPre=-/usr/bin/wget -nc -O /opt/bin/kube-register https://github.com/kelseyhightower/kube-register/releases/download/v0.0.4/kube-register-0.0.4-linux-amd64\n", - " ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-register\n", - " ExecStart=/opt/bin/kube-register \\\n", - " --metadata=k8srole=node \\\n", - " --fleet-endpoint=unix:///var/run/fleet.sock \\\n", - " --api-endpoint=http://127.0.0.1:8080\n", - " Restart=always\n", - " RestartSec=10\n", - " update:\n", - " group: alpha\n", - " reboot-strategy: off\n" - ]]} - } - } - }, - "KubernetesNodeLaunchConfig": { - "Type": "AWS::AutoScaling::LaunchConfiguration", - "Properties": { - "ImageId": {"Fn::FindInMap" : ["RegionMap", {"Ref": "AWS::Region" }, "AMI" ]}, - "InstanceType": {"Ref": "InstanceType"}, - "KeyName": {"Ref": "KeyPair"}, - "AssociatePublicIpAddress" : "true", - "SecurityGroups": [{"Fn::If": [ - "UseEC2Classic", - {"Ref": "KubernetesSecurityGroup"}, - {"Fn::GetAtt": ["KubernetesSecurityGroup", "GroupId"]}] - }], - "UserData": { "Fn::Base64": {"Fn::Join" : ["", [ - "#cloud-config\n\n", - "coreos:\n", - " etcd2:\n", - " listen-client-urls: http://localhost:2379\n", - " initial-cluster: master=http://", {"Fn::GetAtt" :["KubernetesMasterInstance" , "PrivateIp"]}, ":2380\n", - " proxy: on\n", - " fleet:\n", - " etcd_servers: http://localhost:2379\n", - " metadata: k8srole=node\n", - " flannel:\n", - " etcd_endpoints: http://localhost:2379\n", - " locksmithd:\n", - " endpoint: http://localhost:2379\n", - " units:\n", - " - name: etcd2.service\n", - " command: start\n", - " - name: fleet.service\n", - " command: start\n", - " - name: flanneld.service\n", - " command: start\n", - " - name: docker.service\n", - " command: start\n", - " drop-ins:\n", - " - name: 50-docker-mirror.conf\n", - " content: |\n", - " [Service]\n", - " Environment=DOCKER_OPTS='--registry-mirror=http://", {"Fn::GetAtt" :["KubernetesMasterInstance" , "PrivateIp"]}, ":5000'\n", - " - name: kubelet.service\n", - " command: start\n", - " content: |\n", - " [Unit]\n", - " Description=Kubernetes Kubelet\n", - " Documentation=https://k8s.io/kubernetes\n", - " Requires=network-online.target\n", - " After=network-online.target\n\n", - " [Service]\n", - " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kubelet\n", - " ExecStartPre=/usr/bin/chmod +x /opt/bin/kubelet\n", - " ExecStart=/opt/bin/kubelet \\\n", - " --api-servers=", {"Fn::GetAtt" :["KubernetesMasterInstance" , "PrivateIp"]}, ":8080 \\\n", - " --hostname-override=$private_ipv4\n", - " Restart=always\n", - " RestartSec=10\n", - " - name: kube-proxy.service\n", - " command: start\n", - " content: |\n", - " [Unit]\n", - " Description=Kubernetes Proxy\n", - " Documentation=https://k8s.io/kubernetes\n", - " Requires=network-online.target\n", - " After=network-online.target\n\n", - " [Service]\n", - " ExecStartPre=/usr/bin/wget -N -P /opt/bin https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kube-proxy\n", - " ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-proxy\n", - " ExecStart=/opt/bin/kube-proxy \\\n", - " --master=http://", {"Fn::GetAtt" :["KubernetesMasterInstance" , "PrivateIp"]}, ":8080\n", - " Restart=always\n", - " RestartSec=10\n", - " update:\n", - " group: alpha\n", - " reboot-strategy: off\n" - ]]} - } - } - }, - "KubernetesAutoScalingGroup": { - "Type": "AWS::AutoScaling::AutoScalingGroup", - "Properties": { - "AvailabilityZones": {"Fn::If": ["UseEC2Classic", {"Fn::GetAZs": ""}, [{"Ref": "SubnetAZ"}]]}, - "VPCZoneIdentifier": {"Fn::If": ["UseEC2Classic", {"Ref": "AWS::NoValue"}, [{"Ref": "SubnetId"}]]}, - "LaunchConfigurationName": {"Ref": "KubernetesNodeLaunchConfig"}, - "MinSize": "2", - "MaxSize": "12", - "DesiredCapacity": {"Ref": "ClusterSize"}, - "Tags" : [ - {"Key" : "Name", "Value" : {"Fn::Join" : [ "-", [ {"Ref" : "AWS::StackName"}, "k8s-node" ] ]}, "PropagateAtLaunch" : true}, - {"Key" : "KubernetesRole", "Value" : "node", "PropagateAtLaunch" : true} - ] - } - } - }, - "Outputs": { - "KubernetesMasterPublicIp": { - "Description": "Public Ip of the newly created Kubernetes Master instance", - "Value": {"Fn::GetAtt": ["KubernetesMasterInstance" , "PublicIp"]} - } - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/kubectl.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/kubectl.md deleted file mode 100644 index a5d6f435b019..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/aws/kubectl.md +++ /dev/null @@ -1,62 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/aws/kubectl.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Install and configure kubectl - -## Download the kubectl CLI tool - -```bash -### Darwin -wget https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/darwin/amd64/kubectl - -### Linux -wget https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kubectl -``` - -### Copy kubectl to your path - -```bash -chmod +x kubectl -mv kubectl /usr/local/bin/ -``` - -### Create a secure tunnel for API communication - -```bash -ssh -f -nNT -L 8080:127.0.0.1:8080 core@ -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/aws/kubectl.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/azure.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/azure.md deleted file mode 100644 index 539d923802d5..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/azure.md +++ /dev/null @@ -1,115 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/azure.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started on Microsoft Azure ----------------------------------- - -**Table of Contents** - -- [Prerequisites](#prerequisites) -- [Setup](#setup) -- [Getting started with your cluster](#getting-started-with-your-cluster) -- [Tearing down the cluster](#tearing-down-the-cluster) - - -## Prerequisites - -** Azure Prerequisites** - -1. You need an Azure account. Visit http://azure.microsoft.com/ to get started. -2. Install and configure the Azure cross-platform command-line interface. http://azure.microsoft.com/en-us/documentation/articles/xplat-cli/ -3. Make sure you have a default account set in the Azure cli, using `azure account set` - -**Prerequisites for your workstation** - -1. Be running a Linux or Mac OS X. -2. Get or build a [binary release](binary_release.md) -3. If you want to build your own release, you need to have [Docker -installed](https://docs.docker.com/installation/). On Mac OS X you can use -[boot2docker](http://boot2docker.io/). - -## Setup - -### Starting a cluster - -The cluster setup scripts can setup Kubernetes for multiple targets. First modify `cluster/kube-env.sh` to specify azure: - - KUBERNETES_PROVIDER="azure" - -Next, specify an existing virtual network and subnet in `cluster/azure/config-default.sh`: - - AZ_VNET= - AZ_SUBNET= - -You can create a virtual network: - - azure network vnet create --subnet-name= --location "West US" -v - -Now you're ready. - -You can download and install the latest Kubernetes release from [this page](https://k8s.io/kubernetes/releases), then run the `/cluster/kube-up.sh` script to start the cluster: - - cd kubernetes - cluster/kube-up.sh - -The script above will start (by default) a single master VM along with 4 worker VMs. You -can tweak some of these parameters by editing `cluster/azure/config-default.sh`. - -### Adding the Kubernetes command line tools to PATH - -The [kubectl](../../docs/user-guide/kubectl/kubectl.md) tool controls the Kubernetes cluster manager. It lets you inspect your cluster resources, create, delete, and update components, and much more. -You will use it to look at your new cluster and bring up example apps. - -Add the appropriate binary folder to your `PATH` to access kubectl: - - # OS X - export PATH=/platforms/darwin/amd64:$PATH - - # Linux - export PATH=/platforms/linux/amd64:$PATH - -## Getting started with your cluster - -See [a simple nginx example](../user-guide/simple-nginx.md) to try out your new cluster. - -For more complete applications, please look in the [examples directory](../../examples/). - -## Tearing down the cluster - -```sh -cluster/kube-down.sh -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/azure.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/bigquery-logging.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/bigquery-logging.png deleted file mode 100644 index b7a6f94c288e973636ac31a9d870157a8e7ae7dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57417 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 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/binary_release.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/binary_release.md deleted file mode 100644 index 589938a08734..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/binary_release.md +++ /dev/null @@ -1,61 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/binary_release.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Getting a Binary Release - -You can either build a release from sources or download a pre-built release. If you do not plan on developing Kubernetes itself, we suggest a pre-built release. - -### Prebuilt Binary Release - -The list of binary releases is available for download from the [GitHub Kubernetes repo release page](https://k8s.io/kubernetes/releases). - -Download the latest release and unpack this tar file on Linux or OS X, cd to the created `kubernetes/` directory, and then follow the getting started guide for your cloud. - -### Building from source - -Get the Kubernetes source. If you are simply building a release from source there is no need to set up a full golang environment as all building happens in a Docker container. - -Building a release is simple. - -```bash -git clone https://k8s.io/kubernetes.git -cd kubernetes -make release -``` - -For more details on the release process see the [`build/` directory](http://releases.k8s.io/HEAD/build/) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/binary_release.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/centos/centos_manual_config.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/centos/centos_manual_config.md deleted file mode 100644 index af6d02c18080..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/centos/centos_manual_config.md +++ /dev/null @@ -1,207 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/centos/centos_manual_config.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started on [CentOS](http://centos.org) ----------------------------------------------- - -**Table of Contents** - -- [Prerequisites](#prerequisites) -- [Starting a cluster](#starting-a-cluster) - -## Prerequisites - -You need two machines with CentOS installed on them. - -## Starting a cluster - -This is a getting started guide for CentOS. It is a manual configuration so you understand all the underlying packages / services / ports, etc... - -This guide will only get ONE node working. Multiple nodes requires a functional [networking configuration](../../admin/networking.md) done outside of kubernetes. Although the additional Kubernetes configuration requirements should be obvious. - -The Kubernetes package provides a few services: kube-apiserver, kube-scheduler, kube-controller-manager, kubelet, kube-proxy. These services are managed by systemd and the configuration resides in a central location: /etc/kubernetes. We will break the services up between the hosts. The first host, centos-master, will be the Kubernetes master. This host will run the kube-apiserver, kube-controller-manager, and kube-scheduler. In addition, the master will also run _etcd_. The remaining host, centos-minion will be the node and run kubelet, proxy, cadvisor and docker. - -**System Information:** - -Hosts: - -``` -centos-master = 192.168.121.9 -centos-minion = 192.168.121.65 -``` - -**Prepare the hosts:** - -* Create virt7-testing repo on all hosts - centos-{master,minion} with following information. - -``` -[virt7-testing] -name=virt7-testing -baseurl=http://cbs.centos.org/repos/virt7-testing/x86_64/os/ -gpgcheck=0 -``` - -* Install Kubernetes on all hosts - centos-{master,minion}. This will also pull in etcd, docker, and cadvisor. - -```sh -yum -y install --enablerepo=virt7-testing kubernetes -``` - -* Note * Using etcd-0.4.6-7 (This is temporary update in documentation) - -If you do not get etcd-0.4.6-7 installed with virt7-testing repo, - -In the current virt7-testing repo, the etcd package is updated which causes service failure. To avoid this, - -```sh -yum erase etcd -``` - -It will uninstall the current available etcd package - -```sh -yum install http://cbs.centos.org/kojifiles/packages/etcd/0.4.6/7.el7.centos/x86_64/etcd-0.4.6-7.el7.centos.x86_64.rpm -yum -y install --enablerepo=virt7-testing kubernetes -``` - -* Add master and node to /etc/hosts on all machines (not needed if hostnames already in DNS) - -```sh -echo "192.168.121.9 centos-master -192.168.121.65 centos-minion" >> /etc/hosts -``` - -* Edit /etc/kubernetes/config which will be the same on all hosts to contain: - -```sh -# Comma separated list of nodes in the etcd cluster -KUBE_ETCD_SERVERS="--etcd_servers=http://centos-master:4001" - -# logging to stderr means we get it in the systemd journal -KUBE_LOGTOSTDERR="--logtostderr=true" - -# journal message level, 0 is debug -KUBE_LOG_LEVEL="--v=0" - -# Should this cluster be allowed to run privileged docker containers -KUBE_ALLOW_PRIV="--allow_privileged=false" -``` - -* Disable the firewall on both the master and node, as docker does not play well with other firewall rule managers - -```sh -systemctl disable iptables-services firewalld -systemctl stop iptables-services firewalld -``` - -**Configure the Kubernetes services on the master.** - -* Edit /etc/kubernetes/apiserver to appear as such: - -```sh -# The address on the local server to listen to. -KUBE_API_ADDRESS="--address=0.0.0.0" - -# The port on the local server to listen on. -KUBE_API_PORT="--port=8080" - -# How the replication controller and scheduler find the kube-apiserver -KUBE_MASTER="--master=http://centos-master:8080" - -# Port kubelets listen on -KUBELET_PORT="--kubelet_port=10250" - -# Address range to use for services -KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16" - -# Add your own! -KUBE_API_ARGS="" -``` - -* Start the appropriate services on master: - -```sh -for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do - systemctl restart $SERVICES - systemctl enable $SERVICES - systemctl status $SERVICES -done -``` - -**Configure the Kubernetes services on the node.** - -***We need to configure the kubelet and start the kubelet and proxy*** - -* Edit /etc/kubernetes/kubelet to appear as such: - -```sh -# The address for the info server to serve on -KUBELET_ADDRESS="--address=0.0.0.0" - -# The port for the info server to serve on -KUBELET_PORT="--port=10250" - -# You may leave this blank to use the actual hostname -KUBELET_HOSTNAME="--hostname_override=centos-minion" - -# Add your own! -KUBELET_ARGS="" -``` - -* Start the appropriate services on node (centos-minion). - -```sh -for SERVICES in kube-proxy kubelet docker; do - systemctl restart $SERVICES - systemctl enable $SERVICES - systemctl status $SERVICES -done -``` - -*You should be finished!* - -* Check to make sure the cluster can see the node (on centos-master) - -```console -$ kubectl get nodes -NAME LABELS STATUS -centos-minion Ready -``` - -**The cluster should be running! Launch a test pod.** - -You should have a functional cluster, check out [101](../../../docs/user-guide/walkthrough/README.md)! - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/centos/centos_manual_config.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/cloud-logging-console.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/cloud-logging-console.png deleted file mode 100644 index fae0aecbc53d78d3f5304da70b4b429e684a9134..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87825 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≈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 zX008phBy

    u{e7;Hs{NvhBm)0o5#1}&p#}?lC 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 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/cloudstack.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/cloudstack.md deleted file mode 100644 index a08db9866b06..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/cloudstack.md +++ /dev/null @@ -1,121 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/cloudstack.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started on [CloudStack](http://cloudstack.apache.org) ------------------------------------------------------------- - -**Table of Contents** - -- [Introduction](#introduction) -- [Prerequisites](#prerequisites) -- [Clone the playbook](#clone-the-playbook) -- [Create a Kubernetes cluster](#create-a-kubernetes-cluster) - -### Introduction - -CloudStack is a software to build public and private clouds based on hardware virtualization principles (traditional IaaS). To deploy Kubernetes on CloudStack there are several possibilities depending on the Cloud being used and what images are made available. [Exoscale](http://exoscale.ch) for instance makes a [CoreOS](http://coreos.com) template available, therefore instructions to deploy Kubernetes on coreOS can be used. CloudStack also has a vagrant plugin available, hence Vagrant could be used to deploy Kubernetes either using the existing shell provisioner or using new Salt based recipes. - -[CoreOS](http://coreos.com) templates for CloudStack are built [nightly](http://stable.release.core-os.net/amd64-usr/current/). CloudStack operators need to [register](http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/templates.html) this template in their cloud before proceeding with these Kubernetes deployment instructions. - -This guide uses an [Ansible playbook](https://github.com/runseb/ansible-kubernetes). -This is a completely automated, a single playbook deploys Kubernetes based on the coreOS [instructions](coreos/coreos_multinode_cluster.md). - - -This [Ansible](http://ansibleworks.com) playbook deploys Kubernetes on a CloudStack based Cloud using CoreOS images. The playbook, creates an ssh key pair, creates a security group and associated rules and finally starts coreOS instances configured via cloud-init. - -### Prerequisites - - $ sudo apt-get install -y python-pip - $ sudo pip install ansible - $ sudo pip install cs - -[_cs_](https://github.com/exoscale/cs) is a python module for the CloudStack API. - -Set your CloudStack endpoint, API keys and HTTP method used. - -You can define them as environment variables: `CLOUDSTACK_ENDPOINT`, `CLOUDSTACK_KEY`, `CLOUDSTACK_SECRET` and `CLOUDSTACK_METHOD`. - -Or create a `~/.cloudstack.ini` file: - - [cloudstack] - endpoint = - key = - secret = - method = post - -We need to use the http POST method to pass the _large_ userdata to the coreOS instances. - -### Clone the playbook - - $ git clone --recursive https://github.com/runseb/ansible-kubernetes.git - $ cd ansible-kubernetes - -The [ansible-cloudstack](https://github.com/resmo/ansible-cloudstack) module is setup in this repository as a submodule, hence the `--recursive`. - -### Create a Kubernetes cluster - -You simply need to run the playbook. - - $ ansible-playbook k8s.yml - -Some variables can be edited in the `k8s.yml` file. - - vars: - ssh_key: k8s - k8s_num_nodes: 2 - k8s_security_group_name: k8s - k8s_node_prefix: k8s2 - k8s_template: Linux CoreOS alpha 435 64-bit 10GB Disk - k8s_instance_type: Tiny - -This will start a Kubernetes master node and a number of compute nodes (by default 2). -The `instance_type` and `template` by default are specific to [exoscale](http://exoscale.ch), edit them to specify your CloudStack cloud specific template and instance type (i.e service offering). - -Check the tasks and templates in `roles/k8s` if you want to modify anything. - -Once the playbook as finished, it will print out the IP of the Kubernetes master: - - TASK: [k8s | debug msg='k8s master IP is {{ k8s_master.default_ip }}'] ******** - -SSH to it using the key that was created and using the _core_ user and you can list the machines in your cluster: - - $ ssh -i ~/.ssh/id_rsa_k8s core@ - $ fleetctl list-machines - MACHINE IP METADATA - a017c422... role=node - ad13bf84... role=master - e9af8293... role=node - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/cloudstack.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos.md deleted file mode 100644 index d6adb9d4bf35..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos.md +++ /dev/null @@ -1,49 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/coreos.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Getting started on [CoreOS](http://coreos.com) - -There are multiple guides on running Kubernetes with [CoreOS](http://coreos.com): - -* [Multi-node Cluster](coreos/coreos_multinode_cluster.md) -* [Setup Multi-node Cluster on Google Compute Engine in an easy way](https://github.com/rimusz/coreos-multi-node-k8s-gce/blob/master/README.md) -* [Multi-node cluster using cloud-config and Weave on Vagrant](https://github.com/errordeveloper/weave-demos/blob/master/poseidon/README.md) -* [Multi-node cluster using cloud-config and Vagrant](https://github.com/pires/kubernetes-vagrant-coreos-cluster/blob/master/README.md) -* [Yet another multi-node cluster using cloud-config and Vagrant](https://github.com/AntonioMeireles/kubernetes-vagrant-coreos-cluster/blob/master/README.md) (similar to the one above but with an increased, more *aggressive* focus on features and flexibility) -* [Multi-node cluster with Vagrant and fleet units using a small OS X App](https://github.com/rimusz/coreos-osx-gui-kubernetes-cluster/blob/master/README.md) -* [Resizable multi-node cluster on Azure with Weave](coreos/azure/README.md) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/coreos.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/.gitignore b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/.gitignore deleted file mode 100644 index c2658d7d1b31..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules/ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/README.md deleted file mode 100644 index ac6bafd7ae83..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/README.md +++ /dev/null @@ -1,269 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/coreos/azure/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Kubernetes on Azure with CoreOS and [Weave](http://weave.works) ---------------------------------------------------------------- - -**Table of Contents** - -- [Introduction](#introduction) -- [Prerequisites](#prerequisites) -- [Let's go!](#lets-go) -- [Deploying the workload](#deploying-the-workload) -- [Scaling](#scaling) -- [Exposing the app to the outside world](#exposing-the-app-to-the-outside-world) -- [Next steps](#next-steps) -- [Tear down...](#tear-down) - -## Introduction - -In this guide I will demonstrate how to deploy a Kubernetes cluster to Azure cloud. You will be using CoreOS with Weave, which implements simple and secure networking, in a transparent, yet robust way. The purpose of this guide is to provide an out-of-the-box implementation that can ultimately be taken into production with little change. It will demonstrate how to provision a dedicated Kubernetes master and etcd nodes, and show how to scale the cluster with ease. - -### Prerequisites - -1. You need an Azure account. - -## Let's go! - -To get started, you need to checkout the code: - -```sh -git clone https://k8s.io/kubernetes -cd kubernetes/docs/getting-started-guides/coreos/azure/ -``` - -You will need to have [Node.js installed](http://nodejs.org/download/) on you machine. If you have previously used Azure CLI, you should have it already. - -First, you need to install some of the dependencies with - -```sh -npm install -``` - -Now, all you need to do is: - -```sh -./azure-login.js -u -./create-kubernetes-cluster.js -``` - -This script will provision a cluster suitable for production use, where there is a ring of 3 dedicated etcd nodes: 1 kubernetes master and 2 kubernetes nodes. The `kube-00` VM will be the master, your work loads are only to be deployed on the nodes, `kube-01` and `kube-02`. Initially, all VMs are single-core, to ensure a user of the free tier can reproduce it without paying extra. I will show how to add more bigger VMs later. - -![VMs in Azure](initial_cluster.png) - -Once the creation of Azure VMs has finished, you should see the following: - -```console -... -azure_wrapper/info: Saved SSH config, you can use it like so: `ssh -F ./output/kube_1c1496016083b4_ssh_conf ` -azure_wrapper/info: The hosts in this deployment are: - [ 'etcd-00', 'etcd-01', 'etcd-02', 'kube-00', 'kube-01', 'kube-02' ] -azure_wrapper/info: Saved state into `./output/kube_1c1496016083b4_deployment.yml` -``` - -Let's login to the master node like so: - -```sh -ssh -F ./output/kube_1c1496016083b4_ssh_conf kube-00 -``` - -> Note: config file name will be different, make sure to use the one you see. - -Check there are 2 nodes in the cluster: - -```console -core@kube-00 ~ $ kubectl get nodes -NAME LABELS STATUS -kube-01 kubernetes.io/hostname=kube-01 Ready -kube-02 kubernetes.io/hostname=kube-02 Ready -``` - -## Deploying the workload - -Let's follow the Guestbook example now: - -```sh -kubectl create -f ~/guestbook-example -``` - -You need to wait for the pods to get deployed, run the following and wait for `STATUS` to change from `Pending` to `Running`. - -```sh -kubectl get pods --watch -``` - -> Note: the most time it will spend downloading Docker container images on each of the nodes. - -Eventually you should see: - -```console -NAME READY STATUS RESTARTS AGE -frontend-0a9xi 1/1 Running 0 4m -frontend-4wahe 1/1 Running 0 4m -frontend-6l36j 1/1 Running 0 4m -redis-master-talmr 1/1 Running 0 4m -redis-slave-12zfd 1/1 Running 0 4m -redis-slave-3nbce 1/1 Running 0 4m -``` - -## Scaling - -Two single-core nodes are certainly not enough for a production system of today. Let's scale the cluster by adding a couple of bigger nodes. - -You will need to open another terminal window on your machine and go to the same working directory (e.g. `~/Workspace/kubernetes/docs/getting-started-guides/coreos/azure/`). - -First, lets set the size of new VMs: - -```sh -export AZ_VM_SIZE=Large -``` - -Now, run scale script with state file of the previous deployment and number of nodes to add: - -```console -core@kube-00 ~ $ ./scale-kubernetes-cluster.js ./output/kube_1c1496016083b4_deployment.yml 2 -... -azure_wrapper/info: Saved SSH config, you can use it like so: `ssh -F ./output/kube_8f984af944f572_ssh_conf ` -azure_wrapper/info: The hosts in this deployment are: - [ 'etcd-00', - 'etcd-01', - 'etcd-02', - 'kube-00', - 'kube-01', - 'kube-02', - 'kube-03', - 'kube-04' ] -azure_wrapper/info: Saved state into `./output/kube_8f984af944f572_deployment.yml` -``` - -> Note: this step has created new files in `./output`. - -Back on `kube-00`: - -```console -core@kube-00 ~ $ kubectl get nodes -NAME LABELS STATUS -kube-01 kubernetes.io/hostname=kube-01 Ready -kube-02 kubernetes.io/hostname=kube-02 Ready -kube-03 kubernetes.io/hostname=kube-03 Ready -kube-04 kubernetes.io/hostname=kube-04 Ready -``` - -You can see that two more nodes joined happily. Let's scale the number of Guestbook instances now. - -First, double-check how many replication controllers there are: - -```console -core@kube-00 ~ $ kubectl get rc -ONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -frontend php-redis kubernetes/example-guestbook-php-redis:v2 name=frontend 3 -redis-master master redis name=redis-master 1 -redis-slave worker kubernetes/redis-slave:v2 name=redis-slave 2 -``` - -As there are 4 nodes, let's scale proportionally: - -```console -core@kube-00 ~ $ kubectl scale --replicas=4 rc redis-slave ->>>>>>> coreos/azure: Updates for 1.0 -scaled -core@kube-00 ~ $ kubectl scale --replicas=4 rc frontend -scaled -``` - -Check what you have now: - -```console -core@kube-00 ~ $ kubectl get rc -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -frontend php-redis kubernetes/example-guestbook-php-redis:v2 name=frontend 4 -redis-master master redis name=redis-master 1 -redis-slave worker kubernetes/redis-slave:v2 name=redis-slave 4 -``` - -You now will have more instances of front-end Guestbook apps and Redis slaves; and, if you look up all pods labeled `name=frontend`, you should see one running on each node. - -```console -core@kube-00 ~/guestbook-example $ kubectl get pods -l name=frontend -NAME READY STATUS RESTARTS AGE -frontend-0a9xi 1/1 Running 0 22m -frontend-4wahe 1/1 Running 0 22m -frontend-6l36j 1/1 Running 0 22m -frontend-z9oxo 1/1 Running 0 41s -``` - -## Exposing the app to the outside world - -There is no native Azure load-ballancer support in Kubernets 1.0, however here is how you can expose the Guestbook app to the Internet. - -``` -./expose_guestbook_app_port.sh ./output/kube_1c1496016083b4_ssh_conf -Guestbook app is on port 31605, will map it to port 80 on kube-00 -info: Executing command vm endpoint create -+ Getting virtual machines -+ Reading network configuration -+ Updating network configuration -info: vm endpoint create command OK -info: Executing command vm endpoint show -+ Getting virtual machines -data: Name : tcp-80-31605 -data: Local port : 31605 -data: Protcol : tcp -data: Virtual IP Address : 137.117.156.164 -data: Direct server return : Disabled -info: vm endpoint show command OK -``` - -You then should be able to access it from anywhere via the Azure virtual IP for `kube-00` displayed above, i.e. `http://137.117.156.164/` in my case. - -## Next steps - -You now have a full-blow cluster running in Azure, congrats! - -You should probably try deploy other [example apps](../../../../examples/) or write your own ;) - -## Tear down... - -If you don't wish care about the Azure bill, you can tear down the cluster. It's easy to redeploy it, as you can see. - -```sh -./destroy-cluster.js ./output/kube_8f984af944f572_deployment.yml -``` - -> Note: make sure to use the _latest state file_, as after scaling there is a new one. - -By the way, with the scripts shown, you can deploy multiple clusters, if you like :) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/coreos/azure/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/addons/skydns-rc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/addons/skydns-rc.yaml deleted file mode 100644 index 00a20f3b4ae6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/addons/skydns-rc.yaml +++ /dev/null @@ -1,92 +0,0 @@ -apiVersion: v1 -kind: ReplicationController -metadata: - name: kube-dns-v8 - namespace: kube-system - labels: - k8s-app: kube-dns - version: v8 - kubernetes.io/cluster-service: "true" -spec: - replicas: 3 - selector: - k8s-app: kube-dns - version: v8 - template: - metadata: - labels: - k8s-app: kube-dns - version: v8 - kubernetes.io/cluster-service: "true" - spec: - containers: - - name: etcd - image: gcr.io/google_containers/etcd:2.0.9 - resources: - limits: - cpu: 100m - memory: 50Mi - command: - - /usr/local/bin/etcd - - -data-dir - - /var/etcd/data - - -listen-client-urls - - http://127.0.0.1:2379,http://127.0.0.1:4001 - - -advertise-client-urls - - http://127.0.0.1:2379,http://127.0.0.1:4001 - - -initial-cluster-token - - skydns-etcd - volumeMounts: - - name: etcd-storage - mountPath: /var/etcd/data - - name: kube2sky - image: gcr.io/google_containers/kube2sky:1.11 - resources: - limits: - cpu: 100m - memory: 50Mi - args: - # command = "/kube2sky" - - -domain=kube.local - - -kube_master_url=http://kube-00:8080 - - name: skydns - image: gcr.io/google_containers/skydns:2015-03-11-001 - resources: - limits: - cpu: 100m - memory: 50Mi - args: - # command = "/skydns" - - -machines=http://localhost:4001 - - -addr=0.0.0.0:53 - - -domain=kube.local - ports: - - containerPort: 53 - name: dns - protocol: UDP - - containerPort: 53 - name: dns-tcp - protocol: TCP - livenessProbe: - httpGet: - path: /healthz - port: 8080 - scheme: HTTP - initialDelaySeconds: 30 - timeoutSeconds: 5 - - name: healthz - image: gcr.io/google_containers/exechealthz:1.0 - resources: - limits: - cpu: 10m - memory: 20Mi - args: - - -cmd=nslookup kubernetes.default.svc.kube.local localhost >/dev/null - - -port=8080 - ports: - - containerPort: 8080 - protocol: TCP - volumes: - - name: etcd-storage - emptyDir: {} - dnsPolicy: Default # Don't use cluster DNS. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/addons/skydns-svc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/addons/skydns-svc.yaml deleted file mode 100644 index a0e979c26640..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/addons/skydns-svc.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: kube-dns - namespace: kube-system - labels: - k8s-app: kube-dns - kubernetes.io/cluster-service: "true" - kubernetes.io/name: "KubeDNS" -spec: - selector: - k8s-app: kube-dns - clusterIP: 10.1.0.3 - ports: - - name: dns - port: 53 - protocol: UDP - - name: dns-tcp - port: 53 - protocol: TCP diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/azure-login.js b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/azure-login.js deleted file mode 100755 index 624916b2b56a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/azure-login.js +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node - -require('child_process').fork('node_modules/azure-cli/bin/azure', ['login'].concat(process.argv)); diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/cloud_config_templates/kubernetes-cluster-etcd-node-template.yml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/cloud_config_templates/kubernetes-cluster-etcd-node-template.yml deleted file mode 100644 index cf75025ee1aa..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/cloud_config_templates/kubernetes-cluster-etcd-node-template.yml +++ /dev/null @@ -1,19 +0,0 @@ -## This file is used as input to deployment script, which ammends it as needed. -## More specifically, we need to add peer hosts for each but the elected peer. - -coreos: - units: - - name: etcd2.service - enable: true - command: start - etcd2: - name: '%H' - initial-cluster-token: 'etcd-cluster' - initial-advertise-peer-urls: 'http://%H:2380' - listen-peer-urls: 'http://%H:2380' - listen-client-urls: 'http://0.0.0.0:2379,http://0.0.0.0:4001' - advertise-client-urls: 'http://%H:2379,http://%H:4001' - initial-cluster-state: 'new' - update: - group: stable - reboot-strategy: off diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/cloud_config_templates/kubernetes-cluster-main-nodes-template.yml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/cloud_config_templates/kubernetes-cluster-main-nodes-template.yml deleted file mode 100644 index 6955467d4b86..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/cloud_config_templates/kubernetes-cluster-main-nodes-template.yml +++ /dev/null @@ -1,339 +0,0 @@ -## This file is used as input to deployment script, which ammends it as needed. -## More specifically, we need to add environment files for as many nodes as we -## are going to deploy. - -write_files: - - path: /opt/bin/curl-retry.sh - permissions: '0755' - owner: root - content: | - #!/bin/sh -x - until curl $@ - do sleep 1 - done - -coreos: - update: - group: stable - reboot-strategy: off - units: - - name: systemd-networkd-wait-online.service - drop-ins: - - name: 50-check-github-is-reachable.conf - content: | - [Service] - ExecStart=/bin/sh -x -c \ - 'until curl --silent --fail https://status.github.com/api/status.json | grep -q \"good\"; do sleep 2; done' - - - name: docker.service - drop-ins: - - name: 50-weave-kubernetes.conf - content: | - [Service] - Environment=DOCKER_OPTS='--bridge="weave" -r="false"' - - - name: weave-network.target - enable: true - content: | - [Unit] - Description=Weave Network Setup Complete - Documentation=man:systemd.special(7) - RefuseManualStart=no - After=network-online.target - [Install] - WantedBy=multi-user.target - WantedBy=kubernetes-master.target - WantedBy=kubernetes-node.target - - - name: kubernetes-master.target - enable: true - command: start - content: | - [Unit] - Description=Kubernetes Cluster Master - Documentation=http://kubernetes.io/ - RefuseManualStart=no - After=weave-network.target - Requires=weave-network.target - ConditionHost=kube-00 - Wants=kube-apiserver.service - Wants=kube-scheduler.service - Wants=kube-controller-manager.service - Wants=kube-proxy.service - [Install] - WantedBy=multi-user.target - - - name: kubernetes-node.target - enable: true - command: start - content: | - [Unit] - Description=Kubernetes Cluster Node - Documentation=http://kubernetes.io/ - RefuseManualStart=no - After=weave-network.target - Requires=weave-network.target - ConditionHost=!kube-00 - Wants=kube-proxy.service - Wants=kubelet.service - [Install] - WantedBy=multi-user.target - - - name: 10-weave.network - runtime: false - content: | - [Match] - Type=bridge - Name=weave* - [Network] - - - name: install-weave.service - enable: true - content: | - [Unit] - After=network-online.target - Before=weave.service - Before=weave-helper.service - Before=docker.service - Description=Install Weave - Documentation=http://docs.weave.works/ - Requires=network-online.target - [Service] - Type=oneshot - RemainAfterExit=yes - ExecStartPre=/bin/mkdir -p /opt/bin/ - ExecStartPre=/opt/bin/curl-retry.sh \ - --silent \ - --location \ - https://github.com/weaveworks/weave/releases/download/latest_release/weave \ - --output /opt/bin/weave - ExecStartPre=/opt/bin/curl-retry.sh \ - --silent \ - --location \ - https://raw.github.com/errordeveloper/weave-demos/master/poseidon/weave-helper \ - --output /opt/bin/weave-helper - ExecStartPre=/usr/bin/chmod +x /opt/bin/weave - ExecStartPre=/usr/bin/chmod +x /opt/bin/weave-helper - ExecStart=/bin/echo Weave Installed - [Install] - WantedBy=weave-network.target - WantedBy=weave.service - - - name: weave-helper.service - enable: true - content: | - [Unit] - After=install-weave.service - After=docker.service - Description=Weave Network Router - Documentation=http://docs.weave.works/ - Requires=docker.service - Requires=install-weave.service - [Service] - ExecStart=/opt/bin/weave-helper - Restart=always - [Install] - WantedBy=weave-network.target - - - name: weave.service - enable: true - content: | - [Unit] - After=install-weave.service - After=docker.service - Description=Weave Network Router - Documentation=http://docs.weave.works/ - Requires=docker.service - Requires=install-weave.service - [Service] - TimeoutStartSec=0 - EnvironmentFile=/etc/weave.%H.env - ExecStartPre=/opt/bin/weave setup - ExecStartPre=/opt/bin/weave launch $WEAVE_PEERS - ExecStart=/usr/bin/docker attach weave - Restart=on-failure - Restart=always - ExecStop=/opt/bin/weave stop - [Install] - WantedBy=weave-network.target - - - name: weave-create-bridge.service - enable: true - content: | - [Unit] - After=network.target - After=install-weave.service - Before=weave.service - Before=docker.service - Requires=network.target - Requires=install-weave.service - [Service] - Type=oneshot - EnvironmentFile=/etc/weave.%H.env - ExecStart=/opt/bin/weave --local create-bridge - ExecStart=/usr/bin/ip addr add dev weave $BRIDGE_ADDRESS_CIDR - ExecStart=/usr/bin/ip route add $BREAKOUT_ROUTE dev weave scope link - ExecStart=/usr/bin/ip route add 224.0.0.0/4 dev weave - [Install] - WantedBy=multi-user.target - WantedBy=weave-network.target - - - name: install-kubernetes.service - enable: true - content: | - [Unit] - After=network-online.target - Before=kube-apiserver.service - Before=kube-controller-manager.service - Before=kubelet.service - Before=kube-proxy.service - Description=Download Kubernetes Binaries - Documentation=http://kubernetes.io/ - Requires=network-online.target - [Service] - Environment=KUBE_RELEASE_TARBALL=https://k8s.io/kubernetes/releases/download/v1.0.1/kubernetes.tar.gz - ExecStartPre=/bin/mkdir -p /opt/ - ExecStart=/opt/bin/curl-retry.sh --silent --location $KUBE_RELEASE_TARBALL --output /tmp/kubernetes.tgz - ExecStart=/bin/tar xzvf /tmp/kubernetes.tgz -C /tmp/ - ExecStart=/bin/tar xzvf /tmp/kubernetes/server/kubernetes-server-linux-amd64.tar.gz -C /opt - ExecStartPost=/bin/chmod o+rx -R /opt/kubernetes - ExecStartPost=/bin/ln -s /opt/kubernetes/server/bin/kubectl /opt/bin/ - ExecStartPost=/bin/mv /tmp/kubernetes/examples/guestbook /home/core/guestbook-example - ExecStartPost=/bin/chown core. -R /home/core/guestbook-example - ExecStartPost=/bin/rm -rf /tmp/kubernetes - ExecStartPost=/bin/sed 's/# type: LoadBalancer/type: NodePort/' -i /home/core/guestbook-example/frontend-service.yaml - RemainAfterExit=yes - Type=oneshot - [Install] - WantedBy=kubernetes-master.target - WantedBy=kubernetes-node.target - - - name: kube-apiserver.service - enable: true - content: | - [Unit] - After=install-kubernetes.service - Before=kube-controller-manager.service - Before=kube-scheduler.service - ConditionFileIsExecutable=/opt/kubernetes/server/bin/kube-apiserver - Description=Kubernetes API Server - Documentation=http://kubernetes.io/ - Wants=install-kubernetes.service - ConditionHost=kube-00 - [Service] - ExecStart=/opt/kubernetes/server/bin/kube-apiserver \ - --address=0.0.0.0 \ - --port=8080 \ - $ETCD_SERVERS \ - --service-cluster-ip-range=10.1.0.0/16 \ - --logtostderr=true --v=3 - Restart=always - RestartSec=10 - [Install] - WantedBy=kubernetes-master.target - - - name: kube-scheduler.service - enable: true - content: | - [Unit] - After=kube-apiserver.service - After=install-kubernetes.service - ConditionFileIsExecutable=/opt/kubernetes/server/bin/kube-scheduler - Description=Kubernetes Scheduler - Documentation=http://kubernetes.io/ - Wants=kube-apiserver.service - ConditionHost=kube-00 - [Service] - ExecStart=/opt/kubernetes/server/bin/kube-scheduler \ - --logtostderr=true \ - --master=127.0.0.1:8080 - Restart=always - RestartSec=10 - [Install] - WantedBy=kubernetes-master.target - - - name: kube-controller-manager.service - enable: true - content: | - [Unit] - After=install-kubernetes.service - After=kube-apiserver.service - ConditionFileIsExecutable=/opt/kubernetes/server/bin/kube-controller-manager - Description=Kubernetes Controller Manager - Documentation=http://kubernetes.io/ - Wants=kube-apiserver.service - Wants=install-kubernetes.service - ConditionHost=kube-00 - [Service] - ExecStart=/opt/kubernetes/server/bin/kube-controller-manager \ - --master=127.0.0.1:8080 \ - --logtostderr=true - Restart=always - RestartSec=10 - [Install] - WantedBy=kubernetes-master.target - - - name: kubelet.service - enable: true - content: | - [Unit] - After=install-kubernetes.service - ConditionFileIsExecutable=/opt/kubernetes/server/bin/kubelet - Description=Kubernetes Kubelet - Documentation=http://kubernetes.io/ - Wants=install-kubernetes.service - ConditionHost=!kube-00 - [Service] - ExecStartPre=/bin/mkdir -p /etc/kubernetes/manifests/ - ExecStart=/opt/kubernetes/server/bin/kubelet \ - --address=0.0.0.0 \ - --port=10250 \ - --hostname_override=%H \ - --api_servers=http://kube-00:8080 \ - --logtostderr=true \ - --cluster_dns=10.1.0.3 \ - --cluster_domain=kube.local \ - --config=/etc/kubernetes/manifests/ - Restart=always - RestartSec=10 - [Install] - WantedBy=kubernetes-node.target - - - name: kube-proxy.service - enable: true - content: | - [Unit] - After=install-kubernetes.service - ConditionFileIsExecutable=/opt/kubernetes/server/bin/kube-proxy - Description=Kubernetes Proxy - Documentation=http://kubernetes.io/ - Wants=install-kubernetes.service - [Service] - ExecStart=/opt/kubernetes/server/bin/kube-proxy \ - --master=http://kube-00:8080 \ - --logtostderr=true - Restart=always - RestartSec=10 - [Install] - WantedBy=kubernetes-master.target - WantedBy=kubernetes-node.target - - - name: kube-create-addons.service - enable: true - content: | - [Unit] - After=install-kubernetes.service - ConditionFileIsExecutable=/opt/kubernetes/server/bin/kubectl - ConditionPathIsDirectory=/etc/kubernetes/addons/ - ConditionHost=kube-00 - Description=Kubernetes Addons - Documentation=http://kubernetes.io/ - Wants=install-kubernetes.service - Wants=kube-apiserver.service - [Service] - Type=oneshot - RemainAfterExit=no - ExecStart=/opt/kubernetes/server/bin/kubectl create -f /etc/kubernetes/addons/ - SuccessExitStatus=1 - [Install] - WantedBy=kubernetes-master.target diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/create-kubernetes-cluster.js b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/create-kubernetes-cluster.js deleted file mode 100755 index 70248c596c67..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/create-kubernetes-cluster.js +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env node - -var azure = require('./lib/azure_wrapper.js'); -var kube = require('./lib/deployment_logic/kubernetes.js'); - -azure.create_config('kube', { 'etcd': 3, 'kube': 3 }); - -azure.run_task_queue([ - azure.queue_default_network(), - azure.queue_storage_if_needed(), - azure.queue_machines('etcd', 'stable', - kube.create_etcd_cloud_config), - azure.queue_machines('kube', 'stable', - kube.create_node_cloud_config), -]); diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/destroy-cluster.js b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/destroy-cluster.js deleted file mode 100755 index ce441e538a5d..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/destroy-cluster.js +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node - -var azure = require('./lib/azure_wrapper.js'); - -azure.destroy_cluster(process.argv[2]); - -console.log('The cluster had been destroyed, you can delete the state file now.'); diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/expose_guestbook_app_port.sh b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/expose_guestbook_app_port.sh deleted file mode 100755 index 65dfaf5d3a96..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/expose_guestbook_app_port.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -# Copyright 2014 The Kubernetes Authors All rights reserved. -# -# 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. - -set -e - -[ ! -z $1 ] || (echo Usage: $0 ssh_conf; exit 1) - -fe_port=$(ssh -F $1 kube-00 \ - "/opt/bin/kubectl get -o template --template='{{(index .spec.ports 0).nodePort}}' services frontend -L name=frontend" \ -) - -echo "Guestbook app is on port $fe_port, will map it to port 80 on kube-00" - -./node_modules/.bin/azure vm endpoint create kube-00 80 $fe_port - -./node_modules/.bin/azure vm endpoint show kube-00 tcp-80-${fe_port} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/external_access.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/external_access.png deleted file mode 100644 index 6541309b0ac87c4081315c071295400d52614447..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 292367 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∾^*s<$@7TQ-t(eaByz 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

    x|V8l99BH`CfU>K7!K2Uj?g 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�MLVZV2H*=DRvZApUtis2`GD0C3TMn75V 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

    cgf{Bj!`^beXjlZFMY4cD+g+8W7FnF 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 Ok`R#\n\tPort <%= port %>\n")(host); - })).join('\n')); - console.log(clr.yellow('azure_wrapper/info:'), clr.green('Saved SSH config, you can use it like so: `ssh -F ', file_name, '`')); - console.log(clr.yellow('azure_wrapper/info:'), clr.green('The hosts in this deployment are:\n'), _.map(hosts.collection, function (host) { return host.name; })); -}; - -var get_location = function () { - if (process.env['AZ_AFFINITY']) { - return '--affinity-group=' + process.env['AZ_AFFINITY']; - } else if (process.env['AZ_LOCATION']) { - return '--location=' + process.env['AZ_LOCATION']; - } else { - return '--location=West Europe'; - } -} -var get_vm_size = function () { - if (process.env['AZ_VM_SIZE']) { - return '--vm-size=' + process.env['AZ_VM_SIZE']; - } else { - return '--vm-size=Small'; - } -} - -exports.queue_default_network = function () { - task_queue.push([ - 'network', 'vnet', 'create', - get_location(), - '--address-space=172.16.0.0', - conf.resources['vnet'], - ]); -} - -exports.queue_storage_if_needed = function() { - if (!process.env['AZURE_STORAGE_ACCOUNT']) { - conf.resources['storage_account'] = util.rand_suffix; - task_queue.push([ - 'storage', 'account', 'create', - '--type=LRS', - get_location(), - conf.resources['storage_account'], - ]); - process.env['AZURE_STORAGE_ACCOUNT'] = conf.resources['storage_account']; - } else { - // Preserve it for resizing, so we don't create a new one by accedent, - // when the environment variable is unset - conf.resources['storage_account'] = process.env['AZURE_STORAGE_ACCOUNT']; - } -}; - -exports.queue_machines = function (name_prefix, coreos_update_channel, cloud_config_creator) { - var x = conf.nodes[name_prefix]; - var vm_create_base_args = [ - 'vm', 'create', - get_location(), - get_vm_size(), - '--connect=' + conf.resources['service'], - '--virtual-network-name=' + conf.resources['vnet'], - '--no-ssh-password', - '--ssh-cert=' + conf.resources['ssh_key']['pem'], - ]; - - var cloud_config = cloud_config_creator(x, conf); - - var next_host = function (n) { - hosts.ssh_port_counter += 1; - var host = { name: util.hostname(n, name_prefix), port: hosts.ssh_port_counter }; - if (cloud_config instanceof Array) { - host.cloud_config_file = cloud_config[n]; - } else { - host.cloud_config_file = cloud_config; - } - hosts.collection.push(host); - return _.map([ - "--vm-name=<%= name %>", - "--ssh=<%= port %>", - "--custom-data=<%= cloud_config_file %>", - ], function (arg) { return _.template(arg)(host); }); - }; - - task_queue = task_queue.concat(_(x).times(function (n) { - if (conf.resizing && n < conf.old_size) { - return []; - } else { - return vm_create_base_args.concat(next_host(n), [ - coreos_image_ids[coreos_update_channel], 'core', - ]); - } - })); -}; - -exports.create_config = function (name, nodes) { - conf = { - name: name, - nodes: nodes, - weave_salt: util.rand_string(), - resources: { - vnet: [name, 'internal-vnet', util.rand_suffix].join('-'), - service: [name, util.rand_suffix].join('-'), - ssh_key: create_ssh_key(name), - } - }; - -}; - -exports.destroy_cluster = function (state_file) { - load_state(state_file); - if (conf.hosts === undefined) { - console.log(clr.red('azure_wrapper/fail: Nothing to delete.')); - process.abort(); - } - - conf.destroying = true; - task_queue = _.map(conf.hosts, function (host) { - return ['vm', 'delete', '--quiet', '--blob-delete', host.name]; - }); - - task_queue.push(['network', 'vnet', 'delete', '--quiet', conf.resources['vnet']]); - task_queue.push(['storage', 'account', 'delete', '--quiet', conf.resources['storage_account']]); - - exports.run_task_queue(); -}; - -exports.load_state_for_resizing = function (state_file, node_type, new_nodes) { - load_state(state_file); - if (conf.hosts === undefined) { - console.log(clr.red('azure_wrapper/fail: Nothing to look at.')); - process.abort(); - } - conf.resizing = true; - conf.old_size = conf.nodes[node_type]; - conf.old_state_file = state_file; - conf.nodes[node_type] += new_nodes; - hosts.collection = conf.hosts; - hosts.ssh_port_counter += conf.hosts.length; - process.env['AZURE_STORAGE_ACCOUNT'] = conf.resources['storage_account']; -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/cloud_config.js b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/cloud_config.js deleted file mode 100644 index d08b3f06aecf..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/cloud_config.js +++ /dev/null @@ -1,58 +0,0 @@ -var _ = require('underscore'); -var fs = require('fs'); -var yaml = require('js-yaml'); -var colors = require('colors/safe'); - -var write_cloud_config_from_object = function (data, output_file) { - try { - fs.writeFileSync(output_file, [ - '#cloud-config', - yaml.safeDump(data), - ].join("\n")); - return output_file; - } catch (e) { - console.log(colors.red(e)); - } -}; - -exports.generate_environment_file_entry_from_object = function (hostname, environ) { - var data = { - hostname: hostname, - environ_array: _.map(environ, function (value, key) { - return [key.toUpperCase(), JSON.stringify(value.toString())].join('='); - }), - }; - - return { - permissions: '0600', - owner: 'root', - content: _.template("<%= environ_array.join('\\n') %>\n")(data), - path: _.template("/etc/weave.<%= hostname %>.env")(data), - }; -}; - -exports.process_template = function (input_file, output_file, processor) { - var data = {}; - try { - data = yaml.safeLoad(fs.readFileSync(input_file, 'utf8')); - } catch (e) { - console.log(colors.red(e)); - } - return write_cloud_config_from_object(processor(_.clone(data)), output_file); -}; - -exports.write_files_from = function (local_dir, remote_dir) { - try { - return _.map(fs.readdirSync(local_dir), function (fn) { - return { - path: [remote_dir, fn].join('/'), - owner: 'root', - permissions: '0640', - encoding: 'base64', - content: fs.readFileSync([local_dir, fn].join('/')).toString('base64'), - }; - }); - } catch (e) { - console.log(colors.red(e)); - } -}; diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/deployment_logic/kubernetes.js b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/deployment_logic/kubernetes.js deleted file mode 100644 index dfeca7eb6285..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/deployment_logic/kubernetes.js +++ /dev/null @@ -1,77 +0,0 @@ -var _ = require('underscore'); -_.mixin(require('underscore.string').exports()); - -var util = require('../util.js'); -var cloud_config = require('../cloud_config.js'); - - -etcd_initial_cluster_conf_self = function (conf) { - var port = '2380'; - - var data = { - nodes: _(conf.nodes.etcd).times(function (n) { - var host = util.hostname(n, 'etcd'); - return [host, [host, port].join(':')].join('=http://'); - }), - }; - - return { - 'name': 'etcd2.service', - 'drop-ins': [{ - 'name': '50-etcd-initial-cluster.conf', - 'content': _.template("[Service]\nEnvironment=ETCD_INITIAL_CLUSTER=<%= nodes.join(',') %>\n")(data), - }], - }; -}; - -etcd_initial_cluster_conf_kube = function (conf) { - var port = '4001'; - - var data = { - nodes: _(conf.nodes.etcd).times(function (n) { - var host = util.hostname(n, 'etcd'); - return 'http://' + [host, port].join(':'); - }), - }; - - return { - 'name': 'kube-apiserver.service', - 'drop-ins': [{ - 'name': '50-etcd-initial-cluster.conf', - 'content': _.template("[Service]\nEnvironment=ETCD_SERVERS=--etcd_servers=<%= nodes.join(',') %>\n")(data), - }], - }; -}; - -exports.create_etcd_cloud_config = function (node_count, conf) { - var input_file = './cloud_config_templates/kubernetes-cluster-etcd-node-template.yml'; - var output_file = util.join_output_file_path('kubernetes-cluster-etcd-nodes', 'generated.yml'); - - return cloud_config.process_template(input_file, output_file, function(data) { - data.coreos.units.push(etcd_initial_cluster_conf_self(conf)); - return data; - }); -}; - -exports.create_node_cloud_config = function (node_count, conf) { - var elected_node = 0; - - var input_file = './cloud_config_templates/kubernetes-cluster-main-nodes-template.yml'; - var output_file = util.join_output_file_path('kubernetes-cluster-main-nodes', 'generated.yml'); - - var make_node_config = function (n) { - return cloud_config.generate_environment_file_entry_from_object(util.hostname(n, 'kube'), { - weave_password: conf.weave_salt, - weave_peers: n === elected_node ? "" : util.hostname(elected_node, 'kube'), - breakout_route: util.ipv4([10, 2, 0, 0], 16), - bridge_address_cidr: util.ipv4([10, 2, n, 1], 24), - }); - }; - - var write_files_extra = cloud_config.write_files_from('addons', '/etc/kubernetes/addons'); - return cloud_config.process_template(input_file, output_file, function(data) { - data.write_files = data.write_files.concat(_(node_count).times(make_node_config), write_files_extra); - data.coreos.units.push(etcd_initial_cluster_conf_kube(conf)); - return data; - }); -}; diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/util.js b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/util.js deleted file mode 100644 index 2c88b8cff351..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/lib/util.js +++ /dev/null @@ -1,33 +0,0 @@ -var _ = require('underscore'); -_.mixin(require('underscore.string').exports()); - -exports.ipv4 = function (ocets, prefix) { - return { - ocets: ocets, - prefix: prefix, - toString: function () { - return [ocets.join('.'), prefix].join('/'); - } - } -}; - -exports.hostname = function hostname (n, prefix) { - return _.template("<%= pre %>-<%= seq %>")({ - pre: prefix || 'core', - seq: _.pad(n, 2, '0'), - }); -}; - -exports.rand_string = function () { - var crypto = require('crypto'); - var shasum = crypto.createHash('sha256'); - shasum.update(crypto.randomBytes(256)); - return shasum.digest('hex'); -}; - - -exports.rand_suffix = exports.rand_string().substring(50); - -exports.join_output_file_path = function(prefix, suffix) { - return './output/' + [prefix, exports.rand_suffix, suffix].join('_'); -}; diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/package.json b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/package.json deleted file mode 100644 index 3269b418e0cd..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "coreos-azure-weave", - "version": "1.0.0", - "description": "Small utility to bring up a woven CoreOS cluster", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Ilya Dmitrichenko ", - "license": "Apache 2.0", - "dependencies": { - "azure-cli": "^0.9.5", - "colors": "^1.0.3", - "js-yaml": "^3.2.5", - "openssl-wrapper": "^0.2.1", - "underscore": "^1.7.0", - "underscore.string": "^3.0.2" - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/scale-kubernetes-cluster.js b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/scale-kubernetes-cluster.js deleted file mode 100755 index f606898874c0..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/azure/scale-kubernetes-cluster.js +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env node - -var azure = require('./lib/azure_wrapper.js'); -var kube = require('./lib/deployment_logic/kubernetes.js'); - -azure.load_state_for_resizing(process.argv[2], 'kube', parseInt(process.argv[3] || 1)); - -azure.run_task_queue([ - azure.queue_machines('kube', 'stable', kube.create_node_cloud_config), -]); diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/bare_metal_offline.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/bare_metal_offline.md deleted file mode 100644 index fce30d482359..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/bare_metal_offline.md +++ /dev/null @@ -1,707 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/coreos/bare_metal_offline.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Bare Metal CoreOS with Kubernetes (OFFLINE) ------------------------------------------- -Deploy a CoreOS running Kubernetes environment. This particular guild is made to help those in an OFFLINE system, wither for testing a POC before the real deal, or you are restricted to be totally offline for your applications. - -**Table of Contents** - -- [Prerequisites](#prerequisites) -- [High Level Design](#high-level-design) -- [This Guides variables](#this-guides-variables) -- [Setup PXELINUX CentOS](#setup-pxelinux-centos) -- [Adding CoreOS to PXE](#adding-coreos-to-pxe) -- [DHCP configuration](#dhcp-configuration) -- [Kubernetes](#kubernetes) -- [Cloud Configs](#cloud-configs) - - [master.yml](#masteryml) - - [node.yml](#nodeyml) -- [New pxelinux.cfg file](#new-pxelinuxcfg-file) -- [Specify the pxelinux targets](#specify-the-pxelinux-targets) -- [Creating test pod](#creating-test-pod) -- [Helping commands for debugging](#helping-commands-for-debugging) - - -## Prerequisites - -1. Installed *CentOS 6* for PXE server -2. At least two bare metal nodes to work with - -## High Level Design - -1. Manage the tftp directory - * /tftpboot/(coreos)(centos)(RHEL) - * /tftpboot/pxelinux.0/(MAC) -> linked to Linux image config file -2. Update per install the link for pxelinux -3. Update the DHCP config to reflect the host needing deployment -4. Setup nodes to deploy CoreOS creating a etcd cluster. -5. Have no access to the public [etcd discovery tool](https://discovery.etcd.io/). -6. Installing the CoreOS slaves to become Kubernetes nodes. - -## This Guides variables - -| Node Description | MAC | IP | -| :---------------------------- | :---------------: | :---------: | -| CoreOS/etcd/Kubernetes Master | d0:00:67:13:0d:00 | 10.20.30.40 | -| CoreOS Slave 1 | d0:00:67:13:0d:01 | 10.20.30.41 | -| CoreOS Slave 2 | d0:00:67:13:0d:02 | 10.20.30.42 | - - -## Setup PXELINUX CentOS - -To setup CentOS PXELINUX environment there is a complete [guide here](http://docs.fedoraproject.org/en-US/Fedora/7/html/Installation_Guide/ap-pxe-server.html). This section is the abbreviated version. - -1. Install packages needed on CentOS - - sudo yum install tftp-server dhcp syslinux - -2. `vi /etc/xinetd.d/tftp` to enable tftp service and change disable to 'no' - disable = no - -3. Copy over the syslinux images we will need. - - su - - mkdir -p /tftpboot - cd /tftpboot - cp /usr/share/syslinux/pxelinux.0 /tftpboot - cp /usr/share/syslinux/menu.c32 /tftpboot - cp /usr/share/syslinux/memdisk /tftpboot - cp /usr/share/syslinux/mboot.c32 /tftpboot - cp /usr/share/syslinux/chain.c32 /tftpboot - - /sbin/service dhcpd start - /sbin/service xinetd start - /sbin/chkconfig tftp on - -4. Setup default boot menu - - mkdir /tftpboot/pxelinux.cfg - touch /tftpboot/pxelinux.cfg/default - -5. Edit the menu `vi /tftpboot/pxelinux.cfg/default` - - default menu.c32 - prompt 0 - timeout 15 - ONTIMEOUT local - display boot.msg - - MENU TITLE Main Menu - - LABEL local - MENU LABEL Boot local hard drive - LOCALBOOT 0 - -Now you should have a working PXELINUX setup to image CoreOS nodes. You can verify the services by using VirtualBox locally or with bare metal servers. - -## Adding CoreOS to PXE - -This section describes how to setup the CoreOS images to live alongside a pre-existing PXELINUX environment. - -1. Find or create the TFTP root directory that everything will be based off of. - * For this document we will assume `/tftpboot/` is our root directory. -2. Once we know and have our tftp root directory we will create a new directory structure for our CoreOS images. -3. Download the CoreOS PXE files provided by the CoreOS team. - - MY_TFTPROOT_DIR=/tftpboot - mkdir -p $MY_TFTPROOT_DIR/images/coreos/ - cd $MY_TFTPROOT_DIR/images/coreos/ - wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe.vmlinuz - wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe.vmlinuz.sig - wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe_image.cpio.gz - wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe_image.cpio.gz.sig - gpg --verify coreos_production_pxe.vmlinuz.sig - gpg --verify coreos_production_pxe_image.cpio.gz.sig - -4. Edit the menu `vi /tftpboot/pxelinux.cfg/default` again - - default menu.c32 - prompt 0 - timeout 300 - ONTIMEOUT local - display boot.msg - - MENU TITLE Main Menu - - LABEL local - MENU LABEL Boot local hard drive - LOCALBOOT 0 - - MENU BEGIN CoreOS Menu - - LABEL coreos-master - MENU LABEL CoreOS Master - KERNEL images/coreos/coreos_production_pxe.vmlinuz - APPEND initrd=images/coreos/coreos_production_pxe_image.cpio.gz cloud-config-url=http:///pxe-cloud-config-single-master.yml - - LABEL coreos-slave - MENU LABEL CoreOS Slave - KERNEL images/coreos/coreos_production_pxe.vmlinuz - APPEND initrd=images/coreos/coreos_production_pxe_image.cpio.gz cloud-config-url=http:///pxe-cloud-config-slave.yml - MENU END - -This configuration file will now boot from local drive but have the option to PXE image CoreOS. - -## DHCP configuration - -This section covers configuring the DHCP server to hand out our new images. In this case we are assuming that there are other servers that will boot alongside other images. - -1. Add the `filename` to the _host_ or _subnet_ sections. - - filename "/tftpboot/pxelinux.0"; - -2. At this point we want to make pxelinux configuration files that will be the templates for the different CoreOS deployments. - - subnet 10.20.30.0 netmask 255.255.255.0 { - next-server 10.20.30.242; - option broadcast-address 10.20.30.255; - filename ""; - - ... - # http://www.syslinux.org/wiki/index.php/PXELINUX - host core_os_master { - hardware ethernet d0:00:67:13:0d:00; - option routers 10.20.30.1; - fixed-address 10.20.30.40; - option domain-name-servers 10.20.30.242; - filename "/pxelinux.0"; - } - host core_os_slave { - hardware ethernet d0:00:67:13:0d:01; - option routers 10.20.30.1; - fixed-address 10.20.30.41; - option domain-name-servers 10.20.30.242; - filename "/pxelinux.0"; - } - host core_os_slave2 { - hardware ethernet d0:00:67:13:0d:02; - option routers 10.20.30.1; - fixed-address 10.20.30.42; - option domain-name-servers 10.20.30.242; - filename "/pxelinux.0"; - } - ... - } - -We will be specifying the node configuration later in the guide. - -## Kubernetes - -To deploy our configuration we need to create an `etcd` master. To do so we want to pxe CoreOS with a specific cloud-config.yml. There are two options we have here. -1. Is to template the cloud config file and programmatically create new static configs for different cluster setups. -2. Have a service discovery protocol running in our stack to do auto discovery. - -This demo we just make a static single `etcd` server to host our Kubernetes and `etcd` master servers. - -Since we are OFFLINE here most of the helping processes in CoreOS and Kubernetes are then limited. To do our setup we will then have to download and serve up our binaries for Kubernetes in our local environment. - -An easy solution is to host a small web server on the DHCP/TFTP host for all our binaries to make them available to the local CoreOS PXE machines. - -To get this up and running we are going to setup a simple `apache` server to serve our binaries needed to bootstrap Kubernetes. - -This is on the PXE server from the previous section: - - rm /etc/httpd/conf.d/welcome.conf - cd /var/www/html/ - wget -O kube-register https://github.com/kelseyhightower/kube-register/releases/download/v0.0.2/kube-register-0.0.2-linux-amd64 - wget -O setup-network-environment https://github.com/kelseyhightower/setup-network-environment/releases/download/v1.0.0/setup-network-environment - wget https://storage.googleapis.com/kubernetes-release/release/v0.15.0/bin/linux/amd64/kubernetes --no-check-certificate - wget https://storage.googleapis.com/kubernetes-release/release/v0.15.0/bin/linux/amd64/kube-apiserver --no-check-certificate - wget https://storage.googleapis.com/kubernetes-release/release/v0.15.0/bin/linux/amd64/kube-controller-manager --no-check-certificate - wget https://storage.googleapis.com/kubernetes-release/release/v0.15.0/bin/linux/amd64/kube-scheduler --no-check-certificate - wget https://storage.googleapis.com/kubernetes-release/release/v0.15.0/bin/linux/amd64/kubectl --no-check-certificate - wget https://storage.googleapis.com/kubernetes-release/release/v0.15.0/bin/linux/amd64/kubecfg --no-check-certificate - wget https://storage.googleapis.com/kubernetes-release/release/v0.15.0/bin/linux/amd64/kubelet --no-check-certificate - wget https://storage.googleapis.com/kubernetes-release/release/v0.15.0/bin/linux/amd64/kube-proxy --no-check-certificate - wget -O flanneld https://storage.googleapis.com/k8s/flanneld --no-check-certificate - -This sets up our binaries we need to run Kubernetes. This would need to be enhanced to download from the Internet for updates in the future. - -Now for the good stuff! - -## Cloud Configs - -The following config files are tailored for the OFFLINE version of a Kubernetes deployment. - -These are based on the work found here: [master.yml](cloud-configs/master.yaml), [node.yml](cloud-configs/node.yaml) - -To make the setup work, you need to replace a few placeholders: - - - Replace `` with your PXE server ip address (e.g. 10.20.30.242) - - Replace `` with the Kubernetes master ip address (e.g. 10.20.30.40) - - If you run a private docker registry, replace `rdocker.example.com` with your docker registry dns name. - - If you use a proxy, replace `rproxy.example.com` with your proxy server (and port) - - Add your own SSH public key(s) to the cloud config at the end - -### master.yml - -On the PXE server make and fill in the variables `vi /var/www/html/coreos/pxe-cloud-config-master.yml`. - - - #cloud-config - --- - write_files: - - path: /opt/bin/waiter.sh - owner: root - content: | - #! /usr/bin/bash - until curl http://127.0.0.1:4001/v2/machines; do sleep 2; done - - path: /opt/bin/kubernetes-download.sh - owner: root - permissions: 0755 - content: | - #! /usr/bin/bash - /usr/bin/wget -N -P "/opt/bin" "http:///kubectl" - /usr/bin/wget -N -P "/opt/bin" "http:///kubernetes" - /usr/bin/wget -N -P "/opt/bin" "http:///kubecfg" - chmod +x /opt/bin/* - - path: /etc/profile.d/opt-path.sh - owner: root - permissions: 0755 - content: | - #! /usr/bin/bash - PATH=$PATH/opt/bin - coreos: - units: - - name: 10-eno1.network - runtime: true - content: | - [Match] - Name=eno1 - [Network] - DHCP=yes - - name: 20-nodhcp.network - runtime: true - content: | - [Match] - Name=en* - [Network] - DHCP=none - - name: get-kube-tools.service - runtime: true - command: start - content: | - [Service] - ExecStartPre=-/usr/bin/mkdir -p /opt/bin - ExecStart=/opt/bin/kubernetes-download.sh - RemainAfterExit=yes - Type=oneshot - - name: setup-network-environment.service - command: start - content: | - [Unit] - Description=Setup Network Environment - Documentation=https://github.com/kelseyhightower/setup-network-environment - Requires=network-online.target - After=network-online.target - [Service] - ExecStartPre=-/usr/bin/mkdir -p /opt/bin - ExecStartPre=/usr/bin/wget -N -P /opt/bin http:///setup-network-environment - ExecStartPre=/usr/bin/chmod +x /opt/bin/setup-network-environment - ExecStart=/opt/bin/setup-network-environment - RemainAfterExit=yes - Type=oneshot - - name: etcd.service - command: start - content: | - [Unit] - Description=etcd - Requires=setup-network-environment.service - After=setup-network-environment.service - [Service] - EnvironmentFile=/etc/network-environment - User=etcd - PermissionsStartOnly=true - ExecStart=/usr/bin/etcd \ - --name ${DEFAULT_IPV4} \ - --addr ${DEFAULT_IPV4}:4001 \ - --bind-addr 0.0.0.0 \ - --cluster-active-size 1 \ - --data-dir /var/lib/etcd \ - --http-read-timeout 86400 \ - --peer-addr ${DEFAULT_IPV4}:7001 \ - --snapshot true - Restart=always - RestartSec=10s - - name: fleet.socket - command: start - content: | - [Socket] - ListenStream=/var/run/fleet.sock - - name: fleet.service - command: start - content: | - [Unit] - Description=fleet daemon - Wants=etcd.service - After=etcd.service - Wants=fleet.socket - After=fleet.socket - [Service] - Environment="FLEET_ETCD_SERVERS=http://127.0.0.1:4001" - Environment="FLEET_METADATA=role=master" - ExecStart=/usr/bin/fleetd - Restart=always - RestartSec=10s - - name: etcd-waiter.service - command: start - content: | - [Unit] - Description=etcd waiter - Wants=network-online.target - Wants=etcd.service - After=etcd.service - After=network-online.target - Before=flannel.service - Before=setup-network-environment.service - [Service] - ExecStartPre=/usr/bin/chmod +x /opt/bin/waiter.sh - ExecStart=/usr/bin/bash /opt/bin/waiter.sh - RemainAfterExit=true - Type=oneshot - - name: flannel.service - command: start - content: | - [Unit] - Wants=etcd-waiter.service - After=etcd-waiter.service - Requires=etcd.service - After=etcd.service - After=network-online.target - Wants=network-online.target - Description=flannel is an etcd backed overlay network for containers - [Service] - Type=notify - ExecStartPre=-/usr/bin/mkdir -p /opt/bin - ExecStartPre=/usr/bin/wget -N -P /opt/bin http:///flanneld - ExecStartPre=/usr/bin/chmod +x /opt/bin/flanneld - ExecStartPre=-/usr/bin/etcdctl mk /coreos.com/network/config '{"Network":"10.100.0.0/16", "Backend": {"Type": "vxlan"}}' - ExecStart=/opt/bin/flanneld - - name: kube-apiserver.service - command: start - content: | - [Unit] - Description=Kubernetes API Server - Documentation=https://k8s.io/kubernetes - Requires=etcd.service - After=etcd.service - [Service] - ExecStartPre=-/usr/bin/mkdir -p /opt/bin - ExecStartPre=/usr/bin/wget -N -P /opt/bin http:///kube-apiserver - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-apiserver - ExecStart=/opt/bin/kube-apiserver \ - --address=0.0.0.0 \ - --port=8080 \ - --service-cluster-ip-range=10.100.0.0/16 \ - --etcd_servers=http://127.0.0.1:4001 \ - --logtostderr=true - Restart=always - RestartSec=10 - - name: kube-controller-manager.service - command: start - content: | - [Unit] - Description=Kubernetes Controller Manager - Documentation=https://k8s.io/kubernetes - Requires=kube-apiserver.service - After=kube-apiserver.service - [Service] - ExecStartPre=/usr/bin/wget -N -P /opt/bin http:///kube-controller-manager - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-controller-manager - ExecStart=/opt/bin/kube-controller-manager \ - --master=127.0.0.1:8080 \ - --logtostderr=true - Restart=always - RestartSec=10 - - name: kube-scheduler.service - command: start - content: | - [Unit] - Description=Kubernetes Scheduler - Documentation=https://k8s.io/kubernetes - Requires=kube-apiserver.service - After=kube-apiserver.service - [Service] - ExecStartPre=/usr/bin/wget -N -P /opt/bin http:///kube-scheduler - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-scheduler - ExecStart=/opt/bin/kube-scheduler --master=127.0.0.1:8080 - Restart=always - RestartSec=10 - - name: kube-register.service - command: start - content: | - [Unit] - Description=Kubernetes Registration Service - Documentation=https://github.com/kelseyhightower/kube-register - Requires=kube-apiserver.service - After=kube-apiserver.service - Requires=fleet.service - After=fleet.service - [Service] - ExecStartPre=/usr/bin/wget -N -P /opt/bin http:///kube-register - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-register - ExecStart=/opt/bin/kube-register \ - --metadata=role=node \ - --fleet-endpoint=unix:///var/run/fleet.sock \ - --healthz-port=10248 \ - --api-endpoint=http://127.0.0.1:8080 - Restart=always - RestartSec=10 - update: - group: stable - reboot-strategy: off - ssh_authorized_keys: - - ssh-rsa AAAAB3NzaC1yc2EAAAAD... - - -### node.yml - -On the PXE server make and fill in the variables `vi /var/www/html/coreos/pxe-cloud-config-slave.yml`. - - #cloud-config - --- - write_files: - - path: /etc/default/docker - content: | - DOCKER_EXTRA_OPTS='--insecure-registry="rdocker.example.com:5000"' - coreos: - units: - - name: 10-eno1.network - runtime: true - content: | - [Match] - Name=eno1 - [Network] - DHCP=yes - - name: 20-nodhcp.network - runtime: true - content: | - [Match] - Name=en* - [Network] - DHCP=none - - name: etcd.service - mask: true - - name: docker.service - drop-ins: - - name: 50-insecure-registry.conf - content: | - [Service] - Environment="HTTP_PROXY=http://rproxy.example.com:3128/" "NO_PROXY=localhost,127.0.0.0/8,rdocker.example.com" - - name: fleet.service - command: start - content: | - [Unit] - Description=fleet daemon - Wants=fleet.socket - After=fleet.socket - [Service] - Environment="FLEET_ETCD_SERVERS=http://:4001" - Environment="FLEET_METADATA=role=node" - ExecStart=/usr/bin/fleetd - Restart=always - RestartSec=10s - - name: flannel.service - command: start - content: | - [Unit] - After=network-online.target - Wants=network-online.target - Description=flannel is an etcd backed overlay network for containers - [Service] - Type=notify - ExecStartPre=-/usr/bin/mkdir -p /opt/bin - ExecStartPre=/usr/bin/wget -N -P /opt/bin http:///flanneld - ExecStartPre=/usr/bin/chmod +x /opt/bin/flanneld - ExecStart=/opt/bin/flanneld -etcd-endpoints http://:4001 - - name: docker.service - command: start - content: | - [Unit] - After=flannel.service - Wants=flannel.service - Description=Docker Application Container Engine - Documentation=http://docs.docker.io - [Service] - EnvironmentFile=-/etc/default/docker - EnvironmentFile=/run/flannel/subnet.env - ExecStartPre=/bin/mount --make-rprivate / - ExecStart=/usr/bin/docker -d --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} -s=overlay -H fd:// ${DOCKER_EXTRA_OPTS} - [Install] - WantedBy=multi-user.target - - name: setup-network-environment.service - command: start - content: | - [Unit] - Description=Setup Network Environment - Documentation=https://github.com/kelseyhightower/setup-network-environment - Requires=network-online.target - After=network-online.target - [Service] - ExecStartPre=-/usr/bin/mkdir -p /opt/bin - ExecStartPre=/usr/bin/wget -N -P /opt/bin http:///setup-network-environment - ExecStartPre=/usr/bin/chmod +x /opt/bin/setup-network-environment - ExecStart=/opt/bin/setup-network-environment - RemainAfterExit=yes - Type=oneshot - - name: kube-proxy.service - command: start - content: | - [Unit] - Description=Kubernetes Proxy - Documentation=https://k8s.io/kubernetes - Requires=setup-network-environment.service - After=setup-network-environment.service - [Service] - ExecStartPre=/usr/bin/wget -N -P /opt/bin http:///kube-proxy - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-proxy - ExecStart=/opt/bin/kube-proxy \ - --etcd_servers=http://:4001 \ - --logtostderr=true - Restart=always - RestartSec=10 - - name: kube-kubelet.service - command: start - content: | - [Unit] - Description=Kubernetes Kubelet - Documentation=https://k8s.io/kubernetes - Requires=setup-network-environment.service - After=setup-network-environment.service - [Service] - EnvironmentFile=/etc/network-environment - ExecStartPre=/usr/bin/wget -N -P /opt/bin http:///kubelet - ExecStartPre=/usr/bin/chmod +x /opt/bin/kubelet - ExecStart=/opt/bin/kubelet \ - --address=0.0.0.0 \ - --port=10250 \ - --hostname_override=${DEFAULT_IPV4} \ - --api_servers=:8080 \ - --healthz_bind_address=0.0.0.0 \ - --healthz_port=10248 \ - --logtostderr=true - Restart=always - RestartSec=10 - update: - group: stable - reboot-strategy: off - ssh_authorized_keys: - - ssh-rsa AAAAB3NzaC1yc2EAAAAD... - - -## New pxelinux.cfg file - -Create a pxelinux target file for a _slave_ node: `vi /tftpboot/pxelinux.cfg/coreos-node-slave` - - default coreos - prompt 1 - timeout 15 - - display boot.msg - - label coreos - menu default - kernel images/coreos/coreos_production_pxe.vmlinuz - append initrd=images/coreos/coreos_production_pxe_image.cpio.gz cloud-config-url=http:///coreos/pxe-cloud-config-slave.yml console=tty0 console=ttyS0 coreos.autologin=tty1 coreos.autologin=ttyS0 - -And one for the _master_ node: `vi /tftpboot/pxelinux.cfg/coreos-node-master` - - default coreos - prompt 1 - timeout 15 - - display boot.msg - - label coreos - menu default - kernel images/coreos/coreos_production_pxe.vmlinuz - append initrd=images/coreos/coreos_production_pxe_image.cpio.gz cloud-config-url=http:///coreos/pxe-cloud-config-master.yml console=tty0 console=ttyS0 coreos.autologin=tty1 coreos.autologin=ttyS0 - -## Specify the pxelinux targets - -Now that we have our new targets setup for master and slave we want to configure the specific hosts to those targets. We will do this by using the pxelinux mechanism of setting a specific MAC addresses to a specific pxelinux.cfg file. - -Refer to the MAC address table in the beginning of this guide. Documentation for more details can be found [here](http://www.syslinux.org/wiki/index.php/PXELINUX). - - cd /tftpboot/pxelinux.cfg - ln -s coreos-node-master 01-d0-00-67-13-0d-00 - ln -s coreos-node-slave 01-d0-00-67-13-0d-01 - ln -s coreos-node-slave 01-d0-00-67-13-0d-02 - - -Reboot these servers to get the images PXEd and ready for running containers! - -## Creating test pod - -Now that the CoreOS with Kubernetes installed is up and running lets spin up some Kubernetes pods to demonstrate the system. - -See [a simple nginx example](../../../docs/user-guide/simple-nginx.md) to try out your new cluster. - -For more complete applications, please look in the [examples directory](../../../examples/). - -## Helping commands for debugging - -List all keys in etcd: - - etcdctl ls --recursive - -List fleet machines - - fleetctl list-machines - -Check system status of services on master: - - systemctl status kube-apiserver - systemctl status kube-controller-manager - systemctl status kube-scheduler - systemctl status kube-register - -Check system status of services on a node: - - systemctl status kube-kubelet - systemctl status docker.service - -List Kubernetes - - kubectl get pods - kubectl get nodes - - -Kill all pods: - - for i in `kubectl get pods | awk '{print $1}'`; do kubectl stop pod $i; done - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/coreos/bare_metal_offline.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/cloud-configs/master.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/cloud-configs/master.yaml deleted file mode 100644 index 715904a1af52..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/cloud-configs/master.yaml +++ /dev/null @@ -1,140 +0,0 @@ -#cloud-config - ---- -write-files: - - path: /etc/conf.d/nfs - permissions: '0644' - content: | - OPTS_RPC_MOUNTD="" - - path: /opt/bin/wupiao - permissions: '0755' - content: | - #!/bin/bash - # [w]ait [u]ntil [p]ort [i]s [a]ctually [o]pen - [ -n "$1" ] && \ - until curl -o /dev/null -sIf http://${1}; do \ - sleep 1 && echo .; - done; - exit $? - -hostname: master -coreos: - etcd2: - name: master - listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001 - advertise-client-urls: http://$private_ipv4:2379,http://$private_ipv4:4001 - initial-cluster-token: k8s_etcd - listen-peer-urls: http://$private_ipv4:2380,http://$private_ipv4:7001 - initial-advertise-peer-urls: http://$private_ipv4:2380 - initial-cluster: master=http://$private_ipv4:2380 - initial-cluster-state: new - fleet: - metadata: "role=master" - units: - - name: generate-serviceaccount-key.service - command: start - content: | - [Unit] - Description=Generate service-account key file - - [Service] - ExecStartPre=-/usr/bin/mkdir -p /opt/bin - ExecStart=/bin/openssl genrsa -out /opt/bin/kube-serviceaccount.key 2048 2>/dev/null - RemainAfterExit=yes - Type=oneshot - - name: setup-network-environment.service - command: start - content: | - [Unit] - Description=Setup Network Environment - Documentation=https://github.com/kelseyhightower/setup-network-environment - Requires=network-online.target - After=network-online.target - - [Service] - ExecStartPre=-/usr/bin/mkdir -p /opt/bin - ExecStartPre=/usr/bin/curl -L -o /opt/bin/setup-network-environment -z /opt/bin/setup-network-environment https://github.com/kelseyhightower/setup-network-environment/releases/download/v1.0.0/setup-network-environment - ExecStartPre=/usr/bin/chmod +x /opt/bin/setup-network-environment - ExecStart=/opt/bin/setup-network-environment - RemainAfterExit=yes - Type=oneshot - - name: fleet.service - command: start - - name: flanneld.service - command: start - drop-ins: - - name: 50-network-config.conf - content: | - [Unit] - Requires=etcd2.service - [Service] - ExecStartPre=/usr/bin/etcdctl set /coreos.com/network/config '{"Network":"10.244.0.0/16", "Backend": {"Type": "vxlan"}}' - - name: docker.service - command: start - - name: kube-apiserver.service - command: start - content: | - [Unit] - Description=Kubernetes API Server - Documentation=https://k8s.io/kubernetes - Requires=setup-network-environment.service etcd2.service generate-serviceaccount-key.service - After=setup-network-environment.service etcd2.service generate-serviceaccount-key.service - - [Service] - EnvironmentFile=/etc/network-environment - ExecStartPre=-/usr/bin/mkdir -p /opt/bin - ExecStartPre=/usr/bin/curl -L -o /opt/bin/kube-apiserver -z /opt/bin/kube-apiserver https://storage.googleapis.com/kubernetes-release/release/v1.0.1/bin/linux/amd64/kube-apiserver - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-apiserver - ExecStartPre=/opt/bin/wupiao 127.0.0.1:2379/v2/machines - ExecStart=/opt/bin/kube-apiserver \ - --service_account_key_file=/opt/bin/kube-serviceaccount.key \ - --service_account_lookup=false \ - --admission_control=NamespaceLifecycle,NamespaceAutoProvision,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota \ - --runtime_config=api/v1 \ - --allow_privileged=true \ - --insecure_bind_address=0.0.0.0 \ - --insecure_port=8080 \ - --kubelet_https=true \ - --secure_port=6443 \ - --service-cluster-ip-range=10.100.0.0/16 \ - --etcd_servers=http://127.0.0.1:2379 \ - --public_address_override=${DEFAULT_IPV4} \ - --logtostderr=true - Restart=always - RestartSec=10 - - name: kube-controller-manager.service - command: start - content: | - [Unit] - Description=Kubernetes Controller Manager - Documentation=https://k8s.io/kubernetes - Requires=kube-apiserver.service - After=kube-apiserver.service - - [Service] - ExecStartPre=/usr/bin/curl -L -o /opt/bin/kube-controller-manager -z /opt/bin/kube-controller-manager https://storage.googleapis.com/kubernetes-release/release/v1.0.1/bin/linux/amd64/kube-controller-manager - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-controller-manager - ExecStart=/opt/bin/kube-controller-manager \ - --service_account_private_key_file=/opt/bin/kube-serviceaccount.key \ - --master=127.0.0.1:8080 \ - --logtostderr=true - Restart=always - RestartSec=10 - - name: kube-scheduler.service - command: start - content: | - [Unit] - Description=Kubernetes Scheduler - Documentation=https://k8s.io/kubernetes - Requires=kube-apiserver.service - After=kube-apiserver.service - - [Service] - ExecStartPre=/usr/bin/curl -L -o /opt/bin/kube-scheduler -z /opt/bin/kube-scheduler https://storage.googleapis.com/kubernetes-release/release/v1.0.1/bin/linux/amd64/kube-scheduler - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-scheduler - ExecStart=/opt/bin/kube-scheduler --master=127.0.0.1:8080 - Restart=always - RestartSec=10 - update: - group: alpha - reboot-strategy: off diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/cloud-configs/node.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/cloud-configs/node.yaml deleted file mode 100644 index 44674c29c281..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/cloud-configs/node.yaml +++ /dev/null @@ -1,98 +0,0 @@ -#cloud-config -write-files: - - path: /opt/bin/wupiao - permissions: '0755' - content: | - #!/bin/bash - # [w]ait [u]ntil [p]ort [i]s [a]ctually [o]pen - [ -n "$1" ] && [ -n "$2" ] && while ! curl --output /dev/null \ - --silent --head --fail \ - http://${1}:${2}; do sleep 1 && echo -n .; done; - exit $? -coreos: - etcd2: - listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001 - advertise-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001 - initial-cluster: master=http://:2380 - proxy: on - fleet: - metadata: "role=node" - units: - - name: fleet.service - command: start - - name: flanneld.service - command: start - drop-ins: - - name: 50-network-config.conf - content: | - [Unit] - Requires=etcd2.service - [Service] - ExecStartPre=/usr/bin/etcdctl set /coreos.com/network/config '{"Network":"10.244.0.0/16", "Backend": {"Type": "vxlan"}}' - - name: docker.service - command: start - - name: setup-network-environment.service - command: start - content: | - [Unit] - Description=Setup Network Environment - Documentation=https://github.com/kelseyhightower/setup-network-environment - Requires=network-online.target - After=network-online.target - - [Service] - ExecStartPre=-/usr/bin/mkdir -p /opt/bin - ExecStartPre=/usr/bin/curl -L -o /opt/bin/setup-network-environment -z /opt/bin/setup-network-environment https://github.com/kelseyhightower/setup-network-environment/releases/download/v1.0.0/setup-network-environment - ExecStartPre=/usr/bin/chmod +x /opt/bin/setup-network-environment - ExecStart=/opt/bin/setup-network-environment - RemainAfterExit=yes - Type=oneshot - - name: kube-proxy.service - command: start - content: | - [Unit] - Description=Kubernetes Proxy - Documentation=https://k8s.io/kubernetes - Requires=setup-network-environment.service - After=setup-network-environment.service - - [Service] - ExecStartPre=/usr/bin/curl -L -o /opt/bin/kube-proxy -z /opt/bin/kube-proxy https://storage.googleapis.com/kubernetes-release/release/v1.0.1/bin/linux/amd64/kube-proxy - ExecStartPre=/usr/bin/chmod +x /opt/bin/kube-proxy - # wait for kubernetes master to be up and ready - ExecStartPre=/opt/bin/wupiao 8080 - ExecStart=/opt/bin/kube-proxy \ - --master=:8080 \ - --logtostderr=true - Restart=always - RestartSec=10 - - name: kube-kubelet.service - command: start - content: | - [Unit] - Description=Kubernetes Kubelet - Documentation=https://k8s.io/kubernetes - Requires=setup-network-environment.service - After=setup-network-environment.service - - [Service] - EnvironmentFile=/etc/network-environment - ExecStartPre=/usr/bin/curl -L -o /opt/bin/kubelet -z /opt/bin/kubelet https://storage.googleapis.com/kubernetes-release/release/v1.0.1/bin/linux/amd64/kubelet - ExecStartPre=/usr/bin/chmod +x /opt/bin/kubelet - # wait for kubernetes master to be up and ready - ExecStartPre=/opt/bin/wupiao 8080 - ExecStart=/opt/bin/kubelet \ - --address=0.0.0.0 \ - --port=10250 \ - --hostname_override=${DEFAULT_IPV4} \ - --api_servers=:8080 \ - --allow_privileged=true \ - --logtostderr=true \ - --cadvisor_port=4194 \ - --healthz_bind_address=0.0.0.0 \ - --healthz_port=10248 - Restart=always - RestartSec=10 - update: - group: alpha - reboot-strategy: off diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/coreos_multinode_cluster.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/coreos_multinode_cluster.md deleted file mode 100644 index 4aa9fe7650bc..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/coreos/coreos_multinode_cluster.md +++ /dev/null @@ -1,174 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/coreos/coreos_multinode_cluster.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# CoreOS Multinode Cluster - -Use the [master.yaml](cloud-configs/master.yaml) and [node.yaml](cloud-configs/node.yaml) cloud-configs to provision a multi-node Kubernetes cluster. - -> **Attention**: This requires at least CoreOS version **[695.0.0][coreos695]**, which includes `etcd2`. - -[coreos695]: https://coreos.com/releases/#695.0.0 - -## Overview - -* Provision the master node -* Capture the master node private IP address -* Edit node.yaml -* Provision one or more worker nodes - -### AWS - -*Attention:* Replace `` below for a [suitable version of CoreOS image for AWS](https://coreos.com/docs/running-coreos/cloud-providers/ec2/). - -#### Provision the Master - -```sh -aws ec2 create-security-group --group-name kubernetes --description "Kubernetes Security Group" -aws ec2 authorize-security-group-ingress --group-name kubernetes --protocol tcp --port 22 --cidr 0.0.0.0/0 -aws ec2 authorize-security-group-ingress --group-name kubernetes --protocol tcp --port 80 --cidr 0.0.0.0/0 -aws ec2 authorize-security-group-ingress --group-name kubernetes --source-security-group-name kubernetes -``` - -```sh -aws ec2 run-instances \ ---image-id \ ---key-name \ ---region us-west-2 \ ---security-groups kubernetes \ ---instance-type m3.medium \ ---user-data file://master.yaml -``` - -#### Capture the private IP address - -```sh -aws ec2 describe-instances --instance-id -``` - -#### Edit node.yaml - -Edit `node.yaml` and replace all instances of `` with the private IP address of the master node. - -#### Provision worker nodes - -```sh -aws ec2 run-instances \ ---count 1 \ ---image-id \ ---key-name \ ---region us-west-2 \ ---security-groups kubernetes \ ---instance-type m3.medium \ ---user-data file://node.yaml -``` - -### Google Compute Engine (GCE) - -*Attention:* Replace `` below for a [suitable version of CoreOS image for Google Compute Engine](https://coreos.com/docs/running-coreos/cloud-providers/google-compute-engine/). - -#### Provision the Master - -```sh -gcloud compute instances create master \ ---image-project coreos-cloud \ ---image \ ---boot-disk-size 200GB \ ---machine-type n1-standard-1 \ ---zone us-central1-a \ ---metadata-from-file user-data=master.yaml -``` - -#### Capture the private IP address - -```sh -gcloud compute instances list -``` - -#### Edit node.yaml - -Edit `node.yaml` and replace all instances of `` with the private IP address of the master node. - -#### Provision worker nodes - -```sh -gcloud compute instances create node1 \ ---image-project coreos-cloud \ ---image \ ---boot-disk-size 200GB \ ---machine-type n1-standard-1 \ ---zone us-central1-a \ ---metadata-from-file user-data=node.yaml -``` - -#### Establish network connectivity - -Next, setup an ssh tunnel to the master so you can run kubectl from your local host. -In one terminal, run `gcloud compute ssh master --ssh-flag="-L 8080:127.0.0.1:8080"` and in a second -run `gcloud compute ssh master --ssh-flag="-R 8080:127.0.0.1:8080"`. - -### VMware Fusion - -#### Create the master config-drive - -```sh -mkdir -p /tmp/new-drive/openstack/latest/ -cp master.yaml /tmp/new-drive/openstack/latest/user_data -hdiutil makehybrid -iso -joliet -joliet-volume-name "config-2" -joliet -o master.iso /tmp/new-drive -``` - -#### Provision the Master - -Boot the [vmware image](https://coreos.com/docs/running-coreos/platforms/vmware) using `master.iso` as a config drive. - -#### Capture the master private IP address - -#### Edit node.yaml - -Edit `node.yaml` and replace all instances of `` with the private IP address of the master node. - -#### Create the node config-drive - -```sh -mkdir -p /tmp/new-drive/openstack/latest/ -cp node.yaml /tmp/new-drive/openstack/latest/user_data -hdiutil makehybrid -iso -joliet -joliet-volume-name "config-2" -joliet -o node.iso /tmp/new-drive -``` - -#### Provision worker nodes - -Boot one or more the [vmware image](https://coreos.com/docs/running-coreos/platforms/vmware) using `node.iso` as a config drive. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/coreos/coreos_multinode_cluster.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode.md deleted file mode 100644 index 60787ac7105e..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode.md +++ /dev/null @@ -1,118 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/docker-multinode.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Running Multi-Node Kubernetes Using Docker ------------------------------------------- - -_Note_: -These instructions are somewhat significantly more advanced than the [single node](docker.md) instructions. If you are -interested in just starting to explore Kubernetes, we recommend that you start there. - -_Note_: -There is a [bug](https://github.com/docker/docker/issues/14106) in Docker 1.7.0 that prevents this from working correctly. -Please install Docker 1.6.2 or Docker 1.7.1. - -**Table of Contents** - -- [Prerequisites](#prerequisites) -- [Overview](#overview) - - [Bootstrap Docker](#bootstrap-docker) -- [Master Node](#master-node) -- [Adding a worker node](#adding-a-worker-node) -- [Testing your cluster](#testing-your-cluster) - -## Prerequisites - -1. You need a machine with docker of right version installed. - -## Overview - -This guide will set up a 2-node Kubernetes cluster, consisting of a _master_ node which hosts the API server and orchestrates work -and a _worker_ node which receives work from the master. You can repeat the process of adding worker nodes an arbitrary number of -times to create larger clusters. - -Here's a diagram of what the final result will look like: -![Kubernetes Single Node on Docker](k8s-docker.png) - -### Bootstrap Docker - -This guide also uses a pattern of running two instances of the Docker daemon - 1) A _bootstrap_ Docker instance which is used to start system daemons like `flanneld` and `etcd` - 2) A _main_ Docker instance which is used for the Kubernetes infrastructure and user's scheduled containers - -This pattern is necessary because the `flannel` daemon is responsible for setting up and managing the network that interconnects -all of the Docker containers created by Kubernetes. To achieve this, it must run outside of the _main_ Docker daemon. However, -it is still useful to use containers for deployment and management, so we create a simpler _bootstrap_ daemon to achieve this. - -## Master Node - -The first step in the process is to initialize the master node. - -Clone the Kubernetes repo, and run [master.sh](docker-multinode/master.sh) on the master machine with root: - -```sh -export K8S_VERSION= -cd kubernetes/cluster/docker-multinode -./master.sh -``` - -`Master done!` - -See [here](docker-multinode/master.md) for detailed instructions explaination. - -## Adding a worker node - -Once your master is up and running you can add one or more workers on different machines. - -Clone the Kubernetes repo, and run [worker.sh](docker-multinode/worker.sh) on the worker machine with root: - -```sh -export K8S_VERSION= -export MASTER_IP= -cd kubernetes/cluster/docker-multinode -./worker.sh -``` - -`Worker done!` - -See [here](docker-multinode/worker.md) for detailed instructions explaination. - -## Testing your cluster - -Once your cluster has been created you can [test it out](docker-multinode/testing.md) - -For more complete applications, please look in the [examples directory](../../examples/) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/docker-multinode.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/master.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/master.md deleted file mode 100644 index 02d1a30e1111..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/master.md +++ /dev/null @@ -1,204 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/docker-multinode/master.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Installing a Kubernetes Master Node via Docker - -We'll begin by setting up the master node. For the purposes of illustration, we'll assume that the IP of this machine is `${MASTER_IP}` - -There are two main phases to installing the master: - * [Setting up `flanneld` and `etcd`](#setting-up-flanneld-and-etcd) - * [Starting the Kubernetes master components](#starting-the-kubernetes-master) - - -## Setting up flanneld and etcd - -_Note_: -There is a [bug](https://github.com/docker/docker/issues/14106) in Docker 1.7.0 that prevents this from working correctly. -Please install Docker 1.6.2 or Docker 1.7.1. - -### Setup Docker-Bootstrap - -We're going to use `flannel` to set up networking between Docker daemons. Flannel itself (and etcd on which it relies) will run inside of -Docker containers themselves. To achieve this, we need a separate "bootstrap" instance of the Docker daemon. This daemon will be started with -`--iptables=false` so that it can only run containers with `--net=host`. That's sufficient to bootstrap our system. - -Run: - -```sh -sudo sh -c 'docker -d -H unix:///var/run/docker-bootstrap.sock -p /var/run/docker-bootstrap.pid --iptables=false --ip-masq=false --bridge=none --graph=/var/lib/docker-bootstrap 2> /var/log/docker-bootstrap.log 1> /dev/null &' -``` - -_Important Note_: -If you are running this on a long running system, rather than experimenting, you should run the bootstrap Docker instance under something like SysV init, upstart or systemd so that it is restarted -across reboots and failures. - - -### Startup etcd for flannel and the API server to use - -Run: - -```sh -sudo docker -H unix:///var/run/docker-bootstrap.sock run --net=host -d gcr.io/google_containers/etcd:2.0.12 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data -``` - -Next, you need to set a CIDR range for flannel. This CIDR should be chosen to be non-overlapping with any existing network you are using: - -```sh -sudo docker -H unix:///var/run/docker-bootstrap.sock run --net=host gcr.io/google_containers/etcd:2.0.12 etcdctl set /coreos.com/network/config '{ "Network": "10.1.0.0/16" }' -``` - - -### Set up Flannel on the master node - -Flannel is a network abstraction layer build by CoreOS, we will use it to provide simplified networking between our Pods of containers. - -Flannel re-configures the bridge that Docker uses for networking. As a result we need to stop Docker, reconfigure its networking, and then restart Docker. - -#### Bring down Docker - -To re-configure Docker to use flannel, we need to take docker down, run flannel and then restart Docker. - -Turning down Docker is system dependent, it may be: - -```sh -sudo /etc/init.d/docker stop -``` - -or - -```sh -sudo systemctl stop docker -``` - -or it may be something else. - -#### Run flannel - -Now run flanneld itself: - -```sh -sudo docker -H unix:///var/run/docker-bootstrap.sock run -d --net=host --privileged -v /dev/net:/dev/net quay.io/coreos/flannel:0.5.0 -``` - -The previous command should have printed a really long hash, copy this hash. - -Now get the subnet settings from flannel: - -```sh -sudo docker -H unix:///var/run/docker-bootstrap.sock exec cat /run/flannel/subnet.env -``` - -#### Edit the docker configuration - -You now need to edit the docker configuration to activate new flags. Again, this is system specific. - -This may be in `/etc/default/docker` or `/etc/systemd/service/docker.service` or it may be elsewhere. - -Regardless, you need to add the following to the docker command line: - -```sh ---bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} -``` - -#### Remove the existing Docker bridge - -Docker creates a bridge named `docker0` by default. You need to remove this: - -```sh -sudo /sbin/ifconfig docker0 down -sudo brctl delbr docker0 -``` - -You may need to install the `bridge-utils` package for the `brctl` binary. - -#### Restart Docker - -Again this is system dependent, it may be: - -```sh -sudo /etc/init.d/docker start -``` - -it may be: - -```sh -systemctl start docker -``` - -## Starting the Kubernetes Master - -Ok, now that your networking is set up, you can startup Kubernetes, this is the same as the single-node case, we will use the "main" instance of the Docker daemon for the Kubernetes components. - -```sh -sudo docker run --net=host --privileged -d -v /sys:/sys:ro -v /var/run/docker.sock:/var/run/docker.sock gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube kubelet --api-servers=http://localhost:8080 --v=2 --insecure-bind-address=0.0.0.0 --enable-server --hostname-override=127.0.0.1 --config=/etc/kubernetes/manifests-multi -``` - -### Also run the service proxy - -```sh -sudo docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube proxy --master=http://127.0.0.1:8080 --v=2 -``` - -### Test it out - -At this point, you should have a functioning 1-node cluster. Let's test it out! - -Download the kubectl binary -([OS X](http://storage.googleapis.com/kubernetes-release/release/v1.0.1/bin/darwin/amd64/kubectl)) -([linux](http://storage.googleapis.com/kubernetes-release/release/v1.0.1/bin/linux/amd64/kubectl)) - -List the nodes - -```sh -kubectl get nodes -``` - -This should print: - -```console -NAME LABELS STATUS -127.0.0.1 kubernetes.io/hostname=127.0.0.1 Ready -``` - -If the status of the node is `NotReady` or `Unknown` please check that all of the containers you created are successfully running. -If all else fails, ask questions on IRC at [#google-containers](http://webchat.freenode.net/?channels=google-containers). - - -### Next steps - -Move on to [adding one or more workers](worker.md) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/docker-multinode/master.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/master.sh b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/master.sh deleted file mode 100755 index bef09d55896a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/master.sh +++ /dev/null @@ -1,151 +0,0 @@ -#!/bin/bash - -# Copyright 2015 The Kubernetes Authors All rights reserved. -# -# 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. - -# A scripts to install k8s worker node. -# Author @wizard_cxy @reouser - -set -e - -# Make sure docker daemon is running -if ( ! ps -ef | grep "/usr/bin/docker" | grep -v 'grep' &> /dev/null ); then - echo "Docker is not running on this machine!" - exit 1 -fi - -# Make sure k8s version env is properly set -if [ -z ${K8S_VERSION} ]; then - echo "Please export K8S_VERSION in your env" - exit 1 -else - echo "k8s version is set to: ${K8S_VERSION}" -fi - - -# Run as root -if [ "$(id -u)" != "0" ]; then - echo >&2 "Please run as root" - exit 1 -fi - -# Check if a command is valid -command_exists() { - command -v "$@" > /dev/null 2>&1 -} - -lsb_dist="" - -# Detect the OS distro, we support ubuntu, debian, mint, centos, fedora dist -detect_lsb() { - case "$(uname -m)" in - *64) - ;; - *) - echo "Error: We currently only support 64-bit platforms." - exit 1 - ;; - esac - - if command_exists lsb_release; then - lsb_dist="$(lsb_release -si)" - fi - if [ -z ${lsb_dist} ] && [ -r /etc/lsb-release ]; then - lsb_dist="$(. /etc/lsb-release && echo "$DISTRIB_ID")" - fi - if [ -z ${lsb_dist} ] && [ -r /etc/debian_version ]; then - lsb_dist='debian' - fi - if [ -z ${lsb_dist} ] && [ -r /etc/fedora-release ]; then - lsb_dist='fedora' - fi - if [ -z ${lsb_dist} ] && [ -r /etc/os-release ]; then - lsb_dist="$(. /etc/os-release && echo "$ID")" - fi - - lsb_dist="$(echo ${lsb_dist} | tr '[:upper:]' '[:lower:]')" -} - - -# Start the bootstrap daemon -bootstrap_daemon() { - sudo -b docker -d -H unix:///var/run/docker-bootstrap.sock -p /var/run/docker-bootstrap.pid --iptables=false --ip-masq=false --bridge=none --graph=/var/lib/docker-bootstrap 2> /var/log/docker-bootstrap.log 1> /dev/null - - sleep 5 -} - -# Start k8s components in containers -DOCKER_CONF="" - -start_k8s(){ - # Start etcd - docker -H unix:///var/run/docker-bootstrap.sock run --restart=always --net=host -d gcr.io/google_containers/etcd:2.0.12 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data - - sleep 5 - # Set flannel net config - docker -H unix:///var/run/docker-bootstrap.sock run --net=host gcr.io/google_containers/etcd:2.0.12 etcdctl set /coreos.com/network/config '{ "Network": "10.1.0.0/16" }' - - # iface may change to a private network interface, eth0 is for default - flannelCID=$(docker -H unix:///var/run/docker-bootstrap.sock run --restart=always -d --net=host --privileged -v /dev/net:/dev/net quay.io/coreos/flannel:0.5.0 /opt/bin/flanneld -iface="eth0") - - sleep 8 - - # Copy flannel env out and source it on the host - docker -H unix:///var/run/docker-bootstrap.sock cp ${flannelCID}:/run/flannel/subnet.env . - source subnet.env - - # Configure docker net settings, then restart it - case "$lsb_dist" in - fedora|centos|amzn) - DOCKER_CONF="/etc/sysconfig/docker" - ;; - ubuntu|debian|linuxmint) - DOCKER_CONF="/etc/default/docker" - ;; - esac - - # Append the docker opts - echo "DOCKER_OPTS=\"\$DOCKER_OPTS --mtu=${FLANNEL_MTU} --bip=${FLANNEL_SUBNET}\"" | sudo tee -a ${DOCKER_CONF} - - - # sleep a little bit - ifconfig docker0 down - - case "$lsb_dist" in - fedora|centos|amzn) - yum install bridge-utils && brctl delbr docker0 && systemctl restart docker - ;; - ubuntu|debian|linuxmint) - apt-get install bridge-utils && brctl delbr docker0 && service docker restart - ;; - esac - - # sleep a little bit - sleep 5 - - # Start kubelet & proxy, then start master components as pods - docker run --net=host --privileged -d -v /sys:/sys:ro -v /var/run/docker.sock:/var/run/docker.sock gcr.io/google_containers/hyperkube:v${K8S_VERSION} /hyperkube kubelet --api-servers=http://localhost:8080 --v=2 --insecure-bind-address=0.0.0.0 --enable-server --hostname-override=127.0.0.1 --config=/etc/kubernetes/manifests-multi - docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v${K8S_VERSION} /hyperkube proxy --master=http://127.0.0.1:8080 --v=2 -} - -echo "Detecting your OS distro ..." -detect_lsb - -echo "Starting bootstrap docker ..." -bootstrap_daemon - -echo "Starting k8s ..." -start_k8s - -echo "Master done!" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/testing.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/testing.md deleted file mode 100644 index 1f4af152fec0..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/testing.md +++ /dev/null @@ -1,101 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/docker-multinode/testing.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Testing your Kubernetes cluster. - -To validate that your node(s) have been added, run: - -```sh -kubectl get nodes -``` - -That should show something like: - -```console -NAME LABELS STATUS -10.240.99.26 kubernetes.io/hostname=10.240.99.26 Ready -127.0.0.1 kubernetes.io/hostname=127.0.0.1 Ready -``` - -If the status of any node is `Unknown` or `NotReady` your cluster is broken, double check that all containers are running properly, and if all else fails, contact us on IRC at -[`#google-containers`](http://webchat.freenode.net/?channels=google-containers) for advice. - -### Run an application - -```sh -kubectl -s http://localhost:8080 run nginx --image=nginx --port=80 -``` - -now run `docker ps` you should see nginx running. You may need to wait a few minutes for the image to get pulled. - -### Expose it as a service - -```sh -kubectl expose rc nginx --port=80 -``` - -This should print: - -```console -NAME LABELS SELECTOR IP PORT(S) -nginx run=nginx 80/TCP -``` - -Hit the webserver: - -```sh -curl -``` - -Note that you will need run this curl command on your boot2docker VM if you are running on OS X. - -### Scaling - -Now try to scale up the nginx you created before: - -```sh -kubectl scale rc nginx --replicas=3 -``` - -And list the pods - -```sh -kubectl get pods -``` - -You should see pods landing on the newly added machine. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/docker-multinode/testing.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/worker.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/worker.md deleted file mode 100644 index 20eb17f4d493..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/worker.md +++ /dev/null @@ -1,167 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/docker-multinode/worker.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Adding a Kubernetes worker node via Docker. - - - -These instructions are very similar to the master set-up above, but they are duplicated for clarity. -You need to repeat these instructions for each node you want to join the cluster. -We will assume that the IP address of this node is `${NODE_IP}` and you have the IP address of the master in `${MASTER_IP}` that you created in the [master instructions](master.md). - -For each worker node, there are three steps: - * [Set up `flanneld` on the worker node](#set-up-flanneld-on-the-worker-node) - * [Start Kubernetes on the worker node](#start-kubernetes-on-the-worker-node) - * [Add the worker to the cluster](#add-the-node-to-the-cluster) - -### Set up Flanneld on the worker node - -As before, the Flannel daemon is going to provide network connectivity. - -_Note_: -There is a [bug](https://github.com/docker/docker/issues/14106) in Docker 1.7.0 that prevents this from working correctly. -Please install Docker 1.6.2 or wait for Docker 1.7.1. - - -#### Set up a bootstrap docker - -As previously, we need a second instance of the Docker daemon running to bootstrap the flannel networking. - -Run: - -```sh -sudo sh -c 'docker -d -H unix:///var/run/docker-bootstrap.sock -p /var/run/docker-bootstrap.pid --iptables=false --ip-masq=false --bridge=none --graph=/var/lib/docker-bootstrap 2> /var/log/docker-bootstrap.log 1> /dev/null &' -``` - -_Important Note_: -If you are running this on a long running system, rather than experimenting, you should run the bootstrap Docker instance under something like SysV init, upstart or systemd so that it is restarted -across reboots and failures. - -#### Bring down Docker - -To re-configure Docker to use flannel, we need to take docker down, run flannel and then restart Docker. - -Turning down Docker is system dependent, it may be: - -```sh -sudo /etc/init.d/docker stop -``` - -or - -```sh -sudo systemctl stop docker -``` - -or it may be something else. - -#### Run flannel - -Now run flanneld itself, this call is slightly different from the above, since we point it at the etcd instance on the master. - -```sh -sudo docker -H unix:///var/run/docker-bootstrap.sock run -d --net=host --privileged -v /dev/net:/dev/net quay.io/coreos/flannel:0.5.0 /opt/bin/flanneld --etcd-endpoints=http://${MASTER_IP}:4001 -``` - -The previous command should have printed a really long hash, copy this hash. - -Now get the subnet settings from flannel: - -```sh -sudo docker -H unix:///var/run/docker-bootstrap.sock exec cat /run/flannel/subnet.env -``` - - -#### Edit the docker configuration - -You now need to edit the docker configuration to activate new flags. Again, this is system specific. - -This may be in `/etc/default/docker` or `/etc/systemd/service/docker.service` or it may be elsewhere. - -Regardless, you need to add the following to the docker command line: - -```sh ---bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} -``` - -#### Remove the existing Docker bridge - -Docker creates a bridge named `docker0` by default. You need to remove this: - -```sh -sudo /sbin/ifconfig docker0 down -sudo brctl delbr docker0 -``` - -You may need to install the `bridge-utils` package for the `brctl` binary. - -#### Restart Docker - -Again this is system dependent, it may be: - -```sh -sudo /etc/init.d/docker start -``` - -it may be: - -```sh -systemctl start docker -``` - -### Start Kubernetes on the worker node - -#### Run the kubelet - -Again this is similar to the above, but the `--api_servers` now points to the master we set up in the beginning. - -```sh -sudo docker run --net=host --privileged -d -v /sys:/sys:ro -v /var/run/docker.sock:/var/run/docker.sock gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube kubelet --api-servers=http://${MASTER_IP}:8080 --v=2 --insecure-bind-address=0.0.0.0 --enable-server --hostname-override=$(hostname -i) -``` - -#### Run the service proxy - -The service proxy provides load-balancing between groups of containers defined by Kubernetes `Services` - -```sh -sudo docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube proxy --master=http://${MASTER_IP}:8080 --v=2 -``` - -### Next steps - -Move on to [testing your cluster](testing.md) or [add another node](#adding-a-kubernetes-worker-node-via-docker) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/docker-multinode/worker.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/worker.sh b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/worker.sh deleted file mode 100755 index d667147f0b66..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker-multinode/worker.sh +++ /dev/null @@ -1,150 +0,0 @@ -#!/bin/bash - -# Copyright 2015 The Kubernetes Authors All rights reserved. -# -# 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. - -# A scripts to install k8s worker node. -# Author @wizard_cxy @reouser - -set -e - -# Make sure docker daemon is running -if ( ! ps -ef | grep "/usr/bin/docker" | grep -v 'grep' &> /dev/null ); then - echo "Docker is not running on this machine!" - exit 1 -fi - -# Make sure k8s version env is properly set -if [ -z ${K8S_VERSION} ]; then - echo "Please export K8S_VERSION in your env" - exit 1 -else - echo "k8s version is set to: ${K8S_VERSION}" -fi - - -# Run as root -if [ "$(id -u)" != "0" ]; then - echo >&2 "Please run as root" - exit 1 -fi - -# Make sure master ip is properly set -if [ -z ${MASTER_IP} ]; then - echo "Please export MASTER_IP in your env" - exit 1 -else - echo "k8s master is set to: ${MASTER_IP}" -fi - -# Check if a command is valid -command_exists() { - command -v "$@" > /dev/null 2>&1 -} - -lsb_dist="" - -# Detect the OS distro, we support ubuntu, debian, mint, centos, fedora dist -detect_lsb() { - case "$(uname -m)" in - *64) - ;; - *) - echo "Error: We currently only support 64-bit platforms." - exit 1 - ;; - esac - - if command_exists lsb_release; then - lsb_dist="$(lsb_release -si)" - fi - if [ -z ${lsb_dist} ] && [ -r /etc/lsb-release ]; then - lsb_dist="$(. /etc/lsb-release && echo "$DISTRIB_ID")" - fi - if [ -z ${lsb_dist} ] && [ -r /etc/debian_version ]; then - lsb_dist='debian' - fi - if [ -z ${lsb_dist} ] && [ -r /etc/fedora-release ]; then - lsb_dist='fedora' - fi - if [ -z ${lsb_dist} ] && [ -r /etc/os-release ]; then - lsb_dist="$(. /etc/os-release && echo "$ID")" - fi - - lsb_dist="$(echo ${lsb_dist} | tr '[:upper:]' '[:lower:]')" -} - - -# Start the bootstrap daemon -bootstrap_daemon() { - sudo -b docker -d -H unix:///var/run/docker-bootstrap.sock -p /var/run/docker-bootstrap.pid --iptables=false --ip-masq=false --bridge=none --graph=/var/lib/docker-bootstrap 2> /var/log/docker-bootstrap.log 1> /dev/null - - sleep 5 -} - -DOCKER_CONF="" - -# Start k8s components in containers -start_k8s() { - # Start flannel - flannelCID=$(sudo docker -H unix:///var/run/docker-bootstrap.sock run -d --restart=always --net=host --privileged -v /dev/net:/dev/net quay.io/coreos/flannel:0.5.0 /opt/bin/flanneld --etcd-endpoints=http://${MASTER_IP}:4001 -iface="eth0") - - sleep 8 - - # Copy flannel env out and source it on the host - sudo docker -H unix:///var/run/docker-bootstrap.sock cp ${flannelCID}:/run/flannel/subnet.env . - source subnet.env - - # Configure docker net settings, then restart it - case "$lsb_dist" in - fedora|centos|amzn) - DOCKER_CONF="/etc/sysconfig/docker" - ;; - ubuntu|debian|linuxmint) - DOCKER_CONF="/etc/default/docker" - ;; - esac - - echo "DOCKER_OPTS=\"\$DOCKER_OPTS --mtu=${FLANNEL_MTU} --bip=${FLANNEL_SUBNET}\"" | sudo tee -a ${DOCKER_CONF} - - ifconfig docker0 down - - case "$lsb_dist" in - fedora|centos) - yum install bridge-utils && brctl delbr docker0 && systemctl restart docker - ;; - ubuntu|debian|linuxmint) - apt-get install bridge-utils && brctl delbr docker0 && service docker restart - ;; - esac - - # sleep a little bit - sleep 5 - - # Start kubelet & proxy in container - sudo docker run --net=host --privileged -d -v /sys:/sys:ro -v /var/run/docker.sock:/var/run/docker.sock gcr.io/google_containers/hyperkube:v${K8S_VERSION} /hyperkube kubelet --api-servers=http://${MASTER_IP}:8080 --v=2 --insecure-bind-address=0.0.0.0 --enable-server --hostname-override=$(hostname -i) - sudo docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v${K8S_VERSION} /hyperkube proxy --master=http://${MASTER_IP}:8080 --v=2 - -} - -echo "Detecting your OS distro ..." -detect_lsb - -echo "Starting bootstrap docker ..." -bootstrap_daemon - -echo "Starting k8s ..." -start_k8s - -echo "Worker done!" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker.md deleted file mode 100644 index 15828612c03b..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/docker.md +++ /dev/null @@ -1,155 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/docker.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Running Kubernetes locally via Docker -------------------------------------- - -**Table of Contents** - -- [Overview](#setting-up-a-cluster) -- [Prerequisites](#prerequisites) -- [Step One: Run etcd](#step-one-run-etcd) -- [Step Two: Run the master](#step-two-run-the-master) -- [Step Three: Run the service proxy](#step-three-run-the-service-proxy) -- [Test it out](#test-it-out) -- [Run an application](#run-an-application) -- [Expose it as a service:](#expose-it-as-a-service) -- [A note on turning down your cluster](#a-note-on-turning-down-your-cluster) - -### Overview - -The following instructions show you how to set up a simple, single node Kubernetes cluster using Docker. - -Here's a diagram of what the final result will look like: -![Kubernetes Single Node on Docker](k8s-singlenode-docker.png) - -### Prerequisites - -1. You need to have docker installed on one machine. - -### Step One: Run etcd - -```sh -docker run --net=host -d gcr.io/google_containers/etcd:2.0.12 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data -``` - -### Step Two: Run the master - -```sh -docker run --net=host --privileged -d -v /sys:/sys:ro -v /var/run/docker.sock:/var/run/docker.sock gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube kubelet --api-servers=http://localhost:8080 --v=2 --insecure-bind-address=0.0.0.0 --enable-server --hostname-override=127.0.0.1 --config=/etc/kubernetes/manifests -``` - -This actually runs the kubelet, which in turn runs a [pod](../user-guide/pods.md) that contains the other master components. - -### Step Three: Run the service proxy - -*Note, this could be combined with master above, but it requires --privileged for iptables manipulation* - -```sh -docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube proxy --master=http://127.0.0.1:8080 --v=2 -``` - -### Test it out - -At this point you should have a running Kubernetes cluster. You can test this by downloading the kubectl -binary -([OS X](https://storage.googleapis.com/kubernetes-release/release/v1.0.1/bin/darwin/amd64/kubectl)) -([linux](https://storage.googleapis.com/kubernetes-release/release/v1.0.1/bin/linux/amd64/kubectl)) - -*Note:* -On OS/X you will need to set up port forwarding via ssh: - -```sh -boot2docker ssh -L8080:localhost:8080 -``` - -List the nodes in your cluster by running:: - -```sh -kubectl get nodes -``` - -This should print: - -```console -NAME LABELS STATUS -127.0.0.1 Ready -``` - -If you are running different Kubernetes clusters, you may need to specify `-s http://localhost:8080` to select the local cluster. - -### Run an application - -```sh -kubectl -s http://localhost:8080 run nginx --image=nginx --port=80 -``` - -now run `docker ps` you should see nginx running. You may need to wait a few minutes for the image to get pulled. - -### Expose it as a service - -```sh -kubectl expose rc nginx --port=80 -``` - -This should print: - -```console -NAME LABELS SELECTOR IP PORT(S) -nginx run=nginx run=nginx 80/TCP -``` - -If ip-addr is blank run the following command to obtain it. Know issue #10836 - -```sh -kubectl get svc nginx -``` - -Hit the webserver: - -```sh -curl -``` - -Note that you will need run this curl command on your boot2docker VM if you are running on OS X. - -### A note on turning down your cluster - -Many of these containers run under the management of the `kubelet` binary, which attempts to keep containers running, even if they fail. So, in order to turn down -the cluster, you need to first kill the kubelet container, and then any other containers. - -You may use `docker ps -a | awk '{print $1}' | xargs docker kill`, note this removes _all_ containers running under Docker, so use with caution. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/docker.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/es-browser.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/es-browser.png deleted file mode 100644 index f556fa8c5619b8574279eeabaa1302b12aa16331..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40769 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 - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/fedora/fedora_ansible_config.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Configuring Kubernetes on [Fedora](http://fedoraproject.org) via [Ansible](http://www.ansible.com/home) -------------------------------------------------------------------------------------------------------- - -Configuring Kubernetes on Fedora via Ansible offers a simple way to quickly create a clustered environment with little effort. - -**Table of Contents** - -- [Prerequisites](#prerequisites) -- [Architecture of the cluster](#architecture-of-the-cluster) -- [Setting up ansible access to your nodes](#setting-up-ansible-access-to-your-nodes) -- [Setting up the cluster](#setting-up-the-cluster) -- [Testing and using your new cluster](#testing-and-using-your-new-cluster) - -## Prerequisites - -1. Host able to run ansible and able to clone the following repo: [kubernetes](https://k8s.io/kubernetes.git) -2. A Fedora 21+ host to act as cluster master -3. As many Fedora 21+ hosts as you would like, that act as cluster nodes - -The hosts can be virtual or bare metal. Ansible will take care of the rest of the configuration for you - configuring networking, installing packages, handling the firewall, etc. This example will use one master and two nodes. - -## Architecture of the cluster - -A Kubernetes cluster requires etcd, a master, and n nodes, so we will create a cluster with three hosts, for example: - -```console - master,etcd = kube-master.example.com - node1 = kube-node-01.example.com - node2 = kube-node-02.example.com -``` - -**Make sure your local machine has** - - - ansible (must be 1.9.0+) - - git - - python-netaddr - -If not - -```sh -yum install -y ansible git python-netaddr -``` - -**Now clone down the Kubernetes repository** - -```sh -git clone https://k8s.io/kubernetes.git -cd kubernetes/contrib/ansible -``` - -**Tell ansible about each machine and its role in your cluster** - -Get the IP addresses from the master and nodes. Add those to the `~/kubernetes/contrib/ansible/inventory` file on the host running Ansible. - -```console -[masters] -kube-master.example.com - -[etcd] -kube-master.example.com - -[nodes] -kube-node-01.example.com -kube-node-02.example.com -``` - -## Setting up ansible access to your nodes - -If you already are running on a machine which has passwordless ssh access to the kube-master and kube-node-{01,02} nodes, and 'sudo' privileges, simply set the value of `ansible_ssh_user` in `~/kubernetes/contrib/ansible/group_vars/all.yaml` to the username which you use to ssh to the nodes (i.e. `fedora`), and proceed to the next step... - -*Otherwise* setup ssh on the machines like so (you will need to know the root password to all machines in the cluster). - -edit: ~/kubernetes/contrib/ansible/group_vars/all.yml - -```yaml -ansible_ssh_user: root -``` - -**Configuring ssh access to the cluster** - -If you already have ssh access to every machine using ssh public keys you may skip to [setting up the cluster](#setting-up-the-cluster) - -Make sure your local machine (root) has an ssh key pair if not - -```sh -ssh-keygen -``` - -Copy the ssh public key to **all** nodes in the cluster - -```sh -for node in kube-master.example.com kube-node-01.example.com kube-node-02.example.com; do - ssh-copy-id ${node} -done -``` - -## Setting up the cluster - -Although the default value of variables in `~/kubernetes/contrib/ansible/group_vars/all.yml` should be good enough, if not, change them as needed. - -edit: ~/kubernetes/contrib/ansible/group_vars/all.yml - -**Configure access to kubernetes packages** - -Modify `source_type` as below to access kubernetes packages through the package manager. - -```yaml -source_type: packageManager -``` - -**Configure the IP addresses used for services** - -Each Kubernetes service gets its own IP address. These are not real IPs. You need only select a range of IPs which are not in use elsewhere in your environment. - -```yaml -kube_service_addresses: 10.254.0.0/16 -``` - -**Managing flannel** - -Modify `flannel_subnet`, `flannel_prefix` and `flannel_host_prefix` only if defaults are not appropriate for your cluster. - - -**Managing add on services in your cluster** - -Set `cluster_logging` to false or true (default) to disable or enable logging with elasticsearch. - -```yaml -cluster_logging: true -``` - -Turn `cluster_monitoring` to true (default) or false to enable or disable cluster monitoring with heapster and influxdb. - -```yaml -cluster_monitoring: true -``` - -Turn `dns_setup` to true (recommended) or false to enable or disable whole DNS configuration. - -```yaml -dns_setup: true -``` - -**Tell ansible to get to work!** - -This will finally setup your whole Kubernetes cluster for you. - -```sh -cd ~/kubernetes/contrib/ansible/ - -./setup.sh -``` - -## Testing and using your new cluster - -That's all there is to it. It's really that easy. At this point you should have a functioning Kubernetes cluster. - -**Show kubernets nodes** - -Run the following on the kube-master: - -```sh -kubectl get nodes -``` - -**Show services running on masters and nodes** - -```sh -systemctl | grep -i kube -``` - -**Show firewall rules on the masters and nodes** - -```sh -iptables -nvL -``` - -**Create /tmp/apache.json on the master with the following contents and deploy pod** - -```json -{ - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "fedoraapache", - "labels": { - "name": "fedoraapache" - } - }, - "spec": { - "containers": [ - { - "name": "fedoraapache", - "image": "fedora/apache", - "ports": [ - { - "hostPort": 80, - "containerPort": 80 - } - ] - } - ] - } -} -``` - -```sh -kubectl create -f /tmp/apache.json -``` - -**Check where the pod was created** - -```sh -kubectl get pods -``` - -**Check Docker status on nodes** - -```sh -docker ps -docker images -``` - -**After the pod is 'Running' Check web server access on the node** - -```sh -curl http://localhost -``` - -That's it ! - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/fedora/fedora_ansible_config.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/fedora/fedora_manual_config.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/fedora/fedora_manual_config.md deleted file mode 100644 index 3b1e521566bf..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/fedora/fedora_manual_config.md +++ /dev/null @@ -1,242 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/fedora/fedora_manual_config.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started on [Fedora](http://fedoraproject.org) ------------------------------------------------------ - -**Table of Contents** - -- [Prerequisites](#prerequisites) -- [Instructions](#instructions) - -## Prerequisites - -1. You need 2 or more machines with Fedora installed. - -## Instructions - -This is a getting started guide for Fedora. It is a manual configuration so you understand all the underlying packages / services / ports, etc... - -This guide will only get ONE node (previously minion) working. Multiple nodes require a functional [networking configuration](../../admin/networking.md) done outside of Kubernetes. Although the additional Kubernetes configuration requirements should be obvious. - -The Kubernetes package provides a few services: kube-apiserver, kube-scheduler, kube-controller-manager, kubelet, kube-proxy. These services are managed by systemd and the configuration resides in a central location: /etc/kubernetes. We will break the services up between the hosts. The first host, fed-master, will be the Kubernetes master. This host will run the kube-apiserver, kube-controller-manager, and kube-scheduler. In addition, the master will also run _etcd_ (not needed if _etcd_ runs on a different host but this guide assumes that _etcd_ and Kubernetes master run on the same host). The remaining host, fed-node will be the node and run kubelet, proxy and docker. - -**System Information:** - -Hosts: - -``` -fed-master = 192.168.121.9 -fed-node = 192.168.121.65 -``` - -**Prepare the hosts:** - -* Install Kubernetes on all hosts - fed-{master,node}. This will also pull in docker. Also install etcd on fed-master. This guide has been tested with kubernetes-0.18 and beyond. -* The [--enablerepo=update-testing](https://fedoraproject.org/wiki/QA:Updates_Testing) directive in the yum command below will ensure that the most recent Kubernetes version that is scheduled for pre-release will be installed. This should be a more recent version than the Fedora "stable" release for Kubernetes that you would get without adding the directive. -* If you want the very latest Kubernetes release [you can download and yum install the RPM directly from Fedora Koji](http://koji.fedoraproject.org/koji/packageinfo?packageID=19202) instead of using the yum install command below. - -```sh -yum -y install --enablerepo=updates-testing kubernetes -``` - -* Install etcd and iptables - -```sh -yum -y install etcd iptables -``` - -* Add master and node to /etc/hosts on all machines (not needed if hostnames already in DNS). Make sure that communication works between fed-master and fed-node by using a utility such as ping. - -```sh -echo "192.168.121.9 fed-master -192.168.121.65 fed-node" >> /etc/hosts -``` - -* Edit /etc/kubernetes/config which will be the same on all hosts (master and node) to contain: - -```sh -# Comma separated list of nodes in the etcd cluster -KUBE_MASTER="--master=http://fed-master:8080" - -# logging to stderr means we get it in the systemd journal -KUBE_LOGTOSTDERR="--logtostderr=true" - -# journal message level, 0 is debug -KUBE_LOG_LEVEL="--v=0" - -# Should this cluster be allowed to run privileged docker containers -KUBE_ALLOW_PRIV="--allow_privileged=false" -``` - -* Disable the firewall on both the master and node, as docker does not play well with other firewall rule managers. Please note that iptables-services does not exist on default fedora server install. - -```sh -systemctl disable iptables-services firewalld -systemctl stop iptables-services firewalld -``` - -**Configure the Kubernetes services on the master.** - -* Edit /etc/kubernetes/apiserver to appear as such. The service_cluster_ip_range IP addresses must be an unused block of addresses, not used anywhere else. They do not need to be routed or assigned to anything. - -```sh -# The address on the local server to listen to. -KUBE_API_ADDRESS="--address=0.0.0.0" - -# Comma separated list of nodes in the etcd cluster -KUBE_ETCD_SERVERS="--etcd_servers=http://127.0.0.1:4001" - -# Address range to use for services -KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16" - -# Add your own! -KUBE_API_ARGS="" -``` - -* Edit /etc/etcd/etcd.conf,let the etcd to listen all the ip instead of 127.0.0.1, if not, you will get the error like "connection refused" - -```sh -ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:4001" -``` - -* Create /var/run/kubernetes on master: - -```sh -mkdir /var/run/kubernetes -chown kube:kube /var/run/kubernetes -chmod 750 /var/run/kubernetes -``` - -* Start the appropriate services on master: - -```sh -for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do - systemctl restart $SERVICES - systemctl enable $SERVICES - systemctl status $SERVICES -done -``` - -* Addition of nodes: - -* Create following node.json file on Kubernetes master node: - -```json -{ - "apiVersion": "v1", - "kind": "Node", - "metadata": { - "name": "fed-node", - "labels":{ "name": "fed-node-label"} - }, - "spec": { - "externalID": "fed-node" - } -} -``` - -Now create a node object internally in your Kubernetes cluster by running: - -```console -$ kubectl create -f ./node.json - -$ kubectl get nodes -NAME LABELS STATUS -fed-node name=fed-node-label Unknown -``` - -Please note that in the above, it only creates a representation for the node -_fed-node_ internally. It does not provision the actual _fed-node_. Also, it -is assumed that _fed-node_ (as specified in `name`) can be resolved and is -reachable from Kubernetes master node. This guide will discuss how to provision -a Kubernetes node (fed-node) below. - -**Configure the Kubernetes services on the node.** - -***We need to configure the kubelet on the node.*** - -* Edit /etc/kubernetes/kubelet to appear as such: - -```sh -### -# Kubernetes kubelet (node) config - -# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces) -KUBELET_ADDRESS="--address=0.0.0.0" - -# You may leave this blank to use the actual hostname -KUBELET_HOSTNAME="--hostname_override=fed-node" - -# location of the api-server -KUBELET_API_SERVER="--api_servers=http://fed-master:8080" - -# Add your own! -#KUBELET_ARGS="" -``` - -* Start the appropriate services on the node (fed-node). - -```sh -for SERVICES in kube-proxy kubelet docker; do - systemctl restart $SERVICES - systemctl enable $SERVICES - systemctl status $SERVICES -done -``` - -* Check to make sure now the cluster can see the fed-node on fed-master, and its status changes to _Ready_. - -```console -kubectl get nodes -NAME LABELS STATUS -fed-node name=fed-node-label Ready -``` - -* Deletion of nodes: - -To delete _fed-node_ from your Kubernetes cluster, one should run the following on fed-master (Please do not do it, it is just for information): - -```sh -kubectl delete -f ./node.json -``` - -*You should be finished!* - -**The cluster should be running! Launch a test pod.** - -You should have a functional cluster, check out [101](../../../docs/user-guide/walkthrough/README.md)! - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/fedora/fedora_manual_config.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/fedora/flannel_multi_node_cluster.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/fedora/flannel_multi_node_cluster.md deleted file mode 100644 index c23e56ff699f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/fedora/flannel_multi_node_cluster.md +++ /dev/null @@ -1,219 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/fedora/flannel_multi_node_cluster.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Kubernetes multiple nodes cluster with flannel on Fedora --------------------------------------------------------- - -**Table of Contents** - -- [Introduction](#introduction) -- [Prerequisites](#prerequisites) -- [Master Setup](#master-setup) -- [Node Setup](#node-setup) -- [**Test the cluster and flannel configuration**](#test-the-cluster-and-flannel-configuration) - -## Introduction - -This document describes how to deploy Kubernetes on multiple hosts to set up a multi-node cluster and networking with flannel. Follow fedora [getting started guide](fedora_manual_config.md) to setup 1 master (fed-master) and 2 or more nodes. Make sure that all nodes have different names (fed-node1, fed-node2 and so on) and labels (fed-node1-label, fed-node2-label, and so on) to avoid any conflict. Also make sure that the Kubernetes master host is running etcd, kube-controller-manager, kube-scheduler, and kube-apiserver services, and the nodes are running docker, kube-proxy and kubelet services. Now install flannel on Kubernetes nodes. flannel on each node configures an overlay network that docker uses. flannel runs on each node to setup a unique class-C container network. - -## Prerequisites - -1. You need 2 or more machines with Fedora installed. - -## Master Setup - -**Perform following commands on the Kubernetes master** - -* Configure flannel by creating a `flannel-config.json` in your current directory on fed-master. flannel provides udp and vxlan among other overlay networking backend options. In this guide, we choose kernel based vxlan backend. The contents of the json are: - -```json -{ - "Network": "18.16.0.0/16", - "SubnetLen": 24, - "Backend": { - "Type": "vxlan", - "VNI": 1 - } -} -``` - -**NOTE:** Choose an IP range that is *NOT* part of the public IP address range. - -* Add the configuration to the etcd server on fed-master. - -```sh -etcdctl set /coreos.com/network/config < flannel-config.json -``` - -* Verify the key exists in the etcd server on fed-master. - -```sh -etcdctl get /coreos.com/network/config -``` - -## Node Setup - -**Perform following commands on all Kubernetes nodes** - -* Edit the flannel configuration file /etc/sysconfig/flanneld as follows: - -```sh -# Flanneld configuration options - -# etcd url location. Point this to the server where etcd runs -FLANNEL_ETCD="http://fed-master:4001" - -# etcd config key. This is the configuration key that flannel queries -# For address range assignment -FLANNEL_ETCD_KEY="/coreos.com/network" - -# Any additional options that you want to pass -FLANNEL_OPTIONS="" -``` - -**Note:** By default, flannel uses the interface for the default route. If you have multiple interfaces and would like to use an interface other than the default route one, you could add "-iface=" to FLANNEL_OPTIONS. For additional options, run `flanneld --help` on command line. - -* Enable the flannel service. - -```sh -systemctl enable flanneld -``` - -* If docker is not running, then starting flannel service is enough and skip the next step. - -```sh -systemctl start flanneld -``` - -* If docker is already running, then stop docker, delete docker bridge (docker0), start flanneld and restart docker as follows. Another alternative is to just reboot the system (`systemctl reboot`). - -```sh -systemctl stop docker -ip link delete docker0 -systemctl start flanneld -systemctl start docker -``` - -*** - -## **Test the cluster and flannel configuration** - -* Now check the interfaces on the nodes. Notice there is now a flannel.1 interface, and the ip addresses of docker0 and flannel.1 interfaces are in the same network. You will notice that docker0 is assigned a subnet (18.16.29.0/24 as shown below) on each Kubernetes node out of the IP range configured above. A working output should look like this: - -```console -# ip -4 a|grep inet - inet 127.0.0.1/8 scope host lo - inet 192.168.122.77/24 brd 192.168.122.255 scope global dynamic eth0 - inet 18.16.29.0/16 scope global flannel.1 - inet 18.16.29.1/24 scope global docker0 -``` - -* From any node in the cluster, check the cluster members by issuing a query to etcd server via curl (only partial output is shown using `grep -E "\{|\}|key|value"`). If you set up a 1 master and 3 nodes cluster, you should see one block for each node showing the subnets they have been assigned. You can associate those subnets to each node by the MAC address (VtepMAC) and IP address (Public IP) that is listed in the output. - -```sh -curl -s http://fed-master:4001/v2/keys/coreos.com/network/subnets | python -mjson.tool -``` - -```json -{ - "node": { - "key": "/coreos.com/network/subnets", - { - "key": "/coreos.com/network/subnets/18.16.29.0-24", - "value": "{\"PublicIP\":\"192.168.122.77\",\"BackendType\":\"vxlan\",\"BackendData\":{\"VtepMAC\":\"46:f1:d0:18:d0:65\"}}" - }, - { - "key": "/coreos.com/network/subnets/18.16.83.0-24", - "value": "{\"PublicIP\":\"192.168.122.36\",\"BackendType\":\"vxlan\",\"BackendData\":{\"VtepMAC\":\"ca:38:78:fc:72:29\"}}" - }, - { - "key": "/coreos.com/network/subnets/18.16.90.0-24", - "value": "{\"PublicIP\":\"192.168.122.127\",\"BackendType\":\"vxlan\",\"BackendData\":{\"VtepMAC\":\"92:e2:80:ba:2d:4d\"}}" - } - } -} -``` - -* From all nodes, review the `/run/flannel/subnet.env` file. This file was generated automatically by flannel. - -```console -# cat /run/flannel/subnet.env -FLANNEL_SUBNET=18.16.29.1/24 -FLANNEL_MTU=1450 -FLANNEL_IPMASQ=false -``` - -* At this point, we have etcd running on the Kubernetes master, and flannel / docker running on Kubernetes nodes. Next steps are for testing cross-host container communication which will confirm that docker and flannel are configured properly. - -* Issue the following commands on any 2 nodes: - -```console -# docker run -it fedora:latest bash -bash-4.3# -``` - -* This will place you inside the container. Install iproute and iputils packages to install ip and ping utilities. Due to a [bug](https://bugzilla.redhat.com/show_bug.cgi?id=1142311), it is required to modify capabilities of ping binary to work around "Operation not permitted" error. - -```console -bash-4.3# yum -y install iproute iputils -bash-4.3# setcap cap_net_raw-ep /usr/bin/ping -``` - -* Now note the IP address on the first node: - -```console -bash-4.3# ip -4 a l eth0 | grep inet - inet 18.16.29.4/24 scope global eth0 -``` - -* And also note the IP address on the other node: - -```console -bash-4.3# ip a l eth0 | grep inet - inet 18.16.90.4/24 scope global eth0 -``` - -* Now ping from the first node to the other node: - -```console -bash-4.3# ping 18.16.90.4 -PING 18.16.90.4 (18.16.90.4) 56(84) bytes of data. -64 bytes from 18.16.90.4: icmp_seq=1 ttl=62 time=0.275 ms -64 bytes from 18.16.90.4: icmp_seq=2 ttl=62 time=0.372 ms -``` - -* Now Kubernetes multi-node cluster is set up with overlay networking set up by flannel. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/fedora/flannel_multi_node_cluster.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/gce.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/gce.md deleted file mode 100644 index 8517d3c540d6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/gce.md +++ /dev/null @@ -1,253 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/gce.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started on Google Compute Engine ----------------------------------------- - -**Table of Contents** - -- [Before you start](#before-you-start) -- [Prerequisites](#prerequisites) -- [Starting a cluster](#starting-a-cluster) -- [Installing the Kubernetes command line tools on your workstation](#installing-the-kubernetes-command-line-tools-on-your-workstation) -- [Getting started with your cluster](#getting-started-with-your-cluster) - - [Inspect your cluster](#inspect-your-cluster) - - [Run some examples](#run-some-examples) -- [Tearing down the cluster](#tearing-down-the-cluster) -- [Customizing](#customizing) -- [Troubleshooting](#troubleshooting) - - [Project settings](#project-settings) - - [Cluster initialization hang](#cluster-initialization-hang) - - [SSH](#ssh) - - [Networking](#networking) - - -The example below creates a Kubernetes cluster with 4 worker node Virtual Machines and a master Virtual Machine (i.e. 5 VMs in your cluster). This cluster is set up and controlled from your workstation (or wherever you find convenient). - -### Before you start - -If you want a simplified getting started experience and GUI for managing clusters, please consider trying [Google Container Engine](https://cloud.google.com/container-engine/) (GKE) for hosted cluster installation and management. - -If you want to use custom binaries or pure open source Kubernetes, please continue with the instructions below. - -### Prerequisites - -1. You need a Google Cloud Platform account with billing enabled. Visit the [Google Developers Console](http://cloud.google.com/console) for more details. -1. Install `gcloud` as necessary. `gcloud` can be installed as a part of the [Google Cloud SDK](https://cloud.google.com/sdk/). -1. Then, make sure you have the `gcloud preview` command line component installed. Run `gcloud preview` at the command line - if it asks to install any components, go ahead and install them. If it simply shows help text, you're good to go. This is required as the cluster setup script uses GCE [Instance Groups](https://cloud.google.com/compute/docs/instance-groups/), which are in the gcloud preview namespace. You will also need to **enable [`Compute Engine Instance Group Manager API`](https://developers.google.com/console/help/new/#activatingapis)** in the developers console. -1. Make sure that gcloud is set to use the Google Cloud Platform project you want. You can check the current project using `gcloud config list project` and change it via `gcloud config set project `. -1. Make sure you have credentials for GCloud by running ` gcloud auth login`. -1. Make sure you can start up a GCE VM from the command line. At least make sure you can do the [Create an instance](https://cloud.google.com/compute/docs/instances/#startinstancegcloud) part of the GCE Quickstart. -1. Make sure you can ssh into the VM without interactive prompts. See the [Log in to the instance](https://cloud.google.com/compute/docs/instances/#sshing) part of the GCE Quickstart. - -### Starting a cluster - -You can install a client and start a cluster with either one of these commands (we list both in case only one is installed on your machine): - - - ```bash - curl -sS https://get.k8s.io | bash - ``` - -or - -```bash -wget -q -O - https://get.k8s.io | bash -``` - -Once this command completes, you will have a master VM and four worker VMs, running as a Kubernetes cluster. - -By default, some containers will already be running on your cluster. Containers like `kibana` and `elasticsearch` provide [logging](logging.md), while `heapster` provides [monitoring](http://releases.k8s.io/HEAD/cluster/addons/cluster-monitoring/README.md) services. - -The script run by the commands above creates a cluster with the name/prefix "kubernetes". It defines one specific cluster config, so you can't run it more than once. - -Alternately, you can download and install the latest Kubernetes release from [this page](https://k8s.io/kubernetes/releases), then run the `/cluster/kube-up.sh` script to start the cluster: - -```bash -cd kubernetes -cluster/kube-up.sh -``` - -If you want more than one cluster running in your project, want to use a different name, or want a different number of worker nodes, see the `/cluster/gce/config-default.sh` file for more fine-grained configuration before you start up your cluster. - -If you run into trouble, please see the section on [troubleshooting](gce.md#troubleshooting), post to the -[google-containers group](https://groups.google.com/forum/#!forum/google-containers), or come ask questions on IRC at [#google-containers](http://webchat.freenode.net/?channels=google-containers) on freenode. - -The next few steps will show you: - -1. how to set up the command line client on your workstation to manage the cluster -1. examples of how to use the cluster -1. how to delete the cluster -1. how to start clusters with non-default options (like larger clusters) - -### Installing the Kubernetes command line tools on your workstation - -The cluster startup script will leave you with a running cluster and a `kubernetes` directory on your workstation. -The next step is to make sure the `kubectl` tool is in your path. - -The [kubectl](../user-guide/kubectl/kubectl.md) tool controls the Kubernetes cluster manager. It lets you inspect your cluster resources, create, delete, and update components, and much more. -You will use it to look at your new cluster and bring up example apps. - -Add the appropriate binary folder to your `PATH` to access kubectl: - -```bash -# OS X -export PATH=/platforms/darwin/amd64:$PATH - -# Linux -export PATH=/platforms/linux/amd64:$PATH -``` - -**Note**: gcloud also ships with `kubectl`, which by default is added to your path. -However the gcloud bundled kubectl version may be older than the one downloaded by the -get.k8s.io install script. We recommend you use the downloaded binary to avoid -potential issues with client/server version skew. - -### Getting started with your cluster - -#### Inspect your cluster - -Once `kubectl` is in your path, you can use it to look at your cluster. E.g., running: - -```console -$ kubectl get --all-namespaces services -``` - -should show a set of [services](../user-guide/services.md) that look something like this: - -```console -NAMESPACE NAME LABELS SELECTOR IP(S) PORT(S) -default kubernetes component=apiserver,provider=kubernetes 10.0.0.1 443/TCP -kube-system kube-dns k8s-app=kube-dns,kubernetes.io/cluster-service=true,kubernetes.io/name=KubeDNS k8s-app=kube-dns 10.0.0.10 53/UDP - 53/TCP -kube-system kube-ui k8s-app=kube-ui,kubernetes.io/cluster-service=true,kubernetes.io/name=KubeUI k8s-app=kube-ui 10.0.59.25 80/TCP -kube-system monitoring-grafana kubernetes.io/cluster-service=true,kubernetes.io/name=Grafana k8s-app=influxGrafana 10.0.41.246 80/TCP -kube-system monitoring-heapster kubernetes.io/cluster-service=true,kubernetes.io/name=Heapster k8s-app=heapster 10.0.59.48 80/TCP -kube-system monitoring-influxdb kubernetes.io/cluster-service=true,kubernetes.io/name=InfluxDB k8s-app=influxGrafana 10.0.210.156 8083/TCP - 8086/TCP -``` - -Similarly, you can take a look at the set of [pods](../user-guide/pods.md) that were created during cluster startup. -You can do this via the - -```console -$ kubectl get --all-namespaces pods -``` - -command. - -You'll see a list of pods that looks something like this (the name specifics will be different): - -```console -NAMESPACE NAME READY STATUS RESTARTS AGE -kube-system fluentd-cloud-logging-kubernetes-minion-63uo 1/1 Running 0 14m -kube-system fluentd-cloud-logging-kubernetes-minion-c1n9 1/1 Running 0 14m -kube-system fluentd-cloud-logging-kubernetes-minion-c4og 1/1 Running 0 14m -kube-system fluentd-cloud-logging-kubernetes-minion-ngua 1/1 Running 0 14m -kube-system kube-dns-v5-7ztia 3/3 Running 0 15m -kube-system kube-ui-v1-curt1 1/1 Running 0 15m -kube-system monitoring-heapster-v5-ex4u3 1/1 Running 1 15m -kube-system monitoring-influx-grafana-v1-piled 2/2 Running 0 15m -``` - -Some of the pods may take a few seconds to start up (during this time they'll show `Pending`), but check that they all show as `Running` after a short period. - -#### Run some examples - -Then, see [a simple nginx example](../../docs/user-guide/simple-nginx.md) to try out your new cluster. - -For more complete applications, please look in the [examples directory](../../examples/). The [guestbook example](../../examples/guestbook/) is a good "getting started" walkthrough. - -### Tearing down the cluster - -To remove/delete/teardown the cluster, use the `kube-down.sh` script. - -```bash -cd kubernetes -cluster/kube-down.sh -``` - -Likewise, the `kube-up.sh` in the same directory will bring it back up. You do not need to rerun the `curl` or `wget` command: everything needed to setup the Kubernetes cluster is now on your workstation. - -### Customizing - -The script above relies on Google Storage to stage the Kubernetes release. It -then will start (by default) a single master VM along with 4 worker VMs. You -can tweak some of these parameters by editing `kubernetes/cluster/gce/config-default.sh` -You can view a transcript of a successful cluster creation -[here](https://gist.github.com/satnam6502/fc689d1b46db9772adea). - -### Troubleshooting - -#### Project settings - -You need to have the Google Cloud Storage API, and the Google Cloud Storage -JSON API enabled. It is activated by default for new projects. Otherwise, it -can be done in the Google Cloud Console. See the [Google Cloud Storage JSON -API Overview](https://cloud.google.com/storage/docs/json_api/) for more -details. - -Also ensure that-- as listed in the [Prerequsites section](#prerequisites)-- you've enabled the `Compute Engine Instance Group Manager API`, and can start up a GCE VM from the command line as in the [GCE Quickstart](https://cloud.google.com/compute/docs/quickstart) instructions. - -#### Cluster initialization hang - -If the Kubernetes startup script hangs waiting for the API to be reachable, you can troubleshoot by SSHing into the master and node VMs and looking at logs such as `/var/log/startupscript.log`. - -**Once you fix the issue, you should run `kube-down.sh` to cleanup** after the partial cluster creation, before running `kube-up.sh` to try again. - -#### SSH - -If you're having trouble SSHing into your instances, ensure the GCE firewall -isn't blocking port 22 to your VMs. By default, this should work but if you -have edited firewall rules or created a new non-default network, you'll need to -expose it: `gcloud compute firewall-rules create default-ssh --network= ---description "SSH allowed from anywhere" --allow tcp:22` - -Additionally, your GCE SSH key must either have no passcode or you need to be -using `ssh-agent`. - -#### Networking - -The instances must be able to connect to each other using their private IP. The -script uses the "default" network which should have a firewall rule called -"default-allow-internal" which allows traffic on any port on the private IPs. -If this rule is missing from the default network or if you change the network -being used in `cluster/config-default.sh` create a new rule with the following -field values: - -* Source Ranges: `10.0.0.0/8` -* Allowed Protocols and Port: `tcp:1-65535;udp:1-65535;icmp` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/gce.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/juju.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/juju.md deleted file mode 100644 index 1fe1bee538bd..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/juju.md +++ /dev/null @@ -1,273 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    PLEASE NOTE: This document applies to the HEAD of the source tree

    - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/juju.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -Getting started with Juju -------------------------- - -[Juju](https://jujucharms.com/docs/stable/about-juju) makes it easy to deploy -Kubernetes by provisioning, installing and configuring all the systems in -the cluster. Once deployed the cluster can easily scale up with one command -to increase the cluster size. - - -**Table of Contents** - -- [Prerequisites](#prerequisites) - - [On Ubuntu](#on-ubuntu) - - [With Docker](#with-docker) -- [Launch Kubernetes cluster](#launch-kubernetes-cluster) -- [Exploring the cluster](#exploring-the-cluster) -- [Run some containers!](#run-some-containers) -- [Scale out cluster](#scale-out-cluster) -- [Launch the "k8petstore" example app](#launch-the-k8petstore-example-app) -- [Tear down cluster](#tear-down-cluster) -- [More Info](#more-info) - - [Cloud compatibility](#cloud-compatibility) - - -## Prerequisites - -> Note: If you're running kube-up, on Ubuntu - all of the dependencies -> will be handled for you. You may safely skip to the section: -> [Launch Kubernetes Cluster](#launch-kubernetes-cluster) - -### On Ubuntu - -[Install the Juju client](https://jujucharms.com/get-started) on your -local Ubuntu system: - - sudo add-apt-repository ppa:juju/stable - sudo apt-get update - sudo apt-get install juju-core juju-quickstart - - -### With Docker - -If you are not using Ubuntu or prefer the isolation of Docker, you may -run the following: - - mkdir ~/.juju - sudo docker run -v ~/.juju:/home/ubuntu/.juju -ti jujusolutions/jujubox:latest - -At this point from either path you will have access to the `juju -quickstart` command. - -To set up the credentials for your chosen cloud run: - - juju quickstart --constraints="mem=3.75G" -i - -> The `constraints` flag is optional, it changes the size of virtual machines -> that Juju will generate when it requests a new machine. Larger machines -> will run faster but cost more money than smaller machines. - -Follow the dialogue and choose `save` and `use`. Quickstart will now -bootstrap the juju root node and setup the juju web based user -interface. - - -## Launch Kubernetes cluster - -You will need to export the `KUBERNETES_PROVIDER` environment variable before -bringing up the cluster. - - export KUBERNETES_PROVIDER=juju - cluster/kube-up.sh - -If this is your first time running the `kube-up.sh` script, it will install -the required dependencies to get started with Juju, additionally it will -launch a curses based configuration utility allowing you to select your cloud -provider and enter the proper access credentials. - -Next it will deploy the kubernetes master, etcd, 2 nodes with flannel based -Software Defined Networking (SDN) so containers on different hosts can -communicate with each other. - - -## Exploring the cluster - -The `juju status` command provides information about each unit in the cluster: - - $ juju status --format=oneline - - docker/0: 52.4.92.78 (started) - - flannel-docker/0: 52.4.92.78 (started) - - kubernetes/0: 52.4.92.78 (started) - - docker/1: 52.6.104.142 (started) - - flannel-docker/1: 52.6.104.142 (started) - - kubernetes/1: 52.6.104.142 (started) - - etcd/0: 52.5.216.210 (started) 4001/tcp - - juju-gui/0: 52.5.205.174 (started) 80/tcp, 443/tcp - - kubernetes-master/0: 52.6.19.238 (started) 8080/tcp - -You can use `juju ssh` to access any of the units: - - juju ssh kubernetes-master/0 - - -## Run some containers! - -`kubectl` is available on the Kubernetes master node. We'll ssh in to -launch some containers, but one could use `kubectl` locally by setting -`KUBERNETES_MASTER` to point at the ip address of "kubernetes-master/0". - -No pods will be available before starting a container: - - kubectl get pods - NAME READY STATUS RESTARTS AGE - - kubectl get replicationcontrollers - CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS - -We'll follow the aws-coreos example. Create a pod manifest: `pod.json` - -```json -{ - "apiVersion": "v1", - "kind": "Pod", - "metadata": { - "name": "hello", - "labels": { - "name": "hello", - "environment": "testing" - } - }, - "spec": { - "containers": [{ - "name": "hello", - "image": "quay.io/kelseyhightower/hello", - "ports": [{ - "containerPort": 80, - "hostPort": 80 - }] - }] - } -} -``` - -Create the pod with kubectl: - - kubectl create -f pod.json - - -Get info on the pod: - - kubectl get pods - - -To test the hello app, we need to locate which node is hosting -the container. Better tooling for using Juju to introspect container -is in the works but we can use `juju run` and `juju status` to find -our hello app. - -Exit out of our ssh session and run: - - juju run --unit kubernetes/0 "docker ps -n=1" - ... - juju run --unit kubernetes/1 "docker ps -n=1" - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - 02beb61339d8 quay.io/kelseyhightower/hello:latest /hello About an hour ago Up About an hour k8s_hello.... - - -We see "kubernetes/1" has our container, we can open port 80: - - juju run --unit kubernetes/1 "open-port 80" - juju expose kubernetes - sudo apt-get install curl - curl $(juju status --format=oneline kubernetes/1 | cut -d' ' -f3) - -Finally delete the pod: - - juju ssh kubernetes-master/0 - kubectl delete pods hello - - -## Scale out cluster - -We can add node units like so: - - juju add-unit docker # creates unit docker/2, kubernetes/2, docker-flannel/2 - -## Launch the "k8petstore" example app - -The [k8petstore example](../../examples/k8petstore/) is available as a -[juju action](https://jujucharms.com/docs/devel/actions). - - juju action do kubernetes-master/0 - -> Note: this example includes curl statements to exercise the app, which -> automatically generates "petstore" transactions written to redis, and allows -> you to visualize the throughput in your browser. - -## Tear down cluster - - ./kube-down.sh - -or destroy your current Juju environment (using the `juju env` command): - - juju destroy-environment --force `juju env` - - -## More Info - -The Kubernetes charms and bundles can be found in the `kubernetes` project on -github.com: - - - [Bundle Repository](http://releases.k8s.io/HEAD/cluster/juju/bundles) - * [Kubernetes master charm](../../cluster/juju/charms/trusty/kubernetes-master/) - * [Kubernetes node charm](../../cluster/juju/charms/trusty/kubernetes/) - - [More about Juju](https://jujucharms.com) - - -### Cloud compatibility - -Juju runs natively against a variety of public cloud providers. Juju currently -works with [Amazon Web Service](https://jujucharms.com/docs/stable/config-aws), -[Windows Azure](https://jujucharms.com/docs/stable/config-azure), -[DigitalOcean](https://jujucharms.com/docs/stable/config-digitalocean), -[Google Compute Engine](https://jujucharms.com/docs/stable/config-gce), -[HP Public Cloud](https://jujucharms.com/docs/stable/config-hpcloud), -[Joyent](https://jujucharms.com/docs/stable/config-joyent), -[LXC](https://jujucharms.com/docs/stable/config-LXC), any -[OpenStack](https://jujucharms.com/docs/stable/config-openstack) deployment, -[Vagrant](https://jujucharms.com/docs/stable/config-vagrant), and -[Vmware vSphere](https://jujucharms.com/docs/stable/config-vmware). - -If you do not see your favorite cloud provider listed many clouds can be -configured for [manual provisioning](https://jujucharms.com/docs/stable/config-manual). - -The Kubernetes bundle has been tested on GCE and AWS and found to work with -version 1.0.0. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/juju.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/k8s-docker.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/k8s-docker.png deleted file mode 100644 index 6795e35e83d5bf1350903e1a0a0a0028b99ad6ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52545 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

    W5r- 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 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/k8s-singlenode-docker.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/k8s-singlenode-docker.png deleted file mode 100644 index 5ebf812682d27e325cabf532f6a67f7bd69cf86d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31801 zcmeFZRZv`A*RBnOBxs-s8r&_o2MrP+1WoYZ?!h5w6M}1ScXxN!;O;c;?$XF!Jn#E_ z$>Cpr?OnAGcGcp5S*sVb=bUTEb&r9+oQyas(iV$Ve#9-+V_T8RM0} zf|vJ~^pu11@uqSRef|LxM60C#r4?4(mrPF#6Zwai?lj^lx?Fdgyr|g5Vvrf)Q4z-( zB>uifb!m31W_s4>$ZfhFM()lFzTHj*){{L=1@myP?JLIX{?02nTy)r1DzL39hKBIs z*P?I}cTN0pak&!R6_nt(9%-N)G_#GQVwVw7ybqKGKJvpdB4iZnfk`V--_BEDr z*(k&Hr9smd$#|HJE1L1~>%>nm%$RXn16x#S=Kic=n0SZ&r*JR`k)1q^Hm?G2c#M-_ zoU)D91K|B7b+bX!u_hbay@t0Z6`yZ(S?D7>q*wf$J`JB&qJ%Kxc$Qd2i@{Q=TErQL z9~2QB9H>rh8sD_cE)ltZzUS}#4pls%+8<7SAC#=RWWHa>)PxOlNuicNSkWA%2vceC zLTF>9Q1*xf=JYvCB_#2T$j4msSLZ4UHFDtozPT-IiWwvQHWxI-%c`%%hvzD;{}8Ig zn~fs~CYQuwGZ5Rz&dHV%9T-4)6*H`Ve}(?I*2-ft_`Bn6VoEE{$_mw4_;W|+qIS}<-udE{y(U-nw@!-$YSqp%eG4(GO~j?RMA z+uUee6kcK*%KH6b>y{Y#Yk=j-r}t!^H!o2_^=&BA-{NH~d7HPvVT8T3OGRP_Gcv=y z)kY=oWc&6ELIUIMDS`eh`Wd4HoQV*8`FnvG;0UtJz&iXe{RT4u{yqXP+%&-u!34+%#I#&Ao{4nfHv^e1@bbK`gXOZ`E+?db0MEt|he+k`; zQ03y%{m4%fk>funw|i5Mpz-52_2mc&`-^*6H*ZiZ+_(Y$-1Rf_QuXvZxbQ z;!B*?`IV2g*aEL=+HqF!k73^a)M}4F5b8yEHu^yY0sll)I822C7DQ?mPL>ImCl(*} zDigmhSR&kd{n-oOG@V#n>~6d@U)7)$T_v3<-H*(Zv3jvepKvxg4bj=aH(pt~lV#Z| z)P;f$h@7B=V1`a5?NDv?(wMSmGdlac1h0Bp@m2}Gx!2-;WwqoehOa@J4r=h+>p)$h zI&o^GgJ2$cp|#l_>$;LQBY6;b5G{ogcehZ7A*#Wfd7+U;lTesbd_jMMu!V5%4QgkX z2j|M#k@=uIcYf8SEen}>-zZ5yB@=-u=|h2|KtUT<3H~B!N~S@@Pt`;k@%x>=xDBqV zkfv-gMGA=)CE71Rxkwr+OxceFV#2dBJRj?XoQ0f4vJ_BrEhkj+W9yUDWSd0YKDsf9 zN3g}5#jO1 zr=(bXdX%o8ZoIC)?vGWDE_uqvU*KOg7_xanJEdckS)^}-$FrQrYAdBH-_04!F%yb& zWkSazcDl}qx0}up4JZxNH)u8pHr{Mh^eMb(XV$)EQ^3m#iU?{53O!@rtQ%e%p64tv z(R^&Ajk=+;q;riTi!zLYjS9{Gq-ZsXIhmAikuN*JY)WOSV>)XJon$Ns9?ltdOdd|s zVt-t}^W812_y1mdYkJYK%fB1(CjL$H8@xA)Z(`WHIq>2wuD=I$7VHg$2TrA)((#x$-G0Kps7<#Soi&35Hea+XJ&yK>f zQcNmLS|##FX#(;oMJbsr;w|bPeXS!TbJ~IL6WVgq0@7M^l65jx^vLtW3r6WO)G~Ox zx%H~815O0i)Tv7SlO%sh2LG1+JTn3LqFp~+IgDbqX-vglz|qi?Ub>*FTKHiqm8XNR z*EPdA;f5ZWKTstw340M+>+QkY&kTESiB)M;pQ~6@?v~zm%yq__Y3RB2_?WKgRSab> zZdMiLF)TT>9JukuYm_cxH^?*$U%t8|gHl0RUh?}o`8K_}nz3`BY4CQN1nq6F)DE2l zt-Yjnp)MPj%vnlO9ikmV9m+sP!8yj6V8FE*wO*+uunA|>XAIJE`j$4KI3Km9ws$)q zJsrH|&}q@RIKw}CUkjy2lR^s@5A2D|iP(BGjI8MwQ=%NMTvGGvO83b0C`aI(fWJVn z!0Tp*<^ngSYn^+zdxzV_v+3il+i9pQJU4tH;x~?5!yS}D;^k( zErsp);kS5~*rd3$n2T79m{g3)Th)s74?$`{B-#Af#Q0b)6b?3dS7VD(zH9rdNNb0T zY+s`*_UCM>HuCz1i^H_qRITZV@QDeR&>#I@x94qqDn8e$bKHQRj%e_O{@UuM-wHm_ zxHh;8hmY|t_Z}6E>D2JolPs3Rl3at6eP6X~U#@iuUeAjRi_D;9%NxxbH1V#yt{fMp z)Cnl1*I?tPZer?S&tMj*?=zV^RD7K-G#dVi##Ys^AvWaU(}hG3MFQmyRpbiOa)^<* zK}w(e0BG}kJ$~J?pYZqDZ>T$mA%~;AQM1E?&s`hGq1mgVpHszO=j&t~HQMS|E}Hj3 zEl4aRW{>+n^amT@FIfgaCgfA)OPjTgD~>k1h3kanSDF}x)L)r*nPZtBEE-l6na;8fhZjubCz6m1Ng zrk~a{DDO8b>8M+4qnU*2hgP!YmN$JYF%_T8+0EPqzX^@sY}$3HIY^r8nV)W1vhWy( z4Sv@3Qh*4PpwXlEO3tk4y+xPK!b)Ms@Lu|EeT$KYmWSwp#7X$D_)qbyp7v1tN#2QR zu3WB2&i3G6-DPXmJy!S27a}gN3wGq#GU~43xk-6WR(r0AkCIXNW}O4v@^`53Q!cAV z)B@DfrWU6Bt1~%GTt2xh?RbtS5e^YD2qrwbo(EmV#aHwhNezb&VI?N;q&T{t3U~iJ z3G~PDeWz?EP+z$|mQ-9?4Cx2QlxUvR+2qYPLGKh}3XF<*G6 z_T5c(s*Wt0cD_~IN3RuyG(UISy48R(K`!gvHbNeg@Sg>~xIJWSc6roX;NNkB+>gG@ zL(>!-_|AQAe6P2^mQIZ%OP8E4Sad&mJ#CoRbiSWDtvy`fXB6sFE5h^`byFhS@q9RM znEpfMhh6a^@!_DGpvCWH=UvDBK{4ZNKU-)Ys;{C(3sT%2p-o1*zdMi3M)%?bKSFYw zd2XjJEw=Qx*T)@Ajdq8?_u5o52H_fYnfK~FBzL;IqJh?QlcxZrMML!1Ai%Nvh1k_W!`WSC)yeh^1 zrI+7@8k#UX<2+4dR$Rvjt-h?k>p7~qOf(y?cH2}tdKh;68f}Y2MgsSL`z2QmZ;E7b zGu!e2Whu@!^c5bbPeSnX{Pz+HM_}h{c03Dh;j7~}qnDr{LpS?6`0PNntPcYgg#Pbk zEC?4|d@^&18Bq0{0~Jj-!}bSsvhMx;9#UVr=-*2~D60)g|IX!T-DGwIT51%y4U}HQ5t+W!d1z{ zlcD-w*nSI1EgqxWukLP;YFzCz4YB@APzZhup|U~3TxDxvm{=o8Ns_jOXJ1e`+U9J6 z^UtbnW5OLUVxTo=+xf;;fQXzmZmM|HwJ@3f9GZjosf%K|Jg*>tjU=K`^!ayNJQ2RU z0z2UNNB#J~5Bhg*=-^#Sl5mx#D@}f!KVyaP@63@C%{eq5m=+h^=W$BZs#o!x??2XL zHxs;UuaN)J_~)T^Z^7w#RddBd(hc7-LJp*bcQnirU2Hy$yZf0tXZ(Gb!%~DseG+&@ zNV*$5ZXFxCGR`&s-5g*?NWen!qN^e5SXuGjhgstH-%9Gw5t{yI5rJbPK_Q2E!MTc$ zVdQ^~Mf>LqQ+`aPAuAJw790Bi&l&VY&?l9v{7HXu>tUzf^GKk%6x>j|7kUILQ9Jsx z*+THA=-ce!*Q0{(+@<2}_olXXni&KCdI$w*3)Y>MzHfpc)tc9>srd}*UU2Kq3R%->*oTNo1X&qFIiJVkZ)YO83cVP6s~J4q+= z@fh(GD3>^pe+W7@p?}}IU_Y&4x!xPzJSt$a^vISv{gk+8N!%^~JVX^|wKe>1*}_+HHZG_18;Fz^B>Os{;PrQduFgveyC# z!-9{EYxaxw(;J0J9_zz=XF;;iwwJ`~pXQ?j{kXhw;L^#Td71AO)m$pFv$NOw61&eZ zXf|>eeVqGtwdmL&89`<6HG#`2IpLkXsoJfLTZP?@f``_QS@lcLD~QW*4r!6sf6oPG zf>2J8W%5bI>SKs)*~(^t)l{MCVb!#zZNpKsi|*LGWy7HT&RAEG)>2tPrIypmbH}5m ztNMPXmIaHlE^L1b6SMV!IJU*Ro3lkp>ZJ9+H}C9nUG~d*7U)YFS6}h&mwq`xc~o0o z7<+xS8pw1j1wCviq0IAJtJ_N6d&PI$8tGZ=CzJR3Ki0uOHg#N7cQ(RI@8#u;9@^Dz zLCL#DCrPr=Mu}*~y!x6Y_xYxW+r5XeWS7GohZ!B;O#Q=+7%d0e%>nDGsw&GAw@d4J zi<%@^U!2hI0|~y`9eVzr$j?k_r!vIRQkELQnQi@D-)IbM+`5DCESFosmL*M>NP)+Y zaze)i7Oa-X2PkyUuSbqT0N6FlacM651oLwLH9k!L^B+RQ?X7&gyIBnPw->gN((3I( z{9iK;{A5+UFMLc+Y{(K35fsMMgeF?fhIoq|k08y-a$oR=Nkx3FtNE@LY%OaR9c+1z z8Y>Kjxi62FmKfA3dxMGi=UkN7F!cRPU1aBLuYSBh{rE{T!T6;cnZ`_v(~H9<#FMWE z-Df*Z|Lm5K0fzCzk@ETj;q@67p{8Do0LS4&#dmur{-QjX_r77y%ixy_s9XzSq^9Vh z-mhi2+X8==zIr$zw(bPsoeZostcCC@2$QJSv*>l#7L+v41!jE{fSmLY9~HcpLr2## zN_NgBzP$jA67wZYYq}KiZYA2fV!~O^l`NqWM(*X< z=Jnh%!J_&%9mdM_@(;B7y^$fMA_Iycjy7+ znd_`U%m$`^C9(iYlWZI-rDF6XNbpy*L#OYe$yreiB>s}89@xIcT=|TzZf;FXJ}yRA z+;3x`gGQ^->XwpcYV%tZp9*aMvCrUL(o`P*B)gK6?@89(c$y2HIHjf9&riTO);UQI zea56@u+|?0#uTv0z@%%XZyP^5y#XO-c6{z^2Z<6{`{8fika8nB%{y7GG@cEe>6*2B zBWm`BJ%)+AvffJZXvT?+4k5Rt2ALsbAu}~HH?Hrg)mUo8D~G}RanFg*BRK5{K=;`k zx6^#Tr}gq!!{1&{sas`<;#)gGRqni&sR(s@8ol3MBSMA0&-qPb>mU|n3Z;PjO4&$1 zy~CCFW$B6V^+g8}m%Ic!{ickm-5JlJ4k&kO;-fHcJn4Qo3$xP9MHKC%{v_dX(uD(k z7%@by40X+@yC~#DamE=*}p_tM(mi5<=)ILKDpAE(0t**LEmXWG^n~ ztpsbntq7-tmiNjozdJ%iAjVcC5g2~A_x31l^_{iT$YJA|Ov=y$i3CkTo&AZ96+Dw0 zs;}X1F7`K5hRs=sIPgR|*T*XlKezfGfpCj*F`-XR(!(WEojfGu_5m;LeQMc<%*s zLAH;0APwfQG6?)Cp9QXhb#Ca3Yuih_a`>rKK$oSIAr7rXoKEo_p1u0-K`Dp=BEZUU zFNX&&Z84V&{l^p0B>-N58lvTsaMH}e1sV>0E=qoOYK}X;deAHA?v4MreDZLji_1ZD zY&V$1J58E>42OYEF)RQz_o*4yLU|wwLhz$KokO+`JZ8}`Ql;Ud9bvi^7hG%Gq>P8r z&&4D4m3V*0%rqogGHG-MIuT%Z*Tpze_v&ukE zbdFa9bskPIgY!GD#XMFI%C5hPZ)&pYhx(4s^o%EH%e-MVREg6zIW9lNL-M_^BeKG` zMF-V?LxFaSz~38KNBzeS2-#zVN$jsf-EVhtpx85|M7p5|*650UVQ7MP%o#uL*u>>Z z(SPt*Tn12gnt5-xjeD2kGi!Txs2f7EooLz?u^mAw10spm+qri-Y7VbyF7D_6T?$oCphUv#t8NBX`3@fYVYVCWHjz;=& zC=S`gmfH>1;<_VIxUuq+Nb2xOs~dG}&2-D`agJHg9gReCO}uhT>C_?=jk-I3i zPzuHz`1JgAkR>-}IYK4|zuBk3mQWIX;&XPIY*(CA!m-eI;w3u%UM;>{(K^CpOB!c{ zi{_Am49d!^s!Kkx`2}HPNBfZ(ChbR^rI`4iS#O|+NxTKS`1|R~KiA|E#X9RKcLw9m z=_BBQ+7{}~VL>M9<0Jy;{EaGKytqQN&V+;vk*QG7@%^%=;1ksGkcypnB7?Wi(|n0e ziF)K}ZH5x1;n{6bIvkkILRf3JNIg?oCbSq_KF*B>rzq7))dKSKvo(v z0{!#J;@O~9xDqmvO&w+?x^o>EW{GK7S`h^ZRe)x0^5uX!HR(Cdp!bAI#Yt*%{}M zinwSA;Xq}59YVPK$;%e&ux)b#BjmYX<7 zCEkoF_(tJvj@SKnPhQgmNZjo$@m}JH^xbokzB{HOi@x?HL`rsALN_%3I9N)fNyZm~ zGCj9BOhp7@DD*N2N1lg}yg`4Bz$Hv0N*i$+8`Hxh(&+cx`&lvrJn}&WYBA`e6RWMi z=v>>exhqFe3E#B{9tv`W6Io)Yv1DvaZ?f;eB%5r!Mn=+GIvsoh_*VvHe!k~^pXVTB zLU`u)?VN(gLZzS{9%MC|=}u}QL2umTxl2s{h0mSNuJmcg$s?~05!;h@o)Np9hqw4r z5$y0@#k()NWxEYH1_z2Z2CW+%(p|+3KS#s(CYo5ms!3Lsl|q*F6n%o}$i7`JN-+}O z?@pr=mq1uoYA`VRN;WrQMkrukg1CtdJZ(UJ`j!+HO*;$<3SxYzB)c3d}Q-{ z&XtRV(Y-aU_&#P*?7t~zE)AU6Yk#?fbA=`kMa=j1AO56lbYVg6n|1NvXKvP z82%RUx%+?eayfq>JEA`+&X@f&_Wy4C|GgkU_Wx*d7SG9%(s@$-I&uKkpVXd?a^#Q<6vF0SEw8$~|K_6k>zo?4(4@q_gaI5t zDmO3B|K7F8+*d{Qk@7`ZgYNlm6_M96Q_@_GCj{;2y8rdKGZvHrW%UGqAG9{Ga0o z3z`wq&R5?N(=~cF+8#C3{48JV&r$jq1_Z*05KIoqKV$Enf@7m4*vY?e3#9~*Ou$nL>b2lEIa0%7XgwuE%5zc7yx zfO+=!c~fuydbi*aB`BhorR5|3K)cimU~IGY+4NW2VBU?$&o-GOlz$dB_Y)i?1I9}f z+~w7haB}hbC#XZ?xR#fbYy$ujEBRdo%D>j{BfP0p9?MDfTb0t*gYtgH!{ZLLs~Bu1 z&3$xBaU$nT-rMbrCeMN*h8@PvhRmzKK8X$gQBwyMkF`_7{bqwU78MoMav+xFFgwB0 zM%}#Zr(ibYuIQg76;0JZh-{Pyy22P<0rL7~!{Ouu%a(fw$A_D(hJ)&P#whcf(~ZLi z=#eA9G2%n#%}SaUp7Qzc=iA{Q^{69RoKN+Aeap34+z(^*LahD9zJe@Asf_vhD9^F{(#}%PW`c0E)!3c`2QOCDOQ)8XSBnzP|?HpsPzrTldTr=0{dZqHbFYHXY4k7vsgPBj->wQM-p z#9OT+XGR(16XW~tv|~6JzXAEa$G~MV$9@I4`dc#ropU1q18J6)AsCLPiyh7yrPvR6 z07&XtQ)vY&1HU-@svn4aA(6*+AyYD9p&5F($Hb&jKLMa3YlzGBVZ%{9knKYTQv{ci zoL2oIYyO@n&xE5dMPYoTx$3Ix0=yt8o07n$CYU0L<*Z9j`&apbwLYy(g47 z<;`WbMWmQEH!q4_Pl$BY@GZLL^naq(f9Pc-9Jo9oA{KQHAanOw9j|!blK=iE{i3*o-rJ2fu0%qp`WgV*MEpS-36z%&7*P!e$EiY^Xu+*;^CR4+4& zNN3thbZd#)<91}*$ke|ahMXpRpArRY<0tJ4*0xSk+m~x#9)I}Pj)nR%A903_j>JQW z4!X7{m9-9<{0SJ$%YRcnM4qlwveUi$51$1zj7VN^d18bg^>H`8m7N>(QhE?gKQ|UV zMOGpa6;VB&&|#(x?OD%HGR^nyK1To_AW^3)-FW4~LG-N^_HfRuM7p4(dcgUxZcAau zp6t)@*^o)y7bPPS?VS5XDYcN~2#Gs|u;7$=JU)axrzj+;ZvD8CVAVYP*hn0xf{^hc z*yiHm!bE)neRzr!h2d&v+_%OAmWg5-J)1i5n^%R7;iYzALBSca;oFcP6yJ*P?<6a; zu?o5VG6`OQNuUro9}&r0vVu6R1uq`2bP&!Dm9p5^f;dE)&;+hiwVcXMs=Olc!Y%b z3NR5+))^n)X@DdULfI|rHlj~-|EBsMlZ7OQCG|_%n9Z9mrXFzQ(S0S)9%EB_A$~Or zHd3Y;yU2{StybV4t;o-S6+Kx8za%V=I=CIM`Pf4rY5#H!rcdJ1 zV3CseUt`~ZAm?X=!pA=!&3yw5DcTlH%KsUoNdz3+N@3(*T2;OeFf_SfYX9Yr(MF;M zd>J==)*oLA&L;(iIBL`g{|fK^&reOrqVD`W_{MCZC#8fwW;6dO0zibX-XEWIvlY7X zrVr>77vf|lCe^?Jk5S2mT$a2QCF{0c9WcmpyPA9l1QK3|5;WLBebkYt=6Fn5*kA=J zIhm)s(w)&?UKQB>xSftVZBm{GEJ8VYY)vj?P~&R}2>jO7My&tEW_pGhncOXW-{eEo zPl?L;P$2@A%$TN0Ad5;3Lil7)-z4!igDU3hXM<-_htaw3$>e~*rOHFCR$=5ok?hZ+ z=Q08tF=^j2ss3k-#!pBUl?!KroDv8Zj5)y1Jeu3L?ssDvYI#3gnA`L8{o@TbL|e_5 zrV<>i9q%)93J%m{ijHcl`yytn%@xZLA}L_md``OWZEoYgOlUneLky&1K4!jt`WrOl zaI@xfca(ddn^dl6zjNKiXZvn^(Z@;w&dtf7@^pc3YoElU4#}Xz918{WhAirex<@l7 z8y$Ht**~`N3u2+wfEDz^Vi{e=O}~;j9#*1H!UZXiV3RPP-VRW&sVA$hB_}ow6%`L# zqG&mLB+Xm71UGzX6BpIM1P4%j8<~u&KGL%My7MM|X;Y<)s^OsF(7(!ZA$;yyE4ee^ zPA&H{Sy)Qzk)}m2Ejq2ve&i$sI#b&gEpVQ58!3M3STeO$B1-$uTsje4o6A{pgfi=x z2275ti*-6A&I{3|vdot_LOEmyY0HYMTx{1R%^fr8@@Jwyz_0XdFg2HkvM;wa!x29F#h`HTpiW&b{_RGE|6b$OvQ{C^Rs+$$?sglU&y~$?>$n#%ORBAiug@qhdV{c>hk*+WuWV zMUb|9Up*>zkTaKL;FmdMiD65Q1I5U`C;1c132L31d@0irQt76V-+69QTPIB{X@CtL zBh&tH;VI5YaGO>vY zr!Ogf3OR*b(7AW22i#trMe$zb;MZBIV#<+LAN3mJCz+PIol9Br5PpH1$$Y+(5aQ)IEaQv1xHxZb55$SOP z8`2}<=)C(v$9$DJT=*?=m0R^*$KKhra^XRQg!v#ft8DVgT2I4gS$+;#It^^_CFQr? z;;O^Vh%HrszhkH(*D!3H;nYBfgBykm=etUKwXoZi%Q@( zQw=Qg?pieyW^i5n)x@I`By=%X&*fV^7E1j@@yXnmHD?a0BupW=3+`c=T~ge{$fMT zT9@mdfZJ{DQvfvI^-q>CB~zL;Bfn3}i3^qDsjAv}w1l`rEv_~btm>sXXFCr7-Lu)1 zo}6zr*mWz(aiJCbY*EwYAWB{)HrjSKr|2m&>5p>U8OsX6x&Mh(o$TO!p8}}MF83GH zZXVjWni*Os8R}Xc4kIt%EIgUq*0ElkD!ef0p7q|b)5Hb8)Er_Q8Ss%;Fotp-X{-ro zBsYHKsdW2UmCE`#%fl>iqNggsb@l?Et=kQRSeq3pu&eaA!E{)$bU$RjX!m)V4MXiR ze+SYu$)JmS-u;$k9G=eO@o?7O&f#y_zb!7XO<^kRkKx<9 zXb#+4tihSgi5lmPN3J!!G@m}6HL}z=S0lp1(;Veu-7wgf=i;V2lTz&u){12{2zX>Y z>uS8+Ex3QZz)-WWI_zxPaCh3@G)e{ld={tmaPjQs^=U1SCfWX?RLU&KGWghY)o zWOz0(nb29h-+oy^mQ{_Qk`CaKJQ7RoKv;k6a1vmf)uY{AQo(cZ8GrNaQv=OeeUw%A z6eMQe`jFbHVOWWQ_P60}Z#>E4;RYi06TQ=tbfUQF zQcdecHBy2PuJC|%i-hlB=Vzz8lb)R2??4JpczF(N)5YaCAR)cdMZ|v-Aj%i)&1{t) zwhgbtq1%aI_&j=@nWg>!fKB@Fu;*mcy1at@! z$zPN$AsE0D+LM}s`qI8p9EhOtuR~jG+0!qAtz3W504ZWmUEb%McZtu_ENV_^0w16I z9RgW#Rwr|^Wa8_4=+)K53jb4S$|B$&Hh$*t;2MfQo}v4e#^8*STTQ0a7WFCjT5}ma zhJz{Qd%XB6%tG&6N>JvFFI3;SXi4_WN#KMIPN$WKoguiXY%h$t`rCdz!q-^aK%%8S zU0%^yznG-yPgB3Eu+fxua| zRqm-!z%s`88b8BSOWT`Lw%Xj{2YC56u88+&TdrEGu{I2|E)tm>9enj7pA9TF?!a;! z>?@B=I%SYnp{bqLu4)9mWMxt(WE(-z`63)At!cPhGk-ROB*GIkO!d0Nj|B?->jN0qH!{u z<`HJJ8h;?r@3WDG``Up}HrkLrOJivo-fJhgeWYj00)>lSJ{e2$hN4TrzZqBRlc+e$!-{ z9`rSWIOoHISf-PWckMxcIQzkv%cE7(Jn3+HTP2FYxlb^2_okT@dnmf>>IhI=m#!FC zbVV@~%;$ebCac?+crgkWjpcEdp^k%B%se3~>xnOBEB8?IsCjtuJfR-6cxH73CXE&J zX!Z!`r11e$YbKN3q#Lp64n*kq-HwQ$Nh6BVKg$Rt72=*FAVLwstu$>3i|Hej7^?u?H42WL40AG=I zeo5?cXWfH-4wMR{ObKjKVxZg9iR%7B1*)MU+*)E?a05C4H_BPWfFS4PKXbf_XOy^d zoZmiNeC7eZB%>3&I~I9td5M|MUzVrB|m_yGMowU zlt`HU)!)PS`L~8yG}O-$7x&NUpOL6}F+kZ}NFUGLFI}x%OCfGXzNgjE2%T0Iwx0G) z`XMRq^^LFQoVL*7Tr1Hv_LSW}uBUHLdSVd|y7s3_goPpFud0etoZ2NfMvycDKW1%%|IKCyI8oh|j z1GU;)Y-RY-*>#}gJEb(AmbFE@0Iz%hB2??jxcww1o#``EwUl3wv^rcztJAXx;a}i@ z96iP$FNDZvus#w>MHY6xn#!?$wGY=s{kmW()Dj+v4h=hE3i*4(G}EB3kxl=IQI7G>6@z z$4%*d2DiWKu!WxnY#h#qtf9e-*Z`VSe`%3&(?OA2RrV61P`Zv0oz}g+a|-WD7LF3# zSeY#ba?b-ji=Fpt%9xQS6KRVWVq~^xs+kyQvf{R-3;sdX=HKk^gsvdtzcQALGhDt-?|CL0+UT^(AxqwYj6^mv z3;+EC{%>983dANS=y%bI4@y=}sqV{Jw}tA<=GYdX(Xm!xoP_!DvBr-}4sd?L`^2kg z_`QLo@|)dT6YOTR z8-Lw&>Q`5Ht<7c!X=l7Y*}F_$`3{F{uxc{<$`}3J8)Gi|EY>~9i6lHlEWk1 zB9nghd~t`NZ1OhnfM6?fEEy{oDXZwFc+ z<@u}TTJsC`q@&o0)5U6=0yh^W8b?+h^A?2n-iw=~bd{Ire(bO(J}iw-1s0+krK$tU z`Yv8y!Ay?;V!Dsvu_RGt@b&%Gdi)+J0!djW{7#5Rl}7X&w2cDCl{m705jahZ)JxrM zzCM7!s1|>W&_sIn<8g|wX&pLk=4g`pU|7uvV?W(oYk0NPwJ*E_hipS94s-uv?Cu5}5DygU%wiJGEK?wnJk zUxXNoohBa~P!^G=B^`*`$;iUqC&$doIK#(nj$4iN-am;K zx?gec#jEsC{__=4qpNNJ(F%jeUFiW%a^;9i^n_lcuOFQfk)CZFMrQ{%XAIAe>iF23 z2&cu;l9@vwm*FY#=nJL&ryMd9Cd-1-fsjUvQ7Km0iuG0b5#KDIa041at&JAnuFZ$54V zTBh!Anif7Rj*H7d?$j^qW}-vatcJ|pb6>6X-!y&}UELkLwT~5AH`L}+0eAZpn`8I; z%<$a@zu};>_{HfJ?v@|B94xP!3-b)D;tIsT_e82d4P!`4i+LWi^XYmemOU;z3i^u> zyMZ*F(6`A0EPX)aVGfs4)XT808DBFb9q9hf^jeV1?SkcJU2<#Dy=3=9aaU-3C@!_a z!qp5JJaRJg{u^)?{fsbnl}c+t58dWd&DrX#&kO6$Ku@c@zf>m@;v3o? zI5;HUKna5`4k8IrlKBaASrUGWjKSB`GUo+VCx@i3K(Tf3WH%tcNFL5z{4;n}+F&8W znMF8}(@NAf0<>?!pIG^m>>$6WORtn(Uu)oEv&XxHTS+ zTD{nH+e2KR&)-`co^E(_wF!n^9XZM>jzOxe3Z%<&qp*;6N`1H9b%#Xl$zTkPMl_&c^wia*X0%R|!(u1m){548Bnv9~_76qV<^3v=he9G3foIp>7R z5(!9><9ANV5~f)I1ENudV*vTtwKx8dd~tRMRo+^lqV|^a6G9o^`wE{Q4)Zw*0Y!wq zk_jA*AZj{f04;Vl4|cgNYIoqG{X$Z0WfiC%FRE+pT)+w1W`^_QXLD!B%j9q_yrTe{ zOxppV_M1Dog_3Q>a~V=wvaZ4nczvkaP~ix{O^+WEgX9i?((*%E_s)inG0vEC)Oc5GdolGApTyR~>^K$2{~>70Rho399! zfAIMe_9#&X3gw_91XG~;wOAc}puAUj?=qcs`ULn$h{3f*fi1%^Em_m}=~^y%=KyHl zaa6f~4fYedK2s=q&PuaVBgxXv@%$isWKJzg_K8!g$!dSEBnG5|O~e+yi{2Kib<+Z& z_W)KaN+H_70ke`YH?}TuO7Hf`FXh`Cy)uKS5BQYu-qP~tF$6r7`Gcd;uQl<_my(|~ z)Ta=SH->Kd83&eCjka%@mb+p2Gu%|t79m8^f-@Pa> zgC(vCehWqK94J))IFS?GuUhUC%1oJ-pz;w>iek#-Zs;KaznDE86)yi;6j5}=E9O$*ke-KGDOt;$Klm%3@_eeBs^3B4*gt3E0oFMr&0 zqbxI))&lS*D#r#0%u1o{6K-MVfIq^K@iHS_>s9P|&$*WJtRr;54i68D^hpAu{M5Rs z|9EknIn{yFE%L*+JU~aFTGNyLGl-WVuM%{O0TlpM-?e zuZR?gqI>5AQ=k_dMi+Dde*pxG*ts4G7S(0N>G~fj z%TGx0saIilzGUbxv6~fK9v{JNCEt{=t3-7rTJ|(QY0sk);dzAK7uCTjHh}QaFIv3v-D`|JA3W@T7LoISL>ARb2vf_=l_fZ@o{BQ+>IS#UmJc zeP&PTE%P)1V_Gl+)Xsj1V5BK)Hd26$1V1+vj1b8MwyE?mAjMz_d2PfE2-9pUC)^hY z&^E=>jg{ZBA_SQ8mHsG2AL9V^h<1sv>fd58;N5)Z4~$WRm8*bl{O={#2Nc{$-5lmx z{23dOgzqz5`AE&8@aIOXPs^<-CC5$kr&1h;hiu>L4i&_cefj*c?$VT}pRC0{S3E*2 zdeGVR-qLhVy1+yFC}8TPy;!hRyQs(d6kX3I?Lo$f;40K$%T6XGL;bjuieT1N%zs{v zETL4=+qCMHY4$(?Z`}pMB!{j1pzH@d=ZyJ6N9hl)RbqfbGEb=NQIOmkz!7}-a@r`M zi92>A%+LjnI#dIByr+N6<>>$cAz+$N<*mP&d7<^*6qnkU?vr}zDZrFuq@YJh3|t%2 z2*cAwc>31~yTmZuw=y|eXZSkWzD`!#+hj5!$|h~{)=jgEk^$bj3WQ}1JH`f~^W~r)Wf_K%k^Edtn<6X7hDc~Zy4*EUfA0!-_(!?>PPXJzGaHVXUUj=# zVa<203Wn?+Uf!rx{H{H#Om1$h!7jAjf;7yfNYPXymaziwV!2Qr#Ln^5TYzKK%0}eYHF6?i%^iYbm9&H&~fs!9#aHD6M_}-8$b-< zBMz^9!vGKe1E>fWqDE&Pk1lu8M; z@qg;hS?mobzpon25N`l#6tbh*@HeHNu&Th|Q>BJC;%kDAHTXFp)ylY59(x}!D}$i@ zqD?i$06YMt6Gkupxg5$HXsd&00eKm*U2!uYf0kLpjI3|a!>5Z|jLficH5)Eq#l zZ_TL@TwiG(Oyn7_@D!o-0bu^&Vg+Zlf!Br0Ba`!JKak>T3P|YRM4*$t5^yE7HPFAfSA9{r=FgWv}Z^IvnU~ z(8_&0(1%&@#Vt@wbG}mz`EI7QRnvS?#I7Tz%C+QL0Wi?}g(u_~3{(~MyCqFX;{kmi z)#R^W?EsPg`-vW0*lnzB9neKo|I`-t)c>Wq@Ptb>X+{N3Ph`DV5fXicBkmgZ%L9j( zO0)!14ijyMBsZ?&(gmLis(A0u$K9OIjh;%1N;_WJu5|}jQ22}AvN-Ik__m6ik7d(- z&c41{U(^fbR|o=WF5q~_KcAC=(qsVbR3Y`m&g-C;{U+nts;nN55{^K3+>KqS=kMZ% z!`&m)3k7W5@Ye9FZVUkgxmy{6n>wy_G-9~z;itxr=BuWo8=IZav_7L(nfOv{?v)&T zHPz}1sSN6dNWD41hQa9}U1Y6}j)wY7rB+B}+VBt1!t5mMeYfJZ#hk12>Qb|q{WHA* z#!Wh3vzHdJ9`}Iac_^4-K1W2Ym2A@hDSt%Sm}&k(~k>J_>R0i*{b9bvscHS6 z%CIp>>YKZl#IB`GG38X!@$17N5xCHB=eMh>> z)#2fo6jPOc^Khn!IRNH5lArG&I7xz9C#*-saBjFm8i`r;{XAs(nL8p7MRv&qgLWKo zqX9O0SiAPhW4QOT>B^ANbauR*P2~u@i1_t!#KqxOsNoyt;)v*B4GT@x$2`g{#dWejHx=vqC_RG-In7meVJmE0 z@{_B)Tch3TGxs%$U1zdA=J-BePLxOyy&E#>A8^+^n|X89xqmKS`}Ke($1JY0FYm&6 z&UAj7QNNRY_)CgW63aWRgWj*z z3Fxr;e3H2Etpl}KJahn+r=;=pKB0w1nq;?h~QfeOR~wA5_AL zK?W;@6+<@oR*hv>Gaw@fSECvB_VA+P(m|I(^K+I;UVV2!Ca7itKSgaogkXYm`B7@9q*%MbiO^O0 zOc$pjBAUB020P|}TL2>v5Q*rEM5c)0VMLPr*cwICW=h!^c&HH5n=a@6S950-6-T>9 zY0^M|;E>?%L4pLQkpvGA0t9!5;O-VYxRc-n4GxWK(BKwaI=H(u)-XlRf6keitGSt3 zvlbUn-Bf>4{Z-Yw_p@sdy#Nr?`VIheZW*z5n0LXQU0Z`!oG!?|Aq6IDiWgJQis8@Tz;CowV&PFj}9sL&xH`2UY78&KvOFZhVWH)IC=Kv z0s;bO{9_hCi*%3^_6gb8ds1F$s&cIh{hIXGompE<afyRNE+5v{+L32lR$b9*5*WmR&(TuouuSXkr%!h%*wavoh z=HbY(P_K#x*Wn6qVBXvY{xqV{ugQ?q)l$9f3tbS z8Eqd2$|8{-US9cZwQGl6=XU#h%;KXufa490G!(k>J!wVjp*t(~7hG z9f@P3GP-Uv_Nru?{U~Kt$%Fc)VE+T(8Lmf+LUz=FsY*?)+{uQx!9dAesF(P{^DnK# zUNa4fDSV>bp{+c(M7^qO9tWYK*ZmvUf+Ab&*cfogR*Ejv#pUoUcsOlybC9ro8Av<0 zz0AEKND*(dQR66WQfc{BderQ^vl{h6v5<%yEIAZxHEKW;$f!kH*OSn**bt4udpAfX z3QlFiWJu?jU$M7W7Wj=Us^`w+k=u7=JVtza$V58~mTw7lXOo9ah}>HqBj7wG;xLcv zfcM`1GNSC}j;uz;|0R!NaWpDbCn&^x|5KC)n@6ROmvnPU9!%@>*3E*h%jtEVp-#?0 zZHvdG+t;=G(;a=?E^VH}8lJ2MQ!7!YsH!ZBo$36vw9|IC4YnV`_@$pLzBviNj_jHh z+pZdfBWzQuH+@N#ps)0!2IgxeH>h#0M~*ekU)f&ieo}g)v}*r~UF8!|@ygGWPIUHj z>`3{*H&k3HgkEn9JfFI(I+#Si*1OO1Z-9g<*C_UpIYp9!-7D*tW2H;<_*HIYKnT3m6fl2KlT>E;xF; zk{J{wZ;5s{Nsut2W_?-syz8^#jMq^%aYr7nh|`HwG_o(0w7oN!v@4!5QjRP0N@KxmkpoB7}|&RXx>Bl<A+#Lv`Bj8N1koG28s%Knpz=0uA`~38bcVf{G(72Ro-6tirinV5nrY_yOVnS zG0}=ZlUT(~nI&w?dPWl~k&UzPd{cdURvi>hnE z*XC!s$8=cazuQMJ4`)0TR~LWL^0S}P)j`Nk*}}l#KBqj~D}tSoh1zx8hN(eGC1GC< z>Y>YpW>9c9-44f(M`toqj|Vmhx(H4N5)z3X55eoylOBs|_n<-}0=Lu;-8DSEckXsY z!)vJ;vH@|BfSeBm4OC(BR};P=9vU1*A@e~mjYcEEaMST;K1+ZqsQfl2hj#O(a`zjX zA&#v3c50tVgaeLcqNGKHI*qDT4J5x>?(VI;RmMd36xp zaw~`(a~>r9!~36L6VaT6as*Fc5uuy*)m^7Rd^bwMBgNvF*$(+7s9KDixoIaiyq;3ISMEXUiUYfsLs!r3pqcB1z0w4K&^8`KuN zc4H_uvYK_+b0PJ2TZb6BcS^}0Bi#aykb-XGS=$j@l~Q+lay_23#9=Z@^wQa$B2M*C z0U;tY2{cR2bcTT|r}X4P-%F!Y~wRSTb<$&K-Kbyja%O8Ub;(@Hqq! z>9Ooy-yAH>@It4eW(}k@@=ojX&lX!0mmU1zea*guX)b$vx}%4rjg;PSi89+|d#8fw z3g@GTG7r++w}-@+kw;jxAdDr~pbr=eKi%TXN-ObC#K_JF}>=`OztYky53VgWRFM#dk+0XYmG?0 z*SFK$5xEC{%Z|snB$?%*=JoqH^QzXi!%XN(U5DfTeiZhOX;V6t2N^pQOvd@86BY40 zQx4{@Z&e-WvwWXDuC9D>`U0KgD9S5ak)${}%c{Kd?!&}{@c6HVTx?eAhRvrGIHt z*LsN)ExU@lMq2lCAkSvsCY62c$Q|0RV&RLVO|3l;bRhGIeWqq9jgBD<@}Ve>Qpq;+ z{W5+-%$-v|4Et$7+HhKYMa~M%?~0a>b>dY&2=uF zPitMv#*E_)(reZgU>9s|gMxllW7Q>`BG5y+K+<8j|94!)Z=pPj9fR zmxv>(4^SI{MDSLtq*#fp+3AY=lzah1mo}7_7OC5(^k^fAx1a`G%>&rQ!Zr z!vyOUOL788MgCZdYgbGQd^&_{b`vTrc8c)J?0V>|rzWOILMQ%kPyfMlUNIrWh2w2k zpdbjJTJGBYRuglWo46oDgF|r}h?OpzkE_t+7Sx%CQB>+uyU~!khYV}WNV1)^#CtCatWC)Ez@mph` zac|_w+n7TR6hh9BUtNQJOi#u8O0Qy2LQ2shV`B-F>Nk?LJy$Hn2iI$DT#1Oq#&G*S zVoHHmX%P&`Au$=xa8eRSw-I(usJM=1L7!)Qr@lDL-ll13k(WgHd%Q^SB)_-bo~8BT z*B*)=yyX|3hyUypXt#tD2&qXmQm{BSH0s!e%(H>W6{u3Eht>H!5?aEOz?MRk3Cb-a zZNXs>`!?>}h#p(k(zSGdeiK}xcKgo5C#)mJj8D?O+xQr}p`LPFAS%+da|9zubZcrR zPj9|c>AgK_KdR`fuco1N%9FKvk`qppcVO)&>7^k|o>eEFl`0pN64%rvqNOSLMGPQqV>?ZkdvSySfQ~sMTWIrsNnL8 z7y(Fl_tWC;&3Z7sW_81%QYH`E5I*}}IOnk9;)#`~zBeeW;)A~?I?hK2rJmcXyPpjl z=+LciGgcQ=SE*SRPA}M&qh${&tuTc97K~^1W$yC?rd@UWcIjg6UYv=laW_4kd-NT7M9_CEw{7E<=V&!{nXINYL`aB2KtJWNtE#Lk|2<8fA>Z4kmBYq ze3G#TnC9f>VsWJ4Uw=0qb)|?WV2xt`cA!;fCJeI`U$u}?zA5|;H5_5YktQD-WDs+ty0|mg{hD7;sZeO%WtP$|JGcJDvQwwFj%8~u@ND&5L(c6DG z{-Z4;8P;wMI*x~yU(S?!u)_OL;s=CnkA|+BWp@SyUOo6FIv!@szXGXB`R61eelOh6 zp_ZMc?+G@w7qB$VrrSulA9d;Y7m)b$O+Z3M_FN<*W#2WE5D4}Oo;?k9&F)h=7DBO#e*))?6=^<@E?g{^GK0&h{rZgPA zD5SYm4t1NfW|1el<5~I zMv6U(cs*1dF!dZ8BooAiUd2X9K*UHafwQ2;UFBygV2uJ)E;&0g(2Y}i1L)T2!J89p zTR?G&7;V$w8S!l@OcQNRBjqqDBRv&n%Vi>f8O<0&H;iT$=5GKc>afOV^3xEz8uDO* z)`IZ{Al7bkgNS5qMclM#2P%z>8Avrk_$oRWL}7!6w&RQCwl&MTi(%-m3Duu#M8+p^ z{G*gLZkf@^UEP=b?eLf(&{81`8`oy+4<9B=4i(|McsobHwY@EXtP;LQrSeHE`#RMa&~>zC)efLB0^f8LS_-8ZcC?g z;}Z*<+TLw@$)nN9%h7YIXS(&?u8?!rA%d)$Z3M3 z|BrW>;f>E|yY($7H{VvIE??(ef3m1{%T)S7Q_sTxVe9+*6zx3~bLkKBj1{OafZLk* zK`WA_S={E!Pm}MDRm>}#Rm{trZP*H9d0C?VX0-q`D0%=QmOY@E0W_89R;Ev#j#ing z>+^u*U3xjF##-;P_dBS=!PF}@9ZU9jX6gTmu)u;NVT8OS?;`o%ZSxUgNsDi>^yBwGHl_mz;*-nSqxs+splLnkT;RDuKS_6yB66VIA0+dl?rAqVjtK6zrc@VG02Nb{f6q>L)8c|a`rdCp6K0G zel*IWb`P>wn1ObifmN^;&%mVyFjnF{Vbgh;->hV6V`))TjaAb8*p4v}s5*|#KR=KB zEx^-@SN<4#i@NBN;xw4D_5SOT=iy=#^W$kCUzRG%M!RKJVDl48n3(xv%#-|$s-9cB z??@C;oG#P*ud9G=rivxI1e|e-WI!ppy>`zS-7o`wZO#iFBzo&s(R^Ti>?ci`Cl@LP z<>BJ~oWfg&gZa(DEbrCDacLp9PPCB>&reP*BY%6ZjGFEo@6;6{z~||F6Uap&g+wDh zEFSXlo!wN7BYk!-%ZBF`bM}(3C%@a($_SuPEZ$u!kl&nTWsvfZHNIf^7Rk6Q1+0HS zYq&wE9dWc7%@=B0L_8}wUpu(d+1u<7S0mDv_bLG2@)Hj{p@g+H`%7_r#0+zXb@Z}E=#3!VVyi}(&BxsMu5atZAcs?cZ;UwRg!9qX0@C~O5 z=DK|O**fa2d5f1xn>1?sWomuEz~P|=ElXhXFd`^_EPUJ*_xX=m)FAN@^UUJLuwF@N z;DoSCh2x3O^IL};)}rJ2GEU=_+mFtL{@5B|Cszt;FkmOucpP@QA>V3fCW7Bnec-*N zYx~C_k>M|+N)RmOw-wD_H8QNFbF>(8VE;wAg83!$e=HM4E^6;gs{@i88Ear`$7_3w zH0nnLlA>JMA3Tr-#vdupZvOY_jisj|oV!XS0c@A9w!5Verq<#QAiOVZ%~jO_Y-_6J z#qC@lc`J2}bmiuC|5sR4x|x*)n3F{E0FQ{>rNv(=*3hl$Juyb!S-_*>x~lMDiU#0^ z{&7_Jy!qc96?$~ZN(pl1#nl1yZgRh=aG8Lsgn3cmi?Myl9QV&6@Hpj!zzJx#3A$VM z-)+w&fNuzu{JZ}tgknk(*wl1b@5%CSmjx9F8JDRfm<9PlCj9Y0{?|`-1}Yg4wn$8m z3HK~(-aj6Io~hDsu1&MN1T=&1E`9+YIe z^QAW(Gaax{D9?oI*L3ojTw}(3^|Q5a={zrveBn$Jr}2hQMHe^VEt<~F!qj2D$MEzK zBlKW1dX7c&swXS=0cN+i*u6D#^TXHWlOmtJ+_2Wm#O4WrM0}pofg(5Eta7BGYM<}m zMQC=nlIa56rO!0aQSvUlpMX-#{e1J{6AC?Em!kiOWcFJ$dG}9Iw{TKSO)prr4Zx*=ae8XSQk_eI`T3hltO`1>5sbb8&K^-?+apChx z;FfJwS1C;b7?-;}0QuJE*MzQ4j9d@zLcj?lhZ}8o`QIS?uVW=BxP61YHgh)(zd?ck zTOshhlBBbr3$$9K+}iZ*V1o!Wc2mv_VL1*Z)s5Y}W6S6be|He=Eavqn_QQaz0%x&) z=ITT=1Beza&YDl>aSt+$<=eo9whcjUy{P2~u~1x%2K$^xjxjW;;Rf@=jW(kk_g z*(<%AnOa@B!Xxr=yzuVmY%L?xXyVtsm?Ydql4ai>Gf_E>r6Nw594v7(S|FSk&I{87 z!EZT=OOKm`l^F9?(jS2cz?3lh81s-Zhcu;&1Pay7VqKpv`DDEa%T-F?kZ-Q6mi|D8 z*VU}Mu{D^&?gnVlDP7r*n)V?e)Rj2WY|Oy(SxA>o+I8lrG5f^cp}L}Ky#Ur@AWi8J zY8jk?RKy>V6e{v9)>f5 z*?8wXHty%lL-RrzwK0yPKvo9~2tQ~9YS`1cF08bm9`B|Dyi&t!i(&@4*_5Eg^|oh2Ft4S$&J9w+mlOe15C`dI-`n-PUqI?Y4o6Z=Ihy6@(t>?AgK{ zMj_XeknQ@1>A@vuWo*LKs?Q`}_#@G~-ItJGe3S}jR;J_98DODEP2e)<@P}*zGJd13 z+tQQ`5ba@gSc2PBGbQTmkDR7gS^#E*=pW_jzmAvCsPF~Znr0wlA!5OK zQbD)f7hd`;axL+tinlgkMcLmw0+3F{EEDzqp)QsU?WTM9t=BDay$yu)HsavB=&V!0 z*mJx{QkS1WO;=fBX?pG}!Ee8O_=ZR2?=$cGonhfpf0D~)QoVh#$7Z>?H>%CNHjN^m z91qSfR);e`#n}7taHOh+NZ0{Q21Z-f}->~P@3P2+MHArJ@^Y?D)FA6ju=M^^gc?wA|m%F zT~hOpF`kb|^b!zovCIVZJ{x{i(N7L4n>?D9ff0h^A0QLz{2|PK^aEi9##H%TOsThW ze#eUBwdpI0A{Uxgm-E^j`nooHQ7DK?)~+~NF#B-vy};1G>y#(3{^;_Nj~^CgG(EZA z))2U!Na}P6dV(!NP~LX)iJc_%eH>dla1`C&cDuA?Nt3%IrU|*(s#SHta10xKyCx1F zSz^B!O7G*J)~e6xDbn8Du7RFa5S_UHLTwTKgITS>7On1 zMC|apMegoo!ks3~X7i|*Cm1emPBu&^%Z7u=N^bCD2oVrt;tX@1K5^)qWHcHN zB2g>=;!PU8cJfnN5FpNhDA<=2Umjy_wl=VzS_9e8nh#ZZcv6f2<(Eb|&(q}u(2!mM ze1MSSHmzyiNFnTbbxH`puM|G#N^ZZXL-VR9_3l>;J2;Ywbc3ifLG%4894mPV?@ym* z`nf(!lBKf!WJ*=sz5AynF>?KU zXVOwxOAKKHFC1(iYzU+gANCOHI|HL{0)*500XVV>Xq=|_yAFt!S}vLO1iP&l*(*Tf zt%ZXG|7sjPxseS(TEmuT$&H?Ay8sDDdHa}zSst6j^#H>{5VW#iGx{F?Y@JlZyTQ-D z05j;32DO2VOJNB`xWxkDvo}Dlwnxrm%JNO9?*vevcFaDZ&Z4ck!U=IQ zY{}4Wy=;q*{%ZUo>31{Ohm-mOfV=aR@n8Tn*9ZvfGkwFE!V6viExHnvD7FqVvVRO^ zPEyyC75<9v2l#*p>2PEt#$E^f@(M983cV>#0b-1>-B*a7Nvs0L?MKnlAs5iX)Ul$? z?;<73r)l@UDm^4rPx>NNEq;r{sDVRQ?6S(;(j>dsg39;??LbUc-Ru*L!4HR1H{1d4 zzw6`uCfG~sQ@3QrGZ;9kYXhkV+&jFI*bER?srAWE&NHr;=VPv3AJH7VSzqCipu(%< zbjMSmy7{$@ovCJx)m20A=fyLLmcZBMBl2FsEhz>VdaSs#_ZhjnZHfGx7YXs#~&utzzZR3H+S8weDRL`0IO9Pq1;eTE*Gj>^ z#8Dj~IhK2&bLl|#?pQ8YG{E=AQ08K>b0lW47<3Uu<-D(HmvzdYyM3{#mRXC^oXWzn zHE~G1LnQD`)X%q^wMi`mX?2wi;*?W(60kj!cO%u#P+QOj7=7o@Lsz)=U7PtDe@Frk za5C=x@QNmuQ4WK_NrR~TPx$QS#qmdS!q1n>;P?X%x1yO{tk$Tx-O56p5Yy*BLObB> zPrb$^mfCE3wb=1EW6ho)36-Rvocd9I`W8_q;>bGB^J>xY9d^C=L%F4ci1-t~)sO~% zR!P}Tw}h7jmj-=ZDZ*E#RtVzdsG<@mP?$HijyL-pnm>>nOV{cFt)5bPcLJdl>J#Te zm#y@}Ab$<}>M_BKq>xtSV0KiB-6AdVT3tvx8yphSHHK$bGS^`Zd)3eTEtI?THMnrp zj6GbDnO45yY=XX$isVH&iuHm^AI!e_DY`Prw*so0yd|2c*N>4Mzc89YzvJQ}(d2mP zM&178+gmI`+$E#v8KOxV_z=^b7BHF){C2%DlyDJxF4kh2MN-f8uG-qAMtE7~_G%L&TO&(?Nk07ZL>I zKlK4m5}@Z1Wn|^cmnod!rQdiI-l;Ql@?;WA3sZ5R)kwl(h#nm21CJF zhy6n-dNV?q{^9uztr6|!<|q{LUG5?FUmyCoN%o(DVy?sF2RTp7ggf*&%`4fcOVb>S zfVygngoKD|EQ;YKdC0QpMD=m30WXfWYzGU;)7`Kce7zZu4ZN$XvtEEjQKXC_D0z-| zC@Lq4hfoM;jI0!fuP94SIh^I?&FIPSv%5NIuv>zMlvZ}|W0nAi!=dEY;r5?@s^_De ziBv<9W%?*S4M`gvRZfRIK8B%U^?TIsQCE`R_^(6^2g8Br@|&g;M`b>I$XB`Uw(vSQ zl42jm9>+|GBgeA**k=0F$g?TQ4v8G{u4P4c=Ib3Hd6n(!(*l&sw+Sq|xTvY>u|5x# zh%K`TNj7br{u$I9FfNGI{(c7yMHV>*Mf&-@vGl<5KcIde=0 zZgZg*$mxRP{)4sU0kxnlOZ)GdUQvlq?1|*UZ_zIV7Kii#tOI^-jUhSs@y$wQ~!!K~dlg!4ue?Rukk%diB@{7b~QRNn~VutnM zz@114+boQQY_+GT^5KQ{%a-fSv}GKdcKBtnFn(8B)CUthUhQQAdl|wkSZ6{B@id2B zol}Ub^{UW;Jaa+|M!*@Jf}e)$FEBZ2G}d5&EpJDUQ^%sjo|{~#c51@ZL|f3on8yxY zDp=5`i2nXuez1#iOFwghdp$le8iL~8N~3_P%d*$8ieXJq5;&Lq)a&Olhr>!bn4pmA z7m-WHQ$uZ>WQGnjhK^bVHBI*z#RQ6LHFj~9edc!sJBZ2dGO-th1`r>3<57J#Ks}Of=y(zU9BL0 z(Ck*muSY3Z*j{^X!@X1kJ?7+DR&=94m~`4Y*)nU}T`&=X1kqZYw4OZ9$LpCauYoygH_GV>B`%IPXqm{bW`MdKqWh38}}@GuSNhaLM|S z5A|(Jmr5wF;`u9xUOo#}Km&R9bY7^&s&$y4`d}(;7`)#saCMbgU2}zJw@>>k`+7}# zGSoW1bxR}6XY}$Rz|-R;Km@Vz+GCYG0qP4!zgvc~|s2dEm(KM~NVAzyR%W z4W%=?23>iCR8+HVYA~49^T!B*S}%dT;+;4vjkZ+JBc~-6heicIEqj9{9L8<8BI>w> zYD4dl!fNH*C#B-@gY)BhXVRyZxZN7mb(-VadtGHvoO7dsiKi?yViV5vsD6mO#7m_J zZ%7V7Y+HsLsMmR4a@fq+rDa}c-z_nJ{Y1NGm-U&3f_NaxZd9dvS5@@|UV}^5V&}9o zyfbcTY0}OV%krU5Nvn2(By(UALPX!zU)K;OCXHKJ%;OMar0kO>(e6U|bda>y!MA@U zNt80qcOU^38K`p^gMx|LRI3yW(fbpy`$hBz;oO<*?d5+v<%PraJG06z7x}cCa5+l2 zIyBAE_H4Dy$v2^;Z)OKYZB)nF1MdJI$lL$O5g=Y+^-U3VrD$v_)R~MO~!60a{mn9AB(@9S1;_PWXm( zOu+3&J7MM!@P=n1W0lTPI-t5g3HUIJJT3s-+UG_8%bs!$vk z;IT>BMMzrA>sU=q{S4(Alid0aTV)AbTJ?~{T-PQf%=N zy|qIBPHyv)$tUd^L;Zc8i(&i*+|P*h`>Q|^@TQ_9^14> zPuRqw{AkV!Qyy5ZFiiaPlc<8gC)`Tq;H<1{HaZ(v7M02mB|YEk}PB&^xU$DALCsT z!wiR80EOHR(_6!rQpViKU%*d>Mh@3}SQ;yzj%FQ|NsDUoI$azUhNM7~yG{t9VrXhw zlk{T#9TuRss}>MJ1`fr5ngncdj|Nm6DlvaCxsJZ4Y~(gbfB!-V$OFAKn&{N#eFFNs zC7Yg#uFe^P3%nBn*cAUP=*DPb_`pm9^Wg!_YeGwlH$W3T5mvFs@x<$op|75T0dqjn zt$tYSmF4wSz}AK5>%`Cqgn$On1)R(c8E&pOydMBRh?4okhP>-_&2~#xQ-MQ$a=zD> z@pB0d@G>+`b!UsxS8VrzI+AzZbcuu5`tXgw+PFzpErIH2iDW#gGC7(k~Wy z=#q1PXA|X!ZOZ)9m0!$2*ECt|mi|3GA^x$m9pe)Jd6|mNtgOWa|DT?c0F#F(jsMTw zQI+_|rq-TLEBy0r3slr_OfrRk@2V7d^Ynl=-@j*?nu?Csp8MZ3UHuF-{D1l2j)?a< zFHzoCgos8R{^wn&=g*n0tt0m|sU51wr%jLdF3ey=#xyr{{~8HY9QRhSVXKOxl^qsB zAim7c^<)or?aE1Z@PN+tPdlD~R8SNBuhwq2vQ#2%*4LJF{8Ft4`p--v|h@lJ6zT-x_@WAArgsDgXcg diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/kibana-logs.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/kibana-logs.png deleted file mode 100644 index 15b2f6759b3e0e4d3c1b18bc0328e9992e640040..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183775 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 - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/libvirt-coreos.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started with libvirt CoreOS ------------------------------------ - -**Table of Contents** - -- [Highlights](#highlights) -- [Prerequisites](#prerequisites) -- [Setup](#setup) -- [Interacting with your Kubernetes cluster with the `kube-*` scripts.](#interacting-with-your-kubernetes-cluster-with-the-kube--scripts) -- [Troubleshooting](#troubleshooting) - - [!!! Cannot find kubernetes-server-linux-amd64.tar.gz](#-cannot-find-kubernetes-server-linux-amd64targz) - - [Can't find virsh in PATH, please fix and retry.](#cant-find-virsh-in-path-please-fix-and-retry) - - [error: Failed to connect socket to '/var/run/libvirt/libvirt-sock': No such file or directory](#error-failed-to-connect-socket-to-varrunlibvirtlibvirt-sock-no-such-file-or-directory) - - [error: Failed to connect socket to '/var/run/libvirt/libvirt-sock': Permission denied](#error-failed-to-connect-socket-to-varrunlibvirtlibvirt-sock-permission-denied) - - [error: Out of memory initializing network (virsh net-create...)](#error-out-of-memory-initializing-network-virsh-net-create) - -### Highlights - -* Super-fast cluster boot-up (few seconds instead of several minutes for vagrant) -* Reduced disk usage thanks to [COW](https://en.wikibooks.org/wiki/QEMU/Images#Copy_on_write) -* Reduced memory footprint thanks to [KSM](https://www.kernel.org/doc/Documentation/vm/ksm.txt) - -### Prerequisites - -1. Install [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) -2. Install [ebtables](http://ebtables.netfilter.org/) -3. Install [qemu](http://wiki.qemu.org/Main_Page) -4. Install [libvirt](http://libvirt.org/) -5. Enable and start the libvirt daemon, e.g: - * ``systemctl enable libvirtd`` - * ``systemctl start libvirtd`` -6. [Grant libvirt access to your user¹](https://libvirt.org/aclpolkit.html) -7. Check that your $HOME is accessible to the qemu user² - -#### ¹ Depending on your distribution, libvirt access may be denied by default or may require a password at each access. - -You can test it with the following command: - -```sh -virsh -c qemu:///system pool-list -``` - -If you have access error messages, please read https://libvirt.org/acl.html and https://libvirt.org/aclpolkit.html . - -In short, if your libvirt has been compiled with Polkit support (ex: Arch, Fedora 21), you can create `/etc/polkit-1/rules.d/50-org.libvirt.unix.manage.rules` as follows to grant full access to libvirt to `$USER` - -```sh -sudo /bin/sh -c "cat - > /etc/polkit-1/rules.d/50-org.libvirt.unix.manage.rules" << EOF -polkit.addRule(function(action, subject) { - if (action.id == "org.libvirt.unix.manage" && - subject.user == "$USER") { - return polkit.Result.YES; - polkit.log("action=" + action); - polkit.log("subject=" + subject); - } -}); -EOF -``` - -If your libvirt has not been compiled with Polkit (ex: Ubuntu 14.04.1 LTS), check the permissions on the libvirt unix socket: - -```console -$ ls -l /var/run/libvirt/libvirt-sock -srwxrwx--- 1 root libvirtd 0 févr. 12 16:03 /var/run/libvirt/libvirt-sock - -$ usermod -a -G libvirtd $USER -# $USER needs to logout/login to have the new group be taken into account -``` - -(Replace `$USER` with your login name) - -#### ² Qemu will run with a specific user. It must have access to the VMs drives - -All the disk drive resources needed by the VM (CoreOS disk image, Kubernetes binaries, cloud-init files, etc.) are put inside `./cluster/libvirt-coreos/libvirt_storage_pool`. - -As we’re using the `qemu:///system` instance of libvirt, qemu will run with a specific `user:group` distinct from your user. It is configured in `/etc/libvirt/qemu.conf`. That qemu user must have access to that libvirt storage pool. - -If your `$HOME` is world readable, everything is fine. If your $HOME is private, `cluster/kube-up.sh` will fail with an error message like: - -```console -error: Cannot access storage file '$HOME/.../kubernetes/cluster/libvirt-coreos/libvirt_storage_pool/kubernetes_master.img' (as uid:99, gid:78): Permission denied -``` - -In order to fix that issue, you have several possibilities: -* set `POOL_PATH` inside `cluster/libvirt-coreos/config-default.sh` to a directory: - * backed by a filesystem with a lot of free disk space - * writable by your user; - * accessible by the qemu user. -* Grant the qemu user access to the storage pool. - -On Arch: - -```sh -setfacl -m g:kvm:--x ~ -``` - -### Setup - -By default, the libvirt-coreos setup will create a single Kubernetes master and 3 Kubernetes nodes. Because the VM drives use Copy-on-Write and because of memory ballooning and KSM, there is a lot of resource over-allocation. - -To start your local cluster, open a shell and run: - -```sh -cd kubernetes - -export KUBERNETES_PROVIDER=libvirt-coreos -cluster/kube-up.sh -``` - -The `KUBERNETES_PROVIDER` environment variable tells all of the various cluster management scripts which variant to use. If you forget to set this, the assumption is you are running on Google Compute Engine. - -The `NUM_MINIONS` environment variable may be set to specify the number of nodes to start. If it is not set, the number of nodes defaults to 3. - -The `KUBE_PUSH` environment variable may be set to specify which Kubernetes binaries must be deployed on the cluster. Its possible values are: - -* `release` (default if `KUBE_PUSH` is not set) will deploy the binaries of `_output/release-tars/kubernetes-server-….tar.gz`. This is built with `make release` or `make release-skip-tests`. -* `local` will deploy the binaries of `_output/local/go/bin`. These are built with `make`. - -You can check that your machines are there and running with: - -```console -$ virsh -c qemu:///system list - Id Name State ----------------------------------------------------- - 15 kubernetes_master running - 16 kubernetes_minion-01 running - 17 kubernetes_minion-02 running - 18 kubernetes_minion-03 running - ``` - -You can check that the Kubernetes cluster is working with: - -```console -$ kubectl get nodes -NAME LABELS STATUS -192.168.10.2 Ready -192.168.10.3 Ready -192.168.10.4 Ready -``` - -The VMs are running [CoreOS](https://coreos.com/). -Your ssh keys have already been pushed to the VM. (It looks for ~/.ssh/id_*.pub) -The user to use to connect to the VM is `core`. -The IP to connect to the master is 192.168.10.1. -The IPs to connect to the nodes are 192.168.10.2 and onwards. - -Connect to `kubernetes_master`: - -```sh -ssh core@192.168.10.1 -``` - -Connect to `kubernetes_minion-01`: - -```sh -ssh core@192.168.10.2 -``` - -### Interacting with your Kubernetes cluster with the `kube-*` scripts. - -All of the following commands assume you have set `KUBERNETES_PROVIDER` appropriately: - -```sh -export KUBERNETES_PROVIDER=libvirt-coreos -``` - -Bring up a libvirt-CoreOS cluster of 5 nodes - -```sh -NUM_MINIONS=5 cluster/kube-up.sh -``` - -Destroy the libvirt-CoreOS cluster - -```sh -cluster/kube-down.sh -``` - -Update the libvirt-CoreOS cluster with a new Kubernetes release produced by `make release` or `make release-skip-tests`: - -```sh -cluster/kube-push.sh -``` - -Update the libvirt-CoreOS cluster with the locally built Kubernetes binaries produced by `make`: - -```sh -KUBE_PUSH=local cluster/kube-push.sh -``` - -Interact with the cluster - -```sh -kubectl ... -``` - -### Troubleshooting - -#### !!! Cannot find kubernetes-server-linux-amd64.tar.gz - -Build the release tarballs: - -```sh -make release -``` - -#### Can't find virsh in PATH, please fix and retry. - -Install libvirt - -On Arch: - -```sh -pacman -S qemu libvirt -``` - -On Ubuntu 14.04.1: - -```sh -aptitude install qemu-system-x86 libvirt-bin -``` - -On Fedora 21: - -```sh -yum install qemu libvirt -``` - -#### error: Failed to connect socket to '/var/run/libvirt/libvirt-sock': No such file or directory - -Start the libvirt daemon - -On Arch: - -```sh -systemctl start libvirtd -``` - -On Ubuntu 14.04.1: - -```sh -service libvirt-bin start -``` - -#### error: Failed to connect socket to '/var/run/libvirt/libvirt-sock': Permission denied - -Fix libvirt access permission (Remember to adapt `$USER`) - -On Arch and Fedora 21: - -```sh -cat > /etc/polkit-1/rules.d/50-org.libvirt.unix.manage.rules < -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/locally.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started locally ------------------------ - -**Table of Contents** - -- [Requirements](#requirements) - - [Linux](#linux) - - [Docker](#docker) - - [etcd](#etcd) - - [go](#go) -- [Starting the cluster](#starting-the-cluster) -- [Running a container](#running-a-container) -- [Running a user defined pod](#running-a-user-defined-pod) -- [Troubleshooting](#troubleshooting) - - [I cannot reach service IPs on the network.](#i-cannot-reach-service-ips-on-the-network) - - [I cannot create a replication controller with replica size greater than 1! What gives?](#i-cannot-create-a-replication-controller-with-replica-size-greater-than-1--what-gives) - - [I changed Kubernetes code, how do I run it?](#i-changed-kubernetes-code-how-do-i-run-it) - - [kubectl claims to start a container but `get pods` and `docker ps` don't show it.](#kubectl-claims-to-start-a-container-but-get-pods-and-docker-ps-dont-show-it) - - [The pods fail to connect to the services by host names](#the-pods-fail-to-connect-to-the-services-by-host-names) - -### Requirements - -#### Linux - -Not running Linux? Consider running Linux in a local virtual machine with [Vagrant](vagrant.md), or on a cloud provider like [Google Compute Engine](gce.md) - -#### Docker - -At least [Docker](https://docs.docker.com/installation/#installation) -1.3+. Ensure the Docker daemon is running and can be contacted (try `docker -ps`). Some of the Kubernetes components need to run as root, which normally -works fine with docker. - -#### etcd - -You need an [etcd](https://github.com/coreos/etcd/releases) in your path, please make sure it is installed and in your ``$PATH``. - -#### go - -You need [go](https://golang.org/doc/install) at least 1.3+ in your path, please make sure it is installed and in your ``$PATH``. - -### Starting the cluster - -In a separate tab of your terminal, run the following (since one needs sudo access to start/stop Kubernetes daemons, it is easier to run the entire script as root): - -```sh -cd kubernetes -hack/local-up-cluster.sh -``` - -This will build and start a lightweight local cluster, consisting of a master -and a single node. Type Control-C to shut it down. - -You can use the cluster/kubectl.sh script to interact with the local cluster. hack/local-up-cluster.sh will -print the commands to run to point kubectl at the local cluster. - - -### Running a container - -Your cluster is running, and you want to start running containers! - -You can now use any of the cluster/kubectl.sh commands to interact with your local setup. - -```sh -cluster/kubectl.sh get pods -cluster/kubectl.sh get services -cluster/kubectl.sh get replicationcontrollers -cluster/kubectl.sh run my-nginx --image=nginx --replicas=2 --port=80 - - -## begin wait for provision to complete, you can monitor the docker pull by opening a new terminal - sudo docker images - ## you should see it pulling the nginx image, once the above command returns it - sudo docker ps - ## you should see your container running! - exit -## end wait - -## introspect Kubernetes! -cluster/kubectl.sh get pods -cluster/kubectl.sh get services -cluster/kubectl.sh get replicationcontrollers -``` - - -### Running a user defined pod - -Note the difference between a [container](../user-guide/containers.md) -and a [pod](../user-guide/pods.md). Since you only asked for the former, Kubernetes will create a wrapper pod for you. -However you cannot view the nginx start page on localhost. To verify that nginx is running you need to run `curl` within the docker container (try `docker exec`). - -You can control the specifications of a pod via a user defined manifest, and reach nginx through your browser on the port specified therein: - -```sh -cluster/kubectl.sh create -f docs/user-guide/pod.yaml -``` - -Congratulations! - -### Troubleshooting - -#### I cannot reach service IPs on the network. - -Some firewall software that uses iptables may not interact well with -kubernetes. If you have trouble around networking, try disabling any -firewall or other iptables-using systems, first. Also, you can check -if SELinux is blocking anything by running a command such as `journalctl --since yesterday | grep avc`. - -By default the IP range for service cluster IPs is 10.0.*.* - depending on your -docker installation, this may conflict with IPs for containers. If you find -containers running with IPs in this range, edit hack/local-cluster-up.sh and -change the service-cluster-ip-range flag to something else. - -#### I cannot create a replication controller with replica size greater than 1! What gives? - -You are running a single node setup. This has the limitation of only supporting a single replica of a given pod. If you are interested in running with larger replica sizes, we encourage you to try the local vagrant setup or one of the cloud providers. - -#### I changed Kubernetes code, how do I run it? - -```sh -cd kubernetes -hack/build-go.sh -hack/local-up-cluster.sh -``` - -#### kubectl claims to start a container but `get pods` and `docker ps` don't show it. - -One or more of the KUbernetes daemons might've crashed. Tail the logs of each in /tmp. - -#### The pods fail to connect to the services by host names - -The local-up-cluster.sh script doesn't start a DNS service. Similar situation can be found [here](https://k8s.io/kubernetes/issues/6667). You can start a manually. Related documents can be found [here](../../cluster/addons/dns/#how-do-i-configure-it) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/locally.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/logging-elasticsearch.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/logging-elasticsearch.md deleted file mode 100644 index 8ae7f17b92e5..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/logging-elasticsearch.md +++ /dev/null @@ -1,268 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/logging-elasticsearch.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Cluster Level Logging with Elasticsearch and Kibana - -On the Google Compute Engine (GCE) platform the default cluster level logging support targets -[Google Cloud Logging](https://cloud.google.com/logging/docs/) as described at the [Logging](logging.md) getting -started page. Here we describe how to set up a cluster to ingest logs into Elasticsearch and view them using Kibana as an -alternative to Google Cloud Logging. - -To use Elasticsearch and Kibana for cluster logging you should set the following environment variable as shown below: - -```console -KUBE_LOGGING_DESTINATION=elasticsearch -``` - -You should also ensure that `KUBE_ENABLE_NODE_LOGGING=true` (which is the default for the GCE platform). - -Now when you create a cluster a message will indicate that the Fluentd node-level log collectors -will target Elasticsearch: - -```console -$ cluster/kube-up.sh -... -Project: kubernetes-satnam -Zone: us-central1-b -... calling kube-up -Project: kubernetes-satnam -Zone: us-central1-b -+++ Staging server tars to Google Storage: gs://kubernetes-staging-e6d0e81793/devel -+++ kubernetes-server-linux-amd64.tar.gz uploaded (sha1 = 6987c098277871b6d69623141276924ab687f89d) -+++ kubernetes-salt.tar.gz uploaded (sha1 = bdfc83ed6b60fa9e3bff9004b542cfc643464cd0) -Looking for already existing resources -Starting master and configuring firewalls -Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/zones/us-central1-b/disks/kubernetes-master-pd]. -NAME ZONE SIZE_GB TYPE STATUS -kubernetes-master-pd us-central1-b 20 pd-ssd READY -Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/regions/us-central1/addresses/kubernetes-master-ip]. -+++ Logging using Fluentd to elasticsearch -``` - -The node level Fluentd collector pods and the Elasticsearech pods used to ingest cluster logs and the pod for the Kibana -viewer should be running in the kube-system namespace soon after the cluster comes to life. - -```console -$ kubectl get pods --namespace=kube-system -NAME READY REASON RESTARTS AGE -elasticsearch-logging-v1-78nog 1/1 Running 0 2h -elasticsearch-logging-v1-nj2nb 1/1 Running 0 2h -fluentd-elasticsearch-kubernetes-minion-5oq0 1/1 Running 0 2h -fluentd-elasticsearch-kubernetes-minion-6896 1/1 Running 0 2h -fluentd-elasticsearch-kubernetes-minion-l1ds 1/1 Running 0 2h -fluentd-elasticsearch-kubernetes-minion-lz9j 1/1 Running 0 2h -kibana-logging-v1-bhpo8 1/1 Running 0 2h -kube-dns-v3-7r1l9 3/3 Running 0 2h -monitoring-heapster-v4-yl332 1/1 Running 1 2h -monitoring-influx-grafana-v1-o79xf 2/2 Running 0 2h -``` - -Here we see that for a four node cluster there is a `fluent-elasticsearch` pod running which gathers -the Docker container logs and sends them to Elasticsearch. The Fluentd collector communicates to -a Kubernetes service that maps requests to specific Elasticsearch pods. Similarly, Kibana can also be -accessed via a Kubernetes service definition. - - -```console -$ kubectl get services --namespace=kube-system -NAME LABELS SELECTOR IP(S) PORT(S) -elasticsearch-logging k8s-app=elasticsearch-logging,kubernetes.io/cluster-service=true,kubernetes.io/name=Elasticsearch k8s-app=elasticsearch-logging 10.0.222.57 9200/TCP -kibana-logging k8s-app=kibana-logging,kubernetes.io/cluster-service=true,kubernetes.io/name=Kibana k8s-app=kibana-logging 10.0.193.226 5601/TCP -kube-dns k8s-app=kube-dns,kubernetes.io/cluster-service=true,kubernetes.io/name=KubeDNS k8s-app=kube-dns 10.0.0.10 53/UDP - 53/TCP -kubernetes component=apiserver,provider=kubernetes 10.0.0.1 443/TCP -monitoring-grafana kubernetes.io/cluster-service=true,kubernetes.io/name=Grafana k8s-app=influxGrafana 10.0.167.139 80/TCP -monitoring-heapster kubernetes.io/cluster-service=true,kubernetes.io/name=Heapster k8s-app=heapster 10.0.208.221 80/TCP -monitoring-influxdb kubernetes.io/cluster-service=true,kubernetes.io/name=InfluxDB k8s-app=influxGrafana 10.0.188.57 8083/TCP -``` - -By default two Elasticsearch replicas are created and one Kibana replica is created. - -```console -$ kubectl get rc --namespace=kube-system -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -elasticsearch-logging-v1 elasticsearch-logging gcr.io/google_containers/elasticsearch:1.4 k8s-app=elasticsearch-logging,version=v1 2 -kibana-logging-v1 kibana-logging gcr.io/google_containers/kibana:1.3 k8s-app=kibana-logging,version=v1 1 -kube-dns-v3 etcd gcr.io/google_containers/etcd:2.0.9 k8s-app=kube-dns,version=v3 1 - kube2sky gcr.io/google_containers/kube2sky:1.9 - skydns gcr.io/google_containers/skydns:2015-03-11-001 -monitoring-heapster-v4 heapster gcr.io/google_containers/heapster:v0.14.3 k8s-app=heapster,version=v4 1 -monitoring-influx-grafana-v1 influxdb gcr.io/google_containers/heapster_influxdb:v0.3 k8s-app=influxGrafana,version=v1 1 - grafana gcr.io/google_containers/heapster_grafana:v0.7 -``` - -The Elasticsearch and Kibana services are not directly exposed via a publicly reachable IP address. Instead, -they can be accessed via the service proxy running at the master. The URLs for accessing Elasticsearch -and Kibana via the service proxy can be found using the `kubectl cluster-info` command. - -```console -$ kubectl cluster-info -Kubernetes master is running at https://146.148.94.154 -Elasticsearch is running at https://146.148.94.154/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging -Kibana is running at https://146.148.94.154/api/v1/proxy/namespaces/kube-system/services/kibana-logging -KubeDNS is running at https://146.148.94.154/api/v1/proxy/namespaces/kube-system/services/kube-dns -KubeUI is running at https://146.148.94.154/api/v1/proxy/namespaces/kube-system/services/kube-ui -Grafana is running at https://146.148.94.154/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana -Heapster is running at https://146.148.94.154/api/v1/proxy/namespaces/kube-system/services/monitoring-heapster -InfluxDB is running at https://146.148.94.154/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb -``` - -Before accessing the logs ingested into Elasticsearch using a browser and the service proxy URL we need to find out -the `admin` password for the cluster using `kubectl config view`. - -```console -$ kubectl config view -... -- name: kubernetes-satnam_kubernetes-basic-auth - user: - password: 7GlspJ9Q43OnGIJO - username: admin -... -``` - -The first time you try to access the cluster from a browser a dialog box appears asking for the username and password. -Use the username `admin` and provide the basic auth password reported by `kubectl config view` for the -cluster you are trying to connect to. Connecting to the Elasticsearch URL should then give the -status page for Elasticsearch. - -![Elasticsearch Status](es-browser.png) - -You can now type Elasticsearch queries directly into the browser. Alternatively you can query Elasticsearch -from your local machine using `curl` but first you need to know what your bearer token is: - -```console -$ kubectl config view --minify -apiVersion: v1 -clusters: -- cluster: - certificate-authority-data: REDACTED - server: https://146.148.94.154 - name: kubernetes-satnam_kubernetes -contexts: -- context: - cluster: kubernetes-satnam_kubernetes - user: kubernetes-satnam_kubernetes - name: kubernetes-satnam_kubernetes -current-context: kubernetes-satnam_kubernetes -kind: Config -preferences: {} -users: -- name: kubernetes-satnam_kubernetes - user: - client-certificate-data: REDACTED - client-key-data: REDACTED - token: JsUe2Z3cXqa17UQqQ8qWGGf4nOSLwSnp -``` - -Now you can issue requests to Elasticsearch: - -```console -$ curl --header "Authorization: Bearer JsUe2Z3cXqa17UQqQ8qWGGf4nOSLwSnp" --insecure https://146.148.94.154/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging/ -{ - "status" : 200, - "name" : "Vance Astrovik", - "cluster_name" : "kubernetes-logging", - "version" : { - "number" : "1.5.2", - "build_hash" : "62ff9868b4c8a0c45860bebb259e21980778ab1c", - "build_timestamp" : "2015-04-27T09:21:06Z", - "build_snapshot" : false, - "lucene_version" : "4.10.4" - }, - "tagline" : "You Know, for Search" -} -``` - -Note that you need the trailing slash at the end of the service proxy URL. Here is an example of a search: - -```console -$ curl --header "Authorization: Bearer JsUe2Z3cXqa17UQqQ8qWGGf4nOSLwSnp" --insecure https://146.148.94.154/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging/_search?pretty=true -{ - "took" : 7, - "timed_out" : false, - "_shards" : { - "total" : 6, - "successful" : 6, - "failed" : 0 - }, - "hits" : { - "total" : 123711, - "max_score" : 1.0, - "hits" : [ { - "_index" : ".kibana", - "_type" : "config", - "_id" : "4.0.2", - "_score" : 1.0, - "_source":{"buildNum":6004,"defaultIndex":"logstash-*"} - }, { -... - "_index" : "logstash-2015.06.22", - "_type" : "fluentd", - "_id" : "AU4c_GvFZL5p_gZ8dxtx", - "_score" : 1.0, - "_source":{"log":"synthetic-logger-10lps-pod: 31: 2015-06-22 20:35:33.597918073+00:00\n","stream":"stdout","tag":"kubernetes.synthetic-logger-10lps-pod_default_synth-lgr","@timestamp":"2015-06-22T20:35:33+00:00"} - }, { - "_index" : "logstash-2015.06.22", - "_type" : "fluentd", - "_id" : "AU4c_GvFZL5p_gZ8dxt2", - "_score" : 1.0, - "_source":{"log":"synthetic-logger-10lps-pod: 36: 2015-06-22 20:35:34.108780133+00:00\n","stream":"stdout","tag":"kubernetes.synthetic-logger-10lps-pod_default_synth-lgr","@timestamp":"2015-06-22T20:35:34+00:00"} - } ] - } -} -``` - -The Elasticsearch website contains information about [URI search queries](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html) which can be used to extract the required logs. - -Alternatively you can view the ingested logs using Kibana. The first time you visit the Kibana URL you will be -presented with a page that asks you to configure your view of the ingested logs. Select the option for -timeseries values and select `@timestamp`. On the following page select the `Discover` tab and then you -should be able to see the ingested logs. You can set the refresh interval to 5 seconds to have the logs -regulary refreshed. Here is a typical view of ingested logs from the Kibana viewer. - -![Kibana logs](kibana-logs.png) - -Another way to access Elasticsearch and Kibana in the cluster is to use `kubectl proxy` which will serve -a local proxy to the remote master: - -```console -$ kubectl proxy -Starting to serve on localhost:8001 -``` - -Now you can visit the URL [http://localhost:8001/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging](http://localhost:8001/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging) to contact Elasticsearch and [http://localhost:8001/api/v1/proxy/namespaces/kube-system/services/kibana-logging](http://localhost:8001/api/v1/proxy/namespaces/kube-system/services/kibana-logging) to access the Kibana viewer. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/logging-elasticsearch.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/logging.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/logging.md deleted file mode 100644 index 646b741bdca6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/logging.md +++ /dev/null @@ -1,253 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/logging.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Cluster Level Logging to Google Cloud Logging - -A Kubernetes cluster will typically be humming along running many system and application pods. How does the system administrator collect, manage and query the logs of the system pods? How does a user query the logs of their application which is composed of many pods which may be restarted or automatically generated by the Kubernetes system? These questions are addressed by the Kubernetes **cluster level logging** services. - -Cluster level logging for Kubernetes allows us to collect logs which persist beyond the lifetime of the pod’s container images or the lifetime of the pod or even cluster. In this article we assume that a Kubernetes cluster has been created with cluster level logging support for sending logs to Google Cloud Logging. After a cluster has been created you will have a collection of system pods running in the `kube-system` namespace that support monitoring, -logging and DNS resolution for names of Kubernetes services: - -```console -$ kubectl get pods --namespace=kube-system -NAME READY REASON RESTARTS AGE -fluentd-cloud-logging-kubernetes-minion-0f64 1/1 Running 0 32m -fluentd-cloud-logging-kubernetes-minion-27gf 1/1 Running 0 32m -fluentd-cloud-logging-kubernetes-minion-pk22 1/1 Running 0 31m -fluentd-cloud-logging-kubernetes-minion-20ej 1/1 Running 0 31m -kube-dns-v3-pk22 3/3 Running 0 32m -monitoring-heapster-v1-20ej 0/1 Running 9 32m -``` - -Here is the same information in a picture which shows how the pods might be placed on specific nodes. - -![Cluster](../../examples/blog-logging/diagrams/cloud-logging.png) - -This diagram shows four nodes created on a Google Compute Engine cluster with the name of each VM node on a purple background. The internal and public IPs of each node are shown on gray boxes and the pods running in each node are shown in green boxes. Each pod box shows the name of the pod and the namespace it runs in, the IP address of the pod and the images which are run as part of the pod’s execution. Here we see that every node is running a fluentd-cloud-logging pod which is collecting the log output of the containers running on the same node and sending them to Google Cloud Logging. A pod which provides the -[cluster DNS service](../admin/dns.md) runs on one of the nodes and a pod which provides monitoring support runs on another node. - -To help explain how cluster level logging works let’s start off with a synthetic log generator pod specification [counter-pod.yaml](../../examples/blog-logging/counter-pod.yaml): - - - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: counter -spec: - containers: - - name: count - image: ubuntu:14.04 - args: [bash, -c, - 'for ((i = 0; ; i++)); do echo "$i: $(date)"; sleep 1; done'] -``` - -[Download example](../../examples/blog-logging/counter-pod.yaml) - - -This pod specification has one container which runs a bash script when the container is born. This script simply writes out the value of a counter and the date once per second and runs indefinitely. Let’s create the pod in the default -namespace. - -```console - $ kubectl create -f examples/blog-logging/counter-pod.yaml - pods/counter -``` - -We can observe the running pod: - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -counter 1/1 Running 0 5m -``` - -This step may take a few minutes to download the ubuntu:14.04 image during which the pod status will be shown as `Pending`. - -One of the nodes is now running the counter pod: - -![Counter Pod](../../examples/blog-logging/diagrams/27gf-counter.png) - -When the pod status changes to `Running` we can use the kubectl logs command to view the output of this counter pod. - -```console -$ kubectl logs counter -0: Tue Jun 2 21:37:31 UTC 2015 -1: Tue Jun 2 21:37:32 UTC 2015 -2: Tue Jun 2 21:37:33 UTC 2015 -3: Tue Jun 2 21:37:34 UTC 2015 -4: Tue Jun 2 21:37:35 UTC 2015 -5: Tue Jun 2 21:37:36 UTC 2015 -... -``` - -This command fetches the log text from the Docker log file for the image that is running in this container. We can connect to the running container and observe the running counter bash script. - -```console -$ kubectl exec -i counter bash -ps aux -USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND -root 1 0.0 0.0 17976 2888 ? Ss 00:02 0:00 bash -c for ((i = 0; ; i++)); do echo "$i: $(date)"; sleep 1; done -root 468 0.0 0.0 17968 2904 ? Ss 00:05 0:00 bash -root 479 0.0 0.0 4348 812 ? S 00:05 0:00 sleep 1 -root 480 0.0 0.0 15572 2212 ? R 00:05 0:00 ps aux -``` - -What happens if for any reason the image in this pod is killed off and then restarted by Kubernetes? Will we still see the log lines from the previous invocation of the container followed by the log lines for the started container? Or will we lose the log lines from the original container’s execution and only see the log lines for the new container? Let’s find out. First let’s stop the currently running counter. - -```console -$ kubectl stop pod counter -pods/counter -``` - -Now let’s restart the counter. - -```console -$ kubectl create -f examples/blog-logging/counter-pod.yaml -pods/counter -``` - -Let’s wait for the container to restart and get the log lines again. - -```console -$ kubectl logs counter -0: Tue Jun 2 21:51:40 UTC 2015 -1: Tue Jun 2 21:51:41 UTC 2015 -2: Tue Jun 2 21:51:42 UTC 2015 -3: Tue Jun 2 21:51:43 UTC 2015 -4: Tue Jun 2 21:51:44 UTC 2015 -5: Tue Jun 2 21:51:45 UTC 2015 -6: Tue Jun 2 21:51:46 UTC 2015 -7: Tue Jun 2 21:51:47 UTC 2015 -8: Tue Jun 2 21:51:48 UTC 2015 -``` - -We’ve lost the log lines from the first invocation of the container in this pod! Ideally, we want to preserve all the log lines from each invocation of each container in the pod. Furthermore, even if the pod is restarted we would still like to preserve all the log lines that were ever emitted by the containers in the pod. But don’t fear, this is the functionality provided by cluster level logging in Kubernetes. When a cluster is created, the standard output and standard error output of each container can be ingested using a [Fluentd](http://www.fluentd.org/) agent running on each node into either [Google Cloud Logging](https://cloud.google.com/logging/docs/) or into Elasticsearch and viewed with Kibana. - -When a Kubernetes cluster is created with logging to Google Cloud Logging enabled, the system creates a pod called `fluentd-cloud-logging` on each node of the cluster to collect Docker container logs. These pods were shown at the start of this blog article in the response to the first get pods command. - -This log collection pod has a specification which looks something like this: - - - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: fluentd-cloud-logging - namespace: kube-system -spec: - containers: - - name: fluentd-cloud-logging - image: gcr.io/google_containers/fluentd-gcp:1.10 - resources: - limits: - cpu: 100m - memory: 200Mi - env: - - name: FLUENTD_ARGS - value: -qq - volumeMounts: - - name: varlog - mountPath: /varlog - - name: containers - mountPath: /var/lib/docker/containers - volumes: - - name: varlog - hostPath: - path: /var/log - - name: containers - hostPath: - path: /var/lib/docker/containers -``` - -[Download example](../../cluster/saltbase/salt/fluentd-gcp/fluentd-gcp.yaml) - - -This pod specification maps the directory on the host containing the Docker log files, `/var/lib/docker/containers`, to a directory inside the container which has the same path. The pod runs one image, `gcr.io/google_containers/fluentd-gcp:1.6`, which is configured to collect the Docker log files from the logs directory and ingest them into Google Cloud Logging. One instance of this pod runs on each node of the cluster. Kubernetes will notice if this pod fails and automatically restart it. - -We can click on the Logs item under the Monitoring section of the Google Developer Console and select the logs for the counter container, which will be called kubernetes.counter_default_count. This identifies the name of the pod (counter), the namespace (default) and the name of the container (count) for which the log collection occurred. Using this name we can select just the logs for our counter container from the drop down menu: - -![Cloud Logging Console](cloud-logging-console.png) - -When we view the logs in the Developer Console we observe the logs for both invocations of the container. - -![Both Logs](all-lines.png) - -Note the first container counted to 108 and then it was terminated. When the next container image restarted the counting process resumed from 0. Similarly if we deleted the pod and restarted it we would capture the logs for all instances of the containers in the pod whenever the pod was running. - - Logs ingested into Google Cloud Logging may be exported to various other destinations including [Google Cloud Storage](https://cloud.google.com/storage/) buckets and [BigQuery](https://cloud.google.com/bigquery/). Use the Exports tab in the Cloud Logging console to specify where logs should be streamed to. You can also follow this link to the - [settings tab](https://pantheon.corp.google.com/project/_/logs/settings). - - We could query the ingested logs from BigQuery using the SQL query which reports the counter log lines showing the newest lines first: - - ```console - SELECT metadata.timestamp, structPayload.log - FROM [mylogs.kubernetes_counter_default_count_20150611] - ORDER BY metadata.timestamp DESC - ``` - -Here is some sample output: - -![BigQuery](bigquery-logging.png) - -We could also fetch the logs from Google Cloud Storage buckets to our desktop or laptop and then search them locally. The following command fetches logs for the counter pod running in a cluster which is itself in a Compute Engine project called `myproject`. Only logs for the date 2015-06-11 are fetched. - - -```console -$ gsutil -m cp -r gs://myproject/kubernetes.counter_default_count/2015/06/11 . -``` - -Now we can run queries over the ingested logs. The example below uses the [jq](http://stedolan.github.io/jq/) program to extract just the log lines. - -```console -$ cat 21\:00\:00_21\:59\:59_S0.json | jq '.structPayload.log' -"0: Thu Jun 11 21:39:38 UTC 2015\n" -"1: Thu Jun 11 21:39:39 UTC 2015\n" -"2: Thu Jun 11 21:39:40 UTC 2015\n" -"3: Thu Jun 11 21:39:41 UTC 2015\n" -"4: Thu Jun 11 21:39:42 UTC 2015\n" -"5: Thu Jun 11 21:39:43 UTC 2015\n" -"6: Thu Jun 11 21:39:44 UTC 2015\n" -"7: Thu Jun 11 21:39:45 UTC 2015\n" -... -``` - -This page has touched briefly on the underlying mechanisms that support gathering cluster level logs on a Kubernetes deployment. The approach here only works for gathering the standard output and standard error output of the processes running in the pod’s containers. To gather other logs that are stored in files one can use a sidecar container to gather the required files as described at the page [Collecting log files within containers with Fluentd](http://releases.k8s.io/HEAD/contrib/logging/fluentd-sidecar-gcp/README.md) and sending them to the Google Cloud Logging service. - -Some of the material in this section also appears in the blog article [Cluster Level Logging with Kubernetes](http://blog.kubernetes.io/2015/06/cluster-level-logging-with-kubernetes.html). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/logging.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/mesos.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/mesos.md deleted file mode 100644 index 4570472c7ade..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/mesos.md +++ /dev/null @@ -1,376 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/mesos.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started with Kubernetes on Mesos ----------------------------------------- - -**Table of Contents** - -- [About Kubernetes on Mesos](#about-kubernetes-on-mesos) - - [Prerequisites](#prerequisites) - - [Deploy Kubernetes-Mesos](#deploy-kubernetes-mesos) - - [Deploy etcd](#deploy-etcd) - - [Start Kubernetes-Mesos Services](#start-kubernetes-mesos-services) - - [Validate KM Services](#validate-km-services) -- [Spin up a pod](#spin-up-a-pod) -- [Run the Example Guestbook App](#run-the-example-guestbook-app) - - [Test Guestbook App](#test-guestbook-app) - -## About Kubernetes on Mesos - - - -Mesos allows dynamic sharing of cluster resources between Kubernetes and other first-class Mesos frameworks such as [Hadoop][1], [Spark][2], and [Chronos][3]. -Mesos also ensures applications from different frameworks running on your cluster are isolated and that resources are allocated fairly among them. - -Mesos clusters can be deployed on nearly every IaaS cloud provider infrastructure or in your own physical datacenter. Kubernetes on Mesos runs on-top of that and therefore allows you to easily move Kubernetes workloads from one of these environments to the other. - -This tutorial will walk you through setting up Kubernetes on a Mesos cluster. -It provides a step by step walk through of adding Kubernetes to a Mesos cluster and starting your first pod with an nginx webserver. - -**NOTE:** There are [known issues with the current implementation][7] and support for centralized logging and monitoring is not yet available. -Please [file an issue against the kubernetes-mesos project][8] if you have problems completing the steps below. - -Further information is available in the Kubernetes on Mesos [contrib directory][13]. - -### Prerequisites - -* Understanding of [Apache Mesos][6] -* A running [Mesos cluster on Google Compute Engine][5] -* A [VPN connection][10] to the cluster -* A machine in the cluster which should become the Kubernetes *master node* with: - * GoLang > 1.2 - * make (i.e. build-essential) - * Docker - -**Note**: You *can*, but you *don't have to* deploy Kubernetes-Mesos on the same machine the Mesos master is running on. - -### Deploy Kubernetes-Mesos - -Log into the future Kubernetes *master node* over SSH, replacing the placeholder below with the correct IP address. - -```bash -ssh jclouds@${ip_address_of_master_node} -``` - -Build Kubernetes-Mesos. - -```bash -git clone https://k8s.io/kubernetes -cd kubernetes -export KUBERNETES_CONTRIB=mesos -make -``` - -Set some environment variables. -The internal IP address of the master may be obtained via `hostname -i`. - -```bash -export KUBERNETES_MASTER_IP=$(hostname -i) -export KUBERNETES_MASTER=http://${KUBERNETES_MASTER_IP}:8888 -``` - -### Deploy etcd - -Start etcd and verify that it is running: - -```bash -sudo docker run -d --hostname $(uname -n) --name etcd \ - -p 4001:4001 -p 7001:7001 quay.io/coreos/etcd:v2.0.12 \ - --listen-client-urls http://0.0.0.0:4001 \ - --advertise-client-urls http://${KUBERNETES_MASTER_IP}:4001 -``` - -```console -$ sudo docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -fd7bac9e2301 quay.io/coreos/etcd:v2.0.12 "/etcd" 5s ago Up 3s 2379/tcp, 2380/... etcd -``` - -It's also a good idea to ensure your etcd instance is reachable by testing it - -```bash -curl -L http://${KUBERNETES_MASTER_IP}:4001/v2/keys/ -``` - -If connectivity is OK, you will see an output of the available keys in etcd (if any). - -### Start Kubernetes-Mesos Services - -Update your PATH to more easily run the Kubernetes-Mesos binaries: - -```bash -export PATH="$(pwd)/_output/local/go/bin:$PATH" -``` - -Identify your Mesos master: depending on your Mesos installation this is either a `host:port` like `mesos_master:5050` or a ZooKeeper URL like `zk://zookeeper:2181/mesos`. -In order to let Kubernetes survive Mesos master changes, the ZooKeeper URL is recommended for production environments. - -```bash -export MESOS_MASTER= -``` - -Create a cloud config file `mesos-cloud.conf` in the current directory with the following contents: - -```console -$ cat <mesos-cloud.conf -[mesos-cloud] - mesos-master = ${MESOS_MASTER} -EOF -``` - -Now start the kubernetes-mesos API server, controller manager, and scheduler on the master node: - -```console -$ km apiserver \ - --address=${KUBERNETES_MASTER_IP} \ - --etcd-servers=http://${KUBERNETES_MASTER_IP}:4001 \ - --service-cluster-ip-range=10.10.10.0/24 \ - --port=8888 \ - --cloud-provider=mesos \ - --cloud-config=mesos-cloud.conf \ - --v=1 >apiserver.log 2>&1 & - -$ km controller-manager \ - --master=${KUBERNETES_MASTER_IP}:8888 \ - --cloud-provider=mesos \ - --cloud-config=./mesos-cloud.conf \ - --v=1 >controller.log 2>&1 & - -$ km scheduler \ - --address=${KUBERNETES_MASTER_IP} \ - --mesos-master=${MESOS_MASTER} \ - --etcd-servers=http://${KUBERNETES_MASTER_IP}:4001 \ - --mesos-user=root \ - --api-servers=${KUBERNETES_MASTER_IP}:8888 \ - --cluster-dns=10.10.10.10 \ - --cluster-domain=cluster.local \ - --v=2 >scheduler.log 2>&1 & -``` - -Disown your background jobs so that they'll stay running if you log out. - -```bash -disown -a -``` - -#### Validate KM Services - -Add the appropriate binary folder to your `PATH` to access kubectl: - -```bash -export PATH=/platforms/linux/amd64:$PATH -``` - -Interact with the kubernetes-mesos framework via `kubectl`: - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -``` - -```console -# NOTE: your service IPs will likely differ -$ kubectl get services -NAME LABELS SELECTOR IP(S) PORT(S) -k8sm-scheduler component=scheduler,provider=k8sm 10.10.10.113 10251/TCP -kubernetes component=apiserver,provider=kubernetes 10.10.10.1 443/TCP -``` - -Lastly, look for Kubernetes in the Mesos web GUI by pointing your browser to -`http://`. Make sure you have an active VPN connection. -Go to the Frameworks tab, and look for an active framework named "Kubernetes". - -## Spin up a pod - -Write a JSON pod description to a local file: - -```bash -$ cat <nginx.yaml -``` - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: nginx -spec: - containers: - - name: nginx - image: nginx - ports: - - containerPort: 80 -EOPOD -``` - -Send the pod description to Kubernetes using the `kubectl` CLI: - -```console -$ kubectl create -f ./nginx.yaml -pods/nginx -``` - -Wait a minute or two while `dockerd` downloads the image layers from the internet. -We can use the `kubectl` interface to monitor the status of our pod: - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -nginx 1/1 Running 0 14s -``` - -Verify that the pod task is running in the Mesos web GUI. Click on the -Kubernetes framework. The next screen should show the running Mesos task that -started the Kubernetes pod. - -## Launching kube-dns - -Kube-dns is an addon for Kubernetes which adds DNS-based service discovery to the cluster. For a detailed explanation see [DNS in Kubernetes][4]. - -The kube-dns addon runs as a pod inside the cluster. The pod consists of three co-located containers: -- a local etcd instance -- the [skydns][11] DNS server -- the kube2sky process to glue skydns to the state of the Kubernetes cluster. - -The skydns container offers DNS service via port 53 to the cluster. The etcd communication works via local 127.0.0.1 communication - -We assume that kube-dns will use -- the service IP `10.10.10.10` -- and the `cluster.local` domain. - -Note that we have passed these two values already as parameter to the apiserver above. - -A template for an replication controller spinning up the pod with the 3 containers can be found at [cluster/addons/dns/skydns-rc.yaml.in][11] in the repository. The following steps are necessary in order to get a valid replication controller yaml file: - -- replace `{{ pillar['dns_replicas'] }}` with `1` -- replace `{{ pillar['dns_domain'] }}` with `cluster.local.` -- add `--kube_master_url=${KUBERNETES_MASTER}` parameter to the kube2sky container command. - -In addition the service template at [cluster/addons/dns/skydns-svc.yaml.in][12] needs the following replacement: - -- `{{ pillar['dns_server'] }}` with `10.10.10.10`. - -To do this automatically: - -```bash -sed -e "s/{{ pillar\['dns_replicas'\] }}/1/g;"\ -"s,\(command = \"/kube2sky\"\),\\1\\"$'\n'" - --kube_master_url=${KUBERNETES_MASTER},;"\ -"s/{{ pillar\['dns_domain'\] }}/cluster.local/g" \ - cluster/addons/dns/skydns-rc.yaml.in > skydns-rc.yaml -sed -e "s/{{ pillar\['dns_server'\] }}/10.10.10.10/g" \ - cluster/addons/dns/skydns-svc.yaml.in > skydns-svc.yaml -``` - -Now the kube-dns pod and service are ready to be launched: - -```bash -kubectl create -f ./skydns-rc.yaml -kubectl create -f ./skydns-svc.yaml -``` - -Check with `kubectl get pods --namespace=kube-system` that 3/3 containers of the pods are eventually up and running. Note that the kube-dns pods run in the `kube-system` namespace, not in `default`. - -To check that the new DNS service in the cluster works, we start a busybox pod and use that to do a DNS lookup. First create the `busybox.yaml` pod spec: - -```bash -cat <busybox.yaml -``` - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: busybox - namespace: default -spec: - containers: - - image: busybox - command: - - sleep - - "3600" - imagePullPolicy: IfNotPresent - name: busybox - restartPolicy: Always -EOF -``` - -Then start the pod: - -```bash -kubectl create -f ./busybox.yaml -``` - -When the pod is up and running, start a lookup for the Kubernetes master service, made available on 10.10.10.1 by default: - -```bash -kubectl exec busybox -- nslookup kubernetes -``` - -If everything works fine, you will get this output: - -```console -Server: 10.10.10.10 -Address 1: 10.10.10.10 - -Name: kubernetes -Address 1: 10.10.10.1 -``` - -## What next? - -Try out some of the standard [Kubernetes examples][9]. - -Read about Kubernetes on Mesos' architecture in the [contrib directory][13]. - -**NOTE:** Some examples require Kubernetes DNS to be installed on the cluster. -Future work will add instructions to this guide to enable support for Kubernetes DNS. - -**NOTE:** Please be aware that there are [known issues with the current Kubernetes-Mesos implementation][7]. - -[1]: http://mesosphere.com/docs/tutorials/run-hadoop-on-mesos-using-installer -[2]: http://mesosphere.com/docs/tutorials/run-spark-on-mesos -[3]: http://mesosphere.com/docs/tutorials/run-chronos-on-mesos -[4]: ../../cluster/addons/dns/README.md -[5]: http://open.mesosphere.com/getting-started/cloud/google/mesosphere/ -[6]: http://mesos.apache.org/ -[7]: ../../contrib/mesos/docs/issues.md -[8]: https://github.com/mesosphere/kubernetes-mesos/issues -[9]: ../../examples/ -[10]: http://open.mesosphere.com/getting-started/cloud/google/mesosphere/#vpn-setup -[11]: ../../cluster/addons/dns/skydns-rc.yaml.in -[12]: ../../cluster/addons/dns/skydns-svc.yaml.in -[13]: ../../contrib/mesos/README.md - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/mesos.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/mesos/k8s-firewall.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/mesos/k8s-firewall.png deleted file mode 100755 index ed1c57ca7d0980056b9d088b4d3822c4dc0fd223..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88722 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 Km2wm>-T8lGZ)9Kq diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/mesos/k8s-guestbook.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/mesos/k8s-guestbook.png deleted file mode 100755 index 07d2458b3b54fd0975f35f0a6f78fb0e48e287ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44000 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
      NdlsC{ZEfuA7bbgvz`f(d;eP*7 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 - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/ovirt.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started on oVirt ------------------------- - -**Table of Contents** - -- [What is oVirt](#what-is-ovirt) -- [oVirt Cloud Provider Deployment](#ovirt-cloud-provider-deployment) -- [Using the oVirt Cloud Provider](#using-the-ovirt-cloud-provider) -- [oVirt Cloud Provider Screencast](#ovirt-cloud-provider-screencast) - -## What is oVirt - -oVirt is a virtual datacenter manager that delivers powerful management of multiple virtual machines on multiple hosts. Using KVM and libvirt, oVirt can be installed on Fedora, CentOS, or Red Hat Enterprise Linux hosts to set up and manage your virtual data center. - -## oVirt Cloud Provider Deployment - -The oVirt cloud provider allows to easily discover and automatically add new VM instances as nodes to your Kubernetes cluster. -At the moment there are no community-supported or pre-loaded VM images including Kubernetes but it is possible to [import] or [install] Project Atomic (or Fedora) in a VM to [generate a template]. Any other distribution that includes Kubernetes may work as well. - -It is mandatory to [install the ovirt-guest-agent] in the guests for the VM ip address and hostname to be reported to ovirt-engine and ultimately to Kubernetes. - -Once the Kubernetes template is available it is possible to start instantiating VMs that can be discovered by the cloud provider. - -[import]: http://ovedou.blogspot.it/2014/03/importing-glance-images-as-ovirt.html -[install]: http://www.ovirt.org/Quick_Start_Guide#Create_Virtual_Machines -[generate a template]: http://www.ovirt.org/Quick_Start_Guide#Using_Templates -[install the ovirt-guest-agent]: http://www.ovirt.org/How_to_install_the_guest_agent_in_Fedora - -## Using the oVirt Cloud Provider - -The oVirt Cloud Provider requires access to the oVirt REST-API to gather the proper information, the required credential should be specified in the `ovirt-cloud.conf` file: - - [connection] - uri = https://localhost:8443/ovirt-engine/api - username = admin@internal - password = admin - -In the same file it is possible to specify (using the `filters` section) what search query to use to identify the VMs to be reported to Kubernetes: - - [filters] - # Search query used to find nodes - vms = tag=kubernetes - -In the above example all the VMs tagged with the `kubernetes` label will be reported as nodes to Kubernetes. - -The `ovirt-cloud.conf` file then must be specified in kube-controller-manager: - - kube-controller-manager ... --cloud-provider=ovirt --cloud-config=/path/to/ovirt-cloud.conf ... - -## oVirt Cloud Provider Screencast - -This short screencast demonstrates how the oVirt Cloud Provider can be used to dynamically add VMs to your Kubernetes cluster. - -[![Screencast](http://img.youtube.com/vi/JyyST4ZKne8/0.jpg)](http://www.youtube.com/watch?v=JyyST4ZKne8) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/ovirt.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/rackspace.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/rackspace.md deleted file mode 100644 index 97738e7506be..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/rackspace.md +++ /dev/null @@ -1,107 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/rackspace.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started on Rackspace ----------------------------- - -**Table of Contents** - -- [Introduction](#introduction) -- [Prerequisites](#prerequisites) -- [Provider: Rackspace](#provider-rackspace) -- [Build](#build) -- [Cluster](#cluster) -- [Some notes:](#some-notes) -- [Network Design](#network-design) - -## Introduction - -* Supported Version: v0.18.1 - -In general, the dev-build-and-up.sh workflow for Rackspace is the similar to Google Compute Engine. The specific implementation is different due to the use of CoreOS, Rackspace Cloud Files and the overall network design. - -These scripts should be used to deploy development environments for Kubernetes. If your account leverages RackConnect or non-standard networking, these scripts will most likely not work without modification. - -NOTE: The rackspace scripts do NOT rely on `saltstack` and instead rely on cloud-init for configuration. - -The current cluster design is inspired by: -- [corekube](https://github.com/metral/corekube) -- [Angus Lees](https://github.com/anguslees/kube-openstack) - -## Prerequisites - -1. Python2.7 -2. You need to have both `nova` and `swiftly` installed. It's recommended to use a python virtualenv to install these packages into. -3. Make sure you have the appropriate environment variables set to interact with the OpenStack APIs. See [Rackspace Documentation](http://docs.rackspace.com/servers/api/v2/cs-gettingstarted/content/section_gs_install_nova.html) for more details. - -## Provider: Rackspace - -- To build your own released version from source use `export KUBERNETES_PROVIDER=rackspace` and run the `bash hack/dev-build-and-up.sh` -- Note: The get.k8s.io install method is not working yet for our scripts. - * To install the latest released version of Kubernetes use `export KUBERNETES_PROVIDER=rackspace; wget -q -O - https://get.k8s.io | bash` - -## Build - -1. The Kubernetes binaries will be built via the common build scripts in `build/`. -2. If you've set the ENV `KUBERNETES_PROVIDER=rackspace`, the scripts will upload `kubernetes-server-linux-amd64.tar.gz` to Cloud Files. -2. A cloud files container will be created via the `swiftly` CLI and a temp URL will be enabled on the object. -3. The built `kubernetes-server-linux-amd64.tar.gz` will be uploaded to this container and the URL will be passed to master/nodes when booted. - -## Cluster - -There is a specific `cluster/rackspace` directory with the scripts for the following steps: -1. A cloud network will be created and all instances will be attached to this network. - - flanneld uses this network for next hop routing. These routes allow the containers running on each node to communicate with one another on this private network. -2. A SSH key will be created and uploaded if needed. This key must be used to ssh into the machines (we do not capture the password). -3. The master server and additional nodes will be created via the `nova` CLI. A `cloud-config.yaml` is generated and provided as user-data with the entire configuration for the systems. -4. We then boot as many nodes as defined via `$NUM_MINIONS`. - -## Some notes - -- The scripts expect `eth2` to be the cloud network that the containers will communicate across. -- A number of the items in `config-default.sh` are overridable via environment variables. -- For older versions please either: - * Sync back to `v0.9` with `git checkout v0.9` - * Download a [snapshot of `v0.9`](https://k8s.io/kubernetes/archive/v0.9.tar.gz) - * Sync back to `v0.3` with `git checkout v0.3` - * Download a [snapshot of `v0.3`](https://k8s.io/kubernetes/archive/v0.3.tar.gz) - -## Network Design - -- eth0 - Public Interface used for servers/containers to reach the internet -- eth1 - ServiceNet - Intra-cluster communication (k8s, etcd, etc) communicate via this interface. The `cloud-config` files use the special CoreOS identifier `$private_ipv4` to configure the services. -- eth2 - Cloud Network - Used for k8s pods to communicate with one another. The proxy service will pass traffic via this interface. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/rackspace.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/rkt/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/rkt/README.md deleted file mode 100644 index a0af511721bc..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/rkt/README.md +++ /dev/null @@ -1,139 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/rkt/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Run Kubernetes with rkt - -This document describes how to run Kubernetes using [rkt](https://github.com/coreos/rkt) as a container runtime. -We still have [a bunch of work](https://k8s.io/kubernetes/issues/8262) to do to make the experience with rkt wonderful, please stay tuned! - -### **Prerequisite** - -- [systemd](http://www.freedesktop.org/wiki/Software/systemd/) should be installed on your machine and should be enabled. The minimum version required at this moment (2015/05/28) is [215](http://lists.freedesktop.org/archives/systemd-devel/2014-July/020903.html). - *(Note that systemd is not required by rkt itself, we are using it here to monitor and manage the pods launched by kubelet.)* - -- Install the latest rkt release according to the instructions [here](https://github.com/coreos/rkt). - The minimum version required for now is [v0.5.6](https://github.com/coreos/rkt/releases/tag/v0.5.6). - -- Make sure the `rkt metadata service` is running because it is necessary for running pod in private network mode. - More details about the networking of rkt can be found in the [documentation](https://github.com/coreos/rkt/blob/master/Documentation/networking.md). - - To start the `rkt metadata service`, you can simply run: - - ```console - $ sudo rkt metadata-service - ``` - - If you want the service to be running as a systemd service, then: - - ```console - $ sudo systemd-run rkt metadata-service - ``` - - Alternatively, you can use the [rkt-metadata.service](https://github.com/coreos/rkt/blob/master/dist/init/systemd/rkt-metadata.service) and [rkt-metadata.socket](https://github.com/coreos/rkt/blob/master/dist/init/systemd/rkt-metadata.socket) to start the service. - - -### Local cluster - -To use rkt as the container runtime, you just need to set the environment variable `CONTAINER_RUNTIME`: - -```console -$ export CONTAINER_RUNTIME=rkt -$ hack/local-up-cluster.sh -``` - -### CoreOS cluster on Google Compute Engine (GCE) - -To use rkt as the container runtime for your CoreOS cluster on GCE, you need to specify the OS distribution, project, image: - -```console -$ export KUBE_OS_DISTRIBUTION=coreos -$ export KUBE_GCE_MINION_IMAGE= -$ export KUBE_GCE_MINION_PROJECT=coreos-cloud -$ export KUBE_CONTAINER_RUNTIME=rkt -``` - -You can optionally choose the version of rkt used by setting `KUBE_RKT_VERSION`: - -```console -$ export KUBE_RKT_VERSION=0.5.6 -``` - -Then you can launch the cluster by: - -```console -$ kube-up.sh -``` - -Note that we are still working on making all containerized the master components run smoothly in rkt. Before that we are not able to run the master node with rkt yet. - -### CoreOS cluster on AWS - -To use rkt as the container runtime for your CoreOS cluster on AWS, you need to specify the provider and OS distribution: - -```console -$ export KUBERNETES_PROVIDER=aws -$ export KUBE_OS_DISTRIBUTION=coreos -$ export KUBE_CONTAINER_RUNTIME=rkt -``` - -You can optionally choose the version of rkt used by setting `KUBE_RKT_VERSION`: - -```console -$ export KUBE_RKT_VERSION=0.5.6 -``` - -You can optionally choose the CoreOS channel by setting `COREOS_CHANNEL`: - -```console -$ export COREOS_CHANNEL=stable -``` - -Then you can launch the cluster by: - -```console -$ kube-up.sh -``` - -Note: CoreOS is not supported as the master using the automated launch -scripts. The master node is always Ubuntu. - -### Getting started with your cluster - -See [a simple nginx example](../../../docs/user-guide/simple-nginx.md) to try out your new cluster. - -For more complete applications, please look in the [examples directory](../../../examples/). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/rkt/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/scratch.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/scratch.md deleted file mode 100644 index 60b403a4edae..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/scratch.md +++ /dev/null @@ -1,872 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/scratch.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started from Scratch ----------------------------- - -This guide is for people who want to craft a custom Kubernetes cluster. If you -can find an existing Getting Started Guide that meets your needs on [this -list](README.md), then we recommend using it, as you will be able to benefit -from the experience of others. However, if you have specific IaaS, networking, -configuration management, or operating system requirements not met by any of -those guides, then this guide will provide an outline of the steps you need to -take. Note that it requires considerably more effort than using one of the -pre-defined guides. - -This guide is also useful for those wanting to understand at a high level some of the -steps that existing cluster setup scripts are making. - -**Table of Contents** - - - - - [Designing and Preparing](#designing-and-preparing) - - [Learning](#learning) - - [Cloud Provider](#cloud-provider) - - [Nodes](#nodes) - - [Network](#network) - - [Cluster Naming](#cluster-naming) - - [Software Binaries](#software-binaries) - - [Downloading and Extracting Kubernetes Binaries](#downloading-and-extracting-kubernetes-binaries) - - [Selecting Images](#selecting-images) - - [Security Models](#security-models) - - [Preparing Certs](#preparing-certs) - - [Preparing Credentials](#preparing-credentials) - - [Configuring and Installing Base Software on Nodes](#configuring-and-installing-base-software-on-nodes) - - [Docker](#docker) - - [rkt](#rkt) - - [kubelet](#kubelet) - - [kube-proxy](#kube-proxy) - - [Networking](#networking) - - [Other](#other) - - [Using Configuration Management](#using-configuration-management) - - [Bootstrapping the Cluster](#bootstrapping-the-cluster) - - [etcd](#etcd) - - [Apiserver, Controller Manager, and Scheduler](#apiserver-controller-manager-and-scheduler) - - [Apiserver pod template](#apiserver-pod-template) - - [Cloud Providers](#cloud-providers) - - [Scheduler pod template](#scheduler-pod-template) - - [Controller Manager Template](#controller-manager-template) - - [Starting and Verifying Apiserver, Scheduler, and Controller Manager](#starting-and-verifying-apiserver-scheduler-and-controller-manager) - - [Logging](#logging) - - [Monitoring](#monitoring) - - [DNS](#dns) - - [Troubleshooting](#troubleshooting) - - [Running validate-cluster](#running-validate-cluster) - - [Inspect pods and services](#inspect-pods-and-services) - - [Try Examples](#try-examples) - - [Running the Conformance Test](#running-the-conformance-test) - - [Networking](#networking) - - [Getting Help](#getting-help) - - - -## Designing and Preparing - -### Learning - - 1. You should be familiar with using Kubernetes already. We suggest you set - up a temporary cluster by following one of the other Getting Started Guides. - This will help you become familiar with the CLI ([kubectl](../user-guide/kubectl/kubectl.md)) and concepts ([pods](../user-guide/pods.md), [services](../user-guide/services.md), etc.) first. - 1. You should have `kubectl` installed on your desktop. This will happen as a side - effect of completing one of the other Getting Started Guides. If not, follow the instructions - [here](../user-guide/prereqs.md). - -### Cloud Provider - -Kubernetes has the concept of a Cloud Provider, which is a module which provides -an interface for managing TCP Load Balancers, Nodes (Instances) and Networking Routes. -The interface is defined in `pkg/cloudprovider/cloud.go`. It is possible to -create a custom cluster without implementing a cloud provider (for example if using -bare-metal), and not all parts of the interface need to be implemented, depending -on how flags are set on various components. - -### Nodes - -- You can use virtual or physical machines. -- While you can build a cluster with 1 machine, in order to run all the examples and tests you - need at least 4 nodes. -- Many Getting-started-guides make a distinction between the master node and regular nodes. This - is not strictly necessary. -- Nodes will need to run some version of Linux with the x86_64 architecture. It may be possible - to run on other OSes and Architectures, but this guide does not try to assist with that. -- Apiserver and etcd together are fine on a machine with 1 core and 1GB RAM for clusters with 10s of nodes. - Larger or more active clusters may benefit from more cores. -- Other nodes can have any reasonable amount of memory and any number of cores. They need not - have identical configurations. - -### Network - -Kubernetes has a distinctive [networking model](../admin/networking.md). - -Kubernetes allocates an IP address to each pod. When creating a cluster, you -need to allocate a block of IPs for Kubernetes to use as Pod IPs. The simplest -approach is to allocate a different block of IPs to each node in the cluster as -the node is added. A process in one pod should be able to communicate with -another pod using the IP of the second pod. This connectivity can be -accomplished in two ways: -- Configure network to route Pod IPs - - Harder to setup from scratch. - - Google Compute Engine ([GCE](gce.md)) and [AWS](aws.md) guides use this approach. - - Need to make the Pod IPs routable by programming routers, switches, etc. - - Can be configured external to Kubernetes, or can implement in the "Routes" interface of a Cloud Provider module. - - Generally highest performance. -- Create an Overlay network - - Easier to setup - - Traffic is encapsulated, so per-pod IPs are routable. - - Examples: - - [Flannel](https://github.com/coreos/flannel) - - [Weave](http://weave.works/) - - [Open vSwitch (OVS)](http://openvswitch.org/) - - Does not require "Routes" portion of Cloud Provider module. - - Reduced performance (exactly how much depends on your solution). - -You need to select an address range for the Pod IPs. -- Various approaches: - - GCE: each project has its own `10.0.0.0/8`. Carve off a `/16` for each - Kubernetes cluster from that space, which leaves room for several clusters. - Each node gets a further subdivision of this space. - - AWS: use one VPC for whole organization, carve off a chunk for each - cluster, or use different VPC for different clusters. - - IPv6 is not supported yet. -- Allocate one CIDR subnet for each node's PodIPs, or a single large CIDR - from which smaller CIDRs are automatically allocated to each node (if nodes - are dynamically added). - - You need max-pods-per-node * max-number-of-nodes IPs in total. A `/24` per - node supports 254 pods per machine and is a common choice. If IPs are - scarce, a `/26` (62 pods per machine) or even a `/27` (30 pods) may be sufficient. - - e.g. use `10.10.0.0/16` as the range for the cluster, with up to 256 nodes - using `10.10.0.0/24` through `10.10.255.0/24`, respectively. - - Need to make these routable or connect with overlay. - -Kubernetes also allocates an IP to each [service](../user-guide/services.md). However, -service IPs do not necessarily need to be routable. The kube-proxy takes care -of translating Service IPs to Pod IPs before traffic leaves the node. You do -need to Allocate a block of IPs for services. Call this -`SERVICE_CLUSTER_IP_RANGE`. For example, you could set -`SERVICE_CLUSTER_IP_RANGE="10.0.0.0/16"`, allowing 65534 distinct services to -be active at once. Note that you can grow the end of this range, but you -cannot move it without disrupting the services and pods that already use it. - -Also, you need to pick a static IP for master node. -- Call this `MASTER_IP`. -- Open any firewalls to allow access to the apiserver ports 80 and/or 443. -- Enable ipv4 forwarding sysctl, `net.ipv4.ip_forward = 1` - -### Cluster Naming - -You should pick a name for your cluster. Pick a short name for each cluster -which is unique from future cluster names. This will be used in several ways: - - by kubectl to distinguish between various clusters you have access to. You will probably want a - second one sometime later, such as for testing new Kubernetes releases, running in a different -region of the world, etc. - - Kubernetes clusters can create cloud provider resources (e.g. AWS ELBs) and different clusters - need to distinguish which resources each created. Call this `CLUSTERNAME`. - -### Software Binaries - -You will need binaries for: - - etcd - - A container runner, one of: - - docker - - rkt - - Kubernetes - - kubelet - - kube-proxy - - kube-apiserver - - kube-controller-manager - - kube-scheduler - -#### Downloading and Extracting Kubernetes Binaries - -A Kubernetes binary release includes all the Kubernetes binaries as well as the supported release of etcd. -You can use a Kubernetes binary release (recommended) or build your Kubernetes binaries following the instructions in the -[Developer Documentation](../devel/README.md). Only using a binary release is covered in this guide. - -Download the [latest binary release](https://k8s.io/kubernetes/releases/latest) and unzip it. -Then locate `./kubernetes/server/kubernetes-server-linux-amd64.tar.gz` and unzip *that*. -Then, within the second set of unzipped files, locate `./kubernetes/server/bin`, which contains -all the necessary binaries. - -#### Selecting Images - -You will run docker, kubelet, and kube-proxy outside of a container, the same way you would run any system daemon, so -you just need the bare binaries. For etcd, kube-apiserver, kube-controller-manager, and kube-scheduler, -we recommend that you run these as containers, so you need an image to be built. - -You have several choices for Kubernetes images: -- Use images hosted on Google Container Registry (GCR): - - e.g `gcr.io/google_containers/kube-apiserver:$TAG`, where `TAG` is the latest - release tag, which can be found on the [latest releases page](https://k8s.io/kubernetes/releases/latest). - - Ensure $TAG is the same tag as the release tag you are using for kubelet and kube-proxy. -- Build your own images. - - Useful if you are using a private registry. - - The release contains files such as `./kubernetes/server/bin/kube-apiserver.tar` which - can be converted into docker images using a command like - `docker load -i kube-apiserver.tar` - - You can verify if the image is loaded successfully with the right reposity and tag using - command like `docker images` - -For etcd, you can: -- Use images hosted on Google Container Registry (GCR), such as `gcr.io/google_containers/etcd:2.0.12` -- Use images hosted on [Docker Hub](https://registry.hub.docker.com/u/coreos/etcd/) or [quay.io](https://registry.hub.docker.com/u/coreos/etcd/) -- Use etcd binary included in your OS distro. -- Build your own image - - You can do: `cd kubernetes/cluster/images/etcd; make` - -We recommend that you use the etcd version which is provided in the Kubernetes binary distribution. The Kubernetes binaries in the release -were tested extensively with this version of etcd and not with any other version. -The recommended version number can also be found as the value of `ETCD_VERSION` in `kubernetes/cluster/images/etcd/Makefile`. - -The remainder of the document assumes that the image identifiers have been chosen and stored in corresponding env vars. Examples (replace with latest tags and appropriate registry): - - `APISERVER_IMAGE=gcr.io/google_containers/kube-apiserver:$TAG` - - `SCHEDULER_IMAGE=gcr.io/google_containers/kube-scheduler:$TAG` - - `CNTRLMNGR_IMAGE=gcr.io/google_containers/kube-controller-manager:$TAG` - - `ETCD_IMAGE=gcr.io/google_containers/etcd:$ETCD_VERSION` - -### Security Models - -There are two main options for security: -- Access the apiserver using HTTP. - - Use a firewall for security. - - This is easier to setup. -- Access the apiserver using HTTPS - - Use https with certs, and credentials for user. - - This is the recommended approach. - - Configuring certs can be tricky. - -If following the HTTPS approach, you will need to prepare certs and credentials. - -#### Preparing Certs - -You need to prepare several certs: -- The master needs a cert to act as an HTTPS server. -- The kubelets optionally need certs to identify themselves as clients of the master, and when - serving its own API over HTTPS. - -Unless you plan to have a real CA generate your certs, you will need to generate a root cert and use that to sign the master, kubelet, and kubectl certs. -- see function `create-certs` in `cluster/gce/util.sh` -- see also `cluster/saltbase/salt/generate-cert/make-ca-cert.sh` and - `cluster/saltbase/salt/generate-cert/make-cert.sh` - -You will end up with the following files (we will use these variables later on) -- `CA_CERT` - - put in on node where apiserver runs, in e.g. `/srv/kubernetes/ca.crt`. -- `MASTER_CERT` - - signed by CA_CERT - - put in on node where apiserver runs, in e.g. `/srv/kubernetes/server.crt` -- `MASTER_KEY ` - - put in on node where apiserver runs, in e.g. `/srv/kubernetes/server.key` -- `KUBELET_CERT` - - optional -- `KUBELET_KEY` - - optional - -#### Preparing Credentials - -The admin user (and any users) need: - - a token or a password to identify them. - - tokens are just long alphanumeric strings, e.g. 32 chars. See - - `TOKEN=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null)` - -Your tokens and passwords need to be stored in a file for the apiserver -to read. This guide uses `/var/lib/kube-apiserver/known_tokens.csv`. -The format for this file is described in the [authentication documentation](../admin/authentication.md). - -For distributing credentials to clients, the convention in Kubernetes is to put the credentials -into a [kubeconfig file](../user-guide/kubeconfig-file.md). - -The kubeconfig file for the administrator can be created as follows: - - If you have already used Kubernetes with a non-custom cluster (for example, used a Getting Started - Guide), you will already have a `$HOME/.kube/config` file. - - You need to add certs, keys, and the master IP to the kubeconfig file: - - If using the firewall-only security option, set the apiserver this way: - - `kubectl config set-cluster $CLUSTER_NAME --server=http://$MASTER_IP --insecure-skip-tls-verify=true` - - Otherwise, do this to set the apiserver ip, client certs, and user credentials. - - `kubectl config set-cluster $CLUSTER_NAME --certificate-authority=$CA_CERT --embed-certs=true --server=https://$MASTER_IP` - - `kubectl config set-credentials $USER --client-certificate=$CLI_CERT --client-key=$CLI_KEY --embed-certs=true --token=$TOKEN` - - Set your cluster as the default cluster to use: - - `kubectl config set-context $CONTEXT_NAME --cluster=$CLUSTER_NAME --user=$USER` - - `kubectl config use-context $CONTEXT_NAME` - -Next, make a kubeconfig file for the kubelets and kube-proxy. There are a couple of options for how -many distinct files to make: - 1. Use the same credential as the admin - - This is simplest to setup. - 1. One token and kubeconfig file for all kubelets, one for all kube-proxy, one for admin. - - This mirrors what is done on GCE today - 1. Different credentials for every kubelet, etc. - - We are working on this but all the pieces are not ready yet. - -You can make the files by copying the `$HOME/.kube/config`, by following the code -in `cluster/gce/configure-vm.sh` or by using the following template: - -```yaml -apiVersion: v1 -kind: Config -users: -- name: kubelet - user: - token: ${KUBELET_TOKEN} -clusters: -- name: local - cluster: - certificate-authority-data: ${CA_CERT_BASE64_ENCODED} -contexts: -- context: - cluster: local - user: kubelet - name: service-account-context -current-context: service-account-context -``` - -Put the kubeconfig(s) on every node. The examples later in this -guide assume that there are kubeconfigs in `/var/lib/kube-proxy/kubeconfig` and -`/var/lib/kubelet/kubeconfig`. - -## Configuring and Installing Base Software on Nodes - -This section discusses how to configure machines to be Kubernetes nodes. - -You should run three daemons on every node: - - docker or rkt - - kubelet - - kube-proxy - -You will also need to do assorted other configuration on top of a -base OS install. - -Tip: One possible starting point is to setup a cluster using an existing Getting -Started Guide. After getting a cluster running, you can then copy the init.d scripts or systemd unit files from that -cluster, and then modify them for use on your custom cluster. - -### Docker - -The minimum required Docker version will vary as the kubelet version changes. The newest stable release is a good choice. Kubelet will log a warning and refuse to start pods if the version is too old, so pick a version and try it. - -If you previously had Docker installed on a node without setting Kubernetes-specific -options, you may have a Docker-created bridge and iptables rules. You may want to remove these -as follows before proceeding to configure Docker for Kubernetes. - -```sh -iptables -t nat -F -ifconfig docker0 down -brctl delbr docker0 -``` - -The way you configure docker will depend in whether you have chosen the routable-vip or overlay-network approaches for your network. -Some suggested docker options: - - create your own bridge for the per-node CIDR ranges, call it cbr0, and set `--bridge=cbr0` option on docker. - - set `--iptables=false` so docker will not manipulate iptables for host-ports (too coarse on older docker versions, may be fixed in newer versions) -so that kube-proxy can manage iptables instead of docker. - - `--ip-masq=false` - - if you have setup PodIPs to be routable, then you want this false, otherwise, docker will - rewrite the PodIP source-address to a NodeIP. - - some environments (e.g. GCE) still need you to masquerade out-bound traffic when it leaves the cloud environment. This is very environment specific. - - if you are using an overlay network, consult those instructions. - - `--mtu=` - - may be required when using Flannel, because of the extra packet size due to udp encapsulation - - `--insecure-registry $CLUSTER_SUBNET` - - to connect to a private registry, if you set one up, without using SSL. - -You may want to increase the number of open files for docker: - - `DOCKER_NOFILE=1000000` - -Where this config goes depends on your node OS. For example, GCE's Debian-based distro uses `/etc/default/docker`. - -Ensure docker is working correctly on your system before proceeding with the rest of the -installation, by following examples given in the Docker documentation. - -### rkt - -[rkt](https://github.com/coreos/rkt) is an alternative to Docker. You only need to install one of Docker or rkt. -The minimum version required is [v0.5.6](https://github.com/coreos/rkt/releases/tag/v0.5.6). - -[systemd](http://www.freedesktop.org/wiki/Software/systemd/) is required on your node to run rkt. The -minimum version required to match rkt v0.5.6 is -[systemd 215](http://lists.freedesktop.org/archives/systemd-devel/2014-July/020903.html). - -[rkt metadata service](https://github.com/coreos/rkt/blob/master/Documentation/networking.md) is also required -for rkt networking support. You can start rkt metadata service by using command like -`sudo systemd-run rkt metadata-service` - -Then you need to configure your kubelet with flag: - - `--container_runtime=rkt` - -### kubelet - -All nodes should run kubelet. See [Selecting Binaries](#selecting-binaries). - -Arguments to consider: - - If following the HTTPS security approach: - - `--api-servers=https://$MASTER_IP` - - `--kubeconfig=/var/lib/kubelet/kubeconfig` - - Otherwise, if taking the firewall-based security approach - - `--api-servers=http://$MASTER_IP` - - `--config=/etc/kubernetes/manifests` - - `--cluster-dns=` to the address of the DNS server you will setup (see [Starting Addons](#starting-addons).) - - `--cluster-domain=` to the dns domain prefix to use for cluster DNS addresses. - - `--docker-root=` - - `--root-dir=` - - `--configure-cbr0=` (described above) - - `--register-node` (described in [Node](../admin/node.md) documentation.) - -### kube-proxy - -All nodes should run kube-proxy. (Running kube-proxy on a "master" node is not -strictly required, but being consistent is easier.) Obtain a binary as described for -kubelet. - -Arguments to consider: - - If following the HTTPS security approach: - - `--api-servers=https://$MASTER_IP` - - `--kubeconfig=/var/lib/kube-proxy/kubeconfig` - - Otherwise, if taking the firewall-based security approach - - `--api-servers=http://$MASTER_IP` - -### Networking - -Each node needs to be allocated its own CIDR range for pod networking. -Call this `NODE_X_POD_CIDR`. - -A bridge called `cbr0` needs to be created on each node. The bridge is explained -further in the [networking documentation](../admin/networking.md). The bridge itself -needs an address from `$NODE_X_POD_CIDR` - by convention the first IP. Call -this `NODE_X_BRIDGE_ADDR`. For example, if `NODE_X_POD_CIDR` is `10.0.0.0/16`, -then `NODE_X_BRIDGE_ADDR` is `10.0.0.1/16`. NOTE: this retains the `/16` suffix -because of how this is used later. - -- Recommended, automatic approach: - 1. Set `--configure-cbr0=true` option in kubelet init script and restart kubelet service. Kubelet will configure cbr0 automatically. - It will wait to do this until the node controller has set Node.Spec.PodCIDR. Since you have not setup apiserver and node controller - yet, the bridge will not be setup immediately. -- Alternate, manual approach: - 1. Set `--configure-cbr0=false` on kubelet and restart. - 1. Create a bridge - - e.g. `brctl addbr cbr0`. - 1. Set appropriate MTU - - `ip link set dev cbr0 mtu 1460` (NOTE: the actual value of MTU will depend on your network environment) - 1. Add the clusters network to the bridge (docker will go on other side of bridge). - - e.g. `ip addr add $NODE_X_BRIDGE_ADDR dev eth0` - 1. Turn it on - - e.g. `ip link set dev cbr0 up` - -If you have turned off Docker's IP masquerading to allow pods to talk to each -other, then you may need to do masquerading just for destination IPs outside -the cluster network. For example: - -```sh -iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE \! -d ${CLUSTER_SUBNET} -``` - -This will rewrite the source address from -the PodIP to the Node IP for traffic bound outside the cluster, and kernel -[connection tracking](http://www.iptables.info/en/connection-state.html) -will ensure that responses destined to the node still reach -the pod. - -NOTE: This is environment specific. Some environments will not need -any masquerading at all. Others, such as GCE, will not allow pod IPs to send -traffic to the internet, but have no problem with them inside your GCE Project. - -### Other - -- Enable auto-upgrades for your OS package manager, if desired. -- Configure log rotation for all node components (e.g. using [logrotate](http://linux.die.net/man/8/logrotate)). -- Setup liveness-monitoring (e.g. using [monit](http://linux.die.net/man/1/monit)). -- Setup volume plugin support (optional) - - Install any client binaries for optional volume types, such as `glusterfs-client` for GlusterFS - volumes. - -### Using Configuration Management - -The previous steps all involved "conventional" system administration techniques for setting up -machines. You may want to use a Configuration Management system to automate the node configuration -process. There are examples of [Saltstack](../admin/salt.md), Ansible, Juju, and CoreOS Cloud Config in the -various Getting Started Guides. - -## Bootstrapping the Cluster - -While the basic node services (kubelet, kube-proxy, docker) are typically started and managed using -traditional system administration/automation approaches, the remaining *master* components of Kubernetes are -all configured and managed *by Kubernetes*: - - their options are specified in a Pod spec (yaml or json) rather than an /etc/init.d file or - systemd unit. - - they are kept running by Kubernetes rather than by init. - -### etcd - -You will need to run one or more instances of etcd. - - Recommended approach: run one etcd instance, with its log written to a directory backed - by durable storage (RAID, GCE PD) - - Alternative: run 3 or 5 etcd instances. - - Log can be written to non-durable storage because storage is replicated. - - run a single apiserver which connects to one of the etc nodes. - See [cluster-troubleshooting](../admin/cluster-troubleshooting.md) for more discussion on factors affecting cluster -availability. - -To run an etcd instance: -1. copy `cluster/saltbase/salt/etcd/etcd.manifest` -1. make any modifications needed -1. start the pod by putting it into the kubelet manifest directory - -### Apiserver, Controller Manager, and Scheduler - -The apiserver, controller manager, and scheduler will each run as a pod on the master node. - -For each of these components, the steps to start them running are similar: - -1. Start with a provided template for a pod. -1. Set the `APISERVER_IMAGE`, `CNTRLMNGR_IMAGE`, and `SCHEDULER_IMAGE to the values chosen in [Selecting Images](#selecting-images). -1. Determine which flags are needed for your cluster, using the advice below each template. -1. Set the `APISERVER_FLAGS`, `CNTRLMNGR_FLAGS, and `SCHEDULER_FLAGS` to the space-separated list of flags for that component. -1. Start the pod by putting the completed template into the kubelet manifest directory. -1. Verify that the pod is started. - -#### Apiserver pod template - -```json -{ - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "kube-apiserver" - }, - "spec": { - "hostNetwork": true, - "containers": [ - { - "name": "kube-apiserver", - "image": "${APISERVER_IMAGE}", - "command": [ - "/bin/sh", - "-c", - "/usr/local/bin/kube-apiserver $APISERVER_FLAGS" - ], - "ports": [ - { - "name": "https", - "hostPort": 443, - "containerPort": 443 - }, - { - "name": "local", - "hostPort": 8080, - "containerPort": 8080 - } - ], - "volumeMounts": [ - { - "name": "srvkube", - "mountPath": "/srv/kubernetes", - "readOnly": true - }, - { - "name": "etcssl", - "mountPath": "/etc/ssl", - "readOnly": true - } - ], - "livenessProbe": { - "httpGet": { - "path": "/healthz", - "port": 8080 - }, - "initialDelaySeconds": 15, - "timeoutSeconds": 15 - } - } - ], - "volumes": [ - { - "name": "srvkube", - "hostPath": { - "path": "/srv/kubernetes" - } - }, - { - "name": "etcssl", - "hostPath": { - "path": "/etc/ssl" - } - } - ] - } -} -``` - -Here are some apiserver flags you may need to set: - -- `--cloud-provider=` see [cloud providers](#cloud-providers) -- `--cloud-config=` see [cloud providers](#cloud-providers) -- `--address=${MASTER_IP}` *or* `--bind-address=127.0.0.1` and `--address=127.0.0.1` if you want to run a proxy on the master node. -- `--cluster-name=$CLUSTER_NAME` -- `--service-cluster-ip-range=$SERVICE_CLUSTER_IP_RANGE` -- `--etcd-servers=http://127.0.0.1:4001` -- `--tls-cert-file=/srv/kubernetes/server.cert` -- `--tls-private-key-file=/srv/kubernetes/server.key` -- `--admission-control=$RECOMMENDED_LIST` - - See [admission controllers](../admin/admission-controllers.md) for recommended arguments. -- `--allow-privileged=true`, only if you trust your cluster user to run pods as root. - -If you are following the firewall-only security approach, then use these arguments: - -- `--token-auth-file=/dev/null` -- `--insecure-bind-address=$MASTER_IP` -- `--advertise-address=$MASTER_IP` - -If you are using the HTTPS approach, then set: -- `--client-ca-file=/srv/kubernetes/ca.crt` -- `--token-auth-file=/srv/kubernetes/known_tokens.csv` -- `--basic-auth-file=/srv/kubernetes/basic_auth.csv` - -This pod mounts several node file system directories using the `hostPath` volumes. Their purposes are: -- The `/etc/ssl` mount allows the apiserver to find the SSL root certs so it can - authenticate external services, such as a cloud provider. - - This is not required if you do not use a cloud provider (e.g. bare-metal). -- The `/srv/kubernetes` mount allows the apiserver to read certs and credentials stored on the - node disk. These could instead be stored on a persistend disk, such as a GCE PD, or baked into the image. -- Optionally, you may want to mount `/var/log` as well and redirect output there (not shown in template). - - Do this if you prefer your logs to be accessible from the root filesystem with tools like journalctl. - -*TODO* document proxy-ssh setup. - -##### Cloud Providers - -Apiserver supports several cloud providers. - -- options for `--cloud-provider` flag are `aws`, `gce`, `mesos`, `openshift`, `ovirt`, `rackspace`, `vagrant`, or unset. -- unset used for e.g. bare metal setups. -- support for new IaaS is added by contributing code [here](../../pkg/cloudprovider/) - -Some cloud providers require a config file. If so, you need to put config file into apiserver image or mount through hostPath. - -- `--cloud-config=` set if cloud provider requires a config file. -- Used by `aws`, `gce`, `mesos`, `openshift`, `ovirt` and `rackspace`. -- You must put config file into apiserver image or mount through hostPath. -- Cloud config file syntax is [Gcfg](https://code.google.com/p/gcfg/). -- AWS format defined by type [AWSCloudConfig](../../pkg/cloudprovider/aws/aws.go) -- There is a similar type in the corresponding file for other cloud providers. -- GCE example: search for `gce.conf` in [this file](../../cluster/gce/configure-vm.sh) - -#### Scheduler pod template - -Complete this template for the scheduler pod: - -```json - -{ - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "kube-scheduler" - }, - "spec": { - "hostNetwork": true, - "containers": [ - { - "name": "kube-scheduler", - "image": "$SCHEDULER_IMAGE", - "command": [ - "/bin/sh", - "-c", - "/usr/local/bin/kube-scheduler --master=127.0.0.1:8080 $SCHEDULER_FLAGS" - ], - "livenessProbe": { - "httpGet": { - "path": "/healthz", - "port": 10251 - }, - "initialDelaySeconds": 15, - "timeoutSeconds": 15 - } - } - ] - } -} - -``` - -Typically, no additional flags are required for the scheduler. - -Optionally, you may want to mount `/var/log` as well and redirect output there. - -#### Controller Manager Template - -Template for controller manager pod: - -```json - -{ - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "kube-controller-manager" - }, - "spec": { - "hostNetwork": true, - "containers": [ - { - "name": "kube-controller-manager", - "image": "$CNTRLMNGR_IMAGE", - "command": [ - "/bin/sh", - "-c", - "/usr/local/bin/kube-controller-manager $CNTRLMNGR_FLAGS" - ], - "volumeMounts": [ - { - "name": "srvkube", - "mountPath": "/srv/kubernetes", - "readOnly": true - }, - { - "name": "etcssl", - "mountPath": "/etc/ssl", - "readOnly": true - } - ], - "livenessProbe": { - "httpGet": { - "path": "/healthz", - "port": 10252 - }, - "initialDelaySeconds": 15, - "timeoutSeconds": 15 - } - } - ], - "volumes": [ - { - "name": "srvkube", - "hostPath": { - "path": "/srv/kubernetes" - } - }, - { - "name": "etcssl", - "hostPath": { - "path": "/etc/ssl" - } - } - ] - } -} - -``` - -Flags to consider using with controller manager: - - `--cluster-name=$CLUSTER_NAME` - - `--cluster-cidr=` - - *TODO*: explain this flag. - - `--allocate-node-cidrs=` - - *TODO*: explain when you want controller to do this and when you want to do it another way. - - `--cloud-provider=` and `--cloud-config` as described in apiserver section. - - `--service-account-private-key-file=/srv/kubernetes/server.key`, used by the [service account](../user-guide/service-accounts.md) feature. - - `--master=127.0.0.1:8080` - -#### Starting and Verifying Apiserver, Scheduler, and Controller Manager - -Place each completed pod template into the kubelet config dir -(whatever `--config=` argument of kubelet is set to, typically -`/etc/kubernetes/manifests`). The order does not matter: scheduler and -controller manager will retry reaching the apiserver until it is up. - -Use `ps` or `docker ps` to verify that each process has started. For example, verify that kubelet has started a container for the apiserver like this: - -```console -$ sudo docker ps | grep apiserver: -5783290746d5 gcr.io/google_containers/kube-apiserver:e36bf367342b5a80d7467fd7611ad873 "/bin/sh -c '/usr/lo'" 10 seconds ago Up 9 seconds k8s_kube-apiserver.feb145e7_kube-apiserver-kubernetes-master_default_eaebc600cf80dae59902b44225f2fc0a_225a4695 -``` - -Then try to connect to the apiserver: - -```console -$ echo $(curl -s http://localhost:8080/healthz) -ok -$ curl -s http://localhost:8080/api -{ - "versions": [ - "v1" - ] -} -``` - -If you have selected the `--register-node=true` option for kubelets, they will now begin self-registering with the apiserver. -You should soon be able to see all your nodes by running the `kubect get nodes` command. -Otherwise, you will need to manually create node objects. - -### Logging - -**TODO** talk about starting Logging. - -### Monitoring - -**TODO** talk about starting Logging. - -### DNS - -**TODO** talk about starting DNS. - -## Troubleshooting - -### Running validate-cluster - -**TODO** explain how to use `cluster/validate-cluster.sh` - -### Inspect pods and services - -Try to run through the "Inspect your cluster" section in one of the other Getting Started Guides, such as [GCE](gce.md#inspect-your-cluster). -You should see some services. You should also see "mirror pods" for the apiserver, scheduler and controller-manager, plus any add-ons you started. - -### Try Examples - -At this point you should be able to run through one of the basic examples, such as the [nginx example](../../examples/simple-nginx.md). - -### Running the Conformance Test - -You may want to try to run the [Conformance test](http://releases.k8s.io/HEAD/hack/conformance-test.sh). Any failures may give a hint as to areas that need more attention. - -### Networking - -The nodes must be able to connect to each other using their private IP. Verify this by -pinging or SSH-ing from one node to another. - -### Getting Help - -If you run into trouble, please see the section on [troubleshooting](gce.md#troubleshooting), post to the -[google-containers group](https://groups.google.com/forum/#!forum/google-containers), or come ask questions on IRC at [#google-containers](http://webchat.freenode.net/?channels=google-containers) on freenode. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/scratch.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/ubuntu-calico.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/ubuntu-calico.md deleted file mode 100644 index 2019320d2976..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/ubuntu-calico.md +++ /dev/null @@ -1,290 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/ubuntu-calico.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Kubernetes Deployment On Bare-metal Ubuntu Nodes with Calico Networking ------------------------------------------------- - -## Introduction - -This document describes how to deploy Kubernetes on ubuntu bare metal nodes with Calico Networking plugin. See [projectcalico.org](http://projectcalico.org) for more information on what Calico is, and [the calicoctl github](https://github.com/Metaswitch/calico-docker) for more information on the command-line tool, `calicoctl`. - -This guide will set up a simple Kubernetes cluster with a master and two nodes. We will start the following processes with systemd: - -On the Master: -- `etcd` -- `kube-apiserver` -- `kube-controller-manager` -- `kube-scheduler` -- `calico-node` - -On each Node: -- `kube-proxy` -- `kube-kubelet` -- `calico-node` - -## Prerequisites - -1. This guide uses `systemd` and thus uses Ubuntu 15.04 which supports systemd natively. -2. All Kubernetes nodes should have the latest docker stable version installed. At the time of writing, that is Docker 1.7.0. -3. All hosts should be able to communicate with each other, as well as the internet, to download the necessary files. -4. This demo assumes that none of the hosts have been configured with any Kubernetes or Calico software yet. - -## Setup Master - -First, get the sample configurations for this tutorial - -``` -wget https://github.com/Metaswitch/calico-kubernetes-ubuntu-demo/archive/master.tar.gz -tar -xvf master.tar.gz -``` - -### Setup environment variables for systemd services on Master - -Many of the sample systemd services provided rely on environment variables on a per-node basis. Here we'll edit those environment variables and move them into place. - -1.) Copy the network-environment-template from the `master` directory for editing. - -``` -cp calico-kubernetes-ubuntu-demo-master/master/network-environment-template network-environment -``` - -2.) Edit `network-environment` to represent your current host's settings. - -3.) Move the `network-environment` into `/etc` - -``` -sudo mv -f network-environment /etc -``` - -### Install Kubernetes on Master - -1.) Build & Install Kubernetes binaries - -``` -# Get the Kubernetes Source -wget https://k8s.io/kubernetes/releases/download/v0.20.2/kubernetes.tar.gz - -# Untar it -tar -xf kubernetes.tar.gz -tar -xf kubernetes/server/kubernetes-server-linux-amd64.tar.gz -kubernetes/cluster/ubuntu/build.sh - -# Add binaries to /usr/bin -sudo cp -f binaries/master/* /usr/bin -sudo cp -f binaries/kubectl /usr/bin -``` - -2.) Install the sample systemd processes settings for launching kubernetes services - -``` -sudo cp -f calico-kubernetes-ubuntu-demo-master/master/*.service /etc/systemd -sudo systemctl enable /etc/systemd/etcd.service -sudo systemctl enable /etc/systemd/kube-apiserver.service -sudo systemctl enable /etc/systemd/kube-controller-manager.service -sudo systemctl enable /etc/systemd/kube-scheduler.service -``` - -3.) Launch the processes. - -``` -sudo systemctl start etcd.service -sudo systemctl start kube-apiserver.service -sudo systemctl start kube-controller-manager.service -sudo systemctl start kube-scheduler.service -``` - -> *You may want to consider checking their status after to ensure everything is running.* - -### Install Calico on Master - -In order to allow the master to route to pods on our nodes, we will launch the calico-node daemon on our master. This will allow it to learn routes over BGP from the other calico-node daemons in the cluster. The docker daemon should already be running before calico is started. - -``` -# Install the calicoctl binary, which will be used to launch calico -wget https://github.com/Metaswitch/calico-docker/releases/download/v0.5.1/calicoctl -chmod +x calicoctl -sudo cp -f calicoctl /usr/bin - -# Install and start the calico service -sudo cp -f calico-kubernetes-ubuntu-demo-master/master/calico-node.service /etc/systemd -sudo systemctl enable /etc/systemd/calico-node.service -sudo systemctl start calico-node.service -``` - ->Note: calico-node may take a few minutes on first boot while it downloads the calico-node docker image. - -## Setup Nodes - -Perform these steps **once on each node**, ensuring you appropriately set the environment variables on each node - -### Setup environment variables for systemd services on the Node - -1.) Get the sample configurations for this tutorial - -``` -wget https://github.com/Metaswitch/calico-kubernetes-ubuntu-demo/archive/master.tar.gz -tar -xvf master.tar.gz -``` - -2.) Copy the network-environment-template from the `node` directory - -``` -cp calico-kubernetes-ubuntu-demo-master/node/network-environment-template network-environment -``` - -3.) Edit `network-environment` to represent your current host's settings. - -4.) Move `netework-environment` into `/etc` - -``` -sudo mv -f network-environment /etc -``` - -### Configure Docker on the Node - -#### Create the veth - -Instead of using docker's default interface (docker0), we will configure a new one to use desired IP ranges - -``` -sudo brctl addbr cbr0 -sudo ifconfig cbr0 up -sudo ifconfig cbr0 /24 -``` - -> Replace \ with the subnet for this host's containers. Example topology: - - Node | cbr0 IP --------- | ------------- -node-1 | 192.168.1.1/24 -node-2 | 192.168.2.1/24 -node-X | 192.168.X.1/24 - -#### Start docker on cbr0 - -The Docker daemon must be started and told to use the already configured cbr0 instead of using the usual docker0, as well as disabling ip-masquerading and modification of the ip-tables. - -1.) Edit the ubuntu-15.04 docker.service for systemd at: `/lib/systemd/system/docker.service` - -2.) Find the line that reads `ExecStart=/usr/bin/docker -d -H fd://` and append the following flags: `--bridge=cbr0 --iptables=false --ip-masq=false` - -3.) Reload systemctl with `sudo systemctl daemon-reload` - -4.) Restart docker with with `sudo systemctl restart docker` - -### Install Calico on the Node - -1.) Install Calico - -``` -# Get the calicoctl binary -wget https://github.com/Metaswitch/calico-docker/releases/download/v0.5.1/calicoctl -chmod +x calicoctl -sudo cp -f calicoctl /usr/bin - -# Start calico on this node -sudo cp calico-kubernetes-ubuntu-demo-master/node/calico-node.service /etc/systemd -sudo systemctl enable /etc/systemd/calico-node.service -sudo systemctl start calico-node.service -``` - ->The calico-node service will automatically get the kubernetes-calico plugin binary and install it on the host system. - -2.) Use calicoctl to add an IP pool. We must specify the IP and port that the master's etcd is listening on. -**NOTE: This step only needs to be performed once per Kubernetes deployment, as it covers all the node's IP ranges.** - -``` -ETCD_AUTHORITY=:4001 calicoctl pool add 192.168.0.0/16 -``` - -### Install Kubernetes on the Node - -1.) Build & Install Kubernetes binaries - -``` -# Get the Kubernetes Source -wget https://k8s.io/kubernetes/releases/download/v0.20.2/kubernetes.tar.gz - -# Untar it -tar -xf kubernetes.tar.gz -tar -xf kubernetes/server/kubernetes-server-linux-amd64.tar.gz -kubernetes/cluster/ubuntu/build.sh - -# Add binaries to /usr/bin -sudo cp -f binaries/minion/* /usr/bin -``` - -2.) Install and launch the sample systemd processes settings for launching Kubernetes services - -``` -sudo cp calico-kubernetes-ubuntu-demo-master/node/kube-proxy.service /etc/systemd/ -sudo cp calico-kubernetes-ubuntu-demo-master/node/kube-kubelet.service /etc/systemd/ -sudo systemctl enable /etc/systemd/kube-proxy.service -sudo systemctl enable /etc/systemd/kube-kubelet.service -sudo systemctl start kube-proxy.service -sudo systemctl start kube-kubelet.service -``` - ->*You may want to consider checking their status after to ensure everything is running* - -## Launch other Services With Calico-Kubernetes - -At this point, you have a fully functioning cluster running on kubernetes with a master and 2 nodes networked with Calico. You can now follow any of the [standard documentation](../../examples/) to set up other services on your cluster. - -## Connectivity to outside the cluster - -With this sample configuration, because the containers have private `192.168.0.0/16` IPs, you will need NAT to allow connectivity between containers and the internet. However, in a full datacenter deployment, NAT is not always necessary, since Calico can peer with the border routers over BGP. - -### NAT on the nodes - -The simplest method for enabling connectivity from containers to the internet is to use an iptables masquerade rule. This is the standard mechanism [recommended](../../docs/admin/networking.md#google-compute-engine-gce) in the Kubernetes GCE environment. - -We need to NAT traffic that has a destination outside of the cluster. Internal traffic includes the master/nodes, and the container IP pools. Assuming that the master and nodes are in the `172.25.0.0/24` subnet, the cbr0 IP ranges are all in the `192.168.0.0/16` network, and the nodes use the interface `eth0` for external connectivity, a suitable masquerade chain would look like this: - -``` -sudo iptables -t nat -N KUBE-OUTBOUND-NAT -sudo iptables -t nat -A KUBE-OUTBOUND-NAT -d 192.168.0.0/16 -o eth0 -j RETURN -sudo iptables -t nat -A KUBE-OUTBOUND-NAT -d 172.25.0.0/24 -o eth0 -j RETURN -sudo iptables -t nat -A KUBE-OUTBOUND-NAT -j MASQUERADE -sudo iptables -t nat -A POSTROUTING -j KUBE-OUTBOUND-NAT -``` - -This chain should be applied on the master and all nodes. In production, these rules should be persisted, e.g. with `iptables-persistent`. - -### NAT at the border router - -In a datacenter environment, it is recommended to configure Calico to peer with the border routers over BGP. This means that the container IPs will be routable anywhere in the datacenter, and so NAT is not needed on the nodes (though it may be enabled at the datacenter edge to allow outbound-only internet connectivity). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/ubuntu-calico.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/ubuntu.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/ubuntu.md deleted file mode 100644 index 1bd40bcae07d..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/ubuntu.md +++ /dev/null @@ -1,224 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/ubuntu.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Kubernetes Deployment On Bare-metal Ubuntu Nodes ------------------------------------------------- - -- [Introduction](#introduction) -- [Prerequisites](#prerequisites) - - [Starting a Cluster](#starting-a-cluster) - - [Make *kubernetes* , *etcd* and *flanneld* binaries](#make-kubernetes--etcd-and-flanneld-binaries) - - [Configure and start the Kubernetes cluster](#configure-and-start-the-kubernetes-cluster) - - [Deploy addons](#deploy-addons) - - [Trouble Shooting](#trouble-shooting) - -## Introduction - -This document describes how to deploy Kubernetes on ubuntu nodes, including 1 Kubernetes master and 3 Kubernetes nodes, and people uses this approach can scale to **any number of nodes** by changing some settings with ease. The original idea was heavily inspired by @jainvipin 's ubuntu single node work, which has been merge into this document. - -[Cloud team from Zhejiang University](https://github.com/ZJU-SEL) will maintain this work. - -## Prerequisites - -*1 The nodes have installed docker version 1.2+ and bridge-utils to manipulate linux bridge* - -*2 All machines can communicate with each other, no need to connect Internet (should use private docker registry in this case)* - -*3 These guide is tested OK on Ubuntu 14.04 LTS 64bit server, but it can not work with Ubuntu 15 which use systemd instead of upstart and we are fixing this* - -*4 Dependencies of this guide: etcd-2.0.12, flannel-0.4.0, k8s-1.0.1, but it may work with higher versions* - -*5 All the remote servers can be ssh logged in without a password by using key authentication* - - -### Starting a Cluster - -#### Make *kubernetes* , *etcd* and *flanneld* binaries - -First clone the kubernetes github repo, `$ git clone https://k8s.io/kubernetes.git` - -then `$ cd kubernetes/cluster/ubuntu`. - -Then run `$ ./build.sh`, this will download all the needed binaries into `./binaries`. - -You can customize your etcd version, flannel version, k8s version by changing variable `ETCD_VERSION` , `FLANNEL_VERSION` and `K8S_VERSION` in build.sh, default etcd version is 2.0.12, flannel version is 0.4.0 and K8s version is 1.0.1. - -Please make sure that there are `kube-apiserver`, `kube-controller-manager`, `kube-scheduler`, `kubelet`, `kube-proxy`, `etcd`, `etcdctl` and `flannel` in the binaries/master or binaries/minion directory. - -> We used flannel here because we want to use overlay network, but please remember it is not the only choice, and it is also not a k8s' necessary dependence. Actually you can just build up k8s cluster natively, or use flannel, Open vSwitch or any other SDN tool you like, we just choose flannel here as an example. - -#### Configure and start the Kubernetes cluster - -An example cluster is listed as below: - -| IP Address|Role | -|---------|------| -|10.10.103.223| node | -|10.10.103.162| node | -|10.10.103.250| both master and node| - -First configure the cluster information in cluster/ubuntu/config-default.sh, below is a simple sample. - -```sh -export nodes="vcap@10.10.103.250 vcap@10.10.103.162 vcap@10.10.103.223" - -export role="ai i i" - -export NUM_MINIONS=${NUM_MINIONS:-3} - -export SERVICE_CLUSTER_IP_RANGE=192.168.3.0/24 - -export FLANNEL_NET=172.16.0.0/16 -``` - -The first variable `nodes` defines all your cluster nodes, MASTER node comes first and separated with blank space like ` ` - -Then the `roles ` variable defines the role of above machine in the same order, "ai" stands for machine acts as both master and node, "a" stands for master, "i" stands for node. So they are just defined the k8s cluster as the table above described. - -The `NUM_MINIONS` variable defines the total number of nodes. - -The `SERVICE_CLUSTER_IP_RANGE` variable defines the Kubernetes service IP range. Please make sure that you do have a valid private ip range defined here, because some IaaS provider may reserve private ips. You can use below three private network range according to rfc1918. Besides you'd better not choose the one that conflicts with your own private network range. - - 10.0.0.0 - 10.255.255.255 (10/8 prefix) - - 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) - - 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) - -The `FLANNEL_NET` variable defines the IP range used for flannel overlay network, should not conflict with above `SERVICE_CLUSTER_IP_RANGE`. - -After all the above variables being set correctly, we can use following command in cluster/ directory to bring up the whole cluster. - -`$ KUBERNETES_PROVIDER=ubuntu ./kube-up.sh` - -The scripts automatically scp binaries and config files to all the machines and start the k8s service on them. The only thing you need to do is to type the sudo password when promoted. The current machine name is shown below, so you will not type in the wrong password. - -```console -Deploying minion on machine 10.10.103.223 - -... - -[sudo] password to copy files and start minion: -``` - -If all things goes right, you will see the below message from console -`Cluster validation succeeded` indicating the k8s is up. - -**All done !** - -You can also use `kubectl` command to see if the newly created k8s is working correctly. The `kubectl` binary is under the `cluster/ubuntu/binaries` directory. You can move it into your PATH. Then you can use the below command smoothly. - -For example, use `$ kubectl get nodes` to see if all your nodes are in ready status. It may take some time for the nodes ready to use like below. - -```console -NAME LABELS STATUS - -10.10.103.162 kubernetes.io/hostname=10.10.103.162 Ready - -10.10.103.223 kubernetes.io/hostname=10.10.103.223 Ready - -10.10.103.250 kubernetes.io/hostname=10.10.103.250 Ready -``` - -Also you can run Kubernetes [guest-example](../../examples/guestbook/) to build a redis backend cluster on the k8s. - - -#### Deploy addons - -After the previous parts, you will have a working k8s cluster, this part will teach you how to deploy addons like dns onto the existing cluster. - -The configuration of dns is configured in cluster/ubuntu/config-default.sh. - -```sh -ENABLE_CLUSTER_DNS="${KUBE_ENABLE_CLUSTER_DNS:-true}" - -DNS_SERVER_IP="192.168.3.10" - -DNS_DOMAIN="cluster.local" - -DNS_REPLICAS=1 -``` - -The `DNS_SERVER_IP` is defining the ip of dns server which must be in the service_cluster_ip_range. - -The `DNS_REPLICAS` describes how many dns pod running in the cluster. - -After all the above variable have been set. Just type the below command - -```console -$ cd cluster/ubuntu - -$ KUBERNETES_PROVIDER=ubuntu ./deployAddons.sh -``` - -After some time, you can use `$ kubectl get pods` to see the dns pod is running in the cluster. Done! - -#### On going - -We are working on these features which we'd like to let everybody know: - -1. Run Kubernetes binaries in Docker using [kube-in-docker](https://github.com/ZJU-SEL/kube-in-docker/tree/baremetal-kube), to eliminate OS-distro differences. - -2. Tearing Down scripts: clear and re-create the whole stack by one click. - -#### Trouble Shooting - -Generally, what this approach did is quite simple: - -1. Download and copy binaries and configuration files to proper directories on every node - -2. Configure `etcd` using IPs based on input from user - -3. Create and start flannel network - -So, if you see a problem, **check etcd configuration first** - -Please try: - -1. Check `/var/log/upstart/etcd.log` for suspicious etcd log - -2. Check `/etc/default/etcd`, as we do not have much input validation, a right config should be like: - - ```sh - ETCD_OPTS="-name infra1 -initial-advertise-peer-urls -listen-peer-urls -initial-cluster-token etcd-cluster-1 -initial-cluster infra1=,infra2=,infra3= -initial-cluster-state new" - ``` - -3. You can use below command - `$ KUBERNETES_PROVIDER=ubuntu ./kube-down.sh` to bring down the cluster and run - `$ KUBERNETES_PROVIDER=ubuntu ./kube-up.sh` again to start again. - -4. You can also customize your own settings in `/etc/default/{component_name}` after configured success. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/ubuntu.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/vagrant.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/vagrant.md deleted file mode 100644 index f4a831f07b93..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/vagrant.md +++ /dev/null @@ -1,391 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/vagrant.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Getting started with Vagrant - -Running Kubernetes with Vagrant (and VirtualBox) is an easy way to run/test/develop on your local machine (Linux, Mac OS X). - -**Table of Contents** - -- [Prerequisites](#prerequisites) -- [Setup](#setup) -- [Interacting with your Kubernetes cluster with Vagrant.](#interacting-with-your-kubernetes-cluster-with-vagrant) -- [Authenticating with your master](#authenticating-with-your-master) -- [Running containers](#running-containers) -- [Troubleshooting](#troubleshooting) - - [I keep downloading the same (large) box all the time!](#i-keep-downloading-the-same-large-box-all-the-time) - - [I just created the cluster, but I am getting authorization errors!](#i-just-created-the-cluster-but-i-am-getting-authorization-errors) - - [I just created the cluster, but I do not see my container running!](#i-just-created-the-cluster-but-i-do-not-see-my-container-running) - - [I want to make changes to Kubernetes code!](#i-want-to-make-changes-to-kubernetes-code) - - [I have brought Vagrant up but the nodes cannot validate!](#i-have-brought-vagrant-up-but-the-nodes-cannot-validate) - - [I want to change the number of nodes!](#i-want-to-change-the-number-of-nodes) - - [I want my VMs to have more memory!](#i-want-my-vms-to-have-more-memory) - - [I ran vagrant suspend and nothing works!](#i-ran-vagrant-suspend-and-nothing-works) - - [I want vagrant to sync folders via nfs!](#i-want-vagrant-to-sync-folders-via-nfs) - -### Prerequisites - -1. Install latest version >= 1.6.2 of vagrant from http://www.vagrantup.com/downloads.html -2. Install one of: - 1. Version 4.3.28 of Virtual Box from https://www.virtualbox.org/wiki/Download_Old_Builds_4_3 - 2. [VMWare Fusion](https://www.vmware.com/products/fusion/) version 5 or greater as well as the appropriate [Vagrant VMWare Fusion provider](https://www.vagrantup.com/vmware) - 3. [VMWare Workstation](https://www.vmware.com/products/workstation/) version 9 or greater as well as the [Vagrant VMWare Workstation provider](https://www.vagrantup.com/vmware) - 4. [Parallels Desktop](https://www.parallels.com/products/desktop/) version 9 or greater as well as the [Vagrant Parallels provider](https://parallels.github.io/vagrant-parallels/) - 5. libvirt with KVM and enable support of hardware virtualisation. [Vagrant-libvirt](https://github.com/pradels/vagrant-libvirt). For fedora provided official rpm, and possible to use `yum install vagrant-libvirt` - -### Setup - -Setting up a cluster is as simple as running: - -```sh -export KUBERNETES_PROVIDER=vagrant -curl -sS https://get.k8s.io | bash -``` - -Alternatively, you can download [Kubernetes release](https://k8s.io/kubernetes/releases) and extract the archive. To start your local cluster, open a shell and run: - -```sh -cd kubernetes - -export KUBERNETES_PROVIDER=vagrant -./cluster/kube-up.sh -``` - -The `KUBERNETES_PROVIDER` environment variable tells all of the various cluster management scripts which variant to use. If you forget to set this, the assumption is you are running on Google Compute Engine. - -By default, the Vagrant setup will create a single master VM (called kubernetes-master) and one node (called kubernetes-minion-1). Each VM will take 1 GB, so make sure you have at least 2GB to 4GB of free memory (plus appropriate free disk space). - -Vagrant will provision each machine in the cluster with all the necessary components to run Kubernetes. The initial setup can take a few minutes to complete on each machine. - -If you installed more than one Vagrant provider, Kubernetes will usually pick the appropriate one. However, you can override which one Kubernetes will use by setting the [`VAGRANT_DEFAULT_PROVIDER`](https://docs.vagrantup.com/v2/providers/default.html) environment variable: - -```sh -export VAGRANT_DEFAULT_PROVIDER=parallels -export KUBERNETES_PROVIDER=vagrant -./cluster/kube-up.sh -``` - -By default, each VM in the cluster is running Fedora. - -To access the master or any node: - -```sh -vagrant ssh master -vagrant ssh minion-1 -``` - -If you are running more than one node, you can access the others by: - -```sh -vagrant ssh minion-2 -vagrant ssh minion-3 -``` - -Each node in the cluster installs the docker daemon and the kubelet. - -The master node instantiates the Kubernetes master components as pods on the machine. - -To view the service status and/or logs on the kubernetes-master: - -```console -[vagrant@kubernetes-master ~] $ vagrant ssh master -[vagrant@kubernetes-master ~] $ sudo su - -[root@kubernetes-master ~] $ systemctl status kubelet -[root@kubernetes-master ~] $ journalctl -ru kubelet - -[root@kubernetes-master ~] $ systemctl status docker -[root@kubernetes-master ~] $ journalctl -ru docker - -[root@kubernetes-master ~] $ tail -f /var/log/kube-apiserver.log -[root@kubernetes-master ~] $ tail -f /var/log/kube-controller-manager.log -[root@kubernetes-master ~] $ tail -f /var/log/kube-scheduler.log -``` - -To view the services on any of the nodes: - -```console -[vagrant@kubernetes-master ~] $ vagrant ssh minion-1 -[vagrant@kubernetes-master ~] $ sudo su - -[root@kubernetes-master ~] $ systemctl status kubelet -[root@kubernetes-master ~] $ journalctl -ru kubelet - -[root@kubernetes-master ~] $ systemctl status docker -[root@kubernetes-master ~] $ journalctl -ru docker -``` - -### Interacting with your Kubernetes cluster with Vagrant. - -With your Kubernetes cluster up, you can manage the nodes in your cluster with the regular Vagrant commands. - -To push updates to new Kubernetes code after making source changes: - -```sh -./cluster/kube-push.sh -``` - -To stop and then restart the cluster: - -```sh -vagrant halt -./cluster/kube-up.sh -``` - -To destroy the cluster: - -```sh -vagrant destroy -``` - -Once your Vagrant machines are up and provisioned, the first thing to do is to check that you can use the `kubectl.sh` script. - -You may need to build the binaries first, you can do this with `make` - -```console -$ ./cluster/kubectl.sh get nodes - -NAME LABELS -10.245.1.4 -10.245.1.5 -10.245.1.3 -``` - -### Authenticating with your master - -When using the vagrant provider in Kubernetes, the `cluster/kubectl.sh` script will cache your credentials in a `~/.kubernetes_vagrant_auth` file so you will not be prompted for them in the future. - -```sh -cat ~/.kubernetes_vagrant_auth -``` - -```json -{ "User": "vagrant", - "Password": "vagrant", - "CAFile": "/home/k8s_user/.kubernetes.vagrant.ca.crt", - "CertFile": "/home/k8s_user/.kubecfg.vagrant.crt", - "KeyFile": "/home/k8s_user/.kubecfg.vagrant.key" -} -``` - -You should now be set to use the `cluster/kubectl.sh` script. For example try to list the nodes that you have started with: - -```sh -./cluster/kubectl.sh get nodes -``` - -### Running containers - -Your cluster is running, you can list the nodes in your cluster: - -```console -$ ./cluster/kubectl.sh get nodes - -NAME LABELS -10.245.2.4 -10.245.2.3 -10.245.2.2 -``` - -Now start running some containers! - -You can now use any of the `cluster/kube-*.sh` commands to interact with your VM machines. -Before starting a container there will be no pods, services and replication controllers. - -```console -$ ./cluster/kubectl.sh get pods -NAME READY STATUS RESTARTS AGE - -$ ./cluster/kubectl.sh get services -NAME LABELS SELECTOR IP(S) PORT(S) - -$ ./cluster/kubectl.sh get replicationcontrollers -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -``` - -Start a container running nginx with a replication controller and three replicas - -```console -$ ./cluster/kubectl.sh run my-nginx --image=nginx --replicas=3 --port=80 -``` - -When listing the pods, you will see that three containers have been started and are in Waiting state: - -```console -$ ./cluster/kubectl.sh get pods -NAME READY STATUS RESTARTS AGE -my-nginx-5kq0g 0/1 Pending 0 10s -my-nginx-gr3hh 0/1 Pending 0 10s -my-nginx-xql4j 0/1 Pending 0 10s -``` - -You need to wait for the provisioning to complete, you can monitor the nodes by doing: - -```console -$ vagrant ssh minion-1 -c 'sudo docker images' -kubernetes-minion-1: - REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE - 96864a7d2df3 26 hours ago 204.4 MB - google/cadvisor latest e0575e677c50 13 days ago 12.64 MB - kubernetes/pause latest 6c4579af347b 8 weeks ago 239.8 kB -``` - -Once the docker image for nginx has been downloaded, the container will start and you can list it: - -```console -$ vagrant ssh minion-1 -c 'sudo docker ps' -kubernetes-minion-1: - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - dbe79bf6e25b nginx:latest "nginx" 21 seconds ago Up 19 seconds k8s--mynginx.8c5b8a3a--7813c8bd_-_3ffe_-_11e4_-_9036_-_0800279696e1.etcd--7813c8bd_-_3ffe_-_11e4_-_9036_-_0800279696e1--fcfa837f - fa0e29c94501 kubernetes/pause:latest "/pause" 8 minutes ago Up 8 minutes 0.0.0.0:8080->80/tcp k8s--net.a90e7ce4--7813c8bd_-_3ffe_-_11e4_-_9036_-_0800279696e1.etcd--7813c8bd_-_3ffe_-_11e4_-_9036_-_0800279696e1--baf5b21b - aa2ee3ed844a google/cadvisor:latest "/usr/bin/cadvisor" 38 minutes ago Up 38 minutes k8s--cadvisor.9e90d182--cadvisor_-_agent.file--4626b3a2 - 65a3a926f357 kubernetes/pause:latest "/pause" 39 minutes ago Up 39 minutes 0.0.0.0:4194->8080/tcp k8s--net.c5ba7f0e--cadvisor_-_agent.file--342fd561 -``` - -Going back to listing the pods, services and replicationcontrollers, you now have: - -```console -$ ./cluster/kubectl.sh get pods -NAME READY STATUS RESTARTS AGE -my-nginx-5kq0g 1/1 Running 0 1m -my-nginx-gr3hh 1/1 Running 0 1m -my-nginx-xql4j 1/1 Running 0 1m - -$ ./cluster/kubectl.sh get services -NAME LABELS SELECTOR IP(S) PORT(S) - -$ ./cluster/kubectl.sh get replicationcontrollers -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -my-nginx my-nginx nginx run=my-nginx 3 -``` - -We did not start any services, hence there are none listed. But we see three replicas displayed properly. -Check the [guestbook](../../examples/guestbook/README.md) application to learn how to create a service. -You can already play with scaling the replicas with: - -```console -$ ./cluster/kubectl.sh scale rc my-nginx --replicas=2 -$ ./cluster/kubectl.sh get pods -NAME READY STATUS RESTARTS AGE -my-nginx-5kq0g 1/1 Running 0 2m -my-nginx-gr3hh 1/1 Running 0 2m -``` - -Congratulations! - -### Troubleshooting - -#### I keep downloading the same (large) box all the time! - -By default the Vagrantfile will download the box from S3. You can change this (and cache the box locally) by providing a name and an alternate URL when calling `kube-up.sh` - -```sh -export KUBERNETES_BOX_NAME=choose_your_own_name_for_your_kuber_box -export KUBERNETES_BOX_URL=path_of_your_kuber_box -export KUBERNETES_PROVIDER=vagrant -./cluster/kube-up.sh -``` - -#### I just created the cluster, but I am getting authorization errors! - -You probably have an incorrect ~/.kubernetes_vagrant_auth file for the cluster you are attempting to contact. - -```sh -rm ~/.kubernetes_vagrant_auth -``` - -After using kubectl.sh make sure that the correct credentials are set: - -```sh -cat ~/.kubernetes_vagrant_auth -``` - -```json -{ - "User": "vagrant", - "Password": "vagrant" -} -``` - -#### I just created the cluster, but I do not see my container running! - -If this is your first time creating the cluster, the kubelet on each node schedules a number of docker pull requests to fetch prerequisite images. This can take some time and as a result may delay your initial pod getting provisioned. - -#### I want to make changes to Kubernetes code! - -To set up a vagrant cluster for hacking, follow the [vagrant developer guide](../devel/developer-guides/vagrant.md). - -#### I have brought Vagrant up but the nodes cannot validate! - -Log on to one of the nodes (`vagrant ssh minion-1`) and inspect the salt minion log (`sudo cat /var/log/salt/minion`). - -#### I want to change the number of nodes! - -You can control the number of nodes that are instantiated via the environment variable `NUM_MINIONS` on your host machine. If you plan to work with replicas, we strongly encourage you to work with enough nodes to satisfy your largest intended replica size. If you do not plan to work with replicas, you can save some system resources by running with a single node. You do this, by setting `NUM_MINIONS` to 1 like so: - -```sh -export NUM_MINIONS=1 -``` - -#### I want my VMs to have more memory! - -You can control the memory allotted to virtual machines with the `KUBERNETES_MEMORY` environment variable. -Just set it to the number of megabytes you would like the machines to have. For example: - -```sh -export KUBERNETES_MEMORY=2048 -``` - -If you need more granular control, you can set the amount of memory for the master and nodes independently. For example: - -```sh -export KUBERNETES_MASTER_MEMORY=1536 -export KUBERNETES_MINION_MEMORY=2048 -``` - -#### I ran vagrant suspend and nothing works! - -`vagrant suspend` seems to mess up the network. This is not supported at this time. - -#### I want vagrant to sync folders via nfs! - -You can ensure that vagrant uses nfs to sync folders with virtual machines by setting the KUBERNETES_VAGRANT_USE_NFS environment variable to 'true'. nfs is faster than virtualbox or vmware's 'shared folders' and does not require guest additions. See the [vagrant docs](http://docs.vagrantup.com/v2/synced-folders/nfs.html) for details on configuring nfs on the host. This setting will have no effect on the libvirt provider, which uses nfs by default. For example: - -```sh -export KUBERNETES_VAGRANT_USE_NFS=true -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/vagrant.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/vsphere.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/vsphere.md deleted file mode 100644 index c409113edd31..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/getting-started-guides/vsphere.md +++ /dev/null @@ -1,125 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/getting-started-guides/vsphere.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Getting started with vSphere -------------------------------- - -The example below creates a Kubernetes cluster with 4 worker node Virtual -Machines and a master Virtual Machine (i.e. 5 VMs in your cluster). This -cluster is set up and controlled from your workstation (or wherever you find -convenient). - -**Table of Contents** - -- [Prerequisites](#prerequisites) -- [Setup](#setup) -- [Starting a cluster](#starting-a-cluster) -- [Extra: debugging deployment failure](#extra-debugging-deployment-failure) - -### Prerequisites - -1. You need administrator credentials to an ESXi machine or vCenter instance. -2. You must have Go (version 1.2 or later) installed: [www.golang.org](http://www.golang.org). -3. You must have your `GOPATH` set up and include `$GOPATH/bin` in your `PATH`. - - ```sh - export GOPATH=$HOME/src/go - mkdir -p $GOPATH - export PATH=$PATH:$GOPATH/bin - ``` - -4. Install the govc tool to interact with ESXi/vCenter: - - ```sh - go get github.com/vmware/govmomi/govc - ``` - -5. Get or build a [binary release](binary_release.md) - -### Setup - -Download a prebuilt Debian 7.7 VMDK that we'll use as a base image: - -```sh -curl --remote-name-all https://storage.googleapis.com/govmomi/vmdk/2014-11-11/kube.vmdk.gz{,.md5} -md5sum -c kube.vmdk.gz.md5 -gzip -d kube.vmdk.gz -``` - -Import this VMDK into your vSphere datastore: - -```sh -export GOVC_URL='user:pass@hostname' -export GOVC_INSECURE=1 # If the host above uses a self-signed cert -export GOVC_DATASTORE='target datastore' -export GOVC_RESOURCE_POOL='resource pool or cluster with access to datastore' - -govc import.vmdk kube.vmdk ./kube/ -``` - -Verify that the VMDK was correctly uploaded and expanded to ~3GiB: - -```sh -govc datastore.ls ./kube/ -``` - -Take a look at the file `cluster/vsphere/config-common.sh` fill in the required -parameters. The guest login for the image that you imported is `kube:kube`. - -### Starting a cluster - -Now, let's continue with deploying Kubernetes. -This process takes about ~10 minutes. - -```sh -cd kubernetes # Extracted binary release OR repository root -export KUBERNETES_PROVIDER=vsphere -cluster/kube-up.sh -``` - -Refer to the top level README and the getting started guide for Google Compute -Engine. Once you have successfully reached this point, your vSphere Kubernetes -deployment works just as any other one! - -**Enjoy!** - -### Extra: debugging deployment failure - -The output of `kube-up.sh` displays the IP addresses of the VMs it deploys. You -can log into any VM as the `kube` user to poke around and figure out what is -going on (find yourself authorized with your SSH key, or use the password -`kube` otherwise). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/getting-started-guides/vsphere.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/.files_generated b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/.files_generated deleted file mode 100644 index 76219f564803..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/.files_generated +++ /dev/null @@ -1,30 +0,0 @@ -kubectl-api-versions.1 -kubectl-attach.1 -kubectl-cluster-info.1 -kubectl-config-set-cluster.1 -kubectl-config-set-context.1 -kubectl-config-set-credentials.1 -kubectl-config-set.1 -kubectl-config-unset.1 -kubectl-config-use-context.1 -kubectl-config-view.1 -kubectl-config.1 -kubectl-create.1 -kubectl-delete.1 -kubectl-describe.1 -kubectl-exec.1 -kubectl-expose.1 -kubectl-get.1 -kubectl-label.1 -kubectl-logs.1 -kubectl-namespace.1 -kubectl-patch.1 -kubectl-port-forward.1 -kubectl-proxy.1 -kubectl-replace.1 -kubectl-rolling-update.1 -kubectl-run.1 -kubectl-scale.1 -kubectl-stop.1 -kubectl-version.1 -kubectl.1 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-api-versions.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-api-versions.1 deleted file mode 100644 index c4212fd1d464..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-api-versions.1 +++ /dev/null @@ -1,130 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl api\-versions \- Print available API versions. - - -.SH SYNOPSIS -.PP -\fBkubectl api\-versions\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Print available API versions. - - -.SH OPTIONS -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for api\-versions - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-attach.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-attach.1 deleted file mode 100644 index 861cfb8b2a73..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-attach.1 +++ /dev/null @@ -1,161 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl attach \- Attach to a running container. - - -.SH SYNOPSIS -.PP -\fBkubectl attach\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Attach to a a process that is already running inside an existing container. - - -.SH OPTIONS -.PP -\fB\-c\fP, \fB\-\-container\fP="" - Container name - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for attach - -.PP -\fB\-i\fP, \fB\-\-stdin\fP=false - Pass stdin to the container - -.PP -\fB\-t\fP, \fB\-\-tty\fP=false - Stdin is a TTY - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// get output from running pod 123456\-7890, using the first container by default -$ kubectl attach 123456\-7890 - -// get output from ruby\-container from pod 123456\-7890 -$ kubectl attach 123456\-7890 \-c ruby\-container date - -// switch to raw terminal mode, sends stdin to 'bash' in ruby\-container from pod 123456\-780 -// and sends stdout/stderr from 'bash' back to the client -$ kubectl attach 123456\-7890 \-c ruby\-container \-i \-t - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-cluster-info.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-cluster-info.1 deleted file mode 100644 index 3f64ae37ab10..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-cluster-info.1 +++ /dev/null @@ -1,130 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl cluster\-info \- Display cluster info - - -.SH SYNOPSIS -.PP -\fBkubectl cluster\-info\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Display addresses of the master and services with label kubernetes.io/cluster\-service=true - - -.SH OPTIONS -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for cluster\-info - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-cluster.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-cluster.1 deleted file mode 100644 index 374e37bbad7c..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-cluster.1 +++ /dev/null @@ -1,153 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl config set\-cluster \- Sets a cluster entry in kubeconfig - - -.SH SYNOPSIS -.PP -\fBkubectl config set\-cluster\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Sets a cluster entry in kubeconfig. -Specifying a name that already exists will merge new fields on top of existing values for those fields. - - -.SH OPTIONS -.PP -\fB\-\-api\-version\fP="" - api\-version for the cluster entry in kubeconfig - -.PP -\fB\-\-certificate\-authority\fP="" - path to certificate\-authority for the cluster entry in kubeconfig - -.PP -\fB\-\-embed\-certs\fP=false - embed\-certs for the cluster entry in kubeconfig - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for set\-cluster - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - insecure\-skip\-tls\-verify for the cluster entry in kubeconfig - -.PP -\fB\-\-server\fP="" - server for the cluster entry in kubeconfig - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-kubeconfig\fP="" - use a particular kubeconfig file - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Set only the server field on the e2e cluster entry without touching other values. -$ kubectl config set\-cluster e2e \-\-server=https://1.2.3.4 - -// Embed certificate authority data for the e2e cluster entry -$ kubectl config set\-cluster e2e \-\-certificate\-authority=\~/.kube/e2e/kubernetes.ca.crt - -// Disable cert checking for the dev cluster entry -$ kubectl config set\-cluster e2e \-\-insecure\-skip\-tls\-verify=true - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl\-config(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-context.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-context.1 deleted file mode 100644 index 4e7928418ed8..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-context.1 +++ /dev/null @@ -1,143 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl config set\-context \- Sets a context entry in kubeconfig - - -.SH SYNOPSIS -.PP -\fBkubectl config set\-context\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Sets a context entry in kubeconfig -Specifying a name that already exists will merge new fields on top of existing values for those fields. - - -.SH OPTIONS -.PP -\fB\-\-cluster\fP="" - cluster for the context entry in kubeconfig - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for set\-context - -.PP -\fB\-\-namespace\fP="" - namespace for the context entry in kubeconfig - -.PP -\fB\-\-user\fP="" - user for the context entry in kubeconfig - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - use a particular kubeconfig file - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Set the user field on the gce context entry without touching other values -$ kubectl config set\-context gce \-\-user=cluster\-admin - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl\-config(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-credentials.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-credentials.1 deleted file mode 100644 index d025d9119d96..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set-credentials.1 +++ /dev/null @@ -1,169 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl config set\-credentials \- Sets a user entry in kubeconfig - - -.SH SYNOPSIS -.PP -\fBkubectl config set\-credentials\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Sets a user entry in kubeconfig -Specifying a name that already exists will merge new fields on top of existing values. - -.PP -Client\-certificate flags: - \-\-client\-certificate=certfile \-\-client\-key=keyfile - -.PP -Bearer token flags: - \-\-token=bearer\_token - -.PP -Basic auth flags: - \-\-username=basic\_user \-\-password=basic\_password - -.PP -Bearer token and basic auth are mutually exclusive. - - -.SH OPTIONS -.PP -\fB\-\-client\-certificate\fP="" - path to client\-certificate for the user entry in kubeconfig - -.PP -\fB\-\-client\-key\fP="" - path to client\-key for the user entry in kubeconfig - -.PP -\fB\-\-embed\-certs\fP=false - embed client cert/key for the user entry in kubeconfig - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for set\-credentials - -.PP -\fB\-\-password\fP="" - password for the user entry in kubeconfig - -.PP -\fB\-\-token\fP="" - token for the user entry in kubeconfig - -.PP -\fB\-\-username\fP="" - username for the user entry in kubeconfig - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - use a particular kubeconfig file - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Set only the "client\-key" field on the "cluster\-admin" -// entry, without touching other values: -$ kubectl config set\-credentials cluster\-admin \-\-client\-key=\~/.kube/admin.key - -// Set basic auth for the "cluster\-admin" entry -$ kubectl config set\-credentials cluster\-admin \-\-username=admin \-\-password=uXFGweU9l35qcif - -// Embed client certificate data in the "cluster\-admin" entry -$ kubectl config set\-credentials cluster\-admin \-\-client\-certificate=\~/.kube/admin.crt \-\-embed\-certs=true - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl\-config(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set.1 deleted file mode 100644 index f83ea2edaa26..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-set.1 +++ /dev/null @@ -1,132 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl config set \- Sets an individual value in a kubeconfig file - - -.SH SYNOPSIS -.PP -\fBkubectl config set\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Sets an individual value in a kubeconfig file -PROPERTY\_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots. -PROPERTY\_VALUE is the new value you wish to set. - - -.SH OPTIONS -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for set - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - use a particular kubeconfig file - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH SEE ALSO -.PP -\fBkubectl\-config(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-unset.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-unset.1 deleted file mode 100644 index cea12d2e81ab..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-unset.1 +++ /dev/null @@ -1,131 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl config unset \- Unsets an individual value in a kubeconfig file - - -.SH SYNOPSIS -.PP -\fBkubectl config unset\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Unsets an individual value in a kubeconfig file -PROPERTY\_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots. - - -.SH OPTIONS -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for unset - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - use a particular kubeconfig file - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH SEE ALSO -.PP -\fBkubectl\-config(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-use-context.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-use-context.1 deleted file mode 100644 index 4ae194bd2a6c..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-use-context.1 +++ /dev/null @@ -1,130 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl config use\-context \- Sets the current\-context in a kubeconfig file - - -.SH SYNOPSIS -.PP -\fBkubectl config use\-context\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Sets the current\-context in a kubeconfig file - - -.SH OPTIONS -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for use\-context - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - use a particular kubeconfig file - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH SEE ALSO -.PP -\fBkubectl\-config(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-view.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-view.1 deleted file mode 100644 index 7d3f21e43ab1..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config-view.1 +++ /dev/null @@ -1,181 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl config view \- displays Merged kubeconfig settings or a specified kubeconfig file. - - -.SH SYNOPSIS -.PP -\fBkubectl config view\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -displays Merged kubeconfig settings or a specified kubeconfig file. - -.PP -You can use \-\-output=template \-\-template=TEMPLATE to extract specific values. - - -.SH OPTIONS -.PP -\fB\-\-flatten\fP=false - flatten the resulting kubeconfig file into self contained output (useful for creating portable kubeconfig files) - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for view - -.PP -\fB\-\-merge\fP=true - merge together the full hierarchy of kubeconfig files - -.PP -\fB\-\-minify\fP=false - remove all information not used by current\-context from the output - -.PP -\fB\-\-no\-headers\fP=false - When using the default output, don't print headers. - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output format. One of: json|yaml|template|templatefile|wide. - -.PP -\fB\-\-output\-version\fP="" - Output the formatted object with the given version (default api\-version). - -.PP -\fB\-\-raw\fP=false - display raw byte data - -.PP -\fB\-t\fP, \fB\-\-template\fP="" - Template string or path to template file to use when \-o=template or \-o=templatefile. The template format is golang templates [ -\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - use a particular kubeconfig file - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Show Merged kubeconfig settings. -$ kubectl config view - -// Get the password for the e2e user -$ kubectl config view \-o template \-\-template='\{\{range .users\}\}\{\{ if eq .name "e2e" \}\}\{\{ index .user.password \}\}\{\{end\}\}\{\{end\}\}' - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl\-config(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config.1 deleted file mode 100644 index 66eb5e8a1a2e..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-config.1 +++ /dev/null @@ -1,136 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl config \- config modifies kubeconfig files - - -.SH SYNOPSIS -.PP -\fBkubectl config\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -config modifies kubeconfig files using subcommands like "kubectl config set current\-context my\-context" - -.PP -The loading order follows these rules: - 1. If the \-\-kubeconfig flag is set, then only that file is loaded. The flag may only be set once and no merging takes place. - 2. If $KUBECONFIG environment variable is set, then it is used a list of paths (normal path delimitting rules for your system). These paths are merged together. When a value is modified, it is modified in the file that defines the stanza. When a value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the last file in the list. - 3. Otherwise, $\{HOME\}/.kube/config is used and no merging takes place. - - -.SH OPTIONS -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for config - -.PP -\fB\-\-kubeconfig\fP="" - use a particular kubeconfig file - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, \fBkubectl\-config\-view(1)\fP, \fBkubectl\-config\-set\-cluster(1)\fP, \fBkubectl\-config\-set\-credentials(1)\fP, \fBkubectl\-config\-set\-context(1)\fP, \fBkubectl\-config\-set(1)\fP, \fBkubectl\-config\-unset(1)\fP, \fBkubectl\-config\-use\-context(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-create.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-create.1 deleted file mode 100644 index f1eeae6551b3..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-create.1 +++ /dev/null @@ -1,156 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl create \- Create a resource by filename or stdin - - -.SH SYNOPSIS -.PP -\fBkubectl create\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Create a resource by filename or stdin. - -.PP -JSON and YAML formats are accepted. - - -.SH OPTIONS -.PP -\fB\-f\fP, \fB\-\-filename\fP=[] - Filename, directory, or URL to file to use to create the resource - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for create - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output mode. Use "\-o name" for shorter output (resource/name). - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Create a pod using the data in pod.json. -$ kubectl create \-f ./pod.json - -// Create a pod based on the JSON passed into stdin. -$ cat pod.json | kubectl create \-f \- - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-delete.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-delete.1 deleted file mode 100644 index 84da9a2572a9..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-delete.1 +++ /dev/null @@ -1,197 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl delete \- Delete resources by filenames, stdin, resources and names, or by resources and label selector. - - -.SH SYNOPSIS -.PP -\fBkubectl delete\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Delete resources by filenames, stdin, resources and names, or by resources and label selector. - -.PP -JSON and YAML formats are accepted. - -.PP -Only one type of the arguments may be specified: filenames, resources and names, or resources and label selector - -.PP -Note that the delete command does NOT do resource version checks, so if someone -submits an update to a resource right when you submit a delete, their update -will be lost along with the rest of the resource. - - -.SH OPTIONS -.PP -\fB\-\-all\fP=false - [\-all] to select all the specified resources. - -.PP -\fB\-\-cascade\fP=true - If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true. - -.PP -\fB\-f\fP, \fB\-\-filename\fP=[] - Filename, directory, or URL to a file containing the resource to delete. - -.PP -\fB\-\-grace\-period\fP=\-1 - Period of time in seconds given to the resource to terminate gracefully. Ignored if negative. - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for delete - -.PP -\fB\-\-ignore\-not\-found\fP=false - Treat "resource not found" as a successful delete. Defaults to "true" when \-\-all is specified. - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output mode. Use "\-o name" for shorter output (resource/name). - -.PP -\fB\-l\fP, \fB\-\-selector\fP="" - Selector (label query) to filter on. - -.PP -\fB\-\-timeout\fP=0 - The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Delete a pod using the type and name specified in pod.json. -$ kubectl delete \-f ./pod.json - -// Delete a pod based on the type and name in the JSON passed into stdin. -$ cat pod.json | kubectl delete \-f \- - -// Delete pods and services with label name=myLabel. -$ kubectl delete pods,services \-l name=myLabel - -// Delete a pod with UID 1234\-56\-7890\-234234\-456456. -$ kubectl delete pod 1234\-56\-7890\-234234\-456456 - -// Delete all pods -$ kubectl delete pods \-\-all - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-describe.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-describe.1 deleted file mode 100644 index 5a4766103de5..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-describe.1 +++ /dev/null @@ -1,173 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl describe \- Show details of a specific resource or group of resources - - -.SH SYNOPSIS -.PP -\fBkubectl describe\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Show details of a specific resource or group of resources. - -.PP -This command joins many API calls together to form a detailed description of a -given resource or group of resources. - -.PP -$ kubectl describe RESOURCE NAME\_PREFIX - -.PP -will first check for an exact match on RESOURCE and NAME\_PREFIX. If no such resource -exists, it will output details for every resource that has a name prefixed with NAME\_PREFIX - -.PP -Possible resources include (case insensitive): pods (po), services (svc), -replicationcontrollers (rc), nodes (no), events (ev), limitranges (limits), -persistentvolumes (pv), persistentvolumeclaims (pvc), resourcequotas (quota), -namespaces (ns) or secrets. - - -.SH OPTIONS -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for describe - -.PP -\fB\-l\fP, \fB\-\-selector\fP="" - Selector (label query) to filter on - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Describe a node -$ kubectl describe nodes kubernetes\-minion\-emt8.c.myproject.internal - -// Describe a pod -$ kubectl describe pods/nginx - -// Describe pods by label name=myLabel -$ kubectl describe po \-l name=myLabel - -// Describe all pods managed by the 'frontend' replication controller (rc\-created pods -// get the name of the rc as a prefix in the pod the name). -$ kubectl describe pods frontend - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-exec.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-exec.1 deleted file mode 100644 index d6cf8dafbfdb..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-exec.1 +++ /dev/null @@ -1,165 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl exec \- Execute a command in a container. - - -.SH SYNOPSIS -.PP -\fBkubectl exec\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Execute a command in a container. - - -.SH OPTIONS -.PP -\fB\-c\fP, \fB\-\-container\fP="" - Container name - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for exec - -.PP -\fB\-p\fP, \fB\-\-pod\fP="" - Pod name - -.PP -\fB\-i\fP, \fB\-\-stdin\fP=false - Pass stdin to the container - -.PP -\fB\-t\fP, \fB\-\-tty\fP=false - Stdin is a TTY - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// get output from running 'date' from pod 123456\-7890, using the first container by default -$ kubectl exec 123456\-7890 date - -// get output from running 'date' in ruby\-container from pod 123456\-7890 -$ kubectl exec 123456\-7890 \-c ruby\-container date - -// switch to raw terminal mode, sends stdin to 'bash' in ruby\-container from pod 123456\-780 -// and sends stdout/stderr from 'bash' back to the client -$ kubectl exec 123456\-7890 \-c ruby\-container \-i \-t \-\- bash \-il - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-expose.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-expose.1 deleted file mode 100644 index 6b288d38fa70..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-expose.1 +++ /dev/null @@ -1,222 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl expose \- Take a replicated application and expose it as Kubernetes Service - - -.SH SYNOPSIS -.PP -\fBkubectl expose\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Take a replicated application and expose it as Kubernetes Service. - -.PP -Looks up a replication controller or service by name and uses the selector for that resource as the -selector for a new Service on the specified port. If no labels are specified, the new service will -re\-use the labels from the resource it exposes. - - -.SH OPTIONS -.PP -\fB\-\-container\-port\fP="" - Synonym for \-\-target\-port - -.PP -\fB\-\-create\-external\-load\-balancer\fP=false - If true, create an external load balancer for this service (trumped by \-\-type). Implementation is cloud provider dependent. Default is 'false'. - -.PP -\fB\-\-dry\-run\fP=false - If true, only print the object that would be sent, without creating it. - -.PP -\fB\-\-generator\fP="service/v2" - The name of the API generator to use. There are 2 generators: 'service/v1' and 'service/v2'. The only difference between them is that service port in v1 is named 'default', while it is left unnamed in v2. Default is 'service/v2'. - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for expose - -.PP -\fB\-l\fP, \fB\-\-labels\fP="" - Labels to apply to the service created by this call. - -.PP -\fB\-\-name\fP="" - The name for the newly created object. - -.PP -\fB\-\-no\-headers\fP=false - When using the default output, don't print headers. - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output format. One of: json|yaml|template|templatefile|wide. - -.PP -\fB\-\-output\-version\fP="" - Output the formatted object with the given version (default api\-version). - -.PP -\fB\-\-overrides\fP="" - An inline JSON override for the generated object. If this is non\-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field. - -.PP -\fB\-\-port\fP=\-1 - The port that the service should serve on. Copied from the resource being exposed, if unspecified - -.PP -\fB\-\-protocol\fP="TCP" - The network protocol for the service to be created. Default is 'tcp'. - -.PP -\fB\-\-public\-ip\fP="" - Name of a public IP address to set for the service. The service will be assigned this IP in addition to its generated service IP. - -.PP -\fB\-\-selector\fP="" - A label selector to use for this service. If empty (the default) infer the selector from the replication controller. - -.PP -\fB\-\-target\-port\fP="" - Name or number for the port on the container that the service should direct traffic to. Optional. - -.PP -\fB\-t\fP, \fB\-\-template\fP="" - Template string or path to template file to use when \-o=template or \-o=templatefile. The template format is golang templates [ -\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] - -.PP -\fB\-\-type\fP="" - Type for this service: ClusterIP, NodePort, or LoadBalancer. Default is 'ClusterIP' unless \-\-create\-external\-load\-balancer is specified. - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Creates a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000. -$ kubectl expose rc nginx \-\-port=80 \-\-target\-port=8000 - -// Creates a second service based on the above service, exposing the container port 8443 as port 443 with the name "nginx\-https" -$ kubectl expose service nginx \-\-port=443 \-\-target\-port=8443 \-\-name=nginx\-https - -// Create a service for a replicated streaming application on port 4100 balancing UDP traffic and named 'video\-stream'. -$ kubectl expose rc streamer \-\-port=4100 \-\-protocol=udp \-\-name=video\-stream - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-get.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-get.1 deleted file mode 100644 index 7bbe6ac2cf6c..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-get.1 +++ /dev/null @@ -1,207 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl get \- Display one or many resources - - -.SH SYNOPSIS -.PP -\fBkubectl get\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Display one or many resources. - -.PP -Possible resources include (case insensitive): pods (po), services (svc), -replicationcontrollers (rc), nodes (no), events (ev), componentstatuses (cs), -limitranges (limits), persistentvolumes (pv), persistentvolumeclaims (pvc), -resourcequotas (quota), namespaces (ns), endpoints (ep) or secrets. - -.PP -By specifying the output as 'template' and providing a Go template as the value -of the \-\-template flag, you can filter the attributes of the fetched resource(s). - - -.SH OPTIONS -.PP -\fB\-\-all\-namespaces\fP=false - If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with \-\-namespace. - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for get - -.PP -\fB\-L\fP, \fB\-\-label\-columns\fP=[] - Accepts a comma separated list of labels that are going to be presented as columns. Names are case\-sensitive. You can also use multiple flag statements like \-L label1 \-L label2... - -.PP -\fB\-\-no\-headers\fP=false - When using the default output, don't print headers. - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output format. One of: json|yaml|template|templatefile|wide. - -.PP -\fB\-\-output\-version\fP="" - Output the formatted object with the given version (default api\-version). - -.PP -\fB\-l\fP, \fB\-\-selector\fP="" - Selector (label query) to filter on - -.PP -\fB\-t\fP, \fB\-\-template\fP="" - Template string or path to template file to use when \-o=template or \-o=templatefile. The template format is golang templates [ -\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] - -.PP -\fB\-w\fP, \fB\-\-watch\fP=false - After listing/getting the requested object, watch for changes. - -.PP -\fB\-\-watch\-only\fP=false - Watch for changes to the requested object(s), without listing/getting first. - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// List all pods in ps output format. -$ kubectl get pods - -// List all pods in ps output format with more information (such as node name). -$ kubectl get pods \-o wide - -// List a single replication controller with specified NAME in ps output format. -$ kubectl get replicationcontroller web - -// List a single pod in JSON output format. -$ kubectl get \-o json pod web\-pod\-13je7 - -// Return only the phase value of the specified pod. -$ kubectl get \-o template web\-pod\-13je7 \-\-template=\{\{.status.phase\}\} \-\-api\-version=v1 - -// List all replication controllers and services together in ps output format. -$ kubectl get rc,services - -// List one or more resources by their type and names. -$ kubectl get rc/web service/frontend pods/web\-pod\-13je7 - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-label.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-label.1 deleted file mode 100644 index a74ab28140ad..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-label.1 +++ /dev/null @@ -1,193 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl label \- Update the labels on a resource - - -.SH SYNOPSIS -.PP -\fBkubectl label\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Update the labels on a resource. - -.PP -A label must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to 63 characters. -If \-\-overwrite is true, then existing labels can be overwritten, otherwise attempting to overwrite a label will result in an error. -If \-\-resource\-version is specified, then updates will use this resource version, otherwise the existing resource\-version will be used. - - -.SH OPTIONS -.PP -\fB\-\-all\fP=false - select all resources in the namespace of the specified resource types - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for label - -.PP -\fB\-\-no\-headers\fP=false - When using the default output, don't print headers. - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output format. One of: json|yaml|template|templatefile|wide. - -.PP -\fB\-\-output\-version\fP="" - Output the formatted object with the given version (default api\-version). - -.PP -\fB\-\-overwrite\fP=false - If true, allow labels to be overwritten, otherwise reject label updates that overwrite existing labels. - -.PP -\fB\-\-resource\-version\fP="" - If non\-empty, the labels update will only succeed if this is the current resource\-version for the object. Only valid when specifying a single resource. - -.PP -\fB\-l\fP, \fB\-\-selector\fP="" - Selector (label query) to filter on - -.PP -\fB\-t\fP, \fB\-\-template\fP="" - Template string or path to template file to use when \-o=template or \-o=templatefile. The template format is golang templates [ -\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Update pod 'foo' with the label 'unhealthy' and the value 'true'. -$ kubectl label pods foo unhealthy=true - -// Update pod 'foo' with the label 'status' and the value 'unhealthy', overwriting any existing value. -$ kubectl label \-\-overwrite pods foo status=unhealthy - -// Update all pods in the namespace -$ kubectl label pods \-\-all status=unhealthy - -// Update pod 'foo' only if the resource is unchanged from version 1. -$ kubectl label pods foo status=unhealthy \-\-resource\-version=1 - -// Update pod 'foo' by removing a label named 'bar' if it exists. -// Does not require the \-\-overwrite flag. -$ kubectl label pods foo bar\- - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-logs.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-logs.1 deleted file mode 100644 index 657afc01273f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-logs.1 +++ /dev/null @@ -1,164 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl logs \- Print the logs for a container in a pod. - - -.SH SYNOPSIS -.PP -\fBkubectl logs\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Print the logs for a container in a pod. If the pod has only one container, the container name is optional. - - -.SH OPTIONS -.PP -\fB\-c\fP, \fB\-\-container\fP="" - Container name - -.PP -\fB\-f\fP, \fB\-\-follow\fP=false - Specify if the logs should be streamed. - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for logs - -.PP -\fB\-\-interactive\fP=true - If true, prompt the user for input when required. Default true. - -.PP -\fB\-p\fP, \fB\-\-previous\fP=false - If true, print the logs for the previous instance of the container in a pod if it exists. - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Returns snapshot of ruby\-container logs from pod 123456\-7890. -$ kubectl logs 123456\-7890 ruby\-container - -// Returns snapshot of previous terminated ruby\-container logs from pod 123456\-7890. -$ kubectl logs \-p 123456\-7890 ruby\-container - -// Starts streaming of ruby\-container logs from pod 123456\-7890. -$ kubectl logs \-f 123456\-7890 ruby\-container - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-namespace.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-namespace.1 deleted file mode 100644 index 94b04c52a9e8..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-namespace.1 +++ /dev/null @@ -1,133 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl namespace \- SUPERCEDED: Set and view the current Kubernetes namespace - - -.SH SYNOPSIS -.PP -\fBkubectl namespace\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -SUPERCEDED: Set and view the current Kubernetes namespace scope for command line requests. - -.PP -namespace has been superceded by the context.namespace field of .kubeconfig files. See 'kubectl config set\-context \-\-help' for more details. - - -.SH OPTIONS -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for namespace - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-patch.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-patch.1 deleted file mode 100644 index 7d79280e97ec..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-patch.1 +++ /dev/null @@ -1,154 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl patch \- Update field(s) of a resource by stdin. - - -.SH SYNOPSIS -.PP -\fBkubectl patch\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Update field(s) of a resource using strategic merge patch - -.PP -JSON and YAML formats are accepted. - - -.SH OPTIONS -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for patch - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output mode. Use "\-o name" for shorter output (resource/name). - -.PP -\fB\-p\fP, \fB\-\-patch\fP="" - The patch to be applied to the resource JSON file. - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf - -// Partially update a node using strategic merge patch -kubectl patch node k8s\-node\-1 \-p '\{"spec":\{"unschedulable":true\}\}' - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-port-forward.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-port-forward.1 deleted file mode 100644 index 6d52308dd3e0..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-port-forward.1 +++ /dev/null @@ -1,156 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl port\-forward \- Forward one or more local ports to a pod. - - -.SH SYNOPSIS -.PP -\fBkubectl port\-forward\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Forward one or more local ports to a pod. - - -.SH OPTIONS -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for port\-forward - -.PP -\fB\-p\fP, \fB\-\-pod\fP="" - Pod name - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf - -// listens on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod -$ kubectl port\-forward \-p mypod 5000 6000 - -// listens on port 8888 locally, forwarding to 5000 in the pod -$ kubectl port\-forward \-p mypod 8888:5000 - -// listens on a random port locally, forwarding to 5000 in the pod -$ kubectl port\-forward \-p mypod :5000 - -// listens on a random port locally, forwarding to 5000 in the pod -$ kubectl port\-forward \-p mypod 0:5000 - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-proxy.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-proxy.1 deleted file mode 100644 index 3200c91c1311..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-proxy.1 +++ /dev/null @@ -1,207 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl proxy \- Run a proxy to the Kubernetes API server - - -.SH SYNOPSIS -.PP -\fBkubectl proxy\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -To proxy all of the kubernetes api and nothing else, use: - -.PP -kubectl proxy \-\-api\-prefix=/ - -.PP -To proxy only part of the kubernetes api and also some static files: - -.PP -kubectl proxy \-\-www=/my/files \-\-www\-prefix=/static/ \-\-api\-prefix=/api/ - -.PP -The above lets you 'curl localhost:8001/api/v1/pods'. - -.PP -To proxy the entire kubernetes api at a different root, use: - -.PP -kubectl proxy \-\-api\-prefix=/custom/ - -.PP -The above lets you 'curl localhost:8001/custom/api/v1/pods' - - -.SH OPTIONS -.PP -\fB\-\-accept\-hosts\fP="^localhost$,^127\\.0\\.0\\.1$,^\\[::1\\]$" - Regular expression for hosts that the proxy should accept. - -.PP -\fB\-\-accept\-paths\fP="^/.*" - Regular expression for paths that the proxy should accept. - -.PP -\fB\-\-api\-prefix\fP="/api/" - Prefix to serve the proxied API under. - -.PP -\fB\-\-disable\-filter\fP=false - If true, disable request filtering in the proxy. This is dangerous, and can leave you vulnerable to XSRF attacks. Use with caution. - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for proxy - -.PP -\fB\-p\fP, \fB\-\-port\fP=8001 - The port on which to run the proxy. Set to 0 to pick a random port. - -.PP -\fB\-\-reject\-methods\fP="POST,PUT,PATCH" - Regular expression for HTTP methods that the proxy should reject. - -.PP -\fB\-\-reject\-paths\fP="^/api/.\fI/exec,^/api/.\fP/run" - Regular expression for paths that the proxy should reject. - -.PP -\fB\-w\fP, \fB\-\-www\fP="" - Also serve static files from the given directory under the specified prefix. - -.PP -\fB\-P\fP, \fB\-\-www\-prefix\fP="/static/" - Prefix to serve static files under, if static file directory is specified. - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Run a proxy to kubernetes apiserver on port 8011, serving static content from ./local/www/ -$ kubectl proxy \-\-port=8011 \-\-www=./local/www/ - -// Run a proxy to kubernetes apiserver on an arbitrary local port. -// The chosen port for the server will be output to stdout. -$ kubectl proxy \-\-port=0 - -// Run a proxy to kubernetes apiserver, changing the api prefix to k8s\-api -// This makes e.g. the pods api available at localhost:8011/k8s\-api/v1/pods/ -$ kubectl proxy \-\-api\-prefix=/k8s\-api - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-replace.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-replace.1 deleted file mode 100644 index 9825fd6efd6f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-replace.1 +++ /dev/null @@ -1,175 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl replace \- Replace a resource by filename or stdin. - - -.SH SYNOPSIS -.PP -\fBkubectl replace\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Replace a resource by filename or stdin. - -.PP -JSON and YAML formats are accepted. - - -.SH OPTIONS -.PP -\fB\-\-cascade\fP=false - Only relevant during a force replace. If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true. - -.PP -\fB\-f\fP, \fB\-\-filename\fP=[] - Filename, directory, or URL to file to use to replace the resource. - -.PP -\fB\-\-force\fP=false - Delete and re\-create the specified resource - -.PP -\fB\-\-grace\-period\fP=\-1 - Only relevant during a force replace. Period of time in seconds given to the old resource to terminate gracefully. Ignored if negative. - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for replace - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output mode. Use "\-o name" for shorter output (resource/name). - -.PP -\fB\-\-timeout\fP=0 - Only relevant during a force replace. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Replace a pod using the data in pod.json. -$ kubectl replace \-f ./pod.json - -// Replace a pod based on the JSON passed into stdin. -$ cat pod.json | kubectl replace \-f \- - -// Force replace, delete and then re\-create the resource -kubectl replace \-\-force \-f ./pod.json - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-rolling-update.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-rolling-update.1 deleted file mode 100644 index caf05d027c83..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-rolling-update.1 +++ /dev/null @@ -1,207 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl rolling\-update \- Perform a rolling update of the given ReplicationController. - - -.SH SYNOPSIS -.PP -\fBkubectl rolling\-update\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Perform a rolling update of the given ReplicationController. - -.PP -Replaces the specified replication controller with a new replication controller by updating one pod at a time to use the -new PodTemplate. The new\-controller.json must specify the same namespace as the -existing replication controller and overwrite at least one (common) label in its replicaSelector. - - -.SH OPTIONS -.PP -\fB\-\-deployment\-label\-key\fP="deployment" - The key to use to differentiate between two different controllers, default 'deployment'. Only relevant when \-\-image is specified, ignored otherwise - -.PP -\fB\-\-dry\-run\fP=false - If true, print out the changes that would be made, but don't actually make them. - -.PP -\fB\-f\fP, \fB\-\-filename\fP="" - Filename or URL to file to use to create the new replication controller. - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for rolling\-update - -.PP -\fB\-\-image\fP="" - Image to use for upgrading the replication controller. Can not be used with \-\-filename/\-f - -.PP -\fB\-\-no\-headers\fP=false - When using the default output, don't print headers. - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output format. One of: json|yaml|template|templatefile|wide. - -.PP -\fB\-\-output\-version\fP="" - Output the formatted object with the given version (default api\-version). - -.PP -\fB\-\-poll\-interval\fP="3s" - Time delay between polling for replication controller status after the update. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - -.PP -\fB\-\-rollback\fP=false - If true, this is a request to abort an existing rollout that is partially rolled out. It effectively reverses current and next and runs a rollout - -.PP -\fB\-t\fP, \fB\-\-template\fP="" - Template string or path to template file to use when \-o=template or \-o=templatefile. The template format is golang templates [ -\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] - -.PP -\fB\-\-timeout\fP="5m0s" - Max time to wait for a replication controller to update before giving up. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - -.PP -\fB\-\-update\-period\fP="1m0s" - Time to wait between updating pods. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Update pods of frontend\-v1 using new replication controller data in frontend\-v2.json. -$ kubectl rolling\-update frontend\-v1 \-f frontend\-v2.json - -// Update pods of frontend\-v1 using JSON data passed into stdin. -$ cat frontend\-v2.json | kubectl rolling\-update frontend\-v1 \-f \- - -// Update the pods of frontend\-v1 to frontend\-v2 by just changing the image, and switching the -// name of the replication controller. -$ kubectl rolling\-update frontend\-v1 frontend\-v2 \-\-image=image:v2 - -// Update the pods of frontend by just changing the image, and keeping the old name -$ kubectl rolling\-update frontend \-\-image=image:v2 - - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-run.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-run.1 deleted file mode 100644 index d193eacf20ba..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-run.1 +++ /dev/null @@ -1,201 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl run \- Run a particular image on the cluster. - - -.SH SYNOPSIS -.PP -\fBkubectl run\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Create and run a particular image, possibly replicated. -Creates a replication controller to manage the created container(s). - - -.SH OPTIONS -.PP -\fB\-\-dry\-run\fP=false - If true, only print the object that would be sent, without sending it. - -.PP -\fB\-\-generator\fP="run/v1" - The name of the API generator to use. Default is 'run\-controller/v1'. - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for run - -.PP -\fB\-\-hostport\fP=\-1 - The host port mapping for the container port. To demonstrate a single\-machine container. - -.PP -\fB\-\-image\fP="" - The image for the container to run. - -.PP -\fB\-l\fP, \fB\-\-labels\fP="" - Labels to apply to the pod(s). - -.PP -\fB\-\-no\-headers\fP=false - When using the default output, don't print headers. - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output format. One of: json|yaml|template|templatefile|wide. - -.PP -\fB\-\-output\-version\fP="" - Output the formatted object with the given version (default api\-version). - -.PP -\fB\-\-overrides\fP="" - An inline JSON override for the generated object. If this is non\-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field. - -.PP -\fB\-\-port\fP=\-1 - The port that this container exposes. - -.PP -\fB\-r\fP, \fB\-\-replicas\fP=1 - Number of replicas to create for this container. Default is 1. - -.PP -\fB\-t\fP, \fB\-\-template\fP="" - Template string or path to template file to use when \-o=template or \-o=templatefile. The template format is golang templates [ -\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Starts a single instance of nginx. -$ kubectl run nginx \-\-image=nginx - -// Starts a replicated instance of nginx. -$ kubectl run nginx \-\-image=nginx \-\-replicas=5 - -// Dry run. Print the corresponding API objects without creating them. -$ kubectl run nginx \-\-image=nginx \-\-dry\-run - -// Start a single instance of nginx, but overload the spec of the replication controller with a partial set of values parsed from JSON. -$ kubectl run nginx \-\-image=nginx \-\-overrides='\{ "apiVersion": "v1", "spec": \{ ... \} \}' - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-scale.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-scale.1 deleted file mode 100644 index 81d0ea236f6c..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-scale.1 +++ /dev/null @@ -1,174 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl scale \- Set a new size for a Replication Controller. - - -.SH SYNOPSIS -.PP -\fBkubectl scale\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Set a new size for a Replication Controller. - -.PP -Scale also allows users to specify one or more preconditions for the scale action. -If \-\-current\-replicas or \-\-resource\-version is specified, it is validated before the -scale is attempted, and it is guaranteed that the precondition holds true when the -scale is sent to the server. - - -.SH OPTIONS -.PP -\fB\-\-current\-replicas\fP=\-1 - Precondition for current size. Requires that the current size of the replication controller match this value in order to scale. - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for scale - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output mode. Use "\-o name" for shorter output (resource/name). - -.PP -\fB\-\-replicas\fP=\-1 - The new desired number of replicas. Required. - -.PP -\fB\-\-resource\-version\fP="" - Precondition for resource version. Requires that the current resource version match this value in order to scale. - -.PP -\fB\-\-timeout\fP=0 - The length of time to wait before giving up on a scale operation, zero means don't wait. - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Scale replication controller named 'foo' to 3. -$ kubectl scale \-\-replicas=3 replicationcontrollers foo - -// If the replication controller named foo's current size is 2, scale foo to 3. -$ kubectl scale \-\-current\-replicas=2 \-\-replicas=3 replicationcontrollers foo - -// Scale multiple replication controllers. -$ kubectl scale \-\-replicas=5 rc/foo rc/bar - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-stop.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-stop.1 deleted file mode 100644 index 6620c91d6ed6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-stop.1 +++ /dev/null @@ -1,187 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl stop \- Deprecated: Gracefully shut down a resource by name or filename. - - -.SH SYNOPSIS -.PP -\fBkubectl stop\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Deprecated: Gracefully shut down a resource by name or filename. - -.PP -stop command is deprecated, all its functionalities are covered by delete command. -See 'kubectl delete \-\-help' for more details. - -.PP -Attempts to shut down and delete a resource that supports graceful termination. -If the resource is scalable it will be scaled to 0 before deletion. - - -.SH OPTIONS -.PP -\fB\-\-all\fP=false - [\-all] to select all the specified resources. - -.PP -\fB\-f\fP, \fB\-\-filename\fP=[] - Filename, directory, or URL to file of resource(s) to be stopped. - -.PP -\fB\-\-grace\-period\fP=\-1 - Period of time in seconds given to the resource to terminate gracefully. Ignored if negative. - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for stop - -.PP -\fB\-\-ignore\-not\-found\fP=false - Treat "resource not found" as a successful stop. - -.PP -\fB\-o\fP, \fB\-\-output\fP="" - Output mode. Use "\-o name" for shorter output (resource/name). - -.PP -\fB\-l\fP, \fB\-\-selector\fP="" - Selector (label query) to filter on. - -.PP -\fB\-\-timeout\fP=0 - The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH EXAMPLE -.PP -.RS - -.nf -// Shut down foo. -$ kubectl stop replicationcontroller foo - -// Stop pods and services with label name=myLabel. -$ kubectl stop pods,services \-l name=myLabel - -// Shut down the service defined in service.json -$ kubectl stop \-f service.json - -// Shut down all resources in the path/to/resources directory -$ kubectl stop \-f path/to/resources - -.fi -.RE - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-version.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-version.1 deleted file mode 100644 index d91fca6c10f0..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl-version.1 +++ /dev/null @@ -1,134 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl version \- Print the client and server version information. - - -.SH SYNOPSIS -.PP -\fBkubectl version\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -Print the client and server version information. - - -.SH OPTIONS -.PP -\fB\-c\fP, \fB\-\-client\fP=false - Client version only (no server required). - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for version - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH SEE ALSO -.PP -\fBkubectl(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl.1 b/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl.1 deleted file mode 100644 index f1d091bb9736..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/man/man1/kubectl.1 +++ /dev/null @@ -1,132 +0,0 @@ -.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" "" - - -.SH NAME -.PP -kubectl \- kubectl controls the Kubernetes cluster manager - - -.SH SYNOPSIS -.PP -\fBkubectl\fP [OPTIONS] - - -.SH DESCRIPTION -.PP -kubectl controls the Kubernetes cluster manager. - -.PP -Find more information at -\[la]https://k8s.io/kubernetes\[ra]. - - -.SH OPTIONS -.PP -\fB\-\-alsologtostderr\fP=false - log to standard error as well as files - -.PP -\fB\-\-api\-version\fP="" - The API version to use when talking to the server - -.PP -\fB\-\-certificate\-authority\fP="" - Path to a cert. file for the certificate authority. - -.PP -\fB\-\-client\-certificate\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-client\-key\fP="" - Path to a client key file for TLS. - -.PP -\fB\-\-cluster\fP="" - The name of the kubeconfig cluster to use - -.PP -\fB\-\-context\fP="" - The name of the kubeconfig context to use - -.PP -\fB\-h\fP, \fB\-\-help\fP=false - help for kubectl - -.PP -\fB\-\-insecure\-skip\-tls\-verify\fP=false - If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - -.PP -\fB\-\-kubeconfig\fP="" - Path to the kubeconfig file to use for CLI requests. - -.PP -\fB\-\-log\-backtrace\-at\fP=:0 - when logging hits line file:N, emit a stack trace - -.PP -\fB\-\-log\-dir\fP="" - If non\-empty, write log files in this directory - -.PP -\fB\-\-log\-flush\-frequency\fP=5s - Maximum number of seconds between log flushes - -.PP -\fB\-\-logtostderr\fP=true - log to standard error instead of files - -.PP -\fB\-\-match\-server\-version\fP=false - Require server version to match client version - -.PP -\fB\-\-namespace\fP="" - If present, the namespace scope for this CLI request. - -.PP -\fB\-\-password\fP="" - Password for basic authentication to the API server. - -.PP -\fB\-s\fP, \fB\-\-server\fP="" - The address and port of the Kubernetes API server - -.PP -\fB\-\-stderrthreshold\fP=2 - logs at or above this threshold go to stderr - -.PP -\fB\-\-token\fP="" - Bearer token for authentication to the API server. - -.PP -\fB\-\-user\fP="" - The name of the kubeconfig user to use - -.PP -\fB\-\-username\fP="" - Username for basic authentication to the API server. - -.PP -\fB\-\-v\fP=0 - log level for V logs - -.PP -\fB\-\-validate\fP=false - If true, use a schema to validate the input before sending it - -.PP -\fB\-\-vmodule\fP= - comma\-separated list of pattern=N settings for file\-filtered logging - - -.SH SEE ALSO -.PP -\fBkubectl\-get(1)\fP, \fBkubectl\-describe(1)\fP, \fBkubectl\-create(1)\fP, \fBkubectl\-replace(1)\fP, \fBkubectl\-patch(1)\fP, \fBkubectl\-delete(1)\fP, \fBkubectl\-namespace(1)\fP, \fBkubectl\-logs(1)\fP, \fBkubectl\-rolling\-update(1)\fP, \fBkubectl\-scale(1)\fP, \fBkubectl\-attach(1)\fP, \fBkubectl\-exec(1)\fP, \fBkubectl\-port\-forward(1)\fP, \fBkubectl\-proxy(1)\fP, \fBkubectl\-run(1)\fP, \fBkubectl\-stop(1)\fP, \fBkubectl\-expose(1)\fP, \fBkubectl\-label(1)\fP, \fBkubectl\-config(1)\fP, \fBkubectl\-cluster\-info(1)\fP, \fBkubectl\-api\-versions(1)\fP, \fBkubectl\-version(1)\fP, - - -.SH HISTORY -.PP -January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/reporting-security-issues.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/reporting-security-issues.md deleted file mode 100644 index d2948c759125..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/reporting-security-issues.md +++ /dev/null @@ -1,57 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/reporting-security-issues.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Security - -If you believe you have discovered a vulnerability or a have a security incident to report, please follow the steps below. This applies to Kubernetes releases v1.0 or later. - -To watch for security and major API announcements, please join our [kubernetes-announce](https://groups.google.com/forum/#!forum/kubernetes-announce) group. - -## Reporting a security issue - -To report an issue, please: -- Submit a bug report [here](http://goo.gl/vulnz). - - Select “I want to report a technical security bug in a Google product (SQLi, XSS, etc.).” - - Select “Other” as the Application Type. -- Under reproduction steps, please additionally include - - the words "Kubernetes Security issue" - - Description of the issue - - Kubernetes release (e.g. output of `kubectl version` command, which includes server version.) - - Environment setup (e.g. which "Getting Started Guide" you followed, if any; what node operating system used; what service or software creates your virtual machines, if any) - -An online submission will have the fastest response; however, if you prefer email, please send mail to security@google.com. If you feel the need, please use the [PGP public key](https://services.google.com/corporate/publickey.txt) to encrypt communications. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/reporting-security-issues.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/roadmap.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/roadmap.md deleted file mode 100644 index 705fd181224a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/roadmap.md +++ /dev/null @@ -1,43 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/roadmap.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes Roadmap - -We're in the process of prioritizing changes to be made after 1.0. - -Please watch the [Github milestones] (https://k8s.io/kubernetes/milestones) for our future plans. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/roadmap.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/troubleshooting.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/troubleshooting.md deleted file mode 100644 index ed5a6feab1a6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/troubleshooting.md +++ /dev/null @@ -1,76 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/troubleshooting.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Troubleshooting - -Sometimes things go wrong. This guide is aimed at making them right. It has two sections: - * [Troubleshooting your application](user-guide/application-troubleshooting.md) - Useful for users who are deploying code into Kubernetes and wondering why it is not working. - * [Troubleshooting your cluster](admin/cluster-troubleshooting.md) - Useful for cluster administrators and people whose Kubernetes cluster is unhappy. - -You should also check the [known issues](user-guide/known-issues.md) for the release you're using. - -# Getting help - -If your problem isn't answered by any of the guides above, there are variety of ways for you to get help from the Kubernetes team. - -## Questions - -We have a number of FAQ pages - * [User FAQ](https://k8s.io/kubernetes/wiki/User-FAQ) - * [Debugging FAQ](https://k8s.io/kubernetes/wiki/Debugging-FAQ) - * [Services FAQ](https://k8s.io/kubernetes/wiki/Services-FAQ) - -You may also find the StackOverflow topics relevant - * [Kubernetes](http://stackoverflow.com/questions/tagged/kubernetes) - * [Google Container Engine - GKE](http://stackoverflow.com/questions/tagged/google-container-engine) - -## Bugs and Feature requests - -If you have what looks like a bug, or you would like to make a feature request, please use the [Github issue tracking system](https://k8s.io/kubernetes/issues). - -Before you file an issue, please search existing issues to see if your issue is already covered. - -# Help! My question isn't covered! I need help now! - -## IRC - -The Kubernetes team hangs out on IRC at [`#google-containers`](https://botbot.me/freenode/google-containers/) on freenode. Feel free to come and ask any and all questions there. - -## Mailing List - -The Kubernetes mailing list is [google-containers@googlegroups.com](https://groups.google.com/forum/#!forum/google-containers) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/troubleshooting.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/README.md deleted file mode 100644 index 27b713b6fea3..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/README.md +++ /dev/null @@ -1,135 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes User Guide: Managing Applications - -**Table of Contents** - - -- [Kubernetes User Guide: Managing Applications](#kubernetes-user-guide-managing-applications) - - [Quick walkthrough](#quick-walkthrough) - - [Thorough walkthrough](#thorough-walkthrough) - - [Concept guide](#concept-guide) - - [Further reading](#further-reading) - - - -The user guide is intended for anyone who wants to run programs and services on an existing Kubernetes cluster. Setup and administration of a Kubernetes cluster is described in the [Cluster Admin Guide](../../docs/admin/README.md). The [Developer Guide](../../docs/devel/README.md) is for anyone wanting to either write code which directly accesses the Kubernetes API, or to contribute directly to the Kubernetes project. - -Please ensure you have completed the [prerequisites for running examples from the user guide](prereqs.md). - -## Quick walkthrough - -1. [Kubernetes 101](walkthrough/README.md) -1. [Kubernetes 201](walkthrough/k8s201.md) - -## Thorough walkthrough - -If you don't have much familiarity with Kubernetes, we recommend you read the following sections in order: - -1. [Quick start: launch and expose an application](quick-start.md) -1. [Configuring and launching containers: configuring common container parameters](configuring-containers.md) -1. [Deploying continuously running applications](deploying-applications.md) -1. [Connecting applications: exposing applications to clients and users](connecting-applications.md) -1. [Working with containers in production](production-pods.md) -1. [Managing deployments](managing-deployments.md) -1. [Application introspection and debugging](introspection-and-debugging.md) - 1. [Using the Kubernetes web user interface](ui.md) - 1. [Logging](logging.md) - 1. [Monitoring](monitoring.md) - 1. [Getting into containers via `exec`](getting-into-containers.md) - 1. [Connecting to containers via proxies](connecting-to-applications-proxy.md) - 1. [Connecting to containers via port forwarding](connecting-to-applications-port-forward.md) - -## Concept guide - -[**Overview**](overview.md) -: A brief overview of Kubernetes concepts. - -[**Cluster**](../admin/README.md) -: A cluster is a set of physical or virtual machines and other infrastructure resources used by Kubernetes to run your applications. - -[**Node**](../admin/node.md) -: A node is a physical or virtual machine running Kubernetes, onto which pods can be scheduled. - -[**Pod**](pods.md) -: A pod is a co-located group of containers and volumes. - -[**Label**](labels.md) -: A label is a key/value pair that is attached to a resource, such as a pod, to convey a user-defined identifying attribute. Labels can be used to organize and to select subsets of resources. - -[**Selector**](labels.md#label-selectors) -: A selector is an expression that matches labels in order to identify related resources, such as which pods are targeted by a load-balanced service. - -[**Replication Controller**](replication-controller.md) -: A replication controller ensures that a specified number of pod replicas are running at any one time. It both allows for easy scaling of replicated systems and handles re-creation of a pod when the machine it is on reboots or otherwise fails. - -[**Service**](services.md) -: A service defines a set of pods and a means by which to access them, such as single stable IP address and corresponding DNS name. - -[**Volume**](volumes.md) -: A volume is a directory, possibly with some data in it, which is accessible to a Container as part of its filesystem. Kubernetes volumes build upon [Docker Volumes](https://docs.docker.com/userguide/dockervolumes/), adding provisioning of the volume directory and/or device. - -[**Secret**](secrets.md) -: A secret stores sensitive data, such as authentication tokens, which can be made available to containers upon request. - -[**Name**](identifiers.md) -: A user- or client-provided name for a resource. - -[**Namespace**](namespaces.md) -: A namespace is like a prefix to the name of a resource. Namespaces help different projects, teams, or customers to share a cluster, such as by preventing name collisions between unrelated teams. - -[**Annotation**](annotations.md) -: A key/value pair that can hold larger (compared to a label), and possibly not human-readable, data, intended to store non-identifying auxiliary data, especially data manipulated by tools and system extensions. Efficient filtering by annotation values is not supported. - -## Further reading - -* API resources - * [Working with resources](working-with-resources.md) - -* Pods and containers - * [Pod lifecycle and restart policies](pod-states.md) - * [Lifecycle hooks](container-environment.md) - * [Compute resources, such as cpu and memory](compute-resources.md) - * [Specifying commands and requesting capabilities](containers.md) - * [Downward API: accessing system configuration from a pod](downward-api.md) - * [Images and registries](images.md) - * [Migrating from docker-cli to kubectl](docker-cli-to-kubectl.md) - * [Tips and tricks when working with config](config-best-practices.md) - * [Assign pods to selected nodes](node-selection/) - * [Perform a rolling update on a running group of pods](update-demo/) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/accessing-the-cluster.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/accessing-the-cluster.md deleted file mode 100644 index 83709c6bc96e..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/accessing-the-cluster.md +++ /dev/null @@ -1,323 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/accessing-the-cluster.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# User Guide to Accessing the Cluster - -**Table of Contents** - - -- [User Guide to Accessing the Cluster](#user-guide-to-accessing-the-cluster) - - [Accessing the cluster API](#accessing-the-cluster-api) - - [Accessing for the first time with kubectl](#accessing-for-the-first-time-with-kubectl) - - [Directly accessing the REST API](#directly-accessing-the-rest-api) - - [Using kubectl proxy](#using-kubectl-proxy) - - [Without kubectl proxy](#without-kubectl-proxy) - - [Programmatic access to the API](#programmatic-access-to-the-api) - - [Accessing the API from a Pod](#accessing-the-api-from-a-pod) - - [Accessing services running on the cluster](#accessing-services-running-on-the-cluster) - - [Ways to connect](#ways-to-connect) - - [Discovering builtin services](#discovering-builtin-services) - - [Manually constructing apiserver proxy URLs](#manually-constructing-apiserver-proxy-urls) - - [Examples](#examples) - - [Using web browsers to access services running on the cluster](#using-web-browsers-to-access-services-running-on-the-cluster) - - [Requesting redirects](#requesting-redirects) - - [So Many Proxies](#so-many-proxies) - - - -## Accessing the cluster API - -### Accessing for the first time with kubectl - -When accessing the Kubernetes API for the first time, we suggest using the -Kubernetes CLI, `kubectl`. - -To access a cluster, you need to know the location of the cluster and have credentials -to access it. Typically, this is automatically set-up when you work through -though a [Getting started guide](../getting-started-guides/README.md), -or someone else setup the cluster and provided you with credentials and a location. - -Check the location and credentials that kubectl knows about with this command: - -```console -$ kubectl config view -``` - -Many of the [examples](../../examples/) provide an introduction to using -kubectl and complete documentation is found in the [kubectl manual](kubectl/kubectl.md). - -### Directly accessing the REST API - -Kubectl handles locating and authenticating to the apiserver. -If you want to directly access the REST API with an http client like -curl or wget, or a browser, there are several ways to locate and authenticate: - - Run kubectl in proxy mode. - - Recommended approach. - - Uses stored apiserver location. - - Verifies identity of apiserver using self-signed cert. No MITM possible. - - Authenticates to apiserver. - - In future, may do intelligent client-side load-balancing and failover. - - Provide the location and credentials directly to the http client. - - Alternate approach. - - Works with some types of client code that are confused by using a proxy. - - Need to import a root cert into your browser to protect against MITM. - -#### Using kubectl proxy - -The following command runs kubectl in a mode where it acts as a reverse proxy. It handles -locating the apiserver and authenticating. -Run it like this: - -```console -$ kubectl proxy --port=8080 & -``` - -See [kubectl proxy](kubectl/kubectl_proxy.md) for more details. - -Then you can explore the API with curl, wget, or a browser, like so: - -```console -$ curl http://localhost:8080/api/ -{ - "versions": [ - "v1" - ] -} -``` - -#### Without kubectl proxy - -It is also possible to avoid using kubectl proxy by passing an authentication token -directly to the apiserver, like this: - -```console -$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ") -$ TOKEN=$(kubectl config view | grep token | cut -f 2 -d ":" | tr -d " ") -$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure -{ - "versions": [ - "v1" - ] -} -``` - -The above example uses the `--insecure` flag. This leaves it subject to MITM -attacks. When kubectl accesses the cluster it uses a stored root certificate -and client certificates to access the server. (These are installed in the -`~/.kube` directory). Since cluster certificates are typically self-signed, it -make take special configuration to get your http client to use root -certificate. - -On some clusters, the apiserver does not require authentication; it may serve -on localhost, or be protected by a firewall. There is not a standard -for this. [Configuring Access to the API](../admin/accessing-the-api.md) -describes how a cluster admin can configure this. Such approaches may conflict -with future high-availability support. - -### Programmatic access to the API - -There are [client libraries](../devel/client-libraries.md) for accessing the API -from several languages. The Kubernetes project-supported -[Go](http://releases.k8s.io/HEAD/pkg/client/) -client library can use the same [kubeconfig file](kubeconfig-file.md) -as the kubectl CLI does to locate and authenticate to the apiserver. - -See documentation for other libraries for how they authenticate. - -### Accessing the API from a Pod - -When accessing the API from a pod, locating and authenticating -to the api server are somewhat different. - -The recommended way to locate the apiserver within the pod is with -the `kubernetes` DNS name, which resolves to a Service IP which in turn -will be routed to an apiserver. - -The recommended way to authenticate to the apiserver is with a -[service account](service-accounts.md) credential. By kube-system, a pod -is associated with a service account, and a credential (token) for that -service account is placed into the filesystem tree of each container in that pod, -at `/var/run/secrets/kubernetes.io/serviceaccount/token`. - -From within a pod the recommended ways to connect to API are: - - run a kubectl proxy as one of the containers in the pod, or as a background - process within a container. This proxies the - Kubernetes API to the localhost interface of the pod, so that other processes - in any container of the pod can access it. See this [example of using kubectl proxy - in a pod](../../examples/kubectl-container/). - - use the Go client library, and create a client using the `client.NewInCluster()` factory. - This handles locating and authenticating to the apiserver. -In each case, the credentials of the pod are used to communicate securely with the apiserver. - - -## Accessing services running on the cluster - -The previous section was about connecting the Kubernetes API server. This section is about -connecting to other services running on Kubernetes cluster. In Kubernetes, the -[nodes](../admin/node.md), [pods](pods.md) and [services](services.md) all have -their own IPs. In many cases, the node IPs, pod IPs, and some service IPs on a cluster will not be -routable, so they will not be reachable from a machine outside the cluster, -such as your desktop machine. - -### Ways to connect - -You have several options for connecting to nodes, pods and services from outside the cluster: - - Access services through public IPs. - - Use a service with type `NodePort` or `LoadBalancer` to make the service reachable outside - the cluster. See the [services](services.md) and - [kubectl expose](kubectl/kubectl_expose.md) documentation. - - Depending on your cluster environment, this may just expose the service to your corporate network, - or it may expose it to the internet. Think about whether the service being exposed is secure. - Does it do its own authentication? - - Place pods behind services. To access one specific pod from a set of replicas, such as for debugging, - place a unique label on the pod it and create a new service which selects this label. - - In most cases, it should not be necessary for application developer to directly access - nodes via their nodeIPs. - - Access services, nodes, or pods using the Proxy Verb. - - Does apiserver authentication and authorization prior to accessing the remote service. - Use this if the services are not secure enough to expose to the internet, or to gain - access to ports on the node IP, or for debugging. - - Proxies may cause problems for some web applications. - - Only works for HTTP/HTTPS. - - Described [here](#discovering-builtin-services). - - Access from a node or pod in the cluster. - - Run a pod, and then connect to a shell in it using [kubectl exec](kubectl/kubectl_exec.md). - Connect to other nodes, pods, and services from that shell. - - Some clusters may allow you to ssh to a node in the cluster. From there you may be able to - access cluster services. This is a non-standard method, and will work on some clusters but - not others. Browsers and other tools may or may not be installed. Cluster DNS may not work. - -### Discovering builtin services - -Typically, there are several services which are started on a cluster by kube-system. Get a list of these -with the `kubectl cluster-info` command: - -```console -$ kubectl cluster-info - - Kubernetes master is running at https://104.197.5.247 - elasticsearch-logging is running at https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging - kibana-logging is running at https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/kibana-logging - kube-dns is running at https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/kube-dns - grafana is running at https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana - heapster is running at https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/monitoring-heapster -``` - -This shows the proxy-verb URL for accessing each service. -For example, this cluster has cluster-level logging enabled (using Elasticsearch), which can be reached -at `https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging/` if suitable credentials are passed, or through a kubectl proxy at, for example: -`http://localhost:8080/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging/`. -(See [above](#accessing-the-cluster-api) for how to pass credentials or use kubectl proxy.) - -#### Manually constructing apiserver proxy URLs - -As mentioned above, you use the `kubectl cluster-info` command to retrieve the service's proxy URL. To create proxy URLs that include service endpoints, suffixes, and parameters, you simply append to the service's proxy URL: -`http://`*`kubernetes_master_address`*`/`*`service_path`*`/`*`service_name`*`/`*`service_endpoint-suffix-parameter`* - - -##### Examples - - * To access the Elasticsearch service endpoint `_search?q=user:kimchy`, you would use: `http://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging/_search?q=user:kimchy` - * To access the Elasticsearch cluster health information `_cluster/health?pretty=true`, you would use: `https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging/_cluster/health?pretty=true` - - ```json - { - "cluster_name" : "kubernetes_logging", - "status" : "yellow", - "timed_out" : false, - "number_of_nodes" : 1, - "number_of_data_nodes" : 1, - "active_primary_shards" : 5, - "active_shards" : 5, - "relocating_shards" : 0, - "initializing_shards" : 0, - "unassigned_shards" : 5 - } - ``` - -#### Using web browsers to access services running on the cluster - -You may be able to put an apiserver proxy url into the address bar of a browser. However: - - Web browsers cannot usually pass tokens, so you may need to use basic (password) auth. Apiserver can be configured to accept basic auth, - but your cluster may not be configured to accept basic auth. - - Some web apps may not work, particularly those with client side javascript that construct urls in a - way that is unaware of the proxy path prefix. - -## Requesting redirects - -The redirect capabilities have been deprecated and removed. Please use a proxy (see below) instead. - -## So Many Proxies - -There are several different proxies you may encounter when using Kubernetes: - 1. The [kubectl proxy](#directly-accessing-the-rest-api): - - runs on a user's desktop or in a pod - - proxies from a localhost address to the Kubernetes apiserver - - client to proxy uses HTTP - - proxy to apiserver uses HTTPS - - locates apiserver - - adds authentication headers - 1. The [apiserver proxy](#discovering-builtin-services): - - is a bastion built into the apiserver - - connects a user outside of the cluster to cluster IPs which otherwise might not be reachable - - runs in the apiserver processes - - client to proxy uses HTTPS (or http if apiserver so configured) - - proxy to target may use HTTP or HTTPS as chosen by proxy using available information - - can be used to reach a Node, Pod, or Service - - does load balancing when used to reach a Service - 1. The [kube proxy](services.md#ips-and-vips): - - runs on each node - - proxies UDP and TCP - - does not understand HTTP - - provides load balancing - - is just used to reach services - 1. A Proxy/Load-balancer in front of apiserver(s): - - existence and implementation varies from cluster to cluster (e.g. nginx) - - sits between all clients and one or more apiservers - - acts as load balancer if there are several apiservers. - 1. Cloud Load Balancers on external services: - - are provided by some cloud providers (e.g. AWS ELB, Google Cloud Load Balancer) - - are created automatically when the Kubernetes service has type `LoadBalancer` - - use UDP/TCP only - - implementation varies by cloud provider. - - - -Kubernetes users will typically not need to worry about anything other than the first two types. The cluster admin -will typically ensure that the latter types are setup correctly. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/accessing-the-cluster.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/annotations.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/annotations.md deleted file mode 100644 index 11acfadf2d64..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/annotations.md +++ /dev/null @@ -1,64 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/annotations.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Annotations - -We have [labels](labels.md) for identifying metadata. - -It is also useful to be able to attach arbitrary non-identifying metadata, for retrieval by API clients such as tools, libraries, etc. This information may be large, may be structured or unstructured, may include characters not permitted by labels, etc. Such information would not be used for object selection and therefore doesn't belong in labels. - -Like labels, annotations are key-value maps. - -```json -"annotations": { - "key1" : "value1", - "key2" : "value2" -} -``` - -Possible information that could be recorded in annotations: - -* fields managed by a declarative configuration layer, to distinguish them from client- and/or server-set default values and other auto-generated fields, fields set by auto-sizing/auto-scaling systems, etc., in order to facilitate merging -* build/release/image information (timestamps, release ids, git branch, PR numbers, image hashes, registry address, etc.) -* pointers to logging/monitoring/analytics/audit repos -* client library/tool information (e.g. for debugging purposes -- name, version, build info) -* other user and/or tool/system provenance info, such as URLs of related objects from other ecosystem components -* lightweight rollout tool metadata (config and/or checkpoints) -* phone/pager number(s) of person(s) responsible, or directory entry where that info could be found, such as a team website - -Yes, this information could be stored in an external database or directory, but that would make it much harder to produce shared client libraries and tools for deployment, management, introspection, etc. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/annotations.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/application-troubleshooting.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/application-troubleshooting.md deleted file mode 100644 index 5121693006d2..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/application-troubleshooting.md +++ /dev/null @@ -1,211 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/application-troubleshooting.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Application Troubleshooting - -This guide is to help users debug applications that are deployed into Kubernetes and not behaving correctly. -This is *not* a guide for people who want to debug their cluster. For that you should check out -[this guide](../admin/cluster-troubleshooting.md) - -**Table of Contents** - - -- [Application Troubleshooting](#application-troubleshooting) - - [FAQ](#faq) - - [Diagnosing the problem](#diagnosing-the-problem) - - [Debugging Pods](#debugging-pods) - - [My pod stays pending](#my-pod-stays-pending) - - [My pod stays waiting](#my-pod-stays-waiting) - - [My pod is crashing or otherwise unhealthy](#my-pod-is-crashing-or-otherwise-unhealthy) - - [Debugging Replication Controllers](#debugging-replication-controllers) - - [Debugging Services](#debugging-services) - - [My service is missing endpoints](#my-service-is-missing-endpoints) - - [Network traffic is not forwarded](#network-traffic-is-not-forwarded) - - [More information](#more-information) - - - -## FAQ - -Users are highly encouraged to check out our [FAQ](https://k8s.io/kubernetes/wiki/User-FAQ) - -## Diagnosing the problem - -The first step in troubleshooting is triage. What is the problem? Is it your Pods, your Replication Controller or -your Service? - * [Debugging Pods](#debugging-pods) - * [Debugging Replication Controllers](#debugging-replication-controllers) - * [Debugging Services](#debugging-services) - -### Debugging Pods - -The first step in debugging a Pod is taking a look at it. Check the current state of the Pod and recent events with the following command: - -```console -$ kubectl describe pods ${POD_NAME} -``` - -Look at the state of the containers in the pod. Are they all `Running`? Have there been recent restarts? - -Continue debugging depending on the state of the pods. - -#### My pod stays pending - -If a Pod is stuck in `Pending` it means that it can not be scheduled onto a node. Generally this is because -there are insufficient resources of one type or another that prevent scheduling. Look at the output of the -`kubectl describe ...` command above. There should be messages from the scheduler about why it can not schedule -your pod. Reasons include: - -* **You don't have enough resources**: You may have exhausted the supply of CPU or Memory in your cluster, in this case -you need to delete Pods, adjust resource requests, or add new nodes to your cluster. See [Compute Resources document](compute-resources.md#my-pods-are-pending-with-event-message-failedscheduling) for more information. - -* **You are using `hostPort`**: When you bind a Pod to a `hostPort` there are a limited number of places that pod can be -scheduled. In most cases, `hostPort` is unnecessary, try using a Service object to expose your Pod. If you do require -`hostPort` then you can only schedule as many Pods as there are nodes in your Kubernetes cluster. - - -#### My pod stays waiting - -If a Pod is stuck in the `Waiting` state, then it has been scheduled to a worker node, but it can't run on that machine. -Again, the information from `kubectl describe ...` should be informative. The most common cause of `Waiting` pods is a failure to pull the image. There are three things to check: -* Make sure that you have the name of the image correct -* Have you pushed the image to the repository? -* Run a manual `docker pull ` on your machine to see if the image can be pulled. - -#### My pod is crashing or otherwise unhealthy - -First, take a look at the logs of -the current container: - -```console -$ kubectl logs ${POD_NAME} ${CONTAINER_NAME} -``` - -If your container has previously crashed, you can access the previous container's crash log with: - -```console -$ kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME} -``` - -Alternately, you can run commands inside that container with `exec`: - -```console -$ kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN} -``` - -Note that `-c ${CONTAINER_NAME}` is optional and can be omitted for Pods that only contain a single container. - -As an example, to look at the logs from a running Cassandra pod, you might run - -```console -$ kubectl exec cassandra -- cat /var/log/cassandra/system.log -``` - - -If none of these approaches work, you can find the host machine that the pod is running on and SSH into that host, -but this should generally not be necessary given tools in the Kubernetes API. Therefore, if you find yourself needing to ssh into a machine, please file a -feature request on GitHub describing your use case and why these tools are insufficient. - -### Debugging Replication Controllers - -Replication controllers are fairly straightforward. They can either create Pods or they can't. If they can't -create pods, then please refer to the [instructions above](#debugging-pods) to debug your pods. - -You can also use `kubectl describe rc ${CONTROLLER_NAME}` to introspect events related to the replication -controller. - -### Debugging Services - -Services provide load balancing across a set of pods. There are several common problems that can make Services -not work properly. The following instructions should help debug Service problems. - -First, verify that there are endpoints for the service. For every Service object, the apiserver makes an `endpoints` resource available. - -You can view this resource with: - -```console -$ kubectl get endpoints ${SERVICE_NAME} -``` - -Make sure that the endpoints match up with the number of containers that you expect to be a member of your service. -For example, if your Service is for an nginx container with 3 replicas, you would expect to see three different -IP addresses in the Service's endpoints. - -#### My service is missing endpoints - -If you are missing endpoints, try listing pods using the labels that Service uses. Imagine that you have -a Service where the labels are: - -```yaml -... -spec: - - selector: - name: nginx - type: frontend -``` - -You can use: - -```console -$ kubectl get pods --selector=name=nginx,type=frontend -``` - -to list pods that match this selector. Verify that the list matches the Pods that you expect to provide your Service. - -If the list of pods matches expectations, but your endpoints are still empty, it's possible that you don't -have the right ports exposed. If your service has a `containerPort` specified, but the Pods that are -selected don't have that port listed, then they won't be added to the endpoints list. - -Verify that the pod's `containerPort` matches up with the Service's `containerPort` - -#### Network traffic is not forwarded - -If you can connect to the service, but the connection is immediately dropped, and there are endpoints -in the endpoints list, it's likely that the proxy can't contact your pods. - -There are three things to -check: - * Are your pods working correctly? Look for restart count, and [debug pods](#debugging-pods) - * Can you connect to your pods directly? Get the IP address for the Pod, and try to connect directly to that IP - * Is your application serving on the port that you configured? Kubernetes doesn't do port remapping, so if your application serves on 8080, the `containerPort` field needs to be 8080. - -#### More information - -If none of the above solves your problem, follow the instructions in [Debugging Service document](debugging-services.md) to make sure that your `Service` is running, has `Endpoints`, and your `Pods` are actually serving; you have DNS working, iptables rules installed, and kube-proxy does not seem to be misbehaving. - -You may also visit [troubleshooting document](../troubleshooting.md) for more information. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/application-troubleshooting.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/cadvisor.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/cadvisor.png deleted file mode 100644 index 4a5d863db1b79fdfdbf5464626e902cc15f9ca0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60222 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í^33)6yA=Yg;!XrOLw+%XJNG29y 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 jo_cm5BbJjGQu7uF_x5Fig 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 - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/compute-resources.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Compute Resources - -**Table of Contents** - - -- [Compute Resources](#compute-resources) - - [Container and Pod Resource Limits](#container-and-pod-resource-limits) - - [How Pods with Resource Limits are Scheduled](#how-pods-with-resource-limits-are-scheduled) - - [How Pods with Resource Limits are Run](#how-pods-with-resource-limits-are-run) - - [Monitoring Compute Resource Usage](#monitoring-compute-resource-usage) - - [Troubleshooting](#troubleshooting) - - [My pods are pending with event message failedScheduling](#my-pods-are-pending-with-event-message-failedscheduling) - - [My container is terminated](#my-container-is-terminated) - - [Planned Improvements](#planned-improvements) - - - -When specifying a [pod](pods.md), you can optionally specify how much CPU and memory (RAM) each -container needs. When containers have resource limits, the scheduler is able to make better -decisions about which nodes to place pods on, and contention for resources can be handled in a -consistent manner. - -*CPU* and *memory* are each a *resource type*. A resource type has a base unit. CPU is specified -in units of cores. Memory is specified in units of bytes. - -CPU and RAM are collectively referred to as *compute resources*, or just *resources*. Compute -resources are measureable quantities which can be requested, allocated, and consumed. They are -distinct from [API resources](working-with-resources.md). API resources, such as pods and -[services](services.md) are objects that can be written to and retrieved from the Kubernetes API -server. - -## Container and Pod Resource Limits - -Each container of a Pod can optionally specify `spec.container[].resources.limits.cpu` and/or -`spec.container[].resources.limits.memory`. The `spec.container[].resources.requests` field is not -currently used and need not be set. - -Specifying resource limits is optional. In some clusters, an unset value may be replaced with a -default value when a pod is created or updated. The default value depends on how the cluster is -configured. - -Although limits can only be specified on individual containers, it is convenient to talk about pod -resource limits. A *pod resource limit* for a particular resource type is the sum of the resource -limits of that type for each container in the pod, with unset values treated as zero. - -The following pod has two containers. Each has a limit of 0.5 core of cpu and 128MiB -(220 bytes) of memory. The pod can be said to have a limit of 1 core and 256MiB of -memory. - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: frontend -spec: - containers: - - name: db - image: mysql - resources: - limits: - memory: "128Mi" - cpu: "500m" - - name: wp - image: wordpress - resources: - limits: - memory: "128Mi" - cpu: "500m" -``` - -## How Pods with Resource Limits are Scheduled - -When a pod is created, the Kubernetes scheduler selects a node for the pod to -run on. Each node has a maximum capacity for each of the resource types: the -amount of CPU and memory it can provide for pods. The scheduler ensures that, -for each resource type (CPU and memory), the sum of the resource limits of the -containers scheduled to the node is less than the capacity of the node. Note -that although actual memory or CPU resource usage on nodes is very low, the -scheduler will still refuse to place pods onto nodes if the capacity check -fails. This protects against a resource shortage on a node when resource usage -later increases, such as due to a daily peak in request rate. - -Note: Although the scheduler normally spreads pods out across nodes, there are currently some cases -where pods with no limits (unset values) might all land on the same node. - -## How Pods with Resource Limits are Run - -When kubelet starts a container of a pod, it passes the CPU and memory limits to the container -runner (Docker or rkt). - -When using Docker: -- The `spec.container[].resources.limits.cpu` is multiplied by 1024, converted to an integer, and - used as the value of the [`--cpu-shares`]( - https://docs.docker.com/reference/run/#runtime-constraints-on-resources) flag to the `docker run` - command. -- The `spec.container[].resources.limits.memory` is converted to an integer, and used as the value - of the [`--memory`](https://docs.docker.com/reference/run/#runtime-constraints-on-resources) flag - to the `docker run` command. - -**TODO: document behavior for rkt** - -If a container exceeds its memory limit, it may be terminated. If it is restartable, it will be -restarted by kubelet, as will any other type of runtime failure. - -A container may or may not be allowed to exceed its CPU limit for extended periods of time. -However, it will not be killed for excessive CPU usage. - -To determine if a container cannot be scheduled or is being killed due to resource limits, see the -"Troubleshooting" section below. - -## Monitoring Compute Resource Usage - -The resource usage of a pod is reported as part of the Pod status. - -If [optional monitoring](http://releases.k8s.io/HEAD/cluster/addons/cluster-monitoring/README.md) is configured for your cluster, -then pod resource usage can be retrieved from the monitoring system. - -## Troubleshooting - -### My pods are pending with event message failedScheduling - -If the scheduler cannot find any node where a pod can fit, then the pod will remain unscheduled -until a place can be found. An event will be produced each time the scheduler fails to find a -place for the pod, like this: - -```console -$ kubectl describe pods/frontend | grep -A 3 Events -Events: - FirstSeen LastSeen Count From SubobjectPath Reason Message - Tue, 30 Jun 2015 09:01:41 -0700 Tue, 30 Jun 2015 09:39:27 -0700 128 {scheduler } failedScheduling Error scheduling: For each of these fitness predicates, pod frontend failed on at least one node: PodFitsResources. -``` - -If a pod or pods are pending with this message, then there are several things to try: -- Add more nodes to the cluster. -- Terminate unneeded pods to make room for pending pods. -- Check that the pod is not larger than all the nodes. For example, if all the nodes -have a capacity of `cpu: 1`, then a pod with a limit of `cpu: 1.1` will never be scheduled. - -You can check node capacities with the `kubectl get nodes -o ` command. -Here are some example command lines that extract just the necessary information: -- `kubectl get nodes -o yaml | grep '\sname\|cpu\|memory'` -- `kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, cap: .status.capacity}'` - -The [resource quota](../admin/resource-quota.md) feature can be configured -to limit the total amount of resources that can be consumed. If used in conjunction -with namespaces, it can prevent one team from hogging all the resources. - -### My container is terminated - -Your container may be terminated because it's resource-starved. To check if a container is being killed because it is hitting a resource limit, call `kubectl describe pod` -on the pod you are interested in: - -```console -[12:54:41] $ ./cluster/kubectl.sh describe pod simmemleak-hra99 -Name: simmemleak-hra99 -Namespace: default -Image(s): saadali/simmemleak -Node: kubernetes-minion-tf0f/10.240.216.66 -Labels: name=simmemleak -Status: Running -Reason: -Message: -IP: 10.244.2.75 -Replication Controllers: simmemleak (1/1 replicas created) -Containers: - simmemleak: - Image: saadali/simmemleak - Limits: - cpu: 100m - memory: 50Mi - State: Running - Started: Tue, 07 Jul 2015 12:54:41 -0700 - Ready: False - Restart Count: 5 -Conditions: - Type Status - Ready False -Events: - FirstSeen LastSeen Count From SubobjectPath Reason Message - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-minion-tf0f - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-minion-tf0f} implicitly required container POD pulled Pod container image "gcr.io/google_containers/pause:0.8.0" already present on machine - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-minion-tf0f} implicitly required container POD created Created with docker id 6a41280f516d - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-minion-tf0f} implicitly required container POD started Started with docker id 6a41280f516d - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-minion-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a -``` - -The `Restart Count: 5` indicates that the `simmemleak` container in this pod was terminated and restarted 5 times. - -Once [#10861](https://k8s.io/kubernetes/issues/10861) is resolved the reason for the termination of the last container will also be printed in this output. - -Until then you can call `get pod` with the `-o template -t ...` option to fetch the status of previously terminated containers: - -```console -[13:59:01] $ ./cluster/kubectl.sh get pod -o template -t '{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-60xbc -Container Name: simmemleak -LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]][13:59:03] clusterScaleDoc ~/go/src/k8s.io/kubernetes $ -``` - -We can see that this container was terminated because `reason:OOM Killed`, where *OOM* stands for Out Of Memory. - -## Planned Improvements - -The current system only allows resource quantities to be specified on a container. -It is planned to improve accounting for resources which are shared by all containers in a pod, -such as [EmptyDir volumes](volumes.md#emptydir). - -The current system only supports container limits for CPU and Memory. -It is planned to add new resource types, including a node disk space -resource, and a framework for adding custom [resource types](../design/resources.md#resource-types). - -The current system does not facilitate overcommitment of resources because resources reserved -with container limits are assured. It is planned to support multiple levels of [Quality of -Service](https://k8s.io/kubernetes/issues/168). - -Currently, one unit of CPU means different things on different cloud providers, and on different -machine types within the same cloud providers. For example, on AWS, the capacity of a node -is reported in [ECUs](http://aws.amazon.com/ec2/faqs/), while in GCE it is reported in logical -cores. We plan to revise the definition of the cpu resource to allow for more consistency -across providers and platforms. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/compute-resources.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/config-best-practices.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/config-best-practices.md deleted file mode 100644 index fa9016047701..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/config-best-practices.md +++ /dev/null @@ -1,59 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/config-best-practices.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Tips and tricks when working with config - -This document is meant to highlight and consolidate in one place configuration best practices that are introduced throughout the user-guide and getting-started documentation and examples. This is a living document so if you think of something that is not on this list but might be useful to others, please don't hesitate to file an issue or submit a PR. - -1. When writing configuration, use the latest stable API version (currently v1). -1. Configuration should be stored in version control before being pushed to the cluster. This allows configuration to be quickly rolled back if needed and will aid with cluster re-creation and restoration if the worst were to happen. -1. Use YAML rather than JSON. They can be used interchangeably in almost all scenarios but YAML tends to be more user-friendly for config. -1. Group related objects together in a single file. This is often better than separate files. -1. Use `kubectl create -f ` where possible. This looks for config objects in all `.yaml`, `.yml`, and `.json` files in `` and passes them to create. -1. Create a service before corresponding replication controllers so that the scheduler can spread the pods comprising the service. You can also create the replication controller without specifying replicas, create the service, then scale up the replication controller, which may work better in an example using progressive disclosure and may have benefits in real scenarios also, such as ensuring one replica works before creating lots of them) -1. Don't use `hostPort` unless absolutely necessary (e.g., for a node daemon) as it will prevent certain scheduling configurations due to port conflicts. Use the apiserver proxying or port forwarding for debug/admin access, or a service for external service access. If you need to expose a pod's port on the host machine, consider using a [NodePort](services.md#type--loadbalancer) service before resorting to `hostPort`. If you only need access to the port for debugging purposes, you can also use the [kubectl proxy and apiserver proxy](connecting-to-applications-proxy.md) or [kubectl port-forward](connecting-to-applications-port-forward.md). -1. Don't use `hostNetwork` for the same reasons as `hostPort`. -1. Don't specify default values unnecessarily, to simplify and minimize configs. For example, omit the selector and labels in ReplicationController if you want them to be the same as the labels in its podTemplate, since those fields are populated from the podTemplate labels by default. -1. Instead of attaching one label to a set of pods to represent a service (e.g., `service: myservice`) and another to represent the replication controller managing the pods (e.g., `controller: mycontroller`), attach labels that identify semantic attributes of your application or deployment and select the appropriate subsets in your service and replication controller, such as `{ app: myapp, tier: frontend, deployment: v3 }`. A service can be made to span multiple deployments, such as across rolling updates, by simply omitting release-specific labels from its selector, rather than updating a service's selector to match the replication controller's selector fully. -1. Use kubectl bulk operations (via files and/or labels) for get and delete. See [label selectors](labels.md#label-selectors) and [using labels effectively](managing-deployments.md#using-labels-effectively). -1. Use kubectl run and expose to quickly create and expose single container replication controllers. See the [quick start guide](quick-start.md) for an example. -1. Use headless services for easy service discovery when you don't need kube-proxy load balancing. See [headless services](services.md#headless-services). -1. Use kubectl delete rather than stop. Delete has a superset of the functionality of stop and stop is deprecated. -1. If there is a viable alternative to naked pods (i.e. pods not bound to a controller), go with the alternative. Controllers are almost always preferable to creating pods (except for some `restartPolicy: Never` scenarios). A minimal Job is coming. See [#1624](https://k8s.io/kubernetes/issues/1624). Naked pods will not be rescheduled in the event of node failure. -1. Put a version number or hash as a suffix to the name and in a label on a replication controller to facilitate rolling update, as we do for [--image](kubectl/kubectl_rolling-update.md). This is necessary because rolling-update actually creates a new controller as opposed to modifying the existing controller. This does not play well with version agnostic controller names. -1. Put an object description in an annotation to allow better introspection. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/config-best-practices.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/configuring-containers.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/configuring-containers.md deleted file mode 100644 index 5028ca940b73..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/configuring-containers.md +++ /dev/null @@ -1,213 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/configuring-containers.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes User Guide: Managing Applications: Configuring and launching containers - -**Table of Contents** - - -- [Kubernetes User Guide: Managing Applications: Configuring and launching containers](#kubernetes-user-guide-managing-applications-configuring-and-launching-containers) - - [Configuration in Kubernetes](#configuration-in-kubernetes) - - [Launching a container using a configuration file](#launching-a-container-using-a-configuration-file) - - [Validating configuration](#validating-configuration) - - [Environment variables and variable expansion](#environment-variables-and-variable-expansion) - - [Viewing pod status](#viewing-pod-status) - - [Viewing pod output](#viewing-pod-output) - - [Deleting pods](#deleting-pods) - - [What's next?](#whats-next) - - - -## Configuration in Kubernetes - -In addition to the imperative-style commands, such as `kubectl run` and `kubectl expose`, described [elsewhere](quick-start.md), Kubernetes supports declarative configuration. Often times, configuration files are preferable to imperative commands, since they can be checked into version control and changes to the files can be code reviewed, which is especially important for more complex configurations, producing a more robust, reliable and archival system. - -In the declarative style, all configuration is stored in YAML or JSON configuration files using Kubernetes's API resource schemas as the configuration schemas. `kubectl` can create, update, delete, and get API resources. The `apiVersion` (currently “v1”), resource `kind`, and resource `name` are used by `kubectl` to construct the appropriate API path to invoke for the specified operation. - -## Launching a container using a configuration file - -Kubernetes executes containers in [*Pods*](pods.md). A pod containing a simple Hello World container can be specified in YAML as follows: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: hello-world -spec: # specification of the pod’s contents - restartPolicy: Never - containers: - - name: hello - image: "ubuntu:14.04" - command: ["/bin/echo","hello”,”world"] -``` - -The value of `metadata.name`, `hello-world`, will be the name of the pod resource created, and must be unique within the cluster, whereas `containers[0].name` is just a nickname for the container within that pod. `image` is the name of the Docker image, which Kubernetes expects to be able to pull from a registry, the [Docker Hub](https://registry.hub.docker.com/) by default. - -`restartPolicy: Never` indicates that we just want to run the container once and then terminate the pod. - -The [`command`](containers.md#containers-and-commands) overrides the Docker container’s `Entrypoint`. Command arguments (corresponding to Docker’s `Cmd`) may be specified using `args`, as follows: - -```yaml - command: ["/bin/echo"] - args: ["hello","world"] -``` - -This pod can be created using the `create` command: - -```console -$ kubectl create -f ./hello-world.yaml -pods/hello-world -``` - -`kubectl` prints the resource type and name of the resource created when successful. - -## Validating configuration - -If you’re not sure you specified the resource correctly, you can ask `kubectl` to validate it for you: - -```console -$ kubectl create -f ./hello-world.yaml --validate -``` - -Let’s say you specified `entrypoint` instead of `command`. You’d see output as follows: - -```console -I0709 06:33:05.600829 14160 schema.go:126] unknown field: entrypoint -I0709 06:33:05.600988 14160 schema.go:129] this may be a false alarm, see https://k8s.io/kubernetes/issues/6842 -pods/hello-world -``` - -`kubectl create --validate` currently warns about problems it detects, but creates the resource anyway, unless a required field is absent or a field value is invalid. Unknown API fields are ignored, so be careful. This pod was created, but with no `command`, which is an optional field, since the image may specify an `Entrypoint`. -View the [Pod API -object](https://htmlpreview.github.io/?https://k8s.io/kubernetes/HEAD/docs/api-reference/definitions.html#_v1_pod) -to see the list of valid fields. - -## Environment variables and variable expansion - -Kubernetes [does not automatically run commands in a shell](https://k8s.io/kubernetes/wiki/User-FAQ#use-of-environment-variables-on-the-command-line) (not all images contain shells). If you would like to run your command in a shell, such as to expand environment variables (specified using `env`), you could do the following: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: hello-world -spec: # specification of the pod’s contents - restartPolicy: Never - containers: - - name: hello - image: "ubuntu:14.04" - env: - - name: MESSAGE - value: "hello world" - command: ["/bin/sh","-c"] - args: ["/bin/echo \"${MESSAGE}\""] -``` - -However, a shell isn’t necessary just to expand environment variables. Kubernetes will do it for you if you use [`$(ENVVAR)` syntax](../../docs/design/expansion.md): - -```yaml - command: ["/bin/echo"] - args: ["$(MESSAGE)"] -``` - -## Viewing pod status - -You can see the pod you created (actually all of your cluster's pods) using the `get` command. - -If you’re quick, it will look as follows: - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -hello-world 0/1 Pending 0 0s -``` - -Initially, a newly created pod is unscheduled -- no node has been selected to run it. Scheduling happens after creation, but is fast, so you normally shouldn’t see pods in an unscheduled state unless there’s a problem. - -After the pod has been scheduled, the image may need to be pulled to the node on which it was scheduled, if it hadn’t been pulled already. After a few seconds, you should see the container running: - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -hello-world 1/1 Running 0 5s -``` - -The `READY` column shows how many containers in the pod are running. - -Almost immediately after it starts running, this command will terminate. `kubectl` shows that the container is no longer running and displays the exit status: - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -hello-world 0/1 ExitCode:0 0 15s -``` - -## Viewing pod output - -You probably want to see the output of the command you ran. As with [`docker logs`](https://docs.docker.com/userguide/usingdocker/), `kubectl logs` will show you the output: - -```console -$ kubectl logs hello-world -hello world -``` - -## Deleting pods - -When you’re done looking at the output, you should delete the pod: - -```console -$ kubectl delete pod hello-world -pods/hello-world -``` - -As with `create`, `kubectl` prints the resource type and name of the resource deleted when successful. - -You can also use the resource/name format to specify the pod: - -```console -$ kubectl delete pods/hello-world -pods/hello-world -``` - -Terminated pods aren’t currently automatically deleted, so that you can observe their final status, so be sure to clean up your dead pods. - -On the other hand, containers and their logs are eventually deleted automatically in order to free up disk space on the nodes. - -## What's next? - -[Learn about deploying continuously running applications.](deploying-applications.md) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/configuring-containers.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-applications.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-applications.md deleted file mode 100644 index abf2ae4fa69a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-applications.md +++ /dev/null @@ -1,434 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/connecting-applications.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes User Guide: Managing Applications: Connecting applications - -**Table of Contents** - - -- [Kubernetes User Guide: Managing Applications: Connecting applications](#kubernetes-user-guide-managing-applications-connecting-applications) -- [The Kubernetes model for connecting containers](#the-kubernetes-model-for-connecting-containers) - - [Exposing pods to the cluster](#exposing-pods-to-the-cluster) - - [Creating a Service](#creating-a-service) - - [Accessing the Service](#accessing-the-service) - - [Environment Variables](#environment-variables) - - [DNS](#dns) - - [Securing the Service](#securing-the-service) - - [Exposing the Service](#exposing-the-service) - - [What's next?](#whats-next) - - - -# The Kubernetes model for connecting containers - -Now that you have a continuously running, replicated application you can expose it on a network. Before discussing the Kubernetes approach to networking, it is worthwhile to contrast it with the "normal" way networking works with Docker. - -By default, Docker uses host-private networking, so containers can talk to other containers only if they are on the same machine. In order for Docker containers to communicate across nodes, they must be allocated ports on the machine's own IP address, which are then forwarded or proxied to the containers. This obviously means that containers must either coordinate which ports they use very carefully or else be allocated ports dynamically. - -Coordinating ports across multiple developers is very difficult to do at scale and exposes users to cluster-level issues outside of their control. Kubernetes assumes that pods can communicate with other pods, regardless of which host they land on. We give every pod its own cluster-private-IP address so you do not need to explicitly create links between pods or mapping container ports to host ports. This means that containers within a Pod can all reach each other’s ports on localhost, and all pods in a cluster can see each other without NAT. The rest of this document will elaborate on how you can run reliable services on such a networking model. - -This guide uses a simple nginx server to demonstrate proof of concept. The same principles are embodied in a more complete [Jenkins CI application](http://blog.kubernetes.io/2015/07/strong-simple-ssl-for-kubernetes.html). - -## Exposing pods to the cluster - -We did this in a previous example, but lets do it once again and focus on the networking perspective. Create an nginx pod, and note that it has a container port specification: - -```yaml -$ cat nginxrc.yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: my-nginx -spec: - replicas: 2 - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx - ports: - - containerPort: 80 -``` - -This makes it accessible from any node in your cluster. Check the nodes the pod is running on: - -```console -$ kubectl create -f ./nginxrc.yaml -$ kubectl get pods -l app=nginx -o wide -my-nginx-6isf4 1/1 Running 0 2h e2e-test-beeps-minion-93ly -my-nginx-t26zt 1/1 Running 0 2h e2e-test-beeps-minion-93ly -``` - -Check your pods' IPs: - -```console -$ kubectl get pods -l app=nginx -o json | grep podIP - "podIP": "10.245.0.15", - "podIP": "10.245.0.14", -``` - -You should be able to ssh into any node in your cluster and curl both IPs. Note that the containers are *not* using port 80 on the node, nor are there any special NAT rules to route traffic to the pod. This means you can run multiple nginx pods on the same node all using the same containerPort and access them from any other pod or node in your cluster using IP. Like Docker, ports can still be published to the host node's interface(s), but the need for this is radically diminished because of the networking model. - -You can read more about [how we achieve this](../admin/networking.md#how-to-achieve-this) if you’re curious. - -## Creating a Service - -So we have pods running nginx in a flat, cluster wide, address space. In theory, you could talk to these pods directly, but what happens when a node dies? The pods die with it, and the replication controller will create new ones, with different IPs. This is the problem a Service solves. - -A Kubernetes Service is an abstraction which defines a logical set of Pods running somewhere in your cluster, that all provide the same functionality. When created, each Service is assigned a unique IP address (also called clusterIP). This address is tied to the lifespan of the Service, and will not change while the Service is alive. Pods can be configured to talk to the Service, and know that communication to the Service will be automatically load-balanced out to some pod that is a member of the Service. - -You can create a Service for your 2 nginx replicas with the following yaml: - -```yaml -$ cat nginxsvc.yaml -apiVersion: v1 -kind: Service -metadata: - name: nginxsvc - labels: - app: nginx -spec: - ports: - - port: 80 - protocol: TCP - selector: - app: nginx -``` - -This specification will create a Service which targets TCP port 80 on any Pod with the `app=nginx` label, and expose it on an abstracted Service port (`targetPort`: is the port the container accepts traffic on, `port`: is the abstracted Service port, which can be any port other pods use to access the Service). View [service API object](https://htmlpreview.github.io/?https://k8s.io/kubernetes/HEAD/docs/api-reference/definitions.html#_v1_service) to see the list of supported fields in service definition. -Check your Service: - -```console -$ kubectl get svc -NAME LABELS SELECTOR IP(S) PORT(S) -nginxsvc app=nginx app=nginx 10.0.116.146 80/TCP -``` - -As mentioned previously, a Service is backed by a group of pods. These pods are exposed through `endpoints`. The Service's selector will be evaluated continuously and the results will be POSTed to an Endpoints object also named `nginxsvc`. When a pod dies, it is automatically removed from the endpoints, and new pods matching the Service’s selector will automatically get added to the endpoints. Check the endpoints, and note that the IPs are the same as the pods created in the first step: - -```console -$ kubectl describe svc nginxsvc -Name: nginxsvc -Namespace: default -Labels: app=nginx -Selector: app=nginx -Type: ClusterIP -IP: 10.0.116.146 -Port: 80/TCP -Endpoints: 10.245.0.14:80,10.245.0.15:80 -Session Affinity: None -No events. - -$ kubectl get ep -NAME ENDPOINTS -nginxsvc 10.245.0.14:80,10.245.0.15:80 -``` - -You should now be able to curl the nginx Service on `10.0.116.146:80` from any node in your cluster. Note that the Service IP is completely virtual, it never hits the wire, if you’re curious about how this works you can read more about the [service proxy](services.md#virtual-ips-and-service-proxies). - -## Accessing the Service - -Kubernetes supports 2 primary modes of finding a Service - environment variables and DNS. The former works out of the box while the latter requires the [kube-dns cluster addon](http://releases.k8s.io/HEAD/cluster/addons/dns/README.md). - -### Environment Variables - -When a Pod is run on a Node, the kubelet adds a set of environment variables for each active Service. This introduces an ordering problem. To see why, inspect the environment of your running nginx pods: - -```console -$ kubectl exec my-nginx-6isf4 -- printenv | grep SERVICE -KUBERNETES_SERVICE_HOST=10.0.0.1 -KUBERNETES_SERVICE_PORT=443 -``` - -Note there’s no mention of your Service. This is because you created the replicas before the Service. Another disadvantage of doing this is that the scheduler might put both pods on the same machine, which will take your entire Service down if it dies. We can do this the right way by killing the 2 pods and waiting for the replication controller to recreate them. This time around the Service exists *before* the replicas. This will given you scheduler level Service spreading of your pods (provided all your nodes have equal capacity), as well as the right environment variables: - -```console -$ kubectl scale rc my-nginx --replicas=0; kubectl scale rc my-nginx --replicas=2; -$ kubectl get pods -l app=nginx -o wide -NAME READY STATUS RESTARTS AGE NODE -my-nginx-5j8ok 1/1 Running 0 2m node1 -my-nginx-90vaf 1/1 Running 0 2m node2 - -$ kubectl exec my-nginx-5j8ok -- printenv | grep SERVICE -KUBERNETES_SERVICE_PORT=443 -NGINXSVC_SERVICE_HOST=10.0.116.146 -KUBERNETES_SERVICE_HOST=10.0.0.1 -NGINXSVC_SERVICE_PORT=80 -``` - -### DNS - -Kubernetes offers a DNS cluster addon Service that uses skydns to automatically assign dns names to other Services. You can check if it’s running on your cluster: - -```console -$ kubectl get services kube-dns --namespace=kube-system -NAME LABELS SELECTOR IP(S) PORT(S) -kube-dns k8s-app=kube-dns 10.0.0.10 53/UDP - 53/TCP -``` - -If it isn’t running, you can [enable it](http://releases.k8s.io/HEAD/cluster/addons/dns/README.md#how-do-i-configure-it). The rest of this section will assume you have a Service with a long lived IP (nginxsvc), and a dns server that has assigned a name to that IP (the kube-dns cluster addon), so you can talk to the Service from any pod in your cluster using standard methods (e.g. gethostbyname). Let’s create another pod to test this: - -```yaml -$ cat curlpod.yaml -apiVersion: v1 -kind: Pod -metadata: - name: curlpod -spec: - containers: - - image: radial/busyboxplus:curl - command: - - sleep - - "3600" - imagePullPolicy: IfNotPresent - name: curlcontainer - restartPolicy: Always -``` - -And perform a lookup of the nginx Service - -```console -$ kubectl create -f ./curlpod.yaml -default/curlpod -$ kubectl get pods curlpod -NAME READY STATUS RESTARTS AGE -curlpod 1/1 Running 0 18s - -$ kubectl exec curlpod -- nslookup nginxsvc -Server: 10.0.0.10 -Address 1: 10.0.0.10 -Name: nginxsvc -Address 1: 10.0.116.146 -``` - -## Securing the Service - -Till now we have only accessed the nginx server from within the cluster. Before exposing the Service to the internet, you want to make sure the communication channel is secure. For this, you will need: -* Self signed certificates for https (unless you already have an identitiy certificate) -* An nginx server configured to use the cretificates -* A [secret](secrets.md) that makes the certificates accessible to pods - -You can acquire all these from the [nginx https example](../../examples/https-nginx/README.md), in short: - -```console -$ make keys secret KEY=/tmp/nginx.key CERT=/tmp/nginx.crt SECRET=/tmp/secret.json -$ kubectl create -f /tmp/secret.json -secrets/nginxsecret -$ kubectl get secrets -NAME TYPE DATA -default-token-il9rc kubernetes.io/service-account-token 1 -nginxsecret Opaque 2 -``` - -Now modify your nginx replicas to start a https server using the certificate in the secret, and the Service, to expose both ports (80 and 443): - -```yaml -$ cat nginx-app.yaml -apiVersion: v1 -kind: Service -metadata: - name: nginxsvc - labels: - app: nginx -spec: - type: NodePort - ports: - - port: 8080 - targetPort: 80 - protocol: TCP - name: http - - port: 443 - protocol: TCP - name: https - selector: - app: nginx ---- -apiVersion: v1 -kind: ReplicationController -metadata: - name: my-nginx -spec: - replicas: 1 - template: - metadata: - labels: - app: nginx - spec: - volumes: - - name: secret-volume - secret: - secretName: nginxsecret - containers: - - name: nginxhttps - image: bprashanth/nginxhttps:1.0 - ports: - - containerPort: 443 - - containerPort: 80 - volumeMounts: - - mountPath: /etc/nginx/ssl - name: secret-volume -``` - -Noteworthy points about the nginx-app manifest: -- It contains both rc and service specification in the same file -- The [nginx server](../../examples/https-nginx/default.conf) serves http traffic on port 80 and https traffic on 443, and nginx Service exposes both ports. -- Each container has access to the keys through a volume mounted at /etc/nginx/ssl. This is setup *before* the nginx server is started. - -```console -$ kubectl delete rc,svc -l app=nginx; kubectl create -f ./nginx-app.yaml -replicationcontrollers/my-nginx -services/nginxsvc -services/nginxsvc -replicationcontrollers/my-nginx -``` - -At this point you can reach the nginx server from any node. - -```console -$ kubectl get pods -o json | grep -i podip - "podIP": "10.1.0.80", -node $ curl -k https://10.1.0.80 -... -

      Welcome to nginx!

      -``` - -Note how we supplied the `-k` parameter to curl in the last step, this is because we don't know anything about the pods running nginx at certificate generation time, -so we have to tell curl to ignore the CName mismatch. By creating a Service we linked the CName used in the certificate with the actual DNS name used by pods during Service lookup. -Lets test this from a pod (the same secret is being reused for simplicity, the pod only needs nginx.crt to access the Service): - -```console -$ cat curlpod.yaml -vapiVersion: v1 -kind: ReplicationController -metadata: - name: curlrc -spec: - replicas: 1 - template: - metadata: - labels: - app: curlpod - spec: - volumes: - - name: secret-volume - secret: - secretName: nginxsecret - containers: - - name: curlpod - command: - - sh - - -c - - while true; do sleep 1; done - image: radial/busyboxplus:curl - volumeMounts: - - mountPath: /etc/nginx/ssl - name: secret-volume - -$ kubectl create -f ./curlpod.yaml -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -curlpod 1/1 Running 0 2m -my-nginx-7006w 1/1 Running 0 24m - -$ kubectl exec curlpod -- curl https://nginxsvc --cacert /etc/nginx/ssl/nginx.crt -... -Welcome to nginx! -... -``` - -## Exposing the Service - -For some parts of your applications you may want to expose a Service onto an external IP address. Kubernetes supports two ways of doing this: NodePorts and LoadBalancers. The Service created in the last section already used `NodePort`, so your nginx https replica is ready to serve traffic on the internet if your node has a public IP. - -```console -$ kubectl get svc nginxsvc -o json | grep -i nodeport -C 5 - { - "name": "http", - "protocol": "TCP", - "port": 80, - "targetPort": 80, - "nodePort": 32188 - }, - { - "name": "https", - "protocol": "TCP", - "port": 443, - "targetPort": 443, - "nodePort": 30645 - } - -$ kubectl get nodes -o json | grep ExternalIP -C 2 - { - "type": "ExternalIP", - "address": "104.197.63.17" - } --- - }, - { - "type": "ExternalIP", - "address": "104.154.89.170" - } -$ curl https://104.197.63.17:30645 -k -... -

      Welcome to nginx!

      -``` - -Lets now recreate the Service to use a cloud load balancer, just change the `Type` of Service in the nginx-app.yaml from `NodePort` to `LoadBalancer`: - -```console -$ kubectl delete rc, svc -l app=nginx -$ kubectl create -f ./nginx-app.yaml -$ kubectl get svc -o json | grep -i ingress -A 5 - "ingress": [ - { - "ip": "104.197.68.43" - } - ] - } -$ curl https://104.197.68.43 -k -... -Welcome to nginx! -``` - -## What's next? - -[Learn about more Kubernetes features that will help you run containers reliably in production.](production-pods.md) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/connecting-applications.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-to-applications-port-forward.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-to-applications-port-forward.md deleted file mode 100644 index a4c19f659abb..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-to-applications-port-forward.md +++ /dev/null @@ -1,85 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/connecting-to-applications-port-forward.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Connecting to applications: kubectl port-forward - -kubectl port-forward forwards connections to a local port to a port on a pod. Its man page is available [here](kubectl/kubectl_port-forward.md). Compared to [kubectl proxy](accessing-the-cluster.md#using-kubectl-proxy), `kubectl port-forward` is more generic as it can forward TCP traffic while `kubectl proxy` can only forward HTTP traffic. This guide demonstrates how to use `kubectl port-forward` to connect to a Redis database, which may be useful for database debugging. - -## Creating a Redis master - -```console -$ kubectl create examples/redis/redis-master.yaml -pods/redis-master -``` - -wait until the Redis master pod is Running and Ready, - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -redis-master 2/2 Running 0 41s -``` - - -## Connecting to the Redis master[a] - -The Redis master is listening on port 6397, to verify this, - -```console -$ kubectl get pods redis-master -t='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}' -6379 -``` - - -then we forward the port 6379 on the local workstation to the port 6379 of pod redis-master, - -```console -$ kubectl port-forward -p redis-master 6379:6379 -I0710 14:43:38.274550 3655 portforward.go:225] Forwarding from 127.0.0.1:6379 -> 6379 -I0710 14:43:38.274797 3655 portforward.go:225] Forwarding from [::1]:6379 -> 6379 -``` - -To verify the connection is successful, we run a redis-cli on the local workstation, - -```console -$ redis-cli -127.0.0.1:6379> ping -PONG -``` - -Now one can debug the database from the local workstation. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/connecting-to-applications-port-forward.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-to-applications-proxy.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-to-applications-proxy.md deleted file mode 100644 index a71a0b18f426..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/connecting-to-applications-proxy.md +++ /dev/null @@ -1,65 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/connecting-to-applications-proxy.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Connecting to applications: kubectl proxy and apiserver proxy - -You have seen the [basics](accessing-the-cluster.md) about `kubectl proxy` and `apiserver proxy`. This guide shows how to use them together to access a service([kube-ui](ui.md)) running on the Kubernetes cluster from your workstation. - - -## Getting the apiserver proxy URL of kube-ui - -kube-ui is deployed as a cluster add-on. To find its apiserver proxy URL, - -```console -$ kubectl cluster-info | grep "KubeUI" -KubeUI is running at https://173.255.119.104/api/v1/proxy/namespaces/kube-system/services/kube-ui -``` - -if this command does not find the URL, try the steps [here](ui.md#accessing-the-ui). - - -## Connecting to the kube-ui service from your local workstation - -The above proxy URL is an access to the kube-ui service provided by the apiserver. To access it, you still need to authenticate to the apiserver. `kubectl proxy` can handle the authentication. - -```console -$ kubectl proxy --port=8001 -Starting to serve on localhost:8001 -``` - -Now you can access the kube-ui service on your local workstation at [http://localhost:8001/api/v1/proxy/namespaces/kube-system/services/kube-ui](http://localhost:8001/api/v1/proxy/namespaces/kube-system/services/kube-ui) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/connecting-to-applications-proxy.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/container-environment.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/container-environment.md deleted file mode 100644 index 3cb4152a3d37..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/container-environment.md +++ /dev/null @@ -1,153 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/container-environment.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes Container Environment - -**Table of Contents** - - -- [Kubernetes Container Environment](#kubernetes-container-environment) - - [Overview](#overview) - - [Cluster Information](#cluster-information) - - [Container Information](#container-information) - - [Cluster Information](#cluster-information) - - [Container Hooks](#container-hooks) - - [Hook Details](#hook-details) - - [Hook Handler Execution](#hook-handler-execution) - - [Hook delivery guarantees](#hook-delivery-guarantees) - - [Hook Handler Implementations](#hook-handler-implementations) - - - - -## Overview - -This document describes the environment for Kubelet managed containers on a Kubernetes node (kNode).  In contrast to the Kubernetes cluster API, which provides an API for creating and managing containers, the Kubernetes container environment provides the container access to information about what else is going on in the cluster. - -This cluster information makes it possible to build applications that are *cluster aware*. -Additionally, the Kubernetes container environment defines a series of hooks that are surfaced to optional hook handlers defined as part of individual containers.  Container hooks are somewhat analogous to operating system signals in a traditional process model.   However these hooks are designed to make it easier to build reliable, scalable cloud applications in the Kubernetes cluster.  Containers that participate in this cluster lifecycle become *cluster native*. - -Another important part of the container environment is the file system that is available to the container. In Kubernetes, the filesystem is a combination of an [image](images.md) and one or more [volumes](volumes.md). - - -The following sections describe both the cluster information provided to containers, as well as the hooks and life-cycle that allows containers to interact with the management system. - -## Cluster Information - -There are two types of information that are available within the container environment.  There is information about the container itself, and there is information about other objects in the system. - -### Container Information - -Currently, the Pod name for the pod in which the container is running is set as the hostname of the container, and is accessible through all calls to access the hostname within the container (e.g. the hostname command, or the [gethostname][1] function call in libc), but this is planned to change in the future and should not be used. - -The Pod name and namespace are also available as environment variables via the [downward API](downward-api.md). Additionally, user-defined environment variables from the pod definition, are also available to the container, as are any environment variables specified statically in the Docker image. - -In the future, we anticipate expanding this information with richer information about the container.  Examples include available memory, number of restarts, and in general any state that you could get from the call to GET /pods on the API server. - -### Cluster Information - -Currently the list of all services that are running at the time when the container was created via the Kubernetes Cluster API are available to the container as environment variables.  The set of environment variables matches the syntax of Docker links. - -For a service named **foo** that maps to a container port named **bar**, the following variables are defined: - -```sh -FOO_SERVICE_HOST= -FOO_SERVICE_PORT= -``` - -Services have dedicated IP address, and are also surfaced to the container via DNS (If [DNS addon](http://releases.k8s.io/HEAD/cluster/addons/dns/) is enabled).  Of course DNS is still not an enumerable protocol, so we will continue to provide environment variables so that containers can do discovery. - -## Container Hooks - -*NB*: Container hooks are under active development, we anticipate adding additional hooks as the Kubernetes container management system evolves.* - -Container hooks provide information to the container about events in its management lifecycle.  For example, immediately after a container is started, it receives a *PostStart* hook.  These hooks are broadcast *into* the container with information about the life-cycle of the container.  They are different from the events provided by Docker and other systems which are *output* from the container.  Output events provide a log of what has already happened.  Input hooks provide real-time notification about things that are happening, but no historical log. - -### Hook Details - -There are currently two container hooks that are surfaced to containers, and two proposed hooks: - -*PreStart - ****Proposed*** - -This hook is sent immediately before a container is created.  It notifies that the container will be created immediately after the call completes.  No parameters are passed. *Note - *Some event handlers (namely ‘exec’ are incompatible with this event) - -*PostStart* - -This hook is sent immediately after a container is created.  It notifies the container that it has been created.  No parameters are passed to the handler. - -*PostRestart - ****Proposed*** - -This hook is called before the PostStart handler, when a container has been restarted, rather than started for the first time.  No parameters are passed to the handler. - -*PreStop* - -This hook is called immediately before a container is terminated.  This event handler is blocking, and must complete before the call to delete the container is sent to the Docker daemon. The SIGTERM notification sent by Docker is also still sent. - -A single parameter named reason is passed to the handler which contains the reason for termination.  Currently the valid values for reason are: - -* `Delete` - indicating an API call to delete the pod containing this container. -* `Health` - indicating that a health check of the container failed. -* `Dependency` - indicating that a dependency for the container or the pod is missing, and thus, the container needs to be restarted.  Examples include, the pod infra container crashing, or persistent disk failing for a container that mounts PD. - -Eventually, user specified reasons may be [added to the API](https://k8s.io/kubernetes/issues/137). - - -### Hook Handler Execution - -When a management hook occurs, the management system calls into any registered hook handlers in the container for that hook.  These hook handler calls are synchronous in the context of the pod containing the container. Note:this means that hook handler execution blocks any further management of the pod.  If your hook handler blocks, no other management (including [health checks](production-pods.md#liveness-and-readiness-probes-aka-health-checks)) will occur until the hook handler completes.  Blocking hook handlers do *not* affect management of other Pods.  Typically we expect that users will make their hook handlers as lightweight as possible, but there are cases where long running commands make sense (e.g. saving state prior to container stop) - -For hooks which have parameters, these parameters are passed to the event handler as a set of key/value pairs.  The details of this parameter passing is handler implementation dependent (see below). - -### Hook delivery guarantees - -Hook delivery is "at least one", which means that a hook may be called multiple times for any given event (e.g. "start" or "stop") and it is up to the hook implementer to be able to handle this -correctly. - -We expect double delivery to be rare, but in some cases if the `kubelet` restarts in the middle of sending a hook, the hook may be resent after the kubelet comes back up. - -Likewise, we only make a single delivery attempt. If (for example) an http hook receiver is down, and unable to take traffic, we do not make any attempts to resend. - -### Hook Handler Implementations - -Hook handlers are the way that hooks are surfaced to containers.  Containers can select the type of hook handler they would like to implement.  Kubernetes currently supports two different hook handler types: - - * Exec - Executes a specific command (e.g. pre-stop.sh) inside the cgroup and namespaces of the container.  Resources consumed by the command are counted against the container.  Commands which print "ok" to standard out (stdout) are treated as healthy, any other output is treated as container failures (and will cause kubelet to forcibly restart the container).  Parameters are passed to the command as traditional linux command line flags (e.g. pre-stop.sh --reason=HEALTH) - - * HTTP - Executes an HTTP request against a specific endpoint on the container.  HTTP error codes (5xx) and non-response/failure to connect are treated as container failures. Parameters are passed to the http endpoint as query args (e.g. http://some.server.com/some/path?reason=HEALTH) - -[1]: http://man7.org/linux/man-pages/man2/gethostname.2.html - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/container-environment.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/containers.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/containers.md deleted file mode 100644 index 4156ff9fc120..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/containers.md +++ /dev/null @@ -1,127 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/containers.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Containers with Kubernetes - -## Containers and commands - -So far the Pods we've seen have all used the `image` field to indicate what process Kubernetes -should run in a container. In this case, Kubernetes runs the image's default command. If we want -to run a particular command or override the image's defaults, there are two additional fields that -we can use: - -1. `Command`: Controls the actual command run by the image -2. `Args`: Controls the arguments passed to the command - -### How docker handles command and arguments - -Docker images have metadata associated with them that is used to store information about the image. -The image author may use this to define defaults for the command and arguments to run a container -when the user does not supply values. Docker calls the fields for commands and arguments -`Entrypoint` and `Cmd` respectively. The full details for this feature are too complicated to -describe here, mostly due to the fact that the docker API allows users to specify both of these -fields as either a string array or a string and there are subtle differences in how those cases are -handled. We encourage the curious to check out [docker's documentation]() for this feature. - -Kubernetes allows you to override both the image's default command (docker `Entrypoint`) and args -(docker `Cmd`) with the `Command` and `Args` fields of `Container`. The rules are: - -1. If you do not supply a `Command` or `Args` for a container, the defaults defined by the image - will be used -2. If you supply a `Command` but no `Args` for a container, only the supplied `Command` will be - used; the image's default arguments are ignored -3. If you supply only `Args`, the image's default command will be used with the arguments you - supply -4. If you supply a `Command` **and** `Args`, the image's defaults will be ignored and the values - you supply will be used - -Here are examples for these rules in table format - -| Image `Entrypoint` | Image `Cmd` | Container `Command` | Container `Args` | Command Run | -|--------------------|------------------|---------------------|--------------------|------------------| -| `[/ep-1]` | `[foo bar]` | <not set> | <not set> | `[ep-1 foo bar]` | -| `[/ep-1]` | `[foo bar]` | `[/ep-2]` | <not set> | `[ep-2]` | -| `[/ep-1]` | `[foo bar]` | <not set> | `[zoo boo]` | `[ep-1 zoo boo]` | -| `[/ep-1]` | `[foo bar]` | `[/ep-2]` | `[zoo boo]` | `[ep-2 zoo boo]` | - - -## Capabilities - -By default, Docker containers are "unprivileged" and cannot, for example, run a Docker daemon inside a Docker container. We can have fine grain control over the capabilities using cap-add and cap-drop.More details [here](https://docs.docker.com/reference/run/#runtime-privilege-linux-capabilities-and-lxc-configuration). - -The relationship between Docker's capabilities and [Linux capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html) - -| Docker's capabilities | Linux capabilities | -| ---- | ---- | -| SETPCAP | CAP_SETPCAP | -| SYS_MODULE | CAP_SYS_MODULE | -| SYS_RAWIO | CAP_SYS_RAWIO | -| SYS_PACCT | CAP_SYS_PACCT | -| SYS_ADMIN | CAP_SYS_ADMIN | -| SYS_NICE | CAP_SYS_NICE | -| SYS_RESOURCE | CAP_SYS_RESOURCE | -| SYS_TIME | CAP_SYS_TIME | -| SYS_TTY_CONFIG | CAP_SYS_TTY_CONFIG | -| MKNOD | CAP_MKNOD | -| AUDIT_WRITE | CAP_AUDIT_WRITE | -| AUDIT_CONTROL | CAP_AUDIT_CONTROL | -| MAC_OVERRIDE | CAP_MAC_OVERRIDE | -| MAC_ADMIN | CAP_MAC_ADMIN | -| NET_ADMIN | CAP_NET_ADMIN | -| SYSLOG | CAP_SYSLOG | -| CHOWN | CAP_CHOWN | -| NET_RAW | CAP_NET_RAW | -| DAC_OVERRIDE | CAP_DAC_OVERRIDE | -| FOWNER | CAP_FOWNER | -| DAC_READ_SEARCH | CAP_DAC_READ_SEARCH | -| FSETID | CAP_FSETID | -| KILL | CAP_KILL | -| SETGID | CAP_SETGID | -| SETUID | CAP_SETUID | -| LINUX_IMMUTABLE | CAP_LINUX_IMMUTABLE | -| NET_BIND_SERVICE | CAP_NET_BIND_SERVICE | -| NET_BROADCAST | CAP_NET_BROADCAST | -| IPC_LOCK | CAP_IPC_LOCK | -| IPC_OWNER | CAP_IPC_OWNER | -| SYS_CHROOT | CAP_SYS_CHROOT | -| SYS_PTRACE | CAP_SYS_PTRACE | -| SYS_BOOT | CAP_SYS_BOOT | -| LEASE | CAP_LEASE | -| SETFCAP | CAP_SETFCAP | -| WAKE_ALARM | CAP_WAKE_ALARM | -| BLOCK_SUSPEND | CAP_BLOCK_SUSPEND | - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/containers.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/debugging-services.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/debugging-services.md deleted file mode 100644 index 610dff3ae989..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/debugging-services.md +++ /dev/null @@ -1,560 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/debugging-services.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# My Service is not working - how to debug - -An issue that comes up rather frequently for new installations of Kubernetes is -that `Services` are not working properly. You've run all your `Pod`s and -`ReplicationController`s, but you get no response when you try to access them. -This document will hopefully help you to figure out what's going wrong. - -**Table of Contents** - - -- [My Service is not working - how to debug](#my-service-is-not-working---how-to-debug) - - [Conventions](#conventions) - - [Running commands in a Pod](#running-commands-in-a-pod) - - [Setup](#setup) - - [Does the Service exist?](#does-the-service-exist) - - [Does the Service work by DNS?](#does-the-service-work-by-dns) - - [Does any Service exist in DNS?](#does-any-service-exist-in-dns) - - [Does the Service work by IP?](#does-the-service-work-by-ip) - - [Is the Service correct?](#is-the-service-correct) - - [Does the Service have any Endpoints?](#does-the-service-have-any-endpoints) - - [Are the Pods working?](#are-the-pods-working) - - [Is the kube-proxy working?](#is-the-kube-proxy-working) - - [Is kube-proxy running?](#is-kube-proxy-running) - - [Is kube-proxy writing iptables rules?](#is-kube-proxy-writing-iptables-rules) - - [Is kube-proxy proxying?](#is-kube-proxy-proxying) - - [Seek help](#seek-help) - - [More information](#more-information) - - - -## Conventions - -Throughout this doc you will see various commands that you can run. Some -commands need to be run within `Pod`, others on a Kubernetes `Node`, and others -can run anywhere you have `kubectl` and credentials for the cluster. To make it -clear what is expected, this document will use the following conventions. - -If the command "COMMAND" is expected to run in a `Pod` and produce "OUTPUT": - -```console -u@pod$ COMMAND -OUTPUT -``` - -If the command "COMMAND" is expected to run on a `Node` and produce "OUTPUT": - -```console -u@node$ COMMAND -OUTPUT -``` - -If the command is "kubectl ARGS": - -```console -$ kubectl ARGS -OUTPUT -``` - -## Running commands in a Pod - -For many steps here you will want to see what a `Pod` running in the cluster -sees. Kubernetes does not directly support interactive `Pod`s (yet), but you can -approximate it: - -```console -$ cat < -``` - -or - -```console -$ kubectl exec -ti busybox-sleep sh -/ # -``` - -## Setup - -For the purposes of this walk-through, let's run some `Pod`s. Since you're -probably debugging your own `Service` you can substitute your own details, or you -can follow along and get a second data point. - -```console -$ kubectl run hostnames --image=gcr.io/google_containers/serve_hostname \ - --labels=app=hostnames \ - --port=9376 \ - --replicas=3 -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -hostnames hostnames gcr.io/google_containers/serve_hostname app=hostnames 3 -``` - -Note that this is the same as if you had started the `ReplicationController` with -the following YAML: - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: hostnames -spec: - selector: - app: hostnames - replicas: 3 - template: - metadata: - labels: - app: hostnames - spec: - containers: - - name: hostnames - image: gcr.io/google_containers/serve_hostname - ports: - - containerPort: 9376 - protocol: TCP -``` - -Confirm your `Pod`s are running: - -```console -$ kubectl get pods -l app=hostnames -NAME READY STATUS RESTARTS AGE -hostnames-0uton 1/1 Running 0 12s -hostnames-bvc05 1/1 Running 0 12s -hostnames-yp2kp 1/1 Running 0 12s -``` - -## Does the Service exist? - -The astute reader will have noticed that we did not actually create a `Service` -yet - that is intentional. This is a step that sometimes gets forgotten, and -is the first thing to check. - -So what would happen if I tried to access a non-existent `Service`? Assuming you -have another `Pod` that consumes this `Service` by name you would get something -like: - -```console -u@pod$ wget -qO- hostnames -wget: bad address 'hostname' -``` - -or: - -```console -u@pod$ echo $HOSTNAMES_SERVICE_HOST -``` - -So the first thing to check is whether that `Service` actually exists: - -```console -$ kubectl get svc hostnames -Error from server: service "hostnames" not found -``` - -So we have a culprit, let's create the `Service`. As before, this is for the -walk-through - you can use your own `Service`'s details here. - -```console -$ kubectl expose rc hostnames --port=80 --target-port=9376 -NAME LABELS SELECTOR IP(S) PORT(S) -hostnames app=hostnames app=hostnames 80/TCP -``` - -And read it back, just to be sure: - -```console -$ kubectl get svc hostnames -NAME LABELS SELECTOR IP(S) PORT(S) -hostnames app=hostnames app=hostnames 10.0.1.175 80/TCP -``` - -As before, this is the same as if you had started the `Service` with YAML: - -```yaml -apiVersion: v1 -kind: Service -metadata: - name: hostnames -spec: - selector: - app: hostnames - ports: - - name: default - protocol: TCP - port: 80 - targetPort: 9376 -``` - -Now you can confirm that the `Service` exists. - -## Does the Service work by DNS? - -From a `Pod` in the same `Namespace`: - -```console -u@pod$ nslookup hostnames -Server: 10.0.0.10 -Address: 10.0.0.10#53 - -Name: hostnames -Address: 10.0.1.175 -``` - -If this fails, perhaps your `Pod` and `Service` are in different -`Namespace`s, try a namespace-qualified name: - -```console -u@pod$ nslookup hostnames.default -Server: 10.0.0.10 -Address: 10.0.0.10#53 - -Name: hostnames.default -Address: 10.0.1.175 -``` - -If this works, you'll need to ensure that `Pod`s and `Service`s run in the same -`Namespace`. If this still fails, try a fully-qualified name: - -```console -u@pod$ nslookup hostnames.default.svc.cluster.local -Server: 10.0.0.10 -Address: 10.0.0.10#53 - -Name: hostnames.default.svc.cluster.local -Address: 10.0.1.175 -``` - -Note the suffix here: "default.svc.cluster.local". The "default" is the -`Namespace` we're operating in. The "svc" denotes that this is a `Service`. -The "cluster.local" is your cluster domain. - -You can also try this from a `Node` in the cluster (note: 10.0.0.10 is my DNS -`Service`): - -```console -u@node$ nslookup hostnames.default.svc.cluster.local 10.0.0.10 -Server: 10.0.0.10 -Address: 10.0.0.10#53 - -Name: hostnames.default.svc.cluster.local -Address: 10.0.1.175 -``` - -If you are able to do a fully-qualified name lookup but not a relative one, you -need to check that your `kubelet` is running with the right flags. -The `--cluster_dns` flag needs to point to your DNS `Service`'s IP and the -`--cluster_domain` flag needs to be your cluster's domain - we assumed -"cluster.local" in this document, but yours might be different, in which case -you should change that in all of the commands above. - -### Does any Service exist in DNS? - -If the above still fails - DNS lookups are not working for your `Service` - we -can take a step back and see what else is not working. The Kubernetes master -`Service` should always work: - -```console -u@pod$ nslookup kubernetes.default -Server: 10.0.0.10 -Address 1: 10.0.0.10 - -Name: kubernetes -Address 1: 10.0.0.1 -``` - -If this fails, you might need to go to the kube-proxy section of this doc, or -even go back to the top of this document and start over, but instead of -debugging your own `Service`, debug DNS. - -## Does the Service work by IP? - -The next thing to test is whether your `Service` works at all. From a -`Node` in your cluster, access the `Service`'s IP (from `kubectl get` above). - -```console -u@node$ curl 10.0.1.175:80 -hostnames-0uton - -u@node$ curl 10.0.1.175:80 -hostnames-yp2kp - -u@node$ curl 10.0.1.175:80 -hostnames-bvc05 -``` - -If your `Service` is working, you should get correct responses. If not, there -are a number of things that could be going wrong. Read on. - -## Is the Service correct? - -It might sound silly, but you should really double and triple check that your -`Service` is correct and matches your `Pods`. Read back your `Service` and -verify it: - -```console -$ kubectl get service hostnames -o json -{ - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "hostnames", - "namespace": "default", - "selfLink": "/api/v1/namespaces/default/services/hostnames", - "uid": "428c8b6c-24bc-11e5-936d-42010af0a9bc", - "resourceVersion": "347189", - "creationTimestamp": "2015-07-07T15:24:29Z", - "labels": { - "app": "hostnames" - } - }, - "spec": { - "ports": [ - { - "name": "default", - "protocol": "TCP", - "port": 80, - "targetPort": 9376, - "nodePort": 0 - } - ], - "selector": { - "app": "hostnames" - }, - "clusterIP": "10.0.1.175", - "type": "ClusterIP", - "sessionAffinity": "None" - }, - "status": { - "loadBalancer": {} - } -} -``` - -Is the port you are trying to access in `spec.ports[]`? Is the `targetPort` -correct for your `Pod`s? If you meant it to be a numeric port, is it a number -(9376) or a string "9376"? If you meant it to be a named port, do your `Pod`s -expose a port with the same name? Is the port's `protocol` the same as the -`Pod`'s? - -## Does the Service have any Endpoints? - -If you got this far, we assume that you have confirmed that your `Service` -exists and resolves by DNS. Now let's check that the `Pod`s you ran are -actually being selected by the `Service`. - -Earlier we saw that the `Pod`s were running. We can re-check that: - -```console -$ kubectl get pods -l app=hostnames -NAME READY STATUS RESTARTS AGE -hostnames-0uton 1/1 Running 0 1h -hostnames-bvc05 1/1 Running 0 1h -hostnames-yp2kp 1/1 Running 0 1h -``` - -The "AGE" column says that these `Pod`s are about an hour old, which implies that -they are running fine and not crashing. - -The `-l app=hostnames` argument is a label selector - just like our `Service` -has. Inside the Kubernetes system is a control loop which evaluates the -selector of every `Service` and save the results into an `Endpoints` object. - -```console -$ kubectl get endpoints hostnames -NAME ENDPOINTS -hostnames 10.244.0.5:9376,10.244.0.6:9376,10.244.0.7:9376 -``` - -This confirms that the control loop has found the correct `Pod`s for your -`Service`. If the `hostnames` row is blank, you should check that the -`spec.selector` field of your `Service` actually selects for `metadata.labels` -values on your `Pod`s. - -## Are the Pods working? - -At this point, we know that your `Service` exists and has selected your `Pod`s. -Let's check that the `Pod`s are actually working - we can bypass the `Service` -mechanism and go straight to the `Pod`s. - -```console -u@pod$ wget -qO- 10.244.0.5:9376 -hostnames-0uton - -pod $ wget -qO- 10.244.0.6:9376 -hostnames-bvc05 - -u@pod$ wget -qO- 10.244.0.7:9376 -hostnames-yp2kp -``` - -We expect each `Pod` in the `Endpoints` list to return its own hostname. If -this is not what happens (or whatever the correct behavior is for your own -`Pod`s), you should investigate what's happening there. You might find -`kubectl logs` to be useful or `kubectl exec` directly to your `Pod`s and check -service from there. - -## Is the kube-proxy working? - -If you get here, your `Service` is running, has `Endpoints`, and your `Pod`s -are actually serving. At this point, the whole `Service` proxy mechanism is -suspect. Let's confirm it, piece by piece. - -### Is kube-proxy running? - -Confirm that `kube-proxy` is running on your `Node`s. You should get something -like the below: - -```console -u@node$ ps auxw | grep kube-proxy -root 4194 0.4 0.1 101864 17696 ? Sl Jul04 25:43 /usr/local/bin/kube-proxy --master=https://kubernetes-master --kubeconfig=/var/lib/kube-proxy/kubeconfig --v=2 -``` - -Next, confirm that it is not failing something obvious, like contacting the -master. To do this, you'll have to look at the logs. Accessing the logs -depends on your `Node` OS. On some OSes it is a file, such as -/var/log/kube-proxy.log, while other OSes use `journalctl` to access logs. You -should see something like: - -```console -I0707 17:34:53.945651 30031 server.go:88] Running in resource-only container "/kube-proxy" -I0707 17:34:53.945921 30031 proxier.go:121] Setting proxy IP to 10.240.115.247 and initializing iptables -I0707 17:34:54.053023 30031 roundrobin.go:262] LoadBalancerRR: Setting endpoints for default/kubernetes: to [10.240.169.188:443] -I0707 17:34:54.053175 30031 roundrobin.go:262] LoadBalancerRR: Setting endpoints for default/hostnames:default to [10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376] -I0707 17:34:54.053284 30031 roundrobin.go:262] LoadBalancerRR: Setting endpoints for default/kube-dns:dns to [10.244.3.3:53] -I0707 17:34:54.053310 30031 roundrobin.go:262] LoadBalancerRR: Setting endpoints for default/kube-dns:dns-tcp to [10.244.3.3:53] -I0707 17:34:54.054780 30031 proxier.go:306] Adding new service "default/kubernetes:" at 10.0.0.1:443/TCP -I0707 17:34:54.054903 30031 proxier.go:247] Proxying for service "default/kubernetes:" on TCP port 40074 -I0707 17:34:54.079181 30031 proxier.go:306] Adding new service "default/hostnames:default" at 10.0.1.175:80/TCP -I0707 17:34:54.079273 30031 proxier.go:247] Proxying for service "default/hostnames:default" on TCP port 48577 -I0707 17:34:54.113665 30031 proxier.go:306] Adding new service "default/kube-dns:dns" at 10.0.0.10:53/UDP -I0707 17:34:54.113776 30031 proxier.go:247] Proxying for service "default/kube-dns:dns" on UDP port 34149 -I0707 17:34:54.120224 30031 proxier.go:306] Adding new service "default/kube-dns:dns-tcp" at 10.0.0.10:53/TCP -I0707 17:34:54.120297 30031 proxier.go:247] Proxying for service "default/kube-dns:dns-tcp" on TCP port 53476 -I0707 17:34:54.902313 30031 proxysocket.go:130] Accepted TCP connection from 10.244.3.3:42670 to 10.244.3.1:40074 -I0707 17:34:54.903107 30031 proxysocket.go:130] Accepted TCP connection from 10.244.3.3:42671 to 10.244.3.1:40074 -I0707 17:35:46.015868 30031 proxysocket.go:246] New UDP connection from 10.244.3.2:57493 -I0707 17:35:46.017061 30031 proxysocket.go:246] New UDP connection from 10.244.3.2:55471 -``` - -If you see error messages about not being able to contact the master, you -should double-check your `Node` configuration and installation steps. - -### Is kube-proxy writing iptables rules? - -One of the main responsibilities of `kube-proxy` is to write the `iptables` -rules which implement `Service`s. Let's check that those rules are getting -written. - -```console -u@node$ iptables-save | grep hostnames --A KUBE-PORTALS-CONTAINER -d 10.0.1.175/32 -p tcp -m comment --comment "default/hostnames:default" -m tcp --dport 80 -j REDIRECT --to-ports 48577 --A KUBE-PORTALS-HOST -d 10.0.1.175/32 -p tcp -m comment --comment "default/hostnames:default" -m tcp --dport 80 -j DNAT --to-destination 10.240.115.247:48577 -``` - -There should be 2 rules for each port on your `Service` (just one in this -example) - a "KUBE-PORTALS-CONTAINER" and a "KUBE-PORTALS-HOST". If you do -not see these, try restarting `kube-proxy` with the `-V` flag set to 4, and -then look at the logs again. - -### Is kube-proxy proxying? - -Assuming you do see the above rules, try again to access your `Service` by IP: - -```console -u@node$ curl 10.0.1.175:80 -hostnames-0uton -``` - -If this fails, we can try accessing the proxy directly. Look back at the -`iptables-save` output above, and extract the port number that `kube-proxy` is -using for your `Service`. In the above examples it is "48577". Now connect to -that: - -```console -u@node$ curl localhost:48577 -hostnames-yp2kp -``` - -If this still fails, look at the `kube-proxy` logs for specific lines like: - -```console -Setting endpoints for default/hostnames:default to [10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376] -``` - -If you don't see those, try restarting `kube-proxy` with the `-V` flag set to 4, and -then look at the logs again. - -## Seek help - -If you get this far, something very strange is happening. Your `Service` is -running, has `Endpoints`, and your `Pod`s are actually serving. You have DNS -working, `iptables` rules installed, and `kube-proxy` does not seem to be -misbehaving. And yet your `Service` is not working. You should probably let -us know, so we can help investigate! - -Contact us on -[IRC](http://webchat.freenode.net/?channels=google-containers) or -[email](https://groups.google.com/forum/#!forum/google-containers) or -[GitHub](https://k8s.io/kubernetes). - -## More information - -Visit [troubleshooting document](../troubleshooting.md) for more information. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/debugging-services.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/deploying-applications.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/deploying-applications.md deleted file mode 100644 index ca92dd571f1f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/deploying-applications.md +++ /dev/null @@ -1,160 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/deploying-applications.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes User Guide: Managing Applications: Deploying continuously running applications - -**Table of Contents** - - -- [Kubernetes User Guide: Managing Applications: Deploying continuously running applications](#kubernetes-user-guide-managing-applications-deploying-continuously-running-applications) - - [Launching a set of replicas using a configuration file](#launching-a-set-of-replicas-using-a-configuration-file) - - [Viewing replication controller status](#viewing-replication-controller-status) - - [Deleting replication controllers](#deleting-replication-controllers) - - [Labels](#labels) - - [What's next?](#whats-next) - - - -You previously read about how to quickly deploy a simple replicated application using [`kubectl run`](quick-start.md) and how to configure and launch single-run containers using pods ([Configuring containers](configuring-containers.md)). Here you’ll use the configuration-based approach to deploy a continuously running, replicated application. - -## Launching a set of replicas using a configuration file - -Kubernetes creates and manages sets of replicated containers (actually, replicated [Pods](pods.md)) using [*Replication Controllers*](replication-controller.md). - -A replication controller simply ensures that a specified number of pod "replicas" are running at any one time. If there are too many, it will kill some. If there are too few, it will start more. It’s analogous to Google Compute Engine’s [Instance Group Manager](https://cloud.google.com/compute/docs/instance-groups/manager/) or AWS’s [Auto-scaling Group](http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AutoScalingGroup.html) (with no scaling policies). - -The replication controller created to run nginx by `kubctl run` in the [Quick start](quick-start.md) could be specified using YAML as follows: - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: my-nginx -spec: - replicas: 2 - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx - ports: - - containerPort: 80 -``` - -Some differences compared to specifying just a pod are that the `kind` is `ReplicationController`, the number of `replicas` desired is specified, and the pod specification is under the `template` field. The names of the pods don’t need to be specified explicitly because they are generated from the name of the replication controller. -View the [replication controller API -object](https://htmlpreview.github.io/?https://k8s.io/kubernetes/HEAD/docs/api-reference/definitions.html#_v1_replicationcontroller) -to view the list of supported fields. - -This replication controller can be created using `create`, just as with pods: - -```console -$ kubectl create -f ./nginx-rc.yaml -replicationcontrollers/my-nginx -``` - -Unlike in the case where you directly create pods, a replication controller replaces pods that are deleted or terminated for any reason, such as in the case of node failure. For this reason, we recommend that you use a replication controller for a continuously running application even if your application requires only a single pod, in which case you can omit `replicas` and it will default to a single replica. - -## Viewing replication controller status - -You can view the replication controller you created using `get`: - -```console -$ kubectl get rc -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -my-nginx nginx nginx app=nginx 2 -``` - -This tells you that your controller will ensure that you have two nginx replicas. - -You can see those replicas using `get`, just as with pods you created directly: - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -my-nginx-065jq 1/1 Running 0 51s -my-nginx-buaiq 1/1 Running 0 51s -``` - -## Deleting replication controllers - -When you want to kill your application, delete your replication controller, as in the [Quick start](quick-start.md): - -```console -$ kubectl delete rc my-nginx -replicationcontrollers/my-nginx -``` - -By default, this will also cause the pods managed by the replication controller to be deleted. If there were a large number of pods, this may take a while to complete. If you want to leave the pods running, specify `--cascade=false`. - -If you try to delete the pods before deleting the replication controller, it will just replace them, as it is supposed to do. - -## Labels - -Kubernetes uses user-defined key-value attributes called [*labels*](labels.md) to categorize and identify sets of resources, such as pods and replication controllers. The example above specified a single label in the pod template, with key `app` and value `nginx`. All pods created carry that label, which can be viewed using `-L`: - -```console -$ kubectl get pods -L app -NAME READY STATUS RESTARTS AGE APP -my-nginx-afv12 0/1 Running 0 3s nginx -my-nginx-lg99z 0/1 Running 0 3s nginx -``` - -The labels from the pod template are copied to the replication controller’s labels by default, as well -- all resources in Kubernetes support labels: - -```console -$ kubectl get rc my-nginx -L app -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS APP -my-nginx nginx nginx app=nginx 2 nginx -``` - -More importantly, the pod template’s labels are used to create a [`selector`](labels.md#label-selectors) that will match pods carrying those labels. You can see this field by requesting it using the [Go template output format of `kubectl get`](kubectl/kubectl_get.md): - -```console -$ kubectl get rc my-nginx -o template --template="{{.spec.selector}}" -map[app:nginx] -``` - -You could also specify the `selector` explicitly, such as if you wanted to specify labels in the pod template that you didn’t want to select on, but you should ensure that the selector will match the labels of the pods created from the pod template, and that it won’t match pods created by other replication controllers. The most straightforward way to ensure the latter is to create a unique label value for the replication controller, and to specify it in both the pod template’s labels and in the selector. - -## What's next? - -[Learn about exposing applications to users and clients, and connecting tiers of your application together.](connecting-applications.md) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/deploying-applications.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/docker-cli-to-kubectl.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/docker-cli-to-kubectl.md deleted file mode 100644 index ebdae76c7078..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/docker-cli-to-kubectl.md +++ /dev/null @@ -1,337 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/docker-cli-to-kubectl.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# kubectl for docker users - -In this doc, we introduce the Kubernetes command line to for interacting with the api to docker-cli users. The tool, kubectl, is designed to be familiar to docker-cli users but there are a few necessary differences. Each section of this doc highlights a docker subcommand explains the kubectl equivalent. - -**Table of Contents** - - -- [kubectl for docker users](#kubectl-for-docker-users) - - [docker run](#docker-run) - - [docker ps](#docker-ps) - - [docker attach](#docker-attach) - - [docker exec](#docker-exec) - - [docker logs](#docker-logs) - - [docker stop and docker rm](#docker-stop-and-docker-rm) - - [docker login](#docker-login) - - [docker version](#docker-version) - - [docker info](#docker-info) - - - -#### docker run - -How do I run an nginx container and expose it to the world? Checkout [kubectl run](kubectl/kubectl_run.md). - -With docker: - -```console -$ docker run -d --restart=always --name nginx-app -p 80:80 nginx -a9ec34d9878748d2f33dc20cb25c714ff21da8d40558b45bfaec9955859075d0 -$ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -a9ec34d98787 nginx "nginx -g 'daemon of 2 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, 443/tcp nginx-app -``` - -With kubectl: - -```console -# start the pod running nginx -$ kubectl run --image=nginx nginx-app -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -nginx-app nginx-app nginx run=nginx-app 1 -# expose a port through with a service -$ kubectl expose rc nginx-app --port=80 --name=nginx-http -NAME LABELS SELECTOR IP(S) PORT(S) -nginx-http run=nginx-app run=nginx-app 80/TCP -``` - -With kubectl, we create a [replication controller](replication-controller.md) which will make sure that N pods are running nginx (where N is the number of replicas stated in the spec, which defaults to 1). We also create a [service](services.md) with a selector that matches the replication controller's selector. See the [Quick start](quick-start.md) for more information. - -#### docker ps - -How do I list what is currently running? Checkout [kubectl get](kubectl/kubectl_get.md). - -With docker: - -```console -$ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -a9ec34d98787 nginx "nginx -g 'daemon of About an hour ago Up About an hour 0.0.0.0:80->80/tcp, 443/tcp nginx-app -``` - -With kubectl: - -```console -$ kubectl get po -NAME READY STATUS RESTARTS AGE -nginx-app-5jyvm 1/1 Running 0 1h -``` - -#### docker attach - -How do I attach to a process that is already running in a container? Checkout [kubectl attach](kubectl/kubectl_attach.md) - -With docker: - -```console -$ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -a9ec34d98787 nginx "nginx -g 'daemon of 8 minutes ago Up 8 minutes 0.0.0.0:80->80/tcp, 443/tcp nginx-app -$ docker attach -it a9ec34d98787 -... -``` - -With kubectl: - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -nginx-app-5jyvm 1/1 Running 0 10m -$ kubectl attach -it nginx-app-5jyvm -... - -``` - -#### docker exec - -How do I execute a command in a container? Checkout [kubectl exec](kubectl/kubectl_exec.md). - -With docker: - -```console - -$ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -a9ec34d98787 nginx "nginx -g 'daemon of 8 minutes ago Up 8 minutes 0.0.0.0:80->80/tcp, 443/tcp nginx-app -$ docker exec a9ec34d98787 cat /etc/hostname -a9ec34d98787 - -``` - -With kubectl: - -```console - -$ kubectl get po -NAME READY STATUS RESTARTS AGE -nginx-app-5jyvm 1/1 Running 0 10m -$ kubectl exec nginx-app-5jyvm -- cat /etc/hostname -nginx-app-5jyvm - -``` - -What about interactive commands? - - -With docker: - -```console - -$ docker exec -ti a9ec34d98787 /bin/sh - -# exit - -``` - -With kubectl: - -```console - -$ kubectl exec -ti nginx-app-5jyvm -- /bin/sh - -# exit - -``` - -For more information see [Getting into containers](getting-into-containers.md). - -#### docker logs - -How do I follow stdout/stderr of a running process? Checkout [kubectl logs](kubectl/kubectl_logs.md). - - -With docker: - -```console - -$ docker logs -f a9e -192.168.9.1 - - [14/Jul/2015:01:04:02 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.35.0" "-" -192.168.9.1 - - [14/Jul/2015:01:04:03 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.35.0" "-" - -``` - -With kubectl: - -```console - -$ kubectl logs -f nginx-app-zibvs -10.240.63.110 - - [14/Jul/2015:01:09:01 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.26.0" "-" -10.240.63.110 - - [14/Jul/2015:01:09:02 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.26.0" "-" - -``` - -Now's a good time to mention slight difference between pods and containers; by default pods will not terminate if their processes exit. Instead it will restart the process. This is similar to the docker run option `--restart=always` with one major difference. In docker, the output for each invocation of the process is concatenated but for Kubernetes, each invokation is separate. To see the output from a prevoius run in Kubernetes, do this: - -```console - -$ kubectl logs --previous nginx-app-zibvs -10.240.63.110 - - [14/Jul/2015:01:09:01 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.26.0" "-" -10.240.63.110 - - [14/Jul/2015:01:09:02 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.26.0" "-" - -``` - -See [Logging](logging.md) for more information. - -#### docker stop and docker rm - -How do I stop and delete a running process? Checkout [kubectl delete](kubectl/kubectl_delete.md). - -With docker - -```console - -$ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -a9ec34d98787 nginx "nginx -g 'daemon of 22 hours ago Up 22 hours 0.0.0.0:80->80/tcp, 443/tcp nginx-app -$ docker stop a9ec34d98787 -a9ec34d98787 -$ docker rm a9ec34d98787 -a9ec34d98787 - -``` - -With kubectl: - -```console - -$ kubectl get rc nginx-app -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -nginx-app nginx-app nginx run=nginx-app 1 -$ kubectl get po -NAME READY STATUS RESTARTS AGE -nginx-app-aualv 1/1 Running 0 16s -$ kubectl delete rc nginx-app -NAME READY STATUS RESTARTS AGE -nginx-app-aualv 1/1 Running 0 16s -$ kubectl get po -NAME READY STATUS RESTARTS AGE - -``` - -Notice that we don't delete the pod directly. With kubectl we want to delete the replication controller that owns the pod. If we delete the pod directly, the replication controller will recreate the pod. - -#### docker login - -There is no direct analog of `docker login` in kubectl. If you are interested in using Kubernetes with a private registry, see [Using a Private Registry](images.md#using-a-private-registry). - -#### docker version - -How do I get the version of my client and server? Checkout [kubectl version](kubectl/kubectl_version.md). - -With docker: - -```console - -$ docker version -Client version: 1.7.0 -Client API version: 1.19 -Go version (client): go1.4.2 -Git commit (client): 0baf609 -OS/Arch (client): linux/amd64 -Server version: 1.7.0 -Server API version: 1.19 -Go version (server): go1.4.2 -Git commit (server): 0baf609 -OS/Arch (server): linux/amd64 - -``` - -With kubectl: - -```console - -$ kubectl version -Client Version: version.Info{Major:"0", Minor:"20.1", GitVersion:"v0.20.1", GitCommit:"", GitTreeState:"not a git tree"} -Server Version: version.Info{Major:"0", Minor:"21+", GitVersion:"v0.21.1-411-g32699e873ae1ca-dirty", GitCommit:"32699e873ae1caa01812e41de7eab28df4358ee4", GitTreeState:"dirty"} - -``` - -#### docker info - -How do I get miscellaneous info about my environment and configuration? Checkout [kubectl cluster-info](kubectl/kubectl_cluster-info.md). - -With docker: - -```console - -$ docker info -Containers: 40 -Images: 168 -Storage Driver: aufs - Root Dir: /usr/local/google/docker/aufs - Backing Filesystem: extfs - Dirs: 248 - Dirperm1 Supported: false -Execution Driver: native-0.2 -Logging Driver: json-file -Kernel Version: 3.13.0-53-generic -Operating System: Ubuntu 14.04.2 LTS -CPUs: 12 -Total Memory: 31.32 GiB -Name: k8s-is-fun.mtv.corp.google.com -ID: ADUV:GCYR:B3VJ:HMPO:LNPQ:KD5S:YKFQ:76VN:IANZ:7TFV:ZBF4:BYJO -WARNING: No swap limit support - -``` - -With kubectl: - -```console - -$ kubectl cluster-info -Kubernetes master is running at https://108.59.85.141 -KubeDNS is running at https://108.59.85.141/api/v1/proxy/namespaces/kube-system/services/kube-dns -KubeUI is running at https://108.59.85.141/api/v1/proxy/namespaces/kube-system/services/kube-ui -Grafana is running at https://108.59.85.141/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana -Heapster is running at https://108.59.85.141/api/v1/proxy/namespaces/kube-system/services/monitoring-heapster -InfluxDB is running at https://108.59.85.141/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb - -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/docker-cli-to-kubectl.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api.md deleted file mode 100644 index 36bc3769ed25..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api.md +++ /dev/null @@ -1,117 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/downward-api.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Downward API - -It is sometimes useful for a container to have information about itself, but we -want to be careful not to over-couple containers to Kubernetes. The downward -API allows containers to consume information about themselves or the system and -expose that information how they want it, without necessarily coupling to the -Kubernetes client or REST API. - -An example of this is a "legacy" app that is already written assuming -that a particular environment variable will hold a unique identifier. While it -is often possible to "wrap" such applications, this is tedious and error prone, -and violates the goal of low coupling. Instead, the user should be able to use -the Pod's name, for example, and inject it into this well-known variable. - -## Capabilities - -The following information is available to a `Pod` through the downward API: - -* The pod's name -* The pod's namespace - -More information will be exposed through this same API over time. - -## Exposing pod information into a container - -Containers consume information from the downward API using environment -variables. In the future, containers will also be able to consume the downward -API via a volume plugin. - -### Environment variables - -Most environment variables in the Kubernetes API use the `value` field to carry -simple values. However, the alternate `valueFrom` field allows you to specify -a `fieldRef` to select fields from the pod's definition. The `fieldRef` field -is a structure that has an `apiVersion` field and a `fieldPath` field. The -`fieldPath` field is an expression designating a field of the pod. The -`apiVersion` field is the version of the API schema that the `fieldPath` is -written in terms of. If the `apiVersion` field is not specified it is -defaulted to the API version of the enclosing object. - -The `fieldRef` is evaluated and the resulting value is used as the value for -the environment variable. This allows users to publish their pod's name in any -environment variable they want. - -## Example - -This is an example of a pod that consumes its name and namespace via the -downward API: - - - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: dapi-test-pod -spec: - containers: - - name: test-container - image: gcr.io/google_containers/busybox - command: [ "/bin/sh", "-c", "env" ] - env: - - name: MY_POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: MY_POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - restartPolicy: Never -``` - -[Download example](downward-api/dapi-pod.yaml) - - -Some more thorough examples: - * [environment variables](environment-guide/) - * [downward API](downward-api/) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/downward-api.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api/README.md deleted file mode 100644 index ef2619ecbc1c..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api/README.md +++ /dev/null @@ -1,72 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/downward-api/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Downward API example - -Following this example, you will create a pod with a container that consumes the pod's name and -namespace using the [downward API](../downward-api.md). - -## Step Zero: Prerequisites - -This example assumes you have a Kubernetes cluster installed and running, and that you have -installed the `kubectl` command line tool somewhere in your path. Please see the [getting -started](../../../docs/getting-started-guides/) for installation instructions for your platform. - -## Step One: Create the pod - -Containers consume the downward API using environment variables. The downward API allows -containers to be injected with the name and namespace of the pod the container is in. - -Use the [`examples/downward-api/dapi-pod.yaml`](dapi-pod.yaml) file to create a Pod with a container that consumes the -downward API. - -```console -$ kubectl create -f docs/user-guide/downward-api/dapi-pod.yaml -``` - -### Examine the logs - -This pod runs the `env` command in a container that consumes the downward API. You can grep -through the pod logs to see that the pod was injected with the correct values: - -```console -$ kubectl logs dapi-test-pod | grep POD_ -2015-04-30T20:22:18.568024817Z MY_POD_NAME=dapi-test-pod -2015-04-30T20:22:18.568087688Z MY_POD_NAMESPACE=default -2015-04-30T20:22:18.568092435Z MY_POD_IP=10.0.1.6 -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/downward-api/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api/volume/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api/volume/README.md deleted file mode 100644 index aa87b6a261fd..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/downward-api/volume/README.md +++ /dev/null @@ -1,105 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/downward-api/volume/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Downward API volume plugin - -Following this example, you will create a pod with a downward API volume. -A downward API volume is a k8s volume plugin with the ability to save some pod information in a plain text file. The pod information can be for example some [metadata](../../../../docs/devel/api-conventions.md#metadata). - -Supported metadata fields: - -1. `metadata.annotations` -2. `metadata.namespace` -3. `metadata.name` -4. `metadata.labels` - -### Step Zero: Prerequisites - -This example assumes you have a Kubernetes cluster installed and running, and the ```kubectl``` command line tool somewhere in your path. Please see the [gettingstarted](../../../../docs/getting-started-guides/) for installation instructions for your platform. - -### Step One: Create the pod - -Use the `docs/user-guide/downward-api/dapi-volume.yaml` file to create a Pod with a  downward API volume which stores pod labels and pod annotations to `/etc/labels` and  `/etc/annotations` respectively. - -```shell -$ kubectl create -f docs/user-guide/downward-api/volume/dapi-volume.yaml -``` - -### Step Two: Examine pod/container output - -The pod displays (every 5 seconds) the content of the dump files which can be executed via the usual `kubectl log` command - -```shell -$ kubectl logs kubernetes-downwardapi-volume-example -cluster="test-cluster1" -rack="rack-22" -zone="us-est-coast" -build="two" -builder="john-doe" -kubernetes.io/config.seen="2015-08-24T13:47:23.432459138Z" -kubernetes.io/config.source="api" -``` - -### Internals - -In pod's `/etc` directory one may find the file created by the plugin (system files elided): - -```shell -$ kubectl exec kubernetes-downwardapi-volume-example -i -t -- sh -/ # ls -laR /etc -/etc: -total 32 -drwxrwxrwt 3 0 0 180 Aug 24 13:03 . -drwxr-xr-x 1 0 0 4096 Aug 24 13:05 .. -drwx------ 2 0 0 80 Aug 24 13:03 ..2015_08_24_13_03_44259413923 -lrwxrwxrwx 1 0 0 30 Aug 24 13:03 ..downwardapi -> ..2015_08_24_13_03_44259413923 -lrwxrwxrwx 1 0 0 25 Aug 24 13:03 annotations -> ..downwardapi/annotations -lrwxrwxrwx 1 0 0 20 Aug 24 13:03 labels -> ..downwardapi/labels - -/etc/..2015_08_24_13_03_44259413923: -total 8 -drwx------ 2 0 0 80 Aug 24 13:03 . -drwxrwxrwt 3 0 0 180 Aug 24 13:03 .. --rw-r--r-- 1 0 0 115 Aug 24 13:03 annotations --rw-r--r-- 1 0 0 53 Aug 24 13:03 labels -/ # -``` - -The file `labels` is stored in a temporary directory (`..2015_08_24_13_03_44259413923` in the example above) which is symlinked to by `..downwardapi`. Symlinks for annotations and labels in `/etc` point to files containing the actual metadata through the `..downwardapi` indirection.  This structure allows for dynamic atomic refresh of the metadata: updates are written to a new temporary directory, and the `..downwardapi` symlink is updated atomically using `rename(2)`. - - - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/downward-api/volume/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/README.md deleted file mode 100644 index b382f3353480..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/README.md +++ /dev/null @@ -1,126 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/environment-guide/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Environment Guide Example -========================= -This example demonstrates running pods, replication controllers, and -services. It shows two types of pods: frontend and backend, with -services on top of both. Accessing the frontend pod will return -environment information about itself, and a backend pod that it has -accessed through the service. The goal is to illuminate the -environment metadata available to running containers inside the -Kubernetes cluster. The documentation for the Kubernetes environment -is [here](../../../docs/user-guide/container-environment.md). - -![Diagram](diagram.png) - -Prerequisites -------------- -This example assumes that you have a Kubernetes cluster installed and -running, and that you have installed the `kubectl` command line tool -somewhere in your path. Please see the [getting -started](../../../docs/getting-started-guides/) for installation instructions -for your platform. - -Optional: Build your own containers ------------------------------------ -The code for the containers is under -[containers/](containers/) - -Get everything running ----------------------- - - kubectl create -f ./backend-rc.yaml - kubectl create -f ./backend-srv.yaml - kubectl create -f ./show-rc.yaml - kubectl create -f ./show-srv.yaml - -Query the service ------------------ -Use `kubectl describe service show-srv` to determine the public IP of -your service. - -> Note: If your platform does not support external load balancers, - you'll need to open the proper port and direct traffic to the - internal IP shown for the frontend service with the above command - -Run `curl :80` to query the service. You should get -something like this back: - -``` -Pod Name: show-rc-xxu6i -Pod Namespace: default -USER_VAR: important information - -Kubenertes environment variables -BACKEND_SRV_SERVICE_HOST = 10.147.252.185 -BACKEND_SRV_SERVICE_PORT = 5000 -KUBERNETES_RO_SERVICE_HOST = 10.147.240.1 -KUBERNETES_RO_SERVICE_PORT = 80 -KUBERNETES_SERVICE_HOST = 10.147.240.2 -KUBERNETES_SERVICE_PORT = 443 -KUBE_DNS_SERVICE_HOST = 10.147.240.10 -KUBE_DNS_SERVICE_PORT = 53 - -Found backend ip: 10.147.252.185 port: 5000 -Response from backend -Backend Container -Backend Pod Name: backend-rc-6qiya -Backend Namespace: default -``` - -First the frontend pod's information is printed. The pod name and -[namespace](../../../docs/design/namespaces.md) are retreived from the -[Downward API](../../../docs/user-guide/downward-api.md). Next, `USER_VAR` is the name of -an environment variable set in the [pod -definition](show-rc.yaml). Then, the dynamic Kubernetes environment -variables are scanned and printed. These are used to find the backend -service, named `backend-srv`. Finally, the frontend pod queries the -backend service and prints the information returned. Again the backend -pod returns its own pod name and namespace. - -Try running the `curl` command a few times, and notice what -changes. Ex: `watch -n 1 curl -s ` Firstly, the frontend service -is directing your request to different frontend pods each time. The -frontend pods are always contacting the backend through the backend -service. This results in a different backend pod servicing each -request as well. - -Cleanup -------- - kubectl delete rc,service -l type=show-type - kubectl delete rc,service -l type=backend-type - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/environment-guide/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/backend-rc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/backend-rc.yaml deleted file mode 100644 index 6c57b95dac91..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/backend-rc.yaml +++ /dev/null @@ -1,30 +0,0 @@ ---- -apiVersion: v1 -kind: ReplicationController -metadata: - name: backend-rc - labels: - type: backend-type -spec: - replicas: 3 - template: - metadata: - labels: - type: backend-type - spec: - containers: - - name: backend-container - image: gcr.io/google-samples/env-backend:1.1 - imagePullPolicy: Always - ports: - - containerPort: 5000 - protocol: TCP - env: - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/README.md deleted file mode 100644 index 92d708e15f5f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/README.md +++ /dev/null @@ -1,57 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/environment-guide/containers/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Building --------- -For each container, the build steps are the same. The examples below -are for the `show` container. Replace `show` with `backend` for the -backend container. - -Google Container Registry ([GCR](https://cloud.google.com/tools/container-registry/)) ---- - docker build -t gcr.io//show . - gcloud docker push gcr.io//show - -Docker Hub ----------- - docker build -t /show . - docker push /show - -Change Pod Definitions ----------------------- -Edit both `show-rc.yaml` and `backend-rc.yaml` and replace the -specified `image:` with the one that you built. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/environment-guide/containers/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/backend/Dockerfile b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/backend/Dockerfile deleted file mode 100644 index 3fa58ff7abe4..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/backend/Dockerfile +++ /dev/null @@ -1,2 +0,0 @@ -FROM golang:onbuild -EXPOSE 8080 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/show/Dockerfile b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/show/Dockerfile deleted file mode 100644 index 3fa58ff7abe4..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/show/Dockerfile +++ /dev/null @@ -1,2 +0,0 @@ -FROM golang:onbuild -EXPOSE 8080 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/show/show.go b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/show/show.go deleted file mode 100644 index 56bd988b4000..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/show/show.go +++ /dev/null @@ -1,95 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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 main - -import ( - "fmt" - "io" - "log" - "net/http" - "os" - "sort" - "strings" -) - -func getKubeEnv() (map[string]string, error) { - environS := os.Environ() - environ := make(map[string]string) - for _, val := range environS { - split := strings.Split(val, "=") - if len(split) != 2 { - return environ, fmt.Errorf("Some weird env vars") - } - environ[split[0]] = split[1] - } - for key := range environ { - if !(strings.HasSuffix(key, "_SERVICE_HOST") || - strings.HasSuffix(key, "_SERVICE_PORT")) { - delete(environ, key) - } - } - return environ, nil -} - -func printInfo(resp http.ResponseWriter, req *http.Request) { - kubeVars, err := getKubeEnv() - if err != nil { - http.Error(resp, err.Error(), http.StatusInternalServerError) - return - } - - backendHost := os.Getenv("BACKEND_SRV_SERVICE_HOST") - backendPort := os.Getenv("BACKEND_SRV_SERVICE_PORT") - backendRsp, backendErr := http.Get(fmt.Sprintf( - "http://%v:%v/", - backendHost, - backendPort)) - if backendErr == nil { - defer backendRsp.Body.Close() - } - - name := os.Getenv("POD_NAME") - namespace := os.Getenv("POD_NAMESPACE") - fmt.Fprintf(resp, "Pod Name: %v \n", name) - fmt.Fprintf(resp, "Pod Namespace: %v \n", namespace) - - envvar := os.Getenv("USER_VAR") - fmt.Fprintf(resp, "USER_VAR: %v \n", envvar) - - fmt.Fprintf(resp, "\nKubenertes environment variables\n") - var keys []string - for key := range kubeVars { - keys = append(keys, key) - } - sort.Strings(keys) - for _, key := range keys { - fmt.Fprintf(resp, "%v = %v \n", key, kubeVars[key]) - } - - fmt.Fprintf(resp, "\nFound backend ip: %v port: %v\n", backendHost, backendPort) - if backendErr == nil { - fmt.Fprintf(resp, "Response from backend\n") - io.Copy(resp, backendRsp.Body) - } else { - fmt.Fprintf(resp, "Error from backend: %v", backendErr.Error()) - } -} - -func main() { - http.HandleFunc("/", printInfo) - log.Fatal(http.ListenAndServe(":8080", nil)) -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/diagram.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/diagram.png deleted file mode 100644 index dd5d1551631f2adce68bfa4555050a2fa1250af0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18765 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 Jilj}R{4WuILE8WT diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/show-rc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/show-rc.yaml deleted file mode 100644 index 4de94c06ca30..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/show-rc.yaml +++ /dev/null @@ -1,32 +0,0 @@ ---- -apiVersion: v1 -kind: ReplicationController -metadata: - name: show-rc - labels: - type: show-type -spec: - replicas: 3 - template: - metadata: - labels: - type: show-type - spec: - containers: - - name: show-container - image: gcr.io/google-samples/env-show:1.1 - imagePullPolicy: Always - ports: - - containerPort: 8080 - protocol: TCP - env: - - name: USER_VAR - value: important information - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/gcm.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/gcm.png deleted file mode 100644 index c2832c1d982672dbc70d40c31127e2558964cd48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 209311 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 z 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%0D@n4eLLnh`5H8hn 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 C1w5s1<1LbBB64oUN%H%#2AhilQ8 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

      p3#^LG{E+)zxC> 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"aCh)OUZP*8C+N4gceBE6iFm^4E74 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 eUyc?FIeVoXQ|4>qhv)=x07_ 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 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/getting-into-containers.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/getting-into-containers.md deleted file mode 100644 index 5007880f4455..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/getting-into-containers.md +++ /dev/null @@ -1,107 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/getting-into-containers.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -#Getting into containers: kubectl exec -Developers can use `kubectl exec` to run commands in a container. This guide demonstrates two use cases. - -## Using kubectl exec to check the environment variables of a container - -Kubernetes exposes [services](services.md#environment-variables) through environment variables. It is convenient to check these environment variables using `kubectl exec`. - - -We first create a pod and a service, - -```console -$ kubectl create -f examples/guestbook/redis-master-controller.yaml -$ kubectl create -f examples/guestbook/redis-master-service.yaml -``` - -wait until the pod is Running and Ready, - -```console -$ kubectl get pod -NAME READY REASON RESTARTS AGE -redis-master-ft9ex 1/1 Running 0 12s -``` - -then we can check the environment variables of the pod, - -```console -$ kubectl exec redis-master-ft9ex env -... -REDIS_MASTER_SERVICE_PORT=6379 -REDIS_MASTER_SERVICE_HOST=10.0.0.219 -... -``` - -We can use these environment variables in applications to find the service. - - -## Using kubectl exec to check the mounted volumes - -It is convenient to use `kubectl exec` to check if the volumes are mounted as expected. -We first create a Pod with a volume mounted at /data/redis, - -```console -kubectl create -f docs/user-guide/walkthrough/pod-redis.yaml -``` - -wait until the pod is Running and Ready, - -```console -$ kubectl get pods -NAME READY REASON RESTARTS AGE -storage 1/1 Running 0 1m -``` - -we then use `kubectl exec` to verify that the volume is mounted at /data/redis, - -```console -$ kubectl exec storage ls /data -redis -``` - -## Using kubectl exec to open a bash terminal in a pod - -After all, open a terminal in a pod is the most direct way to introspect the pod. Assuming the pod/storage is still running, run - -```console -$ kubectl exec -ti storage -- bash -root@storage:/data# -``` - -This gets you a terminal. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/getting-into-containers.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/identifiers.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/identifiers.md deleted file mode 100644 index 9f5427142562..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/identifiers.md +++ /dev/null @@ -1,51 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/identifiers.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Identifiers - -All objects in the Kubernetes REST API are unambiguously identified by a Name and a UID. - -For non-unique user-provided attributes, Kubernetes provides [labels](labels.md) and [annotations](annotations.md). - -## Names - -Names are generally client-provided. Only one object of a given kind can have a given name at a time (i.e., they are spatially unique). But if you delete an object, you can make a new object with the same name. Names are the used to refer to an object in a resource URL, such as `/api/v1/pods/some-name`. By convention, the names of Kubernetes resources should be up to maximum length of 253 characters and consist of lower case alphanumeric characters, `-`, and `.`, but certain resources have more specific restrictions. See the [identifiers design doc](../design/identifiers.md) for the precise syntax rules for names. - -## UIDs - -UID are generated by Kubernetes. Every object created over the whole lifetime of a Kubernetes cluster has a distinct UID (i.e., they are spatially and temporally unique). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/identifiers.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/images.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/images.md deleted file mode 100644 index 4e59462d2764..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/images.md +++ /dev/null @@ -1,283 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/images.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Images - -Each container in a pod has its own image. Currently, the only type of image supported is a [Docker Image](https://docs.docker.com/userguide/dockerimages/). - -You create your Docker image and push it to a registry before referring to it in a Kubernetes pod. - -The `image` property of a container supports the same syntax as the `docker` command does, including private registries and tags. - -**Table of Contents** - - -- [Images](#images) - - [Updating Images](#updating-images) - - [Using a Private Registry](#using-a-private-registry) - - [Using Google Container Registry](#using-google-container-registry) - - [Configuring Nodes to Authenticate to a Private Repository](#configuring-nodes-to-authenticate-to-a-private-repository) - - [Pre-pulling Images](#pre-pulling-images) - - [Specifying ImagePullSecrets on a Pod](#specifying-imagepullsecrets-on-a-pod) - - [Use Cases](#use-cases) - - - -## Updating Images - -The default pull policy is `PullIfNotPresent` which causes the Kubelet to not -pull an image if it already exists. If you would like to always force a pull -you must set a pull image policy of `PullAlways` or specify a `:latest` tag on -your image. - -## Using a Private Registry - -Private registries may require keys to read images from them. -Credentials can be provided in several ways: - - Using Google Container Registry - - Per-cluster - - automatically configured on Google Compute Engine or Google Container Engine - - all pods can read the project's private registry - - Configuring Nodes to Authenticate to a Private Registry - - all pods can read any configured private registries - - requires node configuration by cluster administrator - - Pre-pulling Images - - all pods can use any images cached on a node - - requires root access to all nodes to setup - - Specifying ImagePullSecrets on a Pod - - only pods which provide own keys can access the private registry -Each option is described in more detail below. - - -### Using Google Container Registry - -Kubernetes has native support for the [Google Container -Registry (GCR)](https://cloud.google.com/tools/container-registry/), when running on Google Compute -Engine (GCE). If you are running your cluster on GCE or Google Container Engine (GKE), simply -use the full image name (e.g. gcr.io/my_project/image:tag). - -All pods in a cluster will have read access to images in this registry. - -The kubelet kubelet will authenticate to GCR using the instance's -Google service account. The service account on the instance -will have a `https://www.googleapis.com/auth/devstorage.read_only`, -so it can pull from the project's GCR, but not push. - -### Configuring Nodes to Authenticate to a Private Repository - -**Note:** if you are running on Google Container Engine (GKE), there will already be a `.dockercfg` on each node -with credentials for Google Container Registry. You cannot use this approach. - -**Note:** this approach is suitable if you can control node configuration. It -will not work reliably on GCE, and any other cloud provider that does automatic -node replacement. - -Docker stores keys for private registries in the `$HOME/.dockercfg` file. If you put this -in the `$HOME` of `root` on a kubelet, then docker will use it. - -Here are the recommended steps to configuring your nodes to use a private registry. In this -example, run these on your desktop/laptop: - 1. run `docker login [server]` for each set of credentials you want to use. - 1. view `$HOME/.dockercfg` in an editor to ensure it contains just the credentials you want to use. - 1. get a list of your nodes - - for example: `nodes=$(kubectl get nodes -o template --template='{{range.items}}{{.metadata.name}} {{end}}')` - 1. copy your local `.dockercfg` to the home directory of root on each node. - - for example: `for n in $nodes; do scp ~/.dockercfg root@$n:/root/.dockercfg; done` - -Verify by creating a pod that uses a private image, e.g.: - -```yaml -$ cat < /tmp/private-image-test-1.yaml -apiVersion: v1 -kind: Pod -metadata: - name: private-image-test-1 -spec: - containers: - - name: uses-private-image - image: $PRIVATE_IMAGE_NAME - command: [ "echo", "SUCCESS" ] - imagePullPolicy: Always -EOF -$ kubectl create -f /tmp/private-image-test-1.yaml -pods/private-image-test-1 -$ -``` - -If everything is working, then, after a few moments, you should see: - -```console -$ kubectl logs private-image-test-1 -SUCCESS -``` - -If it failed, then you will see: - -```console -$ kubectl describe pods/private-image-test-1 | grep "Failed" - Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found -``` - - -You must ensure all nodes in the cluster have the same `.dockercfg`. Otherwise, pods will run on -some nodes and fail to run on others. For example, if you use node autoscaling, then each instance -template needs to include the `.dockercfg` or mount a drive that contains it. - -All pods will have read access to images in any private registry once private -registry keys are added to the `.dockercfg`. - -**This was tested with a private docker repository as of 26 June with Kubernetes version v0.19.3. -It should also work for a private registry such as quay.io, but that has not been tested.** - -### Pre-pulling Images - -**Note:** if you are running on Google Container Engine (GKE), there will already be a `.dockercfg` on each node -with credentials for Google Container Registry. You cannot use this approach. - -**Note:** this approach is suitable if you can control node configuration. It -will not work reliably on GCE, and any other cloud provider that does automatic -node replacement. - -Be default, the kubelet will try to pull each image from the specified registry. -However, if the `imagePullPolicy` property of the container is set to `IfNotPresent` or `Never`, -then a local image is used (preferentially or exclusively, respectively). - -If you want to rely on pre-pulled images as a substitute for registry authentication, -you must ensure all nodes in the cluster have the same pre-pulled images. - -This can be used to preload certain images for speed or as an alternative to authenticating to a private registry. - -All pods will have read access to any pre-pulled images. - -### Specifying ImagePullSecrets on a Pod - -**Note:** This approach is currently the recommended approach for GKE, GCE, and any cloud-providers -where node creation is automated. - -Kubernetes supports specifying registry keys on a pod. - -First, create a `.dockercfg`, such as running `docker login `. -Then put the resulting `.dockercfg` file into a [secret resource](secrets.md). For example: - -```console -$ docker login -Username: janedoe -Password: ●●●●●●●●●●● -Email: jdoe@example.com -WARNING: login credentials saved in /Users/jdoe/.dockercfg. -Login Succeeded - -$ echo $(cat ~/.dockercfg) -{ "https://index.docker.io/v1/": { "auth": "ZmFrZXBhc3N3b3JkMTIK", "email": "jdoe@example.com" } } - -$ cat ~/.dockercfg | base64 -eyAiaHR0cHM6Ly9pbmRleC5kb2NrZXIuaW8vdjEvIjogeyAiYXV0aCI6ICJabUZyWlhCaGMzTjNiM0prTVRJSyIsICJlbWFpbCI6ICJqZG9lQGV4YW1wbGUuY29tIiB9IH0K - -$ cat > /tmp/image-pull-secret.yaml <
      nuGQ;D-@N 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

      =PV69x$SW zN82U*ch_N1wIvv~<$`;nq+>ovNX>S1b@)>1|?b=9fwR<<{1g`;@dO z(mf+L?#0+J&Duk=|6KdbqL4zgw)rgYn@Hh%2L+g>KS$8t^%0Au<7uRFURRJq=yC@) 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Ν{fqdd4TB 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%0D;xGtslf~`F$&FD;agD>R* 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ï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

      tLU@5mBs-PPlVJ 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%0D0b%c)$9<#<-^IzQ61 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

      APAJrb#F`JJ+fgrcI|>HVwO&%x_!`zdYlp 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ⅅ#RPW+L?=-K$8swP_T7oyx{#_Qk_1e7MNWKL+;$Oa%uexx zt2AlG{*sKypekpH^<+3l$=rA=l@m+AS&EFV18;#tb_Hq?ttcHq501^+A%~2%d^3w- znTc2Egvcjs|55H4Di+v7C;fEu3{1PVNw``rg!$u=r{kxAqN(7LoqXjVVSjqDNf+lU zO%)N&hKtO!0rHBk&C62Njg3QQ#~VD7DqO=zTLM$I9IE)}>Y|&lU56Y3rGemsQhUO@ zOo&u{HaR4&rf)>^81fP1@J_xqvOuQfA-blfMvaKBZL^ubB>n8}aO?el-QbqA>N7WP z_D~6AJXSw1xdn}0^==;j!^CWk;OkWN5+05U*T9roJKkw+K@Xz3uz8JAO!L6x{hZbL z+uW45N`$70GF#Ra&8jZ*Qc@Lr%raXx&!SUhNG7;1 zea=LvV8%EeJO~zfscPKsJ7PcmU|<%^XZU)BpOkMNQFyIQa5zERzeL5`YTafj7zzz;8}P zXhg13rx@LheRs|!*i#q|@fPRhMERIZt&OYhm0VIzO#4r*;sVqu39G4gYfX$-r&eV! zw}wa&ABIv>?Lu$ZnER82RX0{&P!Zu8b+yyQ5+wLJi807I`j1SF@1!^+^+VILj!%nK ze(DDxZ>*ihv@MA!N}q7*gw$qd`j?7fFiv5Fke7tpkWmJXlkDvbGCV1cg{v_`gI0bslm2|+C;HxR%}aFqm#^IGCTL&7YrkZ za5H+QEuXUq{dz}f6Bo)5-DV^hYrB>h8f_cbzlTZ_Hi6XjqPXnu`)^l0t{!jcFtSwe zwK1nN)D$#yh_3$A?~ngF^4(dW%#g2)O0zN-F*<2ve8<|}JO-EQi9<-ZplPa~B!x#w z^L)ym8)?sU5L3j|xc%3p@fNNS zlEukf(v+?Fl&m;&hcK{xUaatv-E;M}k&C=JGL}?NY3+$|+XK9>9$Qm-+sTc^y&Tx8 zvNI%C#0Q?Jnm(@*n&x2HL5m?x((^fd#{BP-<<%pA+2xScZM1I(b=}NFh^lAoD!#n- z5zAGFNTq2O|9V+vYxj<^ivB=tq@1;r{$Sy4Uu8}P)A23xfUhJ)X|4+5H(WY%;piR{ zBA0Qqi+HRw58L;?CtSEZ^ioyvN&{tFCUXHxS9Ey$tT$saaRctSP`w>Qw^Z_033l`v z3!|@@J6>k-Y2X+@Q$wVp?RQGNky3kFzQd)AA1s>1JVzdCLru+LzA}RPw8{QD+z8oP zg{dKP$>&7smTlXdoSmJ|pD%u$fQB+4^Jq|eqaSJd#~OV*5cmPfvXbNe>Q1C?H_P(1 zZG~%9+DZLJA2n1&K~d4iSUZ@Zbm^zj%`(J1dP%1&`Eb%8o`Uq7_%vH{@9CbK#naz- zT}~p4VZaUQ2?Wc^4xQDZV=#rL2;6hePUn$AW^UXFjgfJ3cFZA}7ZkiMdfKnu1fy}z z`_l(gd# zcKag-v2fO{sQA8c;WD)i0aF))_?f{{9Gy7W8C~ z9#D4c^Y6$k76E#!?@i#};qc4$OQ7#z5FoNdhA0iRH*M|-T{TZm*3yRBMS zIN$y`?vCxNe_FF^+p1Sn(-GW&{4^X5?jSk`(^+rtB8+n0Uqg%%a;zYb{d_)mO1>1X z$_{AT+uM0hY&BK(#_*f{h78R89JMvyv3)ym6HW&346L4fn=`~Te)4V9LrxTt1j%Rz zkaR{p#HTT^v2k<+F+7AZCtb*IG@4^ujZR(Uwn`7ZCOPrqYu}kVdPl+i*E;d+{M9WA zdb>n#IXHw@M{ll{V-5aruUlXk3&-?4vSsrg`@LsA^ zOw##KSM_Qj=J?>cP0Ec;e?70-)g@^(O)v|7rJuKVzNZ3DMsmx1^PbAs?8ZkZ%WdD{y4*>^%phgheLCt=jb73$GBkjJ@>lJR+B_n_p3p z$ZV+|S5XR2b6}94nPuZ`46(lZt`rSI3H$n(W(L;l*`w)^DAYm-%_=V$Josiro1KEWt3yF?A=h6-`Z6=y2B`S@@nB)S#NF3g zSDtfIk|*gzOJ8ZA4?^-t(MwQDPoF=Kkmh)aUszg4N_*_U@xkoWo7XI4aU`tHnD0+E zh*zN!--XH_Bib}*<9(?(<)$LwxmN@_%~k5%nPXYxkb5zGk0lg4Pw5;ne)u>)KjY1T zg9G1CaEV#lA0raNAv6i6rXnhpBhw+C$pqCI%c@AlJ2!*Tc+Oz^_HBDTy2ot}t}F<= z={WdP-|NcI$I|_Kme2ZaJVJ|(j~~4>$xqU$y{E95$S1(Be5O9Jeq8)VkD(j@^WU;X z%j6pDHIEv{SW899)nBx{N?UL)mVsz@fPXePY7?)&S_Ml|E+V{wN(-WcG&Q4wI=?y9rk}+nR{A11SjFF&j5(#C-4Rv5rqe%Muo84J-@d3Id1ZbVvWV zw3|TvIIcXCCzm`t?y~Z+@Endw3aSY{K*o)@0B11A`&mOWDdd!l$oPyGJRXAFzOI%u zVj$#P1{5)j1Qk2ngoB=OZALr|u^c@L9OCc>WDKz?b9yAD(C#$E0+3(7vr=O98m>9>!7=ro|*VUorMCvGh*gIe% z@HFMZ(i~C@E8$2v@Lvc6mHzFXxW;Jcx!T+&$JQK0 zjJ^Err)yij$L4fuoxdZBTL% zLE$=|d*Onabh`{T`gMjIugH#lm-EVpFJQ3xB5CjC9|p^}ZhJDuyQ1i4@xMmn<+qnD zHy&=zmD-jRMcL}fP1Q6%JE@!dAee*A$i%p)+kfe*AvU)gGf{vo4{vJ9^qzbIg*-H} zy7UP&`}@CtFGNdhN9-Wlf(um!-eYK!XM)m;TzYiNkS5^tIU_wY^SqPOU#K*&@%l@K zFuwc?0_XuQs^!GRTJ~cCl=kYxv!S6Owj&91P7Jk=z436>(BKTTUR)SiEOKmSVh(){ zLJ1%V(A6N8LsO?Z-5mg(BAEWrGoh)zF!a2>v8f4CkG@e4HhB;dTF8gYFCjK7iO z#@8e%o|h1micf<=6=p^^h_ax*1BRQV;|*w|zvQP+pD-PPisRTn7#H9WZ1zG^E+*l> z+FtOg3+m7zk1B$V2NBl7VHx_yidRg-IZPyn$tfiE=;0ig>;OrN4m<>O7T={eB1%K z0e%5&h|J;zL~CQjj*)!wzH6Qk1_DW`DTS%^apV>=$i;sB1G#I==>f$%}@)eER13OpQZG zqp`8+MVWTWl|!ayOzlkUC}OHtzEwLti`!H^_WANlie6HDGNNFAjM^MT{LG;bAO7jM zeiha4`@Tn@!Zo(~(zj}sXy65zf^SoIpbGp@Rl9BL4j!(6^}}ljNy&2Aqt!MC4{sV* zv$WJQF$vlJeYop9ppgZaz3Hc(uOcm#!KuskNYm-SlvMtop&v3DtNQ2fBwhM zQ{@Zw&*WF#wEi*>wHYhktMAhm<7TZBWptVO-=!O*A3eCPky2FD2~8a6a-DC!eXjpA zTrIwR?f)eG)F0XP3nU2%yg#Xi%p9|17}o|Rv8-)C?zIEjwUSrZ5+P*>_csJ@yE}z zGcj6K{G?=vF^St74FL@?A@Lx?Mrx zQvc@mEg_AR7Y}Cu`c$Vp$YC<)4>+AS$W&EWO>NlkJ)NR|aQlfjnnF|pRa%FcEJus^ zUi#l78Qu2I_N_YKYPX#`y5mabuh(bz)dj)jvb{@8fR1o3Shm=!H+!>v{5kk;fAj?O zT4oW~usa5eWHGw!+t9P55UEP(+k}w+HlO6!<`k3`U)zTPLq-2M92>aqzkdCSrHZ^K zaD5NQe1{JN+H53=VBCl`1(zE{Ro0?YSi0#*;vmF^7J%K66sLCSDmXDdUgO-bJ{o})5vQsg=fiqy( z9lFQoG7zFzULAe`Gt5BKqd!wqAmbOjdE*5!$Y%X}`IDcIOX~mwwoQkAx#Lo71&fV5 z)=yM^$ox4y%3{wVa0Cr4XP@-z7OetJ9Fb@U0-8=?58foqWu+2!FRKpN^rO&j6x*+ss&yfiL4JU$s&lspqeu8wk zsk!;Zh3_Bmjr);ltekib{y!wLU}!>6$CmIUBSQuf?aUUu3XWCN*mKXf=5RUZVcSO0 zjEDd|aLwrK2y~2jj}RvTHPfb3u1*c17~3u_ZHuh}M{R7K*a9cuhK7P{0b?HkqHE8+ zIQ}&d#`otnX?HKw=7vx4KGOG2 zZy79JGMs+?O3V2?724NZ=U%iuK zznf8M*1uP?J1n=R!#8G8_#0MzF#w&`+WdXrV3VS3;q>{zu^OGY==+XrfM;h{*J9a* zg{+j69_;1NxPuWI)imG*ej7N$0A|0$io%+~uk|mw{DSD1w4W6TeVCswN~OWa|K~6C zF~8tMgXbP85fHWi_dn(@I*Cei-rdf|KLTg{sEJ3)kH#iM+O}fSHxI)mZs%KMWWE;T zik)Xa2##(50u*8#H>R=(X%@U=ndZ--kcO%36gcw5$H#9nNOG1FtxMj&h{wv7`HRQFtq)Q)WH{>Wy)xE|p*_AvhTU(z0I)YA zz}W*qNI+NkyC4lDd2y~EHW(Zlu{D6E`B4ASMjd&0b7f^$Uca;5Jf|1)%(g7+fLc2Z z+5~Johjn$IpgjHX!O_8?6jn&)&&tS+ShLIH9$>C_2T1R04Ge0I%mxfw5f_xG;3UFr zx^$OK2m?1iBU962Y&Q^?vgiFi*w%)yL0|?_+lTqQ&)=6mSFvy5WeGV+*qVb=IfL`U zUj&{s4o><{2e0RY&)(o`$=BkMNZ0t)>)A|AsqDV4sRffHR>^QfbHff@I@58I z|JK03S}}$>UB>+?S|(PUA&q`K=lIoeYD8&55reU34Xbk%(d#LjY#J?<+$t-a99{bv4uq8+S;?%wU>!-h&%Bpl- zNW0SWON*|FWRk3V2!nQ}`j*E>~|*IalAQ zT3~CQ_b4rXyUx`=LlP2VZ%4OTtT#4p5*H{?y(8(8WV3Fw0lbw^S%Ic^iJ$-Y(<+}i zm-fz%0y)0+;>-1Q26=;S%2`M5KYGF|?#FOrknx{`n0|M*{ps(_0t^OAPaiREhLz;l zo7|U=+Rqt)z7?i<;CWxo_N_bmJOtDQ^^WrRD_xlW*c0G`ri$nHmf}O%?H9+#&~rlN zyPU(@-?y6YKf%iV-0HM~%pC)lbr&--c3UPde4bp(8*=O3g`Em?CKJcX(}->XV;|DS z43j5Sr@+4IbU29(KJ&z+ZdYh&3Zn4!byys_8-QjN8 z(BtBTP!Q<;!S(OCBB7nWT*AW&4Ib?7km%6-81^a>J`lkHN;W<=hLjk#F3A1z<=Y$f zciL0fu@|_1@Rh0H20ZHVwZ}!qvd9ZT7@~p3CME)We8@z!MZ6h%#E#G}L{ea%5kM9e z0OM2|%naxQV~leu`wP;54hX)31Em?vXCtHQl91csPV9kb1h@xK5m84E?w@Tao~tf) zZp%f(kPN>jX6e}#66n?dQk$rH)m=lQ3`mexFx+tVii+YqRVuRMM7}HQz2)L8Qn=f# z1t2mk*0B=cAMOIfzarV3~J^I!9KDk>_jV)2P6 zK!r!4P`oA@4&p|Mg_xw^6w`6eXR_H8E+B+IhDcVzufdK2!z;!fXc}WHx9d8?UR~X< z>hv+}LhZx)B$p*Ts<1#7FANr=AX?%78^r^FVTp7TfMFXLRadp1*f)pHtm@mgXlB@Vl$x29D=6aJQPI{KD zH00yjqb6}}sA}E$*X8z<6&x$Wr(WDAGqxVWhHyz&gp1RAlRhxx4sCgV@)}3;%Odk; zY8U4k3^v4&25^4#neOoM{CY0pT+N=38-lfjo+D_j(e2HHT<6kDyeD_Wl7Fv_iwli8 zv4Q8H9Py}evor1^m9BI5u8jN4{oYu8zKE;bke|&MABb7Ke|BKwrqsCbiiQ!X3NpLL zSoGoY{A7p}12Cm zG4W~3AS5^|V?H5qfUV6bIi5mZQ9r&r;Vf)PAk)4yli8QNvSJhtxk0zrxXNNKXXxYA@ZQ6Of+p-Zut zPkPJqcG&&6j0lnvT!*IHX8qqD5OhCH5nH8a19gW7T{1N?OL|Kc{q%O3t$D3O^o%8m zE8d(06`mYo{loq?pS~b>h*S`4c%p$@WHX_;D0NlYvIT*|0S%%8H+|0-60iUK8P7Tx z{$p|(k*Y%%-=1nnyj9L1>8xM`r94jiFNBHyhx^?0>zuJe&&$0gZ+I}7ff^|cI^DPH zcFN;c=ep|ZO!2*+lN=AOq7eD;T`bX%6w$zd%~E^zJiLGZw`KCR_jb>3SJmxYTl9POJuw?4X>x+oKnuBP-&o+9DwA*%(5%O(opS)>G(Pf zgew=NY6utJmJk038~O2u^i26j;`-4#Uu|m`1C_%6&M!nq6SIy9Rt926M_~aj0){IQ zk|$`ytOF<-BYM_(8NgZsskM#}l?Fctd|=&%bd;#6ErS?aY}Sh>xSuiqd|KWw)vw&m zikS|jzp84YwJ2X1qXAfJLbWKDIy7L6$5?e@e1Z0q5SCJ)waJqgZ{DcD!qJqAeHbbQ zbVQzjrB_rWasBZwwwl53!V-r(zZVp}b$rXhStXT_J2J@KCy3N+8K-PBvltLK@9sW( z444z-uK@7_E(2idYMYkczv!#9w5_p!TrW|%dD#8W!~~+0+?2sNNjn^O#L^P3zxsaN z=nqS`bY4j^_`*rw>f4FD#M=6LcI$=hWOS9h$mK67nX=VPl4pouDpDo~u|?i0_$J3T z%clmMGa_<@(X~<=0HIA%Sv%bVCKZ;t?H-}vACsO0b?|Dj7odU!?8^9!Y4@A5G7X%; z2!01Q_5?@8zc*>YwdN=m$WmSp)M42>SB^&xZO-!FluQiG%)lk#o+hai39DY+4cl;V zCm%Jtfy>>6!{E~zIw_dproeK%JTlii|EDv~XZR9T`XPEJ3#^&NU03T=!dcw@;%)+n z^#csC?YzZ|SJysj%ql{;VRU%K2Ft$&IACwxyLt02r!c0)&ii~+L#pxe<%v=8X}*;8 z+#$p@v0+csbuKF5KCMZkHJiz3MHsyWomx)3Vn^Y!S5t$VDfuVL>Q&~SJ7pd>Gc*fh zec8BweiY|4^O*l!PI=hNZQE9D_xx)GBsm zkU#X4-Nf0V!W9&Ibhd%!rW1oTldesfQ)zJG@92KWA+pIr7(7Mpnq^fFV7~N3TOH?z zYAZQkesV|~swx!Ye*55rW*6oSsRz&J_XPfv-mxvz#>RVMs64*WY#|COQlVh*$jeECAufRlJ3=x?wcdH(!^qsx;moH`WVdB<-|+WNKL7dNtNrtjzzagl z?pW7HmzKgmDdfghSL@j@bBf;ix!P)s;NGWI;kj`8*Az@C(})`*!Hwc(M^Z_CcfOeBUeH1mEG6rV{n4wezR5e&P~ zZHwcFU}$kr?%R)>s$bu`Pv!i1P7Zq~XiVKvmvNsQA!21%S5t%5vv@@?;|qEcA2n8{ zGsXCpmF9|wE^zxVDf&-R`=0)0e@XDhD@J2tV$i*#5vBjBcty4!qj=AGh*z*r(@9Cs z9O9cD3(>E5YBHF-F!2a&49vKwG*mh$21-hWUu)AJq#nF|?CEDn{N0p+x5uLMf-@MG zy1yiVe9pTQpjxxuJJ^zGO0-2=fJdEch;U@-8|@meZY6g0j5=otm3F%Vxtw<|KOp}^ zmM0vhp9d#ps!fcIw_6s?0dRN{UV8vOMp+f68D{@gk74<2LQyjP+d8(IYfck8HAx52 zE@5GOat@wx`GSr3K^7WzRPLz}t@5vz=X9^>>aQUDGY%gafzgb|;%(T-3;6M3DA;yYS-Wi>F2X z7JTIgdIaq^1)d`42XS6+1C&u*4cZnAJmnFYQgKa)F5 zMaGWduA<$d+|kC-x1T(f)?qw+_$uo$Sypy~dPGc&NY>c>nTY{7A@=?{@$f&gj$myq zJLr%`)XO>6vTu~6Ba~tYQR#^-!F%md1Itufv7x#8-J*dAl+s86I`l#K>w&)G`@9zC zU0D?^2KL$)mFg1D2462L`J{QH7Kpjjs_4@?Oy)B!N-x5k(j6QyI!3$btg4TGrlKI} z%EH%H%E8%Nid_r`%-+vF?Y}rSX2_=?cI##4iPeu-1a(Li@0PAdVX&ZeABXSQLN0H8 z%c73U6VwbQv#e)HnU{?X3uhU$SU?%TC!Sl=NzjDfxg#BN3V<4O^H%J26)1p}l*}wF zI-8o%iRo->Q$|W8Br2E>pueq6YHV)il4^{i)BQ`W5H->?AhUHV$5L~P%$HeNf;G<} zZMd~|7kFEtq$-?X+MIWr$3PtA>gsy+>Qxhy7&ed}Fd}neIo3!>$O;+}d#kOjbp1Hy zNmx7D?ET(vi##|RZzG{dQTshtQlf^?%*O-5D{kNl&|>q%-SP zgmy4m8~f|Itj+K#n2I5@A?Y;O=jP-bp+A7N7~lYH(l_@41YNg%{fagmoYW*C^v#!= ze*t5IyBcr;1TvBy)YsQ<5EsY0#<5Em!)qK`aLYx*c-TE4tPkB}w1*`Vw%q-X?ZKx! zO-wMXA9}SeD4y+PY`zlTo=LrPJviNi9ak=jAlt_Jn+3My`s*T|d9W>H@SY zH#eeCOGY;d`EGfw!}He)r#^iO3p=bsS8kIf#zxEY4Z9Xpw0urH`^u~k9+9BjfJS>EHg$ys@}ld#=9bL&)`w8=oP2 zDmvD(WZcWg^1Pj$i0tnk!yw7Z-ssbTb_74!?c0tLp-dsndH-&g+_kM*RsNKoe)#pW z);+J_uECwBx0h%&cjwz(;2UJNN{G2Z;XL4mZm_t(@u-aWG~B+w(T`|09a$fqOQ|R- zOpf1f_otHkZf2UB@{?w`W(P-)>4 zd@a8X01Ln!(6?9fB*;!KKWr&Mw|-ALz@ZDYXJD^HDRGib{)NZSy6lA$EGIau3x&O zpx1;89WZn%EvgDUn5NE73uq826hdxH8kSdJnRTEw`Ue{$;cCTF2bY5uU0SMMXi-1z zB`Jt=I|tXaP$Kpc5ObCb)gMfyMNB=(%#_``_o}^pko8^o?!#HYpdn?$3uA38{BE|_ z^T*H-ydp#@QYST=aKk{gMGm2p(u<4tOG~4RS`0$et5@bUOjw{-02suO2na{rhYw<+ zqU3Gcpru9+;3)Cog9ikqVErT&o<0+R)|{NSZQ0_goCt&v!5Zd$s4!z}Q3pYtfz&@o z$E|uzaFv!^K%(Zodn!swcVlA}<>le@U4AP6K#Jj!BaQYqW}4fVQ6oP56yu|6l-{pa zI7~O9vUjN-mmpFl1mQZT-1W~HTz=GW8tBW7Iu|}7GkF5>Vh6RD?>|qtUGD4q{+!Q7 zPVC@`GOH^Hk#{dR*%V<<`KE0EU6EGQ7U}Xdhhqo-a$$4Ou9wtiJW1u0DIx3}K_^=& zyvglNai*+O&0XIvOB0I})IX=i}@{NnXT^1%P~xt+h^&n|4YrsQp+x;)!Bq7 zEiSM}e4xKBFRZH0#29=6p!ogzOV{7INB2*$CnMQ@C^|euOA5zAf;vJm5Ll^T7glvz z!cD;UZ7t>k{DBOHl)t2T%)sEVUVUZI^|FDrYd`lA^^9$@zx@7abt?FO+D_XHiQkoe zjSQDSDXb&_f&+;sV+>a72XTiVa4tD7L_h@gb(Ye!r7`>wBpr^6fp;B#@hw@x`Bq0$ z-3YB1oy}QaSMp7D*S_1SUKIFFM&t{xz2xs|@ga_V93uXgF2Y{oPLM6x%`@&>+HGL9 z+idgQpi2hg;%_)De1_8xUXGNh=CKh>(ng>U--$dD_+$o&%+e@6X+YVyk$)&za>SO5O*mNJUkC>$v!=d8DI$o1NUfXKCK@ zuEp+9qW$V6q9=spdA#Da1G&QE3^#V~UHdBfxAlbeLEUuS^jM1IW1)i0@6)Q?H=Nxn z@5r5hm|OaKm%Zy9(Jnv!`-&LGn(=lnwK;g8W=VU=veW{Od+WIq-eqyUmv`xWm&NOO zAy@EFu3}^|`fk7XeZ0w|zIXO@m`GG=xiPR4CkbH(Wx4JK=r07eYsI|K-2&|dry@@T zA@!h{%bp0`Z!1J&K3?s17u()zWQ?{$dDgo}!K=J-^>ycpw9V-GH?nkFKMVFUrV3^^ zM#wFj5cNouTkXb`wUlypB3*VxrS7pE4M#pkT>m`#JUzAd19kWTd8^WzkW;B`TsZwl zjD#%iWLpDf7MH4bUkN`bSW7>BqlkoEd~vmp&;K=veqLu&WQD?M#gJ#9p+GOzx=>@_aw?%Jv_5XRCx$}Ka8(XQg>;5bL z&-Z6?QX4We4|v4=_TRPw3V!zEE+nX_vtKhl8Z+gL%13(A|NVLFfBygXNGx&=iV`mg T@Risv!5 - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/introspection-and-debugging.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes User Guide: Managing Applications: Application Introspection and Debugging - -Once your application is running, you’ll inevitably need to debug problems with it. -Earlier we described how you can use `kubectl get pods` to retrieve simple status information about -your pods. But there are a number of ways to get even more information about your application. - -**Table of Contents** - - -- [Kubernetes User Guide: Managing Applications: Application Introspection and Debugging](#kubernetes-user-guide-managing-applications-application-introspection-and-debugging) - - [Using `kubectl describe pod` to fetch details about pods](#using-kubectl-describe-pod-to-fetch-details-about-pods) - - [Example: debugging Pending Pods](#example-debugging-pending-pods) - - [Example: debugging a down/unreachable node](#example-debugging-a-downunreachable-node) - - [What's next?](#whats-next) - - - -## Using `kubectl describe pod` to fetch details about pods - -For this example we’ll use a ReplicationController to create two pods, similar to the earlier example. - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: my-nginx -spec: - replicas: 2 - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx - resources: - limits: - memory: "128Mi" - cpu: "500m" - ports: - - containerPort: 80 -``` - -```console -$ kubectl create -f ./my-nginx-rc.yaml -replicationcontrollers/my-nginx -``` - -```console -$ kubectl get pods -NAME READY REASON RESTARTS AGE -my-nginx-gy1ij 1/1 Running 0 1m -my-nginx-yv5cn 1/1 Running 0 1m -``` - -We can retrieve a lot more information about each of these pods using `kubectl describe pod`. For example: - -```console -$ kubectl describe pod my-nginx-gy1ij -Name: my-nginx-gy1ij -Image(s): nginx -Node: kubernetes-minion-y3vk/10.240.154.168 -Labels: app=nginx -Status: Running -Reason: -Message: -IP: 10.244.1.4 -Replication Controllers: my-nginx (2/2 replicas created) -Containers: - nginx: - Image: nginx - Limits: - cpu: 500m - memory: 128Mi - State: Running - Started: Thu, 09 Jul 2015 15:33:07 -0700 - Ready: True - Restart Count: 0 -Conditions: - Type Status - Ready True -Events: - FirstSeen LastSeen Count From SubobjectPath Reason Message - Thu, 09 Jul 2015 15:32:58 -0700 Thu, 09 Jul 2015 15:32:58 -0700 1 {scheduler } scheduled Successfully assigned my-nginx-gy1ij to kubernetes-minion-y3vk - Thu, 09 Jul 2015 15:32:58 -0700 Thu, 09 Jul 2015 15:32:58 -0700 1 {kubelet kubernetes-minion-y3vk} implicitly required container POD pulled Pod container image "gcr.io/google_containers/pause:0.8.0" already present on machine - Thu, 09 Jul 2015 15:32:58 -0700 Thu, 09 Jul 2015 15:32:58 -0700 1 {kubelet kubernetes-minion-y3vk} implicitly required container POD created Created with docker id cd1644065066 - Thu, 09 Jul 2015 15:32:58 -0700 Thu, 09 Jul 2015 15:32:58 -0700 1 {kubelet kubernetes-minion-y3vk} implicitly required container POD started Started with docker id cd1644065066 - Thu, 09 Jul 2015 15:33:06 -0700 Thu, 09 Jul 2015 15:33:06 -0700 1 {kubelet kubernetes-minion-y3vk} spec.containers{nginx} pulled Successfully pulled image "nginx" - Thu, 09 Jul 2015 15:33:06 -0700 Thu, 09 Jul 2015 15:33:06 -0700 1 {kubelet kubernetes-minion-y3vk} spec.containers{nginx} created Created with docker id 56d7a7b14dac - Thu, 09 Jul 2015 15:33:07 -0700 Thu, 09 Jul 2015 15:33:07 -0700 1 {kubelet kubernetes-minion-y3vk} spec.containers{nginx} started Started with docker id 56d7a7b14dac -``` - -Here you can see configuration information about the container(s) and Pod (labels, resource requirements, etc.), as well as status information about the container(s) and Pod (state, readiness, restart count, events, etc.) - -The container state is one of Waiting, Running, or Terminated. Depending on the state, additional information will be provided -- here you can see that for a container in Running state, the system tells you when the container started. - -Ready tells you whether the container passed its last readiness probe. (In this case, the container does not have a readiness probe configured; the container is assumed to be ready if no readiness probe is configured.) - -Restart Count tells you how many times the container has restarted; this information can be useful for detecting crash loops in containers that are configured with a restart policy of “always.” - -Currently the only Condition associated with a Pod is the binary Ready condition, which indicates that the pod is able to service requests and should be added to the load balancing pools of all matching services. - -Lastly, you see a log of recent events related to your Pod. The system compresses multiple identical events by indicating the first and last time it was seen and the number of times it was seen. "From" indicates the component that is logging the event, "SubobjectPath" tells you which object (e.g. container within the pod) is being referred to, and "Reason" and "Message" tell you what happened. - -## Example: debugging Pending Pods - -A common scenario that you can detect using events is when you’ve created a Pod that won’t fit on any node. For example, the Pod might request more resources than are free on any node, or it might specify a label selector that doesn’t match any nodes. Let’s say we created the previous Replication Controller with 5 replicas (instead of 2) and requesting 600 millicores instead of 500, on a four-node cluster where each (virtual) machine has 1 CPU. In that case one of the Pods will not be able to schedule. (Note that because of the cluster addon pods such as fluentd, skydns, etc., that run on each node, if we requested 1000 millicores then none of the Pods would be able to schedule.) - -```console -$ kubectl get pods -NAME READY REASON RESTARTS AGE -my-nginx-9unp9 0/1 Pending 0 8s -my-nginx-b7zs9 0/1 Running 0 8s -my-nginx-i595c 0/1 Running 0 8s -my-nginx-iichp 0/1 Running 0 8s -my-nginx-tc2j9 0/1 Running 0 8s -``` - -To find out why the my-nginx-9unp9 pod is not running, we can use `kubectl describe pod` on the pending Pod and look at its events: - -```console -$ kubectl describe pod my-nginx-9unp9 -Name: my-nginx-9unp9 -Image(s): nginx -Node: / -Labels: app=nginx -Status: Pending -Reason: -Message: -IP: -Replication Controllers: my-nginx (5/5 replicas created) -Containers: - nginx: - Image: nginx - Limits: - cpu: 600m - memory: 128Mi - State: Waiting - Ready: False - Restart Count: 0 -Events: - FirstSeen LastSeen Count From SubobjectPath Reason Message - Thu, 09 Jul 2015 23:56:21 -0700 Fri, 10 Jul 2015 00:01:30 -0700 21 {scheduler } failedScheduling Failed for reason PodFitsResources and possibly others -``` - -Here you can see the event generated by the scheduler saying that the Pod failed to schedule for reason `PodFitsResources` (and possibly others). `PodFitsResources` means there were not enough resources for the Pod on any of the nodes. Due to the way the event is generated, there may be other reasons as well, hence "and possibly others." - -To correct this situation, you can use `kubectl scale` to update your Replication Controller to specify four or fewer replicas. (Or you could just leave the one Pod pending, which is harmless.) - -Events such as the ones you saw at the end of `kubectl describe pod` are persisted in etcd and provide high-level information on what is happening in the cluster. To list all events you can use - -``` -kubectl get events -``` - -but you have to remember that events are namespaced. This means that if you're interested in events for some namespaced object (e.g. what happened with Pods in namespace `my-namespace`) you need to explicitly provide a namespace to the command: - -``` -kubectl get events --namespace=my-namespace -``` - -To see events from all namespaces, you can use the `--all-namespaces` argument. - -In addition to `kubectl describe pod`, another way to get extra information about a pod (beyond what is provided by `kubectl get pod`) is to pass the `-o yaml` output format flag to `kubectl get pod`. This will give you, in YAML format, even more information than `kubectl describe pod`--essentially all of the information the system has about the Pod. Here you will see things like annotations (which are key-value metadata without the label restrictions, that is used internally by Kubernetes system components), restart policy, ports, and volumes. - -```yaml -$ kubectl get pod my-nginx-i595c -o yaml -apiVersion: v1 -kind: Pod -metadata: - annotations: - kubernetes.io/created-by: '{"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicationController","namespace":"default","name":"my-nginx","uid":"c555c14f-26d0-11e5-99cb-42010af00e4b","apiVersion":"v1","resourceVersion":"26174"}}' - creationTimestamp: 2015-07-10T06:56:21Z - generateName: my-nginx- - labels: - app: nginx - name: my-nginx-i595c - namespace: default - resourceVersion: "26243" - selfLink: /api/v1/namespaces/default/pods/my-nginx-i595c - uid: c558e44b-26d0-11e5-99cb-42010af00e4b -spec: - containers: - - image: nginx - imagePullPolicy: IfNotPresent - name: nginx - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 600m - memory: 128Mi - terminationMessagePath: /dev/termination-log - volumeMounts: - - mountPath: /var/run/secrets/kubernetes.io/serviceaccount - name: default-token-zkhkk - readOnly: true - dnsPolicy: ClusterFirst - nodeName: kubernetes-minion-u619 - restartPolicy: Always - serviceAccountName: default - volumes: - - name: default-token-zkhkk - secret: - secretName: default-token-zkhkk -status: - conditions: - - status: "True" - type: Ready - containerStatuses: - - containerID: docker://9506ace0eb91fbc31aef1d249e0d1d6d6ef5ebafc60424319aad5b12e3a4e6a9 - image: nginx - imageID: docker://319d2015d149943ff4d2a20ddea7d7e5ce06a64bbab1792334c0d3273bbbff1e - lastState: {} - name: nginx - ready: true - restartCount: 0 - state: - running: - startedAt: 2015-07-10T06:56:28Z - hostIP: 10.240.112.234 - phase: Running - podIP: 10.244.3.4 - startTime: 2015-07-10T06:56:21Z -``` - -## Example: debugging a down/unreachable node - -Sometimes when debugging it can be useful to look at the status of a node -- for example, because you've noticed strange behavior of a Pod that’s running on the node, or to find out why a Pod won’t schedule onto the node. As with Pods, you can use `kubectl describe node` and `kubectl get node -o yaml` to retrieve detailed information about nodes. For example, here's what you'll see if a node is down (disconnected from the network, or kubelet dies and won't restart, etc.). Notice the events that show the node is NotReady, and also notice that the pods are no longer running (they are evicted after five minutes of NotReady status). - -```console -$ kubectl get nodes -NAME LABELS STATUS -kubernetes-minion-861h kubernetes.io/hostname=kubernetes-minion-861h NotReady -kubernetes-minion-bols kubernetes.io/hostname=kubernetes-minion-bols Ready -kubernetes-minion-st6x kubernetes.io/hostname=kubernetes-minion-st6x Ready -kubernetes-minion-unaj kubernetes.io/hostname=kubernetes-minion-unaj Ready - -$ kubectl describe node kubernetes-minion-861h -Name: kubernetes-minion-861h -Labels: kubernetes.io/hostname=kubernetes-minion-861h -CreationTimestamp: Fri, 10 Jul 2015 14:32:29 -0700 -Conditions: - Type Status LastHeartbeatTime LastTransitionTime Reason Message - Ready Unknown Fri, 10 Jul 2015 14:34:32 -0700 Fri, 10 Jul 2015 14:35:15 -0700 Kubelet stopped posting node status. -Addresses: 10.240.115.55,104.197.0.26 -Capacity: - cpu: 1 - memory: 3800808Ki - pods: 100 -Version: - Kernel Version: 3.16.0-0.bpo.4-amd64 - OS Image: Debian GNU/Linux 7 (wheezy) - Container Runtime Version: docker://Unknown - Kubelet Version: v0.21.1-185-gffc5a86098dc01 - Kube-Proxy Version: v0.21.1-185-gffc5a86098dc01 -PodCIDR: 10.244.0.0/24 -ExternalID: 15233045891481496305 -Pods: (0 in total) - Namespace Name -Events: - FirstSeen LastSeen Count From SubobjectPath Reason Message - Fri, 10 Jul 2015 14:32:28 -0700 Fri, 10 Jul 2015 14:32:28 -0700 1 {kubelet kubernetes-minion-861h} NodeNotReady Node kubernetes-minion-861h status is now: NodeNotReady - Fri, 10 Jul 2015 14:32:30 -0700 Fri, 10 Jul 2015 14:32:30 -0700 1 {kubelet kubernetes-minion-861h} NodeNotReady Node kubernetes-minion-861h status is now: NodeNotReady - Fri, 10 Jul 2015 14:33:00 -0700 Fri, 10 Jul 2015 14:33:00 -0700 1 {kubelet kubernetes-minion-861h} starting Starting kubelet. - Fri, 10 Jul 2015 14:33:02 -0700 Fri, 10 Jul 2015 14:33:02 -0700 1 {kubelet kubernetes-minion-861h} NodeReady Node kubernetes-minion-861h status is now: NodeReady - Fri, 10 Jul 2015 14:35:15 -0700 Fri, 10 Jul 2015 14:35:15 -0700 1 {controllermanager } NodeNotReady Node kubernetes-minion-861h status is now: NodeNotReady - - -$ kubectl get node kubernetes-minion-861h -o yaml -apiVersion: v1 -kind: Node -metadata: - creationTimestamp: 2015-07-10T21:32:29Z - labels: - kubernetes.io/hostname: kubernetes-minion-861h - name: kubernetes-minion-861h - resourceVersion: "757" - selfLink: /api/v1/nodes/kubernetes-minion-861h - uid: 2a69374e-274b-11e5-a234-42010af0d969 -spec: - externalID: "15233045891481496305" - podCIDR: 10.244.0.0/24 - providerID: gce://striped-torus-760/us-central1-b/kubernetes-minion-861h -status: - addresses: - - address: 10.240.115.55 - type: InternalIP - - address: 104.197.0.26 - type: ExternalIP - capacity: - cpu: "1" - memory: 3800808Ki - pods: "100" - conditions: - - lastHeartbeatTime: 2015-07-10T21:34:32Z - lastTransitionTime: 2015-07-10T21:35:15Z - reason: Kubelet stopped posting node status. - status: Unknown - type: Ready - nodeInfo: - bootID: 4e316776-b40d-4f78-a4ea-ab0d73390897 - containerRuntimeVersion: docker://Unknown - kernelVersion: 3.16.0-0.bpo.4-amd64 - kubeProxyVersion: v0.21.1-185-gffc5a86098dc01 - kubeletVersion: v0.21.1-185-gffc5a86098dc01 - machineID: "" - osImage: Debian GNU/Linux 7 (wheezy) - systemUUID: ABE5F6B4-D44B-108B-C46A-24CCE16C8B6E -``` - -## What's next? - -Learn about additional debugging tools, including: -* [Logging](logging.md) -* [Monitoring](monitoring.md) -* [Getting into containers via `exec`](getting-into-containers.md) -* [Connecting to containers via proxies](connecting-to-applications-proxy.md) -* [Connecting to containers via port forwarding](connecting-to-applications-port-forward.md) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/introspection-and-debugging.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/job.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/job.yaml new file mode 100644 index 000000000000..fe63d5c7d693 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/job.yaml @@ -0,0 +1,19 @@ +apiVersion: extensions/v1beta1 +kind: Job +metadata: + name: pi +spec: + selector: + app: pi + template: + metadata: + name: pi + labels: + app: pi + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never + diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore-filter.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore-filter.png deleted file mode 100644 index a9a53d0edf2e9026270d6db08fd51cd7993bd260..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71468 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 z zGJioCnE(0t>#PA#DFBKu6(&+ryfs-BOC`28{0=8F`wEk}-|#84|q!a%KAF{#j#vW*WviDZrS z%G#0klY9cbj62s8yNsI|!mENWD%{-Rv^2s%;8DxsfBRWSv3C3p@ma>h1f!DPoHzIO z-h9ZWWr{8)J^f~T6zSF}VR+3Yx+DINb zJ++-)w+s=7_`Q17Eo|==O74A}y`93E;&$#zucJQM&Q>TQ0&^;3G6qunvgwAQp#;ez z?(4#`bLI9kJGF;@1Xf0piw*j3L_}t1iYGTVFrOu5JA7JsJfFQ+j+XprHEwj$#pU0o zOg+Hc+2+sNK@(;62xrXU@~ z?|n&Tu2go52Aes}4!Rie(o|N1i+_&|BNr++h|g~$UR{ZdUSE&u+$R21(9G%>e7W0@ z^PS7l6p7(5=4j%%(Ug2HTOWEXjsE_c5AO|odk22q2N3@(DHRr%c_7yzw6`m=UuwKr>$&mQcPe|DN zL5xbHK7OY3lU9u=G{j=ge1GnlV}G_f-*QWGbbEBMlEHX9gNBRn?m~}{vx@@Zr;=2& zK`<5s14*|^xJ20u!e0XG%O4NCK%Mdoo@9+0^7PRlV4azbJ$0s%iyJ!ju>d*0dg{ui$+y9G4f=c$|u&arXQ@&vK{Fp3{yW^lHaXy!vvZ9*YzOg&kYIVLe3E&Zv2ySc=IiMX~}O zLTME>o<2=RR+JUtO~hMR`O#+ePnpIr4UMpXfWpQ_R+BuWSUY?Q3%YZARNclVw63mE z{=;6rl)FDvSC^qASz~h;G7>@?QGu+Io2xhhK@Z4A7sW&VZ?PO%pI<<=%HDLa(|vs> z$jZ+7tG{-3#xa6T!H%2~l)poi3u>eO9LZ)Fa+aji-tv=$T$Ithwps!`IW?7oMbY`H zv>p5$9^MG#c3>gO*{S$qFvM*SkMy)S#Vsv{eg0h3J7xMb^lli$7C`xik8dX(kt2h@ zP;aFk_debrR9cf{hJT=g)^xIFLxTJ=`@^gX_XlxAezLO|WMwcXei$e)o4Q0@J zazysQj)M`vz}|3n&H>Te=GWQToSpI4MxQ}wi|{%jOxRU4=+~SI0Rau;;QVkBoX`5+ zv=aCa7=NOoa;Q}t-@hIEi&0pJkKi{j#AM6SDf@nv)c7= zY;d=hE5$_$B8CiTFakg%`fqs>eBo_%)Hr>+r&{66I}k^EdG@GVNxTMvpZ5ssTT;-$ zUms4gpGNValQcYcW0XtCwnx80VGw^VW*uBwtTRWUmX(-%3uAYhGd8RI5o-fR02m?n ztN4|c!iGx9rvrL$myC>OKPj6OB!12aYo>ulUuCXze0E1LqAf0$9I}lq;n?)b8yu(q z2(?@44gYB-xTU9YyNtDpfG!m3mVZTi(_%nO*=j3bVnWgEsV3%$Chte0T&@U>QK3^Y zX&wsZr@sDuQM~JESLa`hwbmjEg!imU<6DWI1&YCE)L|qcV$m0t&Wr+R@y($d!u&p) zNjmX(uV3!FpPGn6P8O|aB0DSw%}oAnMzR?KLX4|NcqA+-A6OY@=XQQ1>l=UvGl<|f z-=?v#`B748dUy*AEkPCs_mUhJMLd@{ny@t;_>e}sp#T_Ix58h#awRkRRU8x)JH!@P zFzYQsXJj{byo3xS9gV8#8Rf_bF(Vme?|E7K!Nh3P)6`@>mv+5_nJkQ69+P$42$H2D zYj#Nz5grI(ig;yIAz}tF1!<#n-gm$G(RyOZ%)fmDw{m@aKuZ%gm^Ahy8~8A1+mQm~ zzzT0xRoVYHHq(2(V$tSDZc1OV{>P#iEpTgSOh)2! zonay(h5<>?cE!{7)j+qRmRJnysduSxU`OUX;h^Pn zgE&Y9vgOb!bnq!(3=8G-$Oy}cYw!KFMV-3-sXi1-L^`HN+dY~kLt)>7+Qnul7}#d#gaqrJV|V50fDnYl4!+UpxcYA$Y?L9B6~y7c zd}7c&EvOHWQ^GaGU@2U3X5 zLCtKm^NT!?aL*ojla9L4?*Qri1r;7;e6(DIiBuIum<%)^P`W#^R`*xZ`1qxbKUA9) zrwd-6kKhiwU*a4s4)*Bh2*GdPp1T7;i~yf4$^8@=Ata3>`(XaN1R4nz`uR=?xy(8d zXVD@`6jG&+0mtMRMR02&+Q=4Qgv zbC+Ic9Uj&6V8+1l--scT-h*pY4f7?x{YGCz3>qAy)^gC+Avc{f7uu)Jf|gEm!e#%X zl;rwsnH0Rw?YUct^63w0kmj_qG=+sF4qmFMIW5=P8csa*^WTHm{!80B`D$J;+Xs51B^$*5(?-ouXM0okrE>=Xe|9+OJcZrlhbJb1bac1@V={yNM-7tB zvGnPtmg%XfQarZ2@ZJDTS%g4hWTSG_EyZ}m_-41~cG3^s3?6Jry?)^K+B|BYd`NWf zokvHKHSzIBR?-uHh-VvVHCGZ4GC~mEm;elPoD4Q|zhN=b1{Xu^_#WD~ci|wL24@{@qsy z7wFivhnKMoa2RkZ-RthIthy`p4uO(HdbQEJ&3FhSDi}U;JlO5LajD*H#vB46CRP`Q znO?e&vrm{Qf$&#o(*$<8-#Kc#Hb&S>g}6=n481rFn6)nPo(>+ro0vg?+JGrrnby5f zmIfa`qSsHoZZ|oZL!fi63F+hYG5*x_DadlDgm1NbE%rs?t~3MC7x3tv>&!Dx14e1( zd(Gx!c#TmCh2R&CmhMD6<=9_ zOEN#JN3%}G8qjsh%gY=1dUY8%I60LlTM~RjhcBGkBjrNMbjCAz)L5O0fjkpgN@`lH zJvcVDygd$Gbb;@9xrmS>=IHp##<|{D+86hG;!nRF?LG}20pO)Yk$N}RR@>A!B#Gh*<0WIn5jGAYj*(E}nQ-3231ML7Lm(Cw5%+qm zzGYUS&xH8H^y^m)btgpvuY5|2!U=VJvX!Q<99UMTcw+WgQR@=6UirhCcv;$vpImPz( zReM|;f2VKu($J|X=$Zb?V;phz=;3F7T@e@ewL-g%p>%Tw3k&P<{@SEw0i)rG8Hlp> zf9qMUSubKk`y|bYd7YkQZS8DGlb7mL*xA3EE2GwGlq;L@tCHK66jqZb-{%)BN^NRt zZ2LTF`jdyp6he~ZuZRQ$w^P_MStFsRZ?Ul>egSnLaOt;uCgo8Sxx@!U-bx}Pe=jR* zv|f?q{siND!`D4~m75G~rjbd~#Y&%dBg^)qrwB%(C-SZDC|p~H4^xDoT3cchEfzv0 zkg`>1|1Hyy0<9aMdA0f?iiCt4KRWztOz2!Wtr3$ikN3E0Inoss3fzP#gF8!Vx9|Cm z6Xqv8IW0PlE1~Adg~P3EX7Is!N!fWf1{EUB6Ju}9FvywD zY@l$0$GY3zegT4@7dhC9S)KXhC*(^oNuK7tVecNfoFwOp6Aq*KTDMlsx^I|*38lZgGtZ>-aew0v`0YS*Z zt5_Rtg|*vk!qO#COub2pbuDV>HfH*ue)gA?te%4I+YK3@H}!U>vbZwR!hd{q^Xd8d5$c8U%ECtLr* z{CrPe9}^A=u%<6ndCHP^Pi6y>+xEYJFokWj#U(%x3ey5_alVScU^*{f?Q&1Z>aCWh zY5w@e=2mPKg-lei0KK%#4g2*kFy= z>_WeXi}*@ke^XYr7R1(l82Sd7B`O-NUer7;V^eFH%{#C@;B|6h3(@`G;tHcVwJm0M z7L#Z1rvz$u`(O#PfpmtCU?79x|4)4y7gzcI`aF5$OrfBZ65WX;`?m~`|FpO?UI`Tp zkP=BrRaSRJ(7oD1rE^$b=5@#145EhI9I?|S$Ax3V^5^@tny1sjL zdMu|X{F5&&|MITx*L-q=a2=%@d0a_b| zZQK_D1GjBwtaNLo+zogV7-yVW>rPGE(B@$A>4wx*2QEt1q>r3X z8OR(g*+3NL<|e!|R!Z>&1)tsgHJs}cfz7;}AnLQ+R0p3$ABvJ5>GwE)dQH`-e5Ddm zWRyI3xG4#{emik#MROM0y;$#KZ7XRMdnvgy@n}l%%qo=;G9x_o`M4KTdyPs5g%s;Iyc=%fHrS0^rU zS%8@Vd4A~xq`PYs>CCaE%3teGFE|N2`|N6eXwh5&QMh);BGD2u2nnP79kf-JaTiiF1jqNX*NTDWx$;+`RkxmA zd!S+kf+-!^#P8or@!2oLqW3S{Rcl1gA2{nioaW2b4}%`g;5V1}Y$t`%f3FS-<%)RU zmQ_a>nDyxUr7gz|`tYdq^+4Yqz80lS$36GE{x{0yBKxB1zVOpV$3bD>H8Su|=g7X_ z!rmH7_he^RmqpEp^DmjPT@SGCL%IC^!PDb@JOb+GZpvn5s;~eLbOA2Z%=E= zUCHZp*Vxi>eY}=A{(NQ7uk&|_$J_D;uU4INS#Js})^tHp22VDx=P6*h89gs|@Oi9o zjdlma<-d#Qm;3$@!s@t7~$@sq2rD64yWcy+As6xu1aI-`iJR zQ)9PbDkq2b_(xz^B2H0RImhV$JQ+hRR%*VxJ6WIc?Yk}*ALX(il4OpDs%HZ~cQCEVn4*SSXt~xj?!j^Zm(wl?#f}bzJ+95a zWYpGH`T((nvhw^-c}ri2M*WEXp{kKGR=e?Qn{Da3mKH;BKbwPTBhs2h0U+JDw+F|~ z%@`EQAl>sfWPdh4nt0r7R$9F*#c&jFG*4o=+8ru(U|`_x@<63^iYf`{+(CbRf5h$P z+=o;aJ?YGHB&1k6^*mlXzwy8Po;-!>tj#SgASEp!|Mo3rFI9^L^iWt%fC4)siu2KW zoQa*xk1WfXut9x22#93H`+~N&$*pH37i&M|zSj_Fb}~RE7_gp|-an#scFKo>B*!C? zbA|Aev`2x%Q^C0Qj{XHfi}6u|ZI7!F+dmLK zc5D|XOm^!BR{g!h2&=U*;?L@8`C&JUtX`M&G{oo5gCjltQA*|D`pggw`fP7J zM>zfnDkR#`jFze`gStv?F2_egRfl3twsqUA% zm}^8lF6HWU!HKj+*4FRNj+Z%C{9w%k{Y-z0OS*r>A*VWk7YBh#PjA&yeF7{T7~9(( z+$_hMQN5al?%+4i%Bcg=HwtT_6~W$*7(zj|`!l)hru@;-CjEU>7e)^(d)IObLr+Z( zCfhb0cHP}Zpa_A-%4_yXx^P-A|3>-t>96>g{t~4)w1CToF@&you>L{BN3YGYq!f80 zYRY2!*v$JeK){&+^kf6q5wt73H18IRP>5->Sxs5bXEk}=GM8QLeixwZ8F2f}Zet5- z^$KQ>PTH@cHn`Gd%an(=Ku$ENLgJP04b*qZ4qb=p|5H$%YJa%Cr;^tjUJtJ69T4<# zuy+W}dB5C)Z~-y-y|Lw%xI=gzA{vzZjUy7&~eQE3*ZOhtyra>LegKg1LjLYz`@V)fMVUv2Zo zFy57O9!-hZ zpCJQDS`a?Tq_#hnqrkk9#}e0jyGB}PF>Nxo85BHBLn}h9{4<*H-neD;|Ncf~Q*eFX z-q!kHovv-JY4V4IYHG+c$AJC+DW1aQ#Qv|M>;I~!QsKT7WdC<<_5b~6MO1~N-^0TP zpm&vg?)>~5{oOnBx$>1pyA4=mEF6@rN4f)cll7iZ&=K`KRp`jI0stk0y~asfT?w#?z;wdrhWvI6MK_xkU$AK3Z- zDd=#ICk2|nH7?};{;#K4 z7Hlo}N&fb5sezt^4i)({WA(P!kTU8b8*GL0>eE`K8>R4^CS<~wdN-q2c z*qwladUt={U@>P6E(p`p1Hf{9prC>0g-Jk=_T$G-g(B?C zg0y~nUL78`0QhXD{ol6$_Va1&6~w&Gy(<9G*Vi`^kM-`*PrFY25%5RZ&89w*kmv$H z7XUAAUMA7&h>D2Z-ru_%&fCotD_Jepl2&ALIuwAkKcLhgA|e9RdJ2ylQ@lFA$Jyo} zxV5oNz785M%$h{DjHk zVq;_D<7)xs6r45Cod7!r_)c$eZ~&!R2p%4uiOU_3zW}ivpirFvOc9JlBo1Sj=g}5W zF1{h=O-oDj1aEi&yk~q~YOJya3&F4&EQP4>aAr}a_&Ly^w+xnMTu*pd7#s@DM6=UD z9L1L?eD;6WYv1_1?i@u{c>&MRm){o9;lUxT)8cFeRFSXoSX2QsF+6-2EXDM+w1`gx z+|HH&=M79LpZ7y!LxYQ_XRCGv`!@mzopvh+fWQI}CNV&%05Ksx(+zGU#cP&XSJIffb_onT}vEiJE(mas7~6XN3)pE5=O3>^?Q0b1^O ztwX0`uD`z@9|f*V8G!tE4i7!SRf3zPRjUqYy#+Z0Kxqq!iUQQR#=^ovyEt<*B3@6* z@8Wb?&7f;I12BX#I33_109{!H*5N{p30Q~s;6lO3(NIYJ&o%FH{>rK*3+8a9ZoXmsk`*6L7QO{IeCQ!uhi1 z4%%86=WhnG8P0jIb+oHbzd z0T&OT>;}fhKr~{w4&Go5)*G1immLBaap)AX7w6~rpWRu4yWOr1aRt!&_7esT`#gbR z02aa!po_uwIXgess5O;0Hr@ti0dTc9?Qa3e_ut0GG#K}R0r9gZF!gL;XYulaeMrs7 z_`TE?9l=jrT6*);6>KBGV+UK5S8WIEColwM+HLOk_DpJK|1&Keeuo4vA{g)(83`2? zm9sT!m2w_1j@zTDAg>Hz0DBs2c|c`nv6vkh9xee}6EtD~N@7$*1mOIgZ;vwfd4LY9 zH^|5@Ok~iDssn^|n}a|@8M(o6Th`IR2NG1qEzQjZg@x>3ho>EEw}PPo_}RXhRycnF z614dC?9zrecr2#CVg#cSnos740Bbn9BNdrfSa`iV>HjdYWk0A?5FZT|-&)7F%(TA& z&s8ovc8o{Q#GQO!Wm<$2*?y}oVQg)Ss^x-*O)LI9^gtM_6M277N1yOHmIj-YuBkl6 z9+9+6{nMgx@xu6V^agiFla&hYaNG5z=Z(QObLRPz=a@+!XWI_=4dL(kZAwZ?0Gf@> zabsg6m?lFbqx`(QiO0MH$Nk?$-<1(agMxxCpuvg+0`D#R1l&M2a|a56+8(*NT?fNWcT;?f%z)_`Ez0muz=e=uIWfO!RZ&v5r8%rG{ph{2s1Ne zZSN3Z^s8=weTapPTdcRDzKsDmz6Wa385l@RKG?+VZs*2ZLkZY)nlVX9^i)(+v$F-~ z(t;sXRgBU7)Bu7vU$p_=26m?_I3HdJx}c5taG?f}IB|Gf8MJBu0}+I>02rJFY)+>y zG&ZgJ=KemFnTR_s5nU2BJ^h-io0ed==adYF! z$JYUxvcV}ZvjhWRj|@0bu*)%KYH3rrDFyvegs)LvUf}ou9zs6#?e6Hof*lH0&$iva%y!{`XhXdi9NrjBp>uL(wU~14m*&<6%sUE#PUBNhNY{aZO!U z&&rJN*9+=Amr8+8Vrm7D=&82=q5RR}Z9-Dg&gN#NYAIMZ#)gLC1&6#IR}tP50Pi`- zAr4$kqOo;>9=V86)8$PyA0!MD0zW)#R1wNm=3TIKI?Y+fJ4H<)U;H!>OC{_IUsfeL!ZM8YMvFqbP;noQgU;9 z0Lph!QPHLGqLZ74M{r=^3V_Fhod|YJet(UG7T|N*4Bsb zAH={@aavmLf$0NJNFYK(<435fu2!!x9tGYW{A)Z6JiKObV-n4jZ}IT%?k+9BMgqw8 zNL*%PfV>7@c_9U!Jk#-T7G6_R2zo+qY+M z1OSFL4>vdW`}cnB#C89+!AV7}TnezfofFwYVD)#Hj1z$^1c6JS zWI`kbr_yS>*L{^izi0#wSonG-CSpm?WdJbQz0vF5+0bw^Go(?#d508%c$o>Fl2{3q{!4d=rc`$vzHP^0w#Q^Z59dDGgz#{q?oRP5# zwwN>Uk$_hYAl$NSiI+p=zZb3$Sk?c%n1U4lgFizc{||d_8J6W5b&I-|YbhuwAfTd%q=*Pg zH%du&r$I;yf}~&o5~8FC2nfmF~^+KlmwRK_v_;k_1_b#{vY>-iivKqXzAZjg2o*t;kxY9`+P-CH91#*a_f420MJnM-r>7`7Ta^%+Kb2~??3-;+YKPFI zAaKQK8p8wbd?Gy8wJ1Wc3&(G5WhHj%|Gy$^6( zQBiSYb+*P~NJcC{g$TZl#pi2xx6!K`cgZMdX+>{*zi{Z#Ap`{|6aIV**5?a)%_BmA z!@(ywbKaF#c`gcc3!{hkCa6H3K4r}a4+*&pOL8d|p=Wfo9_$_hQnfQ3xJ9O4%Rjrh zF*jgno`@bs?AEPYGBPrZmmXE#96Lb&{@pu9bikfyOF;`@>+7aCw8NvLB{zOZz=y#; zbXaBCee#o$6KY0R`IIz%j7W1qv*NR7mE8Zf)zs|x{^q`tqGE4fA7mNhZ{6!|;U;mZ z#X>Aq*38Vz*dih#y>NaQ!UOM8Qc@BYqmicES7fQdIFH9vtwK20rtIi^4j+ryZ~{@} z5U&bGiNK0uJrS@8@bE;CE&O=57p?T^CH)Mm+&c#b#DV8II3DF5KXhnlac`*X6@@A~~5t0w3YQ3Q%W>ev;S zQNYB<_octz3m6__seD2ZMp<3IZdmSwQ5Osd^w`<66U8n`OaHrfZ%dpoKObKSN^sEc z9i6&;$PPRRM+k-@5sCnKwlc$+Xl@G_##?B*o}QjwLtBIweAqvG_YPq28dQKVi#fTu zV(v@niHTQaWo1!Z$jG>es6$%1c5ZGC_yRDW^F*8PiCf>cL`+BUs&I<|0ri*-LQKDB&mKKJJ)Eu7*@Hj7 z6;CD0g){Y(mzT%H#vYOY4kM$bZTfKoNMAOE*cex?Tv=jS7Qzg!Kf`L2i1aX) z3SsA?6QVRnjsW~go;h>I&21gAKPDMrgI>3^B$vQ5e}8p;;DEHTaXf~X;GtAkZv*@Q zI#B@-Q&Aly@x$)`nlLglQUpBVH0dueQxHoq(bt#XtEr`x!*71|>eZ?jOtcTk2FJ%; z5#ZwaQAhyP;lHeXJ%GZvBfu6vvI6v*NARePwnjW9z!FOp>`Lxk<6+pj?VU8`cMB8O zyoCvq2?qWlxE;L>@JYTBiMXIN&61ZdpVK{!j-Gd|?Ck}-`Gk2q(J?V?BMhOkNYZ)r zW@wz6u*I~l@x5$pY(8XnF92`98Jfqfjynb>{qy%lJf9%yvrGnNrlulZo4SszVJ%~@ zkQ5SNoJyP~+V&sjfHm1#YF9zyIgKjXR8}@_ZjClu30XMn327JRLJMv#uA<`N36XFz zi8L8+kF6Zg7VOm4fb=XZERudCNBQjxbDT;;LoK@tnB(YxfMS&o5Yq!iF3-wPbl|cqs`3Da%M1|TAf#Zpns-9KG(06HIO1e3VRO0Ruo59 zXJ<}&ddSRcfMCqrVK}X(rN!(cAS~PiJwk15ZC%~3^>tC#xs$A{=`;P{K$w|R%BLwL zC@3f}|Bsknk)`m9aTh6r8$0DbW)GN!GJIw~h}+HeMMO)&9xK@hkDQwPWc-v%i0NU? z!ut5nolEC8mwbWQMQj0*M6K=Zg)d+F2L)-Us-AHF2yJa^n_LxlcXwa@U~@fUawY@O2~I(-NsY1f3VYRKPUFhw zbilg?20aKu-RnvcuP`~Q%TLT>Tvu3{eSc->!wcbqXjkTG@Y~{NgU3PS(*wp4cZ!OE z<>h6U+5RmUEZ9rTaFXrn1!?8%?5wBP4XjC+lJ)%gcY^*ifsT?gB0T&M9UUFi+tC3V zr62|o6P9338sIbV62d!x4uq{6SNmYv;SGhsc_GllF~&S2A75Xf>)y|wL*86YPEE}P z-zF+53b8L3qa~3}cq`nQ*V^30@<>dU0TZzXg0`%z3^3*P`a%iU+Y5+3;Fi8{R=?Db&_Lc`c zy@Y>erWK42LUnGL)c&WW!RmcYX!bJ?@Gv}V>VDuQ5Bkt!O~7g)Q;=s+stmmT@nd>_ zKC=%K3(E{9RoQvg=XSF3b8}~9XZM!c(^ZYy%E=KM_5X*#Czzq`#rb)Rf@%VmIZ7gP z{rYto89(qRu++(8-V_oxwzhF`aX3wF=(~xL7vvI7PEK%p@T4Fsv~vvwLH)x2s@Oyr zFJA&5)YN2)@tIg_>}eLC^o$JnRXaRT2M34$gTPEe76Wx~>#?!1czEIU$=*gUUcS76 zg~IYg*_m~ut07tN6-$H>BnWr_VDd3aNp2^J<^CHCVc|?@p%ZjWuBq99Yp4r8c8c~2 z0)JTQ#iga*R}PF-Cl1oTZ)mW>5Ef9`$HAvxzdnv_;l4VfL^Qv&R0(1ojxzQ<*PktH z1tKve1(in8xw&>ZQHXueT!|lp$>4kt`1t!1!4vy^;KNWU5s}J2OH9aYU|tWL*dX$< zl=~)X9}v-#)?zfnn%Mb&{{Bm{p>*cpuGd{Bse}Ig`>&`*%%TfhcHXtU%y#CCcokP{ zlQsxSZEbU$IN@u6KVsy+V>CF6|8E93|CfefO*J~Is;|cuYn(Z^lQJ_2booFzX6q4N z%hu+Zge|L0iwUS9wqs%gumgJRU$(b?5z_iV(Azvu1jdYz_mz26-B-LTM{l-?AQoPGQDfl~G% zBQRwvile~y7-7?uYUe!kfmEo4$>+MYwXlEyh%ob_ZG<$4wr`dhT3cI_k_KZk*lnb1 zfG?3Lw6{u!F9PTxl0fo@-7hDCx{iPvH>je~+o%|Fp`U@-pCThjQ z5#a0qi4$i0J$t5DvoTn^-^Imc|NbCyMj3Eg?Y=nMs5{Q+`~oPB#egjU;w}RxaN_ad zem-HrE_mzTGyE%R8lGc-KDB>=9zzP|qb zd(+o<{z6#cbOl@&ET9M2M_dl#)lgYV3W~6h5RgePU#@Mf4!{n3;Jjk8h6K^$y8Xn& z6R=&dt5H#1;CUxb!f>FK5T=HOr=*M=6yJP_k1F@X^78WX8kE=wx-AUj`N6E}m)NWW zDQ|SXPgocGPb~n@BPp#=$Jei}@BPW6IE=y`?g^?DLJ*4F;ismi!|b}M8X7m@Y2bOt zCCr&2Us<)@_QuBt_wy5l{z<(Awd8ETFi%xFBan}Y(Z{Ge1y+{6LZ{H znt1*CHJCFryoWWE3ui%^jzLh+4fF_*T|;v-ix2$rClFfw-;w^oq@b6Dg*^pkjo^g$ z95^mu*_MokZ%Fzos*k}^g4+R42Rru#89|!KG5ie6PndEFr;8+Dj$s)WHW!$&lP8}e zOhTAM z7*$nT`Zze4_xyRxYvktV2Y_VuSpu{HKj=e-V+hWWz{i%C>nkWU_VmP(wUyeNczFB* zVgSocpwkn-i|=f5$LV28WePSL@S#r#K>1WxUi)D_VtPVyg5T~q{V?7XfHDK_n!f{t zofJbWo($m0v$#0$YY1i9aJWI{;~WE5f}Lh!X2!;7?&~ws(cuS#ZERFPAkdsdOb@SE z<2s*&&<{3vs^&4ze!JdoV z2y`OIF3?0+innj?aZv8_MIPB+q@cQ5jNYfo9L^InWi>Q3Bp`Ys3y?zWT}*=%5{nNd zX15}0!Sq>od&d!v@D|auDk&}}jI)p!vtRoMqC3Q|sPnTtQi8!2 zlEY6Kef*^ua1{33SIZIyO90wBDlkwU2@Nc1aZwQwJ*);MpanBg8c7f#;IK_rfR^Jq z-Dk-wHa3bxSI!;5llO)Q&WXno2>_oE1n7B432=lWS==ENPyCq#rw8L(Kde6c&0l)b zaw+q|;$rq6HVtxwFQ6-J^>vb$Y;0=kY;9FjSLfpA7r!}5Vzf5XCyW^81LGMsHVTOj za8jC@h~Pj}6VYP%2sP zoodw)62Gi0>sz;0U^?+GkS{#Mp=@YuY|o1qcCo__MB${C+=-5Cl^qC`QzAPVL<^X2zerMqJMnIVEQCL+4wU(X7+(!9EFa=eSXjvQU`qZ z^5y5{167awg%YZ6z_3%IwTcsGDj6{bUj*jZcTmYtG%ON2pf}wlJ z0r9tS?BZ$uuXNsi5|U@Iz{4p>VuBySHjb#hib002v6?V_KrCVZ=1%aI<8b?t9-}^V zNb)etsZ;QW;HvaV1qB3r{QNMEb(1i7@Z1#%J39`e<`G8>y@Ejli%Gbf==pi1gMcz% zZCqSd{Zc&$Pw(TChZ;%}AF-!Rsy$Cfiz*Poc|sOZ5Evlp1~vNaW$3 z?#%3tYQzC9&d&#b(fjhsI|fEZ^dVFjpp-W`y*xK}y{BXvpFM6_N`a6i9;3Hmyn!V^ z!oXlmoCzdF$}8~EqZ8^X4KU_2?@hfi3wRTYxaIapk98qN;%Nq-Ln>`=NP4P@R_M zvc6!ZqtgXf;+^sXPw&nS9~!7#mR;ZU2aF-mNLQ~ih@M)3<3`pVf7~&4$xaGr4^eSf zwjMVC3FkMmU7N!GwO8+6cs=4Mc>EE>B-w8XQ}keJfU>EAFo0&&r09Ap7$U^XlRtih zMnt?Ham>liMq0EVqgf?n9UT{ND8Q{#Qd6&>R;Av-5s0y7XWIjvCM9zO1O&cfR>ZGg zgcO)D-UQjOt||`~@D;dpa6e=cIN6xtRtngds5(A7yMs5`cruH!5aguT_b(-A>FKRc zL_+F-M*;#Qygu85AFeoQARS@gv8M!4;xL zobw>95FTS>JjWS5s|q+TkrPPub0P;V`oV2M}m z%WR@*CDcNTpgmsb{7B7H$6SMbVM`m5h8#M^#?>>2Jt?IFq>}V~!EMQT5YW$Ok%DIj z8Bd)eI2K%adri;9n=URpZG{%Z^mrgm4GnL9>g`%9Nw$~7eC%mF7FSn+*rt-g!tjXp z)w_oz5c$J#VW6*6-c~!97ytt>M{v&LfW*cD=M<{ELs)f4uFZN>RlsWEKB!{2;Il4+AJItK%6BGo=YM~3m*ZZO1z42sRy z3wbot{}a=r=zT>;SN9cwE*wsWEh`rn7l7h#T>Bby2o5FYE;`-3X#g4;7vt`Z_$R2i zxOgwgk;~TBJ;+M|+#;~YY9zq>O_3mzxoflTH#K<_a2MSAbZ=R>*W}NipN8g{tXtY- zaNe=o!2x~i>ESdgk03ycL*(S4VPS*czrTc^0E}PT*r1Tuw|_ri7+~qIa?-L_uLzTS z@$?WC68LPN9@rgy0|S*7#>g=|poh;XNSe;hms9%$%>0Cp~}A{tnvbY?$(^qT(;anY_hlO<=Q z20ZNv8kJquG|vR_BfS1^Ot>mu)V`a^N%4mJZI$G_hX1R3AB&j+N2R(SC4LQ07pTu9 z|8s?FdqXZ})~nFdrD|-Zd7q}#A)BGaUyw^sdQjxtCy`!kvETRSH@E*1bNSoW?VMIe z>8*IZ{X3^mPbz3-?|e%A^W*OcKMK{G7QVAEg^aw>9La65B>j)SI~tQJp(6hmT;($};zZHZG}+Hj267~X z9Ip&#ka~^n`m-W;W=**BtQ==~YU)$%z&d8bz~P0s{l|}1=p{NjG$s61Ss^H`fRG5W zJQ*3;Yx6>4dgLeYnNC0q4i59n%V#+_o*ak_37NwzTQZ3?Pp=y{UPeZ0Ay*N_uJ?8X zf;UJJT%4SWUcSWUH!QWIr5^^#02c>|W(y7i0+F##(UNt9gBn6FiSfN6A|l4so^ph> z1HUi}F9Bwg;1(b}D>p|2PhbPY#hoB%@G}TX^7M-*p?OdWWb6w@!uqsEs(`TYDxy@l zEO65Rl`t1hH*UZTTS;D9`=3}9JQhh@HbfZ!!;K9M@TymF?yapWtUB55Uie(Z|3{l} zL7rQqsYS2v(&ur`7d-cp(t$%pM@IB?b;%@fB`%P=A#Mb-1K}R%lX87e&rMh@=!NaC zT=_9OYhs^{X9OnS2v7=4CZIora8QfrReQSKxG@KE8<+<`58B0W;DDa)?j~fhkkkva zh4m_eM_j5s@ykwnoAArft?m!1M7Otx!{`s=C7V z_dUg9#;q@1qot*l@YiL>XqHC-0fd;6mzRp@A4;vAt#mpu&(B?5Q6d;-4;^Mw;Q%uH z?Y?lG7#fd|SWPYe)vK@X-%F_{)D1ZZ97l3W<*`QA?yz`h@GfF$ge36lJ8+nq+T6mT zJ?b7Y{U6n3u|!jXxQVf`7vg9HkQ?)LbU@^+v`2qG=jU?Judu}&>Zfb6QE#oZTt-}- zl}C8dk(2)zA5TYa>hhbv_uOwq`W&d0P~}F(K)DYk7Q#;B7l@!@dd|#L?2$#@;Qp z=~ic=KtzO8+h>I#RyH=+5joCXQ-gz!z$@5&#Q)p_yF+#Ou!2QcF*{`U92|BaQjzQc zq*qf@1AT--4GXSlr9h3+V?H5>qzFt5GN2NPbI2zmayo|Mls?<(>1m);lxavYs3GB) zl{JN3ZPf|H@)7a@L~+>RPZiCp?(g~ibmszMJhTc=-48L}?hm-y!m`;WcNRzpSs_H) zga{DXJ83oWeKveO9UVLj3=+uLlP$bED9#T31*o~^X5|73o3o%a@!r^rgNy5kK*I57 z2`x3ys$n&-VXR?H#>bzAhF&CcaB?y%Fog?SPm&HACtNRF0?6JukS3TG3_xjRY1uk8 z@C6xjuwuoq70~ZFl=VXCV)L!Y5+SHkFyn;Zu;UqeDFXw@3$KEN1_MT@=0WKMD4Hp| ztUs~ppEwO{G*CYjI{MB?Oj4r)1K~?x64>-o)B3Ov0|cH6a98Hs?}SjAz24exX4fyn zD^Ja(R~%;5i)1jKf5;f|M$4*z>K2b&ZC9~7WN`|%l{Pgr9Ly{PP_Qm zuGik$i!H}(-^PTW=d(Za`%@t3wDii%xUQ_f-CLxjZ+n%;S?T0|{G`ruv?_+DiHbxb zJ#aZev#gWF??Yva<#f2sK=oEo>7R|dD|n;VfRjh(oYRSOPtAinuf&kY?KNTiJ(8WE z7P(6@v!KIss{G(lTNQ5oZN&&1V#)ht5=UsH>Yo&CMi+@TeZKAQR=8`IQVEiEU<1A5 zN&pq$iV3+-=NMSEJKj|-F&EA#bw;NPU8{%GEqVeHc*=Yf=8(~LcXyj4p2cOa zJr2<$DESI_uYZ1?_qhQPFg1sve?kG_mb%{#0GJk>_uk$F{*jM|IKvT{6Q2;A3s5qjcJQ5JW2-CE21s9G_&V~eh*rLIbcEC>KUY##2KLHE z3?CO~1TxkLK7JBm0>DLVObnc|jyiPib|5HJe)hwAP5=A}dSc7hj}SX-#}br?AN|l{ z!_!kFPA*U?3AHM}x&Hr!=t!QAP|N}o&Y}{JRHQyqKd?VI!w@ndAuV?a)Ih9&LsD>X zQ;I^==H@1hEACLDh7zJM*SYVIKEO>2K-2K*)l)J|iBEv*@w&PSwGs9b)Oa=DKjWfa zdmsFr?mcqu@-BKNdiuL$3((APLMyWX8CmAuL4FwPGslG?{vSUnwkT|JFo*jA$X_&(A|#gF7Qa#cqd=y86{~+ui~8D9)9j-_pJKgY$tyU=lt9A8?2BA02{h4djfB zvhobr!@uu>RC_}9_G&)lGFi#Vrk4pXoMA!%4|PyVX%Z_N4^L4+K^y8@fKXXkS^4<1 z%l{6l4co45gw*e)E_<{Sv@*NC@BgjP=3ZD>KzIj4epJj;AiSQ*2Rbh&AUF)fXKeCs@vkno|oy7^a;j1OL-|D879{Ljz$V+;SMG!~GGijttNB@$A~gL;Byd<2#X>g#vkl1}=YXpLcY8?`=Z7>w699gN7Cz zwTqFFyd_pVuf_jCEo<&9b0trNf6s^d)-`?-)b;>JKAe2IQCRR z?$JY?u5qa|-^PkMZCYkWIcQwh_W!%1$Zx;T*{MNGv*CmoB`@dO`Jqj>#Z2+EgZ2aJ zBr-=IEDD}C7g}lbxVd>RmLe z>ks5Dsi-2-ERek&$g4_81gJYy9>Q0up&RQxR zRDkkVGuKykVJ+hK`6E?je@=I+scq)9_a5fGX}&yI%PTecX}i8cnnx zS2b4+k$*AomYA41F>yAw@4dywCbw(2sd*sn@vk*oEB3zz7p4-r1&;?dZnbQVND;03 z>?oa_uS$y%YzfjSd$urE8xH#Ac9op!=h1gr*jjKww z6Q(8=+Wfv?T|S51Xw{XD>&QNSo6B?E{@2zJ5q%}i8@rk_{e3PQ-7?R5<}b%99iboY zrn65fWg?TXi}x&dXe*;FU}n@lCs*`m5u@7ACT##!vM| zEnfy}Y|kq+jh`j%u`p)vk+R(!TIFsr8eO$*_E;Y|tFK8*Ra@f}Fgw#syniV8czu3R zwoO;=W}on6(=l{pzod}W`}+A+Z0f`iGKr<-Mt<8teFL3ad1@?x|-UrFYoqL-*&^V z?L9D8-A(3+dI*xEZ%+t6VWbSB6@Jy)N>|eq98Bdjt>0Q;*8SGE(-Ubv%EKBnGg=U| zrl&_N&ls(bhx(IIoM^u3H0?5aV-xaj$0sSvo1H=5DckBm0SO&e#8^ z7J!=PR?dr5KX!f1oGgR>T%&a#Vy)Q$ZxL}{KgZ(Y#^t4kuDmfTt0!Y)LB#YrxkOOm zUhgaSeCv~$DA|p^>BRKyX?Wv6F0S|G8t$wPp3s*RFPB zM3ty{PsvVA{OQ|n8jhlMJr$YW-h9&Jfeb4vHukgMNVRkh+0SM^Ionw7lBZh}-;<&s z-FG{~qaj4>eq&>ow{nKZ7Z%cInaQ2MLbKAJd#xq5H9xYvG9TyVplAI)UWB~6JD-=g z5hBY<$C07aKbNiZ<7f?xs%$==T$|4|#6n4_Cyy5BR>gv>qp{Q)H!u67rGRn*GuYT%H0IwF*uIr=CWw?}7KAa7(ven|>Eyk~{!)CZnv$XCH4*l_U-IY!NfxC{lwW0A zcLn}h756$%zdo?^V>hoOQ<_$m)`-Gy2I-utG+v%ujmW!ha31JB;k*+@dd_K0>U ze2-Y}@}o&{Bu>co`9jUhPOUL;^p;+eX?ULw!wKSllg5b4#AJl`bIG3$T;T1Fd}65j zRBzJq)%5ZUiNGXB^`I)<9usl4?9A`(M{F8Zb}p!OMEYOa|C50=u)%A^PGZbt{HgG$ zp;#63-K2D?7YwT$|c40THLE4(`CDTg}0JVv7uUGOx$>;a$r67fGbm94;linzEOxj#rB?(zf3m zV9@Aw;vW!NeyGFv>eXzb%PK8{+VuG}muVxrvcuLMn-gP8k5qncG&Vk1zk0s-#`nZ) z*7o~d-yS}=P^sIqdbV6fP4jEPR92l-zJj&hoY^y~%#*zdl^+$6PUCw=K$2tgZ6*rTABF3#YeShtTo3^kry199iR~r3v9Y#hJIE@A^Op)7f z`1;E815yucY-bcqud3&J-6oY*b9XnxFt0Mh%<>p6-kh&x;Rb7cR8^DsXqk6~Z3q>1$I`1uQN? zt~)|c&r2z-^z^lZ%b2E)h9L*98&}<%yGm-Bx<_=BbC*_Z|B_a#d%XCqwW9txlwb);-0R8#xUnyCp1Eq3K{6GI_syuy->afKm zX=NQQD>EBwDGUx)Xl!^dasr=f@gc?3Ka!$i z+F?Pr@%HVj-Fr0gjSr^-!J2G-ApMKk`PCDV=PsYy3P8^maOGEfb;pbL!cnnnyP26y z=g077p~+3dLAv+${r-xIY(g#^dBvQhaa>FmbAD_c9$#`-HJNkzA0JOpiHz_+9avD5 zE#MreGaI{YEAH6Fh>NjnPqi6S&b@Gpr>_QNlK%sr_IvbOzk|St-Qk-vT3hh`O3YG>CuG?xG!jN z9|vY`>1F=n5b?RcV%FH_x-c%Z8$~Ssb4)^S4_TdK&aDJ z(a}(*kuOtR34+}7`4gWlT%&qgTSRx;PU!TETiR5OWZ6E~(|R+cO{~cq(V&pIRBlz@ z*w`l!-{$S~7_;NYZKvE#J}N7)8M=R!mh;W9eO|Wlu)^<2L)L@!qmP4TOys8oUtjK- zu6J~NI9M4t=5q6$y7`$bu1Kxu=0dNvX{m!9*Uuic+>#c1L86O5p>1}~kuDP`%%i0Z-IT1#qdhLg~Qzo1{xwi9n z(Qe{!qBU)NxsWn3X&TCj3-@>L~?r`{B=!~F?th197&A^<(c$;){Yp5KN+mdWVD7~`0I_e<&{2Z;n zr2n%=8^Z_`iRPEJ)YTb$LeROdt$k-f>$>uzwNa%X6)rJWR#HkzcJ&kh3$E4Gfj%Lv zFQ|%(kNS}9-D|F@N=iT6ae6!Aw7iUrqfZFwG0m2QJd2}jXl0S8x(02Z{9%mnhHS?> z`mgjlV5_pS!C_NUU!k4lu57hL7pn>NNZX!QckedD@?~VEld*(Xx-r`I>Cd!?i+kx= zm@{diOKcMr%4~{!%?TE zKR(GtL|<_$1Nt^&)eCU~ZxTceqT`R1m<6%j9#d2#*{P$WGBk?zArlu*5%riXbGbgM z$Sffn#o=gF{xK~LYV5GMv-&m0l4_w}zp=Txv#B|=tSiMNqe_oCDvN<46wMsZpa0Zy zRQ-G1;qcVny4@2Q-iH2D%LswKOT6XOyhGl@pl6aFj>(O>N3bvYwe4D(dbXpdH2lC~fVM%+;~L z%Bo08O4$bo9H+mXXHnJ+i#io2RBvf{-tlJblPCL}2mWPb6#VyJ$M3tk-bq@n*f5tX zv@tNa#`0%5O)^~~A|}cYc-i~;WTg_#g zEXBHxBKA3bNug^#A=EiyUK~#Y_xX_Jt5#nB{9~TB?VTO_C)cwE z79{B_iu~IPf-~8VPu zcFEF`*h<+e-QJS3l3H4A%w?68j~5l0ENI-^)Tg%FdkxRi`^1w1Ig8mFqvhg#11hQj z=BA@Zcm%Y;u1|Mlgb!zcPlZG$rsjc?jv>3U%HdY-3acym+ci6gNF-!0-u>Dg-JWYy zmUikCvo!1aGlf|(dMS1mMV0{n?-Sz@tCLz~&S#=pPEkrHy;$G3&umG&p641z)XVN2 zaVgtx=Q=uMjpNgwU+7JIS0^DVx+jkKFr{i3lumVzmPu@KR+I3f+_-0hJIb$?9M=1U z<=eumJlsBfSil$nlQM=^x0Igeaax!z#WlzOy*8>}e6`Z!5-Cmc%hjE)6|-wGGdl;r z&)&3HdBPlU()_2M)%#Rdb)|>?UwNxjB4T*ui*IF6@Mg)VQg+g5X$G_!LgfSV~c_bt7Db3N7ozNT29=|(a)T_(K$b~<64sA zuWA_-=sY<*xBHxs{u%0aOo@mSR*H`9tq&jd+KP{(Q(zh%mRcMYj2AMi|M)TCG(>qM zN4eg2cSrB!$ubeT2-mEOrly@*bZQ@--1uqXMg8&P<;6Wa6v{l6Z~tZ-v3%z#Prk9w zAnv1APT*&B>ud}n-bXQC=G1@Pd%KeN)B~Hu*gWEv63$y`4=V$8pI^R4{Va1~+Lio) zVQa%?NFnwpm&Y%@#)Ib%9vqqJOYP9)6OCJ5F&|dBS#@vhgvZLOfBrcq`M|2Git5Fs zsU>$BVeLBppqiR6lT`l~-|RSFm7TA9T+vrihYrezj-(sr57O09)v3wv6Lv~}l4r5C zA*gO?=g<06Hnl*Emmqi})bX}f`@0tA>?^M~XZOzSG1WEJ)hLo*)pk?z?}v8=8yW{{ zZHlZY_Z(K)%OG^~`;+jjPw%=?hVHnlh3lKAX7DSDuQc@@+MQZV9uU1&BhyHmB9*Ll zlvMu^`B_?r=hqag1P7K61w2hCF&5isO6he(gV@rF$Km`-e6iV5!^0~-W9btvl=h4z zR6XEh)SEDVQ-A8SR%Axu(`?U@=*V1phD(Q|!!emtsmUT2%N=2Y5{y1%b|I9$?#ySGr6BF#-j-N~O%!g&y z>%(&y$ZPA4b!DGkI@)p8K(VJZwmHFN|2_(GwF`H`{L7s}jmw8WaFS6!iES1X3M=Ig zk9hCr8{p5%c)#7MzD0%d_~y@|hu&ZB``^1S9mOdwoH3Hn&#r&tC4PZ7+FyKRP-lL{ z+=iE!gp$1V`Nf643MG@F1wCG-_jmOR6I`&VAGML4Oqg=eBofbv`-H3=KcA35!``cr2gBmo|0sHnpl=|}b7^kmY z)z{CZF0(glEVS6oAFAxGv3+zBQ)ozXb4lu2+fw}M!)X^}epz+CpP5mVm!A;{nDMpBxnBuGBs11av|_;_h2(S{V%6TP_OK#{T{vMbE_Z$fb4N%*Z&Q ztn4&J9UBrNEV2JYu5YoG*a)}8lc}s2r3#;v{$`>4MK(+4*U@OEX`+vYO6+ zJkHd7;y`w!Fs1j!bt#MU`81I~!pDttR8A=*Gq})Mgg$k+6|OLHwXl9+&aR|0?ASu( zrjb<*dC~13r^DYYjNe^|Ej#6Z#jDrV;oZY)dvdy)8r2x6%G`xEbXG{LkGwQnA-><7 ztw!_YvCzw*LKDG9PJ(+L?`vit4-d`Wa2QIU*4Va|y48qt`j?i7q}7H`$5OpVbiQ7f z)xlh|XWwr2SzXDClUp}iUH%eUe8%?|-nO@R>0#}s{&nuH(%WU63zqHto~s4iG%57I zLPvjfj>)&ZJnR1D)ouFex2+!9`#pa4G+M4wdd98CXp$@r9=85vw^q&BB3S-0>&q&q z+5^$rbDvPl1%374;Gm&lVAaZi^(l_fos>IT?jxZlh0g zn3~1vi{iqYy+S!pDED!&$zSvMC2`Tg0b|O8b#ir`h1jm1XF%-|>RwQ8brd;4jkn=M zKR%lB+)RC;T!%1i$Gl^tk(6CQh&IR2^0<&@vqQ3`qnFo1S*d`4pP5=R;TfM54Khq= zY3tiHOpDtJ%=|7r76=cx>0&Y2LB6;%>}Hn_RLE!jL`*bJBWq%7)%mQxESnB>?T3b; zAyR((0(ViRxR_rvchgzBy9=M(-`hmJKgYnL(m88Qv(W3dgYHw;=Hpe}iet@srS|+3 zp;8hhF?0L@q(@HvTDO3%cGP8{$$RnOuCGT(3@dK6nRpjV$ykMj>GJb`XbOfE7#EZ@ zE4E_r+O=@FVzTS7PWs7>C5?B_FP0^~lHOl`Dq);XbTD4zhuEfSS53{Q{E#SN6tkA8 zB#1%A@W|ia)lJxVAB@1zQ1D?6-6nJW>fVqiADm~6H=EWS1^X&7sAGEXhcNpppTt== ztvrrzg>?~;wSCo1-}+r$remCE47a*Wg!2r>L@XX{Z#Y|5U#B~ECRSJ{PxXeSW$#!* zkK5dvnTUDA{a?SvW$v4CeIuDW-0+URD=X^fhVxXa5=&O3UEkGMex2z7`&<(f!_r*W zZ#;3WvS}&?YsboLr5I?$3@dD+-&m!*zCiviq?G^Ak*7Txyw=p-PTkZ0`re!Rs&;$O zN1BaUTs%})@x+OThRsKUofcWF^FM!ov!GY#l#!9$tw`scJ=>Nd6?LIurNduGmo+FT z9D}1j36t>YmvvhVKH`M)9BmdXi9Z4KhsmFse%CC;RlDwwvw0OX2Icr$0Q1A1wvVpq2 zMYlEzyB`B^lIi&ACzh5imWqbE(bgJL` zX4Qj)#g{6=TqMDU9cC>Hg)d@1$=5{3X+VY)5^pNuDCw-+w~|4HbW!E0^1>O!uKt zIwPN4J3u-AtCjIr?Li$u_MFX%;O>#%g_Kg*@Eh)*Z67=ZZW^gCyQ)=Vp`a*MKM1&b!57 zgYJgO+~xwerZW%hQ~#1{q<9$pOCQn-YjbeMGJz2MlI;*LZsNT-D$Z5f5Gkz`Gt6Tj z-;UzF4pzZ;=-R2A;CYpZSdH{pYMfv@{po;Css;1zAMa>0wGKV-VV&yKFf(&#Z7rDU z+P{@`eLuATM)BFTNl_ioHr2Bm5If8e_%PzYF&6tywlpg(=AC~t6+is5hpVTgO!4XS zEY*u{8$~HH!4{~SEnm@a*iMe+aGwHMp4i3M2U|ni+{u}8-W}Ua6 zS1bFy2j~TKDQPkvKI|Z&<2c0-jP7i=IKSKTqO`Q&THUkO7qor{ zBFS5~w>Wh2^s6c<53!89uQu0M6BBa`c-t>5Y2pSZdvvrHgde!w@}TF@EV7GR{1~cl zVNv_~ZcI~b-2Hn}T3Lbm#bG?xpO<^}33-%UlkzDtQ^3^2!PSAY;+x;uIJza-%si~5 zP}o-ByFbpVi~50YhJJ}AY)uX6;j@kmN#8H0BqZGPr{?(N?XD-q`6*%6bvd(hz~m@- zX#0x?JOa9=!p-|-K8BTAMbqW3pEECvu78m|wcD5LSWYR22#NjCx2tWF#Nr#8PC@aT zqfO!`{5mpU4?Oqa`Y|~l=iSoNRWqJc(9Ub+Tdh95Z_~Su$AI5luS+OL!g%4tF3QQ- znw%3SNW5!@-t6XMS4?Sl6LWiOW+v+4D|0>FYDfkx%7V)2dafsPTd2_s;CA_A{hV76VBEM7BA>!g!AW&@A#pfy z)?}{7{)zkYdpkQ4a@&5JZ?9TiCpEXDME-hh{Wo{r8A*mioX6b0f4UpX-q=^Ou=cjK zV$JZjrZ;VrXmDzRV9nF)V#>aEt zguHqw01TT)orLsXeg0fsCB^dMlVXX|vE|@n?2T=sO{ve0=js(+jsF!{pKfoWBylgm zY+_J)>hA7Q4x_nyD4=+JMkmpJLjB#+gnM{ETYFhvHJ8(L;7O9Xjkj7&I`y3cVWpo$ zL%mFXOpNt<7%m>zJxSgg-tla${*s-EVt74s&OnCf4fkU`23A3HLm$Ks<_ac+=N!!a zafrY4c5v!l&YF!~zFg7QdjAABLzkBZi%FQ`+ zFWz3Y#&>q)@F`G|2(dlYVjw8T{`%dR%~ffn>1?RQ-@ER-{N1vxvU-i=kQ+)Ihz<}s zv%R(^CH$w7gdh+iye?e+-+lF+w^l^!3)Nq&Y3F1hi;;#*idAF@s(tHlyw1VQi1$vxm1C4#(Vx&urM{k+pxSxf zfvb5vp3Hh}F|d+wWsMGHuT6Q7y5_ z`l^}6xSv1`BA>VI6U-{1Tn7V!VY-wSKYdGhQTyA45Xh1YlS z`{!eu6i=8LK|M%#xsLqUqyOhivj5iH@4tK%;GtFgpIU(b)zAO`@9p|8tM&ht)p(lh zl!b27lPJe+SS1Mb2Zx4CUdeMBL5Pk5Xm1o)6y*L<=f3tnbd4`IT15U;j6~wOBP3Eq z(3}TIEwo;uBM-%}94P4&va>Hhe7c6J7xagSaF+hF-?n4r-FD}srCD4cyzabs@#6md z-8+jYU=?y2zia>o^*oe>XjFY4I&RcLppOnTkXNM?H$NoSfdv%WqIU+Z-=SD2HJn zbVEy1iq%e(@I~tj6foPP-?Ge$P?K$x^~_c-LSB0t?WqJF{o4LD8!(PamVLfSD5_v+ zEi|fza2pL;orU^#wpYbbvWFhDabmZHP<#Bl67VKE65$JQ(1h*=cXIyYz7ljAEO@68 z1ru5=6H1XzobZC`8xLdeo;?(5FJyxIU57{+tRO_baN#v-K{DGXpmBu=Qc=pja$W`- z2{L1DbRU7@otpj2)qGaUKqU98)<V2MS1)?PC7_; zZNKp_aM1*#T4@`1RQK>`Ayn*sS2k9rV@rpT8Pd=Bq9V4QjOuo@BV0k(0O%>b)_&~G z(H2Gn4@~+gg031RCg@T)wExc?-9ZPvPNpREA8$cMup#0!TKtW7W*y#1L=}bYUsxCr zfa#i<(EDN!&e7?!KY`etQhOAcJ2BKr(Gtp8^Cj6L(d=vmeOborgHZX%O|F-t%^ z#i`LnS>rCHKcy^l-^c_yZTiZKwX;OgasV4|UD#;Ca^Zu5vho28>1`Y#^yaGa;NSUy z0^SkFvcA91QU{@@1nM^XdV8@GOFh>YaP~-W1iHFb@xUPcM-^*JLjxQyRFzw}tN>Y- z@NVtLfq@t~K85iI4`qfbW~*cKZiv-aLb{E9zq7q%g{Z$k%L&bN)w}*ETmO=(bgara zPn9)OJBLko_aFFCx#yqliWrK3Wbm9Q-G=%B!+?Z$eh>=Qj|*Jpi$!m!%RDp&n4tyb zHOiszlk59N!VC+)gw$U^?bWPK8Zxr)KYt!SdQ?sd zy#UsiyG+D4#$TWq?{s9ty=CHq2hsVk8Ko|$C)sZ-fUcgDLA5A=&_}s6jL+(HTr zrGB0cuSeB7;a$oD#;3Xu!~l7%9tA_xdbPLgwxb4E!8Roq3}_Z#os`+mLgzA@g9Tfd4^#i@Pv z*=Mb_*P3%K5(#l&wy-^)E&)pfhdoWMoNs`I1_F!ifTRb~8OUY>A?O6yMWCFr4vN5E zZT|DgRBNk6X}$$gKdf;;45(YPqErjaXch2OK>VL% zZ;j!XH9lUv6l=+K1sZRjcK-tc@I?)_U!Q!@dRu!+WIcW9I@Q+#BK)8C|67##_p$%~ z11F;7%asmsG!sz3iSUlTqUC6x@$z1_cG5BGSuUUN=s(x?<#+Ppk&Zc~AiCboUQFZ9 zCEa9#1NHQl)|)rfuv({Ze25`g=OmOnXAw)^28q~5M59I;CFjLt_J)fv>Ks<<}n`Nw87J3 zJXUi-jC70Ddw;?WBxm3>K${SD+t6Niqx^eXrb?CCRJg0RYEv|G=_lms4GlZeX+>A3_9h1sI#wyu>}gY=rbM=w}Fn1&8Yc zmLH*#me#2nEMN_6Sx-fzfG{iOy!0JxRBvxDTzvYoEGS=0!T^C4=Xt!{4C4g#4i(e@ zw^`SzPzKOVfSCfyOgX)qynm1Nt5s@5R)!J+D^HPVHUXb|!_0sZ2MxqC;4U*160)D( z4KRn>2tuwFpgW<$Ld|6iG^RuFCWoq^W(a=p?C-xrLO1|o!_y~Ddp^LotJ26M-Np?n%*K$rxA9-y2;d^#;4tV1ar38c5EC`oa;u+NWt zFCSNeR+(qEJLuMb;p-#nfgt4=hdWGy(Xyy!M}R0(OpH0}76@yds(!h+K+uE$76nWg zP#MAes{Aiw*eU(%H`V33$Y-`(pDdq5pDMCIXy$W*bBmRe6bHXS15y%jrofh=AvX{O zqxC+xU2E*O8DNoH$0= z8e537#GmxH!~ zTr3v@Fp=)wHHUQ#^I7A@c|z$AfQ4f4VxDf@L_KinrCK&1r6JF#3{;yYAW4Cjw8I=P zXC?u0dU9ms^iFTq9B~kOVV5&O4DdNjAkMQgqxU<}Y zTf`*#kWf@@R1EzxEicujp`SfNN(=J|=AV7%)@5d|>{~Y^*UyVgvP?+UeosLEI@Oj8 z7|SQ(>lehN%0_G+lzJ{ol>J(^XTVyDp)A6^qxU#iRx0FASZ)fO8{+tQg= zhsnBrURsyQ>m$szOidiL1IK0?70H`I-RxaCexl0=4XL=Y3e7T#dT=g4rl0RCoy18t4 zMNiHey}bVzeR!RgfyGQ}<6SPkF$Xg?q$pPA+Dk~swbH4F6ca9QYTM4`Tf@!lpOhZQ z1>o^K7DFHU#DBs%OlsV~8FnNG62@cfN-=8vU_O$*n>M^3MX4c=40M0yDNpKZ950;myU?&Cn*BTF($lzeQ2P(Ure2m_O zU;mnKrd_4v>$-GJO(7|<3VZlt&~?4v+gqmQ?b=$(quxrFrj-F`k1Lt8BN)z|n*^=q$Y?y}^dvm;X>9T{o zHvKRrk6p)Wv=9KzH2U3<>iDrpnIYE`UadRDkDWT3kd)NhtvHhE&&X3cK4Eo}I5pwk z!=a*dK`8IQ$TO4J*b&*RYAQ9jvLK#(QMV#8%F&EHcOT69FV42RL z(=SMU?i@3ej6ZxBZjlZ_qq!ca@R%VnhPSb1R+*W_n>8rr961*HYjY-UFY|S*)-XDK zahpjUpNF}ZN@dyhnx`TI11j5?X9QSgS$*}E!EjZe2K=!_B}nL zGLb4sWDwXL4&4$w!NgDP!F;~GwXDE*{cnA5Q3m9(nNfA?ITMpk_?4piJ%v7|g zCcc%`+B#k7roK65R#xSKIe&6w$6BjqQ2b`%USg<1^Htis-JdFI*=eJttmr-hg0kN_hM3KE&@e>5ZRn6O}IDA9v&ciBFuNp zp`pLE^_29=OFd76DIxTfM!V3Xkf!n2jTKcZOndxsX$B>qhLluePbw*$piA4#OiH=; zgp4==83p`aO-8&uCu+xekDAm{t>A+@0K=|i)UO)i2R34Fh9?bJ@H zJdn+zs5nn)H+Q@vi(maHvHz%!6lCoq+eylpZkl!vN=aE|y;m#kw&q2!k)j6LirCb< zK9gXRr}bz+dB?C!S0sT--DLopw)%u2#7b9m`IIFzwhs>5=7~(pwrs;iT z7^h~kL|e(Wt3cZ9;LoT1@w@5SW`{r@F=STdYtA3Rh5kfQ9~by-P4jK^I6i)4JZ0n-*h-IF<~tI*55G0d3gO|u=gVoM zYTdqm=8L})mCuMT*Z*pZoJCq!+@vmjqF1> za|VxXx;95=jpx6zv@6nU&%1d(EhXW@OPgqJya@=I>=3fx)yg|b#JS``;0iT>&gH0z(KmojqH6?)ZT|mp`;)Z5+;QhF`SBCsvj47$UOhX zYW`K5u?2f7GU{A-Vve`{B{FBR`$Ntf9~&ITvAcdN1CanSYj=dWKwGD{({!VYnpJ5J z03HI!DyQa^srO#Ji>~F- z*j8s^T$@@}igx7#bn=&K60`2O!z8JYUWK@{*~`n(aC#1okxYfy!}9`^>>mR2M)#BiJj5B_Mb8gB_uoq+a1QYrbk<(d72$ybipA5F`eV#Ox7V3Z3#jl zhn9$Ip@^}U6$T+>%Wvtou&~k z@bgFU+CFeRo%AdXB?nw3&;1_k?$G(LyGL_RxSJgiXbM)9ry9B1uDq+WsTvi%`n*nX z-$X=6(6*Wa$khSa>gR=ttZ8J|sJRC6a#ikXq=u~yDRO(1lud0=fwF?W5oj?TPFi%l zI?EHu!ki>*AkWAltW83i(a~lYA_;GI*U^&5S;>%IUb{SxgZG`S)7ag1k-0VAFm{jQ z-RQ;0FgKuj$vmv*m<$N&sU}vAC>^*tDlw+{oki!8{vYai<(F`^WCu zkp&d-**;it9{<4L;kN&%S>GT*$o>=KpMTXg`wKYz1i4dt-#^eP{`Y7lO*?xT7&He? z)>d|ITzawlEWT6Qu}GDz%X?p^w6R{~xqf6T5I1vtLqw|#CV8JnbMiTF<}JwZKDV(N zVduVGM}Ff|xyL|Ck39}+5pep=Lsx^TzdF}O1oPe(LVW6TViVS0`~&|LrS#Z+>r>!t zd1LTya&p^G=dx!E&|(Z0>{wv~Ir(R>z1eC`Uf9pUi8psxe%S8*P!xreS#FtIyWg zm8Fc1;f?`Kp zznLX85-F)wjy5(Z9n$Y36i?b{LWERzukRKhL)df*}W6p zZ&+`0@w$^ze@JZy(7x8Us6cgEGkO%(r(cGSc*v5bKU1 zQM+(X7NyZy~-*HFz0?(Y^s=R2hX2>p0FD?__fCKk_ZX**83u*LbYyQ&a=}S*`Bq<<2zEN zJ{EJQs)eh?A5nL_*lZ2F%O-b|lyRY!9CRUE)-)>W{tBfjBw@K%#%giSX3Ug=M+TD< ztHF|fiFi&_G^N46^Tl3_R>^yDNtyI#6k@u%xp4sjcx-!IjJZz1S0%>O!CZ#3=UWJ( zc#Q+JIhdrRf&$);R~XInkCt^Fv@#)eb>*Z3%ts$wsB(b}nj|DuFvxOfl?zz~*@4gL zVF{g}dwYswnh`(ZDPbPwq~s+xGMdjt$R3<8(OCKx=;PV!y8HnM;jS2Asn~a;rQtu9 z?-b**-Rxp(#U6|6RLLA7o$Nn3EwUZ+bq?iMNlCTiD{wpB;|mN#P@7S>cCEiCot{Oe z%qerZ?(E)T5_@~JkbsbKx=ae-acl5``-o{85o72+{OGZSxC$z&+y-%p5PD5|?YvcH zsesSaEDb-IuMD-&8nM6h3smScE1WtM*7UmmUj8*az`I!S@l4>USeQK2T|D0Ws zL8%E)i&(lJyub58UZr5J7GH#^Zs$ON?gk{4f&qg&Uec;yHFlG&&z7nM74RDkDdS4d zW3AHcfFJ^?+qY9t>J#yNWUP@NB^%tI3nTv26TS`Uj*o+RE+1r=c_Mdrh(VB{RR5Z{(q$@d66Fm;H64!c^OkXy4iXgFM5GZD;w~y!-bA?qlFC*tYf~Yv4;f{uxlS!uR^%!DG}*!3)=GME(1J$f@4xO~dM3<+D4W$5zjJ@vEyJ6Nmpxt^R^kU1^6m-h&175Y9NE^4-j*1|I}?~%AD$;4XO zGmx}~G_=i;9rRie+WcbV)*3xme@@oEz`qNNE)#PdZKeDo2dN6t1<7c z@NTA&P_W26F`yNld;KQKi=2p#F2(=4rk-BdnneIgrL}9SO`SNz&(X0(En-47paq(3 zLTR~6F^K~B$)J69#FrUWds24(T;MgD2U)={S|8PUKT$9R=M9^nL!VIE;?~x|LL(PX z<)b6kzCKMmJ4yV{cN}(Bi&h+TasQ2qBE&>De^}nxJ{Irb)IL%7{ptNlHGs=V;D;F$=9wV^@7%zH;Co zluvx|;>D%OTCs*X+n$jTNG2$7pndQ-uIC;Lwp#RbLzxd{>FJ^v-n{BxF}v_C^!n_Y z95b_8(UAB#6XOCf+X{+In%?F=#1?IA;$NGLhMcW(jkOM&J9f7+I6Gc;scQNzXI2ES z^}X|d+=Xg_W@W!V7YW5kz|!>Ny>&DX?7@CJ`yiSVu_ijKwy-^yZB-`wxQ$vqs zs(iY-?zjEA_zl`^L(5U%u{dck?!Jcj;`#FngUt(I2ov9Pe>f|`e*70L|5 zoIjQJw4j7*Q>|u!N{X3z?R&Bo{$-Aym=p`lU|E6AEXhab%h&Sgu2Hhke)&rP-MhD+oGIwycp!;H4w8!Oj@e9m zq@k6>=8o^W^NLd#RmXY^Hm?fk(1_UV3O32E&~ThMYcR#XZ?d2XICWTEn{OdF!yl7d`^m2Vg@DYO=nIh*xe$C!qiM2n9GZoIDdPEyuZ8P zIiyH$=soIjxWpIj*lrTUG6@iC%=a~!5a?t9&;h_Ijiel(pvj#SvK+J_@k@88PtL_? z$TejiJ~w4touTu_I^n%9UA!Uxaj8K6;l@5SjOw@FQqY(g$FIk{T@a^TWlDX&-k^)BIpQX0l})5QsT6s!_Qm>>HZ}Tiw5?1-;hGt5xQdK;L}Hg( zHvP4WH=fW(L@m@MJ=#_;Jn$v>R^W5-qJA7t_(#!%_@MN3XmNF-(QeC0&r}SqTrtTN zT!2aY6(yy(4mlw{ekgRgt&i?Pu_Z#99t3-#;cvPn$@Kq;>g2p@sWb$gcZjIiKn`@| zmD@?pK(}IqU2F=tw98Gez_FA`Kg*3PFZj)N?Cpeo#84D_#`>82Vt3WKbHJE_pzn#j zuGf*JBr+mNc$tMr$@7atC&f|di%1(`=10reh{Q580~E2QEGF|@!}FREgH2tb@ZgEl zr*||XGL1gUg!$f6W4>|{k+kU-?WE5_cFDB&^luI>YKQ zm5(qJ_QH9St9MrD6Lez}>pGb}6)NzHJySFv@Sq^gQrLJ{YR7;X<< z?v=n!xMctpY|>{_MxxA8RK(-wUD!>;yIzv5PH-_?R2^(fpJ-3S%#Mj6#|v?4@kZ|j zq(6#KX|TH8#lPMO>@qY2Mgdb#RbHY(l(fW#Xcyi6*)_)Kwno$N`RNI36vKY`{*GG~ zPV)PnZ>HS&_S6e)b_7lUP*>V<(UHe$%V=c17moGChL%T@q3PyvEPkwJob0eK4vK&)xc0F5Z+1X0BXi16IuEbI*Ve>K#^9jM(Tm&28KtAU+ z0^;u2RKED-ae>vnbq0?NF;hCsovi5ZZXak`93J|Z2*!8aC*?&MCMu1OJgoW za;>UCi&@Fp{93Jm&mJz@3!ReHiAd^VDiQ3O!`5r?j|HCVTC){SYRJ^H7dlFsv@@r|vJ9c(QggIaa22jD> z3B}qq)}3uLq-^(w>0b3nqttE%+`S)$+Ysu5WnOSkso309xF&&yOxb zPo9w+P3%u+h1`t&$)Qs7+pYTvDi0k6j2^%i!+LjRM$qM3IOFn94|sYOJGrk=nV%5U z)enc9-Pm}?{-I^Q@w)w~cTfM|;!Llo7&ai&9(4<<6LO44`S)k}pRovtiAmC@d=qya zU@BRLg{lh;~uN?Rh6cX9oOlgZT-t~wRgLxf$^u%KGfWSn28FXIEyASihwwtR9JI23BUtGC-oPzqA+Z#?Us)NS~+Jwaci zVM~I(Kyhtxoj+g;!Qh8cVOzsDGq(RO`I$uthJJG`B|3Jze6uc| zV>2JBrhD54F6xuQC-(}n%?Pbp=XW4=iH}FC&lg+ALc7XA`FOkoejqzC?S-2Q5VmjK z8XqlH5P#rPGdq9+vX+UsxI!pR@032_Nh10+1@BG8#I^6)stTo+*)FT^`Z9$`%jgMr zR~Qobx*fir3CYYf?4|)?UtUd(oc^E1Hu3FmFI8R!nM6f|W&e%sR%m9-aXj1epQNHj zAMVQkLe?>sP>6;GJt09sEM*>pOASjDe{i#== zC+HT%hFExD9MA+x7Dj&FLmbg713&x|a7Q|Mx}_fO%#3p1A*rB3%%(LbE?!qBBPMo^ zkX?I8WB9}TV!6$vE|>G?FUm|V34+;3>Liy!G@sKx$Jl2jK&r+8;&8Q}ko(FyW+6hsYj%-D#4f3d5gY+d4e zeH~bguaNds*o?`{%#^%(b=l8=*UmNL(Q8D{<8pcu)*sU5(bD4SYE*do)^upaG zoCRA0k)br@rv|t4mI{@Jk2Q!+HwDxOB&=Kz4PaZD&bzraLJC}TzxdKs5-79_JEjee zXx_K~1Po|1{6#c#3RzH$IJhpz;{tbd@kRGQ_PY^l)14ayul~|7P2C;z^`B;ce4wi( zGA)%9WZM%y`Q@;=;k_2g0j0Adqc$)gH{Fl0WI8IYm6EyN)w6Y8ooqtQyNPX8D^s;a z7W3u=>3_W z$q8y6y@TN3F;_qK#ecNMt+h~RxfN+d3B}s0=HK_@Vbjxdk8+BQwT|aqfjV9kG?bDT z5PDD`y`3pUDeGz zoA*A^5Q;qM3{3Kz+iQFftKExD7(JVbF04*3yC`OR{9`KahrkGSibB-EX>7=x;$R1L zl2l|F>Cj5_*p!iyhC{coKFdV*65)SgNHuItH`eB}F$Yo$JOe?(#=2L5fni>IvBZqR zFV%gaut0YHfHm`UuBWq2W4Zqu4eJnZ_{W)x=T6y7r>~1w_@K4=>FeK#!TI;0d;Se) zKK7|{wf_Cyjk6EmU)a~1LnnXBGAiC0?wETmO9mj|Z)vAfcRvewR)5KzqMB}m$H9UB zo5O{x6C;?a2>?@lwabasyq>uaC)#qSfwnkj0-l_rqzs=C!<~ughu{5^@sxA+KZpNk gPW~S)h~cZAvA3ftR6Y;GLOb(BLP0$5k^bxd0P=9=umAu6 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore-groupby.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore-groupby.png deleted file mode 100644 index 4f313af850d07cd40d037e32af1789ef07c2e3e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72408 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

      f{CYVyDcJ5_&Gh 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 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore-poddetail.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore-poddetail.png deleted file mode 100644 index ddcf6918c702fe9aec6a78049d5d30140989baa5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52998 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�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

    1. miy5%j3@+HJOKM>S`=2TWDI-0B zvWD90l@_4OtTB5-^R16Y^Q(xqR~irv+{|lBqj%91MM}H2ad!Pq)RyaiBeyx2XekG z-)E%{#9P!(*s3s2nHH)lzsT6wFPF1$*16$M(P{C5pv``$K(Twl26wMJOGYU}S$~r99=WkszbJ#w zd4j!nuJKzQ1W^3A)#sWn%5r;F#i#$eJ6ORJzf_jcS00x*36H$&2vbGcDCt6E=a#^Om6R+ zOqKGks|8L1F=Qh=-(HoUNyzb{f~v%LNkT*ws9m38gG5?}9EDca5M^U99^fEQmPSj- zM(L_-BQVX!+mQRf89Q^F&NRNF?)ghk1C}FM(>37{JHPpR6-1DsE@LG=t>dZ5(;`WF zgsjA3^|Nm%KWcatTEoRpqhUq^XxCc)wz*|zwPO|+JFf%7ME|;%vBP*Ni)X}6O0`Q$ zo)+#QuqkJB<62SB0#A+a$F%kxJE_74o6kV3L$~oIrWl3fgvv||9$Fw!AOa{62eh6y zy84544d^z_OZnA&v$H|W%i%pEr_Aw9DyKLo5!b35`_$g9cu9cZ?12?!6@TelYiVl5 zRB{q>XAVIp+jq8gr|g*zq~%Xv1j!f$)B=-AI}Wj0-J3RA6F16gM~=oZLETUil8~7c z6>HPG*ssDTVg7olIo zE}9Wmrpkr8@vv@e30?5qkGh&0^>7MP&e}_Lgd>SeJOp$$fAqP04eeOt&;Qg1U1{e? zoXejS_Wq8QxM3#oaNAQJ2lhJoo$Wh)doV;?qIu?ZdWq$cfOax7Pk9JkS^gO@&%+0+ z#cXfWB|_0RJHJRPngeqfjO!TJ7>YEc_qloR?{gTl+qyCK7jG`eNVGD2SMY|^3vDI* zUaPfoAt^A!vqHcE`B$G{(F!-+`@f{-iIFF|K)ZfY#8c+TlCTsWN_6>7YSPjh8t4=3(yl?)9s2edN zfwOeDpW=C5&C3XGn%$G5B_jB;;w6Bp!TiS;I2uTKuK_(S=f+1VHo5e#!h0K0udbe! zp$yZFVjYt8MHm!d(9!~lxCbERPHmGSahFF6ml1t$@nEx@XN%MJTsl};#!=B5>c82` z67s)*J>_n}1oJkFYP?x_snI&~7dpmU|MFyHbobfTnWaI<@UH ztRv2AW4iqKuw7L1a%vyN{)fc!exh)@PiC=!vD5tiRflPsOpu1n(ftCe+4N5AYvgGu zbB?RZ20wi12p!nNh69r!>?^^WJ`;pjGji-N-D=an2aJufYS;0n_8s5B(6AJYy0l`r zztLI_(A?N!w`%?~)n`18 zpj7!BlnJIWJHQ1hauEzZeR^07zycc+T@Igf_MuJIR@mar){SrYnwbDrSZ!n z`aeE2`sO2+st=ecdx^=cMa<8Ml-nT8BB8(Dml%#ugPZcvmL^)gweJbfS3Rvtr6kLM zUbwjZJkL%5UY$-vbMEu8Y}kU z+M>f69e5`vKMC#em^1mxpe``|!Cq=r)KJKi@4Nzo1eSWB9|F=6p%D~i;?Ac}4%(2( zicL4ywRP;UZ5fywk4{*=S$%MmsZ&aD>fUa-shb^IKSgr;8)i3?vX-|~$vs$U%?Trb zOtmq}TE7IlgUE-qWQ&UCSYZ)<6*M`iW!}H-LG`q4y?bcAa-CUDn&at9q?c7%)R15U z14-^!&b0gb77x((XB|_FIuc7HtN5jTWIqKe#D=fDi)AsM8#qmV-)XGN?E|`6!Opp0za8(rU@V{Dd oNdJ3Ev}gRk2S@+!-r5x|s^Y0Yw#YaGNOO>^q>@C1nBnLD2ZJ=n2mk;8 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-explore.png deleted file mode 100644 index cd6b8b7bf5deae9738db82d335df412302a45ea9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68948 zcmdRVXH-*L*Dh96nkXFs4N{~E(yIzc2k9M@-chR5h$vM+q;~~E525$oi*!PV&^rk& z1PJAB--G8p?~gmi9d~^98{b_&a3|S&l{ugJ%xBHD4SKC4O>l?m4h{|ufvk+ADh>|r zQyiSD^|!79-@Npp8v_2h=JZll{no8pQ}fDmz(-1FDQ#yp2Xkk)w~l5w7WNKyX6#NT zj%H@|PL>YNsA~;kI5-b+WF=pye@NPzaraWwIO*73Wwc5_uGbfp+Oj9Azx}}?^S<@T z9aWXtWX-Pp^~Id6YEWQc$plEpQRng&0ao=@kKe}l-QE=q zBthPD(%cow1_uT%t-yUs>bBTsZv6EtP9Hs0mH=s1V4Cx2U`~2M(Z2#<%y=c(nbH{Fq#d$v4Ml8 zlUgFaB{-blW$TYI=Cq)8zP7NV#;jFB`{mqmawOsH9hF{veRqGc!ABeMCRg=~wzfJd zmRI2ASlP>A=CqXHCk5v|2~x@oV?5U890f^e>t)VS=Im#}KJS0s^AkNYSgd5~3C>Lp zNs$W+-myCK`t#`NkpFYnUvPsnZ{BdWXQjpZwna@T2BtQO{rCL5R~F>5(ozIC>e2g` z_WZaXl8H8mJPFwPWhG*uIKFb~9VNzPNRPX5)l1#z!jdDW{9-}F#eB8kfeoy(akL-z za-cp=yIZEX1h)(-W+rPP%K5QfTb8utgh)u8O9r@`LCCFV2)9LY>3M{m*{d`EZ33h# zn2v!_a@gzkwl8Sv7uTch4>vEn65uQ?H+`Z0IlKX8u7$kqyVY|4(=66WGF6+Cco(Cx zqCCjy{_t0Hdvy<0CE-2ex}mHMqXzL`2D!2ZaYq9TWba2 zdelAdZ-@HI*Z;D?bLvvQZ;DiRb!{zm?u?dEjuq%{(%=6CELINx(34DyW5zP~nXsO- zUKQj#r7e0ws{FGyOq%g}G{u%$3QWMg2X;-WJmWlBr);i353BzSRGvR{x)f5=!@}{6 zM^p0C)ga@)9R6`%+2-0r%KIx5(z+{I9F(4H1=qlI8VZ5cZ2*?TUIknclXLDI{9eW+ zUBpr2NQGNgVcOJ%OqjMf&?sV9CIA~8NkE!TddM$**Elhft5|n>##6U&b<9WGskDjdgdff>ix7?&-UxnkyLX?*G-uV4EKgETLx)_LDlG!Cq62~ zVvuDTgI;PZ0##qP0Jq-0}f$2l~;)SNUF zLho(8Vl5HX{+Y?~(R8+*c~D_m22U&Xv2divvIB^|#W|F(!`F}3hM%TSP<>N~`u;lB z_@odB(HwQTjcg93to`)RfQpOPyWPXF;8HH}hC+M5HwGrBG=vtK1-oZx_v0@v&Sg7-HQ-ET^5!o(~$INzmWlPRbGRPS!s~o+;kJ}9t9f?SUOb(C<26ZRM?q) zi>^#gLv?m%CagHrh^A;t@0|S);^lSAUY5IgeGA;`vlBU1?|z=#5Wc|jqVTP!U!a2Q zt|zLWmd8SVZKeFcZ`az2KvvrKb5_TuLz>$LX?}!&M4a{Fvqi53R*z2@tZO#KGQhyFt?oe5|

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/known-issues.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Known Issues - -This document summarizes known issues with existing Kubernetes releases. - -Please consult this document before filing new bugs. - -### Release 1.0.1 - - * `exec` liveness/readiness probes leak resources due to Docker exec leaking resources (#10659) - * `docker load` sometimes hangs which causes the `kube-apiserver` not to start. Restarting the Docker daemon should fix the issue (#10868) - * The kubelet on the master node doesn't register with the `kube-apiserver` so statistics aren't collected for master daemons (#10891) - * Heapster and InfluxDB both leak memory (#10653) - * Wrong node cpu/memory limit metrics from Heapster (https://github.com/GoogleCloudPlatform/heapster/issues/399) - * Services that set `type=LoadBalancer` can not use port `10250` because of Google Compute Engine firewall limitations - * Add-on services can not be created or deleted via `kubectl` or the Kubernetes API (#11435) - * If a pod with a GCE PD is created and deleted in rapid succession, it may fail to attach/mount correctly leaving PD data inaccessible (or corrupted in the worst case). (https://k8s.io/kubernetes/issues/11231#issuecomment-122049113) - * Suggested temporary work around: introduce a 1-2 minute delay between deleting and recreating a pod with a PD on the same node. - * Explicit errors while detaching GCE PD could prevent PD from ever being detached (#11321) - * GCE PDs may sometimes fail to attach (#11302) - * If multiple Pods use the same RBD volume in read-write mode, it is possible data on the RBD volume could get corrupted. This problem has been found in environments where both apiserver and etcd rebooted and Pods were redistributed. - * A workaround is to ensure there is no other Ceph client using the RBD volume before mapping RBD image in read-write mode. For example, `rados -p poolname listwatchers image_name.rbd` can list RBD clients that are mapping the image. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/known-issues.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubeconfig-file.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubeconfig-file.md deleted file mode 100644 index 4222b7f2892a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubeconfig-file.md +++ /dev/null @@ -1,197 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubeconfig-file.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# kubeconfig files - -In order to easily switch between multiple clusters, a kubeconfig file was defined. This file contains a series of authentication mechanisms and cluster connection information associated with nicknames. It also introduces the concept of a tuple of authentication information (user) and cluster connection information called a context that is also associated with a nickname. - -Multiple kubeconfig files are allowed. At runtime they are loaded and merged together along with override options specified from the command line (see rules below). - -## Related discussion - -https://k8s.io/kubernetes/issues/1755 - -## Example kubeconfig file - -```yaml -apiVersion: v1 -clusters: -- cluster: - api-version: v1 - server: http://cow.org:8080 - name: cow-cluster -- cluster: - certificate-authority: path/to/my/cafile - server: https://horse.org:4443 - name: horse-cluster -- cluster: - insecure-skip-tls-verify: true - server: https://pig.org:443 - name: pig-cluster -contexts: -- context: - cluster: horse-cluster - namespace: chisel-ns - user: green-user - name: federal-context -- context: - cluster: pig-cluster - namespace: saw-ns - user: black-user - name: queen-anne-context -current-context: federal-context -kind: Config -preferences: - colors: true -users: -- name: blue-user - user: - token: blue-token -- name: green-user - user: - client-certificate: path/to/my/client/cert - client-key: path/to/my/client/key -``` - -## Loading and merging rules - -The rules for loading and merging the kubeconfig files are straightforward, but there are a lot of them. The final config is built in this order: - 1. Get the kubeconfig from disk. This is done with the following hierarchy and merge rules: - - - If the CommandLineLocation (the value of the `kubeconfig` command line option) is set, use this file only. No merging. Only one instance of this flag is allowed. - - - Else, if EnvVarLocation (the value of $KUBECONFIG) is available, use it as a list of files that should be merged. - Merge files together based on the following rules. - Empty filenames are ignored. Files with non-deserializable content produced errors. - The first file to set a particular value or map key wins and the value or map key is never changed. - This means that the first file to set CurrentContext will have its context preserved. It also means that if two files specify a "red-user", only values from the first file's red-user are used. Even non-conflicting entries from the second file's "red-user" are discarded. - - - Otherwise, use HomeDirectoryLocation (~/.kube/config) with no merging. - 1. Determine the context to use based on the first hit in this chain - 1. command line argument - the value of the `context` command line option - 1. current-context from the merged kubeconfig file - 1. Empty is allowed at this stage - 1. Determine the cluster info and user to use. At this point, we may or may not have a context. They are built based on the first hit in this chain. (run it twice, once for user, once for cluster) - 1. command line argument - `user` for user name and `cluster` for cluster name - 1. If context is present, then use the context's value - 1. Empty is allowed - 1. Determine the actual cluster info to use. At this point, we may or may not have a cluster info. Build each piece of the cluster info based on the chain (first hit wins): - 1. command line arguments - `server`, `api-version`, `certificate-authority`, and `insecure-skip-tls-verify` - 1. If cluster info is present and a value for the attribute is present, use it. - 1. If you don't have a server location, error. - 1. Determine the actual user info to use. User is built using the same rules as cluster info, EXCEPT that you can only have one authentication technique per user. - 1. Load precedence is 1) command line flag, 2) user fields from kubeconfig - 1. The command line flags are: `client-certificate`, `client-key`, `username`, `password`, and `token`. - 1. If there are two conflicting techniques, fail. - 1. For any information still missing, use default values and potentially prompt for authentication information - -## Manipulation of kubeconfig via `kubectl config ` - -In order to more easily manipulate kubeconfig files, there are a series of subcommands to `kubectl config` to help. -See [kubectl/kubectl_config.md](kubectl/kubectl_config.md) for help. - -### Example - -```console -$ kubectl config set-credentials myself --username=admin --password=secret -$ kubectl config set-cluster local-server --server=http://localhost:8080 -$ kubectl config set-context default-context --cluster=local-server --user=myself -$ kubectl config use-context default-context -$ kubectl config set contexts.default-context.namespace the-right-prefix -$ kubectl config view -``` - -produces this output - -```yaml -clusters: - local-server: - server: http://localhost:8080 -contexts: - default-context: - cluster: local-server - namespace: the-right-prefix - user: myself -current-context: default-context -preferences: {} -users: - myself: - username: admin - password: secret -``` - -and a kubeconfig file that looks like this - -```yaml -apiVersion: v1 -clusters: -- cluster: - server: http://localhost:8080 - name: local-server -contexts: -- context: - cluster: local-server - namespace: the-right-prefix - user: myself - name: default-context -current-context: default-context -kind: Config -preferences: {} -users: -- name: myself - user: - username: admin - password: secret -``` - -#### Commands for the example file - -```console -$ kubectl config set preferences.colors true -$ kubectl config set-cluster cow-cluster --server=http://cow.org:8080 --api-version=v1 -$ kubectl config set-cluster horse-cluster --server=https://horse.org:4443 --certificate-authority=path/to/my/cafile -$ kubectl config set-cluster pig-cluster --server=https://pig.org:443 --insecure-skip-tls-verify=true -$ kubectl config set-credentials blue-user --token=blue-token -$ kubectl config set-credentials green-user --client-certificate=path/to/my/client/cert --client-key=path/to/my/client/key -$ kubectl config set-context queen-anne-context --cluster=pig-cluster --user=black-user --namespace=saw-ns -$ kubectl config set-context federal-context --cluster=horse-cluster --user=green-user --namespace=chisel-ns -$ kubectl config use-context federal-context -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubeconfig-file.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/.files_generated b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/.files_generated deleted file mode 100644 index 73e9a3457786..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/.files_generated +++ /dev/null @@ -1,30 +0,0 @@ -kubectl.md -kubectl_api-versions.md -kubectl_attach.md -kubectl_cluster-info.md -kubectl_config.md -kubectl_config_set-cluster.md -kubectl_config_set-context.md -kubectl_config_set-credentials.md -kubectl_config_set.md -kubectl_config_unset.md -kubectl_config_use-context.md -kubectl_config_view.md -kubectl_create.md -kubectl_delete.md -kubectl_describe.md -kubectl_exec.md -kubectl_expose.md -kubectl_get.md -kubectl_label.md -kubectl_logs.md -kubectl_namespace.md -kubectl_patch.md -kubectl_port-forward.md -kubectl_proxy.md -kubectl_replace.md -kubectl_rolling-update.md -kubectl_run.md -kubectl_scale.md -kubectl_stop.md -kubectl_version.md diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl.md deleted file mode 100644 index 2e94f472efc4..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl.md +++ /dev/null @@ -1,108 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl - -kubectl controls the Kubernetes cluster manager - -### Synopsis - - -kubectl controls the Kubernetes cluster manager. - -Find more information at https://k8s.io/kubernetes. - -``` -kubectl -``` - -### Options - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - -h, --help=false: help for kubectl - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl api-versions](kubectl_api-versions.md) - Print available API versions. -* [kubectl attach](kubectl_attach.md) - Attach to a running container. -* [kubectl cluster-info](kubectl_cluster-info.md) - Display cluster info -* [kubectl config](kubectl_config.md) - config modifies kubeconfig files -* [kubectl create](kubectl_create.md) - Create a resource by filename or stdin -* [kubectl delete](kubectl_delete.md) - Delete resources by filenames, stdin, resources and names, or by resources and label selector. -* [kubectl describe](kubectl_describe.md) - Show details of a specific resource or group of resources -* [kubectl exec](kubectl_exec.md) - Execute a command in a container. -* [kubectl expose](kubectl_expose.md) - Take a replicated application and expose it as Kubernetes Service -* [kubectl get](kubectl_get.md) - Display one or many resources -* [kubectl label](kubectl_label.md) - Update the labels on a resource -* [kubectl logs](kubectl_logs.md) - Print the logs for a container in a pod. -* [kubectl namespace](kubectl_namespace.md) - SUPERCEDED: Set and view the current Kubernetes namespace -* [kubectl patch](kubectl_patch.md) - Update field(s) of a resource by stdin. -* [kubectl port-forward](kubectl_port-forward.md) - Forward one or more local ports to a pod. -* [kubectl proxy](kubectl_proxy.md) - Run a proxy to the Kubernetes API server -* [kubectl replace](kubectl_replace.md) - Replace a resource by filename or stdin. -* [kubectl rolling-update](kubectl_rolling-update.md) - Perform a rolling update of the given ReplicationController. -* [kubectl run](kubectl_run.md) - Run a particular image on the cluster. -* [kubectl scale](kubectl_scale.md) - Set a new size for a Replication Controller. -* [kubectl stop](kubectl_stop.md) - Deprecated: Gracefully shut down a resource by name or filename. -* [kubectl version](kubectl_version.md) - Print the client and server version information. - -###### Auto generated by spf13/cobra at 2015-08-03 05:57:27.777459508 +0000 UTC - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_api-versions.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_api-versions.md deleted file mode 100644 index aa151bb4e1ad..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_api-versions.md +++ /dev/null @@ -1,91 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_api-versions.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl api-versions - -Print available API versions. - -### Synopsis - - -Print available API versions. - -``` -kubectl api-versions -``` - -### Options - -``` - -h, --help=false: help for api-versions -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.959722426 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_api-versions.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_attach.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_attach.md deleted file mode 100644 index a1e51cc63868..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_attach.md +++ /dev/null @@ -1,108 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_attach.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl attach - -Attach to a running container. - -### Synopsis - - -Attach to a a process that is already running inside an existing container. - -``` -kubectl attach POD -c CONTAINER -``` - -### Examples - -``` -// get output from running pod 123456-7890, using the first container by default -$ kubectl attach 123456-7890 - -// get output from ruby-container from pod 123456-7890 -$ kubectl attach 123456-7890 -c ruby-container date - -// switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-780 -// and sends stdout/stderr from 'bash' back to the client -$ kubectl attach 123456-7890 -c ruby-container -i -t -``` - -### Options - -``` - -c, --container="": Container name - -h, --help=false: help for attach - -i, --stdin=false: Pass stdin to the container - -t, --tty=false: Stdin is a TTY -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-30 17:45:25.860905122 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_attach.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_cluster-info.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_cluster-info.md deleted file mode 100644 index fc228f9ab2f4..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_cluster-info.md +++ /dev/null @@ -1,91 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_cluster-info.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl cluster-info - -Display cluster info - -### Synopsis - - -Display addresses of the master and services with label kubernetes.io/cluster-service=true - -``` -kubectl cluster-info -``` - -### Options - -``` - -h, --help=false: help for cluster-info -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.959601452 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_cluster-info.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config.md deleted file mode 100644 index 7f6b79d75673..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config.md +++ /dev/null @@ -1,104 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_config.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl config - -config modifies kubeconfig files - -### Synopsis - - -config modifies kubeconfig files using subcommands like "kubectl config set current-context my-context" - -The loading order follows these rules: - 1. If the --kubeconfig flag is set, then only that file is loaded. The flag may only be set once and no merging takes place. - 2. If $KUBECONFIG environment variable is set, then it is used a list of paths (normal path delimitting rules for your system). These paths are merged together. When a value is modified, it is modified in the file that defines the stanza. When a value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the last file in the list. - 3. Otherwise, ${HOME}/.kube/config is used and no merging takes place. - - -``` -kubectl config SUBCOMMAND -``` - -### Options - -``` - -h, --help=false: help for config - --kubeconfig="": use a particular kubeconfig file -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -* [kubectl config set](kubectl_config_set.md) - Sets an individual value in a kubeconfig file -* [kubectl config set-cluster](kubectl_config_set-cluster.md) - Sets a cluster entry in kubeconfig -* [kubectl config set-context](kubectl_config_set-context.md) - Sets a context entry in kubeconfig -* [kubectl config set-credentials](kubectl_config_set-credentials.md) - Sets a user entry in kubeconfig -* [kubectl config unset](kubectl_config_unset.md) - Unsets an individual value in a kubeconfig file -* [kubectl config use-context](kubectl_config_use-context.md) - Sets the current-context in a kubeconfig file -* [kubectl config view](kubectl_config_view.md) - displays Merged kubeconfig settings or a specified kubeconfig file. - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.959458886 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_config.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-cluster.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-cluster.md deleted file mode 100644 index 9fc7cbc31dc9..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-cluster.md +++ /dev/null @@ -1,106 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_config_set-cluster.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl config set-cluster - -Sets a cluster entry in kubeconfig - -### Synopsis - - -Sets a cluster entry in kubeconfig. -Specifying a name that already exists will merge new fields on top of existing values for those fields. - -``` -kubectl config set-cluster NAME [--server=server] [--certificate-authority=path/to/certficate/authority] [--api-version=apiversion] [--insecure-skip-tls-verify=true] -``` - -### Examples - -``` -// Set only the server field on the e2e cluster entry without touching other values. -$ kubectl config set-cluster e2e --server=https://1.2.3.4 - -// Embed certificate authority data for the e2e cluster entry -$ kubectl config set-cluster e2e --certificate-authority=~/.kube/e2e/kubernetes.ca.crt - -// Disable cert checking for the dev cluster entry -$ kubectl config set-cluster e2e --insecure-skip-tls-verify=true -``` - -### Options - -``` - --api-version=: api-version for the cluster entry in kubeconfig - --certificate-authority=: path to certificate-authority for the cluster entry in kubeconfig - --embed-certs=false: embed-certs for the cluster entry in kubeconfig - -h, --help=false: help for set-cluster - --insecure-skip-tls-verify=false: insecure-skip-tls-verify for the cluster entry in kubeconfig - --server=: server for the cluster entry in kubeconfig -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --kubeconfig="": use a particular kubeconfig file - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl config](kubectl_config.md) - config modifies kubeconfig files - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.95861887 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_config_set-cluster.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-context.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-context.md deleted file mode 100644 index cc53b6c7c5e8..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-context.md +++ /dev/null @@ -1,99 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_config_set-context.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl config set-context - -Sets a context entry in kubeconfig - -### Synopsis - - -Sets a context entry in kubeconfig -Specifying a name that already exists will merge new fields on top of existing values for those fields. - -``` -kubectl config set-context NAME [--cluster=cluster_nickname] [--user=user_nickname] [--namespace=namespace] -``` - -### Examples - -``` -// Set the user field on the gce context entry without touching other values -$ kubectl config set-context gce --user=cluster-admin -``` - -### Options - -``` - --cluster=: cluster for the context entry in kubeconfig - -h, --help=false: help for set-context - --namespace=: namespace for the context entry in kubeconfig - --user=: user for the context entry in kubeconfig -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": use a particular kubeconfig file - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl config](kubectl_config.md) - config modifies kubeconfig files - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.958911281 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_config_set-context.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-credentials.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-credentials.md deleted file mode 100644 index d8f35c0aff06..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set-credentials.md +++ /dev/null @@ -1,119 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_config_set-credentials.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl config set-credentials - -Sets a user entry in kubeconfig - -### Synopsis - - -Sets a user entry in kubeconfig -Specifying a name that already exists will merge new fields on top of existing values. - - Client-certificate flags: - --client-certificate=certfile --client-key=keyfile - - Bearer token flags: - --token=bearer_token - - Basic auth flags: - --username=basic_user --password=basic_password - - Bearer token and basic auth are mutually exclusive. - - -``` -kubectl config set-credentials NAME [--client-certificate=path/to/certfile] [--client-key=path/to/keyfile] [--token=bearer_token] [--username=basic_user] [--password=basic_password] -``` - -### Examples - -``` -// Set only the "client-key" field on the "cluster-admin" -// entry, without touching other values: -$ kubectl config set-credentials cluster-admin --client-key=~/.kube/admin.key - -// Set basic auth for the "cluster-admin" entry -$ kubectl config set-credentials cluster-admin --username=admin --password=uXFGweU9l35qcif - -// Embed client certificate data in the "cluster-admin" entry -$ kubectl config set-credentials cluster-admin --client-certificate=~/.kube/admin.crt --embed-certs=true -``` - -### Options - -``` - --client-certificate=: path to client-certificate for the user entry in kubeconfig - --client-key=: path to client-key for the user entry in kubeconfig - --embed-certs=false: embed client cert/key for the user entry in kubeconfig - -h, --help=false: help for set-credentials - --password=: password for the user entry in kubeconfig - --token=: token for the user entry in kubeconfig - --username=: username for the user entry in kubeconfig -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": use a particular kubeconfig file - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --user="": The name of the kubeconfig user to use - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl config](kubectl_config.md) - config modifies kubeconfig files - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.958785654 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_config_set-credentials.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set.md deleted file mode 100644 index aabd2e6011fa..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_set.md +++ /dev/null @@ -1,93 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_config_set.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl config set - -Sets an individual value in a kubeconfig file - -### Synopsis - - -Sets an individual value in a kubeconfig file -PROPERTY_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots. -PROPERTY_VALUE is the new value you wish to set. - -``` -kubectl config set PROPERTY_NAME PROPERTY_VALUE -``` - -### Options - -``` - -h, --help=false: help for set -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": use a particular kubeconfig file - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl config](kubectl_config.md) - config modifies kubeconfig files - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.959031072 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_config_set.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_unset.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_unset.md deleted file mode 100644 index 80d0430691be..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_unset.md +++ /dev/null @@ -1,92 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_config_unset.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl config unset - -Unsets an individual value in a kubeconfig file - -### Synopsis - - -Unsets an individual value in a kubeconfig file -PROPERTY_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots. - -``` -kubectl config unset PROPERTY_NAME -``` - -### Options - -``` - -h, --help=false: help for unset -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": use a particular kubeconfig file - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl config](kubectl_config.md) - config modifies kubeconfig files - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.959148086 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_config_unset.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_use-context.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_use-context.md deleted file mode 100644 index 292045ae77f1..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_use-context.md +++ /dev/null @@ -1,91 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_config_use-context.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl config use-context - -Sets the current-context in a kubeconfig file - -### Synopsis - - -Sets the current-context in a kubeconfig file - -``` -kubectl config use-context CONTEXT_NAME -``` - -### Options - -``` - -h, --help=false: help for use-context -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": use a particular kubeconfig file - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl config](kubectl_config.md) - config modifies kubeconfig files - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.959263442 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_config_use-context.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_view.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_view.md deleted file mode 100644 index 611310a20961..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_config_view.md +++ /dev/null @@ -1,111 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_config_view.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl config view - -displays Merged kubeconfig settings or a specified kubeconfig file. - -### Synopsis - - -displays Merged kubeconfig settings or a specified kubeconfig file. - -You can use --output=template --template=TEMPLATE to extract specific values. - -``` -kubectl config view -``` - -### Examples - -``` -// Show Merged kubeconfig settings. -$ kubectl config view - -// Get the password for the e2e user -$ kubectl config view -o template --template='{{range .users}}{{ if eq .name "e2e" }}{{ index .user.password }}{{end}}{{end}}' -``` - -### Options - -``` - --flatten=false: flatten the resulting kubeconfig file into self contained output (useful for creating portable kubeconfig files) - -h, --help=false: help for view - --merge=true: merge together the full hierarchy of kubeconfig files - --minify=false: remove all information not used by current-context from the output - --no-headers=false: When using the default output, don't print headers. - -o, --output="": Output format. One of: json|yaml|template|templatefile|wide. - --output-version="": Output the formatted object with the given version (default api-version). - --raw=false: display raw byte data - -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview] -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": use a particular kubeconfig file - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl config](kubectl_config.md) - config modifies kubeconfig files - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.958490153 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_config_view.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_create.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_create.md deleted file mode 100644 index ecff815d9bc6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_create.md +++ /dev/null @@ -1,105 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_create.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl create - -Create a resource by filename or stdin - -### Synopsis - - -Create a resource by filename or stdin. - -JSON and YAML formats are accepted. - -``` -kubectl create -f FILENAME -``` - -### Examples - -``` -// Create a pod using the data in pod.json. -$ kubectl create -f ./pod.json - -// Create a pod based on the JSON passed into stdin. -$ cat pod.json | kubectl create -f - -``` - -### Options - -``` - -f, --filename=[]: Filename, directory, or URL to file to use to create the resource - -h, --help=false: help for create - -o, --output="": Output mode. Use "-o name" for shorter output (resource/name). -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-16 22:39:16.132575015 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_create.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_delete.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_delete.md deleted file mode 100644 index dd8762039dae..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_delete.md +++ /dev/null @@ -1,126 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_delete.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl delete - -Delete resources by filenames, stdin, resources and names, or by resources and label selector. - -### Synopsis - - -Delete resources by filenames, stdin, resources and names, or by resources and label selector. - -JSON and YAML formats are accepted. - -Only one type of the arguments may be specified: filenames, resources and names, or resources and label selector - -Note that the delete command does NOT do resource version checks, so if someone -submits an update to a resource right when you submit a delete, their update -will be lost along with the rest of the resource. - -``` -kubectl delete ([-f FILENAME] | (RESOURCE [(NAME | -l label | --all)] -``` - -### Examples - -``` -// Delete a pod using the type and name specified in pod.json. -$ kubectl delete -f ./pod.json - -// Delete a pod based on the type and name in the JSON passed into stdin. -$ cat pod.json | kubectl delete -f - - -// Delete pods and services with label name=myLabel. -$ kubectl delete pods,services -l name=myLabel - -// Delete a pod with UID 1234-56-7890-234234-456456. -$ kubectl delete pod 1234-56-7890-234234-456456 - -// Delete all pods -$ kubectl delete pods --all -``` - -### Options - -``` - --all=false: [-all] to select all the specified resources. - --cascade=true: If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true. - -f, --filename=[]: Filename, directory, or URL to a file containing the resource to delete. - --grace-period=-1: Period of time in seconds given to the resource to terminate gracefully. Ignored if negative. - -h, --help=false: help for delete - --ignore-not-found=false: Treat "resource not found" as a successful delete. Defaults to "true" when --all is specified. - -o, --output="": Output mode. Use "-o name" for shorter output (resource/name). - -l, --selector="": Selector (label query) to filter on. - --timeout=0: The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-31 02:09:06.816515226 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_delete.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_describe.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_describe.md deleted file mode 100644 index 054e375d02bb..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_describe.md +++ /dev/null @@ -1,122 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_describe.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl describe - -Show details of a specific resource or group of resources - -### Synopsis - - -Show details of a specific resource or group of resources. - -This command joins many API calls together to form a detailed description of a -given resource or group of resources. - -$ kubectl describe RESOURCE NAME_PREFIX - -will first check for an exact match on RESOURCE and NAME_PREFIX. If no such resource -exists, it will output details for every resource that has a name prefixed with NAME_PREFIX - -Possible resources include (case insensitive): pods (po), services (svc), -replicationcontrollers (rc), nodes (no), events (ev), limitranges (limits), -persistentvolumes (pv), persistentvolumeclaims (pvc), resourcequotas (quota), -namespaces (ns) or secrets. - -``` -kubectl describe (RESOURCE NAME_PREFIX | RESOURCE/NAME) -``` - -### Examples - -``` -// Describe a node -$ kubectl describe nodes kubernetes-minion-emt8.c.myproject.internal - -// Describe a pod -$ kubectl describe pods/nginx - -// Describe pods by label name=myLabel -$ kubectl describe po -l name=myLabel - -// Describe all pods managed by the 'frontend' replication controller (rc-created pods -// get the name of the rc as a prefix in the pod the name). -$ kubectl describe pods frontend -``` - -### Options - -``` - -h, --help=false: help for describe - -l, --selector="": Selector (label query) to filter on -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-31 07:12:36.111698336 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_describe.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_exec.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_exec.md deleted file mode 100644 index 9fc3fff907a6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_exec.md +++ /dev/null @@ -1,109 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_exec.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl exec - -Execute a command in a container. - -### Synopsis - - -Execute a command in a container. - -``` -kubectl exec POD -c CONTAINER -- COMMAND [args...] -``` - -### Examples - -``` -// get output from running 'date' from pod 123456-7890, using the first container by default -$ kubectl exec 123456-7890 date - -// get output from running 'date' in ruby-container from pod 123456-7890 -$ kubectl exec 123456-7890 -c ruby-container date - -// switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-780 -// and sends stdout/stderr from 'bash' back to the client -$ kubectl exec 123456-7890 -c ruby-container -i -t -- bash -il -``` - -### Options - -``` - -c, --container="": Container name - -h, --help=false: help for exec - -p, --pod="": Pod name - -i, --stdin=false: Pass stdin to the container - -t, --tty=false: Stdin is a TTY -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.956874128 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_exec.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_expose.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_expose.md deleted file mode 100644 index 12377b80fd61..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_expose.md +++ /dev/null @@ -1,125 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_expose.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl expose - -Take a replicated application and expose it as Kubernetes Service - -### Synopsis - - -Take a replicated application and expose it as Kubernetes Service. - -Looks up a replication controller or service by name and uses the selector for that resource as the -selector for a new Service on the specified port. If no labels are specified, the new service will -re-use the labels from the resource it exposes. - -``` -kubectl expose RESOURCE NAME --port=port [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [--public-ip=ip] [--type=type] -``` - -### Examples - -``` -// Creates a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000. -$ kubectl expose rc nginx --port=80 --target-port=8000 - -// Creates a second service based on the above service, exposing the container port 8443 as port 443 with the name "nginx-https" -$ kubectl expose service nginx --port=443 --target-port=8443 --name=nginx-https - -// Create a service for a replicated streaming application on port 4100 balancing UDP traffic and named 'video-stream'. -$ kubectl expose rc streamer --port=4100 --protocol=udp --name=video-stream -``` - -### Options - -``` - --container-port="": Synonym for --target-port - --create-external-load-balancer=false: If true, create an external load balancer for this service (trumped by --type). Implementation is cloud provider dependent. Default is 'false'. - --dry-run=false: If true, only print the object that would be sent, without creating it. - --generator="service/v2": The name of the API generator to use. There are 2 generators: 'service/v1' and 'service/v2'. The only difference between them is that service port in v1 is named 'default', while it is left unnamed in v2. Default is 'service/v2'. - -h, --help=false: help for expose - -l, --labels="": Labels to apply to the service created by this call. - --name="": The name for the newly created object. - --no-headers=false: When using the default output, don't print headers. - -o, --output="": Output format. One of: json|yaml|template|templatefile|wide. - --output-version="": Output the formatted object with the given version (default api-version). - --overrides="": An inline JSON override for the generated object. If this is non-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field. - --port=-1: The port that the service should serve on. Copied from the resource being exposed, if unspecified - --protocol="TCP": The network protocol for the service to be created. Default is 'tcp'. - --public-ip="": Name of a public IP address to set for the service. The service will be assigned this IP in addition to its generated service IP. - --selector="": A label selector to use for this service. If empty (the default) infer the selector from the replication controller. - --target-port="": Name or number for the port on the container that the service should direct traffic to. Optional. - -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview] - --type="": Type for this service: ClusterIP, NodePort, or LoadBalancer. Default is 'ClusterIP' unless --create-external-load-balancer is specified. -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-17 01:17:57.020108348 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_expose.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_get.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_get.md deleted file mode 100644 index eb78c905aac8..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_get.md +++ /dev/null @@ -1,133 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_get.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl get - -Display one or many resources - -### Synopsis - - -Display one or many resources. - -Possible resources include (case insensitive): pods (po), services (svc), -replicationcontrollers (rc), nodes (no), events (ev), componentstatuses (cs), -limitranges (limits), persistentvolumes (pv), persistentvolumeclaims (pvc), -resourcequotas (quota), namespaces (ns), endpoints (ep) or secrets. - -By specifying the output as 'template' and providing a Go template as the value -of the --template flag, you can filter the attributes of the fetched resource(s). - -``` -kubectl get [(-o|--output=)json|yaml|template|wide|...] (RESOURCE [NAME] | RESOURCE/NAME ...) -``` - -### Examples - -``` -// List all pods in ps output format. -$ kubectl get pods - -// List all pods in ps output format with more information (such as node name). -$ kubectl get pods -o wide - -// List a single replication controller with specified NAME in ps output format. -$ kubectl get replicationcontroller web - -// List a single pod in JSON output format. -$ kubectl get -o json pod web-pod-13je7 - -// Return only the phase value of the specified pod. -$ kubectl get -o template web-pod-13je7 --template={{.status.phase}} --api-version=v1 - -// List all replication controllers and services together in ps output format. -$ kubectl get rc,services - -// List one or more resources by their type and names. -$ kubectl get rc/web service/frontend pods/web-pod-13je7 -``` - -### Options - -``` - --all-namespaces=false: If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace. - -h, --help=false: help for get - -L, --label-columns=[]: Accepts a comma separated list of labels that are going to be presented as columns. Names are case-sensitive. You can also use multiple flag statements like -L label1 -L label2... - --no-headers=false: When using the default output, don't print headers. - -o, --output="": Output format. One of: json|yaml|template|templatefile|wide. - --output-version="": Output the formatted object with the given version (default api-version). - -l, --selector="": Selector (label query) to filter on - -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview] - -w, --watch=false: After listing/getting the requested object, watch for changes. - --watch-only=false: Watch for changes to the requested object(s), without listing/getting first. -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-30 08:43:29.371131796 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_get.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_label.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_label.md deleted file mode 100644 index d90884542838..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_label.md +++ /dev/null @@ -1,123 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_label.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl label - -Update the labels on a resource - -### Synopsis - - -Update the labels on a resource. - -A label must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to 63 characters. -If --overwrite is true, then existing labels can be overwritten, otherwise attempting to overwrite a label will result in an error. -If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used. - -``` -kubectl label [--overwrite] RESOURCE NAME KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version] -``` - -### Examples - -``` -// Update pod 'foo' with the label 'unhealthy' and the value 'true'. -$ kubectl label pods foo unhealthy=true - -// Update pod 'foo' with the label 'status' and the value 'unhealthy', overwriting any existing value. -$ kubectl label --overwrite pods foo status=unhealthy - -// Update all pods in the namespace -$ kubectl label pods --all status=unhealthy - -// Update pod 'foo' only if the resource is unchanged from version 1. -$ kubectl label pods foo status=unhealthy --resource-version=1 - -// Update pod 'foo' by removing a label named 'bar' if it exists. -// Does not require the --overwrite flag. -$ kubectl label pods foo bar- -``` - -### Options - -``` - --all=false: select all resources in the namespace of the specified resource types - -h, --help=false: help for label - --no-headers=false: When using the default output, don't print headers. - -o, --output="": Output format. One of: json|yaml|template|templatefile|wide. - --output-version="": Output the formatted object with the given version (default api-version). - --overwrite=false: If true, allow labels to be overwritten, otherwise reject label updates that overwrite existing labels. - --resource-version="": If non-empty, the labels update will only succeed if this is the current resource-version for the object. Only valid when specifying a single resource. - -l, --selector="": Selector (label query) to filter on - -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview] -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.958329854 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_label.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_logs.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_logs.md deleted file mode 100644 index a34354e669b5..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_logs.md +++ /dev/null @@ -1,108 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_logs.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl logs - -Print the logs for a container in a pod. - -### Synopsis - - -Print the logs for a container in a pod. If the pod has only one container, the container name is optional. - -``` -kubectl logs [-f] [-p] POD [-c CONTAINER] -``` - -### Examples - -``` -// Returns snapshot of ruby-container logs from pod 123456-7890. -$ kubectl logs 123456-7890 ruby-container - -// Returns snapshot of previous terminated ruby-container logs from pod 123456-7890. -$ kubectl logs -p 123456-7890 ruby-container - -// Starts streaming of ruby-container logs from pod 123456-7890. -$ kubectl logs -f 123456-7890 ruby-container -``` - -### Options - -``` - -c, --container="": Container name - -f, --follow=false: Specify if the logs should be streamed. - -h, --help=false: help for logs - --interactive=true: If true, prompt the user for input when required. Default true. - -p, --previous=false: If true, print the logs for the previous instance of the container in a pod if it exists. -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.956443079 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_logs.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_namespace.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_namespace.md deleted file mode 100644 index b93d5187ea81..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_namespace.md +++ /dev/null @@ -1,94 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_namespace.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl namespace - -SUPERCEDED: Set and view the current Kubernetes namespace - -### Synopsis - - -SUPERCEDED: Set and view the current Kubernetes namespace scope for command line requests. - -namespace has been superceded by the context.namespace field of .kubeconfig files. See 'kubectl config set-context --help' for more details. - - -``` -kubectl namespace [namespace] -``` - -### Options - -``` - -h, --help=false: help for namespace -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.956297427 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_namespace.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_patch.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_patch.md deleted file mode 100644 index 36f6bd48cb25..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_patch.md +++ /dev/null @@ -1,103 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_patch.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl patch - -Update field(s) of a resource by stdin. - -### Synopsis - - -Update field(s) of a resource using strategic merge patch - -JSON and YAML formats are accepted. - -``` -kubectl patch RESOURCE NAME -p PATCH -``` - -### Examples - -``` - -// Partially update a node using strategic merge patch -kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}' -``` - -### Options - -``` - -h, --help=false: help for patch - -o, --output="": Output mode. Use "-o name" for shorter output (resource/name). - -p, --patch="": The patch to be applied to the resource JSON file. -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.956026887 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_patch.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_port-forward.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_port-forward.md deleted file mode 100644 index b612513566e1..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_port-forward.md +++ /dev/null @@ -1,109 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_port-forward.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl port-forward - -Forward one or more local ports to a pod. - -### Synopsis - - -Forward one or more local ports to a pod. - -``` -kubectl port-forward -p POD_NAME [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N] -``` - -### Examples - -``` - -// listens on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod -$ kubectl port-forward -p mypod 5000 6000 - -// listens on port 8888 locally, forwarding to 5000 in the pod -$ kubectl port-forward -p mypod 8888:5000 - -// listens on a random port locally, forwarding to 5000 in the pod -$ kubectl port-forward -p mypod :5000 - -// listens on a random port locally, forwarding to 5000 in the pod -$ kubectl port-forward -p mypod 0:5000 -``` - -### Options - -``` - -h, --help=false: help for port-forward - -p, --pod="": Pod name -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.957000233 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_port-forward.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_proxy.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_proxy.md deleted file mode 100644 index 60fcb0274c19..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_proxy.md +++ /dev/null @@ -1,130 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_proxy.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl proxy - -Run a proxy to the Kubernetes API server - -### Synopsis - - -To proxy all of the kubernetes api and nothing else, use: - -kubectl proxy --api-prefix=/ - -To proxy only part of the kubernetes api and also some static files: - -kubectl proxy --www=/my/files --www-prefix=/static/ --api-prefix=/api/ - -The above lets you 'curl localhost:8001/api/v1/pods'. - -To proxy the entire kubernetes api at a different root, use: - -kubectl proxy --api-prefix=/custom/ - -The above lets you 'curl localhost:8001/custom/api/v1/pods' - - -``` -kubectl proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix] -``` - -### Examples - -``` -// Run a proxy to kubernetes apiserver on port 8011, serving static content from ./local/www/ -$ kubectl proxy --port=8011 --www=./local/www/ - -// Run a proxy to kubernetes apiserver on an arbitrary local port. -// The chosen port for the server will be output to stdout. -$ kubectl proxy --port=0 - -// Run a proxy to kubernetes apiserver, changing the api prefix to k8s-api -// This makes e.g. the pods api available at localhost:8011/k8s-api/v1/pods/ -$ kubectl proxy --api-prefix=/k8s-api -``` - -### Options - -``` - --accept-hosts="^localhost$,^127\\.0\\.0\\.1$,^\\[::1\\]$": Regular expression for hosts that the proxy should accept. - --accept-paths="^/.*": Regular expression for paths that the proxy should accept. - --api-prefix="/api/": Prefix to serve the proxied API under. - --disable-filter=false: If true, disable request filtering in the proxy. This is dangerous, and can leave you vulnerable to XSRF attacks. Use with caution. - -h, --help=false: help for proxy - -p, --port=8001: The port on which to run the proxy. Set to 0 to pick a random port. - --reject-methods="POST,PUT,PATCH": Regular expression for HTTP methods that the proxy should reject. - --reject-paths="^/api/.*/exec,^/api/.*/run": Regular expression for paths that the proxy should reject. - -w, --www="": Also serve static files from the given directory under the specified prefix. - -P, --www-prefix="/static/": Prefix to serve static files under, if static file directory is specified. -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.957150329 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_proxy.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_replace.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_replace.md deleted file mode 100644 index 296aff64cc50..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_replace.md +++ /dev/null @@ -1,112 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_replace.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl replace - -Replace a resource by filename or stdin. - -### Synopsis - - -Replace a resource by filename or stdin. - -JSON and YAML formats are accepted. - -``` -kubectl replace -f FILENAME -``` - -### Examples - -``` -// Replace a pod using the data in pod.json. -$ kubectl replace -f ./pod.json - -// Replace a pod based on the JSON passed into stdin. -$ cat pod.json | kubectl replace -f - - -// Force replace, delete and then re-create the resource -kubectl replace --force -f ./pod.json -``` - -### Options - -``` - --cascade=false: Only relevant during a force replace. If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true. - -f, --filename=[]: Filename, directory, or URL to file to use to replace the resource. - --force=false: Delete and re-create the specified resource - --grace-period=-1: Only relevant during a force replace. Period of time in seconds given to the old resource to terminate gracefully. Ignored if negative. - -h, --help=false: help for replace - -o, --output="": Output mode. Use "-o name" for shorter output (resource/name). - --timeout=0: Only relevant during a force replace. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-16 22:39:16.132838722 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_replace.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_rolling-update.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_rolling-update.md deleted file mode 100644 index 478313d70cb8..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_rolling-update.md +++ /dev/null @@ -1,125 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_rolling-update.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl rolling-update - -Perform a rolling update of the given ReplicationController. - -### Synopsis - - -Perform a rolling update of the given ReplicationController. - -Replaces the specified replication controller with a new replication controller by updating one pod at a time to use the -new PodTemplate. The new-controller.json must specify the same namespace as the -existing replication controller and overwrite at least one (common) label in its replicaSelector. - -``` -kubectl rolling-update OLD_CONTROLLER_NAME ([NEW_CONTROLLER_NAME] --image=NEW_CONTAINER_IMAGE | -f NEW_CONTROLLER_SPEC) -``` - -### Examples - -``` -// Update pods of frontend-v1 using new replication controller data in frontend-v2.json. -$ kubectl rolling-update frontend-v1 -f frontend-v2.json - -// Update pods of frontend-v1 using JSON data passed into stdin. -$ cat frontend-v2.json | kubectl rolling-update frontend-v1 -f - - -// Update the pods of frontend-v1 to frontend-v2 by just changing the image, and switching the -// name of the replication controller. -$ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 - -// Update the pods of frontend by just changing the image, and keeping the old name -$ kubectl rolling-update frontend --image=image:v2 - -``` - -### Options - -``` - --deployment-label-key="deployment": The key to use to differentiate between two different controllers, default 'deployment'. Only relevant when --image is specified, ignored otherwise - --dry-run=false: If true, print out the changes that would be made, but don't actually make them. - -f, --filename="": Filename or URL to file to use to create the new replication controller. - -h, --help=false: help for rolling-update - --image="": Image to use for upgrading the replication controller. Can not be used with --filename/-f - --no-headers=false: When using the default output, don't print headers. - -o, --output="": Output format. One of: json|yaml|template|templatefile|wide. - --output-version="": Output the formatted object with the given version (default api-version). - --poll-interval="3s": Time delay between polling for replication controller status after the update. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - --rollback=false: If true, this is a request to abort an existing rollout that is partially rolled out. It effectively reverses current and next and runs a rollout - -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview] - --timeout="5m0s": Max time to wait for a replication controller to update before giving up. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - --update-period="1m0s": Time to wait between updating pods. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.956605022 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_rolling-update.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_run.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_run.md deleted file mode 100644 index 5f3a1943b566..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_run.md +++ /dev/null @@ -1,120 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_run.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl run - -Run a particular image on the cluster. - -### Synopsis - - -Create and run a particular image, possibly replicated. -Creates a replication controller to manage the created container(s). - -``` -kubectl run NAME --image=image [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] -``` - -### Examples - -``` -// Starts a single instance of nginx. -$ kubectl run nginx --image=nginx - -// Starts a replicated instance of nginx. -$ kubectl run nginx --image=nginx --replicas=5 - -// Dry run. Print the corresponding API objects without creating them. -$ kubectl run nginx --image=nginx --dry-run - -// Start a single instance of nginx, but overload the spec of the replication controller with a partial set of values parsed from JSON. -$ kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { ... } }' -``` - -### Options - -``` - --dry-run=false: If true, only print the object that would be sent, without sending it. - --generator="run/v1": The name of the API generator to use. Default is 'run-controller/v1'. - -h, --help=false: help for run - --hostport=-1: The host port mapping for the container port. To demonstrate a single-machine container. - --image="": The image for the container to run. - -l, --labels="": Labels to apply to the pod(s). - --no-headers=false: When using the default output, don't print headers. - -o, --output="": Output format. One of: json|yaml|template|templatefile|wide. - --output-version="": Output the formatted object with the given version (default api-version). - --overrides="": An inline JSON override for the generated object. If this is non-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field. - --port=-1: The port that this container exposes. - -r, --replicas=1: Number of replicas to create for this container. Default is 1. - -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview] -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.957298888 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_run.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_scale.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_scale.md deleted file mode 100644 index f0f3644bd34b..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_scale.md +++ /dev/null @@ -1,114 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_scale.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl scale - -Set a new size for a Replication Controller. - -### Synopsis - - -Set a new size for a Replication Controller. - -Scale also allows users to specify one or more preconditions for the scale action. -If --current-replicas or --resource-version is specified, it is validated before the -scale is attempted, and it is guaranteed that the precondition holds true when the -scale is sent to the server. - -``` -kubectl scale [--resource-version=version] [--current-replicas=count] --replicas=COUNT RESOURCE NAME -``` - -### Examples - -``` -// Scale replication controller named 'foo' to 3. -$ kubectl scale --replicas=3 replicationcontrollers foo - -// If the replication controller named foo's current size is 2, scale foo to 3. -$ kubectl scale --current-replicas=2 --replicas=3 replicationcontrollers foo - -// Scale multiple replication controllers. -$ kubectl scale --replicas=5 rc/foo rc/bar -``` - -### Options - -``` - --current-replicas=-1: Precondition for current size. Requires that the current size of the replication controller match this value in order to scale. - -h, --help=false: help for scale - -o, --output="": Output mode. Use "-o name" for shorter output (resource/name). - --replicas=-1: The new desired number of replicas. Required. - --resource-version="": Precondition for resource version. Requires that the current resource version match this value in order to scale. - --timeout=0: The length of time to wait before giving up on a scale operation, zero means don't wait. -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-30 08:50:55.94117889 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_scale.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_stop.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_stop.md deleted file mode 100644 index 9cf203e294df..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_stop.md +++ /dev/null @@ -1,120 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_stop.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl stop - -Deprecated: Gracefully shut down a resource by name or filename. - -### Synopsis - - -Deprecated: Gracefully shut down a resource by name or filename. - -stop command is deprecated, all its functionalities are covered by delete command. -See 'kubectl delete --help' for more details. - -Attempts to shut down and delete a resource that supports graceful termination. -If the resource is scalable it will be scaled to 0 before deletion. - -``` -kubectl stop (-f FILENAME | RESOURCE (NAME | -l label | --all)) -``` - -### Examples - -``` -// Shut down foo. -$ kubectl stop replicationcontroller foo - -// Stop pods and services with label name=myLabel. -$ kubectl stop pods,services -l name=myLabel - -// Shut down the service defined in service.json -$ kubectl stop -f service.json - -// Shut down all resources in the path/to/resources directory -$ kubectl stop -f path/to/resources -``` - -### Options - -``` - --all=false: [-all] to select all the specified resources. - -f, --filename=[]: Filename, directory, or URL to file of resource(s) to be stopped. - --grace-period=-1: Period of time in seconds given to the resource to terminate gracefully. Ignored if negative. - -h, --help=false: help for stop - --ignore-not-found=false: Treat "resource not found" as a successful stop. - -o, --output="": Output mode. Use "-o name" for shorter output (resource/name). - -l, --selector="": Selector (label query) to filter on. - --timeout=0: The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-29 09:18:59.539597953 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_stop.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_version.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_version.md deleted file mode 100644 index 5d40eb95a894..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/kubectl/kubectl_version.md +++ /dev/null @@ -1,92 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/kubectl/kubectl_version.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## kubectl version - -Print the client and server version information. - -### Synopsis - - -Print the client and server version information. - -``` -kubectl version -``` - -### Options - -``` - -c, --client=false: Client version only (no server required). - -h, --help=false: help for version -``` - -### Options inherited from parent commands - -``` - --alsologtostderr=false: log to standard error as well as files - --api-version="": The API version to use when talking to the server - --certificate-authority="": Path to a cert. file for the certificate authority. - --client-certificate="": Path to a client key file for TLS. - --client-key="": Path to a client key file for TLS. - --cluster="": The name of the kubeconfig cluster to use - --context="": The name of the kubeconfig context to use - --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. - --kubeconfig="": Path to the kubeconfig file to use for CLI requests. - --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace - --log-dir=: If non-empty, write log files in this directory - --log-flush-frequency=5s: Maximum number of seconds between log flushes - --logtostderr=true: log to standard error instead of files - --match-server-version=false: Require server version to match client version - --namespace="": If present, the namespace scope for this CLI request. - --password="": Password for basic authentication to the API server. - -s, --server="": The address and port of the Kubernetes API server - --stderrthreshold=2: logs at or above this threshold go to stderr - --token="": Bearer token for authentication to the API server. - --user="": The name of the kubeconfig user to use - --username="": Username for basic authentication to the API server. - --v=0: log level for V logs - --validate=false: If true, use a schema to validate the input before sending it - --vmodule=: comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager - -###### Auto generated by spf13/cobra at 2015-07-14 00:11:42.959846454 +0000 UTC - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_version.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/labels.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/labels.md deleted file mode 100644 index 5beb5d92bc7a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/labels.md +++ /dev/null @@ -1,148 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/labels.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Labels - -_Labels_ are key/value pairs that are attached to objects, such as pods. -Labels are intended to be used to specify identifying attributes of objects that are meaningful and relevant to users, but which do not directly imply semantics to the core system. -Labels can be used to organize and to select subsets of objects. Labels can be attached to objects at creation time and subsequently added and modified at any time. -Each object can have a set of key/value labels defined. Each Key must be unique for a given object. - -```json -"labels": { - "key1" : "value1", - "key2" : "value2" -} -``` - -We'll eventually index and reverse-index labels for efficient queries and watches, use them to sort and group in UIs and CLIs, etc. We don't want to pollute labels with non-identifying, especially large and/or structured, data. Non-identifying information should be recorded using [annotations](annotations.md). - - -## Motivation - -Labels enable users to map their own organizational structures onto system objects in a loosely coupled fashion, without requiring clients to store these mappings. - -Service deployments and batch processing pipelines are often multi-dimensional entities (e.g., multiple partitions or deployments, multiple release tracks, multiple tiers, multiple micro-services per tier). Management often requires cross-cutting operations, which breaks encapsulation of strictly hierarchical representations, especially rigid hierarchies determined by the infrastructure rather than by users. - -Example labels: - - * `"release" : "stable"`, `"release" : "canary"`, ... - * `"environment" : "dev"`, `"environment" : "qa"`, `"environment" : "production"` - * `"tier" : "frontend"`, `"tier" : "backend"`, `"tier" : "middleware"` - * `"partition" : "customerA"`, `"partition" : "customerB"`, ... - * `"track" : "daily"`, `"track" : "weekly"` - -These are just examples; you are free to develop your own conventions. - - -## Syntax and character set - -_Labels_ are key value pairs. Valid label keys have two segments: an optional prefix and name, separated by a slash (`/`). The name segment is required and must be 63 characters or less, beginning and ending with an alphanumeric character (`[a-z0-9A-Z]`) with dashes (`-`), underscores (`_`), dots (`.`), and alphanumerics between. The prefix is optional. If specified, the prefix must be a DNS subdomain: a series of DNS labels separated by dots (`.`), not longer than 253 characters in total, followed by a slash (`/`). -If the prefix is omitted, the label key is presumed to be private to the user. Automated system components (e.g. `kube-scheduler`, `kube-controller-manager`, `kube-apiserver`, `kubectl`, or other third-party automation) which add labels to end-user objects must specify a prefix. The `kubernetes.io/` prefix is reserved for Kubernetes core components. - -Valid label values must be 63 characters or less and must be empty or begin and end with an alphanumeric character (`[a-z0-9A-Z]`) with dashes (`-`), underscores (`_`), dots (`.`), and alphanumerics between. - -## Label selectors - -Unlike [names and UIDs](identifiers.md), labels do not provide uniqueness. In general, we expect many objects to carry the same label(s). - -Via a _label selector_, the client/user can identify a set of objects. The label selector is the core grouping primitive in Kubernetes. - -The API currently supports two types of selectors: _equality-based_ and _set-based_. -A label selector can be made of multiple _requirements_ which are comma-separated. In the case of multiple requirements, all must be satisfied so comma separator acts as an AND logical operator. - -An empty label selector (that is, one with zero requirements) selects every object in the collection. - -### _Equality-based_ requirement - -_Equality-_ or _inequality-based_ requirements allow filtering by label keys and values. Matching objects must have all of the specified labels (both keys and values), though they may have additional labels as well. -Three kinds of operators are admitted `=`,`==`,`!=`. The first two represent _equality_ and are simply synonyms. While the latter represents _inequality_. For example: - -``` -environment = production -tier != frontend -``` - -The former selects all resources with key equal to `environment` and value equal to `production`. -The latter selects all resources with key equal to `tier` and value distinct from `frontend`. -One could filter for resources in `production` but not `frontend` using the comma operator: `environment=production,tier!=frontend` - - -### _Set-based_ requirement - -_Set-based_ label requirements allow filtering keys according to a set of values. Matching objects must have all of the specified labels (i.e. all keys and at least one of the values specified for each key). Three kind of operators are supported: `in`,`notin` and exists (only the key identifier). For example: - -``` -environment in (production, qa) -tier notin (frontend, backend) -partition -``` - -The first example selects all resources with key equal to `environment` and value equal to `production` or `qa`. -The second example selects all resources with key equal to `tier` and value other than `frontend` and `backend`. -The third example selects all resources including a label with key `partition`; no values are checked. -Similarly the comma separator acts as an _AND_ operator for example filtering resource with a `partition` key (not matter the value) and with `environment` different than `qa`. For example: `partition,environment notin (qa)`. -The _set-based_ label selector is a general form of equality since `environment=production` is equivalent to `environment in (production)`; similarly for `!=` and `notin`. - -_Set-based_ requirements can be mixed with _equality-based_ requirements. For example: `partition in (customerA, customerB),environment!=qa`. - - -## API - -LIST and WATCH operations may specify label selectors to filter the sets of objects returned using a query parameter. Both requirements are permitted: - - * _equality-based_ requirements: `?labelSelector=key1%3Dvalue1,key2%3Dvalue2` - * _set-based_ requirements: `?labelSelector=key+in+%28value1%2Cvalue2%29%2Ckey2+notin+%28value3%29` - -Kubernetes also currently supports two objects that use label selectors to keep track of their members, `service`s and `replicationcontroller`s: - -* `service`: A [service](services.md) is a configuration unit for the proxies that run on every worker node. It is named and points to one or more pods. -* `replicationcontroller`: A [replication controller](replication-controller.md) ensures that a specified number of pod "replicas" are running at any one time. - -The set of pods that a `service` targets is defined with a label selector. Similarly, the population of pods that a `replicationcontroller` is monitoring is also defined with a label selector. For management convenience and consistency, `services` and `replicationcontrollers` may themselves have labels and would generally carry the labels their corresponding pods have in common. - -Sets identified by labels could be overlapping (think Venn diagrams). For instance, a service might target all pods with `"tier": "frontend"` and `"environment" : "prod"`. Now say you have 10 replicated pods that make up this tier. But you want to be able to 'canary' a new version of this component. You could set up a `replicationcontroller` (with `replicas` set to 9) for the bulk of the replicas with labels `"tier" : "frontend"` and `"environment" : "prod"` and `"track" : "stable"` and another `replicationcontroller` (with `replicas` set to 1) for the canary with labels `"tier" : "frontend"` and `"environment" : "prod"` and `"track" : "canary"`. Now the service is covering both the canary and non-canary pods. But you can mess with the `replicationcontrollers` separately to test things out, monitor the results, etc. - -Note that the superset described in the previous example is also heterogeneous. In long-lived, highly available, horizontally scaled, distributed, continuously evolving service applications, heterogeneity is inevitable, due to canaries, incremental rollouts, live reconfiguration, simultaneous updates and auto-scaling, hardware upgrades, and so on. - -Pods (and other objects) may belong to multiple sets simultaneously, which enables representation of service substructure and/or superstructure. In particular, labels are intended to facilitate the creation of non-hierarchical, multi-dimensional deployment structures. They are useful for a variety of management purposes (e.g., configuration, deployment) and for application introspection and analysis (e.g., logging, monitoring, alerting, analytics). Without the ability to form sets by intersecting labels, many implicitly related, overlapping flat sets would need to be created, for each subset and/or superset desired, which would lose semantic information and be difficult to keep consistent. Purely hierarchically nested sets wouldn't readily support slicing sets across different dimensions. - - -## Future developments - -Concerning API: we may extend such filtering to DELETE operations in the future. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/labels.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/README.md deleted file mode 100644 index 041222053512..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/README.md +++ /dev/null @@ -1,206 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/limitrange/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Limit Range -======================================== -By default, pods run with unbounded CPU and memory limits. This means that any pod in the -system will be able to consume as much CPU and memory on the node that executes the pod. - -Users may want to impose restrictions on the amount of resource a single pod in the system may consume -for a variety of reasons. - -For example: - -1. Each node in the cluster has 2GB of memory. The cluster operator does not want to accept pods -that require more than 2GB of memory since no node in the cluster can support the requirement. To prevent a -pod from being permanently unscheduled to a node, the operator instead chooses to reject pods that exceed 2GB -of memory as part of admission control. -2. A cluster is shared by two communities in an organization that runs production and development workloads -respectively. Production workloads may consume up to 8GB of memory, but development workloads may consume up -to 512MB of memory. The cluster operator creates a separate namespace for each workload, and applies limits to -each namespace. -3. Users may create a pod which consumes resources just below the capacity of a machine. The left over space -may be too small to be useful, but big enough for the waste to be costly over the entire cluster. As a result, -the cluster operator may want to set limits that a pod must consume at least 20% of the memory and cpu of their -average node size in order to provide for more uniform scheduling and to limit waste. - -This example demonstrates how limits can be applied to a Kubernetes namespace to control -min/max resource limits per pod. In addition, this example demonstrates how you can -apply default resource limits to pods in the absence of an end-user specified value. - -See [LimitRange design doc](../../design/admission_control_limit_range.md) for more information. For a detailed description of the Kubernetes resource model, see [Resources](../../../docs/user-guide/compute-resources.md) - -Step 0: Prerequisites ------------------------------------------ -This example requires a running Kubernetes cluster. See the [Getting Started guides](../../../docs/getting-started-guides/) for how to get started. - -Change to the `/examples/limitrange` directory if you're not already there. - -Step 1: Create a namespace ------------------------------------------ -This example will work in a custom namespace to demonstrate the concepts involved. - -Let's create a new namespace called limit-example: - -```console -$ kubectl create -f docs/user-guide/limitrange/namespace.yaml -namespaces/limit-example -$ kubectl get namespaces -NAME LABELS STATUS -default Active -limit-example Active -``` - -Step 2: Apply a limit to the namespace ------------------------------------------ -Let's create a simple limit in our namespace. - -```console -$ kubectl create -f docs/user-guide/limitrange/limits.yaml --namespace=limit-example -limitranges/mylimits -``` - -Let's describe the limits that we have imposed in our namespace. - -```console -$ kubectl describe limits mylimits --namespace=limit-example -Name: mylimits -Type Resource Min Max Default ----- -------- --- --- --- -Pod memory 6Mi 1Gi - -Pod cpu 250m 2 - -Container memory 6Mi 1Gi 100Mi -Container cpu 250m 2 250m -``` - -In this scenario, we have said the following: - -1. The total memory usage of a pod across all of its container must fall between 6Mi and 1Gi. -2. The total cpu usage of a pod across all of its containers must fall between 250m and 2 cores. -3. A container in a pod may consume between 6Mi and 1Gi of memory. If the container does not -specify an explicit resource limit, each container in a pod will get 100Mi of memory. -4. A container in a pod may consume between 250m and 2 cores of cpu. If the container does -not specify an explicit resource limit, each container in a pod will get 250m of cpu. - -Step 3: Enforcing limits at point of creation ------------------------------------------ -The limits enumerated in a namespace are only enforced when a pod is created or updated in -the cluster. If you change the limits to a different value range, it does not affect pods that -were previously created in a namespace. - -If a resource (cpu or memory) is being restricted by a limit, the user will get an error at time -of creation explaining why. - -Let's first spin up a replication controller that creates a single container pod to demonstrate -how default values are applied to each pod. - -```console -$ kubectl run nginx --image=nginx --replicas=1 --namespace=limit-example -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -nginx nginx nginx run=nginx 1 -$ kubectl get pods --namespace=limit-example -POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS CREATED MESSAGE -nginx-ykj4j 10.246.1.3 10.245.1.3/ run=nginx Running About a minute - nginx nginx Running 54 seconds -$ kubectl get pods nginx-ykj4j --namespace=limit-example -o yaml | grep resources -C 5 -``` - -```yaml - containers: - - capabilities: {} - image: nginx - imagePullPolicy: IfNotPresent - name: nginx - resources: - limits: - cpu: 250m - memory: 100Mi - terminationMessagePath: /dev/termination-log - volumeMounts: -``` - -Note that our nginx container has picked up the namespace default cpu and memory resource limits. - -Let's create a pod that exceeds our allowed limits by having it have a container that requests 3 cpu cores. - -```console -$ kubectl create -f docs/user-guide/limitrange/invalid-pod.yaml --namespace=limit-example -Error from server: Pod "invalid-pod" is forbidden: Maximum CPU usage per pod is 2, but requested 3 -``` - -Let's create a pod that falls within the allowed limit boundaries. - -```console -$ kubectl create -f docs/user-guide/limitrange/valid-pod.yaml --namespace=limit-example -pods/valid-pod -$ kubectl get pods valid-pod --namespace=limit-example -o yaml | grep -C 5 resources -``` - -```yaml - containers: - - capabilities: {} - image: gcr.io/google_containers/serve_hostname - imagePullPolicy: IfNotPresent - name: nginx - resources: - limits: - cpu: "1" - memory: 512Mi - securityContext: - capabilities: {} -``` - -Note that this pod specifies explicit resource limits so it did not pick up the namespace default values. - -Step 4: Cleanup ----------------------------- -To remove the resources used by this example, you can just delete the limit-example namespace. - -```console -$ kubectl delete namespace limit-example -namespaces/limit-example -$ kubectl get namespaces -NAME LABELS STATUS -default Active -``` - -Summary ----------------------------- -Cluster operators that want to restrict the amount of resources a single container or pod may consume -are able to define allowable ranges per Kubernetes namespace. In the absence of any hard limits, -the Kubernetes system is able to apply default resource limits if desired in order to constrain the -amount of resource a pod consumes on a node. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/limitrange/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/invalid-pod.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/invalid-pod.yaml deleted file mode 100644 index b63f25debabd..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/invalid-pod.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: invalid-pod -spec: - containers: - - name: kubernetes-serve-hostname - image: gcr.io/google_containers/serve_hostname - resources: - limits: - cpu: "3" - memory: 100Mi diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/limits.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/limits.yaml deleted file mode 100644 index ebd63dd5af8c..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/limits.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: v1 -kind: LimitRange -metadata: - name: mylimits -spec: - limits: - - max: - cpu: "2" - memory: 1Gi - min: - cpu: 250m - memory: 6Mi - type: Pod - - default: - cpu: 250m - memory: 100Mi - max: - cpu: "2" - memory: 1Gi - min: - cpu: 250m - memory: 6Mi - type: Container diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/namespace.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/namespace.yaml deleted file mode 100644 index 200a894b0b5e..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: limit-example diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/valid-pod.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/valid-pod.yaml deleted file mode 100644 index c1ec54183beb..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/limitrange/valid-pod.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: valid-pod - labels: - name: valid-pod -spec: - containers: - - name: kubernetes-serve-hostname - image: gcr.io/google_containers/serve_hostname - resources: - limits: - cpu: "1" - memory: 512Mi diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/README.md deleted file mode 100644 index b175078b8ff3..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/README.md +++ /dev/null @@ -1,120 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/liveness/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Overview - -This example shows two types of pod [health checks](../production-pods.md#liveness-and-readiness-probes-aka-health-checks): HTTP checks and container execution checks. - -The [exec-liveness.yaml](exec-liveness.yaml) demonstrates the container execution check. - -```yaml - livenessProbe: - exec: - command: - - cat - - /tmp/health - initialDelaySeconds: 15 - timeoutSeconds: 1 -``` - -Kubelet executes the command `cat /tmp/health` in the container and reports failure if the command returns a non-zero exit code. - -Note that the container removes the `/tmp/health` file after 10 seconds, - -```sh -echo ok > /tmp/health; sleep 10; rm -rf /tmp/health; sleep 600 -``` - -so when Kubelet executes the health check 15 seconds (defined by initialDelaySeconds) after the container started, the check would fail. - - -The [http-liveness.yaml](http-liveness.yaml) demonstrates the HTTP check. - -```yaml - livenessProbe: - httpGet: - path: /healthz - port: 8080 - initialDelaySeconds: 15 - timeoutSeconds: 1 -``` - -The Kubelet sends a HTTP request to the specified path and port to perform the health check. If you take a look at image/server.go, you will see the server starts to respond with an error code 500 after 10 seconds, so the check fails. - -This [guide](../walkthrough/k8s201.md#health-checking) has more information on health checks. - -## Get your hands dirty - -To show the health check is actually working, first create the pods: - -```console -$ kubectl create -f docs/user-guide/liveness/exec-liveness.yaml -$ kubectl create -f docs/user-guide/liveness/http-liveness.yaml -``` - -Check the status of the pods once they are created: - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -[...] -liveness-exec 1/1 Running 0 13s -liveness-http 1/1 Running 0 13s -``` - -Check the status half a minute later, you will see the container restart count being incremented: - -```console -$ kubectl get pods -mwielgus@mwielgusd:~/test/k2/kubernetes/examples/liveness$ kubectl get pods -NAME READY STATUS RESTARTS AGE -[...] -liveness-exec 1/1 Running 1 36s -liveness-http 1/1 Running 1 36s -``` - -At the bottom of the *kubectl describe* output there are messages indicating that the liveness probes have failed, and the containers have been killed and recreated. - -```console -$ kubectl describe pods liveness-exec -[...] -Sat, 27 Jun 2015 13:43:03 +0200 Sat, 27 Jun 2015 13:44:34 +0200 4 {kubelet kubernetes-minion-6fbi} spec.containers{liveness} unhealthy Liveness probe failed: cat: can't open '/tmp/health': No such file or directory -Sat, 27 Jun 2015 13:44:44 +0200 Sat, 27 Jun 2015 13:44:44 +0200 1 {kubelet kubernetes-minion-6fbi} spec.containers{liveness} killing Killing with docker id 65b52d62c635 -Sat, 27 Jun 2015 13:44:44 +0200 Sat, 27 Jun 2015 13:44:44 +0200 1 {kubelet kubernetes-minion-6fbi} spec.containers{liveness} created Created with docker id ed6bb004ee10 -Sat, 27 Jun 2015 13:44:44 +0200 Sat, 27 Jun 2015 13:44:44 +0200 1 {kubelet kubernetes-minion-6fbi} spec.containers{liveness} started Started with docker id ed6bb004ee10 -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/liveness/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/Dockerfile b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/Dockerfile deleted file mode 100644 index d057ecd309e3..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM scratch - -ADD server /server - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/Makefile b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/Makefile deleted file mode 100644 index 3eb9f0e2fe13..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -all: push - -server: server.go - CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w' ./server.go - -container: server - docker build -t gcr.io/google_containers/liveness . - -push: container - gcloud docker push gcr.io/google_containers/liveness - -clean: - rm -f server diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/server.go b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/server.go deleted file mode 100644 index 26c337e767bd..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/liveness/image/server.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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. -*/ - -// A simple server that is alive for 10 seconds, then reports unhealthy for -// the rest of its (hopefully) short existence. -package main - -import ( - "fmt" - "log" - "net/http" - "time" -) - -func main() { - started := time.Now() - http.HandleFunc("/started", func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(200) - data := (time.Now().Sub(started)).String() - w.Write([]byte(data)) - }) - http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { - duration := time.Now().Sub(started) - if duration.Seconds() > 10 { - w.WriteHeader(500) - w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds()))) - } else { - w.WriteHeader(200) - w.Write([]byte("ok")) - } - }) - log.Fatal(http.ListenAndServe(":8080", nil)) -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging-demo/Makefile b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging-demo/Makefile deleted file mode 100644 index 2d9180f30244..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging-demo/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# Makefile for launching synthetic logging sources (any platform) -# and for reporting the forwarding rules for the -# Elasticsearch and Kibana pods for the GCE platform. -# For examples of how to observe the ingested logs please -# see the appropriate getting started guide e.g. -# Google Cloud Logging: https://k8s.io/kubernetes/blob/master/docs/getting-started-guides/logging.md -# With Elasticsearch and Kibana logging: https://k8s.io/kubernetes/blob/master/docs/getting-started-guides/logging-elasticsearch.md - -.PHONY: up down logger-up logger-down logger10-up logger10-down - -up: logger-up logger10-up - -down: logger-down logger10-down - -logger-up: - kubectl create -f synthetic_0_25lps.yaml - -logger-down: - kubectl delete pod synthetic-logger-0.25lps-pod - -logger10-up: - kubectl create -f synthetic_10lps.yaml - -logger10-down: - kubectl delete pod synthetic-logger-10lps-pod - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging-demo/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging-demo/README.md deleted file mode 100644 index d3400eb4b358..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging-demo/README.md +++ /dev/null @@ -1,52 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/logging-demo/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Elasticsearch/Kibana Logging Demonstration - -This directory contains two [pod](../../../docs/user-guide/pods.md) specifications which can be used as synthetic -logging sources. The pod specification in [synthetic_0_25lps.yaml](synthetic_0_25lps.yaml) -describes a pod that just emits a log message once every 4 seconds. The pod specification in -[synthetic_10lps.yaml](synthetic_10lps.yaml) -describes a pod that just emits 10 log lines per second. - -See [logging document](../logging.md) for more details about logging. To observe the ingested log lines when using Google Cloud Logging please see the getting -started instructions -at [Cluster Level Logging to Google Cloud Logging](../../../docs/getting-started-guides/logging.md). -To observe the ingested log lines when using Elasticsearch and Kibana please see the getting -started instructions -at [Cluster Level Logging with Elasticsearch and Kibana](../../../docs/getting-started-guides/logging-elasticsearch.md). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/logging-demo/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging-demo/synth-logger.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging-demo/synth-logger.png deleted file mode 100644 index bd19ea3ee41dc5cd6730ce6a3f54431b09f32a85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89284 zcmce;bySvH*Ej0kZWV)&6c7-QE~OhqLQ13?q?=p11XNH;M7p~hq+7(BF6r*>?)WDA zdDzc;{&>$gXMFGXUBj`7&3)CHYpywevAkcu5=Fg3aOc{!Yp7x`g=DW?yUBm;+Vw{$ zf5LAbl6|3sFW0RF#pF>?P)4StC*enY8)0P|IfQ|Yy|$J9HA4%8xjuunu9d#Ng|!jF zX5)G-oZ!(lF`?)34$-S)_R4ZfB)2xLSx}s@_OWl=kijSWnmL(yCs*-pmr38SqMDM6 zX_%c+mTie`uZbFt{HQY%w!Bc?hws7F*FB_A@DI*rj#G_M)f$1 z`u=fkv^C@0;^IrVqkkQ&=vjr=uYS1p8a;#V>W8k^FE#%7_Ydzs3oc(i?cWD0wye_C z_wfneDlQ-T?*sKyFV5BXM%1X{8e0xkCkGpGypG?k>lcR#)AI5Vm8^5~^L7{KXZo$7 z)vMke9UZMYr{Ci#2qtR!xWi{rh9L%PNypBE~^w7?{;xsX}9*h zuyEzqgPZ8Y?=~mvZevlt<&5s_?VX<1;ovAm`r?U-h!8w@V59Tq-yhzTE;!A?(SQ%G zQV;*JpkUu+SeJ(OAt^F6?g7W4g8kT?hK2@uMZ?q`2j1~8EmxYL=1@ir0wSUuuVr7R z8k9SCREvy$b4Ecw65WNKG-)1s;v0m7 zQ4|sasnjNG=mOX{xWy?nZ57@078Vu;1_p+mu?n*}D5N1FAzJUYgw4&@(q)pUeU_^h z|MiTM6Gn$#QxiGouJFaFx?GMm=ADb-)XDQ{3*v^{%UCpwXRYPWW5OUQ2i z*u%)!xIL1kl6*lkB0QX4y{K!TbD+ACC#Y_5yt*60rfJcb?7>tmIzdf!b4a@WSIPY$=@=ONyuF7?%+(YWaC$UKEynl{C$HPv+w1D;et3pKL{zQY_%$+; zU@qMK<41$`$hqlhSp@~#rS234wGuC(MBD}=BcpWL?yjzUr#%x54GqSyk-@Ad*($=(dPfPetm40+4`Z=^3MrDI2{o$Xy*&X$*#A?^_)B@E=`?p#hg z^X(AiY01e|7w0F~!sZh-E*s<39^XD(zxCPE(|%(-CUvQ(s3?ZVzM-+PRG;&5Oo=3w zlRJ}TVgd3;uEY7RWImE_YMqfOb^dZxqC7>Pt)m}>$cAr8ye~tE4hFE z{CT4-R$o`wdTu-9?m}m&QXx_2c%Am|Y2i5fGk+nnrB&r#T^YR&WkUh`pxx79lKoOE zTF(!RhC3g}TU}k$<;S~xdPc*I$JAj}XJ^$NcT)Sx)YpG} zxPIc`yu)y0RbEwAb~rxfY(G7XLh4d=GFq8sNe+XNAor7(m)AnQ_WlEGJ!5^OK_L(4 zO(G(qkTgln&k478^0DK76&8MX9XT4w9xB{l8yk6QotK@HgN21DB_$=Gz8O$ZG5Reu zv_CjQuI8x1J@oCT+Otsiq#1cpQQ_vn$v5+LyPHdDuH&OV>=)V@S$|x=X*OCGfMGS$ z;P?GIvzFF`diX?sUIa{N$Bq4#6n_HDJ44sg@t+7$G{1YS#={Wwg z@oMK=Xb-!3dI-6!W;+EgPJfG%AR8KDxoyQMgKpfq6~|-0K2`6judna%ZKL*rpPHJQ zhGq%kRaI5>{QNv2ApvG7i($uOkHO(#i;0>Tq>e^~O-4n`Ul z=)}B^+q0GS8=7Tr>jnnwhl`Bu?CkF1G0OA&2o4So3=E8qkB7ua#Q*MasL;^o1})-Pt^IvsJ}1br(Gd~&LEVx3F2{is60~%5dFth4nBF3O1jXhf zC71>TRRTE*{o^i4%3X&BUQfc!e%rPx=kyZMG&!N@u0UN`Gfs%r$>~VWnfB*S%R^DUG zX6KFSu;5@J6z#$xEw{71@Ta;4ZQ%vFjcCOF2SbK&-a?7^ECzZ82AG0&kkCvA7=`ch z5;M`$)ARGY!Y?G7VOm4#$Hv9QB_t%o!!tB7A$a)kAqk1w>7k{dS6G({SsY<3fc zJ8M&Q3x}K!*4M@=OG82wEG@SnsQmo=4BI0^!o!>752rjyKBJS27aB@a3JQ9Kg!DC% zxV@We!4dSz&0SA;;i>7o#wI5xm+*Sf<_o5`9wabAb~6;z%Y%W2Mod!ji@(3WpP#<0 zv76=yqULvBpUcJB0VJQ+V0z6ePF~)3KRs@X`V-G>Igq^Dd=57-+Z<$SY8r8;HI(5l zDk>4@+sUP#vu;XhMvY?kK~58mxV1Mm zErz>2TU}j+Ar5bBZf^EOd-&MHDEkn&Yv2 z&cO?R$zbc7o10r$bm)C#W@i5A?jFG^B?q&9!u4eB?BoE4f;nRK{OknoIW;vEiR@%5 z_4M>4vn{roYk}NUlb9%I*#Zk>xDYyNa!n0CH@DMrZ$?Q;N&B1=BO*&4q)|Iaiy8u=rMn*>XS@E*o7%4Ho3&-u-Tu!^xp7ko#PQ|aO z(}MvWN)DnyhJIt+cUA0v1~fDgw@NRn4cR1ha#*M=k86aSCPM_ z-rCsOj*X7}LY?--V;Zk;48qtR!i&?YaM-dq)krK_q<=!4fARhg4-7oKunomrcw>>A z#)(mt&Mq!4Iy%!wg$v2DG*RubPb@zw?J$@W8096vG$k z9~6j2!c8C4j6zB-^7X-!w~svQ%Uw=Nva(k8On)D2Oe|QH=lQ!<+sE-&R8%Z2Es6R+ z%#nBE5l4yOaO02bjN>*}h1`oKMD*6u5}y#$OjlPnXvAb5yLT5k^cG)ZVFgW3PX{$hQ}3_8RzAyJh{2vR z)ttAAJnv-k*D%{ny*V_pV=GRFG@SO)4Qjcy&l<(jAA#|Gfu(jW?R&-0QX%#9n+#L) z%(JoaqL0kKqh74ubcp;;P0N)=xh-pt@8twWPNf;N0}-RNpaVIocddn(ZxDty$h7Y$QlbuDg@3e zr}q7*F`5YBJr4{bhW^gGPI*2r+iB0Ob0hr9UlqJ=7j2tw$TB{@v0GSBK*PW=R-~Pz z(-RUr8(edKZo+Z8t{xj3+w(I`;FWl0ZU(-9Hm_XMoK>Ur12;bI3U%sJD5jms$%BX~ zZ1v>5Z{Hrs)uf}P)uF_+t6isj}S&t zIo-lU&bZ$~Q&dv8F9>m_ytSv~@eQha_@_uebwS1OKyM!hY73?vs;tb+@87>e1-84l z$H&WyLhADicc#w$mQSNj!69ULEJ{gED5%|Up<9eq;9z0(>~44pK7U^KJ4uwr#|lak zJG+w7QhRIbm5EvbQV*3;=lQmX47oH$%_;}TCQwgT*sk=ijg)3(U2LPLh@Z4gl!VIt zEG{mFau^OLCnuNV-KBxN2?)7HKf;CO<>UPk1l0Oag=uCH{1y+`q8I_ARn}etzxjYt^ zXg)nT5?!09H9W9DkZg42=QoOpwW;wVc`1e4eeoCx@bRt7qSIYYZj&N9qh(Z7$}Q_} zn#b-F22IT7b2a)C-CdlR7#f-jGan&9`prDWEY2EOZ)k+Jqw1jUL@7^wsMbCX3gD=qiR`>AIoD1}6nthIuTp<$ zJs~})O!G9Wp&xaQ-c>%zYPo)rWMXQ6Xt%6fNF{{yZG61%EB*rFH&V{ej;r}}8wTiVpqezvi_OSbsm`a4Rt}J3D7Qc56SPCoL%M@xk5!2?6KsevX>QH`hP@Ae|9}G#nil zwlGk-5naBKd+u5+t{8xUIcvVPl0hFy3Ec=qkVfY(90X5*cIQCEQAN;8`pO7-MY_Nm z!quwD1y9+Gs;r#xADXz%Omm98tn;^*CmxusOzCa*1bk5qc&zuneVRj~b~r@GGyx0O zsPxE4Bp_e=Et9V!mO8G5>p7ZRS>9Z%Z@G@QS%>n1Sl-aN9s9`Zu%4nGkKL9Z{J7-r zj%s5&XtS`TNv7g+QVbAD-tK0R`>rRJLzSc&oMz&*NkjB4m07>x93J0}uqsfp2y4ef z5_6D|Pg}g}Q};DHl8lFuB6<0eMO$4xItfiZLtUL?9%34f_AHE9m~;!Uxb~;=#^Rnt zMew!x6*1pgA!C{gmG@dZGHDp;N{<{kT=ng2k81l!!$h|dPNDGydS?v5SHuDdRVw)~ zYdd54A{uRNZHaK(CYU)mYHhXxgMwyWYiWhNaQD0i{YNtZ08yIVO3U3y2}na&6XCPd z)7_)4YOq4`xopdeilmT23=|i$wLoRk)Phjj-`!qr;vJ@o^gNLk*MQaUzHMz=N=gc( zNg^Tx?X;E?%#gG!#T+M?^iaW`L3MX}ic7By9b5_2C5`?hS!*^>XX@`>eBB!C* z`T0|jJZT||ys)sazP=uC0zRXzcyDOuqd8?BV?qby(32|Vb8yE;qc5a*Q|A$w-B5R#@0TSHcS>ts1j8Z=RtnL9z-Gl^gk3T6*yF)7=QSzviqQ6%`dNEOM)> ztE~oTN3vK(>gl9=O_udN|1MIu=ouJRR+gn>ImLRm?~{vmxLi~ho4USsBqR@O?Tq20 z3K5Uvb(NIq^;_XE`TN+mvd+n-CpoiC%7jNel|}= zG(}Lex`swhPEM)C_|G;RZmY%3TRRIe+>YJ7z4G)H=@^R8#glyD?y|AR%n-6V>`L(P z_$x9M)`RcNg)l=4z5zvPu*b6u0(8_4T21 zNzBtA+&iY`kIRd$2yE7~Dvu8B!Sqgs62inYA~JB8>CtKPHt&+ zIq}|sm?qKk5%5FYRBhH9Jj8UGfFU~Nzf5ODMMv}n>w#3kz!SX>x+SD%f>`g z=#!Yfc#?8HCUu+i!#J)957B7r>CdsiTb-Fkk>ie(&SNKh3P0z+(-c>;=x)7beits& z*RHAM+v;?f-7@xkVqDO0Z=BWp3#G?u&9|K;*3#<(+qX&0aB*ze@-*qwjF0zcwkQ8! zzmj-<$9T+M$vkc%Uhlsn&S>~#7pDn)yYf8yxZ=Qy*d9Ny^h)$^V8z8b`0zZ_}VIW+`S}SfCm6>(^gA&L^pJEE5q! zJ}R$rN{%ZxoOc(WTKsenY>GnEI38|l!#6<_dS4*`xY<(Je7Ce1ZQ0E0!&5)0*zbsm zoAhkkDQRg*qsY)l$-i-Z3nfZ;c4$pa&9)5XRLY~E=KYO{TDJ>V{)eOPXKP(;KLbmx|w(a?*) zxuDtJnwpw|mC<>>YPa18dYMwh!OjjLuS0$d-yNt5$jHe0b2Z=_r=xBCdD(Z+3en0X zVnd@>Vm2h$v-=s95EBcFg_)UvfI#HSgQstPyvKDij8rJsX)AgmH5hy!ijm11Ia-yk zXhXzPWFu4W-o2yr?kohFk8Z8BP!52F+1X{Wk&=Q+qm3ezK?OsZh`>*Cf=H?&z?<>P zD{+No-bqL>FytVVa^!>Gaz2Ds@{q^=or_ED`F>Q}moLf5ja&BX>Cu3lGGTiE>HZOV z>YVHxb2Bp^UteYVP=E|vU5T;8%%vEDB$!K|q*2pyaD>s|c?&^T-nl@RmK*+}jfa~* zE-ol0>A|a4cKh!?WFqcE0a{*GR>kkcIuVF4G|fs$LFyF9i=;V>jy_>wVHq+jfkLj( z*V;gY(idrEX-UJx#KFwm;;1>Q$mAA%v38o#r++UYy1LKJZdtrK{4$MJ7QQLeQu_HEsn6`;5l29h@E)uFMK~h zxqW;&B}6B+ru?b2Z>uKeu!3cDqrOVSrcO|cZwq06)k27zy4!`yoS&yYCVsowg^Vnz z>-i3O;C9iV$G3Uz;->>#1aeI_@~SksxpLKKI@Z-xhDubaO2=jR0&VHr)+{v_MdD;h zIqfz@W!dd_oi8@}9zSGn{rS=tLzXJA-*-+@)V_zdUXOrMN3;em3Vp z%a%H)+xgFK@I+ zS^o7W_??5{gWoJkX+6W`jYV&gW1wJ{^P)?m!@s#C96@b>0qHd3!z45;%S_H+$`RSB zwe9ZO2)>NtcY$I)ow~QL&(_|)6BeZ`^j0{?)Wx&T!NMYfSQi$wc1!n2|K#kk=)B&g%Hq-u> zDct~sUry|n5IXqoV1M62V;OKq-}2j&0!BQ8!9TKuJ6GXe1&hPenPSE`O~N3f5Vl6k1=WZ$$W$o zp@T?`vkT8j@~W^Gm6}+D^*DrZrizck69KpM2Gh8)`mj^E)56rTF^7Yijn7 z%O9kNMkg~f^UIfeb9{6tq_P>iaMcQ%rD@>E{PQ}0JiqQXysLY+owl)4-2?Y#-)^y- zBN9h0tM_wV_U4-h`1lO!RWGTrQ&W>4Q&0?zj5s?uVG7O`MI(<3rEq-#J~4_66;BZ= zr}L3*zQ+73a6!&P8QYdAXZy8HYhf^Td!HcqGx1y>H9HNRMd3^YZb~3Bk+Kq?bE28StG8 zDaIss$sOLpy^BothP+1UEG#46cv<{T+bQ|BW#H0PpjJ2^OYMDndb;6eBg1(2S} zot}>%wB=F<2M1Y|o>K;`4OLgBr@!p!b|Z>UPfrI}%G=xf7WzYZVt!#6U?i|{Gbggv zaT2JPiwACU*xPJ=t80n!t}QdTNH&g#xK4P@sr~aW18F)z6kp`=;fz02&JooOx;i=# z9{^%SM@NU>dB^Vt4X_U`;K^U`S?1fL(jaFB=MS0D(a}XnHke6voQ~;)&OF^~zA&(T z`selQ5vVi~JX%f;4j!LA0SqQ71Gr2mhOE4NZ^cs)VPQ6Qc1Gp=N4&i1N=iyH{5FeS zT-NijUZ_{tcw<;W%LrhkOp*u<(}U=zxmeR6cO~Qu09K`HUD99i$#aFOTh&l* z_55}`|J*)0-HED&%@A_uFOh}@*^Hv9%R^mM>0s|^5{=I?URPd}TB#^HiSXLU#Y}?~ zKm#plSc1psi*dohMTP_GFc8^o^Z-H&$^addocwG2{D`j!fQN{X&(I=3X?cmYC1z!r z)|FDz$W)^S=)C`k`5}>+^w;m-GF{2rKc2h4isN?KZTb!6G+Dq)HMPo5CzR|Ql0J#u z-Lk;iF0Zae1MwLWF*mt5Sf3=S8iYd#{0cs=UQ?lA=c|VTHBgNJ)Lv<~(yv~a@=;ce zPz_nmV$kt!t$09F@AVxhe3>KK>gql?n&_I22tH_`a@t=NyKe&M03eApY!rP>Oy1 zuv_)4SjdUxYBOIE;Lg6$ZnL)UBIz5TrARZF2&s}T5y0hW;f=nh(4kSW+9HO*5}8JS!t%G<&myE3Ks@~{h8(=yP;Lt7y-hqhF50Nc~3y$Bd4&8lPV zI2u-CaVZQ_@+ z8jB;+*>OchwX};fu5+S5*Hc_uLE)0+pvU!90*cr5?0CZMf)8lBM;Nd^l$V$DIc!b> z#7uQbyT3aavllqsd?6$xWMfk#M263-htl)s4uhhxv9X?>o`b_7&~`AD^_W$jJ$nx! zC?xb3%UEQ@)+PB2oME;~;r!}Q;fD_&O#8FBET@HRZHv>=7UG|~L*?i4?p-*?9f&^y zcC*3dzAUJp0c`@3^7{4bFz?C9$<-{iZ{Brty{(O^%hX<%F zDD;3&jP{nJ401V|3yb1FoF6U3A%Ln33hK#GD}Dd|{pjc@d;=|6QW8ArSpPocvw16aqyrL;I)234EMA0Ji*@&HZ?AQxR;T%=ddkGK67IOaeW z0747Hx*0*CTWBqM-QT`l5*ukt(j(PLa3$yr%elCK#(pk7p)dZ}5A7=&U_#wJJ-)s^ zX|*`6t4%UK!k<2W3JnXBNRb65dx~7dO9=JnwiSuiL`4O+_L0{9Zbnv?{nE6Kw)XGA zK~B~uUESS*D%yC2SS;+EWo2c_RaIuIgKrqaB(PK;V~%-OvMjZ8pb>LE%Ea?SMa#|3 zmLIwmgV8-WxHw#F`rP%onPeMP93!lpz15ZWG11XC(Fhz)2cL$t?CtG!Fm?cF*9*j~ zfaOPZ#s#aWv&pW}C$~wV46P$2g};FMo>j^hse_L0pBly2Jp28rZewqMzX7lF{N!YO zUY?fn>u)hJIVD3pmX^=!KZ<;LXt}XoojX=hQC=CtTdXx2 z1$Qf9-AH(`W+E*6{F6hsDLZ3-1#*r|RHB;0b5LoMuKBfStv^gtT0)|AS@p;>F=4_5-Stvmflst5;DEn zzh6PAY%oEGgC48UPOxTX(lq8qAwBoHS~)aQ4luBT#`1?5U(oIrwPSe&T4z=cFV`MA z+$KG8bWAP`n}_nkac^5(>{SAFCLn*h4PT4%^P4(aWIGIvy*dTXBm?x4sh3a7cknv2 z9ud_rD4B>aPk-`NT`ZU>y-i2MsEvCwQ-ionyQd*=y7s6gxf&ZAJ6mJty79JL`|Ky4 zbJ6OGisLjX0ZhTe&{NBq#^0 z6S83;iru`WxjBN-@Xlcp*R-9uW@l&&z?Pl0##3M7P#fQ z(<2}#-)&SM%y-6-U}OK9v+C*TQOZ%Z1yVXoDG%+zlQ%#>w(r#d*7ot^$IZ=6fcshS zW1pdM?v@nfhM{8nnkE;RLdB5%I`PeN-C0%n; zt0q7-DzUl0@95m{1xJhV!hE5_8zFfN97mh$X5&|4au4-ttG*vU9-ZdA<>RXcv@E7} z{k6(7`>E3-8o9K0r*SE$iJuP-53LP5_cu2md5n5jLaHWUr}%=@L5_MA*ykJ8#PeC6 zIy9AiQzQ)Sh^Xhg=tE_i#L&H9(W|HwuJjGD%qx{v^*XLN?$#MfYLA(8Z zC`wvH!&b9blSIFMeZckeF?~^D;`C-hecOpb`c*V*#-}IP>r~_Rc6PCB&bU$SK)PD~iuEcTclB+Y zxh?+JeP^_$bLt*iY}QZa4qg z$;P~c;(%DkI8BX1-cY&jJp<951HtI>hl(QFW5emYA~cSwukkFO+MixCE&TmzPGNd% z!8#VFcgZ+Q>uryE+Ef3Q-J+o$&kt5r`+Lje9Pva+WevRfpoF8{n#sw z^_@ROIbDg@83S5Kc(X>G#n@Pokf^++>DulUw`372xW1zHIo`7|7<^s%2~lQZsVt_V zF!D<8zF-CsqIDn#i_dZUS5s3{N5^_j>4YLPtVNt-SFz~;P~@4Jv_6TT za%$O7G#{&?prR5@IrqJF`cdnBR!*vVx?Q-GY00QYk8h7vp_Hx>GCtC@@RRS5jSX<@ ztWtQmxXg1q^PLi6V%1J_ExxysMhRpHYKHH#xnw$w7Dcu^i*%-mvJ;Oy{VTKjQTyKb zXcsn{T3JVHs$FFeebs)vWU=>rW1nET$kyJDgyc)0SpGOWIXQGtQ&o|{RsaD{__wz# z`>8GFe_VSuHD{o~=O-uSHxN3oz)wHjs*lbhUpvTURXtu>skjyMAfyV1^zqEEgfP@y zVW`s|a@#CI%Mj;!Oe2?=lES9nf*m0l8lG;6#dOK6P4+nsF*!u_zuRIuQsXRLDhj~! z&om|<=O4$#JtY@Klc4DS5&vU3lNLF)rHZ%ND$=c6XE7~dc|0Wj&SZd2s3F`|n%W&fWfR?q%$+M$F zh0W4|TNOn=+hovO*D3GgStF=w1EqbhZKCg4Wze;QxK#kwll$Z%%4%v7Dcz8yq0@V6 zKlit~_At#9zE|i_m|Rv+pkmmk})g)|P^JX6e5b)h6fueb?}x zXD>)?Z(RLAaOZzcxBLI;61|Ib$QYs*&Q9B3-3&diZsXe8^}_$VH)t7&TR_d+plJU{ zYvh{*Thrnp^HxFC@lAXw6qTWoS!D~2kNE)^Lt|bi7E12I2Oj*Xs&^|0*;0%l#UF}`(TZhAC73c%;tukmjj^p-N&*!y;TbGhXxtH+JX(L1N zdM{LRI}>VlnU^{TYGk^*T7x-S``+k^vw^-tsI~LU!I6u0PtSFF2X^k&K7YD^>MLFK zVX2J9lf~@LCF8_BYZHZnmm(+`p;~0SnABEoC?Q(pU_gw8o*)fiLxmW%RPInRsHfNVFI!J-qaGONy3njG@SROsbc0+hHurAMd9&{J7d)AWPyf~S21VyQ%QUvmeu3Z8WA$L#=d9e>RpfM@LFfv zV??tnPo7M^(t(bXlFx}-r}oUexRz1tmVWMzUwLql_O8Kc@e+S}VZIsjXB zbJpQW%RPKola`kD@^NNvZmMx)BDEmOj@#u0FOS24MB~UK0bv=q7ihTsNd$0F{$hyh zi_M?|AvypE39qR`#8v1+$#nl?oA^=tFsMR@80b|rPhA58MQDQ}BZq&gfShc`ZfP6} z`q9yfJTP2`qay1HJ| zhOpcBj%sL`kNYGT*0ET#yk?}qyR)*g(%#mVZEgl+=`iMlt5;Yw1}L$Ojm`AT3<$YY zm6ah3LE~9!HuO_355VT0uP$OKvM*k|2>Hp*@L={WC(MZQB+A@lhB%91sapCJk*%VV z)P~+R)+HHPpy1iqip_7|yE^-DE%0 zSalW#sbkc=5*k~5BO_%XwMIphh8sphr3ct$bH2rdgoH&Y(PDTJ68zWOCSpO&OimU` zi5?2bTzX8iZO@~|W*=PM`KIUQNYR`8vAOx#Zq}H%xQU;7j8}KF_yES=0|N@W5G(#T zX%wI`5l-Sjirqymc~_Ld-dwBa;4^4#T>-oT=(9D@#O|}PveHvims!n;w^nztw$E&3W@RbtcP2tg zRU_h#>jYG!5>&!*6*~D|<&`zwS^U=Zb)Ut>kcGqFdsWF0wxw53)71=#ivMU9%h~w^ zcy}B+#i9bX$W(}0kSs+wL?}#+kXpA_nb10fDvQfj68(_zB|EmhUX*VL?VqOkwu&WRtt zehC4k2W^?s2Z)eSM!wsB{Rto<#BPD|7o_{u6}$e#_0|8^(hwazDp+hMp>bcZ1x9FP z1<+H@hhK%rp8t9G>aXSVmFb})zJA>uL|A|-m#9ZTPBxoZ=X&@R0PUclAa%yPygcw& zS(U3(1{EWiu0FXbU1w0JLXYcN53T|I0%bs-xVX4X4)m3NpJ&kB;EzM-=;#<3!BT~K z@1Ca2Kc9=A0-@AnOflfmz>i|h^F3?tj@&{eQV}HyxSLw-ZSZL+uQ2U0v^*$0OU6 zwpN4h?qULn%FPb6f8GHKsYlXrbjq37>r^4i#M|w`dLa{>r<*aBu~Dtdv14t+*sBE@ zvcY&k<(ig0we_O|>S36Iob<8Lq0PoLq_bV_5gH7iPX?fcQD?VF zABJ{33;Q(2(70^Xp1l2exBKoutn0+195V}#3iZPK>l4J%$MJJ_>k`YZM+=a7{KeTW z(dPfHg-~-B^Xf@|WF6BL-zW1xmeiGw~(BR2>@FATM8oEd4zcNA~ z#pE_)3`kS$AKPmE)GIDnvT9E~dN@mHgJ87P*PqnSooJUI7;4D(FZjwwDiqfkH)<&T zTwhSwMNws}=jZYXlfyp=KHeomTEq4ME|P6hgLj5Ocx&}kV_2`Cdd>pmQn(x*-EcrM#%6T+p7T>JKQG5X}=RN!}2fmqG#nt{x1-Wy8 z@60wO*;6^0Zx}pHTuNx$CiEn3dp3Sm=fxMMOKX_dvh5=A?v*@x>gGRu!#ypQUYv;! zk-37|Z-^+_OwH$)TU#oKh*EF6iEgEGn!S1ls9d*ox{U@BzLLh9f+$hQu{chKJmyz( zyDRvnYhTW6iY3*&UQ^3)MswKzl5r$@eamJYJjhD#bNc(05k*!O;&ahrvvftSA zU((0g&wpDxEE4F0X8V-H#C$LcgDfpY#=Gaw=y|E-;+~fyiey-Giob*@ULmIV-%}Jz zmyA8^+V*POtL)>rgV0CR#MPFjwG+aG`rc)aIKsYqOozU7=~uRPC{M!S3?b>;YD$C09g|y%}NsDyK_Ggb%jTr2ImIB^^ zX6Jtl-Pc%e{m&srEsc$7g}PU_eeL!CArJ^@y#5}banXjW5W5ziIMfRWC+Oztr~h;L zx`NZGFWWnT7hjgLU;p##VC}sBF>Cw(zXjrlz)fKpGxo~Dr1xLzmsbC|BhBE-%1ZF( zMMMmNb4ycB?gh%!TTbXx3uitm-S~TW!uxl;ue1P{pF1=JpW^=ZHW<dPb@o z3qc(W)V8oN68s$8JQW7*Kr^?6KUHT8!w8Iu;(^kr(>WoUXA&gozqvPW>@Vde30g`L;Rb+oZJNN|wM1>9vXjgz$ z!9qeqOKTz#73X$-)D%FD)Y;mcs=rOT&>4r&{bpi5Ugh}X{U1PSRRNFYTx^U$)ViG5 znVPPEe-{dHzh~HM<%WTY4(AjS76ziVJ%)#apFb9Z*=cuCAxjbL+im0Hu5e-6H1$e5^Q~zl zpVO{#{+kcbr>iq|HZ>iB;SDiX(Z|}cHPh$`tvMGLsFwi*03{>TxC6btyVFQt5U%9a zo^#9jwa#glTYbXVZXiUcm%U9`DhqcIeDNXzGeS~PL*vrL9YUuB)DWG?`F1N4c!6ot z^3+P9?zRAH`bvM!2>5Y;4UCw`f^Gsh!EJ{sAnw5umz|vr@-;L<_U!VkUK^W#$Hc`! zs#Mhc#ztIZWCi$fcNRK9MGCTqGq4G+udl<4hejDX%7&d9bI`JHfU;Jt%3%v0Z#YR5U9idP zKKb$f+RED6*|_tDf`USE!4?9%)}0GjfYfwl=0??@U)M@OH=xOdxP z%F5x;4+R6u`H=rzI0hy-@JvjcW}EIuruKAqgWV6B(#)J3A}lQOfR}K>D$AJ$8o5+3 z+|qjD5fj%qZ0Q8N4F2}*$D9=?G(apX0Bk()w-7g|51zz>hXI|0|FOs6$qAVI9`ZRA z6%@#Q`Wx=x6O^I$;r)O)4ZeOPs6Ht{CzW5F9gmb@E?R~+y907T>Z6Nfh6(^ zE(2R3GhX+o6vJ9SbEP%I8D&afDTBS3uib#Tfl0ytqrNTY17K6V7 zx_PJlAw&O%T+?q5`qlfxreO7Q+-c{4o9DUjxP`>Kq`UF(F1^wk)!&nT_kn>J2yf%U zw_whPPgejf7qSyh>^OTrsJRGy`X?K;T0$ijV@~a|Ldl@~29GSm$s$-}?N$d#$sn7d zqo9QIIhPEX;Rf79B{)1jzQlPT|B!X3NQ8lmhZQubW;Xh)1dU&bqJn~0z(_JXt9Rdc zq-5a{ikRcppj5#dQP| z=BE1;$PB<%jS~Q-wz=#u>xB*m)uPKjoen&*;^J0%bT2;Nld;Nzrtng(zB(j#BqLN+ zU46Mj0K6-o{UMOd0%cxS#(6Zs^;9Z~9qin<(a<1q7Ju&mW%@&!lOSn+#~D8kp;_34 z0&oO)T{hO%t9U*5hCV)H#jj-yLx9}MB?w< z+RIAfvMUorDP`87Asc*NJf5pj32tgNdfXHC`#3l$tcrP>XY)}ApC%xVMf{0#=-+MD z-CFa?-QL*=!P3WuXCwy`0J~YZyQM;gN}<7+%fT3#6+{Pkv4Ql3P~C#7@9gh?_4W1j z_b=6bk)v7+GJPO|n>#!4E(6!AsUBTmw93&M)W3_1i<6UY=9rJ{!eRmgF$oEI9JlrS zL|9-W9DQy0h-qH6UAqO5UoI#$g3~1nAPIu84&D+I8{6K8Tg0H=SOk4aa0CN287z9R zB!dsq0Y@|(fxi7dH2XaAY4*%9ZFU3SfMR|HQRzWbe zMPT9L_CqR!1-y3i=iQdm=bx;eGe`MK(iDmne*Z3{2h#)Ah)elUv1$$sh;qjYX23$6 z8$Sz+H54LHv+&!mM~_jx0MqH^%z*Xzw@ERG;Y+=9TZaA}o)|D0KvfT6T|V=b2c-GR z`#;C^0eZ?-EzV3&Z(0}V1}6&a2GHu*TVo*sE*KCdK(ZLDb8S(rdFKc-2ws~#r`vf@WaKie`P~vsXHdC-Fx|H5 zP_@`3qy!$KUA^dg(O1N3Wbgx{-gKF|x;iLjDvz-C#~l{{V~Q3fc1%9)1KZ6x1T=LJ zDX90Wb&z-N7dQq%gysQT4)qE;Dyl-Lkcdc$aStU6iyT+;ThKKF-2huhyiI!*1L(}Za{HP;w}5%M;S%n|Ik0l+vMA?bQxK-}8ef}JqbV5=bzAv~<= z5AiykA-Ql^FJBN6D*s+1k_7vXwDd>|xU`4R9jPk8?hq}uRbNR2VuORRiHRBA;uxrv zG?2zHJo*!V01E+I0Yx$Eiyw`QL2v;Mf4RHIcl}m)|B$tOn!wiBk{c8nx<7GoZa>=; z0KbRW%FD{i`aaCFQI#ZF!xGgF6(m?HYP|-dr){bS6qcc+r&G*c>`Ci{AkS7;%1(r& z1?#ibfQJ1UpwvqKPDfWO)FS}E!8{2MYf#7q(w3|~&7Ii?@anrI%tjXA^B|h21QV&E zVkol$kW?$%bFE~7F)?S5EQWulHS59rjp^<;DTZB3Y?FVQLShN-PS>gho$g);c*YN4 zA0#k-zR`+`zqViM%BFhZ9a4JzqaUb|K0p|nADBn=&1D`oHzJWHIzw6~X+msLqrNXXvLyG&n* zcuHWnAsyf`svp7zF1SpZW`(M-nHZG3u*Jqejf->P(CJEEtt%*RA*Io3Xv2hs)Xx#s zo`OjIU&Or!SXJ4!C5%<2B9wxP2^9ntC95P60Ywlci{xlTGLj`5KoJE*l4K?493+d0 zjAY~xRdSS^p~nI2y0828yLDgp|Nisc&wC0E`|Q2eTr-S0=a~Bo5@lDGX9{Vp``#Q2 zzIOu#2{xD|iZIxWGp}yh7SWni{dw!mj#UBVdQf`nl%E9rd>qu1eiD#lrU1jYxw%;e zEsdW(-9|jX;8{A7fKcH&+Fe)Xn+j=chEh;xc$^$eQ^>=Bf8%ccQ=S*0g4*zv0gRgTCY3Q(7Wd$4GDn1@avQepMW5cSk{76FR5XM;!F^tycY>dH za18~E4$??!>Ng{b2)l-vr6ujj8^TSA>Y8>_4dLNO?)W~A{iM8xPoEohadF|KmbAAo zs0Gu(804okLHD=NHQYdEt5SkO#Pt*03wbm_+{P_2}0j>ic5b*P)wp5zgxs zHvi&sWuKZie${~iBBn;tv|Q83js0QSq%6O@U!h@UwXJjzY7`*B;$}w`qebpQE8h^05`MH#_y# zV6)@J1~lr*T+}n$q~D72_nU~`jQgba(l-6tpiAf@)j;*8gfR0Ofkj)Jo6#K&6b*@^ z9sSuQ=A#C^t!s<>T54Kzux&rRtoxCv29OHtRizaGWr5Cr>yLK-gLw@*|-$n{P0`*Ld>LQf>p~_J5A%{=X$k` z27UYk!}lE$$nV*>jtUBzyE-%7x$RC9rWTN%Vst@rggjr%Fd`ZcH#~+>`+g=Rhrdd-}2_d=G)gH zs=h4BskU?DSm%K$>j+Op4XfLwFOM=SCLTC-%h~y!jg13Xoq!Nb=SwWqCuy!!@^r*c z8lub=O{>J#*8pW+Zf@9tOm1><%T$ddbn4B+Xh6e&P6}ZHc&xNYcq7R zo6&VY&oYXSGjU4cIf2n`RUdHa*86km;abyW%$Y_%;LQ-jnW2}s9JGpfcJ3#}53A8^ zbm@?LBANYi)l$JRF^6>Bbi)}7_OChbZNGJSpBDW=Gh?A{r#XM_=1=qRo$gY0Z6nsN zyB438r#(>*o}7(Pq|G1yR^G$xM?*2ym^ETn8P%1vG#WAHetgA5z@|;Ntg0jPy$5yT zWz}O9qan0=4z_smW)w$UM%8+c4L?Uw!iOJCs+t|?uJU0iMygv0jm!>C7l$t-YMh2w zjqvU){C#-tsaD#vKfehsOz-w-`myf=QO_rNH2{n%h0L^ZHl~Y zYA|oPRp&d$$fF^L!dqPGDM>;z3n8g03C$r=skhW*e5h#KJQo^RI!=zhHNThF*Hqbk zR&fuZVxgHQb&o_wc<}D+ST#Lda7jMQc~R*+K{5;T^M4LmQRZ+tl1u}5En zfquhiJbUZdqY<~qxQ_{k#oDQ=X}k+RA-LdqS$47MXvA4so6MiS=1!`<%*Jx1v^yWyCCP!JSel7XkkfNP3X zbHM#XIF~wtJqBN|4+ z+!JsRyb6?rtU&1HgBRZYP9YI=#vD&m#wKevP_HxeH3fb&!0VGb`UNb=|Y2% z9oi4XeOR`8KnjVWwL*f*!82w=E=_dkLdht=M?xwd?)m)OTqU#^96P`&b^T^#QUbVb zgb+jDzo#NjLK{Mh{&C>HI87NKrG=hRHOg;*pZx08D{$cXjQF760^P&Vave8PhJYWy z%PE{&6Y8D&%q^z?UyOwvWE4 z6PG$rW^H<|kuR)`_Fh>=!|(L;Y>7v8?xgm*vVTplsP2tuy=|J->sH&>HdQ&w+ER#< z`RQ_@kGiZ`*PaC5kgC15<|j9*`UYH;?*6>e;?`Pb$l$4i<%Tz;tgL+7*Rrpg?&Qgo z*RRhBd(}M@4hIAR|En1uD%KcC2{QDBx(%^FpK_#v&Y)=#?kmsUKLLKIVSTZ#fJM?( z4DQ~&i;x7O&;tAtZle5_^Y{fkL-$&p$4x|h23zY+!=Hn&3_G{~#IrtQ&ZP3LZoi!h*2ghz6FrkZK zDexqS6n4BOw_qX#R~9E~B|&s((O=t51h?!)ploRz7RQVV<|6fq%%_gbla-^D3&tLLX%^oN?`DTxH?A$xn>MP-4xIV$TW)!pnpE99 zbwakX^2w!@8Ke7b$K`~@*aF{<)U}?q)0kB(N|blXRbVDp8`W1dyXMKocU73oUZY<& zs-Ql0kT5&4SlQw1+|^Arq7i2_)~h)#QaDPreWIJwbU>%Hd^_HmRmwLFr}|KNFI@>U z-EI^0htH^(is2mdt%z>5{OVh$g3ekI(Gi9mGIDZ0l&Liz1>ENL^r;mVj2)f+b^XX0 z8Bg}rAj+ZV=C*)pycl)`ez%ASlwu-e1#L|1c|RWlzPcEu)B1J{mNM98Bs(hDIu_Mj zVn)d7P>_=|M-f1fX$dC@drIX2lZlwF4L<@pjJ6L-4|qtxy7sz$))U}4dbArrD80%2 zq>h8bie6%vQlWjmvl_A!0Lf=sO{L}J)euZq_D3DGqLZX!?V$u z8OO|f@8>l^1ULoV0uiH4v6Q?@%R z3r9_P_tm*lji`jxXy=85B#;}%vl#0Ti2m;O(w3i78JZp!2RZ0J2bvHjmlg{(TzZUb zN|{0%vYjv9^j>LuB^|b_Z6#8}hiWC;KU+BQgYAIjQqXWYo3TM-)l1XnKx2)=p^TNu zYE0jj-J_<1;AZVC49uTvk5`C`l=#RE^#JUXABP&TJG}{VXTa+KU%8ZkX_Ux&j0HqY zif9w*KcK{kDj7`l^r6wweJ~w3x=d_rz!SeCW>rnseq$Ehpv$^joOdI*o|F@UcrolIF|Qg{ z!>QLe1aOc(Ri`cz&Y(Vm%tMC`p`R8ymY?4a+LYKt46hQ3Mh|0{YsP7804k*IaiebcD9$6l%T3DebJAicKXn< zNsDJgDvQMh0qhm&0~}c;qHTOrI~952E)H7X30GX%V%6cm)U!i;WS4KXmV)cWvw182 zTG}bvYE#q0jvs?c_mwI)*-U=-D=)S@)?sUe{KFN7_@_i59PtH@S)WX|9K&{AaC%r< z=a}&R#OcF6{wQ`gg8lFir5XGAlhOnJ!t(OM=;{(f!w3n3e31U|VW3cCdV2HTfG*XN%ExVpN9gEfWP0=Fy&+S4G#9a?EsK^@!-UyWp~tuop*W*%gap zL{AK!9-qy$zKRL~?mm(bflzfXUi`!*h`$Ae6dYh!%(iUPJ8g-=Sv?ccU@)x>yzs+q8MaT_@~ zY4^!wERbvBVdaHv&C2P48JCsxPoXutM>>?!9m1TcXj`JD;(`i|pWm{DWmtoxFp zWdPR)3lmTNilfc6l0Wagj#7PcOl{z?GFhs34+aga%?KDLvu~4qyR@<|wAkuwy{fQ@ zZzb#gE6Q9d?rt@W-`^wLWmQ+QHIuGdWSkRZ9ka6v*3R%5stA-mrYCH&r=Y)KG-PDP zVo#9XH}*l7>BPdh9F{#_Zdcm1SKss!&7z}Ds0#GaSD7}v@?K#(BcbpL?e<-iX|1-5 z8D?LoXy%(2n)hXk_fUEJy|hYeVM@{0NRFyA_4q6!81UrO%QSBGuQyL>a(v9qgb9)g zKHJ>ZrXE%2y7%P!8!7r-ybj z_~((4ep&+Da{_=hhk!skAU1$^Wf9e2fq^un0%|fLJ8jZc@(_U*i_#%_8S?W$E9 zei?Fz7ttGnW22X%1iB0a1%~$SeiD%mD+?Vfv&Di1NQ|JVp6KkD)pksIjdVd_LRY$6 zx^$@|E~$Wt9#|sL@4@>saHHT?p_-uEl?NnB2a0nnL`YEY;CMWBL^-Jz_F;+mJT`tkB})l`K-kGrQfK$jSuU5vUeRk{Bwbh*~SbQTMl-wF&N}kzvNK__a4G&`K-Q4z~QKY4- zpn8+RAS2I#yq7*Ux*ge24L&c)q!+BeIqkvbh>gZ5J|&h4jE=6rZ&a}UvMUuRFjA7u zYF%*yAHj7{T-?&7C!ghcFzV%cAWP|emn%ZI*gwdsJ3r;I#>(-_%O9FETIqdul&2U( zxf}2e-%})3j}S|k4cpFiPe1hjgmd=h35{%(pU|%1Tg4|Oh==OFYCJ=*xw%br^*UBZ z(s0GxbsY)2+hRJoZM{JD+%CHRiJ4_fBszQ>6(2YgMY(z~NjgVQuY-al|2H6;*R#XY z!H8`RyPv(m9UyWGX?&ynDW9Ti0Q4^+$&GzPT?ABy+-37MB<=NQwH836?a8WuIsMH+MPx}9SS+oH#%y>Ne%Qi59wFH2jw8G7d~S# z^p==x0lD{CC^h6vBjneB!~4{qm;1`JInir=h=CyzDixv(y4JGyz*28JO-@e2|1M)( zQ&J>c?n^s2dA@v!B9FLq_;y53eS3}WijNa|QpWkVP*7y$l88W%fm9zH3TKjebx=-q zzf<%1jEpOP>#gcm78XXv7@@%yTJ;R=noxu)$SiK(o}i$rrp7{#oZrQ;np>xyUP31Y zh?(btU($-t|ymKz{B^u5IK{MyA||NC(5U+8c5_n}pxIVbXvx`|Ae>Ja@= zk)Fc=(r0oHkVN;dp}(E%<^g+0t>a^ysr+5=qj&wUPLQsBxA%XJ8ME#0(Ec$*z4qDr zdY$oW`0IZKh*k?!U%QMveW>2OIMD#-OK)P1+s|*hdHIbLO$xEefWn%+_GX?O5 zUA-2H3vC+Cmq4x##ei~;gRJXc&EKq#Jwpx|H{Dk?d93MA~^ zAkARR*fuRAa=c<&Y=Z0iq1Ob$KY1%-o?$h+!nKwD^y#lH1DbE5;w+-%b*^vNutDrX zR9*AfX7S2a9k*+o!{@GB$QT%KB`2exj4Z*(!Hf%lFd!3sRLTIPiXhJ*6b5}p|3cYl zcxbnR`Z4(j|EKRenCNHE^!qy*;g2ze7Q{ zQ_7SwOlLD$+9O@Pu;lS(TJ@>Enh)BXprEQmKz!}QN9byBNJT~MhYM1AgdR8_NQt}^ znbwYs?(T&o^9JzBJ)yOK3pWPtv^1tQxVi22fXP4Ziu#V^OVhM*{5??ALE^Cw)I=b^!TuJ_5-;}FRu2rT9b4(9$K~b_jTWO4vxKhVdFLJ zPCFuTH0L)Nj=#>tf5YMbb(19b_iN9e`x->SMd=Z`_>yaMacIco?jYrQ_AX=Mr^Uq9 z@!cLmS3T17idaAWvKap&5BUAmFxFspKLu@;f;;yWf@oH7g%l5O7ENm+ea>T>`J88$ z2u~~OHnW|Ek$AhcjV2_0RsYWJ=aIHc+r0nyFvk`~VZ~_rt%OYrO;a$!QmS?nLFTXF@)97{6)g*ISf}s6d4z80QvZq?@ z|1yszeerS7dq{#_5GGPgB0c)>;ct(MPN4eZv+I70egR|+ri|#918bF@=Ui{DCo6k3&aW-O~GWXcp7>DIkcWDEM&1%+(_|Snf&?l?q+h*EnAF}pD+on z>PafC%?*tg|HIqp9KzYfm7Janckd==H53X-D-KJ=)xQ7jx8J-TOGTyqU^c8gP+1%I z42YYYS=34Y=RK0L!`f$}wRT4mYP!D0NB>g14X@Atj@Sb{)^QCvhzd~4AS(=NG1rS> zrMGr?ynFW!h+P?L*1(w-~{{G1`oibIai-!1NeQ;Y>CFL#_jG@k3lA7CcdIk8u`>*=xJuZ0eU z|HK`PTW=7k=Y%_$0hbwB8&z9v;B-C;{H?Ct#OjGQXa$zqa{F zqIm}JE)>+lB*F*sJ{(%xCK>a;nX&)R)!@Hf0Pz3&<=Cp&)>a@| zq;B*3*8EBOmsZnd*&TI(>f6q(mpCj(_5Xf-+1yU}h;i}0Q0C|jzbw_isBUm6PyZbw zWeCx`z7Kxyp{JiyBui!Y4^(<8{krHwvAVDexeI$xxy6m6B(aD0abhtw9BEsGi3 zKQ$eUal^e7nCE$0%$JHQJZs3FdOfhJpkEW5sata<3lwvG7*40WbWZ%{+Ja#IvtM~! z@AA+`F%mgZjSazVpG6plX$4#T{9k=*wT=zz>^VO}VVIC!82t9}>?rr=zp2vya?_2U zoUbRv{a8zkM5i|u4~vPHnd$O^L}8#{gC&nk{4sjJJ4x|YPi$&o#9Q~)?9%T*lr$|H&SnJGM-Ym8iR8 zcZQt%aL{s-3%vT0<_zLi%Deqd@BPzl!Ui?fYai~vd%S`E1{*hRn{^p9KZ%T~Q@eaq zROWeDiV3L|>mvN{oa6=o{uji#{uB<+T&QV!{9<0})309%?%_UTEC~uKViHD38<Dj#B* zNJPS6Gf=HZ=>aQ)KfHMHqJqMk^*_-;%>N1%iGhJE^h82pQFo18iv;I2Kl)byzZ#lb za=q=_%7#Z(nm9$qta1^6laqKMFLltpMiWKCoG&@+r$#dV`~k9^+bJCK8|9hlKUp0W z$v(Qv+R&S*w*>)d{@EPuSI8qSJuovi7SksXUt1Gjd$aD^iQ`*=@Vi)4X%o(8 zgrq-@Jh)eqPtLc7bJM(+05S`QP2WTe=yFi6P`{3wDNQ&aIhsQgF$^$Sg=S-SQc_io zgqT=t^}JjA^=gzMqn29y(xq9jYKjQQEw$*V?JnQieg+94OG_i`rkh)Z!>i@e&Bo90 z=|=bI6m=z{J9I_3#X@-++z+d4bD4X`tHV&>qC>!R~MIfg3DcN z-MW0yZvXSbTW(?9XU?EJH)57o40xn_?Ygc2_gr|wakomJss}fdximC8X|mmIEP;oq*X4~ZNu}&mTRjl zUhuz^JYEgt&t<}B(ZSWCsb@!P@|*f>jbm9RoWECY*uEn&9l2ljpj_GI`PhS%WX65l z9wFzsi24#FIe9Ec)NWq}@Lr=WM_7v?+;*=;`uF|I0QYos2(qz_3}7dA!{uC4=lr@R`LLMUb%#&&yzx0TxXu8a(skaSMZbS868sr>QulGyi8mE_YzR3q6_ zAQ6r>(?~bXIhOlS8~0lv+5f8vi9DAdnZ$=ok6WQBPf{5dB!~G z%)s}^tGcGf4ZOL#Nusx_O|C3-HcS+ezdlp9IJHZ$_x)z-a2yyO^vDIKL}GxB3-p}Lyj2^@U0hJ+dpvWc81K*E-pp=*dwiOVaP8} z48e&nD7;7aUpSwk|Ni}R0)@P2R1=h)qE1MwgGSf%^TfYg(7#mwKQroUUUrt7^y{XB zmAb?rKZ;c=&UCQI;Br_4XTG3>P85UIt%#n}8G!>2Zq{wXVp=tfQ*E#7UQ8>Dz zwulsKqIGrlK%TDE@!`PdXT_g>%ASISsg^I~2~yn_OTKDvQmPfqM`>GCbR77NB~S7= z=47OwG5FF%qd>^@IdWv=>_ngVjMcoAbBWRZm)mR|>SG$@DKdm?Y4gI+{MI3sl)=7!!RyVN_c|Rk+sej^V=SGE)a>qW-Xkf0P~EC&iZriITKH6znu4iW#LQjRwusBQo=$zSo8sEuXX;d8({xi(1a?o@EJA45nrmiqg3_ad z`^a|nwm(D8B}G3-@SdhHGOGN-XlBUY?c7J5*!pRx{=tN>BF}}^4RK31b-Fx_Q19i_0 zhRPehKTdC@m^gOvH>Qon42GLlOPud6M7Pw>mPAjB+03mNq+7`ihPnpVi0F)}ynOL? zqJovR%8F*C_xFgIXJ>ydUAg0Xb?e>>OEko@tuVJleU-n92tZ|V8v4oTIfdQP(f zv-+wL`Buxp@%4daNlCi(?qvGSf^x#CY`2V-^+yw0&EiBq?9ZUs1?8JJMLUw?9gtX% zlYgN5+YdJSr+iYh%l(dNpzdiZ+8(qQb(D2l+O z$l^%p&!hI{ z3^@vK8~w%?JO*2>{I=C-i&=WKw~53Kr^J{q4LWIOR4sOQ_hp)&X+uVC0X<|)f+%A} z&XnlN3J4US?{Ay$nt8nMU;d^q7X6yYo;0HyPBG^eiViWV8zqo|NOuPEnoiCSP#s^3 zh|kF%a7heClNZt_BZR4@p+=MpBr2r{34>}KWz+lj?d#Wmu;yMw$KbQ=Xfs2*Qp(T{ z^dBHI;K#8@iMM{t}(_b}6ZP8qudtm@G0oz8n>U%iLO=eU{S zJ00K3&Yl#iGU?FF>)rNZ3tf$zaoIPTauafD^4{=`Z29@K?%5?nmGgve zECHf=J=$lSYvPYzobYGj^#6P=r1lBAV{WnK6&bbrwC(3&iat!guh=y4NWg)ZG!yxL z?Z@dn190MB+6kw3PjtVrr{ z_;a(@C5>qMN^c`4ugh7SYA4;cZMtTY*K%~84jw8pd0aGY(O20^QFcCTJd)Lc)8GvI z%I!1v^cA!@4aiI<%oCa-eQE`Ak9|GbD$GUiO8$t-Yp}lUrq+W@M#QTy=_aN)4dA^nH>6-uRN+qhH?SNd!!l(@F;T z>P)omx2@HfI#n)+R-2^itV2NonL@={b4DtgMX&PX4efbuzE*8cpG>4B$@F;5$g5I8 zJVW&q=`XW`LfN1NMqa8(V1_f?7&X)92LSxN4qmVD-L zY3CLN8e)I-R>6maCZmBL1MKv@QW#2eFe|qtR>mo8&MetMopyV+$x%L}f)|rETW;d{ zQ&(A27;S&<6Ashl9Gph`V$Y^8wJc@(j+Z6Io7Y&p5Ogq#jEXvTG$=dwhy;5g{Y%WV z@bbFF;s0QG>x1vd=uxGr=s?c2vd85~k`3S7gt)D)?tou7`EY`y2q*nZKR>G}?Z;*= zf9m$L)5EdF;?0Tl4T{}&rrNUy|B?L%kN$CoWgX*HNw1UENS(93JM-d1x76i+#(j!~ z6`!rl^My6%PZ^xavZ|Z!om+I69^otayfFG>cIKAo<0JH2wjU-Hs*lYVi}qtUVo@LI zMG&fIJE5$8x0hg}mI%!|Nv~l|>=@G$1%`bNTA3eI&L>H_DMv9l-R`GUB z%d75)IfZtdj>6u|dut3(yt;Yh2G?7<&|`Q7Fa-`A4svSQGKK+oiB1&biT zfu@qBh?7>bGGLDTg^8MqQ`tS0EZPP=-P&4Pw0iZg=BjMenS1|6vx6bBK2G7X zwbjJ?{3n()g}vHZ36&0u+G+J#j5imk8v^A6{Ca5(G96w=8%epkcn`&S?-mL_5<#O$ z`zD)v!kUv@DIi2)p(7_TIM2_HBkh2PzG&Lx^d~=P8CsitvIrFge##aq!MYq@MAJwz z@DN)20+&Ps>^K_oN41x4a-`YLEIH^*$Ob4ge5qR@JH@K|GK)|@8^+pKQy+vk$Br-5 zq+eawEap>~PLL~+=0R<;S5{UQW$2AhE&y&_U0j%2=hlL}pB-09?x?eB7A&Gb9z}dR zge3eDCm=}y&pyW6`qoK@WI&R<`Bj`E6s%Waz=@pK!;lFQGeAZT+Ld{1m6V4J4lVlhU;p zh&|0+Pz)|uIImY%@j3lo^9sM%(Diyxp+M#Giebqz6)!5{Ch^ZLEjh@W`FI9ADtHr2 z`Th3Lpkr~8Kwpl2S%5en>$fk8>_1WkdZYt5o3wUYE!FtMToHN`ML9>15a%-ukgYxZ zlZqm7(JyMWz}H|O^TZ7i;Su|EtEJw^k?J7A;%m{gL)w4@?ysben+K^0GP670n_|)V z;=0p+bAYlR_n@k%ia^d}Mcu*|LA4XOVnfch3jQVTlOhwdXEYLPJzpA%o;@2-+$euC zDm2!7*q{34OtQaMg7Ua$rne&{tZhpmlgzeYQIFqOtk`I^N>U3E6I;?PTvyQNw1 zijsc5EaXcl`<*#XX;F@(*v$At=94rX*4Ag;6XGaT0=Dha-@nl4<&)(msOHR}=Xb$; za6rCn3*C2Gh6D4jR28Rk-(Gfa&$U>TdcRE3k`w!tkdpewlk)p`L5IfY(z#n2l^K2_ z8V>2Mc6yh;gqIgabQKf4{G@!}Ba9~?oOeF=5!$b1* zyzA>Q;^Gir=R|9M)hD@y{vyde_{o5lwO^ULgCf5Qo6fj2u4gFBs1nwTJNk~RtmlcVubjP3 zdH>G=YsIuA8BEAr>HO3@e8r@A_2yPTcI%qq)sLT3qABTlPl}AN5bv3!?bF6bt8YlE zucZHKKm4bU^qqT{nQYRePNj~uConfCcplhFmYT2B|do>s2wkG>I+ z5GcrclvT5NB_PJ>viFz32wxtlR=Wv$9Y$9Oj5e{>&zs7e#REm}r` zppz7QG{4aNwpKXdgL~qqTH>Cad(-*w{Ms`7*;jL@BK@?5Ox(+F6`ZS+}GFX zgLk@}C~-H#e#Sy0r;k&*X}yW7ZOse8Yp&-Np`erH}S9V!|b~NM=ZnbMy0<+cWCdP)ZS&`{^=8M+{cla2Ha`|Y`yt0{}qh;@Y7Mbfm zvr=DLd7gA^wz2L<`Ipjzy%!iiR@QS=4`wIlr`uYn)(>+~kkfT^xcFu)UvfzAR`t=A ziEt@t`#`wWD#2{?jD1nileiQUlgp+F3G;&Q)1xo@DknsAUmaxUe{Rci^Oe+9mE9?) zb_uER+4q($2b^Mci!Gb_$)fd2!dc$vpc<=S}&6x*NOr z4>%H~`EaJ1H{UjVh1o`I@VN(6864~yjVh!bK7kCDyKO&8#6QOaVYWS$i73wGeYS6Z zSLBwELK#tNsH)0_HtaSpGdea}ez5n4OlAJVH!*K0>8GU@JypMSxp}JkSoCxc@?I|I z5gO4oZP03rWOFSSE6)-N>nM>;dp-#Y6*Dj%kP)Tsb=VyrUC*mC71-?pDgx389^ zN=S<8@D7xWjz1>e9`{m~isDh`U6xDnd6eH9(vGMoX3Iq=XVWW03XwVq*~%p_rwt@9 ziz6k!I)t^t z>!0hgzmDFrYL-q@#n+0GNUw=X7bw+Z9w=CG#@JA)D=mur`w92efQM^$GGrjf_WR?EpMg?@LYh$Cg0+3nW+ zvnz6^i9Pfy)ai-Knqwx7tecxWeJmxndhkf>9=R|eE`2gLZ!~L=&a&HWVkI`mH%TTb zosxd}`ujHT2{33L?@UVqJ{~3p{j_Px^HdgOfW@6HU^bpcQDw9%+h}K10;)QiA4FZNw2n-IO3KNxIXj?qV$(e^bQq*bu!`)Gh=datO`|o8-_WZd9IFL9w z{pW`8FX8#iHunn;ifL*(fC>pk$=Q>&6&3nL4>zL986IRT8r0l0!8*k6u$+hXfXP%8 zf})~olq*NYebiEJh{(uPqbC_%;}JYIjFhjHyEPRLBj>WN-8<=&@v)%3(ZJq{kxtBHjAK*`Sp%uNdbrvzwJ zuw-1|M_@U8J6^J~=!i)}WRL!-#>k#)ry8{k-6GX8Vt50dXXxna5(y!|jj?&tCRCm>eI^xi=P??(_Qfq5ewL)Qq%bjiNvXRsU6| zH1sn3ny&2_uGi8?(@Ef-pq9W73d3T82o-wVR(e-SuNxTHb-vr6s@lTxqdP%zYtfOp z#L8CBLi6sSA?&e=JnI&^g5~)^ls}{KL<;5p;4(nERJj0?=T4&50u1H-x3PT0In>(K zhfsP#wu>ox+tZIoiE(nGTf+vlcxdjx1ml#nvXD}4Rp7y{o@hG&2`5!g&UR6$|(Iu;V@e8KD4#v zqd;ch(du?|B}i5_-y&|z>Oa4BM+^Dpii!$i-vG`Rs(et`c+M{QIri#R-r9z(ZV3Jn zUfpoLjQ*Y;Zj^*K2o^a}*3yz;MbNrFiQ{F`T{iF|Lm|LwYh)#H{Sz9rG#;((O6cl_ zV4q2AKofz)qu22(^b3ot(y=k7@~j6oR(gO6Y7qZn;`iRYsB0o^i^jJ6FB{|-zqb1Qm>dqk6J_=F z_4QaBF})@yLj3`W_Vv?uKmtebfJBK(fIsmBfKLM4IbgFYLQ95Rw9I+Z8WeIulY$Vi z0QLPK-l}y;*ZgODq@BV&;g17NB?P^28$6hxd61V3CC7azo!8}%ChKiYc=(FXGLcfq z&IUY#pp0N*6||eLZ*SKit-+F_y#HCDLpQhvW5=*GV2f)`*YV8Am;&_@Dur1bUvV3# z=<3E&en%HdZ8ExWcd=_MqM;JvwR)_1?u2q9@P3INc|LN0&7)gw|!~niQv_ccrnY;TJlysrO5057I z2<`U$TB^yw!bL z_FrBZMz5^`De5K~LDzBq(WV%R>ZYa@G?NlbOyrpMuqajM+sr`kUtYN<)BiQ)2l$gf z@8^Sp>>rCJ8wb%s4fYTepqcen9aJaP($VQ39Tl{m)b3{wdOVjAB1xKpE+?IDcwCfM zrLPF;-DJQQS_Hv8tULH*Lc7!Pi1gWV~)o z#HCbX>-9a^@+7g+cJo3t(M}NJEAzB=rZ)BvsYmU0s1uK!39my@sYB5<3)Je!w=Ie1 z-#q51jcF2TX{Km_zjVpDpkNuA1bSvaEv*Ai1uANAW>Gbx03z6OM{o}jM~p(cps7mkJP_$Zzh7T{9S~+gZsc$(Nywak;Q6F&bbajfjkl zO)A0hx3hI4O2CjnbxnmPH*39?z(ec`tZ_hwpL-CLUXMAnqmTM|x5!O7Uvpq>yvziX zU3M{p^i1K*R2woTB_+oX9eRyMZ!pl}1rjsVCV_hHGz=x0qcLp)jI{f?bj^Nz-b&|) z|1@jL0+Sco4v6f(u@_9>N?;#+j{{GV0W}5V!mg8qEj^%E>+ffDylZ9_uaQ5G-feR_ zsK8>_d3x7E7_6>R&za#C-_dJM1$D@y)T5`LP8eDoTFG*}>oSxHoiLUabRPj;Ug7@2 zyI2O-{1|l0$Y6j71g0u&vF1ezH`iw3a{lE#UA=IkS?}tE z6f8D46Zp{cO6LeS4qSk^wKbK~tn(jC{QA)##8eV3;#7koZk1AqI98O7?i<7tIv4yJ zC%Cz}d3cN(V&y@9TWw7|0v5D=+Gy*sfKn-fQdu+2#l&wm4HVv^d(|{~h|GkOtNK%8 z1DgK8$${QNun}@#XkWjkC*&f+eknW$b~#AU!5;enC(jyI6g5Lmlz6_0v9XgJ9D|@7 zMCGzn;AuMkjube8I7?eeNtGa4M1nxEZU}k?tpw>93W$hPMNXW!3*Q&M5Gr9CJgzl& z^C`W#6Chw`jTSc~-_V^X2!8~YdUg5X0%1sM*s>dw()2Isr%o+Zg&1#9hC7-(WY(ok zrmSa*eM0FLEPp#ZUUV>kfXHc8f3GfP34_tPb`iDabc)Z|M@1E$l!Otc>40_NRf+rV z?_1R|I4hBl^@%#4D7p6GqF1%!xI6N!IJ7EW;ShtI75qk4Xt)%MICbPm7hGi+Alzg* zdWO-A?9`}-wN70)2ZXRWT_IrZs}8o!p{|B1wNcB>bL~4;Pl5~NwRiSGL_~Kkwf<@# zLUMn1-}hgwhxcFq0`7wTHthD#qK$us1pXH;_$Q}r&(KhO#(}jvJ-2&QUmXlZVgbDC zx6bnR+Io-9zXAvUy36)C$MaBf20d%nAW6MPqeX^5qRJEuw&+6G|ak<{Nl>FcQWj$|ed) z?F^%ic1%_x-Hw*wLI;QJo!vh9`F5ah1eYn@%}wig>bWLwHuW=WHKeVrYB6%~9PvW> z3QPr`N=rdzXSKXI2LkhrYR}L(fEEDQ7EE=4_Cw|m)OEAaa}O(E)K|bo0S4)G-3Bqz z?Vz7}_kvdiK||O@*Nbiktk7=o-oLK2R0k^LsF>GXV`C8RDrjkGU9Sv0=5#kH4h_&C z+pO~E5}$HQNioJuV7L*f&-KC5hxZ`)Zs$T8P5u@)$P0-KFsUxEZs43mL{i_@#=oE_ zu(D`M_Yvd`=;?wwVYZ8ax~LTeHAcy@H#(8G(18sWZ4kTgFklDNt$f3;mdTarb0=925zc0YQ%R+sFvWSk?NO>V5+^ zFFL8O=I3FK5lSV|u#5hQ=dP|-Wn~>HW#h)t>R=fcFp_GpS2KC0ulh%t&Io0i2dT2=+2#9mMzo5NHtf7}PJ85hS8eV5d&WYHF@P5y9XhBRr=8`S}6R zhLwfIkrEy}2Fm%U8~{OT%!iV1ziI){SwD(D5va49Y6eU`@dNd0 z*(MQ(nkd}%aeOW+x{k27wj4+1GC3?dame*d`b)6QAyM|JygUv;21tffH{7|3QB@s? zBCyI}z7{1t3HEdlBOtd1(*BI*&3n?#8^C^tsoC&WdGs19K764nZbsmAmv ztSwp+YlmC0M2c8!1bQgdzCc=o2n5kB0;vbrP_pFkc zL$f_%$|D&mz@)Ce$e0{yQyox^2oDFYfR`A%6D5`r;}3AU%LfCAWWI=sy>tOL0|vv=8ILMYf_YTpCr!HzIG?giC7f|YO{2#&vdV*|b@;@RgT zn6L`~X%v#Mp+%kvVR7P>u*a0&5d!w%t1&SED@8me7)l8KPnhiPn<8-jAWL)T-iCj` z?08%;F_4mYu+hpjlR4c$h+i9klL3XsE2a9nQ6B1| z%!f4>U7v_)1J7EeBCLY{4$2yql0YF+8ylOLB?eI2JjIro^~>t(>mwSKkdy>O=R|0D zDC7){2sA-*>J*CM&v-C#aS^*=5xa%~Rkg`g#6d*3J_45t(oN*k!a3-$UogPh;?y#C z?p|HR`?eT?h&zX2yK@~7!39Fm|5Wo_XF3&87&*Ddx#Mg z=VN3epb-_6>>lI)#K6tSRiB$JdEsNskjh8P~Zj10C(IzptuX6!YhA&|Iw(x^?z=SR@Lgl^xL5#i5Ye?AP%{^uBhsF|y-P=HI=`^Mjx;_TJd{5PIm1FVMPIoI zk|zXj5D$cTryZ6T@ndqD0`SDczHEuXC&Q2ySfOHw-K9}mup$x9Buwk% zq5!&*r_#zTMp_wJ!GC$qJdT4-czVI+c6O6I8j#J5l8J75wrLbh=Jyaqau@xX95M2CZ*TI(&Qd=ureVGymBh_T5LW zy8&KeVfDf&5ZI^MR3|49gnshF{(0c+#j9+28Dnq4bMNnxfmV$ukjId{kdTo4{3YN} zK#lM(au=GfvUFy~$IB`zys8{u4z=ZGfw~%9?=Mvp;Wu6_yxjmJ7v2E1k4UpDb_Qgw zFOMqt*nkJ$8q+`*fET+S;2lR?hcODWD`NN!KzVxc3xH>W5a-=BHLXh)!6Ol=s0#op zL8bTw1OTzT2fgQH^22IXfL;hJ7P2&eg)$Ktpi#8@q*D-CdU;~y>J+w};YB+M2S**I1ffjy zk_SCeGs?==!cLOgi!zCd7DN5>=+(S9%WArG zpFV#c7#v)fomEm%AwCZ3s=$BA$;HKbuS1M<3=}|U(~9bxxHU7-zVfV7CcXD(jHiF> z^Ff?t92(IP?b+mC6f=D}7<}U-GzJ5!V+E}P7ZOlkVr%x#qF=EO?E~O%I_G2LVuOEo zcHrmFUQ5=Ikno26iZBn}zT2n8I@M$@yd^ty?Quy4etiYW-;d}1%5nYr^85c#fAa4| zowpicouN@e_$&<(OTjufZ-ze4&du#LCjg`sy?C)PPH{A!8Q%L(qV}Sp5dc^O3$bW` zeB}VFG~bPnqyXBpA9aR_5-V5ENr7H901!4vzTv$Q-3~Yaj8rZxH;GMm;MzJXNt_&F zKHARD!%Q4$0ygDUodHCLC@x=7X>+Keva%^&xeiDST#CAUp$)6g`oa@53=bX@ftz>q z#}Cu7?;?Bl_yR_{v(Gc%FXBN;${2trAhF<~c@eM+Y!~Eoo3`N`ea4)CRZ+u=mqHe-b;6Dc{4* zMgWKdCSWz*1tpZG*#Wt0g7Bd68)mrBQUn8{;oC|{NaR88pu`XcVZbLs`o;FIRaI3m zQ)FAVFe;~p4^+a+Y3AKKiIfXooSbsjrpR%@S>*#!A%MTWB8%YFYK|f6cqkw4)NBcD1 zyjzu-k{GCGA!oQ$q;whuwv3L+Sy_s-$p{s{-8 zt@R9-p?;m`_q+G8kK@>Ti+%DaHjI9PCsms;fsvkVjLCw;n?NR4?yWFt)STnm-VbA@ zKRR~A+G*J`D&X-s^K-`Ud6JA4z#tvZO`H5%n$l|So9Q$=!9C&06Xy`ZVC|3*SyO(C zP|KpHBV^btk7aTf_|3(t8UL5;Yszg`p=O6yp`VEU&`&!fHa%u7S3U`Kb5M>C&z({`le)>>sE@Tic zZ1`dmGMgWH)-Kg(%1WhiDsc#W%-}G1aMoaVR^w^(Pmc<>%o=y#*=nkRcz7BlW$!np~oN;Q=Pg-Q?VpcOJo4 zkr@*eJT`5rW6L$_0>K8Jj*}>ETqEbQzifd-84F)OebQ$65{O)cfy7+>Af{bX)X!xr z1w&w{xgKe=G>jjONS&UR#t{sTj&|_z!K{%{q(ex(8XQ~zS^F$yQG)GRuF`rlH4*@a zka>@qW5yW&Jk4vWd3Ds;y#;=PSn9*|q3Yw*=d61_w|Wr-WD1~}><$@WVp52Rh>&70p0(;=;} zKE=$)=!1yVa>X5VXWaogoR_nHv>l|{vlp1HE439BU%_8JN6b8}V^Lc2Y0Hd3%<+0e z?ZS;b?E<6z4Y3>Pj)H2Z)WH1}Pm5C)J)@!*XB=j4D)MW8BrNQ2auExS%HE5=66PtA z$J`-`%F5JWaICGL4cVt5+^MqnRWjx?i=W_vYSXhnyr=BwYLl)|gT-yu-#4d=`;G41 zo1YW0rc~wo(Jz^C%zuct7?aaSzt1?^`4SCmQu{vsDRb_LeUHY>W_|^MKI6iL`#M)G z5?PnFmc9cSFlBF2HBfT@6z8!PP0H>`vk{I7@hFQNCYF;ciw&b1w+lf$Rsj$P>2S@aGOgDSt_NtTqu zR5LE{^nx>yGUaeKHn&f|T)@#4tKXz<6|DLT3xj+Nuj`ALQ^FD$MyPSP4R`lR#6ZF? z=Gp)3pRwskx_0)wrR?P6coom)#3LO(f4;CdDg&W4K0Jj*I`iFO#}Xf0>!nYY{>-TZ zmGYey(p=t@J&kOc3vtH}=fPpq4+}+$6&wUSOLyx?k~t zV&l~&@fMf$Ec$v;HuEImCKmApfO63lYkZ!SgsSZJ=|5t`38LhX%(-Bk^u)$d3!W5R zw^ZyyNpK{;L%?6?-U}?}fSu#p*2)KFZK_-R1Vp=nJ9h?<5V$RT`CrKX zF7EbhKFZF@dcr^}pd?NVxKSPqrOq)`M}4N4)F^yxUSv+~B(s!AMbSu=LAWjQyj2e2 z@%qi1c-I$1@IHeFpDA&(@Fso6OyAC!mhpisvdINY6PqxXyt?4(!cIe0aTB3fZel3m zLA2nLbdwu0bm+$?i6f#;kK$eImnr9S=|XF*-+SQ6*q5-yh~X!vx=6}F!jU|0Ag=hpn;%j{obZr+c!q-&%^5tf-7!}%sFSo?0TXd829lP!*XNvit zX`9#Y{W^N|XmJ-2u$pi>XYSl#yiVc?6U7!Vbe^ADT+>K_M10T>0tZp;q#*<+wXLUqD)wH{8vT;J3taK2c~1{3~JUJ2YIN3>P+v`NDgT z9=@9+NBQJ%(d{s{A>t!f;(&?skCbfQD+(Hk`_TUVo`fi6%|Um?>BT?3e&yg;Gae0q zz*2dQeO&|_3=(H;FPLmTDeJ4$Cscl&jWK}UZ>-!n$`q1;!(Jnz!nIjvxrsnWN}eOT zE?vIt_oZMoDr9ecsR63jNHM?PHNNo0dqHK0)=$O-(M^LWKn-_%*E!(&k~M2``Q#Mt ze`o6FdHkV8Wm!&t2(lJoOl#sq(Lupz<0sm!6k}uu5tQIVgXLPs_{qXKntL&6}~EQP7NUbQl8>MMaB%^Yyq&w5#&u(W4VMWDEmU zKqFu4VpTf0)VI-|p`6EaQ(q3|pi(YU?B4Y_q#xS^zL@pbfLO=RM-q!LVe&T+w5pa+!Bd1gMDDgALV4kZ#QIuT#Le);kevZ#xF2n)|52b*h#A?)i&*d_=f|e|^A#wmq*%XyI~lTwosi>#xU4IAOx0`}gNa zlzsj@bl^ZFs_p;=${7SSabG0FtUk&4Cw#~U%x4USN3QCrpLOXHfvFmN4F~{p+qB1; z_LWM7yWCG-YLNN|R%b$Y>aKkoK*9D0GjTulfXJkzlaj?%O)Dd%Xg0NhZQUV5o;mpC zjFXwGn;Uz=p0kCJTn%#vKWXL50-h>#EJFJqI@yk!%Q*W$84-n&>)t(x!sB(BEdN{{U7y22QgJ~MK{~CBAp|Q>1Q51;ZzlXV> zy3vjI3r{32tpf<}*tP2*92KJ!;l){E`5J@(?2JFV;z7(2t^6FUiZOgv_y&-Nt%T!> z6_Y6v_#K|_gX7b(3F=y{Udbsbh-t4VdxvC-Baa`MIg4VuZT7pIDBqn>Q~VrebQhHR zx8;1xP=;@!B4?TC-XU5OFnSJI_b$t@W()bWq$ZI;%B!56ivgvZ?*HNDrkv4BIYZTE z*!mb!b%zWU>)yZqVn4^3opq@;8SGgU7Z}-;oQ3A)Bir<2^C&r5eQCfOCcF+e@+fx%HA248B24D`rV)}v7vfh(zaSFKpVVBg_A zd#dr`(K@RpY?qPG&v9I~Y$C4KcngL>8_3EOoKJ?2jn9GK@g?#7r|2w7!uIQ0%cG}I16_? z|BeLB_96KVi=j_AGRwavCa)VMr!`GZ_dXmL@};F9qpEsmYX3WIxh?ij6FhJ}1S_O|?K zF)F_d>%33VfIWs!IaUCleD_0@PWv zee#Dd(3Uy~+;nu>;veHIN^kK0-c2_n6pDV@e;tY=v`K!iemq)D&HQ&1KOYf1@$JO- z`(gGsmyU&ph8^L#lK@3p=^#2KECwKP)i~+O3#?n<{%EXx1R0{kuE(W3S0(_A{@$+Z z4taKh7Q1Vxs>NkjcX9;DQY=TNt}!2&)8;WXfOKoohxcFEKkKUT9(_s*89@!sw(jqmOcZfKkdg024eQK`>v zlo`__>c$QZr6nb;1Y9jYwc(3SYW-P+_~Dea=h-vL{iVd6eB^5?p;zG0^>HTsU~CAV z#pE6F1n^&N(g_KTtf(?7o#s^^v%cH$PwYDA_C2>46*d*(4pTm_T$^obiZ|g3$~E;WL5WHVD@ILiZ7ZzJ6_Pjj9diSZm-^U7 z<*vo=*?w5puv}7?U={farNgCAoiO1GxPh;E8WSID@V1oSl>C0TT-0arTw zXIC;yHMSQ*y5TtnhKSW0*qI;WgMELg+)W|rpL%!c(&fAB>_1>?nYl#D8CplQKDZN7 z9(-8|en-DK$OJenJ=`m_(Fi4LmAi+)N|0{cxop-Y<@4$n)QL-V_ze8sEB0K{(+_-o1-CE2IF)(jSY8V(ZQ( zkm$Bg&A58`@{rf$z#BzH?%=;m+P}Vl9$@|ni!6uV2w^M=#vEAflqvZ+v1>q0ge!4t zIi?xBR$T9c`&JvzovQ<;Bzch>zx+v`bw{SZVMhanz2>spQXEbW^n0%hOV(U8nucZS zKzO(%9M!v&KiFyL$wO=34nI5NRB>cKTC7TcMSm!Yn(E@_mfSj*LReff55tRxyJN?W zeA*GJs^_ph6E(fr5yxi~R|#RA5=BowAT)Brj~}#B@xpIF$nlxt=8xr#mGU11QdY1v z|N4b-;ViIBRrMi41l$iq_&raLI2iBZGCM4SqkD&#dm#6lLwPg*zU%HoqE2KC@=2bz1do7hrZmK(GqPvH*VZm zb5*H;G z(`KEO;o{^3f%gy&Epa~c7w;DoB=X^@%WIYm)Ao`LMB_yn(3ITo!vb2&6%Z7k=(*$V z?-0?=i)T~<(^uwQzb-BlUbAKm+PCPGsJY~x^pDL(XbSRqo{<_TL-G+9SBV?3xirvc zC}L+9WzO}z1}#GQ0#0tmMkg*Sta0fwdCHW{Teet}{FRkWYgTjBRDO-+6}&Gilj|OO z*_uZqawVXn9WsPS_8tVZWk5R zQJ8V^`Tn)g0rTtdn20|B>?UVX>|4Tseg$sf(-~YVkh1nVlb|LY*29U zKs@f&-TsuWg3n)lD3W}_maI9hdfHN|dv`d654iJE?X;+Kc|9XAT_`FV{Vw?S&xdRZ zYT5FyKJ})9&2RtR$=5vN-_7kc+jSjf6b%5Qp0ob>SHrE4Ggck`_mbWJYg_vNN9@DE zJ3|FUnJrs>k(IG3QC_~{k?q^Po5=nMN*>1o-ix1PzSpMUQ?ZO9N<*(azHwv5_gqF* z{5;k?TXbKOL%N9lGvd-$jwWTVYpV%w5K1S9r0nkQPQDbkSAA{bd$9vuQC(f#U-D}L zDh~kJfk*)e3Y39)#vw|Jo4H~iv8hm6y1#y9wPK%n#7Jx|*2xQF9ZiYSu%1kWADIIa z=Y-`5ci|tFYbX>QF*g6Nfy-Q7j~+hE_j*9BBq_&!Nmi5BR#xJ~z6u0@HL9F^32u~3 z_4)H>@GBuz#BzT?5R5`fax%IPLAHPI-X{j>f`$n6$Qj+_XePkBa1nP}^$7q7a*DC< z7rO^1RPsmgjJ}YkjvhI3Dn3311OdHv=|!gaVr56zS~q1CBOJiD(D_--75h^9Wr}h7 zk=IwEN0Z1&rS~3-Eo4}McgUb^XsD~-YfRET25f?Hy$56VeJ=_M`&Ry;D8<#dTsaz} z=HCvq=`+USB-xgy*h*rZ?|%96<-LP6YIvndo5aOF+$B27`YBnlNniu_3L3DnvGFR5 zH5WyEO?)-LKQUI}*I1Mk4;V(OV}2IWP(6G*M1*6CWDJpGmc}y#J~B zcUnoE-}|VX+4&7qN*XhD{O^CtNiDK1$~d0$!`8Jl%VPwaj41z0OZ~|zf}nEnV|DdP zH@6}E`_GDCgIe~!>c9O?jp*SV0zq5N10_BTW3}m$B{4wQgC>2p>dDGTbZpQ6$?dtK zrfWkf8`ey5sR=PBPZ}5-C!RdnQ6*095F|E7+-M}V!|uQSNG=f+zRuIL@b29*`95T>MT-`VA3r`=oe(;W;%lp3J*6vu=P0{)U%hgFoz+tSo&*3> z#uH=M?S`zlmoR$y@@9|#aS(T2@slS$zPY|pTC(B+<*9EG zEjF#(2v!!}?5m`72F*#(g80(up%0iu18t*wq zSbjwmwG>Q6{cf)5#fv|PH(k09nr~~n8GOY#4hRs!j5-R~$F6x?Nl4grqwK@SkJ!ID z2=mO%%c`o1A3yFOG;#6xAr*5cQN}d@&4mC|lt+&&7A#oMW7mn4l&E9Jqy#3^58R$N z0D1#WnD&$KW5?_kEErX?7AGfhi)Hfv2xu3*%6>)fog6Xl(Tf*jl$5#&OVSqd<|2Cb z{O4G4y2`WL&#{+l4RKT*0MWMggdNr}bMu~po{w|{9t?z9eqgQ-4U7y*M(xZdYQX06 zjaRw4M*rDwIWWJ0A5P$fVmrryX^O$u$a2OEhAa=HAnDh22chEcXV3f*x;bHc_s%sm zyhUw|4Y5=Ec6(-?Nlj%Z=0Hvy00ps%sdE(UCX?Me2`k*)9axjjKS4hw<>932(qmUe zS=rVKkz7N<^rzNkq1VIeZ$#RjAxqzu%j)XtdV4n$F`Zpp!k?)Z6c+v?U$7k!Q!cVH zPBsrT5mSYA6x*f>6V=rzyZQ)vkwSO@oIoSxHdm!@-@e?)9y9niY#N>`D`QkyRaZCO z!*I@=l-%55t!q}Sc)NCT`KAl!&tt-G_GtxhgJwk19zQ&gl|xKriOyoNw5F?|m+%-9 zh^mxmHo#B@Yw_#!(4+U!F9#gEEPupoNY?kFmoJZG#U&;E#GP>Z^l6SLtOXe> zGX@#ne5S#_f{{#6U03xDJDSEXr?fLw=$$$TCq)muyN|t&IvETE1SK&c@4!+pC%);#O{3+n-b%^>sv)GU?#Nu2MJHzOE-5 zdRlpJg_GpN73U)(`$19vIjx$SIFftqnqm(sv9}*8tfk8&Yn$=5%a^AR2ff4<>o6BJkp@_J_mZz%!vGR!Lqvlz0apLLIGMlu9^hlF3 zX^(aCe6$kuRRBQkEuUC7oP=CoiZ>zPC&E3@Ga9S&E6NskJ0yiX8-x>J%xcU0d7B znc09)JbfzKj)iP)L9jt5`(kq%ICyXefuo3r z4Y?~lBLgDcnBkwMr&3Z;8;kywtPW(**j5&3xv#>C0EwYQFrR8JnX0$^}i&=I6 z@-?6wPmHVR7jTQoTEAffO90=xD};|Z{+7`PZ}%%LeVG~?TSh1)7IhKmI3ka50L=T{ zrf)efubmK+lr)7rM)j}jRWFz>2%&sI~C3fO|hBLefx-5?VlUg zlG9SWz}obv;iutNzAryZG-(R~uOCI(Un)41EWiECGmnoB4vG0reVyOqcJ3NE>9BnE z+7Tr$I|?7NHd!^LMQGhhtH_iHc0v<;yEEB8{@VU!MT^Ey^ORS(|7nc(gJ0hVlr%Mr z@3*+UsdvEnSa0j6zx~g~^tPXq@%!MiFL!<8XPNc8;JfOVmO*{)yccaIU(Kb>M|>~u zc2o02cJ?B$V`es&my3#gKVavDix-KLk~^*g0bzfdS$~CT{B&ZXod2}7B+ANlxjZ-y zGRnmX`z+X%(=VsD=;w7=c0PpG|Y(gxQK}WYLC8LP;1?=E*8yLNLC$33Kot@b>z}4@287-`sEgVoOT%oy|Xm)twH$J>@(5 zaCm_ea58i!l2xq2?M@tcgp@Gq;5VAMqK6dUz^n^iKsfm3nj^y$z82LN%R z7wcy2#n$bPhhU9Xul@|jd{uczn>u{`yRXeQHZ}uxLan{8tb`qWuVfOV3%x>Fvvb$3 zM%_Y6d%E=%bB{{@`9N&WeY z!>#jdY{*R^6_capiZyTlqL=4he9Fqof_#*5ar58BE&SQklx%xpcis}ne$fc`_M@@z zAI~eOP2GQG&2DGsBD1R@{z-Yd#U|33pS%P(e0XIo8;CV&{R9CZ26qDrFq@fDrJA>-HU`q0x7Z z-mehy>$P=Zxi0MHLhK!>;x|t6Tet%wY>H+!P~)3Lbo`GWylsO|^OL@}_lFO2Hng+| zPdgG)pfqvx)E|>J>?jy3v1o9ayWb-X*-v@G2k+KHTHcU?AFDe*zZ%ugec3XMobrB# z&*yg$V$MhfM$0Ud8oXW2xh!=?lkeoeX0}jFi%cpd%sgA1aeMo(FVB6Pa ztEW|+6@=?%8tS7oOh;ZfkPnmC6_OORKg26V5T2fFUayf7InO$=XGN8D?aD9fu1$T_ zPEfbmFI46h+lFnCAx42}FAiNvKb=w? z-T3Or3QrS3Fr8~W@_NJGjiwLxs5!Tbn!b#59yCVl4_oo?ICax{*NQmT^vchA1JmEz>&&=|eJR-BvqzVzXB`Vtrs`Q2e=yDMEQAhHPtG2>PvTzL zTHw>mmoG>5S~+$2bIbionLe4=Y#(LaaO2~8*a4}kC*z<`^BwS&54>j=J%fFmT=#`dea#9-=CK#YgPT$ zJi6Vw{QLgsP?sW)yoe`WX}{VcxBd3-*4%CTzl&?}HMZu<=i<{vZAa^P!}4rkMYMwBijoU%@q`;^*^az5v49N9j;JWvCgD&c0C=c zFJHatAW-cX7~I63IzZ|+4qcod<9Y>y8z5V^S2SVvxssCuA=u>8O5~@fTM%IIq3C)` zbfl1=q5xAyIG_4U^u5AllRK{Z{+gt${8xU3xycN3b8!POTZx4LN|4t`vYL4o3QdpA zbnhQh+dlJz=q#W|tC#tmP3!~Tw{Kr;tlUmVmWTfqdyO##B2Pp|n;lLB@<9q_y1k%- zPo2*5@}J}uPz0Yh>hR&_k7uv$A3>^l{_I&M(@8RGeAFUr8m;DT17+ZYH(I|>EQ=Kt z4Gayx>uy?j7C_KAOWEH_!vEqb@D$wr+}X1~nw8@p#XXLX<%5f3E}UhuqO$V6f`Zs9 zTPTZp03mh9+HNb`q#M}SG-F*jH*!c17t}^kU~n^_F9*I9nDc$&iL3Fa>{K?v`$Ke` zyz=qGhtnx3zNiFekDmpH@DVBaC`d3x5DIzp*yuqlf`D|7(*XRedT#ID2Pku}M>j2H zGT;BseBROEBjzGkUTVGk_B^nj4e}4QgYxLnUB>g^!6>2&sH9|AjkU9L6{Z=en|1;m zKL8Bc031WDQ1!Jr!h`Px;d?SZp1*-W()Oh6WMvk#RZUF|-#*81>uv{o`*Fi|-dZ}8 zCD>Y8hqE3H|Mj$SUboY?hj!kchH;Ahw5o^i(Y;I0%8#q*9Su70H|bLE0_^U0l@-uN zkZ=m&l0p_O!t^tsg&@pysarbWw$lXag6j2~hx-a~XU@FJjF3?L7*BVG^WA>T^%=Hr z6Z{agL7}aYu`#_+(CHgCY~aDrlvX}jWf1KU#arGiIGwBx51V+gn?)>Qab0Y(}DFM`sIN~l|oD?;8AJwy&SwcjDmz~FRw;!Sg zDld=gr^D$h5_(lD%#(&W|KxJP*IP|bdigIefT^)Dy~hKjm>2Ma5+0eSw9Z9&E3+tH+`?u)gX(+GKcQn_h9IQ9OrlEUbz=hXgI0=kRJK3UM;e>kD8m1 zaOzYq6_pr^X_8uJ5)<*u9llWpErCnAibokxXg4o%x7`WMA7OpvG&Byl*%s`6c(j-K z<~zRwha7y=C#b`L74Vn7o8GiG8RkqIFB3Xd(kA$)gH8Lmt)d~2<_oC#;L^_ty}r9- zRbSm^`84E<$9B6AzrEK3YF@nOaiN<(45EDJ#}j$PfTW}v>fvS|ohxF?0L)1G(!IlVkK4^k z|GRdJQ^dK)3baAnvVQF>aa5+1bXRN1q z{(Q2EN{_{9lp*wvZ`jaRq9fPu7xLY$gynGL5eE*S|8_~~6?lL7Svq|lJgDVvRub9v ze;q|xz3_@x8Wq91br~=>xLHs``1=WQap`RK9JB|mZ4w(hrzHQUMx=g0{@ zh})!B%#EPQBR19%Y7ptWtAs?1@W6@JVScAddA0H$!6A`PW07P#q`Nv zpseNEa7N7zsm5j|D&-C+e@6LMb}Kbi#Z!4oRF9Nq|MrE+Ta-p`B~nJsZ40sK{k>-2 z!dyKG2dfKpL+EqBH1uO5oiI6xiPeiD6Ev3?x8~>S5OngYJhx;Y4GonYHR^luL`aA? zIP9sq;U{2rfn)rl)q!9i^ZgZx1D6IEcBkWWt}Zqz)2z(_g~uBoFJ-f9XgB)h+QrQm zYi#c?BZVbsU-fZx2+-hf{H3ZS`J|SUY=5%~Fg~*#6o_8BX&zF*wt_k8dBp>zd>$WWTOh$t+(dK5~ z^!~A@PaADKuee~}ejGR6US3qFc~>#=ie2c^F$BUjZ>9|T9KFR-Q4A-O)YU^j8ddiX ztGIsk(W6HQZ*>Xp^;W7}xpD<*`t$qu`AgF%-z==GB99$2P2B9Hg&3r!so6-XfOw=G zh=($C=+NKl8WE3Vm9B#a3Qirc=y}J3B6iM?&|f1Ig=-GMui8>)8xJq))-fU~Fxf!- z`#i^aIw_$CPDkIk@1WKLM}bp@*}%-`6KhM&w)rlD4X&uLw6im{t4?r?{Wjz0z=Mw_ z%I)hEv3QRAZG-ldiiis;3(pA;t`aLa`{*y%{U=SBQ25{h=KkK&GptOP{xrU_*XhKY z{5y({?!VsMO-Q9xBPlg?F(h)s@h%Oz9rnz$w6^Xd_!MPWGiL+Wi9(CCpy%R}fS|!I zqmhL4ZSOYV_2KUFv!aM-5355;;tf-raveX{)Et@YA-^wwD*H9SLBZ?AekZ)TI$M7H z^+iR?VH<#k2}Mn(3mP$$Re>7N##u{_$fY?0YPJ-5Ko!zB(EYLVUuY@9#C~sJQ!>C>mz; zjo+tk$J^9XkQp=x^B&-|!!d1tZ?E4RyhSf4neD2M~luG^wcQ=#=0ViI4BpQuK}AeI5k@Zr6TPV%_)8t>bkf&xy)n6YE8 z`yc`mUXUjAWV6B zkIHE6Gk~BmOq=q3VN05c`~|QNp5`n;H(pWi$1lLD}x;u z@^%?6u;gpcH`RP80ooroNuL1&B%%hRToKebN1lr-v&ygS7X-*&rZz-ITA?&~d3o8` z9QIPh2|>VNepK&g)$1=arV&DJZv_Vk`H&0G4+HT`h-tr77VG-Cb26Q+EG#hSJ)}jQ zm=a6NacmE~6_CojSD-x_`OVGKJXclr(^OZF2zBI;gKVii$hq(s1-mC<1k0+~o!m5e zZ{r(Hc*75j>sq1;aSZ#euisuSjv)no`}e=`qWbVPxEV;+%w9p=-0|Lh|N1GGZ;`678Ny4r$Bz(IJE8uJbchQzc3fpH~VznPMDR* z@nJ49@F}m9{*m&too`hTgEvA#M39fs|6uJEw`9k~#jz*n;NAGgqS+La)Wb)Q|!aYF?`x)b??_~ zx84l%_=i>|;RKGaEUadFr0-VM29Ew8dYkM@%^R9A_PD0H|ou(%OA zajqd9$;E}{1Tm)}{e)rS=E_vD1F>I76#=Gi-v#sLsjhyht`L4WDr$}aVgM-&tIx|z z>qcMEuihEfH#~iBgrB*)2XoNq-#ACT5I54PNZnRFVRj~`lg%N;wFgP&?bXH6;03UFdJ zg43utH!G8`Mi2VW+cUm$jaltTevSwegC8MxcE)F}$yj=;D}s6F?L85jjvO&*KCiE* z*t2SF_|c=YRU~ahGQHP{UT#B!HzTU;b^AdZ+noy^-Yc3mf12^)b*~F=zc%xhagh#J zUonsQvRu}ntwKw-queIJL^p7PirpYBER#d>MLf}1YoG3-uhnnfW{rrX(SP^F*MEUK zfy!QAUym}eY2!wdLxWDcQn^vk03YgibAstkrk<%@{}bR!hMALiC}P9N!JiS8&2Nu- z^-9M_y59O!YL*>X73YS(uT8u1?D({_u)9@$MV8h~yb=VGSh)$?s(1-Z1Cp}tG+IHS zy};ZN$puljmiFz_hhcL|2E2R!J`+T`wCW^r+N%(2T0rNhKgklrr{68a@i`vZCG9ZV z0KgE@!Hwj~n3YN@Dy_iuwuXKFsNqOE3Ml*I#~0xtf>cgV_XJX}pJGp-NWWK^<)d>I zRX!4Ix)s|-L4mmmT*hDy6kdYe$Bw;bCW=DZ@U7Td+EsQ$#cLS(^x?xl@{w0ly`0^c zIo{UD(%M6N>>42>F;+>5Bv-a-JSqv_l-D?P=;~Fgj)aGIDBam}ypn8vl;rD9Vnm9a zmqmj`=j~+#qq4O)ab4~oxj@HLZS9&VQLThx(7>U0|LG`LY-?+B;%~9dyP|^hwG8=? zt{i+D+uA06qnPCt(F7tPAu)iiAtE1B32$X6{Or89qPz+T3rsjpNog>70ANzKbjy?| zKN@N=_fkPqxMaNe1Ww4SO#}4;7nv``@4%5$Mm?X>E9lwBjHQGJx%QY>-%-`^|4VhQ zz&xd(pfGta;vE?^1LsS<)i28n91L+l29I&=V|hUjHJK^yXcp(r&6_oAw6d}rPna@= z0QR-Mo_SR3admlmZsu_c*RbTkWl+a}#EYLjV?ajQzJ1dB^3gz>P>;*5C7w9ZA<8gr zF*zXI=rf1_`xa6MGp*7uT%i9^1OaZ7IS~}jIF5=APkayBq?KY%NXXs$_oHY7gd^ek zIF9qfjCttL0QqiM7{OxXLsQ@dCTTDgL4^{TMTGec*p*WpuC@Zc3^vKnToGmz5gLkk zi(3uS!)5vM&Mq4Yyu&Ii$i5q44S0H{^hSUN%Ree3e~R$0wieYV7YO9_cR@iga{Wb6cizVmlGN)Bk2}UMfRLUVLcE)v(uBi{eoLAOY_qr5<^8vrsu*qw=tTXNHe?#$+ zrG}uTJ9proW9I3(rZ+w_CYGqF9aR;lGF_asv_q%lm)yFyuC|`TWe;{tIvyBtrv^!V zMr!|0!rGr~y?1aZDqE|VZDVd8wr3Bt;*oiZOoIcygi+1HKH`sjt0zRQgF^y*bMW#s zQ&vQO?MV|jQ_7B$MGVJ{%UUa{rSz<+FJac^eKG(_HCp^{f{5H z81S0xM#m4HX=PeC#p0)7ga?6UhvPyYAMFNh<3ziT5%1*DMM{QZ`~?eBR!kr7r)=|J ztwfKmUFi+W_NbUSdv=JPtnASc9TUUI&P|&PWsh17+B4ItV__ClnUnMjMpIue#uGov z`{aqgx*45%OMdv1=hD4T4sq1=Y0?|!aOchO*T#wmg4|T=-ek`j=CZ{#hEY)1;?e15 z8W><2_-+}jxNESd@sh^y&|cp23kwS5ovz)fP+Ev%CwNUNz+MLci9o28PDW3Cf`#32OFf4j0_(kb(@nXM0QJm4daSfa| z7+&x#l^gXB6-V8;C@|{P^hLYxFaP!HSBQc9niCN9vsR zTi^0x@U2QpNojAY9kMUK;%jsJtpQ^G8nDwiqFug+$;zhYW^UOOEv<1j>EiNMiYz=w zEyTbw<<2c?1e(H*qg1YU@f^0V%W9b_`-s zG$uw6Xc5HmFA+bVI~g7A4sam_A2`sd^a`D)eS5s3I2Id+?%l)iGEP{+Gy^JbGQJjb zB-YEu40l+#@Hx)M*5${K9l3PLd)2D3uRk{OF-hvAdf^)Is!Zv^moJ{dKTM2_MBhD8 z6E_*PTMy}UIXn;n((?@rD86V`VuH_cx)AZjf!S3@ewrI7-A)MFw@>syZqGZHmPYGB zWrJ5vmEqpmrvSFOqs>fA28lM>b{&EiK@(C9)EA2;#-I>#%Ju?Spmn@nW}4xQ7I|#ON%Th1w@SH{RbP;3esOZVl;mbh_4bmt+T2Qw%*-5UsDdM7hC|T% znGzU68H?lQ_6frQ;giASL0D96!9#=+x#J&x7P*X@ON`cHgZiR)c`k>WN-@0ur z8D8gj;(!)N@y=bk+}N~rt*c2G=>(338dp>*eM4j=J2??`C_F_Qaw~HD3AB6}xlWohBo^7&*T?U{l*{zyx zcZ@bHYwLqIkDe^Cn`IIod3r>=gTY?cB}-IMe0YLET@>zG9V@xlNm#637sNLI`(v@ zGK$u~lx7swat=vCLXvv@yxpGm~` zIG@)s$%eYK91C5Bd#($2B^Rbq3@0Uxjh!b^WH;j7kz3CCFWUXApE0tf9rt$O6Ebbq z(W4}U{Ps=TKNTCDUR-J)_UH*1qM4$x*X)5fI*0b}zpKIvQi)XM*r<5GHg0duz}5c> zzRhRy&xdarT<+gl>c&sM*FSXzsx1|VZoS=E4~rChc1LG{MolEUt?Eqjv9r#b|jMqxSv7*OhQu!VTr5j?78Q#DIc23 z^E+^8V%(KQ*47D0NnML}&bPGO9;v3J^pWpb|K>>3;qu?=V_=C0x10-Xsnd|J2&*>_ zzdl!}J}8BcQ2&1Nkh$yDedRpTsP~(>LzGGgCXrr-vLyp^W0paZ|4&Qf+arBEbCwjY zUA(YG*Acvh6#^B#)EqGYVV$S=FE*}6DoTTxsz!8t-JmT-*3@yUvrO6`i!(j z34b$nVEZqQ-Pcc<23FP48MfRcaCHB(fbo+jolp(wH46AOW6Rw$y1OictlO=r4?8`^ zBP9KZROb%)9u1R*GO>;@DhT2Tv2#oEFl(o>cqp+4V4}o%&;ib`;hlR)uUvZ~G*IuR zs|%#+kt1VU&zoIzuk;yHWoq>mPinA70v{QIQKwo%Lj!FQ;r0_mQ!o4T{3LWB0f||U z%!C*Qc&IuTc9t(3(JOe#;lrlyz?kT!EVHX0PYhIPDwuISWmjk6au$K2}h6G zg&@_^>)msawyM;KIHNlqL#JG$$Yesz+l*N_bO|u@=r|4>S-$&yw{A1NW#r=fPv3Z6 zF#i6tb~mZkPNjdXF80z3>FE~c=B%yY!qYZ51Pf-y3xewg508NwtNO%$RE#|o@um8{ z>;9mrFf&}OEF%+R<1r&gjzqXuUgWWPVt<5H!aU>3UEE!3w%oXVTY)-TWqk#WpLueG7F1d9_Mxc?&>r=fY5$o&fcl(-kC~nQOXsp z^sU;GhZ=Unsdk@@S*w_DR-ab*^5vihzp1XSUC4t%q)rZxj9jid0Di{TXQe)@%F;bE zOVOR07Mt7HXwhWGz9OHI0SQL@-V{bn{aoLamCn4dKgL>B8VW#GXlG7f4ScX`*L|Vn z1edKHk|1i07>dQ215?6)d)E)fM?CWS{Zm7`F5uQu8U*(5d%Ja>!lAG*HD2DNqvJ-6 zg7Q>eF@<(?ErwZ0)Q2f1npSmp%y5qY&Z^_MDw;Ts- zM2>~u0VKB*0`=wW&L4`3q6=VF!sElH3U+DuG{d8#rKOdfGF~7kZ&$*_Z2NZU8-VNe zb_dcI=LGMNkaD^#h6MM!cGCOMQo`Pkk?~^3iES(7;Q&a{`aE zv+$3-Ij@wj2HOt)qA4{KX2Zgwy>RcSrgUzXH7i$oLk8kWroOOIe#*aP*BpI8-GxKi z-kx;c-#jJ}JFD^uqzAKMVxu*2VCzJe9(7RZ)3r>kAAm;Wl4%%hg%@Z&|D7+ukehCO zAO2&!K2`ge_GMYY*kJnnUhO~%v7>O4LgUjdiYQTUu)XNrsA1Oa!CMPm0io0rR3SY* z?-Uk_B9z_CxmQ9S6cikuwq??jkGxyDLL(0xP&<4Nz|&q3{WqpU4pJpAp9{#vkEoF~ z@5Q;sm_IiqE9=nf@*K(G8-MAZSrPqtFhHMj2F%J}X~<}hbYKLZLW~i1+*a5~{C7yg z%$s0Z-PfWAi?;eLaw~k=PLM+R&(8!EZ{EZic`%uzZsBV$Wjt1p5bo%3+; zWmgg?QXG$sD&K7o2UT-@s3L)(jztn6_)A^NCm%m}FmuJ<@&cVWQayTHOiPRXtDAsu zB=zJ7`iYZ^i{)4yXU97~_Dpav(Xvd^@_sEY5@0@9XUmLp=fs13DTL?rXvKNV7T0Du zGop2bEzx=?c#;qmu&GbzoYV=aA*_i|v9aaUN#gY@Ql&v*2*PWFs@%UWgU@uc003e6^ zD4&%XG~6#;|oNyK7MWk|%S1IZE*9tFcD>~wUp-sO4n#JALT1%2j??Rm*&%>8BlGZ#u+dKErZ zGQL+>cZGPz>XfYtriWlv7AzP#!O4hWQiS1j>3Ki5R6Z~pc0lo?;mRLl#0Y%o%Zpv2 zTtLSMY4Vy&IG}^#=z76=$;0zDirn^){-Rf0Z2K1iu3Yh1u|iSX+O~aRT8!q|nfjI_ zCnwABLx<=LlRk?BYnt!RK0Q=mFYCko;q-weA8yo!eKczRFl+DZix4Jr1qd=&_Rcwst~&@BHqJP{YS%=0yD;kDldBv`Qp89sG~ei^2l*avX& z8uIen{`hg*&s|~}d3ZuCWsaz@#m8g*i0LqA%pS&M5`dzhLh>6#;U#mpjK_QGr^CmV zFmo6q6m}xmKSpqrc}x_8VE%c_5@wu>N|Scud#YB_zN$DRX!714_eG|hw&JwSDspm; zkh3sLJ4*9fem9o3699I&{>yv+sIQoeKu25{uyZK8AhDIm$>kLlNvlloXRY9#J>9>( z{Uv?LU83VQZ2JEG{#osZ{OT;As!3HqlRJS*8XYyzm5C*ra zL*EtOmh$>f-z0QWu;$pnVR_3g-LiCDvxXT~-6SRRRFf}UC@v~Go7v$c#2BrTu>D(@ z1VP&xF$Q_)U1cSMHqO^Y59l9Srr-`-A1+>GIe9}i4)r=Z>;BUlI25o@1{Kpt_@q9kB+Xa>=N2< zh_Ted*j;XZ`NRR{hSxGs^u#XC(>vZs?TVteuG4=RBWF+3q z*O+QrBjR${uu_-Xvw#2hpFdAyW7v><24JyEXT$pSF%fjr(A_8Q78o(2!_?7&$Q~2j zZzg#)9r&ozRd%lKxQ$3Wmo^BZKw4E*)oUgHBxLxD#S0fAQFpt#oHo2JMN#-Atjx`~ zDtv>rGmwr5>Ly6^=uyJTO1hG1EPP!%{Y3}*&$YF+vDeU@Bc4`;PM#EGEuWMHtSFLQ z_arw(T*$@`@P`iAX>q@xg2vAC%#$@WmD--?^`%nswV?F3A)+i(tp^SrYR~vG611%? z(bhOoM-cjjumeh`Ux>(dhlM$EgaJGZn*(nRSb~EF1*5|A5`Bg~)g7zu%ud|g%OY;b zCdH2zSo1S{_;4obQNgepcS!yiS6mVtwRr;?sgUYNG*DEE-IYco$Ev98oVr4sGEEu6 z)hwG_!q6+1qG1E<<1Q6+4lH^P(U(oszI^$5ct6K&P6Vz19ttxFuWz5vxa+rC8kJd` zEBY|Ece7?RZrNm`ou3RbM(zBxqM_L*z28nxoT8qNNuRjBjFNKF5_#me1&X#cA zZVNZN#=vgPIXuB|?pzg&kCaJmCI+<~oF2~^Gpf)$_|fEfI#)yg6}rqv~2G4%<*IvEk5@?p6+?jIN6_%$o1`@DZU8M1hc-=NykyKT>{D|`N)ZfpCJ zNrx@#mPphaE>%-i9iZhovL)a$UGPljJvM6kzZ>j=>bf^PUilFBbo&PT6KBqBL9n`- z-KTV@gDe8@*d|HGFr)c!?eHya^IrV7x4K;E%YlT{Q>GUNYI~_RZ`Su|$*MI|vAaw3N%D&}yR#b{@~w|w-W=9=<-`5Kf?#dAj`?K!THUifm(8enc3%Q) zQ5bQ3+cv+s_8yau$^D#RF)Tq{QzOm!1#@4^H(@@xKmVx1+23D^y9NKN@$8?Uy=iIg zmnV?wy;m^y1M3oYonmX-;1LZQ>T|>PM>0}M#kXzPJYR3?j=A+y8~%r5T_&h)Na=@U zCA>ZlSN@$dbyJzvA_&C?A^tyq*G}{8&|%;ysgMGT`4*pO*nd#iy3oG65cBtn<^A4) zHwNtVMTSut0n)P6&O4m39J9>aW9r8C_R~J^Q@@y;T($5nC3SnDvZ+D+l`yKS!l`@znBjwM&|;XU$6B9;K!A z6k=#*v9nwMxv= zdS&(cDZWpW55tPIHvZZdzMtmr+Y9&hly0g0oV_bpn%20b@X188(+4{xN%Rq`Fhcm`LL#vP1LeDUV#-3pHw7o%M- z@$)bhk!(z#H7h(Ug50*?OJdIgE2%$G@h5*++|4B?V9FFQ8fu%`)to*^^K56ixw$s& z@EEM6C2*XgsmC1N{E`&71UYzkfEHIk~jtks(C^%y5p(o0q-l zqt|YW0db4ya^ETHxK$(OdS+$AgAz59SYz)IYVYPXoseEDx5qrb!Z7z#OYQdSCRPDm zL_2h+_WZB53-P*6-Z#4K6x;T6L(P?Sm#=tTE=p^Dxqaqolmk)m_ZiF1Aqh@1XU=(4 z4Ogxl$SRABjLLoRz%s%7?1L42a@$!0)=O}1m5gaSF~?$2u~UNsj|olJx%R9li|&p5 zQ@Z8SD6@aXs^1HsW!>$nXR`q<12X}d2Wt-*IF#QIq&R+_qhsN-hgR0sUsqZB+iL1; zZn*EfH`93NT#EY@rKY1sS!*vJJVjOJ_GfQBS^e?jA=mMi2&=ZG{(4nchNE#2 zsAT(&^mVhDzwVs;I?3_&Q~hD`W8F>y{^Rv7@h8i{BR(ip;JuwsSp6rKNG znG#dD!UMLNXIpAxlVh>Hkd-?#So`^(Ctv5qWIZn*G{_K?go0;}4RMMeEcUzW9OX^Y0mc7p$MThIKXvJR;lZ0e^Xm_KqjJH*)Ujm>>oBLR zm;XYO*kRfuw6#Z^*{?GtU@HGBt^tPw3v8CaqGO%G*JVx3%jb-43Hd%*QC5|ZSh_kt zO5bdCp+&-)vTL79eN{3vY};-(?U(fF)uC?PruMd5=--M$M>*}iodkLI_Km=5k2W$= zam;`50z~&4HhDX5U9W>_pERD1Zthtep_a{!~o-VA{@R}Dx9_bZUA+*0PrO7^dAuO7-Go;V zBOn!n63?7DlbF~?QE}d^SqUdk0--*r@Ss0r^X6YvnlxtsxdINF_0Na>!{IIkUR=x= zd>%pKo_mbnY4{Suh)55;MuHU zR%T`cQ8^|gl=rlH2chrwd*fisJ{57*FqYbCgR!Q@e;uL9vfq8%Mf3&&{di zkv47AX@Ac#k+g+3XlQZk=l>k}yYNBma) za4USkzQn|ovM?H<$BJ_{BOa+KHVRchU-V>m7SmafDvWWY{LRf>NwUm+#q?u`(Zb7rMxW4a&46*b8$N?&LH&w}p-90&k%dnQjqnETsx^+9 zjM;NaD@5h@XsPFzBQ$!8-J#Kea|l%z`8iVLEBKXhON@W=Y!={9%q36~0enby?JCR= zq8bHh5;LYW1TWXr{D|zw_hstn|2*37Tyt1=;ON1FM-L8KJ6wB2LsW0EIwLEdF-Q=T zStBDNHZap#Y}>9~nN;Y-vddA7Fne#i8p-${V#GI-*x*cOOSc~##IS*AaJp?X*L)P z=QMy0Sp}UbuiVyyVZuk_fb2(%Epu z-Xj^O1FQAd?J{nu#2ZdqM`t8@Y<+!!G~TnP^X^5Zf5`9kUB9krl%=1kd`_VJ?))mR z?Z(CqWDTu4*r^E9Yk)}ZVrX(-V5h}+!!a6W{u>R}D#__~4>FgOkl5yF2?x&^&NcrJ zzRT6xT3XhHCywR;aTnDR$?t{!w~pKN5#O1;=t>bE{eLRM4 zs4Z;X+IITZk2hP+U3q!=rSd*oO#l|DKNsU{K#5B?q5JC9Dm2bjh@$0*a)3wuMck1E zu(PvgXD-pBZXI%PaZ`n<)?#+$UoY>@hf>AcyD`|0S`DcZI`fUxKEk>~h!+=Eia8v= z9FE7g*?$H|Hbib+4dQh`On_TqmOGvsIPFY`@x}52WZBQpk3~&GF5j6P{SXh4`Y2nZ zPe=j)gJ4ClVyj`8!^DZ{gbNN78h|jb4UieEsX2_Z7tyU=G6t1MQpTVuqdbrjoHV=T~C68Pmy= z?*MIT_GKISk1u2T2BToNAeS*}z7Ep1a@8ur^6`9EIysR(Kx@SHMWcry6t%LIj_RI! zb>F_V)>ll0+-|$t%fv5zp}-F@aF0$%Ev>4&eJwRYJ0iA(n18mum;L9mYK=Z|yD@oa zKX(R&lYr_zduGwlCfj5)pjTHu7TikPhRLGCWM+87@m$(=EC%#J7X;-3$PYY*8IS)e zlsO@X4p~TJ%uQK0fhU0q6kxGyM{&iVK{68b_4HFzoMN@~pLZsu{b96jmy9Bld;sAB zGk^8$|7Y7))-~7vhNXmeGe(+M*}O9DPr3>h{myi;2}1b-X>R z)4#voI%C*B6Y_+={Qvsp!?bbYVlC3-4Q)5#|MiyJ(xeUl|GlNrFUg%GFPz5UW8@Nc zn!UOLMIoi3L&kSa`@h~+tl0O(e(MGBAO$a9{y>@KoXg`t7bsE{1X+NtH zom%RVQoe~h2uLLKg(-;gH=L|)%-rkPL8iykk5XHGrp;eJqq)H9=D|@bx?YMf&kY)J zB=W^W$JV}iUs}`U+eRGqY|n4Iy6wlOe3gs(|Gtb`xu*P6+W9{^9=Fdtdetv}#0{+~ zyR5h3HxHkG6ESXeKhN4jADV1MGH2R{nJ!ip&GS6}^pKvB{CM%Ho^Dw;miay_{P*v= z<5WEP#QCj7>3^=cl=Zk}^TP2fUv(UqH^T3+>!aIuqc5etco`QMq_Hw%z@mb=SI=w3 z<#&Aa%|i8#%>u149qU$}{+M%1K4--jo3H)H?#$mJHp%iz$yuZJm;Ddlj5~5%a;Dh= zi}-bhx$dc(Lw5&P-@H;C5+)m?+w?1?ydj4J5=;pwW7R1)a{B#pQz<}N~t^a zYF^&`W#M#qThWjv^OfuMCasd0dEBPqk^BqQRh#u^D@ITEb&I-?5m_0dv5ZV;XTwH!j)Zqk__57vUo%DU4!>y5l(ho*MV8FQ} zn!VGG-t|%Bh&_3g>LT)c9Ha+R;i5+(P)Y2%%OS+!C<-Pl5NGMSU#kgU#V@aa{8!V@ zmT#XRF-YFmVdF2dB`Fl9B_icU0nY3#nz)>|aGr4w$g$N$uoqbVSXQrR?P3%r_dX@O zS=MZmIZ`7gDWd+T5z4|M8#%-A?0J8$mZov7$7jxUnAw~d*sQRkL&dpkKHco|+FO!y zPcPW9TXE6i1r1*U-J)MlTh{v4BS}p${#%6nW2=?@Ri|0UmiS37NZFvD)|8ZWb(Ds3 z$-@ibqb|4^-kS9I&6P42>oTp?84K6jf62>_DyaKDeDZ4Rpi1$>+wz8Ab@|@!&Ed#9 zM~9s;7!vSftPS5kYFx^AqkhBf0vwmQ?A}|WnPVoESUlCt^Xc@fM^dZs_JEOsytC5ySa&;00k zBrnEAbc`{2DpPvkw(-sNqTmb1L+*!!^}5!?{%r( zb2ARMR;oF+G|1fiq_?P5P859XYtIGNB{3@-R;!6@Jts|Gt~S-vp|90~){$eB9#g!? zn$TS~Wy%!nyzh3;mk}lr(Cxh4m|C`{ygUMh(}{^!8GlII3sio?&lZk-49`c=sYYRj z;7vje6pxgHq&nFLvHK#Fi|BaS)s*}ch~y8{>JqV>#dyly#}1#&mQiL{i;{qFD(nji zqI5vF-%UaS!|6#9O!S?B=@Tb4kDG$bYwUZPQ)sX>k3SF|PHort`Q>Va+#?mgaCnMu z7c*LSoa76$&l5H(7*Sy@t)gNR*%vGPLa~3%2nh0kf)YrK8t@Aad%DOWe8I#ayzn^X zOzAmX}zO+*H)880&tCkjB16|#jYFK)Mc80@;dW2&M|BhR8{X}WOURGiHN9qnG^#&zk9bi z?4z-+_LbG1k{>96X7A z!tB{4X(YUKzMH-L&W2-9EI<*k1z!7?Kv2TM3gFRj@8?o3)8`U^@1+R$$xD|;U@W}8 z`Vj6N9KIT-&>2I~-kmu&qpIgFr&fGn2OLBc4hW)4*ArR<4pmk@3!QBv5ld$mow)Q1 zgC~_3Wbg+h!}LM#;n_IeypCBi{2`A}c6`UJ>fO~wA~B^B-m_;97rXUWqrYpHwO0j~ zE&xc0SUf{|E+XbOU@6SA>-9ds{IqI^9wdrWa^a#ExGJ9|6&hW z6O#!l$q7D_0tWT+y7@S4)Vx8a63MR?=qoSTukU=a`*g4Ur9PVODa!9dH$@&FEul7` zyunpRK`lC6G4bsYrNZwY6EDOEojPwBKlMO|BbJ^rCVP*z+AFHR2`paL)wd5d46Jpg zO}s5kFj-I5OevP@%vrOTPb^Fo>)ErXtO+(UdGu85!J)C2_AQB6U_x381nw0;h!tXB zV8Femb(0bl>IF?MyW;+QzUnU`NpJF=5Ru#at&N9=p2*Y9TguV0&ifO0m}@y#T1vutg*{SZJlP{X7oV21%R65PPr*oyMZ60sl=$SPw?+Gp*uyDCFZ z2Sjv7@pMMU91ag3iMTKSiV*sK?#<54-Lrc)=N-Kk0Lsn3exZDCj%xmUHEm0KxqrgC zbqFE-{3Hf76n$6k)fHnO8WA!_yX#(8U+MNX-0O1g;qmV~6wK2bdM)ko%rz1#e19Hm zJET3y(b9JQ^SVzVcT;`5uIeP!&t2aCiF{Ah)m3N9`|WgX{C*A*PBAXkwG%C;V5&6ZAw#y&iHD94y z{tc0nk!6H_vCTEqb>v8Z_7=b1Tz>U@T#$KuzH3}whk)^YUv-%fgYALf8w7er0!8OE z{bEgsiqXPAP;v;NvuXDZn&lO@$FNHEd&i!HEk8dTJ4__-iw-@J>KEVB7Z;u6*KW>< zNEWT0CIi9l&r&~FmQnxH+d~>Z1n?(z=uKNQv*TBI?T!5 z{uH|Cv$IhJDDUjSK0sn>?wuBsRYpKv&8CouWuq~I*78ye9VdYw)PC+|q~)>Sl3YnO z!QDYPS(FSyHLv}BJl1;t%0DGE1_5(w>AT-njJ+^=+xb`VYB@Hx(|5?Mm}p_KEL%$X z+=a~>R&L!q-`ud~{iVaJ2F1mG+P~_a?~{%#dHcd@i~4oiFt+PgHiVOr{*hYM(f8*j z57E+?H^bWRYeL0~T?gmO)fSygJJK`IE~vn&rE|@?!k0eZn`$UE{JS0QvA?+c!tF8a zmt53?Z1;iF7O++6j{pGr1)@(K#XTcY1o0zC(0)&PSn&LLX7^`)p%D=zFwQn#r5Hqj zjXYpJi6UCSJ4U9=;Qfhm5eJJqcZ@AV${T*Vjh_GX4edopG0K_y2I0qSoj|aF8#l)7 z&k94v_`aH;O_*ZpE2tLBhg0<)$ydhu*>-juOk?pQqogDUw3$4)l2Q~P-X1MHR}M2m zM`>MwW4Y4Ch7a8WGxdfK$K(Nf60D@`Q#_7;eC*#v&k~>Il_1DQxeT4QdH8K1>NY$+ zOldgpck<;g|&4_|8JyvbsMI?Ov@F94R7rY4djI^Uo08^-1h{3kto+j=~0nBUkpx0TmB z@7E7?DmJbuoT^z|;5sta_)hbclO-lHM<0q8ZyHO|1Rj||x;2GC5l$%{nU5Zw3+sYgRnf)Q z)l_JFL+DHFfxSMz_(Ili5?hO-1>#wWSZX&Otp^$9>wzfd*wKi&o>n!|gwHPv+3@_y zlM7_z%+VVfp)Di9bB>$;Vc8zHHz zi6DGTU3ccvCC~ZuqxkQnNgYf+qCSj^SsoDH+n8i!bTGpP-io_DnA5`1kWRQhS4Ql;&Kl z_QJ#OIP_?G&HQ4?((&8z|O0$S?)KFCoKgEK^y8*q}=9q zY3U=_c!GLdzH54VI!L%5qbxgk8Y{vs0n2{-@grh_1=i05?&013d2awdr{-t9#e6Tb z7G)g@Phy+7^C~@ckcH8?)qgk@(90(*BL>K?~QliTQruhIZuy~j3&Z3Bx zbz0Uw$>Z^tk@2JN;NHAV_pFvLin*%1G{YMrW9w^@ygkJw$BxKlzc!#Ovpc1B~+m(*_^&$QR3>CY)P+J_5L zbacPEBvu*XBNLMyxCaDg_INvnxfm3FX!Uq7g&-mR6~uf5s0Y0ya;`XMeOWRjFcWZ# z9C?bB6|@7>FeKClg{8n*vmFx?63#BT(T4#7%OkN5==dzjpMc3`bw=| z6T}7M8C&Kp0>_h96FvBzL^T#m@W-QIEc_b=|x=dJMa*sudC+Z@|Hw%?WqX7DC z;Y9|XW4is(fPfq)1(o51(Dk04>dtyh{}G8gE*FPr8B0IOuMVw4w7wLa*q@e`mT-l= z00`oHe=P_WRQH{gTY>{%mS{QNMoS2()R zyVi$>A!wH*x5sdT2GS2TIocj}P}>mI);o#=j36Vo^yd&G2Qt$SOZ54C^NiW7R%sWf zpIc-#K5`|1Wqsz8^uOW{rP94(-r>WI&l5^7$n{fre-i9>#Cl1Qlp>~61%3RCelrgIZ4a4sl%b+g>Bu1 ziuL%zp82Y#e|!Y^wY7Z$InUGwWYAugKeei!6zLbop4}WycPU)j+Sw)&$#!QcrRlTv zcOStqhj&h?Q~i?=hv5T{hZqixJNt~nejXj_!$smHXdma@X+z9c8ya_d zv-8ihr%!LLel^@-9(-t^-1@?2GRgf<_+9L8VIY5Smj8gD;Nuger@rpxclW@@D6_eT z*G{i|Dd~4QI9NM>gR1ot4k!@c%okJa{S&I(6OxL zxcIeTZcxwa_K&tXJktN7^Nhrhcdi=>M+98CR(^9}%g1Zy+cX^(&sUs(^+n#{$046n zzl~}4{8`jby*6edwKOhxgm-eLjHy_1$I@AauN78DefnIblOjLxmY_taDfFS>@tzQ4 zr>UWFjs6xgVA7RvZ}xwA*?MJia&5YoDD%cfD=R1%&|M26M5WVRail8}Ah*%Y7zC05 zk!YhP!Ihi^l3`9Vk{#QCjLBix4`ztGYE58iDee%}&FN$rr?=L6)=AF4n z0Dp!jp&Xa1koGSQU-@7ifP=HFKDd0Th6Q3^#7gON<1zF|QM8s?t zo}fZI1HXDOzhiY_yUaK*jRix@U)KaT=YSGc?QfpOfFGbHfLp$`>g}}}t{M<&J&$f` zMB7iZKu&)cRiKzEf@YCUho_Z2TvC}H&0&t)S>lNkT!WjtyS2g#n$7uq^r>)xx?&GSeYNB0NuH3V0SM>NT2klHEHNqEhRy7lXI9d@7(b{{T zp4ML%ipKwr4z%N6r<;T%tfhu1k~!}j3Ay|0i@P@Zh&(=8oIgZ*S3YvazQF87b!l#+ zSsm|Z>{HT=lKemO0^zgwAIXEW64IP~`#`j@Z-X6_3J~FiL7wgUD$=|Pf8s$Fgz4DNC!#7vVSlpJoZSe{l zl+?5#OQK~NCnZKpzsOw8bpUUdCfn)snX1|AqMgpWn~X+k1@I*cMrQ;_$xu}sEFb6O zF!pmHndj3iLfJO!B7f%5C(GbLSrA zML9xFK>8lRnoWL%P`*56}<>(m~#{94N3o5N6OT<~$s47>&g9 zgRGB`jQVA*=bFf1m@c7TAx#7TTtL*K^)fVmGYvEVy`}NE5cq(&|5ga4T)zA)H}^BM z+JrMtOKTI8VO`&mS=7^w*(Z>*OB*Z=GeUMqlj!z>_@-&C4tHZQxtSKCishOb0e(eTp1t2YyvuM92O;ShX zqorlp_{8)z+3G#>jsoRp!A_2&sxF znQ4y6haOQ3ItY4AN4Ln<(eWsHPE^8eTNo+Eejc*`E8Sm9ulg*oQqOHLU=zRgA4Ej&HWx!_pfmg3V z8w+I$2Mr7gLrWMo%cHq}e`$uFESLgrW#;j#sJe+d=x~AHIfl4}jrH|32}RIt#LORb zg0z7VhJl+Pazf1bNa*d?oCHjccU7MrHzD@(Nhn!C`L% z8c-@#5?AbGXt~0}k_}8Eh2h+RM@u(&d3Eg63EP6=AnX_WC@UWg5BFkS!W;z5-b3-X zdE-Wm69HoK>ohm5E+29J`0;@U_iz(|DLIL_r(~Ap0i#h@v19RA^T?Ew=olRlM56T* z1!|-fr#H(C8`>rL%;b1<1h3s8e^@Ac!yT_6I&k1w#ad;lJR)Dn{ko(ElP~s$D>?!&w zj9tD>l$eH30}f_N(maAzPLJ!}r9Z!NOzhtMC$oifa;Ds@W7HKa&8{S4&D?DXr!@{w z^*ddpc48`Uq;Gp$(-c(=jXe*R?2{kP2a_wGC3NZ1Rd@X^i$w5}=Kuq=DZJ<+xjzf$ zTcJ>DgJshurO{FE3k&x}gxTmD^k!31>k)ZRo;f4gty}L~ZwDOKC>KWytH(evcC<*a zCS=qjyI%7ip%|(ahNEHQO+*nKu5~|KYLshj=ZyE5j;2&KA{X9N*f%Xr$&rx?5xJQQ z-}w?Eex(inBjLQSX*xU#S|I~vC^I-F^b7> za&l!FPMT+w4Pp={cNG8Q@yPAQPYMgIUptU}&zf;o({s{gAtO$d8poB^OW0$OZum^? zhgbL_*;87^5+T~M70ZviDL=@fijYis6((u9b?XF|f&KRfW_Jrra4st@K88p9!eN5( z_|c>EA?i*W7+3A?;pzEcxLRc>jH_J|UPswghZ)V4@)}Eo@>v$IC1*NznQ_!Tc@`lR z*iUdOoHQw(szOzD+ee8fY5F?l;>HHju~KLLcNSPV()N3&@OZ_X(;9Pn#lUqjUx6om z@}y?x&U+Z^mz?&V@XtSUUSd54sGKE5B`Az&Acq}ZDj2t38_Vw zB65dlYTBi3y>;NgY(f=z-ZmLL9Skr$cr{*xBpW{}yQlN&*N$`2?$s4|=f(L2>{JKN zT1eFs;H}T8$dy4sjvT?~>K)p28ca#>Il0RamUXNxvh&d!{3Y1$WHfmJw_9L1V zRM{kzf*mseYuPTMpCHl=3VMX!AAOL&X;Jup$+efn1A~HmAoXz&fM{Zjqo#}m{remm zYAoQmxE)b9@jxJ>A0fY&Z~@_VhDWHW>B_-Q=7&oI2s##h?eNvL(|W@=qb`!|_5)x5 z$m`(H1*c;3jOcCyGDDdGU3%?W#Bcgj zuv+z>V}IRROssE_;0rMS2I(fYrEJ0rSFYfG^nwIZGfzB(S*)q6mj=2H0=Y&-{rbg= z^@LxbL-rysc-o6}@?E`(kf6Mn8Nij5e|a;@Dk{DK8x#fKyxBsIMqgosjy)=r6nHZ- zPr`*W%L=ez{>3H265&v&Q)4g&b%{IOli=Tk`14HjrQemCL9Nr3mfE+)k^|o5Eh@hi zgoc_M#?N13W}KxZz(M+tK#aIknFqj(X7IE5c6N*#K6U;2Mou!YIvVv`8mq#v9fLU| zEz|w(<)4_yxWxnp9}(*7{I6cVOkTC%s$1lN1J7BrYflXdC;-e^V;pPCP>;PTsb8NS z&n1WFjMLn2COy@1_UutZhmru&%4uDlcm(%!g5Y0#x<_dn1{2ZTK7JWqSwxT9#fEsP zqJrJE%goqVtghiU2sLR45VnDDo8g{&YI8d~)Wd*Li<#-(&-iY>>HdRFuP99A<(tr+ zBCEFS9i%#^F3o;4C^{Nea8f<)7KNDK*VCK~kT`twG(sJBul6phs>ITm!;wO$3R$h#W2fCKO5h6ZYeJwUt8 zsed=n+l9DxJK$3VC{Q32b4N0izu3TBi zc-q2?v9Tq9KCEy^sv~GZ$vD=mNiLXX-RX7>b7e=MX(LbqaLcS#39RUnBGw4g41*8v zKyu8_0U>H6KFqjVD*ck7@F+)ko2Dt%H#!?qLOJwe+Qn0velgG?5u=!T#o&PIe#_{2 zAQa@!mk6IU+3M_!umTH%p>a|-a9bc<4G%YUGqz8W2!CWoC&F*VlDhd`!760)=CPr} z_6@A`)SiJqbjzJ>h7JhF-e%#9@0UWYStbW)*sczcrx40IV7r_&+y{uXZQ*8`db zW}8wbMt0TOvM5J;Vtv)16LI9Y&|(0SNS+ubIb^u>#Dv|u9K+sRlD}2|+jL)~SSf<)1 zYW$00=3fObBzlnN3Xmd=ICR2o^(*6Yuj`Vmrba}}MZZNYN5P@7dOsNP%-e^)t8+*b z#R-H}WdBR_WKBq{=MiFV-D-uQsboMh{UGGq^hQD8u(ps(8m3qe`o2ig`OSQ^c?2Ty z?F;#DwA-MiTsl0vK((v2WbyM4iXPJ$96pX2k{REkJ%&`6v^-XI+|g{Uy#GhZz0UbH z`Ck2vjC{+pLkJn*s3=;>Ukn;IE-I_68}{zpbkZw-92L5EKT%Lcga%heO-?r5^m7w= ztaA)uMIx3BQ1bQzr(k$ptWIB+wIQeNwQKr--dptSZESQ$jhe05i{D>5UsI>gO1c9! zUgCGq41#HaMcA6EFRw2F+NM)!P~DM-GMLiIsh!n?pyWiFuPI9pC(Y&7srCo8#COS)^O1Lbp=RC~7v&xUW{=!qm)XAb z^>xfwIg2?<^4&;$@K_V8W zwIoZQP{^~=)Sj?g_n=?j3+3N~>aT|zSe^e+zO{4F%U++gADD$_l^Ki~Lv`Q{MgSPM zaG1P6eRshTlhXv(dU)xctwRebWA?*+y1%*H#c6|@2G}|{2lsf zW{H*S4?>gUG8hhlfC{#?h7*X0&)5spcmOQqfg)SvI_L8#^cGxMaexLKgl&jb5dGDu zWmr>pn8ZF|_UitwP|YwbW)J0lM{pDuw2cXKg;*nGMS%UV#3!VncB5FRR4r3)Bgv{1R#ujkslWLQ{lI}4;CNsC!KBGKQ-&Ngw+xY!6lw!{4Y3Ky4|=dk zd&&&Y?J|e;T&6H@<;H+{13k0o!~$hgm5c^blDo zf3p4V6>9#{dDE2-my6H!M3IBjS_0TiVFhMi6)Uk}frahpu+ z#l|Y^@eAtA=tG!>y)vhhl1M(}d@ckUzm_XD%8pk|KK*jj^aQsR-abC`jIg!MTao}dxP!}pL5LK{TCYzb?`JvTuY1sA&)-6sNj5~lckh@-wrlrp z5ZJP7BWjmsL_a01v^Z?bT!uRvWTcGs&6yi5h!G&9$;DXD+z4`S1p1S`Iyi{QOPPbVAms=NK+MAeMQ=#z!}b!8 zh77skX3M$^d?dfV6p1#OESf2@PPC25SFWJsNsx3J_>_+wUOIJ-DA-mrBUeG{&lKJE z1*~MiQ2{8ynGx+-d_KCacB6NLzs*eEIJLj(V}<(VP-}6KyJHHo(n%Cldi3xhGa)je zR3%aD=@bH&rhj|Lq_!O$Hm!D6Fj;cgbx5DUSJc|I+P#T?AL=$b&zxJnBWod(`uf*K zYohXX-r~^+^iJqc#L0*Q#LzX&OK156Yqi528Jj+*#n05=vBB@WOR^n3s*Oja<%boM z21&$Hs+T;K@7>$Xz8{(TlznOdHmj40x2A>VXrGFc&A7Yuk{ge%lG>h#cLWIv6#`wI z=9i5?DNs2M+&W{>@ZtFYplL^uG_mIdoDk({kXcs_vWTRF``=Hc-M&O zCkn=tUl^gYI@+0J9CjmP%vn-pK0#CTJG4-UnP}OfOhVRDqCe)mLyC!^vsRyj=J8lH z0q}{pv+e6K&kUKW>b{J4S$n1rpB*7x_#(c;Z*FRBpa~ev2#6Oh_v0=5obS`BuZRC6 z{PphL+qu)ePegphcY8C4n?d~xcu_)$9esc|7M=Hvi>e$Gf67$BNnO0Au<#gpW zQ4JFEisceB?jkxXy*|b{T%~`w$DN%PLVyF6q1AbJmKy0Xy}-7pSKzIv9e^ZursJX2 zUJ>C0|D?CR+Ab$H-YzrYp^9bvpyUgPU3ui05o?-;)PRVFHp~f6_;44+B0{(P{OQ#u zjZyyxtr=E$9-eAib3#4-!dCA8RP94XaM1AYgf-`a-)Sw?x&8aAWeCuU*8ZuHdH>E> zOKpyZHQVR(95C;5UD1p={XG=!7&WOX_RQ&O{X186|BeVwYo?luu1?hy+iI_{hD)%i zXu)ZiQhmDbnrv>*9C6jc^6X>#du_rU6Et{v$oLRPJ%u|(!2TOYV==}gJ zyR5qU;SxOssryv*wYMHMHhOt``rj*|P#f>tc9VDjm2vmlG~ksjG^CdnCLI#8Y&$zu z5g0bse57Xl#a7xiy?;1*@zn?tN(F^TD!Z2RpRX}55`v*e`{_&y-P-qabNV5cDYK67 z7-Dc*A{JDJIKO;??X+r#aFnx1i`K9I&RIi%rLn2j*0@^o358U8UZ$!DjWdHN0Corf zO-w5!V4+huOoZ7KltoRZpfrzZT2f((4%|hH5-uI1 zwjQT>_$x;+Iv{Qv&PqLdk=cE*QeN6Zhk zvbv2;Bl=L;lHyIpEWG(U?$TfNmvx}7OoN1U_=A$sr0wWhVugR_8zf$oNr1j>aq0T| z2P)2a$PrS<@YG+w$h4YTevSy~PRM3*L(}s=OC1}D!%Vpo`HozMdY!A%96A*7G+?%l ziG)$G-!)9rQYe2Z(x4Pv*2x4~lB@FTHwlAR2E?q*xeVHVdo> z6D63l_leu+d~HVN){8TtuK9S^MFiz`RyWaFh^*VU|8exk5t>fw#_qSXBj-k*z?*x& zBjplU;i<=rRW~veWb1*Q_ezw;Z+=D_f*zmCcSt9-k<>=WNpk{hOg{ieWu*O;q6#rO zyj40SX@Fcla2`M$3^1(oGODbmu5+GtxvQH<4=kPooc0B-mzj14LWI2E(yMR^K?$I* z@wUW27=wMk>?#Jqwbhn%5Q+oNOqyb+MFy~9X!cbXl~+`N4IMpv_!o^+BzvXWcbIKe zQZt`T=uP_7)Wa3-pS9mK&xFV{Gyl~qoCK!;2#I9c3Y8vr_Ba|WY5ZGLtWsx5iQ0Fh ztIXEDyOe0ldin67lmo6);{%__VOJyC0HuO;w8HH|>iE|rD zPa*YGFB;5>#;x8Zb2nnOL@f1~VC&3A34hed1#G-S$lx8}I~V0#D3{d>GFSgExFO_s z{yMFDU`XKjlwex|^-jyz7c9n3Y>IdTIX8Ssb})(Y)V~wh{SHkJZb6!BM)~CYjemy< z%mGq;iqNJv882R3#R|bDkqqADk7G)Eg75VgDNpeBOB;h(k&LXY+Su+E$Eqa<1g*$8 z?O16R^6nWeTeF>sY(O7+HW5(b?E{a;Zt=Wqnd|8Fc zErHPe(kJm&uA=V%b?vJcN)kG+Xx~}%K)k&S_wg^))q7RC`p|s`?;&e~WH2jcIU-wd z!_;>alK`R&|1e%%XLmBO&zelz;V|9F4Rl~gkx#p?bpHgu8i6eSJy+4kp@T` zAQf}6vq`TeH{QD+Zu(Z}$p$#5C>b5KV9uP~F}shwi-j&hFehN#b#1hSB>YS%qPwB5 zqGCYn$y#(3ltj$!s9?h}Zm^s0pby~qxK3xBqm^#vO!`{FAPUgaq4&M9VKqbwKT~@x zkF*)t8*N}iehpc&JUEvcb=;a_VTuh6|JPT;c{l?#ytntL0FcShNUL(2ZZz{Prz zAQTyS2A%)>v$XFN!~v!%#tD)}lM5`b`niKxmVmXOFDD^^zWny(?GLCY@@6!)z)PGd zvEC{NFTUb5sNtBVo+JH-R5O!cV5r;s)aMU`;W}MA?f}IvdHD=xofk?*a6$|Z{p5;j zPaGqa`czqoCkZc+%42~{*y4ZSC!qYsygWG#(VL>1kX3mYux}rTKm)Zh+|QgGD4q5X3Ti#dSUY zm>xc4J9~#T@0ltGwnTF=E0Y~6>A@8o-s%%imlep3~*&~5${V7WcG?Zd(6RsG0fKX zJ~Ac_L-j#eax2)w`UuX0K1)ysfc@beYf{$2RL3>ej4E4lx77A0> zI*OyO5N7rMhL_!q@!+g$y!DR)dPJd`fsLl*9h%DVUayPT0M|~6rG>@$eGsnF4V5Z} z8)f9=Cfi#lDAj^k1)n(@ZkFsBx_e)FfTeYO!XkMC9R-)d!-ozPJ6R0Smt#?)SCj3! zE5qyqJKVqf5uY%0X~?jZgK*1+7418Hlw5dnXn6nR0M*uohm-_z#7*?DvO#Ol*z%*& zmhuY%M|JW$-9znk!4!98t=xdN0jKbn=&%hY-hM3b*Wcn} zmj8z^x!6YhzqQ$&{$IY#Y)P*L-u=I`k7)lRUA=np*e+{j1XZ-9nYHP8lZ89}7nb(H A8~^|S diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging.md deleted file mode 100644 index 49af4f527d6e..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/logging.md +++ /dev/null @@ -1,128 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/logging.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Logging - -## Logging by Kubernetes Components - -Kubernetes components, such as kubelet and apiserver, use the [glog](https://godoc.org/github.com/golang/glog) logging library. Developer conventions for logging severity are described in [docs/devel/logging.md](../devel/logging.md). - -## Examining the logs of running containers - -The logs of a running container may be fetched using the command `kubectl logs`. For example, given -this pod specification [counter-pod.yaml](../../examples/blog-logging/counter-pod.yaml), which has a container which writes out some text to standard -output every second. (You can find different pod specifications [here](logging-demo/).) - - - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: counter -spec: - containers: - - name: count - image: ubuntu:14.04 - args: [bash, -c, - 'for ((i = 0; ; i++)); do echo "$i: $(date)"; sleep 1; done'] -``` - -[Download example](../../examples/blog-logging/counter-pod.yaml) - - -we can run the pod: - -```console -$ kubectl create -f ./counter-pod.yaml -pods/counter -``` - -and then fetch the logs: - -```console -$ kubectl logs counter -0: Tue Jun 2 21:37:31 UTC 2015 -1: Tue Jun 2 21:37:32 UTC 2015 -2: Tue Jun 2 21:37:33 UTC 2015 -3: Tue Jun 2 21:37:34 UTC 2015 -4: Tue Jun 2 21:37:35 UTC 2015 -5: Tue Jun 2 21:37:36 UTC 2015 -... -``` - -If a pod has more than one container then you need to specify which container's log files should -be fetched e.g. - -```console -$ kubectl logs kube-dns-v3-7r1l9 etcd -2015/06/23 00:43:10 etcdserver: start to snapshot (applied: 30003, lastsnap: 20002) -2015/06/23 00:43:10 etcdserver: compacted log at index 30003 -2015/06/23 00:43:10 etcdserver: saved snapshot at index 30003 -2015/06/23 02:05:42 etcdserver: start to snapshot (applied: 40004, lastsnap: 30003) -2015/06/23 02:05:42 etcdserver: compacted log at index 40004 -2015/06/23 02:05:42 etcdserver: saved snapshot at index 40004 -2015/06/23 03:28:31 etcdserver: start to snapshot (applied: 50005, lastsnap: 40004) -2015/06/23 03:28:31 etcdserver: compacted log at index 50005 -2015/06/23 03:28:31 etcdserver: saved snapshot at index 50005 -2015/06/23 03:28:56 filePurge: successfully removed file default.etcd/member/wal/0000000000000000-0000000000000000.wal -2015/06/23 04:51:03 etcdserver: start to snapshot (applied: 60006, lastsnap: 50005) -2015/06/23 04:51:03 etcdserver: compacted log at index 60006 -2015/06/23 04:51:03 etcdserver: saved snapshot at index 60006 -... -``` - -## Cluster level logging to Google Cloud Logging - -The getting started guide [Cluster Level Logging to Google Cloud Logging](../getting-started-guides/logging.md) -explains how container logs are ingested into [Google Cloud Logging](https://cloud.google.com/logging/docs/) -and shows how to query the ingested logs. - -## Cluster level logging with Elasticsearch and Kibana - -The getting started guide [Cluster Level Logging with Elasticsearch and Kibana](../getting-started-guides/logging-elasticsearch.md) -describes how to ingest cluster level logs into Elasticsearch and view them using Kibana. - -## Ingesting Application Log Files - -Cluster level logging only collects the standard output and standard error output of the applications -running in containers. The guide [Collecting log files within containers with Fluentd](http://releases.k8s.io/HEAD/contrib/logging/fluentd-sidecar-gcp/README.md) explains how the log files of applications can also be ingested into Google Cloud logging. - -## Known issues - -Kubernetes does log rotation for Kubernetes components and docker containers. The command `kubectl logs` currently only read the latest logs, not all historical ones. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/logging.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/managing-deployments.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/managing-deployments.md deleted file mode 100644 index 99aad699316c..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/managing-deployments.md +++ /dev/null @@ -1,460 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/managing-deployments.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes User Guide: Managing Applications: Managing deployments - -You’ve deployed your application and exposed it via a service. Now what? Kubernetes provides a number of tools to help you manage your application deployment, including scaling and updating. Among the features we’ll discuss in more depth are [configuration files](configuring-containers.md#configuration-in-kubernetes) and [labels](deploying-applications.md#labels). - -**Table of Contents** - - -- [Kubernetes User Guide: Managing Applications: Managing deployments](#kubernetes-user-guide-managing-applications-managing-deployments) - - [Organizing resource configurations](#organizing-resource-configurations) - - [Bulk operations in kubectl](#bulk-operations-in-kubectl) - - [Using labels effectively](#using-labels-effectively) - - [Canary deployments](#canary-deployments) - - [Updating labels](#updating-labels) - - [Scaling your application](#scaling-your-application) - - [Updating your application without a service outage](#updating-your-application-without-a-service-outage) - - [In-place updates of resources](#in-place-updates-of-resources) - - [Disruptive updates](#disruptive-updates) - - [What's next?](#whats-next) - - - -## Organizing resource configurations - -Many applications require multiple resources to be created, such as a Replication Controller and a Service. Management of multiple resources can be simplified by grouping them together in the same file (separated by `---` in YAML). For example: - -```yaml -apiVersion: v1 -kind: Service -metadata: - name: my-nginx-svc - labels: - app: nginx -spec: - type: LoadBalancer - ports: - - port: 80 - selector: - app: nginx ---- -apiVersion: v1 -kind: ReplicationController -metadata: - name: my-nginx -spec: - replicas: 2 - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx - ports: - - containerPort: 80 -``` - -Multiple resources can be created the same way as a single resource: - -```console -$ kubectl create -f ./nginx-app.yaml -services/my-nginx-svc -replicationcontrollers/my-nginx -``` - -The resources will be created in the order they appear in the file. Therefore, it's best to specify the service first, since that will ensure the scheduler can spread the pods associated with the service as they are created by the replication controller(s). - -`kubectl create` also accepts multiple `-f` arguments: - -```console -$ kubectl create -f ./nginx-svc.yaml -f ./nginx-rc.yaml -``` - -And a directory can be specified rather than or in addition to individual files: - -```console -$ kubectl create -f ./nginx/ -``` - -`kubectl` will read any files with suffixes `.yaml`, `.yml`, or `.json`. - -It is a recommended practice to put resources related to the same microservice or application tier into the same file, and to group all of the files associated with your application in the same directory. If the tiers of your application bind to each other using DNS, then you can then simply deploy all of the components of your stack en masse. - -A URL can also be specified as a configuration source, which is handy for deploying directly from configuration files checked into github: - -```console -$ kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes/master/docs/user-guide/replication.yaml -replicationcontrollers/nginx -``` - -## Bulk operations in kubectl - -Resource creation isn’t the only operation that `kubectl` can perform in bulk. It can also extract resource names from configuration files in order to perform other operations, in particular to delete the same resources you created: - -```console -$ kubectl delete -f ./nginx/ -replicationcontrollers/my-nginx -services/my-nginx-svc -``` - -In the case of just two resources, it’s also easy to specify both on the command line using the resource/name syntax: - -```console -$ kubectl delete replicationcontrollers/my-nginx services/my-nginx-svc -``` - -For larger numbers of resources, one can use labels to filter resources. The selector is specified using `-l`: - -```console -$ kubectl delete all -lapp=nginx -replicationcontrollers/my-nginx -services/my-nginx-svc -``` - -Because `kubectl` outputs resource names in the same syntax it accepts, it’s easy to chain operations using `$()` or `xargs`: - -```console -$ kubectl get $(kubectl create -f ./nginx/ | grep my-nginx) -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -my-nginx nginx nginx app=nginx 2 -NAME LABELS SELECTOR IP(S) PORT(S) -my-nginx-svc app=nginx app=nginx 10.0.152.174 80/TCP -``` - -## Using labels effectively - -The examples we’ve used so far apply at most a single label to any resource. There are many scenarios where multiple labels should be used to distinguish sets from one another. - -For instance, different applications would use different values for the `app` label, but a multi-tier application, such as the [guestbook example](../../examples/guestbook/), would additionally need to distinguish each tier. The frontend could carry the following labels: - -```yaml - labels: - app: guestbook - tier: frontend -``` - -while the Redis master and slave would have different `tier` labels, and perhaps even an additional `role` label: - -```yaml - labels: - app: guestbook - tier: backend - role: master -``` - -and - -```yaml - labels: - app: guestbook - tier: backend - role: slave -``` - -The labels allow us to slice and dice our resources along any dimension specified by a label: - -```console -$ kubectl create -f ./guestbook-fe.yaml -f ./redis-master.yaml -f ./redis-slave.yaml -replicationcontrollers/guestbook-fe -replicationcontrollers/guestbook-redis-master -replicationcontrollers/guestbook-redis-slave -$ kubectl get pods -Lapp -Ltier -Lrole -NAME READY STATUS RESTARTS AGE APP TIER ROLE -guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend -guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend -guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend -guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master -guestbook-redis-slave-2q2yf 1/1 Running 0 1m guestbook backend slave -guestbook-redis-slave-qgazl 1/1 Running 0 1m guestbook backend slave -my-nginx-divi2 1/1 Running 0 29m nginx -my-nginx-o0ef1 1/1 Running 0 29m nginx -$ kubectl get pods -lapp=guestbook,role=slave -NAME READY STATUS RESTARTS AGE -guestbook-redis-slave-2q2yf 1/1 Running 0 3m -guestbook-redis-slave-qgazl 1/1 Running 0 3m -``` - -## Canary deployments - -Another scenario where multiple labels are needed is to distinguish deployments of different releases or configurations of the same component. For example, it is common practice to deploy a *canary* of a new application release (specified via image tag) side by side with the previous release so that the new release can receive live production traffic before fully rolling it out. For instance, a new release of the guestbook frontend might carry the following labels: - -```yaml - labels: - app: guestbook - tier: frontend - track: canary -``` - -and the primary, stable release would have a different value of the `track` label, so that the sets of pods controlled by the two replication controllers would not overlap: - -```yaml - labels: - app: guestbook - tier: frontend - track: stable -``` - -The frontend service would span both sets of replicas by selecting the common subset of their labels, omitting the `track` label: - -```yaml - selector: - app: guestbook - tier: frontend -``` - -## Updating labels - -Sometimes existing pods and other resources need to be relabeled before creating new resources. This can be done with `kubectl label`. For example: - -```console -$ kubectl label pods -lapp=nginx tier=fe -NAME READY STATUS RESTARTS AGE -my-nginx-v4-9gw19 1/1 Running 0 14m -NAME READY STATUS RESTARTS AGE -my-nginx-v4-hayza 1/1 Running 0 13m -NAME READY STATUS RESTARTS AGE -my-nginx-v4-mde6m 1/1 Running 0 17m -NAME READY STATUS RESTARTS AGE -my-nginx-v4-sh6m8 1/1 Running 0 18m -NAME READY STATUS RESTARTS AGE -my-nginx-v4-wfof4 1/1 Running 0 16m -$ kubectl get pods -lapp=nginx -Ltier -NAME READY STATUS RESTARTS AGE TIER -my-nginx-v4-9gw19 1/1 Running 0 15m fe -my-nginx-v4-hayza 1/1 Running 0 14m fe -my-nginx-v4-mde6m 1/1 Running 0 18m fe -my-nginx-v4-sh6m8 1/1 Running 0 19m fe -my-nginx-v4-wfof4 1/1 Running 0 16m fe -``` - -## Scaling your application - -When load on your application grows or shrinks, it’s easy to scale with `kubectl`. For instance, to increase the number of nginx replicas from 2 to 3, do: - -```console -$ kubectl scale rc my-nginx --replicas=3 -scaled -$ kubectl get pods -lapp=nginx -NAME READY STATUS RESTARTS AGE -my-nginx-1jgkf 1/1 Running 0 3m -my-nginx-divi2 1/1 Running 0 1h -my-nginx-o0ef1 1/1 Running 0 1h -``` - -## Updating your application without a service outage - -At some point, you’ll eventually need to update your deployed application, typically by specifying a new image or image tag, as in the canary deployment scenario above. `kubectl` supports several update operations, each of which is applicable to different scenarios. - -To update a service without an outage, `kubectl` supports what is called [“rolling update”](kubectl/kubectl_rolling-update.md), which updates one pod at a time, rather than taking down the entire service at the same time. See the [rolling update design document](../design/simple-rolling-update.md) and the [example of rolling update](update-demo/) for more information. - -Let’s say you were running version 1.7.9 of nginx: - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: my-nginx -spec: - replicas: 5 - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.7.9 - ports: - - containerPort: 80 -``` - -To update to version 1.9.1, you can use [`kubectl rolling-update --image`](../../docs/design/simple-rolling-update.md): - -```console -$ kubectl rolling-update my-nginx --image=nginx:1.9.1 -Creating my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 -``` - -In another window, you can see that `kubectl` added a `deployment` label to the pods, whose value is a hash of the configuration, to distinguish the new pods from the old: - -```console -$ kubectl get pods -lapp=nginx -Ldeployment -NAME READY STATUS RESTARTS AGE DEPLOYMENT -my-nginx-1jgkf 1/1 Running 0 1h 2d1d7a8f682934a254002b56404b813e -my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-k156z 1/1 Running 0 1m ccba8fbd8cc8160970f63f9a2696fc46 -my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-v95yh 1/1 Running 0 35s ccba8fbd8cc8160970f63f9a2696fc46 -my-nginx-divi2 1/1 Running 0 2h 2d1d7a8f682934a254002b56404b813e -my-nginx-o0ef1 1/1 Running 0 2h 2d1d7a8f682934a254002b56404b813e -my-nginx-q6all 1/1 Running 0 8m 2d1d7a8f682934a254002b56404b813e -``` - -`kubectl rolling-update` reports progress as it progresses: - -```console -Updating my-nginx replicas: 4, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 1 -At end of loop: my-nginx replicas: 4, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 1 -At beginning of loop: my-nginx replicas: 3, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 2 -Updating my-nginx replicas: 3, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 2 -At end of loop: my-nginx replicas: 3, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 2 -At beginning of loop: my-nginx replicas: 2, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 3 -Updating my-nginx replicas: 2, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 3 -At end of loop: my-nginx replicas: 2, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 3 -At beginning of loop: my-nginx replicas: 1, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 4 -Updating my-nginx replicas: 1, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 4 -At end of loop: my-nginx replicas: 1, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 4 -At beginning of loop: my-nginx replicas: 0, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 5 -Updating my-nginx replicas: 0, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 5 -At end of loop: my-nginx replicas: 0, my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 replicas: 5 -Update succeeded. Deleting old controller: my-nginx -Renaming my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 to my-nginx -my-nginx -``` - -If you encounter a problem, you can stop the rolling update midway and revert to the previous version using `--rollback`: - -```console -$ kubectl kubectl rolling-update my-nginx --image=nginx:1.9.1 --rollback -Found existing update in progress (my-nginx-ccba8fbd8cc8160970f63f9a2696fc46), resuming. -Found desired replicas.Continuing update with existing controller my-nginx. -Stopping my-nginx-02ca3e87d8685813dbe1f8c164a46f02 replicas: 1 -> 0 -Update succeeded. Deleting my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 -my-nginx -``` - -This is one example where the immutability of containers is a huge asset. - -If you need to update more than just the image (e.g., command arguments, environment variables), you can create a new replication controller, with a new name and distinguishing label value, such as: - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: my-nginx-v4 -spec: - replicas: 5 - selector: - app: nginx - deployment: v4 - template: - metadata: - labels: - app: nginx - deployment: v4 - spec: - containers: - - name: nginx - image: nginx:1.9.2 - args: [“nginx”,”-T”] - ports: - - containerPort: 80 -``` - -and roll it out: - -```console -$ kubectl rolling-update my-nginx -f ./nginx-rc.yaml -Creating my-nginx-v4 -At beginning of loop: my-nginx replicas: 4, my-nginx-v4 replicas: 1 -Updating my-nginx replicas: 4, my-nginx-v4 replicas: 1 -At end of loop: my-nginx replicas: 4, my-nginx-v4 replicas: 1 -At beginning of loop: my-nginx replicas: 3, my-nginx-v4 replicas: 2 -Updating my-nginx replicas: 3, my-nginx-v4 replicas: 2 -At end of loop: my-nginx replicas: 3, my-nginx-v4 replicas: 2 -At beginning of loop: my-nginx replicas: 2, my-nginx-v4 replicas: 3 -Updating my-nginx replicas: 2, my-nginx-v4 replicas: 3 -At end of loop: my-nginx replicas: 2, my-nginx-v4 replicas: 3 -At beginning of loop: my-nginx replicas: 1, my-nginx-v4 replicas: 4 -Updating my-nginx replicas: 1, my-nginx-v4 replicas: 4 -At end of loop: my-nginx replicas: 1, my-nginx-v4 replicas: 4 -At beginning of loop: my-nginx replicas: 0, my-nginx-v4 replicas: 5 -Updating my-nginx replicas: 0, my-nginx-v4 replicas: 5 -At end of loop: my-nginx replicas: 0, my-nginx-v4 replicas: 5 -Update succeeded. Deleting my-nginx -my-nginx-v4 -``` - -You can also run the [update demo](update-demo/) to see a visual representation of the rolling update process. - -## In-place updates of resources - -Sometimes it’s necessary to make narrow, non-disruptive updates to resources you’ve created. For instance, you might want to add an [annotation](annotations.md) with a description of your object. That’s easiest to do with `kubectl patch`: - -```console -$ kubectl patch rc my-nginx-v4 -p '{"metadata": {"annotations": {"description": "my frontend running nginx"}}}' -my-nginx-v4 -$ kubectl get rc my-nginx-v4 -o yaml -apiVersion: v1 -kind: ReplicationController -metadata: - annotations: - description: my frontend running nginx -... -``` - -The patch is specified using json. - -For more significant changes, you can `get` the resource, edit it, and then `replace` the resource with the updated version: - -```console -$ kubectl get rc my-nginx-v4 -o yaml > /tmp/nginx.yaml -$ vi /tmp/nginx.yaml -$ kubectl replace -f /tmp/nginx.yaml -replicationcontrollers/my-nginx-v4 -$ rm $TMP -``` - -The system ensures that you don’t clobber changes made by other users or components by confirming that the `resourceVersion` doesn’t differ from the version you edited. If you want to update regardless of other changes, remove the `resourceVersion` field when you edit the resource. However, if you do this, don’t use your original configuration file as the source since additional fields most likely were set in the live state. - -## Disruptive updates - -In some cases, you may need to update resource fields that cannot be updated once initialized, or you may just want to make a recursive change immediately, such as to fix broken pods created by a replication controller. To change such fields, use `replace --force`, which deletes and re-creates the resource. In this case, you can simply modify your original configuration file: - -```console -$ kubectl replace -f ./nginx-rc.yaml --force -replicationcontrollers/my-nginx-v4 -replicationcontrollers/my-nginx-v4 -``` - -## What's next? - -- [Learn about how to use `kubectl` for application introspection and debugging.](introspection-and-debugging.md) -- [Tips and tricks when working with config](config-best-practices.md) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/managing-deployments.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/monitoring-architecture.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/monitoring-architecture.png deleted file mode 100644 index 4d0582f909ae0d90111897b702dda8376296b4e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22972 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 X(}^{HmWk`4fsYZ|T)$k`<<5TrGHVt` diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/monitoring.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/monitoring.md deleted file mode 100644 index 67ba04205863..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/monitoring.md +++ /dev/null @@ -1,97 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/monitoring.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Resource Usage Monitoring in Kubernetes - -Understanding how an application behaves when deployed is crucial to scaling the application and providing a reliable service. In a Kubernetes cluster, application performance can be examined at many different levels: containers, [pods](pods.md), [services](services.md), and whole clusters. As part of Kubernetes we want to provide users with detailed resource usage information about their running applications at all these levels. This will give users deep insights into how their applications are performing and where possible application bottlenecks may be found. In comes [Heapster](https://github.com/GoogleCloudPlatform/heapster), a project meant to provide a base monitoring platform on Kubernetes. - -### Overview - -Heapster is a cluster-wide aggregator of monitoring and event data. It currently supports Kubernetes natively and works on all Kubernetes setups. Heapster runs as a pod in the cluster, similar to how any Kubernetes application would run. The Heapster pod discovers all nodes in the cluster and queries usage information from the nodes’ [Kubelet](../../DESIGN.md#kubelet)s, the on-machine Kubernetes agent. The Kubelet itself fetches the data from [cAdvisor](https://github.com/google/cadvisor). Heapster groups the information by pod along with the relevant labels. This data is then pushed to a configurable backend for storage and visualization. Currently supported backends include [InfluxDB](http://influxdb.com/) (with [Grafana](http://grafana.org/) for visualization) and [Google Cloud Monitoring](https://cloud.google.com/monitoring/). The overall architecture of the service can be seen below: - -![overall monitoring architecture](monitoring-architecture.png) - -Let’s look at some of the other components in more detail. - -### cAdvisor - -cAdvisor is an open source container resource usage and performance analysis agent. It is purpose built for containers and supports Docker containers natively. In Kubernetes, cadvisor is integrated into the Kubelet binary. cAdvisor auto-discovers all containers in the machine and collects CPU, memory, filesystem, and network usage statistics. cAdvisor also provides the overall machine usage by analyzing the “root” container on the machine. - -On most Kubernetes clusters, cAdvisor exposes a simple UI for on-machine containers on port 4194. Here is a snapshot of part of cAdvisor’s UI that shows the overall machine usage: - -![cAdvisor](cadvisor.png) - -### Kubelet - -The Kubelet acts as a bridge between the Kubernetes master and the nodes. It manages the pods and containers running on a machine. Kubelet translates each pod into its constituent containers and fetches individual container usage statistics from cAdvisor. It then exposes the aggregated pod resource usage statistics via a REST API. - -## Storage Backends - -### InfluxDB and Grafana - -A Grafana setup with InfluxDB is a very popular combination for monitoring in the open source world. InfluxDB exposes an easy to use API to write and fetch time series data. Heapster is setup to use this storage backend by default on most Kubernetes clusters. A detailed setup guide can be found [here](https://github.com/GoogleCloudPlatform/heapster/blob/master/docs/influxdb.md). InfluxDB and Grafana run in Pods. The pod exposes itself as a Kubernetes service which is how Heapster discovers it. - -The Grafana container serves Grafana’s UI which provides an easy to configure dashboard interface. The default dashboard for Kubernetes contains an example dashboard that monitors resource usage of the cluster and the pods inside of it. This dashboard can easily be customized and expanded. Take a look at the storage schema for InfluxDB [here](https://github.com/GoogleCloudPlatform/heapster/blob/master/docs/storage-schema.md#metrics). - -Here is a video showing how to monitor a Kubernetes cluster using heapster, InfluxDB and Grafana: - -[![How to monitor a Kubernetes cluster using heapster, InfluxDB and Grafana](http://img.youtube.com/vi/SZgqjMrxo3g/0.jpg)](http://www.youtube.com/watch?v=SZgqjMrxo3g) - -Here is a snapshot of the default Kubernetes Grafana dashboard that shows the CPU and Memory usage of the entire cluster, individual pods and containers: - -![snapshot of the default Kubernetes Grafana dashboard](influx.png) - -### Google Cloud Monitoring - -Google Cloud Monitoring is a hosted monitoring service that allows you to visualize and alert on important metrics in your application. Heapster can be setup to automatically push all collected metrics to Google Cloud Monitoring. These metrics are then available in the [Cloud Monitoring Console](https://app.google.stackdriver.com/). This storage backend is the easiest to setup and maintain. The monitoring console allows you to easily create and customize dashboards using the exported data. - -Here is a video showing how to setup and run a Google Cloud Monitoring backed Heapster: - -[![how to setup and run a Google Cloud Monitoring backed Heapster](http://img.youtube.com/vi/xSMNR2fcoLs/0.jpg)](http://www.youtube.com/watch?v=xSMNR2fcoLs) - -Here is a snapshot of the a Google Cloud Monitoring dashboard showing cluster-wide resource usage. - -![Google Cloud Monitoring dashboard](gcm.png) - -## Try it out! - -Now that you’ve learned a bit about Heapster, feel free to try it out on your own clusters! The [Heapster repository](https://github.com/GoogleCloudPlatform/heapster) is available on GitHub. It contains detailed instructions to setup Heapster and its storage backends. Heapster runs by default on most Kubernetes clusters, so you may already have it! Feedback is always welcome. Please let us know if you run into any issues. Heapster and Kubernetes developers hang out in the [#google-containers](http://webchat.freenode.net/?channels=google-containers) IRC channel on freenode.net. You can also reach us on the [google-containers Google Groups mailing list](https://groups.google.com/forum/#!forum/google-containers). - -*** -*Authors: Vishnu Kannan and Victor Marmol, Google Software Engineers.* -*This article was originally posted in [Kubernetes blog](http://blog.kubernetes.io/2015/05/resource-usage-monitoring-kubernetes.html).* - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/monitoring.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/namespaces.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/namespaces.md deleted file mode 100644 index 4a1fcab8d37c..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/namespaces.md +++ /dev/null @@ -1,125 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/namespaces.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Namespaces - -Kubernetes supports multiple virtual clusters backed by the same physical cluster. -These virtual clusters are called namespaces. - -## When to Use Multiple Namespaces - -Namespaces are intended for use in environments with many users spread across multiple -teams, or projects. For clusters with a few to tens of users, you should not -need to create or think about namespaces at all. Start using namespaces when you -need the features they provide. - -Namespaces provide a scope for names. Names of resources need to be unique within a namespace, but not across namespaces. - -Namespaces are a way to divide cluster resources between multiple uses (via [resource quota](../../docs/admin/resource-quota.md). - -In future versions of Kubernetes, objects in the same namespace will have the same -access control policies by default. - -It is not necessary to use multiple namespaces just to separate slightly different -resources, such as different versions of the same software: use [labels](#labels.md) to distinguish -resources within the same namespace. - -## Working with Namespaces - -Creation and deletion of namespaces is described in the [Admin Guide documentation -for namespaces](#../../docs/admin/namespaces.md) - -### Viewing namespaces - -You can list the current namespaces in a cluster using: - -```console -$ kubectl get namespaces -NAME LABELS STATUS -default Active -kube-system Active -``` - -Kubernetes starts with two initial namespaces: - * `default` The default namespace for objects with no other namespace - * `kube-system` The namespace for objects created by the Kubernetes system - -### Setting the namespace for a request - -To temporarily set the namespace for a request, use the `--namespace` flag. - -For example: - -```console -$ kubectl --namespace= run nginx --image=nginx -$ kubectl --namespace= get pods -``` - -### Setting the namespace preference - -You can permanently save the namespace for all subsequent kubectl commands in that -context. - -First get your current context: - -```console -$ export CONTEXT=$(kubectl config view | grep current-context | awk '{print $2}') -``` - -Then update the default namespace: - -```console -$ kubectl config set-context $(CONTEXT) --namespace= -``` - -## Namespaces and DNS - -When you create a [Service](services.md), it creates a corresponding [DNS entry](../admin/dns.md)1. -This entry is of the form `..cluster.local`, which means -that if a container just uses `` it will resolve to the service which -is local to a namespace. This is useful for using the same configuration across -multiple namespaces such as Development, Staging and Production. If you want to reach -across namespaces, you need to use the fully qualified domain name (FQDN). - -## Not All Objects are in a Namespace - -Most kubernetes resources (e.g. pods, services, replication controllers, and others) are -in a some namespace. However namespace resources are not themselves in a namespace. -And, low-level resources, such as [nodes](../../docs/admin/node.md) and -persistentVolumes, are not in any namespace. Events are an exception: they may or may not -have a namespace, depending on the object the event is about. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/namespaces.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/node-selection/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/node-selection/README.md deleted file mode 100644 index a3bbe7b48175..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/node-selection/README.md +++ /dev/null @@ -1,98 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/node-selection/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Node selection example - -This example shows how to assign a [pod](../pods.md) to a specific [node](../../admin/node.md) or to one of a set of nodes using node labels and the nodeSelector field in a pod specification. Generally this is unnecessary, as the scheduler will take care of things for you, but you may want to do so in certain circumstances like to ensure that your pod ends up on a machine with an SSD attached to it. - -### Step Zero: Prerequisites - -This example assumes that you have a basic understanding of Kubernetes pods and that you have [turned up a Kubernetes cluster](https://k8s.io/kubernetes#documentation). - -### Step One: Attach label to the node - -Run `kubectl get nodes` to get the names of your cluster's nodes. Pick out the one that you want to add a label to. - -Then, to add a label to the node you've chosen, run `kubectl label nodes =`. For example, if my node name is 'kubernetes-foo-node-1.c.a-robinson.internal' and my desired label is 'disktype=ssd', then I can run `kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd`. - -If this fails with an "invalid command" error, you're likely using an older version of kubectl that doesn't have the `label` command. In that case, see the [previous version](https://k8s.io/kubernetes/blob/a053dbc313572ed60d89dae9821ecab8bfd676dc/examples/node-selection/README.md) of this guide for instructions on how to manually set labels on a node. - -Also, note that label keys must be in the form of DNS labels (as described in the [identifiers doc](../../../docs/design/identifiers.md)), meaning that they are not allowed to contain any upper-case letters. - -You can verify that it worked by re-running `kubectl get nodes` and checking that the node now has a label. - -### Step Two: Add a nodeSelector field to your pod configuration - -Take whatever pod config file you want to run, and add a nodeSelector section to it, like this. For example, if this is my pod config: - -
      -apiVersion: v1
      -kind: Pod
      -metadata:
      -  name: nginx
      -  labels:
      -    env: test
      -spec:
      -  containers:
      -  - name: nginx
      -    image: nginx
      -
      - -Then add a nodeSelector like so: - -
      -apiVersion: v1
      -kind: Pod
      -metadata:
      -  name: nginx
      -  labels:
      -    env: test
      -spec:
      -  containers:
      -  - name: nginx
      -    image: nginx
      -    imagePullPolicy: IfNotPresent
      -  nodeSelector:
      -    disktype: ssd
      -
      - -When you then run `kubectl create -f pod.yaml`, the pod will get scheduled on the node that you attached the label to! You can verify that it worked by running `kubectl get pods -o wide` and looking at the "NODE" that the pod was assigned to. - -### Conclusion - -While this example only covered one node, you can attach labels to as many nodes as you want. Then when you schedule a pod with a nodeSelector, it can be scheduled on any of the nodes that satisfy that nodeSelector. Be careful that it will match at least one node, however, because if it doesn't the pod won't be scheduled at all. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/node-selection/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/overview.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/overview.md deleted file mode 100644 index 9d537ece202f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/overview.md +++ /dev/null @@ -1,59 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/overview.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes Overview - -Kubernetes is an open-source system for managing containerized applications across multiple hosts in a cluster. Kubernetes is intended to make deploying containerized/microservice-based applications easy but powerful. - -Kubernetes provides mechanisms for application deployment, scheduling, updating, maintenance, and scaling. A key feature of Kubernetes is that it actively manages the containers to ensure that the state of the cluster continually matches the user's intentions. An operations user should be able to launch a micro-service, letting the scheduler find the right placement. We also want to improve the tools and experience for how users can roll-out applications through patterns like canary deployments. - -Kubernetes supports [Docker](http://www.docker.io) and [Rocket](https://coreos.com/blog/rocket/) containers, and other container image formats and container runtimes will be supported in the future. - -While Kubernetes currently focuses on continuously-running stateless (e.g. web server or in-memory object cache) and "cloud native" stateful applications (e.g. NoSQL datastores), in the near future it will support all the other workload types commonly found in production cluster environments, such as batch, stream processing, and traditional databases. - -In Kubernetes, all containers run inside [pods](pods.md). A pod can host a single container, or multiple cooperating containers; in the latter case, the containers in the pod are guaranteed to be co-located on the same machine and can share resources. A pod can also contain zero or more [volumes](volumes.md), which are directories that are private to a container or shared across containers in a pod. For each pod the user creates, the system finds a machine that is healthy and that has sufficient available capacity, and starts up the corresponding container(s) there. If a container fails it can be automatically restarted by Kubernetes' node agent, called the Kubelet. But if the pod or its machine fails, it is not automatically moved or restarted unless the user also defines a [replication controller](replication-controller.md), which we discuss next. - -Users can create and manage pods themselves, but Kubernetes drastically simplifies system management by allowing users to delegate two common pod-related activities: deploying multiple pod replicas based on the same pod configuration, and creating replacement pods when a pod or its machine fails. The Kubernetes API object that manages these behaviors is called a [replication controller](replication-controller.md). It defines a pod in terms of a template, that the system then instantiates as some number of pods (specified by the user). The replicated set of pods might constitute an entire application, a micro-service, or one layer in a multi-tier application. Once the pods are created, the system continually monitors their health and that of the machines they are running on; if a pod fails due to a software problem or machine failure, the replication controller automatically creates a new pod on a healthy machine, to maintain the set of pods at the desired replication level. Multiple pods from the same or different applications can share the same machine. Note that a replication controller is needed even in the case of a single non-replicated pod if the user wants it to be re-created when it or its machine fails. - -Frequently it is useful to refer to a set of pods, for example to limit the set of pods on which a mutating operation should be performed, or that should be queried for status. As a general mechanism, users can attach to most Kubernetes API objects arbitrary key-value pairs called [labels](labels.md), and then use a set of label selectors (key-value queries over labels) to constrain the target of API operations. Each resource also has a map of string keys and values that can be used by external tooling to store and retrieve arbitrary metadata about this object, called [annotations](annotations.md). - -Kubernetes supports a unique [networking model](../admin/networking.md). Kubernetes encourages a flat address space and does not dynamically allocate ports, instead allowing users to select whichever ports are convenient for them. To achieve this, it allocates an IP address for each pod. - -Modern Internet applications are commonly built by layering micro-services, for example a set of web front-ends talking to a distributed in-memory key-value store talking to a replicated storage service. To facilitate this architecture, Kubernetes offers the [service](services.md) abstraction, which provides a stable IP address and [DNS name](../admin/dns.md) that corresponds to a dynamic set of pods such as the set of pods constituting a micro-service. The set is defined using a label selector and thus can refer to any set of pods. When a container running in a Kubernetes pod connects to this address, the connection is forwarded by a local agent (called the kube proxy) running on the source machine, to one of the corresponding back-end containers. The exact back-end is chosen using a round-robin policy to balance load. The kube proxy takes care of tracking the dynamic set of back-ends as pods are replaced by new pods on new hosts, so that the service IP address (and DNS name) never changes. - -Every resource in Kubernetes, such as a pod, is identified by a URI and has a UID. Important components of the URI are the kind of object (e.g. pod), the object’s name, and the object’s [namespace](namespaces.md). For a certain object kind, every name is unique within its namespace. In contexts where an object name is provided without a namespace, it is assumed to be in the default namespace. UID is unique across time and space. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/overview.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/persistent-volumes.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/persistent-volumes.md deleted file mode 100644 index 92b58904ffe8..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/persistent-volumes.md +++ /dev/null @@ -1,230 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/persistent-volumes.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Persistent Volumes and Claims - -This document describes the current state of `PersistentVolumes` in Kubernetes. Familiarity with [volumes](volumes.md) is suggested. - -**Table of Contents** - - -- [Persistent Volumes and Claims](#persistent-volumes-and-claims) - - [Introduction](#introduction) - - [Lifecycle of a volume and claim](#lifecycle-of-a-volume-and-claim) - - [Provisioning](#provisioning) - - [Binding](#binding) - - [Using](#using) - - [Releasing](#releasing) - - [Reclaiming](#reclaiming) - - [Types of Persistent Volumes](#types-of-persistent-volumes) - - [Persistent Volumes](#persistent-volumes) - - [Capacity](#capacity) - - [Access Modes](#access-modes) - - [Recycling Policy](#recycling-policy) - - [Phase](#phase) - - [PersistentVolumeClaims](#persistentvolumeclaims) - - [Access Modes](#access-modes) - - [Resources](#resources) - - [Claims As Volumes](#claims-as-volumes) - - - -## Introduction - -Managing storage is a distinct problem from managing compute. The `PersistentVolume` subsystem provides an API for users and administrators that abstracts details of how storage is provided from how it is consumed. To do this we introduce two new API resources: `PersistentVolume` and `PersistentVolumeClaim`. - -A `PersistentVolume` (PV) is a piece of networked storage in the cluster that has been provisioned by an administrator. It is a resource in the cluster just like a node is a cluster resource. PVs are volume plugins like Volumes, but have a lifecycle independent of any individual pod that uses the PV. This API object captures the details of the implementation of the storage, be that NFS, iSCSI, or a cloud-provider-specific storage system. - -A `PersistentVolumeClaim` (PVC) is a request for storage by a user. It is similar to a pod. Pods consume node resources and PVCs consume PV resources. Pods can request specific levels of resources (CPU and Memory). Claims can request specific size and access modes (e.g, can be mounted once read/write or many times read-only). - -Please see the [detailed walkthrough with working examples](persistent-volumes/). - - -## Lifecycle of a volume and claim - -PVs are resources in the cluster. PVC are requests for those resources and also act as claim checks to the resource. The interaction between PVs and PVCs follows this lifecycle: - -### Provisioning - -A cluster administrator creates some number of PVs. They carry the details of the real storage that is available for use by cluster users. They exist in the Kubernetes API and are available for consumption. - -### Binding - -A user creates a `PersistentVolumeClaim` with a specific amount of storage requested and with certain access modes. A control loop in the master watches for new PVCs, finds a matching PV (if possible), and binds them together. The user will always get at least what they asked for, but the volume may be in excess of what was requested. - -Claims will remain unbound indefinitely if a matching volume does not exist. Claims will be bound as matching volumes become available. For example, a cluster provisioned with many 50Gi volumes would not match a PVC requesting 100Gi. The PVC can be bound when a 100Gi PV is added to the cluster. - -### Using - -Pods use claims as volumes. The cluster inspects the claim to find the bound volume and mounts that volume for a pod. For those volumes that support multiple access modes, the user specifies which mode desired when using their claim as a volume in a pod. - -Once a user has a claim and that claim is bound, the bound PV belongs to the user for as long as she needs it. Users schedule Pods and access their claimed PVs by including a persistentVolumeClaim in their Pod's volumes block. [See below for syntax details](#claims-as-volumes). - -### Releasing - -When a user is done with their volume, they can delete the PVC objects from the API which allows reclamation of the resource. The volume is considered "released" when the claim is deleted, but it is not yet available for another claim. The previous claimant's data remains on the volume which must be handled according to policy. - -### Reclaiming - -A `PersistentVolume's` reclaim policy tells the cluster what to do with the volume after it's released. Currently, volumes can either be Retained or Recycled. Retention allows for manual reclamation of the resource. For those volume plugins that support it, recycling performs a basic scrub ("rm -rf /thevolume/*") on the volume and makes it available again for a new claim. - -## Types of Persistent Volumes - -`PersistentVolume`s are implemented as plugins. Kubernetes currently supports the following plugins: - -* GCEPersistentDisk -* AWSElasticBlockStore -* NFS -* iSCSI -* RBD (Ceph Block Device) -* Glusterfs -* HostPath (single node testing only) - - -## Persistent Volumes - -Each PV contains a spec and status, which is the specification and status of the volume. - - -```yaml - apiVersion: v1 - kind: PersistentVolume - metadata: - name: pv0003 - spec: - capacity: - storage: 5Gi - accessModes: - - ReadWriteOnce - persistentVolumeReclaimPolicy: Recycle - nfs: - path: /tmp - server: 172.17.0.2 -``` - -### Capacity - -Generally, a PV will have a specific storage capacity. This is set using the PV's `capacity` attribute. See the Kubernetes [Resource Model](../design/resources.md) to understand the units expected by `capacity`. - -Currently, storage size is the only resource that can be set or requested. Future attributes may include IOPS, throughput, etc. - -### Access Modes - -`PersistentVolume`s can be mounted on a host in any way supported by the resource provider. Providers will have different capabilities and each PV's access modes are set to the specific modes supported by that particular volume. For example, NFS can support multiple read/write clients, but a specific NFS PV might be exported on the server as read-only. Each PV gets its own set of access modes describing that specific PV's capabilities. - -The access modes are: - -* ReadWriteOnce -- the volume can be mounted as read-write by a single node -* ReadOnlyMany -- the volume can be mounted read-only by many nodes -* ReadWriteMany -- the volume can be mounted as read-write by many nodes - -In the CLI, the access modes are abbreviated to: - -* RWO - ReadWriteOnce -* ROX - ReadOnlyMany -* RWX - ReadWriteMany - -> __Important!__ A volume can only be mounted using one access mode at a time, even if it supports many. For example, a GCEPersistentDisk can be mounted as ReadWriteOnce by a single node or ReadOnlyMany by many nodes, but not at the same time. - - -### Recycling Policy - -Current recycling policies are: - -* Retain -- manual reclamation -* Recycle -- basic scrub ("rm -rf /thevolume/*") - -Currently, NFS and HostPath support recycling. - -### Phase - -A volume will be in one of the following phases: - -* Available -- a free resource that is not yet bound to a claim -* Bound -- the volume is bound to a claim -* Released -- the claim has been deleted, but the resource is not yet reclaimed by the cluster -* Failed -- the volume has failed its automatic reclamation - -The CLI will show the name of the PVC bound to the PV. - -## PersistentVolumeClaims - -Each PVC contains a spec and status, which is the specification and status of the claim. - -```yaml -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: myclaim -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi -``` - -### Access Modes - -Claims use the same conventions as volumes when requesting storage with specific access modes. - -### Resources - -Claims, like pods, can request specific quantities of a resource. In this case, the request is for storage. The same [resource model](../design/resources.md) applies to both volumes and claims. - -## Claims As Volumes - -Pods access storage by using the claim as a volume. Claims must exist in the same namespace as the pod using the claim. The cluster finds the claim in the pod's namespace and uses it to get the `PersistentVolume` backing the claim. The volume is then mounted to the host and into the pod. - -```yaml -kind: Pod -apiVersion: v1 -metadata: - name: mypod -spec: - containers: - - name: myfrontend - image: dockerfile/nginx - volumeMounts: - - mountPath: "/var/www/html" - name: mypd - volumes: - - name: mypd - persistentVolumeClaim: - claimName: myclaim -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/persistent-volumes.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/persistent-volumes/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/persistent-volumes/README.md deleted file mode 100644 index 22c48a17246a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/persistent-volumes/README.md +++ /dev/null @@ -1,133 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/persistent-volumes/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# How To Use Persistent Volumes - -The purpose of this guide is to help you become familiar with [Kubernetes Persistent Volumes](../persistent-volumes.md). By the end of the guide, we'll have -nginx serving content from your persistent volume. - -This guide assumes knowledge of Kubernetes fundamentals and that you have a cluster up and running. - -See [Persistent Storage design document](../../design/persistent-storage.md) for more information. - -## Provisioning - -A Persistent Volume (PV) in Kubernetes represents a real piece of underlying storage capacity in the infrastructure. Cluster administrators -must first create storage (create their Google Compute Engine (GCE) disks, export their NFS shares, etc.) in order for Kubernetes to mount it. - -PVs are intended for "network volumes" like GCE Persistent Disks, NFS shares, and AWS ElasticBlockStore volumes. `HostPath` was included -for ease of development and testing. You'll create a local `HostPath` for this example. - -> IMPORTANT! For `HostPath` to work, you will need to run a single node cluster. Kubernetes does not -support local storage on the host at this time. There is no guarantee your pod ends up on the correct node where the `HostPath` resides. - - - -```console -# This will be nginx's webroot -$ mkdir /tmp/data01 -$ echo 'I love Kubernetes storage!' > /tmp/data01/index.html -``` - -PVs are created by posting them to the API server. - -```console -$ kubectl create -f docs/user-guide/persistent-volumes/volumes/local-01.yaml -NAME LABELS CAPACITY ACCESSMODES STATUS CLAIM REASON -pv0001 type=local 10737418240 RWO Available -``` - -## Requesting storage - -Users of Kubernetes request persistent storage for their pods. They don't know how the underlying cluster is provisioned. -They just know they can rely on their claim to storage and can manage its lifecycle independently from the many pods that may use it. - -Claims must be created in the same namespace as the pods that use them. - -```console -$ kubectl create -f docs/user-guide/persistent-volumes/claims/claim-01.yaml - -$ kubectl get pvc -NAME LABELS STATUS VOLUME -myclaim-1 map[] - - -# A background process will attempt to match this claim to a volume. -# The eventual state of your claim will look something like this: - -$ kubectl get pvc -NAME LABELS STATUS VOLUME -myclaim-1 map[] Bound pv0001 - -$ kubectl get pv -NAME LABELS CAPACITY ACCESSMODES STATUS CLAIM REASON -pv0001 type=local 10737418240 RWO Bound default/myclaim-1 -``` - -## Using your claim as a volume - -Claims are used as volumes in pods. Kubernetes uses the claim to look up its bound PV. The PV is then exposed to the pod. - -```console -$ kubectl create -f docs/user-guide/persistent-volumes/simpletest/pod.yaml - -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -mypod 1/1 Running 0 1h - -$ kubectl create -f docs/user-guide/persistent-volumes/simpletest/service.json -$ kubectl get services -NAME LABELS SELECTOR IP(S) PORT(S) -frontendservice name=frontendhttp 10.0.0.241 3000/TCP -kubernetes component=apiserver,provider=kubernetes 10.0.0.2 443/TCP -``` - -## Next steps - -You should be able to query your service endpoint and see what content nginx is serving. A "forbidden" error might mean you -need to disable SELinux (setenforce 0). - -```console -$ curl 10.0.0.241:3000 -I love Kubernetes storage! -``` - -Hopefully this simple guide is enough to get you started with PersistentVolumes. If you have any questions, join -[`#google-containers`](https://botbot.me/freenode/google-containers/) on IRC and ask! - -Enjoy! - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/persistent-volumes/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/pod-states.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/pod-states.md deleted file mode 100644 index 63c53740ae05..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/pod-states.md +++ /dev/null @@ -1,143 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/pod-states.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# The life of a pod - -Updated: 4/14/2015 - -This document covers the lifecycle of a pod. It is not an exhaustive document, but an introduction to the topic. - -## Pod Phase - -As consistent with the overall [API convention](../devel/api-conventions.md#typical-status-properties), phase is a simple, high-level summary of the phase of the lifecycle of a pod. It is not intended to be a comprehensive rollup of observations of container-level or even pod-level conditions or other state, nor is it intended to be a comprehensive state machine. - -The number and meanings of `PodPhase` values are tightly guarded. Other than what is documented here, nothing should be assumed about pods with a given `PodPhase`. - -* Pending: The pod has been accepted by the system, but one or more of the container images has not been created. This includes time before being scheduled as well as time spent downloading images over the network, which could take a while. -* Running: The pod has been bound to a node, and all of the containers have been created. At least one container is still running, or is in the process of starting or restarting. -* Succeeded: All containers in the pod have terminated in success, and will not be restarted. -* Failed: All containers in the pod have terminated, at least one container has terminated in failure (exited with non-zero exit status or was terminated by the system). - -## Pod Conditions - -A pod containing containers that specify readiness probes will also report the Ready condition. Condition status values may be `True`, `False`, or `Unknown`. - -## Container Probes - -A [Probe](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#Probe) is a diagnostic performed periodically by the kubelet on a container. Specifically the diagnostic is one of three [Handlers](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#Handler): - -* `ExecAction`: executes a specified command inside the container expecting on success that the command exits with status code 0. -* `TCPSocketAction`: performs a tcp check against the container's IP address on a specified port expecting on success that the port is open. -* `HTTPGetAction`: performs an HTTP Get againsts the container's IP address on a specified port and path expecting on success that the response has a status code greater than or equal to 200 and less than 400. - -Each probe will have one of three results: - -* `Success`: indicates that the container passed the diagnostic. -* `Failure`: indicates that the container failed the diagnostic. -* `Unknown`: indicates that the diagnostic failed so no action should be taken. - -Currently, the kubelet optionally performs two independent diagnostics on running containers which trigger action: - -* `LivenessProbe`: indicates whether the container is *live*, i.e. still running. The LivenessProbe hints to the kubelet when a container is unhealthy. If the LivenessProbe fails, the kubelet will kill the container and the container will be subjected to it's [RestartPolicy](#restartpolicy). The default state of Liveness before the initial delay is `Success`. The state of Liveness for a container when no probe is provided is assumed to be `Success`. -* `ReadinessProbe`: indicates whether the container is *ready* to service requests. If the ReadinessProbe fails, the endpoints controller will remove the pod's IP address from the endpoints of all services that match the pod. Thus, the ReadinessProbe is sometimes useful to signal to the endpoints controller that even though a pod may be running, it should not receive traffic from the proxy (e.g. the container has a long startup time before it starts listening or the container is down for maintenance). The default state of Readiness before the initial delay is `Failure`. The state of Readiness for a container when no probe is provided is assumed to be `Success`. - -## Container Statuses - -More detailed information about the current (and previous) container statuses can be found in [ContainerStatuses](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#PodStatus). The information reported depends on the current [ContainerState](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#ContainerState), which may be Waiting, Running, or Terminated. - -## RestartPolicy - -The possible values for RestartPolicy are `Always`, `OnFailure`, or `Never`. If RestartPolicy is not set, the default value is `Always`. RestartPolicy applies to all containers in the pod. RestartPolicy only refers to restarts of the containers by the Kubelet on the same node. As discussed in the [pods document](pods.md#durability-of-pods-or-lack-thereof), once bound to a node, a pod will never be rebound to another node. This means that some kind of controller is necessary in order for a pod to survive node failure, even if just a single pod at a time is desired. - -The only controller we have today is [`ReplicationController`](replication-controller.md). `ReplicationController` is *only* appropriate for pods with `RestartPolicy = Always`. `ReplicationController` should refuse to instantiate any pod that has a different restart policy. - -There is a legitimate need for a controller which keeps pods with other policies alive. Pods having any of the other policies (`OnFailure` or `Never`) eventually terminate, at which point the controller should stop recreating them. Because of this fundamental distinction, let's hypothesize a new controller, called [`JobController`](https://k8s.io/kubernetes/issues/1624) for the sake of this document, which can implement this policy. - -## Pod lifetime - -In general, pods which are created do not disappear until someone destroys them. This might be a human or a `ReplicationController`. The only exception to this rule is that pods with a `PodPhase` of `Succeeded` or `Failed` for more than some duration (determined by the master) will expire and be automatically reaped. - -If a node dies or is disconnected from the rest of the cluster, some entity within the system (call it the NodeController for now) is responsible for applying policy (e.g. a timeout) and marking any pods on the lost node as `Failed`. - -## Examples - - * Pod is `Running`, 1 container, container exits success - * Log completion event - * If RestartPolicy is: - * Always: restart container, pod stays `Running` - * OnFailure: pod becomes `Succeeded` - * Never: pod becomes `Succeeded` - - * Pod is `Running`, 1 container, container exits failure - * Log failure event - * If RestartPolicy is: - * Always: restart container, pod stays `Running` - * OnFailure: restart container, pod stays `Running` - * Never: pod becomes `Failed` - - * Pod is `Running`, 2 containers, container 1 exits failure - * Log failure event - * If RestartPolicy is: - * Always: restart container, pod stays `Running` - * OnFailure: restart container, pod stays `Running` - * Never: pod stays `Running` - * When container 2 exits... - * Log failure event - * If RestartPolicy is: - * Always: restart container, pod stays `Running` - * OnFailure: restart container, pod stays `Running` - * Never: pod becomes `Failed` - - * Pod is `Running`, container becomes OOM - * Container terminates in failure - * Log OOM event - * If RestartPolicy is: - * Always: restart container, pod stays `Running` - * OnFailure: restart container, pod stays `Running` - * Never: log failure event, pod becomes `Failed` - - * Pod is `Running`, a disk dies - * All containers are killed - * Log appropriate event - * Pod becomes `Failed` - * If running under a controller, pod will be recreated elsewhere - - * Pod is `Running`, its node is segmented out - * NodeController waits for timeout - * NodeController marks pod `Failed` - * If running under a controller, pod will be recreated elsewhere - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/pod-states.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/pods.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/pods.md deleted file mode 100644 index 78519c624e73..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/pods.md +++ /dev/null @@ -1,122 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/pods.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Pods - -In Kubernetes, rather than individual application containers, _pods_ are the smallest deployable units that can be created, scheduled, and managed. - -## What is a _pod_? - -A _pod_ (as in a pod of whales or pea pod) corresponds to a colocated group of applications running with a shared context. Within that context, the applications may also have individual cgroup isolations applied. A pod models an application-specific "logical host" in a containerized environment. It may contain one or more applications which are relatively tightly coupled — in a pre-container world, they would have executed on the same physical or virtual host. - -The context of the pod can be defined as the conjunction of several Linux namespaces: - -* PID namespace (applications within the pod can see each other's processes) -* network namespace (applications within the pod have access to the same IP and port space) -* IPC namespace (applications within the pod can use SystemV IPC or POSIX message queues to communicate) -* UTS namespace (applications within the pod share a hostname) - -Applications within a pod also have access to shared volumes, which are defined at the pod level and made available in each application's filesystem. Additionally, a pod may define top-level cgroup isolations which form an outer bound to any individual isolation applied to constituent applications. - -In terms of [Docker](https://www.docker.com/) constructs, a pod consists of a colocated group of Docker containers with shared [volumes](volumes.md). PID namespace sharing is not yet implemented with Docker. - -Like individual application containers, pods are considered to be relatively ephemeral rather than durable entities. As discussed in [life of a pod](pod-states.md), pods are scheduled to nodes and remain there until termination (according to restart policy) or deletion. When a node dies, the pods scheduled to that node are deleted. Specific pods are never rescheduled to new nodes; instead, they must be replaced (see [replication controller](replication-controller.md) for more details). (In the future, a higher-level API may support pod migration.) - -## Motivation for pods - -### Resource sharing and communication - -Pods facilitate data sharing and communication among their constituents. - -The applications in the pod all use the same network namespace/IP and port space, and can find and communicate with each other using localhost. Each pod has an IP address in a flat shared networking namespace that has full communication with other physical computers and containers across the network. The hostname is set to the pod's Name for the application containers within the pod. [More details on networking](../admin/networking.md). - -In addition to defining the application containers that run in the pod, the pod specifies a set of shared storage volumes. Volumes enable data to survive container restarts and to be shared among the applications within the pod. - -### Management - -Pods also simplify application deployment and management by providing a higher-level abstraction than the raw, low-level container interface. Pods serve as units of deployment and horizontal scaling/replication. Co-location (co-scheduling), fate sharing, coordinated replication, resource sharing, and dependency management are handled automatically. - -## Uses of pods - -Pods can be used to host vertically integrated application stacks, but their primary motivation is to support co-located, co-managed helper programs, such as: - -* content management systems, file and data loaders, local cache managers, etc. -* log and checkpoint backup, compression, rotation, snapshotting, etc. -* data change watchers, log tailers, logging and monitoring adapters, event publishers, etc. -* proxies, bridges, and adapters -* controllers, managers, configurators, and updaters - -Individual pods are not intended to run multiple instances of the same application, in general. - -## Alternatives considered - -_Why not just run multiple programs in a single (Docker) container?_ - -1. Transparency. Making the containers within the pod visible to the infrastructure enables the infrastructure to provide services to those containers, such as process management and resource monitoring. This facilitates a number of conveniences for users. -2. Decoupling software dependencies. The individual containers may be rebuilt and redeployed independently. Kubernetes may even support live updates of individual containers someday. -3. Ease of use. Users don't need to run their own process managers, worry about signal and exit-code propagation, etc. -4. Efficiency. Because the infrastructure takes on more responsibility, containers can be lighter weight. - -_Why not support affinity-based co-scheduling of containers?_ - -That approach would provide co-location, but would not provide most of the benefits of pods, such as resource sharing, IPC, guaranteed fate sharing, and simplified management. - -## Durability of pods (or lack thereof) - -Pods aren't intended to be treated as durable [pets](https://blog.engineyard.com/2014/pets-vs-cattle). They won't survive scheduling failures, node failures, or other evictions, such as due to lack of resources, or in the case of node maintenance. - -In general, users shouldn't need to create pods directly. They should almost always use controllers (e.g., [replication controller](replication-controller.md)), even for singletons. Controllers provide self-healing with a cluster scope, as well as replication and rollout management. - -The use of collective APIs as the primary user-facing primitive is relatively common among cluster scheduling systems, including [Borg](https://research.google.com/pubs/pub43438.html), [Marathon](https://mesosphere.github.io/marathon/docs/rest-api.html), [Aurora](http://aurora.apache.org/documentation/latest/configuration-reference/#job-schema), and [Tupperware](http://www.slideshare.net/Docker/aravindnarayanan-facebook140613153626phpapp02-37588997). - -Pod is exposed as a primitive in order to facilitate: - -* scheduler and controller pluggability -* support for pod-level operations without the need to "proxy" them via controller APIs -* decoupling of pod lifetime from controller lifetime, such as for bootstrapping -* decoupling of controllers and services — the endpoint controller just watches pods -* clean composition of Kubelet-level functionality with cluster-level functionality — Kubelet is effectively the "pod controller" -* high-availability applications, which will expect pods to be replaced in advance of their termination and certainly in advance of deletion, such as in the case of planned evictions, image prefetching, or live pod migration [#3949](https://k8s.io/kubernetes/issues/3949) - -The current best practice for pets is to create a replication controller with `replicas` equal to `1` and a corresponding service. If you find this cumbersome, please comment on [issue #260](https://k8s.io/kubernetes/issues/260). - -## API Object - -Pod is a top-level resource in the kubernetes REST API. More details about the -API object can be found at: [Pod API -object](https://htmlpreview.github.io/?https://k8s.io/kubernetes/HEAD/docs/api-reference/definitions.html#_v1_pod). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/pods.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/prereqs.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/prereqs.md deleted file mode 100644 index a5eedb21efc6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/prereqs.md +++ /dev/null @@ -1,93 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/prereqs.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes User Guide: Managing Applications: Prerequisites - -To deploy and manage applications on Kubernetes, you’ll use the Kubernetes command-line tool, [kubectl](kubectl/kubectl.md). It lets you inspect your cluster resources, create, delete, and update components, and much more. You will use it to look at your new cluster and bring up example apps. - -## Installing kubectl - -If you downloaded a pre-compiled [release](https://k8s.io/kubernetes/releases), kubectl should be under `platforms//` from the tar bundle. - -If you built from source, kubectl should be either under `_output/local/bin//` or `_output/dockerized/bin//`. - -The kubectl binary doesn't have to be installed to be executable, but the rest of the walkthrough will assume that it's in your PATH. - -The simplest way to install is to copy or move kubectl into a dir already in PATH (e.g. `/usr/local/bin`). For example: - -```console -# OS X -$ sudo cp kubernetes/platforms/darwin/amd64/kubectl /usr/local/bin/kubectl -# Linux -$ sudo cp kubernetes/platforms/linux/amd64/kubectl /usr/local/bin/kubectl -``` - -You also need to ensure it's executable: - -```console -$ sudo chmod +X /usr/local/bin/kubectl -``` - -If you prefer not to copy kubectl, you need to ensure the tool is in your path: - -```bash -# OS X -export PATH=/platforms/darwin/amd64:$PATH - -# Linux -export PATH=/platforms/linux/amd64:$PATH -``` - -## Configuring kubectl - -In order for kubectl to find and access the Kubernetes cluster, it needs a [kubeconfig file](kubeconfig-file.md), which is created automatically when creating a cluster using kube-up.sh (see the [getting started guides](../../docs/getting-started-guides/) for more about creating clusters). If you need access to a cluster you didn’t create, see the [Sharing Cluster Access document](sharing-clusters.md). -By default, kubectl configuration lives at `~/.kube/config`. - -#### Making sure you're ready - -Check that kubectl is properly configured by getting the cluster state: - -```console -$ kubectl cluster-info -``` - -If you see a url response, you are ready to go. - -## What's next? - -[Learn how to launch and expose your application.](quick-start.md) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/prereqs.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/production-pods.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/production-pods.md deleted file mode 100644 index 2f88bda77d82..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/production-pods.md +++ /dev/null @@ -1,387 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/production-pods.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes User Guide: Managing Applications: Working with pods and containers in production - -**Table of Contents** - - -- [Kubernetes User Guide: Managing Applications: Working with pods and containers in production](#kubernetes-user-guide-managing-applications-working-with-pods-and-containers-in-production) - - [Persistent storage](#persistent-storage) - - [Distributing credentials](#distributing-credentials) - - [Authenticating with a private image registry](#authenticating-with-a-private-image-registry) - - [Helper containers](#helper-containers) - - [Resource management](#resource-management) - - [Liveness and readiness probes (aka health checks)](#liveness-and-readiness-probes-aka-health-checks) - - [Lifecycle hooks and termination notice](#lifecycle-hooks-and-termination-notice) - - [Termination message](#termination-message) - - [What's next?](#whats-next) - - - -You’ve seen [how to configure and deploy pods and containers](configuring-containers.md), using some of the most common configuration parameters. This section dives into additional features that are especially useful for running applications in production. - -## Persistent storage - -The container file system only lives as long as the container does, so when a container crashes and restarts, changes to the filesystem will be lost and the container will restart from a clean slate. To access more-persistent storage, outside the container file system, you need a [*volume*](volumes.md). This is especially important to stateful applications, such as key-value stores and databases. - -For example, [Redis](http://redis.io/) is a key-value cache and store, which we use in the [guestbook](../../examples/guestbook/) and other examples. We can add a volume to it to store persistent data as follows: - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: redis -spec: - template: - metadata: - labels: - app: redis - tier: backend - spec: - # Provision a fresh volume for the pod - volumes: - - name: data - emptyDir: {} - containers: - - name: redis - image: kubernetes/redis:v1 - ports: - - containerPort: 6379 - # Mount the volume into the pod - volumeMounts: - - mountPath: /redis-master-data - name: data # must match the name of the volume, above -``` - -`emptyDir` volumes live for the lifespan of the [pod](pods.md), which is longer than the lifespan of any one container, so if the container fails and is restarted, our storage will live on. - -In addition to the local disk storage provided by `emptyDir`, Kubernetes supports many different network-attached storage solutions, including PD on GCE and EBS on EC2, which are preferred for critical data, and will handle details such as mounting and unmounting the devices on the nodes. See [the volumes doc](volumes.md) for more details. - -## Distributing credentials - -Many applications need credentials, such as passwords, OAuth tokens, and TLS keys, to authenticate with other applications, databases, and services. Storing these credentials in container images or environment variables is less than ideal, since the credentials can then be copied by anyone with access to the image, pod/container specification, host file system, or host Docker daemon. - -Kubernetes provides a mechanism, called [*secrets*](secrets.md), that facilitates delivery of sensitive credentials to applications. A `Secret` is a simple resource containing a map of data. For instance, a simple secret with a username and password might look as follows: - -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: mysecret -type: Opaque -data: - password: dmFsdWUtMg0K - username: dmFsdWUtMQ0K -``` - -As with other resources, this secret can be instantiated using `create` and can be viewed with `get`: - -```console -$ kubectl create -f ./secret.yaml -secrets/mysecret -$ kubectl get secrets -NAME TYPE DATA -default-token-v9pyz kubernetes.io/service-account-token 2 -mysecret Opaque 2 -``` - -To use the secret, you need to reference it in a pod or pod template. The `secret` volume source enables you to mount it as an in-memory directory into your containers. - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: redis -spec: - template: - metadata: - labels: - app: redis - tier: backend - spec: - volumes: - - name: data - emptyDir: {} - - name: supersecret - secret: - secretName: mysecret - containers: - - name: redis - image: kubernetes/redis:v1 - ports: - - containerPort: 6379 - # Mount the volume into the pod - volumeMounts: - - mountPath: /redis-master-data - name: data # must match the name of the volume, above - - mountPath: /var/run/secrets/super - name: supersecret -``` - -For more details, see the [secrets document](secrets.md), [example](secrets/) and [design doc](../../docs/design/secrets.md). - -## Authenticating with a private image registry - -Secrets can also be used to pass [image registry credentials](images.md#using-a-private-registry). - -First, create a `.dockercfg` file, such as running `docker login `. -Then put the resulting `.dockercfg` file into a [secret resource](secrets.md). For example: - -```console -$ docker login -Username: janedoe -Password: ●●●●●●●●●●● -Email: jdoe@example.com -WARNING: login credentials saved in /Users/jdoe/.dockercfg. -Login Succeeded - -$ echo $(cat ~/.dockercfg) -{ "https://index.docker.io/v1/": { "auth": "ZmFrZXBhc3N3b3JkMTIK", "email": "jdoe@example.com" } } - -$ cat ~/.dockercfg | base64 -eyAiaHR0cHM6Ly9pbmRleC5kb2NrZXIuaW8vdjEvIjogeyAiYXV0aCI6ICJabUZyWlhCaGMzTjNiM0prTVRJSyIsICJlbWFpbCI6ICJqZG9lQGV4YW1wbGUuY29tIiB9IH0K - -$ cat > /tmp/image-pull-secret.yaml < /dev/termination-log"] -``` - -The message is recorded along with the other state of the last (i.e., most recent) termination: - -```console -$ kubectl create -f ./pod.yaml -pods/pod-w-message -$ sleep 70 -$ kubectl get pods/pod-w-message -o template -t "{{range .status.containerStatuses}}{{.lastState.terminated.message}}{{end}}" -Sleep expired -$ kubectl get pods/pod-w-message -o template -t "{{range .status.containerStatuses}}{{.lastState.terminated.exitCode}}{{end}}" -0 -``` - -## What's next? - -[Learn more about managing deployments.](managing-deployments.md) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/production-pods.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/quick-start.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/quick-start.md deleted file mode 100644 index 3a9c7d94fa62..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/quick-start.md +++ /dev/null @@ -1,110 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/quick-start.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes User Guide: Managing Applications: Quick start - -**Table of Contents** - - -- [Kubernetes User Guide: Managing Applications: Quick start](#kubernetes-user-guide-managing-applications-quick-start) - - [Launching a simple application](#launching-a-simple-application) - - [Exposing your application to the Internet](#exposing-your-application-to-the-internet) - - [Killing the application](#killing-the-application) - - [What's next?](#whats-next) - - - -This guide will help you get oriented to Kubernetes and running your first containers on the cluster. If you are already familiar with the docker-cli, you can also checkout the docker-cli to kubectl migration guide [here](docker-cli-to-kubectl.md). - - -## Launching a simple application - -Once your application is packaged into a container and pushed to an image registry, you’re ready to deploy it to Kubernetes. - -For example, [nginx](http://wiki.nginx.org/Main) is a popular HTTP server, with a [pre-built container on Docker hub](https://registry.hub.docker.com/_/nginx/). The [`kubectl run`](kubectl/kubectl_run.md) command below will create two nginx replicas, listening on port 80. - -```console -$ kubectl run my-nginx --image=nginx --replicas=2 --port=80 -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -my-nginx my-nginx nginx run=my-nginx 2 -``` - -You can see that they are running by: - -```console -$ kubectl get po -NAME READY STATUS RESTARTS AGE -my-nginx-l8n3i 1/1 Running 0 29m -my-nginx-q7jo3 1/1 Running 0 29m -``` - -Kubernetes will ensure that your application keeps running, by automatically restarting containers that fail, spreading containers across nodes, and recreating containers on new nodes when nodes fail. - -## Exposing your application to the Internet - -Through integration with some cloud providers (for example Google Compute Engine and AWS EC2), Kubernetes enables you to request that it provision a public IP address for your application. To do this run: - -```console -$ kubectl expose rc my-nginx --port=80 --type=LoadBalancer -NAME LABELS SELECTOR IP(S) PORT(S) -my-nginx run=my-nginx run=my-nginx 80/TCP -``` - -To find the public IP address assigned to your application, execute: - -```console -$ kubectl get svc my-nginx -o json | grep \"ip\" - "ip": "130.111.122.213" -``` - -In order to access your nginx landing page, you also have to make sure that traffic from external IPs is allowed. Do this by opening a [firewall to allow traffic on port 80](services-firewalls.md). - -## Killing the application - -To kill the application and delete its containers and public IP address, do: - -```console -$ kubectl delete rc my-nginx -replicationcontrollers/my-nginx -$ kubectl delete svc my-nginx -services/my-nginx -``` - -## What's next? - -[Learn about how to configure common container parameters, such as commands and environment variables.](configuring-containers.md) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/quick-start.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/replication-controller.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/replication-controller.md deleted file mode 100644 index e98dd680f61f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/replication-controller.md +++ /dev/null @@ -1,130 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/replication-controller.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Replication Controller - -**Table of Contents** - - -- [Replication Controller](#replication-controller) - - [What is a _replication controller_?](#what-is-a-replication-controller) - - [How does a replication controller work?](#how-does-a-replication-controller-work) - - [Pod template](#pod-template) - - [Labels](#labels) - - [Responsibilities of the replication controller](#responsibilities-of-the-replication-controller) - - [Common usage patterns](#common-usage-patterns) - - [Rescheduling](#rescheduling) - - [Scaling](#scaling) - - [Rolling updates](#rolling-updates) - - [Multiple release tracks](#multiple-release-tracks) - - [API Object](#api-object) - - - -## What is a _replication controller_? - -A _replication controller_ ensures that a specified number of pod "replicas" are running at any one time. If there are too many, it will kill some. If there are too few, it will start more. Unlike in the case where a user directly created pods, a replication controller replaces pods that are deleted or terminated for any reason, such as in the case of node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, we recommend that you use a replication controller even if your application requires only a single pod. Think of it similarly to a process supervisor, only it supervises multiple pods across multiple nodes instead of individual processes on a single node. A replication controller delegates local container restarts to some agent on the node (e.g., Kubelet or Docker). - -As discussed in [life of a pod](pod-states.md), `ReplicationController` is *only* appropriate for pods with `RestartPolicy = Always`. (Note: If `RestartPolicy` is not set, the default value is `Always`.) `ReplicationController` should refuse to instantiate any pod that has a different restart policy. As discussed in [issue #503](https://k8s.io/kubernetes/issues/503#issuecomment-50169443), we expect other types of controllers to be added to Kubernetes to handle other types of workloads, such as build/test and batch workloads, in the future. - -A replication controller will never terminate on its own, but it isn't expected to be as long-lived as services. Services may be composed of pods controlled by multiple replication controllers, and it is expected that many replication controllers may be created and destroyed over the lifetime of a service (for instance, to perform an update of pods that run the service). Both services themselves and their clients should remain oblivious to the replication controllers that maintain the pods of the services. - -## How does a replication controller work? - -### Pod template - -A replication controller creates new pods from a template, which is currently inline in the `ReplicationController` object, but which we plan to extract into its own resource [#170](https://k8s.io/kubernetes/issues/170). - -Rather than specifying the current desired state of all replicas, pod templates are like cookie cutters. Once a cookie has been cut, the cookie has no relationship to the cutter. There is no quantum entanglement. Subsequent changes to the template or even switching to a new template has no direct effect on the pods already created. Similarly, pods created by a replication controller may subsequently be updated directly. This is in deliberate contrast to pods, which do specify the current desired state of all containers belonging to the pod. This approach radically simplifies system semantics and increases the flexibility of the primitive, as demonstrated by the use cases explained below. - -Pods created by a replication controller are intended to be fungible and semantically identical, though their configurations may become heterogeneous over time. This is an obvious fit for replicated stateless servers, but replication controllers can also be used to maintain availability of master-elected, sharded, and worker-pool applications. Such applications should use dynamic work assignment mechanisms, such as the [etcd lock module](https://coreos.com/docs/distributed-configuration/etcd-modules/) or [RabbitMQ work queues](https://www.rabbitmq.com/tutorials/tutorial-two-python.html), as opposed to static/one-time customization of the configuration of each pod, which is considered an anti-pattern. Any pod customization performed, such as vertical auto-sizing of resources (e.g., cpu or memory), should be performed by another online controller process, not unlike the replication controller itself. - -### Labels - -The population of pods that a replication controller is monitoring is defined with a [label selector](labels.md#label-selectors), which creates a loosely coupled relationship between the controller and the pods controlled, in contrast to pods, which are more tightly coupled to their definition. We deliberately chose not to represent the set of pods controlled using a fixed-length array of pod specifications, because our experience is that approach increases complexity of management operations, for both clients and the system. - -The replication controller should verify that the pods created from the specified template have labels that match its label selector. Though it isn't verified yet, you should also ensure that only one replication controller controls any given pod, by ensuring that the label selectors of replication controllers do not target overlapping sets. If you do end up with multiple controllers that have overlapping selectors, you will have to manage the deletion yourself with --cascade=false until there are no controllers with an overlapping superset of selectors. - -Note that replication controllers may themselves have labels and would generally carry the labels their corresponding pods have in common, but these labels do not affect the behavior of the replication controllers. - -Pods may be removed from a replication controller's target set by changing their labels. This technique may be used to remove pods from service for debugging, data recovery, etc. Pods that are removed in this way will be replaced automatically (assuming that the number of replicas is not also changed). - -Similarly, deleting a replication controller does not affect the pods it created. Its `replicas` field must first be set to 0 in order to delete the pods controlled. (Note that the client tool, kubectl, provides a single operation, [stop](kubectl/kubectl_stop.md) to delete both the replication controller and the pods it controls. However, there is no such operation in the API at the moment) - -## Responsibilities of the replication controller - -The replication controller simply ensures that the desired number of pods matches its label selector and are operational. Currently, only terminated pods are excluded from its count. In the future, [readiness](https://k8s.io/kubernetes/issues/620) and other information available from the system may be taken into account, we may add more controls over the replacement policy, and we plan to emit events that could be used by external clients to implement arbitrarily sophisticated replacement and/or scale-down policies. - -The replication controller is forever constrained to this narrow responsibility. It itself will not perform readiness nor liveness probes. Rather than performing auto-scaling, it is intended to be controlled by an external auto-scaler (as discussed in [#492](https://k8s.io/kubernetes/issues/492)), which would change its `replicas` field. We will not add scheduling policies (e.g., [spreading](https://k8s.io/kubernetes/issues/367#issuecomment-48428019)) to the replication controller. Nor should it verify that the pods controlled match the currently specified template, as that would obstruct auto-sizing and other automated processes. Similarly, completion deadlines, ordering dependencies, configuration expansion, and other features belong elsewhere. We even plan to factor out the mechanism for bulk pod creation ([#170](https://k8s.io/kubernetes/issues/170)). - -The replication controller is intended to be a composable building-block primitive. We expect higher-level APIs and/or tools to be built on top of it and other complementary primitives for user convenience in the future. The "macro" operations currently supported by kubectl (run, stop, scale, rolling-update) are proof-of-concept examples of this. For instance, we could imagine something like [Asgard](http://techblog.netflix.com/2012/06/asgard-web-based-cloud-management-and.html) managing replication controllers, auto-scalers, services, scheduling policies, canaries, etc. - -## Common usage patterns - -### Rescheduling - -As mentioned above, whether you have 1 pod you want to keep running, or 1000, a replication controller will ensure that the specified number of pods exists, even in the event of node failure or pod termination (e.g., due to an action by another control agent). - -### Scaling - -The replication controller makes it easy to scale the number of replicas up or down, either manually or by an auto-scaling control agent, by simply updating the `replicas` field. - -### Rolling updates - -The replication controller is designed to facilitate rolling updates to a service by replacing pods one-by-one. - -As explained in [#1353](https://k8s.io/kubernetes/issues/1353), the recommended approach is to create a new replication controller with 1 replica, scale the new (+1) and old (-1) controllers one by one, and then delete the old controller after it reaches 0 replicas. This predictably updates the set of pods regardless of unexpected failures. - -Ideally, the rolling update controller would take application readiness into account, and would ensure that a sufficient number of pods were productively serving at any given time. - -The two replication controllers would need to create pods with at least one differentiating label, such as the image tag of the primary container of the pod, since it is typically image updates that motivate rolling updates. - -Rolling update is implemented in the client tool -[kubectl](kubectl/kubectl_rolling-update.md) - -### Multiple release tracks - -In addition to running multiple releases of an application while a rolling update is in progress, it's common to run multiple releases for an extended period of time, or even continuously, using multiple release tracks. The tracks would be differentiated by labels. - -For instance, a service might target all pods with `tier in (frontend), environment in (prod)`. Now say you have 10 replicated pods that make up this tier. But you want to be able to 'canary' a new version of this component. You could set up a replication controller with `replicas` set to 9 for the bulk of the replicas, with labels `tier=frontend, environment=prod, track=stable`, and another replication controller with `replicas` set to 1 for the canary, with labels `tier=frontend, environment=prod, track=canary`. Now the service is covering both the canary and non-canary pods. But you can mess with the replication controllers separately to test things out, monitor the results, etc. - -## API Object - -Replication controller is a top-level resource in the kubernetes REST API. More details about the -API object can be found at: [ReplicationController API -object](https://htmlpreview.github.io/?https://k8s.io/kubernetes/HEAD/docs/api-reference/definitions.html#_v1_replicationcontroller). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/replication-controller.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/resourcequota/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/resourcequota/README.md deleted file mode 100644 index 9fc6e3d1bb30..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/resourcequota/README.md +++ /dev/null @@ -1,189 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/resourcequota/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - -Resource Quota -======================================== -This example demonstrates how [resource quota](../../admin/admission-controllers.md#resourcequota) and [limits](../../admin/admission-controllers.md#limitranger) can be applied to a Kubernetes namespace. See [ResourceQuota design doc](../../design/admission_control_resource_quota.md) for more information. - -This example assumes you have a functional Kubernetes setup. - -Step 1: Create a namespace ------------------------------------------ -This example will work in a custom namespace to demonstrate the concepts involved. - -Let's create a new namespace called quota-example: - -```console -$ kubectl create -f docs/user-guide/resourcequota/namespace.yaml -$ kubectl get namespaces -NAME LABELS STATUS -default Active -quota-example Active -``` - -Step 2: Apply a quota to the namespace ------------------------------------------ -By default, a pod will run with unbounded CPU and memory limits. This means that any pod in the -system will be able to consume as much CPU and memory on the node that executes the pod. - -Users may want to restrict how much of the cluster resources a given namespace may consume -across all of its pods in order to manage cluster usage. To do this, a user applies a quota to -a namespace. A quota lets the user set hard limits on the total amount of node resources (cpu, memory) -and API resources (pods, services, etc.) that a namespace may consume. - -Let's create a simple quota in our namespace: - -```console -$ kubectl create -f docs/user-guide/resourcequota/quota.yaml --namespace=quota-example -``` - -Once your quota is applied to a namespace, the system will restrict any creation of content -in the namespace until the quota usage has been calculated. This should happen quickly. - -You can describe your current quota usage to see what resources are being consumed in your -namespace. - -```console -$ kubectl describe quota quota --namespace=quota-example -Name: quota -Namespace: quota-example -Resource Used Hard --------- ---- ---- -cpu 0 20 -memory 0 1Gi -persistentvolumeclaims 0 10 -pods 0 10 -replicationcontrollers 0 20 -resourcequotas 1 1 -secrets 1 10 -services 0 5 -``` - -Step 3: Applying default resource limits ------------------------------------------ -Pod authors rarely specify resource limits for their pods. - -Since we applied a quota to our project, let's see what happens when an end-user creates a pod that has unbounded -cpu and memory by creating an nginx container. - -To demonstrate, lets create a replication controller that runs nginx: - -```console -$ kubectl run nginx --image=nginx --replicas=1 --namespace=quota-example -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -nginx nginx nginx run=nginx 1 -``` - -Now let's look at the pods that were created. - -```console -$ kubectl get pods --namespace=quota-example -NAME READY STATUS RESTARTS AGE -``` - -What happened? I have no pods! Let's describe the replication controller to get a view of what is happening. - -```console -kubectl describe rc nginx --namespace=quota-example -Name: nginx -Image(s): nginx -Selector: run=nginx -Labels: run=nginx -Replicas: 0 current / 1 desired -Pods Status: 0 Running / 0 Waiting / 0 Succeeded / 0 Failed -Events: - FirstSeen LastSeen Count From SubobjectPath Reason Message - Mon, 01 Jun 2015 22:49:31 -0400 Mon, 01 Jun 2015 22:52:22 -0400 7 {replication-controller } failedCreate Error creating: Pod "nginx-" is forbidden: Limited to 1Gi memory, but pod has no specified memory limit -``` - -The Kubernetes API server is rejecting the replication controllers requests to create a pod because our pods -do not specify any memory usage. - -So let's set some default limits for the amount of cpu and memory a pod can consume: - -```console -$ kubectl create -f docs/user-guide/resourcequota/limits.yaml --namespace=quota-example -limitranges/limits -$ kubectl describe limits limits --namespace=quota-example -Name: limits -Namespace: quota-example -Type Resource Min Max Default ----- -------- --- --- --- -Container memory - - 512Mi -Container cpu - - 100m -``` - -Now any time a pod is created in this namespace, if it has not specified any resource limits, the default -amount of cpu and memory per container will be applied as part of admission control. - -Now that we have applied default limits for our namespace, our replication controller should be able to -create its pods. - -```console -$ kubectl get pods --namespace=quota-example -NAME READY STATUS RESTARTS AGE -nginx-t9cap 1/1 Running 0 49s -``` - -And if we print out our quota usage in the namespace: - -```console -$ kubectl describe quota quota --namespace=quota-example -Name: quota -Namespace: default -Resource Used Hard --------- ---- ---- -cpu 100m 20 -memory 536870912 1Gi -persistentvolumeclaims 0 10 -pods 1 10 -replicationcontrollers 1 20 -resourcequotas 1 1 -secrets 1 10 -services 0 5 -``` - -You can now see the pod that was created is consuming explicit amounts of resources, and the usage is being -tracked by the Kubernetes system properly. - -Summary ----------------------------- -Actions that consume node resources for cpu and memory can be subject to hard quota limits defined -by the namespace quota. - -Any action that consumes those resources can be tweaked, or can pick up namespace level defaults to -meet your end goal. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/resourcequota/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/secrets.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/secrets.md deleted file mode 100644 index 6a59f5e0f157..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/secrets.md +++ /dev/null @@ -1,535 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/secrets.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Secrets - -Objects of type `secret` are intended to hold sensitive information, such as -passwords, OAuth tokens, and ssh keys. Putting this information in a `secret` -is safer and more flexible than putting it verbatim in a `pod` definition or in -a docker image. See [Secrets design document](../design/secrets.md) for more information. - -**Table of Contents** - - -- [Secrets](#secrets) - - [Overview of Secrets](#overview-of-secrets) - - [Service Accounts Automatically Create and Use Secrets with API Credentials](#service-accounts-automatically-create-and-use-secrets-with-api-credentials) - - [Creating a Secret Manually](#creating-a-secret-manually) - - [Manually specifying a Secret to be Mounted on a Pod](#manually-specifying-a-secret-to-be-mounted-on-a-pod) - - [Manually specifying an imagePullSecret](#manually-specifying-an-imagepullsecret) - - [Automatic use of Manually Created Secrets](#automatic-use-of-manually-created-secrets) - - [Details](#details) - - [Restrictions](#restrictions) - - [Consuming Secret Values](#consuming-secret-values) - - [Secret and Pod Lifetime interaction](#secret-and-pod-lifetime-interaction) - - [Use cases](#use-cases) - - [Use-Case: Pod with ssh keys](#use-case-pod-with-ssh-keys) - - [Use-Case: Pods with prod / test credentials](#use-case-pods-with-prod--test-credentials) - - [Use-case: Secret visible to one container in a pod](#use-case-secret-visible-to-one-container-in-a-pod) - - [Security Properties](#security-properties) - - [Protections](#protections) - - [Risks](#risks) - - - -## Overview of Secrets - - -Creation of secrets can be manual (done by the user) or automatic (done by -automation built into the cluster). - -A secret can be used with a pod in two ways: either as files in a [volume](volumes.md) mounted on one or more of -its containers, or used by kubelet when pulling images for the pod. - -To use a secret, a pod needs to reference the secret. This reference -can likewise be added manually or automatically. - -A single Pod may use various combination of the above options. - -### Service Accounts Automatically Create and Use Secrets with API Credentials - -Kubernetes automatically creates secrets which contain credentials for -accessing the API and it automatically modifies your pods to use this type of -secret. - -The automatic creation and use of API credentials can be disabled or overridden -if desired. However, if all you need to do is securely access the apiserver, -this is the recommended workflow. - -See the [Service Account](service-accounts.md) documentation for more -information on how Service Accounts work. - -### Creating a Secret Manually - -This is an example of a simple secret, in yaml format: - -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: mysecret -type: Opaque -data: - password: dmFsdWUtMg0K - username: dmFsdWUtMQ0K -``` - -The data field is a map. Its keys must match -[DNS_SUBDOMAIN](../design/identifiers.md), except that leading dots are also -allowed. The values are arbitrary data, encoded using base64. The values of -username and password in the example above, before base64 encoding, -are `value-1` and `value-2`, respectively, with carriage return and newline characters at the end. - -Create the secret using [`kubectl create`](kubectl/kubectl_create.md). - -Once the secret is created, you can: - - create pods that automatically use it via a [Service Account](service-accounts.md). - - modify your pod specification to use the secret - -### Manually specifying a Secret to be Mounted on a Pod - -This is an example of a pod that mounts a secret in a volume: - -```json -{ - "apiVersion": "v1", - "kind": "Pod", - "metadata": { - "name": "mypod", - "namespace": "myns" - }, - "spec": { - "containers": [{ - "name": "mypod", - "image": "redis", - "volumeMounts": [{ - "name": "foo", - "mountPath": "/etc/foo", - "readOnly": true - }] - }], - "volumes": [{ - "name": "foo", - "secret": { - "secretName": "mysecret" - } - }] - } -} -``` - -Each secret you want to use needs its own `spec.volumes`. - -If there are multiple containers in the pod, then each container needs its -own `volumeMounts` block, but only one `spec.volumes` is needed per secret. - -You can package many files into one secret, or use many secrets, -whichever is convenient. - -See another example of creating a secret and a pod that consumes that secret in a volume [here](secrets/). - -### Manually specifying an imagePullSecret - -Use of imagePullSecrets is desribed in the [images documentation](images.md#specifying-imagepullsecrets-on-a-pod) - -### Automatic use of Manually Created Secrets - -*This feature is planned but not implemented. See [issue -9902](https://k8s.io/kubernetes/issues/9902).* - -You can reference manually created secrets from a [service account](service-accounts.md). -Then, pods which use that service account will have -`volumeMounts` and/or `imagePullSecrets` added to them. -The secrets will be mounted at **TBD**. - -## Details - -### Restrictions - -Secret volume sources are validated to ensure that the specified object -reference actually points to an object of type `Secret`. Therefore, a secret -needs to be created before any pods that depend on it. - -Secret API objects reside in a namespace. They can only be referenced by pods -in that same namespace. - -Individual secrets are limited to 1MB in size. This is to discourage creation -of very large secrets which would exhaust apiserver and kubelet memory. -However, creation of many smaller secrets could also exhaust memory. More -comprehensive limits on memory usage due to secrets is a planned feature. - -Kubelet only supports use of secrets for Pods it gets from the API server. -This includes any pods created using kubectl, or indirectly via a replication -controller. It does not include pods created via the kubelets -`--manifest-url` flag, its `--config` flag, or its REST API (these are -not common ways to create pods.) - -### Consuming Secret Values - -Inside the container that mounts a secret volume, the secret keys appear as -files and the secret values are base-64 decoded and stored inside these files. -This is the result of commands -executed inside the container from the example above: - -```console -$ ls /etc/foo/ -username -password -$ cat /etc/foo/username -value-1 -$ cat /etc/foo/password -value-2 -``` - -The program in a container is responsible for reading the secret(s) from the -files. Currently, if a program expects a secret to be stored in an environment -variable, then the user needs to modify the image to populate the environment -variable from the file as an step before running the main program. Future -versions of Kubernetes are expected to provide more automation for populating -environment variables from files. - - -### Secret and Pod Lifetime interaction - -When a pod is created via the API, there is no check whether a referenced -secret exists. Once a pod is scheduled, the kubelet will try to fetch the -secret value. If the secret cannot be fetched because it does not exist or -because of a temporary lack of connection to the API server, kubelet will -periodically retry. It will report an event about the pod explaining the -reason it is not started yet. Once the a secret is fetched, the kubelet will -create and mount a volume containing it. None of the pod's containers will -start until all the pod's volumes are mounted. - -Once the kubelet has started a pod's containers, its secret volumes will not -change, even if the secret resource is modified. To change the secret used, -the original pod must be deleted, and a new pod (perhaps with an identical -`PodSpec`) must be created. Therefore, updating a secret follows the same -workflow as deploying a new container image. The `kubectl rolling-update` -command can be used ([man page](kubectl/kubectl_rolling-update.md)). - -The [`resourceVersion`](../devel/api-conventions.md#concurrency-control-and-consistency) -of the secret is not specified when it is referenced. -Therefore, if a secret is updated at about the same time as pods are starting, -then it is not defined which version of the secret will be used for the pod. It -is not possible currently to check what resource version of a secret object was -used when a pod was created. It is planned that pods will report this -information, so that a replication controller restarts ones using an old -`resourceVersion`. In the interim, if this is a concern, it is recommended to not -update the data of existing secrets, but to create new ones with distinct names. - -## Use cases - -### Use-Case: Pod with ssh keys - -To create a pod that uses an ssh key stored as a secret, we first need to create a secret: - -```json -{ - "kind": "Secret", - "apiVersion": "v1", - "metadata": { - "name": "ssh-key-secret" - }, - "data": { - "id-rsa": "dmFsdWUtMg0KDQo=", - "id-rsa.pub": "dmFsdWUtMQ0K" - } -} -``` - -**Note:** The serialized JSON and YAML values of secret data are encoded as -base64 strings. Newlines are not valid within these strings and must be -omitted. - -Now we can create a pod which references the secret with the ssh key and -consumes it in a volume: - -```json -{ - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "secret-test-pod", - "labels": { - "name": "secret-test" - } - }, - "spec": { - "volumes": [ - { - "name": "secret-volume", - "secret": { - "secretName": "ssh-key-secret" - } - } - ], - "containers": [ - { - "name": "ssh-test-container", - "image": "mySshImage", - "volumeMounts": [ - { - "name": "secret-volume", - "readOnly": true, - "mountPath": "/etc/secret-volume" - } - ] - } - ] - } -} -``` - -When the container's command runs, the pieces of the key will be available in: - - /etc/secret-volume/id-rsa.pub - /etc/secret-volume/id-rsa - -The container is then free to use the secret data to establish an ssh connection. - -### Use-Case: Pods with prod / test credentials - -This example illustrates a pod which consumes a secret containing prod -credentials and another pod which consumes a secret with test environment -credentials. - -The secrets: - -```json -{ - "apiVersion": "v1", - "kind": "List", - "items": - [{ - "kind": "Secret", - "apiVersion": "v1", - "metadata": { - "name": "prod-db-secret" - }, - "data": { - "password": "dmFsdWUtMg0KDQo=", - "username": "dmFsdWUtMQ0K" - } - }, - { - "kind": "Secret", - "apiVersion": "v1", - "metadata": { - "name": "test-db-secret" - }, - "data": { - "password": "dmFsdWUtMg0KDQo=", - "username": "dmFsdWUtMQ0K" - } - }] -} -``` - -The pods: - -```json -{ - "apiVersion": "v1", - "kind": "List", - "items": - [{ - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "prod-db-client-pod", - "labels": { - "name": "prod-db-client" - } - }, - "spec": { - "volumes": [ - { - "name": "secret-volume", - "secret": { - "secretName": "prod-db-secret" - } - } - ], - "containers": [ - { - "name": "db-client-container", - "image": "myClientImage", - "volumeMounts": [ - { - "name": "secret-volume", - "readOnly": true, - "mountPath": "/etc/secret-volume" - } - ] - } - ] - } - }, - { - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "test-db-client-pod", - "labels": { - "name": "test-db-client" - } - }, - "spec": { - "volumes": [ - { - "name": "secret-volume", - "secret": { - "secretName": "test-db-secret" - } - } - ], - "containers": [ - { - "name": "db-client-container", - "image": "myClientImage", - "volumeMounts": [ - { - "name": "secret-volume", - "readOnly": true, - "mountPath": "/etc/secret-volume" - } - ] - } - ] - } - }] -} -``` - -Both containers will have the following files present on their filesystems: - -```console - /etc/secret-volume/username - /etc/secret-volume/password -``` - -Note how the specs for the two pods differ only in one field; this facilitates -creating pods with different capabilities from a common pod config template. - -You could further simplify the base pod specification by using two service accounts: -one called, say, `prod-user` with the `prod-db-secret`, and one called, say, -`test-user` with the `test-db-secret`. Then, the pod spec can be shortened to, for example: - -```json -{ -"kind": "Pod", -"apiVersion": "v1", -"metadata": { - "name": "prod-db-client-pod", - "labels": { - "name": "prod-db-client" - } -}, -"spec": { - "serviceAccount": "prod-db-client", - "containers": [ - { - "name": "db-client-container", - "image": "myClientImage", - } - ] -} -``` - -### Use-case: Secret visible to one container in a pod - -
      - -Consider a program that needs to handle HTTP requests, do some complex business -logic, and then sign some messages with an HMAC. Because it has complex -application logic, there might be an unnoticed remote file reading exploit in -the server, which could expose the private key to an attacker. - -This could be divided into two processes in two containers: a frontend container -which handles user interaction and business logic, but which cannot see the -private key; and a signer container that can see the private key, and responds -to simple signing requests from the frontend (e.g. over localhost networking). - -With this partitioned approach, an attacker now has to trick the application -server into doing something rather arbitrary, which may be harder than getting -it to read a file. - - - -## Security Properties - -### Protections - -Because `secret` objects can be created independently of the `pods` that use -them, there is less risk of the secret being exposed during the workflow of -creating, viewing, and editing pods. The system can also take additional -precautions with `secret` objects, such as avoiding writing them to disk where -possible. - -A secret is only sent to a node if a pod on that node requires it. It is not -written to disk. It is stored in a tmpfs. It is deleted once the pod that -depends on it is deleted. - -On most Kubernetes-project-maintained distributions, communication between user -to the apiserver, and from apiserver to the kubelets, is protected by SSL/TLS. -Secrets are protected when transmitted over these channels. - -There may be secrets for several pods on the same node. However, only the -secrets that a pod requests are potentially visible within its containers. -Therefore, one Pod does not have access to the secrets of another pod. - -There may be several containers in a pod. However, each container in a pod has -to request the secret volume in its `volumeMounts` for it to be visible within -the container. This can be used to construct useful [security partitions at the -Pod level](#use-case-two-containers). - -### Risks - - - Applications still need to protect the value of secret after reading it from the volume, - such as not accidentally logging it or transmitting it to an untrusted party. - - A user who can create a pod that uses a secret can also see the value of that secret. Even - if apiserver policy does not allow that user to read the secret object, the user could - run a pod which exposes the secret. - If multiple replicas of etcd are run, then the secrets will be shared between them. - By default, etcd does not secure peer-to-peer communication with SSL/TLS, though this can be configured. - - It is not possible currently to control which users of a Kubernetes cluster can - access a secret. Support for this is planned. - - Currently, anyone with root on any node can read any secret from the apiserver, - by impersonating the kubelet. It is a planned feature to only send secrets to - nodes that actually require them, to restrict the impact of a root exploit on a - single node. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/secrets.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/secrets/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/secrets/README.md deleted file mode 100644 index 5c8a4d1b7ae0..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/secrets/README.md +++ /dev/null @@ -1,96 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/secrets/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Secrets example - -Following this example, you will create a [secret](../secrets.md) and a [pod](../pods.md) that consumes that secret in a [volume](../volumes.md). See [Secrets design document](../../design/secrets.md) for more information. - -## Step Zero: Prerequisites - -This example assumes you have a Kubernetes cluster installed and running, and that you have -installed the `kubectl` command line tool somewhere in your path. Please see the [getting -started](../../../docs/getting-started-guides/) for installation instructions for your platform. - -## Step One: Create the secret - -A secret contains a set of named byte arrays. - -Use the [`examples/secrets/secret.yaml`](secret.yaml) file to create a secret: - -```console -$ kubectl create -f docs/user-guide/secrets/secret.yaml -``` - -You can use `kubectl` to see information about the secret: - -```console -$ kubectl get secrets -NAME TYPE DATA -test-secret Opaque 2 - -$ kubectl describe secret test-secret -Name: test-secret -Labels: -Annotations: - -Type: Opaque - -Data -==== -data-1: 9 bytes -data-2: 11 bytes -``` - -## Step Two: Create a pod that consumes a secret - -Pods consume secrets in volumes. Now that you have created a secret, you can create a pod that -consumes it. - -Use the [`examples/secrets/secret-pod.yaml`](secret-pod.yaml) file to create a Pod that consumes the secret. - -```console -$ kubectl create -f docs/user-guide/secrets/secret-pod.yaml -``` - -This pod runs a binary that displays the content of one of the pieces of secret data in the secret -volume: - -```console -$ kubectl logs secret-test-pod -2015-04-29T21:17:24.712206409Z content of file "/etc/secret-volume/data-1": value-1 -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/secrets/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/security-context.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/security-context.md deleted file mode 100644 index 2381a61721ea..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/security-context.md +++ /dev/null @@ -1,41 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/security-context.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Security Contexts - -A security context defines the operating system security settings (uid, gid, capabilities, SELinux role, etc..) applied to a container. See [security context design](../design/security_context.md) for more details. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/security-context.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/service-accounts.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/service-accounts.md deleted file mode 100644 index 13da2cd53e1b..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/service-accounts.md +++ /dev/null @@ -1,134 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/service-accounts.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Service Accounts - -A service account provides an identity for processes that run in a Pod. - -*This is a user introduction to Service Accounts. See also the -[Cluster Admin Guide to Service Accounts](../admin/service-accounts-admin.md).* - -*Note: This document describes how service accounts behave in a cluster set up -as recommended by the Kubernetes project. Your cluster administrator may have -customized the behavior in your cluster, in which case this documentation may -not apply.* - -When you (a human) access the cluster (e.g. using kubectl), you are -authenticated by the apiserver as a particular User Account (currently this is -usually "admin", unless your cluster administrator has customized your -cluster). Processes in containers inside pods can also contact the apiserver. -When they do, they are authenticated as a particular Service Account (e.g. -"default"). - -## Using the Default Service Account to access the API server. - -When you create a pod, you do not need to specify a service account. It is -automatically assigned the `default` service account of the same namespace. If -you get the raw json or yaml for a pod you have created (e.g. `kubectl get -pods/podname -o yaml`), you can see the `spec.serviceAccount` field has been -[automatically set](working-with-resources.md#resources-are-automatically-modified). - -You can access the API using a proxy or with a client library, as described in -[Accessing the Cluster](accessing-the-cluster.md#accessing-the-api-from-a-pod). - -## Using Multiple Service Accounts - -Every namespace has a default service account resource called "default". -You can list this and any other serviceAccount resources in the namespace with this command: - -```console -$ kubectl get serviceAccounts -NAME SECRETS -default 1 -``` - -You can create additional serviceAccounts like this: - -```console -$ cat > /tmp/serviceaccount.yaml < - -## Adding Secrets to a service account. - -TODO: Test and explain how to use additional non-K8s secrets with an existing service account. - -TODO explain: - - The token goes to: "/var/run/secrets/kubernetes.io/serviceaccount/$WHATFILENAME" - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/service-accounts.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-detail.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-detail.png deleted file mode 100644 index 7ff19b8209b513668ed6aca0441179aade3b30d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68514 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
      )P!<`iKCt(uoasVvw@yWIF1= zszYye_irLrj}{c>kF?j?U_6!c)`0a_Fsht;=R41;%*CT<*bbh+ZRE z(^+sa96kzwOPse8leVXMB?)25vFxv~p^NAAgWacimTWEBTEQF4s_dY3Km)F!B)eE` zp*}u8zQL(++CyYH9h9B@OP0UV8`D!5}pO zv#&?!v{VC47XU??^k4Arg3VuY<$XGfm zRGd9hO542l#z{*!F(IRC2>`6%7w=wy{9gVr!kf8Q@ z{%QA(>FK#0!pre`Z-t?y;I=DE-V5KPf0l~>Udr_mwx|t@Ok7GdsXmiWbnN`N0o}Jb z;dlTZSg@|0mDyd`{k3h}BoRF)=9}Rpy4+FD^>Of<>PtyUPooCqS86NQeE%YrlJNna z4@!Cc{ExgEO^&##mBr&db(Es!+g}vn%92++8%2oQkr9{4UU(aG5G4O3AMRap8d6#Y z4?5GP-iT61p4oLuNX^#0XV=ddNys!EAm-kg%5F^R%qG1Ce{(mD@+$=R1wuzJD90O4 zXLcUO7%NKn+}3@cY2v%4TfHM@_NUloeKl}@^3mjer{Td)PqL!i-jLF&W>HGB zzP$6|aeCXe(XYC36|Jh*Xk89}K6L&y+2^hBrd=U#57i_u`Wh)}P`Lx^55W({W5VLqDKfg8={278MczoWSW zqVqd->6T{*(Y9Q18uh=yQ*i$i0s#c}|Nmos5iDgyd*NxlOk8PdNi;~cbR)noJLPGZ zC^0x&u2&jn5-53k`uGArzk^I$u4oNmK0X*Y_k1CnK#(hsRpYZb4!LP}ukp+IpnVGP O=b@SotmK|m`2PZgR~3Z- diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-detail.svg b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-detail.svg deleted file mode 100644 index cafaf29eb8f1..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-detail.svg +++ /dev/null @@ -1,570 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Backend Pod 1 - labels: app=MyAppport: 9376 - - - - - - Backend Pod 2 - labels: app=MyAppport: 9376 - - - - - - Backend Pod 3 - labels: app=MyAppport: 9376 - - - - - - - - - - - - - - - Client - - - - - iptables - - - - - kube-proxy - - - - - - - apiserver - - - - 3) connect to 10.0.0.1:1234 - 4) redirect to (random)proxy port - 1) watch Services and Endpoints - 2) open proxy port and set portal rules - 5) proxy to a backend - - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-firewalls.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-firewalls.md deleted file mode 100644 index be7be360e77b..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-firewalls.md +++ /dev/null @@ -1,88 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/services-firewalls.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Services and Firewalls - -Many cloud providers (e.g. Google Compute Engine) define firewalls that help prevent inadvertent -exposure to the internet. When exposing a service to the external world, you may need to open up -one or more ports in these firewalls to serve traffic. This document describes this process, as -well as any provider specific details that may be necessary. - - -### Google Compute Engine - -When using a Service with `spec.type: LoadBalancer`, the firewall will be -opened automatically. When using `spec.type: NodePort`, however, the firewall -is *not* opened by default. - -Google Compute Engine firewalls are documented [elsewhere](https://cloud.google.com/compute/docs/networking#firewalls_1). - -You can add a firewall with the `gcloud` command line tool: - -```console -$ gcloud compute firewall-rules create my-rule --allow=tcp: -``` - -**Note** -There is one important security note when using firewalls on Google Compute Engine: - -as of kubernmetes v1.0.0, GCE firewalls are defined per-vm, rather than per-ip -address. This means that when you open a firewall for a service's ports, -anything that serves on that port on that VM's host IP address may potentially -serve traffic. Note that this is not a problem for other Kubernetes services, -as they listen on IP addresses that are different than the host node's external -IP address. - -Consider: - * You create a Service with an external load balancer (IP Address 1.2.3.4) - and port 80 - * You open the firewall for port 80 for all nodes in your cluster, so that - the external Service actually can deliver packets to your Service - * You start an nginx server, running on port 80 on the host virtual machine - (IP Address 2.3.4.5). This nginx is **also** exposed to the internet on - the VM's external IP address. - -Consequently, please be careful when opening firewalls in Google Compute Engine -or Google Container Engine. You may accidentally be exposing other services to -the wilds of the internet. - -This will be fixed in an upcoming release of Kubernetes. - -### Other cloud providers - -Coming soon. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/services-firewalls.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-overview.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services-overview.png deleted file mode 100644 index 564bd857e87e3ffdf72e363e45a8d11a7a6cb1f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43306 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
      EyeP=9-CHuWz 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 - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - Backend Pod 1 - labels: app=MyAppport: 9376 - - - - - - Backend Pod 2 - labels: app=MyAppport: 9376 - - - - - - Backend Pod 3 - labels: app=MyAppport: 9376 - - - - - - - - - - - - - - - Client - - - - - - kube-proxy - - - - - - - apiserver - - - - - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services.md deleted file mode 100644 index cdceb81feff8..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/services.md +++ /dev/null @@ -1,539 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/services.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Services in Kubernetes - -**Table of Contents** - - -- [Services in Kubernetes](#services-in-kubernetes) - - [Overview](#overview) - - [Defining a service](#defining-a-service) - - [Services without selectors](#services-without-selectors) - - [Virtual IPs and service proxies](#virtual-ips-and-service-proxies) - - [Multi-Port Services](#multi-port-services) - - [Choosing your own IP address](#choosing-your-own-ip-address) - - [Why not use round-robin DNS?](#why-not-use-round-robin-dns) - - [Discovering services](#discovering-services) - - [Environment variables](#environment-variables) - - [DNS](#dns) - - [Headless services](#headless-services) - - [External services](#external-services) - - [Type NodePort](#type-nodeport) - - [Type LoadBalancer](#type-loadbalancer) - - [Shortcomings](#shortcomings) - - [Future work](#future-work) - - [The gory details of virtual IPs](#the-gory-details-of-virtual-ips) - - [Avoiding collisions](#avoiding-collisions) - - [IPs and VIPs](#ips-and-vips) - - [API Object](#api-object) - - - -## Overview - -Kubernetes [`Pods`](pods.md) are mortal. They are born and they die, and they -are not resurrected. [`ReplicationControllers`](replication-controller.md) in -particular create and destroy `Pods` dynamically (e.g. when scaling up or down -or when doing [rolling updates](kubectl/kubectl_rolling-update.md)). While each `Pod` gets its own IP address, even -those IP addresses cannot be relied upon to be stable over time. This leads to -a problem: if some set of `Pods` (let's call them backends) provides -functionality to other `Pods` (let's call them frontends) inside the Kubernetes -cluster, how do those frontends find out and keep track of which backends are -in that set? - -Enter `Services`. - -A Kubernetes `Service` is an abstraction which defines a logical set of `Pods` -and a policy by which to access them - sometimes called a micro-service. The -set of `Pods` targeted by a `Service` is (usually) determined by a [`Label -Selector`](labels.md#label-selectors) (see below for why you might want a -`Service` without a selector). - -As an example, consider an image-processing backend which is running with 3 -replicas. Those replicas are fungible - frontends do not care which backend -they use. While the actual `Pods` that compose the backend set may change, the -frontend clients should not need to be aware of that or keep track of the list -of backends themselves. The `Service` abstraction enables this decoupling. - -For Kubernetes-native applications, Kubernetes offers a simple `Endpoints` API -that is updated whenever the set of `Pods` in a `Service` changes. For -non-native applications, Kubernetes offers a virtual-IP-based bridge to Services -which redirects to the backend `Pods`. - -## Defining a service - -A `Service` in Kubernetes is a REST object, similar to a `Pod`. Like all of the -REST objects, a `Service` definition can be POSTed to the apiserver to create a -new instance. For example, suppose you have a set of `Pods` that each expose -port 9376 and carry a label "app=MyApp". - -```json -{ - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "my-service" - }, - "spec": { - "selector": { - "app": "MyApp" - }, - "ports": [ - { - "protocol": "TCP", - "port": 80, - "targetPort": 9376 - } - ] - } -} -``` - -This specification will create a new `Service` object named "my-service" which -targets TCP port 9376 on any `Pod` with the "app=MyApp" label. This `Service` -will also be assigned an IP address (sometimes called the "cluster IP"), which -is used by the service proxies (see below). The `Service`'s selector will be -evaluated continuously and the results will be POSTed to an `Endpoints` object -also named "my-service". - -Note that a `Service` can map an incoming port to any `targetPort`. By default -the `targetPort` will be set to the same value as the `port` field. Perhaps -more interesting is that `targetPort` can be a string, referring to the name of -a port in the backend `Pods`. The actual port number assigned to that name can -be different in each backend `Pod`. This offers a lot of flexibility for -deploying and evolving your `Services`. For example, you can change the port -number that pods expose in the next version of your backend software, without -breaking clients. - -Kubernetes `Services` support `TCP` and `UDP` for protocols. The default -is `TCP`. - -### Services without selectors - -Services generally abstract access to Kubernetes `Pods`, but they can also -abstract other kinds of backends. For example: - - * You want to have an external database cluster in production, but in test - you use your own databases. - * You want to point your service to a service in another - [`Namespace`](namespaces.md) or on another cluster. - * You are migrating your workload to Kubernetes and some of your backends run - outside of Kubernetes. - -In any of these scenarios you can define a service without a selector: - -```json -{ - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "my-service" - }, - "spec": { - "ports": [ - { - "protocol": "TCP", - "port": 80, - "targetPort": 9376 - } - ] - } -} -``` - -Because this has no selector, the corresponding `Endpoints` object will not be -created. You can manually map the service to your own specific endpoints: - -```json -{ - "kind": "Endpoints", - "apiVersion": "v1", - "metadata": { - "name": "my-service" - }, - "subsets": [ - { - "addresses": [ - { "IP": "1.2.3.4" } - ], - "ports": [ - { "port": 80 } - ] - } - ] -} -``` - -Accessing a `Service` without a selector works the same as if it had selector. -The traffic will be routed to endpoints defined by the user (`1.2.3.4:80` in -this example). - -## Virtual IPs and service proxies - -Every node in a Kubernetes cluster runs a `kube-proxy`. This application -watches the Kubernetes master for the addition and removal of `Service` -and `Endpoints` objects. For each `Service` it opens a port (randomly chosen) -on the local node. Any connections made to that port will be proxied to one of -the corresponding backend `Pods`. Which backend to use is decided based on the -`SessionAffinity` of the `Service`. Lastly, it installs iptables rules which -capture traffic to the `Service`'s cluster IP (which is virtual) and `Port` and -redirects that traffic to the previously described port. - -The net result is that any traffic bound for the `Service` is proxied to an -appropriate backend without the clients knowing anything about Kubernetes or -`Services` or `Pods`. - -![Services overview diagram](services-overview.png) - -By default, the choice of backend is random. Client-IP based session affinity -can be selected by setting `service.spec.sessionAffinity` to `"ClientIP"` (the -default is `"None"`). - -As of Kubernetes 1.0, `Services` are a "layer 3" (TCP/UDP over IP) construct. We do not -yet have a concept of "layer 7" (HTTP) services. - -## Multi-Port Services - -Many `Services` need to expose more than one port. For this case, Kubernetes -supports multiple port definitions on a `Service` object. When using multiple -ports you must give all of your ports names, so that endpoints can be -disambiguated. For example: - -```json -{ - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "my-service" - }, - "spec": { - "selector": { - "app": "MyApp" - }, - "ports": [ - { - "name": "http", - "protocol": "TCP", - "port": 80, - "targetPort": 9376 - }, - { - "name": "https", - "protocol": "TCP", - "port": 443, - "targetPort": 9377 - } - ] - } -} -``` - -## Choosing your own IP address - -You can specify your own cluster IP address as part of a `Service` creation -request. To do this, set the `spec.clusterIP` field. For example, if you -already have an existing DNS entry that you wish to replace, or legacy systems -that are configured for a specific IP address and difficult to re-configure. -The IP address that a user chooses must be a valid IP address and within the -service_cluster_ip_range CIDR range that is specified by flag to the API -server. If the IP address value is invalid, the apiserver returns a 422 HTTP -status code to indicate that the value is invalid. - -### Why not use round-robin DNS? - -A question that pops up every now and then is why we do all this stuff with -virtual IPs rather than just use standard round-robin DNS. There are a few -reasons: - - * There is a long history of DNS libraries not respecting DNS TTLs and - caching the results of name lookups. - * Many apps do DNS lookups once and cache the results. - * Even if apps and libraries did proper re-resolution, the load of every - client re-resolving DNS over and over would be difficult to manage. - -We try to discourage users from doing things that hurt themselves. That said, -if enough people ask for this, we may implement it as an alternative. - -## Discovering services - -Kubernetes supports 2 primary modes of finding a `Service` - environment -variables and DNS. - -### Environment variables - -When a `Pod` is run on a `Node`, the kubelet adds a set of environment variables -for each active `Service`. It supports both [Docker links -compatible](https://docs.docker.com/userguide/dockerlinks/) variables (see -[makeLinkVariables](http://releases.k8s.io/HEAD/pkg/kubelet/envvars/envvars.go#L49)) -and simpler `{SVCNAME}_SERVICE_HOST` and `{SVCNAME}_SERVICE_PORT` variables, -where the Service name is upper-cased and dashes are converted to underscores. - -For example, the Service "redis-master" which exposes TCP port 6379 and has been -allocated cluster IP address 10.0.0.11 produces the following environment -variables: - -```bash -REDIS_MASTER_SERVICE_HOST=10.0.0.11 -REDIS_MASTER_SERVICE_PORT=6379 -REDIS_MASTER_PORT=tcp://10.0.0.11:6379 -REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379 -REDIS_MASTER_PORT_6379_TCP_PROTO=tcp -REDIS_MASTER_PORT_6379_TCP_PORT=6379 -REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11 -``` - -*This does imply an ordering requirement* - any `Service` that a `Pod` wants to -access must be created before the `Pod` itself, or else the environment -variables will not be populated. DNS does not have this restriction. - -### DNS - -An optional (though strongly recommended) [cluster -add-on](http://releases.k8s.io/HEAD/cluster/addons/README.md) is a DNS server. The -DNS server watches the Kubernetes API for new `Services` and creates a set of -DNS records for each. If DNS has been enabled throughout the cluster then all -`Pods` should be able to do name resolution of `Services` automatically. - -For example, if you have a `Service` called "my-service" in Kubernetes -`Namespace` "my-ns" a DNS record for "my-service.my-ns" is created. `Pods` -which exist in the "my-ns" `Namespace` should be able to find it by simply doing -a name lookup for "my-service". `Pods` which exist in other `Namespaces` must -qualify the name as "my-service.my-ns". The result of these name lookups is the -cluster IP. - -Kubernetes also supports DNS SRV (service) records for named ports. If the -"my-service.my-ns" `Service` has a port named "http" with protocol `TCP`, you -can do a DNS SRV query for "_http._tcp.my-service.my-ns" to discover the port -number for "http". - -## Headless services - -Sometimes you don't need or want load-balancing and a single service IP. In -this case, you can create "headless" services by specifying `"None"` for the -cluster IP (`spec.clusterIP`). - -For such `Services`, a cluster IP is not allocated. DNS is configured to return -multiple A records (addresses) for the `Service` name, which point directly to -the `Pods` backing the `Service`. Additionally, the kube proxy does not handle -these services and there is no load balancing or proxying done by the platform -for them. The endpoints controller will still create `Endpoints` records in -the API. - -This option allows developers to reduce coupling to the Kubernetes system, if -they desire, but leaves them freedom to do discovery in their own way. -Applications can still use a self-registration pattern and adapters for other -discovery systems could easily be built upon this API. - -## External services - -For some parts of your application (e.g. frontends) you may want to expose a -Service onto an external (outside of your cluster, maybe public internet) IP -address. Kubernetes supports two ways of doing this: `NodePort`s and -`LoadBalancer`s. - -Every `Service` has a `type` field which defines how the `Service` can be -accessed. Valid values for this field are: - - * `ClusterIP`: use a cluster-internal IP only - this is the default and is - discussed above - * `NodePort`: use a cluster IP, but also expose the service on a port on each - node of the cluster (the same port on each node) - * `LoadBalancer`: use a ClusterIP and a NodePort, but also ask the cloud - provider for a load balancer which forwards to the `Service` - -Note that while `NodePort`s can be TCP or UDP, `LoadBalancer`s only support TCP -as of Kubernetes 1.0. - -### Type NodePort - -If you set the `type` field to `"NodePort"`, the Kubernetes master will -allocate a port from a flag-configured range (default: 30000-32767), and each -node will proxy that port (the same port number on every node) into your `Service`. -That port will be reported in your `Service`'s `spec.ports[*].nodePort` field. - -If you want a specific port number, you can specify a value in the `nodePort` -field, and the system will allocate you that port or else the API transaction -will fail. The value you specify must be in the configured range for node -ports. - -This gives developers the freedom to set up their own load balancers, to -configure cloud environments that are not fully supported by Kubernetes, or -even to just expose one or more nodes' IPs directly. - -### Type LoadBalancer - -On cloud providers which support external load balancers, setting the `type` -field to `"LoadBalancer"` will provision a load balancer for your `Service`. -The actual creation of the load balancer happens asynchronously, and -information about the provisioned balancer will be published in the `Service`'s -`status.loadBalancer` field. For example: - -```json -{ - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "my-service" - }, - "spec": { - "selector": { - "app": "MyApp" - }, - "ports": [ - { - "protocol": "TCP", - "port": 80, - "targetPort": 9376, - "nodePort": 30061 - } - ], - "clusterIP": "10.0.171.239", - "type": "LoadBalancer" - }, - "status": { - "loadBalancer": { - "ingress": [ - { - "ip": "146.148.47.155" - } - ] - } - } -} -``` - -Traffic from the external load balancer will be directed at the backend `Pods`, -though exactly how that works depends on the cloud provider. - -## Shortcomings - -We expect that using iptables and userspace proxies for VIPs will work at -small to medium scale, but may not scale to very large clusters with thousands -of Services. See [the original design proposal for -portals](https://k8s.io/kubernetes/issues/1107) for more -details. - -Using the kube-proxy obscures the source-IP of a packet accessing a `Service`. -This makes some kinds of firewalling impossible. - -LoadBalancers only support TCP, not UDP. - -The `Type` field is designed as nested functionality - each level adds to the -previous. This is not strictly required on all cloud providers (e.g. Google Compute Engine does -not need to allocate a `NodePort` to make `LoadBalancer` work, but AWS does) -but the current API requires it. - -## Future work - -In the future we envision that the proxy policy can become more nuanced than -simple round robin balancing, for example master-elected or sharded. We also -envision that some `Services` will have "real" load balancers, in which case the -VIP will simply transport the packets there. - -There's a -[proposal](https://k8s.io/kubernetes/issues/3760) to -eliminate userspace proxying in favor of doing it all in iptables. This should -perform better and fix the source-IP obfuscation, though is less flexible than -arbitrary userspace code. - -We intend to have first-class support for L7 (HTTP) `Services`. - -We intend to have more flexible ingress modes for `Services` which encompass -the current `ClusterIP`, `NodePort`, and `LoadBalancer` modes and more. - -## The gory details of virtual IPs - -The previous information should be sufficient for many people who just want to -use `Services`. However, there is a lot going on behind the scenes that may be -worth understanding. - -### Avoiding collisions - -One of the primary philosophies of Kubernetes is that users should not be -exposed to situations that could cause their actions to fail through no fault -of their own. In this situation, we are looking at network ports - users -should not have to choose a port number if that choice might collide with -another user. That is an isolation failure. - -In order to allow users to choose a port number for their `Services`, we must -ensure that no two `Services` can collide. We do that by allocating each -`Service` its own IP address. - -To ensure each service receives a unique IP, an internal allocator atomically -updates a global allocation map in etcd prior to each service. The map object -must exist in the registry for services to get IPs, otherwise creations will -fail with a message indicating an IP could not be allocated. A background -controller is responsible for creating that map (to migrate from older versions -of Kubernetes that used in memory locking) as well as checking for invalid -assignments due to administrator intervention and cleaning up any IPs -that were allocated but which no service currently uses. - -### IPs and VIPs - -Unlike `Pod` IP addresses, which actually route to a fixed destination, -`Service` IPs are not actually answered by a single host. Instead, we use -`iptables` (packet processing logic in Linux) to define virtual IP addresses -which are transparently redirected as needed. When clients connect to the -VIP, their traffic is automatically transported to an appropriate endpoint. -The environment variables and DNS for `Services` are actually populated in -terms of the `Service`'s VIP and port. - -As an example, consider the image processing application described above. -When the backend `Service` is created, the Kubernetes master assigns a virtual -IP address, for example 10.0.0.1. Assuming the `Service` port is 1234, the -`Service` is observed by all of the `kube-proxy` instances in the cluster. -When a proxy sees a new `Service`, it opens a new random port, establishes an -iptables redirect from the VIP to this new port, and starts accepting -connections on it. - -When a client connects to the VIP the iptables rule kicks in, and redirects -the packets to the `Service proxy`'s own port. The `Service proxy` chooses a -backend, and starts proxying traffic from the client to the backend. - -This means that `Service` owners can choose any port they want without risk of -collision. Clients can simply connect to an IP and port, without being aware -of which `Pods` they are actually accessing. - -![Services detailed diagram](services-detail.png) - -## API Object - -Service is a top-level resource in the kubernetes REST API. More details about the -API object can be found at: [Service API -object](https://htmlpreview.github.io/?https://k8s.io/kubernetes/HEAD/docs/api-reference/definitions.html#_v1_service). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/services.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/sharing-clusters.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/sharing-clusters.md deleted file mode 100644 index 5835e80978e6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/sharing-clusters.md +++ /dev/null @@ -1,155 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/sharing-clusters.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Sharing Cluster Access - -Client access to a running Kubernetes cluster can be shared by copying -the `kubectl` client config bundle ([.kubeconfig](kubeconfig-file.md)). -This config bundle lives in `$HOME/.kube/config`, and is generated -by `cluster/kube-up.sh`. Sample steps for sharing `kubeconfig` below. - -**1. Create a cluster** - -```console -$ cluster/kube-up.sh -``` - -**2. Copy `kubeconfig` to new host** - -```console -$ scp $HOME/.kube/config user@remotehost:/path/to/.kube/config -``` - -**3. On new host, make copied `config` available to `kubectl`** - -* Option A: copy to default location - -```console -$ mv /path/to/.kube/config $HOME/.kube/config -``` - -* Option B: copy to working directory (from which kubectl is run) - -```console -$ mv /path/to/.kube/config $PWD -``` - -* Option C: manually pass `kubeconfig` location to `.kubectl` - -```console -# via environment variable -$ export KUBECONFIG=/path/to/.kube/config - -# via commandline flag -$ kubectl ... --kubeconfig=/path/to/.kube/config -``` - -## Manually Generating `kubeconfig` - -`kubeconfig` is generated by `kube-up` but you can generate your own -using (any desired subset of) the following commands. - -```console -# create kubeconfig entry -$ kubectl config set-cluster $CLUSTER_NICK \ - --server=https://1.1.1.1 \ - --certificate-authority=/path/to/apiserver/ca_file \ - --embed-certs=true \ - # Or if tls not needed, replace --certificate-authority and --embed-certs with - --insecure-skip-tls-verify=true \ - --kubeconfig=/path/to/standalone/.kube/config - -# create user entry -$ kubectl config set-credentials $USER_NICK \ - # bearer token credentials, generated on kube master - --token=$token \ - # use either username|password or token, not both - --username=$username \ - --password=$password \ - --client-certificate=/path/to/crt_file \ - --client-key=/path/to/key_file \ - --embed-certs=true \ - --kubeconfig=/path/to/standalone/.kubeconfig - -# create context entry -$ kubectl config set-context $CONTEXT_NAME --cluster=$CLUSTER_NICKNAME --user=$USER_NICK -``` - -Notes: -* The `--embed-certs` flag is needed to generate a standalone -`kubeconfig`, that will work as-is on another host. -* `--kubeconfig` is both the preferred file to load config from and the file to -save config too. In the above commands the `--kubeconfig` file could be -omitted if you first run - -```console -$ export KUBECONFIG=/path/to/standalone/.kube/config -``` - -* The ca_file, key_file, and cert_file referenced above are generated on the -kube master at cluster turnup. They can be found on the master under -`/srv/kubernetes`. Bearer token/basic auth are also generated on the kube master. - -For more details on `kubeconfig` see [kubeconfig-file.md](kubeconfig-file.md), -and/or run `kubectl config -h`. - -## Merging `kubeconfig` Example - -`kubectl` loads and merges config from the following locations (in order) - -1. `--kubeconfig=path/to/.kube/config` commandline flag -2. `KUBECONFIG=path/to/.kube/config` env variable -3. `$PWD/.kubeconfig` -4. `$HOME/.kube/config` - -If you create clusters A, B on host1, and clusters C, D on host2, you can -make all four clusters available on both hosts by running - -```console -# on host2, copy host1's default kubeconfig, and merge it from env -$ scp host1:/path/to/home1/.kube/config path/to/other/.kube/config - -$ export $KUBECONFIG=path/to/other/.kube/config - -# on host1, copy host2's default kubeconfig and merge it from env -$ scp host2:/path/to/home2/.kube/config path/to/other/.kube/config - -$ export $KUBECONFIG=path/to/other/.kube/config -``` - -Detailed examples and explanation of `kubeconfig` loading/merging rules can be found in [kubeconfig-file.md](kubeconfig-file.md). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/sharing-clusters.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/simple-nginx.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/simple-nginx.md deleted file mode 100644 index 680c12e42472..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/simple-nginx.md +++ /dev/null @@ -1,93 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/simple-nginx.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Running your first containers in Kubernetes - -Ok, you've run one of the [getting started guides](../../docs/getting-started-guides/) and you have -successfully turned up a Kubernetes cluster. Now what? This guide will help you get oriented -to Kubernetes and running your first containers on the cluster. - -### Running a container (simple version) - -From this point onwards, it is assumed that `kubectl` is on your path from one of the getting started guides. - -The [`kubectl run`](kubectl/kubectl_run.md) line below will create two [nginx](https://registry.hub.docker.com/_/nginx/) [pods](pods.md) listening on port 80. It will also create a [replication controller](replication-controller.md) named `my-nginx` to ensure that there are always two pods running. - -```bash -kubectl run my-nginx --image=nginx --replicas=2 --port=80 -``` - -Once the pods are created, you can list them to see what is up and running: - -```bash -kubectl get pods -``` - -You can also see the replication controller that was created: - -```bash -kubectl get rc -``` - -To stop the two replicated containers, stop the replication controller: - -```bash -kubectl stop rc my-nginx -``` - -### Exposing your pods to the internet. - -On some platforms (for example Google Compute Engine) the kubectl command can integrate with your cloud provider to add a [public IP address](services.md#external-services) for the pods, -to do this run: - -```bash -kubectl expose rc my-nginx --port=80 --type=LoadBalancer -``` - -This should print the service that has been created, and map an external IP address to the service. Where to find this external IP address will depend on the environment you run in. For instance, for Google Compute Engine the external IP address is listed as part of the newly created service and can be retrieved by running - -```bash -kubectl get services -``` - -In order to access your nginx landing page, you also have to make sure that traffic from external IPs is allowed. Do this by opening a firewall to allow traffic on port 80. - -### Next: Configuration files - -Most people will eventually want to use declarative configuration files for creating/modifying their applications. A [simplified introduction](simple-yaml.md) -is given in a different document. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/simple-nginx.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/simple-yaml.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/simple-yaml.md index cf5f0c4a1fa5..aa1bf743421b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/simple-yaml.md +++ b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/simple-yaml.md @@ -64,7 +64,7 @@ spec: - containerPort: 80 ``` -[Download example](pod.yaml) +[Download example](pod.yaml?raw=true) You can see your cluster's pods: @@ -116,7 +116,7 @@ spec: - containerPort: 80 ``` -[Download example](replication.yaml) +[Download example](replication.yaml?raw=true) To delete the replication controller (and the pods it created): diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/ui.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/ui.md deleted file mode 100644 index be671dc98613..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/ui.md +++ /dev/null @@ -1,87 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/ui.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes User Interface - -Kubernetes has a web-based user interface that displays the current cluster state graphically. - -## Accessing the UI - -By default, the Kubernetes UI is deployed as a cluster addon. To access it, visit `https:///ui`, which redirects to `https:///api/v1/proxy/namespaces/kube-system/services/kube-ui/#/dashboard/`. - -If you find that you're not able to access the UI, it may be because the kube-ui service has not been started on your cluster. In that case, you can start it manually with: - -```sh -kubectl create -f cluster/addons/kube-ui/kube-ui-rc.yaml --namespace=kube-system -kubectl create -f cluster/addons/kube-ui/kube-ui-svc.yaml --namespace=kube-system -``` - -Normally, this should be taken care of automatically by the [`kube-addons.sh`](http://releases.k8s.io/HEAD/cluster/saltbase/salt/kube-addons/kube-addons.sh) script that runs on the master. - -## Using the UI - -The Kubernetes UI can be used to introspect your current cluster, such as checking how resources are used, or looking at error messages. You cannot, however, use the UI to modify your cluster. - -### Node Resource Usage - -After accessing Kubernetes UI, you'll see a homepage dynamically listing out all nodes in your current cluster, with related information including internal IP addresses, CPU usage, memory usage, and file systems usage. -![Kubernetes UI home page](k8s-ui-overview.png) - -### Dashboard Views - -Click on the "Views" button in the top-right of the page to see other views available, which include: Explore, Pods, Nodes, Replication Controllers, Services, and Events. - -#### Explore View - -The "Explore" view allows your to see the pods, replication controllers, and services in current cluster easily. -![Kubernetes UI Explore View](k8s-ui-explore.png) -The "Group by" dropdown list allows you to group these resources by a number of factors, such as type, name, host, etc. -![Kubernetes UI Explore View - Group by](k8s-ui-explore-groupby.png) -You can also create filters by clicking on the down triangle of any listed resource instances and choose which filters you want to add. -![Kubernetes UI Explore View - Filter](k8s-ui-explore-filter.png) -To see more details of each resource instance, simply click on it. -![Kubernetes UI - Pod](k8s-ui-explore-poddetail.png) - -### Other Views - -Other views (Pods, Nodes, Replication Controllers, Services, and Events) simply list information about each type of resource. You can also click on any instance for more details. -![Kubernetes UI - Nodes](k8s-ui-nodes.png) - -## More Information - -For more information, see the [Kubernetes UI development document](http://releases.k8s.io/HEAD/www/README.md) in the www directory. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/ui.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/README.md deleted file mode 100644 index 8baacbfa3937..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/README.md +++ /dev/null @@ -1,161 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/update-demo/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - - -# Rolling update example - -This example demonstrates the usage of Kubernetes to perform a [rolling update](../kubectl/kubectl_rolling-update.md) on a running group of [pods](../../../docs/user-guide/pods.md). See [here](../managing-deployments.md#updating-your-application-without-a-service-outage) to understand why you need a rolling update. Also check [rolling update design document](../../design/simple-rolling-update.md) for more information. - -### Step Zero: Prerequisites - -This example assumes that you have forked the repository and [turned up a Kubernetes cluster](../../../docs/getting-started-guides/): - -```console -$ cd kubernetes -$ ./cluster/kube-up.sh -``` - -### Step One: Turn up the UX for the demo - -You can use bash job control to run this in the background (note that you must use the default port -- 8001 -- for the following demonstration to work properly). -This can sometimes spew to the output so you could also run it in a different terminal. You have to run `kubectl proxy` in the root of the -Kubernetes repository. Otherwise you will get "404 page not found" errors as the paths will not match. You can find more information about `kubectl proxy` -[here](../../../docs/user-guide/kubectl/kubectl_proxy.md). - -```console -$ kubectl proxy --www=examples/update-demo/local/ & -I0218 15:18:31.623279 67480 proxy.go:36] Starting to serve on localhost:8001 -``` - -Now visit the the [demo website](http://localhost:8001/static). You won't see anything much quite yet. - -### Step Two: Run the replication controller - -Now we will turn up two replicas of an [image](../images.md). They all serve on internal port 80. - -```console -$ kubectl create -f docs/user-guide/update-demo/nautilus-rc.yaml -``` - -After pulling the image from the Docker Hub to your worker nodes (which may take a minute or so) you'll see a couple of squares in the UI detailing the pods that are running along with the image that they are serving up. A cute little nautilus. - -### Step Three: Try scaling the replication controller - -Now we will increase the number of replicas from two to four: - -```console -$ kubectl scale rc update-demo-nautilus --replicas=4 -``` - -If you go back to the [demo website](http://localhost:8001/static/index.html) you should eventually see four boxes, one for each pod. - -### Step Four: Update the docker image - -We will now update the docker image to serve a different image by doing a rolling update to a new Docker image. - -```console -$ kubectl rolling-update update-demo-nautilus --update-period=10s -f docs/user-guide/update-demo/kitten-rc.yaml -``` - -The rolling-update command in kubectl will do 2 things: - -1. Create a new [replication controller](../../../docs/user-guide/replication-controller.md) with a pod template that uses the new image (`gcr.io/google_containers/update-demo:kitten`) -2. Scale the old and new replication controllers until the new controller replaces the old. This will kill the current pods one at a time, spinning up new ones to replace them. - -Watch the [demo website](http://localhost:8001/static/index.html), it will update one pod every 10 seconds until all of the pods have the new image. -Note that the new replication controller definition does not include the replica count, so the current replica count of the old replication controller is preserved. -But if the replica count had been specified, the final replica count of the new replication controller will be equal this number. - -### Step Five: Bring down the pods - -```console -$ kubectl stop rc update-demo-kitten -``` - -This first stops the replication controller by turning the target number of replicas to 0 and then deletes the controller. - -### Step Six: Cleanup - -To turn down a Kubernetes cluster: - -```console -$ ./cluster/kube-down.sh -``` - -Kill the proxy running in the background: -After you are done running this demo make sure to kill it: - -```console -$ jobs -[1]+ Running ./kubectl proxy --www=local/ & -$ kill %1 -[1]+ Terminated: 15 ./kubectl proxy --www=local/ -``` - -### Updating the Docker images - -If you want to build your own docker images, you can set `$DOCKER_HUB_USER` to your Docker user id and run the included shell script. It can take a few minutes to download/upload stuff. - -```console -$ export DOCKER_HUB_USER=my-docker-id -$ ./examples/update-demo/build-images.sh -``` - -To use your custom docker image in the above examples, you will need to change the image name in `examples/update-demo/nautilus-rc.yaml` and `examples/update-demo/kitten-rc.yaml`. - -### Image Copyright - -Note that the images included here are public domain. - -* [kitten](http://commons.wikimedia.org/wiki/File:Kitten-stare.jpg) -* [nautilus](http://commons.wikimedia.org/wiki/File:Nautilus_pompilius.jpg) - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/update-demo/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/build-images.sh b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/build-images.sh deleted file mode 100755 index 63c0fe929841..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/build-images.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -# Copyright 2014 The Kubernetes Authors All rights reserved. -# -# 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. - -# This script will build and push the images necessary for the demo. - -set -o errexit -set -o nounset -set -o pipefail - -DOCKER_HUB_USER=${DOCKER_HUB_USER:-kubernetes} - -set -x - -docker build -t "${DOCKER_HUB_USER}/update-demo:kitten" images/kitten -docker build -t "${DOCKER_HUB_USER}/update-demo:nautilus" images/nautilus - -docker push "${DOCKER_HUB_USER}/update-demo" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/kitten/Dockerfile b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/kitten/Dockerfile deleted file mode 100644 index b053138b3523..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/kitten/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# 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. - -FROM kubernetes/test-webserver -COPY html/kitten.jpg kitten.jpg -COPY html/data.json data.json diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/kitten/html/data.json b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/kitten/html/data.json deleted file mode 100644 index 0be61a42b301..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/kitten/html/data.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "image": "kitten.jpg" -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/kitten/html/kitten.jpg b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/kitten/html/kitten.jpg deleted file mode 100644 index a382bf16aceb05d0c084a32815dcea80aaf02d4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14769 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 D(=o1& diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/nautilus/Dockerfile b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/nautilus/Dockerfile deleted file mode 100644 index 2904a1079163..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/nautilus/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# 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. - -FROM kubernetes/test-webserver -COPY html/nautilus.jpg nautilus.jpg -COPY html/data.json data.json diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/nautilus/html/data.json b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/nautilus/html/data.json deleted file mode 100644 index 2debee09a918..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/nautilus/html/data.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "image": "nautilus.jpg" -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/nautilus/html/nautilus.jpg b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/images/nautilus/html/nautilus.jpg deleted file mode 100644 index 544d2bd471abf859e029d412f24ac64c2c7aecb6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21231 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 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/LICENSE.angular b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/LICENSE.angular deleted file mode 100644 index 020f87acd2ee..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/LICENSE.angular +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2010-2014 Google, Inc. http://angularjs.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/angular.min.js b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/angular.min.js deleted file mode 100644 index 43f31f670898..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/angular.min.js +++ /dev/null @@ -1,210 +0,0 @@ -/* - AngularJS v1.2.16 - (c) 2010-2014 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(O,U,s){'use strict';function t(b){return function(){var a=arguments[0],c,a="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.2.16/"+(b?b+"/":"")+a;for(c=1;c").append(b).html();try{return 3===b[0].nodeType?K(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/, -function(a,b){return"<"+K(b)})}catch(d){return K(c)}}function Xb(b){try{return decodeURIComponent(b)}catch(a){}}function Yb(b){var a={},c,d;q((b||"").split("&"),function(b){b&&(c=b.split("="),d=Xb(c[0]),B(d)&&(b=B(c[1])?Xb(c[1]):!0,a[d]?M(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Zb(b){var a=[];q(b,function(b,d){M(b)?q(b,function(b){a.push(za(d,!0)+(!0===b?"":"="+za(b,!0)))}):a.push(za(d,!0)+(!0===b?"":"="+za(b,!0)))});return a.length?a.join("&"):""}function wb(b){return za(b, -!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function za(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Wc(b,a){function c(a){a&&d.push(a)}var d=[b],e,g,f=["ng:app","ng-app","x-ng-app","data-ng-app"],h=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;q(f,function(a){f[a]=!0;c(U.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(q(b.querySelectorAll("."+a),c),q(b.querySelectorAll("."+ -a+"\\:"),c),q(b.querySelectorAll("["+a+"]"),c))});q(d,function(a){if(!e){var b=h.exec(" "+a.className+" ");b?(e=a,g=(b[2]||"").replace(/\s+/g,",")):q(a.attributes,function(b){!e&&f[b.name]&&(e=a,g=b.value)})}});e&&a(e,g?[g]:[])}function $b(b,a){var c=function(){b=y(b);if(b.injector()){var c=b[0]===U?"document":ha(b);throw Pa("btstrpd",c);}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=ac(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate", -function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(O&&!d.test(O.name))return c();O.name=O.name.replace(d,"");Ea.resumeBootstrap=function(b){q(b,function(b){a.push(b)});c()}}function fb(b,a){a=a||"_";return b.replace(Xc,function(b,d){return(d?a:"")+b.toLowerCase()})}function xb(b,a,c){if(!b)throw Pa("areq",a||"?",c||"required");return b}function Ra(b,a,c){c&&M(b)&&(b=b[b.length-1]);xb(P(b),a,"not a function, got "+(b&&"object"==typeof b? -b.constructor.name||"Object":typeof b));return b}function Aa(b,a){if("hasOwnProperty"===b)throw Pa("badname",a);}function bc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,g=a.length,f=0;f "+e[1]+a.replace(le,"<$1>")+e[2]; -d.removeChild(d.firstChild);for(a=e[0];a--;)d=d.lastChild;a=0;for(e=d.childNodes.length;a=S?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function Ia(b){var a=typeof b,c;"object"==a&&null!==b?"function"==typeof(c=b.$$hashKey)?c=b.$$hashKey():c===s&&(c=b.$$hashKey=bb()):c=b;return a+":"+c}function Va(b){q(b,this.put,this)}function oc(b){var a,c;"function"==typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(oe, -""),c=c.match(pe),q(c[1].split(qe),function(b){b.replace(re,function(b,c,d){a.push(d)})})),b.$inject=a):M(b)?(c=b.length-1,Ra(b[c],"fn"),a=b.slice(0,c)):Ra(b,"fn",!0);return a}function ac(b){function a(a){return function(b,c){if(X(b))q(b,Rb(a));else return a(b,c)}}function c(a,b){Aa(a,"service");if(P(b)||M(b))b=n.instantiate(b);if(!b.$get)throw Wa("pget",a);return m[a+h]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],c,d,g,h;q(a,function(a){if(!k.get(a)){k.put(a,!0);try{if(w(a))for(c= -Sa(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,g=0,h=d.length;g 4096 bytes)!"));else{if(l.cookie!==da)for(da=l.cookie,d=da.split("; "),Q={},g=0;gk&&this.remove(p.key),b},get:function(a){if(k").parent()[0])});var g=L(a,b,a,c,d,e);ma(a,"ng-scope");return function(b,c,d){xb(b,"scope");var e=c?Ja.clone.call(a):a;q(d,function(a,b){e.data("$"+b+"Controller",a)});d=0;for(var f=e.length;darguments.length&& -(b=a,a=s);D&&(c=lb);return p(a,b,c)}var I,x,v,A,R,H,lb={},da;I=c===g?d:Ub(d,new Hb(y(g),d.$attr));x=I.$$element;if(Q){var T=/^\s*([@=&])(\??)\s*(\w*)\s*$/;f=y(g);H=e.$new(!0);ia&&ia===Q.$$originalDirective?f.data("$isolateScope",H):f.data("$isolateScopeNoTemplate",H);ma(f,"ng-isolate-scope");q(Q.scope,function(a,c){var d=a.match(T)||[],g=d[3]||c,f="?"==d[2],d=d[1],l,m,n,p;H.$$isolateBindings[c]=d+g;switch(d){case "@":I.$observe(g,function(a){H[c]=a});I.$$observers[g].$$scope=e;I[g]&&(H[c]=b(I[g])(e)); -break;case "=":if(f&&!I[g])break;m=r(I[g]);p=m.literal?xa:function(a,b){return a===b};n=m.assign||function(){l=H[c]=m(e);throw ja("nonassign",I[g],Q.name);};l=H[c]=m(e);H.$watch(function(){var a=m(e);p(a,H[c])||(p(a,l)?n(e,a=H[c]):H[c]=a);return l=a},null,m.literal);break;case "&":m=r(I[g]);H[c]=function(a){return m(e,a)};break;default:throw ja("iscp",Q.name,c,a);}})}da=p&&u;L&&q(L,function(a){var b={$scope:a===Q||a.$$isolateScope?H:e,$element:x,$attrs:I,$transclude:da},c;R=a.controller;"@"==R&&(R= -I[a.name]);c=z(R,b);lb[a.name]=c;D||x.data("$"+a.name+"Controller",c);a.controllerAs&&(b.$scope[a.controllerAs]=c)});f=0;for(v=l.length;fG.priority)break;if(V=G.scope)A=A||G,G.templateUrl||(K("new/isolated scope",Q,G,Z),X(V)&&(Q=G));t=G.name;!G.templateUrl&&G.controller&&(V=G.controller,L=L||{},K("'"+t+"' controller",L[t],G,Z),L[t]=G);if(V=G.transclude)E=!0,G.$$tlb||(K("transclusion",T,G,Z),T=G),"element"==V?(D=!0,v=G.priority, -V=H(c,ra,W),Z=d.$$element=y(U.createComment(" "+t+": "+d[t]+" ")),c=Z[0],mb(g,y(ya.call(V,0)),c),Xa=x(V,e,v,f&&f.name,{nonTlbTranscludeDirective:T})):(V=y(Eb(c)).contents(),Z.empty(),Xa=x(V,e));if(G.template)if(K("template",ia,G,Z),ia=G,V=P(G.template)?G.template(Z,d):G.template,V=Y(V),G.replace){f=G;V=Cb.test(V)?y(V):[];c=V[0];if(1!=V.length||1!==c.nodeType)throw ja("tplrt",t,"");mb(g,Z,c);S={$attr:{}};V=da(c,[],S);var $=a.splice(N+1,a.length-(N+1));Q&&pc(V);a=a.concat(V).concat($);B(d,S);S=a.length}else Z.html(V); -if(G.templateUrl)K("template",ia,G,Z),ia=G,G.replace&&(f=G),J=C(a.splice(N,a.length-N),Z,d,g,Xa,l,n,{controllerDirectives:L,newIsolateScopeDirective:Q,templateDirective:ia,nonTlbTranscludeDirective:T}),S=a.length;else if(G.compile)try{O=G.compile(Z,d,Xa),P(O)?u(null,O,ra,W):O&&u(O.pre,O.post,ra,W)}catch(aa){m(aa,ha(Z))}G.terminal&&(J.terminal=!0,v=Math.max(v,G.priority))}J.scope=A&&!0===A.scope;J.transclude=E&&Xa;p.hasElementTranscludeDirective=D;return J}function pc(a){for(var b=0,c=a.length;bp.priority)&&-1!=p.restrict.indexOf(g)&&(n&&(p=Tb(p,{$$start:n,$$end:r})),b.push(p),k=p)}catch(F){m(F)}}return k}function B(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;q(a,function(d,e){"$"!=e.charAt(0)&&(b[e]&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});q(b,function(b,g){"class"==g?(ma(e,b),a["class"]=(a["class"]? -a["class"]+" ":"")+b):"style"==g?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==g.charAt(0)||a.hasOwnProperty(g)||(a[g]=b,d[g]=c[g])})}function C(a,b,c,d,e,g,f,l){var k=[],m,r,z=b[0],u=a.shift(),F=D({},u,{templateUrl:null,transclude:null,replace:null,$$originalDirective:u}),x=P(u.templateUrl)?u.templateUrl(b,c):u.templateUrl;b.empty();n.get(v.getTrustedResourceUrl(x),{cache:p}).success(function(n){var p,J;n=Y(n);if(u.replace){n=Cb.test(n)?y(n):[];p=n[0];if(1!=n.length|| -1!==p.nodeType)throw ja("tplrt",u.name,x);n={$attr:{}};mb(d,b,p);var v=da(p,[],n);X(u.scope)&&pc(v);a=v.concat(a);B(c,n)}else p=z,b.html(n);a.unshift(F);m=ia(a,p,c,e,b,u,g,f,l);q(d,function(a,c){a==p&&(d[c]=b[0])});for(r=L(b[0].childNodes,e);k.length;){n=k.shift();J=k.shift();var A=k.shift(),R=k.shift(),v=b[0];if(J!==z){var H=J.className;l.hasElementTranscludeDirective&&u.replace||(v=Eb(p));mb(A,y(J),v);ma(y(v),H)}J=m.transclude?Q(n,m.transclude):R;m(r,n,v,d,J)}k=null}).error(function(a,b,c,d){throw ja("tpload", -d.url);});return function(a,b,c,d,e){k?(k.push(b),k.push(c),k.push(d),k.push(e)):m(r,b,c,d,e)}}function E(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.namea.status? -b:n.reject(b)}var d={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},g=function(a){function b(a){var c;q(a,function(b,d){P(b)&&(c=b(),null!=c?a[d]=c:delete a[d])})}var c=e.headers,d=D({},a.headers),g,f,c=D({},c.common,c[K(a.method)]);b(c);b(d);a:for(g in c){a=K(g);for(f in d)if(K(f)===a)continue a;d[g]=c[g]}return d}(a);D(d,a);d.headers=g;d.method=Fa(d.method);(a=Ib(d.url)?b.cookies()[d.xsrfCookieName||e.xsrfCookieName]:s)&&(g[d.xsrfHeaderName||e.xsrfHeaderName]= -a);var f=[function(a){g=a.headers;var b=uc(a.data,tc(g),a.transformRequest);E(a.data)&&q(g,function(a,b){"content-type"===K(b)&&delete g[b]});E(a.withCredentials)&&!E(e.withCredentials)&&(a.withCredentials=e.withCredentials);return z(a,b,g).then(c,c)},s],h=n.when(d);for(q(v,function(a){(a.request||a.requestError)&&f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var k=f.shift(),h=h.then(a,k)}h.success=function(a){h.then(function(b){a(b.data, -b.status,b.headers,d)});return h};h.error=function(a){h.then(null,function(b){a(b.data,b.status,b.headers,d)});return h};return h}function z(b,c,g){function f(a,b,c,e){v&&(200<=a&&300>a?v.put(s,[a,b,sc(c),e]):v.remove(s));l(b,a,c,e);d.$$phase||d.$apply()}function l(a,c,d,e){c=Math.max(c,0);(200<=c&&300>c?p.resolve:p.reject)({data:a,status:c,headers:tc(d),config:b,statusText:e})}function k(){var a=db(r.pendingRequests,b);-1!==a&&r.pendingRequests.splice(a,1)}var p=n.defer(),z=p.promise,v,q,s=u(b.url, -b.params);r.pendingRequests.push(b);z.then(k,k);(b.cache||e.cache)&&(!1!==b.cache&&"GET"==b.method)&&(v=X(b.cache)?b.cache:X(e.cache)?e.cache:F);if(v)if(q=v.get(s),B(q)){if(q.then)return q.then(k,k),q;M(q)?l(q[1],q[0],ba(q[2]),q[3]):l(q,200,{},"OK")}else v.put(s,z);E(q)&&a(b.method,s,c,f,g,b.timeout,b.withCredentials,b.responseType);return z}function u(a,b){if(!b)return a;var c=[];Sc(b,function(a,b){null===a||E(a)||(M(a)||(a=[a]),q(a,function(a){X(a)&&(a=qa(a));c.push(za(b)+"="+za(a))}))});0=S&&(!b.match(/^(get|post|head|put|delete|options)$/i)||!O.XMLHttpRequest))return new O.ActiveXObject("Microsoft.XMLHTTP");if(O.XMLHttpRequest)return new O.XMLHttpRequest;throw t("$httpBackend")("noxhr");}function Ud(){this.$get=["$browser","$window","$document",function(b,a,c){return ve(b,ue,b.defer,a.angular.callbacks,c[0])}]}function ve(b,a,c,d,e){function g(a,b){var c=e.createElement("script"),d=function(){c.onreadystatechange= -c.onload=c.onerror=null;e.body.removeChild(c);b&&b()};c.type="text/javascript";c.src=a;S&&8>=S?c.onreadystatechange=function(){/loaded|complete/.test(c.readyState)&&d()}:c.onload=c.onerror=function(){d()};e.body.appendChild(c);return d}var f=-1;return function(e,l,k,m,n,p,r,z){function u(){v=f;A&&A();x&&x.abort()}function F(a,d,e,g,f){L&&c.cancel(L);A=x=null;0===d&&(d=e?200:"file"==sa(l).protocol?404:0);a(1223===d?204:d,e,g,f||"");b.$$completeOutstandingRequest(C)}var v;b.$$incOutstandingRequestCount(); -l=l||b.url();if("jsonp"==K(e)){var J="_"+(d.counter++).toString(36);d[J]=function(a){d[J].data=a};var A=g(l.replace("JSON_CALLBACK","angular.callbacks."+J),function(){d[J].data?F(m,200,d[J].data):F(m,v||-2);d[J]=Ea.noop})}else{var x=a(e);x.open(e,l,!0);q(n,function(a,b){B(a)&&x.setRequestHeader(b,a)});x.onreadystatechange=function(){if(x&&4==x.readyState){var a=null,b=null;v!==f&&(a=x.getAllResponseHeaders(),b="response"in x?x.response:x.responseText);F(m,v||x.status,b,a,x.statusText||"")}};r&&(x.withCredentials= -!0);if(z)try{x.responseType=z}catch(s){if("json"!==z)throw s;}x.send(k||null)}if(0=h&&(n.resolve(r),m(p.$$intervalId),delete e[p.$$intervalId]);z||b.$apply()},f);e[p.$$intervalId]=n;return p}var e={};d.cancel=function(a){return a&&a.$$intervalId in e?(e[a.$$intervalId].reject("canceled"),clearInterval(a.$$intervalId),delete e[a.$$intervalId], -!0):!1};return d}]}function ad(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "), -DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function wc(b){b=b.split("/");for(var a=b.length;a--;)b[a]=wb(b[a]);return b.join("/")}function xc(b,a,c){b=sa(b,c);a.$$protocol= -b.protocol;a.$$host=b.hostname;a.$$port=Y(b.port)||we[b.protocol]||null}function yc(b,a,c){var d="/"!==b.charAt(0);d&&(b="/"+b);b=sa(b,c);a.$$path=decodeURIComponent(d&&"/"===b.pathname.charAt(0)?b.pathname.substring(1):b.pathname);a.$$search=Yb(b.search);a.$$hash=decodeURIComponent(b.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function oa(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function Ya(b){var a=b.indexOf("#");return-1==a?b:b.substr(0,a)}function Jb(b){return b.substr(0, -Ya(b).lastIndexOf("/")+1)}function zc(b,a){this.$$html5=!0;a=a||"";var c=Jb(b);xc(b,this,b);this.$$parse=function(a){var e=oa(c,a);if(!w(e))throw Kb("ipthprfx",a,c);yc(e,this,b);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Zb(this.$$search),b=this.$$hash?"#"+wb(this.$$hash):"";this.$$url=wc(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$rewrite=function(d){var e;if((e=oa(b,d))!==s)return d=e,(e=oa(a,e))!==s?c+(oa("/",e)||e):b+d;if((e=oa(c, -d))!==s)return c+e;if(c==d+"/")return c}}function Lb(b,a){var c=Jb(b);xc(b,this,b);this.$$parse=function(d){var e=oa(b,d)||oa(c,d),e="#"==e.charAt(0)?oa(a,e):this.$$html5?e:"";if(!w(e))throw Kb("ihshprfx",d,a);yc(e,this,b);d=this.$$path;var g=/^\/?.*?:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));g.exec(e)||(d=(e=g.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Zb(this.$$search),e=this.$$hash?"#"+wb(this.$$hash):"";this.$$url=wc(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl= -b+(this.$$url?a+this.$$url:"")};this.$$rewrite=function(a){if(Ya(b)==Ya(a))return a}}function Ac(b,a){this.$$html5=!0;Lb.apply(this,arguments);var c=Jb(b);this.$$rewrite=function(d){var e;if(b==Ya(d))return d;if(e=oa(c,d))return b+a+e;if(c===d+"/")return c}}function nb(b){return function(){return this[b]}}function Bc(b,a){return function(c){if(E(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Vd(){var b="",a=!1;this.hashPrefix=function(a){return B(a)?(b=a,this):b};this.html5Mode= -function(b){return B(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,g){function f(a){c.$broadcast("$locationChangeSuccess",h.absUrl(),a)}var h,l=d.baseHref(),k=d.url();a?(l=k.substring(0,k.indexOf("/",k.indexOf("//")+2))+(l||"/"),e=e.history?zc:Ac):(l=Ya(k),e=Lb);h=new e(l,"#"+b);h.$$parse(h.$$rewrite(k));g.on("click",function(a){if(!a.ctrlKey&&!a.metaKey&&2!=a.which){for(var b=y(a.target);"a"!==K(b[0].nodeName);)if(b[0]===g[0]||!(b=b.parent())[0])return; -var e=b.prop("href");X(e)&&"[object SVGAnimatedString]"===e.toString()&&(e=sa(e.animVal).href);var f=h.$$rewrite(e);e&&(!b.attr("target")&&f&&!a.isDefaultPrevented())&&(a.preventDefault(),f!=d.url()&&(h.$$parse(f),c.$apply(),O.angular["ff-684208-preventDefault"]=!0))}});h.absUrl()!=k&&d.url(h.absUrl(),!0);d.onUrlChange(function(a){h.absUrl()!=a&&(c.$evalAsync(function(){var b=h.absUrl();h.$$parse(a);c.$broadcast("$locationChangeStart",a,b).defaultPrevented?(h.$$parse(b),d.url(b)):f(b)}),c.$$phase|| -c.$digest())});var m=0;c.$watch(function(){var a=d.url(),b=h.$$replace;m&&a==h.absUrl()||(m++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),f(a))}));h.$$replace=!1;return m});return h}]}function Wd(){var b=!0,a=this;this.debugEnabled=function(a){return B(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack: -a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=c.console||{},e=b[a]||b.log||C;a=!1;try{a=!!e.apply}catch(l){}return a?function(){var a=[];q(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function fa(b,a){if("constructor"===b)throw Ba("isecfld",a);return b}function Za(b, -a){if(b){if(b.constructor===b)throw Ba("isecfn",a);if(b.document&&b.location&&b.alert&&b.setInterval)throw Ba("isecwindow",a);if(b.children&&(b.nodeName||b.prop&&b.attr&&b.find))throw Ba("isecdom",a);}return b}function ob(b,a,c,d,e){e=e||{};a=a.split(".");for(var g,f=0;1e?Cc(d[0],d[1],d[2],d[3],d[4],c,a):function(b,g){var f=0,h;do h=Cc(d[f++],d[f++],d[f++],d[f++],d[f++],c,a)(b,g),g=s,b=h;while(fa)for(b in l++,e)e.hasOwnProperty(b)&&!d.hasOwnProperty(b)&&(q--,delete e[b])}else e!==d&&(e=d,l++);return l},function(){p?(p=!1,b(d,d,c)):b(d,f,c);if(h)if(X(d))if(ab(d)){f=Array(d.length);for(var a=0;as&&(y=4-s,Q[y]||(Q[y]=[]),H=P(d.exp)?"fn: "+(d.exp.name||d.exp.toString()):d.exp,H+="; newVal: "+qa(g)+"; oldVal: "+qa(f),Q[y].push(H));else if(d===c){x=!1;break a}}catch(w){p.$$phase= -null,e(w)}if(!(h=L.$$childHead||L!==this&&L.$$nextSibling))for(;L!==this&&!(h=L.$$nextSibling);)L=L.$parent}while(L=h);if((x||k.length)&&!s--)throw p.$$phase=null,a("infdig",b,qa(Q));}while(x||k.length);for(p.$$phase=null;m.length;)try{m.shift()()}catch(T){e(T)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;this!==p&&(q(this.$$listenerCount,eb(null,m,this)),a.$$childHead==this&&(a.$$childHead=this.$$nextSibling),a.$$childTail==this&& -(a.$$childTail=this.$$prevSibling),this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling),this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling),this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=null,this.$$listeners={},this.$$watchers=this.$$asyncQueue=this.$$postDigestQueue=[],this.$destroy=this.$digest=this.$apply=C,this.$on=this.$watch=function(){return C})}},$eval:function(a,b){return g(a)(this,b)},$evalAsync:function(a){p.$$phase|| -p.$$asyncQueue.length||f.defer(function(){p.$$asyncQueue.length&&p.$digest()});this.$$asyncQueue.push({scope:this,expression:a})},$$postDigest:function(a){this.$$postDigestQueue.push(a)},$apply:function(a){try{return l("$apply"),this.$eval(a)}catch(b){e(b)}finally{p.$$phase=null;try{p.$digest()}catch(c){throw e(c),c;}}},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent); -var e=this;return function(){c[db(c,b)]=null;m(e,1,a)}},$emit:function(a,b){var c=[],d,g=this,f=!1,h={name:a,targetScope:g,stopPropagation:function(){f=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},l=[h].concat(ya.call(arguments,1)),k,m;do{d=g.$$listeners[a]||c;h.currentScope=g;k=0;for(m=d.length;kc.msieDocumentMode)throw ua("iequirks");var e=ba(ga);e.isEnabled=function(){return b};e.trustAs=d.trustAs;e.getTrusted=d.getTrusted;e.valueOf=d.valueOf;b||(e.trustAs=e.getTrusted=function(a,b){return b},e.valueOf=Da);e.parseAs=function(b,c){var d=a(c);return d.literal&&d.constant?d:function(a,c){return e.getTrusted(b, -d(a,c))}};var g=e.parseAs,f=e.getTrusted,h=e.trustAs;q(ga,function(a,b){var c=K(b);e[Ta("parse_as_"+c)]=function(b){return g(a,b)};e[Ta("get_trusted_"+c)]=function(b){return f(a,b)};e[Ta("trust_as_"+c)]=function(b){return h(a,b)}});return e}]}function be(){this.$get=["$window","$document",function(b,a){var c={},d=Y((/android (\d+)/.exec(K((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||{}).userAgent),g=a[0]||{},f=g.documentMode,h,l=/^(Moz|webkit|O|ms)(?=[A-Z])/,k=g.body&&g.body.style, -m=!1,n=!1;if(k){for(var p in k)if(m=l.exec(p)){h=m[0];h=h.substr(0,1).toUpperCase()+h.substr(1);break}h||(h="WebkitOpacity"in k&&"webkit");m=!!("transition"in k||h+"Transition"in k);n=!!("animation"in k||h+"Animation"in k);!d||m&&n||(m=w(g.body.style.webkitTransition),n=w(g.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hashchange:"onhashchange"in b&&(!f||7b;b=Math.abs(b);var f=b+"",h="",l=[],k=!1;if(-1!==f.indexOf("e")){var m=f.match(/([\d\.]+)e(-?)(\d+)/);m&&"-"==m[2]&&m[3]>e+1?f="0":(h=f,k=!0)}if(k)0b)&&(h=b.toFixed(e)); -else{f=(f.split(Nc)[1]||"").length;E(e)&&(e=Math.min(Math.max(a.minFrac,f),a.maxFrac));f=Math.pow(10,e);b=Math.round(b*f)/f;b=(""+b).split(Nc);f=b[0];b=b[1]||"";var m=0,n=a.lgSize,p=a.gSize;if(f.length>=n+p)for(m=f.length-n,k=0;kb&&(d="-",b=-b);for(b=""+b;b.length-c)e+=c;0===e&&-12==c&&(e=12);return Ob(e,a,d)}}function pb(b,a){return function(c,d){var e=c["get"+b](),g=Fa(a?"SHORT"+b:b);return d[g][e]}}function Jc(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var g=0,f=0,h=b[8]?a.setUTCFullYear:a.setFullYear,l=b[8]?a.setUTCHours:a.setHours;b[9]&&(g=Y(b[9]+b[10]),f=Y(b[9]+b[11])); -h.call(a,Y(b[1]),Y(b[2])-1,Y(b[3]));g=Y(b[4]||0)-g;f=Y(b[5]||0)-f;h=Y(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));l.call(a,g,f,h,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var g="",f=[],h,l;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;w(c)&&(c=Ge.test(c)?Y(c):a(c));vb(c)&&(c=new Date(c));if(!Na(c))return c;for(;e;)(l=He.exec(e))?(f=f.concat(ya.call(l,1)),e=f.pop()):(f.push(e),e=null);q(f,function(a){h= -Ie[a];g+=h?h(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function Ce(){return function(b){return qa(b,!0)}}function De(){return function(b,a){if(!M(b)&&!w(b))return b;a=Y(a);if(w(b))return a?0<=a?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?a=b.length:a<-b.length&&(a=-b.length);0a||37<=a&&40>=a)||m()});if(e.hasEvent("paste"))a.on("paste cut",m)}a.on("change",l);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)? -"":d.$viewValue)};var n=c.ngPattern;n&&((e=n.match(/^\/(.*)\/([gim]*)$/))?(n=RegExp(e[1],e[2]),e=function(a){return pa(d,"pattern",d.$isEmpty(a)||n.test(a),a)}):e=function(c){var e=b.$eval(n);if(!e||!e.test)throw t("ngPattern")("noregexp",n,e,ha(a));return pa(d,"pattern",d.$isEmpty(c)||e.test(c),c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var p=Y(c.ngMinlength);e=function(a){return pa(d,"minlength",d.$isEmpty(a)||a.length>=p,a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var r= -Y(c.ngMaxlength);e=function(a){return pa(d,"maxlength",d.$isEmpty(a)||a.length<=r,a)};d.$parsers.push(e);d.$formatters.push(e)}}function Pb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;dS?function(b){b=b.nodeName?b:b[0];return b.scopeName&&"HTML"!=b.scopeName?Fa(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var Xc=/[A-Z]/g,$c={full:"1.2.16",major:1,minor:2,dot:16,codeName:"badger-enumeration"},Ua=N.cache={},gb=N.expando="ng-"+(new Date).getTime(), -me=1,Pc=O.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},Fb=O.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)};N._data=function(b){return this.cache[b[this.expando]]||{}};var he=/([\:\-\_]+(.))/g,ie=/^moz([A-Z])/,Bb=t("jqLite"),je=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Cb=/<|&#?\w+;/,ke=/<([\w:]+)/,le=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ea= -{option:[1,'"],thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};ea.optgroup=ea.option;ea.tbody=ea.tfoot=ea.colgroup=ea.caption=ea.thead;ea.th=ea.td;var Ja=N.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===U.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),N(O).on("load",a))},toString:function(){var b= -[];q(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?y(this[b]):y(this[this.length+b])},length:0,push:Ke,sort:[].sort,splice:[].splice},kb={};q("multiple selected checked disabled readOnly required open".split(" "),function(b){kb[K(b)]=b});var nc={};q("input select option textarea button form details".split(" "),function(b){nc[Fa(b)]=!0});q({data:jc,inheritedData:jb,scope:function(b){return y(b).data("$scope")||jb(b.parentNode||b,["$isolateScope","$scope"])}, -isolateScope:function(b){return y(b).data("$isolateScope")||y(b).data("$isolateScopeNoTemplate")},controller:kc,injector:function(b){return jb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Gb,css:function(b,a,c){a=Ta(a);if(B(c))b.style[a]=c;else{var d;8>=S&&(d=b.currentStyle&&b.currentStyle[a],""===d&&(d="auto"));d=d||b.style[a];8>=S&&(d=""===d?s:d);return d}},attr:function(b,a,c){var d=K(a);if(kb[d])if(B(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d)); -else return b[a]||(b.attributes.getNamedItem(a)||C).specified?d:s;else if(B(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?s:b},prop:function(b,a,c){if(B(c))b[a]=c;else return b[a]},text:function(){function b(b,d){var e=a[b.nodeType];if(E(d))return e?b[e]:"";b[e]=d}var a=[];9>S?(a[1]="innerText",a[3]="nodeValue"):a[1]=a[3]="textContent";b.$dv="";return b}(),val:function(b,a){if(E(a)){if("SELECT"===Ka(b)&&b.multiple){var c=[];q(b.options,function(a){a.selected&& -c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(E(a))return b.innerHTML;for(var c=0,d=b.childNodes;c":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Ne={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'}, -Nb=function(a){this.options=a};Nb.prototype={constructor:Nb,lex:function(a){this.text=a;this.index=0;this.ch=s;this.lastCh=":";this.tokens=[];var c;for(a=[];this.index=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"=== -a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=B(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c,d)+"]":" "+d;throw Ba("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn($a.ZERO,a.fn, -this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):this.primary()},fieldAccess:function(a){var c=this,d=this.expect().text,e=Dc(d,this.options,this.text);return D(function(c,d,h){return e(h||a(c,d))},{assign:function(e,f,h){return ob(a(e,h),d,f,c.text,c.options)}})},objectIndex:function(a){var c=this,d=this.expression();this.consume("]");return D(function(e,g){var f=a(e,g),h=d(e,g),l;if(!f)return s;(f=Za(f[h],c.text))&&(f.then&&c.options.unwrapPromises)&&(l=f,"$$v"in f||(l.$$v=s,l.then(function(a){l.$$v= -a})),f=f.$$v);return f},{assign:function(e,g,f){var h=d(e,f);return Za(a(e,f),c.text)[h]=g}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this;return function(g,f){for(var h=[],l=c?c(g,f):g,k=0;ka.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Ob(Math[0=S&&(c.href||c.name||c.$set("href",""),a.append(U.createComment("IE fix")));if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){var g="[object SVGAnimatedString]"===wa.call(c.prop("href"))?"xlink:href":"href";c.on("click",function(a){c.attr(g)||a.preventDefault()})}}}),zb={};q(kb,function(a,c){if("multiple"!=a){var d=na("ng-"+c);zb[d]=function(){return{priority:100,link:function(a,g,f){a.$watch(f[d],function(a){f.$set(c,!!a)})}}}}});q(["src", -"srcset","href"],function(a){var c=na("ng-"+a);zb[c]=function(){return{priority:99,link:function(d,e,g){var f=a,h=a;"href"===a&&"[object SVGAnimatedString]"===wa.call(e.prop("href"))&&(h="xlinkHref",g.$attr[h]="xlink:href",f=null);g.$observe(c,function(a){a&&(g.$set(h,a),S&&f&&e.prop(f,g[h]))})}}}});var sb={$addControl:C,$removeControl:C,$setValidity:C,$setDirty:C,$setPristine:C};Oc.$inject=["$element","$attrs","$scope","$animate"];var Qc=function(a){return["$timeout",function(c){return{name:"form", -restrict:a?"EAC":"E",controller:Oc,compile:function(){return{pre:function(a,e,g,f){if(!g.action){var h=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};Pc(e[0],"submit",h);e.on("$destroy",function(){c(function(){Fb(e[0],"submit",h)},0,!1)})}var l=e.parent().controller("form"),k=g.name||g.ngForm;k&&ob(a,k,f,k);if(l)e.on("$destroy",function(){l.$removeControl(f);k&&ob(a,k,s,k);D(f,sb)})}}}}}]},dd=Qc(),qd=Qc(!0),Oe=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/, -Pe=/^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i,Qe=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,Rc={text:ub,number:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);e.$parsers.push(function(a){var c=e.$isEmpty(a);if(c||Qe.test(a))return e.$setValidity("number",!0),""===a?null:c?a:parseFloat(a);e.$setValidity("number",!1);return s});Je(e,"number",c);e.$formatters.push(function(a){return e.$isEmpty(a)?"":""+a});d.min&&(a=function(a){var c=parseFloat(d.min);return pa(e,"min",e.$isEmpty(a)||a>=c,a)},e.$parsers.push(a), -e.$formatters.push(a));d.max&&(a=function(a){var c=parseFloat(d.max);return pa(e,"max",e.$isEmpty(a)||a<=c,a)},e.$parsers.push(a),e.$formatters.push(a));e.$formatters.push(function(a){return pa(e,"number",e.$isEmpty(a)||vb(a),a)})},url:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);a=function(a){return pa(e,"url",e.$isEmpty(a)||Oe.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);a=function(a){return pa(e,"email",e.$isEmpty(a)||Pe.test(a),a)};e.$formatters.push(a); -e.$parsers.push(a)},radio:function(a,c,d,e){E(d.name)&&c.attr("name",bb());c.on("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var g=d.ngTrueValue,f=d.ngFalseValue;w(g)||(g=!0);w(f)||(f=!1);c.on("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==g}; -e.$formatters.push(function(a){return a===g});e.$parsers.push(function(a){return a?g:f})},hidden:C,button:C,submit:C,reset:C,file:C},dc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",link:function(d,e,g,f){f&&(Rc[K(g.type)]||Rc.text)(d,e,g,f,c,a)}}}],rb="ng-valid",qb="ng-invalid",La="ng-pristine",tb="ng-dirty",Re=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate",function(a,c,d,e,g,f){function h(a,c){c=c?"-"+fb(c,"-"):"";f.removeClass(e,(a?qb:rb)+c); -f.addClass(e,(a?rb:qb)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name=d.name;var l=g(d.ngModel),k=l.assign;if(!k)throw t("ngModel")("nonassign",d.ngModel,ha(e));this.$render=C;this.$isEmpty=function(a){return E(a)||""===a||null===a||a!==a};var m=e.inheritedData("$formController")||sb,n=0,p=this.$error={};e.addClass(La);h(!0);this.$setValidity=function(a,c){p[a]!== -!c&&(c?(p[a]&&n--,n||(h(!0),this.$valid=!0,this.$invalid=!1)):(h(!1),this.$invalid=!0,this.$valid=!1,n++),p[a]=!c,h(c,a),m.$setValidity(a,c,this))};this.$setPristine=function(){this.$dirty=!1;this.$pristine=!0;f.removeClass(e,tb);f.addClass(e,La)};this.$setViewValue=function(d){this.$viewValue=d;this.$pristine&&(this.$dirty=!0,this.$pristine=!1,f.removeClass(e,La),f.addClass(e,tb),m.$setDirty());q(this.$parsers,function(a){d=a(d)});this.$modelValue!==d&&(this.$modelValue=d,k(a,d),q(this.$viewChangeListeners, -function(a){try{a()}catch(d){c(d)}}))};var r=this;a.$watch(function(){var c=l(a);if(r.$modelValue!==c){var d=r.$formatters,e=d.length;for(r.$modelValue=c;e--;)c=d[e](c);r.$viewValue!==c&&(r.$viewValue=c,r.$render())}return c})}],Fd=function(){return{require:["ngModel","^?form"],controller:Re,link:function(a,c,d,e){var g=e[0],f=e[1]||sb;f.$addControl(g);a.$on("$destroy",function(){f.$removeControl(g)})}}},Hd=aa({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}), -ec=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var g=function(a){if(d.required&&e.$isEmpty(a))e.$setValidity("required",!1);else return e.$setValidity("required",!0),a};e.$formatters.push(g);e.$parsers.unshift(g);d.$observe("required",function(){g(e.$viewValue)})}}}},Gd=function(){return{require:"ngModel",link:function(a,c,d,e){var g=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){if(!E(a)){var c=[];a&&q(a.split(g),function(a){a&& -c.push(ca(a))});return c}});e.$formatters.push(function(a){return M(a)?a.join(", "):s});e.$isEmpty=function(a){return!a||!a.length}}}},Se=/^(true|false|\d+)$/,Id=function(){return{priority:100,compile:function(a,c){return Se.test(c.ngValue)?function(a,c,g){g.$set("value",a.$eval(g.ngValue))}:function(a,c,g){a.$watch(g.ngValue,function(a){g.$set("value",a)})}}}},id=va(function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBind);a.$watch(d.ngBind,function(a){c.text(a==s?"":a)})}),kd=["$interpolate", -function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}],jd=["$sce","$parse",function(a,c){return function(d,e,g){e.addClass("ng-binding").data("$binding",g.ngBindHtml);var f=c(g.ngBindHtml);d.$watch(function(){return(f(d)||"").toString()},function(c){e.html(a.getTrustedHtml(f(d))||"")})}}],ld=Pb("",!0),nd=Pb("Odd",0),md=Pb("Even",1),od=va({compile:function(a,c){c.$set("ngCloak",s);a.removeClass("ng-cloak")}}), -pd=[function(){return{scope:!0,controller:"@",priority:500}}],fc={};q("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var c=na("ng-"+a);fc[c]=["$parse",function(d){return{compile:function(e,g){var f=d(g[c]);return function(c,d,e){d.on(K(a),function(a){c.$apply(function(){f(c,{$event:a})})})}}}}]});var sd=["$animate",function(a){return{transclude:"element",priority:600,terminal:!0,restrict:"A", -$$tlb:!0,link:function(c,d,e,g,f){var h,l,k;c.$watch(e.ngIf,function(g){Qa(g)?l||(l=c.$new(),f(l,function(c){c[c.length++]=U.createComment(" end ngIf: "+e.ngIf+" ");h={clone:c};a.enter(c,d.parent(),d)})):(k&&(k.remove(),k=null),l&&(l.$destroy(),l=null),h&&(k=yb(h.clone),a.leave(k,function(){k=null}),h=null))})}}}],td=["$http","$templateCache","$anchorScroll","$animate","$sce",function(a,c,d,e,g){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:Ea.noop,compile:function(f, -h){var l=h.ngInclude||h.src,k=h.onload||"",m=h.autoscroll;return function(f,h,q,s,u){var F=0,v,y,A,x=function(){y&&(y.remove(),y=null);v&&(v.$destroy(),v=null);A&&(e.leave(A,function(){y=null}),y=A,A=null)};f.$watch(g.parseAsResourceUrl(l),function(g){var l=function(){!B(m)||m&&!f.$eval(m)||d()},q=++F;g?(a.get(g,{cache:c}).success(function(a){if(q===F){var c=f.$new();s.template=a;a=u(c,function(a){x();e.enter(a,null,h,l)});v=c;A=a;v.$emit("$includeContentLoaded");f.$eval(k)}}).error(function(){q=== -F&&x()}),f.$emit("$includeContentRequested")):(x(),s.template=null)})}}}}],Jd=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(c,d,e,g){d.html(g.template);a(d.contents())(c)}}}],ud=va({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),vd=va({terminal:!0,priority:1E3}),wd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,g,f){var h=f.count,l=f.$attr.when&&g.attr(f.$attr.when),k=f.offset|| -0,m=e.$eval(l)||{},n={},p=c.startSymbol(),r=c.endSymbol(),s=/^when(Minus)?(.+)$/;q(f,function(a,c){s.test(c)&&(m[K(c.replace("when","").replace("Minus","-"))]=g.attr(f.$attr[c]))});q(m,function(a,e){n[e]=c(a.replace(d,p+h+"-"+k+r))});e.$watch(function(){var c=parseFloat(e.$eval(h));if(isNaN(c))return"";c in m||(c=a.pluralCat(c-k));return n[c](e,g,!0)},function(a){g.text(a)})}}}],xd=["$parse","$animate",function(a,c){var d=t("ngRepeat");return{transclude:"element",priority:1E3,terminal:!0,$$tlb:!0, -link:function(e,g,f,h,l){var k=f.ngRepeat,m=k.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),n,p,r,s,u,F,v={$id:Ia};if(!m)throw d("iexp",k);f=m[1];h=m[2];(m=m[3])?(n=a(m),p=function(a,c,d){F&&(v[F]=a);v[u]=c;v.$index=d;return n(e,v)}):(r=function(a,c){return Ia(c)},s=function(a){return a});m=f.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!m)throw d("iidexp",f);u=m[3]||m[1];F=m[2];var B={};e.$watchCollection(h,function(a){var f,h,m=g[0],n,v={},H,R,w,C,T,t, -E=[];if(ab(a))T=a,n=p||r;else{n=p||s;T=[];for(w in a)a.hasOwnProperty(w)&&"$"!=w.charAt(0)&&T.push(w);T.sort()}H=T.length;h=E.length=T.length;for(f=0;fA;)z.pop().element.remove()}for(;x.length>I;)x.pop()[0].element.remove()}var k;if(!(k=t.match(d)))throw Te("iexp",t,ha(f));var l=c(k[2]||k[1]),m=k[4]||k[6],n=k[5],p=c(k[3]||""),q= -c(k[2]?k[1]:m),y=c(k[7]),w=k[8]?c(k[8]):null,x=[[{element:f,label:""}]];u&&(a(u)(e),u.removeClass("ng-scope"),u.remove());f.empty();f.on("change",function(){e.$apply(function(){var a,c=y(e)||[],d={},h,k,l,p,t,v,u;if(r)for(k=[],p=0,v=x.length;p@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}'); -//# sourceMappingURL=angular.min.js.map diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/angular.min.js.map b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/angular.min.js.map deleted file mode 100644 index 0dddf2aab5d2..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/angular.min.js.map +++ /dev/null @@ -1,8 +0,0 @@ -{ -"version":3, -"file":"angular.min.js", -"lineCount":209, -"mappings":"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", -"sources":["angular.js"], -"names":["window","document","undefined","minErr","isArrayLike","obj","isWindow","length","nodeType","isString","isArray","forEach","iterator","context","key","isFunction","hasOwnProperty","call","sortedKeys","keys","push","sort","forEachSorted","i","reverseParams","iteratorFn","value","nextUid","index","uid","digit","charCodeAt","join","String","fromCharCode","unshift","setHashKey","h","$$hashKey","extend","dst","arguments","int","str","parseInt","inherit","parent","extra","noop","identity","$","valueFn","isUndefined","isDefined","isObject","isNumber","isDate","toString","isRegExp","location","alert","setInterval","isElement","node","nodeName","prop","attr","find","map","results","list","indexOf","array","arrayRemove","splice","copy","source","destination","$evalAsync","$watch","ngMinErr","Date","getTime","RegExp","shallowCopy","src","charAt","equals","o1","o2","t1","t2","keySet","csp","securityPolicy","isActive","querySelector","bind","self","fn","curryArgs","slice","startIndex","apply","concat","toJsonReplacer","val","toJson","pretty","JSON","stringify","fromJson","json","parse","toBoolean","v","lowercase","startingTag","element","jqLite","clone","empty","e","elemHtml","append","html","TEXT_NODE","match","replace","tryDecodeURIComponent","decodeURIComponent","parseKeyValue","keyValue","key_value","split","toKeyValue","parts","arrayValue","encodeUriQuery","encodeUriSegment","pctEncodeSpaces","encodeURIComponent","angularInit","bootstrap","elements","appElement","module","names","NG_APP_CLASS_REGEXP","name","getElementById","querySelectorAll","exec","className","attributes","modules","doBootstrap","injector","tag","$provide","createInjector","invoke","scope","compile","animate","$apply","data","NG_DEFER_BOOTSTRAP","test","angular","resumeBootstrap","angular.resumeBootstrap","extraModules","snake_case","separator","SNAKE_CASE_REGEXP","letter","pos","toLowerCase","assertArg","arg","reason","assertArgFn","acceptArrayAnnotation","constructor","assertNotHasOwnProperty","getter","path","bindFnToScope","lastInstance","len","getBlockElements","nodes","startNode","endNode","nextSibling","setupModuleLoader","$injectorMinErr","$$minErr","factory","requires","configFn","invokeLater","provider","method","insertMethod","invokeQueue","moduleInstance","runBlocks","config","run","block","publishExternalAPI","version","uppercase","angularModule","$LocaleProvider","ngModule","$$SanitizeUriProvider","$CompileProvider","directive","htmlAnchorDirective","inputDirective","formDirective","scriptDirective","selectDirective","styleDirective","optionDirective","ngBindDirective","ngBindHtmlDirective","ngBindTemplateDirective","ngClassDirective","ngClassEvenDirective","ngClassOddDirective","ngCloakDirective","ngControllerDirective","ngFormDirective","ngHideDirective","ngIfDirective","ngIncludeDirective","ngInitDirective","ngNonBindableDirective","ngPluralizeDirective","ngRepeatDirective","ngShowDirective","ngStyleDirective","ngSwitchDirective","ngSwitchWhenDirective","ngSwitchDefaultDirective","ngOptionsDirective","ngTranscludeDirective","ngModelDirective","ngListDirective","ngChangeDirective","requiredDirective","ngValueDirective","ngIncludeFillContentDirective","ngAttributeAliasDirectives","ngEventDirectives","$AnchorScrollProvider","$AnimateProvider","$BrowserProvider","$CacheFactoryProvider","$ControllerProvider","$DocumentProvider","$ExceptionHandlerProvider","$FilterProvider","$InterpolateProvider","$IntervalProvider","$HttpProvider","$HttpBackendProvider","$LocationProvider","$LogProvider","$ParseProvider","$RootScopeProvider","$QProvider","$SceProvider","$SceDelegateProvider","$SnifferProvider","$TemplateCacheProvider","$TimeoutProvider","$WindowProvider","$$RAFProvider","$$AsyncCallbackProvider","camelCase","SPECIAL_CHARS_REGEXP","_","offset","toUpperCase","MOZ_HACK_REGEXP","jqLitePatchJQueryRemove","dispatchThis","filterElems","getterIfNoArguments","removePatch","param","filter","fireEvent","set","setIndex","setLength","childIndex","children","shift","triggerHandler","childLength","jQuery","originalJqFn","$original","JQLite","trim","jqLiteMinErr","parsed","SINGLE_TAG_REGEXP","fragment","createDocumentFragment","HTML_REGEXP","tmp","appendChild","createElement","TAG_NAME_REGEXP","wrap","wrapMap","_default","innerHTML","XHTML_TAG_REGEXP","removeChild","firstChild","lastChild","j","jj","childNodes","textContent","createTextNode","jqLiteAddNodes","jqLiteClone","cloneNode","jqLiteDealoc","jqLiteRemoveData","jqLiteOff","type","unsupported","events","jqLiteExpandoStore","handle","eventHandler","removeEventListenerFn","expandoId","jqName","expandoStore","jqCache","$destroy","jqId","jqLiteData","isSetter","keyDefined","isSimpleGetter","jqLiteHasClass","selector","getAttribute","jqLiteRemoveClass","cssClasses","setAttribute","cssClass","jqLiteAddClass","existingClasses","root","jqLiteController","jqLiteInheritedData","ii","parentNode","host","jqLiteEmpty","getBooleanAttrName","booleanAttr","BOOLEAN_ATTR","BOOLEAN_ELEMENTS","createEventHandler","event","preventDefault","event.preventDefault","returnValue","stopPropagation","event.stopPropagation","cancelBubble","target","srcElement","defaultPrevented","prevent","isDefaultPrevented","event.isDefaultPrevented","eventHandlersCopy","msie","elem","hashKey","objType","HashMap","put","annotate","$inject","fnText","STRIP_COMMENTS","argDecl","FN_ARGS","FN_ARG_SPLIT","FN_ARG","all","underscore","last","modulesToLoad","supportObject","delegate","provider_","providerInjector","instantiate","$get","providerCache","providerSuffix","factoryFn","loadModules","moduleFn","loadedModules","get","_runBlocks","_invokeQueue","invokeArgs","message","stack","createInternalInjector","cache","getService","serviceName","INSTANTIATING","err","locals","args","Type","Constructor","returnedValue","prototype","instance","has","service","$injector","constant","instanceCache","decorator","decorFn","origProvider","orig$get","origProvider.$get","origInstance","instanceInjector","servicename","autoScrollingEnabled","disableAutoScrolling","this.disableAutoScrolling","$window","$location","$rootScope","getFirstAnchor","result","scroll","hash","elm","scrollIntoView","getElementsByName","scrollTo","autoScrollWatch","autoScrollWatchAction","$$rAF","$timeout","supported","Browser","$log","$sniffer","completeOutstandingRequest","outstandingRequestCount","outstandingRequestCallbacks","pop","error","startPoller","interval","setTimeout","check","pollFns","pollFn","pollTimeout","fireUrlChange","newLocation","lastBrowserUrl","url","urlChangeListeners","listener","rawDocument","history","clearTimeout","pendingDeferIds","isMock","$$completeOutstandingRequest","$$incOutstandingRequestCount","self.$$incOutstandingRequestCount","notifyWhenNoOutstandingRequests","self.notifyWhenNoOutstandingRequests","callback","addPollFn","self.addPollFn","href","baseElement","self.url","replaceState","pushState","urlChangeInit","onUrlChange","self.onUrlChange","on","hashchange","baseHref","self.baseHref","lastCookies","lastCookieString","cookiePath","cookies","self.cookies","cookieLength","cookie","escape","warn","cookieArray","unescape","substring","defer","self.defer","delay","timeoutId","cancel","self.defer.cancel","deferId","$document","this.$get","cacheFactory","cacheId","options","refresh","entry","freshEnd","staleEnd","n","link","p","nextEntry","prevEntry","caches","size","stats","capacity","Number","MAX_VALUE","lruHash","lruEntry","remove","removeAll","destroy","info","cacheFactory.info","cacheFactory.get","$cacheFactory","$$sanitizeUriProvider","hasDirectives","Suffix","COMMENT_DIRECTIVE_REGEXP","CLASS_DIRECTIVE_REGEXP","EVENT_HANDLER_ATTR_REGEXP","this.directive","registerDirective","directiveFactory","$exceptionHandler","directives","priority","require","controller","restrict","aHrefSanitizationWhitelist","this.aHrefSanitizationWhitelist","regexp","imgSrcSanitizationWhitelist","this.imgSrcSanitizationWhitelist","$interpolate","$http","$templateCache","$parse","$controller","$sce","$animate","$$sanitizeUri","$compileNodes","transcludeFn","maxPriority","ignoreDirective","previousCompileContext","nodeValue","compositeLinkFn","compileNodes","safeAddClass","publicLinkFn","cloneConnectFn","transcludeControllers","$linkNode","JQLitePrototype","eq","$element","addClass","nodeList","$rootElement","boundTranscludeFn","childLinkFn","$node","childScope","nodeListLength","stableNodeList","Array","linkFns","nodeLinkFn","$new","childTranscludeFn","transclude","createBoundTranscludeFn","attrs","linkFnFound","Attributes","collectDirectives","applyDirectivesToNode","terminal","transcludedScope","cloneFn","controllers","scopeCreated","$$transcluded","attrsMap","$attr","addDirective","directiveNormalize","nodeName_","nName","nAttrs","attrStartName","attrEndName","specified","ngAttrName","NG_ATTR_BINDING","substr","directiveNName","addAttrInterpolateDirective","addTextInterpolateDirective","byPriority","groupScan","attrStart","attrEnd","depth","hasAttribute","$compileMinErr","groupElementsLinkFnWrapper","linkFn","compileNode","templateAttrs","jqCollection","originalReplaceDirective","preLinkFns","postLinkFns","addLinkFns","pre","post","newIsolateScopeDirective","$$isolateScope","cloneAndAnnotateFn","getControllers","elementControllers","retrievalMethod","optional","directiveName","linkNode","controllersBoundTransclude","cloneAttachFn","hasElementTranscludeDirective","isolateScope","$$element","LOCAL_REGEXP","templateDirective","$$originalDirective","definition","scopeName","attrName","mode","lastValue","parentGet","parentSet","compare","$$isolateBindings","$observe","$$observers","$$scope","literal","a","b","assign","parentValueWatch","parentValue","controllerDirectives","controllerInstance","controllerAs","$scope","scopeToChild","template","templateUrl","terminalPriority","newScopeDirective","nonTlbTranscludeDirective","hasTranscludeDirective","$compileNode","$template","$$start","$$end","directiveValue","assertNoDuplicate","$$tlb","createComment","replaceWith","replaceDirective","contents","denormalizeTemplate","newTemplateAttrs","templateDirectives","unprocessedDirectives","markDirectivesAsIsolate","mergeTemplateAttributes","compileTemplateUrl","Math","max","tDirectives","startAttrName","endAttrName","srcAttr","dstAttr","$set","tAttrs","linkQueue","afterTemplateNodeLinkFn","afterTemplateChildLinkFn","beforeTemplateCompileNode","origAsyncDirective","derivedSyncDirective","getTrustedResourceUrl","success","content","childBoundTranscludeFn","tempTemplateAttrs","beforeTemplateLinkNode","linkRootElement","oldClasses","response","code","headers","delayedNodeLinkFn","ignoreChildLinkFn","rootElement","diff","what","previousDirective","text","interpolateFn","textInterpolateLinkFn","bindings","interpolateFnWatchAction","getTrustedContext","attrNormalizedName","HTML","RESOURCE_URL","attrInterpolatePreLinkFn","$$inter","newValue","oldValue","$updateClass","elementsToRemove","newNode","firstElementToRemove","removeCount","j2","replaceChild","expando","k","kk","annotation","$addClass","classVal","$removeClass","removeClass","newClasses","toAdd","tokenDifference","toRemove","setClass","writeAttr","booleanKey","removeAttr","listeners","startSymbol","endSymbol","PREFIX_REGEXP","str1","str2","values","tokens1","tokens2","token","CNTRL_REG","register","this.register","expression","identifier","exception","cause","parseHeaders","line","headersGetter","headersObj","transformData","fns","JSON_START","JSON_END","PROTECTION_PREFIX","CONTENT_TYPE_APPLICATION_JSON","defaults","d","interceptorFactories","interceptors","responseInterceptorFactories","responseInterceptors","$httpBackend","$browser","$q","requestConfig","transformResponse","resp","status","reject","transformRequest","mergeHeaders","execHeaders","headerContent","headerFn","header","defHeaders","reqHeaders","defHeaderName","reqHeaderName","common","lowercaseDefHeaderName","xsrfValue","urlIsSameOrigin","xsrfCookieName","xsrfHeaderName","chain","serverRequest","reqData","withCredentials","sendReq","then","promise","when","reversedInterceptors","interceptor","request","requestError","responseError","thenFn","rejectFn","promise.success","promise.error","done","headersString","statusText","resolvePromise","$$phase","deferred","resolve","removePendingReq","idx","pendingRequests","cachedResp","buildUrl","params","defaultCache","timeout","responseType","interceptorFactory","responseFn","createShortMethods","createShortMethodsWithData","createXhr","XMLHttpRequest","ActiveXObject","createHttpBackend","callbacks","$browserDefer","jsonpReq","script","doneWrapper","onreadystatechange","onload","onerror","body","script.onreadystatechange","readyState","script.onerror","ABORTED","timeoutRequest","jsonpDone","xhr","abort","completeRequest","urlResolve","protocol","callbackId","counter","open","setRequestHeader","xhr.onreadystatechange","responseHeaders","getAllResponseHeaders","responseText","send","this.startSymbol","this.endSymbol","mustHaveExpression","trustedContext","endIndex","hasInterpolation","startSymbolLength","exp","endSymbolLength","$interpolateMinErr","part","getTrusted","valueOf","newErr","$interpolate.startSymbol","$interpolate.endSymbol","count","invokeApply","clearInterval","iteration","skipApply","$$intervalId","tick","notify","intervals","interval.cancel","short","pluralCat","num","encodePath","segments","parseAbsoluteUrl","absoluteUrl","locationObj","appBase","parsedUrl","$$protocol","$$host","hostname","$$port","port","DEFAULT_PORTS","parseAppUrl","relativeUrl","prefixed","$$path","pathname","$$search","search","$$hash","beginsWith","begin","whole","stripHash","stripFile","lastIndexOf","LocationHtml5Url","basePrefix","$$html5","appBaseNoFile","$$parse","this.$$parse","pathUrl","$locationMinErr","$$compose","this.$$compose","$$url","$$absUrl","$$rewrite","this.$$rewrite","appUrl","prevAppUrl","LocationHashbangUrl","hashPrefix","withoutBaseUrl","withoutHashUrl","windowsFilePathExp","firstPathSegmentMatch","LocationHashbangInHtml5Url","locationGetter","property","locationGetterSetter","preprocess","html5Mode","this.hashPrefix","prefix","this.html5Mode","afterLocationChange","oldUrl","$broadcast","absUrl","initialUrl","LocationMode","ctrlKey","metaKey","which","absHref","animVal","rewrittenUrl","newUrl","$digest","changeCounter","$locationWatch","currentReplace","$$replace","debug","debugEnabled","this.debugEnabled","flag","formatError","Error","sourceURL","consoleLog","console","logFn","log","hasApply","arg1","arg2","ensureSafeMemberName","fullExpression","$parseMinErr","ensureSafeObject","setter","setValue","fullExp","propertyObj","unwrapPromises","promiseWarning","$$v","cspSafeGetterFn","key0","key1","key2","key3","key4","cspSafePromiseEnabledGetter","pathVal","cspSafeGetter","simpleGetterFn1","simpleGetterFn2","getterFn","getterFnCache","pathKeys","pathKeysLength","evaledFnGetter","Function","$parseOptions","this.unwrapPromises","logPromiseWarnings","this.logPromiseWarnings","$filter","promiseWarningCache","parsedExpression","lexer","Lexer","parser","Parser","qFactory","nextTick","exceptionHandler","defaultCallback","defaultErrback","pending","ref","createInternalRejectedPromise","progress","errback","progressback","wrappedCallback","wrappedErrback","wrappedProgressback","catch","finally","makePromise","resolved","handleCallback","isResolved","callbackOutput","promises","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","cancelAnimationFrame","webkitCancelAnimationFrame","mozCancelAnimationFrame","webkitCancelRequestAnimationFrame","rafSupported","raf","id","timer","TTL","$rootScopeMinErr","lastDirtyWatch","digestTtl","this.digestTtl","Scope","$id","$parent","$$watchers","$$nextSibling","$$prevSibling","$$childHead","$$childTail","$root","$$destroyed","$$asyncQueue","$$postDigestQueue","$$listeners","$$listenerCount","beginPhase","phase","compileToFn","decrementListenerCount","current","initWatchVal","isolate","child","ChildScope","watchExp","objectEquality","watcher","listenFn","watcher.fn","newVal","oldVal","originalFn","$watchCollection","veryOldValue","trackVeryOldValue","changeDetected","objGetter","internalArray","internalObject","initRun","oldLength","$watchCollectionWatch","newLength","$watchCollectionAction","watch","watchers","asyncQueue","postDigestQueue","dirty","ttl","watchLog","logIdx","logMsg","asyncTask","$eval","isNaN","next","$on","this.$watch","expr","$$postDigest","namedListeners","$emit","listenerArgs","array1","currentScope","sanitizeUri","uri","isImage","regex","normalizedVal","adjustMatcher","matcher","$sceMinErr","adjustMatchers","matchers","adjustedMatchers","SCE_CONTEXTS","resourceUrlWhitelist","resourceUrlBlacklist","this.resourceUrlWhitelist","this.resourceUrlBlacklist","generateHolderType","Base","holderType","trustedValue","$$unwrapTrustedValue","this.$$unwrapTrustedValue","holderType.prototype.valueOf","holderType.prototype.toString","htmlSanitizer","trustedValueHolderBase","byType","CSS","URL","JS","trustAs","maybeTrusted","allowed","enabled","this.enabled","$sceDelegate","msieDocumentMode","sce","isEnabled","sce.isEnabled","sce.getTrusted","parseAs","sce.parseAs","sceParseAsTrusted","enumValue","lName","eventSupport","android","userAgent","navigator","boxee","documentMode","vendorPrefix","vendorRegex","bodyStyle","style","transitions","animations","webkitTransition","webkitAnimation","hasEvent","divElm","deferreds","$$timeoutId","timeout.cancel","base","urlParsingNode","requestUrl","originUrl","filters","suffix","currencyFilter","dateFilter","filterFilter","jsonFilter","limitToFilter","lowercaseFilter","numberFilter","orderByFilter","uppercaseFilter","comparator","comparatorType","predicates","predicates.check","objKey","filtered","$locale","formats","NUMBER_FORMATS","amount","currencySymbol","CURRENCY_SYM","formatNumber","PATTERNS","GROUP_SEP","DECIMAL_SEP","number","fractionSize","pattern","groupSep","decimalSep","isFinite","isNegative","abs","numStr","formatedText","hasExponent","toFixed","fractionLen","min","minFrac","maxFrac","pow","round","fraction","lgroup","lgSize","group","gSize","negPre","posPre","negSuf","posSuf","padNumber","digits","neg","dateGetter","date","dateStrGetter","shortForm","jsonStringToDate","string","R_ISO8601_STR","tzHour","tzMin","dateSetter","setUTCFullYear","setFullYear","timeSetter","setUTCHours","setHours","m","s","ms","parseFloat","format","DATETIME_FORMATS","NUMBER_STRING","DATE_FORMATS_SPLIT","DATE_FORMATS","object","input","limit","out","sortPredicate","reverseOrder","reverseComparator","comp","descending","v1","v2","predicate","arrayCopy","ngDirective","FormController","toggleValidCss","isValid","validationErrorKey","INVALID_CLASS","VALID_CLASS","form","parentForm","nullFormCtrl","invalidCount","errors","$error","controls","$name","ngForm","$dirty","$pristine","$valid","$invalid","$addControl","PRISTINE_CLASS","form.$addControl","control","$removeControl","form.$removeControl","queue","validationToken","$setValidity","form.$setValidity","$setDirty","form.$setDirty","DIRTY_CLASS","$setPristine","form.$setPristine","validate","ctrl","validatorName","validity","addNativeHtml5Validators","$parsers","validator","badInput","customError","typeMismatch","valueMissing","textInputType","composing","ngTrim","$viewValue","$setViewValue","deferListener","keyCode","$render","ctrl.$render","$isEmpty","ngPattern","patternValidator","patternObj","$formatters","ngMinlength","minlength","minLengthValidator","ngMaxlength","maxlength","maxLengthValidator","classDirective","arrayDifference","arrayClasses","classes","digestClassCounts","classCounts","classesToUpdate","ngClassWatchAction","$index","old$index","mod","Object","addEventListenerFn","addEventListener","attachEvent","removeEventListener","detachEvent","_data","JQLite._data","optgroup","option","tbody","tfoot","colgroup","caption","thead","th","td","ready","trigger","fired","removeAttribute","css","currentStyle","lowercasedName","getNamedItem","ret","getText","textProp","NODE_TYPE_TEXT_PROPERTY","$dv","multiple","selected","onFn","eventFns","contains","compareDocumentPosition","adown","documentElement","bup","eventmap","related","relatedTarget","one","off","replaceNode","insertBefore","contentDocument","prepend","wrapNode","after","newElement","toggleClass","condition","classCondition","nextElementSibling","getElementsByTagName","eventName","eventData","arg3","unbind","$animateMinErr","$$selectors","classNameFilter","this.classNameFilter","$$classNameFilter","$$asyncCallback","enter","leave","move","add","PATH_MATCH","paramValue","OPERATORS","null","true","false","+","-","*","/","%","^","===","!==","==","!=","<",">","<=",">=","&&","||","&","|","!","ESCAPE","lex","ch","lastCh","tokens","is","readString","peek","readNumber","isIdent","readIdent","was","isWhitespace","ch2","ch3","fn2","fn3","throwError","chars","isExpOperator","start","end","colStr","peekCh","ident","lastDot","peekIndex","methodName","quote","rawString","hex","rep","ZERO","assignment","logicalOR","functionCall","fieldAccess","objectIndex","filterChain","this.filterChain","primary","statements","expect","consume","arrayDeclaration","msg","peekToken","e1","e2","e3","e4","t","unaryFn","right","ternaryFn","left","middle","binaryFn","statement","argsFn","fnInvoke","ternary","logicalAND","equality","relational","additive","multiplicative","unary","field","indexFn","o","safe","contextGetter","fnPtr","elementFns","allConstant","elementFn","keyValues","ampmGetter","getHours","AMPMS","timeZoneGetter","zone","getTimezoneOffset","paddedZone","xlinkHref","propName","normalized","ngBooleanAttrWatchAction","formDirectiveFactory","isNgForm","formElement","action","preventDefaultListener","parentFormCtrl","alias","URL_REGEXP","EMAIL_REGEXP","NUMBER_REGEXP","inputType","numberInputType","minValidator","maxValidator","urlInputType","urlValidator","emailInputType","emailValidator","radioInputType","checked","checkboxInputType","trueValue","ngTrueValue","falseValue","ngFalseValue","ctrl.$isEmpty","NgModelController","$modelValue","NaN","$viewChangeListeners","ngModelGet","ngModel","ngModelSet","this.$isEmpty","inheritedData","this.$setValidity","this.$setPristine","this.$setViewValue","ngModelWatch","formatters","ctrls","modelCtrl","formCtrl","ngChange","required","ngList","viewValue","CONSTANT_VALUE_REGEXP","tpl","tplAttr","ngValue","ngValueConstantLink","ngValueLink","valueWatchAction","ngBind","ngBindWatchAction","ngBindTemplate","ngBindHtml","getStringValue","ngBindHtmlWatchAction","getTrustedHtml","$transclude","previousElements","ngIf","ngIfWatchAction","$anchorScroll","srcExp","ngInclude","onloadExp","autoScrollExp","autoscroll","previousElement","currentElement","cleanupLastIncludeContent","parseAsResourceUrl","ngIncludeWatchAction","afterAnimation","thisChangeId","newScope","$compile","ngInit","BRACE","numberExp","whenExp","whens","whensExpFns","isWhen","attributeName","ngPluralizeWatch","ngPluralizeWatchAction","ngRepeatMinErr","ngRepeat","trackByExpGetter","trackByIdExpFn","trackByIdArrayFn","trackByIdObjFn","valueIdentifier","keyIdentifier","hashFnLocals","lhs","rhs","trackByExp","lastBlockMap","ngRepeatAction","collection","previousNode","nextNode","nextBlockMap","arrayLength","collectionKeys","nextBlockOrder","trackByIdFn","trackById","$first","$last","$middle","$odd","$even","ngShow","ngShowWatchAction","ngHide","ngHideWatchAction","ngStyle","ngStyleWatchAction","newStyles","oldStyles","ngSwitchController","cases","selectedTranscludes","selectedElements","selectedScopes","ngSwitch","ngSwitchWatchAction","change","selectedTransclude","selectedScope","caseElement","anchor","ngSwitchWhen","$attrs","ngOptionsMinErr","NG_OPTIONS_REGEXP","nullModelCtrl","optionsMap","ngModelCtrl","unknownOption","databound","init","self.init","ngModelCtrl_","nullOption_","unknownOption_","addOption","self.addOption","removeOption","self.removeOption","hasOption","renderUnknownOption","self.renderUnknownOption","unknownVal","self.hasOption","setupAsSingle","selectElement","selectCtrl","ngModelCtrl.$render","emptyOption","setupAsMultiple","lastView","items","selectMultipleWatch","setupAsOptions","render","optionGroups","optionGroupNames","optionGroupName","optionGroup","existingParent","existingOptions","modelValue","valuesFn","keyName","groupIndex","selectedSet","lastElement","trackFn","trackIndex","valueName","groupByFn","modelCast","label","displayFn","nullOption","groupLength","optionGroupsCache","optGroupTemplate","existingOption","optionTemplate","optionsExp","track","optionElement","ngOptions","ngModelCtrl.$isEmpty","nullSelectCtrl","selectCtrlName","interpolateWatchAction","$$csp"] -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/index.html b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/index.html deleted file mode 100644 index 47a1965b7581..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
      - - ID: {{server.podName}}
      - Host:
      {{server.host}}
      - Status: {{server.status}}
      - Image: {{server.dockerImage}}
      - Labels: -
        -
      • {{key}}={{value}}
      • -
      -
      - - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/script.js b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/script.js deleted file mode 100644 index d6edb74f73bb..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/script.js +++ /dev/null @@ -1,100 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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. -*/ - -var base = "/api/v1/"; - -var updateImage = function($http, server) { - $http.get(base + "proxy/namespaces/default/pods/" + server.podName + "/data.json") - .success(function(data) { - console.log(data); - server.image = data.image; - }) - .error(function(data) { - console.log(data); - server.image = ""; - }); -}; - -var updateServer = function($http, server) { - $http.get(base + "namespaces/default/pods/" + server.podName) - .success(function(data) { - console.log(data); - server.labels = data.metadata.labels; - server.host = data.status.hostIP.split('.')[0]; - server.status = data.status.phase; - server.dockerImage = data.status.containerStatuses[0].image; - updateImage($http, server); - }) - .error(function(data) { - console.log(data); - }); -}; - -var updateData = function($scope, $http) { - var servers = $scope.servers; - for (var i = 0; i < servers.length; ++i) { - var server = servers[i]; - updateServer($http, server); - } -}; - -var ButtonsCtrl = function ($scope, $http, $interval) { - $scope.servers = []; - update($scope, $http); - $interval(angular.bind({}, update, $scope, $http), 2000); -}; - -var getServer = function($scope, name) { - var servers = $scope.servers; - for (var i = 0; i < servers.length; ++i) { - if (servers[i].podName == name) { - return servers[i]; - } - } - return null; -}; - -var isUpdateDemoPod = function(pod) { - return pod.metadata && pod.metadata.labels && pod.metadata.labels.name == "update-demo"; -}; - -var update = function($scope, $http) { - if (!$http) { - console.log("No HTTP!"); - return; - } - $http.get(base + "namespaces/default/pods") - .success(function(data) { - console.log(data); - var newServers = []; - for (var i = 0; i < data.items.length; ++i) { - var pod = data.items[i]; - if (!isUpdateDemoPod(pod)) { - continue; - } - var server = getServer($scope, pod.metadata.name); - if (server == null) { - server = { "podName": pod.metadata.name }; - } - newServers.push(server); - } - $scope.servers = newServers; - updateData($scope, $http); - }) - .error(function(data) { - console.log("ERROR: " + data); - }) -}; diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/style.css b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/style.css deleted file mode 100644 index ea8941c0ac35..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/update-demo/local/style.css +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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. -*/ - -img { - height: 100px; - width: 100px; - float: right; - background-size: 100px 100px; - background-color: black; - margin-left: 10px; - border: none; -} - -ul { - margin-top: 0; - margin-bottom: 0; -} - -.pod { - font-family: Roboto, Open Sans, arial; - border: 1px solid black; - border-radius: 5px; - padding: 10px; - margin: 10px; - display: inline-block; - background-color: #D1D1D1; -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/volumes.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/volumes.md deleted file mode 100644 index 9502af5bbd7b..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/volumes.md +++ /dev/null @@ -1,400 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/volumes.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Volumes - -On-disk files in a container are ephemeral, which presents some problems for -non-trivial applications when running in containers. First, when a container -crashes kubelet will restart it, but the files will be lost - the -container starts with a clean slate. Second, when running containers together -in a `Pod` it is often necessary to share files between those containers. The -Kubernetes `Volume` abstraction solves both of these problems. - -Familiarity with [pods](pods.md) is suggested. - -**Table of Contents** - - -- [Volumes](#volumes) - - [Background](#background) - - [Types of Volumes](#types-of-volumes) - - [emptyDir](#emptydir) - - [hostPath](#hostpath) - - [gcePersistentDisk](#gcepersistentdisk) - - [Creating a PD](#creating-a-pd) - - [Example pod](#example-pod) - - [awsElasticBlockStore](#awselasticblockstore) - - [Creating an EBS volume](#creating-an-ebs-volume) - - [AWS EBS Example configuration](#aws-ebs-example-configuration) - - [nfs](#nfs) - - [iscsi](#iscsi) - - [glusterfs](#glusterfs) - - [rbd](#rbd) - - [gitRepo](#gitrepo) - - [secret](#secret) - - [persistentVolumeClaim](#persistentvolumeclaim) - - [Resources](#resources) - - - -## Background - -Docker also has a concept of -[volumes](https://docs.docker.com/userguide/dockervolumes/), though it is -somewhat looser and less managed. In Docker, a volume is simply a directory on -disk or in another container. Lifetimes are not managed and until very -recently there were only local-disk-backed volumes. Docker now provides volume -drivers, but the functionality is very limited for now (e.g. as of Docker 1.7 -only one volume driver is allowed per container and there is no way to pass -parameters to volumes). - -A Kubernetes volume, on the other hand, has an explicit lifetime - the same as -the pod that encloses it. Consequently, a volume outlives any containers that run -within the Pod, and data is preserved across Container restarts. Of course, when a -Pod ceases to exist, the volume will cease to exist, too. Perhaps more -importantly than this, Kubernetes supports many type of volumes, and a Pod can -use any number of them simultaneously. - -At its core, a volume is just a directory, possibly with some data in it, which -is accessible to the containers in a pod. How that directory comes to be, the -medium that backs it, and the contents of it are determined by the particular -volume type used. - -To use a volume, a pod specifies what volumes to provide for the pod (the -[spec.volumes](http://kubernetes.io/third_party/swagger-ui/#!/v1/createPod) -field) and where to mount those into containers(the -[spec.containers.volumeMounts](http://kubernetes.io/third_party/swagger-ui/#!/v1/createPod) -field). - -A process in a container sees a filesystem view composed from their Docker -image and volumes. The [Docker -image](https://docs.docker.com/userguide/dockerimages/) is at the root of the -filesystem hierarchy, and any volumes are mounted at the specified paths within -the image. Volumes can not mount onto other volumes or have hard links to -other volumes. Each container in the Pod must independently specify where to -mount each volume. - -## Types of Volumes - -Kubernetes supports several types of Volumes: - * emptyDir - * hostPath - * gcePersistentDisk - * awsElasticBlockStore - * nfs - * iscsi - * glusterfs - * rbd - * gitRepo - * secret - * persistentVolumeClaim - -We welcome additional contributions. - -### emptyDir - -An `emptyDir` volume is first created when a Pod is assigned to a Node, and -exists as long as that Pod is running on that node. As the name says, it is -initially empty. Containers in the pod can all read and write the same -files in the `emptyDir` volume, though that volume can be mounted at the same -or different paths in each container. When a Pod is removed from a node for -any reason, the data in the `emptyDir` is deleted forever. NOTE: a container -crashing does *NOT* remove a pod from a node, so the data in an `emptyDir` -volume is safe across container crashes. - -Some uses for an `emptyDir` are: - -* scratch space, such as for a disk-based mergesortcw -* checkpointing a long computation for recovery from crashes -* holding files that a content-manager container fetches while a webserver - container serves the data - -By default, `emptyDir` volumes are stored on whatever medium is backing the -machine - that might be disk or SSD or network storage, depending on your -environment. However, you can set the `emptyDir.medium` field to `"Memory"` -to tell Kubernetes to mount a tmpfs (RAM-backed filesystem) for you instead. -While tmpfs is very fast, be aware that unlike disks, tmpfs is cleared on -machine reboot and any files you write will count against your container's -memory limit. - -### hostPath - -A `hostPath` volume mounts a file or directory from the host node's filesystem -into your pod. This is not something that most Pods will need, but it offers a -powerful escape hatch for some applications. - -For example, some uses for a `hostPath` are: - -* running a container that needs access to Docker internals; use a `hostPath` - of `/var/lib/docker` -* running cAdvisor in a container; use a `hostPath` of `/dev/cgroups` - -Watch out when using this type of volume, because: - -* pods with identical configuration (such as created from a podTemplate) may - behave differently on different nodes due to different files on the nodes -* when Kubernetes adds resource-aware scheduling, as is planned, it will not be - able to account for resources used by a `hostPath` - -### gcePersistentDisk - -A `gcePersistentDisk` volume mounts a Google Compute Engine (GCE) [Persistent -Disk](http://cloud.google.com/compute/docs/disks) into your pod. Unlike -`emptyDir`, which is erased when a Pod is removed, the contents of a PD are -preserved and the volume is merely unmounted. This means that a PD can be -pre-populated with data, and that data can be "handed off" between pods. - -__Important: You must create a PD using `gcloud` or the GCE API or UI -before you can use it__ - -There are some restrictions when using a `gcePersistentDisk`: - -* the nodes on which pods are running must be GCE VMs -* those VMs need to be in the same GCE project and zone as the PD - -A feature of PD is that they can be mounted as read-only by multiple consumers -simultaneously. This means that you can pre-populate a PD with your dataset -and then serve it in parallel from as many pods as you need. Unfortunately, -PDs can only be mounted by a single consumer in read-write mode - no -simultaneous readers allowed. - -Using a PD on a pod controlled by a ReplicationController will fail unless -the PD is read-only or the replica count is 0 or 1. - -#### Creating a PD - -Before you can use a GCE PD with a pod, you need to create it. - -```sh -gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk -``` - -#### Example pod - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: test-pd -spec: - containers: - - image: gcr.io/google_containers/test-webserver - name: test-container - volumeMounts: - - mountPath: /test-pd - name: test-volume - volumes: - - name: test-volume - # This GCE PD must already exist. - gcePersistentDisk: - pdName: my-data-disk - fsType: ext4 -``` - -### awsElasticBlockStore - -An `awsElasticBlockStore` volume mounts an Amazon Web Services (AWS) [EBS -Volume](http://aws.amazon.com/ebs/) into your pod. Unlike -`emptyDir`, which is erased when a Pod is removed, the contents of an EBS -volume are preserved and the volume is merely unmounted. This means that an -EBS volume can be pre-populated with data, and that data can be "handed off" -between pods. - -__Important: You must create an EBS volume using `aws ec2 create-volume` or -the AWS API before you can use it__ - -There are some restrictions when using an awsElasticBlockStore volume: - -* the nodes on which pods are running must be AWS EC2 instances -* those instances need to be in the same region and availability-zone as the EBS volume -* EBS only supports a single EC2 instance mounting a volume - -#### Creating an EBS volume - -Before you can use a EBS volume with a pod, you need to create it. - -```sh -aws ec2 create-volume --availability-zone eu-west-1a --size 10 --volume-type gp2 -``` - -Make sure the zone matches the zone you brought up your cluster in. (And also check that the size and EBS volume -type are suitable for your use!) - -#### AWS EBS Example configuration - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: test-ebs -spec: - containers: - - image: gcr.io/google_containers/test-webserver - name: test-container - volumeMounts: - - mountPath: /test-ebs - name: test-volume - volumes: - - name: test-volume - # This AWS EBS volume must already exist. - awsElasticBlockStore: - volumeID: aws:/// - fsType: ext4 -``` - -(Note: the syntax of volumeID is currently awkward; #10181 fixes it) - -### nfs - -An `nfs` volume allows an existing NFS (Network File System) share to be -mounted into your pod. Unlike `emptyDir`, which is erased when a Pod is -removed, the contents of an `nfs` volume are preserved and the volume is merely -unmounted. This means that an NFS volume can be pre-populated with data, and -that data can be "handed off" between pods. NFS can be mounted by multiple -writers simultaneously. - -__Important: You must have your own NFS server running with the share exported -before you can use it__ - -See the [NFS example](../../examples/nfs/) for more details. - -For example, [this file](../../examples/nfs/nfs-web-pod.yaml) demonstrates how to -specify the usage of an NFS volume within a pod. - -In this example one can see that a `volumeMount` called "nfs" is being mounted -onto `/var/www/html` in the container "web". The volume "nfs" is defined as -type `nfs`, with the NFS server serving from `nfs-server.default.kube.local` -and exporting directory `/` as the share. The mount being created in this -example is writeable. - -### iscsi - -An `iscsi` volume allows an existing iSCSI (SCSI over IP) volume to be mounted -into your pod. Unlike `emptyDir`, which is erased when a Pod is removed, the -contents of an `iscsi` volume are preserved and the volume is merely -unmounted. This means that an iscsi volume can be pre-populated with data, and -that data can be "handed off" between pods. - -__Important: You must have your own iSCSI server running with the volume -created before you can use it__ - -A feature of iSCSI is that it can be mounted as read-only by multiple consumers -simultaneously. This means that you can pre-populate a volume with your dataset -and then serve it in parallel from as many pods as you need. Unfortunately, -iSCSI volumes can only be mounted by a single consumer in read-write mode - no -simultaneous readers allowed. - -See the [iSCSI example](../../examples/iscsi/) for more details. - -### glusterfs - -A `glusterfs` volume allows an [Glusterfs](http://www.gluster.org) (an open -source networked filesystem) volume to be mounted into your pod. Unlike -`emptyDir`, which is erased when a Pod is removed, the contents of a -`glusterfs` volume are preserved and the volume is merely unmounted. This -means that a glusterfs volume can be pre-populated with data, and that data can -be "handed off" between pods. GlusterFS can be mounted by multiple writers -simultaneously. - -__Important: You must have your own GlusterFS installation running before you -can use it__ - -See the [GlusterFS example](../../examples/glusterfs/) for more details. - -### rbd - -An `rbd` volume allows a [Rados Block -Device](http://ceph.com/docs/master/rbd/rbd/) volume to be mounted into your -pod. Unlike `emptyDir`, which is erased when a Pod is removed, the contents of -an `rbd` volume are preserved and the volume is merely unmounted. This -means that a RBD volume can be pre-populated with data, and that data can -be "handed off" between pods. - -__Important: You must have your own Ceph installation running before you -can use RBD__ - -A feature of RBD is that it can be mounted as read-only by multiple consumers -simultaneously. This means that you can pre-populate a volume with your dataset -and then serve it in parallel from as many pods as you need. Unfortunately, -RBD volumes can only be mounted by a single consumer in read-write mode - no -simultaneous readers allowed. - -See the [RBD example](../../examples/rbd/) for more details. - -### gitRepo - -A `gitRepo` volume is an example of what can be done as a volume plugin. It -mounts an empty directory and clones a git repository into it for your pod to -use. In the future, such volumes may be moved to an even more decoupled model, -rather than extending the Kubernetes API for every such use case. - -### secret - -A `secret` volume is used to pass sensitive information, such as passwords, to -pods. You can store secrets in the Kubernetes API and mount them as files for -use by pods without coupling to Kubernetes directly. `secret` volumes are -backed by tmpfs (a RAM-backed filesystem) so they are never written to -non-volatile storage. - -__Important: You must create a secret in the Kubernetes API before you can use -it__ - -Secrets are described in more detail [here](secrets.md). - -### persistentVolumeClaim - -A `persistentVolumeClaim` volume is used to mount a -[PersistentVolume](persistent-volumes.md) into a pod. PersistentVolumes are a -way for users to "claim" durable storage (such as a GCE PersistentDisk or an -iSCSI volume) without knowing the details of the particular cloud environment. - -See the [PersistentVolumes example](persistent-volumes/) for more -details. - -## Resources - -The storage media (Disk, SSD, etc) of an `emptyDir` volume is determined by the -medium of the filesystem holding the kubelet root dir (typically -`/var/lib/kubelet`). There is no limit on how much space an `emptyDir` or -`hostPath` volume can consume, and no isolation between containers or between -pods. - -In the future, we expect that `emptyDir` and `hostPath` volumes will be able to -request a certain amount of space using a [resource](compute-resources.md) -specification, and to select the type of media to use, for clusters that have -several media types. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/volumes.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/walkthrough/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/walkthrough/README.md index 9db2f6c5f524..ac9ef12f6759 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/walkthrough/README.md +++ b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/walkthrough/README.md @@ -35,7 +35,7 @@ Documentation for other releases can be found at For Kubernetes 101, we will cover kubectl, pods, volumes, and multiple containers -In order for the kubectl usage examples to work, make sure you have an examples directory locally, either from [a release](https://k8s.io/kubernetes/releases) or [the source](https://k8s.io/kubernetes). +In order for the kubectl usage examples to work, make sure you have an examples directory locally, either from [a release](https://github.com/kubernetes/kubernetes/releases) or [the source](https://github.com/kubernetes/kubernetes). **Table of Contents** @@ -86,7 +86,7 @@ spec: A pod definition is a declaration of a _desired state_. Desired state is a very important concept in the Kubernetes model. Many things present a desired state to the system, and it is Kubernetes' responsibility to make sure that the current state matches the desired state. For example, when you create a Pod, you declare that you want the containers in it to be running. If the containers happen to not be running (e.g. program failure, ...), Kubernetes will continue to (re-)create them for you in order to drive them to the desired state. This process continues until the Pod is deleted. -See the [design document](../../../DESIGN.md) for more details. +See the [design document](../../design/README.md) for more details. #### Pod Management @@ -108,7 +108,7 @@ On most providers, the pod IPs are not externally accessible. The easiest way to Provided the pod IP is accessible, you should be able to access its http endpoint with curl on port 80: ```sh -$ curl http://$(kubectl get pod nginx -o=template -t={{.status.podIP}}) +$ curl http://$(kubectl get pod nginx -o go-template={{.status.podIP}}) ``` Delete the pod by name: @@ -165,16 +165,16 @@ spec: emptyDir: {} ``` -[Download example](pod-redis.yaml) +[Download example](pod-redis.yaml?raw=true) Notes: -- The volume mount name is a reference to a specific empty dir volume. -- The volume mount path is the path to mount the empty dir volume within the container. +- The `volumeMounts` `name` is a reference to a specific `volumes` `name`. +- The `volumeMounts` `mountPath` is the path to mount the volume within the container. ##### Volume Types -- **EmptyDir**: Creates a new directory that will persist across container failures and restarts. +- **EmptyDir**: Creates a new directory that will exist as long as the Pod is running on the node, but it can persist across container failures and restarts. - **HostPath**: Mounts an existing directory on the node's file system (e.g. `/var/logs`). See [volumes](../../../docs/user-guide/volumes.md) for more details. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/walkthrough/k8s201.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/walkthrough/k8s201.md deleted file mode 100644 index 41656188e208..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/walkthrough/k8s201.md +++ /dev/null @@ -1,327 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/walkthrough/k8s201.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Kubernetes 201 - Labels, Replication Controllers, Services and Health Checking - -If you went through [Kubernetes 101](README.md), you learned about kubectl, pods, volumes, and multiple containers. -For Kubernetes 201, we will pick up where 101 left off and cover some slightly more advanced topics in Kubernetes, related to application productionization, deployment and -scaling. - -In order for the kubectl usage examples to work, make sure you have an examples directory locally, either from [a release](https://k8s.io/kubernetes/releases) or [the source](https://k8s.io/kubernetes). - -**Table of Contents** - - -- [Kubernetes 201 - Labels, Replication Controllers, Services and Health Checking](#kubernetes-201---labels-replication-controllers-services-and-health-checking) - - [Labels](#labels) - - [Replication Controllers](#replication-controllers) - - [Replication Controller Management](#replication-controller-management) - - [Services](#services) - - [Service Management](#service-management) - - [Health Checking](#health-checking) - - [Process Health Checking](#process-health-checking) - - [Application Health Checking](#application-health-checking) - - [What's Next?](#whats-next) - - - - -## Labels - -Having already learned about Pods and how to create them, you may be struck by an urge to create many, many pods. Please do! But eventually you will need a system to organize these pods into groups. The system for achieving this in Kubernetes is Labels. Labels are key-value pairs that are attached to each object in Kubernetes. Label selectors can be passed along with a RESTful `list` request to the apiserver to retrieve a list of objects which match that label selector. - -To add a label, add a labels section under metadata in the pod definition: - -```yaml - labels: - app: nginx -``` - -For example, here is the nginx pod definition with labels ([pod-nginx-with-label.yaml](pod-nginx-with-label.yaml)): - - - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: nginx - labels: - app: nginx -spec: - containers: - - name: nginx - image: nginx - ports: - - containerPort: 80 -``` - -[Download example](pod-nginx-with-label.yaml) - - -Create the labeled pod ([pod-nginx-with-label.yaml](pod-nginx-with-label.yaml)): - -```console -$ kubectl create -f docs/user-guide/walkthrough/pod-nginx-with-label.yaml -``` - -List all pods with the label `app=nginx`: - -```console -$ kubectl get pods -l app=nginx -``` - -For more information, see [Labels](../labels.md). -They are a core concept used by two additional Kubernetes building blocks: Replication Controllers and Services. - - -## Replication Controllers - -OK, now you know how to make awesome, multi-container, labeled pods and you want to use them to build an application, you might be tempted to just start building a whole bunch of individual pods, but if you do that, a whole host of operational concerns pop up. For example: how will you scale the number of pods up or down and how will you ensure that all pods are homogenous? - -Replication controllers are the objects to answer these questions. A replication controller combines a template for pod creation (a "cookie-cutter" if you will) and a number of desired replicas, into a single Kubernetes object. The replication controller also contains a label selector that identifies the set of objects managed by the replication controller. The replication controller constantly measures the size of this set relative to the desired size, and takes action by creating or deleting pods. - -For example, here is a replication controller that instantiates two nginx pods ([replication-controller.yaml](replication-controller.yaml)): - - - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: nginx-controller -spec: - replicas: 2 - # selector identifies the set of Pods that this - # replication controller is responsible for managing - selector: - app: nginx - # podTemplate defines the 'cookie cutter' used for creating - # new pods when necessary - template: - metadata: - labels: - # Important: these labels need to match the selector above - # The api server enforces this constraint. - app: nginx - spec: - containers: - - name: nginx - image: nginx - ports: - - containerPort: 80 -``` - -[Download example](replication-controller.yaml) - - -#### Replication Controller Management - -Create an nginx replication controller ([replication-controller.yaml](replication-controller.yaml)): - -```console -$ kubectl create -f docs/user-guide/walkthrough/replication-controller.yaml -``` - -List all replication controllers: - -```console -$ kubectl get rc -``` - -Delete the replication controller by name: - -```console -$ kubectl delete rc nginx-controller -``` - -For more information, see [Replication Controllers](../replication-controller.md). - - -## Services - -Once you have a replicated set of pods, you need an abstraction that enables connectivity between the layers of your application. For example, if you have a replication controller managing your backend jobs, you don't want to have to reconfigure your front-ends whenever you re-scale your backends. Likewise, if the pods in your backends are scheduled (or rescheduled) onto different machines, you can't be required to re-configure your front-ends. In Kubernetes, the service abstraction achieves these goals. A service provides a way to refer to a set of pods (selected by labels) with a single static IP address. It may also provide load balancing, if supported by the provider. - -For example, here is a service that balances across the pods created in the previous nginx replication controller example ([service.yaml](service.yaml)): - - - -```yaml -apiVersion: v1 -kind: Service -metadata: - name: nginx-service -spec: - ports: - - port: 8000 # the port that this service should serve on - # the container on each pod to connect to, can be a name - # (e.g. 'www') or a number (e.g. 80) - targetPort: 80 - protocol: TCP - # just like the selector in the replication controller, - # but this time it identifies the set of pods to load balance - # traffic to. - selector: - app: nginx -``` - -[Download example](service.yaml) - - -#### Service Management - -Create an nginx service ([service.yaml](service.yaml)): - -```console -$ kubectl create -f docs/user-guide/walkthrough/service.yaml -``` - -List all services: - -```console -$ kubectl get services -``` - -On most providers, the service IPs are not externally accessible. The easiest way to test that the service is working is to create a busybox pod and exec commands on it remotely. See the [command execution documentation](../kubectl/kubectl_exec.md) for details. - -Provided the service IP is accessible, you should be able to access its http endpoint with curl on port 80: - -```console -$ export SERVICE_IP=$(kubectl get service nginx-service -o=template -t={{.spec.clusterIP}}) -$ export SERVICE_PORT=$(kubectl get service nginx-service -o=template '-t={{(index .spec.ports 0).port}}') -$ curl http://${SERVICE_IP}:${SERVICE_PORT} -``` - -To delete the service by name: - -```console -$ kubectl delete service nginx-controller -``` - -When created, each service is assigned a unique IP address. This address is tied to the lifespan of the Service, and will not change while the Service is alive. Pods can be configured to talk to the service, and know that communication to the service will be automatically load-balanced out to some pod that is a member of the set identified by the label selector in the Service. - -For more information, see [Services](../services.md). - - -## Health Checking - -When I write code it never crashes, right? Sadly the [Kubernetes issues list](https://k8s.io/kubernetes/issues) indicates otherwise... - -Rather than trying to write bug-free code, a better approach is to use a management system to perform periodic health checking -and repair of your application. That way a system outside of your application itself is responsible for monitoring the -application and taking action to fix it. It's important that the system be outside of the application, since if -your application fails and the health checking agent is part of your application, it may fail as well and you'll never know. -In Kubernetes, the health check monitor is the Kubelet agent. - -#### Process Health Checking - -The simplest form of health-checking is just process level health checking. The Kubelet constantly asks the Docker daemon -if the container process is still running, and if not, the container process is restarted. In all of the Kubernetes examples -you have run so far, this health checking was actually already enabled. It's on for every single container that runs in -Kubernetes. - -#### Application Health Checking - -However, in many cases this low-level health checking is insufficient. Consider, for example, the following code: - -```go -lockOne := sync.Mutex{} -lockTwo := sync.Mutex{} - -go func() { - lockOne.Lock(); - lockTwo.Lock(); - ... -}() - -lockTwo.Lock(); -lockOne.Lock(); -``` - -This is a classic example of a problem in computer science known as ["Deadlock"](https://en.wikipedia.org/wiki/Deadlock). From Docker's perspective your application is -still operating and the process is still running, but from your application's perspective your code is locked up and will never respond correctly. - -To address this problem, Kubernetes supports user implemented application health-checks. These checks are performed by the -Kubelet to ensure that your application is operating correctly for a definition of "correctly" that _you_ provide. - -Currently, there are three types of application health checks that you can choose from: - - * HTTP Health Checks - The Kubelet will call a web hook. If it returns between 200 and 399, it is considered success, failure otherwise. See health check examples [here](../liveness/). - * Container Exec - The Kubelet will execute a command inside your container. If it exits with status 0 it will be considered a success. See health check examples [here](../liveness/). - * TCP Socket - The Kubelet will attempt to open a socket to your container. If it can establish a connection, the container is considered healthy, if it can't it is considered a failure. - -In all cases, if the Kubelet discovers a failure the container is restarted. - -The container health checks are configured in the `livenessProbe` section of your container config. There you can also specify an `initialDelaySeconds` that is a grace period from when the container is started to when health checks are performed, to enable your container to perform any necessary initialization. - -Here is an example config for a pod with an HTTP health check ([pod-with-http-healthcheck.yaml](pod-with-http-healthcheck.yaml)): - - - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: pod-with-healthcheck -spec: - containers: - - name: nginx - image: nginx - # defines the health checking - livenessProbe: - # an http probe - httpGet: - path: /_status/healthz - port: 80 - # length of time to wait for a pod to initialize - # after pod startup, before applying health checking - initialDelaySeconds: 30 - timeoutSeconds: 1 - ports: - - containerPort: 80 -``` - -[Download example](pod-with-http-healthcheck.yaml) - - -For more information about health checking, see [Container Probes](../pod-states.md#container-probes). - - -## What's Next? - -For a complete application see the [guestbook example](../../../examples/guestbook/). - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/walkthrough/k8s201.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/working-with-resources.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/working-with-resources.md deleted file mode 100644 index 437a7654b076..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/working-with-resources.md +++ /dev/null @@ -1,99 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/user-guide/working-with-resources.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Working with Resources - -*This document is aimed at users who have worked through some of the examples, -and who want to learn more about using kubectl to manage resources such -as pods and services. Users who want to access the REST API directly, -and developers who want to extend the Kubernetes API should -refer to the [api conventions](../devel/api-conventions.md) and -the [api document](../api.md).* - -## Resources are Automatically Modified - -When you create a resource such as pod, and then retrieve the created -resource, a number of the fields of the resource are added. -You can see this at work in the following example: - -```console -$ cat > /tmp/original.yaml < /tmp/current.yaml -pods/original -$ wc -l /tmp/original.yaml /tmp/current.yaml - 51 /tmp/current.yaml - 9 /tmp/original.yaml - 60 total -``` - -The resource we posted had only 9 lines, but the one we got back had 51 lines. -If you `diff -u /tmp/original.yaml /tmp/current.yaml`, you can see the fields added to the pod. -The system adds fields in several ways: - - Some fields are added synchronously with creation of the resource and some are set asynchronously. - - For example: `metadata.uid` is set synchronously. (Read more about [metadata](../devel/api-conventions.md#metadata)). - - For example, `status.hostIP` is set only after the pod has been scheduled. This often happens fast, but you may notice pods which do not have this set yet. This is called Late Initialization. (Read mode about [status](../devel/api-conventions.md#spec-and-status) and [late initialization](../devel/api-conventions.md#late-initialization) ). - - Some fields are set to default values. Some defaults vary by cluster and some are fixed for the API at a certain version. (Read more about [defaulting](../devel/api-conventions.md#defaulting)). - - For example, `spec.containers.imagePullPolicy` always defaults to `IfNotPresent` in api v1. - - For example, `spec.containers.resources.limits.cpu` may be defaulted to `100m` on some clusters, to some other value on others, and not defaulted at all on others. -The API will generally not modify fields that you have set; it just sets ones which were unspecified. - -## Finding Documentation on Resource Fields - -You can browse auto-generated API documentation at the [project website](http://kubernetes.io/third_party/swagger-ui/) or directly from your cluster, like this: - - Run `kubectl proxy --api-prefix=/` - - Go to `http://localhost:8001/swagger-ui` in your browser. - - It should say "swagger" at the top-left. - -Once there: - - Click on "v1" and wait for it to expand. - - Search for "pods", "services", "replicationcontrollers" or some other resource. - - Click on that POST row for the matching resource. - - Click on the words "Model". - - You should see a list of all possible resource fields, starting with `v1.pods {...}` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/working-with-resources.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/warning.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/warning.png deleted file mode 100644 index 1d58e4639c312d777414e69fd9d9a72626ade116..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2363 zcmV-B3B>k^P)002P<1^@s6nbld000006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru-vefdrZiK_vhpShg?8#X7*dxG0#VCGC+H|C zly)kp*O zo!oQmI3{o8ku1m8$LF5&_w)SE|2*e$V2qf!^=u26F2K&bK52u2dP2aj1$-vpR{|cN z1k4|>uL$T8ATu5p1w1fT#%PWOuM+8TYyhSWc-sY@7hsMB?=nUkC^!B5CE(9M$fsEn zXm;VBH{0K_p5@tL1yBHv_x_z5h8bSW(tmk9HW=0H;0g(TzoV;W)#E z3wLT5t^p!>d})T)?&&*{;045ie--f2xCk6^s!gD=k>|%RYyMR8GcXZF2Cv|pd?p&Q`^$B=>+!MSP z8c~nbt5u|4`N=1k_4Uer`Z_!5ZfMXA_AGE8kZ{Lq7>8@Qm zvabQ!-SOyI8R?h1fOAR^>g$>M;fEN}X#cg-r%%(>)rIT2G-PNk`T6JcG&Pa>^i$of z?{eXS7>^t#;2%n^F->`O@7{i15<2LeRyYI@2dfoLG0i|L*0OdWm>VQgY+LR>? z&Ye3a9mnwnD;A5%^XJcJwNGr^m?3R}|AEvTa-THNzmN5T1cR z0K>>$ha%gz=USP5DXq)_k6BZbJqXjpaU9?Fp->3Z%pRs$TTAKw{kg_* zU`*>Q0pA3k^mi!(N=gVn^UUBuXuxtDXAoFGx}Vb0bie-AB4EXs1j|e6tpa@GDJ3OS zjvd2@M0`Un;&UA!8jTVN1bmZ(Q;r@bC6!XuBF&xlm;oz;L>~iIs?sl^M;^gyZuafN zwry%_Ykl9VtE(dv@;`sI=Fi7|_+g#0UkyB3EV3_V82(;)lc`gQ9#B(=Wm!y{=9}iC ztgOt}v-)#hZ@q;Xixo7k5eLg#0sjCfXB1wyj=(+lsP|l&)zGr6L91a_2+x>7_}OQ5 zL$n0^&K)CRxDZ&X1j2Q3Hf+!j!Zekf6^TTA2|jb-aMrKKPrLa63`z$U>Jsymu%bCdKRP)IZC!~*KwBvyeQIMHnL!4?CR$#r2-I$Mv1)e zLhjUuVPM;K!C(P6Teo6{Lb@j30_F@SXKxMzD1e`<+DTx_sZ;soi421h#W`U#8qEtV zfbz~xop%BJEQ4o9Gz|9u_bN$!?OFoUr{~?DN|dTR&UZ4^)r8ls)it?a!0r(XL+@Lu z0+gdND=H}2u>;KfyI08r%d&Vvu~WEDP5i+Oz`kIQGhwx^Q%XJ%!Y%4%M>^pbYr7aN?VeDKUnaRyT(jf)eirZ@cJN?9d@yt7Ou_@s4IRg!v9YnB z{$lUELrUM|Ki+(b3sy!_?|Y;x@cc=7^=g6-6jrt#kH;x5FV9}x%FC&%t1GBKtGOBH zsi(9KDB!z8**BVbdK4nP^6gSeg-8Tv(-daLch{$9#{%jvqf>l>V>1|GpHVkczib-aPH$ zfc3JD94{|kT$G6<5(&9z(IQ{4mMmE!uUxrOl>1y>xG)#lZ!L)6MY{5(QQIHj!W|rpWfg9R(51rGI{8bEVi9EaYEMA)MNowTU#qno;+FfdnFGZl)|!fV11ky zX9;-O(^dXqF?TLgKllJN$5X?R4!d{nCYem)I1U{h9h8=q7GHbaxIxdndGwt)p-c3> zH=O-0VRP*TN_3w zge;O+98ELAVVss0l7|ng0E+`Jy71$h_!#-te@Y-YYZhF;t}DhEN3JEovbgclN4Yl0 zuABZB3Rz+JH@sgfOj?%x)rIDMoh8!MFS90b@wNMfSMXwrG;cjY5leF>n1z6^2?&@T z$xoTYL~A8L&~)Jo;E$7dXzfofT)Vj;yIG*Q-CG<}llWkg{sHJufH%pM4j$3Fq{|B@ h&C64`o?aKg{{cOX)t87U(dPgF002ovPDHLkV1ma>c2@uZ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/whatisk8s.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/whatisk8s.md deleted file mode 100644 index e7c00bba21aa..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/whatisk8s.md +++ /dev/null @@ -1,83 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/docs/whatisk8s.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# What is Kubernetes? - -Kubernetes is an open-source platform for automating deployment, scaling, and operations of application containers across clusters of hosts. - -With Kubernetes, you are able to quickly and efficiently respond to customer demand: - - - Scale your applications on the fly. - - Seamlessly roll out new features. - - Optimize use of your hardware by using only the resources you need. - -#### Kubernetes is: - -* **lean**: lightweight, simple, accessible -* **portable**: public, private, hybrid, multi-cloud -* **extensible**: modular, pluggable, hookable, composable -* **self-healing**: auto-placement, auto-restart, auto-replication - -The Kubernetes project was started by Google in 2014. Kubernetes builds upon a [decade and a half of experience that Google has with running production workloads at scale](https://research.google.com/pubs/pub43438.html), combined with best-of-breed ideas and practices from the community. - -##### Ready to [Get Started](getting-started-guides/README.md)? - -
      - -Looking for reasons why you should be using [containers](http://aucouranton.com/2014/06/13/linux-containers-parallels-lxc-openvz-docker-and-more/)? - -Here are some key points: - -* **Application-centric management**: - Raises the level of abstraction from running an OS on virtual hardware to running an application on an OS using logical resources. This provides the simplicity of PaaS with the flexibility of IaaS and enables you to run much more than just [12-factor apps](http://12factor.net/). -* **Dev and Ops separation of concerns**: - Provides separatation of build and deployment; therefore, decoupling applications from infrastructure. -* **Agile application creation and deployment**: - Increased ease and efficiency of container image creation compared to VM image use. -* **Continuous development, integration, and deployment**: - Provides for reliable and frequent container image build and deployment with quick and easy rollbacks (due to image immutability). -* **Loosely coupled, distributed, elastic, liberated [micro-services](http://martinfowler.com/articles/microservices.html)**: - Applications are broken into smaller, independent pieces and can be deployed and managed dynamically -- not a fat monolithic stack running on one big single-purpose machine. -* **Environmental consistency across development, testing, and production**: - Runs the same on a laptop as it does in the cloud. -* **Cloud and OS distribution portability**: - Runs on Ubuntu, RHEL, on-prem, or Google Container Engine, which makes sense for all environments: build, test, and production. -* **Resource isolation**: - Predictable application performance. -* **Resource utilization**: - High efficiency and density. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/whatisk8s.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/celery-controller.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/celery-controller.yaml index 31a4f52a3085..ac2224b467a3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/celery-controller.yaml +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/celery-controller.yaml @@ -2,12 +2,10 @@ apiVersion: v1 kind: ReplicationController metadata: labels: - name: celery + component: celery name: celery-controller spec: replicas: 1 - selector: - component: celery template: metadata: labels: diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/flower-controller.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/flower-controller.yaml index d7dc60915ef0..069350854699 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/flower-controller.yaml +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/flower-controller.yaml @@ -2,12 +2,10 @@ apiVersion: v1 kind: ReplicationController metadata: labels: - name: flower + component: flower name: flower-controller spec: replicas: 1 - selector: - component: flower template: metadata: labels: diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/flower-service.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/flower-service.yaml index 1fdf1ee906ef..9ae819d21c6e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/flower-service.yaml +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/flower-service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: - name: flower + component: flower name: flower-service spec: ports: diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/rabbitmq-controller.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/rabbitmq-controller.yaml index 2d68e34de6ed..5baa32c43937 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/rabbitmq-controller.yaml +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/rabbitmq-controller.yaml @@ -2,12 +2,10 @@ apiVersion: v1 kind: ReplicationController metadata: labels: - name: rabbitmq + component: rabbitmq name: rabbitmq-controller spec: replicas: 1 - selector: - component: rabbitmq template: metadata: labels: diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/rabbitmq-service.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/rabbitmq-service.yaml index ec29b32ce9ae..75b7cc4650b9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/rabbitmq-service.yaml +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/celery-rabbitmq/rabbitmq-service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: - name: rabbitmq + component: rabbitmq name: rabbitmq-service spec: ports: diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/README.md deleted file mode 100644 index b4903f1ee071..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/README.md +++ /dev/null @@ -1,68 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/examples/cephfs/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# How to Use it? - -Install Ceph on the Kubernetes host. For example, on Fedora 21 - - # yum -y install ceph - -If you don't have a Ceph cluster, you can set up a [containerized Ceph cluster](https://github.com/rootfs/ceph_docker) - -Then get the keyring from the Ceph cluster and copy it to */etc/ceph/keyring*. - -Once you have installed Ceph and new Kubernetes, you can create a pod based on my examples [cephfs.json](cephfs.json) and [cephfs-with-secret.json](cephfs-with-secret.json). In the pod JSON, you need to provide the following information. - -- *monitors*: Array of Ceph monitors. -- *user*: The RADOS user name. If not provided, default *admin* is used. -- *secretFile*: The path to the keyring file. If not provided, default */etc/ceph/user.secret* is used. -- *secretRef*: Reference to Ceph authentication secrets. If provided, *secret* overrides *secretFile*. -- *readOnly*: Whether the filesystem is used as readOnly. - - -Here are the commands: - -```console - # create a secret if you want to use Ceph secret instead of secret file - # cluster/kubectl.sh create -f examples/cephfs/secret/ceph-secret.yaml - - # cluster/kubectl.sh create -f examples/cephfs/v1beta3/cephfs.json - # cluster/kubectl.sh get pods -``` - - If you ssh to that machine, you can run `docker ps` to see the actual pod and `docker inspect` to see the volumes used by the container. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/cephfs/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs-with-secret.json b/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs-with-secret.json deleted file mode 100644 index bdaefff30179..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs-with-secret.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "apiVersion": "v1", - "id": "cephfs2", - "kind": "Pod", - "metadata": { - "name": "cephfs2" - }, - "spec": { - "containers": [ - { - "name": "cephfs-rw", - "image": "kubernetes/pause", - "volumeMounts": [ - { - "mountPath": "/mnt/cephfs", - "name": "cephfs" - } - ] - } - ], - "volumes": [ - { - "name": "cephfs", - "cephfs": { - "monitors": [ - "10.16.154.78:6789", - "10.16.154.82:6789", - "10.16.154.83:6789" - ], - "user": "admin", - "secretRef": { - "name": "ceph-secret" - }, - "readOnly": true - } - } - ] - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs-with-secret.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs-with-secret.yaml new file mode 100644 index 000000000000..c3d7a02cb09f --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs-with-secret.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Pod +metadata: + name: cephfs2 +spec: + containers: + - name: cephfs-rw + image: kubernetes/pause + volumeMounts: + - mountPath: "/mnt/cephfs" + name: cephfs + volumes: + - name: cephfs + cephfs: + monitors: + - 10.16.154.78:6789 + - 10.16.154.82:6789 + - 10.16.154.83:6789 + user: admin + secretRef: + name: ceph-secret + readOnly: true diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs.json b/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs.json deleted file mode 100644 index 38a73a7661a0..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "apiVersion": "v1", - "id": "cephfs", - "kind": "Pod", - "metadata": { - "name": "cephfs" - }, - "spec": { - "containers": [ - { - "name": "cephfs-rw", - "image": "kubernetes/pause", - "volumeMounts": [ - { - "mountPath": "/mnt/cephfs", - "name": "cephfs" - } - ] - } - ], - "volumes": [ - { - "name": "cephfs", - "cephfs": { - "monitors": [ - "10.16.154.78:6789", - "10.16.154.82:6789", - "10.16.154.83:6789" - ], - "user": "admin", - "scretFile": "/etc/ceph/admin.secret", - "readOnly": true - } - } - ] - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs.yaml new file mode 100644 index 000000000000..135979e29fe7 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/cephfs.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Pod +metadata: + name: cephfs +spec: + containers: + - name: cephfs-rw + image: kubernetes/pause + volumeMounts: + - mountPath: "/mnt/cephfs" + name: cephfs + volumes: + - name: cephfs + cephfs: + monitors: + - 10.16.154.78:6789 + - 10.16.154.82:6789 + - 10.16.154.83:6789 + user: admin + secretFile: "/etc/ceph/admin.secret" + readOnly: true diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/secret/ceph-secret.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/secret/ceph-secret.yaml deleted file mode 100644 index e29a5535ab49..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/cephfs/secret/ceph-secret.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: ceph-secret -data: - key: QVFCMTZWMVZvRjVtRXhBQTVrQ1FzN2JCajhWVUxSdzI2Qzg0SEE9PQ== diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/README.md deleted file mode 100644 index c15c3f763cb0..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/README.md +++ /dev/null @@ -1,196 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/examples/elasticsearch/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Elasticsearch for Kubernetes - -Kubernetes makes it trivial for anyone to easily build and scale [Elasticsearch](http://www.elasticsearch.org/) clusters. Here, you'll find how to do so. -Current Elasticsearch version is `1.7.1`. - -[A more robust example that follows Elasticsearch best-practices of separating nodes concern is also available](production_cluster/README.md). - -WARNING Current pod descriptors use an `emptyDir` for storing data in each data node container. This is meant to be for the sake of simplicity and [should be adapted according to your storage needs](../../docs/design/persistent-storage.md). - -## Docker image - -This example uses [this pre-built image](https://github.com/pires/docker-elasticsearch-kubernetes) will not be supported. Feel free to fork to fit your own needs, but mind yourself that you will need to change Kubernetes descriptors accordingly. - -## Deploy - -Let's kickstart our cluster with 1 instance of Elasticsearch. - -``` -kubectl create -f examples/elasticsearch/service-account.yaml -kubectl create -f examples/elasticsearch/es-svc.yaml -kubectl create -f examples/elasticsearch/es-rc.yaml -``` - -Let's see if it worked: - -``` -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -es-kfymw 1/1 Running 0 7m -kube-dns-p3v1u 3/3 Running 0 19m -``` - -``` -$ kubectl logs es-kfymw -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -[2015-08-30 10:01:31,946][INFO ][node ] [Hammerhead] version[1.7.1], pid[7], build[b88f43f/2015-07-29T09:54:16Z] -[2015-08-30 10:01:31,946][INFO ][node ] [Hammerhead] initializing ... -[2015-08-30 10:01:32,110][INFO ][plugins ] [Hammerhead] loaded [cloud-kubernetes], sites [] -[2015-08-30 10:01:32,153][INFO ][env ] [Hammerhead] using [1] data paths, mounts [[/data (/dev/sda9)]], net usable_space [14.4gb], net total_space [15.5gb], types [ext4] -[2015-08-30 10:01:37,188][INFO ][node ] [Hammerhead] initialized -[2015-08-30 10:01:37,189][INFO ][node ] [Hammerhead] starting ... -[2015-08-30 10:01:37,499][INFO ][transport ] [Hammerhead] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/10.244.48.2:9300]} -[2015-08-30 10:01:37,550][INFO ][discovery ] [Hammerhead] myesdb/n2-6uu_UT3W5XNrjyqBPiA -[2015-08-30 10:01:43,966][INFO ][cluster.service ] [Hammerhead] new_master [Hammerhead][n2-6uu_UT3W5XNrjyqBPiA][es-kfymw][inet[/10.244.48.2:9300]]{master=true}, reason: zen-disco-join (elected_as_master) -[2015-08-30 10:01:44,010][INFO ][http ] [Hammerhead] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/10.244.48.2:9200]} -[2015-08-30 10:01:44,011][INFO ][node ] [Hammerhead] started -[2015-08-30 10:01:44,042][INFO ][gateway ] [Hammerhead] recovered [0] indices into cluster_state -``` - -So we have a 1-node Elasticsearch cluster ready to handle some work. - -## Scale - -Scaling is as easy as: - -``` -kubectl scale --replicas=3 rc es -``` - -Did it work? - -``` -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -es-78e0s 1/1 Running 0 8m -es-kfymw 1/1 Running 0 17m -es-rjmer 1/1 Running 0 8m -kube-dns-p3v1u 3/3 Running 0 30m -``` - -Let's take a look at logs: - -``` -$ kubectl logs es-kfymw -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -[2015-08-30 10:01:31,946][INFO ][node ] [Hammerhead] version[1.7.1], pid[7], build[b88f43f/2015-07-29T09:54:16Z] -[2015-08-30 10:01:31,946][INFO ][node ] [Hammerhead] initializing ... -[2015-08-30 10:01:32,110][INFO ][plugins ] [Hammerhead] loaded [cloud-kubernetes], sites [] -[2015-08-30 10:01:32,153][INFO ][env ] [Hammerhead] using [1] data paths, mounts [[/data (/dev/sda9)]], net usable_space [14.4gb], net total_space [15.5gb], types [ext4] -[2015-08-30 10:01:37,188][INFO ][node ] [Hammerhead] initialized -[2015-08-30 10:01:37,189][INFO ][node ] [Hammerhead] starting ... -[2015-08-30 10:01:37,499][INFO ][transport ] [Hammerhead] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/10.244.48.2:9300]} -[2015-08-30 10:01:37,550][INFO ][discovery ] [Hammerhead] myesdb/n2-6uu_UT3W5XNrjyqBPiA -[2015-08-30 10:01:43,966][INFO ][cluster.service ] [Hammerhead] new_master [Hammerhead][n2-6uu_UT3W5XNrjyqBPiA][es-kfymw][inet[/10.244.48.2:9300]]{master=true}, reason: zen-disco-join (elected_as_master) -[2015-08-30 10:01:44,010][INFO ][http ] [Hammerhead] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/10.244.48.2:9200]} -[2015-08-30 10:01:44,011][INFO ][node ] [Hammerhead] started -[2015-08-30 10:01:44,042][INFO ][gateway ] [Hammerhead] recovered [0] indices into cluster_state -[2015-08-30 10:08:02,517][INFO ][cluster.service ] [Hammerhead] added {[Tenpin][2gv5MiwhRiOSsrTOF3DhuA][es-78e0s][inet[/10.244.54.4:9300]]{master=true},}, reason: zen-disco-receive(join from node[[Tenpin][2gv5MiwhRiOSsrTOF3DhuA][es-78e0s][inet[/10.244.54.4:9300]]{master=true}]) -[2015-08-30 10:10:10,645][INFO ][cluster.service ] [Hammerhead] added {[Evilhawk][ziTq2PzYRJys43rNL2tbyg][es-rjmer][inet[/10.244.33.3:9300]]{master=true},}, reason: zen-disco-receive(join from node[[Evilhawk][ziTq2PzYRJys43rNL2tbyg][es-rjmer][inet[/10.244.33.3:9300]]{master=true}]) -``` - -So we have a 3-node Elasticsearch cluster ready to handle more work. - -## Access the service - -*Don't forget* that services in Kubernetes are only acessible from containers in the cluster. For different behavior you should [configure the creation of an external load-balancer](http://kubernetes.io/v1.0/docs/user-guide/services.html#type-loadbalancer). While it's supported within this example service descriptor, its usage is out of scope of this document, for now. - -``` -$ kubectl get service elasticsearch -NAME LABELS SELECTOR IP(S) PORT(S) -elasticsearch component=elasticsearch component=elasticsearch 10.100.108.94 9200/TCP - 9300/TCP -``` - -From any host on your cluster (that's running `kube-proxy`), run: - -``` -$ curl 10.100.108.94:9200 -``` - -You should see something similar to the following: - - -```json -{ - "status" : 200, - "name" : "Hammerhead", - "cluster_name" : "myesdb", - "version" : { - "number" : "1.7.1", - "build_hash" : "b88f43fc40b0bcd7f173a1f9ee2e97816de80b19", - "build_timestamp" : "2015-07-29T09:54:16Z", - "build_snapshot" : false, - "lucene_version" : "4.10.4" - }, - "tagline" : "You Know, for Search" -} -``` - -Or if you want to check cluster information: - - -``` -curl 10.100.108.94:9200/_cluster/health?pretty -``` - -You should see something similar to the following: - -```json -{ - "cluster_name" : "myesdb", - "status" : "green", - "timed_out" : false, - "number_of_nodes" : 3, - "number_of_data_nodes" : 3, - "active_primary_shards" : 0, - "active_shards" : 0, - "relocating_shards" : 0, - "initializing_shards" : 0, - "unassigned_shards" : 0, - "delayed_unassigned_shards" : 0, - "number_of_pending_tasks" : 0, - "number_of_in_flight_fetch" : 0 -} -``` - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/elasticsearch/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/README.md deleted file mode 100644 index 11abd839f774..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/README.md +++ /dev/null @@ -1,222 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/examples/elasticsearch/production_cluster/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Elasticsearch for Kubernetes - -Kubernetes makes it trivial for anyone to easily build and scale [Elasticsearch](http://www.elasticsearch.org/) clusters. Here, you'll find how to do so. -Current Elasticsearch version is `1.7.1`. - -Before we start, one needs to know that Elasticsearch best-practices recommend to separate nodes in three roles: -* `Master` nodes - intended for clustering management only, no data, no HTTP API -* `Client` nodes - intended for client usage, no data, with HTTP API -* `Data` nodes - intended for storing and indexing your data, no HTTP API - -This is enforced throughout this document. - -WARNING Current pod descriptors use an `emptyDir` for storing data in each data node container. This is meant to be for the sake of simplicity and [should be adapted according to your storage needs](../../../docs/design/persistent-storage.md). - -## Docker image - -This example uses [this pre-built image](https://github.com/pires/docker-elasticsearch-kubernetes) will not be supported. Feel free to fork to fit your own needs, but mind yourself that you will need to change Kubernetes descriptors accordingly. - -## Deploy - -``` -kubectl create -f examples/elasticsearch/production_cluster/service-account.yaml -kubectl create -f examples/elasticsearch/production_cluster/es-discovery-svc.yaml -kubectl create -f examples/elasticsearch/production_cluster/es-svc.yaml -kubectl create -f examples/elasticsearch/production_cluster/es-master-rc.yaml -``` - -Wait until `es-master` is provisioned, and - -``` -kubectl create -f examples/elasticsearch/production_cluster/es-client-rc.yaml -``` - -Wait until `es-client` is provisioned, and - -``` -kubectl create -f examples/elasticsearch/production_cluster/es-data-rc.yaml -``` - -Wait until `es-data` is provisioned. - -Now, I leave up to you how to validate the cluster, but a first step is to wait for containers to be in ```RUNNING``` state and check the Elasticsearch master logs: - -``` -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -es-client-2ep9o 1/1 Running 0 2m -es-data-r9tgv 1/1 Running 0 1m -es-master-vxl6c 1/1 Running 0 6m -``` - -``` -$ kubectl logs es-master-vxl6c -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -[2015-08-21 10:58:51,324][INFO ][node ] [Arc] version[1.7.1], pid[8], build[b88f43f/2015-07-29T09:54:16Z] -[2015-08-21 10:58:51,328][INFO ][node ] [Arc] initializing ... -[2015-08-21 10:58:51,542][INFO ][plugins ] [Arc] loaded [cloud-kubernetes], sites [] -[2015-08-21 10:58:51,624][INFO ][env ] [Arc] using [1] data paths, mounts [[/data (/dev/sda9)]], net usable_space [14.4gb], net total_space [15.5gb], types [ext4] -[2015-08-21 10:58:57,439][INFO ][node ] [Arc] initialized -[2015-08-21 10:58:57,439][INFO ][node ] [Arc] starting ... -[2015-08-21 10:58:57,782][INFO ][transport ] [Arc] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/10.244.15.2:9300]} -[2015-08-21 10:58:57,847][INFO ][discovery ] [Arc] myesdb/-x16XFUzTCC8xYqWoeEOYQ -[2015-08-21 10:59:05,167][INFO ][cluster.service ] [Arc] new_master [Arc][-x16XFUzTCC8xYqWoeEOYQ][es-master-vxl6c][inet[/10.244.15.2:9300]]{data=false, master=true}, reason: zen-disco-join (elected_as_master) -[2015-08-21 10:59:05,202][INFO ][node ] [Arc] started -[2015-08-21 10:59:05,238][INFO ][gateway ] [Arc] recovered [0] indices into cluster_state -[2015-08-21 11:02:28,797][INFO ][cluster.service ] [Arc] added {[Gideon][4EfhWSqaTqikbK4tI7bODA][es-data-r9tgv][inet[/10.244.59.4:9300]]{master=false},}, reason: zen-disco-receive(join from node[[Gideon][4EfhWSqaTqikbK4tI7bODA][es-data-r9tgv][inet[/10.244.59.4:9300]]{master=false}]) -[2015-08-21 11:03:16,822][INFO ][cluster.service ] [Arc] added {[Venomm][tFYxwgqGSpOejHLG4umRqg][es-client-2ep9o][inet[/10.244.53.2:9300]]{data=false, master=false},}, reason: zen-disco-receive(join from node[[Venomm][tFYxwgqGSpOejHLG4umRqg][es-client-2ep9o][inet[/10.244.53.2:9300]]{data=false, master=false}]) -``` - -As you can assert, the cluster is up and running. Easy, wasn't it? - -## Scale - -Scaling each type of node to handle your cluster is as easy as: - -``` -kubectl scale --replicas=3 rc es-master -kubectl scale --replicas=2 rc es-client -kubectl scale --replicas=2 rc es-data -``` - -Did it work? - -``` -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -es-client-2ep9o 1/1 Running 0 4m -es-client-ye5s1 1/1 Running 0 50s -es-data-8az22 1/1 Running 0 47s -es-data-r9tgv 1/1 Running 0 3m -es-master-57h7k 1/1 Running 0 52s -es-master-kuwse 1/1 Running 0 52s -es-master-vxl6c 1/1 Running 0 8m -``` - -Let's take another look of the Elasticsearch master logs: - -``` -$ kubectl logs es-master-vxl6c -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -log4j:WARN No such property [maxBackupIndex] in org.apache.log4j.DailyRollingFileAppender. -[2015-08-21 10:58:51,324][INFO ][node ] [Arc] version[1.7.1], pid[8], build[b88f43f/2015-07-29T09:54:16Z] -[2015-08-21 10:58:51,328][INFO ][node ] [Arc] initializing ... -[2015-08-21 10:58:51,542][INFO ][plugins ] [Arc] loaded [cloud-kubernetes], sites [] -[2015-08-21 10:58:51,624][INFO ][env ] [Arc] using [1] data paths, mounts [[/data (/dev/sda9)]], net usable_space [14.4gb], net total_space [15.5gb], types [ext4] -[2015-08-21 10:58:57,439][INFO ][node ] [Arc] initialized -[2015-08-21 10:58:57,439][INFO ][node ] [Arc] starting ... -[2015-08-21 10:58:57,782][INFO ][transport ] [Arc] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/10.244.15.2:9300]} -[2015-08-21 10:58:57,847][INFO ][discovery ] [Arc] myesdb/-x16XFUzTCC8xYqWoeEOYQ -[2015-08-21 10:59:05,167][INFO ][cluster.service ] [Arc] new_master [Arc][-x16XFUzTCC8xYqWoeEOYQ][es-master-vxl6c][inet[/10.244.15.2:9300]]{data=false, master=true}, reason: zen-disco-join (elected_as_master) -[2015-08-21 10:59:05,202][INFO ][node ] [Arc] started -[2015-08-21 10:59:05,238][INFO ][gateway ] [Arc] recovered [0] indices into cluster_state -[2015-08-21 11:02:28,797][INFO ][cluster.service ] [Arc] added {[Gideon][4EfhWSqaTqikbK4tI7bODA][es-data-r9tgv][inet[/10.244.59.4:9300]]{master=false},}, reason: zen-disco-receive(join from node[[Gideon][4EfhWSqaTqikbK4tI7bODA][es-data-r9tgv][inet[/10.244.59.4:9300]]{master=false}]) -[2015-08-21 11:03:16,822][INFO ][cluster.service ] [Arc] added {[Venomm][tFYxwgqGSpOejHLG4umRqg][es-client-2ep9o][inet[/10.244.53.2:9300]]{data=false, master=false},}, reason: zen-disco-receive(join from node[[Venomm][tFYxwgqGSpOejHLG4umRqg][es-client-2ep9o][inet[/10.244.53.2:9300]]{data=false, master=false}]) -[2015-08-21 11:04:40,781][INFO ][cluster.service ] [Arc] added {[Erik Josten][QUJlahfLTi-MsxzM6_Da0g][es-master-kuwse][inet[/10.244.59.5:9300]]{data=false, master=true},}, reason: zen-disco-receive(join from node[[Erik Josten][QUJlahfLTi-MsxzM6_Da0g][es-master-kuwse][inet[/10.244.59.5:9300]]{data=false, master=true}]) -[2015-08-21 11:04:41,076][INFO ][cluster.service ] [Arc] added {[Power Princess][V4qnR-6jQOS5ovXQsPgo7g][es-master-57h7k][inet[/10.244.53.3:9300]]{data=false, master=true},}, reason: zen-disco-receive(join from node[[Power Princess][V4qnR-6jQOS5ovXQsPgo7g][es-master-57h7k][inet[/10.244.53.3:9300]]{data=false, master=true}]) -[2015-08-21 11:04:53,966][INFO ][cluster.service ] [Arc] added {[Cagliostro][Wpfx5fkBRiG2qCEWd8laaQ][es-client-ye5s1][inet[/10.244.15.3:9300]]{data=false, master=false},}, reason: zen-disco-receive(join from node[[Cagliostro][Wpfx5fkBRiG2qCEWd8laaQ][es-client-ye5s1][inet[/10.244.15.3:9300]]{data=false, master=false}]) -[2015-08-21 11:04:56,803][INFO ][cluster.service ] [Arc] added {[Thog][vkdEtX3ESfWmhXXf-Wi0_Q][es-data-8az22][inet[/10.244.15.4:9300]]{master=false},}, reason: zen-disco-receive(join from node[[Thog][vkdEtX3ESfWmhXXf-Wi0_Q][es-data-8az22][inet[/10.244.15.4:9300]]{master=false}]) -``` - -## Access the service - -*Don't forget* that services in Kubernetes are only acessible from containers in the cluster. For different behavior you should [configure the creation of an external load-balancer](http://kubernetes.io/v1.0/docs/user-guide/services.html#type-loadbalancer). While it's supported within this example service descriptor, its usage is out of scope of this document, for now. - -``` -$ kubectl get service elasticsearch -NAME LABELS SELECTOR IP(S) PORT(S) -elasticsearch component=elasticsearch,role=client component=elasticsearch,role=client 10.100.134.2 9200/TCP -``` - -From any host on your cluster (that's running `kube-proxy`), run: - -``` -curl http://10.100.134.2:9200 -``` - -You should see something similar to the following: - - -```json -{ - "status" : 200, - "name" : "Cagliostro", - "cluster_name" : "myesdb", - "version" : { - "number" : "1.7.1", - "build_hash" : "b88f43fc40b0bcd7f173a1f9ee2e97816de80b19", - "build_timestamp" : "2015-07-29T09:54:16Z", - "build_snapshot" : false, - "lucene_version" : "4.10.4" - }, - "tagline" : "You Know, for Search" -} -``` - -Or if you want to check cluster information: - - -``` -curl http://10.100.134.2:9200/_cluster/health?pretty -``` - -You should see something similar to the following: - -```json -{ - "cluster_name" : "myesdb", - "status" : "green", - "timed_out" : false, - "number_of_nodes" : 7, - "number_of_data_nodes" : 2, - "active_primary_shards" : 0, - "active_shards" : 0, - "relocating_shards" : 0, - "initializing_shards" : 0, - "unassigned_shards" : 0, - "delayed_unassigned_shards" : 0, - "number_of_pending_tasks" : 0, - "number_of_in_flight_fetch" : 0 -} -``` - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/elasticsearch/production_cluster/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-client-rc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-client-rc.yaml deleted file mode 100644 index 227dce16a1be..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-client-rc.yaml +++ /dev/null @@ -1,55 +0,0 @@ -apiVersion: v1 -kind: ReplicationController -metadata: - name: es-client - labels: - component: elasticsearch - role: client -spec: - replicas: 1 - selector: - component: elasticsearch - role: client - template: - metadata: - labels: - component: elasticsearch - role: client - spec: - serviceAccount: elasticsearch - containers: - - name: es-client - securityContext: - capabilities: - add: - - IPC_LOCK - image: quay.io/pires/docker-elasticsearch-kubernetes:1.7.1-4 - env: - - name: KUBERNETES_CA_CERTIFICATE_FILE - value: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - - name: NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: "CLUSTER_NAME" - value: "myesdb" - - name: NODE_MASTER - value: "false" - - name: NODE_DATA - value: "false" - - name: HTTP_ENABLE - value: "true" - ports: - - containerPort: 9200 - name: http - protocol: TCP - - containerPort: 9300 - name: transport - protocol: TCP - volumeMounts: - - mountPath: /data - name: storage - volumes: - - name: storage - source: - emptyDir: {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-data-rc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-data-rc.yaml deleted file mode 100644 index 7cd099ead6bb..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-data-rc.yaml +++ /dev/null @@ -1,50 +0,0 @@ -apiVersion: v1 -kind: ReplicationController -metadata: - name: es-data - labels: - component: elasticsearch - role: data -spec: - replicas: 1 - selector: - component: elasticsearch - role: data - template: - metadata: - labels: - component: elasticsearch - role: data - spec: - serviceAccount: elasticsearch - containers: - - name: es-data - securityContext: - capabilities: - add: - - IPC_LOCK - image: quay.io/pires/docker-elasticsearch-kubernetes:1.7.1-4 - env: - - name: KUBERNETES_CA_CERTIFICATE_FILE - value: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - - name: NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: "CLUSTER_NAME" - value: "myesdb" - - name: NODE_MASTER - value: "false" - - name: HTTP_ENABLE - value: "false" - ports: - - containerPort: 9300 - name: transport - protocol: TCP - volumeMounts: - - mountPath: /data - name: storage - volumes: - - name: storage - source: - emptyDir: {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-discovery-svc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-discovery-svc.yaml deleted file mode 100644 index cfdc5daa2557..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-discovery-svc.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: elasticsearch-discovery - labels: - component: elasticsearch - role: master -spec: - selector: - component: elasticsearch - role: master - ports: - - name: transport - port: 9300 - protocol: TCP diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-master-rc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-master-rc.yaml deleted file mode 100644 index dfa474aa7606..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-master-rc.yaml +++ /dev/null @@ -1,52 +0,0 @@ -apiVersion: v1 -kind: ReplicationController -metadata: - name: es-master - labels: - component: elasticsearch - role: master -spec: - replicas: 1 - selector: - component: elasticsearch - role: master - template: - metadata: - labels: - component: elasticsearch - role: master - spec: - serviceAccount: elasticsearch - containers: - - name: es-master - securityContext: - capabilities: - add: - - IPC_LOCK - image: quay.io/pires/docker-elasticsearch-kubernetes:1.7.1-4 - env: - - name: KUBERNETES_CA_CERTIFICATE_FILE - value: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - - name: NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: "CLUSTER_NAME" - value: "myesdb" - - name: NODE_MASTER - value: "true" - - name: NODE_DATA - value: "false" - - name: HTTP_ENABLE - value: "false" - ports: - - containerPort: 9300 - name: transport - protocol: TCP - volumeMounts: - - mountPath: /data - name: storage - volumes: - - name: storage - source: - emptyDir: {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-svc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-svc.yaml deleted file mode 100644 index 03bc4efda799..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/es-svc.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: elasticsearch - labels: - component: elasticsearch - role: client -spec: - type: LoadBalancer - selector: - component: elasticsearch - role: client - ports: - - name: http - port: 9200 - protocol: TCP diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/service-account.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/service-account.yaml deleted file mode 100644 index 7b7b80b20097..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/elasticsearch/production_cluster/service-account.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: elasticsearch diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/examples_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/examples/examples_test.go index 087c0780221e..221ea71ff8d6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/examples_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/examples_test.go @@ -27,8 +27,10 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/validation" + "k8s.io/kubernetes/pkg/apis/extensions" + expValidation "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/capabilities" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/yaml" @@ -99,6 +101,21 @@ func validateObject(obj runtime.Object) (errors []error) { t.Namespace = api.NamespaceDefault } errors = validation.ValidateResourceQuota(t) + case *extensions.Deployment: + if t.Namespace == "" { + t.Namespace = api.NamespaceDefault + } + errors = expValidation.ValidateDeployment(t) + case *extensions.Job: + if t.Namespace == "" { + t.Namespace = api.NamespaceDefault + } + errors = expValidation.ValidateJob(t) + case *extensions.DaemonSet: + if t.Namespace == "" { + t.Namespace = api.NamespaceDefault + } + errors = expValidation.ValidateDaemonSet(t) default: return []error{fmt.Errorf("no validation defined for %#v", obj)} } @@ -204,6 +221,10 @@ func TestExampleObjectSchemas(t *testing.T) { "multi-pod": nil, "pod": &api.Pod{}, "replication": &api.ReplicationController{}, + "job": &extensions.Job{}, + }, + "../docs/admin": { + "daemon": &extensions.DaemonSet{}, }, "../examples": { "scheduler-policy-config": &schedulerapi.Policy{}, @@ -297,9 +318,8 @@ func TestExampleObjectSchemas(t *testing.T) { "secret": nil, }, "../examples/phabricator": { - "authenticator-controller": &api.ReplicationController{}, - "phabricator-controller": &api.ReplicationController{}, - "phabricator-service": &api.Service{}, + "phabricator-controller": &api.ReplicationController{}, + "phabricator-service": &api.Service{}, }, "../examples/redis": { "redis-controller": &api.ReplicationController{}, @@ -308,7 +328,7 @@ func TestExampleObjectSchemas(t *testing.T) { "redis-sentinel-controller": &api.ReplicationController{}, "redis-sentinel-service": &api.Service{}, }, - "../docs/user-guide/resourcequota": { + "../docs/admin/resourcequota": { "namespace": &api.Namespace{}, "limits": &api.LimitRange{}, "quota": &api.ResourceQuota{}, @@ -340,6 +360,16 @@ func TestExampleObjectSchemas(t *testing.T) { "cephfs": &api.Pod{}, "cephfs-with-secret": &api.Pod{}, }, + "../examples/fibre_channel": { + "fc": &api.Pod{}, + }, + "../examples/experimental": { + "deployment": &extensions.Deployment{}, + }, + "../examples/javaweb-tomcat-sidecar": { + "javaweb": &api.Pod{}, + "javaweb-2": &api.Pod{}, + }, } capabilities.SetForTests(capabilities.Capabilities{ @@ -366,7 +396,11 @@ func TestExampleObjectSchemas(t *testing.T) { } //TODO: Add validate method for &schedulerapi.Policy } else { - if err := latest.Codec.DecodeInto(data, expectedType); err != nil { + codec, err := testapi.GetCodecForObject(expectedType) + if err != nil { + t.Errorf("Could not get codec for %s: %s", expectedType, err) + } + if err := codec.DecodeInto(data, expectedType); err != nil { t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data)) return } @@ -452,14 +486,14 @@ func TestReadme(t *testing.T) { if err != nil { t.Errorf("%s could not be converted to JSON: %v\n%s", path, err, string(content)) } - if err := latest.Codec.DecodeInto(json, expectedType); err != nil { + if err := testapi.Default.Codec().DecodeInto(json, expectedType); err != nil { t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(content)) continue } if errors := validateObject(expectedType); len(errors) > 0 { t.Errorf("%s did not validate correctly: %v", path, errors) } - _, err = latest.Codec.Encode(expectedType) + _, err = testapi.Default.Codec().Encode(expectedType) if err != nil { t.Errorf("Could not encode object: %v", err) continue diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/experimental/deployment.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/experimental/deployment.yaml new file mode 100644 index 000000000000..340103836ac9 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/experimental/deployment.yaml @@ -0,0 +1,20 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + name: nginx-deployment +spec: + replicas: 3 + selector: + name: nginx + template: + metadata: + labels: + name: nginx + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/explorer/pod.json b/Godeps/_workspace/src/k8s.io/kubernetes/examples/explorer/pod.json deleted file mode 100644 index 25cb803eeb8b..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/explorer/pod.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "explorer" - }, - "spec": { - "containers": [ - { - "name": "explorer", - "image": "gcr.io/google_containers/explorer:1.0", - "args": [ - "-port=8080" - ], - "ports": [ - { - "containerPort": 8080, - "protocol": "TCP" - } - ], - "volumeMounts": [ - { - "name": "test-volume", - "mountPath": "/mount/test-volume" - } - ] - } - ], - "volumes": [ - { - "name": "test-volume", - "emptyDir": {} - } - ] - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/explorer/pod.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/explorer/pod.yaml new file mode 100644 index 000000000000..2c26c3e17444 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/explorer/pod.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Pod +metadata: + name: explorer +spec: + containers: + - name: explorer + image: gcr.io/google_containers/explorer:1.0 + args: ["-port=8080"] + ports: + - containerPort: 8080 + protocol: TCP + volumeMounts: + - mountPath: "/mount/test-volume" + name: test-volume + volumes: + - name: test-volume + emptyDir: {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/fibre_channel/fc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/fibre_channel/fc.yaml new file mode 100644 index 000000000000..ac28bee4a3e0 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/fibre_channel/fc.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Pod +metadata: + name: fc +spec: + containers: + - image: kubernetes/pause + name: fc + volumeMounts: + - name: fc-vol + mountPath: /mnt/fc + volumes: + - name: fc-vol + fc: + targetWWNs: ['500a0982991b8dc5', '500a0982891b8dc5'] + lun: 2 + fsType: ext4 + readOnly: true diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/glusterfs/glusterfs-endpoints.json b/Godeps/_workspace/src/k8s.io/kubernetes/examples/glusterfs/glusterfs-endpoints.json index 751715e68965..740ce4258611 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/glusterfs/glusterfs-endpoints.json +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/glusterfs/glusterfs-endpoints.json @@ -8,7 +8,7 @@ { "addresses": [ { - "IP": "10.240.106.152" + "ip": "10.240.106.152" } ], "ports": [ @@ -20,7 +20,7 @@ { "addresses": [ { - "IP": "10.240.79.157" + "ip": "10.240.79.157" } ], "ports": [ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/README.md deleted file mode 100644 index 1271fba619cc..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/README.md +++ /dev/null @@ -1,609 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/examples/guestbook/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - - -## Guestbook Example - -This example shows how to build a simple, multi-tier web application using Kubernetes and [Docker](https://www.docker.com/). - -**Table of Contents** - - - [Step Zero: Prerequisites](#step-zero-prerequisites) - - [Step One: Start up the redis master](#step-one-start-up-the-redis-master) - - [Optional Interlude](#optional-interlude) - - [Step Two: Fire up the redis master service](#step-two-fire-up-the-redis-master-service) - - [Finding a service](#finding-a-service) - - [Step Three: Fire up the replicated slave pods](#step-three-fire-up-the-replicated-slave-pods) - - [Step Four: Create the redis slave service](#step-four-create-the-redis-slave-service) - - [Step Five: Create the frontend replicated pods](#step-five-create-the-frontend-replicated-pods) - - [Step Six: Set up the guestbook frontend service.](#step-six-set-up-the-guestbook-frontend-service) - - [Using 'type: LoadBalancer' for the frontend service (cloud-provider-specific)](#using-type-loadbalancer-for-the-frontend-service-cloud-provider-specific) - - [Create the Frontend Service](#create-the-frontend-service) - - [Accessing the guestbook site externally](#accessing-the-guestbook-site-externally) - - [Google Compute Engine External Load Balancer Specifics](#gce-external-load-balancer-specifics) - - [Step Seven: Cleanup](#step-seven-cleanup) - - [Troubleshooting](#troubleshooting) - -The example consists of: - -- A web frontend -- A [redis](http://redis.io/) master (for storage), and a replicated set of redis 'slaves'. - -The web front end interacts with the redis master via javascript redis API calls. - -**Note**: If you are running this example on a [Google Container Engine](https://cloud.google.com/container-engine/) installation, see [this Container Engine guestbook walkthrough](https://cloud.google.com/container-engine/docs/tutorials/guestbook) instead. The basic concepts are the same, but the walkthrough is tailored to a Container Engine setup. - -### Step Zero: Prerequisites - -This example requires a running Kubernetes cluster. See the [Getting Started guides](../../docs/getting-started-guides/) for how to get started. As noted above, if you have a Google Container Engine cluster set up, go [here](https://cloud.google.com/container-engine/docs/tutorials/guestbook) instead. - -### Step One: Start up the redis master - -**Note**: The redis master in this example is *not* highly available. Making it highly available would be an interesting, but intricate exercise— redis doesn't actually support multi-master deployments at this point in time, so high availability would be a somewhat tricky thing to implement, and might involve periodic serialization to disk, and so on. - -To start the redis master, use the file `examples/guestbook/redis-master-controller.yaml`, which describes a single [pod](../../docs/user-guide/pods.md) running a redis key-value server in a container. - -Although we have a single instance of our redis master, we are using a [replication controller](../../docs/user-guide/replication-controller.md) to enforce that exactly one pod keeps running. E.g., if the node were to go down, the replication controller will ensure that the redis master gets restarted on a healthy node. (In our simplified example, this could result in data loss.) - - - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: redis-master - labels: - name: redis-master -spec: - replicas: 1 - selector: - name: redis-master - template: - metadata: - labels: - name: redis-master - spec: - containers: - - name: master - image: redis - ports: - - containerPort: 6379 -``` - -[Download example](redis-master-controller.yaml) - - -Change to the `/examples/guestbook` directory if you're not already there. Create the redis master pod in your Kubernetes cluster by running: - -```console -$ kubectl create -f examples/guestbook/redis-master-controller.yaml -replicationcontrollers/redis-master -``` - -The `replicationcontrollers/redis-master` line is the expected response to this operation. -You can see the replication controllers for your cluster by running: - -```console -$ kubectl get rc -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -redis-master master redis name=redis-master 1 -``` - -Then, you can list the pods in the cluster, to verify that the master is running: - -```console -$ kubectl get pods -``` - -You'll see all pods in the cluster, including the redis master pod, and the status of each pod. -The name of the redis master will look similar to that in the following list: - -```console -NAME READY STATUS RESTARTS AGE -... -redis-master-dz33o 1/1 Running 0 2h -``` - -(Note that an initial `docker pull` to grab a container image may take a few minutes, depending on network conditions. A pod will be reported as `Pending` while its image is being downloaded.) - -#### Optional Interlude - -You can get information about a pod, including the machine that it is running on, via `kubectl describe pods/`. E.g., for the redis master, you should see something like the following (your pod name will be different): - -```console -$ kubectl describe pods/redis-master-dz33o -... -Name: redis-master-dz33o -Image(s): redis -Node: kubernetes-minion-krxw/10.240.67.201 -Labels: name=redis-master -Status: Running -Replication Controllers: redis-master (1/1 replicas created) -Containers: - master: - Image: redis - State: Running - Started: Fri, 12 Jun 2015 12:53:46 -0700 - Ready: True - Restart Count: 0 -Conditions: - Type Status - Ready True -No events. -``` - -The 'Node' is the name of the machine, e.g. `kubernetes-minion-krxw` in the example above. - -If you want to view the container logs for a given pod, you can run: - -```console -$ kubectl logs -``` - -These logs will usually give you enough information to troubleshoot. - -However, if you should want to SSH to the listed host machine, you can inspect various logs there directly as well. For example, with Google Compute Engine, using `gcloud`, you can SSH like this: - -```console -me@workstation$ gcloud compute ssh kubernetes-minion-krxw -``` - -Then, you can look at the docker containers on the remote machine. You should see something like this (the specifics of the IDs will be different): - -```console -me@kubernetes-minion-krxw:~$ sudo docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -... -0ffef9649265 redis:latest "redis-server /etc/r" About a minute ago Up About a minute k8s_redis-master.767aef46_redis-master-controller-gb50a.default.api_4530d7b3-ae5d-11e4-bf77-42010af0d719_579ee964 -``` - -If you want to see the logs for a given container, you can run: - -```console -$ docker logs -``` - -### Step Two: Fire up the redis master service - -A Kubernetes [service](../../docs/user-guide/services.md) is a named load balancer that proxies traffic to one or more containers. This is done using the [labels](../../docs/user-guide/labels.md) metadata that we defined in the `redis-master` pod above. As mentioned, we have only one redis master, but we nevertheless want to create a service for it. Why? Because it gives us a deterministic way to route to the single master using an elastic IP. - -Services find the pods to load balance based on the pods' labels. -The pod that you created in [Step One](#step-one-start-up-the-redis-master) has the label `name=redis-master`. -The selector field of the service description determines which pods will receive the traffic sent to the service, and the `port` and `targetPort` information defines what port the service proxy will run at. - -The file `examples/guestbook/redis-master-service.yaml` defines the redis master service: - - - -```yaml -apiVersion: v1 -kind: Service -metadata: - name: redis-master - labels: - name: redis-master -spec: - ports: - # the port that this service should serve on - - port: 6379 - targetPort: 6379 - selector: - name: redis-master -``` - -[Download example](redis-master-service.yaml) - - -Create the service by running: - -```console -$ kubectl create -f examples/guestbook/redis-master-service.yaml -services/redis-master -``` - -Then check the list of services, which should include the redis-master: - -```console -$ kubectl get services -NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE -redis-master 10.0.136.3 6379/TCP app=redis,role=master 1h -... -``` - -This will cause all pods to see the redis master apparently running on :6379. A service can map an incoming port to any `targetPort` in the backend pod. Once created, the service proxy on each node is configured to set up a proxy on the specified port (in this case port 6379). - -`targetPort` will default to `port` if it is omitted in the configuration. For simplicity's sake, we omit it in the following configurations. - -The traffic flow from slaves to masters can be described in two steps, like so: - - - A *redis slave* will connect to "port" on the *redis master service* - - Traffic will be forwarded from the service "port" (on the service node) to the *targetPort* on the pod that the service listens to. - -#### Finding a service - -Kubernetes supports two primary modes of finding a service— environment variables and DNS. - -The services in a Kubernetes cluster are discoverable inside other containers [via environment variables](../../docs/user-guide/services.md#environment-variables). - -An alternative is to use the [cluster's DNS service](../../docs/user-guide/services.md#dns), if it has been enabled for the cluster. This lets all pods do name resolution of services automatically, based on the service name. -We'll use the DNS service for this example. E.g., you can see the service name, `redis-master`, accessed as a `host` value in the PHP script in [Step 5](#step-five-create-the-frontend-replicated-pods). - -**Note**: **If your cluster does not have the DNS service enabled, then this example will not work out of the box.** You will need to edit `examples/guestbook/php-redis/index.php` to use environment variables for service discovery instead, then rebuild the container image from the `Dockerfile` in that directory. (However, this is unlikely to be necessary. You can check for the DNS service in the list of the clusters' services.) - - -### Step Three: Fire up the replicated slave pods - -Now that the redis master is running, we can start up its 'read slaves'. - -We'll define these as replicated pods as well, though this time— unlike for the redis master— we'll define the number of replicas to be 2. -In Kubernetes, a replication controller is responsible for managing multiple instances of a replicated pod. The replication controller will automatically launch new pods if the number of replicas falls below the specified number. -(This particular replicated pod is a great one to test this with -- you can try killing the docker processes for your pods directly, then watch them come back online on a new node shortly thereafter.) - -To create the replicated pod, use the file `examples/guestbook/redis-slave-controller.yaml`, which looks like this: - - - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: redis-slave - labels: - name: redis-slave -spec: - replicas: 2 - selector: - name: redis-slave - template: - metadata: - labels: - name: redis-slave - spec: - containers: - - name: worker - image: kubernetes/redis-slave:v2 - ports: - - containerPort: 6379 -``` - -[Download example](redis-slave-controller.yaml) - - -and create the replication controller by running: - -```console -$ kubectl create -f examples/guestbook/redis-slave-controller.yaml -replicationcontrollers/redis-slave - -$ kubectl get rc -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -redis-master master redis name=redis-master 1 -redis-slave slave kubernetes/redis-slave:v2 name=redis-slave 2 -``` - -Once the replication controller is up, you can list the pods in the cluster, to verify that the master and slaves are running. You should see a list that includes something like the following: - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -... -redis-master-dz33o 1/1 Running 0 2h -redis-slave-35mer 1/1 Running 0 2h -redis-slave-iqkhy 1/1 Running 0 2h -``` - -You should see a single redis master pod and two redis slave pods. As mentioned above, you can get more information about any pod with: `kubectl describe pods/`. - -### Step Four: Create the redis slave service - -Just like the master, we want to have a service to proxy connections to the redis slaves. In this case, in addition to discovery, the slave service will provide transparent load balancing to web app clients. - -The service specification for the slaves is in `examples/guestbook/redis-slave-service.yaml`: - - - -```yaml -apiVersion: v1 -kind: Service -metadata: - name: redis-slave - labels: - name: redis-slave -spec: - ports: - # the port that this service should serve on - - port: 6379 - selector: - name: redis-slave -``` - -[Download example](redis-slave-service.yaml) - - -This time the selector for the service is `name=redis-slave`, because that identifies the pods running redis slaves. It may also be helpful to set labels on your service itself as we've done here to make it easy to locate them with the `kubectl get services -l "label=value"` command. - -Now that you have created the service specification, create it in your cluster by running: - -```console -$ kubectl create -f examples/guestbook/redis-slave-service.yaml -services/redis-slave - -$ kubectl get services -NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE -redis-master 10.0.136.3 6379/TCP app=redis,role=master 1h -redis-slave 10.0.21.92 6379/TCP app-redis,role=slave 1h -``` - -### Step Five: Create the frontend replicated pods - - - -A frontend pod is a simple PHP server that is configured to talk to either the slave or master services, depending on whether the client request is a read or a write. It exposes a simple AJAX interface, and serves an Angular-based UX. -Again we'll create a set of replicated frontend pods instantiated by a replication controller— this time, with three replicas. - -The pod is described in the file `examples/guestbook/frontend-controller.yaml`: - - - -```yaml -apiVersion: v1 -kind: ReplicationController -metadata: - name: frontend - labels: - name: frontend -spec: - replicas: 3 - selector: - name: frontend - template: - metadata: - labels: - name: frontend - spec: - containers: - - name: php-redis - image: kubernetes/example-guestbook-php-redis:v2 - ports: - - containerPort: 80 -``` - -[Download example](frontend-controller.yaml) - - -Using this file, you can turn up your frontend with: - -```console -$ kubectl create -f examples/guestbook/frontend-controller.yaml -replicationcontrollers/frontend -``` - -Then, list all your replication controllers: - -```console -$ kubectl get rc -CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS -frontend php-redis kubernetes/example-guestbook-php-redis:v2 name=frontend 3 -redis-master master redis name=redis-master 1 -redis-slave slave kubernetes/redis-slave:v2 name=redis-slave 2 -``` - -Once it's up (again, it may take up to thirty seconds to create the pods) you can list the pods in the cluster, to verify that the master, slaves and frontends are all running. You should see a list that includes something like the following: - -```console -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -... -frontend-4o11g 1/1 Running 0 2h -frontend-u9aq6 1/1 Running 0 2h -frontend-yga1l 1/1 Running 0 2h -... -redis-master-dz33o 1/1 Running 0 2h -redis-slave-35mer 1/1 Running 0 2h -redis-slave-iqkhy 1/1 Running 0 2h -``` - -You should see a single redis master pod, two redis slaves, and three frontend pods. - -The code for the PHP server that the frontends are running looks like this: - -```php - 'tcp', - 'host' => 'redis-master', - 'port' => 6379, - ]); - - $client->set($_GET['key'], $_GET['value']); - print('{"message": "Updated"}'); - } else { - $client = new Predis\Client([ - 'scheme' => 'tcp', - 'host' => 'redis-slave', - 'port' => 6379, - ]); - - $value = $client->get($_GET['key']); - print('{"data": "' . $value . '"}'); - } -} else { - phpinfo(); -} ?> -``` - -Note the use of the `redis-master` and `redis-slave` host names-- we're finding those services via the Kubernetes cluster's DNS service, as discussed above. All the frontend replicas will write to the load-balancing redis-slaves service, which can be highly replicated as well. - - -### Step Six: Set up the guestbook frontend service. - -As with the other pods, we now want to create a service to group your frontend pods. -The service is described in the file `frontend-service.yaml`: - - - -```yaml -apiVersion: v1 -kind: Service -metadata: - name: frontend - labels: - name: frontend -spec: - # if your cluster supports it, uncomment the following to automatically create - # an external load-balanced IP for the frontend service. - # type: LoadBalancer - ports: - # the port that this service should serve on - - port: 80 - selector: - name: frontend -``` - -[Download example](frontend-service.yaml) - - -#### Using 'type: LoadBalancer' for the frontend service (cloud-provider-specific) - -For supported cloud providers, such as Google Compute Engine or Google Container Engine, you can specify to use an external load balancer -in the service `spec`, to expose the service onto an external load balancer IP. -To do this, uncomment the `type: LoadBalancer` line in the `frontend-service.yaml` file before you start the service. - -[See the section below](#accessing-the-guestbook-site-externally) on accessing the guestbook site externally for more details. - - -#### Create the Frontend Service #### - -Create the service like this: - -```console -$ kubectl create -f examples/guestbook/frontend-service.yaml -services/frontend -``` - -Then, list all your services again: - -```console -$ kubectl get services -NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE -frontend 10.0.93.211 80/TCP name=frontend 1h -redis-master 10.0.136.3 6379/TCP app=redis,role=master 1h -redis-slave 10.0.21.92 6379/TCP app-redis,role=slave 1h -``` - - -#### Accessing the guestbook site externally - - - -You'll want to set up your guestbook service so that it can be accessed from outside of the internal Kubernetes network. Above, we introduced one way to do that, using the `type: LoadBalancer` spec. - -More generally, Kubernetes supports two ways of exposing a service onto an external IP address: `NodePort`s and `LoadBalancer`s , as described [here](../../docs/user-guide/services.md#external-services). - -If the `LoadBalancer` specification is used, it can take a short period for an external IP to show up in `kubectl get services` output, but you should shortly see it listed as well, e.g. like this: - -```console -$ kubectl get services -NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE -frontend 10.0.93.211 130.211.188.51 80/TCP name=frontend 1h -redis-master 10.0.136.3 6379/TCP app=redis,role=master 1h -redis-slave 10.0.21.92 6379/TCP app-redis,role=slave 1h -``` - -Once you've exposed the service to an external IP, visit the IP to see your guestbook in action. E.g., `http://130.211.188.51:80` in the example above. - -You should see a web page that looks something like this (without the messages). Try adding some entries to it! - - - -If you are more advanced in the ops arena, you can also manually get the service IP from looking at the output of `kubectl get pods,services`, and modify your firewall using standard tools and services (firewalld, iptables, selinux) which you are already familiar with. - -##### Google Compute Engine External Load Balancer Specifics - -In Google Compute Engine, `kubectl` automatically creates forwarding rule for services with `LoadBalancer`. - -You can list the forwarding rules like this. The forwarding rule also indicates the external IP. - -```console -$ gcloud compute forwarding-rules list -NAME REGION IP_ADDRESS IP_PROTOCOL TARGET -frontend us-central1 130.211.188.51 TCP us-central1/targetPools/frontend -``` - -In Google Compute Engine, you also may need to open the firewall for port 80 using the [console][cloud-console] or the `gcloud` tool. The following command will allow traffic from any source to instances tagged `kubernetes-minion` (replace with your tags as appropriate): - -```console -$ gcloud compute firewall-rules create --allow=tcp:80 --target-tags=kubernetes-minion kubernetes-minion-80 -``` - -For Google Compute Engine details about limiting traffic to specific sources, see the [Google Compute Engine firewall documentation][gce-firewall-docs]. - -[cloud-console]: https://console.developer.google.com -[gce-firewall-docs]: https://cloud.google.com/compute/docs/networking#firewalls - -### Step Seven: Cleanup - -If you are in a live kubernetes cluster, you can just kill the pods by stopping the replication controllers and deleting the services. Using labels to select the resources to stop or delete is an easy way to do this in one command. - -```console -kubectl stop rc -l "name in (redis-master, redis-slave, frontend)" -kubectl delete service -l "name in (redis-master, redis-slave, frontend)" -``` - -To completely tear down a Kubernetes cluster, if you ran this from source, you can use: - -```console -$ /cluster/kube-down.sh -``` - -### Troubleshooting - -If you are having trouble bringing up your guestbook app, double check that your external IP is properly defined for your frontend service, and that the firewall for your cluster nodes is open to port 80. - -Then, see the [troubleshooting documentation](../../docs/troubleshooting.md) for a further list of common issues and how you can diagnose them. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/guestbook/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/Dockerfile b/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/Dockerfile deleted file mode 100644 index 3cf7c2cfa20f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM brendanburns/php - -ADD index.php /var/www/index.php -ADD controllers.js /var/www/controllers.js -ADD index.html /var/www/index.html - -CMD /run.sh diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/controllers.js b/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/controllers.js deleted file mode 100644 index 1ea5bdce18f1..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/controllers.js +++ /dev/null @@ -1,29 +0,0 @@ -var redisApp = angular.module('redis', ['ui.bootstrap']); - -/** - * Constructor - */ -function RedisController() {} - -RedisController.prototype.onRedis = function() { - this.scope_.messages.push(this.scope_.msg); - this.scope_.msg = ""; - var value = this.scope_.messages.join(); - this.http_.get("/index.php?cmd=set&key=messages&value=" + value) - .success(angular.bind(this, function(data) { - this.scope_.redisResponse = "Updated."; - })); -}; - -redisApp.controller('RedisCtrl', function ($scope, $http, $location) { - $scope.controller = new RedisController(); - $scope.controller.scope_ = $scope; - $scope.controller.location_ = $location; - $scope.controller.http_ = $http; - - $scope.controller.http_.get("/index.php?cmd=get&key=messages") - .success(function(data) { - console.log(data); - $scope.messages = data.data.split(","); - }); -}); diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/index.html b/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/index.html deleted file mode 100644 index 81328b4fcd82..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - Guestbook - - - - - - -
      -

      Guestbook

      -
      -
      -
      - -
      -
      -
      -
      - {{msg}} -
      -
      -
      - - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/index.php b/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/index.php deleted file mode 100644 index 18bff077579f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/php-redis/index.php +++ /dev/null @@ -1,33 +0,0 @@ - 'tcp', - 'host' => 'redis-master', - 'port' => 6379, - ]); - - $client->set($_GET['key'], $_GET['value']); - print('{"message": "Updated"}'); - } else { - $client = new Predis\Client([ - 'scheme' => 'tcp', - 'host' => 'redis-slave', - 'port' => 6379, - ]); - - $value = $client->get($_GET['key']); - print('{"data": "' . $value . '"}'); - } -} else { - phpinfo(); -} ?> diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/redis-slave/Dockerfile b/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/redis-slave/Dockerfile deleted file mode 100644 index 8167438bbeac..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/redis-slave/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM redis - -ADD run.sh /run.sh - -RUN chmod a+x /run.sh - -CMD /run.sh diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/redis-slave/run.sh b/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/redis-slave/run.sh deleted file mode 100755 index bf48f27c0158..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/guestbook/redis-slave/run.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# Copyright 2014 The Kubernetes Authors All rights reserved. -# -# 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. - -redis-server --slaveof redis-master 6379 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/iscsi/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/examples/iscsi/README.md index 357dff020909..bcabfe4f4594 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/iscsi/README.md +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/iscsi/README.md @@ -39,8 +39,7 @@ If you use Fedora 21 on Kubernetes node, then first install iSCSI initiator on t # yum -y install iscsi-initiator-utils - -then edit */etc/iscsi/initiatorname.iscsi* and */etc/iscsi/iscsid.conf* to match your iSCSI target configuration. +then edit */etc/iscsi/iscsid.conf* to match your iSCSI target configuration. I mostly followed these [instructions](http://www.server-world.info/en/note?os=Fedora_21&p=iscsi) to setup iSCSI target. and these [instructions](http://www.server-world.info/en/note?os=Fedora_21&p=iscsi&f=2) to setup iSCSI initiator. @@ -50,7 +49,7 @@ GCE does not provide preconfigured Fedora 21 image, so I set up the iSCSI target ## Step 2. Creating the pod with iSCSI persistent storage -Once you have installed iSCSI initiator and new Kubernetes, you can create a pod based on my example *iscsi.json*. In the pod JSON, you need to provide *targetPortal* (the iSCSI target's **IP** address and *port* if not the default port 3260), target's *iqn*, *lun*, and the type of the filesystem that has been created on the lun, and *readOnly* boolean. +Once you have installed iSCSI initiator and new Kubernetes, you can create a pod based on the example *iscsi.json*. In the pod JSON, you need to provide *targetPortal* (the iSCSI target's **IP** address and *port* if not the default port 3260), target's *iqn*, *lun*, and the type of the filesystem that has been created on the lun, and *readOnly* boolean. No initiator information is required. **Note:** If you have followed the instructions in the links above you may have partitioned the device, the iSCSI volume plugin does not @@ -77,30 +76,33 @@ NAME READY STATUS RESTARTS AGE iscsipd 2/2 RUNNING 0 2m ``` -On the Kubernetes node, I got these in mount output +On the Kubernetes node, verify the mount output ```console # mount |grep kub -/dev/sdb on /var/lib/kubelet/plugins/kubernetes.io/iscsi/iscsi/10.240.205.13:3260-iqn-iqn.2014-12.world.server:storage.target1-lun-0 type ext4 (ro,relatime,data=ordered) -/dev/sdb on /var/lib/kubelet/pods/e36158ce-f8d8-11e4-9ae7-42010af01964/volumes/kubernetes.io~iscsi/iscsipd-ro type ext4 (ro,relatime,data=ordered) -/dev/sdc on /var/lib/kubelet/plugins/kubernetes.io/iscsi/iscsi/10.240.205.13:3260-iqn-iqn.2014-12.world.server:storage.target1-lun-1 type xfs (rw,relatime,attr2,inode64,noquota) -/dev/sdc on /var/lib/kubelet/pods/e36158ce-f8d8-11e4-9ae7-42010af01964/volumes/kubernetes.io~iscsi/iscsipd-rw type xfs (rw,relatime,attr2,inode64,noquota) +/dev/sdb on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.15:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-0 type ext4 (ro,relatime,data=ordered) +/dev/sdb on /var/lib/kubelet/pods/f527ca5b-6d87-11e5-aa7e-080027ff6387/volumes/kubernetes.io~iscsi/iscsipd-ro type ext4 (ro,relatime,data=ordered) +/dev/sdc on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.15:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-1 type ext4 (rw,relatime,data=ordered) +/dev/sdc on /var/lib/kubelet/pods/f527ca5b-6d87-11e5-aa7e-080027ff6387/volumes/kubernetes.io~iscsi/iscsipd-rw type ext4 (rw,relatime,data=ordered) ``` If you ssh to that machine, you can run `docker ps` to see the actual pod. ```console # docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -cc051196e7af kubernetes/pause:latest "/pause" About an hour ago Up About an hour k8s_iscsipd-rw.ff2d2e9f_iscsipd_default_e36158ce-f8d8-11e4-9ae7-42010af01964_26f3a457 -8aa981443cf4 kubernetes/pause:latest "/pause" About an hour ago Up About an hour k8s_iscsipd-ro.d7752e8f_iscsipd_default_e36158ce-f8d8-11e4-9ae7-42010af01964_4939633d +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +f855336407f4 kubernetes/pause "/pause" 6 minutes ago Up 6 minutes k8s_iscsipd-ro.d130ec3e_iscsipd_default_f527ca5b-6d87-11e5-aa7e-080027ff6387_5409a4cb +3b8a772515d2 kubernetes/pause "/pause" 6 minutes ago Up 6 minutes k8s_iscsipd-rw.ed58ec4e_iscsipd_default_f527ca5b-6d87-11e5-aa7e-080027ff6387_d25592c5 ``` -Run *docker inspect* and I found the Containers mounted the host directory into the their */mnt/iscsipd* directory. +Run *docker inspect* and verify the container mounted the host directory into the their */mnt/iscsipd* directory. ```console -# docker inspect --format '{{index .Volumes "/mnt/iscsipd"}}' cc051196e7af -/var/lib/kubelet/pods/75e0af2b-f8e8-11e4-9ae7-42010af01964/volumes/kubernetes.io~iscsi/iscsipd-rw +# docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/mnt/iscsipd" }}{{ .Source }}{{ end }}{{ end }}' f855336407f4 +/var/lib/kubelet/pods/f527ca5b-6d87-11e5-aa7e-080027ff6387/volumes/kubernetes.io~iscsi/iscsipd-ro + +# docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/mnt/iscsipd" }}{{ .Source }}{{ end }}{{ end }}' 3b8a772515d2 +/var/lib/kubelet/pods/f527ca5b-6d87-11e5-aa7e-080027ff6387/volumes/kubernetes.io~iscsi/iscsipd-rw ``` diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/iscsi/iscsi.json b/Godeps/_workspace/src/k8s.io/kubernetes/examples/iscsi/iscsi.json index 5b8d0bd8f379..3c597147f15c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/iscsi/iscsi.json +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/iscsi/iscsi.json @@ -31,8 +31,8 @@ { "name": "iscsipd-ro", "iscsi": { - "targetPortal": "127.0.0.1:3260", - "iqn": "iqn.2014-12.world.server:www.server.world", + "targetPortal": "10.0.2.15:3260", + "iqn": "iqn.2001-04.com.example:storage.kube.sys1.xyz", "lun": 0, "fsType": "ext4", "readOnly": true @@ -41,9 +41,9 @@ { "name": "iscsipd-rw", "iscsi": { - "targetPortal": "127.0.0.1:3260", - "iqn": "iqn.2014-12.world.server:www.server.world", - "lun": 0, + "targetPortal": "10.0.2.15:3260", + "iqn": "iqn.2001-04.com.example:storage.kube.sys1.xyz", + "lun": 1, "fsType": "ext4", "readOnly": false } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/javaweb-tomcat-sidecar/javaweb-2.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/javaweb-tomcat-sidecar/javaweb-2.yaml new file mode 100644 index 000000000000..b34d5ab6e26e --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/javaweb-tomcat-sidecar/javaweb-2.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Pod +metadata: + name: javaweb-2 +spec: + containers: + - image: resouer/sample:v2 + name: war + lifecycle: + postStart: + exec: + command: + - "cp" + - "/sample.war" + - "/app" + volumeMounts: + - mountPath: /app + name: app-volume + - image: resouer/mytomcat:7.0 + name: tomcat + command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"] + volumeMounts: + - mountPath: /root/apache-tomcat-7.0.42-v2/webapps + name: app-volume + ports: + - containerPort: 8080 + hostPort: 8001 + volumes: + - name: app-volume + emptyDir: {} + diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/javaweb-tomcat-sidecar/javaweb.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/javaweb-tomcat-sidecar/javaweb.yaml new file mode 100644 index 000000000000..d77f6a727e62 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/javaweb-tomcat-sidecar/javaweb.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Pod +metadata: + name: javaweb +spec: + containers: + - image: resouer/sample:v1 + name: war + volumeMounts: + - mountPath: /app + name: app-volume + - image: resouer/mytomcat:7.0 + name: tomcat + command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"] + volumeMounts: + - mountPath: /root/apache-tomcat-7.0.42-v2/webapps + name: app-volume + ports: + - containerPort: 8080 + hostPort: 8001 + volumes: + - name: app-volume + emptyDir: {} + diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/metadata/README.md b/Godeps/_workspace/src/k8s.io/kubernetes/examples/metadata/README.md deleted file mode 100644 index 3dcd8d9b4c1b..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/metadata/README.md +++ /dev/null @@ -1,102 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

      PLEASE NOTE: This document applies to the HEAD of the source tree

      - -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - -The latest 1.0.x release of this document can be found -[here](http://releases.k8s.io/release-1.0/examples/metadata/README.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Metadata volume plugin - -Following this example, you will create a pod with a metadata volume. -A metadata volume is a k8s volume plugin with the ability to save pod [metadata](../../docs/devel/api-conventions.md#metadata) field to a plain text file. - -Supported metadata fields: - -1. `metadata.annotations` -2. `metadata.namespace` -3. `metadata.name` -4. `metadata.labels` - -### Step Zero: Prerequisites - -This example assumes you have a Kubernetes cluster installed and running, and the ```kubectl``` command line tool somewhere in your path. Please see the [gettingstarted](../../docs/getting-started-guides/) for installation instructions for your platform. - -### Step One: Create the pod - -Use the `examples/metadata/metadata-volume.yaml` file to create a Pod with a  volume plugin which stores pod labels and pod annotations to `/etc/labels` and  `/etc/annotations` respectively. - -```shell -$ kubectl create -f examples/metadata/metadata-volume.yaml -``` - -### Step Two: Examine pod/container output - -The pod displays (every 5 seconds) the content of the dump files which can be executed via the usual `kubectl log` command - -```shell -$ kubectl logs kubernetes-metadata-volume-example -cluster=test-cluster1 -rack=rack-22 -zone=us-est-coast -build=two -builder=john-doe -kubernetes.io/config.source=api -``` - -### Internals - -In pod's `/etc` directory one may find the metadata created by the plugin (system files elided): - -```shell -$ kubectl exec kubernetes-metadata-volume-example -i -t -- sh -/ # ls -laR /etc -/etc: -total 16 -drwxrwxrwt 3 0 0 180 Jun 2 21:01 . -drwxr-xr-x 1 0 0 4096 Jun 2 21:01 .. -drwx------ 2 0 0 80 Jun 2 21:01 .2015_06_02_21_01_10575342153 -lrwxrwxrwx 1 0 0 29 Jun 2 21:01 .current -> .2015_06_02_21_01_10575342153 -lrwxrwxrwx 1 0 0 20 Jun 2 21:01 annotations -> .current/annotations -lrwxrwxrwx 1 0 0 15 Jun 2 21:01 labels -> .current/labels - -/etc/.2015_06_02_21_01_10575342153: -total 8 -drwx------ 2 0 0 80 Jun 2 21:01 . -drwxrwxrwt 3 0 0 180 Jun 2 21:01 .. --rw-r--r-- 1 0 0 59 Jun 2 21:01 annotations --rw-r--r-- 1 0 0 53 Jun 2 21:01 labels -/ # -``` - -Metadata is stored in a temporary directory (`.2015_06_02_21_01_10575342153` in the example above) which is symlinked to by `.current`. Symlinks for annotations and labels in `/etc` point to files containing the actual metadata through the `.current` indirection.  This structure allows for dynamic atomic refresh of the metadata: updates are written to a new temporary directory, and the `.current` symlink is updated atomically using `rename(2)`. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/Godeps/_workspace/src/k8s.io/kubernetes/examples/metadata/README.md?pixel)]() - diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/metadata/metadata-volume.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/examples/metadata/metadata-volume.yaml deleted file mode 100644 index 145e8b3a4a51..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/metadata/metadata-volume.yaml +++ /dev/null @@ -1,31 +0,0 @@ -kind: Pod -apiVersion: v1 -id: kurbernetes-metadata-volume-plugin -metadata: - labels: - zone: us-est-coast - cluster: test-cluster1 - rack: rack-22 - name: kubernetes-metadata-volume-example - annotations: - build: two - builder: john-doe -spec: - containers: - - name: client-container - image: gcr.io/google_containers/busybox - command: ["sh", "-c", "while true; do if [[ -e /etc/labels ]]; then cat /etc/labels; fi; if [[ -e /etc/annotations ]]; then cat /etc/annotations; fi; sleep 5; done"] - volumeMounts: - - name: podinfo - mountPath: /etc - readOnly: false - volumes: - - name: podinfo - metadata: - items: - - name: "labels" - fieldRef: - fieldPath: metadata.labels - - name: "annotations" - fieldRef: - fieldPath: metadata.annotations diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/phabricator/authenticator-controller.json b/Godeps/_workspace/src/k8s.io/kubernetes/examples/phabricator/authenticator-controller.json deleted file mode 100644 index fbc449a73ddd..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/phabricator/authenticator-controller.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "kind": "ReplicationController", - "apiVersion": "v1", - "metadata": { - "name": "authenticator-controller", - "labels": { - "name": "authenticator" - } - }, - "spec": { - "replicas": 1, - "selector": { - "name": "authenticator" - }, - "template": { - "metadata": { - "labels": { - "name": "authenticator" - } - }, - "spec": { - "containers": [ - { - "name": "authenticator", - "image": "gcr.io/google_containers/cloudsql-authenticator:v1" - } - ] - } - } - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/examples/phabricator/phabricator-controller.json b/Godeps/_workspace/src/k8s.io/kubernetes/examples/phabricator/phabricator-controller.json index 7a6355cd05d9..b13103e11d27 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/examples/phabricator/phabricator-controller.json +++ b/Godeps/_workspace/src/k8s.io/kubernetes/examples/phabricator/phabricator-controller.json @@ -28,6 +28,20 @@ "name": "http-server", "containerPort": 80 } + ], + "env": [ + { + "name": "MYSQL_SERVICE_IP", + "value": "1.2.3.4" + }, + { + "name": "MYSQL_SERVICE_PORT", + "value": "3306" + }, + { + "name": "MYSQL_PASSWORD", + "value": "1234" + } ] } ] diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/admission/errors.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/admission/errors.go index 227b2e5448c8..51204c4c4b6d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/admission/errors.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/admission/errors.go @@ -19,22 +19,17 @@ package admission import ( "k8s.io/kubernetes/pkg/api" apierrors "k8s.io/kubernetes/pkg/api/errors" + errs "k8s.io/kubernetes/pkg/util/errors" ) -// NewForbidden is a utility function to return a well-formatted admission control error response -func NewForbidden(a Attributes, internalError error) error { - // do not double wrap an error of same type - if apierrors.IsForbidden(internalError) { - return internalError - } - - name := "Unknown" - kind := a.GetKind() +func extractKindName(a Attributes) (name, kind string, err error) { + name = "Unknown" + kind = a.GetKind() obj := a.GetObject() if obj != nil { objectMeta, err := api.ObjectMetaFor(obj) if err != nil { - return apierrors.NewForbidden(kind, name, internalError) + return "", "", err } // this is necessary because name object name generation has not occurred yet @@ -44,5 +39,27 @@ func NewForbidden(a Attributes, internalError error) error { name = objectMeta.GenerateName } } + return name, kind, nil +} + +// NewForbidden is a utility function to return a well-formatted admission control error response +func NewForbidden(a Attributes, internalError error) error { + // do not double wrap an error of same type + if apierrors.IsForbidden(internalError) { + return internalError + } + name, kind, err := extractKindName(a) + if err != nil { + return apierrors.NewInternalError(errs.NewAggregate([]error{internalError, err})) + } return apierrors.NewForbidden(kind, name, internalError) } + +// NewNotFound is a utility function to return a well-formatted admission control error response +func NewNotFound(a Attributes) error { + name, kind, err := extractKindName(a) + if err != nil { + return apierrors.NewInternalError(err) + } + return apierrors.NewNotFound(kind, name) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/context.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/context.go index a065e059ead5..7e86395712a1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/context.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/context.go @@ -18,14 +18,32 @@ package api import ( stderrs "errors" + "time" "golang.org/x/net/context" "k8s.io/kubernetes/pkg/auth/user" ) // Context carries values across API boundaries. +// This context matches the context.Context interface +// (https://blog.golang.org/context), for the purposes +// of passing the api.Context through to the storage tier. +// TODO: Determine the extent that this abstraction+interface +// is used by the api, and whether we can remove. type Context interface { + // Value returns the value associated with key or nil if none. Value(key interface{}) interface{} + + // Deadline returns the time when this Context will be canceled, if any. + Deadline() (deadline time.Time, ok bool) + + // Done returns a channel that is closed when this Context is canceled + // or times out. + Done() <-chan struct{} + + // Err indicates why this context was canceled, after the Done channel + // is closed. + Err() error } // The key type is unexported to prevent collisions diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/conversion.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/conversion.go index c0d1a676bb1c..f5ceb96bbcd8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/conversion.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/conversion.go @@ -18,11 +18,11 @@ package api import ( "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" ) // Codec is the identity codec for this package - it can only convert itself @@ -46,7 +46,7 @@ func init() { }, ) Scheme.AddConversionFuncs( - func(in *util.Time, out *util.Time, s conversion.Scope) error { + func(in *unversioned.Time, out *unversioned.Time, s conversion.Scope) error { // Cannot deep copy these, because time.Time has unexported fields. *out = *in return nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/copy_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/copy_test.go index c3c55283a7fd..0744873ce3b1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/copy_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/copy_test.go @@ -24,6 +24,9 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" + "k8s.io/kubernetes/pkg/util" + + "github.com/google/gofuzz" ) func TestDeepCopyApiObjects(t *testing.T) { @@ -31,21 +34,34 @@ func TestDeepCopyApiObjects(t *testing.T) { for _, version := range []string{"", testapi.Default.Version()} { f := apitesting.FuzzerFor(t, version, rand.NewSource(rand.Int63())) for kind := range api.Scheme.KnownTypes(version) { - item, err := api.Scheme.New(version, kind) - if err != nil { - t.Fatalf("Could not create a %s: %s", kind, err) - } - f.Fuzz(item) - itemCopy, err := api.Scheme.DeepCopy(item) - if err != nil { - t.Errorf("Could not deep copy a %s: %s", kind, err) - continue - } - - if !reflect.DeepEqual(item, itemCopy) { - t.Errorf("\nexpected %#v\ngot %#v", item, itemCopy) - } + doDeepCopyTest(t, version, kind, f) } } } } + +func doDeepCopyTest(t *testing.T, version, kind string, f *fuzz.Fuzzer) { + item, err := api.Scheme.New(version, kind) + if err != nil { + t.Fatalf("Could not create a %s: %s", kind, err) + } + f.Fuzz(item) + itemCopy, err := api.Scheme.DeepCopy(item) + if err != nil { + t.Errorf("Could not deep copy a %s: %s", kind, err) + return + } + + if !reflect.DeepEqual(item, itemCopy) { + t.Errorf("\nexpected: %#v\n\ngot: %#v\n\ndiff: %v", item, itemCopy, util.ObjectDiff(item, itemCopy)) + } +} + +func TestDeepCopySingleType(t *testing.T) { + for i := 0; i < *fuzzIters; i++ { + for _, version := range []string{"", testapi.Default.Version()} { + f := apitesting.FuzzerFor(t, version, rand.NewSource(rand.Int63())) + doDeepCopyTest(t, version, "Pod", f) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go index 5c35037d5f51..8b73d005346a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go @@ -22,6 +22,7 @@ import ( time "time" resource "k8s.io/kubernetes/pkg/api/resource" + unversioned "k8s.io/kubernetes/pkg/api/unversioned" conversion "k8s.io/kubernetes/pkg/conversion" fields "k8s.io/kubernetes/pkg/fields" labels "k8s.io/kubernetes/pkg/labels" @@ -39,7 +40,7 @@ func deepCopy_api_AWSElasticBlockStoreVolumeSource(in AWSElasticBlockStoreVolume } func deepCopy_api_Binding(in Binding, out *Binding, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -110,7 +111,7 @@ func deepCopy_api_ComponentCondition(in ComponentCondition, out *ComponentCondit } func deepCopy_api_ComponentStatus(in ComponentStatus, out *ComponentStatus, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -130,10 +131,10 @@ func deepCopy_api_ComponentStatus(in ComponentStatus, out *ComponentStatus, c *c } func deepCopy_api_ComponentStatusList(in ComponentStatusList, out *ComponentStatusList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -279,7 +280,7 @@ func deepCopy_api_ContainerState(in ContainerState, out *ContainerState, c *conv } func deepCopy_api_ContainerStateRunning(in ContainerStateRunning, out *ContainerStateRunning, c *conversion.Cloner) error { - if err := deepCopy_util_Time(in.StartedAt, &out.StartedAt, c); err != nil { + if err := deepCopy_unversioned_Time(in.StartedAt, &out.StartedAt, c); err != nil { return err } return nil @@ -290,10 +291,10 @@ func deepCopy_api_ContainerStateTerminated(in ContainerStateTerminated, out *Con out.Signal = in.Signal out.Reason = in.Reason out.Message = in.Message - if err := deepCopy_util_Time(in.StartedAt, &out.StartedAt, c); err != nil { + if err := deepCopy_unversioned_Time(in.StartedAt, &out.StartedAt, c); err != nil { return err } - if err := deepCopy_util_Time(in.FinishedAt, &out.FinishedAt, c); err != nil { + if err := deepCopy_unversioned_Time(in.FinishedAt, &out.FinishedAt, c); err != nil { return err } out.ContainerID = in.ContainerID @@ -322,8 +323,13 @@ func deepCopy_api_ContainerStatus(in ContainerStatus, out *ContainerStatus, c *c return nil } +func deepCopy_api_DaemonEndpoint(in DaemonEndpoint, out *DaemonEndpoint, c *conversion.Cloner) error { + out.Port = in.Port + return nil +} + func deepCopy_api_DeleteOptions(in DeleteOptions, out *DeleteOptions, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if in.GracePeriodSeconds != nil { @@ -393,6 +399,16 @@ func deepCopy_api_EndpointSubset(in EndpointSubset, out *EndpointSubset, c *conv } else { out.Addresses = nil } + if in.NotReadyAddresses != nil { + out.NotReadyAddresses = make([]EndpointAddress, len(in.NotReadyAddresses)) + for i := range in.NotReadyAddresses { + if err := deepCopy_api_EndpointAddress(in.NotReadyAddresses[i], &out.NotReadyAddresses[i], c); err != nil { + return err + } + } + } else { + out.NotReadyAddresses = nil + } if in.Ports != nil { out.Ports = make([]EndpointPort, len(in.Ports)) for i := range in.Ports { @@ -407,7 +423,7 @@ func deepCopy_api_EndpointSubset(in EndpointSubset, out *EndpointSubset, c *conv } func deepCopy_api_Endpoints(in Endpoints, out *Endpoints, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -427,10 +443,10 @@ func deepCopy_api_Endpoints(in Endpoints, out *Endpoints, c *conversion.Cloner) } func deepCopy_api_EndpointsList(in EndpointsList, out *EndpointsList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -473,7 +489,7 @@ func deepCopy_api_EnvVarSource(in EnvVarSource, out *EnvVarSource, c *conversion } func deepCopy_api_Event(in Event, out *Event, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -487,10 +503,10 @@ func deepCopy_api_Event(in Event, out *Event, c *conversion.Cloner) error { if err := deepCopy_api_EventSource(in.Source, &out.Source, c); err != nil { return err } - if err := deepCopy_util_Time(in.FirstTimestamp, &out.FirstTimestamp, c); err != nil { + if err := deepCopy_unversioned_Time(in.FirstTimestamp, &out.FirstTimestamp, c); err != nil { return err } - if err := deepCopy_util_Time(in.LastTimestamp, &out.LastTimestamp, c); err != nil { + if err := deepCopy_unversioned_Time(in.LastTimestamp, &out.LastTimestamp, c); err != nil { return err } out.Count = in.Count @@ -498,10 +514,10 @@ func deepCopy_api_Event(in Event, out *Event, c *conversion.Cloner) error { } func deepCopy_api_EventList(in EventList, out *EventList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -535,6 +551,31 @@ func deepCopy_api_ExecAction(in ExecAction, out *ExecAction, c *conversion.Clone return nil } +func deepCopy_api_FCVolumeSource(in FCVolumeSource, out *FCVolumeSource, c *conversion.Cloner) error { + if in.TargetWWNs != nil { + out.TargetWWNs = make([]string, len(in.TargetWWNs)) + for i := range in.TargetWWNs { + out.TargetWWNs[i] = in.TargetWWNs[i] + } + } else { + out.TargetWWNs = nil + } + if in.Lun != nil { + out.Lun = new(int) + *out.Lun = *in.Lun + } else { + out.Lun = nil + } + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_api_FlockerVolumeSource(in FlockerVolumeSource, out *FlockerVolumeSource, c *conversion.Cloner) error { + out.DatasetName = in.DatasetName + return nil +} + func deepCopy_api_GCEPersistentDiskVolumeSource(in GCEPersistentDiskVolumeSource, out *GCEPersistentDiskVolumeSource, c *conversion.Cloner) error { out.PDName = in.PDName out.FSType = in.FSType @@ -629,7 +670,7 @@ func deepCopy_api_Lifecycle(in Lifecycle, out *Lifecycle, c *conversion.Cloner) } func deepCopy_api_LimitRange(in LimitRange, out *LimitRange, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -707,10 +748,10 @@ func deepCopy_api_LimitRangeItem(in LimitRangeItem, out *LimitRangeItem, c *conv } func deepCopy_api_LimitRangeList(in LimitRangeList, out *LimitRangeList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -741,10 +782,10 @@ func deepCopy_api_LimitRangeSpec(in LimitRangeSpec, out *LimitRangeSpec, c *conv } func deepCopy_api_List(in List, out *List, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -764,14 +805,8 @@ func deepCopy_api_List(in List, out *List, c *conversion.Cloner) error { return nil } -func deepCopy_api_ListMeta(in ListMeta, out *ListMeta, c *conversion.Cloner) error { - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil -} - func deepCopy_api_ListOptions(in ListOptions, out *ListOptions, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if newVal, err := c.DeepCopy(in.LabelSelector); err != nil { @@ -826,7 +861,7 @@ func deepCopy_api_NFSVolumeSource(in NFSVolumeSource, out *NFSVolumeSource, c *c } func deepCopy_api_Namespace(in Namespace, out *Namespace, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -842,10 +877,10 @@ func deepCopy_api_Namespace(in Namespace, out *Namespace, c *conversion.Cloner) } func deepCopy_api_NamespaceList(in NamespaceList, out *NamespaceList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -879,7 +914,7 @@ func deepCopy_api_NamespaceStatus(in NamespaceStatus, out *NamespaceStatus, c *c } func deepCopy_api_Node(in Node, out *Node, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -903,10 +938,10 @@ func deepCopy_api_NodeAddress(in NodeAddress, out *NodeAddress, c *conversion.Cl func deepCopy_api_NodeCondition(in NodeCondition, out *NodeCondition, c *conversion.Cloner) error { out.Type = in.Type out.Status = in.Status - if err := deepCopy_util_Time(in.LastHeartbeatTime, &out.LastHeartbeatTime, c); err != nil { + if err := deepCopy_unversioned_Time(in.LastHeartbeatTime, &out.LastHeartbeatTime, c); err != nil { return err } - if err := deepCopy_util_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { + if err := deepCopy_unversioned_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { return err } out.Reason = in.Reason @@ -914,11 +949,18 @@ func deepCopy_api_NodeCondition(in NodeCondition, out *NodeCondition, c *convers return nil } +func deepCopy_api_NodeDaemonEndpoints(in NodeDaemonEndpoints, out *NodeDaemonEndpoints, c *conversion.Cloner) error { + if err := deepCopy_api_DaemonEndpoint(in.KubeletEndpoint, &out.KubeletEndpoint, c); err != nil { + return err + } + return nil +} + func deepCopy_api_NodeList(in NodeList, out *NodeList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -976,6 +1018,9 @@ func deepCopy_api_NodeStatus(in NodeStatus, out *NodeStatus, c *conversion.Clone } else { out.Addresses = nil } + if err := deepCopy_api_NodeDaemonEndpoints(in.DaemonEndpoints, &out.DaemonEndpoints, c); err != nil { + return err + } if err := deepCopy_api_NodeSystemInfo(in.NodeInfo, &out.NodeInfo, c); err != nil { return err } @@ -1008,12 +1053,12 @@ func deepCopy_api_ObjectMeta(in ObjectMeta, out *ObjectMeta, c *conversion.Clone out.UID = in.UID out.ResourceVersion = in.ResourceVersion out.Generation = in.Generation - if err := deepCopy_util_Time(in.CreationTimestamp, &out.CreationTimestamp, c); err != nil { + if err := deepCopy_unversioned_Time(in.CreationTimestamp, &out.CreationTimestamp, c); err != nil { return err } if in.DeletionTimestamp != nil { - out.DeletionTimestamp = new(util.Time) - if err := deepCopy_util_Time(*in.DeletionTimestamp, out.DeletionTimestamp, c); err != nil { + out.DeletionTimestamp = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.DeletionTimestamp, out.DeletionTimestamp, c); err != nil { return err } } else { @@ -1056,7 +1101,7 @@ func deepCopy_api_ObjectReference(in ObjectReference, out *ObjectReference, c *c } func deepCopy_api_PersistentVolume(in PersistentVolume, out *PersistentVolume, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1072,7 +1117,7 @@ func deepCopy_api_PersistentVolume(in PersistentVolume, out *PersistentVolume, c } func deepCopy_api_PersistentVolumeClaim(in PersistentVolumeClaim, out *PersistentVolumeClaim, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1088,10 +1133,10 @@ func deepCopy_api_PersistentVolumeClaim(in PersistentVolumeClaim, out *Persisten } func deepCopy_api_PersistentVolumeClaimList(in PersistentVolumeClaimList, out *PersistentVolumeClaimList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1155,10 +1200,10 @@ func deepCopy_api_PersistentVolumeClaimVolumeSource(in PersistentVolumeClaimVolu } func deepCopy_api_PersistentVolumeList(in PersistentVolumeList, out *PersistentVolumeList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1247,6 +1292,22 @@ func deepCopy_api_PersistentVolumeSource(in PersistentVolumeSource, out *Persist } else { out.CephFS = nil } + if in.FC != nil { + out.FC = new(FCVolumeSource) + if err := deepCopy_api_FCVolumeSource(*in.FC, out.FC, c); err != nil { + return err + } + } else { + out.FC = nil + } + if in.Flocker != nil { + out.Flocker = new(FlockerVolumeSource) + if err := deepCopy_api_FlockerVolumeSource(*in.Flocker, out.Flocker, c); err != nil { + return err + } + } else { + out.Flocker = nil + } return nil } @@ -1294,7 +1355,7 @@ func deepCopy_api_PersistentVolumeStatus(in PersistentVolumeStatus, out *Persist } func deepCopy_api_Pod(in Pod, out *Pod, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1310,7 +1371,7 @@ func deepCopy_api_Pod(in Pod, out *Pod, c *conversion.Cloner) error { } func deepCopy_api_PodAttachOptions(in PodAttachOptions, out *PodAttachOptions, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } out.Stdin = in.Stdin @@ -1324,11 +1385,19 @@ func deepCopy_api_PodAttachOptions(in PodAttachOptions, out *PodAttachOptions, c func deepCopy_api_PodCondition(in PodCondition, out *PodCondition, c *conversion.Cloner) error { out.Type = in.Type out.Status = in.Status + if err := deepCopy_unversioned_Time(in.LastProbeTime, &out.LastProbeTime, c); err != nil { + return err + } + if err := deepCopy_unversioned_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message return nil } func deepCopy_api_PodExecOptions(in PodExecOptions, out *PodExecOptions, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } out.Stdin = in.Stdin @@ -1348,10 +1417,10 @@ func deepCopy_api_PodExecOptions(in PodExecOptions, out *PodExecOptions, c *conv } func deepCopy_api_PodList(in PodList, out *PodList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1368,23 +1437,57 @@ func deepCopy_api_PodList(in PodList, out *PodList, c *conversion.Cloner) error } func deepCopy_api_PodLogOptions(in PodLogOptions, out *PodLogOptions, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } out.Container = in.Container out.Follow = in.Follow out.Previous = in.Previous + if in.SinceSeconds != nil { + out.SinceSeconds = new(int64) + *out.SinceSeconds = *in.SinceSeconds + } else { + out.SinceSeconds = nil + } + if in.SinceTime != nil { + out.SinceTime = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.SinceTime, out.SinceTime, c); err != nil { + return err + } + } else { + out.SinceTime = nil + } + out.Timestamps = in.Timestamps + if in.TailLines != nil { + out.TailLines = new(int64) + *out.TailLines = *in.TailLines + } else { + out.TailLines = nil + } + if in.LimitBytes != nil { + out.LimitBytes = new(int64) + *out.LimitBytes = *in.LimitBytes + } else { + out.LimitBytes = nil + } return nil } func deepCopy_api_PodProxyOptions(in PodProxyOptions, out *PodProxyOptions, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } out.Path = in.Path return nil } +func deepCopy_api_PodSecurityContext(in PodSecurityContext, out *PodSecurityContext, c *conversion.Cloner) error { + out.HostNetwork = in.HostNetwork + out.HostPID = in.HostPID + out.HostIPC = in.HostIPC + return nil +} + func deepCopy_api_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error { if in.Volumes != nil { out.Volumes = make([]Volume, len(in.Volumes)) @@ -1430,9 +1533,14 @@ func deepCopy_api_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error } out.ServiceAccountName = in.ServiceAccountName out.NodeName = in.NodeName - out.HostNetwork = in.HostNetwork - out.HostPID = in.HostPID - out.HostIPC = in.HostIPC + if in.SecurityContext != nil { + out.SecurityContext = new(PodSecurityContext) + if err := deepCopy_api_PodSecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil { + return err + } + } else { + out.SecurityContext = nil + } if in.ImagePullSecrets != nil { out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) for i := range in.ImagePullSecrets { @@ -1463,8 +1571,8 @@ func deepCopy_api_PodStatus(in PodStatus, out *PodStatus, c *conversion.Cloner) out.HostIP = in.HostIP out.PodIP = in.PodIP if in.StartTime != nil { - out.StartTime = new(util.Time) - if err := deepCopy_util_Time(*in.StartTime, out.StartTime, c); err != nil { + out.StartTime = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.StartTime, out.StartTime, c); err != nil { return err } } else { @@ -1484,7 +1592,7 @@ func deepCopy_api_PodStatus(in PodStatus, out *PodStatus, c *conversion.Cloner) } func deepCopy_api_PodStatusResult(in PodStatusResult, out *PodStatusResult, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1497,7 +1605,7 @@ func deepCopy_api_PodStatusResult(in PodStatusResult, out *PodStatusResult, c *c } func deepCopy_api_PodTemplate(in PodTemplate, out *PodTemplate, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1510,10 +1618,10 @@ func deepCopy_api_PodTemplate(in PodTemplate, out *PodTemplate, c *conversion.Cl } func deepCopy_api_PodTemplateList(in PodTemplateList, out *PodTemplateList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1575,7 +1683,7 @@ func deepCopy_api_RBDVolumeSource(in RBDVolumeSource, out *RBDVolumeSource, c *c } func deepCopy_api_RangeAllocation(in RangeAllocation, out *RangeAllocation, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1594,7 +1702,7 @@ func deepCopy_api_RangeAllocation(in RangeAllocation, out *RangeAllocation, c *c } func deepCopy_api_ReplicationController(in ReplicationController, out *ReplicationController, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1610,10 +1718,10 @@ func deepCopy_api_ReplicationController(in ReplicationController, out *Replicati } func deepCopy_api_ReplicationControllerList(in ReplicationControllerList, out *ReplicationControllerList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1657,7 +1765,7 @@ func deepCopy_api_ReplicationControllerStatus(in ReplicationControllerStatus, ou } func deepCopy_api_ResourceQuota(in ResourceQuota, out *ResourceQuota, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1673,10 +1781,10 @@ func deepCopy_api_ResourceQuota(in ResourceQuota, out *ResourceQuota, c *convers } func deepCopy_api_ResourceQuotaList(in ResourceQuotaList, out *ResourceQuotaList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1764,42 +1872,6 @@ func deepCopy_api_ResourceRequirements(in ResourceRequirements, out *ResourceReq return nil } -func deepCopy_api_RunAsUserStrategyOptions(in RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.UID != nil { - out.UID = new(int64) - *out.UID = *in.UID - } else { - out.UID = nil - } - if in.UIDRangeMin != nil { - out.UIDRangeMin = new(int64) - *out.UIDRangeMin = *in.UIDRangeMin - } else { - out.UIDRangeMin = nil - } - if in.UIDRangeMax != nil { - out.UIDRangeMax = new(int64) - *out.UIDRangeMax = *in.UIDRangeMax - } else { - out.UIDRangeMax = nil - } - return nil -} - -func deepCopy_api_SELinuxContextStrategyOptions(in SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(SELinuxOptions) - if err := deepCopy_api_SELinuxOptions(*in.SELinuxOptions, out.SELinuxOptions, c); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - return nil -} - func deepCopy_api_SELinuxOptions(in SELinuxOptions, out *SELinuxOptions, c *conversion.Cloner) error { out.User = in.User out.Role = in.Role @@ -1808,44 +1880,8 @@ func deepCopy_api_SELinuxOptions(in SELinuxOptions, out *SELinuxOptions, c *conv return nil } -func deepCopy_api_SupplementalGroupsStrategyOptions(in SupplementalGroupsStrategyOptions, out *SupplementalGroupsStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.Ranges != nil { - out.Ranges = make([]IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := deepCopy_api_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func deepCopy_api_FSGroupStrategyOptions(in FSGroupStrategyOptions, out *FSGroupStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.Ranges != nil { - out.Ranges = make([]IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := deepCopy_api_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func deepCopy_api_IDRange(in IDRange, out *IDRange, c *conversion.Cloner) error { - out.Max = in.Max - out.Min = in.Min - return nil -} - func deepCopy_api_Secret(in Secret, out *Secret, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1868,10 +1904,10 @@ func deepCopy_api_Secret(in Secret, out *Secret, c *conversion.Cloner) error { } func deepCopy_api_SecretList(in SecretList, out *SecretList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1925,80 +1961,8 @@ func deepCopy_api_SecurityContext(in SecurityContext, out *SecurityContext, c *c return nil } -func deepCopy_api_SecurityContextConstraints(in SecurityContextConstraints, out *SecurityContextConstraints, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - out.AllowPrivilegedContainer = in.AllowPrivilegedContainer - if in.AllowedCapabilities != nil { - out.AllowedCapabilities = make([]Capability, len(in.AllowedCapabilities)) - for i := range in.AllowedCapabilities { - out.AllowedCapabilities[i] = in.AllowedCapabilities[i] - } - } else { - out.AllowedCapabilities = nil - } - out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin - out.AllowHostNetwork = in.AllowHostNetwork - out.AllowHostPorts = in.AllowHostPorts - out.AllowHostPID = in.AllowHostPID - out.AllowHostIPC = in.AllowHostIPC - if err := deepCopy_api_SELinuxContextStrategyOptions(in.SELinuxContext, &out.SELinuxContext, c); err != nil { - return err - } - if err := deepCopy_api_RunAsUserStrategyOptions(in.RunAsUser, &out.RunAsUser, c); err != nil { - return err - } - if err := deepCopy_api_FSGroupStrategyOptions(in.FSGroup, &out.FSGroup, c); err != nil { - return err - } - if err := deepCopy_api_SupplementalGroupsStrategyOptions(in.SupplementalGroups, &out.SupplementalGroups, c); err != nil { - return err - } - if in.Users != nil { - out.Users = make([]string, len(in.Users)) - for i := range in.Users { - out.Users[i] = in.Users[i] - } - } else { - out.Users = nil - } - if in.Groups != nil { - out.Groups = make([]string, len(in.Groups)) - for i := range in.Groups { - out.Groups[i] = in.Groups[i] - } - } else { - out.Groups = nil - } - return nil -} - -func deepCopy_api_SecurityContextConstraintsList(in SecurityContextConstraintsList, out *SecurityContextConstraintsList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]SecurityContextConstraints, len(in.Items)) - for i := range in.Items { - if err := deepCopy_api_SecurityContextConstraints(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - func deepCopy_api_SerializedReference(in SerializedReference, out *SerializedReference, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectReference(in.Reference, &out.Reference, c); err != nil { @@ -2008,7 +1972,7 @@ func deepCopy_api_SerializedReference(in SerializedReference, out *SerializedRef } func deepCopy_api_Service(in Service, out *Service, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -2024,7 +1988,7 @@ func deepCopy_api_Service(in Service, out *Service, c *conversion.Cloner) error } func deepCopy_api_ServiceAccount(in ServiceAccount, out *ServiceAccount, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -2054,10 +2018,10 @@ func deepCopy_api_ServiceAccount(in ServiceAccount, out *ServiceAccount, c *conv } func deepCopy_api_ServiceAccountList(in ServiceAccountList, out *ServiceAccountList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -2074,10 +2038,10 @@ func deepCopy_api_ServiceAccountList(in ServiceAccountList, out *ServiceAccountL } func deepCopy_api_ServiceList(in ServiceList, out *ServiceList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -2145,52 +2109,6 @@ func deepCopy_api_ServiceStatus(in ServiceStatus, out *ServiceStatus, c *convers return nil } -func deepCopy_api_Status(in Status, out *Status, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - out.Status = in.Status - out.Message = in.Message - out.Reason = in.Reason - if in.Details != nil { - out.Details = new(StatusDetails) - if err := deepCopy_api_StatusDetails(*in.Details, out.Details, c); err != nil { - return err - } - } else { - out.Details = nil - } - out.Code = in.Code - return nil -} - -func deepCopy_api_StatusCause(in StatusCause, out *StatusCause, c *conversion.Cloner) error { - out.Type = in.Type - out.Message = in.Message - out.Field = in.Field - return nil -} - -func deepCopy_api_StatusDetails(in StatusDetails, out *StatusDetails, c *conversion.Cloner) error { - out.Name = in.Name - out.Kind = in.Kind - if in.Causes != nil { - out.Causes = make([]StatusCause, len(in.Causes)) - for i := range in.Causes { - if err := deepCopy_api_StatusCause(in.Causes[i], &out.Causes[i], c); err != nil { - return err - } - } - } else { - out.Causes = nil - } - out.RetryAfterSeconds = in.RetryAfterSeconds - return nil -} - func deepCopy_api_TCPSocketAction(in TCPSocketAction, out *TCPSocketAction, c *conversion.Cloner) error { if err := deepCopy_util_IntOrString(in.Port, &out.Port, c); err != nil { return err @@ -2198,12 +2116,6 @@ func deepCopy_api_TCPSocketAction(in TCPSocketAction, out *TCPSocketAction, c *c return nil } -func deepCopy_api_TypeMeta(in TypeMeta, out *TypeMeta, c *conversion.Cloner) error { - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil -} - func deepCopy_api_Volume(in Volume, out *Volume, c *conversion.Cloner) error { out.Name = in.Name if err := deepCopy_api_VolumeSource(in.VolumeSource, &out.VolumeSource, c); err != nil { @@ -2324,6 +2236,14 @@ func deepCopy_api_VolumeSource(in VolumeSource, out *VolumeSource, c *conversion } else { out.CephFS = nil } + if in.Flocker != nil { + out.Flocker = new(FlockerVolumeSource) + if err := deepCopy_api_FlockerVolumeSource(*in.Flocker, out.Flocker, c); err != nil { + return err + } + } else { + out.Flocker = nil + } if in.DownwardAPI != nil { out.DownwardAPI = new(DownwardAPIVolumeSource) if err := deepCopy_api_DownwardAPIVolumeSource(*in.DownwardAPI, out.DownwardAPI, c); err != nil { @@ -2332,6 +2252,14 @@ func deepCopy_api_VolumeSource(in VolumeSource, out *VolumeSource, c *conversion } else { out.DownwardAPI = nil } + if in.FC != nil { + out.FC = new(FCVolumeSource) + if err := deepCopy_api_FCVolumeSource(*in.FC, out.FC, c); err != nil { + return err + } + } else { + out.FC = nil + } return nil } @@ -2351,14 +2279,13 @@ func deepCopy_resource_Quantity(in resource.Quantity, out *resource.Quantity, c return nil } -func deepCopy_util_IntOrString(in util.IntOrString, out *util.IntOrString, c *conversion.Cloner) error { - out.Kind = in.Kind - out.IntVal = in.IntVal - out.StrVal = in.StrVal +func deepCopy_unversioned_ListMeta(in unversioned.ListMeta, out *unversioned.ListMeta, c *conversion.Cloner) error { + out.SelfLink = in.SelfLink + out.ResourceVersion = in.ResourceVersion return nil } -func deepCopy_util_Time(in util.Time, out *util.Time, c *conversion.Cloner) error { +func deepCopy_unversioned_Time(in unversioned.Time, out *unversioned.Time, c *conversion.Cloner) error { if newVal, err := c.DeepCopy(in.Time); err != nil { return err } else { @@ -2367,6 +2294,19 @@ func deepCopy_util_Time(in util.Time, out *util.Time, c *conversion.Cloner) erro return nil } +func deepCopy_unversioned_TypeMeta(in unversioned.TypeMeta, out *unversioned.TypeMeta, c *conversion.Cloner) error { + out.Kind = in.Kind + out.APIVersion = in.APIVersion + return nil +} + +func deepCopy_util_IntOrString(in util.IntOrString, out *util.IntOrString, c *conversion.Cloner) error { + out.Kind = in.Kind + out.IntVal = in.IntVal + out.StrVal = in.StrVal + return nil +} + func init() { err := Scheme.AddGeneratedDeepCopyFuncs( deepCopy_api_AWSElasticBlockStoreVolumeSource, @@ -2384,6 +2324,7 @@ func init() { deepCopy_api_ContainerStateTerminated, deepCopy_api_ContainerStateWaiting, deepCopy_api_ContainerStatus, + deepCopy_api_DaemonEndpoint, deepCopy_api_DeleteOptions, deepCopy_api_DownwardAPIVolumeFile, deepCopy_api_DownwardAPIVolumeSource, @@ -2399,14 +2340,14 @@ func init() { deepCopy_api_EventList, deepCopy_api_EventSource, deepCopy_api_ExecAction, - deepCopy_api_FSGroupStrategyOptions, + deepCopy_api_FCVolumeSource, + deepCopy_api_FlockerVolumeSource, deepCopy_api_GCEPersistentDiskVolumeSource, deepCopy_api_GitRepoVolumeSource, deepCopy_api_GlusterfsVolumeSource, deepCopy_api_HTTPGetAction, deepCopy_api_Handler, deepCopy_api_HostPathVolumeSource, - deepCopy_api_IDRange, deepCopy_api_ISCSIVolumeSource, deepCopy_api_Lifecycle, deepCopy_api_LimitRange, @@ -2414,7 +2355,6 @@ func init() { deepCopy_api_LimitRangeList, deepCopy_api_LimitRangeSpec, deepCopy_api_List, - deepCopy_api_ListMeta, deepCopy_api_ListOptions, deepCopy_api_LoadBalancerIngress, deepCopy_api_LoadBalancerStatus, @@ -2427,6 +2367,7 @@ func init() { deepCopy_api_Node, deepCopy_api_NodeAddress, deepCopy_api_NodeCondition, + deepCopy_api_NodeDaemonEndpoints, deepCopy_api_NodeList, deepCopy_api_NodeSpec, deepCopy_api_NodeStatus, @@ -2451,6 +2392,7 @@ func init() { deepCopy_api_PodList, deepCopy_api_PodLogOptions, deepCopy_api_PodProxyOptions, + deepCopy_api_PodSecurityContext, deepCopy_api_PodSpec, deepCopy_api_PodStatus, deepCopy_api_PodStatusResult, @@ -2469,15 +2411,11 @@ func init() { deepCopy_api_ResourceQuotaSpec, deepCopy_api_ResourceQuotaStatus, deepCopy_api_ResourceRequirements, - deepCopy_api_RunAsUserStrategyOptions, - deepCopy_api_SELinuxContextStrategyOptions, deepCopy_api_SELinuxOptions, deepCopy_api_Secret, deepCopy_api_SecretList, deepCopy_api_SecretVolumeSource, deepCopy_api_SecurityContext, - deepCopy_api_SecurityContextConstraints, - deepCopy_api_SecurityContextConstraintsList, deepCopy_api_SerializedReference, deepCopy_api_Service, deepCopy_api_ServiceAccount, @@ -2486,18 +2424,15 @@ func init() { deepCopy_api_ServicePort, deepCopy_api_ServiceSpec, deepCopy_api_ServiceStatus, - deepCopy_api_Status, - deepCopy_api_StatusCause, - deepCopy_api_StatusDetails, - deepCopy_api_SupplementalGroupsStrategyOptions, deepCopy_api_TCPSocketAction, - deepCopy_api_TypeMeta, deepCopy_api_Volume, deepCopy_api_VolumeMount, deepCopy_api_VolumeSource, deepCopy_resource_Quantity, + deepCopy_unversioned_ListMeta, + deepCopy_unversioned_Time, + deepCopy_unversioned_TypeMeta, deepCopy_util_IntOrString, - deepCopy_util_Time, ) if err != nil { // if one of the deep copy functions is malformed, detect it immediately. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/endpoints/util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/endpoints/util.go index 58e661e95f2d..bf9e0b2d3e11 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/endpoints/util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/endpoints/util.go @@ -34,70 +34,97 @@ import ( // form for things like comparison. The result is a newly allocated slice. func RepackSubsets(subsets []api.EndpointSubset) []api.EndpointSubset { // First map each unique port definition to the sets of hosts that - // offer it. The sets of hosts must be de-duped, using IP+UID as the key. - type addressKey struct { - ip string - uid types.UID - } + // offer it. allAddrs := map[addressKey]*api.EndpointAddress{} - portsToAddrs := map[api.EndpointPort]addressSet{} + portToAddrReadyMap := map[api.EndpointPort]addressSet{} for i := range subsets { - for j := range subsets[i].Ports { - epp := &subsets[i].Ports[j] + for _, port := range subsets[i].Ports { for k := range subsets[i].Addresses { - epa := &subsets[i].Addresses[k] - ak := addressKey{ip: epa.IP} - if epa.TargetRef != nil { - ak.uid = epa.TargetRef.UID - } - // Accumulate the address. - if allAddrs[ak] == nil { - // Make a copy so we don't write to the - // input args of this function. - p := &api.EndpointAddress{} - *p = *epa - allAddrs[ak] = p - } - // Remember that this port maps to this address. - if _, found := portsToAddrs[*epp]; !found { - portsToAddrs[*epp] = addressSet{} - } - portsToAddrs[*epp].Insert(allAddrs[ak]) + mapAddressByPort(&subsets[i].Addresses[k], port, true, allAddrs, portToAddrReadyMap) + } + for k := range subsets[i].NotReadyAddresses { + mapAddressByPort(&subsets[i].NotReadyAddresses[k], port, false, allAddrs, portToAddrReadyMap) } } } // Next, map the sets of hosts to the sets of ports they offer. // Go does not allow maps or slices as keys to maps, so we have - // to synthesize and artificial key and do a sort of 2-part + // to synthesize an artificial key and do a sort of 2-part // associative entity. type keyString string - addrSets := map[keyString]addressSet{} - addrSetsToPorts := map[keyString][]api.EndpointPort{} - for epp, addrs := range portsToAddrs { + keyToAddrReadyMap := map[keyString]addressSet{} + addrReadyMapKeyToPorts := map[keyString][]api.EndpointPort{} + for port, addrs := range portToAddrReadyMap { key := keyString(hashAddresses(addrs)) - addrSets[key] = addrs - addrSetsToPorts[key] = append(addrSetsToPorts[key], epp) + keyToAddrReadyMap[key] = addrs + addrReadyMapKeyToPorts[key] = append(addrReadyMapKeyToPorts[key], port) } // Next, build the N-to-M association the API wants. final := []api.EndpointSubset{} - for key, ports := range addrSetsToPorts { - addrs := []api.EndpointAddress{} - for k := range addrSets[key] { - addrs = append(addrs, *k) + for key, ports := range addrReadyMapKeyToPorts { + var readyAddrs, notReadyAddrs []api.EndpointAddress + for addr, ready := range keyToAddrReadyMap[key] { + if ready { + readyAddrs = append(readyAddrs, *addr) + } else { + notReadyAddrs = append(notReadyAddrs, *addr) + } } - final = append(final, api.EndpointSubset{Addresses: addrs, Ports: ports}) + final = append(final, api.EndpointSubset{Addresses: readyAddrs, NotReadyAddresses: notReadyAddrs, Ports: ports}) } // Finally, sort it. return SortSubsets(final) } -type addressSet map[*api.EndpointAddress]struct{} +// The sets of hosts must be de-duped, using IP+UID as the key. +type addressKey struct { + ip string + uid types.UID +} + +// mapAddressByPort adds an address into a map by its ports, registering the address with a unique pointer, and preserving +// any existing ready state. +func mapAddressByPort(addr *api.EndpointAddress, port api.EndpointPort, ready bool, allAddrs map[addressKey]*api.EndpointAddress, portToAddrReadyMap map[api.EndpointPort]addressSet) *api.EndpointAddress { + // use addressKey to distinguish between two endpoints that are identical addresses + // but may have come from different hosts, for attribution. For instance, Mesos + // assigns pods the node IP, but the pods are distinct. + key := addressKey{ip: addr.IP} + if addr.TargetRef != nil { + key.uid = addr.TargetRef.UID + } + + // Accumulate the address. The full EndpointAddress structure is preserved for use when + // we rebuild the subsets so that the final TargetRef has all of the necessary data. + existingAddress := allAddrs[key] + if existingAddress == nil { + // Make a copy so we don't write to the + // input args of this function. + existingAddress = &api.EndpointAddress{} + *existingAddress = *addr + allAddrs[key] = existingAddress + } + + // Remember that this port maps to this address. + if _, found := portToAddrReadyMap[port]; !found { + portToAddrReadyMap[port] = addressSet{} + } + // if we have not yet recorded this port for this address, or if the previous + // state was ready, write the current ready state. not ready always trumps + // ready. + if wasReady, found := portToAddrReadyMap[port][existingAddress]; !found || wasReady { + portToAddrReadyMap[port][existingAddress] = ready + } + return existingAddress +} + +type addressSet map[*api.EndpointAddress]bool -func (set addressSet) Insert(addr *api.EndpointAddress) { - set[addr] = struct{}{} +type addrReady struct { + addr *api.EndpointAddress + ready bool } func hashAddresses(addrs addressSet) string { @@ -105,16 +132,29 @@ func hashAddresses(addrs addressSet) string { // map key. Unfortunately, DeepHashObject is implemented in terms of // spew, and spew does not handle non-primitive map keys well. So // first we collapse it into a slice, sort the slice, then hash that. - slice := []*api.EndpointAddress{} - for k := range addrs { - slice = append(slice, k) + slice := make([]addrReady, 0, len(addrs)) + for k, ready := range addrs { + slice = append(slice, addrReady{k, ready}) } - sort.Sort(addrPtrsByIpAndUID(slice)) + sort.Sort(addrsReady(slice)) hasher := md5.New() util.DeepHashObject(hasher, slice) return hex.EncodeToString(hasher.Sum(nil)[0:]) } +func lessAddrReady(a, b addrReady) bool { + // ready is not significant to hashing since we can't have duplicate addresses + return LessEndpointAddress(a.addr, b.addr) +} + +type addrsReady []addrReady + +func (sl addrsReady) Len() int { return len(sl) } +func (sl addrsReady) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] } +func (sl addrsReady) Less(i, j int) bool { + return lessAddrReady(sl[i], sl[j]) +} + func LessEndpointAddress(a, b *api.EndpointAddress) bool { ipComparison := bytes.Compare([]byte(a.IP), []byte(b.IP)) if ipComparison != 0 { @@ -143,6 +183,7 @@ func SortSubsets(subsets []api.EndpointSubset) []api.EndpointSubset { for i := range subsets { ss := &subsets[i] sort.Sort(addrsByIpAndUID(ss.Addresses)) + sort.Sort(addrsByIpAndUID(ss.NotReadyAddresses)) sort.Sort(portsByHash(ss.Ports)) } sort.Sort(subsetsByHash(subsets)) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/endpoints/util_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/endpoints/util_test.go index 3f047db6da9e..a2f960317dfb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/endpoints/util_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/endpoints/util_test.go @@ -52,6 +52,10 @@ func TestPackSubsets(t *testing.T) { name: "empty ports", given: []api.EndpointSubset{{Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []api.EndpointPort{}}}, expect: []api.EndpointSubset{}, + }, { + name: "empty ports", + given: []api.EndpointSubset{{NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []api.EndpointPort{}}}, + expect: []api.EndpointSubset{}, }, { name: "one set, one ip, one port", given: []api.EndpointSubset{{ @@ -62,6 +66,16 @@ func TestPackSubsets(t *testing.T) { Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []api.EndpointPort{{Port: 111}}, }}, + }, { + name: "one set, one notReady ip, one port", + given: []api.EndpointSubset{{ + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, + expect: []api.EndpointSubset{{ + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, }, { name: "one set, one ip, one UID, one port", given: []api.EndpointSubset{{ @@ -72,6 +86,16 @@ func TestPackSubsets(t *testing.T) { Addresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, Ports: []api.EndpointPort{{Port: 111}}, }}, + }, { + name: "one set, one notReady ip, one UID, one port", + given: []api.EndpointSubset{{ + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, + expect: []api.EndpointSubset{{ + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, }, { name: "one set, one ip, empty UID, one port", given: []api.EndpointSubset{{ @@ -82,6 +106,16 @@ func TestPackSubsets(t *testing.T) { Addresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}}, Ports: []api.EndpointPort{{Port: 111}}, }}, + }, { + name: "one set, one notReady ip, empty UID, one port", + given: []api.EndpointSubset{{ + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, + expect: []api.EndpointSubset{{ + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, }, { name: "one set, two ips, one port", given: []api.EndpointSubset{{ @@ -92,6 +126,29 @@ func TestPackSubsets(t *testing.T) { Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}, {IP: "5.6.7.8"}}, Ports: []api.EndpointPort{{Port: 111}}, }}, + }, { + name: "one set, two mixed ips, one port", + given: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + NotReadyAddresses: []api.EndpointAddress{{IP: "5.6.7.8"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, + expect: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + NotReadyAddresses: []api.EndpointAddress{{IP: "5.6.7.8"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, + }, { + name: "one set, two duplicate ips, one port, notReady is covered by ready", + given: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, + expect: []api.EndpointSubset{{ + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, }, { name: "one set, one ip, two ports", given: []api.EndpointSubset{{ @@ -125,6 +182,23 @@ func TestPackSubsets(t *testing.T) { Addresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: &fooObjRef}}, Ports: []api.EndpointPort{{Port: 111}}, }}, + }, { + name: "one set, dup mixed ips with target-refs, one port", + given: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{ + {IP: "1.2.3.4", TargetRef: &fooObjRef}, + }, + NotReadyAddresses: []api.EndpointAddress{ + {IP: "1.2.3.4", TargetRef: &barObjRef}, + }, + Ports: []api.EndpointPort{{Port: 111}}, + }}, + expect: []api.EndpointSubset{{ + // finding the same address twice is considered an error on input, only the first address+port + // reference is preserved + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: &fooObjRef}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, }, { name: "one set, one ip, dup ports", given: []api.EndpointSubset{{ @@ -148,6 +222,19 @@ func TestPackSubsets(t *testing.T) { Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []api.EndpointPort{{Port: 111}}, }}, + }, { + name: "two sets, dup mixed ip, dup port", + given: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }, { + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, + expect: []api.EndpointSubset{{ + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, }, { name: "two sets, dup ip, two ports", given: []api.EndpointSubset{{ @@ -174,6 +261,22 @@ func TestPackSubsets(t *testing.T) { Addresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, Ports: []api.EndpointPort{{Port: 111}, {Port: 222}}, }}, + }, { + name: "two sets, dup mixed ip, dup uids, two ports", + given: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, + Ports: []api.EndpointPort{{Port: 111}}, + }, { + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, + Ports: []api.EndpointPort{{Port: 222}}, + }}, + expect: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, + Ports: []api.EndpointPort{{Port: 111}}, + }, { + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, + Ports: []api.EndpointPort{{Port: 222}}, + }}, }, { name: "two sets, two ips, dup port", given: []api.EndpointSubset{{ @@ -243,6 +346,32 @@ func TestPackSubsets(t *testing.T) { }, Ports: []api.EndpointPort{{Port: 111}}, }}, + }, { + name: "two sets, two mixed ips, two dup ip with uid, dup port, wrong order, ends up with split addresses", + given: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "5.6.7.8"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }, { + NotReadyAddresses: []api.EndpointAddress{{IP: "5.6.7.8", TargetRef: podRef("uid-1")}}, + Ports: []api.EndpointPort{{Port: 111}}, + }, { + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, + Ports: []api.EndpointPort{{Port: 111}}, + }, { + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }}, + expect: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{ + {IP: "5.6.7.8"}, + }, + NotReadyAddresses: []api.EndpointAddress{ + {IP: "1.2.3.4"}, + {IP: "1.2.3.4", TargetRef: podRef("uid-1")}, + {IP: "5.6.7.8", TargetRef: podRef("uid-1")}, + }, + Ports: []api.EndpointPort{{Port: 111}}, + }}, }, { name: "two sets, two ips, two ports", given: []api.EndpointSubset{{ @@ -281,13 +410,35 @@ func TestPackSubsets(t *testing.T) { Addresses: []api.EndpointAddress{{IP: "1.2.3.5"}}, Ports: []api.EndpointPort{{Port: 222}, {Port: 333}}, }}, + }, { + name: "four sets, three mixed ips, three ports, jumbled", + given: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }, { + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.5"}}, + Ports: []api.EndpointPort{{Port: 222}}, + }, { + Addresses: []api.EndpointAddress{{IP: "1.2.3.6"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }, { + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.5"}}, + Ports: []api.EndpointPort{{Port: 333}}, + }}, + expect: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}, {IP: "1.2.3.6"}}, + Ports: []api.EndpointPort{{Port: 111}}, + }, { + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.5"}}, + Ports: []api.EndpointPort{{Port: 222}, {Port: 333}}, + }}, }, } for _, tc := range testCases { result := RepackSubsets(tc.given) if !reflect.DeepEqual(result, SortSubsets(tc.expect)) { - t.Errorf("case %q: expected %s, got %s", tc.name, spew.Sprintf("%v", SortSubsets(tc.expect)), spew.Sprintf("%v", result)) + t.Errorf("case %q: expected %s, got %s", tc.name, spew.Sprintf("%#v", SortSubsets(tc.expect)), spew.Sprintf("%#v", result)) } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/errors/errors.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/errors/errors.go index 4583c188e38d..bed4c3960f84 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/errors/errors.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/errors/errors.go @@ -22,7 +22,7 @@ import ( "net/http" "strings" - "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/fielderrors" @@ -43,7 +43,7 @@ const ( // StatusError is an error intended for consumption by a REST API server; it can also be // reconstructed by clients from a REST response. Public to allow easy type switches. type StatusError struct { - ErrStatus api.Status + ErrStatus unversioned.Status } var _ error = &StatusError{} @@ -55,7 +55,7 @@ func (e *StatusError) Error() string { // Status allows access to e's status without having to know the detailed workings // of StatusError. Used by pkg/apiserver. -func (e *StatusError) Status() api.Status { +func (e *StatusError) Status() unversioned.Status { return e.ErrStatus } @@ -77,11 +77,11 @@ func (u *UnexpectedObjectError) Error() string { return fmt.Sprintf("unexpected object: %v", u.Object) } -// FromObject generates an StatusError from an api.Status, if that is the type of obj; otherwise, +// FromObject generates an StatusError from an unversioned.Status, if that is the type of obj; otherwise, // returns an UnexpecteObjectError. func FromObject(obj runtime.Object) error { switch t := obj.(type) { - case *api.Status: + case *unversioned.Status: return &StatusError{*t} } return &UnexpectedObjectError{obj} @@ -89,11 +89,11 @@ func FromObject(obj runtime.Object) error { // NewNotFound returns a new error which indicates that the resource of the kind and the name was not found. func NewNotFound(kind, name string) error { - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: http.StatusNotFound, - Reason: api.StatusReasonNotFound, - Details: &api.StatusDetails{ + Reason: unversioned.StatusReasonNotFound, + Details: &unversioned.StatusDetails{ Kind: kind, Name: name, }, @@ -103,11 +103,11 @@ func NewNotFound(kind, name string) error { // NewAlreadyExists returns an error indicating the item requested exists by that identifier. func NewAlreadyExists(kind, name string) error { - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: http.StatusConflict, - Reason: api.StatusReasonAlreadyExists, - Details: &api.StatusDetails{ + Reason: unversioned.StatusReasonAlreadyExists, + Details: &unversioned.StatusDetails{ Kind: kind, Name: name, }, @@ -122,21 +122,21 @@ func NewUnauthorized(reason string) error { if len(message) == 0 { message = "not authorized" } - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: http.StatusUnauthorized, - Reason: api.StatusReasonUnauthorized, + Reason: unversioned.StatusReasonUnauthorized, Message: message, }} } // NewForbidden returns an error indicating the requested action was forbidden func NewForbidden(kind, name string, err error) error { - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: http.StatusForbidden, - Reason: api.StatusReasonForbidden, - Details: &api.StatusDetails{ + Reason: unversioned.StatusReasonForbidden, + Details: &unversioned.StatusDetails{ Kind: kind, Name: name, }, @@ -146,11 +146,11 @@ func NewForbidden(kind, name string, err error) error { // NewConflict returns an error indicating the item can't be updated as provided. func NewConflict(kind, name string, err error) error { - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: http.StatusConflict, - Reason: api.StatusReasonConflict, - Details: &api.StatusDetails{ + Reason: unversioned.StatusReasonConflict, + Details: &unversioned.StatusDetails{ Kind: kind, Name: name, }, @@ -160,21 +160,21 @@ func NewConflict(kind, name string, err error) error { // NewInvalid returns an error indicating the item is invalid and cannot be processed. func NewInvalid(kind, name string, errs fielderrors.ValidationErrorList) error { - causes := make([]api.StatusCause, 0, len(errs)) + causes := make([]unversioned.StatusCause, 0, len(errs)) for i := range errs { if err, ok := errs[i].(*fielderrors.ValidationError); ok { - causes = append(causes, api.StatusCause{ - Type: api.CauseType(err.Type), + causes = append(causes, unversioned.StatusCause{ + Type: unversioned.CauseType(err.Type), Message: err.ErrorBody(), Field: err.Field, }) } } - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: StatusUnprocessableEntity, // RFC 4918: StatusUnprocessableEntity - Reason: api.StatusReasonInvalid, - Details: &api.StatusDetails{ + Reason: unversioned.StatusReasonInvalid, + Details: &unversioned.StatusDetails{ Kind: kind, Name: name, Causes: causes, @@ -185,31 +185,31 @@ func NewInvalid(kind, name string, errs fielderrors.ValidationErrorList) error { // NewBadRequest creates an error that indicates that the request is invalid and can not be processed. func NewBadRequest(reason string) error { - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: http.StatusBadRequest, - Reason: api.StatusReasonBadRequest, + Reason: unversioned.StatusReasonBadRequest, Message: reason, }} } // NewServiceUnavailable creates an error that indicates that the requested service is unavailable. func NewServiceUnavailable(reason string) error { - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: http.StatusServiceUnavailable, - Reason: api.StatusReasonServiceUnavailable, + Reason: unversioned.StatusReasonServiceUnavailable, Message: reason, }} } // NewMethodNotSupported returns an error indicating the requested action is not supported on this kind. func NewMethodNotSupported(kind, action string) error { - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: http.StatusMethodNotAllowed, - Reason: api.StatusReasonMethodNotAllowed, - Details: &api.StatusDetails{ + Reason: unversioned.StatusReasonMethodNotAllowed, + Details: &unversioned.StatusDetails{ Kind: kind, }, Message: fmt.Sprintf("%s is not supported on resources of kind %q", action, kind), @@ -219,11 +219,11 @@ func NewMethodNotSupported(kind, action string) error { // NewServerTimeout returns an error indicating the requested action could not be completed due to a // transient error, and the client should try again. func NewServerTimeout(kind, operation string, retryAfterSeconds int) error { - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: http.StatusInternalServerError, - Reason: api.StatusReasonServerTimeout, - Details: &api.StatusDetails{ + Reason: unversioned.StatusReasonServerTimeout, + Details: &unversioned.StatusDetails{ Kind: kind, Name: operation, RetryAfterSeconds: retryAfterSeconds, @@ -234,12 +234,12 @@ func NewServerTimeout(kind, operation string, retryAfterSeconds int) error { // NewInternalError returns an error indicating the item is invalid and cannot be processed. func NewInternalError(err error) error { - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: http.StatusInternalServerError, - Reason: api.StatusReasonInternalError, - Details: &api.StatusDetails{ - Causes: []api.StatusCause{{Message: err.Error()}}, + Reason: unversioned.StatusReasonInternalError, + Details: &unversioned.StatusDetails{ + Causes: []unversioned.StatusCause{{Message: err.Error()}}, }, Message: fmt.Sprintf("Internal error occurred: %v", err), }} @@ -248,12 +248,12 @@ func NewInternalError(err error) error { // NewTimeoutError returns an error indicating that a timeout occurred before the request // could be completed. Clients may retry, but the operation may still complete. func NewTimeoutError(message string, retryAfterSeconds int) error { - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: StatusServerTimeout, - Reason: api.StatusReasonTimeout, + Reason: unversioned.StatusReasonTimeout, Message: fmt.Sprintf("Timeout: %s", message), - Details: &api.StatusDetails{ + Details: &unversioned.StatusDetails{ RetryAfterSeconds: retryAfterSeconds, }, }} @@ -261,43 +261,43 @@ func NewTimeoutError(message string, retryAfterSeconds int) error { // NewGenericServerResponse returns a new error for server responses that are not in a recognizable form. func NewGenericServerResponse(code int, verb, kind, name, serverMessage string, retryAfterSeconds int, isUnexpectedResponse bool) error { - reason := api.StatusReasonUnknown + reason := unversioned.StatusReasonUnknown message := fmt.Sprintf("the server responded with the status code %d but did not return more information", code) switch code { case http.StatusConflict: if verb == "POST" { - reason = api.StatusReasonAlreadyExists + reason = unversioned.StatusReasonAlreadyExists } else { - reason = api.StatusReasonConflict + reason = unversioned.StatusReasonConflict } message = "the server reported a conflict" case http.StatusNotFound: - reason = api.StatusReasonNotFound + reason = unversioned.StatusReasonNotFound message = "the server could not find the requested resource" case http.StatusBadRequest: - reason = api.StatusReasonBadRequest + reason = unversioned.StatusReasonBadRequest message = "the server rejected our request for an unknown reason" case http.StatusUnauthorized: - reason = api.StatusReasonUnauthorized + reason = unversioned.StatusReasonUnauthorized message = "the server has asked for the client to provide credentials" case http.StatusForbidden: - reason = api.StatusReasonForbidden + reason = unversioned.StatusReasonForbidden message = "the server does not allow access to the requested resource" case http.StatusMethodNotAllowed: - reason = api.StatusReasonMethodNotAllowed + reason = unversioned.StatusReasonMethodNotAllowed message = "the server does not allow this method on the requested resource" case StatusUnprocessableEntity: - reason = api.StatusReasonInvalid + reason = unversioned.StatusReasonInvalid message = "the server rejected our request due to an error in our request" case StatusServerTimeout: - reason = api.StatusReasonServerTimeout + reason = unversioned.StatusReasonServerTimeout message = "the server cannot complete the requested operation at this time, try again later" case StatusTooManyRequests: - reason = api.StatusReasonTimeout + reason = unversioned.StatusReasonTimeout message = "the server has received too many requests and has asked us to try again later" default: if code >= 500 { - reason = api.StatusReasonInternalError + reason = unversioned.StatusReasonInternalError message = "an error on the server has prevented the request from succeeding" } } @@ -307,22 +307,22 @@ func NewGenericServerResponse(code int, verb, kind, name, serverMessage string, case len(kind) > 0: message = fmt.Sprintf("%s (%s %s)", message, strings.ToLower(verb), kind) } - var causes []api.StatusCause + var causes []unversioned.StatusCause if isUnexpectedResponse { - causes = []api.StatusCause{ + causes = []unversioned.StatusCause{ { - Type: api.CauseTypeUnexpectedServerResponse, + Type: unversioned.CauseTypeUnexpectedServerResponse, Message: serverMessage, }, } } else { causes = nil } - return &StatusError{api.Status{ - Status: api.StatusFailure, + return &StatusError{unversioned.Status{ + Status: unversioned.StatusFailure, Code: code, Reason: reason, - Details: &api.StatusDetails{ + Details: &unversioned.StatusDetails{ Kind: kind, Name: name, @@ -335,51 +335,51 @@ func NewGenericServerResponse(code int, verb, kind, name, serverMessage string, // IsNotFound returns true if the specified error was created by NewNotFound. func IsNotFound(err error) bool { - return reasonForError(err) == api.StatusReasonNotFound + return reasonForError(err) == unversioned.StatusReasonNotFound } // IsAlreadyExists determines if the err is an error which indicates that a specified resource already exists. func IsAlreadyExists(err error) bool { - return reasonForError(err) == api.StatusReasonAlreadyExists + return reasonForError(err) == unversioned.StatusReasonAlreadyExists } // IsConflict determines if the err is an error which indicates the provided update conflicts. func IsConflict(err error) bool { - return reasonForError(err) == api.StatusReasonConflict + return reasonForError(err) == unversioned.StatusReasonConflict } // IsInvalid determines if the err is an error which indicates the provided resource is not valid. func IsInvalid(err error) bool { - return reasonForError(err) == api.StatusReasonInvalid + return reasonForError(err) == unversioned.StatusReasonInvalid } // IsMethodNotSupported determines if the err is an error which indicates the provided action could not // be performed because it is not supported by the server. func IsMethodNotSupported(err error) bool { - return reasonForError(err) == api.StatusReasonMethodNotAllowed + return reasonForError(err) == unversioned.StatusReasonMethodNotAllowed } // IsBadRequest determines if err is an error which indicates that the request is invalid. func IsBadRequest(err error) bool { - return reasonForError(err) == api.StatusReasonBadRequest + return reasonForError(err) == unversioned.StatusReasonBadRequest } // IsUnauthorized determines if err is an error which indicates that the request is unauthorized and // requires authentication by the user. func IsUnauthorized(err error) bool { - return reasonForError(err) == api.StatusReasonUnauthorized + return reasonForError(err) == unversioned.StatusReasonUnauthorized } // IsForbidden determines if err is an error which indicates that the request is forbidden and cannot // be completed as requested. func IsForbidden(err error) bool { - return reasonForError(err) == api.StatusReasonForbidden + return reasonForError(err) == unversioned.StatusReasonForbidden } // IsServerTimeout determines if err is an error which indicates that the request needs to be retried // by the client. func IsServerTimeout(err error) bool { - return reasonForError(err) == api.StatusReasonServerTimeout + return reasonForError(err) == unversioned.StatusReasonServerTimeout } // IsUnexpectedServerError returns true if the server response was not in the expected API format, @@ -389,7 +389,7 @@ func IsUnexpectedServerError(err error) bool { case *StatusError: if d := t.Status().Details; d != nil { for _, cause := range d.Causes { - if cause.Type == api.CauseTypeUnexpectedServerResponse { + if cause.Type == unversioned.CauseTypeUnexpectedServerResponse { return true } } @@ -411,7 +411,7 @@ func SuggestsClientDelay(err error) (int, bool) { case *StatusError: if t.Status().Details != nil { switch t.Status().Reason { - case api.StatusReasonServerTimeout, api.StatusReasonTimeout: + case unversioned.StatusReasonServerTimeout, unversioned.StatusReasonTimeout: return t.Status().Details.RetryAfterSeconds, true } } @@ -419,10 +419,10 @@ func SuggestsClientDelay(err error) (int, bool) { return 0, false } -func reasonForError(err error) api.StatusReason { +func reasonForError(err error) unversioned.StatusReason { switch t := err.(type) { case *StatusError: return t.ErrStatus.Reason } - return api.StatusReasonUnknown + return unversioned.StatusReasonUnknown } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/errors/errors_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/errors/errors_test.go index b0f5eed65845..35c6d0801316 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/errors/errors_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/errors/errors_test.go @@ -22,7 +22,7 @@ import ( "reflect" "testing" - "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/fielderrors" ) @@ -30,118 +30,118 @@ import ( func TestErrorNew(t *testing.T) { err := NewAlreadyExists("test", "1") if !IsAlreadyExists(err) { - t.Errorf("expected to be %s", api.StatusReasonAlreadyExists) + t.Errorf("expected to be %s", unversioned.StatusReasonAlreadyExists) } if IsConflict(err) { - t.Errorf("expected to not be %s", api.StatusReasonConflict) + t.Errorf("expected to not be %s", unversioned.StatusReasonConflict) } if IsNotFound(err) { - t.Errorf(fmt.Sprintf("expected to not be %s", api.StatusReasonNotFound)) + t.Errorf(fmt.Sprintf("expected to not be %s", unversioned.StatusReasonNotFound)) } if IsInvalid(err) { - t.Errorf("expected to not be %s", api.StatusReasonInvalid) + t.Errorf("expected to not be %s", unversioned.StatusReasonInvalid) } if IsBadRequest(err) { - t.Errorf("expected to not be %s", api.StatusReasonBadRequest) + t.Errorf("expected to not be %s", unversioned.StatusReasonBadRequest) } if IsForbidden(err) { - t.Errorf("expected to not be %s", api.StatusReasonForbidden) + t.Errorf("expected to not be %s", unversioned.StatusReasonForbidden) } if IsServerTimeout(err) { - t.Errorf("expected to not be %s", api.StatusReasonServerTimeout) + t.Errorf("expected to not be %s", unversioned.StatusReasonServerTimeout) } if IsMethodNotSupported(err) { - t.Errorf("expected to not be %s", api.StatusReasonMethodNotAllowed) + t.Errorf("expected to not be %s", unversioned.StatusReasonMethodNotAllowed) } if !IsConflict(NewConflict("test", "2", errors.New("message"))) { t.Errorf("expected to be conflict") } if !IsNotFound(NewNotFound("test", "3")) { - t.Errorf("expected to be %s", api.StatusReasonNotFound) + t.Errorf("expected to be %s", unversioned.StatusReasonNotFound) } if !IsInvalid(NewInvalid("test", "2", nil)) { - t.Errorf("expected to be %s", api.StatusReasonInvalid) + t.Errorf("expected to be %s", unversioned.StatusReasonInvalid) } if !IsBadRequest(NewBadRequest("reason")) { - t.Errorf("expected to be %s", api.StatusReasonBadRequest) + t.Errorf("expected to be %s", unversioned.StatusReasonBadRequest) } if !IsForbidden(NewForbidden("test", "2", errors.New("reason"))) { - t.Errorf("expected to be %s", api.StatusReasonForbidden) + t.Errorf("expected to be %s", unversioned.StatusReasonForbidden) } if !IsUnauthorized(NewUnauthorized("reason")) { - t.Errorf("expected to be %s", api.StatusReasonUnauthorized) + t.Errorf("expected to be %s", unversioned.StatusReasonUnauthorized) } if !IsServerTimeout(NewServerTimeout("test", "reason", 0)) { - t.Errorf("expected to be %s", api.StatusReasonServerTimeout) + t.Errorf("expected to be %s", unversioned.StatusReasonServerTimeout) } if time, ok := SuggestsClientDelay(NewServerTimeout("test", "doing something", 10)); time != 10 || !ok { - t.Errorf("expected to be %s", api.StatusReasonServerTimeout) + t.Errorf("expected to be %s", unversioned.StatusReasonServerTimeout) } if time, ok := SuggestsClientDelay(NewTimeoutError("test reason", 10)); time != 10 || !ok { - t.Errorf("expected to be %s", api.StatusReasonTimeout) + t.Errorf("expected to be %s", unversioned.StatusReasonTimeout) } if !IsMethodNotSupported(NewMethodNotSupported("foo", "delete")) { - t.Errorf("expected to be %s", api.StatusReasonMethodNotAllowed) + t.Errorf("expected to be %s", unversioned.StatusReasonMethodNotAllowed) } } func TestNewInvalid(t *testing.T) { testCases := []struct { Err *fielderrors.ValidationError - Details *api.StatusDetails + Details *unversioned.StatusDetails }{ { fielderrors.NewFieldDuplicate("field[0].name", "bar"), - &api.StatusDetails{ + &unversioned.StatusDetails{ Kind: "kind", Name: "name", - Causes: []api.StatusCause{{ - Type: api.CauseTypeFieldValueDuplicate, + Causes: []unversioned.StatusCause{{ + Type: unversioned.CauseTypeFieldValueDuplicate, Field: "field[0].name", }}, }, }, { fielderrors.NewFieldInvalid("field[0].name", "bar", "detail"), - &api.StatusDetails{ + &unversioned.StatusDetails{ Kind: "kind", Name: "name", - Causes: []api.StatusCause{{ - Type: api.CauseTypeFieldValueInvalid, + Causes: []unversioned.StatusCause{{ + Type: unversioned.CauseTypeFieldValueInvalid, Field: "field[0].name", }}, }, }, { fielderrors.NewFieldNotFound("field[0].name", "bar"), - &api.StatusDetails{ + &unversioned.StatusDetails{ Kind: "kind", Name: "name", - Causes: []api.StatusCause{{ - Type: api.CauseTypeFieldValueNotFound, + Causes: []unversioned.StatusCause{{ + Type: unversioned.CauseTypeFieldValueNotFound, Field: "field[0].name", }}, }, }, { fielderrors.NewFieldValueNotSupported("field[0].name", "bar", nil), - &api.StatusDetails{ + &unversioned.StatusDetails{ Kind: "kind", Name: "name", - Causes: []api.StatusCause{{ - Type: api.CauseTypeFieldValueNotSupported, + Causes: []unversioned.StatusCause{{ + Type: unversioned.CauseTypeFieldValueNotSupported, Field: "field[0].name", }}, }, }, { fielderrors.NewFieldRequired("field[0].name"), - &api.StatusDetails{ + &unversioned.StatusDetails{ Kind: "kind", Name: "name", - Causes: []api.StatusCause{{ - Type: api.CauseTypeFieldValueRequired, + Causes: []unversioned.StatusCause{{ + Type: unversioned.CauseTypeFieldValueRequired, Field: "field[0].name", }}, }, @@ -152,7 +152,7 @@ func TestNewInvalid(t *testing.T) { expected.Causes[0].Message = vErr.ErrorBody() err := NewInvalid("kind", "name", fielderrors.ValidationErrorList{vErr}) status := err.(*StatusError).ErrStatus - if status.Code != 422 || status.Reason != api.StatusReasonInvalid { + if status.Code != 422 || status.Reason != unversioned.StatusReasonInvalid { t.Errorf("%d: unexpected status: %#v", i, status) } if !reflect.DeepEqual(expected, status.Details) { @@ -162,7 +162,7 @@ func TestNewInvalid(t *testing.T) { } func Test_reasonForError(t *testing.T) { - if e, a := api.StatusReasonUnknown, reasonForError(nil); e != a { + if e, a := unversioned.StatusReasonUnknown, reasonForError(nil); e != a { t.Errorf("unexpected reason type: %#v", a) } } @@ -176,7 +176,7 @@ func TestFromObject(t *testing.T) { obj runtime.Object message string }{ - {&api.Status{Message: "foobar"}, "foobar"}, + {&unversioned.Status{Message: "foobar"}, "foobar"}, {&TestType{}, "unexpected object: &{}"}, } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/helpers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/helpers.go index 931ff3b84b17..e113ffc2a0d5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/helpers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/helpers.go @@ -21,13 +21,14 @@ import ( "fmt" "reflect" "strings" + "time" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" "github.com/davecgh/go-spew/spew" @@ -67,7 +68,7 @@ var Semantic = conversion.EqualitiesOrDie( } return a.Amount.Cmp(b.Amount) == 0 }, - func(a, b util.Time) bool { + func(a, b unversioned.Time) bool { return a.UTC() == b.UTC() }, func(a, b labels.Selector) bool { @@ -235,3 +236,15 @@ func containsAccessMode(modes []PersistentVolumeAccessMode, mode PersistentVolum } return false } + +// ParseRFC3339 parses an RFC3339 date in either RFC3339Nano or RFC3339 format. +func ParseRFC3339(s string, nowFn func() unversioned.Time) (unversioned.Time, error) { + if t, timeErr := time.Parse(time.RFC3339Nano, s); timeErr == nil { + return unversioned.Time{t}, nil + } + t, err := time.Parse(time.RFC3339, s) + if err != nil { + return unversioned.Time{}, err + } + return unversioned.Time{t}, nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go new file mode 100644 index 000000000000..49eeb3ca3304 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go @@ -0,0 +1,119 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 install installs the v1 monolithic api, making it available as an +// option to all of the API encoding/decoding machinery. +package install + +import ( + "fmt" + "strings" + + "github.com/golang/glog" + + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/util/sets" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/registered" + apiutil "k8s.io/kubernetes/pkg/api/util" + "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/runtime" +) + +// userResources is a group of resources mostly used by a kubectl user +var userResources = []string{"rc", "svc", "pods", "pvc"} + +const importPrefix = "k8s.io/kubernetes/pkg/api" + +var accessor = meta.NewAccessor() + +func init() { + groupMeta, err := latest.RegisterGroup("") + if err != nil { + glog.V(4).Infof("%v", err) + return + } + // Use the first API version in the list of registered versions as the latest. + registeredGroupVersions := registered.GroupVersionsForGroup("") + groupVersion := registeredGroupVersions[0] + *groupMeta = latest.GroupMeta{ + GroupVersion: groupVersion, + Group: apiutil.GetGroup(groupVersion), + Version: apiutil.GetVersion(groupVersion), + Codec: runtime.CodecFor(api.Scheme, groupVersion), + } + var versions []string + var groupVersions []string + for i := len(registeredGroupVersions) - 1; i >= 0; i-- { + versions = append(versions, apiutil.GetVersion(registeredGroupVersions[i])) + groupVersions = append(groupVersions, registeredGroupVersions[i]) + } + groupMeta.Versions = versions + groupMeta.GroupVersions = groupVersions + + groupMeta.SelfLinker = runtime.SelfLinker(accessor) + + // the list of kinds that are scoped at the root of the api hierarchy + // if a kind is not enumerated here, it is assumed to have a namespace scope + // the list of kinds that are scoped at the root of the api hierarchy + // if a kind is not enumerated here, it is assumed to have a namespace scope + rootScoped := sets.NewString( + "Node", + "Minion", + "Namespace", + "PersistentVolume", + ) + + // these kinds should be excluded from the list of resources + ignoredKinds := sets.NewString( + "ListOptions", + "DeleteOptions", + "Status", + "PodLogOptions", + "PodExecOptions", + "PodAttachOptions", + "PodProxyOptions", + "ThirdPartyResource", + "ThirdPartyResourceData", + "ThirdPartyResourceList") + + mapper := api.NewDefaultRESTMapper("", versions, interfacesFor, importPrefix, ignoredKinds, rootScoped) + // setup aliases for groups of resources + mapper.AddResourceAlias("all", userResources...) + groupMeta.RESTMapper = mapper + api.RegisterRESTMapper(groupMeta.RESTMapper) + groupMeta.InterfacesFor = interfacesFor +} + +// InterfacesFor returns the default Codec and ResourceVersioner for a given version +// string, or an error if the version is not known. +func interfacesFor(version string) (*meta.VersionInterfaces, error) { + switch version { + case "v1": + return &meta.VersionInterfaces{ + Codec: v1.Codec, + ObjectConvertor: api.Scheme, + MetadataAccessor: accessor, + }, nil + default: + { + g, _ := latest.Group("") + return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(g.Versions, ", ")) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install_test.go new file mode 100644 index 000000000000..3bfc7f589778 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install_test.go @@ -0,0 +1,112 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 install + +import ( + "encoding/json" + "testing" + + internal "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" +) + +func TestResourceVersioner(t *testing.T) { + pod := internal.Pod{ObjectMeta: internal.ObjectMeta{ResourceVersion: "10"}} + version, err := accessor.ResourceVersion(&pod) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if version != "10" { + t.Errorf("unexpected version %v", version) + } + + podList := internal.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "10"}} + version, err = accessor.ResourceVersion(&podList) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if version != "10" { + t.Errorf("unexpected version %v", version) + } +} + +func TestCodec(t *testing.T) { + pod := internal.Pod{} + // We do want to use package latest rather than testapi here, because we + // want to test if the package install and package latest work as expected. + data, err := latest.GroupOrDie("").Codec.Encode(&pod) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + other := internal.Pod{} + if err := json.Unmarshal(data, &other); err != nil { + t.Fatalf("unexpected error: %v", err) + } + if other.APIVersion != latest.GroupOrDie("").Version || other.Kind != "Pod" { + t.Errorf("unexpected unmarshalled object %#v", other) + } +} + +func TestInterfacesFor(t *testing.T) { + if _, err := latest.GroupOrDie("").InterfacesFor(""); err == nil { + t.Fatalf("unexpected non-error: %v", err) + } + for i, version := range append([]string{latest.GroupOrDie("").Version}, latest.GroupOrDie("").Versions...) { + if vi, err := latest.GroupOrDie("").InterfacesFor(version); err != nil || vi == nil { + t.Fatalf("%d: unexpected result: %v", i, err) + } + } +} + +func TestRESTMapper(t *testing.T) { + if v, k, err := latest.GroupOrDie("").RESTMapper.VersionAndKindForResource("replicationcontrollers"); err != nil || v != "v1" || k != "ReplicationController" { + t.Errorf("unexpected version mapping: %s %s %v", v, k, err) + } + + if m, err := latest.GroupOrDie("").RESTMapper.RESTMapping("PodTemplate", ""); err != nil || m.APIVersion != "v1" || m.Resource != "podtemplates" { + t.Errorf("unexpected version mapping: %#v %v", m, err) + } + + for _, version := range latest.GroupOrDie("").Versions { + mapping, err := latest.GroupOrDie("").RESTMapper.RESTMapping("ReplicationController", version) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + if mapping.Resource != "replicationControllers" && mapping.Resource != "replicationcontrollers" { + t.Errorf("incorrect resource name: %#v", mapping) + } + if mapping.APIVersion != version { + t.Errorf("incorrect version: %v", mapping) + } + + interfaces, _ := latest.GroupOrDie("").InterfacesFor(version) + if mapping.Codec != interfaces.Codec { + t.Errorf("unexpected codec: %#v, expected: %#v", mapping, interfaces) + } + + rc := &internal.ReplicationController{ObjectMeta: internal.ObjectMeta{Name: "foo"}} + name, err := mapping.MetadataAccessor.Name(rc) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if name != "foo" { + t.Errorf("unable to retrieve object meta with: %v", mapping.MetadataAccessor) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest.go index 4f3132f32143..9341466615f0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest.go @@ -18,113 +18,132 @@ package latest import ( "fmt" + "sort" "strings" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/registered" - "k8s.io/kubernetes/pkg/api/v1" - "k8s.io/kubernetes/pkg/api/v1beta3" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util/sets" ) -// Version is the string that represents the current external default version. -var Version string - -// OldestVersion is the string that represents the oldest server version supported, -// for client code that wants to hardcode the lowest common denominator. -var OldestVersion string - -// Versions is the list of versions that are recognized in code. The order provided -// may be assumed to be least feature rich to most feature rich, and clients may -// choose to prefer the latter items in the list over the former items when presented -// with a set of versions to choose. -var Versions []string - -// Codec is the default codec for serializing output that should use -// the latest supported version. Use this Codec when writing to -// disk, a data store that is not dynamically versioned, or in tests. -// This codec can decode any object that Kubernetes is aware of. -var Codec runtime.Codec - -// accessor is the shared static metadata accessor for the API. -var accessor = meta.NewAccessor() - -// SelfLinker can set or get the SelfLink field of all API types. -// TODO: when versioning changes, make this part of each API definition. -// TODO(lavalamp): Combine SelfLinker & ResourceVersioner interfaces, force all uses -// to go through the InterfacesFor method below. -var SelfLinker = runtime.SelfLinker(accessor) - -// RESTMapper provides the default mapping between REST paths and the objects declared in api.Scheme and all known -// Kubernetes versions. -var RESTMapper meta.RESTMapper - -// userResources is a group of resources mostly used by a kubectl user -var userResources = []string{"rc", "svc", "pods", "pvc"} - -const importPrefix = "k8s.io/kubernetes/pkg/api" - -func init() { - // Use the first API version in the list of registered versions as the latest. - Version = registered.RegisteredVersions[0] - OldestVersion = registered.RegisteredVersions[len(registered.RegisteredVersions)-1] - Codec = runtime.CodecFor(api.Scheme, Version) - // Put the registered versions in Versions in reverse order. - versions := registered.RegisteredVersions - Versions = []string{} - for i := len(versions) - 1; i >= 0; i-- { - Versions = append(Versions, versions[i]) +var ( + allGroups = GroupMetaMap{} + // Group is a shortcut to allGroups.Group. + Group = allGroups.Group + // RegisterGroup is a shortcut to allGroups.RegisterGroup. + RegisterGroup = allGroups.RegisterGroup + // GroupOrDie is a shortcut to allGroups.GroupOrDie. + GroupOrDie = allGroups.GroupOrDie + // AllPreferredGroupVersions returns the preferred versions of all + // registered groups in the form of "group1/version1,group2/version2,..." + AllPreferredGroupVersions = allGroups.AllPreferredGroupVersions + // IsRegistered is a shortcut to allGroups.IsRegistered. + IsRegistered = allGroups.IsRegistered +) + +// GroupMetaMap is a map between group names and their metadata. +type GroupMetaMap map[string]*GroupMeta + +// RegisterGroup registers a group to GroupMetaMap. +func (g GroupMetaMap) RegisterGroup(group string) (*GroupMeta, error) { + _, found := g[group] + if found { + return nil, fmt.Errorf("group %v is already registered", g) + } + if len(registered.GroupVersionsForGroup(group)) == 0 { + return nil, fmt.Errorf("No version is registered for group %v", group) + } + g[group] = &GroupMeta{} + return g[group], nil +} + +// Group returns the metadata of a group if the gruop is registered, otherwise +// an erorr is returned. +func (g GroupMetaMap) Group(group string) (*GroupMeta, error) { + groupMeta, found := g[group] + if !found { + return nil, fmt.Errorf("no version is registered for group %v", group) } + return groupMeta, nil +} + +// IsRegistered takes a string and determines if it's one of the registered groups +func (g GroupMetaMap) IsRegistered(group string) bool { + _, found := g[group] + return found +} - // the list of kinds that are scoped at the root of the api hierarchy - // if a kind is not enumerated here, it is assumed to have a namespace scope - rootScoped := sets.NewString( - "Node", - "Minion", - "Namespace", - "PersistentVolume", - "SecurityContextConstraints", - ) - - // these kinds should be excluded from the list of resources - ignoredKinds := sets.NewString( - "ListOptions", - "DeleteOptions", - "Status", - "PodLogOptions", - "PodExecOptions", - "PodAttachOptions", - "PodProxyOptions", - "ThirdPartyResource", - "ThirdPartyResourceData", - "ThirdPartyResourceList") - - mapper := api.NewDefaultRESTMapper("api", versions, InterfacesFor, importPrefix, ignoredKinds, rootScoped) - // setup aliases for groups of resources - mapper.AddResourceAlias("all", userResources...) - RESTMapper = mapper - api.RegisterRESTMapper(RESTMapper) +// TODO: This is an expedient function, because we don't check if a Group is +// supported throughout the code base. We will abandon this function and +// checking the error returned by the Group() function. +func (g GroupMetaMap) GroupOrDie(group string) *GroupMeta { + groupMeta, found := g[group] + if !found { + const msg = "Please check the KUBE_API_VERSIONS environment variable." + if group == "" { + panic("The legacy v1 API is not registered. " + msg) + } else { + panic(fmt.Sprintf("No version is registered for group %s. ", group) + msg) + } + } + return groupMeta } -// InterfacesFor returns the default Codec and ResourceVersioner for a given version -// string, or an error if the version is not known. -func InterfacesFor(version string) (*meta.VersionInterfaces, error) { - switch version { - case "v1beta3": - return &meta.VersionInterfaces{ - Codec: v1beta3.Codec, - ObjectConvertor: api.Scheme, - MetadataAccessor: accessor, - }, nil - case "v1": - return &meta.VersionInterfaces{ - Codec: v1.Codec, - ObjectConvertor: api.Scheme, - MetadataAccessor: accessor, - }, nil - default: - return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(Versions, ", ")) +// AllPreferredGroupVersions returns the preferred versions of all registered +// groups in the form of "group1/version1,group2/version2,..." +func (g GroupMetaMap) AllPreferredGroupVersions() string { + if len(g) == 0 { + return "" } + var defaults []string + for _, groupMeta := range g { + defaults = append(defaults, groupMeta.GroupVersion) + } + sort.Strings(defaults) + return strings.Join(defaults, ",") +} + +// GroupMeta stores the metadata of a group, such as the latest supported version. +type GroupMeta struct { + // GroupVersion represents the current external default version of the group. It + // is in the form of "group/version". + GroupVersion string + + // Version represents the current external default version of the group. + // It equals to the "version" part of GroupVersion. + Version string + + // Group represents the name of the group + Group string + + // Versions is the list of versions that are recognized in code. The order + // provided is assumed to be from the oldest to the newest, e.g., + // Versions[0] == oldest and Versions[N-1] == newest. + // Clients may choose to prefer the latter items in the list over the former + // items when presented with a set of versions to choose. + Versions []string + + // GroupVersions is Group + Versions. This is to avoid string concatenation + // in many places. + GroupVersions []string + + // Codec is the default codec for serializing output that should use + // the latest supported version. Use this Codec when writing to + // disk, a data store that is not dynamically versioned, or in tests. + // This codec can decode any object that Kubernetes is aware of. + Codec runtime.Codec + + // SelfLinker can set or get the SelfLink field of all API types. + // TODO: when versioning changes, make this part of each API definition. + // TODO(lavalamp): Combine SelfLinker & ResourceVersioner interfaces, force all uses + // to go through the InterfacesFor method below. + SelfLinker runtime.SelfLinker + + // RESTMapper provides the default mapping between REST paths and the objects declared in api.Scheme and all known + // Kubernetes versions. + RESTMapper meta.RESTMapper + + // InterfacesFor returns the default Codec and ResourceVersioner for a given version + // string, or an error if the version is not known. + InterfacesFor func(version string) (*meta.VersionInterfaces, error) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest_test.go index bfce20aa74ab..4b3e0c91a54d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest_test.go @@ -1,5 +1,5 @@ /* -Copyright 2014 The Kubernetes Authors All rights reserved. +Copyright 2015 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,93 +16,44 @@ limitations under the License. package latest -import ( - "encoding/json" - "testing" - - internal "k8s.io/kubernetes/pkg/api" -) - -func TestResourceVersioner(t *testing.T) { - pod := internal.Pod{ObjectMeta: internal.ObjectMeta{ResourceVersion: "10"}} - version, err := accessor.ResourceVersion(&pod) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if version != "10" { - t.Errorf("unexpected version %v", version) - } - - podList := internal.PodList{ListMeta: internal.ListMeta{ResourceVersion: "10"}} - version, err = accessor.ResourceVersion(&podList) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if version != "10" { - t.Errorf("unexpected version %v", version) - } -} - -func TestCodec(t *testing.T) { - pod := internal.Pod{} - data, err := Codec.Encode(&pod) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - other := internal.Pod{} - if err := json.Unmarshal(data, &other); err != nil { - t.Fatalf("unexpected error: %v", err) - } - if other.APIVersion != Version || other.Kind != "Pod" { - t.Errorf("unexpected unmarshalled object %#v", other) - } -} - -func TestInterfacesFor(t *testing.T) { - if _, err := InterfacesFor(""); err == nil { - t.Fatalf("unexpected non-error: %v", err) - } - for i, version := range append([]string{Version, OldestVersion}, Versions...) { - if vi, err := InterfacesFor(version); err != nil || vi == nil { - t.Fatalf("%d: unexpected result: %v", i, err) - } - } -} - -func TestRESTMapper(t *testing.T) { - if v, k, err := RESTMapper.VersionAndKindForResource("replicationcontrollers"); err != nil || v != "v1" || k != "ReplicationController" { - t.Errorf("unexpected version mapping: %s %s %v", v, k, err) - } - - if m, err := RESTMapper.RESTMapping("PodTemplate", ""); err != nil || m.APIVersion != "v1" || m.Resource != "podtemplates" { - t.Errorf("unexpected version mapping: %#v %v", m, err) - } - - for _, version := range Versions { - mapping, err := RESTMapper.RESTMapping("ReplicationController", version) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - - if mapping.Resource != "replicationControllers" && mapping.Resource != "replicationcontrollers" { - t.Errorf("incorrect resource name: %#v", mapping) - } - if mapping.APIVersion != version { - t.Errorf("incorrect version: %v", mapping) - } - - interfaces, _ := InterfacesFor(version) - if mapping.Codec != interfaces.Codec { - t.Errorf("unexpected codec: %#v, expected: %#v", mapping, interfaces) - } - - rc := &internal.ReplicationController{ObjectMeta: internal.ObjectMeta{Name: "foo"}} - name, err := mapping.MetadataAccessor.Name(rc) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if name != "foo" { - t.Errorf("unable to retrieve object meta with: %v", mapping.MetadataAccessor) +import "testing" + +func TestAllPreferredGroupVersions(t *testing.T) { + testCases := []struct { + groupMetaMap GroupMetaMap + expect string + }{ + { + groupMetaMap: GroupMetaMap{ + "group1": &GroupMeta{ + GroupVersion: "group1/v1", + }, + "group2": &GroupMeta{ + GroupVersion: "group2/v2", + }, + "": &GroupMeta{ + GroupVersion: "v1", + }, + }, + expect: "group1/v1,group2/v2,v1", + }, + { + groupMetaMap: GroupMetaMap{ + "": &GroupMeta{ + GroupVersion: "v1", + }, + }, + expect: "v1", + }, + { + groupMetaMap: GroupMetaMap{}, + expect: "", + }, + } + for _, testCase := range testCases { + output := testCase.groupMetaMap.AllPreferredGroupVersions() + if testCase.expect != output { + t.Errorf("Error. expect: %s, got: %s", testCase.expect, output) } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/mapper.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/mapper.go index 600973aa0931..10a38ff2140b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/mapper.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/mapper.go @@ -42,7 +42,7 @@ func NewDefaultRESTMapper(group string, versions []string, interfacesFunc meta.V for _, version := range versions { for kind, oType := range Scheme.KnownTypes(version) { // TODO: Remove import path prefix check. - // We check the import path prefix because we currently stuff both "api" and "experimental" objects + // We check the import path prefix because we currently stuff both "api" and "extensions" objects // into the same group within Scheme since Scheme has no notion of groups yet. if !strings.HasPrefix(oType.PkgPath(), importPathPrefix) || ignoredKinds.Has(kind) { continue diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta.go index e5fa9635fb6f..a69f66d86d8a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta.go @@ -17,6 +17,7 @@ limitations under the License. package api import ( + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" @@ -24,7 +25,7 @@ import ( // FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta. func FillObjectMetaSystemFields(ctx Context, meta *ObjectMeta) { - meta.CreationTimestamp = util.Now() + meta.CreationTimestamp = unversioned.Now() meta.UID = util.NewUUID() meta.SelfLink = "" } @@ -50,12 +51,12 @@ func ObjectMetaFor(obj runtime.Object) (*ObjectMeta, error) { // ListMetaFor returns a pointer to a provided object's ListMeta, // or an error if the object does not have that pointer. // TODO: allow runtime.Unknown to extract this object -func ListMetaFor(obj runtime.Object) (*ListMeta, error) { +func ListMetaFor(obj runtime.Object) (*unversioned.ListMeta, error) { v, err := conversion.EnforcePtr(obj) if err != nil { return nil, err } - var meta *ListMeta + var meta *unversioned.ListMeta err = runtime.FieldPtr(v, "ListMeta", &meta) return meta, err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/interfaces.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/interfaces.go index 6fd638f2ff00..3d7455469e2e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/interfaces.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/interfaces.go @@ -141,7 +141,7 @@ type RESTMapping struct { // RESTMapper allows clients to map resources to kind, and map kind and version // to interfaces for manipulating those objects. It is primarily intended for -// consumers of Kubernetes compatible REST APIs as defined in docs/api-conventions.md. +// consumers of Kubernetes compatible REST APIs as defined in docs/devel/api-conventions.md. // // The Kubernetes API provides versioned resources and object kinds which are scoped // to API groups. In other words, kinds and resources should not be assumed to be @@ -157,4 +157,5 @@ type RESTMapper interface { RESTMapping(kind string, versions ...string) (*RESTMapping, error) AliasesForResource(resource string) ([]string, bool) ResourceSingularizer(resource string) (singular string, err error) + ResourceIsValid(resource string) bool } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/meta_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/meta_test.go index a1c81e630784..37cedb2be674 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/meta_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/meta_test.go @@ -20,8 +20,8 @@ import ( "reflect" "testing" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" ) func TestGenericTypeMeta(t *testing.T) { @@ -31,7 +31,7 @@ func TestGenericTypeMeta(t *testing.T) { Name string `json:"name,omitempty"` GenerateName string `json:"generateName,omitempty"` UID string `json:"uid,omitempty"` - CreationTimestamp util.Time `json:"creationTimestamp,omitempty"` + CreationTimestamp unversioned.Time `json:"creationTimestamp,omitempty"` SelfLink string `json:"selfLink,omitempty"` ResourceVersion string `json:"resourceVersion,omitempty"` APIVersion string `json:"apiVersion,omitempty"` @@ -146,7 +146,7 @@ type InternalTypeMeta struct { Name string `json:"name,omitempty"` GenerateName string `json:"generateName,omitempty"` UID string `json:"uid,omitempty"` - CreationTimestamp util.Time `json:"creationTimestamp,omitempty"` + CreationTimestamp unversioned.Time `json:"creationTimestamp,omitempty"` SelfLink string `json:"selfLink,omitempty"` ResourceVersion string `json:"resourceVersion,omitempty"` APIVersion string `json:"apiVersion,omitempty"` @@ -321,7 +321,7 @@ func TestGenericObjectMeta(t *testing.T) { Name string `json:"name,omitempty"` GenerateName string `json:"generateName,omitempty"` UID string `json:"uid,omitempty"` - CreationTimestamp util.Time `json:"creationTimestamp,omitempty"` + CreationTimestamp unversioned.Time `json:"creationTimestamp,omitempty"` SelfLink string `json:"selfLink,omitempty"` ResourceVersion string `json:"resourceVersion,omitempty"` Labels map[string]string `json:"labels,omitempty"` diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/restmapper.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/restmapper.go index 89680920e50b..ab389b934d4a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/restmapper.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/restmapper.go @@ -169,6 +169,15 @@ func (m *DefaultRESTMapper) ResourceSingularizer(resource string) (singular stri // VersionAndKindForResource implements RESTMapper func (m *DefaultRESTMapper) VersionAndKindForResource(resource string) (defaultVersion, kind string, err error) { + if parts := strings.Split(resource, "/"); len(parts) > 1 { + if len(parts) > 2 { + return "", "", fmt.Errorf("resource %q has an invalid name", resource) + } + resource = parts[1] + if m.group != parts[0] { + return "", "", fmt.Errorf("no resource %q is defined for group %q", resource, m.group) + } + } meta, ok := m.mapping[strings.ToLower(resource)] if !ok { return "", "", fmt.Errorf("no resource %q has been defined", resource) @@ -273,6 +282,12 @@ func (m *DefaultRESTMapper) AliasesForResource(alias string) ([]string, bool) { return nil, false } +// ResourceIsValid takes a string (kind) and checks if it's a valid resource +func (m *DefaultRESTMapper) ResourceIsValid(resource string) bool { + _, _, err := m.VersionAndKindForResource(resource) + return err == nil +} + // MultiRESTMapper is a wrapper for multiple RESTMappers. type MultiRESTMapper []RESTMapper @@ -335,3 +350,13 @@ func (m MultiRESTMapper) AliasesForResource(alias string) (aliases []string, ok } return nil, false } + +// ResourceIsValid takes a string (either group/kind or kind) and checks if it's a valid resource +func (m MultiRESTMapper) ResourceIsValid(resource string) bool { + for _, t := range m { + if t.ResourceIsValid(resource) { + return true + } + } + return false +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/restmapper_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/restmapper_test.go index 3d2145590f26..40a52b5cefa0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/restmapper_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/meta/restmapper_test.go @@ -18,6 +18,7 @@ package meta import ( "errors" + "io" "testing" "k8s.io/kubernetes/pkg/runtime" @@ -29,6 +30,10 @@ func (fakeCodec) Encode(runtime.Object) ([]byte, error) { return []byte{}, nil } +func (fakeCodec) EncodeToStream(runtime.Object, io.Writer) error { + return nil +} + func (fakeCodec) Decode([]byte) (runtime.Object, error) { return nil, nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/ref_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/ref_test.go index 491c35f145e2..cec77d5454e0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/ref_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/ref_test.go @@ -20,6 +20,7 @@ import ( "reflect" "testing" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" ) @@ -28,7 +29,7 @@ type FakeAPIObject struct{} func (*FakeAPIObject) IsAnAPIObject() {} type ExtensionAPIObject struct { - TypeMeta + unversioned.TypeMeta ObjectMeta } @@ -62,7 +63,7 @@ func TestGetReference(t *testing.T) { }, "serviceList": { obj: &ServiceList{ - ListMeta: ListMeta{ + ListMeta: unversioned.ListMeta{ ResourceVersion: "42", SelfLink: "/api/version2/services", }, @@ -75,7 +76,7 @@ func TestGetReference(t *testing.T) { }, "extensionAPIObject": { obj: &ExtensionAPIObject{ - TypeMeta: TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "ExtensionAPIObject", }, ObjectMeta: ObjectMeta{ @@ -95,7 +96,7 @@ func TestGetReference(t *testing.T) { }, "badSelfLink": { obj: &ServiceList{ - ListMeta: ListMeta{ + ListMeta: unversioned.ListMeta{ ResourceVersion: "42", SelfLink: "version2/services", }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/register.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/register.go index ae426de7795c..917b4a2318dc 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/register.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/register.go @@ -17,6 +17,7 @@ limitations under the License. package api import ( + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" ) @@ -36,7 +37,6 @@ func init() { &Service{}, &NodeList{}, &Node{}, - &Status{}, &Endpoints{}, &EndpointsList{}, &Binding{}, @@ -67,61 +67,50 @@ func init() { &ComponentStatusList{}, &SerializedReference{}, &RangeAllocation{}, - &ThirdPartyResource{}, - &ThirdPartyResourceList{}, - &ThirdPartyResourceData{}, - &SecurityContextConstraints{}, - &SecurityContextConstraintsList{}, ) - // Legacy names are supported - Scheme.AddKnownTypeWithName("", "Minion", &Node{}) - Scheme.AddKnownTypeWithName("", "MinionList", &NodeList{}) + + // Register Unversioned types + Scheme.AddKnownTypes("", &unversioned.Status{}) } -func (*Pod) IsAnAPIObject() {} -func (*PodList) IsAnAPIObject() {} -func (*PodStatusResult) IsAnAPIObject() {} -func (*PodTemplate) IsAnAPIObject() {} -func (*PodTemplateList) IsAnAPIObject() {} -func (*ReplicationController) IsAnAPIObject() {} -func (*ReplicationControllerList) IsAnAPIObject() {} -func (*Service) IsAnAPIObject() {} -func (*ServiceList) IsAnAPIObject() {} -func (*Endpoints) IsAnAPIObject() {} -func (*EndpointsList) IsAnAPIObject() {} -func (*Node) IsAnAPIObject() {} -func (*NodeList) IsAnAPIObject() {} -func (*Binding) IsAnAPIObject() {} -func (*Status) IsAnAPIObject() {} -func (*Event) IsAnAPIObject() {} -func (*EventList) IsAnAPIObject() {} -func (*List) IsAnAPIObject() {} -func (*LimitRange) IsAnAPIObject() {} -func (*LimitRangeList) IsAnAPIObject() {} -func (*ResourceQuota) IsAnAPIObject() {} -func (*ResourceQuotaList) IsAnAPIObject() {} -func (*Namespace) IsAnAPIObject() {} -func (*NamespaceList) IsAnAPIObject() {} -func (*ServiceAccount) IsAnAPIObject() {} -func (*ServiceAccountList) IsAnAPIObject() {} -func (*Secret) IsAnAPIObject() {} -func (*SecretList) IsAnAPIObject() {} -func (*PersistentVolume) IsAnAPIObject() {} -func (*PersistentVolumeList) IsAnAPIObject() {} -func (*PersistentVolumeClaim) IsAnAPIObject() {} -func (*PersistentVolumeClaimList) IsAnAPIObject() {} -func (*DeleteOptions) IsAnAPIObject() {} -func (*ListOptions) IsAnAPIObject() {} -func (*PodAttachOptions) IsAnAPIObject() {} -func (*PodLogOptions) IsAnAPIObject() {} -func (*PodExecOptions) IsAnAPIObject() {} -func (*PodProxyOptions) IsAnAPIObject() {} -func (*ComponentStatus) IsAnAPIObject() {} -func (*ComponentStatusList) IsAnAPIObject() {} -func (*SerializedReference) IsAnAPIObject() {} -func (*RangeAllocation) IsAnAPIObject() {} -func (*ThirdPartyResource) IsAnAPIObject() {} -func (*ThirdPartyResourceList) IsAnAPIObject() {} -func (*ThirdPartyResourceData) IsAnAPIObject() {} -func (*SecurityContextConstraints) IsAnAPIObject() {} -func (*SecurityContextConstraintsList) IsAnAPIObject() {} +func (*Pod) IsAnAPIObject() {} +func (*PodList) IsAnAPIObject() {} +func (*PodStatusResult) IsAnAPIObject() {} +func (*PodTemplate) IsAnAPIObject() {} +func (*PodTemplateList) IsAnAPIObject() {} +func (*ReplicationController) IsAnAPIObject() {} +func (*ReplicationControllerList) IsAnAPIObject() {} +func (*Service) IsAnAPIObject() {} +func (*ServiceList) IsAnAPIObject() {} +func (*Endpoints) IsAnAPIObject() {} +func (*EndpointsList) IsAnAPIObject() {} +func (*Node) IsAnAPIObject() {} +func (*NodeList) IsAnAPIObject() {} +func (*Binding) IsAnAPIObject() {} +func (*Event) IsAnAPIObject() {} +func (*EventList) IsAnAPIObject() {} +func (*List) IsAnAPIObject() {} +func (*LimitRange) IsAnAPIObject() {} +func (*LimitRangeList) IsAnAPIObject() {} +func (*ResourceQuota) IsAnAPIObject() {} +func (*ResourceQuotaList) IsAnAPIObject() {} +func (*Namespace) IsAnAPIObject() {} +func (*NamespaceList) IsAnAPIObject() {} +func (*ServiceAccount) IsAnAPIObject() {} +func (*ServiceAccountList) IsAnAPIObject() {} +func (*Secret) IsAnAPIObject() {} +func (*SecretList) IsAnAPIObject() {} +func (*PersistentVolume) IsAnAPIObject() {} +func (*PersistentVolumeList) IsAnAPIObject() {} +func (*PersistentVolumeClaim) IsAnAPIObject() {} +func (*PersistentVolumeClaimList) IsAnAPIObject() {} +func (*DeleteOptions) IsAnAPIObject() {} +func (*ListOptions) IsAnAPIObject() {} +func (*PodAttachOptions) IsAnAPIObject() {} +func (*PodLogOptions) IsAnAPIObject() {} +func (*PodExecOptions) IsAnAPIObject() {} +func (*PodProxyOptions) IsAnAPIObject() {} +func (*ComponentStatus) IsAnAPIObject() {} +func (*ComponentStatusList) IsAnAPIObject() {} +func (*SerializedReference) IsAnAPIObject() {} +func (*RangeAllocation) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/registered/registered.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/registered/registered.go index b28f5e9f962e..a3f8ddfbfc4d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/registered/registered.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/registered/registered.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/golang/glog" + apiutil "k8s.io/kubernetes/pkg/api/util" ) // List of registered API versions. @@ -29,13 +30,14 @@ import ( var RegisteredVersions []string func init() { + // TODO: caesarxuchao: rename this variable to validGroupVersions validAPIVersions := map[string]bool{ - "v1": true, - "v1beta3": true, + "v1": true, + "extensions/v1beta1": true, } // The default list of supported api versions, in order of most preferred to the least. - defaultSupportedVersions := "v1,v1beta3" + defaultSupportedVersions := "v1,extensions/v1beta1" // Env var KUBE_API_VERSIONS is a comma separated list of API versions that should be registered in the scheme. // The versions should be in the order of most preferred to the least. supportedVersions := os.Getenv("KUBE_API_VERSIONS") @@ -64,3 +66,15 @@ func IsRegisteredAPIVersion(version string) bool { } return false } + +// GroupVersionsForGroup returns the registered versions of a group in the form +// of "group/version". +func GroupVersionsForGroup(group string) []string { + ret := []string{} + for _, v := range RegisteredVersions { + if apiutil.GetGroup(v) == group { + ret = append(ret, v) + } + } + return ret +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/resource/quantity.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/resource/quantity.go index 577d5b6093ca..5b4a99dbc4bf 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/resource/quantity.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/resource/quantity.go @@ -323,9 +323,6 @@ func (q *Quantity) Cmp(y Quantity) int { } func (q *Quantity) Add(y Quantity) error { - if q.Format != y.Format { - return fmt.Errorf("format mismatch: %v vs. %v", q.Format, y.Format) - } q.Amount.Add(q.Amount, y.Amount) return nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/resource_helpers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/resource_helpers.go index 2dee56870b88..8a2948cf9212 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/resource_helpers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/resource_helpers.go @@ -68,10 +68,22 @@ func GetExistingContainerStatus(statuses []ContainerStatus, name string) Contain // IsPodReady retruns true if a pod is ready; false otherwise. func IsPodReady(pod *Pod) bool { - for _, c := range pod.Status.Conditions { - if c.Type == PodReady && c.Status == ConditionTrue { - return true + return IsPodReadyConditionTrue(pod.Status) +} + +// IsPodReady retruns true if a pod is ready; false otherwise. +func IsPodReadyConditionTrue(status PodStatus) bool { + condition := GetPodReadyCondition(status) + return condition != nil && condition.Status == ConditionTrue +} + +// Extracts the pod ready condition from the given status and returns that. +// Returns nil if the condition is not present. +func GetPodReadyCondition(status PodStatus) *PodCondition { + for i, c := range status.Conditions { + if c.Type == PodReady { + return &status.Conditions[i] } } - return false + return nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/delete.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/delete.go index c9df5970ef55..c05f3446db39 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/delete.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/delete.go @@ -20,8 +20,8 @@ import ( "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" ) // RESTDeleteStrategy defines deletion behavior on an object that follows Kubernetes @@ -62,7 +62,7 @@ func BeforeDelete(strategy RESTDeleteStrategy, ctx api.Context, obj runtime.Obje if period > *objectMeta.DeletionGracePeriodSeconds { return false, true, nil } - now := util.NewTime(util.Now().Add(time.Second * time.Duration(*options.GracePeriodSeconds))) + now := unversioned.NewTime(unversioned.Now().Add(time.Second * time.Duration(*options.GracePeriodSeconds))) objectMeta.DeletionTimestamp = &now objectMeta.DeletionGracePeriodSeconds = &period options.GracePeriodSeconds = &period @@ -76,7 +76,7 @@ func BeforeDelete(strategy RESTDeleteStrategy, ctx api.Context, obj runtime.Obje if !strategy.CheckGracefulDelete(obj, options) { return false, false, nil } - now := util.NewTime(util.Now().Add(time.Second * time.Duration(*options.GracePeriodSeconds))) + now := unversioned.NewTime(unversioned.Now().Add(time.Second * time.Duration(*options.GracePeriodSeconds))) objectMeta.DeletionTimestamp = &now objectMeta.DeletionGracePeriodSeconds = options.GracePeriodSeconds return true, false, nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/rest.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/rest.go index d4db3d0a8870..57be322a7ed5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/rest.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/rest.go @@ -202,20 +202,24 @@ type Redirector interface { ResourceLocation(ctx api.Context, id string) (remoteLocation *url.URL, transport http.RoundTripper, err error) } -// ConnectHandler is a handler for HTTP connection requests. It extends the standard -// http.Handler interface by adding a method that returns an error object if an error -// occurred during the handling of the request. -type ConnectHandler interface { - http.Handler - - // RequestError returns an error if one occurred during handling of an HTTP request - RequestError() error +// Responder abstracts the normal response behavior for a REST method and is passed to callers that +// may wish to handle the response directly in some cases, but delegate to the normal error or object +// behavior in other cases. +type Responder interface { + // Object writes the provided object to the response. Invoking this method multiple times is undefined. + Object(statusCode int, obj runtime.Object) + // Error writes the provided error to the response. This method may only be invoked once. + Error(err error) } -// Connecter is a storage object that responds to a connection request +// Connecter is a storage object that responds to a connection request. type Connecter interface { - // Connect returns a ConnectHandler that will handle the request/response for a request - Connect(ctx api.Context, id string, options runtime.Object) (ConnectHandler, error) + // Connect returns an http.Handler that will handle the request/response for a given API invocation. + // The provided responder may be used for common API responses. The responder will write both status + // code and body, so the ServeHTTP method should exit after invoking the responder. The Handler will + // be used for a single API request and then discarded. The Responder is guaranteed to write to the + // same http.ResponseWriter passed to ServeHTTP. + Connect(ctx api.Context, id string, options runtime.Object, r Responder) (http.Handler, error) // NewConnectOptions returns an empty options object that will be used to pass // options to the Connect method. If nil, then a nil options object is passed to diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/resttest/resttest.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/resttest/resttest.go index 1c1ab3a47594..72a2ecb9af64 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/resttest/resttest.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/resttest/resttest.go @@ -26,6 +26,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -369,7 +370,7 @@ func (t *Tester) testCreateRejectsMismatchedNamespace(valid runtime.Object) { func (t *Tester) testCreateResetsUserData(valid runtime.Object) { objectMeta := t.getObjectMetaOrFail(valid) - now := util.Now() + now := unversioned.Now() objectMeta.UID = "bad-uid" objectMeta.CreationTimestamp = now @@ -527,9 +528,9 @@ func (t *Tester) testDeleteNoGraceful(obj runtime.Object, setFn SetFunc, getFn G t.Errorf("unexpected error: %v", err) } if !t.returnDeletedObject { - if status, ok := obj.(*api.Status); !ok { + if status, ok := obj.(*unversioned.Status); !ok { t.Errorf("expected status of delete, got %v", status) - } else if status.Status != api.StatusSuccess { + } else if status.Status != unversioned.StatusSuccess { t.Errorf("expected success, got: %v", status.Status) } } @@ -961,7 +962,7 @@ func (t *Tester) testWatchFields(obj runtime.Object, initWatchFn InitWatchFunc, if !ok { t.Errorf("watch channel should be open") } - case <-time.After(time.Millisecond * 100): + case <-time.After(util.ForeverTestTimeout): t.Errorf("unexpected timeout from result channel") } watcher.Stop() @@ -982,7 +983,7 @@ func (t *Tester) testWatchFields(obj runtime.Object, initWatchFn InitWatchFunc, select { case <-watcher.ResultChan(): t.Errorf("unexpected result from result channel") - case <-time.After(time.Millisecond * 100): + case <-time.After(time.Millisecond * 500): // expected case } watcher.Stop() @@ -1009,7 +1010,7 @@ func (t *Tester) testWatchLabels(obj runtime.Object, initWatchFn InitWatchFunc, if !ok { t.Errorf("watch channel should be open") } - case <-time.After(time.Millisecond * 100): + case <-time.After(util.ForeverTestTimeout): t.Errorf("unexpected timeout from result channel") } watcher.Stop() @@ -1030,7 +1031,7 @@ func (t *Tester) testWatchLabels(obj runtime.Object, initWatchFn InitWatchFunc, select { case <-watcher.ResultChan(): t.Errorf("unexpected result from result channel") - case <-time.After(time.Millisecond * 100): + case <-time.After(time.Millisecond * 500): // expected case } watcher.Stop() diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/update.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/update.go index b65bed246dbd..394cb3d5ffdf 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/update.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/rest/update.go @@ -19,6 +19,7 @@ package rest import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/fielderrors" ) @@ -44,6 +45,22 @@ type RESTUpdateStrategy interface { AllowUnconditionalUpdate() bool } +// TODO: add other common fields that require global validation. +func validateCommonFields(obj, old runtime.Object) fielderrors.ValidationErrorList { + allErrs := fielderrors.ValidationErrorList{} + objectMeta, err := api.ObjectMetaFor(obj) + if err != nil { + return append(allErrs, errors.NewInternalError(err)) + } + oldObjectMeta, err := api.ObjectMetaFor(old) + if err != nil { + return append(allErrs, errors.NewInternalError(err)) + } + allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(objectMeta, oldObjectMeta)...) + + return allErrs +} + // BeforeUpdate ensures that common operations for all resources are performed on update. It only returns // errors that can be converted to api.Status. It will invoke update validation with the provided existing // and updated objects. @@ -59,8 +76,14 @@ func BeforeUpdate(strategy RESTUpdateStrategy, ctx api.Context, obj, old runtime } else { objectMeta.Namespace = api.NamespaceNone } + strategy.PrepareForUpdate(obj, old) - if errs := strategy.ValidateUpdate(ctx, obj, old); len(errs) > 0 { + + // Ensure some common fields, like UID, are validated for all resources. + errs := validateCommonFields(obj, old) + + errs = append(errs, strategy.ValidateUpdate(ctx, obj, old)...) + if len(errs) > 0 { return errors.NewInvalid(kind, objectMeta.Name, errs) } return nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/serialization_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/serialization_test.go index c500623bb5e0..3a631af74254 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/serialization_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/serialization_test.go @@ -25,7 +25,6 @@ import ( "github.com/davecgh/go-spew/spew" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" @@ -33,8 +32,8 @@ import ( "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" - _ "k8s.io/kubernetes/pkg/apis/experimental" - _ "k8s.io/kubernetes/pkg/apis/experimental/v1" + _ "k8s.io/kubernetes/pkg/apis/extensions" + _ "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" flag "github.com/spf13/pflag" ) @@ -91,10 +90,16 @@ func roundTripSame(t *testing.T, item runtime.Object, except ...string) { set := sets.NewString(except...) seed := rand.Int63() fuzzInternalObject(t, "", item, seed) + + codec, err := testapi.GetCodecForObject(item) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + version := testapi.Default.Version() if !set.Has(version) { fuzzInternalObject(t, version, item, seed) - roundTrip(t, testapi.Default.Codec(), item) + roundTrip(t, codec, item) } } @@ -103,7 +108,7 @@ func TestSpecificKind(t *testing.T) { api.Scheme.Log(t) defer api.Scheme.Log(nil) - kind := "PodList" + kind := "Pod" doRoundTripTest(kind, t) } @@ -164,11 +169,13 @@ func TestEncode_Ptr(t *testing.T) { DNSPolicy: api.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, + + SecurityContext: &api.PodSecurityContext{}, }, } obj := runtime.Object(pod) - data, err := latest.Codec.Encode(obj) - obj2, err2 := latest.Codec.Decode(data) + data, err := testapi.Default.Codec().Encode(obj) + obj2, err2 := testapi.Default.Codec().Decode(data) if err != nil || err2 != nil { t.Fatalf("Failure: '%v' '%v'", err, err2) } @@ -176,17 +183,18 @@ func TestEncode_Ptr(t *testing.T) { t.Fatalf("Got wrong type") } if !api.Semantic.DeepEqual(obj2, pod) { - t.Errorf("Expected:\n %#v,\n Got:\n %#v", pod, obj2) + t.Errorf("\nExpected:\n\n %#v,\n\nGot:\n\n %#vDiff: %v\n\n", pod, obj2, util.ObjectDiff(obj2, pod)) + } } func TestBadJSONRejection(t *testing.T) { badJSONMissingKind := []byte(`{ }`) - if _, err := latest.Codec.Decode(badJSONMissingKind); err == nil { + if _, err := testapi.Default.Codec().Decode(badJSONMissingKind); err == nil { t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind) } badJSONUnknownType := []byte(`{"kind": "bar"}`) - if _, err1 := latest.Codec.Decode(badJSONUnknownType); err1 == nil { + if _, err1 := testapi.Default.Codec().Decode(badJSONUnknownType); err1 == nil { t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType) } /*badJSONKindMismatch := []byte(`{"kind": "Pod"}`) @@ -202,7 +210,7 @@ func BenchmarkEncode(b *testing.B) { apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) apiObjectFuzzer.Fuzz(&pod) for i := 0; i < b.N; i++ { - latest.Codec.Encode(&pod) + testapi.Default.Codec().Encode(&pod) } } @@ -220,9 +228,9 @@ func BenchmarkDecode(b *testing.B) { pod := api.Pod{} apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) apiObjectFuzzer.Fuzz(&pod) - data, _ := latest.Codec.Encode(&pod) + data, _ := testapi.Default.Codec().Encode(&pod) for i := 0; i < b.N; i++ { - latest.Codec.Decode(data) + testapi.Default.Codec().Decode(data) } } @@ -230,10 +238,10 @@ func BenchmarkDecodeInto(b *testing.B) { pod := api.Pod{} apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) apiObjectFuzzer.Fuzz(&pod) - data, _ := latest.Codec.Encode(&pod) + data, _ := testapi.Default.Codec().Encode(&pod) for i := 0; i < b.N; i++ { obj := api.Pod{} - latest.Codec.DecodeInto(data, &obj) + testapi.Default.Codec().DecodeInto(data, &obj) } } @@ -242,7 +250,7 @@ func BenchmarkDecodeJSON(b *testing.B) { pod := api.Pod{} apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) apiObjectFuzzer.Fuzz(&pod) - data, _ := latest.Codec.Encode(&pod) + data, _ := testapi.Default.Codec().Encode(&pod) for i := 0; i < b.N; i++ { obj := api.Pod{} json.Unmarshal(data, &obj) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testapi/testapi.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testapi/testapi.go index 8b0cbe59d20b..e0a73bd0bdad 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testapi/testapi.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testapi/testapi.go @@ -22,17 +22,20 @@ import ( "os" "strings" + "k8s.io/kubernetes/pkg/api" + _ "k8s.io/kubernetes/pkg/api/install" + _ "k8s.io/kubernetes/pkg/apis/extensions/install" + "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/meta" apiutil "k8s.io/kubernetes/pkg/api/util" - explatest "k8s.io/kubernetes/pkg/apis/experimental/latest" "k8s.io/kubernetes/pkg/runtime" ) var ( - Groups = make(map[string]TestGroup) - Default TestGroup - Experimental TestGroup + Groups = make(map[string]TestGroup) + Default TestGroup + Extensions TestGroup ) type TestGroup struct { @@ -59,16 +62,16 @@ func init() { // TODO: caesarxuchao: we need a central place to store all available API // groups and their metadata. if _, ok := Groups[""]; !ok { - // TODO: The second latest.Version will be latest.GroupVersion after we + // TODO: The second latest.GroupOrDie("").Version will be latest.GroupVersion after we // have multiple group support - Groups[""] = TestGroup{"", latest.Version, latest.Version} + Groups[""] = TestGroup{"", latest.GroupOrDie("").Version, latest.GroupOrDie("").GroupVersion} } - if _, ok := Groups["experimental"]; !ok { - Groups["experimental"] = TestGroup{"experimental", explatest.Version, explatest.Version} + if _, ok := Groups["extensions"]; !ok { + Groups["extensions"] = TestGroup{"extensions", latest.GroupOrDie("extensions").Version, latest.GroupOrDie("extensions").GroupVersion} } Default = Groups[""] - Experimental = Groups["experimental"] + Extensions = Groups["extensions"] } // Version returns the API version to test against, as set by the KUBE_TEST_API env var. @@ -88,14 +91,14 @@ func (g TestGroup) GroupAndVersion() string { func (g TestGroup) Codec() runtime.Codec { // TODO: caesarxuchao: Restructure the body once we have a central `latest`. if g.Group == "" { - interfaces, err := latest.InterfacesFor(g.VersionUnderTest) + interfaces, err := latest.GroupOrDie("").InterfacesFor(g.GroupVersionUnderTest) if err != nil { panic(err) } return interfaces.Codec } - if g.Group == "experimental" { - interfaces, err := explatest.InterfacesFor(g.VersionUnderTest) + if g.Group == "extensions" { + interfaces, err := latest.GroupOrDie("extensions").InterfacesFor(g.GroupVersionUnderTest) if err != nil { panic(err) } @@ -109,14 +112,14 @@ func (g TestGroup) Codec() runtime.Codec { func (g TestGroup) Converter() runtime.ObjectConvertor { // TODO: caesarxuchao: Restructure the body once we have a central `latest`. if g.Group == "" { - interfaces, err := latest.InterfacesFor(g.VersionUnderTest) + interfaces, err := latest.GroupOrDie("").InterfacesFor(g.VersionUnderTest) if err != nil { panic(err) } return interfaces.ObjectConvertor } - if g.Group == "experimental" { - interfaces, err := explatest.InterfacesFor(g.VersionUnderTest) + if g.Group == "extensions" { + interfaces, err := latest.GroupOrDie("extensions").InterfacesFor(g.VersionUnderTest) if err != nil { panic(err) } @@ -131,14 +134,14 @@ func (g TestGroup) Converter() runtime.ObjectConvertor { func (g TestGroup) MetadataAccessor() meta.MetadataAccessor { // TODO: caesarxuchao: Restructure the body once we have a central `latest`. if g.Group == "" { - interfaces, err := latest.InterfacesFor(g.VersionUnderTest) + interfaces, err := latest.GroupOrDie("").InterfacesFor(g.VersionUnderTest) if err != nil { panic(err) } return interfaces.MetadataAccessor } - if g.Group == "experimental" { - interfaces, err := explatest.InterfacesFor(g.VersionUnderTest) + if g.Group == "extensions" { + interfaces, err := latest.GroupOrDie("extensions").InterfacesFor(g.VersionUnderTest) if err != nil { panic(err) } @@ -160,9 +163,9 @@ func (g TestGroup) SelfLink(resource, name string) string { // TODO: will need a /apis prefix once we have proper multi-group // support if name == "" { - return fmt.Sprintf("/%s/%s/%s", g.Group, g.Version(), resource) + return fmt.Sprintf("/apis/%s/%s/%s", g.Group, g.Version(), resource) } - return fmt.Sprintf("/%s/%s/%s/%s", g.Group, g.Version(), resource, name) + return fmt.Sprintf("/apis/%s/%s/%s/%s", g.Group, g.Version(), resource, name) } } @@ -176,7 +179,7 @@ func (g TestGroup) ResourcePathWithPrefix(prefix, resource, namespace, name stri } else { // TODO: switch back once we have proper multiple group support // path = "/apis/" + g.Group + "/" + Version(group...) - path = "/" + g.Group + "/" + g.Version() + path = "/apis/" + g.Group + "/" + g.Version() } if prefix != "" { @@ -202,3 +205,25 @@ func (g TestGroup) ResourcePathWithPrefix(prefix, resource, namespace, name stri func (g TestGroup) ResourcePath(resource, namespace, name string) string { return g.ResourcePathWithPrefix("", resource, namespace, name) } + +func (g TestGroup) RESTMapper() meta.RESTMapper { + return latest.GroupOrDie(g.Group).RESTMapper +} + +// Get codec based on runtime.Object +func GetCodecForObject(obj runtime.Object) (runtime.Codec, error) { + _, kind, err := api.Scheme.ObjectVersionAndKind(obj) + if err != nil { + return nil, fmt.Errorf("unexpected encoding error: %v", err) + } + // TODO: caesarxuchao: we should detect which group an object belongs to + // by using the version returned by Schem.ObjectVersionAndKind() once we + // split the schemes for internal objects. + // TODO: caesarxuchao: we should add a map from kind to group in Scheme. + for _, group := range Groups { + if api.Scheme.Recognizes(group.GroupAndVersion(), kind) { + return group.Codec(), nil + } + } + return nil, fmt.Errorf("unexpected kind: %v", kind) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/compat/compatibility_tester.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/compat/compatibility_tester.go new file mode 100644 index 000000000000..42314d186219 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/compat/compatibility_tester.go @@ -0,0 +1,144 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 compat + +import ( + "encoding/json" + "fmt" + "os" + "reflect" + "regexp" + "strconv" + "strings" + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/fielderrors" + + "k8s.io/kubernetes/pkg/kubectl" +) + +// Based on: https://github.com/openshift/origin/blob/master/pkg/api/compatibility_test.go +// +// TestCompatibility reencodes the input using the codec for the given +// version and checks for the presence of the expected keys and absent +// keys in the resulting JSON. +func TestCompatibility( + t *testing.T, + version string, + input []byte, + validator func(obj runtime.Object) fielderrors.ValidationErrorList, + expectedKeys map[string]string, + absentKeys []string, +) { + + // Decode + codec := runtime.CodecFor(api.Scheme, version) + obj, err := codec.Decode(input) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // Validate + errs := validator(obj) + if len(errs) != 0 { + t.Fatalf("Unexpected validation errors: %v", errs) + } + + // Encode + output, err := codec.Encode(obj) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // Validate old and new fields are encoded + generic := map[string]interface{}{} + if err := json.Unmarshal(output, &generic); err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + hasError := false + for k, expectedValue := range expectedKeys { + keys := strings.Split(k, ".") + if actualValue, ok, err := getJSONValue(generic, keys...); err != nil || !ok { + t.Errorf("Unexpected error for %s: %v", k, err) + hasError = true + } else if !reflect.DeepEqual(expectedValue, fmt.Sprintf("%v", actualValue)) { + hasError = true + t.Errorf("Unexpected value for %v: expected %v, got %v", k, expectedValue, actualValue) + } + } + + for _, absentKey := range absentKeys { + keys := strings.Split(absentKey, ".") + actualValue, ok, err := getJSONValue(generic, keys...) + if err == nil || ok { + t.Errorf("Unexpected value found for for key %s: %v", absentKey, actualValue) + hasError = true + } + } + + if hasError { + printer := new(kubectl.JSONPrinter) + printer.PrintObj(obj, os.Stdout) + t.Logf("2: Encoded value: %#v", string(output)) + } +} + +func getJSONValue(data map[string]interface{}, keys ...string) (interface{}, bool, error) { + // No keys, current value is it + if len(keys) == 0 { + return data, true, nil + } + + // Get the key (and optional index) + key := keys[0] + index := -1 + if matches := regexp.MustCompile(`^(.*)\[(\d+)\]$`).FindStringSubmatch(key); len(matches) > 0 { + key = matches[1] + index, _ = strconv.Atoi(matches[2]) + } + + // Look up the value + value, ok := data[key] + if !ok { + return nil, false, fmt.Errorf("No key %s found", key) + } + + // Get the indexed value if an index is specified + if index >= 0 { + valueSlice, ok := value.([]interface{}) + if !ok { + return nil, false, fmt.Errorf("Key %s did not hold a slice", key) + } + if index >= len(valueSlice) { + return nil, false, fmt.Errorf("Index %d out of bounds for slice at key: %v", index, key) + } + value = valueSlice[index] + } + + if len(keys) == 1 { + return value, true, nil + } + + childData, ok := value.(map[string]interface{}) + if !ok { + return nil, false, fmt.Errorf("Key %s did not hold a map", keys[0]) + } + return getJSONValue(childData, keys[1:]...) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/fuzzer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/fuzzer.go index 977ba118555f..7b9385fe9d38 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/fuzzer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/fuzzer.go @@ -27,7 +27,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/registered" "k8s.io/kubernetes/pkg/api/resource" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" @@ -54,7 +55,7 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { j.APIVersion = "" j.Kind = "" }, - func(j *api.TypeMeta, c fuzz.Continue) { + func(j *unversioned.TypeMeta, c fuzz.Continue) { // We have to customize the randomization of TypeMetas because their // APIVersion and Kind must remain blank in memory. j.APIVersion = "" @@ -70,7 +71,7 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { var sec, nsec int64 c.Fuzz(&sec) c.Fuzz(&nsec) - j.CreationTimestamp = util.Unix(sec, nsec).Rfc3339Copy() + j.CreationTimestamp = unversioned.Unix(sec, nsec).Rfc3339Copy() }, func(j *api.ObjectReference, c fuzz.Continue) { // We have to customize the randomization of TypeMetas because their @@ -82,7 +83,7 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) j.FieldPath = c.RandString() }, - func(j *api.ListMeta, c fuzz.Continue) { + func(j *unversioned.ListMeta, c fuzz.Continue) { j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) j.SelfLink = c.RandString() }, @@ -91,14 +92,18 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { j.LabelSelector, _ = labels.Parse("a=b") j.FieldSelector, _ = fields.ParseSelector("a=b") }, - func(j *api.PodSpec, c fuzz.Continue) { - c.FuzzNoCustom(j) + func(s *api.PodSpec, c fuzz.Continue) { + c.FuzzNoCustom(s) // has a default value ttl := int64(30) if c.RandBool() { ttl = int64(c.Uint32()) } - j.TerminationGracePeriodSeconds = &ttl + s.TerminationGracePeriodSeconds = &ttl + + if s.SecurityContext == nil { + s.SecurityContext = &api.PodSecurityContext{} + } }, func(j *api.PodPhase, c fuzz.Continue) { statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown} @@ -121,15 +126,15 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { c.FuzzNoCustom(j) // fuzz self without calling this function again //j.TemplateRef = nil // this is required for round trip }, - func(j *experimental.DeploymentStrategy, c fuzz.Continue) { + func(j *extensions.DeploymentStrategy, c fuzz.Continue) { c.FuzzNoCustom(j) // fuzz self without calling this function again // Ensure that strategyType is one of valid values. - strategyTypes := []experimental.DeploymentType{experimental.DeploymentRecreate, experimental.DeploymentRollingUpdate} + strategyTypes := []extensions.DeploymentStrategyType{extensions.RecreateDeploymentStrategyType, extensions.RollingUpdateDeploymentStrategyType} j.Type = strategyTypes[c.Rand.Intn(len(strategyTypes))] - if j.Type != experimental.DeploymentRollingUpdate { + if j.Type != extensions.RollingUpdateDeploymentStrategyType { j.RollingUpdate = nil } else { - rollingUpdate := experimental.RollingUpdateDeployment{} + rollingUpdate := extensions.RollingUpdateDeployment{} if c.RandBool() { rollingUpdate.MaxUnavailable = util.NewIntOrStringFromInt(int(c.RandUint64())) rollingUpdate.MaxSurge = util.NewIntOrStringFromInt(int(c.RandUint64())) @@ -139,6 +144,13 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { j.RollingUpdate = &rollingUpdate } }, + func(j *extensions.JobSpec, c fuzz.Continue) { + c.FuzzNoCustom(j) // fuzz self without calling this function again + completions := c.Rand.Int() + parallelism := c.Rand.Int() + j.Completions = &completions + j.Parallelism = ¶llelism + }, func(j *api.List, c fuzz.Continue) { c.FuzzNoCustom(j) // fuzz self without calling this function again // TODO: uncomment when round trip starts from a versioned object @@ -351,22 +363,11 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { c.FuzzNoCustom(n) n.Spec.ExternalID = "external" }, - func(s *experimental.APIVersion, c fuzz.Continue) { + func(s *extensions.APIVersion, c fuzz.Continue) { // We can't use c.RandString() here because it may generate empty // string, which will cause tests failure. s.APIGroup = "something" }, - func(scc *api.SecurityContextConstraints, c fuzz.Continue) { - c.FuzzNoCustom(scc) // fuzz self without calling this function again - userTypes := []api.RunAsUserStrategyType{api.RunAsUserStrategyMustRunAsNonRoot, api.RunAsUserStrategyMustRunAs, api.RunAsUserStrategyRunAsAny, api.RunAsUserStrategyMustRunAsRange} - scc.RunAsUser.Type = userTypes[c.Rand.Intn(len(userTypes))] - seLinuxTypes := []api.SELinuxContextStrategyType{api.SELinuxStrategyRunAsAny, api.SELinuxStrategyMustRunAs} - scc.SELinuxContext.Type = seLinuxTypes[c.Rand.Intn(len(seLinuxTypes))] - supGroupTypes := []api.SupplementalGroupsStrategyType{api.SupplementalGroupsStrategyMustRunAs, api.SupplementalGroupsStrategyMustRunAs} - scc.SupplementalGroups.Type = supGroupTypes[c.Rand.Intn(len(supGroupTypes))] - fsGroupTypes := []api.FSGroupStrategyType{api.FSGroupStrategyMustRunAs, api.FSGroupStrategyRunAsAny} - scc.FSGroup.Type = fsGroupTypes[c.Rand.Intn(len(fsGroupTypes))] - }, ) return f } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/pod_specs.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/pod_specs.go new file mode 100644 index 000000000000..2020b3f7fb0e --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/pod_specs.go @@ -0,0 +1,32 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 testing + +import ( + "k8s.io/kubernetes/pkg/api" +) + +// DeepEqualSafePodSpec returns a PodSpec which is ready to be used with api.Semantic.DeepEqual +func DeepEqualSafePodSpec() api.PodSpec { + grace := int64(30) + return api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + TerminationGracePeriodSeconds: &grace, + SecurityContext: &api.PodSecurityContext{}, + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go index 0e03869d330b..35aadf2f5a49 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go @@ -18,6 +18,7 @@ package api import ( "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" @@ -54,33 +55,6 @@ import ( // Hypens ('-') cannot be leading or trailing character of the string // and cannot be adjacent to other hyphens. -// TypeMeta describes an individual object in an API response or request -// with strings representing the type of the object and its API schema version. -// Structures that are versioned or persisted should inline TypeMeta. -type TypeMeta struct { - // Kind is a string value representing the REST resource this object represents. - // Servers may infer this from the endpoint the client submits requests to. - Kind string `json:"kind,omitempty"` - - // APIVersion defines the versioned schema of this representation of an object. - // Servers should convert recognized schemas to the latest internal value, and - // may reject unrecognized values. - APIVersion string `json:"apiVersion,omitempty"` -} - -// ListMeta describes metadata that synthetic resources must have, including lists and -// various status objects. A resource may have only one of {ObjectMeta, ListMeta}. -type ListMeta struct { - // SelfLink is a URL representing this object. - SelfLink string `json:"selfLink,omitempty"` - - // An opaque value that represents the version of this response for use with optimistic - // concurrency and change monitoring endpoints. Clients must treat these values as opaque - // and values may only be valid for a particular resource or set of resources. Only servers - // will generate resource versions. - ResourceVersion string `json:"resourceVersion,omitempty"` -} - // ObjectMeta is metadata that all persisted resources must have, which includes all objects // users must create. type ObjectMeta struct { @@ -130,7 +104,7 @@ type ObjectMeta struct { // CreationTimestamp is a timestamp representing the server time when this object was // created. It is not guaranteed to be set in happens-before order across separate operations. // Clients may not set this value. It is represented in RFC3339 form and is in UTC. - CreationTimestamp util.Time `json:"creationTimestamp,omitempty"` + CreationTimestamp unversioned.Time `json:"creationTimestamp,omitempty"` // DeletionTimestamp is the time after which this resource will be deleted. This // field is set by the server when a graceful deletion is requested by the user, and is not @@ -141,7 +115,7 @@ type ObjectMeta struct { // a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination // signal to the containers in the pod. Once the resource is deleted in the API, the Kubelet // will send a hard termination signal to the container. - DeletionTimestamp *util.Time `json:"deletionTimestamp,omitempty"` + DeletionTimestamp *unversioned.Time `json:"deletionTimestamp,omitempty"` // DeletionGracePeriodSeconds records the graceful deletion value set when graceful deletion // was requested. Represents the most recent grace period, and may only be shortened once set. @@ -230,8 +204,13 @@ type VolumeSource struct { // CephFS represents a Cephfs mount on the host that shares a pod's lifetime CephFS *CephFSVolumeSource `json:"cephfs,omitempty"` + // Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running + Flocker *FlockerVolumeSource `json:"flocker,omitempty"` + // DownwardAPI represents metadata about the pod that should populate this volume DownwardAPI *DownwardAPIVolumeSource `json:"downwardAPI,omitempty"` + // FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + FC *FCVolumeSource `json:"fc,omitempty"` } // Similar to VolumeSource but meant for the administrator who creates PVs. @@ -244,8 +223,9 @@ type PersistentVolumeSource struct { // kubelet's host machine and then exposed to the pod. AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty"` // HostPath represents a directory on the host. - // This is useful for development and testing only. - // on-host storage is not supported in any way + // Provisioned by a developer or tester. + // This is useful for single-node development and testing only! + // On-host storage is not supported in any way and WILL NOT WORK in a multi-node cluster. HostPath *HostPathVolumeSource `json:"hostPath,omitempty"` // Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod Glusterfs *GlusterfsVolumeSource `json:"glusterfs,omitempty"` @@ -260,6 +240,10 @@ type PersistentVolumeSource struct { Cinder *CinderVolumeSource `json:"cinder,omitempty"` // CephFS represents a Ceph FS mount on the host that shares a pod's lifetime CephFS *CephFSVolumeSource `json:"cephfs,omitempty"` + // FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + FC *FCVolumeSource `json:"fc,omitempty"` + // Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running + Flocker *FlockerVolumeSource `json:"flocker,omitempty"` } type PersistentVolumeClaimVolumeSource struct { @@ -271,8 +255,8 @@ type PersistentVolumeClaimVolumeSource struct { } type PersistentVolume struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` //Spec defines a persistent volume owned by the cluster Spec PersistentVolumeSpec `json:"spec,omitempty"` @@ -303,12 +287,9 @@ const ( // PersistentVolumeReclaimRecycle means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim. // The volume plugin must support Recycling. PersistentVolumeReclaimRecycle PersistentVolumeReclaimPolicy = "Recycle" - // PersistentVolumeReclaimDelete means the volume will be deleted from Kubernetes on release from its claim. // The volume plugin must support Deletion. - // TODO: implement w/ DeletableVolumePlugin - // PersistentVolumeReclaimDelete PersistentVolumeReclaimPolicy = "Delete" - + PersistentVolumeReclaimDelete PersistentVolumeReclaimPolicy = "Delete" // PersistentVolumeReclaimRetain means the volume will left in its current phase (Released) for manual reclamation by the administrator. // The default policy is Retain. PersistentVolumeReclaimRetain PersistentVolumeReclaimPolicy = "Retain" @@ -324,15 +305,15 @@ type PersistentVolumeStatus struct { } type PersistentVolumeList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` - Items []PersistentVolume `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []PersistentVolume `json:"items"` } // PersistentVolumeClaim is a user's request for and claim to a persistent volume type PersistentVolumeClaim struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Spec defines the volume requested by a pod author Spec PersistentVolumeClaimSpec `json:"spec,omitempty"` @@ -342,9 +323,9 @@ type PersistentVolumeClaim struct { } type PersistentVolumeClaimList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` - Items []PersistentVolumeClaim `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []PersistentVolumeClaim `json:"items"` } // PersistentVolumeClaimSpec describes the common attributes of storage devices @@ -480,6 +461,22 @@ type ISCSIVolumeSource struct { ReadOnly bool `json:"readOnly,omitempty"` } +// A Fibre Channel Disk can only be mounted as read/write once. +type FCVolumeSource struct { + // Required: FC target world wide names (WWNs) + TargetWWNs []string `json:"targetWWNs"` + // Required: FC target lun number + Lun *int `json:"lun"` + // Required: Filesystem type to mount. + // Must be a filesystem type supported by the host operating system. + // Ex. "ext4", "xfs", "ntfs" + // TODO: how do we prevent errors in the filesystem from compromising the machine + FSType string `json:"fsType"` + // Optional: Defaults to false (read/write). ReadOnly here will force + // the ReadOnly setting in VolumeMounts. + ReadOnly bool `json:"readOnly,omitempty"` +} + // AWSElasticBlockStoreVolumeSource represents a Persistent Disk resource in AWS. // // An AWS EBS disk must exist and be formatted before mounting to a container. @@ -600,6 +597,12 @@ type CephFSVolumeSource struct { ReadOnly bool `json:"readOnly,omitempty"` } +// FlockerVolumeSource represents a Flocker volume mounted by the Flocker agent. +type FlockerVolumeSource struct { + // Required: the volume name. This is going to be store on metadata -> name on the payload for Flocker + DatasetName string `json:"datasetName"` +} + // DownwardAPIVolumeSource represents a volume containing downward API info type DownwardAPIVolumeSource struct { // Items is a list of DownwardAPIVolume file @@ -842,17 +845,17 @@ type ContainerStateWaiting struct { } type ContainerStateRunning struct { - StartedAt util.Time `json:"startedAt,omitempty"` + StartedAt unversioned.Time `json:"startedAt,omitempty"` } type ContainerStateTerminated struct { - ExitCode int `json:"exitCode"` - Signal int `json:"signal,omitempty"` - Reason string `json:"reason,omitempty"` - Message string `json:"message,omitempty"` - StartedAt util.Time `json:"startedAt,omitempty"` - FinishedAt util.Time `json:"finishedAt,omitempty"` - ContainerID string `json:"containerID,omitempty"` + ExitCode int `json:"exitCode"` + Signal int `json:"signal,omitempty"` + Reason string `json:"reason,omitempty"` + Message string `json:"message,omitempty"` + StartedAt unversioned.Time `json:"startedAt,omitempty"` + FinishedAt unversioned.Time `json:"finishedAt,omitempty"` + ContainerID string `json:"containerID,omitempty"` } // ContainerState holds a possible state of container. @@ -911,10 +914,13 @@ const ( PodReady PodConditionType = "Ready" ) -// TODO: add LastTransitionTime, Reason, Message to match NodeCondition api. type PodCondition struct { - Type PodConditionType `json:"type"` - Status ConditionStatus `json:"status"` + Type PodConditionType `json:"type"` + Status ConditionStatus `json:"status"` + LastProbeTime unversioned.Time `json:"lastProbeTime,omitempty"` + LastTransitionTime unversioned.Time `json:"lastTransitionTime,omitempty"` + Reason string `json:"reason,omitempty"` + Message string `json:"message,omitempty"` } // RestartPolicy describes how the container should be restarted. @@ -931,8 +937,8 @@ const ( // PodList is a list of Pods. type PodList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []Pod `json:"items"` } @@ -980,20 +986,27 @@ type PodSpec struct { // the scheduler simply schedules this pod onto that node, assuming that it fits resource // requirements. NodeName string `json:"nodeName,omitempty"` - // Use the host's network namespace. If this option is set, the ports that will be + // SecurityContext holds pod-level security attributes and common container settings + SecurityContext *PodSecurityContext `json:"securityContext,omitempty"` + // ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + // If specified, these secrets will be passed to individual puller implementations for them to use. For example, + // in the case of docker, only DockerConfig type secrets are honored. + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty"` +} + +// PodSecurityContext holds pod-level security attributes and common container settings. +type PodSecurityContext struct { + // Use the host's network namespace. If this option is set, the ports that will be // used must be specified. - // Optional: Default to false. + // Optional: Default to false HostNetwork bool `json:"hostNetwork,omitempty"` + // Use the host's pid namespace. // Optional: Default to false. HostPID bool `json:"hostPID,omitempty"` // Use the host's ipc namespace. // Optional: Default to false. HostIPC bool `json:"hostIPC,omitempty"` - // ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. - // If specified, these secrets will be passed to individual puller implementations for them to use. For example, - // in the case of docker, only DockerConfig type secrets are honored. - ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty"` } // PodStatus represents information about the status of a pod. Status may trail the actual @@ -1011,7 +1024,7 @@ type PodStatus struct { // Date and time at which the object was acknowledged by the Kubelet. // This is before the Kubelet pulled the container image(s) for the pod. - StartTime *util.Time `json:"startTime,omitempty"` + StartTime *unversioned.Time `json:"startTime,omitempty"` // The list has one entry per container in the manifest. Each entry is // currently the output of `docker inspect`. This output format is *not* @@ -1023,8 +1036,8 @@ type PodStatus struct { // PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded type PodStatusResult struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Status represents the current information about a pod. This data may not be up // to date. Status PodStatus `json:"status,omitempty"` @@ -1032,8 +1045,8 @@ type PodStatusResult struct { // Pod is a collection of containers, used as either input (create, update) or as output (list, get). type Pod struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Spec defines the behavior of a pod. Spec PodSpec `json:"spec,omitempty"` @@ -1054,8 +1067,8 @@ type PodTemplateSpec struct { // PodTemplate describes a template for creating copies of a predefined pod. type PodTemplate struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Template defines the pods that will be created from this pod template Template PodTemplateSpec `json:"template,omitempty"` @@ -1063,8 +1076,8 @@ type PodTemplate struct { // PodTemplateList is a list of PodTemplates. type PodTemplateList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []PodTemplate `json:"items"` } @@ -1103,8 +1116,8 @@ type ReplicationControllerStatus struct { // ReplicationController represents the configuration of a replication controller. type ReplicationController struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Spec defines the desired behavior of this replication controller. Spec ReplicationControllerSpec `json:"spec,omitempty"` @@ -1116,8 +1129,8 @@ type ReplicationController struct { // ReplicationControllerList is a collection of replication controllers. type ReplicationControllerList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []ReplicationController `json:"items"` } @@ -1130,8 +1143,8 @@ const ( // ServiceList holds a list of services. type ServiceList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []Service `json:"items"` } @@ -1254,8 +1267,8 @@ type ServicePort struct { // (for example 3306) that the proxy listens on, and the selector that determines which pods // will answer requests sent through the proxy. type Service struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Spec defines the behavior of a service. Spec ServiceSpec `json:"spec,omitempty"` @@ -1269,8 +1282,8 @@ type Service struct { // * a principal that can be authenticated and authorized // * a set of secrets type ServiceAccount struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount Secrets []ObjectReference `json:"secrets"` @@ -1283,8 +1296,8 @@ type ServiceAccount struct { // ServiceAccountList is a list of ServiceAccount objects type ServiceAccountList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []ServiceAccount `json:"items"` } @@ -1302,8 +1315,8 @@ type ServiceAccountList struct { // }, // ] type Endpoints struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // The set of all endpoints is the union of all subsets. Subsets []EndpointSubset @@ -1320,8 +1333,9 @@ type Endpoints struct { // a: [ 10.10.1.1:8675, 10.10.2.2:8675 ], // b: [ 10.10.1.1:309, 10.10.2.2:309 ] type EndpointSubset struct { - Addresses []EndpointAddress - Ports []EndpointPort + Addresses []EndpointAddress + NotReadyAddresses []EndpointAddress + Ports []EndpointPort } // EndpointAddress is a tuple that describes single IP address. @@ -1349,8 +1363,8 @@ type EndpointPort struct { // EndpointsList is a list of endpoints. type EndpointsList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []Endpoints `json:"items"` } @@ -1372,23 +1386,35 @@ type NodeSpec struct { Unschedulable bool `json:"unschedulable,omitempty"` } +// DaemonEndpoint contains information about a single Daemon endpoint. +type DaemonEndpoint struct { + // Port number of the given endpoint. + Port int `json:port` +} + +// NodeDaemonEndpoints lists ports opened by daemons running on the Node. +type NodeDaemonEndpoints struct { + // Endpoint on which Kubelet is listening. + KubeletEndpoint DaemonEndpoint `json:"kubeletEndpoint,omitempty"` +} + // NodeSystemInfo is a set of ids/uuids to uniquely identify the node. type NodeSystemInfo struct { - // MachineID is the machine-id reported by the node + // Machine ID reported by the node. MachineID string `json:"machineID"` - // SystemUUID is the system-uuid reported by the node + // System UUID reported by the node. SystemUUID string `json:"systemUUID"` - // BootID is the boot-id reported by the node + // Boot ID reported by the node. BootID string `json:"bootID"` - // Kernel version reported by the node + // Kernel Version reported by the node. KernelVersion string `json:"kernelVersion"` - // OS image used reported by the node + // OS Image reported by the node. OsImage string `json:"osImage"` - // Container runtime version reported by the node + // ContainerRuntime Version reported by the node. ContainerRuntimeVersion string `json:"containerRuntimeVersion"` - // Kubelet version reported by the node + // Kubelet Version reported by the node. KubeletVersion string `json:"kubeletVersion"` - // Kube-proxy version reported by the node + // KubeProxy Version reported by the node. KubeProxyVersion string `json:"kubeProxyVersion"` } @@ -1402,7 +1428,9 @@ type NodeStatus struct { Conditions []NodeCondition `json:"conditions,omitempty"` // Queried from cloud provider, if available. Addresses []NodeAddress `json:"addresses,omitempty"` - // NodeSystemInfo is a set of ids/uuids to uniquely identify the node + // Endpoints of daemons running on the Node. + DaemonEndpoints NodeDaemonEndpoints `json:"daemonEndpoints,omitempty"` + // Set of ids/uuids to uniquely identify the node. NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty"` } @@ -1431,8 +1459,8 @@ const ( type NodeCondition struct { Type NodeConditionType `json:"type"` Status ConditionStatus `json:"status"` - LastHeartbeatTime util.Time `json:"lastHeartbeatTime,omitempty"` - LastTransitionTime util.Time `json:"lastTransitionTime,omitempty"` + LastHeartbeatTime unversioned.Time `json:"lastHeartbeatTime,omitempty"` + LastTransitionTime unversioned.Time `json:"lastTransitionTime,omitempty"` Reason string `json:"reason,omitempty"` Message string `json:"message,omitempty"` } @@ -1454,7 +1482,7 @@ type NodeAddress struct { } // NodeResources is an object for conveying resource information about a node. -// see http://docs.k8s.io/design/resources.md for more details. +// see http://releases.k8s.io/HEAD/docs/design/resources.md for more details. type NodeResources struct { // Capacity represents the available resources of a node Capacity ResourceList `json:"capacity,omitempty"` @@ -1479,8 +1507,8 @@ type ResourceList map[ResourceName]resource.Quantity // Node is a worker node in Kubernetes // The name of the node according to etcd is in ObjectMeta.Name. type Node struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Spec defines the behavior of a node. Spec NodeSpec `json:"spec,omitempty"` @@ -1491,8 +1519,8 @@ type Node struct { // NodeList is a list of nodes. type NodeList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []Node `json:"items"` } @@ -1529,8 +1557,8 @@ const ( // A namespace provides a scope for Names. // Use of multiple namespaces is optional type Namespace struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Spec defines the behavior of the Namespace. Spec NamespaceSpec `json:"spec,omitempty"` @@ -1541,15 +1569,15 @@ type Namespace struct { // NamespaceList is a list of Namespaces. type NamespaceList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []Namespace `json:"items"` } // Binding ties one object to another - for example, a pod is bound to a node by a scheduler. type Binding struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // ObjectMeta describes the object that is being bound. ObjectMeta `json:"metadata,omitempty"` @@ -1559,7 +1587,7 @@ type Binding struct { // DeleteOptions may be provided when deleting an API object type DeleteOptions struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Optional duration in seconds before the object should be deleted. Value must be non-negative integer. // The value zero indicates delete immediately. If this value is nil, the default grace period for the @@ -1570,7 +1598,7 @@ type DeleteOptions struct { // ListOptions is the query options to a standard REST list call, and has future support for // watch calls. type ListOptions struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // A selector based on labels LabelSelector labels.Selector @@ -1584,22 +1612,40 @@ type ListOptions struct { // PodLogOptions is the query options for a Pod's logs REST call type PodLogOptions struct { - TypeMeta + unversioned.TypeMeta // Container for which to return logs Container string - // If true, follow the logs for the pod Follow bool - // If true, return previous terminated container logs Previous bool + // A relative time in seconds before the current time from which to show logs. If this value + // precedes the time a pod was started, only logs since the pod start will be returned. + // If this value is in the future, no logs will be returned. + // Only one of sinceSeconds or sinceTime may be specified. + SinceSeconds *int64 + // An RFC3339 timestamp from which to show logs. If this value + // preceeds the time a pod was started, only logs since the pod start will be returned. + // If this value is in the future, no logs will be returned. + // Only one of sinceSeconds or sinceTime may be specified. + SinceTime *unversioned.Time + // If true, add an RFC3339 or RFC3339Nano timestamp at the beginning of every line + // of log output. + Timestamps bool + // If set, the number of lines from the end of the logs to show. If not specified, + // logs are shown from the creation of the container or sinceSeconds or sinceTime + TailLines *int64 + // If set, the number of bytes to read from the server before terminating the + // log output. This may not display a complete final line of logging, and may return + // slightly more or slightly less than the specified limit. + LimitBytes *int64 } // PodAttachOptions is the query options to a Pod's remote attach call // TODO: merge w/ PodExecOptions below for stdin, stdout, etc type PodAttachOptions struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Stdin if true indicates that stdin is to be redirected for the attach call Stdin bool `json:"stdin,omitempty"` @@ -1619,7 +1665,7 @@ type PodAttachOptions struct { // PodExecOptions is the query options to a Pod's remote exec call type PodExecOptions struct { - TypeMeta + unversioned.TypeMeta // Stdin if true indicates that stdin is to be redirected for the exec call Stdin bool @@ -1642,225 +1688,12 @@ type PodExecOptions struct { // PodProxyOptions is the query options to a Pod's proxy call type PodProxyOptions struct { - TypeMeta + unversioned.TypeMeta // Path is the URL path to use for the current proxy request Path string } -// Status is a return value for calls that don't return other objects. -// TODO: this could go in apiserver, but I'm including it here so clients needn't -// import both. -type Status struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` - - // One of: "Success" or "Failure" - Status string `json:"status,omitempty"` - // A human-readable description of the status of this operation. - Message string `json:"message,omitempty"` - // A machine-readable description of why this operation is in the - // "Failure" status. If this value is empty there - // is no information available. A Reason clarifies an HTTP status - // code but does not override it. - Reason StatusReason `json:"reason,omitempty"` - // Extended data associated with the reason. Each reason may define its - // own extended details. This field is optional and the data returned - // is not guaranteed to conform to any schema except that defined by - // the reason type. - Details *StatusDetails `json:"details,omitempty"` - // Suggested HTTP return code for this status, 0 if not set. - Code int `json:"code,omitempty"` -} - -// StatusDetails is a set of additional properties that MAY be set by the -// server to provide additional information about a response. The Reason -// field of a Status object defines what attributes will be set. Clients -// must ignore fields that do not match the defined type of each attribute, -// and should assume that any attribute may be empty, invalid, or under -// defined. -type StatusDetails struct { - // The name attribute of the resource associated with the status StatusReason - // (when there is a single name which can be described). - Name string `json:"name,omitempty"` - // The kind attribute of the resource associated with the status StatusReason. - // On some operations may differ from the requested resource Kind. - Kind string `json:"kind,omitempty"` - // The Causes array includes more details associated with the StatusReason - // failure. Not all StatusReasons may provide detailed causes. - Causes []StatusCause `json:"causes,omitempty"` - // If specified, the time in seconds before the operation should be retried. - RetryAfterSeconds int `json:"retryAfterSeconds,omitempty"` -} - -// Values of Status.Status -const ( - StatusSuccess = "Success" - StatusFailure = "Failure" -) - -// StatusReason is an enumeration of possible failure causes. Each StatusReason -// must map to a single HTTP status code, but multiple reasons may map -// to the same HTTP status code. -// TODO: move to apiserver -type StatusReason string - -const ( - // StatusReasonUnknown means the server has declined to indicate a specific reason. - // The details field may contain other information about this error. - // Status code 500. - StatusReasonUnknown StatusReason = "" - - // StatusReasonUnauthorized means the server can be reached and understood the request, but requires - // the user to present appropriate authorization credentials (identified by the WWW-Authenticate header) - // in order for the action to be completed. If the user has specified credentials on the request, the - // server considers them insufficient. - // Status code 401 - StatusReasonUnauthorized StatusReason = "Unauthorized" - - // StatusReasonForbidden means the server can be reached and understood the request, but refuses - // to take any further action. It is the result of the server being configured to deny access for some reason - // to the requested resource by the client. - // Details (optional): - // "kind" string - the kind attribute of the forbidden resource - // on some operations may differ from the requested - // resource. - // "id" string - the identifier of the forbidden resource - // Status code 403 - StatusReasonForbidden StatusReason = "Forbidden" - - // StatusReasonNotFound means one or more resources required for this operation - // could not be found. - // Details (optional): - // "kind" string - the kind attribute of the missing resource - // on some operations may differ from the requested - // resource. - // "id" string - the identifier of the missing resource - // Status code 404 - StatusReasonNotFound StatusReason = "NotFound" - - // StatusReasonAlreadyExists means the resource you are creating already exists. - // Details (optional): - // "kind" string - the kind attribute of the conflicting resource - // "id" string - the identifier of the conflicting resource - // Status code 409 - StatusReasonAlreadyExists StatusReason = "AlreadyExists" - - // StatusReasonConflict means the requested update operation cannot be completed - // due to a conflict in the operation. The client may need to alter the request. - // Each resource may define custom details that indicate the nature of the - // conflict. - // Status code 409 - StatusReasonConflict StatusReason = "Conflict" - - // StatusReasonInvalid means the requested create or update operation cannot be - // completed due to invalid data provided as part of the request. The client may - // need to alter the request. When set, the client may use the StatusDetails - // message field as a summary of the issues encountered. - // Details (optional): - // "kind" string - the kind attribute of the invalid resource - // "id" string - the identifier of the invalid resource - // "causes" - one or more StatusCause entries indicating the data in the - // provided resource that was invalid. The code, message, and - // field attributes will be set. - // Status code 422 - StatusReasonInvalid StatusReason = "Invalid" - - // StatusReasonServerTimeout means the server can be reached and understood the request, - // but cannot complete the action in a reasonable time. The client should retry the request. - // This is may be due to temporary server load or a transient communication issue with - // another server. Status code 500 is used because the HTTP spec provides no suitable - // server-requested client retry and the 5xx class represents actionable errors. - // Details (optional): - // "kind" string - the kind attribute of the resource being acted on. - // "id" string - the operation that is being attempted. - // "retryAfterSeconds" int - the number of seconds before the operation should be retried - // Status code 500 - StatusReasonServerTimeout StatusReason = "ServerTimeout" - - // StatusReasonTimeout means that the request could not be completed within the given time. - // Clients can get this response only when they specified a timeout param in the request, - // or if the server cannot complete the operation within a reasonable amount of time. - // The request might succeed with an increased value of timeout param. The client *should* - // wait at least the number of seconds specified by the retryAfterSeconds field. - // Details (optional): - // "retryAfterSeconds" int - the number of seconds before the operation should be retried - // Status code 504 - StatusReasonTimeout StatusReason = "Timeout" - - // StatusReasonBadRequest means that the request itself was invalid, because the request - // doesn't make any sense, for example deleting a read-only object. This is different than - // StatusReasonInvalid above which indicates that the API call could possibly succeed, but the - // data was invalid. API calls that return BadRequest can never succeed. - StatusReasonBadRequest StatusReason = "BadRequest" - - // StatusReasonMethodNotAllowed means that the action the client attempted to perform on the - // resource was not supported by the code - for instance, attempting to delete a resource that - // can only be created. API calls that return MethodNotAllowed can never succeed. - StatusReasonMethodNotAllowed StatusReason = "MethodNotAllowed" - - // StatusReasonInternalError indicates that an internal error occurred, it is unexpected - // and the outcome of the call is unknown. - // Details (optional): - // "causes" - The original error - // Status code 500 - StatusReasonInternalError = "InternalError" - - // StatusReasonServiceUnavailable means that the request itself was valid, - // but the requested service is unavailable at this time. - // Retrying the request after some time might succeed. - // Status code 503 - StatusReasonServiceUnavailable StatusReason = "ServiceUnavailable" -) - -// StatusCause provides more information about an api.Status failure, including -// cases when multiple errors are encountered. -type StatusCause struct { - // A machine-readable description of the cause of the error. If this value is - // empty there is no information available. - Type CauseType `json:"reason,omitempty"` - // A human-readable description of the cause of the error. This field may be - // presented as-is to a reader. - Message string `json:"message,omitempty"` - // The field of the resource that has caused this error, as named by its JSON - // serialization. May include dot and postfix notation for nested attributes. - // Arrays are zero-indexed. Fields may appear more than once in an array of - // causes due to fields having multiple errors. - // Optional. - // - // Examples: - // "name" - the field "name" on the current resource - // "items[0].name" - the field "name" on the first array entry in "items" - Field string `json:"field,omitempty"` -} - -// CauseType is a machine readable value providing more detail about what -// occurred in a status response. An operation may have multiple causes for a -// status (whether Failure or Success). -type CauseType string - -const ( - // CauseTypeFieldValueNotFound is used to report failure to find a requested value - // (e.g. looking up an ID). - CauseTypeFieldValueNotFound CauseType = "FieldValueNotFound" - // CauseTypeFieldValueRequired is used to report required values that are not - // provided (e.g. empty strings, null values, or empty arrays). - CauseTypeFieldValueRequired CauseType = "FieldValueRequired" - // CauseTypeFieldValueDuplicate is used to report collisions of values that must be - // unique (e.g. unique IDs). - CauseTypeFieldValueDuplicate CauseType = "FieldValueDuplicate" - // CauseTypeFieldValueInvalid is used to report malformed values (e.g. failed regex - // match). - CauseTypeFieldValueInvalid CauseType = "FieldValueInvalid" - // CauseTypeFieldValueNotSupported is used to report valid (as per formatting rules) - // values that can not be handled (e.g. an enumerated string). - CauseTypeFieldValueNotSupported CauseType = "FieldValueNotSupported" - // CauseTypeUnexpectedServerResponse is used to report when the server responded to the client - // without the expected return type. The presence of this cause indicates the error may be - // due to an intervening proxy or the server software malfunctioning. - CauseTypeUnexpectedServerResponse CauseType = "UnexpectedServerResponse" -) - // ObjectReference contains enough information to let you inspect or modify the referred object. type ObjectReference struct { Kind string `json:"kind,omitempty"` @@ -1888,8 +1721,8 @@ type LocalObjectReference struct { } type SerializedReference struct { - TypeMeta `json:",inline"` - Reference ObjectReference `json:"reference,omitempty"` + unversioned.TypeMeta `json:",inline"` + Reference ObjectReference `json:"reference,omitempty"` } type EventSource struct { @@ -1902,8 +1735,8 @@ type EventSource struct { // Event is a report of an event somewhere in the cluster. // TODO: Decide whether to store these separately or with the object they apply to. type Event struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Required. The object that this event is about. InvolvedObject ObjectReference `json:"involvedObject,omitempty"` @@ -1922,10 +1755,10 @@ type Event struct { Source EventSource `json:"source,omitempty"` // The time at which the event was first recorded. (Time of server receipt is in TypeMeta.) - FirstTimestamp util.Time `json:"firstTimestamp,omitempty"` + FirstTimestamp unversioned.Time `json:"firstTimestamp,omitempty"` // The time at which the most recent occurrence of this event was recorded. - LastTimestamp util.Time `json:"lastTimestamp,omitempty"` + LastTimestamp unversioned.Time `json:"lastTimestamp,omitempty"` // The number of times this event has occurred. Count int `json:"count,omitempty"` @@ -1933,16 +1766,16 @@ type Event struct { // EventList is a list of events. type EventList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []Event `json:"items"` } // List holds a list of objects, which may not be known by the server. type List struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []runtime.Object `json:"items"` } @@ -1981,8 +1814,8 @@ type LimitRangeSpec struct { // LimitRange sets resource usage limits for each kind of resource in a Namespace type LimitRange struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Spec defines the limits enforced Spec LimitRangeSpec `json:"spec,omitempty"` @@ -1990,8 +1823,8 @@ type LimitRange struct { // LimitRangeList is a list of LimitRange items. type LimitRangeList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of LimitRange objects Items []LimitRange `json:"items"` @@ -2029,8 +1862,8 @@ type ResourceQuotaStatus struct { // ResourceQuota sets aggregate quota restrictions enforced per namespace type ResourceQuota struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Spec defines the desired quota Spec ResourceQuotaSpec `json:"spec,omitempty"` @@ -2041,8 +1874,8 @@ type ResourceQuota struct { // ResourceQuotaList is a list of ResourceQuota items type ResourceQuotaList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of ResourceQuota objects Items []ResourceQuota `json:"items"` @@ -2051,8 +1884,8 @@ type ResourceQuotaList struct { // Secret holds secret data of a certain type. The total bytes of the values in // the Data field must be less than MaxSecretSize bytes. type Secret struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // Data contains the secret data. Each key must be a valid DNS_SUBDOMAIN // or leading dot followed by valid DNS_SUBDOMAIN. @@ -2099,11 +1932,20 @@ const ( // DockerConfigKey is the key of the required data for SecretTypeDockercfg secrets DockerConfigKey = ".dockercfg" + + // SecretTypeDockerConfigJson contains a dockercfg file that follows the same format rules as ~/.docker/config.json + // + // Required fields: + // - Secret.Data[".dockerconfigjson"] - a serialized ~/.docker/config.json file + SecretTypeDockerConfigJson SecretType = "kubernetes.io/dockerconfigjson" + + // DockerConfigJsonKey is the key of the required data for SecretTypeDockerConfigJson secrets + DockerConfigJsonKey = ".dockerconfigjson" ) type SecretList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []Secret `json:"items"` } @@ -2127,14 +1969,24 @@ const ( // Command to run for remote command execution ExecCommandParamm = "command" - StreamType = "streamType" - StreamTypeStdin = "stdin" + // Name of header that specifies stream type + StreamType = "streamType" + // Value for streamType header for stdin stream + StreamTypeStdin = "stdin" + // Value for streamType header for stdout stream StreamTypeStdout = "stdout" + // Value for streamType header for stderr stream StreamTypeStderr = "stderr" - StreamTypeData = "data" - StreamTypeError = "error" + // Value for streamType header for data stream + StreamTypeData = "data" + // Value for streamType header for error stream + StreamTypeError = "error" + // Name of header that specifies the port being forwarded PortHeader = "port" + // Name of header that specifies a request ID used to associate the error + // and data streams for a single forwarded connection + PortForwardRequestIDHeader = "requestID" ) // Similarly to above, these are constants to support HTTP PATCH utilized by @@ -2165,15 +2017,15 @@ type ComponentCondition struct { // ComponentStatus (and ComponentStatusList) holds the cluster validation info. type ComponentStatus struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` Conditions []ComponentCondition `json:"conditions,omitempty"` } type ComponentStatusList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []ComponentStatus `json:"items"` } @@ -2225,8 +2077,8 @@ type SELinuxOptions struct { // data encoding hints). A range allocation should *ALWAYS* be recreatable at any time by observation // of the cluster, thus the object is less strongly typed than most. type RangeAllocation struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` // A string representing a unique label for a range of resources, such as a CIDR "10.0.0.0/8" or // port range "10000-30000". Range is not strongly schema'd here. The Range is expected to define // a start and end unless there is an implicit end. @@ -2237,168 +2089,3 @@ type RangeAllocation struct { // a single allocated address (the fifth bit on CIDR 10.0.0.0/8 is 10.0.0.4). Data []byte `json:"data"` } - -// A ThirdPartyResource is a generic representation of a resource, it is used by add-ons and plugins to add new resource -// types to the API. It consists of one or more Versions of the api. -type ThirdPartyResource struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` - - Description string `json:"description,omitempty"` - - Versions []APIVersion `json:"versions,omitempty"` -} - -type ThirdPartyResourceList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` - - Items []ThirdPartyResource `json:"items"` -} - -// An APIVersion represents a single concrete version of an object model. -type APIVersion struct { - Name string `json:"name,omitempty"` - APIGroup string `json:"apiGroup,omitempty"` -} - -// An internal object, used for versioned storage in etcd. Not exposed to the end user. -type ThirdPartyResourceData struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` - - Data []byte `json:"name,omitempty"` -} - -// SecurityContextConstraints governs the ability to make requests that affect the SecurityContext -// that will be applied to a container. -type SecurityContextConstraints struct { - TypeMeta - ObjectMeta - - // AllowPrivilegedContainer determines if a container can request to be run as privileged. - AllowPrivilegedContainer bool - // AllowedCapabilities is a list of capabilities that can be requested to add to the container. - AllowedCapabilities []Capability - // AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin - AllowHostDirVolumePlugin bool - // AllowHostNetwork determines if the policy allows the use of HostNetwork in the pod spec. - AllowHostNetwork bool - // AllowHostPorts determines if the policy allows host ports in the containers. - AllowHostPorts bool - // AllowHostPID determines if the policy allows host pid in the containers. - AllowHostPID bool - // AllowHostIPC determines if the policy allows host ipc in the containers. - AllowHostIPC bool - // SELinuxContext is the strategy that will dictate what labels will be set in the SecurityContext. - SELinuxContext SELinuxContextStrategyOptions - // RunAsUser is the strategy that will dictate what RunAsUser is used in the SecurityContext. - RunAsUser RunAsUserStrategyOptions - // SupplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. - SupplementalGroups SupplementalGroupsStrategyOptions - // FSGroup is the strategy that will dictate what fs group is used by the SecurityContext. - FSGroup FSGroupStrategyOptions - - // The users who have permissions to use this security context constraints - Users []string - // The groups that have permission to use this security context constraints - Groups []string -} - -// SELinuxContextStrategyOptions defines the strategy type and any options used to create the strategy. -type SELinuxContextStrategyOptions struct { - // Type is the strategy that will dictate what SELinux context is used in the SecurityContext. - Type SELinuxContextStrategyType - // seLinuxOptions required to run as; required for MustRunAs - SELinuxOptions *SELinuxOptions -} - -// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. -type RunAsUserStrategyOptions struct { - // Type is the strategy that will dictate what RunAsUser is used in the SecurityContext. - Type RunAsUserStrategyType - // UID is the user id that containers must run as. Required for the MustRunAs strategy if not using - // namespace/service account allocated uids. - UID *int64 - // UIDRangeMin defines the min value for a strategy that allocates by range. - UIDRangeMin *int64 - // UIDRangeMax defines the max value for a strategy that allocates by range. - UIDRangeMax *int64 -} - -// FSGroupStrategyOptions defines the strategy type and options used to create the strategy. -type FSGroupStrategyOptions struct { - // Type is the strategy that will dictate what FSGroup is used in the SecurityContext. - Type FSGroupStrategyType - // Ranges are the allowed ranges of fs groups. If you would like to force a single - // fs group then supply a single range with the same start and end. - Ranges []IDRange -} - -// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. -type SupplementalGroupsStrategyOptions struct { - // Type is the strategy that will dictate what supplemental groups is used in the SecurityContext. - Type SupplementalGroupsStrategyType - // Ranges are the allowed ranges of supplemental groups. If you would like to force a single - // supplemental group then supply a single range with the same start and end. - Ranges []IDRange -} - -// IDRange provides a min/max of an allowed range of IDs. -// TODO: this could be reused for UIDs. -type IDRange struct { - // Min is the start of the range, inclusive. - Min int64 - // Max is the end of the range, inclusive. - Max int64 -} - -// SELinuxContextStrategyType denotes strategy types for generating SELinux options for a -// SecurityContext -type SELinuxContextStrategyType string - -// RunAsUserStrategyType denotes strategy types for generating RunAsUser values for a -// SecurityContext -type RunAsUserStrategyType string - -// SupplementalGroupsStrategyType denotes strategy types for determining valid supplemental -// groups for a SecurityContext. -type SupplementalGroupsStrategyType string - -// FSGroupStrategyType denotes strategy types for generating FSGroup values for a -// SecurityContext -type FSGroupStrategyType string - -const ( - // container must have SELinux labels of X applied. - SELinuxStrategyMustRunAs SELinuxContextStrategyType = "MustRunAs" - // container may make requests for any SELinux context labels. - SELinuxStrategyRunAsAny SELinuxContextStrategyType = "RunAsAny" - - // container must run as a particular uid. - RunAsUserStrategyMustRunAs RunAsUserStrategyType = "MustRunAs" - // container must run as a particular uid. - RunAsUserStrategyMustRunAsRange RunAsUserStrategyType = "MustRunAsRange" - // container must run as a non-root uid - RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategyType = "MustRunAsNonRoot" - // container may make requests for any uid. - RunAsUserStrategyRunAsAny RunAsUserStrategyType = "RunAsAny" - - // container must have FSGroup of X applied. - FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs" - // container may make requests for any FSGroup labels. - FSGroupStrategyRunAsAny FSGroupStrategyType = "RunAsAny" - - // container must run as a particular gid. - SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs" - // container may make requests for any gid. - SupplementalGroupsrStrategyRunAsAny SupplementalGroupsStrategyType = "RunAsAny" -) - -// SecurityContextConstraintsList is a list of SecurityContextConstraints objects -type SecurityContextConstraintsList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` - - Items []SecurityContextConstraints `json:"items"` -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned.go deleted file mode 100644 index cf0d809d99e2..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 api - -import ( - "strings" -) - -// This file contains API types that are unversioned. - -// APIVersions lists the api versions that are available, to allow -// version negotiation. APIVersions isn't just an unnamed array of -// strings in order to allow for future evolution, though unversioned -type APIVersions struct { - Versions []string `json:"versions"` -} - -// RootPaths lists the paths available at root. -// For example: "/healthz", "/api". -type RootPaths struct { - Paths []string `json:"paths"` -} - -// TODO: remove me when watch is refactored -func LabelSelectorQueryParam(version string) string { - return "labelSelector" -} - -// TODO: remove me when watch is refactored -func FieldSelectorQueryParam(version string) string { - return "fieldSelector" -} - -// String returns available api versions as a human-friendly version string. -func (apiVersions APIVersions) String() string { - return strings.Join(apiVersions.Versions, ",") -} - -func (apiVersions APIVersions) GoString() string { - return apiVersions.String() -} - -// Patch is provided to give a concrete name and type to the Kubernetes PATCH request body. -type Patch struct{} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/duration.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/duration.go new file mode 100644 index 000000000000..d9209f2c3e15 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/duration.go @@ -0,0 +1,47 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "encoding/json" + "time" +) + +// Duration is a wrapper around time.Duration which supports correct +// marshaling to YAML and JSON. In particular, it marshals into strings, which +// can be used as map keys in json. +type Duration struct { + time.Duration +} + +// UnmarshalJSON implements the json.Unmarshaller interface. +func (d *Duration) UnmarshalJSON(b []byte) error { + var str string + json.Unmarshal(b, &str) + + pd, err := time.ParseDuration(str) + if err != nil { + return err + } + d.Duration = pd + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (d Duration) MarshalJSON() ([]byte, error) { + return json.Marshal(d.String()) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/duration_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/duration_test.go new file mode 100644 index 000000000000..6650ca9aa160 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/duration_test.go @@ -0,0 +1,153 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "encoding/json" + "testing" + "time" + + "github.com/ghodss/yaml" +) + +type DurationHolder struct { + D Duration `json:"d"` +} + +func TestDurationMarshalYAML(t *testing.T) { + cases := []struct { + input Duration + result string + }{ + {Duration{5 * time.Second}, "d: 5s\n"}, + {Duration{2 * time.Minute}, "d: 2m0s\n"}, + {Duration{time.Hour + 3*time.Millisecond}, "d: 1h0m0.003s\n"}, + } + + for _, c := range cases { + input := DurationHolder{c.input} + result, err := yaml.Marshal(&input) + if err != nil { + t.Errorf("Failed to marshal input: %q: %v", input, err) + } + if string(result) != c.result { + t.Errorf("Failed to marshal input: %q: expected %q, got %q", input, c.result, string(result)) + } + } +} + +func TestDurationUnmarshalYAML(t *testing.T) { + cases := []struct { + input string + result Duration + }{ + {"d: 0s\n", Duration{}}, + {"d: 5s\n", Duration{5 * time.Second}}, + {"d: 2m0s\n", Duration{2 * time.Minute}}, + {"d: 1h0m0.003s\n", Duration{time.Hour + 3*time.Millisecond}}, + + // Units with zero values can optionally be dropped + {"d: 2m\n", Duration{2 * time.Minute}}, + {"d: 1h0.003s\n", Duration{time.Hour + 3*time.Millisecond}}, + } + + for _, c := range cases { + var result DurationHolder + if err := yaml.Unmarshal([]byte(c.input), &result); err != nil { + t.Errorf("Failed to unmarshal input %q: %v", c.input, err) + } + if result.D != c.result { + t.Errorf("Failed to unmarshal input %q: expected %q, got %q", c.input, c.result, result) + } + } +} + +func TestDurationMarshalJSON(t *testing.T) { + cases := []struct { + input Duration + result string + }{ + {Duration{5 * time.Second}, `{"d":"5s"}`}, + {Duration{2 * time.Minute}, `{"d":"2m0s"}`}, + {Duration{time.Hour + 3*time.Millisecond}, `{"d":"1h0m0.003s"}`}, + } + + for _, c := range cases { + input := DurationHolder{c.input} + result, err := json.Marshal(&input) + if err != nil { + t.Errorf("Failed to marshal input: %q: %v", input, err) + } + if string(result) != c.result { + t.Errorf("Failed to marshal input: %q: expected %q, got %q", input, c.result, string(result)) + } + } +} + +func TestDurationUnmarshalJSON(t *testing.T) { + cases := []struct { + input string + result Duration + }{ + {`{"d":"0s"}`, Duration{}}, + {`{"d":"5s"}`, Duration{5 * time.Second}}, + {`{"d":"2m0s"}`, Duration{2 * time.Minute}}, + {`{"d":"1h0m0.003s"}`, Duration{time.Hour + 3*time.Millisecond}}, + + // Units with zero values can optionally be dropped + {`{"d":"2m"}`, Duration{2 * time.Minute}}, + {`{"d":"1h0.003s"}`, Duration{time.Hour + 3*time.Millisecond}}, + } + + for _, c := range cases { + var result DurationHolder + if err := json.Unmarshal([]byte(c.input), &result); err != nil { + t.Errorf("Failed to unmarshal input %q: %v", c.input, err) + } + if result.D != c.result { + t.Errorf("Failed to unmarshal input %q: expected %q, got %q", c.input, c.result, result) + } + } +} + +func TestDurationMarshalJSONUnmarshalYAML(t *testing.T) { + cases := []struct { + input Duration + }{ + {Duration{}}, + {Duration{5 * time.Second}}, + {Duration{2 * time.Minute}}, + {Duration{time.Hour + 3*time.Millisecond}}, + } + + for i, c := range cases { + input := DurationHolder{c.input} + jsonMarshalled, err := json.Marshal(&input) + if err != nil { + t.Errorf("%d-1: Failed to marshal input: '%v': %v", i, input, err) + } + + var result DurationHolder + if err := yaml.Unmarshal(jsonMarshalled, &result); err != nil { + t.Errorf("%d-2: Failed to unmarshal '%+v': %v", i, string(jsonMarshalled), err) + } + + if input.D != result.D { + t.Errorf("%d-4: Failed to marshal input '%#v': got %#v", i, input, result) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/time.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/time.go similarity index 99% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/time.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/time.go index 001a50776347..bc403e55dcc7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/time.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/time.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util +package unversioned import ( "encoding/json" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/time_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/time_test.go similarity index 99% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/time_test.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/time_test.go index 8f3dac267009..2f4f3696d6d0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/time_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/time_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util +package unversioned import ( "encoding/json" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/types.go new file mode 100644 index 000000000000..809c5851882f --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/types.go @@ -0,0 +1,356 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned contains API types that are common to all versions. +package unversioned + +import "strings" + +// TypeMeta describes an individual object in an API response or request +// with strings representing the type of the object and its API schema version. +// Structures that are versioned or persisted should inline TypeMeta. +type TypeMeta struct { + // Kind is a string value representing the REST resource this object represents. + // Servers may infer this from the endpoint the client submits requests to. + // Cannot be updated. + // In CamelCase. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + Kind string `json:"kind,omitempty"` + + // APIVersion defines the versioned schema of this representation of an object. + // Servers should convert recognized schemas to the latest internal value, and + // may reject unrecognized values. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources + APIVersion string `json:"apiVersion,omitempty"` +} + +// ListMeta describes metadata that synthetic resources must have, including lists and +// various status objects. A resource may have only one of {ObjectMeta, ListMeta}. +type ListMeta struct { + // SelfLink is a URL representing this object. + // Populated by the system. + // Read-only. + SelfLink string `json:"selfLink,omitempty"` + + // String that identifies the server's internal version of this object that + // can be used by clients to determine when objects have changed. + // Value must be treated as opaque by clients and passed unmodified back to the server. + // Populated by the system. + // Read-only. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency + ResourceVersion string `json:"resourceVersion,omitempty"` +} + +// Status is a return value for calls that don't return other objects. +type Status struct { + TypeMeta `json:",inline"` + // Standard list metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + ListMeta `json:"metadata,omitempty"` + + // Status of the operation. + // One of: "Success" or "Failure". + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + Status string `json:"status,omitempty"` + // A human-readable description of the status of this operation. + Message string `json:"message,omitempty"` + // A machine-readable description of why this operation is in the + // "Failure" status. If this value is empty there + // is no information available. A Reason clarifies an HTTP status + // code but does not override it. + Reason StatusReason `json:"reason,omitempty"` + // Extended data associated with the reason. Each reason may define its + // own extended details. This field is optional and the data returned + // is not guaranteed to conform to any schema except that defined by + // the reason type. + Details *StatusDetails `json:"details,omitempty"` + // Suggested HTTP return code for this status, 0 if not set. + Code int `json:"code,omitempty"` +} + +// StatusDetails is a set of additional properties that MAY be set by the +// server to provide additional information about a response. The Reason +// field of a Status object defines what attributes will be set. Clients +// must ignore fields that do not match the defined type of each attribute, +// and should assume that any attribute may be empty, invalid, or under +// defined. +type StatusDetails struct { + // The name attribute of the resource associated with the status StatusReason + // (when there is a single name which can be described). + Name string `json:"name,omitempty"` + // The kind attribute of the resource associated with the status StatusReason. + // On some operations may differ from the requested resource Kind. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + Kind string `json:"kind,omitempty"` + // The Causes array includes more details associated with the StatusReason + // failure. Not all StatusReasons may provide detailed causes. + Causes []StatusCause `json:"causes,omitempty"` + // If specified, the time in seconds before the operation should be retried. + RetryAfterSeconds int `json:"retryAfterSeconds,omitempty"` +} + +// Values of Status.Status +const ( + StatusSuccess = "Success" + StatusFailure = "Failure" +) + +// StatusReason is an enumeration of possible failure causes. Each StatusReason +// must map to a single HTTP status code, but multiple reasons may map +// to the same HTTP status code. +// TODO: move to apiserver +type StatusReason string + +const ( + // StatusReasonUnknown means the server has declined to indicate a specific reason. + // The details field may contain other information about this error. + // Status code 500. + StatusReasonUnknown StatusReason = "" + + // StatusReasonUnauthorized means the server can be reached and understood the request, but requires + // the user to present appropriate authorization credentials (identified by the WWW-Authenticate header) + // in order for the action to be completed. If the user has specified credentials on the request, the + // server considers them insufficient. + // Status code 401 + StatusReasonUnauthorized StatusReason = "Unauthorized" + + // StatusReasonForbidden means the server can be reached and understood the request, but refuses + // to take any further action. It is the result of the server being configured to deny access for some reason + // to the requested resource by the client. + // Details (optional): + // "kind" string - the kind attribute of the forbidden resource + // on some operations may differ from the requested + // resource. + // "id" string - the identifier of the forbidden resource + // Status code 403 + StatusReasonForbidden StatusReason = "Forbidden" + + // StatusReasonNotFound means one or more resources required for this operation + // could not be found. + // Details (optional): + // "kind" string - the kind attribute of the missing resource + // on some operations may differ from the requested + // resource. + // "id" string - the identifier of the missing resource + // Status code 404 + StatusReasonNotFound StatusReason = "NotFound" + + // StatusReasonAlreadyExists means the resource you are creating already exists. + // Details (optional): + // "kind" string - the kind attribute of the conflicting resource + // "id" string - the identifier of the conflicting resource + // Status code 409 + StatusReasonAlreadyExists StatusReason = "AlreadyExists" + + // StatusReasonConflict means the requested update operation cannot be completed + // due to a conflict in the operation. The client may need to alter the request. + // Each resource may define custom details that indicate the nature of the + // conflict. + // Status code 409 + StatusReasonConflict StatusReason = "Conflict" + + // StatusReasonInvalid means the requested create or update operation cannot be + // completed due to invalid data provided as part of the request. The client may + // need to alter the request. When set, the client may use the StatusDetails + // message field as a summary of the issues encountered. + // Details (optional): + // "kind" string - the kind attribute of the invalid resource + // "id" string - the identifier of the invalid resource + // "causes" - one or more StatusCause entries indicating the data in the + // provided resource that was invalid. The code, message, and + // field attributes will be set. + // Status code 422 + StatusReasonInvalid StatusReason = "Invalid" + + // StatusReasonServerTimeout means the server can be reached and understood the request, + // but cannot complete the action in a reasonable time. The client should retry the request. + // This is may be due to temporary server load or a transient communication issue with + // another server. Status code 500 is used because the HTTP spec provides no suitable + // server-requested client retry and the 5xx class represents actionable errors. + // Details (optional): + // "kind" string - the kind attribute of the resource being acted on. + // "id" string - the operation that is being attempted. + // "retryAfterSeconds" int - the number of seconds before the operation should be retried + // Status code 500 + StatusReasonServerTimeout StatusReason = "ServerTimeout" + + // StatusReasonTimeout means that the request could not be completed within the given time. + // Clients can get this response only when they specified a timeout param in the request, + // or if the server cannot complete the operation within a reasonable amount of time. + // The request might succeed with an increased value of timeout param. The client *should* + // wait at least the number of seconds specified by the retryAfterSeconds field. + // Details (optional): + // "retryAfterSeconds" int - the number of seconds before the operation should be retried + // Status code 504 + StatusReasonTimeout StatusReason = "Timeout" + + // StatusReasonBadRequest means that the request itself was invalid, because the request + // doesn't make any sense, for example deleting a read-only object. This is different than + // StatusReasonInvalid above which indicates that the API call could possibly succeed, but the + // data was invalid. API calls that return BadRequest can never succeed. + StatusReasonBadRequest StatusReason = "BadRequest" + + // StatusReasonMethodNotAllowed means that the action the client attempted to perform on the + // resource was not supported by the code - for instance, attempting to delete a resource that + // can only be created. API calls that return MethodNotAllowed can never succeed. + StatusReasonMethodNotAllowed StatusReason = "MethodNotAllowed" + + // StatusReasonInternalError indicates that an internal error occurred, it is unexpected + // and the outcome of the call is unknown. + // Details (optional): + // "causes" - The original error + // Status code 500 + StatusReasonInternalError = "InternalError" + + // StatusReasonServiceUnavailable means that the request itself was valid, + // but the requested service is unavailable at this time. + // Retrying the request after some time might succeed. + // Status code 503 + StatusReasonServiceUnavailable StatusReason = "ServiceUnavailable" +) + +// StatusCause provides more information about an api.Status failure, including +// cases when multiple errors are encountered. +type StatusCause struct { + // A machine-readable description of the cause of the error. If this value is + // empty there is no information available. + Type CauseType `json:"reason,omitempty"` + // A human-readable description of the cause of the error. This field may be + // presented as-is to a reader. + Message string `json:"message,omitempty"` + // The field of the resource that has caused this error, as named by its JSON + // serialization. May include dot and postfix notation for nested attributes. + // Arrays are zero-indexed. Fields may appear more than once in an array of + // causes due to fields having multiple errors. + // Optional. + // + // Examples: + // "name" - the field "name" on the current resource + // "items[0].name" - the field "name" on the first array entry in "items" + Field string `json:"field,omitempty"` +} + +// CauseType is a machine readable value providing more detail about what +// occurred in a status response. An operation may have multiple causes for a +// status (whether Failure or Success). +type CauseType string + +const ( + // CauseTypeFieldValueNotFound is used to report failure to find a requested value + // (e.g. looking up an ID). + CauseTypeFieldValueNotFound CauseType = "FieldValueNotFound" + // CauseTypeFieldValueRequired is used to report required values that are not + // provided (e.g. empty strings, null values, or empty arrays). + CauseTypeFieldValueRequired CauseType = "FieldValueRequired" + // CauseTypeFieldValueDuplicate is used to report collisions of values that must be + // unique (e.g. unique IDs). + CauseTypeFieldValueDuplicate CauseType = "FieldValueDuplicate" + // CauseTypeFieldValueInvalid is used to report malformed values (e.g. failed regex + // match). + CauseTypeFieldValueInvalid CauseType = "FieldValueInvalid" + // CauseTypeFieldValueNotSupported is used to report valid (as per formatting rules) + // values that can not be handled (e.g. an enumerated string). + CauseTypeFieldValueNotSupported CauseType = "FieldValueNotSupported" + // CauseTypeUnexpectedServerResponse is used to report when the server responded to the client + // without the expected return type. The presence of this cause indicates the error may be + // due to an intervening proxy or the server software malfunctioning. + CauseTypeUnexpectedServerResponse CauseType = "UnexpectedServerResponse" +) + +func (*Status) IsAnAPIObject() {} + +// APIVersions lists the versions that are available, to allow clients to +// discover the API at /api, which is the root path of the legacy v1 API. +type APIVersions struct { + // versions are the api versions that are available. + Versions []string `json:"versions"` +} + +// APIGroupList is a list of APIGroup, to allow clients to discover the API at +// /apis. +type APIGroupList struct { + // groups is a list of APIGroup. + Groups []APIGroup `json:"groups"` +} + +// APIGroup contains the name, the supported versions, and the preferred version +// of a group. +type APIGroup struct { + // name is the name of the group. + Name string `json:"name"` + // versions are the versions supported in this group. + Versions []GroupVersion `json:"versions"` + // preferredVersion is the version preferred by the API server, which + // probably is the storage version. + PreferredVersion GroupVersion `json:"preferredVersion,omitempty"` +} + +// GroupVersion contains the "group/version" and "version" string of a version. +// It is made a struct to keep extensiblity. +type GroupVersion struct { + // groupVersion specifies the API group and version in the form "group/version" + GroupVersion string `json:"groupVersion"` + // version specifies the version in the form of "version". This is to save + // the clients the trouble of splitting the GroupVersion. + Version string `json:"version"` +} + +// APIResource specifies the name of a resource and whether it is namespaced. +type APIResource struct { + // name is the name of the resource. + Name string `json:"name"` + // namespaced indicates if a resource is namespaced or not. + Namespaced bool `json:"namespaced"` +} + +// APIResourceList is a list of APIResource, it is used to expose the name of the +// resources supported in a specific group and version, and if the resource +// is namespaced. +type APIResourceList struct { + // groupVersion is the group and version this APIResourceList is for. + GroupVersion string `json:"groupVersion"` + // resources contains the name of the resources and if they are namespaced. + APIResources []APIResource `json:"resources"` +} + +// RootPaths lists the paths available at root. +// For example: "/healthz", "/apis". +type RootPaths struct { + // paths are the paths available at root. + Paths []string `json:"paths"` +} + +// TODO: remove me when watch is refactored +func LabelSelectorQueryParam(version string) string { + return "labelSelector" +} + +// TODO: remove me when watch is refactored +func FieldSelectorQueryParam(version string) string { + return "fieldSelector" +} + +// String returns available api versions as a human-friendly version string. +func (apiVersions APIVersions) String() string { + return strings.Join(apiVersions.Versions, ",") +} + +func (apiVersions APIVersions) GoString() string { + return apiVersions.String() +} + +// Patch is provided to give a concrete name and type to the Kubernetes PATCH request body. +type Patch struct{} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/types_swagger_doc_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/types_swagger_doc_generated.go new file mode 100644 index 000000000000..cf9ad3f41b25 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/unversioned/types_swagger_doc_generated.go @@ -0,0 +1,163 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned + +// This file contains a collection of methods that can be used from go-resful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-generated-swagger-docs.sh + +// AUTO-GENERATED FUNCTIONS START HERE +var map_APIGroup = map[string]string{ + "": "APIGroup contains the name, the supported versions, and the preferred version of a group.", + "name": "name is the name of the group.", + "versions": "versions are the versions supported in this group.", + "preferredVersion": "preferredVersion is the version preferred by the API server, which probably is the storage version.", +} + +func (APIGroup) SwaggerDoc() map[string]string { + return map_APIGroup +} + +var map_APIGroupList = map[string]string{ + "": "APIGroupList is a list of APIGroup, to allow clients to discover the API at /apis.", + "groups": "groups is a list of APIGroup.", +} + +func (APIGroupList) SwaggerDoc() map[string]string { + return map_APIGroupList +} + +var map_APIResource = map[string]string{ + "": "APIResource specifies the name of a resource and whether it is namespaced.", + "name": "name is the name of the resource.", + "namespaced": "namespaced indicates if a resource is namespaced or not.", +} + +func (APIResource) SwaggerDoc() map[string]string { + return map_APIResource +} + +var map_APIResourceList = map[string]string{ + "": "APIResourceList is a list of APIResource, it is used to expose the name of the resources supported in a specific group and version, and if the resource is namespaced.", + "groupVersion": "groupVersion is the group and version this APIResourceList is for.", + "resources": "resources contains the name of the resources and if they are namespaced.", +} + +func (APIResourceList) SwaggerDoc() map[string]string { + return map_APIResourceList +} + +var map_APIVersions = map[string]string{ + "": "APIVersions lists the versions that are available, to allow clients to discover the API at /api, which is the root path of the legacy v1 API.", + "versions": "versions are the api versions that are available.", +} + +func (APIVersions) SwaggerDoc() map[string]string { + return map_APIVersions +} + +var map_GroupVersion = map[string]string{ + "": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensiblity.", + "groupVersion": "groupVersion specifies the API group and version in the form \"group/version\"", + "version": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.", +} + +func (GroupVersion) SwaggerDoc() map[string]string { + return map_GroupVersion +} + +var map_ListMeta = map[string]string{ + "": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.", + "selfLink": "SelfLink is a URL representing this object. Populated by the system. Read-only.", + "resourceVersion": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency", +} + +func (ListMeta) SwaggerDoc() map[string]string { + return map_ListMeta +} + +var map_Patch = map[string]string{ + "": "Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.", +} + +func (Patch) SwaggerDoc() map[string]string { + return map_Patch +} + +var map_RootPaths = map[string]string{ + "": "RootPaths lists the paths available at root. For example: \"/healthz\", \"/apis\".", + "paths": "paths are the paths available at root.", +} + +func (RootPaths) SwaggerDoc() map[string]string { + return map_RootPaths +} + +var map_Status = map[string]string{ + "": "Status is a return value for calls that don't return other objects.", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", + "status": "Status of the operation. One of: \"Success\" or \"Failure\". More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "message": "A human-readable description of the status of this operation.", + "reason": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.", + "details": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.", + "code": "Suggested HTTP return code for this status, 0 if not set.", +} + +func (Status) SwaggerDoc() map[string]string { + return map_Status +} + +var map_StatusCause = map[string]string{ + "": "StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.", + "reason": "A machine-readable description of the cause of the error. If this value is empty there is no information available.", + "message": "A human-readable description of the cause of the error. This field may be presented as-is to a reader.", + "field": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"", +} + +func (StatusCause) SwaggerDoc() map[string]string { + return map_StatusCause +} + +var map_StatusDetails = map[string]string{ + "": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.", + "name": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).", + "kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", + "causes": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.", + "retryAfterSeconds": "If specified, the time in seconds before the operation should be retried.", +} + +func (StatusDetails) SwaggerDoc() map[string]string { + return map_StatusDetails +} + +var map_TypeMeta = map[string]string{ + "": "TypeMeta describes an individual object in an API response or request with strings representing the type of the object and its API schema version. Structures that are versioned or persisted should inline TypeMeta.", + "kind": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", + "apiVersion": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources", +} + +func (TypeMeta) SwaggerDoc() map[string]string { + return map_TypeMeta +} + +// AUTO-GENERATED FUNCTIONS END HERE diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/util/group_version.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/util/group_version.go index 1a9cab0985e9..0cee250234a9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/util/group_version.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/util/group_version.go @@ -37,3 +37,12 @@ func GetGroup(groupVersion string) string { } return s[0] } + +// GetGroupVersion returns the "group/version". It returns "version" is if group +// is empty. It returns "group/" if version is empty. +func GetGroupVersion(group, version string) string { + if len(group) == 0 { + return version + } + return group + "/" + version +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/util/group_version_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/util/group_version_test.go index 163cd5f3f67f..d53b5f4e5a8f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/util/group_version_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/util/group_version_test.go @@ -28,8 +28,8 @@ func TestGetVersion(t *testing.T) { "v1", }, { - "experimental/v1alpha1", - "v1alpha1", + "extensions/v1beta1", + "v1beta1", }, } for _, test := range testCases { @@ -50,8 +50,8 @@ func TestGetGroup(t *testing.T) { "", }, { - "experimental/v1alpha1", - "experimental", + "extensions/v1beta1", + "extensions", }, } for _, test := range testCases { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/backward_compatibility_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/backward_compatibility_test.go new file mode 100644 index 000000000000..0bcfa3e31b6c --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/backward_compatibility_test.go @@ -0,0 +1,166 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 v1_test + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/testing/compat" + "k8s.io/kubernetes/pkg/api/validation" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +func TestCompatibility_v1_PodSecurityContext(t *testing.T) { + cases := []struct { + name string + input string + expectedKeys map[string]string + absentKeys []string + }{ + { + name: "hostNetwork = true", + input: ` +{ + "kind":"Pod", + "apiVersion":"v1", + "metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"}, + "spec": { + "hostNetwork": true, + "containers":[{ + "name":"a", + "image":"my-container-image" + }] + } +} +`, + expectedKeys: map[string]string{ + "spec.hostNetwork": "true", + }, + }, + { + name: "hostNetwork = false", + input: ` +{ + "kind":"Pod", + "apiVersion":"v1", + "metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"}, + "spec": { + "hostNetwork": false, + "containers":[{ + "name":"a", + "image":"my-container-image" + }] + } +} +`, + absentKeys: []string{ + "spec.hostNetwork", + }, + }, + { + name: "hostIPC = true", + input: ` +{ + "kind":"Pod", + "apiVersion":"v1", + "metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"}, + "spec": { + "hostIPC": true, + "containers":[{ + "name":"a", + "image":"my-container-image" + }] + } +} +`, + expectedKeys: map[string]string{ + "spec.hostIPC": "true", + }, + }, + { + name: "hostIPC = false", + input: ` +{ + "kind":"Pod", + "apiVersion":"v1", + "metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"}, + "spec": { + "hostIPC": false, + "containers":[{ + "name":"a", + "image":"my-container-image" + }] + } +} +`, + absentKeys: []string{ + "spec.hostIPC", + }, + }, + { + name: "hostPID = true", + input: ` +{ + "kind":"Pod", + "apiVersion":"v1", + "metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"}, + "spec": { + "hostPID": true, + "containers":[{ + "name":"a", + "image":"my-container-image" + }] + } +} +`, + expectedKeys: map[string]string{ + "spec.hostPID": "true", + }, + }, + { + name: "hostPID = false", + input: ` +{ + "kind":"Pod", + "apiVersion":"v1", + "metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"}, + "spec": { + "hostPID": false, + "containers":[{ + "name":"a", + "image":"my-container-image" + }] + } +} +`, + absentKeys: []string{ + "spec.hostPID", + }, + }, + } + + validator := func(obj runtime.Object) fielderrors.ValidationErrorList { + return validation.ValidatePodSpec(&(obj.(*api.Pod).Spec)) + } + + for _, tc := range cases { + t.Logf("Testing 1.0.0 backward compatibility for %v", tc.name) + compat.TestCompatibility(t, "v1", []byte(tc.input), validator, tc.expectedKeys, tc.absentKeys) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go index 3a1655265085..ba5f619d175e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go @@ -29,10 +29,10 @@ func addConversionFuncs() { err := api.Scheme.AddConversionFuncs( convert_api_PodSpec_To_v1_PodSpec, convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec, - convert_api_VolumeSource_To_v1_VolumeSource, + convert_api_ServiceSpec_To_v1_ServiceSpec, convert_v1_PodSpec_To_api_PodSpec, convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec, - convert_v1_VolumeSource_To_api_VolumeSource, + convert_v1_ServiceSpec_To_api_ServiceSpec, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. @@ -283,9 +283,16 @@ func convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversi // DeprecatedServiceAccount is an alias for ServiceAccountName. out.DeprecatedServiceAccount = in.ServiceAccountName out.NodeName = in.NodeName - out.HostNetwork = in.HostNetwork - out.HostPID = in.HostPID - out.HostIPC = in.HostIPC + if in.SecurityContext != nil { + out.SecurityContext = new(PodSecurityContext) + if err := convert_api_PodSecurityContext_To_v1_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { + return err + } + + out.HostPID = in.SecurityContext.HostPID + out.HostNetwork = in.SecurityContext.HostNetwork + out.HostIPC = in.SecurityContext.HostIPC + } if in.ImagePullSecrets != nil { out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) for i := range in.ImagePullSecrets { @@ -296,10 +303,6 @@ func convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversi } else { out.ImagePullSecrets = nil } - - // carry conversion - out.DeprecatedHost = in.NodeName - return nil } @@ -356,15 +359,18 @@ func convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversi out.ServiceAccountName = in.DeprecatedServiceAccount } out.NodeName = in.NodeName - - // carry conversion - if in.NodeName == "" { - out.NodeName = in.DeprecatedHost + if in.SecurityContext != nil { + out.SecurityContext = new(api.PodSecurityContext) + if err := convert_v1_PodSecurityContext_To_api_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { + return err + } } - - out.HostNetwork = in.HostNetwork - out.HostPID = in.HostPID - out.HostIPC = in.HostIPC + if out.SecurityContext == nil { + out.SecurityContext = new(api.PodSecurityContext) + } + out.SecurityContext.HostNetwork = in.HostNetwork + out.SecurityContext.HostPID = in.HostPID + out.SecurityContext.HostIPC = in.HostIPC if in.ImagePullSecrets != nil { out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets)) for i := range in.ImagePullSecrets { @@ -378,96 +384,41 @@ func convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversi return nil } -// This will convert our internal represantation of VolumeSource to its v1 representation -// Used for keeping backwards compatibility for the Metadata field -func convert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *VolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.VolumeSource))(in) - } - - if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { +func convert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *ServiceSpec, s conversion.Scope) error { + if err := autoconvert_api_ServiceSpec_To_v1_ServiceSpec(in, out, s); err != nil { return err } - - if in.DownwardAPI != nil { - out.Metadata = new(MetadataVolumeSource) - if err := convert_api_DownwardAPIVolumeSource_To_v1_MetadataVolumeSource(in.DownwardAPI, out.Metadata, s); err != nil { - return err - } - } - return nil -} - -// downward -> metadata (api -> v1) -func convert_api_DownwardAPIVolumeSource_To_v1_MetadataVolumeSource(in *api.DownwardAPIVolumeSource, out *MetadataVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.DownwardAPIVolumeSource))(in) - } - if in.Items != nil { - out.Items = make([]MetadataFile, len(in.Items)) - for i := range in.Items { - if err := convert_api_DownwardAPIVolumeFile_To_v1_MetadataFile(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } - return nil -} - -func convert_api_DownwardAPIVolumeFile_To_v1_MetadataFile(in *api.DownwardAPIVolumeFile, out *MetadataFile, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.DownwardAPIVolumeFile))(in) - } - out.Name = in.Path - if err := convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { - return err + // Publish both externalIPs and deprecatedPublicIPs fields in v1. + for _, ip := range in.ExternalIPs { + out.DeprecatedPublicIPs = append(out.DeprecatedPublicIPs, ip) } return nil } -// This will convert the v1 representation of VolumeSource to our internal representation -// Used for keeping backwards compatibility for the Metadata field -func convert_v1_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api.VolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*VolumeSource))(in) - } - - if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { +func convert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.ServiceSpec, s conversion.Scope) error { + if err := autoconvert_v1_ServiceSpec_To_api_ServiceSpec(in, out, s); err != nil { return err } - - if in.Metadata != nil { - out.DownwardAPI = new(api.DownwardAPIVolumeSource) - if err := convert_v1_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in.Metadata, out.DownwardAPI, s); err != nil { - return err + // Prefer the legacy deprecatedPublicIPs field, if provided. + if len(in.DeprecatedPublicIPs) > 0 { + out.ExternalIPs = nil + for _, ip := range in.DeprecatedPublicIPs { + out.ExternalIPs = append(out.ExternalIPs, ip) } } return nil } -// metadata -> downward (v1 -> api) -func convert_v1_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in *MetadataVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { +func convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *PodSecurityContext, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*MetadataVolumeSource))(in) - } - if in.Items != nil { - out.Items = make([]api.DownwardAPIVolumeFile, len(in.Items)) - for i := range in.Items { - if err := convert_v1_MetadataFile_To_api_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } + defaulting.(func(*api.PodSecurityContext))(in) } return nil } -func convert_v1_MetadataFile_To_api_DownwardAPIVolumeFile(in *MetadataFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { +func convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*MetadataFile))(in) - } - out.Path = in.Name - if err := convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { - return err + defaulting.(func(*PodSecurityContext))(in) } return nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go index b0e2d138e82b..0e9e777d8d26 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go @@ -26,7 +26,7 @@ import ( conversion "k8s.io/kubernetes/pkg/conversion" ) -func convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in *api.AWSElasticBlockStoreVolumeSource, out *AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { +func autoconvert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in *api.AWSElasticBlockStoreVolumeSource, out *AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.AWSElasticBlockStoreVolumeSource))(in) } @@ -37,11 +37,15 @@ func convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolu return nil } -func convert_api_Binding_To_v1_Binding(in *api.Binding, out *Binding, s conversion.Scope) error { +func convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in *api.AWSElasticBlockStoreVolumeSource, out *AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { + return autoconvert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in, out, s) +} + +func autoconvert_api_Binding_To_v1_Binding(in *api.Binding, out *Binding, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Binding))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -53,7 +57,11 @@ func convert_api_Binding_To_v1_Binding(in *api.Binding, out *Binding, s conversi return nil } -func convert_api_Capabilities_To_v1_Capabilities(in *api.Capabilities, out *Capabilities, s conversion.Scope) error { +func convert_api_Binding_To_v1_Binding(in *api.Binding, out *Binding, s conversion.Scope) error { + return autoconvert_api_Binding_To_v1_Binding(in, out, s) +} + +func autoconvert_api_Capabilities_To_v1_Capabilities(in *api.Capabilities, out *Capabilities, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Capabilities))(in) } @@ -76,7 +84,11 @@ func convert_api_Capabilities_To_v1_Capabilities(in *api.Capabilities, out *Capa return nil } -func convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in *api.CephFSVolumeSource, out *CephFSVolumeSource, s conversion.Scope) error { +func convert_api_Capabilities_To_v1_Capabilities(in *api.Capabilities, out *Capabilities, s conversion.Scope) error { + return autoconvert_api_Capabilities_To_v1_Capabilities(in, out, s) +} + +func autoconvert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in *api.CephFSVolumeSource, out *CephFSVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.CephFSVolumeSource))(in) } @@ -102,7 +114,11 @@ func convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in *api.CephFSVolum return nil } -func convert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in *api.CinderVolumeSource, out *CinderVolumeSource, s conversion.Scope) error { +func convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in *api.CephFSVolumeSource, out *CephFSVolumeSource, s conversion.Scope) error { + return autoconvert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in, out, s) +} + +func autoconvert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in *api.CinderVolumeSource, out *CinderVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.CinderVolumeSource))(in) } @@ -112,7 +128,11 @@ func convert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in *api.CinderVolum return nil } -func convert_api_ComponentCondition_To_v1_ComponentCondition(in *api.ComponentCondition, out *ComponentCondition, s conversion.Scope) error { +func convert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in *api.CinderVolumeSource, out *CinderVolumeSource, s conversion.Scope) error { + return autoconvert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in, out, s) +} + +func autoconvert_api_ComponentCondition_To_v1_ComponentCondition(in *api.ComponentCondition, out *ComponentCondition, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ComponentCondition))(in) } @@ -123,11 +143,15 @@ func convert_api_ComponentCondition_To_v1_ComponentCondition(in *api.ComponentCo return nil } -func convert_api_ComponentStatus_To_v1_ComponentStatus(in *api.ComponentStatus, out *ComponentStatus, s conversion.Scope) error { +func convert_api_ComponentCondition_To_v1_ComponentCondition(in *api.ComponentCondition, out *ComponentCondition, s conversion.Scope) error { + return autoconvert_api_ComponentCondition_To_v1_ComponentCondition(in, out, s) +} + +func autoconvert_api_ComponentStatus_To_v1_ComponentStatus(in *api.ComponentStatus, out *ComponentStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ComponentStatus))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -146,14 +170,18 @@ func convert_api_ComponentStatus_To_v1_ComponentStatus(in *api.ComponentStatus, return nil } -func convert_api_ComponentStatusList_To_v1_ComponentStatusList(in *api.ComponentStatusList, out *ComponentStatusList, s conversion.Scope) error { +func convert_api_ComponentStatus_To_v1_ComponentStatus(in *api.ComponentStatus, out *ComponentStatus, s conversion.Scope) error { + return autoconvert_api_ComponentStatus_To_v1_ComponentStatus(in, out, s) +} + +func autoconvert_api_ComponentStatusList_To_v1_ComponentStatusList(in *api.ComponentStatusList, out *ComponentStatusList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ComponentStatusList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -169,7 +197,11 @@ func convert_api_ComponentStatusList_To_v1_ComponentStatusList(in *api.Component return nil } -func convert_api_Container_To_v1_Container(in *api.Container, out *Container, s conversion.Scope) error { +func convert_api_ComponentStatusList_To_v1_ComponentStatusList(in *api.ComponentStatusList, out *ComponentStatusList, s conversion.Scope) error { + return autoconvert_api_ComponentStatusList_To_v1_ComponentStatusList(in, out, s) +} + +func autoconvert_api_Container_To_v1_Container(in *api.Container, out *Container, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Container))(in) } @@ -264,7 +296,11 @@ func convert_api_Container_To_v1_Container(in *api.Container, out *Container, s return nil } -func convert_api_ContainerPort_To_v1_ContainerPort(in *api.ContainerPort, out *ContainerPort, s conversion.Scope) error { +func convert_api_Container_To_v1_Container(in *api.Container, out *Container, s conversion.Scope) error { + return autoconvert_api_Container_To_v1_Container(in, out, s) +} + +func autoconvert_api_ContainerPort_To_v1_ContainerPort(in *api.ContainerPort, out *ContainerPort, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ContainerPort))(in) } @@ -276,7 +312,11 @@ func convert_api_ContainerPort_To_v1_ContainerPort(in *api.ContainerPort, out *C return nil } -func convert_api_ContainerState_To_v1_ContainerState(in *api.ContainerState, out *ContainerState, s conversion.Scope) error { +func convert_api_ContainerPort_To_v1_ContainerPort(in *api.ContainerPort, out *ContainerPort, s conversion.Scope) error { + return autoconvert_api_ContainerPort_To_v1_ContainerPort(in, out, s) +} + +func autoconvert_api_ContainerState_To_v1_ContainerState(in *api.ContainerState, out *ContainerState, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ContainerState))(in) } @@ -307,7 +347,11 @@ func convert_api_ContainerState_To_v1_ContainerState(in *api.ContainerState, out return nil } -func convert_api_ContainerStateRunning_To_v1_ContainerStateRunning(in *api.ContainerStateRunning, out *ContainerStateRunning, s conversion.Scope) error { +func convert_api_ContainerState_To_v1_ContainerState(in *api.ContainerState, out *ContainerState, s conversion.Scope) error { + return autoconvert_api_ContainerState_To_v1_ContainerState(in, out, s) +} + +func autoconvert_api_ContainerStateRunning_To_v1_ContainerStateRunning(in *api.ContainerStateRunning, out *ContainerStateRunning, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ContainerStateRunning))(in) } @@ -317,7 +361,11 @@ func convert_api_ContainerStateRunning_To_v1_ContainerStateRunning(in *api.Conta return nil } -func convert_api_ContainerStateTerminated_To_v1_ContainerStateTerminated(in *api.ContainerStateTerminated, out *ContainerStateTerminated, s conversion.Scope) error { +func convert_api_ContainerStateRunning_To_v1_ContainerStateRunning(in *api.ContainerStateRunning, out *ContainerStateRunning, s conversion.Scope) error { + return autoconvert_api_ContainerStateRunning_To_v1_ContainerStateRunning(in, out, s) +} + +func autoconvert_api_ContainerStateTerminated_To_v1_ContainerStateTerminated(in *api.ContainerStateTerminated, out *ContainerStateTerminated, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ContainerStateTerminated))(in) } @@ -335,7 +383,11 @@ func convert_api_ContainerStateTerminated_To_v1_ContainerStateTerminated(in *api return nil } -func convert_api_ContainerStateWaiting_To_v1_ContainerStateWaiting(in *api.ContainerStateWaiting, out *ContainerStateWaiting, s conversion.Scope) error { +func convert_api_ContainerStateTerminated_To_v1_ContainerStateTerminated(in *api.ContainerStateTerminated, out *ContainerStateTerminated, s conversion.Scope) error { + return autoconvert_api_ContainerStateTerminated_To_v1_ContainerStateTerminated(in, out, s) +} + +func autoconvert_api_ContainerStateWaiting_To_v1_ContainerStateWaiting(in *api.ContainerStateWaiting, out *ContainerStateWaiting, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ContainerStateWaiting))(in) } @@ -344,7 +396,11 @@ func convert_api_ContainerStateWaiting_To_v1_ContainerStateWaiting(in *api.Conta return nil } -func convert_api_ContainerStatus_To_v1_ContainerStatus(in *api.ContainerStatus, out *ContainerStatus, s conversion.Scope) error { +func convert_api_ContainerStateWaiting_To_v1_ContainerStateWaiting(in *api.ContainerStateWaiting, out *ContainerStateWaiting, s conversion.Scope) error { + return autoconvert_api_ContainerStateWaiting_To_v1_ContainerStateWaiting(in, out, s) +} + +func autoconvert_api_ContainerStatus_To_v1_ContainerStatus(in *api.ContainerStatus, out *ContainerStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ContainerStatus))(in) } @@ -363,11 +419,27 @@ func convert_api_ContainerStatus_To_v1_ContainerStatus(in *api.ContainerStatus, return nil } -func convert_api_DeleteOptions_To_v1_DeleteOptions(in *api.DeleteOptions, out *DeleteOptions, s conversion.Scope) error { +func convert_api_ContainerStatus_To_v1_ContainerStatus(in *api.ContainerStatus, out *ContainerStatus, s conversion.Scope) error { + return autoconvert_api_ContainerStatus_To_v1_ContainerStatus(in, out, s) +} + +func autoconvert_api_DaemonEndpoint_To_v1_DaemonEndpoint(in *api.DaemonEndpoint, out *DaemonEndpoint, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DaemonEndpoint))(in) + } + out.Port = in.Port + return nil +} + +func convert_api_DaemonEndpoint_To_v1_DaemonEndpoint(in *api.DaemonEndpoint, out *DaemonEndpoint, s conversion.Scope) error { + return autoconvert_api_DaemonEndpoint_To_v1_DaemonEndpoint(in, out, s) +} + +func autoconvert_api_DeleteOptions_To_v1_DeleteOptions(in *api.DeleteOptions, out *DeleteOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.DeleteOptions))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if in.GracePeriodSeconds != nil { @@ -379,7 +451,11 @@ func convert_api_DeleteOptions_To_v1_DeleteOptions(in *api.DeleteOptions, out *D return nil } -func convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in *api.DownwardAPIVolumeFile, out *DownwardAPIVolumeFile, s conversion.Scope) error { +func convert_api_DeleteOptions_To_v1_DeleteOptions(in *api.DeleteOptions, out *DeleteOptions, s conversion.Scope) error { + return autoconvert_api_DeleteOptions_To_v1_DeleteOptions(in, out, s) +} + +func autoconvert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in *api.DownwardAPIVolumeFile, out *DownwardAPIVolumeFile, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.DownwardAPIVolumeFile))(in) } @@ -390,7 +466,11 @@ func convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in *api.Downw return nil } -func convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in *api.DownwardAPIVolumeSource, out *DownwardAPIVolumeSource, s conversion.Scope) error { +func convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in *api.DownwardAPIVolumeFile, out *DownwardAPIVolumeFile, s conversion.Scope) error { + return autoconvert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in, out, s) +} + +func autoconvert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in *api.DownwardAPIVolumeSource, out *DownwardAPIVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.DownwardAPIVolumeSource))(in) } @@ -407,7 +487,11 @@ func convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in *api.D return nil } -func convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in *api.EmptyDirVolumeSource, out *EmptyDirVolumeSource, s conversion.Scope) error { +func convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in *api.DownwardAPIVolumeSource, out *DownwardAPIVolumeSource, s conversion.Scope) error { + return autoconvert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in, out, s) +} + +func autoconvert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in *api.EmptyDirVolumeSource, out *EmptyDirVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.EmptyDirVolumeSource))(in) } @@ -415,7 +499,11 @@ func convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in *api.EmptyDi return nil } -func convert_api_EndpointAddress_To_v1_EndpointAddress(in *api.EndpointAddress, out *EndpointAddress, s conversion.Scope) error { +func convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in *api.EmptyDirVolumeSource, out *EmptyDirVolumeSource, s conversion.Scope) error { + return autoconvert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in, out, s) +} + +func autoconvert_api_EndpointAddress_To_v1_EndpointAddress(in *api.EndpointAddress, out *EndpointAddress, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.EndpointAddress))(in) } @@ -431,7 +519,11 @@ func convert_api_EndpointAddress_To_v1_EndpointAddress(in *api.EndpointAddress, return nil } -func convert_api_EndpointPort_To_v1_EndpointPort(in *api.EndpointPort, out *EndpointPort, s conversion.Scope) error { +func convert_api_EndpointAddress_To_v1_EndpointAddress(in *api.EndpointAddress, out *EndpointAddress, s conversion.Scope) error { + return autoconvert_api_EndpointAddress_To_v1_EndpointAddress(in, out, s) +} + +func autoconvert_api_EndpointPort_To_v1_EndpointPort(in *api.EndpointPort, out *EndpointPort, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.EndpointPort))(in) } @@ -441,7 +533,11 @@ func convert_api_EndpointPort_To_v1_EndpointPort(in *api.EndpointPort, out *Endp return nil } -func convert_api_EndpointSubset_To_v1_EndpointSubset(in *api.EndpointSubset, out *EndpointSubset, s conversion.Scope) error { +func convert_api_EndpointPort_To_v1_EndpointPort(in *api.EndpointPort, out *EndpointPort, s conversion.Scope) error { + return autoconvert_api_EndpointPort_To_v1_EndpointPort(in, out, s) +} + +func autoconvert_api_EndpointSubset_To_v1_EndpointSubset(in *api.EndpointSubset, out *EndpointSubset, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.EndpointSubset))(in) } @@ -455,6 +551,16 @@ func convert_api_EndpointSubset_To_v1_EndpointSubset(in *api.EndpointSubset, out } else { out.Addresses = nil } + if in.NotReadyAddresses != nil { + out.NotReadyAddresses = make([]EndpointAddress, len(in.NotReadyAddresses)) + for i := range in.NotReadyAddresses { + if err := convert_api_EndpointAddress_To_v1_EndpointAddress(&in.NotReadyAddresses[i], &out.NotReadyAddresses[i], s); err != nil { + return err + } + } + } else { + out.NotReadyAddresses = nil + } if in.Ports != nil { out.Ports = make([]EndpointPort, len(in.Ports)) for i := range in.Ports { @@ -468,11 +574,15 @@ func convert_api_EndpointSubset_To_v1_EndpointSubset(in *api.EndpointSubset, out return nil } -func convert_api_Endpoints_To_v1_Endpoints(in *api.Endpoints, out *Endpoints, s conversion.Scope) error { +func convert_api_EndpointSubset_To_v1_EndpointSubset(in *api.EndpointSubset, out *EndpointSubset, s conversion.Scope) error { + return autoconvert_api_EndpointSubset_To_v1_EndpointSubset(in, out, s) +} + +func autoconvert_api_Endpoints_To_v1_Endpoints(in *api.Endpoints, out *Endpoints, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Endpoints))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -491,14 +601,18 @@ func convert_api_Endpoints_To_v1_Endpoints(in *api.Endpoints, out *Endpoints, s return nil } -func convert_api_EndpointsList_To_v1_EndpointsList(in *api.EndpointsList, out *EndpointsList, s conversion.Scope) error { +func convert_api_Endpoints_To_v1_Endpoints(in *api.Endpoints, out *Endpoints, s conversion.Scope) error { + return autoconvert_api_Endpoints_To_v1_Endpoints(in, out, s) +} + +func autoconvert_api_EndpointsList_To_v1_EndpointsList(in *api.EndpointsList, out *EndpointsList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.EndpointsList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -514,7 +628,11 @@ func convert_api_EndpointsList_To_v1_EndpointsList(in *api.EndpointsList, out *E return nil } -func convert_api_EnvVar_To_v1_EnvVar(in *api.EnvVar, out *EnvVar, s conversion.Scope) error { +func convert_api_EndpointsList_To_v1_EndpointsList(in *api.EndpointsList, out *EndpointsList, s conversion.Scope) error { + return autoconvert_api_EndpointsList_To_v1_EndpointsList(in, out, s) +} + +func autoconvert_api_EnvVar_To_v1_EnvVar(in *api.EnvVar, out *EnvVar, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.EnvVar))(in) } @@ -531,7 +649,11 @@ func convert_api_EnvVar_To_v1_EnvVar(in *api.EnvVar, out *EnvVar, s conversion.S return nil } -func convert_api_EnvVarSource_To_v1_EnvVarSource(in *api.EnvVarSource, out *EnvVarSource, s conversion.Scope) error { +func convert_api_EnvVar_To_v1_EnvVar(in *api.EnvVar, out *EnvVar, s conversion.Scope) error { + return autoconvert_api_EnvVar_To_v1_EnvVar(in, out, s) +} + +func autoconvert_api_EnvVarSource_To_v1_EnvVarSource(in *api.EnvVarSource, out *EnvVarSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.EnvVarSource))(in) } @@ -546,11 +668,15 @@ func convert_api_EnvVarSource_To_v1_EnvVarSource(in *api.EnvVarSource, out *EnvV return nil } -func convert_api_Event_To_v1_Event(in *api.Event, out *Event, s conversion.Scope) error { +func convert_api_EnvVarSource_To_v1_EnvVarSource(in *api.EnvVarSource, out *EnvVarSource, s conversion.Scope) error { + return autoconvert_api_EnvVarSource_To_v1_EnvVarSource(in, out, s) +} + +func autoconvert_api_Event_To_v1_Event(in *api.Event, out *Event, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Event))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -574,14 +700,18 @@ func convert_api_Event_To_v1_Event(in *api.Event, out *Event, s conversion.Scope return nil } -func convert_api_EventList_To_v1_EventList(in *api.EventList, out *EventList, s conversion.Scope) error { +func convert_api_Event_To_v1_Event(in *api.Event, out *Event, s conversion.Scope) error { + return autoconvert_api_Event_To_v1_Event(in, out, s) +} + +func autoconvert_api_EventList_To_v1_EventList(in *api.EventList, out *EventList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.EventList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -597,7 +727,11 @@ func convert_api_EventList_To_v1_EventList(in *api.EventList, out *EventList, s return nil } -func convert_api_EventSource_To_v1_EventSource(in *api.EventSource, out *EventSource, s conversion.Scope) error { +func convert_api_EventList_To_v1_EventList(in *api.EventList, out *EventList, s conversion.Scope) error { + return autoconvert_api_EventList_To_v1_EventList(in, out, s) +} + +func autoconvert_api_EventSource_To_v1_EventSource(in *api.EventSource, out *EventSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.EventSource))(in) } @@ -606,7 +740,11 @@ func convert_api_EventSource_To_v1_EventSource(in *api.EventSource, out *EventSo return nil } -func convert_api_ExecAction_To_v1_ExecAction(in *api.ExecAction, out *ExecAction, s conversion.Scope) error { +func convert_api_EventSource_To_v1_EventSource(in *api.EventSource, out *EventSource, s conversion.Scope) error { + return autoconvert_api_EventSource_To_v1_EventSource(in, out, s) +} + +func autoconvert_api_ExecAction_To_v1_ExecAction(in *api.ExecAction, out *ExecAction, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ExecAction))(in) } @@ -621,7 +759,50 @@ func convert_api_ExecAction_To_v1_ExecAction(in *api.ExecAction, out *ExecAction return nil } -func convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in *api.GCEPersistentDiskVolumeSource, out *GCEPersistentDiskVolumeSource, s conversion.Scope) error { +func convert_api_ExecAction_To_v1_ExecAction(in *api.ExecAction, out *ExecAction, s conversion.Scope) error { + return autoconvert_api_ExecAction_To_v1_ExecAction(in, out, s) +} + +func autoconvert_api_FCVolumeSource_To_v1_FCVolumeSource(in *api.FCVolumeSource, out *FCVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.FCVolumeSource))(in) + } + if in.TargetWWNs != nil { + out.TargetWWNs = make([]string, len(in.TargetWWNs)) + for i := range in.TargetWWNs { + out.TargetWWNs[i] = in.TargetWWNs[i] + } + } else { + out.TargetWWNs = nil + } + if in.Lun != nil { + out.Lun = new(int) + *out.Lun = *in.Lun + } else { + out.Lun = nil + } + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_FCVolumeSource_To_v1_FCVolumeSource(in *api.FCVolumeSource, out *FCVolumeSource, s conversion.Scope) error { + return autoconvert_api_FCVolumeSource_To_v1_FCVolumeSource(in, out, s) +} + +func autoconvert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource(in *api.FlockerVolumeSource, out *FlockerVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.FlockerVolumeSource))(in) + } + out.DatasetName = in.DatasetName + return nil +} + +func convert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource(in *api.FlockerVolumeSource, out *FlockerVolumeSource, s conversion.Scope) error { + return autoconvert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource(in, out, s) +} + +func autoconvert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in *api.GCEPersistentDiskVolumeSource, out *GCEPersistentDiskVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.GCEPersistentDiskVolumeSource))(in) } @@ -632,7 +813,11 @@ func convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSour return nil } -func convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in *api.GitRepoVolumeSource, out *GitRepoVolumeSource, s conversion.Scope) error { +func convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in *api.GCEPersistentDiskVolumeSource, out *GCEPersistentDiskVolumeSource, s conversion.Scope) error { + return autoconvert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in, out, s) +} + +func autoconvert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in *api.GitRepoVolumeSource, out *GitRepoVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.GitRepoVolumeSource))(in) } @@ -641,7 +826,11 @@ func convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in *api.GitRepoVo return nil } -func convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in *api.GlusterfsVolumeSource, out *GlusterfsVolumeSource, s conversion.Scope) error { +func convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in *api.GitRepoVolumeSource, out *GitRepoVolumeSource, s conversion.Scope) error { + return autoconvert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in, out, s) +} + +func autoconvert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in *api.GlusterfsVolumeSource, out *GlusterfsVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.GlusterfsVolumeSource))(in) } @@ -651,7 +840,11 @@ func convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in *api.Glust return nil } -func convert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, out *HTTPGetAction, s conversion.Scope) error { +func convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in *api.GlusterfsVolumeSource, out *GlusterfsVolumeSource, s conversion.Scope) error { + return autoconvert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in, out, s) +} + +func autoconvert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, out *HTTPGetAction, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.HTTPGetAction))(in) } @@ -664,7 +857,11 @@ func convert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, out *H return nil } -func convert_api_Handler_To_v1_Handler(in *api.Handler, out *Handler, s conversion.Scope) error { +func convert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, out *HTTPGetAction, s conversion.Scope) error { + return autoconvert_api_HTTPGetAction_To_v1_HTTPGetAction(in, out, s) +} + +func autoconvert_api_Handler_To_v1_Handler(in *api.Handler, out *Handler, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Handler))(in) } @@ -695,7 +892,11 @@ func convert_api_Handler_To_v1_Handler(in *api.Handler, out *Handler, s conversi return nil } -func convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in *api.HostPathVolumeSource, out *HostPathVolumeSource, s conversion.Scope) error { +func convert_api_Handler_To_v1_Handler(in *api.Handler, out *Handler, s conversion.Scope) error { + return autoconvert_api_Handler_To_v1_Handler(in, out, s) +} + +func autoconvert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in *api.HostPathVolumeSource, out *HostPathVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.HostPathVolumeSource))(in) } @@ -703,7 +904,11 @@ func convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in *api.HostPat return nil } -func convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in *api.ISCSIVolumeSource, out *ISCSIVolumeSource, s conversion.Scope) error { +func convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in *api.HostPathVolumeSource, out *HostPathVolumeSource, s conversion.Scope) error { + return autoconvert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in, out, s) +} + +func autoconvert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in *api.ISCSIVolumeSource, out *ISCSIVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ISCSIVolumeSource))(in) } @@ -715,7 +920,11 @@ func convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in *api.ISCSIVolumeSo return nil } -func convert_api_Lifecycle_To_v1_Lifecycle(in *api.Lifecycle, out *Lifecycle, s conversion.Scope) error { +func convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in *api.ISCSIVolumeSource, out *ISCSIVolumeSource, s conversion.Scope) error { + return autoconvert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in, out, s) +} + +func autoconvert_api_Lifecycle_To_v1_Lifecycle(in *api.Lifecycle, out *Lifecycle, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Lifecycle))(in) } @@ -738,11 +947,15 @@ func convert_api_Lifecycle_To_v1_Lifecycle(in *api.Lifecycle, out *Lifecycle, s return nil } -func convert_api_LimitRange_To_v1_LimitRange(in *api.LimitRange, out *LimitRange, s conversion.Scope) error { +func convert_api_Lifecycle_To_v1_Lifecycle(in *api.Lifecycle, out *Lifecycle, s conversion.Scope) error { + return autoconvert_api_Lifecycle_To_v1_Lifecycle(in, out, s) +} + +func autoconvert_api_LimitRange_To_v1_LimitRange(in *api.LimitRange, out *LimitRange, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.LimitRange))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -754,7 +967,11 @@ func convert_api_LimitRange_To_v1_LimitRange(in *api.LimitRange, out *LimitRange return nil } -func convert_api_LimitRangeItem_To_v1_LimitRangeItem(in *api.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { +func convert_api_LimitRange_To_v1_LimitRange(in *api.LimitRange, out *LimitRange, s conversion.Scope) error { + return autoconvert_api_LimitRange_To_v1_LimitRange(in, out, s) +} + +func autoconvert_api_LimitRangeItem_To_v1_LimitRangeItem(in *api.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.LimitRangeItem))(in) } @@ -822,14 +1039,18 @@ func convert_api_LimitRangeItem_To_v1_LimitRangeItem(in *api.LimitRangeItem, out return nil } -func convert_api_LimitRangeList_To_v1_LimitRangeList(in *api.LimitRangeList, out *LimitRangeList, s conversion.Scope) error { +func convert_api_LimitRangeItem_To_v1_LimitRangeItem(in *api.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { + return autoconvert_api_LimitRangeItem_To_v1_LimitRangeItem(in, out, s) +} + +func autoconvert_api_LimitRangeList_To_v1_LimitRangeList(in *api.LimitRangeList, out *LimitRangeList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.LimitRangeList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -845,7 +1066,11 @@ func convert_api_LimitRangeList_To_v1_LimitRangeList(in *api.LimitRangeList, out return nil } -func convert_api_LimitRangeSpec_To_v1_LimitRangeSpec(in *api.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error { +func convert_api_LimitRangeList_To_v1_LimitRangeList(in *api.LimitRangeList, out *LimitRangeList, s conversion.Scope) error { + return autoconvert_api_LimitRangeList_To_v1_LimitRangeList(in, out, s) +} + +func autoconvert_api_LimitRangeSpec_To_v1_LimitRangeSpec(in *api.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.LimitRangeSpec))(in) } @@ -862,14 +1087,18 @@ func convert_api_LimitRangeSpec_To_v1_LimitRangeSpec(in *api.LimitRangeSpec, out return nil } -func convert_api_List_To_v1_List(in *api.List, out *List, s conversion.Scope) error { +func convert_api_LimitRangeSpec_To_v1_LimitRangeSpec(in *api.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error { + return autoconvert_api_LimitRangeSpec_To_v1_LimitRangeSpec(in, out, s) +} + +func autoconvert_api_List_To_v1_List(in *api.List, out *List, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.List))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if err := s.Convert(&in.Items, &out.Items, 0); err != nil { @@ -878,20 +1107,15 @@ func convert_api_List_To_v1_List(in *api.List, out *List, s conversion.Scope) er return nil } -func convert_api_ListMeta_To_v1_ListMeta(in *api.ListMeta, out *ListMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ListMeta))(in) - } - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil +func convert_api_List_To_v1_List(in *api.List, out *List, s conversion.Scope) error { + return autoconvert_api_List_To_v1_List(in, out, s) } -func convert_api_ListOptions_To_v1_ListOptions(in *api.ListOptions, out *ListOptions, s conversion.Scope) error { +func autoconvert_api_ListOptions_To_v1_ListOptions(in *api.ListOptions, out *ListOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ListOptions))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.LabelSelector, &out.LabelSelector, 0); err != nil { @@ -905,7 +1129,11 @@ func convert_api_ListOptions_To_v1_ListOptions(in *api.ListOptions, out *ListOpt return nil } -func convert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress(in *api.LoadBalancerIngress, out *LoadBalancerIngress, s conversion.Scope) error { +func convert_api_ListOptions_To_v1_ListOptions(in *api.ListOptions, out *ListOptions, s conversion.Scope) error { + return autoconvert_api_ListOptions_To_v1_ListOptions(in, out, s) +} + +func autoconvert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress(in *api.LoadBalancerIngress, out *LoadBalancerIngress, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.LoadBalancerIngress))(in) } @@ -914,7 +1142,11 @@ func convert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress(in *api.LoadBalan return nil } -func convert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus(in *api.LoadBalancerStatus, out *LoadBalancerStatus, s conversion.Scope) error { +func convert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress(in *api.LoadBalancerIngress, out *LoadBalancerIngress, s conversion.Scope) error { + return autoconvert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress(in, out, s) +} + +func autoconvert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus(in *api.LoadBalancerStatus, out *LoadBalancerStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.LoadBalancerStatus))(in) } @@ -931,7 +1163,11 @@ func convert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus(in *api.LoadBalance return nil } -func convert_api_LocalObjectReference_To_v1_LocalObjectReference(in *api.LocalObjectReference, out *LocalObjectReference, s conversion.Scope) error { +func convert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus(in *api.LoadBalancerStatus, out *LoadBalancerStatus, s conversion.Scope) error { + return autoconvert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus(in, out, s) +} + +func autoconvert_api_LocalObjectReference_To_v1_LocalObjectReference(in *api.LocalObjectReference, out *LocalObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.LocalObjectReference))(in) } @@ -939,7 +1175,11 @@ func convert_api_LocalObjectReference_To_v1_LocalObjectReference(in *api.LocalOb return nil } -func convert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in *api.NFSVolumeSource, out *NFSVolumeSource, s conversion.Scope) error { +func convert_api_LocalObjectReference_To_v1_LocalObjectReference(in *api.LocalObjectReference, out *LocalObjectReference, s conversion.Scope) error { + return autoconvert_api_LocalObjectReference_To_v1_LocalObjectReference(in, out, s) +} + +func autoconvert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in *api.NFSVolumeSource, out *NFSVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.NFSVolumeSource))(in) } @@ -949,11 +1189,15 @@ func convert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in *api.NFSVolumeSource, return nil } -func convert_api_Namespace_To_v1_Namespace(in *api.Namespace, out *Namespace, s conversion.Scope) error { +func convert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in *api.NFSVolumeSource, out *NFSVolumeSource, s conversion.Scope) error { + return autoconvert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in, out, s) +} + +func autoconvert_api_Namespace_To_v1_Namespace(in *api.Namespace, out *Namespace, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Namespace))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -968,14 +1212,18 @@ func convert_api_Namespace_To_v1_Namespace(in *api.Namespace, out *Namespace, s return nil } -func convert_api_NamespaceList_To_v1_NamespaceList(in *api.NamespaceList, out *NamespaceList, s conversion.Scope) error { +func convert_api_Namespace_To_v1_Namespace(in *api.Namespace, out *Namespace, s conversion.Scope) error { + return autoconvert_api_Namespace_To_v1_Namespace(in, out, s) +} + +func autoconvert_api_NamespaceList_To_v1_NamespaceList(in *api.NamespaceList, out *NamespaceList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.NamespaceList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -991,7 +1239,11 @@ func convert_api_NamespaceList_To_v1_NamespaceList(in *api.NamespaceList, out *N return nil } -func convert_api_NamespaceSpec_To_v1_NamespaceSpec(in *api.NamespaceSpec, out *NamespaceSpec, s conversion.Scope) error { +func convert_api_NamespaceList_To_v1_NamespaceList(in *api.NamespaceList, out *NamespaceList, s conversion.Scope) error { + return autoconvert_api_NamespaceList_To_v1_NamespaceList(in, out, s) +} + +func autoconvert_api_NamespaceSpec_To_v1_NamespaceSpec(in *api.NamespaceSpec, out *NamespaceSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.NamespaceSpec))(in) } @@ -1006,7 +1258,11 @@ func convert_api_NamespaceSpec_To_v1_NamespaceSpec(in *api.NamespaceSpec, out *N return nil } -func convert_api_NamespaceStatus_To_v1_NamespaceStatus(in *api.NamespaceStatus, out *NamespaceStatus, s conversion.Scope) error { +func convert_api_NamespaceSpec_To_v1_NamespaceSpec(in *api.NamespaceSpec, out *NamespaceSpec, s conversion.Scope) error { + return autoconvert_api_NamespaceSpec_To_v1_NamespaceSpec(in, out, s) +} + +func autoconvert_api_NamespaceStatus_To_v1_NamespaceStatus(in *api.NamespaceStatus, out *NamespaceStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.NamespaceStatus))(in) } @@ -1014,11 +1270,15 @@ func convert_api_NamespaceStatus_To_v1_NamespaceStatus(in *api.NamespaceStatus, return nil } -func convert_api_Node_To_v1_Node(in *api.Node, out *Node, s conversion.Scope) error { +func convert_api_NamespaceStatus_To_v1_NamespaceStatus(in *api.NamespaceStatus, out *NamespaceStatus, s conversion.Scope) error { + return autoconvert_api_NamespaceStatus_To_v1_NamespaceStatus(in, out, s) +} + +func autoconvert_api_Node_To_v1_Node(in *api.Node, out *Node, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Node))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1033,7 +1293,11 @@ func convert_api_Node_To_v1_Node(in *api.Node, out *Node, s conversion.Scope) er return nil } -func convert_api_NodeAddress_To_v1_NodeAddress(in *api.NodeAddress, out *NodeAddress, s conversion.Scope) error { +func convert_api_Node_To_v1_Node(in *api.Node, out *Node, s conversion.Scope) error { + return autoconvert_api_Node_To_v1_Node(in, out, s) +} + +func autoconvert_api_NodeAddress_To_v1_NodeAddress(in *api.NodeAddress, out *NodeAddress, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.NodeAddress))(in) } @@ -1042,7 +1306,11 @@ func convert_api_NodeAddress_To_v1_NodeAddress(in *api.NodeAddress, out *NodeAdd return nil } -func convert_api_NodeCondition_To_v1_NodeCondition(in *api.NodeCondition, out *NodeCondition, s conversion.Scope) error { +func convert_api_NodeAddress_To_v1_NodeAddress(in *api.NodeAddress, out *NodeAddress, s conversion.Scope) error { + return autoconvert_api_NodeAddress_To_v1_NodeAddress(in, out, s) +} + +func autoconvert_api_NodeCondition_To_v1_NodeCondition(in *api.NodeCondition, out *NodeCondition, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.NodeCondition))(in) } @@ -1059,14 +1327,32 @@ func convert_api_NodeCondition_To_v1_NodeCondition(in *api.NodeCondition, out *N return nil } -func convert_api_NodeList_To_v1_NodeList(in *api.NodeList, out *NodeList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { +func convert_api_NodeCondition_To_v1_NodeCondition(in *api.NodeCondition, out *NodeCondition, s conversion.Scope) error { + return autoconvert_api_NodeCondition_To_v1_NodeCondition(in, out, s) +} + +func autoconvert_api_NodeDaemonEndpoints_To_v1_NodeDaemonEndpoints(in *api.NodeDaemonEndpoints, out *NodeDaemonEndpoints, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NodeDaemonEndpoints))(in) + } + if err := convert_api_DaemonEndpoint_To_v1_DaemonEndpoint(&in.KubeletEndpoint, &out.KubeletEndpoint, s); err != nil { + return err + } + return nil +} + +func convert_api_NodeDaemonEndpoints_To_v1_NodeDaemonEndpoints(in *api.NodeDaemonEndpoints, out *NodeDaemonEndpoints, s conversion.Scope) error { + return autoconvert_api_NodeDaemonEndpoints_To_v1_NodeDaemonEndpoints(in, out, s) +} + +func autoconvert_api_NodeList_To_v1_NodeList(in *api.NodeList, out *NodeList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.NodeList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1082,7 +1368,11 @@ func convert_api_NodeList_To_v1_NodeList(in *api.NodeList, out *NodeList, s conv return nil } -func convert_api_NodeSpec_To_v1_NodeSpec(in *api.NodeSpec, out *NodeSpec, s conversion.Scope) error { +func convert_api_NodeList_To_v1_NodeList(in *api.NodeList, out *NodeList, s conversion.Scope) error { + return autoconvert_api_NodeList_To_v1_NodeList(in, out, s) +} + +func autoconvert_api_NodeSpec_To_v1_NodeSpec(in *api.NodeSpec, out *NodeSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.NodeSpec))(in) } @@ -1093,7 +1383,11 @@ func convert_api_NodeSpec_To_v1_NodeSpec(in *api.NodeSpec, out *NodeSpec, s conv return nil } -func convert_api_NodeStatus_To_v1_NodeStatus(in *api.NodeStatus, out *NodeStatus, s conversion.Scope) error { +func convert_api_NodeSpec_To_v1_NodeSpec(in *api.NodeSpec, out *NodeSpec, s conversion.Scope) error { + return autoconvert_api_NodeSpec_To_v1_NodeSpec(in, out, s) +} + +func autoconvert_api_NodeStatus_To_v1_NodeStatus(in *api.NodeStatus, out *NodeStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.NodeStatus))(in) } @@ -1130,13 +1424,20 @@ func convert_api_NodeStatus_To_v1_NodeStatus(in *api.NodeStatus, out *NodeStatus } else { out.Addresses = nil } + if err := convert_api_NodeDaemonEndpoints_To_v1_NodeDaemonEndpoints(&in.DaemonEndpoints, &out.DaemonEndpoints, s); err != nil { + return err + } if err := convert_api_NodeSystemInfo_To_v1_NodeSystemInfo(&in.NodeInfo, &out.NodeInfo, s); err != nil { return err } return nil } -func convert_api_NodeSystemInfo_To_v1_NodeSystemInfo(in *api.NodeSystemInfo, out *NodeSystemInfo, s conversion.Scope) error { +func convert_api_NodeStatus_To_v1_NodeStatus(in *api.NodeStatus, out *NodeStatus, s conversion.Scope) error { + return autoconvert_api_NodeStatus_To_v1_NodeStatus(in, out, s) +} + +func autoconvert_api_NodeSystemInfo_To_v1_NodeSystemInfo(in *api.NodeSystemInfo, out *NodeSystemInfo, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.NodeSystemInfo))(in) } @@ -1151,7 +1452,11 @@ func convert_api_NodeSystemInfo_To_v1_NodeSystemInfo(in *api.NodeSystemInfo, out return nil } -func convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *api.ObjectFieldSelector, out *ObjectFieldSelector, s conversion.Scope) error { +func convert_api_NodeSystemInfo_To_v1_NodeSystemInfo(in *api.NodeSystemInfo, out *NodeSystemInfo, s conversion.Scope) error { + return autoconvert_api_NodeSystemInfo_To_v1_NodeSystemInfo(in, out, s) +} + +func autoconvert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *api.ObjectFieldSelector, out *ObjectFieldSelector, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ObjectFieldSelector))(in) } @@ -1160,7 +1465,11 @@ func convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *api.ObjectFie return nil } -func convert_api_ObjectMeta_To_v1_ObjectMeta(in *api.ObjectMeta, out *ObjectMeta, s conversion.Scope) error { +func convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *api.ObjectFieldSelector, out *ObjectFieldSelector, s conversion.Scope) error { + return autoconvert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in, out, s) +} + +func autoconvert_api_ObjectMeta_To_v1_ObjectMeta(in *api.ObjectMeta, out *ObjectMeta, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ObjectMeta))(in) } @@ -1206,7 +1515,11 @@ func convert_api_ObjectMeta_To_v1_ObjectMeta(in *api.ObjectMeta, out *ObjectMeta return nil } -func convert_api_ObjectReference_To_v1_ObjectReference(in *api.ObjectReference, out *ObjectReference, s conversion.Scope) error { +func convert_api_ObjectMeta_To_v1_ObjectMeta(in *api.ObjectMeta, out *ObjectMeta, s conversion.Scope) error { + return autoconvert_api_ObjectMeta_To_v1_ObjectMeta(in, out, s) +} + +func autoconvert_api_ObjectReference_To_v1_ObjectReference(in *api.ObjectReference, out *ObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ObjectReference))(in) } @@ -1220,11 +1533,15 @@ func convert_api_ObjectReference_To_v1_ObjectReference(in *api.ObjectReference, return nil } -func convert_api_PersistentVolume_To_v1_PersistentVolume(in *api.PersistentVolume, out *PersistentVolume, s conversion.Scope) error { +func convert_api_ObjectReference_To_v1_ObjectReference(in *api.ObjectReference, out *ObjectReference, s conversion.Scope) error { + return autoconvert_api_ObjectReference_To_v1_ObjectReference(in, out, s) +} + +func autoconvert_api_PersistentVolume_To_v1_PersistentVolume(in *api.PersistentVolume, out *PersistentVolume, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PersistentVolume))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1239,11 +1556,15 @@ func convert_api_PersistentVolume_To_v1_PersistentVolume(in *api.PersistentVolum return nil } -func convert_api_PersistentVolumeClaim_To_v1_PersistentVolumeClaim(in *api.PersistentVolumeClaim, out *PersistentVolumeClaim, s conversion.Scope) error { +func convert_api_PersistentVolume_To_v1_PersistentVolume(in *api.PersistentVolume, out *PersistentVolume, s conversion.Scope) error { + return autoconvert_api_PersistentVolume_To_v1_PersistentVolume(in, out, s) +} + +func autoconvert_api_PersistentVolumeClaim_To_v1_PersistentVolumeClaim(in *api.PersistentVolumeClaim, out *PersistentVolumeClaim, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PersistentVolumeClaim))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1258,14 +1579,18 @@ func convert_api_PersistentVolumeClaim_To_v1_PersistentVolumeClaim(in *api.Persi return nil } -func convert_api_PersistentVolumeClaimList_To_v1_PersistentVolumeClaimList(in *api.PersistentVolumeClaimList, out *PersistentVolumeClaimList, s conversion.Scope) error { +func convert_api_PersistentVolumeClaim_To_v1_PersistentVolumeClaim(in *api.PersistentVolumeClaim, out *PersistentVolumeClaim, s conversion.Scope) error { + return autoconvert_api_PersistentVolumeClaim_To_v1_PersistentVolumeClaim(in, out, s) +} + +func autoconvert_api_PersistentVolumeClaimList_To_v1_PersistentVolumeClaimList(in *api.PersistentVolumeClaimList, out *PersistentVolumeClaimList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PersistentVolumeClaimList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1281,7 +1606,11 @@ func convert_api_PersistentVolumeClaimList_To_v1_PersistentVolumeClaimList(in *a return nil } -func convert_api_PersistentVolumeClaimSpec_To_v1_PersistentVolumeClaimSpec(in *api.PersistentVolumeClaimSpec, out *PersistentVolumeClaimSpec, s conversion.Scope) error { +func convert_api_PersistentVolumeClaimList_To_v1_PersistentVolumeClaimList(in *api.PersistentVolumeClaimList, out *PersistentVolumeClaimList, s conversion.Scope) error { + return autoconvert_api_PersistentVolumeClaimList_To_v1_PersistentVolumeClaimList(in, out, s) +} + +func autoconvert_api_PersistentVolumeClaimSpec_To_v1_PersistentVolumeClaimSpec(in *api.PersistentVolumeClaimSpec, out *PersistentVolumeClaimSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PersistentVolumeClaimSpec))(in) } @@ -1300,7 +1629,11 @@ func convert_api_PersistentVolumeClaimSpec_To_v1_PersistentVolumeClaimSpec(in *a return nil } -func convert_api_PersistentVolumeClaimStatus_To_v1_PersistentVolumeClaimStatus(in *api.PersistentVolumeClaimStatus, out *PersistentVolumeClaimStatus, s conversion.Scope) error { +func convert_api_PersistentVolumeClaimSpec_To_v1_PersistentVolumeClaimSpec(in *api.PersistentVolumeClaimSpec, out *PersistentVolumeClaimSpec, s conversion.Scope) error { + return autoconvert_api_PersistentVolumeClaimSpec_To_v1_PersistentVolumeClaimSpec(in, out, s) +} + +func autoconvert_api_PersistentVolumeClaimStatus_To_v1_PersistentVolumeClaimStatus(in *api.PersistentVolumeClaimStatus, out *PersistentVolumeClaimStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PersistentVolumeClaimStatus))(in) } @@ -1328,7 +1661,11 @@ func convert_api_PersistentVolumeClaimStatus_To_v1_PersistentVolumeClaimStatus(i return nil } -func convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in *api.PersistentVolumeClaimVolumeSource, out *PersistentVolumeClaimVolumeSource, s conversion.Scope) error { +func convert_api_PersistentVolumeClaimStatus_To_v1_PersistentVolumeClaimStatus(in *api.PersistentVolumeClaimStatus, out *PersistentVolumeClaimStatus, s conversion.Scope) error { + return autoconvert_api_PersistentVolumeClaimStatus_To_v1_PersistentVolumeClaimStatus(in, out, s) +} + +func autoconvert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in *api.PersistentVolumeClaimVolumeSource, out *PersistentVolumeClaimVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PersistentVolumeClaimVolumeSource))(in) } @@ -1337,14 +1674,18 @@ func convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVo return nil } -func convert_api_PersistentVolumeList_To_v1_PersistentVolumeList(in *api.PersistentVolumeList, out *PersistentVolumeList, s conversion.Scope) error { +func convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in *api.PersistentVolumeClaimVolumeSource, out *PersistentVolumeClaimVolumeSource, s conversion.Scope) error { + return autoconvert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in, out, s) +} + +func autoconvert_api_PersistentVolumeList_To_v1_PersistentVolumeList(in *api.PersistentVolumeList, out *PersistentVolumeList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PersistentVolumeList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1360,7 +1701,11 @@ func convert_api_PersistentVolumeList_To_v1_PersistentVolumeList(in *api.Persist return nil } -func convert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api.PersistentVolumeSource, out *PersistentVolumeSource, s conversion.Scope) error { +func convert_api_PersistentVolumeList_To_v1_PersistentVolumeList(in *api.PersistentVolumeList, out *PersistentVolumeList, s conversion.Scope) error { + return autoconvert_api_PersistentVolumeList_To_v1_PersistentVolumeList(in, out, s) +} + +func autoconvert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api.PersistentVolumeSource, out *PersistentVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PersistentVolumeSource))(in) } @@ -1436,10 +1781,30 @@ func convert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api.Per } else { out.CephFS = nil } + if in.FC != nil { + out.FC = new(FCVolumeSource) + if err := convert_api_FCVolumeSource_To_v1_FCVolumeSource(in.FC, out.FC, s); err != nil { + return err + } + } else { + out.FC = nil + } + if in.Flocker != nil { + out.Flocker = new(FlockerVolumeSource) + if err := convert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource(in.Flocker, out.Flocker, s); err != nil { + return err + } + } else { + out.Flocker = nil + } return nil } -func convert_api_PersistentVolumeSpec_To_v1_PersistentVolumeSpec(in *api.PersistentVolumeSpec, out *PersistentVolumeSpec, s conversion.Scope) error { +func convert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api.PersistentVolumeSource, out *PersistentVolumeSource, s conversion.Scope) error { + return autoconvert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in, out, s) +} + +func autoconvert_api_PersistentVolumeSpec_To_v1_PersistentVolumeSpec(in *api.PersistentVolumeSpec, out *PersistentVolumeSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PersistentVolumeSpec))(in) } @@ -1478,7 +1843,11 @@ func convert_api_PersistentVolumeSpec_To_v1_PersistentVolumeSpec(in *api.Persist return nil } -func convert_api_PersistentVolumeStatus_To_v1_PersistentVolumeStatus(in *api.PersistentVolumeStatus, out *PersistentVolumeStatus, s conversion.Scope) error { +func convert_api_PersistentVolumeSpec_To_v1_PersistentVolumeSpec(in *api.PersistentVolumeSpec, out *PersistentVolumeSpec, s conversion.Scope) error { + return autoconvert_api_PersistentVolumeSpec_To_v1_PersistentVolumeSpec(in, out, s) +} + +func autoconvert_api_PersistentVolumeStatus_To_v1_PersistentVolumeStatus(in *api.PersistentVolumeStatus, out *PersistentVolumeStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PersistentVolumeStatus))(in) } @@ -1488,11 +1857,15 @@ func convert_api_PersistentVolumeStatus_To_v1_PersistentVolumeStatus(in *api.Per return nil } -func convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error { +func convert_api_PersistentVolumeStatus_To_v1_PersistentVolumeStatus(in *api.PersistentVolumeStatus, out *PersistentVolumeStatus, s conversion.Scope) error { + return autoconvert_api_PersistentVolumeStatus_To_v1_PersistentVolumeStatus(in, out, s) +} + +func autoconvert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Pod))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1507,11 +1880,15 @@ func convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error return nil } -func convert_api_PodAttachOptions_To_v1_PodAttachOptions(in *api.PodAttachOptions, out *PodAttachOptions, s conversion.Scope) error { +func convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error { + return autoconvert_api_Pod_To_v1_Pod(in, out, s) +} + +func autoconvert_api_PodAttachOptions_To_v1_PodAttachOptions(in *api.PodAttachOptions, out *PodAttachOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodAttachOptions))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Stdin = in.Stdin @@ -1522,20 +1899,36 @@ func convert_api_PodAttachOptions_To_v1_PodAttachOptions(in *api.PodAttachOption return nil } -func convert_api_PodCondition_To_v1_PodCondition(in *api.PodCondition, out *PodCondition, s conversion.Scope) error { +func convert_api_PodAttachOptions_To_v1_PodAttachOptions(in *api.PodAttachOptions, out *PodAttachOptions, s conversion.Scope) error { + return autoconvert_api_PodAttachOptions_To_v1_PodAttachOptions(in, out, s) +} + +func autoconvert_api_PodCondition_To_v1_PodCondition(in *api.PodCondition, out *PodCondition, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodCondition))(in) } out.Type = PodConditionType(in.Type) out.Status = ConditionStatus(in.Status) + if err := s.Convert(&in.LastProbeTime, &out.LastProbeTime, 0); err != nil { + return err + } + if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message return nil } -func convert_api_PodExecOptions_To_v1_PodExecOptions(in *api.PodExecOptions, out *PodExecOptions, s conversion.Scope) error { +func convert_api_PodCondition_To_v1_PodCondition(in *api.PodCondition, out *PodCondition, s conversion.Scope) error { + return autoconvert_api_PodCondition_To_v1_PodCondition(in, out, s) +} + +func autoconvert_api_PodExecOptions_To_v1_PodExecOptions(in *api.PodExecOptions, out *PodExecOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodExecOptions))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Stdin = in.Stdin @@ -1554,14 +1947,18 @@ func convert_api_PodExecOptions_To_v1_PodExecOptions(in *api.PodExecOptions, out return nil } -func convert_api_PodList_To_v1_PodList(in *api.PodList, out *PodList, s conversion.Scope) error { +func convert_api_PodExecOptions_To_v1_PodExecOptions(in *api.PodExecOptions, out *PodExecOptions, s conversion.Scope) error { + return autoconvert_api_PodExecOptions_To_v1_PodExecOptions(in, out, s) +} + +func autoconvert_api_PodList_To_v1_PodList(in *api.PodList, out *PodList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1577,31 +1974,137 @@ func convert_api_PodList_To_v1_PodList(in *api.PodList, out *PodList, s conversi return nil } -func convert_api_PodLogOptions_To_v1_PodLogOptions(in *api.PodLogOptions, out *PodLogOptions, s conversion.Scope) error { +func convert_api_PodList_To_v1_PodList(in *api.PodList, out *PodList, s conversion.Scope) error { + return autoconvert_api_PodList_To_v1_PodList(in, out, s) +} + +func autoconvert_api_PodLogOptions_To_v1_PodLogOptions(in *api.PodLogOptions, out *PodLogOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodLogOptions))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Container = in.Container out.Follow = in.Follow out.Previous = in.Previous + if in.SinceSeconds != nil { + out.SinceSeconds = new(int64) + *out.SinceSeconds = *in.SinceSeconds + } else { + out.SinceSeconds = nil + } + if in.SinceTime != nil { + if err := s.Convert(&in.SinceTime, &out.SinceTime, 0); err != nil { + return err + } + } else { + out.SinceTime = nil + } + out.Timestamps = in.Timestamps + if in.TailLines != nil { + out.TailLines = new(int64) + *out.TailLines = *in.TailLines + } else { + out.TailLines = nil + } + if in.LimitBytes != nil { + out.LimitBytes = new(int64) + *out.LimitBytes = *in.LimitBytes + } else { + out.LimitBytes = nil + } return nil } -func convert_api_PodProxyOptions_To_v1_PodProxyOptions(in *api.PodProxyOptions, out *PodProxyOptions, s conversion.Scope) error { +func convert_api_PodLogOptions_To_v1_PodLogOptions(in *api.PodLogOptions, out *PodLogOptions, s conversion.Scope) error { + return autoconvert_api_PodLogOptions_To_v1_PodLogOptions(in, out, s) +} + +func autoconvert_api_PodProxyOptions_To_v1_PodProxyOptions(in *api.PodProxyOptions, out *PodProxyOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodProxyOptions))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Path = in.Path return nil } -func convert_api_PodStatus_To_v1_PodStatus(in *api.PodStatus, out *PodStatus, s conversion.Scope) error { +func convert_api_PodProxyOptions_To_v1_PodProxyOptions(in *api.PodProxyOptions, out *PodProxyOptions, s conversion.Scope) error { + return autoconvert_api_PodProxyOptions_To_v1_PodProxyOptions(in, out, s) +} + +func autoconvert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodSpec))(in) + } + if in.Volumes != nil { + out.Volumes = make([]Volume, len(in.Volumes)) + for i := range in.Volumes { + if err := convert_api_Volume_To_v1_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil { + return err + } + } + } else { + out.Volumes = nil + } + if in.Containers != nil { + out.Containers = make([]Container, len(in.Containers)) + for i := range in.Containers { + if err := convert_api_Container_To_v1_Container(&in.Containers[i], &out.Containers[i], s); err != nil { + return err + } + } + } else { + out.Containers = nil + } + out.RestartPolicy = RestartPolicy(in.RestartPolicy) + if in.TerminationGracePeriodSeconds != nil { + out.TerminationGracePeriodSeconds = new(int64) + *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds + } else { + out.TerminationGracePeriodSeconds = nil + } + if in.ActiveDeadlineSeconds != nil { + out.ActiveDeadlineSeconds = new(int64) + *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds + } else { + out.ActiveDeadlineSeconds = nil + } + out.DNSPolicy = DNSPolicy(in.DNSPolicy) + if in.NodeSelector != nil { + out.NodeSelector = make(map[string]string) + for key, val := range in.NodeSelector { + out.NodeSelector[key] = val + } + } else { + out.NodeSelector = nil + } + out.ServiceAccountName = in.ServiceAccountName + out.NodeName = in.NodeName + if in.SecurityContext != nil { + if err := s.Convert(&in.SecurityContext, &out.SecurityContext, 0); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + if in.ImagePullSecrets != nil { + out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) + for i := range in.ImagePullSecrets { + if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { + return err + } + } + } else { + out.ImagePullSecrets = nil + } + return nil +} + +func autoconvert_api_PodStatus_To_v1_PodStatus(in *api.PodStatus, out *PodStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodStatus))(in) } @@ -1640,11 +2143,15 @@ func convert_api_PodStatus_To_v1_PodStatus(in *api.PodStatus, out *PodStatus, s return nil } -func convert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { +func convert_api_PodStatus_To_v1_PodStatus(in *api.PodStatus, out *PodStatus, s conversion.Scope) error { + return autoconvert_api_PodStatus_To_v1_PodStatus(in, out, s) +} + +func autoconvert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodStatusResult))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1656,11 +2163,15 @@ func convert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, return nil } -func convert_api_PodTemplate_To_v1_PodTemplate(in *api.PodTemplate, out *PodTemplate, s conversion.Scope) error { +func convert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { + return autoconvert_api_PodStatusResult_To_v1_PodStatusResult(in, out, s) +} + +func autoconvert_api_PodTemplate_To_v1_PodTemplate(in *api.PodTemplate, out *PodTemplate, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodTemplate))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1672,14 +2183,18 @@ func convert_api_PodTemplate_To_v1_PodTemplate(in *api.PodTemplate, out *PodTemp return nil } -func convert_api_PodTemplateList_To_v1_PodTemplateList(in *api.PodTemplateList, out *PodTemplateList, s conversion.Scope) error { +func convert_api_PodTemplate_To_v1_PodTemplate(in *api.PodTemplate, out *PodTemplate, s conversion.Scope) error { + return autoconvert_api_PodTemplate_To_v1_PodTemplate(in, out, s) +} + +func autoconvert_api_PodTemplateList_To_v1_PodTemplateList(in *api.PodTemplateList, out *PodTemplateList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodTemplateList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1695,7 +2210,11 @@ func convert_api_PodTemplateList_To_v1_PodTemplateList(in *api.PodTemplateList, return nil } -func convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error { +func convert_api_PodTemplateList_To_v1_PodTemplateList(in *api.PodTemplateList, out *PodTemplateList, s conversion.Scope) error { + return autoconvert_api_PodTemplateList_To_v1_PodTemplateList(in, out, s) +} + +func autoconvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodTemplateSpec))(in) } @@ -1708,7 +2227,11 @@ func convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, return nil } -func convert_api_Probe_To_v1_Probe(in *api.Probe, out *Probe, s conversion.Scope) error { +func convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error { + return autoconvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s) +} + +func autoconvert_api_Probe_To_v1_Probe(in *api.Probe, out *Probe, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Probe))(in) } @@ -1720,7 +2243,11 @@ func convert_api_Probe_To_v1_Probe(in *api.Probe, out *Probe, s conversion.Scope return nil } -func convert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in *api.RBDVolumeSource, out *RBDVolumeSource, s conversion.Scope) error { +func convert_api_Probe_To_v1_Probe(in *api.Probe, out *Probe, s conversion.Scope) error { + return autoconvert_api_Probe_To_v1_Probe(in, out, s) +} + +func autoconvert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in *api.RBDVolumeSource, out *RBDVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.RBDVolumeSource))(in) } @@ -1749,11 +2276,15 @@ func convert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in *api.RBDVolumeSource, return nil } -func convert_api_RangeAllocation_To_v1_RangeAllocation(in *api.RangeAllocation, out *RangeAllocation, s conversion.Scope) error { +func convert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in *api.RBDVolumeSource, out *RBDVolumeSource, s conversion.Scope) error { + return autoconvert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in, out, s) +} + +func autoconvert_api_RangeAllocation_To_v1_RangeAllocation(in *api.RangeAllocation, out *RangeAllocation, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.RangeAllocation))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1766,11 +2297,15 @@ func convert_api_RangeAllocation_To_v1_RangeAllocation(in *api.RangeAllocation, return nil } -func convert_api_ReplicationController_To_v1_ReplicationController(in *api.ReplicationController, out *ReplicationController, s conversion.Scope) error { +func convert_api_RangeAllocation_To_v1_RangeAllocation(in *api.RangeAllocation, out *RangeAllocation, s conversion.Scope) error { + return autoconvert_api_RangeAllocation_To_v1_RangeAllocation(in, out, s) +} + +func autoconvert_api_ReplicationController_To_v1_ReplicationController(in *api.ReplicationController, out *ReplicationController, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ReplicationController))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1785,14 +2320,18 @@ func convert_api_ReplicationController_To_v1_ReplicationController(in *api.Repli return nil } -func convert_api_ReplicationControllerList_To_v1_ReplicationControllerList(in *api.ReplicationControllerList, out *ReplicationControllerList, s conversion.Scope) error { +func convert_api_ReplicationController_To_v1_ReplicationController(in *api.ReplicationController, out *ReplicationController, s conversion.Scope) error { + return autoconvert_api_ReplicationController_To_v1_ReplicationController(in, out, s) +} + +func autoconvert_api_ReplicationControllerList_To_v1_ReplicationControllerList(in *api.ReplicationControllerList, out *ReplicationControllerList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ReplicationControllerList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1808,7 +2347,37 @@ func convert_api_ReplicationControllerList_To_v1_ReplicationControllerList(in *a return nil } -func convert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStatus(in *api.ReplicationControllerStatus, out *ReplicationControllerStatus, s conversion.Scope) error { +func convert_api_ReplicationControllerList_To_v1_ReplicationControllerList(in *api.ReplicationControllerList, out *ReplicationControllerList, s conversion.Scope) error { + return autoconvert_api_ReplicationControllerList_To_v1_ReplicationControllerList(in, out, s) +} + +func autoconvert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *api.ReplicationControllerSpec, out *ReplicationControllerSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ReplicationControllerSpec))(in) + } + if err := s.Convert(&in.Replicas, &out.Replicas, 0); err != nil { + return err + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(PodTemplateSpec) + if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + return nil +} + +func autoconvert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStatus(in *api.ReplicationControllerStatus, out *ReplicationControllerStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ReplicationControllerStatus))(in) } @@ -1817,11 +2386,15 @@ func convert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStatus(i return nil } -func convert_api_ResourceQuota_To_v1_ResourceQuota(in *api.ResourceQuota, out *ResourceQuota, s conversion.Scope) error { +func convert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStatus(in *api.ReplicationControllerStatus, out *ReplicationControllerStatus, s conversion.Scope) error { + return autoconvert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStatus(in, out, s) +} + +func autoconvert_api_ResourceQuota_To_v1_ResourceQuota(in *api.ResourceQuota, out *ResourceQuota, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ResourceQuota))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1836,14 +2409,18 @@ func convert_api_ResourceQuota_To_v1_ResourceQuota(in *api.ResourceQuota, out *R return nil } -func convert_api_ResourceQuotaList_To_v1_ResourceQuotaList(in *api.ResourceQuotaList, out *ResourceQuotaList, s conversion.Scope) error { +func convert_api_ResourceQuota_To_v1_ResourceQuota(in *api.ResourceQuota, out *ResourceQuota, s conversion.Scope) error { + return autoconvert_api_ResourceQuota_To_v1_ResourceQuota(in, out, s) +} + +func autoconvert_api_ResourceQuotaList_To_v1_ResourceQuotaList(in *api.ResourceQuotaList, out *ResourceQuotaList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ResourceQuotaList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1859,7 +2436,11 @@ func convert_api_ResourceQuotaList_To_v1_ResourceQuotaList(in *api.ResourceQuota return nil } -func convert_api_ResourceQuotaSpec_To_v1_ResourceQuotaSpec(in *api.ResourceQuotaSpec, out *ResourceQuotaSpec, s conversion.Scope) error { +func convert_api_ResourceQuotaList_To_v1_ResourceQuotaList(in *api.ResourceQuotaList, out *ResourceQuotaList, s conversion.Scope) error { + return autoconvert_api_ResourceQuotaList_To_v1_ResourceQuotaList(in, out, s) +} + +func autoconvert_api_ResourceQuotaSpec_To_v1_ResourceQuotaSpec(in *api.ResourceQuotaSpec, out *ResourceQuotaSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ResourceQuotaSpec))(in) } @@ -1878,7 +2459,11 @@ func convert_api_ResourceQuotaSpec_To_v1_ResourceQuotaSpec(in *api.ResourceQuota return nil } -func convert_api_ResourceQuotaStatus_To_v1_ResourceQuotaStatus(in *api.ResourceQuotaStatus, out *ResourceQuotaStatus, s conversion.Scope) error { +func convert_api_ResourceQuotaSpec_To_v1_ResourceQuotaSpec(in *api.ResourceQuotaSpec, out *ResourceQuotaSpec, s conversion.Scope) error { + return autoconvert_api_ResourceQuotaSpec_To_v1_ResourceQuotaSpec(in, out, s) +} + +func autoconvert_api_ResourceQuotaStatus_To_v1_ResourceQuotaStatus(in *api.ResourceQuotaStatus, out *ResourceQuotaStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ResourceQuotaStatus))(in) } @@ -1909,7 +2494,11 @@ func convert_api_ResourceQuotaStatus_To_v1_ResourceQuotaStatus(in *api.ResourceQ return nil } -func convert_api_ResourceRequirements_To_v1_ResourceRequirements(in *api.ResourceRequirements, out *ResourceRequirements, s conversion.Scope) error { +func convert_api_ResourceQuotaStatus_To_v1_ResourceQuotaStatus(in *api.ResourceQuotaStatus, out *ResourceQuotaStatus, s conversion.Scope) error { + return autoconvert_api_ResourceQuotaStatus_To_v1_ResourceQuotaStatus(in, out, s) +} + +func autoconvert_api_ResourceRequirements_To_v1_ResourceRequirements(in *api.ResourceRequirements, out *ResourceRequirements, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ResourceRequirements))(in) } @@ -1940,91 +2529,11 @@ func convert_api_ResourceRequirements_To_v1_ResourceRequirements(in *api.Resourc return nil } -func convert_api_FSGroupStrategyOptions_To_v1_FSGroupStrategyOptions(in *api.FSGroupStrategyOptions, out *FSGroupStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.FSGroupStrategyOptions))(in) - } - out.Type = FSGroupStrategyType(in.Type) - if in.Ranges != nil { - out.Ranges = make([]IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := convert_api_IDRange_To_v1_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func convert_api_SupplementalGroupsStrategyOptions_To_v1_SupplementalGroupsStrategyOptions(in *api.SupplementalGroupsStrategyOptions, out *SupplementalGroupsStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SupplementalGroupsStrategyOptions))(in) - } - out.Type = SupplementalGroupsStrategyType(in.Type) - if in.Ranges != nil { - out.Ranges = make([]IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := convert_api_IDRange_To_v1_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func convert_api_IDRange_To_v1_IDRange(in *api.IDRange, out *IDRange, s conversion.Scope) error { - out.Min = in.Min - out.Max = in.Max - return nil -} - -func convert_api_RunAsUserStrategyOptions_To_v1_RunAsUserStrategyOptions(in *api.RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.RunAsUserStrategyOptions))(in) - } - out.Type = RunAsUserStrategyType(in.Type) - if in.UID != nil { - out.UID = new(int64) - *out.UID = *in.UID - } else { - out.UID = nil - } - if in.UIDRangeMin != nil { - out.UIDRangeMin = new(int64) - *out.UIDRangeMin = *in.UIDRangeMin - } else { - out.UIDRangeMin = nil - } - if in.UIDRangeMax != nil { - out.UIDRangeMax = new(int64) - *out.UIDRangeMax = *in.UIDRangeMax - } else { - out.UIDRangeMax = nil - } - return nil -} - -func convert_api_SELinuxContextStrategyOptions_To_v1_SELinuxContextStrategyOptions(in *api.SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SELinuxContextStrategyOptions))(in) - } - out.Type = SELinuxContextStrategyType(in.Type) - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(SELinuxOptions) - if err := convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - return nil -} - -func convert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, out *SELinuxOptions, s conversion.Scope) error { +func convert_api_ResourceRequirements_To_v1_ResourceRequirements(in *api.ResourceRequirements, out *ResourceRequirements, s conversion.Scope) error { + return autoconvert_api_ResourceRequirements_To_v1_ResourceRequirements(in, out, s) +} + +func autoconvert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, out *SELinuxOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.SELinuxOptions))(in) } @@ -2035,11 +2544,15 @@ func convert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, out return nil } -func convert_api_Secret_To_v1_Secret(in *api.Secret, out *Secret, s conversion.Scope) error { +func convert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, out *SELinuxOptions, s conversion.Scope) error { + return autoconvert_api_SELinuxOptions_To_v1_SELinuxOptions(in, out, s) +} + +func autoconvert_api_Secret_To_v1_Secret(in *api.Secret, out *Secret, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Secret))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2061,14 +2574,18 @@ func convert_api_Secret_To_v1_Secret(in *api.Secret, out *Secret, s conversion.S return nil } -func convert_api_SecretList_To_v1_SecretList(in *api.SecretList, out *SecretList, s conversion.Scope) error { +func convert_api_Secret_To_v1_Secret(in *api.Secret, out *Secret, s conversion.Scope) error { + return autoconvert_api_Secret_To_v1_Secret(in, out, s) +} + +func autoconvert_api_SecretList_To_v1_SecretList(in *api.SecretList, out *SecretList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.SecretList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2084,7 +2601,11 @@ func convert_api_SecretList_To_v1_SecretList(in *api.SecretList, out *SecretList return nil } -func convert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretVolumeSource, out *SecretVolumeSource, s conversion.Scope) error { +func convert_api_SecretList_To_v1_SecretList(in *api.SecretList, out *SecretList, s conversion.Scope) error { + return autoconvert_api_SecretList_To_v1_SecretList(in, out, s) +} + +func autoconvert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretVolumeSource, out *SecretVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.SecretVolumeSource))(in) } @@ -2092,7 +2613,11 @@ func convert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretVolum return nil } -func convert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityContext, out *SecurityContext, s conversion.Scope) error { +func convert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretVolumeSource, out *SecretVolumeSource, s conversion.Scope) error { + return autoconvert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in, out, s) +} + +func autoconvert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityContext, out *SecurityContext, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.SecurityContext))(in) } @@ -2128,102 +2653,32 @@ func convert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityContext, return nil } -func convert_api_SecurityContextConstraints_To_v1_SecurityContextConstraints(in *api.SecurityContextConstraints, out *SecurityContextConstraints, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SecurityContextConstraints))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - out.AllowPrivilegedContainer = in.AllowPrivilegedContainer - if in.AllowedCapabilities != nil { - out.AllowedCapabilities = make([]Capability, len(in.AllowedCapabilities)) - for i := range in.AllowedCapabilities { - out.AllowedCapabilities[i] = Capability(in.AllowedCapabilities[i]) - } - } else { - out.AllowedCapabilities = nil - } - out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin - out.AllowHostNetwork = in.AllowHostNetwork - out.AllowHostPorts = in.AllowHostPorts - out.AllowHostPID = in.AllowHostPID - out.AllowHostIPC = in.AllowHostIPC - if err := convert_api_SELinuxContextStrategyOptions_To_v1_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil { - return err - } - if err := convert_api_RunAsUserStrategyOptions_To_v1_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil { - return err - } - if err := convert_api_FSGroupStrategyOptions_To_v1_FSGroupStrategyOptions(&in.FSGroup, &out.FSGroup, s); err != nil { - return err - } - if err := convert_api_SupplementalGroupsStrategyOptions_To_v1_SupplementalGroupsStrategyOptions(&in.SupplementalGroups, &out.SupplementalGroups, s); err != nil { - return err - } - if in.Users != nil { - out.Users = make([]string, len(in.Users)) - for i := range in.Users { - out.Users[i] = in.Users[i] - } - } else { - out.Users = nil - } - if in.Groups != nil { - out.Groups = make([]string, len(in.Groups)) - for i := range in.Groups { - out.Groups[i] = in.Groups[i] - } - } else { - out.Groups = nil - } - return nil +func convert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityContext, out *SecurityContext, s conversion.Scope) error { + return autoconvert_api_SecurityContext_To_v1_SecurityContext(in, out, s) } -func convert_api_SecurityContextConstraintsList_To_v1_SecurityContextConstraintsList(in *api.SecurityContextConstraintsList, out *SecurityContextConstraintsList, s conversion.Scope) error { +func autoconvert_api_SerializedReference_To_v1_SerializedReference(in *api.SerializedReference, out *SerializedReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SecurityContextConstraintsList))(in) + defaulting.(func(*api.SerializedReference))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := convert_api_ObjectReference_To_v1_ObjectReference(&in.Reference, &out.Reference, s); err != nil { return err } - if in.Items != nil { - out.Items = make([]SecurityContextConstraints, len(in.Items)) - for i := range in.Items { - if err := convert_api_SecurityContextConstraints_To_v1_SecurityContextConstraints(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } return nil } func convert_api_SerializedReference_To_v1_SerializedReference(in *api.SerializedReference, out *SerializedReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SerializedReference))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectReference_To_v1_ObjectReference(&in.Reference, &out.Reference, s); err != nil { - return err - } - return nil + return autoconvert_api_SerializedReference_To_v1_SerializedReference(in, out, s) } -func convert_api_Service_To_v1_Service(in *api.Service, out *Service, s conversion.Scope) error { +func autoconvert_api_Service_To_v1_Service(in *api.Service, out *Service, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Service))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2238,11 +2693,15 @@ func convert_api_Service_To_v1_Service(in *api.Service, out *Service, s conversi return nil } -func convert_api_ServiceAccount_To_v1_ServiceAccount(in *api.ServiceAccount, out *ServiceAccount, s conversion.Scope) error { +func convert_api_Service_To_v1_Service(in *api.Service, out *Service, s conversion.Scope) error { + return autoconvert_api_Service_To_v1_Service(in, out, s) +} + +func autoconvert_api_ServiceAccount_To_v1_ServiceAccount(in *api.ServiceAccount, out *ServiceAccount, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ServiceAccount))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2271,14 +2730,18 @@ func convert_api_ServiceAccount_To_v1_ServiceAccount(in *api.ServiceAccount, out return nil } -func convert_api_ServiceAccountList_To_v1_ServiceAccountList(in *api.ServiceAccountList, out *ServiceAccountList, s conversion.Scope) error { +func convert_api_ServiceAccount_To_v1_ServiceAccount(in *api.ServiceAccount, out *ServiceAccount, s conversion.Scope) error { + return autoconvert_api_ServiceAccount_To_v1_ServiceAccount(in, out, s) +} + +func autoconvert_api_ServiceAccountList_To_v1_ServiceAccountList(in *api.ServiceAccountList, out *ServiceAccountList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ServiceAccountList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2294,14 +2757,18 @@ func convert_api_ServiceAccountList_To_v1_ServiceAccountList(in *api.ServiceAcco return nil } -func convert_api_ServiceList_To_v1_ServiceList(in *api.ServiceList, out *ServiceList, s conversion.Scope) error { +func convert_api_ServiceAccountList_To_v1_ServiceAccountList(in *api.ServiceAccountList, out *ServiceAccountList, s conversion.Scope) error { + return autoconvert_api_ServiceAccountList_To_v1_ServiceAccountList(in, out, s) +} + +func autoconvert_api_ServiceList_To_v1_ServiceList(in *api.ServiceList, out *ServiceList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ServiceList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2317,7 +2784,11 @@ func convert_api_ServiceList_To_v1_ServiceList(in *api.ServiceList, out *Service return nil } -func convert_api_ServicePort_To_v1_ServicePort(in *api.ServicePort, out *ServicePort, s conversion.Scope) error { +func convert_api_ServiceList_To_v1_ServiceList(in *api.ServiceList, out *ServiceList, s conversion.Scope) error { + return autoconvert_api_ServiceList_To_v1_ServiceList(in, out, s) +} + +func autoconvert_api_ServicePort_To_v1_ServicePort(in *api.ServicePort, out *ServicePort, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ServicePort))(in) } @@ -2331,7 +2802,11 @@ func convert_api_ServicePort_To_v1_ServicePort(in *api.ServicePort, out *Service return nil } -func convert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *ServiceSpec, s conversion.Scope) error { +func convert_api_ServicePort_To_v1_ServicePort(in *api.ServicePort, out *ServicePort, s conversion.Scope) error { + return autoconvert_api_ServicePort_To_v1_ServicePort(in, out, s) +} + +func autoconvert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *ServiceSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ServiceSpec))(in) } @@ -2365,14 +2840,10 @@ func convert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *Service } out.LoadBalancerIP = in.LoadBalancerIP out.SessionAffinity = ServiceAffinity(in.SessionAffinity) - - // Carry conversion - out.DeprecatedPortalIP = in.ClusterIP - return nil } -func convert_api_ServiceStatus_To_v1_ServiceStatus(in *api.ServiceStatus, out *ServiceStatus, s conversion.Scope) error { +func autoconvert_api_ServiceStatus_To_v1_ServiceStatus(in *api.ServiceStatus, out *ServiceStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ServiceStatus))(in) } @@ -2382,62 +2853,11 @@ func convert_api_ServiceStatus_To_v1_ServiceStatus(in *api.ServiceStatus, out *S return nil } -func convert_api_Status_To_v1_Status(in *api.Status, out *Status, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Status))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - out.Status = in.Status - out.Message = in.Message - out.Reason = StatusReason(in.Reason) - if in.Details != nil { - out.Details = new(StatusDetails) - if err := convert_api_StatusDetails_To_v1_StatusDetails(in.Details, out.Details, s); err != nil { - return err - } - } else { - out.Details = nil - } - out.Code = in.Code - return nil -} - -func convert_api_StatusCause_To_v1_StatusCause(in *api.StatusCause, out *StatusCause, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.StatusCause))(in) - } - out.Type = CauseType(in.Type) - out.Message = in.Message - out.Field = in.Field - return nil -} - -func convert_api_StatusDetails_To_v1_StatusDetails(in *api.StatusDetails, out *StatusDetails, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.StatusDetails))(in) - } - out.Name = in.Name - out.Kind = in.Kind - if in.Causes != nil { - out.Causes = make([]StatusCause, len(in.Causes)) - for i := range in.Causes { - if err := convert_api_StatusCause_To_v1_StatusCause(&in.Causes[i], &out.Causes[i], s); err != nil { - return err - } - } - } else { - out.Causes = nil - } - out.RetryAfterSeconds = in.RetryAfterSeconds - return nil +func convert_api_ServiceStatus_To_v1_ServiceStatus(in *api.ServiceStatus, out *ServiceStatus, s conversion.Scope) error { + return autoconvert_api_ServiceStatus_To_v1_ServiceStatus(in, out, s) } -func convert_api_TCPSocketAction_To_v1_TCPSocketAction(in *api.TCPSocketAction, out *TCPSocketAction, s conversion.Scope) error { +func autoconvert_api_TCPSocketAction_To_v1_TCPSocketAction(in *api.TCPSocketAction, out *TCPSocketAction, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.TCPSocketAction))(in) } @@ -2447,16 +2867,11 @@ func convert_api_TCPSocketAction_To_v1_TCPSocketAction(in *api.TCPSocketAction, return nil } -func convert_api_TypeMeta_To_v1_TypeMeta(in *api.TypeMeta, out *TypeMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.TypeMeta))(in) - } - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil +func convert_api_TCPSocketAction_To_v1_TCPSocketAction(in *api.TCPSocketAction, out *TCPSocketAction, s conversion.Scope) error { + return autoconvert_api_TCPSocketAction_To_v1_TCPSocketAction(in, out, s) } -func convert_api_Volume_To_v1_Volume(in *api.Volume, out *Volume, s conversion.Scope) error { +func autoconvert_api_Volume_To_v1_Volume(in *api.Volume, out *Volume, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Volume))(in) } @@ -2467,7 +2882,11 @@ func convert_api_Volume_To_v1_Volume(in *api.Volume, out *Volume, s conversion.S return nil } -func convert_api_VolumeMount_To_v1_VolumeMount(in *api.VolumeMount, out *VolumeMount, s conversion.Scope) error { +func convert_api_Volume_To_v1_Volume(in *api.Volume, out *Volume, s conversion.Scope) error { + return autoconvert_api_Volume_To_v1_Volume(in, out, s) +} + +func autoconvert_api_VolumeMount_To_v1_VolumeMount(in *api.VolumeMount, out *VolumeMount, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.VolumeMount))(in) } @@ -2477,83 +2896,242 @@ func convert_api_VolumeMount_To_v1_VolumeMount(in *api.VolumeMount, out *VolumeM return nil } -func convert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in *AWSElasticBlockStoreVolumeSource, out *api.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*AWSElasticBlockStoreVolumeSource))(in) - } - out.VolumeID = in.VolumeID - out.FSType = in.FSType - out.Partition = in.Partition - out.ReadOnly = in.ReadOnly - return nil +func convert_api_VolumeMount_To_v1_VolumeMount(in *api.VolumeMount, out *VolumeMount, s conversion.Scope) error { + return autoconvert_api_VolumeMount_To_v1_VolumeMount(in, out, s) } -func convert_v1_Binding_To_api_Binding(in *Binding, out *api.Binding, s conversion.Scope) error { +func autoconvert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *VolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Binding))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err + defaulting.(func(*api.VolumeSource))(in) } - if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.Target, &out.Target, s); err != nil { - return err + if in.HostPath != nil { + out.HostPath = new(HostPathVolumeSource) + if err := convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in.HostPath, out.HostPath, s); err != nil { + return err + } + } else { + out.HostPath = nil } - return nil -} - -func convert_v1_Capabilities_To_api_Capabilities(in *Capabilities, out *api.Capabilities, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Capabilities))(in) + if in.EmptyDir != nil { + out.EmptyDir = new(EmptyDirVolumeSource) + if err := convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in.EmptyDir, out.EmptyDir, s); err != nil { + return err + } + } else { + out.EmptyDir = nil } - if in.Add != nil { - out.Add = make([]api.Capability, len(in.Add)) - for i := range in.Add { - out.Add[i] = api.Capability(in.Add[i]) + if in.GCEPersistentDisk != nil { + out.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) + if err := convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in.GCEPersistentDisk, out.GCEPersistentDisk, s); err != nil { + return err } } else { - out.Add = nil + out.GCEPersistentDisk = nil } - if in.Drop != nil { - out.Drop = make([]api.Capability, len(in.Drop)) - for i := range in.Drop { - out.Drop[i] = api.Capability(in.Drop[i]) + if in.AWSElasticBlockStore != nil { + out.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) + if err := convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in.AWSElasticBlockStore, out.AWSElasticBlockStore, s); err != nil { + return err } } else { - out.Drop = nil + out.AWSElasticBlockStore = nil } - return nil -} - -func convert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in *CephFSVolumeSource, out *api.CephFSVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*CephFSVolumeSource))(in) + if in.GitRepo != nil { + out.GitRepo = new(GitRepoVolumeSource) + if err := convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in.GitRepo, out.GitRepo, s); err != nil { + return err + } + } else { + out.GitRepo = nil } - if in.Monitors != nil { - out.Monitors = make([]string, len(in.Monitors)) - for i := range in.Monitors { - out.Monitors[i] = in.Monitors[i] + if in.Secret != nil { + out.Secret = new(SecretVolumeSource) + if err := convert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in.Secret, out.Secret, s); err != nil { + return err } } else { - out.Monitors = nil + out.Secret = nil } - out.User = in.User - out.SecretFile = in.SecretFile - if in.SecretRef != nil { - out.SecretRef = new(api.LocalObjectReference) - if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + if in.NFS != nil { + out.NFS = new(NFSVolumeSource) + if err := convert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in.NFS, out.NFS, s); err != nil { return err } } else { - out.SecretRef = nil + out.NFS = nil + } + if in.ISCSI != nil { + out.ISCSI = new(ISCSIVolumeSource) + if err := convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { + return err + } + } else { + out.ISCSI = nil + } + if in.Glusterfs != nil { + out.Glusterfs = new(GlusterfsVolumeSource) + if err := convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { + return err + } + } else { + out.Glusterfs = nil + } + if in.PersistentVolumeClaim != nil { + out.PersistentVolumeClaim = new(PersistentVolumeClaimVolumeSource) + if err := convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in.PersistentVolumeClaim, out.PersistentVolumeClaim, s); err != nil { + return err + } + } else { + out.PersistentVolumeClaim = nil + } + if in.RBD != nil { + out.RBD = new(RBDVolumeSource) + if err := convert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in.RBD, out.RBD, s); err != nil { + return err + } + } else { + out.RBD = nil + } + if in.Cinder != nil { + out.Cinder = new(CinderVolumeSource) + if err := convert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in.Cinder, out.Cinder, s); err != nil { + return err + } + } else { + out.Cinder = nil + } + if in.CephFS != nil { + out.CephFS = new(CephFSVolumeSource) + if err := convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in.CephFS, out.CephFS, s); err != nil { + return err + } + } else { + out.CephFS = nil + } + if in.Flocker != nil { + out.Flocker = new(FlockerVolumeSource) + if err := convert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource(in.Flocker, out.Flocker, s); err != nil { + return err + } + } else { + out.Flocker = nil + } + if in.DownwardAPI != nil { + out.DownwardAPI = new(DownwardAPIVolumeSource) + if err := convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in.DownwardAPI, out.DownwardAPI, s); err != nil { + return err + } + } else { + out.DownwardAPI = nil + } + if in.FC != nil { + out.FC = new(FCVolumeSource) + if err := convert_api_FCVolumeSource_To_v1_FCVolumeSource(in.FC, out.FC, s); err != nil { + return err + } + } else { + out.FC = nil } - out.ReadOnly = in.ReadOnly return nil } -func convert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in *CinderVolumeSource, out *api.CinderVolumeSource, s conversion.Scope) error { +func convert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *VolumeSource, s conversion.Scope) error { + return autoconvert_api_VolumeSource_To_v1_VolumeSource(in, out, s) +} + +func autoconvert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in *AWSElasticBlockStoreVolumeSource, out *api.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*AWSElasticBlockStoreVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in *AWSElasticBlockStoreVolumeSource, out *api.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { + return autoconvert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in, out, s) +} + +func autoconvert_v1_Binding_To_api_Binding(in *Binding, out *api.Binding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Binding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.Target, &out.Target, s); err != nil { + return err + } + return nil +} + +func convert_v1_Binding_To_api_Binding(in *Binding, out *api.Binding, s conversion.Scope) error { + return autoconvert_v1_Binding_To_api_Binding(in, out, s) +} + +func autoconvert_v1_Capabilities_To_api_Capabilities(in *Capabilities, out *api.Capabilities, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Capabilities))(in) + } + if in.Add != nil { + out.Add = make([]api.Capability, len(in.Add)) + for i := range in.Add { + out.Add[i] = api.Capability(in.Add[i]) + } + } else { + out.Add = nil + } + if in.Drop != nil { + out.Drop = make([]api.Capability, len(in.Drop)) + for i := range in.Drop { + out.Drop[i] = api.Capability(in.Drop[i]) + } + } else { + out.Drop = nil + } + return nil +} + +func convert_v1_Capabilities_To_api_Capabilities(in *Capabilities, out *api.Capabilities, s conversion.Scope) error { + return autoconvert_v1_Capabilities_To_api_Capabilities(in, out, s) +} + +func autoconvert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in *CephFSVolumeSource, out *api.CephFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*CephFSVolumeSource))(in) + } + if in.Monitors != nil { + out.Monitors = make([]string, len(in.Monitors)) + for i := range in.Monitors { + out.Monitors[i] = in.Monitors[i] + } + } else { + out.Monitors = nil + } + out.User = in.User + out.SecretFile = in.SecretFile + if in.SecretRef != nil { + out.SecretRef = new(api.LocalObjectReference) + if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in *CephFSVolumeSource, out *api.CephFSVolumeSource, s conversion.Scope) error { + return autoconvert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in, out, s) +} + +func autoconvert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in *CinderVolumeSource, out *api.CinderVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*CinderVolumeSource))(in) } @@ -2563,7 +3141,11 @@ func convert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in *CinderVolumeSou return nil } -func convert_v1_ComponentCondition_To_api_ComponentCondition(in *ComponentCondition, out *api.ComponentCondition, s conversion.Scope) error { +func convert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in *CinderVolumeSource, out *api.CinderVolumeSource, s conversion.Scope) error { + return autoconvert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in, out, s) +} + +func autoconvert_v1_ComponentCondition_To_api_ComponentCondition(in *ComponentCondition, out *api.ComponentCondition, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ComponentCondition))(in) } @@ -2574,11 +3156,15 @@ func convert_v1_ComponentCondition_To_api_ComponentCondition(in *ComponentCondit return nil } -func convert_v1_ComponentStatus_To_api_ComponentStatus(in *ComponentStatus, out *api.ComponentStatus, s conversion.Scope) error { +func convert_v1_ComponentCondition_To_api_ComponentCondition(in *ComponentCondition, out *api.ComponentCondition, s conversion.Scope) error { + return autoconvert_v1_ComponentCondition_To_api_ComponentCondition(in, out, s) +} + +func autoconvert_v1_ComponentStatus_To_api_ComponentStatus(in *ComponentStatus, out *api.ComponentStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ComponentStatus))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2597,14 +3183,18 @@ func convert_v1_ComponentStatus_To_api_ComponentStatus(in *ComponentStatus, out return nil } -func convert_v1_ComponentStatusList_To_api_ComponentStatusList(in *ComponentStatusList, out *api.ComponentStatusList, s conversion.Scope) error { +func convert_v1_ComponentStatus_To_api_ComponentStatus(in *ComponentStatus, out *api.ComponentStatus, s conversion.Scope) error { + return autoconvert_v1_ComponentStatus_To_api_ComponentStatus(in, out, s) +} + +func autoconvert_v1_ComponentStatusList_To_api_ComponentStatusList(in *ComponentStatusList, out *api.ComponentStatusList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ComponentStatusList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2620,7 +3210,11 @@ func convert_v1_ComponentStatusList_To_api_ComponentStatusList(in *ComponentStat return nil } -func convert_v1_Container_To_api_Container(in *Container, out *api.Container, s conversion.Scope) error { +func convert_v1_ComponentStatusList_To_api_ComponentStatusList(in *ComponentStatusList, out *api.ComponentStatusList, s conversion.Scope) error { + return autoconvert_v1_ComponentStatusList_To_api_ComponentStatusList(in, out, s) +} + +func autoconvert_v1_Container_To_api_Container(in *Container, out *api.Container, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Container))(in) } @@ -2715,7 +3309,11 @@ func convert_v1_Container_To_api_Container(in *Container, out *api.Container, s return nil } -func convert_v1_ContainerPort_To_api_ContainerPort(in *ContainerPort, out *api.ContainerPort, s conversion.Scope) error { +func convert_v1_Container_To_api_Container(in *Container, out *api.Container, s conversion.Scope) error { + return autoconvert_v1_Container_To_api_Container(in, out, s) +} + +func autoconvert_v1_ContainerPort_To_api_ContainerPort(in *ContainerPort, out *api.ContainerPort, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ContainerPort))(in) } @@ -2727,7 +3325,11 @@ func convert_v1_ContainerPort_To_api_ContainerPort(in *ContainerPort, out *api.C return nil } -func convert_v1_ContainerState_To_api_ContainerState(in *ContainerState, out *api.ContainerState, s conversion.Scope) error { +func convert_v1_ContainerPort_To_api_ContainerPort(in *ContainerPort, out *api.ContainerPort, s conversion.Scope) error { + return autoconvert_v1_ContainerPort_To_api_ContainerPort(in, out, s) +} + +func autoconvert_v1_ContainerState_To_api_ContainerState(in *ContainerState, out *api.ContainerState, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ContainerState))(in) } @@ -2758,7 +3360,11 @@ func convert_v1_ContainerState_To_api_ContainerState(in *ContainerState, out *ap return nil } -func convert_v1_ContainerStateRunning_To_api_ContainerStateRunning(in *ContainerStateRunning, out *api.ContainerStateRunning, s conversion.Scope) error { +func convert_v1_ContainerState_To_api_ContainerState(in *ContainerState, out *api.ContainerState, s conversion.Scope) error { + return autoconvert_v1_ContainerState_To_api_ContainerState(in, out, s) +} + +func autoconvert_v1_ContainerStateRunning_To_api_ContainerStateRunning(in *ContainerStateRunning, out *api.ContainerStateRunning, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ContainerStateRunning))(in) } @@ -2768,7 +3374,11 @@ func convert_v1_ContainerStateRunning_To_api_ContainerStateRunning(in *Container return nil } -func convert_v1_ContainerStateTerminated_To_api_ContainerStateTerminated(in *ContainerStateTerminated, out *api.ContainerStateTerminated, s conversion.Scope) error { +func convert_v1_ContainerStateRunning_To_api_ContainerStateRunning(in *ContainerStateRunning, out *api.ContainerStateRunning, s conversion.Scope) error { + return autoconvert_v1_ContainerStateRunning_To_api_ContainerStateRunning(in, out, s) +} + +func autoconvert_v1_ContainerStateTerminated_To_api_ContainerStateTerminated(in *ContainerStateTerminated, out *api.ContainerStateTerminated, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ContainerStateTerminated))(in) } @@ -2786,7 +3396,11 @@ func convert_v1_ContainerStateTerminated_To_api_ContainerStateTerminated(in *Con return nil } -func convert_v1_ContainerStateWaiting_To_api_ContainerStateWaiting(in *ContainerStateWaiting, out *api.ContainerStateWaiting, s conversion.Scope) error { +func convert_v1_ContainerStateTerminated_To_api_ContainerStateTerminated(in *ContainerStateTerminated, out *api.ContainerStateTerminated, s conversion.Scope) error { + return autoconvert_v1_ContainerStateTerminated_To_api_ContainerStateTerminated(in, out, s) +} + +func autoconvert_v1_ContainerStateWaiting_To_api_ContainerStateWaiting(in *ContainerStateWaiting, out *api.ContainerStateWaiting, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ContainerStateWaiting))(in) } @@ -2795,7 +3409,11 @@ func convert_v1_ContainerStateWaiting_To_api_ContainerStateWaiting(in *Container return nil } -func convert_v1_ContainerStatus_To_api_ContainerStatus(in *ContainerStatus, out *api.ContainerStatus, s conversion.Scope) error { +func convert_v1_ContainerStateWaiting_To_api_ContainerStateWaiting(in *ContainerStateWaiting, out *api.ContainerStateWaiting, s conversion.Scope) error { + return autoconvert_v1_ContainerStateWaiting_To_api_ContainerStateWaiting(in, out, s) +} + +func autoconvert_v1_ContainerStatus_To_api_ContainerStatus(in *ContainerStatus, out *api.ContainerStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ContainerStatus))(in) } @@ -2814,11 +3432,27 @@ func convert_v1_ContainerStatus_To_api_ContainerStatus(in *ContainerStatus, out return nil } -func convert_v1_DeleteOptions_To_api_DeleteOptions(in *DeleteOptions, out *api.DeleteOptions, s conversion.Scope) error { +func convert_v1_ContainerStatus_To_api_ContainerStatus(in *ContainerStatus, out *api.ContainerStatus, s conversion.Scope) error { + return autoconvert_v1_ContainerStatus_To_api_ContainerStatus(in, out, s) +} + +func autoconvert_v1_DaemonEndpoint_To_api_DaemonEndpoint(in *DaemonEndpoint, out *api.DaemonEndpoint, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DaemonEndpoint))(in) + } + out.Port = in.Port + return nil +} + +func convert_v1_DaemonEndpoint_To_api_DaemonEndpoint(in *DaemonEndpoint, out *api.DaemonEndpoint, s conversion.Scope) error { + return autoconvert_v1_DaemonEndpoint_To_api_DaemonEndpoint(in, out, s) +} + +func autoconvert_v1_DeleteOptions_To_api_DeleteOptions(in *DeleteOptions, out *api.DeleteOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*DeleteOptions))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if in.GracePeriodSeconds != nil { @@ -2830,7 +3464,11 @@ func convert_v1_DeleteOptions_To_api_DeleteOptions(in *DeleteOptions, out *api.D return nil } -func convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *DownwardAPIVolumeFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { +func convert_v1_DeleteOptions_To_api_DeleteOptions(in *DeleteOptions, out *api.DeleteOptions, s conversion.Scope) error { + return autoconvert_v1_DeleteOptions_To_api_DeleteOptions(in, out, s) +} + +func autoconvert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *DownwardAPIVolumeFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*DownwardAPIVolumeFile))(in) } @@ -2841,7 +3479,11 @@ func convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *DownwardA return nil } -func convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *DownwardAPIVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { +func convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *DownwardAPIVolumeFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { + return autoconvert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in, out, s) +} + +func autoconvert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *DownwardAPIVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*DownwardAPIVolumeSource))(in) } @@ -2858,7 +3500,11 @@ func convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *Downw return nil } -func convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in *EmptyDirVolumeSource, out *api.EmptyDirVolumeSource, s conversion.Scope) error { +func convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *DownwardAPIVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { + return autoconvert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in, out, s) +} + +func autoconvert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in *EmptyDirVolumeSource, out *api.EmptyDirVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*EmptyDirVolumeSource))(in) } @@ -2866,7 +3512,11 @@ func convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in *EmptyDirVol return nil } -func convert_v1_EndpointAddress_To_api_EndpointAddress(in *EndpointAddress, out *api.EndpointAddress, s conversion.Scope) error { +func convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in *EmptyDirVolumeSource, out *api.EmptyDirVolumeSource, s conversion.Scope) error { + return autoconvert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in, out, s) +} + +func autoconvert_v1_EndpointAddress_To_api_EndpointAddress(in *EndpointAddress, out *api.EndpointAddress, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*EndpointAddress))(in) } @@ -2882,7 +3532,11 @@ func convert_v1_EndpointAddress_To_api_EndpointAddress(in *EndpointAddress, out return nil } -func convert_v1_EndpointPort_To_api_EndpointPort(in *EndpointPort, out *api.EndpointPort, s conversion.Scope) error { +func convert_v1_EndpointAddress_To_api_EndpointAddress(in *EndpointAddress, out *api.EndpointAddress, s conversion.Scope) error { + return autoconvert_v1_EndpointAddress_To_api_EndpointAddress(in, out, s) +} + +func autoconvert_v1_EndpointPort_To_api_EndpointPort(in *EndpointPort, out *api.EndpointPort, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*EndpointPort))(in) } @@ -2892,7 +3546,11 @@ func convert_v1_EndpointPort_To_api_EndpointPort(in *EndpointPort, out *api.Endp return nil } -func convert_v1_EndpointSubset_To_api_EndpointSubset(in *EndpointSubset, out *api.EndpointSubset, s conversion.Scope) error { +func convert_v1_EndpointPort_To_api_EndpointPort(in *EndpointPort, out *api.EndpointPort, s conversion.Scope) error { + return autoconvert_v1_EndpointPort_To_api_EndpointPort(in, out, s) +} + +func autoconvert_v1_EndpointSubset_To_api_EndpointSubset(in *EndpointSubset, out *api.EndpointSubset, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*EndpointSubset))(in) } @@ -2906,6 +3564,16 @@ func convert_v1_EndpointSubset_To_api_EndpointSubset(in *EndpointSubset, out *ap } else { out.Addresses = nil } + if in.NotReadyAddresses != nil { + out.NotReadyAddresses = make([]api.EndpointAddress, len(in.NotReadyAddresses)) + for i := range in.NotReadyAddresses { + if err := convert_v1_EndpointAddress_To_api_EndpointAddress(&in.NotReadyAddresses[i], &out.NotReadyAddresses[i], s); err != nil { + return err + } + } + } else { + out.NotReadyAddresses = nil + } if in.Ports != nil { out.Ports = make([]api.EndpointPort, len(in.Ports)) for i := range in.Ports { @@ -2919,11 +3587,15 @@ func convert_v1_EndpointSubset_To_api_EndpointSubset(in *EndpointSubset, out *ap return nil } -func convert_v1_Endpoints_To_api_Endpoints(in *Endpoints, out *api.Endpoints, s conversion.Scope) error { +func convert_v1_EndpointSubset_To_api_EndpointSubset(in *EndpointSubset, out *api.EndpointSubset, s conversion.Scope) error { + return autoconvert_v1_EndpointSubset_To_api_EndpointSubset(in, out, s) +} + +func autoconvert_v1_Endpoints_To_api_Endpoints(in *Endpoints, out *api.Endpoints, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Endpoints))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2942,14 +3614,18 @@ func convert_v1_Endpoints_To_api_Endpoints(in *Endpoints, out *api.Endpoints, s return nil } -func convert_v1_EndpointsList_To_api_EndpointsList(in *EndpointsList, out *api.EndpointsList, s conversion.Scope) error { +func convert_v1_Endpoints_To_api_Endpoints(in *Endpoints, out *api.Endpoints, s conversion.Scope) error { + return autoconvert_v1_Endpoints_To_api_Endpoints(in, out, s) +} + +func autoconvert_v1_EndpointsList_To_api_EndpointsList(in *EndpointsList, out *api.EndpointsList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*EndpointsList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2965,7 +3641,11 @@ func convert_v1_EndpointsList_To_api_EndpointsList(in *EndpointsList, out *api.E return nil } -func convert_v1_EnvVar_To_api_EnvVar(in *EnvVar, out *api.EnvVar, s conversion.Scope) error { +func convert_v1_EndpointsList_To_api_EndpointsList(in *EndpointsList, out *api.EndpointsList, s conversion.Scope) error { + return autoconvert_v1_EndpointsList_To_api_EndpointsList(in, out, s) +} + +func autoconvert_v1_EnvVar_To_api_EnvVar(in *EnvVar, out *api.EnvVar, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*EnvVar))(in) } @@ -2982,7 +3662,11 @@ func convert_v1_EnvVar_To_api_EnvVar(in *EnvVar, out *api.EnvVar, s conversion.S return nil } -func convert_v1_EnvVarSource_To_api_EnvVarSource(in *EnvVarSource, out *api.EnvVarSource, s conversion.Scope) error { +func convert_v1_EnvVar_To_api_EnvVar(in *EnvVar, out *api.EnvVar, s conversion.Scope) error { + return autoconvert_v1_EnvVar_To_api_EnvVar(in, out, s) +} + +func autoconvert_v1_EnvVarSource_To_api_EnvVarSource(in *EnvVarSource, out *api.EnvVarSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*EnvVarSource))(in) } @@ -2997,11 +3681,15 @@ func convert_v1_EnvVarSource_To_api_EnvVarSource(in *EnvVarSource, out *api.EnvV return nil } -func convert_v1_Event_To_api_Event(in *Event, out *api.Event, s conversion.Scope) error { +func convert_v1_EnvVarSource_To_api_EnvVarSource(in *EnvVarSource, out *api.EnvVarSource, s conversion.Scope) error { + return autoconvert_v1_EnvVarSource_To_api_EnvVarSource(in, out, s) +} + +func autoconvert_v1_Event_To_api_Event(in *Event, out *api.Event, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Event))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -3025,14 +3713,18 @@ func convert_v1_Event_To_api_Event(in *Event, out *api.Event, s conversion.Scope return nil } -func convert_v1_EventList_To_api_EventList(in *EventList, out *api.EventList, s conversion.Scope) error { +func convert_v1_Event_To_api_Event(in *Event, out *api.Event, s conversion.Scope) error { + return autoconvert_v1_Event_To_api_Event(in, out, s) +} + +func autoconvert_v1_EventList_To_api_EventList(in *EventList, out *api.EventList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*EventList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -3048,7 +3740,11 @@ func convert_v1_EventList_To_api_EventList(in *EventList, out *api.EventList, s return nil } -func convert_v1_EventSource_To_api_EventSource(in *EventSource, out *api.EventSource, s conversion.Scope) error { +func convert_v1_EventList_To_api_EventList(in *EventList, out *api.EventList, s conversion.Scope) error { + return autoconvert_v1_EventList_To_api_EventList(in, out, s) +} + +func autoconvert_v1_EventSource_To_api_EventSource(in *EventSource, out *api.EventSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*EventSource))(in) } @@ -3057,7 +3753,11 @@ func convert_v1_EventSource_To_api_EventSource(in *EventSource, out *api.EventSo return nil } -func convert_v1_ExecAction_To_api_ExecAction(in *ExecAction, out *api.ExecAction, s conversion.Scope) error { +func convert_v1_EventSource_To_api_EventSource(in *EventSource, out *api.EventSource, s conversion.Scope) error { + return autoconvert_v1_EventSource_To_api_EventSource(in, out, s) +} + +func autoconvert_v1_ExecAction_To_api_ExecAction(in *ExecAction, out *api.ExecAction, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ExecAction))(in) } @@ -3072,7 +3772,50 @@ func convert_v1_ExecAction_To_api_ExecAction(in *ExecAction, out *api.ExecAction return nil } -func convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in *GCEPersistentDiskVolumeSource, out *api.GCEPersistentDiskVolumeSource, s conversion.Scope) error { +func convert_v1_ExecAction_To_api_ExecAction(in *ExecAction, out *api.ExecAction, s conversion.Scope) error { + return autoconvert_v1_ExecAction_To_api_ExecAction(in, out, s) +} + +func autoconvert_v1_FCVolumeSource_To_api_FCVolumeSource(in *FCVolumeSource, out *api.FCVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*FCVolumeSource))(in) + } + if in.TargetWWNs != nil { + out.TargetWWNs = make([]string, len(in.TargetWWNs)) + for i := range in.TargetWWNs { + out.TargetWWNs[i] = in.TargetWWNs[i] + } + } else { + out.TargetWWNs = nil + } + if in.Lun != nil { + out.Lun = new(int) + *out.Lun = *in.Lun + } else { + out.Lun = nil + } + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_FCVolumeSource_To_api_FCVolumeSource(in *FCVolumeSource, out *api.FCVolumeSource, s conversion.Scope) error { + return autoconvert_v1_FCVolumeSource_To_api_FCVolumeSource(in, out, s) +} + +func autoconvert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource(in *FlockerVolumeSource, out *api.FlockerVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*FlockerVolumeSource))(in) + } + out.DatasetName = in.DatasetName + return nil +} + +func convert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource(in *FlockerVolumeSource, out *api.FlockerVolumeSource, s conversion.Scope) error { + return autoconvert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource(in, out, s) +} + +func autoconvert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in *GCEPersistentDiskVolumeSource, out *api.GCEPersistentDiskVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*GCEPersistentDiskVolumeSource))(in) } @@ -3083,7 +3826,11 @@ func convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSour return nil } -func convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in *GitRepoVolumeSource, out *api.GitRepoVolumeSource, s conversion.Scope) error { +func convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in *GCEPersistentDiskVolumeSource, out *api.GCEPersistentDiskVolumeSource, s conversion.Scope) error { + return autoconvert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in, out, s) +} + +func autoconvert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in *GitRepoVolumeSource, out *api.GitRepoVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*GitRepoVolumeSource))(in) } @@ -3092,7 +3839,11 @@ func convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in *GitRepoVolume return nil } -func convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in *GlusterfsVolumeSource, out *api.GlusterfsVolumeSource, s conversion.Scope) error { +func convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in *GitRepoVolumeSource, out *api.GitRepoVolumeSource, s conversion.Scope) error { + return autoconvert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in, out, s) +} + +func autoconvert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in *GlusterfsVolumeSource, out *api.GlusterfsVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*GlusterfsVolumeSource))(in) } @@ -3102,7 +3853,11 @@ func convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in *Glusterfs return nil } -func convert_v1_HTTPGetAction_To_api_HTTPGetAction(in *HTTPGetAction, out *api.HTTPGetAction, s conversion.Scope) error { +func convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in *GlusterfsVolumeSource, out *api.GlusterfsVolumeSource, s conversion.Scope) error { + return autoconvert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in, out, s) +} + +func autoconvert_v1_HTTPGetAction_To_api_HTTPGetAction(in *HTTPGetAction, out *api.HTTPGetAction, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*HTTPGetAction))(in) } @@ -3115,7 +3870,11 @@ func convert_v1_HTTPGetAction_To_api_HTTPGetAction(in *HTTPGetAction, out *api.H return nil } -func convert_v1_Handler_To_api_Handler(in *Handler, out *api.Handler, s conversion.Scope) error { +func convert_v1_HTTPGetAction_To_api_HTTPGetAction(in *HTTPGetAction, out *api.HTTPGetAction, s conversion.Scope) error { + return autoconvert_v1_HTTPGetAction_To_api_HTTPGetAction(in, out, s) +} + +func autoconvert_v1_Handler_To_api_Handler(in *Handler, out *api.Handler, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Handler))(in) } @@ -3146,7 +3905,11 @@ func convert_v1_Handler_To_api_Handler(in *Handler, out *api.Handler, s conversi return nil } -func convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in *HostPathVolumeSource, out *api.HostPathVolumeSource, s conversion.Scope) error { +func convert_v1_Handler_To_api_Handler(in *Handler, out *api.Handler, s conversion.Scope) error { + return autoconvert_v1_Handler_To_api_Handler(in, out, s) +} + +func autoconvert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in *HostPathVolumeSource, out *api.HostPathVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*HostPathVolumeSource))(in) } @@ -3154,7 +3917,11 @@ func convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in *HostPathVol return nil } -func convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in *ISCSIVolumeSource, out *api.ISCSIVolumeSource, s conversion.Scope) error { +func convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in *HostPathVolumeSource, out *api.HostPathVolumeSource, s conversion.Scope) error { + return autoconvert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in, out, s) +} + +func autoconvert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in *ISCSIVolumeSource, out *api.ISCSIVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ISCSIVolumeSource))(in) } @@ -3166,7 +3933,11 @@ func convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in *ISCSIVolumeSource return nil } -func convert_v1_Lifecycle_To_api_Lifecycle(in *Lifecycle, out *api.Lifecycle, s conversion.Scope) error { +func convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in *ISCSIVolumeSource, out *api.ISCSIVolumeSource, s conversion.Scope) error { + return autoconvert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in, out, s) +} + +func autoconvert_v1_Lifecycle_To_api_Lifecycle(in *Lifecycle, out *api.Lifecycle, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Lifecycle))(in) } @@ -3189,11 +3960,15 @@ func convert_v1_Lifecycle_To_api_Lifecycle(in *Lifecycle, out *api.Lifecycle, s return nil } -func convert_v1_LimitRange_To_api_LimitRange(in *LimitRange, out *api.LimitRange, s conversion.Scope) error { +func convert_v1_Lifecycle_To_api_Lifecycle(in *Lifecycle, out *api.Lifecycle, s conversion.Scope) error { + return autoconvert_v1_Lifecycle_To_api_Lifecycle(in, out, s) +} + +func autoconvert_v1_LimitRange_To_api_LimitRange(in *LimitRange, out *api.LimitRange, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*LimitRange))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -3205,7 +3980,11 @@ func convert_v1_LimitRange_To_api_LimitRange(in *LimitRange, out *api.LimitRange return nil } -func convert_v1_LimitRangeItem_To_api_LimitRangeItem(in *LimitRangeItem, out *api.LimitRangeItem, s conversion.Scope) error { +func convert_v1_LimitRange_To_api_LimitRange(in *LimitRange, out *api.LimitRange, s conversion.Scope) error { + return autoconvert_v1_LimitRange_To_api_LimitRange(in, out, s) +} + +func autoconvert_v1_LimitRangeItem_To_api_LimitRangeItem(in *LimitRangeItem, out *api.LimitRangeItem, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*LimitRangeItem))(in) } @@ -3273,14 +4052,18 @@ func convert_v1_LimitRangeItem_To_api_LimitRangeItem(in *LimitRangeItem, out *ap return nil } -func convert_v1_LimitRangeList_To_api_LimitRangeList(in *LimitRangeList, out *api.LimitRangeList, s conversion.Scope) error { +func convert_v1_LimitRangeItem_To_api_LimitRangeItem(in *LimitRangeItem, out *api.LimitRangeItem, s conversion.Scope) error { + return autoconvert_v1_LimitRangeItem_To_api_LimitRangeItem(in, out, s) +} + +func autoconvert_v1_LimitRangeList_To_api_LimitRangeList(in *LimitRangeList, out *api.LimitRangeList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*LimitRangeList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -3296,7 +4079,11 @@ func convert_v1_LimitRangeList_To_api_LimitRangeList(in *LimitRangeList, out *ap return nil } -func convert_v1_LimitRangeSpec_To_api_LimitRangeSpec(in *LimitRangeSpec, out *api.LimitRangeSpec, s conversion.Scope) error { +func convert_v1_LimitRangeList_To_api_LimitRangeList(in *LimitRangeList, out *api.LimitRangeList, s conversion.Scope) error { + return autoconvert_v1_LimitRangeList_To_api_LimitRangeList(in, out, s) +} + +func autoconvert_v1_LimitRangeSpec_To_api_LimitRangeSpec(in *LimitRangeSpec, out *api.LimitRangeSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*LimitRangeSpec))(in) } @@ -3313,14 +4100,18 @@ func convert_v1_LimitRangeSpec_To_api_LimitRangeSpec(in *LimitRangeSpec, out *ap return nil } -func convert_v1_List_To_api_List(in *List, out *api.List, s conversion.Scope) error { +func convert_v1_LimitRangeSpec_To_api_LimitRangeSpec(in *LimitRangeSpec, out *api.LimitRangeSpec, s conversion.Scope) error { + return autoconvert_v1_LimitRangeSpec_To_api_LimitRangeSpec(in, out, s) +} + +func autoconvert_v1_List_To_api_List(in *List, out *api.List, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*List))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if err := s.Convert(&in.Items, &out.Items, 0); err != nil { @@ -3329,20 +4120,15 @@ func convert_v1_List_To_api_List(in *List, out *api.List, s conversion.Scope) er return nil } -func convert_v1_ListMeta_To_api_ListMeta(in *ListMeta, out *api.ListMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ListMeta))(in) - } - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil +func convert_v1_List_To_api_List(in *List, out *api.List, s conversion.Scope) error { + return autoconvert_v1_List_To_api_List(in, out, s) } -func convert_v1_ListOptions_To_api_ListOptions(in *ListOptions, out *api.ListOptions, s conversion.Scope) error { +func autoconvert_v1_ListOptions_To_api_ListOptions(in *ListOptions, out *api.ListOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ListOptions))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := s.Convert(&in.LabelSelector, &out.LabelSelector, 0); err != nil { @@ -3356,7 +4142,11 @@ func convert_v1_ListOptions_To_api_ListOptions(in *ListOptions, out *api.ListOpt return nil } -func convert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress(in *LoadBalancerIngress, out *api.LoadBalancerIngress, s conversion.Scope) error { +func convert_v1_ListOptions_To_api_ListOptions(in *ListOptions, out *api.ListOptions, s conversion.Scope) error { + return autoconvert_v1_ListOptions_To_api_ListOptions(in, out, s) +} + +func autoconvert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress(in *LoadBalancerIngress, out *api.LoadBalancerIngress, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*LoadBalancerIngress))(in) } @@ -3365,7 +4155,11 @@ func convert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress(in *LoadBalancerI return nil } -func convert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus(in *LoadBalancerStatus, out *api.LoadBalancerStatus, s conversion.Scope) error { +func convert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress(in *LoadBalancerIngress, out *api.LoadBalancerIngress, s conversion.Scope) error { + return autoconvert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress(in, out, s) +} + +func autoconvert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus(in *LoadBalancerStatus, out *api.LoadBalancerStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*LoadBalancerStatus))(in) } @@ -3382,7 +4176,11 @@ func convert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus(in *LoadBalancerSta return nil } -func convert_v1_LocalObjectReference_To_api_LocalObjectReference(in *LocalObjectReference, out *api.LocalObjectReference, s conversion.Scope) error { +func convert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus(in *LoadBalancerStatus, out *api.LoadBalancerStatus, s conversion.Scope) error { + return autoconvert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus(in, out, s) +} + +func autoconvert_v1_LocalObjectReference_To_api_LocalObjectReference(in *LocalObjectReference, out *api.LocalObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*LocalObjectReference))(in) } @@ -3390,7 +4188,11 @@ func convert_v1_LocalObjectReference_To_api_LocalObjectReference(in *LocalObject return nil } -func convert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in *NFSVolumeSource, out *api.NFSVolumeSource, s conversion.Scope) error { +func convert_v1_LocalObjectReference_To_api_LocalObjectReference(in *LocalObjectReference, out *api.LocalObjectReference, s conversion.Scope) error { + return autoconvert_v1_LocalObjectReference_To_api_LocalObjectReference(in, out, s) +} + +func autoconvert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in *NFSVolumeSource, out *api.NFSVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*NFSVolumeSource))(in) } @@ -3400,11 +4202,15 @@ func convert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in *NFSVolumeSource, out return nil } -func convert_v1_Namespace_To_api_Namespace(in *Namespace, out *api.Namespace, s conversion.Scope) error { +func convert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in *NFSVolumeSource, out *api.NFSVolumeSource, s conversion.Scope) error { + return autoconvert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in, out, s) +} + +func autoconvert_v1_Namespace_To_api_Namespace(in *Namespace, out *api.Namespace, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Namespace))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -3419,14 +4225,18 @@ func convert_v1_Namespace_To_api_Namespace(in *Namespace, out *api.Namespace, s return nil } -func convert_v1_NamespaceList_To_api_NamespaceList(in *NamespaceList, out *api.NamespaceList, s conversion.Scope) error { +func convert_v1_Namespace_To_api_Namespace(in *Namespace, out *api.Namespace, s conversion.Scope) error { + return autoconvert_v1_Namespace_To_api_Namespace(in, out, s) +} + +func autoconvert_v1_NamespaceList_To_api_NamespaceList(in *NamespaceList, out *api.NamespaceList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*NamespaceList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -3442,7 +4252,11 @@ func convert_v1_NamespaceList_To_api_NamespaceList(in *NamespaceList, out *api.N return nil } -func convert_v1_NamespaceSpec_To_api_NamespaceSpec(in *NamespaceSpec, out *api.NamespaceSpec, s conversion.Scope) error { +func convert_v1_NamespaceList_To_api_NamespaceList(in *NamespaceList, out *api.NamespaceList, s conversion.Scope) error { + return autoconvert_v1_NamespaceList_To_api_NamespaceList(in, out, s) +} + +func autoconvert_v1_NamespaceSpec_To_api_NamespaceSpec(in *NamespaceSpec, out *api.NamespaceSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*NamespaceSpec))(in) } @@ -3457,7 +4271,11 @@ func convert_v1_NamespaceSpec_To_api_NamespaceSpec(in *NamespaceSpec, out *api.N return nil } -func convert_v1_NamespaceStatus_To_api_NamespaceStatus(in *NamespaceStatus, out *api.NamespaceStatus, s conversion.Scope) error { +func convert_v1_NamespaceSpec_To_api_NamespaceSpec(in *NamespaceSpec, out *api.NamespaceSpec, s conversion.Scope) error { + return autoconvert_v1_NamespaceSpec_To_api_NamespaceSpec(in, out, s) +} + +func autoconvert_v1_NamespaceStatus_To_api_NamespaceStatus(in *NamespaceStatus, out *api.NamespaceStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*NamespaceStatus))(in) } @@ -3465,11 +4283,15 @@ func convert_v1_NamespaceStatus_To_api_NamespaceStatus(in *NamespaceStatus, out return nil } -func convert_v1_Node_To_api_Node(in *Node, out *api.Node, s conversion.Scope) error { +func convert_v1_NamespaceStatus_To_api_NamespaceStatus(in *NamespaceStatus, out *api.NamespaceStatus, s conversion.Scope) error { + return autoconvert_v1_NamespaceStatus_To_api_NamespaceStatus(in, out, s) +} + +func autoconvert_v1_Node_To_api_Node(in *Node, out *api.Node, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Node))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -3484,7 +4306,11 @@ func convert_v1_Node_To_api_Node(in *Node, out *api.Node, s conversion.Scope) er return nil } -func convert_v1_NodeAddress_To_api_NodeAddress(in *NodeAddress, out *api.NodeAddress, s conversion.Scope) error { +func convert_v1_Node_To_api_Node(in *Node, out *api.Node, s conversion.Scope) error { + return autoconvert_v1_Node_To_api_Node(in, out, s) +} + +func autoconvert_v1_NodeAddress_To_api_NodeAddress(in *NodeAddress, out *api.NodeAddress, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*NodeAddress))(in) } @@ -3493,7 +4319,11 @@ func convert_v1_NodeAddress_To_api_NodeAddress(in *NodeAddress, out *api.NodeAdd return nil } -func convert_v1_NodeCondition_To_api_NodeCondition(in *NodeCondition, out *api.NodeCondition, s conversion.Scope) error { +func convert_v1_NodeAddress_To_api_NodeAddress(in *NodeAddress, out *api.NodeAddress, s conversion.Scope) error { + return autoconvert_v1_NodeAddress_To_api_NodeAddress(in, out, s) +} + +func autoconvert_v1_NodeCondition_To_api_NodeCondition(in *NodeCondition, out *api.NodeCondition, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*NodeCondition))(in) } @@ -3510,14 +4340,32 @@ func convert_v1_NodeCondition_To_api_NodeCondition(in *NodeCondition, out *api.N return nil } -func convert_v1_NodeList_To_api_NodeList(in *NodeList, out *api.NodeList, s conversion.Scope) error { +func convert_v1_NodeCondition_To_api_NodeCondition(in *NodeCondition, out *api.NodeCondition, s conversion.Scope) error { + return autoconvert_v1_NodeCondition_To_api_NodeCondition(in, out, s) +} + +func autoconvert_v1_NodeDaemonEndpoints_To_api_NodeDaemonEndpoints(in *NodeDaemonEndpoints, out *api.NodeDaemonEndpoints, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NodeDaemonEndpoints))(in) + } + if err := convert_v1_DaemonEndpoint_To_api_DaemonEndpoint(&in.KubeletEndpoint, &out.KubeletEndpoint, s); err != nil { + return err + } + return nil +} + +func convert_v1_NodeDaemonEndpoints_To_api_NodeDaemonEndpoints(in *NodeDaemonEndpoints, out *api.NodeDaemonEndpoints, s conversion.Scope) error { + return autoconvert_v1_NodeDaemonEndpoints_To_api_NodeDaemonEndpoints(in, out, s) +} + +func autoconvert_v1_NodeList_To_api_NodeList(in *NodeList, out *api.NodeList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*NodeList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -3533,7 +4381,11 @@ func convert_v1_NodeList_To_api_NodeList(in *NodeList, out *api.NodeList, s conv return nil } -func convert_v1_NodeSpec_To_api_NodeSpec(in *NodeSpec, out *api.NodeSpec, s conversion.Scope) error { +func convert_v1_NodeList_To_api_NodeList(in *NodeList, out *api.NodeList, s conversion.Scope) error { + return autoconvert_v1_NodeList_To_api_NodeList(in, out, s) +} + +func autoconvert_v1_NodeSpec_To_api_NodeSpec(in *NodeSpec, out *api.NodeSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*NodeSpec))(in) } @@ -3544,7 +4396,11 @@ func convert_v1_NodeSpec_To_api_NodeSpec(in *NodeSpec, out *api.NodeSpec, s conv return nil } -func convert_v1_NodeStatus_To_api_NodeStatus(in *NodeStatus, out *api.NodeStatus, s conversion.Scope) error { +func convert_v1_NodeSpec_To_api_NodeSpec(in *NodeSpec, out *api.NodeSpec, s conversion.Scope) error { + return autoconvert_v1_NodeSpec_To_api_NodeSpec(in, out, s) +} + +func autoconvert_v1_NodeStatus_To_api_NodeStatus(in *NodeStatus, out *api.NodeStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*NodeStatus))(in) } @@ -3581,13 +4437,20 @@ func convert_v1_NodeStatus_To_api_NodeStatus(in *NodeStatus, out *api.NodeStatus } else { out.Addresses = nil } + if err := convert_v1_NodeDaemonEndpoints_To_api_NodeDaemonEndpoints(&in.DaemonEndpoints, &out.DaemonEndpoints, s); err != nil { + return err + } if err := convert_v1_NodeSystemInfo_To_api_NodeSystemInfo(&in.NodeInfo, &out.NodeInfo, s); err != nil { return err } return nil } -func convert_v1_NodeSystemInfo_To_api_NodeSystemInfo(in *NodeSystemInfo, out *api.NodeSystemInfo, s conversion.Scope) error { +func convert_v1_NodeStatus_To_api_NodeStatus(in *NodeStatus, out *api.NodeStatus, s conversion.Scope) error { + return autoconvert_v1_NodeStatus_To_api_NodeStatus(in, out, s) +} + +func autoconvert_v1_NodeSystemInfo_To_api_NodeSystemInfo(in *NodeSystemInfo, out *api.NodeSystemInfo, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*NodeSystemInfo))(in) } @@ -3602,7 +4465,11 @@ func convert_v1_NodeSystemInfo_To_api_NodeSystemInfo(in *NodeSystemInfo, out *ap return nil } -func convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *ObjectFieldSelector, out *api.ObjectFieldSelector, s conversion.Scope) error { +func convert_v1_NodeSystemInfo_To_api_NodeSystemInfo(in *NodeSystemInfo, out *api.NodeSystemInfo, s conversion.Scope) error { + return autoconvert_v1_NodeSystemInfo_To_api_NodeSystemInfo(in, out, s) +} + +func autoconvert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *ObjectFieldSelector, out *api.ObjectFieldSelector, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ObjectFieldSelector))(in) } @@ -3611,7 +4478,11 @@ func convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *ObjectFieldSe return nil } -func convert_v1_ObjectMeta_To_api_ObjectMeta(in *ObjectMeta, out *api.ObjectMeta, s conversion.Scope) error { +func convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *ObjectFieldSelector, out *api.ObjectFieldSelector, s conversion.Scope) error { + return autoconvert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in, out, s) +} + +func autoconvert_v1_ObjectMeta_To_api_ObjectMeta(in *ObjectMeta, out *api.ObjectMeta, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ObjectMeta))(in) } @@ -3657,7 +4528,11 @@ func convert_v1_ObjectMeta_To_api_ObjectMeta(in *ObjectMeta, out *api.ObjectMeta return nil } -func convert_v1_ObjectReference_To_api_ObjectReference(in *ObjectReference, out *api.ObjectReference, s conversion.Scope) error { +func convert_v1_ObjectMeta_To_api_ObjectMeta(in *ObjectMeta, out *api.ObjectMeta, s conversion.Scope) error { + return autoconvert_v1_ObjectMeta_To_api_ObjectMeta(in, out, s) +} + +func autoconvert_v1_ObjectReference_To_api_ObjectReference(in *ObjectReference, out *api.ObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ObjectReference))(in) } @@ -3671,11 +4546,15 @@ func convert_v1_ObjectReference_To_api_ObjectReference(in *ObjectReference, out return nil } -func convert_v1_PersistentVolume_To_api_PersistentVolume(in *PersistentVolume, out *api.PersistentVolume, s conversion.Scope) error { +func convert_v1_ObjectReference_To_api_ObjectReference(in *ObjectReference, out *api.ObjectReference, s conversion.Scope) error { + return autoconvert_v1_ObjectReference_To_api_ObjectReference(in, out, s) +} + +func autoconvert_v1_PersistentVolume_To_api_PersistentVolume(in *PersistentVolume, out *api.PersistentVolume, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PersistentVolume))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -3690,11 +4569,15 @@ func convert_v1_PersistentVolume_To_api_PersistentVolume(in *PersistentVolume, o return nil } -func convert_v1_PersistentVolumeClaim_To_api_PersistentVolumeClaim(in *PersistentVolumeClaim, out *api.PersistentVolumeClaim, s conversion.Scope) error { +func convert_v1_PersistentVolume_To_api_PersistentVolume(in *PersistentVolume, out *api.PersistentVolume, s conversion.Scope) error { + return autoconvert_v1_PersistentVolume_To_api_PersistentVolume(in, out, s) +} + +func autoconvert_v1_PersistentVolumeClaim_To_api_PersistentVolumeClaim(in *PersistentVolumeClaim, out *api.PersistentVolumeClaim, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PersistentVolumeClaim))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -3709,14 +4592,18 @@ func convert_v1_PersistentVolumeClaim_To_api_PersistentVolumeClaim(in *Persisten return nil } -func convert_v1_PersistentVolumeClaimList_To_api_PersistentVolumeClaimList(in *PersistentVolumeClaimList, out *api.PersistentVolumeClaimList, s conversion.Scope) error { +func convert_v1_PersistentVolumeClaim_To_api_PersistentVolumeClaim(in *PersistentVolumeClaim, out *api.PersistentVolumeClaim, s conversion.Scope) error { + return autoconvert_v1_PersistentVolumeClaim_To_api_PersistentVolumeClaim(in, out, s) +} + +func autoconvert_v1_PersistentVolumeClaimList_To_api_PersistentVolumeClaimList(in *PersistentVolumeClaimList, out *api.PersistentVolumeClaimList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PersistentVolumeClaimList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -3732,7 +4619,11 @@ func convert_v1_PersistentVolumeClaimList_To_api_PersistentVolumeClaimList(in *P return nil } -func convert_v1_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec(in *PersistentVolumeClaimSpec, out *api.PersistentVolumeClaimSpec, s conversion.Scope) error { +func convert_v1_PersistentVolumeClaimList_To_api_PersistentVolumeClaimList(in *PersistentVolumeClaimList, out *api.PersistentVolumeClaimList, s conversion.Scope) error { + return autoconvert_v1_PersistentVolumeClaimList_To_api_PersistentVolumeClaimList(in, out, s) +} + +func autoconvert_v1_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec(in *PersistentVolumeClaimSpec, out *api.PersistentVolumeClaimSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PersistentVolumeClaimSpec))(in) } @@ -3751,7 +4642,11 @@ func convert_v1_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec(in *P return nil } -func convert_v1_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus(in *PersistentVolumeClaimStatus, out *api.PersistentVolumeClaimStatus, s conversion.Scope) error { +func convert_v1_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec(in *PersistentVolumeClaimSpec, out *api.PersistentVolumeClaimSpec, s conversion.Scope) error { + return autoconvert_v1_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec(in, out, s) +} + +func autoconvert_v1_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus(in *PersistentVolumeClaimStatus, out *api.PersistentVolumeClaimStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PersistentVolumeClaimStatus))(in) } @@ -3779,7 +4674,11 @@ func convert_v1_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus(i return nil } -func convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in *PersistentVolumeClaimVolumeSource, out *api.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { +func convert_v1_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus(in *PersistentVolumeClaimStatus, out *api.PersistentVolumeClaimStatus, s conversion.Scope) error { + return autoconvert_v1_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus(in, out, s) +} + +func autoconvert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in *PersistentVolumeClaimVolumeSource, out *api.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PersistentVolumeClaimVolumeSource))(in) } @@ -3788,14 +4687,18 @@ func convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVo return nil } -func convert_v1_PersistentVolumeList_To_api_PersistentVolumeList(in *PersistentVolumeList, out *api.PersistentVolumeList, s conversion.Scope) error { +func convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in *PersistentVolumeClaimVolumeSource, out *api.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { + return autoconvert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in, out, s) +} + +func autoconvert_v1_PersistentVolumeList_To_api_PersistentVolumeList(in *PersistentVolumeList, out *api.PersistentVolumeList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PersistentVolumeList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -3811,7 +4714,11 @@ func convert_v1_PersistentVolumeList_To_api_PersistentVolumeList(in *PersistentV return nil } -func convert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in *PersistentVolumeSource, out *api.PersistentVolumeSource, s conversion.Scope) error { +func convert_v1_PersistentVolumeList_To_api_PersistentVolumeList(in *PersistentVolumeList, out *api.PersistentVolumeList, s conversion.Scope) error { + return autoconvert_v1_PersistentVolumeList_To_api_PersistentVolumeList(in, out, s) +} + +func autoconvert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in *PersistentVolumeSource, out *api.PersistentVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PersistentVolumeSource))(in) } @@ -3887,10 +4794,30 @@ func convert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in *Persist } else { out.CephFS = nil } + if in.FC != nil { + out.FC = new(api.FCVolumeSource) + if err := convert_v1_FCVolumeSource_To_api_FCVolumeSource(in.FC, out.FC, s); err != nil { + return err + } + } else { + out.FC = nil + } + if in.Flocker != nil { + out.Flocker = new(api.FlockerVolumeSource) + if err := convert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource(in.Flocker, out.Flocker, s); err != nil { + return err + } + } else { + out.Flocker = nil + } return nil } -func convert_v1_PersistentVolumeSpec_To_api_PersistentVolumeSpec(in *PersistentVolumeSpec, out *api.PersistentVolumeSpec, s conversion.Scope) error { +func convert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in *PersistentVolumeSource, out *api.PersistentVolumeSource, s conversion.Scope) error { + return autoconvert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in, out, s) +} + +func autoconvert_v1_PersistentVolumeSpec_To_api_PersistentVolumeSpec(in *PersistentVolumeSpec, out *api.PersistentVolumeSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PersistentVolumeSpec))(in) } @@ -3929,7 +4856,11 @@ func convert_v1_PersistentVolumeSpec_To_api_PersistentVolumeSpec(in *PersistentV return nil } -func convert_v1_PersistentVolumeStatus_To_api_PersistentVolumeStatus(in *PersistentVolumeStatus, out *api.PersistentVolumeStatus, s conversion.Scope) error { +func convert_v1_PersistentVolumeSpec_To_api_PersistentVolumeSpec(in *PersistentVolumeSpec, out *api.PersistentVolumeSpec, s conversion.Scope) error { + return autoconvert_v1_PersistentVolumeSpec_To_api_PersistentVolumeSpec(in, out, s) +} + +func autoconvert_v1_PersistentVolumeStatus_To_api_PersistentVolumeStatus(in *PersistentVolumeStatus, out *api.PersistentVolumeStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PersistentVolumeStatus))(in) } @@ -3939,11 +4870,15 @@ func convert_v1_PersistentVolumeStatus_To_api_PersistentVolumeStatus(in *Persist return nil } -func convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error { +func convert_v1_PersistentVolumeStatus_To_api_PersistentVolumeStatus(in *PersistentVolumeStatus, out *api.PersistentVolumeStatus, s conversion.Scope) error { + return autoconvert_v1_PersistentVolumeStatus_To_api_PersistentVolumeStatus(in, out, s) +} + +func autoconvert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Pod))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -3958,11 +4893,15 @@ func convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error return nil } -func convert_v1_PodAttachOptions_To_api_PodAttachOptions(in *PodAttachOptions, out *api.PodAttachOptions, s conversion.Scope) error { +func convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error { + return autoconvert_v1_Pod_To_api_Pod(in, out, s) +} + +func autoconvert_v1_PodAttachOptions_To_api_PodAttachOptions(in *PodAttachOptions, out *api.PodAttachOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodAttachOptions))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Stdin = in.Stdin @@ -3973,20 +4912,36 @@ func convert_v1_PodAttachOptions_To_api_PodAttachOptions(in *PodAttachOptions, o return nil } -func convert_v1_PodCondition_To_api_PodCondition(in *PodCondition, out *api.PodCondition, s conversion.Scope) error { +func convert_v1_PodAttachOptions_To_api_PodAttachOptions(in *PodAttachOptions, out *api.PodAttachOptions, s conversion.Scope) error { + return autoconvert_v1_PodAttachOptions_To_api_PodAttachOptions(in, out, s) +} + +func autoconvert_v1_PodCondition_To_api_PodCondition(in *PodCondition, out *api.PodCondition, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodCondition))(in) } out.Type = api.PodConditionType(in.Type) out.Status = api.ConditionStatus(in.Status) + if err := s.Convert(&in.LastProbeTime, &out.LastProbeTime, 0); err != nil { + return err + } + if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message return nil } -func convert_v1_PodExecOptions_To_api_PodExecOptions(in *PodExecOptions, out *api.PodExecOptions, s conversion.Scope) error { +func convert_v1_PodCondition_To_api_PodCondition(in *PodCondition, out *api.PodCondition, s conversion.Scope) error { + return autoconvert_v1_PodCondition_To_api_PodCondition(in, out, s) +} + +func autoconvert_v1_PodExecOptions_To_api_PodExecOptions(in *PodExecOptions, out *api.PodExecOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodExecOptions))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Stdin = in.Stdin @@ -4005,14 +4960,18 @@ func convert_v1_PodExecOptions_To_api_PodExecOptions(in *PodExecOptions, out *ap return nil } -func convert_v1_PodList_To_api_PodList(in *PodList, out *api.PodList, s conversion.Scope) error { +func convert_v1_PodExecOptions_To_api_PodExecOptions(in *PodExecOptions, out *api.PodExecOptions, s conversion.Scope) error { + return autoconvert_v1_PodExecOptions_To_api_PodExecOptions(in, out, s) +} + +func autoconvert_v1_PodList_To_api_PodList(in *PodList, out *api.PodList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -4028,31 +4987,141 @@ func convert_v1_PodList_To_api_PodList(in *PodList, out *api.PodList, s conversi return nil } -func convert_v1_PodLogOptions_To_api_PodLogOptions(in *PodLogOptions, out *api.PodLogOptions, s conversion.Scope) error { +func convert_v1_PodList_To_api_PodList(in *PodList, out *api.PodList, s conversion.Scope) error { + return autoconvert_v1_PodList_To_api_PodList(in, out, s) +} + +func autoconvert_v1_PodLogOptions_To_api_PodLogOptions(in *PodLogOptions, out *api.PodLogOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodLogOptions))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Container = in.Container out.Follow = in.Follow out.Previous = in.Previous + if in.SinceSeconds != nil { + out.SinceSeconds = new(int64) + *out.SinceSeconds = *in.SinceSeconds + } else { + out.SinceSeconds = nil + } + if in.SinceTime != nil { + if err := s.Convert(&in.SinceTime, &out.SinceTime, 0); err != nil { + return err + } + } else { + out.SinceTime = nil + } + out.Timestamps = in.Timestamps + if in.TailLines != nil { + out.TailLines = new(int64) + *out.TailLines = *in.TailLines + } else { + out.TailLines = nil + } + if in.LimitBytes != nil { + out.LimitBytes = new(int64) + *out.LimitBytes = *in.LimitBytes + } else { + out.LimitBytes = nil + } return nil } -func convert_v1_PodProxyOptions_To_api_PodProxyOptions(in *PodProxyOptions, out *api.PodProxyOptions, s conversion.Scope) error { +func convert_v1_PodLogOptions_To_api_PodLogOptions(in *PodLogOptions, out *api.PodLogOptions, s conversion.Scope) error { + return autoconvert_v1_PodLogOptions_To_api_PodLogOptions(in, out, s) +} + +func autoconvert_v1_PodProxyOptions_To_api_PodProxyOptions(in *PodProxyOptions, out *api.PodProxyOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodProxyOptions))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Path = in.Path return nil } -func convert_v1_PodStatus_To_api_PodStatus(in *PodStatus, out *api.PodStatus, s conversion.Scope) error { +func convert_v1_PodProxyOptions_To_api_PodProxyOptions(in *PodProxyOptions, out *api.PodProxyOptions, s conversion.Scope) error { + return autoconvert_v1_PodProxyOptions_To_api_PodProxyOptions(in, out, s) +} + +func autoconvert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodSpec))(in) + } + if in.Volumes != nil { + out.Volumes = make([]api.Volume, len(in.Volumes)) + for i := range in.Volumes { + if err := convert_v1_Volume_To_api_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil { + return err + } + } + } else { + out.Volumes = nil + } + if in.Containers != nil { + out.Containers = make([]api.Container, len(in.Containers)) + for i := range in.Containers { + if err := convert_v1_Container_To_api_Container(&in.Containers[i], &out.Containers[i], s); err != nil { + return err + } + } + } else { + out.Containers = nil + } + out.RestartPolicy = api.RestartPolicy(in.RestartPolicy) + if in.TerminationGracePeriodSeconds != nil { + out.TerminationGracePeriodSeconds = new(int64) + *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds + } else { + out.TerminationGracePeriodSeconds = nil + } + if in.ActiveDeadlineSeconds != nil { + out.ActiveDeadlineSeconds = new(int64) + *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds + } else { + out.ActiveDeadlineSeconds = nil + } + out.DNSPolicy = api.DNSPolicy(in.DNSPolicy) + if in.NodeSelector != nil { + out.NodeSelector = make(map[string]string) + for key, val := range in.NodeSelector { + out.NodeSelector[key] = val + } + } else { + out.NodeSelector = nil + } + out.ServiceAccountName = in.ServiceAccountName + // in.DeprecatedServiceAccount has no peer in out + out.NodeName = in.NodeName + // in.HostNetwork has no peer in out + // in.HostPID has no peer in out + // in.HostIPC has no peer in out + if in.SecurityContext != nil { + if err := s.Convert(&in.SecurityContext, &out.SecurityContext, 0); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + if in.ImagePullSecrets != nil { + out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets)) + for i := range in.ImagePullSecrets { + if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { + return err + } + } + } else { + out.ImagePullSecrets = nil + } + return nil +} + +func autoconvert_v1_PodStatus_To_api_PodStatus(in *PodStatus, out *api.PodStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodStatus))(in) } @@ -4091,11 +5160,15 @@ func convert_v1_PodStatus_To_api_PodStatus(in *PodStatus, out *api.PodStatus, s return nil } -func convert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error { +func convert_v1_PodStatus_To_api_PodStatus(in *PodStatus, out *api.PodStatus, s conversion.Scope) error { + return autoconvert_v1_PodStatus_To_api_PodStatus(in, out, s) +} + +func autoconvert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodStatusResult))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -4107,11 +5180,15 @@ func convert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out return nil } -func convert_v1_PodTemplate_To_api_PodTemplate(in *PodTemplate, out *api.PodTemplate, s conversion.Scope) error { +func convert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error { + return autoconvert_v1_PodStatusResult_To_api_PodStatusResult(in, out, s) +} + +func autoconvert_v1_PodTemplate_To_api_PodTemplate(in *PodTemplate, out *api.PodTemplate, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodTemplate))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -4123,14 +5200,18 @@ func convert_v1_PodTemplate_To_api_PodTemplate(in *PodTemplate, out *api.PodTemp return nil } -func convert_v1_PodTemplateList_To_api_PodTemplateList(in *PodTemplateList, out *api.PodTemplateList, s conversion.Scope) error { +func convert_v1_PodTemplate_To_api_PodTemplate(in *PodTemplate, out *api.PodTemplate, s conversion.Scope) error { + return autoconvert_v1_PodTemplate_To_api_PodTemplate(in, out, s) +} + +func autoconvert_v1_PodTemplateList_To_api_PodTemplateList(in *PodTemplateList, out *api.PodTemplateList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodTemplateList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -4146,7 +5227,11 @@ func convert_v1_PodTemplateList_To_api_PodTemplateList(in *PodTemplateList, out return nil } -func convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { +func convert_v1_PodTemplateList_To_api_PodTemplateList(in *PodTemplateList, out *api.PodTemplateList, s conversion.Scope) error { + return autoconvert_v1_PodTemplateList_To_api_PodTemplateList(in, out, s) +} + +func autoconvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodTemplateSpec))(in) } @@ -4159,7 +5244,11 @@ func convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out return nil } -func convert_v1_Probe_To_api_Probe(in *Probe, out *api.Probe, s conversion.Scope) error { +func convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { + return autoconvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in, out, s) +} + +func autoconvert_v1_Probe_To_api_Probe(in *Probe, out *api.Probe, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Probe))(in) } @@ -4171,7 +5260,11 @@ func convert_v1_Probe_To_api_Probe(in *Probe, out *api.Probe, s conversion.Scope return nil } -func convert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in *RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error { +func convert_v1_Probe_To_api_Probe(in *Probe, out *api.Probe, s conversion.Scope) error { + return autoconvert_v1_Probe_To_api_Probe(in, out, s) +} + +func autoconvert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in *RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*RBDVolumeSource))(in) } @@ -4200,11 +5293,15 @@ func convert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in *RBDVolumeSource, out return nil } -func convert_v1_RangeAllocation_To_api_RangeAllocation(in *RangeAllocation, out *api.RangeAllocation, s conversion.Scope) error { +func convert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in *RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error { + return autoconvert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in, out, s) +} + +func autoconvert_v1_RangeAllocation_To_api_RangeAllocation(in *RangeAllocation, out *api.RangeAllocation, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*RangeAllocation))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -4217,11 +5314,15 @@ func convert_v1_RangeAllocation_To_api_RangeAllocation(in *RangeAllocation, out return nil } -func convert_v1_ReplicationController_To_api_ReplicationController(in *ReplicationController, out *api.ReplicationController, s conversion.Scope) error { +func convert_v1_RangeAllocation_To_api_RangeAllocation(in *RangeAllocation, out *api.RangeAllocation, s conversion.Scope) error { + return autoconvert_v1_RangeAllocation_To_api_RangeAllocation(in, out, s) +} + +func autoconvert_v1_ReplicationController_To_api_ReplicationController(in *ReplicationController, out *api.ReplicationController, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ReplicationController))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -4236,14 +5337,18 @@ func convert_v1_ReplicationController_To_api_ReplicationController(in *Replicati return nil } -func convert_v1_ReplicationControllerList_To_api_ReplicationControllerList(in *ReplicationControllerList, out *api.ReplicationControllerList, s conversion.Scope) error { +func convert_v1_ReplicationController_To_api_ReplicationController(in *ReplicationController, out *api.ReplicationController, s conversion.Scope) error { + return autoconvert_v1_ReplicationController_To_api_ReplicationController(in, out, s) +} + +func autoconvert_v1_ReplicationControllerList_To_api_ReplicationControllerList(in *ReplicationControllerList, out *api.ReplicationControllerList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ReplicationControllerList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -4259,7 +5364,35 @@ func convert_v1_ReplicationControllerList_To_api_ReplicationControllerList(in *R return nil } -func convert_v1_ReplicationControllerStatus_To_api_ReplicationControllerStatus(in *ReplicationControllerStatus, out *api.ReplicationControllerStatus, s conversion.Scope) error { +func convert_v1_ReplicationControllerList_To_api_ReplicationControllerList(in *ReplicationControllerList, out *api.ReplicationControllerList, s conversion.Scope) error { + return autoconvert_v1_ReplicationControllerList_To_api_ReplicationControllerList(in, out, s) +} + +func autoconvert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *ReplicationControllerSpec, out *api.ReplicationControllerSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ReplicationControllerSpec))(in) + } + // in.Replicas has no peer in out + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(api.PodTemplateSpec) + if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + return nil +} + +func autoconvert_v1_ReplicationControllerStatus_To_api_ReplicationControllerStatus(in *ReplicationControllerStatus, out *api.ReplicationControllerStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ReplicationControllerStatus))(in) } @@ -4268,11 +5401,15 @@ func convert_v1_ReplicationControllerStatus_To_api_ReplicationControllerStatus(i return nil } -func convert_v1_ResourceQuota_To_api_ResourceQuota(in *ResourceQuota, out *api.ResourceQuota, s conversion.Scope) error { +func convert_v1_ReplicationControllerStatus_To_api_ReplicationControllerStatus(in *ReplicationControllerStatus, out *api.ReplicationControllerStatus, s conversion.Scope) error { + return autoconvert_v1_ReplicationControllerStatus_To_api_ReplicationControllerStatus(in, out, s) +} + +func autoconvert_v1_ResourceQuota_To_api_ResourceQuota(in *ResourceQuota, out *api.ResourceQuota, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ResourceQuota))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -4287,14 +5424,18 @@ func convert_v1_ResourceQuota_To_api_ResourceQuota(in *ResourceQuota, out *api.R return nil } -func convert_v1_ResourceQuotaList_To_api_ResourceQuotaList(in *ResourceQuotaList, out *api.ResourceQuotaList, s conversion.Scope) error { +func convert_v1_ResourceQuota_To_api_ResourceQuota(in *ResourceQuota, out *api.ResourceQuota, s conversion.Scope) error { + return autoconvert_v1_ResourceQuota_To_api_ResourceQuota(in, out, s) +} + +func autoconvert_v1_ResourceQuotaList_To_api_ResourceQuotaList(in *ResourceQuotaList, out *api.ResourceQuotaList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ResourceQuotaList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -4310,7 +5451,11 @@ func convert_v1_ResourceQuotaList_To_api_ResourceQuotaList(in *ResourceQuotaList return nil } -func convert_v1_ResourceQuotaSpec_To_api_ResourceQuotaSpec(in *ResourceQuotaSpec, out *api.ResourceQuotaSpec, s conversion.Scope) error { +func convert_v1_ResourceQuotaList_To_api_ResourceQuotaList(in *ResourceQuotaList, out *api.ResourceQuotaList, s conversion.Scope) error { + return autoconvert_v1_ResourceQuotaList_To_api_ResourceQuotaList(in, out, s) +} + +func autoconvert_v1_ResourceQuotaSpec_To_api_ResourceQuotaSpec(in *ResourceQuotaSpec, out *api.ResourceQuotaSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ResourceQuotaSpec))(in) } @@ -4329,7 +5474,11 @@ func convert_v1_ResourceQuotaSpec_To_api_ResourceQuotaSpec(in *ResourceQuotaSpec return nil } -func convert_v1_ResourceQuotaStatus_To_api_ResourceQuotaStatus(in *ResourceQuotaStatus, out *api.ResourceQuotaStatus, s conversion.Scope) error { +func convert_v1_ResourceQuotaSpec_To_api_ResourceQuotaSpec(in *ResourceQuotaSpec, out *api.ResourceQuotaSpec, s conversion.Scope) error { + return autoconvert_v1_ResourceQuotaSpec_To_api_ResourceQuotaSpec(in, out, s) +} + +func autoconvert_v1_ResourceQuotaStatus_To_api_ResourceQuotaStatus(in *ResourceQuotaStatus, out *api.ResourceQuotaStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ResourceQuotaStatus))(in) } @@ -4360,7 +5509,11 @@ func convert_v1_ResourceQuotaStatus_To_api_ResourceQuotaStatus(in *ResourceQuota return nil } -func convert_v1_ResourceRequirements_To_api_ResourceRequirements(in *ResourceRequirements, out *api.ResourceRequirements, s conversion.Scope) error { +func convert_v1_ResourceQuotaStatus_To_api_ResourceQuotaStatus(in *ResourceQuotaStatus, out *api.ResourceQuotaStatus, s conversion.Scope) error { + return autoconvert_v1_ResourceQuotaStatus_To_api_ResourceQuotaStatus(in, out, s) +} + +func autoconvert_v1_ResourceRequirements_To_api_ResourceRequirements(in *ResourceRequirements, out *api.ResourceRequirements, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ResourceRequirements))(in) } @@ -4391,91 +5544,11 @@ func convert_v1_ResourceRequirements_To_api_ResourceRequirements(in *ResourceReq return nil } -func convert_v1_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions(in *FSGroupStrategyOptions, out *api.FSGroupStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*FSGroupStrategyOptions))(in) - } - out.Type = api.FSGroupStrategyType(in.Type) - if in.Ranges != nil { - out.Ranges = make([]api.IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := convert_v1_IDRange_To_api_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func convert_v1_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions(in *SupplementalGroupsStrategyOptions, out *api.SupplementalGroupsStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SupplementalGroupsStrategyOptions))(in) - } - out.Type = api.SupplementalGroupsStrategyType(in.Type) - if in.Ranges != nil { - out.Ranges = make([]api.IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := convert_v1_IDRange_To_api_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func convert_v1_IDRange_To_api_IDRange(in *IDRange, out *api.IDRange, s conversion.Scope) error { - out.Min = in.Min - out.Max = in.Max - return nil -} - -func convert_v1_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions(in *RunAsUserStrategyOptions, out *api.RunAsUserStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*RunAsUserStrategyOptions))(in) - } - out.Type = api.RunAsUserStrategyType(in.Type) - if in.UID != nil { - out.UID = new(int64) - *out.UID = *in.UID - } else { - out.UID = nil - } - if in.UIDRangeMin != nil { - out.UIDRangeMin = new(int64) - *out.UIDRangeMin = *in.UIDRangeMin - } else { - out.UIDRangeMin = nil - } - if in.UIDRangeMax != nil { - out.UIDRangeMax = new(int64) - *out.UIDRangeMax = *in.UIDRangeMax - } else { - out.UIDRangeMax = nil - } - return nil -} - -func convert_v1_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions(in *SELinuxContextStrategyOptions, out *api.SELinuxContextStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SELinuxContextStrategyOptions))(in) - } - out.Type = api.SELinuxContextStrategyType(in.Type) - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(api.SELinuxOptions) - if err := convert_v1_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - return nil +func convert_v1_ResourceRequirements_To_api_ResourceRequirements(in *ResourceRequirements, out *api.ResourceRequirements, s conversion.Scope) error { + return autoconvert_v1_ResourceRequirements_To_api_ResourceRequirements(in, out, s) } -func convert_v1_SELinuxOptions_To_api_SELinuxOptions(in *SELinuxOptions, out *api.SELinuxOptions, s conversion.Scope) error { +func autoconvert_v1_SELinuxOptions_To_api_SELinuxOptions(in *SELinuxOptions, out *api.SELinuxOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*SELinuxOptions))(in) } @@ -4486,11 +5559,15 @@ func convert_v1_SELinuxOptions_To_api_SELinuxOptions(in *SELinuxOptions, out *ap return nil } -func convert_v1_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.Scope) error { +func convert_v1_SELinuxOptions_To_api_SELinuxOptions(in *SELinuxOptions, out *api.SELinuxOptions, s conversion.Scope) error { + return autoconvert_v1_SELinuxOptions_To_api_SELinuxOptions(in, out, s) +} + +func autoconvert_v1_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Secret))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -4512,14 +5589,18 @@ func convert_v1_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.S return nil } -func convert_v1_SecretList_To_api_SecretList(in *SecretList, out *api.SecretList, s conversion.Scope) error { +func convert_v1_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.Scope) error { + return autoconvert_v1_Secret_To_api_Secret(in, out, s) +} + +func autoconvert_v1_SecretList_To_api_SecretList(in *SecretList, out *api.SecretList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*SecretList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -4535,7 +5616,11 @@ func convert_v1_SecretList_To_api_SecretList(in *SecretList, out *api.SecretList return nil } -func convert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error { +func convert_v1_SecretList_To_api_SecretList(in *SecretList, out *api.SecretList, s conversion.Scope) error { + return autoconvert_v1_SecretList_To_api_SecretList(in, out, s) +} + +func autoconvert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*SecretVolumeSource))(in) } @@ -4543,7 +5628,11 @@ func convert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *SecretVolumeSou return nil } -func convert_v1_SecurityContext_To_api_SecurityContext(in *SecurityContext, out *api.SecurityContext, s conversion.Scope) error { +func convert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error { + return autoconvert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in, out, s) +} + +func autoconvert_v1_SecurityContext_To_api_SecurityContext(in *SecurityContext, out *api.SecurityContext, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*SecurityContext))(in) } @@ -4579,102 +5668,32 @@ func convert_v1_SecurityContext_To_api_SecurityContext(in *SecurityContext, out return nil } -func convert_v1_SecurityContextConstraints_To_api_SecurityContextConstraints(in *SecurityContextConstraints, out *api.SecurityContextConstraints, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SecurityContextConstraints))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - out.AllowPrivilegedContainer = in.AllowPrivilegedContainer - if in.AllowedCapabilities != nil { - out.AllowedCapabilities = make([]api.Capability, len(in.AllowedCapabilities)) - for i := range in.AllowedCapabilities { - out.AllowedCapabilities[i] = api.Capability(in.AllowedCapabilities[i]) - } - } else { - out.AllowedCapabilities = nil - } - out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin - out.AllowHostNetwork = in.AllowHostNetwork - out.AllowHostPorts = in.AllowHostPorts - out.AllowHostPID = in.AllowHostPID - out.AllowHostIPC = in.AllowHostIPC - if err := convert_v1_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil { - return err - } - if err := convert_v1_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil { - return err - } - if err := convert_v1_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions(&in.FSGroup, &out.FSGroup, s); err != nil { - return err - } - if err := convert_v1_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions(&in.SupplementalGroups, &out.SupplementalGroups, s); err != nil { - return err - } - if in.Users != nil { - out.Users = make([]string, len(in.Users)) - for i := range in.Users { - out.Users[i] = in.Users[i] - } - } else { - out.Users = nil - } - if in.Groups != nil { - out.Groups = make([]string, len(in.Groups)) - for i := range in.Groups { - out.Groups[i] = in.Groups[i] - } - } else { - out.Groups = nil - } - return nil +func convert_v1_SecurityContext_To_api_SecurityContext(in *SecurityContext, out *api.SecurityContext, s conversion.Scope) error { + return autoconvert_v1_SecurityContext_To_api_SecurityContext(in, out, s) } -func convert_v1_SecurityContextConstraintsList_To_api_SecurityContextConstraintsList(in *SecurityContextConstraintsList, out *api.SecurityContextConstraintsList, s conversion.Scope) error { +func autoconvert_v1_SerializedReference_To_api_SerializedReference(in *SerializedReference, out *api.SerializedReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SecurityContextConstraintsList))(in) + defaulting.(func(*SerializedReference))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.Reference, &out.Reference, s); err != nil { return err } - if in.Items != nil { - out.Items = make([]api.SecurityContextConstraints, len(in.Items)) - for i := range in.Items { - if err := convert_v1_SecurityContextConstraints_To_api_SecurityContextConstraints(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } return nil } func convert_v1_SerializedReference_To_api_SerializedReference(in *SerializedReference, out *api.SerializedReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SerializedReference))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.Reference, &out.Reference, s); err != nil { - return err - } - return nil + return autoconvert_v1_SerializedReference_To_api_SerializedReference(in, out, s) } -func convert_v1_Service_To_api_Service(in *Service, out *api.Service, s conversion.Scope) error { +func autoconvert_v1_Service_To_api_Service(in *Service, out *api.Service, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Service))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -4689,11 +5708,15 @@ func convert_v1_Service_To_api_Service(in *Service, out *api.Service, s conversi return nil } -func convert_v1_ServiceAccount_To_api_ServiceAccount(in *ServiceAccount, out *api.ServiceAccount, s conversion.Scope) error { +func convert_v1_Service_To_api_Service(in *Service, out *api.Service, s conversion.Scope) error { + return autoconvert_v1_Service_To_api_Service(in, out, s) +} + +func autoconvert_v1_ServiceAccount_To_api_ServiceAccount(in *ServiceAccount, out *api.ServiceAccount, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ServiceAccount))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -4722,14 +5745,18 @@ func convert_v1_ServiceAccount_To_api_ServiceAccount(in *ServiceAccount, out *ap return nil } -func convert_v1_ServiceAccountList_To_api_ServiceAccountList(in *ServiceAccountList, out *api.ServiceAccountList, s conversion.Scope) error { +func convert_v1_ServiceAccount_To_api_ServiceAccount(in *ServiceAccount, out *api.ServiceAccount, s conversion.Scope) error { + return autoconvert_v1_ServiceAccount_To_api_ServiceAccount(in, out, s) +} + +func autoconvert_v1_ServiceAccountList_To_api_ServiceAccountList(in *ServiceAccountList, out *api.ServiceAccountList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ServiceAccountList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -4745,14 +5772,18 @@ func convert_v1_ServiceAccountList_To_api_ServiceAccountList(in *ServiceAccountL return nil } -func convert_v1_ServiceList_To_api_ServiceList(in *ServiceList, out *api.ServiceList, s conversion.Scope) error { +func convert_v1_ServiceAccountList_To_api_ServiceAccountList(in *ServiceAccountList, out *api.ServiceAccountList, s conversion.Scope) error { + return autoconvert_v1_ServiceAccountList_To_api_ServiceAccountList(in, out, s) +} + +func autoconvert_v1_ServiceList_To_api_ServiceList(in *ServiceList, out *api.ServiceList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ServiceList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -4768,7 +5799,11 @@ func convert_v1_ServiceList_To_api_ServiceList(in *ServiceList, out *api.Service return nil } -func convert_v1_ServicePort_To_api_ServicePort(in *ServicePort, out *api.ServicePort, s conversion.Scope) error { +func convert_v1_ServiceList_To_api_ServiceList(in *ServiceList, out *api.ServiceList, s conversion.Scope) error { + return autoconvert_v1_ServiceList_To_api_ServiceList(in, out, s) +} + +func autoconvert_v1_ServicePort_To_api_ServicePort(in *ServicePort, out *api.ServicePort, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ServicePort))(in) } @@ -4782,7 +5817,11 @@ func convert_v1_ServicePort_To_api_ServicePort(in *ServicePort, out *api.Service return nil } -func convert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.ServiceSpec, s conversion.Scope) error { +func convert_v1_ServicePort_To_api_ServicePort(in *ServicePort, out *api.ServicePort, s conversion.Scope) error { + return autoconvert_v1_ServicePort_To_api_ServicePort(in, out, s) +} + +func autoconvert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.ServiceSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ServiceSpec))(in) } @@ -4814,12 +5853,13 @@ func convert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.Service } else { out.ExternalIPs = nil } + // in.DeprecatedPublicIPs has no peer in out out.SessionAffinity = api.ServiceAffinity(in.SessionAffinity) out.LoadBalancerIP = in.LoadBalancerIP return nil } -func convert_v1_ServiceStatus_To_api_ServiceStatus(in *ServiceStatus, out *api.ServiceStatus, s conversion.Scope) error { +func autoconvert_v1_ServiceStatus_To_api_ServiceStatus(in *ServiceStatus, out *api.ServiceStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*ServiceStatus))(in) } @@ -4829,62 +5869,11 @@ func convert_v1_ServiceStatus_To_api_ServiceStatus(in *ServiceStatus, out *api.S return nil } -func convert_v1_Status_To_api_Status(in *Status, out *api.Status, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Status))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - out.Status = in.Status - out.Message = in.Message - out.Reason = api.StatusReason(in.Reason) - if in.Details != nil { - out.Details = new(api.StatusDetails) - if err := convert_v1_StatusDetails_To_api_StatusDetails(in.Details, out.Details, s); err != nil { - return err - } - } else { - out.Details = nil - } - out.Code = in.Code - return nil -} - -func convert_v1_StatusCause_To_api_StatusCause(in *StatusCause, out *api.StatusCause, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*StatusCause))(in) - } - out.Type = api.CauseType(in.Type) - out.Message = in.Message - out.Field = in.Field - return nil -} - -func convert_v1_StatusDetails_To_api_StatusDetails(in *StatusDetails, out *api.StatusDetails, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*StatusDetails))(in) - } - out.Name = in.Name - out.Kind = in.Kind - if in.Causes != nil { - out.Causes = make([]api.StatusCause, len(in.Causes)) - for i := range in.Causes { - if err := convert_v1_StatusCause_To_api_StatusCause(&in.Causes[i], &out.Causes[i], s); err != nil { - return err - } - } - } else { - out.Causes = nil - } - out.RetryAfterSeconds = in.RetryAfterSeconds - return nil +func convert_v1_ServiceStatus_To_api_ServiceStatus(in *ServiceStatus, out *api.ServiceStatus, s conversion.Scope) error { + return autoconvert_v1_ServiceStatus_To_api_ServiceStatus(in, out, s) } -func convert_v1_TCPSocketAction_To_api_TCPSocketAction(in *TCPSocketAction, out *api.TCPSocketAction, s conversion.Scope) error { +func autoconvert_v1_TCPSocketAction_To_api_TCPSocketAction(in *TCPSocketAction, out *api.TCPSocketAction, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*TCPSocketAction))(in) } @@ -4894,16 +5883,11 @@ func convert_v1_TCPSocketAction_To_api_TCPSocketAction(in *TCPSocketAction, out return nil } -func convert_v1_TypeMeta_To_api_TypeMeta(in *TypeMeta, out *api.TypeMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*TypeMeta))(in) - } - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil +func convert_v1_TCPSocketAction_To_api_TCPSocketAction(in *TCPSocketAction, out *api.TCPSocketAction, s conversion.Scope) error { + return autoconvert_v1_TCPSocketAction_To_api_TCPSocketAction(in, out, s) } -func convert_v1_Volume_To_api_Volume(in *Volume, out *api.Volume, s conversion.Scope) error { +func autoconvert_v1_Volume_To_api_Volume(in *Volume, out *api.Volume, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Volume))(in) } @@ -4914,7 +5898,11 @@ func convert_v1_Volume_To_api_Volume(in *Volume, out *api.Volume, s conversion.S return nil } -func convert_v1_VolumeMount_To_api_VolumeMount(in *VolumeMount, out *api.VolumeMount, s conversion.Scope) error { +func convert_v1_Volume_To_api_Volume(in *Volume, out *api.Volume, s conversion.Scope) error { + return autoconvert_v1_Volume_To_api_Volume(in, out, s) +} + +func autoconvert_v1_VolumeMount_To_api_VolumeMount(in *VolumeMount, out *api.VolumeMount, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*VolumeMount))(in) } @@ -4924,254 +5912,387 @@ func convert_v1_VolumeMount_To_api_VolumeMount(in *VolumeMount, out *api.VolumeM return nil } +func convert_v1_VolumeMount_To_api_VolumeMount(in *VolumeMount, out *api.VolumeMount, s conversion.Scope) error { + return autoconvert_v1_VolumeMount_To_api_VolumeMount(in, out, s) +} + +func autoconvert_v1_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api.VolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*VolumeSource))(in) + } + if in.HostPath != nil { + out.HostPath = new(api.HostPathVolumeSource) + if err := convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in.HostPath, out.HostPath, s); err != nil { + return err + } + } else { + out.HostPath = nil + } + if in.EmptyDir != nil { + out.EmptyDir = new(api.EmptyDirVolumeSource) + if err := convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in.EmptyDir, out.EmptyDir, s); err != nil { + return err + } + } else { + out.EmptyDir = nil + } + if in.GCEPersistentDisk != nil { + out.GCEPersistentDisk = new(api.GCEPersistentDiskVolumeSource) + if err := convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in.GCEPersistentDisk, out.GCEPersistentDisk, s); err != nil { + return err + } + } else { + out.GCEPersistentDisk = nil + } + if in.AWSElasticBlockStore != nil { + out.AWSElasticBlockStore = new(api.AWSElasticBlockStoreVolumeSource) + if err := convert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in.AWSElasticBlockStore, out.AWSElasticBlockStore, s); err != nil { + return err + } + } else { + out.AWSElasticBlockStore = nil + } + if in.GitRepo != nil { + out.GitRepo = new(api.GitRepoVolumeSource) + if err := convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in.GitRepo, out.GitRepo, s); err != nil { + return err + } + } else { + out.GitRepo = nil + } + if in.Secret != nil { + out.Secret = new(api.SecretVolumeSource) + if err := convert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in.Secret, out.Secret, s); err != nil { + return err + } + } else { + out.Secret = nil + } + if in.NFS != nil { + out.NFS = new(api.NFSVolumeSource) + if err := convert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in.NFS, out.NFS, s); err != nil { + return err + } + } else { + out.NFS = nil + } + if in.ISCSI != nil { + out.ISCSI = new(api.ISCSIVolumeSource) + if err := convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { + return err + } + } else { + out.ISCSI = nil + } + if in.Glusterfs != nil { + out.Glusterfs = new(api.GlusterfsVolumeSource) + if err := convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { + return err + } + } else { + out.Glusterfs = nil + } + if in.PersistentVolumeClaim != nil { + out.PersistentVolumeClaim = new(api.PersistentVolumeClaimVolumeSource) + if err := convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in.PersistentVolumeClaim, out.PersistentVolumeClaim, s); err != nil { + return err + } + } else { + out.PersistentVolumeClaim = nil + } + if in.RBD != nil { + out.RBD = new(api.RBDVolumeSource) + if err := convert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in.RBD, out.RBD, s); err != nil { + return err + } + } else { + out.RBD = nil + } + if in.Cinder != nil { + out.Cinder = new(api.CinderVolumeSource) + if err := convert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in.Cinder, out.Cinder, s); err != nil { + return err + } + } else { + out.Cinder = nil + } + if in.CephFS != nil { + out.CephFS = new(api.CephFSVolumeSource) + if err := convert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in.CephFS, out.CephFS, s); err != nil { + return err + } + } else { + out.CephFS = nil + } + if in.Flocker != nil { + out.Flocker = new(api.FlockerVolumeSource) + if err := convert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource(in.Flocker, out.Flocker, s); err != nil { + return err + } + } else { + out.Flocker = nil + } + if in.DownwardAPI != nil { + out.DownwardAPI = new(api.DownwardAPIVolumeSource) + if err := convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in.DownwardAPI, out.DownwardAPI, s); err != nil { + return err + } + } else { + out.DownwardAPI = nil + } + if in.FC != nil { + out.FC = new(api.FCVolumeSource) + if err := convert_v1_FCVolumeSource_To_api_FCVolumeSource(in.FC, out.FC, s); err != nil { + return err + } + } else { + out.FC = nil + } + return nil +} + +func convert_v1_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api.VolumeSource, s conversion.Scope) error { + return autoconvert_v1_VolumeSource_To_api_VolumeSource(in, out, s) +} + func init() { err := api.Scheme.AddGeneratedConversionFuncs( - convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource, - convert_api_Binding_To_v1_Binding, - convert_api_Capabilities_To_v1_Capabilities, - convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource, - convert_api_CinderVolumeSource_To_v1_CinderVolumeSource, - convert_api_ComponentCondition_To_v1_ComponentCondition, - convert_api_ComponentStatusList_To_v1_ComponentStatusList, - convert_api_ComponentStatus_To_v1_ComponentStatus, - convert_api_ContainerPort_To_v1_ContainerPort, - convert_api_ContainerStateRunning_To_v1_ContainerStateRunning, - convert_api_ContainerStateTerminated_To_v1_ContainerStateTerminated, - convert_api_ContainerStateWaiting_To_v1_ContainerStateWaiting, - convert_api_ContainerState_To_v1_ContainerState, - convert_api_ContainerStatus_To_v1_ContainerStatus, - convert_api_Container_To_v1_Container, - convert_api_DeleteOptions_To_v1_DeleteOptions, - convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile, - convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource, - convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource, - convert_api_EndpointAddress_To_v1_EndpointAddress, - convert_api_EndpointPort_To_v1_EndpointPort, - convert_api_EndpointSubset_To_v1_EndpointSubset, - convert_api_EndpointsList_To_v1_EndpointsList, - convert_api_Endpoints_To_v1_Endpoints, - convert_api_EnvVarSource_To_v1_EnvVarSource, - convert_api_EnvVar_To_v1_EnvVar, - convert_api_EventList_To_v1_EventList, - convert_api_EventSource_To_v1_EventSource, - convert_api_Event_To_v1_Event, - convert_api_ExecAction_To_v1_ExecAction, - convert_api_FSGroupStrategyOptions_To_v1_FSGroupStrategyOptions, - convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource, - convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource, - convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource, - convert_api_HTTPGetAction_To_v1_HTTPGetAction, - convert_api_Handler_To_v1_Handler, - convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource, - convert_api_IDRange_To_v1_IDRange, - convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource, - convert_api_Lifecycle_To_v1_Lifecycle, - convert_api_LimitRangeItem_To_v1_LimitRangeItem, - convert_api_LimitRangeList_To_v1_LimitRangeList, - convert_api_LimitRangeSpec_To_v1_LimitRangeSpec, - convert_api_LimitRange_To_v1_LimitRange, - convert_api_ListMeta_To_v1_ListMeta, - convert_api_ListOptions_To_v1_ListOptions, - convert_api_List_To_v1_List, - convert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress, - convert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus, - convert_api_LocalObjectReference_To_v1_LocalObjectReference, - convert_api_NFSVolumeSource_To_v1_NFSVolumeSource, - convert_api_NamespaceList_To_v1_NamespaceList, - convert_api_NamespaceSpec_To_v1_NamespaceSpec, - convert_api_NamespaceStatus_To_v1_NamespaceStatus, - convert_api_Namespace_To_v1_Namespace, - convert_api_NodeAddress_To_v1_NodeAddress, - convert_api_NodeCondition_To_v1_NodeCondition, - convert_api_NodeList_To_v1_NodeList, - convert_api_NodeSpec_To_v1_NodeSpec, - convert_api_NodeStatus_To_v1_NodeStatus, - convert_api_NodeSystemInfo_To_v1_NodeSystemInfo, - convert_api_Node_To_v1_Node, - convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector, - convert_api_ObjectMeta_To_v1_ObjectMeta, - convert_api_ObjectReference_To_v1_ObjectReference, - convert_api_PersistentVolumeClaimList_To_v1_PersistentVolumeClaimList, - convert_api_PersistentVolumeClaimSpec_To_v1_PersistentVolumeClaimSpec, - convert_api_PersistentVolumeClaimStatus_To_v1_PersistentVolumeClaimStatus, - convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource, - convert_api_PersistentVolumeClaim_To_v1_PersistentVolumeClaim, - convert_api_PersistentVolumeList_To_v1_PersistentVolumeList, - convert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource, - convert_api_PersistentVolumeSpec_To_v1_PersistentVolumeSpec, - convert_api_PersistentVolumeStatus_To_v1_PersistentVolumeStatus, - convert_api_PersistentVolume_To_v1_PersistentVolume, - convert_api_PodAttachOptions_To_v1_PodAttachOptions, - convert_api_PodCondition_To_v1_PodCondition, - convert_api_PodExecOptions_To_v1_PodExecOptions, - convert_api_PodList_To_v1_PodList, - convert_api_PodLogOptions_To_v1_PodLogOptions, - convert_api_PodProxyOptions_To_v1_PodProxyOptions, - convert_api_PodStatusResult_To_v1_PodStatusResult, - convert_api_PodStatus_To_v1_PodStatus, - convert_api_PodTemplateList_To_v1_PodTemplateList, - convert_api_PodTemplateSpec_To_v1_PodTemplateSpec, - convert_api_PodTemplate_To_v1_PodTemplate, - convert_api_Pod_To_v1_Pod, - convert_api_Probe_To_v1_Probe, - convert_api_RBDVolumeSource_To_v1_RBDVolumeSource, - convert_api_RangeAllocation_To_v1_RangeAllocation, - convert_api_ReplicationControllerList_To_v1_ReplicationControllerList, - convert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStatus, - convert_api_ReplicationController_To_v1_ReplicationController, - convert_api_ResourceQuotaList_To_v1_ResourceQuotaList, - convert_api_ResourceQuotaSpec_To_v1_ResourceQuotaSpec, - convert_api_ResourceQuotaStatus_To_v1_ResourceQuotaStatus, - convert_api_ResourceQuota_To_v1_ResourceQuota, - convert_api_ResourceRequirements_To_v1_ResourceRequirements, - convert_api_RunAsUserStrategyOptions_To_v1_RunAsUserStrategyOptions, - convert_api_SELinuxContextStrategyOptions_To_v1_SELinuxContextStrategyOptions, - convert_api_SELinuxOptions_To_v1_SELinuxOptions, - convert_api_SecretList_To_v1_SecretList, - convert_api_SecretVolumeSource_To_v1_SecretVolumeSource, - convert_api_Secret_To_v1_Secret, - convert_api_SecurityContextConstraintsList_To_v1_SecurityContextConstraintsList, - convert_api_SecurityContextConstraints_To_v1_SecurityContextConstraints, - convert_api_SecurityContext_To_v1_SecurityContext, - convert_api_SerializedReference_To_v1_SerializedReference, - convert_api_ServiceAccountList_To_v1_ServiceAccountList, - convert_api_ServiceAccount_To_v1_ServiceAccount, - convert_api_ServiceList_To_v1_ServiceList, - convert_api_ServicePort_To_v1_ServicePort, - convert_api_ServiceSpec_To_v1_ServiceSpec, - convert_api_ServiceStatus_To_v1_ServiceStatus, - convert_api_Service_To_v1_Service, - convert_api_StatusCause_To_v1_StatusCause, - convert_api_StatusDetails_To_v1_StatusDetails, - convert_api_Status_To_v1_Status, - convert_api_SupplementalGroupsStrategyOptions_To_v1_SupplementalGroupsStrategyOptions, - convert_api_TCPSocketAction_To_v1_TCPSocketAction, - convert_api_TypeMeta_To_v1_TypeMeta, - convert_api_VolumeMount_To_v1_VolumeMount, - convert_api_Volume_To_v1_Volume, - convert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource, - convert_v1_Binding_To_api_Binding, - convert_v1_Capabilities_To_api_Capabilities, - convert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource, - convert_v1_CinderVolumeSource_To_api_CinderVolumeSource, - convert_v1_ComponentCondition_To_api_ComponentCondition, - convert_v1_ComponentStatusList_To_api_ComponentStatusList, - convert_v1_ComponentStatus_To_api_ComponentStatus, - convert_v1_ContainerPort_To_api_ContainerPort, - convert_v1_ContainerStateRunning_To_api_ContainerStateRunning, - convert_v1_ContainerStateTerminated_To_api_ContainerStateTerminated, - convert_v1_ContainerStateWaiting_To_api_ContainerStateWaiting, - convert_v1_ContainerState_To_api_ContainerState, - convert_v1_ContainerStatus_To_api_ContainerStatus, - convert_v1_Container_To_api_Container, - convert_v1_DeleteOptions_To_api_DeleteOptions, - convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile, - convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource, - convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource, - convert_v1_EndpointAddress_To_api_EndpointAddress, - convert_v1_EndpointPort_To_api_EndpointPort, - convert_v1_EndpointSubset_To_api_EndpointSubset, - convert_v1_EndpointsList_To_api_EndpointsList, - convert_v1_Endpoints_To_api_Endpoints, - convert_v1_EnvVarSource_To_api_EnvVarSource, - convert_v1_EnvVar_To_api_EnvVar, - convert_v1_EventList_To_api_EventList, - convert_v1_EventSource_To_api_EventSource, - convert_v1_Event_To_api_Event, - convert_v1_ExecAction_To_api_ExecAction, - convert_v1_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions, - convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource, - convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource, - convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource, - convert_v1_HTTPGetAction_To_api_HTTPGetAction, - convert_v1_Handler_To_api_Handler, - convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource, - convert_v1_IDRange_To_api_IDRange, - convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource, - convert_v1_Lifecycle_To_api_Lifecycle, - convert_v1_LimitRangeItem_To_api_LimitRangeItem, - convert_v1_LimitRangeList_To_api_LimitRangeList, - convert_v1_LimitRangeSpec_To_api_LimitRangeSpec, - convert_v1_LimitRange_To_api_LimitRange, - convert_v1_ListMeta_To_api_ListMeta, - convert_v1_ListOptions_To_api_ListOptions, - convert_v1_List_To_api_List, - convert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress, - convert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus, - convert_v1_LocalObjectReference_To_api_LocalObjectReference, - convert_v1_NFSVolumeSource_To_api_NFSVolumeSource, - convert_v1_NamespaceList_To_api_NamespaceList, - convert_v1_NamespaceSpec_To_api_NamespaceSpec, - convert_v1_NamespaceStatus_To_api_NamespaceStatus, - convert_v1_Namespace_To_api_Namespace, - convert_v1_NodeAddress_To_api_NodeAddress, - convert_v1_NodeCondition_To_api_NodeCondition, - convert_v1_NodeList_To_api_NodeList, - convert_v1_NodeSpec_To_api_NodeSpec, - convert_v1_NodeStatus_To_api_NodeStatus, - convert_v1_NodeSystemInfo_To_api_NodeSystemInfo, - convert_v1_Node_To_api_Node, - convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector, - convert_v1_ObjectMeta_To_api_ObjectMeta, - convert_v1_ObjectReference_To_api_ObjectReference, - convert_v1_PersistentVolumeClaimList_To_api_PersistentVolumeClaimList, - convert_v1_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec, - convert_v1_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus, - convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource, - convert_v1_PersistentVolumeClaim_To_api_PersistentVolumeClaim, - convert_v1_PersistentVolumeList_To_api_PersistentVolumeList, - convert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource, - convert_v1_PersistentVolumeSpec_To_api_PersistentVolumeSpec, - convert_v1_PersistentVolumeStatus_To_api_PersistentVolumeStatus, - convert_v1_PersistentVolume_To_api_PersistentVolume, - convert_v1_PodAttachOptions_To_api_PodAttachOptions, - convert_v1_PodCondition_To_api_PodCondition, - convert_v1_PodExecOptions_To_api_PodExecOptions, - convert_v1_PodList_To_api_PodList, - convert_v1_PodLogOptions_To_api_PodLogOptions, - convert_v1_PodProxyOptions_To_api_PodProxyOptions, - convert_v1_PodStatusResult_To_api_PodStatusResult, - convert_v1_PodStatus_To_api_PodStatus, - convert_v1_PodTemplateList_To_api_PodTemplateList, - convert_v1_PodTemplateSpec_To_api_PodTemplateSpec, - convert_v1_PodTemplate_To_api_PodTemplate, - convert_v1_Pod_To_api_Pod, - convert_v1_Probe_To_api_Probe, - convert_v1_RBDVolumeSource_To_api_RBDVolumeSource, - convert_v1_RangeAllocation_To_api_RangeAllocation, - convert_v1_ReplicationControllerList_To_api_ReplicationControllerList, - convert_v1_ReplicationControllerStatus_To_api_ReplicationControllerStatus, - convert_v1_ReplicationController_To_api_ReplicationController, - convert_v1_ResourceQuotaList_To_api_ResourceQuotaList, - convert_v1_ResourceQuotaSpec_To_api_ResourceQuotaSpec, - convert_v1_ResourceQuotaStatus_To_api_ResourceQuotaStatus, - convert_v1_ResourceQuota_To_api_ResourceQuota, - convert_v1_ResourceRequirements_To_api_ResourceRequirements, - convert_v1_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions, - convert_v1_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions, - convert_v1_SELinuxOptions_To_api_SELinuxOptions, - convert_v1_SecretList_To_api_SecretList, - convert_v1_SecretVolumeSource_To_api_SecretVolumeSource, - convert_v1_Secret_To_api_Secret, - convert_v1_SecurityContextConstraintsList_To_api_SecurityContextConstraintsList, - convert_v1_SecurityContextConstraints_To_api_SecurityContextConstraints, - convert_v1_SecurityContext_To_api_SecurityContext, - convert_v1_SerializedReference_To_api_SerializedReference, - convert_v1_ServiceAccountList_To_api_ServiceAccountList, - convert_v1_ServiceAccount_To_api_ServiceAccount, - convert_v1_ServiceList_To_api_ServiceList, - convert_v1_ServicePort_To_api_ServicePort, - convert_v1_ServiceSpec_To_api_ServiceSpec, - convert_v1_ServiceStatus_To_api_ServiceStatus, - convert_v1_Service_To_api_Service, - convert_v1_StatusCause_To_api_StatusCause, - convert_v1_StatusDetails_To_api_StatusDetails, - convert_v1_Status_To_api_Status, - convert_v1_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions, - convert_v1_TCPSocketAction_To_api_TCPSocketAction, - convert_v1_TypeMeta_To_api_TypeMeta, - convert_v1_VolumeMount_To_api_VolumeMount, - convert_v1_Volume_To_api_Volume, + autoconvert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource, + autoconvert_api_Binding_To_v1_Binding, + autoconvert_api_Capabilities_To_v1_Capabilities, + autoconvert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource, + autoconvert_api_CinderVolumeSource_To_v1_CinderVolumeSource, + autoconvert_api_ComponentCondition_To_v1_ComponentCondition, + autoconvert_api_ComponentStatusList_To_v1_ComponentStatusList, + autoconvert_api_ComponentStatus_To_v1_ComponentStatus, + autoconvert_api_ContainerPort_To_v1_ContainerPort, + autoconvert_api_ContainerStateRunning_To_v1_ContainerStateRunning, + autoconvert_api_ContainerStateTerminated_To_v1_ContainerStateTerminated, + autoconvert_api_ContainerStateWaiting_To_v1_ContainerStateWaiting, + autoconvert_api_ContainerState_To_v1_ContainerState, + autoconvert_api_ContainerStatus_To_v1_ContainerStatus, + autoconvert_api_Container_To_v1_Container, + autoconvert_api_DaemonEndpoint_To_v1_DaemonEndpoint, + autoconvert_api_DeleteOptions_To_v1_DeleteOptions, + autoconvert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile, + autoconvert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource, + autoconvert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource, + autoconvert_api_EndpointAddress_To_v1_EndpointAddress, + autoconvert_api_EndpointPort_To_v1_EndpointPort, + autoconvert_api_EndpointSubset_To_v1_EndpointSubset, + autoconvert_api_EndpointsList_To_v1_EndpointsList, + autoconvert_api_Endpoints_To_v1_Endpoints, + autoconvert_api_EnvVarSource_To_v1_EnvVarSource, + autoconvert_api_EnvVar_To_v1_EnvVar, + autoconvert_api_EventList_To_v1_EventList, + autoconvert_api_EventSource_To_v1_EventSource, + autoconvert_api_Event_To_v1_Event, + autoconvert_api_ExecAction_To_v1_ExecAction, + autoconvert_api_FCVolumeSource_To_v1_FCVolumeSource, + autoconvert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource, + autoconvert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource, + autoconvert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource, + autoconvert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource, + autoconvert_api_HTTPGetAction_To_v1_HTTPGetAction, + autoconvert_api_Handler_To_v1_Handler, + autoconvert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource, + autoconvert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource, + autoconvert_api_Lifecycle_To_v1_Lifecycle, + autoconvert_api_LimitRangeItem_To_v1_LimitRangeItem, + autoconvert_api_LimitRangeList_To_v1_LimitRangeList, + autoconvert_api_LimitRangeSpec_To_v1_LimitRangeSpec, + autoconvert_api_LimitRange_To_v1_LimitRange, + autoconvert_api_ListOptions_To_v1_ListOptions, + autoconvert_api_List_To_v1_List, + autoconvert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress, + autoconvert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus, + autoconvert_api_LocalObjectReference_To_v1_LocalObjectReference, + autoconvert_api_NFSVolumeSource_To_v1_NFSVolumeSource, + autoconvert_api_NamespaceList_To_v1_NamespaceList, + autoconvert_api_NamespaceSpec_To_v1_NamespaceSpec, + autoconvert_api_NamespaceStatus_To_v1_NamespaceStatus, + autoconvert_api_Namespace_To_v1_Namespace, + autoconvert_api_NodeAddress_To_v1_NodeAddress, + autoconvert_api_NodeCondition_To_v1_NodeCondition, + autoconvert_api_NodeDaemonEndpoints_To_v1_NodeDaemonEndpoints, + autoconvert_api_NodeList_To_v1_NodeList, + autoconvert_api_NodeSpec_To_v1_NodeSpec, + autoconvert_api_NodeStatus_To_v1_NodeStatus, + autoconvert_api_NodeSystemInfo_To_v1_NodeSystemInfo, + autoconvert_api_Node_To_v1_Node, + autoconvert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector, + autoconvert_api_ObjectMeta_To_v1_ObjectMeta, + autoconvert_api_ObjectReference_To_v1_ObjectReference, + autoconvert_api_PersistentVolumeClaimList_To_v1_PersistentVolumeClaimList, + autoconvert_api_PersistentVolumeClaimSpec_To_v1_PersistentVolumeClaimSpec, + autoconvert_api_PersistentVolumeClaimStatus_To_v1_PersistentVolumeClaimStatus, + autoconvert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource, + autoconvert_api_PersistentVolumeClaim_To_v1_PersistentVolumeClaim, + autoconvert_api_PersistentVolumeList_To_v1_PersistentVolumeList, + autoconvert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource, + autoconvert_api_PersistentVolumeSpec_To_v1_PersistentVolumeSpec, + autoconvert_api_PersistentVolumeStatus_To_v1_PersistentVolumeStatus, + autoconvert_api_PersistentVolume_To_v1_PersistentVolume, + autoconvert_api_PodAttachOptions_To_v1_PodAttachOptions, + autoconvert_api_PodCondition_To_v1_PodCondition, + autoconvert_api_PodExecOptions_To_v1_PodExecOptions, + autoconvert_api_PodList_To_v1_PodList, + autoconvert_api_PodLogOptions_To_v1_PodLogOptions, + autoconvert_api_PodProxyOptions_To_v1_PodProxyOptions, + autoconvert_api_PodSpec_To_v1_PodSpec, + autoconvert_api_PodStatusResult_To_v1_PodStatusResult, + autoconvert_api_PodStatus_To_v1_PodStatus, + autoconvert_api_PodTemplateList_To_v1_PodTemplateList, + autoconvert_api_PodTemplateSpec_To_v1_PodTemplateSpec, + autoconvert_api_PodTemplate_To_v1_PodTemplate, + autoconvert_api_Pod_To_v1_Pod, + autoconvert_api_Probe_To_v1_Probe, + autoconvert_api_RBDVolumeSource_To_v1_RBDVolumeSource, + autoconvert_api_RangeAllocation_To_v1_RangeAllocation, + autoconvert_api_ReplicationControllerList_To_v1_ReplicationControllerList, + autoconvert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec, + autoconvert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStatus, + autoconvert_api_ReplicationController_To_v1_ReplicationController, + autoconvert_api_ResourceQuotaList_To_v1_ResourceQuotaList, + autoconvert_api_ResourceQuotaSpec_To_v1_ResourceQuotaSpec, + autoconvert_api_ResourceQuotaStatus_To_v1_ResourceQuotaStatus, + autoconvert_api_ResourceQuota_To_v1_ResourceQuota, + autoconvert_api_ResourceRequirements_To_v1_ResourceRequirements, + autoconvert_api_SELinuxOptions_To_v1_SELinuxOptions, + autoconvert_api_SecretList_To_v1_SecretList, + autoconvert_api_SecretVolumeSource_To_v1_SecretVolumeSource, + autoconvert_api_Secret_To_v1_Secret, + autoconvert_api_SecurityContext_To_v1_SecurityContext, + autoconvert_api_SerializedReference_To_v1_SerializedReference, + autoconvert_api_ServiceAccountList_To_v1_ServiceAccountList, + autoconvert_api_ServiceAccount_To_v1_ServiceAccount, + autoconvert_api_ServiceList_To_v1_ServiceList, + autoconvert_api_ServicePort_To_v1_ServicePort, + autoconvert_api_ServiceSpec_To_v1_ServiceSpec, + autoconvert_api_ServiceStatus_To_v1_ServiceStatus, + autoconvert_api_Service_To_v1_Service, + autoconvert_api_TCPSocketAction_To_v1_TCPSocketAction, + autoconvert_api_VolumeMount_To_v1_VolumeMount, + autoconvert_api_VolumeSource_To_v1_VolumeSource, + autoconvert_api_Volume_To_v1_Volume, + autoconvert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource, + autoconvert_v1_Binding_To_api_Binding, + autoconvert_v1_Capabilities_To_api_Capabilities, + autoconvert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource, + autoconvert_v1_CinderVolumeSource_To_api_CinderVolumeSource, + autoconvert_v1_ComponentCondition_To_api_ComponentCondition, + autoconvert_v1_ComponentStatusList_To_api_ComponentStatusList, + autoconvert_v1_ComponentStatus_To_api_ComponentStatus, + autoconvert_v1_ContainerPort_To_api_ContainerPort, + autoconvert_v1_ContainerStateRunning_To_api_ContainerStateRunning, + autoconvert_v1_ContainerStateTerminated_To_api_ContainerStateTerminated, + autoconvert_v1_ContainerStateWaiting_To_api_ContainerStateWaiting, + autoconvert_v1_ContainerState_To_api_ContainerState, + autoconvert_v1_ContainerStatus_To_api_ContainerStatus, + autoconvert_v1_Container_To_api_Container, + autoconvert_v1_DaemonEndpoint_To_api_DaemonEndpoint, + autoconvert_v1_DeleteOptions_To_api_DeleteOptions, + autoconvert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile, + autoconvert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource, + autoconvert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource, + autoconvert_v1_EndpointAddress_To_api_EndpointAddress, + autoconvert_v1_EndpointPort_To_api_EndpointPort, + autoconvert_v1_EndpointSubset_To_api_EndpointSubset, + autoconvert_v1_EndpointsList_To_api_EndpointsList, + autoconvert_v1_Endpoints_To_api_Endpoints, + autoconvert_v1_EnvVarSource_To_api_EnvVarSource, + autoconvert_v1_EnvVar_To_api_EnvVar, + autoconvert_v1_EventList_To_api_EventList, + autoconvert_v1_EventSource_To_api_EventSource, + autoconvert_v1_Event_To_api_Event, + autoconvert_v1_ExecAction_To_api_ExecAction, + autoconvert_v1_FCVolumeSource_To_api_FCVolumeSource, + autoconvert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource, + autoconvert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource, + autoconvert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource, + autoconvert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource, + autoconvert_v1_HTTPGetAction_To_api_HTTPGetAction, + autoconvert_v1_Handler_To_api_Handler, + autoconvert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource, + autoconvert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource, + autoconvert_v1_Lifecycle_To_api_Lifecycle, + autoconvert_v1_LimitRangeItem_To_api_LimitRangeItem, + autoconvert_v1_LimitRangeList_To_api_LimitRangeList, + autoconvert_v1_LimitRangeSpec_To_api_LimitRangeSpec, + autoconvert_v1_LimitRange_To_api_LimitRange, + autoconvert_v1_ListOptions_To_api_ListOptions, + autoconvert_v1_List_To_api_List, + autoconvert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress, + autoconvert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus, + autoconvert_v1_LocalObjectReference_To_api_LocalObjectReference, + autoconvert_v1_NFSVolumeSource_To_api_NFSVolumeSource, + autoconvert_v1_NamespaceList_To_api_NamespaceList, + autoconvert_v1_NamespaceSpec_To_api_NamespaceSpec, + autoconvert_v1_NamespaceStatus_To_api_NamespaceStatus, + autoconvert_v1_Namespace_To_api_Namespace, + autoconvert_v1_NodeAddress_To_api_NodeAddress, + autoconvert_v1_NodeCondition_To_api_NodeCondition, + autoconvert_v1_NodeDaemonEndpoints_To_api_NodeDaemonEndpoints, + autoconvert_v1_NodeList_To_api_NodeList, + autoconvert_v1_NodeSpec_To_api_NodeSpec, + autoconvert_v1_NodeStatus_To_api_NodeStatus, + autoconvert_v1_NodeSystemInfo_To_api_NodeSystemInfo, + autoconvert_v1_Node_To_api_Node, + autoconvert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector, + autoconvert_v1_ObjectMeta_To_api_ObjectMeta, + autoconvert_v1_ObjectReference_To_api_ObjectReference, + autoconvert_v1_PersistentVolumeClaimList_To_api_PersistentVolumeClaimList, + autoconvert_v1_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec, + autoconvert_v1_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus, + autoconvert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource, + autoconvert_v1_PersistentVolumeClaim_To_api_PersistentVolumeClaim, + autoconvert_v1_PersistentVolumeList_To_api_PersistentVolumeList, + autoconvert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource, + autoconvert_v1_PersistentVolumeSpec_To_api_PersistentVolumeSpec, + autoconvert_v1_PersistentVolumeStatus_To_api_PersistentVolumeStatus, + autoconvert_v1_PersistentVolume_To_api_PersistentVolume, + autoconvert_v1_PodAttachOptions_To_api_PodAttachOptions, + autoconvert_v1_PodCondition_To_api_PodCondition, + autoconvert_v1_PodExecOptions_To_api_PodExecOptions, + autoconvert_v1_PodList_To_api_PodList, + autoconvert_v1_PodLogOptions_To_api_PodLogOptions, + autoconvert_v1_PodProxyOptions_To_api_PodProxyOptions, + autoconvert_v1_PodSpec_To_api_PodSpec, + autoconvert_v1_PodStatusResult_To_api_PodStatusResult, + autoconvert_v1_PodStatus_To_api_PodStatus, + autoconvert_v1_PodTemplateList_To_api_PodTemplateList, + autoconvert_v1_PodTemplateSpec_To_api_PodTemplateSpec, + autoconvert_v1_PodTemplate_To_api_PodTemplate, + autoconvert_v1_Pod_To_api_Pod, + autoconvert_v1_Probe_To_api_Probe, + autoconvert_v1_RBDVolumeSource_To_api_RBDVolumeSource, + autoconvert_v1_RangeAllocation_To_api_RangeAllocation, + autoconvert_v1_ReplicationControllerList_To_api_ReplicationControllerList, + autoconvert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec, + autoconvert_v1_ReplicationControllerStatus_To_api_ReplicationControllerStatus, + autoconvert_v1_ReplicationController_To_api_ReplicationController, + autoconvert_v1_ResourceQuotaList_To_api_ResourceQuotaList, + autoconvert_v1_ResourceQuotaSpec_To_api_ResourceQuotaSpec, + autoconvert_v1_ResourceQuotaStatus_To_api_ResourceQuotaStatus, + autoconvert_v1_ResourceQuota_To_api_ResourceQuota, + autoconvert_v1_ResourceRequirements_To_api_ResourceRequirements, + autoconvert_v1_SELinuxOptions_To_api_SELinuxOptions, + autoconvert_v1_SecretList_To_api_SecretList, + autoconvert_v1_SecretVolumeSource_To_api_SecretVolumeSource, + autoconvert_v1_Secret_To_api_Secret, + autoconvert_v1_SecurityContext_To_api_SecurityContext, + autoconvert_v1_SerializedReference_To_api_SerializedReference, + autoconvert_v1_ServiceAccountList_To_api_ServiceAccountList, + autoconvert_v1_ServiceAccount_To_api_ServiceAccount, + autoconvert_v1_ServiceList_To_api_ServiceList, + autoconvert_v1_ServicePort_To_api_ServicePort, + autoconvert_v1_ServiceSpec_To_api_ServiceSpec, + autoconvert_v1_ServiceStatus_To_api_ServiceStatus, + autoconvert_v1_Service_To_api_Service, + autoconvert_v1_TCPSocketAction_To_api_TCPSocketAction, + autoconvert_v1_VolumeMount_To_api_VolumeMount, + autoconvert_v1_VolumeSource_To_api_VolumeSource, + autoconvert_v1_Volume_To_api_Volume, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_test.go index 2c74a518f559..ad9115994850 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_test.go @@ -23,29 +23,6 @@ import ( versioned "k8s.io/kubernetes/pkg/api/v1" ) -func TestNodeConversion(t *testing.T) { - obj, err := versioned.Codec.Decode([]byte(`{"kind":"Minion","apiVersion":"v1"}`)) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if _, ok := obj.(*api.Node); !ok { - t.Errorf("unexpected type: %#v", obj) - } - - obj, err = versioned.Codec.Decode([]byte(`{"kind":"MinionList","apiVersion":"v1"}`)) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if _, ok := obj.(*api.NodeList); !ok { - t.Errorf("unexpected type: %#v", obj) - } - - obj = &api.Node{} - if err := versioned.Codec.DecodeInto([]byte(`{"kind":"Minion","apiVersion":"v1"}`), obj); err != nil { - t.Fatalf("unexpected error: %v", err) - } -} - // TestPodSpecConversion tests that ServiceAccount is an alias for // ServiceAccountName. func TestPodSpecConversion(t *testing.T) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_volumesource_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_volumesource_test.go deleted file mode 100644 index a833f0e189bd..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_volumesource_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package v1 - -import ( - "testing" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/conversion" -) - -func TestAPItoV1VolumeSourceConversion(t *testing.T) { - c := conversion.NewConverter() - c.Debug = t - - if err := c.RegisterConversionFunc(convert_api_VolumeSource_To_v1_VolumeSource); err != nil { - t.Fatalf("unexpected error %v", err) - } - - in := api.VolumeSource{ - DownwardAPI: &api.DownwardAPIVolumeSource{ - Items: []api.DownwardAPIVolumeFile{ - { - Path: "./test/api-to-v1/conversion", - }, - }, - }, - } - out := VolumeSource{} - - if err := c.Convert(&in, &out, 0, nil); err != nil { - t.Fatalf("unexpected error %v", err) - } - if e, a := in.DownwardAPI.Items[0].Path, out.Metadata.Items[0].Name; e != a { - t.Errorf("expected %v, got %v", e, a) - } - if e, a := in.DownwardAPI.Items[0].Path, out.DownwardAPI.Items[0].Path; e != a { - t.Errorf("expected %v, got %v", e, a) - } -} - -func TestV1toAPIVolumeSourceConversion(t *testing.T) { - c := conversion.NewConverter() - c.Debug = t - - if err := c.RegisterConversionFunc(convert_v1_VolumeSource_To_api_VolumeSource); err != nil { - t.Fatalf("unexpected error %v", err) - } - - in := VolumeSource{ - DownwardAPI: &DownwardAPIVolumeSource{ - Items: []DownwardAPIVolumeFile{ - { - Path: "./test/v1-to-api/conversion", - }, - }, - }, - Metadata: &MetadataVolumeSource{ - Items: []MetadataFile{ - { - Name: "./test/v1-to-api/conversion", - }, - }, - }, - } - out := api.VolumeSource{} - - if err := c.Convert(&in, &out, 0, nil); err != nil { - t.Fatalf("unexpected error %v", err) - } - if e, a := in.Metadata.Items[0].Name, out.DownwardAPI.Items[0].Path; e != a { - t.Errorf("expected %v, got %v", e, a) - } - if e, a := in.DownwardAPI.Items[0].Path, out.DownwardAPI.Items[0].Path; e != a { - t.Errorf("expected %v, got %v", e, a) - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go index 80c1c00c1069..87cbcf4b71c7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go @@ -23,6 +23,7 @@ import ( api "k8s.io/kubernetes/pkg/api" resource "k8s.io/kubernetes/pkg/api/resource" + unversioned "k8s.io/kubernetes/pkg/api/unversioned" conversion "k8s.io/kubernetes/pkg/conversion" runtime "k8s.io/kubernetes/pkg/runtime" util "k8s.io/kubernetes/pkg/util" @@ -45,6 +46,27 @@ func deepCopy_resource_Quantity(in resource.Quantity, out *resource.Quantity, c return nil } +func deepCopy_unversioned_ListMeta(in unversioned.ListMeta, out *unversioned.ListMeta, c *conversion.Cloner) error { + out.SelfLink = in.SelfLink + out.ResourceVersion = in.ResourceVersion + return nil +} + +func deepCopy_unversioned_Time(in unversioned.Time, out *unversioned.Time, c *conversion.Cloner) error { + if newVal, err := c.DeepCopy(in.Time); err != nil { + return err + } else { + out.Time = newVal.(time.Time) + } + return nil +} + +func deepCopy_unversioned_TypeMeta(in unversioned.TypeMeta, out *unversioned.TypeMeta, c *conversion.Cloner) error { + out.Kind = in.Kind + out.APIVersion = in.APIVersion + return nil +} + func deepCopy_v1_AWSElasticBlockStoreVolumeSource(in AWSElasticBlockStoreVolumeSource, out *AWSElasticBlockStoreVolumeSource, c *conversion.Cloner) error { out.VolumeID = in.VolumeID out.FSType = in.FSType @@ -54,7 +76,7 @@ func deepCopy_v1_AWSElasticBlockStoreVolumeSource(in AWSElasticBlockStoreVolumeS } func deepCopy_v1_Binding(in Binding, out *Binding, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -125,7 +147,7 @@ func deepCopy_v1_ComponentCondition(in ComponentCondition, out *ComponentConditi } func deepCopy_v1_ComponentStatus(in ComponentStatus, out *ComponentStatus, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -145,10 +167,10 @@ func deepCopy_v1_ComponentStatus(in ComponentStatus, out *ComponentStatus, c *co } func deepCopy_v1_ComponentStatusList(in ComponentStatusList, out *ComponentStatusList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -294,7 +316,7 @@ func deepCopy_v1_ContainerState(in ContainerState, out *ContainerState, c *conve } func deepCopy_v1_ContainerStateRunning(in ContainerStateRunning, out *ContainerStateRunning, c *conversion.Cloner) error { - if err := deepCopy_util_Time(in.StartedAt, &out.StartedAt, c); err != nil { + if err := deepCopy_unversioned_Time(in.StartedAt, &out.StartedAt, c); err != nil { return err } return nil @@ -305,10 +327,10 @@ func deepCopy_v1_ContainerStateTerminated(in ContainerStateTerminated, out *Cont out.Signal = in.Signal out.Reason = in.Reason out.Message = in.Message - if err := deepCopy_util_Time(in.StartedAt, &out.StartedAt, c); err != nil { + if err := deepCopy_unversioned_Time(in.StartedAt, &out.StartedAt, c); err != nil { return err } - if err := deepCopy_util_Time(in.FinishedAt, &out.FinishedAt, c); err != nil { + if err := deepCopy_unversioned_Time(in.FinishedAt, &out.FinishedAt, c); err != nil { return err } out.ContainerID = in.ContainerID @@ -337,8 +359,13 @@ func deepCopy_v1_ContainerStatus(in ContainerStatus, out *ContainerStatus, c *co return nil } +func deepCopy_v1_DaemonEndpoint(in DaemonEndpoint, out *DaemonEndpoint, c *conversion.Cloner) error { + out.Port = in.Port + return nil +} + func deepCopy_v1_DeleteOptions(in DeleteOptions, out *DeleteOptions, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if in.GracePeriodSeconds != nil { @@ -408,6 +435,16 @@ func deepCopy_v1_EndpointSubset(in EndpointSubset, out *EndpointSubset, c *conve } else { out.Addresses = nil } + if in.NotReadyAddresses != nil { + out.NotReadyAddresses = make([]EndpointAddress, len(in.NotReadyAddresses)) + for i := range in.NotReadyAddresses { + if err := deepCopy_v1_EndpointAddress(in.NotReadyAddresses[i], &out.NotReadyAddresses[i], c); err != nil { + return err + } + } + } else { + out.NotReadyAddresses = nil + } if in.Ports != nil { out.Ports = make([]EndpointPort, len(in.Ports)) for i := range in.Ports { @@ -422,7 +459,7 @@ func deepCopy_v1_EndpointSubset(in EndpointSubset, out *EndpointSubset, c *conve } func deepCopy_v1_Endpoints(in Endpoints, out *Endpoints, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -442,10 +479,10 @@ func deepCopy_v1_Endpoints(in Endpoints, out *Endpoints, c *conversion.Cloner) e } func deepCopy_v1_EndpointsList(in EndpointsList, out *EndpointsList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -488,7 +525,7 @@ func deepCopy_v1_EnvVarSource(in EnvVarSource, out *EnvVarSource, c *conversion. } func deepCopy_v1_Event(in Event, out *Event, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -502,10 +539,10 @@ func deepCopy_v1_Event(in Event, out *Event, c *conversion.Cloner) error { if err := deepCopy_v1_EventSource(in.Source, &out.Source, c); err != nil { return err } - if err := deepCopy_util_Time(in.FirstTimestamp, &out.FirstTimestamp, c); err != nil { + if err := deepCopy_unversioned_Time(in.FirstTimestamp, &out.FirstTimestamp, c); err != nil { return err } - if err := deepCopy_util_Time(in.LastTimestamp, &out.LastTimestamp, c); err != nil { + if err := deepCopy_unversioned_Time(in.LastTimestamp, &out.LastTimestamp, c); err != nil { return err } out.Count = in.Count @@ -513,10 +550,10 @@ func deepCopy_v1_Event(in Event, out *Event, c *conversion.Cloner) error { } func deepCopy_v1_EventList(in EventList, out *EventList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -550,6 +587,31 @@ func deepCopy_v1_ExecAction(in ExecAction, out *ExecAction, c *conversion.Cloner return nil } +func deepCopy_v1_FCVolumeSource(in FCVolumeSource, out *FCVolumeSource, c *conversion.Cloner) error { + if in.TargetWWNs != nil { + out.TargetWWNs = make([]string, len(in.TargetWWNs)) + for i := range in.TargetWWNs { + out.TargetWWNs[i] = in.TargetWWNs[i] + } + } else { + out.TargetWWNs = nil + } + if in.Lun != nil { + out.Lun = new(int) + *out.Lun = *in.Lun + } else { + out.Lun = nil + } + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_v1_FlockerVolumeSource(in FlockerVolumeSource, out *FlockerVolumeSource, c *conversion.Cloner) error { + out.DatasetName = in.DatasetName + return nil +} + func deepCopy_v1_GCEPersistentDiskVolumeSource(in GCEPersistentDiskVolumeSource, out *GCEPersistentDiskVolumeSource, c *conversion.Cloner) error { out.PDName = in.PDName out.FSType = in.FSType @@ -644,7 +706,7 @@ func deepCopy_v1_Lifecycle(in Lifecycle, out *Lifecycle, c *conversion.Cloner) e } func deepCopy_v1_LimitRange(in LimitRange, out *LimitRange, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -722,10 +784,10 @@ func deepCopy_v1_LimitRangeItem(in LimitRangeItem, out *LimitRangeItem, c *conve } func deepCopy_v1_LimitRangeList(in LimitRangeList, out *LimitRangeList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -756,10 +818,10 @@ func deepCopy_v1_LimitRangeSpec(in LimitRangeSpec, out *LimitRangeSpec, c *conve } func deepCopy_v1_List(in List, out *List, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -775,14 +837,8 @@ func deepCopy_v1_List(in List, out *List, c *conversion.Cloner) error { return nil } -func deepCopy_v1_ListMeta(in ListMeta, out *ListMeta, c *conversion.Cloner) error { - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil -} - func deepCopy_v1_ListOptions(in ListOptions, out *ListOptions, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } out.LabelSelector = in.LabelSelector @@ -817,28 +873,6 @@ func deepCopy_v1_LocalObjectReference(in LocalObjectReference, out *LocalObjectR return nil } -func deepCopy_v1_MetadataFile(in MetadataFile, out *MetadataFile, c *conversion.Cloner) error { - out.Name = in.Name - if err := deepCopy_v1_ObjectFieldSelector(in.FieldRef, &out.FieldRef, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1_MetadataVolumeSource(in MetadataVolumeSource, out *MetadataVolumeSource, c *conversion.Cloner) error { - if in.Items != nil { - out.Items = make([]MetadataFile, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1_MetadataFile(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - func deepCopy_v1_NFSVolumeSource(in NFSVolumeSource, out *NFSVolumeSource, c *conversion.Cloner) error { out.Server = in.Server out.Path = in.Path @@ -847,7 +881,7 @@ func deepCopy_v1_NFSVolumeSource(in NFSVolumeSource, out *NFSVolumeSource, c *co } func deepCopy_v1_Namespace(in Namespace, out *Namespace, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -863,10 +897,10 @@ func deepCopy_v1_Namespace(in Namespace, out *Namespace, c *conversion.Cloner) e } func deepCopy_v1_NamespaceList(in NamespaceList, out *NamespaceList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -900,7 +934,7 @@ func deepCopy_v1_NamespaceStatus(in NamespaceStatus, out *NamespaceStatus, c *co } func deepCopy_v1_Node(in Node, out *Node, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -924,10 +958,10 @@ func deepCopy_v1_NodeAddress(in NodeAddress, out *NodeAddress, c *conversion.Clo func deepCopy_v1_NodeCondition(in NodeCondition, out *NodeCondition, c *conversion.Cloner) error { out.Type = in.Type out.Status = in.Status - if err := deepCopy_util_Time(in.LastHeartbeatTime, &out.LastHeartbeatTime, c); err != nil { + if err := deepCopy_unversioned_Time(in.LastHeartbeatTime, &out.LastHeartbeatTime, c); err != nil { return err } - if err := deepCopy_util_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { + if err := deepCopy_unversioned_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { return err } out.Reason = in.Reason @@ -935,11 +969,18 @@ func deepCopy_v1_NodeCondition(in NodeCondition, out *NodeCondition, c *conversi return nil } +func deepCopy_v1_NodeDaemonEndpoints(in NodeDaemonEndpoints, out *NodeDaemonEndpoints, c *conversion.Cloner) error { + if err := deepCopy_v1_DaemonEndpoint(in.KubeletEndpoint, &out.KubeletEndpoint, c); err != nil { + return err + } + return nil +} + func deepCopy_v1_NodeList(in NodeList, out *NodeList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -997,6 +1038,9 @@ func deepCopy_v1_NodeStatus(in NodeStatus, out *NodeStatus, c *conversion.Cloner } else { out.Addresses = nil } + if err := deepCopy_v1_NodeDaemonEndpoints(in.DaemonEndpoints, &out.DaemonEndpoints, c); err != nil { + return err + } if err := deepCopy_v1_NodeSystemInfo(in.NodeInfo, &out.NodeInfo, c); err != nil { return err } @@ -1029,12 +1073,12 @@ func deepCopy_v1_ObjectMeta(in ObjectMeta, out *ObjectMeta, c *conversion.Cloner out.UID = in.UID out.ResourceVersion = in.ResourceVersion out.Generation = in.Generation - if err := deepCopy_util_Time(in.CreationTimestamp, &out.CreationTimestamp, c); err != nil { + if err := deepCopy_unversioned_Time(in.CreationTimestamp, &out.CreationTimestamp, c); err != nil { return err } if in.DeletionTimestamp != nil { - out.DeletionTimestamp = new(util.Time) - if err := deepCopy_util_Time(*in.DeletionTimestamp, out.DeletionTimestamp, c); err != nil { + out.DeletionTimestamp = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.DeletionTimestamp, out.DeletionTimestamp, c); err != nil { return err } } else { @@ -1077,7 +1121,7 @@ func deepCopy_v1_ObjectReference(in ObjectReference, out *ObjectReference, c *co } func deepCopy_v1_PersistentVolume(in PersistentVolume, out *PersistentVolume, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1093,7 +1137,7 @@ func deepCopy_v1_PersistentVolume(in PersistentVolume, out *PersistentVolume, c } func deepCopy_v1_PersistentVolumeClaim(in PersistentVolumeClaim, out *PersistentVolumeClaim, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1109,10 +1153,10 @@ func deepCopy_v1_PersistentVolumeClaim(in PersistentVolumeClaim, out *Persistent } func deepCopy_v1_PersistentVolumeClaimList(in PersistentVolumeClaimList, out *PersistentVolumeClaimList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1176,10 +1220,10 @@ func deepCopy_v1_PersistentVolumeClaimVolumeSource(in PersistentVolumeClaimVolum } func deepCopy_v1_PersistentVolumeList(in PersistentVolumeList, out *PersistentVolumeList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1268,6 +1312,22 @@ func deepCopy_v1_PersistentVolumeSource(in PersistentVolumeSource, out *Persiste } else { out.CephFS = nil } + if in.FC != nil { + out.FC = new(FCVolumeSource) + if err := deepCopy_v1_FCVolumeSource(*in.FC, out.FC, c); err != nil { + return err + } + } else { + out.FC = nil + } + if in.Flocker != nil { + out.Flocker = new(FlockerVolumeSource) + if err := deepCopy_v1_FlockerVolumeSource(*in.Flocker, out.Flocker, c); err != nil { + return err + } + } else { + out.Flocker = nil + } return nil } @@ -1315,7 +1375,7 @@ func deepCopy_v1_PersistentVolumeStatus(in PersistentVolumeStatus, out *Persiste } func deepCopy_v1_Pod(in Pod, out *Pod, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1331,7 +1391,7 @@ func deepCopy_v1_Pod(in Pod, out *Pod, c *conversion.Cloner) error { } func deepCopy_v1_PodAttachOptions(in PodAttachOptions, out *PodAttachOptions, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } out.Stdin = in.Stdin @@ -1345,11 +1405,19 @@ func deepCopy_v1_PodAttachOptions(in PodAttachOptions, out *PodAttachOptions, c func deepCopy_v1_PodCondition(in PodCondition, out *PodCondition, c *conversion.Cloner) error { out.Type = in.Type out.Status = in.Status + if err := deepCopy_unversioned_Time(in.LastProbeTime, &out.LastProbeTime, c); err != nil { + return err + } + if err := deepCopy_unversioned_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message return nil } func deepCopy_v1_PodExecOptions(in PodExecOptions, out *PodExecOptions, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } out.Stdin = in.Stdin @@ -1369,10 +1437,10 @@ func deepCopy_v1_PodExecOptions(in PodExecOptions, out *PodExecOptions, c *conve } func deepCopy_v1_PodList(in PodList, out *PodList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1389,23 +1457,54 @@ func deepCopy_v1_PodList(in PodList, out *PodList, c *conversion.Cloner) error { } func deepCopy_v1_PodLogOptions(in PodLogOptions, out *PodLogOptions, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } out.Container = in.Container out.Follow = in.Follow out.Previous = in.Previous + if in.SinceSeconds != nil { + out.SinceSeconds = new(int64) + *out.SinceSeconds = *in.SinceSeconds + } else { + out.SinceSeconds = nil + } + if in.SinceTime != nil { + out.SinceTime = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.SinceTime, out.SinceTime, c); err != nil { + return err + } + } else { + out.SinceTime = nil + } + out.Timestamps = in.Timestamps + if in.TailLines != nil { + out.TailLines = new(int64) + *out.TailLines = *in.TailLines + } else { + out.TailLines = nil + } + if in.LimitBytes != nil { + out.LimitBytes = new(int64) + *out.LimitBytes = *in.LimitBytes + } else { + out.LimitBytes = nil + } return nil } func deepCopy_v1_PodProxyOptions(in PodProxyOptions, out *PodProxyOptions, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } out.Path = in.Path return nil } +func deepCopy_v1_PodSecurityContext(in PodSecurityContext, out *PodSecurityContext, c *conversion.Cloner) error { + return nil +} + func deepCopy_v1_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error { if in.Volumes != nil { out.Volumes = make([]Volume, len(in.Volumes)) @@ -1449,13 +1548,20 @@ func deepCopy_v1_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error { } else { out.NodeSelector = nil } - out.DeprecatedHost = in.DeprecatedHost out.ServiceAccountName = in.ServiceAccountName out.DeprecatedServiceAccount = in.DeprecatedServiceAccount out.NodeName = in.NodeName out.HostNetwork = in.HostNetwork out.HostPID = in.HostPID out.HostIPC = in.HostIPC + if in.SecurityContext != nil { + out.SecurityContext = new(PodSecurityContext) + if err := deepCopy_v1_PodSecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil { + return err + } + } else { + out.SecurityContext = nil + } if in.ImagePullSecrets != nil { out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) for i := range in.ImagePullSecrets { @@ -1466,7 +1572,6 @@ func deepCopy_v1_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error { } else { out.ImagePullSecrets = nil } - return nil } @@ -1487,8 +1592,8 @@ func deepCopy_v1_PodStatus(in PodStatus, out *PodStatus, c *conversion.Cloner) e out.HostIP = in.HostIP out.PodIP = in.PodIP if in.StartTime != nil { - out.StartTime = new(util.Time) - if err := deepCopy_util_Time(*in.StartTime, out.StartTime, c); err != nil { + out.StartTime = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.StartTime, out.StartTime, c); err != nil { return err } } else { @@ -1508,7 +1613,7 @@ func deepCopy_v1_PodStatus(in PodStatus, out *PodStatus, c *conversion.Cloner) e } func deepCopy_v1_PodStatusResult(in PodStatusResult, out *PodStatusResult, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1521,7 +1626,7 @@ func deepCopy_v1_PodStatusResult(in PodStatusResult, out *PodStatusResult, c *co } func deepCopy_v1_PodTemplate(in PodTemplate, out *PodTemplate, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1534,10 +1639,10 @@ func deepCopy_v1_PodTemplate(in PodTemplate, out *PodTemplate, c *conversion.Clo } func deepCopy_v1_PodTemplateList(in PodTemplateList, out *PodTemplateList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1599,7 +1704,7 @@ func deepCopy_v1_RBDVolumeSource(in RBDVolumeSource, out *RBDVolumeSource, c *co } func deepCopy_v1_RangeAllocation(in RangeAllocation, out *RangeAllocation, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1618,7 +1723,7 @@ func deepCopy_v1_RangeAllocation(in RangeAllocation, out *RangeAllocation, c *co } func deepCopy_v1_ReplicationController(in ReplicationController, out *ReplicationController, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1634,10 +1739,10 @@ func deepCopy_v1_ReplicationController(in ReplicationController, out *Replicatio } func deepCopy_v1_ReplicationControllerList(in ReplicationControllerList, out *ReplicationControllerList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1686,7 +1791,7 @@ func deepCopy_v1_ReplicationControllerStatus(in ReplicationControllerStatus, out } func deepCopy_v1_ResourceQuota(in ResourceQuota, out *ResourceQuota, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1702,10 +1807,10 @@ func deepCopy_v1_ResourceQuota(in ResourceQuota, out *ResourceQuota, c *conversi } func deepCopy_v1_ResourceQuotaList(in ResourceQuotaList, out *ResourceQuotaList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1793,42 +1898,6 @@ func deepCopy_v1_ResourceRequirements(in ResourceRequirements, out *ResourceRequ return nil } -func deepCopy_v1_RunAsUserStrategyOptions(in RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.UID != nil { - out.UID = new(int64) - *out.UID = *in.UID - } else { - out.UID = nil - } - if in.UIDRangeMin != nil { - out.UIDRangeMin = new(int64) - *out.UIDRangeMin = *in.UIDRangeMin - } else { - out.UIDRangeMin = nil - } - if in.UIDRangeMax != nil { - out.UIDRangeMax = new(int64) - *out.UIDRangeMax = *in.UIDRangeMax - } else { - out.UIDRangeMax = nil - } - return nil -} - -func deepCopy_v1_SELinuxContextStrategyOptions(in SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(SELinuxOptions) - if err := deepCopy_v1_SELinuxOptions(*in.SELinuxOptions, out.SELinuxOptions, c); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - return nil -} - func deepCopy_v1_SELinuxOptions(in SELinuxOptions, out *SELinuxOptions, c *conversion.Cloner) error { out.User = in.User out.Role = in.Role @@ -1837,44 +1906,8 @@ func deepCopy_v1_SELinuxOptions(in SELinuxOptions, out *SELinuxOptions, c *conve return nil } -func deepCopy_v1_SupplementalGroupsStrategyOptions(in SupplementalGroupsStrategyOptions, out *SupplementalGroupsStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.Ranges != nil { - out.Ranges = make([]IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := deepCopy_v1_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func deepCopy_v1_FSGroupStrategyOptions(in FSGroupStrategyOptions, out *FSGroupStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.Ranges != nil { - out.Ranges = make([]IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := deepCopy_v1_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func deepCopy_v1_IDRange(in IDRange, out *IDRange, c *conversion.Cloner) error { - out.Max = in.Max - out.Min = in.Min - return nil -} - func deepCopy_v1_Secret(in Secret, out *Secret, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1897,10 +1930,10 @@ func deepCopy_v1_Secret(in Secret, out *Secret, c *conversion.Cloner) error { } func deepCopy_v1_SecretList(in SecretList, out *SecretList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -1954,80 +1987,8 @@ func deepCopy_v1_SecurityContext(in SecurityContext, out *SecurityContext, c *co return nil } -func deepCopy_v1_SecurityContextConstraints(in SecurityContextConstraints, out *SecurityContextConstraints, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - out.AllowPrivilegedContainer = in.AllowPrivilegedContainer - if in.AllowedCapabilities != nil { - out.AllowedCapabilities = make([]Capability, len(in.AllowedCapabilities)) - for i := range in.AllowedCapabilities { - out.AllowedCapabilities[i] = in.AllowedCapabilities[i] - } - } else { - out.AllowedCapabilities = nil - } - out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin - out.AllowHostNetwork = in.AllowHostNetwork - out.AllowHostPorts = in.AllowHostPorts - out.AllowHostPID = in.AllowHostPID - out.AllowHostIPC = in.AllowHostIPC - if err := deepCopy_v1_SELinuxContextStrategyOptions(in.SELinuxContext, &out.SELinuxContext, c); err != nil { - return err - } - if err := deepCopy_v1_RunAsUserStrategyOptions(in.RunAsUser, &out.RunAsUser, c); err != nil { - return err - } - if err := deepCopy_v1_FSGroupStrategyOptions(in.FSGroup, &out.FSGroup, c); err != nil { - return err - } - if err := deepCopy_v1_SupplementalGroupsStrategyOptions(in.SupplementalGroups, &out.SupplementalGroups, c); err != nil { - return err - } - if in.Users != nil { - out.Users = make([]string, len(in.Users)) - for i := range in.Users { - out.Users[i] = in.Users[i] - } - } else { - out.Users = nil - } - if in.Groups != nil { - out.Groups = make([]string, len(in.Groups)) - for i := range in.Groups { - out.Groups[i] = in.Groups[i] - } - } else { - out.Groups = nil - } - return nil -} - -func deepCopy_v1_SecurityContextConstraintsList(in SecurityContextConstraintsList, out *SecurityContextConstraintsList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]SecurityContextConstraints, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1_SecurityContextConstraints(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - func deepCopy_v1_SerializedReference(in SerializedReference, out *SerializedReference, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectReference(in.Reference, &out.Reference, c); err != nil { @@ -2037,7 +1998,7 @@ func deepCopy_v1_SerializedReference(in SerializedReference, out *SerializedRefe } func deepCopy_v1_Service(in Service, out *Service, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -2053,7 +2014,7 @@ func deepCopy_v1_Service(in Service, out *Service, c *conversion.Cloner) error { } func deepCopy_v1_ServiceAccount(in ServiceAccount, out *ServiceAccount, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -2083,10 +2044,10 @@ func deepCopy_v1_ServiceAccount(in ServiceAccount, out *ServiceAccount, c *conve } func deepCopy_v1_ServiceAccountList(in ServiceAccountList, out *ServiceAccountList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -2103,10 +2064,10 @@ func deepCopy_v1_ServiceAccountList(in ServiceAccountList, out *ServiceAccountLi } func deepCopy_v1_ServiceList(in ServiceList, out *ServiceList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { @@ -2162,11 +2123,16 @@ func deepCopy_v1_ServiceSpec(in ServiceSpec, out *ServiceSpec, c *conversion.Clo } else { out.ExternalIPs = nil } + if in.DeprecatedPublicIPs != nil { + out.DeprecatedPublicIPs = make([]string, len(in.DeprecatedPublicIPs)) + for i := range in.DeprecatedPublicIPs { + out.DeprecatedPublicIPs[i] = in.DeprecatedPublicIPs[i] + } + } else { + out.DeprecatedPublicIPs = nil + } out.SessionAffinity = in.SessionAffinity out.LoadBalancerIP = in.LoadBalancerIP - - // Carry copy - out.DeprecatedPortalIP = in.DeprecatedPortalIP return nil } @@ -2177,52 +2143,6 @@ func deepCopy_v1_ServiceStatus(in ServiceStatus, out *ServiceStatus, c *conversi return nil } -func deepCopy_v1_Status(in Status, out *Status, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - out.Status = in.Status - out.Message = in.Message - out.Reason = in.Reason - if in.Details != nil { - out.Details = new(StatusDetails) - if err := deepCopy_v1_StatusDetails(*in.Details, out.Details, c); err != nil { - return err - } - } else { - out.Details = nil - } - out.Code = in.Code - return nil -} - -func deepCopy_v1_StatusCause(in StatusCause, out *StatusCause, c *conversion.Cloner) error { - out.Type = in.Type - out.Message = in.Message - out.Field = in.Field - return nil -} - -func deepCopy_v1_StatusDetails(in StatusDetails, out *StatusDetails, c *conversion.Cloner) error { - out.Name = in.Name - out.Kind = in.Kind - if in.Causes != nil { - out.Causes = make([]StatusCause, len(in.Causes)) - for i := range in.Causes { - if err := deepCopy_v1_StatusCause(in.Causes[i], &out.Causes[i], c); err != nil { - return err - } - } - } else { - out.Causes = nil - } - out.RetryAfterSeconds = in.RetryAfterSeconds - return nil -} - func deepCopy_v1_TCPSocketAction(in TCPSocketAction, out *TCPSocketAction, c *conversion.Cloner) error { if err := deepCopy_util_IntOrString(in.Port, &out.Port, c); err != nil { return err @@ -2230,12 +2150,6 @@ func deepCopy_v1_TCPSocketAction(in TCPSocketAction, out *TCPSocketAction, c *co return nil } -func deepCopy_v1_TypeMeta(in TypeMeta, out *TypeMeta, c *conversion.Cloner) error { - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil -} - func deepCopy_v1_Volume(in Volume, out *Volume, c *conversion.Cloner) error { out.Name = in.Name if err := deepCopy_v1_VolumeSource(in.VolumeSource, &out.VolumeSource, c); err != nil { @@ -2356,6 +2270,14 @@ func deepCopy_v1_VolumeSource(in VolumeSource, out *VolumeSource, c *conversion. } else { out.CephFS = nil } + if in.Flocker != nil { + out.Flocker = new(FlockerVolumeSource) + if err := deepCopy_v1_FlockerVolumeSource(*in.Flocker, out.Flocker, c); err != nil { + return err + } + } else { + out.Flocker = nil + } if in.DownwardAPI != nil { out.DownwardAPI = new(DownwardAPIVolumeSource) if err := deepCopy_v1_DownwardAPIVolumeSource(*in.DownwardAPI, out.DownwardAPI, c); err != nil { @@ -2364,13 +2286,13 @@ func deepCopy_v1_VolumeSource(in VolumeSource, out *VolumeSource, c *conversion. } else { out.DownwardAPI = nil } - if in.Metadata != nil { - out.Metadata = new(MetadataVolumeSource) - if err := deepCopy_v1_MetadataVolumeSource(*in.Metadata, out.Metadata, c); err != nil { + if in.FC != nil { + out.FC = new(FCVolumeSource) + if err := deepCopy_v1_FCVolumeSource(*in.FC, out.FC, c); err != nil { return err } } else { - out.Metadata = nil + out.FC = nil } return nil } @@ -2394,18 +2316,12 @@ func deepCopy_util_IntOrString(in util.IntOrString, out *util.IntOrString, c *co return nil } -func deepCopy_util_Time(in util.Time, out *util.Time, c *conversion.Cloner) error { - if newVal, err := c.DeepCopy(in.Time); err != nil { - return err - } else { - out.Time = newVal.(time.Time) - } - return nil -} - func init() { err := api.Scheme.AddGeneratedDeepCopyFuncs( deepCopy_resource_Quantity, + deepCopy_unversioned_ListMeta, + deepCopy_unversioned_Time, + deepCopy_unversioned_TypeMeta, deepCopy_v1_AWSElasticBlockStoreVolumeSource, deepCopy_v1_Binding, deepCopy_v1_Capabilities, @@ -2421,6 +2337,7 @@ func init() { deepCopy_v1_ContainerStateTerminated, deepCopy_v1_ContainerStateWaiting, deepCopy_v1_ContainerStatus, + deepCopy_v1_DaemonEndpoint, deepCopy_v1_DeleteOptions, deepCopy_v1_DownwardAPIVolumeFile, deepCopy_v1_DownwardAPIVolumeSource, @@ -2436,14 +2353,14 @@ func init() { deepCopy_v1_EventList, deepCopy_v1_EventSource, deepCopy_v1_ExecAction, - deepCopy_v1_FSGroupStrategyOptions, + deepCopy_v1_FCVolumeSource, + deepCopy_v1_FlockerVolumeSource, deepCopy_v1_GCEPersistentDiskVolumeSource, deepCopy_v1_GitRepoVolumeSource, deepCopy_v1_GlusterfsVolumeSource, deepCopy_v1_HTTPGetAction, deepCopy_v1_Handler, deepCopy_v1_HostPathVolumeSource, - deepCopy_v1_IDRange, deepCopy_v1_ISCSIVolumeSource, deepCopy_v1_Lifecycle, deepCopy_v1_LimitRange, @@ -2451,13 +2368,10 @@ func init() { deepCopy_v1_LimitRangeList, deepCopy_v1_LimitRangeSpec, deepCopy_v1_List, - deepCopy_v1_ListMeta, deepCopy_v1_ListOptions, deepCopy_v1_LoadBalancerIngress, deepCopy_v1_LoadBalancerStatus, deepCopy_v1_LocalObjectReference, - deepCopy_v1_MetadataFile, - deepCopy_v1_MetadataVolumeSource, deepCopy_v1_NFSVolumeSource, deepCopy_v1_Namespace, deepCopy_v1_NamespaceList, @@ -2466,6 +2380,7 @@ func init() { deepCopy_v1_Node, deepCopy_v1_NodeAddress, deepCopy_v1_NodeCondition, + deepCopy_v1_NodeDaemonEndpoints, deepCopy_v1_NodeList, deepCopy_v1_NodeSpec, deepCopy_v1_NodeStatus, @@ -2490,6 +2405,7 @@ func init() { deepCopy_v1_PodList, deepCopy_v1_PodLogOptions, deepCopy_v1_PodProxyOptions, + deepCopy_v1_PodSecurityContext, deepCopy_v1_PodSpec, deepCopy_v1_PodStatus, deepCopy_v1_PodStatusResult, @@ -2508,15 +2424,11 @@ func init() { deepCopy_v1_ResourceQuotaSpec, deepCopy_v1_ResourceQuotaStatus, deepCopy_v1_ResourceRequirements, - deepCopy_v1_RunAsUserStrategyOptions, - deepCopy_v1_SELinuxContextStrategyOptions, deepCopy_v1_SELinuxOptions, deepCopy_v1_Secret, deepCopy_v1_SecretList, deepCopy_v1_SecretVolumeSource, deepCopy_v1_SecurityContext, - deepCopy_v1_SecurityContextConstraints, - deepCopy_v1_SecurityContextConstraintsList, deepCopy_v1_SerializedReference, deepCopy_v1_Service, deepCopy_v1_ServiceAccount, @@ -2525,18 +2437,12 @@ func init() { deepCopy_v1_ServicePort, deepCopy_v1_ServiceSpec, deepCopy_v1_ServiceStatus, - deepCopy_v1_Status, - deepCopy_v1_StatusCause, - deepCopy_v1_StatusDetails, - deepCopy_v1_SupplementalGroupsStrategyOptions, deepCopy_v1_TCPSocketAction, - deepCopy_v1_TypeMeta, deepCopy_v1_Volume, deepCopy_v1_VolumeMount, deepCopy_v1_VolumeSource, deepCopy_runtime_RawExtension, deepCopy_util_IntOrString, - deepCopy_util_Time, ) if err != nil { // if one of the deep copy functions is malformed, detect it immediately. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go index 62c258ecd483..c4a67e3295ac 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go @@ -25,11 +25,6 @@ import ( func addDefaultingFuncs() { api.Scheme.AddDefaultingFuncs( - func(obj *APIVersion) { - if len(obj.APIGroup) == 0 { - obj.APIGroup = "experimental" - } - }, func(obj *ReplicationController) { var labels map[string]string if obj.Spec.Template != nil { @@ -60,14 +55,6 @@ func addDefaultingFuncs() { if obj.Protocol == "" { obj.Protocol = ProtocolTCP } - - // Carry conversion to make port case valid - switch strings.ToUpper(string(obj.Protocol)) { - case string(ProtocolTCP): - obj.Protocol = ProtocolTCP - case string(ProtocolUDP): - obj.Protocol = ProtocolUDP - } }, func(obj *Container) { if obj.ImagePullPolicy == "" { @@ -100,19 +87,23 @@ func addDefaultingFuncs() { sp.TargetPort = util.NewIntOrStringFromInt(sp.Port) } } - - // Carry conversion - if len(obj.ClusterIP) == 0 && len(obj.DeprecatedPortalIP) > 0 { - obj.ClusterIP = obj.DeprecatedPortalIP - } }, - func(obj *ServicePort) { - // Carry conversion to make port case valid - switch strings.ToUpper(string(obj.Protocol)) { - case string(ProtocolTCP): - obj.Protocol = ProtocolTCP - case string(ProtocolUDP): - obj.Protocol = ProtocolUDP + func(obj *Pod) { + // If limits are specified, but requests are not, default requests to limits + // This is done here rather than a more specific defaulting pass on ResourceRequirements + // because we only want this defaulting semantic to take place on a Pod and not a PodTemplate + for i := range obj.Spec.Containers { + // set requests to limits if requests are not specified, but limits are + if obj.Spec.Containers[i].Resources.Limits != nil { + if obj.Spec.Containers[i].Resources.Requests == nil { + obj.Spec.Containers[i].Resources.Requests = make(ResourceList) + } + for key, value := range obj.Spec.Containers[i].Resources.Limits { + if _, exists := obj.Spec.Containers[i].Resources.Requests[key]; !exists { + obj.Spec.Containers[i].Resources.Requests[key] = *(value.Copy()) + } + } + } } }, func(obj *PodSpec) { @@ -125,16 +116,9 @@ func addDefaultingFuncs() { if obj.HostNetwork { defaultHostNetworkPorts(&obj.Containers) } - - // Carry migration from serviceAccount to serviceAccountName - if len(obj.ServiceAccountName) == 0 && len(obj.DeprecatedServiceAccount) > 0 { - obj.ServiceAccountName = obj.DeprecatedServiceAccount - } - // Carry migration from host to nodeName - if len(obj.NodeName) == 0 && len(obj.DeprecatedHost) > 0 { - obj.NodeName = obj.DeprecatedHost + if obj.SecurityContext == nil { + obj.SecurityContext = &PodSecurityContext{} } - if obj.TerminationGracePeriodSeconds == nil { period := int64(DefaultTerminationGracePeriodSeconds) obj.TerminationGracePeriodSeconds = &period @@ -174,15 +158,6 @@ func addDefaultingFuncs() { } } }, - func(obj *EndpointPort) { - // Carry conversion to make port case valid - switch strings.ToUpper(string(obj.Protocol)) { - case string(ProtocolTCP): - obj.Protocol = ProtocolTCP - case string(ProtocolUDP): - obj.Protocol = ProtocolUDP - } - }, func(obj *HTTPGetAction) { if obj.Path == "" { obj.Path = "/" @@ -206,19 +181,6 @@ func addDefaultingFuncs() { obj.APIVersion = "v1" } }, - func(obj *ResourceRequirements) { - // Set requests to limits if requests are not specified (but limits are). - if obj.Limits != nil { - if obj.Requests == nil { - obj.Requests = make(ResourceList) - } - for key, value := range obj.Limits { - if _, exists := obj.Requests[key]; !exists { - obj.Requests[key] = *(value.Copy()) - } - } - } - }, func(obj *LimitRangeItem) { // for container limits, we apply default values if obj.Type == LimitTypeContainer { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults_test.go index 7a60866fb349..7ce9c8efa579 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults_test.go @@ -433,6 +433,77 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { } } +func TestSetDefaultRequestsPod(t *testing.T) { + // verify we default if limits are specified + s := versioned.PodSpec{} + s.Containers = []versioned.Container{ + { + Resources: versioned.ResourceRequirements{ + Limits: versioned.ResourceList{ + versioned.ResourceCPU: resource.MustParse("100m"), + }, + }, + }, + } + pod := &versioned.Pod{ + Spec: s, + } + output := roundTrip(t, runtime.Object(pod)) + pod2 := output.(*versioned.Pod) + defaultRequest := pod2.Spec.Containers[0].Resources.Requests + requestValue := defaultRequest[versioned.ResourceCPU] + if requestValue.String() != "100m" { + t.Errorf("Expected request cpu: %s, got: %s", "100m", requestValue.String()) + } + + // verify we do nothing if no limits are specified + s = versioned.PodSpec{} + s.Containers = []versioned.Container{{}} + pod = &versioned.Pod{ + Spec: s, + } + output = roundTrip(t, runtime.Object(pod)) + pod2 = output.(*versioned.Pod) + defaultRequest = pod2.Spec.Containers[0].Resources.Requests + requestValue = defaultRequest[versioned.ResourceCPU] + if requestValue.String() != "0" { + t.Errorf("Expected 0 request value, got: %s", requestValue.String()) + } +} + +func TestDefaultRequestIsNotSetForReplicationController(t *testing.T) { + s := versioned.PodSpec{} + s.Containers = []versioned.Container{ + { + Resources: versioned.ResourceRequirements{ + Limits: versioned.ResourceList{ + versioned.ResourceCPU: resource.MustParse("100m"), + }, + }, + }, + } + rc := &versioned.ReplicationController{ + Spec: versioned.ReplicationControllerSpec{ + Replicas: newInt(3), + Template: &versioned.PodTemplateSpec{ + ObjectMeta: versioned.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + Spec: s, + }, + }, + } + output := roundTrip(t, runtime.Object(rc)) + rc2 := output.(*versioned.ReplicationController) + defaultRequest := rc2.Spec.Template.Spec.Containers[0].Resources.Requests + requestValue := defaultRequest[versioned.ResourceCPU] + if requestValue.String() != "0" { + t.Errorf("Expected 0 request value, got: %s", requestValue.String()) + } +} + func TestSetDefaultLimitRangeItem(t *testing.T) { limitRange := &versioned.LimitRange{ ObjectMeta: versioned.ObjectMeta{ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/register.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/register.go index 51a87ca53f09..9957c98bf730 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/register.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/register.go @@ -19,6 +19,7 @@ package v1 import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/registered" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" ) @@ -54,7 +55,6 @@ func addKnownTypes() { &Node{}, &NodeList{}, &Binding{}, - &Status{}, &Event{}, &EventList{}, &List{}, @@ -82,61 +82,50 @@ func addKnownTypes() { &ComponentStatusList{}, &SerializedReference{}, &RangeAllocation{}, - &ThirdPartyResource{}, - &ThirdPartyResourceList{}, - &ThirdPartyResourceData{}, - &SecurityContextConstraints{}, - &SecurityContextConstraintsList{}, ) - // Legacy names are supported - api.Scheme.AddKnownTypeWithName("v1", "Minion", &Node{}) - api.Scheme.AddKnownTypeWithName("v1", "MinionList", &NodeList{}) + + // Add common types + api.Scheme.AddKnownTypes("v1", &unversioned.Status{}) } -func (*Pod) IsAnAPIObject() {} -func (*PodList) IsAnAPIObject() {} -func (*PodStatusResult) IsAnAPIObject() {} -func (*PodTemplate) IsAnAPIObject() {} -func (*PodTemplateList) IsAnAPIObject() {} -func (*ReplicationController) IsAnAPIObject() {} -func (*ReplicationControllerList) IsAnAPIObject() {} -func (*Service) IsAnAPIObject() {} -func (*ServiceList) IsAnAPIObject() {} -func (*Endpoints) IsAnAPIObject() {} -func (*EndpointsList) IsAnAPIObject() {} -func (*Node) IsAnAPIObject() {} -func (*NodeList) IsAnAPIObject() {} -func (*Binding) IsAnAPIObject() {} -func (*Status) IsAnAPIObject() {} -func (*Event) IsAnAPIObject() {} -func (*EventList) IsAnAPIObject() {} -func (*List) IsAnAPIObject() {} -func (*LimitRange) IsAnAPIObject() {} -func (*LimitRangeList) IsAnAPIObject() {} -func (*ResourceQuota) IsAnAPIObject() {} -func (*ResourceQuotaList) IsAnAPIObject() {} -func (*Namespace) IsAnAPIObject() {} -func (*NamespaceList) IsAnAPIObject() {} -func (*Secret) IsAnAPIObject() {} -func (*SecretList) IsAnAPIObject() {} -func (*ServiceAccount) IsAnAPIObject() {} -func (*ServiceAccountList) IsAnAPIObject() {} -func (*PersistentVolume) IsAnAPIObject() {} -func (*PersistentVolumeList) IsAnAPIObject() {} -func (*PersistentVolumeClaim) IsAnAPIObject() {} -func (*PersistentVolumeClaimList) IsAnAPIObject() {} -func (*DeleteOptions) IsAnAPIObject() {} -func (*ListOptions) IsAnAPIObject() {} -func (*PodAttachOptions) IsAnAPIObject() {} -func (*PodLogOptions) IsAnAPIObject() {} -func (*PodExecOptions) IsAnAPIObject() {} -func (*PodProxyOptions) IsAnAPIObject() {} -func (*ComponentStatus) IsAnAPIObject() {} -func (*ComponentStatusList) IsAnAPIObject() {} -func (*SerializedReference) IsAnAPIObject() {} -func (*RangeAllocation) IsAnAPIObject() {} -func (*ThirdPartyResource) IsAnAPIObject() {} -func (*ThirdPartyResourceList) IsAnAPIObject() {} -func (*ThirdPartyResourceData) IsAnAPIObject() {} -func (*SecurityContextConstraints) IsAnAPIObject() {} -func (*SecurityContextConstraintsList) IsAnAPIObject() {} +func (*Pod) IsAnAPIObject() {} +func (*PodList) IsAnAPIObject() {} +func (*PodStatusResult) IsAnAPIObject() {} +func (*PodTemplate) IsAnAPIObject() {} +func (*PodTemplateList) IsAnAPIObject() {} +func (*ReplicationController) IsAnAPIObject() {} +func (*ReplicationControllerList) IsAnAPIObject() {} +func (*Service) IsAnAPIObject() {} +func (*ServiceList) IsAnAPIObject() {} +func (*Endpoints) IsAnAPIObject() {} +func (*EndpointsList) IsAnAPIObject() {} +func (*Node) IsAnAPIObject() {} +func (*NodeList) IsAnAPIObject() {} +func (*Binding) IsAnAPIObject() {} +func (*Event) IsAnAPIObject() {} +func (*EventList) IsAnAPIObject() {} +func (*List) IsAnAPIObject() {} +func (*LimitRange) IsAnAPIObject() {} +func (*LimitRangeList) IsAnAPIObject() {} +func (*ResourceQuota) IsAnAPIObject() {} +func (*ResourceQuotaList) IsAnAPIObject() {} +func (*Namespace) IsAnAPIObject() {} +func (*NamespaceList) IsAnAPIObject() {} +func (*Secret) IsAnAPIObject() {} +func (*SecretList) IsAnAPIObject() {} +func (*ServiceAccount) IsAnAPIObject() {} +func (*ServiceAccountList) IsAnAPIObject() {} +func (*PersistentVolume) IsAnAPIObject() {} +func (*PersistentVolumeList) IsAnAPIObject() {} +func (*PersistentVolumeClaim) IsAnAPIObject() {} +func (*PersistentVolumeClaimList) IsAnAPIObject() {} +func (*DeleteOptions) IsAnAPIObject() {} +func (*ListOptions) IsAnAPIObject() {} +func (*PodAttachOptions) IsAnAPIObject() {} +func (*PodLogOptions) IsAnAPIObject() {} +func (*PodExecOptions) IsAnAPIObject() {} +func (*PodProxyOptions) IsAnAPIObject() {} +func (*ComponentStatus) IsAnAPIObject() {} +func (*ComponentStatusList) IsAnAPIObject() {} +func (*SerializedReference) IsAnAPIObject() {} +func (*RangeAllocation) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go index 1a581b54c5be..13f4618b7b8d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go @@ -18,6 +18,7 @@ package v1 import ( "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" @@ -27,8 +28,8 @@ import ( // generate Swagger API documentation for its models. Please read this PR for more // information on the implementation: https://github.com/emicklei/go-restful/pull/215 // -// TODOs are ignored from the parser. (e.g. TODO(andronat):... || TODO:...) iff -// are on one line! For multiple line or blocks that you want to ignore use ---. +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored and not exported to the SwaggerAPI. // // The aforementioned methods can be generated by hack/update-generated-swagger-docs.sh @@ -62,41 +63,6 @@ import ( // Hypens ('-') cannot be leading or trailing character of the string // and cannot be adjacent to other hyphens. -// TypeMeta describes an individual object in an API response or request -// with strings representing the type of the object and its API schema version. -// Structures that are versioned or persisted should inline TypeMeta. -type TypeMeta struct { - // A string value representing the REST resource this object represents. - // Servers may infer this from the endpoint the client submits requests to. - // Cannot be updated. - // In CamelCase. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - Kind string `json:"kind,omitempty"` - - // APIVersion defines the version of the schema of an object. - // Servers should convert recognized schemas to the latest internal value, and - // may reject unrecognized values. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources - APIVersion string `json:"apiVersion,omitempty"` -} - -// ListMeta describes metadata that synthetic resources must have, including lists and -// various status objects. -type ListMeta struct { - // SelfLink is a URL representing this object. - // Populated by the system. - // Read-only. - SelfLink string `json:"selfLink,omitempty"` - - // String that identifies the server's internal version of this object that - // can be used by clients to determine when objects have changed. - // Value must be treated as opaque by clients and passed unmodified back to the server. - // Populated by the system. - // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency - ResourceVersion string `json:"resourceVersion,omitempty"` -} - // ObjectMeta is metadata that all persisted resources must have, which includes all objects // users must create. type ObjectMeta struct { @@ -175,7 +141,7 @@ type ObjectMeta struct { // Read-only. // Null for lists. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata - CreationTimestamp util.Time `json:"creationTimestamp,omitempty"` + CreationTimestamp unversioned.Time `json:"creationTimestamp,omitempty"` // DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This // field is set by the server when a graceful deletion is requested by the user, and is not @@ -191,7 +157,7 @@ type ObjectMeta struct { // Populated by the system when a graceful deletion is requested. // Read-only. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata - DeletionTimestamp *util.Time `json:"deletionTimestamp,omitempty"` + DeletionTimestamp *unversioned.Time `json:"deletionTimestamp,omitempty"` // Number of seconds allowed for this object to gracefully terminate before // it will be removed from the system. Only set when deletionTimestamp is also set. @@ -280,13 +246,17 @@ type VolumeSource struct { // Cinder represents a cinder volume attached and mounted on kubelets host machine // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md Cinder *CinderVolumeSource `json:"cinder,omitempty"` + // CephFS represents a Ceph FS mount on the host that shares a pod's lifetime CephFS *CephFSVolumeSource `json:"cephfs,omitempty"` + + // Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running + Flocker *FlockerVolumeSource `json:"flocker,omitempty"` + // DownwardAPI represents downward API about the pod that should populate this volume DownwardAPI *DownwardAPIVolumeSource `json:"downwardAPI,omitempty"` - // Metadata represents metadata about the pod that should populate this volume - // NOTE: Deprecated in favor of DownwardAPI - Metadata *MetadataVolumeSource `json:"metadata,omitempty" description: "Metadata volume containing information about the pod"` + // FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + FC *FCVolumeSource `json:"fc,omitempty"` } // PersistentVolumeClaimVolumeSource references the user's PVC in the same namespace. @@ -315,8 +285,8 @@ type PersistentVolumeSource struct { AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty"` // HostPath represents a directory on the host. // Provisioned by a developer or tester. - // This is useful for development and testing only. - // On-host storage is not supported in any way. + // This is useful for single-node development and testing only! + // On-host storage is not supported in any way and WILL NOT WORK in a multi-node cluster. // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath HostPath *HostPathVolumeSource `json:"hostPath,omitempty"` // Glusterfs represents a Glusterfs volume that is attached to a host and @@ -337,13 +307,17 @@ type PersistentVolumeSource struct { Cinder *CinderVolumeSource `json:"cinder,omitempty"` // CephFS represents a Ceph FS mount on the host that shares a pod's lifetime CephFS *CephFSVolumeSource `json:"cephfs,omitempty"` + // FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + FC *FCVolumeSource `json:"fc,omitempty"` + // Flocker represents a Flocker volume attached to a kubelet's host machine and exposed to the pod for its usage. This depends on the Flocker control service being running + Flocker *FlockerVolumeSource `json:"flocker,omitempty"` } // PersistentVolume (PV) is a storage resource provisioned by an administrator. // It is analogous to a node. // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md type PersistentVolume struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -389,12 +363,9 @@ const ( // PersistentVolumeReclaimRecycle means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim. // The volume plugin must support Recycling. PersistentVolumeReclaimRecycle PersistentVolumeReclaimPolicy = "Recycle" - // PersistentVolumeReclaimDelete means the volume will be deleted from Kubernetes on release from its claim. // The volume plugin must support Deletion. - // TODO: implement w/ DeletableVolumePlugin - // PersistentVolumeReclaimDelete PersistentVolumeReclaimPolicy = "Delete" - + PersistentVolumeReclaimDelete PersistentVolumeReclaimPolicy = "Delete" // PersistentVolumeReclaimRetain means the volume will left in its current phase (Released) for manual reclamation by the administrator. // The default policy is Retain. PersistentVolumeReclaimRetain PersistentVolumeReclaimPolicy = "Retain" @@ -414,10 +385,10 @@ type PersistentVolumeStatus struct { // PersistentVolumeList is a list of PersistentVolume items. type PersistentVolumeList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // List of persistent volumes. // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md Items []PersistentVolume `json:"items"` @@ -425,7 +396,7 @@ type PersistentVolumeList struct { // PersistentVolumeClaim is a user's request for and claim to a persistent volume type PersistentVolumeClaim struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -442,10 +413,10 @@ type PersistentVolumeClaim struct { // PersistentVolumeClaimList is a list of PersistentVolumeClaim items. type PersistentVolumeClaimList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // A list of persistent volume claims. // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims Items []PersistentVolumeClaim `json:"items"` @@ -623,6 +594,12 @@ type CephFSVolumeSource struct { ReadOnly bool `json:"readOnly,omitempty"` } +// FlockerVolumeSource represents a Flocker volume mounted by the Flocker agent. +type FlockerVolumeSource struct { + // Required: the volume name. This is going to be store on metadata -> name on the payload for Flocker + DatasetName string `json:"datasetName"` +} + const ( StorageMediumDefault StorageMedium = "" // use whatever the default is for the node StorageMediumMemory StorageMedium = "Memory" // use memory (tmpfs) @@ -744,6 +721,22 @@ type ISCSIVolumeSource struct { ReadOnly bool `json:"readOnly,omitempty"` } +// A Fibre Channel Disk can only be mounted as read/write once. +type FCVolumeSource struct { + // Required: FC target world wide names (WWNs) + TargetWWNs []string `json:"targetWWNs"` + // Required: FC target lun number + Lun *int `json:"lun"` + // Required: Filesystem type to mount. + // Must be a filesystem type supported by the host operating system. + // Ex. "ext4", "xfs", "ntfs" + // TODO: how do we prevent errors in the filesystem from compromising the machine + FSType string `json:"fsType"` + // Optional: Defaults to false (read/write). ReadOnly here will force + // the ReadOnly setting in VolumeMounts. + ReadOnly bool `json:"readOnly,omitempty"` +} + // ContainerPort represents a network port in a single container. type ContainerPort struct { // If specified, this must be an IANA_SVC_NAME and unique within the pod. Each @@ -1046,7 +1039,7 @@ type ContainerStateWaiting struct { // ContainerStateRunning is a running state of a container. type ContainerStateRunning struct { // Time at which the container was last (re-)started - StartedAt util.Time `json:"startedAt,omitempty"` + StartedAt unversioned.Time `json:"startedAt,omitempty"` } // ContainerStateTerminated is a terminated state of a container. @@ -1060,9 +1053,9 @@ type ContainerStateTerminated struct { // Message regarding the last termination of the container Message string `json:"message,omitempty"` // Time at which previous execution of the container started - StartedAt util.Time `json:"startedAt,omitempty"` + StartedAt unversioned.Time `json:"startedAt,omitempty"` // Time at which the container last terminated - FinishedAt util.Time `json:"finishedAt,omitempty"` + FinishedAt unversioned.Time `json:"finishedAt,omitempty"` // Container's ID in the format 'docker://' ContainerID string `json:"containerID,omitempty"` } @@ -1140,7 +1133,6 @@ const ( ) // PodCondition contains details for the current condition of this pod. -// TODO: add LastTransitionTime, Reason, Message to match NodeCondition api. type PodCondition struct { // Type is the type of the condition. // Currently only Ready. @@ -1150,6 +1142,14 @@ type PodCondition struct { // Can be True, False, Unknown. // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions Status ConditionStatus `json:"status"` + // Last time we probed the condition. + LastProbeTime unversioned.Time `json:"lastProbeTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime unversioned.Time `json:"lastTransitionTime,omitempty"` + // Unique, one-word, CamelCase reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // Human-readable message indicating details about last transition. + Message string `json:"message,omitempty"` } // RestartPolicy describes how the container should be restarted. @@ -1217,9 +1217,6 @@ type PodSpec struct { // More info: http://releases.k8s.io/HEAD/docs/user-guide/node-selection/README.md NodeSelector map[string]string `json:"nodeSelector,omitempty"` - // DeprecatedHost is a request to schedule this pod onto a specific node - DeprecatedHost string `json:"host,omitempty" description:"deprecated, use nodeName instead"` - // ServiceAccountName is the name of the ServiceAccount to use to run this pod. // More info: http://releases.k8s.io/HEAD/docs/design/service_accounts.md ServiceAccountName string `json:"serviceAccountName,omitempty"` @@ -1241,6 +1238,8 @@ type PodSpec struct { // Use the host's ipc namespace. // Optional: Default to false. HostIPC bool `json:"hostIPC,omitempty"` + // SecurityContext holds pod-level security attributes and common container settings + SecurityContext *PodSecurityContext `json:"securityContext,omitempty"` // ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. // If specified, these secrets will be passed to individual puller implementations for them to use. For example, // in the case of docker, only DockerConfig type secrets are honored. @@ -1248,6 +1247,10 @@ type PodSpec struct { ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" patchStrategy:"merge" patchMergeKey:"name"` } +// PodSecurityContext holds pod-level security attributes and common container settings. +type PodSecurityContext struct { +} + // PodStatus represents information about the status of a pod. Status may trail the actual // state of a system. type PodStatus struct { @@ -1271,7 +1274,7 @@ type PodStatus struct { // RFC 3339 date and time at which the object was acknowledged by the Kubelet. // This is before the Kubelet pulled the container image(s) for the pod. - StartTime *util.Time `json:"startTime,omitempty"` + StartTime *unversioned.Time `json:"startTime,omitempty"` // The list has one entry per container in the manifest. Each entry is currently the output // of `docker inspect`. @@ -1281,7 +1284,7 @@ type PodStatus struct { // PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded type PodStatusResult struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -1296,7 +1299,7 @@ type PodStatusResult struct { // Pod is a collection of containers that can run on a host. This resource is created // by clients and scheduled onto hosts. type Pod struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -1315,10 +1318,10 @@ type Pod struct { // PodList is a list of Pods. type PodList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // List of pods. // More info: http://releases.k8s.io/HEAD/docs/user-guide/pods.md @@ -1338,7 +1341,7 @@ type PodTemplateSpec struct { // PodTemplate describes a template for creating copies of a predefined pod. type PodTemplate struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -1350,10 +1353,10 @@ type PodTemplate struct { // PodTemplateList is a list of PodTemplates. type PodTemplateList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // List of pod templates Items []PodTemplate `json:"items"` @@ -1398,7 +1401,7 @@ type ReplicationControllerStatus struct { // ReplicationController represents the configuration of a replication controller. type ReplicationController struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // If the Labels of a ReplicationController are empty, they are defaulted to // be the same as the Pod(s) that the replication controller manages. @@ -1419,10 +1422,10 @@ type ReplicationController struct { // ReplicationControllerList is a collection of replication controllers. type ReplicationControllerList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // List of replication controllers. // More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md @@ -1496,9 +1499,6 @@ type ServiceSpec struct { // More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview Selector map[string]string `json:"selector,omitempty"` - // DeprecatedPortalIP - DeprecatedPortalIP string `json:"portalIP,omitempty" description:"deprecated, use clusterIP instead"` - // ClusterIP is usually assigned by the master and is the IP address of the service. // If specified, it will be allocated to the service if it is unused // or else creation of the service will fail. @@ -1513,11 +1513,22 @@ type ServiceSpec struct { // More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services Type ServiceType `json:"type,omitempty"` - // ExternalIPs are used by external load balancers, or can be set by - // users to handle external traffic that arrives at a node. - // Externally visible IPs (e.g. load balancers) that should be proxied to this service. + // externalIPs is a list of IP addresses for which nodes in the cluster + // will also accept traffic for this service. These IPs are not managed by + // Kubernetes. The user is responsible for ensuring that traffic arrives + // at a node with this IP. A common example is external load-balancers + // that are not part of the Kubernetes system. A previous form of this + // functionality exists as the deprecatedPublicIPs field. When using this + // field, callers should also clear the deprecatedPublicIPs field. ExternalIPs []string `json:"externalIPs,omitempty"` + // deprecatedPublicIPs is deprecated and replaced by the externalIPs field + // with almost the exact same semantics. This field is retained in the v1 + // API for compatibility until at least 8/20/2016. It will be removed from + // any new API revisions. If both deprecatedPublicIPs *and* externalIPs are + // set, deprecatedPublicIPs is used. + DeprecatedPublicIPs []string `json:"deprecatedPublicIPs,omitempty"` + // Supports "ClientIP" and "None". Used to maintain session affinity. // Enable client IP based session affinity. // Must be ClientIP or None. @@ -1569,7 +1580,7 @@ type ServicePort struct { // (for example 3306) that the proxy listens on, and the selector that determines which pods // will answer requests sent through the proxy. type Service struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -1593,10 +1604,10 @@ const ( // ServiceList holds a list of services. type ServiceList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // List of services Items []Service `json:"items"` @@ -1607,7 +1618,7 @@ type ServiceList struct { // * a principal that can be authenticated and authorized // * a set of secrets type ServiceAccount struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -1625,10 +1636,10 @@ type ServiceAccount struct { // ServiceAccountList is a list of ServiceAccount objects type ServiceAccountList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // List of ServiceAccounts. // More info: http://releases.k8s.io/HEAD/docs/design/service_accounts.md#service-accounts @@ -1648,12 +1659,17 @@ type ServiceAccountList struct { // }, // ] type Endpoints struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` - // The set of all endpoints is the union of all subsets. + // The set of all endpoints is the union of all subsets. Addresses are placed into + // subsets according to the IPs they share. A single address with multiple ports, + // some of which are ready and some of which are not (because they come from + // different containers) will result in the address being displayed in different + // subsets for the different ports. No address will appear in both Addresses and + // NotReadyAddresses in the same subset. // Sets of addresses and ports that comprise a service. Subsets []EndpointSubset `json:"subsets"` } @@ -1669,8 +1685,13 @@ type Endpoints struct { // a: [ 10.10.1.1:8675, 10.10.2.2:8675 ], // b: [ 10.10.1.1:309, 10.10.2.2:309 ] type EndpointSubset struct { - // IP addresses which offer the related ports. + // IP addresses which offer the related ports that are marked as ready. These endpoints + // should be considered safe for load balancers and clients to utilize. Addresses []EndpointAddress `json:"addresses,omitempty"` + // IP addresses which offer the related ports but are not currently marked as ready + // because they have not yet finished starting, have recently failed a readiness check, + // or have recently failed a liveness check. + NotReadyAddresses []EndpointAddress `json:"notReadyAddresses,omitempty"` // Port numbers available on the related IP addresses. Ports []EndpointPort `json:"ports,omitempty"` } @@ -1705,10 +1726,10 @@ type EndpointPort struct { // EndpointsList is a list of endpoints. type EndpointsList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // List of endpoints. Items []Endpoints `json:"items"` @@ -1728,23 +1749,35 @@ type NodeSpec struct { Unschedulable bool `json:"unschedulable,omitempty"` } +// DaemonEndpoint contains information about a single Daemon endpoint. +type DaemonEndpoint struct { + // Port number of the given endpoint. + Port int `json:port` +} + +// NodeDaemonEndpoints lists ports opened by daemons running on the Node. +type NodeDaemonEndpoints struct { + // Endpoint on which Kubelet is listening. + KubeletEndpoint DaemonEndpoint `json:"kubeletEndpoint,omitempty"` +} + // NodeSystemInfo is a set of ids/uuids to uniquely identify the node. type NodeSystemInfo struct { - // MachineID is the machine-id reported by the node. + // Machine ID reported by the node. MachineID string `json:"machineID"` - // SystemUUID is the system-uuid reported by the node. + // System UUID reported by the node. SystemUUID string `json:"systemUUID"` - // BootID is the boot-id reported by the node. + // Boot ID reported by the node. BootID string `json:"bootID"` - // Kernel version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64) + // Kernel Version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64). KernelVersion string `json:"kernelVersion"` - // OS image used reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy)) + // OS Image reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy)). OsImage string `json:"osImage"` - // Container runtime version reported by the node through runtime remote API (e.g. docker://1.5.0) + // ContainerRuntime Version reported by the node through runtime remote API (e.g. docker://1.5.0). ContainerRuntimeVersion string `json:"containerRuntimeVersion"` - // Kubelet version reported by the node. + // Kubelet Version reported by the node. KubeletVersion string `json:"kubeletVersion"` - // Kube-proxy version reported by the node. + // KubeProxy Version reported by the node. KubeProxyVersion string `json:"kubeProxyVersion"` } @@ -1763,7 +1796,9 @@ type NodeStatus struct { // Queried from cloud provider, if available. // More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-addresses Addresses []NodeAddress `json:"addresses,omitempty" patchStrategy:"merge" patchMergeKey:"type"` - // NodeSystemInfo is a set of ids/uuids to uniquely identify the node. + // Endpoints of daemons running on the Node. + DaemonEndpoints NodeDaemonEndpoints `json:"daemonEndpoints,omitempty"` + // Set of ids/uuids to uniquely identify the node. // More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-info NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty"` } @@ -1797,9 +1832,9 @@ type NodeCondition struct { // Status of the condition, one of True, False, Unknown. Status ConditionStatus `json:"status"` // Last time we got an update on a given condition. - LastHeartbeatTime util.Time `json:"lastHeartbeatTime,omitempty"` + LastHeartbeatTime unversioned.Time `json:"lastHeartbeatTime,omitempty"` // Last time the condition transit from one status to another. - LastTransitionTime util.Time `json:"lastTransitionTime,omitempty"` + LastTransitionTime unversioned.Time `json:"lastTransitionTime,omitempty"` // (brief) reason for the condition's last transition. Reason string `json:"reason,omitempty"` // Human readable message indicating details about last transition. @@ -1841,7 +1876,7 @@ type ResourceList map[ResourceName]resource.Quantity // Node is a worker node in Kubernetes, formerly known as minion. // Each node will have a unique identifier in the cache (i.e. in etcd). type Node struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -1859,10 +1894,10 @@ type Node struct { // NodeList is the whole list of all Nodes which have been registered with master. type NodeList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // List of nodes Items []Node `json:"items"` @@ -1902,7 +1937,7 @@ const ( // Namespace provides a scope for Names. // Use of multiple namespaces is optional. type Namespace struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -1918,10 +1953,10 @@ type Namespace struct { // NamespaceList is a list of Namespaces. type NamespaceList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of Namespace objects in the list. // More info: http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md @@ -1931,7 +1966,7 @@ type NamespaceList struct { // Binding ties one object to another. // For example, a pod is bound to a node by a scheduler. type Binding struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -1942,7 +1977,7 @@ type Binding struct { // DeleteOptions may be provided when deleting an API object type DeleteOptions struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // The duration in seconds before the object should be deleted. Value must be non-negative integer. // The value zero indicates delete immediately. If this value is nil, the default grace period for the @@ -1953,7 +1988,7 @@ type DeleteOptions struct { // ListOptions is the query options to a standard REST list call. type ListOptions struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // A selector to restrict the list of returned objects by their labels. // Defaults to everything. @@ -1971,18 +2006,34 @@ type ListOptions struct { // PodLogOptions is the query options for a Pod's logs REST call. type PodLogOptions struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // The container for which to stream logs. Defaults to only container if there is one container in the pod. Container string `json:"container,omitempty"` - - // Follow the log stream of the pod. - // Defaults to false. + // Follow the log stream of the pod. Defaults to false. Follow bool `json:"follow,omitempty"` - - // Return previous terminated container logs. - // Defaults to false. + // Return previous terminated container logs. Defaults to false. Previous bool `json:"previous,omitempty"` + // A relative time in seconds before the current time from which to show logs. If this value + // precedes the time a pod was started, only logs since the pod start will be returned. + // If this value is in the future, no logs will be returned. + // Only one of sinceSeconds or sinceTime may be specified. + SinceSeconds *int64 `json:"sinceSeconds,omitempty"` + // An RFC3339 timestamp from which to show logs. If this value + // preceeds the time a pod was started, only logs since the pod start will be returned. + // If this value is in the future, no logs will be returned. + // Only one of sinceSeconds or sinceTime may be specified. + SinceTime *unversioned.Time `json:"sinceTime,omitempty"` + // If true, add an RFC3339 or RFC3339Nano timestamp at the beginning of every line + // of log output. Defaults to false. + Timestamps bool `json:"timestamps,omitempty"` + // If set, the number of lines from the end of the logs to show. If not specified, + // logs are shown from the creation of the container or sinceSeconds or sinceTime + TailLines *int64 `json:"tailLines,omitempty"` + // If set, the number of bytes to read from the server before terminating the + // log output. This may not display a complete final line of logging, and may return + // slightly more or slightly less than the specified limit. + LimitBytes *int64 `json:"limitBytes,omitempty"` } // PodAttachOptions is the query options to a Pod's remote attach call. @@ -1990,7 +2041,7 @@ type PodLogOptions struct { // TODO: merge w/ PodExecOptions below for stdin, stdout, etc // and also when we cut V2, we should export a "StreamOptions" or somesuch that contains Stdin, Stdout, Stder and TTY type PodAttachOptions struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Stdin if true, redirects the standard input stream of the pod for this call. // Defaults to false. @@ -2020,7 +2071,7 @@ type PodAttachOptions struct { // TODO: This is largely identical to PodAttachOptions above, make sure they stay in sync and see about merging // and also when we cut V2, we should export a "StreamOptions" or somesuch that contains Stdin, Stdout, Stder and TTY type PodExecOptions struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Redirect the standard input stream of the pod for this call. // Defaults to false. @@ -2048,170 +2099,12 @@ type PodExecOptions struct { // PodProxyOptions is the query options to a Pod's proxy call. type PodProxyOptions struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Path is the URL path to use for the current proxy request to pod. Path string `json:"path,omitempty"` } -// Status is a return value for calls that don't return other objects. -type Status struct { - TypeMeta `json:",inline"` - // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` - - // Status of the operation. - // One of: "Success" or "Failure". - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status - Status string `json:"status,omitempty"` - // A human-readable description of the status of this operation. - Message string `json:"message,omitempty"` - // A machine-readable description of why this operation is in the - // "Failure" status. If this value is empty there - // is no information available. A Reason clarifies an HTTP status - // code but does not override it. - Reason StatusReason `json:"reason,omitempty"` - // Extended data associated with the reason. Each reason may define its - // own extended details. This field is optional and the data returned - // is not guaranteed to conform to any schema except that defined by - // the reason type. - Details *StatusDetails `json:"details,omitempty"` - // Suggested HTTP return code for this status, 0 if not set. - Code int `json:"code,omitempty"` -} - -// StatusDetails is a set of additional properties that MAY be set by the -// server to provide additional information about a response. The Reason -// field of a Status object defines what attributes will be set. Clients -// must ignore fields that do not match the defined type of each attribute, -// and should assume that any attribute may be empty, invalid, or under -// defined. -type StatusDetails struct { - // The name attribute of the resource associated with the status StatusReason - // (when there is a single name which can be described). - Name string `json:"name,omitempty"` - // The kind attribute of the resource associated with the status StatusReason. - // On some operations may differ from the requested resource Kind. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - Kind string `json:"kind,omitempty"` - // The Causes array includes more details associated with the StatusReason - // failure. Not all StatusReasons may provide detailed causes. - Causes []StatusCause `json:"causes,omitempty"` - // If specified, the time in seconds before the operation should be retried. - RetryAfterSeconds int `json:"retryAfterSeconds,omitempty"` -} - -// Values of Status.Status -const ( - StatusSuccess = "Success" - StatusFailure = "Failure" -) - -// StatusReason is an enumeration of possible failure causes. Each StatusReason -// must map to a single HTTP status code, but multiple reasons may map -// to the same HTTP status code. -// TODO: move to apiserver -type StatusReason string - -const ( - // StatusReasonUnknown means the server has declined to indicate a specific reason. - // The details field may contain other information about this error. - // Status code 500. - StatusReasonUnknown StatusReason = "" - - // StatusReasonNotFound means one or more resources required for this operation - // could not be found. - // Details (optional): - // "kind" string - the kind attribute of the missing resource - // on some operations may differ from the requested - // resource. - // "id" string - the identifier of the missing resource - // Status code 404 - StatusReasonNotFound StatusReason = "NotFound" - - // StatusReasonAlreadyExists means the resource you are creating already exists. - // Details (optional): - // "kind" string - the kind attribute of the conflicting resource - // "id" string - the identifier of the conflicting resource - // Status code 409 - StatusReasonAlreadyExists StatusReason = "AlreadyExists" - - // StatusReasonConflict means the requested update operation cannot be completed - // due to a conflict in the operation. The client may need to alter the request. - // Each resource may define custom details that indicate the nature of the - // conflict. - // Status code 409 - StatusReasonConflict StatusReason = "Conflict" - - // StatusReasonInvalid means the requested create or update operation cannot be - // completed due to invalid data provided as part of the request. The client may - // need to alter the request. When set, the client may use the StatusDetails - // message field as a summary of the issues encountered. - // Details (optional): - // "kind" string - the kind attribute of the invalid resource - // "id" string - the identifier of the invalid resource - // "causes" - one or more StatusCause entries indicating the data in the - // provided resource that was invalid. The code, message, and - // field attributes will be set. - // Status code 422 - StatusReasonInvalid StatusReason = "Invalid" - - // StatusReasonServerTimeout means the server can be reached and understood the request, - // but cannot complete the action in a reasonable time. The client should retry the request. - // This is may be due to temporary server load or a transient communication issue with - // another server. Status code 500 is used because the HTTP spec provides no suitable - // server-requested client retry and the 5xx class represents actionable errors. - // Details (optional): - // "kind" string - the kind attribute of the resource being acted on. - // "id" string - the operation that is being attempted. - // Status code 500 - StatusReasonServerTimeout StatusReason = "ServerTimeout" -) - -// StatusCause provides more information about an api.Status failure, including -// cases when multiple errors are encountered. -type StatusCause struct { - // A machine-readable description of the cause of the error. If this value is - // empty there is no information available. - Type CauseType `json:"reason,omitempty"` - // A human-readable description of the cause of the error. This field may be - // presented as-is to a reader. - Message string `json:"message,omitempty"` - // The field of the resource that has caused this error, as named by its JSON - // serialization. May include dot and postfix notation for nested attributes. - // Arrays are zero-indexed. Fields may appear more than once in an array of - // causes due to fields having multiple errors. - // - // Examples: - // "name" - the field "name" on the current resource - // "items[0].name" - the field "name" on the first array entry in "items" - Field string `json:"field,omitempty"` -} - -// CauseType is a machine readable value providing more detail about what -// occurred in a status response. An operation may have multiple causes for a -// status (whether Failure or Success). -type CauseType string - -const ( - // CauseTypeFieldValueNotFound is used to report failure to find a requested value - // (e.g. looking up an ID). - CauseTypeFieldValueNotFound CauseType = "FieldValueNotFound" - // CauseTypeFieldValueRequired is used to report required values that are not - // provided (e.g. empty strings, null values, or empty arrays). - CauseTypeFieldValueRequired CauseType = "FieldValueRequired" - // CauseTypeFieldValueDuplicate is used to report collisions of values that must be - // unique (e.g. unique IDs). - CauseTypeFieldValueDuplicate CauseType = "FieldValueDuplicate" - // CauseTypeFieldValueInvalid is used to report malformed values (e.g. failed regex - // match). - CauseTypeFieldValueInvalid CauseType = "FieldValueInvalid" - // CauseTypeFieldValueNotSupported is used to report valid (as per formatting rules) - // values that can not be handled (e.g. an enumerated string). - CauseTypeFieldValueNotSupported CauseType = "FieldValueNotSupported" -) - // ObjectReference contains enough information to let you inspect or modify the referred object. type ObjectReference struct { // Kind of the referent. @@ -2254,7 +2147,7 @@ type LocalObjectReference struct { // SerializedReference is a reference to serialized object. type SerializedReference struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // The reference to an object in the system. Reference ObjectReference `json:"reference,omitempty"` } @@ -2270,7 +2163,7 @@ type EventSource struct { // Event is a report of an event somewhere in the cluster. // TODO: Decide whether to store these separately or with the object they apply to. type Event struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata"` @@ -2291,10 +2184,10 @@ type Event struct { Source EventSource `json:"source,omitempty"` // The time at which the event was first recorded. (Time of server receipt is in TypeMeta.) - FirstTimestamp util.Time `json:"firstTimestamp,omitempty"` + FirstTimestamp unversioned.Time `json:"firstTimestamp,omitempty"` // The time at which the most recent occurrence of this event was recorded. - LastTimestamp util.Time `json:"lastTimestamp,omitempty"` + LastTimestamp unversioned.Time `json:"lastTimestamp,omitempty"` // The number of times this event has occurred. Count int `json:"count,omitempty"` @@ -2302,10 +2195,10 @@ type Event struct { // EventList is a list of events. type EventList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // List of events Items []Event `json:"items"` @@ -2313,10 +2206,10 @@ type EventList struct { // List holds a list of objects, which may not be known by the server. type List struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // List of objects Items []runtime.RawExtension `json:"items"` @@ -2356,7 +2249,7 @@ type LimitRangeSpec struct { // LimitRange sets resource usage limits for each kind of resource in a Namespace. type LimitRange struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -2368,10 +2261,10 @@ type LimitRange struct { // LimitRangeList is a list of LimitRange items. type LimitRangeList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of LimitRange objects. // More info: http://releases.k8s.io/HEAD/docs/design/admission_control_limit_range.md @@ -2412,7 +2305,7 @@ type ResourceQuotaStatus struct { // ResourceQuota sets aggregate quota restrictions enforced per namespace type ResourceQuota struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -2428,10 +2321,10 @@ type ResourceQuota struct { // ResourceQuotaList is a list of ResourceQuota items. type ResourceQuotaList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of ResourceQuota objects. // More info: http://releases.k8s.io/HEAD/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota @@ -2441,7 +2334,7 @@ type ResourceQuotaList struct { // Secret holds secret data of a certain type. The total bytes of the values in // the Data field must be less than MaxSecretSize bytes. type Secret struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -2496,10 +2389,10 @@ const ( // SecretList is a list of Secret. type SecretList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of secret objects. // More info: http://releases.k8s.io/HEAD/docs/user-guide/secrets.md @@ -2532,7 +2425,7 @@ type ComponentCondition struct { // ComponentStatus (and ComponentStatusList) holds the cluster validation info. type ComponentStatus struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -2543,31 +2436,15 @@ type ComponentStatus struct { // Status of all the conditions for the component as a list of ComponentStatus objects. type ComponentStatusList struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds - ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // List of ComponentStatus objects. Items []ComponentStatus `json:"items"` } -// MetadataVolumeSource represents a volume containing metadata about a pod. -// NOTE: Deprecated in favor of DownwardAPIVolumeSource -type MetadataVolumeSource struct { - // Items is a list of metadata file name - Items []MetadataFile `json:"items,omitempty" description:"list of metadata files"` -} - -// MetadataFile expresses information about a file holding pod metadata. -// NOTE: Deprecated in favor of DownwardAPIVolumeFile -type MetadataFile struct { - // Required: Name is the name of the file - Name string `json:"name" description:"the name of the file to be created"` - // Required: Selects a field of the pod: only annotations, labels, name and namespace are supported. - FieldRef ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod. Supported fields: metadata.annotations, metadata.labels, metadata.name, metadata.namespace"` -} - // DownwardAPIVolumeSource represents a volume containing downward API info type DownwardAPIVolumeSource struct { // Items is a list of downward API volume file @@ -2632,7 +2509,7 @@ type SELinuxOptions struct { // RangeAllocation is not a public type. type RangeAllocation struct { - TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` @@ -2642,182 +2519,3 @@ type RangeAllocation struct { // Data is a bit array containing all allocated addresses in the previous segment. Data []byte `json:"data"` } - -// A ThirdPartyResource is a generic representation of a resource, it is used by add-ons and plugins to add new resource -// types to the API. It consists of one or more Versions of the api. -type ThirdPartyResource struct { - TypeMeta `json:",inline"` - // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata - ObjectMeta `json:"metadata,omitempty"` - - // The description of this object. - Description string `json:"description,omitempty"` - - // The versions for this third party object. - Versions []APIVersion `json:"versions,omitempty"` -} - -// ThirdPartyResourceList is a list of ThirdPartyResource. -type ThirdPartyResourceList struct { - TypeMeta `json:",inline"` - // Standard list metadata. - // More info: http://docs.k8s.io/api-conventions.md#metadata - ListMeta `json:"metadata,omitempty"` - - // Items is a list of schema objects. - Items []ThirdPartyResource `json:"items"` -} - -// An APIVersion represents a single concrete version of an object model. -type APIVersion struct { - // Name of this version (e.g. 'v1'). - Name string `json:"name,omitempty"` - // The API group to add this object into. - // Default 'experimental'. - APIGroup string `json:"apiGroup,omitempty"` -} - -// An internal object, used for versioned storage in etcd. Not exposed to the end user. -type ThirdPartyResourceData struct { - TypeMeta `json:",inline"` - // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata - ObjectMeta `json:"metadata,omitempty"` - - // The raw JSON data for this data. - Data []byte `json:"name,omitempty"` -} - -// SecurityContextConstraints governs the ability to make requests that affect the SecurityContext -// that will be applied to a container. -type SecurityContextConstraints struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` - - // AllowPrivilegedContainer determines if a container can request to be run as privileged. - AllowPrivilegedContainer bool `json:"allowPrivilegedContainer" description:"allow containers to run as privileged"` - // AllowedCapabilities is a list of capabilities that can be requested to add to the container. - AllowedCapabilities []Capability `json:"allowedCapabilities" description:"capabilities that are allowed to be added"` - // AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin - AllowHostDirVolumePlugin bool `json:"allowHostDirVolumePlugin" description:"allow the use of the host dir volume plugin"` - // AllowHostNetwork determines if the policy allows the use of HostNetwork in the pod spec. - AllowHostNetwork bool `json:"allowHostNetwork" description:"allow the use of the hostNetwork in the pod spec"` - // AllowHostPorts determines if the policy allows host ports in the containers. - AllowHostPorts bool `json:"allowHostPorts" description:"allow the use of the host ports in the containers"` - // AllowHostPID determines if the policy allows host pid in the containers. - AllowHostPID bool `json:"allowHostPID" description:"allow the use of the host pid in the containers"` - // AllowHostIPC determines if the policy allows host ipc in the containers. - AllowHostIPC bool `json:"allowHostIPC" description:"allow the use of the host ipc in the containers"` - // SELinuxContext is the strategy that will dictate what labels will be set in the SecurityContext. - SELinuxContext SELinuxContextStrategyOptions `json:"seLinuxContext,omitempty" description:"strategy used to generate SELinuxOptions"` - // RunAsUser is the strategy that will dictate what RunAsUser is used in the SecurityContext. - RunAsUser RunAsUserStrategyOptions `json:"runAsUser,omitempty" description:"strategy used to generate RunAsUser"` - // SupplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. - SupplementalGroups SupplementalGroupsStrategyOptions `json:"supplementalGroups,omitempty" description:"strategy used to generate supplemental groups"` - // FSGroup is the strategy that will dictate what fs group is used by the SecurityContext. - FSGroup FSGroupStrategyOptions `json:"fsGroup,omitempty" description:"strategy used to generate fsGroup"` - - // The users who have permissions to use this security context constraints - Users []string `json:"users,omitempty" description:"users allowed to use this SecurityContextConstraints"` - // The groups that have permission to use this security context constraints - Groups []string `json:"groups,omitempty" description:"groups allowed to use this SecurityContextConstraints"` -} - -// SELinuxContextStrategyOptions defines the strategy type and any options used to create the strategy. -type SELinuxContextStrategyOptions struct { - // Type is the strategy that will dictate what SELinux context is used in the SecurityContext. - Type SELinuxContextStrategyType `json:"type,omitempty" description:"strategy used to generate the SELinux context"` - // seLinuxOptions required to run as; required for MustRunAs - SELinuxOptions *SELinuxOptions `json:"seLinuxOptions,omitempty" description:"seLinuxOptions required to run as; required for MustRunAs"` -} - -// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. -type RunAsUserStrategyOptions struct { - // Type is the strategy that will dictate what RunAsUser is used in the SecurityContext. - Type RunAsUserStrategyType `json:"type,omitempty" description:"strategy used to generate RunAsUser"` - // UID is the user id that containers must run as. Required for the MustRunAs strategy if not using - // namespace/service account allocated uids. - UID *int64 `json:"uid,omitempty" description:"the uid to always run as; required for MustRunAs"` - // UIDRangeMin defines the min value for a strategy that allocates by range. - UIDRangeMin *int64 `json:"uidRangeMin,omitempty" description:"min value for range based allocators"` - // UIDRangeMax defines the max value for a strategy that allocates by range. - UIDRangeMax *int64 `json:"uidRangeMax,omitempty" description:"max value for range based allocators"` -} - -// FSGroupStrategyOptions defines the strategy type and options used to create the strategy. -type FSGroupStrategyOptions struct { - // Type is the strategy that will dictate what FSGroup is used in the SecurityContext. - Type FSGroupStrategyType `json:"type,omitempty" description:"strategy used to generate fsGroup"` - // Ranges are the allowed ranges of fs groups. If you would like to force a single - // fs group then supply a single range with the same start and end. - Ranges []IDRange `json:"ranges,omitempty" description:"ranges of allowable IDs for fsGroup"` -} - -// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. -type SupplementalGroupsStrategyOptions struct { - // Type is the strategy that will dictate what supplemental groups is used in the SecurityContext. - Type SupplementalGroupsStrategyType `json:"type,omitempty" description:"strategy used to generate supplemental groups"` - // Ranges are the allowed ranges of supplemental groups. If you would like to force a single - // supplemental group then supply a single range with the same start and end. - Ranges []IDRange `json:"ranges,omitempty" description:"ranges of allowable IDs for supplemental groups"` -} - -// IDRange provides a min/max of an allowed range of IDs. -// TODO: this could be reused for UIDs. -type IDRange struct { - // Min is the start of the range, inclusive. - Min int64 `json:"min,omitempty" description:"min value for the range"` - // Max is the end of the range, inclusive. - Max int64 `json:"max,omitempty" description:"min value for the range"` -} - -// SELinuxContextStrategyType denotes strategy types for generating SELinux options for a -// SecurityContext -type SELinuxContextStrategyType string - -// RunAsUserStrategyType denotes strategy types for generating RunAsUser values for a -// SecurityContext -type RunAsUserStrategyType string - -// SupplementalGroupsStrategyType denotes strategy types for determining valid supplemental -// groups for a SecurityContext. -type SupplementalGroupsStrategyType string - -// FSGroupStrategyType denotes strategy types for generating FSGroup values for a -// SecurityContext -type FSGroupStrategyType string - -const ( - // container must have SELinux labels of X applied. - SELinuxStrategyMustRunAs SELinuxContextStrategyType = "MustRunAs" - // container may make requests for any SELinux context labels. - SELinuxStrategyRunAsAny SELinuxContextStrategyType = "RunAsAny" - - // container must run as a particular uid. - RunAsUserStrategyMustRunAs RunAsUserStrategyType = "MustRunAs" - // container must run as a particular uid. - RunAsUserStrategyMustRunAsRange RunAsUserStrategyType = "MustRunAsRange" - // container must run as a non-root uid - RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategyType = "MustRunAsNonRoot" - // container may make requests for any uid. - RunAsUserStrategyRunAsAny RunAsUserStrategyType = "RunAsAny" - - // container must have FSGroup of X applied. - FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs" - // container may make requests for any FSGroup labels. - FSGroupStrategyRunAsAny FSGroupStrategyType = "RunAsAny" - - // container must run as a particular gid. - SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs" - // container may make requests for any gid. - SupplementalGroupsrStrategyRunAsAny SupplementalGroupsStrategyType = "RunAsAny" -) - -// SecurityContextConstraintsList is a list of SecurityContextConstraints objects -type SecurityContextConstraintsList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` - - Items []SecurityContextConstraints `json:"items"` -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types_swagger_doc_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types_swagger_doc_generated.go index 88751937679e..4f25221a79ae 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types_swagger_doc_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types_swagger_doc_generated.go @@ -20,23 +20,13 @@ package v1 // generate Swagger API documentation for its models. Please read this PR for more // information on the implementation: https://github.com/emicklei/go-restful/pull/215 // -// TODOs are ignored from the parser. (e.g. TODO(andronat):... || TODO:...) iff -// are on one line! For multiple line or blocks that you want to ignore use ---. +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // // Those methods can be generated by using hack/update-generated-swagger-docs.sh // AUTO-GENERATED FUNCTIONS START HERE -var map_APIVersion = map[string]string{ - "": "An APIVersion represents a single concrete version of an object model.", - "name": "Name of this version (e.g. 'v1').", - "apiGroup": "The API group to add this object into. Default 'experimental'.", -} - -func (APIVersion) SwaggerDoc() map[string]string { - return map_APIVersion -} - var map_AWSElasticBlockStoreVolumeSource = map[string]string{ "": "Represents a persistent disk resource in AWS.\n\nAn Amazon Elastic Block Store (EBS) must already be created, formatted, and reside in the same AWS zone as the kubelet before it can be mounted. Note: Amazon EBS volumes can be mounted to only one instance at a time.", "volumeID": "Unique ID of the persistent disk resource in AWS (Amazon EBS volume). More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore", @@ -224,6 +214,15 @@ func (ContainerStatus) SwaggerDoc() map[string]string { return map_ContainerStatus } +var map_DaemonEndpoint = map[string]string{ + "": "DaemonEndpoint contains information about a single Daemon endpoint.", + "Port": "Port number of the given endpoint.", +} + +func (DaemonEndpoint) SwaggerDoc() map[string]string { + return map_DaemonEndpoint +} + var map_DeleteOptions = map[string]string{ "": "DeleteOptions may be provided when deleting an API object", "gracePeriodSeconds": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", @@ -283,9 +282,10 @@ func (EndpointPort) SwaggerDoc() map[string]string { } var map_EndpointSubset = map[string]string{ - "": "EndpointSubset is a group of addresses with a common set of ports. The expanded set of endpoints is the Cartesian product of Addresses x Ports. For example, given:\n {\n Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n }\nThe resulting set of endpoints can be viewed as:\n a: [ 10.10.1.1:8675, 10.10.2.2:8675 ],\n b: [ 10.10.1.1:309, 10.10.2.2:309 ]", - "addresses": "IP addresses which offer the related ports.", - "ports": "Port numbers available on the related IP addresses.", + "": "EndpointSubset is a group of addresses with a common set of ports. The expanded set of endpoints is the Cartesian product of Addresses x Ports. For example, given:\n {\n Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n }\nThe resulting set of endpoints can be viewed as:\n a: [ 10.10.1.1:8675, 10.10.2.2:8675 ],\n b: [ 10.10.1.1:309, 10.10.2.2:309 ]", + "addresses": "IP addresses which offer the related ports that are marked as ready. These endpoints should be considered safe for load balancers and clients to utilize.", + "notReadyAddresses": "IP addresses which offer the related ports but are not currently marked as ready because they have not yet finished starting, have recently failed a readiness check, or have recently failed a liveness check.", + "ports": "Port numbers available on the related IP addresses.", } func (EndpointSubset) SwaggerDoc() map[string]string { @@ -295,7 +295,7 @@ func (EndpointSubset) SwaggerDoc() map[string]string { var map_Endpoints = map[string]string{ "": "Endpoints is a collection of endpoints that implement the actual service. Example:\n Name: \"mysvc\",\n Subsets: [\n {\n Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n },\n {\n Addresses: [{\"ip\": \"10.10.3.3\"}],\n Ports: [{\"name\": \"a\", \"port\": 93}, {\"name\": \"b\", \"port\": 76}]\n },\n ]", "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "subsets": "The set of all endpoints is the union of all subsets. Sets of addresses and ports that comprise a service.", + "subsets": "The set of all endpoints is the union of all subsets. Addresses are placed into subsets according to the IPs they share. A single address with multiple ports, some of which are ready and some of which are not (because they come from different containers) will result in the address being displayed in different subsets for the different ports. No address will appear in both Addresses and NotReadyAddresses in the same subset. Sets of addresses and ports that comprise a service.", } func (Endpoints) SwaggerDoc() map[string]string { @@ -377,6 +377,27 @@ func (ExecAction) SwaggerDoc() map[string]string { return map_ExecAction } +var map_FCVolumeSource = map[string]string{ + "": "A Fibre Channel Disk can only be mounted as read/write once.", + "targetWWNs": "Required: FC target world wide names (WWNs)", + "lun": "Required: FC target lun number", + "fsType": "Required: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\"", + "readOnly": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.", +} + +func (FCVolumeSource) SwaggerDoc() map[string]string { + return map_FCVolumeSource +} + +var map_FlockerVolumeSource = map[string]string{ + "": "FlockerVolumeSource represents a Flocker volume mounted by the Flocker agent.", + "datasetName": "Required: the volume name. This is going to be store on metadata -> name on the payload for Flocker", +} + +func (FlockerVolumeSource) SwaggerDoc() map[string]string { + return map_FlockerVolumeSource +} + var map_GCEPersistentDiskVolumeSource = map[string]string{ "": "GCEPersistentDiskVolumeSource represents a Persistent Disk resource in Google Compute Engine.\n\nA GCE PD must exist and be formatted before mounting to a container. The disk must also be in the same GCE project and zone as the kubelet. A GCE PD can only be mounted as read/write once.", "pdName": "Unique name of the PD resource in GCE. Used to identify the disk in GCE. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk", @@ -518,16 +539,6 @@ func (List) SwaggerDoc() map[string]string { return map_List } -var map_ListMeta = map[string]string{ - "": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects.", - "selfLink": "SelfLink is a URL representing this object. Populated by the system. Read-only.", - "resourceVersion": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency", -} - -func (ListMeta) SwaggerDoc() map[string]string { - return map_ListMeta -} - var map_ListOptions = map[string]string{ "": "ListOptions is the query options to a standard REST list call.", "labelSelector": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", @@ -653,6 +664,15 @@ func (NodeCondition) SwaggerDoc() map[string]string { return map_NodeCondition } +var map_NodeDaemonEndpoints = map[string]string{ + "": "NodeDaemonEndpoints lists ports opened by daemons running on the Node.", + "kubeletEndpoint": "Endpoint on which Kubelet is listening.", +} + +func (NodeDaemonEndpoints) SwaggerDoc() map[string]string { + return map_NodeDaemonEndpoints +} + var map_NodeList = map[string]string{ "": "NodeList is the whole list of all Nodes which have been registered with master.", "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", @@ -676,12 +696,13 @@ func (NodeSpec) SwaggerDoc() map[string]string { } var map_NodeStatus = map[string]string{ - "": "NodeStatus is information about the current status of a node.", - "capacity": "Capacity represents the available resources of a node. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#capacity for more details.", - "phase": "NodePhase is the recently observed lifecycle phase of the node. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-phase", - "conditions": "Conditions is an array of current observed node conditions. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-condition", - "addresses": "List of addresses reachable to the node. Queried from cloud provider, if available. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-addresses", - "nodeInfo": "NodeSystemInfo is a set of ids/uuids to uniquely identify the node. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-info", + "": "NodeStatus is information about the current status of a node.", + "capacity": "Capacity represents the available resources of a node. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#capacity for more details.", + "phase": "NodePhase is the recently observed lifecycle phase of the node. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-phase", + "conditions": "Conditions is an array of current observed node conditions. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-condition", + "addresses": "List of addresses reachable to the node. Queried from cloud provider, if available. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-addresses", + "daemonEndpoints": "Endpoints of daemons running on the Node.", + "nodeInfo": "Set of ids/uuids to uniquely identify the node. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-info", } func (NodeStatus) SwaggerDoc() map[string]string { @@ -690,14 +711,14 @@ func (NodeStatus) SwaggerDoc() map[string]string { var map_NodeSystemInfo = map[string]string{ "": "NodeSystemInfo is a set of ids/uuids to uniquely identify the node.", - "machineID": "MachineID is the machine-id reported by the node.", - "systemUUID": "SystemUUID is the system-uuid reported by the node.", - "bootID": "BootID is the boot-id reported by the node.", - "kernelVersion": "Kernel version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64)", - "osImage": "OS image used reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy))", - "containerRuntimeVersion": "Container runtime version reported by the node through runtime remote API (e.g. docker://1.5.0)", - "kubeletVersion": "Kubelet version reported by the node.", - "kubeProxyVersion": "Kube-proxy version reported by the node.", + "machineID": "Machine ID reported by the node.", + "systemUUID": "System UUID reported by the node.", + "bootID": "Boot ID reported by the node.", + "kernelVersion": "Kernel Version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64).", + "osImage": "OS Image reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy)).", + "containerRuntimeVersion": "ContainerRuntime Version reported by the node through runtime remote API (e.g. docker://1.5.0).", + "kubeletVersion": "Kubelet Version reported by the node.", + "kubeProxyVersion": "KubeProxy Version reported by the node.", } func (NodeSystemInfo) SwaggerDoc() map[string]string { @@ -827,13 +848,15 @@ var map_PersistentVolumeSource = map[string]string{ "": "PersistentVolumeSource is similar to VolumeSource but meant for the administrator who creates PVs. Exactly one of its members must be set.", "gcePersistentDisk": "GCEPersistentDisk represents a GCE Disk resource that is attached to a kubelet's host machine and then exposed to the pod. Provisioned by an admin. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk", "awsElasticBlockStore": "AWSElasticBlockStore represents an AWS Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore", - "hostPath": "HostPath represents a directory on the host. Provisioned by a developer or tester. This is useful for development and testing only. On-host storage is not supported in any way. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath", + "hostPath": "HostPath represents a directory on the host. Provisioned by a developer or tester. This is useful for single-node development and testing only! On-host storage is not supported in any way and WILL NOT WORK in a multi-node cluster. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath", "glusterfs": "Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod. Provisioned by an admin. More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md", "nfs": "NFS represents an NFS mount on the host. Provisioned by an admin. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs", "rbd": "RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md", "iscsi": "ISCSI represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. Provisioned by an admin.", "cinder": "Cinder represents a cinder volume attached and mounted on kubelets host machine More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md", "cephfs": "CephFS represents a Ceph FS mount on the host that shares a pod's lifetime", + "fc": "FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.", + "flocker": "Flocker represents a Flocker volume attached to a kubelet's host machine and exposed to the pod for its usage. This depends on the Flocker control service being running", } func (PersistentVolumeSource) SwaggerDoc() map[string]string { @@ -888,9 +911,13 @@ func (PodAttachOptions) SwaggerDoc() map[string]string { } var map_PodCondition = map[string]string{ - "": "PodCondition contains details for the current condition of this pod.", - "type": "Type is the type of the condition. Currently only Ready. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions", - "status": "Status is the status of the condition. Can be True, False, Unknown. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions", + "": "PodCondition contains details for the current condition of this pod.", + "type": "Type is the type of the condition. Currently only Ready. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions", + "status": "Status is the status of the condition. Can be True, False, Unknown. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions", + "lastProbeTime": "Last time we probed the condition.", + "lastTransitionTime": "Last time the condition transitioned from one status to another.", + "reason": "Unique, one-word, CamelCase reason for the condition's last transition.", + "message": "Human-readable message indicating details about last transition.", } func (PodCondition) SwaggerDoc() map[string]string { @@ -922,10 +949,15 @@ func (PodList) SwaggerDoc() map[string]string { } var map_PodLogOptions = map[string]string{ - "": "PodLogOptions is the query options for a Pod's logs REST call.", - "container": "The container for which to stream logs. Defaults to only container if there is one container in the pod.", - "follow": "Follow the log stream of the pod. Defaults to false.", - "previous": "Return previous terminated container logs. Defaults to false.", + "": "PodLogOptions is the query options for a Pod's logs REST call.", + "container": "The container for which to stream logs. Defaults to only container if there is one container in the pod.", + "follow": "Follow the log stream of the pod. Defaults to false.", + "previous": "Return previous terminated container logs. Defaults to false.", + "sinceSeconds": "A relative time in seconds before the current time from which to show logs. If this value precedes the time a pod was started, only logs since the pod start will be returned. If this value is in the future, no logs will be returned. Only one of sinceSeconds or sinceTime may be specified.", + "sinceTime": "An RFC3339 timestamp from which to show logs. If this value preceeds the time a pod was started, only logs since the pod start will be returned. If this value is in the future, no logs will be returned. Only one of sinceSeconds or sinceTime may be specified.", + "timestamps": "If true, add an RFC3339 or RFC3339Nano timestamp at the beginning of every line of log output. Defaults to false.", + "tailLines": "If set, the number of lines from the end of the logs to show. If not specified, logs are shown from the creation of the container or sinceSeconds or sinceTime", + "limitBytes": "If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit.", } func (PodLogOptions) SwaggerDoc() map[string]string { @@ -941,6 +973,14 @@ func (PodProxyOptions) SwaggerDoc() map[string]string { return map_PodProxyOptions } +var map_PodSecurityContext = map[string]string{ + "": "PodSecurityContext holds pod-level security attributes and common container settings.", +} + +func (PodSecurityContext) SwaggerDoc() map[string]string { + return map_PodSecurityContext +} + var map_PodSpec = map[string]string{ "": "PodSpec is a description of a pod.", "volumes": "List of volumes that can be mounted by containers belonging to the pod. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md", @@ -956,6 +996,7 @@ var map_PodSpec = map[string]string{ "hostNetwork": "Host networking requested for this pod. Use the host's network namespace. If this option is set, the ports that will be used must be specified. Default to false.", "hostPID": "Use the host's pid namespace. Optional: Default to false.", "hostIPC": "Use the host's ipc namespace. Optional: Default to false.", + "securityContext": "SecurityContext holds pod-level security attributes and common container settings", "imagePullSecrets": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md#specifying-imagepullsecrets-on-a-pod", } @@ -1268,14 +1309,15 @@ func (ServicePort) SwaggerDoc() map[string]string { } var map_ServiceSpec = map[string]string{ - "": "ServiceSpec describes the attributes that a user creates on a service.", - "ports": "The list of ports that are exposed by this service. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies", - "selector": "This service will route traffic to pods having labels matching this selector. Label keys and values that must match in order to receive traffic for this service. If empty, all pods are selected, if not specified, endpoints must be manually specified. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview", - "clusterIP": "ClusterIP is usually assigned by the master and is the IP address of the service. If specified, it will be allocated to the service if it is unused or else creation of the service will fail. Valid values are None, empty string (\"\"), or a valid IP address. 'None' can be specified for a headless service when proxying is not required. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies", - "type": "Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer. Defaults to ClusterIP. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services", - "externalIPs": "ExternalIPs are used by external load balancers, or can be set by users to handle external traffic that arrives at a node. Externally visible IPs (e.g. load balancers) that should be proxied to this service.", - "sessionAffinity": "Supports \"ClientIP\" and \"None\". Used to maintain session affinity. Enable client IP based session affinity. Must be ClientIP or None. Defaults to None. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies", - "loadBalancerIP": "Only applies to Service Type: LoadBalancer LoadBalancer will get created with the IP specified in this field. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature.", + "": "ServiceSpec describes the attributes that a user creates on a service.", + "ports": "The list of ports that are exposed by this service. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies", + "selector": "This service will route traffic to pods having labels matching this selector. Label keys and values that must match in order to receive traffic for this service. If empty, all pods are selected, if not specified, endpoints must be manually specified. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview", + "clusterIP": "ClusterIP is usually assigned by the master and is the IP address of the service. If specified, it will be allocated to the service if it is unused or else creation of the service will fail. Valid values are None, empty string (\"\"), or a valid IP address. 'None' can be specified for a headless service when proxying is not required. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies", + "type": "Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer. Defaults to ClusterIP. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services", + "externalIPs": "externalIPs is a list of IP addresses for which nodes in the cluster will also accept traffic for this service. These IPs are not managed by Kubernetes. The user is responsible for ensuring that traffic arrives at a node with this IP. A common example is external load-balancers that are not part of the Kubernetes system. A previous form of this functionality exists as the deprecatedPublicIPs field. When using this field, callers should also clear the deprecatedPublicIPs field.", + "deprecatedPublicIPs": "deprecatedPublicIPs is deprecated and replaced by the externalIPs field with almost the exact same semantics. This field is retained in the v1 API for compatibility until at least 8/20/2016. It will be removed from any new API revisions. If both deprecatedPublicIPs *and* externalIPs are set, deprecatedPublicIPs is used.", + "sessionAffinity": "Supports \"ClientIP\" and \"None\". Used to maintain session affinity. Enable client IP based session affinity. Must be ClientIP or None. Defaults to None. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies", + "loadBalancerIP": "Only applies to Service Type: LoadBalancer LoadBalancer will get created with the IP specified in this field. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature.", } func (ServiceSpec) SwaggerDoc() map[string]string { @@ -1291,43 +1333,6 @@ func (ServiceStatus) SwaggerDoc() map[string]string { return map_ServiceStatus } -var map_Status = map[string]string{ - "": "Status is a return value for calls that don't return other objects.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "status": "Status of the operation. One of: \"Success\" or \"Failure\". More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "message": "A human-readable description of the status of this operation.", - "reason": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.", - "details": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.", - "code": "Suggested HTTP return code for this status, 0 if not set.", -} - -func (Status) SwaggerDoc() map[string]string { - return map_Status -} - -var map_StatusCause = map[string]string{ - "": "StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.", - "reason": "A machine-readable description of the cause of the error. If this value is empty there is no information available.", - "message": "A human-readable description of the cause of the error. This field may be presented as-is to a reader.", - "field": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"", -} - -func (StatusCause) SwaggerDoc() map[string]string { - return map_StatusCause -} - -var map_StatusDetails = map[string]string{ - "": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.", - "name": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).", - "kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "causes": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.", - "retryAfterSeconds": "If specified, the time in seconds before the operation should be retried.", -} - -func (StatusDetails) SwaggerDoc() map[string]string { - return map_StatusDetails -} - var map_TCPSocketAction = map[string]string{ "": "TCPSocketAction describes an action based on opening a socket", "port": "Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME.", @@ -1337,47 +1342,6 @@ func (TCPSocketAction) SwaggerDoc() map[string]string { return map_TCPSocketAction } -var map_ThirdPartyResource = map[string]string{ - "": "A ThirdPartyResource is a generic representation of a resource, it is used by add-ons and plugins to add new resource types to the API. It consists of one or more Versions of the api.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "description": "The description of this object.", - "versions": "The versions for this third party object.", -} - -func (ThirdPartyResource) SwaggerDoc() map[string]string { - return map_ThirdPartyResource -} - -var map_ThirdPartyResourceData = map[string]string{ - "": "An internal object, used for versioned storage in etcd. Not exposed to the end user.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "name": "The raw JSON data for this data.", -} - -func (ThirdPartyResourceData) SwaggerDoc() map[string]string { - return map_ThirdPartyResourceData -} - -var map_ThirdPartyResourceList = map[string]string{ - "": "ThirdPartyResourceList is a list of ThirdPartyResource.", - "metadata": "Standard list metadata. More info: http://docs.k8s.io/api-conventions.md#metadata", - "items": "Items is a list of schema objects.", -} - -func (ThirdPartyResourceList) SwaggerDoc() map[string]string { - return map_ThirdPartyResourceList -} - -var map_TypeMeta = map[string]string{ - "": "TypeMeta describes an individual object in an API response or request with strings representing the type of the object and its API schema version. Structures that are versioned or persisted should inline TypeMeta.", - "kind": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "apiVersion": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources", -} - -func (TypeMeta) SwaggerDoc() map[string]string { - return map_TypeMeta -} - var map_Volume = map[string]string{ "": "Volume represents a named volume in a pod that may be accessed by any container in the pod.", "name": "Volume's name. Must be a DNS_LABEL and unique within the pod. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names", @@ -1413,7 +1377,9 @@ var map_VolumeSource = map[string]string{ "rbd": "RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md", "cinder": "Cinder represents a cinder volume attached and mounted on kubelets host machine More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md", "cephfs": "CephFS represents a Ceph FS mount on the host that shares a pod's lifetime", + "flocker": "Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running", "downwardAPI": "DownwardAPI represents downward API about the pod that should populate this volume", + "fc": "FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.", } func (VolumeSource) SwaggerDoc() map[string]string { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion.go deleted file mode 100644 index a43eb3170a4e..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion.go +++ /dev/null @@ -1,888 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 v1beta3 - -import ( - "fmt" - "reflect" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/conversion" -) - -func addConversionFuncs() { - // Add non-generated conversion functions - err := api.Scheme.AddConversionFuncs( - convert_v1beta3_Container_To_api_Container, - convert_api_Container_To_v1beta3_Container, - convert_v1beta3_ServiceSpec_To_api_ServiceSpec, - convert_api_ServiceSpec_To_v1beta3_ServiceSpec, - convert_v1beta3_PodSpec_To_api_PodSpec, - convert_api_PodSpec_To_v1beta3_PodSpec, - convert_v1beta3_ContainerState_To_api_ContainerState, - convert_api_ContainerState_To_v1beta3_ContainerState, - convert_api_ContainerStateTerminated_To_v1beta3_ContainerStateTerminated, - convert_v1beta3_ContainerStateTerminated_To_api_ContainerStateTerminated, - convert_v1beta3_StatusDetails_To_api_StatusDetails, - convert_api_StatusDetails_To_v1beta3_StatusDetails, - convert_v1beta3_StatusCause_To_api_StatusCause, - convert_api_StatusCause_To_v1beta3_StatusCause, - convert_api_ReplicationControllerSpec_To_v1beta3_ReplicationControllerSpec, - convert_v1beta3_ReplicationControllerSpec_To_api_ReplicationControllerSpec, - convert_v1beta3_VolumeSource_To_api_VolumeSource, - convert_api_VolumeSource_To_v1beta3_VolumeSource, - ) - if err != nil { - // If one of the conversion functions is malformed, detect it immediately. - panic(err) - } - - // Add field conversion funcs. - err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Pod", - func(label, value string) (string, string, error) { - switch label { - case "metadata.name", - "metadata.namespace", - "metadata.labels", - "metadata.annotations", - "status.podIP", - "status.phase": - return label, value, nil - case "spec.host": - return "spec.nodeName", value, nil - default: - return "", "", fmt.Errorf("field label not supported: %s", label) - } - }) - if err != nil { - // If one of the conversion functions is malformed, detect it immediately. - panic(err) - } - err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Node", - func(label, value string) (string, string, error) { - switch label { - case "metadata.name": - return label, value, nil - case "spec.unschedulable": - return label, value, nil - default: - return "", "", fmt.Errorf("field label not supported: %s", label) - } - }) - if err != nil { - // If one of the conversion functions is malformed, detect it immediately. - panic(err) - } - err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "ReplicationController", - func(label, value string) (string, string, error) { - switch label { - case "metadata.name", - "status.replicas": - return label, value, nil - default: - return "", "", fmt.Errorf("field label not supported: %s", label) - } - }) - if err != nil { - // If one of the conversion functions is malformed, detect it immediately. - panic(err) - } - err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Event", - func(label, value string) (string, string, error) { - switch label { - case "involvedObject.kind", - "involvedObject.namespace", - "involvedObject.name", - "involvedObject.uid", - "involvedObject.apiVersion", - "involvedObject.resourceVersion", - "involvedObject.fieldPath", - "reason", - "source": - return label, value, nil - default: - return "", "", fmt.Errorf("field label not supported: %s", label) - } - }) - if err != nil { - // If one of the conversion functions is malformed, detect it immediately. - panic(err) - } - err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Namespace", - func(label, value string) (string, string, error) { - switch label { - case "status.phase": - return label, value, nil - default: - return "", "", fmt.Errorf("field label not supported: %s", label) - } - }) - if err != nil { - // If one of the conversion functions is malformed, detect it immediately. - panic(err) - } - err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Secret", - func(label, value string) (string, string, error) { - switch label { - case "type": - return label, value, nil - default: - return "", "", fmt.Errorf("field label not supported: %s", label) - } - }) - if err != nil { - // If one of the conversion functions is malformed, detect it immediately. - panic(err) - } - err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "ServiceAccount", - func(label, value string) (string, string, error) { - switch label { - case "metadata.name": - return label, value, nil - default: - return "", "", fmt.Errorf("field label not supported: %s", label) - } - }) - if err != nil { - // If one of the conversion functions is malformed, detect it immediately. - panic(err) - } - err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Endpoints", - func(label, value string) (string, string, error) { - switch label { - case "metadata.name": - return label, value, nil - default: - return "", "", fmt.Errorf("field label not supported: %s", label) - } - }) - if err != nil { - // If one of the conversion functions is malformed, detect it immediately. - panic(err) - } -} - -func convert_v1beta3_Container_To_api_Container(in *Container, out *api.Container, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Container))(in) - } - out.Name = in.Name - out.Image = in.Image - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } - if in.Args != nil { - out.Args = make([]string, len(in.Args)) - for i := range in.Args { - out.Args[i] = in.Args[i] - } - } - out.WorkingDir = in.WorkingDir - if in.Ports != nil { - out.Ports = make([]api.ContainerPort, len(in.Ports)) - for i := range in.Ports { - if err := convert_v1beta3_ContainerPort_To_api_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { - return err - } - } - } - if in.Env != nil { - out.Env = make([]api.EnvVar, len(in.Env)) - for i := range in.Env { - if err := convert_v1beta3_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { - return err - } - } - } - if err := s.Convert(&in.Resources, &out.Resources, 0); err != nil { - return err - } - if in.VolumeMounts != nil { - out.VolumeMounts = make([]api.VolumeMount, len(in.VolumeMounts)) - for i := range in.VolumeMounts { - if err := convert_v1beta3_VolumeMount_To_api_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { - return err - } - } - } - if in.LivenessProbe != nil { - out.LivenessProbe = new(api.Probe) - if err := convert_v1beta3_Probe_To_api_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { - return err - } - } else { - out.LivenessProbe = nil - } - if in.ReadinessProbe != nil { - out.ReadinessProbe = new(api.Probe) - if err := convert_v1beta3_Probe_To_api_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { - return err - } - } else { - out.ReadinessProbe = nil - } - if in.Lifecycle != nil { - out.Lifecycle = new(api.Lifecycle) - if err := convert_v1beta3_Lifecycle_To_api_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { - return err - } - } else { - out.Lifecycle = nil - } - out.TerminationMessagePath = in.TerminationMessagePath - out.ImagePullPolicy = api.PullPolicy(in.ImagePullPolicy) - if in.SecurityContext != nil { - if in.SecurityContext.Capabilities != nil { - if !reflect.DeepEqual(in.SecurityContext.Capabilities.Add, in.Capabilities.Add) || - !reflect.DeepEqual(in.SecurityContext.Capabilities.Drop, in.Capabilities.Drop) { - return fmt.Errorf("container capability settings do not match security context settings, cannot convert") - } - } - if in.SecurityContext.Privileged != nil { - if in.Privileged != *in.SecurityContext.Privileged { - return fmt.Errorf("container privileged settings do not match security context settings, cannot convert") - } - } - } - if in.SecurityContext != nil { - out.SecurityContext = new(api.SecurityContext) - if err := convert_v1beta3_SecurityContext_To_api_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { - return err - } - } else { - out.SecurityContext = nil - } - - out.Stdin = in.Stdin - out.TTY = in.TTY - return nil -} - -func convert_api_Container_To_v1beta3_Container(in *api.Container, out *Container, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Container))(in) - } - out.Name = in.Name - out.Image = in.Image - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } - if in.Args != nil { - out.Args = make([]string, len(in.Args)) - for i := range in.Args { - out.Args[i] = in.Args[i] - } - } - out.WorkingDir = in.WorkingDir - if in.Ports != nil { - out.Ports = make([]ContainerPort, len(in.Ports)) - for i := range in.Ports { - if err := convert_api_ContainerPort_To_v1beta3_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { - return err - } - } - } - if in.Env != nil { - out.Env = make([]EnvVar, len(in.Env)) - for i := range in.Env { - if err := convert_api_EnvVar_To_v1beta3_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { - return err - } - } - } - if err := s.Convert(&in.Resources, &out.Resources, 0); err != nil { - return err - } - if in.VolumeMounts != nil { - out.VolumeMounts = make([]VolumeMount, len(in.VolumeMounts)) - for i := range in.VolumeMounts { - if err := convert_api_VolumeMount_To_v1beta3_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { - return err - } - } - } - if in.LivenessProbe != nil { - out.LivenessProbe = new(Probe) - if err := convert_api_Probe_To_v1beta3_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { - return err - } - } else { - out.LivenessProbe = nil - } - if in.ReadinessProbe != nil { - out.ReadinessProbe = new(Probe) - if err := convert_api_Probe_To_v1beta3_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { - return err - } - } else { - out.ReadinessProbe = nil - } - if in.Lifecycle != nil { - out.Lifecycle = new(Lifecycle) - if err := convert_api_Lifecycle_To_v1beta3_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { - return err - } - } else { - out.Lifecycle = nil - } - out.TerminationMessagePath = in.TerminationMessagePath - out.ImagePullPolicy = PullPolicy(in.ImagePullPolicy) - if in.SecurityContext != nil { - out.SecurityContext = new(SecurityContext) - if err := convert_api_SecurityContext_To_v1beta3_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { - return err - } - } else { - out.SecurityContext = nil - } - // now that we've converted set the container field from security context - if out.SecurityContext != nil && out.SecurityContext.Privileged != nil { - out.Privileged = *out.SecurityContext.Privileged - } - // now that we've converted set the container field from security context - if out.SecurityContext != nil && out.SecurityContext.Capabilities != nil { - out.Capabilities = *out.SecurityContext.Capabilities - } - - out.Stdin = in.Stdin - out.TTY = in.TTY - return nil -} - -func convert_v1beta3_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.ServiceSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ServiceSpec))(in) - } - if in.Ports != nil { - out.Ports = make([]api.ServicePort, len(in.Ports)) - for i := range in.Ports { - if err := convert_v1beta3_ServicePort_To_api_ServicePort(&in.Ports[i], &out.Ports[i], s); err != nil { - return err - } - } - } else { - out.Ports = nil - } - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - out.ClusterIP = in.PortalIP - - typeIn := in.Type - if typeIn == "" { - if in.CreateExternalLoadBalancer { - typeIn = ServiceTypeLoadBalancer - } else { - typeIn = ServiceTypeClusterIP - } - } - if err := s.Convert(&typeIn, &out.Type, 0); err != nil { - return err - } - - if in.PublicIPs != nil { - out.ExternalIPs = make([]string, len(in.PublicIPs)) - for i := range in.PublicIPs { - out.ExternalIPs[i] = in.PublicIPs[i] - } - } else { - out.ExternalIPs = nil - } - out.SessionAffinity = api.ServiceAffinity(in.SessionAffinity) - return nil -} - -func convert_api_ServiceSpec_To_v1beta3_ServiceSpec(in *api.ServiceSpec, out *ServiceSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ServiceSpec))(in) - } - if in.Ports != nil { - out.Ports = make([]ServicePort, len(in.Ports)) - for i := range in.Ports { - if err := convert_api_ServicePort_To_v1beta3_ServicePort(&in.Ports[i], &out.Ports[i], s); err != nil { - return err - } - } - } else { - out.Ports = nil - } - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - out.PortalIP = in.ClusterIP - - if err := s.Convert(&in.Type, &out.Type, 0); err != nil { - return err - } - out.CreateExternalLoadBalancer = in.Type == api.ServiceTypeLoadBalancer - - if in.ExternalIPs != nil { - out.PublicIPs = make([]string, len(in.ExternalIPs)) - for i := range in.ExternalIPs { - out.PublicIPs[i] = in.ExternalIPs[i] - } - } else { - out.PublicIPs = nil - } - out.SessionAffinity = ServiceAffinity(in.SessionAffinity) - return nil -} - -func convert_v1beta3_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PodSpec))(in) - } - if in.Volumes != nil { - out.Volumes = make([]api.Volume, len(in.Volumes)) - for i := range in.Volumes { - if err := convert_v1beta3_Volume_To_api_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil { - return err - } - } - } else { - out.Volumes = nil - } - if in.Containers != nil { - out.Containers = make([]api.Container, len(in.Containers)) - for i := range in.Containers { - if err := convert_v1beta3_Container_To_api_Container(&in.Containers[i], &out.Containers[i], s); err != nil { - return err - } - } - } else { - out.Containers = nil - } - out.RestartPolicy = api.RestartPolicy(in.RestartPolicy) - if in.TerminationGracePeriodSeconds != nil { - out.TerminationGracePeriodSeconds = new(int64) - *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds - } else { - out.TerminationGracePeriodSeconds = nil - } - if in.ActiveDeadlineSeconds != nil { - out.ActiveDeadlineSeconds = new(int64) - *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds - } else { - out.ActiveDeadlineSeconds = nil - } - out.DNSPolicy = api.DNSPolicy(in.DNSPolicy) - if in.NodeSelector != nil { - out.NodeSelector = make(map[string]string) - for key, val := range in.NodeSelector { - out.NodeSelector[key] = val - } - } else { - out.NodeSelector = nil - } - out.ServiceAccountName = in.ServiceAccount - out.NodeName = in.Host - out.HostNetwork = in.HostNetwork - out.HostPID = in.HostPID - out.HostIPC = in.HostIPC - if in.ImagePullSecrets != nil { - out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets)) - for i := range in.ImagePullSecrets { - if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { - return err - } - } - } else { - out.ImagePullSecrets = nil - } - return nil -} - -func convert_api_PodSpec_To_v1beta3_PodSpec(in *api.PodSpec, out *PodSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodSpec))(in) - } - if in.Volumes != nil { - out.Volumes = make([]Volume, len(in.Volumes)) - for i := range in.Volumes { - if err := convert_api_Volume_To_v1beta3_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil { - return err - } - } - } else { - out.Volumes = nil - } - if in.Containers != nil { - out.Containers = make([]Container, len(in.Containers)) - for i := range in.Containers { - if err := convert_api_Container_To_v1beta3_Container(&in.Containers[i], &out.Containers[i], s); err != nil { - return err - } - } - } else { - out.Containers = nil - } - out.RestartPolicy = RestartPolicy(in.RestartPolicy) - if in.TerminationGracePeriodSeconds != nil { - out.TerminationGracePeriodSeconds = new(int64) - *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds - } else { - out.TerminationGracePeriodSeconds = nil - } - if in.ActiveDeadlineSeconds != nil { - out.ActiveDeadlineSeconds = new(int64) - *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds - } else { - out.ActiveDeadlineSeconds = nil - } - out.DNSPolicy = DNSPolicy(in.DNSPolicy) - if in.NodeSelector != nil { - out.NodeSelector = make(map[string]string) - for key, val := range in.NodeSelector { - out.NodeSelector[key] = val - } - } else { - out.NodeSelector = nil - } - out.ServiceAccount = in.ServiceAccountName - out.Host = in.NodeName - out.HostNetwork = in.HostNetwork - out.HostPID = in.HostPID - out.HostIPC = in.HostIPC - if in.ImagePullSecrets != nil { - out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) - for i := range in.ImagePullSecrets { - if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { - return err - } - } - } else { - out.ImagePullSecrets = nil - } - return nil -} - -func convert_api_ContainerState_To_v1beta3_ContainerState(in *api.ContainerState, out *ContainerState, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ContainerState))(in) - } - if in.Waiting != nil { - out.Waiting = new(ContainerStateWaiting) - if err := convert_api_ContainerStateWaiting_To_v1beta3_ContainerStateWaiting(in.Waiting, out.Waiting, s); err != nil { - return err - } - } else { - out.Waiting = nil - } - if in.Running != nil { - out.Running = new(ContainerStateRunning) - if err := convert_api_ContainerStateRunning_To_v1beta3_ContainerStateRunning(in.Running, out.Running, s); err != nil { - return err - } - } else { - out.Running = nil - } - if in.Terminated != nil { - out.Termination = new(ContainerStateTerminated) - if err := convert_api_ContainerStateTerminated_To_v1beta3_ContainerStateTerminated(in.Terminated, out.Termination, s); err != nil { - return err - } - } else { - out.Termination = nil - } - return nil -} - -func convert_v1beta3_ContainerState_To_api_ContainerState(in *ContainerState, out *api.ContainerState, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ContainerState))(in) - } - if in.Waiting != nil { - out.Waiting = new(api.ContainerStateWaiting) - if err := convert_v1beta3_ContainerStateWaiting_To_api_ContainerStateWaiting(in.Waiting, out.Waiting, s); err != nil { - return err - } - } else { - out.Waiting = nil - } - if in.Running != nil { - out.Running = new(api.ContainerStateRunning) - if err := convert_v1beta3_ContainerStateRunning_To_api_ContainerStateRunning(in.Running, out.Running, s); err != nil { - return err - } - } else { - out.Running = nil - } - if in.Termination != nil { - out.Terminated = new(api.ContainerStateTerminated) - if err := convert_v1beta3_ContainerStateTerminated_To_api_ContainerStateTerminated(in.Termination, out.Terminated, s); err != nil { - return err - } - } else { - out.Terminated = nil - } - return nil -} - -func convert_api_ContainerStateTerminated_To_v1beta3_ContainerStateTerminated(in *api.ContainerStateTerminated, out *ContainerStateTerminated, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ContainerStateTerminated))(in) - } - out.ExitCode = in.ExitCode - out.Signal = in.Signal - out.Reason = in.Reason - out.Message = in.Message - if err := s.Convert(&in.StartedAt, &out.StartedAt, 0); err != nil { - return err - } - if err := s.Convert(&in.FinishedAt, &out.FinishedAt, 0); err != nil { - return err - } - out.ContainerID = in.ContainerID - return nil -} - -func convert_v1beta3_ContainerStateTerminated_To_api_ContainerStateTerminated(in *ContainerStateTerminated, out *api.ContainerStateTerminated, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ContainerStateTerminated))(in) - } - out.ExitCode = in.ExitCode - out.Signal = in.Signal - out.Reason = in.Reason - out.Message = in.Message - if err := s.Convert(&in.StartedAt, &out.StartedAt, 0); err != nil { - return err - } - if err := s.Convert(&in.FinishedAt, &out.FinishedAt, 0); err != nil { - return err - } - out.ContainerID = in.ContainerID - return nil -} - -func convert_v1beta3_StatusDetails_To_api_StatusDetails(in *StatusDetails, out *api.StatusDetails, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*StatusDetails))(in) - } - out.Name = in.ID - out.Kind = in.Kind - if in.Causes != nil { - out.Causes = make([]api.StatusCause, len(in.Causes)) - for i := range in.Causes { - if err := convert_v1beta3_StatusCause_To_api_StatusCause(&in.Causes[i], &out.Causes[i], s); err != nil { - return err - } - } - } else { - out.Causes = nil - } - out.RetryAfterSeconds = in.RetryAfterSeconds - return nil -} - -func convert_api_StatusDetails_To_v1beta3_StatusDetails(in *api.StatusDetails, out *StatusDetails, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.StatusDetails))(in) - } - out.ID = in.Name - out.Kind = in.Kind - if in.Causes != nil { - out.Causes = make([]StatusCause, len(in.Causes)) - for i := range in.Causes { - if err := convert_api_StatusCause_To_v1beta3_StatusCause(&in.Causes[i], &out.Causes[i], s); err != nil { - return err - } - } - } else { - out.Causes = nil - } - out.RetryAfterSeconds = in.RetryAfterSeconds - return nil -} - -func convert_v1beta3_StatusCause_To_api_StatusCause(in *StatusCause, out *api.StatusCause, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*StatusCause))(in) - } - out.Type = api.CauseType(in.Type) - out.Message = in.Message - out.Field = in.Field - return nil -} - -func convert_api_StatusCause_To_v1beta3_StatusCause(in *api.StatusCause, out *StatusCause, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.StatusCause))(in) - } - out.Type = CauseType(in.Type) - out.Message = in.Message - out.Field = in.Field - return nil -} - -func convert_api_ReplicationControllerSpec_To_v1beta3_ReplicationControllerSpec(in *api.ReplicationControllerSpec, out *ReplicationControllerSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ReplicationControllerSpec))(in) - } - out.Replicas = &in.Replicas - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - if in.Template != nil { - out.Template = new(PodTemplateSpec) - if err := convert_api_PodTemplateSpec_To_v1beta3_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil - } - return nil -} - -func convert_v1beta3_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *ReplicationControllerSpec, out *api.ReplicationControllerSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ReplicationControllerSpec))(in) - } - out.Replicas = *in.Replicas - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - if in.Template != nil { - out.Template = new(api.PodTemplateSpec) - if err := convert_v1beta3_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil - } - return nil -} - -// This will convert our internal represantation of VolumeSource to its v1beta3 representation -// Used for keeping backwards compatibility for the Metadata field -func convert_api_VolumeSource_To_v1beta3_VolumeSource(in *api.VolumeSource, out *VolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.VolumeSource))(in) - } - - if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { - return err - } - - if in.DownwardAPI != nil { - out.Metadata = new(MetadataVolumeSource) - if err := convert_api_DownwardAPIVolumeSource_To_v1beta3_MetadataVolumeSource(in.DownwardAPI, out.Metadata, s); err != nil { - return err - } - } - return nil -} - -// downward -> metadata (api -> v1beta3) -func convert_api_DownwardAPIVolumeSource_To_v1beta3_MetadataVolumeSource(in *api.DownwardAPIVolumeSource, out *MetadataVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.DownwardAPIVolumeSource))(in) - } - if in.Items != nil { - out.Items = make([]MetadataFile, len(in.Items)) - for i := range in.Items { - if err := convert_api_DownwardAPIVolumeFile_To_v1beta3_MetadataFile(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } - return nil -} - -func convert_api_DownwardAPIVolumeFile_To_v1beta3_MetadataFile(in *api.DownwardAPIVolumeFile, out *MetadataFile, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.DownwardAPIVolumeFile))(in) - } - out.Name = in.Path - if err := convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { - return err - } - return nil -} - -// This will convert the v1beta3 representation of VolumeSource to our internal representation -// Used for keeping backwards compatibility for the Metadata field -func convert_v1beta3_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api.VolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*VolumeSource))(in) - } - - if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { - return err - } - - // if specified Metadata will stomp DownwardAPI - if in.Metadata != nil { - out.DownwardAPI = new(api.DownwardAPIVolumeSource) - if err := convert_v1beta3_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in.Metadata, out.DownwardAPI, s); err != nil { - return err - } - } - return nil -} - -// metadata -> downward (v1beta3 -> api) -func convert_v1beta3_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in *MetadataVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*MetadataVolumeSource))(in) - } - if in.Items != nil { - out.Items = make([]api.DownwardAPIVolumeFile, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_MetadataFile_To_api_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } - return nil -} - -func convert_v1beta3_MetadataFile_To_api_DownwardAPIVolumeFile(in *MetadataFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*MetadataFile))(in) - } - out.Path = in.Name - if err := convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { - return err - } - return nil -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go deleted file mode 100644 index bde01f6ed4d5..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go +++ /dev/null @@ -1,4708 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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. -*/ - -// DO NOT EDIT. THIS FILE IS AUTO-GENERATED BY $KUBEROOT/hack/update-generated-conversions.sh - -package v1beta3 - -import ( - reflect "reflect" - - api "k8s.io/kubernetes/pkg/api" - resource "k8s.io/kubernetes/pkg/api/resource" - conversion "k8s.io/kubernetes/pkg/conversion" -) - -func convert_api_AWSElasticBlockStoreVolumeSource_To_v1beta3_AWSElasticBlockStoreVolumeSource(in *api.AWSElasticBlockStoreVolumeSource, out *AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.AWSElasticBlockStoreVolumeSource))(in) - } - out.VolumeID = in.VolumeID - out.FSType = in.FSType - out.Partition = in.Partition - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_Binding_To_v1beta3_Binding(in *api.Binding, out *Binding, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Binding))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.Target, &out.Target, s); err != nil { - return err - } - return nil -} - -func convert_api_Capabilities_To_v1beta3_Capabilities(in *api.Capabilities, out *Capabilities, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Capabilities))(in) - } - if in.Add != nil { - out.Add = make([]Capability, len(in.Add)) - for i := range in.Add { - out.Add[i] = Capability(in.Add[i]) - } - } else { - out.Add = nil - } - if in.Drop != nil { - out.Drop = make([]Capability, len(in.Drop)) - for i := range in.Drop { - out.Drop[i] = Capability(in.Drop[i]) - } - } else { - out.Drop = nil - } - return nil -} - -func convert_api_CephFSVolumeSource_To_v1beta3_CephFSVolumeSource(in *api.CephFSVolumeSource, out *CephFSVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.CephFSVolumeSource))(in) - } - if in.Monitors != nil { - out.Monitors = make([]string, len(in.Monitors)) - for i := range in.Monitors { - out.Monitors[i] = in.Monitors[i] - } - } else { - out.Monitors = nil - } - out.User = in.User - out.SecretFile = in.SecretFile - if in.SecretRef != nil { - out.SecretRef = new(LocalObjectReference) - if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { - return err - } - } else { - out.SecretRef = nil - } - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_CinderVolumeSource_To_v1beta3_CinderVolumeSource(in *api.CinderVolumeSource, out *CinderVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.CinderVolumeSource))(in) - } - out.VolumeID = in.VolumeID - out.FSType = in.FSType - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_ComponentCondition_To_v1beta3_ComponentCondition(in *api.ComponentCondition, out *ComponentCondition, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ComponentCondition))(in) - } - out.Type = ComponentConditionType(in.Type) - out.Status = ConditionStatus(in.Status) - out.Message = in.Message - out.Error = in.Error - return nil -} - -func convert_api_ComponentStatus_To_v1beta3_ComponentStatus(in *api.ComponentStatus, out *ComponentStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ComponentStatus))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if in.Conditions != nil { - out.Conditions = make([]ComponentCondition, len(in.Conditions)) - for i := range in.Conditions { - if err := convert_api_ComponentCondition_To_v1beta3_ComponentCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { - return err - } - } - } else { - out.Conditions = nil - } - return nil -} - -func convert_api_ComponentStatusList_To_v1beta3_ComponentStatusList(in *api.ComponentStatusList, out *ComponentStatusList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ComponentStatusList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]ComponentStatus, len(in.Items)) - for i := range in.Items { - if err := convert_api_ComponentStatus_To_v1beta3_ComponentStatus(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_ContainerPort_To_v1beta3_ContainerPort(in *api.ContainerPort, out *ContainerPort, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ContainerPort))(in) - } - out.Name = in.Name - out.HostPort = in.HostPort - out.ContainerPort = in.ContainerPort - out.Protocol = Protocol(in.Protocol) - out.HostIP = in.HostIP - return nil -} - -func convert_api_ContainerStateRunning_To_v1beta3_ContainerStateRunning(in *api.ContainerStateRunning, out *ContainerStateRunning, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ContainerStateRunning))(in) - } - if err := s.Convert(&in.StartedAt, &out.StartedAt, 0); err != nil { - return err - } - return nil -} - -func convert_api_ContainerStateWaiting_To_v1beta3_ContainerStateWaiting(in *api.ContainerStateWaiting, out *ContainerStateWaiting, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ContainerStateWaiting))(in) - } - out.Reason = in.Reason - return nil -} - -func convert_api_ContainerStatus_To_v1beta3_ContainerStatus(in *api.ContainerStatus, out *ContainerStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ContainerStatus))(in) - } - out.Name = in.Name - if err := convert_api_ContainerState_To_v1beta3_ContainerState(&in.State, &out.State, s); err != nil { - return err - } - if err := convert_api_ContainerState_To_v1beta3_ContainerState(&in.LastTerminationState, &out.LastTerminationState, s); err != nil { - return err - } - out.Ready = in.Ready - out.RestartCount = in.RestartCount - out.Image = in.Image - out.ImageID = in.ImageID - out.ContainerID = in.ContainerID - return nil -} - -func convert_api_DeleteOptions_To_v1beta3_DeleteOptions(in *api.DeleteOptions, out *DeleteOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.DeleteOptions))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if in.GracePeriodSeconds != nil { - out.GracePeriodSeconds = new(int64) - *out.GracePeriodSeconds = *in.GracePeriodSeconds - } else { - out.GracePeriodSeconds = nil - } - return nil -} - -func convert_api_DownwardAPIVolumeFile_To_v1beta3_DownwardAPIVolumeFile(in *api.DownwardAPIVolumeFile, out *DownwardAPIVolumeFile, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.DownwardAPIVolumeFile))(in) - } - out.Path = in.Path - if err := convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { - return err - } - return nil -} - -func convert_api_DownwardAPIVolumeSource_To_v1beta3_DownwardAPIVolumeSource(in *api.DownwardAPIVolumeSource, out *DownwardAPIVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.DownwardAPIVolumeSource))(in) - } - if in.Items != nil { - out.Items = make([]DownwardAPIVolumeFile, len(in.Items)) - for i := range in.Items { - if err := convert_api_DownwardAPIVolumeFile_To_v1beta3_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_EmptyDirVolumeSource_To_v1beta3_EmptyDirVolumeSource(in *api.EmptyDirVolumeSource, out *EmptyDirVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EmptyDirVolumeSource))(in) - } - out.Medium = StorageMedium(in.Medium) - return nil -} - -func convert_api_EndpointAddress_To_v1beta3_EndpointAddress(in *api.EndpointAddress, out *EndpointAddress, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EndpointAddress))(in) - } - out.IP = in.IP - if in.TargetRef != nil { - out.TargetRef = new(ObjectReference) - if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(in.TargetRef, out.TargetRef, s); err != nil { - return err - } - } else { - out.TargetRef = nil - } - return nil -} - -func convert_api_EndpointPort_To_v1beta3_EndpointPort(in *api.EndpointPort, out *EndpointPort, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EndpointPort))(in) - } - out.Name = in.Name - out.Port = in.Port - out.Protocol = Protocol(in.Protocol) - return nil -} - -func convert_api_EndpointSubset_To_v1beta3_EndpointSubset(in *api.EndpointSubset, out *EndpointSubset, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EndpointSubset))(in) - } - if in.Addresses != nil { - out.Addresses = make([]EndpointAddress, len(in.Addresses)) - for i := range in.Addresses { - if err := convert_api_EndpointAddress_To_v1beta3_EndpointAddress(&in.Addresses[i], &out.Addresses[i], s); err != nil { - return err - } - } - } else { - out.Addresses = nil - } - if in.Ports != nil { - out.Ports = make([]EndpointPort, len(in.Ports)) - for i := range in.Ports { - if err := convert_api_EndpointPort_To_v1beta3_EndpointPort(&in.Ports[i], &out.Ports[i], s); err != nil { - return err - } - } - } else { - out.Ports = nil - } - return nil -} - -func convert_api_Endpoints_To_v1beta3_Endpoints(in *api.Endpoints, out *Endpoints, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Endpoints))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if in.Subsets != nil { - out.Subsets = make([]EndpointSubset, len(in.Subsets)) - for i := range in.Subsets { - if err := convert_api_EndpointSubset_To_v1beta3_EndpointSubset(&in.Subsets[i], &out.Subsets[i], s); err != nil { - return err - } - } - } else { - out.Subsets = nil - } - return nil -} - -func convert_api_EndpointsList_To_v1beta3_EndpointsList(in *api.EndpointsList, out *EndpointsList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EndpointsList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Endpoints, len(in.Items)) - for i := range in.Items { - if err := convert_api_Endpoints_To_v1beta3_Endpoints(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_EnvVar_To_v1beta3_EnvVar(in *api.EnvVar, out *EnvVar, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EnvVar))(in) - } - out.Name = in.Name - out.Value = in.Value - if in.ValueFrom != nil { - out.ValueFrom = new(EnvVarSource) - if err := convert_api_EnvVarSource_To_v1beta3_EnvVarSource(in.ValueFrom, out.ValueFrom, s); err != nil { - return err - } - } else { - out.ValueFrom = nil - } - return nil -} - -func convert_api_EnvVarSource_To_v1beta3_EnvVarSource(in *api.EnvVarSource, out *EnvVarSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EnvVarSource))(in) - } - if in.FieldRef != nil { - out.FieldRef = new(ObjectFieldSelector) - if err := convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(in.FieldRef, out.FieldRef, s); err != nil { - return err - } - } else { - out.FieldRef = nil - } - return nil -} - -func convert_api_Event_To_v1beta3_Event(in *api.Event, out *Event, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Event))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.InvolvedObject, &out.InvolvedObject, s); err != nil { - return err - } - out.Reason = in.Reason - out.Message = in.Message - if err := convert_api_EventSource_To_v1beta3_EventSource(&in.Source, &out.Source, s); err != nil { - return err - } - if err := s.Convert(&in.FirstTimestamp, &out.FirstTimestamp, 0); err != nil { - return err - } - if err := s.Convert(&in.LastTimestamp, &out.LastTimestamp, 0); err != nil { - return err - } - out.Count = in.Count - return nil -} - -func convert_api_EventList_To_v1beta3_EventList(in *api.EventList, out *EventList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EventList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Event, len(in.Items)) - for i := range in.Items { - if err := convert_api_Event_To_v1beta3_Event(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_EventSource_To_v1beta3_EventSource(in *api.EventSource, out *EventSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EventSource))(in) - } - out.Component = in.Component - out.Host = in.Host - return nil -} - -func convert_api_ExecAction_To_v1beta3_ExecAction(in *api.ExecAction, out *ExecAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ExecAction))(in) - } - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } else { - out.Command = nil - } - return nil -} - -func convert_api_GCEPersistentDiskVolumeSource_To_v1beta3_GCEPersistentDiskVolumeSource(in *api.GCEPersistentDiskVolumeSource, out *GCEPersistentDiskVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.GCEPersistentDiskVolumeSource))(in) - } - out.PDName = in.PDName - out.FSType = in.FSType - out.Partition = in.Partition - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_GitRepoVolumeSource_To_v1beta3_GitRepoVolumeSource(in *api.GitRepoVolumeSource, out *GitRepoVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.GitRepoVolumeSource))(in) - } - out.Repository = in.Repository - out.Revision = in.Revision - return nil -} - -func convert_api_GlusterfsVolumeSource_To_v1beta3_GlusterfsVolumeSource(in *api.GlusterfsVolumeSource, out *GlusterfsVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.GlusterfsVolumeSource))(in) - } - out.EndpointsName = in.EndpointsName - out.Path = in.Path - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_HTTPGetAction_To_v1beta3_HTTPGetAction(in *api.HTTPGetAction, out *HTTPGetAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.HTTPGetAction))(in) - } - out.Path = in.Path - if err := s.Convert(&in.Port, &out.Port, 0); err != nil { - return err - } - out.Host = in.Host - out.Scheme = URIScheme(in.Scheme) - return nil -} - -func convert_api_Handler_To_v1beta3_Handler(in *api.Handler, out *Handler, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Handler))(in) - } - if in.Exec != nil { - out.Exec = new(ExecAction) - if err := convert_api_ExecAction_To_v1beta3_ExecAction(in.Exec, out.Exec, s); err != nil { - return err - } - } else { - out.Exec = nil - } - if in.HTTPGet != nil { - out.HTTPGet = new(HTTPGetAction) - if err := convert_api_HTTPGetAction_To_v1beta3_HTTPGetAction(in.HTTPGet, out.HTTPGet, s); err != nil { - return err - } - } else { - out.HTTPGet = nil - } - if in.TCPSocket != nil { - out.TCPSocket = new(TCPSocketAction) - if err := convert_api_TCPSocketAction_To_v1beta3_TCPSocketAction(in.TCPSocket, out.TCPSocket, s); err != nil { - return err - } - } else { - out.TCPSocket = nil - } - return nil -} - -func convert_api_HostPathVolumeSource_To_v1beta3_HostPathVolumeSource(in *api.HostPathVolumeSource, out *HostPathVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.HostPathVolumeSource))(in) - } - out.Path = in.Path - return nil -} - -func convert_api_ISCSIVolumeSource_To_v1beta3_ISCSIVolumeSource(in *api.ISCSIVolumeSource, out *ISCSIVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ISCSIVolumeSource))(in) - } - out.TargetPortal = in.TargetPortal - out.IQN = in.IQN - out.Lun = in.Lun - out.FSType = in.FSType - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_Lifecycle_To_v1beta3_Lifecycle(in *api.Lifecycle, out *Lifecycle, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Lifecycle))(in) - } - if in.PostStart != nil { - out.PostStart = new(Handler) - if err := convert_api_Handler_To_v1beta3_Handler(in.PostStart, out.PostStart, s); err != nil { - return err - } - } else { - out.PostStart = nil - } - if in.PreStop != nil { - out.PreStop = new(Handler) - if err := convert_api_Handler_To_v1beta3_Handler(in.PreStop, out.PreStop, s); err != nil { - return err - } - } else { - out.PreStop = nil - } - return nil -} - -func convert_api_LimitRange_To_v1beta3_LimitRange(in *api.LimitRange, out *LimitRange, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.LimitRange))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_LimitRangeSpec_To_v1beta3_LimitRangeSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - return nil -} - -func convert_api_LimitRangeItem_To_v1beta3_LimitRangeItem(in *api.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.LimitRangeItem))(in) - } - out.Type = LimitType(in.Type) - if in.Max != nil { - out.Max = make(ResourceList) - for key, val := range in.Max { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Max[ResourceName(key)] = newVal - } - } else { - out.Max = nil - } - if in.Min != nil { - out.Min = make(ResourceList) - for key, val := range in.Min { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Min[ResourceName(key)] = newVal - } - } else { - out.Min = nil - } - if in.Default != nil { - out.Default = make(ResourceList) - for key, val := range in.Default { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Default[ResourceName(key)] = newVal - } - } else { - out.Default = nil - } - if in.DefaultRequest != nil { - out.DefaultRequest = make(ResourceList) - for key, val := range in.DefaultRequest { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.DefaultRequest[ResourceName(key)] = newVal - } - } else { - out.DefaultRequest = nil - } - if in.MaxLimitRequestRatio != nil { - out.MaxLimitRequestRatio = make(ResourceList) - for key, val := range in.MaxLimitRequestRatio { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.MaxLimitRequestRatio[ResourceName(key)] = newVal - } - } else { - out.MaxLimitRequestRatio = nil - } - return nil -} - -func convert_api_LimitRangeList_To_v1beta3_LimitRangeList(in *api.LimitRangeList, out *LimitRangeList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.LimitRangeList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]LimitRange, len(in.Items)) - for i := range in.Items { - if err := convert_api_LimitRange_To_v1beta3_LimitRange(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_LimitRangeSpec_To_v1beta3_LimitRangeSpec(in *api.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.LimitRangeSpec))(in) - } - if in.Limits != nil { - out.Limits = make([]LimitRangeItem, len(in.Limits)) - for i := range in.Limits { - if err := convert_api_LimitRangeItem_To_v1beta3_LimitRangeItem(&in.Limits[i], &out.Limits[i], s); err != nil { - return err - } - } - } else { - out.Limits = nil - } - return nil -} - -func convert_api_List_To_v1beta3_List(in *api.List, out *List, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.List))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if err := s.Convert(&in.Items, &out.Items, 0); err != nil { - return err - } - return nil -} - -func convert_api_ListMeta_To_v1beta3_ListMeta(in *api.ListMeta, out *ListMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ListMeta))(in) - } - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil -} - -func convert_api_ListOptions_To_v1beta3_ListOptions(in *api.ListOptions, out *ListOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ListOptions))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := s.Convert(&in.LabelSelector, &out.LabelSelector, 0); err != nil { - return err - } - if err := s.Convert(&in.FieldSelector, &out.FieldSelector, 0); err != nil { - return err - } - out.Watch = in.Watch - out.ResourceVersion = in.ResourceVersion - return nil -} - -func convert_api_LoadBalancerIngress_To_v1beta3_LoadBalancerIngress(in *api.LoadBalancerIngress, out *LoadBalancerIngress, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.LoadBalancerIngress))(in) - } - out.IP = in.IP - out.Hostname = in.Hostname - return nil -} - -func convert_api_LoadBalancerStatus_To_v1beta3_LoadBalancerStatus(in *api.LoadBalancerStatus, out *LoadBalancerStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.LoadBalancerStatus))(in) - } - if in.Ingress != nil { - out.Ingress = make([]LoadBalancerIngress, len(in.Ingress)) - for i := range in.Ingress { - if err := convert_api_LoadBalancerIngress_To_v1beta3_LoadBalancerIngress(&in.Ingress[i], &out.Ingress[i], s); err != nil { - return err - } - } - } else { - out.Ingress = nil - } - return nil -} - -func convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in *api.LocalObjectReference, out *LocalObjectReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.LocalObjectReference))(in) - } - out.Name = in.Name - return nil -} - -func convert_api_NFSVolumeSource_To_v1beta3_NFSVolumeSource(in *api.NFSVolumeSource, out *NFSVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.NFSVolumeSource))(in) - } - out.Server = in.Server - out.Path = in.Path - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_Namespace_To_v1beta3_Namespace(in *api.Namespace, out *Namespace, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Namespace))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_NamespaceSpec_To_v1beta3_NamespaceSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_api_NamespaceStatus_To_v1beta3_NamespaceStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_api_NamespaceList_To_v1beta3_NamespaceList(in *api.NamespaceList, out *NamespaceList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.NamespaceList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Namespace, len(in.Items)) - for i := range in.Items { - if err := convert_api_Namespace_To_v1beta3_Namespace(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_NamespaceSpec_To_v1beta3_NamespaceSpec(in *api.NamespaceSpec, out *NamespaceSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.NamespaceSpec))(in) - } - if in.Finalizers != nil { - out.Finalizers = make([]FinalizerName, len(in.Finalizers)) - for i := range in.Finalizers { - out.Finalizers[i] = FinalizerName(in.Finalizers[i]) - } - } else { - out.Finalizers = nil - } - return nil -} - -func convert_api_NamespaceStatus_To_v1beta3_NamespaceStatus(in *api.NamespaceStatus, out *NamespaceStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.NamespaceStatus))(in) - } - out.Phase = NamespacePhase(in.Phase) - return nil -} - -func convert_api_Node_To_v1beta3_Node(in *api.Node, out *Node, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Node))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_NodeSpec_To_v1beta3_NodeSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_api_NodeStatus_To_v1beta3_NodeStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_api_NodeAddress_To_v1beta3_NodeAddress(in *api.NodeAddress, out *NodeAddress, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.NodeAddress))(in) - } - out.Type = NodeAddressType(in.Type) - out.Address = in.Address - return nil -} - -func convert_api_NodeCondition_To_v1beta3_NodeCondition(in *api.NodeCondition, out *NodeCondition, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.NodeCondition))(in) - } - out.Type = NodeConditionType(in.Type) - out.Status = ConditionStatus(in.Status) - if err := s.Convert(&in.LastHeartbeatTime, &out.LastHeartbeatTime, 0); err != nil { - return err - } - if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { - return err - } - out.Reason = in.Reason - out.Message = in.Message - return nil -} - -func convert_api_NodeList_To_v1beta3_NodeList(in *api.NodeList, out *NodeList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.NodeList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Node, len(in.Items)) - for i := range in.Items { - if err := convert_api_Node_To_v1beta3_Node(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_NodeSpec_To_v1beta3_NodeSpec(in *api.NodeSpec, out *NodeSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.NodeSpec))(in) - } - out.PodCIDR = in.PodCIDR - out.ExternalID = in.ExternalID - out.ProviderID = in.ProviderID - out.Unschedulable = in.Unschedulable - return nil -} - -func convert_api_NodeStatus_To_v1beta3_NodeStatus(in *api.NodeStatus, out *NodeStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.NodeStatus))(in) - } - if in.Capacity != nil { - out.Capacity = make(ResourceList) - for key, val := range in.Capacity { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Capacity[ResourceName(key)] = newVal - } - } else { - out.Capacity = nil - } - out.Phase = NodePhase(in.Phase) - if in.Conditions != nil { - out.Conditions = make([]NodeCondition, len(in.Conditions)) - for i := range in.Conditions { - if err := convert_api_NodeCondition_To_v1beta3_NodeCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { - return err - } - } - } else { - out.Conditions = nil - } - if in.Addresses != nil { - out.Addresses = make([]NodeAddress, len(in.Addresses)) - for i := range in.Addresses { - if err := convert_api_NodeAddress_To_v1beta3_NodeAddress(&in.Addresses[i], &out.Addresses[i], s); err != nil { - return err - } - } - } else { - out.Addresses = nil - } - if err := convert_api_NodeSystemInfo_To_v1beta3_NodeSystemInfo(&in.NodeInfo, &out.NodeInfo, s); err != nil { - return err - } - return nil -} - -func convert_api_NodeSystemInfo_To_v1beta3_NodeSystemInfo(in *api.NodeSystemInfo, out *NodeSystemInfo, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.NodeSystemInfo))(in) - } - out.MachineID = in.MachineID - out.SystemUUID = in.SystemUUID - out.BootID = in.BootID - out.KernelVersion = in.KernelVersion - out.OsImage = in.OsImage - out.ContainerRuntimeVersion = in.ContainerRuntimeVersion - out.KubeletVersion = in.KubeletVersion - out.KubeProxyVersion = in.KubeProxyVersion - return nil -} - -func convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(in *api.ObjectFieldSelector, out *ObjectFieldSelector, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ObjectFieldSelector))(in) - } - out.APIVersion = in.APIVersion - out.FieldPath = in.FieldPath - return nil -} - -func convert_api_ObjectMeta_To_v1beta3_ObjectMeta(in *api.ObjectMeta, out *ObjectMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ObjectMeta))(in) - } - out.Name = in.Name - out.GenerateName = in.GenerateName - out.Namespace = in.Namespace - out.SelfLink = in.SelfLink - out.UID = in.UID - out.ResourceVersion = in.ResourceVersion - out.Generation = in.Generation - if err := s.Convert(&in.CreationTimestamp, &out.CreationTimestamp, 0); err != nil { - return err - } - if in.DeletionTimestamp != nil { - if err := s.Convert(&in.DeletionTimestamp, &out.DeletionTimestamp, 0); err != nil { - return err - } - } else { - out.DeletionTimestamp = nil - } - if in.DeletionGracePeriodSeconds != nil { - out.DeletionGracePeriodSeconds = new(int64) - *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds - } else { - out.DeletionGracePeriodSeconds = nil - } - if in.Labels != nil { - out.Labels = make(map[string]string) - for key, val := range in.Labels { - out.Labels[key] = val - } - } else { - out.Labels = nil - } - if in.Annotations != nil { - out.Annotations = make(map[string]string) - for key, val := range in.Annotations { - out.Annotations[key] = val - } - } else { - out.Annotations = nil - } - return nil -} - -func convert_api_ObjectReference_To_v1beta3_ObjectReference(in *api.ObjectReference, out *ObjectReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ObjectReference))(in) - } - out.Kind = in.Kind - out.Namespace = in.Namespace - out.Name = in.Name - out.UID = in.UID - out.APIVersion = in.APIVersion - out.ResourceVersion = in.ResourceVersion - out.FieldPath = in.FieldPath - return nil -} - -func convert_api_PersistentVolume_To_v1beta3_PersistentVolume(in *api.PersistentVolume, out *PersistentVolume, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PersistentVolume))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_PersistentVolumeSpec_To_v1beta3_PersistentVolumeSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_api_PersistentVolumeStatus_To_v1beta3_PersistentVolumeStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_api_PersistentVolumeClaim_To_v1beta3_PersistentVolumeClaim(in *api.PersistentVolumeClaim, out *PersistentVolumeClaim, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PersistentVolumeClaim))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_PersistentVolumeClaimSpec_To_v1beta3_PersistentVolumeClaimSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_api_PersistentVolumeClaimStatus_To_v1beta3_PersistentVolumeClaimStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_api_PersistentVolumeClaimList_To_v1beta3_PersistentVolumeClaimList(in *api.PersistentVolumeClaimList, out *PersistentVolumeClaimList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PersistentVolumeClaimList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]PersistentVolumeClaim, len(in.Items)) - for i := range in.Items { - if err := convert_api_PersistentVolumeClaim_To_v1beta3_PersistentVolumeClaim(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_PersistentVolumeClaimSpec_To_v1beta3_PersistentVolumeClaimSpec(in *api.PersistentVolumeClaimSpec, out *PersistentVolumeClaimSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PersistentVolumeClaimSpec))(in) - } - if in.AccessModes != nil { - out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) - for i := range in.AccessModes { - out.AccessModes[i] = PersistentVolumeAccessMode(in.AccessModes[i]) - } - } else { - out.AccessModes = nil - } - if err := convert_api_ResourceRequirements_To_v1beta3_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { - return err - } - out.VolumeName = in.VolumeName - return nil -} - -func convert_api_PersistentVolumeClaimStatus_To_v1beta3_PersistentVolumeClaimStatus(in *api.PersistentVolumeClaimStatus, out *PersistentVolumeClaimStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PersistentVolumeClaimStatus))(in) - } - out.Phase = PersistentVolumeClaimPhase(in.Phase) - if in.AccessModes != nil { - out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) - for i := range in.AccessModes { - out.AccessModes[i] = PersistentVolumeAccessMode(in.AccessModes[i]) - } - } else { - out.AccessModes = nil - } - if in.Capacity != nil { - out.Capacity = make(ResourceList) - for key, val := range in.Capacity { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Capacity[ResourceName(key)] = newVal - } - } else { - out.Capacity = nil - } - return nil -} - -func convert_api_PersistentVolumeClaimVolumeSource_To_v1beta3_PersistentVolumeClaimVolumeSource(in *api.PersistentVolumeClaimVolumeSource, out *PersistentVolumeClaimVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PersistentVolumeClaimVolumeSource))(in) - } - out.ClaimName = in.ClaimName - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_PersistentVolumeList_To_v1beta3_PersistentVolumeList(in *api.PersistentVolumeList, out *PersistentVolumeList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PersistentVolumeList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]PersistentVolume, len(in.Items)) - for i := range in.Items { - if err := convert_api_PersistentVolume_To_v1beta3_PersistentVolume(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_PersistentVolumeSource_To_v1beta3_PersistentVolumeSource(in *api.PersistentVolumeSource, out *PersistentVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PersistentVolumeSource))(in) - } - if in.GCEPersistentDisk != nil { - out.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) - if err := convert_api_GCEPersistentDiskVolumeSource_To_v1beta3_GCEPersistentDiskVolumeSource(in.GCEPersistentDisk, out.GCEPersistentDisk, s); err != nil { - return err - } - } else { - out.GCEPersistentDisk = nil - } - if in.AWSElasticBlockStore != nil { - out.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) - if err := convert_api_AWSElasticBlockStoreVolumeSource_To_v1beta3_AWSElasticBlockStoreVolumeSource(in.AWSElasticBlockStore, out.AWSElasticBlockStore, s); err != nil { - return err - } - } else { - out.AWSElasticBlockStore = nil - } - if in.HostPath != nil { - out.HostPath = new(HostPathVolumeSource) - if err := convert_api_HostPathVolumeSource_To_v1beta3_HostPathVolumeSource(in.HostPath, out.HostPath, s); err != nil { - return err - } - } else { - out.HostPath = nil - } - if in.Glusterfs != nil { - out.Glusterfs = new(GlusterfsVolumeSource) - if err := convert_api_GlusterfsVolumeSource_To_v1beta3_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { - return err - } - } else { - out.Glusterfs = nil - } - if in.NFS != nil { - out.NFS = new(NFSVolumeSource) - if err := convert_api_NFSVolumeSource_To_v1beta3_NFSVolumeSource(in.NFS, out.NFS, s); err != nil { - return err - } - } else { - out.NFS = nil - } - if in.RBD != nil { - out.RBD = new(RBDVolumeSource) - if err := convert_api_RBDVolumeSource_To_v1beta3_RBDVolumeSource(in.RBD, out.RBD, s); err != nil { - return err - } - } else { - out.RBD = nil - } - if in.ISCSI != nil { - out.ISCSI = new(ISCSIVolumeSource) - if err := convert_api_ISCSIVolumeSource_To_v1beta3_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { - return err - } - } else { - out.ISCSI = nil - } - if in.Cinder != nil { - out.Cinder = new(CinderVolumeSource) - if err := convert_api_CinderVolumeSource_To_v1beta3_CinderVolumeSource(in.Cinder, out.Cinder, s); err != nil { - return err - } - } else { - out.Cinder = nil - } - if in.CephFS != nil { - out.CephFS = new(CephFSVolumeSource) - if err := convert_api_CephFSVolumeSource_To_v1beta3_CephFSVolumeSource(in.CephFS, out.CephFS, s); err != nil { - return err - } - } else { - out.CephFS = nil - } - return nil -} - -func convert_api_PersistentVolumeSpec_To_v1beta3_PersistentVolumeSpec(in *api.PersistentVolumeSpec, out *PersistentVolumeSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PersistentVolumeSpec))(in) - } - if in.Capacity != nil { - out.Capacity = make(ResourceList) - for key, val := range in.Capacity { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Capacity[ResourceName(key)] = newVal - } - } else { - out.Capacity = nil - } - if err := convert_api_PersistentVolumeSource_To_v1beta3_PersistentVolumeSource(&in.PersistentVolumeSource, &out.PersistentVolumeSource, s); err != nil { - return err - } - if in.AccessModes != nil { - out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) - for i := range in.AccessModes { - out.AccessModes[i] = PersistentVolumeAccessMode(in.AccessModes[i]) - } - } else { - out.AccessModes = nil - } - if in.ClaimRef != nil { - out.ClaimRef = new(ObjectReference) - if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(in.ClaimRef, out.ClaimRef, s); err != nil { - return err - } - } else { - out.ClaimRef = nil - } - out.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimPolicy(in.PersistentVolumeReclaimPolicy) - return nil -} - -func convert_api_PersistentVolumeStatus_To_v1beta3_PersistentVolumeStatus(in *api.PersistentVolumeStatus, out *PersistentVolumeStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PersistentVolumeStatus))(in) - } - out.Phase = PersistentVolumePhase(in.Phase) - out.Message = in.Message - out.Reason = in.Reason - return nil -} - -func convert_api_Pod_To_v1beta3_Pod(in *api.Pod, out *Pod, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Pod))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_PodSpec_To_v1beta3_PodSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_api_PodStatus_To_v1beta3_PodStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_api_PodCondition_To_v1beta3_PodCondition(in *api.PodCondition, out *PodCondition, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodCondition))(in) - } - out.Type = PodConditionType(in.Type) - out.Status = ConditionStatus(in.Status) - return nil -} - -func convert_api_PodExecOptions_To_v1beta3_PodExecOptions(in *api.PodExecOptions, out *PodExecOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodExecOptions))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - out.Stdin = in.Stdin - out.Stdout = in.Stdout - out.Stderr = in.Stderr - out.TTY = in.TTY - out.Container = in.Container - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } else { - out.Command = nil - } - return nil -} - -func convert_api_PodList_To_v1beta3_PodList(in *api.PodList, out *PodList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Pod, len(in.Items)) - for i := range in.Items { - if err := convert_api_Pod_To_v1beta3_Pod(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_PodLogOptions_To_v1beta3_PodLogOptions(in *api.PodLogOptions, out *PodLogOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodLogOptions))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - out.Container = in.Container - out.Follow = in.Follow - out.Previous = in.Previous - return nil -} - -func convert_api_PodProxyOptions_To_v1beta3_PodProxyOptions(in *api.PodProxyOptions, out *PodProxyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodProxyOptions))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - out.Path = in.Path - return nil -} - -func convert_api_PodStatus_To_v1beta3_PodStatus(in *api.PodStatus, out *PodStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodStatus))(in) - } - out.Phase = PodPhase(in.Phase) - if in.Conditions != nil { - out.Conditions = make([]PodCondition, len(in.Conditions)) - for i := range in.Conditions { - if err := convert_api_PodCondition_To_v1beta3_PodCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { - return err - } - } - } else { - out.Conditions = nil - } - out.Message = in.Message - out.Reason = in.Reason - out.HostIP = in.HostIP - out.PodIP = in.PodIP - if in.StartTime != nil { - if err := s.Convert(&in.StartTime, &out.StartTime, 0); err != nil { - return err - } - } else { - out.StartTime = nil - } - if in.ContainerStatuses != nil { - out.ContainerStatuses = make([]ContainerStatus, len(in.ContainerStatuses)) - for i := range in.ContainerStatuses { - if err := convert_api_ContainerStatus_To_v1beta3_ContainerStatus(&in.ContainerStatuses[i], &out.ContainerStatuses[i], s); err != nil { - return err - } - } - } else { - out.ContainerStatuses = nil - } - return nil -} - -func convert_api_PodStatusResult_To_v1beta3_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodStatusResult))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_PodStatus_To_v1beta3_PodStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_api_PodTemplate_To_v1beta3_PodTemplate(in *api.PodTemplate, out *PodTemplate, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodTemplate))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_PodTemplateSpec_To_v1beta3_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { - return err - } - return nil -} - -func convert_api_PodTemplateList_To_v1beta3_PodTemplateList(in *api.PodTemplateList, out *PodTemplateList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodTemplateList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]PodTemplate, len(in.Items)) - for i := range in.Items { - if err := convert_api_PodTemplate_To_v1beta3_PodTemplate(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_PodTemplateSpec_To_v1beta3_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodTemplateSpec))(in) - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_PodSpec_To_v1beta3_PodSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - return nil -} - -func convert_api_Probe_To_v1beta3_Probe(in *api.Probe, out *Probe, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Probe))(in) - } - if err := convert_api_Handler_To_v1beta3_Handler(&in.Handler, &out.Handler, s); err != nil { - return err - } - out.InitialDelaySeconds = in.InitialDelaySeconds - out.TimeoutSeconds = in.TimeoutSeconds - return nil -} - -func convert_api_RBDVolumeSource_To_v1beta3_RBDVolumeSource(in *api.RBDVolumeSource, out *RBDVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.RBDVolumeSource))(in) - } - if in.CephMonitors != nil { - out.CephMonitors = make([]string, len(in.CephMonitors)) - for i := range in.CephMonitors { - out.CephMonitors[i] = in.CephMonitors[i] - } - } else { - out.CephMonitors = nil - } - out.RBDImage = in.RBDImage - out.FSType = in.FSType - out.RBDPool = in.RBDPool - out.RadosUser = in.RadosUser - out.Keyring = in.Keyring - if in.SecretRef != nil { - out.SecretRef = new(LocalObjectReference) - if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { - return err - } - } else { - out.SecretRef = nil - } - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_RangeAllocation_To_v1beta3_RangeAllocation(in *api.RangeAllocation, out *RangeAllocation, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.RangeAllocation))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - out.Range = in.Range - if err := s.Convert(&in.Data, &out.Data, 0); err != nil { - return err - } - return nil -} - -func convert_api_ReplicationController_To_v1beta3_ReplicationController(in *api.ReplicationController, out *ReplicationController, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ReplicationController))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_ReplicationControllerSpec_To_v1beta3_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_api_ReplicationControllerStatus_To_v1beta3_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_api_ReplicationControllerList_To_v1beta3_ReplicationControllerList(in *api.ReplicationControllerList, out *ReplicationControllerList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ReplicationControllerList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]ReplicationController, len(in.Items)) - for i := range in.Items { - if err := convert_api_ReplicationController_To_v1beta3_ReplicationController(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_ReplicationControllerStatus_To_v1beta3_ReplicationControllerStatus(in *api.ReplicationControllerStatus, out *ReplicationControllerStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ReplicationControllerStatus))(in) - } - out.Replicas = in.Replicas - out.ObservedGeneration = in.ObservedGeneration - return nil -} - -func convert_api_ResourceQuota_To_v1beta3_ResourceQuota(in *api.ResourceQuota, out *ResourceQuota, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ResourceQuota))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_ResourceQuotaSpec_To_v1beta3_ResourceQuotaSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_api_ResourceQuotaStatus_To_v1beta3_ResourceQuotaStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_api_ResourceQuotaList_To_v1beta3_ResourceQuotaList(in *api.ResourceQuotaList, out *ResourceQuotaList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ResourceQuotaList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]ResourceQuota, len(in.Items)) - for i := range in.Items { - if err := convert_api_ResourceQuota_To_v1beta3_ResourceQuota(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_ResourceQuotaSpec_To_v1beta3_ResourceQuotaSpec(in *api.ResourceQuotaSpec, out *ResourceQuotaSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ResourceQuotaSpec))(in) - } - if in.Hard != nil { - out.Hard = make(ResourceList) - for key, val := range in.Hard { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Hard[ResourceName(key)] = newVal - } - } else { - out.Hard = nil - } - return nil -} - -func convert_api_ResourceQuotaStatus_To_v1beta3_ResourceQuotaStatus(in *api.ResourceQuotaStatus, out *ResourceQuotaStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ResourceQuotaStatus))(in) - } - if in.Hard != nil { - out.Hard = make(ResourceList) - for key, val := range in.Hard { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Hard[ResourceName(key)] = newVal - } - } else { - out.Hard = nil - } - if in.Used != nil { - out.Used = make(ResourceList) - for key, val := range in.Used { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Used[ResourceName(key)] = newVal - } - } else { - out.Used = nil - } - return nil -} - -func convert_api_ResourceRequirements_To_v1beta3_ResourceRequirements(in *api.ResourceRequirements, out *ResourceRequirements, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ResourceRequirements))(in) - } - if in.Limits != nil { - out.Limits = make(ResourceList) - for key, val := range in.Limits { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Limits[ResourceName(key)] = newVal - } - } else { - out.Limits = nil - } - if in.Requests != nil { - out.Requests = make(ResourceList) - for key, val := range in.Requests { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Requests[ResourceName(key)] = newVal - } - } else { - out.Requests = nil - } - return nil -} - -func convert_api_FSGroupStrategyOptions_To_v1beta3_FSGroupStrategyOptions(in *api.FSGroupStrategyOptions, out *FSGroupStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.FSGroupStrategyOptions))(in) - } - out.Type = FSGroupStrategyType(in.Type) - if in.Ranges != nil { - out.Ranges = make([]IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := convert_api_IDRange_To_v1beta3_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func convert_api_SupplementalGroupsStrategyOptions_To_v1beta3_SupplementalGroupsStrategyOptions(in *api.SupplementalGroupsStrategyOptions, out *SupplementalGroupsStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SupplementalGroupsStrategyOptions))(in) - } - out.Type = SupplementalGroupsStrategyType(in.Type) - if in.Ranges != nil { - out.Ranges = make([]IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := convert_api_IDRange_To_v1beta3_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func convert_api_IDRange_To_v1beta3_IDRange(in *api.IDRange, out *IDRange, s conversion.Scope) error { - out.Min = in.Min - out.Max = in.Max - return nil -} - -func convert_api_RunAsUserStrategyOptions_To_v1beta3_RunAsUserStrategyOptions(in *api.RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.RunAsUserStrategyOptions))(in) - } - out.Type = RunAsUserStrategyType(in.Type) - if in.UID != nil { - out.UID = new(int64) - *out.UID = *in.UID - } else { - out.UID = nil - } - if in.UIDRangeMin != nil { - out.UIDRangeMin = new(int64) - *out.UIDRangeMin = *in.UIDRangeMin - } else { - out.UIDRangeMin = nil - } - if in.UIDRangeMax != nil { - out.UIDRangeMax = new(int64) - *out.UIDRangeMax = *in.UIDRangeMax - } else { - out.UIDRangeMax = nil - } - return nil -} - -func convert_api_SELinuxContextStrategyOptions_To_v1beta3_SELinuxContextStrategyOptions(in *api.SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SELinuxContextStrategyOptions))(in) - } - out.Type = SELinuxContextStrategyType(in.Type) - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(SELinuxOptions) - if err := convert_api_SELinuxOptions_To_v1beta3_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - return nil -} - -func convert_api_SELinuxOptions_To_v1beta3_SELinuxOptions(in *api.SELinuxOptions, out *SELinuxOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SELinuxOptions))(in) - } - out.User = in.User - out.Role = in.Role - out.Type = in.Type - out.Level = in.Level - return nil -} - -func convert_api_Secret_To_v1beta3_Secret(in *api.Secret, out *Secret, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Secret))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if in.Data != nil { - out.Data = make(map[string][]uint8) - for key, val := range in.Data { - newVal := []uint8{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Data[key] = newVal - } - } else { - out.Data = nil - } - out.Type = SecretType(in.Type) - return nil -} - -func convert_api_SecretList_To_v1beta3_SecretList(in *api.SecretList, out *SecretList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SecretList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Secret, len(in.Items)) - for i := range in.Items { - if err := convert_api_Secret_To_v1beta3_Secret(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_SecretVolumeSource_To_v1beta3_SecretVolumeSource(in *api.SecretVolumeSource, out *SecretVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SecretVolumeSource))(in) - } - out.SecretName = in.SecretName - return nil -} - -func convert_api_SecurityContext_To_v1beta3_SecurityContext(in *api.SecurityContext, out *SecurityContext, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SecurityContext))(in) - } - if in.Capabilities != nil { - out.Capabilities = new(Capabilities) - if err := convert_api_Capabilities_To_v1beta3_Capabilities(in.Capabilities, out.Capabilities, s); err != nil { - return err - } - } else { - out.Capabilities = nil - } - if in.Privileged != nil { - out.Privileged = new(bool) - *out.Privileged = *in.Privileged - } else { - out.Privileged = nil - } - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(SELinuxOptions) - if err := convert_api_SELinuxOptions_To_v1beta3_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - if in.RunAsUser != nil { - out.RunAsUser = new(int64) - *out.RunAsUser = *in.RunAsUser - } else { - out.RunAsUser = nil - } - out.RunAsNonRoot = in.RunAsNonRoot - return nil -} - -func convert_api_SecurityContextConstraints_To_v1beta3_SecurityContextConstraints(in *api.SecurityContextConstraints, out *SecurityContextConstraints, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SecurityContextConstraints))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - out.AllowPrivilegedContainer = in.AllowPrivilegedContainer - if in.AllowedCapabilities != nil { - out.AllowedCapabilities = make([]Capability, len(in.AllowedCapabilities)) - for i := range in.AllowedCapabilities { - out.AllowedCapabilities[i] = Capability(in.AllowedCapabilities[i]) - } - } else { - out.AllowedCapabilities = nil - } - out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin - out.AllowHostNetwork = in.AllowHostNetwork - out.AllowHostPorts = in.AllowHostPorts - out.AllowHostPID = in.AllowHostPID - out.AllowHostIPC = in.AllowHostIPC - if err := convert_api_SELinuxContextStrategyOptions_To_v1beta3_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil { - return err - } - if err := convert_api_RunAsUserStrategyOptions_To_v1beta3_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil { - return err - } - if err := convert_api_FSGroupStrategyOptions_To_v1beta3_FSGroupStrategyOptions(&in.FSGroup, &out.FSGroup, s); err != nil { - return err - } - if err := convert_api_SupplementalGroupsStrategyOptions_To_v1beta3_SupplementalGroupsStrategyOptions(&in.SupplementalGroups, &out.SupplementalGroups, s); err != nil { - return err - } - if in.Users != nil { - out.Users = make([]string, len(in.Users)) - for i := range in.Users { - out.Users[i] = in.Users[i] - } - } else { - out.Users = nil - } - if in.Groups != nil { - out.Groups = make([]string, len(in.Groups)) - for i := range in.Groups { - out.Groups[i] = in.Groups[i] - } - } else { - out.Groups = nil - } - return nil -} - -func convert_api_SecurityContextConstraintsList_To_v1beta3_SecurityContextConstraintsList(in *api.SecurityContextConstraintsList, out *SecurityContextConstraintsList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SecurityContextConstraintsList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]SecurityContextConstraints, len(in.Items)) - for i := range in.Items { - if err := convert_api_SecurityContextConstraints_To_v1beta3_SecurityContextConstraints(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_SerializedReference_To_v1beta3_SerializedReference(in *api.SerializedReference, out *SerializedReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SerializedReference))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.Reference, &out.Reference, s); err != nil { - return err - } - return nil -} - -func convert_api_Service_To_v1beta3_Service(in *api.Service, out *Service, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Service))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_ServiceSpec_To_v1beta3_ServiceSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_api_ServiceStatus_To_v1beta3_ServiceStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_api_ServiceAccount_To_v1beta3_ServiceAccount(in *api.ServiceAccount, out *ServiceAccount, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ServiceAccount))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if in.Secrets != nil { - out.Secrets = make([]ObjectReference, len(in.Secrets)) - for i := range in.Secrets { - if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.Secrets[i], &out.Secrets[i], s); err != nil { - return err - } - } - } else { - out.Secrets = nil - } - if in.ImagePullSecrets != nil { - out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) - for i := range in.ImagePullSecrets { - if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { - return err - } - } - } else { - out.ImagePullSecrets = nil - } - return nil -} - -func convert_api_ServiceAccountList_To_v1beta3_ServiceAccountList(in *api.ServiceAccountList, out *ServiceAccountList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ServiceAccountList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]ServiceAccount, len(in.Items)) - for i := range in.Items { - if err := convert_api_ServiceAccount_To_v1beta3_ServiceAccount(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_ServiceList_To_v1beta3_ServiceList(in *api.ServiceList, out *ServiceList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ServiceList))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Service, len(in.Items)) - for i := range in.Items { - if err := convert_api_Service_To_v1beta3_Service(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_ServicePort_To_v1beta3_ServicePort(in *api.ServicePort, out *ServicePort, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ServicePort))(in) - } - out.Name = in.Name - out.Protocol = Protocol(in.Protocol) - out.Port = in.Port - if err := s.Convert(&in.TargetPort, &out.TargetPort, 0); err != nil { - return err - } - out.NodePort = in.NodePort - return nil -} - -func convert_api_ServiceStatus_To_v1beta3_ServiceStatus(in *api.ServiceStatus, out *ServiceStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ServiceStatus))(in) - } - if err := convert_api_LoadBalancerStatus_To_v1beta3_LoadBalancerStatus(&in.LoadBalancer, &out.LoadBalancer, s); err != nil { - return err - } - return nil -} - -func convert_api_Status_To_v1beta3_Status(in *api.Status, out *Status, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Status))(in) - } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - out.Status = in.Status - out.Message = in.Message - out.Reason = StatusReason(in.Reason) - if in.Details != nil { - out.Details = new(StatusDetails) - if err := convert_api_StatusDetails_To_v1beta3_StatusDetails(in.Details, out.Details, s); err != nil { - return err - } - } else { - out.Details = nil - } - out.Code = in.Code - return nil -} - -func convert_api_TCPSocketAction_To_v1beta3_TCPSocketAction(in *api.TCPSocketAction, out *TCPSocketAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.TCPSocketAction))(in) - } - if err := s.Convert(&in.Port, &out.Port, 0); err != nil { - return err - } - return nil -} - -func convert_api_TypeMeta_To_v1beta3_TypeMeta(in *api.TypeMeta, out *TypeMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.TypeMeta))(in) - } - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil -} - -func convert_api_Volume_To_v1beta3_Volume(in *api.Volume, out *Volume, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Volume))(in) - } - out.Name = in.Name - if err := convert_api_VolumeSource_To_v1beta3_VolumeSource(&in.VolumeSource, &out.VolumeSource, s); err != nil { - return err - } - return nil -} - -func convert_api_VolumeMount_To_v1beta3_VolumeMount(in *api.VolumeMount, out *VolumeMount, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.VolumeMount))(in) - } - out.Name = in.Name - out.ReadOnly = in.ReadOnly - out.MountPath = in.MountPath - return nil -} - -func convert_v1beta3_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in *AWSElasticBlockStoreVolumeSource, out *api.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*AWSElasticBlockStoreVolumeSource))(in) - } - out.VolumeID = in.VolumeID - out.FSType = in.FSType - out.Partition = in.Partition - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1beta3_Binding_To_api_Binding(in *Binding, out *api.Binding, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Binding))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.Target, &out.Target, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_Capabilities_To_api_Capabilities(in *Capabilities, out *api.Capabilities, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Capabilities))(in) - } - if in.Add != nil { - out.Add = make([]api.Capability, len(in.Add)) - for i := range in.Add { - out.Add[i] = api.Capability(in.Add[i]) - } - } else { - out.Add = nil - } - if in.Drop != nil { - out.Drop = make([]api.Capability, len(in.Drop)) - for i := range in.Drop { - out.Drop[i] = api.Capability(in.Drop[i]) - } - } else { - out.Drop = nil - } - return nil -} - -func convert_v1beta3_CephFSVolumeSource_To_api_CephFSVolumeSource(in *CephFSVolumeSource, out *api.CephFSVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*CephFSVolumeSource))(in) - } - if in.Monitors != nil { - out.Monitors = make([]string, len(in.Monitors)) - for i := range in.Monitors { - out.Monitors[i] = in.Monitors[i] - } - } else { - out.Monitors = nil - } - out.User = in.User - out.SecretFile = in.SecretFile - if in.SecretRef != nil { - out.SecretRef = new(api.LocalObjectReference) - if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { - return err - } - } else { - out.SecretRef = nil - } - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1beta3_CinderVolumeSource_To_api_CinderVolumeSource(in *CinderVolumeSource, out *api.CinderVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*CinderVolumeSource))(in) - } - out.VolumeID = in.VolumeID - out.FSType = in.FSType - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1beta3_ComponentCondition_To_api_ComponentCondition(in *ComponentCondition, out *api.ComponentCondition, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ComponentCondition))(in) - } - out.Type = api.ComponentConditionType(in.Type) - out.Status = api.ConditionStatus(in.Status) - out.Message = in.Message - out.Error = in.Error - return nil -} - -func convert_v1beta3_ComponentStatus_To_api_ComponentStatus(in *ComponentStatus, out *api.ComponentStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ComponentStatus))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if in.Conditions != nil { - out.Conditions = make([]api.ComponentCondition, len(in.Conditions)) - for i := range in.Conditions { - if err := convert_v1beta3_ComponentCondition_To_api_ComponentCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { - return err - } - } - } else { - out.Conditions = nil - } - return nil -} - -func convert_v1beta3_ComponentStatusList_To_api_ComponentStatusList(in *ComponentStatusList, out *api.ComponentStatusList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ComponentStatusList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.ComponentStatus, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_ComponentStatus_To_api_ComponentStatus(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_ContainerPort_To_api_ContainerPort(in *ContainerPort, out *api.ContainerPort, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ContainerPort))(in) - } - out.Name = in.Name - out.HostPort = in.HostPort - out.ContainerPort = in.ContainerPort - out.Protocol = api.Protocol(in.Protocol) - out.HostIP = in.HostIP - return nil -} - -func convert_v1beta3_ContainerStateRunning_To_api_ContainerStateRunning(in *ContainerStateRunning, out *api.ContainerStateRunning, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ContainerStateRunning))(in) - } - if err := s.Convert(&in.StartedAt, &out.StartedAt, 0); err != nil { - return err - } - return nil -} - -func convert_v1beta3_ContainerStateWaiting_To_api_ContainerStateWaiting(in *ContainerStateWaiting, out *api.ContainerStateWaiting, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ContainerStateWaiting))(in) - } - out.Reason = in.Reason - return nil -} - -func convert_v1beta3_ContainerStatus_To_api_ContainerStatus(in *ContainerStatus, out *api.ContainerStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ContainerStatus))(in) - } - out.Name = in.Name - if err := convert_v1beta3_ContainerState_To_api_ContainerState(&in.State, &out.State, s); err != nil { - return err - } - if err := convert_v1beta3_ContainerState_To_api_ContainerState(&in.LastTerminationState, &out.LastTerminationState, s); err != nil { - return err - } - out.Ready = in.Ready - out.RestartCount = in.RestartCount - out.Image = in.Image - out.ImageID = in.ImageID - out.ContainerID = in.ContainerID - return nil -} - -func convert_v1beta3_DeleteOptions_To_api_DeleteOptions(in *DeleteOptions, out *api.DeleteOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*DeleteOptions))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if in.GracePeriodSeconds != nil { - out.GracePeriodSeconds = new(int64) - *out.GracePeriodSeconds = *in.GracePeriodSeconds - } else { - out.GracePeriodSeconds = nil - } - return nil -} - -func convert_v1beta3_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *DownwardAPIVolumeFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*DownwardAPIVolumeFile))(in) - } - out.Path = in.Path - if err := convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *DownwardAPIVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*DownwardAPIVolumeSource))(in) - } - if in.Items != nil { - out.Items = make([]api.DownwardAPIVolumeFile, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in *EmptyDirVolumeSource, out *api.EmptyDirVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*EmptyDirVolumeSource))(in) - } - out.Medium = api.StorageMedium(in.Medium) - return nil -} - -func convert_v1beta3_EndpointAddress_To_api_EndpointAddress(in *EndpointAddress, out *api.EndpointAddress, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*EndpointAddress))(in) - } - out.IP = in.IP - if in.TargetRef != nil { - out.TargetRef = new(api.ObjectReference) - if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(in.TargetRef, out.TargetRef, s); err != nil { - return err - } - } else { - out.TargetRef = nil - } - return nil -} - -func convert_v1beta3_EndpointPort_To_api_EndpointPort(in *EndpointPort, out *api.EndpointPort, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*EndpointPort))(in) - } - out.Name = in.Name - out.Port = in.Port - out.Protocol = api.Protocol(in.Protocol) - return nil -} - -func convert_v1beta3_EndpointSubset_To_api_EndpointSubset(in *EndpointSubset, out *api.EndpointSubset, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*EndpointSubset))(in) - } - if in.Addresses != nil { - out.Addresses = make([]api.EndpointAddress, len(in.Addresses)) - for i := range in.Addresses { - if err := convert_v1beta3_EndpointAddress_To_api_EndpointAddress(&in.Addresses[i], &out.Addresses[i], s); err != nil { - return err - } - } - } else { - out.Addresses = nil - } - if in.Ports != nil { - out.Ports = make([]api.EndpointPort, len(in.Ports)) - for i := range in.Ports { - if err := convert_v1beta3_EndpointPort_To_api_EndpointPort(&in.Ports[i], &out.Ports[i], s); err != nil { - return err - } - } - } else { - out.Ports = nil - } - return nil -} - -func convert_v1beta3_Endpoints_To_api_Endpoints(in *Endpoints, out *api.Endpoints, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Endpoints))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if in.Subsets != nil { - out.Subsets = make([]api.EndpointSubset, len(in.Subsets)) - for i := range in.Subsets { - if err := convert_v1beta3_EndpointSubset_To_api_EndpointSubset(&in.Subsets[i], &out.Subsets[i], s); err != nil { - return err - } - } - } else { - out.Subsets = nil - } - return nil -} - -func convert_v1beta3_EndpointsList_To_api_EndpointsList(in *EndpointsList, out *api.EndpointsList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*EndpointsList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.Endpoints, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_Endpoints_To_api_Endpoints(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_EnvVar_To_api_EnvVar(in *EnvVar, out *api.EnvVar, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*EnvVar))(in) - } - out.Name = in.Name - out.Value = in.Value - if in.ValueFrom != nil { - out.ValueFrom = new(api.EnvVarSource) - if err := convert_v1beta3_EnvVarSource_To_api_EnvVarSource(in.ValueFrom, out.ValueFrom, s); err != nil { - return err - } - } else { - out.ValueFrom = nil - } - return nil -} - -func convert_v1beta3_EnvVarSource_To_api_EnvVarSource(in *EnvVarSource, out *api.EnvVarSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*EnvVarSource))(in) - } - if in.FieldRef != nil { - out.FieldRef = new(api.ObjectFieldSelector) - if err := convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(in.FieldRef, out.FieldRef, s); err != nil { - return err - } - } else { - out.FieldRef = nil - } - return nil -} - -func convert_v1beta3_Event_To_api_Event(in *Event, out *api.Event, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Event))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.InvolvedObject, &out.InvolvedObject, s); err != nil { - return err - } - out.Reason = in.Reason - out.Message = in.Message - if err := convert_v1beta3_EventSource_To_api_EventSource(&in.Source, &out.Source, s); err != nil { - return err - } - if err := s.Convert(&in.FirstTimestamp, &out.FirstTimestamp, 0); err != nil { - return err - } - if err := s.Convert(&in.LastTimestamp, &out.LastTimestamp, 0); err != nil { - return err - } - out.Count = in.Count - return nil -} - -func convert_v1beta3_EventList_To_api_EventList(in *EventList, out *api.EventList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*EventList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.Event, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_Event_To_api_Event(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_EventSource_To_api_EventSource(in *EventSource, out *api.EventSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*EventSource))(in) - } - out.Component = in.Component - out.Host = in.Host - return nil -} - -func convert_v1beta3_ExecAction_To_api_ExecAction(in *ExecAction, out *api.ExecAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ExecAction))(in) - } - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } else { - out.Command = nil - } - return nil -} - -func convert_v1beta3_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in *GCEPersistentDiskVolumeSource, out *api.GCEPersistentDiskVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*GCEPersistentDiskVolumeSource))(in) - } - out.PDName = in.PDName - out.FSType = in.FSType - out.Partition = in.Partition - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1beta3_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in *GitRepoVolumeSource, out *api.GitRepoVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*GitRepoVolumeSource))(in) - } - out.Repository = in.Repository - out.Revision = in.Revision - return nil -} - -func convert_v1beta3_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in *GlusterfsVolumeSource, out *api.GlusterfsVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*GlusterfsVolumeSource))(in) - } - out.EndpointsName = in.EndpointsName - out.Path = in.Path - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1beta3_HTTPGetAction_To_api_HTTPGetAction(in *HTTPGetAction, out *api.HTTPGetAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*HTTPGetAction))(in) - } - out.Path = in.Path - if err := s.Convert(&in.Port, &out.Port, 0); err != nil { - return err - } - out.Host = in.Host - out.Scheme = api.URIScheme(in.Scheme) - return nil -} - -func convert_v1beta3_Handler_To_api_Handler(in *Handler, out *api.Handler, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Handler))(in) - } - if in.Exec != nil { - out.Exec = new(api.ExecAction) - if err := convert_v1beta3_ExecAction_To_api_ExecAction(in.Exec, out.Exec, s); err != nil { - return err - } - } else { - out.Exec = nil - } - if in.HTTPGet != nil { - out.HTTPGet = new(api.HTTPGetAction) - if err := convert_v1beta3_HTTPGetAction_To_api_HTTPGetAction(in.HTTPGet, out.HTTPGet, s); err != nil { - return err - } - } else { - out.HTTPGet = nil - } - if in.TCPSocket != nil { - out.TCPSocket = new(api.TCPSocketAction) - if err := convert_v1beta3_TCPSocketAction_To_api_TCPSocketAction(in.TCPSocket, out.TCPSocket, s); err != nil { - return err - } - } else { - out.TCPSocket = nil - } - return nil -} - -func convert_v1beta3_HostPathVolumeSource_To_api_HostPathVolumeSource(in *HostPathVolumeSource, out *api.HostPathVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*HostPathVolumeSource))(in) - } - out.Path = in.Path - return nil -} - -func convert_v1beta3_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in *ISCSIVolumeSource, out *api.ISCSIVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ISCSIVolumeSource))(in) - } - out.TargetPortal = in.TargetPortal - out.IQN = in.IQN - out.Lun = in.Lun - out.FSType = in.FSType - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1beta3_Lifecycle_To_api_Lifecycle(in *Lifecycle, out *api.Lifecycle, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Lifecycle))(in) - } - if in.PostStart != nil { - out.PostStart = new(api.Handler) - if err := convert_v1beta3_Handler_To_api_Handler(in.PostStart, out.PostStart, s); err != nil { - return err - } - } else { - out.PostStart = nil - } - if in.PreStop != nil { - out.PreStop = new(api.Handler) - if err := convert_v1beta3_Handler_To_api_Handler(in.PreStop, out.PreStop, s); err != nil { - return err - } - } else { - out.PreStop = nil - } - return nil -} - -func convert_v1beta3_LimitRange_To_api_LimitRange(in *LimitRange, out *api.LimitRange, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*LimitRange))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_LimitRangeSpec_To_api_LimitRangeSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_LimitRangeItem_To_api_LimitRangeItem(in *LimitRangeItem, out *api.LimitRangeItem, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*LimitRangeItem))(in) - } - out.Type = api.LimitType(in.Type) - if in.Max != nil { - out.Max = make(api.ResourceList) - for key, val := range in.Max { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Max[api.ResourceName(key)] = newVal - } - } else { - out.Max = nil - } - if in.Min != nil { - out.Min = make(api.ResourceList) - for key, val := range in.Min { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Min[api.ResourceName(key)] = newVal - } - } else { - out.Min = nil - } - if in.Default != nil { - out.Default = make(api.ResourceList) - for key, val := range in.Default { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Default[api.ResourceName(key)] = newVal - } - } else { - out.Default = nil - } - if in.DefaultRequest != nil { - out.DefaultRequest = make(api.ResourceList) - for key, val := range in.DefaultRequest { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.DefaultRequest[api.ResourceName(key)] = newVal - } - } else { - out.DefaultRequest = nil - } - if in.MaxLimitRequestRatio != nil { - out.MaxLimitRequestRatio = make(api.ResourceList) - for key, val := range in.MaxLimitRequestRatio { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.MaxLimitRequestRatio[api.ResourceName(key)] = newVal - } - } else { - out.MaxLimitRequestRatio = nil - } - return nil -} - -func convert_v1beta3_LimitRangeList_To_api_LimitRangeList(in *LimitRangeList, out *api.LimitRangeList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*LimitRangeList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.LimitRange, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_LimitRange_To_api_LimitRange(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_LimitRangeSpec_To_api_LimitRangeSpec(in *LimitRangeSpec, out *api.LimitRangeSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*LimitRangeSpec))(in) - } - if in.Limits != nil { - out.Limits = make([]api.LimitRangeItem, len(in.Limits)) - for i := range in.Limits { - if err := convert_v1beta3_LimitRangeItem_To_api_LimitRangeItem(&in.Limits[i], &out.Limits[i], s); err != nil { - return err - } - } - } else { - out.Limits = nil - } - return nil -} - -func convert_v1beta3_List_To_api_List(in *List, out *api.List, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*List))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if err := s.Convert(&in.Items, &out.Items, 0); err != nil { - return err - } - return nil -} - -func convert_v1beta3_ListMeta_To_api_ListMeta(in *ListMeta, out *api.ListMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ListMeta))(in) - } - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil -} - -func convert_v1beta3_ListOptions_To_api_ListOptions(in *ListOptions, out *api.ListOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ListOptions))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := s.Convert(&in.LabelSelector, &out.LabelSelector, 0); err != nil { - return err - } - if err := s.Convert(&in.FieldSelector, &out.FieldSelector, 0); err != nil { - return err - } - out.Watch = in.Watch - out.ResourceVersion = in.ResourceVersion - return nil -} - -func convert_v1beta3_LoadBalancerIngress_To_api_LoadBalancerIngress(in *LoadBalancerIngress, out *api.LoadBalancerIngress, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*LoadBalancerIngress))(in) - } - out.IP = in.IP - out.Hostname = in.Hostname - return nil -} - -func convert_v1beta3_LoadBalancerStatus_To_api_LoadBalancerStatus(in *LoadBalancerStatus, out *api.LoadBalancerStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*LoadBalancerStatus))(in) - } - if in.Ingress != nil { - out.Ingress = make([]api.LoadBalancerIngress, len(in.Ingress)) - for i := range in.Ingress { - if err := convert_v1beta3_LoadBalancerIngress_To_api_LoadBalancerIngress(&in.Ingress[i], &out.Ingress[i], s); err != nil { - return err - } - } - } else { - out.Ingress = nil - } - return nil -} - -func convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in *LocalObjectReference, out *api.LocalObjectReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*LocalObjectReference))(in) - } - out.Name = in.Name - return nil -} - -func convert_v1beta3_NFSVolumeSource_To_api_NFSVolumeSource(in *NFSVolumeSource, out *api.NFSVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*NFSVolumeSource))(in) - } - out.Server = in.Server - out.Path = in.Path - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1beta3_Namespace_To_api_Namespace(in *Namespace, out *api.Namespace, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Namespace))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_NamespaceSpec_To_api_NamespaceSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1beta3_NamespaceStatus_To_api_NamespaceStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_NamespaceList_To_api_NamespaceList(in *NamespaceList, out *api.NamespaceList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*NamespaceList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.Namespace, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_Namespace_To_api_Namespace(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_NamespaceSpec_To_api_NamespaceSpec(in *NamespaceSpec, out *api.NamespaceSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*NamespaceSpec))(in) - } - if in.Finalizers != nil { - out.Finalizers = make([]api.FinalizerName, len(in.Finalizers)) - for i := range in.Finalizers { - out.Finalizers[i] = api.FinalizerName(in.Finalizers[i]) - } - } else { - out.Finalizers = nil - } - return nil -} - -func convert_v1beta3_NamespaceStatus_To_api_NamespaceStatus(in *NamespaceStatus, out *api.NamespaceStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*NamespaceStatus))(in) - } - out.Phase = api.NamespacePhase(in.Phase) - return nil -} - -func convert_v1beta3_Node_To_api_Node(in *Node, out *api.Node, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Node))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_NodeSpec_To_api_NodeSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1beta3_NodeStatus_To_api_NodeStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_NodeAddress_To_api_NodeAddress(in *NodeAddress, out *api.NodeAddress, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*NodeAddress))(in) - } - out.Type = api.NodeAddressType(in.Type) - out.Address = in.Address - return nil -} - -func convert_v1beta3_NodeCondition_To_api_NodeCondition(in *NodeCondition, out *api.NodeCondition, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*NodeCondition))(in) - } - out.Type = api.NodeConditionType(in.Type) - out.Status = api.ConditionStatus(in.Status) - if err := s.Convert(&in.LastHeartbeatTime, &out.LastHeartbeatTime, 0); err != nil { - return err - } - if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { - return err - } - out.Reason = in.Reason - out.Message = in.Message - return nil -} - -func convert_v1beta3_NodeList_To_api_NodeList(in *NodeList, out *api.NodeList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*NodeList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.Node, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_Node_To_api_Node(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_NodeSpec_To_api_NodeSpec(in *NodeSpec, out *api.NodeSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*NodeSpec))(in) - } - out.PodCIDR = in.PodCIDR - out.ExternalID = in.ExternalID - out.ProviderID = in.ProviderID - out.Unschedulable = in.Unschedulable - return nil -} - -func convert_v1beta3_NodeStatus_To_api_NodeStatus(in *NodeStatus, out *api.NodeStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*NodeStatus))(in) - } - if in.Capacity != nil { - out.Capacity = make(api.ResourceList) - for key, val := range in.Capacity { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Capacity[api.ResourceName(key)] = newVal - } - } else { - out.Capacity = nil - } - out.Phase = api.NodePhase(in.Phase) - if in.Conditions != nil { - out.Conditions = make([]api.NodeCondition, len(in.Conditions)) - for i := range in.Conditions { - if err := convert_v1beta3_NodeCondition_To_api_NodeCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { - return err - } - } - } else { - out.Conditions = nil - } - if in.Addresses != nil { - out.Addresses = make([]api.NodeAddress, len(in.Addresses)) - for i := range in.Addresses { - if err := convert_v1beta3_NodeAddress_To_api_NodeAddress(&in.Addresses[i], &out.Addresses[i], s); err != nil { - return err - } - } - } else { - out.Addresses = nil - } - if err := convert_v1beta3_NodeSystemInfo_To_api_NodeSystemInfo(&in.NodeInfo, &out.NodeInfo, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_NodeSystemInfo_To_api_NodeSystemInfo(in *NodeSystemInfo, out *api.NodeSystemInfo, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*NodeSystemInfo))(in) - } - out.MachineID = in.MachineID - out.SystemUUID = in.SystemUUID - out.BootID = in.BootID - out.KernelVersion = in.KernelVersion - out.OsImage = in.OsImage - out.ContainerRuntimeVersion = in.ContainerRuntimeVersion - out.KubeletVersion = in.KubeletVersion - out.KubeProxyVersion = in.KubeProxyVersion - return nil -} - -func convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(in *ObjectFieldSelector, out *api.ObjectFieldSelector, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ObjectFieldSelector))(in) - } - out.APIVersion = in.APIVersion - out.FieldPath = in.FieldPath - return nil -} - -func convert_v1beta3_ObjectMeta_To_api_ObjectMeta(in *ObjectMeta, out *api.ObjectMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ObjectMeta))(in) - } - out.Name = in.Name - out.GenerateName = in.GenerateName - out.Namespace = in.Namespace - out.SelfLink = in.SelfLink - out.UID = in.UID - out.ResourceVersion = in.ResourceVersion - out.Generation = in.Generation - if err := s.Convert(&in.CreationTimestamp, &out.CreationTimestamp, 0); err != nil { - return err - } - if in.DeletionTimestamp != nil { - if err := s.Convert(&in.DeletionTimestamp, &out.DeletionTimestamp, 0); err != nil { - return err - } - } else { - out.DeletionTimestamp = nil - } - if in.DeletionGracePeriodSeconds != nil { - out.DeletionGracePeriodSeconds = new(int64) - *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds - } else { - out.DeletionGracePeriodSeconds = nil - } - if in.Labels != nil { - out.Labels = make(map[string]string) - for key, val := range in.Labels { - out.Labels[key] = val - } - } else { - out.Labels = nil - } - if in.Annotations != nil { - out.Annotations = make(map[string]string) - for key, val := range in.Annotations { - out.Annotations[key] = val - } - } else { - out.Annotations = nil - } - return nil -} - -func convert_v1beta3_ObjectReference_To_api_ObjectReference(in *ObjectReference, out *api.ObjectReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ObjectReference))(in) - } - out.Kind = in.Kind - out.Namespace = in.Namespace - out.Name = in.Name - out.UID = in.UID - out.APIVersion = in.APIVersion - out.ResourceVersion = in.ResourceVersion - out.FieldPath = in.FieldPath - return nil -} - -func convert_v1beta3_PersistentVolume_To_api_PersistentVolume(in *PersistentVolume, out *api.PersistentVolume, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PersistentVolume))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_PersistentVolumeSpec_To_api_PersistentVolumeSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1beta3_PersistentVolumeStatus_To_api_PersistentVolumeStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_PersistentVolumeClaim_To_api_PersistentVolumeClaim(in *PersistentVolumeClaim, out *api.PersistentVolumeClaim, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PersistentVolumeClaim))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1beta3_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_PersistentVolumeClaimList_To_api_PersistentVolumeClaimList(in *PersistentVolumeClaimList, out *api.PersistentVolumeClaimList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PersistentVolumeClaimList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.PersistentVolumeClaim, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_PersistentVolumeClaim_To_api_PersistentVolumeClaim(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec(in *PersistentVolumeClaimSpec, out *api.PersistentVolumeClaimSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PersistentVolumeClaimSpec))(in) - } - if in.AccessModes != nil { - out.AccessModes = make([]api.PersistentVolumeAccessMode, len(in.AccessModes)) - for i := range in.AccessModes { - out.AccessModes[i] = api.PersistentVolumeAccessMode(in.AccessModes[i]) - } - } else { - out.AccessModes = nil - } - if err := convert_v1beta3_ResourceRequirements_To_api_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { - return err - } - out.VolumeName = in.VolumeName - return nil -} - -func convert_v1beta3_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus(in *PersistentVolumeClaimStatus, out *api.PersistentVolumeClaimStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PersistentVolumeClaimStatus))(in) - } - out.Phase = api.PersistentVolumeClaimPhase(in.Phase) - if in.AccessModes != nil { - out.AccessModes = make([]api.PersistentVolumeAccessMode, len(in.AccessModes)) - for i := range in.AccessModes { - out.AccessModes[i] = api.PersistentVolumeAccessMode(in.AccessModes[i]) - } - } else { - out.AccessModes = nil - } - if in.Capacity != nil { - out.Capacity = make(api.ResourceList) - for key, val := range in.Capacity { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Capacity[api.ResourceName(key)] = newVal - } - } else { - out.Capacity = nil - } - return nil -} - -func convert_v1beta3_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in *PersistentVolumeClaimVolumeSource, out *api.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PersistentVolumeClaimVolumeSource))(in) - } - out.ClaimName = in.ClaimName - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1beta3_PersistentVolumeList_To_api_PersistentVolumeList(in *PersistentVolumeList, out *api.PersistentVolumeList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PersistentVolumeList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.PersistentVolume, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_PersistentVolume_To_api_PersistentVolume(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_PersistentVolumeSource_To_api_PersistentVolumeSource(in *PersistentVolumeSource, out *api.PersistentVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PersistentVolumeSource))(in) - } - if in.GCEPersistentDisk != nil { - out.GCEPersistentDisk = new(api.GCEPersistentDiskVolumeSource) - if err := convert_v1beta3_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in.GCEPersistentDisk, out.GCEPersistentDisk, s); err != nil { - return err - } - } else { - out.GCEPersistentDisk = nil - } - if in.AWSElasticBlockStore != nil { - out.AWSElasticBlockStore = new(api.AWSElasticBlockStoreVolumeSource) - if err := convert_v1beta3_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in.AWSElasticBlockStore, out.AWSElasticBlockStore, s); err != nil { - return err - } - } else { - out.AWSElasticBlockStore = nil - } - if in.HostPath != nil { - out.HostPath = new(api.HostPathVolumeSource) - if err := convert_v1beta3_HostPathVolumeSource_To_api_HostPathVolumeSource(in.HostPath, out.HostPath, s); err != nil { - return err - } - } else { - out.HostPath = nil - } - if in.Glusterfs != nil { - out.Glusterfs = new(api.GlusterfsVolumeSource) - if err := convert_v1beta3_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { - return err - } - } else { - out.Glusterfs = nil - } - if in.NFS != nil { - out.NFS = new(api.NFSVolumeSource) - if err := convert_v1beta3_NFSVolumeSource_To_api_NFSVolumeSource(in.NFS, out.NFS, s); err != nil { - return err - } - } else { - out.NFS = nil - } - if in.RBD != nil { - out.RBD = new(api.RBDVolumeSource) - if err := convert_v1beta3_RBDVolumeSource_To_api_RBDVolumeSource(in.RBD, out.RBD, s); err != nil { - return err - } - } else { - out.RBD = nil - } - if in.ISCSI != nil { - out.ISCSI = new(api.ISCSIVolumeSource) - if err := convert_v1beta3_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { - return err - } - } else { - out.ISCSI = nil - } - if in.CephFS != nil { - out.CephFS = new(api.CephFSVolumeSource) - if err := convert_v1beta3_CephFSVolumeSource_To_api_CephFSVolumeSource(in.CephFS, out.CephFS, s); err != nil { - return err - } - } else { - out.CephFS = nil - } - if in.Cinder != nil { - out.Cinder = new(api.CinderVolumeSource) - if err := convert_v1beta3_CinderVolumeSource_To_api_CinderVolumeSource(in.Cinder, out.Cinder, s); err != nil { - return err - } - } else { - out.Cinder = nil - } - return nil -} - -func convert_v1beta3_PersistentVolumeSpec_To_api_PersistentVolumeSpec(in *PersistentVolumeSpec, out *api.PersistentVolumeSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PersistentVolumeSpec))(in) - } - if in.Capacity != nil { - out.Capacity = make(api.ResourceList) - for key, val := range in.Capacity { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Capacity[api.ResourceName(key)] = newVal - } - } else { - out.Capacity = nil - } - if err := convert_v1beta3_PersistentVolumeSource_To_api_PersistentVolumeSource(&in.PersistentVolumeSource, &out.PersistentVolumeSource, s); err != nil { - return err - } - if in.AccessModes != nil { - out.AccessModes = make([]api.PersistentVolumeAccessMode, len(in.AccessModes)) - for i := range in.AccessModes { - out.AccessModes[i] = api.PersistentVolumeAccessMode(in.AccessModes[i]) - } - } else { - out.AccessModes = nil - } - if in.ClaimRef != nil { - out.ClaimRef = new(api.ObjectReference) - if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(in.ClaimRef, out.ClaimRef, s); err != nil { - return err - } - } else { - out.ClaimRef = nil - } - out.PersistentVolumeReclaimPolicy = api.PersistentVolumeReclaimPolicy(in.PersistentVolumeReclaimPolicy) - return nil -} - -func convert_v1beta3_PersistentVolumeStatus_To_api_PersistentVolumeStatus(in *PersistentVolumeStatus, out *api.PersistentVolumeStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PersistentVolumeStatus))(in) - } - out.Phase = api.PersistentVolumePhase(in.Phase) - out.Message = in.Message - out.Reason = in.Reason - return nil -} - -func convert_v1beta3_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Pod))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_PodSpec_To_api_PodSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1beta3_PodStatus_To_api_PodStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_PodCondition_To_api_PodCondition(in *PodCondition, out *api.PodCondition, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PodCondition))(in) - } - out.Type = api.PodConditionType(in.Type) - out.Status = api.ConditionStatus(in.Status) - return nil -} - -func convert_v1beta3_PodExecOptions_To_api_PodExecOptions(in *PodExecOptions, out *api.PodExecOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PodExecOptions))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - out.Stdin = in.Stdin - out.Stdout = in.Stdout - out.Stderr = in.Stderr - out.TTY = in.TTY - out.Container = in.Container - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } else { - out.Command = nil - } - return nil -} - -func convert_v1beta3_PodList_To_api_PodList(in *PodList, out *api.PodList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PodList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.Pod, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_Pod_To_api_Pod(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_PodLogOptions_To_api_PodLogOptions(in *PodLogOptions, out *api.PodLogOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PodLogOptions))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - out.Container = in.Container - out.Follow = in.Follow - out.Previous = in.Previous - return nil -} - -func convert_v1beta3_PodProxyOptions_To_api_PodProxyOptions(in *PodProxyOptions, out *api.PodProxyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PodProxyOptions))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - out.Path = in.Path - return nil -} - -func convert_v1beta3_PodStatus_To_api_PodStatus(in *PodStatus, out *api.PodStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PodStatus))(in) - } - out.Phase = api.PodPhase(in.Phase) - if in.Conditions != nil { - out.Conditions = make([]api.PodCondition, len(in.Conditions)) - for i := range in.Conditions { - if err := convert_v1beta3_PodCondition_To_api_PodCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { - return err - } - } - } else { - out.Conditions = nil - } - out.Message = in.Message - out.Reason = in.Reason - out.HostIP = in.HostIP - out.PodIP = in.PodIP - if in.StartTime != nil { - if err := s.Convert(&in.StartTime, &out.StartTime, 0); err != nil { - return err - } - } else { - out.StartTime = nil - } - if in.ContainerStatuses != nil { - out.ContainerStatuses = make([]api.ContainerStatus, len(in.ContainerStatuses)) - for i := range in.ContainerStatuses { - if err := convert_v1beta3_ContainerStatus_To_api_ContainerStatus(&in.ContainerStatuses[i], &out.ContainerStatuses[i], s); err != nil { - return err - } - } - } else { - out.ContainerStatuses = nil - } - return nil -} - -func convert_v1beta3_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PodStatusResult))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_PodStatus_To_api_PodStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_PodTemplate_To_api_PodTemplate(in *PodTemplate, out *api.PodTemplate, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PodTemplate))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_PodTemplateList_To_api_PodTemplateList(in *PodTemplateList, out *api.PodTemplateList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PodTemplateList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.PodTemplate, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_PodTemplate_To_api_PodTemplate(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*PodTemplateSpec))(in) - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_PodSpec_To_api_PodSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_Probe_To_api_Probe(in *Probe, out *api.Probe, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Probe))(in) - } - if err := convert_v1beta3_Handler_To_api_Handler(&in.Handler, &out.Handler, s); err != nil { - return err - } - out.InitialDelaySeconds = in.InitialDelaySeconds - out.TimeoutSeconds = in.TimeoutSeconds - return nil -} - -func convert_v1beta3_RBDVolumeSource_To_api_RBDVolumeSource(in *RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*RBDVolumeSource))(in) - } - if in.CephMonitors != nil { - out.CephMonitors = make([]string, len(in.CephMonitors)) - for i := range in.CephMonitors { - out.CephMonitors[i] = in.CephMonitors[i] - } - } else { - out.CephMonitors = nil - } - out.RBDImage = in.RBDImage - out.FSType = in.FSType - out.RBDPool = in.RBDPool - out.RadosUser = in.RadosUser - out.Keyring = in.Keyring - if in.SecretRef != nil { - out.SecretRef = new(api.LocalObjectReference) - if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { - return err - } - } else { - out.SecretRef = nil - } - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1beta3_RangeAllocation_To_api_RangeAllocation(in *RangeAllocation, out *api.RangeAllocation, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*RangeAllocation))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - out.Range = in.Range - if err := s.Convert(&in.Data, &out.Data, 0); err != nil { - return err - } - return nil -} - -func convert_v1beta3_ReplicationController_To_api_ReplicationController(in *ReplicationController, out *api.ReplicationController, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ReplicationController))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ReplicationControllerSpec_To_api_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1beta3_ReplicationControllerStatus_To_api_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_ReplicationControllerList_To_api_ReplicationControllerList(in *ReplicationControllerList, out *api.ReplicationControllerList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ReplicationControllerList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.ReplicationController, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_ReplicationController_To_api_ReplicationController(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_ReplicationControllerStatus_To_api_ReplicationControllerStatus(in *ReplicationControllerStatus, out *api.ReplicationControllerStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ReplicationControllerStatus))(in) - } - out.Replicas = in.Replicas - out.ObservedGeneration = in.ObservedGeneration - return nil -} - -func convert_v1beta3_ResourceQuota_To_api_ResourceQuota(in *ResourceQuota, out *api.ResourceQuota, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ResourceQuota))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ResourceQuotaSpec_To_api_ResourceQuotaSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1beta3_ResourceQuotaStatus_To_api_ResourceQuotaStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_ResourceQuotaList_To_api_ResourceQuotaList(in *ResourceQuotaList, out *api.ResourceQuotaList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ResourceQuotaList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.ResourceQuota, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_ResourceQuota_To_api_ResourceQuota(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_ResourceQuotaSpec_To_api_ResourceQuotaSpec(in *ResourceQuotaSpec, out *api.ResourceQuotaSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ResourceQuotaSpec))(in) - } - if in.Hard != nil { - out.Hard = make(api.ResourceList) - for key, val := range in.Hard { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Hard[api.ResourceName(key)] = newVal - } - } else { - out.Hard = nil - } - return nil -} - -func convert_v1beta3_ResourceQuotaStatus_To_api_ResourceQuotaStatus(in *ResourceQuotaStatus, out *api.ResourceQuotaStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ResourceQuotaStatus))(in) - } - if in.Hard != nil { - out.Hard = make(api.ResourceList) - for key, val := range in.Hard { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Hard[api.ResourceName(key)] = newVal - } - } else { - out.Hard = nil - } - if in.Used != nil { - out.Used = make(api.ResourceList) - for key, val := range in.Used { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Used[api.ResourceName(key)] = newVal - } - } else { - out.Used = nil - } - return nil -} - -func convert_v1beta3_ResourceRequirements_To_api_ResourceRequirements(in *ResourceRequirements, out *api.ResourceRequirements, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ResourceRequirements))(in) - } - if in.Limits != nil { - out.Limits = make(api.ResourceList) - for key, val := range in.Limits { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Limits[api.ResourceName(key)] = newVal - } - } else { - out.Limits = nil - } - if in.Requests != nil { - out.Requests = make(api.ResourceList) - for key, val := range in.Requests { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Requests[api.ResourceName(key)] = newVal - } - } else { - out.Requests = nil - } - return nil -} - -func convert_v1beta3_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions(in *FSGroupStrategyOptions, out *api.FSGroupStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*FSGroupStrategyOptions))(in) - } - out.Type = api.FSGroupStrategyType(in.Type) - if in.Ranges != nil { - out.Ranges = make([]api.IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := convert_v1beta3_IDRange_To_api_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func convert_v1beta3_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions(in *SupplementalGroupsStrategyOptions, out *api.SupplementalGroupsStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SupplementalGroupsStrategyOptions))(in) - } - out.Type = api.SupplementalGroupsStrategyType(in.Type) - if in.Ranges != nil { - out.Ranges = make([]api.IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := convert_v1beta3_IDRange_To_api_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func convert_v1beta3_IDRange_To_api_IDRange(in *IDRange, out *api.IDRange, s conversion.Scope) error { - out.Min = in.Min - out.Max = in.Max - return nil -} - -func convert_v1beta3_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions(in *RunAsUserStrategyOptions, out *api.RunAsUserStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*RunAsUserStrategyOptions))(in) - } - out.Type = api.RunAsUserStrategyType(in.Type) - if in.UID != nil { - out.UID = new(int64) - *out.UID = *in.UID - } else { - out.UID = nil - } - if in.UIDRangeMin != nil { - out.UIDRangeMin = new(int64) - *out.UIDRangeMin = *in.UIDRangeMin - } else { - out.UIDRangeMin = nil - } - if in.UIDRangeMax != nil { - out.UIDRangeMax = new(int64) - *out.UIDRangeMax = *in.UIDRangeMax - } else { - out.UIDRangeMax = nil - } - return nil -} - -func convert_v1beta3_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions(in *SELinuxContextStrategyOptions, out *api.SELinuxContextStrategyOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SELinuxContextStrategyOptions))(in) - } - out.Type = api.SELinuxContextStrategyType(in.Type) - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(api.SELinuxOptions) - if err := convert_v1beta3_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - return nil -} - -func convert_v1beta3_SELinuxOptions_To_api_SELinuxOptions(in *SELinuxOptions, out *api.SELinuxOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SELinuxOptions))(in) - } - out.User = in.User - out.Role = in.Role - out.Type = in.Type - out.Level = in.Level - return nil -} - -func convert_v1beta3_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Secret))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if in.Data != nil { - out.Data = make(map[string][]uint8) - for key, val := range in.Data { - newVal := []uint8{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Data[key] = newVal - } - } else { - out.Data = nil - } - out.Type = api.SecretType(in.Type) - return nil -} - -func convert_v1beta3_SecretList_To_api_SecretList(in *SecretList, out *api.SecretList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SecretList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.Secret, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_Secret_To_api_Secret(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_SecretVolumeSource_To_api_SecretVolumeSource(in *SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SecretVolumeSource))(in) - } - out.SecretName = in.SecretName - return nil -} - -func convert_v1beta3_SecurityContext_To_api_SecurityContext(in *SecurityContext, out *api.SecurityContext, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SecurityContext))(in) - } - if in.Capabilities != nil { - out.Capabilities = new(api.Capabilities) - if err := convert_v1beta3_Capabilities_To_api_Capabilities(in.Capabilities, out.Capabilities, s); err != nil { - return err - } - } else { - out.Capabilities = nil - } - if in.Privileged != nil { - out.Privileged = new(bool) - *out.Privileged = *in.Privileged - } else { - out.Privileged = nil - } - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(api.SELinuxOptions) - if err := convert_v1beta3_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - if in.RunAsUser != nil { - out.RunAsUser = new(int64) - *out.RunAsUser = *in.RunAsUser - } else { - out.RunAsUser = nil - } - out.RunAsNonRoot = in.RunAsNonRoot - return nil -} - -func convert_v1beta3_SecurityContextConstraints_To_api_SecurityContextConstraints(in *SecurityContextConstraints, out *api.SecurityContextConstraints, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SecurityContextConstraints))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - out.AllowPrivilegedContainer = in.AllowPrivilegedContainer - if in.AllowedCapabilities != nil { - out.AllowedCapabilities = make([]api.Capability, len(in.AllowedCapabilities)) - for i := range in.AllowedCapabilities { - out.AllowedCapabilities[i] = api.Capability(in.AllowedCapabilities[i]) - } - } else { - out.AllowedCapabilities = nil - } - out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin - out.AllowHostNetwork = in.AllowHostNetwork - out.AllowHostPorts = in.AllowHostPorts - out.AllowHostPID = in.AllowHostPID - out.AllowHostIPC = in.AllowHostIPC - if err := convert_v1beta3_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil { - return err - } - if err := convert_v1beta3_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil { - return err - } - if err := convert_v1beta3_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions(&in.FSGroup, &out.FSGroup, s); err != nil { - return err - } - if err := convert_v1beta3_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions(&in.SupplementalGroups, &out.SupplementalGroups, s); err != nil { - return err - } - if in.Users != nil { - out.Users = make([]string, len(in.Users)) - for i := range in.Users { - out.Users[i] = in.Users[i] - } - } else { - out.Users = nil - } - if in.Groups != nil { - out.Groups = make([]string, len(in.Groups)) - for i := range in.Groups { - out.Groups[i] = in.Groups[i] - } - } else { - out.Groups = nil - } - return nil -} - -func convert_v1beta3_SecurityContextConstraintsList_To_api_SecurityContextConstraintsList(in *SecurityContextConstraintsList, out *api.SecurityContextConstraintsList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SecurityContextConstraintsList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.SecurityContextConstraints, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_SecurityContextConstraints_To_api_SecurityContextConstraints(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_SerializedReference_To_api_SerializedReference(in *SerializedReference, out *api.SerializedReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SerializedReference))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.Reference, &out.Reference, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_Service_To_api_Service(in *Service, out *api.Service, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Service))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ServiceSpec_To_api_ServiceSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1beta3_ServiceStatus_To_api_ServiceStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_ServiceAccount_To_api_ServiceAccount(in *ServiceAccount, out *api.ServiceAccount, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ServiceAccount))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if in.Secrets != nil { - out.Secrets = make([]api.ObjectReference, len(in.Secrets)) - for i := range in.Secrets { - if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.Secrets[i], &out.Secrets[i], s); err != nil { - return err - } - } - } else { - out.Secrets = nil - } - if in.ImagePullSecrets != nil { - out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets)) - for i := range in.ImagePullSecrets { - if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { - return err - } - } - } else { - out.ImagePullSecrets = nil - } - return nil -} - -func convert_v1beta3_ServiceAccountList_To_api_ServiceAccountList(in *ServiceAccountList, out *api.ServiceAccountList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ServiceAccountList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.ServiceAccount, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_ServiceAccount_To_api_ServiceAccount(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_ServiceList_To_api_ServiceList(in *ServiceList, out *api.ServiceList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ServiceList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]api.Service, len(in.Items)) - for i := range in.Items { - if err := convert_v1beta3_Service_To_api_Service(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1beta3_ServicePort_To_api_ServicePort(in *ServicePort, out *api.ServicePort, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ServicePort))(in) - } - out.Name = in.Name - out.Protocol = api.Protocol(in.Protocol) - out.Port = in.Port - if err := s.Convert(&in.TargetPort, &out.TargetPort, 0); err != nil { - return err - } - out.NodePort = in.NodePort - return nil -} - -func convert_v1beta3_ServiceStatus_To_api_ServiceStatus(in *ServiceStatus, out *api.ServiceStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ServiceStatus))(in) - } - if err := convert_v1beta3_LoadBalancerStatus_To_api_LoadBalancerStatus(&in.LoadBalancer, &out.LoadBalancer, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_Status_To_api_Status(in *Status, out *api.Status, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Status))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - out.Status = in.Status - out.Message = in.Message - out.Reason = api.StatusReason(in.Reason) - if in.Details != nil { - out.Details = new(api.StatusDetails) - if err := convert_v1beta3_StatusDetails_To_api_StatusDetails(in.Details, out.Details, s); err != nil { - return err - } - } else { - out.Details = nil - } - out.Code = in.Code - return nil -} - -func convert_v1beta3_TCPSocketAction_To_api_TCPSocketAction(in *TCPSocketAction, out *api.TCPSocketAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*TCPSocketAction))(in) - } - if err := s.Convert(&in.Port, &out.Port, 0); err != nil { - return err - } - return nil -} - -func convert_v1beta3_TypeMeta_To_api_TypeMeta(in *TypeMeta, out *api.TypeMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*TypeMeta))(in) - } - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil -} - -func convert_v1beta3_Volume_To_api_Volume(in *Volume, out *api.Volume, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Volume))(in) - } - out.Name = in.Name - if err := convert_v1beta3_VolumeSource_To_api_VolumeSource(&in.VolumeSource, &out.VolumeSource, s); err != nil { - return err - } - return nil -} - -func convert_v1beta3_VolumeMount_To_api_VolumeMount(in *VolumeMount, out *api.VolumeMount, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*VolumeMount))(in) - } - out.Name = in.Name - out.ReadOnly = in.ReadOnly - out.MountPath = in.MountPath - return nil -} - -func init() { - err := api.Scheme.AddGeneratedConversionFuncs( - convert_api_AWSElasticBlockStoreVolumeSource_To_v1beta3_AWSElasticBlockStoreVolumeSource, - convert_api_Binding_To_v1beta3_Binding, - convert_api_Capabilities_To_v1beta3_Capabilities, - convert_api_CephFSVolumeSource_To_v1beta3_CephFSVolumeSource, - convert_api_CinderVolumeSource_To_v1beta3_CinderVolumeSource, - convert_api_ComponentCondition_To_v1beta3_ComponentCondition, - convert_api_ComponentStatusList_To_v1beta3_ComponentStatusList, - convert_api_ComponentStatus_To_v1beta3_ComponentStatus, - convert_api_ContainerPort_To_v1beta3_ContainerPort, - convert_api_ContainerStateRunning_To_v1beta3_ContainerStateRunning, - convert_api_ContainerStateWaiting_To_v1beta3_ContainerStateWaiting, - convert_api_ContainerStatus_To_v1beta3_ContainerStatus, - convert_api_DeleteOptions_To_v1beta3_DeleteOptions, - convert_api_DownwardAPIVolumeFile_To_v1beta3_DownwardAPIVolumeFile, - convert_api_DownwardAPIVolumeSource_To_v1beta3_DownwardAPIVolumeSource, - convert_api_EmptyDirVolumeSource_To_v1beta3_EmptyDirVolumeSource, - convert_api_EndpointAddress_To_v1beta3_EndpointAddress, - convert_api_EndpointPort_To_v1beta3_EndpointPort, - convert_api_EndpointSubset_To_v1beta3_EndpointSubset, - convert_api_EndpointsList_To_v1beta3_EndpointsList, - convert_api_Endpoints_To_v1beta3_Endpoints, - convert_api_EnvVarSource_To_v1beta3_EnvVarSource, - convert_api_EnvVar_To_v1beta3_EnvVar, - convert_api_EventList_To_v1beta3_EventList, - convert_api_EventSource_To_v1beta3_EventSource, - convert_api_Event_To_v1beta3_Event, - convert_api_ExecAction_To_v1beta3_ExecAction, - convert_api_FSGroupStrategyOptions_To_v1beta3_FSGroupStrategyOptions, - convert_api_GCEPersistentDiskVolumeSource_To_v1beta3_GCEPersistentDiskVolumeSource, - convert_api_GitRepoVolumeSource_To_v1beta3_GitRepoVolumeSource, - convert_api_GlusterfsVolumeSource_To_v1beta3_GlusterfsVolumeSource, - convert_api_HTTPGetAction_To_v1beta3_HTTPGetAction, - convert_api_Handler_To_v1beta3_Handler, - convert_api_HostPathVolumeSource_To_v1beta3_HostPathVolumeSource, - convert_api_IDRange_To_v1beta3_IDRange, - convert_api_ISCSIVolumeSource_To_v1beta3_ISCSIVolumeSource, - convert_api_Lifecycle_To_v1beta3_Lifecycle, - convert_api_LimitRangeItem_To_v1beta3_LimitRangeItem, - convert_api_LimitRangeList_To_v1beta3_LimitRangeList, - convert_api_LimitRangeSpec_To_v1beta3_LimitRangeSpec, - convert_api_LimitRange_To_v1beta3_LimitRange, - convert_api_ListMeta_To_v1beta3_ListMeta, - convert_api_ListOptions_To_v1beta3_ListOptions, - convert_api_List_To_v1beta3_List, - convert_api_LoadBalancerIngress_To_v1beta3_LoadBalancerIngress, - convert_api_LoadBalancerStatus_To_v1beta3_LoadBalancerStatus, - convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference, - convert_api_NFSVolumeSource_To_v1beta3_NFSVolumeSource, - convert_api_NamespaceList_To_v1beta3_NamespaceList, - convert_api_NamespaceSpec_To_v1beta3_NamespaceSpec, - convert_api_NamespaceStatus_To_v1beta3_NamespaceStatus, - convert_api_Namespace_To_v1beta3_Namespace, - convert_api_NodeAddress_To_v1beta3_NodeAddress, - convert_api_NodeCondition_To_v1beta3_NodeCondition, - convert_api_NodeList_To_v1beta3_NodeList, - convert_api_NodeSpec_To_v1beta3_NodeSpec, - convert_api_NodeStatus_To_v1beta3_NodeStatus, - convert_api_NodeSystemInfo_To_v1beta3_NodeSystemInfo, - convert_api_Node_To_v1beta3_Node, - convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector, - convert_api_ObjectMeta_To_v1beta3_ObjectMeta, - convert_api_ObjectReference_To_v1beta3_ObjectReference, - convert_api_PersistentVolumeClaimList_To_v1beta3_PersistentVolumeClaimList, - convert_api_PersistentVolumeClaimSpec_To_v1beta3_PersistentVolumeClaimSpec, - convert_api_PersistentVolumeClaimStatus_To_v1beta3_PersistentVolumeClaimStatus, - convert_api_PersistentVolumeClaimVolumeSource_To_v1beta3_PersistentVolumeClaimVolumeSource, - convert_api_PersistentVolumeClaim_To_v1beta3_PersistentVolumeClaim, - convert_api_PersistentVolumeList_To_v1beta3_PersistentVolumeList, - convert_api_PersistentVolumeSource_To_v1beta3_PersistentVolumeSource, - convert_api_PersistentVolumeSpec_To_v1beta3_PersistentVolumeSpec, - convert_api_PersistentVolumeStatus_To_v1beta3_PersistentVolumeStatus, - convert_api_PersistentVolume_To_v1beta3_PersistentVolume, - convert_api_PodCondition_To_v1beta3_PodCondition, - convert_api_PodExecOptions_To_v1beta3_PodExecOptions, - convert_api_PodList_To_v1beta3_PodList, - convert_api_PodLogOptions_To_v1beta3_PodLogOptions, - convert_api_PodProxyOptions_To_v1beta3_PodProxyOptions, - convert_api_PodStatusResult_To_v1beta3_PodStatusResult, - convert_api_PodStatus_To_v1beta3_PodStatus, - convert_api_PodTemplateList_To_v1beta3_PodTemplateList, - convert_api_PodTemplateSpec_To_v1beta3_PodTemplateSpec, - convert_api_PodTemplate_To_v1beta3_PodTemplate, - convert_api_Pod_To_v1beta3_Pod, - convert_api_Probe_To_v1beta3_Probe, - convert_api_RBDVolumeSource_To_v1beta3_RBDVolumeSource, - convert_api_RangeAllocation_To_v1beta3_RangeAllocation, - convert_api_ReplicationControllerList_To_v1beta3_ReplicationControllerList, - convert_api_ReplicationControllerStatus_To_v1beta3_ReplicationControllerStatus, - convert_api_ReplicationController_To_v1beta3_ReplicationController, - convert_api_ResourceQuotaList_To_v1beta3_ResourceQuotaList, - convert_api_ResourceQuotaSpec_To_v1beta3_ResourceQuotaSpec, - convert_api_ResourceQuotaStatus_To_v1beta3_ResourceQuotaStatus, - convert_api_ResourceQuota_To_v1beta3_ResourceQuota, - convert_api_ResourceRequirements_To_v1beta3_ResourceRequirements, - convert_api_RunAsUserStrategyOptions_To_v1beta3_RunAsUserStrategyOptions, - convert_api_SELinuxContextStrategyOptions_To_v1beta3_SELinuxContextStrategyOptions, - convert_api_SELinuxOptions_To_v1beta3_SELinuxOptions, - convert_api_SecretList_To_v1beta3_SecretList, - convert_api_SecretVolumeSource_To_v1beta3_SecretVolumeSource, - convert_api_Secret_To_v1beta3_Secret, - convert_api_SecurityContextConstraintsList_To_v1beta3_SecurityContextConstraintsList, - convert_api_SecurityContextConstraints_To_v1beta3_SecurityContextConstraints, - convert_api_SecurityContext_To_v1beta3_SecurityContext, - convert_api_SerializedReference_To_v1beta3_SerializedReference, - convert_api_ServiceAccountList_To_v1beta3_ServiceAccountList, - convert_api_ServiceAccount_To_v1beta3_ServiceAccount, - convert_api_ServiceList_To_v1beta3_ServiceList, - convert_api_ServicePort_To_v1beta3_ServicePort, - convert_api_ServiceStatus_To_v1beta3_ServiceStatus, - convert_api_Service_To_v1beta3_Service, - convert_api_Status_To_v1beta3_Status, - convert_api_SupplementalGroupsStrategyOptions_To_v1beta3_SupplementalGroupsStrategyOptions, - convert_api_TCPSocketAction_To_v1beta3_TCPSocketAction, - convert_api_TypeMeta_To_v1beta3_TypeMeta, - convert_api_VolumeMount_To_v1beta3_VolumeMount, - convert_api_Volume_To_v1beta3_Volume, - convert_v1beta3_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource, - convert_v1beta3_Binding_To_api_Binding, - convert_v1beta3_Capabilities_To_api_Capabilities, - convert_v1beta3_CephFSVolumeSource_To_api_CephFSVolumeSource, - convert_v1beta3_CinderVolumeSource_To_api_CinderVolumeSource, - convert_v1beta3_ComponentCondition_To_api_ComponentCondition, - convert_v1beta3_ComponentStatusList_To_api_ComponentStatusList, - convert_v1beta3_ComponentStatus_To_api_ComponentStatus, - convert_v1beta3_ContainerPort_To_api_ContainerPort, - convert_v1beta3_ContainerStateRunning_To_api_ContainerStateRunning, - convert_v1beta3_ContainerStateWaiting_To_api_ContainerStateWaiting, - convert_v1beta3_ContainerStatus_To_api_ContainerStatus, - convert_v1beta3_DeleteOptions_To_api_DeleteOptions, - convert_v1beta3_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile, - convert_v1beta3_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource, - convert_v1beta3_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource, - convert_v1beta3_EndpointAddress_To_api_EndpointAddress, - convert_v1beta3_EndpointPort_To_api_EndpointPort, - convert_v1beta3_EndpointSubset_To_api_EndpointSubset, - convert_v1beta3_EndpointsList_To_api_EndpointsList, - convert_v1beta3_Endpoints_To_api_Endpoints, - convert_v1beta3_EnvVarSource_To_api_EnvVarSource, - convert_v1beta3_EnvVar_To_api_EnvVar, - convert_v1beta3_EventList_To_api_EventList, - convert_v1beta3_EventSource_To_api_EventSource, - convert_v1beta3_Event_To_api_Event, - convert_v1beta3_ExecAction_To_api_ExecAction, - convert_v1beta3_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions, - convert_v1beta3_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource, - convert_v1beta3_GitRepoVolumeSource_To_api_GitRepoVolumeSource, - convert_v1beta3_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource, - convert_v1beta3_HTTPGetAction_To_api_HTTPGetAction, - convert_v1beta3_Handler_To_api_Handler, - convert_v1beta3_HostPathVolumeSource_To_api_HostPathVolumeSource, - convert_v1beta3_IDRange_To_api_IDRange, - convert_v1beta3_ISCSIVolumeSource_To_api_ISCSIVolumeSource, - convert_v1beta3_Lifecycle_To_api_Lifecycle, - convert_v1beta3_LimitRangeItem_To_api_LimitRangeItem, - convert_v1beta3_LimitRangeList_To_api_LimitRangeList, - convert_v1beta3_LimitRangeSpec_To_api_LimitRangeSpec, - convert_v1beta3_LimitRange_To_api_LimitRange, - convert_v1beta3_ListMeta_To_api_ListMeta, - convert_v1beta3_ListOptions_To_api_ListOptions, - convert_v1beta3_List_To_api_List, - convert_v1beta3_LoadBalancerIngress_To_api_LoadBalancerIngress, - convert_v1beta3_LoadBalancerStatus_To_api_LoadBalancerStatus, - convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference, - convert_v1beta3_NFSVolumeSource_To_api_NFSVolumeSource, - convert_v1beta3_NamespaceList_To_api_NamespaceList, - convert_v1beta3_NamespaceSpec_To_api_NamespaceSpec, - convert_v1beta3_NamespaceStatus_To_api_NamespaceStatus, - convert_v1beta3_Namespace_To_api_Namespace, - convert_v1beta3_NodeAddress_To_api_NodeAddress, - convert_v1beta3_NodeCondition_To_api_NodeCondition, - convert_v1beta3_NodeList_To_api_NodeList, - convert_v1beta3_NodeSpec_To_api_NodeSpec, - convert_v1beta3_NodeStatus_To_api_NodeStatus, - convert_v1beta3_NodeSystemInfo_To_api_NodeSystemInfo, - convert_v1beta3_Node_To_api_Node, - convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector, - convert_v1beta3_ObjectMeta_To_api_ObjectMeta, - convert_v1beta3_ObjectReference_To_api_ObjectReference, - convert_v1beta3_PersistentVolumeClaimList_To_api_PersistentVolumeClaimList, - convert_v1beta3_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec, - convert_v1beta3_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus, - convert_v1beta3_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource, - convert_v1beta3_PersistentVolumeClaim_To_api_PersistentVolumeClaim, - convert_v1beta3_PersistentVolumeList_To_api_PersistentVolumeList, - convert_v1beta3_PersistentVolumeSource_To_api_PersistentVolumeSource, - convert_v1beta3_PersistentVolumeSpec_To_api_PersistentVolumeSpec, - convert_v1beta3_PersistentVolumeStatus_To_api_PersistentVolumeStatus, - convert_v1beta3_PersistentVolume_To_api_PersistentVolume, - convert_v1beta3_PodCondition_To_api_PodCondition, - convert_v1beta3_PodExecOptions_To_api_PodExecOptions, - convert_v1beta3_PodList_To_api_PodList, - convert_v1beta3_PodLogOptions_To_api_PodLogOptions, - convert_v1beta3_PodProxyOptions_To_api_PodProxyOptions, - convert_v1beta3_PodStatusResult_To_api_PodStatusResult, - convert_v1beta3_PodStatus_To_api_PodStatus, - convert_v1beta3_PodTemplateList_To_api_PodTemplateList, - convert_v1beta3_PodTemplateSpec_To_api_PodTemplateSpec, - convert_v1beta3_PodTemplate_To_api_PodTemplate, - convert_v1beta3_Pod_To_api_Pod, - convert_v1beta3_Probe_To_api_Probe, - convert_v1beta3_RBDVolumeSource_To_api_RBDVolumeSource, - convert_v1beta3_RangeAllocation_To_api_RangeAllocation, - convert_v1beta3_ReplicationControllerList_To_api_ReplicationControllerList, - convert_v1beta3_ReplicationControllerStatus_To_api_ReplicationControllerStatus, - convert_v1beta3_ReplicationController_To_api_ReplicationController, - convert_v1beta3_ResourceQuotaList_To_api_ResourceQuotaList, - convert_v1beta3_ResourceQuotaSpec_To_api_ResourceQuotaSpec, - convert_v1beta3_ResourceQuotaStatus_To_api_ResourceQuotaStatus, - convert_v1beta3_ResourceQuota_To_api_ResourceQuota, - convert_v1beta3_ResourceRequirements_To_api_ResourceRequirements, - convert_v1beta3_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions, - convert_v1beta3_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions, - convert_v1beta3_SELinuxOptions_To_api_SELinuxOptions, - convert_v1beta3_SecretList_To_api_SecretList, - convert_v1beta3_SecretVolumeSource_To_api_SecretVolumeSource, - convert_v1beta3_Secret_To_api_Secret, - convert_v1beta3_SecurityContextConstraintsList_To_api_SecurityContextConstraintsList, - convert_v1beta3_SecurityContextConstraints_To_api_SecurityContextConstraints, - convert_v1beta3_SecurityContext_To_api_SecurityContext, - convert_v1beta3_SerializedReference_To_api_SerializedReference, - convert_v1beta3_ServiceAccountList_To_api_ServiceAccountList, - convert_v1beta3_ServiceAccount_To_api_ServiceAccount, - convert_v1beta3_ServiceList_To_api_ServiceList, - convert_v1beta3_ServicePort_To_api_ServicePort, - convert_v1beta3_ServiceStatus_To_api_ServiceStatus, - convert_v1beta3_Service_To_api_Service, - convert_v1beta3_Status_To_api_Status, - convert_v1beta3_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions, - convert_v1beta3_TCPSocketAction_To_api_TCPSocketAction, - convert_v1beta3_TypeMeta_To_api_TypeMeta, - convert_v1beta3_VolumeMount_To_api_VolumeMount, - convert_v1beta3_Volume_To_api_Volume, - ) - if err != nil { - // If one of the conversion functions is malformed, detect it immediately. - panic(err) - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_test.go deleted file mode 100644 index a4c3aabffac8..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_test.go +++ /dev/null @@ -1,139 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 v1beta3_test - -import ( - "testing" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/resource" - versioned "k8s.io/kubernetes/pkg/api/v1beta3" -) - -func TestResourceQuotaStatusConversion(t *testing.T) { - // should serialize as "0" - expected := resource.NewQuantity(int64(0), resource.DecimalSI) - if "0" != expected.String() { - t.Errorf("Expected: 0, Actual: %v, do not require units", expected.String()) - } - - parsed := resource.MustParse("0") - if "0" != parsed.String() { - t.Errorf("Expected: 0, Actual: %v, do not require units", parsed.String()) - } - - quota := &api.ResourceQuota{} - quota.Status = api.ResourceQuotaStatus{} - quota.Status.Hard = api.ResourceList{} - quota.Status.Used = api.ResourceList{} - quota.Status.Hard[api.ResourcePods] = *expected - - // round-trip the object - data, _ := versioned.Codec.Encode(quota) - object, _ := versioned.Codec.Decode(data) - after := object.(*api.ResourceQuota) - actualQuantity := after.Status.Hard[api.ResourcePods] - actual := &actualQuantity - - // should be "0", but was "0m" - if expected.String() != actual.String() { - t.Errorf("Expected %v, Actual %v", expected.String(), actual.String()) - } -} - -func TestNodeConversion(t *testing.T) { - obj, err := versioned.Codec.Decode([]byte(`{"kind":"Minion","apiVersion":"v1beta3"}`)) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if _, ok := obj.(*api.Node); !ok { - t.Errorf("unexpected type: %#v", obj) - } - - obj, err = versioned.Codec.Decode([]byte(`{"kind":"MinionList","apiVersion":"v1beta3"}`)) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if _, ok := obj.(*api.NodeList); !ok { - t.Errorf("unexpected type: %#v", obj) - } - - obj = &api.Node{} - if err := versioned.Codec.DecodeInto([]byte(`{"kind":"Minion","apiVersion":"v1beta3"}`), obj); err != nil { - t.Fatalf("unexpected error: %v", err) - } -} - -func TestBadSecurityContextConversion(t *testing.T) { - priv := false - testCases := map[string]struct { - c *versioned.Container - err string - }{ - // this use case must use true for the container and false for the sc. Otherwise the defaulter - // will assume privileged was left undefined (since it is the default value) and copy the - // sc setting upwards - "mismatched privileged": { - c: &versioned.Container{ - Privileged: true, - SecurityContext: &versioned.SecurityContext{ - Privileged: &priv, - }, - }, - err: "container privileged settings do not match security context settings, cannot convert", - }, - "mismatched caps add": { - c: &versioned.Container{ - Capabilities: versioned.Capabilities{ - Add: []versioned.Capability{"foo"}, - }, - SecurityContext: &versioned.SecurityContext{ - Capabilities: &versioned.Capabilities{ - Add: []versioned.Capability{"bar"}, - }, - }, - }, - err: "container capability settings do not match security context settings, cannot convert", - }, - "mismatched caps drop": { - c: &versioned.Container{ - Capabilities: versioned.Capabilities{ - Drop: []versioned.Capability{"foo"}, - }, - SecurityContext: &versioned.SecurityContext{ - Capabilities: &versioned.Capabilities{ - Drop: []versioned.Capability{"bar"}, - }, - }, - }, - err: "container capability settings do not match security context settings, cannot convert", - }, - } - - for k, v := range testCases { - got := api.Container{} - err := api.Scheme.Convert(v.c, &got) - if err == nil { - t.Errorf("expected error for case %s but got none", k) - } else { - if err.Error() != v.err { - t.Errorf("unexpected error for case %s. Expected: %s but got: %s", k, v.err, err.Error()) - } - } - } - -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_volumesource_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_volumesource_test.go deleted file mode 100644 index 02393ad4227d..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_volumesource_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package v1beta3 - -import ( - "testing" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/conversion" -) - -func TestAPItoV1Beta3VolumeSourceConversion(t *testing.T) { - c := conversion.NewConverter() - c.Debug = t - - if err := c.RegisterConversionFunc(convert_api_VolumeSource_To_v1beta3_VolumeSource); err != nil { - t.Fatalf("unexpected error %v", err) - } - - in := api.VolumeSource{ - DownwardAPI: &api.DownwardAPIVolumeSource{ - Items: []api.DownwardAPIVolumeFile{ - { - Path: "./test/api-to-v1beta3/conversion", - }, - }, - }, - } - out := VolumeSource{} - - if err := c.Convert(&in, &out, 0, nil); err != nil { - t.Fatalf("unexpected error %v", err) - } - if e, a := in.DownwardAPI.Items[0].Path, out.Metadata.Items[0].Name; e != a { - t.Errorf("expected %v, got %v", e, a) - } -} - -func TestV1Beta3toAPIVolumeSourceConversion(t *testing.T) { - c := conversion.NewConverter() - c.Debug = t - - if err := c.RegisterConversionFunc(convert_v1beta3_VolumeSource_To_api_VolumeSource); err != nil { - t.Fatalf("unexpected error %v", err) - } - - in := VolumeSource{ - Metadata: &MetadataVolumeSource{ - Items: []MetadataFile{ - { - Name: "./test/v1beta3-to-api/conversion", - }, - }, - }, - } - out := api.VolumeSource{} - - if err := c.Convert(&in, &out, 0, nil); err != nil { - t.Fatalf("unexpected error %v", err) - } - if e, a := in.Metadata.Items[0].Name, out.DownwardAPI.Items[0].Path; e != a { - t.Errorf("expected %v, got %v", e, a) - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go deleted file mode 100644 index 3d2c8d2e6489..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go +++ /dev/null @@ -1,2529 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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. -*/ - -// DO NOT EDIT. THIS FILE IS AUTO-GENERATED BY $KUBEROOT/hack/update-generated-deep-copies.sh. - -package v1beta3 - -import ( - time "time" - - api "k8s.io/kubernetes/pkg/api" - resource "k8s.io/kubernetes/pkg/api/resource" - conversion "k8s.io/kubernetes/pkg/conversion" - runtime "k8s.io/kubernetes/pkg/runtime" - util "k8s.io/kubernetes/pkg/util" - inf "speter.net/go/exp/math/dec/inf" -) - -func deepCopy_resource_Quantity(in resource.Quantity, out *resource.Quantity, c *conversion.Cloner) error { - if in.Amount != nil { - if newVal, err := c.DeepCopy(in.Amount); err != nil { - return err - } else if newVal == nil { - out.Amount = nil - } else { - out.Amount = newVal.(*inf.Dec) - } - } else { - out.Amount = nil - } - out.Format = in.Format - return nil -} - -func deepCopy_v1beta3_AWSElasticBlockStoreVolumeSource(in AWSElasticBlockStoreVolumeSource, out *AWSElasticBlockStoreVolumeSource, c *conversion.Cloner) error { - out.VolumeID = in.VolumeID - out.FSType = in.FSType - out.Partition = in.Partition - out.ReadOnly = in.ReadOnly - return nil -} - -func deepCopy_v1beta3_Binding(in Binding, out *Binding, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectReference(in.Target, &out.Target, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_Capabilities(in Capabilities, out *Capabilities, c *conversion.Cloner) error { - if in.Add != nil { - out.Add = make([]Capability, len(in.Add)) - for i := range in.Add { - out.Add[i] = in.Add[i] - } - } else { - out.Add = nil - } - if in.Drop != nil { - out.Drop = make([]Capability, len(in.Drop)) - for i := range in.Drop { - out.Drop[i] = in.Drop[i] - } - } else { - out.Drop = nil - } - return nil -} - -func deepCopy_v1beta3_CephFSVolumeSource(in CephFSVolumeSource, out *CephFSVolumeSource, c *conversion.Cloner) error { - if in.Monitors != nil { - out.Monitors = make([]string, len(in.Monitors)) - for i := range in.Monitors { - out.Monitors[i] = in.Monitors[i] - } - } else { - out.Monitors = nil - } - out.User = in.User - out.SecretFile = in.SecretFile - if in.SecretRef != nil { - out.SecretRef = new(LocalObjectReference) - if err := deepCopy_v1beta3_LocalObjectReference(*in.SecretRef, out.SecretRef, c); err != nil { - return err - } - } else { - out.SecretRef = nil - } - out.ReadOnly = in.ReadOnly - return nil -} - -func deepCopy_v1beta3_CinderVolumeSource(in CinderVolumeSource, out *CinderVolumeSource, c *conversion.Cloner) error { - out.VolumeID = in.VolumeID - out.FSType = in.FSType - out.ReadOnly = in.ReadOnly - return nil -} - -func deepCopy_v1beta3_ComponentCondition(in ComponentCondition, out *ComponentCondition, c *conversion.Cloner) error { - out.Type = in.Type - out.Status = in.Status - out.Message = in.Message - out.Error = in.Error - return nil -} - -func deepCopy_v1beta3_ComponentStatus(in ComponentStatus, out *ComponentStatus, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if in.Conditions != nil { - out.Conditions = make([]ComponentCondition, len(in.Conditions)) - for i := range in.Conditions { - if err := deepCopy_v1beta3_ComponentCondition(in.Conditions[i], &out.Conditions[i], c); err != nil { - return err - } - } - } else { - out.Conditions = nil - } - return nil -} - -func deepCopy_v1beta3_ComponentStatusList(in ComponentStatusList, out *ComponentStatusList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]ComponentStatus, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_ComponentStatus(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_Container(in Container, out *Container, c *conversion.Cloner) error { - out.Name = in.Name - out.Image = in.Image - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } else { - out.Command = nil - } - if in.Args != nil { - out.Args = make([]string, len(in.Args)) - for i := range in.Args { - out.Args[i] = in.Args[i] - } - } else { - out.Args = nil - } - out.WorkingDir = in.WorkingDir - if in.Ports != nil { - out.Ports = make([]ContainerPort, len(in.Ports)) - for i := range in.Ports { - if err := deepCopy_v1beta3_ContainerPort(in.Ports[i], &out.Ports[i], c); err != nil { - return err - } - } - } else { - out.Ports = nil - } - if in.Env != nil { - out.Env = make([]EnvVar, len(in.Env)) - for i := range in.Env { - if err := deepCopy_v1beta3_EnvVar(in.Env[i], &out.Env[i], c); err != nil { - return err - } - } - } else { - out.Env = nil - } - if err := deepCopy_v1beta3_ResourceRequirements(in.Resources, &out.Resources, c); err != nil { - return err - } - if in.VolumeMounts != nil { - out.VolumeMounts = make([]VolumeMount, len(in.VolumeMounts)) - for i := range in.VolumeMounts { - if err := deepCopy_v1beta3_VolumeMount(in.VolumeMounts[i], &out.VolumeMounts[i], c); err != nil { - return err - } - } - } else { - out.VolumeMounts = nil - } - if in.LivenessProbe != nil { - out.LivenessProbe = new(Probe) - if err := deepCopy_v1beta3_Probe(*in.LivenessProbe, out.LivenessProbe, c); err != nil { - return err - } - } else { - out.LivenessProbe = nil - } - if in.ReadinessProbe != nil { - out.ReadinessProbe = new(Probe) - if err := deepCopy_v1beta3_Probe(*in.ReadinessProbe, out.ReadinessProbe, c); err != nil { - return err - } - } else { - out.ReadinessProbe = nil - } - if in.Lifecycle != nil { - out.Lifecycle = new(Lifecycle) - if err := deepCopy_v1beta3_Lifecycle(*in.Lifecycle, out.Lifecycle, c); err != nil { - return err - } - } else { - out.Lifecycle = nil - } - out.TerminationMessagePath = in.TerminationMessagePath - out.Privileged = in.Privileged - out.ImagePullPolicy = in.ImagePullPolicy - if err := deepCopy_v1beta3_Capabilities(in.Capabilities, &out.Capabilities, c); err != nil { - return err - } - if in.SecurityContext != nil { - out.SecurityContext = new(SecurityContext) - if err := deepCopy_v1beta3_SecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil { - return err - } - } else { - out.SecurityContext = nil - } - out.Stdin = in.Stdin - out.TTY = in.TTY - return nil -} - -func deepCopy_v1beta3_ContainerPort(in ContainerPort, out *ContainerPort, c *conversion.Cloner) error { - out.Name = in.Name - out.HostPort = in.HostPort - out.ContainerPort = in.ContainerPort - out.Protocol = in.Protocol - out.HostIP = in.HostIP - return nil -} - -func deepCopy_v1beta3_ContainerState(in ContainerState, out *ContainerState, c *conversion.Cloner) error { - if in.Waiting != nil { - out.Waiting = new(ContainerStateWaiting) - if err := deepCopy_v1beta3_ContainerStateWaiting(*in.Waiting, out.Waiting, c); err != nil { - return err - } - } else { - out.Waiting = nil - } - if in.Running != nil { - out.Running = new(ContainerStateRunning) - if err := deepCopy_v1beta3_ContainerStateRunning(*in.Running, out.Running, c); err != nil { - return err - } - } else { - out.Running = nil - } - if in.Termination != nil { - out.Termination = new(ContainerStateTerminated) - if err := deepCopy_v1beta3_ContainerStateTerminated(*in.Termination, out.Termination, c); err != nil { - return err - } - } else { - out.Termination = nil - } - return nil -} - -func deepCopy_v1beta3_ContainerStateRunning(in ContainerStateRunning, out *ContainerStateRunning, c *conversion.Cloner) error { - if err := deepCopy_util_Time(in.StartedAt, &out.StartedAt, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_ContainerStateTerminated(in ContainerStateTerminated, out *ContainerStateTerminated, c *conversion.Cloner) error { - out.ExitCode = in.ExitCode - out.Signal = in.Signal - out.Reason = in.Reason - out.Message = in.Message - if err := deepCopy_util_Time(in.StartedAt, &out.StartedAt, c); err != nil { - return err - } - if err := deepCopy_util_Time(in.FinishedAt, &out.FinishedAt, c); err != nil { - return err - } - out.ContainerID = in.ContainerID - return nil -} - -func deepCopy_v1beta3_ContainerStateWaiting(in ContainerStateWaiting, out *ContainerStateWaiting, c *conversion.Cloner) error { - out.Reason = in.Reason - return nil -} - -func deepCopy_v1beta3_ContainerStatus(in ContainerStatus, out *ContainerStatus, c *conversion.Cloner) error { - out.Name = in.Name - if err := deepCopy_v1beta3_ContainerState(in.State, &out.State, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ContainerState(in.LastTerminationState, &out.LastTerminationState, c); err != nil { - return err - } - out.Ready = in.Ready - out.RestartCount = in.RestartCount - out.Image = in.Image - out.ImageID = in.ImageID - out.ContainerID = in.ContainerID - return nil -} - -func deepCopy_v1beta3_DeleteOptions(in DeleteOptions, out *DeleteOptions, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if in.GracePeriodSeconds != nil { - out.GracePeriodSeconds = new(int64) - *out.GracePeriodSeconds = *in.GracePeriodSeconds - } else { - out.GracePeriodSeconds = nil - } - return nil -} - -func deepCopy_v1beta3_DownwardAPIVolumeFile(in DownwardAPIVolumeFile, out *DownwardAPIVolumeFile, c *conversion.Cloner) error { - out.Path = in.Path - if err := deepCopy_v1beta3_ObjectFieldSelector(in.FieldRef, &out.FieldRef, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_DownwardAPIVolumeSource(in DownwardAPIVolumeSource, out *DownwardAPIVolumeSource, c *conversion.Cloner) error { - if in.Items != nil { - out.Items = make([]DownwardAPIVolumeFile, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_DownwardAPIVolumeFile(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_EmptyDirVolumeSource(in EmptyDirVolumeSource, out *EmptyDirVolumeSource, c *conversion.Cloner) error { - out.Medium = in.Medium - return nil -} - -func deepCopy_v1beta3_EndpointAddress(in EndpointAddress, out *EndpointAddress, c *conversion.Cloner) error { - out.IP = in.IP - if in.TargetRef != nil { - out.TargetRef = new(ObjectReference) - if err := deepCopy_v1beta3_ObjectReference(*in.TargetRef, out.TargetRef, c); err != nil { - return err - } - } else { - out.TargetRef = nil - } - return nil -} - -func deepCopy_v1beta3_EndpointPort(in EndpointPort, out *EndpointPort, c *conversion.Cloner) error { - out.Name = in.Name - out.Port = in.Port - out.Protocol = in.Protocol - return nil -} - -func deepCopy_v1beta3_EndpointSubset(in EndpointSubset, out *EndpointSubset, c *conversion.Cloner) error { - if in.Addresses != nil { - out.Addresses = make([]EndpointAddress, len(in.Addresses)) - for i := range in.Addresses { - if err := deepCopy_v1beta3_EndpointAddress(in.Addresses[i], &out.Addresses[i], c); err != nil { - return err - } - } - } else { - out.Addresses = nil - } - if in.Ports != nil { - out.Ports = make([]EndpointPort, len(in.Ports)) - for i := range in.Ports { - if err := deepCopy_v1beta3_EndpointPort(in.Ports[i], &out.Ports[i], c); err != nil { - return err - } - } - } else { - out.Ports = nil - } - return nil -} - -func deepCopy_v1beta3_Endpoints(in Endpoints, out *Endpoints, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if in.Subsets != nil { - out.Subsets = make([]EndpointSubset, len(in.Subsets)) - for i := range in.Subsets { - if err := deepCopy_v1beta3_EndpointSubset(in.Subsets[i], &out.Subsets[i], c); err != nil { - return err - } - } - } else { - out.Subsets = nil - } - return nil -} - -func deepCopy_v1beta3_EndpointsList(in EndpointsList, out *EndpointsList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Endpoints, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_Endpoints(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_EnvVar(in EnvVar, out *EnvVar, c *conversion.Cloner) error { - out.Name = in.Name - out.Value = in.Value - if in.ValueFrom != nil { - out.ValueFrom = new(EnvVarSource) - if err := deepCopy_v1beta3_EnvVarSource(*in.ValueFrom, out.ValueFrom, c); err != nil { - return err - } - } else { - out.ValueFrom = nil - } - return nil -} - -func deepCopy_v1beta3_EnvVarSource(in EnvVarSource, out *EnvVarSource, c *conversion.Cloner) error { - if in.FieldRef != nil { - out.FieldRef = new(ObjectFieldSelector) - if err := deepCopy_v1beta3_ObjectFieldSelector(*in.FieldRef, out.FieldRef, c); err != nil { - return err - } - } else { - out.FieldRef = nil - } - return nil -} - -func deepCopy_v1beta3_Event(in Event, out *Event, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectReference(in.InvolvedObject, &out.InvolvedObject, c); err != nil { - return err - } - out.Reason = in.Reason - out.Message = in.Message - if err := deepCopy_v1beta3_EventSource(in.Source, &out.Source, c); err != nil { - return err - } - if err := deepCopy_util_Time(in.FirstTimestamp, &out.FirstTimestamp, c); err != nil { - return err - } - if err := deepCopy_util_Time(in.LastTimestamp, &out.LastTimestamp, c); err != nil { - return err - } - out.Count = in.Count - return nil -} - -func deepCopy_v1beta3_EventList(in EventList, out *EventList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Event, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_Event(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_EventSource(in EventSource, out *EventSource, c *conversion.Cloner) error { - out.Component = in.Component - out.Host = in.Host - return nil -} - -func deepCopy_v1beta3_ExecAction(in ExecAction, out *ExecAction, c *conversion.Cloner) error { - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } else { - out.Command = nil - } - return nil -} - -func deepCopy_v1beta3_GCEPersistentDiskVolumeSource(in GCEPersistentDiskVolumeSource, out *GCEPersistentDiskVolumeSource, c *conversion.Cloner) error { - out.PDName = in.PDName - out.FSType = in.FSType - out.Partition = in.Partition - out.ReadOnly = in.ReadOnly - return nil -} - -func deepCopy_v1beta3_GitRepoVolumeSource(in GitRepoVolumeSource, out *GitRepoVolumeSource, c *conversion.Cloner) error { - out.Repository = in.Repository - out.Revision = in.Revision - return nil -} - -func deepCopy_v1beta3_GlusterfsVolumeSource(in GlusterfsVolumeSource, out *GlusterfsVolumeSource, c *conversion.Cloner) error { - out.EndpointsName = in.EndpointsName - out.Path = in.Path - out.ReadOnly = in.ReadOnly - return nil -} - -func deepCopy_v1beta3_HTTPGetAction(in HTTPGetAction, out *HTTPGetAction, c *conversion.Cloner) error { - out.Path = in.Path - if err := deepCopy_util_IntOrString(in.Port, &out.Port, c); err != nil { - return err - } - out.Host = in.Host - out.Scheme = in.Scheme - return nil -} - -func deepCopy_v1beta3_Handler(in Handler, out *Handler, c *conversion.Cloner) error { - if in.Exec != nil { - out.Exec = new(ExecAction) - if err := deepCopy_v1beta3_ExecAction(*in.Exec, out.Exec, c); err != nil { - return err - } - } else { - out.Exec = nil - } - if in.HTTPGet != nil { - out.HTTPGet = new(HTTPGetAction) - if err := deepCopy_v1beta3_HTTPGetAction(*in.HTTPGet, out.HTTPGet, c); err != nil { - return err - } - } else { - out.HTTPGet = nil - } - if in.TCPSocket != nil { - out.TCPSocket = new(TCPSocketAction) - if err := deepCopy_v1beta3_TCPSocketAction(*in.TCPSocket, out.TCPSocket, c); err != nil { - return err - } - } else { - out.TCPSocket = nil - } - return nil -} - -func deepCopy_v1beta3_HostPathVolumeSource(in HostPathVolumeSource, out *HostPathVolumeSource, c *conversion.Cloner) error { - out.Path = in.Path - return nil -} - -func deepCopy_v1beta3_ISCSIVolumeSource(in ISCSIVolumeSource, out *ISCSIVolumeSource, c *conversion.Cloner) error { - out.TargetPortal = in.TargetPortal - out.IQN = in.IQN - out.Lun = in.Lun - out.FSType = in.FSType - out.ReadOnly = in.ReadOnly - return nil -} - -func deepCopy_v1beta3_Lifecycle(in Lifecycle, out *Lifecycle, c *conversion.Cloner) error { - if in.PostStart != nil { - out.PostStart = new(Handler) - if err := deepCopy_v1beta3_Handler(*in.PostStart, out.PostStart, c); err != nil { - return err - } - } else { - out.PostStart = nil - } - if in.PreStop != nil { - out.PreStop = new(Handler) - if err := deepCopy_v1beta3_Handler(*in.PreStop, out.PreStop, c); err != nil { - return err - } - } else { - out.PreStop = nil - } - return nil -} - -func deepCopy_v1beta3_LimitRange(in LimitRange, out *LimitRange, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_LimitRangeSpec(in.Spec, &out.Spec, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_LimitRangeItem(in LimitRangeItem, out *LimitRangeItem, c *conversion.Cloner) error { - out.Type = in.Type - if in.Max != nil { - out.Max = make(ResourceList) - for key, val := range in.Max { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.Max[key] = *newVal - } - } else { - out.Max = nil - } - if in.Min != nil { - out.Min = make(ResourceList) - for key, val := range in.Min { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.Min[key] = *newVal - } - } else { - out.Min = nil - } - if in.Default != nil { - out.Default = make(ResourceList) - for key, val := range in.Default { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.Default[key] = *newVal - } - } else { - out.Default = nil - } - if in.DefaultRequest != nil { - out.DefaultRequest = make(ResourceList) - for key, val := range in.DefaultRequest { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.DefaultRequest[key] = *newVal - } - } else { - out.DefaultRequest = nil - } - if in.MaxLimitRequestRatio != nil { - out.MaxLimitRequestRatio = make(ResourceList) - for key, val := range in.MaxLimitRequestRatio { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.MaxLimitRequestRatio[key] = *newVal - } - } else { - out.MaxLimitRequestRatio = nil - } - return nil -} - -func deepCopy_v1beta3_LimitRangeList(in LimitRangeList, out *LimitRangeList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]LimitRange, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_LimitRange(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_LimitRangeSpec(in LimitRangeSpec, out *LimitRangeSpec, c *conversion.Cloner) error { - if in.Limits != nil { - out.Limits = make([]LimitRangeItem, len(in.Limits)) - for i := range in.Limits { - if err := deepCopy_v1beta3_LimitRangeItem(in.Limits[i], &out.Limits[i], c); err != nil { - return err - } - } - } else { - out.Limits = nil - } - return nil -} - -func deepCopy_v1beta3_List(in List, out *List, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]runtime.RawExtension, len(in.Items)) - for i := range in.Items { - if err := deepCopy_runtime_RawExtension(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_ListMeta(in ListMeta, out *ListMeta, c *conversion.Cloner) error { - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil -} - -func deepCopy_v1beta3_ListOptions(in ListOptions, out *ListOptions, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - out.LabelSelector = in.LabelSelector - out.FieldSelector = in.FieldSelector - out.Watch = in.Watch - out.ResourceVersion = in.ResourceVersion - return nil -} - -func deepCopy_v1beta3_LoadBalancerIngress(in LoadBalancerIngress, out *LoadBalancerIngress, c *conversion.Cloner) error { - out.IP = in.IP - out.Hostname = in.Hostname - return nil -} - -func deepCopy_v1beta3_LoadBalancerStatus(in LoadBalancerStatus, out *LoadBalancerStatus, c *conversion.Cloner) error { - if in.Ingress != nil { - out.Ingress = make([]LoadBalancerIngress, len(in.Ingress)) - for i := range in.Ingress { - if err := deepCopy_v1beta3_LoadBalancerIngress(in.Ingress[i], &out.Ingress[i], c); err != nil { - return err - } - } - } else { - out.Ingress = nil - } - return nil -} - -func deepCopy_v1beta3_LocalObjectReference(in LocalObjectReference, out *LocalObjectReference, c *conversion.Cloner) error { - out.Name = in.Name - return nil -} - -func deepCopy_v1beta3_MetadataFile(in MetadataFile, out *MetadataFile, c *conversion.Cloner) error { - out.Name = in.Name - if err := deepCopy_v1beta3_ObjectFieldSelector(in.FieldRef, &out.FieldRef, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_MetadataVolumeSource(in MetadataVolumeSource, out *MetadataVolumeSource, c *conversion.Cloner) error { - if in.Items != nil { - out.Items = make([]MetadataFile, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_MetadataFile(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_NFSVolumeSource(in NFSVolumeSource, out *NFSVolumeSource, c *conversion.Cloner) error { - out.Server = in.Server - out.Path = in.Path - out.ReadOnly = in.ReadOnly - return nil -} - -func deepCopy_v1beta3_Namespace(in Namespace, out *Namespace, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_NamespaceSpec(in.Spec, &out.Spec, c); err != nil { - return err - } - if err := deepCopy_v1beta3_NamespaceStatus(in.Status, &out.Status, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_NamespaceList(in NamespaceList, out *NamespaceList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Namespace, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_Namespace(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_NamespaceSpec(in NamespaceSpec, out *NamespaceSpec, c *conversion.Cloner) error { - if in.Finalizers != nil { - out.Finalizers = make([]FinalizerName, len(in.Finalizers)) - for i := range in.Finalizers { - out.Finalizers[i] = in.Finalizers[i] - } - } else { - out.Finalizers = nil - } - return nil -} - -func deepCopy_v1beta3_NamespaceStatus(in NamespaceStatus, out *NamespaceStatus, c *conversion.Cloner) error { - out.Phase = in.Phase - return nil -} - -func deepCopy_v1beta3_Node(in Node, out *Node, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_NodeSpec(in.Spec, &out.Spec, c); err != nil { - return err - } - if err := deepCopy_v1beta3_NodeStatus(in.Status, &out.Status, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_NodeAddress(in NodeAddress, out *NodeAddress, c *conversion.Cloner) error { - out.Type = in.Type - out.Address = in.Address - return nil -} - -func deepCopy_v1beta3_NodeCondition(in NodeCondition, out *NodeCondition, c *conversion.Cloner) error { - out.Type = in.Type - out.Status = in.Status - if err := deepCopy_util_Time(in.LastHeartbeatTime, &out.LastHeartbeatTime, c); err != nil { - return err - } - if err := deepCopy_util_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { - return err - } - out.Reason = in.Reason - out.Message = in.Message - return nil -} - -func deepCopy_v1beta3_NodeList(in NodeList, out *NodeList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Node, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_Node(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_NodeSpec(in NodeSpec, out *NodeSpec, c *conversion.Cloner) error { - out.PodCIDR = in.PodCIDR - out.ExternalID = in.ExternalID - out.ProviderID = in.ProviderID - out.Unschedulable = in.Unschedulable - return nil -} - -func deepCopy_v1beta3_NodeStatus(in NodeStatus, out *NodeStatus, c *conversion.Cloner) error { - if in.Capacity != nil { - out.Capacity = make(ResourceList) - for key, val := range in.Capacity { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.Capacity[key] = *newVal - } - } else { - out.Capacity = nil - } - out.Phase = in.Phase - if in.Conditions != nil { - out.Conditions = make([]NodeCondition, len(in.Conditions)) - for i := range in.Conditions { - if err := deepCopy_v1beta3_NodeCondition(in.Conditions[i], &out.Conditions[i], c); err != nil { - return err - } - } - } else { - out.Conditions = nil - } - if in.Addresses != nil { - out.Addresses = make([]NodeAddress, len(in.Addresses)) - for i := range in.Addresses { - if err := deepCopy_v1beta3_NodeAddress(in.Addresses[i], &out.Addresses[i], c); err != nil { - return err - } - } - } else { - out.Addresses = nil - } - if err := deepCopy_v1beta3_NodeSystemInfo(in.NodeInfo, &out.NodeInfo, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_NodeSystemInfo(in NodeSystemInfo, out *NodeSystemInfo, c *conversion.Cloner) error { - out.MachineID = in.MachineID - out.SystemUUID = in.SystemUUID - out.BootID = in.BootID - out.KernelVersion = in.KernelVersion - out.OsImage = in.OsImage - out.ContainerRuntimeVersion = in.ContainerRuntimeVersion - out.KubeletVersion = in.KubeletVersion - out.KubeProxyVersion = in.KubeProxyVersion - return nil -} - -func deepCopy_v1beta3_ObjectFieldSelector(in ObjectFieldSelector, out *ObjectFieldSelector, c *conversion.Cloner) error { - out.APIVersion = in.APIVersion - out.FieldPath = in.FieldPath - return nil -} - -func deepCopy_v1beta3_ObjectMeta(in ObjectMeta, out *ObjectMeta, c *conversion.Cloner) error { - out.Name = in.Name - out.GenerateName = in.GenerateName - out.Namespace = in.Namespace - out.SelfLink = in.SelfLink - out.UID = in.UID - out.ResourceVersion = in.ResourceVersion - out.Generation = in.Generation - if err := deepCopy_util_Time(in.CreationTimestamp, &out.CreationTimestamp, c); err != nil { - return err - } - if in.DeletionTimestamp != nil { - out.DeletionTimestamp = new(util.Time) - if err := deepCopy_util_Time(*in.DeletionTimestamp, out.DeletionTimestamp, c); err != nil { - return err - } - } else { - out.DeletionTimestamp = nil - } - if in.DeletionGracePeriodSeconds != nil { - out.DeletionGracePeriodSeconds = new(int64) - *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds - } else { - out.DeletionGracePeriodSeconds = nil - } - if in.Labels != nil { - out.Labels = make(map[string]string) - for key, val := range in.Labels { - out.Labels[key] = val - } - } else { - out.Labels = nil - } - if in.Annotations != nil { - out.Annotations = make(map[string]string) - for key, val := range in.Annotations { - out.Annotations[key] = val - } - } else { - out.Annotations = nil - } - return nil -} - -func deepCopy_v1beta3_ObjectReference(in ObjectReference, out *ObjectReference, c *conversion.Cloner) error { - out.Kind = in.Kind - out.Namespace = in.Namespace - out.Name = in.Name - out.UID = in.UID - out.APIVersion = in.APIVersion - out.ResourceVersion = in.ResourceVersion - out.FieldPath = in.FieldPath - return nil -} - -func deepCopy_v1beta3_PersistentVolume(in PersistentVolume, out *PersistentVolume, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_PersistentVolumeSpec(in.Spec, &out.Spec, c); err != nil { - return err - } - if err := deepCopy_v1beta3_PersistentVolumeStatus(in.Status, &out.Status, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_PersistentVolumeClaim(in PersistentVolumeClaim, out *PersistentVolumeClaim, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_PersistentVolumeClaimSpec(in.Spec, &out.Spec, c); err != nil { - return err - } - if err := deepCopy_v1beta3_PersistentVolumeClaimStatus(in.Status, &out.Status, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_PersistentVolumeClaimList(in PersistentVolumeClaimList, out *PersistentVolumeClaimList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]PersistentVolumeClaim, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_PersistentVolumeClaim(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_PersistentVolumeClaimSpec(in PersistentVolumeClaimSpec, out *PersistentVolumeClaimSpec, c *conversion.Cloner) error { - if in.AccessModes != nil { - out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) - for i := range in.AccessModes { - out.AccessModes[i] = in.AccessModes[i] - } - } else { - out.AccessModes = nil - } - if err := deepCopy_v1beta3_ResourceRequirements(in.Resources, &out.Resources, c); err != nil { - return err - } - out.VolumeName = in.VolumeName - return nil -} - -func deepCopy_v1beta3_PersistentVolumeClaimStatus(in PersistentVolumeClaimStatus, out *PersistentVolumeClaimStatus, c *conversion.Cloner) error { - out.Phase = in.Phase - if in.AccessModes != nil { - out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) - for i := range in.AccessModes { - out.AccessModes[i] = in.AccessModes[i] - } - } else { - out.AccessModes = nil - } - if in.Capacity != nil { - out.Capacity = make(ResourceList) - for key, val := range in.Capacity { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.Capacity[key] = *newVal - } - } else { - out.Capacity = nil - } - return nil -} - -func deepCopy_v1beta3_PersistentVolumeClaimVolumeSource(in PersistentVolumeClaimVolumeSource, out *PersistentVolumeClaimVolumeSource, c *conversion.Cloner) error { - out.ClaimName = in.ClaimName - out.ReadOnly = in.ReadOnly - return nil -} - -func deepCopy_v1beta3_PersistentVolumeList(in PersistentVolumeList, out *PersistentVolumeList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]PersistentVolume, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_PersistentVolume(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_PersistentVolumeSource(in PersistentVolumeSource, out *PersistentVolumeSource, c *conversion.Cloner) error { - if in.GCEPersistentDisk != nil { - out.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) - if err := deepCopy_v1beta3_GCEPersistentDiskVolumeSource(*in.GCEPersistentDisk, out.GCEPersistentDisk, c); err != nil { - return err - } - } else { - out.GCEPersistentDisk = nil - } - if in.AWSElasticBlockStore != nil { - out.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) - if err := deepCopy_v1beta3_AWSElasticBlockStoreVolumeSource(*in.AWSElasticBlockStore, out.AWSElasticBlockStore, c); err != nil { - return err - } - } else { - out.AWSElasticBlockStore = nil - } - if in.HostPath != nil { - out.HostPath = new(HostPathVolumeSource) - if err := deepCopy_v1beta3_HostPathVolumeSource(*in.HostPath, out.HostPath, c); err != nil { - return err - } - } else { - out.HostPath = nil - } - if in.Glusterfs != nil { - out.Glusterfs = new(GlusterfsVolumeSource) - if err := deepCopy_v1beta3_GlusterfsVolumeSource(*in.Glusterfs, out.Glusterfs, c); err != nil { - return err - } - } else { - out.Glusterfs = nil - } - if in.NFS != nil { - out.NFS = new(NFSVolumeSource) - if err := deepCopy_v1beta3_NFSVolumeSource(*in.NFS, out.NFS, c); err != nil { - return err - } - } else { - out.NFS = nil - } - if in.RBD != nil { - out.RBD = new(RBDVolumeSource) - if err := deepCopy_v1beta3_RBDVolumeSource(*in.RBD, out.RBD, c); err != nil { - return err - } - } else { - out.RBD = nil - } - if in.ISCSI != nil { - out.ISCSI = new(ISCSIVolumeSource) - if err := deepCopy_v1beta3_ISCSIVolumeSource(*in.ISCSI, out.ISCSI, c); err != nil { - return err - } - } else { - out.ISCSI = nil - } - if in.CephFS != nil { - out.CephFS = new(CephFSVolumeSource) - if err := deepCopy_v1beta3_CephFSVolumeSource(*in.CephFS, out.CephFS, c); err != nil { - return err - } - } else { - out.CephFS = nil - } - if in.Cinder != nil { - out.Cinder = new(CinderVolumeSource) - if err := deepCopy_v1beta3_CinderVolumeSource(*in.Cinder, out.Cinder, c); err != nil { - return err - } - } else { - out.Cinder = nil - } - return nil -} - -func deepCopy_v1beta3_PersistentVolumeSpec(in PersistentVolumeSpec, out *PersistentVolumeSpec, c *conversion.Cloner) error { - if in.Capacity != nil { - out.Capacity = make(ResourceList) - for key, val := range in.Capacity { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.Capacity[key] = *newVal - } - } else { - out.Capacity = nil - } - if err := deepCopy_v1beta3_PersistentVolumeSource(in.PersistentVolumeSource, &out.PersistentVolumeSource, c); err != nil { - return err - } - if in.AccessModes != nil { - out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) - for i := range in.AccessModes { - out.AccessModes[i] = in.AccessModes[i] - } - } else { - out.AccessModes = nil - } - if in.ClaimRef != nil { - out.ClaimRef = new(ObjectReference) - if err := deepCopy_v1beta3_ObjectReference(*in.ClaimRef, out.ClaimRef, c); err != nil { - return err - } - } else { - out.ClaimRef = nil - } - out.PersistentVolumeReclaimPolicy = in.PersistentVolumeReclaimPolicy - return nil -} - -func deepCopy_v1beta3_PersistentVolumeStatus(in PersistentVolumeStatus, out *PersistentVolumeStatus, c *conversion.Cloner) error { - out.Phase = in.Phase - out.Message = in.Message - out.Reason = in.Reason - return nil -} - -func deepCopy_v1beta3_Pod(in Pod, out *Pod, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_PodSpec(in.Spec, &out.Spec, c); err != nil { - return err - } - if err := deepCopy_v1beta3_PodStatus(in.Status, &out.Status, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_PodCondition(in PodCondition, out *PodCondition, c *conversion.Cloner) error { - out.Type = in.Type - out.Status = in.Status - return nil -} - -func deepCopy_v1beta3_PodExecOptions(in PodExecOptions, out *PodExecOptions, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - out.Stdin = in.Stdin - out.Stdout = in.Stdout - out.Stderr = in.Stderr - out.TTY = in.TTY - out.Container = in.Container - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } else { - out.Command = nil - } - return nil -} - -func deepCopy_v1beta3_PodList(in PodList, out *PodList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Pod, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_Pod(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_PodLogOptions(in PodLogOptions, out *PodLogOptions, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - out.Container = in.Container - out.Follow = in.Follow - out.Previous = in.Previous - return nil -} - -func deepCopy_v1beta3_PodProxyOptions(in PodProxyOptions, out *PodProxyOptions, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - out.Path = in.Path - return nil -} - -func deepCopy_v1beta3_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error { - if in.Volumes != nil { - out.Volumes = make([]Volume, len(in.Volumes)) - for i := range in.Volumes { - if err := deepCopy_v1beta3_Volume(in.Volumes[i], &out.Volumes[i], c); err != nil { - return err - } - } - } else { - out.Volumes = nil - } - if in.Containers != nil { - out.Containers = make([]Container, len(in.Containers)) - for i := range in.Containers { - if err := deepCopy_v1beta3_Container(in.Containers[i], &out.Containers[i], c); err != nil { - return err - } - } - } else { - out.Containers = nil - } - out.RestartPolicy = in.RestartPolicy - if in.TerminationGracePeriodSeconds != nil { - out.TerminationGracePeriodSeconds = new(int64) - *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds - } else { - out.TerminationGracePeriodSeconds = nil - } - if in.ActiveDeadlineSeconds != nil { - out.ActiveDeadlineSeconds = new(int64) - *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds - } else { - out.ActiveDeadlineSeconds = nil - } - out.DNSPolicy = in.DNSPolicy - if in.NodeSelector != nil { - out.NodeSelector = make(map[string]string) - for key, val := range in.NodeSelector { - out.NodeSelector[key] = val - } - } else { - out.NodeSelector = nil - } - out.ServiceAccount = in.ServiceAccount - out.Host = in.Host - out.HostNetwork = in.HostNetwork - out.HostPID = in.HostPID - out.HostIPC = in.HostIPC - if in.ImagePullSecrets != nil { - out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) - for i := range in.ImagePullSecrets { - if err := deepCopy_v1beta3_LocalObjectReference(in.ImagePullSecrets[i], &out.ImagePullSecrets[i], c); err != nil { - return err - } - } - } else { - out.ImagePullSecrets = nil - } - return nil -} - -func deepCopy_v1beta3_PodStatus(in PodStatus, out *PodStatus, c *conversion.Cloner) error { - out.Phase = in.Phase - if in.Conditions != nil { - out.Conditions = make([]PodCondition, len(in.Conditions)) - for i := range in.Conditions { - if err := deepCopy_v1beta3_PodCondition(in.Conditions[i], &out.Conditions[i], c); err != nil { - return err - } - } - } else { - out.Conditions = nil - } - out.Message = in.Message - out.Reason = in.Reason - out.HostIP = in.HostIP - out.PodIP = in.PodIP - if in.StartTime != nil { - out.StartTime = new(util.Time) - if err := deepCopy_util_Time(*in.StartTime, out.StartTime, c); err != nil { - return err - } - } else { - out.StartTime = nil - } - if in.ContainerStatuses != nil { - out.ContainerStatuses = make([]ContainerStatus, len(in.ContainerStatuses)) - for i := range in.ContainerStatuses { - if err := deepCopy_v1beta3_ContainerStatus(in.ContainerStatuses[i], &out.ContainerStatuses[i], c); err != nil { - return err - } - } - } else { - out.ContainerStatuses = nil - } - return nil -} - -func deepCopy_v1beta3_PodStatusResult(in PodStatusResult, out *PodStatusResult, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_PodStatus(in.Status, &out.Status, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_PodTemplate(in PodTemplate, out *PodTemplate, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_PodTemplateSpec(in.Template, &out.Template, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_PodTemplateList(in PodTemplateList, out *PodTemplateList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]PodTemplate, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_PodTemplate(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_PodTemplateSpec(in PodTemplateSpec, out *PodTemplateSpec, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_PodSpec(in.Spec, &out.Spec, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_Probe(in Probe, out *Probe, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_Handler(in.Handler, &out.Handler, c); err != nil { - return err - } - out.InitialDelaySeconds = in.InitialDelaySeconds - out.TimeoutSeconds = in.TimeoutSeconds - return nil -} - -func deepCopy_v1beta3_RBDVolumeSource(in RBDVolumeSource, out *RBDVolumeSource, c *conversion.Cloner) error { - if in.CephMonitors != nil { - out.CephMonitors = make([]string, len(in.CephMonitors)) - for i := range in.CephMonitors { - out.CephMonitors[i] = in.CephMonitors[i] - } - } else { - out.CephMonitors = nil - } - out.RBDImage = in.RBDImage - out.FSType = in.FSType - out.RBDPool = in.RBDPool - out.RadosUser = in.RadosUser - out.Keyring = in.Keyring - if in.SecretRef != nil { - out.SecretRef = new(LocalObjectReference) - if err := deepCopy_v1beta3_LocalObjectReference(*in.SecretRef, out.SecretRef, c); err != nil { - return err - } - } else { - out.SecretRef = nil - } - out.ReadOnly = in.ReadOnly - return nil -} - -func deepCopy_v1beta3_RangeAllocation(in RangeAllocation, out *RangeAllocation, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - out.Range = in.Range - if in.Data != nil { - out.Data = make([]uint8, len(in.Data)) - for i := range in.Data { - out.Data[i] = in.Data[i] - } - } else { - out.Data = nil - } - return nil -} - -func deepCopy_v1beta3_ReplicationController(in ReplicationController, out *ReplicationController, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ReplicationControllerSpec(in.Spec, &out.Spec, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ReplicationControllerStatus(in.Status, &out.Status, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_ReplicationControllerList(in ReplicationControllerList, out *ReplicationControllerList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]ReplicationController, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_ReplicationController(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_ReplicationControllerSpec(in ReplicationControllerSpec, out *ReplicationControllerSpec, c *conversion.Cloner) error { - if in.Replicas != nil { - out.Replicas = new(int) - *out.Replicas = *in.Replicas - } else { - out.Replicas = nil - } - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - if in.Template != nil { - out.Template = new(PodTemplateSpec) - if err := deepCopy_v1beta3_PodTemplateSpec(*in.Template, out.Template, c); err != nil { - return err - } - } else { - out.Template = nil - } - return nil -} - -func deepCopy_v1beta3_ReplicationControllerStatus(in ReplicationControllerStatus, out *ReplicationControllerStatus, c *conversion.Cloner) error { - out.Replicas = in.Replicas - out.ObservedGeneration = in.ObservedGeneration - return nil -} - -func deepCopy_v1beta3_ResourceQuota(in ResourceQuota, out *ResourceQuota, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ResourceQuotaSpec(in.Spec, &out.Spec, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ResourceQuotaStatus(in.Status, &out.Status, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_ResourceQuotaList(in ResourceQuotaList, out *ResourceQuotaList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]ResourceQuota, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_ResourceQuota(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_ResourceQuotaSpec(in ResourceQuotaSpec, out *ResourceQuotaSpec, c *conversion.Cloner) error { - if in.Hard != nil { - out.Hard = make(ResourceList) - for key, val := range in.Hard { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.Hard[key] = *newVal - } - } else { - out.Hard = nil - } - return nil -} - -func deepCopy_v1beta3_ResourceQuotaStatus(in ResourceQuotaStatus, out *ResourceQuotaStatus, c *conversion.Cloner) error { - if in.Hard != nil { - out.Hard = make(ResourceList) - for key, val := range in.Hard { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.Hard[key] = *newVal - } - } else { - out.Hard = nil - } - if in.Used != nil { - out.Used = make(ResourceList) - for key, val := range in.Used { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.Used[key] = *newVal - } - } else { - out.Used = nil - } - return nil -} - -func deepCopy_v1beta3_ResourceRequirements(in ResourceRequirements, out *ResourceRequirements, c *conversion.Cloner) error { - if in.Limits != nil { - out.Limits = make(ResourceList) - for key, val := range in.Limits { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.Limits[key] = *newVal - } - } else { - out.Limits = nil - } - if in.Requests != nil { - out.Requests = make(ResourceList) - for key, val := range in.Requests { - newVal := new(resource.Quantity) - if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { - return err - } - out.Requests[key] = *newVal - } - } else { - out.Requests = nil - } - return nil -} - -func deepCopy_v1beta3_RunAsUserStrategyOptions(in RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.UID != nil { - out.UID = new(int64) - *out.UID = *in.UID - } else { - out.UID = nil - } - if in.UIDRangeMin != nil { - out.UIDRangeMin = new(int64) - *out.UIDRangeMin = *in.UIDRangeMin - } else { - out.UIDRangeMin = nil - } - if in.UIDRangeMax != nil { - out.UIDRangeMax = new(int64) - *out.UIDRangeMax = *in.UIDRangeMax - } else { - out.UIDRangeMax = nil - } - return nil -} - -func deepCopy_v1beta3_SELinuxContextStrategyOptions(in SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(SELinuxOptions) - if err := deepCopy_v1beta3_SELinuxOptions(*in.SELinuxOptions, out.SELinuxOptions, c); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - return nil -} - -func deepCopy_v1beta3_SELinuxOptions(in SELinuxOptions, out *SELinuxOptions, c *conversion.Cloner) error { - out.User = in.User - out.Role = in.Role - out.Type = in.Type - out.Level = in.Level - return nil -} - -func deepCopy_v1beta3_SupplementalGroupsStrategyOptions(in SupplementalGroupsStrategyOptions, out *SupplementalGroupsStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.Ranges != nil { - out.Ranges = make([]IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := deepCopy_v1beta3_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func deepCopy_v1beta3_FSGroupStrategyOptions(in FSGroupStrategyOptions, out *FSGroupStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type - if in.Ranges != nil { - out.Ranges = make([]IDRange, len(in.Ranges)) - for i := range in.Ranges { - if err := deepCopy_v1beta3_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { - return err - } - } - } else { - out.Ranges = nil - } - return nil -} - -func deepCopy_v1beta3_IDRange(in IDRange, out *IDRange, c *conversion.Cloner) error { - out.Max = in.Max - out.Min = in.Min - return nil -} - -func deepCopy_v1beta3_Secret(in Secret, out *Secret, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if in.Data != nil { - out.Data = make(map[string][]uint8) - for key, val := range in.Data { - if newVal, err := c.DeepCopy(val); err != nil { - return err - } else { - out.Data[key] = newVal.([]uint8) - } - } - } else { - out.Data = nil - } - out.Type = in.Type - return nil -} - -func deepCopy_v1beta3_SecretList(in SecretList, out *SecretList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Secret, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_Secret(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_SecretVolumeSource(in SecretVolumeSource, out *SecretVolumeSource, c *conversion.Cloner) error { - out.SecretName = in.SecretName - return nil -} - -func deepCopy_v1beta3_SecurityContext(in SecurityContext, out *SecurityContext, c *conversion.Cloner) error { - if in.Capabilities != nil { - out.Capabilities = new(Capabilities) - if err := deepCopy_v1beta3_Capabilities(*in.Capabilities, out.Capabilities, c); err != nil { - return err - } - } else { - out.Capabilities = nil - } - if in.Privileged != nil { - out.Privileged = new(bool) - *out.Privileged = *in.Privileged - } else { - out.Privileged = nil - } - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(SELinuxOptions) - if err := deepCopy_v1beta3_SELinuxOptions(*in.SELinuxOptions, out.SELinuxOptions, c); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - if in.RunAsUser != nil { - out.RunAsUser = new(int64) - *out.RunAsUser = *in.RunAsUser - } else { - out.RunAsUser = nil - } - out.RunAsNonRoot = in.RunAsNonRoot - return nil -} - -func deepCopy_v1beta3_SecurityContextConstraints(in SecurityContextConstraints, out *SecurityContextConstraints, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - out.AllowPrivilegedContainer = in.AllowPrivilegedContainer - if in.AllowedCapabilities != nil { - out.AllowedCapabilities = make([]Capability, len(in.AllowedCapabilities)) - for i := range in.AllowedCapabilities { - out.AllowedCapabilities[i] = in.AllowedCapabilities[i] - } - } else { - out.AllowedCapabilities = nil - } - out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin - out.AllowHostNetwork = in.AllowHostNetwork - out.AllowHostPorts = in.AllowHostPorts - out.AllowHostPID = in.AllowHostPID - out.AllowHostIPC = in.AllowHostIPC - if err := deepCopy_v1beta3_SELinuxContextStrategyOptions(in.SELinuxContext, &out.SELinuxContext, c); err != nil { - return err - } - if err := deepCopy_v1beta3_RunAsUserStrategyOptions(in.RunAsUser, &out.RunAsUser, c); err != nil { - return err - } - if err := deepCopy_v1beta3_FSGroupStrategyOptions(in.FSGroup, &out.FSGroup, c); err != nil { - return err - } - if err := deepCopy_v1beta3_SupplementalGroupsStrategyOptions(in.SupplementalGroups, &out.SupplementalGroups, c); err != nil { - return err - } - if in.Users != nil { - out.Users = make([]string, len(in.Users)) - for i := range in.Users { - out.Users[i] = in.Users[i] - } - } else { - out.Users = nil - } - if in.Groups != nil { - out.Groups = make([]string, len(in.Groups)) - for i := range in.Groups { - out.Groups[i] = in.Groups[i] - } - } else { - out.Groups = nil - } - return nil -} - -func deepCopy_v1beta3_SecurityContextConstraintsList(in SecurityContextConstraintsList, out *SecurityContextConstraintsList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]SecurityContextConstraints, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_SecurityContextConstraints(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_SerializedReference(in SerializedReference, out *SerializedReference, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectReference(in.Reference, &out.Reference, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_Service(in Service, out *Service, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ServiceSpec(in.Spec, &out.Spec, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ServiceStatus(in.Status, &out.Status, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_ServiceAccount(in ServiceAccount, out *ServiceAccount, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { - return err - } - if in.Secrets != nil { - out.Secrets = make([]ObjectReference, len(in.Secrets)) - for i := range in.Secrets { - if err := deepCopy_v1beta3_ObjectReference(in.Secrets[i], &out.Secrets[i], c); err != nil { - return err - } - } - } else { - out.Secrets = nil - } - if in.ImagePullSecrets != nil { - out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) - for i := range in.ImagePullSecrets { - if err := deepCopy_v1beta3_LocalObjectReference(in.ImagePullSecrets[i], &out.ImagePullSecrets[i], c); err != nil { - return err - } - } - } else { - out.ImagePullSecrets = nil - } - return nil -} - -func deepCopy_v1beta3_ServiceAccountList(in ServiceAccountList, out *ServiceAccountList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]ServiceAccount, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_ServiceAccount(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_ServiceList(in ServiceList, out *ServiceList, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Service, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1beta3_Service(in.Items[i], &out.Items[i], c); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func deepCopy_v1beta3_ServicePort(in ServicePort, out *ServicePort, c *conversion.Cloner) error { - out.Name = in.Name - out.Protocol = in.Protocol - out.Port = in.Port - if err := deepCopy_util_IntOrString(in.TargetPort, &out.TargetPort, c); err != nil { - return err - } - out.NodePort = in.NodePort - return nil -} - -func deepCopy_v1beta3_ServiceSpec(in ServiceSpec, out *ServiceSpec, c *conversion.Cloner) error { - if in.Ports != nil { - out.Ports = make([]ServicePort, len(in.Ports)) - for i := range in.Ports { - if err := deepCopy_v1beta3_ServicePort(in.Ports[i], &out.Ports[i], c); err != nil { - return err - } - } - } else { - out.Ports = nil - } - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - out.PortalIP = in.PortalIP - out.CreateExternalLoadBalancer = in.CreateExternalLoadBalancer - out.Type = in.Type - if in.PublicIPs != nil { - out.PublicIPs = make([]string, len(in.PublicIPs)) - for i := range in.PublicIPs { - out.PublicIPs[i] = in.PublicIPs[i] - } - } else { - out.PublicIPs = nil - } - out.SessionAffinity = in.SessionAffinity - return nil -} - -func deepCopy_v1beta3_ServiceStatus(in ServiceStatus, out *ServiceStatus, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_LoadBalancerStatus(in.LoadBalancer, &out.LoadBalancer, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_Status(in Status, out *Status, c *conversion.Cloner) error { - if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { - return err - } - if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { - return err - } - out.Status = in.Status - out.Message = in.Message - out.Reason = in.Reason - if in.Details != nil { - out.Details = new(StatusDetails) - if err := deepCopy_v1beta3_StatusDetails(*in.Details, out.Details, c); err != nil { - return err - } - } else { - out.Details = nil - } - out.Code = in.Code - return nil -} - -func deepCopy_v1beta3_StatusCause(in StatusCause, out *StatusCause, c *conversion.Cloner) error { - out.Type = in.Type - out.Message = in.Message - out.Field = in.Field - return nil -} - -func deepCopy_v1beta3_StatusDetails(in StatusDetails, out *StatusDetails, c *conversion.Cloner) error { - out.ID = in.ID - out.Kind = in.Kind - if in.Causes != nil { - out.Causes = make([]StatusCause, len(in.Causes)) - for i := range in.Causes { - if err := deepCopy_v1beta3_StatusCause(in.Causes[i], &out.Causes[i], c); err != nil { - return err - } - } - } else { - out.Causes = nil - } - out.RetryAfterSeconds = in.RetryAfterSeconds - return nil -} - -func deepCopy_v1beta3_TCPSocketAction(in TCPSocketAction, out *TCPSocketAction, c *conversion.Cloner) error { - if err := deepCopy_util_IntOrString(in.Port, &out.Port, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_TypeMeta(in TypeMeta, out *TypeMeta, c *conversion.Cloner) error { - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil -} - -func deepCopy_v1beta3_Volume(in Volume, out *Volume, c *conversion.Cloner) error { - out.Name = in.Name - if err := deepCopy_v1beta3_VolumeSource(in.VolumeSource, &out.VolumeSource, c); err != nil { - return err - } - return nil -} - -func deepCopy_v1beta3_VolumeMount(in VolumeMount, out *VolumeMount, c *conversion.Cloner) error { - out.Name = in.Name - out.ReadOnly = in.ReadOnly - out.MountPath = in.MountPath - return nil -} - -func deepCopy_v1beta3_VolumeSource(in VolumeSource, out *VolumeSource, c *conversion.Cloner) error { - if in.HostPath != nil { - out.HostPath = new(HostPathVolumeSource) - if err := deepCopy_v1beta3_HostPathVolumeSource(*in.HostPath, out.HostPath, c); err != nil { - return err - } - } else { - out.HostPath = nil - } - if in.EmptyDir != nil { - out.EmptyDir = new(EmptyDirVolumeSource) - if err := deepCopy_v1beta3_EmptyDirVolumeSource(*in.EmptyDir, out.EmptyDir, c); err != nil { - return err - } - } else { - out.EmptyDir = nil - } - if in.GCEPersistentDisk != nil { - out.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) - if err := deepCopy_v1beta3_GCEPersistentDiskVolumeSource(*in.GCEPersistentDisk, out.GCEPersistentDisk, c); err != nil { - return err - } - } else { - out.GCEPersistentDisk = nil - } - if in.AWSElasticBlockStore != nil { - out.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) - if err := deepCopy_v1beta3_AWSElasticBlockStoreVolumeSource(*in.AWSElasticBlockStore, out.AWSElasticBlockStore, c); err != nil { - return err - } - } else { - out.AWSElasticBlockStore = nil - } - if in.GitRepo != nil { - out.GitRepo = new(GitRepoVolumeSource) - if err := deepCopy_v1beta3_GitRepoVolumeSource(*in.GitRepo, out.GitRepo, c); err != nil { - return err - } - } else { - out.GitRepo = nil - } - if in.Secret != nil { - out.Secret = new(SecretVolumeSource) - if err := deepCopy_v1beta3_SecretVolumeSource(*in.Secret, out.Secret, c); err != nil { - return err - } - } else { - out.Secret = nil - } - if in.NFS != nil { - out.NFS = new(NFSVolumeSource) - if err := deepCopy_v1beta3_NFSVolumeSource(*in.NFS, out.NFS, c); err != nil { - return err - } - } else { - out.NFS = nil - } - if in.ISCSI != nil { - out.ISCSI = new(ISCSIVolumeSource) - if err := deepCopy_v1beta3_ISCSIVolumeSource(*in.ISCSI, out.ISCSI, c); err != nil { - return err - } - } else { - out.ISCSI = nil - } - if in.Glusterfs != nil { - out.Glusterfs = new(GlusterfsVolumeSource) - if err := deepCopy_v1beta3_GlusterfsVolumeSource(*in.Glusterfs, out.Glusterfs, c); err != nil { - return err - } - } else { - out.Glusterfs = nil - } - if in.PersistentVolumeClaim != nil { - out.PersistentVolumeClaim = new(PersistentVolumeClaimVolumeSource) - if err := deepCopy_v1beta3_PersistentVolumeClaimVolumeSource(*in.PersistentVolumeClaim, out.PersistentVolumeClaim, c); err != nil { - return err - } - } else { - out.PersistentVolumeClaim = nil - } - if in.RBD != nil { - out.RBD = new(RBDVolumeSource) - if err := deepCopy_v1beta3_RBDVolumeSource(*in.RBD, out.RBD, c); err != nil { - return err - } - } else { - out.RBD = nil - } - if in.CephFS != nil { - out.CephFS = new(CephFSVolumeSource) - if err := deepCopy_v1beta3_CephFSVolumeSource(*in.CephFS, out.CephFS, c); err != nil { - return err - } - } else { - out.CephFS = nil - } - if in.Metadata != nil { - out.Metadata = new(MetadataVolumeSource) - if err := deepCopy_v1beta3_MetadataVolumeSource(*in.Metadata, out.Metadata, c); err != nil { - return err - } - } else { - out.Metadata = nil - } - if in.DownwardAPI != nil { - out.DownwardAPI = new(DownwardAPIVolumeSource) - if err := deepCopy_v1beta3_DownwardAPIVolumeSource(*in.DownwardAPI, out.DownwardAPI, c); err != nil { - return err - } - } else { - out.DownwardAPI = nil - } - if in.Cinder != nil { - out.Cinder = new(CinderVolumeSource) - if err := deepCopy_v1beta3_CinderVolumeSource(*in.Cinder, out.Cinder, c); err != nil { - return err - } - } else { - out.Cinder = nil - } - return nil -} - -func deepCopy_runtime_RawExtension(in runtime.RawExtension, out *runtime.RawExtension, c *conversion.Cloner) error { - if in.RawJSON != nil { - out.RawJSON = make([]uint8, len(in.RawJSON)) - for i := range in.RawJSON { - out.RawJSON[i] = in.RawJSON[i] - } - } else { - out.RawJSON = nil - } - return nil -} - -func deepCopy_util_IntOrString(in util.IntOrString, out *util.IntOrString, c *conversion.Cloner) error { - out.Kind = in.Kind - out.IntVal = in.IntVal - out.StrVal = in.StrVal - return nil -} - -func deepCopy_util_Time(in util.Time, out *util.Time, c *conversion.Cloner) error { - if newVal, err := c.DeepCopy(in.Time); err != nil { - return err - } else { - out.Time = newVal.(time.Time) - } - return nil -} - -func init() { - err := api.Scheme.AddGeneratedDeepCopyFuncs( - deepCopy_resource_Quantity, - deepCopy_v1beta3_AWSElasticBlockStoreVolumeSource, - deepCopy_v1beta3_Binding, - deepCopy_v1beta3_Capabilities, - deepCopy_v1beta3_CephFSVolumeSource, - deepCopy_v1beta3_CinderVolumeSource, - deepCopy_v1beta3_ComponentCondition, - deepCopy_v1beta3_ComponentStatus, - deepCopy_v1beta3_ComponentStatusList, - deepCopy_v1beta3_Container, - deepCopy_v1beta3_ContainerPort, - deepCopy_v1beta3_ContainerState, - deepCopy_v1beta3_ContainerStateRunning, - deepCopy_v1beta3_ContainerStateTerminated, - deepCopy_v1beta3_ContainerStateWaiting, - deepCopy_v1beta3_ContainerStatus, - deepCopy_v1beta3_DeleteOptions, - deepCopy_v1beta3_DownwardAPIVolumeFile, - deepCopy_v1beta3_DownwardAPIVolumeSource, - deepCopy_v1beta3_EmptyDirVolumeSource, - deepCopy_v1beta3_EndpointAddress, - deepCopy_v1beta3_EndpointPort, - deepCopy_v1beta3_EndpointSubset, - deepCopy_v1beta3_Endpoints, - deepCopy_v1beta3_EndpointsList, - deepCopy_v1beta3_EnvVar, - deepCopy_v1beta3_EnvVarSource, - deepCopy_v1beta3_Event, - deepCopy_v1beta3_EventList, - deepCopy_v1beta3_EventSource, - deepCopy_v1beta3_ExecAction, - deepCopy_v1beta3_FSGroupStrategyOptions, - deepCopy_v1beta3_GCEPersistentDiskVolumeSource, - deepCopy_v1beta3_GitRepoVolumeSource, - deepCopy_v1beta3_GlusterfsVolumeSource, - deepCopy_v1beta3_HTTPGetAction, - deepCopy_v1beta3_Handler, - deepCopy_v1beta3_HostPathVolumeSource, - deepCopy_v1beta3_IDRange, - deepCopy_v1beta3_ISCSIVolumeSource, - deepCopy_v1beta3_Lifecycle, - deepCopy_v1beta3_LimitRange, - deepCopy_v1beta3_LimitRangeItem, - deepCopy_v1beta3_LimitRangeList, - deepCopy_v1beta3_LimitRangeSpec, - deepCopy_v1beta3_List, - deepCopy_v1beta3_ListMeta, - deepCopy_v1beta3_ListOptions, - deepCopy_v1beta3_LoadBalancerIngress, - deepCopy_v1beta3_LoadBalancerStatus, - deepCopy_v1beta3_LocalObjectReference, - deepCopy_v1beta3_MetadataFile, - deepCopy_v1beta3_MetadataVolumeSource, - deepCopy_v1beta3_NFSVolumeSource, - deepCopy_v1beta3_Namespace, - deepCopy_v1beta3_NamespaceList, - deepCopy_v1beta3_NamespaceSpec, - deepCopy_v1beta3_NamespaceStatus, - deepCopy_v1beta3_Node, - deepCopy_v1beta3_NodeAddress, - deepCopy_v1beta3_NodeCondition, - deepCopy_v1beta3_NodeList, - deepCopy_v1beta3_NodeSpec, - deepCopy_v1beta3_NodeStatus, - deepCopy_v1beta3_NodeSystemInfo, - deepCopy_v1beta3_ObjectFieldSelector, - deepCopy_v1beta3_ObjectMeta, - deepCopy_v1beta3_ObjectReference, - deepCopy_v1beta3_PersistentVolume, - deepCopy_v1beta3_PersistentVolumeClaim, - deepCopy_v1beta3_PersistentVolumeClaimList, - deepCopy_v1beta3_PersistentVolumeClaimSpec, - deepCopy_v1beta3_PersistentVolumeClaimStatus, - deepCopy_v1beta3_PersistentVolumeClaimVolumeSource, - deepCopy_v1beta3_PersistentVolumeList, - deepCopy_v1beta3_PersistentVolumeSource, - deepCopy_v1beta3_PersistentVolumeSpec, - deepCopy_v1beta3_PersistentVolumeStatus, - deepCopy_v1beta3_Pod, - deepCopy_v1beta3_PodCondition, - deepCopy_v1beta3_PodExecOptions, - deepCopy_v1beta3_PodList, - deepCopy_v1beta3_PodLogOptions, - deepCopy_v1beta3_PodProxyOptions, - deepCopy_v1beta3_PodSpec, - deepCopy_v1beta3_PodStatus, - deepCopy_v1beta3_PodStatusResult, - deepCopy_v1beta3_PodTemplate, - deepCopy_v1beta3_PodTemplateList, - deepCopy_v1beta3_PodTemplateSpec, - deepCopy_v1beta3_Probe, - deepCopy_v1beta3_RBDVolumeSource, - deepCopy_v1beta3_RangeAllocation, - deepCopy_v1beta3_ReplicationController, - deepCopy_v1beta3_ReplicationControllerList, - deepCopy_v1beta3_ReplicationControllerSpec, - deepCopy_v1beta3_ReplicationControllerStatus, - deepCopy_v1beta3_ResourceQuota, - deepCopy_v1beta3_ResourceQuotaList, - deepCopy_v1beta3_ResourceQuotaSpec, - deepCopy_v1beta3_ResourceQuotaStatus, - deepCopy_v1beta3_ResourceRequirements, - deepCopy_v1beta3_RunAsUserStrategyOptions, - deepCopy_v1beta3_SELinuxContextStrategyOptions, - deepCopy_v1beta3_SELinuxOptions, - deepCopy_v1beta3_Secret, - deepCopy_v1beta3_SecretList, - deepCopy_v1beta3_SecretVolumeSource, - deepCopy_v1beta3_SecurityContext, - deepCopy_v1beta3_SecurityContextConstraints, - deepCopy_v1beta3_SecurityContextConstraintsList, - deepCopy_v1beta3_SerializedReference, - deepCopy_v1beta3_Service, - deepCopy_v1beta3_ServiceAccount, - deepCopy_v1beta3_ServiceAccountList, - deepCopy_v1beta3_ServiceList, - deepCopy_v1beta3_ServicePort, - deepCopy_v1beta3_ServiceSpec, - deepCopy_v1beta3_ServiceStatus, - deepCopy_v1beta3_Status, - deepCopy_v1beta3_StatusCause, - deepCopy_v1beta3_StatusDetails, - deepCopy_v1beta3_SupplementalGroupsStrategyOptions, - deepCopy_v1beta3_TCPSocketAction, - deepCopy_v1beta3_TypeMeta, - deepCopy_v1beta3_Volume, - deepCopy_v1beta3_VolumeMount, - deepCopy_v1beta3_VolumeSource, - deepCopy_runtime_RawExtension, - deepCopy_util_IntOrString, - deepCopy_util_Time, - ) - if err != nil { - // if one of the deep copy functions is malformed, detect it immediately. - panic(err) - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go deleted file mode 100644 index 35c6f91d28d9..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go +++ /dev/null @@ -1,218 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 v1beta3 - -import ( - "strings" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" - "github.com/golang/glog" -) - -func addDefaultingFuncs() { - api.Scheme.AddDefaultingFuncs( - func(obj *ReplicationController) { - var labels map[string]string - if obj.Spec.Template != nil { - labels = obj.Spec.Template.Labels - } - // TODO: support templates defined elsewhere when we support them in the API - if labels != nil { - if len(obj.Spec.Selector) == 0 { - obj.Spec.Selector = labels - } - if len(obj.Labels) == 0 { - obj.Labels = labels - } - } - if obj.Spec.Replicas == nil { - obj.Spec.Replicas = new(int) - *obj.Spec.Replicas = 0 - } - }, - func(obj *Volume) { - if util.AllPtrFieldsNil(&obj.VolumeSource) { - obj.VolumeSource = VolumeSource{ - EmptyDir: &EmptyDirVolumeSource{}, - } - } - }, - func(obj *ContainerPort) { - if obj.Protocol == "" { - obj.Protocol = ProtocolTCP - } - }, - func(obj *Container) { - if obj.ImagePullPolicy == "" { - // TODO(dchen1107): Move ParseImageName code to pkg/util - parts := strings.Split(obj.Image, ":") - // Check image tag - if parts[len(parts)-1] == "latest" { - obj.ImagePullPolicy = PullAlways - } else { - obj.ImagePullPolicy = PullIfNotPresent - } - } - if obj.TerminationMessagePath == "" { - obj.TerminationMessagePath = TerminationMessagePathDefault - } - defaultSecurityContext(obj) - }, - func(obj *ServiceSpec) { - if obj.SessionAffinity == "" { - obj.SessionAffinity = ServiceAffinityNone - } - if obj.Type == "" { - if obj.CreateExternalLoadBalancer { - obj.Type = ServiceTypeLoadBalancer - } else { - obj.Type = ServiceTypeClusterIP - } - } else if obj.Type == ServiceTypeLoadBalancer { - obj.CreateExternalLoadBalancer = true - } - for i := range obj.Ports { - sp := &obj.Ports[i] - if sp.Protocol == "" { - sp.Protocol = ProtocolTCP - } - if sp.TargetPort == util.NewIntOrStringFromInt(0) || sp.TargetPort == util.NewIntOrStringFromString("") { - sp.TargetPort = util.NewIntOrStringFromInt(sp.Port) - } - } - }, - func(obj *PodSpec) { - if obj.DNSPolicy == "" { - obj.DNSPolicy = DNSClusterFirst - } - if obj.RestartPolicy == "" { - obj.RestartPolicy = RestartPolicyAlways - } - if obj.HostNetwork { - defaultHostNetworkPorts(&obj.Containers) - } - }, - func(obj *Probe) { - if obj.TimeoutSeconds == 0 { - obj.TimeoutSeconds = 1 - } - }, - func(obj *Secret) { - if obj.Type == "" { - obj.Type = SecretTypeOpaque - } - }, - func(obj *PersistentVolume) { - if obj.Status.Phase == "" { - obj.Status.Phase = VolumePending - } - if obj.Spec.PersistentVolumeReclaimPolicy == "" { - obj.Spec.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimRetain - } - }, - func(obj *PersistentVolumeClaim) { - if obj.Status.Phase == "" { - obj.Status.Phase = ClaimPending - } - }, - func(obj *Endpoints) { - for i := range obj.Subsets { - ss := &obj.Subsets[i] - for i := range ss.Ports { - ep := &ss.Ports[i] - if ep.Protocol == "" { - ep.Protocol = ProtocolTCP - } - } - } - }, - func(obj *HTTPGetAction) { - if obj.Path == "" { - obj.Path = "/" - } - if obj.Scheme == "" { - obj.Scheme = URISchemeHTTP - } - }, - func(obj *NamespaceStatus) { - if obj.Phase == "" { - obj.Phase = NamespaceActive - } - }, - func(obj *Node) { - if obj.Spec.ExternalID == "" { - obj.Spec.ExternalID = obj.Name - } - }, - func(obj *ObjectFieldSelector) { - if obj.APIVersion == "" { - obj.APIVersion = "v1beta3" - } - }, - ) -} - -// With host networking default all container ports to host ports. -func defaultHostNetworkPorts(containers *[]Container) { - for i := range *containers { - for j := range (*containers)[i].Ports { - if (*containers)[i].Ports[j].HostPort == 0 { - (*containers)[i].Ports[j].HostPort = (*containers)[i].Ports[j].ContainerPort - } - } - } -} - -// defaultSecurityContext performs the downward and upward merges of a pod definition -func defaultSecurityContext(container *Container) { - if container.SecurityContext == nil { - if (len(container.Capabilities.Add) == 0) && (len(container.Capabilities.Drop) == 0) && (container.Privileged == false) { - return - } - glog.V(5).Infof("creating security context for container %s", container.Name) - container.SecurityContext = &SecurityContext{} - } - // if there are no capabilities defined on the SecurityContext then copy the container settings - if container.SecurityContext.Capabilities == nil { - container.SecurityContext.Capabilities = &container.Capabilities - } else { - // if there are capabilities defined on the security context and the container setting is - // empty then assume that it was left off the pod definition and ensure that the container - // settings match the security context settings (checked by the convert functions). If - // there are settings in both then don't touch it, the converter will error if they don't - // match - if len(container.Capabilities.Add) == 0 { - container.Capabilities.Add = container.SecurityContext.Capabilities.Add - } - if len(container.Capabilities.Drop) == 0 { - container.Capabilities.Drop = container.SecurityContext.Capabilities.Drop - } - } - // if there are no privileged settings on the security context then copy the container settings - if container.SecurityContext.Privileged == nil { - container.SecurityContext.Privileged = &container.Privileged - } else { - // we don't have a good way to know if container.Privileged was set or just defaulted to false - // so the best we can do here is check if the securityContext is set to true and the - // container is set to false and assume that the Privileged field was left off the container - // definition and not an intentional mismatch - if *container.SecurityContext.Privileged && !container.Privileged { - container.Privileged = *container.SecurityContext.Privileged - } - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go deleted file mode 100644 index b9c232400113..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go +++ /dev/null @@ -1,471 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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 v1beta3_test - -import ( - "reflect" - "testing" - - "k8s.io/kubernetes/pkg/api" - versioned "k8s.io/kubernetes/pkg/api/v1beta3" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" -) - -func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { - data, err := versioned.Codec.Encode(obj) - if err != nil { - t.Errorf("%v\n %#v", err, obj) - return nil - } - obj2, err := api.Codec.Decode(data) - if err != nil { - t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj) - return nil - } - obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object) - err = api.Scheme.Convert(obj2, obj3) - if err != nil { - t.Errorf("%v\nSource: %#v", err, obj2) - return nil - } - return obj3 -} - -func TestSetDefaultReplicationController(t *testing.T) { - tests := []struct { - rc *versioned.ReplicationController - expectLabels bool - expectSelector bool - }{ - { - rc: &versioned.ReplicationController{ - Spec: versioned.ReplicationControllerSpec{ - Template: &versioned.PodTemplateSpec{ - ObjectMeta: versioned.ObjectMeta{ - Labels: map[string]string{ - "foo": "bar", - }, - }, - }, - }, - }, - expectLabels: true, - expectSelector: true, - }, - { - rc: &versioned.ReplicationController{ - ObjectMeta: versioned.ObjectMeta{ - Labels: map[string]string{ - "bar": "foo", - }, - }, - Spec: versioned.ReplicationControllerSpec{ - Template: &versioned.PodTemplateSpec{ - ObjectMeta: versioned.ObjectMeta{ - Labels: map[string]string{ - "foo": "bar", - }, - }, - }, - }, - }, - expectLabels: false, - expectSelector: true, - }, - { - rc: &versioned.ReplicationController{ - ObjectMeta: versioned.ObjectMeta{ - Labels: map[string]string{ - "bar": "foo", - }, - }, - Spec: versioned.ReplicationControllerSpec{ - Selector: map[string]string{ - "some": "other", - }, - Template: &versioned.PodTemplateSpec{ - ObjectMeta: versioned.ObjectMeta{ - Labels: map[string]string{ - "foo": "bar", - }, - }, - }, - }, - }, - expectLabels: false, - expectSelector: false, - }, - { - rc: &versioned.ReplicationController{ - Spec: versioned.ReplicationControllerSpec{ - Selector: map[string]string{ - "some": "other", - }, - Template: &versioned.PodTemplateSpec{ - ObjectMeta: versioned.ObjectMeta{ - Labels: map[string]string{ - "foo": "bar", - }, - }, - }, - }, - }, - expectLabels: true, - expectSelector: false, - }, - } - - for _, test := range tests { - rc := test.rc - obj2 := roundTrip(t, runtime.Object(rc)) - rc2, ok := obj2.(*versioned.ReplicationController) - if !ok { - t.Errorf("unexpected object: %v", rc2) - t.FailNow() - } - if test.expectSelector != reflect.DeepEqual(rc2.Spec.Selector, rc2.Spec.Template.Labels) { - if test.expectSelector { - t.Errorf("expected: %v, got: %v", rc2.Spec.Template.Labels, rc2.Spec.Selector) - } else { - t.Errorf("unexpected equality: %v", rc.Spec.Selector) - } - } - if test.expectLabels != reflect.DeepEqual(rc2.Labels, rc2.Spec.Template.Labels) { - if test.expectLabels { - t.Errorf("expected: %v, got: %v", rc2.Spec.Template.Labels, rc2.Labels) - } else { - t.Errorf("unexpected equality: %v", rc.Labels) - } - } - } -} - -func TestSetDefaultService(t *testing.T) { - svc := &versioned.Service{} - obj2 := roundTrip(t, runtime.Object(svc)) - svc2 := obj2.(*versioned.Service) - if svc2.Spec.SessionAffinity != versioned.ServiceAffinityNone { - t.Errorf("Expected default session affinity type:%s, got: %s", versioned.ServiceAffinityNone, svc2.Spec.SessionAffinity) - } - if svc2.Spec.Type != versioned.ServiceTypeClusterIP { - t.Errorf("Expected default type:%s, got: %s", versioned.ServiceTypeClusterIP, svc2.Spec.Type) - } -} - -func TestSetDefaultServiceWithLoadbalancer(t *testing.T) { - svc := &versioned.Service{} - svc.Spec.CreateExternalLoadBalancer = true - obj2 := roundTrip(t, runtime.Object(svc)) - svc2 := obj2.(*versioned.Service) - if svc2.Spec.Type != versioned.ServiceTypeLoadBalancer { - t.Errorf("Expected default type:%s, got: %s", versioned.ServiceTypeLoadBalancer, svc2.Spec.Type) - } -} - -func TestSetDefaultSecret(t *testing.T) { - s := &versioned.Secret{} - obj2 := roundTrip(t, runtime.Object(s)) - s2 := obj2.(*versioned.Secret) - - if s2.Type != versioned.SecretTypeOpaque { - t.Errorf("Expected secret type %v, got %v", versioned.SecretTypeOpaque, s2.Type) - } -} - -func TestSetDefaultPersistentVolume(t *testing.T) { - pv := &versioned.PersistentVolume{} - obj2 := roundTrip(t, runtime.Object(pv)) - pv2 := obj2.(*versioned.PersistentVolume) - - if pv2.Status.Phase != versioned.VolumePending { - t.Errorf("Expected volume phase %v, got %v", versioned.VolumePending, pv2.Status.Phase) - } - if pv2.Spec.PersistentVolumeReclaimPolicy != versioned.PersistentVolumeReclaimRetain { - t.Errorf("Expected pv reclaim policy %v, got %v", versioned.PersistentVolumeReclaimRetain, pv2.Spec.PersistentVolumeReclaimPolicy) - } -} - -func TestSetDefaultPersistentVolumeClaim(t *testing.T) { - pvc := &versioned.PersistentVolumeClaim{} - obj2 := roundTrip(t, runtime.Object(pvc)) - pvc2 := obj2.(*versioned.PersistentVolumeClaim) - - if pvc2.Status.Phase != versioned.ClaimPending { - t.Errorf("Expected claim phase %v, got %v", versioned.ClaimPending, pvc2.Status.Phase) - } -} - -func TestSetDefaulEndpointsProtocol(t *testing.T) { - in := &versioned.Endpoints{Subsets: []versioned.EndpointSubset{ - {Ports: []versioned.EndpointPort{{}, {Protocol: "UDP"}, {}}}, - }} - obj := roundTrip(t, runtime.Object(in)) - out := obj.(*versioned.Endpoints) - - for i := range out.Subsets { - for j := range out.Subsets[i].Ports { - if in.Subsets[i].Ports[j].Protocol == "" { - if out.Subsets[i].Ports[j].Protocol != versioned.ProtocolTCP { - t.Errorf("Expected protocol %s, got %s", versioned.ProtocolTCP, out.Subsets[i].Ports[j].Protocol) - } - } else { - if out.Subsets[i].Ports[j].Protocol != in.Subsets[i].Ports[j].Protocol { - t.Errorf("Expected protocol %s, got %s", in.Subsets[i].Ports[j].Protocol, out.Subsets[i].Ports[j].Protocol) - } - } - } - } -} - -func TestSetDefaulServiceTargetPort(t *testing.T) { - in := &versioned.Service{Spec: versioned.ServiceSpec{Ports: []versioned.ServicePort{{Port: 1234}}}} - obj := roundTrip(t, runtime.Object(in)) - out := obj.(*versioned.Service) - if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromInt(1234) { - t.Errorf("Expected TargetPort to be defaulted, got %s", out.Spec.Ports[0].TargetPort) - } - - in = &versioned.Service{Spec: versioned.ServiceSpec{Ports: []versioned.ServicePort{{Port: 1234, TargetPort: util.NewIntOrStringFromInt(5678)}}}} - obj = roundTrip(t, runtime.Object(in)) - out = obj.(*versioned.Service) - if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromInt(5678) { - t.Errorf("Expected TargetPort to be unchanged, got %s", out.Spec.Ports[0].TargetPort) - } -} - -func TestSetDefaultServicePort(t *testing.T) { - // Unchanged if set. - in := &versioned.Service{Spec: versioned.ServiceSpec{ - Ports: []versioned.ServicePort{ - {Protocol: "UDP", Port: 9376, TargetPort: util.NewIntOrStringFromString("p")}, - {Protocol: "UDP", Port: 8675, TargetPort: util.NewIntOrStringFromInt(309)}, - }, - }} - out := roundTrip(t, runtime.Object(in)).(*versioned.Service) - if out.Spec.Ports[0].Protocol != versioned.ProtocolUDP { - t.Errorf("Expected protocol %s, got %s", versioned.ProtocolUDP, out.Spec.Ports[0].Protocol) - } - if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromString("p") { - t.Errorf("Expected port %d, got %s", in.Spec.Ports[0].Port, out.Spec.Ports[0].TargetPort) - } - if out.Spec.Ports[1].Protocol != versioned.ProtocolUDP { - t.Errorf("Expected protocol %s, got %s", versioned.ProtocolUDP, out.Spec.Ports[1].Protocol) - } - if out.Spec.Ports[1].TargetPort != util.NewIntOrStringFromInt(309) { - t.Errorf("Expected port %d, got %s", in.Spec.Ports[1].Port, out.Spec.Ports[1].TargetPort) - } - - // Defaulted. - in = &versioned.Service{Spec: versioned.ServiceSpec{ - Ports: []versioned.ServicePort{ - {Protocol: "", Port: 9376, TargetPort: util.NewIntOrStringFromString("")}, - {Protocol: "", Port: 8675, TargetPort: util.NewIntOrStringFromInt(0)}, - }, - }} - out = roundTrip(t, runtime.Object(in)).(*versioned.Service) - if out.Spec.Ports[0].Protocol != versioned.ProtocolTCP { - t.Errorf("Expected protocol %s, got %s", versioned.ProtocolTCP, out.Spec.Ports[0].Protocol) - } - if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromInt(in.Spec.Ports[0].Port) { - t.Errorf("Expected port %d, got %d", in.Spec.Ports[0].Port, out.Spec.Ports[0].TargetPort) - } - if out.Spec.Ports[1].Protocol != versioned.ProtocolTCP { - t.Errorf("Expected protocol %s, got %s", versioned.ProtocolTCP, out.Spec.Ports[1].Protocol) - } - if out.Spec.Ports[1].TargetPort != util.NewIntOrStringFromInt(in.Spec.Ports[1].Port) { - t.Errorf("Expected port %d, got %d", in.Spec.Ports[1].Port, out.Spec.Ports[1].TargetPort) - } -} - -func TestSetDefaultNamespace(t *testing.T) { - s := &versioned.Namespace{} - obj2 := roundTrip(t, runtime.Object(s)) - s2 := obj2.(*versioned.Namespace) - - if s2.Status.Phase != versioned.NamespaceActive { - t.Errorf("Expected phase %v, got %v", versioned.NamespaceActive, s2.Status.Phase) - } -} - -func TestSetDefaultPodSpecHostNetwork(t *testing.T) { - portNum := 8080 - s := versioned.PodSpec{} - s.HostNetwork = true - s.Containers = []versioned.Container{ - { - Ports: []versioned.ContainerPort{ - { - ContainerPort: portNum, - }, - }, - }, - } - pod := &versioned.Pod{ - Spec: s, - } - obj2 := roundTrip(t, runtime.Object(pod)) - pod2 := obj2.(*versioned.Pod) - s2 := pod2.Spec - - hostPortNum := s2.Containers[0].Ports[0].HostPort - if hostPortNum != portNum { - t.Errorf("Expected container port to be defaulted, was made %d instead of %d", hostPortNum, portNum) - } -} - -func TestSetDefaultNodeExternalID(t *testing.T) { - name := "node0" - n := &versioned.Node{} - n.Name = name - obj2 := roundTrip(t, runtime.Object(n)) - n2 := obj2.(*versioned.Node) - if n2.Spec.ExternalID != name { - t.Errorf("Expected default External ID: %s, got: %s", name, n2.Spec.ExternalID) - } - if n2.Spec.ProviderID != "" { - t.Errorf("Expected empty default Cloud Provider ID, got: %s", n2.Spec.ProviderID) - } -} - -func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { - s := versioned.PodSpec{ - Containers: []versioned.Container{ - { - Env: []versioned.EnvVar{ - { - ValueFrom: &versioned.EnvVarSource{ - FieldRef: &versioned.ObjectFieldSelector{}, - }, - }, - }, - }, - }, - } - pod := &versioned.Pod{ - Spec: s, - } - obj2 := roundTrip(t, runtime.Object(pod)) - pod2 := obj2.(*versioned.Pod) - s2 := pod2.Spec - - apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion - if apiVersion != "v1beta3" { - t.Errorf("Expected default APIVersion v1beta3, got: %v", apiVersion) - } -} - -func TestSetDefaultSecurityContext(t *testing.T) { - priv := false - privTrue := true - testCases := map[string]struct { - c versioned.Container - }{ - "downward defaulting caps": { - c: versioned.Container{ - Privileged: false, - Capabilities: versioned.Capabilities{ - Add: []versioned.Capability{"foo"}, - Drop: []versioned.Capability{"bar"}, - }, - SecurityContext: &versioned.SecurityContext{ - Privileged: &priv, - }, - }, - }, - "downward defaulting priv": { - c: versioned.Container{ - Privileged: false, - Capabilities: versioned.Capabilities{ - Add: []versioned.Capability{"foo"}, - Drop: []versioned.Capability{"bar"}, - }, - SecurityContext: &versioned.SecurityContext{ - Capabilities: &versioned.Capabilities{ - Add: []versioned.Capability{"foo"}, - Drop: []versioned.Capability{"bar"}, - }, - }, - }, - }, - "upward defaulting caps": { - c: versioned.Container{ - Privileged: false, - SecurityContext: &versioned.SecurityContext{ - Privileged: &priv, - Capabilities: &versioned.Capabilities{ - Add: []versioned.Capability{"biz"}, - Drop: []versioned.Capability{"baz"}, - }, - }, - }, - }, - "upward defaulting priv": { - c: versioned.Container{ - Capabilities: versioned.Capabilities{ - Add: []versioned.Capability{"foo"}, - Drop: []versioned.Capability{"bar"}, - }, - SecurityContext: &versioned.SecurityContext{ - Privileged: &privTrue, - Capabilities: &versioned.Capabilities{ - Add: []versioned.Capability{"foo"}, - Drop: []versioned.Capability{"bar"}, - }, - }, - }, - }, - } - - pod := &versioned.Pod{ - Spec: versioned.PodSpec{}, - } - - for k, v := range testCases { - pod.Spec.Containers = []versioned.Container{v.c} - obj := roundTrip(t, runtime.Object(pod)) - defaultedPod := obj.(*versioned.Pod) - c := defaultedPod.Spec.Containers[0] - if isEqual, issues := areSecurityContextAndContainerEqual(&c); !isEqual { - t.Errorf("test case %s expected the security context to have the same values as the container but found %#v", k, issues) - } - } -} - -func areSecurityContextAndContainerEqual(c *versioned.Container) (bool, []string) { - issues := make([]string, 0) - equal := true - - if c.SecurityContext == nil || c.SecurityContext.Privileged == nil || c.SecurityContext.Capabilities == nil { - equal = false - issues = append(issues, "Expected non nil settings for SecurityContext") - return equal, issues - } - if *c.SecurityContext.Privileged != c.Privileged { - equal = false - issues = append(issues, "The defaulted SecurityContext.Privileged value did not match the container value") - } - if !reflect.DeepEqual(c.Capabilities.Add, c.Capabilities.Add) { - equal = false - issues = append(issues, "The defaulted SecurityContext.Capabilities.Add did not match the container settings") - } - if !reflect.DeepEqual(c.Capabilities.Drop, c.Capabilities.Drop) { - equal = false - issues = append(issues, "The defaulted SecurityContext.Capabilities.Drop did not match the container settings") - } - return equal, issues -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/register.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/register.go deleted file mode 100644 index 974dda550350..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/register.go +++ /dev/null @@ -1,134 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 v1beta3 - -import ( - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/registered" - "k8s.io/kubernetes/pkg/runtime" -) - -// Codec encodes internal objects to the v1beta3 scheme -var Codec = runtime.CodecFor(api.Scheme, "v1beta3") - -func init() { - // Check if v1beta3 is in the list of supported API versions. - if !registered.IsRegisteredAPIVersion("v1beta3") { - return - } - - // Register the API. - addKnownTypes() - addConversionFuncs() - addDefaultingFuncs() -} - -// Adds the list of known types to api.Scheme. -func addKnownTypes() { - api.Scheme.AddKnownTypes("v1beta3", - &Pod{}, - &PodList{}, - &PodStatusResult{}, - &PodTemplate{}, - &PodTemplateList{}, - &ReplicationController{}, - &ReplicationControllerList{}, - &Service{}, - &ServiceList{}, - &Endpoints{}, - &EndpointsList{}, - &Node{}, - &NodeList{}, - &Binding{}, - &Status{}, - &Event{}, - &EventList{}, - &List{}, - &LimitRange{}, - &LimitRangeList{}, - &ResourceQuota{}, - &ResourceQuotaList{}, - &Namespace{}, - &NamespaceList{}, - &Secret{}, - &SecretList{}, - &ServiceAccount{}, - &ServiceAccountList{}, - &PersistentVolume{}, - &PersistentVolumeList{}, - &PersistentVolumeClaim{}, - &PersistentVolumeClaimList{}, - &DeleteOptions{}, - &ListOptions{}, - &PodLogOptions{}, - &PodExecOptions{}, - &PodProxyOptions{}, - &ComponentStatus{}, - &ComponentStatusList{}, - &SerializedReference{}, - &RangeAllocation{}, - &SecurityContextConstraints{}, - &SecurityContextConstraintsList{}, - ) - // Legacy names are supported - api.Scheme.AddKnownTypeWithName("v1beta3", "Minion", &Node{}) - api.Scheme.AddKnownTypeWithName("v1beta3", "MinionList", &NodeList{}) -} - -func (*Pod) IsAnAPIObject() {} -func (*PodList) IsAnAPIObject() {} -func (*PodStatusResult) IsAnAPIObject() {} -func (*PodTemplate) IsAnAPIObject() {} -func (*PodTemplateList) IsAnAPIObject() {} -func (*ReplicationController) IsAnAPIObject() {} -func (*ReplicationControllerList) IsAnAPIObject() {} -func (*Service) IsAnAPIObject() {} -func (*ServiceList) IsAnAPIObject() {} -func (*Endpoints) IsAnAPIObject() {} -func (*EndpointsList) IsAnAPIObject() {} -func (*Node) IsAnAPIObject() {} -func (*NodeList) IsAnAPIObject() {} -func (*Binding) IsAnAPIObject() {} -func (*Status) IsAnAPIObject() {} -func (*Event) IsAnAPIObject() {} -func (*EventList) IsAnAPIObject() {} -func (*List) IsAnAPIObject() {} -func (*LimitRange) IsAnAPIObject() {} -func (*LimitRangeList) IsAnAPIObject() {} -func (*ResourceQuota) IsAnAPIObject() {} -func (*ResourceQuotaList) IsAnAPIObject() {} -func (*Namespace) IsAnAPIObject() {} -func (*NamespaceList) IsAnAPIObject() {} -func (*Secret) IsAnAPIObject() {} -func (*SecretList) IsAnAPIObject() {} -func (*ServiceAccount) IsAnAPIObject() {} -func (*ServiceAccountList) IsAnAPIObject() {} -func (*PersistentVolume) IsAnAPIObject() {} -func (*PersistentVolumeList) IsAnAPIObject() {} -func (*PersistentVolumeClaim) IsAnAPIObject() {} -func (*PersistentVolumeClaimList) IsAnAPIObject() {} -func (*DeleteOptions) IsAnAPIObject() {} -func (*ListOptions) IsAnAPIObject() {} -func (*PodLogOptions) IsAnAPIObject() {} -func (*PodExecOptions) IsAnAPIObject() {} -func (*PodProxyOptions) IsAnAPIObject() {} -func (*ComponentStatus) IsAnAPIObject() {} -func (*ComponentStatusList) IsAnAPIObject() {} -func (*SerializedReference) IsAnAPIObject() {} -func (*RangeAllocation) IsAnAPIObject() {} -func (*SecurityContextConstraints) IsAnAPIObject() {} -func (*SecurityContextConstraintsList) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go deleted file mode 100644 index 7e905538c024..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go +++ /dev/null @@ -1,2219 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 v1beta3 - -import ( - "k8s.io/kubernetes/pkg/api/resource" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/types" - "k8s.io/kubernetes/pkg/util" -) - -// Common string formats -// --------------------- -// Many fields in this API have formatting requirements. The commonly used -// formats are defined here. -// -// C_IDENTIFIER: This is a string that conforms to the definition of an "identifier" -// in the C language. This is captured by the following regex: -// [A-Za-z_][A-Za-z0-9_]* -// This defines the format, but not the length restriction, which should be -// specified at the definition of any field of this type. -// -// DNS_LABEL: This is a string, no more than 63 characters long, that conforms -// to the definition of a "label" in RFCs 1035 and 1123. This is captured -// by the following regex: -// [a-z0-9]([-a-z0-9]*[a-z0-9])? -// -// DNS_SUBDOMAIN: This is a string, no more than 253 characters long, that conforms -// to the definition of a "subdomain" in RFCs 1035 and 1123. This is captured -// by the following regex: -// [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)* -// or more simply: -// DNS_LABEL(\.DNS_LABEL)* -// -// IANA_SVC_NAME: This is a string, no more than 15 characters long, that -// conforms to the definition of IANA service name in RFC 6335. -// It must contains at least one letter [a-z] and it must contains only [a-z0-9-]. -// Hypens ('-') cannot be leading or trailing character of the string -// and cannot be adjacent to other hyphens. - -// TypeMeta describes an individual object in an API response or request -// with strings representing the type of the object and its API schema version. -// Structures that are versioned or persisted should inline TypeMeta. -type TypeMeta struct { - // Kind is a string value representing the REST resource this object represents. - // Servers may infer this from the endpoint the client submits requests to. - Kind string `json:"kind,omitempty" description:"kind of object, in CamelCase; cannot be updated"` - - // APIVersion defines the versioned schema of this representation of an object. - // Servers should convert recognized schemas to the latest internal value, and - // may reject unrecognized values. - APIVersion string `json:"apiVersion,omitempty" description:"version of the schema the object should have"` -} - -// ListMeta describes metadata that synthetic resources must have, including lists and -// various status objects. -type ListMeta struct { - // SelfLink is a URL representing this object. - SelfLink string `json:"selfLink,omitempty" description:"URL for the object; populated by the system, read-only"` - - // An opaque value that represents the version of this response for use with optimistic - // concurrency and change monitoring endpoints. Clients must treat these values as opaque - // and values may only be valid for a particular resource or set of resources. Only servers - // will generate resource versions. - ResourceVersion string `json:"resourceVersion,omitempty" description:"string that identifies the internal version of this object that can be used by clients to determine when objects have changed; populated by the system, read-only; value must be treated as opaque by clients and passed unmodified back to the server: http://releases.k8s.io/v1.0.0/docs/api-conventions.md#concurrency-control-and-consistency"` -} - -// ObjectMeta is metadata that all persisted resources must have, which includes all objects -// users must create. -type ObjectMeta struct { - // Name is unique within a namespace. Name is required when creating resources, although - // some resources may allow a client to request the generation of an appropriate name - // automatically. Name is primarily intended for creation idempotence and configuration - // definition. - Name string `json:"name,omitempty" description:"string that identifies an object. Must be unique within a namespace; cannot be updated"` - - // GenerateName indicates that the name should be made unique by the server prior to persisting - // it. A non-empty value for the field indicates the name will be made unique (and the name - // returned to the client will be different than the name passed). The value of this field will - // be combined with a unique suffix on the server if the Name field has not been provided. - // The provided value must be valid within the rules for Name, and may be truncated by the length - // of the suffix required to make the value unique on the server. - // - // If this field is specified, and Name is not present, the server will NOT return a 409 if the - // generated name exists - instead, it will either return 201 Created or 500 with Reason - // ServerTimeout indicating a unique name could not be found in the time allotted, and the client - // should retry (optionally after the time indicated in the Retry-After header). - GenerateName string `json:"generateName,omitempty" description:"an optional prefix to use to generate a unique name; has the same validation rules as name; optional, and is applied only name if is not specified"` - - // Namespace defines the space within which name must be unique. An empty namespace is - // equivalent to the "default" namespace, but "default" is the canonical representation. - // Not all objects are required to be scoped to a namespace - the value of this field for - // those objects will be empty. - Namespace string `json:"namespace,omitempty" description:"namespace of the object; must be a DNS_LABEL; cannot be updated"` - - // SelfLink is a URL representing this object. - SelfLink string `json:"selfLink,omitempty" description:"URL for the object; populated by the system, read-only"` - - // UID is the unique in time and space value for this object. It is typically generated by - // the server on successful creation of a resource and is not allowed to change on PUT - // operations. - UID types.UID `json:"uid,omitempty" description:"unique UUID across space and time; populated by the system; read-only"` - - // An opaque value that represents the version of this resource. May be used for optimistic - // concurrency, change detection, and the watch operation on a resource or set of resources. - // Clients must treat these values as opaque and values may only be valid for a particular - // resource or set of resources. Only servers will generate resource versions. - ResourceVersion string `json:"resourceVersion,omitempty" description:"string that identifies the internal version of this object that can be used by clients to determine when objects have changed; populated by the system, read-only; value must be treated as opaque by clients and passed unmodified back to the server: http://releases.k8s.io/v1.0.0/docs/api-conventions.md#concurrency-control-and-consistency"` - - // A sequence number representing a specific generation of the desired state. - // Currently only implemented by replication controllers. - Generation int64 `json:"generation,omitempty" description:"a sequence number representing a specific generation of the desired state; populated by the system; read-only"` - - // CreationTimestamp is a timestamp representing the server time when this object was - // created. It is not guaranteed to be set in happens-before order across separate operations. - // Clients may not set this value. It is represented in RFC3339 form and is in UTC. - CreationTimestamp util.Time `json:"creationTimestamp,omitempty" description:"RFC 3339 date and time at which the object was created; populated by the system, read-only; null for lists"` - - // DeletionTimestamp is the time after which this resource will be deleted. This - // field is set by the server when a graceful deletion is requested by the user, and is not - // directly settable by a client. The resource will be deleted (no longer visible from - // resource lists, and not reachable by name) after the time in this field. Once set, this - // value may not be unset or be set further into the future, although it may be shortened - // or the resource may be deleted prior to this time. For example, a user may request that - // a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination - // signal to the containers in the pod. Once the resource is deleted in the API, the Kubelet - // will send a hard termination signal to the container. - DeletionTimestamp *util.Time `json:"deletionTimestamp,omitempty" description:"RFC 3339 date and time at which the object will be deleted; populated by the system when a graceful deletion is requested, read-only; if not set, graceful deletion of the object has not been requested"` - - // Number of seconds allowed for this object to gracefully terminate before - // it will be removed from the system. Only set when deletionTimestamp is also set. - // May only be shortened. - // Read-only. - DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty"` - - // Labels are key value pairs that may be used to scope and select individual resources. - // TODO: replace map[string]string with labels.LabelSet type - Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize objects; may match selectors of replication controllers and services"` - - // Annotations are unstructured key value data stored with a resource that may be set by - // external tooling. They are not queryable and should be preserved when modifying - // objects. - Annotations map[string]string `json:"annotations,omitempty" description:"map of string keys and values that can be used by external tooling to store and retrieve arbitrary metadata about objects"` -} - -const ( - // NamespaceDefault means the object is in the default namespace which is applied when not specified by clients - NamespaceDefault string = "default" - // NamespaceAll is the default argument to specify on a context when you want to list or filter resources across all namespaces - NamespaceAll string = "" -) - -// Volume represents a named volume in a pod that may be accessed by any containers in the pod. -type Volume struct { - // Required: This must be a DNS_LABEL. Each volume in a pod must have - // a unique name. - Name string `json:"name" description:"volume name; must be a DNS_LABEL and unique within the pod"` - // Source represents the location and type of a volume to mount. - // This is optional for now. If not specified, the Volume is implied to be an EmptyDir. - // This implied behavior is deprecated and will be removed in a future version. - VolumeSource `json:",inline"` -} - -// VolumeSource represents the source location of a volume to mount. -// Only one of its members may be specified. -type VolumeSource struct { - // HostPath represents a pre-existing file or directory on the host - // machine that is directly exposed to the container. This is generally - // used for system agents or other privileged things that are allowed - // to see the host machine. Most containers will NOT need this. - // TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not - // mount host directories as read/write. - HostPath *HostPathVolumeSource `json:"hostPath,omitempty" description:"pre-existing host file or directory; generally for privileged system daemons or other agents tied to the host"` - // EmptyDir represents a temporary directory that shares a pod's lifetime. - EmptyDir *EmptyDirVolumeSource `json:"emptyDir,omitempty" description:"temporary directory that shares a pod's lifetime"` - // GCEPersistentDisk represents a GCE Disk resource that is attached to a - // kubelet's host machine and then exposed to the pod. - GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty" description:"GCE disk resource attached to the host machine on demand"` - // AWSElasticBlockStore represents an AWS Disk resource that is attached to a - // kubelet's host machine and then exposed to the pod. - AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty" description:"AWS disk resource attached to the host machine on demand"` - // GitRepo represents a git repository at a particular revision. - GitRepo *GitRepoVolumeSource `json:"gitRepo,omitempty" description:"git repository at a particular revision"` - // Secret represents a secret that should populate this volume. - Secret *SecretVolumeSource `json:"secret,omitempty" description:"secret to populate volume"` - // NFS represents an NFS mount on the host that shares a pod's lifetime - NFS *NFSVolumeSource `json:"nfs,omitempty" description:"NFS volume that will be mounted in the host machine"` - // ISCSI represents an ISCSI Disk resource that is attached to a - // kubelet's host machine and then exposed to the pod. - ISCSI *ISCSIVolumeSource `json:"iscsi,omitempty" description:"iSCSI disk attached to host machine on demand"` - // Glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime - Glusterfs *GlusterfsVolumeSource `json:"glusterfs,omitempty" description:"Glusterfs volume that will be mounted on the host machine "` - // PersistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace - PersistentVolumeClaim *PersistentVolumeClaimVolumeSource `json:"persistentVolumeClaim,omitempty" description:"a reference to a PersistentVolumeClaim in the same namespace"` - // RBD represents a Rados Block Device mount on the host that shares a pod's lifetime - RBD *RBDVolumeSource `json:"rbd,omitempty" description:"rados block volume that will be mounted on the host machine"` - // Cinder represents a cinder volume attached and mounted on kubelets host machine - // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md - Cinder *CinderVolumeSource `json:"cinder,omitempty"` - // CephFS represents a Ceph FS mount on the host that shares a pod's lifetime - CephFS *CephFSVolumeSource `json:"cephfs,omitempty" description:"Ceph filesystem that will be mounted on the host machine"` - // DownwardAPI represents metadata about the pod that should populate this volume - DownwardAPI *DownwardAPIVolumeSource `json:"downwardAPI,omitempty"` - // Metadata represents metadata about the pod that should populate this volume - // NOTE: Deprecated in favor of DownwardAPI - Metadata *MetadataVolumeSource `json:"metadata,omitempty" description: "Metadata volume containing information about the pod"` -} - -type PersistentVolumeClaimVolumeSource struct { - // ClaimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume - ClaimName string `json:"claimName,omitempty" description:"the name of the claim in the same namespace to be mounted as a volume"` - // Optional: Defaults to false (read/write). ReadOnly here - // will force the ReadOnly setting in VolumeMounts - ReadOnly bool `json:"readOnly,omitempty" description:"mount volume as read-only when true; default false"` -} - -// Similar to VolumeSource but meant for the administrator who creates PVs. -// Exactly one of its members must be set. -type PersistentVolumeSource struct { - // GCEPersistentDisk represents a GCE Disk resource that is attached to a - // kubelet's host machine and then exposed to the pod. - GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty" description:"GCE disk resource provisioned by an admin"` - // AWSElasticBlockStore represents an AWS Disk resource that is attached to a - // kubelet's host machine and then exposed to the pod. - AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty" description:"AWS disk resource provisioned by an admin"` - // HostPath represents a directory on the host. - // This is useful for development and testing only. - // on-host storage is not supported in any way. - HostPath *HostPathVolumeSource `json:"hostPath,omitempty" description:"a HostPath provisioned by a developer or tester; for develment use only"` - // Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod - Glusterfs *GlusterfsVolumeSource `json:"glusterfs,omitempty" description:"Glusterfs volume resource provisioned by an admin"` - // NFS represents an NFS mount on the host - NFS *NFSVolumeSource `json:"nfs,omitempty" description:"NFS volume resource provisioned by an admin"` - // RBD represents a Rados Block Device mount on the host that shares a pod's lifetime - RBD *RBDVolumeSource `json:"rbd,omitempty" description:"rados block volume that will be mounted on the host machine"` - // ISCSI represents an ISCSI Disk resource that is attached to a - // kubelet's host machine and then exposed to the pod. - ISCSI *ISCSIVolumeSource `json:"iscsi,omitempty" description:"an iSCSI disk resource provisioned by an admin"` - // CephFS represents a Ceph FS mount on the host that shares a pod's lifetime - CephFS *CephFSVolumeSource `json:"cephfs,omitempty" description:"Ceph filesystem that will be mounted on the host machine"` - // Cinder represents a cinder volume attached and mounted on kubelets host machine - // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md - Cinder *CinderVolumeSource `json:"cinder,omitempty"` -} - -type PersistentVolume struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - //Spec defines a persistent volume owned by the cluster - Spec PersistentVolumeSpec `json:"spec,omitempty" description:"specification of a persistent volume as provisioned by an administrator"` - - // Status represents the current information about persistent volume. - Status PersistentVolumeStatus `json:"status,omitempty" description:"current status of a persistent volume; populated by the system, read-only"` -} - -type PersistentVolumeSpec struct { - // Resources represents the actual resources of the volume - Capacity ResourceList `json:"capacity,omitempty" description:"a description of the persistent volume's resources and capacity"` - // Source represents the location and type of a volume to mount. - PersistentVolumeSource `json:",inline" description:"the actual volume backing the persistent volume"` - // AccessModes contains all ways the volume can be mounted - AccessModes []PersistentVolumeAccessMode `json:"accessModes,omitempty" description:"all ways the volume can be mounted"` - // ClaimRef is part of a bi-directional binding between PersistentVolume and PersistentVolumeClaim. - // ClaimRef is expected to be non-nil when bound. - // claim.VolumeName is the authoritative bind between PV and PVC. - ClaimRef *ObjectReference `json:"claimRef,omitempty" description:"when bound, a reference to the bound claim"` - // Optional: what happens to a persistent volume when released from its claim. - PersistentVolumeReclaimPolicy PersistentVolumeReclaimPolicy `json:"persistentVolumeReclaimPolicy,omitempty" description:"what happens to a volume when released from its claim; Valid options are Retain (default) and Recycle. Recyling must be supported by the volume plugin underlying this persistent volume."` -} - -// PersistentVolumeReclaimPolicy describes a policy for end-of-life maintenance of persistent volumes -type PersistentVolumeReclaimPolicy string - -const ( - // PersistentVolumeReclaimRecycle means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim. - // The volume plugin must support Recycling. - PersistentVolumeReclaimRecycle PersistentVolumeReclaimPolicy = "Recycle" - // PersistentVolumeReclaimDelete means the volume will be deleted from Kubernetes on release from its claim. - // The volume plugin must support Deletion. - // TODO: implement w/ DeletableVolumePlugin - // PersistentVolumeReclaimDelete PersistentVolumeReclaimPolicy = "Delete" - // PersistentVolumeReclaimRetain means the volume will left in its current phase (Released) for manual reclamation by the administrator. - // The default policy is Retain. - PersistentVolumeReclaimRetain PersistentVolumeReclaimPolicy = "Retain" -) - -type PersistentVolumeStatus struct { - // Phase indicates if a volume is available, bound to a claim, or released by a claim - Phase PersistentVolumePhase `json:"phase,omitempty" description:"the current phase of a persistent volume"` - // A human-readable message indicating details about why the volume is in this state. - Message string `json:"message,omitempty" description:"human-readable message indicating details about why the volume is in this state"` - // Reason is a brief CamelCase string that describes any failure and is meant for machine parsing and tidy display in the CLI - Reason string `json:"reason,omitempty" description:"(brief) reason the volume is not is not available"` -} - -type PersistentVolumeList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#types-kinds"` - Items []PersistentVolume `json:"items,omitempty" description:"list of persistent volumes"` -} - -// PersistentVolumeClaim is a user's request for and claim to a persistent volume -type PersistentVolumeClaim struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Spec defines the volume requested by a pod author - Spec PersistentVolumeClaimSpec `json:"spec,omitempty" description:"the desired characteristics of a volume"` - - // Status represents the current information about a claim - Status PersistentVolumeClaimStatus `json:"status,omitempty" description:"the current status of a persistent volume claim; read-only"` -} - -type PersistentVolumeClaimList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#types-kinds"` - Items []PersistentVolumeClaim `json:"items,omitempty" description:"a list of persistent volume claims"` -} - -// PersistentVolumeClaimSpec describes the common attributes of storage devices -// and allows a Source for provider-specific attributes -type PersistentVolumeClaimSpec struct { - // Contains the types of access modes required - AccessModes []PersistentVolumeAccessMode `json:"accessModes,omitempty" description:"the desired access modes the volume should have"` - // Resources represents the minimum resources required - Resources ResourceRequirements `json:"resources,omitempty" description:"the desired resources the volume should have"` - // VolumeName is the binding reference to the PersistentVolume backing this claim - VolumeName string `json:"volumeName,omitempty" description:"the binding reference to the persistent volume backing this claim"` -} - -type PersistentVolumeClaimStatus struct { - // Phase represents the current phase of PersistentVolumeClaim - Phase PersistentVolumeClaimPhase `json:"phase,omitempty" description:"the current phase of the claim"` - // AccessModes contains all ways the volume backing the PVC can be mounted - AccessModes []PersistentVolumeAccessMode `json:"accessModes,omitempty" description:"the actual access modes the volume has"` - // Represents the actual resources of the underlying volume - Capacity ResourceList `json:"capacity,omitempty" description:"the actual resources the volume has"` -} - -type PersistentVolumeAccessMode string - -const ( - // can be mounted read/write mode to exactly 1 host - ReadWriteOnce PersistentVolumeAccessMode = "ReadWriteOnce" - // can be mounted in read-only mode to many hosts - ReadOnlyMany PersistentVolumeAccessMode = "ReadOnlyMany" - // can be mounted in read/write mode to many hosts - ReadWriteMany PersistentVolumeAccessMode = "ReadWriteMany" -) - -type PersistentVolumePhase string - -const ( - // used for PersistentVolumes that are not available - VolumePending PersistentVolumePhase = "Pending" - // used for PersistentVolumes that are not yet bound - // Available volumes are held by the binder and matched to PersistentVolumeClaims - VolumeAvailable PersistentVolumePhase = "Available" - // used for PersistentVolumes that are bound - VolumeBound PersistentVolumePhase = "Bound" - // used for PersistentVolumes where the bound PersistentVolumeClaim was deleted - // released volumes must be recycled before becoming available again - // this phase is used by the persistent volume claim binder to signal to another process to reclaim the resource - VolumeReleased PersistentVolumePhase = "Released" - // used for PersistentVolumes that failed to be correctly recycled or deleted after being released from a claim - VolumeFailed PersistentVolumePhase = "Failed" -) - -type PersistentVolumeClaimPhase string - -const ( - // used for PersistentVolumeClaims that are not yet bound - ClaimPending PersistentVolumeClaimPhase = "Pending" - // used for PersistentVolumeClaims that are bound - ClaimBound PersistentVolumeClaimPhase = "Bound" -) - -// HostPathVolumeSource represents bare host directory volume. -type HostPathVolumeSource struct { - Path string `json:"path" description:"path of the directory on the host"` -} - -type EmptyDirVolumeSource struct { - // Optional: what type of storage medium should back this directory. - // The default is "" which means to use the node's default medium. - Medium StorageMedium `json:"medium,omitempty" description:"type of storage used to back the volume; must be an empty string (default) or Memory"` -} - -// GlusterfsVolumeSource represents a Glusterfs Mount that lasts the lifetime of a pod -type GlusterfsVolumeSource struct { - // Required: EndpointsName is the endpoint name that details Glusterfs topology - EndpointsName string `json:"endpoints" description:"gluster hosts endpoints name"` - - // Required: Path is the Glusterfs volume path - Path string `json:"path" description:"path to gluster volume"` - - // Optional: Defaults to false (read/write). ReadOnly here will force - // the Glusterfs volume to be mounted with read-only permissions - ReadOnly bool `json:"readOnly,omitempty" description:"glusterfs volume to be mounted with read-only permissions"` -} - -// DownwardAPIVolumeSource represents a volume containing downward API info -type DownwardAPIVolumeSource struct { - // Items is a list of DownwardAPIVolume file - Items []DownwardAPIVolumeFile `json:"items,omitempty"` -} - -// DownwardAPIVolumeFile represents a single file containing information from the downward API -type DownwardAPIVolumeFile struct { - // Required: Path is the relative path name of the file to be created. Must not be absolute or contain the '..' path. Must be utf-8 encoded. The first item of the relative path must not start with '..' - Path string `json:"path"` - // Required: Selects a field of the pod: only annotations, labels, name and namespace are supported. - FieldRef ObjectFieldSelector `json:"fieldRef"` -} - -// MetadataVolumeSource represents a volume containing metadata about a pod. -// NOTE: Deprecated in favor of DownwardAPIVolumeSource -type MetadataVolumeSource struct { - // Items is a list of metadata file name - Items []MetadataFile `json:"items,omitempty" description:"list of metadata files"` -} - -// MetadataFile expresses information about a file holding pod metadata. -// NOTE: Deprecated in favor of DownwardAPIVolumeFile -type MetadataFile struct { - // Required: Name is the name of the file - Name string `json:"name" description:"the name of the file to be created"` - // Required: Selects a field of the pod: only annotations, labels, name and namespace are supported. - FieldRef ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod. Supported fields: metadata.annotations, metadata.labels, metadata.name, metadata.namespace"` -} - -// StorageMedium defines ways that storage can be allocated to a volume. -type StorageMedium string - -// RBDVolumeSource represents a Rados Block Device Mount that lasts the lifetime of a pod -type RBDVolumeSource struct { - // Required: CephMonitors is a collection of Ceph monitors - CephMonitors []string `json:"monitors" description:"a collection of Ceph monitors"` - // Required: RBDImage is the rados image name - RBDImage string `json:"image" description:"rados image name"` - // Required: Filesystem type to mount. - // Must be a filesystem type supported by the host operating system. - // Ex. "ext4", "xfs", "ntfs" - // TODO: how do we prevent errors in the filesystem from compromising the machine - FSType string `json:"fsType,omitempty" description:"file system type to mount, such as ext4, xfs, ntfs"` - // Optional: RadosPool is the rados pool name,default is rbd - RBDPool string `json:"pool" description:"rados pool name; default is rbd; optional"` - // Optional: RBDUser is the rados user name, default is admin - RadosUser string `json:"user" description:"rados user name; default is admin; optional"` - // Optional: Keyring is the path to key ring for RBDUser, default is /etc/ceph/keyring - Keyring string `json:"keyring" description:"keyring is the path to key ring for rados user; default is /etc/ceph/keyring; optional"` - // Optional: SecretRef is name of the authentication secret for RBDUser, default is empty. - SecretRef *LocalObjectReference `json:"secretRef" description:"name of a secret to authenticate the RBD user; if provided overrides keyring; optional"` - // Optional: Defaults to false (read/write). ReadOnly here will force - // the ReadOnly setting in VolumeMounts. - ReadOnly bool `json:"readOnly,omitempty" description:"rbd volume to be mounted with read-only permissions"` -} - -// CinderVolumeSource represents a cinder volume resource in Openstack. -// A Cinder volume must exist before mounting to a container. -// The volume must also be in the same region as the kubelet. -type CinderVolumeSource struct { - // volume id used to identify the volume in cinder - // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md - VolumeID string `json:"volumeID"` - // Required: Filesystem type to mount. - // Must be a filesystem type supported by the host operating system. - // Only ext3 and ext4 are allowed - // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md - FSType string `json:"fsType,omitempty"` - // Optional: Defaults to false (read/write). ReadOnly here will force - // the ReadOnly setting in VolumeMounts. - // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md - ReadOnly bool `json:"readOnly,omitempty"` -} - -// CephFSVolumeSource represents a Ceph Filesystem Mount that lasts the lifetime of a pod -type CephFSVolumeSource struct { - // Required: Monitors is a collection of Ceph monitors - Monitors []string `json:"monitors" description:"a collection of Ceph monitors"` - // Optional: User is the rados user name, default is admin - User string `json:"user,omitempty" description:"rados user name; default is admin; optional"` - // Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret - SecretFile string `json:"secretFile,omitempty" description:"path to secret for rados user; default is /etc/ceph/user.secret; optional"` - // Optional: SecretRef is reference to the authentication secret for User, default is empty. - SecretRef *LocalObjectReference `json:"secretRef,omitempty" description:"name of a secret to authenticate the user; if provided overrides keyring; optional"` - // Optional: Defaults to false (read/write). ReadOnly here will force - // the ReadOnly setting in VolumeMounts. - ReadOnly bool `json:"readOnly,omitempty" description:"Ceph fs to be mounted with read-only permissions"` -} - -const ( - StorageMediumDefault StorageMedium = "" // use whatever the default is for the node - StorageMediumMemory StorageMedium = "Memory" // use memory (tmpfs) -) - -// Protocol defines network protocols supported for things like conatiner ports. -type Protocol string - -const ( - // ProtocolTCP is the TCP protocol. - ProtocolTCP Protocol = "TCP" - // ProtocolUDP is the UDP protocol. - ProtocolUDP Protocol = "UDP" -) - -// GCEPersistentDiskVolumeSource represents a Persistent Disk resource in Google Compute Engine. -// -// A GCE PD must exist and be formatted before mounting to a container. -// The disk must also be in the same GCE project and zone as the kubelet. -// A GCE PD can only be mounted as read/write once. -type GCEPersistentDiskVolumeSource struct { - // Unique name of the PD resource. Used to identify the disk in GCE - PDName string `json:"pdName" description:"unique name of the PD resource in GCE"` - // Required: Filesystem type to mount. - // Must be a filesystem type supported by the host operating system. - // Ex. "ext4", "xfs", "ntfs" - // TODO: how do we prevent errors in the filesystem from compromising the machine - FSType string `json:"fsType" description:"file system type to mount, such as ext4, xfs, ntfs"` - // Optional: Partition on the disk to mount. - // If omitted, kubelet will attempt to mount the device name. - // Ex. For /dev/sda1, this field is "1", for /dev/sda, this field is 0 or empty. - Partition int `json:"partition,omitempty" description:"partition on the disk to mount (e.g., '1' for /dev/sda1); if omitted the plain device name (e.g., /dev/sda) will be mounted"` - // Optional: Defaults to false (read/write). ReadOnly here will force - // the ReadOnly setting in VolumeMounts. - ReadOnly bool `json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"` -} - -// AWSElasticBlockStoreVolumeSource represents a Persistent Disk resource in AWS. -// -// An AWS PD must exist and be formatted before mounting to a container. -// The disk must also be in the same AWS zone as the kubelet. -// A AWS PD can only be mounted on a single machine. -type AWSElasticBlockStoreVolumeSource struct { - // Unique id of the PD resource. Used to identify the disk in AWS - VolumeID string `json:"volumeID" description:"unique id of the PD resource in AWS"` - // Required: Filesystem type to mount. - // Must be a filesystem type supported by the host operating system. - // Ex. "ext4", "xfs", "ntfs" - // TODO: how do we prevent errors in the filesystem from compromising the machine - FSType string `json:"fsType" description:"file system type to mount, such as ext4, xfs, ntfs"` - // Optional: Partition on the disk to mount. - // If omitted, kubelet will attempt to mount the device name. - // Ex. For /dev/sda1, this field is "1", for /dev/sda, this field 0 or empty. - Partition int `json:"partition,omitempty" description:"partition on the disk to mount (e.g., '1' for /dev/sda1); if omitted the plain device name (e.g., /dev/sda) will be mounted"` - // Optional: Defaults to false (read/write). ReadOnly here will force - // the ReadOnly setting in VolumeMounts. - ReadOnly bool `json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"` -} - -// GitRepoVolumeSource represents a volume that is pulled from git when the pod is created. -type GitRepoVolumeSource struct { - // Repository URL - Repository string `json:"repository" description:"repository URL"` - // Commit hash, this is optional - Revision string `json:"revision,omitempty" description:"commit hash for the specified revision"` -} - -// SecretVolumeSource adapts a Secret into a VolumeSource -// -// http://releases.k8s.io/v1.0.0/docs/design/secrets.md -type SecretVolumeSource struct { - // Name of the secret in the pod's namespace to use - SecretName string `json:"secretName" description:"secretName is the name of a secret in the pod's namespace"` -} - -// NFSVolumeSource represents an NFS mount that lasts the lifetime of a pod -type NFSVolumeSource struct { - // Server is the hostname or IP address of the NFS server - Server string `json:"server" description:"the hostname or IP address of the NFS server"` - - // Path is the exported NFS share - Path string `json:"path" description:"the path that is exported by the NFS server"` - - // Optional: Defaults to false (read/write). ReadOnly here will force - // the NFS export to be mounted with read-only permissions - ReadOnly bool `json:"readOnly,omitempty" description:"forces the NFS export to be mounted with read-only permissions"` -} - -// A ISCSI Disk can only be mounted as read/write once. -type ISCSIVolumeSource struct { - // Required: iSCSI target portal - // the portal is either an IP or ip_addr:port if port is other than default (typically TCP ports 860 and 3260) - TargetPortal string `json:"targetPortal" description:"iSCSI target portal"` - // Required: target iSCSI Qualified Name - IQN string `json:"iqn" description:"iSCSI Qualified Name"` - // Required: iSCSI target lun number - Lun int `json:"lun" description:"iscsi target lun number"` - // Required: Filesystem type to mount. - // Must be a filesystem type supported by the host operating system. - // Ex. "ext4", "xfs", "ntfs" - // TODO: how do we prevent errors in the filesystem from compromising the machine - FSType string `json:"fsType" description:"file system type to mount, such as ext4, xfs, ntfs"` - // Optional: Defaults to false (read/write). ReadOnly here will force - // the ReadOnly setting in VolumeMounts. - ReadOnly bool `json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"` -} - -// ContainerPort represents a network port in a single container. -type ContainerPort struct { - // Optional: If specified, this must be a IANA_SVC_NAME. Each named port - // in a pod must have a unique name. - Name string `json:"name,omitempty" description:"name for the port that can be referred to by services; must be a IANA_SVC_NAME and unique within the pod"` - // Optional: If specified, this must be a valid port number, 0 < x < 65536. - // If HostNetwork is specified, this must match ContainerPort. - HostPort int `json:"hostPort,omitempty" description:"number of port to expose on the host; most containers do not need this"` - // Required: This must be a valid port number, 0 < x < 65536. - ContainerPort int `json:"containerPort" description:"number of port to expose on the pod's IP address"` - // Optional: Defaults to "TCP". - Protocol Protocol `json:"protocol,omitempty" description:"protocol for port; must be UDP or TCP; TCP if unspecified"` - // Optional: What host IP to bind the external port to. - HostIP string `json:"hostIP,omitempty" description:"host IP to bind the port to"` -} - -// VolumeMount describes a mounting of a Volume within a container. -type VolumeMount struct { - // Required: This must match the Name of a Volume [above]. - Name string `json:"name" description:"name of the volume to mount"` - // Optional: Defaults to false (read-write). - ReadOnly bool `json:"readOnly,omitempty" description:"mounted read-only if true, read-write otherwise (false or unspecified)"` - // Required. - MountPath string `json:"mountPath" description:"path within the container at which the volume should be mounted"` -} - -// EnvVar represents an environment variable present in a Container. -type EnvVar struct { - // Required: This must be a C_IDENTIFIER. - Name string `json:"name" description:"name of the environment variable; must be a C_IDENTIFIER"` - // Optional: no more than one of the following may be specified. - // Optional: Defaults to ""; variable references $(VAR_NAME) are expanded - // using the previous defined environment variables in the container and - // any service environment variables. If a variable cannot be resolved, - // the reference in the input string will be unchanged. The $(VAR_NAME) - // syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped - // references will never be expanded, regardless of whether the variable - // exists or not. - Value string `json:"value,omitempty" description:"value of the environment variable; defaults to empty string; variable references $(VAR_NAME) are expanded using the previously defined environment varibles in the container and any service environment variables; if a variable cannot be resolved, the reference in the input string will be unchanged; the $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME) ; escaped references will never be expanded, regardless of whether the variable exists or not"` - // Optional: Specifies a source the value of this var should come from. - ValueFrom *EnvVarSource `json:"valueFrom,omitempty" description:"source for the environment variable's value; cannot be used if value is not empty"` -} - -// EnvVarSource represents a source for the value of an EnvVar. -type EnvVarSource struct { - // Required: Selects a field of the pod; only name and namespace are supported. - FieldRef *ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod; only name and namespace are supported"` -} - -// ObjectFieldSelector selects an APIVersioned field of an object. -type ObjectFieldSelector struct { - // Optional: Version of the schema the FieldPath is written in terms of, defaults to "v1beta3" - APIVersion string `json:"apiVersion,omitempty" description:"version of the schema that fieldPath is written in terms of; defaults to v1beta3"` - // Required: Path of the field to select in the specified API version - FieldPath string `json:"fieldPath" description:"path of the field to select in the specified API version"` -} - -// HTTPGetAction describes an action based on HTTP Get requests. -type HTTPGetAction struct { - // Optional: Path to access on the HTTP server. - Path string `json:"path,omitempty" description:"path to access on the HTTP server"` - // Required: Name or number of the port to access on the container. - Port util.IntOrString `json:"port" description:"number or name of the port to access on the container; number must be in the range 1 to 65535; name must be a IANA_SVC_NAME"` - // Optional: Host name to connect to, defaults to the pod IP. - Host string `json:"host,omitempty" description:"hostname to connect to; defaults to pod IP"` - // Optional: Scheme to use for connecting to the host, defaults to HTTP. - Scheme URIScheme `json:"scheme,omitempty" description:"scheme to connect with, must be HTTP or HTTPS, defaults to HTTP"` -} - -// URIScheme identifies the scheme used for connection to a host for Get actions -type URIScheme string - -const ( - // URISchemeHTTP means that the scheme used will be http:// - URISchemeHTTP URIScheme = "HTTP" - // URISchemeHTTPS means that the scheme used will be https:// - URISchemeHTTPS URIScheme = "HTTPS" -) - -// TCPSocketAction describes an action based on opening a socket -type TCPSocketAction struct { - // Required: Port to connect to. - Port util.IntOrString `json:"port" description:"number or name of the port to access on the container; number must be in the range 1 to 65535; name must be a IANA_SVC_NAME"` -} - -// ExecAction describes a "run in container" action. -type ExecAction struct { - // Command is the command line to execute inside the container, the working directory for the - // command is root ('/') in the container's filesystem. The command is simply exec'd, it is - // not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - // a shell, you need to explicitly call out to that shell. - Command []string `json:"command,omitempty" description:"command line to execute inside the container; working directory for the command is root ('/') in the container's file system; the command is exec'd, not run inside a shell; exit status of 0 is treated as live/healthy and non-zero is unhealthy"` -} - -// Probe describes a liveness probe to be examined to the container. -type Probe struct { - // The action taken to determine the health of a container - Handler `json:",inline"` - // Length of time before health checking is activated. In seconds. - InitialDelaySeconds int64 `json:"initialDelaySeconds,omitempty" description:"number of seconds after the container has started before liveness probes are initiated"` - // Length of time before health checking times out. In seconds. - TimeoutSeconds int64 `json:"timeoutSeconds,omitempty" description:"number of seconds after which liveness probes timeout; defaults to 1 second"` -} - -// PullPolicy describes a policy for if/when to pull a container image -type PullPolicy string - -const ( - // PullAlways means that kubelet always attempts to pull the latest image. Container will fail If the pull fails. - PullAlways PullPolicy = "Always" - // PullNever means that kubelet never pulls an image, but only uses a local image. Container will fail if the image isn't present - PullNever PullPolicy = "Never" - // PullIfNotPresent means that kubelet pulls if the image isn't present on disk. Container will fail if the image isn't present and the pull fails. - PullIfNotPresent PullPolicy = "IfNotPresent" -) - -// Capability represent POSIX capabilities type -type Capability string - -// Capabilities represent POSIX capabilities that can be added or removed to a running container. -type Capabilities struct { - // Added capabilities - Add []Capability `json:"add,omitempty" description:"added capabilities"` - // Removed capabilities - Drop []Capability `json:"drop,omitempty" description:"droped capabilities"` -} - -// ResourceRequirements describes the compute resource requirements. -type ResourceRequirements struct { - // Limits describes the maximum amount of compute resources required. - Limits ResourceList `json:"limits,omitempty" description:"Maximum amount of compute resources allowed"` - // Requests describes the minimum amount of compute resources required. - // Note: 'Requests' are honored only for Persistent Volumes as of now. - // TODO: Update the scheduler to use 'Requests' in addition to 'Limits'. If Request is omitted for a container, - // it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value - Requests ResourceList `json:"requests,omitempty" description:"Minimum amount of resources requested; requests are honored only for persistent volumes as of now"` -} - -const ( - // TerminationMessagePathDefault means the default path to capture the application termination message running in a container - TerminationMessagePathDefault string = "/dev/termination-log" -) - -// Container represents a single container that is expected to be run on the host. -type Container struct { - // Required: This must be a DNS_LABEL. Each container in a pod must - // have a unique name. - Name string `json:"name" description:"name of the container; must be a DNS_LABEL and unique within the pod; cannot be updated"` - // Required. - Image string `json:"image" description:"Docker image name"` - // Optional: The docker image's entrypoint is used if this is not provided; cannot be updated. - // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - // cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax - // can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, - // regardless of whether the variable exists or not. - Command []string `json:"command,omitempty" description:"entrypoint array; not executed within a shell; the docker image's entrypoint is used if this is not provided; cannot be updated; variable references $(VAR_NAME) are expanded using the container's environment variables; if a variable cannot be resolved, the reference in the input string will be unchanged; the $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME) ; escaped references will never be expanded, regardless of whether the variable exists or not"` - // Optional: The docker image's cmd is used if this is not provided; cannot be updated. - // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - // cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax - // can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, - // regardless of whether the variable exists or not. - Args []string `json:"args,omitempty" description:"command array; the docker image's cmd is used if this is not provided; arguments to the entrypoint; cannot be updated; variable references $(VAR_NAME) are expanded using the container's environment variables; if a variable cannot be resolved, the reference in the input string will be unchanged; the $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME) ; escaped references will never be expanded, regardless of whether the variable exists or not"` - // Optional: Defaults to Docker's default. - WorkingDir string `json:"workingDir,omitempty" description:"container's working directory; defaults to image's default; cannot be updated"` - Ports []ContainerPort `json:"ports,omitempty" description:"list of ports to expose from the container; cannot be updated" patchStrategy:"merge" patchMergeKey:"containerPort"` - Env []EnvVar `json:"env,omitempty" description:"list of environment variables to set in the container; cannot be updated" patchStrategy:"merge" patchMergeKey:"name"` - Resources ResourceRequirements `json:"resources,omitempty" description:"Compute Resources required by this container; cannot be updated"` - VolumeMounts []VolumeMount `json:"volumeMounts,omitempty" description:"pod volumes to mount into the container's filesyste; cannot be updated" patchStrategy:"merge" patchMergeKey:"name"` - LivenessProbe *Probe `json:"livenessProbe,omitempty" description:"periodic probe of container liveness; container will be restarted if the probe fails; cannot be updated"` - ReadinessProbe *Probe `json:"readinessProbe,omitempty" description:"periodic probe of container service readiness; container will be removed from service endpoints if the probe fails; cannot be updated"` - Lifecycle *Lifecycle `json:"lifecycle,omitempty" description:"actions that the management system should take in response to container lifecycle events; cannot be updated"` - // Optional: Defaults to /dev/termination-log - TerminationMessagePath string `json:"terminationMessagePath,omitempty" description:"path at which the file to which the container's termination message will be written is mounted into the container's filesystem; message written is intended to be brief final status, such as an assertion failure message; defaults to /dev/termination-log; cannot be updated"` - // Deprecated - see SecurityContext. Optional: Default to false. - Privileged bool `json:"privileged,omitempty" description:"whether or not the container is granted privileged status; defaults to false; cannot be updated; deprecated; See SecurityContext."` - // Optional: Policy for pulling images for this container - ImagePullPolicy PullPolicy `json:"imagePullPolicy,omitempty" description:"image pull policy; one of Always, Never, IfNotPresent; defaults to Always if :latest tag is specified, or IfNotPresent otherwise; cannot be updated"` - // Deprecated - see SecurityContext. Optional: Capabilities for container. - Capabilities Capabilities `json:"capabilities,omitempty" description:"capabilities for container; cannot be updated; deprecated; See SecurityContext."` - // Optional: SecurityContext defines the security options the pod should be run with - SecurityContext *SecurityContext `json:"securityContext,omitempty" description:"security options the pod should run with"` - - // Variables for interactive containers, these have very specialized use-cases (e.g. debugging) - // and shouldn't be used for general purpose containers. - Stdin bool `json:"stdin,omitempty" description:"Whether this container should allocate a buffer for stdin in the container runtime; default is false"` - TTY bool `json:"tty,omitempty" description:"Whether this container should allocate a TTY for itself, also requires 'stdin' to be true; default is false"` -} - -// Handler defines a specific action that should be taken -// TODO: pass structured data to these actions, and document that data here. -type Handler struct { - // One and only one of the following should be specified. - // Exec specifies the action to take. - Exec *ExecAction `json:"exec,omitempty" description:"exec-based handler"` - // HTTPGet specifies the http request to perform. - HTTPGet *HTTPGetAction `json:"httpGet,omitempty" description:"HTTP-based handler"` - // TCPSocket specifies an action involving a TCP port. - // TODO: implement a realistic TCP lifecycle hook - TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty" description:"TCP-based handler; TCP hooks not yet supported"` -} - -// Lifecycle describes actions that the management system should take in response to container lifecycle -// events. For the PostStart and PreStop lifecycle handlers, management of the container blocks -// until the action is complete, unless the container process fails, in which case the handler is aborted. -type Lifecycle struct { - // PostStart is called immediately after a container is created. If the handler fails, the container - // is terminated and restarted. - PostStart *Handler `json:"postStart,omitempty" description:"called immediately after a container is started; if the handler fails, the container is terminated and restarted according to its restart policy; other management of the container blocks until the hook completes"` - // PreStop is called immediately before a container is terminated. The reason for termination is - // passed to the handler. Regardless of the outcome of the handler, the container is eventually terminated. - PreStop *Handler `json:"preStop,omitempty" description:"called before a container is terminated; the container is terminated after the handler completes; other management of the container blocks until the hook completes"` -} - -type ConditionStatus string - -// These are valid condition statuses. "ConditionTrue" means a resource is in the condition; -// "ConditionFalse" means a resource is not in the condition; "ConditionUnknown" means kubernetes -// can't decide if a resource is in the condition or not. In the future, we could add other -// intermediate conditions, e.g. ConditionDegraded. -const ( - ConditionTrue ConditionStatus = "True" - ConditionFalse ConditionStatus = "False" - ConditionUnknown ConditionStatus = "Unknown" -) - -type ContainerStateWaiting struct { - // Reason could be pulling image, - Reason string `json:"reason,omitempty" description:"(brief) reason the container is not yet running, such as pulling its image"` -} - -type ContainerStateRunning struct { - StartedAt util.Time `json:"startedAt,omitempty" description:"time at which the container was last (re-)started"` -} - -type ContainerStateTerminated struct { - ExitCode int `json:"exitCode" description:"exit status from the last termination of the container"` - Signal int `json:"signal,omitempty" description:"signal from the last termination of the container"` - Reason string `json:"reason,omitempty" description:"(brief) reason from the last termination of the container"` - Message string `json:"message,omitempty" description:"message regarding the last termination of the container"` - StartedAt util.Time `json:"startedAt,omitempty" description:"time at which previous execution of the container started"` - FinishedAt util.Time `json:"finishedAt,omitempty" description:"time at which the container last terminated"` - ContainerID string `json:"containerID,omitempty" description:"container's ID in the format 'docker://'"` -} - -// ContainerState holds a possible state of container. -// Only one of its members may be specified. -// If none of them is specified, the default one is ContainerStateWaiting. -type ContainerState struct { - Waiting *ContainerStateWaiting `json:"waiting,omitempty" description:"details about a waiting container"` - Running *ContainerStateRunning `json:"running,omitempty" description:"details about a running container"` - Termination *ContainerStateTerminated `json:"termination,omitempty" description:"details about a terminated container"` -} - -type ContainerStatus struct { - // Required: This must be a DNS_LABEL. Each container in a pod must have a unique name. - Name string `json:"name" description:"name of the container; must be a DNS_LABEL and unique within the pod; cannot be updated"` - // TODO(dchen1107): Should we rename PodStatus to a more generic name or have a separate states - // defined for container? - State ContainerState `json:"state,omitempty" description:"details about the container's current condition"` - LastTerminationState ContainerState `json:"lastState,omitempty" description:"details about the container's last termination condition"` - Ready bool `json:"ready" description:"specifies whether the container has passed its readiness probe"` - // Note that this is calculated from dead containers. But those containers are subject to - // garbage collection. This value will get capped at 5 by GC. - RestartCount int `json:"restartCount" description:"the number of times the container has been restarted, currently based on the number of dead containers that have not yet been removed"` - // TODO(dchen1107): Which image the container is running with? - // The image the container is running - Image string `json:"image" description:"image of the container"` - ImageID string `json:"imageID" description:"ID of the container's image"` - ContainerID string `json:"containerID,omitempty" description:"container's ID in the format 'docker://'"` -} - -// PodPhase is a label for the condition of a pod at the current time. -type PodPhase string - -// These are the valid statuses of pods. -const ( - // PodPending means the pod has been accepted by the system, but one or more of the containers - // has not been started. This includes time before being bound to a node, as well as time spent - // pulling images onto the host. - PodPending PodPhase = "Pending" - // PodRunning means the pod has been bound to a node and all of the containers have been started. - // At least one container is still running or is in the process of being restarted. - PodRunning PodPhase = "Running" - // PodSucceeded means that all containers in the pod have voluntarily terminated - // with a container exit code of 0, and the system is not going to restart any of these containers. - PodSucceeded PodPhase = "Succeeded" - // PodFailed means that all containers in the pod have terminated, and at least one container has - // terminated in a failure (exited with a non-zero exit code or was stopped by the system). - PodFailed PodPhase = "Failed" - // PodUnknown means that for some reason the state of the pod could not be obtained, typically due - // to an error in communicating with the host of the pod. - PodUnknown PodPhase = "Unknown" -) - -// PodConditionType is a valid value for PodCondition.Type -type PodConditionType string - -// These are valid conditions of pod. -const ( - // PodReady means the pod is able to service requests and should be added to the - // load balancing pools of all matching services. - PodReady PodConditionType = "Ready" -) - -// TODO: add LastTransitionTime, Reason, Message to match NodeCondition api. -type PodCondition struct { - // Type is the type of the condition - Type PodConditionType `json:"type" description:"kind of the condition, currently only Ready"` - // Status is the status of the condition - Status ConditionStatus `json:"status" description:"status of the condition, one of True, False, Unknown"` -} - -// RestartPolicy describes how the container should be restarted. -// Only one of the following restart policies may be specified. -// If none of the following policies is specified, the default one -// is RestartPolicyAlways. -type RestartPolicy string - -const ( - RestartPolicyAlways RestartPolicy = "Always" - RestartPolicyOnFailure RestartPolicy = "OnFailure" - RestartPolicyNever RestartPolicy = "Never" -) - -// DNSPolicy defines how a pod's DNS will be configured. -type DNSPolicy string - -const ( - // DNSClusterFirst indicates that the pod should use cluster DNS - // first, if it is available, then fall back on the default (as - // determined by kubelet) DNS settings. - DNSClusterFirst DNSPolicy = "ClusterFirst" - - // DNSDefault indicates that the pod should use the default (as - // determined by kubelet) DNS settings. - DNSDefault DNSPolicy = "Default" -) - -// PodSpec is a description of a pod -type PodSpec struct { - Volumes []Volume `json:"volumes,omitempty" description:"list of volumes that can be mounted by containers belonging to the pod" patchStrategy:"merge" patchMergeKey:"name"` - // Required: there must be at least one container in a pod. - Containers []Container `json:"containers" description:"list of containers belonging to the pod; cannot be updated; containers cannot currently be added or removed; there must be at least one container in a Pod" patchStrategy:"merge" patchMergeKey:"name"` - RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of Always, OnFailure, Never; defaults to Always"` - // Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. - // Value must be non-negative integer. The value zero indicates delete immediately. - // If this value is nil, the default grace period will be used instead. - // The grace period is the duration in seconds after the processes running in the pod are sent - // a termination signal and the time when the processes are forcibly halted with a kill signal. - // Set this value longer than the expected cleanup time for your process. - TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" description:"optional duration in seconds the pod needs to terminate gracefully; may be decreased in delete request; value must be non-negative integer; the value zero indicates delete immediately; if this value is not set, the default grace period will be used instead; the grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal; set this value longer than the expected cleanup time for your process"` - ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" description:"optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers; value must be a positive integer` - // Optional: Set DNS policy. Defaults to "ClusterFirst" - DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty" description:"DNS policy for containers within the pod; one of 'ClusterFirst' or 'Default'"` - // NodeSelector is a selector which must be true for the pod to fit on a node - NodeSelector map[string]string `json:"nodeSelector,omitempty" description:"selector which must match a node's labels for the pod to be scheduled on that node"` - - // ServiceAccount is the name of the ServiceAccount to use to run this pod - ServiceAccount string `json:"serviceAccount,omitempty" description:"name of the ServiceAccount to use to run this pod"` - - // Host is a request to schedule this pod onto a specific host. If it is non-empty, - // the the scheduler simply schedules this pod onto that host, assuming that it fits - // resource requirements. - Host string `json:"host,omitempty" description:"host requested for this pod"` - // Uses the host's network namespace. If this option is set, the ports that will be - // used must be specified. - // Optional: Default to false. - HostNetwork bool `json:"hostNetwork,omitempty" description:"host networking requested for this pod"` - // Use the host's pid namespace. - // Optional: Default to false. - HostPID bool `json:"hostPID,omitempty" description:"use the host's pid namespace"` - // Use the host's ipc namespace. - // Optional: Default to false. - HostIPC bool `json:"hostIPC,omitempty" description:"use the host's ipc namespace"` - // ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. - // If specified, these secrets will be passed to individual puller implementations for them to use. For example, - // in the case of docker, only DockerConfig type secrets are honored. - ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" description:"list of references to secrets in the same namespace available for pulling the container images" patchStrategy:"merge" patchMergeKey:"name"` -} - -// PodStatus represents information about the status of a pod. Status may trail the actual -// state of a system. -type PodStatus struct { - Phase PodPhase `json:"phase,omitempty" description:"current condition of the pod."` - Conditions []PodCondition `json:"Condition,omitempty" description:"current service state of pod" patchStrategy:"merge" patchMergeKey:"type"` - // A human readable message indicating details about why the pod is in this state. - Message string `json:"message,omitempty" description:"human readable message indicating details about why the pod is in this condition"` - // A brief CamelCase message indicating details about why the pod is in this state. e.g. 'OutOfDisk' - Reason string `json:"reason,omitempty" description:"(brief-CamelCase) reason indicating details about why the pod is in this condition"` - - HostIP string `json:"hostIP,omitempty" description:"IP address of the host to which the pod is assigned; empty if not yet scheduled"` - PodIP string `json:"podIP,omitempty" description:"IP address allocated to the pod; routable at least within the cluster; empty if not yet allocated"` - - StartTime *util.Time `json:"startTime,omitempty" description:"RFC 3339 date and time at which the object was acknowledged by the Kubelet. This is before the Kubelet pulled the container image(s) for the pod."` - - // The list has one entry per container in the manifest. Each entry is currently the output - // of `docker inspect`. - ContainerStatuses []ContainerStatus `json:"containerStatuses,omitempty" description:"list of container statuses"` -} - -// PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded -type PodStatusResult struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - // Status represents the current information about a pod. This data may not be up - // to date. - Status PodStatus `json:"status,omitempty" description:"most recently observed status of the pod; populated by the system, read-only; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` -} - -// Pod is a collection of containers that can run on a host. This resource is created -// by clients and scheduled onto hosts. -type Pod struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Spec defines the behavior of a pod. - Spec PodSpec `json:"spec,omitempty" description:"specification of the desired behavior of the pod; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` - - // Status represents the current information about a pod. This data may not be up - // to date. - Status PodStatus `json:"status,omitempty" description:"most recently observed status of the pod; populated by the system, read-only; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` -} - -// PodList is a list of Pods. -type PodList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#types-kinds"` - - Items []Pod `json:"items" description:"list of pods"` -} - -// PodTemplateSpec describes the data a pod should have when created from a template -type PodTemplateSpec struct { - // Metadata of the pods created from this template. - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Spec defines the behavior of a pod. - Spec PodSpec `json:"spec,omitempty" description:"specification of the desired behavior of the pod; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` -} - -// PodTemplate describes a template for creating copies of a predefined pod. -type PodTemplate struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Template defines the pods that will be created from this pod template - Template PodTemplateSpec `json:"template,omitempty" description:"the template of the desired behavior of the pod; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` -} - -// PodTemplateList is a list of PodTemplates. -type PodTemplateList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Items []PodTemplate `json:"items" description:"list of pod templates"` -} - -// ReplicationControllerSpec is the specification of a replication controller. -type ReplicationControllerSpec struct { - // Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. - Replicas *int `json:"replicas,omitempty" description:"number of replicas desired"` - - // Selector is a label query over pods that should match the Replicas count. - // If Selector is empty, it is defaulted to the labels present on the Pod template. - Selector map[string]string `json:"selector,omitempty" description:"label keys and values that must match in order to be controlled by this replication controller, if empty defaulted to labels on Pod template"` - - // TemplateRef is a reference to an object that describes the pod that will be created if - // insufficient replicas are detected. - //TemplateRef *ObjectReference `json:"templateRef,omitempty" description:"reference to an object that describes the pod that will be created if insufficient replicas are detected"` - - // Template is the object that describes the pod that will be created if - // insufficient replicas are detected. This takes precedence over a - // TemplateRef. - Template *PodTemplateSpec `json:"template,omitempty" description:"object that describes the pod that will be created if insufficient replicas are detected; takes precendence over templateRef"` -} - -// ReplicationControllerStatus represents the current status of a replication -// controller. -type ReplicationControllerStatus struct { - // Replicas is the number of actual replicas. - Replicas int `json:"replicas" description:"most recently oberved number of replicas"` - - // ObservedGeneration is the most recent generation observed by the controller. - ObservedGeneration int64 `json:"observedGeneration,omitempty" description:"reflects the generation of the most recently observed replication controller"` -} - -// ReplicationController represents the configuration of a replication controller. -type ReplicationController struct { - TypeMeta `json:",inline"` - // If the Labels of a ReplicationController are empty, they are defaulted to be the same as the Pod(s) that the replication controller manages. - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Spec defines the desired behavior of this replication controller. - Spec ReplicationControllerSpec `json:"spec,omitempty" description:"specification of the desired behavior of the replication controller; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` - - // Status is the current status of this replication controller. This data may be - // out of date by some window of time. - Status ReplicationControllerStatus `json:"status,omitempty" description:"most recently observed status of the replication controller; populated by the system, read-only; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` -} - -// ReplicationControllerList is a collection of replication controllers. -type ReplicationControllerList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Items []ReplicationController `json:"items" description:"list of replication controllers"` -} - -// Session Affinity Type string -type ServiceAffinity string - -const ( - // ServiceAffinityClientIP is the Client IP based. - ServiceAffinityClientIP ServiceAffinity = "ClientIP" - - // ServiceAffinityNone - no session affinity. - ServiceAffinityNone ServiceAffinity = "None" -) - -// Service Type string describes ingress methods for a service -type ServiceType string - -const ( - // ServiceTypeClusterIP means a service will only be accessible inside the - // cluster, via the portal IP. - ServiceTypeClusterIP ServiceType = "ClusterIP" - - // ServiceTypeNodePort means a service will be exposed on one port of - // every node, in addition to 'ClusterIP' type. - ServiceTypeNodePort ServiceType = "NodePort" - - // ServiceTypeLoadBalancer means a service will be exposed via an - // external load balancer (if the cloud provider supports it), in addition - // to 'NodePort' type. - ServiceTypeLoadBalancer ServiceType = "LoadBalancer" -) - -// ServiceStatus represents the current status of a service -type ServiceStatus struct { - // LoadBalancer contains the current status of the load-balancer, - // if one is present. - LoadBalancer LoadBalancerStatus `json:"loadBalancer,omitempty" description:"status of load-balancer"` -} - -// LoadBalancerStatus represents the status of a load-balancer -type LoadBalancerStatus struct { - // Ingress is a list containing ingress points for the load-balancer; - // traffic intended for the service should be sent to these ingress points. - Ingress []LoadBalancerIngress `json:"ingress,omitempty" description:"load-balancer ingress points"` -} - -// LoadBalancerIngress represents the status of a load-balancer ingress point: -// traffic intended for the service should be sent to an ingress point. -type LoadBalancerIngress struct { - // IP is set for load-balancer ingress points that are IP based - // (typically GCE or OpenStack load-balancers) - IP string `json:"ip,omitempty" description:"IP address of ingress point"` - - // Hostname is set for load-balancer ingress points that are DNS based - // (typically AWS load-balancers) - Hostname string `json:"hostname,omitempty" description:"hostname of ingress point"` -} - -// ServiceSpec describes the attributes that a user creates on a service -type ServiceSpec struct { - // Required: The list of ports that are exposed by this service. - Ports []ServicePort `json:"ports" description:"ports exposed by the service"` - - // This service will route traffic to pods having labels matching this selector. If null, no endpoints will be automatically created. If empty, all pods will be selected. - Selector map[string]string `json:"selector,omitempty" description:"label keys and values that must match in order to receive traffic for this service; if empty, all pods are selected, if not specified, endpoints must be manually specified"` - - // PortalIP is usually assigned by the master. If specified by the user - // we will try to respect it or else fail the request. This field can - // not be changed by updates. - // Valid values are None, empty string (""), or a valid IP address - // None can be specified for headless services when proxying is not required - PortalIP string `json:"portalIP,omitempty description: IP address of the service; usually assigned by the system; if specified, it will be allocated to the service if unused, and creation of the service will fail otherwise; cannot be updated; 'None' can be specified for a headless service when proxying is not required"` - - // CreateExternalLoadBalancer indicates whether a load balancer should be created for this service. - CreateExternalLoadBalancer bool `json:"createExternalLoadBalancer,omitempty" description:"set up a cloud-provider-specific load balancer on an external IP"` - - // Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer - Type ServiceType `json:"type,omitempty" description:"type of this service; must be ClusterIP, NodePort, or LoadBalancer; defaults to ClusterIP"` - - // Deprecated. PublicIPs are used by external load balancers, or can be set by - // users to handle external traffic that arrives at a node. - PublicIPs []string `json:"publicIPs,omitempty" description:"deprecated. externally visible IPs (e.g. load balancers) that should be proxied to this service"` - - // Optional: Supports "ClientIP" and "None". Used to maintain session affinity. - SessionAffinity ServiceAffinity `json:"sessionAffinity,omitempty" description:"enable client IP based session affinity; must be ClientIP or None; defaults to None"` -} - -type ServicePort struct { - // Optional if only one ServicePort is defined on this service: The - // name of this port within the service. This must be a DNS_LABEL. - // All ports within a ServiceSpec must have unique names. This maps to - // the 'Name' field in EndpointPort objects. - Name string `json:"name,omitempty" description:"the name of this port; optional if only one port is defined"` - - // Optional: The IP protocol for this port. Supports "TCP" and "UDP", - // default is TCP. - Protocol Protocol `json:"protocol,omitempty" description:"the protocol used by this port; must be UDP or TCP; TCP if unspecified"` - - // Required: The port that will be exposed by this service. - Port int `json:"port" description:"the port number that is exposed"` - - // Optional: The target port on pods selected by this service. - // If this is a string, it will be looked up as a named port in the - // target Pod's container ports. If this is not specified, the value - // of Port is used (an identity map). - TargetPort util.IntOrString `json:"targetPort,omitempty" description:"number or name of the port to access on the pods targeted by the service; defaults to the service port; number must be in the range 1 to 65535; name must be a IANA_SVC_NAME"` - - // The port on each node on which this service is exposed. - // Default is to auto-allocate a port if the ServiceType of this Service requires one. - NodePort int `json:"nodePort" description:"the port on each node on which this service is exposed"` -} - -// Service is a named abstraction of software service (for example, mysql) consisting of local port -// (for example 3306) that the proxy listens on, and the selector that determines which pods -// will answer requests sent through the proxy. -type Service struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Spec defines the behavior of a service. - Spec ServiceSpec `json:"spec,omitempty" description:"specification of the desired behavior of the service; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` - - // Status represents the current status of a service. - Status ServiceStatus `json:"status,omitempty" description:"most recently observed status of the service; populated by the system, read-only; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` -} - -const ( - // PortalIPNone - do not assign a portal IP - // no proxying required and no environment variables should be created for pods - PortalIPNone = "None" -) - -// ServiceList holds a list of services. -type ServiceList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Items []Service `json:"items" description:"list of services"` -} - -// ServiceAccount binds together: -// * a name, understood by users, and perhaps by peripheral systems, for an identity -// * a principal that can be authenticated and authorized -// * a set of secrets -type ServiceAccount struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount - Secrets []ObjectReference `json:"secrets,omitempty" description:"list of secrets that can be used by pods running as this service account" patchStrategy:"merge" patchMergeKey:"name"` - - // ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images - // in pods that reference this ServiceAccount. ImagePullSecrets are distinct from Secrets because Secrets - // can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet. - ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" description:"list of references to secrets in the same namespace available for pulling container images"` -} - -// ServiceAccountList is a list of ServiceAccount objects -type ServiceAccountList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Items []ServiceAccount `json:"items" description:"list of ServiceAccounts"` -} - -// Endpoints is a collection of endpoints that implement the actual service. Example: -// Name: "mysvc", -// Subsets: [ -// { -// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], -// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] -// }, -// { -// Addresses: [{"ip": "10.10.3.3"}], -// Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}] -// }, -// ] -type Endpoints struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // The set of all endpoints is the union of all subsets. - Subsets []EndpointSubset `json:"subsets" description:"sets of addresses and ports that comprise a service"` -} - -// EndpointSubset is a group of addresses with a common set of ports. The -// expanded set of endpoints is the Cartesian product of Addresses x Ports. -// For example, given: -// { -// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], -// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] -// } -// The resulting set of endpoints can be viewed as: -// a: [ 10.10.1.1:8675, 10.10.2.2:8675 ], -// b: [ 10.10.1.1:309, 10.10.2.2:309 ] -type EndpointSubset struct { - Addresses []EndpointAddress `json:"addresses,omitempty" description:"IP addresses which offer the related ports"` - Ports []EndpointPort `json:"ports,omitempty" description:"port numbers available on the related IP addresses"` -} - -// EndpointAddress is a tuple that describes single IP address. -type EndpointAddress struct { - // The IP of this endpoint. - // TODO: This should allow hostname or IP, see #4447. - IP string `json:"IP" description:"IP address of the endpoint"` - - // Optional: The kubernetes object related to the entry point. - TargetRef *ObjectReference `json:"targetRef,omitempty" description:"reference to object providing the endpoint"` -} - -// EndpointPort is a tuple that describes a single port. -type EndpointPort struct { - // The name of this port (corresponds to ServicePort.Name). Optional - // if only one port is defined. Must be a DNS_LABEL. - Name string `json:"name,omitempty" description:"name of this port"` - - // The port number. - Port int `json:"port" description:"port number of the endpoint"` - - // The IP protocol for this port. - Protocol Protocol `json:"protocol,omitempty" description:"protocol for this port; must be UDP or TCP; TCP if unspecified"` -} - -// EndpointsList is a list of endpoints. -type EndpointsList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Items []Endpoints `json:"items" description:"list of endpoints"` -} - -// NodeSpec describes the attributes that a node is created with. -type NodeSpec struct { - // PodCIDR represents the pod IP range assigned to the node - PodCIDR string `json:"podCIDR,omitempty" description:"pod IP range assigned to the node"` - // External ID of the node assigned by some machine database (e.g. a cloud provider) - ExternalID string `json:"externalID,omitempty" description:"deprecated. External ID assigned to the node by some machine database (e.g. a cloud provider). Defaults to node name when empty."` - // ID of the node assigned by the cloud provider - ProviderID string `json:"providerID,omitempty" description:"ID of the node assigned by the cloud provider in the format: ://"` - // Unschedulable controls node schedulability of new pods. By default node is schedulable. - Unschedulable bool `json:"unschedulable,omitempty" description:"disable pod scheduling on the node"` -} - -// NodeSystemInfo is a set of ids/uuids to uniquely identify the node. -type NodeSystemInfo struct { - // MachineID is the machine-id reported by the node - MachineID string `json:"machineID" description:"machine-id reported by the node"` - // SystemUUID is the system-uuid reported by the node - SystemUUID string `json:"systemUUID" description:"system-uuid reported by the node"` - // BootID is the boot-id reported by the node - BootID string `json:"bootID" description:"boot id is the boot-id reported by the node"` - // Kernel version reported by the node - KernelVersion string `json:"kernelVersion" description:"Kernel version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64)"` - // OS image used reported by the node - OsImage string `json:"osImage" description:"OS image used reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy))"` - // Container runtime version reported by the node - ContainerRuntimeVersion string `json:"containerRuntimeVersion" description:"Container runtime version reported by the node through runtime remote API (e.g. docker://1.5.0)"` - // Kubelet version reported by the node - KubeletVersion string `json:"kubeletVersion" description:"Kubelet version reported by the node"` - // Kube-proxy version reported by the node - KubeProxyVersion string `json:"kubeProxyVersion" description:"Kube-proxy version reported by the node"` -} - -// NodeStatus is information about the current status of a node. -type NodeStatus struct { - // Capacity represents the available resources of a node. - // see http://releases.k8s.io/v1.0.0/docs/resources.md for more details. - Capacity ResourceList `json:"capacity,omitempty" description:"compute resource capacity of the node; http://releases.k8s.io/v1.0.0/docs/resources.md"` - // NodePhase is the current lifecycle phase of the node. - Phase NodePhase `json:"phase,omitempty" description:"most recently observed lifecycle phase of the node"` - // Conditions is an array of current node conditions. - Conditions []NodeCondition `json:"conditions,omitempty" description:"list of node conditions observed" patchStrategy:"merge" patchMergeKey:"type"` - // Queried from cloud provider, if available. - Addresses []NodeAddress `json:"addresses,omitempty" description:"list of addresses reachable to the node" patchStrategy:"merge" patchMergeKey:"type"` - // NodeSystemInfo is a set of ids/uuids to uniquely identify the node - NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty" description:"set of ids/uuids to uniquely identify the node"` -} - -type NodePhase string - -// These are the valid phases of node. -const ( - // NodePending means the node has been created/added by the system, but not configured. - NodePending NodePhase = "Pending" - // NodeRunning means the node has been configured and has Kubernetes components running. - NodeRunning NodePhase = "Running" - // NodeTerminated means the node has been removed from the cluster. - NodeTerminated NodePhase = "Terminated" -) - -type NodeConditionType string - -// These are valid conditions of node. Currently, we don't have enough information to decide -// node condition. In the future, we will add more. The proposed set of conditions are: -// NodeReachable, NodeLive, NodeReady, NodeSchedulable, NodeRunnable. -const ( - // NodeReady means kubelet is healthy and ready to accept pods. - NodeReady NodeConditionType = "Ready" -) - -type NodeCondition struct { - Type NodeConditionType `json:"type" description:"type of node condition, currently only Ready"` - Status ConditionStatus `json:"status" description:"status of the condition, one of True, False, Unknown"` - LastHeartbeatTime util.Time `json:"lastHeartbeatTime,omitempty" description:"last time we got an update on a given condition"` - LastTransitionTime util.Time `json:"lastTransitionTime,omitempty" description:"last time the condition transit from one status to another"` - Reason string `json:"reason,omitempty" description:"(brief) reason for the condition's last transition"` - Message string `json:"message,omitempty" description:"human readable message indicating details about last transition"` -} - -type NodeAddressType string - -// These are valid address type of node. -const ( - NodeHostName NodeAddressType = "Hostname" - NodeExternalIP NodeAddressType = "ExternalIP" - NodeInternalIP NodeAddressType = "InternalIP" -) - -type NodeAddress struct { - Type NodeAddressType `json:"type" description:"node address type, one of Hostname, ExternalIP or InternalIP"` - Address string `json:"address" description:"the node address"` -} - -// ResourceName is the name identifying various resources in a ResourceList. -type ResourceName string - -const ( - // CPU, in cores. (500m = .5 cores) - ResourceCPU ResourceName = "cpu" - // Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) - ResourceMemory ResourceName = "memory" - // Volume size, in bytes (e,g. 5Gi = 5GiB = 5 * 1024 * 1024 * 1024) - ResourceStorage ResourceName = "storage" -) - -// ResourceList is a set of (resource name, quantity) pairs. -type ResourceList map[ResourceName]resource.Quantity - -// Node is a worker node in Kubernetes. -// The name of the node according to etcd is in ID. -type Node struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Spec defines the behavior of a node. - Spec NodeSpec `json:"spec,omitempty" description:"specification of a node; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` - - // Status describes the current status of a Node - Status NodeStatus `json:"status,omitempty" description:"most recently observed status of the node; populated by the system, read-only; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` -} - -// NodeList is a list of minions. -type NodeList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Items []Node `json:"items" description:"list of nodes"` -} - -type FinalizerName string - -// These are internal finalizer values to Kubernetes, must be qualified name unless defined here -const ( - FinalizerKubernetes FinalizerName = "kubernetes" -) - -// NamespaceSpec describes the attributes on a Namespace -type NamespaceSpec struct { - // Finalizers is an opaque list of values that must be empty to permanently remove object from storage - Finalizers []FinalizerName `json:"finalizers,omitempty" description:"an opaque list of values that must be empty to permanently remove object from storage"` -} - -// NamespaceStatus is information about the current status of a Namespace. -type NamespaceStatus struct { - // Phase is the current lifecycle phase of the namespace. - Phase NamespacePhase `json:"phase,omitempty" description:"phase is the current lifecycle phase of the namespace"` -} - -type NamespacePhase string - -// These are the valid phases of a namespace. -const ( - // NamespaceActive means the namespace is available for use in the system - NamespaceActive NamespacePhase = "Active" - // NamespaceTerminating means the namespace is undergoing graceful termination - NamespaceTerminating NamespacePhase = "Terminating" -) - -// A namespace provides a scope for Names. -// Use of multiple namespaces is optional -type Namespace struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Spec defines the behavior of the Namespace. - Spec NamespaceSpec `json:"spec,omitempty" description:"spec defines the behavior of the Namespace; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` - - // Status describes the current status of a Namespace - Status NamespaceStatus `json:"status,omitempty" description:"status describes the current status of a Namespace; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` -} - -// NamespaceList is a list of Namespaces. -type NamespaceList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Items is the list of Namespace objects in the list - Items []Namespace `json:"items" description:"items is the list of Namespace objects in the list"` -} - -// Binding ties one object to another - for example, a pod is bound to a node by a scheduler. -type Binding struct { - TypeMeta `json:",inline"` - // ObjectMeta describes the object that is being bound. - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Target is the object to bind to. - Target ObjectReference `json:"target" description:"an object to bind to"` -} - -// DeleteOptions may be provided when deleting an API object -type DeleteOptions struct { - TypeMeta `json:",inline"` - - // Optional duration in seconds before the object should be deleted. Value must be non-negative integer. - // The value zero indicates delete immediately. If this value is nil, the default grace period for the - // specified type will be used. - GracePeriodSeconds *int64 `json:"gracePeriodSeconds,omitempty" description:"the duration in seconds to wait before deleting this object; defaults to a per object value if not specified; zero means delete immediately"` -} - -// ListOptions is the query options to a standard REST list call -type ListOptions struct { - TypeMeta `json:",inline"` - - // A selector based on labels - LabelSelector string `json:"labelSelector,omitempty" description:"a selector to restrict the list of returned objects by their labels; defaults to everything"` - // A selector based on fields - FieldSelector string `json:"fieldSelector,omitempty" description:"a selector to restrict the list of returned objects by their fields; defaults to everything"` - // If true, watch for changes to the selected resources - Watch bool `json:"watch,omitempty" description:"watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion"` - // The desired resource version to watch - ResourceVersion string `json:"resourceVersion,omitempty" description:"when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history"` -} - -// PodLogOptions is the query options for a Pod's logs REST call -type PodLogOptions struct { - TypeMeta `json:",inline"` - - // Container for which to return logs - Container string `json:"container,omitempty" description:"the container for which to stream logs; defaults to only container if there is one container in the pod"` - - // If true, follow the logs for the pod - Follow bool `json:"follow,omitempty" description:"follow the log stream of the pod; defaults to false"` - - // If true, return previous terminated container logs - Previous bool `json:"previous,omitempty" description:"return previous terminated container logs; defaults to false"` -} - -// PodExecOptions is the query options to a Pod's remote exec call -type PodExecOptions struct { - TypeMeta `json:",inline"` - - // Stdin if true indicates that stdin is to be redirected for the exec call - Stdin bool `json:"stdin,omitempty" description:"redirect the standard input stream of the pod for this call; defaults to false"` - - // Stdout if true indicates that stdout is to be redirected for the exec call - Stdout bool `json:"stdout,omitempty" description:"redirect the standard output stream of the pod for this call; defaults to true"` - - // Stderr if true indicates that stderr is to be redirected for the exec call - Stderr bool `json:"stderr,omitempty" description:"redirect the standard error stream of the pod for this call; defaults to true"` - - // TTY if true indicates that a tty will be allocated for the exec call - TTY bool `json:"tty,omitempty" description:"allocate a terminal for this exec call; defaults to false"` - - // Container in which to execute the command. - Container string `json:"container,omitempty" description:"the container in which to execute the command. Defaults to only container if there is only one container in the pod."` - - // Command is the remote command to execute; argv array; not executed within a shell. - Command []string `json:"command" description:"the command to execute; argv array; not executed within a shell"` -} - -// PodProxyOptions is the query options to a Pod's proxy call -type PodProxyOptions struct { - TypeMeta `json:",inline"` - - // Path is the URL path to use for the current proxy request - Path string `json:"path,omitempty" description:"URL path to use in proxy request to pod"` -} - -// Status is a return value for calls that don't return other objects. -type Status struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // One of: "Success" or "Failure" - Status string `json:"status,omitempty" description:"status of the operation; either Success, or Failure"` - // A human-readable description of the status of this operation. - Message string `json:"message,omitempty" description:"human-readable description of the status of this operation"` - // A machine-readable description of why this operation is in the - // "Failure" status. If this value is empty there - // is no information available. A Reason clarifies an HTTP status - // code but does not override it. - Reason StatusReason `json:"reason,omitempty" description:"machine-readable description of why this operation is in the 'Failure' status; if this value is empty there is no information available; a reason clarifies an HTTP status code but does not override it"` - // Extended data associated with the reason. Each reason may define its - // own extended details. This field is optional and the data returned - // is not guaranteed to conform to any schema except that defined by - // the reason type. - Details *StatusDetails `json:"details,omitempty" description:"extended data associated with the reason; each reason may define its own extended details; this field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type"` - // Suggested HTTP return code for this status, 0 if not set. - Code int `json:"code,omitempty" description:"suggested HTTP return code for this status; 0 if not set"` -} - -// StatusDetails is a set of additional properties that MAY be set by the -// server to provide additional information about a response. The Reason -// field of a Status object defines what attributes will be set. Clients -// must ignore fields that do not match the defined type of each attribute, -// and should assume that any attribute may be empty, invalid, or under -// defined. -type StatusDetails struct { - // The ID attribute of the resource associated with the status StatusReason - // (when there is a single ID which can be described). - ID string `json:"id,omitempty" description:"the ID attribute of the resource associated with the status StatusReason (when there is a single ID which can be described)"` - // The kind attribute of the resource associated with the status StatusReason. - // On some operations may differ from the requested resource Kind. - Kind string `json:"kind,omitempty" description:"the kind attribute of the resource associated with the status StatusReason; on some operations may differ from the requested resource Kind"` - // The Causes array includes more details associated with the StatusReason - // failure. Not all StatusReasons may provide detailed causes. - Causes []StatusCause `json:"causes,omitempty" description:"the Causes array includes more details associated with the StatusReason failure; not all StatusReasons may provide detailed causes"` - // If specified, the time in seconds before the operation should be retried. - RetryAfterSeconds int `json:"retryAfterSeconds,omitempty" description:"the number of seconds before the client should attempt to retry this operation"` -} - -// Values of Status.Status -const ( - StatusSuccess = "Success" - StatusFailure = "Failure" -) - -// StatusReason is an enumeration of possible failure causes. Each StatusReason -// must map to a single HTTP status code, but multiple reasons may map -// to the same HTTP status code. -// TODO: move to apiserver -type StatusReason string - -const ( - // StatusReasonUnknown means the server has declined to indicate a specific reason. - // The details field may contain other information about this error. - // Status code 500. - StatusReasonUnknown StatusReason = "" - - // StatusReasonNotFound means one or more resources required for this operation - // could not be found. - // Details (optional): - // "kind" string - the kind attribute of the missing resource - // on some operations may differ from the requested - // resource. - // "id" string - the identifier of the missing resource - // Status code 404 - StatusReasonNotFound StatusReason = "NotFound" - - // StatusReasonAlreadyExists means the resource you are creating already exists. - // Details (optional): - // "kind" string - the kind attribute of the conflicting resource - // "id" string - the identifier of the conflicting resource - // Status code 409 - StatusReasonAlreadyExists StatusReason = "AlreadyExists" - - // StatusReasonConflict means the requested update operation cannot be completed - // due to a conflict in the operation. The client may need to alter the request. - // Each resource may define custom details that indicate the nature of the - // conflict. - // Status code 409 - StatusReasonConflict StatusReason = "Conflict" - - // StatusReasonInvalid means the requested create or update operation cannot be - // completed due to invalid data provided as part of the request. The client may - // need to alter the request. When set, the client may use the StatusDetails - // message field as a summary of the issues encountered. - // Details (optional): - // "kind" string - the kind attribute of the invalid resource - // "id" string - the identifier of the invalid resource - // "causes" - one or more StatusCause entries indicating the data in the - // provided resource that was invalid. The code, message, and - // field attributes will be set. - // Status code 422 - StatusReasonInvalid StatusReason = "Invalid" - - // StatusReasonServerTimeout means the server can be reached and understood the request, - // but cannot complete the action in a reasonable time. The client should retry the request. - // This is may be due to temporary server load or a transient communication issue with - // another server. Status code 500 is used because the HTTP spec provides no suitable - // server-requested client retry and the 5xx class represents actionable errors. - // Details (optional): - // "kind" string - the kind attribute of the resource being acted on. - // "id" string - the operation that is being attempted. - // Status code 500 - StatusReasonServerTimeout StatusReason = "ServerTimeout" -) - -// StatusCause provides more information about an api.Status failure, including -// cases when multiple errors are encountered. -type StatusCause struct { - // A machine-readable description of the cause of the error. If this value is - // empty there is no information available. - Type CauseType `json:"reason,omitempty" description:"machine-readable description of the cause of the error; if this value is empty there is no information available"` - // A human-readable description of the cause of the error. This field may be - // presented as-is to a reader. - Message string `json:"message,omitempty" description:"human-readable description of the cause of the error; this field may be presented as-is to a reader"` - // The field of the resource that has caused this error, as named by its JSON - // serialization. May include dot and postfix notation for nested attributes. - // Arrays are zero-indexed. Fields may appear more than once in an array of - // causes due to fields having multiple errors. - // Optional. - // - // Examples: - // "name" - the field "name" on the current resource - // "items[0].name" - the field "name" on the first array entry in "items" - Field string `json:"field,omitempty" description:"field of the resource that has caused this error, as named by its JSON serialization; may include dot and postfix notation for nested attributes; arrays are zero-indexed; fields may appear more than once in an array of causes due to fields having multiple errors"` -} - -// CauseType is a machine readable value providing more detail about what -// occured in a status response. An operation may have multiple causes for a -// status (whether Failure or Success). -type CauseType string - -const ( - // CauseTypeFieldValueNotFound is used to report failure to find a requested value - // (e.g. looking up an ID). - CauseTypeFieldValueNotFound CauseType = "FieldValueNotFound" - // CauseTypeFieldValueRequired is used to report required values that are not - // provided (e.g. empty strings, null values, or empty arrays). - CauseTypeFieldValueRequired CauseType = "FieldValueRequired" - // CauseTypeFieldValueDuplicate is used to report collisions of values that must be - // unique (e.g. unique IDs). - CauseTypeFieldValueDuplicate CauseType = "FieldValueDuplicate" - // CauseTypeFieldValueInvalid is used to report malformed values (e.g. failed regex - // match). - CauseTypeFieldValueInvalid CauseType = "FieldValueInvalid" - // CauseTypeFieldValueNotSupported is used to report valid (as per formatting rules) - // values that can not be handled (e.g. an enumerated string). - CauseTypeFieldValueNotSupported CauseType = "FieldValueNotSupported" -) - -// ObjectReference contains enough information to let you inspect or modify the referred object. -type ObjectReference struct { - Kind string `json:"kind,omitempty" description:"kind of the referent"` - Namespace string `json:"namespace,omitempty" description:"namespace of the referent"` - Name string `json:"name,omitempty" description:"name of the referent"` - UID types.UID `json:"uid,omitempty" description:"uid of the referent"` - APIVersion string `json:"apiVersion,omitempty" description:"API version of the referent"` - ResourceVersion string `json:"resourceVersion,omitempty" description:"specific resourceVersion to which this reference is made, if any: http://releases.k8s.io/v1.0.0/docs/api-conventions.md#concurrency-control-and-consistency"` - - // Optional. If referring to a piece of an object instead of an entire object, this string - // should contain information to identify the sub-object. For example, if the object - // reference is to a container within a pod, this would take on a value like: - // "spec.containers{name}" (where "name" refers to the name of the container that triggered - // the event) or if no container name is specified "spec.containers[2]" (container with - // index 2 in this pod). This syntax is chosen only to have some well-defined way of - // referencing a part of an object. - // TODO: this design is not final and this field is subject to change in the future. - FieldPath string `json:"fieldPath,omitempty" description:"if referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]"` -} - -// LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. -type LocalObjectReference struct { - //TODO: Add other useful fields. apiVersion, kind, uid? - Name string `json:"name,omitempty" description:"name of the referent"` -} - -type SerializedReference struct { - TypeMeta `json:",inline"` - Reference ObjectReference `json:"reference,omitempty" description:"the reference to an object in the system"` -} - -type EventSource struct { - // Component from which the event is generated. - Component string `json:"component,omitempty" description:"component that generated the event"` - // Host name on which the event is generated. - Host string `json:"host,omitempty" description:"name of the host where the event is generated"` -} - -// Event is a report of an event somewhere in the cluster. -// TODO: Decide whether to store these separately or with the object they apply to. -type Event struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Required. The object that this event is about. - InvolvedObject ObjectReference `json:"involvedObject" description:"object this event is about"` - - // Optional; this should be a short, machine understandable string that gives the reason - // for this event being generated. - // TODO: provide exact specification for format. - Reason string `json:"reason,omitempty" description:"short, machine understandable string that gives the reason for the transition into the object's current status"` - - // Optional. A human-readable description of the status of this operation. - // TODO: decide on maximum length. - Message string `json:"message,omitempty" description:"human-readable description of the status of this operation"` - - // Optional. The component reporting this event. Should be a short machine understandable string. - Source EventSource `json:"source,omitempty" description:"component reporting this event"` - - // The time at which the event was first recorded. (Time of server receipt is in TypeMeta.) - FirstTimestamp util.Time `json:"firstTimestamp,omitempty" description:"the time at which the event was first recorded"` - - // The time at which the most recent occurance of this event was recorded. - LastTimestamp util.Time `json:"lastTimestamp,omitempty" description:"the time at which the most recent occurance of this event was recorded"` - - // The number of times this event has occurred. - Count int `json:"count,omitempty" description:"the number of times this event has occurred"` -} - -// EventList is a list of events. -type EventList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Items []Event `json:"items" description:"list of events"` -} - -// List holds a list of objects, which may not be known by the server. -type List struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Items []runtime.RawExtension `json:"items" description:"list of objects"` -} - -// A type of object that is limited -type LimitType string - -const ( - // Limit that applies to all pods in a namespace - LimitTypePod LimitType = "Pod" - // Limit that applies to all containers in a namespace - LimitTypeContainer LimitType = "Container" -) - -// LimitRangeItem defines a min/max usage limit for any resource that matches on kind -type LimitRangeItem struct { - // Type of resource that this limit applies to - Type LimitType `json:"type,omitempty" description:"type of resource that this limit applies to"` - // Max usage constraints on this kind by resource name - Max ResourceList `json:"max,omitempty" description:"max usage constraints on this kind by resource name"` - // Min usage constraints on this kind by resource name - Min ResourceList `json:"min,omitempty" description:"min usage constraints on this kind by resource name"` - // Default usage constraints on this kind by resource name - Default ResourceList `json:"default,omitempty" description:"default values on this kind by resource name if omitted"` - // DefaultRequest is the default resource requirement request value by resource name if resource request is omitted. - DefaultRequest ResourceList `json:"defaultRequest,omitempty"` - // MaxLimitRequestRatio if specified, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value; this represents the max burst for the named resource. - MaxLimitRequestRatio ResourceList `json:"maxLimitRequestRatio,omitempty"` -} - -// LimitRangeSpec defines a min/max usage limit for resources that match on kind -type LimitRangeSpec struct { - // Limits is the list of LimitRangeItem objects that are enforced - Limits []LimitRangeItem `json:"limits" description:"limits is the list of LimitRangeItem objects that are enforced"` -} - -// LimitRange sets resource usage limits for each kind of resource in a Namespace -type LimitRange struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Spec defines the limits enforced - Spec LimitRangeSpec `json:"spec,omitempty" description:"spec defines the limits enforced; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` -} - -// LimitRangeList is a list of LimitRange items. -type LimitRangeList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Items is a list of LimitRange objects - Items []LimitRange `json:"items" description:"items is a list of LimitRange objects"` -} - -// The following identify resource constants for Kubernetes object types -const ( - // Pods, number - ResourcePods ResourceName = "pods" - // Services, number - ResourceServices ResourceName = "services" - // ReplicationControllers, number - ResourceReplicationControllers ResourceName = "replicationcontrollers" - // ResourceQuotas, number - ResourceQuotas ResourceName = "resourcequotas" - // ResourceSecrets, number - ResourceSecrets ResourceName = "secrets" - // ResourcePersistentVolumeClaims, number - ResourcePersistentVolumeClaims ResourceName = "persistentvolumeclaims" -) - -// ResourceQuotaSpec defines the desired hard limits to enforce for Quota -type ResourceQuotaSpec struct { - // Hard is the set of desired hard limits for each named resource - Hard ResourceList `json:"hard,omitempty" description:"hard is the set of desired hard limits for each named resource"` -} - -// ResourceQuotaStatus defines the enforced hard limits and observed use -type ResourceQuotaStatus struct { - // Hard is the set of enforced hard limits for each named resource - Hard ResourceList `json:"hard,omitempty" description:"hard is the set of enforced hard limits for each named resource"` - // Used is the current observed total usage of the resource in the namespace - Used ResourceList `json:"used,omitempty" description:"used is the current observed total usage of the resource in the namespace"` -} - -// ResourceQuota sets aggregate quota restrictions enforced per namespace -type ResourceQuota struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Spec defines the desired quota - Spec ResourceQuotaSpec `json:"spec,omitempty" description:"spec defines the desired quota; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` - - // Status defines the actual enforced quota and its current usage - Status ResourceQuotaStatus `json:"status,omitempty" description:"status defines the actual enforced quota and current usage; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` -} - -// ResourceQuotaList is a list of ResourceQuota items -type ResourceQuotaList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Items is a list of ResourceQuota objects - Items []ResourceQuota `json:"items" description:"items is a list of ResourceQuota objects"` -} - -// Secret holds secret data of a certain type. The total bytes of the values in -// the Data field must be less than MaxSecretSize bytes. -type Secret struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - // Data contains the secret data. Each key must be a valid DNS_SUBDOMAIN - // or leading dot followed by valid DNS_SUBDOMAIN. - // The serialized form of the secret data is a base64 encoded string, - // representing the arbitrary (possibly non-string) data value here. - Data map[string][]byte `json:"data,omitempty" description:"data contains the secret data. Each key must be a valid DNS_SUBDOMAIN or leading dot followed by valid DNS_SUBDOMAIN. Each value must be a base64 encoded string as described in https://tools.ietf.org/html/rfc4648#section-4"` - - // Used to facilitate programmatic handling of secret data. - Type SecretType `json:"type,omitempty" description:"type facilitates programmatic handling of secret data"` -} - -const MaxSecretSize = 1 * 1024 * 1024 - -type SecretType string - -const ( - // SecretTypeOpaque is the default; arbitrary user-defined data - SecretTypeOpaque SecretType = "Opaque" - - // SecretTypeServiceAccountToken contains a token that identifies a service account to the API - // - // Required fields: - // - Secret.Annotations["kubernetes.io/service-account.name"] - the name of the ServiceAccount the token identifies - // - Secret.Annotations["kubernetes.io/service-account.uid"] - the UID of the ServiceAccount the token identifies - // - Secret.Data["token"] - a token that identifies the service account to the API - SecretTypeServiceAccountToken SecretType = "kubernetes.io/service-account-token" - - // ServiceAccountNameKey is the key of the required annotation for SecretTypeServiceAccountToken secrets - ServiceAccountNameKey = "kubernetes.io/service-account.name" - // ServiceAccountUIDKey is the key of the required annotation for SecretTypeServiceAccountToken secrets - ServiceAccountUIDKey = "kubernetes.io/service-account.uid" - // ServiceAccountTokenKey is the key of the required data for SecretTypeServiceAccountToken secrets - ServiceAccountTokenKey = "token" - // ServiceAccountKubeconfigKey is the key of the optional kubeconfig data for SecretTypeServiceAccountToken secrets - ServiceAccountKubeconfigKey = "kubernetes.kubeconfig" - // ServiceAccountRootCAKey is the key of the optional root certificate authority for SecretTypeServiceAccountToken secrets - ServiceAccountRootCAKey = "ca.crt" - - // SecretTypeDockercfg contains a dockercfg file that follows the same format rules as ~/.dockercfg - // - // Required fields: - // - Secret.Data[".dockercfg"] - a serialized ~/.dockercfg file - SecretTypeDockercfg SecretType = "kubernetes.io/dockercfg" - - // DockerConfigKey is the key of the required data for SecretTypeDockercfg secrets - DockerConfigKey = ".dockercfg" -) - -type SecretList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Items []Secret `json:"items" description:"items is a list of secret objects"` -} - -// Type and constants for component health validation. -type ComponentConditionType string - -// These are the valid conditions for the component. -const ( - ComponentHealthy ComponentConditionType = "Healthy" -) - -type ComponentCondition struct { - Type ComponentConditionType `json:"type" description:"type of component condition, currently only Healthy"` - Status ConditionStatus `json:"status" description:"current status of this component condition, one of True, False, Unknown"` - Message string `json:"message,omitempty" description:"health check message received from the component"` - Error string `json:"error,omitempty" description:"error code from health check attempt (if any)"` -} - -// ComponentStatus (and ComponentStatusList) holds the cluster validation info. -type ComponentStatus struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Conditions []ComponentCondition `json:"conditions,omitempty" description:"list of component conditions observed" patchStrategy:"merge" patchMergeKey:"type"` -} - -type ComponentStatusList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Items []ComponentStatus `json:"items" description:"list of component status objects"` -} - -// SecurityContext holds security configuration that will be applied to a container. SecurityContext -// contains duplication of some existing fields from the Container resource. These duplicate fields -// will be populated based on the Container configuration if they are not set. Defining them on -// both the Container AND the SecurityContext will result in an error. -type SecurityContext struct { - // Capabilities are the capabilities to add/drop when running the container - // Must match Container.Capabilities or be unset. Will be defaulted to Container.Capabilities if left unset - Capabilities *Capabilities `json:"capabilities,omitempty" description:"the linux capabilites that should be added or removed"` - - // Run the container in privileged mode - // Must match Container.Privileged or be unset. Will be defaulted to Container.Privileged if left unset - Privileged *bool `json:"privileged,omitempty" description:"run the container in privileged mode"` - - // SELinuxOptions are the labels to be applied to the container - // and volumes - SELinuxOptions *SELinuxOptions `json:"seLinuxOptions,omitempty" description:"options that control the SELinux labels applied"` - - // RunAsUser is the UID to run the entrypoint of the container process. - RunAsUser *int64 `json:"runAsUser,omitempty" description:"the user id that runs the first process in the container"` - - // RunAsNonRoot indicates that the container should be run as a non-root user. If the RunAsUser - // field is not explicitly set then the kubelet may check the image for a specified user or - // perform defaulting to specify a user. - RunAsNonRoot bool `json:"runAsNonRoot,omitempty" description:"indicates the container be must run as a non-root user either by specifying the runAsUser or in the image specification"` -} - -// SELinuxOptions are the labels to be applied to the container. -type SELinuxOptions struct { - // SELinux user label - User string `json:"user,omitempty" description:"the user label to apply to the container"` - - // SELinux role label - Role string `json:"role,omitempty" description:"the role label to apply to the container"` - - // SELinux type label - Type string `json:"type,omitempty" description:"the type label to apply to the container"` - - // SELinux level label. - Level string `json:"level,omitempty" description:"the level label to apply to the container"` -} - -// RangeAllocation is not a public type -type RangeAllocation struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` - - Range string `json:"range" description:"a range string that identifies the range represented by 'data'; required"` - Data []byte `json:"data" description:"a bit array containing all allocated addresses in the previous segment"` -} - -// SecurityContextConstraints governs the ability to make requests that affect the SecurityContext -// that will be applied to a container. -type SecurityContextConstraints struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata,omitempty"` - - // AllowPrivilegedContainer determines if a container can request to be run as privileged. - AllowPrivilegedContainer bool `json:"allowPrivilegedContainer" description:"allow containers to run as privileged"` - // AllowedCapabilities is a list of capabilities that can be requested to add to the container. - AllowedCapabilities []Capability `json:"allowedCapabilities" description:"capabilities that are allowed to be added"` - // AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin - AllowHostDirVolumePlugin bool `json:"allowHostDirVolumePlugin" description:"allow the use of the host dir volume plugin"` - // AllowHostNetwork determines if the policy allows the use of HostNetwork in the pod spec. - AllowHostNetwork bool `json:"allowHostNetwork" description:"allow the use of the hostNetwork in the pod spec"` - // AllowHostPorts determines if the policy allows host ports in the containers. - AllowHostPorts bool `json:"allowHostPorts" description:"allow the use of the host ports in the containers"` - // AllowHostPID determines if the policy allows host pid in the containers. - AllowHostPID bool `json:"allowHostPID" description:"allow the use of the host pid in the containers"` - // AllowHostIPC determines if the policy allows host ipc in the containers. - AllowHostIPC bool `json:"allowHostIPC" description:"allow the use of the host ipc in the containers"` - // SELinuxContext is the strategy that will dictate what labels will be set in the SecurityContext. - SELinuxContext SELinuxContextStrategyOptions `json:"seLinuxContext,omitempty" description:"strategy used to generate SELinuxOptions"` - // RunAsUser is the strategy that will dictate what RunAsUser is used in the SecurityContext. - RunAsUser RunAsUserStrategyOptions `json:"runAsUser,omitempty" description:"strategy used to generate RunAsUser"` - // SupplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. - SupplementalGroups SupplementalGroupsStrategyOptions `json:"supplementalGroups,omitempty" description:"strategy used to generate supplemental groups"` - // FSGroup is the strategy that will dictate what fs group is used by the SecurityContext. - FSGroup FSGroupStrategyOptions `json:"fsGroup,omitempty" description:"strategy used to generate fsGroup"` - - // The users who have permissions to use this security context constraints - Users []string `json:"users,omitempty" description:"users allowed to use this SecurityContextConstraints"` - // The groups that have permission to use this security context constraints - Groups []string `json:"groups,omitempty" description:"groups allowed to use this SecurityContextConstraints"` -} - -// SELinuxContextStrategyOptions defines the strategy type and any options used to create the strategy. -type SELinuxContextStrategyOptions struct { - // Type is the strategy that will dictate what SELinux context is used in the SecurityContext. - Type SELinuxContextStrategyType `json:"type,omitempty" description:"strategy used to generate the SELinux context"` - // seLinuxOptions required to run as; required for MustRunAs - SELinuxOptions *SELinuxOptions `json:"seLinuxOptions,omitempty" description:"seLinuxOptions required to run as; required for MustRunAs"` -} - -// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. -type RunAsUserStrategyOptions struct { - // Type is the strategy that will dictate what RunAsUser is used in the SecurityContext. - Type RunAsUserStrategyType `json:"type,omitempty" description:"strategy used to generate RunAsUser"` - // UID is the user id that containers must run as. Required for the MustRunAs strategy if not using - // namespace/service account allocated uids. - UID *int64 `json:"uid,omitempty" description:"the uid to always run as; required for MustRunAs"` - // UIDRangeMin defines the min value for a strategy that allocates by range. - UIDRangeMin *int64 `json:"uidRangeMin,omitempty" description:"min value for range based allocators"` - // UIDRangeMax defines the max value for a strategy that allocates by range. - UIDRangeMax *int64 `json:"uidRangeMax,omitempty" description:"max value for range based allocators"` -} - -// FSGroupStrategyOptions defines the strategy type and options used to create the strategy. -type FSGroupStrategyOptions struct { - // Type is the strategy that will dictate what FSGroup is used in the SecurityContext. - Type FSGroupStrategyType `json:"type,omitempty" description:"strategy used to generate fsGroup"` - // Ranges are the allowed ranges of fs groups. If you would like to force a single - // fs group then supply a single range with the same start and end. - Ranges []IDRange `json:"ranges,omitempty" description:"ranges of allowable IDs for fsGroup"` -} - -// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. -type SupplementalGroupsStrategyOptions struct { - // Type is the strategy that will dictate what supplemental groups is used in the SecurityContext. - Type SupplementalGroupsStrategyType `json:"type,omitempty" description:"strategy used to generate supplemental groups"` - // Ranges are the allowed ranges of supplemental groups. If you would like to force a single - // supplemental group then supply a single range with the same start and end. - Ranges []IDRange `json:"ranges,omitempty" description:"ranges of allowable IDs for supplemental groups"` -} - -// IDRange provides a min/max of an allowed range of IDs. -// TODO: this could be reused for UIDs. -type IDRange struct { - // Min is the start of the range, inclusive. - Min int64 `json:"min,omitempty" description:"min value for the range"` - // Max is the end of the range, inclusive. - Max int64 `json:"max,omitempty" description:"min value for the range"` -} - -// SELinuxContextStrategyType denotes strategy types for generating SELinux options for a -// SecurityContext -type SELinuxContextStrategyType string - -// RunAsUserStrategyType denotes strategy types for generating RunAsUser values for a -// SecurityContext -type RunAsUserStrategyType string - -// SupplementalGroupsStrategyType denotes strategy types for determining valid supplemental -// groups for a SecurityContext. -type SupplementalGroupsStrategyType string - -// FSGroupStrategyType denotes strategy types for generating FSGroup values for a -// SecurityContext -type FSGroupStrategyType string - -const ( - // container must have SELinux labels of X applied. - SELinuxStrategyMustRunAs SELinuxContextStrategyType = "MustRunAs" - // container may make requests for any SELinux context labels. - SELinuxStrategyRunAsAny SELinuxContextStrategyType = "RunAsAny" - - // container must run as a particular uid. - RunAsUserStrategyMustRunAs RunAsUserStrategyType = "MustRunAs" - // container must run as a particular uid. - RunAsUserStrategyMustRunAsRange RunAsUserStrategyType = "MustRunAsRange" - // container must run as a non-root uid - RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategyType = "MustRunAsNonRoot" - // container may make requests for any uid. - RunAsUserStrategyRunAsAny RunAsUserStrategyType = "RunAsAny" - - // container must have FSGroup of X applied. - FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs" - // container may make requests for any FSGroup labels. - FSGroupStrategyRunAsAny FSGroupStrategyType = "RunAsAny" - - // container must run as a particular gid. - SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs" - // container may make requests for any gid. - SupplementalGroupsrStrategyRunAsAny SupplementalGroupsStrategyType = "RunAsAny" -) - -// SecurityContextConstraintsList is a list of SecurityContextConstraints objects -type SecurityContextConstraintsList struct { - TypeMeta `json:",inline"` - ListMeta `json:"metadata,omitempty"` - - Items []SecurityContextConstraints `json:"items"` -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/events.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/events.go index 2fe0f7ac504e..cc44d2b6bb0e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/events.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/events.go @@ -18,19 +18,19 @@ package validation import ( "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" errs "k8s.io/kubernetes/pkg/util/fielderrors" + "k8s.io/kubernetes/pkg/util/validation" ) // ValidateEvent makes sure that the event makes sense. func ValidateEvent(event *api.Event) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - // TODO: There is no namespace required for minion + // TODO: There is no namespace required for node. if event.InvolvedObject.Kind != "Node" && event.Namespace != event.InvolvedObject.Namespace { allErrs = append(allErrs, errs.NewFieldInvalid("involvedObject.namespace", event.InvolvedObject.Namespace, "namespace does not match involvedObject")) } - if !util.IsDNS1123Subdomain(event.Namespace) { + if !validation.IsDNS1123Subdomain(event.Namespace) { allErrs = append(allErrs, errs.NewFieldInvalid("namespace", event.Namespace, "")) } return allErrs diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/schema.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/schema.go index 8b1cf674b6b7..4ef14aae4f81 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/schema.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/schema.go @@ -20,10 +20,12 @@ import ( "encoding/json" "fmt" "reflect" + "regexp" "strings" "github.com/emicklei/go-restful/swagger" "github.com/golang/glog" + apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/util/errors" errs "k8s.io/kubernetes/pkg/util/fielderrors" "k8s.io/kubernetes/pkg/util/yaml" @@ -65,6 +67,60 @@ func NewSwaggerSchemaFromBytes(data []byte) (Schema, error) { return schema, nil } +// validateList unpack a list and validate every item in the list. +// It return nil if every item is ok. +// Otherwise it return an error list contain errors of every item. +func (s *SwaggerSchema) validateList(obj map[string]interface{}) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + items, exists := obj["items"] + if !exists { + return append(allErrs, fmt.Errorf("no items field in %#v", obj)) + } + itemList, ok := items.([]interface{}) + if !ok { + return append(allErrs, fmt.Errorf("items isn't a slice")) + } + for i, item := range itemList { + fields, ok := item.(map[string]interface{}) + if !ok { + allErrs = append(allErrs, fmt.Errorf("items[%d] isn't a map[string]interface{}", i)) + continue + } + groupVersion := fields["apiVersion"] + if groupVersion == nil { + allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion not set", i)) + continue + } + itemVersion, ok := groupVersion.(string) + if !ok { + allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion isn't string type", i)) + continue + } + if len(itemVersion) == 0 { + allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion is empty", i)) + } + kind := fields["kind"] + if kind == nil { + allErrs = append(allErrs, fmt.Errorf("items[%d].kind not set", i)) + continue + } + itemKind, ok := kind.(string) + if !ok { + allErrs = append(allErrs, fmt.Errorf("items[%d].kind isn't string type", i)) + continue + } + if len(itemKind) == 0 { + allErrs = append(allErrs, fmt.Errorf("items[%d].kind is empty", i)) + } + version := apiutil.GetVersion(itemVersion) + errs := s.ValidateObject(item, "", version+"."+itemKind) + if len(errs) >= 1 { + allErrs = append(allErrs, errs...) + } + } + return allErrs +} + func (s *SwaggerSchema) ValidateBytes(data []byte) error { var obj interface{} out, err := yaml.ToJSON(data) @@ -79,25 +135,34 @@ func (s *SwaggerSchema) ValidateBytes(data []byte) error { if !ok { return fmt.Errorf("error in unmarshaling data %s", string(data)) } - apiVersion := fields["apiVersion"] - if apiVersion == nil { + groupVersion := fields["apiVersion"] + if groupVersion == nil { return fmt.Errorf("apiVersion not set") } + if _, ok := groupVersion.(string); !ok { + return fmt.Errorf("apiVersion isn't string type") + } kind := fields["kind"] if kind == nil { return fmt.Errorf("kind not set") } - allErrs := s.ValidateObject(obj, apiVersion.(string), "", apiVersion.(string)+"."+kind.(string)) + if _, ok := kind.(string); !ok { + return fmt.Errorf("kind isn't string type") + } + if strings.HasSuffix(kind.(string), "List") { + return errors.NewAggregate(s.validateList(fields)) + } + version := apiutil.GetVersion(groupVersion.(string)) + allErrs := s.ValidateObject(obj, "", version+"."+kind.(string)) if len(allErrs) == 1 { return allErrs[0] } return errors.NewAggregate(allErrs) } -func (s *SwaggerSchema) ValidateObject(obj interface{}, apiVersion, fieldName, typeName string) errs.ValidationErrorList { +func (s *SwaggerSchema) ValidateObject(obj interface{}, fieldName, typeName string) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} models := s.api.Models - // TODO: handle required fields here too. model, ok := models.At(typeName) if !ok { return append(allErrs, fmt.Errorf("couldn't find type: %s", typeName)) @@ -139,7 +204,7 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, apiVersion, fieldName, t glog.V(2).Infof("Skipping nil field: %s", key) continue } - errs := s.validateField(value, apiVersion, fieldName+key, fieldType, &details) + errs := s.validateField(value, fieldName+key, fieldType, &details) if len(errs) > 0 { allErrs = append(allErrs, errs...) } @@ -147,9 +212,22 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, apiVersion, fieldName, t return allErrs } -func (s *SwaggerSchema) validateField(value interface{}, apiVersion, fieldName, fieldType string, fieldDetails *swagger.ModelProperty) errs.ValidationErrorList { - if strings.HasPrefix(fieldType, apiVersion) { - return s.ValidateObject(value, apiVersion, fieldName, fieldType) +// This matches type name in the swagger spec, such as "v1.Binding". +var versionRegexp = regexp.MustCompile(`^v.+\..*`) + +func (s *SwaggerSchema) validateField(value interface{}, fieldName, fieldType string, fieldDetails *swagger.ModelProperty) errs.ValidationErrorList { + // TODO: caesarxuchao: because we have multiple group/versions and objects + // may reference objects in other group, the commented out way of checking + // if a filedType is a type defined by us is outdated. We use a hacky way + // for now. + // TODO: the type name in the swagger spec is something like "v1.Binding", + // and the "v1" is generated from the package name, not the groupVersion of + // the type. We need to fix go-restful to embed the group name in the type + // name, otherwise we couldn't handle identically named types in different + // groups correctly. + if versionRegexp.MatchString(fieldType) { + // if strings.HasPrefix(fieldType, apiVersion) { + return s.ValidateObject(value, fieldName, fieldType) } allErrs := errs.ValidationErrorList{} switch fieldType { @@ -176,7 +254,7 @@ func (s *SwaggerSchema) validateField(value interface{}, apiVersion, fieldName, arrType = *fieldDetails.Items.Type } for ix := range arr { - errs := s.validateField(arr[ix], apiVersion, fmt.Sprintf("%s[%d]", fieldName, ix), arrType, nil) + errs := s.validateField(arr[ix], fmt.Sprintf("%s[%d]", fieldName, ix), arrType, nil) if len(errs) > 0 { allErrs = append(allErrs, errs...) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/schema_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/schema_test.go index d1d386f7218f..b2b5ea1a6654 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/schema_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/schema_test.go @@ -125,3 +125,31 @@ func TestValid(t *testing.T) { } } } + +func TestVersionRegex(t *testing.T) { + testCases := []struct { + typeName string + match bool + }{ + { + typeName: "v1.Binding", + match: true, + }, + { + typeName: "v1beta1.Binding", + match: true, + }, + { + typeName: "Binding", + match: false, + }, + } + for _, test := range testCases { + if versionRegexp.MatchString(test.typeName) && !test.match { + t.Errorf("unexpected error: expect %s not to match the regular expression", test.typeName) + } + if !versionRegexp.MatchString(test.typeName) && test.match { + t.Errorf("unexpected error: expect %s to match the regular expression", test.typeName) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go index 5615801b3dcf..d48f7183a4bf 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go @@ -33,31 +33,36 @@ import ( "k8s.io/kubernetes/pkg/util" errs "k8s.io/kubernetes/pkg/util/fielderrors" "k8s.io/kubernetes/pkg/util/sets" + "k8s.io/kubernetes/pkg/util/validation" "github.com/golang/glog" ) -const cIdentifierErrorMsg string = `must be a C identifier (matching regex ` + util.CIdentifierFmt + `): e.g. "my_name" or "MyName"` +// TODO: delete this global variable when we enable the validation of common +// fields by default. +var RepairMalformedUpdates bool = true + +const cIdentifierErrorMsg string = `must be a C identifier (matching regex ` + validation.CIdentifierFmt + `): e.g. "my_name" or "MyName"` const isNegativeErrorMsg string = `must be non-negative` func intervalErrorMsg(lo, hi int) string { return fmt.Sprintf(`must be greater than %d and less than %d`, lo, hi) } -var labelValueErrorMsg string = fmt.Sprintf(`must have at most %d characters, matching regex %s: e.g. "MyValue" or ""`, util.LabelValueMaxLength, util.LabelValueFmt) -var qualifiedNameErrorMsg string = fmt.Sprintf(`must be a qualified name (at most %d characters, matching regex %s), with an optional DNS subdomain prefix (at most %d characters, matching regex %s) and slash (/): e.g. "MyName" or "example.com/MyName"`, util.QualifiedNameMaxLength, util.QualifiedNameFmt, util.DNS1123SubdomainMaxLength, util.DNS1123SubdomainFmt) -var DNSSubdomainErrorMsg string = fmt.Sprintf(`must be a DNS subdomain (at most %d characters, matching regex %s): e.g. "example.com"`, util.DNS1123SubdomainMaxLength, util.DNS1123SubdomainFmt) -var DNS1123LabelErrorMsg string = fmt.Sprintf(`must be a DNS label (at most %d characters, matching regex %s): e.g. "my-name"`, util.DNS1123LabelMaxLength, util.DNS1123LabelFmt) -var DNS952LabelErrorMsg string = fmt.Sprintf(`must be a DNS 952 label (at most %d characters, matching regex %s): e.g. "my-name"`, util.DNS952LabelMaxLength, util.DNS952LabelFmt) +var labelValueErrorMsg string = fmt.Sprintf(`must have at most %d characters, matching regex %s: e.g. "MyValue" or ""`, validation.LabelValueMaxLength, validation.LabelValueFmt) +var qualifiedNameErrorMsg string = fmt.Sprintf(`must be a qualified name (at most %d characters, matching regex %s), with an optional DNS subdomain prefix (at most %d characters, matching regex %s) and slash (/): e.g. "MyName" or "example.com/MyName"`, validation.QualifiedNameMaxLength, validation.QualifiedNameFmt, validation.DNS1123SubdomainMaxLength, validation.DNS1123SubdomainFmt) +var DNSSubdomainErrorMsg string = fmt.Sprintf(`must be a DNS subdomain (at most %d characters, matching regex %s): e.g. "example.com"`, validation.DNS1123SubdomainMaxLength, validation.DNS1123SubdomainFmt) +var DNS1123LabelErrorMsg string = fmt.Sprintf(`must be a DNS label (at most %d characters, matching regex %s): e.g. "my-name"`, validation.DNS1123LabelMaxLength, validation.DNS1123LabelFmt) +var DNS952LabelErrorMsg string = fmt.Sprintf(`must be a DNS 952 label (at most %d characters, matching regex %s): e.g. "my-name"`, validation.DNS952LabelMaxLength, validation.DNS952LabelFmt) var pdPartitionErrorMsg string = intervalErrorMsg(0, 255) var portRangeErrorMsg string = intervalErrorMsg(0, 65536) -var portNameErrorMsg string = fmt.Sprintf(`must be an IANA_SVC_NAME (at most 15 characters, matching regex %s, it must contain at least one letter [a-z], and hyphens cannot be adjacent to other hyphens): e.g. "http"`, util.IdentifierNoHyphensBeginEndFmt) +var portNameErrorMsg string = fmt.Sprintf(`must be an IANA_SVC_NAME (at most 15 characters, matching regex %s, it must contain at least one letter [a-z], and hyphens cannot be adjacent to other hyphens): e.g. "http"`, validation.IdentifierNoHyphensBeginEndFmt) const totalAnnotationSizeLimitB int = 64 * (1 << 10) // 64 kB func ValidateLabelName(labelName, fieldName string) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - if !util.IsQualifiedName(labelName) { + if !validation.IsQualifiedName(labelName) { allErrs = append(allErrs, errs.NewFieldInvalid(fieldName, labelName, qualifiedNameErrorMsg)) } return allErrs @@ -68,7 +73,7 @@ func ValidateLabels(labels map[string]string, field string) errs.ValidationError allErrs := errs.ValidationErrorList{} for k, v := range labels { allErrs = append(allErrs, ValidateLabelName(k, field)...) - if !util.IsValidLabelValue(v) { + if !validation.IsValidLabelValue(v) { allErrs = append(allErrs, errs.NewFieldInvalid(field, v, labelValueErrorMsg)) } } @@ -80,7 +85,7 @@ func ValidateAnnotations(annotations map[string]string, field string) errs.Valid allErrs := errs.ValidationErrorList{} var totalSize int64 for k, v := range annotations { - if !util.IsQualifiedName(strings.ToLower(k)) { + if !validation.IsQualifiedName(strings.ToLower(k)) { allErrs = append(allErrs, errs.NewFieldInvalid(field, k, qualifiedNameErrorMsg)) } totalSize += (int64)(len(k)) + (int64)(len(v)) @@ -177,20 +182,12 @@ func ValidateEndpointsName(name string, prefix bool) (bool, string) { return NameIsDNSSubdomain(name, prefix) } -// ValidateSecurityContextConstraintsName can be used to check whether the given -// security context constraint name is valid. -// Prefix indicates this name will be used as part of generation, in which case -// trailing dashes are allowed. -func ValidateSecurityContextConstraintsName(name string, prefix bool) (bool, string) { - return NameIsDNSSubdomain(name, prefix) -} - // NameIsDNSSubdomain is a ValidateNameFunc for names that must be a DNS subdomain. func NameIsDNSSubdomain(name string, prefix bool) (bool, string) { if prefix { name = maskTrailingDash(name) } - if util.IsDNS1123Subdomain(name) { + if validation.IsDNS1123Subdomain(name) { return true, "" } return false, DNSSubdomainErrorMsg @@ -201,7 +198,7 @@ func NameIsDNSLabel(name string, prefix bool) (bool, string) { if prefix { name = maskTrailingDash(name) } - if util.IsDNS1123Label(name) { + if validation.IsDNS1123Label(name) { return true, "" } return false, DNS1123LabelErrorMsg @@ -212,7 +209,7 @@ func NameIsDNS952Label(name string, prefix bool) (bool, string) { if prefix { name = maskTrailingDash(name) } - if util.IsDNS952Label(name) { + if validation.IsDNS952Label(name) { return true, "" } return false, DNS952LabelErrorMsg @@ -227,8 +224,18 @@ func ValidatePositiveField(value int64, fieldName string) errs.ValidationErrorLi return allErrs } +// Validates that a Quantity is not negative +func ValidatePositiveQuantity(value resource.Quantity, fieldName string) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if value.Cmp(resource.Quantity{}) < 0 { + allErrs = append(allErrs, errs.NewFieldInvalid(fieldName, value.String(), isNegativeErrorMsg)) + } + return allErrs +} + // ValidateObjectMeta validates an object's metadata on creation. It expects that name generation has already // been performed. +// TODO: Remove calls to this method scattered in validations of specific resources, e.g., ValidatePodUpdate. func ValidateObjectMeta(meta *api.ObjectMeta, requiresNamespace bool, nameFn ValidateNameFunc) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} @@ -271,23 +278,32 @@ func ValidateObjectMeta(meta *api.ObjectMeta, requiresNamespace bool, nameFn Val func ValidateObjectMetaUpdate(new, old *api.ObjectMeta) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - // in the event it is left empty, set it, to allow clients more flexibility - if len(new.UID) == 0 { - new.UID = old.UID - } - // ignore changes to timestamp - if old.CreationTimestamp.IsZero() { - old.CreationTimestamp = new.CreationTimestamp - } else { - new.CreationTimestamp = old.CreationTimestamp - } - // an object can never remove a deletion timestamp or clear/change grace period seconds - if !old.DeletionTimestamp.IsZero() { - new.DeletionTimestamp = old.DeletionTimestamp + if !RepairMalformedUpdates && new.UID != old.UID { + allErrs = append(allErrs, errs.NewFieldInvalid("uid", new.UID, "field is immutable")) } - if old.DeletionGracePeriodSeconds != nil && new.DeletionGracePeriodSeconds == nil { - new.DeletionGracePeriodSeconds = old.DeletionGracePeriodSeconds + // in the event it is left empty, set it, to allow clients more flexibility + // TODO: remove the following code that repairs the update request when we retire the clients that modify the immutable fields. + // Please do not copy this pattern elsewhere; validation functions should not be modifying the objects they are passed! + if RepairMalformedUpdates { + if len(new.UID) == 0 { + new.UID = old.UID + } + // ignore changes to timestamp + if old.CreationTimestamp.IsZero() { + old.CreationTimestamp = new.CreationTimestamp + } else { + new.CreationTimestamp = old.CreationTimestamp + } + // an object can never remove a deletion timestamp or clear/change grace period seconds + if !old.DeletionTimestamp.IsZero() { + new.DeletionTimestamp = old.DeletionTimestamp + } + if old.DeletionGracePeriodSeconds != nil && new.DeletionGracePeriodSeconds == nil { + new.DeletionGracePeriodSeconds = old.DeletionGracePeriodSeconds + } } + + // TODO: needs to check if new==nil && old !=nil after the repair logic is removed. if new.DeletionGracePeriodSeconds != nil && old.DeletionGracePeriodSeconds != nil && *new.DeletionGracePeriodSeconds != *old.DeletionGracePeriodSeconds { allErrs = append(allErrs, errs.NewFieldInvalid("deletionGracePeriodSeconds", new.DeletionGracePeriodSeconds, "field is immutable; may only be changed via deletion")) } @@ -324,7 +340,7 @@ func validateVolumes(volumes []api.Volume) (sets.String, errs.ValidationErrorLis el := validateSource(&vol.VolumeSource).Prefix("source") if len(vol.Name) == 0 { el = append(el, errs.NewFieldRequired("name")) - } else if !util.IsDNS1123Label(vol.Name) { + } else if !validation.IsDNS1123Label(vol.Name) { el = append(el, errs.NewFieldInvalid("name", vol.Name, DNS1123LabelErrorMsg)) } else if allNames.Has(vol.Name) { el = append(el, errs.NewFieldDuplicate("name", vol.Name)) @@ -377,6 +393,10 @@ func validateSource(source *api.VolumeSource) errs.ValidationErrorList { numVolumes++ allErrs = append(allErrs, validateGlusterfs(source.Glusterfs).Prefix("glusterfs")...) } + if source.Flocker != nil { + numVolumes++ + allErrs = append(allErrs, validateFlocker(source.Flocker).Prefix("flocker")...) + } if source.PersistentVolumeClaim != nil { numVolumes++ allErrs = append(allErrs, validatePersistentClaimVolumeSource(source.PersistentVolumeClaim).Prefix("persistentVolumeClaim")...) @@ -397,6 +417,10 @@ func validateSource(source *api.VolumeSource) errs.ValidationErrorList { numVolumes++ allErrs = append(allErrs, validateDownwardAPIVolumeSource(source.DownwardAPI).Prefix("downwardApi")...) } + if source.FC != nil { + numVolumes++ + allErrs = append(allErrs, validateFCVolumeSource(source.FC).Prefix("fc")...) + } if numVolumes != 1 { allErrs = append(allErrs, errs.NewFieldInvalid("", source, "exactly 1 volume type is required")) } @@ -404,9 +428,9 @@ func validateSource(source *api.VolumeSource) errs.ValidationErrorList { return allErrs } -func validateHostPathVolumeSource(hostDir *api.HostPathVolumeSource) errs.ValidationErrorList { +func validateHostPathVolumeSource(hostPath *api.HostPathVolumeSource) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - if hostDir.Path == "" { + if hostPath.Path == "" { allErrs = append(allErrs, errs.NewFieldRequired("path")) } return allErrs @@ -437,6 +461,25 @@ func validateISCSIVolumeSource(iscsi *api.ISCSIVolumeSource) errs.ValidationErro return allErrs } +func validateFCVolumeSource(fc *api.FCVolumeSource) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if len(fc.TargetWWNs) < 1 { + allErrs = append(allErrs, errs.NewFieldRequired("targetWWNs")) + } + if fc.FSType == "" { + allErrs = append(allErrs, errs.NewFieldRequired("fsType")) + } + + if fc.Lun == nil { + allErrs = append(allErrs, errs.NewFieldRequired("lun")) + } else { + if *fc.Lun < 0 || *fc.Lun > 255 { + allErrs = append(allErrs, errs.NewFieldInvalid("lun", fc.Lun, "")) + } + } + return allErrs +} + func validateGCEPersistentDiskVolumeSource(PD *api.GCEPersistentDiskVolumeSource) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} if PD.PDName == "" { @@ -506,6 +549,17 @@ func validateGlusterfs(glusterfs *api.GlusterfsVolumeSource) errs.ValidationErro return allErrs } +func validateFlocker(flocker *api.FlockerVolumeSource) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if flocker.DatasetName == "" { + allErrs = append(allErrs, errs.NewFieldRequired("datasetName")) + } + if strings.Contains(flocker.DatasetName, "/") { + allErrs = append(allErrs, errs.NewFieldInvalid("datasetName", flocker.DatasetName, "must not contain '/'")) + } + return allErrs +} + var validDownwardAPIFieldPathExpressions = sets.NewString("metadata.name", "metadata.namespace", "metadata.labels", "metadata.annotations") func validateDownwardAPIVolumeSource(downwardAPIVolume *api.DownwardAPIVolumeSource) errs.ValidationErrorList { @@ -611,6 +665,10 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) errs.ValidationErrorList numVolumes++ allErrs = append(allErrs, validateGlusterfs(pv.Spec.Glusterfs).Prefix("glusterfs")...) } + if pv.Spec.Flocker != nil { + numVolumes++ + allErrs = append(allErrs, validateFlocker(pv.Spec.Flocker).Prefix("flocker")...) + } if pv.Spec.NFS != nil { numVolumes++ allErrs = append(allErrs, validateNFS(pv.Spec.NFS).Prefix("nfs")...) @@ -631,6 +689,10 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) errs.ValidationErrorList numVolumes++ allErrs = append(allErrs, validateCinderVolumeSource(pv.Spec.Cinder).Prefix("cinder")...) } + if pv.Spec.FC != nil { + numVolumes++ + allErrs = append(allErrs, validateFCVolumeSource(pv.Spec.FC).Prefix("fc")...) + } if numVolumes != 1 { allErrs = append(allErrs, errs.NewFieldInvalid("", pv.Spec.PersistentVolumeSource, "exactly 1 volume type is required")) } @@ -706,7 +768,7 @@ func validatePorts(ports []api.ContainerPort) errs.ValidationErrorList { for i, port := range ports { pErrs := errs.ValidationErrorList{} if len(port.Name) > 0 { - if !util.IsValidPortName(port.Name) { + if !validation.IsValidPortName(port.Name) { pErrs = append(pErrs, errs.NewFieldInvalid("name", port.Name, portNameErrorMsg)) } else if allNames.Has(port.Name) { pErrs = append(pErrs, errs.NewFieldDuplicate("name", port.Name)) @@ -716,10 +778,10 @@ func validatePorts(ports []api.ContainerPort) errs.ValidationErrorList { } if port.ContainerPort == 0 { pErrs = append(pErrs, errs.NewFieldInvalid("containerPort", port.ContainerPort, portRangeErrorMsg)) - } else if !util.IsValidPortNum(port.ContainerPort) { + } else if !validation.IsValidPortNum(port.ContainerPort) { pErrs = append(pErrs, errs.NewFieldInvalid("containerPort", port.ContainerPort, portRangeErrorMsg)) } - if port.HostPort != 0 && !util.IsValidPortNum(port.HostPort) { + if port.HostPort != 0 && !validation.IsValidPortNum(port.HostPort) { pErrs = append(pErrs, errs.NewFieldInvalid("hostPort", port.HostPort, portRangeErrorMsg)) } if len(port.Protocol) == 0 { @@ -739,7 +801,7 @@ func validateEnv(vars []api.EnvVar) errs.ValidationErrorList { vErrs := errs.ValidationErrorList{} if len(ev.Name) == 0 { vErrs = append(vErrs, errs.NewFieldRequired("name")) - } else if !util.IsCIdentifier(ev.Name) { + } else if !validation.IsCIdentifier(ev.Name) { vErrs = append(vErrs, errs.NewFieldInvalid("name", ev.Name, cIdentifierErrorMsg)) } vErrs = append(vErrs, validateEnvVarValueFrom(ev).Prefix("valueFrom")...) @@ -869,9 +931,9 @@ func validateHTTPGetAction(http *api.HTTPGetAction) errs.ValidationErrorList { if len(http.Path) == 0 { allErrors = append(allErrors, errs.NewFieldRequired("path")) } - if http.Port.Kind == util.IntstrInt && !util.IsValidPortNum(http.Port.IntVal) { + if http.Port.Kind == util.IntstrInt && !validation.IsValidPortNum(http.Port.IntVal) { allErrors = append(allErrors, errs.NewFieldInvalid("port", http.Port, portRangeErrorMsg)) - } else if http.Port.Kind == util.IntstrString && !util.IsValidPortName(http.Port.StrVal) { + } else if http.Port.Kind == util.IntstrString && !validation.IsValidPortName(http.Port.StrVal) { allErrors = append(allErrors, errs.NewFieldInvalid("port", http.Port.StrVal, portNameErrorMsg)) } supportedSchemes := sets.NewString(string(api.URISchemeHTTP), string(api.URISchemeHTTPS)) @@ -883,9 +945,9 @@ func validateHTTPGetAction(http *api.HTTPGetAction) errs.ValidationErrorList { func validateTCPSocketAction(tcp *api.TCPSocketAction) errs.ValidationErrorList { allErrors := errs.ValidationErrorList{} - if tcp.Port.Kind == util.IntstrInt && !util.IsValidPortNum(tcp.Port.IntVal) { + if tcp.Port.Kind == util.IntstrInt && !validation.IsValidPortNum(tcp.Port.IntVal) { allErrors = append(allErrors, errs.NewFieldInvalid("port", tcp.Port, portRangeErrorMsg)) - } else if tcp.Port.Kind == util.IntstrString && !util.IsValidPortName(tcp.Port.StrVal) { + } else if tcp.Port.Kind == util.IntstrString && !validation.IsValidPortName(tcp.Port.StrVal) { allErrors = append(allErrors, errs.NewFieldInvalid("port", tcp.Port.StrVal, portNameErrorMsg)) } return allErrors @@ -951,7 +1013,7 @@ func validateContainers(containers []api.Container, volumes sets.String) errs.Va cErrs := errs.ValidationErrorList{} if len(ctr.Name) == 0 { cErrs = append(cErrs, errs.NewFieldRequired("name")) - } else if !util.IsDNS1123Label(ctr.Name) { + } else if !validation.IsDNS1123Label(ctr.Name) { cErrs = append(cErrs, errs.NewFieldInvalid("name", ctr.Name, DNS1123LabelErrorMsg)) } else if allNames.Has(ctr.Name) { cErrs = append(cErrs, errs.NewFieldDuplicate("name", ctr.Name)) @@ -1059,7 +1121,7 @@ func ValidatePodSpec(spec *api.PodSpec) errs.ValidationErrorList { allErrs = append(allErrs, validateRestartPolicy(&spec.RestartPolicy).Prefix("restartPolicy")...) allErrs = append(allErrs, validateDNSPolicy(&spec.DNSPolicy).Prefix("dnsPolicy")...) allErrs = append(allErrs, ValidateLabels(spec.NodeSelector, "nodeSelector")...) - allErrs = append(allErrs, validateHostNetwork(spec.HostNetwork, spec.Containers).Prefix("hostNetwork")...) + allErrs = append(allErrs, ValidatePodSecurityContext(spec.SecurityContext, spec).Prefix("securityContext")...) allErrs = append(allErrs, validateImagePullSecrets(spec.ImagePullSecrets).Prefix("imagePullSecrets")...) if len(spec.ServiceAccountName) > 0 { if ok, msg := ValidateServiceAccountName(spec.ServiceAccountName, false); !ok { @@ -1075,6 +1137,17 @@ func ValidatePodSpec(spec *api.PodSpec) errs.ValidationErrorList { return allErrs } +// ValidatePodSecurityContext test that the specified PodSecurityContext has valid data. +func ValidatePodSecurityContext(securityContext *api.PodSecurityContext, spec *api.PodSpec) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + + if securityContext != nil { + allErrs = append(allErrs, validateHostNetwork(securityContext.HostNetwork, spec.Containers).Prefix("hostNetwork")...) + } + + return allErrs +} + // ValidatePodUpdate tests to see if the update is legal for an end user to make. newPod is updated with fields // that cannot be changed. func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { @@ -1087,15 +1160,6 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { allErrs = append(allErrs, errs.NewFieldInvalid("spec.containers", "content of spec.containers is not printed out, please refer to the \"details\"", "may not add or remove containers")) return allErrs } - - // for updates, we are allowing ActiveDeadlineSeconds to be 0 - // since a user may just want to terminate the containers without deleting the pod - if newPod.Spec.ActiveDeadlineSeconds != nil { - if *newPod.Spec.ActiveDeadlineSeconds <= 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("activeDeadlineSeconds", newPod.Spec.ActiveDeadlineSeconds, "activeDeadlineSeconds must be a positive integer greater than 0")) - } - } - pod := *newPod // Tricky, we need to copy the container list so that we don't overwrite the update var newContainers []api.Container @@ -1104,14 +1168,6 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { newContainers = append(newContainers, container) } pod.Spec.Containers = newContainers - - // allow ActiveDeadlineSeconds to be updated as well - pod.Spec.ActiveDeadlineSeconds = nil - if oldPod.Spec.ActiveDeadlineSeconds != nil { - activeDeadlineSeconds := *oldPod.Spec.ActiveDeadlineSeconds - pod.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds - } - if !api.Semantic.DeepEqual(pod.Spec, oldPod.Spec) { //TODO: Pinpoint the specific field that causes the invalid error after we have strategic merge diff allErrs = append(allErrs, errs.NewFieldInvalid("spec", "content of spec is not printed out, please refer to the \"details\"", "may not update fields other than container.image")) @@ -1252,7 +1308,7 @@ func validateServicePort(sp *api.ServicePort, requireName bool, allNames *sets.S if requireName && sp.Name == "" { allErrs = append(allErrs, errs.NewFieldRequired("name")) } else if sp.Name != "" { - if !util.IsDNS1123Label(sp.Name) { + if !validation.IsDNS1123Label(sp.Name) { allErrs = append(allErrs, errs.NewFieldInvalid("name", sp.Name, DNS1123LabelErrorMsg)) } else if allNames.Has(sp.Name) { allErrs = append(allErrs, errs.NewFieldDuplicate("name", sp.Name)) @@ -1261,7 +1317,7 @@ func validateServicePort(sp *api.ServicePort, requireName bool, allNames *sets.S } } - if !util.IsValidPortNum(sp.Port) { + if !validation.IsValidPortNum(sp.Port) { allErrs = append(allErrs, errs.NewFieldInvalid("port", sp.Port, portRangeErrorMsg)) } @@ -1271,10 +1327,10 @@ func validateServicePort(sp *api.ServicePort, requireName bool, allNames *sets.S allErrs = append(allErrs, errs.NewFieldValueNotSupported("protocol", sp.Protocol, supportedPortProtocols.List())) } - if sp.TargetPort.Kind == util.IntstrInt && !util.IsValidPortNum(sp.TargetPort.IntVal) { + if sp.TargetPort.Kind == util.IntstrInt && !validation.IsValidPortNum(sp.TargetPort.IntVal) { allErrs = append(allErrs, errs.NewFieldInvalid("targetPort", sp.TargetPort, portRangeErrorMsg)) } - if sp.TargetPort.Kind == util.IntstrString && !util.IsValidPortName(sp.TargetPort.StrVal) { + if sp.TargetPort.Kind == util.IntstrString && !validation.IsValidPortName(sp.TargetPort.StrVal) { allErrs = append(allErrs, errs.NewFieldInvalid("targetPort", sp.TargetPort, portNameErrorMsg)) } @@ -1310,6 +1366,15 @@ func ValidateReplicationControllerUpdate(oldController, controller *api.Replicat return allErrs } +// ValidateReplicationControllerStatusUpdate tests if required fields in the replication controller are set. +func ValidateReplicationControllerStatusUpdate(oldController, controller *api.ReplicationController) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, ValidateObjectMetaUpdate(&controller.ObjectMeta, &oldController.ObjectMeta).Prefix("metadata")...) + allErrs = append(allErrs, ValidatePositiveField(int64(controller.Status.Replicas), "status.replicas")...) + allErrs = append(allErrs, ValidatePositiveField(int64(controller.Status.ObservedGeneration), "status.observedGeneration")...) + return allErrs +} + // Validates that the given selector is non-empty. func ValidateNonEmptySelector(selectorMap map[string]string, fieldName string) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} @@ -1436,10 +1501,10 @@ func ValidateNodeUpdate(oldNode *api.Node, node *api.Node) errs.ValidationErrorL } // Validate compute resource typename. -// Refer to docs/resources.md for more details. +// Refer to docs/design/resources.md for more details. func validateResourceName(value string, field string) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - if !util.IsQualifiedName(value) { + if !validation.IsQualifiedName(value) { return append(allErrs, errs.NewFieldInvalid(field, value, "resource typename: "+qualifiedNameErrorMsg)) } @@ -1457,7 +1522,7 @@ func ValidateLimitRange(limitRange *api.LimitRange) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} allErrs = append(allErrs, ValidateObjectMeta(&limitRange.ObjectMeta, true, ValidateLimitRangeName).Prefix("metadata")...) - // ensure resource names are properly qualified per docs/resources.md + // ensure resource names are properly qualified per docs/design/resources.md limitTypeSet := map[api.LimitType]bool{} for i := range limitRange.Spec.Limits { limit := limitRange.Spec.Limits[i] @@ -1472,6 +1537,7 @@ func ValidateLimitRange(limitRange *api.LimitRange) errs.ValidationErrorList { max := map[string]resource.Quantity{} defaults := map[string]resource.Quantity{} defaultRequests := map[string]resource.Quantity{} + maxLimitRequestRatios := map[string]resource.Quantity{} for k, q := range limit.Max { allErrs = append(allErrs, validateResourceName(string(k), fmt.Sprintf("spec.limits[%d].max[%s]", i, k))...) @@ -1504,8 +1570,10 @@ func ValidateLimitRange(limitRange *api.LimitRange) errs.ValidationErrorList { } } - for k := range limit.MaxLimitRequestRatio { + for k, q := range limit.MaxLimitRequestRatio { allErrs = append(allErrs, validateResourceName(string(k), fmt.Sprintf("spec.limits[%d].maxLimitRequestRatio[%s]", i, k))...) + keys.Insert(string(k)) + maxLimitRequestRatios[string(k)] = q } for k := range keys { @@ -1513,6 +1581,7 @@ func ValidateLimitRange(limitRange *api.LimitRange) errs.ValidationErrorList { maxQuantity, maxQuantityFound := max[k] defaultQuantity, defaultQuantityFound := defaults[k] defaultRequestQuantity, defaultRequestQuantityFound := defaultRequests[k] + maxRatio, maxRatioFound := maxLimitRequestRatios[k] if minQuantityFound && maxQuantityFound && minQuantity.Cmp(maxQuantity) > 0 { allErrs = append(allErrs, errs.NewFieldInvalid(fmt.Sprintf("spec.limits[%d].min[%s]", i, k), minQuantity, fmt.Sprintf("min value %s is greater than max value %s", minQuantity.String(), maxQuantity.String()))) @@ -1537,6 +1606,23 @@ func ValidateLimitRange(limitRange *api.LimitRange) errs.ValidationErrorList { if defaultQuantityFound && maxQuantityFound && defaultQuantity.Cmp(maxQuantity) > 0 { allErrs = append(allErrs, errs.NewFieldInvalid(fmt.Sprintf("spec.limits[%d].default[%s]", i, k), maxQuantity, fmt.Sprintf("default value %s is greater than max value %s", defaultQuantity.String(), maxQuantity.String()))) } + if maxRatioFound && maxRatio.Cmp(*resource.NewQuantity(1, resource.DecimalSI)) < 0 { + allErrs = append(allErrs, errs.NewFieldInvalid(fmt.Sprintf("spec.limits[%d].maxLimitRequestRatio[%s]", i, k), maxRatio, fmt.Sprintf("maxLimitRequestRatio %s is less than 1", maxRatio.String()))) + } + if maxRatioFound && minQuantityFound && maxQuantityFound { + maxRatioValue := float64(maxRatio.Value()) + minQuantityValue := minQuantity.Value() + maxQuantityValue := maxQuantity.Value() + if maxRatio.Value() < resource.MaxMilliValue && minQuantityValue < resource.MaxMilliValue && maxQuantityValue < resource.MaxMilliValue { + maxRatioValue = float64(maxRatio.MilliValue()) / 1000 + minQuantityValue = minQuantity.MilliValue() + maxQuantityValue = maxQuantity.MilliValue() + } + maxRatioLimit := float64(maxQuantityValue) / float64(minQuantityValue) + if maxRatioValue > maxRatioLimit { + allErrs = append(allErrs, errs.NewFieldInvalid(fmt.Sprintf("spec.limits[%d].maxLimitRequestRatio[%s]", i, k), maxRatio, fmt.Sprintf("maxLimitRequestRatio %s is greater than max/min = %f", maxRatio.String(), maxRatioLimit))) + } + } } } @@ -1558,14 +1644,14 @@ func ValidateServiceAccountUpdate(oldServiceAccount, newServiceAccount *api.Serv return allErrs } -const SecretKeyFmt string = "\\.?" + util.DNS1123LabelFmt + "(\\." + util.DNS1123LabelFmt + ")*" +const SecretKeyFmt string = "\\.?" + validation.DNS1123LabelFmt + "(\\." + validation.DNS1123LabelFmt + ")*" var secretKeyRegexp = regexp.MustCompile("^" + SecretKeyFmt + "$") // IsSecretKey tests for a string that conforms to the definition of a // subdomain in DNS (RFC 1123), except that a leading dot is allowed func IsSecretKey(value string) bool { - return len(value) <= util.DNS1123SubdomainMaxLength && secretKeyRegexp.MatchString(value) + return len(value) <= validation.DNS1123SubdomainMaxLength && secretKeyRegexp.MatchString(value) } // ValidateSecret tests if required fields in the Secret are set. @@ -1576,7 +1662,7 @@ func ValidateSecret(secret *api.Secret) errs.ValidationErrorList { totalSize := 0 for key, value := range secret.Data { if !IsSecretKey(key) { - allErrs = append(allErrs, errs.NewFieldInvalid(fmt.Sprintf("data[%s]", key), key, fmt.Sprintf("must have at most %d characters and match regex %s", util.DNS1123SubdomainMaxLength, SecretKeyFmt))) + allErrs = append(allErrs, errs.NewFieldInvalid(fmt.Sprintf("data[%s]", key), key, fmt.Sprintf("must have at most %d characters and match regex %s", validation.DNS1123SubdomainMaxLength, SecretKeyFmt))) } totalSize += len(value) @@ -1677,14 +1763,17 @@ func ValidateResourceQuota(resourceQuota *api.ResourceQuota) errs.ValidationErro allErrs := errs.ValidationErrorList{} allErrs = append(allErrs, ValidateObjectMeta(&resourceQuota.ObjectMeta, true, ValidateResourceQuotaName).Prefix("metadata")...) - for k := range resourceQuota.Spec.Hard { + for k, v := range resourceQuota.Spec.Hard { allErrs = append(allErrs, validateResourceName(string(k), string(resourceQuota.TypeMeta.Kind))...) + allErrs = append(allErrs, ValidatePositiveQuantity(v, string(k))...) } - for k := range resourceQuota.Status.Hard { + for k, v := range resourceQuota.Status.Hard { allErrs = append(allErrs, validateResourceName(string(k), string(resourceQuota.TypeMeta.Kind))...) + allErrs = append(allErrs, ValidatePositiveQuantity(v, string(k))...) } - for k := range resourceQuota.Status.Used { + for k, v := range resourceQuota.Status.Used { allErrs = append(allErrs, validateResourceName(string(k), string(resourceQuota.TypeMeta.Kind))...) + allErrs = append(allErrs, ValidatePositiveQuantity(v, string(k))...) } return allErrs } @@ -1732,7 +1821,7 @@ func ValidateNamespace(namespace *api.Namespace) errs.ValidationErrorList { // Validate finalizer names func validateFinalizerName(stringValue string) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - if !util.IsQualifiedName(stringValue) { + if !validation.IsQualifiedName(stringValue) { return append(allErrs, errs.NewFieldInvalid("spec.finalizers", stringValue, qualifiedNameErrorMsg)) } @@ -1801,8 +1890,8 @@ func validateEndpointSubsets(subsets []api.EndpointSubset) errs.ValidationErrorL ssErrs := errs.ValidationErrorList{} - if len(ss.Addresses) == 0 { - ssErrs = append(ssErrs, errs.NewFieldRequired("addresses")) + if len(ss.Addresses) == 0 && len(ss.NotReadyAddresses) == 0 { + ssErrs = append(ssErrs, errs.NewFieldRequired("addresses or notReadyAddresses")) } if len(ss.Ports) == 0 { ssErrs = append(ssErrs, errs.NewFieldRequired("ports")) @@ -1822,7 +1911,7 @@ func validateEndpointSubsets(subsets []api.EndpointSubset) errs.ValidationErrorL func validateEndpointAddress(address *api.EndpointAddress) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - if !util.IsValidIPv4(address.IP) { + if !validation.IsValidIPv4(address.IP) { allErrs = append(allErrs, errs.NewFieldInvalid("ip", address.IP, "invalid IPv4 address")) return allErrs } @@ -1855,11 +1944,11 @@ func validateEndpointPort(port *api.EndpointPort, requireName bool) errs.Validat if requireName && port.Name == "" { allErrs = append(allErrs, errs.NewFieldRequired("name")) } else if port.Name != "" { - if !util.IsDNS1123Label(port.Name) { + if !validation.IsDNS1123Label(port.Name) { allErrs = append(allErrs, errs.NewFieldInvalid("name", port.Name, DNS1123LabelErrorMsg)) } } - if !util.IsValidPortNum(port.Port) { + if !validation.IsValidPortNum(port.Port) { allErrs = append(allErrs, errs.NewFieldInvalid("port", port.Port, portRangeErrorMsg)) } if len(port.Protocol) == 0 { @@ -1900,68 +1989,22 @@ func ValidateSecurityContext(sc *api.SecurityContext) errs.ValidationErrorList { return allErrs } -func ValidateThirdPartyResourceUpdate(old, update *api.ThirdPartyResource) errs.ValidationErrorList { - return ValidateThirdPartyResource(update) -} - -func ValidateThirdPartyResource(obj *api.ThirdPartyResource) errs.ValidationErrorList { +func ValidatePodLogOptions(opts *api.PodLogOptions) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - if len(obj.Name) == 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("name", obj.Name, "name must be non-empty")) + if opts.TailLines != nil && *opts.TailLines < 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("tailLines", *opts.TailLines, "tailLines must be a non-negative integer or nil")) } - versions := sets.String{} - for ix := range obj.Versions { - version := &obj.Versions[ix] - if len(version.Name) == 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("name", version, "name can not be empty")) - } - if versions.Has(version.Name) { - allErrs = append(allErrs, errs.NewFieldDuplicate("version", version)) - } - versions.Insert(version.Name) + if opts.LimitBytes != nil && *opts.LimitBytes < 1 { + allErrs = append(allErrs, errs.NewFieldInvalid("limitBytes", *opts.LimitBytes, "limitBytes must be a positive integer or nil")) } - return allErrs -} - -func ValidateSchemaUpdate(oldResource, newResource *api.ThirdPartyResource) errs.ValidationErrorList { - return errs.ValidationErrorList{fmt.Errorf("Schema update is not supported.")} -} - -func ValidateSecurityContextConstraints(scc *api.SecurityContextConstraints) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - allErrs = append(allErrs, ValidateObjectMeta(&scc.ObjectMeta, false, ValidateSecurityContextConstraintsName).Prefix("metadata")...) - - // ensure the user strat has a valid type - switch scc.RunAsUser.Type { - case api.RunAsUserStrategyMustRunAs, api.RunAsUserStrategyMustRunAsNonRoot, api.RunAsUserStrategyRunAsAny, api.RunAsUserStrategyMustRunAsRange: - //good types - default: - msg := fmt.Sprintf("invalid strategy type. Valid values are %s, %s, %s", api.RunAsUserStrategyMustRunAs, api.RunAsUserStrategyMustRunAsNonRoot, api.RunAsUserStrategyRunAsAny) - allErrs = append(allErrs, errs.NewFieldInvalid("runAsUser.type", scc.RunAsUser.Type, msg)) - } - - // if specified, uid cannot be negative - if scc.RunAsUser.UID != nil { - if *scc.RunAsUser.UID < 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("runAsUser.uid", *scc.RunAsUser.UID, "uid cannot be negative")) + switch { + case opts.SinceSeconds != nil && opts.SinceTime != nil: + allErrs = append(allErrs, errs.NewFieldInvalid("sinceSeconds", *opts.SinceSeconds, "only one of sinceTime or sinceSeconds can be provided")) + allErrs = append(allErrs, errs.NewFieldInvalid("sinceTime", *opts.SinceTime, "only one of sinceTime or sinceSeconds can be provided")) + case opts.SinceSeconds != nil: + if *opts.SinceSeconds < 1 { + allErrs = append(allErrs, errs.NewFieldInvalid("sinceSeconds", *opts.SinceSeconds, "sinceSeconds must be a positive integer")) } } - - // ensure the selinux strat has a valid type - switch scc.SELinuxContext.Type { - case api.SELinuxStrategyMustRunAs, api.SELinuxStrategyRunAsAny: - //good types - default: - msg := fmt.Sprintf("invalid strategy type. Valid values are %s, %s", api.SELinuxStrategyMustRunAs, api.SELinuxStrategyRunAsAny) - allErrs = append(allErrs, errs.NewFieldInvalid("seLinuxContext.type", scc.RunAsUser.Type, msg)) - } - - return allErrs -} - -func ValidateSecurityContextConstraintsUpdate(old *api.SecurityContextConstraints, new *api.SecurityContextConstraints) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - allErrs = append(allErrs, ValidateObjectMetaUpdate(&old.ObjectMeta, &new.ObjectMeta).Prefix("metadata")...) - allErrs = append(allErrs, ValidateSecurityContextConstraints(new)...) return allErrs } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go index 1f6d5c1b604f..426a02aa4abf 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go @@ -25,6 +25,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/capabilities" "k8s.io/kubernetes/pkg/util" utilerrors "k8s.io/kubernetes/pkg/util/errors" @@ -88,19 +89,19 @@ func TestValidateObjectMetaNamespaces(t *testing.T) { func TestValidateObjectMetaUpdateIgnoresCreationTimestamp(t *testing.T) { if errs := ValidateObjectMetaUpdate( &api.ObjectMeta{Name: "test", ResourceVersion: "1"}, - &api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: util.NewTime(time.Unix(10, 0))}, + &api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: unversioned.NewTime(time.Unix(10, 0))}, ); len(errs) != 0 { t.Fatalf("unexpected errors: %v", errs) } if errs := ValidateObjectMetaUpdate( - &api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: util.NewTime(time.Unix(10, 0))}, + &api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: unversioned.NewTime(time.Unix(10, 0))}, &api.ObjectMeta{Name: "test", ResourceVersion: "1"}, ); len(errs) != 0 { t.Fatalf("unexpected errors: %v", errs) } if errs := ValidateObjectMetaUpdate( - &api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: util.NewTime(time.Unix(10, 0))}, - &api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: util.NewTime(time.Unix(11, 0))}, + &api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: unversioned.NewTime(time.Unix(10, 0))}, + &api.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: unversioned.NewTime(time.Unix(11, 0))}, ); len(errs) != 0 { t.Fatalf("unexpected errors: %v", errs) } @@ -445,6 +446,7 @@ func TestValidatePersistentVolumeClaim(t *testing.T) { } func TestValidateVolumes(t *testing.T) { + lun := 1 successCase := []api.Volume{ {Name: "abc", VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{Path: "/mnt/path1"}}}, {Name: "123", VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{Path: "/mnt/path2"}}}, @@ -456,6 +458,7 @@ func TestValidateVolumes(t *testing.T) { {Name: "iscsidisk", VolumeSource: api.VolumeSource{ISCSI: &api.ISCSIVolumeSource{TargetPortal: "127.0.0.1", IQN: "iqn.2015-02.example.com:test", Lun: 1, FSType: "ext4", ReadOnly: false}}}, {Name: "secret", VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "my-secret"}}}, {Name: "glusterfs", VolumeSource: api.VolumeSource{Glusterfs: &api.GlusterfsVolumeSource{EndpointsName: "host1", Path: "path", ReadOnly: false}}}, + {Name: "flocker", VolumeSource: api.VolumeSource{Flocker: &api.FlockerVolumeSource{DatasetName: "datasetName"}}}, {Name: "rbd", VolumeSource: api.VolumeSource{RBD: &api.RBDVolumeSource{CephMonitors: []string{"foo"}, RBDImage: "bar", FSType: "ext4"}}}, {Name: "cinder", VolumeSource: api.VolumeSource{Cinder: &api.CinderVolumeSource{"29ea5088-4f60-4757-962e-dba678767887", "ext4", false}}}, {Name: "cephfs", VolumeSource: api.VolumeSource{CephFS: &api.CephFSVolumeSource{Monitors: []string{"foo"}}}}, @@ -485,12 +488,13 @@ func TestValidateVolumes(t *testing.T) { APIVersion: "v1", FieldPath: "metadata.labels"}}, }}}}, + {Name: "fc", VolumeSource: api.VolumeSource{FC: &api.FCVolumeSource{[]string{"some_wwn"}, &lun, "ext4", false}}}, } names, errs := validateVolumes(successCase) if len(errs) != 0 { t.Errorf("expected success: %v", errs) } - if len(names) != len(successCase) || !names.HasAll("abc", "123", "abc-123", "empty", "gcepd", "gitrepo", "secret", "iscsidisk", "cinder", "cephfs") { + if len(names) != len(successCase) || !names.HasAll("abc", "123", "abc-123", "empty", "gcepd", "gitrepo", "secret", "iscsidisk", "cinder", "cephfs", "fc") { t.Errorf("wrong names result: %v", names) } emptyVS := api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}} @@ -498,6 +502,7 @@ func TestValidateVolumes(t *testing.T) { emptyIQN := api.VolumeSource{ISCSI: &api.ISCSIVolumeSource{TargetPortal: "127.0.0.1", IQN: "", Lun: 1, FSType: "ext4", ReadOnly: false}} emptyHosts := api.VolumeSource{Glusterfs: &api.GlusterfsVolumeSource{EndpointsName: "", Path: "path", ReadOnly: false}} emptyPath := api.VolumeSource{Glusterfs: &api.GlusterfsVolumeSource{EndpointsName: "host", Path: "", ReadOnly: false}} + emptyName := api.VolumeSource{Flocker: &api.FlockerVolumeSource{DatasetName: ""}} emptyMon := api.VolumeSource{RBD: &api.RBDVolumeSource{CephMonitors: []string{}, RBDImage: "bar", FSType: "ext4"}} emptyImage := api.VolumeSource{RBD: &api.RBDVolumeSource{CephMonitors: []string{"foo"}, RBDImage: "", FSType: "ext4"}} emptyCephFSMon := api.VolumeSource{CephFS: &api.CephFSVolumeSource{Monitors: []string{}}} @@ -526,28 +531,35 @@ func TestValidateVolumes(t *testing.T) { APIVersion: "v1", FieldPath: "metadata.labels"}}}, }} + zeroWWN := api.VolumeSource{FC: &api.FCVolumeSource{[]string{}, &lun, "ext4", false}} + emptyLun := api.VolumeSource{FC: &api.FCVolumeSource{[]string{"wwn"}, nil, "ext4", false}} + slashInName := api.VolumeSource{Flocker: &api.FlockerVolumeSource{DatasetName: "foo/bar"}} errorCases := map[string]struct { V []api.Volume T errors.ValidationErrorType F string D string }{ - "zero-length name": {[]api.Volume{{Name: "", VolumeSource: emptyVS}}, errors.ValidationErrorTypeRequired, "[0].name", ""}, - "name > 63 characters": {[]api.Volume{{Name: strings.Repeat("a", 64), VolumeSource: emptyVS}}, errors.ValidationErrorTypeInvalid, "[0].name", "must be a DNS label (at most 63 characters, matching regex [a-z0-9]([-a-z0-9]*[a-z0-9])?): e.g. \"my-name\""}, - "name not a DNS label": {[]api.Volume{{Name: "a.b.c", VolumeSource: emptyVS}}, errors.ValidationErrorTypeInvalid, "[0].name", "must be a DNS label (at most 63 characters, matching regex [a-z0-9]([-a-z0-9]*[a-z0-9])?): e.g. \"my-name\""}, - "name not unique": {[]api.Volume{{Name: "abc", VolumeSource: emptyVS}, {Name: "abc", VolumeSource: emptyVS}}, errors.ValidationErrorTypeDuplicate, "[1].name", ""}, - "empty portal": {[]api.Volume{{Name: "badportal", VolumeSource: emptyPortal}}, errors.ValidationErrorTypeRequired, "[0].source.iscsi.targetPortal", ""}, - "empty iqn": {[]api.Volume{{Name: "badiqn", VolumeSource: emptyIQN}}, errors.ValidationErrorTypeRequired, "[0].source.iscsi.iqn", ""}, - "empty hosts": {[]api.Volume{{Name: "badhost", VolumeSource: emptyHosts}}, errors.ValidationErrorTypeRequired, "[0].source.glusterfs.endpoints", ""}, - "empty path": {[]api.Volume{{Name: "badpath", VolumeSource: emptyPath}}, errors.ValidationErrorTypeRequired, "[0].source.glusterfs.path", ""}, - "empty mon": {[]api.Volume{{Name: "badmon", VolumeSource: emptyMon}}, errors.ValidationErrorTypeRequired, "[0].source.rbd.monitors", ""}, - "empty image": {[]api.Volume{{Name: "badimage", VolumeSource: emptyImage}}, errors.ValidationErrorTypeRequired, "[0].source.rbd.image", ""}, - "empty cephfs mon": {[]api.Volume{{Name: "badmon", VolumeSource: emptyCephFSMon}}, errors.ValidationErrorTypeRequired, "[0].source.cephfs.monitors", ""}, - "empty metatada path": {[]api.Volume{{Name: "emptyname", VolumeSource: emptyPathName}}, errors.ValidationErrorTypeRequired, "[0].source.downwardApi.path", ""}, - "absolute path": {[]api.Volume{{Name: "absolutepath", VolumeSource: absolutePathName}}, errors.ValidationErrorTypeForbidden, "[0].source.downwardApi.path", ""}, - "dot dot path": {[]api.Volume{{Name: "dotdotpath", VolumeSource: dotDotInPath}}, errors.ValidationErrorTypeInvalid, "[0].source.downwardApi.path", "must not contain \"..\"."}, - "dot dot file name": {[]api.Volume{{Name: "dotdotfilename", VolumeSource: dotDotPathName}}, errors.ValidationErrorTypeInvalid, "[0].source.downwardApi.path", "must not start with \"..\"."}, - "dot dot first level dirent ": {[]api.Volume{{Name: "dotdotdirfilename", VolumeSource: dotDotFirstLevelDirent}}, errors.ValidationErrorTypeInvalid, "[0].source.downwardApi.path", "must not start with \"..\"."}, + "zero-length name": {[]api.Volume{{Name: "", VolumeSource: emptyVS}}, errors.ValidationErrorTypeRequired, "[0].name", ""}, + "name > 63 characters": {[]api.Volume{{Name: strings.Repeat("a", 64), VolumeSource: emptyVS}}, errors.ValidationErrorTypeInvalid, "[0].name", "must be a DNS label (at most 63 characters, matching regex [a-z0-9]([-a-z0-9]*[a-z0-9])?): e.g. \"my-name\""}, + "name not a DNS label": {[]api.Volume{{Name: "a.b.c", VolumeSource: emptyVS}}, errors.ValidationErrorTypeInvalid, "[0].name", "must be a DNS label (at most 63 characters, matching regex [a-z0-9]([-a-z0-9]*[a-z0-9])?): e.g. \"my-name\""}, + "name not unique": {[]api.Volume{{Name: "abc", VolumeSource: emptyVS}, {Name: "abc", VolumeSource: emptyVS}}, errors.ValidationErrorTypeDuplicate, "[1].name", ""}, + "empty portal": {[]api.Volume{{Name: "badportal", VolumeSource: emptyPortal}}, errors.ValidationErrorTypeRequired, "[0].source.iscsi.targetPortal", ""}, + "empty iqn": {[]api.Volume{{Name: "badiqn", VolumeSource: emptyIQN}}, errors.ValidationErrorTypeRequired, "[0].source.iscsi.iqn", ""}, + "empty hosts": {[]api.Volume{{Name: "badhost", VolumeSource: emptyHosts}}, errors.ValidationErrorTypeRequired, "[0].source.glusterfs.endpoints", ""}, + "empty path": {[]api.Volume{{Name: "badpath", VolumeSource: emptyPath}}, errors.ValidationErrorTypeRequired, "[0].source.glusterfs.path", ""}, + "empty datasetName": {[]api.Volume{{Name: "badname", VolumeSource: emptyName}}, errors.ValidationErrorTypeRequired, "[0].source.flocker.datasetName", ""}, + "empty mon": {[]api.Volume{{Name: "badmon", VolumeSource: emptyMon}}, errors.ValidationErrorTypeRequired, "[0].source.rbd.monitors", ""}, + "empty image": {[]api.Volume{{Name: "badimage", VolumeSource: emptyImage}}, errors.ValidationErrorTypeRequired, "[0].source.rbd.image", ""}, + "empty cephfs mon": {[]api.Volume{{Name: "badmon", VolumeSource: emptyCephFSMon}}, errors.ValidationErrorTypeRequired, "[0].source.cephfs.monitors", ""}, + "empty metatada path": {[]api.Volume{{Name: "emptyname", VolumeSource: emptyPathName}}, errors.ValidationErrorTypeRequired, "[0].source.downwardApi.path", ""}, + "absolute path": {[]api.Volume{{Name: "absolutepath", VolumeSource: absolutePathName}}, errors.ValidationErrorTypeForbidden, "[0].source.downwardApi.path", ""}, + "dot dot path": {[]api.Volume{{Name: "dotdotpath", VolumeSource: dotDotInPath}}, errors.ValidationErrorTypeInvalid, "[0].source.downwardApi.path", "must not contain \"..\"."}, + "dot dot file name": {[]api.Volume{{Name: "dotdotfilename", VolumeSource: dotDotPathName}}, errors.ValidationErrorTypeInvalid, "[0].source.downwardApi.path", "must not start with \"..\"."}, + "dot dot first level dirent": {[]api.Volume{{Name: "dotdotdirfilename", VolumeSource: dotDotFirstLevelDirent}}, errors.ValidationErrorTypeInvalid, "[0].source.downwardApi.path", "must not start with \"..\"."}, + "empty wwn": {[]api.Volume{{Name: "badimage", VolumeSource: zeroWWN}}, errors.ValidationErrorTypeRequired, "[0].source.fc.targetWWNs", ""}, + "empty lun": {[]api.Volume{{Name: "badimage", VolumeSource: emptyLun}}, errors.ValidationErrorTypeRequired, "[0].source.fc.lun", ""}, + "slash in datasetName": {[]api.Volume{{Name: "slashinname", VolumeSource: slashInName}}, errors.ValidationErrorTypeInvalid, "[0].source.flocker.datasetName", "must not contain '/'"}, } for k, v := range errorCases { _, errs := validateVolumes(v.V) @@ -1247,20 +1259,25 @@ func TestValidatePodSpec(t *testing.T) { {HostPort: 8080, ContainerPort: 8080, Protocol: "TCP"}}, }, }, - HostNetwork: true, - HostIPC: true, + SecurityContext: &api.PodSecurityContext{ + HostNetwork: true, + }, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, { // Populate HostIPC. - HostIPC: true, + SecurityContext: &api.PodSecurityContext{ + HostIPC: true, + }, Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}}, Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, { // Populate HostPID. - HostPID: true, + SecurityContext: &api.PodSecurityContext{ + HostPID: true, + }, Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}}, Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, RestartPolicy: api.RestartPolicyAlways, @@ -1312,7 +1329,9 @@ func TestValidatePodSpec(t *testing.T) { {HostPort: 8080, ContainerPort: 2600, Protocol: "TCP"}}, }, }, - HostNetwork: true, + SecurityContext: &api.PodSecurityContext{ + HostNetwork: true, + }, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, @@ -1416,12 +1435,9 @@ func TestValidatePod(t *testing.T) { } func TestValidatePodUpdate(t *testing.T) { - now := util.Now() + now := unversioned.Now() grace := int64(30) grace2 := int64(31) - activeDeadlineSecondsZero := int64(0) - activeDeadlineSecondsNegative := int64(-30) - activeDeadlineSecondsPositive := int64(30) tests := []struct { a api.Pod b api.Pod @@ -1508,46 +1524,6 @@ func TestValidatePodUpdate(t *testing.T) { false, "more containers", }, - { - api.Pod{ - Spec: api.PodSpec{ - ActiveDeadlineSeconds: &activeDeadlineSecondsZero, - }, - }, - api.Pod{}, - false, - "activedeadlineseconds change to 0", - }, - { - api.Pod{ - Spec: api.PodSpec{ - ActiveDeadlineSeconds: &activeDeadlineSecondsPositive, - }, - }, - api.Pod{}, - true, - "activedeadlineseconds change to positive", - }, - { - api.Pod{ - Spec: api.PodSpec{ - ActiveDeadlineSeconds: &activeDeadlineSecondsNegative, - }, - }, - api.Pod{}, - false, - "activedeadlineseconds change to negative", - }, - { - api.Pod{ - Spec: api.PodSpec{ - ActiveDeadlineSeconds: &activeDeadlineSecondsPositive, - }, - }, - api.Pod{}, - true, - "activedeadlineseconds change back to nil", - }, { api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", DeletionTimestamp: &now}, @@ -2125,6 +2101,89 @@ func TestValidateService(t *testing.T) { } } +func TestValidateReplicationControllerStatusUpdate(t *testing.T) { + validSelector := map[string]string{"a": "b"} + validPodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: validSelector, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + }, + }, + } + type rcUpdateTest struct { + old api.ReplicationController + update api.ReplicationController + } + successCases := []rcUpdateTest{ + { + old: api.ReplicationController{ + ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, + Spec: api.ReplicationControllerSpec{ + Selector: validSelector, + Template: &validPodTemplate.Template, + }, + Status: api.ReplicationControllerStatus{ + Replicas: 2, + }, + }, + update: api.ReplicationController{ + ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, + Spec: api.ReplicationControllerSpec{ + Replicas: 3, + Selector: validSelector, + Template: &validPodTemplate.Template, + }, + Status: api.ReplicationControllerStatus{ + Replicas: 4, + }, + }, + }, + } + for _, successCase := range successCases { + successCase.old.ObjectMeta.ResourceVersion = "1" + successCase.update.ObjectMeta.ResourceVersion = "1" + if errs := ValidateReplicationControllerStatusUpdate(&successCase.old, &successCase.update); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + errorCases := map[string]rcUpdateTest{ + "negative replicas": { + old: api.ReplicationController{ + ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault}, + Spec: api.ReplicationControllerSpec{ + Selector: validSelector, + Template: &validPodTemplate.Template, + }, + Status: api.ReplicationControllerStatus{ + Replicas: 3, + }, + }, + update: api.ReplicationController{ + ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, + Spec: api.ReplicationControllerSpec{ + Replicas: 2, + Selector: validSelector, + Template: &validPodTemplate.Template, + }, + Status: api.ReplicationControllerStatus{ + Replicas: -3, + }, + }, + }, + } + for testName, errorCase := range errorCases { + if errs := ValidateReplicationControllerStatusUpdate(&errorCase.old, &errorCase.update); len(errs) == 0 { + t.Errorf("expected failure: %s", testName) + } + } + +} + func TestValidateReplicationControllerUpdate(t *testing.T) { validSelector := map[string]string{"a": "b"} validPodTemplate := api.PodTemplate{ @@ -2499,7 +2558,8 @@ func TestValidateReplicationController(t *testing.T) { field != "spec.replicas" && field != "spec.template.labels" && field != "metadata.annotations" && - field != "metadata.labels" { + field != "metadata.labels" && + field != "status.replicas" { t.Errorf("%s: missing prefix for: %v", k, errs[i]) } } @@ -3120,6 +3180,30 @@ func TestValidateLimitRange(t *testing.T) { }}, "default request value 800m is greater than default limit value 500m", }, + "invalid spec maxLimitRequestRatio less than 1": { + api.LimitRange{ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: "foo"}, Spec: api.LimitRangeSpec{ + Limits: []api.LimitRangeItem{ + { + Type: api.LimitTypePod, + MaxLimitRequestRatio: getResourceList("800m", ""), + }, + }, + }}, + "maxLimitRequestRatio 800m is less than 1", + }, + "invalid spec maxLimitRequestRatio greater than max/min": { + api.LimitRange{ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: "foo"}, Spec: api.LimitRangeSpec{ + Limits: []api.LimitRangeItem{ + { + Type: api.LimitTypeContainer, + Max: getResourceList("", "2Gi"), + Min: getResourceList("", "512Mi"), + MaxLimitRequestRatio: getResourceList("", "10"), + }, + }, + }}, + "maxLimitRequestRatio 10 is greater than max/min = 4.000000", + }, } for k, v := range errorCases { @@ -3143,12 +3227,23 @@ func TestValidateResourceQuota(t *testing.T) { api.ResourceCPU: resource.MustParse("100"), api.ResourceMemory: resource.MustParse("10000"), api.ResourcePods: resource.MustParse("10"), - api.ResourceServices: resource.MustParse("10"), + api.ResourceServices: resource.MustParse("0"), api.ResourceReplicationControllers: resource.MustParse("10"), api.ResourceQuotas: resource.MustParse("10"), }, } + negativeSpec := api.ResourceQuotaSpec{ + Hard: api.ResourceList{ + api.ResourceCPU: resource.MustParse("-100"), + api.ResourceMemory: resource.MustParse("-10000"), + api.ResourcePods: resource.MustParse("-10"), + api.ResourceServices: resource.MustParse("-10"), + api.ResourceReplicationControllers: resource.MustParse("-10"), + api.ResourceQuotas: resource.MustParse("-10"), + }, + } + successCases := []api.ResourceQuota{ { ObjectMeta: api.ObjectMeta{ @@ -3185,6 +3280,10 @@ func TestValidateResourceQuota(t *testing.T) { api.ResourceQuota{ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: "^Invalid"}, Spec: spec}, DNS1123LabelErrorMsg, }, + "negative-limits": { + api.ResourceQuota{ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: "foo"}, Spec: negativeSpec}, + isNegativeErrorMsg, + }, } for k, v := range errorCases { errs := ValidateResourceQuota(&v.R) @@ -3194,7 +3293,7 @@ func TestValidateResourceQuota(t *testing.T) { for i := range errs { field := errs[i].(*errors.ValidationError).Field detail := errs[i].(*errors.ValidationError).Detail - if field != "metadata.name" && field != "metadata.namespace" { + if field != "metadata.name" && field != "metadata.namespace" && !api.IsStandardResourceName(field) { t.Errorf("%s: missing prefix for: %v", k, field) } if detail != v.D { @@ -3309,7 +3408,7 @@ func TestValidateNamespaceFinalizeUpdate(t *testing.T) { } func TestValidateNamespaceStatusUpdate(t *testing.T) { - now := util.Now() + now := unversioned.Now() tests := []struct { oldNamespace api.Namespace @@ -3892,135 +3991,33 @@ func fakeValidSecurityContext(priv bool) *api.SecurityContext { } } -func TestValidateSecurityContextConstraints(t *testing.T) { - var invalidUID int64 = -1 - errorCases := map[string]struct { - scc *api.SecurityContextConstraints - errorType fielderrors.ValidationErrorType - errorDetail string - }{ - "no user options": { - scc: &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyMustRunAs, - }, - }, - errorType: errors.ValidationErrorTypeInvalid, - errorDetail: "invalid strategy type. Valid values are MustRunAs, MustRunAsNonRoot, RunAsAny", - }, - "no selinux options": { - scc: &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - RunAsUser: api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyMustRunAs, - }, - }, - errorType: errors.ValidationErrorTypeInvalid, - errorDetail: "invalid strategy type. Valid values are MustRunAs, RunAsAny", - }, - "invalid user strategy type": { - scc: &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - RunAsUser: api.RunAsUserStrategyOptions{ - Type: "invalid", - }, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyMustRunAs, - }, - }, - errorType: errors.ValidationErrorTypeInvalid, - errorDetail: "invalid strategy type. Valid values are MustRunAs, MustRunAsNonRoot, RunAsAny", - }, - "invalid selinux strategy type": { - scc: &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - RunAsUser: api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyMustRunAs, - }, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: "invalid", - }, - }, - errorType: errors.ValidationErrorTypeInvalid, - errorDetail: "invalid strategy type. Valid values are MustRunAs, RunAsAny", - }, - "invalid uid": { - scc: &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - RunAsUser: api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyMustRunAs, - UID: &invalidUID, - }, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyMustRunAs, - }, - }, - errorType: errors.ValidationErrorTypeInvalid, - errorDetail: "uid cannot be negative", - }, - "missing object meta name": { - scc: &api.SecurityContextConstraints{ - RunAsUser: api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyMustRunAs, - }, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyMustRunAs, - }, - }, - errorType: errors.ValidationErrorTypeRequired, - }, - } - - for k, v := range errorCases { - if errs := ValidateSecurityContextConstraints(v.scc); len(errs) == 0 || errs[0].(*errors.ValidationError).Type != v.errorType || errs[0].(*errors.ValidationError).Detail != v.errorDetail { - t.Errorf("Expected error type %s with detail %s for %s, got %v", v.errorType, v.errorDetail, k, errs) - } - } - - var validUID int64 = 1 - successCases := map[string]struct { - scc *api.SecurityContextConstraints +func TestValidPodLogOptions(t *testing.T) { + now := unversioned.Now() + negative := int64(-1) + zero := int64(0) + positive := int64(1) + tests := []struct { + opt api.PodLogOptions + errs int }{ - "must run as": { - scc: &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - RunAsUser: api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyMustRunAs, - UID: &validUID, - }, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyMustRunAs, - }, - }, - }, - "run as any": { - scc: &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - RunAsUser: api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyRunAsAny, - }, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyRunAsAny, - }, - }, - }, - "run as non-root (user only)": { - scc: &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - RunAsUser: api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyMustRunAsNonRoot, - }, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyRunAsAny, - }, - }, - }, + {api.PodLogOptions{}, 0}, + {api.PodLogOptions{Previous: true}, 0}, + {api.PodLogOptions{Follow: true}, 0}, + {api.PodLogOptions{TailLines: &zero}, 0}, + {api.PodLogOptions{TailLines: &negative}, 1}, + {api.PodLogOptions{TailLines: &positive}, 0}, + {api.PodLogOptions{LimitBytes: &zero}, 1}, + {api.PodLogOptions{LimitBytes: &negative}, 1}, + {api.PodLogOptions{LimitBytes: &positive}, 0}, + {api.PodLogOptions{SinceSeconds: &negative}, 1}, + {api.PodLogOptions{SinceSeconds: &positive}, 0}, + {api.PodLogOptions{SinceSeconds: &zero}, 1}, + {api.PodLogOptions{SinceTime: &now}, 0}, } - - for k, v := range successCases { - if errs := ValidateSecurityContextConstraints(v.scc); len(errs) != 0 { - t.Errorf("Expected success for %s, got %v", k, errs) + for i, test := range tests { + errs := ValidatePodLogOptions(&test.opt) + if test.errs != len(errs) { + t.Errorf("%d: Unexpected errors: %v", i, errs) } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/latest/latest.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/latest/latest.go deleted file mode 100644 index d276211a5e59..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/latest/latest.go +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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 latest - -import ( - "fmt" - "strings" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/meta" - _ "k8s.io/kubernetes/pkg/apis/experimental" - "k8s.io/kubernetes/pkg/apis/experimental/v1" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util/sets" -) - -var ( - Version string - Versions []string - - accessor = meta.NewAccessor() - Codec runtime.Codec - SelfLinker = runtime.SelfLinker(accessor) - RESTMapper meta.RESTMapper -) - -const importPrefix = "k8s.io/kubernetes/pkg/apis/experimental" - -func init() { - // hardcode these values to be correct for now. The next rebase completely changes how these are registered - Version = "v1" - Versions = []string{"v1"} - - Codec = runtime.CodecFor(api.Scheme, Version) - - // the list of kinds that are scoped at the root of the api hierarchy - // if a kind is not enumerated here, it is assumed to have a namespace scope - rootScoped := sets.NewString() - - ignoredKinds := sets.NewString() - - RESTMapper = api.NewDefaultRESTMapper("experimental", Versions, InterfacesFor, importPrefix, ignoredKinds, rootScoped) - api.RegisterRESTMapper(RESTMapper) -} - -// InterfacesFor returns the default Codec and ResourceVersioner for a given version -// string, or an error if the version is not known. -func InterfacesFor(version string) (*meta.VersionInterfaces, error) { - switch version { - case "v1": - return &meta.VersionInterfaces{ - Codec: v1.Codec, - ObjectConvertor: api.Scheme, - MetadataAccessor: accessor, - }, nil - default: - return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(Versions, ", ")) - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/testapi/testapi.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/testapi/testapi.go deleted file mode 100644 index 229a1bf04ac0..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/testapi/testapi.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 testapi - -import ( - "strings" - - "k8s.io/kubernetes/pkg/apis/experimental/latest" -) - -// Returns the appropriate path for the given prefix (watch, proxy, redirect, etc), resource, namespace and name. -// For example, this is of the form: -// /experimental/v1/watch/namespaces/foo/pods/pod0 for v1. -func ResourcePathWithPrefix(prefix, resource, namespace, name string) string { - path := "/experimental/" + latest.Version - if prefix != "" { - path = path + "/" + prefix - } - if namespace != "" { - path = path + "/namespaces/" + namespace - } - // Resource names are lower case. - resource = strings.ToLower(resource) - if resource != "" { - path = path + "/" + resource - } - if name != "" { - path = path + "/" + name - } - return path -} - -// Returns the appropriate path for the given resource, namespace and name. -// For example, this is of the form: -// /experimental/v1/namespaces/foo/pods/pod0 for v1. -func ResourcePath(resource, namespace, name string) string { - return ResourcePathWithPrefix("", resource, namespace, name) -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/conversion_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/conversion_generated.go deleted file mode 100644 index 2035113a1a95..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/conversion_generated.go +++ /dev/null @@ -1,2494 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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. -*/ - -// DO NOT EDIT. THIS FILE IS AUTO-GENERATED BY $KUBEROOT/hack/update-generated-conversions.sh - -package v1 - -import ( - reflect "reflect" - - api "k8s.io/kubernetes/pkg/api" - resource "k8s.io/kubernetes/pkg/api/resource" - v1 "k8s.io/kubernetes/pkg/api/v1" - experimental "k8s.io/kubernetes/pkg/apis/experimental" - conversion "k8s.io/kubernetes/pkg/conversion" -) - -func convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in *api.AWSElasticBlockStoreVolumeSource, out *v1.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.AWSElasticBlockStoreVolumeSource))(in) - } - out.VolumeID = in.VolumeID - out.FSType = in.FSType - out.Partition = in.Partition - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_Capabilities_To_v1_Capabilities(in *api.Capabilities, out *v1.Capabilities, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Capabilities))(in) - } - if in.Add != nil { - out.Add = make([]v1.Capability, len(in.Add)) - for i := range in.Add { - out.Add[i] = v1.Capability(in.Add[i]) - } - } else { - out.Add = nil - } - if in.Drop != nil { - out.Drop = make([]v1.Capability, len(in.Drop)) - for i := range in.Drop { - out.Drop[i] = v1.Capability(in.Drop[i]) - } - } else { - out.Drop = nil - } - return nil -} - -func convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in *api.CephFSVolumeSource, out *v1.CephFSVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.CephFSVolumeSource))(in) - } - if in.Monitors != nil { - out.Monitors = make([]string, len(in.Monitors)) - for i := range in.Monitors { - out.Monitors[i] = in.Monitors[i] - } - } else { - out.Monitors = nil - } - out.User = in.User - out.SecretFile = in.SecretFile - if in.SecretRef != nil { - out.SecretRef = new(v1.LocalObjectReference) - if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { - return err - } - } else { - out.SecretRef = nil - } - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in *api.CinderVolumeSource, out *v1.CinderVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.CinderVolumeSource))(in) - } - out.VolumeID = in.VolumeID - out.FSType = in.FSType - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_Container_To_v1_Container(in *api.Container, out *v1.Container, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Container))(in) - } - out.Name = in.Name - out.Image = in.Image - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } else { - out.Command = nil - } - if in.Args != nil { - out.Args = make([]string, len(in.Args)) - for i := range in.Args { - out.Args[i] = in.Args[i] - } - } else { - out.Args = nil - } - out.WorkingDir = in.WorkingDir - if in.Ports != nil { - out.Ports = make([]v1.ContainerPort, len(in.Ports)) - for i := range in.Ports { - if err := convert_api_ContainerPort_To_v1_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { - return err - } - } - } else { - out.Ports = nil - } - if in.Env != nil { - out.Env = make([]v1.EnvVar, len(in.Env)) - for i := range in.Env { - if err := convert_api_EnvVar_To_v1_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { - return err - } - } - } else { - out.Env = nil - } - if err := convert_api_ResourceRequirements_To_v1_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { - return err - } - if in.VolumeMounts != nil { - out.VolumeMounts = make([]v1.VolumeMount, len(in.VolumeMounts)) - for i := range in.VolumeMounts { - if err := convert_api_VolumeMount_To_v1_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { - return err - } - } - } else { - out.VolumeMounts = nil - } - if in.LivenessProbe != nil { - out.LivenessProbe = new(v1.Probe) - if err := convert_api_Probe_To_v1_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { - return err - } - } else { - out.LivenessProbe = nil - } - if in.ReadinessProbe != nil { - out.ReadinessProbe = new(v1.Probe) - if err := convert_api_Probe_To_v1_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { - return err - } - } else { - out.ReadinessProbe = nil - } - if in.Lifecycle != nil { - out.Lifecycle = new(v1.Lifecycle) - if err := convert_api_Lifecycle_To_v1_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { - return err - } - } else { - out.Lifecycle = nil - } - out.TerminationMessagePath = in.TerminationMessagePath - out.ImagePullPolicy = v1.PullPolicy(in.ImagePullPolicy) - if in.SecurityContext != nil { - out.SecurityContext = new(v1.SecurityContext) - if err := convert_api_SecurityContext_To_v1_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { - return err - } - } else { - out.SecurityContext = nil - } - out.Stdin = in.Stdin - out.TTY = in.TTY - return nil -} - -func convert_api_ContainerPort_To_v1_ContainerPort(in *api.ContainerPort, out *v1.ContainerPort, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ContainerPort))(in) - } - out.Name = in.Name - out.HostPort = in.HostPort - out.ContainerPort = in.ContainerPort - out.Protocol = v1.Protocol(in.Protocol) - out.HostIP = in.HostIP - return nil -} - -func convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in *api.DownwardAPIVolumeFile, out *v1.DownwardAPIVolumeFile, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.DownwardAPIVolumeFile))(in) - } - out.Path = in.Path - if err := convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { - return err - } - return nil -} - -func convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in *api.DownwardAPIVolumeSource, out *v1.DownwardAPIVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.DownwardAPIVolumeSource))(in) - } - if in.Items != nil { - out.Items = make([]v1.DownwardAPIVolumeFile, len(in.Items)) - for i := range in.Items { - if err := convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in *api.EmptyDirVolumeSource, out *v1.EmptyDirVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EmptyDirVolumeSource))(in) - } - out.Medium = v1.StorageMedium(in.Medium) - return nil -} - -func convert_api_EnvVar_To_v1_EnvVar(in *api.EnvVar, out *v1.EnvVar, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EnvVar))(in) - } - out.Name = in.Name - out.Value = in.Value - if in.ValueFrom != nil { - out.ValueFrom = new(v1.EnvVarSource) - if err := convert_api_EnvVarSource_To_v1_EnvVarSource(in.ValueFrom, out.ValueFrom, s); err != nil { - return err - } - } else { - out.ValueFrom = nil - } - return nil -} - -func convert_api_EnvVarSource_To_v1_EnvVarSource(in *api.EnvVarSource, out *v1.EnvVarSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.EnvVarSource))(in) - } - if in.FieldRef != nil { - out.FieldRef = new(v1.ObjectFieldSelector) - if err := convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in.FieldRef, out.FieldRef, s); err != nil { - return err - } - } else { - out.FieldRef = nil - } - return nil -} - -func convert_api_ExecAction_To_v1_ExecAction(in *api.ExecAction, out *v1.ExecAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ExecAction))(in) - } - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } else { - out.Command = nil - } - return nil -} - -func convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in *api.GCEPersistentDiskVolumeSource, out *v1.GCEPersistentDiskVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.GCEPersistentDiskVolumeSource))(in) - } - out.PDName = in.PDName - out.FSType = in.FSType - out.Partition = in.Partition - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in *api.GitRepoVolumeSource, out *v1.GitRepoVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.GitRepoVolumeSource))(in) - } - out.Repository = in.Repository - out.Revision = in.Revision - return nil -} - -func convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in *api.GlusterfsVolumeSource, out *v1.GlusterfsVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.GlusterfsVolumeSource))(in) - } - out.EndpointsName = in.EndpointsName - out.Path = in.Path - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, out *v1.HTTPGetAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.HTTPGetAction))(in) - } - out.Path = in.Path - if err := s.Convert(&in.Port, &out.Port, 0); err != nil { - return err - } - out.Host = in.Host - out.Scheme = v1.URIScheme(in.Scheme) - return nil -} - -func convert_api_Handler_To_v1_Handler(in *api.Handler, out *v1.Handler, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Handler))(in) - } - if in.Exec != nil { - out.Exec = new(v1.ExecAction) - if err := convert_api_ExecAction_To_v1_ExecAction(in.Exec, out.Exec, s); err != nil { - return err - } - } else { - out.Exec = nil - } - if in.HTTPGet != nil { - out.HTTPGet = new(v1.HTTPGetAction) - if err := convert_api_HTTPGetAction_To_v1_HTTPGetAction(in.HTTPGet, out.HTTPGet, s); err != nil { - return err - } - } else { - out.HTTPGet = nil - } - if in.TCPSocket != nil { - out.TCPSocket = new(v1.TCPSocketAction) - if err := convert_api_TCPSocketAction_To_v1_TCPSocketAction(in.TCPSocket, out.TCPSocket, s); err != nil { - return err - } - } else { - out.TCPSocket = nil - } - return nil -} - -func convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in *api.HostPathVolumeSource, out *v1.HostPathVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.HostPathVolumeSource))(in) - } - out.Path = in.Path - return nil -} - -func convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in *api.ISCSIVolumeSource, out *v1.ISCSIVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ISCSIVolumeSource))(in) - } - out.TargetPortal = in.TargetPortal - out.IQN = in.IQN - out.Lun = in.Lun - out.FSType = in.FSType - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_Lifecycle_To_v1_Lifecycle(in *api.Lifecycle, out *v1.Lifecycle, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Lifecycle))(in) - } - if in.PostStart != nil { - out.PostStart = new(v1.Handler) - if err := convert_api_Handler_To_v1_Handler(in.PostStart, out.PostStart, s); err != nil { - return err - } - } else { - out.PostStart = nil - } - if in.PreStop != nil { - out.PreStop = new(v1.Handler) - if err := convert_api_Handler_To_v1_Handler(in.PreStop, out.PreStop, s); err != nil { - return err - } - } else { - out.PreStop = nil - } - return nil -} - -func convert_api_ListMeta_To_v1_ListMeta(in *api.ListMeta, out *v1.ListMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ListMeta))(in) - } - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil -} - -func convert_api_LocalObjectReference_To_v1_LocalObjectReference(in *api.LocalObjectReference, out *v1.LocalObjectReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.LocalObjectReference))(in) - } - out.Name = in.Name - return nil -} - -func convert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in *api.NFSVolumeSource, out *v1.NFSVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.NFSVolumeSource))(in) - } - out.Server = in.Server - out.Path = in.Path - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *api.ObjectFieldSelector, out *v1.ObjectFieldSelector, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ObjectFieldSelector))(in) - } - out.APIVersion = in.APIVersion - out.FieldPath = in.FieldPath - return nil -} - -func convert_api_ObjectMeta_To_v1_ObjectMeta(in *api.ObjectMeta, out *v1.ObjectMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ObjectMeta))(in) - } - out.Name = in.Name - out.GenerateName = in.GenerateName - out.Namespace = in.Namespace - out.SelfLink = in.SelfLink - out.UID = in.UID - out.ResourceVersion = in.ResourceVersion - out.Generation = in.Generation - if err := s.Convert(&in.CreationTimestamp, &out.CreationTimestamp, 0); err != nil { - return err - } - if in.DeletionTimestamp != nil { - if err := s.Convert(&in.DeletionTimestamp, &out.DeletionTimestamp, 0); err != nil { - return err - } - } else { - out.DeletionTimestamp = nil - } - if in.DeletionGracePeriodSeconds != nil { - out.DeletionGracePeriodSeconds = new(int64) - *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds - } else { - out.DeletionGracePeriodSeconds = nil - } - if in.Labels != nil { - out.Labels = make(map[string]string) - for key, val := range in.Labels { - out.Labels[key] = val - } - } else { - out.Labels = nil - } - if in.Annotations != nil { - out.Annotations = make(map[string]string) - for key, val := range in.Annotations { - out.Annotations[key] = val - } - } else { - out.Annotations = nil - } - return nil -} - -func convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in *api.PersistentVolumeClaimVolumeSource, out *v1.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PersistentVolumeClaimVolumeSource))(in) - } - out.ClaimName = in.ClaimName - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *v1.PodTemplateSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.PodTemplateSpec))(in) - } - if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_api_PodSpec_To_v1_PodSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - return nil -} - -func convert_api_Probe_To_v1_Probe(in *api.Probe, out *v1.Probe, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Probe))(in) - } - if err := convert_api_Handler_To_v1_Handler(&in.Handler, &out.Handler, s); err != nil { - return err - } - out.InitialDelaySeconds = in.InitialDelaySeconds - out.TimeoutSeconds = in.TimeoutSeconds - return nil -} - -func convert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in *api.RBDVolumeSource, out *v1.RBDVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.RBDVolumeSource))(in) - } - if in.CephMonitors != nil { - out.CephMonitors = make([]string, len(in.CephMonitors)) - for i := range in.CephMonitors { - out.CephMonitors[i] = in.CephMonitors[i] - } - } else { - out.CephMonitors = nil - } - out.RBDImage = in.RBDImage - out.FSType = in.FSType - out.RBDPool = in.RBDPool - out.RadosUser = in.RadosUser - out.Keyring = in.Keyring - if in.SecretRef != nil { - out.SecretRef = new(v1.LocalObjectReference) - if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { - return err - } - } else { - out.SecretRef = nil - } - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_api_ResourceRequirements_To_v1_ResourceRequirements(in *api.ResourceRequirements, out *v1.ResourceRequirements, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.ResourceRequirements))(in) - } - if in.Limits != nil { - out.Limits = make(v1.ResourceList) - for key, val := range in.Limits { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Limits[v1.ResourceName(key)] = newVal - } - } else { - out.Limits = nil - } - if in.Requests != nil { - out.Requests = make(v1.ResourceList) - for key, val := range in.Requests { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Requests[v1.ResourceName(key)] = newVal - } - } else { - out.Requests = nil - } - return nil -} - -func convert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, out *v1.SELinuxOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SELinuxOptions))(in) - } - out.User = in.User - out.Role = in.Role - out.Type = in.Type - out.Level = in.Level - return nil -} - -func convert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretVolumeSource, out *v1.SecretVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SecretVolumeSource))(in) - } - out.SecretName = in.SecretName - return nil -} - -func convert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityContext, out *v1.SecurityContext, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.SecurityContext))(in) - } - if in.Capabilities != nil { - out.Capabilities = new(v1.Capabilities) - if err := convert_api_Capabilities_To_v1_Capabilities(in.Capabilities, out.Capabilities, s); err != nil { - return err - } - } else { - out.Capabilities = nil - } - if in.Privileged != nil { - out.Privileged = new(bool) - *out.Privileged = *in.Privileged - } else { - out.Privileged = nil - } - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(v1.SELinuxOptions) - if err := convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - if in.RunAsUser != nil { - out.RunAsUser = new(int64) - *out.RunAsUser = *in.RunAsUser - } else { - out.RunAsUser = nil - } - out.RunAsNonRoot = in.RunAsNonRoot - return nil -} - -func convert_api_TCPSocketAction_To_v1_TCPSocketAction(in *api.TCPSocketAction, out *v1.TCPSocketAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.TCPSocketAction))(in) - } - if err := s.Convert(&in.Port, &out.Port, 0); err != nil { - return err - } - return nil -} - -func convert_api_TypeMeta_To_v1_TypeMeta(in *api.TypeMeta, out *v1.TypeMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.TypeMeta))(in) - } - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil -} - -func convert_api_Volume_To_v1_Volume(in *api.Volume, out *v1.Volume, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.Volume))(in) - } - out.Name = in.Name - if err := convert_api_VolumeSource_To_v1_VolumeSource(&in.VolumeSource, &out.VolumeSource, s); err != nil { - return err - } - return nil -} - -func convert_api_VolumeMount_To_v1_VolumeMount(in *api.VolumeMount, out *v1.VolumeMount, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.VolumeMount))(in) - } - out.Name = in.Name - out.ReadOnly = in.ReadOnly - out.MountPath = in.MountPath - return nil -} - -func convert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in *v1.AWSElasticBlockStoreVolumeSource, out *api.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.AWSElasticBlockStoreVolumeSource))(in) - } - out.VolumeID = in.VolumeID - out.FSType = in.FSType - out.Partition = in.Partition - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1_Capabilities_To_api_Capabilities(in *v1.Capabilities, out *api.Capabilities, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.Capabilities))(in) - } - if in.Add != nil { - out.Add = make([]api.Capability, len(in.Add)) - for i := range in.Add { - out.Add[i] = api.Capability(in.Add[i]) - } - } else { - out.Add = nil - } - if in.Drop != nil { - out.Drop = make([]api.Capability, len(in.Drop)) - for i := range in.Drop { - out.Drop[i] = api.Capability(in.Drop[i]) - } - } else { - out.Drop = nil - } - return nil -} - -func convert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in *v1.CephFSVolumeSource, out *api.CephFSVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.CephFSVolumeSource))(in) - } - if in.Monitors != nil { - out.Monitors = make([]string, len(in.Monitors)) - for i := range in.Monitors { - out.Monitors[i] = in.Monitors[i] - } - } else { - out.Monitors = nil - } - out.User = in.User - out.SecretFile = in.SecretFile - if in.SecretRef != nil { - out.SecretRef = new(api.LocalObjectReference) - if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { - return err - } - } else { - out.SecretRef = nil - } - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in *v1.CinderVolumeSource, out *api.CinderVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.CinderVolumeSource))(in) - } - out.VolumeID = in.VolumeID - out.FSType = in.FSType - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1_Container_To_api_Container(in *v1.Container, out *api.Container, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.Container))(in) - } - out.Name = in.Name - out.Image = in.Image - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } else { - out.Command = nil - } - if in.Args != nil { - out.Args = make([]string, len(in.Args)) - for i := range in.Args { - out.Args[i] = in.Args[i] - } - } else { - out.Args = nil - } - out.WorkingDir = in.WorkingDir - if in.Ports != nil { - out.Ports = make([]api.ContainerPort, len(in.Ports)) - for i := range in.Ports { - if err := convert_v1_ContainerPort_To_api_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { - return err - } - } - } else { - out.Ports = nil - } - if in.Env != nil { - out.Env = make([]api.EnvVar, len(in.Env)) - for i := range in.Env { - if err := convert_v1_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { - return err - } - } - } else { - out.Env = nil - } - if err := convert_v1_ResourceRequirements_To_api_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { - return err - } - if in.VolumeMounts != nil { - out.VolumeMounts = make([]api.VolumeMount, len(in.VolumeMounts)) - for i := range in.VolumeMounts { - if err := convert_v1_VolumeMount_To_api_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { - return err - } - } - } else { - out.VolumeMounts = nil - } - if in.LivenessProbe != nil { - out.LivenessProbe = new(api.Probe) - if err := convert_v1_Probe_To_api_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { - return err - } - } else { - out.LivenessProbe = nil - } - if in.ReadinessProbe != nil { - out.ReadinessProbe = new(api.Probe) - if err := convert_v1_Probe_To_api_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { - return err - } - } else { - out.ReadinessProbe = nil - } - if in.Lifecycle != nil { - out.Lifecycle = new(api.Lifecycle) - if err := convert_v1_Lifecycle_To_api_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { - return err - } - } else { - out.Lifecycle = nil - } - out.TerminationMessagePath = in.TerminationMessagePath - out.ImagePullPolicy = api.PullPolicy(in.ImagePullPolicy) - if in.SecurityContext != nil { - out.SecurityContext = new(api.SecurityContext) - if err := convert_v1_SecurityContext_To_api_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { - return err - } - } else { - out.SecurityContext = nil - } - out.Stdin = in.Stdin - out.TTY = in.TTY - return nil -} - -func convert_v1_ContainerPort_To_api_ContainerPort(in *v1.ContainerPort, out *api.ContainerPort, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.ContainerPort))(in) - } - out.Name = in.Name - out.HostPort = in.HostPort - out.ContainerPort = in.ContainerPort - out.Protocol = api.Protocol(in.Protocol) - out.HostIP = in.HostIP - return nil -} - -func convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *v1.DownwardAPIVolumeFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.DownwardAPIVolumeFile))(in) - } - out.Path = in.Path - if err := convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { - return err - } - return nil -} - -func convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *v1.DownwardAPIVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.DownwardAPIVolumeSource))(in) - } - if in.Items != nil { - out.Items = make([]api.DownwardAPIVolumeFile, len(in.Items)) - for i := range in.Items { - if err := convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in *v1.EmptyDirVolumeSource, out *api.EmptyDirVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.EmptyDirVolumeSource))(in) - } - out.Medium = api.StorageMedium(in.Medium) - return nil -} - -func convert_v1_EnvVar_To_api_EnvVar(in *v1.EnvVar, out *api.EnvVar, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.EnvVar))(in) - } - out.Name = in.Name - out.Value = in.Value - if in.ValueFrom != nil { - out.ValueFrom = new(api.EnvVarSource) - if err := convert_v1_EnvVarSource_To_api_EnvVarSource(in.ValueFrom, out.ValueFrom, s); err != nil { - return err - } - } else { - out.ValueFrom = nil - } - return nil -} - -func convert_v1_EnvVarSource_To_api_EnvVarSource(in *v1.EnvVarSource, out *api.EnvVarSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.EnvVarSource))(in) - } - if in.FieldRef != nil { - out.FieldRef = new(api.ObjectFieldSelector) - if err := convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in.FieldRef, out.FieldRef, s); err != nil { - return err - } - } else { - out.FieldRef = nil - } - return nil -} - -func convert_v1_ExecAction_To_api_ExecAction(in *v1.ExecAction, out *api.ExecAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.ExecAction))(in) - } - if in.Command != nil { - out.Command = make([]string, len(in.Command)) - for i := range in.Command { - out.Command[i] = in.Command[i] - } - } else { - out.Command = nil - } - return nil -} - -func convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in *v1.GCEPersistentDiskVolumeSource, out *api.GCEPersistentDiskVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.GCEPersistentDiskVolumeSource))(in) - } - out.PDName = in.PDName - out.FSType = in.FSType - out.Partition = in.Partition - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in *v1.GitRepoVolumeSource, out *api.GitRepoVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.GitRepoVolumeSource))(in) - } - out.Repository = in.Repository - out.Revision = in.Revision - return nil -} - -func convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in *v1.GlusterfsVolumeSource, out *api.GlusterfsVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.GlusterfsVolumeSource))(in) - } - out.EndpointsName = in.EndpointsName - out.Path = in.Path - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1_HTTPGetAction_To_api_HTTPGetAction(in *v1.HTTPGetAction, out *api.HTTPGetAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.HTTPGetAction))(in) - } - out.Path = in.Path - if err := s.Convert(&in.Port, &out.Port, 0); err != nil { - return err - } - out.Host = in.Host - out.Scheme = api.URIScheme(in.Scheme) - return nil -} - -func convert_v1_Handler_To_api_Handler(in *v1.Handler, out *api.Handler, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.Handler))(in) - } - if in.Exec != nil { - out.Exec = new(api.ExecAction) - if err := convert_v1_ExecAction_To_api_ExecAction(in.Exec, out.Exec, s); err != nil { - return err - } - } else { - out.Exec = nil - } - if in.HTTPGet != nil { - out.HTTPGet = new(api.HTTPGetAction) - if err := convert_v1_HTTPGetAction_To_api_HTTPGetAction(in.HTTPGet, out.HTTPGet, s); err != nil { - return err - } - } else { - out.HTTPGet = nil - } - if in.TCPSocket != nil { - out.TCPSocket = new(api.TCPSocketAction) - if err := convert_v1_TCPSocketAction_To_api_TCPSocketAction(in.TCPSocket, out.TCPSocket, s); err != nil { - return err - } - } else { - out.TCPSocket = nil - } - return nil -} - -func convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in *v1.HostPathVolumeSource, out *api.HostPathVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.HostPathVolumeSource))(in) - } - out.Path = in.Path - return nil -} - -func convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in *v1.ISCSIVolumeSource, out *api.ISCSIVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.ISCSIVolumeSource))(in) - } - out.TargetPortal = in.TargetPortal - out.IQN = in.IQN - out.Lun = in.Lun - out.FSType = in.FSType - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1_Lifecycle_To_api_Lifecycle(in *v1.Lifecycle, out *api.Lifecycle, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.Lifecycle))(in) - } - if in.PostStart != nil { - out.PostStart = new(api.Handler) - if err := convert_v1_Handler_To_api_Handler(in.PostStart, out.PostStart, s); err != nil { - return err - } - } else { - out.PostStart = nil - } - if in.PreStop != nil { - out.PreStop = new(api.Handler) - if err := convert_v1_Handler_To_api_Handler(in.PreStop, out.PreStop, s); err != nil { - return err - } - } else { - out.PreStop = nil - } - return nil -} - -func convert_v1_ListMeta_To_api_ListMeta(in *v1.ListMeta, out *api.ListMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.ListMeta))(in) - } - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil -} - -func convert_v1_LocalObjectReference_To_api_LocalObjectReference(in *v1.LocalObjectReference, out *api.LocalObjectReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.LocalObjectReference))(in) - } - out.Name = in.Name - return nil -} - -func convert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in *v1.NFSVolumeSource, out *api.NFSVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.NFSVolumeSource))(in) - } - out.Server = in.Server - out.Path = in.Path - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *v1.ObjectFieldSelector, out *api.ObjectFieldSelector, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.ObjectFieldSelector))(in) - } - out.APIVersion = in.APIVersion - out.FieldPath = in.FieldPath - return nil -} - -func convert_v1_ObjectMeta_To_api_ObjectMeta(in *v1.ObjectMeta, out *api.ObjectMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.ObjectMeta))(in) - } - out.Name = in.Name - out.GenerateName = in.GenerateName - out.Namespace = in.Namespace - out.SelfLink = in.SelfLink - out.UID = in.UID - out.ResourceVersion = in.ResourceVersion - out.Generation = in.Generation - if err := s.Convert(&in.CreationTimestamp, &out.CreationTimestamp, 0); err != nil { - return err - } - if in.DeletionTimestamp != nil { - if err := s.Convert(&in.DeletionTimestamp, &out.DeletionTimestamp, 0); err != nil { - return err - } - } else { - out.DeletionTimestamp = nil - } - if in.DeletionGracePeriodSeconds != nil { - out.DeletionGracePeriodSeconds = new(int64) - *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds - } else { - out.DeletionGracePeriodSeconds = nil - } - if in.Labels != nil { - out.Labels = make(map[string]string) - for key, val := range in.Labels { - out.Labels[key] = val - } - } else { - out.Labels = nil - } - if in.Annotations != nil { - out.Annotations = make(map[string]string) - for key, val := range in.Annotations { - out.Annotations[key] = val - } - } else { - out.Annotations = nil - } - return nil -} - -func convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in *v1.PersistentVolumeClaimVolumeSource, out *api.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.PersistentVolumeClaimVolumeSource))(in) - } - out.ClaimName = in.ClaimName - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *v1.PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.PodTemplateSpec))(in) - } - if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1_PodSpec_To_api_PodSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - return nil -} - -func convert_v1_Probe_To_api_Probe(in *v1.Probe, out *api.Probe, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.Probe))(in) - } - if err := convert_v1_Handler_To_api_Handler(&in.Handler, &out.Handler, s); err != nil { - return err - } - out.InitialDelaySeconds = in.InitialDelaySeconds - out.TimeoutSeconds = in.TimeoutSeconds - return nil -} - -func convert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in *v1.RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.RBDVolumeSource))(in) - } - if in.CephMonitors != nil { - out.CephMonitors = make([]string, len(in.CephMonitors)) - for i := range in.CephMonitors { - out.CephMonitors[i] = in.CephMonitors[i] - } - } else { - out.CephMonitors = nil - } - out.RBDImage = in.RBDImage - out.FSType = in.FSType - out.RBDPool = in.RBDPool - out.RadosUser = in.RadosUser - out.Keyring = in.Keyring - if in.SecretRef != nil { - out.SecretRef = new(api.LocalObjectReference) - if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { - return err - } - } else { - out.SecretRef = nil - } - out.ReadOnly = in.ReadOnly - return nil -} - -func convert_v1_ResourceRequirements_To_api_ResourceRequirements(in *v1.ResourceRequirements, out *api.ResourceRequirements, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.ResourceRequirements))(in) - } - if in.Limits != nil { - out.Limits = make(api.ResourceList) - for key, val := range in.Limits { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Limits[api.ResourceName(key)] = newVal - } - } else { - out.Limits = nil - } - if in.Requests != nil { - out.Requests = make(api.ResourceList) - for key, val := range in.Requests { - newVal := resource.Quantity{} - if err := s.Convert(&val, &newVal, 0); err != nil { - return err - } - out.Requests[api.ResourceName(key)] = newVal - } - } else { - out.Requests = nil - } - return nil -} - -func convert_v1_SELinuxOptions_To_api_SELinuxOptions(in *v1.SELinuxOptions, out *api.SELinuxOptions, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.SELinuxOptions))(in) - } - out.User = in.User - out.Role = in.Role - out.Type = in.Type - out.Level = in.Level - return nil -} - -func convert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *v1.SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.SecretVolumeSource))(in) - } - out.SecretName = in.SecretName - return nil -} - -func convert_v1_SecurityContext_To_api_SecurityContext(in *v1.SecurityContext, out *api.SecurityContext, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.SecurityContext))(in) - } - if in.Capabilities != nil { - out.Capabilities = new(api.Capabilities) - if err := convert_v1_Capabilities_To_api_Capabilities(in.Capabilities, out.Capabilities, s); err != nil { - return err - } - } else { - out.Capabilities = nil - } - if in.Privileged != nil { - out.Privileged = new(bool) - *out.Privileged = *in.Privileged - } else { - out.Privileged = nil - } - if in.SELinuxOptions != nil { - out.SELinuxOptions = new(api.SELinuxOptions) - if err := convert_v1_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { - return err - } - } else { - out.SELinuxOptions = nil - } - if in.RunAsUser != nil { - out.RunAsUser = new(int64) - *out.RunAsUser = *in.RunAsUser - } else { - out.RunAsUser = nil - } - out.RunAsNonRoot = in.RunAsNonRoot - return nil -} - -func convert_v1_TCPSocketAction_To_api_TCPSocketAction(in *v1.TCPSocketAction, out *api.TCPSocketAction, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.TCPSocketAction))(in) - } - if err := s.Convert(&in.Port, &out.Port, 0); err != nil { - return err - } - return nil -} - -func convert_v1_TypeMeta_To_api_TypeMeta(in *v1.TypeMeta, out *api.TypeMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.TypeMeta))(in) - } - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil -} - -func convert_v1_Volume_To_api_Volume(in *v1.Volume, out *api.Volume, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.Volume))(in) - } - out.Name = in.Name - if err := convert_v1_VolumeSource_To_api_VolumeSource(&in.VolumeSource, &out.VolumeSource, s); err != nil { - return err - } - return nil -} - -func convert_v1_VolumeMount_To_api_VolumeMount(in *v1.VolumeMount, out *api.VolumeMount, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.VolumeMount))(in) - } - out.Name = in.Name - out.ReadOnly = in.ReadOnly - out.MountPath = in.MountPath - return nil -} - -func convert_experimental_APIVersion_To_v1_APIVersion(in *experimental.APIVersion, out *APIVersion, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.APIVersion))(in) - } - out.Name = in.Name - out.APIGroup = in.APIGroup - return nil -} - -func convert_experimental_DaemonSet_To_v1_DaemonSet(in *experimental.DaemonSet, out *DaemonSet, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.DaemonSet))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_experimental_DaemonSetSpec_To_v1_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_experimental_DaemonSetStatus_To_v1_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_experimental_DaemonSetList_To_v1_DaemonSetList(in *experimental.DaemonSetList, out *DaemonSetList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.DaemonSetList))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]DaemonSet, len(in.Items)) - for i := range in.Items { - if err := convert_experimental_DaemonSet_To_v1_DaemonSet(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_experimental_DaemonSetSpec_To_v1_DaemonSetSpec(in *experimental.DaemonSetSpec, out *DaemonSetSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.DaemonSetSpec))(in) - } - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - if in.Template != nil { - out.Template = new(v1.PodTemplateSpec) - if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil - } - return nil -} - -func convert_experimental_DaemonSetStatus_To_v1_DaemonSetStatus(in *experimental.DaemonSetStatus, out *DaemonSetStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.DaemonSetStatus))(in) - } - out.CurrentNumberScheduled = in.CurrentNumberScheduled - out.NumberMisscheduled = in.NumberMisscheduled - out.DesiredNumberScheduled = in.DesiredNumberScheduled - return nil -} - -func convert_experimental_Deployment_To_v1_Deployment(in *experimental.Deployment, out *Deployment, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.Deployment))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_experimental_DeploymentSpec_To_v1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_experimental_DeploymentStatus_To_v1_DeploymentStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_experimental_DeploymentList_To_v1_DeploymentList(in *experimental.DeploymentList, out *DeploymentList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.DeploymentList))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Deployment, len(in.Items)) - for i := range in.Items { - if err := convert_experimental_Deployment_To_v1_Deployment(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_experimental_DeploymentStatus_To_v1_DeploymentStatus(in *experimental.DeploymentStatus, out *DeploymentStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.DeploymentStatus))(in) - } - out.Replicas = in.Replicas - out.UpdatedReplicas = in.UpdatedReplicas - return nil -} - -func convert_experimental_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(in *experimental.HorizontalPodAutoscaler, out *HorizontalPodAutoscaler, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.HorizontalPodAutoscaler))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_experimental_HorizontalPodAutoscalerSpec_To_v1_HorizontalPodAutoscalerSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if in.Status != nil { - out.Status = new(HorizontalPodAutoscalerStatus) - if err := convert_experimental_HorizontalPodAutoscalerStatus_To_v1_HorizontalPodAutoscalerStatus(in.Status, out.Status, s); err != nil { - return err - } - } else { - out.Status = nil - } - return nil -} - -func convert_experimental_HorizontalPodAutoscalerList_To_v1_HorizontalPodAutoscalerList(in *experimental.HorizontalPodAutoscalerList, out *HorizontalPodAutoscalerList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.HorizontalPodAutoscalerList))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]HorizontalPodAutoscaler, len(in.Items)) - for i := range in.Items { - if err := convert_experimental_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_experimental_HorizontalPodAutoscalerSpec_To_v1_HorizontalPodAutoscalerSpec(in *experimental.HorizontalPodAutoscalerSpec, out *HorizontalPodAutoscalerSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.HorizontalPodAutoscalerSpec))(in) - } - if in.ScaleRef != nil { - out.ScaleRef = new(SubresourceReference) - if err := convert_experimental_SubresourceReference_To_v1_SubresourceReference(in.ScaleRef, out.ScaleRef, s); err != nil { - return err - } - } else { - out.ScaleRef = nil - } - out.MinCount = in.MinCount - out.MaxCount = in.MaxCount - if err := convert_experimental_ResourceConsumption_To_v1_ResourceConsumption(&in.Target, &out.Target, s); err != nil { - return err - } - return nil -} - -func convert_experimental_HorizontalPodAutoscalerStatus_To_v1_HorizontalPodAutoscalerStatus(in *experimental.HorizontalPodAutoscalerStatus, out *HorizontalPodAutoscalerStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.HorizontalPodAutoscalerStatus))(in) - } - out.CurrentReplicas = in.CurrentReplicas - out.DesiredReplicas = in.DesiredReplicas - if in.CurrentConsumption != nil { - out.CurrentConsumption = new(ResourceConsumption) - if err := convert_experimental_ResourceConsumption_To_v1_ResourceConsumption(in.CurrentConsumption, out.CurrentConsumption, s); err != nil { - return err - } - } else { - out.CurrentConsumption = nil - } - if in.LastScaleTimestamp != nil { - if err := s.Convert(&in.LastScaleTimestamp, &out.LastScaleTimestamp, 0); err != nil { - return err - } - } else { - out.LastScaleTimestamp = nil - } - return nil -} - -func convert_experimental_Job_To_v1_Job(in *experimental.Job, out *Job, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.Job))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_experimental_JobSpec_To_v1_JobSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_experimental_JobStatus_To_v1_JobStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_experimental_JobCondition_To_v1_JobCondition(in *experimental.JobCondition, out *JobCondition, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.JobCondition))(in) - } - out.Type = JobConditionType(in.Type) - out.Status = v1.ConditionStatus(in.Status) - if err := s.Convert(&in.LastProbeTime, &out.LastProbeTime, 0); err != nil { - return err - } - if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { - return err - } - out.Reason = in.Reason - out.Message = in.Message - return nil -} - -func convert_experimental_JobList_To_v1_JobList(in *experimental.JobList, out *JobList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.JobList))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]Job, len(in.Items)) - for i := range in.Items { - if err := convert_experimental_Job_To_v1_Job(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_experimental_JobSpec_To_v1_JobSpec(in *experimental.JobSpec, out *JobSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.JobSpec))(in) - } - if in.Parallelism != nil { - out.Parallelism = new(int) - *out.Parallelism = *in.Parallelism - } else { - out.Parallelism = nil - } - if in.Completions != nil { - out.Completions = new(int) - *out.Completions = *in.Completions - } else { - out.Completions = nil - } - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - if in.Template != nil { - out.Template = new(v1.PodTemplateSpec) - if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil - } - return nil -} - -func convert_experimental_JobStatus_To_v1_JobStatus(in *experimental.JobStatus, out *JobStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.JobStatus))(in) - } - if in.Conditions != nil { - out.Conditions = make([]JobCondition, len(in.Conditions)) - for i := range in.Conditions { - if err := convert_experimental_JobCondition_To_v1_JobCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { - return err - } - } - } else { - out.Conditions = nil - } - if in.StartTime != nil { - if err := s.Convert(&in.StartTime, &out.StartTime, 0); err != nil { - return err - } - } else { - out.StartTime = nil - } - if in.CompletionTime != nil { - if err := s.Convert(&in.CompletionTime, &out.CompletionTime, 0); err != nil { - return err - } - } else { - out.CompletionTime = nil - } - out.Active = in.Active - out.Successful = in.Successful - out.Unsuccessful = in.Unsuccessful - return nil -} - -func convert_experimental_ReplicationControllerDummy_To_v1_ReplicationControllerDummy(in *experimental.ReplicationControllerDummy, out *ReplicationControllerDummy, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.ReplicationControllerDummy))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - return nil -} - -func convert_experimental_ResourceConsumption_To_v1_ResourceConsumption(in *experimental.ResourceConsumption, out *ResourceConsumption, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.ResourceConsumption))(in) - } - out.Resource = v1.ResourceName(in.Resource) - if err := s.Convert(&in.Quantity, &out.Quantity, 0); err != nil { - return err - } - return nil -} - -func convert_experimental_Scale_To_v1_Scale(in *experimental.Scale, out *Scale, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.Scale))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_experimental_ScaleSpec_To_v1_ScaleSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_experimental_ScaleStatus_To_v1_ScaleStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_experimental_ScaleSpec_To_v1_ScaleSpec(in *experimental.ScaleSpec, out *ScaleSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.ScaleSpec))(in) - } - out.Replicas = in.Replicas - return nil -} - -func convert_experimental_ScaleStatus_To_v1_ScaleStatus(in *experimental.ScaleStatus, out *ScaleStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.ScaleStatus))(in) - } - out.Replicas = in.Replicas - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - return nil -} - -func convert_experimental_SubresourceReference_To_v1_SubresourceReference(in *experimental.SubresourceReference, out *SubresourceReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.SubresourceReference))(in) - } - out.Kind = in.Kind - out.Namespace = in.Namespace - out.Name = in.Name - out.APIVersion = in.APIVersion - out.Subresource = in.Subresource - return nil -} - -func convert_experimental_ThirdPartyResource_To_v1_ThirdPartyResource(in *experimental.ThirdPartyResource, out *ThirdPartyResource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.ThirdPartyResource))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - out.Description = in.Description - if in.Versions != nil { - out.Versions = make([]APIVersion, len(in.Versions)) - for i := range in.Versions { - if err := convert_experimental_APIVersion_To_v1_APIVersion(&in.Versions[i], &out.Versions[i], s); err != nil { - return err - } - } - } else { - out.Versions = nil - } - return nil -} - -func convert_experimental_ThirdPartyResourceData_To_v1_ThirdPartyResourceData(in *experimental.ThirdPartyResourceData, out *ThirdPartyResourceData, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.ThirdPartyResourceData))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := s.Convert(&in.Data, &out.Data, 0); err != nil { - return err - } - return nil -} - -func convert_experimental_ThirdPartyResourceDataList_To_v1_ThirdPartyResourceDataList(in *experimental.ThirdPartyResourceDataList, out *ThirdPartyResourceDataList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.ThirdPartyResourceDataList))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]ThirdPartyResourceData, len(in.Items)) - for i := range in.Items { - if err := convert_experimental_ThirdPartyResourceData_To_v1_ThirdPartyResourceData(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_experimental_ThirdPartyResourceList_To_v1_ThirdPartyResourceList(in *experimental.ThirdPartyResourceList, out *ThirdPartyResourceList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.ThirdPartyResourceList))(in) - } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]ThirdPartyResource, len(in.Items)) - for i := range in.Items { - if err := convert_experimental_ThirdPartyResource_To_v1_ThirdPartyResource(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1_APIVersion_To_experimental_APIVersion(in *APIVersion, out *experimental.APIVersion, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*APIVersion))(in) - } - out.Name = in.Name - out.APIGroup = in.APIGroup - return nil -} - -func convert_v1_DaemonSet_To_experimental_DaemonSet(in *DaemonSet, out *experimental.DaemonSet, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*DaemonSet))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1_DaemonSetSpec_To_experimental_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1_DaemonSetStatus_To_experimental_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1_DaemonSetList_To_experimental_DaemonSetList(in *DaemonSetList, out *experimental.DaemonSetList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*DaemonSetList))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]experimental.DaemonSet, len(in.Items)) - for i := range in.Items { - if err := convert_v1_DaemonSet_To_experimental_DaemonSet(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1_DaemonSetSpec_To_experimental_DaemonSetSpec(in *DaemonSetSpec, out *experimental.DaemonSetSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*DaemonSetSpec))(in) - } - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - if in.Template != nil { - out.Template = new(api.PodTemplateSpec) - if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil - } - return nil -} - -func convert_v1_DaemonSetStatus_To_experimental_DaemonSetStatus(in *DaemonSetStatus, out *experimental.DaemonSetStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*DaemonSetStatus))(in) - } - out.CurrentNumberScheduled = in.CurrentNumberScheduled - out.NumberMisscheduled = in.NumberMisscheduled - out.DesiredNumberScheduled = in.DesiredNumberScheduled - return nil -} - -func convert_v1_Deployment_To_experimental_Deployment(in *Deployment, out *experimental.Deployment, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Deployment))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1_DeploymentSpec_To_experimental_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1_DeploymentStatus_To_experimental_DeploymentStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1_DeploymentList_To_experimental_DeploymentList(in *DeploymentList, out *experimental.DeploymentList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*DeploymentList))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]experimental.Deployment, len(in.Items)) - for i := range in.Items { - if err := convert_v1_Deployment_To_experimental_Deployment(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1_DeploymentStatus_To_experimental_DeploymentStatus(in *DeploymentStatus, out *experimental.DeploymentStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*DeploymentStatus))(in) - } - out.Replicas = in.Replicas - out.UpdatedReplicas = in.UpdatedReplicas - return nil -} - -func convert_v1_HorizontalPodAutoscaler_To_experimental_HorizontalPodAutoscaler(in *HorizontalPodAutoscaler, out *experimental.HorizontalPodAutoscaler, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*HorizontalPodAutoscaler))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1_HorizontalPodAutoscalerSpec_To_experimental_HorizontalPodAutoscalerSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if in.Status != nil { - out.Status = new(experimental.HorizontalPodAutoscalerStatus) - if err := convert_v1_HorizontalPodAutoscalerStatus_To_experimental_HorizontalPodAutoscalerStatus(in.Status, out.Status, s); err != nil { - return err - } - } else { - out.Status = nil - } - return nil -} - -func convert_v1_HorizontalPodAutoscalerList_To_experimental_HorizontalPodAutoscalerList(in *HorizontalPodAutoscalerList, out *experimental.HorizontalPodAutoscalerList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*HorizontalPodAutoscalerList))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]experimental.HorizontalPodAutoscaler, len(in.Items)) - for i := range in.Items { - if err := convert_v1_HorizontalPodAutoscaler_To_experimental_HorizontalPodAutoscaler(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1_HorizontalPodAutoscalerSpec_To_experimental_HorizontalPodAutoscalerSpec(in *HorizontalPodAutoscalerSpec, out *experimental.HorizontalPodAutoscalerSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*HorizontalPodAutoscalerSpec))(in) - } - if in.ScaleRef != nil { - out.ScaleRef = new(experimental.SubresourceReference) - if err := convert_v1_SubresourceReference_To_experimental_SubresourceReference(in.ScaleRef, out.ScaleRef, s); err != nil { - return err - } - } else { - out.ScaleRef = nil - } - out.MinCount = in.MinCount - out.MaxCount = in.MaxCount - if err := convert_v1_ResourceConsumption_To_experimental_ResourceConsumption(&in.Target, &out.Target, s); err != nil { - return err - } - return nil -} - -func convert_v1_HorizontalPodAutoscalerStatus_To_experimental_HorizontalPodAutoscalerStatus(in *HorizontalPodAutoscalerStatus, out *experimental.HorizontalPodAutoscalerStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*HorizontalPodAutoscalerStatus))(in) - } - out.CurrentReplicas = in.CurrentReplicas - out.DesiredReplicas = in.DesiredReplicas - if in.CurrentConsumption != nil { - out.CurrentConsumption = new(experimental.ResourceConsumption) - if err := convert_v1_ResourceConsumption_To_experimental_ResourceConsumption(in.CurrentConsumption, out.CurrentConsumption, s); err != nil { - return err - } - } else { - out.CurrentConsumption = nil - } - if in.LastScaleTimestamp != nil { - if err := s.Convert(&in.LastScaleTimestamp, &out.LastScaleTimestamp, 0); err != nil { - return err - } - } else { - out.LastScaleTimestamp = nil - } - return nil -} - -func convert_v1_Job_To_experimental_Job(in *Job, out *experimental.Job, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Job))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1_JobSpec_To_experimental_JobSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1_JobStatus_To_experimental_JobStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1_JobCondition_To_experimental_JobCondition(in *JobCondition, out *experimental.JobCondition, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*JobCondition))(in) - } - out.Type = experimental.JobConditionType(in.Type) - out.Status = api.ConditionStatus(in.Status) - if err := s.Convert(&in.LastProbeTime, &out.LastProbeTime, 0); err != nil { - return err - } - if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { - return err - } - out.Reason = in.Reason - out.Message = in.Message - return nil -} - -func convert_v1_JobList_To_experimental_JobList(in *JobList, out *experimental.JobList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*JobList))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]experimental.Job, len(in.Items)) - for i := range in.Items { - if err := convert_v1_Job_To_experimental_Job(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1_JobSpec_To_experimental_JobSpec(in *JobSpec, out *experimental.JobSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*JobSpec))(in) - } - if in.Parallelism != nil { - out.Parallelism = new(int) - *out.Parallelism = *in.Parallelism - } else { - out.Parallelism = nil - } - if in.Completions != nil { - out.Completions = new(int) - *out.Completions = *in.Completions - } else { - out.Completions = nil - } - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - if in.Template != nil { - out.Template = new(api.PodTemplateSpec) - if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil - } - return nil -} - -func convert_v1_JobStatus_To_experimental_JobStatus(in *JobStatus, out *experimental.JobStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*JobStatus))(in) - } - if in.Conditions != nil { - out.Conditions = make([]experimental.JobCondition, len(in.Conditions)) - for i := range in.Conditions { - if err := convert_v1_JobCondition_To_experimental_JobCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { - return err - } - } - } else { - out.Conditions = nil - } - if in.StartTime != nil { - if err := s.Convert(&in.StartTime, &out.StartTime, 0); err != nil { - return err - } - } else { - out.StartTime = nil - } - if in.CompletionTime != nil { - if err := s.Convert(&in.CompletionTime, &out.CompletionTime, 0); err != nil { - return err - } - } else { - out.CompletionTime = nil - } - out.Active = in.Active - out.Successful = in.Successful - out.Unsuccessful = in.Unsuccessful - return nil -} - -func convert_v1_ReplicationControllerDummy_To_experimental_ReplicationControllerDummy(in *ReplicationControllerDummy, out *experimental.ReplicationControllerDummy, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ReplicationControllerDummy))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - return nil -} - -func convert_v1_ResourceConsumption_To_experimental_ResourceConsumption(in *ResourceConsumption, out *experimental.ResourceConsumption, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ResourceConsumption))(in) - } - out.Resource = api.ResourceName(in.Resource) - if err := s.Convert(&in.Quantity, &out.Quantity, 0); err != nil { - return err - } - return nil -} - -func convert_v1_Scale_To_experimental_Scale(in *Scale, out *experimental.Scale, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*Scale))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := convert_v1_ScaleSpec_To_experimental_ScaleSpec(&in.Spec, &out.Spec, s); err != nil { - return err - } - if err := convert_v1_ScaleStatus_To_experimental_ScaleStatus(&in.Status, &out.Status, s); err != nil { - return err - } - return nil -} - -func convert_v1_ScaleSpec_To_experimental_ScaleSpec(in *ScaleSpec, out *experimental.ScaleSpec, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ScaleSpec))(in) - } - out.Replicas = in.Replicas - return nil -} - -func convert_v1_ScaleStatus_To_experimental_ScaleStatus(in *ScaleStatus, out *experimental.ScaleStatus, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ScaleStatus))(in) - } - out.Replicas = in.Replicas - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } - return nil -} - -func convert_v1_SubresourceReference_To_experimental_SubresourceReference(in *SubresourceReference, out *experimental.SubresourceReference, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SubresourceReference))(in) - } - out.Kind = in.Kind - out.Namespace = in.Namespace - out.Name = in.Name - out.APIVersion = in.APIVersion - out.Subresource = in.Subresource - return nil -} - -func convert_v1_ThirdPartyResource_To_experimental_ThirdPartyResource(in *ThirdPartyResource, out *experimental.ThirdPartyResource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ThirdPartyResource))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - out.Description = in.Description - if in.Versions != nil { - out.Versions = make([]experimental.APIVersion, len(in.Versions)) - for i := range in.Versions { - if err := convert_v1_APIVersion_To_experimental_APIVersion(&in.Versions[i], &out.Versions[i], s); err != nil { - return err - } - } - } else { - out.Versions = nil - } - return nil -} - -func convert_v1_ThirdPartyResourceData_To_experimental_ThirdPartyResourceData(in *ThirdPartyResourceData, out *experimental.ThirdPartyResourceData, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ThirdPartyResourceData))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { - return err - } - if err := s.Convert(&in.Data, &out.Data, 0); err != nil { - return err - } - return nil -} - -func convert_v1_ThirdPartyResourceDataList_To_experimental_ThirdPartyResourceDataList(in *ThirdPartyResourceDataList, out *experimental.ThirdPartyResourceDataList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ThirdPartyResourceDataList))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]experimental.ThirdPartyResourceData, len(in.Items)) - for i := range in.Items { - if err := convert_v1_ThirdPartyResourceData_To_experimental_ThirdPartyResourceData(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func convert_v1_ThirdPartyResourceList_To_experimental_ThirdPartyResourceList(in *ThirdPartyResourceList, out *experimental.ThirdPartyResourceList, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*ThirdPartyResourceList))(in) - } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { - return err - } - if in.Items != nil { - out.Items = make([]experimental.ThirdPartyResource, len(in.Items)) - for i := range in.Items { - if err := convert_v1_ThirdPartyResource_To_experimental_ThirdPartyResource(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } else { - out.Items = nil - } - return nil -} - -func init() { - err := api.Scheme.AddGeneratedConversionFuncs( - convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource, - convert_api_Capabilities_To_v1_Capabilities, - convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource, - convert_api_CinderVolumeSource_To_v1_CinderVolumeSource, - convert_api_ContainerPort_To_v1_ContainerPort, - convert_api_Container_To_v1_Container, - convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile, - convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource, - convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource, - convert_api_EnvVarSource_To_v1_EnvVarSource, - convert_api_EnvVar_To_v1_EnvVar, - convert_api_ExecAction_To_v1_ExecAction, - convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource, - convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource, - convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource, - convert_api_HTTPGetAction_To_v1_HTTPGetAction, - convert_api_Handler_To_v1_Handler, - convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource, - convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource, - convert_api_Lifecycle_To_v1_Lifecycle, - convert_api_ListMeta_To_v1_ListMeta, - convert_api_LocalObjectReference_To_v1_LocalObjectReference, - convert_api_NFSVolumeSource_To_v1_NFSVolumeSource, - convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector, - convert_api_ObjectMeta_To_v1_ObjectMeta, - convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource, - convert_api_PodTemplateSpec_To_v1_PodTemplateSpec, - convert_api_Probe_To_v1_Probe, - convert_api_RBDVolumeSource_To_v1_RBDVolumeSource, - convert_api_ResourceRequirements_To_v1_ResourceRequirements, - convert_api_SELinuxOptions_To_v1_SELinuxOptions, - convert_api_SecretVolumeSource_To_v1_SecretVolumeSource, - convert_api_SecurityContext_To_v1_SecurityContext, - convert_api_TCPSocketAction_To_v1_TCPSocketAction, - convert_api_TypeMeta_To_v1_TypeMeta, - convert_api_VolumeMount_To_v1_VolumeMount, - convert_api_Volume_To_v1_Volume, - convert_experimental_APIVersion_To_v1_APIVersion, - convert_experimental_DaemonSetList_To_v1_DaemonSetList, - convert_experimental_DaemonSetSpec_To_v1_DaemonSetSpec, - convert_experimental_DaemonSetStatus_To_v1_DaemonSetStatus, - convert_experimental_DaemonSet_To_v1_DaemonSet, - convert_experimental_DeploymentList_To_v1_DeploymentList, - convert_experimental_DeploymentStatus_To_v1_DeploymentStatus, - convert_experimental_Deployment_To_v1_Deployment, - convert_experimental_HorizontalPodAutoscalerList_To_v1_HorizontalPodAutoscalerList, - convert_experimental_HorizontalPodAutoscalerSpec_To_v1_HorizontalPodAutoscalerSpec, - convert_experimental_HorizontalPodAutoscalerStatus_To_v1_HorizontalPodAutoscalerStatus, - convert_experimental_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler, - convert_experimental_JobCondition_To_v1_JobCondition, - convert_experimental_JobList_To_v1_JobList, - convert_experimental_JobSpec_To_v1_JobSpec, - convert_experimental_JobStatus_To_v1_JobStatus, - convert_experimental_Job_To_v1_Job, - convert_experimental_ReplicationControllerDummy_To_v1_ReplicationControllerDummy, - convert_experimental_ResourceConsumption_To_v1_ResourceConsumption, - convert_experimental_ScaleSpec_To_v1_ScaleSpec, - convert_experimental_ScaleStatus_To_v1_ScaleStatus, - convert_experimental_Scale_To_v1_Scale, - convert_experimental_SubresourceReference_To_v1_SubresourceReference, - convert_experimental_ThirdPartyResourceDataList_To_v1_ThirdPartyResourceDataList, - convert_experimental_ThirdPartyResourceData_To_v1_ThirdPartyResourceData, - convert_experimental_ThirdPartyResourceList_To_v1_ThirdPartyResourceList, - convert_experimental_ThirdPartyResource_To_v1_ThirdPartyResource, - convert_v1_APIVersion_To_experimental_APIVersion, - convert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource, - convert_v1_Capabilities_To_api_Capabilities, - convert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource, - convert_v1_CinderVolumeSource_To_api_CinderVolumeSource, - convert_v1_ContainerPort_To_api_ContainerPort, - convert_v1_Container_To_api_Container, - convert_v1_DaemonSetList_To_experimental_DaemonSetList, - convert_v1_DaemonSetSpec_To_experimental_DaemonSetSpec, - convert_v1_DaemonSetStatus_To_experimental_DaemonSetStatus, - convert_v1_DaemonSet_To_experimental_DaemonSet, - convert_v1_DeploymentList_To_experimental_DeploymentList, - convert_v1_DeploymentStatus_To_experimental_DeploymentStatus, - convert_v1_Deployment_To_experimental_Deployment, - convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile, - convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource, - convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource, - convert_v1_EnvVarSource_To_api_EnvVarSource, - convert_v1_EnvVar_To_api_EnvVar, - convert_v1_ExecAction_To_api_ExecAction, - convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource, - convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource, - convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource, - convert_v1_HTTPGetAction_To_api_HTTPGetAction, - convert_v1_Handler_To_api_Handler, - convert_v1_HorizontalPodAutoscalerList_To_experimental_HorizontalPodAutoscalerList, - convert_v1_HorizontalPodAutoscalerSpec_To_experimental_HorizontalPodAutoscalerSpec, - convert_v1_HorizontalPodAutoscalerStatus_To_experimental_HorizontalPodAutoscalerStatus, - convert_v1_HorizontalPodAutoscaler_To_experimental_HorizontalPodAutoscaler, - convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource, - convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource, - convert_v1_JobCondition_To_experimental_JobCondition, - convert_v1_JobList_To_experimental_JobList, - convert_v1_JobSpec_To_experimental_JobSpec, - convert_v1_JobStatus_To_experimental_JobStatus, - convert_v1_Job_To_experimental_Job, - convert_v1_Lifecycle_To_api_Lifecycle, - convert_v1_ListMeta_To_api_ListMeta, - convert_v1_LocalObjectReference_To_api_LocalObjectReference, - convert_v1_NFSVolumeSource_To_api_NFSVolumeSource, - convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector, - convert_v1_ObjectMeta_To_api_ObjectMeta, - convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource, - convert_v1_PodTemplateSpec_To_api_PodTemplateSpec, - convert_v1_Probe_To_api_Probe, - convert_v1_RBDVolumeSource_To_api_RBDVolumeSource, - convert_v1_ReplicationControllerDummy_To_experimental_ReplicationControllerDummy, - convert_v1_ResourceConsumption_To_experimental_ResourceConsumption, - convert_v1_ResourceRequirements_To_api_ResourceRequirements, - convert_v1_SELinuxOptions_To_api_SELinuxOptions, - convert_v1_ScaleSpec_To_experimental_ScaleSpec, - convert_v1_ScaleStatus_To_experimental_ScaleStatus, - convert_v1_Scale_To_experimental_Scale, - convert_v1_SecretVolumeSource_To_api_SecretVolumeSource, - convert_v1_SecurityContext_To_api_SecurityContext, - convert_v1_SubresourceReference_To_experimental_SubresourceReference, - convert_v1_TCPSocketAction_To_api_TCPSocketAction, - convert_v1_ThirdPartyResourceDataList_To_experimental_ThirdPartyResourceDataList, - convert_v1_ThirdPartyResourceData_To_experimental_ThirdPartyResourceData, - convert_v1_ThirdPartyResourceList_To_experimental_ThirdPartyResourceList, - convert_v1_ThirdPartyResource_To_experimental_ThirdPartyResource, - convert_v1_TypeMeta_To_api_TypeMeta, - convert_v1_VolumeMount_To_api_VolumeMount, - convert_v1_Volume_To_api_Volume, - ) - if err != nil { - // If one of the conversion functions is malformed, detect it immediately. - panic(err) - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/validation/validation.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/validation/validation.go deleted file mode 100644 index 1a6454fa2cc7..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/validation/validation.go +++ /dev/null @@ -1,319 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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 validation - -import ( - "strconv" - - "k8s.io/kubernetes/pkg/api" - apivalidation "k8s.io/kubernetes/pkg/api/validation" - "k8s.io/kubernetes/pkg/apis/experimental" - "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/util" - errs "k8s.io/kubernetes/pkg/util/fielderrors" - "k8s.io/kubernetes/pkg/util/sets" -) - -const isNegativeErrorMsg string = `must be non-negative` - -// ValidateHorizontalPodAutoscaler can be used to check whether the given autoscaler name is valid. -// Prefix indicates this name will be used as part of generation, in which case trailing dashes are allowed. -func ValidateHorizontalPodAutoscalerName(name string, prefix bool) (bool, string) { - // TODO: finally move it to pkg/api/validation and use nameIsDNSSubdomain function - return apivalidation.ValidateReplicationControllerName(name, prefix) -} - -func validateHorizontalPodAutoscalerSpec(autoscaler experimental.HorizontalPodAutoscalerSpec) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - if autoscaler.MinCount < 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("minCount", autoscaler.MinCount, `must be non-negative`)) - } - if autoscaler.MaxCount < autoscaler.MinCount { - allErrs = append(allErrs, errs.NewFieldInvalid("maxCount", autoscaler.MaxCount, `must be bigger or equal to minCount`)) - } - if autoscaler.ScaleRef == nil { - allErrs = append(allErrs, errs.NewFieldRequired("scaleRef")) - } - resource := autoscaler.Target.Resource.String() - if resource != string(api.ResourceMemory) && resource != string(api.ResourceCPU) { - allErrs = append(allErrs, errs.NewFieldInvalid("target.resource", resource, "resource not supported by autoscaler")) - } - quantity := autoscaler.Target.Quantity.Value() - if quantity < 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("target.quantity", quantity, "must be non-negative")) - } - return allErrs -} - -func ValidateHorizontalPodAutoscaler(autoscaler *experimental.HorizontalPodAutoscaler) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&autoscaler.ObjectMeta, true, ValidateHorizontalPodAutoscalerName).Prefix("metadata")...) - allErrs = append(allErrs, validateHorizontalPodAutoscalerSpec(autoscaler.Spec)...) - return allErrs -} - -func ValidateHorizontalPodAutoscalerUpdate(newAutoscler, oldAutoscaler *experimental.HorizontalPodAutoscaler) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&newAutoscler.ObjectMeta, &oldAutoscaler.ObjectMeta).Prefix("metadata")...) - allErrs = append(allErrs, validateHorizontalPodAutoscalerSpec(newAutoscler.Spec)...) - return allErrs -} - -func ValidateThirdPartyResourceUpdate(old, update *experimental.ThirdPartyResource) errs.ValidationErrorList { - return ValidateThirdPartyResource(update) -} - -func ValidateThirdPartyResource(obj *experimental.ThirdPartyResource) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - if len(obj.Name) == 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("name", obj.Name, "name must be non-empty")) - } - versions := sets.String{} - for ix := range obj.Versions { - version := &obj.Versions[ix] - if len(version.Name) == 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("name", version, "name can not be empty")) - } - if versions.Has(version.Name) { - allErrs = append(allErrs, errs.NewFieldDuplicate("version", version)) - } - versions.Insert(version.Name) - } - return allErrs -} - -// ValidateDaemonSet tests if required fields in the DaemonSet are set. -func ValidateDaemonSet(controller *experimental.DaemonSet) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&controller.ObjectMeta, true, apivalidation.ValidateReplicationControllerName).Prefix("metadata")...) - allErrs = append(allErrs, ValidateDaemonSetSpec(&controller.Spec).Prefix("spec")...) - return allErrs -} - -// ValidateDaemonSetUpdate tests if required fields in the DaemonSet are set. -func ValidateDaemonSetUpdate(oldController, controller *experimental.DaemonSet) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&controller.ObjectMeta, &oldController.ObjectMeta).Prefix("metadata")...) - allErrs = append(allErrs, ValidateDaemonSetSpec(&controller.Spec).Prefix("spec")...) - allErrs = append(allErrs, ValidateDaemonSetTemplateUpdate(oldController.Spec.Template, controller.Spec.Template).Prefix("spec.template")...) - return allErrs -} - -// ValidateDaemonSetTemplateUpdate tests that certain fields in the daemon set's pod template are not updated. -func ValidateDaemonSetTemplateUpdate(oldPodTemplate, podTemplate *api.PodTemplateSpec) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - podSpec := podTemplate.Spec - // podTemplate.Spec is not a pointer, so we can modify NodeSelector and NodeName directly. - podSpec.NodeSelector = oldPodTemplate.Spec.NodeSelector - podSpec.NodeName = oldPodTemplate.Spec.NodeName - // In particular, we do not allow updates to container images at this point. - if !api.Semantic.DeepEqual(oldPodTemplate.Spec, podSpec) { - // TODO: Pinpoint the specific field that causes the invalid error after we have strategic merge diff - allErrs = append(allErrs, errs.NewFieldInvalid("spec", "content of spec is not printed out, please refer to the \"details\"", "may not update fields other than spec.nodeSelector")) - } - return allErrs -} - -// ValidateDaemonSetSpec tests if required fields in the DaemonSetSpec are set. -func ValidateDaemonSetSpec(spec *experimental.DaemonSetSpec) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - - selector := labels.Set(spec.Selector).AsSelector() - if selector.Empty() { - allErrs = append(allErrs, errs.NewFieldRequired("selector")) - } - - if spec.Template == nil { - allErrs = append(allErrs, errs.NewFieldRequired("template")) - } else { - labels := labels.Set(spec.Template.Labels) - if !selector.Matches(labels) { - allErrs = append(allErrs, errs.NewFieldInvalid("template.metadata.labels", spec.Template.Labels, "selector does not match template")) - } - allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(spec.Template).Prefix("template")...) - // Daemons typically run on more than one node, so mark Read-Write persistent disks as invalid. - allErrs = append(allErrs, apivalidation.ValidateReadOnlyPersistentDisks(spec.Template.Spec.Volumes).Prefix("template.spec.volumes")...) - // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). - if spec.Template.Spec.RestartPolicy != api.RestartPolicyAlways { - allErrs = append(allErrs, errs.NewFieldValueNotSupported("template.spec.restartPolicy", spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)})) - } - } - return allErrs -} - -// ValidateDaemonSetName can be used to check whether the given daemon set name is valid. -// Prefix indicates this name will be used as part of generation, in which case -// trailing dashes are allowed. -func ValidateDaemonSetName(name string, prefix bool) (bool, string) { - return apivalidation.NameIsDNSSubdomain(name, prefix) -} - -// Validates that the given name can be used as a deployment name. -func ValidateDeploymentName(name string, prefix bool) (bool, string) { - return apivalidation.NameIsDNSSubdomain(name, prefix) -} - -func ValidatePositiveIntOrPercent(intOrPercent util.IntOrString, fieldName string) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - if intOrPercent.Kind == util.IntstrString { - if !util.IsValidPercent(intOrPercent.StrVal) { - allErrs = append(allErrs, errs.NewFieldInvalid(fieldName, intOrPercent, "value should be int(5) or percentage(5%)")) - } - - } else if intOrPercent.Kind == util.IntstrInt { - allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(intOrPercent.IntVal), fieldName)...) - } - return allErrs -} - -func getPercentValue(intOrStringValue util.IntOrString) (int, bool) { - if intOrStringValue.Kind != util.IntstrString || !util.IsValidPercent(intOrStringValue.StrVal) { - return 0, false - } - value, _ := strconv.Atoi(intOrStringValue.StrVal[:len(intOrStringValue.StrVal)-1]) - return value, true -} - -func getIntOrPercentValue(intOrStringValue util.IntOrString) int { - value, isPercent := getPercentValue(intOrStringValue) - if isPercent { - return value - } - return intOrStringValue.IntVal -} - -func IsNotMoreThan100Percent(intOrStringValue util.IntOrString, fieldName string) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - value, isPercent := getPercentValue(intOrStringValue) - if !isPercent || value <= 100 { - return nil - } - allErrs = append(allErrs, errs.NewFieldInvalid(fieldName, intOrStringValue, "should not be more than 100%")) - return allErrs -} - -func ValidateRollingUpdateDeployment(rollingUpdate *experimental.RollingUpdateDeployment, fieldName string) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxUnavailable, fieldName+"maxUnavailable")...) - allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxSurge, fieldName+".maxSurge")...) - if getIntOrPercentValue(rollingUpdate.MaxUnavailable) == 0 && getIntOrPercentValue(rollingUpdate.MaxSurge) == 0 { - // Both MaxSurge and MaxUnavailable cannot be zero. - allErrs = append(allErrs, errs.NewFieldInvalid(fieldName+".maxUnavailable", rollingUpdate.MaxUnavailable, "cannot be 0 when maxSurge is 0 as well")) - } - // Validate that MaxUnavailable is not more than 100%. - allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fieldName+".maxUnavailable")...) - allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(rollingUpdate.MinReadySeconds), fieldName+".minReadySeconds")...) - return allErrs -} - -func ValidateDeploymentStrategy(strategy *experimental.DeploymentStrategy, fieldName string) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - if strategy.RollingUpdate == nil { - return allErrs - } - switch strategy.Type { - case experimental.DeploymentRecreate: - allErrs = append(allErrs, errs.NewFieldForbidden("rollingUpdate", "rollingUpdate should be nil when strategy type is "+experimental.DeploymentRecreate)) - case experimental.DeploymentRollingUpdate: - allErrs = append(allErrs, ValidateRollingUpdateDeployment(strategy.RollingUpdate, "rollingUpdate")...) - } - return allErrs -} - -// Validates given deployment spec. -func ValidateDeploymentSpec(spec *experimental.DeploymentSpec) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - allErrs = append(allErrs, apivalidation.ValidateNonEmptySelector(spec.Selector, "selector")...) - allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(spec.Replicas), "replicas")...) - allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpecForRC(spec.Template, spec.Selector, spec.Replicas, "template")...) - allErrs = append(allErrs, ValidateDeploymentStrategy(&spec.Strategy, "strategy")...) - allErrs = append(allErrs, apivalidation.ValidateLabelName(spec.UniqueLabelKey, "uniqueLabel")...) - return allErrs -} - -func ValidateDeploymentUpdate(old, update *experimental.Deployment) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta).Prefix("metadata")...) - allErrs = append(allErrs, ValidateDeploymentSpec(&update.Spec).Prefix("spec")...) - return allErrs -} - -func ValidateDeployment(obj *experimental.Deployment) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&obj.ObjectMeta, true, ValidateDeploymentName).Prefix("metadata")...) - allErrs = append(allErrs, ValidateDeploymentSpec(&obj.Spec).Prefix("spec")...) - return allErrs -} - -func ValidateThirdPartyResourceDataUpdate(old, update *experimental.ThirdPartyResourceData) errs.ValidationErrorList { - return ValidateThirdPartyResourceData(update) -} - -func ValidateThirdPartyResourceData(obj *experimental.ThirdPartyResourceData) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - if len(obj.Name) == 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("name", obj.Name, "name must be non-empty")) - } - return allErrs -} - -func ValidateJob(job *experimental.Job) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - // Jobs and rcs have the same name validation - allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&job.ObjectMeta, true, apivalidation.ValidateReplicationControllerName).Prefix("metadata")...) - allErrs = append(allErrs, ValidateJobSpec(&job.Spec).Prefix("spec")...) - return allErrs -} - -func ValidateJobSpec(spec *experimental.JobSpec) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - - if spec.Parallelism != nil && *spec.Parallelism < 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("parallelism", spec.Parallelism, isNegativeErrorMsg)) - } - if spec.Completions != nil && *spec.Completions < 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("completions", spec.Completions, isNegativeErrorMsg)) - } - - selector := labels.Set(spec.Selector).AsSelector() - if selector.Empty() { - allErrs = append(allErrs, errs.NewFieldRequired("selector")) - } - - if spec.Template == nil { - allErrs = append(allErrs, errs.NewFieldRequired("template")) - } else { - labels := labels.Set(spec.Template.Labels) - if !selector.Matches(labels) { - allErrs = append(allErrs, errs.NewFieldInvalid("template.labels", spec.Template.Labels, "selector does not match template")) - } - allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(spec.Template).Prefix("template")...) - if spec.Template.Spec.RestartPolicy != api.RestartPolicyOnFailure && - spec.Template.Spec.RestartPolicy != api.RestartPolicyNever { - allErrs = append(allErrs, errs.NewFieldValueNotSupported("template.spec.restartPolicy", - spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyOnFailure), string(api.RestartPolicyNever)})) - } - } - return allErrs -} - -func ValidateJobUpdate(oldJob, job *experimental.Job) errs.ValidationErrorList { - allErrs := errs.ValidationErrorList{} - allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&oldJob.ObjectMeta, &job.ObjectMeta).Prefix("metadata")...) - allErrs = append(allErrs, ValidateJobSpec(&job.Spec).Prefix("spec")...) - return allErrs -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/deep_copy_generated.go similarity index 62% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/deep_copy_generated.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/deep_copy_generated.go index 3f424a6f9c4a..fcd0c810b6b4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/deep_copy_generated.go @@ -16,13 +16,14 @@ limitations under the License. // DO NOT EDIT. THIS FILE IS AUTO-GENERATED BY $KUBEROOT/hack/update-generated-deep-copies.sh. -package experimental +package extensions import ( time "time" api "k8s.io/kubernetes/pkg/api" resource "k8s.io/kubernetes/pkg/api/resource" + unversioned "k8s.io/kubernetes/pkg/api/unversioned" conversion "k8s.io/kubernetes/pkg/conversion" util "k8s.io/kubernetes/pkg/util" inf "speter.net/go/exp/math/dec/inf" @@ -252,6 +253,31 @@ func deepCopy_api_ExecAction(in api.ExecAction, out *api.ExecAction, c *conversi return nil } +func deepCopy_api_FCVolumeSource(in api.FCVolumeSource, out *api.FCVolumeSource, c *conversion.Cloner) error { + if in.TargetWWNs != nil { + out.TargetWWNs = make([]string, len(in.TargetWWNs)) + for i := range in.TargetWWNs { + out.TargetWWNs[i] = in.TargetWWNs[i] + } + } else { + out.TargetWWNs = nil + } + if in.Lun != nil { + out.Lun = new(int) + *out.Lun = *in.Lun + } else { + out.Lun = nil + } + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_api_FlockerVolumeSource(in api.FlockerVolumeSource, out *api.FlockerVolumeSource, c *conversion.Cloner) error { + out.DatasetName = in.DatasetName + return nil +} + func deepCopy_api_GCEPersistentDiskVolumeSource(in api.GCEPersistentDiskVolumeSource, out *api.GCEPersistentDiskVolumeSource, c *conversion.Cloner) error { out.PDName = in.PDName out.FSType = in.FSType @@ -345,9 +371,23 @@ func deepCopy_api_Lifecycle(in api.Lifecycle, out *api.Lifecycle, c *conversion. return nil } -func deepCopy_api_ListMeta(in api.ListMeta, out *api.ListMeta, c *conversion.Cloner) error { - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion +func deepCopy_api_LoadBalancerIngress(in api.LoadBalancerIngress, out *api.LoadBalancerIngress, c *conversion.Cloner) error { + out.IP = in.IP + out.Hostname = in.Hostname + return nil +} + +func deepCopy_api_LoadBalancerStatus(in api.LoadBalancerStatus, out *api.LoadBalancerStatus, c *conversion.Cloner) error { + if in.Ingress != nil { + out.Ingress = make([]api.LoadBalancerIngress, len(in.Ingress)) + for i := range in.Ingress { + if err := deepCopy_api_LoadBalancerIngress(in.Ingress[i], &out.Ingress[i], c); err != nil { + return err + } + } + } else { + out.Ingress = nil + } return nil } @@ -377,12 +417,12 @@ func deepCopy_api_ObjectMeta(in api.ObjectMeta, out *api.ObjectMeta, c *conversi out.UID = in.UID out.ResourceVersion = in.ResourceVersion out.Generation = in.Generation - if err := deepCopy_util_Time(in.CreationTimestamp, &out.CreationTimestamp, c); err != nil { + if err := deepCopy_unversioned_Time(in.CreationTimestamp, &out.CreationTimestamp, c); err != nil { return err } if in.DeletionTimestamp != nil { - out.DeletionTimestamp = new(util.Time) - if err := deepCopy_util_Time(*in.DeletionTimestamp, out.DeletionTimestamp, c); err != nil { + out.DeletionTimestamp = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.DeletionTimestamp, out.DeletionTimestamp, c); err != nil { return err } } else { @@ -419,6 +459,13 @@ func deepCopy_api_PersistentVolumeClaimVolumeSource(in api.PersistentVolumeClaim return nil } +func deepCopy_api_PodSecurityContext(in api.PodSecurityContext, out *api.PodSecurityContext, c *conversion.Cloner) error { + out.HostNetwork = in.HostNetwork + out.HostPID = in.HostPID + out.HostIPC = in.HostIPC + return nil +} + func deepCopy_api_PodSpec(in api.PodSpec, out *api.PodSpec, c *conversion.Cloner) error { if in.Volumes != nil { out.Volumes = make([]api.Volume, len(in.Volumes)) @@ -464,9 +511,14 @@ func deepCopy_api_PodSpec(in api.PodSpec, out *api.PodSpec, c *conversion.Cloner } out.ServiceAccountName = in.ServiceAccountName out.NodeName = in.NodeName - out.HostNetwork = in.HostNetwork - out.HostPID = in.HostPID - out.HostIPC = in.HostIPC + if in.SecurityContext != nil { + out.SecurityContext = new(api.PodSecurityContext) + if err := deepCopy_api_PodSecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil { + return err + } + } else { + out.SecurityContext = nil + } if in.ImagePullSecrets != nil { out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets)) for i := range in.ImagePullSecrets { @@ -606,12 +658,6 @@ func deepCopy_api_TCPSocketAction(in api.TCPSocketAction, out *api.TCPSocketActi return nil } -func deepCopy_api_TypeMeta(in api.TypeMeta, out *api.TypeMeta, c *conversion.Cloner) error { - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil -} - func deepCopy_api_Volume(in api.Volume, out *api.Volume, c *conversion.Cloner) error { out.Name = in.Name if err := deepCopy_api_VolumeSource(in.VolumeSource, &out.VolumeSource, c); err != nil { @@ -732,6 +778,14 @@ func deepCopy_api_VolumeSource(in api.VolumeSource, out *api.VolumeSource, c *co } else { out.CephFS = nil } + if in.Flocker != nil { + out.Flocker = new(api.FlockerVolumeSource) + if err := deepCopy_api_FlockerVolumeSource(*in.Flocker, out.Flocker, c); err != nil { + return err + } + } else { + out.Flocker = nil + } if in.DownwardAPI != nil { out.DownwardAPI = new(api.DownwardAPIVolumeSource) if err := deepCopy_api_DownwardAPIVolumeSource(*in.DownwardAPI, out.DownwardAPI, c); err != nil { @@ -740,6 +794,14 @@ func deepCopy_api_VolumeSource(in api.VolumeSource, out *api.VolumeSource, c *co } else { out.DownwardAPI = nil } + if in.FC != nil { + out.FC = new(api.FCVolumeSource) + if err := deepCopy_api_FCVolumeSource(*in.FC, out.FC, c); err != nil { + return err + } + } else { + out.FC = nil + } return nil } @@ -759,39 +821,109 @@ func deepCopy_resource_Quantity(in resource.Quantity, out *resource.Quantity, c return nil } -func deepCopy_experimental_APIVersion(in APIVersion, out *APIVersion, c *conversion.Cloner) error { +func deepCopy_unversioned_ListMeta(in unversioned.ListMeta, out *unversioned.ListMeta, c *conversion.Cloner) error { + out.SelfLink = in.SelfLink + out.ResourceVersion = in.ResourceVersion + return nil +} + +func deepCopy_unversioned_Time(in unversioned.Time, out *unversioned.Time, c *conversion.Cloner) error { + if newVal, err := c.DeepCopy(in.Time); err != nil { + return err + } else { + out.Time = newVal.(time.Time) + } + return nil +} + +func deepCopy_unversioned_TypeMeta(in unversioned.TypeMeta, out *unversioned.TypeMeta, c *conversion.Cloner) error { + out.Kind = in.Kind + out.APIVersion = in.APIVersion + return nil +} + +func deepCopy_extensions_APIVersion(in APIVersion, out *APIVersion, c *conversion.Cloner) error { out.Name = in.Name out.APIGroup = in.APIGroup return nil } -func deepCopy_experimental_DaemonSet(in DaemonSet, out *DaemonSet, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_ClusterAutoscaler(in ClusterAutoscaler, out *ClusterAutoscaler, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_extensions_ClusterAutoscalerSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + return nil +} + +func deepCopy_extensions_ClusterAutoscalerList(in ClusterAutoscalerList, out *ClusterAutoscalerList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ClusterAutoscaler, len(in.Items)) + for i := range in.Items { + if err := deepCopy_extensions_ClusterAutoscaler(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_extensions_ClusterAutoscalerSpec(in ClusterAutoscalerSpec, out *ClusterAutoscalerSpec, c *conversion.Cloner) error { + out.MinNodes = in.MinNodes + out.MaxNodes = in.MaxNodes + if in.TargetUtilization != nil { + out.TargetUtilization = make([]NodeUtilization, len(in.TargetUtilization)) + for i := range in.TargetUtilization { + if err := deepCopy_extensions_NodeUtilization(in.TargetUtilization[i], &out.TargetUtilization[i], c); err != nil { + return err + } + } + } else { + out.TargetUtilization = nil + } + return nil +} + +func deepCopy_extensions_DaemonSet(in DaemonSet, out *DaemonSet, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { return err } - if err := deepCopy_experimental_DaemonSetSpec(in.Spec, &out.Spec, c); err != nil { + if err := deepCopy_extensions_DaemonSetSpec(in.Spec, &out.Spec, c); err != nil { return err } - if err := deepCopy_experimental_DaemonSetStatus(in.Status, &out.Status, c); err != nil { + if err := deepCopy_extensions_DaemonSetStatus(in.Status, &out.Status, c); err != nil { return err } return nil } -func deepCopy_experimental_DaemonSetList(in DaemonSetList, out *DaemonSetList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_DaemonSetList(in DaemonSetList, out *DaemonSetList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]DaemonSet, len(in.Items)) for i := range in.Items { - if err := deepCopy_experimental_DaemonSet(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_extensions_DaemonSet(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -801,7 +933,7 @@ func deepCopy_experimental_DaemonSetList(in DaemonSetList, out *DaemonSetList, c return nil } -func deepCopy_experimental_DaemonSetSpec(in DaemonSetSpec, out *DaemonSetSpec, c *conversion.Cloner) error { +func deepCopy_extensions_DaemonSetSpec(in DaemonSetSpec, out *DaemonSetSpec, c *conversion.Cloner) error { if in.Selector != nil { out.Selector = make(map[string]string) for key, val := range in.Selector { @@ -821,40 +953,40 @@ func deepCopy_experimental_DaemonSetSpec(in DaemonSetSpec, out *DaemonSetSpec, c return nil } -func deepCopy_experimental_DaemonSetStatus(in DaemonSetStatus, out *DaemonSetStatus, c *conversion.Cloner) error { +func deepCopy_extensions_DaemonSetStatus(in DaemonSetStatus, out *DaemonSetStatus, c *conversion.Cloner) error { out.CurrentNumberScheduled = in.CurrentNumberScheduled out.NumberMisscheduled = in.NumberMisscheduled out.DesiredNumberScheduled = in.DesiredNumberScheduled return nil } -func deepCopy_experimental_Deployment(in Deployment, out *Deployment, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_Deployment(in Deployment, out *Deployment, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { return err } - if err := deepCopy_experimental_DeploymentSpec(in.Spec, &out.Spec, c); err != nil { + if err := deepCopy_extensions_DeploymentSpec(in.Spec, &out.Spec, c); err != nil { return err } - if err := deepCopy_experimental_DeploymentStatus(in.Status, &out.Status, c); err != nil { + if err := deepCopy_extensions_DeploymentStatus(in.Status, &out.Status, c); err != nil { return err } return nil } -func deepCopy_experimental_DeploymentList(in DeploymentList, out *DeploymentList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_DeploymentList(in DeploymentList, out *DeploymentList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]Deployment, len(in.Items)) for i := range in.Items { - if err := deepCopy_experimental_Deployment(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_extensions_Deployment(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -864,7 +996,7 @@ func deepCopy_experimental_DeploymentList(in DeploymentList, out *DeploymentList return nil } -func deepCopy_experimental_DeploymentSpec(in DeploymentSpec, out *DeploymentSpec, c *conversion.Cloner) error { +func deepCopy_extensions_DeploymentSpec(in DeploymentSpec, out *DeploymentSpec, c *conversion.Cloner) error { out.Replicas = in.Replicas if in.Selector != nil { out.Selector = make(map[string]string) @@ -882,24 +1014,24 @@ func deepCopy_experimental_DeploymentSpec(in DeploymentSpec, out *DeploymentSpec } else { out.Template = nil } - if err := deepCopy_experimental_DeploymentStrategy(in.Strategy, &out.Strategy, c); err != nil { + if err := deepCopy_extensions_DeploymentStrategy(in.Strategy, &out.Strategy, c); err != nil { return err } out.UniqueLabelKey = in.UniqueLabelKey return nil } -func deepCopy_experimental_DeploymentStatus(in DeploymentStatus, out *DeploymentStatus, c *conversion.Cloner) error { +func deepCopy_extensions_DeploymentStatus(in DeploymentStatus, out *DeploymentStatus, c *conversion.Cloner) error { out.Replicas = in.Replicas out.UpdatedReplicas = in.UpdatedReplicas return nil } -func deepCopy_experimental_DeploymentStrategy(in DeploymentStrategy, out *DeploymentStrategy, c *conversion.Cloner) error { +func deepCopy_extensions_DeploymentStrategy(in DeploymentStrategy, out *DeploymentStrategy, c *conversion.Cloner) error { out.Type = in.Type if in.RollingUpdate != nil { out.RollingUpdate = new(RollingUpdateDeployment) - if err := deepCopy_experimental_RollingUpdateDeployment(*in.RollingUpdate, out.RollingUpdate, c); err != nil { + if err := deepCopy_extensions_RollingUpdateDeployment(*in.RollingUpdate, out.RollingUpdate, c); err != nil { return err } } else { @@ -908,38 +1040,55 @@ func deepCopy_experimental_DeploymentStrategy(in DeploymentStrategy, out *Deploy return nil } -func deepCopy_experimental_HorizontalPodAutoscaler(in HorizontalPodAutoscaler, out *HorizontalPodAutoscaler, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_HTTPIngressPath(in HTTPIngressPath, out *HTTPIngressPath, c *conversion.Cloner) error { + out.Path = in.Path + if err := deepCopy_extensions_IngressBackend(in.Backend, &out.Backend, c); err != nil { + return err + } + return nil +} + +func deepCopy_extensions_HTTPIngressRuleValue(in HTTPIngressRuleValue, out *HTTPIngressRuleValue, c *conversion.Cloner) error { + if in.Paths != nil { + out.Paths = make([]HTTPIngressPath, len(in.Paths)) + for i := range in.Paths { + if err := deepCopy_extensions_HTTPIngressPath(in.Paths[i], &out.Paths[i], c); err != nil { + return err + } + } + } else { + out.Paths = nil + } + return nil +} + +func deepCopy_extensions_HorizontalPodAutoscaler(in HorizontalPodAutoscaler, out *HorizontalPodAutoscaler, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { return err } - if err := deepCopy_experimental_HorizontalPodAutoscalerSpec(in.Spec, &out.Spec, c); err != nil { + if err := deepCopy_extensions_HorizontalPodAutoscalerSpec(in.Spec, &out.Spec, c); err != nil { return err } - if in.Status != nil { - out.Status = new(HorizontalPodAutoscalerStatus) - if err := deepCopy_experimental_HorizontalPodAutoscalerStatus(*in.Status, out.Status, c); err != nil { - return err - } - } else { - out.Status = nil + if err := deepCopy_extensions_HorizontalPodAutoscalerStatus(in.Status, &out.Status, c); err != nil { + return err } return nil } -func deepCopy_experimental_HorizontalPodAutoscalerList(in HorizontalPodAutoscalerList, out *HorizontalPodAutoscalerList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_HorizontalPodAutoscalerList(in HorizontalPodAutoscalerList, out *HorizontalPodAutoscalerList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]HorizontalPodAutoscaler, len(in.Items)) for i := range in.Items { - if err := deepCopy_experimental_HorizontalPodAutoscaler(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_extensions_HorizontalPodAutoscaler(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -949,37 +1098,37 @@ func deepCopy_experimental_HorizontalPodAutoscalerList(in HorizontalPodAutoscale return nil } -func deepCopy_experimental_HorizontalPodAutoscalerSpec(in HorizontalPodAutoscalerSpec, out *HorizontalPodAutoscalerSpec, c *conversion.Cloner) error { +func deepCopy_extensions_HorizontalPodAutoscalerSpec(in HorizontalPodAutoscalerSpec, out *HorizontalPodAutoscalerSpec, c *conversion.Cloner) error { if in.ScaleRef != nil { out.ScaleRef = new(SubresourceReference) - if err := deepCopy_experimental_SubresourceReference(*in.ScaleRef, out.ScaleRef, c); err != nil { + if err := deepCopy_extensions_SubresourceReference(*in.ScaleRef, out.ScaleRef, c); err != nil { return err } } else { out.ScaleRef = nil } - out.MinCount = in.MinCount - out.MaxCount = in.MaxCount - if err := deepCopy_experimental_ResourceConsumption(in.Target, &out.Target, c); err != nil { + out.MinReplicas = in.MinReplicas + out.MaxReplicas = in.MaxReplicas + if err := deepCopy_extensions_ResourceConsumption(in.Target, &out.Target, c); err != nil { return err } return nil } -func deepCopy_experimental_HorizontalPodAutoscalerStatus(in HorizontalPodAutoscalerStatus, out *HorizontalPodAutoscalerStatus, c *conversion.Cloner) error { +func deepCopy_extensions_HorizontalPodAutoscalerStatus(in HorizontalPodAutoscalerStatus, out *HorizontalPodAutoscalerStatus, c *conversion.Cloner) error { out.CurrentReplicas = in.CurrentReplicas out.DesiredReplicas = in.DesiredReplicas if in.CurrentConsumption != nil { out.CurrentConsumption = new(ResourceConsumption) - if err := deepCopy_experimental_ResourceConsumption(*in.CurrentConsumption, out.CurrentConsumption, c); err != nil { + if err := deepCopy_extensions_ResourceConsumption(*in.CurrentConsumption, out.CurrentConsumption, c); err != nil { return err } } else { out.CurrentConsumption = nil } if in.LastScaleTimestamp != nil { - out.LastScaleTimestamp = new(util.Time) - if err := deepCopy_util_Time(*in.LastScaleTimestamp, out.LastScaleTimestamp, c); err != nil { + out.LastScaleTimestamp = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.LastScaleTimestamp, out.LastScaleTimestamp, c); err != nil { return err } } else { @@ -988,29 +1137,122 @@ func deepCopy_experimental_HorizontalPodAutoscalerStatus(in HorizontalPodAutosca return nil } -func deepCopy_experimental_Job(in Job, out *Job, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_Ingress(in Ingress, out *Ingress, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { return err } - if err := deepCopy_experimental_JobSpec(in.Spec, &out.Spec, c); err != nil { + if err := deepCopy_extensions_IngressSpec(in.Spec, &out.Spec, c); err != nil { return err } - if err := deepCopy_experimental_JobStatus(in.Status, &out.Status, c); err != nil { + if err := deepCopy_extensions_IngressStatus(in.Status, &out.Status, c); err != nil { return err } return nil } -func deepCopy_experimental_JobCondition(in JobCondition, out *JobCondition, c *conversion.Cloner) error { +func deepCopy_extensions_IngressBackend(in IngressBackend, out *IngressBackend, c *conversion.Cloner) error { + out.ServiceName = in.ServiceName + if err := deepCopy_util_IntOrString(in.ServicePort, &out.ServicePort, c); err != nil { + return err + } + return nil +} + +func deepCopy_extensions_IngressList(in IngressList, out *IngressList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Ingress, len(in.Items)) + for i := range in.Items { + if err := deepCopy_extensions_Ingress(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_extensions_IngressRule(in IngressRule, out *IngressRule, c *conversion.Cloner) error { + out.Host = in.Host + if err := deepCopy_extensions_IngressRuleValue(in.IngressRuleValue, &out.IngressRuleValue, c); err != nil { + return err + } + return nil +} + +func deepCopy_extensions_IngressRuleValue(in IngressRuleValue, out *IngressRuleValue, c *conversion.Cloner) error { + if in.HTTP != nil { + out.HTTP = new(HTTPIngressRuleValue) + if err := deepCopy_extensions_HTTPIngressRuleValue(*in.HTTP, out.HTTP, c); err != nil { + return err + } + } else { + out.HTTP = nil + } + return nil +} + +func deepCopy_extensions_IngressSpec(in IngressSpec, out *IngressSpec, c *conversion.Cloner) error { + if in.Backend != nil { + out.Backend = new(IngressBackend) + if err := deepCopy_extensions_IngressBackend(*in.Backend, out.Backend, c); err != nil { + return err + } + } else { + out.Backend = nil + } + if in.Rules != nil { + out.Rules = make([]IngressRule, len(in.Rules)) + for i := range in.Rules { + if err := deepCopy_extensions_IngressRule(in.Rules[i], &out.Rules[i], c); err != nil { + return err + } + } + } else { + out.Rules = nil + } + return nil +} + +func deepCopy_extensions_IngressStatus(in IngressStatus, out *IngressStatus, c *conversion.Cloner) error { + if err := deepCopy_api_LoadBalancerStatus(in.LoadBalancer, &out.LoadBalancer, c); err != nil { + return err + } + return nil +} + +func deepCopy_extensions_Job(in Job, out *Job, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_extensions_JobSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + if err := deepCopy_extensions_JobStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_extensions_JobCondition(in JobCondition, out *JobCondition, c *conversion.Cloner) error { out.Type = in.Type out.Status = in.Status - if err := deepCopy_util_Time(in.LastProbeTime, &out.LastProbeTime, c); err != nil { + if err := deepCopy_unversioned_Time(in.LastProbeTime, &out.LastProbeTime, c); err != nil { return err } - if err := deepCopy_util_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { + if err := deepCopy_unversioned_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { return err } out.Reason = in.Reason @@ -1018,17 +1260,17 @@ func deepCopy_experimental_JobCondition(in JobCondition, out *JobCondition, c *c return nil } -func deepCopy_experimental_JobList(in JobList, out *JobList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_JobList(in JobList, out *JobList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]Job, len(in.Items)) for i := range in.Items { - if err := deepCopy_experimental_Job(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_extensions_Job(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -1038,7 +1280,7 @@ func deepCopy_experimental_JobList(in JobList, out *JobList, c *conversion.Clone return nil } -func deepCopy_experimental_JobSpec(in JobSpec, out *JobSpec, c *conversion.Cloner) error { +func deepCopy_extensions_JobSpec(in JobSpec, out *JobSpec, c *conversion.Cloner) error { if in.Parallelism != nil { out.Parallelism = new(int) *out.Parallelism = *in.Parallelism @@ -1059,22 +1301,17 @@ func deepCopy_experimental_JobSpec(in JobSpec, out *JobSpec, c *conversion.Clone } else { out.Selector = nil } - if in.Template != nil { - out.Template = new(api.PodTemplateSpec) - if err := deepCopy_api_PodTemplateSpec(*in.Template, out.Template, c); err != nil { - return err - } - } else { - out.Template = nil + if err := deepCopy_api_PodTemplateSpec(in.Template, &out.Template, c); err != nil { + return err } return nil } -func deepCopy_experimental_JobStatus(in JobStatus, out *JobStatus, c *conversion.Cloner) error { +func deepCopy_extensions_JobStatus(in JobStatus, out *JobStatus, c *conversion.Cloner) error { if in.Conditions != nil { out.Conditions = make([]JobCondition, len(in.Conditions)) for i := range in.Conditions { - if err := deepCopy_experimental_JobCondition(in.Conditions[i], &out.Conditions[i], c); err != nil { + if err := deepCopy_extensions_JobCondition(in.Conditions[i], &out.Conditions[i], c); err != nil { return err } } @@ -1082,35 +1319,41 @@ func deepCopy_experimental_JobStatus(in JobStatus, out *JobStatus, c *conversion out.Conditions = nil } if in.StartTime != nil { - out.StartTime = new(util.Time) - if err := deepCopy_util_Time(*in.StartTime, out.StartTime, c); err != nil { + out.StartTime = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.StartTime, out.StartTime, c); err != nil { return err } } else { out.StartTime = nil } if in.CompletionTime != nil { - out.CompletionTime = new(util.Time) - if err := deepCopy_util_Time(*in.CompletionTime, out.CompletionTime, c); err != nil { + out.CompletionTime = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.CompletionTime, out.CompletionTime, c); err != nil { return err } } else { out.CompletionTime = nil } out.Active = in.Active - out.Successful = in.Successful - out.Unsuccessful = in.Unsuccessful + out.Succeeded = in.Succeeded + out.Failed = in.Failed return nil } -func deepCopy_experimental_ReplicationControllerDummy(in ReplicationControllerDummy, out *ReplicationControllerDummy, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_NodeUtilization(in NodeUtilization, out *NodeUtilization, c *conversion.Cloner) error { + out.Resource = in.Resource + out.Value = in.Value + return nil +} + +func deepCopy_extensions_ReplicationControllerDummy(in ReplicationControllerDummy, out *ReplicationControllerDummy, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } return nil } -func deepCopy_experimental_ResourceConsumption(in ResourceConsumption, out *ResourceConsumption, c *conversion.Cloner) error { +func deepCopy_extensions_ResourceConsumption(in ResourceConsumption, out *ResourceConsumption, c *conversion.Cloner) error { out.Resource = in.Resource if err := deepCopy_resource_Quantity(in.Quantity, &out.Quantity, c); err != nil { return err @@ -1118,7 +1361,7 @@ func deepCopy_experimental_ResourceConsumption(in ResourceConsumption, out *Reso return nil } -func deepCopy_experimental_RollingUpdateDeployment(in RollingUpdateDeployment, out *RollingUpdateDeployment, c *conversion.Cloner) error { +func deepCopy_extensions_RollingUpdateDeployment(in RollingUpdateDeployment, out *RollingUpdateDeployment, c *conversion.Cloner) error { if err := deepCopy_util_IntOrString(in.MaxUnavailable, &out.MaxUnavailable, c); err != nil { return err } @@ -1129,28 +1372,28 @@ func deepCopy_experimental_RollingUpdateDeployment(in RollingUpdateDeployment, o return nil } -func deepCopy_experimental_Scale(in Scale, out *Scale, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_Scale(in Scale, out *Scale, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { return err } - if err := deepCopy_experimental_ScaleSpec(in.Spec, &out.Spec, c); err != nil { + if err := deepCopy_extensions_ScaleSpec(in.Spec, &out.Spec, c); err != nil { return err } - if err := deepCopy_experimental_ScaleStatus(in.Status, &out.Status, c); err != nil { + if err := deepCopy_extensions_ScaleStatus(in.Status, &out.Status, c); err != nil { return err } return nil } -func deepCopy_experimental_ScaleSpec(in ScaleSpec, out *ScaleSpec, c *conversion.Cloner) error { +func deepCopy_extensions_ScaleSpec(in ScaleSpec, out *ScaleSpec, c *conversion.Cloner) error { out.Replicas = in.Replicas return nil } -func deepCopy_experimental_ScaleStatus(in ScaleStatus, out *ScaleStatus, c *conversion.Cloner) error { +func deepCopy_extensions_ScaleStatus(in ScaleStatus, out *ScaleStatus, c *conversion.Cloner) error { out.Replicas = in.Replicas if in.Selector != nil { out.Selector = make(map[string]string) @@ -1163,7 +1406,7 @@ func deepCopy_experimental_ScaleStatus(in ScaleStatus, out *ScaleStatus, c *conv return nil } -func deepCopy_experimental_SubresourceReference(in SubresourceReference, out *SubresourceReference, c *conversion.Cloner) error { +func deepCopy_extensions_SubresourceReference(in SubresourceReference, out *SubresourceReference, c *conversion.Cloner) error { out.Kind = in.Kind out.Namespace = in.Namespace out.Name = in.Name @@ -1172,8 +1415,8 @@ func deepCopy_experimental_SubresourceReference(in SubresourceReference, out *Su return nil } -func deepCopy_experimental_ThirdPartyResource(in ThirdPartyResource, out *ThirdPartyResource, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_ThirdPartyResource(in ThirdPartyResource, out *ThirdPartyResource, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1183,7 +1426,7 @@ func deepCopy_experimental_ThirdPartyResource(in ThirdPartyResource, out *ThirdP if in.Versions != nil { out.Versions = make([]APIVersion, len(in.Versions)) for i := range in.Versions { - if err := deepCopy_experimental_APIVersion(in.Versions[i], &out.Versions[i], c); err != nil { + if err := deepCopy_extensions_APIVersion(in.Versions[i], &out.Versions[i], c); err != nil { return err } } @@ -1193,8 +1436,8 @@ func deepCopy_experimental_ThirdPartyResource(in ThirdPartyResource, out *ThirdP return nil } -func deepCopy_experimental_ThirdPartyResourceData(in ThirdPartyResourceData, out *ThirdPartyResourceData, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_ThirdPartyResourceData(in ThirdPartyResourceData, out *ThirdPartyResourceData, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1211,17 +1454,17 @@ func deepCopy_experimental_ThirdPartyResourceData(in ThirdPartyResourceData, out return nil } -func deepCopy_experimental_ThirdPartyResourceDataList(in ThirdPartyResourceDataList, out *ThirdPartyResourceDataList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_ThirdPartyResourceDataList(in ThirdPartyResourceDataList, out *ThirdPartyResourceDataList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]ThirdPartyResourceData, len(in.Items)) for i := range in.Items { - if err := deepCopy_experimental_ThirdPartyResourceData(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_extensions_ThirdPartyResourceData(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -1231,17 +1474,17 @@ func deepCopy_experimental_ThirdPartyResourceDataList(in ThirdPartyResourceDataL return nil } -func deepCopy_experimental_ThirdPartyResourceList(in ThirdPartyResourceList, out *ThirdPartyResourceList, c *conversion.Cloner) error { - if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_extensions_ThirdPartyResourceList(in ThirdPartyResourceList, out *ThirdPartyResourceList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_api_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]ThirdPartyResource, len(in.Items)) for i := range in.Items { - if err := deepCopy_experimental_ThirdPartyResource(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_extensions_ThirdPartyResource(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -1258,15 +1501,6 @@ func deepCopy_util_IntOrString(in util.IntOrString, out *util.IntOrString, c *co return nil } -func deepCopy_util_Time(in util.Time, out *util.Time, c *conversion.Cloner) error { - if newVal, err := c.DeepCopy(in.Time); err != nil { - return err - } else { - out.Time = newVal.(time.Time) - } - return nil -} - func init() { err := api.Scheme.AddGeneratedDeepCopyFuncs( deepCopy_api_AWSElasticBlockStoreVolumeSource, @@ -1281,6 +1515,8 @@ func init() { deepCopy_api_EnvVar, deepCopy_api_EnvVarSource, deepCopy_api_ExecAction, + deepCopy_api_FCVolumeSource, + deepCopy_api_FlockerVolumeSource, deepCopy_api_GCEPersistentDiskVolumeSource, deepCopy_api_GitRepoVolumeSource, deepCopy_api_GlusterfsVolumeSource, @@ -1289,12 +1525,14 @@ func init() { deepCopy_api_HostPathVolumeSource, deepCopy_api_ISCSIVolumeSource, deepCopy_api_Lifecycle, - deepCopy_api_ListMeta, + deepCopy_api_LoadBalancerIngress, + deepCopy_api_LoadBalancerStatus, deepCopy_api_LocalObjectReference, deepCopy_api_NFSVolumeSource, deepCopy_api_ObjectFieldSelector, deepCopy_api_ObjectMeta, deepCopy_api_PersistentVolumeClaimVolumeSource, + deepCopy_api_PodSecurityContext, deepCopy_api_PodSpec, deepCopy_api_PodTemplateSpec, deepCopy_api_Probe, @@ -1304,43 +1542,57 @@ func init() { deepCopy_api_SecretVolumeSource, deepCopy_api_SecurityContext, deepCopy_api_TCPSocketAction, - deepCopy_api_TypeMeta, deepCopy_api_Volume, deepCopy_api_VolumeMount, deepCopy_api_VolumeSource, deepCopy_resource_Quantity, - deepCopy_experimental_APIVersion, - deepCopy_experimental_DaemonSet, - deepCopy_experimental_DaemonSetList, - deepCopy_experimental_DaemonSetSpec, - deepCopy_experimental_DaemonSetStatus, - deepCopy_experimental_Deployment, - deepCopy_experimental_DeploymentList, - deepCopy_experimental_DeploymentSpec, - deepCopy_experimental_DeploymentStatus, - deepCopy_experimental_DeploymentStrategy, - deepCopy_experimental_HorizontalPodAutoscaler, - deepCopy_experimental_HorizontalPodAutoscalerList, - deepCopy_experimental_HorizontalPodAutoscalerSpec, - deepCopy_experimental_HorizontalPodAutoscalerStatus, - deepCopy_experimental_Job, - deepCopy_experimental_JobCondition, - deepCopy_experimental_JobList, - deepCopy_experimental_JobSpec, - deepCopy_experimental_JobStatus, - deepCopy_experimental_ReplicationControllerDummy, - deepCopy_experimental_ResourceConsumption, - deepCopy_experimental_RollingUpdateDeployment, - deepCopy_experimental_Scale, - deepCopy_experimental_ScaleSpec, - deepCopy_experimental_ScaleStatus, - deepCopy_experimental_SubresourceReference, - deepCopy_experimental_ThirdPartyResource, - deepCopy_experimental_ThirdPartyResourceData, - deepCopy_experimental_ThirdPartyResourceDataList, - deepCopy_experimental_ThirdPartyResourceList, + deepCopy_unversioned_ListMeta, + deepCopy_unversioned_Time, + deepCopy_unversioned_TypeMeta, + deepCopy_extensions_APIVersion, + deepCopy_extensions_ClusterAutoscaler, + deepCopy_extensions_ClusterAutoscalerList, + deepCopy_extensions_ClusterAutoscalerSpec, + deepCopy_extensions_DaemonSet, + deepCopy_extensions_DaemonSetList, + deepCopy_extensions_DaemonSetSpec, + deepCopy_extensions_DaemonSetStatus, + deepCopy_extensions_Deployment, + deepCopy_extensions_DeploymentList, + deepCopy_extensions_DeploymentSpec, + deepCopy_extensions_DeploymentStatus, + deepCopy_extensions_DeploymentStrategy, + deepCopy_extensions_HTTPIngressPath, + deepCopy_extensions_HTTPIngressRuleValue, + deepCopy_extensions_HorizontalPodAutoscaler, + deepCopy_extensions_HorizontalPodAutoscalerList, + deepCopy_extensions_HorizontalPodAutoscalerSpec, + deepCopy_extensions_HorizontalPodAutoscalerStatus, + deepCopy_extensions_Ingress, + deepCopy_extensions_IngressBackend, + deepCopy_extensions_IngressList, + deepCopy_extensions_IngressRule, + deepCopy_extensions_IngressRuleValue, + deepCopy_extensions_IngressSpec, + deepCopy_extensions_IngressStatus, + deepCopy_extensions_Job, + deepCopy_extensions_JobCondition, + deepCopy_extensions_JobList, + deepCopy_extensions_JobSpec, + deepCopy_extensions_JobStatus, + deepCopy_extensions_NodeUtilization, + deepCopy_extensions_ReplicationControllerDummy, + deepCopy_extensions_ResourceConsumption, + deepCopy_extensions_RollingUpdateDeployment, + deepCopy_extensions_Scale, + deepCopy_extensions_ScaleSpec, + deepCopy_extensions_ScaleStatus, + deepCopy_extensions_SubresourceReference, + deepCopy_extensions_ThirdPartyResource, + deepCopy_extensions_ThirdPartyResourceData, + deepCopy_extensions_ThirdPartyResourceDataList, + deepCopy_extensions_ThirdPartyResourceList, deepCopy_util_IntOrString, - deepCopy_util_Time, ) if err != nil { // if one of the deep copy functions is malformed, detect it immediately. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/install/install.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/install/install.go new file mode 100644 index 000000000000..100dcfdbf923 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/install/install.go @@ -0,0 +1,92 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 install installs the experimental API group, making it available as +// an option to all of the API encoding/decoding machinery. +package install + +import ( + "fmt" + "strings" + + "github.com/golang/glog" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/registered" + apiutil "k8s.io/kubernetes/pkg/api/util" + _ "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/sets" +) + +const importPrefix = "k8s.io/kubernetes/pkg/apis/extensions" + +var accessor = meta.NewAccessor() + +func init() { + groupMeta, err := latest.RegisterGroup("extensions") + if err != nil { + glog.V(4).Infof("%v", err) + return + } + registeredGroupVersions := registered.GroupVersionsForGroup("extensions") + groupVersion := registeredGroupVersions[0] + *groupMeta = latest.GroupMeta{ + GroupVersion: groupVersion, + Group: apiutil.GetGroup(groupVersion), + Version: apiutil.GetVersion(groupVersion), + Codec: runtime.CodecFor(api.Scheme, groupVersion), + } + var versions []string + var groupVersions []string + for i := len(registeredGroupVersions) - 1; i >= 0; i-- { + versions = append(versions, apiutil.GetVersion(registeredGroupVersions[i])) + groupVersions = append(groupVersions, registeredGroupVersions[i]) + } + groupMeta.Versions = versions + groupMeta.GroupVersions = groupVersions + + groupMeta.SelfLinker = runtime.SelfLinker(accessor) + + // the list of kinds that are scoped at the root of the api hierarchy + // if a kind is not enumerated here, it is assumed to have a namespace scope + rootScoped := sets.NewString() + + ignoredKinds := sets.NewString() + + groupMeta.RESTMapper = api.NewDefaultRESTMapper("extensions", groupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) + api.RegisterRESTMapper(groupMeta.RESTMapper) + groupMeta.InterfacesFor = interfacesFor +} + +// InterfacesFor returns the default Codec and ResourceVersioner for a given version +// string, or an error if the version is not known. +func interfacesFor(version string) (*meta.VersionInterfaces, error) { + switch version { + case "extensions/v1beta1": + return &meta.VersionInterfaces{ + Codec: v1beta1.Codec, + ObjectConvertor: api.Scheme, + MetadataAccessor: accessor, + }, nil + default: + g, _ := latest.Group("extensions") + return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(g.Versions, ", ")) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/install/install_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/install/install_test.go new file mode 100644 index 000000000000..97c28a94a256 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/install/install_test.go @@ -0,0 +1,113 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 install + +import ( + "encoding/json" + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" +) + +func TestResourceVersioner(t *testing.T) { + daemonSet := extensions.DaemonSet{ObjectMeta: api.ObjectMeta{ResourceVersion: "10"}} + version, err := accessor.ResourceVersion(&daemonSet) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if version != "10" { + t.Errorf("unexpected version %v", version) + } + + daemonSetList := extensions.DaemonSetList{ListMeta: unversioned.ListMeta{ResourceVersion: "10"}} + version, err = accessor.ResourceVersion(&daemonSetList) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if version != "10" { + t.Errorf("unexpected version %v", version) + } +} + +func TestCodec(t *testing.T) { + daemonSet := extensions.DaemonSet{} + // We do want to use package latest rather than testapi here, because we + // want to test if the package install and package latest work as expected. + data, err := latest.GroupOrDie("extensions").Codec.Encode(&daemonSet) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + other := extensions.DaemonSet{} + if err := json.Unmarshal(data, &other); err != nil { + t.Fatalf("unexpected error: %v", err) + } + if other.APIVersion != latest.GroupOrDie("extensions").GroupVersion || other.Kind != "DaemonSet" { + t.Errorf("unexpected unmarshalled object %#v", other) + } +} + +func TestInterfacesFor(t *testing.T) { + if _, err := latest.GroupOrDie("extensions").InterfacesFor(""); err == nil { + t.Fatalf("unexpected non-error: %v", err) + } + for i, groupVersion := range append([]string{latest.GroupOrDie("extensions").GroupVersion}, latest.GroupOrDie("extensions").GroupVersions...) { + if vi, err := latest.GroupOrDie("extensions").InterfacesFor(groupVersion); err != nil || vi == nil { + t.Fatalf("%d: unexpected result: %v", i, err) + } + } +} + +func TestRESTMapper(t *testing.T) { + if v, k, err := latest.GroupOrDie("extensions").RESTMapper.VersionAndKindForResource("horizontalpodautoscalers"); err != nil || v != "extensions/v1beta1" || k != "HorizontalPodAutoscaler" { + t.Errorf("unexpected version mapping: %s %s %v", v, k, err) + } + + if m, err := latest.GroupOrDie("extensions").RESTMapper.RESTMapping("DaemonSet", ""); err != nil || m.APIVersion != "extensions/v1beta1" || m.Resource != "daemonsets" { + t.Errorf("unexpected version mapping: %#v %v", m, err) + } + + for _, groupVersion := range latest.GroupOrDie("extensions").GroupVersions { + mapping, err := latest.GroupOrDie("extensions").RESTMapper.RESTMapping("HorizontalPodAutoscaler", groupVersion) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + if mapping.Resource != "horizontalpodautoscalers" { + t.Errorf("incorrect resource name: %#v", mapping) + } + if mapping.APIVersion != groupVersion { + t.Errorf("incorrect groupVersion: %v", mapping) + } + + interfaces, _ := latest.GroupOrDie("extensions").InterfacesFor(groupVersion) + if mapping.Codec != interfaces.Codec { + t.Errorf("unexpected codec: %#v, expected: %#v", mapping, interfaces) + } + + rc := &extensions.HorizontalPodAutoscaler{ObjectMeta: api.ObjectMeta{Name: "foo"}} + name, err := mapping.MetadataAccessor.Name(rc) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if name != "foo" { + t.Errorf("unable to retrieve object meta with: %v", mapping.MetadataAccessor) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/register.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/register.go similarity index 85% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/register.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/register.go index 1c207f083dd7..535c3c407df9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/register.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/register.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package experimental +package extensions import ( "k8s.io/kubernetes/pkg/api" @@ -28,6 +28,8 @@ func init() { // Adds the list of known types to api.Scheme. func addKnownTypes() { api.Scheme.AddKnownTypes("", + &ClusterAutoscaler{}, + &ClusterAutoscalerList{}, &Deployment{}, &DeploymentList{}, &HorizontalPodAutoscaler{}, @@ -42,9 +44,13 @@ func addKnownTypes() { &DaemonSet{}, &ThirdPartyResourceData{}, &ThirdPartyResourceDataList{}, + &Ingress{}, + &IngressList{}, ) } +func (*ClusterAutoscaler) IsAnAPIObject() {} +func (*ClusterAutoscalerList) IsAnAPIObject() {} func (*Deployment) IsAnAPIObject() {} func (*DeploymentList) IsAnAPIObject() {} func (*HorizontalPodAutoscaler) IsAnAPIObject() {} @@ -59,3 +65,5 @@ func (*DaemonSet) IsAnAPIObject() {} func (*DaemonSetList) IsAnAPIObject() {} func (*ThirdPartyResourceData) IsAnAPIObject() {} func (*ThirdPartyResourceDataList) IsAnAPIObject() {} +func (*Ingress) IsAnAPIObject() {} +func (*IngressList) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/types.go similarity index 58% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/types.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/types.go index aea6f77e307a..4c7f52f895f4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/types.go @@ -15,7 +15,7 @@ limitations under the License. */ /* -This file (together with pkg/apis/experimental/v1/types.go) contain the experimental +This file (together with pkg/apis/extensions/v1beta1/types.go) contain the experimental types in kubernetes. These API objects are experimental, meaning that the APIs may be broken at any time by the kubernetes team. @@ -26,11 +26,12 @@ beyond registration differences. In other words, experimental API group support is experimental. */ -package experimental +package extensions import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util" ) @@ -51,7 +52,7 @@ type ScaleStatus struct { // Scale subresource, applicable to ReplicationControllers and (in future) Deployment. type Scale struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata. api.ObjectMeta `json:"metadata,omitempty"` @@ -64,7 +65,7 @@ type Scale struct { // Dummy definition type ReplicationControllerDummy struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` } // SubresourceReference contains enough information to let you inspect or modify the referred subresource. @@ -92,10 +93,10 @@ type HorizontalPodAutoscalerSpec struct { // ScaleRef is a reference to Scale subresource. HorizontalPodAutoscaler will learn the current resource consumption from its status, // and will set the desired number of pods by modyfying its spec. ScaleRef *SubresourceReference `json:"scaleRef"` - // MinCount is the lower limit for the number of pods that can be set by the autoscaler. - MinCount int `json:"minCount"` - // MaxCount is the upper limit for the number of pods that can be set by the autoscaler. It cannot be smaller than MinCount. - MaxCount int `json:"maxCount"` + // MinReplicas is the lower limit for the number of pods that can be set by the autoscaler. + MinReplicas int `json:"minReplicas"` + // MaxReplicas is the upper limit for the number of pods that can be set by the autoscaler. It cannot be smaller than MinReplicas. + MaxReplicas int `json:"maxReplicas"` // Target is the target average consumption of the given resource that the autoscaler will try to maintain by adjusting the desired number of pods. // Currently two types of resources are supported: "cpu" and "memory". Target ResourceConsumption `json:"target"` @@ -117,25 +118,25 @@ type HorizontalPodAutoscalerStatus struct { // LastScaleTimestamp is the last time the HorizontalPodAutoscaler scaled the number of pods. // This is used by the autoscaler to controll how often the number of pods is changed. - LastScaleTimestamp *util.Time `json:"lastScaleTimestamp,omitempty"` + LastScaleTimestamp *unversioned.Time `json:"lastScaleTimestamp,omitempty"` } // HorizontalPodAutoscaler represents the configuration of a horizontal pod autoscaler. type HorizontalPodAutoscaler struct { - api.TypeMeta `json:",inline"` - api.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + api.ObjectMeta `json:"metadata,omitempty"` // Spec defines the behaviour of autoscaler. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty"` // Status represents the current information about the autoscaler. - Status *HorizontalPodAutoscalerStatus `json:"status,omitempty"` + Status HorizontalPodAutoscalerStatus `json:"status,omitempty"` } // HorizontalPodAutoscaler is a collection of pod autoscalers. type HorizontalPodAutoscalerList struct { - api.TypeMeta `json:",inline"` - api.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of horizontal pod autoscalers. Items []HorizontalPodAutoscaler `json:"items"` @@ -144,7 +145,7 @@ type HorizontalPodAutoscalerList struct { // A ThirdPartyResource is a generic representation of a resource, it is used by add-ons and plugins to add new resource // types to the API. It consists of one or more Versions of the api. type ThirdPartyResource struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object metadata api.ObjectMeta `json:"metadata,omitempty"` @@ -157,16 +158,17 @@ type ThirdPartyResource struct { } type ThirdPartyResourceList struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. - api.ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of horizontal pod autoscalers. Items []ThirdPartyResource `json:"items"` } // An APIVersion represents a single concrete version of an object model. +// TODO: we should consider merge this struct with GroupVersion in unversioned.go type APIVersion struct { // Name of this version (e.g. 'v1'). Name string `json:"name,omitempty"` @@ -177,7 +179,7 @@ type APIVersion struct { // An internal object, used for versioned storage in etcd. Not exposed to the end user. type ThirdPartyResourceData struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object metadata. api.ObjectMeta `json:"metadata,omitempty"` @@ -186,8 +188,8 @@ type ThirdPartyResourceData struct { } type Deployment struct { - api.TypeMeta `json:",inline"` - api.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + api.ObjectMeta `json:"metadata,omitempty"` // Specification of the desired behavior of the Deployment. Spec DeploymentSpec `json:"spec,omitempty"` @@ -202,7 +204,7 @@ type DeploymentSpec struct { Replicas int `json:"replicas,omitempty"` // Label selector for pods. Existing ReplicationControllers whose pods are - // selected by this will be scaled down. + // selected by this will be the ones affected by this deployment. Selector map[string]string `json:"selector,omitempty"` // Template describes the pods that will be created. @@ -224,9 +226,9 @@ type DeploymentSpec struct { type DeploymentStrategy struct { // Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate. - Type DeploymentType `json:"type,omitempty"` + Type DeploymentStrategyType `json:"type,omitempty"` - // Rolling update config params. Present only if DeploymentType = + // Rolling update config params. Present only if DeploymentStrategyType = // RollingUpdate. //--- // TODO: Update this to follow our convention for oneOf, whatever we decide it @@ -234,14 +236,14 @@ type DeploymentStrategy struct { RollingUpdate *RollingUpdateDeployment `json:"rollingUpdate,omitempty"` } -type DeploymentType string +type DeploymentStrategyType string const ( // Kill all existing pods before creating new ones. - DeploymentRecreate DeploymentType = "Recreate" + RecreateDeploymentStrategyType DeploymentStrategyType = "Recreate" // Replace the old RCs by new one using rolling update i.e gradually scale down the old RCs and scale up the new one. - DeploymentRollingUpdate DeploymentType = "RollingUpdate" + RollingUpdateDeploymentStrategyType DeploymentStrategyType = "RollingUpdate" ) // Spec to control the desired behavior of rolling update. @@ -277,17 +279,16 @@ type RollingUpdateDeployment struct { } type DeploymentStatus struct { - // Total number of ready pods targeted by this deployment (this - // includes both the old and new pods). + // Total number of non-terminated pods targeted by this deployment (their labels match the selector). Replicas int `json:"replicas,omitempty"` - // Total number of new ready pods with the desired template spec. + // Total number of non-terminated pods targeted by this deployment that have the desired template spec. UpdatedReplicas int `json:"updatedReplicas,omitempty"` } type DeploymentList struct { - api.TypeMeta `json:",inline"` - api.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of deployments. Items []Deployment `json:"items"` @@ -311,7 +312,7 @@ type DaemonSetSpec struct { // DaemonSetStatus represents the current status of a daemon set. type DaemonSetStatus struct { - // CurrentNumberScheduled is the number of nodes that are running exactly 1 + // CurrentNumberScheduled is the number of nodes that are running at least 1 // daemon pod and are supposed to run the daemon pod. CurrentNumberScheduled int `json:"currentNumberScheduled"` @@ -326,7 +327,7 @@ type DaemonSetStatus struct { // DaemonSet represents the configuration of a daemon set. type DaemonSet struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata api.ObjectMeta `json:"metadata,omitempty"` @@ -345,27 +346,27 @@ type DaemonSet struct { // DaemonSetList is a collection of daemon sets. type DaemonSetList struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata - api.ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of daemon sets. Items []DaemonSet `json:"items"` } type ThirdPartyResourceDataList struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata - api.ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of third party objects Items []ThirdPartyResourceData `json:"items"` } // Job represents the configuration of a single job. type Job struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata api.ObjectMeta `json:"metadata,omitempty"` @@ -381,10 +382,10 @@ type Job struct { // JobList is a collection of jobs. type JobList struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata - api.ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of Job. Items []Job `json:"items"` @@ -408,7 +409,7 @@ type JobSpec struct { // Template is the object that describes the pod that will be created when // executing a job. - Template *api.PodTemplateSpec `json:"template"` + Template api.PodTemplateSpec `json:"template"` } // JobStatus represents the current state of a Job. @@ -420,22 +421,21 @@ type JobStatus struct { // StartTime represents time when the job was acknowledged by the Job Manager. // It is not guaranteed to be set in happens-before order across separate operations. // It is represented in RFC3339 form and is in UTC. - StartTime *util.Time `json:"startTime,omitempty"` + StartTime *unversioned.Time `json:"startTime,omitempty"` // CompletionTime represents time when the job was completed. It is not guaranteed to // be set in happens-before order across separate operations. // It is represented in RFC3339 form and is in UTC. - CompletionTime *util.Time `json:"completionTime,omitempty"` + CompletionTime *unversioned.Time `json:"completionTime,omitempty"` // Active is the number of actively running pods. Active int `json:"active,omitempty"` - // Successful is the number of pods which reached Phase Succeeded. - Successful int `json:"successful,omitempty"` + // Succeeded is the number of pods which reached Phase Succeeded. + Succeeded int `json:"succeeded,omitempty"` - // Unsuccessful is the number of pods failures, this applies only to jobs - // created with RestartPolicyNever, otherwise this value will always be 0. - Unsuccessful int `json:"unsuccessful,omitempty"` + // Failed is the number of pods which reached Phase Failed. + Failed int `json:"failed,omitempty"` } type JobConditionType string @@ -453,11 +453,234 @@ type JobCondition struct { // Status of the condition, one of True, False, Unknown. Status api.ConditionStatus `json:"status"` // Last time the condition was checked. - LastProbeTime util.Time `json:"lastProbeTime,omitempty"` + LastProbeTime unversioned.Time `json:"lastProbeTime,omitempty"` // Last time the condition transit from one status to another. - LastTransitionTime util.Time `json:"lastTransitionTime,omitempty"` + LastTransitionTime unversioned.Time `json:"lastTransitionTime,omitempty"` // (brief) reason for the condition's last transition. Reason string `json:"reason,omitempty"` // Human readable message indicating details about last transition. Message string `json:"message,omitempty"` } + +// Ingress is a collection of rules that allow inbound connections to reach the +// endpoints defined by a backend. An Ingress can be configured to give services +// externally-reachable urls, load balance traffic, terminate SSL, offer name +// based virtual hosting etc. +type Ingress struct { + unversioned.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + api.ObjectMeta `json:"metadata,omitempty"` + + // Spec is the desired state of the Ingress. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + Spec IngressSpec `json:"spec,omitempty"` + + // Status is the current state of the Ingress. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + Status IngressStatus `json:"status,omitempty"` +} + +// IngressList is a collection of Ingress. +type IngressList struct { + unversioned.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + unversioned.ListMeta `json:"metadata,omitempty"` + + // Items is the list of Ingress. + Items []Ingress `json:"items"` +} + +// IngressSpec describes the Ingress the user wishes to exist. +type IngressSpec struct { + // A default backend capable of servicing requests that don't match any + // rule. At least one of 'backend' or 'rules' must be specified. This field + // is optional to allow the loadbalancer controller or defaulting logic to + // specify a global default. + Backend *IngressBackend `json:"backend,omitempty"` + // A list of host rules used to configure the Ingress. If unspecified, or + // no rule matches, all traffic is sent to the default backend. + Rules []IngressRule `json:"rules,omitempty"` + // TODO: Add the ability to specify load-balancer IP through claims +} + +// IngressStatus describe the current state of the Ingress. +type IngressStatus struct { + // LoadBalancer contains the current status of the load-balancer. + LoadBalancer api.LoadBalancerStatus `json:"loadBalancer,omitempty"` +} + +// IngressRule represents the rules mapping the paths under a specified host to +// the related backend services. Incoming requests are first evaluated for a host +// match, then routed to the backend associated with the matching IngressRuleValue. +type IngressRule struct { + // Host is the fully qualified domain name of a network host, as defined + // by RFC 3986. Note the following deviations from the "host" part of the + // URI as defined in the RFC: + // 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the + // IP in the Spec of the parent Ingress. + // 2. The `:` delimiter is not respected because ports are not allowed. + // Currently the port of an Ingress is implicitly :80 for http and + // :443 for https. + // Both these may change in the future. + // Incoming requests are matched against the host before the IngressRuleValue. + // If the host is unspecified, the Ingress routes all traffic based on the + // specified IngressRuleValue. + Host string `json:"host,omitempty"` + // IngressRuleValue represents a rule to route requests for this IngressRule. + // If unspecified, the rule defaults to a http catch-all. Whether that sends + // just traffic matching the host to the default backend or all traffic to the + // default backend, is left to the controller fulfilling the Ingress. Http is + // currently the only supported IngressRuleValue. + IngressRuleValue `json:",inline,omitempty"` +} + +// IngressRuleValue represents a rule to apply against incoming requests. If the +// rule is satisfied, the request is routed to the specified backend. Currently +// mixing different types of rules in a single Ingress is disallowed, so exactly +// one of the following must be set. +type IngressRuleValue struct { + //TODO: + // 1. Consider renaming this resource and the associated rules so they + // aren't tied to Ingress. They can be used to route intra-cluster traffic. + // 2. Consider adding fields for ingress-type specific global options + // usable by a loadbalancer, like http keep-alive. + + HTTP *HTTPIngressRuleValue `json:"http,omitempty"` +} + +// HTTPIngressRuleValue is a list of http selectors pointing to backends. +// In the example: http:///? -> backend where +// where parts of the url correspond to RFC 3986, this resource will be used +// to match against everything after the last '/' and before the first '?' +// or '#'. +type HTTPIngressRuleValue struct { + // A collection of paths that map requests to backends. + Paths []HTTPIngressPath `json:"paths"` + // TODO: Consider adding fields for ingress-type specific global + // options usable by a loadbalancer, like http keep-alive. +} + +// HTTPIngressPath associates a path regex with a backend. Incoming urls matching +// the path are forwarded to the backend. +type HTTPIngressPath struct { + // Path is a extended POSIX regex as defined by IEEE Std 1003.1, + // (i.e this follows the egrep/unix syntax, not the perl syntax) + // matched against the path of an incoming request. Currently it can + // contain characters disallowed from the conventional "path" + // part of a URL as defined by RFC 3986. Paths must begin with + // a '/'. If unspecified, the path defaults to a catch all sending + // traffic to the backend. + Path string `json:"path,omitempty"` + + // Backend defines the referenced service endpoint to which the traffic + // will be forwarded to. + Backend IngressBackend `json:"backend"` +} + +// IngressBackend describes all endpoints for a given service and port. +type IngressBackend struct { + // Specifies the name of the referenced service. + ServiceName string `json:"serviceName"` + + // Specifies the port of the referenced service. + ServicePort util.IntOrString `json:"servicePort"` +} + +type NodeResource string + +const ( + // Percentage of node's CPUs that is currently used. + CpuConsumption NodeResource = "CpuConsumption" + + // Percentage of node's CPUs that is currently requested for pods. + CpuRequest NodeResource = "CpuRequest" + + // Percentage od node's memory that is currently used. + MemConsumption NodeResource = "MemConsumption" + + // Percentage of node's CPUs that is currently requested for pods. + MemRequest NodeResource = "MemRequest" +) + +// NodeUtilization describes what percentage of a particular resource is used on a node. +type NodeUtilization struct { + Resource NodeResource `json:"resource"` + + // The accepted values are from 0 to 1. + Value float64 `json:"value"` +} + +// Configuration of the Cluster Autoscaler +type ClusterAutoscalerSpec struct { + // Minimum number of nodes that the cluster should have. + MinNodes int `json:"minNodes"` + + // Maximum number of nodes that the cluster should have. + MaxNodes int `json:"maxNodes"` + + // Target average utilization of the cluster nodes. New nodes will be added if one of the + // targets is exceeded. Cluster size will be decreased if the current utilization is too low + // for all targets. + TargetUtilization []NodeUtilization `json:"target"` +} + +type ClusterAutoscaler struct { + unversioned.TypeMeta `json:",inline"` + + // Standard object's metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // For now (experimental api) it is required that the name is set to "ClusterAutoscaler" and namespace is "default". + api.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired behavior of this daemon set. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + Spec ClusterAutoscalerSpec `json:"spec,omitempty"` +} + +// There will be just one (or none) ClusterAutoscaler. +type ClusterAutoscalerList struct { + unversioned.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + unversioned.ListMeta `json:"metadata,omitempty"` + + Items []ClusterAutoscaler `json:"items"` +} + +// A pod selector is a label query over a set of pods. The result of matchLabels and +// matchExpressions are ANDed. An empty pod selector matches all objects. A null +// pod selector matches no objects. +type PodSelector struct { + // matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + // map is equivalent to an element of matchExpressions, whose key field is "key", the + // operator is "In", and the values array contains only "value". The requirements are ANDed. + MatchLabels map[string]string `json:"matchLabels,omitempty"` + // matchExpressions is a list of pod selector requirements. The requirements are ANDed. + MatchExpressions []PodSelectorRequirement `json:"matchExpressions,omitempty"` +} + +// A pod selector requirement is a selector that contains values, a key and an operator that +// relates the key and values. +type PodSelectorRequirement struct { + // key is the label key that the selector applies to. + Key string `json:"key" patchStrategy:"merge" patchMergeKey:"key"` + // operator represents a key's relationship to a set of values. + // Valid operators ard In, NotIn, Exists and DoesNotExist. + Operator PodSelectorOperator `json:"operator"` + // values is a set of string values. If the operator is In or NotIn, + // the values set must be non-empty. This array is replaced during a + // strategic merge patch. + Values []string `json:"stringValues,omitempty"` +} + +// A pod selector operator is the set of operators that can be used in a selector requirement. +type PodSelectorOperator string + +const ( + PodSelectorOpIn PodSelectorOperator = "In" + PodSelectorOpNotIn PodSelectorOperator = "NotIn" + PodSelectorOpExists PodSelectorOperator = "Exists" + PodSelectorOpDoesNotExist PodSelectorOperator = "DoesNotExist" +) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/conversion.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion.go similarity index 56% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/conversion.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion.go index fda03fb9607c..0f6ffac777e9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/conversion.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion.go @@ -14,14 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1 +package v1beta1 import ( "reflect" "k8s.io/kubernetes/pkg/api" v1 "k8s.io/kubernetes/pkg/api/v1" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/util" ) @@ -31,14 +31,12 @@ func addConversionFuncs() { err := api.Scheme.AddConversionFuncs( convert_api_PodSpec_To_v1_PodSpec, convert_v1_PodSpec_To_api_PodSpec, - convert_api_VolumeSource_To_v1_VolumeSource, - convert_experimental_DeploymentSpec_To_v1_DeploymentSpec, - convert_v1_DeploymentSpec_To_experimental_DeploymentSpec, - convert_experimental_DeploymentStrategy_To_v1_DeploymentStrategy, - convert_v1_DeploymentStrategy_To_experimental_DeploymentStrategy, - convert_experimental_RollingUpdateDeployment_To_v1_RollingUpdateDeployment, - convert_v1_RollingUpdateDeployment_To_experimental_RollingUpdateDeployment, - convert_v1_VolumeSource_To_api_VolumeSource, + convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec, + convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec, + convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy, + convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy, + convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment, + convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. @@ -99,9 +97,16 @@ func convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *v1.PodSpec, s conve // DeprecatedServiceAccount is an alias for ServiceAccountName. out.DeprecatedServiceAccount = in.ServiceAccountName out.NodeName = in.NodeName - out.HostNetwork = in.HostNetwork - out.HostPID = in.HostPID - out.HostIPC = in.HostIPC + if in.SecurityContext != nil { + out.SecurityContext = new(v1.PodSecurityContext) + if err := convert_api_PodSecurityContext_To_v1_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { + return err + } + + out.HostNetwork = in.SecurityContext.HostNetwork + out.HostPID = in.SecurityContext.HostPID + out.HostIPC = in.SecurityContext.HostIPC + } if in.ImagePullSecrets != nil { out.ImagePullSecrets = make([]v1.LocalObjectReference, len(in.ImagePullSecrets)) for i := range in.ImagePullSecrets { @@ -168,9 +173,19 @@ func convert_v1_PodSpec_To_api_PodSpec(in *v1.PodSpec, out *api.PodSpec, s conve out.ServiceAccountName = in.DeprecatedServiceAccount } out.NodeName = in.NodeName - out.HostNetwork = in.HostNetwork - out.HostPID = in.HostPID - out.HostIPC = in.HostIPC + + if in.SecurityContext != nil { + out.SecurityContext = new(api.PodSecurityContext) + if err := convert_v1_PodSecurityContext_To_api_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { + return err + } + } + if out.SecurityContext == nil { + out.SecurityContext = new(api.PodSecurityContext) + } + out.SecurityContext.HostNetwork = in.HostNetwork + out.SecurityContext.HostPID = in.HostPID + out.SecurityContext.HostIPC = in.HostIPC if in.ImagePullSecrets != nil { out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets)) for i := range in.ImagePullSecrets { @@ -184,9 +199,9 @@ func convert_v1_PodSpec_To_api_PodSpec(in *v1.PodSpec, out *api.PodSpec, s conve return nil } -func convert_experimental_DeploymentSpec_To_v1_DeploymentSpec(in *experimental.DeploymentSpec, out *DeploymentSpec, s conversion.Scope) error { +func convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensions.DeploymentSpec, out *DeploymentSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.DeploymentSpec))(in) + defaulting.(func(*extensions.DeploymentSpec))(in) } out.Replicas = new(int) *out.Replicas = in.Replicas @@ -206,7 +221,7 @@ func convert_experimental_DeploymentSpec_To_v1_DeploymentSpec(in *experimental.D } else { out.Template = nil } - if err := convert_experimental_DeploymentStrategy_To_v1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } out.UniqueLabelKey = new(string) @@ -214,7 +229,7 @@ func convert_experimental_DeploymentSpec_To_v1_DeploymentSpec(in *experimental.D return nil } -func convert_v1_DeploymentSpec_To_experimental_DeploymentSpec(in *DeploymentSpec, out *experimental.DeploymentSpec, s conversion.Scope) error { +func convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *DeploymentSpec, out *extensions.DeploymentSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*DeploymentSpec))(in) } @@ -237,7 +252,7 @@ func convert_v1_DeploymentSpec_To_experimental_DeploymentSpec(in *DeploymentSpec } else { out.Template = nil } - if err := convert_v1_DeploymentStrategy_To_experimental_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + if err := convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { return err } if in.UniqueLabelKey != nil { @@ -246,14 +261,14 @@ func convert_v1_DeploymentSpec_To_experimental_DeploymentSpec(in *DeploymentSpec return nil } -func convert_experimental_DeploymentStrategy_To_v1_DeploymentStrategy(in *experimental.DeploymentStrategy, out *DeploymentStrategy, s conversion.Scope) error { +func convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *extensions.DeploymentStrategy, out *DeploymentStrategy, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.DeploymentStrategy))(in) + defaulting.(func(*extensions.DeploymentStrategy))(in) } - out.Type = DeploymentType(in.Type) + out.Type = DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { out.RollingUpdate = new(RollingUpdateDeployment) - if err := convert_experimental_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + if err := convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } else { @@ -262,14 +277,14 @@ func convert_experimental_DeploymentStrategy_To_v1_DeploymentStrategy(in *experi return nil } -func convert_v1_DeploymentStrategy_To_experimental_DeploymentStrategy(in *DeploymentStrategy, out *experimental.DeploymentStrategy, s conversion.Scope) error { +func convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(in *DeploymentStrategy, out *extensions.DeploymentStrategy, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*DeploymentStrategy))(in) } - out.Type = experimental.DeploymentType(in.Type) + out.Type = extensions.DeploymentStrategyType(in.Type) if in.RollingUpdate != nil { - out.RollingUpdate = new(experimental.RollingUpdateDeployment) - if err := convert_v1_RollingUpdateDeployment_To_experimental_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + out.RollingUpdate = new(extensions.RollingUpdateDeployment) + if err := convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { return err } } else { @@ -278,9 +293,9 @@ func convert_v1_DeploymentStrategy_To_experimental_DeploymentStrategy(in *Deploy return nil } -func convert_experimental_RollingUpdateDeployment_To_v1_RollingUpdateDeployment(in *experimental.RollingUpdateDeployment, out *RollingUpdateDeployment, s conversion.Scope) error { +func convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in *extensions.RollingUpdateDeployment, out *RollingUpdateDeployment, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*experimental.RollingUpdateDeployment))(in) + defaulting.(func(*extensions.RollingUpdateDeployment))(in) } if out.MaxUnavailable == nil { out.MaxUnavailable = &util.IntOrString{} @@ -298,7 +313,7 @@ func convert_experimental_RollingUpdateDeployment_To_v1_RollingUpdateDeployment( return nil } -func convert_v1_RollingUpdateDeployment_To_experimental_RollingUpdateDeployment(in *RollingUpdateDeployment, out *experimental.RollingUpdateDeployment, s conversion.Scope) error { +func convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in *RollingUpdateDeployment, out *extensions.RollingUpdateDeployment, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*RollingUpdateDeployment))(in) } @@ -312,114 +327,16 @@ func convert_v1_RollingUpdateDeployment_To_experimental_RollingUpdateDeployment( return nil } -// This will convert our internal represantation of VolumeSource to its v1 representation -// Used for keeping backwards compatibility for the Metadata field -func convert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *v1.VolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.VolumeSource))(in) - } - - if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { - return err - } - - if in.DownwardAPI != nil { - out.DownwardAPI = new(v1.DownwardAPIVolumeSource) - if err := convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in.DownwardAPI, out.DownwardAPI, s); err != nil { - return err - } - - // also copy to Metadata - out.Metadata = new(v1.MetadataVolumeSource) - if err := convert_api_DownwardAPIVolumeSource_To_v1_MetadataVolumeSource(in.DownwardAPI, out.Metadata, s); err != nil { - return err - } - } else { - out.DownwardAPI = nil - } - return nil -} - -// downward -> metadata (api -> v1) -func convert_api_DownwardAPIVolumeSource_To_v1_MetadataVolumeSource(in *api.DownwardAPIVolumeSource, out *v1.MetadataVolumeSource, s conversion.Scope) error { +func convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *v1.PodSecurityContext, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.DownwardAPIVolumeSource))(in) - } - if in.Items != nil { - out.Items = make([]v1.MetadataFile, len(in.Items)) - for i := range in.Items { - if err := convert_api_DownwardAPIVolumeFile_To_v1_MetadataFile(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } + defaulting.(func(*api.PodSecurityContext))(in) } return nil } -func convert_api_DownwardAPIVolumeFile_To_v1_MetadataFile(in *api.DownwardAPIVolumeFile, out *v1.MetadataFile, s conversion.Scope) error { +func convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *v1.PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.DownwardAPIVolumeFile))(in) - } - out.Name = in.Path - if err := convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { - return err - } - return nil -} - -// This will convert the v1 representation of VolumeSource to our internal representation -// Used for keeping backwards compatibility for the Metadata field -func convert_v1_VolumeSource_To_api_VolumeSource(in *v1.VolumeSource, out *api.VolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.VolumeSource))(in) - } - - if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { - return err - } - - // if specified Metadata will stomp DownwardAPI - if in.Metadata != nil { - out.DownwardAPI = new(api.DownwardAPIVolumeSource) - if err := convert_v1_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in.Metadata, out.DownwardAPI, s); err != nil { - return err - } - } else { - if in.DownwardAPI != nil { - out.DownwardAPI = new(api.DownwardAPIVolumeSource) - if err := convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in.DownwardAPI, out.DownwardAPI, s); err != nil { - return err - } - } else { - out.DownwardAPI = nil - } - } - return nil -} - -// metadata -> downward (v1 -> api) -func convert_v1_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in *v1.MetadataVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.MetadataVolumeSource))(in) - } - if in.Items != nil { - out.Items = make([]api.DownwardAPIVolumeFile, len(in.Items)) - for i := range in.Items { - if err := convert_v1_MetadataFile_To_api_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { - return err - } - } - } - return nil -} - -func convert_v1_MetadataFile_To_api_DownwardAPIVolumeFile(in *v1.MetadataFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1.MetadataFile))(in) - } - out.Path = in.Name - if err := convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { - return err + defaulting.(func(*v1.PodSecurityContext))(in) } return nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion_generated.go new file mode 100644 index 000000000000..51465c728bb2 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion_generated.go @@ -0,0 +1,4159 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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. +*/ + +// DO NOT EDIT. THIS FILE IS AUTO-GENERATED BY $KUBEROOT/hack/update-generated-conversions.sh + +package v1beta1 + +import ( + reflect "reflect" + + api "k8s.io/kubernetes/pkg/api" + resource "k8s.io/kubernetes/pkg/api/resource" + v1 "k8s.io/kubernetes/pkg/api/v1" + extensions "k8s.io/kubernetes/pkg/apis/extensions" + conversion "k8s.io/kubernetes/pkg/conversion" +) + +func autoconvert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in *api.AWSElasticBlockStoreVolumeSource, out *v1.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.AWSElasticBlockStoreVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in *api.AWSElasticBlockStoreVolumeSource, out *v1.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { + return autoconvert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in, out, s) +} + +func autoconvert_api_Capabilities_To_v1_Capabilities(in *api.Capabilities, out *v1.Capabilities, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Capabilities))(in) + } + if in.Add != nil { + out.Add = make([]v1.Capability, len(in.Add)) + for i := range in.Add { + out.Add[i] = v1.Capability(in.Add[i]) + } + } else { + out.Add = nil + } + if in.Drop != nil { + out.Drop = make([]v1.Capability, len(in.Drop)) + for i := range in.Drop { + out.Drop[i] = v1.Capability(in.Drop[i]) + } + } else { + out.Drop = nil + } + return nil +} + +func convert_api_Capabilities_To_v1_Capabilities(in *api.Capabilities, out *v1.Capabilities, s conversion.Scope) error { + return autoconvert_api_Capabilities_To_v1_Capabilities(in, out, s) +} + +func autoconvert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in *api.CephFSVolumeSource, out *v1.CephFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.CephFSVolumeSource))(in) + } + if in.Monitors != nil { + out.Monitors = make([]string, len(in.Monitors)) + for i := range in.Monitors { + out.Monitors[i] = in.Monitors[i] + } + } else { + out.Monitors = nil + } + out.User = in.User + out.SecretFile = in.SecretFile + if in.SecretRef != nil { + out.SecretRef = new(v1.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in *api.CephFSVolumeSource, out *v1.CephFSVolumeSource, s conversion.Scope) error { + return autoconvert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in, out, s) +} + +func autoconvert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in *api.CinderVolumeSource, out *v1.CinderVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.CinderVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in *api.CinderVolumeSource, out *v1.CinderVolumeSource, s conversion.Scope) error { + return autoconvert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in, out, s) +} + +func autoconvert_api_Container_To_v1_Container(in *api.Container, out *v1.Container, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Container))(in) + } + out.Name = in.Name + out.Image = in.Image + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + if in.Args != nil { + out.Args = make([]string, len(in.Args)) + for i := range in.Args { + out.Args[i] = in.Args[i] + } + } else { + out.Args = nil + } + out.WorkingDir = in.WorkingDir + if in.Ports != nil { + out.Ports = make([]v1.ContainerPort, len(in.Ports)) + for i := range in.Ports { + if err := convert_api_ContainerPort_To_v1_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.Env != nil { + out.Env = make([]v1.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_api_EnvVar_To_v1_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + if err := convert_api_ResourceRequirements_To_v1_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { + return err + } + if in.VolumeMounts != nil { + out.VolumeMounts = make([]v1.VolumeMount, len(in.VolumeMounts)) + for i := range in.VolumeMounts { + if err := convert_api_VolumeMount_To_v1_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { + return err + } + } + } else { + out.VolumeMounts = nil + } + if in.LivenessProbe != nil { + out.LivenessProbe = new(v1.Probe) + if err := convert_api_Probe_To_v1_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { + return err + } + } else { + out.LivenessProbe = nil + } + if in.ReadinessProbe != nil { + out.ReadinessProbe = new(v1.Probe) + if err := convert_api_Probe_To_v1_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { + return err + } + } else { + out.ReadinessProbe = nil + } + if in.Lifecycle != nil { + out.Lifecycle = new(v1.Lifecycle) + if err := convert_api_Lifecycle_To_v1_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { + return err + } + } else { + out.Lifecycle = nil + } + out.TerminationMessagePath = in.TerminationMessagePath + out.ImagePullPolicy = v1.PullPolicy(in.ImagePullPolicy) + if in.SecurityContext != nil { + out.SecurityContext = new(v1.SecurityContext) + if err := convert_api_SecurityContext_To_v1_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + out.Stdin = in.Stdin + out.TTY = in.TTY + return nil +} + +func convert_api_Container_To_v1_Container(in *api.Container, out *v1.Container, s conversion.Scope) error { + return autoconvert_api_Container_To_v1_Container(in, out, s) +} + +func autoconvert_api_ContainerPort_To_v1_ContainerPort(in *api.ContainerPort, out *v1.ContainerPort, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ContainerPort))(in) + } + out.Name = in.Name + out.HostPort = in.HostPort + out.ContainerPort = in.ContainerPort + out.Protocol = v1.Protocol(in.Protocol) + out.HostIP = in.HostIP + return nil +} + +func convert_api_ContainerPort_To_v1_ContainerPort(in *api.ContainerPort, out *v1.ContainerPort, s conversion.Scope) error { + return autoconvert_api_ContainerPort_To_v1_ContainerPort(in, out, s) +} + +func autoconvert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in *api.DownwardAPIVolumeFile, out *v1.DownwardAPIVolumeFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeFile))(in) + } + out.Path = in.Path + if err := convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + return nil +} + +func convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in *api.DownwardAPIVolumeFile, out *v1.DownwardAPIVolumeFile, s conversion.Scope) error { + return autoconvert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in, out, s) +} + +func autoconvert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in *api.DownwardAPIVolumeSource, out *v1.DownwardAPIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]v1.DownwardAPIVolumeFile, len(in.Items)) + for i := range in.Items { + if err := convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in *api.DownwardAPIVolumeSource, out *v1.DownwardAPIVolumeSource, s conversion.Scope) error { + return autoconvert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in, out, s) +} + +func autoconvert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in *api.EmptyDirVolumeSource, out *v1.EmptyDirVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EmptyDirVolumeSource))(in) + } + out.Medium = v1.StorageMedium(in.Medium) + return nil +} + +func convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in *api.EmptyDirVolumeSource, out *v1.EmptyDirVolumeSource, s conversion.Scope) error { + return autoconvert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in, out, s) +} + +func autoconvert_api_EnvVar_To_v1_EnvVar(in *api.EnvVar, out *v1.EnvVar, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EnvVar))(in) + } + out.Name = in.Name + out.Value = in.Value + if in.ValueFrom != nil { + out.ValueFrom = new(v1.EnvVarSource) + if err := convert_api_EnvVarSource_To_v1_EnvVarSource(in.ValueFrom, out.ValueFrom, s); err != nil { + return err + } + } else { + out.ValueFrom = nil + } + return nil +} + +func convert_api_EnvVar_To_v1_EnvVar(in *api.EnvVar, out *v1.EnvVar, s conversion.Scope) error { + return autoconvert_api_EnvVar_To_v1_EnvVar(in, out, s) +} + +func autoconvert_api_EnvVarSource_To_v1_EnvVarSource(in *api.EnvVarSource, out *v1.EnvVarSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EnvVarSource))(in) + } + if in.FieldRef != nil { + out.FieldRef = new(v1.ObjectFieldSelector) + if err := convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in.FieldRef, out.FieldRef, s); err != nil { + return err + } + } else { + out.FieldRef = nil + } + return nil +} + +func convert_api_EnvVarSource_To_v1_EnvVarSource(in *api.EnvVarSource, out *v1.EnvVarSource, s conversion.Scope) error { + return autoconvert_api_EnvVarSource_To_v1_EnvVarSource(in, out, s) +} + +func autoconvert_api_ExecAction_To_v1_ExecAction(in *api.ExecAction, out *v1.ExecAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ExecAction))(in) + } + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + return nil +} + +func convert_api_ExecAction_To_v1_ExecAction(in *api.ExecAction, out *v1.ExecAction, s conversion.Scope) error { + return autoconvert_api_ExecAction_To_v1_ExecAction(in, out, s) +} + +func autoconvert_api_FCVolumeSource_To_v1_FCVolumeSource(in *api.FCVolumeSource, out *v1.FCVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.FCVolumeSource))(in) + } + if in.TargetWWNs != nil { + out.TargetWWNs = make([]string, len(in.TargetWWNs)) + for i := range in.TargetWWNs { + out.TargetWWNs[i] = in.TargetWWNs[i] + } + } else { + out.TargetWWNs = nil + } + if in.Lun != nil { + out.Lun = new(int) + *out.Lun = *in.Lun + } else { + out.Lun = nil + } + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_FCVolumeSource_To_v1_FCVolumeSource(in *api.FCVolumeSource, out *v1.FCVolumeSource, s conversion.Scope) error { + return autoconvert_api_FCVolumeSource_To_v1_FCVolumeSource(in, out, s) +} + +func autoconvert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource(in *api.FlockerVolumeSource, out *v1.FlockerVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.FlockerVolumeSource))(in) + } + out.DatasetName = in.DatasetName + return nil +} + +func convert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource(in *api.FlockerVolumeSource, out *v1.FlockerVolumeSource, s conversion.Scope) error { + return autoconvert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource(in, out, s) +} + +func autoconvert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in *api.GCEPersistentDiskVolumeSource, out *v1.GCEPersistentDiskVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.GCEPersistentDiskVolumeSource))(in) + } + out.PDName = in.PDName + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in *api.GCEPersistentDiskVolumeSource, out *v1.GCEPersistentDiskVolumeSource, s conversion.Scope) error { + return autoconvert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in, out, s) +} + +func autoconvert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in *api.GitRepoVolumeSource, out *v1.GitRepoVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.GitRepoVolumeSource))(in) + } + out.Repository = in.Repository + out.Revision = in.Revision + return nil +} + +func convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in *api.GitRepoVolumeSource, out *v1.GitRepoVolumeSource, s conversion.Scope) error { + return autoconvert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in, out, s) +} + +func autoconvert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in *api.GlusterfsVolumeSource, out *v1.GlusterfsVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.GlusterfsVolumeSource))(in) + } + out.EndpointsName = in.EndpointsName + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in *api.GlusterfsVolumeSource, out *v1.GlusterfsVolumeSource, s conversion.Scope) error { + return autoconvert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in, out, s) +} + +func autoconvert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, out *v1.HTTPGetAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.HTTPGetAction))(in) + } + out.Path = in.Path + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + out.Host = in.Host + out.Scheme = v1.URIScheme(in.Scheme) + return nil +} + +func convert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, out *v1.HTTPGetAction, s conversion.Scope) error { + return autoconvert_api_HTTPGetAction_To_v1_HTTPGetAction(in, out, s) +} + +func autoconvert_api_Handler_To_v1_Handler(in *api.Handler, out *v1.Handler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Handler))(in) + } + if in.Exec != nil { + out.Exec = new(v1.ExecAction) + if err := convert_api_ExecAction_To_v1_ExecAction(in.Exec, out.Exec, s); err != nil { + return err + } + } else { + out.Exec = nil + } + if in.HTTPGet != nil { + out.HTTPGet = new(v1.HTTPGetAction) + if err := convert_api_HTTPGetAction_To_v1_HTTPGetAction(in.HTTPGet, out.HTTPGet, s); err != nil { + return err + } + } else { + out.HTTPGet = nil + } + if in.TCPSocket != nil { + out.TCPSocket = new(v1.TCPSocketAction) + if err := convert_api_TCPSocketAction_To_v1_TCPSocketAction(in.TCPSocket, out.TCPSocket, s); err != nil { + return err + } + } else { + out.TCPSocket = nil + } + return nil +} + +func convert_api_Handler_To_v1_Handler(in *api.Handler, out *v1.Handler, s conversion.Scope) error { + return autoconvert_api_Handler_To_v1_Handler(in, out, s) +} + +func autoconvert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in *api.HostPathVolumeSource, out *v1.HostPathVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.HostPathVolumeSource))(in) + } + out.Path = in.Path + return nil +} + +func convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in *api.HostPathVolumeSource, out *v1.HostPathVolumeSource, s conversion.Scope) error { + return autoconvert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in, out, s) +} + +func autoconvert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in *api.ISCSIVolumeSource, out *v1.ISCSIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ISCSIVolumeSource))(in) + } + out.TargetPortal = in.TargetPortal + out.IQN = in.IQN + out.Lun = in.Lun + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in *api.ISCSIVolumeSource, out *v1.ISCSIVolumeSource, s conversion.Scope) error { + return autoconvert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in, out, s) +} + +func autoconvert_api_Lifecycle_To_v1_Lifecycle(in *api.Lifecycle, out *v1.Lifecycle, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Lifecycle))(in) + } + if in.PostStart != nil { + out.PostStart = new(v1.Handler) + if err := convert_api_Handler_To_v1_Handler(in.PostStart, out.PostStart, s); err != nil { + return err + } + } else { + out.PostStart = nil + } + if in.PreStop != nil { + out.PreStop = new(v1.Handler) + if err := convert_api_Handler_To_v1_Handler(in.PreStop, out.PreStop, s); err != nil { + return err + } + } else { + out.PreStop = nil + } + return nil +} + +func convert_api_Lifecycle_To_v1_Lifecycle(in *api.Lifecycle, out *v1.Lifecycle, s conversion.Scope) error { + return autoconvert_api_Lifecycle_To_v1_Lifecycle(in, out, s) +} + +func autoconvert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress(in *api.LoadBalancerIngress, out *v1.LoadBalancerIngress, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LoadBalancerIngress))(in) + } + out.IP = in.IP + out.Hostname = in.Hostname + return nil +} + +func convert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress(in *api.LoadBalancerIngress, out *v1.LoadBalancerIngress, s conversion.Scope) error { + return autoconvert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress(in, out, s) +} + +func autoconvert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus(in *api.LoadBalancerStatus, out *v1.LoadBalancerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LoadBalancerStatus))(in) + } + if in.Ingress != nil { + out.Ingress = make([]v1.LoadBalancerIngress, len(in.Ingress)) + for i := range in.Ingress { + if err := convert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress(&in.Ingress[i], &out.Ingress[i], s); err != nil { + return err + } + } + } else { + out.Ingress = nil + } + return nil +} + +func convert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus(in *api.LoadBalancerStatus, out *v1.LoadBalancerStatus, s conversion.Scope) error { + return autoconvert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus(in, out, s) +} + +func autoconvert_api_LocalObjectReference_To_v1_LocalObjectReference(in *api.LocalObjectReference, out *v1.LocalObjectReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LocalObjectReference))(in) + } + out.Name = in.Name + return nil +} + +func convert_api_LocalObjectReference_To_v1_LocalObjectReference(in *api.LocalObjectReference, out *v1.LocalObjectReference, s conversion.Scope) error { + return autoconvert_api_LocalObjectReference_To_v1_LocalObjectReference(in, out, s) +} + +func autoconvert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in *api.NFSVolumeSource, out *v1.NFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NFSVolumeSource))(in) + } + out.Server = in.Server + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in *api.NFSVolumeSource, out *v1.NFSVolumeSource, s conversion.Scope) error { + return autoconvert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in, out, s) +} + +func autoconvert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *api.ObjectFieldSelector, out *v1.ObjectFieldSelector, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ObjectFieldSelector))(in) + } + out.APIVersion = in.APIVersion + out.FieldPath = in.FieldPath + return nil +} + +func convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *api.ObjectFieldSelector, out *v1.ObjectFieldSelector, s conversion.Scope) error { + return autoconvert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in, out, s) +} + +func autoconvert_api_ObjectMeta_To_v1_ObjectMeta(in *api.ObjectMeta, out *v1.ObjectMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ObjectMeta))(in) + } + out.Name = in.Name + out.GenerateName = in.GenerateName + out.Namespace = in.Namespace + out.SelfLink = in.SelfLink + out.UID = in.UID + out.ResourceVersion = in.ResourceVersion + out.Generation = in.Generation + if err := s.Convert(&in.CreationTimestamp, &out.CreationTimestamp, 0); err != nil { + return err + } + if in.DeletionTimestamp != nil { + if err := s.Convert(&in.DeletionTimestamp, &out.DeletionTimestamp, 0); err != nil { + return err + } + } else { + out.DeletionTimestamp = nil + } + if in.DeletionGracePeriodSeconds != nil { + out.DeletionGracePeriodSeconds = new(int64) + *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds + } else { + out.DeletionGracePeriodSeconds = nil + } + if in.Labels != nil { + out.Labels = make(map[string]string) + for key, val := range in.Labels { + out.Labels[key] = val + } + } else { + out.Labels = nil + } + if in.Annotations != nil { + out.Annotations = make(map[string]string) + for key, val := range in.Annotations { + out.Annotations[key] = val + } + } else { + out.Annotations = nil + } + return nil +} + +func convert_api_ObjectMeta_To_v1_ObjectMeta(in *api.ObjectMeta, out *v1.ObjectMeta, s conversion.Scope) error { + return autoconvert_api_ObjectMeta_To_v1_ObjectMeta(in, out, s) +} + +func autoconvert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in *api.PersistentVolumeClaimVolumeSource, out *v1.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolumeClaimVolumeSource))(in) + } + out.ClaimName = in.ClaimName + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in *api.PersistentVolumeClaimVolumeSource, out *v1.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { + return autoconvert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in, out, s) +} + +func autoconvert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *v1.PodSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodSpec))(in) + } + if in.Volumes != nil { + out.Volumes = make([]v1.Volume, len(in.Volumes)) + for i := range in.Volumes { + if err := convert_api_Volume_To_v1_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil { + return err + } + } + } else { + out.Volumes = nil + } + if in.Containers != nil { + out.Containers = make([]v1.Container, len(in.Containers)) + for i := range in.Containers { + if err := convert_api_Container_To_v1_Container(&in.Containers[i], &out.Containers[i], s); err != nil { + return err + } + } + } else { + out.Containers = nil + } + out.RestartPolicy = v1.RestartPolicy(in.RestartPolicy) + if in.TerminationGracePeriodSeconds != nil { + out.TerminationGracePeriodSeconds = new(int64) + *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds + } else { + out.TerminationGracePeriodSeconds = nil + } + if in.ActiveDeadlineSeconds != nil { + out.ActiveDeadlineSeconds = new(int64) + *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds + } else { + out.ActiveDeadlineSeconds = nil + } + out.DNSPolicy = v1.DNSPolicy(in.DNSPolicy) + if in.NodeSelector != nil { + out.NodeSelector = make(map[string]string) + for key, val := range in.NodeSelector { + out.NodeSelector[key] = val + } + } else { + out.NodeSelector = nil + } + out.ServiceAccountName = in.ServiceAccountName + out.NodeName = in.NodeName + if in.SecurityContext != nil { + if err := s.Convert(&in.SecurityContext, &out.SecurityContext, 0); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + if in.ImagePullSecrets != nil { + out.ImagePullSecrets = make([]v1.LocalObjectReference, len(in.ImagePullSecrets)) + for i := range in.ImagePullSecrets { + if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { + return err + } + } + } else { + out.ImagePullSecrets = nil + } + return nil +} + +func autoconvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *v1.PodTemplateSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodTemplateSpec))(in) + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_PodSpec_To_v1_PodSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *v1.PodTemplateSpec, s conversion.Scope) error { + return autoconvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s) +} + +func autoconvert_api_Probe_To_v1_Probe(in *api.Probe, out *v1.Probe, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Probe))(in) + } + if err := convert_api_Handler_To_v1_Handler(&in.Handler, &out.Handler, s); err != nil { + return err + } + out.InitialDelaySeconds = in.InitialDelaySeconds + out.TimeoutSeconds = in.TimeoutSeconds + return nil +} + +func convert_api_Probe_To_v1_Probe(in *api.Probe, out *v1.Probe, s conversion.Scope) error { + return autoconvert_api_Probe_To_v1_Probe(in, out, s) +} + +func autoconvert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in *api.RBDVolumeSource, out *v1.RBDVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.RBDVolumeSource))(in) + } + if in.CephMonitors != nil { + out.CephMonitors = make([]string, len(in.CephMonitors)) + for i := range in.CephMonitors { + out.CephMonitors[i] = in.CephMonitors[i] + } + } else { + out.CephMonitors = nil + } + out.RBDImage = in.RBDImage + out.FSType = in.FSType + out.RBDPool = in.RBDPool + out.RadosUser = in.RadosUser + out.Keyring = in.Keyring + if in.SecretRef != nil { + out.SecretRef = new(v1.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in *api.RBDVolumeSource, out *v1.RBDVolumeSource, s conversion.Scope) error { + return autoconvert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in, out, s) +} + +func autoconvert_api_ResourceRequirements_To_v1_ResourceRequirements(in *api.ResourceRequirements, out *v1.ResourceRequirements, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ResourceRequirements))(in) + } + if in.Limits != nil { + out.Limits = make(v1.ResourceList) + for key, val := range in.Limits { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Limits[v1.ResourceName(key)] = newVal + } + } else { + out.Limits = nil + } + if in.Requests != nil { + out.Requests = make(v1.ResourceList) + for key, val := range in.Requests { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Requests[v1.ResourceName(key)] = newVal + } + } else { + out.Requests = nil + } + return nil +} + +func convert_api_ResourceRequirements_To_v1_ResourceRequirements(in *api.ResourceRequirements, out *v1.ResourceRequirements, s conversion.Scope) error { + return autoconvert_api_ResourceRequirements_To_v1_ResourceRequirements(in, out, s) +} + +func autoconvert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, out *v1.SELinuxOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SELinuxOptions))(in) + } + out.User = in.User + out.Role = in.Role + out.Type = in.Type + out.Level = in.Level + return nil +} + +func convert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, out *v1.SELinuxOptions, s conversion.Scope) error { + return autoconvert_api_SELinuxOptions_To_v1_SELinuxOptions(in, out, s) +} + +func autoconvert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretVolumeSource, out *v1.SecretVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SecretVolumeSource))(in) + } + out.SecretName = in.SecretName + return nil +} + +func convert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretVolumeSource, out *v1.SecretVolumeSource, s conversion.Scope) error { + return autoconvert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in, out, s) +} + +func autoconvert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityContext, out *v1.SecurityContext, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SecurityContext))(in) + } + if in.Capabilities != nil { + out.Capabilities = new(v1.Capabilities) + if err := convert_api_Capabilities_To_v1_Capabilities(in.Capabilities, out.Capabilities, s); err != nil { + return err + } + } else { + out.Capabilities = nil + } + if in.Privileged != nil { + out.Privileged = new(bool) + *out.Privileged = *in.Privileged + } else { + out.Privileged = nil + } + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(v1.SELinuxOptions) + if err := convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + if in.RunAsUser != nil { + out.RunAsUser = new(int64) + *out.RunAsUser = *in.RunAsUser + } else { + out.RunAsUser = nil + } + out.RunAsNonRoot = in.RunAsNonRoot + return nil +} + +func convert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityContext, out *v1.SecurityContext, s conversion.Scope) error { + return autoconvert_api_SecurityContext_To_v1_SecurityContext(in, out, s) +} + +func autoconvert_api_TCPSocketAction_To_v1_TCPSocketAction(in *api.TCPSocketAction, out *v1.TCPSocketAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.TCPSocketAction))(in) + } + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + return nil +} + +func convert_api_TCPSocketAction_To_v1_TCPSocketAction(in *api.TCPSocketAction, out *v1.TCPSocketAction, s conversion.Scope) error { + return autoconvert_api_TCPSocketAction_To_v1_TCPSocketAction(in, out, s) +} + +func autoconvert_api_Volume_To_v1_Volume(in *api.Volume, out *v1.Volume, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Volume))(in) + } + out.Name = in.Name + if err := convert_api_VolumeSource_To_v1_VolumeSource(&in.VolumeSource, &out.VolumeSource, s); err != nil { + return err + } + return nil +} + +func convert_api_Volume_To_v1_Volume(in *api.Volume, out *v1.Volume, s conversion.Scope) error { + return autoconvert_api_Volume_To_v1_Volume(in, out, s) +} + +func autoconvert_api_VolumeMount_To_v1_VolumeMount(in *api.VolumeMount, out *v1.VolumeMount, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.VolumeMount))(in) + } + out.Name = in.Name + out.ReadOnly = in.ReadOnly + out.MountPath = in.MountPath + return nil +} + +func convert_api_VolumeMount_To_v1_VolumeMount(in *api.VolumeMount, out *v1.VolumeMount, s conversion.Scope) error { + return autoconvert_api_VolumeMount_To_v1_VolumeMount(in, out, s) +} + +func autoconvert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *v1.VolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.VolumeSource))(in) + } + if in.HostPath != nil { + out.HostPath = new(v1.HostPathVolumeSource) + if err := convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in.HostPath, out.HostPath, s); err != nil { + return err + } + } else { + out.HostPath = nil + } + if in.EmptyDir != nil { + out.EmptyDir = new(v1.EmptyDirVolumeSource) + if err := convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in.EmptyDir, out.EmptyDir, s); err != nil { + return err + } + } else { + out.EmptyDir = nil + } + if in.GCEPersistentDisk != nil { + out.GCEPersistentDisk = new(v1.GCEPersistentDiskVolumeSource) + if err := convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in.GCEPersistentDisk, out.GCEPersistentDisk, s); err != nil { + return err + } + } else { + out.GCEPersistentDisk = nil + } + if in.AWSElasticBlockStore != nil { + out.AWSElasticBlockStore = new(v1.AWSElasticBlockStoreVolumeSource) + if err := convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in.AWSElasticBlockStore, out.AWSElasticBlockStore, s); err != nil { + return err + } + } else { + out.AWSElasticBlockStore = nil + } + if in.GitRepo != nil { + out.GitRepo = new(v1.GitRepoVolumeSource) + if err := convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in.GitRepo, out.GitRepo, s); err != nil { + return err + } + } else { + out.GitRepo = nil + } + if in.Secret != nil { + out.Secret = new(v1.SecretVolumeSource) + if err := convert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in.Secret, out.Secret, s); err != nil { + return err + } + } else { + out.Secret = nil + } + if in.NFS != nil { + out.NFS = new(v1.NFSVolumeSource) + if err := convert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in.NFS, out.NFS, s); err != nil { + return err + } + } else { + out.NFS = nil + } + if in.ISCSI != nil { + out.ISCSI = new(v1.ISCSIVolumeSource) + if err := convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { + return err + } + } else { + out.ISCSI = nil + } + if in.Glusterfs != nil { + out.Glusterfs = new(v1.GlusterfsVolumeSource) + if err := convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { + return err + } + } else { + out.Glusterfs = nil + } + if in.PersistentVolumeClaim != nil { + out.PersistentVolumeClaim = new(v1.PersistentVolumeClaimVolumeSource) + if err := convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in.PersistentVolumeClaim, out.PersistentVolumeClaim, s); err != nil { + return err + } + } else { + out.PersistentVolumeClaim = nil + } + if in.RBD != nil { + out.RBD = new(v1.RBDVolumeSource) + if err := convert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in.RBD, out.RBD, s); err != nil { + return err + } + } else { + out.RBD = nil + } + if in.Cinder != nil { + out.Cinder = new(v1.CinderVolumeSource) + if err := convert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in.Cinder, out.Cinder, s); err != nil { + return err + } + } else { + out.Cinder = nil + } + if in.CephFS != nil { + out.CephFS = new(v1.CephFSVolumeSource) + if err := convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in.CephFS, out.CephFS, s); err != nil { + return err + } + } else { + out.CephFS = nil + } + if in.Flocker != nil { + out.Flocker = new(v1.FlockerVolumeSource) + if err := convert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource(in.Flocker, out.Flocker, s); err != nil { + return err + } + } else { + out.Flocker = nil + } + if in.DownwardAPI != nil { + out.DownwardAPI = new(v1.DownwardAPIVolumeSource) + if err := convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in.DownwardAPI, out.DownwardAPI, s); err != nil { + return err + } + } else { + out.DownwardAPI = nil + } + if in.FC != nil { + out.FC = new(v1.FCVolumeSource) + if err := convert_api_FCVolumeSource_To_v1_FCVolumeSource(in.FC, out.FC, s); err != nil { + return err + } + } else { + out.FC = nil + } + return nil +} + +func convert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *v1.VolumeSource, s conversion.Scope) error { + return autoconvert_api_VolumeSource_To_v1_VolumeSource(in, out, s) +} + +func autoconvert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in *v1.AWSElasticBlockStoreVolumeSource, out *api.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.AWSElasticBlockStoreVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in *v1.AWSElasticBlockStoreVolumeSource, out *api.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { + return autoconvert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in, out, s) +} + +func autoconvert_v1_Capabilities_To_api_Capabilities(in *v1.Capabilities, out *api.Capabilities, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Capabilities))(in) + } + if in.Add != nil { + out.Add = make([]api.Capability, len(in.Add)) + for i := range in.Add { + out.Add[i] = api.Capability(in.Add[i]) + } + } else { + out.Add = nil + } + if in.Drop != nil { + out.Drop = make([]api.Capability, len(in.Drop)) + for i := range in.Drop { + out.Drop[i] = api.Capability(in.Drop[i]) + } + } else { + out.Drop = nil + } + return nil +} + +func convert_v1_Capabilities_To_api_Capabilities(in *v1.Capabilities, out *api.Capabilities, s conversion.Scope) error { + return autoconvert_v1_Capabilities_To_api_Capabilities(in, out, s) +} + +func autoconvert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in *v1.CephFSVolumeSource, out *api.CephFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.CephFSVolumeSource))(in) + } + if in.Monitors != nil { + out.Monitors = make([]string, len(in.Monitors)) + for i := range in.Monitors { + out.Monitors[i] = in.Monitors[i] + } + } else { + out.Monitors = nil + } + out.User = in.User + out.SecretFile = in.SecretFile + if in.SecretRef != nil { + out.SecretRef = new(api.LocalObjectReference) + if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in *v1.CephFSVolumeSource, out *api.CephFSVolumeSource, s conversion.Scope) error { + return autoconvert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in, out, s) +} + +func autoconvert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in *v1.CinderVolumeSource, out *api.CinderVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.CinderVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in *v1.CinderVolumeSource, out *api.CinderVolumeSource, s conversion.Scope) error { + return autoconvert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in, out, s) +} + +func autoconvert_v1_Container_To_api_Container(in *v1.Container, out *api.Container, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Container))(in) + } + out.Name = in.Name + out.Image = in.Image + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + if in.Args != nil { + out.Args = make([]string, len(in.Args)) + for i := range in.Args { + out.Args[i] = in.Args[i] + } + } else { + out.Args = nil + } + out.WorkingDir = in.WorkingDir + if in.Ports != nil { + out.Ports = make([]api.ContainerPort, len(in.Ports)) + for i := range in.Ports { + if err := convert_v1_ContainerPort_To_api_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.Env != nil { + out.Env = make([]api.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_v1_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + if err := convert_v1_ResourceRequirements_To_api_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { + return err + } + if in.VolumeMounts != nil { + out.VolumeMounts = make([]api.VolumeMount, len(in.VolumeMounts)) + for i := range in.VolumeMounts { + if err := convert_v1_VolumeMount_To_api_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { + return err + } + } + } else { + out.VolumeMounts = nil + } + if in.LivenessProbe != nil { + out.LivenessProbe = new(api.Probe) + if err := convert_v1_Probe_To_api_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { + return err + } + } else { + out.LivenessProbe = nil + } + if in.ReadinessProbe != nil { + out.ReadinessProbe = new(api.Probe) + if err := convert_v1_Probe_To_api_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { + return err + } + } else { + out.ReadinessProbe = nil + } + if in.Lifecycle != nil { + out.Lifecycle = new(api.Lifecycle) + if err := convert_v1_Lifecycle_To_api_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { + return err + } + } else { + out.Lifecycle = nil + } + out.TerminationMessagePath = in.TerminationMessagePath + out.ImagePullPolicy = api.PullPolicy(in.ImagePullPolicy) + if in.SecurityContext != nil { + out.SecurityContext = new(api.SecurityContext) + if err := convert_v1_SecurityContext_To_api_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + out.Stdin = in.Stdin + out.TTY = in.TTY + return nil +} + +func convert_v1_Container_To_api_Container(in *v1.Container, out *api.Container, s conversion.Scope) error { + return autoconvert_v1_Container_To_api_Container(in, out, s) +} + +func autoconvert_v1_ContainerPort_To_api_ContainerPort(in *v1.ContainerPort, out *api.ContainerPort, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ContainerPort))(in) + } + out.Name = in.Name + out.HostPort = in.HostPort + out.ContainerPort = in.ContainerPort + out.Protocol = api.Protocol(in.Protocol) + out.HostIP = in.HostIP + return nil +} + +func convert_v1_ContainerPort_To_api_ContainerPort(in *v1.ContainerPort, out *api.ContainerPort, s conversion.Scope) error { + return autoconvert_v1_ContainerPort_To_api_ContainerPort(in, out, s) +} + +func autoconvert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *v1.DownwardAPIVolumeFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.DownwardAPIVolumeFile))(in) + } + out.Path = in.Path + if err := convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + return nil +} + +func convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *v1.DownwardAPIVolumeFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { + return autoconvert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in, out, s) +} + +func autoconvert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *v1.DownwardAPIVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.DownwardAPIVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]api.DownwardAPIVolumeFile, len(in.Items)) + for i := range in.Items { + if err := convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *v1.DownwardAPIVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { + return autoconvert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in, out, s) +} + +func autoconvert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in *v1.EmptyDirVolumeSource, out *api.EmptyDirVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.EmptyDirVolumeSource))(in) + } + out.Medium = api.StorageMedium(in.Medium) + return nil +} + +func convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in *v1.EmptyDirVolumeSource, out *api.EmptyDirVolumeSource, s conversion.Scope) error { + return autoconvert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in, out, s) +} + +func autoconvert_v1_EnvVar_To_api_EnvVar(in *v1.EnvVar, out *api.EnvVar, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.EnvVar))(in) + } + out.Name = in.Name + out.Value = in.Value + if in.ValueFrom != nil { + out.ValueFrom = new(api.EnvVarSource) + if err := convert_v1_EnvVarSource_To_api_EnvVarSource(in.ValueFrom, out.ValueFrom, s); err != nil { + return err + } + } else { + out.ValueFrom = nil + } + return nil +} + +func convert_v1_EnvVar_To_api_EnvVar(in *v1.EnvVar, out *api.EnvVar, s conversion.Scope) error { + return autoconvert_v1_EnvVar_To_api_EnvVar(in, out, s) +} + +func autoconvert_v1_EnvVarSource_To_api_EnvVarSource(in *v1.EnvVarSource, out *api.EnvVarSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.EnvVarSource))(in) + } + if in.FieldRef != nil { + out.FieldRef = new(api.ObjectFieldSelector) + if err := convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in.FieldRef, out.FieldRef, s); err != nil { + return err + } + } else { + out.FieldRef = nil + } + return nil +} + +func convert_v1_EnvVarSource_To_api_EnvVarSource(in *v1.EnvVarSource, out *api.EnvVarSource, s conversion.Scope) error { + return autoconvert_v1_EnvVarSource_To_api_EnvVarSource(in, out, s) +} + +func autoconvert_v1_ExecAction_To_api_ExecAction(in *v1.ExecAction, out *api.ExecAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ExecAction))(in) + } + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + return nil +} + +func convert_v1_ExecAction_To_api_ExecAction(in *v1.ExecAction, out *api.ExecAction, s conversion.Scope) error { + return autoconvert_v1_ExecAction_To_api_ExecAction(in, out, s) +} + +func autoconvert_v1_FCVolumeSource_To_api_FCVolumeSource(in *v1.FCVolumeSource, out *api.FCVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.FCVolumeSource))(in) + } + if in.TargetWWNs != nil { + out.TargetWWNs = make([]string, len(in.TargetWWNs)) + for i := range in.TargetWWNs { + out.TargetWWNs[i] = in.TargetWWNs[i] + } + } else { + out.TargetWWNs = nil + } + if in.Lun != nil { + out.Lun = new(int) + *out.Lun = *in.Lun + } else { + out.Lun = nil + } + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_FCVolumeSource_To_api_FCVolumeSource(in *v1.FCVolumeSource, out *api.FCVolumeSource, s conversion.Scope) error { + return autoconvert_v1_FCVolumeSource_To_api_FCVolumeSource(in, out, s) +} + +func autoconvert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource(in *v1.FlockerVolumeSource, out *api.FlockerVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.FlockerVolumeSource))(in) + } + out.DatasetName = in.DatasetName + return nil +} + +func convert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource(in *v1.FlockerVolumeSource, out *api.FlockerVolumeSource, s conversion.Scope) error { + return autoconvert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource(in, out, s) +} + +func autoconvert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in *v1.GCEPersistentDiskVolumeSource, out *api.GCEPersistentDiskVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.GCEPersistentDiskVolumeSource))(in) + } + out.PDName = in.PDName + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in *v1.GCEPersistentDiskVolumeSource, out *api.GCEPersistentDiskVolumeSource, s conversion.Scope) error { + return autoconvert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in, out, s) +} + +func autoconvert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in *v1.GitRepoVolumeSource, out *api.GitRepoVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.GitRepoVolumeSource))(in) + } + out.Repository = in.Repository + out.Revision = in.Revision + return nil +} + +func convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in *v1.GitRepoVolumeSource, out *api.GitRepoVolumeSource, s conversion.Scope) error { + return autoconvert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in, out, s) +} + +func autoconvert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in *v1.GlusterfsVolumeSource, out *api.GlusterfsVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.GlusterfsVolumeSource))(in) + } + out.EndpointsName = in.EndpointsName + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in *v1.GlusterfsVolumeSource, out *api.GlusterfsVolumeSource, s conversion.Scope) error { + return autoconvert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in, out, s) +} + +func autoconvert_v1_HTTPGetAction_To_api_HTTPGetAction(in *v1.HTTPGetAction, out *api.HTTPGetAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.HTTPGetAction))(in) + } + out.Path = in.Path + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + out.Host = in.Host + out.Scheme = api.URIScheme(in.Scheme) + return nil +} + +func convert_v1_HTTPGetAction_To_api_HTTPGetAction(in *v1.HTTPGetAction, out *api.HTTPGetAction, s conversion.Scope) error { + return autoconvert_v1_HTTPGetAction_To_api_HTTPGetAction(in, out, s) +} + +func autoconvert_v1_Handler_To_api_Handler(in *v1.Handler, out *api.Handler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Handler))(in) + } + if in.Exec != nil { + out.Exec = new(api.ExecAction) + if err := convert_v1_ExecAction_To_api_ExecAction(in.Exec, out.Exec, s); err != nil { + return err + } + } else { + out.Exec = nil + } + if in.HTTPGet != nil { + out.HTTPGet = new(api.HTTPGetAction) + if err := convert_v1_HTTPGetAction_To_api_HTTPGetAction(in.HTTPGet, out.HTTPGet, s); err != nil { + return err + } + } else { + out.HTTPGet = nil + } + if in.TCPSocket != nil { + out.TCPSocket = new(api.TCPSocketAction) + if err := convert_v1_TCPSocketAction_To_api_TCPSocketAction(in.TCPSocket, out.TCPSocket, s); err != nil { + return err + } + } else { + out.TCPSocket = nil + } + return nil +} + +func convert_v1_Handler_To_api_Handler(in *v1.Handler, out *api.Handler, s conversion.Scope) error { + return autoconvert_v1_Handler_To_api_Handler(in, out, s) +} + +func autoconvert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in *v1.HostPathVolumeSource, out *api.HostPathVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.HostPathVolumeSource))(in) + } + out.Path = in.Path + return nil +} + +func convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in *v1.HostPathVolumeSource, out *api.HostPathVolumeSource, s conversion.Scope) error { + return autoconvert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in, out, s) +} + +func autoconvert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in *v1.ISCSIVolumeSource, out *api.ISCSIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ISCSIVolumeSource))(in) + } + out.TargetPortal = in.TargetPortal + out.IQN = in.IQN + out.Lun = in.Lun + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in *v1.ISCSIVolumeSource, out *api.ISCSIVolumeSource, s conversion.Scope) error { + return autoconvert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in, out, s) +} + +func autoconvert_v1_Lifecycle_To_api_Lifecycle(in *v1.Lifecycle, out *api.Lifecycle, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Lifecycle))(in) + } + if in.PostStart != nil { + out.PostStart = new(api.Handler) + if err := convert_v1_Handler_To_api_Handler(in.PostStart, out.PostStart, s); err != nil { + return err + } + } else { + out.PostStart = nil + } + if in.PreStop != nil { + out.PreStop = new(api.Handler) + if err := convert_v1_Handler_To_api_Handler(in.PreStop, out.PreStop, s); err != nil { + return err + } + } else { + out.PreStop = nil + } + return nil +} + +func convert_v1_Lifecycle_To_api_Lifecycle(in *v1.Lifecycle, out *api.Lifecycle, s conversion.Scope) error { + return autoconvert_v1_Lifecycle_To_api_Lifecycle(in, out, s) +} + +func autoconvert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress(in *v1.LoadBalancerIngress, out *api.LoadBalancerIngress, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.LoadBalancerIngress))(in) + } + out.IP = in.IP + out.Hostname = in.Hostname + return nil +} + +func convert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress(in *v1.LoadBalancerIngress, out *api.LoadBalancerIngress, s conversion.Scope) error { + return autoconvert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress(in, out, s) +} + +func autoconvert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus(in *v1.LoadBalancerStatus, out *api.LoadBalancerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.LoadBalancerStatus))(in) + } + if in.Ingress != nil { + out.Ingress = make([]api.LoadBalancerIngress, len(in.Ingress)) + for i := range in.Ingress { + if err := convert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress(&in.Ingress[i], &out.Ingress[i], s); err != nil { + return err + } + } + } else { + out.Ingress = nil + } + return nil +} + +func convert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus(in *v1.LoadBalancerStatus, out *api.LoadBalancerStatus, s conversion.Scope) error { + return autoconvert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus(in, out, s) +} + +func autoconvert_v1_LocalObjectReference_To_api_LocalObjectReference(in *v1.LocalObjectReference, out *api.LocalObjectReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.LocalObjectReference))(in) + } + out.Name = in.Name + return nil +} + +func convert_v1_LocalObjectReference_To_api_LocalObjectReference(in *v1.LocalObjectReference, out *api.LocalObjectReference, s conversion.Scope) error { + return autoconvert_v1_LocalObjectReference_To_api_LocalObjectReference(in, out, s) +} + +func autoconvert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in *v1.NFSVolumeSource, out *api.NFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.NFSVolumeSource))(in) + } + out.Server = in.Server + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in *v1.NFSVolumeSource, out *api.NFSVolumeSource, s conversion.Scope) error { + return autoconvert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in, out, s) +} + +func autoconvert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *v1.ObjectFieldSelector, out *api.ObjectFieldSelector, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ObjectFieldSelector))(in) + } + out.APIVersion = in.APIVersion + out.FieldPath = in.FieldPath + return nil +} + +func convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *v1.ObjectFieldSelector, out *api.ObjectFieldSelector, s conversion.Scope) error { + return autoconvert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in, out, s) +} + +func autoconvert_v1_ObjectMeta_To_api_ObjectMeta(in *v1.ObjectMeta, out *api.ObjectMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ObjectMeta))(in) + } + out.Name = in.Name + out.GenerateName = in.GenerateName + out.Namespace = in.Namespace + out.SelfLink = in.SelfLink + out.UID = in.UID + out.ResourceVersion = in.ResourceVersion + out.Generation = in.Generation + if err := s.Convert(&in.CreationTimestamp, &out.CreationTimestamp, 0); err != nil { + return err + } + if in.DeletionTimestamp != nil { + if err := s.Convert(&in.DeletionTimestamp, &out.DeletionTimestamp, 0); err != nil { + return err + } + } else { + out.DeletionTimestamp = nil + } + if in.DeletionGracePeriodSeconds != nil { + out.DeletionGracePeriodSeconds = new(int64) + *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds + } else { + out.DeletionGracePeriodSeconds = nil + } + if in.Labels != nil { + out.Labels = make(map[string]string) + for key, val := range in.Labels { + out.Labels[key] = val + } + } else { + out.Labels = nil + } + if in.Annotations != nil { + out.Annotations = make(map[string]string) + for key, val := range in.Annotations { + out.Annotations[key] = val + } + } else { + out.Annotations = nil + } + return nil +} + +func convert_v1_ObjectMeta_To_api_ObjectMeta(in *v1.ObjectMeta, out *api.ObjectMeta, s conversion.Scope) error { + return autoconvert_v1_ObjectMeta_To_api_ObjectMeta(in, out, s) +} + +func autoconvert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in *v1.PersistentVolumeClaimVolumeSource, out *api.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.PersistentVolumeClaimVolumeSource))(in) + } + out.ClaimName = in.ClaimName + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in *v1.PersistentVolumeClaimVolumeSource, out *api.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { + return autoconvert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in, out, s) +} + +func autoconvert_v1_PodSpec_To_api_PodSpec(in *v1.PodSpec, out *api.PodSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.PodSpec))(in) + } + if in.Volumes != nil { + out.Volumes = make([]api.Volume, len(in.Volumes)) + for i := range in.Volumes { + if err := convert_v1_Volume_To_api_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil { + return err + } + } + } else { + out.Volumes = nil + } + if in.Containers != nil { + out.Containers = make([]api.Container, len(in.Containers)) + for i := range in.Containers { + if err := convert_v1_Container_To_api_Container(&in.Containers[i], &out.Containers[i], s); err != nil { + return err + } + } + } else { + out.Containers = nil + } + out.RestartPolicy = api.RestartPolicy(in.RestartPolicy) + if in.TerminationGracePeriodSeconds != nil { + out.TerminationGracePeriodSeconds = new(int64) + *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds + } else { + out.TerminationGracePeriodSeconds = nil + } + if in.ActiveDeadlineSeconds != nil { + out.ActiveDeadlineSeconds = new(int64) + *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds + } else { + out.ActiveDeadlineSeconds = nil + } + out.DNSPolicy = api.DNSPolicy(in.DNSPolicy) + if in.NodeSelector != nil { + out.NodeSelector = make(map[string]string) + for key, val := range in.NodeSelector { + out.NodeSelector[key] = val + } + } else { + out.NodeSelector = nil + } + out.ServiceAccountName = in.ServiceAccountName + // in.DeprecatedServiceAccount has no peer in out + out.NodeName = in.NodeName + // in.HostNetwork has no peer in out + // in.HostPID has no peer in out + // in.HostIPC has no peer in out + if in.SecurityContext != nil { + if err := s.Convert(&in.SecurityContext, &out.SecurityContext, 0); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + if in.ImagePullSecrets != nil { + out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets)) + for i := range in.ImagePullSecrets { + if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { + return err + } + } + } else { + out.ImagePullSecrets = nil + } + return nil +} + +func autoconvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *v1.PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.PodTemplateSpec))(in) + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1_PodSpec_To_api_PodSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *v1.PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { + return autoconvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in, out, s) +} + +func autoconvert_v1_Probe_To_api_Probe(in *v1.Probe, out *api.Probe, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Probe))(in) + } + if err := convert_v1_Handler_To_api_Handler(&in.Handler, &out.Handler, s); err != nil { + return err + } + out.InitialDelaySeconds = in.InitialDelaySeconds + out.TimeoutSeconds = in.TimeoutSeconds + return nil +} + +func convert_v1_Probe_To_api_Probe(in *v1.Probe, out *api.Probe, s conversion.Scope) error { + return autoconvert_v1_Probe_To_api_Probe(in, out, s) +} + +func autoconvert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in *v1.RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.RBDVolumeSource))(in) + } + if in.CephMonitors != nil { + out.CephMonitors = make([]string, len(in.CephMonitors)) + for i := range in.CephMonitors { + out.CephMonitors[i] = in.CephMonitors[i] + } + } else { + out.CephMonitors = nil + } + out.RBDImage = in.RBDImage + out.FSType = in.FSType + out.RBDPool = in.RBDPool + out.RadosUser = in.RadosUser + out.Keyring = in.Keyring + if in.SecretRef != nil { + out.SecretRef = new(api.LocalObjectReference) + if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in *v1.RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error { + return autoconvert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in, out, s) +} + +func autoconvert_v1_ResourceRequirements_To_api_ResourceRequirements(in *v1.ResourceRequirements, out *api.ResourceRequirements, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ResourceRequirements))(in) + } + if in.Limits != nil { + out.Limits = make(api.ResourceList) + for key, val := range in.Limits { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Limits[api.ResourceName(key)] = newVal + } + } else { + out.Limits = nil + } + if in.Requests != nil { + out.Requests = make(api.ResourceList) + for key, val := range in.Requests { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Requests[api.ResourceName(key)] = newVal + } + } else { + out.Requests = nil + } + return nil +} + +func convert_v1_ResourceRequirements_To_api_ResourceRequirements(in *v1.ResourceRequirements, out *api.ResourceRequirements, s conversion.Scope) error { + return autoconvert_v1_ResourceRequirements_To_api_ResourceRequirements(in, out, s) +} + +func autoconvert_v1_SELinuxOptions_To_api_SELinuxOptions(in *v1.SELinuxOptions, out *api.SELinuxOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.SELinuxOptions))(in) + } + out.User = in.User + out.Role = in.Role + out.Type = in.Type + out.Level = in.Level + return nil +} + +func convert_v1_SELinuxOptions_To_api_SELinuxOptions(in *v1.SELinuxOptions, out *api.SELinuxOptions, s conversion.Scope) error { + return autoconvert_v1_SELinuxOptions_To_api_SELinuxOptions(in, out, s) +} + +func autoconvert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *v1.SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.SecretVolumeSource))(in) + } + out.SecretName = in.SecretName + return nil +} + +func convert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *v1.SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error { + return autoconvert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in, out, s) +} + +func autoconvert_v1_SecurityContext_To_api_SecurityContext(in *v1.SecurityContext, out *api.SecurityContext, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.SecurityContext))(in) + } + if in.Capabilities != nil { + out.Capabilities = new(api.Capabilities) + if err := convert_v1_Capabilities_To_api_Capabilities(in.Capabilities, out.Capabilities, s); err != nil { + return err + } + } else { + out.Capabilities = nil + } + if in.Privileged != nil { + out.Privileged = new(bool) + *out.Privileged = *in.Privileged + } else { + out.Privileged = nil + } + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(api.SELinuxOptions) + if err := convert_v1_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + if in.RunAsUser != nil { + out.RunAsUser = new(int64) + *out.RunAsUser = *in.RunAsUser + } else { + out.RunAsUser = nil + } + out.RunAsNonRoot = in.RunAsNonRoot + return nil +} + +func convert_v1_SecurityContext_To_api_SecurityContext(in *v1.SecurityContext, out *api.SecurityContext, s conversion.Scope) error { + return autoconvert_v1_SecurityContext_To_api_SecurityContext(in, out, s) +} + +func autoconvert_v1_TCPSocketAction_To_api_TCPSocketAction(in *v1.TCPSocketAction, out *api.TCPSocketAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.TCPSocketAction))(in) + } + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + return nil +} + +func convert_v1_TCPSocketAction_To_api_TCPSocketAction(in *v1.TCPSocketAction, out *api.TCPSocketAction, s conversion.Scope) error { + return autoconvert_v1_TCPSocketAction_To_api_TCPSocketAction(in, out, s) +} + +func autoconvert_v1_Volume_To_api_Volume(in *v1.Volume, out *api.Volume, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Volume))(in) + } + out.Name = in.Name + if err := convert_v1_VolumeSource_To_api_VolumeSource(&in.VolumeSource, &out.VolumeSource, s); err != nil { + return err + } + return nil +} + +func convert_v1_Volume_To_api_Volume(in *v1.Volume, out *api.Volume, s conversion.Scope) error { + return autoconvert_v1_Volume_To_api_Volume(in, out, s) +} + +func autoconvert_v1_VolumeMount_To_api_VolumeMount(in *v1.VolumeMount, out *api.VolumeMount, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.VolumeMount))(in) + } + out.Name = in.Name + out.ReadOnly = in.ReadOnly + out.MountPath = in.MountPath + return nil +} + +func convert_v1_VolumeMount_To_api_VolumeMount(in *v1.VolumeMount, out *api.VolumeMount, s conversion.Scope) error { + return autoconvert_v1_VolumeMount_To_api_VolumeMount(in, out, s) +} + +func autoconvert_v1_VolumeSource_To_api_VolumeSource(in *v1.VolumeSource, out *api.VolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.VolumeSource))(in) + } + if in.HostPath != nil { + out.HostPath = new(api.HostPathVolumeSource) + if err := convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in.HostPath, out.HostPath, s); err != nil { + return err + } + } else { + out.HostPath = nil + } + if in.EmptyDir != nil { + out.EmptyDir = new(api.EmptyDirVolumeSource) + if err := convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in.EmptyDir, out.EmptyDir, s); err != nil { + return err + } + } else { + out.EmptyDir = nil + } + if in.GCEPersistentDisk != nil { + out.GCEPersistentDisk = new(api.GCEPersistentDiskVolumeSource) + if err := convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in.GCEPersistentDisk, out.GCEPersistentDisk, s); err != nil { + return err + } + } else { + out.GCEPersistentDisk = nil + } + if in.AWSElasticBlockStore != nil { + out.AWSElasticBlockStore = new(api.AWSElasticBlockStoreVolumeSource) + if err := convert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in.AWSElasticBlockStore, out.AWSElasticBlockStore, s); err != nil { + return err + } + } else { + out.AWSElasticBlockStore = nil + } + if in.GitRepo != nil { + out.GitRepo = new(api.GitRepoVolumeSource) + if err := convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in.GitRepo, out.GitRepo, s); err != nil { + return err + } + } else { + out.GitRepo = nil + } + if in.Secret != nil { + out.Secret = new(api.SecretVolumeSource) + if err := convert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in.Secret, out.Secret, s); err != nil { + return err + } + } else { + out.Secret = nil + } + if in.NFS != nil { + out.NFS = new(api.NFSVolumeSource) + if err := convert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in.NFS, out.NFS, s); err != nil { + return err + } + } else { + out.NFS = nil + } + if in.ISCSI != nil { + out.ISCSI = new(api.ISCSIVolumeSource) + if err := convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { + return err + } + } else { + out.ISCSI = nil + } + if in.Glusterfs != nil { + out.Glusterfs = new(api.GlusterfsVolumeSource) + if err := convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { + return err + } + } else { + out.Glusterfs = nil + } + if in.PersistentVolumeClaim != nil { + out.PersistentVolumeClaim = new(api.PersistentVolumeClaimVolumeSource) + if err := convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in.PersistentVolumeClaim, out.PersistentVolumeClaim, s); err != nil { + return err + } + } else { + out.PersistentVolumeClaim = nil + } + if in.RBD != nil { + out.RBD = new(api.RBDVolumeSource) + if err := convert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in.RBD, out.RBD, s); err != nil { + return err + } + } else { + out.RBD = nil + } + if in.Cinder != nil { + out.Cinder = new(api.CinderVolumeSource) + if err := convert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in.Cinder, out.Cinder, s); err != nil { + return err + } + } else { + out.Cinder = nil + } + if in.CephFS != nil { + out.CephFS = new(api.CephFSVolumeSource) + if err := convert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in.CephFS, out.CephFS, s); err != nil { + return err + } + } else { + out.CephFS = nil + } + if in.Flocker != nil { + out.Flocker = new(api.FlockerVolumeSource) + if err := convert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource(in.Flocker, out.Flocker, s); err != nil { + return err + } + } else { + out.Flocker = nil + } + if in.DownwardAPI != nil { + out.DownwardAPI = new(api.DownwardAPIVolumeSource) + if err := convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in.DownwardAPI, out.DownwardAPI, s); err != nil { + return err + } + } else { + out.DownwardAPI = nil + } + if in.FC != nil { + out.FC = new(api.FCVolumeSource) + if err := convert_v1_FCVolumeSource_To_api_FCVolumeSource(in.FC, out.FC, s); err != nil { + return err + } + } else { + out.FC = nil + } + return nil +} + +func convert_v1_VolumeSource_To_api_VolumeSource(in *v1.VolumeSource, out *api.VolumeSource, s conversion.Scope) error { + return autoconvert_v1_VolumeSource_To_api_VolumeSource(in, out, s) +} + +func autoconvert_extensions_APIVersion_To_v1beta1_APIVersion(in *extensions.APIVersion, out *APIVersion, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.APIVersion))(in) + } + out.Name = in.Name + out.APIGroup = in.APIGroup + return nil +} + +func convert_extensions_APIVersion_To_v1beta1_APIVersion(in *extensions.APIVersion, out *APIVersion, s conversion.Scope) error { + return autoconvert_extensions_APIVersion_To_v1beta1_APIVersion(in, out, s) +} + +func autoconvert_extensions_ClusterAutoscaler_To_v1beta1_ClusterAutoscaler(in *extensions.ClusterAutoscaler, out *ClusterAutoscaler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ClusterAutoscaler))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_extensions_ClusterAutoscalerSpec_To_v1beta1_ClusterAutoscalerSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_extensions_ClusterAutoscaler_To_v1beta1_ClusterAutoscaler(in *extensions.ClusterAutoscaler, out *ClusterAutoscaler, s conversion.Scope) error { + return autoconvert_extensions_ClusterAutoscaler_To_v1beta1_ClusterAutoscaler(in, out, s) +} + +func autoconvert_extensions_ClusterAutoscalerList_To_v1beta1_ClusterAutoscalerList(in *extensions.ClusterAutoscalerList, out *ClusterAutoscalerList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ClusterAutoscalerList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ClusterAutoscaler, len(in.Items)) + for i := range in.Items { + if err := convert_extensions_ClusterAutoscaler_To_v1beta1_ClusterAutoscaler(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_extensions_ClusterAutoscalerList_To_v1beta1_ClusterAutoscalerList(in *extensions.ClusterAutoscalerList, out *ClusterAutoscalerList, s conversion.Scope) error { + return autoconvert_extensions_ClusterAutoscalerList_To_v1beta1_ClusterAutoscalerList(in, out, s) +} + +func autoconvert_extensions_ClusterAutoscalerSpec_To_v1beta1_ClusterAutoscalerSpec(in *extensions.ClusterAutoscalerSpec, out *ClusterAutoscalerSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ClusterAutoscalerSpec))(in) + } + out.MinNodes = in.MinNodes + out.MaxNodes = in.MaxNodes + if in.TargetUtilization != nil { + out.TargetUtilization = make([]NodeUtilization, len(in.TargetUtilization)) + for i := range in.TargetUtilization { + if err := convert_extensions_NodeUtilization_To_v1beta1_NodeUtilization(&in.TargetUtilization[i], &out.TargetUtilization[i], s); err != nil { + return err + } + } + } else { + out.TargetUtilization = nil + } + return nil +} + +func convert_extensions_ClusterAutoscalerSpec_To_v1beta1_ClusterAutoscalerSpec(in *extensions.ClusterAutoscalerSpec, out *ClusterAutoscalerSpec, s conversion.Scope) error { + return autoconvert_extensions_ClusterAutoscalerSpec_To_v1beta1_ClusterAutoscalerSpec(in, out, s) +} + +func autoconvert_extensions_DaemonSet_To_v1beta1_DaemonSet(in *extensions.DaemonSet, out *DaemonSet, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.DaemonSet))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_extensions_DaemonSet_To_v1beta1_DaemonSet(in *extensions.DaemonSet, out *DaemonSet, s conversion.Scope) error { + return autoconvert_extensions_DaemonSet_To_v1beta1_DaemonSet(in, out, s) +} + +func autoconvert_extensions_DaemonSetList_To_v1beta1_DaemonSetList(in *extensions.DaemonSetList, out *DaemonSetList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.DaemonSetList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]DaemonSet, len(in.Items)) + for i := range in.Items { + if err := convert_extensions_DaemonSet_To_v1beta1_DaemonSet(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_extensions_DaemonSetList_To_v1beta1_DaemonSetList(in *extensions.DaemonSetList, out *DaemonSetList, s conversion.Scope) error { + return autoconvert_extensions_DaemonSetList_To_v1beta1_DaemonSetList(in, out, s) +} + +func autoconvert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in *extensions.DaemonSetSpec, out *DaemonSetSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.DaemonSetSpec))(in) + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(v1.PodTemplateSpec) + if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + return nil +} + +func convert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in *extensions.DaemonSetSpec, out *DaemonSetSpec, s conversion.Scope) error { + return autoconvert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in, out, s) +} + +func autoconvert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus(in *extensions.DaemonSetStatus, out *DaemonSetStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.DaemonSetStatus))(in) + } + out.CurrentNumberScheduled = in.CurrentNumberScheduled + out.NumberMisscheduled = in.NumberMisscheduled + out.DesiredNumberScheduled = in.DesiredNumberScheduled + return nil +} + +func convert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus(in *extensions.DaemonSetStatus, out *DaemonSetStatus, s conversion.Scope) error { + return autoconvert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus(in, out, s) +} + +func autoconvert_extensions_Deployment_To_v1beta1_Deployment(in *extensions.Deployment, out *Deployment, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.Deployment))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_extensions_Deployment_To_v1beta1_Deployment(in *extensions.Deployment, out *Deployment, s conversion.Scope) error { + return autoconvert_extensions_Deployment_To_v1beta1_Deployment(in, out, s) +} + +func autoconvert_extensions_DeploymentList_To_v1beta1_DeploymentList(in *extensions.DeploymentList, out *DeploymentList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.DeploymentList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Deployment, len(in.Items)) + for i := range in.Items { + if err := convert_extensions_Deployment_To_v1beta1_Deployment(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_extensions_DeploymentList_To_v1beta1_DeploymentList(in *extensions.DeploymentList, out *DeploymentList, s conversion.Scope) error { + return autoconvert_extensions_DeploymentList_To_v1beta1_DeploymentList(in, out, s) +} + +func autoconvert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensions.DeploymentSpec, out *DeploymentSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.DeploymentSpec))(in) + } + if err := s.Convert(&in.Replicas, &out.Replicas, 0); err != nil { + return err + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(v1.PodTemplateSpec) + if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + if err := convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + return err + } + if err := s.Convert(&in.UniqueLabelKey, &out.UniqueLabelKey, 0); err != nil { + return err + } + return nil +} + +func autoconvert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in *extensions.DeploymentStatus, out *DeploymentStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.DeploymentStatus))(in) + } + out.Replicas = in.Replicas + out.UpdatedReplicas = in.UpdatedReplicas + return nil +} + +func convert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in *extensions.DeploymentStatus, out *DeploymentStatus, s conversion.Scope) error { + return autoconvert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus(in, out, s) +} + +func autoconvert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy(in *extensions.DeploymentStrategy, out *DeploymentStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.DeploymentStrategy))(in) + } + out.Type = DeploymentStrategyType(in.Type) + if in.RollingUpdate != nil { + out.RollingUpdate = new(RollingUpdateDeployment) + if err := convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in.RollingUpdate, out.RollingUpdate, s); err != nil { + return err + } + } else { + out.RollingUpdate = nil + } + return nil +} + +func autoconvert_extensions_HTTPIngressPath_To_v1beta1_HTTPIngressPath(in *extensions.HTTPIngressPath, out *HTTPIngressPath, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.HTTPIngressPath))(in) + } + out.Path = in.Path + if err := convert_extensions_IngressBackend_To_v1beta1_IngressBackend(&in.Backend, &out.Backend, s); err != nil { + return err + } + return nil +} + +func convert_extensions_HTTPIngressPath_To_v1beta1_HTTPIngressPath(in *extensions.HTTPIngressPath, out *HTTPIngressPath, s conversion.Scope) error { + return autoconvert_extensions_HTTPIngressPath_To_v1beta1_HTTPIngressPath(in, out, s) +} + +func autoconvert_extensions_HTTPIngressRuleValue_To_v1beta1_HTTPIngressRuleValue(in *extensions.HTTPIngressRuleValue, out *HTTPIngressRuleValue, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.HTTPIngressRuleValue))(in) + } + if in.Paths != nil { + out.Paths = make([]HTTPIngressPath, len(in.Paths)) + for i := range in.Paths { + if err := convert_extensions_HTTPIngressPath_To_v1beta1_HTTPIngressPath(&in.Paths[i], &out.Paths[i], s); err != nil { + return err + } + } + } else { + out.Paths = nil + } + return nil +} + +func convert_extensions_HTTPIngressRuleValue_To_v1beta1_HTTPIngressRuleValue(in *extensions.HTTPIngressRuleValue, out *HTTPIngressRuleValue, s conversion.Scope) error { + return autoconvert_extensions_HTTPIngressRuleValue_To_v1beta1_HTTPIngressRuleValue(in, out, s) +} + +func autoconvert_extensions_HorizontalPodAutoscaler_To_v1beta1_HorizontalPodAutoscaler(in *extensions.HorizontalPodAutoscaler, out *HorizontalPodAutoscaler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.HorizontalPodAutoscaler))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_extensions_HorizontalPodAutoscalerSpec_To_v1beta1_HorizontalPodAutoscalerSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_extensions_HorizontalPodAutoscalerStatus_To_v1beta1_HorizontalPodAutoscalerStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_extensions_HorizontalPodAutoscaler_To_v1beta1_HorizontalPodAutoscaler(in *extensions.HorizontalPodAutoscaler, out *HorizontalPodAutoscaler, s conversion.Scope) error { + return autoconvert_extensions_HorizontalPodAutoscaler_To_v1beta1_HorizontalPodAutoscaler(in, out, s) +} + +func autoconvert_extensions_HorizontalPodAutoscalerList_To_v1beta1_HorizontalPodAutoscalerList(in *extensions.HorizontalPodAutoscalerList, out *HorizontalPodAutoscalerList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.HorizontalPodAutoscalerList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]HorizontalPodAutoscaler, len(in.Items)) + for i := range in.Items { + if err := convert_extensions_HorizontalPodAutoscaler_To_v1beta1_HorizontalPodAutoscaler(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_extensions_HorizontalPodAutoscalerList_To_v1beta1_HorizontalPodAutoscalerList(in *extensions.HorizontalPodAutoscalerList, out *HorizontalPodAutoscalerList, s conversion.Scope) error { + return autoconvert_extensions_HorizontalPodAutoscalerList_To_v1beta1_HorizontalPodAutoscalerList(in, out, s) +} + +func autoconvert_extensions_HorizontalPodAutoscalerSpec_To_v1beta1_HorizontalPodAutoscalerSpec(in *extensions.HorizontalPodAutoscalerSpec, out *HorizontalPodAutoscalerSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.HorizontalPodAutoscalerSpec))(in) + } + if in.ScaleRef != nil { + out.ScaleRef = new(SubresourceReference) + if err := convert_extensions_SubresourceReference_To_v1beta1_SubresourceReference(in.ScaleRef, out.ScaleRef, s); err != nil { + return err + } + } else { + out.ScaleRef = nil + } + out.MinReplicas = in.MinReplicas + out.MaxReplicas = in.MaxReplicas + if err := convert_extensions_ResourceConsumption_To_v1beta1_ResourceConsumption(&in.Target, &out.Target, s); err != nil { + return err + } + return nil +} + +func convert_extensions_HorizontalPodAutoscalerSpec_To_v1beta1_HorizontalPodAutoscalerSpec(in *extensions.HorizontalPodAutoscalerSpec, out *HorizontalPodAutoscalerSpec, s conversion.Scope) error { + return autoconvert_extensions_HorizontalPodAutoscalerSpec_To_v1beta1_HorizontalPodAutoscalerSpec(in, out, s) +} + +func autoconvert_extensions_HorizontalPodAutoscalerStatus_To_v1beta1_HorizontalPodAutoscalerStatus(in *extensions.HorizontalPodAutoscalerStatus, out *HorizontalPodAutoscalerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.HorizontalPodAutoscalerStatus))(in) + } + out.CurrentReplicas = in.CurrentReplicas + out.DesiredReplicas = in.DesiredReplicas + if in.CurrentConsumption != nil { + out.CurrentConsumption = new(ResourceConsumption) + if err := convert_extensions_ResourceConsumption_To_v1beta1_ResourceConsumption(in.CurrentConsumption, out.CurrentConsumption, s); err != nil { + return err + } + } else { + out.CurrentConsumption = nil + } + if in.LastScaleTimestamp != nil { + if err := s.Convert(&in.LastScaleTimestamp, &out.LastScaleTimestamp, 0); err != nil { + return err + } + } else { + out.LastScaleTimestamp = nil + } + return nil +} + +func convert_extensions_HorizontalPodAutoscalerStatus_To_v1beta1_HorizontalPodAutoscalerStatus(in *extensions.HorizontalPodAutoscalerStatus, out *HorizontalPodAutoscalerStatus, s conversion.Scope) error { + return autoconvert_extensions_HorizontalPodAutoscalerStatus_To_v1beta1_HorizontalPodAutoscalerStatus(in, out, s) +} + +func autoconvert_extensions_Ingress_To_v1beta1_Ingress(in *extensions.Ingress, out *Ingress, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.Ingress))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_extensions_IngressSpec_To_v1beta1_IngressSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_extensions_IngressStatus_To_v1beta1_IngressStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_extensions_Ingress_To_v1beta1_Ingress(in *extensions.Ingress, out *Ingress, s conversion.Scope) error { + return autoconvert_extensions_Ingress_To_v1beta1_Ingress(in, out, s) +} + +func autoconvert_extensions_IngressBackend_To_v1beta1_IngressBackend(in *extensions.IngressBackend, out *IngressBackend, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.IngressBackend))(in) + } + out.ServiceName = in.ServiceName + if err := s.Convert(&in.ServicePort, &out.ServicePort, 0); err != nil { + return err + } + return nil +} + +func convert_extensions_IngressBackend_To_v1beta1_IngressBackend(in *extensions.IngressBackend, out *IngressBackend, s conversion.Scope) error { + return autoconvert_extensions_IngressBackend_To_v1beta1_IngressBackend(in, out, s) +} + +func autoconvert_extensions_IngressList_To_v1beta1_IngressList(in *extensions.IngressList, out *IngressList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.IngressList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Ingress, len(in.Items)) + for i := range in.Items { + if err := convert_extensions_Ingress_To_v1beta1_Ingress(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_extensions_IngressList_To_v1beta1_IngressList(in *extensions.IngressList, out *IngressList, s conversion.Scope) error { + return autoconvert_extensions_IngressList_To_v1beta1_IngressList(in, out, s) +} + +func autoconvert_extensions_IngressRule_To_v1beta1_IngressRule(in *extensions.IngressRule, out *IngressRule, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.IngressRule))(in) + } + out.Host = in.Host + if err := convert_extensions_IngressRuleValue_To_v1beta1_IngressRuleValue(&in.IngressRuleValue, &out.IngressRuleValue, s); err != nil { + return err + } + return nil +} + +func convert_extensions_IngressRule_To_v1beta1_IngressRule(in *extensions.IngressRule, out *IngressRule, s conversion.Scope) error { + return autoconvert_extensions_IngressRule_To_v1beta1_IngressRule(in, out, s) +} + +func autoconvert_extensions_IngressRuleValue_To_v1beta1_IngressRuleValue(in *extensions.IngressRuleValue, out *IngressRuleValue, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.IngressRuleValue))(in) + } + if in.HTTP != nil { + out.HTTP = new(HTTPIngressRuleValue) + if err := convert_extensions_HTTPIngressRuleValue_To_v1beta1_HTTPIngressRuleValue(in.HTTP, out.HTTP, s); err != nil { + return err + } + } else { + out.HTTP = nil + } + return nil +} + +func convert_extensions_IngressRuleValue_To_v1beta1_IngressRuleValue(in *extensions.IngressRuleValue, out *IngressRuleValue, s conversion.Scope) error { + return autoconvert_extensions_IngressRuleValue_To_v1beta1_IngressRuleValue(in, out, s) +} + +func autoconvert_extensions_IngressSpec_To_v1beta1_IngressSpec(in *extensions.IngressSpec, out *IngressSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.IngressSpec))(in) + } + if in.Backend != nil { + out.Backend = new(IngressBackend) + if err := convert_extensions_IngressBackend_To_v1beta1_IngressBackend(in.Backend, out.Backend, s); err != nil { + return err + } + } else { + out.Backend = nil + } + if in.Rules != nil { + out.Rules = make([]IngressRule, len(in.Rules)) + for i := range in.Rules { + if err := convert_extensions_IngressRule_To_v1beta1_IngressRule(&in.Rules[i], &out.Rules[i], s); err != nil { + return err + } + } + } else { + out.Rules = nil + } + return nil +} + +func convert_extensions_IngressSpec_To_v1beta1_IngressSpec(in *extensions.IngressSpec, out *IngressSpec, s conversion.Scope) error { + return autoconvert_extensions_IngressSpec_To_v1beta1_IngressSpec(in, out, s) +} + +func autoconvert_extensions_IngressStatus_To_v1beta1_IngressStatus(in *extensions.IngressStatus, out *IngressStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.IngressStatus))(in) + } + if err := convert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus(&in.LoadBalancer, &out.LoadBalancer, s); err != nil { + return err + } + return nil +} + +func convert_extensions_IngressStatus_To_v1beta1_IngressStatus(in *extensions.IngressStatus, out *IngressStatus, s conversion.Scope) error { + return autoconvert_extensions_IngressStatus_To_v1beta1_IngressStatus(in, out, s) +} + +func autoconvert_extensions_Job_To_v1beta1_Job(in *extensions.Job, out *Job, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.Job))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_extensions_JobSpec_To_v1beta1_JobSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_extensions_JobStatus_To_v1beta1_JobStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_extensions_Job_To_v1beta1_Job(in *extensions.Job, out *Job, s conversion.Scope) error { + return autoconvert_extensions_Job_To_v1beta1_Job(in, out, s) +} + +func autoconvert_extensions_JobCondition_To_v1beta1_JobCondition(in *extensions.JobCondition, out *JobCondition, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.JobCondition))(in) + } + out.Type = JobConditionType(in.Type) + out.Status = v1.ConditionStatus(in.Status) + if err := s.Convert(&in.LastProbeTime, &out.LastProbeTime, 0); err != nil { + return err + } + if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message + return nil +} + +func convert_extensions_JobCondition_To_v1beta1_JobCondition(in *extensions.JobCondition, out *JobCondition, s conversion.Scope) error { + return autoconvert_extensions_JobCondition_To_v1beta1_JobCondition(in, out, s) +} + +func autoconvert_extensions_JobList_To_v1beta1_JobList(in *extensions.JobList, out *JobList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.JobList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Job, len(in.Items)) + for i := range in.Items { + if err := convert_extensions_Job_To_v1beta1_Job(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_extensions_JobList_To_v1beta1_JobList(in *extensions.JobList, out *JobList, s conversion.Scope) error { + return autoconvert_extensions_JobList_To_v1beta1_JobList(in, out, s) +} + +func autoconvert_extensions_JobSpec_To_v1beta1_JobSpec(in *extensions.JobSpec, out *JobSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.JobSpec))(in) + } + if in.Parallelism != nil { + out.Parallelism = new(int) + *out.Parallelism = *in.Parallelism + } else { + out.Parallelism = nil + } + if in.Completions != nil { + out.Completions = new(int) + *out.Completions = *in.Completions + } else { + out.Completions = nil + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +func convert_extensions_JobSpec_To_v1beta1_JobSpec(in *extensions.JobSpec, out *JobSpec, s conversion.Scope) error { + return autoconvert_extensions_JobSpec_To_v1beta1_JobSpec(in, out, s) +} + +func autoconvert_extensions_JobStatus_To_v1beta1_JobStatus(in *extensions.JobStatus, out *JobStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.JobStatus))(in) + } + if in.Conditions != nil { + out.Conditions = make([]JobCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := convert_extensions_JobCondition_To_v1beta1_JobCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + if in.StartTime != nil { + if err := s.Convert(&in.StartTime, &out.StartTime, 0); err != nil { + return err + } + } else { + out.StartTime = nil + } + if in.CompletionTime != nil { + if err := s.Convert(&in.CompletionTime, &out.CompletionTime, 0); err != nil { + return err + } + } else { + out.CompletionTime = nil + } + out.Active = in.Active + out.Succeeded = in.Succeeded + out.Failed = in.Failed + return nil +} + +func convert_extensions_JobStatus_To_v1beta1_JobStatus(in *extensions.JobStatus, out *JobStatus, s conversion.Scope) error { + return autoconvert_extensions_JobStatus_To_v1beta1_JobStatus(in, out, s) +} + +func autoconvert_extensions_NodeUtilization_To_v1beta1_NodeUtilization(in *extensions.NodeUtilization, out *NodeUtilization, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.NodeUtilization))(in) + } + out.Resource = NodeResource(in.Resource) + out.Value = in.Value + return nil +} + +func convert_extensions_NodeUtilization_To_v1beta1_NodeUtilization(in *extensions.NodeUtilization, out *NodeUtilization, s conversion.Scope) error { + return autoconvert_extensions_NodeUtilization_To_v1beta1_NodeUtilization(in, out, s) +} + +func autoconvert_extensions_ReplicationControllerDummy_To_v1beta1_ReplicationControllerDummy(in *extensions.ReplicationControllerDummy, out *ReplicationControllerDummy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ReplicationControllerDummy))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + return nil +} + +func convert_extensions_ReplicationControllerDummy_To_v1beta1_ReplicationControllerDummy(in *extensions.ReplicationControllerDummy, out *ReplicationControllerDummy, s conversion.Scope) error { + return autoconvert_extensions_ReplicationControllerDummy_To_v1beta1_ReplicationControllerDummy(in, out, s) +} + +func autoconvert_extensions_ResourceConsumption_To_v1beta1_ResourceConsumption(in *extensions.ResourceConsumption, out *ResourceConsumption, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ResourceConsumption))(in) + } + out.Resource = v1.ResourceName(in.Resource) + if err := s.Convert(&in.Quantity, &out.Quantity, 0); err != nil { + return err + } + return nil +} + +func convert_extensions_ResourceConsumption_To_v1beta1_ResourceConsumption(in *extensions.ResourceConsumption, out *ResourceConsumption, s conversion.Scope) error { + return autoconvert_extensions_ResourceConsumption_To_v1beta1_ResourceConsumption(in, out, s) +} + +func autoconvert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment(in *extensions.RollingUpdateDeployment, out *RollingUpdateDeployment, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.RollingUpdateDeployment))(in) + } + if err := s.Convert(&in.MaxUnavailable, &out.MaxUnavailable, 0); err != nil { + return err + } + if err := s.Convert(&in.MaxSurge, &out.MaxSurge, 0); err != nil { + return err + } + out.MinReadySeconds = in.MinReadySeconds + return nil +} + +func autoconvert_extensions_Scale_To_v1beta1_Scale(in *extensions.Scale, out *Scale, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.Scale))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_extensions_ScaleSpec_To_v1beta1_ScaleSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_extensions_ScaleStatus_To_v1beta1_ScaleStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_extensions_Scale_To_v1beta1_Scale(in *extensions.Scale, out *Scale, s conversion.Scope) error { + return autoconvert_extensions_Scale_To_v1beta1_Scale(in, out, s) +} + +func autoconvert_extensions_ScaleSpec_To_v1beta1_ScaleSpec(in *extensions.ScaleSpec, out *ScaleSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ScaleSpec))(in) + } + out.Replicas = in.Replicas + return nil +} + +func convert_extensions_ScaleSpec_To_v1beta1_ScaleSpec(in *extensions.ScaleSpec, out *ScaleSpec, s conversion.Scope) error { + return autoconvert_extensions_ScaleSpec_To_v1beta1_ScaleSpec(in, out, s) +} + +func autoconvert_extensions_ScaleStatus_To_v1beta1_ScaleStatus(in *extensions.ScaleStatus, out *ScaleStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ScaleStatus))(in) + } + out.Replicas = in.Replicas + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + return nil +} + +func convert_extensions_ScaleStatus_To_v1beta1_ScaleStatus(in *extensions.ScaleStatus, out *ScaleStatus, s conversion.Scope) error { + return autoconvert_extensions_ScaleStatus_To_v1beta1_ScaleStatus(in, out, s) +} + +func autoconvert_extensions_SubresourceReference_To_v1beta1_SubresourceReference(in *extensions.SubresourceReference, out *SubresourceReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.SubresourceReference))(in) + } + out.Kind = in.Kind + out.Namespace = in.Namespace + out.Name = in.Name + out.APIVersion = in.APIVersion + out.Subresource = in.Subresource + return nil +} + +func convert_extensions_SubresourceReference_To_v1beta1_SubresourceReference(in *extensions.SubresourceReference, out *SubresourceReference, s conversion.Scope) error { + return autoconvert_extensions_SubresourceReference_To_v1beta1_SubresourceReference(in, out, s) +} + +func autoconvert_extensions_ThirdPartyResource_To_v1beta1_ThirdPartyResource(in *extensions.ThirdPartyResource, out *ThirdPartyResource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ThirdPartyResource))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.Description = in.Description + if in.Versions != nil { + out.Versions = make([]APIVersion, len(in.Versions)) + for i := range in.Versions { + if err := convert_extensions_APIVersion_To_v1beta1_APIVersion(&in.Versions[i], &out.Versions[i], s); err != nil { + return err + } + } + } else { + out.Versions = nil + } + return nil +} + +func convert_extensions_ThirdPartyResource_To_v1beta1_ThirdPartyResource(in *extensions.ThirdPartyResource, out *ThirdPartyResource, s conversion.Scope) error { + return autoconvert_extensions_ThirdPartyResource_To_v1beta1_ThirdPartyResource(in, out, s) +} + +func autoconvert_extensions_ThirdPartyResourceData_To_v1beta1_ThirdPartyResourceData(in *extensions.ThirdPartyResourceData, out *ThirdPartyResourceData, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ThirdPartyResourceData))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Data, &out.Data, 0); err != nil { + return err + } + return nil +} + +func convert_extensions_ThirdPartyResourceData_To_v1beta1_ThirdPartyResourceData(in *extensions.ThirdPartyResourceData, out *ThirdPartyResourceData, s conversion.Scope) error { + return autoconvert_extensions_ThirdPartyResourceData_To_v1beta1_ThirdPartyResourceData(in, out, s) +} + +func autoconvert_extensions_ThirdPartyResourceDataList_To_v1beta1_ThirdPartyResourceDataList(in *extensions.ThirdPartyResourceDataList, out *ThirdPartyResourceDataList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ThirdPartyResourceDataList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ThirdPartyResourceData, len(in.Items)) + for i := range in.Items { + if err := convert_extensions_ThirdPartyResourceData_To_v1beta1_ThirdPartyResourceData(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_extensions_ThirdPartyResourceDataList_To_v1beta1_ThirdPartyResourceDataList(in *extensions.ThirdPartyResourceDataList, out *ThirdPartyResourceDataList, s conversion.Scope) error { + return autoconvert_extensions_ThirdPartyResourceDataList_To_v1beta1_ThirdPartyResourceDataList(in, out, s) +} + +func autoconvert_extensions_ThirdPartyResourceList_To_v1beta1_ThirdPartyResourceList(in *extensions.ThirdPartyResourceList, out *ThirdPartyResourceList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ThirdPartyResourceList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ThirdPartyResource, len(in.Items)) + for i := range in.Items { + if err := convert_extensions_ThirdPartyResource_To_v1beta1_ThirdPartyResource(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_extensions_ThirdPartyResourceList_To_v1beta1_ThirdPartyResourceList(in *extensions.ThirdPartyResourceList, out *ThirdPartyResourceList, s conversion.Scope) error { + return autoconvert_extensions_ThirdPartyResourceList_To_v1beta1_ThirdPartyResourceList(in, out, s) +} + +func autoconvert_v1beta1_APIVersion_To_extensions_APIVersion(in *APIVersion, out *extensions.APIVersion, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*APIVersion))(in) + } + out.Name = in.Name + out.APIGroup = in.APIGroup + return nil +} + +func convert_v1beta1_APIVersion_To_extensions_APIVersion(in *APIVersion, out *extensions.APIVersion, s conversion.Scope) error { + return autoconvert_v1beta1_APIVersion_To_extensions_APIVersion(in, out, s) +} + +func autoconvert_v1beta1_ClusterAutoscaler_To_extensions_ClusterAutoscaler(in *ClusterAutoscaler, out *extensions.ClusterAutoscaler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ClusterAutoscaler))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta1_ClusterAutoscalerSpec_To_extensions_ClusterAutoscalerSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_ClusterAutoscaler_To_extensions_ClusterAutoscaler(in *ClusterAutoscaler, out *extensions.ClusterAutoscaler, s conversion.Scope) error { + return autoconvert_v1beta1_ClusterAutoscaler_To_extensions_ClusterAutoscaler(in, out, s) +} + +func autoconvert_v1beta1_ClusterAutoscalerList_To_extensions_ClusterAutoscalerList(in *ClusterAutoscalerList, out *extensions.ClusterAutoscalerList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ClusterAutoscalerList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]extensions.ClusterAutoscaler, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta1_ClusterAutoscaler_To_extensions_ClusterAutoscaler(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta1_ClusterAutoscalerList_To_extensions_ClusterAutoscalerList(in *ClusterAutoscalerList, out *extensions.ClusterAutoscalerList, s conversion.Scope) error { + return autoconvert_v1beta1_ClusterAutoscalerList_To_extensions_ClusterAutoscalerList(in, out, s) +} + +func autoconvert_v1beta1_ClusterAutoscalerSpec_To_extensions_ClusterAutoscalerSpec(in *ClusterAutoscalerSpec, out *extensions.ClusterAutoscalerSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ClusterAutoscalerSpec))(in) + } + out.MinNodes = in.MinNodes + out.MaxNodes = in.MaxNodes + if in.TargetUtilization != nil { + out.TargetUtilization = make([]extensions.NodeUtilization, len(in.TargetUtilization)) + for i := range in.TargetUtilization { + if err := convert_v1beta1_NodeUtilization_To_extensions_NodeUtilization(&in.TargetUtilization[i], &out.TargetUtilization[i], s); err != nil { + return err + } + } + } else { + out.TargetUtilization = nil + } + return nil +} + +func convert_v1beta1_ClusterAutoscalerSpec_To_extensions_ClusterAutoscalerSpec(in *ClusterAutoscalerSpec, out *extensions.ClusterAutoscalerSpec, s conversion.Scope) error { + return autoconvert_v1beta1_ClusterAutoscalerSpec_To_extensions_ClusterAutoscalerSpec(in, out, s) +} + +func autoconvert_v1beta1_DaemonSet_To_extensions_DaemonSet(in *DaemonSet, out *extensions.DaemonSet, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DaemonSet))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_DaemonSet_To_extensions_DaemonSet(in *DaemonSet, out *extensions.DaemonSet, s conversion.Scope) error { + return autoconvert_v1beta1_DaemonSet_To_extensions_DaemonSet(in, out, s) +} + +func autoconvert_v1beta1_DaemonSetList_To_extensions_DaemonSetList(in *DaemonSetList, out *extensions.DaemonSetList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DaemonSetList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]extensions.DaemonSet, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta1_DaemonSet_To_extensions_DaemonSet(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta1_DaemonSetList_To_extensions_DaemonSetList(in *DaemonSetList, out *extensions.DaemonSetList, s conversion.Scope) error { + return autoconvert_v1beta1_DaemonSetList_To_extensions_DaemonSetList(in, out, s) +} + +func autoconvert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(in *DaemonSetSpec, out *extensions.DaemonSetSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DaemonSetSpec))(in) + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(api.PodTemplateSpec) + if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + return nil +} + +func convert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(in *DaemonSetSpec, out *extensions.DaemonSetSpec, s conversion.Scope) error { + return autoconvert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(in, out, s) +} + +func autoconvert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus(in *DaemonSetStatus, out *extensions.DaemonSetStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DaemonSetStatus))(in) + } + out.CurrentNumberScheduled = in.CurrentNumberScheduled + out.NumberMisscheduled = in.NumberMisscheduled + out.DesiredNumberScheduled = in.DesiredNumberScheduled + return nil +} + +func convert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus(in *DaemonSetStatus, out *extensions.DaemonSetStatus, s conversion.Scope) error { + return autoconvert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus(in, out, s) +} + +func autoconvert_v1beta1_Deployment_To_extensions_Deployment(in *Deployment, out *extensions.Deployment, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Deployment))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_Deployment_To_extensions_Deployment(in *Deployment, out *extensions.Deployment, s conversion.Scope) error { + return autoconvert_v1beta1_Deployment_To_extensions_Deployment(in, out, s) +} + +func autoconvert_v1beta1_DeploymentList_To_extensions_DeploymentList(in *DeploymentList, out *extensions.DeploymentList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DeploymentList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]extensions.Deployment, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta1_Deployment_To_extensions_Deployment(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta1_DeploymentList_To_extensions_DeploymentList(in *DeploymentList, out *extensions.DeploymentList, s conversion.Scope) error { + return autoconvert_v1beta1_DeploymentList_To_extensions_DeploymentList(in, out, s) +} + +func autoconvert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec(in *DeploymentSpec, out *extensions.DeploymentSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DeploymentSpec))(in) + } + // in.Replicas has no peer in out + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(api.PodTemplateSpec) + if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + if err := convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy(&in.Strategy, &out.Strategy, s); err != nil { + return err + } + // in.UniqueLabelKey has no peer in out + return nil +} + +func autoconvert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(in *DeploymentStatus, out *extensions.DeploymentStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DeploymentStatus))(in) + } + out.Replicas = in.Replicas + out.UpdatedReplicas = in.UpdatedReplicas + return nil +} + +func convert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(in *DeploymentStatus, out *extensions.DeploymentStatus, s conversion.Scope) error { + return autoconvert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus(in, out, s) +} + +func autoconvert_v1beta1_HTTPIngressPath_To_extensions_HTTPIngressPath(in *HTTPIngressPath, out *extensions.HTTPIngressPath, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HTTPIngressPath))(in) + } + out.Path = in.Path + if err := convert_v1beta1_IngressBackend_To_extensions_IngressBackend(&in.Backend, &out.Backend, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_HTTPIngressPath_To_extensions_HTTPIngressPath(in *HTTPIngressPath, out *extensions.HTTPIngressPath, s conversion.Scope) error { + return autoconvert_v1beta1_HTTPIngressPath_To_extensions_HTTPIngressPath(in, out, s) +} + +func autoconvert_v1beta1_HTTPIngressRuleValue_To_extensions_HTTPIngressRuleValue(in *HTTPIngressRuleValue, out *extensions.HTTPIngressRuleValue, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HTTPIngressRuleValue))(in) + } + if in.Paths != nil { + out.Paths = make([]extensions.HTTPIngressPath, len(in.Paths)) + for i := range in.Paths { + if err := convert_v1beta1_HTTPIngressPath_To_extensions_HTTPIngressPath(&in.Paths[i], &out.Paths[i], s); err != nil { + return err + } + } + } else { + out.Paths = nil + } + return nil +} + +func convert_v1beta1_HTTPIngressRuleValue_To_extensions_HTTPIngressRuleValue(in *HTTPIngressRuleValue, out *extensions.HTTPIngressRuleValue, s conversion.Scope) error { + return autoconvert_v1beta1_HTTPIngressRuleValue_To_extensions_HTTPIngressRuleValue(in, out, s) +} + +func autoconvert_v1beta1_HorizontalPodAutoscaler_To_extensions_HorizontalPodAutoscaler(in *HorizontalPodAutoscaler, out *extensions.HorizontalPodAutoscaler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HorizontalPodAutoscaler))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta1_HorizontalPodAutoscalerSpec_To_extensions_HorizontalPodAutoscalerSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta1_HorizontalPodAutoscalerStatus_To_extensions_HorizontalPodAutoscalerStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_HorizontalPodAutoscaler_To_extensions_HorizontalPodAutoscaler(in *HorizontalPodAutoscaler, out *extensions.HorizontalPodAutoscaler, s conversion.Scope) error { + return autoconvert_v1beta1_HorizontalPodAutoscaler_To_extensions_HorizontalPodAutoscaler(in, out, s) +} + +func autoconvert_v1beta1_HorizontalPodAutoscalerList_To_extensions_HorizontalPodAutoscalerList(in *HorizontalPodAutoscalerList, out *extensions.HorizontalPodAutoscalerList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HorizontalPodAutoscalerList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]extensions.HorizontalPodAutoscaler, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta1_HorizontalPodAutoscaler_To_extensions_HorizontalPodAutoscaler(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta1_HorizontalPodAutoscalerList_To_extensions_HorizontalPodAutoscalerList(in *HorizontalPodAutoscalerList, out *extensions.HorizontalPodAutoscalerList, s conversion.Scope) error { + return autoconvert_v1beta1_HorizontalPodAutoscalerList_To_extensions_HorizontalPodAutoscalerList(in, out, s) +} + +func autoconvert_v1beta1_HorizontalPodAutoscalerSpec_To_extensions_HorizontalPodAutoscalerSpec(in *HorizontalPodAutoscalerSpec, out *extensions.HorizontalPodAutoscalerSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HorizontalPodAutoscalerSpec))(in) + } + if in.ScaleRef != nil { + out.ScaleRef = new(extensions.SubresourceReference) + if err := convert_v1beta1_SubresourceReference_To_extensions_SubresourceReference(in.ScaleRef, out.ScaleRef, s); err != nil { + return err + } + } else { + out.ScaleRef = nil + } + out.MinReplicas = in.MinReplicas + out.MaxReplicas = in.MaxReplicas + if err := convert_v1beta1_ResourceConsumption_To_extensions_ResourceConsumption(&in.Target, &out.Target, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_HorizontalPodAutoscalerSpec_To_extensions_HorizontalPodAutoscalerSpec(in *HorizontalPodAutoscalerSpec, out *extensions.HorizontalPodAutoscalerSpec, s conversion.Scope) error { + return autoconvert_v1beta1_HorizontalPodAutoscalerSpec_To_extensions_HorizontalPodAutoscalerSpec(in, out, s) +} + +func autoconvert_v1beta1_HorizontalPodAutoscalerStatus_To_extensions_HorizontalPodAutoscalerStatus(in *HorizontalPodAutoscalerStatus, out *extensions.HorizontalPodAutoscalerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HorizontalPodAutoscalerStatus))(in) + } + out.CurrentReplicas = in.CurrentReplicas + out.DesiredReplicas = in.DesiredReplicas + if in.CurrentConsumption != nil { + out.CurrentConsumption = new(extensions.ResourceConsumption) + if err := convert_v1beta1_ResourceConsumption_To_extensions_ResourceConsumption(in.CurrentConsumption, out.CurrentConsumption, s); err != nil { + return err + } + } else { + out.CurrentConsumption = nil + } + if in.LastScaleTimestamp != nil { + if err := s.Convert(&in.LastScaleTimestamp, &out.LastScaleTimestamp, 0); err != nil { + return err + } + } else { + out.LastScaleTimestamp = nil + } + return nil +} + +func convert_v1beta1_HorizontalPodAutoscalerStatus_To_extensions_HorizontalPodAutoscalerStatus(in *HorizontalPodAutoscalerStatus, out *extensions.HorizontalPodAutoscalerStatus, s conversion.Scope) error { + return autoconvert_v1beta1_HorizontalPodAutoscalerStatus_To_extensions_HorizontalPodAutoscalerStatus(in, out, s) +} + +func autoconvert_v1beta1_Ingress_To_extensions_Ingress(in *Ingress, out *extensions.Ingress, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Ingress))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta1_IngressSpec_To_extensions_IngressSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta1_IngressStatus_To_extensions_IngressStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_Ingress_To_extensions_Ingress(in *Ingress, out *extensions.Ingress, s conversion.Scope) error { + return autoconvert_v1beta1_Ingress_To_extensions_Ingress(in, out, s) +} + +func autoconvert_v1beta1_IngressBackend_To_extensions_IngressBackend(in *IngressBackend, out *extensions.IngressBackend, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*IngressBackend))(in) + } + out.ServiceName = in.ServiceName + if err := s.Convert(&in.ServicePort, &out.ServicePort, 0); err != nil { + return err + } + return nil +} + +func convert_v1beta1_IngressBackend_To_extensions_IngressBackend(in *IngressBackend, out *extensions.IngressBackend, s conversion.Scope) error { + return autoconvert_v1beta1_IngressBackend_To_extensions_IngressBackend(in, out, s) +} + +func autoconvert_v1beta1_IngressList_To_extensions_IngressList(in *IngressList, out *extensions.IngressList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*IngressList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]extensions.Ingress, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta1_Ingress_To_extensions_Ingress(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta1_IngressList_To_extensions_IngressList(in *IngressList, out *extensions.IngressList, s conversion.Scope) error { + return autoconvert_v1beta1_IngressList_To_extensions_IngressList(in, out, s) +} + +func autoconvert_v1beta1_IngressRule_To_extensions_IngressRule(in *IngressRule, out *extensions.IngressRule, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*IngressRule))(in) + } + out.Host = in.Host + if err := convert_v1beta1_IngressRuleValue_To_extensions_IngressRuleValue(&in.IngressRuleValue, &out.IngressRuleValue, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_IngressRule_To_extensions_IngressRule(in *IngressRule, out *extensions.IngressRule, s conversion.Scope) error { + return autoconvert_v1beta1_IngressRule_To_extensions_IngressRule(in, out, s) +} + +func autoconvert_v1beta1_IngressRuleValue_To_extensions_IngressRuleValue(in *IngressRuleValue, out *extensions.IngressRuleValue, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*IngressRuleValue))(in) + } + if in.HTTP != nil { + out.HTTP = new(extensions.HTTPIngressRuleValue) + if err := convert_v1beta1_HTTPIngressRuleValue_To_extensions_HTTPIngressRuleValue(in.HTTP, out.HTTP, s); err != nil { + return err + } + } else { + out.HTTP = nil + } + return nil +} + +func convert_v1beta1_IngressRuleValue_To_extensions_IngressRuleValue(in *IngressRuleValue, out *extensions.IngressRuleValue, s conversion.Scope) error { + return autoconvert_v1beta1_IngressRuleValue_To_extensions_IngressRuleValue(in, out, s) +} + +func autoconvert_v1beta1_IngressSpec_To_extensions_IngressSpec(in *IngressSpec, out *extensions.IngressSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*IngressSpec))(in) + } + if in.Backend != nil { + out.Backend = new(extensions.IngressBackend) + if err := convert_v1beta1_IngressBackend_To_extensions_IngressBackend(in.Backend, out.Backend, s); err != nil { + return err + } + } else { + out.Backend = nil + } + if in.Rules != nil { + out.Rules = make([]extensions.IngressRule, len(in.Rules)) + for i := range in.Rules { + if err := convert_v1beta1_IngressRule_To_extensions_IngressRule(&in.Rules[i], &out.Rules[i], s); err != nil { + return err + } + } + } else { + out.Rules = nil + } + return nil +} + +func convert_v1beta1_IngressSpec_To_extensions_IngressSpec(in *IngressSpec, out *extensions.IngressSpec, s conversion.Scope) error { + return autoconvert_v1beta1_IngressSpec_To_extensions_IngressSpec(in, out, s) +} + +func autoconvert_v1beta1_IngressStatus_To_extensions_IngressStatus(in *IngressStatus, out *extensions.IngressStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*IngressStatus))(in) + } + if err := convert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus(&in.LoadBalancer, &out.LoadBalancer, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_IngressStatus_To_extensions_IngressStatus(in *IngressStatus, out *extensions.IngressStatus, s conversion.Scope) error { + return autoconvert_v1beta1_IngressStatus_To_extensions_IngressStatus(in, out, s) +} + +func autoconvert_v1beta1_Job_To_extensions_Job(in *Job, out *extensions.Job, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Job))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta1_JobSpec_To_extensions_JobSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta1_JobStatus_To_extensions_JobStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_Job_To_extensions_Job(in *Job, out *extensions.Job, s conversion.Scope) error { + return autoconvert_v1beta1_Job_To_extensions_Job(in, out, s) +} + +func autoconvert_v1beta1_JobCondition_To_extensions_JobCondition(in *JobCondition, out *extensions.JobCondition, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*JobCondition))(in) + } + out.Type = extensions.JobConditionType(in.Type) + out.Status = api.ConditionStatus(in.Status) + if err := s.Convert(&in.LastProbeTime, &out.LastProbeTime, 0); err != nil { + return err + } + if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message + return nil +} + +func convert_v1beta1_JobCondition_To_extensions_JobCondition(in *JobCondition, out *extensions.JobCondition, s conversion.Scope) error { + return autoconvert_v1beta1_JobCondition_To_extensions_JobCondition(in, out, s) +} + +func autoconvert_v1beta1_JobList_To_extensions_JobList(in *JobList, out *extensions.JobList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*JobList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]extensions.Job, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta1_Job_To_extensions_Job(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta1_JobList_To_extensions_JobList(in *JobList, out *extensions.JobList, s conversion.Scope) error { + return autoconvert_v1beta1_JobList_To_extensions_JobList(in, out, s) +} + +func autoconvert_v1beta1_JobSpec_To_extensions_JobSpec(in *JobSpec, out *extensions.JobSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*JobSpec))(in) + } + if in.Parallelism != nil { + out.Parallelism = new(int) + *out.Parallelism = *in.Parallelism + } else { + out.Parallelism = nil + } + if in.Completions != nil { + out.Completions = new(int) + *out.Completions = *in.Completions + } else { + out.Completions = nil + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_JobSpec_To_extensions_JobSpec(in *JobSpec, out *extensions.JobSpec, s conversion.Scope) error { + return autoconvert_v1beta1_JobSpec_To_extensions_JobSpec(in, out, s) +} + +func autoconvert_v1beta1_JobStatus_To_extensions_JobStatus(in *JobStatus, out *extensions.JobStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*JobStatus))(in) + } + if in.Conditions != nil { + out.Conditions = make([]extensions.JobCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := convert_v1beta1_JobCondition_To_extensions_JobCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + if in.StartTime != nil { + if err := s.Convert(&in.StartTime, &out.StartTime, 0); err != nil { + return err + } + } else { + out.StartTime = nil + } + if in.CompletionTime != nil { + if err := s.Convert(&in.CompletionTime, &out.CompletionTime, 0); err != nil { + return err + } + } else { + out.CompletionTime = nil + } + out.Active = in.Active + out.Succeeded = in.Succeeded + out.Failed = in.Failed + return nil +} + +func convert_v1beta1_JobStatus_To_extensions_JobStatus(in *JobStatus, out *extensions.JobStatus, s conversion.Scope) error { + return autoconvert_v1beta1_JobStatus_To_extensions_JobStatus(in, out, s) +} + +func autoconvert_v1beta1_NodeUtilization_To_extensions_NodeUtilization(in *NodeUtilization, out *extensions.NodeUtilization, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NodeUtilization))(in) + } + out.Resource = extensions.NodeResource(in.Resource) + out.Value = in.Value + return nil +} + +func convert_v1beta1_NodeUtilization_To_extensions_NodeUtilization(in *NodeUtilization, out *extensions.NodeUtilization, s conversion.Scope) error { + return autoconvert_v1beta1_NodeUtilization_To_extensions_NodeUtilization(in, out, s) +} + +func autoconvert_v1beta1_ReplicationControllerDummy_To_extensions_ReplicationControllerDummy(in *ReplicationControllerDummy, out *extensions.ReplicationControllerDummy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ReplicationControllerDummy))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + return nil +} + +func convert_v1beta1_ReplicationControllerDummy_To_extensions_ReplicationControllerDummy(in *ReplicationControllerDummy, out *extensions.ReplicationControllerDummy, s conversion.Scope) error { + return autoconvert_v1beta1_ReplicationControllerDummy_To_extensions_ReplicationControllerDummy(in, out, s) +} + +func autoconvert_v1beta1_ResourceConsumption_To_extensions_ResourceConsumption(in *ResourceConsumption, out *extensions.ResourceConsumption, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ResourceConsumption))(in) + } + out.Resource = api.ResourceName(in.Resource) + if err := s.Convert(&in.Quantity, &out.Quantity, 0); err != nil { + return err + } + return nil +} + +func convert_v1beta1_ResourceConsumption_To_extensions_ResourceConsumption(in *ResourceConsumption, out *extensions.ResourceConsumption, s conversion.Scope) error { + return autoconvert_v1beta1_ResourceConsumption_To_extensions_ResourceConsumption(in, out, s) +} + +func autoconvert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment(in *RollingUpdateDeployment, out *extensions.RollingUpdateDeployment, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*RollingUpdateDeployment))(in) + } + // in.MaxUnavailable has no peer in out + // in.MaxSurge has no peer in out + out.MinReadySeconds = in.MinReadySeconds + return nil +} + +func autoconvert_v1beta1_Scale_To_extensions_Scale(in *Scale, out *extensions.Scale, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Scale))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta1_ScaleSpec_To_extensions_ScaleSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta1_ScaleStatus_To_extensions_ScaleStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta1_Scale_To_extensions_Scale(in *Scale, out *extensions.Scale, s conversion.Scope) error { + return autoconvert_v1beta1_Scale_To_extensions_Scale(in, out, s) +} + +func autoconvert_v1beta1_ScaleSpec_To_extensions_ScaleSpec(in *ScaleSpec, out *extensions.ScaleSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ScaleSpec))(in) + } + out.Replicas = in.Replicas + return nil +} + +func convert_v1beta1_ScaleSpec_To_extensions_ScaleSpec(in *ScaleSpec, out *extensions.ScaleSpec, s conversion.Scope) error { + return autoconvert_v1beta1_ScaleSpec_To_extensions_ScaleSpec(in, out, s) +} + +func autoconvert_v1beta1_ScaleStatus_To_extensions_ScaleStatus(in *ScaleStatus, out *extensions.ScaleStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ScaleStatus))(in) + } + out.Replicas = in.Replicas + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + return nil +} + +func convert_v1beta1_ScaleStatus_To_extensions_ScaleStatus(in *ScaleStatus, out *extensions.ScaleStatus, s conversion.Scope) error { + return autoconvert_v1beta1_ScaleStatus_To_extensions_ScaleStatus(in, out, s) +} + +func autoconvert_v1beta1_SubresourceReference_To_extensions_SubresourceReference(in *SubresourceReference, out *extensions.SubresourceReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SubresourceReference))(in) + } + out.Kind = in.Kind + out.Namespace = in.Namespace + out.Name = in.Name + out.APIVersion = in.APIVersion + out.Subresource = in.Subresource + return nil +} + +func convert_v1beta1_SubresourceReference_To_extensions_SubresourceReference(in *SubresourceReference, out *extensions.SubresourceReference, s conversion.Scope) error { + return autoconvert_v1beta1_SubresourceReference_To_extensions_SubresourceReference(in, out, s) +} + +func autoconvert_v1beta1_ThirdPartyResource_To_extensions_ThirdPartyResource(in *ThirdPartyResource, out *extensions.ThirdPartyResource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ThirdPartyResource))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.Description = in.Description + if in.Versions != nil { + out.Versions = make([]extensions.APIVersion, len(in.Versions)) + for i := range in.Versions { + if err := convert_v1beta1_APIVersion_To_extensions_APIVersion(&in.Versions[i], &out.Versions[i], s); err != nil { + return err + } + } + } else { + out.Versions = nil + } + return nil +} + +func convert_v1beta1_ThirdPartyResource_To_extensions_ThirdPartyResource(in *ThirdPartyResource, out *extensions.ThirdPartyResource, s conversion.Scope) error { + return autoconvert_v1beta1_ThirdPartyResource_To_extensions_ThirdPartyResource(in, out, s) +} + +func autoconvert_v1beta1_ThirdPartyResourceData_To_extensions_ThirdPartyResourceData(in *ThirdPartyResourceData, out *extensions.ThirdPartyResourceData, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ThirdPartyResourceData))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Data, &out.Data, 0); err != nil { + return err + } + return nil +} + +func convert_v1beta1_ThirdPartyResourceData_To_extensions_ThirdPartyResourceData(in *ThirdPartyResourceData, out *extensions.ThirdPartyResourceData, s conversion.Scope) error { + return autoconvert_v1beta1_ThirdPartyResourceData_To_extensions_ThirdPartyResourceData(in, out, s) +} + +func autoconvert_v1beta1_ThirdPartyResourceDataList_To_extensions_ThirdPartyResourceDataList(in *ThirdPartyResourceDataList, out *extensions.ThirdPartyResourceDataList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ThirdPartyResourceDataList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]extensions.ThirdPartyResourceData, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta1_ThirdPartyResourceData_To_extensions_ThirdPartyResourceData(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta1_ThirdPartyResourceDataList_To_extensions_ThirdPartyResourceDataList(in *ThirdPartyResourceDataList, out *extensions.ThirdPartyResourceDataList, s conversion.Scope) error { + return autoconvert_v1beta1_ThirdPartyResourceDataList_To_extensions_ThirdPartyResourceDataList(in, out, s) +} + +func autoconvert_v1beta1_ThirdPartyResourceList_To_extensions_ThirdPartyResourceList(in *ThirdPartyResourceList, out *extensions.ThirdPartyResourceList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ThirdPartyResourceList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]extensions.ThirdPartyResource, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta1_ThirdPartyResource_To_extensions_ThirdPartyResource(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta1_ThirdPartyResourceList_To_extensions_ThirdPartyResourceList(in *ThirdPartyResourceList, out *extensions.ThirdPartyResourceList, s conversion.Scope) error { + return autoconvert_v1beta1_ThirdPartyResourceList_To_extensions_ThirdPartyResourceList(in, out, s) +} + +func init() { + err := api.Scheme.AddGeneratedConversionFuncs( + autoconvert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource, + autoconvert_api_Capabilities_To_v1_Capabilities, + autoconvert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource, + autoconvert_api_CinderVolumeSource_To_v1_CinderVolumeSource, + autoconvert_api_ContainerPort_To_v1_ContainerPort, + autoconvert_api_Container_To_v1_Container, + autoconvert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile, + autoconvert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource, + autoconvert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource, + autoconvert_api_EnvVarSource_To_v1_EnvVarSource, + autoconvert_api_EnvVar_To_v1_EnvVar, + autoconvert_api_ExecAction_To_v1_ExecAction, + autoconvert_api_FCVolumeSource_To_v1_FCVolumeSource, + autoconvert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource, + autoconvert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource, + autoconvert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource, + autoconvert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource, + autoconvert_api_HTTPGetAction_To_v1_HTTPGetAction, + autoconvert_api_Handler_To_v1_Handler, + autoconvert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource, + autoconvert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource, + autoconvert_api_Lifecycle_To_v1_Lifecycle, + autoconvert_api_LoadBalancerIngress_To_v1_LoadBalancerIngress, + autoconvert_api_LoadBalancerStatus_To_v1_LoadBalancerStatus, + autoconvert_api_LocalObjectReference_To_v1_LocalObjectReference, + autoconvert_api_NFSVolumeSource_To_v1_NFSVolumeSource, + autoconvert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector, + autoconvert_api_ObjectMeta_To_v1_ObjectMeta, + autoconvert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource, + autoconvert_api_PodSpec_To_v1_PodSpec, + autoconvert_api_PodTemplateSpec_To_v1_PodTemplateSpec, + autoconvert_api_Probe_To_v1_Probe, + autoconvert_api_RBDVolumeSource_To_v1_RBDVolumeSource, + autoconvert_api_ResourceRequirements_To_v1_ResourceRequirements, + autoconvert_api_SELinuxOptions_To_v1_SELinuxOptions, + autoconvert_api_SecretVolumeSource_To_v1_SecretVolumeSource, + autoconvert_api_SecurityContext_To_v1_SecurityContext, + autoconvert_api_TCPSocketAction_To_v1_TCPSocketAction, + autoconvert_api_VolumeMount_To_v1_VolumeMount, + autoconvert_api_VolumeSource_To_v1_VolumeSource, + autoconvert_api_Volume_To_v1_Volume, + autoconvert_extensions_APIVersion_To_v1beta1_APIVersion, + autoconvert_extensions_ClusterAutoscalerList_To_v1beta1_ClusterAutoscalerList, + autoconvert_extensions_ClusterAutoscalerSpec_To_v1beta1_ClusterAutoscalerSpec, + autoconvert_extensions_ClusterAutoscaler_To_v1beta1_ClusterAutoscaler, + autoconvert_extensions_DaemonSetList_To_v1beta1_DaemonSetList, + autoconvert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec, + autoconvert_extensions_DaemonSetStatus_To_v1beta1_DaemonSetStatus, + autoconvert_extensions_DaemonSet_To_v1beta1_DaemonSet, + autoconvert_extensions_DeploymentList_To_v1beta1_DeploymentList, + autoconvert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec, + autoconvert_extensions_DeploymentStatus_To_v1beta1_DeploymentStatus, + autoconvert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy, + autoconvert_extensions_Deployment_To_v1beta1_Deployment, + autoconvert_extensions_HTTPIngressPath_To_v1beta1_HTTPIngressPath, + autoconvert_extensions_HTTPIngressRuleValue_To_v1beta1_HTTPIngressRuleValue, + autoconvert_extensions_HorizontalPodAutoscalerList_To_v1beta1_HorizontalPodAutoscalerList, + autoconvert_extensions_HorizontalPodAutoscalerSpec_To_v1beta1_HorizontalPodAutoscalerSpec, + autoconvert_extensions_HorizontalPodAutoscalerStatus_To_v1beta1_HorizontalPodAutoscalerStatus, + autoconvert_extensions_HorizontalPodAutoscaler_To_v1beta1_HorizontalPodAutoscaler, + autoconvert_extensions_IngressBackend_To_v1beta1_IngressBackend, + autoconvert_extensions_IngressList_To_v1beta1_IngressList, + autoconvert_extensions_IngressRuleValue_To_v1beta1_IngressRuleValue, + autoconvert_extensions_IngressRule_To_v1beta1_IngressRule, + autoconvert_extensions_IngressSpec_To_v1beta1_IngressSpec, + autoconvert_extensions_IngressStatus_To_v1beta1_IngressStatus, + autoconvert_extensions_Ingress_To_v1beta1_Ingress, + autoconvert_extensions_JobCondition_To_v1beta1_JobCondition, + autoconvert_extensions_JobList_To_v1beta1_JobList, + autoconvert_extensions_JobSpec_To_v1beta1_JobSpec, + autoconvert_extensions_JobStatus_To_v1beta1_JobStatus, + autoconvert_extensions_Job_To_v1beta1_Job, + autoconvert_extensions_NodeUtilization_To_v1beta1_NodeUtilization, + autoconvert_extensions_ReplicationControllerDummy_To_v1beta1_ReplicationControllerDummy, + autoconvert_extensions_ResourceConsumption_To_v1beta1_ResourceConsumption, + autoconvert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment, + autoconvert_extensions_ScaleSpec_To_v1beta1_ScaleSpec, + autoconvert_extensions_ScaleStatus_To_v1beta1_ScaleStatus, + autoconvert_extensions_Scale_To_v1beta1_Scale, + autoconvert_extensions_SubresourceReference_To_v1beta1_SubresourceReference, + autoconvert_extensions_ThirdPartyResourceDataList_To_v1beta1_ThirdPartyResourceDataList, + autoconvert_extensions_ThirdPartyResourceData_To_v1beta1_ThirdPartyResourceData, + autoconvert_extensions_ThirdPartyResourceList_To_v1beta1_ThirdPartyResourceList, + autoconvert_extensions_ThirdPartyResource_To_v1beta1_ThirdPartyResource, + autoconvert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource, + autoconvert_v1_Capabilities_To_api_Capabilities, + autoconvert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource, + autoconvert_v1_CinderVolumeSource_To_api_CinderVolumeSource, + autoconvert_v1_ContainerPort_To_api_ContainerPort, + autoconvert_v1_Container_To_api_Container, + autoconvert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile, + autoconvert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource, + autoconvert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource, + autoconvert_v1_EnvVarSource_To_api_EnvVarSource, + autoconvert_v1_EnvVar_To_api_EnvVar, + autoconvert_v1_ExecAction_To_api_ExecAction, + autoconvert_v1_FCVolumeSource_To_api_FCVolumeSource, + autoconvert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource, + autoconvert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource, + autoconvert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource, + autoconvert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource, + autoconvert_v1_HTTPGetAction_To_api_HTTPGetAction, + autoconvert_v1_Handler_To_api_Handler, + autoconvert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource, + autoconvert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource, + autoconvert_v1_Lifecycle_To_api_Lifecycle, + autoconvert_v1_LoadBalancerIngress_To_api_LoadBalancerIngress, + autoconvert_v1_LoadBalancerStatus_To_api_LoadBalancerStatus, + autoconvert_v1_LocalObjectReference_To_api_LocalObjectReference, + autoconvert_v1_NFSVolumeSource_To_api_NFSVolumeSource, + autoconvert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector, + autoconvert_v1_ObjectMeta_To_api_ObjectMeta, + autoconvert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource, + autoconvert_v1_PodSpec_To_api_PodSpec, + autoconvert_v1_PodTemplateSpec_To_api_PodTemplateSpec, + autoconvert_v1_Probe_To_api_Probe, + autoconvert_v1_RBDVolumeSource_To_api_RBDVolumeSource, + autoconvert_v1_ResourceRequirements_To_api_ResourceRequirements, + autoconvert_v1_SELinuxOptions_To_api_SELinuxOptions, + autoconvert_v1_SecretVolumeSource_To_api_SecretVolumeSource, + autoconvert_v1_SecurityContext_To_api_SecurityContext, + autoconvert_v1_TCPSocketAction_To_api_TCPSocketAction, + autoconvert_v1_VolumeMount_To_api_VolumeMount, + autoconvert_v1_VolumeSource_To_api_VolumeSource, + autoconvert_v1_Volume_To_api_Volume, + autoconvert_v1beta1_APIVersion_To_extensions_APIVersion, + autoconvert_v1beta1_ClusterAutoscalerList_To_extensions_ClusterAutoscalerList, + autoconvert_v1beta1_ClusterAutoscalerSpec_To_extensions_ClusterAutoscalerSpec, + autoconvert_v1beta1_ClusterAutoscaler_To_extensions_ClusterAutoscaler, + autoconvert_v1beta1_DaemonSetList_To_extensions_DaemonSetList, + autoconvert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec, + autoconvert_v1beta1_DaemonSetStatus_To_extensions_DaemonSetStatus, + autoconvert_v1beta1_DaemonSet_To_extensions_DaemonSet, + autoconvert_v1beta1_DeploymentList_To_extensions_DeploymentList, + autoconvert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec, + autoconvert_v1beta1_DeploymentStatus_To_extensions_DeploymentStatus, + autoconvert_v1beta1_Deployment_To_extensions_Deployment, + autoconvert_v1beta1_HTTPIngressPath_To_extensions_HTTPIngressPath, + autoconvert_v1beta1_HTTPIngressRuleValue_To_extensions_HTTPIngressRuleValue, + autoconvert_v1beta1_HorizontalPodAutoscalerList_To_extensions_HorizontalPodAutoscalerList, + autoconvert_v1beta1_HorizontalPodAutoscalerSpec_To_extensions_HorizontalPodAutoscalerSpec, + autoconvert_v1beta1_HorizontalPodAutoscalerStatus_To_extensions_HorizontalPodAutoscalerStatus, + autoconvert_v1beta1_HorizontalPodAutoscaler_To_extensions_HorizontalPodAutoscaler, + autoconvert_v1beta1_IngressBackend_To_extensions_IngressBackend, + autoconvert_v1beta1_IngressList_To_extensions_IngressList, + autoconvert_v1beta1_IngressRuleValue_To_extensions_IngressRuleValue, + autoconvert_v1beta1_IngressRule_To_extensions_IngressRule, + autoconvert_v1beta1_IngressSpec_To_extensions_IngressSpec, + autoconvert_v1beta1_IngressStatus_To_extensions_IngressStatus, + autoconvert_v1beta1_Ingress_To_extensions_Ingress, + autoconvert_v1beta1_JobCondition_To_extensions_JobCondition, + autoconvert_v1beta1_JobList_To_extensions_JobList, + autoconvert_v1beta1_JobSpec_To_extensions_JobSpec, + autoconvert_v1beta1_JobStatus_To_extensions_JobStatus, + autoconvert_v1beta1_Job_To_extensions_Job, + autoconvert_v1beta1_NodeUtilization_To_extensions_NodeUtilization, + autoconvert_v1beta1_ReplicationControllerDummy_To_extensions_ReplicationControllerDummy, + autoconvert_v1beta1_ResourceConsumption_To_extensions_ResourceConsumption, + autoconvert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment, + autoconvert_v1beta1_ScaleSpec_To_extensions_ScaleSpec, + autoconvert_v1beta1_ScaleStatus_To_extensions_ScaleStatus, + autoconvert_v1beta1_Scale_To_extensions_Scale, + autoconvert_v1beta1_SubresourceReference_To_extensions_SubresourceReference, + autoconvert_v1beta1_ThirdPartyResourceDataList_To_extensions_ThirdPartyResourceDataList, + autoconvert_v1beta1_ThirdPartyResourceData_To_extensions_ThirdPartyResourceData, + autoconvert_v1beta1_ThirdPartyResourceList_To_extensions_ThirdPartyResourceList, + autoconvert_v1beta1_ThirdPartyResource_To_extensions_ThirdPartyResource, + ) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/deep_copy_generated.go similarity index 63% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/deep_copy_generated.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/deep_copy_generated.go index 6c4d6e4b0239..a573e9b8ac48 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/deep_copy_generated.go @@ -16,13 +16,14 @@ limitations under the License. // DO NOT EDIT. THIS FILE IS AUTO-GENERATED BY $KUBEROOT/hack/update-generated-deep-copies.sh. -package v1 +package v1beta1 import ( time "time" api "k8s.io/kubernetes/pkg/api" resource "k8s.io/kubernetes/pkg/api/resource" + unversioned "k8s.io/kubernetes/pkg/api/unversioned" v1 "k8s.io/kubernetes/pkg/api/v1" conversion "k8s.io/kubernetes/pkg/conversion" util "k8s.io/kubernetes/pkg/util" @@ -45,6 +46,27 @@ func deepCopy_resource_Quantity(in resource.Quantity, out *resource.Quantity, c return nil } +func deepCopy_unversioned_ListMeta(in unversioned.ListMeta, out *unversioned.ListMeta, c *conversion.Cloner) error { + out.SelfLink = in.SelfLink + out.ResourceVersion = in.ResourceVersion + return nil +} + +func deepCopy_unversioned_Time(in unversioned.Time, out *unversioned.Time, c *conversion.Cloner) error { + if newVal, err := c.DeepCopy(in.Time); err != nil { + return err + } else { + out.Time = newVal.(time.Time) + } + return nil +} + +func deepCopy_unversioned_TypeMeta(in unversioned.TypeMeta, out *unversioned.TypeMeta, c *conversion.Cloner) error { + out.Kind = in.Kind + out.APIVersion = in.APIVersion + return nil +} + func deepCopy_v1_AWSElasticBlockStoreVolumeSource(in v1.AWSElasticBlockStoreVolumeSource, out *v1.AWSElasticBlockStoreVolumeSource, c *conversion.Cloner) error { out.VolumeID = in.VolumeID out.FSType = in.FSType @@ -269,6 +291,31 @@ func deepCopy_v1_ExecAction(in v1.ExecAction, out *v1.ExecAction, c *conversion. return nil } +func deepCopy_v1_FCVolumeSource(in v1.FCVolumeSource, out *v1.FCVolumeSource, c *conversion.Cloner) error { + if in.TargetWWNs != nil { + out.TargetWWNs = make([]string, len(in.TargetWWNs)) + for i := range in.TargetWWNs { + out.TargetWWNs[i] = in.TargetWWNs[i] + } + } else { + out.TargetWWNs = nil + } + if in.Lun != nil { + out.Lun = new(int) + *out.Lun = *in.Lun + } else { + out.Lun = nil + } + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_v1_FlockerVolumeSource(in v1.FlockerVolumeSource, out *v1.FlockerVolumeSource, c *conversion.Cloner) error { + out.DatasetName = in.DatasetName + return nil +} + func deepCopy_v1_GCEPersistentDiskVolumeSource(in v1.GCEPersistentDiskVolumeSource, out *v1.GCEPersistentDiskVolumeSource, c *conversion.Cloner) error { out.PDName = in.PDName out.FSType = in.FSType @@ -362,39 +409,31 @@ func deepCopy_v1_Lifecycle(in v1.Lifecycle, out *v1.Lifecycle, c *conversion.Clo return nil } -func deepCopy_v1_ListMeta(in v1.ListMeta, out *v1.ListMeta, c *conversion.Cloner) error { - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil -} - -func deepCopy_v1_LocalObjectReference(in v1.LocalObjectReference, out *v1.LocalObjectReference, c *conversion.Cloner) error { - out.Name = in.Name - return nil -} - -func deepCopy_v1_MetadataFile(in v1.MetadataFile, out *v1.MetadataFile, c *conversion.Cloner) error { - out.Name = in.Name - if err := deepCopy_v1_ObjectFieldSelector(in.FieldRef, &out.FieldRef, c); err != nil { - return err - } +func deepCopy_v1_LoadBalancerIngress(in v1.LoadBalancerIngress, out *v1.LoadBalancerIngress, c *conversion.Cloner) error { + out.IP = in.IP + out.Hostname = in.Hostname return nil } -func deepCopy_v1_MetadataVolumeSource(in v1.MetadataVolumeSource, out *v1.MetadataVolumeSource, c *conversion.Cloner) error { - if in.Items != nil { - out.Items = make([]v1.MetadataFile, len(in.Items)) - for i := range in.Items { - if err := deepCopy_v1_MetadataFile(in.Items[i], &out.Items[i], c); err != nil { +func deepCopy_v1_LoadBalancerStatus(in v1.LoadBalancerStatus, out *v1.LoadBalancerStatus, c *conversion.Cloner) error { + if in.Ingress != nil { + out.Ingress = make([]v1.LoadBalancerIngress, len(in.Ingress)) + for i := range in.Ingress { + if err := deepCopy_v1_LoadBalancerIngress(in.Ingress[i], &out.Ingress[i], c); err != nil { return err } } } else { - out.Items = nil + out.Ingress = nil } return nil } +func deepCopy_v1_LocalObjectReference(in v1.LocalObjectReference, out *v1.LocalObjectReference, c *conversion.Cloner) error { + out.Name = in.Name + return nil +} + func deepCopy_v1_NFSVolumeSource(in v1.NFSVolumeSource, out *v1.NFSVolumeSource, c *conversion.Cloner) error { out.Server = in.Server out.Path = in.Path @@ -416,12 +455,12 @@ func deepCopy_v1_ObjectMeta(in v1.ObjectMeta, out *v1.ObjectMeta, c *conversion. out.UID = in.UID out.ResourceVersion = in.ResourceVersion out.Generation = in.Generation - if err := deepCopy_util_Time(in.CreationTimestamp, &out.CreationTimestamp, c); err != nil { + if err := deepCopy_unversioned_Time(in.CreationTimestamp, &out.CreationTimestamp, c); err != nil { return err } if in.DeletionTimestamp != nil { - out.DeletionTimestamp = new(util.Time) - if err := deepCopy_util_Time(*in.DeletionTimestamp, out.DeletionTimestamp, c); err != nil { + out.DeletionTimestamp = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.DeletionTimestamp, out.DeletionTimestamp, c); err != nil { return err } } else { @@ -458,6 +497,10 @@ func deepCopy_v1_PersistentVolumeClaimVolumeSource(in v1.PersistentVolumeClaimVo return nil } +func deepCopy_v1_PodSecurityContext(in v1.PodSecurityContext, out *v1.PodSecurityContext, c *conversion.Cloner) error { + return nil +} + func deepCopy_v1_PodSpec(in v1.PodSpec, out *v1.PodSpec, c *conversion.Cloner) error { if in.Volumes != nil { out.Volumes = make([]v1.Volume, len(in.Volumes)) @@ -501,13 +544,20 @@ func deepCopy_v1_PodSpec(in v1.PodSpec, out *v1.PodSpec, c *conversion.Cloner) e } else { out.NodeSelector = nil } - out.DeprecatedHost = in.DeprecatedHost out.ServiceAccountName = in.ServiceAccountName out.DeprecatedServiceAccount = in.DeprecatedServiceAccount out.NodeName = in.NodeName out.HostNetwork = in.HostNetwork out.HostPID = in.HostPID out.HostIPC = in.HostIPC + if in.SecurityContext != nil { + out.SecurityContext = new(v1.PodSecurityContext) + if err := deepCopy_v1_PodSecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil { + return err + } + } else { + out.SecurityContext = nil + } if in.ImagePullSecrets != nil { out.ImagePullSecrets = make([]v1.LocalObjectReference, len(in.ImagePullSecrets)) for i := range in.ImagePullSecrets { @@ -647,12 +697,6 @@ func deepCopy_v1_TCPSocketAction(in v1.TCPSocketAction, out *v1.TCPSocketAction, return nil } -func deepCopy_v1_TypeMeta(in v1.TypeMeta, out *v1.TypeMeta, c *conversion.Cloner) error { - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil -} - func deepCopy_v1_Volume(in v1.Volume, out *v1.Volume, c *conversion.Cloner) error { out.Name = in.Name if err := deepCopy_v1_VolumeSource(in.VolumeSource, &out.VolumeSource, c); err != nil { @@ -773,6 +817,14 @@ func deepCopy_v1_VolumeSource(in v1.VolumeSource, out *v1.VolumeSource, c *conve } else { out.CephFS = nil } + if in.Flocker != nil { + out.Flocker = new(v1.FlockerVolumeSource) + if err := deepCopy_v1_FlockerVolumeSource(*in.Flocker, out.Flocker, c); err != nil { + return err + } + } else { + out.Flocker = nil + } if in.DownwardAPI != nil { out.DownwardAPI = new(v1.DownwardAPIVolumeSource) if err := deepCopy_v1_DownwardAPIVolumeSource(*in.DownwardAPI, out.DownwardAPI, c); err != nil { @@ -781,50 +833,99 @@ func deepCopy_v1_VolumeSource(in v1.VolumeSource, out *v1.VolumeSource, c *conve } else { out.DownwardAPI = nil } - if in.Metadata != nil { - out.Metadata = new(v1.MetadataVolumeSource) - if err := deepCopy_v1_MetadataVolumeSource(*in.Metadata, out.Metadata, c); err != nil { + if in.FC != nil { + out.FC = new(v1.FCVolumeSource) + if err := deepCopy_v1_FCVolumeSource(*in.FC, out.FC, c); err != nil { return err } } else { - out.Metadata = nil + out.FC = nil } return nil } -func deepCopy_v1_APIVersion(in APIVersion, out *APIVersion, c *conversion.Cloner) error { +func deepCopy_v1beta1_APIVersion(in APIVersion, out *APIVersion, c *conversion.Cloner) error { out.Name = in.Name out.APIGroup = in.APIGroup return nil } -func deepCopy_v1_DaemonSet(in DaemonSet, out *DaemonSet, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_ClusterAutoscaler(in ClusterAutoscaler, out *ClusterAutoscaler, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { return err } - if err := deepCopy_v1_DaemonSetSpec(in.Spec, &out.Spec, c); err != nil { + if err := deepCopy_v1beta1_ClusterAutoscalerSpec(in.Spec, &out.Spec, c); err != nil { return err } - if err := deepCopy_v1_DaemonSetStatus(in.Status, &out.Status, c); err != nil { + return nil +} + +func deepCopy_v1beta1_ClusterAutoscalerList(in ClusterAutoscalerList, out *ClusterAutoscalerList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } + if in.Items != nil { + out.Items = make([]ClusterAutoscaler, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta1_ClusterAutoscaler(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } return nil } -func deepCopy_v1_DaemonSetList(in DaemonSetList, out *DaemonSetList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_ClusterAutoscalerSpec(in ClusterAutoscalerSpec, out *ClusterAutoscalerSpec, c *conversion.Cloner) error { + out.MinNodes = in.MinNodes + out.MaxNodes = in.MaxNodes + if in.TargetUtilization != nil { + out.TargetUtilization = make([]NodeUtilization, len(in.TargetUtilization)) + for i := range in.TargetUtilization { + if err := deepCopy_v1beta1_NodeUtilization(in.TargetUtilization[i], &out.TargetUtilization[i], c); err != nil { + return err + } + } + } else { + out.TargetUtilization = nil + } + return nil +} + +func deepCopy_v1beta1_DaemonSet(in DaemonSet, out *DaemonSet, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta1_DaemonSetSpec(in.Spec, &out.Spec, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_v1beta1_DaemonSetStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta1_DaemonSetList(in DaemonSetList, out *DaemonSetList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]DaemonSet, len(in.Items)) for i := range in.Items { - if err := deepCopy_v1_DaemonSet(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_v1beta1_DaemonSet(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -834,7 +935,7 @@ func deepCopy_v1_DaemonSetList(in DaemonSetList, out *DaemonSetList, c *conversi return nil } -func deepCopy_v1_DaemonSetSpec(in DaemonSetSpec, out *DaemonSetSpec, c *conversion.Cloner) error { +func deepCopy_v1beta1_DaemonSetSpec(in DaemonSetSpec, out *DaemonSetSpec, c *conversion.Cloner) error { if in.Selector != nil { out.Selector = make(map[string]string) for key, val := range in.Selector { @@ -854,40 +955,40 @@ func deepCopy_v1_DaemonSetSpec(in DaemonSetSpec, out *DaemonSetSpec, c *conversi return nil } -func deepCopy_v1_DaemonSetStatus(in DaemonSetStatus, out *DaemonSetStatus, c *conversion.Cloner) error { +func deepCopy_v1beta1_DaemonSetStatus(in DaemonSetStatus, out *DaemonSetStatus, c *conversion.Cloner) error { out.CurrentNumberScheduled = in.CurrentNumberScheduled out.NumberMisscheduled = in.NumberMisscheduled out.DesiredNumberScheduled = in.DesiredNumberScheduled return nil } -func deepCopy_v1_Deployment(in Deployment, out *Deployment, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_Deployment(in Deployment, out *Deployment, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { return err } - if err := deepCopy_v1_DeploymentSpec(in.Spec, &out.Spec, c); err != nil { + if err := deepCopy_v1beta1_DeploymentSpec(in.Spec, &out.Spec, c); err != nil { return err } - if err := deepCopy_v1_DeploymentStatus(in.Status, &out.Status, c); err != nil { + if err := deepCopy_v1beta1_DeploymentStatus(in.Status, &out.Status, c); err != nil { return err } return nil } -func deepCopy_v1_DeploymentList(in DeploymentList, out *DeploymentList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_DeploymentList(in DeploymentList, out *DeploymentList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]Deployment, len(in.Items)) for i := range in.Items { - if err := deepCopy_v1_Deployment(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_v1beta1_Deployment(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -897,7 +998,7 @@ func deepCopy_v1_DeploymentList(in DeploymentList, out *DeploymentList, c *conve return nil } -func deepCopy_v1_DeploymentSpec(in DeploymentSpec, out *DeploymentSpec, c *conversion.Cloner) error { +func deepCopy_v1beta1_DeploymentSpec(in DeploymentSpec, out *DeploymentSpec, c *conversion.Cloner) error { if in.Replicas != nil { out.Replicas = new(int) *out.Replicas = *in.Replicas @@ -920,7 +1021,7 @@ func deepCopy_v1_DeploymentSpec(in DeploymentSpec, out *DeploymentSpec, c *conve } else { out.Template = nil } - if err := deepCopy_v1_DeploymentStrategy(in.Strategy, &out.Strategy, c); err != nil { + if err := deepCopy_v1beta1_DeploymentStrategy(in.Strategy, &out.Strategy, c); err != nil { return err } if in.UniqueLabelKey != nil { @@ -932,17 +1033,17 @@ func deepCopy_v1_DeploymentSpec(in DeploymentSpec, out *DeploymentSpec, c *conve return nil } -func deepCopy_v1_DeploymentStatus(in DeploymentStatus, out *DeploymentStatus, c *conversion.Cloner) error { +func deepCopy_v1beta1_DeploymentStatus(in DeploymentStatus, out *DeploymentStatus, c *conversion.Cloner) error { out.Replicas = in.Replicas out.UpdatedReplicas = in.UpdatedReplicas return nil } -func deepCopy_v1_DeploymentStrategy(in DeploymentStrategy, out *DeploymentStrategy, c *conversion.Cloner) error { +func deepCopy_v1beta1_DeploymentStrategy(in DeploymentStrategy, out *DeploymentStrategy, c *conversion.Cloner) error { out.Type = in.Type if in.RollingUpdate != nil { out.RollingUpdate = new(RollingUpdateDeployment) - if err := deepCopy_v1_RollingUpdateDeployment(*in.RollingUpdate, out.RollingUpdate, c); err != nil { + if err := deepCopy_v1beta1_RollingUpdateDeployment(*in.RollingUpdate, out.RollingUpdate, c); err != nil { return err } } else { @@ -951,38 +1052,55 @@ func deepCopy_v1_DeploymentStrategy(in DeploymentStrategy, out *DeploymentStrate return nil } -func deepCopy_v1_HorizontalPodAutoscaler(in HorizontalPodAutoscaler, out *HorizontalPodAutoscaler, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_HTTPIngressPath(in HTTPIngressPath, out *HTTPIngressPath, c *conversion.Cloner) error { + out.Path = in.Path + if err := deepCopy_v1beta1_IngressBackend(in.Backend, &out.Backend, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta1_HTTPIngressRuleValue(in HTTPIngressRuleValue, out *HTTPIngressRuleValue, c *conversion.Cloner) error { + if in.Paths != nil { + out.Paths = make([]HTTPIngressPath, len(in.Paths)) + for i := range in.Paths { + if err := deepCopy_v1beta1_HTTPIngressPath(in.Paths[i], &out.Paths[i], c); err != nil { + return err + } + } + } else { + out.Paths = nil + } + return nil +} + +func deepCopy_v1beta1_HorizontalPodAutoscaler(in HorizontalPodAutoscaler, out *HorizontalPodAutoscaler, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { return err } - if err := deepCopy_v1_HorizontalPodAutoscalerSpec(in.Spec, &out.Spec, c); err != nil { + if err := deepCopy_v1beta1_HorizontalPodAutoscalerSpec(in.Spec, &out.Spec, c); err != nil { return err } - if in.Status != nil { - out.Status = new(HorizontalPodAutoscalerStatus) - if err := deepCopy_v1_HorizontalPodAutoscalerStatus(*in.Status, out.Status, c); err != nil { - return err - } - } else { - out.Status = nil + if err := deepCopy_v1beta1_HorizontalPodAutoscalerStatus(in.Status, &out.Status, c); err != nil { + return err } return nil } -func deepCopy_v1_HorizontalPodAutoscalerList(in HorizontalPodAutoscalerList, out *HorizontalPodAutoscalerList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_HorizontalPodAutoscalerList(in HorizontalPodAutoscalerList, out *HorizontalPodAutoscalerList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]HorizontalPodAutoscaler, len(in.Items)) for i := range in.Items { - if err := deepCopy_v1_HorizontalPodAutoscaler(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_v1beta1_HorizontalPodAutoscaler(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -992,37 +1110,37 @@ func deepCopy_v1_HorizontalPodAutoscalerList(in HorizontalPodAutoscalerList, out return nil } -func deepCopy_v1_HorizontalPodAutoscalerSpec(in HorizontalPodAutoscalerSpec, out *HorizontalPodAutoscalerSpec, c *conversion.Cloner) error { +func deepCopy_v1beta1_HorizontalPodAutoscalerSpec(in HorizontalPodAutoscalerSpec, out *HorizontalPodAutoscalerSpec, c *conversion.Cloner) error { if in.ScaleRef != nil { out.ScaleRef = new(SubresourceReference) - if err := deepCopy_v1_SubresourceReference(*in.ScaleRef, out.ScaleRef, c); err != nil { + if err := deepCopy_v1beta1_SubresourceReference(*in.ScaleRef, out.ScaleRef, c); err != nil { return err } } else { out.ScaleRef = nil } - out.MinCount = in.MinCount - out.MaxCount = in.MaxCount - if err := deepCopy_v1_ResourceConsumption(in.Target, &out.Target, c); err != nil { + out.MinReplicas = in.MinReplicas + out.MaxReplicas = in.MaxReplicas + if err := deepCopy_v1beta1_ResourceConsumption(in.Target, &out.Target, c); err != nil { return err } return nil } -func deepCopy_v1_HorizontalPodAutoscalerStatus(in HorizontalPodAutoscalerStatus, out *HorizontalPodAutoscalerStatus, c *conversion.Cloner) error { +func deepCopy_v1beta1_HorizontalPodAutoscalerStatus(in HorizontalPodAutoscalerStatus, out *HorizontalPodAutoscalerStatus, c *conversion.Cloner) error { out.CurrentReplicas = in.CurrentReplicas out.DesiredReplicas = in.DesiredReplicas if in.CurrentConsumption != nil { out.CurrentConsumption = new(ResourceConsumption) - if err := deepCopy_v1_ResourceConsumption(*in.CurrentConsumption, out.CurrentConsumption, c); err != nil { + if err := deepCopy_v1beta1_ResourceConsumption(*in.CurrentConsumption, out.CurrentConsumption, c); err != nil { return err } } else { out.CurrentConsumption = nil } if in.LastScaleTimestamp != nil { - out.LastScaleTimestamp = new(util.Time) - if err := deepCopy_util_Time(*in.LastScaleTimestamp, out.LastScaleTimestamp, c); err != nil { + out.LastScaleTimestamp = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.LastScaleTimestamp, out.LastScaleTimestamp, c); err != nil { return err } } else { @@ -1031,29 +1149,122 @@ func deepCopy_v1_HorizontalPodAutoscalerStatus(in HorizontalPodAutoscalerStatus, return nil } -func deepCopy_v1_Job(in Job, out *Job, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_Ingress(in Ingress, out *Ingress, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta1_IngressSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + if err := deepCopy_v1beta1_IngressStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta1_IngressBackend(in IngressBackend, out *IngressBackend, c *conversion.Cloner) error { + out.ServiceName = in.ServiceName + if err := deepCopy_util_IntOrString(in.ServicePort, &out.ServicePort, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta1_IngressList(in IngressList, out *IngressList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Ingress, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta1_Ingress(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta1_IngressRule(in IngressRule, out *IngressRule, c *conversion.Cloner) error { + out.Host = in.Host + if err := deepCopy_v1beta1_IngressRuleValue(in.IngressRuleValue, &out.IngressRuleValue, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta1_IngressRuleValue(in IngressRuleValue, out *IngressRuleValue, c *conversion.Cloner) error { + if in.HTTP != nil { + out.HTTP = new(HTTPIngressRuleValue) + if err := deepCopy_v1beta1_HTTPIngressRuleValue(*in.HTTP, out.HTTP, c); err != nil { + return err + } + } else { + out.HTTP = nil + } + return nil +} + +func deepCopy_v1beta1_IngressSpec(in IngressSpec, out *IngressSpec, c *conversion.Cloner) error { + if in.Backend != nil { + out.Backend = new(IngressBackend) + if err := deepCopy_v1beta1_IngressBackend(*in.Backend, out.Backend, c); err != nil { + return err + } + } else { + out.Backend = nil + } + if in.Rules != nil { + out.Rules = make([]IngressRule, len(in.Rules)) + for i := range in.Rules { + if err := deepCopy_v1beta1_IngressRule(in.Rules[i], &out.Rules[i], c); err != nil { + return err + } + } + } else { + out.Rules = nil + } + return nil +} + +func deepCopy_v1beta1_IngressStatus(in IngressStatus, out *IngressStatus, c *conversion.Cloner) error { + if err := deepCopy_v1_LoadBalancerStatus(in.LoadBalancer, &out.LoadBalancer, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta1_Job(in Job, out *Job, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { return err } - if err := deepCopy_v1_JobSpec(in.Spec, &out.Spec, c); err != nil { + if err := deepCopy_v1beta1_JobSpec(in.Spec, &out.Spec, c); err != nil { return err } - if err := deepCopy_v1_JobStatus(in.Status, &out.Status, c); err != nil { + if err := deepCopy_v1beta1_JobStatus(in.Status, &out.Status, c); err != nil { return err } return nil } -func deepCopy_v1_JobCondition(in JobCondition, out *JobCondition, c *conversion.Cloner) error { +func deepCopy_v1beta1_JobCondition(in JobCondition, out *JobCondition, c *conversion.Cloner) error { out.Type = in.Type out.Status = in.Status - if err := deepCopy_util_Time(in.LastProbeTime, &out.LastProbeTime, c); err != nil { + if err := deepCopy_unversioned_Time(in.LastProbeTime, &out.LastProbeTime, c); err != nil { return err } - if err := deepCopy_util_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { + if err := deepCopy_unversioned_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { return err } out.Reason = in.Reason @@ -1061,17 +1272,17 @@ func deepCopy_v1_JobCondition(in JobCondition, out *JobCondition, c *conversion. return nil } -func deepCopy_v1_JobList(in JobList, out *JobList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_JobList(in JobList, out *JobList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]Job, len(in.Items)) for i := range in.Items { - if err := deepCopy_v1_Job(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_v1beta1_Job(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -1081,7 +1292,7 @@ func deepCopy_v1_JobList(in JobList, out *JobList, c *conversion.Cloner) error { return nil } -func deepCopy_v1_JobSpec(in JobSpec, out *JobSpec, c *conversion.Cloner) error { +func deepCopy_v1beta1_JobSpec(in JobSpec, out *JobSpec, c *conversion.Cloner) error { if in.Parallelism != nil { out.Parallelism = new(int) *out.Parallelism = *in.Parallelism @@ -1102,22 +1313,17 @@ func deepCopy_v1_JobSpec(in JobSpec, out *JobSpec, c *conversion.Cloner) error { } else { out.Selector = nil } - if in.Template != nil { - out.Template = new(v1.PodTemplateSpec) - if err := deepCopy_v1_PodTemplateSpec(*in.Template, out.Template, c); err != nil { - return err - } - } else { - out.Template = nil + if err := deepCopy_v1_PodTemplateSpec(in.Template, &out.Template, c); err != nil { + return err } return nil } -func deepCopy_v1_JobStatus(in JobStatus, out *JobStatus, c *conversion.Cloner) error { +func deepCopy_v1beta1_JobStatus(in JobStatus, out *JobStatus, c *conversion.Cloner) error { if in.Conditions != nil { out.Conditions = make([]JobCondition, len(in.Conditions)) for i := range in.Conditions { - if err := deepCopy_v1_JobCondition(in.Conditions[i], &out.Conditions[i], c); err != nil { + if err := deepCopy_v1beta1_JobCondition(in.Conditions[i], &out.Conditions[i], c); err != nil { return err } } @@ -1125,35 +1331,41 @@ func deepCopy_v1_JobStatus(in JobStatus, out *JobStatus, c *conversion.Cloner) e out.Conditions = nil } if in.StartTime != nil { - out.StartTime = new(util.Time) - if err := deepCopy_util_Time(*in.StartTime, out.StartTime, c); err != nil { + out.StartTime = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.StartTime, out.StartTime, c); err != nil { return err } } else { out.StartTime = nil } if in.CompletionTime != nil { - out.CompletionTime = new(util.Time) - if err := deepCopy_util_Time(*in.CompletionTime, out.CompletionTime, c); err != nil { + out.CompletionTime = new(unversioned.Time) + if err := deepCopy_unversioned_Time(*in.CompletionTime, out.CompletionTime, c); err != nil { return err } } else { out.CompletionTime = nil } out.Active = in.Active - out.Successful = in.Successful - out.Unsuccessful = in.Unsuccessful + out.Succeeded = in.Succeeded + out.Failed = in.Failed return nil } -func deepCopy_v1_ReplicationControllerDummy(in ReplicationControllerDummy, out *ReplicationControllerDummy, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_NodeUtilization(in NodeUtilization, out *NodeUtilization, c *conversion.Cloner) error { + out.Resource = in.Resource + out.Value = in.Value + return nil +} + +func deepCopy_v1beta1_ReplicationControllerDummy(in ReplicationControllerDummy, out *ReplicationControllerDummy, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } return nil } -func deepCopy_v1_ResourceConsumption(in ResourceConsumption, out *ResourceConsumption, c *conversion.Cloner) error { +func deepCopy_v1beta1_ResourceConsumption(in ResourceConsumption, out *ResourceConsumption, c *conversion.Cloner) error { out.Resource = in.Resource if err := deepCopy_resource_Quantity(in.Quantity, &out.Quantity, c); err != nil { return err @@ -1161,7 +1373,7 @@ func deepCopy_v1_ResourceConsumption(in ResourceConsumption, out *ResourceConsum return nil } -func deepCopy_v1_RollingUpdateDeployment(in RollingUpdateDeployment, out *RollingUpdateDeployment, c *conversion.Cloner) error { +func deepCopy_v1beta1_RollingUpdateDeployment(in RollingUpdateDeployment, out *RollingUpdateDeployment, c *conversion.Cloner) error { if in.MaxUnavailable != nil { out.MaxUnavailable = new(util.IntOrString) if err := deepCopy_util_IntOrString(*in.MaxUnavailable, out.MaxUnavailable, c); err != nil { @@ -1182,28 +1394,28 @@ func deepCopy_v1_RollingUpdateDeployment(in RollingUpdateDeployment, out *Rollin return nil } -func deepCopy_v1_Scale(in Scale, out *Scale, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_Scale(in Scale, out *Scale, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { return err } - if err := deepCopy_v1_ScaleSpec(in.Spec, &out.Spec, c); err != nil { + if err := deepCopy_v1beta1_ScaleSpec(in.Spec, &out.Spec, c); err != nil { return err } - if err := deepCopy_v1_ScaleStatus(in.Status, &out.Status, c); err != nil { + if err := deepCopy_v1beta1_ScaleStatus(in.Status, &out.Status, c); err != nil { return err } return nil } -func deepCopy_v1_ScaleSpec(in ScaleSpec, out *ScaleSpec, c *conversion.Cloner) error { +func deepCopy_v1beta1_ScaleSpec(in ScaleSpec, out *ScaleSpec, c *conversion.Cloner) error { out.Replicas = in.Replicas return nil } -func deepCopy_v1_ScaleStatus(in ScaleStatus, out *ScaleStatus, c *conversion.Cloner) error { +func deepCopy_v1beta1_ScaleStatus(in ScaleStatus, out *ScaleStatus, c *conversion.Cloner) error { out.Replicas = in.Replicas if in.Selector != nil { out.Selector = make(map[string]string) @@ -1216,7 +1428,7 @@ func deepCopy_v1_ScaleStatus(in ScaleStatus, out *ScaleStatus, c *conversion.Clo return nil } -func deepCopy_v1_SubresourceReference(in SubresourceReference, out *SubresourceReference, c *conversion.Cloner) error { +func deepCopy_v1beta1_SubresourceReference(in SubresourceReference, out *SubresourceReference, c *conversion.Cloner) error { out.Kind = in.Kind out.Namespace = in.Namespace out.Name = in.Name @@ -1225,8 +1437,8 @@ func deepCopy_v1_SubresourceReference(in SubresourceReference, out *SubresourceR return nil } -func deepCopy_v1_ThirdPartyResource(in ThirdPartyResource, out *ThirdPartyResource, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_ThirdPartyResource(in ThirdPartyResource, out *ThirdPartyResource, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1236,7 +1448,7 @@ func deepCopy_v1_ThirdPartyResource(in ThirdPartyResource, out *ThirdPartyResour if in.Versions != nil { out.Versions = make([]APIVersion, len(in.Versions)) for i := range in.Versions { - if err := deepCopy_v1_APIVersion(in.Versions[i], &out.Versions[i], c); err != nil { + if err := deepCopy_v1beta1_APIVersion(in.Versions[i], &out.Versions[i], c); err != nil { return err } } @@ -1246,8 +1458,8 @@ func deepCopy_v1_ThirdPartyResource(in ThirdPartyResource, out *ThirdPartyResour return nil } -func deepCopy_v1_ThirdPartyResourceData(in ThirdPartyResourceData, out *ThirdPartyResourceData, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_ThirdPartyResourceData(in ThirdPartyResourceData, out *ThirdPartyResourceData, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { @@ -1264,17 +1476,17 @@ func deepCopy_v1_ThirdPartyResourceData(in ThirdPartyResourceData, out *ThirdPar return nil } -func deepCopy_v1_ThirdPartyResourceDataList(in ThirdPartyResourceDataList, out *ThirdPartyResourceDataList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_ThirdPartyResourceDataList(in ThirdPartyResourceDataList, out *ThirdPartyResourceDataList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]ThirdPartyResourceData, len(in.Items)) for i := range in.Items { - if err := deepCopy_v1_ThirdPartyResourceData(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_v1beta1_ThirdPartyResourceData(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -1284,17 +1496,17 @@ func deepCopy_v1_ThirdPartyResourceDataList(in ThirdPartyResourceDataList, out * return nil } -func deepCopy_v1_ThirdPartyResourceList(in ThirdPartyResourceList, out *ThirdPartyResourceList, c *conversion.Cloner) error { - if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { +func deepCopy_v1beta1_ThirdPartyResourceList(in ThirdPartyResourceList, out *ThirdPartyResourceList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err } - if err := deepCopy_v1_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { return err } if in.Items != nil { out.Items = make([]ThirdPartyResource, len(in.Items)) for i := range in.Items { - if err := deepCopy_v1_ThirdPartyResource(in.Items[i], &out.Items[i], c); err != nil { + if err := deepCopy_v1beta1_ThirdPartyResource(in.Items[i], &out.Items[i], c); err != nil { return err } } @@ -1311,18 +1523,12 @@ func deepCopy_util_IntOrString(in util.IntOrString, out *util.IntOrString, c *co return nil } -func deepCopy_util_Time(in util.Time, out *util.Time, c *conversion.Cloner) error { - if newVal, err := c.DeepCopy(in.Time); err != nil { - return err - } else { - out.Time = newVal.(time.Time) - } - return nil -} - func init() { err := api.Scheme.AddGeneratedDeepCopyFuncs( deepCopy_resource_Quantity, + deepCopy_unversioned_ListMeta, + deepCopy_unversioned_Time, + deepCopy_unversioned_TypeMeta, deepCopy_v1_AWSElasticBlockStoreVolumeSource, deepCopy_v1_Capabilities, deepCopy_v1_CephFSVolumeSource, @@ -1335,6 +1541,8 @@ func init() { deepCopy_v1_EnvVar, deepCopy_v1_EnvVarSource, deepCopy_v1_ExecAction, + deepCopy_v1_FCVolumeSource, + deepCopy_v1_FlockerVolumeSource, deepCopy_v1_GCEPersistentDiskVolumeSource, deepCopy_v1_GitRepoVolumeSource, deepCopy_v1_GlusterfsVolumeSource, @@ -1343,14 +1551,14 @@ func init() { deepCopy_v1_HostPathVolumeSource, deepCopy_v1_ISCSIVolumeSource, deepCopy_v1_Lifecycle, - deepCopy_v1_ListMeta, + deepCopy_v1_LoadBalancerIngress, + deepCopy_v1_LoadBalancerStatus, deepCopy_v1_LocalObjectReference, - deepCopy_v1_MetadataFile, - deepCopy_v1_MetadataVolumeSource, deepCopy_v1_NFSVolumeSource, deepCopy_v1_ObjectFieldSelector, deepCopy_v1_ObjectMeta, deepCopy_v1_PersistentVolumeClaimVolumeSource, + deepCopy_v1_PodSecurityContext, deepCopy_v1_PodSpec, deepCopy_v1_PodTemplateSpec, deepCopy_v1_Probe, @@ -1360,42 +1568,53 @@ func init() { deepCopy_v1_SecretVolumeSource, deepCopy_v1_SecurityContext, deepCopy_v1_TCPSocketAction, - deepCopy_v1_TypeMeta, deepCopy_v1_Volume, deepCopy_v1_VolumeMount, deepCopy_v1_VolumeSource, - deepCopy_v1_APIVersion, - deepCopy_v1_DaemonSet, - deepCopy_v1_DaemonSetList, - deepCopy_v1_DaemonSetSpec, - deepCopy_v1_DaemonSetStatus, - deepCopy_v1_Deployment, - deepCopy_v1_DeploymentList, - deepCopy_v1_DeploymentSpec, - deepCopy_v1_DeploymentStatus, - deepCopy_v1_DeploymentStrategy, - deepCopy_v1_HorizontalPodAutoscaler, - deepCopy_v1_HorizontalPodAutoscalerList, - deepCopy_v1_HorizontalPodAutoscalerSpec, - deepCopy_v1_HorizontalPodAutoscalerStatus, - deepCopy_v1_Job, - deepCopy_v1_JobCondition, - deepCopy_v1_JobList, - deepCopy_v1_JobSpec, - deepCopy_v1_JobStatus, - deepCopy_v1_ReplicationControllerDummy, - deepCopy_v1_ResourceConsumption, - deepCopy_v1_RollingUpdateDeployment, - deepCopy_v1_Scale, - deepCopy_v1_ScaleSpec, - deepCopy_v1_ScaleStatus, - deepCopy_v1_SubresourceReference, - deepCopy_v1_ThirdPartyResource, - deepCopy_v1_ThirdPartyResourceData, - deepCopy_v1_ThirdPartyResourceDataList, - deepCopy_v1_ThirdPartyResourceList, + deepCopy_v1beta1_APIVersion, + deepCopy_v1beta1_ClusterAutoscaler, + deepCopy_v1beta1_ClusterAutoscalerList, + deepCopy_v1beta1_ClusterAutoscalerSpec, + deepCopy_v1beta1_DaemonSet, + deepCopy_v1beta1_DaemonSetList, + deepCopy_v1beta1_DaemonSetSpec, + deepCopy_v1beta1_DaemonSetStatus, + deepCopy_v1beta1_Deployment, + deepCopy_v1beta1_DeploymentList, + deepCopy_v1beta1_DeploymentSpec, + deepCopy_v1beta1_DeploymentStatus, + deepCopy_v1beta1_DeploymentStrategy, + deepCopy_v1beta1_HTTPIngressPath, + deepCopy_v1beta1_HTTPIngressRuleValue, + deepCopy_v1beta1_HorizontalPodAutoscaler, + deepCopy_v1beta1_HorizontalPodAutoscalerList, + deepCopy_v1beta1_HorizontalPodAutoscalerSpec, + deepCopy_v1beta1_HorizontalPodAutoscalerStatus, + deepCopy_v1beta1_Ingress, + deepCopy_v1beta1_IngressBackend, + deepCopy_v1beta1_IngressList, + deepCopy_v1beta1_IngressRule, + deepCopy_v1beta1_IngressRuleValue, + deepCopy_v1beta1_IngressSpec, + deepCopy_v1beta1_IngressStatus, + deepCopy_v1beta1_Job, + deepCopy_v1beta1_JobCondition, + deepCopy_v1beta1_JobList, + deepCopy_v1beta1_JobSpec, + deepCopy_v1beta1_JobStatus, + deepCopy_v1beta1_NodeUtilization, + deepCopy_v1beta1_ReplicationControllerDummy, + deepCopy_v1beta1_ResourceConsumption, + deepCopy_v1beta1_RollingUpdateDeployment, + deepCopy_v1beta1_Scale, + deepCopy_v1beta1_ScaleSpec, + deepCopy_v1beta1_ScaleStatus, + deepCopy_v1beta1_SubresourceReference, + deepCopy_v1beta1_ThirdPartyResource, + deepCopy_v1beta1_ThirdPartyResourceData, + deepCopy_v1beta1_ThirdPartyResourceDataList, + deepCopy_v1beta1_ThirdPartyResourceList, deepCopy_util_IntOrString, - deepCopy_util_Time, ) if err != nil { // if one of the deep copy functions is malformed, detect it immediately. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/defaults.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults.go similarity index 67% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/defaults.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults.go index cc141513c25b..07c691580757 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/defaults.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1 +package v1beta1 import ( "k8s.io/kubernetes/pkg/api" @@ -25,7 +25,7 @@ func addDefaultingFuncs() { api.Scheme.AddDefaultingFuncs( func(obj *APIVersion) { if len(obj.APIGroup) == 0 { - obj.APIGroup = "experimental" + obj.APIGroup = "extensions" } }, func(obj *DaemonSet) { @@ -44,17 +44,30 @@ func addDefaultingFuncs() { } }, func(obj *Deployment) { + // Default labels and selector to labels from pod template spec. + var labels map[string]string + if obj.Spec.Template != nil { + labels = obj.Spec.Template.Labels + } + if labels != nil { + if len(obj.Spec.Selector) == 0 { + obj.Spec.Selector = labels + } + if len(obj.Labels) == 0 { + obj.Labels = labels + } + } // Set DeploymentSpec.Replicas to 1 if it is not set. if obj.Spec.Replicas == nil { obj.Spec.Replicas = new(int) *obj.Spec.Replicas = 1 } strategy := &obj.Spec.Strategy - // Set default DeploymentType as RollingUpdate. + // Set default DeploymentStrategyType as RollingUpdate. if strategy.Type == "" { - strategy.Type = DeploymentRollingUpdate + strategy.Type = RollingUpdateDeploymentStrategyType } - if strategy.Type == DeploymentRollingUpdate { + if strategy.Type == RollingUpdateDeploymentStrategyType { if strategy.RollingUpdate == nil { rollingUpdate := RollingUpdateDeployment{} strategy.RollingUpdate = &rollingUpdate @@ -75,5 +88,24 @@ func addDefaultingFuncs() { *obj.Spec.UniqueLabelKey = "deployment.kubernetes.io/podTemplateHash" } }, + func(obj *Job) { + labels := obj.Spec.Template.Labels + // TODO: support templates defined elsewhere when we support them in the API + if labels != nil { + if len(obj.Spec.Selector) == 0 { + obj.Spec.Selector = labels + } + if len(obj.Labels) == 0 { + obj.Labels = labels + } + } + if obj.Spec.Completions == nil { + completions := 1 + obj.Spec.Completions = &completions + } + if obj.Spec.Parallelism == nil { + obj.Spec.Parallelism = obj.Spec.Completions + } + }, ) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/defaults_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults_test.go similarity index 69% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/defaults_test.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults_test.go index afc00939fa2e..4eb9069b3212 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/defaults_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1 +package v1beta1 import ( "reflect" @@ -98,7 +98,7 @@ func TestSetDefaultDeployment(t *testing.T) { Spec: DeploymentSpec{ Replicas: newInt(1), Strategy: DeploymentStrategy{ - Type: DeploymentRollingUpdate, + Type: RollingUpdateDeploymentStrategyType, RollingUpdate: &RollingUpdateDeployment{ MaxSurge: &defaultIntOrString, MaxUnavailable: &defaultIntOrString, @@ -123,7 +123,7 @@ func TestSetDefaultDeployment(t *testing.T) { Spec: DeploymentSpec{ Replicas: newInt(5), Strategy: DeploymentStrategy{ - Type: DeploymentRollingUpdate, + Type: RollingUpdateDeploymentStrategyType, RollingUpdate: &RollingUpdateDeployment{ MaxSurge: &differentIntOrString, MaxUnavailable: &defaultIntOrString, @@ -138,7 +138,7 @@ func TestSetDefaultDeployment(t *testing.T) { Spec: DeploymentSpec{ Replicas: newInt(5), Strategy: DeploymentStrategy{ - Type: DeploymentRecreate, + Type: RecreateDeploymentStrategyType, }, }, }, @@ -146,7 +146,7 @@ func TestSetDefaultDeployment(t *testing.T) { Spec: DeploymentSpec{ Replicas: newInt(5), Strategy: DeploymentStrategy{ - Type: DeploymentRecreate, + Type: RecreateDeploymentStrategyType, }, UniqueLabelKey: newString(deploymentLabelKey), }, @@ -157,7 +157,7 @@ func TestSetDefaultDeployment(t *testing.T) { Spec: DeploymentSpec{ Replicas: newInt(5), Strategy: DeploymentStrategy{ - Type: DeploymentRecreate, + Type: RecreateDeploymentStrategyType, }, UniqueLabelKey: newString("customDeploymentKey"), }, @@ -166,7 +166,7 @@ func TestSetDefaultDeployment(t *testing.T) { Spec: DeploymentSpec{ Replicas: newInt(5), Strategy: DeploymentStrategy{ - Type: DeploymentRecreate, + Type: RecreateDeploymentStrategyType, }, UniqueLabelKey: newString("customDeploymentKey"), }, @@ -189,8 +189,76 @@ func TestSetDefaultDeployment(t *testing.T) { } } +func TestSetDefaultJob(t *testing.T) { + expected := &Job{ + Spec: JobSpec{ + Selector: map[string]string{"job": "selector"}, + Completions: newInt(1), + Parallelism: newInt(1), + }, + } + tests := []*Job{ + // selector set explicitly, completions and parallelism - default + { + Spec: JobSpec{ + Selector: map[string]string{"job": "selector"}, + }, + }, + // selector from template labels, completions and parallelism - default + { + Spec: JobSpec{ + Template: v1.PodTemplateSpec{ + ObjectMeta: v1.ObjectMeta{ + Labels: map[string]string{"job": "selector"}, + }, + }, + }, + }, + // selector from template labels, completions set explicitly, parallelism - default + { + Spec: JobSpec{ + Completions: newInt(1), + Template: v1.PodTemplateSpec{ + ObjectMeta: v1.ObjectMeta{ + Labels: map[string]string{"job": "selector"}, + }, + }, + }, + }, + // selector from template labels, completions - default, parallelism set explicitly + { + Spec: JobSpec{ + Parallelism: newInt(1), + Template: v1.PodTemplateSpec{ + ObjectMeta: v1.ObjectMeta{ + Labels: map[string]string{"job": "selector"}, + }, + }, + }, + }, + } + + for _, original := range tests { + obj2 := roundTrip(t, runtime.Object(original)) + got, ok := obj2.(*Job) + if !ok { + t.Errorf("unexpected object: %v", got) + t.FailNow() + } + if *got.Spec.Completions != *expected.Spec.Completions { + t.Errorf("got different completions than expected: %d %d", *got.Spec.Completions, *expected.Spec.Completions) + } + if *got.Spec.Parallelism != *expected.Spec.Parallelism { + t.Errorf("got different parallelism than expected: %d %d", *got.Spec.Parallelism, *expected.Spec.Parallelism) + } + if !reflect.DeepEqual(got.Spec.Selector, expected.Spec.Selector) { + t.Errorf("got different selectors %#v %#v", got.Spec.Selector, expected.Spec.Selector) + } + } +} + func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { - data, err := v1.Codec.Encode(obj) + data, err := Codec.Encode(obj) if err != nil { t.Errorf("%v\n %#v", err, obj) return nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/register.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/register.go similarity index 81% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/register.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/register.go index 88d0514b5a15..05c4b09c0af3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/register.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/register.go @@ -14,14 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1 +package v1beta1 import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/runtime" ) -var Codec = runtime.CodecFor(api.Scheme, "v1") +var Codec = runtime.CodecFor(api.Scheme, "extensions/v1beta1") func init() { addKnownTypes() @@ -31,7 +31,9 @@ func init() { // Adds the list of known types to api.Scheme. func addKnownTypes() { - api.Scheme.AddKnownTypes("v1", + api.Scheme.AddKnownTypes("extensions/v1beta1", + &ClusterAutoscaler{}, + &ClusterAutoscalerList{}, &Deployment{}, &DeploymentList{}, &HorizontalPodAutoscaler{}, @@ -46,9 +48,13 @@ func addKnownTypes() { &DaemonSet{}, &ThirdPartyResourceData{}, &ThirdPartyResourceDataList{}, + &Ingress{}, + &IngressList{}, ) } +func (*ClusterAutoscaler) IsAnAPIObject() {} +func (*ClusterAutoscalerList) IsAnAPIObject() {} func (*Deployment) IsAnAPIObject() {} func (*DeploymentList) IsAnAPIObject() {} func (*HorizontalPodAutoscaler) IsAnAPIObject() {} @@ -63,3 +69,5 @@ func (*DaemonSet) IsAnAPIObject() {} func (*DaemonSetList) IsAnAPIObject() {} func (*ThirdPartyResourceData) IsAnAPIObject() {} func (*ThirdPartyResourceDataList) IsAnAPIObject() {} +func (*Ingress) IsAnAPIObject() {} +func (*IngressList) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.go similarity index 59% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/types.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.go index 3be346140f4b..5b05de54a2f3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.go @@ -14,10 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1 +package v1beta1 import ( "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/util" ) @@ -39,7 +40,7 @@ type ScaleStatus struct { // Scale subresource, applicable to ReplicationControllers and (in future) Deployment. type Scale struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata. v1.ObjectMeta `json:"metadata,omitempty"` @@ -52,7 +53,7 @@ type Scale struct { // Dummy definition type ReplicationControllerDummy struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` } // SubresourceReference contains enough information to let you inspect or modify the referred subresource. @@ -82,10 +83,10 @@ type HorizontalPodAutoscalerSpec struct { // ScaleRef is a reference to Scale subresource. HorizontalPodAutoscaler will learn the current resource consumption from its status, // and will set the desired number of pods by modyfying its spec. ScaleRef *SubresourceReference `json:"scaleRef"` - // MinCount is the lower limit for the number of pods that can be set by the autoscaler. - MinCount int `json:"minCount"` - // MaxCount is the upper limit for the number of pods that can be set by the autoscaler. It cannot be smaller than MinCount. - MaxCount int `json:"maxCount"` + // MinReplicas is the lower limit for the number of pods that can be set by the autoscaler. + MinReplicas int `json:"minReplicas"` + // MaxReplicas is the upper limit for the number of pods that can be set by the autoscaler. It cannot be smaller than MinReplicas. + MaxReplicas int `json:"maxReplicas"` // Target is the target average consumption of the given resource that the autoscaler will try to maintain by adjusting the desired number of pods. // Currently two types of resources are supported: "cpu" and "memory". Target ResourceConsumption `json:"target"` @@ -106,12 +107,12 @@ type HorizontalPodAutoscalerStatus struct { // LastScaleTimestamp is the last time the HorizontalPodAutoscaler scaled the number of pods. // This is used by the autoscaler to controll how often the number of pods is changed. - LastScaleTimestamp *util.Time `json:"lastScaleTimestamp,omitempty"` + LastScaleTimestamp *unversioned.Time `json:"lastScaleTimestamp,omitempty"` } // HorizontalPodAutoscaler represents the configuration of a horizontal pod autoscaler. type HorizontalPodAutoscaler struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata v1.ObjectMeta `json:"metadata,omitempty"` @@ -119,14 +120,14 @@ type HorizontalPodAutoscaler struct { Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty"` // Status represents the current information about the autoscaler. - Status *HorizontalPodAutoscalerStatus `json:"status,omitempty"` + Status HorizontalPodAutoscalerStatus `json:"status,omitempty"` } // HorizontalPodAutoscalerList is a list of HorizontalPodAutoscalers. type HorizontalPodAutoscalerList struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. - v1.ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of HorizontalPodAutoscalers. Items []HorizontalPodAutoscaler `json:"items"` @@ -135,7 +136,7 @@ type HorizontalPodAutoscalerList struct { // A ThirdPartyResource is a generic representation of a resource, it is used by add-ons and plugins to add new resource // types to the API. It consists of one or more Versions of the api. type ThirdPartyResource struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object metadata v1.ObjectMeta `json:"metadata,omitempty"` @@ -149,10 +150,10 @@ type ThirdPartyResource struct { // ThirdPartyResourceList is a list of ThirdPartyResources. type ThirdPartyResourceList struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. - v1.ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of ThirdPartyResources. Items []ThirdPartyResource `json:"items"` @@ -169,7 +170,7 @@ type APIVersion struct { // An internal object, used for versioned storage in etcd. Not exposed to the end user. type ThirdPartyResourceData struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object metadata. v1.ObjectMeta `json:"metadata,omitempty"` @@ -179,7 +180,7 @@ type ThirdPartyResourceData struct { // Deployment enables declarative updates for Pods and ReplicationControllers. type Deployment struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object metadata. v1.ObjectMeta `json:"metadata,omitempty"` @@ -197,7 +198,7 @@ type DeploymentSpec struct { Replicas *int `json:"replicas,omitempty"` // Label selector for pods. Existing ReplicationControllers whose pods are - // selected by this will be scaled down. + // selected by this will be the ones affected by this deployment. Selector map[string]string `json:"selector,omitempty"` // Template describes the pods that will be created. @@ -220,9 +221,9 @@ type DeploymentSpec struct { // DeploymentStrategy describes how to replace existing pods with new ones. type DeploymentStrategy struct { // Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate. - Type DeploymentType `json:"type,omitempty"` + Type DeploymentStrategyType `json:"type,omitempty"` - // Rolling update config params. Present only if DeploymentType = + // Rolling update config params. Present only if DeploymentStrategyType = // RollingUpdate. //--- // TODO: Update this to follow our convention for oneOf, whatever we decide it @@ -230,40 +231,41 @@ type DeploymentStrategy struct { RollingUpdate *RollingUpdateDeployment `json:"rollingUpdate,omitempty"` } -type DeploymentType string +type DeploymentStrategyType string const ( // Kill all existing pods before creating new ones. - DeploymentRecreate DeploymentType = "Recreate" + RecreateDeploymentStrategyType DeploymentStrategyType = "Recreate" // Replace the old RCs by new one using rolling update i.e gradually scale down the old RCs and scale up the new one. - DeploymentRollingUpdate DeploymentType = "RollingUpdate" + RollingUpdateDeploymentStrategyType DeploymentStrategyType = "RollingUpdate" ) // Spec to control the desired behavior of rolling update. type RollingUpdateDeployment struct { // The maximum number of pods that can be unavailable during the update. - // Value can be an absolute number (ex: 5) or a percentage of total pods at the start of update (ex: 10%). + // Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). // Absolute number is calculated from percentage by rounding up. // This can not be 0 if MaxSurge is 0. // By default, a fixed value of 1 is used. - // Example: when this is set to 30%, the old RC can be scaled down by 30% + // Example: when this is set to 30%, the old RC can be scaled down to 70% of desired pods // immediately when the rolling update starts. Once new pods are ready, old RC // can be scaled down further, followed by scaling up the new RC, ensuring - // that at least 70% of original number of pods are available at all times - // during the update. + // that the total number of pods available at all times during the update is at + // least 70% of desired pods. MaxUnavailable *util.IntOrString `json:"maxUnavailable,omitempty"` - // The maximum number of pods that can be scheduled above the original number of + // The maximum number of pods that can be scheduled above the desired number of // pods. - // Value can be an absolute number (ex: 5) or a percentage of total pods at - // the start of the update (ex: 10%). This can not be 0 if MaxUnavailable is 0. + // Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + // This can not be 0 if MaxUnavailable is 0. // Absolute number is calculated from percentage by rounding up. // By default, a value of 1 is used. - // Example: when this is set to 30%, the new RC can be scaled up by 30% - // immediately when the rolling update starts. Once old pods have been killed, + // Example: when this is set to 30%, the new RC can be scaled up immediately when + // the rolling update starts, such that the total number of old and new pods do not exceed + // 130% of desired pods. Once old pods have been killed, // new RC can be scaled up further, ensuring that total number of pods running - // at any time during the update is atmost 130% of original pods. + // at any time during the update is atmost 130% of desired pods. MaxSurge *util.IntOrString `json:"maxSurge,omitempty"` // Minimum number of seconds for which a newly created pod should be ready @@ -274,19 +276,18 @@ type RollingUpdateDeployment struct { // DeploymentStatus is the most recently observed status of the Deployment. type DeploymentStatus struct { - // Total number of ready pods targeted by this deployment (this - // includes both the old and new pods). + // Total number of non-terminated pods targeted by this deployment (their labels match the selector). Replicas int `json:"replicas,omitempty"` - // Total number of new ready pods with the desired template spec. + // Total number of non-terminated pods targeted by this deployment that have the desired template spec. UpdatedReplicas int `json:"updatedReplicas,omitempty"` } // DeploymentList is a list of Deployments. type DeploymentList struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. - v1.ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of Deployments. Items []Deployment `json:"items"` @@ -310,22 +311,25 @@ type DaemonSetSpec struct { // DaemonSetStatus represents the current status of a daemon set. type DaemonSetStatus struct { - // CurrentNumberScheduled is the number of nodes that are running exactly 1 + // CurrentNumberScheduled is the number of nodes that are running at least 1 // daemon pod and are supposed to run the daemon pod. + // More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md CurrentNumberScheduled int `json:"currentNumberScheduled"` // NumberMisscheduled is the number of nodes that are running the daemon pod, but are // not supposed to run the daemon pod. + // More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md NumberMisscheduled int `json:"numberMisscheduled"` // DesiredNumberScheduled is the total number of nodes that should be running the daemon // pod (including nodes correctly running the daemon pod). + // More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md DesiredNumberScheduled int `json:"desiredNumberScheduled"` } // DaemonSet represents the configuration of a daemon set. type DaemonSet struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata v1.ObjectMeta `json:"metadata,omitempty"` @@ -344,10 +348,10 @@ type DaemonSet struct { // DaemonSetList is a collection of daemon sets. type DaemonSetList struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata - v1.ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of daemon sets. Items []DaemonSet `json:"items"` @@ -355,10 +359,10 @@ type DaemonSetList struct { // ThirdPartyResrouceDataList is a list of ThirdPartyResourceData. type ThirdPartyResourceDataList struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata - v1.ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of ThirdpartyResourceData. Items []ThirdPartyResourceData `json:"items"` @@ -366,7 +370,7 @@ type ThirdPartyResourceDataList struct { // Job represents the configuration of a single job. type Job struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard object's metadata. // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata v1.ObjectMeta `json:"metadata,omitempty"` @@ -382,10 +386,10 @@ type Job struct { // JobList is a collection of jobs. type JobList struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Standard list metadata // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata - v1.ListMeta `json:"metadata,omitempty"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of Job. Items []Job `json:"items"` @@ -398,45 +402,49 @@ type JobSpec struct { // run at any given time. The actual number of pods running in steady state will // be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), // i.e. when the work left to do is less than max parallelism. + // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md Parallelism *int `json:"parallelism,omitempty"` // Completions specifies the desired number of successfully finished pods the // job should be run with. Defaults to 1. + // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md Completions *int `json:"completions,omitempty"` // Selector is a label query over pods that should match the pod count. - Selector map[string]string `json:"selector"` + // More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors + Selector map[string]string `json:"selector,omitempty"` // Template is the object that describes the pod that will be created when // executing a job. - Template *v1.PodTemplateSpec `json:"template"` + // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md + Template v1.PodTemplateSpec `json:"template"` } // JobStatus represents the current state of a Job. type JobStatus struct { // Conditions represent the latest available observations of an object's current state. + // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md Conditions []JobCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` // StartTime represents time when the job was acknowledged by the Job Manager. // It is not guaranteed to be set in happens-before order across separate operations. // It is represented in RFC3339 form and is in UTC. - StartTime *util.Time `json:"startTime,omitempty"` + StartTime *unversioned.Time `json:"startTime,omitempty"` // CompletionTime represents time when the job was completed. It is not guaranteed to // be set in happens-before order across separate operations. // It is represented in RFC3339 form and is in UTC. - CompletionTime *util.Time `json:"completionTime,omitempty"` + CompletionTime *unversioned.Time `json:"completionTime,omitempty"` // Active is the number of actively running pods. Active int `json:"active,omitempty"` - // Successful is the number of pods which reached Phase Succeeded. - Successful int `json:"successful,omitempty"` + // Succeeded is the number of pods which reached Phase Succeeded. + Succeeded int `json:"succeeded,omitempty"` - // Unsuccessful is the number of pods failures, this applies only to jobs - // created with RestartPolicyNever, otherwise this value will always be 0. - Unsuccessful int `json:"unsuccessful,omitempty"` + // Failed is the number of pods which reached Phase Failed. + Failed int `json:"failed,omitempty"` } type JobConditionType string @@ -454,11 +462,198 @@ type JobCondition struct { // Status of the condition, one of True, False, Unknown. Status v1.ConditionStatus `json:"status"` // Last time the condition was checked. - LastProbeTime util.Time `json:"lastProbeTime,omitempty"` + LastProbeTime unversioned.Time `json:"lastProbeTime,omitempty"` // Last time the condition transit from one status to another. - LastTransitionTime util.Time `json:"lastTransitionTime,omitempty"` + LastTransitionTime unversioned.Time `json:"lastTransitionTime,omitempty"` // (brief) reason for the condition's last transition. Reason string `json:"reason,omitempty"` // Human readable message indicating details about last transition. Message string `json:"message,omitempty"` } + +// Ingress is a collection of rules that allow inbound connections to reach the +// endpoints defined by a backend. An Ingress can be configured to give services +// externally-reachable urls, load balance traffic, terminate SSL, offer name +// based virtual hosting etc. +type Ingress struct { + unversioned.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + v1.ObjectMeta `json:"metadata,omitempty"` + + // Spec is the desired state of the Ingress. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + Spec IngressSpec `json:"spec,omitempty"` + + // Status is the current state of the Ingress. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + Status IngressStatus `json:"status,omitempty"` +} + +// IngressList is a collection of Ingress. +type IngressList struct { + unversioned.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + unversioned.ListMeta `json:"metadata,omitempty"` + + // Items is the list of Ingress. + Items []Ingress `json:"items"` +} + +// IngressSpec describes the Ingress the user wishes to exist. +type IngressSpec struct { + // A default backend capable of servicing requests that don't match any + // rule. At least one of 'backend' or 'rules' must be specified. This field + // is optional to allow the loadbalancer controller or defaulting logic to + // specify a global default. + Backend *IngressBackend `json:"backend,omitempty"` + // A list of host rules used to configure the Ingress. If unspecified, or + // no rule matches, all traffic is sent to the default backend. + Rules []IngressRule `json:"rules,omitempty"` + // TODO: Add the ability to specify load-balancer IP through claims +} + +// IngressStatus describe the current state of the Ingress. +type IngressStatus struct { + // LoadBalancer contains the current status of the load-balancer. + LoadBalancer v1.LoadBalancerStatus `json:"loadBalancer,omitempty"` +} + +// IngressRule represents the rules mapping the paths under a specified host to +// the related backend services. Incoming requests are first evaluated for a host +// match, then routed to the backend associated with the matching IngressRuleValue. +type IngressRule struct { + // Host is the fully qualified domain name of a network host, as defined + // by RFC 3986. Note the following deviations from the "host" part of the + // URI as defined in the RFC: + // 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the + // IP in the Spec of the parent Ingress. + // 2. The `:` delimiter is not respected because ports are not allowed. + // Currently the port of an Ingress is implicitly :80 for http and + // :443 for https. + // Both these may change in the future. + // Incoming requests are matched against the host before the IngressRuleValue. + // If the host is unspecified, the Ingress routes all traffic based on the + // specified IngressRuleValue. + Host string `json:"host,omitempty"` + // IngressRuleValue represents a rule to route requests for this IngressRule. + // If unspecified, the rule defaults to a http catch-all. Whether that sends + // just traffic matching the host to the default backend or all traffic to the + // default backend, is left to the controller fulfilling the Ingress. Http is + // currently the only supported IngressRuleValue. + IngressRuleValue `json:",inline,omitempty"` +} + +// IngressRuleValue represents a rule to apply against incoming requests. If the +// rule is satisfied, the request is routed to the specified backend. Currently +// mixing different types of rules in a single Ingress is disallowed, so exactly +// one of the following must be set. +type IngressRuleValue struct { + //TODO: + // 1. Consider renaming this resource and the associated rules so they + // aren't tied to Ingress. They can be used to route intra-cluster traffic. + // 2. Consider adding fields for ingress-type specific global options + // usable by a loadbalancer, like http keep-alive. + + HTTP *HTTPIngressRuleValue `json:"http,omitempty"` +} + +// HTTPIngressRuleValue is a list of http selectors pointing to backends. +// In the example: http:///? -> backend where +// where parts of the url correspond to RFC 3986, this resource will be used +// to match against everything after the last '/' and before the first '?' +// or '#'. +type HTTPIngressRuleValue struct { + // A collection of paths that map requests to backends. + Paths []HTTPIngressPath `json:"paths"` + // TODO: Consider adding fields for ingress-type specific global + // options usable by a loadbalancer, like http keep-alive. +} + +// HTTPIngressPath associates a path regex with a backend. Incoming urls matching +// the path are forwarded to the backend. +type HTTPIngressPath struct { + // Path is a extended POSIX regex as defined by IEEE Std 1003.1, + // (i.e this follows the egrep/unix syntax, not the perl syntax) + // matched against the path of an incoming request. Currently it can + // contain characters disallowed from the conventional "path" + // part of a URL as defined by RFC 3986. Paths must begin with + // a '/'. If unspecified, the path defaults to a catch all sending + // traffic to the backend. + Path string `json:"path,omitempty"` + + // Backend defines the referenced service endpoint to which the traffic + // will be forwarded to. + Backend IngressBackend `json:"backend"` +} + +// IngressBackend describes all endpoints for a given service and port. +type IngressBackend struct { + // Specifies the name of the referenced service. + ServiceName string `json:"serviceName"` + + // Specifies the port of the referenced service. + ServicePort util.IntOrString `json:"servicePort"` +} + +type NodeResource string + +const ( + // Percentage of node's CPUs that is currently used. + CpuConsumption NodeResource = "CpuConsumption" + + // Percentage of node's CPUs that is currently requested for pods. + CpuRequest NodeResource = "CpuRequest" + + // Percentage od node's memory that is currently used. + MemConsumption NodeResource = "MemConsumption" + + // Percentage of node's CPUs that is currently requested for pods. + MemRequest NodeResource = "MemRequest" +) + +// NodeUtilization describes what percentage of a particular resource is used on a node. +type NodeUtilization struct { + Resource NodeResource `json:"resource"` + + // The accepted values are from 0 to 1. + Value float64 `json:"value"` +} + +// Configuration of the Cluster Autoscaler +type ClusterAutoscalerSpec struct { + // Minimum number of nodes that the cluster should have. + MinNodes int `json:"minNodes"` + + // Maximum number of nodes that the cluster should have. + MaxNodes int `json:"maxNodes"` + + // Target average utilization of the cluster nodes. New nodes will be added if one of the + // targets is exceeded. Cluster size will be decreased if the current utilization is too low + // for all targets. + TargetUtilization []NodeUtilization `json:"target"` +} + +type ClusterAutoscaler struct { + unversioned.TypeMeta `json:",inline"` + + // Standard object's metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // For now (experimental api) it is required that the name is set to "ClusterAutoscaler" and namespace is "default". + v1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired behavior of this daemon set. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + Spec ClusterAutoscalerSpec `json:"spec,omitempty"` +} + +// There will be just one (or none) ClusterAutoscaler. +type ClusterAutoscalerList struct { + unversioned.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + unversioned.ListMeta `json:"metadata,omitempty"` + + Items []ClusterAutoscaler `json:"items"` +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/types_swagger_doc_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types_swagger_doc_generated.go similarity index 61% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/types_swagger_doc_generated.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types_swagger_doc_generated.go index e43c3244ba3e..0e047782d7d8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/types_swagger_doc_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types_swagger_doc_generated.go @@ -14,14 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1 +package v1beta1 // This file contains a collection of methods that can be used from go-resful to // generate Swagger API documentation for its models. Please read this PR for more // information on the implementation: https://github.com/emicklei/go-restful/pull/215 // -// TODOs are ignored from the parser. (e.g. TODO(andronat):... || TODO:...) iff -// are on one line! For multiple line or blocks that you want to ignore use ---. +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // // Those methods can be generated by using hack/update-generated-swagger-docs.sh @@ -37,6 +37,35 @@ func (APIVersion) SwaggerDoc() map[string]string { return map_APIVersion } +var map_ClusterAutoscaler = map[string]string{ + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata For now (experimental api) it is required that the name is set to \"ClusterAutoscaler\" and namespace is \"default\".", + "spec": "Spec defines the desired behavior of this daemon set. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", +} + +func (ClusterAutoscaler) SwaggerDoc() map[string]string { + return map_ClusterAutoscaler +} + +var map_ClusterAutoscalerList = map[string]string{ + "": "There will be just one (or none) ClusterAutoscaler.", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", +} + +func (ClusterAutoscalerList) SwaggerDoc() map[string]string { + return map_ClusterAutoscalerList +} + +var map_ClusterAutoscalerSpec = map[string]string{ + "": "Configuration of the Cluster Autoscaler", + "minNodes": "Minimum number of nodes that the cluster should have.", + "maxNodes": "Maximum number of nodes that the cluster should have.", + "target": "Target average utilization of the cluster nodes. New nodes will be added if one of the targets is exceeded. Cluster size will be decreased if the current utilization is too low for all targets.", +} + +func (ClusterAutoscalerSpec) SwaggerDoc() map[string]string { + return map_ClusterAutoscalerSpec +} + var map_DaemonSet = map[string]string{ "": "DaemonSet represents the configuration of a daemon set.", "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", @@ -70,9 +99,9 @@ func (DaemonSetSpec) SwaggerDoc() map[string]string { var map_DaemonSetStatus = map[string]string{ "": "DaemonSetStatus represents the current status of a daemon set.", - "currentNumberScheduled": "CurrentNumberScheduled is the number of nodes that are running exactly 1 daemon pod and are supposed to run the daemon pod.", - "numberMisscheduled": "NumberMisscheduled is the number of nodes that are running the daemon pod, but are not supposed to run the daemon pod.", - "desiredNumberScheduled": "DesiredNumberScheduled is the total number of nodes that should be running the daemon pod (including nodes correctly running the daemon pod).", + "currentNumberScheduled": "CurrentNumberScheduled is the number of nodes that are running at least 1 daemon pod and are supposed to run the daemon pod. More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md", + "numberMisscheduled": "NumberMisscheduled is the number of nodes that are running the daemon pod, but are not supposed to run the daemon pod. More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md", + "desiredNumberScheduled": "DesiredNumberScheduled is the total number of nodes that should be running the daemon pod (including nodes correctly running the daemon pod). More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md", } func (DaemonSetStatus) SwaggerDoc() map[string]string { @@ -103,7 +132,7 @@ func (DeploymentList) SwaggerDoc() map[string]string { var map_DeploymentSpec = map[string]string{ "": "DeploymentSpec is the specification of the desired behavior of the Deployment.", "replicas": "Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.", - "selector": "Label selector for pods. Existing ReplicationControllers whose pods are selected by this will be scaled down.", + "selector": "Label selector for pods. Existing ReplicationControllers whose pods are selected by this will be the ones affected by this deployment.", "template": "Template describes the pods that will be created.", "strategy": "The deployment strategy to use to replace existing pods with new ones.", "uniqueLabelKey": "Key of the selector that is added to existing RCs (and label key that is added to its pods) to prevent the existing RCs to select new pods (and old pods being selected by new RC). Users can set this to an empty string to indicate that the system should not add any selector and label. If unspecified, system uses \"deployment.kubernetes.io/podTemplateHash\". Value of this key is hash of DeploymentSpec.PodTemplateSpec. No label is added if this is set to empty string.", @@ -115,8 +144,8 @@ func (DeploymentSpec) SwaggerDoc() map[string]string { var map_DeploymentStatus = map[string]string{ "": "DeploymentStatus is the most recently observed status of the Deployment.", - "replicas": "Total number of ready pods targeted by this deployment (this includes both the old and new pods).", - "updatedReplicas": "Total number of new ready pods with the desired template spec.", + "replicas": "Total number of non-terminated pods targeted by this deployment (their labels match the selector).", + "updatedReplicas": "Total number of non-terminated pods targeted by this deployment that have the desired template spec.", } func (DeploymentStatus) SwaggerDoc() map[string]string { @@ -126,13 +155,32 @@ func (DeploymentStatus) SwaggerDoc() map[string]string { var map_DeploymentStrategy = map[string]string{ "": "DeploymentStrategy describes how to replace existing pods with new ones.", "type": "Type of deployment. Can be \"Recreate\" or \"RollingUpdate\". Default is RollingUpdate.", - "rollingUpdate": "Rolling update config params. Present only if DeploymentType = RollingUpdate.", + "rollingUpdate": "Rolling update config params. Present only if DeploymentStrategyType = RollingUpdate.", } func (DeploymentStrategy) SwaggerDoc() map[string]string { return map_DeploymentStrategy } +var map_HTTPIngressPath = map[string]string{ + "": "HTTPIngressPath associates a path regex with a backend. Incoming urls matching the path are forwarded to the backend.", + "path": "Path is a extended POSIX regex as defined by IEEE Std 1003.1, (i.e this follows the egrep/unix syntax, not the perl syntax) matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. If unspecified, the path defaults to a catch all sending traffic to the backend.", + "backend": "Backend defines the referenced service endpoint to which the traffic will be forwarded to.", +} + +func (HTTPIngressPath) SwaggerDoc() map[string]string { + return map_HTTPIngressPath +} + +var map_HTTPIngressRuleValue = map[string]string{ + "": "HTTPIngressRuleValue is a list of http selectors pointing to backends. In the example: http:///? -> backend where where parts of the url correspond to RFC 3986, this resource will be used to match against everything after the last '/' and before the first '?' or '#'.", + "paths": "A collection of paths that map requests to backends.", +} + +func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { + return map_HTTPIngressRuleValue +} + var map_HorizontalPodAutoscaler = map[string]string{ "": "HorizontalPodAutoscaler represents the configuration of a horizontal pod autoscaler.", "metadata": "Standard object metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", @@ -155,11 +203,11 @@ func (HorizontalPodAutoscalerList) SwaggerDoc() map[string]string { } var map_HorizontalPodAutoscalerSpec = map[string]string{ - "": "HorizontalPodAutoscalerSpec is the specification of a horizontal pod autoscaler.", - "scaleRef": "ScaleRef is a reference to Scale subresource. HorizontalPodAutoscaler will learn the current resource consumption from its status, and will set the desired number of pods by modyfying its spec.", - "minCount": "MinCount is the lower limit for the number of pods that can be set by the autoscaler.", - "maxCount": "MaxCount is the upper limit for the number of pods that can be set by the autoscaler. It cannot be smaller than MinCount.", - "target": "Target is the target average consumption of the given resource that the autoscaler will try to maintain by adjusting the desired number of pods. Currently two types of resources are supported: \"cpu\" and \"memory\".", + "": "HorizontalPodAutoscalerSpec is the specification of a horizontal pod autoscaler.", + "scaleRef": "ScaleRef is a reference to Scale subresource. HorizontalPodAutoscaler will learn the current resource consumption from its status, and will set the desired number of pods by modyfying its spec.", + "minReplicas": "MinReplicas is the lower limit for the number of pods that can be set by the autoscaler.", + "maxReplicas": "MaxReplicas is the upper limit for the number of pods that can be set by the autoscaler. It cannot be smaller than MinReplicas.", + "target": "Target is the target average consumption of the given resource that the autoscaler will try to maintain by adjusting the desired number of pods. Currently two types of resources are supported: \"cpu\" and \"memory\".", } func (HorizontalPodAutoscalerSpec) SwaggerDoc() map[string]string { @@ -178,6 +226,73 @@ func (HorizontalPodAutoscalerStatus) SwaggerDoc() map[string]string { return map_HorizontalPodAutoscalerStatus } +var map_Ingress = map[string]string{ + "": "Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. An Ingress can be configured to give services externally-reachable urls, load balance traffic, terminate SSL, offer name based virtual hosting etc.", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "spec": "Spec is the desired state of the Ingress. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "status": "Status is the current state of the Ingress. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", +} + +func (Ingress) SwaggerDoc() map[string]string { + return map_Ingress +} + +var map_IngressBackend = map[string]string{ + "": "IngressBackend describes all endpoints for a given service and port.", + "serviceName": "Specifies the name of the referenced service.", + "servicePort": "Specifies the port of the referenced service.", +} + +func (IngressBackend) SwaggerDoc() map[string]string { + return map_IngressBackend +} + +var map_IngressList = map[string]string{ + "": "IngressList is a collection of Ingress.", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "items": "Items is the list of Ingress.", +} + +func (IngressList) SwaggerDoc() map[string]string { + return map_IngressList +} + +var map_IngressRule = map[string]string{ + "": "IngressRule represents the rules mapping the paths under a specified host to the related backend services. Incoming requests are first evaluated for a host match, then routed to the backend associated with the matching IngressRuleValue.", + "host": "Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in the RFC: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the\n\t IP in the Spec of the parent Ingress.\n2. The `:` delimiter is not respected because ports are not allowed.\n\t Currently the port of an Ingress is implicitly :80 for http and\n\t :443 for https.\nBoth these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.", +} + +func (IngressRule) SwaggerDoc() map[string]string { + return map_IngressRule +} + +var map_IngressRuleValue = map[string]string{ + "": "IngressRuleValue represents a rule to apply against incoming requests. If the rule is satisfied, the request is routed to the specified backend. Currently mixing different types of rules in a single Ingress is disallowed, so exactly one of the following must be set.", +} + +func (IngressRuleValue) SwaggerDoc() map[string]string { + return map_IngressRuleValue +} + +var map_IngressSpec = map[string]string{ + "": "IngressSpec describes the Ingress the user wishes to exist.", + "backend": "A default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default.", + "rules": "A list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.", +} + +func (IngressSpec) SwaggerDoc() map[string]string { + return map_IngressSpec +} + +var map_IngressStatus = map[string]string{ + "": "IngressStatus describe the current state of the Ingress.", + "loadBalancer": "LoadBalancer contains the current status of the load-balancer.", +} + +func (IngressStatus) SwaggerDoc() map[string]string { + return map_IngressStatus +} + var map_Job = map[string]string{ "": "Job represents the configuration of a single job.", "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", @@ -215,10 +330,10 @@ func (JobList) SwaggerDoc() map[string]string { var map_JobSpec = map[string]string{ "": "JobSpec describes how the job execution will look like.", - "parallelism": "Parallelism specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism.", - "completions": "Completions specifies the desired number of successfully finished pods the job should be run with. Defaults to 1.", - "selector": "Selector is a label query over pods that should match the pod count.", - "template": "Template is the object that describes the pod that will be created when executing a job.", + "parallelism": "Parallelism specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", + "completions": "Completions specifies the desired number of successfully finished pods the job should be run with. Defaults to 1. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", + "selector": "Selector is a label query over pods that should match the pod count. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors", + "template": "Template is the object that describes the pod that will be created when executing a job. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", } func (JobSpec) SwaggerDoc() map[string]string { @@ -227,18 +342,27 @@ func (JobSpec) SwaggerDoc() map[string]string { var map_JobStatus = map[string]string{ "": "JobStatus represents the current state of a Job.", - "conditions": "Conditions represent the latest available observations of an object's current state.", + "conditions": "Conditions represent the latest available observations of an object's current state. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", "startTime": "StartTime represents time when the job was acknowledged by the Job Manager. It is not guaranteed to be set in happens-before order across separate operations. It is represented in RFC3339 form and is in UTC.", "completionTime": "CompletionTime represents time when the job was completed. It is not guaranteed to be set in happens-before order across separate operations. It is represented in RFC3339 form and is in UTC.", "active": "Active is the number of actively running pods.", - "successful": "Successful is the number of pods which reached Phase Succeeded.", - "unsuccessful": "Unsuccessful is the number of pods failures, this applies only to jobs created with RestartPolicyNever, otherwise this value will always be 0.", + "succeeded": "Succeeded is the number of pods which reached Phase Succeeded.", + "failed": "Failed is the number of pods which reached Phase Failed.", } func (JobStatus) SwaggerDoc() map[string]string { return map_JobStatus } +var map_NodeUtilization = map[string]string{ + "": "NodeUtilization describes what percentage of a particular resource is used on a node.", + "value": "The accepted values are from 0 to 1.", +} + +func (NodeUtilization) SwaggerDoc() map[string]string { + return map_NodeUtilization +} + var map_ReplicationControllerDummy = map[string]string{ "": "Dummy definition", } @@ -259,8 +383,8 @@ func (ResourceConsumption) SwaggerDoc() map[string]string { var map_RollingUpdateDeployment = map[string]string{ "": "Spec to control the desired behavior of rolling update.", - "maxUnavailable": "The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of total pods at the start of update (ex: 10%). Absolute number is calculated from percentage by rounding up. This can not be 0 if MaxSurge is 0. By default, a fixed value of 1 is used. Example: when this is set to 30%, the old RC can be scaled down by 30% immediately when the rolling update starts. Once new pods are ready, old RC can be scaled down further, followed by scaling up the new RC, ensuring that at least 70% of original number of pods are available at all times during the update.", - "maxSurge": "The maximum number of pods that can be scheduled above the original number of pods. Value can be an absolute number (ex: 5) or a percentage of total pods at the start of the update (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. By default, a value of 1 is used. Example: when this is set to 30%, the new RC can be scaled up by 30% immediately when the rolling update starts. Once old pods have been killed, new RC can be scaled up further, ensuring that total number of pods running at any time during the update is atmost 130% of original pods.", + "maxUnavailable": "The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding up. This can not be 0 if MaxSurge is 0. By default, a fixed value of 1 is used. Example: when this is set to 30%, the old RC can be scaled down to 70% of desired pods immediately when the rolling update starts. Once new pods are ready, old RC can be scaled down further, followed by scaling up the new RC, ensuring that the total number of pods available at all times during the update is at least 70% of desired pods.", + "maxSurge": "The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. By default, a value of 1 is used. Example: when this is set to 30%, the new RC can be scaled up immediately when the rolling update starts, such that the total number of old and new pods do not exceed 130% of desired pods. Once old pods have been killed, new RC can be scaled up further, ensuring that total number of pods running at any time during the update is atmost 130% of desired pods.", "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/validation/validation.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/validation/validation.go new file mode 100644 index 000000000000..33a38d247929 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/validation/validation.go @@ -0,0 +1,562 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 validation + +import ( + "fmt" + "net" + "regexp" + "strconv" + "strings" + + "k8s.io/kubernetes/pkg/api" + apivalidation "k8s.io/kubernetes/pkg/api/validation" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/util" + errs "k8s.io/kubernetes/pkg/util/fielderrors" + "k8s.io/kubernetes/pkg/util/sets" + "k8s.io/kubernetes/pkg/util/validation" + utilvalidation "k8s.io/kubernetes/pkg/util/validation" +) + +const isNegativeErrorMsg string = `must be non-negative` + +// TODO: Expose from apivalidation instead of duplicating. +func intervalErrorMsg(lo, hi int) string { + return fmt.Sprintf(`must be greater than %d and less than %d`, lo, hi) +} + +var portRangeErrorMsg string = intervalErrorMsg(0, 65536) +var portNameErrorMsg string = fmt.Sprintf(`must be an IANA_SVC_NAME (at most 15 characters, matching regex %s, it must contain at least one letter [a-z], and hyphens cannot be adjacent to other hyphens): e.g. "http"`, validation.IdentifierNoHyphensBeginEndFmt) + +// ValidateHorizontalPodAutoscaler can be used to check whether the given autoscaler name is valid. +// Prefix indicates this name will be used as part of generation, in which case trailing dashes are allowed. +func ValidateHorizontalPodAutoscalerName(name string, prefix bool) (bool, string) { + // TODO: finally move it to pkg/api/validation and use nameIsDNSSubdomain function + return apivalidation.ValidateReplicationControllerName(name, prefix) +} + +func validateResourceConsumption(consumption *extensions.ResourceConsumption, fieldName string) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + resource := consumption.Resource.String() + if resource != string(api.ResourceMemory) && resource != string(api.ResourceCPU) { + allErrs = append(allErrs, errs.NewFieldInvalid(fieldName+".resource", resource, "resource not supported by autoscaler")) + } + quantity := consumption.Quantity.Value() + if quantity < 0 { + allErrs = append(allErrs, errs.NewFieldInvalid(fieldName+".quantity", quantity, "must be non-negative")) + } + return allErrs +} + +func validateHorizontalPodAutoscalerSpec(autoscaler extensions.HorizontalPodAutoscalerSpec) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if autoscaler.MinReplicas < 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("minReplicas", autoscaler.MinReplicas, isNegativeErrorMsg)) + } + if autoscaler.MaxReplicas < autoscaler.MinReplicas { + allErrs = append(allErrs, errs.NewFieldInvalid("maxReplicas", autoscaler.MaxReplicas, `must be bigger or equal to minReplicas`)) + } + if autoscaler.ScaleRef == nil { + allErrs = append(allErrs, errs.NewFieldRequired("scaleRef")) + } + resource := autoscaler.Target.Resource.String() + if resource != string(api.ResourceMemory) && resource != string(api.ResourceCPU) { + allErrs = append(allErrs, errs.NewFieldInvalid("target.resource", resource, "resource not supported by autoscaler")) + } + quantity := autoscaler.Target.Quantity.Value() + if quantity < 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("target.quantity", quantity, isNegativeErrorMsg)) + } + return allErrs +} + +func ValidateHorizontalPodAutoscaler(autoscaler *extensions.HorizontalPodAutoscaler) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&autoscaler.ObjectMeta, true, ValidateHorizontalPodAutoscalerName).Prefix("metadata")...) + allErrs = append(allErrs, validateHorizontalPodAutoscalerSpec(autoscaler.Spec)...) + return allErrs +} + +func ValidateHorizontalPodAutoscalerUpdate(newAutoscler, oldAutoscaler *extensions.HorizontalPodAutoscaler) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&newAutoscler.ObjectMeta, &oldAutoscaler.ObjectMeta).Prefix("metadata")...) + allErrs = append(allErrs, validateHorizontalPodAutoscalerSpec(newAutoscler.Spec)...) + return allErrs +} + +func ValidateHorizontalPodAutoscalerStatusUpdate(controller, oldController *extensions.HorizontalPodAutoscaler) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&controller.ObjectMeta, &oldController.ObjectMeta).Prefix("metadata")...) + + status := controller.Status + allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(status.CurrentReplicas), "currentReplicas")...) + allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(status.DesiredReplicas), "desiredReplicas")...) + if status.CurrentConsumption != nil { + allErrs = append(allErrs, validateResourceConsumption(status.CurrentConsumption, "currentConsumption")...) + } + return allErrs +} + +func ValidateThirdPartyResourceUpdate(old, update *extensions.ThirdPartyResource) errs.ValidationErrorList { + return ValidateThirdPartyResource(update) +} + +func ValidateThirdPartyResource(obj *extensions.ThirdPartyResource) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if len(obj.Name) == 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("name", obj.Name, "name must be non-empty")) + } + versions := sets.String{} + for ix := range obj.Versions { + version := &obj.Versions[ix] + if len(version.Name) == 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("name", version, "name can not be empty")) + } + if versions.Has(version.Name) { + allErrs = append(allErrs, errs.NewFieldDuplicate("version", version)) + } + versions.Insert(version.Name) + } + return allErrs +} + +// ValidateDaemonSet tests if required fields in the DaemonSet are set. +func ValidateDaemonSet(controller *extensions.DaemonSet) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&controller.ObjectMeta, true, apivalidation.ValidateReplicationControllerName).Prefix("metadata")...) + allErrs = append(allErrs, ValidateDaemonSetSpec(&controller.Spec).Prefix("spec")...) + return allErrs +} + +// ValidateDaemonSetUpdate tests if required fields in the DaemonSet are set. +func ValidateDaemonSetUpdate(oldController, controller *extensions.DaemonSet) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&controller.ObjectMeta, &oldController.ObjectMeta).Prefix("metadata")...) + allErrs = append(allErrs, ValidateDaemonSetSpec(&controller.Spec).Prefix("spec")...) + allErrs = append(allErrs, ValidateDaemonSetTemplateUpdate(oldController.Spec.Template, controller.Spec.Template).Prefix("spec.template")...) + return allErrs +} + +// validateDaemonSetStatus validates a DaemonSetStatus +func validateDaemonSetStatus(status *extensions.DaemonSetStatus) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(status.CurrentNumberScheduled), "currentNumberScheduled")...) + allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(status.NumberMisscheduled), "numberMisscheduled")...) + allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(status.DesiredNumberScheduled), "desiredNumberScheduled")...) + return allErrs +} + +// ValidateDaemonSetStatus validates tests if required fields in the DaemonSet Status section +func ValidateDaemonSetStatusUpdate(controller, oldController *extensions.DaemonSet) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&controller.ObjectMeta, &oldController.ObjectMeta).Prefix("metadata")...) + allErrs = append(allErrs, validateDaemonSetStatus(&controller.Status)...) + return allErrs +} + +// ValidateDaemonSetTemplateUpdate tests that certain fields in the daemon set's pod template are not updated. +func ValidateDaemonSetTemplateUpdate(oldPodTemplate, podTemplate *api.PodTemplateSpec) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + podSpec := podTemplate.Spec + // podTemplate.Spec is not a pointer, so we can modify NodeSelector and NodeName directly. + podSpec.NodeSelector = oldPodTemplate.Spec.NodeSelector + podSpec.NodeName = oldPodTemplate.Spec.NodeName + // In particular, we do not allow updates to container images at this point. + if !api.Semantic.DeepEqual(oldPodTemplate.Spec, podSpec) { + // TODO: Pinpoint the specific field that causes the invalid error after we have strategic merge diff + allErrs = append(allErrs, errs.NewFieldInvalid("spec", "content of spec is not printed out, please refer to the \"details\"", "may not update fields other than spec.nodeSelector")) + } + return allErrs +} + +// ValidateDaemonSetSpec tests if required fields in the DaemonSetSpec are set. +func ValidateDaemonSetSpec(spec *extensions.DaemonSetSpec) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + + selector := labels.Set(spec.Selector).AsSelector() + if selector.Empty() { + allErrs = append(allErrs, errs.NewFieldRequired("selector")) + } + + if spec.Template == nil { + allErrs = append(allErrs, errs.NewFieldRequired("template")) + } else { + labels := labels.Set(spec.Template.Labels) + if !selector.Matches(labels) { + allErrs = append(allErrs, errs.NewFieldInvalid("template.metadata.labels", spec.Template.Labels, "selector does not match template")) + } + allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(spec.Template).Prefix("template")...) + // Daemons typically run on more than one node, so mark Read-Write persistent disks as invalid. + allErrs = append(allErrs, apivalidation.ValidateReadOnlyPersistentDisks(spec.Template.Spec.Volumes).Prefix("template.spec.volumes")...) + // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). + if spec.Template.Spec.RestartPolicy != api.RestartPolicyAlways { + allErrs = append(allErrs, errs.NewFieldValueNotSupported("template.spec.restartPolicy", spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)})) + } + } + return allErrs +} + +// ValidateDaemonSetName can be used to check whether the given daemon set name is valid. +// Prefix indicates this name will be used as part of generation, in which case +// trailing dashes are allowed. +func ValidateDaemonSetName(name string, prefix bool) (bool, string) { + return apivalidation.NameIsDNSSubdomain(name, prefix) +} + +// Validates that the given name can be used as a deployment name. +func ValidateDeploymentName(name string, prefix bool) (bool, string) { + return apivalidation.NameIsDNSSubdomain(name, prefix) +} + +func ValidatePositiveIntOrPercent(intOrPercent util.IntOrString, fieldName string) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if intOrPercent.Kind == util.IntstrString { + if !validation.IsValidPercent(intOrPercent.StrVal) { + allErrs = append(allErrs, errs.NewFieldInvalid(fieldName, intOrPercent, "value should be int(5) or percentage(5%)")) + } + + } else if intOrPercent.Kind == util.IntstrInt { + allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(intOrPercent.IntVal), fieldName)...) + } + return allErrs +} + +func getPercentValue(intOrStringValue util.IntOrString) (int, bool) { + if intOrStringValue.Kind != util.IntstrString || !validation.IsValidPercent(intOrStringValue.StrVal) { + return 0, false + } + value, _ := strconv.Atoi(intOrStringValue.StrVal[:len(intOrStringValue.StrVal)-1]) + return value, true +} + +func getIntOrPercentValue(intOrStringValue util.IntOrString) int { + value, isPercent := getPercentValue(intOrStringValue) + if isPercent { + return value + } + return intOrStringValue.IntVal +} + +func IsNotMoreThan100Percent(intOrStringValue util.IntOrString, fieldName string) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + value, isPercent := getPercentValue(intOrStringValue) + if !isPercent || value <= 100 { + return nil + } + allErrs = append(allErrs, errs.NewFieldInvalid(fieldName, intOrStringValue, "should not be more than 100%")) + return allErrs +} + +func ValidateRollingUpdateDeployment(rollingUpdate *extensions.RollingUpdateDeployment, fieldName string) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxUnavailable, fieldName+"maxUnavailable")...) + allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxSurge, fieldName+".maxSurge")...) + if getIntOrPercentValue(rollingUpdate.MaxUnavailable) == 0 && getIntOrPercentValue(rollingUpdate.MaxSurge) == 0 { + // Both MaxSurge and MaxUnavailable cannot be zero. + allErrs = append(allErrs, errs.NewFieldInvalid(fieldName+".maxUnavailable", rollingUpdate.MaxUnavailable, "cannot be 0 when maxSurge is 0 as well")) + } + // Validate that MaxUnavailable is not more than 100%. + allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fieldName+".maxUnavailable")...) + allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(rollingUpdate.MinReadySeconds), fieldName+".minReadySeconds")...) + return allErrs +} + +func ValidateDeploymentStrategy(strategy *extensions.DeploymentStrategy, fieldName string) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if strategy.RollingUpdate == nil { + return allErrs + } + switch strategy.Type { + case extensions.RecreateDeploymentStrategyType: + allErrs = append(allErrs, errs.NewFieldForbidden("rollingUpdate", "rollingUpdate should be nil when strategy type is "+extensions.RecreateDeploymentStrategyType)) + case extensions.RollingUpdateDeploymentStrategyType: + allErrs = append(allErrs, ValidateRollingUpdateDeployment(strategy.RollingUpdate, "rollingUpdate")...) + } + return allErrs +} + +// Validates given deployment spec. +func ValidateDeploymentSpec(spec *extensions.DeploymentSpec) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateNonEmptySelector(spec.Selector, "selector")...) + allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(spec.Replicas), "replicas")...) + allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpecForRC(spec.Template, spec.Selector, spec.Replicas, "template")...) + allErrs = append(allErrs, ValidateDeploymentStrategy(&spec.Strategy, "strategy")...) + allErrs = append(allErrs, apivalidation.ValidateLabelName(spec.UniqueLabelKey, "uniqueLabel")...) + return allErrs +} + +func ValidateDeploymentUpdate(old, update *extensions.Deployment) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta).Prefix("metadata")...) + allErrs = append(allErrs, ValidateDeploymentSpec(&update.Spec).Prefix("spec")...) + return allErrs +} + +func ValidateDeployment(obj *extensions.Deployment) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&obj.ObjectMeta, true, ValidateDeploymentName).Prefix("metadata")...) + allErrs = append(allErrs, ValidateDeploymentSpec(&obj.Spec).Prefix("spec")...) + return allErrs +} + +func ValidateThirdPartyResourceDataUpdate(old, update *extensions.ThirdPartyResourceData) errs.ValidationErrorList { + return ValidateThirdPartyResourceData(update) +} + +func ValidateThirdPartyResourceData(obj *extensions.ThirdPartyResourceData) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if len(obj.Name) == 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("name", obj.Name, "name must be non-empty")) + } + return allErrs +} + +func ValidateJob(job *extensions.Job) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + // Jobs and rcs have the same name validation + allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&job.ObjectMeta, true, apivalidation.ValidateReplicationControllerName).Prefix("metadata")...) + allErrs = append(allErrs, ValidateJobSpec(&job.Spec).Prefix("spec")...) + return allErrs +} + +func ValidateJobSpec(spec *extensions.JobSpec) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + + if spec.Parallelism != nil && *spec.Parallelism < 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("parallelism", spec.Parallelism, isNegativeErrorMsg)) + } + if spec.Completions != nil && *spec.Completions < 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("completions", spec.Completions, isNegativeErrorMsg)) + } + + selector := labels.Set(spec.Selector).AsSelector() + if selector.Empty() { + allErrs = append(allErrs, errs.NewFieldRequired("selector")) + } + + labels := labels.Set(spec.Template.Labels) + if !selector.Matches(labels) { + allErrs = append(allErrs, errs.NewFieldInvalid("template.labels", spec.Template.Labels, "selector does not match template")) + } + allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(&spec.Template).Prefix("template")...) + if spec.Template.Spec.RestartPolicy != api.RestartPolicyOnFailure && + spec.Template.Spec.RestartPolicy != api.RestartPolicyNever { + allErrs = append(allErrs, errs.NewFieldValueNotSupported("template.spec.restartPolicy", + spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyOnFailure), string(api.RestartPolicyNever)})) + } + return allErrs +} + +func ValidateJobStatus(status *extensions.JobStatus) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(status.Active), "active")...) + allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(status.Succeeded), "succeeded")...) + allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(status.Failed), "failed")...) + return allErrs +} + +func ValidateJobUpdate(oldJob, job *extensions.Job) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&oldJob.ObjectMeta, &job.ObjectMeta).Prefix("metadata")...) + allErrs = append(allErrs, ValidateJobSpecUpdate(oldJob.Spec, job.Spec).Prefix("spec")...) + return allErrs +} + +func ValidateJobUpdateStatus(oldJob, job *extensions.Job) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&oldJob.ObjectMeta, &job.ObjectMeta).Prefix("metadata")...) + allErrs = append(allErrs, ValidateJobStatusUpdate(oldJob.Status, job.Status).Prefix("status")...) + return allErrs +} + +func ValidateJobSpecUpdate(oldSpec, spec extensions.JobSpec) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, ValidateJobSpec(&spec)...) + if !api.Semantic.DeepEqual(oldSpec.Completions, spec.Completions) { + allErrs = append(allErrs, errs.NewFieldInvalid("completions", spec.Completions, "field is immutable")) + } + if !api.Semantic.DeepEqual(oldSpec.Selector, spec.Selector) { + allErrs = append(allErrs, errs.NewFieldInvalid("selector", spec.Selector, "field is immutable")) + } + if !api.Semantic.DeepEqual(oldSpec.Template, spec.Template) { + allErrs = append(allErrs, errs.NewFieldInvalid("template", "[omitted]", "field is immutable")) + } + return allErrs +} + +func ValidateJobStatusUpdate(oldStatus, status extensions.JobStatus) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, ValidateJobStatus(&status)...) + return allErrs +} + +// ValidateIngress tests if required fields in the Ingress are set. +func ValidateIngress(ingress *extensions.Ingress) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&ingress.ObjectMeta, true, ValidateIngressName).Prefix("metadata")...) + allErrs = append(allErrs, ValidateIngressSpec(&ingress.Spec).Prefix("spec")...) + return allErrs +} + +// ValidateIngressName validates that the given name can be used as an Ingress name. +func ValidateIngressName(name string, prefix bool) (bool, string) { + return apivalidation.NameIsDNSSubdomain(name, prefix) +} + +// ValidateIngressSpec tests if required fields in the IngressSpec are set. +func ValidateIngressSpec(spec *extensions.IngressSpec) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + // TODO: Is a default backend mandatory? + if spec.Backend != nil { + allErrs = append(allErrs, validateIngressBackend(spec.Backend).Prefix("backend")...) + } else if len(spec.Rules) == 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("rules", spec.Rules, "Either a default backend or a set of host rules are required for ingress.")) + } + if len(spec.Rules) > 0 { + allErrs = append(allErrs, validateIngressRules(spec.Rules).Prefix("rules")...) + } + return allErrs +} + +// ValidateIngressUpdate tests if required fields in the Ingress are set. +func ValidateIngressUpdate(oldIngress, ingress *extensions.Ingress) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&ingress.ObjectMeta, &oldIngress.ObjectMeta).Prefix("metadata")...) + allErrs = append(allErrs, ValidateIngressSpec(&ingress.Spec).Prefix("spec")...) + return allErrs +} + +func validateIngressRules(IngressRules []extensions.IngressRule) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if len(IngressRules) == 0 { + return append(allErrs, errs.NewFieldRequired("IngressRules")) + } + for _, ih := range IngressRules { + if len(ih.Host) > 0 { + // TODO: Ports and ips are allowed in the host part of a url + // according to RFC 3986, consider allowing them. + if valid, errMsg := apivalidation.NameIsDNSSubdomain(ih.Host, false); !valid { + allErrs = append(allErrs, errs.NewFieldInvalid("host", ih.Host, errMsg)) + } + if isIP := (net.ParseIP(ih.Host) != nil); isIP { + allErrs = append(allErrs, errs.NewFieldInvalid("host", ih.Host, "Host must be a DNS name, not ip address")) + } + } + allErrs = append(allErrs, validateIngressRuleValue(&ih.IngressRuleValue).Prefix("ingressRule")...) + } + return allErrs +} + +func validateIngressRuleValue(ingressRule *extensions.IngressRuleValue) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if ingressRule.HTTP != nil { + allErrs = append(allErrs, validateHTTPIngressRuleValue(ingressRule.HTTP).Prefix("http")...) + } + return allErrs +} + +func validateHTTPIngressRuleValue(httpIngressRuleValue *extensions.HTTPIngressRuleValue) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if len(httpIngressRuleValue.Paths) == 0 { + allErrs = append(allErrs, errs.NewFieldRequired("paths")) + } + for _, rule := range httpIngressRuleValue.Paths { + if len(rule.Path) > 0 { + if !strings.HasPrefix(rule.Path, "/") { + allErrs = append(allErrs, errs.NewFieldInvalid("path", rule.Path, "path must begin with /")) + } + // TODO: More draconian path regex validation. + // Path must be a valid regex. This is the basic requirement. + // In addition to this any characters not allowed in a path per + // RFC 3986 section-3.3 cannot appear as a literal in the regex. + // Consider the example: http://host/valid?#bar, everything after + // the last '/' is a valid regex that matches valid#bar, which + // isn't a valid path, because the path terminates at the first ? + // or #. A more sophisticated form of validation would detect that + // the user is confusing url regexes with path regexes. + _, err := regexp.CompilePOSIX(rule.Path) + if err != nil { + allErrs = append(allErrs, errs.NewFieldInvalid("path", rule.Path, "httpIngressRuleValue.path must be a valid regex.")) + } + } + allErrs = append(allErrs, validateIngressBackend(&rule.Backend).Prefix("backend")...) + } + return allErrs +} + +// validateIngressBackend tests if a given backend is valid. +func validateIngressBackend(backend *extensions.IngressBackend) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + + // All backends must reference a single local service by name, and a single service port by name or number. + if len(backend.ServiceName) == 0 { + return append(allErrs, errs.NewFieldRequired("serviceName")) + } else if ok, errMsg := apivalidation.ValidateServiceName(backend.ServiceName, false); !ok { + allErrs = append(allErrs, errs.NewFieldInvalid("serviceName", backend.ServiceName, errMsg)) + } + if backend.ServicePort.Kind == util.IntstrString { + if !utilvalidation.IsDNS1123Label(backend.ServicePort.StrVal) { + allErrs = append(allErrs, errs.NewFieldInvalid("servicePort", backend.ServicePort.StrVal, apivalidation.DNS1123LabelErrorMsg)) + } + if !utilvalidation.IsValidPortName(backend.ServicePort.StrVal) { + allErrs = append(allErrs, errs.NewFieldInvalid("servicePort", backend.ServicePort.StrVal, portNameErrorMsg)) + } + } else if !utilvalidation.IsValidPortNum(backend.ServicePort.IntVal) { + allErrs = append(allErrs, errs.NewFieldInvalid("servicePort", backend.ServicePort, portRangeErrorMsg)) + } + return allErrs +} + +func validateClusterAutoscalerSpec(spec extensions.ClusterAutoscalerSpec) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if spec.MinNodes < 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("minNodes", spec.MinNodes, `must be non-negative`)) + } + if spec.MaxNodes < spec.MinNodes { + allErrs = append(allErrs, errs.NewFieldInvalid("maxNodes", spec.MaxNodes, `must be bigger or equal to minNodes`)) + } + if len(spec.TargetUtilization) == 0 { + allErrs = append(allErrs, errs.NewFieldRequired("targetUtilization")) + } + for _, target := range spec.TargetUtilization { + if len(target.Resource) == 0 { + allErrs = append(allErrs, errs.NewFieldRequired("targetUtilization.resource")) + } + if target.Value <= 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("targetUtilization.value", target.Value, "must be greater than 0")) + } + if target.Value > 1 { + allErrs = append(allErrs, errs.NewFieldInvalid("targetUtilization.value", target.Value, "must be less or equal 1")) + } + } + return allErrs +} + +func ValidateClusterAutoscaler(autoscaler *extensions.ClusterAutoscaler) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if autoscaler.Name != "ClusterAutoscaler" { + allErrs = append(allErrs, errs.NewFieldInvalid("name", autoscaler.Name, `name must be ClusterAutoscaler`)) + } + if autoscaler.Namespace != api.NamespaceDefault { + allErrs = append(allErrs, errs.NewFieldInvalid("namespace", autoscaler.Namespace, `namespace must be default`)) + } + allErrs = append(allErrs, validateClusterAutoscalerSpec(autoscaler.Spec)...) + return allErrs +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/validation/validation_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/validation/validation_test.go similarity index 59% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/validation/validation_test.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/validation/validation_test.go index 6cfd1e8d72e2..1f9b7f31c9f7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/validation/validation_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/validation/validation_test.go @@ -17,30 +17,31 @@ limitations under the License. package validation import ( + "fmt" "strings" "testing" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/util" errors "k8s.io/kubernetes/pkg/util/fielderrors" ) func TestValidateHorizontalPodAutoscaler(t *testing.T) { - successCases := []experimental.HorizontalPodAutoscaler{ + successCases := []extensions.HorizontalPodAutoscaler{ { ObjectMeta: api.ObjectMeta{ Name: "myautoscaler", Namespace: api.NamespaceDefault, }, - Spec: experimental.HorizontalPodAutoscalerSpec{ - ScaleRef: &experimental.SubresourceReference{ + Spec: extensions.HorizontalPodAutoscalerSpec{ + ScaleRef: &extensions.SubresourceReference{ Subresource: "scale", }, - MinCount: 1, - MaxCount: 5, - Target: experimental.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")}, + MinReplicas: 1, + MaxReplicas: 5, + Target: extensions.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")}, }, }, } @@ -50,33 +51,33 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) { } } - errorCases := map[string]experimental.HorizontalPodAutoscaler{ + errorCases := map[string]extensions.HorizontalPodAutoscaler{ "must be non-negative": { ObjectMeta: api.ObjectMeta{ Name: "myautoscaler", Namespace: api.NamespaceDefault, }, - Spec: experimental.HorizontalPodAutoscalerSpec{ - ScaleRef: &experimental.SubresourceReference{ + Spec: extensions.HorizontalPodAutoscalerSpec{ + ScaleRef: &extensions.SubresourceReference{ Subresource: "scale", }, - MinCount: -1, - MaxCount: 5, - Target: experimental.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")}, + MinReplicas: -1, + MaxReplicas: 5, + Target: extensions.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")}, }, }, - "must be bigger or equal to minCount": { + "must be bigger or equal to minReplicas": { ObjectMeta: api.ObjectMeta{ Name: "myautoscaler", Namespace: api.NamespaceDefault, }, - Spec: experimental.HorizontalPodAutoscalerSpec{ - ScaleRef: &experimental.SubresourceReference{ + Spec: extensions.HorizontalPodAutoscalerSpec{ + ScaleRef: &extensions.SubresourceReference{ Subresource: "scale", }, - MinCount: 7, - MaxCount: 5, - Target: experimental.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")}, + MinReplicas: 7, + MaxReplicas: 5, + Target: extensions.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")}, }, }, "invalid value": { @@ -84,13 +85,13 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) { Name: "myautoscaler", Namespace: api.NamespaceDefault, }, - Spec: experimental.HorizontalPodAutoscalerSpec{ - ScaleRef: &experimental.SubresourceReference{ + Spec: extensions.HorizontalPodAutoscalerSpec{ + ScaleRef: &extensions.SubresourceReference{ Subresource: "scale", }, - MinCount: 1, - MaxCount: 5, - Target: experimental.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("-0.8")}, + MinReplicas: 1, + MaxReplicas: 5, + Target: extensions.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("-0.8")}, }, }, "resource not supported": { @@ -98,13 +99,13 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) { Name: "myautoscaler", Namespace: api.NamespaceDefault, }, - Spec: experimental.HorizontalPodAutoscalerSpec{ - ScaleRef: &experimental.SubresourceReference{ + Spec: extensions.HorizontalPodAutoscalerSpec{ + ScaleRef: &extensions.SubresourceReference{ Subresource: "scale", }, - MinCount: 1, - MaxCount: 5, - Target: experimental.ResourceConsumption{Resource: api.ResourceName("NotSupportedResource"), Quantity: resource.MustParse("0.8")}, + MinReplicas: 1, + MaxReplicas: 5, + Target: extensions.ResourceConsumption{Resource: api.ResourceName("NotSupportedResource"), Quantity: resource.MustParse("0.8")}, }, }, "required value": { @@ -112,10 +113,10 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) { Name: "myautoscaler", Namespace: api.NamespaceDefault, }, - Spec: experimental.HorizontalPodAutoscalerSpec{ - MinCount: 1, - MaxCount: 5, - Target: experimental.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")}, + Spec: extensions.HorizontalPodAutoscalerSpec{ + MinReplicas: 1, + MaxReplicas: 5, + Target: extensions.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")}, }, }, } @@ -130,6 +131,70 @@ func TestValidateHorizontalPodAutoscaler(t *testing.T) { } } +func TestValidateDaemonSetStatusUpdate(t *testing.T) { + type dsUpdateTest struct { + old extensions.DaemonSet + update extensions.DaemonSet + } + + successCases := []dsUpdateTest{ + { + old: extensions.DaemonSet{ + ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, + Status: extensions.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + }, + }, + update: extensions.DaemonSet{ + ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, + Status: extensions.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 1, + DesiredNumberScheduled: 3, + }, + }, + }, + } + + for _, successCase := range successCases { + successCase.old.ObjectMeta.ResourceVersion = "1" + successCase.update.ObjectMeta.ResourceVersion = "1" + if errs := ValidateDaemonSetStatusUpdate(&successCase.update, &successCase.old); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + + errorCases := map[string]dsUpdateTest{ + "negative values": { + old: extensions.DaemonSet{ + ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, + Status: extensions.DaemonSetStatus{ + CurrentNumberScheduled: 1, + NumberMisscheduled: 2, + DesiredNumberScheduled: 3, + }, + }, + update: extensions.DaemonSet{ + ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, + Status: extensions.DaemonSetStatus{ + CurrentNumberScheduled: -1, + NumberMisscheduled: -1, + DesiredNumberScheduled: -3, + }, + }, + }, + } + + for testName, errorCase := range errorCases { + if errs := ValidateDaemonSetStatusUpdate(&errorCase.old, &errorCase.update); len(errs) == 0 { + t.Errorf("expected failure: %s", testName) + } + } + +} + func TestValidateDaemonSetUpdate(t *testing.T) { validSelector := map[string]string{"a": "b"} validSelector2 := map[string]string{"c": "d"} @@ -212,53 +277,53 @@ func TestValidateDaemonSetUpdate(t *testing.T) { } type dsUpdateTest struct { - old experimental.DaemonSet - update experimental.DaemonSet + old extensions.DaemonSet + update extensions.DaemonSet } successCases := []dsUpdateTest{ { - old: experimental.DaemonSet{ + old: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateAbc.Template, }, }, - update: experimental.DaemonSet{ + update: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateAbc.Template, }, }, }, { - old: experimental.DaemonSet{ + old: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateAbc.Template, }, }, - update: experimental.DaemonSet{ + update: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector2, Template: &validPodTemplateAbc2.Template, }, }, }, { - old: experimental.DaemonSet{ + old: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateAbc.Template, }, }, - update: experimental.DaemonSet{ + update: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateNodeSelector.Template, }, @@ -274,80 +339,80 @@ func TestValidateDaemonSetUpdate(t *testing.T) { } errorCases := map[string]dsUpdateTest{ "change daemon name": { - old: experimental.DaemonSet{ + old: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateAbc.Template, }, }, - update: experimental.DaemonSet{ + update: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateAbc.Template, }, }, }, "invalid selector": { - old: experimental.DaemonSet{ + old: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateAbc.Template, }, }, - update: experimental.DaemonSet{ + update: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: invalidSelector, Template: &validPodTemplateAbc.Template, }, }, }, "invalid pod": { - old: experimental.DaemonSet{ + old: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateAbc.Template, }, }, - update: experimental.DaemonSet{ + update: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &invalidPodTemplate.Template, }, }, }, "change container image": { - old: experimental.DaemonSet{ + old: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateAbc.Template, }, }, - update: experimental.DaemonSet{ + update: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateDef.Template, }, }, }, "read-write volume": { - old: experimental.DaemonSet{ + old: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplateAbc.Template, }, }, - update: experimental.DaemonSet{ + update: extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &readWriteVolumePodTemplate.Template, }, @@ -387,17 +452,17 @@ func TestValidateDaemonSet(t *testing.T) { }, }, } - successCases := []experimental.DaemonSet{ + successCases := []extensions.DaemonSet{ { ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplate.Template, }, }, { ObjectMeta: api.ObjectMeta{Name: "abc-123", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplate.Template, }, @@ -409,37 +474,37 @@ func TestValidateDaemonSet(t *testing.T) { } } - errorCases := map[string]experimental.DaemonSet{ + errorCases := map[string]extensions.DaemonSet{ "zero-length ID": { ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplate.Template, }, }, "missing-namespace": { ObjectMeta: api.ObjectMeta{Name: "abc-123"}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplate.Template, }, }, "empty selector": { ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Template: &validPodTemplate.Template, }, }, "selector_doesnt_match": { ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: map[string]string{"foo": "bar"}, Template: &validPodTemplate.Template, }, }, "invalid manifest": { ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, }, }, @@ -451,7 +516,7 @@ func TestValidateDaemonSet(t *testing.T) { "NoUppercaseOrSpecialCharsLike=Equals": "bar", }, }, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplate.Template, }, @@ -464,7 +529,7 @@ func TestValidateDaemonSet(t *testing.T) { "NoUppercaseOrSpecialCharsLike=Equals": "bar", }, }, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Template: &invalidPodTemplate.Template, }, }, @@ -476,7 +541,7 @@ func TestValidateDaemonSet(t *testing.T) { "NoUppercaseOrSpecialCharsLike=Equals": "bar", }, }, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &validPodTemplate.Template, }, @@ -486,7 +551,7 @@ func TestValidateDaemonSet(t *testing.T) { Name: "abc-123", Namespace: api.NamespaceDefault, }, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &api.PodTemplateSpec{ Spec: api.PodSpec{ @@ -505,7 +570,7 @@ func TestValidateDaemonSet(t *testing.T) { Name: "abc-123", Namespace: api.NamespaceDefault, }, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: validSelector, Template: &api.PodTemplateSpec{ Spec: api.PodSpec{ @@ -542,13 +607,13 @@ func TestValidateDaemonSet(t *testing.T) { } } -func validDeployment() *experimental.Deployment { - return &experimental.Deployment{ +func validDeployment() *extensions.Deployment { + return &extensions.Deployment{ ObjectMeta: api.ObjectMeta{ Name: "abc", Namespace: api.NamespaceDefault, }, - Spec: experimental.DeploymentSpec{ + Spec: extensions.DeploymentSpec{ Selector: map[string]string{ "name": "abc", }, @@ -578,7 +643,7 @@ func validDeployment() *experimental.Deployment { } func TestValidateDeployment(t *testing.T) { - successCases := []*experimental.Deployment{ + successCases := []*extensions.Deployment{ validDeployment(), } for _, successCase := range successCases { @@ -587,8 +652,8 @@ func TestValidateDeployment(t *testing.T) { } } - errorCases := map[string]*experimental.Deployment{} - errorCases["metadata.name: required value"] = &experimental.Deployment{ + errorCases := map[string]*extensions.Deployment{} + errorCases["metadata.name: required value"] = &extensions.Deployment{ ObjectMeta: api.ObjectMeta{ Namespace: api.NamespaceDefault, }, @@ -612,17 +677,17 @@ func TestValidateDeployment(t *testing.T) { // rollingUpdate should be nil for recreate. invalidRecreateDeployment := validDeployment() - invalidRecreateDeployment.Spec.Strategy = experimental.DeploymentStrategy{ - Type: experimental.DeploymentRecreate, - RollingUpdate: &experimental.RollingUpdateDeployment{}, + invalidRecreateDeployment.Spec.Strategy = extensions.DeploymentStrategy{ + Type: extensions.RecreateDeploymentStrategyType, + RollingUpdate: &extensions.RollingUpdateDeployment{}, } errorCases["rollingUpdate should be nil when strategy type is Recreate"] = invalidRecreateDeployment // MaxSurge should be in the form of 20%. invalidMaxSurgeDeployment := validDeployment() - invalidMaxSurgeDeployment.Spec.Strategy = experimental.DeploymentStrategy{ - Type: experimental.DeploymentRollingUpdate, - RollingUpdate: &experimental.RollingUpdateDeployment{ + invalidMaxSurgeDeployment.Spec.Strategy = extensions.DeploymentStrategy{ + Type: extensions.RollingUpdateDeploymentStrategyType, + RollingUpdate: &extensions.RollingUpdateDeployment{ MaxSurge: util.NewIntOrStringFromString("20Percent"), }, } @@ -630,9 +695,9 @@ func TestValidateDeployment(t *testing.T) { // MaxSurge and MaxUnavailable cannot both be zero. invalidRollingUpdateDeployment := validDeployment() - invalidRollingUpdateDeployment.Spec.Strategy = experimental.DeploymentStrategy{ - Type: experimental.DeploymentRollingUpdate, - RollingUpdate: &experimental.RollingUpdateDeployment{ + invalidRollingUpdateDeployment.Spec.Strategy = extensions.DeploymentStrategy{ + Type: extensions.RollingUpdateDeploymentStrategyType, + RollingUpdate: &extensions.RollingUpdateDeployment{ MaxSurge: util.NewIntOrStringFromString("0%"), MaxUnavailable: util.NewIntOrStringFromInt(0), }, @@ -641,9 +706,9 @@ func TestValidateDeployment(t *testing.T) { // MaxUnavailable should not be more than 100%. invalidMaxUnavailableDeployment := validDeployment() - invalidMaxUnavailableDeployment.Spec.Strategy = experimental.DeploymentStrategy{ - Type: experimental.DeploymentRollingUpdate, - RollingUpdate: &experimental.RollingUpdateDeployment{ + invalidMaxUnavailableDeployment.Spec.Strategy = extensions.DeploymentStrategy{ + Type: extensions.RollingUpdateDeploymentStrategyType, + RollingUpdate: &extensions.RollingUpdateDeployment{ MaxUnavailable: util.NewIntOrStringFromString("110%"), }, } @@ -671,15 +736,15 @@ func TestValidateJob(t *testing.T) { Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, } - successCases := []experimental.Job{ + successCases := []extensions.Job{ { ObjectMeta: api.ObjectMeta{ Name: "myjob", Namespace: api.NamespaceDefault, }, - Spec: experimental.JobSpec{ + Spec: extensions.JobSpec{ Selector: validSelector, - Template: &validPodTemplateSpec, + Template: validPodTemplateSpec, }, }, } @@ -689,16 +754,16 @@ func TestValidateJob(t *testing.T) { } } negative := -1 - errorCases := map[string]experimental.Job{ + errorCases := map[string]extensions.Job{ "spec.parallelism:must be non-negative": { ObjectMeta: api.ObjectMeta{ Name: "myjob", Namespace: api.NamespaceDefault, }, - Spec: experimental.JobSpec{ + Spec: extensions.JobSpec{ Parallelism: &negative, Selector: validSelector, - Template: &validPodTemplateSpec, + Template: validPodTemplateSpec, }, }, "spec.completions:must be non-negative": { @@ -706,10 +771,10 @@ func TestValidateJob(t *testing.T) { Name: "myjob", Namespace: api.NamespaceDefault, }, - Spec: experimental.JobSpec{ + Spec: extensions.JobSpec{ Completions: &negative, Selector: validSelector, - Template: &validPodTemplateSpec, + Template: validPodTemplateSpec, }, }, "spec.selector:required value": { @@ -717,18 +782,9 @@ func TestValidateJob(t *testing.T) { Name: "myjob", Namespace: api.NamespaceDefault, }, - Spec: experimental.JobSpec{ + Spec: extensions.JobSpec{ Selector: map[string]string{}, - Template: &validPodTemplateSpec, - }, - }, - "spec.template:required value": { - ObjectMeta: api.ObjectMeta{ - Name: "myjob", - Namespace: api.NamespaceDefault, - }, - Spec: experimental.JobSpec{ - Selector: validSelector, + Template: validPodTemplateSpec, }, }, "spec.template.labels:selector does not match template": { @@ -736,9 +792,9 @@ func TestValidateJob(t *testing.T) { Name: "myjob", Namespace: api.NamespaceDefault, }, - Spec: experimental.JobSpec{ + Spec: extensions.JobSpec{ Selector: validSelector, - Template: &api.PodTemplateSpec{ + Template: api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: map[string]string{"y": "z"}, }, @@ -755,9 +811,9 @@ func TestValidateJob(t *testing.T) { Name: "myjob", Namespace: api.NamespaceDefault, }, - Spec: experimental.JobSpec{ + Spec: extensions.JobSpec{ Selector: validSelector, - Template: &api.PodTemplateSpec{ + Template: api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: validSelector, }, @@ -784,3 +840,218 @@ func TestValidateJob(t *testing.T) { } } } + +type ingressRules map[string]string + +func TestValidateIngress(t *testing.T) { + defaultBackend := extensions.IngressBackend{ + ServiceName: "default-backend", + ServicePort: util.IntOrString{Kind: util.IntstrInt, IntVal: 80}, + } + + newValid := func() extensions.Ingress { + return extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.IngressSpec{ + Backend: &extensions.IngressBackend{ + ServiceName: "default-backend", + ServicePort: util.IntOrString{Kind: util.IntstrInt, IntVal: 80}, + }, + Rules: []extensions.IngressRule{ + { + Host: "foo.bar.com", + IngressRuleValue: extensions.IngressRuleValue{ + HTTP: &extensions.HTTPIngressRuleValue{ + Paths: []extensions.HTTPIngressPath{ + { + Path: "/foo", + Backend: defaultBackend, + }, + }, + }, + }, + }, + }, + }, + Status: extensions.IngressStatus{ + LoadBalancer: api.LoadBalancerStatus{ + Ingress: []api.LoadBalancerIngress{ + {IP: "127.0.0.1"}, + }, + }, + }, + } + } + servicelessBackend := newValid() + servicelessBackend.Spec.Backend.ServiceName = "" + invalidNameBackend := newValid() + invalidNameBackend.Spec.Backend.ServiceName = "defaultBackend" + noPortBackend := newValid() + noPortBackend.Spec.Backend = &extensions.IngressBackend{ServiceName: defaultBackend.ServiceName} + noForwardSlashPath := newValid() + noForwardSlashPath.Spec.Rules[0].IngressRuleValue.HTTP.Paths = []extensions.HTTPIngressPath{ + { + Path: "invalid", + Backend: defaultBackend, + }, + } + noPaths := newValid() + noPaths.Spec.Rules[0].IngressRuleValue.HTTP.Paths = []extensions.HTTPIngressPath{} + badHost := newValid() + badHost.Spec.Rules[0].Host = "foobar:80" + badRegexPath := newValid() + badPathExpr := "/invalid[" + badRegexPath.Spec.Rules[0].IngressRuleValue.HTTP.Paths = []extensions.HTTPIngressPath{ + { + Path: badPathExpr, + Backend: defaultBackend, + }, + } + badPathErr := fmt.Sprintf("spec.rules.ingressRule.http.path: invalid value '%v'", + badPathExpr) + hostIP := "127.0.0.1" + badHostIP := newValid() + badHostIP.Spec.Rules[0].Host = hostIP + badHostIPErr := fmt.Sprintf("spec.rules.host: invalid value '%v'", hostIP) + + errorCases := map[string]extensions.Ingress{ + "spec.backend.serviceName: required value": servicelessBackend, + "spec.backend.serviceName: invalid value": invalidNameBackend, + "spec.backend.servicePort: invalid value": noPortBackend, + "spec.rules.host: invalid value": badHost, + "spec.rules.ingressRule.http.paths: required value": noPaths, + "spec.rules.ingressRule.http.path: invalid value": noForwardSlashPath, + } + errorCases[badPathErr] = badRegexPath + errorCases[badHostIPErr] = badHostIP + + for k, v := range errorCases { + errs := ValidateIngress(&v) + if len(errs) == 0 { + t.Errorf("expected failure for %s", k) + } else { + s := strings.Split(k, ":") + err := errs[0].(*errors.ValidationError) + if err.Field != s[0] || !strings.Contains(err.Error(), s[1]) { + t.Errorf("unexpected error: %v, expected: %s", errs[0], k) + } + } + } +} + +func TestValidateClusterAutoscaler(t *testing.T) { + successCases := []extensions.ClusterAutoscaler{ + { + ObjectMeta: api.ObjectMeta{ + Name: "ClusterAutoscaler", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.ClusterAutoscalerSpec{ + MinNodes: 1, + MaxNodes: 5, + TargetUtilization: []extensions.NodeUtilization{ + { + Resource: extensions.CpuRequest, + Value: 0.7, + }, + }, + }, + }, + } + for _, successCase := range successCases { + if errs := ValidateClusterAutoscaler(&successCase); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + + errorCases := map[string]extensions.ClusterAutoscaler{ + "name must be ClusterAutoscaler": { + ObjectMeta: api.ObjectMeta{ + Name: "TestClusterAutoscaler", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.ClusterAutoscalerSpec{ + MinNodes: 1, + MaxNodes: 5, + TargetUtilization: []extensions.NodeUtilization{ + { + Resource: extensions.CpuRequest, + Value: 0.7, + }, + }, + }, + }, + "namespace must be default": { + ObjectMeta: api.ObjectMeta{ + Name: "ClusterAutoscaler", + Namespace: "test", + }, + Spec: extensions.ClusterAutoscalerSpec{ + MinNodes: 1, + MaxNodes: 5, + TargetUtilization: []extensions.NodeUtilization{ + { + Resource: extensions.CpuRequest, + Value: 0.7, + }, + }, + }, + }, + + `must be non-negative`: { + ObjectMeta: api.ObjectMeta{ + Name: "ClusterAutoscaler", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.ClusterAutoscalerSpec{ + MinNodes: -1, + MaxNodes: 5, + TargetUtilization: []extensions.NodeUtilization{ + { + Resource: extensions.CpuRequest, + Value: 0.7, + }, + }, + }, + }, + `must be bigger or equal to minNodes`: { + ObjectMeta: api.ObjectMeta{ + Name: "ClusterAutoscaler", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.ClusterAutoscalerSpec{ + MinNodes: 10, + MaxNodes: 5, + TargetUtilization: []extensions.NodeUtilization{ + { + Resource: extensions.CpuRequest, + Value: 0.7, + }, + }, + }, + }, + "required value": { + ObjectMeta: api.ObjectMeta{ + Name: "ClusterAutoscaler", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.ClusterAutoscalerSpec{ + MinNodes: 1, + MaxNodes: 5, + TargetUtilization: []extensions.NodeUtilization{}, + }, + }, + } + + for k, v := range errorCases { + errs := ValidateClusterAutoscaler(&v) + if len(errs) == 0 { + t.Errorf("expected failure for %s", k) + } else if !strings.Contains(errs[0].Error(), k) { + t.Errorf("unexpected error: %v, expected: %s", errs[0], k) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go index 162588c925b5..1a463dd34bdd 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go @@ -29,6 +29,7 @@ import ( "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/runtime" watchjson "k8s.io/kubernetes/pkg/watch/json" @@ -60,12 +61,9 @@ type documentable interface { var errEmptyName = errors.NewBadRequest("name must be provided") // Installs handlers for API resources. -func (a *APIInstaller) Install() (ws *restful.WebService, errors []error) { +func (a *APIInstaller) Install(ws *restful.WebService) (apiResources []unversioned.APIResource, errors []error) { errors = make([]error, 0) - // Create the WebService. - ws = a.newWebService() - proxyHandler := (&ProxyHandler{a.prefix + "/proxy/", a.group.Storage, a.group.Codec, a.group.Context, a.info}) // Register the paths in a deterministic (sorted) order to get a deterministic swagger spec. @@ -77,17 +75,23 @@ func (a *APIInstaller) Install() (ws *restful.WebService, errors []error) { } sort.Strings(paths) for _, path := range paths { - if err := a.registerResourceHandlers(path, a.group.Storage[path], ws, proxyHandler); err != nil { + apiResource, err := a.registerResourceHandlers(path, a.group.Storage[path], ws, proxyHandler) + if err != nil { errors = append(errors, err) } + if apiResource != nil { + apiResources = append(apiResources, *apiResource) + } } - return ws, errors + return apiResources, errors } -func (a *APIInstaller) newWebService() *restful.WebService { +// NewWebService creates a new restful webservice with the api installer's prefix and version. +func (a *APIInstaller) NewWebService() *restful.WebService { ws := new(restful.WebService) ws.Path(a.prefix) - ws.Doc("API at " + a.prefix + " version " + a.group.Version) + // a.prefix contains "prefix/group/version" + ws.Doc("API at " + a.prefix) // TODO: change to restful.MIME_JSON when we set content type in client ws.Consumes("*/*") ws.Produces(restful.MIME_JSON) @@ -96,7 +100,7 @@ func (a *APIInstaller) newWebService() *restful.WebService { return ws } -func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storage, ws *restful.WebService, proxyHandler http.Handler) error { +func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storage, ws *restful.WebService, proxyHandler http.Handler) (*unversioned.APIResource, error) { admit := a.group.Admit context := a.group.Context @@ -113,40 +117,40 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag resource = parts[0] default: // TODO: support deeper paths - return fmt.Errorf("api_installer allows only one or two segment paths (resource or resource/subresource)") + return nil, fmt.Errorf("api_installer allows only one or two segment paths (resource or resource/subresource)") } hasSubresource := len(subresource) > 0 object := storage.New() _, kind, err := a.group.Typer.ObjectVersionAndKind(object) if err != nil { - return err + return nil, err } versionedPtr, err := a.group.Creater.New(a.group.Version, kind) if err != nil { - return err + return nil, err } versionedObject := indirectArbitraryPointer(versionedPtr) mapping, err := a.group.Mapper.RESTMapping(kind, a.group.Version) if err != nil { - return err + return nil, err } // subresources must have parent resources, and follow the namespacing rules of their parent if hasSubresource { parentStorage, ok := a.group.Storage[resource] if !ok { - return fmt.Errorf("subresources can only be declared when the parent is also registered: %s needs %s", path, resource) + return nil, fmt.Errorf("subresources can only be declared when the parent is also registered: %s needs %s", path, resource) } parentObject := parentStorage.New() _, parentKind, err := a.group.Typer.ObjectVersionAndKind(parentObject) if err != nil { - return err + return nil, err } parentMapping, err := a.group.Mapper.RESTMapping(parentKind, a.group.Version) if err != nil { - return err + return nil, err } mapping.Scope = parentMapping.Scope } @@ -179,14 +183,14 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag _, listKind, err := a.group.Typer.ObjectVersionAndKind(list) versionedListPtr, err := a.group.Creater.New(a.group.Version, listKind) if err != nil { - return err + return nil, err } versionedList = indirectArbitraryPointer(versionedListPtr) } versionedListOptions, err := a.group.Creater.New(serverVersion, "ListOptions") if err != nil { - return err + return nil, err } var versionedDeleterObject interface{} @@ -194,7 +198,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag case isGracefulDeleter: objectPtr, err := a.group.Creater.New(serverVersion, "DeleteOptions") if err != nil { - return err + return nil, err } versionedDeleterObject = indirectArbitraryPointer(objectPtr) isDeleter = true @@ -204,7 +208,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag versionedStatusPtr, err := a.group.Creater.New(serverVersion, "Status") if err != nil { - return err + return nil, err } versionedStatus := indirectArbitraryPointer(versionedStatusPtr) var ( @@ -218,11 +222,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag getOptions, getSubpath, getSubpathKey = getterWithOptions.NewGetOptions() _, getOptionsKind, err = a.group.Typer.ObjectVersionAndKind(getOptions) if err != nil { - return err + return nil, err } versionedGetOptions, err = a.group.Creater.New(serverVersion, getOptionsKind) if err != nil { - return err + return nil, err } isGetter = true } @@ -239,7 +243,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if connectOptions != nil { _, connectOptionsKind, err = a.group.Typer.ObjectVersionAndKind(connectOptions) if err != nil { - return err + return nil, err } versionedConnectOptions, err = a.group.Creater.New(serverVersion, connectOptionsKind) } @@ -259,10 +263,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag allowWatchList := isWatcher && isLister // watching on lists is allowed only for kinds that support both watch and list. scope := mapping.Scope nameParam := ws.PathParameter("name", "name of the "+kind).DataType("string") - pathParam := ws.PathParameter("path:*", "path to the resource").DataType("string") + pathParam := ws.PathParameter("path", "path to the resource").DataType("string") params := []*restful.Parameter{} actions := []action{} + var apiResource unversioned.APIResource // Get the list of actions for the given scope. switch scope.Name() { case meta.RESTScopeNameRoot: @@ -277,6 +282,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag resourcePath = itemPath resourceParams = nameParams } + apiResource.Name = path + apiResource.Namespaced = false namer := rootScopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath)} // Handler for standard REST verbs (GET, PUT, POST and DELETE). @@ -315,6 +322,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag resourcePath = itemPath resourceParams = nameParams } + apiResource.Name = path + apiResource.Namespaced = true namer := scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), false} actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer}, isLister) @@ -341,12 +350,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if !hasSubresource { namer = scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), true} actions = appendIf(actions, action{"LIST", resource, params, namer}, isLister) - actions = appendIf(actions, action{"POST", resource, params, namer}, isCreater) actions = appendIf(actions, action{"WATCHLIST", "watch/" + resource, params, namer}, allowWatchList) } break default: - return fmt.Errorf("unsupported restscope: %s", scope.Name()) + return nil, fmt.Errorf("unsupported restscope: %s", scope.Name()) } // Create Routes for the actions. @@ -406,7 +414,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Writes(versionedObject) if isGetterWithOptions { if err := addObjectParams(ws, route, versionedGetOptions); err != nil { - return err + return nil, err } } addParams(route, action.Params) @@ -425,7 +433,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Returns(http.StatusOK, "OK", versionedList). Writes(versionedList) if err := addObjectParams(ws, route, versionedListOptions); err != nil { - return err + return nil, err } switch { case isLister && isWatcher: @@ -472,7 +480,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Operation("patch"+namespaced+kind+strings.Title(subresource)). Produces(append(storageMeta.ProducesMIMETypes(action.Verb), "application/json")...). Returns(http.StatusOK, "OK", versionedObject). - Reads(api.Patch{}). + Reads(unversioned.Patch{}). Writes(versionedObject) addParams(route, action.Params) ws.Route(route) @@ -531,7 +539,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Returns(http.StatusOK, "OK", watchjson.WatchEvent{}). Writes(watchjson.WatchEvent{}) if err := addObjectParams(ws, route, versionedListOptions); err != nil { - return err + return nil, err } addParams(route, action.Params) ws.Route(route) @@ -550,7 +558,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Returns(http.StatusOK, "OK", watchjson.WatchEvent{}). Writes(watchjson.WatchEvent{}) if err := addObjectParams(ws, route, versionedListOptions); err != nil { - return err + return nil, err } addParams(route, action.Params) ws.Route(route) @@ -578,18 +586,18 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Writes("string") if versionedConnectOptions != nil { if err := addObjectParams(ws, route, versionedConnectOptions); err != nil { - return err + return nil, err } } addParams(route, action.Params) ws.Route(route) } default: - return fmt.Errorf("unrecognized action verb: %s", action.Verb) + return nil, fmt.Errorf("unrecognized action verb: %s", action.Verb) } // Note: update GetAttribs() when adding a custom handler. } - return nil + return &apiResource, nil } // rootScopeNaming reads only names from a request and ignores namespaces. It implements ScopeNamer @@ -809,7 +817,7 @@ func addObjectParams(ws *restful.WebService, route *restful.RouteBuilder, obj in if docable, ok := obj.(documentable); ok { desc = docable.SwaggerDoc()[jsonName] } - route.Param(ws.QueryParameter(jsonName, desc).DataType(typeToJSON(sf.Type.Name()))) + route.Param(ws.QueryParameter(jsonName, desc).DataType(typeToJSON(sf.Type.String()))) } } } @@ -824,11 +832,15 @@ func typeToJSON(typeName string) string { return "boolean" case "uint8", "int", "int32", "int64", "uint32", "uint64": return "integer" - case "byte": - return "string" case "float64", "float32": return "number" - case "util.Time", "*util.Time": + case "unversioned.Time": + return "string" + case "byte": + return "string" + case "[]string": + // TODO: Fix this when go-restful supports a way to specify an array query param: + // https://github.com/emicklei/go-restful/issues/225 return "string" default: return typeName diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer_test.go index fd5750ccf3c4..57df10e94c4d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer_test.go @@ -21,6 +21,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" "github.com/emicklei/go-restful" ) @@ -43,7 +44,7 @@ func TestScopeNamingGenerateLink(t *testing.T) { Name: "foo", Namespace: "other", }, - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Service", }, } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/apiserver.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/apiserver.go index 7b4b33a65b4b..d805f7ab321e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/apiserver.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/apiserver.go @@ -36,13 +36,13 @@ import ( "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apiserver/metrics" "k8s.io/kubernetes/pkg/healthz" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/flushwriter" - "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/wsstream" "k8s.io/kubernetes/pkg/version" @@ -79,13 +79,20 @@ type Mux interface { type APIGroupVersion struct { Storage map[string]rest.Storage - Root string + Root string + // TODO: caesarxuchao: Version actually contains "group/version", refactor it to avoid confusion. Version string + // APIRequestInfoResolver is used to parse URLs for the legacy proxy handler. Don't use this for anything else + // TODO: refactor proxy handler to use sub resources + APIRequestInfoResolver *APIRequestInfoResolver + // ServerVersion controls the Kubernetes APIVersion used for common objects in the apiserver // schema like api.Status, api.DeleteOptions, and api.ListOptions. Other implementors may // define a version "v1beta1" but want to use the Kubernetes "v1" internal objects. If // empty, defaults to Version. + // TODO: caesarxuchao: ServerVersion actually contains "group/version", + // refactor it to avoid confusion. ServerVersion string Mapper meta.RESTMapper @@ -114,20 +121,51 @@ const ( // InstallREST registers the REST handlers (storage, watch, proxy and redirect) into a restful Container. // It is expected that the provided path root prefix will serve all operations. Root MUST NOT end -// in a slash. A restful WebService is created for the group and version. +// in a slash. func (g *APIGroupVersion) InstallREST(container *restful.Container) error { - info := &APIRequestInfoResolver{sets.NewString(strings.TrimPrefix(g.Root, "/")), g.Mapper} + installer := g.newInstaller() + ws := installer.NewWebService() + apiResources, registrationErrors := installer.Install(ws) + // TODO: g.Version only contains "version" now, it will contain "group/version" in the near future. + AddSupportedResourcesWebService(ws, g.Version, apiResources) + container.Add(ws) + return errors.NewAggregate(registrationErrors) +} + +// UpdateREST registers the REST handlers for this APIGroupVersion to an existing web service +// in the restful Container. It will use the prefix (root/version) to find the existing +// web service. If a web service does not exist within the container to support the prefix +// this method will return an error. +func (g *APIGroupVersion) UpdateREST(container *restful.Container) error { + installer := g.newInstaller() + var ws *restful.WebService = nil + + for i, s := range container.RegisteredWebServices() { + if s.RootPath() == installer.prefix { + ws = container.RegisteredWebServices()[i] + break + } + } + + if ws == nil { + return apierrors.NewInternalError(fmt.Errorf("unable to find an existing webservice for prefix %s", installer.prefix)) + } + apiResources, registrationErrors := installer.Install(ws) + // TODO: g.Version only contains "version" now, it will contain "group/version" in the near future. + AddSupportedResourcesWebService(ws, g.Version, apiResources) + return errors.NewAggregate(registrationErrors) +} +// newInstaller is a helper to create the installer. Used by InstallREST and UpdateREST. +func (g *APIGroupVersion) newInstaller() *APIInstaller { prefix := path.Join(g.Root, g.Version) installer := &APIInstaller{ group: g, - info: info, + info: g.APIRequestInfoResolver, prefix: prefix, minRequestTimeout: g.MinRequestTimeout, } - ws, registrationErrors := installer.Install() - container.Add(ws) - return errors.NewAggregate(registrationErrors) + return installer } // TODO: document all handlers @@ -176,7 +214,7 @@ func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter) glog.Errorln(buffer.String()) // TODO: make status unversioned or plumb enough of the request to deduce the requested API version - errorJSON(apierrors.NewGenericServerResponse(http.StatusInternalServerError, "", "", "", "", 0, false), latest.Codec, httpWriter) + errorJSON(apierrors.NewGenericServerResponse(http.StatusInternalServerError, "", "", "", "", 0, false), latest.GroupOrDie("").Codec, httpWriter) } func InstallServiceErrorHandler(container *restful.Container, requestResolver *APIRequestInfoResolver, apiVersions []string) { @@ -187,7 +225,7 @@ func InstallServiceErrorHandler(container *restful.Container, requestResolver *A func serviceErrorHandler(requestResolver *APIRequestInfoResolver, apiVersions []string, serviceErr restful.ServiceError, request *restful.Request, response *restful.Response) { requestInfo, err := requestResolver.GetAPIRequestInfo(request.Request) - codec := latest.Codec + codec := latest.GroupOrDie("").Codec if err == nil && requestInfo.APIVersion != "" { // check if the api version is valid. for _, version := range apiVersions { @@ -202,7 +240,7 @@ func serviceErrorHandler(requestResolver *APIRequestInfoResolver, apiVersions [] errorJSON(apierrors.NewGenericServerResponse(serviceErr.Code, "", "", "", "", 0, false), codec, response.ResponseWriter) } -// Adds a service to return the supported api versions. +// Adds a service to return the supported api versions at the legacy /api. func AddApiWebService(container *restful.Container, apiPrefix string, versions []string) { // TODO: InstallREST should register each version automatically @@ -218,6 +256,46 @@ func AddApiWebService(container *restful.Container, apiPrefix string, versions [ container.Add(ws) } +// Adds a service to return the supported api versions at /apis. +func AddApisWebService(container *restful.Container, apiPrefix string, groups []unversioned.APIGroup) { + rootAPIHandler := RootAPIHandler(groups) + ws := new(restful.WebService) + ws.Path(apiPrefix) + ws.Doc("get available API versions") + ws.Route(ws.GET("/").To(rootAPIHandler). + Doc("get available API versions"). + Operation("getAPIVersions"). + Produces(restful.MIME_JSON). + Consumes(restful.MIME_JSON)) + container.Add(ws) +} + +// Adds a service to return the supported versions, preferred version, and name +// of a group. E.g., a such web service will be registered at /apis/extensions. +func AddGroupWebService(container *restful.Container, path string, group unversioned.APIGroup) { + groupHandler := GroupHandler(group) + ws := new(restful.WebService) + ws.Path(path) + ws.Doc("get information of a group") + ws.Route(ws.GET("/").To(groupHandler). + Doc("get information of a group"). + Operation("getAPIGroup"). + Produces(restful.MIME_JSON). + Consumes(restful.MIME_JSON)) + container.Add(ws) +} + +// Adds a service to return the supported resources, E.g., a such web service +// will be registered at /apis/extensions/v1. +func AddSupportedResourcesWebService(ws *restful.WebService, groupVersion string, apiResources []unversioned.APIResource) { + resourceHandler := SupportedResourcesHandler(groupVersion, apiResources) + ws.Route(ws.GET("/").To(resourceHandler). + Doc("get available resources"). + Operation("getAPIResources"). + Produces(restful.MIME_JSON). + Consumes(restful.MIME_JSON)) +} + // handleVersion writes the server's version information. func handleVersion(req *restful.Request, resp *restful.Response) { // TODO: use restful's Response methods @@ -228,7 +306,32 @@ func handleVersion(req *restful.Request, resp *restful.Response) { func APIVersionHandler(versions ...string) restful.RouteFunction { return func(req *restful.Request, resp *restful.Response) { // TODO: use restful's Response methods - writeRawJSON(http.StatusOK, api.APIVersions{Versions: versions}, resp.ResponseWriter) + writeRawJSON(http.StatusOK, unversioned.APIVersions{Versions: versions}, resp.ResponseWriter) + } +} + +// RootAPIHandler returns a handler which will list the provided groups and versions as available. +func RootAPIHandler(groups []unversioned.APIGroup) restful.RouteFunction { + return func(req *restful.Request, resp *restful.Response) { + // TODO: use restful's Response methods + writeRawJSON(http.StatusOK, unversioned.APIGroupList{Groups: groups}, resp.ResponseWriter) + } +} + +// GroupHandler returns a handler which will return the api.GroupAndVersion of +// the group. +func GroupHandler(group unversioned.APIGroup) restful.RouteFunction { + return func(req *restful.Request, resp *restful.Response) { + // TODO: use restful's Response methods + writeRawJSON(http.StatusOK, group, resp.ResponseWriter) + } +} + +// SupportedResourcesHandler returns a handler which will list the provided resources as available. +func SupportedResourcesHandler(groupVersion string, apiResources []unversioned.APIResource) restful.RouteFunction { + return func(req *restful.Request, resp *restful.Response) { + // TODO: use restful's Response methods + writeRawJSON(http.StatusOK, unversioned.APIResourceList{GroupVersion: groupVersion, APIResources: apiResources}, resp.ResponseWriter) } } @@ -290,24 +393,32 @@ func isPrettyPrint(req *http.Request) bool { // writeJSON renders an object as JSON to the response. func writeJSON(statusCode int, codec runtime.Codec, object runtime.Object, w http.ResponseWriter, pretty bool) { + w.Header().Set("Content-Type", "application/json") + // We send the status code before we encode the object, so if we error, the status code stays but there will + // still be an error object. This seems ok, the alternative is to validate the object before + // encoding, but this really should never happen, so it's wasted compute for every API request. + w.WriteHeader(statusCode) + if pretty { + prettyJSON(codec, object, w) + return + } + err := codec.EncodeToStream(object, w) + if err != nil { + errorJSONFatal(err, codec, w) + } +} + +func prettyJSON(codec runtime.Codec, object runtime.Object, w http.ResponseWriter) { + formatted := &bytes.Buffer{} output, err := codec.Encode(object) if err != nil { errorJSONFatal(err, codec, w) - return } - if pretty { - // PR #2243: Pretty-print JSON by default. - formatted := &bytes.Buffer{} - err = json.Indent(formatted, output, "", " ") - if err != nil { - errorJSONFatal(err, codec, w) - return - } - output = formatted.Bytes() + if err := json.Indent(formatted, output, "", " "); err != nil { + errorJSONFatal(err, codec, w) + return } - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(statusCode) - w.Write(output) + w.Write(formatted.Bytes()) } // errorJSON renders an error to the response. Returns the HTTP status code of the error. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/apiserver_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/apiserver_test.go index ccade600b396..86d454c42975 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/apiserver_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/apiserver_test.go @@ -37,10 +37,13 @@ import ( apierrs "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" + apiservertesting "k8s.io/kubernetes/pkg/apiserver/testing" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/pkg/watch" "k8s.io/kubernetes/plugin/pkg/admission/admit" @@ -94,26 +97,30 @@ func newMapper() *meta.DefaultRESTMapper { func addTestTypes() { type ListOptions struct { runtime.Object - api.TypeMeta `json:",inline"` - LabelSelector string `json:"labels,omitempty"` - FieldSelector string `json:"fields,omitempty"` - Watch bool `json:"watch,omitempty"` - ResourceVersion string `json:"resourceVersion,omitempty"` - } - api.Scheme.AddKnownTypes(testVersion, &Simple{}, &SimpleList{}, &api.Status{}, &ListOptions{}, &api.DeleteOptions{}, &SimpleGetOptions{}, &SimpleRoot{}) + unversioned.TypeMeta `json:",inline"` + LabelSelector string `json:"labels,omitempty"` + FieldSelector string `json:"fields,omitempty"` + Watch bool `json:"watch,omitempty"` + ResourceVersion string `json:"resourceVersion,omitempty"` + } + api.Scheme.AddKnownTypes( + testVersion, &apiservertesting.Simple{}, &apiservertesting.SimpleList{}, &unversioned.Status{}, + &ListOptions{}, &api.DeleteOptions{}, &apiservertesting.SimpleGetOptions{}, &apiservertesting.SimpleRoot{}) api.Scheme.AddKnownTypes(testVersion, &api.Pod{}) } func addNewTestTypes() { type ListOptions struct { runtime.Object - api.TypeMeta `json:",inline"` - LabelSelector string `json:"labelSelector,omitempty"` - FieldSelector string `json:"fieldSelector,omitempty"` - Watch bool `json:"watch,omitempty"` - ResourceVersion string `json:"resourceVersion,omitempty"` + unversioned.TypeMeta `json:",inline"` + LabelSelector string `json:"labelSelector,omitempty"` + FieldSelector string `json:"fieldSelector,omitempty"` + Watch bool `json:"watch,omitempty"` + ResourceVersion string `json:"resourceVersion,omitempty"` } - api.Scheme.AddKnownTypes(newVersion, &Simple{}, &SimpleList{}, &api.Status{}, &ListOptions{}, &api.DeleteOptions{}, &SimpleGetOptions{}, &SimpleRoot{}) + api.Scheme.AddKnownTypes( + newVersion, &apiservertesting.Simple{}, &apiservertesting.SimpleList{}, &unversioned.Status{}, + &ListOptions{}, &api.DeleteOptions{}, &apiservertesting.SimpleGetOptions{}, &apiservertesting.SimpleRoot{}) } func init() { @@ -121,7 +128,9 @@ func init() { // api.Status is returned in errors // "internal" version - api.Scheme.AddKnownTypes("", &Simple{}, &SimpleList{}, &api.Status{}, &api.ListOptions{}, &SimpleGetOptions{}, &SimpleRoot{}) + api.Scheme.AddKnownTypes( + "", &apiservertesting.Simple{}, &apiservertesting.SimpleList{}, &unversioned.Status{}, + &api.ListOptions{}, &apiservertesting.SimpleGetOptions{}, &apiservertesting.SimpleRoot{}) addTestTypes() addNewTestTypes() @@ -131,7 +140,7 @@ func init() { // the mapper how to address our resources for _, version := range versions { for kind := range api.Scheme.KnownTypes(version) { - root := kind == "SimpleRoot" + root := bool(kind == "SimpleRoot") if root { nsMapper.Add(meta.RESTScopeRoot, kind, version, false) } else { @@ -189,11 +198,16 @@ func handleLinker(storage map[string]rest.Storage, selfLinker runtime.SelfLinker return handleInternal(true, storage, admissionControl, selfLinker) } +func newTestAPIRequestInfoResolver() *APIRequestInfoResolver { + return &APIRequestInfoResolver{sets.NewString("api", "apis"), sets.NewString("api")} +} + func handleInternal(legacy bool, storage map[string]rest.Storage, admissionControl admission.Interface, selfLinker runtime.SelfLinker) http.Handler { group := &APIGroupVersion{ Storage: storage, Root: "/api", + APIRequestInfoResolver: newTestAPIRequestInfoResolver(), Creater: api.Scheme, Convertor: api.Scheme, @@ -227,50 +241,8 @@ func handleInternal(legacy bool, storage map[string]rest.Storage, admissionContr return &defaultAPIServer{mux, group, container} } -type Simple struct { - api.TypeMeta `json:",inline"` - api.ObjectMeta `json:"metadata"` - Other string `json:"other,omitempty"` - Labels map[string]string `json:"labels,omitempty"` -} - -func (*Simple) IsAnAPIObject() {} - -type SimpleRoot struct { - api.TypeMeta `json:",inline"` - api.ObjectMeta `json:"metadata"` - Other string `json:"other,omitempty"` - Labels map[string]string `json:"labels,omitempty"` -} - -func (*SimpleRoot) IsAnAPIObject() {} - -type SimpleGetOptions struct { - api.TypeMeta `json:",inline"` - Param1 string `json:"param1"` - Param2 string `json:"param2"` - Path string `json:"atAPath"` -} - -func (SimpleGetOptions) SwaggerDoc() map[string]string { - return map[string]string{ - "param1": "description for param1", - "param2": "description for param2", - } -} - -func (*SimpleGetOptions) IsAnAPIObject() {} - -type SimpleList struct { - api.TypeMeta `json:",inline"` - api.ListMeta `json:"metadata,inline"` - Items []Simple `json:"items,omitempty"` -} - -func (*SimpleList) IsAnAPIObject() {} - func TestSimpleSetupRight(t *testing.T) { - s := &Simple{ObjectMeta: api.ObjectMeta{Name: "aName"}} + s := &apiservertesting.Simple{ObjectMeta: api.ObjectMeta{Name: "aName"}} wire, err := codec.Encode(s) if err != nil { t.Fatal(err) @@ -285,7 +257,7 @@ func TestSimpleSetupRight(t *testing.T) { } func TestSimpleOptionsSetupRight(t *testing.T) { - s := &SimpleGetOptions{} + s := &apiservertesting.SimpleGetOptions{} wire, err := codec.Encode(s) if err != nil { t.Fatal(err) @@ -301,11 +273,11 @@ func TestSimpleOptionsSetupRight(t *testing.T) { type SimpleRESTStorage struct { errors map[string]error - list []Simple - item Simple + list []apiservertesting.Simple + item apiservertesting.Simple - updated *Simple - created *Simple + updated *apiservertesting.Simple + created *apiservertesting.Simple stream *SimpleStream @@ -335,7 +307,7 @@ type SimpleRESTStorage struct { func (storage *SimpleRESTStorage) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) { storage.checkContext(ctx) - result := &SimpleList{ + result := &apiservertesting.SimpleList{ Items: storage.list, } storage.requestedLabelSelector = label @@ -366,19 +338,14 @@ func (s *SimpleStream) InputStream(version, accept string) (io.ReadCloser, bool, return s, false, s.contentType, s.err } -type SimpleConnectHandler struct { +type OutputConnect struct { response string - err error } -func (h *SimpleConnectHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { +func (h *OutputConnect) ServeHTTP(w http.ResponseWriter, req *http.Request) { w.Write([]byte(h.response)) } -func (h *SimpleConnectHandler) RequestError() error { - return h.err -} - func (storage *SimpleRESTStorage) Get(ctx api.Context, id string) (runtime.Object, error) { storage.checkContext(ctx) if id == "binary" { @@ -398,25 +365,25 @@ func (storage *SimpleRESTStorage) Delete(ctx api.Context, id string, options *ap if err := storage.errors["delete"]; err != nil { return nil, err } - var obj runtime.Object = &api.Status{Status: api.StatusSuccess} + var obj runtime.Object = &unversioned.Status{Status: unversioned.StatusSuccess} var err error if storage.injectedFunction != nil { - obj, err = storage.injectedFunction(&Simple{ObjectMeta: api.ObjectMeta{Name: id}}) + obj, err = storage.injectedFunction(&apiservertesting.Simple{ObjectMeta: api.ObjectMeta{Name: id}}) } return obj, err } func (storage *SimpleRESTStorage) New() runtime.Object { - return &Simple{} + return &apiservertesting.Simple{} } func (storage *SimpleRESTStorage) NewList() runtime.Object { - return &SimpleList{} + return &apiservertesting.SimpleList{} } func (storage *SimpleRESTStorage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) { storage.checkContext(ctx) - storage.created = obj.(*Simple) + storage.created = obj.(*apiservertesting.Simple) if err := storage.errors["create"]; err != nil { return nil, err } @@ -429,7 +396,7 @@ func (storage *SimpleRESTStorage) Create(ctx api.Context, obj runtime.Object) (r func (storage *SimpleRESTStorage) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) { storage.checkContext(ctx) - storage.updated = obj.(*Simple) + storage.updated = obj.(*apiservertesting.Simple) if err := storage.errors["update"]; err != nil { return nil, false, err } @@ -476,10 +443,13 @@ func (storage *SimpleRESTStorage) ResourceLocation(ctx api.Context, id string) ( // Implement Connecter type ConnecterRESTStorage struct { - connectHandler rest.ConnectHandler + connectHandler http.Handler + handlerFunc func() http.Handler + emptyConnectOptions runtime.Object receivedConnectOptions runtime.Object receivedID string + receivedResponder rest.Responder takesPath string } @@ -487,12 +457,16 @@ type ConnecterRESTStorage struct { var _ = rest.Connecter(&ConnecterRESTStorage{}) func (s *ConnecterRESTStorage) New() runtime.Object { - return &Simple{} + return &apiservertesting.Simple{} } -func (s *ConnecterRESTStorage) Connect(ctx api.Context, id string, options runtime.Object) (rest.ConnectHandler, error) { +func (s *ConnecterRESTStorage) Connect(ctx api.Context, id string, options runtime.Object, responder rest.Responder) (http.Handler, error) { s.receivedConnectOptions = options s.receivedID = id + s.receivedResponder = responder + if s.handlerFunc != nil { + return s.handlerFunc(), nil + } return s.connectHandler, nil } @@ -533,7 +507,7 @@ type GetWithOptionsRESTStorage struct { } func (r *GetWithOptionsRESTStorage) Get(ctx api.Context, name string, options runtime.Object) (runtime.Object, error) { - if _, ok := options.(*SimpleGetOptions); !ok { + if _, ok := options.(*apiservertesting.SimpleGetOptions); !ok { return nil, fmt.Errorf("Unexpected options object: %#v", options) } r.optionsReceived = options @@ -542,9 +516,9 @@ func (r *GetWithOptionsRESTStorage) Get(ctx api.Context, name string, options ru func (r *GetWithOptionsRESTStorage) NewGetOptions() (runtime.Object, bool, string) { if len(r.takesPath) > 0 { - return &SimpleGetOptions{}, true, r.takesPath + return &apiservertesting.SimpleGetOptions{}, true, r.takesPath } - return &SimpleGetOptions{}, false, "" + return &apiservertesting.SimpleGetOptions{}, false, "" } var _ rest.GetterWithOptions = &GetWithOptionsRESTStorage{} @@ -556,7 +530,7 @@ type NamedCreaterRESTStorage struct { func (storage *NamedCreaterRESTStorage) Create(ctx api.Context, name string, obj runtime.Object) (runtime.Object, error) { storage.checkContext(ctx) - storage.created = obj.(*Simple) + storage.created = obj.(*apiservertesting.Simple) storage.createdName = name if err := storage.errors["create"]; err != nil { return nil, err @@ -666,7 +640,7 @@ func TestNotFound(t *testing.T) { type UnimplementedRESTStorage struct{} func (UnimplementedRESTStorage) New() runtime.Object { - return &Simple{} + return &apiservertesting.Simple{} } // TestUnimplementedRESTStorage ensures that if a rest.Storage does not implement a given @@ -903,7 +877,7 @@ func TestErrorList(t *testing.T) { func TestNonEmptyList(t *testing.T) { storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ - list: []Simple{ + list: []apiservertesting.Simple{ { ObjectMeta: api.ObjectMeta{Name: "something", Namespace: "other"}, Other: "foo", @@ -929,7 +903,7 @@ func TestNonEmptyList(t *testing.T) { t.Logf("Data: %s", string(body)) } - var listOut SimpleList + var listOut apiservertesting.SimpleList body, err := extractBody(resp, &listOut) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -954,7 +928,7 @@ func TestNonEmptyList(t *testing.T) { func TestSelfLinkSkipsEmptyName(t *testing.T) { storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ - list: []Simple{ + list: []apiservertesting.Simple{ { ObjectMeta: api.ObjectMeta{Namespace: "other"}, Other: "foo", @@ -979,7 +953,7 @@ func TestSelfLinkSkipsEmptyName(t *testing.T) { } t.Logf("Data: %s", string(body)) } - var listOut SimpleList + var listOut apiservertesting.SimpleList body, err := extractBody(resp, &listOut) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -1024,7 +998,7 @@ func TestMetadata(t *testing.T) { func TestGet(t *testing.T) { storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ - item: Simple{ + item: apiservertesting.Simple{ Other: "foo", }, } @@ -1046,7 +1020,7 @@ func TestGet(t *testing.T) { if resp.StatusCode != http.StatusOK { t.Fatalf("unexpected response: %#v", resp) } - var itemOut Simple + var itemOut apiservertesting.Simple body, err := extractBody(resp, &itemOut) if err != nil { t.Errorf("unexpected error: %v", err) @@ -1138,7 +1112,7 @@ func TestGetWithOptions(t *testing.T) { storage := map[string]rest.Storage{} simpleStorage := GetWithOptionsRESTStorage{ SimpleRESTStorage: &SimpleRESTStorage{ - item: Simple{ + item: apiservertesting.Simple{ Other: "foo", }, }, @@ -1155,7 +1129,7 @@ func TestGetWithOptions(t *testing.T) { if resp.StatusCode != http.StatusOK { t.Fatalf("unexpected response: %#v", resp) } - var itemOut Simple + var itemOut apiservertesting.Simple body, err := extractBody(resp, &itemOut) if err != nil { t.Errorf("unexpected error: %v", err) @@ -1165,7 +1139,7 @@ func TestGetWithOptions(t *testing.T) { t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body)) } - opts, ok := simpleStorage.optionsReceived.(*SimpleGetOptions) + opts, ok := simpleStorage.optionsReceived.(*apiservertesting.SimpleGetOptions) if !ok { t.Errorf("Unexpected options object received: %#v", simpleStorage.optionsReceived) return @@ -1179,7 +1153,7 @@ func TestGetWithOptionsAndPath(t *testing.T) { storage := map[string]rest.Storage{} simpleStorage := GetWithOptionsRESTStorage{ SimpleRESTStorage: &SimpleRESTStorage{ - item: Simple{ + item: apiservertesting.Simple{ Other: "foo", }, }, @@ -1197,7 +1171,7 @@ func TestGetWithOptionsAndPath(t *testing.T) { if resp.StatusCode != http.StatusOK { t.Fatalf("unexpected response: %#v", resp) } - var itemOut Simple + var itemOut apiservertesting.Simple body, err := extractBody(resp, &itemOut) if err != nil { t.Errorf("unexpected error: %v", err) @@ -1207,7 +1181,7 @@ func TestGetWithOptionsAndPath(t *testing.T) { t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body)) } - opts, ok := simpleStorage.optionsReceived.(*SimpleGetOptions) + opts, ok := simpleStorage.optionsReceived.(*apiservertesting.SimpleGetOptions) if !ok { t.Errorf("Unexpected options object received: %#v", simpleStorage.optionsReceived) return @@ -1219,7 +1193,7 @@ func TestGetWithOptionsAndPath(t *testing.T) { func TestGetAlternateSelfLink(t *testing.T) { storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ - item: Simple{ + item: apiservertesting.Simple{ Other: "foo", }, } @@ -1241,7 +1215,7 @@ func TestGetAlternateSelfLink(t *testing.T) { if resp.StatusCode != http.StatusOK { t.Fatalf("unexpected response: %#v", resp) } - var itemOut Simple + var itemOut apiservertesting.Simple body, err := extractBody(resp, &itemOut) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -1257,7 +1231,7 @@ func TestGetAlternateSelfLink(t *testing.T) { func TestGetNamespaceSelfLink(t *testing.T) { storage := map[string]rest.Storage{} simpleStorage := SimpleRESTStorage{ - item: Simple{ + item: apiservertesting.Simple{ Other: "foo", }, } @@ -1279,7 +1253,7 @@ func TestGetNamespaceSelfLink(t *testing.T) { if resp.StatusCode != http.StatusOK { t.Fatalf("unexpected response: %#v", resp) } - var itemOut Simple + var itemOut apiservertesting.Simple body, err := extractBody(resp, &itemOut) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -1315,7 +1289,7 @@ func TestConnect(t *testing.T) { responseText := "Hello World" itemID := "theID" connectStorage := &ConnecterRESTStorage{ - connectHandler: &SimpleConnectHandler{ + connectHandler: &OutputConnect{ response: responseText, }, } @@ -1348,10 +1322,93 @@ func TestConnect(t *testing.T) { } } +func TestConnectResponderObject(t *testing.T) { + itemID := "theID" + simple := &apiservertesting.Simple{Other: "foo"} + connectStorage := &ConnecterRESTStorage{} + connectStorage.handlerFunc = func() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + connectStorage.receivedResponder.Object(http.StatusCreated, simple) + }) + } + storage := map[string]rest.Storage{ + "simple": &SimpleRESTStorage{}, + "simple/connect": connectStorage, + } + handler := handle(storage) + server := httptest.NewServer(handler) + defer server.Close() + + resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect") + + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if resp.StatusCode != http.StatusCreated { + t.Errorf("unexpected response: %#v", resp) + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if connectStorage.receivedID != itemID { + t.Errorf("Unexpected item id. Expected: %s. Actual: %s.", itemID, connectStorage.receivedID) + } + obj, err := codec.Decode(body) + if err != nil { + t.Fatal(err) + } + if !api.Semantic.DeepEqual(obj, simple) { + t.Errorf("Unexpected response: %#v", obj) + } +} + +func TestConnectResponderError(t *testing.T) { + itemID := "theID" + connectStorage := &ConnecterRESTStorage{} + connectStorage.handlerFunc = func() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + connectStorage.receivedResponder.Error(apierrs.NewForbidden("simple", itemID, errors.New("you are terminated"))) + }) + } + storage := map[string]rest.Storage{ + "simple": &SimpleRESTStorage{}, + "simple/connect": connectStorage, + } + handler := handle(storage) + server := httptest.NewServer(handler) + defer server.Close() + + resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect") + + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if resp.StatusCode != http.StatusForbidden { + t.Errorf("unexpected response: %#v", resp) + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if connectStorage.receivedID != itemID { + t.Errorf("Unexpected item id. Expected: %s. Actual: %s.", itemID, connectStorage.receivedID) + } + obj, err := codec.Decode(body) + if err != nil { + t.Fatal(err) + } + if obj.(*unversioned.Status).Code != http.StatusForbidden { + t.Errorf("Unexpected response: %#v", obj) + } +} + func TestConnectWithOptionsRouteParams(t *testing.T) { connectStorage := &ConnecterRESTStorage{ - connectHandler: &SimpleConnectHandler{}, - emptyConnectOptions: &SimpleGetOptions{}, + connectHandler: &OutputConnect{}, + emptyConnectOptions: &apiservertesting.SimpleGetOptions{}, } storage := map[string]rest.Storage{ "simple": &SimpleRESTStorage{}, @@ -1379,10 +1436,10 @@ func TestConnectWithOptions(t *testing.T) { responseText := "Hello World" itemID := "theID" connectStorage := &ConnecterRESTStorage{ - connectHandler: &SimpleConnectHandler{ + connectHandler: &OutputConnect{ response: responseText, }, - emptyConnectOptions: &SimpleGetOptions{}, + emptyConnectOptions: &apiservertesting.SimpleGetOptions{}, } storage := map[string]rest.Storage{ "simple": &SimpleRESTStorage{}, @@ -1411,7 +1468,10 @@ func TestConnectWithOptions(t *testing.T) { if string(body) != responseText { t.Errorf("Unexpected response. Expected: %s. Actual: %s.", responseText, string(body)) } - opts, ok := connectStorage.receivedConnectOptions.(*SimpleGetOptions) + if connectStorage.receivedResponder == nil { + t.Errorf("Unexpected responder") + } + opts, ok := connectStorage.receivedConnectOptions.(*apiservertesting.SimpleGetOptions) if !ok { t.Errorf("Unexpected options type: %#v", connectStorage.receivedConnectOptions) } @@ -1425,10 +1485,10 @@ func TestConnectWithOptionsAndPath(t *testing.T) { itemID := "theID" testPath := "a/b/c/def" connectStorage := &ConnecterRESTStorage{ - connectHandler: &SimpleConnectHandler{ + connectHandler: &OutputConnect{ response: responseText, }, - emptyConnectOptions: &SimpleGetOptions{}, + emptyConnectOptions: &apiservertesting.SimpleGetOptions{}, takesPath: "atAPath", } storage := map[string]rest.Storage{ @@ -1458,7 +1518,7 @@ func TestConnectWithOptionsAndPath(t *testing.T) { if string(body) != responseText { t.Errorf("Unexpected response. Expected: %s. Actual: %s.", responseText, string(body)) } - opts, ok := connectStorage.receivedConnectOptions.(*SimpleGetOptions) + opts, ok := connectStorage.receivedConnectOptions.(*apiservertesting.SimpleGetOptions) if !ok { t.Errorf("Unexpected options type: %#v", connectStorage.receivedConnectOptions) } @@ -1638,7 +1698,7 @@ func TestDeleteMissing(t *testing.T) { func TestPatch(t *testing.T) { storage := map[string]rest.Storage{} ID := "id" - item := &Simple{ + item := &apiservertesting.Simple{ ObjectMeta: api.ObjectMeta{ Name: ID, Namespace: "", // update should allow the client to send an empty namespace @@ -1659,7 +1719,7 @@ func TestPatch(t *testing.T) { client := http.Client{} request, err := http.NewRequest("PATCH", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`))) - request.Header.Set("Content-Type", "application/merge-patch+json") + request.Header.Set("Content-Type", "application/merge-patch+json; charset=UTF-8") _, err = client.Do(request) if err != nil { t.Errorf("unexpected error: %v", err) @@ -1676,7 +1736,7 @@ func TestPatch(t *testing.T) { func TestPatchRequiresMatchingName(t *testing.T) { storage := map[string]rest.Storage{} ID := "id" - item := &Simple{ + item := &apiservertesting.Simple{ ObjectMeta: api.ObjectMeta{ Name: ID, Namespace: "", // update should allow the client to send an empty namespace @@ -1716,7 +1776,7 @@ func TestUpdate(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - item := &Simple{ + item := &apiservertesting.Simple{ ObjectMeta: api.ObjectMeta{ Name: ID, Namespace: "", // update should allow the client to send an empty namespace @@ -1753,7 +1813,7 @@ func TestUpdateInvokesAdmissionControl(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - item := &Simple{ + item := &apiservertesting.Simple{ ObjectMeta: api.ObjectMeta{ Name: ID, Namespace: api.NamespaceDefault, @@ -1786,7 +1846,7 @@ func TestUpdateRequiresMatchingName(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - item := &Simple{ + item := &apiservertesting.Simple{ Other: "bar", } body, err := codec.Encode(item) @@ -1815,7 +1875,7 @@ func TestUpdateAllowsMissingNamespace(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - item := &Simple{ + item := &apiservertesting.Simple{ ObjectMeta: api.ObjectMeta{ Name: ID, }, @@ -1852,7 +1912,7 @@ func TestUpdateAllowsMismatchedNamespaceOnError(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - item := &Simple{ + item := &apiservertesting.Simple{ ObjectMeta: api.ObjectMeta{ Name: ID, Namespace: "other", // does not match request @@ -1889,7 +1949,7 @@ func TestUpdatePreventsMismatchedNamespace(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - item := &Simple{ + item := &apiservertesting.Simple{ ObjectMeta: api.ObjectMeta{ Name: ID, Namespace: "other", @@ -1924,7 +1984,7 @@ func TestUpdateMissing(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - item := &Simple{ + item := &apiservertesting.Simple{ ObjectMeta: api.ObjectMeta{ Name: ID, Namespace: api.NamespaceDefault, @@ -1959,7 +2019,7 @@ func TestCreateNotFound(t *testing.T) { defer server.Close() client := http.Client{} - simple := &Simple{Other: "foo"} + simple := &apiservertesting.Simple{Other: "foo"} data, err := codec.Encode(simple) if err != nil { t.Errorf("unexpected error: %v", err) @@ -2009,20 +2069,100 @@ func TestCreateChecksDecode(t *testing.T) { } } +// TestUpdateREST tests that you can add new rest implementations to a pre-existing +// web service. +func TestUpdateREST(t *testing.T) { + makeGroup := func(storage map[string]rest.Storage) *APIGroupVersion { + return &APIGroupVersion{ + Storage: storage, + Root: "/api", + APIRequestInfoResolver: newTestAPIRequestInfoResolver(), + Creater: api.Scheme, + Convertor: api.Scheme, + Typer: api.Scheme, + Linker: selfLinker, + + Admit: admissionControl, + Context: requestContextMapper, + Mapper: namespaceMapper, + + Version: newVersion, + ServerVersion: newVersion, + Codec: newCodec, + } + } + + makeStorage := func(paths ...string) map[string]rest.Storage { + storage := map[string]rest.Storage{} + for _, s := range paths { + storage[s] = &SimpleRESTStorage{} + } + return storage + } + + testREST := func(t *testing.T, container *restful.Container, barCode int) { + w := httptest.NewRecorder() + container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/api/version2/namespaces/test/foo/test"}}) + if w.Code != http.StatusOK { + t.Fatalf("expected OK: %#v", w) + } + + w = httptest.NewRecorder() + container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/api/version2/namespaces/test/bar/test"}}) + if w.Code != barCode { + t.Errorf("expected response code %d for GET to bar but received %d", barCode, w.Code) + } + } + + storage1 := makeStorage("foo") + group1 := makeGroup(storage1) + + storage2 := makeStorage("bar") + group2 := makeGroup(storage2) + + container := restful.NewContainer() + + // install group1. Ensure that + // 1. Foo storage is accessible + // 2. Bar storage is not accessible + if err := group1.InstallREST(container); err != nil { + t.Fatal(err) + } + testREST(t, container, http.StatusNotFound) + + // update with group2. Ensure that + // 1. Foo storage is still accessible + // 2. Bar storage is now accessible + if err := group2.UpdateREST(container); err != nil { + t.Fatal(err) + } + testREST(t, container, http.StatusOK) + + // try to update a group that does not have an existing webservice with a matching prefix + // should not affect the existing registered webservice + invalidGroup := makeGroup(storage1) + invalidGroup.Root = "bad" + if err := invalidGroup.UpdateREST(container); err == nil { + t.Fatal("expected an error from UpdateREST when updating a non-existing prefix but got none") + } + testREST(t, container, http.StatusOK) +} + func TestParentResourceIsRequired(t *testing.T) { storage := &SimpleTypedStorage{ - baseType: &SimpleRoot{}, // a root scoped type - item: &SimpleRoot{}, + baseType: &apiservertesting.SimpleRoot{}, // a root scoped type + item: &apiservertesting.SimpleRoot{}, } group := &APIGroupVersion{ Storage: map[string]rest.Storage{ "simple/sub": storage, }, - Root: "/api", - Creater: api.Scheme, - Convertor: api.Scheme, - Typer: api.Scheme, - Linker: selfLinker, + Root: "/api", + APIRequestInfoResolver: newTestAPIRequestInfoResolver(), + Creater: api.Scheme, + Convertor: api.Scheme, + Typer: api.Scheme, + Linker: selfLinker, Admit: admissionControl, Context: requestContextMapper, @@ -2038,19 +2178,20 @@ func TestParentResourceIsRequired(t *testing.T) { } storage = &SimpleTypedStorage{ - baseType: &SimpleRoot{}, // a root scoped type - item: &SimpleRoot{}, + baseType: &apiservertesting.SimpleRoot{}, // a root scoped type + item: &apiservertesting.SimpleRoot{}, } group = &APIGroupVersion{ Storage: map[string]rest.Storage{ "simple": &SimpleRESTStorage{}, "simple/sub": storage, }, - Root: "/api", - Creater: api.Scheme, - Convertor: api.Scheme, - Typer: api.Scheme, - Linker: selfLinker, + Root: "/api", + APIRequestInfoResolver: newTestAPIRequestInfoResolver(), + Creater: api.Scheme, + Convertor: api.Scheme, + Typer: api.Scheme, + Linker: selfLinker, Admit: admissionControl, Context: requestContextMapper, @@ -2094,7 +2235,7 @@ func TestCreateWithName(t *testing.T) { defer server.Close() client := http.Client{} - simple := &Simple{Other: "foo"} + simple := &apiservertesting.Simple{Other: "foo"} data, err := codec.Encode(simple) if err != nil { t.Errorf("unexpected error: %v", err) @@ -2195,7 +2336,7 @@ func TestCreate(t *testing.T) { defer server.Close() client := http.Client{} - simple := &Simple{ + simple := &apiservertesting.Simple{ Other: "bar", } data, err := codec.Encode(simple) @@ -2219,7 +2360,7 @@ func TestCreate(t *testing.T) { t.Errorf("unexpected error: %v", err) } - var itemOut Simple + var itemOut apiservertesting.Simple body, err := extractBody(response, &itemOut) if err != nil { t.Errorf("unexpected error: %v", err) @@ -2254,7 +2395,7 @@ func TestCreateInNamespace(t *testing.T) { defer server.Close() client := http.Client{} - simple := &Simple{ + simple := &apiservertesting.Simple{ Other: "bar", } data, err := codec.Encode(simple) @@ -2278,7 +2419,7 @@ func TestCreateInNamespace(t *testing.T) { t.Errorf("unexpected error: %v", err) } - var itemOut Simple + var itemOut apiservertesting.Simple body, err := extractBody(response, &itemOut) if err != nil { t.Errorf("unexpected error: %v", err) @@ -2313,7 +2454,7 @@ func TestCreateInvokesAdmissionControl(t *testing.T) { defer server.Close() client := http.Client{} - simple := &Simple{ + simple := &apiservertesting.Simple{ Other: "bar", } data, err := codec.Encode(simple) @@ -2341,7 +2482,7 @@ func TestCreateInvokesAdmissionControl(t *testing.T) { } } -func expectApiStatus(t *testing.T, method, url string, data []byte, code int) *api.Status { +func expectApiStatus(t *testing.T, method, url string, data []byte, code int) *unversioned.Status { client := http.Client{} request, err := http.NewRequest(method, url, bytes.NewBuffer(data)) if err != nil { @@ -2353,10 +2494,9 @@ func expectApiStatus(t *testing.T, method, url string, data []byte, code int) *a t.Fatalf("unexpected error on %s %s: %v", method, url, err) return nil } - var status api.Status - _, err = extractBody(response, &status) - if err != nil { - t.Fatalf("unexpected error on %s %s: %v", method, url, err) + var status unversioned.Status + if body, err := extractBody(response, &status); err != nil { + t.Fatalf("unexpected error on %s %s: %v\nbody:\n%s", method, url, err, body) return nil } if code != response.StatusCode { @@ -2376,7 +2516,7 @@ func TestDelayReturnsError(t *testing.T) { defer server.Close() status := expectApiStatus(t, "DELETE", fmt.Sprintf("%s/api/version/namespaces/default/foo/bar", server.URL), nil, http.StatusConflict) - if status.Status != api.StatusFailure || status.Message == "" || status.Details == nil || status.Reason != api.StatusReasonAlreadyExists { + if status.Status != unversioned.StatusFailure || status.Message == "" || status.Details == nil || status.Reason != unversioned.StatusReasonAlreadyExists { t.Errorf("Unexpected status %#v", status) } } @@ -2392,8 +2532,11 @@ func TestWriteJSONDecodeError(t *testing.T) { writeJSON(http.StatusOK, codec, &UnregisteredAPIObject{"Undecodable"}, w, false) })) defer server.Close() - status := expectApiStatus(t, "GET", server.URL, nil, http.StatusInternalServerError) - if status.Reason != api.StatusReasonUnknown { + // We send a 200 status code before we encode the object, so we expect OK, but there will + // still be an error object. This seems ok, the alternative is to validate the object before + // encoding, but this really should never happen, so it's wasted compute for every API request. + status := expectApiStatus(t, "GET", server.URL, nil, http.StatusOK) + if status.Reason != unversioned.StatusReasonUnknown { t.Errorf("unexpected reason %#v", status) } if !strings.Contains(status.Message, "type apiserver.UnregisteredAPIObject is not registered") { @@ -2441,13 +2584,13 @@ func TestCreateTimeout(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - simple := &Simple{Other: "foo"} + simple := &apiservertesting.Simple{Other: "foo"} data, err := codec.Encode(simple) if err != nil { t.Errorf("unexpected error: %v", err) } itemOut := expectApiStatus(t, "POST", server.URL+"/api/version/namespaces/default/foo?timeout=4ms", data, apierrs.StatusServerTimeout) - if itemOut.Status != api.StatusFailure || itemOut.Reason != api.StatusReasonTimeout { + if itemOut.Status != unversioned.StatusFailure || itemOut.Reason != unversioned.StatusReasonTimeout { t.Errorf("Unexpected status %#v", itemOut) } } @@ -2532,7 +2675,7 @@ func TestCreateChecksAPIVersion(t *testing.T) { defer server.Close() client := http.Client{} - simple := &Simple{} + simple := &apiservertesting.Simple{} //using newCodec and send the request to testVersion URL shall cause a discrepancy in apiVersion data, err := newCodec.Encode(simple) if err != nil { @@ -2563,7 +2706,7 @@ func TestCreateDefaultsAPIVersion(t *testing.T) { defer server.Close() client := http.Client{} - simple := &Simple{} + simple := &apiservertesting.Simple{} data, err := codec.Encode(simple) if err != nil { t.Errorf("unexpected error: %v", err) @@ -2598,7 +2741,7 @@ func TestUpdateChecksAPIVersion(t *testing.T) { defer server.Close() client := http.Client{} - simple := &Simple{ObjectMeta: api.ObjectMeta{Name: "bar"}} + simple := &apiservertesting.Simple{ObjectMeta: api.ObjectMeta{Name: "bar"}} data, err := newCodec.Encode(simple) if err != nil { t.Errorf("unexpected error: %v", err) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/authz.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/authz.go index 8da50c33313b..b556b1013058 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/authz.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/authz.go @@ -19,6 +19,7 @@ package apiserver import ( "errors" "fmt" + "k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/auth/authorizer/abac" "k8s.io/kubernetes/pkg/auth/authorizer/union" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/errors.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/errors.go index 53f35179cb2b..a7c1fbdf328f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/errors.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/errors.go @@ -20,29 +20,29 @@ import ( "fmt" "net/http" - "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" "k8s.io/kubernetes/pkg/util" ) -// statusError is an object that can be converted into an api.Status +// statusError is an object that can be converted into an unversioned.Status type statusError interface { - Status() api.Status + Status() unversioned.Status } -// errToAPIStatus converts an error to an api.Status object. -func errToAPIStatus(err error) *api.Status { +// errToAPIStatus converts an error to an unversioned.Status object. +func errToAPIStatus(err error) *unversioned.Status { switch t := err.(type) { case statusError: status := t.Status() if len(status.Status) == 0 { - status.Status = api.StatusFailure + status.Status = unversioned.StatusFailure } if status.Code == 0 { switch status.Status { - case api.StatusSuccess: + case unversioned.StatusSuccess: status.Code = http.StatusOK - case api.StatusFailure: + case unversioned.StatusFailure: status.Code = http.StatusInternalServerError } } @@ -59,11 +59,11 @@ func errToAPIStatus(err error) *api.Status { // by REST storage - these typically indicate programmer // error by not using pkg/api/errors, or unexpected failure // cases. - util.HandleError(fmt.Errorf("apiserver received an error that is not an api.Status: %v", err)) - return &api.Status{ - Status: api.StatusFailure, + util.HandleError(fmt.Errorf("apiserver received an error that is not an unversioned.Status: %v", err)) + return &unversioned.Status{ + Status: unversioned.StatusFailure, Code: status, - Reason: api.StatusReasonUnknown, + Reason: unversioned.StatusReasonUnknown, Message: err.Error(), } } @@ -86,3 +86,22 @@ func forbidden(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusForbidden) fmt.Fprintf(w, "Forbidden: %#v", req.RequestURI) } + +// errAPIPrefixNotFound indicates that a APIRequestInfo resolution failed because the request isn't under +// any known API prefixes +type errAPIPrefixNotFound struct { + SpecifiedPrefix string +} + +func (e *errAPIPrefixNotFound) Error() string { + return fmt.Sprintf("no valid API prefix found matching %v", e.SpecifiedPrefix) +} + +func IsAPIPrefixNotFound(err error) bool { + if err == nil { + return false + } + + _, ok := err.(*errAPIPrefixNotFound) + return ok +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/errors_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/errors_test.go index b40a82e1cb1a..e5cdfae53ca9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/errors_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/errors_test.go @@ -22,38 +22,38 @@ import ( "reflect" "testing" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" ) func TestErrorsToAPIStatus(t *testing.T) { - cases := map[error]api.Status{ + cases := map[error]unversioned.Status{ errors.NewNotFound("foo", "bar"): { - Status: api.StatusFailure, + Status: unversioned.StatusFailure, Code: http.StatusNotFound, - Reason: api.StatusReasonNotFound, + Reason: unversioned.StatusReasonNotFound, Message: "foo \"bar\" not found", - Details: &api.StatusDetails{ + Details: &unversioned.StatusDetails{ Kind: "foo", Name: "bar", }, }, errors.NewAlreadyExists("foo", "bar"): { - Status: api.StatusFailure, + Status: unversioned.StatusFailure, Code: http.StatusConflict, Reason: "AlreadyExists", Message: "foo \"bar\" already exists", - Details: &api.StatusDetails{ + Details: &unversioned.StatusDetails{ Kind: "foo", Name: "bar", }, }, errors.NewConflict("foo", "bar", stderrs.New("failure")): { - Status: api.StatusFailure, + Status: unversioned.StatusFailure, Code: http.StatusConflict, Reason: "Conflict", Message: "foo \"bar\" cannot be updated: failure", - Details: &api.StatusDetails{ + Details: &unversioned.StatusDetails{ Kind: "foo", Name: "bar", }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/handlers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/handlers.go index df76fb8cb002..307ee582acba 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/handlers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/handlers.go @@ -31,10 +31,8 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" - "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/httplog" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" ) @@ -96,17 +94,6 @@ func MaxInFlightLimit(c chan bool, longRunningRequestRE *regexp.Regexp, handler }) } -// RateLimit uses rl to rate limit accepting requests to 'handler'. -func RateLimit(rl util.RateLimiter, handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - if rl.CanAccept() { - handler.ServeHTTP(w, req) - return - } - tooManyRequests(w) - }) -} - func tooManyRequests(w http.ResponseWriter) { // Return a 429 status indicating "Too Many Requests" w.Header().Set("Retry-After", RetryAfter) @@ -361,8 +348,8 @@ type requestAttributeGetter struct { } // NewAttributeGetter returns an object which implements the RequestAttributeGetter interface. -func NewRequestAttributeGetter(requestContextMapper api.RequestContextMapper, restMapper meta.RESTMapper, apiRoots ...string) RequestAttributeGetter { - return &requestAttributeGetter{requestContextMapper, &APIRequestInfoResolver{sets.NewString(apiRoots...), restMapper}} +func NewRequestAttributeGetter(requestContextMapper api.RequestContextMapper, apiRequestInfoResolver *APIRequestInfoResolver) RequestAttributeGetter { + return &requestAttributeGetter{requestContextMapper, apiRequestInfoResolver} } func (r *requestAttributeGetter) GetAttribs(req *http.Request) authorizer.Attributes { @@ -378,6 +365,7 @@ func (r *requestAttributeGetter) GetAttribs(req *http.Request) authorizer.Attrib apiRequestInfo, _ := r.apiRequestInfoResolver.GetAPIRequestInfo(req) + attribs.APIGroup = apiRequestInfo.APIGroup attribs.Verb = apiRequestInfo.Verb // If a path follows the conventions of the REST object store, then @@ -408,6 +396,8 @@ func WithAuthorizationCheck(handler http.Handler, getAttribs RequestAttributeGet type APIRequestInfo struct { // Verb is the kube verb associated with the request, not the http verb. This includes things like list and watch. Verb string + APIPrefix string + APIGroup string APIVersion string Namespace string // Resource is the name of the resource being requested. This is not the kind. For example: pods @@ -416,8 +406,6 @@ type APIRequestInfo struct { // For instance, /pods has the resource "pods" and the kind "Pod", while /pods/foo/status has the resource "pods", the sub resource "status", and the kind "Pod" // (because status operates on pods). The binding resource for a pod though may be /pods/foo/binding, which has resource "pods", subresource "binding", and kind "Binding". Subresource string - // Kind is the type of object being manipulated. For example: Pod - Kind string // Name is empty for some verbs, but if the request directly indicates a name (not in body content) then this field is filled in. Name string // Parts are the path parts for the request, always starting with /{resource}/{name} @@ -428,32 +416,29 @@ type APIRequestInfo struct { } type APIRequestInfoResolver struct { - APIPrefixes sets.String - RestMapper meta.RESTMapper + APIPrefixes sets.String + GrouplessAPIPrefixes sets.String } // TODO write an integration test against the swagger doc to test the APIRequestInfo and match up behavior to responses // GetAPIRequestInfo returns the information from the http request. If error is not nil, APIRequestInfo holds the information as best it is known before the failure // Valid Inputs: // Storage paths -// /namespaces -// /namespaces/{namespace} -// /namespaces/{namespace}/{resource} -// /namespaces/{namespace}/{resource}/{resourceName} -// /{resource} -// /{resource}/{resourceName} +// /apis/{api-group}/{version}/namespaces +// /api/{version}/namespaces +// /api/{version}/namespaces/{namespace} +// /api/{version}/namespaces/{namespace}/{resource} +// /api/{version}/namespaces/{namespace}/{resource}/{resourceName} +// /api/{version}/{resource} +// /api/{version}/{resource}/{resourceName} // // Special verbs: -// /proxy/{resource}/{resourceName} -// /proxy/namespaces/{namespace}/{resource}/{resourceName} -// /redirect/namespaces/{namespace}/{resource}/{resourceName} -// /redirect/{resource}/{resourceName} -// /watch/{resource} -// /watch/namespaces/{namespace}/{resource} -// -// Fully qualified paths for above: -// /api/{version}/* -// /api/{version}/* +// /api/{version}/proxy/{resource}/{resourceName} +// /api/{version}/proxy/namespaces/{namespace}/{resource}/{resourceName} +// /api/{version}/redirect/namespaces/{namespace}/{resource}/{resourceName} +// /api/{version}/redirect/{resource}/{resourceName} +// /api/{version}/watch/{resource} +// /api/{version}/watch/namespaces/{namespace}/{resource} func (r *APIRequestInfoResolver) GetAPIRequestInfo(req *http.Request) (APIRequestInfo, error) { requestInfo := APIRequestInfo{ Raw: splitPath(req.URL.Path), @@ -461,34 +446,38 @@ func (r *APIRequestInfoResolver) GetAPIRequestInfo(req *http.Request) (APIReques } currentParts := requestInfo.Raw - if len(currentParts) < 1 { - return requestInfo, fmt.Errorf("Unable to determine kind and namespace from an empty URL path") + if len(currentParts) < 3 { + return requestInfo, fmt.Errorf("a resource request must have a url with at least three parts, not %v", req.URL) } - for _, currPrefix := range r.APIPrefixes.List() { - // handle input of form /api/{version}/* by adjusting special paths - if currentParts[0] == currPrefix { - if len(currentParts) > 1 { - requestInfo.APIVersion = currentParts[1] - } + if !r.APIPrefixes.Has(currentParts[0]) { + return requestInfo, &errAPIPrefixNotFound{currentParts[0]} + } + requestInfo.APIPrefix = currentParts[0] + currentParts = currentParts[1:] - if len(currentParts) > 2 { - currentParts = currentParts[2:] - } else { - return requestInfo, fmt.Errorf("Unable to determine kind and namespace from url, %v", req.URL) - } + if !r.GrouplessAPIPrefixes.Has(requestInfo.APIPrefix) { + // one part (APIPrefix) has already been consumed, so this is actually "do we have four parts?" + if len(currentParts) < 3 { + return requestInfo, fmt.Errorf("a resource request with an API group must have a url with at least four parts, not %v", req.URL) } + + requestInfo.APIGroup = currentParts[0] + currentParts = currentParts[1:] } + requestInfo.APIVersion = currentParts[0] + currentParts = currentParts[1:] + // handle input of form /{specialVerb}/* if _, ok := specialVerbs[currentParts[0]]; ok { + if len(currentParts) < 2 { + return requestInfo, fmt.Errorf("unable to determine kind and namespace from url, %v", req.URL) + } + requestInfo.Verb = currentParts[0] + currentParts = currentParts[1:] - if len(currentParts) > 1 { - currentParts = currentParts[1:] - } else { - return requestInfo, fmt.Errorf("Unable to determine kind and namespace from url, %v", req.URL) - } } else { switch req.Method { case "POST": @@ -543,10 +532,5 @@ func (r *APIRequestInfoResolver) GetAPIRequestInfo(req *http.Request) (APIReques requestInfo.Verb = "list" } - // if we have a resource, we have a good shot at being able to determine kind - if len(requestInfo.Resource) > 0 { - _, requestInfo.Kind, _ = r.RestMapper.VersionAndKindForResource(requestInfo.Resource) - } - return requestInfo, nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/handlers_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/handlers_test.go index f62667a91b9d..029684e7dc79 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/handlers_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/handlers_test.go @@ -29,9 +29,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" - "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/util/sets" ) type fakeRL bool @@ -63,6 +61,9 @@ func TestMaxInFlight(t *testing.T) { const Iterations = 3 block := sync.WaitGroup{} block.Add(1) + oneFinished := sync.WaitGroup{} + oneFinished.Add(1) + var once sync.Once sem := make(chan bool, Iterations) re := regexp.MustCompile("[.*\\/watch][^\\/proxy.*]") @@ -87,6 +88,7 @@ func TestMaxInFlight(t *testing.T) { // These should hang waiting on block... go func() { expectHTTP(server.URL+"/foo/bar/watch", http.StatusOK, t) + once.Do(oneFinished.Done) }() } @@ -94,6 +96,7 @@ func TestMaxInFlight(t *testing.T) { // These should hang waiting on block... go func() { expectHTTP(server.URL+"/proxy/foo/bar", http.StatusOK, t) + once.Do(oneFinished.Done) }() } expectHTTP(server.URL+"/dontwait", http.StatusOK, t) @@ -102,6 +105,7 @@ func TestMaxInFlight(t *testing.T) { // These should hang waiting on block... go func() { expectHTTP(server.URL, http.StatusOK, t) + once.Do(oneFinished.Done) }() } calls.Wait() @@ -118,24 +122,11 @@ func TestMaxInFlight(t *testing.T) { block.Done() // Show that we recover from being blocked up. + // However, we should until at least one of the requests really finishes. + oneFinished.Wait() expectHTTP(server.URL, http.StatusOK, t) } -func TestRateLimit(t *testing.T) { - for _, allow := range []bool{true, false} { - rl := fakeRL(allow) - server := httptest.NewServer(RateLimit(rl, http.HandlerFunc( - func(w http.ResponseWriter, req *http.Request) { - if !allow { - t.Errorf("Unexpected call") - } - }, - ))) - defer server.Close() - http.Get(server.URL) - } -} - func TestReadOnly(t *testing.T) { server := httptest.NewServer(ReadOnly(http.HandlerFunc( func(w http.ResponseWriter, req *http.Request) { @@ -215,48 +206,49 @@ func TestGetAPIRequestInfo(t *testing.T) { method string url string expectedVerb string + expectedAPIPrefix string + expectedAPIGroup string expectedAPIVersion string expectedNamespace string expectedResource string expectedSubresource string - expectedKind string expectedName string expectedParts []string }{ // resource paths - {"GET", "/namespaces", "list", "", "", "namespaces", "", "Namespace", "", []string{"namespaces"}}, - {"GET", "/namespaces/other", "get", "", "other", "namespaces", "", "Namespace", "other", []string{"namespaces", "other"}}, + {"GET", "/api/v1/namespaces", "list", "api", "", "v1", "", "namespaces", "", "", []string{"namespaces"}}, + {"GET", "/api/v1/namespaces/other", "get", "api", "", "v1", "other", "namespaces", "", "other", []string{"namespaces", "other"}}, - {"GET", "/namespaces/other/pods", "list", "", "other", "pods", "", "Pod", "", []string{"pods"}}, - {"GET", "/namespaces/other/pods/foo", "get", "", "other", "pods", "", "Pod", "foo", []string{"pods", "foo"}}, - {"GET", "/pods", "list", "", api.NamespaceAll, "pods", "", "Pod", "", []string{"pods"}}, - {"GET", "/namespaces/other/pods/foo", "get", "", "other", "pods", "", "Pod", "foo", []string{"pods", "foo"}}, - {"GET", "/namespaces/other/pods", "list", "", "other", "pods", "", "Pod", "", []string{"pods"}}, + {"GET", "/api/v1/namespaces/other/pods", "list", "api", "", "v1", "other", "pods", "", "", []string{"pods"}}, + {"GET", "/api/v1/namespaces/other/pods/foo", "get", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}}, + {"GET", "/api/v1/pods", "list", "api", "", "v1", api.NamespaceAll, "pods", "", "", []string{"pods"}}, + {"GET", "/api/v1/namespaces/other/pods/foo", "get", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}}, + {"GET", "/api/v1/namespaces/other/pods", "list", "api", "", "v1", "other", "pods", "", "", []string{"pods"}}, // special verbs - {"GET", "/proxy/namespaces/other/pods/foo", "proxy", "", "other", "pods", "", "Pod", "foo", []string{"pods", "foo"}}, - {"GET", "/redirect/namespaces/other/pods/foo", "redirect", "", "other", "pods", "", "Pod", "foo", []string{"pods", "foo"}}, - {"GET", "/watch/pods", "watch", "", api.NamespaceAll, "pods", "", "Pod", "", []string{"pods"}}, - {"GET", "/watch/namespaces/other/pods", "watch", "", "other", "pods", "", "Pod", "", []string{"pods"}}, - - // fully-qualified paths - {"GET", getPath("pods", "other", ""), "list", testapi.Default.Version(), "other", "pods", "", "Pod", "", []string{"pods"}}, - {"GET", getPath("pods", "other", "foo"), "get", testapi.Default.Version(), "other", "pods", "", "Pod", "foo", []string{"pods", "foo"}}, - {"GET", getPath("pods", "", ""), "list", testapi.Default.Version(), api.NamespaceAll, "pods", "", "Pod", "", []string{"pods"}}, - {"POST", getPath("pods", "", ""), "create", testapi.Default.Version(), api.NamespaceAll, "pods", "", "Pod", "", []string{"pods"}}, - {"GET", getPath("pods", "", "foo"), "get", testapi.Default.Version(), api.NamespaceAll, "pods", "", "Pod", "foo", []string{"pods", "foo"}}, - {"GET", pathWithPrefix("proxy", "pods", "", "foo"), "proxy", testapi.Default.Version(), api.NamespaceAll, "pods", "", "Pod", "foo", []string{"pods", "foo"}}, - {"GET", pathWithPrefix("watch", "pods", "", ""), "watch", testapi.Default.Version(), api.NamespaceAll, "pods", "", "Pod", "", []string{"pods"}}, - {"GET", pathWithPrefix("redirect", "pods", "", ""), "redirect", testapi.Default.Version(), api.NamespaceAll, "pods", "", "Pod", "", []string{"pods"}}, - {"GET", pathWithPrefix("watch", "pods", "other", ""), "watch", testapi.Default.Version(), "other", "pods", "", "Pod", "", []string{"pods"}}, + {"GET", "/api/v1/proxy/namespaces/other/pods/foo", "proxy", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}}, + {"GET", "/api/v1/redirect/namespaces/other/pods/foo", "redirect", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}}, + {"GET", "/api/v1/watch/pods", "watch", "api", "", "v1", api.NamespaceAll, "pods", "", "", []string{"pods"}}, + {"GET", "/api/v1/watch/namespaces/other/pods", "watch", "api", "", "v1", "other", "pods", "", "", []string{"pods"}}, // subresource identification - {"GET", "/namespaces/other/pods/foo/status", "get", "", "other", "pods", "status", "Pod", "foo", []string{"pods", "foo", "status"}}, - {"PUT", "/namespaces/other/finalize", "update", "", "other", "finalize", "", "", "", []string{"finalize"}}, + {"GET", "/api/v1/namespaces/other/pods/foo/status", "get", "api", "", "v1", "other", "pods", "status", "foo", []string{"pods", "foo", "status"}}, + {"PUT", "/api/v1/namespaces/other/finalize", "update", "api", "", "v1", "other", "finalize", "", "", []string{"finalize"}}, + + // verb identification + {"PATCH", "/api/v1/namespaces/other/pods/foo", "patch", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}}, + {"DELETE", "/api/v1/namespaces/other/pods/foo", "delete", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}}, + {"POST", "/api/v1/namespaces/other/pods", "create", "api", "", "v1", "other", "pods", "", "", []string{"pods"}}, + + // api group identification + {"POST", "/apis/extensions/v1/namespaces/other/pods", "create", "api", "extensions", "v1", "other", "pods", "", "", []string{"pods"}}, + + // api version identification + {"POST", "/apis/extensions/v1beta3/namespaces/other/pods", "create", "api", "extensions", "v1beta3", "other", "pods", "", "", []string{"pods"}}, } - apiRequestInfoResolver := &APIRequestInfoResolver{sets.NewString("api"), latest.RESTMapper} + apiRequestInfoResolver := newTestAPIRequestInfoResolver() for _, successCase := range successCases { req, _ := http.NewRequest(successCase.method, successCase.url, nil) @@ -274,9 +266,6 @@ func TestGetAPIRequestInfo(t *testing.T) { if successCase.expectedNamespace != apiRequestInfo.Namespace { t.Errorf("Unexpected namespace for url: %s, expected: %s, actual: %s", successCase.url, successCase.expectedNamespace, apiRequestInfo.Namespace) } - if successCase.expectedKind != apiRequestInfo.Kind { - t.Errorf("Unexpected kind for url: %s, expected: %s, actual: %s", successCase.url, successCase.expectedKind, apiRequestInfo.Kind) - } if successCase.expectedResource != apiRequestInfo.Resource { t.Errorf("Unexpected resource for url: %s, expected: %s, actual: %s", successCase.url, successCase.expectedResource, apiRequestInfo.Resource) } @@ -294,7 +283,10 @@ func TestGetAPIRequestInfo(t *testing.T) { errorCases := map[string]string{ "no resource path": "/", "just apiversion": "/api/version/", + "just prefix, group, version": "/apis/group/version/", "apiversion with no resource": "/api/version/", + "bad prefix": "/badprefix/version/resource", + "missing api group": "/apis/version/resource", } for k, v := range errorCases { req, err := http.NewRequest("GET", v, nil) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/index.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/index.go index 480deb6e1ac2..c01174d75d19 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/index.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/index.go @@ -20,7 +20,7 @@ import ( "net/http" "sort" - "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "github.com/emicklei/go-restful" ) @@ -41,6 +41,6 @@ func IndexHandler(container *restful.Container, muxHelper *MuxHelper) func(http. // Extract the paths handled using mux handler. handledPaths = append(handledPaths, muxHelper.RegisteredPaths...) sort.Strings(handledPaths) - writeRawJSON(status, api.RootPaths{Paths: handledPaths}, w) + writeRawJSON(status, unversioned.RootPaths{Paths: handledPaths}, w) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/resthandler.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/resthandler.go index eff8ab9f3541..eeec11638407 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/resthandler.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/resthandler.go @@ -17,16 +17,19 @@ limitations under the License. package apiserver import ( + "encoding/json" "fmt" "net/http" "net/url" gpath "path" + "strings" "time" "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" @@ -81,6 +84,9 @@ type RequestScope struct { // may be used to deserialize an options object to pass to the getter. type getterFunc func(ctx api.Context, name string, req *restful.Request) (runtime.Object, error) +// MaxPatchConflicts is the maximum number of conflicts retry for during a patch operation before returning failure +const MaxPatchConflicts = 5 + // getResourceHandler is an HTTP handler function for get requests. It delegates to the // passed-in getterFunc to perform the actual get. func getResourceHandler(scope RequestScope, getter getterFunc) restful.RouteFunction { @@ -173,20 +179,30 @@ func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admissi return } } - handler, err := connecter.Connect(ctx, name, opts) + handler, err := connecter.Connect(ctx, name, opts, &responder{scope: scope, req: req.Request, w: w}) if err != nil { errorJSON(err, scope.Codec, w) return } handler.ServeHTTP(w, req.Request) - err = handler.RequestError() - if err != nil { - errorJSON(err, scope.Codec, w) - return - } } } +// responder implements rest.Responder for assisting a connector in writing objects or errors. +type responder struct { + scope RequestScope + req *http.Request + w http.ResponseWriter +} + +func (r *responder) Object(statusCode int, obj runtime.Object) { + write(statusCode, r.scope.APIVersion, r.scope.Codec, obj, r.w, r.req) +} + +func (r *responder) Error(err error) { + errorJSON(err, r.scope.Codec, r.w) +} + // ListResource returns a function that handles retrieving a list of resources from a rest.Storage object. func ListResource(r rest.Lister, rw rest.Watcher, scope RequestScope, forceWatch bool, minRequestTimeout time.Duration) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { @@ -321,7 +337,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object result, err := finishRequest(timeout, func() (runtime.Object, error) { out, err := r.Create(ctx, name, obj) - if status, ok := out.(*api.Status); ok && err == nil && status.Code == 0 { + if status, ok := out.(*unversioned.Status); ok && err == nil && status.Code == 0 { status.Code = http.StatusCreated } return out, err @@ -390,49 +406,26 @@ func PatchResource(r rest.Patcher, scope RequestScope, typer runtime.ObjectTyper } } - versionedObj, err := converter.ConvertToVersion(obj, scope.APIVersion) + versionedObj, err := converter.ConvertToVersion(r.New(), scope.APIVersion) if err != nil { errorJSON(err, scope.Codec, w) return } - original, err := r.Get(ctx, name) - if err != nil { - errorJSON(err, scope.Codec, w) - return + contentType := req.HeaderParameter("Content-Type") + // Remove "; charset=" if included in header. + if idx := strings.Index(contentType, ";"); idx > 0 { + contentType = contentType[:idx] } + patchType := api.PatchType(contentType) - originalObjJS, err := scope.Codec.Encode(original) - if err != nil { - errorJSON(err, scope.Codec, w) - return - } patchJS, err := readBody(req.Request) if err != nil { errorJSON(err, scope.Codec, w) return } - contentType := req.HeaderParameter("Content-Type") - patchedObjJS, err := getPatchedJS(contentType, originalObjJS, patchJS, versionedObj) - if err != nil { - errorJSON(err, scope.Codec, w) - return - } - if err := scope.Codec.DecodeInto(patchedObjJS, obj); err != nil { - errorJSON(err, scope.Codec, w) - return - } - if err := checkName(obj, name, namespace, scope.Namer); err != nil { - errorJSON(err, scope.Codec, w) - return - } - - result, err := finishRequest(timeout, func() (runtime.Object, error) { - // update should never create as previous get would fail - obj, _, err := r.Update(ctx, obj) - return obj, err - }) + result, err := patchResource(ctx, timeout, versionedObj, r, name, patchType, patchJS, scope.Namer, scope.Codec) if err != nil { errorJSON(err, scope.Codec, w) return @@ -445,6 +438,95 @@ func PatchResource(r rest.Patcher, scope RequestScope, typer runtime.ObjectTyper write(http.StatusOK, scope.APIVersion, scope.Codec, result, w, req.Request) } + +} + +// patchResource divides PatchResource for easier unit testing +func patchResource(ctx api.Context, timeout time.Duration, versionedObj runtime.Object, patcher rest.Patcher, name string, patchType api.PatchType, patchJS []byte, namer ScopeNamer, codec runtime.Codec) (runtime.Object, error) { + namespace := api.NamespaceValue(ctx) + + original, err := patcher.Get(ctx, name) + if err != nil { + return nil, err + } + + originalObjJS, err := codec.Encode(original) + if err != nil { + return nil, err + } + originalPatchedObjJS, err := getPatchedJS(patchType, originalObjJS, patchJS, versionedObj) + if err != nil { + return nil, err + } + + objToUpdate := patcher.New() + if err := codec.DecodeInto(originalPatchedObjJS, objToUpdate); err != nil { + return nil, err + } + if err := checkName(objToUpdate, name, namespace, namer); err != nil { + return nil, err + } + + return finishRequest(timeout, func() (runtime.Object, error) { + // update should never create as previous get would fail + updateObject, _, updateErr := patcher.Update(ctx, objToUpdate) + for i := 0; i < MaxPatchConflicts && (errors.IsConflict(updateErr)); i++ { + + // on a conflict, + // 1. build a strategic merge patch from originalJS and the patchedJS. Different patch types can + // be specified, but a strategic merge patch should be expressive enough handle them. Build the + // patch with this type to handle those cases. + // 2. build a strategic merge patch from originalJS and the currentJS + // 3. ensure no conflicts between the two patches + // 4. apply the #1 patch to the currentJS object + // 5. retry the update + currentObject, err := patcher.Get(ctx, name) + if err != nil { + return nil, err + } + currentObjectJS, err := codec.Encode(currentObject) + if err != nil { + return nil, err + } + + currentPatch, err := strategicpatch.CreateStrategicMergePatch(originalObjJS, currentObjectJS, patcher.New()) + if err != nil { + return nil, err + } + originalPatch, err := strategicpatch.CreateStrategicMergePatch(originalObjJS, originalPatchedObjJS, patcher.New()) + if err != nil { + return nil, err + } + + diff1 := make(map[string]interface{}) + if err := json.Unmarshal(originalPatch, &diff1); err != nil { + return nil, err + } + diff2 := make(map[string]interface{}) + if err := json.Unmarshal(currentPatch, &diff2); err != nil { + return nil, err + } + hasConflicts, err := strategicpatch.HasConflicts(diff1, diff2) + if err != nil { + return nil, err + } + if hasConflicts { + return updateObject, updateErr + } + + newlyPatchedObjJS, err := getPatchedJS(api.StrategicMergePatchType, currentObjectJS, originalPatch, versionedObj) + if err != nil { + return nil, err + } + if err := codec.DecodeInto(newlyPatchedObjJS, objToUpdate); err != nil { + return nil, err + } + + updateObject, _, updateErr = patcher.Update(ctx, objToUpdate) + } + + return updateObject, updateErr + }) } // UpdateResource returns a function that will handle a resource update @@ -567,17 +649,17 @@ func DeleteResource(r rest.GracefulDeleter, checkBody bool, scope RequestScope, // if the rest.Deleter returns a nil object, fill out a status. Callers may return a valid // object with the response. if result == nil { - result = &api.Status{ - Status: api.StatusSuccess, + result = &unversioned.Status{ + Status: unversioned.StatusSuccess, Code: http.StatusOK, - Details: &api.StatusDetails{ + Details: &unversioned.StatusDetails{ Name: name, Kind: scope.Kind, }, } } else { // when a non-status response is returned, set the self link - if _, ok := result.(*api.Status); !ok { + if _, ok := result.(*unversioned.Status); !ok { if err := setSelfLink(result, req, scope.Namer); err != nil { errorJSON(err, scope.Codec, w) return @@ -636,7 +718,7 @@ func finishRequest(timeout time.Duration, fn resultFunc) (result runtime.Object, select { case result = <-ch: - if status, ok := result.(*api.Status); ok { + if status, ok := result.(*unversioned.Status); ok { return nil, errors.FromObject(status) } return result, nil @@ -734,8 +816,7 @@ func setListSelfLink(obj runtime.Object, req *restful.Request, namer ScopeNamer) } -func getPatchedJS(contentType string, originalJS, patchJS []byte, obj runtime.Object) ([]byte, error) { - patchType := api.PatchType(contentType) +func getPatchedJS(patchType api.PatchType, originalJS, patchJS []byte, obj runtime.Object) ([]byte, error) { switch patchType { case api.JSONPatchType: patchObj, err := jsonpatch.DecodePatch(patchJS) @@ -749,6 +830,6 @@ func getPatchedJS(contentType string, originalJS, patchJS []byte, obj runtime.Ob return strategicpatch.StrategicMergePatchData(originalJS, patchJS, obj) default: // only here as a safety net - go-restful filters content-type - return nil, fmt.Errorf("unknown Content-Type header for patch: %s", contentType) + return nil, fmt.Errorf("unknown Content-Type header for patch: %v", patchType) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/resthandler_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/resthandler_test.go index 8923fecdfcf7..18fdddd933a0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/resthandler_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/resthandler_test.go @@ -17,13 +17,26 @@ limitations under the License. package apiserver import ( + "errors" + "fmt" + "reflect" "testing" + "time" + + "github.com/emicklei/go-restful" + "github.com/evanphx/json-patch" "k8s.io/kubernetes/pkg/api" + apierrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/strategicpatch" ) type testPatchType struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` testPatchSubType `json:",inline"` } @@ -39,12 +52,280 @@ func TestPatchAnonymousField(t *testing.T) { patch := `{"theField": "changed!"}` expectedJS := `{"kind":"testPatchType","theField":"changed!"}` - actualBytes, err := getPatchedJS(string(api.StrategicMergePatchType), []byte(originalJS), []byte(patch), &testPatchType{}) + actualBytes, err := getPatchedJS(api.StrategicMergePatchType, []byte(originalJS), []byte(patch), &testPatchType{}) if err != nil { t.Fatalf("unexpected error: %v", err) } if string(actualBytes) != expectedJS { t.Errorf("expected %v, got %v", expectedJS, string(actualBytes)) } +} + +type testPatcher struct { + // startingPod is used for the first Get + startingPod *api.Pod + + // updatePod is the pod that is used for conflict comparison and returned for the SECOND Get + updatePod *api.Pod + + numGets int +} + +func (p *testPatcher) New() runtime.Object { + return &api.Pod{} +} + +func (p *testPatcher) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) { + inPod := obj.(*api.Pod) + if inPod.ResourceVersion != p.updatePod.ResourceVersion { + return nil, false, apierrors.NewConflict("Pod", inPod.Name, fmt.Errorf("existing %v, new %v", p.updatePod.ResourceVersion, inPod.ResourceVersion)) + } + + return inPod, false, nil +} + +func (p *testPatcher) Get(ctx api.Context, name string) (runtime.Object, error) { + if p.numGets > 0 { + return p.updatePod, nil + } + p.numGets++ + + return p.startingPod, nil +} + +type testNamer struct { + namespace string + name string +} + +func (p *testNamer) Namespace(req *restful.Request) (namespace string, err error) { + return p.namespace, nil +} + +// Name returns the name from the request, and an optional namespace value if this is a namespace +// scoped call. An error is returned if the name is not available. +func (p *testNamer) Name(req *restful.Request) (namespace, name string, err error) { + return p.namespace, p.name, nil +} + +// ObjectName returns the namespace and name from an object if they exist, or an error if the object +// does not support names. +func (p *testNamer) ObjectName(obj runtime.Object) (namespace, name string, err error) { + return p.namespace, p.name, nil +} + +// SetSelfLink sets the provided URL onto the object. The method should return nil if the object +// does not support selfLinks. +func (p *testNamer) SetSelfLink(obj runtime.Object, url string) error { + return errors.New("not implemented") +} + +// GenerateLink creates a path and query for a given runtime object that represents the canonical path. +func (p *testNamer) GenerateLink(req *restful.Request, obj runtime.Object) (path, query string, err error) { + return "", "", errors.New("not implemented") +} + +// GenerateLink creates a path and query for a list that represents the canonical path. +func (p *testNamer) GenerateListLink(req *restful.Request) (path, query string, err error) { + return "", "", errors.New("not implemented") +} + +type patchTestCase struct { + name string + + // startingPod is used for the first Get + startingPod *api.Pod + // changedPod is the "destination" pod for the patch. The test will create a patch from the startingPod to the changedPod + // to use when calling the patch operation + changedPod *api.Pod + // updatePod is the pod that is used for conflict comparison and returned for the SECOND Get + updatePod *api.Pod + + // expectedPod is the pod that you expect to get back after the patch is complete + expectedPod *api.Pod + expectedError string +} + +func (tc *patchTestCase) Run(t *testing.T) { + t.Logf("Starting test %s", tc.name) + + namespace := tc.startingPod.Namespace + name := tc.startingPod.Name + + codec := latest.GroupOrDie("").Codec + + testPatcher := &testPatcher{} + testPatcher.startingPod = tc.startingPod + testPatcher.updatePod = tc.updatePod + + ctx := api.NewDefaultContext() + ctx = api.WithNamespace(ctx, namespace) + + namer := &testNamer{namespace, name} + + versionedObj, err := api.Scheme.ConvertToVersion(&api.Pod{}, "v1") + if err != nil { + t.Errorf("%s: unexpected error: %v", tc.name, err) + return + } + + for _, patchType := range []api.PatchType{api.JSONPatchType, api.MergePatchType, api.StrategicMergePatchType} { + // TODO SUPPORT THIS! + if patchType == api.JSONPatchType { + continue + } + t.Logf("Working with patchType %v", patchType) + + originalObjJS, err := codec.Encode(tc.startingPod) + if err != nil { + t.Errorf("%s: unexpected error: %v", tc.name, err) + return + } + changedJS, err := codec.Encode(tc.changedPod) + if err != nil { + t.Errorf("%s: unexpected error: %v", tc.name, err) + return + } + + patch := []byte{} + switch patchType { + case api.JSONPatchType: + continue + + case api.StrategicMergePatchType: + patch, err = strategicpatch.CreateStrategicMergePatch(originalObjJS, changedJS, &api.Pod{}) + if err != nil { + t.Errorf("%s: unexpected error: %v", tc.name, err) + return + } + + case api.MergePatchType: + patch, err = jsonpatch.CreateMergePatch(originalObjJS, changedJS) + if err != nil { + t.Errorf("%s: unexpected error: %v", tc.name, err) + return + } + + } + + resultObj, err := patchResource(ctx, 1*time.Second, versionedObj, testPatcher, name, patchType, patch, namer, codec) + if len(tc.expectedError) != 0 { + if err == nil || err.Error() != tc.expectedError { + t.Errorf("%s: expected error %v, but got %v", tc.name, tc.expectedError, err) + return + } + } else { + if err != nil { + t.Errorf("%s: unexpected error: %v", tc.name, err) + return + } + } + + if tc.expectedPod == nil { + if resultObj != nil { + t.Errorf("%s: unexpected result: %v", tc.name, resultObj) + } + return + } + + resultPod := resultObj.(*api.Pod) + + // roundtrip to get defaulting + expectedJS, err := codec.Encode(tc.expectedPod) + if err != nil { + t.Errorf("%s: unexpected error: %v", tc.name, err) + return + } + expectedObj, err := codec.Decode(expectedJS) + if err != nil { + t.Errorf("%s: unexpected error: %v", tc.name, err) + return + } + reallyExpectedPod := expectedObj.(*api.Pod) + + if !reflect.DeepEqual(*reallyExpectedPod, *resultPod) { + t.Errorf("%s mismatch: %v\n", tc.name, util.ObjectGoPrintDiff(reallyExpectedPod, resultPod)) + return + } + } + +} + +func TestPatchResourceWithVersionConflict(t *testing.T) { + namespace := "bar" + name := "foo" + fifteen := int64(15) + thirty := int64(30) + + tc := &patchTestCase{ + name: "TestPatchResourceWithVersionConflict", + + startingPod: &api.Pod{}, + changedPod: &api.Pod{}, + updatePod: &api.Pod{}, + + expectedPod: &api.Pod{}, + } + + tc.startingPod.Name = name + tc.startingPod.Namespace = namespace + tc.startingPod.ResourceVersion = "1" + tc.startingPod.APIVersion = "v1" + tc.startingPod.Spec.ActiveDeadlineSeconds = &fifteen + + tc.changedPod.Name = name + tc.changedPod.Namespace = namespace + tc.changedPod.ResourceVersion = "1" + tc.changedPod.APIVersion = "v1" + tc.changedPod.Spec.ActiveDeadlineSeconds = &thirty + + tc.updatePod.Name = name + tc.updatePod.Namespace = namespace + tc.updatePod.ResourceVersion = "2" + tc.updatePod.APIVersion = "v1" + tc.updatePod.Spec.ActiveDeadlineSeconds = &fifteen + tc.updatePod.Spec.NodeName = "anywhere" + + tc.expectedPod.Name = name + tc.expectedPod.Namespace = namespace + tc.expectedPod.ResourceVersion = "2" + tc.expectedPod.Spec.ActiveDeadlineSeconds = &thirty + tc.expectedPod.Spec.NodeName = "anywhere" + + tc.Run(t) +} + +func TestPatchResourceWithConflict(t *testing.T) { + namespace := "bar" + name := "foo" + + tc := &patchTestCase{ + name: "TestPatchResourceWithConflict", + + startingPod: &api.Pod{}, + changedPod: &api.Pod{}, + updatePod: &api.Pod{}, + + expectedError: `Pod "foo" cannot be updated: existing 2, new 1`, + } + + tc.startingPod.Name = name + tc.startingPod.Namespace = namespace + tc.startingPod.ResourceVersion = "1" + tc.startingPod.APIVersion = "v1" + tc.startingPod.Spec.NodeName = "here" + + tc.changedPod.Name = name + tc.changedPod.Namespace = namespace + tc.changedPod.ResourceVersion = "1" + tc.changedPod.APIVersion = "v1" + tc.changedPod.Spec.NodeName = "there" + + tc.updatePod.Name = name + tc.updatePod.Namespace = namespace + tc.updatePod.ResourceVersion = "2" + tc.updatePod.APIVersion = "v1" + tc.updatePod.Spec.NodeName = "anywhere" + tc.Run(t) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/testing/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/testing/types.go new file mode 100644 index 000000000000..8f0f6bac7fef --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/testing/types.go @@ -0,0 +1,64 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 testing + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" +) + +type Simple struct { + unversioned.TypeMeta `json:",inline"` + api.ObjectMeta `json:"metadata"` + Other string `json:"other,omitempty"` + Labels map[string]string `json:"labels,omitempty"` +} + +func (*Simple) IsAnAPIObject() {} + +type SimpleRoot struct { + unversioned.TypeMeta `json:",inline"` + api.ObjectMeta `json:"metadata"` + Other string `json:"other,omitempty"` + Labels map[string]string `json:"labels,omitempty"` +} + +func (*SimpleRoot) IsAnAPIObject() {} + +type SimpleGetOptions struct { + unversioned.TypeMeta `json:",inline"` + Param1 string `json:"param1"` + Param2 string `json:"param2"` + Path string `json:"atAPath"` +} + +func (SimpleGetOptions) SwaggerDoc() map[string]string { + return map[string]string{ + "param1": "description for param1", + "param2": "description for param2", + } +} + +func (*SimpleGetOptions) IsAnAPIObject() {} + +type SimpleList struct { + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,inline"` + Items []Simple `json:"items,omitempty"` +} + +func (*SimpleList) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/validator.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/validator.go index a3916da68675..b9860a4b1095 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/validator.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/validator.go @@ -23,9 +23,9 @@ import ( "net" "net/http" "strconv" - "time" "k8s.io/kubernetes/pkg/probe" + "k8s.io/kubernetes/pkg/util" ) // TODO: this basic interface is duplicated in N places. consolidate? @@ -59,15 +59,9 @@ func (server *Server) DoServerCheck(rt http.RoundTripper) (probe.Result, string, // TODO(roberthbailey): The servers that use HTTPS are currently the // kubelets, and we should be using a standard kubelet client library // to talk to them rather than a separate http client. - transport := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - Dial: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - TLSHandshakeTimeout: 10 * time.Second, - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - } + transport := util.SetTransportDefaults(&http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }) client = &http.Client{Transport: transport} scheme = "https://" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/watch_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/watch_test.go index 74e799f4c3cc..6553424bf4a1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/watch_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/watch_test.go @@ -29,9 +29,12 @@ import ( "golang.org/x/net/websocket" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" + apiservertesting "k8s.io/kubernetes/pkg/apiserver/testing" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/watch" ) @@ -45,9 +48,9 @@ var watchTestTable = []struct { t watch.EventType obj runtime.Object }{ - {watch.Added, &Simple{ObjectMeta: api.ObjectMeta{Name: "foo"}}}, - {watch.Modified, &Simple{ObjectMeta: api.ObjectMeta{Name: "bar"}}}, - {watch.Deleted, &Simple{ObjectMeta: api.ObjectMeta{Name: "bar"}}}, + {watch.Added, &apiservertesting.Simple{ObjectMeta: api.ObjectMeta{Name: "foo"}}}, + {watch.Modified, &apiservertesting.Simple{ObjectMeta: api.ObjectMeta{Name: "bar"}}}, + {watch.Deleted, &apiservertesting.Simple{ObjectMeta: api.ObjectMeta{Name: "bar"}}}, } func TestWatchWebsocket(t *testing.T) { @@ -361,7 +364,7 @@ func TestWatchHTTPTimeout(t *testing.T) { req, _ := http.NewRequest("GET", dest.String(), nil) client := http.Client{} resp, err := client.Do(req) - watcher.Add(&Simple{TypeMeta: api.TypeMeta{APIVersion: newVersion}}) + watcher.Add(&apiservertesting.Simple{TypeMeta: unversioned.TypeMeta{APIVersion: newVersion}}) // Make sure we can actually watch an endpoint decoder := json.NewDecoder(resp.Body) @@ -378,8 +381,8 @@ func TestWatchHTTPTimeout(t *testing.T) { if !watcher.Stopped { t.Errorf("Leaked watch on timeout") } - case <-time.After(100 * time.Millisecond): - t.Errorf("Failed to stop watcher after 100ms of timeout signal") + case <-time.After(util.ForeverTestTimeout): + t.Errorf("Failed to stop watcher after %s of timeout signal", util.ForeverTestTimeout.String()) } // Make sure we can't receive any more events through the timeout watch diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/auth/authorizer/abac/abac.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/auth/authorizer/abac/abac.go index cbc2c5901853..4c4b9e6bd2c2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/auth/authorizer/abac/abac.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/auth/authorizer/abac/abac.go @@ -44,7 +44,7 @@ type policy struct { // providers are in use. Either add "Realm", or assume "user@example.com" // format. - // TODO: Make the "cluster" Kinds be one API group (minions, bindings, + // TODO: Make the "cluster" Kinds be one API group (nodes, bindings, // events, endpoints). The "user" Kinds are another (pods, services, // replicationControllers, operations) Make a "plugin", e.g. build // controller, be another group. That way when we add a new object to a diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/auth/authorizer/interfaces.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/auth/authorizer/interfaces.go index 6d318d1a2b98..eadda02bf283 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/auth/authorizer/interfaces.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/auth/authorizer/interfaces.go @@ -47,6 +47,9 @@ type Attributes interface { // The kind of object, if a request is for a REST object. GetResource() string + + // The group of the resource, if a request is for a REST object. + GetAPIGroup() string } // Authorizer makes an authorization decision based on information gained by making @@ -72,6 +75,7 @@ type AttributesRecord struct { User user.Info Verb string Namespace string + APIGroup string Resource string } @@ -98,3 +102,7 @@ func (a AttributesRecord) GetNamespace() string { func (a AttributesRecord) GetResource() string { return a.Resource } + +func (a AttributesRecord) GetAPIGroup() string { + return a.APIGroup +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/doc.go index c6a2857ddec7..16600cf24238 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/doc.go @@ -18,7 +18,7 @@ limitations under the License. // reducing the number of server calls you'd otherwise need to make. // Reflector watches a server and updates a Store. Two stores are provided; // one that simply caches objects (for example, to allow a scheduler to -// list currently available minions), and one that additionally acts as +// list currently available nodes), and one that additionally acts as // a FIFO queue (for example, to allow a scheduler to process incoming // pods). package cache diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go index e6d67c14274e..0881bd0f0627 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go @@ -17,9 +17,10 @@ limitations under the License. package cache import ( + "time" + "github.com/golang/glog" "k8s.io/kubernetes/pkg/util" - "time" ) // ExpirationCache implements the store interface @@ -73,7 +74,7 @@ func (c *ExpirationCache) getTimestampedEntry(key string) (*timestampedEntry, bo return nil, false } -// getOrExpire retrieves the object from the timestampedEntry iff it hasn't +// getOrExpire retrieves the object from the timestampedEntry if and only if it hasn't // already expired. It kicks-off a go routine to delete expired objects from // the store and sets exists=false. func (c *ExpirationCache) getOrExpire(key string) (interface{}, bool) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache_test.go index 375ffcceaa3d..546b98d919f8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache_test.go @@ -55,7 +55,7 @@ func TestTTLExpirationBasic(t *testing.T) { if delKey != key { t.Errorf("Unexpected delete for key %s", key) } - case <-time.After(time.Millisecond * 100): + case <-time.After(util.ForeverTestTimeout): t.Errorf("Unexpected timeout waiting on delete") } close(deleteChan) @@ -100,7 +100,7 @@ func TestTTLList(t *testing.T) { t.Errorf("Unexpected delete for key %s", delKey) } expireKeys.Delete(delKey) - case <-time.After(time.Millisecond * 100): + case <-time.After(util.ForeverTestTimeout): t.Errorf("Unexpected timeout waiting on delete") return } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers.go index 0bb917f69a1e..060e74e7f787 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers.go @@ -21,7 +21,7 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/labels" ) @@ -158,19 +158,19 @@ func (s storeToNodeConditionLister) List() (nodes api.NodeList, err error) { // TODO Move this back to scheduler as a helper function that takes a Store, // rather than a method of StoreToNodeLister. -// GetNodeInfo returns cached data for the minion 'id'. +// GetNodeInfo returns cached data for the node 'id'. func (s *StoreToNodeLister) GetNodeInfo(id string) (*api.Node, error) { - minion, exists, err := s.Get(&api.Node{ObjectMeta: api.ObjectMeta{Name: id}}) + node, exists, err := s.Get(&api.Node{ObjectMeta: api.ObjectMeta{Name: id}}) if err != nil { - return nil, fmt.Errorf("error retrieving minion '%v' from cache: %v", id, err) + return nil, fmt.Errorf("error retrieving node '%v' from cache: %v", id, err) } if !exists { - return nil, fmt.Errorf("minion '%v' is not in cache", id) + return nil, fmt.Errorf("node '%v' is not in cache", id) } - return minion.(*api.Node), nil + return node.(*api.Node), nil } // StoreToReplicationControllerLister gives a store List and Exists methods. The store must contain only ReplicationControllers. @@ -232,7 +232,7 @@ type StoreToDaemonSetLister struct { } // Exists checks if the given daemon set exists in the store. -func (s *StoreToDaemonSetLister) Exists(ds *experimental.DaemonSet) (bool, error) { +func (s *StoreToDaemonSetLister) Exists(ds *extensions.DaemonSet) (bool, error) { _, exists, err := s.Store.Get(ds) if err != nil { return false, err @@ -242,17 +242,18 @@ func (s *StoreToDaemonSetLister) Exists(ds *experimental.DaemonSet) (bool, error // List lists all daemon sets in the store. // TODO: converge on the interface in pkg/client -func (s *StoreToDaemonSetLister) List() (dss []experimental.DaemonSet, err error) { +func (s *StoreToDaemonSetLister) List() (dss []extensions.DaemonSet, err error) { for _, c := range s.Store.List() { - dss = append(dss, *(c.(*experimental.DaemonSet))) + dss = append(dss, *(c.(*extensions.DaemonSet))) } return dss, nil } -// GetPodDaemonSets returns a list of daemon sets managing a pod. Returns an error iff no matching daemon sets are found. -func (s *StoreToDaemonSetLister) GetPodDaemonSets(pod *api.Pod) (daemonSets []experimental.DaemonSet, err error) { +// GetPodDaemonSets returns a list of daemon sets managing a pod. +// Returns an error if and only if no matching daemon sets are found. +func (s *StoreToDaemonSetLister) GetPodDaemonSets(pod *api.Pod) (daemonSets []extensions.DaemonSet, err error) { var selector labels.Selector - var daemonSet experimental.DaemonSet + var daemonSet extensions.DaemonSet if len(pod.Labels) == 0 { err = fmt.Errorf("No daemon sets found for pod %v because it has no labels", pod.Name) @@ -260,7 +261,7 @@ func (s *StoreToDaemonSetLister) GetPodDaemonSets(pod *api.Pod) (daemonSets []ex } for _, m := range s.Store.List() { - daemonSet = *m.(*experimental.DaemonSet) + daemonSet = *m.(*extensions.DaemonSet) if daemonSet.Namespace != pod.Namespace { continue } @@ -343,3 +344,55 @@ func (s *StoreToEndpointsLister) GetServiceEndpoints(svc *api.Service) (ep api.E err = fmt.Errorf("Could not find endpoints for service: %v", svc.Name) return } + +// StoreToJobLister gives a store List and Exists methods. The store must contain only Jobs. +type StoreToJobLister struct { + Store +} + +// Exists checks if the given job exists in the store. +func (s *StoreToJobLister) Exists(job *extensions.Job) (bool, error) { + _, exists, err := s.Store.Get(job) + if err != nil { + return false, err + } + return exists, nil +} + +// StoreToJobLister lists all jobs in the store. +func (s *StoreToJobLister) List() (jobs []extensions.Job, err error) { + for _, c := range s.Store.List() { + jobs = append(jobs, *(c.(*extensions.Job))) + } + return jobs, nil +} + +// GetPodControllers returns a list of jobs managing a pod. Returns an error only if no matching jobs are found. +func (s *StoreToJobLister) GetPodJobs(pod *api.Pod) (jobs []extensions.Job, err error) { + var selector labels.Selector + var job extensions.Job + + if len(pod.Labels) == 0 { + err = fmt.Errorf("No jobs found for pod %v because it has no labels", pod.Name) + return + } + + for _, m := range s.Store.List() { + job = *m.(*extensions.Job) + if job.Namespace != pod.Namespace { + continue + } + labelSet := labels.Set(job.Spec.Selector) + selector = labels.Set(job.Spec.Selector).AsSelector() + + // Job with a nil or empty selector match nothing + if labelSet.AsSelector().Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + jobs = append(jobs, job) + } + if len(jobs) == 0 { + err = fmt.Errorf("Could not find jobs for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + return +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers_test.go index 79098254a9ee..43f82aab6c06 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers_test.go @@ -20,12 +20,12 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/util/sets" ) -func TestStoreToMinionLister(t *testing.T) { +func TestStoreToNodeLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) ids := sets.NewString("foo", "bar", "baz") for id := range ids { @@ -160,44 +160,44 @@ func TestStoreToDaemonSetLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) lister := StoreToDaemonSetLister{store} testCases := []struct { - inDSs []*experimental.DaemonSet - list func() ([]experimental.DaemonSet, error) + inDSs []*extensions.DaemonSet + list func() ([]extensions.DaemonSet, error) outDaemonSetNames sets.String expectErr bool }{ // Basic listing { - inDSs: []*experimental.DaemonSet{ + inDSs: []*extensions.DaemonSet{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, }, - list: func() ([]experimental.DaemonSet, error) { + list: func() ([]extensions.DaemonSet, error) { return lister.List() }, outDaemonSetNames: sets.NewString("basic"), }, // Listing multiple daemon sets { - inDSs: []*experimental.DaemonSet{ + inDSs: []*extensions.DaemonSet{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, {ObjectMeta: api.ObjectMeta{Name: "complex"}}, {ObjectMeta: api.ObjectMeta{Name: "complex2"}}, }, - list: func() ([]experimental.DaemonSet, error) { + list: func() ([]extensions.DaemonSet, error) { return lister.List() }, outDaemonSetNames: sets.NewString("basic", "complex", "complex2"), }, // No pod labels { - inDSs: []*experimental.DaemonSet{ + inDSs: []*extensions.DaemonSet{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: map[string]string{"foo": "baz"}, }, }, }, - list: func() ([]experimental.DaemonSet, error) { + list: func() ([]extensions.DaemonSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"}, } @@ -208,12 +208,12 @@ func TestStoreToDaemonSetLister(t *testing.T) { }, // No DS selectors { - inDSs: []*experimental.DaemonSet{ + inDSs: []*extensions.DaemonSet{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, - list: func() ([]experimental.DaemonSet, error) { + list: func() ([]extensions.DaemonSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", @@ -228,21 +228,21 @@ func TestStoreToDaemonSetLister(t *testing.T) { }, // Matching labels to selectors and namespace { - inDSs: []*experimental.DaemonSet{ + inDSs: []*extensions.DaemonSet{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: map[string]string{"foo": "bar"}, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: map[string]string{"foo": "bar"}, }, }, }, - list: func() ([]experimental.DaemonSet, error) { + list: func() ([]extensions.DaemonSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listwatch_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listwatch_test.go index 33f45db26e7b..db34c48ebbad 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listwatch_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listwatch_test.go @@ -23,6 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/util" @@ -54,17 +55,17 @@ func buildLocation(resourcePath string, query url.Values) string { } func TestListWatchesCanList(t *testing.T) { - fieldSelectorQueryParamName := api.FieldSelectorQueryParam(testapi.Default.Version()) + fieldSelectorQueryParamName := unversioned.FieldSelectorQueryParam(testapi.Default.Version()) table := []struct { location string resource string namespace string fieldSelector fields.Selector }{ - // Minion + // Node { - location: testapi.Default.ResourcePath("minions", api.NamespaceAll, ""), - resource: "minions", + location: testapi.Default.ResourcePath("nodes", api.NamespaceAll, ""), + resource: "nodes", namespace: api.NamespaceAll, fieldSelector: parseSelectorOrDie(""), }, @@ -104,7 +105,7 @@ func TestListWatchesCanList(t *testing.T) { } func TestListWatchesCanWatch(t *testing.T) { - fieldSelectorQueryParamName := api.FieldSelectorQueryParam(testapi.Default.Version()) + fieldSelectorQueryParamName := unversioned.FieldSelectorQueryParam(testapi.Default.Version()) table := []struct { rv string location string @@ -112,22 +113,22 @@ func TestListWatchesCanWatch(t *testing.T) { namespace string fieldSelector fields.Selector }{ - // Minion + // Node { location: buildLocation( - testapi.Default.ResourcePathWithPrefix("watch", "minions", api.NamespaceAll, ""), + testapi.Default.ResourcePathWithPrefix("watch", "nodes", api.NamespaceAll, ""), buildQueryValues(url.Values{"resourceVersion": []string{""}})), rv: "", - resource: "minions", + resource: "nodes", namespace: api.NamespaceAll, fieldSelector: parseSelectorOrDie(""), }, { location: buildLocation( - testapi.Default.ResourcePathWithPrefix("watch", "minions", api.NamespaceAll, ""), + testapi.Default.ResourcePathWithPrefix("watch", "nodes", api.NamespaceAll, ""), buildQueryValues(url.Values{"resourceVersion": []string{"42"}})), rv: "42", - resource: "minions", + resource: "nodes", namespace: api.NamespaceAll, fieldSelector: parseSelectorOrDie(""), }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/reflector_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/reflector_test.go index c57b723ae7b9..f0593434893d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/reflector_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/reflector_test.go @@ -24,6 +24,7 @@ import ( "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/watch" @@ -48,7 +49,7 @@ func TestCloseWatchChannelOnError(t *testing.T) { return fw, nil }, ListFunc: func() (runtime.Object, error) { - return &api.PodList{ListMeta: api.ListMeta{ResourceVersion: "1"}}, nil + return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil }, } go r.ListAndWatch(util.NeverStop) @@ -58,8 +59,8 @@ func TestCloseWatchChannelOnError(t *testing.T) { if ok { t.Errorf("Watch channel left open after cancellation") } - case <-time.After(100 * time.Millisecond): - t.Errorf("the cancellation is at least 99 milliseconds late") + case <-time.After(util.ForeverTestTimeout): + t.Errorf("the cancellation is at least %s late", util.ForeverTestTimeout.String()) break } } @@ -74,7 +75,7 @@ func TestRunUntil(t *testing.T) { return fw, nil }, ListFunc: func() (runtime.Object, error) { - return &api.PodList{ListMeta: api.ListMeta{ResourceVersion: "1"}}, nil + return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil }, } r.RunUntil(stopCh) @@ -87,8 +88,8 @@ func TestRunUntil(t *testing.T) { if ok { t.Errorf("Watch channel left open after stopping the watch") } - case <-time.After(100 * time.Millisecond): - t.Errorf("the cancellation is at least 99 milliseconds late") + case <-time.After(util.ForeverTestTimeout): + t.Errorf("the cancellation is at least %s late", util.ForeverTestTimeout.String()) break } } @@ -97,7 +98,7 @@ func TestReflector_resyncChan(t *testing.T) { s := NewStore(MetaNamespaceKeyFunc) g := NewReflector(&testLW{}, &api.Pod{}, s, time.Millisecond) a, _ := g.resyncChan() - b := time.After(100 * time.Millisecond) + b := time.After(util.ForeverTestTimeout) select { case <-a: t.Logf("got timeout as expected") @@ -234,7 +235,7 @@ func TestReflector_ListAndWatch(t *testing.T) { return fw, nil }, ListFunc: func() (runtime.Object, error) { - return &api.PodList{ListMeta: api.ListMeta{ResourceVersion: "1"}}, nil + return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil }, } s := NewFIFO(MetaNamespaceKeyFunc) @@ -277,7 +278,7 @@ func TestReflector_ListAndWatchWithErrors(t *testing.T) { return &api.Pod{ObjectMeta: api.ObjectMeta{Name: id, ResourceVersion: rv}} } mkList := func(rv string, pods ...*api.Pod) *api.PodList { - list := &api.PodList{ListMeta: api.ListMeta{ResourceVersion: rv}} + list := &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: rv}} for _, pod := range pods { list.Items = append(list.Items, *pod) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/metrics/metrics.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/metrics/metrics.go index ce7e17fdaa8e..c98d6a41326f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/metrics/metrics.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/metrics/metrics.go @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package metrics provides utilities for registering client metrics to Prometheus. package metrics import ( @@ -26,6 +27,8 @@ import ( const restClientSubsystem = "rest_client" var ( + // RequestLatency is a Prometheus Summary metric type partitioned by + // "verb" and "url" labels. It is used for the rest client latency metrics. RequestLatency = prometheus.NewSummaryVec( prometheus.SummaryOpts{ Subsystem: restClientSubsystem, @@ -39,7 +42,8 @@ var ( var registerMetrics sync.Once -// Register all metrics. +// Register registers all metrics to Prometheus with +// respect to the RequestLatency. func Register() { // Register the metrics. registerMetrics.Do(func() { @@ -47,7 +51,7 @@ func Register() { }) } -// Gets the time since the specified start in microseconds. +// Calculates the time since the specified start in microseconds. func SinceInMicroseconds(start time.Time) float64 { return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds()) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event.go index 4058e632038f..09b11a4933ed 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event.go @@ -17,15 +17,18 @@ limitations under the License. package record import ( + "encoding/json" "fmt" "math/rand" "time" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/strategicpatch" "k8s.io/kubernetes/pkg/watch" "github.com/golang/glog" @@ -44,6 +47,7 @@ const maxQueuedEvents = 1000 type EventSink interface { Create(event *api.Event) (*api.Event, error) Update(event *api.Event) (*api.Event, error) + Patch(oldEvent *api.Event, data []byte) (*api.Event, error) } // EventRecorder knows how to record events on behalf of an EventSource. @@ -64,7 +68,7 @@ type EventRecorder interface { Eventf(object runtime.Object, reason, messageFmt string, args ...interface{}) // PastEventf is just like Eventf, but with an option to specify the event's 'timestamp' field. - PastEventf(object runtime.Object, timestamp util.Time, reason, messageFmt string, args ...interface{}) + PastEventf(object runtime.Object, timestamp unversioned.Time, reason, messageFmt string, args ...interface{}) } // EventBroadcaster knows how to receive events and send them to any EventSink, watcher, or log. @@ -103,25 +107,33 @@ func (eventBroadcaster *eventBroadcasterImpl) StartRecordingToSink(sink EventSin // The default math/rand package functions aren't thread safe, so create a // new Rand object for each StartRecording call. randGen := rand.New(rand.NewSource(time.Now().UnixNano())) + var eventCache *historyCache = NewEventCache() return eventBroadcaster.StartEventWatcher( func(event *api.Event) { // Make a copy before modification, because there could be multiple listeners. // Events are safe to copy like this. eventCopy := *event event = &eventCopy - - previousEvent := getEvent(event) + var patch []byte + previousEvent := eventCache.getEvent(event) updateExistingEvent := previousEvent.Count > 0 if updateExistingEvent { - event.Count = previousEvent.Count + 1 - event.FirstTimestamp = previousEvent.FirstTimestamp + // we still need to copy Name because the Patch relies on the Name to find the target event event.Name = previousEvent.Name - event.ResourceVersion = previousEvent.ResourceVersion + event.Count = previousEvent.Count + 1 + + // we need to make sure the Count and LastTimestamp are the only differences between event and the eventCopy2 + eventCopy2 := *event + eventCopy2.Count = 0 + eventCopy2.LastTimestamp = unversioned.NewTime(time.Unix(0, 0)) + newData, _ := json.Marshal(event) + oldData, _ := json.Marshal(eventCopy2) + patch, _ = strategicpatch.CreateStrategicMergePatch(oldData, newData, event) } tries := 0 for { - if recordEvent(sink, event, updateExistingEvent) { + if recordEvent(sink, event, patch, updateExistingEvent, eventCache) { break } tries++ @@ -155,11 +167,11 @@ func isKeyNotFoundError(err error) bool { // was successfully recorded or discarded, false if it should be retried. // If updateExistingEvent is false, it creates a new event, otherwise it updates // existing event. -func recordEvent(sink EventSink, event *api.Event, updateExistingEvent bool) bool { +func recordEvent(sink EventSink, event *api.Event, patch []byte, updateExistingEvent bool, eventCache *historyCache) bool { var newEvent *api.Event var err error if updateExistingEvent { - newEvent, err = sink.Update(event) + newEvent, err = sink.Patch(event, patch) } // Update can fail because the event may have been removed and it no longer exists. if !updateExistingEvent || (updateExistingEvent && isKeyNotFoundError(err)) { @@ -168,7 +180,7 @@ func recordEvent(sink EventSink, event *api.Event, updateExistingEvent bool) boo newEvent, err = sink.Create(event) } if err == nil { - addOrUpdateEvent(newEvent) + eventCache.addOrUpdateEvent(newEvent) return true } @@ -230,41 +242,42 @@ func (eventBroadcaster *eventBroadcasterImpl) StartEventWatcher(eventHandler fun // NewRecorder returns an EventRecorder that records events with the given event source. func (eventBroadcaster *eventBroadcasterImpl) NewRecorder(source api.EventSource) EventRecorder { - return &recorderImpl{source, eventBroadcaster.Broadcaster} + return &recorderImpl{source, eventBroadcaster.Broadcaster, util.RealClock{}} } type recorderImpl struct { source api.EventSource *watch.Broadcaster + clock util.Clock } -func (recorder *recorderImpl) generateEvent(object runtime.Object, timestamp util.Time, reason, message string) { +func (recorder *recorderImpl) generateEvent(object runtime.Object, timestamp unversioned.Time, reason, message string) { ref, err := api.GetReference(object) if err != nil { glog.Errorf("Could not construct reference to: '%#v' due to: '%v'. Will not report event: '%v' '%v'", object, err, reason, message) return } - event := makeEvent(ref, reason, message) + event := recorder.makeEvent(ref, reason, message) event.Source = recorder.source recorder.Action(watch.Added, event) } func (recorder *recorderImpl) Event(object runtime.Object, reason, message string) { - recorder.generateEvent(object, util.Now(), reason, message) + recorder.generateEvent(object, unversioned.Now(), reason, message) } func (recorder *recorderImpl) Eventf(object runtime.Object, reason, messageFmt string, args ...interface{}) { recorder.Event(object, reason, fmt.Sprintf(messageFmt, args...)) } -func (recorder *recorderImpl) PastEventf(object runtime.Object, timestamp util.Time, reason, messageFmt string, args ...interface{}) { +func (recorder *recorderImpl) PastEventf(object runtime.Object, timestamp unversioned.Time, reason, messageFmt string, args ...interface{}) { recorder.generateEvent(object, timestamp, reason, fmt.Sprintf(messageFmt, args...)) } -func makeEvent(ref *api.ObjectReference, reason, message string) *api.Event { - t := util.Now() +func (recorder *recorderImpl) makeEvent(ref *api.ObjectReference, reason, message string) *api.Event { + t := unversioned.Time{recorder.clock.Now()} namespace := ref.Namespace if namespace == "" { namespace = api.NamespaceDefault diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event_test.go index 5234513c466e..4a551dc23d40 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event_test.go @@ -17,18 +17,20 @@ limitations under the License. package record import ( + "encoding/json" "fmt" "reflect" "strconv" "strings" - "sync" "testing" + "time" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/strategicpatch" ) func init() { @@ -39,6 +41,7 @@ func init() { type testEventSink struct { OnCreate func(e *api.Event) (*api.Event, error) OnUpdate func(e *api.Event) (*api.Event, error) + OnPatch func(e *api.Event, p []byte) (*api.Event, error) } // CreateEvent records the event for testing. @@ -57,6 +60,50 @@ func (t *testEventSink) Update(e *api.Event) (*api.Event, error) { return e, nil } +// PatchEvent records the event for testing. +func (t *testEventSink) Patch(e *api.Event, p []byte) (*api.Event, error) { + if t.OnPatch != nil { + return t.OnPatch(e, p) + } + return e, nil +} + +type OnCreateFunc func(*api.Event) (*api.Event, error) + +func OnCreateFactory(testCache map[string]*api.Event, createEvent chan<- *api.Event) OnCreateFunc { + return func(event *api.Event) (*api.Event, error) { + testCache[getEventKey(event)] = event + createEvent <- event + return event, nil + } +} + +type OnPatchFunc func(*api.Event, []byte) (*api.Event, error) + +func OnPatchFactory(testCache map[string]*api.Event, patchEvent chan<- *api.Event) OnPatchFunc { + return func(event *api.Event, patch []byte) (*api.Event, error) { + cachedEvent, found := testCache[getEventKey(event)] + if !found { + return nil, fmt.Errorf("unexpected error: couldn't find Event in testCache. Try to find Event: %v", event) + } + originalData, err := json.Marshal(cachedEvent) + if err != nil { + return nil, fmt.Errorf("unexpected error: %v", err) + } + patched, err := strategicpatch.StrategicMergePatch(originalData, patch, event) + if err != nil { + return nil, fmt.Errorf("unexpected error: %v", err) + } + patchedObj := &api.Event{} + err = json.Unmarshal(patched, patchedObj) + if err != nil { + return nil, fmt.Errorf("unexpected error: %v", err) + } + patchEvent <- patchedObj + return patchedObj, nil + } +} + func TestEventf(t *testing.T) { testPod := &api.Pod{ ObjectMeta: api.ObjectMeta{ @@ -271,81 +318,90 @@ func TestEventf(t *testing.T) { }, } + testCache := map[string]*api.Event{} + logCalled := make(chan struct{}) + createEvent := make(chan *api.Event) + updateEvent := make(chan *api.Event) + patchEvent := make(chan *api.Event) + testEvents := testEventSink{ + OnCreate: OnCreateFactory(testCache, createEvent), + OnUpdate: func(event *api.Event) (*api.Event, error) { + updateEvent <- event + return event, nil + }, + OnPatch: OnPatchFactory(testCache, patchEvent), + } + eventBroadcaster := NewBroadcaster() + sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents) + + clock := &util.FakeClock{time.Now()} + recorder := recorderWithFakeClock(api.EventSource{Component: "eventTest"}, eventBroadcaster, clock) for _, item := range table { - var wg sync.WaitGroup - // We expect only one callback - wg.Add(1) - testEvents := testEventSink{ - OnCreate: func(event *api.Event) (*api.Event, error) { - defer wg.Done() - returnEvent, _ := validateEvent(event, item.expect, t) - if item.expectUpdate { - t.Errorf("Expected event update(), got event create()") - } - return returnEvent, nil - }, - OnUpdate: func(event *api.Event) (*api.Event, error) { - defer wg.Done() - returnEvent, _ := validateEvent(event, item.expect, t) - if !item.expectUpdate { - t.Errorf("Expected event create(), got event update()") - } - return returnEvent, nil - }, - } - eventBroadcaster := NewBroadcaster() - sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents) + clock.Step(1 * time.Second) logWatcher1 := eventBroadcaster.StartLogging(t.Logf) // Prove that it is useful - wg.Add(1) logWatcher2 := eventBroadcaster.StartLogging(func(formatter string, args ...interface{}) { - defer wg.Done() if e, a := item.expectLog, fmt.Sprintf(formatter, args...); e != a { t.Errorf("Expected '%v', got '%v'", e, a) } + logCalled <- struct{}{} }) - recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "eventTest"}) recorder.Eventf(item.obj, item.reason, item.messageFmt, item.elements...) - wg.Wait() - sinkWatcher.Stop() + <-logCalled + + // validate event + if item.expectUpdate { + actualEvent := <-patchEvent + validateEvent(actualEvent, item.expect, t) + } else { + actualEvent := <-createEvent + validateEvent(actualEvent, item.expect, t) + } logWatcher1.Stop() logWatcher2.Stop() } + sinkWatcher.Stop() } func validateEvent(actualEvent *api.Event, expectedEvent *api.Event, t *testing.T) (*api.Event, error) { + recvEvent := *actualEvent expectCompression := expectedEvent.Count > 1 + t.Logf("expectedEvent.Count is %d\n", expectedEvent.Count) // Just check that the timestamp was set. - if actualEvent.FirstTimestamp.IsZero() || actualEvent.LastTimestamp.IsZero() { - t.Errorf("timestamp wasn't set: %#v", *actualEvent) + if recvEvent.FirstTimestamp.IsZero() || recvEvent.LastTimestamp.IsZero() { + t.Errorf("timestamp wasn't set: %#v", recvEvent) } - actualFirstTimestamp := actualEvent.FirstTimestamp - actualLastTimestamp := actualEvent.LastTimestamp + actualFirstTimestamp := recvEvent.FirstTimestamp + actualLastTimestamp := recvEvent.LastTimestamp if actualFirstTimestamp.Equal(actualLastTimestamp) { if expectCompression { - t.Errorf("FirstTimestamp (%q) and LastTimestamp (%q) must be different to indicate event compression happened, but were the same. Actual Event: %#v", actualFirstTimestamp, actualLastTimestamp, *actualEvent) + t.Errorf("FirstTimestamp (%q) and LastTimestamp (%q) must be different to indicate event compression happened, but were the same. Actual Event: %#v", actualFirstTimestamp, actualLastTimestamp, recvEvent) } } else { if expectedEvent.Count == 1 { - t.Errorf("FirstTimestamp (%q) and LastTimestamp (%q) must be equal to indicate only one occurrence of the event, but were different. Actual Event: %#v", actualFirstTimestamp, actualLastTimestamp, *actualEvent) + t.Errorf("FirstTimestamp (%q) and LastTimestamp (%q) must be equal to indicate only one occurrence of the event, but were different. Actual Event: %#v", actualFirstTimestamp, actualLastTimestamp, recvEvent) } } // Temp clear time stamps for comparison because actual values don't matter for comparison - actualEvent.FirstTimestamp = expectedEvent.FirstTimestamp - actualEvent.LastTimestamp = expectedEvent.LastTimestamp + recvEvent.FirstTimestamp = expectedEvent.FirstTimestamp + recvEvent.LastTimestamp = expectedEvent.LastTimestamp // Check that name has the right prefix. - if n, en := actualEvent.Name, expectedEvent.Name; !strings.HasPrefix(n, en) { + if n, en := recvEvent.Name, expectedEvent.Name; !strings.HasPrefix(n, en) { t.Errorf("Name '%v' does not contain prefix '%v'", n, en) } - actualEvent.Name = expectedEvent.Name - if e, a := expectedEvent, actualEvent; !reflect.DeepEqual(e, a) { + recvEvent.Name = expectedEvent.Name + if e, a := expectedEvent, &recvEvent; !reflect.DeepEqual(e, a) { t.Errorf("diff: %s", util.ObjectGoPrintDiff(e, a)) } - actualEvent.FirstTimestamp = actualFirstTimestamp - actualEvent.LastTimestamp = actualLastTimestamp + recvEvent.FirstTimestamp = actualFirstTimestamp + recvEvent.LastTimestamp = actualLastTimestamp return actualEvent, nil } +func recorderWithFakeClock(eventSource api.EventSource, eventBroadcaster EventBroadcaster, clock util.Clock) EventRecorder { + return &recorderImpl{eventSource, eventBroadcaster.(*eventBroadcasterImpl).Broadcaster, clock} +} + func TestWriteEventError(t *testing.T) { ref := &api.ObjectReference{ Kind: "Pod", @@ -410,8 +466,10 @@ func TestWriteEventError(t *testing.T) { }, }, ).Stop() - recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "eventTest"}) + clock := &util.FakeClock{time.Now()} + recorder := recorderWithFakeClock(api.EventSource{Component: "eventTest"}, eventBroadcaster, clock) for caseName := range table { + clock.Step(1 * time.Second) recorder.Event(ref, "Reason", caseName) } recorder.Event(ref, "Reason", "finished") @@ -526,42 +584,328 @@ func TestEventfNoNamespace(t *testing.T) { }, } + testCache := map[string]*api.Event{} + logCalled := make(chan struct{}) + createEvent := make(chan *api.Event) + updateEvent := make(chan *api.Event) + patchEvent := make(chan *api.Event) + testEvents := testEventSink{ + OnCreate: OnCreateFactory(testCache, createEvent), + OnUpdate: func(event *api.Event) (*api.Event, error) { + updateEvent <- event + return event, nil + }, + OnPatch: OnPatchFactory(testCache, patchEvent), + } + eventBroadcaster := NewBroadcaster() + sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents) + + clock := &util.FakeClock{time.Now()} + recorder := recorderWithFakeClock(api.EventSource{Component: "eventTest"}, eventBroadcaster, clock) + for _, item := range table { - called := make(chan struct{}) - testEvents := testEventSink{ - OnCreate: func(event *api.Event) (*api.Event, error) { - returnEvent, _ := validateEvent(event, item.expect, t) - if item.expectUpdate { - t.Errorf("Expected event update(), got event create()") - } - called <- struct{}{} - return returnEvent, nil - }, - OnUpdate: func(event *api.Event) (*api.Event, error) { - returnEvent, _ := validateEvent(event, item.expect, t) - if !item.expectUpdate { - t.Errorf("Expected event create(), got event update()") - } - called <- struct{}{} - return returnEvent, nil - }, - } - eventBroadcaster := NewBroadcaster() - sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents) + clock.Step(1 * time.Second) logWatcher1 := eventBroadcaster.StartLogging(t.Logf) // Prove that it is useful logWatcher2 := eventBroadcaster.StartLogging(func(formatter string, args ...interface{}) { if e, a := item.expectLog, fmt.Sprintf(formatter, args...); e != a { t.Errorf("Expected '%v', got '%v'", e, a) } - called <- struct{}{} + logCalled <- struct{}{} }) - recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "eventTest"}) recorder.Eventf(item.obj, item.reason, item.messageFmt, item.elements...) - <-called - <-called - sinkWatcher.Stop() + <-logCalled + + // validate event + if item.expectUpdate { + actualEvent := <-patchEvent + validateEvent(actualEvent, item.expect, t) + } else { + actualEvent := <-createEvent + validateEvent(actualEvent, item.expect, t) + } + logWatcher1.Stop() logWatcher2.Stop() } + sinkWatcher.Stop() +} + +func TestMultiSinkCache(t *testing.T) { + testPod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + SelfLink: "/api/version/pods/foo", + Name: "foo", + Namespace: "baz", + UID: "bar", + }, + } + testPod2 := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + SelfLink: "/api/version/pods/foo", + Name: "foo", + Namespace: "baz", + UID: "differentUid", + }, + } + testRef, err := api.GetPartialReference(testPod, "spec.containers[2]") + testRef2, err := api.GetPartialReference(testPod2, "spec.containers[3]") + if err != nil { + t.Fatal(err) + } + table := []struct { + obj runtime.Object + reason string + messageFmt string + elements []interface{} + expect *api.Event + expectLog string + expectUpdate bool + }{ + { + obj: testRef, + reason: "Started", + messageFmt: "some verbose message: %v", + elements: []interface{}{1}, + expect: &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: "baz", + }, + InvolvedObject: api.ObjectReference{ + Kind: "Pod", + Name: "foo", + Namespace: "baz", + UID: "bar", + APIVersion: "version", + FieldPath: "spec.containers[2]", + }, + Reason: "Started", + Message: "some verbose message: 1", + Source: api.EventSource{Component: "eventTest"}, + Count: 1, + }, + expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): reason: 'Started' some verbose message: 1`, + expectUpdate: false, + }, + { + obj: testPod, + reason: "Killed", + messageFmt: "some other verbose message: %v", + elements: []interface{}{1}, + expect: &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: "baz", + }, + InvolvedObject: api.ObjectReference{ + Kind: "Pod", + Name: "foo", + Namespace: "baz", + UID: "bar", + APIVersion: "version", + }, + Reason: "Killed", + Message: "some other verbose message: 1", + Source: api.EventSource{Component: "eventTest"}, + Count: 1, + }, + expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:""}): reason: 'Killed' some other verbose message: 1`, + expectUpdate: false, + }, + { + obj: testRef, + reason: "Started", + messageFmt: "some verbose message: %v", + elements: []interface{}{1}, + expect: &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: "baz", + }, + InvolvedObject: api.ObjectReference{ + Kind: "Pod", + Name: "foo", + Namespace: "baz", + UID: "bar", + APIVersion: "version", + FieldPath: "spec.containers[2]", + }, + Reason: "Started", + Message: "some verbose message: 1", + Source: api.EventSource{Component: "eventTest"}, + Count: 2, + }, + expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): reason: 'Started' some verbose message: 1`, + expectUpdate: true, + }, + { + obj: testRef2, + reason: "Started", + messageFmt: "some verbose message: %v", + elements: []interface{}{1}, + expect: &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: "baz", + }, + InvolvedObject: api.ObjectReference{ + Kind: "Pod", + Name: "foo", + Namespace: "baz", + UID: "differentUid", + APIVersion: "version", + FieldPath: "spec.containers[3]", + }, + Reason: "Started", + Message: "some verbose message: 1", + Source: api.EventSource{Component: "eventTest"}, + Count: 1, + }, + expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): reason: 'Started' some verbose message: 1`, + expectUpdate: false, + }, + { + obj: testRef, + reason: "Started", + messageFmt: "some verbose message: %v", + elements: []interface{}{1}, + expect: &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: "baz", + }, + InvolvedObject: api.ObjectReference{ + Kind: "Pod", + Name: "foo", + Namespace: "baz", + UID: "bar", + APIVersion: "version", + FieldPath: "spec.containers[2]", + }, + Reason: "Started", + Message: "some verbose message: 1", + Source: api.EventSource{Component: "eventTest"}, + Count: 3, + }, + expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): reason: 'Started' some verbose message: 1`, + expectUpdate: true, + }, + { + obj: testRef2, + reason: "Stopped", + messageFmt: "some verbose message: %v", + elements: []interface{}{1}, + expect: &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: "baz", + }, + InvolvedObject: api.ObjectReference{ + Kind: "Pod", + Name: "foo", + Namespace: "baz", + UID: "differentUid", + APIVersion: "version", + FieldPath: "spec.containers[3]", + }, + Reason: "Stopped", + Message: "some verbose message: 1", + Source: api.EventSource{Component: "eventTest"}, + Count: 1, + }, + expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): reason: 'Stopped' some verbose message: 1`, + expectUpdate: false, + }, + { + obj: testRef2, + reason: "Stopped", + messageFmt: "some verbose message: %v", + elements: []interface{}{1}, + expect: &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: "baz", + }, + InvolvedObject: api.ObjectReference{ + Kind: "Pod", + Name: "foo", + Namespace: "baz", + UID: "differentUid", + APIVersion: "version", + FieldPath: "spec.containers[3]", + }, + Reason: "Stopped", + Message: "some verbose message: 1", + Source: api.EventSource{Component: "eventTest"}, + Count: 2, + }, + expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): reason: 'Stopped' some verbose message: 1`, + expectUpdate: true, + }, + } + + testCache := map[string]*api.Event{} + createEvent := make(chan *api.Event) + updateEvent := make(chan *api.Event) + patchEvent := make(chan *api.Event) + testEvents := testEventSink{ + OnCreate: OnCreateFactory(testCache, createEvent), + OnUpdate: func(event *api.Event) (*api.Event, error) { + updateEvent <- event + return event, nil + }, + OnPatch: OnPatchFactory(testCache, patchEvent), + } + + testCache2 := map[string]*api.Event{} + createEvent2 := make(chan *api.Event) + updateEvent2 := make(chan *api.Event) + patchEvent2 := make(chan *api.Event) + testEvents2 := testEventSink{ + OnCreate: OnCreateFactory(testCache2, createEvent2), + OnUpdate: func(event *api.Event) (*api.Event, error) { + updateEvent2 <- event + return event, nil + }, + OnPatch: OnPatchFactory(testCache2, patchEvent2), + } + + eventBroadcaster := NewBroadcaster() + clock := &util.FakeClock{time.Now()} + recorder := recorderWithFakeClock(api.EventSource{Component: "eventTest"}, eventBroadcaster, clock) + + sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents) + for _, item := range table { + clock.Step(1 * time.Second) + recorder.Eventf(item.obj, item.reason, item.messageFmt, item.elements...) + + // validate event + if item.expectUpdate { + actualEvent := <-patchEvent + validateEvent(actualEvent, item.expect, t) + } else { + actualEvent := <-createEvent + validateEvent(actualEvent, item.expect, t) + } + } + + // Another StartRecordingToSink call should start to record events with new clean cache. + sinkWatcher2 := eventBroadcaster.StartRecordingToSink(&testEvents2) + for _, item := range table { + clock.Step(1 * time.Second) + recorder.Eventf(item.obj, item.reason, item.messageFmt, item.elements...) + + // validate event + if item.expectUpdate { + actualEvent := <-patchEvent2 + validateEvent(actualEvent, item.expect, t) + } else { + actualEvent := <-createEvent2 + validateEvent(actualEvent, item.expect, t) + } + } + + sinkWatcher.Stop() + sinkWatcher2.Stop() } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache.go index 67ca127745b8..dc4b6e08f6ef 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache.go @@ -21,7 +21,7 @@ import ( "github.com/golang/groupcache/lru" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) type history struct { @@ -29,7 +29,7 @@ type history struct { Count int // The time at which the event was first recorded. - FirstTimestamp util.Time + FirstTimestamp unversioned.Time // The unique name of the first occurrence of this event Name string @@ -47,15 +47,17 @@ type historyCache struct { cache *lru.Cache } -var previousEvents = historyCache{cache: lru.New(maxLruCacheEntries)} +func NewEventCache() *historyCache { + return &historyCache{cache: lru.New(maxLruCacheEntries)} +} // addOrUpdateEvent creates a new entry for the given event in the previous events hash table if the event // doesn't already exist, otherwise it updates the existing entry. -func addOrUpdateEvent(newEvent *api.Event) history { +func (eventCache *historyCache) addOrUpdateEvent(newEvent *api.Event) history { key := getEventKey(newEvent) - previousEvents.Lock() - defer previousEvents.Unlock() - previousEvents.cache.Add( + eventCache.Lock() + defer eventCache.Unlock() + eventCache.cache.Add( key, history{ Count: newEvent.Count, @@ -63,20 +65,20 @@ func addOrUpdateEvent(newEvent *api.Event) history { Name: newEvent.Name, ResourceVersion: newEvent.ResourceVersion, }) - return getEventFromCache(key) + return eventCache.getEventFromCache(key) } // getEvent returns the entry corresponding to the given event, if one exists, otherwise a history object // with a count of 0 is returned. -func getEvent(event *api.Event) history { +func (eventCache *historyCache) getEvent(event *api.Event) history { key := getEventKey(event) - previousEvents.RLock() - defer previousEvents.RUnlock() - return getEventFromCache(key) + eventCache.RLock() + defer eventCache.RUnlock() + return eventCache.getEventFromCache(key) } -func getEventFromCache(key string) history { - value, ok := previousEvents.cache.Get(key) +func (eventCache *historyCache) getEventFromCache(key string) history { + value, ok := eventCache.cache.Get(key) if ok { historyValue, ok := value.(history) if ok { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache_test.go index 282122029ba2..78dcb2d84cbf 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache_test.go @@ -20,12 +20,13 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) func TestAddOrUpdateEventNoExisting(t *testing.T) { // Arrange - eventTime := util.Now() + eventCache := NewEventCache() + eventTime := unversioned.Now() event := api.Event{ Reason: "my reasons are many", Message: "my message is love", @@ -46,7 +47,7 @@ func TestAddOrUpdateEventNoExisting(t *testing.T) { } // Act - result := addOrUpdateEvent(&event) + result := eventCache.addOrUpdateEvent(&event) // Assert compareEventWithHistoryEntry(&event, &result, t) @@ -54,8 +55,9 @@ func TestAddOrUpdateEventNoExisting(t *testing.T) { func TestAddOrUpdateEventExisting(t *testing.T) { // Arrange - event1Time := util.Unix(2324, 2342) - event2Time := util.Now() + eventCache := NewEventCache() + event1Time := unversioned.Unix(2324, 2342) + event2Time := unversioned.Now() event1 := api.Event{ Reason: "something happened", Message: "can you believe it?", @@ -100,9 +102,9 @@ func TestAddOrUpdateEventExisting(t *testing.T) { } // Act - addOrUpdateEvent(&event1) - result1 := addOrUpdateEvent(&event2) - result2 := getEvent(&event1) + eventCache.addOrUpdateEvent(&event1) + result1 := eventCache.addOrUpdateEvent(&event2) + result2 := eventCache.getEvent(&event1) // Assert compareEventWithHistoryEntry(&event2, &result1, t) @@ -111,6 +113,7 @@ func TestAddOrUpdateEventExisting(t *testing.T) { func TestGetEventNoExisting(t *testing.T) { // Arrange + eventCache := NewEventCache() event := api.Event{ Reason: "to be or not to be", Message: "do I exist", @@ -129,7 +132,7 @@ func TestGetEventNoExisting(t *testing.T) { } // Act - existingEvent := getEvent(&event) + existingEvent := eventCache.getEvent(&event) // Assert if existingEvent.Count != 0 { @@ -139,7 +142,8 @@ func TestGetEventNoExisting(t *testing.T) { func TestGetEventExisting(t *testing.T) { // Arrange - eventTime := util.Now() + eventCache := NewEventCache() + eventTime := unversioned.Now() event := api.Event{ Reason: "do I exist", Message: "I do, oh my", @@ -158,10 +162,10 @@ func TestGetEventExisting(t *testing.T) { FirstTimestamp: eventTime, LastTimestamp: eventTime, } - addOrUpdateEvent(&event) + eventCache.addOrUpdateEvent(&event) // Act - existingEvent := getEvent(&event) + existingEvent := eventCache.getEvent(&event) // Assert compareEventWithHistoryEntry(&event, &existingEvent, t) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/fake.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/fake.go index bdfdf1562dda..9efed89ac891 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/fake.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/fake.go @@ -19,8 +19,8 @@ package record import ( "fmt" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" ) // FakeRecorder is used as a fake during tests. @@ -36,5 +36,5 @@ func (f *FakeRecorder) Eventf(object runtime.Object, reason, messageFmt string, f.Events = append(f.Events, fmt.Sprintf(reason+" "+messageFmt, args...)) } -func (f *FakeRecorder) PastEventf(object runtime.Object, timestamp util.Time, reason, messageFmt string, args ...interface{}) { +func (f *FakeRecorder) PastEventf(object runtime.Object, timestamp unversioned.Time, reason, messageFmt string, args ...interface{}) { } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client.go index 920cd3e38785..ef23b692382a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client.go @@ -23,7 +23,11 @@ import ( "net/url" "strings" + "github.com/emicklei/go-restful/swagger" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/version" ) @@ -46,8 +50,8 @@ type Interface interface { PersistentVolumesInterface PersistentVolumeClaimsNamespacer ComponentStatusesInterface - Experimental() ExperimentalInterface - SecurityContextConstraintsInterface + SwaggerSchemaInterface + Extensions() ExtensionsInterface } func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface { @@ -58,10 +62,6 @@ func (c *Client) Nodes() NodeInterface { return newNodes(c) } -func (c *Client) SecurityContextConstraints() SecurityContextConstraintInterface { - return newSecurityContextConstraints(c) -} - func (c *Client) Events(namespace string) EventInterface { return newEvents(c, namespace) } @@ -116,19 +116,19 @@ func (c *Client) ComponentStatuses() ComponentStatusInterface { // VersionInterface has a method to retrieve the server version. type VersionInterface interface { ServerVersion() (*version.Info, error) - ServerAPIVersions() (*api.APIVersions, error) + ServerAPIVersions() (*unversioned.APIVersions, error) } // APIStatus is exposed by errors that can be converted to an api.Status object // for finer grained details. type APIStatus interface { - Status() api.Status + Status() unversioned.Status } // Client is the implementation of a Kubernetes client. type Client struct { *RESTClient - *ExperimentalClient + *ExtensionsClient } // ServerVersion retrieves and parses the server's version. @@ -146,12 +146,12 @@ func (c *Client) ServerVersion() (*version.Info, error) { } // ServerAPIVersions retrieves and parses the list of API versions the server supports. -func (c *Client) ServerAPIVersions() (*api.APIVersions, error) { +func (c *Client) ServerAPIVersions() (*unversioned.APIVersions, error) { body, err := c.Get().UnversionedPath("").Do().Raw() if err != nil { return nil, err } - var v api.APIVersions + var v unversioned.APIVersions err = json.Unmarshal(body, &v) if err != nil { return nil, fmt.Errorf("got '%s': %v", string(body), err) @@ -178,6 +178,49 @@ func (c *Client) ValidateComponents() (*api.ComponentStatusList, error) { return &api.ComponentStatusList{Items: statuses}, nil } +// SwaggerSchemaInterface has a method to retrieve the swagger schema. Used in +// client.Interface +type SwaggerSchemaInterface interface { + SwaggerSchema(version string) (*swagger.ApiDeclaration, error) +} + +// SwaggerSchema retrieves and parses the swagger API schema the server supports. +func (c *Client) SwaggerSchema(version string) (*swagger.ApiDeclaration, error) { + if version == "" { + version = latest.GroupOrDie("").Version + } + + vers, err := c.ServerAPIVersions() + if err != nil { + return nil, err + } + + // This check also takes care the case that kubectl is newer than the running endpoint + if stringDoesntExistIn(version, vers.Versions) { + return nil, fmt.Errorf("API version: %s is not supported by the server. Use one of: %v", version, vers.Versions) + } + + body, err := c.Get().AbsPath("/swaggerapi/api/" + version).Do().Raw() + if err != nil { + return nil, err + } + var schema swagger.ApiDeclaration + err = json.Unmarshal(body, &schema) + if err != nil { + return nil, fmt.Errorf("got '%s': %v", string(body), err) + } + return &schema, nil +} + +func stringDoesntExistIn(str string, slice []string) bool { + for _, s := range slice { + if s == str { + return false + } + } + return true +} + // IsTimeout tests if this is a timeout error in the underlying transport. // This is unbelievably ugly. // See: http://stackoverflow.com/questions/23494950/specifically-check-for-timeout-error for details @@ -200,6 +243,6 @@ func IsTimeout(err error) bool { return false } -func (c *Client) Experimental() ExperimentalInterface { - return c.ExperimentalClient +func (c *Client) Extensions() ExtensionsInterface { + return c.ExtensionsClient } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client_test.go index 72f412b47785..843e4ee30237 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client_test.go @@ -26,8 +26,11 @@ import ( "strings" "testing" + "github.com/emicklei/go-restful/swagger" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" @@ -90,9 +93,9 @@ func (c *testClient) Setup(t *testing.T) *testClient { // We will fix this by supporting multiple group versions in Config version = c.Version if len(version) == 0 { - version = testapi.Experimental.Version() + version = testapi.Extensions.Version() } - c.ExperimentalClient = NewExperimentalOrDie(&Config{ + c.ExtensionsClient = NewExtensionsOrDie(&Config{ Host: c.server.URL, Version: version, }) @@ -147,9 +150,9 @@ func (c *testClient) ValidateCommon(t *testing.T, err error) { validator, ok := c.QueryValidator[key] if !ok { switch key { - case api.LabelSelectorQueryParam(testapi.Default.Version()): + case unversioned.LabelSelectorQueryParam(testapi.Default.Version()): validator = validateLabels - case api.FieldSelectorQueryParam(testapi.Default.Version()): + case unversioned.FieldSelectorQueryParam(testapi.Default.Version()): validator = validateFields default: validator = func(a, b string) bool { return a == b } @@ -227,8 +230,8 @@ func body(t *testing.T, obj runtime.Object, raw *string) *string { if err != nil { t.Errorf("unexpected encoding error: %v", err) } - } else if api.Scheme.Recognizes(testapi.Experimental.GroupAndVersion(), kind) { - bs, err = testapi.Experimental.Codec().Encode(obj) + } else if api.Scheme.Recognizes(testapi.Extensions.GroupAndVersion(), kind) { + bs, err = testapi.Extensions.Codec().Encode(obj) if err != nil { t.Errorf("unexpected encoding error: %v", err) } @@ -270,7 +273,7 @@ func TestGetServerVersion(t *testing.T) { func TestGetServerAPIVersions(t *testing.T) { versions := []string{"v1", "v2", "v3"} - expect := api.APIVersions{Versions: versions} + expect := unversioned.APIVersions{Versions: versions} server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { output, err := json.Marshal(expect) if err != nil { @@ -290,3 +293,63 @@ func TestGetServerAPIVersions(t *testing.T) { t.Errorf("expected %v, got %v", e, a) } } + +func swaggerSchemaFakeServer() (*httptest.Server, error) { + request := 1 + var sErr error + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + var resp interface{} + if request == 1 { + resp = unversioned.APIVersions{Versions: []string{"v1", "v2", "v3"}} + request++ + } else { + resp = swagger.ApiDeclaration{} + } + output, err := json.Marshal(resp) + if err != nil { + sErr = err + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(output) + })) + return server, sErr +} + +func TestGetSwaggerSchema(t *testing.T) { + expect := swagger.ApiDeclaration{} + + server, err := swaggerSchemaFakeServer() + if err != nil { + t.Errorf("unexpected encoding error: %v", err) + } + + client := NewOrDie(&Config{Host: server.URL}) + got, err := client.SwaggerSchema("v1") + if err != nil { + t.Fatalf("unexpected encoding error: %v", err) + } + if e, a := expect, *got; !reflect.DeepEqual(e, a) { + t.Errorf("expected %v, got %v", e, a) + } +} + +func TestGetSwaggerSchemaFail(t *testing.T) { + expErr := "API version: v4 is not supported by the server. Use one of: [v1 v2 v3]" + + server, err := swaggerSchemaFakeServer() + if err != nil { + t.Errorf("unexpected encoding error: %v", err) + } + + client := NewOrDie(&Config{Host: server.URL}) + got, err := client.SwaggerSchema("v4") + if got != nil { + t.Fatalf("unexpected response: %v", got) + } + if err.Error() != expErr { + t.Errorf("expected an error, got %v", err) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/client_config_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/client_config_test.go index 4bf6eebd6969..cb6f861d1cd2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/client_config_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/client_config_test.go @@ -20,7 +20,7 @@ import ( "reflect" "testing" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/testapi" client "k8s.io/kubernetes/pkg/client/unversioned" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" ) @@ -34,7 +34,7 @@ func createValidTestConfig() *clientcmdapi.Config { config := clientcmdapi.NewConfig() config.Clusters["clean"] = &clientcmdapi.Cluster{ Server: server, - APIVersion: latest.Version, + APIVersion: testapi.Default.Version(), } config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ Token: token, @@ -89,7 +89,7 @@ func TestCertificateData(t *testing.T) { config := clientcmdapi.NewConfig() config.Clusters["clean"] = &clientcmdapi.Cluster{ Server: "https://localhost:8443", - APIVersion: latest.Version, + APIVersion: testapi.Default.Version(), CertificateAuthorityData: caData, } config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ @@ -122,7 +122,7 @@ func TestBasicAuthData(t *testing.T) { config := clientcmdapi.NewConfig() config.Clusters["clean"] = &clientcmdapi.Cluster{ Server: "https://localhost:8443", - APIVersion: latest.Version, + APIVersion: testapi.Default.Version(), } config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ Username: username, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/doc.go index d8c64d858347..7e8f9b4e3adb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/doc.go @@ -19,13 +19,19 @@ Package clientcmd provides one stop shopping for building a working client from from a .kubeconfig file, from command line flags, or from any merged combination. Sample usage from merged .kubeconfig files (local directory, home directory) - loadingRules := clientcmd.NewKubeConfigLoadingRules() + + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() // if you want to change the loading rules (which files in which order), you can do so here configOverrides := &clientcmd.ConfigOverrides{} // if you want to change override values or bind them to flags, there are methods to help you - kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingKubeConfig(loadingRules, configOverrides) - kubeConfig.Client() + kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides) + config, err := kubeConfig.ClientConfig() + if err != nil { + // Do something + } + client, err := unversioned.New(config) + // ... */ package clientcmd diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/loader.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/loader.go index 09c9ae7a8e61..2d8a99a60091 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/loader.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/loader.go @@ -36,11 +36,14 @@ import ( const ( RecommendedConfigPathFlag = "kubeconfig" RecommendedConfigPathEnvVar = "KUBECONFIG" - RecommendedHomeFileName = "/.kube/config" + RecommendedHomeDir = ".kube" + RecommendedFileName = "config" + RecommendedSchemaName = "schema" ) var OldRecommendedHomeFile = path.Join(os.Getenv("HOME"), "/.kube/.kubeconfig") -var RecommendedHomeFile = path.Join(os.Getenv("HOME"), RecommendedHomeFileName) +var RecommendedHomeFile = path.Join(os.Getenv("HOME"), RecommendedHomeDir, RecommendedFileName) +var RecommendedSchemaFile = path.Join(os.Getenv("HOME"), RecommendedHomeDir, RecommendedSchemaName) // ClientConfigLoadingRules is an ExplicitPath and string slice of specific locations that are used for merging together a Config // Callers can put the chain together however they want, but we'd recommend: diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/merged_client_builder.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/merged_client_builder.go index 42c8d1df551a..2888981f9f7b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/merged_client_builder.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/merged_client_builder.go @@ -86,7 +86,7 @@ func (config DeferredLoadingClientConfig) ClientConfig() (*client.Config, error) icc := inClusterClientConfig{} defaultConfig, err := DefaultClientConfig.ClientConfig() if icc.Possible() && err == nil && reflect.DeepEqual(mergedConfig, defaultConfig) { - glog.V(2).Info("no kubeconfig could be created, falling back to service account.") + glog.V(2).Info("No kubeconfig could be created, falling back to service account.") return icc.ClientConfig() } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/validation.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/validation.go index 002f135d10df..a631dc65d1de 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/validation.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/validation.go @@ -23,8 +23,8 @@ import ( "strings" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" - "k8s.io/kubernetes/pkg/util" utilerrors "k8s.io/kubernetes/pkg/util/errors" + "k8s.io/kubernetes/pkg/util/validation" ) var ErrNoContext = errors.New("no context chosen") @@ -232,7 +232,7 @@ func validateContext(contextName string, context clientcmdapi.Context, config cl validationErrors = append(validationErrors, fmt.Errorf("cluster %q was not found for context %q", context.Cluster, contextName)) } - if (len(context.Namespace) != 0) && !util.IsDNS952Label(context.Namespace) { + if (len(context.Namespace) != 0) && !validation.IsDNS952Label(context.Namespace) { validationErrors = append(validationErrors, fmt.Errorf("namespace %q for context %q does not conform to the kubernetes DNS952 rules", context.Namespace, contextName)) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/conditions.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/conditions.go index e26067cda75a..9117a6ff36f3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/conditions.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/conditions.go @@ -18,11 +18,12 @@ package unversioned import ( "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/util/wait" ) -// ControllerHasDesiredReplicas returns a condition that will be true iff the desired replica count -// for a controller's ReplicaSelector equals the Replicas count. +// ControllerHasDesiredReplicas returns a condition that will be true if and only if +// the desired replica count for a controller's ReplicaSelector equals the Replicas count. func ControllerHasDesiredReplicas(c Interface, controller *api.ReplicationController) wait.ConditionFunc { // If we're given a controller where the status lags the spec, it either means that the controller is stale, @@ -41,3 +42,23 @@ func ControllerHasDesiredReplicas(c Interface, controller *api.ReplicationContro return ctrl.Status.ObservedGeneration >= desiredGeneration && ctrl.Status.Replicas == ctrl.Spec.Replicas, nil } } + +// JobHasDesiredParallelism returns a condition that will be true if the desired parallelism count +// for a job equals the current active counts or is less by an appropriate successful/unsuccessful count. +func JobHasDesiredParallelism(c Interface, job *extensions.Job) wait.ConditionFunc { + + return func() (bool, error) { + job, err := c.Extensions().Jobs(job.Namespace).Get(job.Name) + if err != nil { + return false, err + } + + // desired parallelism can be either the exact number, in which case return immediately + if job.Status.Active == *job.Spec.Parallelism { + return true, nil + } + // otherwise count successful + progress := *job.Spec.Completions - job.Status.Active - job.Status.Succeeded + return progress == 0, nil + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/daemon_sets.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/daemon_sets.go index 857ecaf5c942..ebff86e5445f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/daemon_sets.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/daemon_sets.go @@ -17,7 +17,7 @@ limitations under the License. package unversioned import ( - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/watch" @@ -29,54 +29,62 @@ type DaemonSetsNamespacer interface { } type DaemonSetInterface interface { - List(selector labels.Selector) (*experimental.DaemonSetList, error) - Get(name string) (*experimental.DaemonSet, error) - Create(ctrl *experimental.DaemonSet) (*experimental.DaemonSet, error) - Update(ctrl *experimental.DaemonSet) (*experimental.DaemonSet, error) + List(label labels.Selector, field fields.Selector) (*extensions.DaemonSetList, error) + Get(name string) (*extensions.DaemonSet, error) + Create(ctrl *extensions.DaemonSet) (*extensions.DaemonSet, error) + Update(ctrl *extensions.DaemonSet) (*extensions.DaemonSet, error) + UpdateStatus(ctrl *extensions.DaemonSet) (*extensions.DaemonSet, error) Delete(name string) error Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) } // daemonSets implements DaemonsSetsNamespacer interface type daemonSets struct { - r *ExperimentalClient + r *ExtensionsClient ns string } -func newDaemonSets(c *ExperimentalClient, namespace string) *daemonSets { +func newDaemonSets(c *ExtensionsClient, namespace string) *daemonSets { return &daemonSets{c, namespace} } // Ensure statically that daemonSets implements DaemonSetsInterface. var _ DaemonSetInterface = &daemonSets{} -func (c *daemonSets) List(selector labels.Selector) (result *experimental.DaemonSetList, err error) { - result = &experimental.DaemonSetList{} - err = c.r.Get().Namespace(c.ns).Resource("daemonsets").LabelsSelectorParam(selector).Do().Into(result) +func (c *daemonSets) List(label labels.Selector, field fields.Selector) (result *extensions.DaemonSetList, err error) { + result = &extensions.DaemonSetList{} + err = c.r.Get().Namespace(c.ns).Resource("daemonsets").LabelsSelectorParam(label).FieldsSelectorParam(field).Do().Into(result) return } // Get returns information about a particular daemon set. -func (c *daemonSets) Get(name string) (result *experimental.DaemonSet, err error) { - result = &experimental.DaemonSet{} +func (c *daemonSets) Get(name string) (result *extensions.DaemonSet, err error) { + result = &extensions.DaemonSet{} err = c.r.Get().Namespace(c.ns).Resource("daemonsets").Name(name).Do().Into(result) return } // Create creates a new daemon set. -func (c *daemonSets) Create(daemon *experimental.DaemonSet) (result *experimental.DaemonSet, err error) { - result = &experimental.DaemonSet{} +func (c *daemonSets) Create(daemon *extensions.DaemonSet) (result *extensions.DaemonSet, err error) { + result = &extensions.DaemonSet{} err = c.r.Post().Namespace(c.ns).Resource("daemonsets").Body(daemon).Do().Into(result) return } // Update updates an existing daemon set. -func (c *daemonSets) Update(daemon *experimental.DaemonSet) (result *experimental.DaemonSet, err error) { - result = &experimental.DaemonSet{} +func (c *daemonSets) Update(daemon *extensions.DaemonSet) (result *extensions.DaemonSet, err error) { + result = &extensions.DaemonSet{} err = c.r.Put().Namespace(c.ns).Resource("daemonsets").Name(daemon.Name).Body(daemon).Do().Into(result) return } +// UpdateStatus updates an existing daemon set status +func (c *daemonSets) UpdateStatus(daemon *extensions.DaemonSet) (result *extensions.DaemonSet, err error) { + result = &extensions.DaemonSet{} + err = c.r.Put().Namespace(c.ns).Resource("daemonsets").Name(daemon.Name).SubResource("status").Body(daemon).Do().Into(result) + return +} + // Delete deletes an existing daemon set. func (c *daemonSets) Delete(name string) error { return c.r.Delete().Namespace(c.ns).Resource("daemonsets").Name(name).Do().Error() diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/daemon_sets_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/daemon_sets_test.go index f556f6b689fb..e81ac47e196d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/daemon_sets_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/daemon_sets_test.go @@ -21,7 +21,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" ) @@ -34,11 +35,11 @@ func TestListDaemonSets(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "GET", - Path: testapi.Experimental.ResourcePath(getDSResourceName(), ns, ""), + Path: testapi.Extensions.ResourcePath(getDSResourceName(), ns, ""), }, Response: Response{StatusCode: 200, - Body: &experimental.DaemonSetList{ - Items: []experimental.DaemonSet{ + Body: &extensions.DaemonSetList{ + Items: []extensions.DaemonSet{ { ObjectMeta: api.ObjectMeta{ Name: "foo", @@ -47,7 +48,7 @@ func TestListDaemonSets(t *testing.T) { "name": "baz", }, }, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Template: &api.PodTemplateSpec{}, }, }, @@ -55,7 +56,7 @@ func TestListDaemonSets(t *testing.T) { }, }, } - receivedDSs, err := c.Setup(t).Experimental().DaemonSets(ns).List(labels.Everything()) + receivedDSs, err := c.Setup(t).Extensions().DaemonSets(ns).List(labels.Everything(), fields.Everything()) c.Validate(t, receivedDSs, err) } @@ -63,10 +64,10 @@ func TestListDaemonSets(t *testing.T) { func TestGetDaemonSet(t *testing.T) { ns := api.NamespaceDefault c := &testClient{ - Request: testRequest{Method: "GET", Path: testapi.Experimental.ResourcePath(getDSResourceName(), ns, "foo"), Query: buildQueryValues(nil)}, + Request: testRequest{Method: "GET", Path: testapi.Extensions.ResourcePath(getDSResourceName(), ns, "foo"), Query: buildQueryValues(nil)}, Response: Response{ StatusCode: 200, - Body: &experimental.DaemonSet{ + Body: &extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{ Name: "foo", Labels: map[string]string{ @@ -74,20 +75,20 @@ func TestGetDaemonSet(t *testing.T) { "name": "baz", }, }, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Template: &api.PodTemplateSpec{}, }, }, }, } - receivedDaemonSet, err := c.Setup(t).Experimental().DaemonSets(ns).Get("foo") + receivedDaemonSet, err := c.Setup(t).Extensions().DaemonSets(ns).Get("foo") c.Validate(t, receivedDaemonSet, err) } func TestGetDaemonSetWithNoName(t *testing.T) { ns := api.NamespaceDefault c := &testClient{Error: true} - receivedPod, err := c.Setup(t).Experimental().DaemonSets(ns).Get("") + receivedPod, err := c.Setup(t).Extensions().DaemonSets(ns).Get("") if (err != nil) && (err.Error() != nameRequiredError) { t.Errorf("Expected error: %v, but got %v", nameRequiredError, err) } @@ -97,14 +98,14 @@ func TestGetDaemonSetWithNoName(t *testing.T) { func TestUpdateDaemonSet(t *testing.T) { ns := api.NamespaceDefault - requestDaemonSet := &experimental.DaemonSet{ + requestDaemonSet := &extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, } c := &testClient{ - Request: testRequest{Method: "PUT", Path: testapi.Experimental.ResourcePath(getDSResourceName(), ns, "foo"), Query: buildQueryValues(nil)}, + Request: testRequest{Method: "PUT", Path: testapi.Extensions.ResourcePath(getDSResourceName(), ns, "foo"), Query: buildQueryValues(nil)}, Response: Response{ StatusCode: 200, - Body: &experimental.DaemonSet{ + Body: &extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{ Name: "foo", Labels: map[string]string{ @@ -112,36 +113,64 @@ func TestUpdateDaemonSet(t *testing.T) { "name": "baz", }, }, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Template: &api.PodTemplateSpec{}, }, }, }, } - receivedDaemonSet, err := c.Setup(t).Experimental().DaemonSets(ns).Update(requestDaemonSet) + receivedDaemonSet, err := c.Setup(t).Extensions().DaemonSets(ns).Update(requestDaemonSet) + c.Validate(t, receivedDaemonSet, err) +} + +func TestUpdateDaemonSetUpdateStatus(t *testing.T) { + ns := api.NamespaceDefault + requestDaemonSet := &extensions.DaemonSet{ + ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, + } + c := &testClient{ + Request: testRequest{Method: "PUT", Path: testapi.Extensions.ResourcePath(getDSResourceName(), ns, "foo") + "/status", Query: buildQueryValues(nil)}, + Response: Response{ + StatusCode: 200, + Body: &extensions.DaemonSet{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: extensions.DaemonSetSpec{ + Template: &api.PodTemplateSpec{}, + }, + Status: extensions.DaemonSetStatus{}, + }, + }, + } + receivedDaemonSet, err := c.Setup(t).Extensions().DaemonSets(ns).UpdateStatus(requestDaemonSet) c.Validate(t, receivedDaemonSet, err) } func TestDeleteDaemon(t *testing.T) { ns := api.NamespaceDefault c := &testClient{ - Request: testRequest{Method: "DELETE", Path: testapi.Experimental.ResourcePath(getDSResourceName(), ns, "foo"), Query: buildQueryValues(nil)}, + Request: testRequest{Method: "DELETE", Path: testapi.Extensions.ResourcePath(getDSResourceName(), ns, "foo"), Query: buildQueryValues(nil)}, Response: Response{StatusCode: 200}, } - err := c.Setup(t).Experimental().DaemonSets(ns).Delete("foo") + err := c.Setup(t).Extensions().DaemonSets(ns).Delete("foo") c.Validate(t, nil, err) } func TestCreateDaemonSet(t *testing.T) { ns := api.NamespaceDefault - requestDaemonSet := &experimental.DaemonSet{ + requestDaemonSet := &extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{Name: "foo"}, } c := &testClient{ - Request: testRequest{Method: "POST", Path: testapi.Experimental.ResourcePath(getDSResourceName(), ns, ""), Body: requestDaemonSet, Query: buildQueryValues(nil)}, + Request: testRequest{Method: "POST", Path: testapi.Extensions.ResourcePath(getDSResourceName(), ns, ""), Body: requestDaemonSet, Query: buildQueryValues(nil)}, Response: Response{ StatusCode: 200, - Body: &experimental.DaemonSet{ + Body: &extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{ Name: "foo", Labels: map[string]string{ @@ -149,12 +178,12 @@ func TestCreateDaemonSet(t *testing.T) { "name": "baz", }, }, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Template: &api.PodTemplateSpec{}, }, }, }, } - receivedDaemonSet, err := c.Setup(t).Experimental().DaemonSets(ns).Create(requestDaemonSet) + receivedDaemonSet, err := c.Setup(t).Extensions().DaemonSets(ns).Create(requestDaemonSet) c.Validate(t, receivedDaemonSet, err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/deployment.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/deployment.go index a4e2924858a8..878f5ee1f212 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/deployment.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/deployment.go @@ -18,7 +18,7 @@ package unversioned import ( "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/watch" @@ -31,22 +31,22 @@ type DeploymentsNamespacer interface { // DeploymentInterface has methods to work with Deployment resources. type DeploymentInterface interface { - List(label labels.Selector, field fields.Selector) (*experimental.DeploymentList, error) - Get(name string) (*experimental.Deployment, error) + List(label labels.Selector, field fields.Selector) (*extensions.DeploymentList, error) + Get(name string) (*extensions.Deployment, error) Delete(name string, options *api.DeleteOptions) error - Create(Deployment *experimental.Deployment) (*experimental.Deployment, error) - Update(Deployment *experimental.Deployment) (*experimental.Deployment, error) + Create(Deployment *extensions.Deployment) (*extensions.Deployment, error) + Update(Deployment *extensions.Deployment) (*extensions.Deployment, error) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) } // deployments implements DeploymentInterface type deployments struct { - client *ExperimentalClient + client *ExtensionsClient ns string } // newDeployments returns a Deployments -func newDeployments(c *ExperimentalClient, namespace string) *deployments { +func newDeployments(c *ExtensionsClient, namespace string) *deployments { return &deployments{ client: c, ns: namespace, @@ -54,15 +54,15 @@ func newDeployments(c *ExperimentalClient, namespace string) *deployments { } // List takes label and field selectors, and returns the list of Deployments that match those selectors. -func (c *deployments) List(label labels.Selector, field fields.Selector) (result *experimental.DeploymentList, err error) { - result = &experimental.DeploymentList{} +func (c *deployments) List(label labels.Selector, field fields.Selector) (result *extensions.DeploymentList, err error) { + result = &extensions.DeploymentList{} err = c.client.Get().Namespace(c.ns).Resource("deployments").LabelsSelectorParam(label).FieldsSelectorParam(field).Do().Into(result) return } // Get takes name of the deployment, and returns the corresponding deployment object, and an error if there is any. -func (c *deployments) Get(name string) (result *experimental.Deployment, err error) { - result = &experimental.Deployment{} +func (c *deployments) Get(name string) (result *extensions.Deployment, err error) { + result = &extensions.Deployment{} err = c.client.Get().Namespace(c.ns).Resource("deployments").Name(name).Do().Into(result) return } @@ -80,15 +80,15 @@ func (c *deployments) Delete(name string, options *api.DeleteOptions) error { } // Create takes the representation of a deployment and creates it. Returns the server's representation of the deployment, and an error, if there is any. -func (c *deployments) Create(deployment *experimental.Deployment) (result *experimental.Deployment, err error) { - result = &experimental.Deployment{} +func (c *deployments) Create(deployment *extensions.Deployment) (result *extensions.Deployment, err error) { + result = &extensions.Deployment{} err = c.client.Post().Namespace(c.ns).Resource("deployments").Body(deployment).Do().Into(result) return } // Update takes the representation of a deployment and updates it. Returns the server's representation of the deployment, and an error, if there is any. -func (c *deployments) Update(deployment *experimental.Deployment) (result *experimental.Deployment, err error) { - result = &experimental.Deployment{} +func (c *deployments) Update(deployment *extensions.Deployment) (result *extensions.Deployment, err error) { + result = &extensions.Deployment{} err = c.client.Put().Namespace(c.ns).Resource("deployments").Name(deployment.Name).Body(deployment).Do().Into(result) return } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/deployment_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/deployment_test.go index 6d41c18248b4..0a94a5f8c9c1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/deployment_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/deployment_test.go @@ -22,7 +22,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" ) @@ -33,7 +33,7 @@ func getDeploymentsResoureName() string { func TestDeploymentCreate(t *testing.T) { ns := api.NamespaceDefault - deployment := experimental.Deployment{ + deployment := extensions.Deployment{ ObjectMeta: api.ObjectMeta{ Name: "abc", Namespace: ns, @@ -42,7 +42,7 @@ func TestDeploymentCreate(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "POST", - Path: testapi.Experimental.ResourcePath(getDeploymentsResoureName(), ns, ""), + Path: testapi.Extensions.ResourcePath(getDeploymentsResoureName(), ns, ""), Query: buildQueryValues(nil), Body: &deployment, }, @@ -58,7 +58,7 @@ func TestDeploymentCreate(t *testing.T) { func TestDeploymentGet(t *testing.T) { ns := api.NamespaceDefault - deployment := &experimental.Deployment{ + deployment := &extensions.Deployment{ ObjectMeta: api.ObjectMeta{ Name: "abc", Namespace: ns, @@ -67,7 +67,7 @@ func TestDeploymentGet(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "GET", - Path: testapi.Experimental.ResourcePath(getDeploymentsResoureName(), ns, "abc"), + Path: testapi.Extensions.ResourcePath(getDeploymentsResoureName(), ns, "abc"), Query: buildQueryValues(nil), Body: nil, }, @@ -80,8 +80,8 @@ func TestDeploymentGet(t *testing.T) { func TestDeploymentList(t *testing.T) { ns := api.NamespaceDefault - deploymentList := &experimental.DeploymentList{ - Items: []experimental.Deployment{ + deploymentList := &extensions.DeploymentList{ + Items: []extensions.Deployment{ { ObjectMeta: api.ObjectMeta{ Name: "foo", @@ -93,7 +93,7 @@ func TestDeploymentList(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "GET", - Path: testapi.Experimental.ResourcePath(getDeploymentsResoureName(), ns, ""), + Path: testapi.Extensions.ResourcePath(getDeploymentsResoureName(), ns, ""), Query: buildQueryValues(nil), Body: nil, }, @@ -105,7 +105,7 @@ func TestDeploymentList(t *testing.T) { func TestDeploymentUpdate(t *testing.T) { ns := api.NamespaceDefault - deployment := &experimental.Deployment{ + deployment := &extensions.Deployment{ ObjectMeta: api.ObjectMeta{ Name: "abc", Namespace: ns, @@ -115,7 +115,7 @@ func TestDeploymentUpdate(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "PUT", - Path: testapi.Experimental.ResourcePath(getDeploymentsResoureName(), ns, "abc"), + Path: testapi.Extensions.ResourcePath(getDeploymentsResoureName(), ns, "abc"), Query: buildQueryValues(nil), }, Response: Response{StatusCode: 200, Body: deployment}, @@ -129,7 +129,7 @@ func TestDeploymentDelete(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "DELETE", - Path: testapi.Experimental.ResourcePath(getDeploymentsResoureName(), ns, "foo"), + Path: testapi.Extensions.ResourcePath(getDeploymentsResoureName(), ns, "foo"), Query: buildQueryValues(nil), }, Response: Response{StatusCode: 200}, @@ -142,7 +142,7 @@ func TestDeploymentWatch(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "GET", - Path: testapi.Experimental.ResourcePathWithPrefix("watch", getDeploymentsResoureName(), "", ""), + Path: testapi.Extensions.ResourcePathWithPrefix("watch", getDeploymentsResoureName(), "", ""), Query: url.Values{"resourceVersion": []string{}}, }, Response: Response{StatusCode: 200}, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/doc.go index 210f9916064b..f9c7f16e712a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/doc.go @@ -15,14 +15,14 @@ limitations under the License. */ /* -Package client contains the implementation of the client side communication with the +Package unversioned contains the implementation of the client side communication with the Kubernetes master. The Client class provides methods for reading, creating, updating, -and deleting pods, replication controllers, daemons, services, and minions. +and deleting pods, replication controllers, daemons, services, and nodes. Most consumers should use the Config object to create a Client: import ( - "k8s.io/kubernetes/pkg/client" + client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -52,7 +52,7 @@ More advanced consumers may wish to provide their own transport via a http.Round } client, err := client.New(config) -The RESTClient type implements the Kubernetes API conventions (see `docs/api-conventions.md`) +The RESTClient type implements the Kubernetes API conventions (see `docs/devel/api-conventions.md`) for a given API path and is intended for use by consumers implementing their own Kubernetes compatible APIs. */ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/events.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/events.go index c37bcf178002..6094f9773b11 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/events.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/events.go @@ -35,6 +35,7 @@ type EventNamespacer interface { type EventInterface interface { Create(event *api.Event) (*api.Event, error) Update(event *api.Event) (*api.Event, error) + Patch(event *api.Event, data []byte) (*api.Event, error) List(label labels.Selector, field fields.Selector) (*api.EventList, error) Get(name string) (*api.Event, error) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) @@ -98,6 +99,22 @@ func (e *events) Update(event *api.Event) (*api.Event, error) { return result, err } +// Patch modifies an existing event. It returns the copy of the event that the server returns, or an +// error. The namespace and name of the target event is deduced from the incompleteEvent. The +// namespace must either match this event client's namespace, or this event client must have been +// created with the "" namespace. +func (e *events) Patch(incompleteEvent *api.Event, data []byte) (*api.Event, error) { + result := &api.Event{} + err := e.client.Patch(api.StrategicMergePatchType). + NamespaceIfScoped(incompleteEvent.Namespace, len(incompleteEvent.Namespace) > 0). + Resource("events"). + Name(incompleteEvent.Name). + Body(data). + Do(). + Into(result) + return result, err +} + // List returns a list of events matching the selectors. func (e *events) List(label labels.Selector, field fields.Selector) (*api.EventList, error) { result := &api.EventList{} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/events_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/events_test.go index e8d7de4957e1..40ec69963749 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/events_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/events_test.go @@ -23,9 +23,9 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/util" ) func TestEventSearch(t *testing.T) { @@ -34,12 +34,12 @@ func TestEventSearch(t *testing.T) { Method: "GET", Path: testapi.Default.ResourcePath("events", "baz", ""), Query: url.Values{ - api.FieldSelectorQueryParam(testapi.Default.Version()): []string{ + unversioned.FieldSelectorQueryParam(testapi.Default.Version()): []string{ getInvolvedObjectNameFieldLabel(testapi.Default.Version()) + "=foo,", "involvedObject.namespace=baz,", "involvedObject.kind=Pod", }, - api.LabelSelectorQueryParam(testapi.Default.Version()): []string{}, + unversioned.LabelSelectorQueryParam(testapi.Default.Version()): []string{}, }, }, Response: Response{StatusCode: 200, Body: &api.EventList{}}, @@ -65,7 +65,7 @@ func TestEventCreate(t *testing.T) { APIVersion: "apiv1", ResourceVersion: "1", } - timeStamp := util.Now() + timeStamp := unversioned.Now() event := &api.Event{ ObjectMeta: api.ObjectMeta{ Namespace: api.NamespaceDefault, @@ -104,7 +104,7 @@ func TestEventGet(t *testing.T) { APIVersion: "apiv1", ResourceVersion: "1", } - timeStamp := util.Now() + timeStamp := unversioned.Now() event := &api.Event{ ObjectMeta: api.ObjectMeta{ Namespace: "other", @@ -144,7 +144,7 @@ func TestEventList(t *testing.T) { APIVersion: "apiv1", ResourceVersion: "1", } - timeStamp := util.Now() + timeStamp := unversioned.Now() eventList := &api.EventList{ Items: []api.Event{ { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/experimental.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/extensions.go similarity index 50% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/experimental.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/extensions.go index 00f33daa1c05..dba43f575ac3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/experimental.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/extensions.go @@ -21,32 +21,34 @@ import ( "fmt" "strings" - "k8s.io/kubernetes/pkg/api" - explatest "k8s.io/kubernetes/pkg/apis/experimental/latest" + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/version" ) // Interface holds the experimental methods for clients of Kubernetes // to allow mock testing. -// Experimental features are not supported and may be changed or removed in +// Features of Extensions group are not supported and may be changed or removed in // incompatible ways at any time. -type ExperimentalInterface interface { +type ExtensionsInterface interface { VersionInterface HorizontalPodAutoscalersNamespacer ScaleNamespacer DaemonSetsNamespacer DeploymentsNamespacer + JobsNamespacer + IngressNamespacer } -// ExperimentalClient is used to interact with experimental Kubernetes features. -// Experimental features are not supported and may be changed or removed in +// ExtensionsClient is used to interact with experimental Kubernetes features. +// Features of Extensions group are not supported and may be changed or removed in // incompatible ways at any time. -type ExperimentalClient struct { +type ExtensionsClient struct { *RESTClient } // ServerVersion retrieves and parses the server's version. -func (c *ExperimentalClient) ServerVersion() (*version.Info, error) { +func (c *ExtensionsClient) ServerVersion() (*version.Info, error) { body, err := c.Get().AbsPath("/version").Do().Raw() if err != nil { return nil, err @@ -61,12 +63,12 @@ func (c *ExperimentalClient) ServerVersion() (*version.Info, error) { // ServerAPIVersions retrieves and parses the list of experimental API versions the // server supports. -func (c *ExperimentalClient) ServerAPIVersions() (*api.APIVersions, error) { +func (c *ExtensionsClient) ServerAPIVersions() (*unversioned.APIVersions, error) { body, err := c.Get().UnversionedPath("").Do().Raw() if err != nil { return nil, err } - var v api.APIVersions + var v unversioned.APIVersions err = json.Unmarshal(body, &v) if err != nil { return nil, fmt.Errorf("got '%s': %v", string(body), err) @@ -74,66 +76,79 @@ func (c *ExperimentalClient) ServerAPIVersions() (*api.APIVersions, error) { return &v, nil } -func (c *ExperimentalClient) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerInterface { +func (c *ExtensionsClient) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerInterface { return newHorizontalPodAutoscalers(c, namespace) } -func (c *ExperimentalClient) Scales(namespace string) ScaleInterface { +func (c *ExtensionsClient) Scales(namespace string) ScaleInterface { return newScales(c, namespace) } -func (c *ExperimentalClient) DaemonSets(namespace string) DaemonSetInterface { +func (c *ExtensionsClient) DaemonSets(namespace string) DaemonSetInterface { return newDaemonSets(c, namespace) } -func (c *ExperimentalClient) Deployments(namespace string) DeploymentInterface { +func (c *ExtensionsClient) Deployments(namespace string) DeploymentInterface { return newDeployments(c, namespace) } -// NewExperimental creates a new ExperimentalClient for the given config. This client +func (c *ExtensionsClient) Jobs(namespace string) JobInterface { + return newJobs(c, namespace) +} + +func (c *ExtensionsClient) Ingress(namespace string) IngressInterface { + return newIngress(c, namespace) +} + +// NewExtensions creates a new ExtensionsClient for the given config. This client // provides access to experimental Kubernetes features. -// Experimental features are not supported and may be changed or removed in +// Features of Extensions group are not supported and may be changed or removed in // incompatible ways at any time. -func NewExperimental(c *Config) (*ExperimentalClient, error) { +func NewExtensions(c *Config) (*ExtensionsClient, error) { config := *c - if err := setExperimentalDefaults(&config); err != nil { + if err := setExtensionsDefaults(&config); err != nil { return nil, err } client, err := RESTClientFor(&config) if err != nil { return nil, err } - return &ExperimentalClient{client}, nil + return &ExtensionsClient{client}, nil } -// NewExperimentalOrDie creates a new ExperimentalClient for the given config and +// NewExtensionsOrDie creates a new ExtensionsClient for the given config and // panics if there is an error in the config. -// Experimental features are not supported and may be changed or removed in +// Features of Extensions group are not supported and may be changed or removed in // incompatible ways at any time. -func NewExperimentalOrDie(c *Config) *ExperimentalClient { - client, err := NewExperimental(c) +func NewExtensionsOrDie(c *Config) *ExtensionsClient { + client, err := NewExtensions(c) if err != nil { panic(err) } return client } -func setExperimentalDefaults(config *Config) error { - config.Prefix = "/experimental" +func setExtensionsDefaults(config *Config) error { + // if experimental group is not registered, return an error + g, err := latest.Group("extensions") + if err != nil { + return err + } + config.Prefix = "apis/" if config.UserAgent == "" { config.UserAgent = DefaultKubernetesUserAgent() } - if config.Version == "" { - config.Version = explatest.Version - } - versionInterfaces, err := explatest.InterfacesFor(config.Version) + // TODO: Unconditionally set the config.Version, until we fix the config. + //if config.Version == "" { + config.Version = g.GroupVersion + //} + + versionInterfaces, err := g.InterfacesFor(config.Version) if err != nil { - return fmt.Errorf("Experimental API version '%s' is not recognized (valid values: %s)", - config.Version, strings.Join(explatest.Versions, ", ")) - } - if config.Codec == nil { - config.Codec = versionInterfaces.Codec + return fmt.Errorf("Extensions API version '%s' is not recognized (valid values: %s)", + config.Version, strings.Join(latest.GroupOrDie("extensions").Versions, ", ")) } + config.Codec = versionInterfaces.Codec if config.QPS == 0 { config.QPS = 5 } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/fake.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/fake.go deleted file mode 100644 index a52cdb097277..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/fake.go +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 unversioned - -import ( - "net/http" - "net/url" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/runtime" -) - -type HTTPClientFunc func(*http.Request) (*http.Response, error) - -func (f HTTPClientFunc) Do(req *http.Request) (*http.Response, error) { - return f(req) -} - -// FakeRESTClient provides a fake RESTClient interface. -type FakeRESTClient struct { - Client HTTPClient - Codec runtime.Codec - Req *http.Request - Resp *http.Response - Err error -} - -func (c *FakeRESTClient) Get() *Request { - return NewRequest(c, "GET", &url.URL{Host: "localhost"}, testapi.Default.Version(), c.Codec) -} - -func (c *FakeRESTClient) Put() *Request { - return NewRequest(c, "PUT", &url.URL{Host: "localhost"}, testapi.Default.Version(), c.Codec) -} - -func (c *FakeRESTClient) Patch(_ api.PatchType) *Request { - return NewRequest(c, "PATCH", &url.URL{Host: "localhost"}, testapi.Default.Version(), c.Codec) -} - -func (c *FakeRESTClient) Post() *Request { - return NewRequest(c, "POST", &url.URL{Host: "localhost"}, testapi.Default.Version(), c.Codec) -} - -func (c *FakeRESTClient) Delete() *Request { - return NewRequest(c, "DELETE", &url.URL{Host: "localhost"}, testapi.Default.Version(), c.Codec) -} - -func (c *FakeRESTClient) Do(req *http.Request) (*http.Response, error) { - c.Req = req - if c.Client != HTTPClient(nil) { - return c.Client.Do(req) - } - return c.Resp, c.Err -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/fake/fake.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/fake/fake.go new file mode 100644 index 000000000000..8e77910a6492 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/fake/fake.go @@ -0,0 +1,72 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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. +*/ + +// This is made a separate package and should only be imported by tests, because +// it imports testapi +package fake + +import ( + "net/http" + "net/url" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/runtime" +) + +type HTTPClientFunc func(*http.Request) (*http.Response, error) + +func (f HTTPClientFunc) Do(req *http.Request) (*http.Response, error) { + return f(req) +} + +// RESTClient provides a fake RESTClient interface. +type RESTClient struct { + Client unversioned.HTTPClient + Codec runtime.Codec + Req *http.Request + Resp *http.Response + Err error +} + +func (c *RESTClient) Get() *unversioned.Request { + return unversioned.NewRequest(c, "GET", &url.URL{Host: "localhost"}, testapi.Default.Version(), c.Codec) +} + +func (c *RESTClient) Put() *unversioned.Request { + return unversioned.NewRequest(c, "PUT", &url.URL{Host: "localhost"}, testapi.Default.Version(), c.Codec) +} + +func (c *RESTClient) Patch(_ api.PatchType) *unversioned.Request { + return unversioned.NewRequest(c, "PATCH", &url.URL{Host: "localhost"}, testapi.Default.Version(), c.Codec) +} + +func (c *RESTClient) Post() *unversioned.Request { + return unversioned.NewRequest(c, "POST", &url.URL{Host: "localhost"}, testapi.Default.Version(), c.Codec) +} + +func (c *RESTClient) Delete() *unversioned.Request { + return unversioned.NewRequest(c, "DELETE", &url.URL{Host: "localhost"}, testapi.Default.Version(), c.Codec) +} + +func (c *RESTClient) Do(req *http.Request) (*http.Response, error) { + c.Req = req + if c.Client != unversioned.HTTPClient(nil) { + return c.Client.Do(req) + } + return c.Resp, c.Err +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper.go index dc83828bc096..3e938ea4cdec 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper.go @@ -17,6 +17,7 @@ limitations under the License. package unversioned import ( + "encoding/json" "fmt" "io/ioutil" "net" @@ -33,6 +34,7 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" @@ -143,15 +145,16 @@ func New(c *Config) (*Client, error) { if err != nil { return nil, err } + + if _, err := latest.Group("extensions"); err != nil { + return &Client{RESTClient: client, ExtensionsClient: nil}, nil + } experimentalConfig := *c - // clearing Version from the config so that the --api-version flag will work. This may or may not be unborked after the next rebase - // but they are working on the issue in: https://github.com/kubernetes/kubernetes/pull/14383 - experimentalConfig.Version = "" - experimentalClient, err := NewExperimental(&experimentalConfig) + experimentalClient, err := NewExtensions(&experimentalConfig) if err != nil { return nil, err } - return &Client{RESTClient: client, ExperimentalClient: experimentalClient}, nil + return &Client{RESTClient: client, ExtensionsClient: experimentalClient}, nil } // MatchesServerVersion queries the server to compares the build version @@ -177,6 +180,65 @@ func MatchesServerVersion(client *Client, c *Config) error { return nil } +func extractGroupVersions(l *unversioned.APIGroupList) []string { + var groupVersions []string + for _, g := range l.Groups { + for _, gv := range g.Versions { + groupVersions = append(groupVersions, gv.GroupVersion) + } + } + return groupVersions +} + +// ServerAPIVersions returns the GroupVersions supported by the API server. +// It creates a RESTClient based on the passed in config, but it doesn't rely +// on the Version, Codec, and Prefix of the config, because it uses AbsPath and +// takes the raw response. +func ServerAPIVersions(c *Config) (groupVersions []string, err error) { + transport, err := TransportFor(c) + if err != nil { + return nil, err + } + client := http.Client{Transport: transport} + + configCopy := *c + configCopy.Version = "" + configCopy.Prefix = "" + baseURL, err := defaultServerUrlFor(c) + if err != nil { + return nil, err + } + // Get the groupVersions exposed at /api + baseURL.Path = "/api" + resp, err := client.Get(baseURL.String()) + if err != nil { + return nil, err + } + var v unversioned.APIVersions + defer resp.Body.Close() + err = json.NewDecoder(resp.Body).Decode(&v) + if err != nil { + return nil, fmt.Errorf("unexpected error: %v", err) + } + + groupVersions = append(groupVersions, v.Versions...) + // Get the groupVersions exposed at /apis + baseURL.Path = "/apis" + resp2, err := client.Get(baseURL.String()) + if err != nil { + return nil, err + } + var apiGroupList unversioned.APIGroupList + defer resp2.Body.Close() + err = json.NewDecoder(resp2.Body).Decode(&apiGroupList) + if err != nil { + return nil, fmt.Errorf("unexpected error: %v", err) + } + groupVersions = append(groupVersions, extractGroupVersions(&apiGroupList)...) + + return groupVersions, nil +} + // NegotiateVersion queries the server's supported api versions to find // a version that both client and server support. // - If no version is provided, try registered client versions in order of @@ -230,9 +292,11 @@ func NegotiateVersion(client *Client, c *Config, version string, clientRegistere if serverVersions.Has(clientVersion) { // Version was not explicitly requested in command config (--api-version). // Ok to fall back to a supported version with a warning. - if len(version) != 0 { - glog.Warningf("Server does not support API version '%s'. Falling back to '%s'.", version, clientVersion) - } + // TODO: caesarxuchao: enable the warning message when we have + // proper fix. Please refer to issue #14895. + // if len(version) != 0 { + // glog.Warningf("Server does not support API version '%s'. Falling back to '%s'.", version, clientVersion) + // } return clientVersion, nil } } @@ -261,7 +325,7 @@ func InClusterConfig() (*Config, error) { tlsClientConfig := TLSClientConfig{} rootCAFile := "/var/run/secrets/kubernetes.io/serviceaccount/" + api.ServiceAccountRootCAKey if _, err := util.CertPoolFromFile(rootCAFile); err != nil { - glog.Errorf("expected to load root CA config from %s, but got err: %v", rootCAFile, err) + glog.Errorf("Expected to load root CA config from %s, but got err: %v", rootCAFile, err) } else { tlsClientConfig.CAFile = rootCAFile } @@ -285,6 +349,7 @@ func NewInCluster() (*Client, error) { // SetKubernetesDefaults sets default values on the provided client config for accessing the // Kubernetes API or returns an error if any of the defaults are impossible or invalid. +// TODO: this method needs to be split into one that sets defaults per group, expected to be fix in PR "Refactoring clientcache.go and helper.go #14592" func SetKubernetesDefaults(config *Config) error { if config.Prefix == "" { config.Prefix = "/api" @@ -296,9 +361,9 @@ func SetKubernetesDefaults(config *Config) error { config.Version = defaultVersionFor(config) } version := config.Version - versionInterfaces, err := latest.InterfacesFor(version) + versionInterfaces, err := latest.GroupOrDie("").InterfacesFor(version) if err != nil { - return fmt.Errorf("API version '%s' is not recognized (valid values: %s)", version, strings.Join(latest.Versions, ", ")) + return fmt.Errorf("API version '%s' is not recognized (valid values: %s)", version, strings.Join(latest.GroupOrDie("").Versions, ", ")) } if config.Codec == nil { config.Codec = versionInterfaces.Codec @@ -380,15 +445,9 @@ func tlsTransportFor(config *Config) (http.RoundTripper, error) { } // Cache a single transport for these options - tlsTransports[key] = &http.Transport{ + tlsTransports[key] = util.SetTransportDefaults(&http.Transport{ TLSClientConfig: tlsConfig, - Proxy: http.ProxyFromEnvironment, - Dial: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - TLSHandshakeTimeout: 10 * time.Second, - } + }) return tlsTransports[key], nil } @@ -473,9 +532,6 @@ func DefaultServerURL(host, prefix, version string, defaultTLS bool) (*url.URL, if host == "" { return nil, fmt.Errorf("host must be a URL or a host:port pair") } - if version == "" { - return nil, fmt.Errorf("version must be set") - } base := host hostURL, err := url.Parse(base) if err != nil { @@ -510,7 +566,7 @@ func DefaultServerURL(host, prefix, version string, defaultTLS bool) (*url.URL, return hostURL, nil } -// IsConfigTransportTLS returns true iff the provided config will result in a protected +// IsConfigTransportTLS returns true if and only if the provided config will result in a protected // connection to the server when it is passed to client.New() or client.RESTClientFor(). // Use to determine when to send credentials over the wire. // @@ -549,7 +605,7 @@ func defaultVersionFor(config *Config) string { if version == "" { // Clients default to the preferred code API version // TODO: implement version negotiation (highest version supported by server) - version = latest.Version + version = latest.GroupOrDie("").Version } return version } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper_blackbox_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper_blackbox_test.go new file mode 100644 index 000000000000..23c30b086ed5 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper_blackbox_test.go @@ -0,0 +1,112 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned_test + +import ( + "bytes" + "encoding/json" + "io" + "io/ioutil" + "net/http" + "testing" + + "k8s.io/kubernetes/pkg/api/testapi" + unversioned_api "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" +) + +func objBody(object interface{}) io.ReadCloser { + output, err := json.MarshalIndent(object, "", "") + if err != nil { + panic(err) + } + return ioutil.NopCloser(bytes.NewReader([]byte(output))) +} + +func TestNegotiateVersion(t *testing.T) { + tests := []struct { + name, version, expectedVersion string + serverVersions []string + clientVersions []string + config *unversioned.Config + expectErr bool + }{ + { + name: "server supports client default", + version: "version1", + config: &unversioned.Config{}, + serverVersions: []string{"version1", testapi.Default.Version()}, + clientVersions: []string{"version1", testapi.Default.Version()}, + expectedVersion: "version1", + expectErr: false, + }, + { + name: "server falls back to client supported", + version: testapi.Default.Version(), + config: &unversioned.Config{}, + serverVersions: []string{"version1"}, + clientVersions: []string{"version1", testapi.Default.Version()}, + expectedVersion: "version1", + expectErr: false, + }, + { + name: "explicit version supported", + version: "", + config: &unversioned.Config{Version: testapi.Default.Version()}, + serverVersions: []string{"version1", testapi.Default.Version()}, + clientVersions: []string{"version1", testapi.Default.Version()}, + expectedVersion: testapi.Default.Version(), + expectErr: false, + }, + { + name: "explicit version not supported", + version: "", + config: &unversioned.Config{Version: testapi.Default.Version()}, + serverVersions: []string{"version1"}, + clientVersions: []string{"version1", testapi.Default.Version()}, + expectedVersion: "", + expectErr: true, + }, + } + codec := testapi.Default.Codec() + + for _, test := range tests { + fakeClient := &fake.RESTClient{ + Codec: codec, + Resp: &http.Response{ + StatusCode: 200, + Body: objBody(&unversioned_api.APIVersions{Versions: test.serverVersions}), + }, + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + return &http.Response{StatusCode: 200, Body: objBody(&unversioned_api.APIVersions{Versions: test.serverVersions})}, nil + }), + } + c := unversioned.NewOrDie(test.config) + c.Client = fakeClient.Client + response, err := unversioned.NegotiateVersion(c, test.config, test.version, test.clientVersions) + if err == nil && test.expectErr { + t.Errorf("expected error, got nil for [%s].", test.name) + } + if err != nil && !test.expectErr { + t.Errorf("unexpected error for [%s]: %v.", test.name, err) + } + if response != test.expectedVersion { + t.Errorf("expected version %s, got %s.", test.expectedVersion, response) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper_test.go index a81c5d9a6126..fe4365245d22 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/helper_test.go @@ -17,18 +17,15 @@ limitations under the License. package unversioned import ( - "bytes" "encoding/json" - "io" - "io/ioutil" "net/http" + "net/http/httptest" "reflect" "strings" "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" ) const ( @@ -222,7 +219,7 @@ func TestTLSTransportCache(t *testing.T) { "host": {Insecure: true, Host: "foo"}, "prefix": {Insecure: true, Prefix: "foo"}, "version": {Insecure: true, Version: "foo"}, - "codec": {Insecure: true, Codec: latest.Codec}, + "codec": {Insecure: true, Codec: testapi.Default.Codec()}, "basic": {Insecure: true, Username: "bob", Password: "password"}, "bearer": {Insecure: true, BearerToken: "token"}, "user agent": {Insecure: true, UserAgent: "useragent"}, @@ -336,8 +333,8 @@ func TestSetKubernetesDefaults(t *testing.T) { Config{}, Config{ Prefix: "/api", - Version: latest.Version, - Codec: latest.Codec, + Version: testapi.Default.Version(), + Codec: testapi.Default.Codec(), QPS: 5, Burst: 10, }, @@ -381,83 +378,58 @@ func TestSetKubernetesDefaultsUserAgent(t *testing.T) { } } -func objBody(object interface{}) io.ReadCloser { - output, err := json.MarshalIndent(object, "", "") - if err != nil { - panic(err) - } - return ioutil.NopCloser(bytes.NewReader([]byte(output))) -} - -func TestNegotiateVersion(t *testing.T) { - tests := []struct { - name, version, expectedVersion string - serverVersions []string - clientVersions []string - config *Config - expectErr bool - }{ - { - name: "server supports client default", - version: "version1", - config: &Config{}, - serverVersions: []string{"version1", testapi.Default.Version()}, - clientVersions: []string{"version1", testapi.Default.Version()}, - expectedVersion: "version1", - expectErr: false, - }, - { - name: "server falls back to client supported", - version: testapi.Default.Version(), - config: &Config{}, - serverVersions: []string{"version1"}, - clientVersions: []string{"version1", testapi.Default.Version()}, - expectedVersion: "version1", - expectErr: false, - }, - { - name: "explicit version supported", - version: "", - config: &Config{Version: testapi.Default.Version()}, - serverVersions: []string{"version1", testapi.Default.Version()}, - clientVersions: []string{"version1", testapi.Default.Version()}, - expectedVersion: testapi.Default.Version(), - expectErr: false, - }, - { - name: "explicit version not supported", - version: "", - config: &Config{Version: testapi.Default.Version()}, - serverVersions: []string{"version1"}, - clientVersions: []string{"version1", testapi.Default.Version()}, - expectedVersion: "", - expectErr: true, +func TestHelperGetServerAPIVersions(t *testing.T) { + expect := []string{"v1", "v2", "v3"} + APIVersions := unversioned.APIVersions{Versions: expect} + expect = append(expect, "group1/v1", "group1/v2", "group2/v1", "group2/v2") + APIGroupList := unversioned.APIGroupList{ + Groups: []unversioned.APIGroup{ + { + Versions: []unversioned.GroupVersion{ + { + GroupVersion: "group1/v1", + }, + { + GroupVersion: "group1/v2", + }, + }, + }, + { + Versions: []unversioned.GroupVersion{ + { + GroupVersion: "group2/v1", + }, + { + GroupVersion: "group2/v2", + }, + }, + }, }, } - codec := testapi.Default.Codec() + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + var output []byte + var err error + switch req.URL.Path { + case "/api": + output, err = json.Marshal(APIVersions) - for _, test := range tests { - fakeClient := &FakeRESTClient{ - Codec: codec, - Resp: &http.Response{ - StatusCode: 200, - Body: objBody(&api.APIVersions{Versions: test.serverVersions}), - }, - Client: HTTPClientFunc(func(req *http.Request) (*http.Response, error) { - return &http.Response{StatusCode: 200, Body: objBody(&api.APIVersions{Versions: test.serverVersions})}, nil - }), + case "/apis": + output, err = json.Marshal(APIGroupList) } - c := NewOrDie(test.config) - c.Client = fakeClient.Client - response, err := NegotiateVersion(c, test.config, test.version, test.clientVersions) - if err == nil && test.expectErr { - t.Errorf("expected error, got nil for [%s].", test.name) - } - if err != nil && !test.expectErr { - t.Errorf("unexpected error for [%s]: %v.", test.name, err) - } - if response != test.expectedVersion { - t.Errorf("expected version %s, got %s.", test.expectedVersion, response) + if err != nil { + t.Errorf("unexpected encoding error: %v", err) + return } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(output) + })) + got, err := ServerAPIVersions(&Config{Host: server.URL, Version: "invalid version", Codec: testapi.Default.Codec()}) + if err != nil { + t.Fatalf("unexpected encoding error: %v", err) + } + if e, a := expect, got; !reflect.DeepEqual(e, a) { + t.Errorf("expected %v, got %v", e, a) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/horizontalpodautoscaler.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/horizontalpodautoscaler.go index 94f8030b64ad..af98c99df9be 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/horizontalpodautoscaler.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/horizontalpodautoscaler.go @@ -18,7 +18,7 @@ package unversioned import ( "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/watch" @@ -31,22 +31,23 @@ type HorizontalPodAutoscalersNamespacer interface { // HorizontalPodAutoscalerInterface has methods to work with HorizontalPodAutoscaler resources. type HorizontalPodAutoscalerInterface interface { - List(label labels.Selector, field fields.Selector) (*experimental.HorizontalPodAutoscalerList, error) - Get(name string) (*experimental.HorizontalPodAutoscaler, error) + List(label labels.Selector, field fields.Selector) (*extensions.HorizontalPodAutoscalerList, error) + Get(name string) (*extensions.HorizontalPodAutoscaler, error) Delete(name string, options *api.DeleteOptions) error - Create(horizontalPodAutoscaler *experimental.HorizontalPodAutoscaler) (*experimental.HorizontalPodAutoscaler, error) - Update(horizontalPodAutoscaler *experimental.HorizontalPodAutoscaler) (*experimental.HorizontalPodAutoscaler, error) + Create(horizontalPodAutoscaler *extensions.HorizontalPodAutoscaler) (*extensions.HorizontalPodAutoscaler, error) + Update(horizontalPodAutoscaler *extensions.HorizontalPodAutoscaler) (*extensions.HorizontalPodAutoscaler, error) + UpdateStatus(horizontalPodAutoscaler *extensions.HorizontalPodAutoscaler) (*extensions.HorizontalPodAutoscaler, error) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) } // horizontalPodAutoscalers implements HorizontalPodAutoscalersNamespacer interface type horizontalPodAutoscalers struct { - client *ExperimentalClient + client *ExtensionsClient ns string } // newHorizontalPodAutoscalers returns a horizontalPodAutoscalers -func newHorizontalPodAutoscalers(c *ExperimentalClient, namespace string) *horizontalPodAutoscalers { +func newHorizontalPodAutoscalers(c *ExtensionsClient, namespace string) *horizontalPodAutoscalers { return &horizontalPodAutoscalers{ client: c, ns: namespace, @@ -54,15 +55,15 @@ func newHorizontalPodAutoscalers(c *ExperimentalClient, namespace string) *horiz } // List takes label and field selectors, and returns the list of horizontalPodAutoscalers that match those selectors. -func (c *horizontalPodAutoscalers) List(label labels.Selector, field fields.Selector) (result *experimental.HorizontalPodAutoscalerList, err error) { - result = &experimental.HorizontalPodAutoscalerList{} +func (c *horizontalPodAutoscalers) List(label labels.Selector, field fields.Selector) (result *extensions.HorizontalPodAutoscalerList, err error) { + result = &extensions.HorizontalPodAutoscalerList{} err = c.client.Get().Namespace(c.ns).Resource("horizontalPodAutoscalers").LabelsSelectorParam(label).FieldsSelectorParam(field).Do().Into(result) return } // Get takes the name of the horizontalPodAutoscaler, and returns the corresponding HorizontalPodAutoscaler object, and an error if it occurs -func (c *horizontalPodAutoscalers) Get(name string) (result *experimental.HorizontalPodAutoscaler, err error) { - result = &experimental.HorizontalPodAutoscaler{} +func (c *horizontalPodAutoscalers) Get(name string) (result *extensions.HorizontalPodAutoscaler, err error) { + result = &extensions.HorizontalPodAutoscaler{} err = c.client.Get().Namespace(c.ns).Resource("horizontalPodAutoscalers").Name(name).Do().Into(result) return } @@ -81,19 +82,26 @@ func (c *horizontalPodAutoscalers) Delete(name string, options *api.DeleteOption } // Create takes the representation of a horizontalPodAutoscaler and creates it. Returns the server's representation of the horizontalPodAutoscaler, and an error, if it occurs. -func (c *horizontalPodAutoscalers) Create(horizontalPodAutoscaler *experimental.HorizontalPodAutoscaler) (result *experimental.HorizontalPodAutoscaler, err error) { - result = &experimental.HorizontalPodAutoscaler{} +func (c *horizontalPodAutoscalers) Create(horizontalPodAutoscaler *extensions.HorizontalPodAutoscaler) (result *extensions.HorizontalPodAutoscaler, err error) { + result = &extensions.HorizontalPodAutoscaler{} err = c.client.Post().Namespace(c.ns).Resource("horizontalPodAutoscalers").Body(horizontalPodAutoscaler).Do().Into(result) return } // Update takes the representation of a horizontalPodAutoscaler and updates it. Returns the server's representation of the horizontalPodAutoscaler, and an error, if it occurs. -func (c *horizontalPodAutoscalers) Update(horizontalPodAutoscaler *experimental.HorizontalPodAutoscaler) (result *experimental.HorizontalPodAutoscaler, err error) { - result = &experimental.HorizontalPodAutoscaler{} +func (c *horizontalPodAutoscalers) Update(horizontalPodAutoscaler *extensions.HorizontalPodAutoscaler) (result *extensions.HorizontalPodAutoscaler, err error) { + result = &extensions.HorizontalPodAutoscaler{} err = c.client.Put().Namespace(c.ns).Resource("horizontalPodAutoscalers").Name(horizontalPodAutoscaler.Name).Body(horizontalPodAutoscaler).Do().Into(result) return } +// UpdateStatus takes the representation of a horizontalPodAutoscaler and updates it. Returns the server's representation of the horizontalPodAutoscaler, and an error, if it occurs. +func (c *horizontalPodAutoscalers) UpdateStatus(horizontalPodAutoscaler *extensions.HorizontalPodAutoscaler) (result *extensions.HorizontalPodAutoscaler, err error) { + result = &extensions.HorizontalPodAutoscaler{} + err = c.client.Put().Namespace(c.ns).Resource("horizontalPodAutoscalers").Name(horizontalPodAutoscaler.Name).SubResource("status").Body(horizontalPodAutoscaler).Do().Into(result) + return +} + // Watch returns a watch.Interface that watches the requested horizontalPodAutoscalers. func (c *horizontalPodAutoscalers) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { return c.client.Get(). diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/horizontalpodautoscaler_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/horizontalpodautoscaler_test.go index 020defc813af..42b8f7639ca8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/horizontalpodautoscaler_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/horizontalpodautoscaler_test.go @@ -22,7 +22,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" ) @@ -33,7 +33,7 @@ func getHorizontalPodAutoscalersResoureName() string { func TestHorizontalPodAutoscalerCreate(t *testing.T) { ns := api.NamespaceDefault - horizontalPodAutoscaler := experimental.HorizontalPodAutoscaler{ + horizontalPodAutoscaler := extensions.HorizontalPodAutoscaler{ ObjectMeta: api.ObjectMeta{ Name: "abc", Namespace: ns, @@ -42,14 +42,14 @@ func TestHorizontalPodAutoscalerCreate(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "POST", - Path: testapi.Experimental.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, ""), + Path: testapi.Extensions.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, ""), Query: buildQueryValues(nil), Body: &horizontalPodAutoscaler, }, Response: Response{StatusCode: 200, Body: &horizontalPodAutoscaler}, } - response, err := c.Setup(t).Experimental().HorizontalPodAutoscalers(ns).Create(&horizontalPodAutoscaler) + response, err := c.Setup(t).Extensions().HorizontalPodAutoscalers(ns).Create(&horizontalPodAutoscaler) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -58,7 +58,7 @@ func TestHorizontalPodAutoscalerCreate(t *testing.T) { func TestHorizontalPodAutoscalerGet(t *testing.T) { ns := api.NamespaceDefault - horizontalPodAutoscaler := &experimental.HorizontalPodAutoscaler{ + horizontalPodAutoscaler := &extensions.HorizontalPodAutoscaler{ ObjectMeta: api.ObjectMeta{ Name: "abc", Namespace: ns, @@ -67,21 +67,21 @@ func TestHorizontalPodAutoscalerGet(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "GET", - Path: testapi.Experimental.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, "abc"), + Path: testapi.Extensions.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, "abc"), Query: buildQueryValues(nil), Body: nil, }, Response: Response{StatusCode: 200, Body: horizontalPodAutoscaler}, } - response, err := c.Setup(t).Experimental().HorizontalPodAutoscalers(ns).Get("abc") + response, err := c.Setup(t).Extensions().HorizontalPodAutoscalers(ns).Get("abc") c.Validate(t, response, err) } func TestHorizontalPodAutoscalerList(t *testing.T) { ns := api.NamespaceDefault - horizontalPodAutoscalerList := &experimental.HorizontalPodAutoscalerList{ - Items: []experimental.HorizontalPodAutoscaler{ + horizontalPodAutoscalerList := &extensions.HorizontalPodAutoscalerList{ + Items: []extensions.HorizontalPodAutoscaler{ { ObjectMeta: api.ObjectMeta{ Name: "foo", @@ -93,19 +93,19 @@ func TestHorizontalPodAutoscalerList(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "GET", - Path: testapi.Experimental.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, ""), + Path: testapi.Extensions.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, ""), Query: buildQueryValues(nil), Body: nil, }, Response: Response{StatusCode: 200, Body: horizontalPodAutoscalerList}, } - response, err := c.Setup(t).Experimental().HorizontalPodAutoscalers(ns).List(labels.Everything(), fields.Everything()) + response, err := c.Setup(t).Extensions().HorizontalPodAutoscalers(ns).List(labels.Everything(), fields.Everything()) c.Validate(t, response, err) } func TestHorizontalPodAutoscalerUpdate(t *testing.T) { ns := api.NamespaceDefault - horizontalPodAutoscaler := &experimental.HorizontalPodAutoscaler{ + horizontalPodAutoscaler := &extensions.HorizontalPodAutoscaler{ ObjectMeta: api.ObjectMeta{ Name: "abc", Namespace: ns, @@ -113,20 +113,37 @@ func TestHorizontalPodAutoscalerUpdate(t *testing.T) { }, } c := &testClient{ - Request: testRequest{Method: "PUT", Path: testapi.Experimental.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, "abc"), Query: buildQueryValues(nil)}, + Request: testRequest{Method: "PUT", Path: testapi.Extensions.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, "abc"), Query: buildQueryValues(nil)}, Response: Response{StatusCode: 200, Body: horizontalPodAutoscaler}, } - response, err := c.Setup(t).Experimental().HorizontalPodAutoscalers(ns).Update(horizontalPodAutoscaler) + response, err := c.Setup(t).Extensions().HorizontalPodAutoscalers(ns).Update(horizontalPodAutoscaler) + c.Validate(t, response, err) +} + +func TestHorizontalPodAutoscalerUpdateStatus(t *testing.T) { + ns := api.NamespaceDefault + horizontalPodAutoscaler := &extensions.HorizontalPodAutoscaler{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: ns, + ResourceVersion: "1", + }, + } + c := &testClient{ + Request: testRequest{Method: "PUT", Path: testapi.Extensions.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, "abc") + "/status", Query: buildQueryValues(nil)}, + Response: Response{StatusCode: 200, Body: horizontalPodAutoscaler}, + } + response, err := c.Setup(t).Extensions().HorizontalPodAutoscalers(ns).UpdateStatus(horizontalPodAutoscaler) c.Validate(t, response, err) } func TestHorizontalPodAutoscalerDelete(t *testing.T) { ns := api.NamespaceDefault c := &testClient{ - Request: testRequest{Method: "DELETE", Path: testapi.Experimental.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, "foo"), Query: buildQueryValues(nil)}, + Request: testRequest{Method: "DELETE", Path: testapi.Extensions.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, "foo"), Query: buildQueryValues(nil)}, Response: Response{StatusCode: 200}, } - err := c.Setup(t).Experimental().HorizontalPodAutoscalers(ns).Delete("foo", nil) + err := c.Setup(t).Extensions().HorizontalPodAutoscalers(ns).Delete("foo", nil) c.Validate(t, nil, err) } @@ -134,10 +151,10 @@ func TestHorizontalPodAutoscalerWatch(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "GET", - Path: testapi.Experimental.ResourcePathWithPrefix("watch", getHorizontalPodAutoscalersResoureName(), "", ""), + Path: testapi.Extensions.ResourcePathWithPrefix("watch", getHorizontalPodAutoscalersResoureName(), "", ""), Query: url.Values{"resourceVersion": []string{}}}, Response: Response{StatusCode: 200}, } - _, err := c.Setup(t).Experimental().HorizontalPodAutoscalers(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), "") + _, err := c.Setup(t).Extensions().HorizontalPodAutoscalers(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), "") c.Validate(t, nil, err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/import_known_versions.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/import_known_versions.go new file mode 100644 index 000000000000..e0549772e29e --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/import_known_versions.go @@ -0,0 +1,23 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned + +// These imports are the API groups the client will support. +import ( + _ "k8s.io/kubernetes/pkg/api/install" + _ "k8s.io/kubernetes/pkg/apis/extensions/install" +) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/ingress.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/ingress.go new file mode 100644 index 000000000000..8c8544c5c473 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/ingress.go @@ -0,0 +1,112 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/watch" +) + +// IngressNamespacer has methods to work with Ingress resources in a namespace +type IngressNamespacer interface { + Ingress(namespace string) IngressInterface +} + +// IngressInterface exposes methods to work on Ingress resources. +type IngressInterface interface { + List(label labels.Selector, field fields.Selector) (*extensions.IngressList, error) + Get(name string) (*extensions.Ingress, error) + Create(ingress *extensions.Ingress) (*extensions.Ingress, error) + Update(ingress *extensions.Ingress) (*extensions.Ingress, error) + Delete(name string, options *api.DeleteOptions) error + Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) + UpdateStatus(ingress *extensions.Ingress) (*extensions.Ingress, error) +} + +// ingress implements IngressNamespacer interface +type ingress struct { + r *ExtensionsClient + ns string +} + +// newIngress returns a ingress +func newIngress(c *ExtensionsClient, namespace string) *ingress { + return &ingress{c, namespace} +} + +// List returns a list of ingress that match the label and field selectors. +func (c *ingress) List(label labels.Selector, field fields.Selector) (result *extensions.IngressList, err error) { + result = &extensions.IngressList{} + err = c.r.Get().Namespace(c.ns).Resource("ingress").LabelsSelectorParam(label).FieldsSelectorParam(field).Do().Into(result) + return +} + +// Get returns information about a particular ingress. +func (c *ingress) Get(name string) (result *extensions.Ingress, err error) { + result = &extensions.Ingress{} + err = c.r.Get().Namespace(c.ns).Resource("ingress").Name(name).Do().Into(result) + return +} + +// Create creates a new ingress. +func (c *ingress) Create(ingress *extensions.Ingress) (result *extensions.Ingress, err error) { + result = &extensions.Ingress{} + err = c.r.Post().Namespace(c.ns).Resource("ingress").Body(ingress).Do().Into(result) + return +} + +// Update updates an existing ingress. +func (c *ingress) Update(ingress *extensions.Ingress) (result *extensions.Ingress, err error) { + result = &extensions.Ingress{} + err = c.r.Put().Namespace(c.ns).Resource("ingress").Name(ingress.Name).Body(ingress).Do().Into(result) + return +} + +// Delete deletes a ingress, returns error if one occurs. +func (c *ingress) Delete(name string, options *api.DeleteOptions) (err error) { + if options == nil { + return c.r.Delete().Namespace(c.ns).Resource("ingress").Name(name).Do().Error() + } + + body, err := api.Scheme.EncodeToVersion(options, c.r.APIVersion()) + if err != nil { + return err + } + return c.r.Delete().Namespace(c.ns).Resource("ingress").Name(name).Body(body).Do().Error() +} + +// Watch returns a watch.Interface that watches the requested ingress. +func (c *ingress) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { + return c.r.Get(). + Prefix("watch"). + Namespace(c.ns). + Resource("ingress"). + Param("resourceVersion", resourceVersion). + LabelsSelectorParam(label). + FieldsSelectorParam(field). + Watch() +} + +// UpdateStatus takes the name of the ingress and the new status. Returns the server's representation of the ingress, and an error, if it occurs. +func (c *ingress) UpdateStatus(ingress *extensions.Ingress) (result *extensions.Ingress, err error) { + result = &extensions.Ingress{} + err = c.r.Put().Namespace(c.ns).Resource("ingress").Name(ingress.Name).SubResource("status").Body(ingress).Do().Into(result) + return +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/ingress_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/ingress_test.go new file mode 100644 index 000000000000..a8a5e35fe053 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/ingress_test.go @@ -0,0 +1,230 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" +) + +func getIngressResourceName() string { + return "ingress" +} + +func TestListIngress(t *testing.T) { + ns := api.NamespaceAll + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: testapi.Extensions.ResourcePath(getIngressResourceName(), ns, ""), + }, + Response: Response{StatusCode: 200, + Body: &extensions.IngressList{ + Items: []extensions.Ingress{ + { + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: extensions.IngressSpec{ + Rules: []extensions.IngressRule{}, + }, + }, + }, + }, + }, + } + receivedIngressList, err := c.Setup(t).Extensions().Ingress(ns).List(labels.Everything(), fields.Everything()) + c.Validate(t, receivedIngressList, err) +} + +func TestGetIngress(t *testing.T) { + ns := api.NamespaceDefault + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: testapi.Extensions.ResourcePath(getIngressResourceName(), ns, "foo"), + Query: buildQueryValues(nil), + }, + Response: Response{ + StatusCode: 200, + Body: &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: extensions.IngressSpec{ + Rules: []extensions.IngressRule{}, + }, + }, + }, + } + receivedIngress, err := c.Setup(t).Extensions().Ingress(ns).Get("foo") + c.Validate(t, receivedIngress, err) +} + +func TestGetIngressWithNoName(t *testing.T) { + ns := api.NamespaceDefault + c := &testClient{Error: true} + receivedIngress, err := c.Setup(t).Extensions().Ingress(ns).Get("") + if (err != nil) && (err.Error() != nameRequiredError) { + t.Errorf("Expected error: %v, but got %v", nameRequiredError, err) + } + + c.Validate(t, receivedIngress, err) +} + +func TestUpdateIngress(t *testing.T) { + ns := api.NamespaceDefault + requestIngress := &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: ns, + ResourceVersion: "1", + }, + } + c := &testClient{ + Request: testRequest{ + Method: "PUT", + Path: testapi.Extensions.ResourcePath(getIngressResourceName(), ns, "foo"), + Query: buildQueryValues(nil), + }, + Response: Response{ + StatusCode: 200, + Body: &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: extensions.IngressSpec{ + Rules: []extensions.IngressRule{}, + }, + }, + }, + } + receivedIngress, err := c.Setup(t).Extensions().Ingress(ns).Update(requestIngress) + c.Validate(t, receivedIngress, err) +} + +func TestUpdateIngressStatus(t *testing.T) { + ns := api.NamespaceDefault + lbStatus := api.LoadBalancerStatus{ + Ingress: []api.LoadBalancerIngress{ + {IP: "127.0.0.1"}, + }, + } + requestIngress := &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: ns, + ResourceVersion: "1", + }, + Status: extensions.IngressStatus{ + LoadBalancer: lbStatus, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "PUT", + Path: testapi.Extensions.ResourcePath(getIngressResourceName(), ns, "foo") + "/status", + Query: buildQueryValues(nil), + }, + Response: Response{ + StatusCode: 200, + Body: &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: extensions.IngressSpec{ + Rules: []extensions.IngressRule{}, + }, + Status: extensions.IngressStatus{ + LoadBalancer: lbStatus, + }, + }, + }, + } + receivedIngress, err := c.Setup(t).Extensions().Ingress(ns).UpdateStatus(requestIngress) + c.Validate(t, receivedIngress, err) +} + +func TestDeleteIngress(t *testing.T) { + ns := api.NamespaceDefault + c := &testClient{ + Request: testRequest{ + Method: "DELETE", + Path: testapi.Extensions.ResourcePath(getIngressResourceName(), ns, "foo"), + Query: buildQueryValues(nil), + }, + Response: Response{StatusCode: 200}, + } + err := c.Setup(t).Extensions().Ingress(ns).Delete("foo", nil) + c.Validate(t, nil, err) +} + +func TestCreateIngress(t *testing.T) { + ns := api.NamespaceDefault + requestIngress := &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: ns, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "POST", + Path: testapi.Extensions.ResourcePath(getIngressResourceName(), ns, ""), + Body: requestIngress, + Query: buildQueryValues(nil), + }, + Response: Response{ + StatusCode: 200, + Body: &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: extensions.IngressSpec{ + Rules: []extensions.IngressRule{}, + }, + }, + }, + } + receivedIngress, err := c.Setup(t).Extensions().Ingress(ns).Create(requestIngress) + c.Validate(t, receivedIngress, err) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/jobs.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/jobs.go new file mode 100644 index 000000000000..d6a88edb1792 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/jobs.go @@ -0,0 +1,116 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/watch" +) + +// JobsNamespacer has methods to work with Job resources in a namespace +type JobsNamespacer interface { + Jobs(namespace string) JobInterface +} + +// JobInterface exposes methods to work on Job resources. +type JobInterface interface { + List(label labels.Selector, field fields.Selector) (*extensions.JobList, error) + Get(name string) (*extensions.Job, error) + Create(job *extensions.Job) (*extensions.Job, error) + Update(job *extensions.Job) (*extensions.Job, error) + Delete(name string, options *api.DeleteOptions) error + Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) + UpdateStatus(job *extensions.Job) (*extensions.Job, error) +} + +// jobs implements JobsNamespacer interface +type jobs struct { + r *ExtensionsClient + ns string +} + +// newJobs returns a jobs +func newJobs(c *ExtensionsClient, namespace string) *jobs { + return &jobs{c, namespace} +} + +// Ensure statically that jobs implements JobInterface. +var _ JobInterface = &jobs{} + +// List returns a list of jobs that match the label and field selectors. +func (c *jobs) List(label labels.Selector, field fields.Selector) (result *extensions.JobList, err error) { + result = &extensions.JobList{} + err = c.r.Get().Namespace(c.ns).Resource("jobs").LabelsSelectorParam(label).FieldsSelectorParam(field).Do().Into(result) + return +} + +// Get returns information about a particular job. +func (c *jobs) Get(name string) (result *extensions.Job, err error) { + result = &extensions.Job{} + err = c.r.Get().Namespace(c.ns).Resource("jobs").Name(name).Do().Into(result) + return +} + +// Create creates a new job. +func (c *jobs) Create(job *extensions.Job) (result *extensions.Job, err error) { + result = &extensions.Job{} + err = c.r.Post().Namespace(c.ns).Resource("jobs").Body(job).Do().Into(result) + return +} + +// Update updates an existing job. +func (c *jobs) Update(job *extensions.Job) (result *extensions.Job, err error) { + result = &extensions.Job{} + err = c.r.Put().Namespace(c.ns).Resource("jobs").Name(job.Name).Body(job).Do().Into(result) + return +} + +// Delete deletes a job, returns error if one occurs. +func (c *jobs) Delete(name string, options *api.DeleteOptions) (err error) { + if options == nil { + return c.r.Delete().Namespace(c.ns).Resource("jobs").Name(name).Do().Error() + } + + body, err := api.Scheme.EncodeToVersion(options, latest.GroupOrDie("").GroupVersion) + if err != nil { + return err + } + return c.r.Delete().Namespace(c.ns).Resource("jobs").Name(name).Body(body).Do().Error() +} + +// Watch returns a watch.Interface that watches the requested jobs. +func (c *jobs) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { + return c.r.Get(). + Prefix("watch"). + Namespace(c.ns). + Resource("jobs"). + Param("resourceVersion", resourceVersion). + LabelsSelectorParam(label). + FieldsSelectorParam(field). + Watch() +} + +// UpdateStatus takes the name of the job and the new status. Returns the server's representation of the job, and an error, if it occurs. +func (c *jobs) UpdateStatus(job *extensions.Job) (result *extensions.Job, err error) { + result = &extensions.Job{} + err = c.r.Put().Namespace(c.ns).Resource("jobs").Name(job.Name).SubResource("status").Body(job).Do().Into(result) + return +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/jobs_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/jobs_test.go new file mode 100644 index 000000000000..856dfaf19717 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/jobs_test.go @@ -0,0 +1,222 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" +) + +func getJobResourceName() string { + return "jobs" +} + +func TestListJobs(t *testing.T) { + ns := api.NamespaceAll + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: testapi.Extensions.ResourcePath(getJobResourceName(), ns, ""), + }, + Response: Response{StatusCode: 200, + Body: &extensions.JobList{ + Items: []extensions.Job{ + { + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: extensions.JobSpec{ + Template: api.PodTemplateSpec{}, + }, + }, + }, + }, + }, + } + receivedJobList, err := c.Setup(t).Extensions().Jobs(ns).List(labels.Everything(), fields.Everything()) + c.Validate(t, receivedJobList, err) +} + +func TestGetJob(t *testing.T) { + ns := api.NamespaceDefault + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: testapi.Extensions.ResourcePath(getJobResourceName(), ns, "foo"), + Query: buildQueryValues(nil), + }, + Response: Response{ + StatusCode: 200, + Body: &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: extensions.JobSpec{ + Template: api.PodTemplateSpec{}, + }, + }, + }, + } + receivedJob, err := c.Setup(t).Extensions().Jobs(ns).Get("foo") + c.Validate(t, receivedJob, err) +} + +func TestGetJobWithNoName(t *testing.T) { + ns := api.NamespaceDefault + c := &testClient{Error: true} + receivedJob, err := c.Setup(t).Extensions().Jobs(ns).Get("") + if (err != nil) && (err.Error() != nameRequiredError) { + t.Errorf("Expected error: %v, but got %v", nameRequiredError, err) + } + + c.Validate(t, receivedJob, err) +} + +func TestUpdateJob(t *testing.T) { + ns := api.NamespaceDefault + requestJob := &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: ns, + ResourceVersion: "1", + }, + } + c := &testClient{ + Request: testRequest{ + Method: "PUT", + Path: testapi.Extensions.ResourcePath(getJobResourceName(), ns, "foo"), + Query: buildQueryValues(nil), + }, + Response: Response{ + StatusCode: 200, + Body: &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: extensions.JobSpec{ + Template: api.PodTemplateSpec{}, + }, + }, + }, + } + receivedJob, err := c.Setup(t).Extensions().Jobs(ns).Update(requestJob) + c.Validate(t, receivedJob, err) +} + +func TestUpdateJobStatus(t *testing.T) { + ns := api.NamespaceDefault + requestJob := &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: ns, + ResourceVersion: "1", + }, + } + c := &testClient{ + Request: testRequest{ + Method: "PUT", + Path: testapi.Extensions.ResourcePath(getJobResourceName(), ns, "foo") + "/status", + Query: buildQueryValues(nil), + }, + Response: Response{ + StatusCode: 200, + Body: &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: extensions.JobSpec{ + Template: api.PodTemplateSpec{}, + }, + Status: extensions.JobStatus{ + Active: 1, + }, + }, + }, + } + receivedJob, err := c.Setup(t).Extensions().Jobs(ns).UpdateStatus(requestJob) + c.Validate(t, receivedJob, err) +} + +func TestDeleteJob(t *testing.T) { + ns := api.NamespaceDefault + c := &testClient{ + Request: testRequest{ + Method: "DELETE", + Path: testapi.Extensions.ResourcePath(getJobResourceName(), ns, "foo"), + Query: buildQueryValues(nil), + }, + Response: Response{StatusCode: 200}, + } + err := c.Setup(t).Extensions().Jobs(ns).Delete("foo", nil) + c.Validate(t, nil, err) +} + +func TestCreateJob(t *testing.T) { + ns := api.NamespaceDefault + requestJob := &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: ns, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "POST", + Path: testapi.Extensions.ResourcePath(getJobResourceName(), ns, ""), + Body: requestJob, + Query: buildQueryValues(nil), + }, + Response: Response{ + StatusCode: 200, + Body: &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: extensions.JobSpec{ + Template: api.PodTemplateSpec{}, + }, + }, + }, + } + receivedJob, err := c.Setup(t).Extensions().Jobs(ns).Create(requestJob) + c.Validate(t, receivedJob, err) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/limit_ranges.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/limit_ranges.go index 45c87fd3b33d..5e90480ec6b2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/limit_ranges.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/limit_ranges.go @@ -32,7 +32,7 @@ type LimitRangesNamespacer interface { // LimitRangeInterface has methods to work with LimitRange resources. type LimitRangeInterface interface { - List(selector labels.Selector) (*api.LimitRangeList, error) + List(label labels.Selector, field fields.Selector) (*api.LimitRangeList, error) Get(name string) (*api.LimitRange, error) Delete(name string) error Create(limitRange *api.LimitRange) (*api.LimitRange, error) @@ -55,9 +55,9 @@ func newLimitRanges(c *Client, namespace string) *limitRanges { } // List takes a selector, and returns the list of limitRanges that match that selector. -func (c *limitRanges) List(selector labels.Selector) (result *api.LimitRangeList, err error) { +func (c *limitRanges) List(label labels.Selector, field fields.Selector) (result *api.LimitRangeList, err error) { result = &api.LimitRangeList{} - err = c.r.Get().Namespace(c.ns).Resource("limitRanges").LabelsSelectorParam(selector).Do().Into(result) + err = c.r.Get().Namespace(c.ns).Resource("limitRanges").LabelsSelectorParam(label).FieldsSelectorParam(field).Do().Into(result) return } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/limit_ranges_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/limit_ranges_test.go index cba367172fd9..23e0fbad5c45 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/limit_ranges_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/limit_ranges_test.go @@ -122,7 +122,7 @@ func TestLimitRangeList(t *testing.T) { }, Response: Response{StatusCode: 200, Body: limitRangeList}, } - response, err := c.Setup(t).LimitRanges(ns).List(labels.Everything()) + response, err := c.Setup(t).LimitRanges(ns).List(labels.Everything(), fields.Everything()) c.Validate(t, response, err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/nodes_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/nodes_test.go index 44ca27bc6cf3..96d67d64174c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/nodes_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/nodes_test.go @@ -23,6 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" ) @@ -31,20 +32,20 @@ func getNodesResourceName() string { return "nodes" } -func TestListMinions(t *testing.T) { +func TestListNodes(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "GET", Path: testapi.Default.ResourcePath(getNodesResourceName(), "", ""), }, - Response: Response{StatusCode: 200, Body: &api.NodeList{ListMeta: api.ListMeta{ResourceVersion: "1"}}}, + Response: Response{StatusCode: 200, Body: &api.NodeList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}}, } response, err := c.Setup(t).Nodes().List(labels.Everything(), fields.Everything()) c.Validate(t, response, err) } -func TestListMinionsLabels(t *testing.T) { - labelSelectorQueryParamName := api.LabelSelectorQueryParam(testapi.Default.Version()) +func TestListNodesLabels(t *testing.T) { + labelSelectorQueryParamName := unversioned.LabelSelectorQueryParam(testapi.Default.Version()) c := &testClient{ Request: testRequest{ Method: "GET", @@ -73,19 +74,19 @@ func TestListMinionsLabels(t *testing.T) { c.Validate(t, receivedNodeList, err) } -func TestGetMinion(t *testing.T) { +func TestGetNode(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "GET", Path: testapi.Default.ResourcePath(getNodesResourceName(), "", "1"), }, - Response: Response{StatusCode: 200, Body: &api.Node{ObjectMeta: api.ObjectMeta{Name: "minion-1"}}}, + Response: Response{StatusCode: 200, Body: &api.Node{ObjectMeta: api.ObjectMeta{Name: "node-1"}}}, } response, err := c.Setup(t).Nodes().Get("1") c.Validate(t, response, err) } -func TestGetMinionWithNoName(t *testing.T) { +func TestGetNodeWithNoName(t *testing.T) { c := &testClient{Error: true} receivedNode, err := c.Setup(t).Nodes().Get("") if (err != nil) && (err.Error() != nameRequiredError) { @@ -95,10 +96,10 @@ func TestGetMinionWithNoName(t *testing.T) { c.Validate(t, receivedNode, err) } -func TestCreateMinion(t *testing.T) { - requestMinion := &api.Node{ +func TestCreateNode(t *testing.T) { + requestNode := &api.Node{ ObjectMeta: api.ObjectMeta{ - Name: "minion-1", + Name: "node-1", }, Status: api.NodeStatus{ Capacity: api.ResourceList{ @@ -114,17 +115,17 @@ func TestCreateMinion(t *testing.T) { Request: testRequest{ Method: "POST", Path: testapi.Default.ResourcePath(getNodesResourceName(), "", ""), - Body: requestMinion}, + Body: requestNode}, Response: Response{ StatusCode: 200, - Body: requestMinion, + Body: requestNode, }, } - receivedMinion, err := c.Setup(t).Nodes().Create(requestMinion) - c.Validate(t, receivedMinion, err) + receivedNode, err := c.Setup(t).Nodes().Create(requestNode) + c.Validate(t, receivedNode, err) } -func TestDeleteMinion(t *testing.T) { +func TestDeleteNode(t *testing.T) { c := &testClient{ Request: testRequest{ Method: "DELETE", @@ -136,8 +137,8 @@ func TestDeleteMinion(t *testing.T) { c.Validate(t, nil, err) } -func TestUpdateMinion(t *testing.T) { - requestMinion := &api.Node{ +func TestUpdateNode(t *testing.T) { + requestNode := &api.Node{ ObjectMeta: api.ObjectMeta{ Name: "foo", ResourceVersion: "1", @@ -157,8 +158,8 @@ func TestUpdateMinion(t *testing.T) { Method: "PUT", Path: testapi.Default.ResourcePath(getNodesResourceName(), "", "foo"), }, - Response: Response{StatusCode: 200, Body: requestMinion}, + Response: Response{StatusCode: 200, Body: requestNode}, } - response, err := c.Setup(t).Nodes().Update(requestMinion) + response, err := c.Setup(t).Nodes().Update(requestNode) c.Validate(t, response, err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/pods_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/pods_test.go index ad28e089ddbe..2e2a41725c95 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/pods_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/pods_test.go @@ -22,6 +22,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" ) @@ -64,7 +65,7 @@ func TestListPods(t *testing.T) { func TestListPodsLabels(t *testing.T) { ns := api.NamespaceDefault - labelSelectorQueryParamName := api.LabelSelectorQueryParam(testapi.Default.Version()) + labelSelectorQueryParamName := unversioned.LabelSelectorQueryParam(testapi.Default.Version()) c := &testClient{ Request: testRequest{ Method: "GET", diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/portforward/portforward.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/portforward/portforward.go index 5efc21565de6..36916bdcf497 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/portforward/portforward.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/portforward/portforward.go @@ -25,36 +25,26 @@ import ( "net/http" "strconv" "strings" + "sync" "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" - client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/httpstream" - "k8s.io/kubernetes/pkg/util/httpstream/spdy" ) -type upgrader interface { - upgrade(*client.Request, *client.Config) (httpstream.Connection, error) -} - -type defaultUpgrader struct{} - -func (u *defaultUpgrader) upgrade(req *client.Request, config *client.Config) (httpstream.Connection, error) { - return req.Upgrade(config, spdy.NewRoundTripper) -} - // PortForwarder knows how to listen for local connections and forward them to // a remote pod via an upgraded HTTP request. type PortForwarder struct { - req *client.Request - config *client.Config ports []ForwardedPort stopChan <-chan struct{} - streamConn httpstream.Connection - listeners []io.Closer - upgrader upgrader - Ready chan struct{} + dialer httpstream.Dialer + streamConn httpstream.Connection + listeners []io.Closer + Ready chan struct{} + requestIDLock sync.Mutex + requestID int } // ForwardedPort contains a Local:Remote port pairing. @@ -116,7 +106,7 @@ func parsePorts(ports []string) ([]ForwardedPort, error) { } // New creates a new PortForwarder. -func New(req *client.Request, config *client.Config, ports []string, stopChan <-chan struct{}) (*PortForwarder, error) { +func New(dialer httpstream.Dialer, ports []string, stopChan <-chan struct{}) (*PortForwarder, error) { if len(ports) == 0 { return nil, errors.New("You must specify at least 1 port") } @@ -124,10 +114,8 @@ func New(req *client.Request, config *client.Config, ports []string, stopChan <- if err != nil { return nil, err } - return &PortForwarder{ - req: req, - config: config, + dialer: dialer, ports: parsedPorts, stopChan: stopChan, Ready: make(chan struct{}), @@ -139,13 +127,10 @@ func New(req *client.Request, config *client.Config, ports []string, stopChan <- func (pf *PortForwarder) ForwardPorts() error { defer pf.Close() - if pf.upgrader == nil { - pf.upgrader = &defaultUpgrader{} - } var err error - pf.streamConn, err = pf.upgrader.upgrade(pf.req, pf.config) + pf.streamConn, err = pf.dialer.Dial() if err != nil { - return fmt.Errorf("Error upgrading connection: %s", err) + return fmt.Errorf("error upgrading connection: %s", err) } defer pf.streamConn.Close() @@ -179,7 +164,7 @@ func (pf *PortForwarder) forward() error { select { case <-pf.stopChan: case <-pf.streamConn.CloseChan(): - glog.Errorf("Lost connection to pod") + util.HandleError(errors.New("lost connection to pod")) } return nil @@ -213,7 +198,7 @@ func (pf *PortForwarder) listenOnPortAndAddress(port *ForwardedPort, protocol st func (pf *PortForwarder) getListener(protocol string, hostname string, port *ForwardedPort) (net.Listener, error) { listener, err := net.Listen(protocol, fmt.Sprintf("%s:%d", hostname, port.Local)) if err != nil { - glog.Errorf("Unable to create listener: Error %s", err) + util.HandleError(fmt.Errorf("Unable to create listener: Error %s", err)) return nil, err } listenerAddress := listener.Addr().String() @@ -237,7 +222,7 @@ func (pf *PortForwarder) waitForConnection(listener net.Listener, port Forwarded if err != nil { // TODO consider using something like https://github.com/hydrogen18/stoppableListener? if !strings.Contains(strings.ToLower(err.Error()), "use of closed network connection") { - glog.Errorf("Error accepting connection on port %d: %v", port.Local, err) + util.HandleError(fmt.Errorf("Error accepting connection on port %d: %v", port.Local, err)) } return } @@ -245,6 +230,14 @@ func (pf *PortForwarder) waitForConnection(listener net.Listener, port Forwarded } } +func (pf *PortForwarder) nextRequestID() int { + pf.requestIDLock.Lock() + defer pf.requestIDLock.Unlock() + id := pf.requestID + pf.requestID++ + return id +} + // handleConnection copies data between the local connection and the stream to // the remote server. func (pf *PortForwarder) handleConnection(conn net.Conn, port ForwardedPort) { @@ -252,65 +245,76 @@ func (pf *PortForwarder) handleConnection(conn net.Conn, port ForwardedPort) { glog.Infof("Handling connection for %d", port.Local) - errorChan := make(chan error) - doneChan := make(chan struct{}, 2) + requestID := pf.nextRequestID() // create error stream headers := http.Header{} headers.Set(api.StreamType, api.StreamTypeError) headers.Set(api.PortHeader, fmt.Sprintf("%d", port.Remote)) + headers.Set(api.PortForwardRequestIDHeader, strconv.Itoa(requestID)) errorStream, err := pf.streamConn.CreateStream(headers) if err != nil { - glog.Errorf("Error creating error stream for port %d -> %d: %v", port.Local, port.Remote, err) + util.HandleError(fmt.Errorf("error creating error stream for port %d -> %d: %v", port.Local, port.Remote, err)) return } - defer errorStream.Reset() + // we're not writing to this stream + errorStream.Close() + + errorChan := make(chan error) go func() { message, err := ioutil.ReadAll(errorStream) - if err != nil && err != io.EOF { - errorChan <- fmt.Errorf("Error reading from error stream for port %d -> %d: %v", port.Local, port.Remote, err) - } - if len(message) > 0 { - errorChan <- fmt.Errorf("An error occurred forwarding %d -> %d: %v", port.Local, port.Remote, string(message)) + switch { + case err != nil: + errorChan <- fmt.Errorf("error reading from error stream for port %d -> %d: %v", port.Local, port.Remote, err) + case len(message) > 0: + errorChan <- fmt.Errorf("an error occurred forwarding %d -> %d: %v", port.Local, port.Remote, string(message)) } + close(errorChan) }() // create data stream headers.Set(api.StreamType, api.StreamTypeData) dataStream, err := pf.streamConn.CreateStream(headers) if err != nil { - glog.Errorf("Error creating forwarding stream for port %d -> %d: %v", port.Local, port.Remote, err) + util.HandleError(fmt.Errorf("error creating forwarding stream for port %d -> %d: %v", port.Local, port.Remote, err)) return } - // Send a Reset when this function exits to completely tear down the stream here - // and in the remote server. - defer dataStream.Reset() + + localError := make(chan struct{}) + remoteDone := make(chan struct{}) go func() { - // Copy from the remote side to the local port. We won't get an EOF from - // the server as it has no way of knowing when to close the stream. We'll - // take care of closing both ends of the stream with the call to - // stream.Reset() when this function exits. - if _, err := io.Copy(conn, dataStream); err != nil && err != io.EOF && !strings.Contains(err.Error(), "use of closed network connection") { - glog.Errorf("Error copying from remote stream to local connection: %v", err) + // Copy from the remote side to the local port. + if _, err := io.Copy(conn, dataStream); err != nil && !strings.Contains(err.Error(), "use of closed network connection") { + util.HandleError(fmt.Errorf("error copying from remote stream to local connection: %v", err)) } - doneChan <- struct{}{} + + // inform the select below that the remote copy is done + close(remoteDone) }() go func() { - // Copy from the local port to the remote side. Here we will be able to know - // when the Copy gets an EOF from conn, as that will happen as soon as conn is - // closed (i.e. client disconnected). - if _, err := io.Copy(dataStream, conn); err != nil && err != io.EOF && !strings.Contains(err.Error(), "use of closed network connection") { - glog.Errorf("Error copying from local connection to remote stream: %v", err) + // inform server we're not sending any more data after copy unblocks + defer dataStream.Close() + + // Copy from the local port to the remote side. + if _, err := io.Copy(dataStream, conn); err != nil && !strings.Contains(err.Error(), "use of closed network connection") { + util.HandleError(fmt.Errorf("error copying from local connection to remote stream: %v", err)) + // break out of the select below without waiting for the other copy to finish + close(localError) } - doneChan <- struct{}{} }() + // wait for either a local->remote error or for copying from remote->local to finish select { - case err := <-errorChan: - glog.Error(err) - case <-doneChan: + case <-remoteDone: + case <-localError: + } + + // always expect something on errorChan (it may be nil) + err = <-errorChan + if err != nil { + util.HandleError(err) } } @@ -318,7 +322,7 @@ func (pf *PortForwarder) Close() { // stop all listeners for _, l := range pf.listeners { if err := l.Close(); err != nil { - glog.Errorf("Error closing listener: %v", err) + util.HandleError(fmt.Errorf("error closing listener: %v", err)) } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/portforward/portforward_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/portforward/portforward_test.go index f5e6c639fa22..f208a9e88144 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/portforward/portforward_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/portforward/portforward_test.go @@ -18,22 +18,36 @@ package portforward import ( "bytes" - "errors" "fmt" "io" "net" "net/http" + "net/http/httptest" + "net/url" "reflect" "strings" "sync" "testing" "time" - "k8s.io/kubernetes/pkg/api" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" + "k8s.io/kubernetes/pkg/kubelet" + "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util/httpstream" ) +type fakeDialer struct { + dialed bool + conn httpstream.Connection + err error +} + +func (d *fakeDialer) Dial() (httpstream.Connection, error) { + d.dialed = true + return d.conn, d.err +} + func TestParsePortsAndNew(t *testing.T) { tests := []struct { input []string @@ -70,10 +84,9 @@ func TestParsePortsAndNew(t *testing.T) { t.Fatalf("%d: parsePorts: error expected=%t, got %t: %s", i, e, a, err) } - expectedRequest := &client.Request{} - expectedConfig := &client.Config{} + dialer := &fakeDialer{} expectedStopChan := make(chan struct{}) - pf, err := New(expectedRequest, expectedConfig, test.input, expectedStopChan) + pf, err := New(dialer, test.input, expectedStopChan) haveError = err != nil if e, a := test.expectNewError, haveError; e != a { t.Fatalf("%d: New: error expected=%t, got %t: %s", i, e, a, err) @@ -92,11 +105,8 @@ func TestParsePortsAndNew(t *testing.T) { } } - if e, a := expectedRequest, pf.req; e != a { - t.Fatalf("%d: req: expected %#v, got %#v", i, e, a) - } - if e, a := expectedConfig, pf.config; e != a { - t.Fatalf("%d: config: expected %#v, got %#v", i, e, a) + if dialer.dialed { + t.Fatalf("%d: expected not dialed", i) } if e, a := test.expected, pf.ports; !reflect.DeepEqual(e, a) { t.Fatalf("%d: ports: expected %#v, got %#v", i, e, a) @@ -110,109 +120,6 @@ func TestParsePortsAndNew(t *testing.T) { } } -type fakeUpgrader struct { - conn *fakeUpgradeConnection - err error -} - -func (u *fakeUpgrader) upgrade(req *client.Request, config *client.Config) (httpstream.Connection, error) { - return u.conn, u.err -} - -type fakeUpgradeConnection struct { - closeCalled bool - lock sync.Mutex - streams map[string]*fakeUpgradeStream - portData map[string]string -} - -func newFakeUpgradeConnection() *fakeUpgradeConnection { - return &fakeUpgradeConnection{ - streams: make(map[string]*fakeUpgradeStream), - portData: make(map[string]string), - } -} - -func (c *fakeUpgradeConnection) CreateStream(headers http.Header) (httpstream.Stream, error) { - c.lock.Lock() - defer c.lock.Unlock() - - stream := &fakeUpgradeStream{} - c.streams[headers.Get(api.PortHeader)] = stream - // only simulate data on the data stream for now, not the error stream - if headers.Get(api.StreamType) == api.StreamTypeData { - stream.data = c.portData[headers.Get(api.PortHeader)] - } - - return stream, nil -} - -func (c *fakeUpgradeConnection) Close() error { - c.lock.Lock() - defer c.lock.Unlock() - - c.closeCalled = true - return nil -} - -func (c *fakeUpgradeConnection) CloseChan() <-chan bool { - return make(chan bool) -} - -func (c *fakeUpgradeConnection) SetIdleTimeout(timeout time.Duration) { -} - -type fakeUpgradeStream struct { - readCalled bool - writeCalled bool - dataWritten []byte - closeCalled bool - resetCalled bool - data string - lock sync.Mutex -} - -func (s *fakeUpgradeStream) Read(p []byte) (int, error) { - s.lock.Lock() - defer s.lock.Unlock() - s.readCalled = true - b := []byte(s.data) - n := copy(p, b) - // Indicate we returned all the data, and have no more data (EOF) - // Returning an EOF here will cause the port forwarder to immediately terminate, which is correct when we have no more data to send - return n, io.EOF -} - -func (s *fakeUpgradeStream) Write(p []byte) (int, error) { - s.lock.Lock() - defer s.lock.Unlock() - s.writeCalled = true - s.dataWritten = append(s.dataWritten, p...) - // Indicate the stream accepted all the data, and can accept more (no err) - // Returning an EOF here will cause the port forwarder to immediately terminate, which is incorrect, in case someone writes more data - return len(p), nil -} - -func (s *fakeUpgradeStream) Close() error { - s.lock.Lock() - defer s.lock.Unlock() - s.closeCalled = true - return nil -} - -func (s *fakeUpgradeStream) Reset() error { - s.lock.Lock() - defer s.lock.Unlock() - s.resetCalled = true - return nil -} - -func (s *fakeUpgradeStream) Headers() http.Header { - s.lock.Lock() - defer s.lock.Unlock() - return http.Header{} -} - type GetListenerTestCase struct { Hostname string Protocol string @@ -295,55 +202,118 @@ func TestGetListener(t *testing.T) { } } +// fakePortForwarder simulates port forwarding for testing. It implements +// kubelet.PortForwarder. +type fakePortForwarder struct { + lock sync.Mutex + // stores data received from the stream per port + received map[uint16]string + // data to be sent to the stream per port + send map[uint16]string +} + +var _ kubelet.PortForwarder = &fakePortForwarder{} + +func (pf *fakePortForwarder) PortForward(name string, uid types.UID, port uint16, stream io.ReadWriteCloser) error { + defer stream.Close() + + var wg sync.WaitGroup + + // client -> server + wg.Add(1) + go func() { + defer wg.Done() + + // copy from stream into a buffer + received := new(bytes.Buffer) + io.Copy(received, stream) + + // store the received content + pf.lock.Lock() + pf.received[port] = received.String() + pf.lock.Unlock() + }() + + // server -> client + wg.Add(1) + go func() { + defer wg.Done() + + // send the hardcoded data to the stream + io.Copy(stream, strings.NewReader(pf.send[port])) + }() + + wg.Wait() + + return nil +} + +// fakePortForwardServer creates an HTTP server that can handle port forwarding +// requests. +func fakePortForwardServer(t *testing.T, testName string, serverSends, expectedFromClient map[uint16]string) http.HandlerFunc { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + pf := &fakePortForwarder{ + received: make(map[uint16]string), + send: serverSends, + } + kubelet.ServePortForward(w, req, pf, "pod", "uid", 0, 10*time.Second) + + for port, expected := range expectedFromClient { + actual, ok := pf.received[port] + if !ok { + t.Errorf("%s: server didn't receive any data for port %d", testName, port) + continue + } + + if expected != actual { + t.Errorf("%s: server expected to receive %q, got %q for port %d", testName, expected, actual, port) + } + } + + for port, actual := range pf.received { + if _, ok := expectedFromClient[port]; !ok { + t.Errorf("%s: server unexpectedly received %q for port %d", testName, actual, port) + } + } + }) +} + func TestForwardPorts(t *testing.T) { - testCases := []struct { - Upgrader *fakeUpgrader - Ports []string - Send map[uint16]string - Receive map[uint16]string - Err bool + tests := map[string]struct { + ports []string + clientSends map[uint16]string + serverSends map[uint16]string }{ - { - Upgrader: &fakeUpgrader{err: errors.New("bail")}, - Err: true, - }, - { - Upgrader: &fakeUpgrader{conn: newFakeUpgradeConnection()}, - Ports: []string{"5000"}, + "forward 1 port with no data either direction": { + ports: []string{"5000"}, }, - { - Upgrader: &fakeUpgrader{conn: newFakeUpgradeConnection()}, - Ports: []string{"5001", "6000"}, - Send: map[uint16]string{ + "forward 2 ports with bidirectional data": { + ports: []string{"5001", "6000"}, + clientSends: map[uint16]string{ 5001: "abcd", 6000: "ghij", }, - Receive: map[uint16]string{ + serverSends: map[uint16]string{ 5001: "1234", 6000: "5678", }, }, } - for i, testCase := range testCases { - stopChan := make(chan struct{}, 1) + for testName, test := range tests { + server := httptest.NewServer(fakePortForwardServer(t, testName, test.serverSends, test.clientSends)) - pf, err := New(&client.Request{}, &client.Config{}, testCase.Ports, stopChan) - hasErr := err != nil - if hasErr != testCase.Err { - t.Fatalf("%d: New: expected %t, got %t: %v", i, testCase.Err, hasErr, err) - } - if pf == nil { - continue + url, _ := url.Parse(server.URL) + exec, err := remotecommand.NewExecutor(&client.Config{}, "POST", url) + if err != nil { + t.Fatal(err) } - pf.upgrader = testCase.Upgrader - if testCase.Upgrader.err != nil { - err := pf.ForwardPorts() - hasErr := err != nil - if hasErr != testCase.Err { - t.Fatalf("%d: ForwardPorts: expected %t, got %t: %v", i, testCase.Err, hasErr, err) - } - continue + + stopChan := make(chan struct{}, 1) + + pf, err := New(exec, test.ports, stopChan) + if err != nil { + t.Fatalf("%s: unexpected error calling New: %v", testName, err) } doneChan := make(chan error) @@ -352,74 +322,77 @@ func TestForwardPorts(t *testing.T) { }() <-pf.Ready - conn := testCase.Upgrader.conn - - for port, data := range testCase.Send { - conn.lock.Lock() - conn.portData[fmt.Sprintf("%d", port)] = testCase.Receive[port] - conn.lock.Unlock() - + for port, data := range test.clientSends { clientConn, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", port)) if err != nil { - t.Fatalf("%d: error dialing %d: %s", i, port, err) + t.Errorf("%s: error dialing %d: %s", testName, port, err) + server.Close() + continue } defer clientConn.Close() n, err := clientConn.Write([]byte(data)) if err != nil && err != io.EOF { - t.Fatalf("%d: Error sending data '%s': %s", i, data, err) + t.Errorf("%s: Error sending data '%s': %s", testName, data, err) + server.Close() + continue } if n == 0 { - t.Fatalf("%d: unexpected write of 0 bytes", i) + t.Errorf("%s: unexpected write of 0 bytes", testName) + server.Close() + continue } b := make([]byte, 4) n, err = clientConn.Read(b) if err != nil && err != io.EOF { - t.Fatalf("%d: Error reading data: %s", i, err) + t.Errorf("%s: Error reading data: %s", testName, err) + server.Close() + continue } - if !bytes.Equal([]byte(testCase.Receive[port]), b) { - t.Fatalf("%d: expected to read '%s', got '%s'", i, testCase.Receive[port], b) + if !bytes.Equal([]byte(test.serverSends[port]), b) { + t.Errorf("%s: expected to read '%s', got '%s'", testName, test.serverSends[port], b) + server.Close() + continue } } - // tell r.ForwardPorts to stop close(stopChan) // wait for r.ForwardPorts to actually return err = <-doneChan if err != nil { - t.Fatalf("%d: unexpected error: %s", i, err) - } - - if e, a := len(testCase.Send), len(conn.streams); e != a { - t.Fatalf("%d: expected %d streams to be created, got %d", i, e, a) - } - - if !conn.closeCalled { - t.Fatalf("%d: expected conn closure", i) + t.Errorf("%s: unexpected error: %s", testName, err) } + server.Close() } } func TestForwardPortsReturnsErrorWhenAllBindsFailed(t *testing.T) { + server := httptest.NewServer(fakePortForwardServer(t, "allBindsFailed", nil, nil)) + defer server.Close() + + url, _ := url.Parse(server.URL) + exec, err := remotecommand.NewExecutor(&client.Config{}, "POST", url) + if err != nil { + t.Fatal(err) + } + stopChan1 := make(chan struct{}, 1) defer close(stopChan1) - pf1, err := New(&client.Request{}, &client.Config{}, []string{"5555"}, stopChan1) + pf1, err := New(exec, []string{"5555"}, stopChan1) if err != nil { t.Fatalf("error creating pf1: %v", err) } - pf1.upgrader = &fakeUpgrader{conn: newFakeUpgradeConnection()} go pf1.ForwardPorts() <-pf1.Ready stopChan2 := make(chan struct{}, 1) - pf2, err := New(&client.Request{}, &client.Config{}, []string{"5555"}, stopChan2) + pf2, err := New(exec, []string{"5555"}, stopChan2) if err != nil { t.Fatalf("error creating pf2: %v", err) } - pf2.upgrader = &fakeUpgrader{conn: newFakeUpgradeConnection()} if err := pf2.ForwardPorts(); err == nil { t.Fatal("expected non-nil error for pf2.ForwardPorts") } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/remotecommand/remotecommand.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/remotecommand/remotecommand.go index e63af79aa0a1..505e3fc9c1bc 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/remotecommand/remotecommand.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/remotecommand/remotecommand.go @@ -21,141 +21,127 @@ import ( "io" "io/ioutil" "net/http" + "net/url" "sync" "k8s.io/kubernetes/pkg/api" client "k8s.io/kubernetes/pkg/client/unversioned" - "k8s.io/kubernetes/pkg/conversion/queryparams" - "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/httpstream" "k8s.io/kubernetes/pkg/util/httpstream/spdy" ) -type upgrader interface { - upgrade(*client.Request, *client.Config) (httpstream.Connection, error) +// Executor is an interface for transporting shell-style streams. +type Executor interface { + // Stream initiates the transport of the standard shell streams. It will transport any + // non-nil stream to a remote system, and return an error if a problem occurs. If tty + // is set, the stderr stream is not used (raw TTY manages stdout and stderr over the + // stdout stream). + Stream(stdin io.Reader, stdout, stderr io.Writer, tty bool) error } -type defaultUpgrader struct{} - -func (u *defaultUpgrader) upgrade(req *client.Request, config *client.Config) (httpstream.Connection, error) { - return req.Upgrade(config, spdy.NewRoundTripper) +// StreamExecutor supports the ability to dial an httpstream connection and the ability to +// run a command line stream protocol over that dialer. +type StreamExecutor interface { + Executor + httpstream.Dialer } -type Streamer struct { - req *client.Request - config *client.Config - stdin io.Reader - stdout io.Writer - stderr io.Writer - tty bool +// streamExecutor handles transporting standard shell streams over an httpstream connection. +type streamExecutor struct { + upgrader httpstream.UpgradeRoundTripper + transport http.RoundTripper - upgrader upgrader + method string + url *url.URL } -// Executor executes a command on a pod container -type Executor struct { - Streamer - command []string -} +// NewExecutor connects to the provided server and upgrades the connection to +// multiplexed bidirectional streams. The current implementation uses SPDY, +// but this could be replaced with HTTP/2 once it's available, or something else. +// TODO: the common code between this and portforward could be abstracted. +func NewExecutor(config *client.Config, method string, url *url.URL) (StreamExecutor, error) { + tlsConfig, err := client.TLSConfigFor(config) + if err != nil { + return nil, err + } -// New creates a new RemoteCommandExecutor -func New(req *client.Request, config *client.Config, command []string, stdin io.Reader, stdout, stderr io.Writer, tty bool) *Executor { - return &Executor{ - command: command, - Streamer: Streamer{ - req: req, - config: config, - stdin: stdin, - stdout: stdout, - stderr: stderr, - tty: tty, - }, + upgradeRoundTripper := spdy.NewRoundTripper(tlsConfig) + wrapper, err := client.HTTPWrappersForConfig(config, upgradeRoundTripper) + if err != nil { + return nil, err } -} -type Attach struct { - Streamer + return &streamExecutor{ + upgrader: upgradeRoundTripper, + transport: wrapper, + method: method, + url: url, + }, nil } -// NewAttach creates a new RemoteAttach -func NewAttach(req *client.Request, config *client.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) *Attach { - return &Attach{ - Streamer: Streamer{ - req: req, - config: config, - stdin: stdin, - stdout: stdout, - stderr: stderr, - tty: tty, - }, +// NewStreamExecutor upgrades the request so that it supports multiplexed bidirectional +// streams. This method takes a stream upgrader and an optional function that is invoked +// to wrap the round tripper. This method may be used by clients that are lower level than +// Kubernetes clients or need to provide their own upgrade round tripper. +func NewStreamExecutor(upgrader httpstream.UpgradeRoundTripper, fn func(http.RoundTripper) http.RoundTripper, method string, url *url.URL) (StreamExecutor, error) { + var rt http.RoundTripper = upgrader + if fn != nil { + rt = fn(rt) } + return &streamExecutor{ + upgrader: upgrader, + transport: rt, + method: method, + url: url, + }, nil } -// Execute sends a remote command execution request, upgrading the -// connection and creating streams to represent stdin/stdout/stderr. Data is -// copied between these streams and the supplied stdin/stdout/stderr parameters. -func (e *Attach) Execute() error { - opts := api.PodAttachOptions{ - Stdin: (e.stdin != nil), - Stdout: (e.stdout != nil), - Stderr: (!e.tty && e.stderr != nil), - TTY: e.tty, - } - - if err := e.setupRequestParameters(&opts); err != nil { - return err - } - - return e.doStream() -} +// Dial opens a connection to a remote server and attempts to negotiate a SPDY connection. +func (e *streamExecutor) Dial() (httpstream.Connection, error) { + client := &http.Client{Transport: e.transport} -// Execute sends a remote command execution request, upgrading the -// connection and creating streams to represent stdin/stdout/stderr. Data is -// copied between these streams and the supplied stdin/stdout/stderr parameters. -func (e *Executor) Execute() error { - opts := api.PodExecOptions{ - Stdin: (e.stdin != nil), - Stdout: (e.stdout != nil), - Stderr: (!e.tty && e.stderr != nil), - TTY: e.tty, - Command: e.command, + req, err := http.NewRequest(e.method, e.url.String(), nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %s", err) } - if err := e.setupRequestParameters(&opts); err != nil { - return err + resp, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %s", err) } + defer resp.Body.Close() - return e.doStream() + // TODO: handle protocol selection in the future + return e.upgrader.NewConnection(resp) } -func (e *Streamer) setupRequestParameters(obj runtime.Object) error { - versioned, err := api.Scheme.ConvertToVersion(obj, e.config.Version) - if err != nil { - return err - } - params, err := queryparams.Convert(versioned) +// Stream opens a protocol streamer to the server and streams until a client closes +// the connection or the server disconnects. +func (e *streamExecutor) Stream(stdin io.Reader, stdout, stderr io.Writer, tty bool) error { + conn, err := e.Dial() if err != nil { return err } - for k, v := range params { - for _, vv := range v { - e.req.Param(k, vv) - } + defer conn.Close() + // TODO: negotiate protocols + streamer := &streamProtocol{ + stdin: stdin, + stdout: stdout, + stderr: stderr, + tty: tty, } - return nil + return streamer.stream(conn) } -func (e *Streamer) doStream() error { - if e.upgrader == nil { - e.upgrader = &defaultUpgrader{} - } - conn, err := e.upgrader.upgrade(e.req, e.config) - if err != nil { - return err - } - defer conn.Close() +type streamProtocol struct { + stdin io.Reader + stdout io.Writer + stderr io.Writer + tty bool +} +func (e *streamProtocol) stream(conn httpstream.Connection) error { headers := http.Header{} // set up error stream diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/remotecommand/remotecommand_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/remotecommand/remotecommand_test.go index 9870ee259bcf..56cb3372bfb0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/remotecommand/remotecommand_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/remotecommand/remotecommand_test.go @@ -20,6 +20,7 @@ import ( "bytes" "fmt" "io" + "io/ioutil" "net/http" "net/http/httptest" "net/url" @@ -183,12 +184,17 @@ func TestRequestExecuteRemoteCommand(t *testing.T) { url, _ := url.ParseRequestURI(server.URL) c := client.NewRESTClient(url, "x", nil, -1, -1) req := c.Post().Resource("testing") - + req.Param("command", "ls") + req.Param("command", "/") conf := &client.Config{ Host: server.URL, } - e := New(req, conf, []string{"ls", "/"}, strings.NewReader(strings.Repeat(testCase.Stdin, testCase.MessageCount)), localOut, localErr, testCase.Tty) - err := e.Execute() + e, err := NewExecutor(conf, "POST", req.URL()) + if err != nil { + t.Errorf("%d: unexpected error: %v", i, err) + continue + } + err = e.Stream(strings.NewReader(strings.Repeat(testCase.Stdin, testCase.MessageCount)), localOut, localErr, testCase.Tty) hasErr := err != nil if len(testCase.Error) > 0 { @@ -263,8 +269,12 @@ func TestRequestAttachRemoteCommand(t *testing.T) { conf := &client.Config{ Host: server.URL, } - e := NewAttach(req, conf, strings.NewReader(testCase.Stdin), localOut, localErr, testCase.Tty) - err := e.Execute() + e, err := NewExecutor(conf, "POST", req.URL()) + if err != nil { + t.Errorf("%d: unexpected error: %v", i, err) + continue + } + err = e.Stream(strings.NewReader(testCase.Stdin), localOut, localErr, testCase.Tty) hasErr := err != nil if len(testCase.Error) > 0 { @@ -301,3 +311,66 @@ func TestRequestAttachRemoteCommand(t *testing.T) { server.Close() } } + +type fakeUpgrader struct { + req *http.Request + resp *http.Response + conn httpstream.Connection + err, connErr error + checkResponse bool + + t *testing.T +} + +func (u *fakeUpgrader) RoundTrip(req *http.Request) (*http.Response, error) { + u.req = req + return u.resp, u.err +} + +func (u *fakeUpgrader) NewConnection(resp *http.Response) (httpstream.Connection, error) { + if u.checkResponse && u.resp != resp { + u.t.Errorf("response objects passed did not match: %#v", resp) + } + return u.conn, u.connErr +} + +type fakeConnection struct { + httpstream.Connection +} + +// Dial is the common functionality between any stream based upgrader, regardless of protocol. +// This method ensures that someone can use a generic stream executor without being dependent +// on the core Kube client config behavior. +func TestDial(t *testing.T) { + upgrader := &fakeUpgrader{ + t: t, + checkResponse: true, + conn: &fakeConnection{}, + resp: &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(&bytes.Buffer{}), + }, + } + var called bool + testFn := func(rt http.RoundTripper) http.RoundTripper { + if rt != upgrader { + t.Fatalf("unexpected round tripper: %#v", rt) + } + called = true + return rt + } + exec, err := NewStreamExecutor(upgrader, testFn, "POST", &url.URL{Host: "something.com", Scheme: "https"}) + if err != nil { + t.Fatal(err) + } + conn, err := exec.Dial() + if err != nil { + t.Fatal(err) + } + if conn != upgrader.conn { + t.Errorf("unexpected connection: %#v", conn) + } + if !called { + t.Errorf("wrapper not called") + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/replication_controllers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/replication_controllers.go index 81add2c0586e..1ea08d6cb12a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/replication_controllers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/replication_controllers.go @@ -30,10 +30,11 @@ type ReplicationControllersNamespacer interface { // ReplicationControllerInterface has methods to work with ReplicationController resources. type ReplicationControllerInterface interface { - List(selector labels.Selector) (*api.ReplicationControllerList, error) + List(label labels.Selector, field fields.Selector) (*api.ReplicationControllerList, error) Get(name string) (*api.ReplicationController, error) Create(ctrl *api.ReplicationController) (*api.ReplicationController, error) Update(ctrl *api.ReplicationController) (*api.ReplicationController, error) + UpdateStatus(ctrl *api.ReplicationController) (*api.ReplicationController, error) Delete(name string) error Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) } @@ -50,9 +51,9 @@ func newReplicationControllers(c *Client, namespace string) *replicationControll } // List takes a selector, and returns the list of replication controllers that match that selector. -func (c *replicationControllers) List(selector labels.Selector) (result *api.ReplicationControllerList, err error) { +func (c *replicationControllers) List(label labels.Selector, field fields.Selector) (result *api.ReplicationControllerList, err error) { result = &api.ReplicationControllerList{} - err = c.r.Get().Namespace(c.ns).Resource("replicationControllers").LabelsSelectorParam(selector).Do().Into(result) + err = c.r.Get().Namespace(c.ns).Resource("replicationControllers").LabelsSelectorParam(label).FieldsSelectorParam(field).Do().Into(result) return } @@ -77,6 +78,13 @@ func (c *replicationControllers) Update(controller *api.ReplicationController) ( return } +// UpdateStatus updates an existing replication controller status +func (c *replicationControllers) UpdateStatus(controller *api.ReplicationController) (result *api.ReplicationController, err error) { + result = &api.ReplicationController{} + err = c.r.Put().Namespace(c.ns).Resource("replicationControllers").Name(controller.Name).SubResource("status").Body(controller).Do().Into(result) + return +} + // Delete deletes an existing replication controller. func (c *replicationControllers) Delete(name string) error { return c.r.Delete().Namespace(c.ns).Resource("replicationControllers").Name(name).Do().Error() diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/replication_controllers_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/replication_controllers_test.go index 6908f42a6547..2e3d0f55015c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/replication_controllers_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/replication_controllers_test.go @@ -21,6 +21,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" ) @@ -55,7 +56,7 @@ func TestListControllers(t *testing.T) { }, }, } - receivedControllerList, err := c.Setup(t).ReplicationControllers(ns).List(labels.Everything()) + receivedControllerList, err := c.Setup(t).ReplicationControllers(ns).List(labels.Everything(), fields.Everything()) c.Validate(t, receivedControllerList, err) } @@ -124,6 +125,36 @@ func TestUpdateController(t *testing.T) { c.Validate(t, receivedController, err) } +func TestUpdateStatusController(t *testing.T) { + ns := api.NamespaceDefault + requestController := &api.ReplicationController{ + ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, + } + c := &testClient{ + Request: testRequest{Method: "PUT", Path: testapi.Default.ResourcePath(getRCResourceName(), ns, "foo") + "/status", Query: buildQueryValues(nil)}, + Response: Response{ + StatusCode: 200, + Body: &api.ReplicationController{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Spec: api.ReplicationControllerSpec{ + Replicas: 2, + Template: &api.PodTemplateSpec{}, + }, + Status: api.ReplicationControllerStatus{ + Replicas: 2, + }, + }, + }, + } + receivedController, err := c.Setup(t).ReplicationControllers(ns).UpdateStatus(requestController) + c.Validate(t, receivedController, err) +} func TestDeleteController(t *testing.T) { ns := api.NamespaceDefault c := &testClient{ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go index b7fab1eec400..04c71854d634 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go @@ -18,7 +18,6 @@ package unversioned import ( "bytes" - "crypto/tls" "fmt" "io" "io/ioutil" @@ -31,14 +30,14 @@ import ( "time" "github.com/golang/glog" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/metrics" + "k8s.io/kubernetes/pkg/conversion/queryparams" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" - "k8s.io/kubernetes/pkg/util/httpstream" "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/watch" watchjson "k8s.io/kubernetes/pkg/watch/json" @@ -308,51 +307,19 @@ type versionToResourceToFieldMapping map[string]resourceTypeToFieldMapping func (v versionToResourceToFieldMapping) filterField(apiVersion, resourceType, field, value string) (newField, newValue string, err error) { rMapping, ok := v[apiVersion] if !ok { + glog.Warningf("Field selector: %v - %v - %v - %v: need to check if this is versioned correctly.", apiVersion, resourceType, field, value) return field, value, nil } newField, newValue, err = rMapping.filterField(resourceType, field, value) if err != nil { // This is only a warning until we find and fix all of the client's usages. + glog.Warningf("Field selector: %v - %v - %v - %v: need to check if this is versioned correctly.", apiVersion, resourceType, field, value) return field, value, nil } return newField, newValue, nil } var fieldMappings = versionToResourceToFieldMapping{ - "v1beta3": resourceTypeToFieldMapping{ - "nodes": clientFieldNameToAPIVersionFieldName{ - ObjectNameField: "metadata.name", - NodeUnschedulable: "spec.unschedulable", - }, - "minions": clientFieldNameToAPIVersionFieldName{ - ObjectNameField: "metadata.name", - NodeUnschedulable: "spec.unschedulable", - }, - "pods": clientFieldNameToAPIVersionFieldName{ - PodHost: "spec.host", - }, - "secrets": clientFieldNameToAPIVersionFieldName{ - SecretType: "type", - }, - "serviceAccounts": clientFieldNameToAPIVersionFieldName{ - ObjectNameField: "metadata.name", - }, - "endpoints": clientFieldNameToAPIVersionFieldName{ - ObjectNameField: "metadata.name", - }, - "events": clientFieldNameToAPIVersionFieldName{ - ObjectNameField: "metadata.name", - EventReason: "reason", - EventSource: "source", - EventInvolvedKind: "involvedObject.kind", - EventInvolvedNamespace: "involvedObject.namespace", - EventInvolvedName: "involvedObject.name", - EventInvolvedUID: "involvedObject.uid", - EventInvolvedAPIVersion: "involvedObject.apiVersion", - EventInvolvedResourceVersion: "involvedObject.resourceVersion", - EventInvolvedFieldPath: "involvedObject.fieldPath", - }, - }, "v1": resourceTypeToFieldMapping{ "nodes": clientFieldNameToAPIVersionFieldName{ ObjectNameField: "metadata.name", @@ -404,7 +371,7 @@ func (r *Request) FieldsSelectorParam(s fields.Selector) *Request { r.err = err return r } - return r.setParam(api.FieldSelectorQueryParam(r.apiVersion), s2.String()) + return r.setParam(unversioned.FieldSelectorQueryParam(r.apiVersion), s2.String()) } // LabelsSelectorParam adds the given selector as a query parameter @@ -418,7 +385,7 @@ func (r *Request) LabelsSelectorParam(s labels.Selector) *Request { if s.Empty() { return r } - return r.setParam(api.LabelSelectorQueryParam(r.apiVersion), s.String()) + return r.setParam(unversioned.LabelSelectorQueryParam(r.apiVersion), s.String()) } // UintParam creates a query parameter with the given value. @@ -437,6 +404,31 @@ func (r *Request) Param(paramName, s string) *Request { return r.setParam(paramName, s) } +// VersionedParams will take the provided object, serialize it to a map[string][]string using the +// implicit RESTClient API version and the provided object convertor, and then add those as parameters +// to the request. Use this to provide versioned query parameters from client libraries. +func (r *Request) VersionedParams(obj runtime.Object, convertor runtime.ObjectConvertor) *Request { + if r.err != nil { + return r + } + versioned, err := convertor.ConvertToVersion(obj, r.apiVersion) + if err != nil { + r.err = err + return r + } + params, err := queryparams.Convert(versioned) + if err != nil { + r.err = err + return r + } + for k, v := range params { + for _, vv := range v { + r.setParam(k, vv) + } + } + return r +} + func (r *Request) setParam(paramName, value string) *Request { if specialParams.Has(paramName) { r.err = fmt.Errorf("must set %v through the corresponding function, not directly.", paramName) @@ -644,43 +636,8 @@ func (r *Request) Stream() (io.ReadCloser, error) { } } -// Upgrade upgrades the request so that it supports multiplexed bidirectional -// streams. The current implementation uses SPDY, but this could be replaced -// with HTTP/2 once it's available, or something else. -func (r *Request) Upgrade(config *Config, newRoundTripperFunc func(*tls.Config) httpstream.UpgradeRoundTripper) (httpstream.Connection, error) { - if r.err != nil { - return nil, r.err - } - - tlsConfig, err := TLSConfigFor(config) - if err != nil { - return nil, err - } - - upgradeRoundTripper := newRoundTripperFunc(tlsConfig) - wrapper, err := HTTPWrappersForConfig(config, upgradeRoundTripper) - if err != nil { - return nil, err - } - - r.client = &http.Client{Transport: wrapper} - - req, err := http.NewRequest(r.verb, r.URL().String(), nil) - if err != nil { - return nil, fmt.Errorf("Error creating request: %s", err) - } - - resp, err := r.client.Do(req) - if err != nil { - return nil, fmt.Errorf("Error sending request: %s", err) - } - defer resp.Body.Close() - - return upgradeRoundTripper.NewConnection(resp) -} - // request connects to the server and invokes the provided function when a server response is -// received. It handles retry behavior and up front validation of requests. It wil invoke +// received. It handles retry behavior and up front validation of requests. It will invoke // fn at most once. It will return an error if a problem occurred prior to connecting to the // server - the provided function is responsible for handling server errors. func (r *Request) request(fn func(*http.Request, *http.Response)) error { @@ -789,7 +746,7 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu // Did the server give us a status response? isStatusResponse := false - var status api.Status + var status unversioned.Status if err := r.codec.DecodeInto(body, &status); err == nil && status.Status != "" { isStatusResponse = true } @@ -806,7 +763,7 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu // If the server gave us a status back, look at what it was. success := resp.StatusCode >= http.StatusOK && resp.StatusCode <= http.StatusPartialContent - if isStatusResponse && (status.Status != api.StatusSuccess && !success) { + if isStatusResponse && (status.Status != unversioned.StatusSuccess && !success) { // "Failed" requests are clearly just an error and it makes sense to return them as such. return Result{err: errors.FromObject(&status)} } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request_test.go index 7fbe26c55562..ce55d36c435a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request_test.go @@ -18,7 +18,6 @@ package unversioned import ( "bytes" - "crypto/tls" "encoding/base64" "errors" "io" @@ -34,8 +33,8 @@ import ( "k8s.io/kubernetes/pkg/api" apierrors "k8s.io/kubernetes/pkg/api/errors" - "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" @@ -158,6 +157,22 @@ func TestRequestParam(t *testing.T) { } } +func TestRequestVersionedParams(t *testing.T) { + r := (&Request{}).Param("foo", "a") + if !api.Semantic.DeepDerivative(r.params, url.Values{"foo": []string{"a"}}) { + t.Errorf("should have set a param: %#v", r) + } + r.VersionedParams(&api.PodLogOptions{Follow: true, Container: "bar"}, api.Scheme) + + if !api.Semantic.DeepDerivative(r.params, url.Values{ + "foo": []string{"a"}, + "container": []string{"bar"}, + "follow": []string{"1"}, + }) { + t.Errorf("should have set a param: %#v", r) + } +} + func TestRequestURI(t *testing.T) { r := (&Request{}).Param("foo", "a") r.Prefix("other") @@ -193,7 +208,7 @@ func TestRequestBody(t *testing.T) { } // test unencodable api object - r = (&Request{codec: latest.Codec}).Body(&NotAnAPIObject{}) + r = (&Request{codec: testapi.Default.Codec()}).Body(&NotAnAPIObject{}) if r.err == nil || r.body != nil { t.Errorf("should have set err and left body nil: %#v", r) } @@ -356,7 +371,7 @@ func TestTransformUnstructuredError(t *testing.T) { for _, testCase := range testCases { r := &Request{ - codec: latest.Codec, + codec: testapi.Default.Codec(), resourceName: testCase.Name, resource: testCase.Resource, } @@ -437,9 +452,9 @@ func TestRequestWatch(t *testing.T) { client: clientFunc(func(req *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusUnauthorized, - Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &api.Status{ - Status: api.StatusFailure, - Reason: api.StatusReasonUnauthorized, + Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &unversioned.Status{ + Status: unversioned.StatusFailure, + Reason: unversioned.StatusReasonUnauthorized, })))), }, nil }), @@ -537,13 +552,13 @@ func TestRequestStream(t *testing.T) { client: clientFunc(func(req *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusUnauthorized, - Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &api.Status{ - Status: api.StatusFailure, - Reason: api.StatusReasonUnauthorized, + Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &unversioned.Status{ + Status: unversioned.StatusFailure, + Reason: unversioned.StatusReasonUnauthorized, })))), }, nil }), - codec: latest.Codec, + codec: testapi.Default.Codec(), baseURL: &url.URL{}, }, Err: true, @@ -595,88 +610,6 @@ func (f *fakeUpgradeRoundTripper) NewConnection(resp *http.Response) (httpstream return f.conn, nil } -func TestRequestUpgrade(t *testing.T) { - uri, _ := url.Parse("http://localhost/") - testCases := []struct { - Request *Request - Config *Config - RoundTripper *fakeUpgradeRoundTripper - Err bool - AuthBasicHeader bool - AuthBearerHeader bool - }{ - { - Request: &Request{err: errors.New("bail")}, - Err: true, - }, - { - Request: &Request{}, - Config: &Config{ - TLSClientConfig: TLSClientConfig{ - CAFile: "foo", - }, - Insecure: true, - }, - Err: true, - }, - { - Request: &Request{}, - Config: &Config{ - Username: "u", - Password: "p", - BearerToken: "b", - }, - Err: true, - }, - { - Request: NewRequest(nil, "", uri, testapi.Default.Version(), testapi.Default.Codec()), - Config: &Config{ - Username: "u", - Password: "p", - }, - AuthBasicHeader: true, - Err: false, - }, - { - Request: NewRequest(nil, "", uri, testapi.Default.Version(), testapi.Default.Codec()), - Config: &Config{ - BearerToken: "b", - }, - AuthBearerHeader: true, - Err: false, - }, - } - for i, testCase := range testCases { - r := testCase.Request - rt := &fakeUpgradeRoundTripper{} - expectedConn := &fakeUpgradeConnection{} - conn, err := r.Upgrade(testCase.Config, func(config *tls.Config) httpstream.UpgradeRoundTripper { - rt.conn = expectedConn - return rt - }) - _ = conn - hasErr := err != nil - if hasErr != testCase.Err { - t.Errorf("%d: expected %t, got %t: %v", i, testCase.Err, hasErr, r.err) - } - if testCase.Err { - continue - } - - if testCase.AuthBasicHeader && !strings.Contains(rt.req.Header.Get("Authorization"), "Basic") { - t.Errorf("%d: expected basic auth header, got: %s", i, rt.req.Header.Get("Authorization")) - } - - if testCase.AuthBearerHeader && !strings.Contains(rt.req.Header.Get("Authorization"), "Bearer") { - t.Errorf("%d: expected bearer auth header, got: %s", i, rt.req.Header.Get("Authorization")) - } - - if e, a := expectedConn, conn; e != a { - t.Errorf("%d: conn: expected %#v, got %#v", i, e, a) - } - } -} - func TestRequestDo(t *testing.T) { testCases := []struct { Request *Request @@ -844,7 +777,7 @@ func TestDoRequestNewWayReader(t *testing.T) { } tmpStr := string(reqBodyExpected) requestURL := testapi.Default.ResourcePathWithPrefix("foo", "bar", "", "baz") - requestURL += "?" + api.LabelSelectorQueryParam(testapi.Default.Version()) + "=name%3Dfoo&timeout=1s" + requestURL += "?" + unversioned.LabelSelectorQueryParam(testapi.Default.Version()) + "=name%3Dfoo&timeout=1s" fakeHandler.ValidateRequest(t, requestURL, "POST", &tmpStr) if fakeHandler.RequestReceived.Header["Authorization"] == nil { t.Errorf("Request is missing authorization header: %#v", *fakeHandler.RequestReceived) @@ -886,7 +819,7 @@ func TestDoRequestNewWayObj(t *testing.T) { } tmpStr := string(reqBodyExpected) requestURL := testapi.Default.ResourcePath("foo", "", "bar/baz") - requestURL += "?" + api.LabelSelectorQueryParam(testapi.Default.Version()) + "=name%3Dfoo&timeout=1s" + requestURL += "?" + unversioned.LabelSelectorQueryParam(testapi.Default.Version()) + "=name%3Dfoo&timeout=1s" fakeHandler.ValidateRequest(t, requestURL, "POST", &tmpStr) if fakeHandler.RequestReceived.Header["Authorization"] == nil { t.Errorf("Request is missing authorization header: %#v", *fakeHandler.RequestReceived) @@ -1185,7 +1118,7 @@ func TestWatch(t *testing.T) { w.WriteHeader(http.StatusOK) flusher.Flush() - encoder := watchjson.NewEncoder(w, latest.Codec) + encoder := watchjson.NewEncoder(w, testapi.Default.Codec()) for _, item := range table { if err := encoder.Encode(&watch.Event{Type: item.t, Object: item.obj}); err != nil { panic(err) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/resource_quotas.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/resource_quotas.go index 3ca89c531418..46241be294e0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/resource_quotas.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/resource_quotas.go @@ -30,7 +30,7 @@ type ResourceQuotasNamespacer interface { // ResourceQuotaInterface has methods to work with ResourceQuota resources. type ResourceQuotaInterface interface { - List(selector labels.Selector) (*api.ResourceQuotaList, error) + List(label labels.Selector, field fields.Selector) (*api.ResourceQuotaList, error) Get(name string) (*api.ResourceQuota, error) Delete(name string) error Create(resourceQuota *api.ResourceQuota) (*api.ResourceQuota, error) @@ -54,9 +54,9 @@ func newResourceQuotas(c *Client, namespace string) *resourceQuotas { } // List takes a selector, and returns the list of resourceQuotas that match that selector. -func (c *resourceQuotas) List(selector labels.Selector) (result *api.ResourceQuotaList, err error) { +func (c *resourceQuotas) List(label labels.Selector, field fields.Selector) (result *api.ResourceQuotaList, err error) { result = &api.ResourceQuotaList{} - err = c.r.Get().Namespace(c.ns).Resource("resourceQuotas").LabelsSelectorParam(selector).Do().Into(result) + err = c.r.Get().Namespace(c.ns).Resource("resourceQuotas").LabelsSelectorParam(label).FieldsSelectorParam(field).Do().Into(result) return } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/resource_quotas_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/resource_quotas_test.go index 4c01070ae859..27688fb2cd4e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/resource_quotas_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/resource_quotas_test.go @@ -114,7 +114,7 @@ func TestResourceQuotaList(t *testing.T) { }, Response: Response{StatusCode: 200, Body: resourceQuotaList}, } - response, err := c.Setup(t).ResourceQuotas(ns).List(labels.Everything()) + response, err := c.Setup(t).ResourceQuotas(ns).List(labels.Everything(), fields.Everything()) c.Validate(t, response, err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/restclient_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/restclient_test.go index 942ccf5570ef..801485d9ba03 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/restclient_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/restclient_test.go @@ -22,9 +22,8 @@ import ( "reflect" "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" ) @@ -108,8 +107,8 @@ func TestValidatesHostParameter(t *testing.T) { } func TestDoRequestBearer(t *testing.T) { - status := &api.Status{Status: api.StatusFailure} - expectedBody, _ := latest.Codec.Encode(status) + status := &unversioned.Status{Status: unversioned.StatusFailure} + expectedBody, _ := testapi.Default.Codec().Encode(status) fakeHandler := util.FakeHandler{ StatusCode: 400, ResponseBody: string(expectedBody), @@ -137,8 +136,8 @@ func TestDoRequestBearer(t *testing.T) { } func TestDoRequestWithoutPassword(t *testing.T) { - status := &api.Status{Status: api.StatusFailure} - expectedBody, _ := latest.Codec.Encode(status) + status := &unversioned.Status{Status: unversioned.StatusFailure} + expectedBody, _ := testapi.Default.Codec().Encode(status) fakeHandler := util.FakeHandler{ StatusCode: 400, ResponseBody: string(expectedBody), @@ -176,8 +175,8 @@ func TestDoRequestWithoutPassword(t *testing.T) { } func TestDoRequestSuccess(t *testing.T) { - status := &api.Status{Status: api.StatusSuccess} - expectedBody, _ := latest.Codec.Encode(status) + status := &unversioned.Status{Status: unversioned.StatusSuccess} + expectedBody, _ := testapi.Default.Codec().Encode(status) fakeHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: string(expectedBody), @@ -202,7 +201,7 @@ func TestDoRequestSuccess(t *testing.T) { if fakeHandler.RequestReceived.Header["Authorization"] == nil { t.Errorf("Request is missing authorization header: %#v", fakeHandler.RequestReceived) } - statusOut, err := latest.Codec.Decode(body) + statusOut, err := testapi.Default.Codec().Decode(body) if err != nil { t.Errorf("Unexpected error %#v", err) } @@ -213,14 +212,14 @@ func TestDoRequestSuccess(t *testing.T) { } func TestDoRequestFailed(t *testing.T) { - status := &api.Status{ + status := &unversioned.Status{ Code: http.StatusNotFound, - Status: api.StatusFailure, - Reason: api.StatusReasonNotFound, + Status: unversioned.StatusFailure, + Reason: unversioned.StatusReasonNotFound, Message: " \"\" not found", - Details: &api.StatusDetails{}, + Details: &unversioned.StatusDetails{}, } - expectedBody, _ := latest.Codec.Encode(status) + expectedBody, _ := testapi.Default.Codec().Encode(status) fakeHandler := util.FakeHandler{ StatusCode: 404, ResponseBody: string(expectedBody), @@ -251,8 +250,8 @@ func TestDoRequestFailed(t *testing.T) { } func TestDoRequestCreated(t *testing.T) { - status := &api.Status{Status: api.StatusSuccess} - expectedBody, _ := latest.Codec.Encode(status) + status := &unversioned.Status{Status: unversioned.StatusSuccess} + expectedBody, _ := testapi.Default.Codec().Encode(status) fakeHandler := util.FakeHandler{ StatusCode: 201, ResponseBody: string(expectedBody), @@ -278,7 +277,7 @@ func TestDoRequestCreated(t *testing.T) { if !created { t.Errorf("Expected object to be created") } - statusOut, err := latest.Codec.Decode(body) + statusOut, err := testapi.Default.Codec().Decode(body) if err != nil { t.Errorf("Unexpected error %#v", err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/scale.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/scale.go index 8b664eb6750f..7663325b4877 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/scale.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/scale.go @@ -18,7 +18,7 @@ package unversioned import ( "k8s.io/kubernetes/pkg/api/meta" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" ) type ScaleNamespacer interface { @@ -27,18 +27,18 @@ type ScaleNamespacer interface { // ScaleInterface has methods to work with Scale (sub)resources. type ScaleInterface interface { - Get(string, string) (*experimental.Scale, error) - Update(string, *experimental.Scale) (*experimental.Scale, error) + Get(string, string) (*extensions.Scale, error) + Update(string, *extensions.Scale) (*extensions.Scale, error) } // horizontalPodAutoscalers implements HorizontalPodAutoscalersNamespacer interface type scales struct { - client *ExperimentalClient + client *ExtensionsClient ns string } // newHorizontalPodAutoscalers returns a horizontalPodAutoscalers -func newScales(c *ExperimentalClient, namespace string) *scales { +func newScales(c *ExtensionsClient, namespace string) *scales { return &scales{ client: c, ns: namespace, @@ -46,15 +46,15 @@ func newScales(c *ExperimentalClient, namespace string) *scales { } // Get takes the reference to scale subresource and returns the subresource or error, if one occurs. -func (c *scales) Get(kind string, name string) (result *experimental.Scale, err error) { - result = &experimental.Scale{} +func (c *scales) Get(kind string, name string) (result *extensions.Scale, err error) { + result = &extensions.Scale{} resource, _ := meta.KindToResource(kind, false) err = c.client.Get().Namespace(c.ns).Resource(resource).Name(name).SubResource("scale").Do().Into(result) return } -func (c *scales) Update(kind string, scale *experimental.Scale) (result *experimental.Scale, err error) { - result = &experimental.Scale{} +func (c *scales) Update(kind string, scale *extensions.Scale) (result *extensions.Scale, err error) { + result = &extensions.Scale{} resource, _ := meta.KindToResource(kind, false) err = c.client.Put(). Namespace(scale.Namespace). diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints.go deleted file mode 100644 index fc81d7713ed8..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints.go +++ /dev/null @@ -1,115 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 unversioned - -import ( - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/fields" - "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/watch" -) - -type SecurityContextConstraintsInterface interface { - SecurityContextConstraints() SecurityContextConstraintInterface -} - -type SecurityContextConstraintInterface interface { - Get(name string) (result *api.SecurityContextConstraints, err error) - Create(scc *api.SecurityContextConstraints) (*api.SecurityContextConstraints, error) - List(label labels.Selector, field fields.Selector) (*api.SecurityContextConstraintsList, error) - Delete(name string) error - Update(*api.SecurityContextConstraints) (*api.SecurityContextConstraints, error) - Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) -} - -// securityContextConstraints implements SecurityContextConstraintInterface -type securityContextConstraints struct { - client *Client -} - -// newSecurityContextConstraints returns a securityContextConstraints object. -func newSecurityContextConstraints(c *Client) *securityContextConstraints { - return &securityContextConstraints{c} -} - -func (s *securityContextConstraints) Create(scc *api.SecurityContextConstraints) (*api.SecurityContextConstraints, error) { - result := &api.SecurityContextConstraints{} - err := s.client.Post(). - Resource("securityContextConstraints"). - Body(scc). - Do(). - Into(result) - - return result, err -} - -// List returns a list of SecurityContextConstraints matching the selectors. -func (s *securityContextConstraints) List(label labels.Selector, field fields.Selector) (*api.SecurityContextConstraintsList, error) { - result := &api.SecurityContextConstraintsList{} - - err := s.client.Get(). - Resource("securityContextConstraints"). - LabelsSelectorParam(label). - FieldsSelectorParam(field). - Do(). - Into(result) - - return result, err -} - -// Get returns the given SecurityContextConstraints, or an error. -func (s *securityContextConstraints) Get(name string) (*api.SecurityContextConstraints, error) { - result := &api.SecurityContextConstraints{} - err := s.client.Get(). - Resource("securityContextConstraints"). - Name(name). - Do(). - Into(result) - - return result, err -} - -// Watch starts watching for SecurityContextConstraints matching the given selectors. -func (s *securityContextConstraints) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { - return s.client.Get(). - Prefix("watch"). - Resource("securityContextConstraints"). - Param("resourceVersion", resourceVersion). - LabelsSelectorParam(label). - FieldsSelectorParam(field). - Watch() -} - -func (s *securityContextConstraints) Delete(name string) error { - return s.client.Delete(). - Resource("securityContextConstraints"). - Name(name). - Do(). - Error() -} - -func (s *securityContextConstraints) Update(scc *api.SecurityContextConstraints) (result *api.SecurityContextConstraints, err error) { - result = &api.SecurityContextConstraints{} - err = s.client.Put(). - Resource("securityContextConstraints"). - Name(scc.Name). - Body(scc). - Do(). - Into(result) - - return -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints_test.go deleted file mode 100644 index ae91b79381e1..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints_test.go +++ /dev/null @@ -1,137 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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 unversioned - -import ( - "testing" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/fields" - "k8s.io/kubernetes/pkg/labels" - - "net/url" -) - -func TestSecurityContextConstraintsCreate(t *testing.T) { - ns := api.NamespaceNone - scc := &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{ - Name: "abc", - }, - } - - c := &testClient{ - Request: testRequest{ - Method: "POST", - Path: testapi.Default.ResourcePath(getSCCResoureName(), ns, ""), - Query: buildQueryValues(nil), - Body: scc, - }, - Response: Response{StatusCode: 200, Body: scc}, - } - - response, err := c.Setup(t).SecurityContextConstraints().Create(scc) - c.Validate(t, response, err) -} - -func TestSecurityContextConstraintsGet(t *testing.T) { - ns := api.NamespaceNone - scc := &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{ - Name: "abc", - }, - } - c := &testClient{ - Request: testRequest{ - Method: "GET", - Path: testapi.Default.ResourcePath(getSCCResoureName(), ns, "abc"), - Query: buildQueryValues(nil), - Body: nil, - }, - Response: Response{StatusCode: 200, Body: scc}, - } - - response, err := c.Setup(t).SecurityContextConstraints().Get("abc") - c.Validate(t, response, err) -} - -func TestSecurityContextConstraintsList(t *testing.T) { - ns := api.NamespaceNone - sccList := &api.SecurityContextConstraintsList{ - Items: []api.SecurityContextConstraints{ - { - ObjectMeta: api.ObjectMeta{ - Name: "abc", - }, - }, - }, - } - c := &testClient{ - Request: testRequest{ - Method: "GET", - Path: testapi.Default.ResourcePath(getSCCResoureName(), ns, ""), - Query: buildQueryValues(nil), - Body: nil, - }, - Response: Response{StatusCode: 200, Body: sccList}, - } - response, err := c.Setup(t).SecurityContextConstraints().List(labels.Everything(), fields.Everything()) - c.Validate(t, response, err) -} - -func TestSecurityContextConstraintsUpdate(t *testing.T) { - ns := api.NamespaceNone - scc := &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{ - Name: "abc", - ResourceVersion: "1", - }, - } - c := &testClient{ - Request: testRequest{Method: "PUT", Path: testapi.Default.ResourcePath(getSCCResoureName(), ns, "abc"), Query: buildQueryValues(nil)}, - Response: Response{StatusCode: 200, Body: scc}, - } - response, err := c.Setup(t).SecurityContextConstraints().Update(scc) - c.Validate(t, response, err) -} - -func TestSecurityContextConstraintsDelete(t *testing.T) { - ns := api.NamespaceNone - c := &testClient{ - Request: testRequest{Method: "DELETE", Path: testapi.Default.ResourcePath(getSCCResoureName(), ns, "foo"), Query: buildQueryValues(nil)}, - Response: Response{StatusCode: 200}, - } - err := c.Setup(t).SecurityContextConstraints().Delete("foo") - c.Validate(t, nil, err) -} - -func TestSecurityContextConstraintsWatch(t *testing.T) { - c := &testClient{ - Request: testRequest{ - Method: "GET", - Path: "/api/" + testapi.Default.Version() + "/watch/" + getSCCResoureName(), - Query: url.Values{"resourceVersion": []string{}}}, - Response: Response{StatusCode: 200}, - } - _, err := c.Setup(t).SecurityContextConstraints().Watch(labels.Everything(), fields.Everything(), "") - c.Validate(t, nil, err) -} - -func getSCCResoureName() string { - return "securitycontextconstraints" -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/services.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/services.go index 691e780790dd..54b1171e9a5a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/services.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/services.go @@ -30,7 +30,7 @@ type ServicesNamespacer interface { // ServiceInterface has methods to work with Service resources. type ServiceInterface interface { - List(selector labels.Selector) (*api.ServiceList, error) + List(label labels.Selector, field fields.Selector) (*api.ServiceList, error) Get(name string) (*api.Service, error) Create(srv *api.Service) (*api.Service, error) Update(srv *api.Service) (*api.Service, error) @@ -51,12 +51,13 @@ func newServices(c *Client, namespace string) *services { } // List takes a selector, and returns the list of services that match that selector -func (c *services) List(selector labels.Selector) (result *api.ServiceList, err error) { +func (c *services) List(label labels.Selector, field fields.Selector) (result *api.ServiceList, err error) { result = &api.ServiceList{} err = c.r.Get(). Namespace(c.ns). Resource("services"). - LabelsSelectorParam(selector). + LabelsSelectorParam(label). + FieldsSelectorParam(field). Do(). Into(result) return diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/services_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/services_test.go index fb1e638f0561..a491b09515fe 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/services_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/services_test.go @@ -22,6 +22,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" ) @@ -53,14 +55,14 @@ func TestListServices(t *testing.T) { }, }, } - receivedServiceList, err := c.Setup(t).Services(ns).List(labels.Everything()) + receivedServiceList, err := c.Setup(t).Services(ns).List(labels.Everything(), fields.Everything()) t.Logf("received services: %v %#v", err, receivedServiceList) c.Validate(t, receivedServiceList, err) } func TestListServicesLabels(t *testing.T) { ns := api.NamespaceDefault - labelSelectorQueryParamName := api.LabelSelectorQueryParam(testapi.Default.Version()) + labelSelectorQueryParamName := unversioned.LabelSelectorQueryParam(testapi.Default.Version()) c := &testClient{ Request: testRequest{ Method: "GET", @@ -90,7 +92,7 @@ func TestListServicesLabels(t *testing.T) { c.Setup(t) c.QueryValidator[labelSelectorQueryParamName] = validateLabels selector := labels.Set{"foo": "bar", "name": "baz"}.AsSelector() - receivedServiceList, err := c.Services(ns).List(selector) + receivedServiceList, err := c.Services(ns).List(selector, fields.Everything()) c.Validate(t, receivedServiceList, err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/actions.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/actions.go index ff4a6a701608..04132dc25ee4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/actions.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/actions.go @@ -100,6 +100,36 @@ func NewUpdateAction(resource, namespace string, object runtime.Object) UpdateAc return action } +func NewRootPatchAction(resource string, object runtime.Object) PatchActionImpl { + action := PatchActionImpl{} + action.Verb = "patch" + action.Resource = resource + action.Object = object + + return action +} + +func NewPatchAction(resource, namespace string, object runtime.Object) PatchActionImpl { + action := PatchActionImpl{} + action.Verb = "patch" + action.Resource = resource + action.Namespace = namespace + action.Object = object + + return action +} + +func NewUpdateSubresourceAction(resource, subresource, namespace string, object runtime.Object) UpdateActionImpl { + action := UpdateActionImpl{} + action.Verb = "update" + action.Resource = resource + action.Subresource = subresource + action.Namespace = namespace + action.Object = object + + return action +} + func NewRootDeleteAction(resource, name string) DeleteActionImpl { action := DeleteActionImpl{} action.Verb = "delete" @@ -278,6 +308,15 @@ func (a UpdateActionImpl) GetObject() runtime.Object { return a.Object } +type PatchActionImpl struct { + ActionImpl + Object runtime.Object +} + +func (a PatchActionImpl) GetObject() runtime.Object { + return a.Object +} + type DeleteActionImpl struct { ActionImpl Name string diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_daemon_sets.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_daemon_sets.go index 7b04ebd15345..9a096cc09bc4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_daemon_sets.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_daemon_sets.go @@ -17,7 +17,7 @@ limitations under the License. package testclient import ( - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" kClientLib "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -34,40 +34,48 @@ type FakeDaemonSets struct { // Ensure statically that FakeDaemonSets implements DaemonInterface. var _ kClientLib.DaemonSetInterface = &FakeDaemonSets{} -func (c *FakeDaemonSets) Get(name string) (*experimental.DaemonSet, error) { - obj, err := c.Fake.Invokes(NewGetAction("daemonsets", c.Namespace, name), &experimental.DaemonSet{}) +func (c *FakeDaemonSets) Get(name string) (*extensions.DaemonSet, error) { + obj, err := c.Fake.Invokes(NewGetAction("daemonsets", c.Namespace, name), &extensions.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*experimental.DaemonSet), err + return obj.(*extensions.DaemonSet), err } -func (c *FakeDaemonSets) List(label labels.Selector) (*experimental.DaemonSetList, error) { - obj, err := c.Fake.Invokes(NewListAction("daemonsets", c.Namespace, label, nil), &experimental.DaemonSetList{}) +func (c *FakeDaemonSets) List(label labels.Selector, field fields.Selector) (*extensions.DaemonSetList, error) { + obj, err := c.Fake.Invokes(NewListAction("daemonsets", c.Namespace, label, field), &extensions.DaemonSetList{}) if obj == nil { return nil, err } - return obj.(*experimental.DaemonSetList), err + return obj.(*extensions.DaemonSetList), err } -func (c *FakeDaemonSets) Create(daemon *experimental.DaemonSet) (*experimental.DaemonSet, error) { - obj, err := c.Fake.Invokes(NewCreateAction("daemonsets", c.Namespace, daemon), &experimental.DaemonSet{}) +func (c *FakeDaemonSets) Create(daemon *extensions.DaemonSet) (*extensions.DaemonSet, error) { + obj, err := c.Fake.Invokes(NewCreateAction("daemonsets", c.Namespace, daemon), &extensions.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*experimental.DaemonSet), err + return obj.(*extensions.DaemonSet), err } -func (c *FakeDaemonSets) Update(daemon *experimental.DaemonSet) (*experimental.DaemonSet, error) { - obj, err := c.Fake.Invokes(NewUpdateAction("daemonsets", c.Namespace, daemon), &experimental.DaemonSet{}) +func (c *FakeDaemonSets) Update(daemon *extensions.DaemonSet) (*extensions.DaemonSet, error) { + obj, err := c.Fake.Invokes(NewUpdateAction("daemonsets", c.Namespace, daemon), &extensions.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*experimental.DaemonSet), err + return obj.(*extensions.DaemonSet), err +} + +func (c *FakeDaemonSets) UpdateStatus(daemon *extensions.DaemonSet) (*extensions.DaemonSet, error) { + obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("daemonsets", "status", c.Namespace, daemon), &extensions.DaemonSet{}) + if obj == nil { + return nil, err + } + return obj.(*extensions.DaemonSet), err } func (c *FakeDaemonSets) Delete(name string) error { - _, err := c.Fake.Invokes(NewDeleteAction("daemonsets", c.Namespace, name), &experimental.DaemonSet{}) + _, err := c.Fake.Invokes(NewDeleteAction("daemonsets", c.Namespace, name), &extensions.DaemonSet{}) return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_deployments.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_deployments.go index 9433a385805e..6febc1298272 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_deployments.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_deployments.go @@ -18,7 +18,7 @@ package testclient import ( "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/watch" @@ -31,22 +31,22 @@ type FakeDeployments struct { Namespace string } -func (c *FakeDeployments) Get(name string) (*experimental.Deployment, error) { - obj, err := c.Fake.Invokes(NewGetAction("deployments", c.Namespace, name), &experimental.Deployment{}) +func (c *FakeDeployments) Get(name string) (*extensions.Deployment, error) { + obj, err := c.Fake.Invokes(NewGetAction("deployments", c.Namespace, name), &extensions.Deployment{}) if obj == nil { return nil, err } - return obj.(*experimental.Deployment), err + return obj.(*extensions.Deployment), err } -func (c *FakeDeployments) List(label labels.Selector, field fields.Selector) (*experimental.DeploymentList, error) { - obj, err := c.Fake.Invokes(NewListAction("deployments", c.Namespace, label, field), &experimental.DeploymentList{}) +func (c *FakeDeployments) List(label labels.Selector, field fields.Selector) (*extensions.DeploymentList, error) { + obj, err := c.Fake.Invokes(NewListAction("deployments", c.Namespace, label, field), &extensions.DeploymentList{}) if obj == nil { return nil, err } - list := &experimental.DeploymentList{} - for _, deployment := range obj.(*experimental.DeploymentList).Items { + list := &extensions.DeploymentList{} + for _, deployment := range obj.(*extensions.DeploymentList).Items { if label.Matches(labels.Set(deployment.Labels)) { list.Items = append(list.Items, deployment) } @@ -54,26 +54,26 @@ func (c *FakeDeployments) List(label labels.Selector, field fields.Selector) (*e return list, err } -func (c *FakeDeployments) Create(deployment *experimental.Deployment) (*experimental.Deployment, error) { +func (c *FakeDeployments) Create(deployment *extensions.Deployment) (*extensions.Deployment, error) { obj, err := c.Fake.Invokes(NewCreateAction("deployments", c.Namespace, deployment), deployment) if obj == nil { return nil, err } - return obj.(*experimental.Deployment), err + return obj.(*extensions.Deployment), err } -func (c *FakeDeployments) Update(deployment *experimental.Deployment) (*experimental.Deployment, error) { +func (c *FakeDeployments) Update(deployment *extensions.Deployment) (*extensions.Deployment, error) { obj, err := c.Fake.Invokes(NewUpdateAction("deployments", c.Namespace, deployment), deployment) if obj == nil { return nil, err } - return obj.(*experimental.Deployment), err + return obj.(*extensions.Deployment), err } func (c *FakeDeployments) Delete(name string, options *api.DeleteOptions) error { - _, err := c.Fake.Invokes(NewDeleteAction("deployments", c.Namespace, name), &experimental.Deployment{}) + _, err := c.Fake.Invokes(NewDeleteAction("deployments", c.Namespace, name), &extensions.Deployment{}) return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_events.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_events.go index 23cdc62eb600..f8186e9a8e37 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_events.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_events.go @@ -87,6 +87,20 @@ func (c *FakeEvents) Update(event *api.Event) (*api.Event, error) { return obj.(*api.Event), err } +// Patch patches an existing event. Returns the copy of the event the server returns, or an error. +func (c *FakeEvents) Patch(event *api.Event, data []byte) (*api.Event, error) { + action := NewRootPatchAction("events", event) + if c.Namespace != "" { + action = NewPatchAction("events", c.Namespace, event) + } + obj, err := c.Fake.Invokes(action, event) + if obj == nil { + return nil, err + } + + return obj.(*api.Event), err +} + func (c *FakeEvents) Delete(name string) error { action := NewRootDeleteAction("events", name) if c.Namespace != "" { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_horizontal_pod_autoscalers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_horizontal_pod_autoscalers.go index c7c920276860..bc901f9d4a07 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_horizontal_pod_autoscalers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_horizontal_pod_autoscalers.go @@ -18,7 +18,7 @@ package testclient import ( "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/watch" @@ -31,22 +31,22 @@ type FakeHorizontalPodAutoscalers struct { Namespace string } -func (c *FakeHorizontalPodAutoscalers) Get(name string) (*experimental.HorizontalPodAutoscaler, error) { - obj, err := c.Fake.Invokes(NewGetAction("horizontalpodautoscalers", c.Namespace, name), &experimental.HorizontalPodAutoscaler{}) +func (c *FakeHorizontalPodAutoscalers) Get(name string) (*extensions.HorizontalPodAutoscaler, error) { + obj, err := c.Fake.Invokes(NewGetAction("horizontalpodautoscalers", c.Namespace, name), &extensions.HorizontalPodAutoscaler{}) if obj == nil { return nil, err } - return obj.(*experimental.HorizontalPodAutoscaler), err + return obj.(*extensions.HorizontalPodAutoscaler), err } -func (c *FakeHorizontalPodAutoscalers) List(label labels.Selector, field fields.Selector) (*experimental.HorizontalPodAutoscalerList, error) { - obj, err := c.Fake.Invokes(NewListAction("horizontalpodautoscalers", c.Namespace, label, field), &experimental.HorizontalPodAutoscalerList{}) +func (c *FakeHorizontalPodAutoscalers) List(label labels.Selector, field fields.Selector) (*extensions.HorizontalPodAutoscalerList, error) { + obj, err := c.Fake.Invokes(NewListAction("horizontalpodautoscalers", c.Namespace, label, field), &extensions.HorizontalPodAutoscalerList{}) if obj == nil { return nil, err } - list := &experimental.HorizontalPodAutoscalerList{} - for _, a := range obj.(*experimental.HorizontalPodAutoscalerList).Items { + list := &extensions.HorizontalPodAutoscalerList{} + for _, a := range obj.(*extensions.HorizontalPodAutoscalerList).Items { if label.Matches(labels.Set(a.Labels)) { list.Items = append(list.Items, a) } @@ -54,26 +54,34 @@ func (c *FakeHorizontalPodAutoscalers) List(label labels.Selector, field fields. return list, err } -func (c *FakeHorizontalPodAutoscalers) Create(a *experimental.HorizontalPodAutoscaler) (*experimental.HorizontalPodAutoscaler, error) { +func (c *FakeHorizontalPodAutoscalers) Create(a *extensions.HorizontalPodAutoscaler) (*extensions.HorizontalPodAutoscaler, error) { obj, err := c.Fake.Invokes(NewCreateAction("horizontalpodautoscalers", c.Namespace, a), a) if obj == nil { return nil, err } - return obj.(*experimental.HorizontalPodAutoscaler), err + return obj.(*extensions.HorizontalPodAutoscaler), err } -func (c *FakeHorizontalPodAutoscalers) Update(a *experimental.HorizontalPodAutoscaler) (*experimental.HorizontalPodAutoscaler, error) { +func (c *FakeHorizontalPodAutoscalers) Update(a *extensions.HorizontalPodAutoscaler) (*extensions.HorizontalPodAutoscaler, error) { obj, err := c.Fake.Invokes(NewUpdateAction("horizontalpodautoscalers", c.Namespace, a), a) if obj == nil { return nil, err } - return obj.(*experimental.HorizontalPodAutoscaler), err + return obj.(*extensions.HorizontalPodAutoscaler), err +} + +func (c *FakeHorizontalPodAutoscalers) UpdateStatus(a *extensions.HorizontalPodAutoscaler) (*extensions.HorizontalPodAutoscaler, error) { + obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("horizontalpodautoscalers", "status", c.Namespace, a), &extensions.HorizontalPodAutoscaler{}) + if obj == nil { + return nil, err + } + return obj.(*extensions.HorizontalPodAutoscaler), err } func (c *FakeHorizontalPodAutoscalers) Delete(name string, options *api.DeleteOptions) error { - _, err := c.Fake.Invokes(NewDeleteAction("horizontalpodautoscalers", c.Namespace, name), &experimental.HorizontalPodAutoscaler{}) + _, err := c.Fake.Invokes(NewDeleteAction("horizontalpodautoscalers", c.Namespace, name), &extensions.HorizontalPodAutoscaler{}) return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_ingress.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_ingress.go new file mode 100644 index 000000000000..30be16ffb83b --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_ingress.go @@ -0,0 +1,86 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 testclient + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/watch" +) + +// FakeIngress implements IngressInterface. Meant to be embedded into a struct to get a default +// implementation. This makes faking out just the method you want to test easier. +type FakeIngress struct { + Fake *FakeExperimental + Namespace string +} + +func (c *FakeIngress) Get(name string) (*extensions.Ingress, error) { + obj, err := c.Fake.Invokes(NewGetAction("ingress", c.Namespace, name), &extensions.Ingress{}) + if obj == nil { + return nil, err + } + + return obj.(*extensions.Ingress), err +} + +func (c *FakeIngress) List(label labels.Selector, fields fields.Selector) (*extensions.IngressList, error) { + obj, err := c.Fake.Invokes(NewListAction("ingress", c.Namespace, label, nil), &extensions.IngressList{}) + if obj == nil { + return nil, err + } + + return obj.(*extensions.IngressList), err +} + +func (c *FakeIngress) Create(ingress *extensions.Ingress) (*extensions.Ingress, error) { + obj, err := c.Fake.Invokes(NewCreateAction("ingress", c.Namespace, ingress), ingress) + if obj == nil { + return nil, err + } + + return obj.(*extensions.Ingress), err +} + +func (c *FakeIngress) Update(ingress *extensions.Ingress) (*extensions.Ingress, error) { + obj, err := c.Fake.Invokes(NewUpdateAction("ingress", c.Namespace, ingress), ingress) + if obj == nil { + return nil, err + } + + return obj.(*extensions.Ingress), err +} + +func (c *FakeIngress) Delete(name string, options *api.DeleteOptions) error { + _, err := c.Fake.Invokes(NewDeleteAction("ingress", c.Namespace, name), &extensions.Ingress{}) + return err +} + +func (c *FakeIngress) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { + return c.Fake.InvokesWatch(NewWatchAction("ingress", c.Namespace, label, field, resourceVersion)) +} + +func (c *FakeIngress) UpdateStatus(ingress *extensions.Ingress) (result *extensions.Ingress, err error) { + obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("ingress", "status", c.Namespace, ingress), ingress) + if obj == nil { + return nil, err + } + + return obj.(*extensions.Ingress), err +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_jobs.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_jobs.go new file mode 100644 index 000000000000..6bd1e71802ad --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_jobs.go @@ -0,0 +1,86 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 testclient + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/watch" +) + +// FakeJobs implements JobInterface. Meant to be embedded into a struct to get a default +// implementation. This makes faking out just the method you want to test easier. +type FakeJobs struct { + Fake *FakeExperimental + Namespace string +} + +func (c *FakeJobs) Get(name string) (*extensions.Job, error) { + obj, err := c.Fake.Invokes(NewGetAction("jobs", c.Namespace, name), &extensions.Job{}) + if obj == nil { + return nil, err + } + + return obj.(*extensions.Job), err +} + +func (c *FakeJobs) List(label labels.Selector, fields fields.Selector) (*extensions.JobList, error) { + obj, err := c.Fake.Invokes(NewListAction("jobs", c.Namespace, label, nil), &extensions.JobList{}) + if obj == nil { + return nil, err + } + + return obj.(*extensions.JobList), err +} + +func (c *FakeJobs) Create(job *extensions.Job) (*extensions.Job, error) { + obj, err := c.Fake.Invokes(NewCreateAction("jobs", c.Namespace, job), job) + if obj == nil { + return nil, err + } + + return obj.(*extensions.Job), err +} + +func (c *FakeJobs) Update(job *extensions.Job) (*extensions.Job, error) { + obj, err := c.Fake.Invokes(NewUpdateAction("jobs", c.Namespace, job), job) + if obj == nil { + return nil, err + } + + return obj.(*extensions.Job), err +} + +func (c *FakeJobs) Delete(name string, options *api.DeleteOptions) error { + _, err := c.Fake.Invokes(NewDeleteAction("jobs", c.Namespace, name), &extensions.Job{}) + return err +} + +func (c *FakeJobs) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { + return c.Fake.InvokesWatch(NewWatchAction("jobs", c.Namespace, label, field, resourceVersion)) +} + +func (c *FakeJobs) UpdateStatus(job *extensions.Job) (result *extensions.Job, err error) { + obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("jobs", "status", c.Namespace, job), job) + if obj == nil { + return nil, err + } + + return obj.(*extensions.Job), err +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_limit_ranges.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_limit_ranges.go index f7f72feaa337..473f3d19dff5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_limit_ranges.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_limit_ranges.go @@ -39,8 +39,8 @@ func (c *FakeLimitRanges) Get(name string) (*api.LimitRange, error) { return obj.(*api.LimitRange), err } -func (c *FakeLimitRanges) List(label labels.Selector) (*api.LimitRangeList, error) { - obj, err := c.Fake.Invokes(NewListAction("limitranges", c.Namespace, label, nil), &api.LimitRangeList{}) +func (c *FakeLimitRanges) List(label labels.Selector, field fields.Selector) (*api.LimitRangeList, error) { + obj, err := c.Fake.Invokes(NewListAction("limitranges", c.Namespace, label, field), &api.LimitRangeList{}) if obj == nil { return nil, err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_nodes.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_nodes.go index 5a1b2de4cbd2..ff70ce376827 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_nodes.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_nodes.go @@ -23,7 +23,7 @@ import ( "k8s.io/kubernetes/pkg/watch" ) -// FakeNodes implements MinionInterface. Meant to be embedded into a struct to get a default +// FakeNodes implements NodeInterface. Meant to be embedded into a struct to get a default // implementation. This makes faking out just the method you want to test easier. type FakeNodes struct { Fake *Fake @@ -47,8 +47,8 @@ func (c *FakeNodes) List(label labels.Selector, field fields.Selector) (*api.Nod return obj.(*api.NodeList), err } -func (c *FakeNodes) Create(minion *api.Node) (*api.Node, error) { - obj, err := c.Fake.Invokes(NewRootCreateAction("nodes", minion), minion) +func (c *FakeNodes) Create(node *api.Node) (*api.Node, error) { + obj, err := c.Fake.Invokes(NewRootCreateAction("nodes", node), node) if obj == nil { return nil, err } @@ -56,8 +56,8 @@ func (c *FakeNodes) Create(minion *api.Node) (*api.Node, error) { return obj.(*api.Node), err } -func (c *FakeNodes) Update(minion *api.Node) (*api.Node, error) { - obj, err := c.Fake.Invokes(NewRootUpdateAction("nodes", minion), minion) +func (c *FakeNodes) Update(node *api.Node) (*api.Node, error) { + obj, err := c.Fake.Invokes(NewRootUpdateAction("nodes", node), node) if obj == nil { return nil, err } @@ -74,14 +74,14 @@ func (c *FakeNodes) Watch(label labels.Selector, field fields.Selector, resource return c.Fake.InvokesWatch(NewRootWatchAction("nodes", label, field, resourceVersion)) } -func (c *FakeNodes) UpdateStatus(minion *api.Node) (*api.Node, error) { +func (c *FakeNodes) UpdateStatus(node *api.Node) (*api.Node, error) { action := CreateActionImpl{} action.Verb = "update" action.Resource = "nodes" action.Subresource = "status" - action.Object = minion + action.Object = node - obj, err := c.Fake.Invokes(action, minion) + obj, err := c.Fake.Invokes(action, node) if obj == nil { return nil, err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_persistent_volume_claims.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_persistent_volume_claims.go index a0ca6526a5d4..d5752a1339eb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_persistent_volume_claims.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_persistent_volume_claims.go @@ -74,13 +74,7 @@ func (c *FakePersistentVolumeClaims) Watch(label labels.Selector, field fields.S } func (c *FakePersistentVolumeClaims) UpdateStatus(claim *api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error) { - action := UpdateActionImpl{} - action.Verb = "update" - action.Resource = "persistentvolumeclaims" - action.Subresource = "status" - action.Object = claim - - obj, err := c.Fake.Invokes(action, claim) + obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("persistentvolumeclaims", "status", c.Namespace, claim), claim) if obj == nil { return nil, err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_pods.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_pods.go index 1c30306462d2..05cda9f84c80 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_pods.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_pods.go @@ -92,13 +92,7 @@ func (c *FakePods) Bind(binding *api.Binding) error { } func (c *FakePods) UpdateStatus(pod *api.Pod) (*api.Pod, error) { - action := UpdateActionImpl{} - action.Verb = "update" - action.Resource = "pods" - action.Subresource = "status" - action.Object = pod - - obj, err := c.Fake.Invokes(action, pod) + obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("pods", "status", c.Namespace, pod), pod) if obj == nil { return nil, err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_replication_controllers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_replication_controllers.go index 34307e3579d2..c9eeddd88493 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_replication_controllers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_replication_controllers.go @@ -39,8 +39,8 @@ func (c *FakeReplicationControllers) Get(name string) (*api.ReplicationControlle return obj.(*api.ReplicationController), err } -func (c *FakeReplicationControllers) List(label labels.Selector) (*api.ReplicationControllerList, error) { - obj, err := c.Fake.Invokes(NewListAction("replicationcontrollers", c.Namespace, label, nil), &api.ReplicationControllerList{}) +func (c *FakeReplicationControllers) List(label labels.Selector, field fields.Selector) (*api.ReplicationControllerList, error) { + obj, err := c.Fake.Invokes(NewListAction("replicationcontrollers", c.Namespace, label, field), &api.ReplicationControllerList{}) if obj == nil { return nil, err } @@ -66,6 +66,14 @@ func (c *FakeReplicationControllers) Update(controller *api.ReplicationControlle return obj.(*api.ReplicationController), err } +func (c *FakeReplicationControllers) UpdateStatus(controller *api.ReplicationController) (*api.ReplicationController, error) { + obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("replicationcontrollers", "status", c.Namespace, controller), &api.ReplicationController{}) + if obj == nil { + return nil, err + } + return obj.(*api.ReplicationController), err +} + func (c *FakeReplicationControllers) Delete(name string) error { _, err := c.Fake.Invokes(NewDeleteAction("replicationcontrollers", c.Namespace, name), &api.ReplicationController{}) return err diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_resource_quotas.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_resource_quotas.go index 69ea6ca782ce..9dd2bd4f4a05 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_resource_quotas.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_resource_quotas.go @@ -39,8 +39,8 @@ func (c *FakeResourceQuotas) Get(name string) (*api.ResourceQuota, error) { return obj.(*api.ResourceQuota), err } -func (c *FakeResourceQuotas) List(label labels.Selector) (*api.ResourceQuotaList, error) { - obj, err := c.Fake.Invokes(NewListAction("resourcequotas", c.Namespace, label, nil), &api.ResourceQuotaList{}) +func (c *FakeResourceQuotas) List(label labels.Selector, field fields.Selector) (*api.ResourceQuotaList, error) { + obj, err := c.Fake.Invokes(NewListAction("resourcequotas", c.Namespace, label, field), &api.ResourceQuotaList{}) if obj == nil { return nil, err } @@ -76,13 +76,7 @@ func (c *FakeResourceQuotas) Watch(label labels.Selector, field fields.Selector, } func (c *FakeResourceQuotas) UpdateStatus(resourceQuota *api.ResourceQuota) (*api.ResourceQuota, error) { - action := UpdateActionImpl{} - action.Verb = "update" - action.Resource = "resourcequotas" - action.Subresource = "status" - action.Object = resourceQuota - - obj, err := c.Fake.Invokes(action, resourceQuota) + obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("resourcequotas", "status", c.Namespace, resourceQuota), resourceQuota) if obj == nil { return nil, err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_scales.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_scales.go index 9c29f61e4f0a..53ff5f87df36 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_scales.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_scales.go @@ -17,7 +17,7 @@ limitations under the License. package testclient import ( - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" ) // FakeScales implements ScaleInterface. Meant to be embedded into a struct to get a default @@ -27,19 +27,19 @@ type FakeScales struct { Namespace string } -func (c *FakeScales) Get(kind string, name string) (result *experimental.Scale, err error) { +func (c *FakeScales) Get(kind string, name string) (result *extensions.Scale, err error) { action := GetActionImpl{} action.Verb = "get" action.Namespace = c.Namespace action.Resource = kind action.Subresource = "scale" action.Name = name - obj, err := c.Fake.Invokes(action, &experimental.Scale{}) - result = obj.(*experimental.Scale) + obj, err := c.Fake.Invokes(action, &extensions.Scale{}) + result = obj.(*extensions.Scale) return } -func (c *FakeScales) Update(kind string, scale *experimental.Scale) (result *experimental.Scale, err error) { +func (c *FakeScales) Update(kind string, scale *extensions.Scale) (result *extensions.Scale, err error) { action := UpdateActionImpl{} action.Verb = "update" action.Namespace = c.Namespace @@ -47,6 +47,6 @@ func (c *FakeScales) Update(kind string, scale *experimental.Scale) (result *exp action.Subresource = "scale" action.Object = scale obj, err := c.Fake.Invokes(action, scale) - result = obj.(*experimental.Scale) + result = obj.(*extensions.Scale) return } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_securitycontextconstraints.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_securitycontextconstraints.go deleted file mode 100644 index d7e13ef1f5a6..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_securitycontextconstraints.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 testclient - -import ( - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/fields" - "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/watch" -) - -// FakeSecurityContextConstraints implements SecurityContextConstraintInterface. Meant to be -// embedded into a struct to get a default implementation. This makes faking out just -// the method you want to test easier. -type FakeSecurityContextConstraints struct { - Fake *Fake - Namespace string -} - -func (c *FakeSecurityContextConstraints) List(label labels.Selector, field fields.Selector) (*api.SecurityContextConstraintsList, error) { - obj, err := c.Fake.Invokes(NewListAction("securitycontextconstraints", c.Namespace, label, field), &api.SecurityContextConstraintsList{}) - return obj.(*api.SecurityContextConstraintsList), err -} - -func (c *FakeSecurityContextConstraints) Get(name string) (*api.SecurityContextConstraints, error) { - obj, err := c.Fake.Invokes(NewGetAction("securitycontextconstraints", c.Namespace, name), &api.SecurityContextConstraints{}) - return obj.(*api.SecurityContextConstraints), err -} - -func (c *FakeSecurityContextConstraints) Create(scc *api.SecurityContextConstraints) (*api.SecurityContextConstraints, error) { - obj, err := c.Fake.Invokes(NewCreateAction("securitycontextconstraints", c.Namespace, scc), &api.SecurityContextConstraints{}) - return obj.(*api.SecurityContextConstraints), err -} - -func (c *FakeSecurityContextConstraints) Update(scc *api.SecurityContextConstraints) (*api.SecurityContextConstraints, error) { - obj, err := c.Fake.Invokes(NewUpdateAction("securitycontextconstraints", c.Namespace, scc), &api.SecurityContextConstraints{}) - return obj.(*api.SecurityContextConstraints), err -} - -func (c *FakeSecurityContextConstraints) Delete(name string) error { - _, err := c.Fake.Invokes(NewDeleteAction("securitycontextconstraints", c.Namespace, name), &api.SecurityContextConstraints{}) - return err -} - -func (c *FakeSecurityContextConstraints) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { - return c.Fake.InvokesWatch(NewWatchAction("securitycontextconstraints", c.Namespace, label, field, resourceVersion)) -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_services.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_services.go index a24b2db5bb71..caaadbb81877 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_services.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_services.go @@ -40,8 +40,8 @@ func (c *FakeServices) Get(name string) (*api.Service, error) { return obj.(*api.Service), err } -func (c *FakeServices) List(label labels.Selector) (*api.ServiceList, error) { - obj, err := c.Fake.Invokes(NewListAction("services", c.Namespace, label, nil), &api.ServiceList{}) +func (c *FakeServices) List(label labels.Selector, field fields.Selector) (*api.ServiceList, error) { + obj, err := c.Fake.Invokes(NewListAction("services", c.Namespace, label, field), &api.ServiceList{}) if obj == nil { return nil, err } @@ -77,6 +77,5 @@ func (c *FakeServices) Watch(label labels.Selector, field fields.Selector, resou } func (c *FakeServices) ProxyGet(name, path string, params map[string]string) unversioned.ResponseWrapper { - c.Fake.Invokes(NewProxyGetAction("services", c.Namespace, name, path, params), nil) - return nil + return c.Fake.InvokesProxy(NewProxyGetAction("services", c.Namespace, name, path, params)) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fixture.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fixture.go index ce0f750e7572..fd515ec037cb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fixture.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fixture.go @@ -25,6 +25,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" + client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/yaml" "k8s.io/kubernetes/pkg/watch" @@ -182,11 +184,11 @@ func (o objects) Kind(kind, name string) (runtime.Object, error) { } o.last[kind] = index + 1 - if status, ok := out.(*api.Status); ok { + if status, ok := out.(*unversioned.Status); ok { if status.Details != nil { status.Details.Kind = kind } - if status.Status != api.StatusSuccess { + if status.Status != unversioned.StatusSuccess { return nilValue, &errors.StatusError{ErrStatus: *status} } } @@ -219,7 +221,7 @@ func (o objects) Add(obj runtime.Object) error { } } default: - if status, ok := obj.(*api.Status); ok && status.Details != nil { + if status, ok := obj.(*unversioned.Status); ok && status.Details != nil { kind = status.Details.Kind } o.types[kind] = append(o.types[kind], obj) @@ -260,7 +262,7 @@ func (r *SimpleReactor) React(action Action) (bool, runtime.Object, error) { return r.Reaction(action) } -// SimpleWatchReactor is a Reactor. Each reaction function is attached to a given verb,resource tuple. "*" in either field matches everything for that value. +// SimpleWatchReactor is a WatchReactor. Each reaction function is attached to a given resource. "*" matches everything for that value. // For instance, *,pods matches all verbs on pods. This allows for easier composition of reaction functions type SimpleWatchReactor struct { Resource string @@ -280,3 +282,24 @@ func (r *SimpleWatchReactor) Handles(action Action) bool { func (r *SimpleWatchReactor) React(action Action) (bool, watch.Interface, error) { return r.Reaction(action) } + +// SimpleProxyReactor is a ProxyReactor. Each reaction function is attached to a given resource. "*" matches everything for that value. +// For instance, *,pods matches all verbs on pods. This allows for easier composition of reaction functions. +type SimpleProxyReactor struct { + Resource string + + Reaction ProxyReactionFunc +} + +func (r *SimpleProxyReactor) Handles(action Action) bool { + resourceCovers := r.Resource == "*" || r.Resource == action.GetResource() + if !resourceCovers { + return false + } + + return true +} + +func (r *SimpleProxyReactor) React(action Action) (bool, client.ResponseWrapper, error) { + return r.Reaction(action) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient.go index 11c1f4026359..fe0e2fdcd75f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient.go @@ -20,9 +20,11 @@ import ( "fmt" "sync" + "github.com/emicklei/go-restful/swagger" + "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/registered" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/version" @@ -39,7 +41,7 @@ func NewSimpleFake(objects ...runtime.Object) *Fake { } fakeClient := &Fake{} - fakeClient.AddReactor("*", "*", ObjectReaction(o, latest.RESTMapper)) + fakeClient.AddReactor("*", "*", ObjectReaction(o, api.RESTMapper)) fakeClient.AddWatchReactor("*", DefaultWatchReactor(watch.NewFake(), nil)) @@ -56,6 +58,8 @@ type Fake struct { ReactionChain []Reactor // WatchReactionChain is the list of watch reactors that will be attempted for every request in the order they are tried WatchReactionChain []WatchReactor + // ProxyReactionChain is the list of proxy reactors that will be attempted for every request in the order they are tried + ProxyReactionChain []ProxyReactor } // Reactor is an interface to allow the composition of reaction functions. @@ -74,6 +78,14 @@ type WatchReactor interface { React(action Action) (handled bool, ret watch.Interface, err error) } +// ProxyReactor is an interface to allow the composition of proxy get functions. +type ProxyReactor interface { + // Handles indicates whether or not this Reactor deals with a given action + Handles(action Action) bool + // React handles a watch action and returns results. It may choose to delegate by indicated handled=false + React(action Action) (handled bool, ret client.ResponseWrapper, err error) +} + // ReactionFunc is a function that returns an object or error for a given Action. If "handled" is false, // then the test client will continue ignore the results and continue to the next ReactionFunc type ReactionFunc func(action Action) (handled bool, ret runtime.Object, err error) @@ -82,6 +94,10 @@ type ReactionFunc func(action Action) (handled bool, ret runtime.Object, err err // then the test client will continue ignore the results and continue to the next ReactionFunc type WatchReactionFunc func(action Action) (handled bool, ret watch.Interface, err error) +// ProxyReactionFunc is a function that returns a ResponseWrapper interface for a given Action. If "handled" is false, +// then the test client will continue ignore the results and continue to the next ProxyReactionFunc +type ProxyReactionFunc func(action Action) (handled bool, ret client.ResponseWrapper, err error) + // AddReactor appends a reactor to the end of the chain func (c *Fake) AddReactor(verb, resource string, reaction ReactionFunc) { c.ReactionChain = append(c.ReactionChain, &SimpleReactor{verb, resource, reaction}) @@ -89,10 +105,7 @@ func (c *Fake) AddReactor(verb, resource string, reaction ReactionFunc) { // PrependReactor adds a reactor to the beginning of the chain func (c *Fake) PrependReactor(verb, resource string, reaction ReactionFunc) { - newChain := make([]Reactor, 0, len(c.ReactionChain)+1) - newChain = append(newChain, &SimpleReactor{verb, resource, reaction}) - newChain = append(newChain, c.ReactionChain...) - c.ReactionChain = newChain + c.ReactionChain = append([]Reactor{&SimpleReactor{verb, resource, reaction}}, c.ReactionChain...) } // AddWatchReactor appends a reactor to the end of the chain @@ -102,10 +115,17 @@ func (c *Fake) AddWatchReactor(resource string, reaction WatchReactionFunc) { // PrependWatchReactor adds a reactor to the beginning of the chain func (c *Fake) PrependWatchReactor(resource string, reaction WatchReactionFunc) { - newChain := make([]WatchReactor, 0, len(c.WatchReactionChain)+1) - newChain = append(newChain, &SimpleWatchReactor{resource, reaction}) - newChain = append(newChain, c.WatchReactionChain...) - c.WatchReactionChain = newChain + c.WatchReactionChain = append([]WatchReactor{&SimpleWatchReactor{resource, reaction}}, c.WatchReactionChain...) +} + +// AddProxyReactor appends a reactor to the end of the chain +func (c *Fake) AddProxyReactor(resource string, reaction ProxyReactionFunc) { + c.ProxyReactionChain = append(c.ProxyReactionChain, &SimpleProxyReactor{resource, reaction}) +} + +// PrependProxyReactor adds a reactor to the beginning of the chain +func (c *Fake) PrependProxyReactor(resource string, reaction ProxyReactionFunc) { + c.ProxyReactionChain = append([]ProxyReactor{&SimpleProxyReactor{resource, reaction}}, c.ProxyReactionChain...) } // Invokes records the provided Action and then invokes the ReactFn (if provided). @@ -153,6 +173,28 @@ func (c *Fake) InvokesWatch(action Action) (watch.Interface, error) { return nil, fmt.Errorf("unhandled watch: %#v", action) } +// InvokesProxy records the provided Action and then invokes the ReactFn (if provided). +func (c *Fake) InvokesProxy(action Action) client.ResponseWrapper { + c.Lock() + defer c.Unlock() + + c.actions = append(c.actions, action) + for _, reactor := range c.ProxyReactionChain { + if !reactor.Handles(action) { + continue + } + + handled, ret, err := reactor.React(action) + if !handled || err != nil { + continue + } + + return ret + } + + return nil +} + // ClearActions clears the history of actions called on the fake client func (c *Fake) ClearActions() { c.Lock() @@ -186,10 +228,6 @@ func (c *Fake) Nodes() client.NodeInterface { return &FakeNodes{Fake: c} } -func (c *Fake) SecurityContextConstraints() client.SecurityContextConstraintInterface { - return &FakeSecurityContextConstraints{Fake: c} -} - func (c *Fake) Events(namespace string) client.EventInterface { return &FakeEvents{Fake: c, Namespace: namespace} } @@ -230,7 +268,7 @@ func (c *Fake) Namespaces() client.NamespaceInterface { return &FakeNamespaces{Fake: c} } -func (c *Fake) Experimental() client.ExperimentalInterface { +func (c *Fake) Extensions() client.ExtensionsInterface { return &FakeExperimental{c} } @@ -244,19 +282,29 @@ func (c *Fake) ServerVersion() (*version.Info, error) { return &versionInfo, nil } -func (c *Fake) ServerAPIVersions() (*api.APIVersions, error) { +func (c *Fake) ServerAPIVersions() (*unversioned.APIVersions, error) { action := ActionImpl{} action.Verb = "get" action.Resource = "apiversions" c.Invokes(action, nil) - return &api.APIVersions{Versions: registered.RegisteredVersions}, nil + return &unversioned.APIVersions{Versions: registered.RegisteredVersions}, nil } func (c *Fake) ComponentStatuses() client.ComponentStatusInterface { return &FakeComponentStatuses{Fake: c} } +// SwaggerSchema returns an empty swagger.ApiDeclaration for testing +func (c *Fake) SwaggerSchema(version string) (*swagger.ApiDeclaration, error) { + action := ActionImpl{} + action.Verb = "get" + action.Resource = "/swaggerapi/api/" + version + + c.Invokes(action, nil) + return &swagger.ApiDeclaration{}, nil +} + type FakeExperimental struct { *Fake } @@ -276,3 +324,11 @@ func (c *FakeExperimental) Deployments(namespace string) client.DeploymentInterf func (c *FakeExperimental) Scales(namespace string) client.ScaleInterface { return &FakeScales{Fake: c, Namespace: namespace} } + +func (c *FakeExperimental) Jobs(namespace string) client.JobInterface { + return &FakeJobs{Fake: c, Namespace: namespace} +} + +func (c *FakeExperimental) Ingress(namespace string) client.IngressInterface { + return &FakeIngress{Fake: c, Namespace: namespace} +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient_test.go index a8e1f85381d4..9ee7d77e1273 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient_test.go @@ -21,7 +21,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" ) @@ -32,8 +33,8 @@ func TestNewClient(t *testing.T) { t.Fatal(err) } client := &Fake{} - client.AddReactor("*", "*", ObjectReaction(o, latest.RESTMapper)) - list, err := client.Services("test").List(labels.Everything()) + client.AddReactor("*", "*", ObjectReaction(o, testapi.Default.RESTMapper())) + list, err := client.Services("test").List(labels.Everything(), fields.Everything()) if err != nil { t.Fatal(err) } @@ -42,7 +43,7 @@ func TestNewClient(t *testing.T) { } // When list is invoked a second time, the same results are returned. - list, err = client.Services("test").List(labels.Everything()) + list, err = client.Services("test").List(labels.Everything(), fields.Everything()) if err != nil { t.Fatal(err) } @@ -63,13 +64,13 @@ func TestErrors(t *testing.T) { }, }) client := &Fake{} - client.AddReactor("*", "*", ObjectReaction(o, latest.RESTMapper)) - _, err := client.Services("test").List(labels.Everything()) + client.AddReactor("*", "*", ObjectReaction(o, testapi.Default.RESTMapper())) + _, err := client.Services("test").List(labels.Everything(), fields.Everything()) if !errors.IsNotFound(err) { t.Fatalf("unexpected error: %v", err) } t.Logf("error: %#v", err.(*errors.StatusError).Status()) - _, err = client.Services("test").List(labels.Everything()) + _, err = client.Services("test").List(labels.Everything(), fields.Everything()) if !errors.IsForbidden(err) { t.Fatalf("unexpected error: %v", err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/transport.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/transport.go index f31b1a47e126..405b495c21df 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/transport.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/transport.go @@ -110,28 +110,32 @@ func TLSConfigFor(config *Config) (*tls.Config, error) { hasCA := len(config.CAFile) > 0 || len(config.CAData) > 0 hasCert := len(config.CertFile) > 0 || len(config.CertData) > 0 + if !hasCA && !hasCert && !config.Insecure { + return nil, nil + } if hasCA && config.Insecure { return nil, fmt.Errorf("specifying a root certificates file with the insecure flag is not allowed") } if err := LoadTLSFiles(config); err != nil { return nil, err } - var tlsConfig *tls.Config - switch { - case hasCert: - cfg, err := NewClientCertTLSConfig(config.CertData, config.KeyData, config.CAData) - if err != nil { - return nil, err - } - tlsConfig = cfg - case hasCA: - cfg, err := NewTLSConfig(config.CAData) + + tlsConfig := &tls.Config{ + // Change default from SSLv3 to TLSv1.0 (because of POODLE vulnerability) + MinVersion: tls.VersionTLS10, + InsecureSkipVerify: config.Insecure, + } + + if hasCA { + tlsConfig.RootCAs = rootCertPool(config.CAData) + } + + if hasCert { + cert, err := tls.X509KeyPair(config.CertData, config.KeyData) if err != nil { return nil, err } - tlsConfig = cfg - case config.Insecure: - tlsConfig = NewUnsafeTLSConfig() + tlsConfig.Certificates = []tls.Certificate{cert} } return tlsConfig, nil @@ -186,30 +190,6 @@ func dataFromSliceOrFile(data []byte, file string) ([]byte, error) { return nil, nil } -func NewClientCertTLSConfig(certData, keyData, caData []byte) (*tls.Config, error) { - cert, err := tls.X509KeyPair(certData, keyData) - if err != nil { - return nil, err - } - - return &tls.Config{ - // Change default from SSLv3 to TLSv1.0 (because of POODLE vulnerability) - MinVersion: tls.VersionTLS10, - Certificates: []tls.Certificate{ - cert, - }, - RootCAs: rootCertPool(caData), - }, nil -} - -func NewTLSConfig(caData []byte) (*tls.Config, error) { - return &tls.Config{ - // Change default from SSLv3 to TLSv1.0 (because of POODLE vulnerability) - MinVersion: tls.VersionTLS10, - RootCAs: rootCertPool(caData), - }, nil -} - // rootCertPool returns nil if caData is empty. When passed along, this will mean "use system CAs". // When caData is not empty, it will be the ONLY information used in the CertPool. func rootCertPool(caData []byte) *x509.CertPool { @@ -226,12 +206,6 @@ func rootCertPool(caData []byte) *x509.CertPool { return certPool } -func NewUnsafeTLSConfig() *tls.Config { - return &tls.Config{ - InsecureSkipVerify: true, - } -} - // cloneRequest returns a clone of the provided *http.Request. // The clone is a shallow copy of the struct and its Header map. func cloneRequest(r *http.Request) *http.Request { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/transport_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/transport_test.go index 3b8d1bed0a2f..8ba609110f44 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/transport_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/transport_test.go @@ -21,16 +21,9 @@ import ( "net/http" "testing" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/testapi" ) -func TestUnsecuredTLSTransport(t *testing.T) { - cfg := NewUnsafeTLSConfig() - if !cfg.InsecureSkipVerify { - t.Errorf("expected config to be insecure") - } -} - type testRoundTripper struct { Request *http.Request Response *http.Response @@ -109,7 +102,7 @@ func TestTLSConfigKey(t *testing.T) { "host": {Host: "foo"}, "prefix": {Prefix: "foo"}, "version": {Version: "foo"}, - "codec": {Codec: latest.Codec}, + "codec": {Codec: testapi.Default.Codec()}, "basic": {Username: "bob", Password: "password"}, "bearer": {BearerToken: "token"}, "user agent": {UserAgent: "useragent"}, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/cloud.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/cloud.go index 9212f740a6c5..fff0bddf9f19 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/cloud.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/cloud.go @@ -43,7 +43,7 @@ type Interface interface { // Clusters is an abstract, pluggable interface for clusters of containers. type Clusters interface { - // List lists the names of the available clusters. + // ListClusters lists the names of the available clusters. ListClusters() ([]string, error) // Master gets back the address (either DNS name or IP address) of the master node for the cluster. Master(clusterName string) (string, error) @@ -110,7 +110,7 @@ type Instances interface { // AddSSHKeyToAllInstances adds an SSH public key as a legal identity for all instances // expected format for the key is standard ssh-keygen format: AddSSHKeyToAllInstances(user string, keyData []byte) error - // Returns the name of the node we are currently running on + // CurrentNodeName returns the name of the node we are currently running on // On most clouds (e.g. GCE) this is the hostname, so we provide the hostname CurrentNodeName(hostname string) (string, error) } @@ -123,20 +123,20 @@ type Route struct { // TargetInstance is the name of the instance as specified in routing rules // for the cloud-provider (in gce: the Instance Name). TargetInstance string - // Destination CIDR is the CIDR format IP range that this routing rule + // DestinationCIDR is the CIDR format IP range that this routing rule // applies to. DestinationCIDR string } // Routes is an abstract, pluggable interface for advanced routing rules. type Routes interface { - // List all managed routes that belong to the specified clusterName + // ListRoutes lists all managed routes that belong to the specified clusterName ListRoutes(clusterName string) ([]*Route, error) - // Create the described managed route + // CreateRoute creates the described managed route // route.Name will be ignored, although the cloud-provider may use nameHint // to create a more user-meaningful name. CreateRoute(clusterName string, nameHint string, route *Route) error - // Delete the specified managed route + // DeleteRoute deletes the specified managed route // Route should be as returned by ListRoutes DeleteRoute(clusterName string, route *Route) error } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws.go index f5376e9abc08..d4cc2d01b83f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "net/url" @@ -33,6 +32,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" + "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/service/autoscaling" "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/elb" @@ -40,6 +41,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/cloudprovider" + "k8s.io/kubernetes/pkg/util/sets" "github.com/golang/glog" ) @@ -60,7 +62,7 @@ type AWSServices interface { Compute(region string) (EC2, error) LoadBalancing(region string) (ELB, error) Autoscaling(region string) (ASG, error) - Metadata() AWSMetadata + Metadata() (EC2Metadata, error) } // TODO: Should we rename this to AWS (EBS & ELB are not technically part of EC2) @@ -89,8 +91,6 @@ type EC2 interface { AuthorizeSecurityGroupIngress(*ec2.AuthorizeSecurityGroupIngressInput) (*ec2.AuthorizeSecurityGroupIngressOutput, error) RevokeSecurityGroupIngress(*ec2.RevokeSecurityGroupIngressInput) (*ec2.RevokeSecurityGroupIngressOutput, error) - DescribeVPCs(*ec2.DescribeVPCsInput) ([]*ec2.VPC, error) - DescribeSubnets(*ec2.DescribeSubnetsInput) ([]*ec2.Subnet, error) CreateTags(*ec2.CreateTagsInput) (*ec2.CreateTagsOutput, error) @@ -128,9 +128,9 @@ type ASG interface { } // Abstraction over the AWS metadata service -type AWSMetadata interface { +type EC2Metadata interface { // Query the EC2 metadata service (used to discover instance-id etc) - GetMetaData(key string) ([]byte, error) + GetMetadata(path string) (string, error) } type VolumeOptions struct { @@ -170,9 +170,10 @@ type InstanceGroupInfo interface { // AWSCloud is an implementation of Interface, TCPLoadBalancer and Instances for Amazon Web Services. type AWSCloud struct { - awsServices AWSServices ec2 EC2 + elb ELB asg ASG + metadata EC2Metadata cfg *AWSCloudConfig availabilityZone string region string @@ -183,8 +184,6 @@ type AWSCloud struct { selfAWSInstance *awsInstance mutex sync.Mutex - // Protects elbClients - elbClients map[string]ELB } type AWSCloudConfig struct { @@ -209,7 +208,7 @@ type awsSDKProvider struct { func (p *awsSDKProvider) Compute(regionName string) (EC2, error) { ec2 := &awsSdkEC2{ ec2: ec2.New(&aws.Config{ - Region: regionName, + Region: ®ionName, Credentials: p.creds, }), } @@ -218,7 +217,7 @@ func (p *awsSDKProvider) Compute(regionName string) (EC2, error) { func (p *awsSDKProvider) LoadBalancing(regionName string) (ELB, error) { elbClient := elb.New(&aws.Config{ - Region: regionName, + Region: ®ionName, Credentials: p.creds, }) return elbClient, nil @@ -226,31 +225,15 @@ func (p *awsSDKProvider) LoadBalancing(regionName string) (ELB, error) { func (p *awsSDKProvider) Autoscaling(regionName string) (ASG, error) { client := autoscaling.New(&aws.Config{ - Region: regionName, + Region: ®ionName, Credentials: p.creds, }) return client, nil } -func (p *awsSDKProvider) Metadata() AWSMetadata { - return &awsSdkMetadata{} -} - -// Builds an ELB client for the specified region -func (s *AWSCloud) getELBClient(regionName string) (ELB, error) { - s.mutex.Lock() - defer s.mutex.Unlock() - - elbClient, found := s.elbClients[regionName] - if !found { - var err error - elbClient, err = s.awsServices.LoadBalancing(regionName) - if err != nil { - return nil, err - } - s.elbClients[regionName] = elbClient - } - return elbClient, nil +func (p *awsSDKProvider) Metadata() (EC2Metadata, error) { + client := ec2metadata.New(nil) + return client, nil } func stringPointerArray(orig []string) []*string { @@ -324,34 +307,16 @@ func (self *awsSdkEC2) DescribeInstances(request *ec2.DescribeInstancesInput) ([ } type awsSdkMetadata struct { + metadata *ec2metadata.Client } var metadataClient = http.Client{ Timeout: time.Second * 10, } -// Implements AWSMetadata.GetMetaData -func (self *awsSdkMetadata) GetMetaData(key string) ([]byte, error) { - // TODO Get an implementation of this merged into aws-sdk-go - url := "http://169.254.169.254/latest/meta-data/" + key - - res, err := metadataClient.Get(url) - if err != nil { - return nil, err - } - defer res.Body.Close() - - if res.StatusCode != 200 { - err = fmt.Errorf("Code %d returned for url %s", res.StatusCode, url) - return nil, fmt.Errorf("Error querying AWS metadata for key %s: %v", key, err) - } - - body, err := ioutil.ReadAll(res.Body) - if err != nil { - return nil, fmt.Errorf("Error querying AWS metadata for key %s: %v", key, err) - } - - return []byte(body), nil +// Implements EC2Metadata.GetMetadata +func (self *awsSdkMetadata) GetMetadata(path string) (string, error) { + return self.metadata.GetMetadata(path) } // Implements EC2.DescribeSecurityGroups @@ -367,8 +332,8 @@ func (s *awsSdkEC2) DescribeSecurityGroups(request *ec2.DescribeSecurityGroupsIn func (s *awsSdkEC2) AttachVolume(volumeID, instanceId, device string) (resp *ec2.VolumeAttachment, err error) { request := ec2.AttachVolumeInput{ Device: &device, - InstanceID: &instanceId, - VolumeID: &volumeID, + InstanceId: &instanceId, + VolumeId: &volumeID, } return s.ec2.AttachVolume(&request) } @@ -406,19 +371,10 @@ func (s *awsSdkEC2) CreateVolume(request *ec2.CreateVolumeInput) (resp *ec2.Volu } func (s *awsSdkEC2) DeleteVolume(volumeID string) (resp *ec2.DeleteVolumeOutput, err error) { - request := ec2.DeleteVolumeInput{VolumeID: &volumeID} + request := ec2.DeleteVolumeInput{VolumeId: &volumeID} return s.ec2.DeleteVolume(&request) } -func (s *awsSdkEC2) DescribeVPCs(request *ec2.DescribeVPCsInput) ([]*ec2.VPC, error) { - // VPCs are not paged - response, err := s.ec2.DescribeVPCs(request) - if err != nil { - return nil, fmt.Errorf("error listing AWS VPCs: %v", err) - } - return response.VPCs, nil -} - func (s *awsSdkEC2) DescribeSubnets(request *ec2.DescribeSubnetsInput) ([]*ec2.Subnet, error) { // Subnets are not paged response, err := s.ec2.DescribeSubnets(request) @@ -474,7 +430,7 @@ func init() { creds := credentials.NewChainCredentials( []credentials.Provider{ &credentials.EnvProvider{}, - &credentials.EC2RoleProvider{}, + &ec2rolecreds.EC2RoleProvider{}, &credentials.SharedCredentialsProvider{}, }) aws := &awsSDKProvider{creds: creds} @@ -483,7 +439,7 @@ func init() { } // readAWSCloudConfig reads an instance of AWSCloudConfig from config reader. -func readAWSCloudConfig(config io.Reader, metadata AWSMetadata) (*AWSCloudConfig, error) { +func readAWSCloudConfig(config io.Reader, metadata EC2Metadata) (*AWSCloudConfig, error) { var cfg AWSCloudConfig var err error @@ -510,15 +466,8 @@ func readAWSCloudConfig(config io.Reader, metadata AWSMetadata) (*AWSCloudConfig return &cfg, nil } -func getAvailabilityZone(metadata AWSMetadata) (string, error) { - availabilityZoneBytes, err := metadata.GetMetaData("placement/availability-zone") - if err != nil { - return "", err - } - if availabilityZoneBytes == nil || len(availabilityZoneBytes) == 0 { - return "", fmt.Errorf("Unable to determine availability-zone from instance metadata") - } - return string(availabilityZoneBytes), nil +func getAvailabilityZone(metadata EC2Metadata) (string, error) { + return metadata.GetMetadata("placement/availability-zone") } func isRegionValid(region string) bool { @@ -531,6 +480,8 @@ func isRegionValid(region string) bool { "ap-southeast-1", "ap-southeast-2", "ap-northeast-1", + "cn-north-1", + "us-gov-west-1", "sa-east-1", } for _, r := range regions { @@ -544,7 +495,11 @@ func isRegionValid(region string) bool { // newAWSCloud creates a new instance of AWSCloud. // AWSProvider and instanceId are primarily for tests func newAWSCloud(config io.Reader, awsServices AWSServices) (*AWSCloud, error) { - metadata := awsServices.Metadata() + metadata, err := awsServices.Metadata() + if err != nil { + return nil, fmt.Errorf("error creating AWS metadata client: %v", err) + } + cfg, err := readAWSCloudConfig(config, metadata) if err != nil { return nil, fmt.Errorf("unable to read AWS cloud provider config file: %v", err) @@ -566,19 +521,24 @@ func newAWSCloud(config io.Reader, awsServices AWSServices) (*AWSCloud, error) { return nil, fmt.Errorf("error creating AWS EC2 client: %v", err) } + elb, err := awsServices.LoadBalancing(regionName) + if err != nil { + return nil, fmt.Errorf("error creating AWS ELB client: %v", err) + } + asg, err := awsServices.Autoscaling(regionName) if err != nil { return nil, fmt.Errorf("error creating AWS autoscaling client: %v", err) } awsCloud := &AWSCloud{ - awsServices: awsServices, ec2: ec2, + elb: elb, asg: asg, + metadata: metadata, cfg: cfg, region: regionName, availabilityZone: zone, - elbClients: map[string]ELB{}, } filterTags := map[string]string{} @@ -648,11 +608,11 @@ func (aws *AWSCloud) NodeAddresses(name string) ([]api.NodeAddress, error) { addresses := []api.NodeAddress{} - if !isNilOrEmpty(instance.PrivateIPAddress) { - ipAddress := *instance.PrivateIPAddress + if !isNilOrEmpty(instance.PrivateIpAddress) { + ipAddress := *instance.PrivateIpAddress ip := net.ParseIP(ipAddress) if ip == nil { - return nil, fmt.Errorf("EC2 instance had invalid private address: %s (%s)", orEmpty(instance.InstanceID), ipAddress) + return nil, fmt.Errorf("EC2 instance had invalid private address: %s (%s)", orEmpty(instance.InstanceId), ipAddress) } addresses = append(addresses, api.NodeAddress{Type: api.NodeInternalIP, Address: ip.String()}) @@ -661,11 +621,11 @@ func (aws *AWSCloud) NodeAddresses(name string) ([]api.NodeAddress, error) { } // TODO: Other IP addresses (multiple ips)? - if !isNilOrEmpty(instance.PublicIPAddress) { - ipAddress := *instance.PublicIPAddress + if !isNilOrEmpty(instance.PublicIpAddress) { + ipAddress := *instance.PublicIpAddress ip := net.ParseIP(ipAddress) if ip == nil { - return nil, fmt.Errorf("EC2 instance had invalid public address: %s (%s)", orEmpty(instance.InstanceID), ipAddress) + return nil, fmt.Errorf("EC2 instance had invalid public address: %s (%s)", orEmpty(instance.InstanceId), ipAddress) } addresses = append(addresses, api.NodeAddress{Type: api.NodeExternalIP, Address: ip.String()}) } @@ -684,7 +644,7 @@ func (aws *AWSCloud) ExternalID(name string) (string, error) { if instance == nil || !isAlive(instance) { return "", cloudprovider.InstanceNotFound } - return orEmpty(instance.InstanceID), nil + return orEmpty(instance.InstanceId), nil } // InstanceID returns the cloud provider ID of the specified instance. @@ -696,7 +656,7 @@ func (aws *AWSCloud) InstanceID(name string) (string, error) { } // In the future it is possible to also return an endpoint as: // // - return "/" + orEmpty(inst.Placement.AvailabilityZone) + "/" + orEmpty(inst.InstanceID), nil + return "/" + orEmpty(inst.Placement.AvailabilityZone) + "/" + orEmpty(inst.InstanceId), nil } // Check if the instance is alive (running or pending) @@ -713,7 +673,7 @@ func isAlive(instance *ec2.Instance) bool { case "pending", "running": return true default: - glog.Errorf("unknown EC2 instance state: %s", stateName) + glog.Errorf("Unknown EC2 instance state: %s", stateName) return false } } @@ -754,14 +714,14 @@ func (s *AWSCloud) getInstancesByRegex(regex string) ([]string, error) { // Only return fully-ready instances when listing instances // (vs a query by name, where we will return it if we find it) if orEmpty(instance.State.Name) == "pending" { - glog.V(2).Infof("skipping EC2 instance (pending): %s", *instance.InstanceID) + glog.V(2).Infof("Skipping EC2 instance (pending): %s", *instance.InstanceId) continue } - privateDNSName := orEmpty(instance.PrivateDNSName) + privateDNSName := orEmpty(instance.PrivateDnsName) if privateDNSName == "" { - glog.V(2).Infof("skipping EC2 instance (no PrivateDNSName): %s", - orEmpty(instance.InstanceID)) + glog.V(2).Infof("Skipping EC2 instance (no PrivateDNSName): %s", + orEmpty(instance.InstanceId)) continue } @@ -784,10 +744,6 @@ func (aws *AWSCloud) List(filter string) ([]string, error) { // GetZone implements Zones.GetZone func (self *AWSCloud) GetZone() (cloudprovider.Zone, error) { - if self.availabilityZone == "" { - // Should be unreachable - panic("availabilityZone not set") - } return cloudprovider.Zone{ FailureDomain: self.availabilityZone, Region: self.region, @@ -845,7 +801,7 @@ func (self *awsInstance) getInstanceType() *awsInstanceType { func (self *awsInstance) getInfo() (*ec2.Instance, error) { instanceID := self.awsID request := &ec2.DescribeInstancesInput{ - InstanceIDs: []*string{&instanceID}, + InstanceIds: []*string{&instanceID}, } instances, err := self.ec2.DescribeInstances(request) @@ -890,7 +846,7 @@ func (self *awsInstance) assignMountpoint(volumeID string) (mountpoint string, a if strings.HasPrefix(mountpoint, "/dev/xvd") { mountpoint = mountpoint[8:] } - deviceMappings[mountpoint] = orEmpty(blockDevice.EBS.VolumeID) + deviceMappings[mountpoint] = orEmpty(blockDevice.Ebs.VolumeId) } self.deviceMappings = deviceMappings } @@ -992,7 +948,7 @@ func (self *awsDisk) getInfo() (*ec2.Volume, error) { volumeID := self.awsID request := &ec2.DescribeVolumesInput{ - VolumeIDs: []*string{&volumeID}, + VolumeIds: []*string{&volumeID}, } volumes, err := self.ec2.DescribeVolumes(request) @@ -1071,17 +1027,16 @@ func (s *AWSCloud) getSelfAWSInstance() (*awsInstance, error) { i := s.selfAWSInstance if i == nil { - metadata := s.awsServices.Metadata() - instanceIdBytes, err := metadata.GetMetaData("instance-id") + instanceId, err := s.metadata.GetMetadata("instance-id") if err != nil { return nil, fmt.Errorf("error fetching instance-id from ec2 metadata service: %v", err) } - privateDnsNameBytes, err := metadata.GetMetaData("local-hostname") + privateDnsName, err := s.metadata.GetMetadata("local-hostname") if err != nil { return nil, fmt.Errorf("error fetching local-hostname from ec2 metadata service: %v", err) } - i = newAWSInstance(s.ec2, string(instanceIdBytes), string(privateDnsNameBytes)) + i = newAWSInstance(s.ec2, instanceId, privateDnsName) s.selfAWSInstance = i } @@ -1103,7 +1058,7 @@ func (aws *AWSCloud) getAwsInstance(nodeName string) (*awsInstance, error) { return nil, fmt.Errorf("error finding instance %s: %v", nodeName, err) } - awsInstance = newAWSInstance(aws.ec2, orEmpty(instance.InstanceID), orEmpty(instance.PrivateDNSName)) + awsInstance = newAWSInstance(aws.ec2, orEmpty(instance.InstanceId), orEmpty(instance.PrivateDnsName)) } return awsInstance, nil @@ -1181,8 +1136,8 @@ func (aws *AWSCloud) DetachDisk(instanceName string, diskName string) error { } request := ec2.DetachVolumeInput{ - InstanceID: &awsInstance.awsID, - VolumeID: &disk.awsID, + InstanceId: &awsInstance.awsID, + VolumeId: &disk.awsID, } response, err := aws.ec2.DetachVolume(&request) @@ -1215,7 +1170,7 @@ func (aws *AWSCloud) CreateVolume(volumeOptions *VolumeOptions) (string, error) } az := orEmpty(response.AvailabilityZone) - awsID := orEmpty(response.VolumeID) + awsID := orEmpty(response.VolumeId) volumeName := "aws://" + az + "/" + awsID @@ -1240,16 +1195,11 @@ func (v *AWSCloud) Release(name string) error { } // Gets the current load balancer state -func (s *AWSCloud) describeLoadBalancer(region, name string) (*elb.LoadBalancerDescription, error) { - elbClient, err := s.getELBClient(region) - if err != nil { - return nil, err - } - +func (s *AWSCloud) describeLoadBalancer(name string) (*elb.LoadBalancerDescription, error) { request := &elb.DescribeLoadBalancersInput{} request.LoadBalancerNames = []*string{&name} - response, err := elbClient.DescribeLoadBalancers(request) + response, err := s.elb.DescribeLoadBalancers(request) if err != nil { if awsError, ok := err.(awserr.Error); ok { if awsError.Code() == "LoadBalancerNotFound" { @@ -1269,75 +1219,32 @@ func (s *AWSCloud) describeLoadBalancer(region, name string) (*elb.LoadBalancerD return ret, nil } -// TCPLoadBalancerExists implements TCPLoadBalancer.TCPLoadBalancerExists. -func (self *AWSCloud) TCPLoadBalancerExists(name, region string) (bool, error) { - lb, err := self.describeLoadBalancer(name, region) - if err != nil { - return false, err - } - - if lb != nil { - return true, nil - } - return false, nil -} - // Retrieves instance's vpc id from metadata func (self *AWSCloud) findVPCID() (string, error) { - - metadata := self.awsServices.Metadata() - macsBytes, err := metadata.GetMetaData("network/interfaces/macs/") + macs, err := self.metadata.GetMetadata("network/interfaces/macs/") if err != nil { return "", fmt.Errorf("Could not list interfaces of the instance", err) } // loop over interfaces, first vpc id returned wins - for _, macPath := range strings.Split(string(macsBytes), "\n") { - + for _, macPath := range strings.Split(macs, "\n") { if len(macPath) == 0 { continue } url := fmt.Sprintf("network/interfaces/macs/%svpc-id", macPath) - vpcIDBytes, err := metadata.GetMetaData(url) + vpcID, err := self.metadata.GetMetadata(url) if err != nil { continue } - return string(vpcIDBytes), nil + return vpcID, nil } - return "", fmt.Errorf("Could not find VPC id in instance metadata") -} - -// Find the kubernetes VPC -func (self *AWSCloud) findVPC() (*ec2.VPC, error) { - request := &ec2.DescribeVPCsInput{} - - // find by vpcID from metadata - vpcID, err := self.findVPCID() - if err != nil { - return nil, err - } - filters := []*ec2.Filter{newEc2Filter("vpc-id", vpcID)} - request.Filters = self.addFilters(filters) - - vpcs, err := self.ec2.DescribeVPCs(request) - if err != nil { - glog.Error("error listing VPCs", err) - return nil, err - } - - if len(vpcs) == 0 { - return nil, nil - } - if len(vpcs) == 1 { - return vpcs[0], nil - } - return nil, fmt.Errorf("Found multiple matching VPCs for vpcID = %s", vpcID) + return "", fmt.Errorf("Could not find VPC ID in instance metadata") } // Retrieves the specified security group from the AWS API, or returns nil if not found func (s *AWSCloud) findSecurityGroup(securityGroupId string) (*ec2.SecurityGroup, error) { describeSecurityGroupsRequest := &ec2.DescribeSecurityGroupsInput{ - GroupIDs: []*string{&securityGroupId}, + GroupIds: []*string{&securityGroupId}, } groups, err := s.ec2.DescribeSecurityGroups(describeSecurityGroupsRequest) @@ -1376,34 +1283,34 @@ func isEqualStringPointer(l, r *string) bool { return *l == *r } -func isEqualIPPermission(l, r *ec2.IPPermission, compareGroupUserIDs bool) bool { +func isEqualIPPermission(l, r *ec2.IpPermission, compareGroupUserIDs bool) bool { if !isEqualIntPointer(l.FromPort, r.FromPort) { return false } if !isEqualIntPointer(l.ToPort, r.ToPort) { return false } - if !isEqualStringPointer(l.IPProtocol, r.IPProtocol) { + if !isEqualStringPointer(l.IpProtocol, r.IpProtocol) { return false } - if len(l.IPRanges) != len(r.IPRanges) { + if len(l.IpRanges) != len(r.IpRanges) { return false } - for j := range l.IPRanges { - if !isEqualStringPointer(l.IPRanges[j].CIDRIP, r.IPRanges[j].CIDRIP) { + for j := range l.IpRanges { + if !isEqualStringPointer(l.IpRanges[j].CidrIp, r.IpRanges[j].CidrIp) { return false } } - if len(l.UserIDGroupPairs) != len(r.UserIDGroupPairs) { + if len(l.UserIdGroupPairs) != len(r.UserIdGroupPairs) { return false } - for j := range l.UserIDGroupPairs { - if !isEqualStringPointer(l.UserIDGroupPairs[j].GroupID, r.UserIDGroupPairs[j].GroupID) { + for j := range l.UserIdGroupPairs { + if !isEqualStringPointer(l.UserIdGroupPairs[j].GroupId, r.UserIdGroupPairs[j].GroupId) { return false } if compareGroupUserIDs { - if !isEqualStringPointer(l.UserIDGroupPairs[j].UserID, r.UserIDGroupPairs[j].UserID) { + if !isEqualStringPointer(l.UserIdGroupPairs[j].UserId, r.UserIdGroupPairs[j].UserId) { return false } } @@ -1413,9 +1320,9 @@ func isEqualIPPermission(l, r *ec2.IPPermission, compareGroupUserIDs bool) bool } // Makes sure the security group includes the specified permissions -// Returns true iff changes were made +// Returns true if and only if changes were made // The security group must already exist -func (s *AWSCloud) ensureSecurityGroupIngress(securityGroupId string, addPermissions []*ec2.IPPermission) (bool, error) { +func (s *AWSCloud) ensureSecurityGroupIngress(securityGroupId string, addPermissions []*ec2.IpPermission) (bool, error) { group, err := s.findSecurityGroup(securityGroupId) if err != nil { glog.Warning("error retrieving security group", err) @@ -1426,17 +1333,17 @@ func (s *AWSCloud) ensureSecurityGroupIngress(securityGroupId string, addPermiss return false, fmt.Errorf("security group not found: %s", securityGroupId) } - changes := []*ec2.IPPermission{} + changes := []*ec2.IpPermission{} for _, addPermission := range addPermissions { hasUserID := false - for i := range addPermission.UserIDGroupPairs { - if addPermission.UserIDGroupPairs[i].UserID != nil { + for i := range addPermission.UserIdGroupPairs { + if addPermission.UserIdGroupPairs[i].UserId != nil { hasUserID = true } } found := false - for _, groupPermission := range group.IPPermissions { + for _, groupPermission := range group.IpPermissions { if isEqualIPPermission(addPermission, groupPermission, hasUserID) { found = true break @@ -1455,8 +1362,8 @@ func (s *AWSCloud) ensureSecurityGroupIngress(securityGroupId string, addPermiss glog.V(2).Infof("Adding security group ingress: %s %v", securityGroupId, changes) request := &ec2.AuthorizeSecurityGroupIngressInput{} - request.GroupID = &securityGroupId - request.IPPermissions = changes + request.GroupId = &securityGroupId + request.IpPermissions = changes _, err = s.ec2.AuthorizeSecurityGroupIngress(request) if err != nil { glog.Warning("error authorizing security group ingress", err) @@ -1467,9 +1374,9 @@ func (s *AWSCloud) ensureSecurityGroupIngress(securityGroupId string, addPermiss } // Makes sure the security group no longer includes the specified permissions -// Returns true iff changes were made +// Returns true if and only if changes were made // If the security group no longer exists, will return (false, nil) -func (s *AWSCloud) removeSecurityGroupIngress(securityGroupId string, removePermissions []*ec2.IPPermission) (bool, error) { +func (s *AWSCloud) removeSecurityGroupIngress(securityGroupId string, removePermissions []*ec2.IpPermission) (bool, error) { group, err := s.findSecurityGroup(securityGroupId) if err != nil { glog.Warning("error retrieving security group", err) @@ -1481,17 +1388,17 @@ func (s *AWSCloud) removeSecurityGroupIngress(securityGroupId string, removePerm return false, nil } - changes := []*ec2.IPPermission{} + changes := []*ec2.IpPermission{} for _, removePermission := range removePermissions { hasUserID := false - for i := range removePermission.UserIDGroupPairs { - if removePermission.UserIDGroupPairs[i].UserID != nil { + for i := range removePermission.UserIdGroupPairs { + if removePermission.UserIdGroupPairs[i].UserId != nil { hasUserID = true } } - var found *ec2.IPPermission - for _, groupPermission := range group.IPPermissions { + var found *ec2.IpPermission + for _, groupPermission := range group.IpPermissions { if isEqualIPPermission(groupPermission, removePermission, hasUserID) { found = groupPermission break @@ -1510,8 +1417,8 @@ func (s *AWSCloud) removeSecurityGroupIngress(securityGroupId string, removePerm glog.V(2).Infof("Removing security group ingress: %s %v", securityGroupId, changes) request := &ec2.RevokeSecurityGroupIngressInput{} - request.GroupID = &securityGroupId - request.IPPermissions = changes + request.GroupId = &securityGroupId + request.IpPermissions = changes _, err = s.ec2.RevokeSecurityGroupIngress(request) if err != nil { glog.Warning("error revoking security group ingress", err) @@ -1545,11 +1452,11 @@ func (s *AWSCloud) ensureSecurityGroup(name string, description string, vpcID st if len(securityGroups) > 1 { glog.Warning("Found multiple security groups with name:", name) } - return orEmpty(securityGroups[0].GroupID), nil + return orEmpty(securityGroups[0].GroupId), nil } createRequest := &ec2.CreateSecurityGroupInput{} - createRequest.VPCID = &vpcID + createRequest.VpcId = &vpcID createRequest.GroupName = &name createRequest.Description = &description @@ -1564,12 +1471,12 @@ func (s *AWSCloud) ensureSecurityGroup(name string, description string, vpcID st } } if !ignore { - glog.Error("error creating security group: ", err) + glog.Error("Error creating security group: ", err) return "", err } time.Sleep(1 * time.Second) } else { - groupID = orEmpty(createResponse.GroupID) + groupID = orEmpty(createResponse.GroupId) break } } @@ -1621,14 +1528,47 @@ func (s *AWSCloud) createTags(request *ec2.CreateTagsInput) (*ec2.CreateTagsOutp } } +func (s *AWSCloud) listSubnetIDsinVPC(vpcId string) ([]string, error) { + + subnetIds := []string{} + + request := &ec2.DescribeSubnetsInput{} + filters := []*ec2.Filter{} + filters = append(filters, newEc2Filter("vpc-id", vpcId)) + // Note, this will only return subnets tagged with the cluster identifier for this Kubernetes cluster. + // In the case where an AZ has public & private subnets per AWS best practices, the deployment should ensure + // only the public subnet (where the ELB will go) is so tagged. + filters = s.addFilters(filters) + request.Filters = filters + + subnets, err := s.ec2.DescribeSubnets(request) + if err != nil { + glog.Error("error describing subnets: ", err) + return nil, err + } + + availabilityZones := sets.NewString() + for _, subnet := range subnets { + az := orEmpty(subnet.AvailabilityZone) + id := orEmpty(subnet.SubnetId) + if availabilityZones.Has(az) { + glog.Warning("Found multiple subnets per AZ '", az, "', ignoring subnet '", id, "'") + continue + } + subnetIds = append(subnetIds, id) + availabilityZones.Insert(az) + } + + return subnetIds, nil +} + // EnsureTCPLoadBalancer implements TCPLoadBalancer.EnsureTCPLoadBalancer // TODO(justinsb) It is weird that these take a region. I suspect it won't work cross-region anwyay. func (s *AWSCloud) EnsureTCPLoadBalancer(name, region string, publicIP net.IP, ports []*api.ServicePort, hosts []string, affinity api.ServiceAffinity) (*api.LoadBalancerStatus, error) { glog.V(2).Infof("EnsureTCPLoadBalancer(%v, %v, %v, %v, %v)", name, region, publicIP, ports, hosts) - elbClient, err := s.getELBClient(region) - if err != nil { - return nil, err + if region != s.region { + return nil, fmt.Errorf("requested load balancer region '%s' does not match cluster region '%s'", region, s.region) } if affinity != api.ServiceAffinityNone { @@ -1645,39 +1585,16 @@ func (s *AWSCloud) EnsureTCPLoadBalancer(name, region string, publicIP net.IP, p return nil, err } - vpc, err := s.findVPC() + vpcId, err := s.findVPCID() if err != nil { - glog.Error("error finding VPC", err) return nil, err } - if vpc == nil { - return nil, fmt.Errorf("Unable to find VPC") - } // Construct list of configured subnets - subnetIDs := []string{} - { - request := &ec2.DescribeSubnetsInput{} - filters := []*ec2.Filter{} - filters = append(filters, newEc2Filter("vpc-id", orEmpty(vpc.VPCID))) - filters = s.addFilters(filters) - request.Filters = filters - - subnets, err := s.ec2.DescribeSubnets(request) - if err != nil { - glog.Error("error describing subnets: ", err) - return nil, err - } - - // zones := []string{} - for _, subnet := range subnets { - subnetIDs = append(subnetIDs, orEmpty(subnet.SubnetID)) - if !strings.HasPrefix(orEmpty(subnet.AvailabilityZone), region) { - glog.Error("found AZ that did not match region", orEmpty(subnet.AvailabilityZone), " vs ", region) - return nil, fmt.Errorf("invalid AZ for region") - } - // zones = append(zones, subnet.AvailabilityZone) - } + subnetIDs, err := s.listSubnetIDsinVPC(vpcId) + if err != nil { + glog.Error("error listing subnets in VPC", err) + return nil, err } // Create a security group for the load balancer @@ -1685,23 +1602,23 @@ func (s *AWSCloud) EnsureTCPLoadBalancer(name, region string, publicIP net.IP, p { sgName := "k8s-elb-" + name sgDescription := "Security group for Kubernetes ELB " + name - securityGroupID, err = s.ensureSecurityGroup(sgName, sgDescription, orEmpty(vpc.VPCID)) + securityGroupID, err = s.ensureSecurityGroup(sgName, sgDescription, vpcId) if err != nil { - glog.Error("error creating load balancer security group: ", err) + glog.Error("Error creating load balancer security group: ", err) return nil, err } - permissions := []*ec2.IPPermission{} + permissions := []*ec2.IpPermission{} for _, port := range ports { portInt64 := int64(port.Port) protocol := strings.ToLower(string(port.Protocol)) sourceIp := "0.0.0.0/0" - permission := &ec2.IPPermission{} + permission := &ec2.IpPermission{} permission.FromPort = &portInt64 permission.ToPort = &portInt64 - permission.IPRanges = []*ec2.IPRange{{CIDRIP: &sourceIp}} - permission.IPProtocol = &protocol + permission.IpRanges = []*ec2.IpRange{{CidrIp: &sourceIp}} + permission.IpProtocol = &protocol permissions = append(permissions, permission) } @@ -1733,12 +1650,12 @@ func (s *AWSCloud) EnsureTCPLoadBalancer(name, region string, publicIP net.IP, p } // Build the load balancer itself - loadBalancer, err := s.ensureLoadBalancer(region, name, listeners, subnetIDs, securityGroupIDs) + loadBalancer, err := s.ensureLoadBalancer(name, listeners, subnetIDs, securityGroupIDs) if err != nil { return nil, err } - err = s.ensureLoadBalancerHealthCheck(region, loadBalancer, listeners) + err = s.ensureLoadBalancerHealthCheck(loadBalancer, listeners) if err != nil { return nil, err } @@ -1749,7 +1666,7 @@ func (s *AWSCloud) EnsureTCPLoadBalancer(name, region string, publicIP net.IP, p return nil, err } - err = s.ensureLoadBalancerInstances(elbClient, orEmpty(loadBalancer.LoadBalancerName), loadBalancer.Instances, instances) + err = s.ensureLoadBalancerInstances(orEmpty(loadBalancer.LoadBalancerName), loadBalancer.Instances, instances) if err != nil { glog.Warning("Error registering instances with the load balancer: %v", err) return nil, err @@ -1765,7 +1682,11 @@ func (s *AWSCloud) EnsureTCPLoadBalancer(name, region string, publicIP net.IP, p // GetTCPLoadBalancer is an implementation of TCPLoadBalancer.GetTCPLoadBalancer func (s *AWSCloud) GetTCPLoadBalancer(name, region string) (*api.LoadBalancerStatus, bool, error) { - lb, err := s.describeLoadBalancer(region, name) + if region != s.region { + return nil, false, fmt.Errorf("requested load balancer region '%s' does not match cluster region '%s'", region, s.region) + } + + lb, err := s.describeLoadBalancer(name) if err != nil { return nil, false, err } @@ -1795,23 +1716,23 @@ func toStatus(lb *elb.LoadBalancerDescription) *api.LoadBalancerStatus { func findSecurityGroupForInstance(instance *ec2.Instance) *string { var securityGroupId *string for _, securityGroup := range instance.SecurityGroups { - if securityGroup == nil || securityGroup.GroupID == nil { + if securityGroup == nil || securityGroup.GroupId == nil { // Not expected, but avoid panic - glog.Warning("Unexpected empty security group for instance: ", orEmpty(instance.InstanceID)) + glog.Warning("Unexpected empty security group for instance: ", orEmpty(instance.InstanceId)) continue } if securityGroupId != nil { // We create instances with one SG - glog.Warningf("Multiple security groups found for instance (%s); will use first group (%s)", orEmpty(instance.InstanceID), *securityGroupId) + glog.Warningf("Multiple security groups found for instance (%s); will use first group (%s)", orEmpty(instance.InstanceId), *securityGroupId) continue } else { - securityGroupId = securityGroup.GroupID + securityGroupId = securityGroup.GroupId } } if securityGroupId == nil { - glog.Warning("No security group found for instance ", orEmpty(instance.InstanceID)) + glog.Warning("No security group found for instance ", orEmpty(instance.InstanceId)) } return securityGroupId @@ -1858,7 +1779,7 @@ func (s *AWSCloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalan for _, instance := range allInstances { securityGroupId := findSecurityGroupForInstance(instance) if isNilOrEmpty(securityGroupId) { - glog.Warning("ignoring instance without security group: ", orEmpty(instance.InstanceID)) + glog.Warning("Ignoring instance without security group: ", orEmpty(instance.InstanceId)) continue } @@ -1867,12 +1788,12 @@ func (s *AWSCloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalan // Compare to actual groups for _, actualGroup := range actualGroups { - if isNilOrEmpty(actualGroup.GroupID) { - glog.Warning("ignoring group without ID: ", actualGroup) + if isNilOrEmpty(actualGroup.GroupId) { + glog.Warning("Ignoring group without ID: ", actualGroup) continue } - actualGroupID := *actualGroup.GroupID + actualGroupID := *actualGroup.GroupId adding, found := instanceSecurityGroupIds[actualGroupID] if found && adding { @@ -1890,16 +1811,16 @@ func (s *AWSCloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalan } else { glog.V(2).Infof("Removing rule for traffic from the load balancer (%s) to instance (%s)", loadBalancerSecurityGroupId, instanceSecurityGroupId) } - sourceGroupId := &ec2.UserIDGroupPair{} - sourceGroupId.GroupID = &loadBalancerSecurityGroupId + sourceGroupId := &ec2.UserIdGroupPair{} + sourceGroupId.GroupId = &loadBalancerSecurityGroupId allProtocols := "-1" - permission := &ec2.IPPermission{} - permission.IPProtocol = &allProtocols - permission.UserIDGroupPairs = []*ec2.UserIDGroupPair{sourceGroupId} + permission := &ec2.IpPermission{} + permission.IpProtocol = &allProtocols + permission.UserIdGroupPairs = []*ec2.UserIdGroupPair{sourceGroupId} - permissions := []*ec2.IPPermission{permission} + permissions := []*ec2.IpPermission{permission} if add { changed, err := s.ensureSecurityGroupIngress(instanceSecurityGroupId, permissions) @@ -1925,12 +1846,11 @@ func (s *AWSCloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalan // EnsureTCPLoadBalancerDeleted implements TCPLoadBalancer.EnsureTCPLoadBalancerDeleted. func (s *AWSCloud) EnsureTCPLoadBalancerDeleted(name, region string) error { - elbClient, err := s.getELBClient(region) - if err != nil { - return err + if region != s.region { + return fmt.Errorf("requested load balancer region '%s' does not match cluster region '%s'", region, s.region) } - lb, err := s.describeLoadBalancer(region, name) + lb, err := s.describeLoadBalancer(name) if err != nil { return err } @@ -1944,7 +1864,7 @@ func (s *AWSCloud) EnsureTCPLoadBalancerDeleted(name, region string) error { // De-authorize the load balancer security group from the instances security group err = s.updateInstanceSecurityGroupsForLoadBalancer(lb, nil) if err != nil { - glog.Error("error deregistering load balancer from instance security groups: ", err) + glog.Error("Error deregistering load balancer from instance security groups: ", err) return err } } @@ -1954,10 +1874,10 @@ func (s *AWSCloud) EnsureTCPLoadBalancerDeleted(name, region string) error { request := &elb.DeleteLoadBalancerInput{} request.LoadBalancerName = lb.LoadBalancerName - _, err = elbClient.DeleteLoadBalancer(request) + _, err = s.elb.DeleteLoadBalancer(request) if err != nil { // TODO: Check if error was because load balancer was concurrently deleted - glog.Error("error deleting load balancer: ", err) + glog.Error("Error deleting load balancer: ", err) return err } } @@ -1982,7 +1902,7 @@ func (s *AWSCloud) EnsureTCPLoadBalancerDeleted(name, region string) error { for { for securityGroupID := range securityGroupIDs { request := &ec2.DeleteSecurityGroupInput{} - request.GroupID = &securityGroupID + request.GroupId = &securityGroupID _, err := s.ec2.DeleteSecurityGroup(request) if err == nil { delete(securityGroupIDs, securityGroupID) @@ -2020,17 +1940,16 @@ func (s *AWSCloud) EnsureTCPLoadBalancerDeleted(name, region string) error { // UpdateTCPLoadBalancer implements TCPLoadBalancer.UpdateTCPLoadBalancer func (s *AWSCloud) UpdateTCPLoadBalancer(name, region string, hosts []string) error { - instances, err := s.getInstancesByNodeNames(hosts) - if err != nil { - return err + if region != s.region { + return fmt.Errorf("requested load balancer region '%s' does not match cluster region '%s'", region, s.region) } - elbClient, err := s.getELBClient(region) + instances, err := s.getInstancesByNodeNames(hosts) if err != nil { return err } - lb, err := s.describeLoadBalancer(region, name) + lb, err := s.describeLoadBalancer(name) if err != nil { return err } @@ -2039,7 +1958,7 @@ func (s *AWSCloud) UpdateTCPLoadBalancer(name, region string, hosts []string) er return fmt.Errorf("Load balancer not found") } - err = s.ensureLoadBalancerInstances(elbClient, orEmpty(lb.LoadBalancerName), lb.Instances, instances) + err = s.ensureLoadBalancerInstances(orEmpty(lb.LoadBalancerName), lb.Instances, instances) if err != nil { return nil } @@ -2052,26 +1971,10 @@ func (s *AWSCloud) UpdateTCPLoadBalancer(name, region string, hosts []string) er return nil } -// TODO: Make efficient -func (a *AWSCloud) getInstancesByIds(ids []string) ([]*ec2.Instance, error) { - instances := []*ec2.Instance{} - for _, id := range ids { - instance, err := a.getInstanceById(id) - if err != nil { - return nil, err - } - if instance == nil { - return nil, fmt.Errorf("unable to find instance " + id) - } - instances = append(instances, instance) - } - return instances, nil -} - // Returns the instance with the specified ID func (a *AWSCloud) getInstanceById(instanceID string) (*ec2.Instance, error) { request := &ec2.DescribeInstancesInput{ - InstanceIDs: []*string{&instanceID}, + InstanceIds: []*string{&instanceID}, } instances, err := a.ec2.DescribeInstances(request) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_instancegroups.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_instancegroups.go index 11d2ac6a74bd..643c8fa7c556 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_instancegroups.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_instancegroups.go @@ -18,6 +18,7 @@ package aws_cloud import ( "fmt" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/autoscaling" "github.com/golang/glog" @@ -31,8 +32,8 @@ var _ InstanceGroups = &AWSCloud{} func (a *AWSCloud) ResizeInstanceGroup(instanceGroupName string, size int) error { request := &autoscaling.UpdateAutoScalingGroupInput{ AutoScalingGroupName: aws.String(instanceGroupName), - MinSize: aws.Long(int64(size)), - MaxSize: aws.Long(int64(size)), + MinSize: aws.Int64(int64(size)), + MaxSize: aws.Int64(int64(size)), } if _, err := a.asg.UpdateAutoScalingGroup(request); err != nil { return fmt.Errorf("error resizing AWS autoscaling group: %v", err) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_loadbalancer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_loadbalancer.go index c3469bcddb2a..58d867ba5203 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_loadbalancer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_loadbalancer.go @@ -27,13 +27,8 @@ import ( "k8s.io/kubernetes/pkg/util/sets" ) -func (s *AWSCloud) ensureLoadBalancer(region, name string, listeners []*elb.Listener, subnetIDs []string, securityGroupIDs []string) (*elb.LoadBalancerDescription, error) { - elbClient, err := s.getELBClient(region) - if err != nil { - return nil, err - } - - loadBalancer, err := s.describeLoadBalancer(region, name) +func (s *AWSCloud) ensureLoadBalancer(name string, listeners []*elb.Listener, subnetIDs []string, securityGroupIDs []string) (*elb.LoadBalancerDescription, error) { + loadBalancer, err := s.describeLoadBalancer(name) if err != nil { return nil, err } @@ -53,7 +48,7 @@ func (s *AWSCloud) ensureLoadBalancer(region, name string, listeners []*elb.List createRequest.SecurityGroups = stringPointerArray(securityGroupIDs) glog.Info("Creating load balancer with name: ", name) - _, err := elbClient.CreateLoadBalancer(createRequest) + _, err := s.elb.CreateLoadBalancer(createRequest) if err != nil { return nil, err } @@ -67,24 +62,24 @@ func (s *AWSCloud) ensureLoadBalancer(region, name string, listeners []*elb.List additions := expected.Difference(actual) removals := actual.Difference(expected) - if len(removals) != 0 { + if removals.Len() != 0 { request := &elb.DetachLoadBalancerFromSubnetsInput{} request.LoadBalancerName = aws.String(name) request.Subnets = stringSetToPointers(removals) glog.V(2).Info("Detaching load balancer from removed subnets") - _, err := elbClient.DetachLoadBalancerFromSubnets(request) + _, err := s.elb.DetachLoadBalancerFromSubnets(request) if err != nil { return nil, fmt.Errorf("error detaching AWS loadbalancer from subnets: %v", err) } dirty = true } - if len(additions) != 0 { + if additions.Len() != 0 { request := &elb.AttachLoadBalancerToSubnetsInput{} request.LoadBalancerName = aws.String(name) request.Subnets = stringSetToPointers(additions) glog.V(2).Info("Attaching load balancer to added subnets") - _, err := elbClient.AttachLoadBalancerToSubnets(request) + _, err := s.elb.AttachLoadBalancerToSubnets(request) if err != nil { return nil, fmt.Errorf("error attaching AWS loadbalancer to subnets: %v", err) } @@ -103,7 +98,7 @@ func (s *AWSCloud) ensureLoadBalancer(region, name string, listeners []*elb.List request.LoadBalancerName = aws.String(name) request.SecurityGroups = stringPointerArray(securityGroupIDs) glog.V(2).Info("Applying updated security groups to load balancer") - _, err := elbClient.ApplySecurityGroupsToLoadBalancer(request) + _, err := s.elb.ApplySecurityGroupsToLoadBalancer(request) if err != nil { return nil, fmt.Errorf("error applying AWS loadbalancer security groups: %v", err) } @@ -138,7 +133,7 @@ func (s *AWSCloud) ensureLoadBalancer(region, name string, listeners []*elb.List if orZero(actual.LoadBalancerPort) != orZero(expected.LoadBalancerPort) { continue } - if orEmpty(actual.SSLCertificateID) != orEmpty(expected.SSLCertificateID) { + if orEmpty(actual.SSLCertificateId) != orEmpty(expected.SSLCertificateId) { continue } found = i @@ -163,7 +158,7 @@ func (s *AWSCloud) ensureLoadBalancer(region, name string, listeners []*elb.List request.LoadBalancerName = aws.String(name) request.LoadBalancerPorts = removals glog.V(2).Info("Deleting removed load balancer listeners") - _, err := elbClient.DeleteLoadBalancerListeners(request) + _, err := s.elb.DeleteLoadBalancerListeners(request) if err != nil { return nil, fmt.Errorf("error deleting AWS loadbalancer listeners: %v", err) } @@ -175,7 +170,7 @@ func (s *AWSCloud) ensureLoadBalancer(region, name string, listeners []*elb.List request.LoadBalancerName = aws.String(name) request.Listeners = additions glog.V(2).Info("Creating added load balancer listeners") - _, err := elbClient.CreateLoadBalancerListeners(request) + _, err := s.elb.CreateLoadBalancerListeners(request) if err != nil { return nil, fmt.Errorf("error creating AWS loadbalancer listeners: %v", err) } @@ -185,7 +180,7 @@ func (s *AWSCloud) ensureLoadBalancer(region, name string, listeners []*elb.List } if dirty { - loadBalancer, err = s.describeLoadBalancer(region, name) + loadBalancer, err = s.describeLoadBalancer(name) if err != nil { glog.Warning("Unable to retrieve load balancer after creation/update") return nil, err @@ -196,12 +191,7 @@ func (s *AWSCloud) ensureLoadBalancer(region, name string, listeners []*elb.List } // Makes sure that the health check for an ELB matches the configured listeners -func (s *AWSCloud) ensureLoadBalancerHealthCheck(region string, loadBalancer *elb.LoadBalancerDescription, listeners []*elb.Listener) error { - elbClient, err := s.getELBClient(region) - if err != nil { - return err - } - +func (s *AWSCloud) ensureLoadBalancerHealthCheck(loadBalancer *elb.LoadBalancerDescription, listeners []*elb.Listener) error { actual := loadBalancer.HealthCheck // Default AWS settings @@ -245,7 +235,7 @@ func (s *AWSCloud) ensureLoadBalancerHealthCheck(region string, loadBalancer *el request.HealthCheck = healthCheck request.LoadBalancerName = loadBalancer.LoadBalancerName - _, err = elbClient.ConfigureHealthCheck(request) + _, err := s.elb.ConfigureHealthCheck(request) if err != nil { return fmt.Errorf("error configuring load-balancer health-check: %v", err) } @@ -254,31 +244,31 @@ func (s *AWSCloud) ensureLoadBalancerHealthCheck(region string, loadBalancer *el } // Makes sure that exactly the specified hosts are registered as instances with the load balancer -func (s *AWSCloud) ensureLoadBalancerInstances(elbClient ELB, loadBalancerName string, lbInstances []*elb.Instance, instances []*ec2.Instance) error { +func (s *AWSCloud) ensureLoadBalancerInstances(loadBalancerName string, lbInstances []*elb.Instance, instances []*ec2.Instance) error { expected := sets.NewString() for _, instance := range instances { - expected.Insert(orEmpty(instance.InstanceID)) + expected.Insert(orEmpty(instance.InstanceId)) } actual := sets.NewString() for _, lbInstance := range lbInstances { - actual.Insert(orEmpty(lbInstance.InstanceID)) + actual.Insert(orEmpty(lbInstance.InstanceId)) } additions := expected.Difference(actual) removals := actual.Difference(expected) addInstances := []*elb.Instance{} - for instanceId := range additions { + for _, instanceId := range additions.List() { addInstance := &elb.Instance{} - addInstance.InstanceID = aws.String(instanceId) + addInstance.InstanceId = aws.String(instanceId) addInstances = append(addInstances, addInstance) } removeInstances := []*elb.Instance{} - for instanceId := range removals { + for _, instanceId := range removals.List() { removeInstance := &elb.Instance{} - removeInstance.InstanceID = aws.String(instanceId) + removeInstance.InstanceId = aws.String(instanceId) removeInstances = append(removeInstances, removeInstance) } @@ -286,7 +276,7 @@ func (s *AWSCloud) ensureLoadBalancerInstances(elbClient ELB, loadBalancerName s registerRequest := &elb.RegisterInstancesWithLoadBalancerInput{} registerRequest.Instances = addInstances registerRequest.LoadBalancerName = aws.String(loadBalancerName) - _, err := elbClient.RegisterInstancesWithLoadBalancer(registerRequest) + _, err := s.elb.RegisterInstancesWithLoadBalancer(registerRequest) if err != nil { return err } @@ -297,7 +287,7 @@ func (s *AWSCloud) ensureLoadBalancerInstances(elbClient ELB, loadBalancerName s deregisterRequest := &elb.DeregisterInstancesFromLoadBalancerInput{} deregisterRequest.Instances = removeInstances deregisterRequest.LoadBalancerName = aws.String(loadBalancerName) - _, err := elbClient.DeregisterInstancesFromLoadBalancer(deregisterRequest) + _, err := s.elb.DeregisterInstancesFromLoadBalancer(deregisterRequest) if err != nil { return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_routes.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_routes.go index b81763fc8f44..cfa5db37006f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_routes.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_routes.go @@ -56,8 +56,8 @@ func (s *AWSCloud) ListRoutes(clusterName string) ([]*cloudprovider.Route, error var routes []*cloudprovider.Route for _, r := range table.Routes { - instanceID := orEmpty(r.InstanceID) - destinationCIDR := orEmpty(r.DestinationCIDRBlock) + instanceID := orEmpty(r.InstanceId) + destinationCIDR := orEmpty(r.DestinationCidrBlock) if instanceID == "" || destinationCIDR == "" { continue @@ -67,7 +67,7 @@ func (s *AWSCloud) ListRoutes(clusterName string) ([]*cloudprovider.Route, error if err != nil { return nil, err } - instanceName := orEmpty(instance.PrivateDNSName) + instanceName := orEmpty(instance.PrivateDnsName) routeName := clusterName + "-" + destinationCIDR routes = append(routes, &cloudprovider.Route{Name: routeName, TargetInstance: instanceName, DestinationCIDR: destinationCIDR}) } @@ -78,8 +78,8 @@ func (s *AWSCloud) ListRoutes(clusterName string) ([]*cloudprovider.Route, error // Sets the instance attribute "source-dest-check" to the specified value func (s *AWSCloud) configureInstanceSourceDestCheck(instanceID string, sourceDestCheck bool) error { request := &ec2.ModifyInstanceAttributeInput{} - request.InstanceID = aws.String(instanceID) - request.SourceDestCheck = &ec2.AttributeBooleanValue{Value: aws.Boolean(sourceDestCheck)} + request.InstanceId = aws.String(instanceID) + request.SourceDestCheck = &ec2.AttributeBooleanValue{Value: aws.Bool(sourceDestCheck)} _, err := s.ec2.ModifyInstanceAttribute(request) if err != nil { @@ -98,7 +98,7 @@ func (s *AWSCloud) CreateRoute(clusterName string, nameHint string, route *cloud // In addition to configuring the route itself, we also need to configure the instance to accept that traffic // On AWS, this requires turning source-dest checks off - err = s.configureInstanceSourceDestCheck(orEmpty(instance.InstanceID), false) + err = s.configureInstanceSourceDestCheck(orEmpty(instance.InstanceId), false) if err != nil { return err } @@ -110,9 +110,9 @@ func (s *AWSCloud) CreateRoute(clusterName string, nameHint string, route *cloud request := &ec2.CreateRouteInput{} // TODO: use ClientToken for idempotency? - request.DestinationCIDRBlock = aws.String(route.DestinationCIDR) - request.InstanceID = instance.InstanceID - request.RouteTableID = table.RouteTableID + request.DestinationCidrBlock = aws.String(route.DestinationCIDR) + request.InstanceId = instance.InstanceId + request.RouteTableId = table.RouteTableId _, err = s.ec2.CreateRoute(request) if err != nil { @@ -131,8 +131,8 @@ func (s *AWSCloud) DeleteRoute(clusterName string, route *cloudprovider.Route) e } request := &ec2.DeleteRouteInput{} - request.DestinationCIDRBlock = aws.String(route.DestinationCIDR) - request.RouteTableID = table.RouteTableID + request.DestinationCidrBlock = aws.String(route.DestinationCIDR) + request.RouteTableId = table.RouteTableId _, err = s.ec2.DeleteRoute(request) if err != nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_test.go index 07171a118276..e7245caf8def 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws_test.go @@ -17,6 +17,7 @@ limitations under the License. package aws_cloud import ( + "fmt" "io" "reflect" "strings" @@ -82,9 +83,9 @@ func TestReadAWSCloudConfig(t *testing.T) { for _, test := range tests { t.Logf("Running test case %s", test.name) - var metadata AWSMetadata + var metadata EC2Metadata if test.aws != nil { - metadata = test.aws.Metadata() + metadata, _ = test.aws.Metadata() } cfg, err := readAWSCloudConfig(test.reader, metadata) if test.expectError { @@ -131,8 +132,8 @@ func NewFakeAWSServices() *FakeAWSServices { s.instanceId = "i-self" s.privateDnsName = "ip-172-20-0-100.ec2.internal" var selfInstance ec2.Instance - selfInstance.InstanceID = &s.instanceId - selfInstance.PrivateDNSName = &s.privateDnsName + selfInstance.InstanceId = &s.instanceId + selfInstance.PrivateDnsName = &s.privateDnsName s.instances = []*ec2.Instance{&selfInstance} var tag ec2.Tag @@ -165,8 +166,8 @@ func (s *FakeAWSServices) Autoscaling(region string) (ASG, error) { return s.asg, nil } -func (s *FakeAWSServices) Metadata() AWSMetadata { - return s.metadata +func (s *FakeAWSServices) Metadata() (EC2Metadata, error) { + return s.metadata, nil } func TestFilterTags(t *testing.T) { @@ -246,7 +247,9 @@ func TestNewAWSCloud(t *testing.T) { } type FakeEC2 struct { - aws *FakeAWSServices + aws *FakeAWSServices + Subnets []*ec2.Subnet + DescribeSubnetsInput *ec2.DescribeSubnetsInput } func contains(haystack []*string, needle string) bool { @@ -262,10 +265,10 @@ func contains(haystack []*string, needle string) bool { func instanceMatchesFilter(instance *ec2.Instance, filter *ec2.Filter) bool { name := *filter.Name if name == "private-dns-name" { - if instance.PrivateDNSName == nil { + if instance.PrivateDnsName == nil { return false } - return contains(filter.Values, *instance.PrivateDNSName) + return contains(filter.Values, *instance.PrivateDnsName) } panic("Unknown filter name: " + name) } @@ -273,15 +276,15 @@ func instanceMatchesFilter(instance *ec2.Instance, filter *ec2.Filter) bool { func (self *FakeEC2) DescribeInstances(request *ec2.DescribeInstancesInput) ([]*ec2.Instance, error) { matches := []*ec2.Instance{} for _, instance := range self.aws.instances { - if request.InstanceIDs != nil { - if instance.InstanceID == nil { + if request.InstanceIds != nil { + if instance.InstanceId == nil { glog.Warning("Instance with no instance id: ", instance) continue } found := false - for _, instanceId := range request.InstanceIDs { - if *instanceId == *instance.InstanceID { + for _, instanceId := range request.InstanceIds { + if *instanceId == *instance.InstanceId { found = true break } @@ -312,31 +315,31 @@ type FakeMetadata struct { aws *FakeAWSServices } -func (self *FakeMetadata) GetMetaData(key string) ([]byte, error) { +func (self *FakeMetadata) GetMetadata(key string) (string, error) { networkInterfacesPrefix := "network/interfaces/macs/" if key == "placement/availability-zone" { - return []byte(self.aws.availabilityZone), nil + return self.aws.availabilityZone, nil } else if key == "instance-id" { - return []byte(self.aws.instanceId), nil + return self.aws.instanceId, nil } else if key == "local-hostname" { - return []byte(self.aws.privateDnsName), nil + return self.aws.privateDnsName, nil } else if strings.HasPrefix(key, networkInterfacesPrefix) { if key == networkInterfacesPrefix { - return []byte(strings.Join(self.aws.networkInterfacesMacs, "/\n") + "/\n"), nil + return strings.Join(self.aws.networkInterfacesMacs, "/\n") + "/\n", nil } else { keySplit := strings.Split(key, "/") macParam := keySplit[3] if len(keySplit) == 5 && keySplit[4] == "vpc-id" { for i, macElem := range self.aws.networkInterfacesMacs { if macParam == macElem { - return []byte(self.aws.networkInterfacesVpcIDs[i]), nil + return self.aws.networkInterfacesVpcIDs[i], nil } } } - return nil, nil + return "", nil } } else { - return nil, nil + return "", nil } } @@ -380,12 +383,9 @@ func (ec2 *FakeEC2) RevokeSecurityGroupIngress(*ec2.RevokeSecurityGroupIngressIn panic("Not implemented") } -func (ec2 *FakeEC2) DescribeVPCs(*ec2.DescribeVPCsInput) ([]*ec2.VPC, error) { - panic("Not implemented") -} - -func (ec2 *FakeEC2) DescribeSubnets(*ec2.DescribeSubnetsInput) ([]*ec2.Subnet, error) { - panic("Not implemented") +func (ec2 *FakeEC2) DescribeSubnets(request *ec2.DescribeSubnetsInput) ([]*ec2.Subnet, error) { + ec2.DescribeSubnetsInput = request + return ec2.Subnets, nil } func (ec2 *FakeEC2) CreateTags(*ec2.CreateTagsInput) (*ec2.CreateTagsOutput, error) { @@ -470,7 +470,6 @@ func (a *FakeASG) DescribeAutoScalingGroups(*autoscaling.DescribeAutoScalingGrou func mockInstancesResp(instances []*ec2.Instance) *AWSCloud { awsServices := NewFakeAWSServices().withInstances(instances) return &AWSCloud{ - awsServices: awsServices, ec2: awsServices.ec2, availabilityZone: awsServices.availabilityZone, } @@ -479,7 +478,6 @@ func mockInstancesResp(instances []*ec2.Instance) *AWSCloud { func mockAvailabilityZone(region string, availabilityZone string) *AWSCloud { awsServices := NewFakeAWSServices().withAz(availabilityZone) return &AWSCloud{ - awsServices: awsServices, ec2: awsServices.ec2, availabilityZone: awsServices.availabilityZone, region: region, @@ -499,8 +497,8 @@ func TestList(t *testing.T) { Value: aws.String("foo"), } instance0.Tags = []*ec2.Tag{&tag0} - instance0.InstanceID = aws.String("instance0") - instance0.PrivateDNSName = aws.String("instance0.ec2.internal") + instance0.InstanceId = aws.String("instance0") + instance0.PrivateDnsName = aws.String("instance0.ec2.internal") state0 := ec2.InstanceState{ Name: aws.String("running"), } @@ -512,8 +510,8 @@ func TestList(t *testing.T) { Value: aws.String("bar"), } instance1.Tags = []*ec2.Tag{&tag1} - instance1.InstanceID = aws.String("instance1") - instance1.PrivateDNSName = aws.String("instance1.ec2.internal") + instance1.InstanceId = aws.String("instance1") + instance1.PrivateDnsName = aws.String("instance1.ec2.internal") state1 := ec2.InstanceState{ Name: aws.String("running"), } @@ -525,8 +523,8 @@ func TestList(t *testing.T) { Value: aws.String("baz"), } instance2.Tags = []*ec2.Tag{&tag2} - instance2.InstanceID = aws.String("instance2") - instance2.PrivateDNSName = aws.String("instance2.ec2.internal") + instance2.InstanceId = aws.String("instance2") + instance2.PrivateDnsName = aws.String("instance2.ec2.internal") state2 := ec2.InstanceState{ Name: aws.String("running"), } @@ -538,8 +536,8 @@ func TestList(t *testing.T) { Value: aws.String("quux"), } instance3.Tags = []*ec2.Tag{&tag3} - instance3.InstanceID = aws.String("instance3") - instance3.PrivateDNSName = aws.String("instance3.ec2.internal") + instance3.InstanceId = aws.String("instance3") + instance3.PrivateDnsName = aws.String("instance3.ec2.internal") state3 := ec2.InstanceState{ Name: aws.String("running"), } @@ -584,10 +582,10 @@ func TestNodeAddresses(t *testing.T) { var instance1 ec2.Instance //0 - instance0.InstanceID = aws.String("instance-same") - instance0.PrivateDNSName = aws.String("instance-same.ec2.internal") - instance0.PrivateIPAddress = aws.String("192.168.0.1") - instance0.PublicIPAddress = aws.String("1.2.3.4") + instance0.InstanceId = aws.String("instance-same") + instance0.PrivateDnsName = aws.String("instance-same.ec2.internal") + instance0.PrivateIpAddress = aws.String("192.168.0.1") + instance0.PublicIpAddress = aws.String("1.2.3.4") instance0.InstanceType = aws.String("c3.large") state0 := ec2.InstanceState{ Name: aws.String("running"), @@ -595,9 +593,9 @@ func TestNodeAddresses(t *testing.T) { instance0.State = &state0 //1 - instance1.InstanceID = aws.String("instance-same") - instance1.PrivateDNSName = aws.String("instance-same.ec2.internal") - instance1.PrivateIPAddress = aws.String("192.168.0.2") + instance1.InstanceId = aws.String("instance-same") + instance1.PrivateDnsName = aws.String("instance-same.ec2.internal") + instance1.PrivateIpAddress = aws.String("192.168.0.2") instance1.InstanceType = aws.String("c3.large") state1 := ec2.InstanceState{ Name: aws.String("running"), @@ -664,3 +662,121 @@ func TestFindVPCID(t *testing.T) { t.Errorf("Unexpected vpcID: %s", vpcID) } } + +func TestLoadBalancerMatchesClusterRegion(t *testing.T) { + awsServices := NewFakeAWSServices() + c, err := newAWSCloud(strings.NewReader("[global]"), awsServices) + if err != nil { + t.Errorf("Error building aws cloud: %v", err) + return + } + + badELBRegion := "bad-elb-region" + errorMessage := fmt.Sprintf("requested load balancer region '%s' does not match cluster region '%s'", badELBRegion, c.region) + + _, _, err = c.GetTCPLoadBalancer("elb-name", badELBRegion) + if err == nil || err.Error() != errorMessage { + t.Errorf("Expected GetTCPLoadBalancer region mismatch error.") + } + + _, err = c.EnsureTCPLoadBalancer("elb-name", badELBRegion, nil, nil, nil, api.ServiceAffinityNone) + if err == nil || err.Error() != errorMessage { + t.Errorf("Expected EnsureTCPLoadBalancer region mismatch error.") + } + + err = c.EnsureTCPLoadBalancerDeleted("elb-name", badELBRegion) + if err == nil || err.Error() != errorMessage { + t.Errorf("Expected EnsureTCPLoadBalancerDeleted region mismatch error.") + } + + err = c.UpdateTCPLoadBalancer("elb-name", badELBRegion, nil) + if err == nil || err.Error() != errorMessage { + t.Errorf("Expected UpdateTCPLoadBalancer region mismatch error.") + } +} + +func constructSubnets(subnetsIn map[int]map[string]string) (subnetsOut []*ec2.Subnet) { + for i := range subnetsIn { + subnetsOut = append( + subnetsOut, + constructSubnet( + subnetsIn[i]["id"], + subnetsIn[i]["az"], + ), + ) + } + return +} + +func constructSubnet(id string, az string) *ec2.Subnet { + return &ec2.Subnet{ + SubnetId: &id, + AvailabilityZone: &az, + } +} + +func TestSubnetIDsinVPC(t *testing.T) { + awsServices := NewFakeAWSServices() + c, err := newAWSCloud(strings.NewReader("[global]"), awsServices) + if err != nil { + t.Errorf("Error building aws cloud: %v", err) + return + } + + vpcID := "vpc-deadbeef" + + // test with 3 subnets from 3 different AZs + subnets := make(map[int]map[string]string) + subnets[0] = make(map[string]string) + subnets[0]["id"] = "subnet-a0000001" + subnets[0]["az"] = "af-south-1a" + subnets[1] = make(map[string]string) + subnets[1]["id"] = "subnet-b0000001" + subnets[1]["az"] = "af-south-1b" + subnets[2] = make(map[string]string) + subnets[2]["id"] = "subnet-c0000001" + subnets[2]["az"] = "af-south-1c" + awsServices.ec2.Subnets = constructSubnets(subnets) + + result, err := c.listSubnetIDsinVPC(vpcID) + if err != nil { + t.Errorf("Error listing subnets: %v", err) + return + } + + if len(result) != 3 { + t.Errorf("Expected 3 subnets but got %d", len(result)) + return + } + + result_set := make(map[string]bool) + for _, v := range result { + result_set[v] = true + } + + for i := range subnets { + if !result_set[subnets[i]["id"]] { + t.Errorf("Expected subnet%d '%s' in result: %v", i, subnets[i]["id"], result) + return + } + } + + // test with 4 subnets from 3 different AZs + // add duplicate az subnet + subnets[3] = make(map[string]string) + subnets[3]["id"] = "subnet-c0000002" + subnets[3]["az"] = "af-south-1c" + awsServices.ec2.Subnets = constructSubnets(subnets) + + result, err = c.listSubnetIDsinVPC(vpcID) + if err != nil { + t.Errorf("Error listing subnets: %v", err) + return + } + + if len(result) != 3 { + t.Errorf("Expected 3 subnets but got %d", len(result)) + return + } + +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce.go index c6987de80307..884846f3dce6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce.go @@ -22,12 +22,14 @@ import ( "net" "net/http" "path" + "sort" "strconv" "strings" "time" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/cloudprovider" + "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/wait" @@ -43,9 +45,16 @@ import ( const ( ProviderName = "gce" -) -const k8sNodeRouteTag = "k8s-node-route" + k8sNodeRouteTag = "k8s-node-route" + + // AffinityTypeNone - no session affinity. + gceAffinityTypeNone = "None" + // AffinityTypeClientIP - affinity based on Client IP. + gceAffinityTypeClientIP = "CLIENT_IP" + // AffinityTypeClientIPProto - affinity based on Client IP and port. + gceAffinityTypeClientIPProto = "CLIENT_IP_PROTO" +) // GCECloud is an implementation of Interface, TCPLoadBalancer and Instances for Google Compute Engine. type GCECloud struct { @@ -231,38 +240,6 @@ func hostURLToComparablePath(hostURL string) string { return hostURL[idx:] } -// Session Affinity Type string -type GCEAffinityType string - -const ( - // AffinityTypeNone - no session affinity. - GCEAffinityTypeNone GCEAffinityType = "None" - // AffinityTypeClientIP is the Client IP based. - GCEAffinityTypeClientIP GCEAffinityType = "CLIENT_IP" - // AffinityTypeClientIP is the Client IP based. - GCEAffinityTypeClientIPProto GCEAffinityType = "CLIENT_IP_PROTO" -) - -func (gce *GCECloud) makeTargetPool(name, region string, hosts []string, affinityType GCEAffinityType) error { - var instances []string - for _, host := range hosts { - instances = append(instances, makeHostURL(gce.projectID, gce.zone, host)) - } - pool := &compute.TargetPool{ - Name: name, - Instances: instances, - SessionAffinity: string(affinityType), - } - op, err := gce.service.TargetPools.Insert(gce.projectID, region, pool).Do() - if err != nil { - return err - } - if err = gce.waitForRegionOp(op, region); err != nil { - return err - } - return nil -} - func (gce *GCECloud) targetPoolURL(name, region string) string { return fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/regions/%s/targetPools/%s", gce.projectID, region, name) } @@ -332,56 +309,157 @@ func isHTTPErrorCode(err error, code int) bool { return ok && apiErr.Code == code } -// translate from what K8s supports to what the cloud provider supports for session affinity. -func translateAffinityType(affinityType api.ServiceAffinity) GCEAffinityType { - switch affinityType { - case api.ServiceAffinityClientIP: - return GCEAffinityTypeClientIP - case api.ServiceAffinityNone: - return GCEAffinityTypeNone - default: - glog.Errorf("unexpected affinity type: %v", affinityType) - return GCEAffinityTypeNone - } -} - -func makeFirewallName(name string) string { - return fmt.Sprintf("k8s-fw-%s", name) -} - // EnsureTCPLoadBalancer is an implementation of TCPLoadBalancer.EnsureTCPLoadBalancer. -// TODO(a-robinson): Don't just ignore specified IP addresses. Check if they're -// owned by the project and available to be used, and use them if they are. -func (gce *GCECloud) EnsureTCPLoadBalancer(name, region string, loadBalancerIP net.IP, ports []*api.ServicePort, hosts []string, affinityType api.ServiceAffinity) (*api.LoadBalancerStatus, error) { +// Our load balancers in GCE consist of four separate GCE resources - a static +// IP address, a firewall rule, a target pool, and a forwarding rule. This +// function has to manage all of them. +// Due to an interesting series of design decisions, this handles both creating +// new load balancers and updating existing load balancers, recognizing when +// each is needed. +func (gce *GCECloud) EnsureTCPLoadBalancer(name, region string, requestedIP net.IP, ports []*api.ServicePort, hosts []string, affinityType api.ServiceAffinity) (*api.LoadBalancerStatus, error) { if len(hosts) == 0 { return nil, fmt.Errorf("Cannot EnsureTCPLoadBalancer() with no hosts") } - glog.V(2).Infof("Checking if load balancer already exists: %s", name) - _, exists, err := gce.GetTCPLoadBalancer(name, region) + // Check if the forwarding rule exists, and if so, what its IP is. + fwdRuleExists, fwdRuleNeedsUpdate, fwdRuleIP, err := gce.forwardingRuleNeedsUpdate(name, region, requestedIP, ports) if err != nil { - return nil, fmt.Errorf("error checking if GCE load balancer already exists: %v", err) + return nil, err } - // TODO: Implement a more efficient update strategy for common changes than delete & create - // In particular, if we implement hosts update, we can get rid of UpdateHosts - if exists { - err := gce.EnsureTCPLoadBalancerDeleted(name, region) + // Make sure we know which IP address will be used and have properly reserved + // it as static before moving forward with the rest of our operations. + // + // We use static IP addresses when updating a load balancer to ensure that we + // can replace the load balancer's other components without changing the + // address its service is reachable on. We do it this way rather than always + // keeping the static IP around even though this is more complicated because + // it makes it less likely that we'll run into quota issues. Only 7 static + // IP addresses are allowed per region by default. + // + // We could let an IP be allocated for us when the forwarding rule is created, + // but we need the IP to set up the firewall rule, and we want to keep the + // forwarding rule creation as the last thing that needs to be done in this + // function in order to maintain the invariant that "if the forwarding rule + // exists, the LB has been fully created". + ipAddress := "" + if requestedIP != nil { + // If a specific IP address has been requested, we have to respect the + // user's request and use that IP. If the forwarding rule was already using + // a different IP, it will be harmlessly abandoned because it was only an + // ephemeral IP (or it was a different static IP owned by the user, in which + // case we shouldn't delete it anyway). + if err := gce.projectOwnsStaticIP(name, region, requestedIP.String()); err != nil { + return nil, err + } + ipAddress = requestedIP.String() + } else { + // This will either allocate a new static IP if the forwarding rule didn't + // already have an IP, or it will promote the forwarding rule's IP from + // ephemeral to static. + ipAddress, err = gce.createOrPromoteStaticIP(name, region, fwdRuleIP) if err != nil { - return nil, fmt.Errorf("error deleting existing GCE load balancer: %v", err) + return nil, err } } - err = gce.makeTargetPool(name, region, hosts, translateAffinityType(affinityType)) + // Deal with the firewall next. The reason we do this here rather than last + // is because the forwarding rule is used as the indicator that the load + // balancer is fully created - it's what getTCPLoadBalancer checks for. + firewallExists, firewallNeedsUpdate, err := gce.firewallNeedsUpdate(name, region, ipAddress, ports) if err != nil { - if !isHTTPErrorCode(err, http.StatusConflict) { - return nil, err + return nil, err + } + + if firewallNeedsUpdate { + // Unlike forwarding rules and target pools, firewalls can be updated + // without needing to be deleted and recreated. + if firewallExists { + if err := gce.updateFirewall(name, region, ipAddress, ports, hosts); err != nil { + return nil, err + } + } else { + if err := gce.createFirewall(name, region, ipAddress, ports, hosts); err != nil { + return nil, err + } + } + } + + tpExists, tpNeedsUpdate, err := gce.targetPoolNeedsUpdate(name, region, affinityType) + if err != nil { + return nil, err + } + + // Now we get to some slightly more interesting logic. + // First, neither target pools nor forwarding rules can be updated in place - + // they have to be deleted and recreated. + // Second, forwarding rules are layered on top of target pools in that you + // can't delete a target pool that's currently in use by a forwarding rule. + // Thus, we have to tear down the forwarding rule if either it or the target + // pool needs to be updated. + if fwdRuleExists && (fwdRuleNeedsUpdate || tpNeedsUpdate) { + if err := gce.deleteForwardingRule(name, region); err != nil { + return nil, fmt.Errorf("failed to delete existing forwarding rule %s for load balancer update: %v", name, err) + } + } + if tpExists && tpNeedsUpdate { + if err := gce.deleteTargetPool(name, region); err != nil { + return nil, fmt.Errorf("failed to delete existing target pool %s for load balancer update: %v", name, err) + } + } + + // Once we've deleted the resources (if necessary), build them back up (or for + // the first time if they're new). + if tpNeedsUpdate { + if err := gce.createTargetPool(name, region, hosts, affinityType); err != nil { + return nil, fmt.Errorf("failed to create target pool %s: %v", name, err) + } + } + if tpNeedsUpdate || fwdRuleNeedsUpdate { + if err := gce.createForwardingRule(name, region, ipAddress, ports); err != nil { + return nil, fmt.Errorf("failed to create forwarding rule %s: %v", name, err) + } + } + + // Now that we're done operating on everything, demote the static IP back to + // ephemeral to avoid taking up the user's static IP quota. + if err := gce.deleteStaticIP(name, region); err != nil { + return nil, fmt.Errorf("failed to release static IP %s after finishing update of load balancer resources: %v", err) + } + + status := &api.LoadBalancerStatus{} + status.Ingress = []api.LoadBalancerIngress{{IP: ipAddress}} + return status, nil +} + +// Passing nil for requested IP is perfectly fine - it just means that no specific +// IP is being requested. +// Returns whether the forwarding rule exists, whether it needs to be updated, +// what its IP address is (if it exists), and any error we encountered. +func (gce *GCECloud) forwardingRuleNeedsUpdate(name, region string, requestedIP net.IP, ports []*api.ServicePort) (exists bool, needsUpdate bool, ipAddress string, err error) { + fwd, err := gce.service.ForwardingRules.Get(gce.projectID, region, name).Do() + if err != nil { + if isHTTPErrorCode(err, http.StatusNotFound) { + return false, true, "", nil } - glog.Infof("Creating forwarding rule pointing at target pool that already exists: %v", err) + return false, false, "", fmt.Errorf("error getting load balancer's forwarding rule: %v", err) + } + if requestedIP != nil && requestedIP.String() != fwd.IPAddress { + return true, true, fwd.IPAddress, nil + } + portRange, err := loadBalancerPortRange(ports) + if err != nil { + return false, false, "", err } + if portRange != fwd.PortRange { + return true, true, fwd.IPAddress, nil + } + return true, false, fwd.IPAddress, nil +} +func loadBalancerPortRange(ports []*api.ServicePort) (string, error) { if len(ports) == 0 { - return nil, fmt.Errorf("no ports specified for GCE load balancer") + return "", fmt.Errorf("no ports specified for GCE load balancer") } minPort := 65536 maxPort := 0 @@ -393,44 +471,185 @@ func (gce *GCECloud) EnsureTCPLoadBalancer(name, region string, loadBalancerIP n maxPort = ports[i].Port } } + return fmt.Sprintf("%d-%d", minPort, maxPort), nil +} + +// Doesn't check whether the hosts have changed, since host updating is handled +// separately. +func (gce *GCECloud) targetPoolNeedsUpdate(name, region string, affinityType api.ServiceAffinity) (exists bool, needsUpdate bool, err error) { + tp, err := gce.service.TargetPools.Get(gce.projectID, region, name).Do() + if err != nil { + if isHTTPErrorCode(err, http.StatusNotFound) { + return false, true, nil + } + return false, false, fmt.Errorf("error getting load balancer's target pool: %v", err) + } + if translateAffinityType(affinityType) != tp.SessionAffinity { + return true, true, nil + } + return true, false, nil +} + +// translate from what K8s supports to what the cloud provider supports for session affinity. +func translateAffinityType(affinityType api.ServiceAffinity) string { + switch affinityType { + case api.ServiceAffinityClientIP: + return gceAffinityTypeClientIP + case api.ServiceAffinityNone: + return gceAffinityTypeNone + default: + glog.Errorf("Unexpected affinity type: %v", affinityType) + return gceAffinityTypeNone + } +} + +func (gce *GCECloud) firewallNeedsUpdate(name, region, ipAddress string, ports []*api.ServicePort) (exists bool, needsUpdate bool, err error) { + fw, err := gce.service.Firewalls.Get(gce.projectID, makeFirewallName(name)).Do() + if err != nil { + if isHTTPErrorCode(err, http.StatusNotFound) { + return false, true, nil + } + return false, false, fmt.Errorf("error getting load balancer's target pool: %v", err) + } + if fw.Description != makeFirewallDescription(ipAddress) { + return true, true, nil + } + if len(fw.Allowed) != 1 || fw.Allowed[0].IPProtocol != "tcp" { + return true, true, nil + } + // Make sure the allowed ports match. + allowedPorts := make([]string, len(ports)) + for ix := range ports { + allowedPorts[ix] = strconv.Itoa(ports[ix].Port) + } + if !slicesEqual(allowedPorts, fw.Allowed[0].Ports) { + return true, true, nil + } + return true, false, nil +} + +func makeFirewallName(name string) string { + return fmt.Sprintf("k8s-fw-%s", name) +} + +func makeFirewallDescription(ipAddress string) string { + return fmt.Sprintf("KubernetesAutoGenerated_OnlyAllowTrafficForDestinationIP_%s", ipAddress) +} + +func slicesEqual(x, y []string) bool { + if len(x) != len(y) { + return false + } + sort.Strings(x) + sort.Strings(y) + for i := range x { + if x[i] != y[i] { + return false + } + } + return true +} + +func (gce *GCECloud) createForwardingRule(name, region, ipAddress string, ports []*api.ServicePort) error { + portRange, err := loadBalancerPortRange(ports) + if err != nil { + return err + } req := &compute.ForwardingRule{ Name: name, + IPAddress: ipAddress, IPProtocol: "TCP", - PortRange: fmt.Sprintf("%d-%d", minPort, maxPort), + PortRange: portRange, Target: gce.targetPoolURL(name, region), } - if loadBalancerIP != nil { - req.IPAddress = loadBalancerIP.String() - } op, err := gce.service.ForwardingRules.Insert(gce.projectID, region, req).Do() if err != nil && !isHTTPErrorCode(err, http.StatusConflict) { - return nil, err + return err } if op != nil { err = gce.waitForRegionOp(op, region) if err != nil && !isHTTPErrorCode(err, http.StatusConflict) { - return nil, err + return err } } - fwd, err := gce.service.ForwardingRules.Get(gce.projectID, region, name).Do() + return nil +} + +func (gce *GCECloud) createTargetPool(name, region string, hosts []string, affinityType api.ServiceAffinity) error { + var instances []string + for _, host := range hosts { + instances = append(instances, makeHostURL(gce.projectID, gce.zone, host)) + } + pool := &compute.TargetPool{ + Name: name, + Instances: instances, + SessionAffinity: translateAffinityType(affinityType), + } + op, err := gce.service.TargetPools.Insert(gce.projectID, region, pool).Do() + if err != nil && !isHTTPErrorCode(err, http.StatusConflict) { + return err + } + if op != nil { + err = gce.waitForRegionOp(op, region) + if err != nil && !isHTTPErrorCode(err, http.StatusConflict) { + return err + } + } + return nil +} + +func (gce *GCECloud) createFirewall(name, region, ipAddress string, ports []*api.ServicePort, hosts []string) error { + firewall, err := gce.firewallObject(name, region, ipAddress, ports, hosts) if err != nil { - return nil, err + return err + } + op, err := gce.service.Firewalls.Insert(gce.projectID, firewall).Do() + if err != nil && !isHTTPErrorCode(err, http.StatusConflict) { + return err + } + if op != nil { + err = gce.waitForGlobalOp(op) + if err != nil && !isHTTPErrorCode(err, http.StatusConflict) { + return err + } + } + return nil +} + +func (gce *GCECloud) updateFirewall(name, region, ipAddress string, ports []*api.ServicePort, hosts []string) error { + firewall, err := gce.firewallObject(name, region, ipAddress, ports, hosts) + if err != nil { + return err + } + op, err := gce.service.Firewalls.Update(gce.projectID, makeFirewallName(name), firewall).Do() + if err != nil && !isHTTPErrorCode(err, http.StatusConflict) { + return err + } + if op != nil { + err = gce.waitForGlobalOp(op) + if err != nil { + return err + } } + return nil +} +func (gce *GCECloud) firewallObject(name, region, ipAddress string, ports []*api.ServicePort, hosts []string) (*compute.Firewall, error) { allowedPorts := make([]string, len(ports)) for ix := range ports { allowedPorts[ix] = strconv.Itoa(ports[ix].Port) } - - hostTag := gce.computeHostTag(hosts[0]) - + hostTags, err := gce.computeHostTags(hosts) + if err != nil { + return nil, err + } firewall := &compute.Firewall{ Name: makeFirewallName(name), - Description: fmt.Sprintf("KubernetesAutoGenerated_OnlyAllowTrafficForDestinationIP_%s", fwd.IPAddress), + Description: makeFirewallDescription(ipAddress), Network: gce.networkURL, SourceRanges: []string{"0.0.0.0/0"}, - TargetTags: []string{hostTag}, + TargetTags: hostTags, Allowed: []*compute.FirewallAllowed{ { IPProtocol: "tcp", @@ -438,28 +657,89 @@ func (gce *GCECloud) EnsureTCPLoadBalancer(name, region string, loadBalancerIP n }, }, } - if op, err = gce.service.Firewalls.Insert(gce.projectID, firewall).Do(); err != nil && !isHTTPErrorCode(err, http.StatusConflict) { + return firewall, nil +} + +// We grab all tags from all instances being added to the pool. +// * The longest tag that is a prefix of the instance name is used +// * If any instance has a prefix tag, all instances must +// * If no instances have a prefix tag, no tags are used +func (gce *GCECloud) computeHostTags(hosts []string) ([]string, error) { + listCall := gce.service.Instances.List(gce.projectID, gce.zone) + + // Add the filter for hosts + listCall = listCall.Filter("name eq (" + strings.Join(hosts, "|") + ")") + + // Add the fields we want + listCall = listCall.Fields("items(name,tags)") + + res, err := listCall.Do() + if err != nil { return nil, err } - if err = gce.waitForGlobalOp(op); err != nil && !isHTTPErrorCode(err, http.StatusConflict) { - return nil, err + + tags := sets.NewString() + for _, instance := range res.Items { + longest_tag := "" + for _, tag := range instance.Tags.Items { + if strings.HasPrefix(instance.Name, tag) && len(tag) > len(longest_tag) { + longest_tag = tag + } + } + if len(longest_tag) > 0 { + tags.Insert(longest_tag) + } else if len(tags) > 0 { + return nil, fmt.Errorf("Some, but not all, instances have prefix tags (%s is missing)", instance.Name) + } } - status := &api.LoadBalancerStatus{} - status.Ingress = []api.LoadBalancerIngress{{IP: fwd.IPAddress}} - return status, nil + if len(tags) == 0 { + glog.V(2).Info("No instances had tags, creating rule without target tags") + } + + return tags.List(), nil } -// This is kind of hacky, but the managed instance group adds 4 random chars and a hyphen -// to the base name. Older naming schemes put a hyphen and an incrementing index after -// the base name. Thus we pull off the characters after the final dash to support both. -func (gce *GCECloud) computeHostTag(host string) string { - host = strings.SplitN(host, ".", 2)[0] - lastHyphen := strings.LastIndex(host, "-") - if lastHyphen == -1 { - return host +func (gce *GCECloud) projectOwnsStaticIP(name, region string, ipAddress string) error { + addresses, err := gce.service.Addresses.List(gce.projectID, region).Do() + if err != nil { + return fmt.Errorf("failed to list gce IP addresses: %v", err) } - return host[:lastHyphen] + for _, addr := range addresses.Items { + if addr.Address == ipAddress { + // This project does own the address, so return success. + return nil + } + } + return fmt.Errorf("this gce project doesn't own the IP address: %s", ipAddress) +} + +func (gce *GCECloud) createOrPromoteStaticIP(name, region, existingIP string) (ipAddress string, err error) { + // If the address doesn't exist, this will create it. + // If the existingIP exists but is ephemeral, this will promote it to static. + // If the address already exists, this will harmlessly return a StatusConflict + // and we'll grab the IP before returning. + addressObj := &compute.Address{Name: name} + if existingIP != "" { + addressObj.Address = existingIP + } + op, err := gce.service.Addresses.Insert(gce.projectID, region, addressObj).Do() + if err != nil && !isHTTPErrorCode(err, http.StatusConflict) { + return "", fmt.Errorf("error creating gce static IP address: %v", err) + } + if op != nil { + err := gce.waitForRegionOp(op, region) + if err != nil && !isHTTPErrorCode(err, http.StatusConflict) { + return "", fmt.Errorf("error waiting for gce static IP address to be created: %v", err) + } + } + + // We have to get the address to know which IP was allocated for us. + address, err := gce.service.Addresses.Get(gce.projectID, region, name).Do() + if err != nil { + return "", fmt.Errorf("error re-getting gce static IP address: %v", err) + } + return address.Address, nil } // UpdateTCPLoadBalancer is an implementation of TCPLoadBalancer.UpdateTCPLoadBalancer. @@ -525,45 +805,412 @@ func (gce *GCECloud) UpdateTCPLoadBalancer(name, region string, hosts []string) // EnsureTCPLoadBalancerDeleted is an implementation of TCPLoadBalancer.EnsureTCPLoadBalancerDeleted. func (gce *GCECloud) EnsureTCPLoadBalancerDeleted(name, region string) error { + err := errors.AggregateGoroutines( + func() error { return gce.deleteFirewall(name, region) }, + // Even though we don't hold on to static IPs for load balancers, it's + // possible that EnsureTCPLoadBalancer left one around in a failed + // creation/update attempt, so make sure we clean it up here just in case. + func() error { return gce.deleteStaticIP(name, region) }, + func() error { + // The forwarding rule must be deleted before either the target pool can, + // unfortunately, so we have to do these two serially. + if err := gce.deleteForwardingRule(name, region); err != nil { + return err + } + if err := gce.deleteTargetPool(name, region); err != nil { + return err + } + return nil + }, + ) + if err != nil { + return errors.Flatten(err) + } + return nil +} + +func (gce *GCECloud) deleteForwardingRule(name, region string) error { op, err := gce.service.ForwardingRules.Delete(gce.projectID, region, name).Do() if err != nil && isHTTPErrorCode(err, http.StatusNotFound) { - glog.Infof("Forwarding rule %s already deleted. Continuing to delete target pool.", name) + glog.Infof("Forwarding rule %s already deleted. Continuing to delete other resources.", name) } else if err != nil { - glog.Warningf("Failed to delete Forwarding Rules %s: got error %s.", name, err.Error()) + glog.Warningf("Failed to delete forwarding rule %s: got error %s.", name, err.Error()) return err } else { - err = gce.waitForRegionOp(op, region) - if err != nil { - glog.Warningf("Failed waiting for Forwarding Rule %s to be deleted: got error %s.", name, err.Error()) + if err := gce.waitForRegionOp(op, region); err != nil { + glog.Warningf("Failed waiting for forwarding rule %s to be deleted: got error %s.", name, err.Error()) return err } } - op, err = gce.service.TargetPools.Delete(gce.projectID, region, name).Do() + return nil +} + +func (gce *GCECloud) deleteTargetPool(name, region string) error { + op, err := gce.service.TargetPools.Delete(gce.projectID, region, name).Do() if err != nil && isHTTPErrorCode(err, http.StatusNotFound) { - glog.Infof("Target pool %s already deleted.", name) - return nil + glog.Infof("Target pool %s already deleted. Continuing to delete other resources.", name) } else if err != nil { - glog.Warningf("Failed to delete Target Pool %s, got error %s.", name, err.Error()) + glog.Warningf("Failed to delete target pool %s, got error %s.", name, err.Error()) return err + } else { + if err := gce.waitForRegionOp(op, region); err != nil { + glog.Warningf("Failed waiting for target pool %s to be deleted: got error %s.", name, err.Error()) + return err + } } - err = gce.waitForRegionOp(op, region) - if err != nil { - glog.Warningf("Failed waiting for Target Pool %s to be deleted: got error %s.", name, err.Error()) - } + return nil +} + +func (gce *GCECloud) deleteFirewall(name, region string) error { fwName := makeFirewallName(name) - op, err = gce.service.Firewalls.Delete(gce.projectID, fwName).Do() + op, err := gce.service.Firewalls.Delete(gce.projectID, fwName).Do() if err != nil && isHTTPErrorCode(err, http.StatusNotFound) { - glog.Infof("Firewall doesn't exist, moving on to deleting target pool.") + glog.Infof("Firewall %s already deleted. Continuing to delete other resources.", name) } else if err != nil { glog.Warningf("Failed to delete firewall %s, got error %v", fwName, err) return err } else { - if err = gce.waitForGlobalOp(op); err != nil { + if err := gce.waitForGlobalOp(op); err != nil { glog.Warningf("Failed waiting for Firewall %s to be deleted. Got error: %v", fwName, err) return err } } - return err + return nil +} + +func (gce *GCECloud) deleteStaticIP(name, region string) error { + op, err := gce.service.Addresses.Delete(gce.projectID, region, name).Do() + if err != nil && isHTTPErrorCode(err, http.StatusNotFound) { + glog.Infof("Static IP address %s already deleted. Continuing to delete other resources.", name) + } else if err != nil { + glog.Warningf("Failed to delete static IP address %s, got error %v", name, err) + return err + } else { + if err := gce.waitForRegionOp(op, region); err != nil { + glog.Warningf("Failed waiting for address %s to be deleted, got error: %v", name, err) + return err + } + } + return nil +} + +// UrlMap management + +// GetUrlMap returns the UrlMap by name. +func (gce *GCECloud) GetUrlMap(name string) (*compute.UrlMap, error) { + return gce.service.UrlMaps.Get(gce.projectID, name).Do() +} + +// CreateUrlMap creates an url map, using the given backend service as the default service. +func (gce *GCECloud) CreateUrlMap(backend *compute.BackendService, name string) (*compute.UrlMap, error) { + urlMap := &compute.UrlMap{ + Name: name, + DefaultService: backend.SelfLink, + } + op, err := gce.service.UrlMaps.Insert(gce.projectID, urlMap).Do() + if err != nil { + return nil, err + } + if err = gce.waitForGlobalOp(op); err != nil { + return nil, err + } + return gce.GetUrlMap(name) +} + +// UpdateUrlMap applies the given UrlMap as an update, and returns the new UrlMap. +func (gce *GCECloud) UpdateUrlMap(urlMap *compute.UrlMap) (*compute.UrlMap, error) { + op, err := gce.service.UrlMaps.Update(gce.projectID, urlMap.Name, urlMap).Do() + if err != nil { + return nil, err + } + if err = gce.waitForGlobalOp(op); err != nil { + return nil, err + } + return gce.service.UrlMaps.Get(gce.projectID, urlMap.Name).Do() +} + +// DeleteUrlMap deletes a url map by name. +func (gce *GCECloud) DeleteUrlMap(name string) error { + op, err := gce.service.UrlMaps.Delete(gce.projectID, name).Do() + if err != nil { + if isHTTPErrorCode(err, http.StatusNotFound) { + return nil + } + return err + } + return gce.waitForGlobalOp(op) +} + +// TargetHttpProxy management + +// GetTargetHttpProxy returns the UrlMap by name. +func (gce *GCECloud) GetTargetHttpProxy(name string) (*compute.TargetHttpProxy, error) { + return gce.service.TargetHttpProxies.Get(gce.projectID, name).Do() +} + +// CreateTargetHttpProxy creates and returns a TargetHttpProxy with the given UrlMap. +func (gce *GCECloud) CreateTargetHttpProxy(urlMap *compute.UrlMap, name string) (*compute.TargetHttpProxy, error) { + proxy := &compute.TargetHttpProxy{ + Name: name, + UrlMap: urlMap.SelfLink, + } + op, err := gce.service.TargetHttpProxies.Insert(gce.projectID, proxy).Do() + if err != nil { + return nil, err + } + if err = gce.waitForGlobalOp(op); err != nil { + return nil, err + } + return gce.GetTargetHttpProxy(name) +} + +// SetUrlMapForTargetHttpProxy sets the given UrlMap for the given TargetHttpProxy. +func (gce *GCECloud) SetUrlMapForTargetHttpProxy(proxy *compute.TargetHttpProxy, urlMap *compute.UrlMap) error { + op, err := gce.service.TargetHttpProxies.SetUrlMap(gce.projectID, proxy.Name, &compute.UrlMapReference{urlMap.SelfLink}).Do() + if err != nil { + return err + } + return gce.waitForGlobalOp(op) +} + +// DeleteTargetHttpProxy deletes the TargetHttpProxy by name. +func (gce *GCECloud) DeleteTargetHttpProxy(name string) error { + op, err := gce.service.TargetHttpProxies.Delete(gce.projectID, name).Do() + if err != nil { + if isHTTPErrorCode(err, http.StatusNotFound) { + return nil + } + return err + } + return gce.waitForGlobalOp(op) +} + +// GlobalForwardingRule management + +// CreateGlobalForwardingRule creates and returns a GlobalForwardingRule that points to the given TargetHttpProxy. +func (gce *GCECloud) CreateGlobalForwardingRule(proxy *compute.TargetHttpProxy, name string, portRange string) (*compute.ForwardingRule, error) { + rule := &compute.ForwardingRule{ + Name: name, + Target: proxy.SelfLink, + PortRange: portRange, + IPProtocol: "TCP", + } + op, err := gce.service.GlobalForwardingRules.Insert(gce.projectID, rule).Do() + if err != nil { + return nil, err + } + if err = gce.waitForGlobalOp(op); err != nil { + return nil, err + } + return gce.GetGlobalForwardingRule(name) +} + +// SetProxyForGlobalForwardingRule links the given TargetHttpProxy with the given GlobalForwardingRule. +func (gce *GCECloud) SetProxyForGlobalForwardingRule(fw *compute.ForwardingRule, proxy *compute.TargetHttpProxy) error { + op, err := gce.service.GlobalForwardingRules.SetTarget(gce.projectID, fw.Name, &compute.TargetReference{proxy.SelfLink}).Do() + if err != nil { + return err + } + return gce.waitForGlobalOp(op) +} + +// DeleteGlobalForwardingRule deletes the GlobalForwardingRule by name. +func (gce *GCECloud) DeleteGlobalForwardingRule(name string) error { + op, err := gce.service.GlobalForwardingRules.Delete(gce.projectID, name).Do() + if err != nil { + if isHTTPErrorCode(err, http.StatusNotFound) { + return nil + } + return err + } + return gce.waitForGlobalOp(op) +} + +// GetGlobalForwardingRule returns the GlobalForwardingRule by name. +func (gce *GCECloud) GetGlobalForwardingRule(name string) (*compute.ForwardingRule, error) { + return gce.service.GlobalForwardingRules.Get(gce.projectID, name).Do() +} + +// BackendService Management + +// GetBackendService retrieves a backend by name. +func (gce *GCECloud) GetBackendService(name string) (*compute.BackendService, error) { + return gce.service.BackendServices.Get(gce.projectID, name).Do() +} + +// UpdateBackendService applies the given BackendService as an update to an existing service. +func (gce *GCECloud) UpdateBackendService(bg *compute.BackendService) error { + op, err := gce.service.BackendServices.Update(gce.projectID, bg.Name, bg).Do() + if err != nil { + return err + } + return gce.waitForGlobalOp(op) +} + +// DeleteBackendService deletes the given BackendService by name. +func (gce *GCECloud) DeleteBackendService(name string) error { + op, err := gce.service.BackendServices.Delete(gce.projectID, name).Do() + if err != nil { + if isHTTPErrorCode(err, http.StatusNotFound) { + return nil + } + return err + } + return gce.waitForGlobalOp(op) +} + +// CreateBackendService creates the given BackendService. +func (gce *GCECloud) CreateBackendService(bg *compute.BackendService) error { + op, err := gce.service.BackendServices.Insert(gce.projectID, bg).Do() + if err != nil { + return err + } + return gce.waitForGlobalOp(op) +} + +// Health Checks + +// GetHttpHealthCheck returns the given HttpHealthCheck by name. +func (gce *GCECloud) GetHttpHealthCheck(name string) (*compute.HttpHealthCheck, error) { + return gce.service.HttpHealthChecks.Get(gce.projectID, name).Do() +} + +// UpdateHttpHealthCheck applies the given HttpHealthCheck as an update. +func (gce *GCECloud) UpdateHttpHealthCheck(hc *compute.HttpHealthCheck) error { + op, err := gce.service.HttpHealthChecks.Update(gce.projectID, hc.Name, hc).Do() + if err != nil { + return err + } + return gce.waitForGlobalOp(op) +} + +// DeleteHttpHealthCheck deletes the given HttpHealthCheck by name. +func (gce *GCECloud) DeleteHttpHealthCheck(name string) error { + op, err := gce.service.HttpHealthChecks.Delete(gce.projectID, name).Do() + if err != nil { + if isHTTPErrorCode(err, http.StatusNotFound) { + return nil + } + return err + } + return gce.waitForGlobalOp(op) +} + +// CreateHttpHealthCheck creates the given HttpHealthCheck. +func (gce *GCECloud) CreateHttpHealthCheck(hc *compute.HttpHealthCheck) error { + op, err := gce.service.HttpHealthChecks.Insert(gce.projectID, hc).Do() + if err != nil { + return err + } + return gce.waitForGlobalOp(op) +} + +// InstanceGroup Management + +// CreateInstanceGroup creates an instance group with the given instances. It is the callers responsibility to add named ports. +func (gce *GCECloud) CreateInstanceGroup(name string) (*compute.InstanceGroup, error) { + op, err := gce.service.InstanceGroups.Insert( + gce.projectID, gce.zone, &compute.InstanceGroup{Name: name}).Do() + if err != nil { + return nil, err + } + if err = gce.waitForZoneOp(op); err != nil { + return nil, err + } + return gce.GetInstanceGroup(name) +} + +// DeleteInstanceGroup deletes an instance group. +func (gce *GCECloud) DeleteInstanceGroup(name string) error { + op, err := gce.service.InstanceGroups.Delete( + gce.projectID, gce.zone, name).Do() + if err != nil { + return err + } + return gce.waitForZoneOp(op) +} + +// ListInstancesInInstanceGroup lists all the instances in a given istance group and state. +func (gce *GCECloud) ListInstancesInInstanceGroup(name string, state string) (*compute.InstanceGroupsListInstances, error) { + return gce.service.InstanceGroups.ListInstances( + gce.projectID, gce.zone, name, + &compute.InstanceGroupsListInstancesRequest{InstanceState: state}).Do() +} + +// AddInstancesToInstanceGroup adds the given instances to the given instance group. +func (gce *GCECloud) AddInstancesToInstanceGroup(name string, instanceNames []string) error { + if len(instanceNames) == 0 { + return nil + } + // Adding the same instance twice will result in a 4xx error + instances := []*compute.InstanceReference{} + for _, ins := range instanceNames { + instances = append(instances, &compute.InstanceReference{makeHostURL(gce.projectID, gce.zone, ins)}) + } + op, err := gce.service.InstanceGroups.AddInstances( + gce.projectID, gce.zone, name, + &compute.InstanceGroupsAddInstancesRequest{ + Instances: instances, + }).Do() + + if err != nil { + return err + } + return gce.waitForZoneOp(op) +} + +// RemoveInstancesFromInstanceGroup removes the given instances from the instance group. +func (gce *GCECloud) RemoveInstancesFromInstanceGroup(name string, instanceNames []string) error { + if len(instanceNames) == 0 { + return nil + } + instances := []*compute.InstanceReference{} + for _, ins := range instanceNames { + instanceLink := makeHostURL(gce.projectID, gce.zone, ins) + instances = append(instances, &compute.InstanceReference{instanceLink}) + } + op, err := gce.service.InstanceGroups.RemoveInstances( + gce.projectID, gce.zone, name, + &compute.InstanceGroupsRemoveInstancesRequest{ + Instances: instances, + }).Do() + + if err != nil { + if isHTTPErrorCode(err, http.StatusNotFound) { + return nil + } + return err + } + return gce.waitForZoneOp(op) +} + +// AddPortToInstanceGroup adds a port to the given instance group. +func (gce *GCECloud) AddPortToInstanceGroup(ig *compute.InstanceGroup, port int64) (*compute.NamedPort, error) { + for _, np := range ig.NamedPorts { + if np.Port == port { + glog.Infof("Instance group %v already has named port %+v", ig.Name, np) + return np, nil + } + } + glog.Infof("Adding port %v to instance group %v with %d ports", port, ig.Name, len(ig.NamedPorts)) + namedPort := compute.NamedPort{fmt.Sprintf("port%v", port), port} + ig.NamedPorts = append(ig.NamedPorts, &namedPort) + op, err := gce.service.InstanceGroups.SetNamedPorts( + gce.projectID, gce.zone, ig.Name, + &compute.InstanceGroupsSetNamedPortsRequest{ + NamedPorts: ig.NamedPorts}).Do() + if err != nil { + return nil, err + } + if err = gce.waitForZoneOp(op); err != nil { + return nil, err + } + return &namedPort, nil +} + +// GetInstanceGroup returns an instance group by name. +func (gce *GCECloud) GetInstanceGroup(name string) (*compute.InstanceGroup, error) { + return gce.service.InstanceGroups.Get(gce.projectID, gce.zone, name).Do() } // Take a GCE instance 'hostname' and break it down to something that can be fed @@ -792,7 +1439,8 @@ func (gce *GCECloud) AttachDisk(diskName string, readOnly bool) error { readWrite = "READ_ONLY" } attachedDisk := gce.convertDiskToAttachedDisk(disk, readWrite) - _, err = gce.service.Instances.AttachDisk(gce.projectID, gce.zone, gce.instanceID, attachedDisk).Do() + + attachOp, err := gce.service.Instances.AttachDisk(gce.projectID, gce.zone, gce.instanceID, attachedDisk).Do() if err != nil { // Check if the disk is already attached to this instance. We do this only // in the error case, since it is expected to be exceptional. @@ -806,14 +1454,18 @@ func (gce *GCECloud) AttachDisk(diskName string, readOnly bool) error { return nil } } - } - return err + + return gce.waitForZoneOp(attachOp) } func (gce *GCECloud) DetachDisk(devicePath string) error { - _, err := gce.service.Instances.DetachDisk(gce.projectID, gce.zone, gce.instanceID, devicePath).Do() - return err + detachOp, err := gce.service.Instances.DetachDisk(gce.projectID, gce.zone, gce.instanceID, devicePath).Do() + if err != nil { + return err + } + + return gce.waitForZoneOp(detachOp) } func (gce *GCECloud) getDisk(diskName string) (*compute.Disk, error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_test.go index 3f916848135e..0c2504c99c32 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_test.go @@ -16,9 +16,7 @@ limitations under the License. package gce_cloud -import ( - "testing" -) +import "testing" func TestGetRegion(t *testing.T) { gce := &GCECloud{ @@ -37,34 +35,6 @@ func TestGetRegion(t *testing.T) { } } -func TestGetHostTag(t *testing.T) { - tests := []struct { - host string - expected string - }{ - { - host: "kubernetes-minion-559o", - expected: "kubernetes-minion", - }, - { - host: "gke-test-ea6e8c80-node-8ytk", - expected: "gke-test-ea6e8c80-node", - }, - { - host: "kubernetes-minion-559o.c.PROJECT_NAME.internal", - expected: "kubernetes-minion", - }, - } - - gce := &GCECloud{} - for _, test := range tests { - hostTag := gce.computeHostTag(test.host) - if hostTag != test.expected { - t.Errorf("expected: %s, saw: %s for %s", test.expected, hostTag, test.host) - } - } -} - func TestComparingHostURLs(t *testing.T) { tests := []struct { host1 string diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/controller_utils.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/controller_utils.go index d49d720981bb..2601b5b9c8bf 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/controller_utils.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/controller_utils.go @@ -18,15 +18,14 @@ package controller import ( "fmt" - "time" - + "sync" "sync/atomic" + "time" "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/validation" - "k8s.io/kubernetes/pkg/apis/experimental" "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/client/record" client "k8s.io/kubernetes/pkg/client/unversioned" @@ -44,7 +43,7 @@ const ( // of expectations, without it the controller could stay asleep forever. This should // be set based on the expected latency of watch events. // - // Currently an controller can service (create *and* observe the watch events for said + // Currently a controller can service (create *and* observe the watch events for said // creation) about 10-20 pods a second, so it takes about 1 min to service // 500 pods. Just creation is limited to 20qps, and watching happens with ~10-30s // latency/pod at the scale of 3000 pods over 100 nodes. @@ -55,6 +54,13 @@ var ( KeyFunc = framework.DeletionHandlingMetaNamespaceKeyFunc ) +type ResyncPeriodFunc func() time.Duration + +// Returns 0 for resyncPeriod in case resyncing is not needed. +func NoResyncPeriodFunc() time.Duration { + return 0 +} + // Expectations are a way for controllers to tell the controller manager what they expect. eg: // ControllerExpectations: { // controller1: expects 2 adds in 2 minutes @@ -213,10 +219,10 @@ func NewControllerExpectations() *ControllerExpectations { // PodControlInterface is an interface that knows how to add or delete pods // created as an interface to allow testing. type PodControlInterface interface { - // CreateReplica creates new replicated pods according to the spec. - CreateReplica(namespace string, controller *api.ReplicationController) error - // CreateReplicaOnNode creates a new pod according to the spec on the specified node. - CreateReplicaOnNode(namespace string, ds *experimental.DaemonSet, nodeName string) error + // CreatePods creates new pods according to the spec. + CreatePods(namespace string, template *api.PodTemplateSpec, object runtime.Object) error + // CreatePodsOnNode creates a new pod accorting to the spec on the specified node. + CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error // DeletePod deletes the pod identified by podID. DeletePod(namespace string, podID string) error } @@ -227,7 +233,9 @@ type RealPodControl struct { Recorder record.EventRecorder } -func getReplicaLabelSet(template *api.PodTemplateSpec) labels.Set { +var _ PodControlInterface = &RealPodControl{} + +func getPodsLabelSet(template *api.PodTemplateSpec) labels.Set { desiredLabels := make(labels.Set) for k, v := range template.Labels { desiredLabels[k] = v @@ -235,7 +243,7 @@ func getReplicaLabelSet(template *api.PodTemplateSpec) labels.Set { return desiredLabels } -func getReplicaAnnotationSet(template *api.PodTemplateSpec, object runtime.Object) (labels.Set, error) { +func getPodsAnnotationSet(template *api.PodTemplateSpec, object runtime.Object) (labels.Set, error) { desiredAnnotations := make(labels.Set) for k, v := range template.Annotations { desiredAnnotations[k] = v @@ -244,7 +252,7 @@ func getReplicaAnnotationSet(template *api.PodTemplateSpec, object runtime.Objec if err != nil { return desiredAnnotations, fmt.Errorf("unable to get controller reference: %v", err) } - createdByRefJson, err := latest.Codec.Encode(&api.SerializedReference{ + createdByRefJson, err := latest.GroupOrDie("").Codec.Encode(&api.SerializedReference{ Reference: *createdByRef, }) if err != nil { @@ -254,7 +262,7 @@ func getReplicaAnnotationSet(template *api.PodTemplateSpec, object runtime.Objec return desiredAnnotations, nil } -func getReplicaPrefix(controllerName string) string { +func getPodsPrefix(controllerName string) string { // use the dash (if the name isn't too long) to make the pod name a bit prettier prefix := fmt.Sprintf("%s-", controllerName) if ok, _ := validation.ValidatePodName(prefix, true); !ok { @@ -263,13 +271,25 @@ func getReplicaPrefix(controllerName string) string { return prefix } -func (r RealPodControl) CreateReplica(namespace string, controller *api.ReplicationController) error { - desiredLabels := getReplicaLabelSet(controller.Spec.Template) - desiredAnnotations, err := getReplicaAnnotationSet(controller.Spec.Template, controller) +func (r RealPodControl) CreatePods(namespace string, template *api.PodTemplateSpec, object runtime.Object) error { + return r.createPods("", namespace, template, object) +} + +func (r RealPodControl) CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error { + return r.createPods(nodeName, namespace, template, object) +} + +func (r RealPodControl) createPods(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error { + desiredLabels := getPodsLabelSet(template) + desiredAnnotations, err := getPodsAnnotationSet(template, object) if err != nil { return err } - prefix := getReplicaPrefix(controller.Name) + meta, err := api.ObjectMetaFor(object) + if err != nil { + return fmt.Errorf("object does not have ObjectMeta, %v", err) + } + prefix := getPodsPrefix(meta.Name) pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ @@ -278,58 +298,73 @@ func (r RealPodControl) CreateReplica(namespace string, controller *api.Replicat GenerateName: prefix, }, } - if err := api.Scheme.Convert(&controller.Spec.Template.Spec, &pod.Spec); err != nil { + if err := api.Scheme.Convert(&template.Spec, &pod.Spec); err != nil { return fmt.Errorf("unable to convert pod template: %v", err) } + if len(nodeName) != 0 { + pod.Spec.NodeName = nodeName + } if labels.Set(pod.Labels).AsSelector().Empty() { - return fmt.Errorf("unable to create pod replica, no labels") + return fmt.Errorf("unable to create pods, no labels") } if newPod, err := r.KubeClient.Pods(namespace).Create(pod); err != nil { - r.Recorder.Eventf(controller, "FailedCreate", "Error creating: %v", err) - return fmt.Errorf("unable to create pod replica: %v", err) + r.Recorder.Eventf(object, "FailedCreate", "Error creating: %v", err) + return fmt.Errorf("unable to create pods: %v", err) } else { - glog.V(4).Infof("Controller %v created pod %v", controller.Name, newPod.Name) - r.Recorder.Eventf(controller, "SuccessfulCreate", "Created pod: %v", newPod.Name) + glog.V(4).Infof("Controller %v created pod %v", meta.Name, newPod.Name) + r.Recorder.Eventf(object, "SuccessfulCreate", "Created pod: %v", newPod.Name) } return nil } -func (r RealPodControl) CreateReplicaOnNode(namespace string, ds *experimental.DaemonSet, nodeName string) error { - desiredLabels := getReplicaLabelSet(ds.Spec.Template) - desiredAnnotations, err := getReplicaAnnotationSet(ds.Spec.Template, ds) - if err != nil { - return err - } - prefix := getReplicaPrefix(ds.Name) +func (r RealPodControl) DeletePod(namespace, podID string) error { + return r.KubeClient.Pods(namespace).Delete(podID, nil) +} - pod := &api.Pod{ - ObjectMeta: api.ObjectMeta{ - Labels: desiredLabels, - Annotations: desiredAnnotations, - GenerateName: prefix, - }, - } - if err := api.Scheme.Convert(&ds.Spec.Template.Spec, &pod.Spec); err != nil { - return fmt.Errorf("unable to convert pod template: %v", err) - } - // if a pod does not have labels then it cannot be controlled by any controller - if labels.Set(pod.Labels).AsSelector().Empty() { - return fmt.Errorf("unable to create pod replica, no labels") +type FakePodControl struct { + sync.Mutex + Templates []api.PodTemplateSpec + DeletePodName []string + Err error +} + +var _ PodControlInterface = &FakePodControl{} + +func (f *FakePodControl) CreatePods(namespace string, spec *api.PodTemplateSpec, object runtime.Object) error { + f.Lock() + defer f.Unlock() + if f.Err != nil { + return f.Err } - pod.Spec.NodeName = nodeName - if newPod, err := r.KubeClient.Pods(namespace).Create(pod); err != nil { - r.Recorder.Eventf(ds, "failedCreate", "Error creating: %v", err) - return fmt.Errorf("unable to create pod replica: %v", err) - } else { - glog.V(4).Infof("Controller %v created pod %v", ds.Name, newPod.Name) - r.Recorder.Eventf(ds, "successfulCreate", "Created pod: %v", newPod.Name) + f.Templates = append(f.Templates, *spec) + return nil +} + +func (f *FakePodControl) CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error { + f.Lock() + defer f.Unlock() + if f.Err != nil { + return f.Err } + f.Templates = append(f.Templates, *template) + return nil +} +func (f *FakePodControl) DeletePod(namespace string, podName string) error { + f.Lock() + defer f.Unlock() + if f.Err != nil { + return f.Err + } + f.DeletePodName = append(f.DeletePodName, podName) return nil } -func (r RealPodControl) DeletePod(namespace, podID string) error { - return r.KubeClient.Pods(namespace).Delete(podID, nil) +func (f *FakePodControl) Clear() { + f.Lock() + defer f.Unlock() + f.DeletePodName = []string{} + f.Templates = []api.PodTemplateSpec{} } // ActivePods type allows custom sorting of pods so a controller can pick the best ones to delete. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/controller_utils_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/controller_utils_test.go index 07574f2500a4..c9c39c0b5578 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/controller_utils_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/controller_utils_test.go @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/client/record" client "k8s.io/kubernetes/pkg/client/unversioned" @@ -49,7 +50,7 @@ func NewFakeControllerExpectationsLookup(ttl time.Duration) (*ControllerExpectat func newReplicationController(replicas int) *api.ReplicationController { rc := &api.ReplicationController{ - TypeMeta: api.TypeMeta{APIVersion: testapi.Default.Version()}, + TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.Version()}, ObjectMeta: api.ObjectMeta{ UID: util.NewUUID(), Name: "foobar", @@ -180,7 +181,7 @@ func TestControllerExpectations(t *testing.T) { } } -func TestCreateReplica(t *testing.T) { +func TestCreatePods(t *testing.T) { ns := api.NamespaceDefault body := runtime.EncodeOrDie(testapi.Default.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Name: "empty_pod"}}) fakeHandler := util.FakeHandler{ @@ -199,7 +200,7 @@ func TestCreateReplica(t *testing.T) { controllerSpec := newReplicationController(1) // Make sure createReplica sends a POST to the apiserver with a pod from the controllers pod template - podControl.CreateReplica(ns, controllerSpec) + podControl.CreatePods(ns, controllerSpec.Spec.Template, controllerSpec) expectedPod := api.Pod{ ObjectMeta: api.ObjectMeta{ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/daemon/controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/daemon/controller.go index e6db35b14d1a..408a45c30efe 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/daemon/controller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/daemon/controller.go @@ -23,7 +23,7 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/client/record" client "k8s.io/kubernetes/pkg/client/unversioned" @@ -40,10 +40,11 @@ import ( const ( // Daemon sets will periodically check that their daemon pods are running as expected. FullDaemonSetResyncPeriod = 30 * time.Second // TODO: Figure out if this time seems reasonable. - // Nodes don't need relisting. - FullNodeResyncPeriod = 0 - // Daemon pods don't need relisting. - FullDaemonPodResyncPeriod = 0 + + // We must avoid counting pods until the pod store has synced. If it hasn't synced, to + // avoid a hot loop, we'll wait this long between checks. + PodStoreSyncedPollPeriod = 100 * time.Millisecond + // If sending a status upate to API server fails, we retry a finite number of times. StatusUpdateRetries = 1 ) @@ -70,11 +71,15 @@ type DaemonSetsController struct { podController *framework.Controller // Watches changes to all nodes. nodeController *framework.Controller + // podStoreSynced returns true if the pod store has been synced at least once. + // Added as a member to the struct to allow injection for testing. + podStoreSynced func() bool + // Daemon sets that need to be synced. queue *workqueue.Type } -func NewDaemonSetsController(kubeClient client.Interface) *DaemonSetsController { +func NewDaemonSetsController(kubeClient client.Interface, resyncPeriod controller.ResyncPeriodFunc) *DaemonSetsController { eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartLogging(glog.Infof) eventBroadcaster.StartRecordingToSink(kubeClient.Events("")) @@ -92,27 +97,28 @@ func NewDaemonSetsController(kubeClient client.Interface) *DaemonSetsController dsc.dsStore.Store, dsc.dsController = framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { - return dsc.kubeClient.Experimental().DaemonSets(api.NamespaceAll).List(labels.Everything()) + return dsc.kubeClient.Extensions().DaemonSets(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(rv string) (watch.Interface, error) { - return dsc.kubeClient.Experimental().DaemonSets(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), rv) + return dsc.kubeClient.Extensions().DaemonSets(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), rv) }, }, - &experimental.DaemonSet{}, + &extensions.DaemonSet{}, + // TODO: Can we have much longer period here? FullDaemonSetResyncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { - ds := obj.(*experimental.DaemonSet) + ds := obj.(*extensions.DaemonSet) glog.V(4).Infof("Adding daemon set %s", ds.Name) dsc.enqueueDaemonSet(obj) }, UpdateFunc: func(old, cur interface{}) { - oldDS := old.(*experimental.DaemonSet) + oldDS := old.(*extensions.DaemonSet) glog.V(4).Infof("Updating daemon set %s", oldDS.Name) dsc.enqueueDaemonSet(cur) }, DeleteFunc: func(obj interface{}) { - ds := obj.(*experimental.DaemonSet) + ds := obj.(*extensions.DaemonSet) glog.V(4).Infof("Deleting daemon set %s", ds.Name) dsc.enqueueDaemonSet(obj) }, @@ -130,7 +136,7 @@ func NewDaemonSetsController(kubeClient client.Interface) *DaemonSetsController }, }, &api.Pod{}, - FullDaemonPodResyncPeriod, + resyncPeriod(), framework.ResourceEventHandlerFuncs{ AddFunc: dsc.addPod, UpdateFunc: dsc.updatePod, @@ -148,18 +154,20 @@ func NewDaemonSetsController(kubeClient client.Interface) *DaemonSetsController }, }, &api.Node{}, - FullNodeResyncPeriod, + resyncPeriod(), framework.ResourceEventHandlerFuncs{ AddFunc: dsc.addNode, UpdateFunc: dsc.updateNode, }, ) dsc.syncHandler = dsc.syncDaemonSet + dsc.podStoreSynced = dsc.podController.HasSynced return dsc } // Run begins watching and syncing daemon sets. func (dsc *DaemonSetsController) Run(workers int, stopCh <-chan struct{}) { + defer util.HandleCrash() go dsc.dsController.Run(stopCh) go dsc.podController.Run(stopCh) go dsc.nodeController.Run(stopCh) @@ -205,20 +213,24 @@ func (dsc *DaemonSetsController) enqueueDaemonSet(obj interface{}) { glog.Errorf("Couldn't get key for object %+v: %v", obj, err) return } + + // TODO: Handle overlapping controllers better. See comment in ReplicationManager. dsc.queue.Add(key) } -func (dsc *DaemonSetsController) getPodDaemonSet(pod *api.Pod) *experimental.DaemonSet { +func (dsc *DaemonSetsController) getPodDaemonSet(pod *api.Pod) *extensions.DaemonSet { sets, err := dsc.dsStore.GetPodDaemonSets(pod) if err != nil { glog.V(4).Infof("No daemon sets found for pod %v, daemon set controller will avoid syncing", pod.Name) return nil } - // More than two items in this list indicates user error. If two daemon - // sets overlap, sort by creation timestamp, subsort by name, then pick - // the first. - glog.Errorf("user error! more than one daemon is selecting pods with labels: %+v", pod.Labels) - sort.Sort(byCreationTimestamp(sets)) + if len(sets) > 1 { + // More than two items in this list indicates user error. If two daemon + // sets overlap, sort by creation timestamp, subsort by name, then pick + // the first. + glog.Errorf("user error! more than one daemon is selecting pods with labels: %+v", pod.Labels) + sort.Sort(byCreationTimestamp(sets)) + } return &sets[0] } @@ -309,7 +321,7 @@ func (dsc *DaemonSetsController) updateNode(old, cur interface{}) { } // getNodesToDaemonSetPods returns a map from nodes to daemon pods (corresponding to ds) running on the nodes. -func (dsc *DaemonSetsController) getNodesToDaemonPods(ds *experimental.DaemonSet) (map[string][]*api.Pod, error) { +func (dsc *DaemonSetsController) getNodesToDaemonPods(ds *extensions.DaemonSet) (map[string][]*api.Pod, error) { nodeToDaemonPods := make(map[string][]*api.Pod) daemonPods, err := dsc.podStore.Pods(ds.Namespace).List(labels.Set(ds.Spec.Selector).AsSelector()) if err != nil { @@ -322,7 +334,7 @@ func (dsc *DaemonSetsController) getNodesToDaemonPods(ds *experimental.DaemonSet return nodeToDaemonPods, nil } -func (dsc *DaemonSetsController) manage(ds *experimental.DaemonSet) { +func (dsc *DaemonSetsController) manage(ds *extensions.DaemonSet) { // Find out which nodes are running the daemon pods selected by ds. nodeToDaemonPods, err := dsc.getNodesToDaemonPods(ds) if err != nil { @@ -349,7 +361,8 @@ func (dsc *DaemonSetsController) manage(ds *experimental.DaemonSet) { nodesNeedingDaemonPods = append(nodesNeedingDaemonPods, nodeName) } else if shouldRun && len(daemonPods) > 1 { // If daemon pod is supposed to be running on node, but more than 1 daemon pod is running, delete the excess daemon pods. - // TODO: sort the daemon pods by creation time, so the the oldest is preserved. + // Sort the daemon pods by creation time, so the the oldest is preserved. + sort.Sort(podByCreationTimestamp(daemonPods)) for i := 1; i < len(daemonPods); i++ { podsToDelete = append(podsToDelete, daemonPods[i].Name) } @@ -371,7 +384,7 @@ func (dsc *DaemonSetsController) manage(ds *experimental.DaemonSet) { glog.V(4).Infof("Nodes needing daemon pods for daemon set %s: %+v", ds.Name, nodesNeedingDaemonPods) for i := range nodesNeedingDaemonPods { - if err := dsc.podControl.CreateReplicaOnNode(ds.Namespace, ds, nodesNeedingDaemonPods[i]); err != nil { + if err := dsc.podControl.CreatePodsOnNode(nodesNeedingDaemonPods[i], ds.Namespace, ds.Spec.Template, ds); err != nil { glog.V(2).Infof("Failed creation, decrementing expectations for set %q/%q", ds.Namespace, ds.Name) dsc.expectations.CreationObserved(dsKey) util.HandleError(err) @@ -388,7 +401,7 @@ func (dsc *DaemonSetsController) manage(ds *experimental.DaemonSet) { } } -func storeDaemonSetStatus(dsClient client.DaemonSetInterface, ds *experimental.DaemonSet, desiredNumberScheduled, currentNumberScheduled, numberMisscheduled int) error { +func storeDaemonSetStatus(dsClient client.DaemonSetInterface, ds *extensions.DaemonSet, desiredNumberScheduled, currentNumberScheduled, numberMisscheduled int) error { if ds.Status.DesiredNumberScheduled == desiredNumberScheduled && ds.Status.CurrentNumberScheduled == currentNumberScheduled && ds.Status.NumberMisscheduled == numberMisscheduled { return nil } @@ -398,7 +411,7 @@ func storeDaemonSetStatus(dsClient client.DaemonSetInterface, ds *experimental.D ds.Status.DesiredNumberScheduled = desiredNumberScheduled ds.Status.CurrentNumberScheduled = currentNumberScheduled ds.Status.NumberMisscheduled = numberMisscheduled - _, updateErr = dsClient.Update(ds) + _, updateErr = dsClient.UpdateStatus(ds) if updateErr == nil { // successful update return nil @@ -413,8 +426,8 @@ func storeDaemonSetStatus(dsClient client.DaemonSetInterface, ds *experimental.D return updateErr } -func (dsc *DaemonSetsController) updateDaemonSetStatus(ds *experimental.DaemonSet) { - glog.Infof("Updating daemon set status") +func (dsc *DaemonSetsController) updateDaemonSetStatus(ds *extensions.DaemonSet) { + glog.V(4).Infof("Updating daemon set status") nodeToDaemonPods, err := dsc.getNodesToDaemonPods(ds) if err != nil { glog.Errorf("Error getting node to daemon pod mapping for daemon set %+v: %v", ds, err) @@ -428,21 +441,26 @@ func (dsc *DaemonSetsController) updateDaemonSetStatus(ds *experimental.DaemonSe var desiredNumberScheduled, currentNumberScheduled, numberMisscheduled int for _, node := range nodeList.Items { nodeSelector := labels.Set(ds.Spec.Template.Spec.NodeSelector).AsSelector() - shouldRun := nodeSelector.Matches(labels.Set(node.Labels)) + nameMatch := ds.Spec.Template.Name == "" || ds.Spec.Template.Name == node.Name + labelMatch := nodeSelector.Matches(labels.Set(node.Labels)) + shouldRun := nameMatch && labelMatch + numDaemonPods := len(nodeToDaemonPods[node.Name]) - if numDaemonPods > 0 { + if shouldRun && numDaemonPods > 0 { currentNumberScheduled++ } if shouldRun { desiredNumberScheduled++ - } else if numDaemonPods >= 0 { + } + + if !shouldRun && numDaemonPods > 0 { numberMisscheduled++ } } - err = storeDaemonSetStatus(dsc.kubeClient.Experimental().DaemonSets(ds.Namespace), ds, desiredNumberScheduled, currentNumberScheduled, numberMisscheduled) + err = storeDaemonSetStatus(dsc.kubeClient.Extensions().DaemonSets(ds.Namespace), ds, desiredNumberScheduled, currentNumberScheduled, numberMisscheduled) if err != nil { glog.Errorf("Error storing status for daemon set %+v: %v", ds, err) } @@ -464,7 +482,14 @@ func (dsc *DaemonSetsController) syncDaemonSet(key string) error { dsc.expectations.DeleteExpectations(key) return nil } - ds := obj.(*experimental.DaemonSet) + ds := obj.(*extensions.DaemonSet) + if !dsc.podStoreSynced() { + // Sleep so we give the pod reflector goroutine a chance to run. + time.Sleep(PodStoreSyncedPollPeriod) + glog.Infof("Waiting for pods controller to sync, requeuing ds %v", ds.Name) + dsc.enqueueDaemonSet(ds) + return nil + } // Don't process a daemon set until all its creations and deletions have been processed. // For example if daemon set foo asked for 3 new daemon pods in the previous call to manage, @@ -484,7 +509,7 @@ func (dsc *DaemonSetsController) syncDaemonSet(key string) error { } // byCreationTimestamp sorts a list by creation timestamp, using their names as a tie breaker. -type byCreationTimestamp []experimental.DaemonSet +type byCreationTimestamp []extensions.DaemonSet func (o byCreationTimestamp) Len() int { return len(o) } func (o byCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] } @@ -495,3 +520,15 @@ func (o byCreationTimestamp) Less(i, j int) bool { } return o[i].CreationTimestamp.Before(o[j].CreationTimestamp) } + +type podByCreationTimestamp []*api.Pod + +func (o podByCreationTimestamp) Len() int { return len(o) } +func (o podByCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] } + +func (o podByCreationTimestamp) Less(i, j int) bool { + if o[i].CreationTimestamp.Equal(o[j].CreationTimestamp) { + return o[i].Name < o[j].Name + } + return o[i].CreationTimestamp.Before(o[j].CreationTimestamp) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/daemon/controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/daemon/controller_test.go index 1ab55b2b72c5..56adeb531b77 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/daemon/controller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/daemon/controller_test.go @@ -18,12 +18,12 @@ package daemon import ( "fmt" - "sync" "testing" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/controller" @@ -35,57 +35,30 @@ var ( simpleDaemonSetLabel2 = map[string]string{"name": "simple-daemon", "type": "test"} simpleNodeLabel = map[string]string{"color": "blue", "speed": "fast"} simpleNodeLabel2 = map[string]string{"color": "red", "speed": "fast"} + alwaysReady = func() bool { return true } ) -type FakePodControl struct { - daemonSet []experimental.DaemonSet - deletePodName []string - lock sync.Mutex - err error -} - func init() { api.ForTesting_ReferencesAllowBlankSelfLinks = true } -func (f *FakePodControl) CreateReplica(namespace string, spec *api.ReplicationController) error { - return nil -} - -func (f *FakePodControl) CreateReplicaOnNode(namespace string, ds *experimental.DaemonSet, nodeName string) error { - f.lock.Lock() - defer f.lock.Unlock() - if f.err != nil { - return f.err - } - f.daemonSet = append(f.daemonSet, *ds) - return nil -} - -func (f *FakePodControl) DeletePod(namespace string, podName string) error { - f.lock.Lock() - defer f.lock.Unlock() - if f.err != nil { - return f.err +func getKey(ds *extensions.DaemonSet, t *testing.T) string { + if key, err := controller.KeyFunc(ds); err != nil { + t.Errorf("Unexpected error getting key for ds %v: %v", ds.Name, err) + return "" + } else { + return key } - f.deletePodName = append(f.deletePodName, podName) - return nil -} -func (f *FakePodControl) clear() { - f.lock.Lock() - defer f.lock.Unlock() - f.deletePodName = []string{} - f.daemonSet = []experimental.DaemonSet{} } -func newDaemonSet(name string) *experimental.DaemonSet { - return &experimental.DaemonSet{ - TypeMeta: api.TypeMeta{APIVersion: testapi.Experimental.Version()}, +func newDaemonSet(name string) *extensions.DaemonSet { + return &extensions.DaemonSet{ + TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Extensions.Version()}, ObjectMeta: api.ObjectMeta{ Name: name, Namespace: api.NamespaceDefault, }, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: simpleDaemonSetLabel, Template: &api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ @@ -109,7 +82,7 @@ func newDaemonSet(name string) *experimental.DaemonSet { func newNode(name string, label map[string]string) *api.Node { return &api.Node{ - TypeMeta: api.TypeMeta{APIVersion: testapi.Default.Version()}, + TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.Version()}, ObjectMeta: api.ObjectMeta{ Name: name, Labels: label, @@ -126,7 +99,7 @@ func addNodes(nodeStore cache.Store, startIndex, numNodes int, label map[string] func newPod(podName string, nodeName string, label map[string]string) *api.Pod { pod := &api.Pod{ - TypeMeta: api.TypeMeta{APIVersion: testapi.Default.Version()}, + TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.Version()}, ObjectMeta: api.ObjectMeta{ GenerateName: podName, Labels: label, @@ -155,24 +128,25 @@ func addPods(podStore cache.Store, nodeName string, label map[string]string, num } } -func newTestController() (*DaemonSetsController, *FakePodControl) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Experimental.Version()}) - manager := NewDaemonSetsController(client) - podControl := &FakePodControl{} +func newTestController() (*DaemonSetsController, *controller.FakePodControl) { + client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + manager := NewDaemonSetsController(client, controller.NoResyncPeriodFunc) + manager.podStoreSynced = alwaysReady + podControl := &controller.FakePodControl{} manager.podControl = podControl return manager, podControl } -func validateSyncDaemonSets(t *testing.T, fakePodControl *FakePodControl, expectedCreates, expectedDeletes int) { - if len(fakePodControl.daemonSet) != expectedCreates { - t.Errorf("Unexpected number of creates. Expected %d, saw %d\n", expectedCreates, len(fakePodControl.daemonSet)) +func validateSyncDaemonSets(t *testing.T, fakePodControl *controller.FakePodControl, expectedCreates, expectedDeletes int) { + if len(fakePodControl.Templates) != expectedCreates { + t.Errorf("Unexpected number of creates. Expected %d, saw %d\n", expectedCreates, len(fakePodControl.Templates)) } - if len(fakePodControl.deletePodName) != expectedDeletes { - t.Errorf("Unexpected number of deletes. Expected %d, saw %d\n", expectedDeletes, len(fakePodControl.deletePodName)) + if len(fakePodControl.DeletePodName) != expectedDeletes { + t.Errorf("Unexpected number of deletes. Expected %d, saw %d\n", expectedDeletes, len(fakePodControl.DeletePodName)) } } -func syncAndValidateDaemonSets(t *testing.T, manager *DaemonSetsController, ds *experimental.DaemonSet, podControl *FakePodControl, expectedCreates, expectedDeletes int) { +func syncAndValidateDaemonSets(t *testing.T, manager *DaemonSetsController, ds *extensions.DaemonSet, podControl *controller.FakePodControl, expectedCreates, expectedDeletes int) { key, err := controller.KeyFunc(ds) if err != nil { t.Errorf("Could not get key for daemon.") @@ -319,3 +293,25 @@ func TestInconsistentNameSelectorDaemonSetDoesNothing(t *testing.T) { manager.dsStore.Add(ds) syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0) } + +func TestDSManagerNotReady(t *testing.T) { + manager, podControl := newTestController() + manager.podStoreSynced = func() bool { return false } + addNodes(manager.nodeStore.Store, 0, 1, nil) + + // Simulates the ds reflector running before the pod reflector. We don't + // want to end up creating daemon pods in this case until the pod reflector + // has synced, so the ds manager should just requeue the ds. + ds := newDaemonSet("foo") + manager.dsStore.Add(ds) + + dsKey := getKey(ds, t) + syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0) + queueDS, _ := manager.queue.Get() + if queueDS != dsKey { + t.Fatalf("Expected to find key %v in queue, found %v", dsKey, queueDS) + } + + manager.podStoreSynced = alwaysReady + syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/deployment/deployment_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/deployment/deployment_controller.go new file mode 100644 index 000000000000..aca9f3afe2f3 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/deployment/deployment_controller.go @@ -0,0 +1,279 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 deployment + +import ( + "fmt" + "math" + "time" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/client/record" + client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/util" + deploymentUtil "k8s.io/kubernetes/pkg/util/deployment" +) + +type DeploymentController struct { + client client.Interface + expClient client.ExtensionsInterface + eventRecorder record.EventRecorder +} + +func New(client client.Interface) *DeploymentController { + eventBroadcaster := record.NewBroadcaster() + eventBroadcaster.StartLogging(glog.Infof) + eventBroadcaster.StartRecordingToSink(client.Events("")) + + return &DeploymentController{ + client: client, + expClient: client.Extensions(), + eventRecorder: eventBroadcaster.NewRecorder(api.EventSource{Component: "deployment-controller"}), + } +} + +func (d *DeploymentController) Run(syncPeriod time.Duration) { + go util.Until(func() { + errs := d.reconcileDeployments() + for _, err := range errs { + glog.Errorf("Failed to reconcile: %v", err) + } + }, syncPeriod, util.NeverStop) +} + +func (d *DeploymentController) reconcileDeployments() []error { + list, err := d.expClient.Deployments(api.NamespaceAll).List(labels.Everything(), fields.Everything()) + if err != nil { + return []error{fmt.Errorf("error listing deployments: %v", err)} + } + errs := []error{} + for _, deployment := range list.Items { + if err := d.reconcileDeployment(&deployment); err != nil { + errs = append(errs, fmt.Errorf("error in reconciling deployment %s: %v", deployment.Name, err)) + } + } + return errs +} + +func (d *DeploymentController) reconcileDeployment(deployment *extensions.Deployment) error { + switch deployment.Spec.Strategy.Type { + case extensions.RecreateDeploymentStrategyType: + return d.reconcileRecreateDeployment(*deployment) + case extensions.RollingUpdateDeploymentStrategyType: + return d.reconcileRollingUpdateDeployment(*deployment) + } + return fmt.Errorf("unexpected deployment strategy type: %s", deployment.Spec.Strategy.Type) +} + +func (d *DeploymentController) reconcileRecreateDeployment(deployment extensions.Deployment) error { + // TODO: implement me. + return nil +} + +func (d *DeploymentController) reconcileRollingUpdateDeployment(deployment extensions.Deployment) error { + newRC, err := d.getNewRC(deployment) + if err != nil { + return err + } + + oldRCs, err := d.getOldRCs(deployment) + if err != nil { + return err + } + + allRCs := append(oldRCs, newRC) + + // Scale up, if we can. + scaledUp, err := d.reconcileNewRC(allRCs, newRC, deployment) + if err != nil { + return err + } + if scaledUp { + // Update DeploymentStatus + return d.updateDeploymentStatus(allRCs, newRC, deployment) + } + + // Scale down, if we can. + scaledDown, err := d.reconcileOldRCs(allRCs, oldRCs, newRC, deployment) + if err != nil { + return err + } + if scaledDown { + // Update DeploymentStatus + return d.updateDeploymentStatus(allRCs, newRC, deployment) + } + // TODO: raise an event, neither scaled up nor down. + return nil +} + +func (d *DeploymentController) getOldRCs(deployment extensions.Deployment) ([]*api.ReplicationController, error) { + return deploymentUtil.GetOldRCs(deployment, d.client) +} + +// Returns an RC that matches the intent of the given deployment. +// It creates a new RC if required. +func (d *DeploymentController) getNewRC(deployment extensions.Deployment) (*api.ReplicationController, error) { + existingNewRC, err := deploymentUtil.GetNewRC(deployment, d.client) + if err != nil || existingNewRC != nil { + return existingNewRC, err + } + // new RC does not exist, create one. + namespace := deployment.ObjectMeta.Namespace + podTemplateSpecHash := deploymentUtil.GetPodTemplateSpecHash(deployment.Spec.Template) + rcName := fmt.Sprintf("deploymentrc-%d", podTemplateSpecHash) + newRCTemplate := deploymentUtil.GetNewRCTemplate(deployment) + // Add podTemplateHash label to selector. + newRCSelector := deploymentUtil.CloneAndAddLabel(deployment.Spec.Selector, deployment.Spec.UniqueLabelKey, podTemplateSpecHash) + + newRC := api.ReplicationController{ + ObjectMeta: api.ObjectMeta{ + Name: rcName, + Namespace: namespace, + }, + Spec: api.ReplicationControllerSpec{ + Replicas: 0, + Selector: newRCSelector, + Template: newRCTemplate, + }, + } + createdRC, err := d.client.ReplicationControllers(namespace).Create(&newRC) + if err != nil { + return nil, fmt.Errorf("error creating replication controller: %v", err) + } + return createdRC, nil +} + +func (d *DeploymentController) reconcileNewRC(allRCs []*api.ReplicationController, newRC *api.ReplicationController, deployment extensions.Deployment) (bool, error) { + if newRC.Spec.Replicas == deployment.Spec.Replicas { + // Scaling not required. + return false, nil + } + if newRC.Spec.Replicas > deployment.Spec.Replicas { + // Scale down. + _, err := d.scaleRCAndRecordEvent(newRC, deployment.Spec.Replicas, deployment) + return true, err + } + // Check if we can scale up. + maxSurge, isPercent, err := util.GetIntOrPercentValue(&deployment.Spec.Strategy.RollingUpdate.MaxSurge) + if err != nil { + return false, fmt.Errorf("invalid value for MaxSurge: %v", err) + } + if isPercent { + maxSurge = util.GetValueFromPercent(maxSurge, deployment.Spec.Replicas) + } + // Find the total number of pods + currentPodCount := deploymentUtil.GetReplicaCountForRCs(allRCs) + maxTotalPods := deployment.Spec.Replicas + maxSurge + if currentPodCount >= maxTotalPods { + // Cannot scale up. + return false, nil + } + // Scale up. + scaleUpCount := maxTotalPods - currentPodCount + // Do not exceed the number of desired replicas. + scaleUpCount = int(math.Min(float64(scaleUpCount), float64(deployment.Spec.Replicas-newRC.Spec.Replicas))) + newReplicasCount := newRC.Spec.Replicas + scaleUpCount + _, err = d.scaleRCAndRecordEvent(newRC, newReplicasCount, deployment) + return true, err +} + +func (d *DeploymentController) reconcileOldRCs(allRCs []*api.ReplicationController, oldRCs []*api.ReplicationController, newRC *api.ReplicationController, deployment extensions.Deployment) (bool, error) { + oldPodsCount := deploymentUtil.GetReplicaCountForRCs(oldRCs) + if oldPodsCount == 0 { + // Cant scale down further + return false, nil + } + maxUnavailable, isPercent, err := util.GetIntOrPercentValue(&deployment.Spec.Strategy.RollingUpdate.MaxUnavailable) + if err != nil { + return false, fmt.Errorf("invalid value for MaxUnavailable: %v", err) + } + if isPercent { + maxUnavailable = util.GetValueFromPercent(maxUnavailable, deployment.Spec.Replicas) + } + // Check if we can scale down. + minAvailable := deployment.Spec.Replicas - maxUnavailable + // Find the number of ready pods. + readyPodCount, err := deploymentUtil.GetAvailablePodsForRCs(d.client, allRCs) + if err != nil { + return false, fmt.Errorf("could not find available pods: %v", err) + } + + if readyPodCount <= minAvailable { + // Cannot scale down. + return false, nil + } + totalScaleDownCount := readyPodCount - minAvailable + for _, targetRC := range oldRCs { + if totalScaleDownCount == 0 { + // No further scaling required. + break + } + if targetRC.Spec.Replicas == 0 { + // cannot scale down this RC. + continue + } + // Scale down. + scaleDownCount := int(math.Min(float64(targetRC.Spec.Replicas), float64(totalScaleDownCount))) + newReplicasCount := targetRC.Spec.Replicas - scaleDownCount + _, err = d.scaleRCAndRecordEvent(targetRC, newReplicasCount, deployment) + if err != nil { + return false, err + } + totalScaleDownCount -= scaleDownCount + } + return true, err +} + +func (d *DeploymentController) updateDeploymentStatus(allRCs []*api.ReplicationController, newRC *api.ReplicationController, deployment extensions.Deployment) error { + totalReplicas := deploymentUtil.GetReplicaCountForRCs(allRCs) + updatedReplicas := deploymentUtil.GetReplicaCountForRCs([]*api.ReplicationController{newRC}) + newDeployment := deployment + // TODO: Reconcile this with API definition. API definition talks about ready pods, while this just computes created pods. + newDeployment.Status = extensions.DeploymentStatus{ + Replicas: totalReplicas, + UpdatedReplicas: updatedReplicas, + } + _, err := d.updateDeployment(&newDeployment) + return err +} + +func (d *DeploymentController) scaleRCAndRecordEvent(rc *api.ReplicationController, newScale int, deployment extensions.Deployment) (*api.ReplicationController, error) { + scalingOperation := "down" + if rc.Spec.Replicas < newScale { + scalingOperation = "up" + } + newRC, err := d.scaleRC(rc, newScale) + if err == nil { + d.eventRecorder.Eventf(&deployment, "ScalingRC", "Scaled %s rc %s to %d", scalingOperation, rc.Name, newScale) + } + return newRC, err +} + +func (d *DeploymentController) scaleRC(rc *api.ReplicationController, newScale int) (*api.ReplicationController, error) { + // TODO: Using client for now, update to use store when it is ready. + rc.Spec.Replicas = newScale + return d.client.ReplicationControllers(rc.ObjectMeta.Namespace).Update(rc) +} + +func (d *DeploymentController) updateDeployment(deployment *extensions.Deployment) (*extensions.Deployment, error) { + // TODO: Using client for now, update to use store when it is ready. + return d.client.Extensions().Deployments(deployment.ObjectMeta.Namespace).Update(deployment) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/deployment/deployment_controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/deployment/deployment_controller_test.go new file mode 100644 index 000000000000..e1359f00e208 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/deployment/deployment_controller_test.go @@ -0,0 +1,260 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 deployment + +import ( + "fmt" + "testing" + + "k8s.io/kubernetes/pkg/api" + exp "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/client/record" + "k8s.io/kubernetes/pkg/client/unversioned/testclient" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util" +) + +func TestDeploymentController_reconcileNewRC(t *testing.T) { + tests := []struct { + deploymentReplicas int + maxSurge util.IntOrString + oldReplicas int + newReplicas int + scaleExpected bool + expectedNewReplicas int + }{ + { + // Should not scale up. + deploymentReplicas: 10, + maxSurge: util.NewIntOrStringFromInt(0), + oldReplicas: 10, + newReplicas: 0, + scaleExpected: false, + }, + { + deploymentReplicas: 10, + maxSurge: util.NewIntOrStringFromInt(2), + oldReplicas: 10, + newReplicas: 0, + scaleExpected: true, + expectedNewReplicas: 2, + }, + { + deploymentReplicas: 10, + maxSurge: util.NewIntOrStringFromInt(2), + oldReplicas: 5, + newReplicas: 0, + scaleExpected: true, + expectedNewReplicas: 7, + }, + { + deploymentReplicas: 10, + maxSurge: util.NewIntOrStringFromInt(2), + oldReplicas: 10, + newReplicas: 2, + scaleExpected: false, + }, + { + // Should scale down. + deploymentReplicas: 10, + maxSurge: util.NewIntOrStringFromInt(2), + oldReplicas: 2, + newReplicas: 11, + scaleExpected: true, + expectedNewReplicas: 10, + }, + } + + for i, test := range tests { + t.Logf("executing scenario %d", i) + newRc := rc("foo-v2", test.newReplicas) + oldRc := rc("foo-v2", test.oldReplicas) + allRcs := []*api.ReplicationController{newRc, oldRc} + deployment := deployment("foo", test.deploymentReplicas, test.maxSurge, util.NewIntOrStringFromInt(0)) + fake := &testclient.Fake{} + controller := &DeploymentController{ + client: fake, + eventRecorder: &record.FakeRecorder{}, + } + scaled, err := controller.reconcileNewRC(allRcs, newRc, deployment) + if err != nil { + t.Errorf("unexpected error: %v", err) + continue + } + if !test.scaleExpected { + if scaled || len(fake.Actions()) > 0 { + t.Errorf("unexpected scaling: %v", fake.Actions()) + } + continue + } + if test.scaleExpected && !scaled { + t.Errorf("expected scaling to occur") + continue + } + if len(fake.Actions()) != 1 { + t.Errorf("expected 1 action during scale, got: %v", fake.Actions()) + continue + } + updated := fake.Actions()[0].(testclient.UpdateAction).GetObject().(*api.ReplicationController) + if e, a := test.expectedNewReplicas, updated.Spec.Replicas; e != a { + t.Errorf("expected update to %d replicas, got %d", e, a) + } + } +} + +func TestDeploymentController_reconcileOldRCs(t *testing.T) { + tests := []struct { + deploymentReplicas int + maxUnavailable util.IntOrString + readyPods int + oldReplicas int + scaleExpected bool + expectedOldReplicas int + }{ + { + deploymentReplicas: 10, + maxUnavailable: util.NewIntOrStringFromInt(0), + readyPods: 10, + oldReplicas: 10, + scaleExpected: false, + }, + { + deploymentReplicas: 10, + maxUnavailable: util.NewIntOrStringFromInt(2), + readyPods: 10, + oldReplicas: 10, + scaleExpected: true, + expectedOldReplicas: 8, + }, + { + deploymentReplicas: 10, + maxUnavailable: util.NewIntOrStringFromInt(2), + readyPods: 8, + oldReplicas: 10, + scaleExpected: false, + }, + { + deploymentReplicas: 10, + maxUnavailable: util.NewIntOrStringFromInt(2), + readyPods: 10, + oldReplicas: 0, + scaleExpected: false, + }, + } + + for i, test := range tests { + t.Logf("executing scenario %d", i) + oldRc := rc("foo-v2", test.oldReplicas) + allRcs := []*api.ReplicationController{oldRc} + oldRcs := []*api.ReplicationController{oldRc} + deployment := deployment("foo", test.deploymentReplicas, util.NewIntOrStringFromInt(0), test.maxUnavailable) + fake := &testclient.Fake{} + fake.AddReactor("list", "pods", func(action testclient.Action) (handled bool, ret runtime.Object, err error) { + switch action.(type) { + case testclient.ListAction: + podList := &api.PodList{} + for podIndex := 0; podIndex < test.readyPods; podIndex++ { + podList.Items = append(podList.Items, api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: fmt.Sprintf("%s-pod-%d", oldRc.Name, podIndex), + }, + Status: api.PodStatus{ + Conditions: []api.PodCondition{ + { + Type: api.PodReady, + Status: api.ConditionTrue, + }, + }, + }, + }) + } + return true, podList, nil + } + return false, nil, nil + }) + controller := &DeploymentController{ + client: fake, + eventRecorder: &record.FakeRecorder{}, + } + scaled, err := controller.reconcileOldRCs(allRcs, oldRcs, nil, deployment) + if err != nil { + t.Errorf("unexpected error: %v", err) + continue + } + if !test.scaleExpected { + if scaled { + t.Errorf("unexpected scaling: %v", fake.Actions()) + } + continue + } + if test.scaleExpected && !scaled { + t.Errorf("expected scaling to occur; actions: %v", fake.Actions()) + continue + } + // There are both list and update actions logged, so extract the update + // action for verification. + var updateAction testclient.UpdateAction + for _, action := range fake.Actions() { + switch a := action.(type) { + case testclient.UpdateAction: + if updateAction != nil { + t.Errorf("expected only 1 update action; had %v and found %v", updateAction, a) + } else { + updateAction = a + } + } + } + if updateAction == nil { + t.Errorf("expected an update action") + continue + } + updated := updateAction.GetObject().(*api.ReplicationController) + if e, a := test.expectedOldReplicas, updated.Spec.Replicas; e != a { + t.Errorf("expected update to %d replicas, got %d", e, a) + } + } +} + +func rc(name string, replicas int) *api.ReplicationController { + return &api.ReplicationController{ + ObjectMeta: api.ObjectMeta{ + Name: name, + }, + Spec: api.ReplicationControllerSpec{ + Replicas: replicas, + Template: &api.PodTemplateSpec{}, + }, + } +} + +func deployment(name string, replicas int, maxSurge, maxUnavailable util.IntOrString) exp.Deployment { + return exp.Deployment{ + ObjectMeta: api.ObjectMeta{ + Name: name, + }, + Spec: exp.DeploymentSpec{ + Replicas: replicas, + Strategy: exp.DeploymentStrategy{ + Type: exp.RollingUpdateDeploymentStrategyType, + RollingUpdate: &exp.RollingUpdateDeployment{ + MaxSurge: maxSurge, + MaxUnavailable: maxUnavailable, + }, + }, + }, + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/doc.go index 058b1643a6b5..c51ec65183be 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/doc.go @@ -16,4 +16,4 @@ limitations under the License. // Package service provides EndpointController implementation // to manage and sync service endpoints. -package endpointcontroller +package endpoint diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/endpoints_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/endpoints_controller.go index ab06f869a517..35d7550730fe 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/endpoints_controller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/endpoints_controller.go @@ -16,7 +16,7 @@ limitations under the License. // CAUTION: If you update code in this file, you may need to also update code // in contrib/mesos/pkg/service/endpoints_controller.go -package endpointcontroller +package endpoint import ( "fmt" @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller/framework" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -45,11 +46,6 @@ const ( // often. Higher numbers = lower CPU/network load; lower numbers = // shorter amount of time before a mistaken endpoint is corrected. FullServiceResyncPeriod = 30 * time.Second - - // We'll keep pod watches open up to this long. In the unlikely case - // that a watch misdelivers info about a pod, it'll take this long for - // that mistake to be rectified. - PodRelistPeriod = 5 * time.Minute ) var ( @@ -57,7 +53,7 @@ var ( ) // NewEndpointController returns a new *EndpointController. -func NewEndpointController(client *client.Client) *EndpointController { +func NewEndpointController(client *client.Client, resyncPeriod controller.ResyncPeriodFunc) *EndpointController { e := &EndpointController{ client: client, queue: workqueue.New(), @@ -66,13 +62,14 @@ func NewEndpointController(client *client.Client) *EndpointController { e.serviceStore.Store, e.serviceController = framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { - return e.client.Services(api.NamespaceAll).List(labels.Everything()) + return e.client.Services(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(rv string) (watch.Interface, error) { return e.client.Services(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), rv) }, }, &api.Service{}, + // TODO: Can we have much longer period here? FullServiceResyncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: e.enqueueService, @@ -93,7 +90,7 @@ func NewEndpointController(client *client.Client) *EndpointController { }, }, &api.Pod{}, - PodRelistPeriod, + resyncPeriod(), framework.ResourceEventHandlerFuncs{ AddFunc: e.addPod, UpdateFunc: e.updatePod, @@ -319,11 +316,6 @@ func (e *EndpointController) syncService(key string) { continue } - if !api.IsPodReady(pod) { - glog.V(5).Infof("Pod is out of service: %v/%v", pod.Namespace, pod.Name) - continue - } - epp := api.EndpointPort{Name: portName, Port: portNum, Protocol: portProto} epa := api.EndpointAddress{IP: pod.Status.PodIP, TargetRef: &api.ObjectReference{ Kind: "Pod", @@ -332,7 +324,18 @@ func (e *EndpointController) syncService(key string) { UID: pod.ObjectMeta.UID, ResourceVersion: pod.ObjectMeta.ResourceVersion, }} - subsets = append(subsets, api.EndpointSubset{Addresses: []api.EndpointAddress{epa}, Ports: []api.EndpointPort{epp}}) + if api.IsPodReady(pod) { + subsets = append(subsets, api.EndpointSubset{ + Addresses: []api.EndpointAddress{epa}, + Ports: []api.EndpointPort{epp}, + }) + } else { + glog.V(5).Infof("Pod is out of service: %v/%v", pod.Namespace, pod.Name) + subsets = append(subsets, api.EndpointSubset{ + NotReadyAddresses: []api.EndpointAddress{epa}, + Ports: []api.EndpointPort{epp}, + }) + } } } subsets = endpoints.RepackSubsets(subsets) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/endpoints_controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/endpoints_controller_test.go index 9fb4e1bae559..40d22993514d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/endpoints_controller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/endpoint/endpoints_controller_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package endpointcontroller +package endpoint import ( "fmt" @@ -26,16 +26,18 @@ import ( endptspkg "k8s.io/kubernetes/pkg/api/endpoints" _ "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" ) -func addPods(store cache.Store, namespace string, nPods int, nPorts int) { - for i := 0; i < nPods; i++ { +func addPods(store cache.Store, namespace string, nPods int, nPorts int, nNotReady int) { + for i := 0; i < nPods+nNotReady; i++ { p := &api.Pod{ - TypeMeta: api.TypeMeta{APIVersion: testapi.Default.Version()}, + TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.Version()}, ObjectMeta: api.ObjectMeta{ Namespace: namespace, Name: fmt.Sprintf("pod%d", i), @@ -54,6 +56,9 @@ func addPods(store cache.Store, namespace string, nPods int, nPorts int) { }, }, } + if i >= nPods { + p.Status.Conditions[0].Status = api.ConditionFalse + } for j := 0; j < nPorts; j++ { p.Spec.Containers[0].Ports = append(p.Spec.Containers[0].Ports, api.ContainerPort{Name: fmt.Sprintf("port%d", i), ContainerPort: 8080 + j}) @@ -184,7 +189,7 @@ func TestSyncEndpointsItemsPreserveNoSelector(t *testing.T) { }}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - endpoints := NewEndpointController(client) + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: ns}, Spec: api.ServiceSpec{Ports: []api.ServicePort{{Port: 80}}}, @@ -199,7 +204,7 @@ func TestCheckLeftoverEndpoints(t *testing.T) { // below. testServer, _ := makeTestServer(t, api.NamespaceAll, serverResponse{http.StatusOK, &api.EndpointsList{ - ListMeta: api.ListMeta{ + ListMeta: unversioned.ListMeta{ ResourceVersion: "1", }, Items: []api.Endpoints{{ @@ -216,7 +221,7 @@ func TestCheckLeftoverEndpoints(t *testing.T) { }}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - endpoints := NewEndpointController(client) + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) endpoints.checkLeftoverEndpoints() if e, a := 1, endpoints.queue.Len(); e != a { @@ -244,7 +249,7 @@ func TestSyncEndpointsProtocolTCP(t *testing.T) { }}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - endpoints := NewEndpointController(client) + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: ns}, Spec: api.ServiceSpec{ @@ -272,7 +277,7 @@ func TestSyncEndpointsProtocolUDP(t *testing.T) { }}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - endpoints := NewEndpointController(client) + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: ns}, Spec: api.ServiceSpec{ @@ -297,8 +302,8 @@ func TestSyncEndpointsItemsEmptySelectorSelectsAll(t *testing.T) { }}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - endpoints := NewEndpointController(client) - addPods(endpoints.podStore.Store, ns, 1, 1) + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) + addPods(endpoints.podStore.Store, ns, 1, 1, 0) endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: ns}, Spec: api.ServiceSpec{ @@ -321,6 +326,81 @@ func TestSyncEndpointsItemsEmptySelectorSelectsAll(t *testing.T) { endpointsHandler.ValidateRequest(t, testapi.Default.ResourcePath("endpoints", ns, "foo"), "PUT", &data) } +func TestSyncEndpointsItemsEmptySelectorSelectsAllNotReady(t *testing.T) { + ns := "other" + testServer, endpointsHandler := makeTestServer(t, ns, + serverResponse{http.StatusOK, &api.Endpoints{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: ns, + ResourceVersion: "1", + }, + Subsets: []api.EndpointSubset{}, + }}) + defer testServer.Close() + client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) + addPods(endpoints.podStore.Store, ns, 0, 1, 1) + endpoints.serviceStore.Store.Add(&api.Service{ + ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: ns}, + Spec: api.ServiceSpec{ + Selector: map[string]string{}, + Ports: []api.ServicePort{{Port: 80, Protocol: "TCP", TargetPort: util.NewIntOrStringFromInt(8080)}}, + }, + }) + endpoints.syncService(ns + "/foo") + data := runtime.EncodeOrDie(testapi.Default.Codec(), &api.Endpoints{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: ns, + ResourceVersion: "1", + }, + Subsets: []api.EndpointSubset{{ + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: &api.ObjectReference{Kind: "Pod", Name: "pod0", Namespace: ns}}}, + Ports: []api.EndpointPort{{Port: 8080, Protocol: "TCP"}}, + }}, + }) + endpointsHandler.ValidateRequest(t, testapi.Default.ResourcePath("endpoints", ns, "foo"), "PUT", &data) +} + +func TestSyncEndpointsItemsEmptySelectorSelectsAllMixed(t *testing.T) { + ns := "other" + testServer, endpointsHandler := makeTestServer(t, ns, + serverResponse{http.StatusOK, &api.Endpoints{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: ns, + ResourceVersion: "1", + }, + Subsets: []api.EndpointSubset{}, + }}) + defer testServer.Close() + client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) + addPods(endpoints.podStore.Store, ns, 1, 1, 1) + endpoints.serviceStore.Store.Add(&api.Service{ + ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: ns}, + Spec: api.ServiceSpec{ + Selector: map[string]string{}, + Ports: []api.ServicePort{{Port: 80, Protocol: "TCP", TargetPort: util.NewIntOrStringFromInt(8080)}}, + }, + }) + endpoints.syncService(ns + "/foo") + data := runtime.EncodeOrDie(testapi.Default.Codec(), &api.Endpoints{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: ns, + ResourceVersion: "1", + }, + Subsets: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: &api.ObjectReference{Kind: "Pod", Name: "pod0", Namespace: ns}}}, + NotReadyAddresses: []api.EndpointAddress{{IP: "1.2.3.5", TargetRef: &api.ObjectReference{Kind: "Pod", Name: "pod1", Namespace: ns}}}, + Ports: []api.EndpointPort{{Port: 8080, Protocol: "TCP"}}, + }}, + }) + endpointsHandler.ValidateRequest(t, testapi.Default.ResourcePath("endpoints", ns, "foo"), "PUT", &data) +} + func TestSyncEndpointsItemsPreexisting(t *testing.T) { ns := "bar" testServer, endpointsHandler := makeTestServer(t, ns, @@ -337,8 +417,8 @@ func TestSyncEndpointsItemsPreexisting(t *testing.T) { }}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - endpoints := NewEndpointController(client) - addPods(endpoints.podStore.Store, ns, 1, 1) + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) + addPods(endpoints.podStore.Store, ns, 1, 1, 0) endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: ns}, Spec: api.ServiceSpec{ @@ -377,8 +457,8 @@ func TestSyncEndpointsItemsPreexistingIdentical(t *testing.T) { }}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - endpoints := NewEndpointController(client) - addPods(endpoints.podStore.Store, api.NamespaceDefault, 1, 1) + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) + addPods(endpoints.podStore.Store, api.NamespaceDefault, 1, 1, 0) endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault}, Spec: api.ServiceSpec{ @@ -396,9 +476,9 @@ func TestSyncEndpointsItems(t *testing.T) { serverResponse{http.StatusOK, &api.Endpoints{}}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - endpoints := NewEndpointController(client) - addPods(endpoints.podStore.Store, ns, 3, 2) - addPods(endpoints.podStore.Store, "blah", 5, 2) // make sure these aren't found! + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) + addPods(endpoints.podStore.Store, ns, 3, 2, 0) + addPods(endpoints.podStore.Store, "blah", 5, 2, 0) // make sure these aren't found! endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: ns}, Spec: api.ServiceSpec{ @@ -438,8 +518,8 @@ func TestSyncEndpointsItemsWithLabels(t *testing.T) { serverResponse{http.StatusOK, &api.Endpoints{}}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - endpoints := NewEndpointController(client) - addPods(endpoints.podStore.Store, ns, 3, 2) + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) + addPods(endpoints.podStore.Store, ns, 3, 2, 0) serviceLabels := map[string]string{"foo": "bar"} endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{ @@ -498,8 +578,8 @@ func TestSyncEndpointsItemsPreexistingLabelsChange(t *testing.T) { }}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - endpoints := NewEndpointController(client) - addPods(endpoints.podStore.Store, ns, 1, 1) + endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) + addPods(endpoints.podStore.Store, ns, 1, 1, 0) serviceLabels := map[string]string{"baz": "blah"} endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/framework/controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/framework/controller_test.go index 7adc169b30d1..d5fb51871fe1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/framework/controller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/framework/controller_test.go @@ -133,7 +133,7 @@ func ExampleInformer() { time.Millisecond*100, framework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { - source.DeleteDropWatch(obj.(runtime.Object)) + source.Delete(obj.(runtime.Object)) }, DeleteFunc: func(obj interface{}) { key, err := framework.DeletionHandlingMetaNamespaceKeyFunc(obj) @@ -327,7 +327,7 @@ func TestUpdate(t *testing.T) { if !allowedTransitions[pair{from, to}] { t.Errorf("observed transition %q -> %q for %v", from, to, n.Name) } - source.DeleteDropWatch(n) + source.Delete(n) }, DeleteFunc: func(obj interface{}) { testDoneWG.Done() @@ -384,7 +384,7 @@ func TestUpdate(t *testing.T) { go func(name string, f func(string)) { defer wg.Done() f(name) - }(fmt.Sprintf("%d-%d", i, j), f) + }(fmt.Sprintf("%v-%v", i, j), f) } } wg.Wait() diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/framework/fake_controller_source.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/framework/fake_controller_source.go index e590e231f982..d4b99bd096dc 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/framework/fake_controller_source.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/framework/fake_controller_source.go @@ -37,7 +37,7 @@ func NewFakeControllerSource() *FakeControllerSource { // FakeControllerSource implements listing/watching for testing. type FakeControllerSource struct { - sync.RWMutex + lock sync.RWMutex items map[nnu]runtime.Object changes []watch.Event // one change per resourceVersion broadcaster *watch.Broadcaster @@ -95,8 +95,8 @@ func (f *FakeControllerSource) key(meta *api.ObjectMeta) nnu { // Change records the given event (setting the object's resource version) and // sends a watch event with the specified probability. func (f *FakeControllerSource) Change(e watch.Event, watchProbability float64) { - f.Lock() - defer f.Unlock() + f.lock.Lock() + defer f.lock.Unlock() objMeta, err := api.ObjectMetaFor(e.Object) if err != nil { @@ -121,8 +121,8 @@ func (f *FakeControllerSource) Change(e watch.Event, watchProbability float64) { // List returns a list object, with its resource version set. func (f *FakeControllerSource) List() (runtime.Object, error) { - f.RLock() - defer f.RUnlock() + f.lock.RLock() + defer f.lock.RUnlock() list := make([]runtime.Object, 0, len(f.items)) for _, obj := range f.items { // Must make a copy to allow clients to modify the object. @@ -151,8 +151,8 @@ func (f *FakeControllerSource) List() (runtime.Object, error) { // Watch returns a watch, which will be pre-populated with all changes // after resourceVersion. func (f *FakeControllerSource) Watch(resourceVersion string) (watch.Interface, error) { - f.RLock() - defer f.RUnlock() + f.lock.RLock() + defer f.lock.RUnlock() rc, err := strconv.Atoi(resourceVersion) if err != nil { return nil, err diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/doc.go new file mode 100644 index 000000000000..db08e7a36da7 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 gc contains a very simple pod "garbage collector" implementation, +// GCController, that runs in the controller manager. If the number of pods +// in terminated phases (right now either Failed or Succeeded) surpasses a +// configurable threshold, the controller will delete pods in terminated state +// until the system reaches the allowed threshold again. The GCController +// prioritizes pods to delete by sorting by creation timestamp and deleting the +// oldest objects first. The GCController will not delete non-terminated pods. +package gc diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/gc_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/gc_controller.go new file mode 100644 index 000000000000..ea15d29279d5 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/gc_controller.go @@ -0,0 +1,135 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 gc + +import ( + "sort" + "sync" + "time" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/cache" + "k8s.io/kubernetes/pkg/client/record" + client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/controller" + "k8s.io/kubernetes/pkg/controller/framework" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/watch" + + "github.com/golang/glog" +) + +const ( + gcCheckPeriod = 20 * time.Second +) + +type GCController struct { + kubeClient client.Interface + podStore cache.StoreToPodLister + podStoreSyncer *framework.Controller + deletePod func(namespace, name string) error + threshold int +} + +func New(kubeClient client.Interface, resyncPeriod controller.ResyncPeriodFunc, threshold int) *GCController { + eventBroadcaster := record.NewBroadcaster() + eventBroadcaster.StartLogging(glog.Infof) + eventBroadcaster.StartRecordingToSink(kubeClient.Events("")) + + gcc := &GCController{ + kubeClient: kubeClient, + threshold: threshold, + deletePod: func(namespace, name string) error { + return kubeClient.Pods(namespace).Delete(name, api.NewDeleteOptions(0)) + }, + } + + terminatedSelector := compileTerminatedPodSelector() + + gcc.podStore.Store, gcc.podStoreSyncer = framework.NewInformer( + &cache.ListWatch{ + ListFunc: func() (runtime.Object, error) { + return gcc.kubeClient.Pods(api.NamespaceAll).List(labels.Everything(), terminatedSelector) + }, + WatchFunc: func(rv string) (watch.Interface, error) { + return gcc.kubeClient.Pods(api.NamespaceAll).Watch(labels.Everything(), terminatedSelector, rv) + }, + }, + &api.Pod{}, + resyncPeriod(), + framework.ResourceEventHandlerFuncs{}, + ) + return gcc +} + +func (gcc *GCController) Run(stop <-chan struct{}) { + go gcc.podStoreSyncer.Run(stop) + go util.Until(gcc.gc, gcCheckPeriod, stop) + <-stop +} + +func (gcc *GCController) gc() { + terminatedPods, _ := gcc.podStore.List(labels.Everything()) + terminatedPodCount := len(terminatedPods) + sort.Sort(byCreationTimestamp(terminatedPods)) + + deleteCount := terminatedPodCount - gcc.threshold + + if deleteCount > terminatedPodCount { + deleteCount = terminatedPodCount + } + if deleteCount > 0 { + glog.Infof("garbage collecting %v pods", deleteCount) + } + + var wait sync.WaitGroup + for i := 0; i < deleteCount; i++ { + wait.Add(1) + go func(namespace string, name string) { + defer wait.Done() + if err := gcc.deletePod(namespace, name); err != nil { + // ignore not founds + defer util.HandleError(err) + } + }(terminatedPods[i].Namespace, terminatedPods[i].Name) + } + wait.Wait() +} + +func compileTerminatedPodSelector() fields.Selector { + selector, err := fields.ParseSelector("status.phase!=" + string(api.PodPending) + ",status.phase!=" + string(api.PodRunning) + ",status.phase!=" + string(api.PodUnknown)) + if err != nil { + panic("terminatedSelector must compile: " + err.Error()) + } + return selector +} + +// byCreationTimestamp sorts a list by creation timestamp, using their names as a tie breaker. +type byCreationTimestamp []*api.Pod + +func (o byCreationTimestamp) Len() int { return len(o) } +func (o byCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] } + +func (o byCreationTimestamp) Less(i, j int) bool { + if o[i].CreationTimestamp.Equal(o[j].CreationTimestamp) { + return o[i].Name < o[j].Name + } + return o[i].CreationTimestamp.Before(o[j].CreationTimestamp) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/gc_controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/gc_controller_test.go new file mode 100644 index 000000000000..a935881910af --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/gc/gc_controller_test.go @@ -0,0 +1,108 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 gc + +import ( + "sync" + "testing" + "time" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/testclient" + "k8s.io/kubernetes/pkg/controller" + "k8s.io/kubernetes/pkg/util/sets" +) + +func TestGC(t *testing.T) { + type nameToPhase struct { + name string + phase api.PodPhase + } + + testCases := []struct { + pods []nameToPhase + threshold int + deletedPodNames sets.String + }{ + { + pods: []nameToPhase{ + {name: "a", phase: api.PodFailed}, + {name: "b", phase: api.PodSucceeded}, + }, + threshold: 0, + deletedPodNames: sets.NewString("a", "b"), + }, + { + pods: []nameToPhase{ + {name: "a", phase: api.PodFailed}, + {name: "b", phase: api.PodSucceeded}, + }, + threshold: 1, + deletedPodNames: sets.NewString("a"), + }, + { + pods: []nameToPhase{ + {name: "a", phase: api.PodFailed}, + {name: "b", phase: api.PodSucceeded}, + }, + threshold: 5, + deletedPodNames: sets.NewString(), + }, + } + + for i, test := range testCases { + client := testclient.NewSimpleFake() + gcc := New(client, controller.NoResyncPeriodFunc, test.threshold) + deletedPodNames := make([]string, 0) + var lock sync.Mutex + gcc.deletePod = func(_, name string) error { + lock.Lock() + defer lock.Unlock() + deletedPodNames = append(deletedPodNames, name) + return nil + } + + creationTime := time.Unix(0, 0) + for _, pod := range test.pods { + creationTime = creationTime.Add(1 * time.Hour) + gcc.podStore.Store.Add(&api.Pod{ + ObjectMeta: api.ObjectMeta{Name: pod.name, CreationTimestamp: unversioned.Time{creationTime}}, + Status: api.PodStatus{Phase: pod.phase}, + }) + } + + gcc.gc() + + pass := true + for _, pod := range deletedPodNames { + if !test.deletedPodNames.Has(pod) { + pass = false + } + } + if len(deletedPodNames) != len(test.deletedPodNames) { + pass = false + } + if !pass { + t.Errorf("[%v]pod's deleted expected and actual did not match.\n\texpected: %v\n\tactual: %v", i, test.deletedPodNames, deletedPodNames) + } + } +} + +func TestTerminatedPodSelectorCompiles(t *testing.T) { + compileTerminatedPodSelector() +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/job/controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/job/controller.go new file mode 100644 index 000000000000..f2f702c30850 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/job/controller.go @@ -0,0 +1,469 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 job + +import ( + "reflect" + "sort" + "sync" + "time" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/client/cache" + "k8s.io/kubernetes/pkg/client/record" + client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/controller" + "k8s.io/kubernetes/pkg/controller/framework" + replicationcontroller "k8s.io/kubernetes/pkg/controller/replication" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/workqueue" + "k8s.io/kubernetes/pkg/watch" +) + +type JobController struct { + kubeClient client.Interface + podControl controller.PodControlInterface + + // To allow injection of updateJobStatus for testing. + updateHandler func(job *extensions.Job) error + syncHandler func(jobKey string) error + // podStoreSynced returns true if the pod store has been synced at least once. + // Added as a member to the struct to allow injection for testing. + podStoreSynced func() bool + + // A TTLCache of pod creates/deletes each rc expects to see + expectations controller.ControllerExpectationsInterface + + // A store of job, populated by the jobController + jobStore cache.StoreToJobLister + // Watches changes to all jobs + jobController *framework.Controller + + // A store of pods, populated by the podController + podStore cache.StoreToPodLister + // Watches changes to all pods + podController *framework.Controller + + // Jobs that need to be updated + queue *workqueue.Type +} + +func NewJobController(kubeClient client.Interface, resyncPeriod controller.ResyncPeriodFunc) *JobController { + eventBroadcaster := record.NewBroadcaster() + eventBroadcaster.StartLogging(glog.Infof) + eventBroadcaster.StartRecordingToSink(kubeClient.Events("")) + + jm := &JobController{ + kubeClient: kubeClient, + podControl: controller.RealPodControl{ + KubeClient: kubeClient, + Recorder: eventBroadcaster.NewRecorder(api.EventSource{Component: "job"}), + }, + expectations: controller.NewControllerExpectations(), + queue: workqueue.New(), + } + + jm.jobStore.Store, jm.jobController = framework.NewInformer( + &cache.ListWatch{ + ListFunc: func() (runtime.Object, error) { + return jm.kubeClient.Extensions().Jobs(api.NamespaceAll).List(labels.Everything(), fields.Everything()) + }, + WatchFunc: func(rv string) (watch.Interface, error) { + return jm.kubeClient.Extensions().Jobs(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), rv) + }, + }, + &extensions.Job{}, + // TODO: Can we have much longer period here? + replicationcontroller.FullControllerResyncPeriod, + framework.ResourceEventHandlerFuncs{ + AddFunc: jm.enqueueController, + UpdateFunc: func(old, cur interface{}) { + if job := cur.(*extensions.Job); !isJobFinished(job) { + jm.enqueueController(job) + } + }, + DeleteFunc: jm.enqueueController, + }, + ) + + jm.podStore.Store, jm.podController = framework.NewInformer( + &cache.ListWatch{ + ListFunc: func() (runtime.Object, error) { + return jm.kubeClient.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()) + }, + WatchFunc: func(rv string) (watch.Interface, error) { + return jm.kubeClient.Pods(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), rv) + }, + }, + &api.Pod{}, + resyncPeriod(), + framework.ResourceEventHandlerFuncs{ + AddFunc: jm.addPod, + UpdateFunc: jm.updatePod, + DeleteFunc: jm.deletePod, + }, + ) + + jm.updateHandler = jm.updateJobStatus + jm.syncHandler = jm.syncJob + jm.podStoreSynced = jm.podController.HasSynced + return jm +} + +// Run the main goroutine responsible for watching and syncing jobs. +func (jm *JobController) Run(workers int, stopCh <-chan struct{}) { + defer util.HandleCrash() + go jm.jobController.Run(stopCh) + go jm.podController.Run(stopCh) + for i := 0; i < workers; i++ { + go util.Until(jm.worker, time.Second, stopCh) + } + <-stopCh + glog.Infof("Shutting down Job Manager") + jm.queue.ShutDown() +} + +// getPodJob returns the job managing the given pod. +func (jm *JobController) getPodJob(pod *api.Pod) *extensions.Job { + jobs, err := jm.jobStore.GetPodJobs(pod) + if err != nil { + glog.V(4).Infof("No jobs found for pod %v, job controller will avoid syncing", pod.Name) + return nil + } + if len(jobs) > 1 { + glog.Errorf("user error! more than one job is selecting pods with labels: %+v", pod.Labels) + sort.Sort(byCreationTimestamp(jobs)) + } + return &jobs[0] +} + +// When a pod is created, enqueue the controller that manages it and update it's expectations. +func (jm *JobController) addPod(obj interface{}) { + pod := obj.(*api.Pod) + if pod.DeletionTimestamp != nil { + // on a restart of the controller controller, it's possible a new pod shows up in a state that + // is already pending deletion. Prevent the pod from being a creation observation. + jm.deletePod(pod) + return + } + if job := jm.getPodJob(pod); job != nil { + jobKey, err := controller.KeyFunc(job) + if err != nil { + glog.Errorf("Couldn't get key for job %#v: %v", job, err) + return + } + jm.expectations.CreationObserved(jobKey) + jm.enqueueController(job) + } +} + +// When a pod is updated, figure out what job/s manage it and wake them up. +// If the labels of the pod have changed we need to awaken both the old +// and new job. old and cur must be *api.Pod types. +func (jm *JobController) updatePod(old, cur interface{}) { + if api.Semantic.DeepEqual(old, cur) { + // A periodic relist will send update events for all known pods. + return + } + curPod := cur.(*api.Pod) + if curPod.DeletionTimestamp != nil { + // when a pod is deleted gracefully it's deletion timestamp is first modified to reflect a grace period, + // and after such time has passed, the kubelet actually deletes it from the store. We receive an update + // for modification of the deletion timestamp and expect an job to create more pods asap, not wait + // until the kubelet actually deletes the pod. + jm.deletePod(curPod) + return + } + if job := jm.getPodJob(curPod); job != nil { + jm.enqueueController(job) + } + oldPod := old.(*api.Pod) + // Only need to get the old job if the labels changed. + if !reflect.DeepEqual(curPod.Labels, oldPod.Labels) { + // If the old and new job are the same, the first one that syncs + // will set expectations preventing any damage from the second. + if oldJob := jm.getPodJob(oldPod); oldJob != nil { + jm.enqueueController(oldJob) + } + } +} + +// When a pod is deleted, enqueue the job that manages the pod and update its expectations. +// obj could be an *api.Pod, or a DeletionFinalStateUnknown marker item. +func (jm *JobController) deletePod(obj interface{}) { + pod, ok := obj.(*api.Pod) + + // When a delete is dropped, the relist will notice a pod in the store not + // in the list, leading to the insertion of a tombstone object which contains + // the deleted key/value. Note that this value might be stale. If the pod + // changed labels the new job will not be woken up till the periodic resync. + if !ok { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + glog.Errorf("Couldn't get object from tombstone %+v, could take up to %v before a job recreates a pod", obj, controller.ExpectationsTimeout) + return + } + pod, ok = tombstone.Obj.(*api.Pod) + if !ok { + glog.Errorf("Tombstone contained object that is not a pod %+v, could take up to %v before job recreates a pod", obj, controller.ExpectationsTimeout) + return + } + } + if job := jm.getPodJob(pod); job != nil { + jobKey, err := controller.KeyFunc(job) + if err != nil { + glog.Errorf("Couldn't get key for job %#v: %v", job, err) + return + } + jm.expectations.DeletionObserved(jobKey) + jm.enqueueController(job) + } +} + +// obj could be an *extensions.Job, or a DeletionFinalStateUnknown marker item. +func (jm *JobController) enqueueController(obj interface{}) { + key, err := controller.KeyFunc(obj) + if err != nil { + glog.Errorf("Couldn't get key for object %+v: %v", obj, err) + return + } + + // TODO: Handle overlapping controllers better. Either disallow them at admission time or + // deterministically avoid syncing controllers that fight over pods. Currently, we only + // ensure that the same controller is synced for a given pod. When we periodically relist + // all controllers there will still be some replica instability. One way to handle this is + // by querying the store for all controllers that this rc overlaps, as well as all + // controllers that overlap this rc, and sorting them. + jm.queue.Add(key) +} + +// worker runs a worker thread that just dequeues items, processes them, and marks them done. +// It enforces that the syncHandler is never invoked concurrently with the same key. +func (jm *JobController) worker() { + for { + func() { + key, quit := jm.queue.Get() + if quit { + return + } + defer jm.queue.Done(key) + err := jm.syncHandler(key.(string)) + if err != nil { + glog.Errorf("Error syncing job: %v", err) + } + }() + } +} + +// syncJob will sync the job with the given key if it has had its expectations fulfilled, meaning +// it did not expect to see any more of its pods created or deleted. This function is not meant to be invoked +// concurrently with the same key. +func (jm *JobController) syncJob(key string) error { + startTime := time.Now() + defer func() { + glog.V(4).Infof("Finished syncing job %q (%v)", key, time.Now().Sub(startTime)) + }() + + obj, exists, err := jm.jobStore.Store.GetByKey(key) + if !exists { + glog.V(4).Infof("Job has been deleted: %v", key) + jm.expectations.DeleteExpectations(key) + return nil + } + if err != nil { + glog.Errorf("Unable to retrieve job %v from store: %v", key, err) + jm.queue.Add(key) + return err + } + job := *obj.(*extensions.Job) + if !jm.podStoreSynced() { + // Sleep so we give the pod reflector goroutine a chance to run. + time.Sleep(replicationcontroller.PodStoreSyncedPollPeriod) + glog.V(4).Infof("Waiting for pods controller to sync, requeuing job %v", job.Name) + jm.enqueueController(&job) + return nil + } + + // Check the expectations of the job before counting active pods, otherwise a new pod can sneak in + // and update the expectations after we've retrieved active pods from the store. If a new pod enters + // the store after we've checked the expectation, the job sync is just deferred till the next relist. + jobKey, err := controller.KeyFunc(&job) + if err != nil { + glog.Errorf("Couldn't get key for job %#v: %v", job, err) + return err + } + jobNeedsSync := jm.expectations.SatisfiedExpectations(jobKey) + podList, err := jm.podStore.Pods(job.Namespace).List(labels.Set(job.Spec.Selector).AsSelector()) + if err != nil { + glog.Errorf("Error getting pods for job %q: %v", key, err) + jm.queue.Add(key) + return err + } + + activePods := controller.FilterActivePods(podList.Items) + active := len(activePods) + succeeded, failed := getStatus(podList.Items) + if jobNeedsSync { + active = jm.manageJob(activePods, succeeded, &job) + } + completions := succeeded + if completions == *job.Spec.Completions { + job.Status.Conditions = append(job.Status.Conditions, newCondition()) + } + + // no need to update the job if the status hasn't changed since last time + if job.Status.Active != active || job.Status.Succeeded != succeeded || job.Status.Failed != failed { + job.Status.Active = active + job.Status.Succeeded = succeeded + job.Status.Failed = failed + + if err := jm.updateHandler(&job); err != nil { + glog.Errorf("Failed to update job %v, requeuing. Error: %v", job.Name, err) + jm.enqueueController(&job) + } + } + return nil +} + +func newCondition() extensions.JobCondition { + return extensions.JobCondition{ + Type: extensions.JobComplete, + Status: api.ConditionTrue, + LastProbeTime: unversioned.Now(), + LastTransitionTime: unversioned.Now(), + } +} + +func getStatus(pods []api.Pod) (succeeded, failed int) { + succeeded = filterPods(pods, api.PodSucceeded) + failed = filterPods(pods, api.PodFailed) + return +} + +func (jm *JobController) manageJob(activePods []*api.Pod, succeeded int, job *extensions.Job) int { + var activeLock sync.Mutex + active := len(activePods) + parallelism := *job.Spec.Parallelism + jobKey, err := controller.KeyFunc(job) + if err != nil { + glog.Errorf("Couldn't get key for job %#v: %v", job, err) + return 0 + } + + if active > parallelism { + diff := active - parallelism + jm.expectations.ExpectDeletions(jobKey, diff) + glog.V(4).Infof("Too many pods running job %q, need %d, deleting %d", jobKey, parallelism, diff) + // Sort the pods in the order such that not-ready < ready, unscheduled + // < scheduled, and pending < running. This ensures that we delete pods + // in the earlier stages whenever possible. + sort.Sort(controller.ActivePods(activePods)) + + active -= diff + wait := sync.WaitGroup{} + wait.Add(diff) + for i := 0; i < diff; i++ { + go func(ix int) { + defer wait.Done() + if err := jm.podControl.DeletePod(job.Namespace, activePods[ix].Name); err != nil { + defer util.HandleError(err) + // Decrement the expected number of deletes because the informer won't observe this deletion + jm.expectations.DeletionObserved(jobKey) + activeLock.Lock() + active++ + activeLock.Unlock() + } + }(i) + } + wait.Wait() + + } else if active < parallelism { + // how many executions are left to run + diff := *job.Spec.Completions - succeeded + // limit to parallelism and count active pods as well + if diff > parallelism { + diff = parallelism + } + diff -= active + jm.expectations.ExpectCreations(jobKey, diff) + glog.V(4).Infof("Too few pods running job %q, need %d, creating %d", jobKey, parallelism, diff) + + active += diff + wait := sync.WaitGroup{} + wait.Add(diff) + for i := 0; i < diff; i++ { + go func() { + defer wait.Done() + if err := jm.podControl.CreatePods(job.Namespace, &job.Spec.Template, job); err != nil { + defer util.HandleError(err) + // Decrement the expected number of creates because the informer won't observe this pod + jm.expectations.CreationObserved(jobKey) + activeLock.Lock() + active-- + activeLock.Unlock() + } + }() + } + wait.Wait() + } + + return active +} + +func (jm *JobController) updateJobStatus(job *extensions.Job) error { + _, err := jm.kubeClient.Extensions().Jobs(job.Namespace).UpdateStatus(job) + return err +} + +// filterPods returns pods based on their phase. +func filterPods(pods []api.Pod, phase api.PodPhase) int { + result := 0 + for i := range pods { + if phase == pods[i].Status.Phase { + result++ + } + } + return result +} + +func isJobFinished(j *extensions.Job) bool { + for _, c := range j.Status.Conditions { + if c.Type == extensions.JobComplete && c.Status == api.ConditionTrue { + return true + } + } + return false +} + +// byCreationTimestamp sorts a list by creation timestamp, using their names as a tie breaker. +type byCreationTimestamp []extensions.Job + +func (o byCreationTimestamp) Len() int { return len(o) } +func (o byCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] } + +func (o byCreationTimestamp) Less(i, j int) bool { + if o[i].CreationTimestamp.Equal(o[j].CreationTimestamp) { + return o[i].Name < o[j].Name + } + return o[i].CreationTimestamp.Before(o[j].CreationTimestamp) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/job/controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/job/controller_test.go new file mode 100644 index 000000000000..21f1f177518e --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/job/controller_test.go @@ -0,0 +1,486 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 job + +import ( + "fmt" + "testing" + "time" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" + client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/testclient" + "k8s.io/kubernetes/pkg/controller" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/watch" +) + +var alwaysReady = func() bool { return true } + +func newJob(parallelism, completions int) *extensions.Job { + return &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: "foobar", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.JobSpec{ + Parallelism: ¶llelism, + Completions: &completions, + Selector: map[string]string{"foo": "bar"}, + Template: api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + {Image: "foo/bar"}, + }, + }, + }, + }, + } +} + +func getKey(job *extensions.Job, t *testing.T) string { + if key, err := controller.KeyFunc(job); err != nil { + t.Errorf("Unexpected error getting key for job %v: %v", job.Name, err) + return "" + } else { + return key + } +} + +// create count pods with the given phase for the given job +func newPodList(count int, status api.PodPhase, job *extensions.Job) []api.Pod { + pods := []api.Pod{} + for i := 0; i < count; i++ { + newPod := api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: fmt.Sprintf("pod-%v", unversioned.Now().UnixNano()), + Labels: job.Spec.Selector, + Namespace: job.Namespace, + }, + Status: api.PodStatus{Phase: status}, + } + pods = append(pods, newPod) + } + return pods +} + +func TestControllerSyncJob(t *testing.T) { + testCases := map[string]struct { + // job setup + parallelism int + completions int + + // pod setup + podControllerError error + activePods int + succeededPods int + failedPods int + + // expectations + expectedCreations int + expectedDeletions int + expectedActive int + expectedSucceeded int + expectedFailed int + expectedComplete bool + }{ + "job start": { + 2, 5, + nil, 0, 0, 0, + 2, 0, 2, 0, 0, false, + }, + "correct # of pods": { + 2, 5, + nil, 2, 0, 0, + 0, 0, 2, 0, 0, false, + }, + "too few active pods": { + 2, 5, + nil, 1, 1, 0, + 1, 0, 2, 1, 0, false, + }, + "too few active pods, with controller error": { + 2, 5, + fmt.Errorf("Fake error"), 1, 1, 0, + 0, 0, 1, 1, 0, false, + }, + "too many active pods": { + 2, 5, + nil, 3, 0, 0, + 0, 1, 2, 0, 0, false, + }, + "too many active pods, with controller error": { + 2, 5, + fmt.Errorf("Fake error"), 3, 0, 0, + 0, 0, 3, 0, 0, false, + }, + "failed pod": { + 2, 5, + nil, 1, 1, 1, + 1, 0, 2, 1, 1, false, + }, + "job finish": { + 2, 5, + nil, 0, 5, 0, + 0, 0, 0, 5, 0, true, + }, + "more active pods than completions": { + 2, 5, + nil, 10, 0, 0, + 0, 8, 2, 0, 0, false, + }, + "status change": { + 2, 5, + nil, 2, 2, 0, + 0, 0, 2, 2, 0, false, + }, + } + + for name, tc := range testCases { + // job manager setup + client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + manager := NewJobController(client, controller.NoResyncPeriodFunc) + fakePodControl := controller.FakePodControl{Err: tc.podControllerError} + manager.podControl = &fakePodControl + manager.podStoreSynced = alwaysReady + var actual *extensions.Job + manager.updateHandler = func(job *extensions.Job) error { + actual = job + return nil + } + + // job & pods setup + job := newJob(tc.parallelism, tc.completions) + manager.jobStore.Store.Add(job) + for _, pod := range newPodList(tc.activePods, api.PodRunning, job) { + manager.podStore.Store.Add(&pod) + } + for _, pod := range newPodList(tc.succeededPods, api.PodSucceeded, job) { + manager.podStore.Store.Add(&pod) + } + for _, pod := range newPodList(tc.failedPods, api.PodFailed, job) { + manager.podStore.Store.Add(&pod) + } + + // run + err := manager.syncJob(getKey(job, t)) + if err != nil { + t.Errorf("%s: unexpected error when syncing jobs %v", err) + } + + // validate created/deleted pods + if len(fakePodControl.Templates) != tc.expectedCreations { + t.Errorf("%s: unexpected number of creates. Expected %d, saw %d\n", name, tc.expectedCreations, len(fakePodControl.Templates)) + } + if len(fakePodControl.DeletePodName) != tc.expectedDeletions { + t.Errorf("%s: unexpected number of deletes. Expected %d, saw %d\n", name, tc.expectedDeletions, len(fakePodControl.DeletePodName)) + } + // validate status + if actual.Status.Active != tc.expectedActive { + t.Errorf("%s: unexpected number of active pods. Expected %d, saw %d\n", name, tc.expectedActive, actual.Status.Active) + } + if actual.Status.Succeeded != tc.expectedSucceeded { + t.Errorf("%s: unexpected number of succeeded pods. Expected %d, saw %d\n", name, tc.expectedSucceeded, actual.Status.Succeeded) + } + if actual.Status.Failed != tc.expectedFailed { + t.Errorf("%s: unexpected number of failed pods. Expected %d, saw %d\n", name, tc.expectedFailed, actual.Status.Failed) + } + // validate conditions + if tc.expectedComplete { + completed := false + for _, v := range actual.Status.Conditions { + if v.Type == extensions.JobComplete && v.Status == api.ConditionTrue { + completed = true + break + } + } + if !completed { + t.Errorf("%s: expected completion condition. Got %v", name, actual.Status.Conditions) + } + } + } +} + +func TestSyncJobDeleted(t *testing.T) { + client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + manager := NewJobController(client, controller.NoResyncPeriodFunc) + fakePodControl := controller.FakePodControl{} + manager.podControl = &fakePodControl + manager.podStoreSynced = alwaysReady + manager.updateHandler = func(job *extensions.Job) error { return nil } + job := newJob(2, 2) + err := manager.syncJob(getKey(job, t)) + if err != nil { + t.Errorf("Unexpected error when syncing jobs %v", err) + } + if len(fakePodControl.Templates) != 0 { + t.Errorf("Unexpected number of creates. Expected %d, saw %d\n", 0, len(fakePodControl.Templates)) + } + if len(fakePodControl.DeletePodName) != 0 { + t.Errorf("Unexpected number of deletes. Expected %d, saw %d\n", 0, len(fakePodControl.DeletePodName)) + } +} + +func TestSyncJobUpdateRequeue(t *testing.T) { + client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + manager := NewJobController(client, controller.NoResyncPeriodFunc) + fakePodControl := controller.FakePodControl{} + manager.podControl = &fakePodControl + manager.podStoreSynced = alwaysReady + manager.updateHandler = func(job *extensions.Job) error { return fmt.Errorf("Fake error") } + job := newJob(2, 2) + manager.jobStore.Store.Add(job) + err := manager.syncJob(getKey(job, t)) + if err != nil { + t.Errorf("Unxpected error when syncing jobs, got %v", err) + } + t.Log("Waiting for a job in the queue") + key, _ := manager.queue.Get() + expectedKey := getKey(job, t) + if key != expectedKey { + t.Errorf("Expected requeue of job with key %s got %s", expectedKey, key) + } +} + +func TestJobPodLookup(t *testing.T) { + client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + manager := NewJobController(client, controller.NoResyncPeriodFunc) + manager.podStoreSynced = alwaysReady + testCases := []struct { + job *extensions.Job + pod *api.Pod + + expectedName string + }{ + // pods without labels don't match any job + { + job: &extensions.Job{ + ObjectMeta: api.ObjectMeta{Name: "basic"}, + }, + pod: &api.Pod{ + ObjectMeta: api.ObjectMeta{Name: "foo1", Namespace: api.NamespaceAll}, + }, + expectedName: "", + }, + // matching labels, different namespace + { + job: &extensions.Job{ + ObjectMeta: api.ObjectMeta{Name: "foo"}, + Spec: extensions.JobSpec{ + Selector: map[string]string{"foo": "bar"}, + }, + }, + pod: &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: "foo2", + Namespace: "ns", + Labels: map[string]string{"foo": "bar"}, + }, + }, + expectedName: "", + }, + // matching ns and labels returns + { + job: &extensions.Job{ + ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, + Spec: extensions.JobSpec{ + Selector: map[string]string{"foo": "bar"}, + }, + }, + pod: &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: "foo3", + Namespace: "ns", + Labels: map[string]string{"foo": "bar"}, + }, + }, + expectedName: "bar", + }, + } + for _, tc := range testCases { + manager.jobStore.Add(tc.job) + if job := manager.getPodJob(tc.pod); job != nil { + if tc.expectedName != job.Name { + t.Errorf("Got job %+v expected %+v", job.Name, tc.expectedName) + } + } else if tc.expectedName != "" { + t.Errorf("Expected a job %v pod %v, found none", tc.expectedName, tc.pod.Name) + } + } +} + +type FakeJobExpectations struct { + *controller.ControllerExpectations + satisfied bool + expSatisfied func() +} + +func (fe FakeJobExpectations) SatisfiedExpectations(controllerKey string) bool { + fe.expSatisfied() + return fe.satisfied +} + +// TestSyncJobExpectations tests that a pod cannot sneak in between counting active pods +// and checking expectations. +func TestSyncJobExpectations(t *testing.T) { + client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + manager := NewJobController(client, controller.NoResyncPeriodFunc) + fakePodControl := controller.FakePodControl{} + manager.podControl = &fakePodControl + manager.podStoreSynced = alwaysReady + manager.updateHandler = func(job *extensions.Job) error { return nil } + + job := newJob(2, 2) + manager.jobStore.Store.Add(job) + pods := newPodList(2, api.PodPending, job) + manager.podStore.Store.Add(&pods[0]) + + manager.expectations = FakeJobExpectations{ + controller.NewControllerExpectations(), true, func() { + // If we check active pods before checking expectataions, the job + // will create a new replica because it doesn't see this pod, but + // has fulfilled its expectations. + manager.podStore.Store.Add(&pods[1]) + }, + } + manager.syncJob(getKey(job, t)) + if len(fakePodControl.Templates) != 0 { + t.Errorf("Unexpected number of creates. Expected %d, saw %d\n", 0, len(fakePodControl.Templates)) + } + if len(fakePodControl.DeletePodName) != 0 { + t.Errorf("Unexpected number of deletes. Expected %d, saw %d\n", 0, len(fakePodControl.DeletePodName)) + } +} + +type FakeWatcher struct { + w *watch.FakeWatcher + *testclient.Fake +} + +func TestWatchJobs(t *testing.T) { + client := testclient.NewSimpleFake() + fakeWatch := watch.NewFake() + client.PrependWatchReactor("*", testclient.DefaultWatchReactor(fakeWatch, nil)) + manager := NewJobController(client, controller.NoResyncPeriodFunc) + manager.podStoreSynced = alwaysReady + + var testJob extensions.Job + received := make(chan struct{}) + + // The update sent through the fakeWatcher should make its way into the workqueue, + // and eventually into the syncHandler. + manager.syncHandler = func(key string) error { + + obj, exists, err := manager.jobStore.Store.GetByKey(key) + if !exists || err != nil { + t.Errorf("Expected to find job under key %v", key) + } + job := *obj.(*extensions.Job) + if !api.Semantic.DeepDerivative(job, testJob) { + t.Errorf("Expected %#v, but got %#v", testJob, job) + } + close(received) + return nil + } + // Start only the job watcher and the workqueue, send a watch event, + // and make sure it hits the sync method. + stopCh := make(chan struct{}) + defer close(stopCh) + go manager.jobController.Run(stopCh) + go util.Until(manager.worker, 10*time.Millisecond, stopCh) + + // We're sending new job to see if it reaches syncHandler. + testJob.Name = "foo" + fakeWatch.Add(&testJob) + t.Log("Waiting for job to reach syncHandler") + <-received +} + +func TestIsJobFinished(t *testing.T) { + job := &extensions.Job{ + Status: extensions.JobStatus{ + Conditions: []extensions.JobCondition{{ + Type: extensions.JobComplete, + Status: api.ConditionTrue, + }}, + }, + } + + if !isJobFinished(job) { + t.Error("Job was expected to be finished") + } + + job.Status.Conditions[0].Status = api.ConditionFalse + if isJobFinished(job) { + t.Error("Job was not expected to be finished") + } + + job.Status.Conditions[0].Status = api.ConditionUnknown + if isJobFinished(job) { + t.Error("Job was not expected to be finished") + } +} + +func TestWatchPods(t *testing.T) { + client := testclient.NewSimpleFake() + fakeWatch := watch.NewFake() + client.PrependWatchReactor("*", testclient.DefaultWatchReactor(fakeWatch, nil)) + manager := NewJobController(client, controller.NoResyncPeriodFunc) + manager.podStoreSynced = alwaysReady + + // Put one job and one pod into the store + testJob := newJob(2, 2) + manager.jobStore.Store.Add(testJob) + received := make(chan struct{}) + // The pod update sent through the fakeWatcher should figure out the managing job and + // send it into the syncHandler. + manager.syncHandler = func(key string) error { + + obj, exists, err := manager.jobStore.Store.GetByKey(key) + if !exists || err != nil { + t.Errorf("Expected to find job under key %v", key) + } + job := obj.(*extensions.Job) + if !api.Semantic.DeepDerivative(job, testJob) { + t.Errorf("\nExpected %#v,\nbut got %#v", testJob, job) + } + close(received) + return nil + } + // Start only the pod watcher and the workqueue, send a watch event, + // and make sure it hits the sync method for the right job. + stopCh := make(chan struct{}) + defer close(stopCh) + go manager.podController.Run(stopCh) + go util.Until(manager.worker, 10*time.Millisecond, stopCh) + + pods := newPodList(1, api.PodRunning, testJob) + testPod := pods[0] + testPod.Status.Phase = api.PodFailed + fakeWatch.Add(&testPod) + + t.Log("Waiting for pod to reach syncHandler") + <-received +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/job/doc.go similarity index 77% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/doc.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/job/doc.go index a3ce47444557..9c569bfc08c2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/job/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2014 The Kubernetes Authors All rights reserved. +Copyright 2015 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,5 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package user contains security context constraints user strategy implementations. -package user +// Package job contains logic for watching and synchronizing jobs. +package job diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/doc.go index 57c790073394..fea657af5e7a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/doc.go @@ -15,4 +15,4 @@ limitations under the License. */ // namespace contains a controller that handles namespace lifecycle -package namespacecontroller +package namespace diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller.go index 198c608880a9..5ccaa8f42af7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package namespacecontroller +package namespace import ( "fmt" @@ -22,6 +22,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/controller/framework" @@ -54,11 +55,12 @@ func NewNamespaceController(kubeClient client.Interface, experimentalMode bool, }, }, &api.Namespace{}, + // TODO: Can we have much longer period here? resyncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { namespace := obj.(*api.Namespace) - if err := syncNamespace(kubeClient, experimentalMode, *namespace); err != nil { + if err := syncNamespace(kubeClient, experimentalMode, namespace); err != nil { if estimate, ok := err.(*contentRemainingError); ok { go func() { // Estimate is the aggregate total of TerminationGracePeriodSeconds, which defaults to 30s @@ -80,7 +82,7 @@ func NewNamespaceController(kubeClient client.Interface, experimentalMode bool, }, UpdateFunc: func(oldObj, newObj interface{}) { namespace := newObj.(*api.Namespace) - if err := syncNamespace(kubeClient, experimentalMode, *namespace); err != nil { + if err := syncNamespace(kubeClient, experimentalMode, namespace); err != nil { if estimate, ok := err.(*contentRemainingError); ok { go func() { t := estimate.Estimate/2 + 1 @@ -120,12 +122,12 @@ func (nm *NamespaceController) Stop() { } // finalized returns true if the spec.finalizers is empty list -func finalized(namespace api.Namespace) bool { +func finalized(namespace *api.Namespace) bool { return len(namespace.Spec.Finalizers) == 0 } // finalize will finalize the namespace for kubernetes -func finalize(kubeClient client.Interface, namespace api.Namespace) (*api.Namespace, error) { +func finalizeNamespaceFunc(kubeClient client.Interface, namespace *api.Namespace) (*api.Namespace, error) { namespaceFinalize := api.Namespace{} namespaceFinalize.ObjectMeta = namespace.ObjectMeta namespaceFinalize.Spec = namespace.Spec @@ -153,7 +155,7 @@ func (e *contentRemainingError) Error() string { // deleteAllContent will delete all content known to the system in a namespace. It returns an estimate // of the time remaining before the remaining resources are deleted. If estimate > 0 not all resources // are guaranteed to be gone. -func deleteAllContent(kubeClient client.Interface, experimentalMode bool, namespace string, before util.Time) (estimate int64, err error) { +func deleteAllContent(kubeClient client.Interface, experimentalMode bool, namespace string, before unversioned.Time) (estimate int64, err error) { err = deleteServiceAccounts(kubeClient, namespace) if err != nil { return estimate, err @@ -192,15 +194,23 @@ func deleteAllContent(kubeClient client.Interface, experimentalMode bool, namesp } // If experimental mode, delete all experimental resources for the namespace. if experimentalMode { - err = deleteHorizontalPodAutoscalers(kubeClient.Experimental(), namespace) + err = deleteHorizontalPodAutoscalers(kubeClient.Extensions(), namespace) if err != nil { return estimate, err } - err = deleteDaemons(kubeClient.Experimental(), namespace) + err = deleteDaemonSets(kubeClient.Extensions(), namespace) if err != nil { return estimate, err } - err = deleteDeployments(kubeClient.Experimental(), namespace) + err = deleteJobs(kubeClient.Extensions(), namespace) + if err != nil { + return estimate, err + } + err = deleteDeployments(kubeClient.Extensions(), namespace) + if err != nil { + return estimate, err + } + err = deleteIngress(kubeClient.Extensions(), namespace) if err != nil { return estimate, err } @@ -208,25 +218,56 @@ func deleteAllContent(kubeClient client.Interface, experimentalMode bool, namesp return estimate, nil } -// syncNamespace makes namespace life-cycle decisions -func syncNamespace(kubeClient client.Interface, experimentalMode bool, namespace api.Namespace) (err error) { +// updateNamespaceFunc is a function that makes an update to a namespace +type updateNamespaceFunc func(kubeClient client.Interface, namespace *api.Namespace) (*api.Namespace, error) + +// retryOnConflictError retries the specified fn if there was a conflict error +// TODO RetryOnConflict should be a generic concept in client code +func retryOnConflictError(kubeClient client.Interface, namespace *api.Namespace, fn updateNamespaceFunc) (result *api.Namespace, err error) { + latestNamespace := namespace + for { + result, err = fn(kubeClient, latestNamespace) + if err == nil { + return result, nil + } + if !errors.IsConflict(err) { + return nil, err + } + latestNamespace, err = kubeClient.Namespaces().Get(latestNamespace.Name) + if err != nil { + return nil, err + } + } + return +} + +// updateNamespaceStatusFunc will verify that the status of the namespace is correct +func updateNamespaceStatusFunc(kubeClient client.Interface, namespace *api.Namespace) (*api.Namespace, error) { + if namespace.DeletionTimestamp.IsZero() || namespace.Status.Phase == api.NamespaceTerminating { + return namespace, nil + } + newNamespace := api.Namespace{} + newNamespace.ObjectMeta = namespace.ObjectMeta + newNamespace.Status = namespace.Status + newNamespace.Status.Phase = api.NamespaceTerminating + return kubeClient.Namespaces().Status(&newNamespace) +} + +// syncNamespace orchestrates deletion of a Namespace and its associated content. +func syncNamespace(kubeClient client.Interface, experimentalMode bool, namespace *api.Namespace) (err error) { if namespace.DeletionTimestamp == nil { return nil } glog.V(4).Infof("Syncing namespace %s", namespace.Name) - // if there is a deletion timestamp, and the status is not terminating, then update status - if !namespace.DeletionTimestamp.IsZero() && namespace.Status.Phase != api.NamespaceTerminating { - newNamespace := api.Namespace{} - newNamespace.ObjectMeta = namespace.ObjectMeta - newNamespace.Status = namespace.Status - newNamespace.Status.Phase = api.NamespaceTerminating - result, err := kubeClient.Namespaces().Status(&newNamespace) - if err != nil { - return err + // ensure that the status is up to date on the namespace + // if we get a not found error, we assume the namespace is truly gone + namespace, err = retryOnConflictError(kubeClient, namespace, updateNamespaceStatusFunc) + if err != nil { + if errors.IsNotFound(err) { + return nil } - // work with the latest copy so we can proceed to clean up right away without another interval - namespace = *result + return err } // if the namespace is already finalized, delete it @@ -248,13 +289,13 @@ func syncNamespace(kubeClient client.Interface, experimentalMode bool, namespace } // we have removed content, so mark it finalized by us - result, err := finalize(kubeClient, namespace) + result, err := retryOnConflictError(kubeClient, namespace, finalizeNamespaceFunc) if err != nil { return err } // now check if all finalizers have reported that we delete now - if finalized(*result) { + if finalized(result) { err = kubeClient.Namespaces().Delete(namespace.Name) if err != nil && !errors.IsNotFound(err) { return err @@ -265,7 +306,7 @@ func syncNamespace(kubeClient client.Interface, experimentalMode bool, namespace } func deleteLimitRanges(kubeClient client.Interface, ns string) error { - items, err := kubeClient.LimitRanges(ns).List(labels.Everything()) + items, err := kubeClient.LimitRanges(ns).List(labels.Everything(), fields.Everything()) if err != nil { return err } @@ -279,7 +320,7 @@ func deleteLimitRanges(kubeClient client.Interface, ns string) error { } func deleteResourceQuotas(kubeClient client.Interface, ns string) error { - resourceQuotas, err := kubeClient.ResourceQuotas(ns).List(labels.Everything()) + resourceQuotas, err := kubeClient.ResourceQuotas(ns).List(labels.Everything(), fields.Everything()) if err != nil { return err } @@ -307,7 +348,7 @@ func deleteServiceAccounts(kubeClient client.Interface, ns string) error { } func deleteServices(kubeClient client.Interface, ns string) error { - items, err := kubeClient.Services(ns).List(labels.Everything()) + items, err := kubeClient.Services(ns).List(labels.Everything(), fields.Everything()) if err != nil { return err } @@ -321,7 +362,7 @@ func deleteServices(kubeClient client.Interface, ns string) error { } func deleteReplicationControllers(kubeClient client.Interface, ns string) error { - items, err := kubeClient.ReplicationControllers(ns).List(labels.Everything()) + items, err := kubeClient.ReplicationControllers(ns).List(labels.Everything(), fields.Everything()) if err != nil { return err } @@ -334,12 +375,12 @@ func deleteReplicationControllers(kubeClient client.Interface, ns string) error return nil } -func deletePods(kubeClient client.Interface, ns string, before util.Time) (int64, error) { +func deletePods(kubeClient client.Interface, ns string, before unversioned.Time) (int64, error) { items, err := kubeClient.Pods(ns).List(labels.Everything(), fields.Everything()) if err != nil { return 0, err } - expired := util.Now().After(before.Time) + expired := unversioned.Now().After(before.Time) var deleteOptions *api.DeleteOptions if expired { deleteOptions = api.NewDeleteOptions(0) @@ -405,7 +446,7 @@ func deletePersistentVolumeClaims(kubeClient client.Interface, ns string) error return nil } -func deleteHorizontalPodAutoscalers(expClient client.ExperimentalInterface, ns string) error { +func deleteHorizontalPodAutoscalers(expClient client.ExtensionsInterface, ns string) error { items, err := expClient.HorizontalPodAutoscalers(ns).List(labels.Everything(), fields.Everything()) if err != nil { return err @@ -419,8 +460,8 @@ func deleteHorizontalPodAutoscalers(expClient client.ExperimentalInterface, ns s return nil } -func deleteDaemons(expClient client.ExperimentalInterface, ns string) error { - items, err := expClient.DaemonSets(ns).List(labels.Everything()) +func deleteDaemonSets(expClient client.ExtensionsInterface, ns string) error { + items, err := expClient.DaemonSets(ns).List(labels.Everything(), fields.Everything()) if err != nil { return err } @@ -433,7 +474,21 @@ func deleteDaemons(expClient client.ExperimentalInterface, ns string) error { return nil } -func deleteDeployments(expClient client.ExperimentalInterface, ns string) error { +func deleteJobs(expClient client.ExtensionsInterface, ns string) error { + items, err := expClient.Jobs(ns).List(labels.Everything(), fields.Everything()) + if err != nil { + return err + } + for i := range items.Items { + err := expClient.Jobs(ns).Delete(items.Items[i].Name, nil) + if err != nil && !errors.IsNotFound(err) { + return err + } + } + return nil +} + +func deleteDeployments(expClient client.ExtensionsInterface, ns string) error { items, err := expClient.Deployments(ns).List(labels.Everything(), fields.Everything()) if err != nil { return err @@ -446,3 +501,17 @@ func deleteDeployments(expClient client.ExperimentalInterface, ns string) error } return nil } + +func deleteIngress(expClient client.ExtensionsInterface, ns string) error { + items, err := expClient.Ingress(ns).List(labels.Everything(), fields.Everything()) + if err != nil { + return err + } + for i := range items.Items { + err := expClient.Ingress(ns).Delete(items.Items[i].Name, nil) + if err != nil && !errors.IsNotFound(err) { + return err + } + } + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller_test.go index ccdd96b7b85a..93a462ec08c7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller_test.go @@ -14,21 +14,24 @@ See the License for the specific language governing permissions and limitations under the License. */ -package namespacecontroller +package namespace import ( + "fmt" "strings" "testing" "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" + client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/testclient" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" ) func TestFinalized(t *testing.T) { - testNamespace := api.Namespace{ + testNamespace := &api.Namespace{ Spec: api.NamespaceSpec{ Finalizers: []api.FinalizerName{"a", "b"}, }, @@ -42,9 +45,9 @@ func TestFinalized(t *testing.T) { } } -func TestFinalize(t *testing.T) { +func TestFinalizeNamespaceFunc(t *testing.T) { mockClient := &testclient.Fake{} - testNamespace := api.Namespace{ + testNamespace := &api.Namespace{ ObjectMeta: api.ObjectMeta{ Name: "test", ResourceVersion: "1", @@ -53,7 +56,7 @@ func TestFinalize(t *testing.T) { Finalizers: []api.FinalizerName{"kubernetes", "other"}, }, } - finalize(mockClient, testNamespace) + finalizeNamespaceFunc(mockClient, testNamespace) actions := mockClient.Actions() if len(actions) != 1 { t.Errorf("Expected 1 mock client action, but got %v", len(actions)) @@ -72,8 +75,8 @@ func TestFinalize(t *testing.T) { func testSyncNamespaceThatIsTerminating(t *testing.T, experimentalMode bool) { mockClient := &testclient.Fake{} - now := util.Now() - testNamespace := api.Namespace{ + now := unversioned.Now() + testNamespace := &api.Namespace{ ObjectMeta: api.ObjectMeta{ Name: "test", ResourceVersion: "1", @@ -110,6 +113,8 @@ func testSyncNamespaceThatIsTerminating(t *testing.T, experimentalMode bool) { strings.Join([]string{"list", "horizontalpodautoscalers", ""}, "-"), strings.Join([]string{"list", "daemonsets", ""}, "-"), strings.Join([]string{"list", "deployments", ""}, "-"), + strings.Join([]string{"list", "jobs", ""}, "-"), + strings.Join([]string{"list", "ingress", ""}, "-"), ) } @@ -125,6 +130,26 @@ func testSyncNamespaceThatIsTerminating(t *testing.T, experimentalMode bool) { } } +func TestRetryOnConflictError(t *testing.T) { + mockClient := &testclient.Fake{} + numTries := 0 + retryOnce := func(kubeClient client.Interface, namespace *api.Namespace) (*api.Namespace, error) { + numTries++ + if numTries <= 1 { + return namespace, errors.NewConflict(namespace.Kind, namespace.Name, fmt.Errorf("ERROR!")) + } + return namespace, nil + } + namespace := &api.Namespace{} + _, err := retryOnConflictError(mockClient, namespace, retryOnce) + if err != nil { + t.Errorf("Unexpected error %v", err) + } + if numTries != 2 { + t.Errorf("Expected %v, but got %v", 2, numTries) + } +} + func TestSyncNamespaceThatIsTerminatingNonExperimental(t *testing.T) { testSyncNamespaceThatIsTerminating(t, false) } @@ -135,7 +160,7 @@ func TestSyncNamespaceThatIsTerminatingExperimental(t *testing.T) { func TestSyncNamespaceThatIsActive(t *testing.T) { mockClient := &testclient.Fake{} - testNamespace := api.Namespace{ + testNamespace := &api.Namespace{ ObjectMeta: api.ObjectMeta{ Name: "test", ResourceVersion: "1", diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/doc.go index 3174bef7c090..084754e699d3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/doc.go @@ -14,6 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package nodecontroller contains code for syncing cloud instances with +// Package node contains code for syncing cloud instances with // node registry -package nodecontroller +package node diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/nodecontroller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/nodecontroller.go index 2e9bdc0c85fd..aa93d587ccee 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/nodecontroller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/nodecontroller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package nodecontroller +package node import ( "errors" @@ -25,6 +25,7 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/record" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/cloudprovider" @@ -36,9 +37,7 @@ import ( ) var ( - ErrRegistration = errors.New("unable to register all nodes.") - ErrQueryIPAddress = errors.New("unable to query IP address.") - ErrCloudInstance = errors.New("cloud provider doesn't support instances.") + ErrCloudInstance = errors.New("cloud provider doesn't support instances.") ) const ( @@ -49,8 +48,8 @@ const ( ) type nodeStatusData struct { - probeTimestamp util.Time - readyTransitionTimestamp util.Time + probeTimestamp unversioned.Time + readyTransitionTimestamp unversioned.Time status api.NodeStatus } @@ -89,7 +88,7 @@ type NodeController struct { // This timestamp is to be used instead of LastProbeTime stored in Condition. We do this // to aviod the problem with time skew across the cluster. nodeStatusMap map[string]nodeStatusData - now func() util.Time + now func() unversioned.Time // Lock to access evictor workers evictorLock *sync.Mutex // workers that evicts pods from unresponsive nodes. @@ -106,7 +105,8 @@ func NewNodeController( cloud cloudprovider.Interface, kubeClient client.Interface, podEvictionTimeout time.Duration, - podEvictionLimiter util.RateLimiter, + deletionEvictionLimiter util.RateLimiter, + terminationEvictionLimiter util.RateLimiter, nodeMonitorGracePeriod time.Duration, nodeStartupGracePeriod time.Duration, nodeMonitorPeriod time.Duration, @@ -133,14 +133,14 @@ func NewNodeController( podEvictionTimeout: podEvictionTimeout, maximumGracePeriod: 5 * time.Minute, evictorLock: &evictorLock, - podEvictor: NewRateLimitedTimedQueue(podEvictionLimiter), - terminationEvictor: NewRateLimitedTimedQueue(podEvictionLimiter), + podEvictor: NewRateLimitedTimedQueue(deletionEvictionLimiter), + terminationEvictor: NewRateLimitedTimedQueue(terminationEvictionLimiter), nodeStatusMap: make(map[string]nodeStatusData), nodeMonitorGracePeriod: nodeMonitorGracePeriod, nodeMonitorPeriod: nodeMonitorPeriod, nodeStartupGracePeriod: nodeStartupGracePeriod, lookupIP: net.LookupIP, - now: util.Now, + now: unversioned.Now, clusterCIDR: clusterCIDR, allocateNodeCIDRs: allocateNodeCIDRs, } @@ -270,9 +270,6 @@ func (nc *NodeController) monitorNodeStatus() error { } } - if err != nil { - return err - } if nc.allocateNodeCIDRs { // TODO (cjcullen): Use pkg/controller/framework to watch nodes and // reduce lists/decouple this from monitoring status. @@ -380,13 +377,13 @@ func (nc *NodeController) reconcileNodeCIDRs(nodes *api.NodeList) { if node.Spec.PodCIDR == "" { podCIDR, found := availableCIDRs.PopAny() if !found { - nc.recordNodeStatusChange(&node, "No available CIDR") + nc.recordNodeStatusChange(&node, "CIDRNotAvailable") continue } glog.V(4).Infof("Assigning node %s CIDR %s", node.Name, podCIDR) node.Spec.PodCIDR = podCIDR if _, err := nc.kubeClient.Nodes().Update(&node); err != nil { - nc.recordNodeStatusChange(&node, "CIDR assignment failed") + nc.recordNodeStatusChange(&node, "CIDRAssignmentFailed") } } } @@ -417,7 +414,7 @@ func (nc *NodeController) recordNodeStatusChange(node *api.Node, new_status stri } // For a given node checks its conditions and tries to update it. Returns grace period to which given node -// is entitled, state of current and last observed Ready Condition, and an error if it ocured. +// is entitled, state of current and last observed Ready Condition, and an error if it occurred. func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, api.NodeCondition, *api.NodeCondition, error) { var err error var gracePeriod time.Duration @@ -460,7 +457,10 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap // - if 'LastProbeTime' have gone back in time its probably an error, currently we ignore it, // - currently only correct Ready State transition outside of Node Controller is marking it ready by Kubelet, we don't check // if that's the case, but it does not seem necessary. - savedCondition := nc.getCondition(&savedNodeStatus.status, api.NodeReady) + var savedCondition *api.NodeCondition + if found { + savedCondition = nc.getCondition(&savedNodeStatus.status, api.NodeReady) + } observedCondition := nc.getCondition(&node.Status, api.NodeReady) if !found { glog.Warningf("Missing timestamp for Node %s. Assuming now as a timestamp.", node.Name) @@ -488,7 +488,7 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap } nc.nodeStatusMap[node.Name] = savedNodeStatus } else if savedCondition != nil && observedCondition != nil && savedCondition.LastHeartbeatTime != observedCondition.LastHeartbeatTime { - var transitionTime util.Time + var transitionTime unversioned.Time // If ReadyCondition changed since the last time we checked, we update the transition timestamp to "now", // otherwise we leave it as it is. if savedCondition.LastTransitionTime != observedCondition.LastTransitionTime { @@ -515,7 +515,8 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap node.Status.Conditions = append(node.Status.Conditions, api.NodeCondition{ Type: api.NodeReady, Status: api.ConditionUnknown, - Reason: fmt.Sprintf("Kubelet never posted node status."), + Reason: "NodeStatusNeverUpdated", + Message: fmt.Sprintf("Kubelet never posted node status."), LastHeartbeatTime: node.CreationTimestamp, LastTransitionTime: nc.now(), }) @@ -524,7 +525,8 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap node.Name, nc.now().Time.Sub(savedNodeStatus.probeTimestamp.Time), lastReadyCondition) if lastReadyCondition.Status != api.ConditionUnknown { readyCondition.Status = api.ConditionUnknown - readyCondition.Reason = fmt.Sprintf("Kubelet stopped posting node status.") + readyCondition.Reason = "NodeStatusUnknown" + readyCondition.Message = fmt.Sprintf("Kubelet stopped posting node status.") // LastProbeTime is the last time we heard from kubelet. readyCondition.LastHeartbeatTime = lastReadyCondition.LastHeartbeatTime readyCondition.LastTransitionTime = nc.now() @@ -569,12 +571,15 @@ func (nc *NodeController) evictPods(nodeName string) bool { // cancelPodEviction removes any queued evictions, typically because the node is available again. It // returns true if an eviction was queued. func (nc *NodeController) cancelPodEviction(nodeName string) bool { - glog.V(2).Infof("Cancelling pod Eviction on Node: %v", nodeName) nc.evictorLock.Lock() defer nc.evictorLock.Unlock() wasDeleting := nc.podEvictor.Remove(nodeName) wasTerminating := nc.terminationEvictor.Remove(nodeName) - return wasDeleting || wasTerminating + if wasDeleting || wasTerminating { + glog.V(2).Infof("Cancelling pod Eviction on Node: %v", nodeName) + return true + } + return false } // deletePods will delete all pods from master running on given node, and return true @@ -600,8 +605,8 @@ func (nc *NodeController) deletePods(nodeName string) (bool, error) { continue } - glog.V(2).Infof("Delete pod %v", pod.Name) - nc.recorder.Eventf(&pod, "NodeControllerEviction", "Deleting Pod %s from Node %s", pod.Name, nodeName) + glog.V(2).Infof("Starting deletion of pod %v", pod.Name) + nc.recorder.Eventf(&pod, "NodeControllerEviction", "Marking for deletion Pod %s from Node %s", pod.Name, nodeName) if err := nc.kubeClient.Pods(pod.Namespace).Delete(pod.Name, nil); err != nil { return false, err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/nodecontroller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/nodecontroller_test.go index 2b58083cba15..abe3998ca9d3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/nodecontroller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/nodecontroller_test.go @@ -14,12 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -package nodecontroller +package node import ( "errors" "fmt" - "sort" "sync" "testing" "time" @@ -27,6 +26,7 @@ import ( "k8s.io/kubernetes/pkg/api" apierrors "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/fields" @@ -141,7 +141,7 @@ func (m *FakeNodeHandler) Watch(label labels.Selector, field fields.Selector, re } func TestMonitorNodeStatusEvictPods(t *testing.T) { - fakeNow := util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC) + fakeNow := unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC) evictionTimeout := 10 * time.Minute table := []struct { @@ -176,15 +176,15 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) { { ObjectMeta: api.ObjectMeta{ Name: "node0", - CreationTimestamp: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + CreationTimestamp: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeReady, Status: api.ConditionFalse, - LastHeartbeatTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastHeartbeatTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastTransitionTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), }, }, }, @@ -199,8 +199,8 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) { Type: api.NodeReady, Status: api.ConditionFalse, // Node status has just been updated, and is NotReady for 10min. - LastHeartbeatTime: util.Date(2015, 1, 1, 12, 9, 0, 0, time.UTC), - LastTransitionTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastHeartbeatTime: unversioned.Date(2015, 1, 1, 12, 9, 0, 0, time.UTC), + LastTransitionTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), }, }, }, @@ -214,15 +214,15 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) { { ObjectMeta: api.ObjectMeta{ Name: "node0", - CreationTimestamp: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + CreationTimestamp: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeReady, Status: api.ConditionFalse, - LastHeartbeatTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastHeartbeatTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastTransitionTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), }, }, }, @@ -237,8 +237,8 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) { Type: api.NodeReady, Status: api.ConditionFalse, // Node status has just been updated, and is NotReady for 1hr. - LastHeartbeatTime: util.Date(2015, 1, 1, 12, 59, 0, 0, time.UTC), - LastTransitionTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastHeartbeatTime: unversioned.Date(2015, 1, 1, 12, 59, 0, 0, time.UTC), + LastTransitionTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), }, }, }, @@ -252,15 +252,15 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) { { ObjectMeta: api.ObjectMeta{ Name: "node0", - CreationTimestamp: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + CreationTimestamp: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeReady, Status: api.ConditionUnknown, - LastHeartbeatTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastHeartbeatTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastTransitionTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), }, }, }, @@ -275,8 +275,8 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) { Type: api.NodeReady, Status: api.ConditionUnknown, // Node status was updated by nodecontroller 10min ago - LastHeartbeatTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastHeartbeatTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastTransitionTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), }, }, }, @@ -290,15 +290,15 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) { { ObjectMeta: api.ObjectMeta{ Name: "node0", - CreationTimestamp: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + CreationTimestamp: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeReady, Status: api.ConditionUnknown, - LastHeartbeatTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastHeartbeatTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastTransitionTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), }, }, }, @@ -313,8 +313,8 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) { Type: api.NodeReady, Status: api.ConditionUnknown, // Node status was updated by nodecontroller 1hr ago - LastHeartbeatTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastHeartbeatTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastTransitionTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), }, }, }, @@ -325,14 +325,14 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) { for _, item := range table { nodeController := NewNodeController(nil, item.fakeNodeHandler, - evictionTimeout, util.NewFakeRateLimiter(), testNodeMonitorGracePeriod, + evictionTimeout, util.NewFakeRateLimiter(), util.NewFakeRateLimiter(), testNodeMonitorGracePeriod, testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, false) - nodeController.now = func() util.Time { return fakeNow } + nodeController.now = func() unversioned.Time { return fakeNow } if err := nodeController.monitorNodeStatus(); err != nil { t.Errorf("unexpected error: %v", err) } if item.timeToPass > 0 { - nodeController.now = func() util.Time { return util.Time{Time: fakeNow.Add(item.timeToPass)} } + nodeController.now = func() unversioned.Time { return unversioned.Time{Time: fakeNow.Add(item.timeToPass)} } item.fakeNodeHandler.Existing[0].Status = item.newNodeStatus } if err := nodeController.monitorNodeStatus(); err != nil { @@ -365,7 +365,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) { } func TestMonitorNodeStatusUpdateStatus(t *testing.T) { - fakeNow := util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC) + fakeNow := unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC) table := []struct { fakeNodeHandler *FakeNodeHandler timeToPass time.Duration @@ -382,7 +382,7 @@ func TestMonitorNodeStatusUpdateStatus(t *testing.T) { { ObjectMeta: api.ObjectMeta{ Name: "node0", - CreationTimestamp: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + CreationTimestamp: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, }, }, @@ -393,15 +393,16 @@ func TestMonitorNodeStatusUpdateStatus(t *testing.T) { { ObjectMeta: api.ObjectMeta{ Name: "node0", - CreationTimestamp: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + CreationTimestamp: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeReady, Status: api.ConditionUnknown, - Reason: fmt.Sprintf("Kubelet never posted node status."), - LastHeartbeatTime: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + Reason: "NodeStatusNeverUpdated", + Message: fmt.Sprintf("Kubelet never posted node status."), + LastHeartbeatTime: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), LastTransitionTime: fakeNow, }, }, @@ -434,7 +435,7 @@ func TestMonitorNodeStatusUpdateStatus(t *testing.T) { { ObjectMeta: api.ObjectMeta{ Name: "node0", - CreationTimestamp: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + CreationTimestamp: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ @@ -442,8 +443,8 @@ func TestMonitorNodeStatusUpdateStatus(t *testing.T) { Type: api.NodeReady, Status: api.ConditionTrue, // Node status hasn't been updated for 1hr. - LastHeartbeatTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastHeartbeatTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastTransitionTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), }, }, Capacity: api.ResourceList{ @@ -466,8 +467,8 @@ func TestMonitorNodeStatusUpdateStatus(t *testing.T) { Type: api.NodeReady, Status: api.ConditionTrue, // Node status hasn't been updated for 1hr. - LastHeartbeatTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastHeartbeatTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastTransitionTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), }, }, Capacity: api.ResourceList{ @@ -479,16 +480,17 @@ func TestMonitorNodeStatusUpdateStatus(t *testing.T) { { ObjectMeta: api.ObjectMeta{ Name: "node0", - CreationTimestamp: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + CreationTimestamp: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeReady, Status: api.ConditionUnknown, - Reason: fmt.Sprintf("Kubelet stopped posting node status."), - LastHeartbeatTime: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: util.Time{Time: util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC).Add(time.Hour)}, + Reason: "NodeStatusStopUpdated", + Message: fmt.Sprintf("Kubelet stopped posting node status."), + LastHeartbeatTime: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), + LastTransitionTime: unversioned.Time{Time: unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC).Add(time.Hour)}, }, }, Capacity: api.ResourceList{ @@ -510,7 +512,7 @@ func TestMonitorNodeStatusUpdateStatus(t *testing.T) { { ObjectMeta: api.ObjectMeta{ Name: "node0", - CreationTimestamp: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + CreationTimestamp: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ @@ -541,13 +543,13 @@ func TestMonitorNodeStatusUpdateStatus(t *testing.T) { for _, item := range table { nodeController := NewNodeController(nil, item.fakeNodeHandler, 5*time.Minute, util.NewFakeRateLimiter(), - testNodeMonitorGracePeriod, testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, false) - nodeController.now = func() util.Time { return fakeNow } + util.NewFakeRateLimiter(), testNodeMonitorGracePeriod, testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, false) + nodeController.now = func() unversioned.Time { return fakeNow } if err := nodeController.monitorNodeStatus(); err != nil { t.Errorf("unexpected error: %v", err) } if item.timeToPass > 0 { - nodeController.now = func() util.Time { return util.Time{Time: fakeNow.Add(item.timeToPass)} } + nodeController.now = func() unversioned.Time { return unversioned.Time{Time: fakeNow.Add(item.timeToPass)} } item.fakeNodeHandler.Existing[0].Status = item.newNodeStatus if err := nodeController.monitorNodeStatus(); err != nil { t.Errorf("unexpected error: %v", err) @@ -564,13 +566,13 @@ func TestMonitorNodeStatusUpdateStatus(t *testing.T) { } func TestNodeDeletion(t *testing.T) { - fakeNow := util.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC) + fakeNow := unversioned.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC) fakeNodeHandler := &FakeNodeHandler{ Existing: []*api.Node{ { ObjectMeta: api.ObjectMeta{ Name: "node0", - CreationTimestamp: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + CreationTimestamp: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ @@ -594,7 +596,7 @@ func TestNodeDeletion(t *testing.T) { { ObjectMeta: api.ObjectMeta{ Name: "node1", - CreationTimestamp: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + CreationTimestamp: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ @@ -619,9 +621,9 @@ func TestNodeDeletion(t *testing.T) { Fake: testclient.NewSimpleFake(&api.PodList{Items: []api.Pod{*newPod("pod0", "node0"), *newPod("pod1", "node1")}}), } - nodeController := NewNodeController(nil, fakeNodeHandler, 5*time.Minute, util.NewFakeRateLimiter(), + nodeController := NewNodeController(nil, fakeNodeHandler, 5*time.Minute, util.NewFakeRateLimiter(), util.NewFakeRateLimiter(), testNodeMonitorGracePeriod, testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, false) - nodeController.now = func() util.Time { return fakeNow } + nodeController.now = func() unversioned.Time { return fakeNow } if err := nodeController.monitorNodeStatus(); err != nil { t.Errorf("unexpected error: %v", err) } @@ -663,35 +665,6 @@ func newPod(name, host string) *api.Pod { return &api.Pod{ObjectMeta: api.ObjectMeta{Name: name}, Spec: api.PodSpec{NodeName: host}} } -func sortedNodeNames(nodes []*api.Node) []string { - nodeNames := []string{} - for _, node := range nodes { - nodeNames = append(nodeNames, node.Name) - } - sort.Strings(nodeNames) - return nodeNames -} - -func sortedNodeAddresses(nodes []*api.Node) []string { - nodeAddresses := []string{} - for _, node := range nodes { - for _, addr := range node.Status.Addresses { - nodeAddresses = append(nodeAddresses, addr.Address) - } - } - sort.Strings(nodeAddresses) - return nodeAddresses -} - -func sortedNodeExternalIDs(nodes []*api.Node) []string { - nodeExternalIDs := []string{} - for _, node := range nodes { - nodeExternalIDs = append(nodeExternalIDs, node.Spec.ExternalID) - } - sort.Strings(nodeExternalIDs) - return nodeExternalIDs -} - func contains(node *api.Node, nodes []*api.Node) bool { for i := 0; i < len(nodes); i++ { if node.Name == nodes[i].Name { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue.go index 71950f54a476..4545243a2e21 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue.go @@ -14,13 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -package nodecontroller +package node import ( "container/heap" "sync" "time" + "github.com/golang/glog" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" ) @@ -163,16 +164,14 @@ func (q *RateLimitedTimedQueue) Try(fn ActionFunc) { for ok { // rate limit the queue checking if !q.limiter.CanAccept() { + glog.V(10).Info("Try rate limitted...") // Try again later break } now := now() if now.Before(val.ProcessAt) { - q.queue.Replace(val) - val, ok = q.queue.Head() - // we do not sleep here because other values may be added at the front of the queue - continue + break } if ok, wait := fn(val); !ok { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue_test.go index 762e82638224..e0bccd54e92e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package nodecontroller +package node import ( "reflect" @@ -175,10 +175,10 @@ func TestTryOrdering(t *testing.T) { order = append(order, value.Value) return true, 0 }) - if !reflect.DeepEqual(order, []string{"first", "third", "second"}) { + if !reflect.DeepEqual(order, []string{"first", "third"}) { t.Fatalf("order was wrong: %v", order) } - if count != 4 { + if count != 3 { t.Fatalf("unexpected iterations: %d", count) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_claim_binder_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_claim_binder_controller.go index 1cb45dff4bbe..ee1c566d5f3c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_claim_binder_controller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_claim_binder_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package volumeclaimbinder +package persistentvolume import ( "fmt" @@ -63,6 +63,7 @@ func NewPersistentVolumeClaimBinder(kubeClient client.Interface, syncPeriod time }, }, &api.PersistentVolume{}, + // TODO: Can we have much longer period here? syncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: binder.addVolume, @@ -80,6 +81,7 @@ func NewPersistentVolumeClaimBinder(kubeClient client.Interface, syncPeriod time }, }, &api.PersistentVolumeClaim{}, + // TODO: Can we have much longer period here? syncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: binder.addClaim, @@ -229,6 +231,8 @@ func syncVolume(volumeIndex *persistentVolumeOrderedIndex, binderClient binderCl } else { // another process is watching for released volumes. // PersistentVolumeReclaimPolicy is set per PersistentVolume + // Recycle - sets the PV to Pending and back under this controller's management + // Delete - delete events are handled by this controller's watch. PVs are removed from the index. } // volumes are removed by processes external to this binder and must be removed from the cluster diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_claim_binder_controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_claim_binder_controller_test.go index 352b44aa5b59..98adc82c4f48 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_claim_binder_controller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_claim_binder_controller_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package volumeclaimbinder +package persistentvolume import ( "reflect" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_index_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_index_test.go index 143c74a81e3c..154d47e3f425 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_index_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_index_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package volumeclaimbinder +package persistentvolume import ( "testing" @@ -484,3 +484,78 @@ func createTestVolumes() []*api.PersistentVolume { }, } } + +func TestFindingPreboundVolumes(t *testing.T) { + pv1 := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: "pv1", + Annotations: map[string]string{}, + }, + Spec: api.PersistentVolumeSpec{ + Capacity: api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("1Gi")}, + PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{}}, + AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, + }, + } + + pv5 := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: "pv5", + Annotations: map[string]string{}, + }, + Spec: api.PersistentVolumeSpec{ + Capacity: api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("5Gi")}, + PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{}}, + AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, + }, + } + + pv8 := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: "pv8", + Annotations: map[string]string{}, + }, + Spec: api.PersistentVolumeSpec{ + Capacity: api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("8Gi")}, + PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{}}, + AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, + }, + } + + claim := &api.PersistentVolumeClaim{ + ObjectMeta: api.ObjectMeta{ + Name: "claim01", + Namespace: "myns", + }, + Spec: api.PersistentVolumeClaimSpec{ + AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, + Resources: api.ResourceRequirements{Requests: api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("1Gi")}}, + }, + } + + index := NewPersistentVolumeOrderedIndex() + index.Add(pv1) + index.Add(pv5) + index.Add(pv8) + + // expected exact match on size + volume, _ := index.FindBestMatchForClaim(claim) + if volume.Name != pv1.Name { + t.Errorf("Expected %s but got volume %s instead", pv1.Name, volume.Name) + } + + // pretend the exact match is pre-bound. should get the next size up. + pv1.Annotations[createdForKey] = "some/other/claim" + volume, _ = index.FindBestMatchForClaim(claim) + if volume.Name != pv5.Name { + t.Errorf("Expected %s but got volume %s instead", pv5.Name, volume.Name) + } + + // pretend the exact match is available but the largest volume is pre-bound to the claim. + delete(pv1.Annotations, createdForKey) + pv8.Annotations[createdForKey] = "myns/claim01" + volume, _ = index.FindBestMatchForClaim(claim) + if volume.Name != pv8.Name { + t.Errorf("Expected %s but got volume %s instead", pv8.Name, volume.Name) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_recycler_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_recycler_controller.go index fadbe023b0e8..67380be0db84 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_recycler_controller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_recycler_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package volumeclaimbinder +package persistentvolume import ( "fmt" @@ -30,6 +30,7 @@ import ( "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/types" + ioutil "k8s.io/kubernetes/pkg/util/io" "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/watch" @@ -70,6 +71,7 @@ func NewPersistentVolumeRecycler(kubeClient client.Interface, syncPeriod time.Du }, }, &api.PersistentVolume{}, + // TODO: Can we have much longer period here? syncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { @@ -99,12 +101,13 @@ func (recycler *PersistentVolumeRecycler) reclaimVolume(pv *api.PersistentVolume return fmt.Errorf("PersistentVolume[%s] phase is %s, expected %s. Skipping.", pv.Name, latest.Status.Phase, api.VolumeReleased) } - // handleRecycle blocks until completion + // both handleRecycle and handleDelete block until completion // TODO: allow parallel recycling operations to increase throughput - // TODO implement handleDelete in a separate PR w/ cloud volumes switch pv.Spec.PersistentVolumeReclaimPolicy { case api.PersistentVolumeReclaimRecycle: err = recycler.handleRecycle(pv) + case api.PersistentVolumeReclaimDelete: + err = recycler.handleDelete(pv) case api.PersistentVolumeReclaimRetain: glog.V(5).Infof("Volume %s is set to retain after release. Skipping.\n", pv.Name) default: @@ -161,6 +164,49 @@ func (recycler *PersistentVolumeRecycler) handleRecycle(pv *api.PersistentVolume return nil } +func (recycler *PersistentVolumeRecycler) handleDelete(pv *api.PersistentVolume) error { + glog.V(5).Infof("Deleting PersistentVolume[%s]\n", pv.Name) + + currentPhase := pv.Status.Phase + nextPhase := currentPhase + + spec := volume.NewSpecFromPersistentVolume(pv, false) + plugin, err := recycler.pluginMgr.FindDeletablePluginBySpec(spec) + if err != nil { + return fmt.Errorf("Could not find deletable volume plugin for spec: %+v", err) + } + deleter, err := plugin.NewDeleter(spec) + if err != nil { + return fmt.Errorf("could not obtain Deleter for spec: %+v", err) + } + // blocks until completion + err = deleter.Delete() + if err != nil { + glog.Errorf("PersistentVolume[%s] failed deletion: %+v", pv.Name, err) + pv.Status.Message = fmt.Sprintf("Deletion error: %s", err) + nextPhase = api.VolumeFailed + } else { + glog.V(5).Infof("PersistentVolume[%s] successfully deleted through plugin\n", pv.Name) + // after successful deletion through the plugin, we can also remove the PV from the cluster + err = recycler.client.DeletePersistentVolume(pv) + if err != nil { + return fmt.Errorf("error deleting persistent volume: %+v", err) + } + } + + if currentPhase != nextPhase { + glog.V(5).Infof("PersistentVolume[%s] changing phase from %s to %s\n", pv.Name, currentPhase, nextPhase) + pv.Status.Phase = nextPhase + _, err := recycler.client.UpdatePersistentVolumeStatus(pv) + if err != nil { + // Rollback to previous phase + pv.Status.Phase = currentPhase + } + } + + return nil +} + // Run starts this recycler's control loops func (recycler *PersistentVolumeRecycler) Run() { glog.V(5).Infof("Starting PersistentVolumeRecycler\n") @@ -183,6 +229,7 @@ func (recycler *PersistentVolumeRecycler) Stop() { type recyclerClient interface { GetPersistentVolume(name string) (*api.PersistentVolume, error) UpdatePersistentVolume(volume *api.PersistentVolume) (*api.PersistentVolume, error) + DeletePersistentVolume(volume *api.PersistentVolume) error UpdatePersistentVolumeStatus(volume *api.PersistentVolume) (*api.PersistentVolume, error) } @@ -202,6 +249,10 @@ func (c *realRecyclerClient) UpdatePersistentVolume(volume *api.PersistentVolume return c.client.PersistentVolumes().Update(volume) } +func (c *realRecyclerClient) DeletePersistentVolume(volume *api.PersistentVolume) error { + return c.client.PersistentVolumes().Delete(volume.Name) +} + func (c *realRecyclerClient) UpdatePersistentVolumeStatus(volume *api.PersistentVolume) (*api.PersistentVolume, error) { return c.client.PersistentVolumes().UpdateStatus(volume) } @@ -224,14 +275,22 @@ func (f *PersistentVolumeRecycler) GetKubeClient() client.Interface { return f.kubeClient } -func (f *PersistentVolumeRecycler) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (f *PersistentVolumeRecycler) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { return nil, fmt.Errorf("NewWrapperBuilder not supported by PVClaimBinder's VolumeHost implementation") } -func (f *PersistentVolumeRecycler) NewWrapperCleaner(spec *volume.Spec, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { +func (f *PersistentVolumeRecycler) NewWrapperCleaner(spec *volume.Spec, podUID types.UID) (volume.Cleaner, error) { return nil, fmt.Errorf("NewWrapperCleaner not supported by PVClaimBinder's VolumeHost implementation") } func (f *PersistentVolumeRecycler) GetCloudProvider() cloudprovider.Interface { return nil } + +func (f *PersistentVolumeRecycler) GetMounter() mount.Interface { + return nil +} + +func (f *PersistentVolumeRecycler) GetWriter() ioutil.Writer { + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/types.go index bcce67039e4c..6f38c36b86da 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/persistentvolume/types.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package volumeclaimbinder +package persistentvolume import ( "fmt" @@ -25,6 +25,13 @@ import ( "k8s.io/kubernetes/pkg/client/cache" ) +const ( + // A PV created specifically for one claim must contain this annotation in order to bind to the claim. + // The value must be the namespace and name of the claim being bound to (i.e, claim.Namespace/claim.Name) + // This is an experimental feature and likely to change in the future. + createdForKey = "volume.extensions.kubernetes.io/provisioned-for" +) + // persistentVolumeOrderedIndex is a cache.Store that keeps persistent volumes indexed by AccessModes and ordered by storage capacity. type persistentVolumeOrderedIndex struct { cache.Indexer @@ -73,8 +80,8 @@ func (pvIndex *persistentVolumeOrderedIndex) ListByAccessModes(modes []api.Persi type matchPredicate func(compareThis, toThis *api.PersistentVolume) bool // Find returns the nearest PV from the ordered list or nil if a match is not found -func (pvIndex *persistentVolumeOrderedIndex) Find(pv *api.PersistentVolume, matchPredicate matchPredicate) (*api.PersistentVolume, error) { - // the 'pv' argument is a synthetic PV with capacity and accessmodes set according to the user's PersistentVolumeClaim. +func (pvIndex *persistentVolumeOrderedIndex) Find(searchPV *api.PersistentVolume, matchPredicate matchPredicate) (*api.PersistentVolume, error) { + // the 'searchPV' argument is a synthetic PV with capacity and accessmodes set according to the user's PersistentVolumeClaim. // the synthetic pv arg is, therefore, a request for a storage resource. // // PVs are indexed by their access modes to allow easier searching. Each index is the string representation of a set of access modes. @@ -85,7 +92,7 @@ func (pvIndex *persistentVolumeOrderedIndex) Find(pv *api.PersistentVolume, matc // // Searches are performed against a set of access modes, so we can attempt not only the exact matching modes but also // potential matches (the GCEPD example above). - allPossibleModes := pvIndex.allPossibleMatchingAccessModes(pv.Spec.AccessModes) + allPossibleModes := pvIndex.allPossibleMatchingAccessModes(searchPV.Spec.AccessModes) for _, modes := range allPossibleModes { volumes, err := pvIndex.ListByAccessModes(modes) @@ -93,16 +100,31 @@ func (pvIndex *persistentVolumeOrderedIndex) Find(pv *api.PersistentVolume, matc return nil, err } - // volumes are sorted by size but some may be bound. - // remove bound volumes for easy binary search by size + // volumes are sorted by size but some may be bound or earmarked for a specific claim. + // filter those volumes for easy binary search by size + // return the exact pre-binding match, if found unboundVolumes := []*api.PersistentVolume{} - for _, v := range volumes { - if v.Spec.ClaimRef == nil { - unboundVolumes = append(unboundVolumes, v) + for _, volume := range volumes { + // check for current binding + if volume.Spec.ClaimRef != nil { + continue + } + + // check for pre-bind where the volume is intended for one specific claim + if createdFor, ok := volume.Annotations[createdForKey]; ok { + if createdFor != searchPV.Annotations[createdForKey] { + // the volume is pre-bound and does not match the search criteria. + continue + } + // exact annotation match! No search required. + return volume, nil } + + // volume isn't currently bound or pre-bound. + unboundVolumes = append(unboundVolumes, volume) } - i := sort.Search(len(unboundVolumes), func(i int) bool { return matchPredicate(pv, unboundVolumes[i]) }) + i := sort.Search(len(unboundVolumes), func(i int) bool { return matchPredicate(searchPV, unboundVolumes[i]) }) if i < len(unboundVolumes) { return unboundVolumes[i], nil } @@ -110,9 +132,14 @@ func (pvIndex *persistentVolumeOrderedIndex) Find(pv *api.PersistentVolume, matc return nil, nil } -// FindByAccessModesAndStorageCapacity is a convenience method that calls Find w/ requisite matchPredicate for storage -func (pvIndex *persistentVolumeOrderedIndex) FindByAccessModesAndStorageCapacity(modes []api.PersistentVolumeAccessMode, qty resource.Quantity) (*api.PersistentVolume, error) { +// findByAccessModesAndStorageCapacity is a convenience method that calls Find w/ requisite matchPredicate for storage +func (pvIndex *persistentVolumeOrderedIndex) findByAccessModesAndStorageCapacity(prebindKey string, modes []api.PersistentVolumeAccessMode, qty resource.Quantity) (*api.PersistentVolume, error) { pv := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Annotations: map[string]string{ + createdForKey: prebindKey, + }, + }, Spec: api.PersistentVolumeSpec{ AccessModes: modes, Capacity: api.ResourceList{ @@ -125,7 +152,7 @@ func (pvIndex *persistentVolumeOrderedIndex) FindByAccessModesAndStorageCapacity // FindBestMatchForClaim is a convenience method that finds a volume by the claim's AccessModes and requests for Storage func (pvIndex *persistentVolumeOrderedIndex) FindBestMatchForClaim(claim *api.PersistentVolumeClaim) (*api.PersistentVolume, error) { - return pvIndex.FindByAccessModesAndStorageCapacity(claim.Spec.AccessModes, claim.Spec.Resources.Requests[api.ResourceName(api.ResourceStorage)]) + return pvIndex.findByAccessModesAndStorageCapacity(fmt.Sprintf("%s/%s", claim.Namespace, claim.Name), claim.Spec.AccessModes, claim.Spec.Resources.Requests[api.ResourceName(api.ResourceStorage)]) } // byCapacity is used to order volumes by ascending storage size diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal.go index 938616c81160..3071feddc1d0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal.go @@ -23,7 +23,9 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/client/record" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/controller/podautoscaler/metrics" "k8s.io/kubernetes/pkg/fields" @@ -32,9 +34,6 @@ import ( ) const ( - heapsterNamespace = "kube-system" - heapsterService = "monitoring-heapster" - // Usage shoud exceed the tolerance before we start downscale or upscale the pods. // TODO: make it a flag or HPA spec element. tolerance = 0.1 @@ -43,15 +42,21 @@ const ( type HorizontalController struct { client client.Interface metricsClient metrics.MetricsClient + eventRecorder record.EventRecorder } -var downscaleForbiddenWindow, _ = time.ParseDuration("20m") -var upscaleForbiddenWindow, _ = time.ParseDuration("3m") +var downscaleForbiddenWindow = 5 * time.Minute +var upscaleForbiddenWindow = 3 * time.Minute func NewHorizontalController(client client.Interface, metricsClient metrics.MetricsClient) *HorizontalController { + broadcaster := record.NewBroadcaster() + broadcaster.StartRecordingToSink(client.Events("")) + recorder := broadcaster.NewRecorder(api.EventSource{Component: "horizontal-pod-autoscaler"}) + return &HorizontalController{ client: client, metricsClient: metricsClient, + eventRecorder: recorder, } } @@ -63,92 +68,103 @@ func (a *HorizontalController) Run(syncPeriod time.Duration) { }, syncPeriod, util.NeverStop) } -func (a *HorizontalController) reconcileAutoscalers() error { - ns := api.NamespaceAll - list, err := a.client.Experimental().HorizontalPodAutoscalers(ns).List(labels.Everything(), fields.Everything()) +func (a *HorizontalController) reconcileAutoscaler(hpa extensions.HorizontalPodAutoscaler) error { + reference := fmt.Sprintf("%s/%s/%s", hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Namespace, hpa.Spec.ScaleRef.Name) + + scale, err := a.client.Extensions().Scales(hpa.Spec.ScaleRef.Namespace).Get(hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Name) if err != nil { - return fmt.Errorf("error listing nodes: %v", err) + a.eventRecorder.Event(&hpa, "FailedGetScale", err.Error()) + return fmt.Errorf("failed to query scale subresource for %s: %v", reference, err) } - for _, hpa := range list.Items { - reference := fmt.Sprintf("%s/%s/%s", hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Namespace, hpa.Spec.ScaleRef.Name) + currentReplicas := scale.Status.Replicas + currentConsumption, err := a.metricsClient. + ResourceConsumption(hpa.Spec.ScaleRef.Namespace). + Get(hpa.Spec.Target.Resource, scale.Status.Selector) - scale, err := a.client.Experimental().Scales(hpa.Spec.ScaleRef.Namespace).Get(hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Name) - if err != nil { - glog.Warningf("Failed to query scale subresource for %s: %v", reference, err) - continue - } - currentReplicas := scale.Status.Replicas - currentConsumption, err := a.metricsClient.ResourceConsumption(hpa.Spec.ScaleRef.Namespace).Get(hpa.Spec.Target.Resource, - scale.Status.Selector) + // TODO: what to do on partial errors (like metrics obtained for 75% of pods). + if err != nil { + a.eventRecorder.Event(&hpa, "FailedGetMetrics", err.Error()) + return fmt.Errorf("failed to get metrics for %s: %v", reference, err) + } - // TODO: what to do on partial errors (like metrics obtained for 75% of pods). - if err != nil { - glog.Warningf("Error while getting metrics for %s: %v", reference, err) - continue - } + usageRatio := float64(currentConsumption.Quantity.MilliValue()) / float64(hpa.Spec.Target.Quantity.MilliValue()) + desiredReplicas := int(math.Ceil(usageRatio * float64(currentReplicas))) - usageRatio := float64(currentConsumption.Quantity.MilliValue()) / float64(hpa.Spec.Target.Quantity.MilliValue()) - desiredReplicas := int(math.Ceil(usageRatio * float64(currentReplicas))) + if desiredReplicas < hpa.Spec.MinReplicas { + desiredReplicas = hpa.Spec.MinReplicas + } - if desiredReplicas < hpa.Spec.MinCount { - desiredReplicas = hpa.Spec.MinCount - } + // TODO: remove when pod ideling is done. + if desiredReplicas == 0 { + desiredReplicas = 1 + } - // TODO: remove when pod ideling is done. - if desiredReplicas == 0 { - desiredReplicas = 1 + if desiredReplicas > hpa.Spec.MaxReplicas { + desiredReplicas = hpa.Spec.MaxReplicas + } + now := time.Now() + rescale := false + + if desiredReplicas != currentReplicas { + // Going down only if the usageRatio dropped significantly below the target + // and there was no rescaling in the last downscaleForbiddenWindow. + if desiredReplicas < currentReplicas && usageRatio < (1-tolerance) && + (hpa.Status.LastScaleTimestamp == nil || + hpa.Status.LastScaleTimestamp.Add(downscaleForbiddenWindow).Before(now)) { + rescale = true } - if desiredReplicas > hpa.Spec.MaxCount { - desiredReplicas = hpa.Spec.MaxCount - } - now := time.Now() - rescale := false - - if desiredReplicas != currentReplicas { - // Going down only if the usageRatio dropped significantly below the target - // and there was no rescaling in the last downscaleForbiddenWindow. - if desiredReplicas < currentReplicas && usageRatio < (1-tolerance) && - (hpa.Status == nil || hpa.Status.LastScaleTimestamp == nil || - hpa.Status.LastScaleTimestamp.Add(downscaleForbiddenWindow).Before(now)) { - rescale = true - } - - // Going up only if the usage ratio increased significantly above the target - // and there was no rescaling in the last upscaleForbiddenWindow. - if desiredReplicas > currentReplicas && usageRatio > (1+tolerance) && - (hpa.Status == nil || hpa.Status.LastScaleTimestamp == nil || - hpa.Status.LastScaleTimestamp.Add(upscaleForbiddenWindow).Before(now)) { - rescale = true - } + // Going up only if the usage ratio increased significantly above the target + // and there was no rescaling in the last upscaleForbiddenWindow. + if desiredReplicas > currentReplicas && usageRatio > (1+tolerance) && + (hpa.Status.LastScaleTimestamp == nil || + hpa.Status.LastScaleTimestamp.Add(upscaleForbiddenWindow).Before(now)) { + rescale = true } + } - if rescale { - scale.Spec.Replicas = desiredReplicas - _, err = a.client.Experimental().Scales(hpa.Namespace).Update(hpa.Spec.ScaleRef.Kind, scale) - if err != nil { - glog.Warningf("Failed to rescale %s: %v", reference, err) - continue - } - } else { - desiredReplicas = currentReplicas + if rescale { + scale.Spec.Replicas = desiredReplicas + _, err = a.client.Extensions().Scales(hpa.Namespace).Update(hpa.Spec.ScaleRef.Kind, scale) + if err != nil { + a.eventRecorder.Eventf(&hpa, "FailedRescale", "New size: %d; error: %v", desiredReplicas, err.Error()) + return fmt.Errorf("failed to rescale %s: %v", reference, err) } + a.eventRecorder.Eventf(&hpa, "SuccessfulRescale", "New size: %d", desiredReplicas) + glog.Infof("Successfull rescale of %s, old size: %d, new size: %d, usage ratio: %f", + hpa.Name, currentReplicas, desiredReplicas, usageRatio) + } else { + desiredReplicas = currentReplicas + } - status := experimental.HorizontalPodAutoscalerStatus{ - CurrentReplicas: currentReplicas, - DesiredReplicas: desiredReplicas, - CurrentConsumption: currentConsumption, - } - hpa.Status = &status - if rescale { - now := util.NewTime(now) - hpa.Status.LastScaleTimestamp = &now - } + hpa.Status = extensions.HorizontalPodAutoscalerStatus{ + CurrentReplicas: currentReplicas, + DesiredReplicas: desiredReplicas, + CurrentConsumption: currentConsumption, + } + if rescale { + now := unversioned.NewTime(now) + hpa.Status.LastScaleTimestamp = &now + } + + _, err = a.client.Extensions().HorizontalPodAutoscalers(hpa.Namespace).UpdateStatus(&hpa) + if err != nil { + a.eventRecorder.Event(&hpa, "FailedUpdateStatus", err.Error()) + return fmt.Errorf("failed to update status for %s: %v", hpa.Name, err) + } + return nil +} - _, err = a.client.Experimental().HorizontalPodAutoscalers(hpa.Namespace).Update(&hpa) +func (a *HorizontalController) reconcileAutoscalers() error { + ns := api.NamespaceAll + list, err := a.client.Extensions().HorizontalPodAutoscalers(ns).List(labels.Everything(), fields.Everything()) + if err != nil { + return fmt.Errorf("error listing nodes: %v", err) + } + for _, hpa := range list.Items { + err := a.reconcileAutoscaler(hpa) if err != nil { - glog.Warningf("Failed to update HorizontalPodAutoscaler %s: %v", hpa.Name, err) - continue + glog.Warningf("Failed to reconcile %s: %v", hpa.Name, err) } } return nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal_test.go index 1bb03ae810e3..4b96a6758783 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal_test.go @@ -17,187 +17,345 @@ limitations under the License. package podautoscaler import ( + "encoding/json" "fmt" - "net/http" - "net/http/httptest" + "io" "testing" + "time" "k8s.io/kubernetes/pkg/api" _ "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/resource" - "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/controller/podautoscaler/metrics" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" - "github.com/golang/glog" + heapster "k8s.io/heapster/api/v1/types" + "github.com/stretchr/testify/assert" ) -const ( - namespace = api.NamespaceDefault - rcName = "app-rc" - podNameLabel = "app" - hpaName = "foo" +func (w fakeResponseWrapper) DoRaw() ([]byte, error) { + return w.raw, nil +} - hpaListHandler = "HpaList" - scaleHandler = "Scale" - updateHpaHandler = "HpaUpdate" -) +func (w fakeResponseWrapper) Stream() (io.ReadCloser, error) { + return nil, nil +} -type serverResponse struct { - statusCode int - obj interface{} +func newFakeResponseWrapper(raw []byte) fakeResponseWrapper { + return fakeResponseWrapper{raw: raw} } -type fakeMetricsClient struct { - consumption metrics.ResourceConsumptionClient +type fakeResponseWrapper struct { + raw []byte } -type fakeResourceConsumptionClient struct { - metrics map[api.ResourceName]experimental.ResourceConsumption +type testCase struct { + minReplicas int + maxReplicas int + initialReplicas int + desiredReplicas int + targetResource api.ResourceName + targetLevel resource.Quantity + reportedLevels []uint64 + scaleUpdated bool + eventCreated bool + verifyEvents bool } -func (f *fakeMetricsClient) ResourceConsumption(namespace string) metrics.ResourceConsumptionClient { - return f.consumption +func (tc *testCase) prepareTestClient(t *testing.T) *testclient.Fake { + namespace := "test-namespace" + hpaName := "test-hpa" + rcName := "test-rc" + podNamePrefix := "test-pod" + + tc.scaleUpdated = false + tc.eventCreated = false + + fakeClient := &testclient.Fake{} + fakeClient.AddReactor("list", "horizontalpodautoscalers", func(action testclient.Action) (handled bool, ret runtime.Object, err error) { + obj := &extensions.HorizontalPodAutoscalerList{ + Items: []extensions.HorizontalPodAutoscaler{ + { + ObjectMeta: api.ObjectMeta{ + Name: hpaName, + Namespace: namespace, + SelfLink: "experimental/v1/namespaces/" + namespace + "/horizontalpodautoscalers/" + hpaName, + }, + Spec: extensions.HorizontalPodAutoscalerSpec{ + ScaleRef: &extensions.SubresourceReference{ + Kind: "replicationController", + Name: rcName, + Namespace: namespace, + Subresource: "scale", + }, + MinReplicas: tc.minReplicas, + MaxReplicas: tc.maxReplicas, + Target: extensions.ResourceConsumption{Resource: tc.targetResource, Quantity: tc.targetLevel}, + }, + }, + }, + } + return true, obj, nil + }) + + fakeClient.AddReactor("get", "replicationController", func(action testclient.Action) (handled bool, ret runtime.Object, err error) { + obj := &extensions.Scale{ + ObjectMeta: api.ObjectMeta{ + Name: rcName, + Namespace: namespace, + }, + Spec: extensions.ScaleSpec{ + Replicas: tc.initialReplicas, + }, + Status: extensions.ScaleStatus{ + Replicas: tc.initialReplicas, + Selector: map[string]string{"name": podNamePrefix}, + }, + } + return true, obj, nil + }) + + fakeClient.AddReactor("list", "pods", func(action testclient.Action) (handled bool, ret runtime.Object, err error) { + obj := &api.PodList{} + for i := 0; i < tc.initialReplicas; i++ { + podName := fmt.Sprintf("%s-%d", podNamePrefix, i) + pod := api.Pod{ + Status: api.PodStatus{ + Phase: api.PodRunning, + }, + ObjectMeta: api.ObjectMeta{ + Name: podName, + Namespace: namespace, + Labels: map[string]string{ + "name": podNamePrefix, + }, + }, + } + obj.Items = append(obj.Items, pod) + } + return true, obj, nil + }) + + fakeClient.AddProxyReactor("services", func(action testclient.Action) (handled bool, ret client.ResponseWrapper, err error) { + timestamp := time.Now() + metrics := heapster.MetricResultList{} + for _, level := range tc.reportedLevels { + metric := heapster.MetricResult{ + Metrics: []heapster.MetricPoint{{timestamp, level}}, + LatestTimestamp: timestamp, + } + metrics.Items = append(metrics.Items, metric) + } + heapsterRawMemResponse, _ := json.Marshal(&metrics) + return true, newFakeResponseWrapper(heapsterRawMemResponse), nil + }) + + fakeClient.AddReactor("update", "replicationController", func(action testclient.Action) (handled bool, ret runtime.Object, err error) { + obj := action.(testclient.UpdateAction).GetObject().(*extensions.Scale) + replicas := action.(testclient.UpdateAction).GetObject().(*extensions.Scale).Spec.Replicas + assert.Equal(t, tc.desiredReplicas, replicas) + tc.scaleUpdated = true + return true, obj, nil + }) + + fakeClient.AddReactor("update", "horizontalpodautoscalers", func(action testclient.Action) (handled bool, ret runtime.Object, err error) { + obj := action.(testclient.UpdateAction).GetObject().(*extensions.HorizontalPodAutoscaler) + assert.Equal(t, namespace, obj.Namespace) + assert.Equal(t, hpaName, obj.Name) + assert.Equal(t, tc.desiredReplicas, obj.Status.DesiredReplicas) + return true, obj, nil + }) + + fakeClient.AddReactor("*", "events", func(action testclient.Action) (handled bool, ret runtime.Object, err error) { + obj := action.(testclient.CreateAction).GetObject().(*api.Event) + if tc.verifyEvents { + assert.Equal(t, "SuccessfulRescale", obj.Reason) + assert.Equal(t, fmt.Sprintf("New size: %d", tc.desiredReplicas), obj.Message) + } + tc.eventCreated = true + return true, obj, nil + }) + + return fakeClient } -func (f *fakeResourceConsumptionClient) Get(resource api.ResourceName, selector map[string]string) (*experimental.ResourceConsumption, error) { - consumption, found := f.metrics[resource] - if !found { - return nil, fmt.Errorf("resource not found: %v", resource) +func (tc *testCase) verifyResults(t *testing.T) { + assert.Equal(t, tc.initialReplicas != tc.desiredReplicas, tc.scaleUpdated) + if tc.verifyEvents { + assert.Equal(t, tc.initialReplicas != tc.desiredReplicas, tc.eventCreated) } - return &consumption, nil } -func makeTestServer(t *testing.T, responses map[string]*serverResponse) (*httptest.Server, map[string]*util.FakeHandler) { +func (tc *testCase) runTest(t *testing.T) { + testClient := tc.prepareTestClient(t) + hpaController := NewHorizontalController(testClient, metrics.NewHeapsterMetricsClient(testClient)) + err := hpaController.reconcileAutoscalers() + assert.Equal(t, nil, err) + if tc.verifyEvents { + // We need to wait for events to be broadcasted (sleep for longer than record.sleepDuration). + time.Sleep(12 * time.Second) + } + tc.verifyResults(t) +} - handlers := map[string]*util.FakeHandler{} - mux := http.NewServeMux() +func TestCPU(t *testing.T) { + tc := testCase{ + minReplicas: 1, + maxReplicas: 5, + initialReplicas: 1, + desiredReplicas: 2, + targetResource: api.ResourceCPU, + targetLevel: resource.MustParse("0.1"), + reportedLevels: []uint64{200}, + } + tc.runTest(t) +} - mkHandler := func(url string, response serverResponse) *util.FakeHandler { - handler := util.FakeHandler{ - StatusCode: response.statusCode, - ResponseBody: runtime.EncodeOrDie(testapi.Experimental.Codec(), response.obj.(runtime.Object)), - } - mux.Handle(url, &handler) - glog.Infof("Will handle %s", url) - return &handler +func TestMemory(t *testing.T) { + tc := testCase{ + minReplicas: 1, + maxReplicas: 5, + initialReplicas: 1, + desiredReplicas: 2, + targetResource: api.ResourceMemory, + targetLevel: resource.MustParse("1k"), + reportedLevels: []uint64{2000}, } + tc.runTest(t) +} - if responses[hpaListHandler] != nil { - handlers[hpaListHandler] = mkHandler("/experimental/v1/horizontalpodautoscalers", *responses[hpaListHandler]) +func TestScaleUp(t *testing.T) { + tc := testCase{ + minReplicas: 2, + maxReplicas: 6, + initialReplicas: 3, + desiredReplicas: 5, + targetResource: api.ResourceMemory, + targetLevel: resource.MustParse("3k"), + reportedLevels: []uint64{3000, 5000, 7000}, } + tc.runTest(t) +} - if responses[scaleHandler] != nil { - handlers[scaleHandler] = mkHandler( - fmt.Sprintf("/experimental/v1/namespaces/%s/replicationcontrollers/%s/scale", namespace, rcName), *responses[scaleHandler]) +func TestScaleDown(t *testing.T) { + tc := testCase{ + minReplicas: 2, + maxReplicas: 6, + initialReplicas: 5, + desiredReplicas: 3, + targetResource: api.ResourceCPU, + targetLevel: resource.MustParse("0.5"), + reportedLevels: []uint64{100, 300, 500, 250, 250}, } + tc.runTest(t) +} - if responses[updateHpaHandler] != nil { - handlers[updateHpaHandler] = mkHandler(fmt.Sprintf("/experimental/v1/namespaces/%s/horizontalpodautoscalers/%s", namespace, hpaName), - *responses[updateHpaHandler]) +func TestTolerance(t *testing.T) { + tc := testCase{ + minReplicas: 1, + maxReplicas: 5, + initialReplicas: 3, + desiredReplicas: 3, + targetResource: api.ResourceMemory, + targetLevel: resource.MustParse("1k"), + reportedLevels: []uint64{1010, 1030, 1020}, } + tc.runTest(t) +} - mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) { - t.Errorf("unexpected request: %v", req.RequestURI) - res.WriteHeader(http.StatusNotFound) - }) - return httptest.NewServer(mux), handlers +func TestMinReplicas(t *testing.T) { + tc := testCase{ + minReplicas: 2, + maxReplicas: 5, + initialReplicas: 3, + desiredReplicas: 2, + targetResource: api.ResourceMemory, + targetLevel: resource.MustParse("1k"), + reportedLevels: []uint64{10, 95, 10}, + } + tc.runTest(t) } -func TestSyncEndpointsItemsPreserveNoSelector(t *testing.T) { +func TestMaxReplicas(t *testing.T) { + tc := testCase{ + minReplicas: 2, + maxReplicas: 5, + initialReplicas: 3, + desiredReplicas: 5, + targetResource: api.ResourceMemory, + targetLevel: resource.MustParse("1k"), + reportedLevels: []uint64{8000, 9500, 1000}, + } + tc.runTest(t) +} - hpaResponse := serverResponse{http.StatusOK, &experimental.HorizontalPodAutoscalerList{ - Items: []experimental.HorizontalPodAutoscaler{ - { - ObjectMeta: api.ObjectMeta{ - Name: hpaName, - Namespace: namespace, - }, - Spec: experimental.HorizontalPodAutoscalerSpec{ - ScaleRef: &experimental.SubresourceReference{ - Kind: "replicationController", - Name: rcName, - Namespace: namespace, - Subresource: "scale", - }, - MinCount: 1, - MaxCount: 5, - Target: experimental.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.3")}, - }, - }}}} - - scaleResponse := serverResponse{http.StatusOK, &experimental.Scale{ - ObjectMeta: api.ObjectMeta{ - Name: rcName, - Namespace: namespace, - }, - Spec: experimental.ScaleSpec{ - Replicas: 1, - }, - Status: experimental.ScaleStatus{ - Replicas: 1, - Selector: map[string]string{"name": podNameLabel}, - }, - }} - - status := experimental.HorizontalPodAutoscalerStatus{ - CurrentReplicas: 1, - DesiredReplicas: 3, +func TestSuperfluousMetrics(t *testing.T) { + tc := testCase{ + minReplicas: 2, + maxReplicas: 6, + initialReplicas: 4, + desiredReplicas: 4, + targetResource: api.ResourceMemory, + targetLevel: resource.MustParse("1k"), + reportedLevels: []uint64{4000, 9500, 3000, 7000, 3200, 2000}, } - updateHpaResponse := serverResponse{http.StatusOK, &experimental.HorizontalPodAutoscaler{ - - ObjectMeta: api.ObjectMeta{ - Name: hpaName, - Namespace: namespace, - }, - Spec: experimental.HorizontalPodAutoscalerSpec{ - ScaleRef: &experimental.SubresourceReference{ - Kind: "replicationController", - Name: rcName, - Namespace: namespace, - Subresource: "scale", - }, - MinCount: 1, - MaxCount: 5, - Target: experimental.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.3")}, - }, - Status: &status, - }} - - testServer, handlers := makeTestServer(t, - map[string]*serverResponse{ - hpaListHandler: &hpaResponse, - scaleHandler: &scaleResponse, - updateHpaHandler: &updateHpaResponse, - }) - - defer testServer.Close() - kubeClient := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Experimental.Version()}) - fakeRC := fakeResourceConsumptionClient{metrics: map[api.ResourceName]experimental.ResourceConsumption{ - api.ResourceCPU: {Resource: api.ResourceCPU, Quantity: resource.MustParse("650m")}, - }} - fake := fakeMetricsClient{consumption: &fakeRC} - - hpaController := NewHorizontalController(kubeClient, &fake) + tc.runTest(t) +} - err := hpaController.reconcileAutoscalers() - if err != nil { - t.Fatal("Failed to reconcile: %v", err) +func TestMissingMetrics(t *testing.T) { + tc := testCase{ + minReplicas: 2, + maxReplicas: 6, + initialReplicas: 4, + desiredReplicas: 4, + targetResource: api.ResourceMemory, + targetLevel: resource.MustParse("1k"), + reportedLevels: []uint64{400, 95}, } - for _, h := range handlers { - h.ValidateRequestCount(t, 1) + tc.runTest(t) +} + +func TestEmptyMetrics(t *testing.T) { + tc := testCase{ + minReplicas: 2, + maxReplicas: 6, + initialReplicas: 4, + desiredReplicas: 4, + targetResource: api.ResourceMemory, + targetLevel: resource.MustParse("1k"), + reportedLevels: []uint64{}, } - obj, err := kubeClient.Codec.Decode([]byte(handlers[updateHpaHandler].RequestBody)) - if err != nil { - t.Fatal("Failed to decode: %v %v", err) + tc.runTest(t) +} + +func TestEventCreated(t *testing.T) { + tc := testCase{ + minReplicas: 1, + maxReplicas: 5, + initialReplicas: 1, + desiredReplicas: 2, + targetResource: api.ResourceCPU, + targetLevel: resource.MustParse("0.1"), + reportedLevels: []uint64{200}, + verifyEvents: true, } - hpa, _ := obj.(*experimental.HorizontalPodAutoscaler) + tc.runTest(t) +} - assert.Equal(t, 3, hpa.Status.DesiredReplicas) - assert.Equal(t, int64(650), hpa.Status.CurrentConsumption.Quantity.MilliValue()) - assert.NotNil(t, hpa.Status.LastScaleTimestamp) +func TestEventNotCreated(t *testing.T) { + tc := testCase{ + minReplicas: 1, + maxReplicas: 5, + initialReplicas: 2, + desiredReplicas: 2, + targetResource: api.ResourceCPU, + targetLevel: resource.MustParse("0.2"), + reportedLevels: []uint64{200, 200}, + verifyEvents: true, + } + tc.runTest(t) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client.go index 7f631309e43b..68497f2b7681 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client.go @@ -25,7 +25,7 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -35,10 +35,10 @@ import ( const ( heapsterNamespace = "kube-system" - heapsterService = "monitoring-heapster" + heapsterService = "heapster" ) -var heapsterQueryStart, _ = time.ParseDuration("-5m") +var heapsterQueryStart = -5 * time.Minute // An interface for getting metrics for pods. type MetricsClient interface { @@ -47,12 +47,12 @@ type MetricsClient interface { type ResourceConsumptionClient interface { // Gets average resource consumption for pods under the given selector. - Get(resourceName api.ResourceName, selector map[string]string) (*experimental.ResourceConsumption, error) + Get(resourceName api.ResourceName, selector map[string]string) (*extensions.ResourceConsumption, error) } // Aggregates results into ResourceConsumption. Also returns number of // pods included in the aggregation. -type metricAggregator func(heapster.MetricResultList) (experimental.ResourceConsumption, int) +type metricAggregator func(heapster.MetricResultList) (extensions.ResourceConsumption, int) type metricDefinition struct { name string @@ -76,23 +76,23 @@ func NewHeapsterMetricsClient(client client.Interface) *HeapsterMetricsClient { var heapsterMetricDefinitions = map[api.ResourceName]metricDefinition{ api.ResourceCPU: {"cpu-usage", - func(metrics heapster.MetricResultList) (experimental.ResourceConsumption, int) { + func(metrics heapster.MetricResultList) (extensions.ResourceConsumption, int) { sum, count := calculateSumFromLatestSample(metrics) value := "0" if count > 0 { // assumes that cpu usage is in millis value = fmt.Sprintf("%dm", sum/uint64(count)) } - return experimental.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse(value)}, count + return extensions.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse(value)}, count }}, api.ResourceMemory: {"memory-usage", - func(metrics heapster.MetricResultList) (experimental.ResourceConsumption, int) { + func(metrics heapster.MetricResultList) (extensions.ResourceConsumption, int) { sum, count := calculateSumFromLatestSample(metrics) value := int64(0) if count > 0 { value = int64(sum) / int64(count) } - return experimental.ResourceConsumption{Resource: api.ResourceMemory, Quantity: *resource.NewQuantity(value, resource.DecimalSI)}, count + return extensions.ResourceConsumption{Resource: api.ResourceMemory, Quantity: *resource.NewQuantity(value, resource.DecimalSI)}, count }}, } @@ -104,7 +104,7 @@ func (h *HeapsterMetricsClient) ResourceConsumption(namespace string) ResourceCo } } -func (h *HeapsterResourceConsumptionClient) Get(resourceName api.ResourceName, selector map[string]string) (*experimental.ResourceConsumption, error) { +func (h *HeapsterResourceConsumptionClient) Get(resourceName api.ResourceName, selector map[string]string) (*extensions.ResourceConsumption, error) { podList, err := h.client.Pods(h.namespace). List(labels.SelectorFromSet(labels.Set(selector)), fields.Everything()) @@ -118,7 +118,7 @@ func (h *HeapsterResourceConsumptionClient) Get(resourceName api.ResourceName, s return h.getForPods(resourceName, podNames) } -func (h *HeapsterResourceConsumptionClient) getForPods(resourceName api.ResourceName, podNames []string) (*experimental.ResourceConsumption, error) { +func (h *HeapsterResourceConsumptionClient) getForPods(resourceName api.ResourceName, podNames []string) (*extensions.ResourceConsumption, error) { metricSpec, metricDefined := h.resourceDefinitions[resourceName] if !metricDefined { return nil, fmt.Errorf("heapster metric not defined for %v", resourceName) @@ -161,9 +161,9 @@ func calculateSumFromLatestSample(metrics heapster.MetricResultList) (uint64, in for _, metrics := range metrics.Items { var newest *heapster.MetricPoint newest = nil - for _, metricPoint := range metrics.Metrics { + for i, metricPoint := range metrics.Metrics { if newest == nil || newest.Timestamp.Before(metricPoint.Timestamp) { - newest = &metricPoint + newest = &metrics.Metrics[i] } } if newest != nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client_test.go index 38211856c14f..86dd1d020466 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client_test.go @@ -19,136 +19,350 @@ package metrics import ( "encoding/json" "fmt" - "net/http" - "net/http/httptest" + "io" "testing" "time" "k8s.io/kubernetes/pkg/api" _ "k8s.io/kubernetes/pkg/api/latest" - "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/apis/extensions" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" heapster "k8s.io/heapster/api/v1/types" - "github.com/golang/glog" "github.com/stretchr/testify/assert" ) -const ( - namespace = "test-namespace" - podName = "pod1" - podListHandler = "podlisthandler" - heapsterCpuHandler = "heapstercpuhandler" - heapsterMemHandler = "heapstermemhandler" - cpu = 650 - memory = 20000000 -) +func (w fakeResponseWrapper) DoRaw() ([]byte, error) { + return w.raw, nil +} + +func (w fakeResponseWrapper) Stream() (io.ReadCloser, error) { + return nil, nil +} + +func newFakeResponseWrapper(raw []byte) fakeResponseWrapper { + return fakeResponseWrapper{raw: raw} +} -type serverResponse struct { - statusCode int - obj interface{} +type fakeResponseWrapper struct { + raw []byte } -func makeTestServer(t *testing.T, responses map[string]*serverResponse) (*httptest.Server, map[string]*util.FakeHandler) { - handlers := map[string]*util.FakeHandler{} - mux := http.NewServeMux() +// timestamp is used for establishing order on metricPoints +type metricPoint struct { + level uint64 + timestamp int +} + +type testCase struct { + replicas int + desiredValue int64 + desiredError error + targetResource api.ResourceName + reportedMetricsPoints [][]metricPoint + namespace string + selector map[string]string +} + +func (tc *testCase) prepareTestClient(t *testing.T) *testclient.Fake { + namespace := "test-namespace" + tc.namespace = namespace + podNamePrefix := "test-pod" + selector := map[string]string{"name": podNamePrefix} + tc.selector = selector + + fakeClient := &testclient.Fake{} - mkHandler := func(url string, response serverResponse) *util.FakeHandler { - handler := util.FakeHandler{ - StatusCode: response.statusCode, - ResponseBody: runtime.EncodeOrDie(testapi.Experimental.Codec(), response.obj.(runtime.Object)), + fakeClient.AddReactor("list", "pods", func(action testclient.Action) (handled bool, ret runtime.Object, err error) { + obj := &api.PodList{} + for i := 0; i < tc.replicas; i++ { + podName := fmt.Sprintf("%s-%d", podNamePrefix, i) + pod := api.Pod{ + Status: api.PodStatus{ + Phase: api.PodRunning, + }, + ObjectMeta: api.ObjectMeta{ + Name: podName, + Namespace: namespace, + Labels: selector, + }, + } + obj.Items = append(obj.Items, pod) } - mux.Handle(url, &handler) - glog.Infof("Will handle %s", url) - return &handler - } + return true, obj, nil + }) - mkRawHandler := func(url string, response serverResponse) *util.FakeHandler { - handler := util.FakeHandler{ - StatusCode: response.statusCode, - ResponseBody: *response.obj.(*string), + fakeClient.AddProxyReactor("services", func(action testclient.Action) (handled bool, ret client.ResponseWrapper, err error) { + metrics := heapster.MetricResultList{} + firstTimestamp := time.Now() + var latestTimestamp time.Time + for _, reportedMetricPoints := range tc.reportedMetricsPoints { + var heapsterMetricPoints []heapster.MetricPoint + for _, reportedMetricPoint := range reportedMetricPoints { + timestamp := firstTimestamp.Add(time.Duration(reportedMetricPoint.timestamp) * time.Minute) + if latestTimestamp.Before(timestamp) { + latestTimestamp = timestamp + } + heapsterMetricPoint := heapster.MetricPoint{timestamp, reportedMetricPoint.level} + heapsterMetricPoints = append(heapsterMetricPoints, heapsterMetricPoint) + } + metric := heapster.MetricResult{ + Metrics: heapsterMetricPoints, + LatestTimestamp: latestTimestamp, + } + metrics.Items = append(metrics.Items, metric) } - mux.Handle(url, &handler) - glog.Infof("Will handle %s", url) - return &handler + heapsterRawMemResponse, _ := json.Marshal(&metrics) + return true, newFakeResponseWrapper(heapsterRawMemResponse), nil + }) + + return fakeClient +} + +func (tc *testCase) verifyResults(t *testing.T, val *extensions.ResourceConsumption, err error) { + assert.Equal(t, tc.desiredError, err) + if tc.desiredError != nil { + return } + if tc.targetResource == api.ResourceCPU { + assert.Equal(t, tc.desiredValue, val.Quantity.MilliValue()) + } + if tc.targetResource == api.ResourceMemory { + assert.Equal(t, tc.desiredValue, val.Quantity.Value()) + } +} - if responses[podListHandler] != nil { - handlers[podListHandler] = mkHandler(fmt.Sprintf("/api/v1/namespaces/%s/pods", namespace), *responses[podListHandler]) +func (tc *testCase) runTest(t *testing.T) { + testClient := tc.prepareTestClient(t) + metricsClient := NewHeapsterMetricsClient(testClient) + val, err := metricsClient.ResourceConsumption(tc.namespace).Get(tc.targetResource, tc.selector) + tc.verifyResults(t, val, err) +} + +func TestCPU(t *testing.T) { + tc := testCase{ + replicas: 3, + desiredValue: 5000, + targetResource: api.ResourceCPU, + reportedMetricsPoints: [][]metricPoint{{{5000, 1}}, {{5000, 1}}, {{5000, 1}}}, } + tc.runTest(t) +} - if responses[heapsterCpuHandler] != nil { - handlers[heapsterCpuHandler] = mkRawHandler( - fmt.Sprintf("/api/v1/proxy/namespaces/kube-system/services/monitoring-heapster/api/v1/model/namespaces/%s/pod-list/%s/metrics/cpu-usage", - namespace, podName), *responses[heapsterCpuHandler]) +func TestMemory(t *testing.T) { + tc := testCase{ + replicas: 3, + desiredValue: 5000, + targetResource: api.ResourceMemory, + reportedMetricsPoints: [][]metricPoint{{{5000, 1}}, {{5000, 2}}, {{5000, 4}}}, } + tc.runTest(t) +} - if responses[heapsterMemHandler] != nil { - handlers[heapsterMemHandler] = mkRawHandler( - fmt.Sprintf("/api/v1/proxy/namespaces/kube-system/services/monitoring-heapster/api/v1/model/namespaces/%s/pod-list/%s/metrics/memory-usage", - namespace, podName), *responses[heapsterMemHandler]) +func TestCPUSumEqualZero(t *testing.T) { + tc := testCase{ + replicas: 3, + desiredValue: 0, + targetResource: api.ResourceCPU, + reportedMetricsPoints: [][]metricPoint{{{0, 0}}, {{0, 0}}, {{0, 0}}}, } + tc.runTest(t) +} - mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) { - t.Errorf("unexpected request: %v", req.RequestURI) - res.WriteHeader(http.StatusNotFound) - }) - return httptest.NewServer(mux), handlers +func TestMemorySumEqualZero(t *testing.T) { + tc := testCase{ + replicas: 3, + desiredValue: 0, + targetResource: api.ResourceMemory, + reportedMetricsPoints: [][]metricPoint{{{0, 0}}, {{0, 0}}, {{0, 0}}}, + } + tc.runTest(t) } -func TestHeapsterResourceConsumptionGet(t *testing.T) { - podListResponse := serverResponse{http.StatusOK, &api.PodList{ - Items: []api.Pod{ - { - ObjectMeta: api.ObjectMeta{ - Name: podName, - Namespace: namespace, - }, - }}}} - - timestamp := time.Now() - metricsCpu := heapster.MetricResultList{ - Items: []heapster.MetricResult{{ - Metrics: []heapster.MetricPoint{{timestamp, cpu}}, - LatestTimestamp: timestamp, - }}} - heapsterRawCpuResponse, _ := json.Marshal(&metricsCpu) - heapsterStrCpuResponse := string(heapsterRawCpuResponse) - heapsterCpuResponse := serverResponse{http.StatusOK, &heapsterStrCpuResponse} - - metricsMem := heapster.MetricResultList{ - Items: []heapster.MetricResult{{ - Metrics: []heapster.MetricPoint{{timestamp, memory}}, - LatestTimestamp: timestamp, - }}} - heapsterRawMemResponse, _ := json.Marshal(&metricsMem) - heapsterStrMemResponse := string(heapsterRawMemResponse) - heapsterMemResponse := serverResponse{http.StatusOK, &heapsterStrMemResponse} - - testServer, _ := makeTestServer(t, - map[string]*serverResponse{ - heapsterCpuHandler: &heapsterCpuResponse, - heapsterMemHandler: &heapsterMemResponse, - podListHandler: &podListResponse, - }) - - defer testServer.Close() - kubeClient := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Experimental.Version()}) - - metricsClient := NewHeapsterMetricsClient(kubeClient) - - val, err := metricsClient.ResourceConsumption(namespace).Get(api.ResourceCPU, map[string]string{"app": "test"}) - if err != nil { - t.Fatalf("Error while getting consumption: %v", err) - } - assert.Equal(t, int64(cpu), val.Quantity.MilliValue()) - - val, err = metricsClient.ResourceConsumption(namespace).Get(api.ResourceMemory, map[string]string{"app": "test"}) - if err != nil { - t.Fatalf("Error while getting consumption: %v", err) - } - assert.Equal(t, int64(memory), val.Quantity.Value()) +func TestCPUMoreMetrics(t *testing.T) { + tc := testCase{ + replicas: 5, + desiredValue: 5000, + targetResource: api.ResourceCPU, + reportedMetricsPoints: [][]metricPoint{ + {{0, 3}, {0, 6}, {5, 4}, {9000, 10}}, + {{5000, 2}, {10, 5}, {66, 1}, {0, 10}}, + {{5000, 3}, {80, 5}, {6000, 10}}, + {{5000, 3}, {40, 3}, {0, 9}, {200, 2}, {8000, 10}}, + {{5000, 2}, {20, 2}, {2000, 10}}}, + } + tc.runTest(t) +} + +func TestMemoryMoreMetrics(t *testing.T) { + tc := testCase{ + replicas: 5, + desiredValue: 5000, + targetResource: api.ResourceMemory, + reportedMetricsPoints: [][]metricPoint{ + {{0, 3}, {0, 6}, {5, 4}, {9000, 10}}, + {{5000, 2}, {10, 5}, {66, 1}, {0, 10}}, + {{5000, 3}, {80, 5}, {6000, 10}}, + {{5000, 3}, {40, 3}, {0, 9}, {200, 2}, {8000, 10}}, + {{5000, 2}, {20, 2}, {2000, 10}}}, + } + tc.runTest(t) +} + +func TestCPUResultIsFloat(t *testing.T) { + tc := testCase{ + replicas: 6, + desiredValue: 4783, + targetResource: api.ResourceCPU, + reportedMetricsPoints: [][]metricPoint{{{4000, 4}}, {{9500, 4}}, {{3000, 4}}, {{7000, 4}}, {{3200, 4}}, {{2000, 4}}}, + } + tc.runTest(t) +} + +func TestMemoryResultIsFloat(t *testing.T) { + tc := testCase{ + replicas: 6, + desiredValue: 4783, + targetResource: api.ResourceMemory, + reportedMetricsPoints: [][]metricPoint{{{4000, 4}}, {{9500, 4}}, {{3000, 4}}, {{7000, 4}}, {{3200, 4}}, {{2000, 4}}}, + } + tc.runTest(t) +} + +func TestCPUSamplesWithRandomTimestamps(t *testing.T) { + tc := testCase{ + replicas: 3, + desiredValue: 3000, + targetResource: api.ResourceCPU, + reportedMetricsPoints: [][]metricPoint{ + {{1, 1}, {3000, 3}, {2, 2}}, + {{2, 2}, {1, 1}, {3000, 3}}, + {{3000, 3}, {1, 1}, {2, 2}}}, + } + tc.runTest(t) +} + +func TestMemorySamplesWithRandomTimestamps(t *testing.T) { + tc := testCase{ + replicas: 3, + desiredValue: 3000, + targetResource: api.ResourceMemory, + reportedMetricsPoints: [][]metricPoint{ + {{1, 1}, {3000, 3}, {2, 2}}, + {{2, 2}, {1, 1}, {3000, 3}}, + {{3000, 3}, {1, 1}, {2, 2}}}, + } + tc.runTest(t) +} + +func TestErrorMetricNotDefined(t *testing.T) { + tc := testCase{ + replicas: 1, + desiredError: fmt.Errorf("heapster metric not defined for "), + reportedMetricsPoints: [][]metricPoint{{{4000, 4}}}, + } + tc.runTest(t) +} + +func TestCPUMissingMetrics(t *testing.T) { + tc := testCase{ + replicas: 3, + targetResource: api.ResourceCPU, + desiredError: fmt.Errorf("metrics obtained for 1/3 of pods"), + reportedMetricsPoints: [][]metricPoint{{{4000, 4}}}, + } + tc.runTest(t) +} + +func TestMemoryMissingMetrics(t *testing.T) { + tc := testCase{ + replicas: 3, + targetResource: api.ResourceMemory, + desiredError: fmt.Errorf("metrics obtained for 1/3 of pods"), + reportedMetricsPoints: [][]metricPoint{{{4000, 4}}}, + } + tc.runTest(t) +} + +func TestCPUSuperfluousMetrics(t *testing.T) { + tc := testCase{ + replicas: 3, + targetResource: api.ResourceCPU, + desiredError: fmt.Errorf("metrics obtained for 6/3 of pods"), + reportedMetricsPoints: [][]metricPoint{{{1000, 1}}, {{2000, 4}}, {{2000, 1}}, {{4000, 5}}, {{2000, 1}}, {{4000, 4}}}, + } + tc.runTest(t) +} + +func TestMemorySuperfluousMetrics(t *testing.T) { + tc := testCase{ + replicas: 3, + targetResource: api.ResourceMemory, + desiredError: fmt.Errorf("metrics obtained for 6/3 of pods"), + reportedMetricsPoints: [][]metricPoint{{{1000, 1}}, {{2000, 4}}, {{2000, 1}}, {{4000, 5}}, {{2000, 1}}, {{4000, 4}}}, + } + tc.runTest(t) +} + +func TestCPUEmptyMetrics(t *testing.T) { + tc := testCase{ + replicas: 3, + targetResource: api.ResourceCPU, + desiredError: fmt.Errorf("metrics obtained for 0/3 of pods"), + reportedMetricsPoints: [][]metricPoint{}, + } + tc.runTest(t) +} + +func TestMemoryEmptyMetrics(t *testing.T) { + tc := testCase{ + replicas: 3, + targetResource: api.ResourceMemory, + desiredError: fmt.Errorf("metrics obtained for 0/3 of pods"), + reportedMetricsPoints: [][]metricPoint{}, + } + tc.runTest(t) +} + +func TestCPUZeroReplicas(t *testing.T) { + tc := testCase{ + replicas: 0, + targetResource: api.ResourceCPU, + desiredValue: 0, + reportedMetricsPoints: [][]metricPoint{}, + } + tc.runTest(t) +} + +func TestMemoryZeroReplicas(t *testing.T) { + tc := testCase{ + replicas: 0, + targetResource: api.ResourceMemory, + desiredValue: 0, + reportedMetricsPoints: [][]metricPoint{}, + } + tc.runTest(t) +} + +func TestCPUEmptyMetricsForOnePod(t *testing.T) { + tc := testCase{ + replicas: 3, + targetResource: api.ResourceCPU, + desiredError: fmt.Errorf("metrics obtained for 2/3 of pods"), + reportedMetricsPoints: [][]metricPoint{{}, {{100, 1}}, {{400, 2}, {300, 3}}}, + } + tc.runTest(t) +} + +func TestMemoryEmptyMetricsForOnePod(t *testing.T) { + tc := testCase{ + replicas: 3, + targetResource: api.ResourceMemory, + desiredError: fmt.Errorf("metrics obtained for 2/3 of pods"), + reportedMetricsPoints: [][]metricPoint{{}, {{100, 1}}, {{400, 2}, {300, 3}}}, + } + tc.runTest(t) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/doc.go index eb6027db312c..b60e1d99c4e3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/doc.go @@ -16,4 +16,4 @@ limitations under the License. // Package replication contains logic for watching and synchronizing // replication controllers. -package replicationcontroller +package replication diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller.go index 082abe963e04..fd59aa5d9cb6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package replicationcontroller +package replication import ( "reflect" @@ -43,12 +43,6 @@ const ( // happens based on contents in local pod storage. FullControllerResyncPeriod = 30 * time.Second - // If a watch misdelivers info about a pod, it'll take at least this long - // to rectify the number of replicas. Note that dropped deletes are only - // rectified after the expectation times out because we don't know the - // final resting state of the pod. - PodRelistPeriod = 5 * time.Minute - // Realistic value of the burstReplica field for the replication manager based off // performance requirements for kubernetes 1.0. BurstReplicas = 500 @@ -75,28 +69,27 @@ type ReplicationManager struct { // To allow injection of syncReplicationController for testing. syncHandler func(rcKey string) error - // podStoreSynced returns true if the pod store has been synced at least once. - // Added as a member to the struct to allow injection for testing. - podStoreSynced func() bool - // A TTLCache of pod creates/deletes each rc expects to see expectations controller.ControllerExpectationsInterface // A store of replication controllers, populated by the rcController rcStore cache.StoreToReplicationControllerLister - - // A store of pods, populated by the podController - podStore cache.StoreToPodLister // Watches changes to all replication controllers rcController *framework.Controller + // A store of pods, populated by the podController + podStore cache.StoreToPodLister // Watches changes to all pods podController *framework.Controller - // Controllers that need to be updated + // podStoreSynced returns true if the pod store has been synced at least once. + // Added as a member to the struct to allow injection for testing. + podStoreSynced func() bool + + // Controllers that need to be synced queue *workqueue.Type } // NewReplicationManager creates a new ReplicationManager. -func NewReplicationManager(kubeClient client.Interface, burstReplicas int) *ReplicationManager { +func NewReplicationManager(kubeClient client.Interface, resyncPeriod controller.ResyncPeriodFunc, burstReplicas int) *ReplicationManager { eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartLogging(glog.Infof) eventBroadcaster.StartRecordingToSink(kubeClient.Events("")) @@ -115,23 +108,30 @@ func NewReplicationManager(kubeClient client.Interface, burstReplicas int) *Repl rm.rcStore.Store, rm.rcController = framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { - return rm.kubeClient.ReplicationControllers(api.NamespaceAll).List(labels.Everything()) + return rm.kubeClient.ReplicationControllers(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(rv string) (watch.Interface, error) { return rm.kubeClient.ReplicationControllers(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), rv) }, }, &api.ReplicationController{}, + // TODO: Can we have much longer period here? FullControllerResyncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: rm.enqueueController, UpdateFunc: func(old, cur interface{}) { - // We only really need to do this when spec changes, but for correctness it is safer to - // periodically double check. It is overkill for 2 reasons: - // 1. Status.Replica updates will cause a sync - // 2. Every 30s we will get a full resync (this will happen anyway every 5 minutes when pods relist) - // However, it shouldn't be that bad as rcs that haven't met expectations won't sync, and all - // the listing is done using local stores. + // You might imagine that we only really need to enqueue the + // controller when Spec changes, but it is safer to sync any + // time this function is triggered. That way a full informer + // resync can requeue any controllers that don't yet have pods + // but whose last attempts at creating a pod have failed (since + // we don't block on creation of pods) instead of those + // controllers stalling indefinitely. Enqueueing every time + // does result in some spurious syncs (like when Status.Replica + // is updated and the watch notification from it retriggers + // this function), but in general extra resyncs shouldn't be + // that bad as rcs that haven't met expectations yet won't + // sync, and all the listing is done using local stores. oldRC := old.(*api.ReplicationController) curRC := cur.(*api.ReplicationController) if oldRC.Status.Replicas != curRC.Status.Replicas { @@ -156,7 +156,7 @@ func NewReplicationManager(kubeClient client.Interface, burstReplicas int) *Repl }, }, &api.Pod{}, - PodRelistPeriod, + resyncPeriod(), framework.ResourceEventHandlerFuncs{ AddFunc: rm.addPod, // This invokes the rc for every pod change, eg: host assignment. Though this might seem like overkill @@ -206,7 +206,13 @@ func (rm *ReplicationManager) getPodController(pod *api.Pod) *api.ReplicationCon // rc1 (older rc): [(k1=v1)], replicas=1 rc2: [(k2=v2)], replicas=2 // pod: [(k1:v1), (k2:v2)] will wake both rc1 and rc2, and we will sync rc1. // pod: [(k2:v2)] will wake rc2 which creates a new replica. - sort.Sort(overlappingControllers(controllers)) + if len(controllers) > 1 { + // More than two items in this list indicates user error. If two replication-controller + // overlap, sort by creation timestamp, subsort by name, then pick + // the first. + glog.Errorf("user error! more than one replication controller is selecting pods with labels: %+v", pod.Labels) + sort.Sort(overlappingControllers(controllers)) + } return &controllers[0] } @@ -350,7 +356,7 @@ func (rm *ReplicationManager) manageReplicas(filteredPods []*api.Pod, rc *api.Re for i := 0; i < diff; i++ { go func() { defer wait.Done() - if err := rm.podControl.CreateReplica(rc.Namespace, rc); err != nil { + if err := rm.podControl.CreatePods(rc.Namespace, rc.Spec.Template, rc); err != nil { // Decrement the expected number of creates because the informer won't observe this pod glog.V(2).Infof("Failed creation, decrementing expectations for controller %q/%q", rc.Namespace, rc.Name) rm.expectations.CreationObserved(rcKey) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller_test.go index 404099a02710..5747d75ad266 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller_test.go @@ -14,82 +14,35 @@ See the License for the specific language governing permissions and limitations under the License. */ -package replicationcontroller +package replication import ( "fmt" "math/rand" - "net/http" "net/http/httptest" - "sync" "testing" "time" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/controller" - "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" - "k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/watch" ) -type FakePodControl struct { - controllerSpec []api.ReplicationController - deletePodName []string - lock sync.Mutex - err error -} - -// Give each test that starts a background controller up to 1/2 a second. -// Since we need to start up a goroutine to test watch, this routine needs -// to get cpu before the test can complete. If the test is starved of cpu, -// the watch test will take up to 1/2 a second before timing out. -const controllerTimeout = 500 * time.Millisecond - var alwaysReady = func() bool { return true } func init() { api.ForTesting_ReferencesAllowBlankSelfLinks = true } -func (f *FakePodControl) CreateReplica(namespace string, spec *api.ReplicationController) error { - f.lock.Lock() - defer f.lock.Unlock() - if f.err != nil { - return f.err - } - f.controllerSpec = append(f.controllerSpec, *spec) - return nil -} - -func (f *FakePodControl) CreateReplicaOnNode(namespace string, daemon *experimental.DaemonSet, nodeName string) error { - return nil -} - -func (f *FakePodControl) DeletePod(namespace string, podName string) error { - f.lock.Lock() - defer f.lock.Unlock() - if f.err != nil { - return f.err - } - f.deletePodName = append(f.deletePodName, podName) - return nil -} -func (f *FakePodControl) clear() { - f.lock.Lock() - defer f.lock.Unlock() - f.deletePodName = []string{} - f.controllerSpec = []api.ReplicationController{} -} - func getKey(rc *api.ReplicationController, t *testing.T) string { if key, err := controller.KeyFunc(rc); err != nil { t.Errorf("Unexpected error getting key for rc %v: %v", rc.Name, err) @@ -101,7 +54,7 @@ func getKey(rc *api.ReplicationController, t *testing.T) string { func newReplicationController(replicas int) *api.ReplicationController { rc := &api.ReplicationController{ - TypeMeta: api.TypeMeta{APIVersion: testapi.Default.Version()}, + TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.Version()}, ObjectMeta: api.ObjectMeta{ UID: util.NewUUID(), Name: "foobar", @@ -161,12 +114,12 @@ func newPodList(store cache.Store, count int, status api.PodPhase, rc *api.Repli } } -func validateSyncReplication(t *testing.T, fakePodControl *FakePodControl, expectedCreates, expectedDeletes int) { - if len(fakePodControl.controllerSpec) != expectedCreates { - t.Errorf("Unexpected number of creates. Expected %d, saw %d\n", expectedCreates, len(fakePodControl.controllerSpec)) +func validateSyncReplication(t *testing.T, fakePodControl *controller.FakePodControl, expectedCreates, expectedDeletes int) { + if len(fakePodControl.Templates) != expectedCreates { + t.Errorf("Unexpected number of creates. Expected %d, saw %d\n", expectedCreates, len(fakePodControl.Templates)) } - if len(fakePodControl.deletePodName) != expectedDeletes { - t.Errorf("Unexpected number of deletes. Expected %d, saw %d\n", expectedDeletes, len(fakePodControl.deletePodName)) + if len(fakePodControl.DeletePodName) != expectedDeletes { + t.Errorf("Unexpected number of deletes. Expected %d, saw %d\n", expectedDeletes, len(fakePodControl.DeletePodName)) } } @@ -179,55 +132,10 @@ type serverResponse struct { obj interface{} } -func makeTestServer(t *testing.T, namespace, name string, podResponse, controllerResponse, updateResponse serverResponse) (*httptest.Server, *util.FakeHandler) { - fakePodHandler := util.FakeHandler{ - StatusCode: podResponse.statusCode, - ResponseBody: runtime.EncodeOrDie(testapi.Default.Codec(), podResponse.obj.(runtime.Object)), - } - fakeControllerHandler := util.FakeHandler{ - StatusCode: controllerResponse.statusCode, - ResponseBody: runtime.EncodeOrDie(testapi.Default.Codec(), controllerResponse.obj.(runtime.Object)), - } - fakeUpdateHandler := util.FakeHandler{ - StatusCode: updateResponse.statusCode, - ResponseBody: runtime.EncodeOrDie(testapi.Default.Codec(), updateResponse.obj.(runtime.Object)), - } - mux := http.NewServeMux() - mux.Handle(testapi.Default.ResourcePath("pods", namespace, ""), &fakePodHandler) - mux.Handle(testapi.Default.ResourcePath(replicationControllerResourceName(), "", ""), &fakeControllerHandler) - if namespace != "" { - mux.Handle(testapi.Default.ResourcePath(replicationControllerResourceName(), namespace, ""), &fakeControllerHandler) - } - if name != "" { - mux.Handle(testapi.Default.ResourcePath(replicationControllerResourceName(), namespace, name), &fakeUpdateHandler) - } - mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) { - t.Errorf("unexpected request: %v", req.RequestURI) - res.WriteHeader(http.StatusNotFound) - }) - return httptest.NewServer(mux), &fakeUpdateHandler -} - -func startManagerAndWait(manager *ReplicationManager, pods int, t *testing.T) chan struct{} { - stopCh := make(chan struct{}) - go manager.Run(1, stopCh) - err := wait.Poll(10*time.Millisecond, 100*time.Millisecond, func() (bool, error) { - podList, err := manager.podStore.List(labels.Everything()) - if err != nil { - return false, err - } - return len(podList) == pods, nil - }) - if err != nil { - t.Errorf("Failed to observe %d pods in 100ms", pods) - } - return stopCh -} - func TestSyncReplicationControllerDoesNothing(t *testing.T) { client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) - fakePodControl := FakePodControl{} - manager := NewReplicationManager(client, BurstReplicas) + fakePodControl := controller.FakePodControl{} + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady // 2 running pods, a controller with 2 replicas, sync is a no-op @@ -242,8 +150,8 @@ func TestSyncReplicationControllerDoesNothing(t *testing.T) { func TestSyncReplicationControllerDeletes(t *testing.T) { client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) - fakePodControl := FakePodControl{} - manager := NewReplicationManager(client, BurstReplicas) + fakePodControl := controller.FakePodControl{} + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady manager.podControl = &fakePodControl @@ -258,8 +166,8 @@ func TestSyncReplicationControllerDeletes(t *testing.T) { func TestDeleteFinalStateUnknown(t *testing.T) { client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) - fakePodControl := FakePodControl{} - manager := NewReplicationManager(client, BurstReplicas) + fakePodControl := controller.FakePodControl{} + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady manager.podControl = &fakePodControl @@ -284,23 +192,23 @@ func TestDeleteFinalStateUnknown(t *testing.T) { if key != expected { t.Errorf("Unexpected sync all for rc %v, expected %v", key, expected) } - case <-time.After(100 * time.Millisecond): + case <-time.After(util.ForeverTestTimeout): t.Errorf("Processing DeleteFinalStateUnknown took longer than expected") } } func TestSyncReplicationControllerCreates(t *testing.T) { client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) - manager := NewReplicationManager(client, BurstReplicas) + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady // A controller with 2 replicas and no pods in the store, 2 creates expected - controller := newReplicationController(2) - manager.rcStore.Store.Add(controller) + rc := newReplicationController(2) + manager.rcStore.Store.Add(rc) - fakePodControl := FakePodControl{} + fakePodControl := controller.FakePodControl{} manager.podControl = &fakePodControl - manager.syncReplicationController(getKey(controller, t)) + manager.syncReplicationController(getKey(rc, t)) validateSyncReplication(t, &fakePodControl, 2, 0) } @@ -313,7 +221,7 @@ func TestStatusUpdatesWithoutReplicasChange(t *testing.T) { testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - manager := NewReplicationManager(client, BurstReplicas) + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady // Steady state for the replication controller, no Status.Replicas updates expected @@ -323,7 +231,7 @@ func TestStatusUpdatesWithoutReplicasChange(t *testing.T) { rc.Status = api.ReplicationControllerStatus{Replicas: activePods} newPodList(manager.podStore.Store, activePods, api.PodRunning, rc) - fakePodControl := FakePodControl{} + fakePodControl := controller.FakePodControl{} manager.podControl = &fakePodControl manager.syncReplicationController(getKey(rc, t)) @@ -342,7 +250,7 @@ func TestStatusUpdatesWithoutReplicasChange(t *testing.T) { rc.Status.ObservedGeneration = rc.Generation updatedRc := runtime.EncodeOrDie(testapi.Default.Codec(), rc) - fakeHandler.ValidateRequest(t, testapi.Default.ResourcePath(replicationControllerResourceName(), rc.Namespace, rc.Name), "PUT", &updatedRc) + fakeHandler.ValidateRequest(t, testapi.Default.ResourcePath(replicationControllerResourceName(), rc.Namespace, rc.Name)+"/status", "PUT", &updatedRc) } func TestControllerUpdateReplicas(t *testing.T) { @@ -355,7 +263,7 @@ func TestControllerUpdateReplicas(t *testing.T) { defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - manager := NewReplicationManager(client, BurstReplicas) + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady // Insufficient number of pods in the system, and Status.Replicas is wrong; @@ -370,7 +278,7 @@ func TestControllerUpdateReplicas(t *testing.T) { response := runtime.EncodeOrDie(testapi.Default.Codec(), &api.ReplicationController{}) fakeHandler.ResponseBody = response - fakePodControl := FakePodControl{} + fakePodControl := controller.FakePodControl{} manager.podControl = &fakePodControl manager.syncReplicationController(getKey(rc, t)) @@ -380,7 +288,7 @@ func TestControllerUpdateReplicas(t *testing.T) { rc.Status = api.ReplicationControllerStatus{Replicas: 4, ObservedGeneration: 1} decRc := runtime.EncodeOrDie(testapi.Default.Codec(), rc) - fakeHandler.ValidateRequest(t, testapi.Default.ResourcePath(replicationControllerResourceName(), rc.Namespace, rc.Name), "PUT", &decRc) + fakeHandler.ValidateRequest(t, testapi.Default.ResourcePath(replicationControllerResourceName(), rc.Namespace, rc.Name)+"/status", "PUT", &decRc) validateSyncReplication(t, &fakePodControl, 1, 0) } @@ -394,8 +302,8 @@ func TestSyncReplicationControllerDormancy(t *testing.T) { defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - fakePodControl := FakePodControl{} - manager := NewReplicationManager(client, BurstReplicas) + fakePodControl := controller.FakePodControl{} + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady manager.podControl = &fakePodControl @@ -410,7 +318,7 @@ func TestSyncReplicationControllerDormancy(t *testing.T) { // Expectations prevents replicas but not an update on status controllerSpec.Status.Replicas = 0 - fakePodControl.clear() + fakePodControl.Clear() manager.syncReplicationController(getKey(controllerSpec, t)) validateSyncReplication(t, &fakePodControl, 0, 0) @@ -424,14 +332,14 @@ func TestSyncReplicationControllerDormancy(t *testing.T) { // fakePodControl error will prevent this, leaving expectations at 0, 0 manager.expectations.CreationObserved(rcKey) controllerSpec.Status.Replicas = 1 - fakePodControl.clear() - fakePodControl.err = fmt.Errorf("Fake Error") + fakePodControl.Clear() + fakePodControl.Err = fmt.Errorf("Fake Error") manager.syncReplicationController(getKey(controllerSpec, t)) validateSyncReplication(t, &fakePodControl, 0, 0) // This replica should not need a Lowering of expectations, since the previous create failed - fakePodControl.err = nil + fakePodControl.Err = nil manager.syncReplicationController(getKey(controllerSpec, t)) validateSyncReplication(t, &fakePodControl, 1, 0) @@ -441,7 +349,7 @@ func TestSyncReplicationControllerDormancy(t *testing.T) { } func TestPodControllerLookup(t *testing.T) { - manager := NewReplicationManager(client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}), BurstReplicas) + manager := NewReplicationManager(client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}), controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady testCases := []struct { inRCs []*api.ReplicationController @@ -509,7 +417,7 @@ func TestWatchControllers(t *testing.T) { fakeWatch := watch.NewFake() client := &testclient.Fake{} client.AddWatchReactor("*", testclient.DefaultWatchReactor(fakeWatch, nil)) - manager := NewReplicationManager(client, BurstReplicas) + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady var testControllerSpec api.ReplicationController @@ -543,7 +451,7 @@ func TestWatchControllers(t *testing.T) { select { case <-received: - case <-time.After(controllerTimeout): + case <-time.After(util.ForeverTestTimeout): t.Errorf("Expected 1 call but got 0") } } @@ -552,7 +460,7 @@ func TestWatchPods(t *testing.T) { fakeWatch := watch.NewFake() client := &testclient.Fake{} client.AddWatchReactor("*", testclient.DefaultWatchReactor(fakeWatch, nil)) - manager := NewReplicationManager(client, BurstReplicas) + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady // Put one rc and one pod into the controller's stores @@ -588,16 +496,13 @@ func TestWatchPods(t *testing.T) { select { case <-received: - case <-time.After(controllerTimeout): + case <-time.After(util.ForeverTestTimeout): t.Errorf("Expected 1 call but got 0") } } func TestUpdatePods(t *testing.T) { - fakeWatch := watch.NewFake() - client := &testclient.Fake{} - client.AddWatchReactor("*", testclient.DefaultWatchReactor(fakeWatch, nil)) - manager := NewReplicationManager(client, BurstReplicas) + manager := NewReplicationManager(testclient.NewSimpleFake(), controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady received := make(chan string) @@ -640,7 +545,7 @@ func TestUpdatePods(t *testing.T) { if !expected.Has(got) { t.Errorf("Expected keys %#v got %v", expected, got) } - case <-time.After(controllerTimeout): + case <-time.After(util.ForeverTestTimeout): t.Errorf("Expected update notifications for controllers within 100ms each") } } @@ -656,7 +561,7 @@ func TestControllerUpdateRequeue(t *testing.T) { defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) - manager := NewReplicationManager(client, BurstReplicas) + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady rc := newReplicationController(1) @@ -664,7 +569,7 @@ func TestControllerUpdateRequeue(t *testing.T) { rc.Status = api.ReplicationControllerStatus{Replicas: 2} newPodList(manager.podStore.Store, 1, api.PodRunning, rc) - fakePodControl := FakePodControl{} + fakePodControl := controller.FakePodControl{} manager.podControl = &fakePodControl manager.syncReplicationController(getKey(rc, t)) @@ -680,7 +585,7 @@ func TestControllerUpdateRequeue(t *testing.T) { if key != expectedKey { t.Errorf("Expected requeue of controller with key %s got %s", expectedKey, key) } - case <-time.After(controllerTimeout): + case <-time.After(util.ForeverTestTimeout): manager.queue.ShutDown() t.Errorf("Expected to find an rc in the queue, found none.") } @@ -736,8 +641,8 @@ func TestControllerUpdateStatusWithFailure(t *testing.T) { func doTestControllerBurstReplicas(t *testing.T, burstReplicas, numReplicas int) { client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) - fakePodControl := FakePodControl{} - manager := NewReplicationManager(client, burstReplicas) + fakePodControl := controller.FakePodControl{} + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, burstReplicas) manager.podStoreSynced = alwaysReady manager.podControl = &fakePodControl @@ -808,7 +713,7 @@ func doTestControllerBurstReplicas(t *testing.T, burstReplicas, numReplicas int) } // Check that the rc didn't take any action for all the above pods - fakePodControl.clear() + fakePodControl.Clear() manager.syncReplicationController(getKey(controllerSpec, t)) validateSyncReplication(t, &fakePodControl, 0, 0) @@ -856,8 +761,8 @@ func (fe FakeRCExpectations) SatisfiedExpectations(controllerKey string) bool { // and checking expectations. func TestRCSyncExpectations(t *testing.T) { client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) - fakePodControl := FakePodControl{} - manager := NewReplicationManager(client, 2) + fakePodControl := controller.FakePodControl{} + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, 2) manager.podStoreSynced = alwaysReady manager.podControl = &fakePodControl @@ -881,19 +786,19 @@ func TestRCSyncExpectations(t *testing.T) { func TestDeleteControllerAndExpectations(t *testing.T) { client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) - manager := NewReplicationManager(client, 10) + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, 10) manager.podStoreSynced = alwaysReady rc := newReplicationController(1) manager.rcStore.Store.Add(rc) - fakePodControl := FakePodControl{} + fakePodControl := controller.FakePodControl{} manager.podControl = &fakePodControl // This should set expectations for the rc manager.syncReplicationController(getKey(rc, t)) validateSyncReplication(t, &fakePodControl, 1, 0) - fakePodControl.clear() + fakePodControl.Clear() // Get the RC key rcKey, err := controller.KeyFunc(rc) @@ -923,8 +828,8 @@ func TestDeleteControllerAndExpectations(t *testing.T) { func TestRCManagerNotReady(t *testing.T) { client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) - fakePodControl := FakePodControl{} - manager := NewReplicationManager(client, 2) + fakePodControl := controller.FakePodControl{} + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, 2) manager.podControl = &fakePodControl manager.podStoreSynced = func() bool { return false } @@ -962,14 +867,14 @@ func TestOverlappingRCs(t *testing.T) { client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) for i := 0; i < 5; i++ { - manager := NewReplicationManager(client, 10) + manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, 10) manager.podStoreSynced = alwaysReady // Create 10 rcs, shuffled them randomly and insert them into the rc manager's store var controllers []*api.ReplicationController for j := 1; j < 10; j++ { controllerSpec := newReplicationController(1) - controllerSpec.CreationTimestamp = util.Date(2014, time.December, j, 0, 0, 0, 0, time.Local) + controllerSpec.CreationTimestamp = unversioned.Date(2014, time.December, j, 0, 0, 0, 0, time.Local) controllerSpec.Name = string(util.NewUUID()) controllers = append(controllers, controllerSpec) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller_utils.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller_utils.go index 13858358a610..5033c29011c2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller_utils.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/replication/replication_controller_utils.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package replicationcontroller +package replication import ( "github.com/golang/glog" @@ -43,7 +43,7 @@ func updateReplicaCount(rcClient client.ReplicationControllerInterface, controll controller.Name, controller.Status.Replicas, numReplicas, controller.Spec.Replicas, controller.Status.ObservedGeneration, generation) rc.Status = api.ReplicationControllerStatus{Replicas: numReplicas, ObservedGeneration: generation} - _, updateErr = rcClient.Update(rc) + _, updateErr = rcClient.UpdateStatus(rc) if updateErr == nil || i >= statusUpdateRetries { return updateErr } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/doc.go index 73fa39f90e73..a83ad10dd665 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/doc.go @@ -15,4 +15,4 @@ limitations under the License. */ // resourcequota contains a controller that makes resource quota usage observations -package resourcequotacontroller +package resourcequota diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller.go index 9d319aacaf8a..053e68d4434e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package resourcequotacontroller +package resourcequota import ( "fmt" @@ -58,7 +58,7 @@ func (rm *ResourceQuotaController) Run(period time.Duration) { func (rm *ResourceQuotaController) synchronize() { var resourceQuotas []api.ResourceQuota - list, err := rm.kubeClient.ResourceQuotas(api.NamespaceAll).List(labels.Everything()) + list, err := rm.kubeClient.ResourceQuotas(api.NamespaceAll).List(labels.Everything(), fields.Everything()) if err != nil { glog.Errorf("Synchronization error: %v (%#v)", err, err) } @@ -165,19 +165,19 @@ func (rm *ResourceQuotaController) syncResourceQuota(quota api.ResourceQuota) (e case api.ResourcePods: value = resource.NewQuantity(int64(len(filteredPods)), resource.DecimalSI) case api.ResourceServices: - items, err := rm.kubeClient.Services(usage.Namespace).List(labels.Everything()) + items, err := rm.kubeClient.Services(usage.Namespace).List(labels.Everything(), fields.Everything()) if err != nil { return err } value = resource.NewQuantity(int64(len(items.Items)), resource.DecimalSI) case api.ResourceReplicationControllers: - items, err := rm.kubeClient.ReplicationControllers(usage.Namespace).List(labels.Everything()) + items, err := rm.kubeClient.ReplicationControllers(usage.Namespace).List(labels.Everything(), fields.Everything()) if err != nil { return err } value = resource.NewQuantity(int64(len(items.Items)), resource.DecimalSI) case api.ResourceQuotas: - items, err := rm.kubeClient.ResourceQuotas(usage.Namespace).List(labels.Everything()) + items, err := rm.kubeClient.ResourceQuotas(usage.Namespace).List(labels.Everything(), fields.Everything()) if err != nil { return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller_test.go index 4cb0b1f4f739..e72ef37d2339 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package resourcequotacontroller +package resourcequota import ( "strconv" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/doc.go index 8ad76248a5a3..bc4ae60a27ae 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/doc.go @@ -14,6 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package routecontroller contains code for syncing cloud routing rules with +// Package route contains code for syncing cloud routing rules with // the list of registered nodes. -package routecontroller +package route diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/routecontroller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/routecontroller.go index bd513aca821c..eb30dc13e8fc 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/routecontroller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/routecontroller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package routecontroller +package route import ( "fmt" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/routecontroller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/routecontroller_test.go index d09b6764eaf6..4277aec45c14 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/routecontroller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/route/routecontroller_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package routecontroller +package route import ( "net" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/doc.go index da5426f365cc..78c20eb96507 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/doc.go @@ -14,6 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package servicecontroller contains code for syncing cloud load balancers +// Package service contains code for syncing cloud load balancers // with the service registry. -package servicecontroller +package service diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/servicecontroller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/servicecontroller.go index 688283b015f9..3fba65073da4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/servicecontroller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/servicecontroller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package servicecontroller +package service import ( "fmt" @@ -238,14 +238,14 @@ func (s *ServiceController) processDelta(delta *cache.Delta) (error, bool) { case cache.Sync: err, retry := s.createLoadBalancerIfNeeded(namespacedName, service, cachedService.appliedState) if err != nil { - message := "error creating load balancer" + message := "Error creating load balancer" if retry { message += " (will retry): " } else { message += " (will not retry): " } message += err.Error() - s.eventRecorder.Event(service, "creating loadbalancer failed", message) + s.eventRecorder.Event(service, "CreatingLoadBalancerFailed", message) return err, retry } // Always update the cache upon success. @@ -255,14 +255,14 @@ func (s *ServiceController) processDelta(delta *cache.Delta) (error, bool) { cachedService.appliedState = service s.cache.set(namespacedName.String(), cachedService) case cache.Deleted: - s.eventRecorder.Event(service, "deleting loadbalancer", "deleting loadbalancer") + s.eventRecorder.Event(service, "DeletingLoadBalancer", "Deleting load balancer") err := s.balancer.EnsureTCPLoadBalancerDeleted(s.loadBalancerName(service), s.zone.Region) if err != nil { - message := "error deleting load balancer (will retry): " + err.Error() - s.eventRecorder.Event(service, "deleting loadbalancer failed", message) + message := "Error deleting load balancer (will retry): " + err.Error() + s.eventRecorder.Event(service, "DeletingLoadBalancerFailed", message) return err, retryable } - s.eventRecorder.Event(service, "deleted loadbalancer", "deleted loadbalancer") + s.eventRecorder.Event(service, "DeletedLoadBalancer", "Deleted load balancer") s.cache.delete(namespacedName.String()) default: glog.Errorf("Unexpected delta type: %v", delta.Type) @@ -305,11 +305,11 @@ func (s *ServiceController) createLoadBalancerIfNeeded(namespacedName types.Name if needDelete { glog.Infof("Deleting existing load balancer for service %s that no longer needs a load balancer.", namespacedName) - s.eventRecorder.Event(service, "deleting loadbalancer", "deleting loadbalancer") + s.eventRecorder.Event(service, "DeletingLoadBalancer", "Deleting load balancer") if err := s.balancer.EnsureTCPLoadBalancerDeleted(s.loadBalancerName(service), s.zone.Region); err != nil { return err, retryable } - s.eventRecorder.Event(service, "deleted loadbalancer", "deleted loadbalancer") + s.eventRecorder.Event(service, "DeletedLoadBalancer", "Deleted load balancer") } service.Status.LoadBalancer = api.LoadBalancerStatus{} @@ -319,12 +319,12 @@ func (s *ServiceController) createLoadBalancerIfNeeded(namespacedName types.Name // TODO: We could do a dry-run here if wanted to avoid the spurious cloud-calls & events when we restart // The load balancer doesn't exist yet, so create it. - s.eventRecorder.Event(service, "creating loadbalancer", "creating loadbalancer") - err := s.createExternalLoadBalancer(service) + s.eventRecorder.Event(service, "CreatingLoadBalancer", "Creating load balancer") + err := s.createLoadBalancer(service) if err != nil { - return fmt.Errorf("failed to create external load balancer for service %s: %v", namespacedName, err), retryable + return fmt.Errorf("Failed to create load balancer for service %s: %v", namespacedName, err), retryable } - s.eventRecorder.Event(service, "created loadbalancer", "created loadbalancer") + s.eventRecorder.Event(service, "CreatedLoadBalancer", "Created load balancer") } // Write the state if changed @@ -368,7 +368,7 @@ func (s *ServiceController) persistUpdate(service *api.Service) error { return err } -func (s *ServiceController) createExternalLoadBalancer(service *api.Service) error { +func (s *ServiceController) createLoadBalancer(service *api.Service) error { ports, err := getPortsForLB(service) if err != nil { return err @@ -659,7 +659,7 @@ func (s *ServiceController) lockedUpdateLoadBalancerHosts(service *api.Service, name := cloudprovider.GetLoadBalancerName(service) err := s.balancer.UpdateTCPLoadBalancer(name, s.zone.Region, hosts) if err == nil { - s.eventRecorder.Event(service, "updated loadbalancer", "updated loadbalancer with new hosts") + s.eventRecorder.Event(service, "UpdatedLoadBalancer", "Updated load balancer with new hosts") return nil } @@ -670,8 +670,7 @@ func (s *ServiceController) lockedUpdateLoadBalancerHosts(service *api.Service, return nil } - message := "error updating loadbalancer with new hosts: " + err.Error() - s.eventRecorder.Event(service, "updating loadbalancer failed", message) + s.eventRecorder.Eventf(service, "LoadBalancerUpdateFailed", "Error updating load balancer with new hosts %v: %v", hosts, err) return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/servicecontroller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/servicecontroller_test.go index 7c7da8b3ef35..05e84abae0cf 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/servicecontroller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/service/servicecontroller_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package servicecontroller +package service import ( "reflect" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller.go index 27e933fd0f87..0bb3b5e48844 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller.go @@ -29,6 +29,7 @@ import ( "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/watch" ) @@ -43,8 +44,8 @@ func nameIndexFunc(obj interface{}) ([]string, error) { // ServiceAccountsControllerOptions contains options for running a ServiceAccountsController type ServiceAccountsControllerOptions struct { - // ServiceAccounts is the list of service accounts to ensure exist in every namespace - ServiceAccounts []api.ServiceAccount + // Names is the set of service account names to ensure exist in every namespace + Names sets.String // ServiceAccountResync is the interval between full resyncs of ServiceAccounts. // If non-zero, all service accounts will be re-listed this often. @@ -58,24 +59,20 @@ type ServiceAccountsControllerOptions struct { } func DefaultServiceAccountsControllerOptions() ServiceAccountsControllerOptions { - return ServiceAccountsControllerOptions{ - ServiceAccounts: []api.ServiceAccount{ - {ObjectMeta: api.ObjectMeta{Name: "default"}}, - }, - } + return ServiceAccountsControllerOptions{Names: sets.NewString("default")} } // NewServiceAccountsController returns a new *ServiceAccountsController. func NewServiceAccountsController(cl client.Interface, options ServiceAccountsControllerOptions) *ServiceAccountsController { e := &ServiceAccountsController{ - client: cl, - serviceAccountsToEnsure: options.ServiceAccounts, + client: cl, + names: options.Names, } accountSelector := fields.Everything() - if len(options.ServiceAccounts) == 1 { + if len(options.Names) == 1 { // If we're maintaining a single account, we can scope the accounts we watch to just that name - accountSelector = fields.SelectorFromSet(map[string]string{client.ObjectNameField: options.ServiceAccounts[0].Name}) + accountSelector = fields.SelectorFromSet(map[string]string{client.ObjectNameField: options.Names.List()[0]}) } e.serviceAccounts, e.serviceAccountController = framework.NewIndexerInformer( &cache.ListWatch{ @@ -119,8 +116,8 @@ func NewServiceAccountsController(cl client.Interface, options ServiceAccountsCo type ServiceAccountsController struct { stopChan chan struct{} - client client.Interface - serviceAccountsToEnsure []api.ServiceAccount + client client.Interface + names sets.String serviceAccounts cache.Indexer namespaces cache.Indexer @@ -156,26 +153,24 @@ func (e *ServiceAccountsController) serviceAccountDeleted(obj interface{}) { return } // If the deleted service account is one we're maintaining, recreate it - for _, sa := range e.serviceAccountsToEnsure { - if sa.Name == serviceAccount.Name { - e.createServiceAccountIfNeeded(sa, serviceAccount.Namespace) - } + if e.names.Has(serviceAccount.Name) { + e.createServiceAccountIfNeeded(serviceAccount.Name, serviceAccount.Namespace) } } // namespaceAdded reacts to a Namespace creation by creating a default ServiceAccount object func (e *ServiceAccountsController) namespaceAdded(obj interface{}) { namespace := obj.(*api.Namespace) - for _, sa := range e.serviceAccountsToEnsure { - e.createServiceAccountIfNeeded(sa, namespace.Name) + for _, name := range e.names.List() { + e.createServiceAccountIfNeeded(name, namespace.Name) } } // namespaceUpdated reacts to a Namespace update (or re-list) by creating a default ServiceAccount in the namespace if needed func (e *ServiceAccountsController) namespaceUpdated(oldObj interface{}, newObj interface{}) { newNamespace := newObj.(*api.Namespace) - for _, sa := range e.serviceAccountsToEnsure { - e.createServiceAccountIfNeeded(sa, newNamespace.Name) + for _, name := range e.names.List() { + e.createServiceAccountIfNeeded(name, newNamespace.Name) } } @@ -183,13 +178,13 @@ func (e *ServiceAccountsController) namespaceUpdated(oldObj interface{}, newObj // * the named ServiceAccount does not already exist // * the specified namespace exists // * the specified namespace is in the ACTIVE phase -func (e *ServiceAccountsController) createServiceAccountIfNeeded(sa api.ServiceAccount, namespace string) { - existingServiceAccount, err := e.getServiceAccount(sa.Name, namespace) +func (e *ServiceAccountsController) createServiceAccountIfNeeded(name, namespace string) { + serviceAccount, err := e.getServiceAccount(name, namespace) if err != nil { glog.Error(err) return } - if existingServiceAccount != nil { + if serviceAccount != nil { // If service account already exists, it doesn't need to be created return } @@ -208,18 +203,20 @@ func (e *ServiceAccountsController) createServiceAccountIfNeeded(sa api.ServiceA return } - e.createServiceAccount(sa, namespace) + e.createServiceAccount(name, namespace) } // createDefaultServiceAccount creates a default ServiceAccount in the specified namespace -func (e *ServiceAccountsController) createServiceAccount(sa api.ServiceAccount, namespace string) { - sa.Namespace = namespace - if _, err := e.client.ServiceAccounts(namespace).Create(&sa); err != nil { +func (e *ServiceAccountsController) createServiceAccount(name, namespace string) { + serviceAccount := &api.ServiceAccount{} + serviceAccount.Name = name + serviceAccount.Namespace = namespace + if _, err := e.client.ServiceAccounts(namespace).Create(serviceAccount); err != nil { glog.Error(err) } } -// getServiceAccount returns the ServiceAccount with the given name for the given namespace +// getDefaultServiceAccount returns the ServiceAccount with the given name for the given namespace func (e *ServiceAccountsController) getServiceAccount(name, namespace string) (*api.ServiceAccount, error) { key := &api.ServiceAccount{ObjectMeta: api.ObjectMeta{Namespace: namespace}} accounts, err := e.serviceAccounts.Index("namespace", key) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller_test.go index 8718c6478537..146ce7d567ea 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller_test.go @@ -17,15 +17,10 @@ limitations under the License. package serviceaccount import ( - "net/http" - "net/http/httptest" "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/client/unversioned/testclient" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" ) @@ -34,21 +29,6 @@ type serverResponse struct { obj interface{} } -func makeTestServer(t *testing.T, namespace string, serviceAccountResponse serverResponse) (*httptest.Server, *util.FakeHandler) { - fakeServiceAccountsHandler := util.FakeHandler{ - StatusCode: serviceAccountResponse.statusCode, - ResponseBody: runtime.EncodeOrDie(testapi.Default.Codec(), serviceAccountResponse.obj.(runtime.Object)), - } - - mux := http.NewServeMux() - mux.Handle(testapi.Default.ResourcePath("serviceAccounts", namespace, ""), &fakeServiceAccountsHandler) - mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) { - t.Errorf("unexpected request: %v", req.RequestURI) - res.WriteHeader(http.StatusNotFound) - }) - return httptest.NewServer(mux), &fakeServiceAccountsHandler -} - func TestServiceAccountCreation(t *testing.T) { ns := api.NamespaceDefault @@ -171,10 +151,7 @@ func TestServiceAccountCreation(t *testing.T) { for k, tc := range testcases { client := testclient.NewSimpleFake(defaultServiceAccount, managedServiceAccount) options := DefaultServiceAccountsControllerOptions() - options.ServiceAccounts = []api.ServiceAccount{ - {ObjectMeta: api.ObjectMeta{Name: defaultName}}, - {ObjectMeta: api.ObjectMeta{Name: managedName}}, - } + options.Names = sets.NewString(defaultName, managedName) controller := NewServiceAccountsController(client, options) if tc.ExistingNamespace != nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/tokens_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/tokens_controller.go index ce9bd657ceff..e4b6afaf4951 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/tokens_controller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/tokens_controller.go @@ -436,7 +436,7 @@ func (e *TokensController) removeSecretReferenceIfNeeded(serviceAccount *api.Ser // getServiceAccount returns the ServiceAccount referenced by the given secret. If the secret is not // of type ServiceAccountToken, or if the referenced ServiceAccount does not exist, nil is returned func (e *TokensController) getServiceAccount(secret *api.Secret, fetchOnCacheMiss bool) (*api.ServiceAccount, error) { - name, uid := serviceAccountNameAndUID(secret) + name, _ := serviceAccountNameAndUID(secret) if len(name) == 0 { return nil, nil } @@ -449,15 +449,10 @@ func (e *TokensController) getServiceAccount(secret *api.Secret, fetchOnCacheMis for _, obj := range namespaceAccounts { serviceAccount := obj.(*api.ServiceAccount) - if name != serviceAccount.Name { - // Name must match - continue - } - if len(uid) > 0 && uid != string(serviceAccount.UID) { - // If UID is specified, it must match - continue + + if IsServiceAccountToken(secret, serviceAccount) { + return serviceAccount, nil } - return serviceAccount, nil } if fetchOnCacheMiss { @@ -468,11 +463,10 @@ func (e *TokensController) getServiceAccount(secret *api.Secret, fetchOnCacheMis if err != nil { return nil, err } - if len(uid) > 0 && uid != string(serviceAccount.UID) { - // If UID is specified, it must match - return nil, nil + + if IsServiceAccountToken(secret, serviceAccount) { + return serviceAccount, nil } - return serviceAccount, nil } return nil, nil @@ -490,16 +484,10 @@ func (e *TokensController) listTokenSecrets(serviceAccount *api.ServiceAccount) items := []*api.Secret{} for _, obj := range namespaceSecrets { secret := obj.(*api.Secret) - name, uid := serviceAccountNameAndUID(secret) - if name != serviceAccount.Name { - // Name must match - continue - } - if len(uid) > 0 && uid != string(serviceAccount.UID) { - // If UID is specified, it must match - continue + + if IsServiceAccountToken(secret, serviceAccount) { + items = append(items, secret) } - items = append(items, secret) } return items, nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/util.go index 6f7e3e75050f..60791236429f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/util.go @@ -20,6 +20,7 @@ import ( "fmt" "strings" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/auth/user" ) @@ -81,3 +82,23 @@ func UserInfo(namespace, name, uid string) user.Info { Groups: MakeGroupNames(namespace, name), } } + +// IsServiceAccountToken returns true if the secret is a valid api token for the service account +func IsServiceAccountToken(secret *api.Secret, sa *api.ServiceAccount) bool { + if secret.Type != api.SecretTypeServiceAccountToken { + return false + } + + name := secret.Annotations[api.ServiceAccountNameKey] + uid := secret.Annotations[api.ServiceAccountUIDKey] + if name != sa.Name { + // Name must match + return false + } + if len(uid) > 0 && uid != string(sa.UID) { + // If UID is specified, it must match + return false + } + + return true +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/converter.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/converter.go index a77f321551f1..61025b617253 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/converter.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/converter.go @@ -583,7 +583,12 @@ func (c *Converter) defaultConvert(sv, dv reflect.Value, scope *scope) error { return nil } dv.Set(reflect.New(dt.Elem())) - return c.convert(sv.Elem(), dv.Elem(), scope) + switch st.Kind() { + case reflect.Ptr, reflect.Interface: + return c.convert(sv.Elem(), dv.Elem(), scope) + default: + return c.convert(sv, dv.Elem(), scope) + } case reflect.Map: if sv.IsNil() { // Don't copy a nil ptr! diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/converter_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/converter_test.go index 6ba1bac9cc80..2a110546bbd7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/converter_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/converter_test.go @@ -39,6 +39,34 @@ func TestConverter_byteSlice(t *testing.T) { } } +func TestConverter_MismatchedTypes(t *testing.T) { + c := NewConverter() + + err := c.RegisterConversionFunc( + func(in *[]string, out *int, s Scope) error { + if str, err := strconv.Atoi((*in)[0]); err != nil { + return err + } else { + *out = str + return nil + } + }, + ) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + src := []string{"5"} + var dest *int + err = c.Convert(&src, &dest, 0, nil) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if e, a := 5, *dest; e != a { + t.Errorf("expected %#v, got %#v", e, a) + } +} + func TestConverter_DefaultConvert(t *testing.T) { type A struct { Foo string diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/encode.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/encode.go index 10c16a2e0acb..7e1b82445bfa 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/encode.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/encode.go @@ -17,8 +17,11 @@ limitations under the License. package conversion import ( + "bytes" "encoding/json" "fmt" + "io" + "path" ) // EncodeToVersion turns the given api object into an appropriate JSON string. @@ -50,27 +53,49 @@ import ( // config files. // func (s *Scheme) EncodeToVersion(obj interface{}, destVersion string) (data []byte, err error) { + buff := &bytes.Buffer{} + if err := s.EncodeToVersionStream(obj, destVersion, buff); err != nil { + return nil, err + } + return buff.Bytes(), nil +} + +func (s *Scheme) EncodeToVersionStream(obj interface{}, destVersion string, stream io.Writer) error { obj = maybeCopy(obj) v, _ := EnforcePtr(obj) // maybeCopy guarantees a pointer + + // Don't encode an object defined in the unversioned package, unless if the + // destVersion is v1, encode it to v1 for backward compatibility. + pkg := path.Base(v.Type().PkgPath()) + if pkg == "unversioned" && destVersion != "v1" { + // TODO: convert this to streaming too + data, err := s.encodeUnversionedObject(obj) + if err != nil { + return err + } + _, err = stream.Write(data) + return err + } + if _, registered := s.typeToVersion[v.Type()]; !registered { - return nil, fmt.Errorf("type %v is not registered for %q and it will be impossible to Decode it, therefore Encode will refuse to encode it.", v.Type(), destVersion) + return fmt.Errorf("type %v is not registered for %q and it will be impossible to Decode it, therefore Encode will refuse to encode it.", v.Type(), destVersion) } objVersion, objKind, err := s.ObjectVersionAndKind(obj) if err != nil { - return nil, err + return err } // Perform a conversion if necessary. if objVersion != destVersion { objOut, err := s.NewObject(destVersion, objKind) if err != nil { - return nil, err + return err } flags, meta := s.generateConvertMeta(objVersion, destVersion, obj) err = s.converter.Convert(obj, objOut, flags, meta) if err != nil { - return nil, err + return err } obj = objOut } @@ -78,27 +103,45 @@ func (s *Scheme) EncodeToVersion(obj interface{}, destVersion string) (data []by // ensure the output object name comes from the destination type _, objKind, err = s.ObjectVersionAndKind(obj) if err != nil { - return nil, err + return err } // Version and Kind should be set on the wire. err = s.SetVersionAndKind(destVersion, objKind, obj) if err != nil { - return nil, err + return err } // To add metadata, do some simple surgery on the JSON. - data, err = json.Marshal(obj) - if err != nil { - return nil, err + encoder := json.NewEncoder(stream) + if err := encoder.Encode(obj); err != nil { + return err } // Version and Kind should be blank in memory. Reset them, since it's // possible that we modified a user object and not a copy above. err = s.SetVersionAndKind("", "", obj) if err != nil { - return nil, err + return err } + return nil +} + +func (s *Scheme) encodeUnversionedObject(obj interface{}) (data []byte, err error) { + _, objKind, err := s.ObjectVersionAndKind(obj) + if err != nil { + return nil, err + } + if err = s.SetVersionAndKind("", objKind, obj); err != nil { + return nil, err + } + data, err = json.Marshal(obj) + if err != nil { + return nil, err + } + // Version and Kind should be blank in memory. Reset them, since it's + // possible that we modified a user object and not a copy above. + err = s.SetVersionAndKind("", "", obj) return data, nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/meta.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/meta.go index 44ba29af67ff..1488570f30e0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/meta.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/meta.go @@ -19,6 +19,7 @@ package conversion import ( "encoding/json" "fmt" + "path" "reflect" ) @@ -77,6 +78,7 @@ func UpdateVersionAndKind(baseFields []string, versionField, version, kindField, if err != nil { return err } + pkg := path.Base(v.Type().PkgPath()) t := v.Type() name := t.Name() if v.Kind() != reflect.Struct { @@ -93,6 +95,15 @@ func UpdateVersionAndKind(baseFields []string, versionField, version, kindField, field := v.FieldByName(kindField) if !field.IsValid() { + // Types defined in the unversioned package are allowed to not have a + // kindField. Clients will have to know what they are based on the + // context. + // TODO: add some type trait here, or some way of indicating whether + // this feature is allowed on a per-type basis. Using package name is + // overly broad and a bit hacky. + if pkg == "unversioned" { + return nil + } return fmt.Errorf("couldn't find %v field in %#v", kindField, v.Interface()) } field.SetString(kind) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/meta_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/meta_test.go index df001d59f74e..452ea1483017 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/meta_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/meta_test.go @@ -17,8 +17,11 @@ limitations under the License. package conversion import ( + "fmt" "reflect" "testing" + + "k8s.io/kubernetes/pkg/api/unversioned" ) func TestSimpleMetaFactoryInterpret(t *testing.T) { @@ -72,6 +75,25 @@ func TestSimpleMetaFactoryUpdate(t *testing.T) { } } +// Test Updating objects that don't have a Kind field. +func TestSimpleMetaFactoryUpdateNoKindField(t *testing.T) { + factory := SimpleMetaFactory{VersionField: "APIVersion", KindField: "Kind"} + // obj does not have a Kind field and is not defined in the unversioned package. + obj := struct { + SomeField string + }{"1"} + expectedError := fmt.Errorf("couldn't find %v field in %#v", factory.KindField, obj) + if err := factory.Update("test", "other", &obj); err == nil || expectedError.Error() != err.Error() { + t.Fatalf("expected error: %v, got: %v", expectedError, err) + } + + // ListMeta does not have a Kind field, but is defined in the unversioned package. + listMeta := unversioned.ListMeta{} + if err := factory.Update("test", "other", &listMeta); err != nil { + t.Fatalf("unexpected error: %v", err) + } +} + func TestSimpleMetaFactoryUpdateStruct(t *testing.T) { factory := SimpleMetaFactory{BaseFields: []string{"Test"}, VersionField: "V", KindField: "K"} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/scheme.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/scheme.go index e534345a1ae7..1906178a9dc7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/scheme.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/scheme.go @@ -44,7 +44,8 @@ type Scheme struct { // deep copy behavior. cloner *Cloner - // Indent will cause the JSON output from Encode to be indented, iff it is true. + // Indent will cause the JSON output from Encode to be indented, + // if and only if it is true. Indent bool // InternalVersion is the default internal version. It is recommended that diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/unversioned_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/unversioned_test.go new file mode 100644 index 000000000000..a637ee09fe77 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/unversioned_test.go @@ -0,0 +1,92 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 conversion_test + +import ( + "encoding/json" + "reflect" + "testing" + + // TODO: Ideally we should create the necessary package structure in e.g., + // pkg/conversion/test/... instead of importing pkg/api here. + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/runtime" +) + +var status = &unversioned.Status{ + Status: unversioned.StatusFailure, + Code: 200, + Reason: unversioned.StatusReasonUnknown, + Message: "", +} + +func TestV1EncodeDecodeStatus(t *testing.T) { + + v1Codec := testapi.Default.Codec() + + encoded, err := v1Codec.Encode(status) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + typeMeta := unversioned.TypeMeta{} + if err := json.Unmarshal(encoded, &typeMeta); err != nil { + t.Errorf("unexpected error: %v", err) + } + if typeMeta.Kind != "Status" { + t.Errorf("Kind is not set to \"Status\". Got %v", string(encoded)) + } + if typeMeta.APIVersion != "v1" { + t.Errorf("APIVersion is not set to \"v1\". Got %v", string(encoded)) + } + decoded, err := v1Codec.Decode(encoded) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if !reflect.DeepEqual(status, decoded) { + t.Errorf("expected: %v, got: %v", status, decoded) + } +} + +func TestExperimentalEncodeDecodeStatus(t *testing.T) { + // TODO: caesarxuchao: use the testapi.Extensions.Codec() once the PR that + // moves experimental from v1 to v1beta1 got merged. + // expCodec := testapi.Extensions.Codec() + expCodec := runtime.CodecFor(api.Scheme, "extensions/v1beta1") + encoded, err := expCodec.Encode(status) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + typeMeta := unversioned.TypeMeta{} + if err := json.Unmarshal(encoded, &typeMeta); err != nil { + t.Errorf("unexpected error: %v", err) + } + if typeMeta.Kind != "Status" { + t.Errorf("Kind is not set to \"Status\". Got %s", encoded) + } + if typeMeta.APIVersion != "" { + t.Errorf("APIVersion is not set to \"\". Got %s", encoded) + } + decoded, err := expCodec.Decode(encoded) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if !reflect.DeepEqual(status, decoded) { + t.Errorf("expected: %v, got: %v", status, decoded) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/config.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/config.go index 6ba2adb67195..f03bd26c3189 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/config.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/config.go @@ -30,6 +30,13 @@ import ( "github.com/golang/glog" ) +// DockerConfigJson represents ~/.docker/config.json file info +// see https://github.com/docker/docker/pull/12009 +type DockerConfigJson struct { + Auths DockerConfig `json:"auths"` + HttpHeaders map[string]string `json:"HttpHeaders,omitempty"` +} + // DockerConfig represents the config file used by the docker CLI. // This config that represents the credentials that should be used // when pulling images from specific image repositories. @@ -47,8 +54,11 @@ var ( workingDirPath = "" homeDirPath = os.Getenv("HOME") rootDirPath = "/" + homeJsonDirPath = filepath.Join(homeDirPath, ".docker") + rootJsonDirPath = filepath.Join(rootDirPath, ".docker") - configFileName = ".dockercfg" + configFileName = ".dockercfg" + configJsonFileName = "config.json" ) func SetPreferredDockercfgPath(path string) { @@ -64,6 +74,32 @@ func GetPreferredDockercfgPath() string { } func ReadDockerConfigFile() (cfg DockerConfig, err error) { + // Try happy path first - latest config file + dockerConfigJsonLocations := []string{GetPreferredDockercfgPath(), workingDirPath, homeJsonDirPath, rootJsonDirPath} + for _, configPath := range dockerConfigJsonLocations { + absDockerConfigFileLocation, err := filepath.Abs(filepath.Join(configPath, configJsonFileName)) + if err != nil { + glog.Errorf("while trying to canonicalize %s: %v", configPath, err) + continue + } + glog.V(4).Infof("looking for .docker/config.json at %s", absDockerConfigFileLocation) + contents, err := ioutil.ReadFile(absDockerConfigFileLocation) + if os.IsNotExist(err) { + continue + } + if err != nil { + glog.V(4).Infof("while trying to read %s: %v", absDockerConfigFileLocation, err) + continue + } + cfg, err := readDockerConfigJsonFileFromBytes(contents) + if err == nil { + glog.V(4).Infof("found .docker/config.json at %s", absDockerConfigFileLocation) + return cfg, nil + } + } + glog.V(4).Infof("couldn't find valid .docker/config.json after checking in %v", dockerConfigJsonLocations) + + // Can't find latest config file so check for the old one dockerConfigFileLocations := []string{GetPreferredDockercfgPath(), workingDirPath, homeDirPath, rootDirPath} for _, configPath := range dockerConfigFileLocations { absDockerConfigFileLocation, err := filepath.Abs(filepath.Join(configPath, configFileName)) @@ -147,6 +183,16 @@ func readDockerConfigFileFromBytes(contents []byte) (cfg DockerConfig, err error return } +func readDockerConfigJsonFileFromBytes(contents []byte) (cfg DockerConfig, err error) { + var cfgJson DockerConfigJson + if err = json.Unmarshal(contents, &cfgJson); err != nil { + glog.Errorf("while trying to parse blob %q: %v", contents, err) + return nil, err + } + cfg = cfgJson.Auths + return +} + // dockerConfigEntryWithAuth is used solely for deserializing the Auth field // into a dockerConfigEntry during JSON deserialization. type dockerConfigEntryWithAuth struct { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/config_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/config_test.go index ea8c4c6e8776..587879fe9311 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/config_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/config_test.go @@ -22,6 +22,35 @@ import ( "testing" ) +func TestDockerConfigJsonJSONDecode(t *testing.T) { + input := []byte(`{"auths": {"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"}, "http://bar.example.com":{"username": "bar", "password": "baz", "email": "bar@example.com"}}}`) + + expect := DockerConfigJson{ + Auths: DockerConfig(map[string]DockerConfigEntry{ + "http://foo.example.com": { + Username: "foo", + Password: "bar", + Email: "foo@example.com", + }, + "http://bar.example.com": { + Username: "bar", + Password: "baz", + Email: "bar@example.com", + }, + }), + } + + var output DockerConfigJson + err := json.Unmarshal(input, &output) + if err != nil { + t.Errorf("Received unexpected error: %v", err) + } + + if !reflect.DeepEqual(expect, output) { + t.Errorf("Received unexpected output. Expected %#v, got %#v", expect, output) + } +} + func TestDockerConfigJSONDecode(t *testing.T) { input := []byte(`{"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"}, "http://bar.example.com":{"username": "bar", "password": "baz", "email": "bar@example.com"}}`) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/keyring.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/keyring.go index 404e8ed4aaef..0ea079aee5da 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/keyring.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/credentialprovider/keyring.go @@ -277,7 +277,14 @@ func (k *unionDockerKeyring) Lookup(image string) ([]docker.AuthConfiguration, b func MakeDockerKeyring(passedSecrets []api.Secret, defaultKeyring DockerKeyring) (DockerKeyring, error) { passedCredentials := []DockerConfig{} for _, passedSecret := range passedSecrets { - if dockercfgBytes, dockercfgExists := passedSecret.Data[api.DockerConfigKey]; (passedSecret.Type == api.SecretTypeDockercfg) && dockercfgExists && (len(dockercfgBytes) > 0) { + if dockerConfigJsonBytes, dockerConfigJsonExists := passedSecret.Data[api.DockerConfigJsonKey]; (passedSecret.Type == api.SecretTypeDockerConfigJson) && dockerConfigJsonExists && (len(dockerConfigJsonBytes) > 0) { + dockerConfigJson := DockerConfigJson{} + if err := json.Unmarshal(dockerConfigJsonBytes, &dockerConfigJson); err != nil { + return nil, err + } + + passedCredentials = append(passedCredentials, dockerConfigJson.Auths) + } else if dockercfgBytes, dockercfgExists := passedSecret.Data[api.DockerConfigKey]; (passedSecret.Type == api.SecretTypeDockercfg) && dockercfgExists && (len(dockercfgBytes) > 0) { dockercfg := DockerConfig{} if err := json.Unmarshal(dockercfgBytes, &dockercfg); err != nil { return nil, err diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/apply.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/apply.go new file mode 100644 index 000000000000..8b77abbd1f20 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/apply.go @@ -0,0 +1,179 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 kubectl + +import ( + "encoding/json" + + "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/kubectl/resource" +) + +type debugError interface { + DebugError() (msg string, args []interface{}) +} + +// LastAppliedConfigAnnotation is the annotation used to store the previous +// configuration of a resource for use in a three way diff by UpdateApplyAnnotation. +const LastAppliedConfigAnnotation = kubectlAnnotationPrefix + "last-applied-configuration" + +// GetOriginalConfiguration retrieves the original configuration of the object +// from the annotation, or nil if no annotation was found. +func GetOriginalConfiguration(info *resource.Info) ([]byte, error) { + annotations, err := info.Mapping.MetadataAccessor.Annotations(info.Object) + if err != nil { + return nil, err + } + + if annotations == nil { + return nil, nil + } + + original, ok := annotations[LastAppliedConfigAnnotation] + if !ok { + return nil, nil + } + + return []byte(original), nil +} + +// SetOriginalConfiguration sets the original configuration of the object +// as the annotation on the object for later use in computing a three way patch. +func SetOriginalConfiguration(info *resource.Info, original []byte) error { + if len(original) < 1 { + return nil + } + + accessor := info.Mapping.MetadataAccessor + annotations, err := accessor.Annotations(info.Object) + if err != nil { + return err + } + + if annotations == nil { + annotations = map[string]string{} + } + + annotations[LastAppliedConfigAnnotation] = string(original) + if err := info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annotations); err != nil { + return err + } + + return nil +} + +// GetModifiedConfiguration retrieves the modified configuration of the object. +// If annotate is true, it embeds the result as an anotation in the modified +// configuration. If an object was read from the command input, it will use that +// version of the object. Otherwise, it will use the version from the server. +func GetModifiedConfiguration(info *resource.Info, annotate bool) ([]byte, error) { + // First serialize the object without the annotation to prevent recursion, + // then add that serialization to it as the annotation and serialize it again. + var modified []byte + if info.VersionedObject != nil { + // If an object was read from input, use that version. + accessor, err := meta.Accessor(info.VersionedObject) + if err != nil { + return nil, err + } + + // Get the current annotations from the object. + annotations := accessor.Annotations() + if annotations == nil { + annotations = map[string]string{} + } + + original := annotations[LastAppliedConfigAnnotation] + delete(annotations, LastAppliedConfigAnnotation) + accessor.SetAnnotations(annotations) + modified, err = json.Marshal(info.VersionedObject) + if err != nil { + return nil, err + } + + if annotate { + annotations[LastAppliedConfigAnnotation] = string(modified) + accessor.SetAnnotations(annotations) + modified, err = json.Marshal(info.VersionedObject) + if err != nil { + return nil, err + } + } + + // Restore the object to its original condition. + annotations[LastAppliedConfigAnnotation] = original + accessor.SetAnnotations(annotations) + } else { + // Otherwise, use the server side version of the object. + accessor := info.Mapping.MetadataAccessor + // Get the current annotations from the object. + annotations, err := accessor.Annotations(info.Object) + if err != nil { + return nil, err + } + + if annotations == nil { + annotations = map[string]string{} + } + + original := annotations[LastAppliedConfigAnnotation] + delete(annotations, LastAppliedConfigAnnotation) + if err := accessor.SetAnnotations(info.Object, annotations); err != nil { + return nil, err + } + + modified, err = info.Mapping.Codec.Encode(info.Object) + if err != nil { + return nil, err + } + + if annotate { + annotations[LastAppliedConfigAnnotation] = string(modified) + if err := info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annotations); err != nil { + return nil, err + } + + modified, err = info.Mapping.Codec.Encode(info.Object) + if err != nil { + return nil, err + } + } + + // Restore the object to its original condition. + annotations[LastAppliedConfigAnnotation] = original + if err := info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annotations); err != nil { + return nil, err + } + } + + return modified, nil +} + +// UpdateApplyAnnotation gets the modified configuration of the object, +// without embedding it again, and then sets it on the object as the annotation. +func UpdateApplyAnnotation(info *resource.Info) error { + modified, err := GetModifiedConfiguration(info, false) + if err != nil { + return err + } + + if err := SetOriginalConfiguration(info, modified); err != nil { + return err + } + + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/annotate_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/annotate_test.go index ea45b030d06e..d518846bc3f4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/annotate_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/annotate_test.go @@ -26,6 +26,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/runtime" ) @@ -420,9 +421,9 @@ func TestAnnotateObject(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch req.Method { case "GET": switch req.URL.Path { @@ -467,9 +468,9 @@ func TestAnnotateObjectFromFile(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch req.Method { case "GET": switch req.URL.Path { @@ -515,9 +516,9 @@ func TestAnnotateMultipleObjects(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch req.Method { case "GET": switch req.URL.Path { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apiversions.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apiversions.go index 9694f0e4d7b4..fd5a4faa73ba 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apiversions.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apiversions.go @@ -23,7 +23,7 @@ import ( "github.com/spf13/cobra" - "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) @@ -57,12 +57,11 @@ func RunApiVersions(f *cmdutil.Factory, w io.Writer) error { os.Exit(1) } - var expAPIVersions *api.APIVersions - expAPIVersions, err = client.Experimental().ServerAPIVersions() - showExpVersions := (err == nil) + var expAPIVersions *unversioned.APIVersions + expAPIVersions, err = client.Extensions().ServerAPIVersions() fmt.Fprintf(w, "Available Server Api Versions: %#v\n", *apiVersions) - if showExpVersions { + if err == nil { fmt.Fprintf(w, "Available Server Experimental Api Versions: %#v\n", *expAPIVersions) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apply.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apply.go new file mode 100644 index 000000000000..b9da2105208e --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apply.go @@ -0,0 +1,164 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 cmd + +import ( + "fmt" + "io" + + "github.com/spf13/cobra" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/kubectl" + cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + "k8s.io/kubernetes/pkg/kubectl/resource" + "k8s.io/kubernetes/pkg/util/strategicpatch" +) + +// ApplyOptions stores cmd.Flag values for apply. As new fields are added, +// add them here instead of referencing the cmd.Flags() +type ApplyOptions struct { + Filenames []string +} + +const ( + apply_long = `Apply a configuration to a resource by filename or stdin. + +JSON and YAML formats are accepted.` + apply_example = `# Apply the configuration in pod.json to a pod. +$ kubectl apply -f ./pod.json + +# Apply the JSON passed into stdin to a pod. +$ cat pod.json | kubectl apply -f -` +) + +func NewCmdApply(f *cmdutil.Factory, out io.Writer) *cobra.Command { + options := &ApplyOptions{} + + cmd := &cobra.Command{ + Use: "apply -f FILENAME", + Short: "Apply a configuration to a resource by filename or stdin", + Long: apply_long, + Example: apply_example, + Run: func(cmd *cobra.Command, args []string) { + cmdutil.CheckErr(validateArgs(cmd, args)) + cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd)) + cmdutil.CheckErr(RunApply(f, cmd, out, options)) + }, + } + + usage := "Filename, directory, or URL to file that contains the configuration to apply" + kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage) + cmd.MarkFlagRequired("filename") + cmdutil.AddValidateFlags(cmd) + cmdutil.AddOutputFlagsForMutation(cmd) + return cmd +} + +func validateArgs(cmd *cobra.Command, args []string) error { + if len(args) != 0 { + return cmdutil.UsageError(cmd, "Unexpected args: %v", args) + } + + return nil +} + +func RunApply(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *ApplyOptions) error { + shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" + schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagString(cmd, "schema-cache-dir")) + if err != nil { + return err + } + + cmdNamespace, enforceNamespace, err := f.DefaultNamespace() + if err != nil { + return err + } + + mapper, typer := f.Object() + r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). + Schema(schema). + ContinueOnError(). + NamespaceParam(cmdNamespace).DefaultNamespace(). + FilenameParam(enforceNamespace, options.Filenames...). + Flatten(). + Do() + err = r.Err() + if err != nil { + return err + } + + count := 0 + err = r.Visit(func(info *resource.Info, err error) error { + // In this method, info.Object contains the object retrieved from the server + // and info.VersionedObject contains the object decoded from the input source. + if err != nil { + return err + } + + // Get the modified configuration of the object. Embed the result + // as an annotation in the modified configuration, so that it will appear + // in the patch sent to the server. + modified, err := kubectl.GetModifiedConfiguration(info, true) + if err != nil { + return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving modified configuration from:\n%v\nfor:", info), info.Source, err) + } + + if err := info.Get(); err != nil { + return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving current configuration of:\n%v\nfrom server for:", info), info.Source, err) + } + + // Serialize the current configuration of the object from the server. + current, err := info.Mapping.Codec.Encode(info.Object) + if err != nil { + return cmdutil.AddSourceToErr(fmt.Sprintf("serializing current configuration from:\n%v\nfor:", info), info.Source, err) + } + + // Retrieve the original configuration of the object from the annotation. + original, err := kubectl.GetOriginalConfiguration(info) + if err != nil { + return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving original configuration from:\n%v\nfor:", info), info.Source, err) + } + + // Compute a three way strategic merge patch to send to server. + patch, err := strategicpatch.CreateThreeWayMergePatch(original, modified, current, info.VersionedObject, false) + if err != nil { + format := "creating patch with:\noriginal:\n%s\nmodified:\n%s\ncurrent:\n%s\nfrom:\n%v\nfor:" + return cmdutil.AddSourceToErr(fmt.Sprintf(format, original, modified, current, info), info.Source, err) + } + + helper := resource.NewHelper(info.Client, info.Mapping) + _, err = helper.Patch(info.Namespace, info.Name, api.StrategicMergePatchType, patch) + if err != nil { + return cmdutil.AddSourceToErr(fmt.Sprintf("applying patch:\n%s\nto:\n%v\nfor:", patch, info), info.Source, err) + } + + count++ + cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "configured") + return nil + }) + + if err != nil { + return err + } + + if count == 0 { + return fmt.Errorf("no objects passed to apply") + } + + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apply_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apply_test.go new file mode 100644 index 000000000000..505a32400052 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/apply_test.go @@ -0,0 +1,260 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 cmd + +import ( + "bytes" + "encoding/json" + "io/ioutil" + "net/http" + "os" + "testing" + + "github.com/ghodss/yaml" + "github.com/spf13/cobra" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/unversioned/fake" + "k8s.io/kubernetes/pkg/kubectl" + cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + "k8s.io/kubernetes/pkg/runtime" +) + +func TestApplyExtraArgsFail(t *testing.T) { + buf := bytes.NewBuffer([]byte{}) + + f, _, _ := NewAPIFactory() + c := NewCmdApply(f, buf) + if validateApplyArgs(c, []string{"rc"}) == nil { + t.Fatalf("unexpected non-error") + } +} + +func validateApplyArgs(cmd *cobra.Command, args []string) error { + if len(args) != 0 { + return cmdutil.UsageError(cmd, "Unexpected args: %v", args) + } + return nil +} + +const ( + filenameRC = "../../../examples/guestbook/redis-master-controller.yaml" + filenameSVC = "../../../examples/guestbook/frontend-service.yaml" +) + +func readBytesFromFile(t *testing.T, filename string) []byte { + file, err := os.Open(filename) + if err != nil { + t.Fatal(err) + } + + data, err := ioutil.ReadAll(file) + if err != nil { + t.Fatal(err) + } + + return data +} + +func readReplicationControllerFromFile(t *testing.T, filename string) *api.ReplicationController { + data := readBytesFromFile(t, filename) + rc := api.ReplicationController{} + // TODO(jackgr): Replace with a call to testapi.Codec().Decode(). + if err := yaml.Unmarshal(data, &rc); err != nil { + t.Fatal(err) + } + + return &rc +} + +func readServiceFromFile(t *testing.T, filename string) *api.Service { + data := readBytesFromFile(t, filename) + svc := api.Service{} + // TODO(jackgr): Replace with a call to testapi.Codec().Decode(). + if err := yaml.Unmarshal(data, &svc); err != nil { + t.Fatal(err) + } + + return &svc +} + +func annotateRuntimeObject(t *testing.T, originalObj, currentObj runtime.Object, kind string) (string, []byte) { + originalMeta, err := api.ObjectMetaFor(originalObj) + if err != nil { + t.Fatal(err) + } + + originalMeta.Labels["DELETE_ME"] = "DELETE_ME" + original, err := json.Marshal(originalObj) + if err != nil { + t.Fatal(err) + } + + currentMeta, err := api.ObjectMetaFor(currentObj) + if err != nil { + t.Fatal(err) + } + + if currentMeta.Annotations == nil { + currentMeta.Annotations = map[string]string{} + } + + currentMeta.Annotations[kubectl.LastAppliedConfigAnnotation] = string(original) + current, err := json.Marshal(currentObj) + if err != nil { + t.Fatal(err) + } + + return currentMeta.Name, current +} + +func readAndAnnotateReplicationController(t *testing.T, filename string) (string, []byte) { + rc1 := readReplicationControllerFromFile(t, filename) + rc2 := readReplicationControllerFromFile(t, filename) + return annotateRuntimeObject(t, rc1, rc2, "ReplicationController") +} + +func readAndAnnotateService(t *testing.T, filename string) (string, []byte) { + svc1 := readServiceFromFile(t, filename) + svc2 := readServiceFromFile(t, filename) + return annotateRuntimeObject(t, svc1, svc2, "Service") +} + +func validatePatchApplication(t *testing.T, req *http.Request) { + patch, err := ioutil.ReadAll(req.Body) + if err != nil { + t.Fatal(err) + } + + patchMap := map[string]interface{}{} + if err := json.Unmarshal(patch, &patchMap); err != nil { + t.Fatal(err) + } + + annotationsMap := walkMapPath(t, patchMap, []string{"metadata", "annotations"}) + if _, ok := annotationsMap[kubectl.LastAppliedConfigAnnotation]; !ok { + t.Fatalf("patch does not contain annotation:\n%s\n", patch) + } + + labelMap := walkMapPath(t, patchMap, []string{"metadata", "labels"}) + if deleteMe, ok := labelMap["DELETE_ME"]; !ok || deleteMe != nil { + t.Fatalf("patch does not remove deleted key: DELETE_ME:\n%s\n", patch) + } +} + +func walkMapPath(t *testing.T, start map[string]interface{}, path []string) map[string]interface{} { + finish := start + for i := 0; i < len(path); i++ { + var ok bool + finish, ok = finish[path[i]].(map[string]interface{}) + if !ok { + t.Fatalf("key:%s of path:%v not found in map:%v", path[i], path, start) + } + } + + return finish +} + +func TestApplyObject(t *testing.T) { + nameRC, currentRC := readAndAnnotateReplicationController(t, filenameRC) + pathRC := "/namespaces/test/replicationcontrollers/" + nameRC + + f, tf, codec := NewAPIFactory() + tf.Printer = &testPrinter{} + tf.Client = &fake.RESTClient{ + Codec: codec, + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + switch p, m := req.URL.Path, req.Method; { + case p == pathRC && m == "GET": + bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC)) + return &http.Response{StatusCode: 200, Body: bodyRC}, nil + case p == pathRC && m == "PATCH": + validatePatchApplication(t, req) + bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC)) + return &http.Response{StatusCode: 200, Body: bodyRC}, nil + default: + t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) + return nil, nil + } + }), + } + tf.Namespace = "test" + buf := bytes.NewBuffer([]byte{}) + + cmd := NewCmdApply(f, buf) + cmd.Flags().Set("filename", filenameRC) + cmd.Flags().Set("output", "name") + cmd.Run(cmd, []string{}) + + // uses the name from the file, not the response + expectRC := "replicationcontroller/" + nameRC + "\n" + if buf.String() != expectRC { + t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expectRC) + } +} + +func TestApplyMultipleObject(t *testing.T) { + nameRC, currentRC := readAndAnnotateReplicationController(t, filenameRC) + pathRC := "/namespaces/test/replicationcontrollers/" + nameRC + + nameSVC, currentSVC := readAndAnnotateService(t, filenameSVC) + pathSVC := "/namespaces/test/services/" + nameSVC + + f, tf, codec := NewAPIFactory() + tf.Printer = &testPrinter{} + tf.Client = &fake.RESTClient{ + Codec: codec, + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + switch p, m := req.URL.Path, req.Method; { + case p == pathRC && m == "GET": + bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC)) + return &http.Response{StatusCode: 200, Body: bodyRC}, nil + case p == pathRC && m == "PATCH": + validatePatchApplication(t, req) + bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC)) + return &http.Response{StatusCode: 200, Body: bodyRC}, nil + case p == pathSVC && m == "GET": + bodySVC := ioutil.NopCloser(bytes.NewReader(currentSVC)) + return &http.Response{StatusCode: 200, Body: bodySVC}, nil + case p == pathSVC && m == "PATCH": + validatePatchApplication(t, req) + bodySVC := ioutil.NopCloser(bytes.NewReader(currentSVC)) + return &http.Response{StatusCode: 200, Body: bodySVC}, nil + default: + t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) + return nil, nil + } + }), + } + tf.Namespace = "test" + buf := bytes.NewBuffer([]byte{}) + + cmd := NewCmdApply(f, buf) + cmd.Flags().Set("filename", filenameRC) + cmd.Flags().Set("filename", filenameSVC) + cmd.Flags().Set("output", "name") + + cmd.Run(cmd, []string{}) + + // Names should come from the REST response, NOT the files + expectRC := "replicationcontroller/" + nameRC + "\n" + expectSVC := "service/" + nameSVC + "\n" + expect := expectRC + expectSVC + if buf.String() != expect { + t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expect) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/attach.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/attach.go index e3433121d176..6dcd579ccc96 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/attach.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/attach.go @@ -19,6 +19,7 @@ package cmd import ( "fmt" "io" + "net/url" "os" "os/signal" "syscall" @@ -39,7 +40,7 @@ $ kubectl attach 123456-7890 # Get output from ruby-container from pod 123456-7890 $ kubectl attach 123456-7890 -c ruby-container date -# Switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-780 +# Switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-7890 # and sends stdout/stderr from 'bash' back to the client $ kubectl attach 123456-7890 -c ruby-container -i -t` ) @@ -64,7 +65,7 @@ func NewCmdAttach(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) }, } // TODO support UID - cmd.Flags().StringVarP(&options.ContainerName, "container", "c", "", "Container name") + cmd.Flags().StringVarP(&options.ContainerName, "container", "c", "", "Container name. If omitted, the first container in the pod will be chosen") cmd.Flags().BoolVarP(&options.Stdin, "stdin", "i", false, "Pass stdin to the container") cmd.Flags().BoolVarP(&options.TTY, "tty", "t", false, "Stdin is a TTY") return cmd @@ -72,15 +73,18 @@ func NewCmdAttach(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) // RemoteAttach defines the interface accepted by the Attach command - provided for test stubbing type RemoteAttach interface { - Attach(req *client.Request, config *client.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error + Attach(method string, url *url.URL, config *client.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error } // DefaultRemoteAttach is the standard implementation of attaching type DefaultRemoteAttach struct{} -func (*DefaultRemoteAttach) Attach(req *client.Request, config *client.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { - attach := remotecommand.NewAttach(req, config, stdin, stdout, stderr, tty) - return attach.Execute() +func (*DefaultRemoteAttach) Attach(method string, url *url.URL, config *client.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { + exec, err := remotecommand.NewExecutor(config, method, url) + if err != nil { + return err + } + return exec.Stream(stdin, stdout, stderr, tty) } // AttachOptions declare the arguments accepted by the Exec command @@ -156,12 +160,6 @@ func (p *AttachOptions) Run() error { return fmt.Errorf("pod %s is not running and cannot be attached to; current phase is %s", p.PodName, pod.Status.Phase) } - containerName := p.ContainerName - if len(containerName) == 0 { - glog.V(4).Infof("defaulting container name to %s", pod.Spec.Containers[0].Name) - containerName = pod.Spec.Containers[0].Name - } - // TODO: refactor with terminal helpers from the edit utility once that is merged var stdin io.Reader tty := p.TTY @@ -205,7 +203,17 @@ func (p *AttachOptions) Run() error { Name(pod.Name). Namespace(pod.Namespace). SubResource("attach"). - Param("container", containerName) + Param("container", p.GetContainerName(pod)) + + return p.Attach.Attach("POST", req.URL(), p.Config, stdin, p.Out, p.Err, tty) +} + +// GetContainerName returns the name of the container to attach to, with a fallback. +func (p *AttachOptions) GetContainerName(pod *api.Pod) string { + if len(p.ContainerName) > 0 { + return p.ContainerName + } - return p.Attach.Attach(req, p.Config, stdin, p.Out, p.Err, tty) + glog.V(4).Infof("defaulting container name to %s", pod.Spec.Containers[0].Name) + return pod.Spec.Containers[0].Name } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/attach_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/attach_test.go index b7d336cd06fe..acf44470fd91 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/attach_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/attach_test.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "net/http" + "net/url" "testing" "github.com/spf13/cobra" @@ -28,15 +29,18 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" ) type fakeRemoteAttach struct { - req *client.Request + method string + url *url.URL attachErr error } -func (f *fakeRemoteAttach) Attach(req *client.Request, config *client.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { - f.req = req +func (f *fakeRemoteAttach) Attach(method string, url *url.URL, config *client.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { + f.method = method + f.url = url return f.attachErr } @@ -76,9 +80,9 @@ func TestPodAndContainerAttach(t *testing.T) { } for _, test := range tests { f, tf, codec := NewAPIFactory() - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { return nil, nil }), + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { return nil, nil }), } tf.Namespace = "test" tf.ClientConfig = &client.Config{} @@ -129,9 +133,9 @@ func TestAttach(t *testing.T) { } for _, test := range tests { f, tf, codec := NewAPIFactory() - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == test.podPath && m == "GET": body := objBody(codec, test.pod) @@ -172,10 +176,16 @@ func TestAttach(t *testing.T) { t.Errorf("%s: Unexpected error: %v", test.name, err) continue } - if !test.attachErr && ex.req.URL().Path != test.attachPath { + if test.attachErr { + continue + } + if ex.url.Path != test.attachPath { t.Errorf("%s: Did not get expected path for exec request", test.name) continue } + if ex.method != "POST" { + t.Errorf("%s: Did not get method for attach request: %s", test.name, ex.method) + } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go index e882d5a0d18c..b52b67161637 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go @@ -111,28 +111,17 @@ __custom_func() { ` valid_resources = `Valid resource types include: * pods (aka 'po') - * services (aka 'svc') - * deploymentconfigs (aka 'dc') - * buildconfigs (aka 'bc') - * builds - * routes * replicationcontrollers (aka 'rc') + * daemonsets (aka 'ds') + * services (aka 'svc') * events (aka 'ev') - * projects + * nodes (aka 'no') + * namespaces (aka 'ns') * secrets - * imagestraams (aka 'is') - * imagestreamtags (aka 'istag') - * imagestreamimages (aka 'isimage') * persistentvolumes (aka 'pv') * persistentvolumeclaims (aka 'pvc') - * policies - * rolebindings * limitranges (aka 'limits') * resourcequotas (aka 'quota') - * nodes (aka 'no') - * namespaces (aka 'ns') - * users - * groups ` ) @@ -160,6 +149,8 @@ Find more information at https://github.com/kubernetes/kubernetes.`, cmds.AddCommand(NewCmdReplace(f, out)) cmds.AddCommand(NewCmdPatch(f, out)) cmds.AddCommand(NewCmdDelete(f, out)) + cmds.AddCommand(NewCmdEdit(f, out)) + cmds.AddCommand(NewCmdApply(f, out)) cmds.AddCommand(NewCmdNamespace(out)) cmds.AddCommand(NewCmdLog(f, out)) @@ -182,6 +173,8 @@ Find more information at https://github.com/kubernetes/kubernetes.`, cmds.AddCommand(NewCmdClusterInfo(f, out)) cmds.AddCommand(NewCmdApiVersions(f, out)) cmds.AddCommand(NewCmdVersion(f, out)) + cmds.AddCommand(NewCmdExplain(f, out)) + cmds.AddCommand(NewCmdConvert(f, out)) return cmds } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd_test.go index 2ec74ffe4efd..b7377dcd0db4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd_test.go @@ -29,11 +29,12 @@ import ( "time" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/validation" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/kubectl" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" @@ -176,7 +177,7 @@ func NewTestFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) { func NewMixedFactory(apiClient resource.RESTClient) (*cmdutil.Factory, *testFactory, runtime.Codec) { f, t, c := NewTestFactory() f.Object = func() (meta.RESTMapper, runtime.ObjectTyper) { - return meta.MultiRESTMapper{t.Mapper, latest.RESTMapper}, runtime.MultiObjectTyper{t.Typer, api.Scheme} + return meta.MultiRESTMapper{t.Mapper, testapi.Default.RESTMapper()}, runtime.MultiObjectTyper{t.Typer, api.Scheme} } f.RESTClient = func(m *meta.RESTMapping) (resource.RESTClient, error) { if m.ObjectConvertor == api.Scheme { @@ -200,11 +201,11 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) { } f := &cmdutil.Factory{ Object: func() (meta.RESTMapper, runtime.ObjectTyper) { - return latest.RESTMapper, api.Scheme + return testapi.Default.RESTMapper(), api.Scheme }, Client: func() (*client.Client, error) { // Swap out the HTTP client out of the client with the fake's version. - fakeClient := t.Client.(*client.FakeRESTClient) + fakeClient := t.Client.(*fake.RESTClient) c := client.NewOrDie(t.ClientConfig) c.Client = fakeClient.Client return c, t.Err @@ -232,10 +233,9 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) { return generator, ok }, } - rf := cmdutil.NewFactory(nil) f.PodSelectorForObject = rf.PodSelectorForObject - + f.CanBeExposed = rf.CanBeExposed return f, t, testapi.Default.Codec() } @@ -270,7 +270,7 @@ func stringBody(body string) io.ReadCloser { func ExamplePrintReplicationControllerWithNamespace() { f, tf, codec := NewAPIFactory() tf.Printer = kubectl.NewHumanReadablePrinter(false, true, false, false, []string{}) - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Client: nil, } @@ -280,7 +280,7 @@ func ExamplePrintReplicationControllerWithNamespace() { Name: "foo", Namespace: "beep", Labels: map[string]string{"foo": "bar"}, - CreationTimestamp: util.Time{Time: time.Now().AddDate(-10, 0, 0)}, + CreationTimestamp: unversioned.Time{Time: time.Now().AddDate(-10, 0, 0)}, }, Spec: api.ReplicationControllerSpec{ Replicas: 1, @@ -312,7 +312,7 @@ func ExamplePrintReplicationControllerWithNamespace() { func ExamplePrintPodWithWideFormat() { f, tf, codec := NewAPIFactory() tf.Printer = kubectl.NewHumanReadablePrinter(false, false, true, false, []string{}) - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Client: nil, } @@ -321,7 +321,7 @@ func ExamplePrintPodWithWideFormat() { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test1", - CreationTimestamp: util.Time{Time: time.Now().AddDate(-10, 0, 0)}, + CreationTimestamp: unversioned.Time{Time: time.Now().AddDate(-10, 0, 0)}, }, Spec: api.PodSpec{ Containers: make([]api.Container, 2), @@ -351,7 +351,7 @@ func newAllPhasePodList() *api.PodList { { ObjectMeta: api.ObjectMeta{ Name: "test1", - CreationTimestamp: util.Time{time.Now().AddDate(-10, 0, 0)}, + CreationTimestamp: unversioned.Time{time.Now().AddDate(-10, 0, 0)}, }, Spec: api.PodSpec{ Containers: make([]api.Container, 2), @@ -368,7 +368,7 @@ func newAllPhasePodList() *api.PodList { { ObjectMeta: api.ObjectMeta{ Name: "test2", - CreationTimestamp: util.Time{time.Now().AddDate(-10, 0, 0)}, + CreationTimestamp: unversioned.Time{time.Now().AddDate(-10, 0, 0)}, }, Spec: api.PodSpec{ Containers: make([]api.Container, 2), @@ -385,7 +385,7 @@ func newAllPhasePodList() *api.PodList { { ObjectMeta: api.ObjectMeta{ Name: "test3", - CreationTimestamp: util.Time{time.Now().AddDate(-10, 0, 0)}, + CreationTimestamp: unversioned.Time{time.Now().AddDate(-10, 0, 0)}, }, Spec: api.PodSpec{ Containers: make([]api.Container, 2), @@ -402,7 +402,7 @@ func newAllPhasePodList() *api.PodList { { ObjectMeta: api.ObjectMeta{ Name: "test4", - CreationTimestamp: util.Time{time.Now().AddDate(-10, 0, 0)}, + CreationTimestamp: unversioned.Time{time.Now().AddDate(-10, 0, 0)}, }, Spec: api.PodSpec{ Containers: make([]api.Container, 2), @@ -419,7 +419,7 @@ func newAllPhasePodList() *api.PodList { { ObjectMeta: api.ObjectMeta{ Name: "test5", - CreationTimestamp: util.Time{time.Now().AddDate(-10, 0, 0)}, + CreationTimestamp: unversioned.Time{time.Now().AddDate(-10, 0, 0)}, }, Spec: api.PodSpec{ Containers: make([]api.Container, 2), @@ -439,7 +439,7 @@ func newAllPhasePodList() *api.PodList { func ExamplePrintPodHideTerminated() { f, tf, codec := NewAPIFactory() tf.Printer = kubectl.NewHumanReadablePrinter(false, false, false, false, []string{}) - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Client: nil, } @@ -459,7 +459,7 @@ func ExamplePrintPodHideTerminated() { func ExamplePrintPodShowAll() { f, tf, codec := NewAPIFactory() tf.Printer = kubectl.NewHumanReadablePrinter(false, false, false, true, []string{}) - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Client: nil, } @@ -481,7 +481,7 @@ func ExamplePrintPodShowAll() { func ExamplePrintServiceWithNamespacesAndLabels() { f, tf, codec := NewAPIFactory() tf.Printer = kubectl.NewHumanReadablePrinter(false, true, false, false, []string{"l1"}) - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Client: nil, } @@ -492,7 +492,7 @@ func ExamplePrintServiceWithNamespacesAndLabels() { ObjectMeta: api.ObjectMeta{ Name: "svc1", Namespace: "ns1", - CreationTimestamp: util.Time{Time: time.Now().AddDate(-10, 0, 0)}, + CreationTimestamp: unversioned.Time{Time: time.Now().AddDate(-10, 0, 0)}, Labels: map[string]string{ "l1": "value", }, @@ -513,7 +513,7 @@ func ExamplePrintServiceWithNamespacesAndLabels() { ObjectMeta: api.ObjectMeta{ Name: "svc2", Namespace: "ns2", - CreationTimestamp: util.Time{Time: time.Now().AddDate(-10, 0, 0)}, + CreationTimestamp: unversioned.Time{Time: time.Now().AddDate(-10, 0, 0)}, Labels: map[string]string{ "l1": "dolla-bill-yall", }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/config.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/config.go index d45b1dac772e..d73ea26804eb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/config.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/config.go @@ -100,7 +100,7 @@ func NewDefaultPathOptions() *PathOptions { EnvVar: clientcmd.RecommendedConfigPathEnvVar, ExplicitFileFlag: clientcmd.RecommendedConfigPathFlag, - GlobalFileSubpath: clientcmd.RecommendedHomeFileName, + GlobalFileSubpath: path.Join(clientcmd.RecommendedHomeDir, clientcmd.RecommendedFileName), LoadingRules: clientcmd.NewDefaultClientConfigLoadingRules(), } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/config_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/config_test.go index 3fe325e5e046..eb7401fa8f87 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/config_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/config_test.go @@ -101,7 +101,7 @@ func TestSetNonExistentContext(t *testing.T) { args: []string{"use-context", "non-existent-config"}, startingConfig: expectedConfig, expectedConfig: expectedConfig, - expectedOutputs: []string{`No context exists with the name: "non-existent-config"`}, + expectedOutputs: []string{`no context exists with the name: "non-existent-config"`}, } test.run(t) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_authinfo.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_authinfo.go index e46c2bb3d6f5..65422668feb4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_authinfo.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_authinfo.go @@ -84,6 +84,8 @@ func NewCmdConfigSetAuthInfo(out io.Writer, configAccess ConfigAccess) *cobra.Co err := options.run() if err != nil { fmt.Fprintf(out, "%v\n", err) + } else { + fmt.Fprintf(out, "user %q set.\n", options.name) } }, } @@ -197,7 +199,7 @@ func (o *createAuthInfoOptions) complete(cmd *cobra.Command) bool { func (o createAuthInfoOptions) validate() error { if len(o.name) == 0 { - return errors.New("You must specify a non-empty user name") + return errors.New("you must specify a non-empty user name") } methods := []string{} if len(o.token.Value()) > 0 { @@ -207,22 +209,22 @@ func (o createAuthInfoOptions) validate() error { methods = append(methods, fmt.Sprintf("--%v/--%v", clientcmd.FlagUsername, clientcmd.FlagPassword)) } if len(methods) > 1 { - return fmt.Errorf("You cannot specify more than one authentication method at the same time: %v", strings.Join(methods, ", ")) + return fmt.Errorf("you cannot specify more than one authentication method at the same time: %v", strings.Join(methods, ", ")) } if o.embedCertData.Value() { certPath := o.clientCertificate.Value() keyPath := o.clientKey.Value() if certPath == "" && keyPath == "" { - return fmt.Errorf("You must specify a --%s or --%s to embed", clientcmd.FlagCertFile, clientcmd.FlagKeyFile) + return fmt.Errorf("you must specify a --%s or --%s to embed", clientcmd.FlagCertFile, clientcmd.FlagKeyFile) } if certPath != "" { if _, err := ioutil.ReadFile(certPath); err != nil { - return fmt.Errorf("Error reading %s data from %s: %v", clientcmd.FlagCertFile, certPath, err) + return fmt.Errorf("error reading %s data from %s: %v", clientcmd.FlagCertFile, certPath, err) } } if keyPath != "" { if _, err := ioutil.ReadFile(keyPath); err != nil { - return fmt.Errorf("Error reading %s data from %s: %v", clientcmd.FlagKeyFile, keyPath, err) + return fmt.Errorf("error reading %s data from %s: %v", clientcmd.FlagKeyFile, keyPath, err) } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_cluster.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_cluster.go index 3fd0432e7235..fb1d086c3659 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_cluster.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_cluster.go @@ -69,6 +69,8 @@ func NewCmdConfigSetCluster(out io.Writer, configAccess ConfigAccess) *cobra.Com err := options.run() if err != nil { fmt.Fprintf(out, "%v\n", err) + } else { + fmt.Fprintf(out, "cluster %q set.\n", options.name) } }, } @@ -160,18 +162,18 @@ func (o *createClusterOptions) complete(cmd *cobra.Command) bool { func (o createClusterOptions) validate() error { if len(o.name) == 0 { - return errors.New("You must specify a non-empty cluster name") + return errors.New("you must specify a non-empty cluster name") } if o.insecureSkipTLSVerify.Value() && o.certificateAuthority.Value() != "" { - return errors.New("You cannot specify a certificate authority and insecure mode at the same time") + return errors.New("you cannot specify a certificate authority and insecure mode at the same time") } if o.embedCAData.Value() { caPath := o.certificateAuthority.Value() if caPath == "" { - return fmt.Errorf("You must specify a --%s to embed", clientcmd.FlagCAFile) + return fmt.Errorf("you must specify a --%s to embed", clientcmd.FlagCAFile) } if _, err := ioutil.ReadFile(caPath); err != nil { - return fmt.Errorf("Could not read %s data from %s: %v", clientcmd.FlagCAFile, caPath, err) + return fmt.Errorf("could not read %s data from %s: %v", clientcmd.FlagCAFile, caPath, err) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_context.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_context.go index 584f255b855e..093ce944c421 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_context.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_context.go @@ -58,7 +58,9 @@ func NewCmdConfigSetContext(out io.Writer, configAccess ConfigAccess) *cobra.Com err := options.run() if err != nil { - fmt.Printf("%v\n", err) + fmt.Fprintf(out, "%v\n", err) + } else { + fmt.Fprintf(out, "context %q set.\n", options.name) } }, } @@ -124,7 +126,7 @@ func (o *createContextOptions) complete(cmd *cobra.Command) bool { func (o createContextOptions) validate() error { if len(o.name) == 0 { - return errors.New("You must specify a non-empty context name") + return errors.New("you must specify a non-empty context name") } return nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/set.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/set.go index 65f3d0294420..c175a23c2f1a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/set.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/set.go @@ -55,7 +55,9 @@ func NewCmdConfigSet(out io.Writer, configAccess ConfigAccess) *cobra.Command { err := options.run() if err != nil { - fmt.Printf("%v\n", err) + fmt.Fprintf(out, "%v\n", err) + } else { + fmt.Fprintf(out, "property %q set.\n", options.propertyName) } }, } @@ -103,11 +105,11 @@ func (o *setOptions) complete(cmd *cobra.Command) bool { func (o setOptions) validate() error { if len(o.propertyValue) == 0 { - return errors.New("You cannot use set to unset a property") + return errors.New("you cannot use set to unset a property") } if len(o.propertyName) == 0 { - return errors.New("You must specify a property") + return errors.New("you must specify a property") } return nil @@ -124,7 +126,7 @@ func modifyConfig(curr reflect.Value, steps *navigationSteps, propertyValue stri switch actualCurrValue.Kind() { case reflect.Map: if !steps.moreStepsRemaining() && !unset { - return fmt.Errorf("Can't set a map to a value: %v", actualCurrValue) + return fmt.Errorf("can't set a map to a value: %v", actualCurrValue) } mapKey := reflect.ValueOf(currStep.stepValue) @@ -152,14 +154,14 @@ func modifyConfig(curr reflect.Value, steps *navigationSteps, propertyValue stri case reflect.String: if steps.moreStepsRemaining() { - return fmt.Errorf("Can't have more steps after a string. %v", steps) + return fmt.Errorf("can't have more steps after a string. %v", steps) } actualCurrValue.SetString(propertyValue) return nil case reflect.Bool: if steps.moreStepsRemaining() { - return fmt.Errorf("Can't have more steps after a bool. %v", steps) + return fmt.Errorf("can't have more steps after a bool. %v", steps) } boolValue, err := toBool(propertyValue) if err != nil { @@ -198,9 +200,9 @@ func modifyConfig(curr reflect.Value, steps *navigationSteps, propertyValue stri } } - return fmt.Errorf("Unable to locate path %#v under %v", currStep, actualCurrValue) + return fmt.Errorf("unable to locate path %#v under %v", currStep, actualCurrValue) } - panic(fmt.Errorf("Unrecognized type: %v", actualCurrValue)) + panic(fmt.Errorf("unrecognized type: %v", actualCurrValue)) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/unset.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/unset.go index ef418060b623..555309ccbe5d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/unset.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/unset.go @@ -47,7 +47,9 @@ func NewCmdConfigUnset(out io.Writer, configAccess ConfigAccess) *cobra.Command err := options.run() if err != nil { - fmt.Printf("%v\n", err) + fmt.Fprintf(out, "%v\n", err) + } else { + fmt.Fprintf(out, "property %q unset.\n", options.propertyName) } }, } @@ -95,7 +97,7 @@ func (o *unsetOptions) complete(cmd *cobra.Command) bool { func (o unsetOptions) validate() error { if len(o.propertyName) == 0 { - return errors.New("You must specify a property") + return errors.New("you must specify a property") } return nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/use_context.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/use_context.go index fad34b7ef3f6..a6a5c26d557c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/use_context.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/use_context.go @@ -46,6 +46,8 @@ func NewCmdConfigUseContext(out io.Writer, configAccess ConfigAccess) *cobra.Com err := options.run() if err != nil { fmt.Fprintf(out, "%v\n", err) + } else { + fmt.Fprintf(out, "switched to context %q.\n", options.contextName) } }, } @@ -86,7 +88,7 @@ func (o *useContextOptions) complete(cmd *cobra.Command) bool { func (o useContextOptions) validate(config *clientcmdapi.Config) error { if len(o.contextName) == 0 { - return errors.New("You must specify a current-context") + return errors.New("you must specify a current-context") } for name := range config.Contexts { @@ -95,5 +97,5 @@ func (o useContextOptions) validate(config *clientcmdapi.Config) error { } } - return fmt.Errorf("No context exists with the name: %q.", o.contextName) + return fmt.Errorf("no context exists with the name: %q.", o.contextName) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/view.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/view.go index 498be7ef106c..8220645eabdc 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/view.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/config/view.go @@ -40,7 +40,7 @@ type ViewOptions struct { } const ( - view_long = `displays Merged kubeconfig settings or a specified kubeconfig file. + view_long = `Displays merged kubeconfig settings or a specified kubeconfig file. You can use --output=template --template=TEMPLATE to extract specific values.` view_example = `# Show Merged kubeconfig settings. @@ -55,7 +55,7 @@ func NewCmdConfigView(out io.Writer, ConfigAccess ConfigAccess) *cobra.Command { cmd := &cobra.Command{ Use: "view", - Short: "displays Merged kubeconfig settings or a specified kubeconfig file.", + Short: "Displays merged kubeconfig settings or a specified kubeconfig file.", Long: view_long, Example: view_example, Run: func(cmd *cobra.Command, args []string) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/convert.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/convert.go new file mode 100644 index 000000000000..8421b46c5595 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/convert.go @@ -0,0 +1,156 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 cmd + +import ( + "fmt" + "io" + + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/registered" + "k8s.io/kubernetes/pkg/kubectl" + cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + "k8s.io/kubernetes/pkg/kubectl/resource" + + "github.com/spf13/cobra" +) + +const ( + convert_long = `Convert config files between different API versions. Both YAML +and JSON formats are accepted. + +The command takes filename, directory, or URL as input, and convert it into format +of version specified by --output-version flag. If target version is not specified or +not supported, convert to latest version. + +The default output will be printed to stdout in YAML format. One can use -o option +to change to output destination. +` + convert_example = `# Convert 'pod.yaml' to latest version and print to stdout. +$ kubectl convert -f pod.yaml + +# Convert the live state of the resource specified by 'pod.yaml' to the latest version +# and print to stdout in json format. +$ kubectl convert -f pod.yaml --local -o json + +# Convert all files under current directory to latest version and create them all. +$ kubectl convert -f . | kubectl create -f - +` +) + +// NewCmdConvert creates a command object for the generic "convert" action, which +// translates the config file into a given version. +func NewCmdConvert(f *cmdutil.Factory, out io.Writer) *cobra.Command { + options := &ConvertOptions{} + + cmd := &cobra.Command{ + Use: "convert -f FILENAME", + Short: "Convert config files between different API versions", + Long: convert_long, + Example: convert_example, + Run: func(cmd *cobra.Command, args []string) { + err := options.Complete(f, out, cmd, args) + cmdutil.CheckErr(err) + err = options.RunConvert() + cmdutil.CheckErr(err) + }, + } + + usage := "Filename, directory, or URL to file to need to get converted." + kubectl.AddJsonFilenameFlag(cmd, &options.filenames, usage) + cmd.MarkFlagRequired("filename") + cmdutil.AddValidateFlags(cmd) + cmdutil.AddPrinterFlags(cmd) + cmd.Flags().BoolVar(&options.local, "local", true, "If true, convert will NOT try to contact api-server but run locally.") + + return cmd +} + +// ConvertOptions have the data required to perform the convert operation +type ConvertOptions struct { + builder *resource.Builder + filenames []string + local bool + + out io.Writer + printer kubectl.ResourcePrinter + + outputVersion string +} + +// Complete collects information required to run Convert command from command line. +func (o *ConvertOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) (err error) { + o.outputVersion = cmdutil.OutputVersion(cmd, latest.GroupOrDie("").Version) + if !registered.IsRegisteredAPIVersion(o.outputVersion) { + cmdutil.UsageError(cmd, "'%s' is not a registered version.", o.outputVersion) + } + + // build the builder + mapper, typer := f.Object() + if o.local { + fmt.Fprintln(out, "running in local mode...") + o.builder = resource.NewBuilder(mapper, typer, f.NilClientMapperForCommand()) + } else { + o.builder = resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()) + schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagString(cmd, "schema-cache-dir")) + if err != nil { + return err + } + o.builder = o.builder.Schema(schema) + } + cmdNamespace, _, err := f.DefaultNamespace() + if err != nil { + return err + } + o.builder = o.builder.NamespaceParam(cmdNamespace). + ContinueOnError(). + FilenameParam(false, o.filenames...). + Flatten() + + // build the printer + o.out = out + outputFormat := cmdutil.GetFlagString(cmd, "output") + templateFile := cmdutil.GetFlagString(cmd, "template") + if len(outputFormat) == 0 { + if len(templateFile) == 0 { + outputFormat = "yaml" + } else { + outputFormat = "template" + } + } + o.printer, _, err = kubectl.GetPrinter(outputFormat, templateFile) + if err != nil { + return err + } + + return nil +} + +// RunConvert implements the generic Convert command +func (o *ConvertOptions) RunConvert() error { + infos, err := o.builder.Do().Infos() + if err != nil { + return err + } + + objects, err := resource.AsVersionedObject(infos, false, o.outputVersion) + if err != nil { + return err + } + + return o.printer.PrintObj(objects, o.out) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/create.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/create.go index 4753340886e8..7693dce9e69b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/create.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/create.go @@ -106,14 +106,23 @@ func RunCreate(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *C if err != nil { return err } + + // Update the annotation used by kubectl apply + if err := kubectl.UpdateApplyAnnotation(info); err != nil { + return cmdutil.AddSourceToErr("creating", info.Source, err) + } + + // Serialize the object with the annotation applied. data, err := info.Mapping.Codec.Encode(info.Object) if err != nil { return cmdutil.AddSourceToErr("creating", info.Source, err) } + obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, data) if err != nil { return cmdutil.AddSourceToErr("creating", info.Source, err) } + count++ info.Refresh(obj, true) shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/create_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/create_test.go index aed138bd9f2e..d1f2cfe0f9bd 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/create_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/create_test.go @@ -22,7 +22,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/runtime" ) @@ -42,9 +42,9 @@ func TestCreateObject(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers" && m == "POST": return &http.Response{StatusCode: 201, Body: objBody(codec, &rc.Items[0])}, nil @@ -73,9 +73,9 @@ func TestCreateMultipleObject(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/services" && m == "POST": return &http.Response{StatusCode: 201, Body: objBody(codec, &svc.Items[0])}, nil @@ -108,9 +108,9 @@ func TestCreateDirectory(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/services" && m == "POST": return &http.Response{StatusCode: 201, Body: objBody(codec, &svc.Items[0])}, nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/delete_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/delete_test.go index 8be48805d0ad..c74a1c079423 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/delete_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/delete_test.go @@ -25,7 +25,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/testapi" - client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" ) func TestDeleteObjectByTuple(t *testing.T) { @@ -33,9 +34,9 @@ func TestDeleteObjectByTuple(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "DELETE": return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil @@ -65,9 +66,9 @@ func TestDeleteNamedObject(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "DELETE": return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil @@ -97,9 +98,9 @@ func TestDeleteObject(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE": return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil @@ -127,9 +128,9 @@ func TestDeleteObject(t *testing.T) { func TestDeleteObjectNotFound(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE": return &http.Response{StatusCode: 404, Body: stringBody("")}, nil @@ -157,9 +158,9 @@ func TestDeleteObjectNotFound(t *testing.T) { func TestDeleteObjectIgnoreNotFound(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE": return &http.Response{StatusCode: 404, Body: stringBody("")}, nil @@ -194,9 +195,9 @@ func TestDeleteAllNotFound(t *testing.T) { notFoundError := &errors.NewNotFound("Service", "foo").(*errors.StatusError).ErrStatus tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/services" && m == "GET": return &http.Response{StatusCode: 200, Body: objBody(codec, svc)}, nil @@ -236,9 +237,9 @@ func TestDeleteAllIgnoreNotFound(t *testing.T) { notFoundError := &errors.NewNotFound("Service", "foo").(*errors.StatusError).ErrStatus tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/services" && m == "GET": return &http.Response{StatusCode: 200, Body: objBody(codec, svc)}, nil @@ -271,9 +272,9 @@ func TestDeleteMultipleObject(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE": return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil @@ -305,9 +306,9 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE": return &http.Response{StatusCode: 404, Body: stringBody("")}, nil @@ -342,9 +343,9 @@ func TestDeleteMultipleResourcesWithTheSameName(t *testing.T) { _, svc, rc := testData() f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/baz" && m == "DELETE": return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil @@ -378,9 +379,9 @@ func TestDeleteDirectory(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case strings.HasPrefix(p, "/namespaces/test/services/") && m == "DELETE": return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil @@ -411,17 +412,17 @@ func TestDeleteMultipleSelector(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/pods" && m == "GET": - if req.URL.Query().Get(api.LabelSelectorQueryParam(testapi.Default.Version())) != "a=b" { + if req.URL.Query().Get(unversioned.LabelSelectorQueryParam(testapi.Default.Version())) != "a=b" { t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) } return &http.Response{StatusCode: 200, Body: objBody(codec, pods)}, nil case p == "/namespaces/test/services" && m == "GET": - if req.URL.Query().Get(api.LabelSelectorQueryParam(testapi.Default.Version())) != "a=b" { + if req.URL.Query().Get(unversioned.LabelSelectorQueryParam(testapi.Default.Version())) != "a=b" { t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) } return &http.Response{StatusCode: 200, Body: objBody(codec, svc)}, nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/describe_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/describe_test.go index 2637ba0f0441..4c473eb9e822 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/describe_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/describe_test.go @@ -22,7 +22,7 @@ import ( "net/http" "testing" - client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" ) // Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get. @@ -30,7 +30,7 @@ func TestDescribeUnknownSchemaObject(t *testing.T) { d := &testDescriber{Output: "test output"} f, tf, codec := NewTestFactory() tf.Describer = d - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Resp: &http.Response{StatusCode: 200, Body: objBody(codec, &internalType{Name: "foo"})}, } @@ -54,9 +54,9 @@ func TestDescribeObject(t *testing.T) { f, tf, codec := NewAPIFactory() d := &testDescriber{Output: "test output"} tf.Describer = d - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "GET": return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil @@ -87,7 +87,7 @@ func TestDescribeListObjects(t *testing.T) { f, tf, codec := NewAPIFactory() d := &testDescriber{Output: "test output"} tf.Describer = d - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Resp: &http.Response{StatusCode: 200, Body: objBody(codec, pods)}, } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/edit.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/edit.go new file mode 100644 index 000000000000..83c5ed46a9e6 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/edit.go @@ -0,0 +1,397 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 cmd + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "io" + "os" + "strings" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/errors" + client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/kubectl" + cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + "k8s.io/kubernetes/pkg/kubectl/cmd/util/editor" + "k8s.io/kubernetes/pkg/kubectl/cmd/util/jsonmerge" + "k8s.io/kubernetes/pkg/kubectl/resource" + "k8s.io/kubernetes/pkg/util/strategicpatch" + "k8s.io/kubernetes/pkg/util/yaml" + + "github.com/golang/glog" + "github.com/spf13/cobra" +) + +const ( + editLong = `Edit a resource from the default editor. + +The edit command allows you to directly edit any API resource you can retrieve via the +command line tools. It will open the editor defined by your KUBE_EDITOR, GIT_EDITOR, +or EDITOR environment variables, or fall back to 'vi'. You can edit multiple objects, +although changes are applied one at a time. The command accepts filenames as well as +command line arguments, although the files you point to must be previously saved +versions of resources. + +The files to edit will be output in the default API version, or a version specified +by --output-version. The default format is YAML - if you would like to edit in JSON +pass -o json. + +In the event an error occurs while updating, a temporary file will be created on disk +that contains your unapplied changes. The most common error when updating a resource +is another editor changing the resource on the server. When this occurs, you will have +to apply your changes to the newer version of the resource, or update your temporary +saved copy to include the latest resource version.` + + editExample = ` # Edit the service named 'docker-registry': + $ kubectl edit svc/docker-registry + + # Use an alternative editor + $ KUBE_EDITOR="nano" kubectl edit svc/docker-registry + + # Edit the service 'docker-registry' in JSON using the v1 API format: + $ kubectl edit svc/docker-registry --output-version=v1 -o json` +) + +var errExit = fmt.Errorf("exit directly") + +func NewCmdEdit(f *cmdutil.Factory, out io.Writer) *cobra.Command { + filenames := []string{} + cmd := &cobra.Command{ + Use: "edit (RESOURCE/NAME | -f FILENAME)", + Short: "Edit a resource on the server", + Long: editLong, + Example: fmt.Sprintf(editExample), + Run: func(cmd *cobra.Command, args []string) { + err := RunEdit(f, out, cmd, args, filenames) + if err == errExit { + os.Exit(1) + } + cmdutil.CheckErr(err) + }, + } + usage := "Filename, directory, or URL to file to use to edit the resource" + kubectl.AddJsonFilenameFlag(cmd, &filenames, usage) + cmd.Flags().StringP("output", "o", "yaml", "Output format. One of: yaml|json.") + cmd.Flags().String("output-version", "", "Output the formatted object with the given version (default api-version).") + return cmd +} + +func RunEdit(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames []string) error { + var printer kubectl.ResourcePrinter + var ext string + switch format := cmdutil.GetFlagString(cmd, "output"); format { + case "json": + printer = &kubectl.JSONPrinter{} + ext = ".json" + case "yaml": + printer = &kubectl.YAMLPrinter{} + ext = ".yaml" + default: + return cmdutil.UsageError(cmd, "The flag 'output' must be one of yaml|json") + } + + cmdNamespace, enforceNamespace, err := f.DefaultNamespace() + if err != nil { + return err + } + + mapper, typer := f.Object() + rmap := &resource.Mapper{ + ObjectTyper: typer, + RESTMapper: mapper, + ClientMapper: f.ClientMapperForCommand(), + } + + r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). + NamespaceParam(cmdNamespace).DefaultNamespace(). + FilenameParam(enforceNamespace, filenames...). + ResourceTypeOrNameArgs(true, args...). + Latest(). + Flatten(). + Do() + err = r.Err() + if err != nil { + return err + } + + infos, err := r.Infos() + if err != nil { + return err + } + + clientConfig, err := f.ClientConfig() + if err != nil { + return err + } + + defaultVersion := cmdutil.OutputVersion(cmd, clientConfig.Version) + results := editResults{} + for { + obj, err := resource.AsVersionedObject(infos, false, defaultVersion) + if err != nil { + return preservedFile(err, results.file, out) + } + + // TODO: add an annotating YAML printer that can print inline comments on each field, + // including descriptions or validation errors + + // generate the file to edit + buf := &bytes.Buffer{} + if err := results.header.writeTo(buf); err != nil { + return preservedFile(err, results.file, out) + } + if err := printer.PrintObj(obj, buf); err != nil { + return preservedFile(err, results.file, out) + } + original := buf.Bytes() + + // launch the editor + edit := editor.NewDefaultEditor() + edited, file, err := edit.LaunchTempFile("kubectl-edit-", ext, buf) + if err != nil { + return preservedFile(err, results.file, out) + } + + // cleanup any file from the previous pass + if len(results.file) > 0 { + os.Remove(results.file) + } + + glog.V(4).Infof("User edited:\n%s", string(edited)) + fmt.Printf("User edited:\n%s", string(edited)) + lines, err := hasLines(bytes.NewBuffer(edited)) + if err != nil { + return preservedFile(err, file, out) + } + if bytes.Equal(original, edited) { + if len(results.edit) > 0 { + preservedFile(nil, file, out) + } else { + os.Remove(file) + } + fmt.Fprintln(out, "Edit cancelled, no changes made.") + return nil + } + if !lines { + if len(results.edit) > 0 { + preservedFile(nil, file, out) + } else { + os.Remove(file) + } + fmt.Fprintln(out, "Edit cancelled, saved file was empty.") + return nil + } + + results = editResults{ + file: file, + } + + // parse the edited file + updates, err := rmap.InfoForData(edited, "edited-file") + if err != nil { + return preservedFile(err, file, out) + } + + // annotate the edited object for kubectl apply + if err := kubectl.UpdateApplyAnnotation(updates); err != nil { + return preservedFile(err, file, out) + } + + visitor := resource.NewFlattenListVisitor(updates, rmap) + + // need to make sure the original namespace wasn't changed while editing + if err = visitor.Visit(resource.RequireNamespace(cmdNamespace)); err != nil { + return preservedFile(err, file, out) + } + + // use strategic merge to create a patch + originalJS, err := yaml.ToJSON(original) + if err != nil { + return preservedFile(err, file, out) + } + editedJS, err := yaml.ToJSON(edited) + if err != nil { + return preservedFile(err, file, out) + } + patch, err := strategicpatch.CreateStrategicMergePatch(originalJS, editedJS, obj) + // TODO: change all jsonmerge to strategicpatch + // for checking preconditions + preconditions := []jsonmerge.PreconditionFunc{} + if err != nil { + glog.V(4).Infof("Unable to calculate diff, no merge is possible: %v", err) + return preservedFile(err, file, out) + } else { + preconditions = append(preconditions, jsonmerge.RequireKeyUnchanged("apiVersion")) + preconditions = append(preconditions, jsonmerge.RequireKeyUnchanged("kind")) + preconditions = append(preconditions, jsonmerge.RequireMetadataKeyUnchanged("name")) + results.version = defaultVersion + } + + if hold, msg := jsonmerge.TestPreconditionsHold(patch, preconditions); !hold { + fmt.Fprintf(out, "error: %s", msg) + return preservedFile(nil, file, out) + } + + err = visitor.Visit(func(info *resource.Info, err error) error { + patched, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, api.StrategicMergePatchType, patch) + if err != nil { + fmt.Fprintln(out, results.addError(err, info)) + return nil + } + info.Refresh(patched, true) + cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, "edited") + return nil + }) + if err != nil { + return preservedFile(err, file, out) + } + + if results.retryable > 0 { + fmt.Fprintf(out, "You can run `kubectl replace -f %s` to try this update again.\n", file) + return errExit + } + if results.conflict > 0 { + fmt.Fprintf(out, "You must update your local resource version and run `kubectl replace -f %s` to overwrite the remote changes.\n", file) + return errExit + } + if len(results.edit) == 0 { + if results.notfound == 0 { + os.Remove(file) + } else { + fmt.Fprintf(out, "The edits you made on deleted resources have been saved to %q\n", file) + } + return nil + } + + // loop again and edit the remaining items + infos = results.edit + } + return nil +} + +// print json file (such as patch file) content for debugging +func printJson(out io.Writer, file []byte) error { + diff := make(map[string]interface{}) + if err := json.Unmarshal(file, &diff); err != nil { + return err + } + fmt.Fprintf(out, "%v\n", diff) + return nil +} + +// editReason preserves a message about the reason this file must be edited again +type editReason struct { + head string + other []string +} + +// editHeader includes a list of reasons the edit must be retried +type editHeader struct { + reasons []editReason +} + +// writeTo outputs the current header information into a stream +func (h *editHeader) writeTo(w io.Writer) error { + fmt.Fprint(w, `# Please edit the object below. Lines beginning with a '#' will be ignored, +# and an empty file will abort the edit. If an error occurs while saving this file will be +# reopened with the relevant failures. +# +`) + for _, r := range h.reasons { + if len(r.other) > 0 { + fmt.Fprintf(w, "# %s:\n", r.head) + } else { + fmt.Fprintf(w, "# %s\n", r.head) + } + for _, o := range r.other { + fmt.Fprintf(w, "# * %s\n", o) + } + fmt.Fprintln(w, "#") + } + return nil +} + +// editResults capture the result of an update +type editResults struct { + header editHeader + retryable int + notfound int + conflict int + edit []*resource.Info + file string + + version string +} + +func (r *editResults) addError(err error, info *resource.Info) string { + switch { + case errors.IsInvalid(err): + r.edit = append(r.edit, info) + reason := editReason{ + head: fmt.Sprintf("%s %s was not valid", info.Mapping.Kind, info.Name), + } + if err, ok := err.(client.APIStatus); ok { + if details := err.Status().Details; details != nil { + for _, cause := range details.Causes { + reason.other = append(reason.other, cause.Message) + } + } + } + r.header.reasons = append(r.header.reasons, reason) + return fmt.Sprintf("Error: the %s %s is invalid", info.Mapping.Kind, info.Name) + case errors.IsNotFound(err): + r.notfound++ + return fmt.Sprintf("Error: the %s %s could not be found on the server", info.Mapping.Kind, info.Name) + default: + r.retryable++ + return fmt.Sprintf("Error: the %s %s could not be patched: %v", info.Mapping.Kind, info.Name, err) + } +} + +// preservedFile writes out a message about the provided file if it exists to the +// provided output stream when an error happens. Used to notify the user where +// their updates were preserved. +func preservedFile(err error, path string, out io.Writer) error { + if len(path) > 0 { + if _, err := os.Stat(path); !os.IsNotExist(err) { + fmt.Fprintf(out, "A copy of your changes has been stored to %q\n", path) + } + } + return err +} + +// hasLines returns true if any line in the provided stream is non empty - has non-whitespace +// characters, or the first non-whitespace character is a '#' indicating a comment. Returns +// any errors encountered reading the stream. +func hasLines(r io.Reader) (bool, error) { + // TODO: if any files we read have > 64KB lines, we'll need to switch to bytes.ReadLine + // TODO: probably going to be secrets + s := bufio.NewScanner(r) + for s.Scan() { + if line := strings.TrimSpace(s.Text()); len(line) > 0 && line[0] != '#' { + return true, nil + } + } + if err := s.Err(); err != nil && err != io.EOF { + return false, err + } + return false, nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec.go index 83310f4d6ca6..a0c0c88924b5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec.go @@ -19,6 +19,7 @@ package cmd import ( "fmt" "io" + "net/url" "os" "os/signal" "syscall" @@ -27,7 +28,6 @@ import ( "github.com/golang/glog" "github.com/spf13/cobra" "k8s.io/kubernetes/pkg/api" - apierrors "k8s.io/kubernetes/pkg/api/errors" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -40,7 +40,7 @@ $ kubectl exec 123456-7890 date # Get output from running 'date' in ruby-container from pod 123456-7890 $ kubectl exec 123456-7890 -c ruby-container date -# Switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-780 +# Switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-7890 # and sends stdout/stderr from 'bash' back to the client $ kubectl exec 123456-7890 -c ruby-container -i -t -- bash -il` ) @@ -74,15 +74,18 @@ func NewCmdExec(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) * // RemoteExecutor defines the interface accepted by the Exec command - provided for test stubbing type RemoteExecutor interface { - Execute(req *client.Request, config *client.Config, command []string, stdin io.Reader, stdout, stderr io.Writer, tty bool) error + Execute(method string, url *url.URL, config *client.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error } // DefaultRemoteExecutor is the standard implementation of remote command execution type DefaultRemoteExecutor struct{} -func (*DefaultRemoteExecutor) Execute(req *client.Request, config *client.Config, command []string, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { - executor := remotecommand.New(req, config, command, stdin, stdout, stderr, tty) - return executor.Execute() +func (*DefaultRemoteExecutor) Execute(method string, url *url.URL, config *client.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { + exec, err := remotecommand.NewExecutor(config, method, url) + if err != nil { + return err + } + return exec.Stream(stdin, stdout, stderr, tty) } // ExecOptions declare the arguments accepted by the Exec command @@ -221,31 +224,14 @@ func (p *ExecOptions) Run() error { Namespace(pod.Namespace). SubResource("exec"). Param("container", containerName) - - postErr := p.Executor.Execute(req, p.Config, p.Command, stdin, p.Out, p.Err, tty) - - // if we don't have an error, return. If we did get an error, try a GET because v3.0.0 shipped with exec running as a GET. - if postErr == nil { - return nil - } - - // only try the get if the error is either a forbidden or method not supported, otherwise trying with a GET probably won't help - if !apierrors.IsForbidden(postErr) && !apierrors.IsMethodNotSupported(postErr) { - return postErr - } - - getReq := p.Client.RESTClient.Get(). - Resource("pods"). - Name(pod.Name). - Namespace(pod.Namespace). - SubResource("exec"). - Param("container", containerName) - - getErr := p.Executor.Execute(getReq, p.Config, p.Command, stdin, p.Out, p.Err, tty) - if getErr == nil { - return nil - } - - // if we got a getErr, return the postErr because it's more likely to be correct. GET is legacy - return postErr + req.VersionedParams(&api.PodExecOptions{ + Container: containerName, + Command: p.Command, + Stdin: stdin != nil, + Stdout: p.Out != nil, + Stderr: p.Err != nil, + TTY: tty, + }, api.Scheme) + + return p.Executor.Execute("POST", req.URL(), p.Config, stdin, p.Out, p.Err, tty) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec_test.go index 34b147718a85..dd7b85d2ffe9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec_test.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "net/http" + "net/url" "reflect" "testing" @@ -29,15 +30,18 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" ) type fakeRemoteExecutor struct { - req *client.Request + method string + url *url.URL execErr error } -func (f *fakeRemoteExecutor) Execute(req *client.Request, config *client.Config, command []string, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { - f.req = req +func (f *fakeRemoteExecutor) Execute(method string, url *url.URL, config *client.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { + f.method = method + f.url = url return f.execErr } @@ -97,9 +101,9 @@ func TestPodAndContainer(t *testing.T) { } for _, test := range tests { f, tf, codec := NewAPIFactory() - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { return nil, nil }), + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { return nil, nil }), } tf.Namespace = "test" tf.ClientConfig = &client.Config{} @@ -153,9 +157,9 @@ func TestExec(t *testing.T) { } for _, test := range tests { f, tf, codec := NewAPIFactory() - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == test.podPath && m == "GET": body := objBody(codec, test.pod) @@ -197,10 +201,16 @@ func TestExec(t *testing.T) { t.Errorf("%s: Unexpected error: %v", test.name, err) continue } - if !test.execErr && ex.req.URL().Path != test.execPath { + if test.execErr { + continue + } + if ex.url.Path != test.execPath { t.Errorf("%s: Did not get expected path for exec request", test.name) continue } + if ex.method != "POST" { + t.Errorf("%s: Did not get method for exec request: %s", test.name, ex.method) + } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/explain.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/explain.go new file mode 100644 index 000000000000..15053964b0ff --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/explain.go @@ -0,0 +1,85 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 cmd + +import ( + "io" + + "github.com/spf13/cobra" + + "k8s.io/kubernetes/pkg/kubectl" + cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" +) + +const ( + explainExamples = `# Get the documentation of the resource and its fields +$ kubectl explain pods + +# Get the documentation of a specific field of a resource +$ kubectl explain pods.spec.containers` + + explainLong = `Documentation of resources. + +Possible resource types include: pods (po), services (svc), +replicationcontrollers (rc), nodes (no), events (ev), componentstatuses (cs), +limitranges (limits), persistentvolumes (pv), persistentvolumeclaims (pvc), +resourcequotas (quota), namespaces (ns) or endpoints (ep).` +) + +// NewCmdExplain returns a cobra command for swagger docs +func NewCmdExplain(f *cmdutil.Factory, out io.Writer) *cobra.Command { + cmd := &cobra.Command{ + Use: "explain RESOURCE", + Short: "Documentation of resources.", + Long: explainLong, + Example: explainExamples, + Run: func(cmd *cobra.Command, args []string) { + err := RunExplain(f, out, cmd, args) + cmdutil.CheckErr(err) + }, + } + cmd.Flags().Bool("recursive", false, "Print the fields of fields (Currently only 1 level deep)") + return cmd +} + +// RunExplain executes the appropriate steps to print a model's documentation +func RunExplain(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return cmdutil.UsageError(cmd, "We accept only this format: explain RESOURCE") + } + + client, err := f.Client() + if err != nil { + return err + } + + recursive := cmdutil.GetFlagBool(cmd, "recursive") + apiV := cmdutil.GetFlagString(cmd, "api-version") + + swagSchema, err := kubectl.GetSwaggerSchema(apiV, client) + if err != nil { + return err + } + + mapper, _ := f.Object() + inModel, fieldsPath, err := kubectl.SplitAndParseResourceRequest(args[0], mapper) + if err != nil { + return err + } + + return kubectl.PrintModelDescription(inModel, fieldsPath, out, swagSchema, recursive) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/expose.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/expose.go index 32af16f34644..3cc960fdc589 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/expose.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/expose.go @@ -25,7 +25,7 @@ import ( "k8s.io/kubernetes/pkg/kubectl" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/validation" ) // ExposeOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of @@ -35,9 +35,9 @@ type ExposeOptions struct { } const ( - expose_long = `Take a replicated application and expose it as Kubernetes Service. + expose_long = `Take a replication controller, service or pod and expose it as a new Kubernetes Service. -Looks up a replication controller or service by name and uses the selector for that resource as the +Looks up a replication controller, service or pod by name and uses the selector for that resource as the selector for a new Service on the specified port. If no labels are specified, the new service will re-use the labels from the resource it exposes.` @@ -47,6 +47,9 @@ $ kubectl expose rc nginx --port=80 --target-port=8000 # Create a service for a replication controller identified by type and name specified in "nginx-controller.yaml", which serves on port 80 and connects to the containers on port 8000. $ kubectl expose -f nginx-controller.yaml --port=80 --target-port=8000 +# Create a service for a pod valid-pod, which serves on port 444 with the name "frontend" +$ kubectl expose pod valid-pod --port=444 --name=frontend + # Create a second service based on the above service, exposing the container port 8443 as port 443 with the name "nginx-https" $ kubectl expose service nginx --port=443 --target-port=8443 --name=nginx-https @@ -59,7 +62,7 @@ func NewCmdExposeService(f *cmdutil.Factory, out io.Writer) *cobra.Command { cmd := &cobra.Command{ Use: "expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [----external-ip=external-ip-of-service] [--type=type]", - Short: "Take a replicated application and expose it as Kubernetes Service", + Short: "Take a replication controller, service or pod and expose it as a new Kubernetes Service", Long: expose_long, Example: expose_example, Run: func(cmd *cobra.Command, args []string) { @@ -70,7 +73,7 @@ func NewCmdExposeService(f *cmdutil.Factory, out io.Writer) *cobra.Command { cmdutil.AddPrinterFlags(cmd) cmd.Flags().String("generator", "service/v2", "The name of the API generator to use. There are 2 generators: 'service/v1' and 'service/v2'. The only difference between them is that service port in v1 is named 'default', while it is left unnamed in v2. Default is 'service/v2'.") cmd.Flags().String("protocol", "TCP", "The network protocol for the service to be created. Default is 'tcp'.") - cmd.Flags().Int("port", -1, "The port that the service should serve on. Copied from the resource being exposed, if unspecified") + cmd.Flags().String("port", "", "The port that the service should serve on. Copied from the resource being exposed, if unspecified") cmd.Flags().String("type", "", "Type for this service: ClusterIP, NodePort, or LoadBalancer. Default is 'ClusterIP'.") // TODO: remove create-external-load-balancer in code on or after Aug 25, 2016. cmd.Flags().Bool("create-external-load-balancer", false, "If true, create an external load balancer for this service (trumped by --type). Implementation is cloud provider dependent. Default is 'false'.") @@ -114,7 +117,9 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str } info := infos[0] mapping := info.ResourceMapping() - + if err := f.CanBeExposed(mapping.Kind); err != nil { + return err + } // Get the input object inputObject, err := r.Object() if err != nil { @@ -130,8 +135,8 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str names := generator.ParamNames() params := kubectl.MakeParams(cmd, names) name := info.Name - if len(name) > util.DNS952LabelMaxLength { - name = name[:util.DNS952LabelMaxLength] + if len(name) > validation.DNS952LabelMaxLength { + name = name[:validation.DNS952LabelMaxLength] } params["default-name"] = name @@ -145,32 +150,22 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str params["selector"] = s } - if cmdutil.GetFlagInt(cmd, "port") < 1 { - noPorts := true - for _, param := range names { - if param.Name == "port" { - noPorts = false - break - } + // For objects that need a port, derive it from the exposed object in case a user + // didn't explicitly specify one via --port + if port, found := params["port"]; found && kubectl.IsZero(port) { + ports, err := f.PortsForObject(inputObject) + if err != nil { + return cmdutil.UsageError(cmd, fmt.Sprintf("couldn't find port via --port flag or introspection: %s", err)) } - if cmdutil.GetFlagInt(cmd, "port") < 0 && !noPorts { - ports, err := f.PortsForObject(inputObject) - if err != nil { - return cmdutil.UsageError(cmd, fmt.Sprintf("couldn't find port via --port flag or introspection: %s", err)) - } - switch len(ports) { - case 0: - return cmdutil.UsageError(cmd, "couldn't find port via --port flag or introspection") - case 1: - params["port"] = ports[0] - default: - return cmdutil.UsageError(cmd, fmt.Sprintf("multiple ports to choose from: %v, please explicitly specify a port using the --port flag.", ports)) - } + switch len(ports) { + case 0: + return cmdutil.UsageError(cmd, "couldn't find port via --port flag or introspection") + case 1: + params["port"] = ports[0] + default: + return cmdutil.UsageError(cmd, fmt.Sprintf("multiple ports to choose from: %v, please explicitly specify a port using the --port flag.", ports)) } } - if cmdutil.GetFlagBool(cmd, "create-external-load-balancer") { - params["create-external-load-balancer"] = "true" - } if kubectl.IsZero(params["labels"]) { labels, err := f.LabelsForObject(inputObject) if err != nil { @@ -178,22 +173,17 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str } params["labels"] = kubectl.MakeLabels(labels) } - if v := cmdutil.GetFlagString(cmd, "type"); v != "" { - params["type"] = v - } - err = kubectl.ValidateParams(names, params) - if err != nil { + if err = kubectl.ValidateParams(names, params); err != nil { return err } - // Expose new object + // Generate new object object, err := generator.Generate(params) if err != nil { return err } - inline := cmdutil.GetFlagString(cmd, "overrides") - if len(inline) > 0 { + if inline := cmdutil.GetFlagString(cmd, "overrides"); len(inline) > 0 { object, err = cmdutil.Merge(object, inline, mapping.Kind) if err != nil { return err @@ -207,19 +197,24 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str } // TODO: extract this flag to a central location, when such a location exists. if cmdutil.GetFlagBool(cmd, "dry-run") { - fmt.Fprintln(out, "running in dry-run mode...") - } else { - data, err := info.Mapping.Codec.Encode(object) - if err != nil { - return err - } - object, err = resource.NewHelper(info.Client, info.Mapping).Create(namespace, false, data) - if err != nil { - return err - } + return f.PrintObject(cmd, object, out) + } + // Serialize the configuration into an annotation. + if err := kubectl.UpdateApplyAnnotation(info); err != nil { + return err + } + + // Serialize the object with the annotation applied. + data, err := info.Mapping.Codec.Encode(object) + if err != nil { + return err + } + object, err = resource.NewHelper(info.Client, info.Mapping).Create(namespace, false, data) + if err != nil { + return err } - outputFormat := cmdutil.GetFlagString(cmd, "output") - if outputFormat != "" { + + if len(cmdutil.GetFlagString(cmd, "output")) > 0 { return f.PrintObject(cmd, object, out) } cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, "exposed") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/expose_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/expose_test.go index dbcf7ec7b056..6a03cac4cac6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/expose_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/expose_test.go @@ -23,7 +23,8 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" + "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" ) @@ -135,7 +136,7 @@ func TestRunExposeService(t *testing.T) { status: 200, }, { - name: "expose-external-service", + name: "expose-service", args: []string{"service", "baz"}, ns: "test", calls: map[string]string{ @@ -148,7 +149,7 @@ func TestRunExposeService(t *testing.T) { Selector: map[string]string{"app": "go"}, }, }, - flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "create-external-load-balancer": "true"}, + flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "type": "LoadBalancer", "dry-run": "true"}, output: &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "", Labels: map[string]string{"svc": "test"}}, Spec: api.ServiceSpec{ @@ -163,11 +164,10 @@ func TestRunExposeService(t *testing.T) { Type: api.ServiceTypeLoadBalancer, }, }, - expected: "service \"foo\" exposed", - status: 200, + status: 200, }, { - name: "expose-external-affinity-service", + name: "expose-affinity-service", args: []string{"service", "baz"}, ns: "test", calls: map[string]string{ @@ -180,7 +180,7 @@ func TestRunExposeService(t *testing.T) { Selector: map[string]string{"app": "go"}, }, }, - flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "create-external-load-balancer": "true", "session-affinity": "ClientIP"}, + flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "type": "LoadBalancer", "session-affinity": "ClientIP", "dry-run": "true"}, output: &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "", Labels: map[string]string{"svc": "test"}}, Spec: api.ServiceSpec{ @@ -196,8 +196,7 @@ func TestRunExposeService(t *testing.T) { SessionAffinity: api.ServiceAffinityClientIP, }, }, - expected: "service \"foo\" exposed", - status: 200, + status: 200, }, { name: "expose-external-service", @@ -214,7 +213,7 @@ func TestRunExposeService(t *testing.T) { }, }, // Even if we specify --selector, since service/test doesn't need one it will ignore it - flags: map[string]string{"selector": "svc=fromexternal", "port": "90", "labels": "svc=fromexternal", "name": "frombaz", "generator": "service/test"}, + flags: map[string]string{"selector": "svc=fromexternal", "port": "90", "labels": "svc=fromexternal", "name": "frombaz", "generator": "service/test", "dry-run": "true"}, output: &api.Service{ ObjectMeta: api.ObjectMeta{Name: "frombaz", Namespace: "", Labels: map[string]string{"svc": "fromexternal"}}, Spec: api.ServiceSpec{ @@ -227,17 +226,74 @@ func TestRunExposeService(t *testing.T) { }, }, }, - expected: "service \"frombaz\" exposed", + status: 200, + }, + { + name: "expose-from-file", + args: []string{}, + ns: "test", + calls: map[string]string{ + "GET": "/namespaces/test/services/redis-master", + "POST": "/namespaces/test/services", + }, + input: &api.Service{ + ObjectMeta: api.ObjectMeta{Name: "redis-master", Namespace: "test", ResourceVersion: "12"}, + Spec: api.ServiceSpec{ + Selector: map[string]string{"app": "go"}, + }, + }, + flags: map[string]string{"filename": "../../../examples/guestbook/redis-master-service.yaml", "selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "dry-run": "true"}, + output: &api.Service{ + ObjectMeta: api.ObjectMeta{Name: "foo", Labels: map[string]string{"svc": "test"}}, + Spec: api.ServiceSpec{ + Ports: []api.ServicePort{ + { + Protocol: api.ProtocolUDP, + Port: 14, + TargetPort: util.NewIntOrStringFromInt(14), + }, + }, + Selector: map[string]string{"func": "stream"}, + }, + }, + status: 200, + }, + { + name: "truncate-name", + args: []string{"pod", "a-name-that-is-toooo-big-for-a-service"}, + ns: "test", + calls: map[string]string{ + "GET": "/namespaces/test/pods/a-name-that-is-toooo-big-for-a-service", + "POST": "/namespaces/test/services", + }, + input: &api.Pod{ + ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"}, + }, + flags: map[string]string{"selector": "svc=frompod", "port": "90", "labels": "svc=frompod", "generator": "service/v2"}, + output: &api.Service{ + ObjectMeta: api.ObjectMeta{Name: "a-name-that-is-toooo-big", Namespace: "", Labels: map[string]string{"svc": "frompod"}}, + Spec: api.ServiceSpec{ + Ports: []api.ServicePort{ + { + Protocol: api.ProtocolTCP, + Port: 90, + TargetPort: util.NewIntOrStringFromInt(90), + }, + }, + Selector: map[string]string{"svc": "frompod"}, + }, + }, + expected: "service \"a-name-that-is-toooo-big\" exposed", status: 200, }, } for _, test := range tests { f, tf, codec := NewAPIFactory() - tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Printer = &kubectl.JSONPrinter{} + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == test.calls[m] && m == "GET": return &http.Response{StatusCode: test.status, Body: objBody(codec, test.input)}, nil @@ -259,82 +315,19 @@ func TestRunExposeService(t *testing.T) { } cmd.Run(cmd, test.args) - out, expectedOut := buf.String(), test.expected - if !strings.Contains(out, expectedOut) { - t.Errorf("%s: Unexpected output! Expected\n%s\ngot\n%s", test.name, expectedOut, out) - } - } -} - -func TestRunExposeServiceFromFile(t *testing.T) { - test := struct { - calls map[string]string - input runtime.Object - flags map[string]string - output runtime.Object - expected string - status int - }{ - calls: map[string]string{ - "GET": "/namespaces/test/services/redis-master", - "POST": "/namespaces/test/services", - }, - input: &api.Service{ - ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"}, - TypeMeta: api.TypeMeta{Kind: "Service", APIVersion: "v1"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"app": "go"}, - }, - }, - flags: map[string]string{"selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test"}, - output: &api.Service{ - ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "12", Labels: map[string]string{"svc": "test"}}, - TypeMeta: api.TypeMeta{Kind: "Service", APIVersion: "v1"}, - Spec: api.ServiceSpec{ - Ports: []api.ServicePort{ - { - Name: "default", - Protocol: api.Protocol("UDP"), - Port: 14, - }, - }, - Selector: map[string]string{"func": "stream"}, - }, - }, - status: 200, - } - - f, tf, codec := NewAPIFactory() - tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ - Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { - switch p, m := req.URL.Path, req.Method; { - case p == test.calls[m] && m == "GET": - return &http.Response{StatusCode: test.status, Body: objBody(codec, test.input)}, nil - case p == test.calls[m] && m == "POST": - return &http.Response{StatusCode: test.status, Body: objBody(codec, test.output)}, nil - default: - t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) - return nil, nil + out := buf.String() + if _, ok := test.flags["dry-run"]; ok { + buf.Reset() + if err := tf.Printer.PrintObj(test.output, buf); err != nil { + t.Errorf("%s: Unexpected error: %v", test.name, err) + continue } - }), - } - tf.Namespace = "test" - buf := bytes.NewBuffer([]byte{}) - cmd := NewCmdExposeService(f, buf) - cmd.SetOutput(buf) + test.expected = buf.String() + } - for flag, value := range test.flags { - cmd.Flags().Set(flag, value) - } - cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-service.yaml") - cmd.Run(cmd, []string{}) - if len(test.expected) > 0 { - out := buf.String() if !strings.Contains(out, test.expected) { - t.Errorf("unexpected output: %s", out) + t.Errorf("%s: Unexpected output! Expected\n%s\ngot\n%s", test.name, test.expected, out) } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get.go index 04d8fb96f079..88f18fedc144 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get.go @@ -21,6 +21,7 @@ import ( "io" "github.com/spf13/cobra" + "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/kubectl" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" @@ -220,13 +221,23 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string } // use the default printer for each object - return b.Do().Visit(func(r *resource.Info, err error) error { + printer = nil + var lastMapping *meta.RESTMapping + w := kubectl.GetNewTabWriter(out) + defer w.Flush() + return b.Flatten().Do().Visit(func(r *resource.Info, err error) error { if err != nil { return err } - printer, err := f.PrinterForMapping(cmd, r.Mapping, allNamespaces) - if err != nil { - return err + if printer == nil || lastMapping == nil || r.Mapping == nil || r.Mapping.Resource != lastMapping.Resource { + printer, err = f.PrinterForMapping(cmd, r.Mapping, allNamespaces) + if err != nil { + return err + } + lastMapping = r.Mapping + } + if _, found := printer.(*kubectl.HumanReadablePrinter); found { + return printer.PrintObj(r.Object, w) } return printer.PrintObj(r.Object, out) }) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get_test.go index b15d6ec67e3a..e5f07480da11 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get_test.go @@ -28,9 +28,11 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/testapi" + apitesting "k8s.io/kubernetes/pkg/api/testing" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/watch" @@ -38,32 +40,23 @@ import ( ) func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList) { - grace := int64(30) pods := &api.PodList{ - ListMeta: api.ListMeta{ + ListMeta: unversioned.ListMeta{ ResourceVersion: "15", }, Items: []api.Pod{ { ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, }, } svc := &api.ServiceList{ - ListMeta: api.ListMeta{ + ListMeta: unversioned.ListMeta{ ResourceVersion: "16", }, Items: []api.Service{ @@ -77,7 +70,7 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList) }, } rc := &api.ReplicationControllerList{ - ListMeta: api.ListMeta{ + ListMeta: unversioned.ListMeta{ ResourceVersion: "17", }, Items: []api.ReplicationController{ @@ -93,29 +86,29 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList) } func testComponentStatusData() *api.ComponentStatusList { - good := &api.ComponentStatus{ + good := api.ComponentStatus{ Conditions: []api.ComponentCondition{ {Type: api.ComponentHealthy, Status: api.ConditionTrue, Message: "ok", Error: "nil"}, }, + ObjectMeta: api.ObjectMeta{Name: "servergood", Namespace: "test"}, } - good.Name = "servergood" - bad := &api.ComponentStatus{ + bad := api.ComponentStatus{ Conditions: []api.ComponentCondition{ {Type: api.ComponentHealthy, Status: api.ConditionFalse, Message: "", Error: "bad status: 500"}, }, + ObjectMeta: api.ObjectMeta{Name: "serverbad", Namespace: "test"}, } - bad.Name = "serverbad" - unknown := &api.ComponentStatus{ + unknown := api.ComponentStatus{ Conditions: []api.ComponentCondition{ {Type: api.ComponentHealthy, Status: api.ConditionUnknown, Message: "", Error: "fizzbuzz error"}, }, + ObjectMeta: api.ObjectMeta{Name: "serverunknown", Namespace: "test"}, } - unknown.Name = "serverunknown" return &api.ComponentStatusList{ - Items: []api.ComponentStatus{*good, *bad, *unknown}, + Items: []api.ComponentStatus{good, bad, unknown}, } } @@ -123,12 +116,12 @@ func testComponentStatusData() *api.ComponentStatusList { func TestGetUnknownSchemaObject(t *testing.T) { f, tf, codec := NewTestFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Resp: &http.Response{StatusCode: 200, Body: objBody(codec, &internalType{Name: "foo"})}, } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: latest.Version} + tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdGet(f, buf) @@ -153,9 +146,9 @@ func TestGetUnknownSchemaObject(t *testing.T) { // // The expected behavior of the `kubectl get` command is: // 1. objects using unrecognized schemes will always be returned using that scheme/version, "unlikelyversion" in this test; -// 2. if the specified output-version is a recognized, valid Scheme, then the list should use that scheme, and otherwise it will default to the client version, latest.Version in this test; +// 2. if the specified output-version is a recognized, valid Scheme, then the list should use that scheme, and otherwise it will default to the client version, testapi.Default.Version() in this test; // 3a. if the specified output-version is a recognized, valid Scheme, in which the requested object (replicationcontroller) can be represented, then the object should be returned using that version; -// 3b. otherwise if the specified output-version is unrecognized, but the requested object (replicationcontroller) is recognized by the client's codec, then it will be converted to the client version, latest.Version in this test. +// 3b. otherwise if the specified output-version is unrecognized, but the requested object (replicationcontroller) is recognized by the client's codec, then it will be converted to the client version, testapi.Default.Version() in this test. func TestGetUnknownSchemaObjectListGeneric(t *testing.T) { testCases := map[string]struct { outputVersion string @@ -164,16 +157,16 @@ func TestGetUnknownSchemaObjectListGeneric(t *testing.T) { rcVersion string }{ "handles specific version": { - outputVersion: latest.Version, - listVersion: latest.Version, + outputVersion: testapi.Default.Version(), + listVersion: testapi.Default.Version(), testtypeVersion: "unlikelyversion", - rcVersion: latest.Version, + rcVersion: testapi.Default.Version(), }, "handles second specific version": { outputVersion: "unlikelyversion", - listVersion: latest.Version, + listVersion: testapi.Default.Version(), testtypeVersion: "unlikelyversion", - rcVersion: latest.Version, // see expected behavior 3b + rcVersion: testapi.Default.Version(), // see expected behavior 3b }, "handles common version": { outputVersion: testapi.Default.Version(), @@ -184,23 +177,23 @@ func TestGetUnknownSchemaObjectListGeneric(t *testing.T) { } for k, test := range testCases { apiCodec := runtime.CodecFor(api.Scheme, testapi.Default.Version()) - regularClient := &client.FakeRESTClient{ + regularClient := &fake.RESTClient{ Codec: apiCodec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { return &http.Response{StatusCode: 200, Body: objBody(apiCodec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}})}, nil }), } f, tf, codec := NewMixedFactory(regularClient) tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { return &http.Response{StatusCode: 200, Body: objBody(codec, &internalType{Name: "foo"})}, nil }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: latest.Version} + tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdGet(f, buf) cmd.SetOutput(buf) @@ -232,11 +225,11 @@ func TestGetUnknownSchemaObjectListGeneric(t *testing.T) { // Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get. func TestGetSchemaObject(t *testing.T) { f, tf, _ := NewTestFactory() - tf.Mapper = latest.RESTMapper + tf.Mapper = testapi.Default.RESTMapper() tf.Typer = api.Scheme - codec := latest.Codec + codec := testapi.Default.Codec() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Resp: &http.Response{StatusCode: 200, Body: objBody(codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}})}, } @@ -257,7 +250,7 @@ func TestGetObjects(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Resp: &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, } @@ -283,7 +276,7 @@ func TestGetObjectsIdentifiedByFile(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Resp: &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, } @@ -310,7 +303,7 @@ func TestGetListObjects(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Resp: &http.Response{StatusCode: 200, Body: objBody(codec, pods)}, } @@ -321,22 +314,39 @@ func TestGetListObjects(t *testing.T) { cmd.SetOutput(buf) cmd.Run(cmd, []string{"pods"}) - expected := []runtime.Object{pods} + expected, err := extractResourceList([]runtime.Object{pods}) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } actual := tf.Printer.(*testPrinter).Objects if !reflect.DeepEqual(expected, actual) { - t.Errorf("unexpected object: %#v %#v", expected, actual) + t.Errorf("unexpected object: expected %#v, got %#v", expected, actual) } if len(buf.String()) == 0 { t.Errorf("unexpected empty output") } } +func extractResourceList(objs []runtime.Object) ([]runtime.Object, error) { + finalObjs := []runtime.Object{} + for _, obj := range objs { + items, err := runtime.ExtractList(obj) + if err != nil { + return nil, err + } + for _, item := range items { + finalObjs = append(finalObjs, item) + } + } + return finalObjs, nil +} + func TestGetAllListObjects(t *testing.T) { pods, _, _ := testData() f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Resp: &http.Response{StatusCode: 200, Body: objBody(codec, pods)}, } @@ -348,7 +358,10 @@ func TestGetAllListObjects(t *testing.T) { cmd.Flags().Set("show-all", "true") cmd.Run(cmd, []string{"pods"}) - expected := []runtime.Object{pods} + expected, err := extractResourceList([]runtime.Object{pods}) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } actual := tf.Printer.(*testPrinter).Objects if !reflect.DeepEqual(expected, actual) { t.Errorf("unexpected object: %#v %#v", expected, actual) @@ -363,7 +376,7 @@ func TestGetListComponentStatus(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, Resp: &http.Response{StatusCode: 200, Body: objBody(codec, statuses)}, } @@ -374,10 +387,13 @@ func TestGetListComponentStatus(t *testing.T) { cmd.SetOutput(buf) cmd.Run(cmd, []string{"componentstatuses"}) - expected := []runtime.Object{statuses} + expected, err := extractResourceList([]runtime.Object{statuses}) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } actual := tf.Printer.(*testPrinter).Objects if !reflect.DeepEqual(expected, actual) { - t.Errorf("unexpected object: %#v %#v", expected, actual) + t.Errorf("unexpected object: expected %#v, got %#v", expected, actual) } if len(buf.String()) == 0 { t.Errorf("unexpected empty output") @@ -389,9 +405,9 @@ func TestGetMultipleTypeObjects(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch req.URL.Path { case "/namespaces/test/pods": return &http.Response{StatusCode: 200, Body: objBody(codec, pods)}, nil @@ -410,7 +426,10 @@ func TestGetMultipleTypeObjects(t *testing.T) { cmd.SetOutput(buf) cmd.Run(cmd, []string{"pods,services"}) - expected := []runtime.Object{pods, svc} + expected, err := extractResourceList([]runtime.Object{pods, svc}) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } actual := tf.Printer.(*testPrinter).Objects if !reflect.DeepEqual(expected, actual) { t.Errorf("unexpected object: %#v", actual) @@ -425,9 +444,9 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch req.URL.Path { case "/namespaces/test/pods": return &http.Response{StatusCode: 200, Body: objBody(codec, pods)}, nil @@ -485,10 +504,10 @@ func TestGetMultipleTypeObjectsWithSelector(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { - if req.URL.Query().Get(api.LabelSelectorQueryParam(testapi.Default.Version())) != "a=b" { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + if req.URL.Query().Get(unversioned.LabelSelectorQueryParam(testapi.Default.Version())) != "a=b" { t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) } switch req.URL.Path { @@ -511,7 +530,10 @@ func TestGetMultipleTypeObjectsWithSelector(t *testing.T) { cmd.Flags().Set("selector", "a=b") cmd.Run(cmd, []string{"pods,services"}) - expected := []runtime.Object{pods, svc} + expected, err := extractResourceList([]runtime.Object{pods, svc}) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } actual := tf.Printer.(*testPrinter).Objects if !reflect.DeepEqual(expected, actual) { t.Errorf("unexpected object: %#v", actual) @@ -534,9 +556,9 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch req.URL.Path { case "/nodes/foo": return &http.Response{StatusCode: 200, Body: objBody(codec, node)}, nil @@ -566,7 +588,6 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) { } } func watchTestData() ([]api.Pod, []watch.Event) { - grace := int64(30) pods := []api.Pod{ { ObjectMeta: api.ObjectMeta{ @@ -574,11 +595,7 @@ func watchTestData() ([]api.Pod, []watch.Event) { Namespace: "test", ResourceVersion: "10", }, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, } events := []watch.Event{ @@ -590,11 +607,7 @@ func watchTestData() ([]api.Pod, []watch.Event) { Namespace: "test", ResourceVersion: "11", }, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, }, { @@ -605,11 +618,7 @@ func watchTestData() ([]api.Pod, []watch.Event) { Namespace: "test", ResourceVersion: "12", }, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, }, } @@ -621,10 +630,10 @@ func TestWatchSelector(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { - if req.URL.Query().Get(api.LabelSelectorQueryParam(testapi.Default.Version())) != "a=b" { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + if req.URL.Query().Get(unversioned.LabelSelectorQueryParam(testapi.Default.Version())) != "a=b" { t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) } switch req.URL.Path { @@ -651,7 +660,7 @@ func TestWatchSelector(t *testing.T) { expected := []runtime.Object{&api.PodList{Items: pods}, events[0].Object, events[1].Object} actual := tf.Printer.(*testPrinter).Objects if !reflect.DeepEqual(expected, actual) { - t.Errorf("unexpected object: %#v %#v", expected[0], actual[0]) + t.Errorf("unexpected object:\nExpected: %#v\n\nGot: %#v\n\n", expected[0], actual[0]) } if len(buf.String()) == 0 { t.Errorf("unexpected empty output") @@ -663,9 +672,9 @@ func TestWatchResource(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch req.URL.Path { case "/namespaces/test/pods/foo": return &http.Response{StatusCode: 200, Body: objBody(codec, &pods[0])}, nil @@ -689,7 +698,7 @@ func TestWatchResource(t *testing.T) { expected := []runtime.Object{&pods[0], events[0].Object, events[1].Object} actual := tf.Printer.(*testPrinter).Objects if !reflect.DeepEqual(expected, actual) { - t.Errorf("unexpected object: %#v", actual) + t.Errorf("unexpected object:\nExpected: %#v\n\nGot: %#v\n\n", expected, actual) } if len(buf.String()) == 0 { t.Errorf("unexpected empty output") @@ -701,9 +710,9 @@ func TestWatchResourceIdentifiedByFile(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch req.URL.Path { case "/namespaces/test/pods/cassandra": return &http.Response{StatusCode: 200, Body: objBody(codec, &pods[0])}, nil @@ -740,9 +749,9 @@ func TestWatchOnlyResource(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch req.URL.Path { case "/namespaces/test/pods/foo": return &http.Response{StatusCode: 200, Body: objBody(codec, &pods[0])}, nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/label.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/label.go index 6de412d8e716..0f040a8d1f19 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/label.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/label.go @@ -27,8 +27,8 @@ import ( cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/errors" + "k8s.io/kubernetes/pkg/util/validation" ) // LabelOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of @@ -77,7 +77,7 @@ func NewCmdLabel(f *cmdutil.Factory, out io.Writer) *cobra.Command { cmd := &cobra.Command{ Use: "label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]", Short: "Update the labels on a resource", - Long: fmt.Sprintf(label_long, util.LabelValueMaxLength), + Long: fmt.Sprintf(label_long, validation.LabelValueMaxLength), Example: label_example, Run: func(cmd *cobra.Command, args []string) { err := RunLabel(f, out, cmd, args, options) @@ -113,7 +113,7 @@ func parseLabels(spec []string) (map[string]string, []string, error) { for _, labelSpec := range spec { if strings.Index(labelSpec, "=") != -1 { parts := strings.Split(labelSpec, "=") - if len(parts) != 2 || len(parts[1]) == 0 || !util.IsValidLabelValue(parts[1]) { + if len(parts) != 2 || len(parts[1]) == 0 || !validation.IsValidLabelValue(parts[1]) { return nil, nil, fmt.Errorf("invalid label spec: %v", labelSpec) } labels[parts[0]] = parts[1] diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/label_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/label_test.go index 814aa6052397..8e25cfeb51d7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/label_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/label_test.go @@ -26,6 +26,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/runtime" ) @@ -326,9 +327,9 @@ func TestLabelErrors(t *testing.T) { func TestLabelForResourceFromFile(t *testing.T) { pods, _, _ := testData() f, tf, codec := NewAPIFactory() - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch req.Method { case "GET": switch req.URL.Path { @@ -373,9 +374,9 @@ func TestLabelForResourceFromFile(t *testing.T) { func TestLabelMultipleObjects(t *testing.T) { pods, _, _ := testData() f, tf, codec := NewAPIFactory() - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch req.Method { case "GET": switch req.URL.Path { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log.go index 52ad0dfab563..e67df4eaa3f4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log.go @@ -19,26 +19,35 @@ package cmd import ( "fmt" "io" + "math" "os" "strconv" "strings" + "time" "github.com/spf13/cobra" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/util/sets" ) const ( - log_example = `# Return snapshot of ruby-container logs from pod 123456-7890. -$ kubectl logs 123456-7890 ruby-container + log_example = `# Return snapshot logs from pod nginx with only one container +$ kubectl logs nginx -# Return snapshot of previous terminated ruby-container logs from pod 123456-7890. -$ kubectl logs -p 123456-7890 ruby-container +# Return snapshot of previous terminated ruby container logs from pod web-1 +$ kubectl logs -p -c ruby web-1 -# Start streaming of ruby-container logs from pod 123456-7890. -$ kubectl logs -f 123456-7890 ruby-container` +# Begin streaming the logs of the ruby container in pod web-1 +$ kubectl logs -f -c ruby web-1 + +# Display only the most recent 20 lines of output in pod nginx +$ kubectl logs --tail=20 nginx + +# Show all logs from pod nginx written in the last hour +$ kubectl logs --since=1h nginx` ) func selectContainer(pod *api.Pod, in io.Reader, out io.Writer) string { @@ -63,117 +72,142 @@ func selectContainer(pod *api.Pod, in io.Reader, out io.Writer) string { } } -type LogsOptions struct { - Client *client.Client - - PodNamespace string - PodName string - ContainerName string - Follow bool - Interactive bool - Previous bool - Out io.Writer +type logParams struct { + containerName string } // NewCmdLog creates a new pod log command func NewCmdLog(f *cmdutil.Factory, out io.Writer) *cobra.Command { - o := &LogsOptions{ - Out: out, - Interactive: true, - } - + params := &logParams{} cmd := &cobra.Command{ Use: "logs [-f] [-p] POD [-c CONTAINER]", Short: "Print the logs for a container in a pod.", Long: "Print the logs for a container in a pod. If the pod has only one container, the container name is optional.", Example: log_example, Run: func(cmd *cobra.Command, args []string) { - if len(os.Args) > 1 && os.Args[1] == "log" { - printDeprecationWarning("logs", "log") - } - - cmdutil.CheckErr(o.Complete(f, out, cmd, args)) - - cmdutil.CheckErr(o.Validate(cmd)) - - cmdutil.CheckErr(o.RunLog()) + err := RunLog(f, out, cmd, args, params) + cmdutil.CheckErr(err) }, Aliases: []string{"log"}, } - cmd.Flags().BoolVarP(&o.Follow, "follow", "f", o.Follow, "Specify if the logs should be streamed.") - cmd.Flags().BoolVar(&o.Interactive, "interactive", o.Interactive, "If true, prompt the user for input when required. Default true.") - cmd.Flags().BoolVarP(&o.Previous, "previous", "p", o.Previous, "If true, print the logs for the previous instance of the container in a pod if it exists.") - cmd.Flags().StringVarP(&o.ContainerName, "container", "c", o.ContainerName, "Container name") + cmd.Flags().BoolP("follow", "f", false, "Specify if the logs should be streamed.") + cmd.Flags().Bool("timestamps", false, "Include timestamps on each line in the log output") + cmd.Flags().Bool("interactive", true, "If true, prompt the user for input when required. Default true.") + cmd.Flags().BoolP("previous", "p", false, "If true, print the logs for the previous instance of the container in a pod if it exists.") + cmd.Flags().Int("limit-bytes", 0, "Maximum bytes of logs to return. Defaults to no limit.") + cmd.Flags().Int("tail", -1, "Lines of recent log file to display. Defaults to -1, showing all log lines.") + cmd.Flags().String("since-time", "", "Only return logs after a specific date (RFC3339). Defaults to all logs. Only one of since-time / since may be used.") + cmd.Flags().Duration("since", 0, "Only return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to all logs. Only one of since-time / since may be used.") + cmd.Flags().StringVarP(¶ms.containerName, "container", "c", "", "Container name") return cmd } -func (o *LogsOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { - switch len(args) { - case 0: - return cmdutil.UsageError(cmd, "POD is required for log") +// RunLog retrieves a pod log +func RunLog(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, p *logParams) error { + if len(os.Args) > 1 && os.Args[1] == "log" { + printDeprecationWarning("logs", "log") + } - case 1: - o.PodName = args[0] - case 2: - o.PodName = args[0] - o.ContainerName = args[1] + if len(args) == 0 { + return cmdutil.UsageError(cmd, "POD is required for log") + } - default: + if len(args) > 2 { return cmdutil.UsageError(cmd, "log POD [CONTAINER]") } - var err error - o.PodNamespace, _, err = f.DefaultNamespace() + sinceSeconds := cmdutil.GetFlagDuration(cmd, "since") + sinceTime := cmdutil.GetFlagString(cmd, "since-time") + if len(sinceTime) > 0 && sinceSeconds > 0 { + return cmdutil.UsageError(cmd, "only one of --since, --since-time may be specified") + } + + namespace, _, err := f.DefaultNamespace() if err != nil { return err } - o.Client, err = f.Client() + client, err := f.Client() if err != nil { return err } - return nil -} - -func (o *LogsOptions) Validate(cmd *cobra.Command) error { - return nil -} + podID := args[0] -// RunLog retrieves a pod log -func (o *LogsOptions) RunLog() error { - pod, err := o.Client.Pods(o.PodNamespace).Get(o.PodName) + pod, err := client.Pods(namespace).Get(podID) if err != nil { return err } // [-c CONTAINER] - container := o.ContainerName + container := p.containerName if len(container) == 0 { // [CONTAINER] (container as arg not flag) is supported as legacy behavior. See PR #10519 for more details. - if len(pod.Spec.Containers) != 1 { - podContainersNames := []string{} - for _, container := range pod.Spec.Containers { - podContainersNames = append(podContainersNames, container.Name) + if len(args) == 1 { + if len(pod.Spec.Containers) != 1 { + podContainersNames := []string{} + for _, container := range pod.Spec.Containers { + podContainersNames = append(podContainersNames, container.Name) + } + + return fmt.Errorf("Pod %s has the following containers: %s; please specify the container to print logs for with -c", pod.ObjectMeta.Name, strings.Join(podContainersNames, ", ")) } - - return fmt.Errorf("Pod %s has the following containers: %s; please specify the container to print logs for with -c", pod.ObjectMeta.Name, strings.Join(podContainersNames, ", ")) + container = pod.Spec.Containers[0].Name + } else { + container = args[1] } - container = pod.Spec.Containers[0].Name } - return handleLog(o.Client, o.PodNamespace, o.PodName, container, o.Follow, o.Previous, o.Out) + logOptions := &api.PodLogOptions{ + Container: container, + Follow: cmdutil.GetFlagBool(cmd, "follow"), + Previous: cmdutil.GetFlagBool(cmd, "previous"), + Timestamps: cmdutil.GetFlagBool(cmd, "timestamps"), + } + if sinceSeconds > 0 { + // round up to the nearest second + sec := int64(math.Ceil(float64(sinceSeconds) / float64(time.Second))) + logOptions.SinceSeconds = &sec + } + if t, err := api.ParseRFC3339(sinceTime, unversioned.Now); err == nil { + logOptions.SinceTime = &t + } + if limitBytes := cmdutil.GetFlagInt(cmd, "limit-bytes"); limitBytes != 0 { + i := int64(limitBytes) + logOptions.LimitBytes = &i + } + if tail := cmdutil.GetFlagInt(cmd, "tail"); tail >= 0 { + i := int64(tail) + logOptions.TailLines = &i + } + + return handleLog(client, namespace, podID, logOptions, out) } -func handleLog(client *client.Client, namespace, podID, container string, follow, previous bool, out io.Writer) error { - readCloser, err := client.RESTClient.Get(). +func handleLog(client *client.Client, namespace, podID string, logOptions *api.PodLogOptions, out io.Writer) error { + // TODO: transform this into a PodLogOptions call + req := client.RESTClient.Get(). Namespace(namespace). Name(podID). Resource("pods"). SubResource("log"). - Param("follow", strconv.FormatBool(follow)). - Param("container", container). - Param("previous", strconv.FormatBool(previous)). - Stream() + Param("follow", strconv.FormatBool(logOptions.Follow)). + Param("container", logOptions.Container). + Param("previous", strconv.FormatBool(logOptions.Previous)). + Param("timestamps", strconv.FormatBool(logOptions.Timestamps)) + + if logOptions.SinceSeconds != nil { + req.Param("sinceSeconds", strconv.FormatInt(*logOptions.SinceSeconds, 10)) + } + if logOptions.SinceTime != nil { + req.Param("sinceTime", logOptions.SinceTime.Format(time.RFC3339)) + } + if logOptions.LimitBytes != nil { + req.Param("limitBytes", strconv.FormatInt(*logOptions.LimitBytes, 10)) + } + if logOptions.TailLines != nil { + req.Param("tailLines", strconv.FormatInt(*logOptions.TailLines, 10)) + } + readCloser, err := req.Stream() if err != nil { return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log_test.go index 58ba2eecf230..16171223cc3c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log_test.go @@ -24,6 +24,7 @@ import ( "k8s.io/kubernetes/pkg/api" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" ) func TestSelectContainer(t *testing.T) { @@ -165,9 +166,9 @@ func TestLog(t *testing.T) { for _, test := range tests { logContent := "test log content" f, tf, codec := NewAPIFactory() - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == test.podPath && m == "GET": body := objBody(codec, test.pod) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/patch_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/patch_test.go index 21efbb443f51..2819bb372d22 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/patch_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/patch_test.go @@ -21,7 +21,7 @@ import ( "net/http" "testing" - client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" ) func TestPatchObject(t *testing.T) { @@ -29,9 +29,9 @@ func TestPatchObject(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/services/frontend" && (m == "PATCH" || m == "GET"): return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil @@ -61,9 +61,9 @@ func TestPatchObjectFromFile(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/services/frontend" && (m == "PATCH" || m == "GET"): return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward.go index 45042bd26fe7..942a1c5009e2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward.go @@ -17,15 +17,16 @@ limitations under the License. package cmd import ( + "net/url" "os" "os/signal" "github.com/golang/glog" "github.com/spf13/cobra" "k8s.io/kubernetes/pkg/api" - apierrors "k8s.io/kubernetes/pkg/api/errors" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/portforward" + "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) @@ -61,13 +62,17 @@ func NewCmdPortForward(f *cmdutil.Factory) *cobra.Command { } type portForwarder interface { - ForwardPorts(req *client.Request, config *client.Config, ports []string, stopChan <-chan struct{}) error + ForwardPorts(method string, url *url.URL, config *client.Config, ports []string, stopChan <-chan struct{}) error } type defaultPortForwarder struct{} -func (*defaultPortForwarder) ForwardPorts(req *client.Request, config *client.Config, ports []string, stopChan <-chan struct{}) error { - fw, err := portforward.New(req, config, ports, stopChan) +func (*defaultPortForwarder) ForwardPorts(method string, url *url.URL, config *client.Config, ports []string, stopChan <-chan struct{}) error { + dialer, err := remotecommand.NewExecutor(config, method, url) + if err != nil { + return err + } + fw, err := portforward.New(dialer, ports, stopChan) if err != nil { return err } @@ -131,28 +136,5 @@ func RunPortForward(f *cmdutil.Factory, cmd *cobra.Command, args []string, fw po Name(pod.Name). SubResource("portforward") - postErr := fw.ForwardPorts(req, config, args, stopCh) - - // if we don't have an error, return. If we did get an error, try a GET because v3.0.0 shipped with port-forward running as a GET. - if postErr == nil { - return nil - } - - // only try the get if the error is either a forbidden or method not supported, otherwise trying with a GET probably won't help - if !apierrors.IsForbidden(postErr) && !apierrors.IsMethodNotSupported(postErr) { - return postErr - } - - getReq := client.RESTClient.Get(). - Resource("pods"). - Namespace(namespace). - Name(pod.Name). - SubResource("portforward") - getErr := fw.ForwardPorts(getReq, config, args, stopCh) - if getErr == nil { - return nil - } - - // if we got a getErr, return the postErr because it's more likely to be correct. GET is legacy - return postErr + return fw.ForwardPorts("POST", req.URL(), config, args, stopCh) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward_test.go index 059231910819..7092eb7aac89 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward_test.go @@ -19,6 +19,7 @@ package cmd import ( "fmt" "net/http" + "net/url" "testing" "github.com/spf13/cobra" @@ -26,15 +27,18 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" ) type fakePortForwarder struct { - req *client.Request - pfErr error + method string + url *url.URL + pfErr error } -func (f *fakePortForwarder) ForwardPorts(req *client.Request, config *client.Config, ports []string, stopChan <-chan struct{}) error { - f.req = req +func (f *fakePortForwarder) ForwardPorts(method string, url *url.URL, config *client.Config, ports []string, stopChan <-chan struct{}) error { + f.method = method + f.url = url return f.pfErr } @@ -64,9 +68,9 @@ func TestPortForward(t *testing.T) { } for _, test := range tests { f, tf, codec := NewAPIFactory() - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == test.podPath && m == "GET": body := objBody(codec, test.pod) @@ -91,12 +95,20 @@ func TestPortForward(t *testing.T) { if test.pfErr && err != ff.pfErr { t.Errorf("%s: Unexpected exec error: %v", test.name, err) } - if !test.pfErr && ff.req.URL().Path != test.pfPath { - t.Errorf("%s: Did not get expected path for portforward request", test.name) - } if !test.pfErr && err != nil { t.Errorf("%s: Unexpected error: %v", test.name, err) } + if test.pfErr { + continue + } + + if ff.url.Path != test.pfPath { + t.Errorf("%s: Did not get expected path for portforward request", test.name) + } + if ff.method != "POST" { + t.Errorf("%s: Did not get method for attach request: %s", test.name, ff.method) + } + } } @@ -126,9 +138,9 @@ func TestPortForwardWithPFlag(t *testing.T) { } for _, test := range tests { f, tf, codec := NewAPIFactory() - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == test.podPath && m == "GET": body := objBody(codec, test.pod) @@ -153,7 +165,7 @@ func TestPortForwardWithPFlag(t *testing.T) { if test.pfErr && err != ff.pfErr { t.Errorf("%s: Unexpected exec error: %v", test.name, err) } - if !test.pfErr && ff.req.URL().Path != test.pfPath { + if !test.pfErr && ff.url.Path != test.pfPath { t.Errorf("%s: Did not get expected path for portforward request", test.name) } if !test.pfErr && err != nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/proxy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/proxy.go index 5ab96b185ee4..130e2ae59673 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/proxy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/proxy.go @@ -71,12 +71,13 @@ The above lets you 'curl localhost:8001/custom/api/v1/pods' } cmd.Flags().StringP("www", "w", "", "Also serve static files from the given directory under the specified prefix.") cmd.Flags().StringP("www-prefix", "P", "/static/", "Prefix to serve static files under, if static file directory is specified.") - cmd.Flags().StringP("api-prefix", "", "/api/", "Prefix to serve the proxied API under.") + cmd.Flags().StringP("api-prefix", "", "/", "Prefix to serve the proxied API under.") cmd.Flags().String("accept-paths", kubectl.DefaultPathAcceptRE, "Regular expression for paths that the proxy should accept.") cmd.Flags().String("reject-paths", kubectl.DefaultPathRejectRE, "Regular expression for paths that the proxy should reject.") cmd.Flags().String("accept-hosts", kubectl.DefaultHostAcceptRE, "Regular expression for hosts that the proxy should accept.") cmd.Flags().String("reject-methods", kubectl.DefaultMethodRejectRE, "Regular expression for HTTP methods that the proxy should reject.") cmd.Flags().IntP("port", "p", default_port, "The port on which to run the proxy. Set to 0 to pick a random port.") + cmd.Flags().StringP("address", "", "127.0.0.1", "The IP address on which to serve on.") cmd.Flags().Bool("disable-filter", false, "If true, disable request filtering in the proxy. This is dangerous, and can leave you vulnerable to XSRF attacks, when used with an accessible port.") cmd.Flags().StringP("unix-socket", "u", "", "Unix socket on which to run the proxy.") return cmd @@ -85,6 +86,7 @@ The above lets you 'curl localhost:8001/custom/api/v1/pods' func RunProxy(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command) error { path := cmdutil.GetFlagString(cmd, "unix-socket") port := cmdutil.GetFlagInt(cmd, "port") + address := cmdutil.GetFlagString(cmd, "address") if port != default_port && path != "" { return errors.New("Don't specify both --unix-socket and --port") @@ -122,7 +124,7 @@ func RunProxy(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command) error { // when it is chosen by os (eg: port == 0) var l net.Listener if path == "" { - l, err = server.Listen(port) + l, err = server.Listen(address, port) } else { l, err = server.ListenUnix(path) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/replace.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/replace.go index 34a0fcc2e791..6bdf4f39935e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/replace.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/replace.go @@ -127,14 +127,23 @@ func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st if err != nil { return err } + + // Serialize the configuration into an annotation. + if err := kubectl.UpdateApplyAnnotation(info); err != nil { + return err + } + + // Serialize the object with the annotation applied. data, err := info.Mapping.Codec.Encode(info.Object) if err != nil { return cmdutil.AddSourceToErr("replacing", info.Source, err) } + obj, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, true, data) if err != nil { return cmdutil.AddSourceToErr("replacing", info.Source, err) } + info.Refresh(obj, true) printObjectSpecificMessage(obj, out) cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "replaced") @@ -211,14 +220,23 @@ func forceReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args [] if err != nil { return err } + + // Serialize the configuration into an annotation. + if err := kubectl.UpdateApplyAnnotation(info); err != nil { + return err + } + + // Serialize the object with the annotation applied. data, err := info.Mapping.Codec.Encode(info.Object) if err != nil { return err } + obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, data) if err != nil { return err } + count++ info.Refresh(obj, true) printObjectSpecificMessage(obj, out) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/replace_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/replace_test.go index 03c1e27e42f0..6b7e98dcf927 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/replace_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/replace_test.go @@ -22,7 +22,7 @@ import ( "strings" "testing" - client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" ) func TestReplaceObject(t *testing.T) { @@ -30,9 +30,9 @@ func TestReplaceObject(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && (m == "GET" || m == "PUT" || m == "DELETE"): return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil @@ -73,9 +73,9 @@ func TestReplaceMultipleObject(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && (m == "GET" || m == "PUT" || m == "DELETE"): return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil @@ -120,9 +120,9 @@ func TestReplaceDirectory(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case strings.HasPrefix(p, "/namespaces/test/services/") && (m == "GET" || m == "PUT" || m == "DELETE"): return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil @@ -167,9 +167,9 @@ func TestForceReplaceObjectNotFound(t *testing.T) { f, tf, codec := NewAPIFactory() tf.Printer = &testPrinter{} - tf.Client = &client.FakeRESTClient{ + tf.Client = &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE": return &http.Response{StatusCode: 404, Body: stringBody("")}, nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate.go index dabd5c5c087f..3192d27e20e8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate.go @@ -30,7 +30,6 @@ import ( "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/v1" - "k8s.io/kubernetes/pkg/api/v1beta3" "k8s.io/kubernetes/pkg/kubectl" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" @@ -101,47 +100,62 @@ func NewCmdRollingUpdate(f *cmdutil.Factory, out io.Writer) *cobra.Command { return cmd } -func validateArguments(cmd *cobra.Command, filenames, args []string) (deploymentKey, filename, image, oldName string, err error) { - deploymentKey = cmdutil.GetFlagString(cmd, "deployment-label-key") - image = cmdutil.GetFlagString(cmd, "image") - filename = "" +func validateArguments(cmd *cobra.Command, filenames, args []string) error { + deploymentKey := cmdutil.GetFlagString(cmd, "deployment-label-key") + image := cmdutil.GetFlagString(cmd, "image") + rollback := cmdutil.GetFlagBool(cmd, "rollback") if len(deploymentKey) == 0 { - return "", "", "", "", cmdutil.UsageError(cmd, "--deployment-label-key can not be empty") + return cmdutil.UsageError(cmd, "--deployment-label-key can not be empty") } if len(filenames) > 1 { - return "", "", "", "", cmdutil.UsageError(cmd, "May only specificy a single filename for new controller") + return cmdutil.UsageError(cmd, "May only specify a single filename for new controller") } - if len(filenames) > 0 { - filename = filenames[0] - } - if len(filenames) == 0 && len(image) == 0 { - return "", "", "", "", cmdutil.UsageError(cmd, "Must specify --filename or --image for new controller") - } - if len(filenames) != 0 && len(image) != 0 { - return "", "", "", "", cmdutil.UsageError(cmd, "--filename and --image can not both be specified") + + if !rollback { + if len(filenames) == 0 && len(image) == 0 { + return cmdutil.UsageError(cmd, "Must specify --filename or --image for new controller") + } + if len(filenames) != 0 && len(image) != 0 { + return cmdutil.UsageError(cmd, "--filename and --image can not both be specified") + } + } else { + if len(filenames) != 0 || len(image) != 0 { + return cmdutil.UsageError(cmd, "Don't specify --filename or --image on rollback") + } } + if len(args) < 1 { - return "", "", "", "", cmdutil.UsageError(cmd, "Must specify the controller to update") + return cmdutil.UsageError(cmd, "Must specify the controller to update") } - return deploymentKey, filename, image, args[0], nil + return nil } func RunRollingUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, options *RollingUpdateOptions) error { if len(os.Args) > 1 && os.Args[1] == "rollingupdate" { printDeprecationWarning("rolling-update", "rollingupdate") } - deploymentKey, filename, image, oldName, err := validateArguments(cmd, options.Filenames, args) + err := validateArguments(cmd, options.Filenames, args) if err != nil { return err } + + deploymentKey := cmdutil.GetFlagString(cmd, "deployment-label-key") + filename := "" + image := cmdutil.GetFlagString(cmd, "image") + oldName := args[0] + rollback := cmdutil.GetFlagBool(cmd, "rollback") period := cmdutil.GetFlagDuration(cmd, "update-period") interval := cmdutil.GetFlagDuration(cmd, "poll-interval") timeout := cmdutil.GetFlagDuration(cmd, "timeout") dryrun := cmdutil.GetFlagBool(cmd, "dry-run") outputFormat := cmdutil.GetFlagString(cmd, "output") + if len(options.Filenames) > 0 { + filename = options.Filenames[0] + } + cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err @@ -239,6 +253,19 @@ func RunRollingUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, arg return err } } + + if rollback { + keepOldName = len(args) == 1 + newName := findNewName(args, oldRc) + if newRc, err = kubectl.LoadExistingNextReplicationController(client, cmdNamespace, newName); err != nil { + return err + } + + if newRc == nil { + return cmdutil.UsageError(cmd, "Could not find %s to rollback.\n", newName) + } + } + if oldName == newRc.Name { return cmdutil.UsageError(cmd, "%s cannot have the same name as the existing ReplicationController %s", filename, oldName) @@ -296,8 +323,11 @@ func RunRollingUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, arg MaxUnavailable: util.NewIntOrStringFromInt(0), MaxSurge: util.NewIntOrStringFromInt(1), } - if cmdutil.GetFlagBool(cmd, "rollback") { - kubectl.AbortRollingUpdate(config) + if rollback { + err = kubectl.AbortRollingUpdate(config) + if err != nil { + return err + } client.ReplicationControllers(config.NewRc.Namespace).Update(config.NewRc) } err = updater.Update(config) @@ -344,10 +374,6 @@ func isReplicasDefaulted(info *resource.Info) bool { return false } switch info.Mapping.APIVersion { - case "v1beta3": - if rc, ok := info.VersionedObject.(*v1beta3.ReplicationController); ok { - return rc.Spec.Replicas == nil - } case "v1": if rc, ok := info.VersionedObject.(*v1.ReplicationController); ok { return rc.Spec.Replicas == nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate_test.go index a132a7dcee60..bf2204b27312 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate_test.go @@ -79,7 +79,7 @@ func TestValidateArgs(t *testing.T) { cmd.Flags().Set(key, val) } } - _, _, _, _, err := validateArguments(cmd, test.filenames, test.args) + err := validateArguments(cmd, test.filenames, test.args) if err != nil && !test.expectErr { t.Errorf("unexpected error: %v (%s)", err, test.testName) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/run.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/run.go index d79f40d3803d..a4a3b0182692 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/run.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/run.go @@ -42,7 +42,7 @@ $ kubectl run nginx --image=nginx $ kubectl run hazelcast --image=hazelcast --port=5701 # Start a single instance of hazelcast and set environment variables "DNS_DOMAIN=cluster" and "POD_NAMESPACE=default" in the container. -$ kubectl run hazelcast --image=hazelcast --env="DNS_DOMAIN=local" --env="POD_NAMESPACE=default" +$ kubectl run hazelcast --image=hazelcast --env="DNS_DOMAIN=cluster" --env="POD_NAMESPACE=default" # Start a replicated instance of nginx. $ kubectl run nginx --image=nginx --replicas=5 @@ -184,10 +184,23 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob // TODO: extract this flag to a central location, when such a location exists. if !cmdutil.GetFlagBool(cmd, "dry-run") { - data, err := mapping.Codec.Encode(obj) + resourceMapper := &resource.Mapper{ObjectTyper: typer, RESTMapper: mapper, ClientMapper: f.ClientMapperForCommand()} + info, err := resourceMapper.InfoForObject(obj) if err != nil { return err } + + // Serialize the configuration into an annotation. + if err := kubectl.UpdateApplyAnnotation(info); err != nil { + return err + } + + // Serialize the object with the annotation applied. + data, err := mapping.Codec.Encode(info.Object) + if err != nil { + return err + } + obj, err = resource.NewHelper(client, mapping).Create(namespace, false, data) if err != nil { return err @@ -291,12 +304,16 @@ func handleAttachPod(c *client.Client, pod *api.Pod, opts *AttachOptions) error return err } if status == api.PodSucceeded || status == api.PodFailed { - return handleLog(c, pod.Namespace, pod.Name, pod.Spec.Containers[0].Name, false, false, opts.Out) + return handleLog(c, pod.Namespace, pod.Name, &api.PodLogOptions{Container: opts.GetContainerName(pod)}, opts.Out) } opts.Client = c opts.PodName = pod.Name opts.Namespace = pod.Namespace - return opts.Run() + if err := opts.Run(); err != nil { + fmt.Fprintf(opts.Out, "Error attaching, falling back to logs: %v\n", err) + return handleLog(c, pod.Namespace, pod.Name, &api.PodLogOptions{Container: opts.GetContainerName(pod)}, opts.Out) + } + return nil } func getRestartPolicy(cmd *cobra.Command, interactive bool) (api.RestartPolicy, error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/editor.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/editor.go new file mode 100644 index 000000000000..2145792e9013 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/editor.go @@ -0,0 +1,199 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 editor + +import ( + "fmt" + "io" + "io/ioutil" + "math/rand" + "os" + "os/exec" + "os/signal" + "path/filepath" + "strings" + + "github.com/docker/docker/pkg/term" + "github.com/golang/glog" +) + +const ( + // sorry, blame Git + defaultEditor = "vi" + defaultShell = "/bin/bash" +) + +type Editor struct { + Args []string + Shell bool +} + +// NewDefaultEditor creates a struct Editor that uses the OS environment to +// locate the editor program, looking at EDITOR environment variable to find +// the proper command line. If the provided editor has no spaces, or no quotes, +// it is treated as a bare command to be loaded. Otherwise, the string will +// be passed to the user's shell for execution. +func NewDefaultEditor() Editor { + args, shell := defaultEnvEditor() + return Editor{ + Args: args, + Shell: shell, + } +} + +func defaultEnvShell() []string { + shell := os.Getenv("SHELL") + if len(shell) == 0 { + shell = defaultShell + } + return []string{shell, "-c"} +} + +func defaultEnvEditor() ([]string, bool) { + editor := os.Getenv("EDITOR") + if len(editor) == 0 { + editor = defaultEditor + } + if !strings.Contains(editor, " ") { + return []string{editor}, false + } + if !strings.ContainsAny(editor, "\"'\\") { + return strings.Split(editor, " "), false + } + // rather than parse the shell arguments ourselves, punt to the shell + shell := defaultEnvShell() + return append(shell, editor), true +} + +func (e Editor) args(path string) []string { + args := make([]string, len(e.Args)) + copy(args, e.Args) + if e.Shell { + last := args[len(args)-1] + args[len(args)-1] = fmt.Sprintf("%s %q", last, path) + } else { + args = append(args, path) + } + return args +} + +// Launch opens the described or returns an error. The TTY will be protected, and +// SIGQUIT, SIGTERM, and SIGINT will all be trapped. +func (e Editor) Launch(path string) error { + if len(e.Args) == 0 { + return fmt.Errorf("no editor defined, can't open %s", path) + } + abs, err := filepath.Abs(path) + if err != nil { + return err + } + args := e.args(abs) + cmd := exec.Command(args[0], args[1:]...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Stdin = os.Stdin + glog.V(5).Infof("Opening file with editor %v", args) + if err := withSafeTTYAndInterrupts(cmd.Run); err != nil { + if err, ok := err.(*exec.Error); ok { + if err.Err == exec.ErrNotFound { + return fmt.Errorf("unable to launch the editor %q", strings.Join(e.Args, " ")) + } + } + return fmt.Errorf("there was a problem with the editor %q", strings.Join(e.Args, " ")) + } + return nil +} + +// LaunchTempFile reads the provided stream into a temporary file in the given directory +// and file prefix, and then invokes Launch with the path of that file. It will return +// the contents of the file after launch, any errors that occur, and the path of the +// temporary file so the caller can clean it up as needed. +func (e Editor) LaunchTempFile(prefix, suffix string, r io.Reader) ([]byte, string, error) { + f, err := tempFile(prefix, suffix) + if err != nil { + return nil, "", err + } + defer f.Close() + path := f.Name() + if _, err := io.Copy(f, r); err != nil { + os.Remove(path) + return nil, path, err + } + if err := e.Launch(path); err != nil { + return nil, path, err + } + bytes, err := ioutil.ReadFile(path) + return bytes, path, err +} + +// withSafeTTYAndInterrupts invokes the provided function after the terminal +// state has been stored, and then on any error or termination attempts to +// restore the terminal state to its prior behavior. It also eats signals +// for the duration of the function. +func withSafeTTYAndInterrupts(fn func() error) error { + ch := make(chan os.Signal, 1) + signal.Notify(ch, childSignals...) + defer signal.Stop(ch) + + inFd := os.Stdin.Fd() + if !term.IsTerminal(inFd) { + if f, err := os.Open("/dev/tty"); err == nil { + defer f.Close() + inFd = f.Fd() + } + } + + if term.IsTerminal(inFd) { + state, err := term.SaveState(inFd) + if err != nil { + return err + } + go func() { + if _, ok := <-ch; !ok { + return + } + term.RestoreTerminal(inFd, state) + }() + defer term.RestoreTerminal(inFd, state) + return fn() + } + return fn() +} + +func tempFile(prefix, suffix string) (f *os.File, err error) { + dir := os.TempDir() + + for i := 0; i < 10000; i++ { + name := filepath.Join(dir, prefix+randSeq(5)+suffix) + f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) + if os.IsExist(err) { + continue + } + break + } + return +} + +var letters = []rune("abcdefghijklmnopqrstuvwxyz0123456789") + +func randSeq(n int) string { + b := make([]rune, n) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + return string(b) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/editor_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/editor_test.go new file mode 100644 index 000000000000..9be83a04276d --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/editor_test.go @@ -0,0 +1,63 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 editor + +import ( + "bytes" + "io/ioutil" + "os" + "reflect" + "strings" + "testing" +) + +func TestArgs(t *testing.T) { + if e, a := []string{"/bin/bash", "-c \"test\""}, (Editor{Args: []string{"/bin/bash", "-c"}, Shell: true}).args("test"); !reflect.DeepEqual(e, a) { + t.Errorf("unexpected args: %v", a) + } + if e, a := []string{"/bin/bash", "-c", "test"}, (Editor{Args: []string{"/bin/bash", "-c"}, Shell: false}).args("test"); !reflect.DeepEqual(e, a) { + t.Errorf("unexpected args: %v", a) + } + if e, a := []string{"/bin/bash", "-i -c \"test\""}, (Editor{Args: []string{"/bin/bash", "-i -c"}, Shell: true}).args("test"); !reflect.DeepEqual(e, a) { + t.Errorf("unexpected args: %v", a) + } + if e, a := []string{"/test", "test"}, (Editor{Args: []string{"/test"}}).args("test"); !reflect.DeepEqual(e, a) { + t.Errorf("unexpected args: %v", a) + } +} + +func TestEditor(t *testing.T) { + edit := Editor{Args: []string{"cat"}} + testStr := "test something\n" + contents, path, err := edit.LaunchTempFile("", "someprefix", bytes.NewBufferString(testStr)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if _, err := os.Stat(path); err != nil { + t.Fatalf("no temp file: %s", path) + } + defer os.Remove(path) + if disk, err := ioutil.ReadFile(path); err != nil || !bytes.Equal(contents, disk) { + t.Errorf("unexpected file on disk: %v %s", err, string(disk)) + } + if !bytes.Equal(contents, []byte(testStr)) { + t.Errorf("unexpected contents: %s", string(contents)) + } + if !strings.Contains(path, "someprefix") { + t.Errorf("path not expected: %s", path) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/term.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/term.go new file mode 100644 index 000000000000..9db85fe4b062 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/term.go @@ -0,0 +1,27 @@ +// +build !windows + +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 editor + +import ( + "os" + "syscall" +) + +// childSignals are the allowed signals that can be sent to children in Unix variant OS's +var childSignals = []os.Signal{syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/term_unsupported.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/term_unsupported.go new file mode 100644 index 000000000000..4c0b788166d4 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/term_unsupported.go @@ -0,0 +1,26 @@ +// +build windows + +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 editor + +import ( + "os" +) + +// childSignals are the allowed signals that can be sent to children in Windows to terminate +var childSignals = []os.Signal{os.Interrupt} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go index 2d90df2ade5e..6fd411881817 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go @@ -18,11 +18,13 @@ package util import ( "bytes" + "errors" "flag" "fmt" "io" "io/ioutil" "os" + "os/user" "path" "strconv" @@ -86,6 +88,8 @@ type Factory struct { DefaultNamespace func() (string, bool, error) // Returns the generator for the provided generator name Generator func(name string) (kubectl.Generator, bool) + // Check whether the kind of resources could be exposed + CanBeExposed func(kind string) error } // NewFactory creates a factory with the default Kubernetes resources defined @@ -136,10 +140,10 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { return nil, err } switch group { - case "api": + case "": return client.RESTClient, nil - case "experimental": - return client.ExperimentalClient.RESTClient, nil + case "extensions": + return client.ExtensionsClient.RESTClient, nil } return nil, fmt.Errorf("unable to get RESTClient for resource '%s'", mapping.Resource) }, @@ -208,7 +212,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { if err != nil { return nil, err } - return kubectl.ScalerFor(mapping.Kind, kubectl.NewScalerClient(client)) + return kubectl.ScalerFor(mapping.Kind, client) }, Reaper: func(mapping *meta.RESTMapping) (kubectl.Reaper, error) { client, err := clients.ClientForVersion(mapping.APIVersion) @@ -233,8 +237,8 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { } return &clientSwaggerSchema{ c: client, - ec: client.ExperimentalClient, cacheDir: dir, + mapper: api.RESTMapper, }, nil } return validation.NullSchema{}, nil @@ -246,6 +250,12 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { generator, ok := generators[name] return generator, ok }, + CanBeExposed: func(kind string) error { + if kind != "ReplicationController" && kind != "Service" && kind != "Pod" { + return fmt.Errorf("invalid resource provided: %v, only a replication controller, service or pod is accepted", kind) + } + return nil + }, } } @@ -289,8 +299,8 @@ func getServicePorts(spec api.ServiceSpec) []string { type clientSwaggerSchema struct { c *client.Client - ec *client.ExperimentalClient cacheDir string + mapper meta.RESTMapper } const schemaFileName = "schema.json" @@ -299,9 +309,63 @@ type schemaClient interface { Get() *client.Request } -func getSchemaAndValidate(c schemaClient, data []byte, group, version, cacheDir string) (err error) { +func recursiveSplit(dir string) []string { + parent, file := path.Split(dir) + if len(parent) == 0 { + return []string{file} + } + return append(recursiveSplit(parent[:len(parent)-1]), file) +} + +func substituteUserHome(dir string) (string, error) { + if len(dir) == 0 || dir[0] != '~' { + return dir, nil + } + parts := recursiveSplit(dir) + if len(parts[0]) == 1 { + parts[0] = os.Getenv("HOME") + } else { + usr, err := user.Lookup(parts[0][1:]) + if err != nil { + return "", err + } + parts[0] = usr.HomeDir + } + return path.Join(parts...), nil +} + +func writeSchemaFile(schemaData []byte, cacheDir, cacheFile, prefix, groupVersion string) error { + if err := os.MkdirAll(path.Join(cacheDir, prefix, groupVersion), 0755); err != nil { + return err + } + tmpFile, err := ioutil.TempFile(cacheDir, "schema") + if err != nil { + // If we can't write, keep going. + if os.IsPermission(err) { + return nil + } + return err + } + if _, err := io.Copy(tmpFile, bytes.NewBuffer(schemaData)); err != nil { + return err + } + if err := os.Link(tmpFile.Name(), cacheFile); err != nil { + // If we can't write due to file existing, or permission problems, keep going. + if os.IsExist(err) || os.IsPermission(err) { + return nil + } + return err + } + return nil +} + +func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cacheDir string) (err error) { var schemaData []byte - cacheFile := path.Join(cacheDir, group, version, schemaFileName) + fullDir, err := substituteUserHome(cacheDir) + if err != nil { + return err + } + cacheFile := path.Join(fullDir, prefix, groupVersion, schemaFileName) if len(cacheDir) != 0 { if schemaData, err = ioutil.ReadFile(cacheFile); err != nil && !os.IsNotExist(err) { @@ -310,24 +374,14 @@ func getSchemaAndValidate(c schemaClient, data []byte, group, version, cacheDir } if schemaData == nil { schemaData, err = c.Get(). - AbsPath("/swaggerapi", group, version). + AbsPath("/swaggerapi", prefix, groupVersion). Do(). Raw() if err != nil { return err } if len(cacheDir) != 0 { - if err = os.MkdirAll(path.Join(cacheDir, group, version), 0755); err != nil { - return err - } - tmpFile, err := ioutil.TempFile(cacheDir, "schema") - if err != nil { - return err - } - if _, err := io.Copy(tmpFile, bytes.NewBuffer(schemaData)); err != nil { - return err - } - if err := os.Link(tmpFile.Name(), cacheFile); err != nil && !os.IsExist(err) { + if err := writeSchemaFile(schemaData, fullDir, cacheFile, prefix, groupVersion); err != nil { return err } } @@ -340,25 +394,25 @@ func getSchemaAndValidate(c schemaClient, data []byte, group, version, cacheDir } func (c *clientSwaggerSchema) ValidateBytes(data []byte) error { - version, _, err := runtime.UnstructuredJSONScheme.DataVersionAndKind(data) + version, kind, err := runtime.UnstructuredJSONScheme.DataVersionAndKind(data) if err != nil { return err } if ok := registered.IsRegisteredAPIVersion(version); !ok { return fmt.Errorf("API version %q isn't supported, only supports API versions %q", version, registered.RegisteredVersions) } - // First try stable api, if we can't validate using that, try experimental. - // If experimental fails, return error from stable api. - // TODO: Figure out which group to try once multiple group support is merged - // instead of trying everything. - err = getSchemaAndValidate(c.c.RESTClient, data, "api", version, c.cacheDir) - if err != nil && c.ec != nil { - errExp := getSchemaAndValidate(c.ec.RESTClient, data, "experimental", version, c.cacheDir) - if errExp == nil { - return nil + resource, _ := meta.KindToResource(kind, false) + group, err := c.mapper.GroupForResource(resource) + if err != nil { + return fmt.Errorf("could not find api group for %s: %v", kind, err) + } + if group == "extensions" { + if c.c.ExtensionsClient == nil { + return errors.New("unable to validate: no experimental client") } + return getSchemaAndValidate(c.c.ExtensionsClient.RESTClient, data, "apis/", version, c.cacheDir) } - return err + return getSchemaAndValidate(c.c.RESTClient, data, "api", version, c.cacheDir) } // DefaultClientConfig creates a clientcmd.ClientConfig with the following hierarchy: @@ -478,3 +532,11 @@ func (f *Factory) ClientMapperForCommand() resource.ClientMapper { return f.RESTClient(mapping) }) } + +// NilClientMapperForCommand returns a ClientMapper which always returns nil. +// When command is running locally and client isn't needed, this mapper can be parsed to NewBuilder. +func (f *Factory) NilClientMapperForCommand() resource.ClientMapper { + return resource.ClientMapperFunc(func(mapping *meta.RESTMapping) (resource.RESTClient, error) { + return nil, nil + }) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory_test.go index c4b5c917994d..41af6303ea81 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory_test.go @@ -22,6 +22,7 @@ import ( "io/ioutil" "net/http" "os" + "os/user" "path" "sort" "strings" @@ -29,10 +30,11 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/validation" - client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" + "k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" @@ -127,7 +129,7 @@ func TestLabelsForObject(t *testing.T) { name: "successful re-use of labels", object: &api.Service{ ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", Labels: map[string]string{"svc": "test"}}, - TypeMeta: api.TypeMeta{Kind: "Service", APIVersion: "v1"}, + TypeMeta: unversioned.TypeMeta{Kind: "Service", APIVersion: "v1"}, }, expected: "svc=test", err: nil, @@ -136,7 +138,7 @@ func TestLabelsForObject(t *testing.T) { name: "empty labels", object: &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", Labels: map[string]string{}}, - TypeMeta: api.TypeMeta{Kind: "Service", APIVersion: "v1"}, + TypeMeta: unversioned.TypeMeta{Kind: "Service", APIVersion: "v1"}, }, expected: "", err: nil, @@ -145,7 +147,7 @@ func TestLabelsForObject(t *testing.T) { name: "nil labels", object: &api.Service{ ObjectMeta: api.ObjectMeta{Name: "zen", Namespace: "test", Labels: nil}, - TypeMeta: api.TypeMeta{Kind: "Service", APIVersion: "v1"}, + TypeMeta: unversioned.TypeMeta{Kind: "Service", APIVersion: "v1"}, }, expected: "", err: nil, @@ -165,6 +167,33 @@ func TestLabelsForObject(t *testing.T) { } } +func TestCanBeExposed(t *testing.T) { + factory := NewFactory(nil) + tests := []struct { + kind string + expectErr bool + }{ + { + kind: "ReplicationController", + expectErr: false, + }, + { + kind: "Node", + expectErr: true, + }, + } + + for _, test := range tests { + err := factory.CanBeExposed(test.kind) + if test.expectErr && err == nil { + t.Error("unexpected non-error") + } + if !test.expectErr && err != nil { + t.Errorf("unexpected error: %v", err) + } + } +} + func TestFlagUnderscoreRenaming(t *testing.T) { factory := NewFactory(nil) @@ -199,9 +228,9 @@ func TestValidateCachesSchema(t *testing.T) { } requests := map[string]int{} - c := &client.FakeRESTClient{ + c := &fake.RESTClient{ Codec: testapi.Default.Codec(), - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case strings.HasPrefix(p, "/swaggerapi") && m == "GET": requests[p] = requests[p] + 1 @@ -274,3 +303,36 @@ func TestValidateCachesSchema(t *testing.T) { t.Errorf("unexpected cache file error: %v", err) } } + +func TestSubstitueUser(t *testing.T) { + usr, err := user.Current() + if err != nil { + t.Logf("SKIPPING TEST: unexpected error: %v", err) + return + } + tests := []struct { + input string + expected string + expectErr bool + }{ + {input: "~/foo", expected: path.Join(os.Getenv("HOME"), "foo")}, + {input: "~" + usr.Username + "/bar", expected: usr.HomeDir + "/bar"}, + {input: "/foo/bar", expected: "/foo/bar"}, + {input: "~doesntexit/bar", expectErr: true}, + } + for _, test := range tests { + output, err := substituteUserHome(test.input) + if test.expectErr { + if err == nil { + t.Error("unexpected non-error") + } + continue + } + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if output != test.expected { + t.Errorf("expected: %s, saw: %s", test.expected, output) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go index 523fb3fa9010..9e3283fa4615 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go @@ -29,11 +29,12 @@ import ( "time" "github.com/evanphx/json-patch" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/runtime" utilerrors "k8s.io/kubernetes/pkg/util/errors" @@ -122,7 +123,7 @@ func checkErr(err error, handleErr func(string)) { handleErr(msg) } -func statusCausesToAggrError(scs []api.StatusCause) utilerrors.Aggregate { +func statusCausesToAggrError(scs []unversioned.StatusCause) utilerrors.Aggregate { errs := make([]error, len(scs)) for i, sc := range scs { errs[i] = fmt.Errorf("%s: %s", sc.Field, sc.Message) @@ -260,6 +261,15 @@ func GetFlagInt(cmd *cobra.Command, flag string) int { return i } +// Assumes the flag has a default value. +func GetFlagInt64(cmd *cobra.Command, flag string) int64 { + i, err := cmd.Flags().GetInt64(flag) + if err != nil { + glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err) + } + return i +} + func GetFlagDuration(cmd *cobra.Command, flag string) time.Duration { d, err := cmd.Flags().GetDuration(flag) if err != nil { @@ -269,8 +279,8 @@ func GetFlagDuration(cmd *cobra.Command, flag string) time.Duration { } func AddValidateFlags(cmd *cobra.Command) { - cmd.Flags().Bool("validate", false, "If true, use a schema to validate the input before sending it") - cmd.Flags().String("schema-cache-dir", "/tmp/kubectl.schema", "If non-empty, load/store cached API schemas in this directory, default is '/tmp/kubectl.schema'") + cmd.Flags().Bool("validate", true, "If true, use a schema to validate the input before sending it") + cmd.Flags().String("schema-cache-dir", fmt.Sprintf("~/%s/%s", clientcmd.RecommendedHomeDir, clientcmd.RecommendedSchemaName), fmt.Sprintf("If non-empty, load/store cached API schemas in this directory, default is '$HOME/%s/%s'", clientcmd.RecommendedHomeDir, clientcmd.RecommendedSchemaName)) } func ReadConfigDataFromReader(reader io.Reader, source string) ([]byte, error) { @@ -345,7 +355,7 @@ func Merge(dst runtime.Object, fragment, kind string) (runtime.Object, error) { if !ok { return nil, fmt.Errorf("apiVersion must be a string") } - i, err := latest.InterfacesFor(versionString) + i, err := latest.GroupOrDie("").InterfacesFor(versionString) if err != nil { return nil, err } @@ -395,18 +405,23 @@ func DumpReaderToFile(reader io.Reader, filename string) error { func UpdateObject(info *resource.Info, updateFn func(runtime.Object) error) (runtime.Object, error) { helper := resource.NewHelper(info.Client, info.Mapping) - err := updateFn(info.Object) - if err != nil { + if err := updateFn(info.Object); err != nil { + return nil, err + } + + // Update the annotation used by kubectl apply + if err := kubectl.UpdateApplyAnnotation(info); err != nil { return nil, err } + data, err := helper.Codec.Encode(info.Object) if err != nil { return nil, err } - _, err = helper.Replace(info.Namespace, info.Name, true, data) - if err != nil { + if _, err := helper.Replace(info.Namespace, info.Name, true, data); err != nil { return nil, err } + return info.Object, nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers_test.go index 2547c10fb0de..a0e7d6299430 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers_test.go @@ -29,6 +29,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/testapi" + apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/fielderrors" ) @@ -54,11 +55,7 @@ func TestMerge(t *testing.T) { ObjectMeta: api.ObjectMeta{ Name: "foo", }, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, }, /* TODO: uncomment this test once Merge is updated to use @@ -127,6 +124,7 @@ func TestMerge(t *testing.T) { RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, + SecurityContext: &api.PodSecurityContext{}, }, }, }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/jsonmerge/jsonmerge.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/jsonmerge/jsonmerge.go new file mode 100644 index 000000000000..84a76da9541b --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/jsonmerge/jsonmerge.go @@ -0,0 +1,193 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 jsonmerge + +import ( + "encoding/json" + "fmt" + + "github.com/evanphx/json-patch" + "github.com/golang/glog" + + "k8s.io/kubernetes/pkg/util/strategicpatch" + "k8s.io/kubernetes/pkg/util/yaml" +) + +// Delta represents a change between two JSON documents. +type Delta struct { + original []byte + edit []byte + + preconditions []PreconditionFunc +} + +// PreconditionFunc is a test to verify that an incompatible change +// has occurred before an Apply can be successful. +type PreconditionFunc func(interface{}) (hold bool, message string) + +// AddPreconditions adds precondition checks to a change which must +// be satisfied before an Apply is considered successful. If a +// precondition returns false, the Apply is failed with +// ErrPreconditionFailed. +func (d *Delta) AddPreconditions(fns ...PreconditionFunc) { + d.preconditions = append(d.preconditions, fns...) +} + +// RequireKeyUnchanged creates a precondition function that fails +// if the provided key is present in the diff (indicating its value +// has changed). +func RequireKeyUnchanged(key string) PreconditionFunc { + return func(diff interface{}) (bool, string) { + m, ok := diff.(map[string]interface{}) + if !ok { + return true, "" + } + // the presence of key in a diff means that its value has been changed, therefore + // we should fail the precondition. + _, ok = m[key] + if ok { + return false, key + " should not be changed\n" + } else { + return true, "" + } + } +} + +// RequireKeyUnchanged creates a precondition function that fails +// if the metadata.key is present in the diff (indicating its value +// has changed). +func RequireMetadataKeyUnchanged(key string) PreconditionFunc { + return func(diff interface{}) (bool, string) { + m, ok := diff.(map[string]interface{}) + if !ok { + return true, "" + } + m1, ok := m["metadata"] + if !ok { + return true, "" + } + m2, ok := m1.(map[string]interface{}) + if !ok { + return true, "" + } + _, ok = m2[key] + if ok { + return false, "metadata." + key + " should not be changed\n" + } else { + return true, "" + } + } +} + +// TestPreconditions test if preconditions hold given the edit +func TestPreconditionsHold(edit []byte, preconditions []PreconditionFunc) (bool, string) { + diff := make(map[string]interface{}) + if err := json.Unmarshal(edit, &diff); err != nil { + return false, err.Error() + } + for _, fn := range preconditions { + if hold, msg := fn(diff); !hold { + return false, msg + } + } + return true, "" +} + +// NewDelta accepts two JSON or YAML documents and calculates the difference +// between them. It returns a Delta object which can be used to resolve +// conflicts against a third version with a common parent, or an error +// if either document is in error. +func NewDelta(from, to []byte) (*Delta, error) { + d := &Delta{} + before, err := yaml.ToJSON(from) + if err != nil { + return nil, err + } + after, err := yaml.ToJSON(to) + if err != nil { + return nil, err + } + diff, err := jsonpatch.CreateMergePatch(before, after) + if err != nil { + return nil, err + } + glog.V(6).Infof("Patch created from:\n%s\n%s\n%s", string(before), string(after), string(diff)) + d.original = before + d.edit = diff + return d, nil +} + +// Apply attempts to apply the changes described by Delta onto latest, +// returning an error if the changes cannot be applied cleanly. +// IsConflicting will be true if the changes overlap, otherwise a +// generic error will be returned. +func (d *Delta) Apply(latest []byte) ([]byte, error) { + base, err := yaml.ToJSON(latest) + if err != nil { + return nil, err + } + changes, err := jsonpatch.CreateMergePatch(d.original, base) + if err != nil { + return nil, err + } + diff1 := make(map[string]interface{}) + if err := json.Unmarshal(d.edit, &diff1); err != nil { + return nil, err + } + diff2 := make(map[string]interface{}) + if err := json.Unmarshal(changes, &diff2); err != nil { + return nil, err + } + for _, fn := range d.preconditions { + hold1, _ := fn(diff1) + hold2, _ := fn(diff2) + if !hold1 || !hold2 { + return nil, ErrPreconditionFailed + } + } + + glog.V(6).Infof("Testing for conflict between:\n%s\n%s", string(d.edit), string(changes)) + hasConflicts, err := strategicpatch.HasConflicts(diff1, diff2) + if err != nil { + return nil, err + } + if hasConflicts { + return nil, ErrConflict + } + + return jsonpatch.MergePatch(base, d.edit) +} + +// IsConflicting returns true if the provided error indicates a +// conflict exists between the original changes and the applied +// changes. +func IsConflicting(err error) bool { + return err == ErrConflict +} + +// IsPreconditionFailed returns true if the provided error indicates +// a Delta precondition did not succeed. +func IsPreconditionFailed(err error) bool { + return err == ErrPreconditionFailed +} + +var ErrPreconditionFailed = fmt.Errorf("a precondition failed") +var ErrConflict = fmt.Errorf("changes are in conflict") + +func (d *Delta) Edit() []byte { + return d.edit +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/version.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/version.go index e0af74e914be..beaeda7bb100 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/version.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/version.go @@ -35,6 +35,7 @@ func NewCmdVersion(f *cmdutil.Factory, out io.Writer) *cobra.Command { }, } cmd.Flags().BoolP("client", "c", false, "Client version only (no server required).") + cmd.Flags().MarkShorthandDeprecated("client", "please use --client instead.") return cmd } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/custom_column_printer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/custom_column_printer.go index e48003fac60d..c73feba8f16a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/custom_column_printer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/custom_column_printer.go @@ -26,6 +26,7 @@ import ( "strings" "text/tabwriter" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/jsonpath" ) @@ -187,6 +188,13 @@ func (s *CustomColumnsPrinter) PrintObj(obj runtime.Object, out io.Writer) error func (s *CustomColumnsPrinter) printOneObject(obj runtime.Object, parsers []*jsonpath.JSONPath, out io.Writer) error { columns := make([]string, len(parsers)) + switch u := obj.(type) { + case *runtime.Unknown: + var err error + if obj, err = api.Codec.Decode(u.RawJSON); err != nil { + return err + } + } for ix := range parsers { parser := parsers[ix] values, err := parser.FindResults(reflect.ValueOf(obj).Elem().Interface()) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/custom_column_printer_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/custom_column_printer_test.go index ac9fc9699ea0..41897f4b28fb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/custom_column_printer_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/custom_column_printer_test.go @@ -21,6 +21,7 @@ import ( "reflect" "testing" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/runtime" ) @@ -251,7 +252,7 @@ bar FieldSpec: "{.apiVersion}", }, }, - obj: &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "foo"}, TypeMeta: v1.TypeMeta{APIVersion: "baz"}}, + obj: &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "foo"}, TypeMeta: unversioned.TypeMeta{APIVersion: "baz"}}, expectedOutput: `NAME API_VERSION foo baz `, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe.go index d4d539ea945f..8966b0cf6189 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe.go @@ -28,12 +28,14 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/apis/extensions" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fieldpath" "k8s.io/kubernetes/pkg/fields" qosutil "k8s.io/kubernetes/pkg/kubelet/qos/util" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/types" + deploymentUtil "k8s.io/kubernetes/pkg/util/deployment" "k8s.io/kubernetes/pkg/util/sets" ) @@ -85,6 +87,9 @@ func describerMap(c *client.Client) map[string]Describer { func expDescriberMap(c *client.Client) map[string]Describer { return map[string]Describer{ "HorizontalPodAutoscaler": &HorizontalPodAutoscalerDescriber{c}, + "DaemonSet": &DaemonSetDescriber{c}, + "Job": &JobDescriber{c}, + "Deployment": &DeploymentDescriber{c}, } } @@ -106,9 +111,9 @@ func DescriberFor(group string, kind string, c *client.Client) (Describer, bool) var ok bool switch group { - case "api": + case "": f, ok = describerMap(c)[kind] - case "experimental": + case "extensions": f, ok = expDescriberMap(c)[kind] } @@ -126,6 +131,7 @@ func init() { describePod, describeService, describeReplicationController, + describeDaemonSet, describeNode, describeNamespace, ) @@ -145,11 +151,11 @@ func (d *NamespaceDescriber) Describe(namespace, name string) (string, error) { if err != nil { return "", err } - resourceQuotaList, err := d.ResourceQuotas(name).List(labels.Everything()) + resourceQuotaList, err := d.ResourceQuotas(name).List(labels.Everything(), fields.Everything()) if err != nil { return "", err } - limitRangeList, err := d.LimitRanges(name).List(labels.Everything()) + limitRangeList, err := d.LimitRanges(name).List(labels.Everything(), fields.Everything()) if err != nil { return "", err } @@ -467,14 +473,18 @@ func describePod(pod *api.Pod, rcs []api.ReplicationController, events *api.Even fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(pod.Labels)) if pod.DeletionTimestamp != nil { fmt.Fprintf(out, "Status:\tTerminating (expires %s)\n", pod.DeletionTimestamp.Time.Format(time.RFC1123Z)) - fmt.Fprintf(out, "Termination Grace Period:\t%ds\n", pod.DeletionGracePeriodSeconds) + fmt.Fprintf(out, "Termination Grace Period:\t%ds\n", *pod.DeletionGracePeriodSeconds) } else { fmt.Fprintf(out, "Status:\t%s\n", string(pod.Status.Phase)) } fmt.Fprintf(out, "Reason:\t%s\n", pod.Status.Reason) fmt.Fprintf(out, "Message:\t%s\n", pod.Status.Message) fmt.Fprintf(out, "IP:\t%s\n", pod.Status.PodIP) - fmt.Fprintf(out, "Replication Controllers:\t%s\n", printReplicationControllersByLabels(rcs)) + var matchingRCs []*api.ReplicationController + for _, rc := range rcs { + matchingRCs = append(matchingRCs, &rc) + } + fmt.Fprintf(out, "Replication Controllers:\t%s\n", printReplicationControllersByLabels(matchingRCs)) fmt.Fprintf(out, "Containers:\n") describeContainers(pod, out) if len(pod.Status.Conditions) > 0 { @@ -821,7 +831,7 @@ func (d *ReplicationControllerDescriber) Describe(namespace, name string) (strin return "", err } - running, waiting, succeeded, failed, err := getPodStatusForReplicationController(pc, controller) + running, waiting, succeeded, failed, err := getPodStatusForController(pc, controller.Spec.Selector) if err != nil { return "", err } @@ -854,6 +864,86 @@ func describeReplicationController(controller *api.ReplicationController, events }) } +// JobDescriber generates information about a job and the pods it has created. +type JobDescriber struct { + client *client.Client +} + +func (d *JobDescriber) Describe(namespace, name string) (string, error) { + job, err := d.client.Extensions().Jobs(namespace).Get(name) + if err != nil { + return "", err + } + + events, _ := d.client.Events(namespace).Search(job) + + return describeJob(job, events) +} + +func describeJob(job *extensions.Job, events *api.EventList) (string, error) { + return tabbedString(func(out io.Writer) error { + fmt.Fprintf(out, "Name:\t%s\n", job.Name) + fmt.Fprintf(out, "Namespace:\t%s\n", job.Namespace) + fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(&job.Spec.Template.Spec)) + fmt.Fprintf(out, "Selector:\t%s\n", labels.FormatLabels(job.Spec.Selector)) + fmt.Fprintf(out, "Parallelism:\t%d\n", *job.Spec.Parallelism) + fmt.Fprintf(out, "Completions:\t%d\n", *job.Spec.Completions) + fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(job.Labels)) + fmt.Fprintf(out, "Pods Statuses:\t%d Running / %d Succeeded / %d Failed\n", job.Status.Active, job.Status.Succeeded, job.Status.Failed) + describeVolumes(job.Spec.Template.Spec.Volumes, out) + if events != nil { + DescribeEvents(events, out) + } + return nil + }) +} + +// DaemonSetDescriber generates information about a daemon set and the pods it has created. +type DaemonSetDescriber struct { + client.Interface +} + +func (d *DaemonSetDescriber) Describe(namespace, name string) (string, error) { + dc := d.Extensions().DaemonSets(namespace) + pc := d.Pods(namespace) + + daemon, err := dc.Get(name) + if err != nil { + return "", err + } + + running, waiting, succeeded, failed, err := getPodStatusForController(pc, daemon.Spec.Selector) + if err != nil { + return "", err + } + + events, _ := d.Events(namespace).Search(daemon) + + return describeDaemonSet(daemon, events, running, waiting, succeeded, failed) +} + +func describeDaemonSet(daemon *extensions.DaemonSet, events *api.EventList, running, waiting, succeeded, failed int) (string, error) { + return tabbedString(func(out io.Writer) error { + fmt.Fprintf(out, "Name:\t%s\n", daemon.Name) + if daemon.Spec.Template != nil { + fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(&daemon.Spec.Template.Spec)) + } else { + fmt.Fprintf(out, "Image(s):\t%s\n", "") + } + fmt.Fprintf(out, "Selector:\t%s\n", labels.FormatLabels(daemon.Spec.Selector)) + fmt.Fprintf(out, "Node-Selector:\t%s\n", labels.FormatLabels(daemon.Spec.Template.Spec.NodeSelector)) + fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(daemon.Labels)) + fmt.Fprintf(out, "Desired Number of Nodes Scheduled: %d\n", daemon.Status.DesiredNumberScheduled) + fmt.Fprintf(out, "Current Number of Nodes Scheduled: %d\n", daemon.Status.CurrentNumberScheduled) + fmt.Fprintf(out, "Number of Nodes Misscheduled: %d\n", daemon.Status.NumberMisscheduled) + fmt.Fprintf(out, "Pods Status:\t%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed) + if events != nil { + DescribeEvents(events, out) + } + return nil + }) +} + // SecretDescriber generates information about a secret type SecretDescriber struct { client.Interface @@ -882,8 +972,7 @@ func describeSecret(secret *api.Secret) (string, error) { fmt.Fprintf(out, "\nData\n====\n") for k, v := range secret.Data { switch { - case k == api.ServiceAccountTokenKey && secret.Type == api.SecretTypeServiceAccountToken, - k == api.DockerConfigKey && secret.Type == api.SecretTypeDockercfg: + case k == api.ServiceAccountTokenKey && secret.Type == api.SecretTypeServiceAccountToken: fmt.Fprintf(out, "%s:\t%s\n", k, string(v)) default: fmt.Fprintf(out, "%s:\t%d bytes\n", k, len(v)) @@ -1146,7 +1235,7 @@ type HorizontalPodAutoscalerDescriber struct { } func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string) (string, error) { - hpa, err := d.client.Experimental().HorizontalPodAutoscalers(namespace).Get(name) + hpa, err := d.client.Extensions().HorizontalPodAutoscalers(namespace).Get(name) if err != nil { return "", err } @@ -1165,15 +1254,15 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string) (str hpa.Spec.Target.Resource) fmt.Fprintf(out, "Current resource consumption:\t") - if hpa.Status != nil && hpa.Status.CurrentConsumption != nil { + if hpa.Status.CurrentConsumption != nil { fmt.Fprintf(out, "%s %s\n", hpa.Status.CurrentConsumption.Quantity.String(), hpa.Status.CurrentConsumption.Resource) } else { fmt.Fprintf(out, "\n") } - fmt.Fprintf(out, "Min pods:\t%d\n", hpa.Spec.MinCount) - fmt.Fprintf(out, "Max pods:\t%d\n", hpa.Spec.MaxCount) + fmt.Fprintf(out, "Min pods:\t%d\n", hpa.Spec.MinReplicas) + fmt.Fprintf(out, "Max pods:\t%d\n", hpa.Spec.MaxReplicas) // TODO: switch to scale subresource once the required code is submitted. if strings.ToLower(hpa.Spec.ScaleRef.Kind) == "replicationcontroller" { @@ -1306,6 +1395,72 @@ func DescribeEvents(el *api.EventList, w io.Writer) { } } +// DeploymentDescriber generates information about a deployment. +type DeploymentDescriber struct { + client.Interface +} + +func (dd *DeploymentDescriber) Describe(namespace, name string) (string, error) { + d, err := dd.Extensions().Deployments(namespace).Get(name) + if err != nil { + return "", err + } + return tabbedString(func(out io.Writer) error { + fmt.Fprintf(out, "Name:\t%s\n", d.ObjectMeta.Name) + fmt.Fprintf(out, "Namespace:\t%s\n", d.ObjectMeta.Namespace) + fmt.Fprintf(out, "CreationTimestamp:\t%s\n", d.CreationTimestamp.Time.Format(time.RFC1123Z)) + fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(d.Labels)) + fmt.Fprintf(out, "Selector:\t%s\n", labels.FormatLabels(d.Spec.Selector)) + fmt.Fprintf(out, "Replicas:\t%d updated / %d total\n", d.Status.UpdatedReplicas, d.Spec.Replicas) + fmt.Fprintf(out, "StrategyType:\t%s\n", d.Spec.Strategy.Type) + if d.Spec.Strategy.RollingUpdate != nil { + ru := d.Spec.Strategy.RollingUpdate + fmt.Fprintf(out, "RollingUpdateStrategy:\t%s max unavailable, %s max surge, %d min ready seconds\n", ru.MaxUnavailable.String(), ru.MaxSurge.String(), ru.MinReadySeconds) + } + oldRCs, err := deploymentUtil.GetOldRCs(*d, dd) + if err == nil { + fmt.Fprintf(out, "OldReplicationControllers:\t%s\n", printReplicationControllersByLabels(oldRCs)) + } + newRC, err := deploymentUtil.GetNewRC(*d, dd) + if err == nil { + var newRCs []*api.ReplicationController + if newRC != nil { + newRCs = append(newRCs, newRC) + } + fmt.Fprintf(out, "NewReplicationController:\t%s\n", printReplicationControllersByLabels(newRCs)) + } + events, err := dd.Events(namespace).Search(d) + if err == nil && events != nil { + DescribeEvents(events, out) + } + return nil + }) +} + +// Get all daemon set whose selectors would match a given set of labels. +// TODO: Move this to pkg/client and ideally implement it server-side (instead +// of getting all DS's and searching through them manually). +// TODO: write an interface for controllers and fuse getReplicationControllersForLabels +// and getDaemonSetsForLabels. +func getDaemonSetsForLabels(c client.DaemonSetInterface, labelsToMatch labels.Labels) ([]extensions.DaemonSet, error) { + // Get all daemon sets + // TODO: this needs a namespace scope as argument + dss, err := c.List(labels.Everything(), fields.Everything()) + if err != nil { + return nil, fmt.Errorf("error getting daemon set: %v", err) + } + + // Find the ones that match labelsToMatch. + var matchingDaemonSets []extensions.DaemonSet + for _, ds := range dss.Items { + selector := labels.SelectorFromSet(ds.Spec.Selector) + if selector.Matches(labelsToMatch) { + matchingDaemonSets = append(matchingDaemonSets, ds) + } + } + return matchingDaemonSets, nil +} + // Get all replication controllers whose selectors would match a given set of // labels. // TODO Move this to pkg/client and ideally implement it server-side (instead @@ -1313,7 +1468,7 @@ func DescribeEvents(el *api.EventList, w io.Writer) { func getReplicationControllersForLabels(c client.ReplicationControllerInterface, labelsToMatch labels.Labels) ([]api.ReplicationController, error) { // Get all replication controllers. // TODO this needs a namespace scope as argument - rcs, err := c.List(labels.Everything()) + rcs, err := c.List(labels.Everything(), fields.Everything()) if err != nil { return nil, fmt.Errorf("error getting replication controllers: %v", err) } @@ -1329,7 +1484,7 @@ func getReplicationControllersForLabels(c client.ReplicationControllerInterface, return matchingRCs, nil } -func printReplicationControllersByLabels(matchingRCs []api.ReplicationController) string { +func printReplicationControllersByLabels(matchingRCs []*api.ReplicationController) string { // Format the matching RC's into strings. var rcStrings []string for _, controller := range matchingRCs { @@ -1343,8 +1498,8 @@ func printReplicationControllersByLabels(matchingRCs []api.ReplicationController return list } -func getPodStatusForReplicationController(c client.PodInterface, controller *api.ReplicationController) (running, waiting, succeeded, failed int, err error) { - rcPods, err := c.List(labels.SelectorFromSet(controller.Spec.Selector), fields.Everything()) +func getPodStatusForController(c client.PodInterface, selector map[string]string) (running, waiting, succeeded, failed int, err error) { + rcPods, err := c.List(labels.SelectorFromSet(selector), fields.Everything()) if err != nil { return } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe_test.go index 131bb7f2e2d0..01476ec71f88 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe_test.go @@ -26,9 +26,10 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/testclient" - "k8s.io/kubernetes/pkg/util" ) type describeClient struct { @@ -85,22 +86,22 @@ func TestPodDescribeResultsSorted(t *testing.T) { { Source: api.EventSource{Component: "kubelet"}, Message: "Item 1", - FirstTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), - LastTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + FirstTimestamp: unversioned.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + LastTimestamp: unversioned.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "scheduler"}, Message: "Item 2", - FirstTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), - LastTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + FirstTimestamp: unversioned.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + LastTimestamp: unversioned.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "kubelet"}, Message: "Item 3", - FirstTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), - LastTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + FirstTimestamp: unversioned.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + LastTimestamp: unversioned.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), Count: 1, }, }, @@ -131,7 +132,7 @@ func TestDescribeContainers(t *testing.T) { Name: "test", State: api.ContainerState{ Running: &api.ContainerStateRunning{ - StartedAt: util.NewTime(time.Now()), + StartedAt: unversioned.NewTime(time.Now()), }, }, Ready: true, @@ -161,8 +162,8 @@ func TestDescribeContainers(t *testing.T) { Name: "test", State: api.ContainerState{ Terminated: &api.ContainerStateTerminated{ - StartedAt: util.NewTime(time.Now()), - FinishedAt: util.NewTime(time.Now()), + StartedAt: unversioned.NewTime(time.Now()), + FinishedAt: unversioned.NewTime(time.Now()), Reason: "potato", ExitCode: 2, }, @@ -179,13 +180,13 @@ func TestDescribeContainers(t *testing.T) { Name: "test", State: api.ContainerState{ Running: &api.ContainerStateRunning{ - StartedAt: util.NewTime(time.Now()), + StartedAt: unversioned.NewTime(time.Now()), }, }, LastTerminationState: api.ContainerState{ Terminated: &api.ContainerStateTerminated{ - StartedAt: util.NewTime(time.Now().Add(time.Second * 3)), - FinishedAt: util.NewTime(time.Now()), + StartedAt: unversioned.NewTime(time.Now().Add(time.Second * 3)), + FinishedAt: unversioned.NewTime(time.Now()), Reason: "crashing", ExitCode: 3, }, @@ -476,6 +477,26 @@ func TestPersistentVolumeDescriber(t *testing.T) { if str == "" { t.Errorf("Unexpected empty string for test %s. Expected PV Describer output", name) } + } +} +func TestDescribeDeployment(t *testing.T) { + fake := testclient.NewSimpleFake(&extensions.Deployment{ + ObjectMeta: api.ObjectMeta{ + Name: "bar", + Namespace: "foo", + }, + Spec: extensions.DeploymentSpec{ + Template: &api.PodTemplateSpec{}, + }, + }) + c := &describeClient{T: t, Namespace: "foo", Interface: fake} + d := DeploymentDescriber{c} + out, err := d.Describe("foo", "bar") + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if !strings.Contains(out, "bar") || !strings.Contains(out, "foo") { + t.Errorf("unexpected out: %s", out) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/explain.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/explain.go new file mode 100644 index 000000000000..087c217c55d0 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/explain.go @@ -0,0 +1,260 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 kubectl + +import ( + "fmt" + "io" + "strings" + + "github.com/emicklei/go-restful/swagger" + + "k8s.io/kubernetes/pkg/api/meta" + client "k8s.io/kubernetes/pkg/client/unversioned" +) + +var allModels = make(map[string]*swagger.NamedModel) +var recursive = false // this is global for convenience, can become int for multiple levels + +// GetSwaggerSchema returns the swagger spec from master +func GetSwaggerSchema(apiVer string, kubeClient client.Interface) (*swagger.ApiDeclaration, error) { + swaggerSchema, err := kubeClient.SwaggerSchema(apiVer) + if err != nil { + return nil, fmt.Errorf("couldn't read swagger schema from server: %v", err) + } + return swaggerSchema, nil +} + +// SplitAndParseResourceRequest separates the users input into a model and fields +func SplitAndParseResourceRequest(inResource string, mapper meta.RESTMapper) (string, []string, error) { + inResource, fieldsPath := splitDotNotation(inResource) + inResource, _ = mapper.ResourceSingularizer(expandResourceShortcut(inResource)) + return inResource, fieldsPath, nil +} + +// PrintModelDescription prints the description of a specific model or dot path +func PrintModelDescription(inModel string, fieldsPath []string, w io.Writer, swaggerSchema *swagger.ApiDeclaration, r bool) error { + recursive = r // this is global for convenience + apiVer := swaggerSchema.ApiVersion + "." + + var pointedModel *swagger.NamedModel + for i := range swaggerSchema.Models.List { + name := swaggerSchema.Models.List[i].Name + + allModels[name] = &swaggerSchema.Models.List[i] + if strings.ToLower(name) == strings.ToLower(apiVer+inModel) { + pointedModel = &swaggerSchema.Models.List[i] + } + } + if pointedModel == nil { + return fmt.Errorf("Requested resourse: %s doesn't exit", inModel) + } + + if len(fieldsPath) == 0 { + return printTopLevelResourceInfo(w, pointedModel) + } + + var pointedModelAsProp *swagger.NamedModelProperty + for _, field := range fieldsPath { + if prop, nextModel, isModel := getField(pointedModel, field); prop != nil { + if isModel { + pointedModelAsProp = prop + pointedModel = allModels[nextModel] + } else { + return printPrimitive(w, prop) + } + } else { + return fmt.Errorf("field: %s doesn't exist", field) + } + } + return printModelInfo(w, pointedModel, pointedModelAsProp) +} + +func splitDotNotation(model string) (string, []string) { + var fieldsPath []string + dotModel := strings.Split(model, ".") + if len(dotModel) >= 1 { + fieldsPath = dotModel[1:] + } + return dotModel[0], fieldsPath +} + +func getPointedModel(prop *swagger.ModelProperty) (string, bool) { + if prop.Ref != nil { + return *prop.Ref, true + } else if *prop.Type == "array" && prop.Items.Ref != nil { + return *prop.Items.Ref, true + } + return "", false +} + +func getField(model *swagger.NamedModel, sField string) (*swagger.NamedModelProperty, string, bool) { + for _, prop := range model.Model.Properties.List { + if prop.Name == sField { + pointedModel, isModel := getPointedModel(&prop.Property) + return &prop, pointedModel, isModel + } + } + return nil, "", false +} + +func printModelInfo(w io.Writer, model *swagger.NamedModel, modelProp *swagger.NamedModelProperty) error { + t, _ := getFieldType(&modelProp.Property) + fmt.Fprintf(w, "RESOURCE: %s <%s>\n\n", modelProp.Name, t) + fieldDesc, _ := wrapAndIndentText(modelProp.Property.Description, " ", 80) + fmt.Fprintf(w, "DESCRIPTION:\n%s\n\n%s\n", fieldDesc, indentText(model.Model.Description, " ")) + return printFields(w, model) +} + +func printPrimitive(w io.Writer, field *swagger.NamedModelProperty) error { + t, _ := getFieldType(&field.Property) + fmt.Fprintf(w, "FIELD: %s <%s>\n\n", field.Name, t) + d, _ := wrapAndIndentText(field.Property.Description, " ", 80) + fmt.Fprintf(w, "DESCRIPTION:\n%s\n", d) + return nil +} + +func printTopLevelResourceInfo(w io.Writer, model *swagger.NamedModel) error { + fmt.Fprintf(w, "DESCRIPTION:\n%s\n", model.Model.Description) + return printFields(w, model) +} + +func printFields(w io.Writer, model *swagger.NamedModel) error { + fmt.Fprint(w, "\nFIELDS:\n") + for _, field := range model.Model.Properties.List { + fieldType, err := getFieldType(&field.Property) + if err != nil { + return err + } + + if arrayContains(model.Model.Required, field.Name) { + fmt.Fprintf(w, " %s\t<%s> -required-\n", field.Name, fieldType) + } else { + fmt.Fprintf(w, " %s\t<%s>\n", field.Name, fieldType) + } + + if recursive { + pointedModel, isModel := getPointedModel(&field.Property) + if isModel { + for _, nestedField := range allModels[pointedModel].Model.Properties.List { + t, _ := getFieldType(&nestedField.Property) + fmt.Fprintf(w, " %s\t<%s>\n", nestedField.Name, t) + } + } + } else { + fieldDesc, _ := wrapAndIndentText(field.Property.Description, " ", 80) + fmt.Fprintf(w, "%s\n\n", fieldDesc) + } + } + fmt.Fprint(w, "\n") + return nil +} + +func getFieldType(prop *swagger.ModelProperty) (string, error) { + if prop.Type == nil { + return "Object", nil + } else if *prop.Type == "any" { + // Swagger Spec doesn't return information for maps. + return "map[string]string", nil + } else if *prop.Type == "array" { + if prop.Items == nil { + return "", fmt.Errorf("error in swagger spec. Property: %v contains an array without type", prop) + } + if prop.Items.Ref != nil { + fieldType := "[]Object" + return fieldType, nil + } + fieldType := "[]" + *prop.Items.Type + return fieldType, nil + } + return *prop.Type, nil +} + +func wrapAndIndentText(desc, indent string, lim int) (string, error) { + words := strings.Split(strings.Replace(strings.TrimSpace(desc), "\n", " ", -1), " ") + n := len(words) + + for i := 0; i < n; i++ { + if len(words[i]) > lim { + if strings.Contains(words[i], "/") { + s := breakURL(words[i]) + words = append(words[:i], append(s, words[i+1:]...)...) + i = i + len(s) - 1 + } else { + fmt.Println(len(words[i])) + return "", fmt.Errorf("there are words longer that the break limit is") + } + } + } + + var lines []string + line := []string{indent} + lineL := len(indent) + for i := 0; i < len(words); i++ { + w := words[i] + + if strings.HasSuffix(w, "/") && lineL+len(w)-1 < lim { + prev := line[len(line)-1] + if strings.HasSuffix(prev, "/") { + if i+1 < len(words)-1 && !strings.HasSuffix(words[i+1], "/") { + w = strings.TrimSuffix(w, "/") + } + + line[len(line)-1] = prev + w + lineL += len(w) + } else { + line = append(line, w) + lineL += len(w) + 1 + } + } else if lineL+len(w) < lim { + line = append(line, w) + lineL += len(w) + 1 + } else { + lines = append(lines, strings.Join(line, " ")) + line = []string{indent, w} + lineL = len(indent) + len(w) + } + } + lines = append(lines, strings.Join(line, " ")) + + return strings.Join(lines, "\n"), nil +} + +func breakURL(url string) []string { + var buf []string + for _, part := range strings.Split(url, "/") { + buf = append(buf, part+"/") + } + return buf +} + +func indentText(text, indent string) string { + lines := strings.Split(text, "\n") + for i := range lines { + lines[i] = indent + lines[i] + } + return strings.Join(lines, "\n") +} + +func arrayContains(s []string, e string) bool { + for _, a := range s { + if a == e { + return true + } + } + return false +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/kubectl.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/kubectl.go index e3a1c1fd6b50..691866ec6687 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/kubectl.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/kubectl.go @@ -18,7 +18,6 @@ limitations under the License. package kubectl import ( - "fmt" "strings" "k8s.io/kubernetes/pkg/api" @@ -80,13 +79,15 @@ type ShortcutExpander struct { func (e ShortcutExpander) VersionAndKindForResource(resource string) (defaultVersion, kind string, err error) { resource = expandResourceShortcut(resource) defaultVersion, kind, err = e.RESTMapper.VersionAndKindForResource(resource) - // TODO: remove this once v1beta1 and v1beta2 are deprecated - if err == nil && kind == "Minion" { - err = fmt.Errorf("Alias minion(s) is deprecated. Use node(s) instead") - } return defaultVersion, kind, err } +// ResourceIsValid takes a string (kind) and checks if it's a valid resource. +// It expands the resource first, then invokes the wrapped mapper. +func (e ShortcutExpander) ResourceIsValid(resource string) bool { + return e.RESTMapper.ResourceIsValid(expandResourceShortcut(resource)) +} + // expandResourceShortcut will return the expanded version of resource // (something that a pkg/api/meta.RESTMapper can understand), if it is // indeed a shortcut. Otherwise, will return resource unmodified. @@ -105,8 +106,9 @@ func expandResourceShortcut(resource string) string { "pvc": "persistentvolumeclaims", "quota": "resourcequotas", "rc": "replicationcontrollers", + "ds": "daemonsets", "svc": "services", - "scc": "securityContextConstraints", + "ing": "ingress", } if expanded, ok := shortForms[resource]; ok { return expanded diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/proxy_server.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/proxy_server.go index 31343e1c6348..bfbb9b6a0e3e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/proxy_server.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/proxy_server.go @@ -179,8 +179,8 @@ func NewProxyServer(filebase string, apiProxyPrefix string, staticPrefix string, } // Listen is a simple wrapper around net.Listen. -func (s *ProxyServer) Listen(port int) (net.Listener, error) { - return net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) +func (s *ProxyServer) Listen(address string, port int) (net.Listener, error) { + return net.Listen("tcp", fmt.Sprintf("%s:%d", address, port)) } // ListenUnix does net.Listen for a unix socket diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/builder.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/builder.go index 9da9c106666d..265626a65079 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/builder.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/builder.go @@ -186,12 +186,12 @@ func (b *Builder) ResourceTypes(types ...string) *Builder { return b } -// ResourceNames accepts a default type and one or more names, and creates tuples of +// ResourceNames accepts a default type or group/type and one or more names, and creates tuples of // resources func (b *Builder) ResourceNames(resource string, names ...string) *Builder { for _, name := range names { - // See if this input string is of type/name format - tuple, ok, err := splitResourceTypeName(name) + // See if this input string is of type/name or group/type/name format + tuple, ok, err := splitGroupResourceTypeName(name) if err != nil { b.errs = append(b.errs, err) return b @@ -274,12 +274,47 @@ func (b *Builder) SelectAllParam(selectAll bool) *Builder { return b } -// ResourceTypeOrNameArgs indicates that the builder should accept arguments -// of the form `([,,...]| [,,...])`. When one argument is -// received, the types provided will be retrieved from the server (and be comma delimited). -// When two or more arguments are received, they must be a single type and resource name(s). +func (b *Builder) hasNamesArg(args []string) bool { + if len(args) > 1 { + return true + } + if len(args) != 1 { + return false + } + // the first (and the only) arg could be (type[,group/type]), type/name, or group/type/name + s := args[0] + // type or group/type (no name) + if strings.Contains(s, ",") { + return false + } + // type (no name) + if !strings.Contains(s, "/") { + return false + } + // group/type/name, type/name or group/type + tuple := strings.Split(s, "/") + if len(tuple) != 3 && !b.mapper.ResourceIsValid(tuple[0]) { + // TODO: prints warning/error message here when tuple[0] may be resource or group (name duplication)? + return false + } + return true +} + +func getResource(groupResource string) string { + if strings.Contains(groupResource, "/") { + return strings.Split(groupResource, "/")[1] + } + return groupResource +} + +// ResourceTypeOrNameArgs indicates that the builder should accept arguments of the form +// `([,,...] [[ ...]]|/ [/...]|)` +// When one argument is received, the types provided will be retrieved from the server (and be comma delimited). // The allowEmptySelector permits to select all the resources (via Everything func). +// = (/ | ) func (b *Builder) ResourceTypeOrNameArgs(allowEmptySelector bool, args ...string) *Builder { + hasNames := b.hasNamesArg(args) + // convert multiple resources to resource tuples, a,b,c d as a transform to a/d b/d c/d if len(args) >= 2 { resources := []string{} @@ -297,13 +332,13 @@ func (b *Builder) ResourceTypeOrNameArgs(allowEmptySelector bool, args ...string } } - if ok, err := hasCombinedTypeArgs(args); ok { + if ok, err := hasCombinedTypeArgs(args); ok && hasNames { if err != nil { b.errs = append(b.errs, err) return b } for _, s := range args { - tuple, ok, err := splitResourceTypeName(s) + tuple, ok, err := splitGroupResourceTypeName(s) if err != nil { b.errs = append(b.errs, err) return b @@ -342,7 +377,7 @@ func (b *Builder) ResourceTypeOrNameArgs(allowEmptySelector bool, args ...string func (b *Builder) replaceAliases(input string) string { replaced := []string{} for _, arg := range strings.Split(input, ",") { - if aliases, ok := b.mapper.AliasesForResource(arg); ok { + if aliases, ok := b.mapper.AliasesForResource(getResource(arg)); ok { arg = strings.Join(aliases, ",") } replaced = append(replaced, arg) @@ -360,13 +395,33 @@ func hasCombinedTypeArgs(args []string) (bool, error) { switch { case hasSlash > 0 && hasSlash == len(args): return true, nil - case hasSlash > 0 && hasSlash != len(args): - return true, fmt.Errorf("when passing arguments in resource/name form, all arguments must include the resource") default: return false, nil } } +// splitGroupResourceTypeName handles group/type/name resource formats and returns a resource tuple +// (empty or not), whether it successfully found one, and an error +func splitGroupResourceTypeName(s string) (resourceTuple, bool, error) { + if !strings.Contains(s, "/") { + return resourceTuple{}, false, nil + } + seg := strings.Split(s, "/") + if len(seg) != 2 && len(seg) != 3 { + return resourceTuple{}, false, fmt.Errorf("arguments in group/resource/name form may not have more than two slashes") + } + resource, name := "", "" + if len(seg) == 2 { + resource, name = seg[0], seg[1] + } else { + resource, name = fmt.Sprintf("%s/%s", seg[0], seg[1]), seg[2] + } + if len(resource) == 0 || len(name) == 0 || len(SplitResourceArgument(resource)) != 1 { + return resourceTuple{}, false, fmt.Errorf("arguments in group/resource/name form must have a single resource and name") + } + return resourceTuple{Resource: resource, Name: name}, true, nil +} + // splitResourceTypeName handles type/name resource formats and returns a resource tuple // (empty or not), whether it successfully found one, and an error func splitResourceTypeName(s string) (resourceTuple, bool, error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/builder_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/builder_test.go index 97322f3d5d11..a930aafe642a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/builder_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/builder_test.go @@ -29,11 +29,12 @@ import ( "github.com/ghodss/yaml" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/testapi" - client "k8s.io/kubernetes/pkg/client/unversioned" + apitesting "k8s.io/kubernetes/pkg/api/testing" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/watch" @@ -46,7 +47,7 @@ func stringBody(body string) io.ReadCloser { func watchBody(events ...watch.Event) string { buf := &bytes.Buffer{} - enc := watchjson.NewEncoder(buf, latest.Codec) + enc := watchjson.NewEncoder(buf, testapi.Default.Codec()) for _, e := range events { enc.Encode(&e) } @@ -55,15 +56,15 @@ func watchBody(events ...watch.Event) string { func fakeClient() ClientMapper { return ClientMapperFunc(func(*meta.RESTMapping) (RESTClient, error) { - return &client.FakeRESTClient{}, nil + return &fake.RESTClient{}, nil }) } func fakeClientWith(testName string, t *testing.T, data map[string]string) ClientMapper { return ClientMapperFunc(func(*meta.RESTMapping) (RESTClient, error) { - return &client.FakeRESTClient{ - Codec: latest.Codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + return &fake.RESTClient{ + Codec: testapi.Default.Codec(), + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { p := req.URL.Path q := req.URL.RawQuery if len(q) != 0 { @@ -83,32 +84,23 @@ func fakeClientWith(testName string, t *testing.T, data map[string]string) Clien } func testData() (*api.PodList, *api.ServiceList) { - grace := int64(30) pods := &api.PodList{ - ListMeta: api.ListMeta{ + ListMeta: unversioned.ListMeta{ ResourceVersion: "15", }, Items: []api.Pod{ { ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, }, } svc := &api.ServiceList{ - ListMeta: api.ListMeta{ + ListMeta: unversioned.ListMeta{ ResourceVersion: "16", }, Items: []api.Service{ @@ -129,8 +121,8 @@ func streamTestData() (io.Reader, *api.PodList, *api.ServiceList) { r, w := io.Pipe() go func() { defer w.Close() - w.Write([]byte(runtime.EncodeOrDie(latest.Codec, pods))) - w.Write([]byte(runtime.EncodeOrDie(latest.Codec, svc))) + w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), pods))) + w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), svc))) }() return r, pods, svc } @@ -148,9 +140,9 @@ func streamYAMLTestData() (io.Reader, *api.PodList, *api.ServiceList) { r, w := io.Pipe() go func() { defer w.Close() - w.Write(JSONToYAMLOrDie([]byte(runtime.EncodeOrDie(latest.Codec, pods)))) + w.Write(JSONToYAMLOrDie([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), pods)))) w.Write([]byte("\n---\n")) - w.Write(JSONToYAMLOrDie([]byte(runtime.EncodeOrDie(latest.Codec, svc)))) + w.Write(JSONToYAMLOrDie([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), svc)))) }() return r, pods, svc } @@ -159,7 +151,7 @@ func streamTestObject(obj runtime.Object) io.Reader { r, w := io.Pipe() go func() { defer w.Close() - w.Write([]byte(runtime.EncodeOrDie(latest.Codec, obj))) + w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), obj))) }() return r } @@ -186,7 +178,7 @@ func (v *testVisitor) Objects() []runtime.Object { } func TestPathBuilder(t *testing.T) { - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). FilenameParam(false, "../../../examples/guestbook/redis-master-controller.yaml") test := &testVisitor{} @@ -217,10 +209,10 @@ func TestNodeBuilder(t *testing.T) { r, w := io.Pipe() go func() { defer w.Close() - w.Write([]byte(runtime.EncodeOrDie(latest.Codec, node))) + w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), node))) }() - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). NamespaceParam("test").Stream(r, "STDIN") test := &testVisitor{} @@ -236,7 +228,7 @@ func TestNodeBuilder(t *testing.T) { } func TestPathBuilderWithMultiple(t *testing.T) { - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). FilenameParam(false, "../../../examples/guestbook/redis-master-controller.yaml"). FilenameParam(false, "../../../examples/pod"). NamespaceParam("test").DefaultNamespace() @@ -260,7 +252,7 @@ func TestPathBuilderWithMultiple(t *testing.T) { } func TestDirectoryBuilder(t *testing.T) { - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). FilenameParam(false, "../../../examples/guestbook"). NamespaceParam("test").DefaultNamespace() @@ -286,11 +278,11 @@ func TestDirectoryBuilder(t *testing.T) { func TestNamespaceOverride(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusOK) - w.Write([]byte(runtime.EncodeOrDie(latest.Codec, &api.Pod{ObjectMeta: api.ObjectMeta{Namespace: "foo", Name: "test"}}))) + w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Namespace: "foo", Name: "test"}}))) })) defer s.Close() - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). FilenameParam(false, s.URL). NamespaceParam("test") @@ -301,7 +293,7 @@ func TestNamespaceOverride(t *testing.T) { t.Fatalf("unexpected response: %v %#v", err, test.Infos) } - b = NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b = NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). FilenameParam(true, s.URL). NamespaceParam("test") @@ -316,11 +308,11 @@ func TestNamespaceOverride(t *testing.T) { func TestURLBuilder(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusOK) - w.Write([]byte(runtime.EncodeOrDie(latest.Codec, &api.Pod{ObjectMeta: api.ObjectMeta{Namespace: "foo", Name: "test"}}))) + w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Namespace: "foo", Name: "test"}}))) })) defer s.Close() - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). FilenameParam(false, s.URL). NamespaceParam("test") @@ -340,11 +332,11 @@ func TestURLBuilder(t *testing.T) { func TestURLBuilderRequireNamespace(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusOK) - w.Write([]byte(runtime.EncodeOrDie(latest.Codec, &api.Pod{ObjectMeta: api.ObjectMeta{Namespace: "foo", Name: "test"}}))) + w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Namespace: "foo", Name: "test"}}))) })) defer s.Close() - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). FilenameParam(false, s.URL). NamespaceParam("test").RequireNamespace() @@ -359,8 +351,8 @@ func TestURLBuilderRequireNamespace(t *testing.T) { func TestResourceByName(t *testing.T) { pods, _ := testData() - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith("", t, map[string]string{ - "/namespaces/test/pods/foo": runtime.EncodeOrDie(latest.Codec, &pods.Items[0]), + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), })). NamespaceParam("test") @@ -392,11 +384,11 @@ func TestResourceByName(t *testing.T) { func TestMultipleResourceByTheSameName(t *testing.T) { pods, svcs := testData() - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith("", t, map[string]string{ - "/namespaces/test/pods/foo": runtime.EncodeOrDie(latest.Codec, &pods.Items[0]), - "/namespaces/test/pods/baz": runtime.EncodeOrDie(latest.Codec, &pods.Items[1]), - "/namespaces/test/services/foo": runtime.EncodeOrDie(latest.Codec, &svcs.Items[0]), - "/namespaces/test/services/baz": runtime.EncodeOrDie(latest.Codec, &svcs.Items[0]), + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), + "/namespaces/test/pods/baz": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[1]), + "/namespaces/test/services/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &svcs.Items[0]), + "/namespaces/test/services/baz": runtime.EncodeOrDie(testapi.Default.Codec(), &svcs.Items[0]), })). NamespaceParam("test") @@ -424,9 +416,9 @@ func TestMultipleResourceByTheSameName(t *testing.T) { func TestResourceNames(t *testing.T) { pods, svc := testData() - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith("", t, map[string]string{ - "/namespaces/test/pods/foo": runtime.EncodeOrDie(latest.Codec, &pods.Items[0]), - "/namespaces/test/services/baz": runtime.EncodeOrDie(latest.Codec, &svc.Items[0]), + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), + "/namespaces/test/services/baz": runtime.EncodeOrDie(testapi.Default.Codec(), &svc.Items[0]), })). NamespaceParam("test") @@ -451,7 +443,7 @@ func TestResourceNames(t *testing.T) { } func TestResourceByNameWithoutRequireObject(t *testing.T) { - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith("", t, map[string]string{})). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{})). NamespaceParam("test") test := &testVisitor{} @@ -485,8 +477,8 @@ func TestResourceByNameWithoutRequireObject(t *testing.T) { func TestResourceByNameAndEmptySelector(t *testing.T) { pods, _ := testData() - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith("", t, map[string]string{ - "/namespaces/test/pods/foo": runtime.EncodeOrDie(latest.Codec, &pods.Items[0]), + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), })). NamespaceParam("test"). SelectorParam(""). @@ -512,10 +504,10 @@ func TestResourceByNameAndEmptySelector(t *testing.T) { func TestSelector(t *testing.T) { pods, svc := testData() - labelKey := api.LabelSelectorQueryParam(testapi.Default.Version()) - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith("", t, map[string]string{ - "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(latest.Codec, pods), - "/namespaces/test/services?" + labelKey + "=a%3Db": runtime.EncodeOrDie(latest.Codec, svc), + labelKey := unversioned.LabelSelectorQueryParam(testapi.Default.Version()) + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), pods), + "/namespaces/test/services?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), svc), })). SelectorParam("a=b"). NamespaceParam("test"). @@ -544,7 +536,7 @@ func TestSelector(t *testing.T) { } func TestSelectorRequiresKnownTypes(t *testing.T) { - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). SelectorParam("a=b"). NamespaceParam("test"). ResourceTypes("unknown") @@ -555,7 +547,7 @@ func TestSelectorRequiresKnownTypes(t *testing.T) { } func TestSingleResourceType(t *testing.T) { - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). SelectorParam("a=b"). SingleResourceType(). ResourceTypeOrNameArgs(true, "pods,services") @@ -565,6 +557,112 @@ func TestSingleResourceType(t *testing.T) { } } +func TestHasNamesArg(t *testing.T) { + testCases := map[string]struct { + args []string + expected bool + }{ + "resource/name": { + args: []string{"pods/foo"}, + expected: true, + }, + "resource name": { + args: []string{"pods", "foo"}, + expected: true, + }, + "resource1,resource2 name": { + args: []string{"pods,rc", "foo"}, + expected: true, + }, + "resource1,group2/resource2 name": { + args: []string{"pods,experimental/deployments", "foo"}, + expected: true, + }, + "group/resource name": { + args: []string{"experimental/deployments", "foo"}, + expected: true, + }, + "group/resource/name": { + args: []string{"experimental/deployments/foo"}, + expected: true, + }, + "group1/resource1,group2/resource2": { + args: []string{"experimental/daemonsets,experimental/deployments"}, + expected: false, + }, + "resource1,group2/resource2": { + args: []string{"pods,experimental/deployments"}, + expected: false, + }, + "group/resource/name,group2/resource2": { + args: []string{"experimental/deployments/foo,controller/deamonset"}, + expected: false, + }, + } + for k, testCase := range testCases { + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()) + if testCase.expected != b.hasNamesArg(testCase.args) { + t.Errorf("%s: unexpected argument - expected: %v", k, testCase.expected) + } + } +} + +func TestSplitGroupResourceTypeName(t *testing.T) { + expectNoErr := func(err error) bool { return err == nil } + expectErr := func(err error) bool { return err != nil } + testCases := map[string]struct { + arg string + expectedTuple resourceTuple + expectedOK bool + errFn func(error) bool + }{ + "group/type/name": { + arg: "experimental/deployments/foo", + expectedTuple: resourceTuple{Resource: "experimental/deployments", Name: "foo"}, + expectedOK: true, + errFn: expectNoErr, + }, + "type/name": { + arg: "pods/foo", + expectedTuple: resourceTuple{Resource: "pods", Name: "foo"}, + expectedOK: true, + errFn: expectNoErr, + }, + "type": { + arg: "pods", + expectedOK: false, + errFn: expectNoErr, + }, + "": { + arg: "", + expectedOK: false, + errFn: expectNoErr, + }, + "/": { + arg: "/", + expectedOK: false, + errFn: expectErr, + }, + "group/type/name/something": { + arg: "experimental/deployments/foo/something", + expectedOK: false, + errFn: expectErr, + }, + } + for k, testCase := range testCases { + tuple, ok, err := splitGroupResourceTypeName(testCase.arg) + if !testCase.errFn(err) { + t.Errorf("%s: unexpected error: %v", k, err) + } + if ok != testCase.expectedOK { + t.Errorf("%s: unexpected ok: %v", k, ok) + } + if testCase.expectedOK && !reflect.DeepEqual(tuple, testCase.expectedTuple) { + t.Errorf("%s: unexpected tuple - expected: %v, got: %v", k, testCase.expectedTuple, tuple) + } + } +} + func TestResourceTuple(t *testing.T) { expectNoErr := func(err error) bool { return err == nil } expectErr := func(err error) bool { return err != nil } @@ -581,7 +679,7 @@ func TestResourceTuple(t *testing.T) { errFn: expectNoErr, }, "valid multiple with namespaced and non-namespaced types": { - args: []string{"minions/foo", "pod/bar"}, + args: []string{"nodes/foo", "pod/bar"}, errFn: expectNoErr, }, "mixed arg types": { @@ -619,14 +717,13 @@ func TestResourceTuple(t *testing.T) { if requireObject { pods, _ := testData() expectedRequests = map[string]string{ - "/namespaces/test/pods/foo": runtime.EncodeOrDie(latest.Codec, &pods.Items[0]), - "/namespaces/test/pods/bar": runtime.EncodeOrDie(latest.Codec, &pods.Items[0]), - "/nodes/foo": runtime.EncodeOrDie(latest.Codec, &api.Node{ObjectMeta: api.ObjectMeta{Name: "foo"}}), - "/minions/foo": runtime.EncodeOrDie(latest.Codec, &api.Node{ObjectMeta: api.ObjectMeta{Name: "foo"}}), + "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), + "/namespaces/test/pods/bar": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), + "/nodes/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &api.Node{ObjectMeta: api.ObjectMeta{Name: "foo"}}), } } - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith(k, t, expectedRequests)). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith(k, t, expectedRequests)). NamespaceParam("test").DefaultNamespace(). ResourceTypeOrNameArgs(true, testCase.args...).RequireObject(requireObject) @@ -657,7 +754,7 @@ func TestResourceTuple(t *testing.T) { func TestStream(t *testing.T) { r, pods, rc := streamTestData() - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). NamespaceParam("test").Stream(r, "STDIN").Flatten() test := &testVisitor{} @@ -674,7 +771,7 @@ func TestStream(t *testing.T) { func TestYAMLStream(t *testing.T) { r, pods, rc := streamYAMLTestData() - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). NamespaceParam("test").Stream(r, "STDIN").Flatten() test := &testVisitor{} @@ -691,7 +788,7 @@ func TestYAMLStream(t *testing.T) { func TestMultipleObject(t *testing.T) { r, pods, svc := streamTestData() - obj, err := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + obj, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). NamespaceParam("test").Stream(r, "STDIN").Flatten(). Do().Object() @@ -713,7 +810,7 @@ func TestMultipleObject(t *testing.T) { func TestContinueOnErrorVisitor(t *testing.T) { r, _, _ := streamTestData() - req := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + req := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). ContinueOnError(). NamespaceParam("test").Stream(r, "STDIN").Flatten(). Do() @@ -742,7 +839,7 @@ func TestContinueOnErrorVisitor(t *testing.T) { } func TestSingularObject(t *testing.T) { - obj, err := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + obj, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). NamespaceParam("test").DefaultNamespace(). FilenameParam(false, "../../../examples/guestbook/redis-master-controller.yaml"). Flatten(). @@ -762,7 +859,7 @@ func TestSingularObject(t *testing.T) { } func TestSingularObjectNoExtension(t *testing.T) { - obj, err := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + obj, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). NamespaceParam("test").DefaultNamespace(). FilenameParam(false, "../../../examples/pod"). Flatten(). @@ -784,7 +881,7 @@ func TestSingularObjectNoExtension(t *testing.T) { func TestSingularRootScopedObject(t *testing.T) { node := &api.Node{ObjectMeta: api.ObjectMeta{Name: "test"}, Spec: api.NodeSpec{ExternalID: "test"}} r := streamTestObject(node) - infos, err := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + infos, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). NamespaceParam("test").DefaultNamespace(). Stream(r, "STDIN"). Flatten(). @@ -808,9 +905,9 @@ func TestSingularRootScopedObject(t *testing.T) { func TestListObject(t *testing.T) { pods, _ := testData() - labelKey := api.LabelSelectorQueryParam(testapi.Default.Version()) - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith("", t, map[string]string{ - "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(latest.Codec, pods), + labelKey := unversioned.LabelSelectorQueryParam(testapi.Default.Version()) + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), pods), })). SelectorParam("a=b"). NamespaceParam("test"). @@ -841,10 +938,10 @@ func TestListObject(t *testing.T) { func TestListObjectWithDifferentVersions(t *testing.T) { pods, svc := testData() - labelKey := api.LabelSelectorQueryParam(testapi.Default.Version()) - obj, err := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith("", t, map[string]string{ - "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(latest.Codec, pods), - "/namespaces/test/services?" + labelKey + "=a%3Db": runtime.EncodeOrDie(latest.Codec, svc), + labelKey := unversioned.LabelSelectorQueryParam(testapi.Default.Version()) + obj, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + "/namespaces/test/pods?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), pods), + "/namespaces/test/services?" + labelKey + "=a%3Db": runtime.EncodeOrDie(testapi.Default.Codec(), svc), })). SelectorParam("a=b"). NamespaceParam("test"). @@ -868,7 +965,7 @@ func TestListObjectWithDifferentVersions(t *testing.T) { func TestWatch(t *testing.T) { _, svc := testData() - w, err := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith("", t, map[string]string{ + w, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ "/watch/namespaces/test/services/redis-master?resourceVersion=12": watchBody(watch.Event{ Type: watch.Added, Object: &svc.Items[0], @@ -900,7 +997,7 @@ func TestWatch(t *testing.T) { } func TestWatchMultipleError(t *testing.T) { - _, err := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + _, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). NamespaceParam("test").DefaultNamespace(). FilenameParam(false, "../../../examples/guestbook/redis-master-controller.yaml").Flatten(). FilenameParam(false, "../../../examples/guestbook/redis-master-controller.yaml").Flatten(). @@ -923,10 +1020,10 @@ func TestLatest(t *testing.T) { ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "15"}, } - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith("", t, map[string]string{ - "/namespaces/test/pods/foo": runtime.EncodeOrDie(latest.Codec, newPod), - "/namespaces/test/pods/bar": runtime.EncodeOrDie(latest.Codec, newPod2), - "/namespaces/test/services/baz": runtime.EncodeOrDie(latest.Codec, newSvc), + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), newPod), + "/namespaces/test/pods/bar": runtime.EncodeOrDie(testapi.Default.Codec(), newPod2), + "/namespaces/test/services/baz": runtime.EncodeOrDie(testapi.Default.Codec(), newSvc), })). NamespaceParam("other").Stream(r, "STDIN").Flatten().Latest() @@ -949,17 +1046,17 @@ func TestReceiveMultipleErrors(t *testing.T) { go func() { defer w.Close() w.Write([]byte(`{}`)) - w.Write([]byte(runtime.EncodeOrDie(latest.Codec, &pods.Items[0]))) + w.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]))) }() r2, w2 := io.Pipe() go func() { defer w2.Close() w2.Write([]byte(`{}`)) - w2.Write([]byte(runtime.EncodeOrDie(latest.Codec, &svc.Items[0]))) + w2.Write([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), &svc.Items[0]))) }() - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()). + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()). Stream(r, "1").Stream(r2, "2"). ContinueOnError() @@ -1003,7 +1100,7 @@ func TestReplaceAliases(t *testing.T) { }, } - b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()) + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient()) for _, test := range tests { replaced := b.replaceAliases(test.arg) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/helper_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/helper_test.go index dcc1ede01603..8566f3c6882d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/helper_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/helper_test.go @@ -28,7 +28,9 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" - client "k8s.io/kubernetes/pkg/client/unversioned" + apitesting "k8s.io/kubernetes/pkg/api/testing" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" ) @@ -60,14 +62,14 @@ func TestHelperDelete(t *testing.T) { { Resp: &http.Response{ StatusCode: http.StatusNotFound, - Body: objBody(&api.Status{Status: api.StatusFailure}), + Body: objBody(&unversioned.Status{Status: unversioned.StatusFailure}), }, Err: true, }, { Resp: &http.Response{ StatusCode: http.StatusOK, - Body: objBody(&api.Status{Status: api.StatusSuccess}), + Body: objBody(&unversioned.Status{Status: unversioned.StatusSuccess}), }, Req: func(req *http.Request) bool { if req.Method != "DELETE" { @@ -92,7 +94,7 @@ func TestHelperDelete(t *testing.T) { }, } for _, test := range tests { - client := &client.FakeRESTClient{ + client := &fake.RESTClient{ Codec: testapi.Default.Codec(), Resp: test.Resp, Err: test.HttpErr, @@ -128,10 +130,9 @@ func TestHelperCreate(t *testing.T) { return true } - grace := int64(30) tests := []struct { Resp *http.Response - RespFunc client.HTTPClientFunc + RespFunc fake.HTTPClientFunc HttpErr error Modify bool Object runtime.Object @@ -147,14 +148,14 @@ func TestHelperCreate(t *testing.T) { { Resp: &http.Response{ StatusCode: http.StatusNotFound, - Body: objBody(&api.Status{Status: api.StatusFailure}), + Body: objBody(&unversioned.Status{Status: unversioned.StatusFailure}), }, Err: true, }, { Resp: &http.Response{ StatusCode: http.StatusOK, - Body: objBody(&api.Status{Status: api.StatusSuccess}), + Body: objBody(&unversioned.Status{Status: unversioned.StatusSuccess}), }, Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, ExpectObject: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, @@ -164,7 +165,7 @@ func TestHelperCreate(t *testing.T) { Modify: false, Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}}, ExpectObject: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}}, - Resp: &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Status{Status: api.StatusSuccess})}, + Resp: &http.Response{StatusCode: http.StatusOK, Body: objBody(&unversioned.Status{Status: unversioned.StatusSuccess})}, Req: expectPost, }, { @@ -172,18 +173,14 @@ func TestHelperCreate(t *testing.T) { Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}}, ExpectObject: &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, - Resp: &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Status{Status: api.StatusSuccess})}, + Resp: &http.Response{StatusCode: http.StatusOK, Body: objBody(&unversioned.Status{Status: unversioned.StatusSuccess})}, Req: expectPost, }, } for i, test := range tests { - client := &client.FakeRESTClient{ + client := &fake.RESTClient{ Codec: testapi.Default.Codec(), Resp: test.Resp, Err: test.HttpErr, @@ -241,7 +238,7 @@ func TestHelperGet(t *testing.T) { { Resp: &http.Response{ StatusCode: http.StatusNotFound, - Body: objBody(&api.Status{Status: api.StatusFailure}), + Body: objBody(&unversioned.Status{Status: unversioned.StatusFailure}), }, Err: true, }, @@ -269,7 +266,7 @@ func TestHelperGet(t *testing.T) { }, } for _, test := range tests { - client := &client.FakeRESTClient{ + client := &fake.RESTClient{ Codec: testapi.Default.Codec(), Resp: test.Resp, Err: test.HttpErr, @@ -308,7 +305,7 @@ func TestHelperList(t *testing.T) { { Resp: &http.Response{ StatusCode: http.StatusNotFound, - Body: objBody(&api.Status{Status: api.StatusFailure}), + Body: objBody(&unversioned.Status{Status: unversioned.StatusFailure}), }, Err: true, }, @@ -331,7 +328,7 @@ func TestHelperList(t *testing.T) { t.Errorf("url doesn't contain name: %#v", req.URL) return false } - if req.URL.Query().Get(api.LabelSelectorQueryParam(testapi.Default.Version())) != labels.SelectorFromSet(labels.Set{"foo": "baz"}).String() { + if req.URL.Query().Get(unversioned.LabelSelectorQueryParam(testapi.Default.Version())) != labels.SelectorFromSet(labels.Set{"foo": "baz"}).String() { t.Errorf("url doesn't contain query parameters: %#v", req.URL) return false } @@ -340,7 +337,7 @@ func TestHelperList(t *testing.T) { }, } for _, test := range tests { - client := &client.FakeRESTClient{ + client := &fake.RESTClient{ Codec: testapi.Default.Codec(), Resp: test.Resp, Err: test.HttpErr, @@ -383,10 +380,9 @@ func TestHelperReplace(t *testing.T) { return true } - grace := int64(30) tests := []struct { Resp *http.Response - RespFunc client.HTTPClientFunc + RespFunc fake.HTTPClientFunc HttpErr error Overwrite bool Object runtime.Object @@ -403,7 +399,7 @@ func TestHelperReplace(t *testing.T) { Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, Resp: &http.Response{ StatusCode: http.StatusNotFound, - Body: objBody(&api.Status{Status: api.StatusFailure}), + Body: objBody(&unversioned.Status{Status: unversioned.StatusFailure}), }, Err: true, }, @@ -412,7 +408,7 @@ func TestHelperReplace(t *testing.T) { ExpectObject: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, Resp: &http.Response{ StatusCode: http.StatusOK, - Body: objBody(&api.Status{Status: api.StatusSuccess}), + Body: objBody(&unversioned.Status{Status: unversioned.StatusSuccess}), }, Req: expectPut, }, @@ -420,16 +416,12 @@ func TestHelperReplace(t *testing.T) { Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, ExpectObject: &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, Overwrite: true, RespFunc: func(req *http.Request) (*http.Response, error) { if req.Method == "PUT" { - return &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Status{Status: api.StatusSuccess})}, nil + return &http.Response{StatusCode: http.StatusOK, Body: objBody(&unversioned.Status{Status: unversioned.StatusSuccess})}, nil } return &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}})}, nil }, @@ -438,12 +430,12 @@ func TestHelperReplace(t *testing.T) { { Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}}, ExpectObject: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}}, - Resp: &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Status{Status: api.StatusSuccess})}, + Resp: &http.Response{StatusCode: http.StatusOK, Body: objBody(&unversioned.Status{Status: unversioned.StatusSuccess})}, Req: expectPut, }, } for i, test := range tests { - client := &client.FakeRESTClient{ + client := &fake.RESTClient{ Codec: testapi.Default.Codec(), Resp: test.Resp, Err: test.HttpErr, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/mapper.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/mapper.go index a489a6a06c86..a3fc32845e7b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/mapper.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/mapper.go @@ -66,6 +66,7 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) { if err != nil { return nil, fmt.Errorf("unable to connect to a server to handle %q: %v", mapping.Resource, err) } + name, _ := mapping.MetadataAccessor.Name(obj) namespace, _ := mapping.MetadataAccessor.Namespace(obj) resourceVersion, _ := mapping.MetadataAccessor.ResourceVersion(obj) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/result.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/result.go index 3ac6d7201578..6eda37a171a5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/result.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource/result.go @@ -23,6 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/sets" @@ -147,7 +148,7 @@ func (r *Result) Object() (runtime.Object, error) { version = versions.List()[0] } return &api.List{ - ListMeta: api.ListMeta{ + ListMeta: unversioned.ListMeta{ ResourceVersion: version, }, Items: objects, @@ -220,7 +221,7 @@ func AsVersionedObject(infos []*Info, forceList bool, version string) (runtime.O object = objects[0] } else { object = &api.List{Items: objects} - converted, err := tryConvert(api.Scheme, object, version, latest.Version) + converted, err := tryConvert(api.Scheme, object, version, latest.GroupOrDie("").Version) if err != nil { return nil, err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go index 89ce5703e3bc..3937cd9cf7f4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go @@ -35,16 +35,24 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/v1" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/jsonpath" "k8s.io/kubernetes/pkg/util/sets" ) +const ( + tabwriterMinWidth = 10 + tabwriterWidth = 4 + tabwriterPadding = 3 + tabwriterPadChar = ' ' + tabwriterFlags = 0 +) + // GetPrinter takes a format type, an optional format argument. It will return true // if the format is generic (untyped), otherwise it will return false. The printer // is agnostic to schema versions, so you must send arguments to PrintObj in the @@ -213,7 +221,7 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error { if err != nil { return err } - tpmeta := api.TypeMeta{ + tpmeta := unversioned.TypeMeta{ APIVersion: version, Kind: kind, } @@ -380,9 +388,12 @@ func (h *HumanReadablePrinter) HandledResources() []string { var podColumns = []string{"NAME", "READY", "STATUS", "RESTARTS", "AGE"} var podTemplateColumns = []string{"TEMPLATE", "CONTAINER(S)", "IMAGE(S)", "PODLABELS"} var replicationControllerColumns = []string{"CONTROLLER", "CONTAINER(S)", "IMAGE(S)", "SELECTOR", "REPLICAS", "AGE"} +var jobColumns = []string{"JOB", "CONTAINER(S)", "IMAGE(S)", "SELECTOR", "SUCCESSFUL"} var serviceColumns = []string{"NAME", "CLUSTER_IP", "EXTERNAL_IP", "PORT(S)", "SELECTOR", "AGE"} +var ingressColumns = []string{"NAME", "RULE", "BACKEND", "ADDRESS"} var endpointColumns = []string{"NAME", "ENDPOINTS", "AGE"} var nodeColumns = []string{"NAME", "LABELS", "STATUS", "AGE"} +var daemonSetColumns = []string{"NAME", "CONTAINER(S)", "IMAGE(S)", "SELECTOR", "NODE-SELECTOR"} var eventColumns = []string{"FIRSTSEEN", "LASTSEEN", "COUNT", "NAME", "KIND", "SUBOBJECT", "REASON", "SOURCE", "MESSAGE"} var limitRangeColumns = []string{"NAME", "AGE"} var resourceQuotaColumns = []string{"NAME", "AGE"} @@ -396,7 +407,6 @@ var thirdPartyResourceColumns = []string{"NAME", "DESCRIPTION", "VERSION(S)"} var horizontalPodAutoscalerColumns = []string{"NAME", "REFERENCE", "TARGET", "CURRENT", "MINPODS", "MAXPODS", "AGE"} var withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print cluster name too. var deploymentColumns = []string{"NAME", "UPDATEDREPLICAS", "AGE"} -var securityContextConstraintsColumns = []string{"NAME", "PRIV", "CAPS", "HOSTDIR", "SELINUX", "RUNASUSER"} // addDefaultHandlers adds print handlers for default Kubernetes types. func (h *HumanReadablePrinter) addDefaultHandlers() { @@ -406,8 +416,14 @@ func (h *HumanReadablePrinter) addDefaultHandlers() { h.Handler(podTemplateColumns, printPodTemplateList) h.Handler(replicationControllerColumns, printReplicationController) h.Handler(replicationControllerColumns, printReplicationControllerList) + h.Handler(daemonSetColumns, printDaemonSet) + h.Handler(daemonSetColumns, printDaemonSetList) + h.Handler(jobColumns, printJob) + h.Handler(jobColumns, printJobList) h.Handler(serviceColumns, printService) h.Handler(serviceColumns, printServiceList) + h.Handler(ingressColumns, printIngress) + h.Handler(ingressColumns, printIngressList) h.Handler(endpointColumns, printEndpoints) h.Handler(endpointColumns, printEndpointsList) h.Handler(nodeColumns, printNode) @@ -436,8 +452,6 @@ func (h *HumanReadablePrinter) addDefaultHandlers() { h.Handler(deploymentColumns, printDeploymentList) h.Handler(horizontalPodAutoscalerColumns, printHorizontalPodAutoscaler) h.Handler(horizontalPodAutoscalerColumns, printHorizontalPodAutoscalerList) - h.Handler(securityContextConstraintsColumns, printSecurityContextConstraints) - h.Handler(securityContextConstraintsColumns, printSecurityContextConstraintsList) } func (h *HumanReadablePrinter) unknown(data []byte, w io.Writer) error { @@ -514,7 +528,7 @@ func shortHumanDuration(d time.Duration) string { // translateTimestamp returns the elapsed time since timestamp in // human-readable approximation. -func translateTimestamp(timestamp util.Time) string { +func translateTimestamp(timestamp unversioned.Time) string { if timestamp.IsZero() { return "" } @@ -658,7 +672,6 @@ func printPodTemplateList(podList *api.PodTemplateList, w io.Writer, withNamespa func printReplicationController(controller *api.ReplicationController, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { name := controller.Name namespace := controller.Namespace - containers := controller.Spec.Template.Spec.Containers var firstContainer api.Container if len(containers) > 0 { @@ -710,6 +723,70 @@ func printReplicationControllerList(list *api.ReplicationControllerList, w io.Wr return nil } +func printJob(job *extensions.Job, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { + name := job.Name + namespace := job.Namespace + containers := job.Spec.Template.Spec.Containers + var firstContainer api.Container + if len(containers) > 0 { + firstContainer, containers = containers[0], containers[1:] + } + if withNamespace { + if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { + return err + } + } + _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%d\n", + name, + firstContainer.Name, + firstContainer.Image, + labels.FormatLabels(job.Spec.Selector), + job.Status.Succeeded) + if err != nil { + return err + } + if _, err := fmt.Fprint(w, appendLabels(job.Labels, columnLabels)); err != nil { + return err + } + + // Lay out all the other containers on separate lines. + extraLinePrefix := "\t" + if withNamespace { + extraLinePrefix = "\t\t" + } + for _, container := range containers { + _, err := fmt.Fprintf(w, "%s%s\t%s\t%s\t%s", extraLinePrefix, container.Name, container.Image, "", "") + if err != nil { + return err + } + if _, err := fmt.Fprint(w, appendLabelTabs(columnLabels)); err != nil { + return err + } + } + return nil +} + +func printJobList(list *extensions.JobList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { + for _, job := range list.Items { + if err := printJob(&job, w, withNamespace, wide, showAll, columnLabels); err != nil { + return err + } + } + return nil +} + +// loadBalancerStatusStringer behaves just like a string interface and converts the given status to a string. +func loadBalancerStatusStringer(s api.LoadBalancerStatus) string { + ingress := s.Ingress + result := []string{} + for i := range ingress { + if ingress[i].IP != "" { + result = append(result, ingress[i].IP) + } + } + return strings.Join(result, ",") +} + func getServiceExternalIP(svc *api.Service) string { switch svc.Spec.Type { case api.ServiceTypeClusterIP: @@ -723,17 +800,12 @@ func getServiceExternalIP(svc *api.Service) string { } return "nodes" case api.ServiceTypeLoadBalancer: - ingress := svc.Status.LoadBalancer.Ingress - result := []string{} - for i := range ingress { - if ingress[i].IP != "" { - result = append(result, ingress[i].IP) - } - } + lbIps := loadBalancerStatusStringer(svc.Status.LoadBalancer) if len(svc.Spec.ExternalIPs) > 0 { - result = append(result, svc.Spec.ExternalIPs...) + result := append(strings.Split(lbIps, ","), svc.Spec.ExternalIPs...) + return strings.Join(result, ",") } - return strings.Join(result, ",") + return lbIps } return "unknown" } @@ -784,6 +856,125 @@ func printServiceList(list *api.ServiceList, w io.Writer, withNamespace bool, wi return nil } +// backendStringer behaves just like a string interface and converts the given backend to a string. +func backendStringer(backend *extensions.IngressBackend) string { + if backend == nil { + return "" + } + return fmt.Sprintf("%v:%v", backend.ServiceName, backend.ServicePort.String()) +} + +func printIngress(ingress *extensions.Ingress, w io.Writer, withNamespace, wide bool, showAll bool, columnLabels []string) error { + name := ingress.Name + namespace := ingress.Namespace + + hostRules := ingress.Spec.Rules + if withNamespace { + if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { + return err + } + } + + if _, err := fmt.Fprintf(w, "%s\t%v\t%v\t%v\n", + name, + "-", + backendStringer(ingress.Spec.Backend), + loadBalancerStatusStringer(ingress.Status.LoadBalancer)); err != nil { + return err + } + + // Lay out all the rules on separate lines. + extraLinePrefix := "" + if withNamespace { + extraLinePrefix = "\t" + } + for _, rules := range hostRules { + if rules.HTTP == nil { + continue + } + _, err := fmt.Fprintf(w, "%s\t%v\t", extraLinePrefix, rules.Host) + if err != nil { + return err + } + if _, err := fmt.Fprint(w, appendLabelTabs(columnLabels)); err != nil { + return err + } + for _, rule := range rules.HTTP.Paths { + _, err := fmt.Fprintf(w, "%s\t%v\t%v", extraLinePrefix, rule.Path, backendStringer(&rule.Backend)) + if err != nil { + return err + } + if _, err := fmt.Fprint(w, appendLabelTabs(columnLabels)); err != nil { + return err + } + } + } + return nil +} + +func printIngressList(ingressList *extensions.IngressList, w io.Writer, withNamespace, wide bool, showAll bool, columnLabels []string) error { + for _, ingress := range ingressList.Items { + if err := printIngress(&ingress, w, withNamespace, wide, true, columnLabels); err != nil { + return err + } + } + return nil +} + +func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { + name := ds.Name + namespace := ds.Namespace + + containers := ds.Spec.Template.Spec.Containers + var firstContainer api.Container + if len(containers) > 0 { + firstContainer, containers = containers[0], containers[1:] + } + + if withNamespace { + if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { + return err + } + } + if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s", + name, + firstContainer.Name, + firstContainer.Image, + labels.FormatLabels(ds.Spec.Selector), + labels.FormatLabels(ds.Spec.Template.Spec.NodeSelector), + ); err != nil { + return err + } + if _, err := fmt.Fprint(w, appendLabels(ds.Labels, columnLabels)); err != nil { + return err + } + + // Lay out all the other containers on separate lines. + extraLinePrefix := "\t" + if withNamespace { + extraLinePrefix = "\t\t" + } + for _, container := range containers { + _, err := fmt.Fprintf(w, "%s%s\t%s\t%s\t%s", extraLinePrefix, container.Name, container.Image, "", "") + if err != nil { + return err + } + if _, err := fmt.Fprint(w, appendLabelTabs(columnLabels)); err != nil { + return err + } + } + return nil +} + +func printDaemonSetList(list *extensions.DaemonSetList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { + for _, ds := range list.Items { + if err := printDaemonSet(&ds, w, withNamespace, wide, showAll, columnLabels); err != nil { + return err + } + } + return nil +} + func printEndpoints(endpoints *api.Endpoints, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { name := endpoints.Name namespace := endpoints.Namespace @@ -1139,7 +1330,7 @@ func printComponentStatusList(list *api.ComponentStatusList, w io.Writer, withNa return nil } -func printThirdPartyResource(rsrc *experimental.ThirdPartyResource, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printThirdPartyResource(rsrc *extensions.ThirdPartyResource, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { versions := make([]string, len(rsrc.Versions)) for ix := range rsrc.Versions { version := &rsrc.Versions[ix] @@ -1152,7 +1343,7 @@ func printThirdPartyResource(rsrc *experimental.ThirdPartyResource, w io.Writer, return nil } -func printThirdPartyResourceList(list *experimental.ThirdPartyResourceList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printThirdPartyResourceList(list *extensions.ThirdPartyResourceList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { for _, item := range list.Items { if err := printThirdPartyResource(&item, w, withNamespace, wide, showAll, columnLabels); err != nil { return err @@ -1162,7 +1353,7 @@ func printThirdPartyResourceList(list *experimental.ThirdPartyResourceList, w io return nil } -func printDeployment(deployment *experimental.Deployment, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printDeployment(deployment *extensions.Deployment, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { if withNamespace { if _, err := fmt.Fprintf(w, "%s\t", deployment.Namespace); err != nil { return err @@ -1178,7 +1369,7 @@ func printDeployment(deployment *experimental.Deployment, w io.Writer, withNames return err } -func printDeploymentList(list *experimental.DeploymentList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printDeploymentList(list *extensions.DeploymentList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { for _, item := range list.Items { if err := printDeployment(&item, w, withNamespace, wide, showAll, columnLabels); err != nil { return err @@ -1187,7 +1378,7 @@ func printDeploymentList(list *experimental.DeploymentList, w io.Writer, withNam return nil } -func printHorizontalPodAutoscaler(hpa *experimental.HorizontalPodAutoscaler, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printHorizontalPodAutoscaler(hpa *extensions.HorizontalPodAutoscaler, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { namespace := hpa.Namespace name := hpa.Name reference := fmt.Sprintf("%s/%s/%s/%s", @@ -1198,11 +1389,11 @@ func printHorizontalPodAutoscaler(hpa *experimental.HorizontalPodAutoscaler, w i target := fmt.Sprintf("%s %v", hpa.Spec.Target.Quantity.String(), hpa.Spec.Target.Resource) current := "" - if hpa.Status != nil && hpa.Status.CurrentConsumption != nil { + if hpa.Status.CurrentConsumption != nil { current = fmt.Sprintf("%s %v", hpa.Status.CurrentConsumption.Quantity.String(), hpa.Status.CurrentConsumption.Resource) } - minPods := hpa.Spec.MinCount - maxPods := hpa.Spec.MaxCount + minPods := hpa.Spec.MinReplicas + maxPods := hpa.Spec.MaxReplicas if withNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err @@ -1224,7 +1415,7 @@ func printHorizontalPodAutoscaler(hpa *experimental.HorizontalPodAutoscaler, w i return err } -func printHorizontalPodAutoscalerList(list *experimental.HorizontalPodAutoscalerList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { +func printHorizontalPodAutoscalerList(list *extensions.HorizontalPodAutoscalerList, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { for i := range list.Items { if err := printHorizontalPodAutoscaler(&list.Items[i], w, withNamespace, wide, showAll, columnLabels); err != nil { return err @@ -1233,23 +1424,6 @@ func printHorizontalPodAutoscalerList(list *experimental.HorizontalPodAutoscaler return nil } -func printSecurityContextConstraints(item *api.SecurityContextConstraints, w io.Writer, withNamespace, wide, showAll bool, columnLabels []string) error { - _, err := fmt.Fprintf(w, "%s\t%t\t%v\t%t\t%s\t%s\n", item.Name, item.AllowPrivilegedContainer, - item.AllowedCapabilities, item.AllowHostDirVolumePlugin, item.SELinuxContext.Type, - item.RunAsUser.Type) - return err -} - -func printSecurityContextConstraintsList(list *api.SecurityContextConstraintsList, w io.Writer, withNamespace, wide, showAll bool, columnLabels []string) error { - for _, item := range list.Items { - if err := printSecurityContextConstraints(&item, w, withNamespace, wide, showAll, columnLabels); err != nil { - return err - } - } - - return nil -} - func appendLabels(itemLabels map[string]string, columnLabels []string) string { var buffer bytes.Buffer @@ -1301,10 +1475,19 @@ func formatWideHeaders(wide bool, t reflect.Type) []string { return nil } +// GetNewTabWriter returns a tabwriter that translates tabbed columns in input into properly aligned text. +func GetNewTabWriter(output io.Writer) *tabwriter.Writer { + return tabwriter.NewWriter(output, tabwriterMinWidth, tabwriterWidth, tabwriterPadding, tabwriterPadChar, tabwriterFlags) +} + // PrintObj prints the obj in a human-friendly format according to the type of the obj. func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) error { - w := tabwriter.NewWriter(output, 10, 4, 3, ' ', 0) - defer w.Flush() + // if output is a tabwriter (when it's called by kubectl get), we use it; create a new tabwriter otherwise + w, found := output.(*tabwriter.Writer) + if !found { + w = GetNewTabWriter(output) + defer w.Flush() + } t := reflect.TypeOf(obj) if handler := h.handlerMap[t]; handler != nil { if !h.noHeaders && t != h.lastType { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer_test.go index 72f24fc01b36..fe2e2776fecf 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer_test.go @@ -28,8 +28,10 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/v1" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" + kubectltesting "k8s.io/kubernetes/pkg/kubectl/testing" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" @@ -37,23 +39,12 @@ import ( "github.com/ghodss/yaml" ) -type testStruct struct { - api.TypeMeta `json:",inline"` - api.ObjectMeta `json:"metadata,omitempty"` - Key string `json:"Key"` - Map map[string]int `json:"Map"` - StringList []string `json:"StringList"` - IntList []int `json:"IntList"` -} - -func (ts *testStruct) IsAnAPIObject() {} - func init() { - api.Scheme.AddKnownTypes("", &testStruct{}) - api.Scheme.AddKnownTypes(testapi.Default.Version(), &testStruct{}) + api.Scheme.AddKnownTypes("", &kubectltesting.TestStruct{}) + api.Scheme.AddKnownTypes(testapi.Default.Version(), &kubectltesting.TestStruct{}) } -var testData = testStruct{ +var testData = kubectltesting.TestStruct{ Key: "testValue", Map: map[string]int{"TestSubkey": 1}, StringList: []string{"a", "b", "c"}, @@ -61,13 +52,13 @@ var testData = testStruct{ } func TestVersionedPrinter(t *testing.T) { - original := &testStruct{Key: "value"} + original := &kubectltesting.TestStruct{Key: "value"} p := NewVersionedPrinter( ResourcePrinterFunc(func(obj runtime.Object, w io.Writer) error { if obj == original { t.Fatalf("object should not be identical: %#v", obj) } - if obj.(*testStruct).Key != "value" { + if obj.(*kubectltesting.TestStruct).Key != "value" { t.Fatalf("object was not converted: %#v", obj) } return nil @@ -176,14 +167,14 @@ func testPrinter(t *testing.T, printer ResourcePrinter, unmarshalFunc func(data if err != nil { t.Fatal(err) } - var poutput testStruct + var poutput kubectltesting.TestStruct // Verify that given function runs without error. err = unmarshalFunc(buf.Bytes(), &poutput) if err != nil { t.Fatal(err) } // Use real decode function to undo the versioning process. - poutput = testStruct{} + poutput = kubectltesting.TestStruct{} err = runtime.YAMLDecoder(testapi.Default.Codec()).DecodeInto(buf.Bytes(), &poutput) if err != nil { t.Fatal(err) @@ -292,7 +283,7 @@ func TestNamePrinter(t *testing.T) { }{ "singleObject": { &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", }, ObjectMeta: api.ObjectMeta{ @@ -302,7 +293,7 @@ func TestNamePrinter(t *testing.T) { "pod/foo\n"}, "List": { &v1.List{ - TypeMeta: v1.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "List", }, Items: []runtime.RawExtension{ @@ -389,7 +380,7 @@ func TestTemplateStrings(t *testing.T) { Name: "bar", State: api.ContainerState{ Running: &api.ContainerStateRunning{ - StartedAt: util.Time{}, + StartedAt: unversioned.Time{}, }, }, }, @@ -406,7 +397,7 @@ func TestTemplateStrings(t *testing.T) { Name: "foo", State: api.ContainerState{ Running: &api.ContainerStateRunning{ - StartedAt: util.Time{}, + StartedAt: unversioned.Time{}, }, }, }, @@ -414,7 +405,7 @@ func TestTemplateStrings(t *testing.T) { Name: "bar", State: api.ContainerState{ Running: &api.ContainerStateRunning{ - StartedAt: util.Time{}, + StartedAt: unversioned.Time{}, }, }, }, @@ -513,22 +504,22 @@ func TestPrintEventsResultSorted(t *testing.T) { { Source: api.EventSource{Component: "kubelet"}, Message: "Item 1", - FirstTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), - LastTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + FirstTimestamp: unversioned.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + LastTimestamp: unversioned.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "scheduler"}, Message: "Item 2", - FirstTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), - LastTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + FirstTimestamp: unversioned.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + LastTimestamp: unversioned.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "kubelet"}, Message: "Item 3", - FirstTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), - LastTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + FirstTimestamp: unversioned.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + LastTimestamp: unversioned.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), Count: 1, }, }, @@ -908,8 +899,8 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) { ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, Source: api.EventSource{Component: "kubelet"}, Message: "Item 1", - FirstTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), - LastTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + FirstTimestamp: unversioned.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + LastTimestamp: unversioned.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), Count: 1, }, isNamespaced: true, @@ -1214,16 +1205,16 @@ type stringTestList []struct { func TestTranslateTimestamp(t *testing.T) { tl := stringTestList{ - {"a while from now", translateTimestamp(util.Time{Time: time.Now().Add(2.1e9)}), ""}, - {"almost now", translateTimestamp(util.Time{Time: time.Now().Add(1.9e9)}), "0s"}, - {"now", translateTimestamp(util.Time{Time: time.Now()}), "0s"}, - {"unknown", translateTimestamp(util.Time{}), ""}, - {"30 seconds ago", translateTimestamp(util.Time{Time: time.Now().Add(-3e10)}), "30s"}, - {"5 minutes ago", translateTimestamp(util.Time{Time: time.Now().Add(-3e11)}), "5m"}, - {"an hour ago", translateTimestamp(util.Time{Time: time.Now().Add(-6e12)}), "1h"}, - {"2 days ago", translateTimestamp(util.Time{Time: time.Now().AddDate(0, 0, -2)}), "2d"}, - {"months ago", translateTimestamp(util.Time{Time: time.Now().AddDate(0, -3, 0)}), "92d"}, - {"10 years ago", translateTimestamp(util.Time{Time: time.Now().AddDate(-10, 0, 0)}), "10y"}, + {"a while from now", translateTimestamp(unversioned.Time{Time: time.Now().Add(2.1e9)}), ""}, + {"almost now", translateTimestamp(unversioned.Time{Time: time.Now().Add(1.9e9)}), "0s"}, + {"now", translateTimestamp(unversioned.Time{Time: time.Now()}), "0s"}, + {"unknown", translateTimestamp(unversioned.Time{}), ""}, + {"30 seconds ago", translateTimestamp(unversioned.Time{Time: time.Now().Add(-3e10)}), "30s"}, + {"5 minutes ago", translateTimestamp(unversioned.Time{Time: time.Now().Add(-3e11)}), "5m"}, + {"an hour ago", translateTimestamp(unversioned.Time{Time: time.Now().Add(-6e12)}), "1h"}, + {"2 days ago", translateTimestamp(unversioned.Time{Time: time.Now().AddDate(0, 0, -2)}), "2d"}, + {"months ago", translateTimestamp(unversioned.Time{Time: time.Now().AddDate(0, -3, 0)}), "92d"}, + {"10 years ago", translateTimestamp(unversioned.Time{Time: time.Now().AddDate(-10, 0, 0)}), "10y"}, } for _, test := range tl { if test.got != test.exp { @@ -1235,22 +1226,22 @@ func TestTranslateTimestamp(t *testing.T) { func TestPrintDeployment(t *testing.T) { tests := []struct { - deployment experimental.Deployment + deployment extensions.Deployment expect string }{ { - experimental.Deployment{ + extensions.Deployment{ ObjectMeta: api.ObjectMeta{ Name: "test1", - CreationTimestamp: util.Time{Time: time.Now().Add(1.9e9)}, + CreationTimestamp: unversioned.Time{Time: time.Now().Add(1.9e9)}, }, - Spec: experimental.DeploymentSpec{ + Spec: extensions.DeploymentSpec{ Replicas: 5, Template: &api.PodTemplateSpec{ Spec: api.PodSpec{Containers: make([]api.Container, 2)}, }, }, - Status: experimental.DeploymentStatus{ + Status: extensions.DeploymentStatus{ Replicas: 10, UpdatedReplicas: 2, }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go index 5aa4d63e387c..f2420456a0c7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go @@ -60,25 +60,27 @@ type RollingUpdaterConfig struct { // CleanupPolicy defines the cleanup action to take after the deployment is // complete. CleanupPolicy RollingUpdaterCleanupPolicy - // The maximum number of pods that can be unavailable during the update. - // Value can be an absolute number (ex: 5) or a percentage of total pods at - // the start of update (ex: 10%). Absolute number is calculated from - // percentage by rounding up. This can not be 0 if MaxSurge is 0. By - // default, a fixed value of 1 is used. Example: when this is set to 30%, - // the old RC can be scaled down by 30% immediately when the rolling update - // starts. Once new pods are ready, old RC can be scaled down further, - // followed by scaling up the new RC, ensuring that at least 70% of original - // number of pods are available at all times during the update. + // MaxUnavailable is the maximum number of pods that can be unavailable during the update. + // Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + // Absolute number is calculated from percentage by rounding up. + // This can not be 0 if MaxSurge is 0. + // By default, a fixed value of 1 is used. + // Example: when this is set to 30%, the old RC can be scaled down to 70% of desired pods + // immediately when the rolling update starts. Once new pods are ready, old RC + // can be scaled down further, followed by scaling up the new RC, ensuring + // that the total number of pods available at all times during the update is at + // least 70% of desired pods. MaxUnavailable util.IntOrString - // The maximum number of pods that can be scheduled above the original - // number of pods. Value can be an absolute number (ex: 5) or a percentage of total - // pods at the start of the update (ex: 10%). This can not be 0 if - // MaxUnavailable is 0. Absolute number is calculated from percentage by - // rounding up. By default, a value of 1 is used. Example: when this is set - // to 30%, the new RC can be scaled up by 30% immediately when the rolling - // update starts. Once old pods have been killed, new RC can be scaled up + // MaxSurge is the maximum number of pods that can be scheduled above the desired number of pods. + // Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + // This can not be 0 if MaxUnavailable is 0. + // Absolute number is calculated from percentage by rounding up. + // By default, a value of 1 is used. + // Example: when this is set to 30%, the new RC can be scaled up immediately + // when the rolling update starts, such that the total number of old and new pods do not exceed + // 130% of desired pods. Once old pods have been killed, new RC can be scaled up // further, ensuring that total number of pods running at any time during - // the update is atmost 130% of original pods. + // the update is atmost 130% of desired pods. MaxSurge util.IntOrString } @@ -197,12 +199,12 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error { oldRc.Name, originalReplicasAnnotation, oldRc.Annotations[originalReplicasAnnotation]) } // The maximum pods which can go unavailable during the update. - maxUnavailable, err := extractMaxValue(config.MaxUnavailable, "maxUnavailable", original) + maxUnavailable, err := extractMaxValue(config.MaxUnavailable, "maxUnavailable", desired) if err != nil { return err } // The maximum scaling increment. - maxSurge, err := extractMaxValue(config.MaxSurge, "maxSurge", original) + maxSurge, err := extractMaxValue(config.MaxSurge, "maxSurge", desired) if err != nil { return err } @@ -340,8 +342,7 @@ func (r *RollingUpdater) scaleDown(newRc, oldRc *api.ReplicationController, desi // scalerScaleAndWait scales a controller using a Scaler and a real client. func (r *RollingUpdater) scaleAndWaitWithScaler(rc *api.ReplicationController, retry *RetryParams, wait *RetryParams) (*api.ReplicationController, error) { - scalerClient := NewScalerClient(r.c) - scaler, err := ScalerFor("ReplicationController", scalerClient) + scaler, err := ScalerFor("ReplicationController", r.c) if err != nil { return nil, fmt.Errorf("Couldn't make scaler: %s", err) } @@ -353,7 +354,7 @@ func (r *RollingUpdater) scaleAndWaitWithScaler(rc *api.ReplicationController, r // pollForReadyPods polls oldRc and newRc each interval and returns the old // and new ready counts for their pods. If a pod is observed as being ready, -// it's considered ready even if it later becomes unready. +// it's considered ready even if it later becomes notReady. func (r *RollingUpdater) pollForReadyPods(interval, timeout time.Duration, oldRc, newRc *api.ReplicationController) (int, int, error) { controllers := []*api.ReplicationController{oldRc, newRc} oldReady := 0 @@ -452,8 +453,7 @@ func (r *RollingUpdater) cleanupWithClients(oldRc, newRc *api.ReplicationControl if err != nil { return err } - scalerClient := NewScalerClient(r.c) - if err = wait.Poll(config.Interval, config.Timeout, scalerClient.ControllerHasDesiredReplicas(newRc)); err != nil { + if err = wait.Poll(config.Interval, config.Timeout, client.ControllerHasDesiredReplicas(r.c, newRc)); err != nil { return err } newRc, err = r.c.ReplicationControllers(r.ns).Get(newRc.Name) @@ -482,8 +482,8 @@ func (r *RollingUpdater) cleanupWithClients(oldRc, newRc *api.ReplicationControl } // func extractMaxValue is a helper to extract config max values as either -// absolute numbers or based on percentages of the original rc. -func extractMaxValue(field util.IntOrString, name string, original int) (int, error) { +// absolute numbers or based on percentages of the given value. +func extractMaxValue(field util.IntOrString, name string, value int) (int, error) { switch field.Kind { case util.IntstrInt: if field.IntVal < 0 { @@ -499,7 +499,7 @@ func extractMaxValue(field util.IntOrString, name string, original int) (int, er if v < 0 { return 0, fmt.Errorf("%s must be >= 0", name) } - return int(math.Ceil(float64(original) * (float64(v)) / 100)), nil + return int(math.Ceil(float64(value) * (float64(v)) / 100)), nil } return 0, fmt.Errorf("invalid kind %q for %s", field.Kind, name) } @@ -564,7 +564,7 @@ func CreateNewControllerFromCurrentController(c *client.Client, namespace, oldNa return newRc, nil } -func AbortRollingUpdate(c *RollingUpdaterConfig) { +func AbortRollingUpdate(c *RollingUpdaterConfig) error { // Swap the controllers tmp := c.OldRc c.OldRc = c.NewRc @@ -574,12 +574,18 @@ func AbortRollingUpdate(c *RollingUpdaterConfig) { c.NewRc.Annotations = map[string]string{} } c.NewRc.Annotations[sourceIdAnnotation] = fmt.Sprintf("%s:%s", c.OldRc.Name, c.OldRc.UID) - desiredSize, found := c.OldRc.Annotations[desiredReplicasAnnotation] - if found { - fmt.Printf("Found desired replicas.") - c.NewRc.Annotations[desiredReplicasAnnotation] = desiredSize + + // Use the original value since the replica count change from old to new + // could be asymmetric. If we don't know the original count, we can't safely + // roll back to a known good size. + originalSize, foundOriginal := tmp.Annotations[originalReplicasAnnotation] + if !foundOriginal { + return fmt.Errorf("couldn't find original replica count of %q", tmp.Name) } + fmt.Fprintf(c.Out, "Setting %q replicas to %s\n", c.NewRc.Name, originalSize) + c.NewRc.Annotations[desiredReplicasAnnotation] = originalSize c.CleanupPolicy = DeleteRollingUpdateCleanupPolicy + return nil } func GetNextControllerAnnotation(rc *api.ReplicationController) (string, bool) { @@ -712,7 +718,7 @@ func updateWithRetries(rcClient client.ReplicationControllerInterface, rc *api.R } func FindSourceController(r client.ReplicationControllersNamespacer, namespace, name string) (*api.ReplicationController, error) { - list, err := r.ReplicationControllers(namespace).List(labels.Everything()) + list, err := r.ReplicationControllers(namespace).List(labels.Everything(), fields.Everything()) if err != nil { return nil, err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/rolling_updater_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/rolling_updater_test.go index 2ca9ab6ef580..f48f08d7c15f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/rolling_updater_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/rolling_updater_test.go @@ -28,7 +28,9 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + apitesting "k8s.io/kubernetes/pkg/api/testing" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" @@ -537,7 +539,7 @@ Scaling foo-v1 down to 0 down{oldReady: 10, newReady: 20, to: 0}, }, output: `Created foo-v2 -Scaling up foo-v2 from 0 to 20, scaling down foo-v1 from 10 to 0 (keep 10 pods available, don't exceed 40 pods) +Scaling up foo-v2 from 0 to 20, scaling down foo-v1 from 10 to 0 (keep 10 pods available, don't exceed 70 pods) Scaling foo-v2 up to 20 Scaling foo-v1 down to 0 `, @@ -816,7 +818,7 @@ func TestRollingUpdater_cleanupWithClients(t *testing.T) { t.Errorf("unexpected error: %v", err) } if len(fake.Actions()) != len(test.expected) { - t.Fatalf("%s: unexpected actions: %v, expected %v", test.name, fake.Actions, test.expected) + t.Fatalf("%s: unexpected actions: %v, expected %v", test.name, fake.Actions(), test.expected) } for j, action := range fake.Actions() { if e, a := test.expected[j], action.GetVerb(); e != a { @@ -1010,7 +1012,6 @@ func TestUpdateExistingReplicationController(t *testing.T) { func TestUpdateWithRetries(t *testing.T) { codec := testapi.Default.Codec() - grace := int64(30) rc := &api.ReplicationController{ ObjectMeta: api.ObjectMeta{Name: "rc", Labels: map[string]string{ @@ -1027,11 +1028,7 @@ func TestUpdateWithRetries(t *testing.T) { "foo": "bar", }, }, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, }, } @@ -1052,9 +1049,9 @@ func TestUpdateWithRetries(t *testing.T) { {StatusCode: 500, Body: objBody(codec, &api.ReplicationController{})}, {StatusCode: 200, Body: objBody(codec, rc)}, } - fakeClient := &client.FakeRESTClient{ + fakeClient := &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == testapi.Default.ResourcePath("replicationcontrollers", "default", "rc") && m == "PUT": update := updates[0] @@ -1143,9 +1140,9 @@ func TestAddDeploymentHash(t *testing.T) { seen := sets.String{} updatedRc := false - fakeClient := &client.FakeRESTClient{ + fakeClient := &fake.RESTClient{ Codec: codec, - Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { + Client: fake.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == testapi.Default.ResourcePath("pods", "default", "") && m == "GET": if req.URL.RawQuery != "labelSelector=foo%3Dbar" { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/run.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/run.go index be8e843f39f9..9add392bf45a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/run.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/run.go @@ -24,7 +24,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/validation" ) type BasicReplicationController struct{} @@ -394,7 +394,7 @@ func parseEnvs(envArray []string) ([]api.EnvVar, error) { envs := []api.EnvVar{} for _, env := range envArray { parts := strings.Split(env, "=") - if len(parts) != 2 || !util.IsCIdentifier(parts[0]) || len(parts[1]) == 0 { + if len(parts) != 2 || !validation.IsCIdentifier(parts[0]) || len(parts[1]) == 0 { return nil, fmt.Errorf("invalid env: %v", env) } envVar := api.EnvVar{Name: parts[0], Value: parts[1]} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/scale.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/scale.go index c24e8e7a0f74..1080e2bc56f4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/scale.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/scale.go @@ -22,6 +22,8 @@ import ( "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/apis/extensions" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/util/wait" ) @@ -52,6 +54,7 @@ type ControllerScaleErrorType int const ( ControllerScaleGetFailure ControllerScaleErrorType = iota ControllerScaleUpdateFailure + ControllerScaleUpdateInvalidFailure ) // A ControllerScaleError is returned when a scale request passes @@ -68,8 +71,8 @@ func (c ControllerScaleError) Error() string { c.ActualError, c.ResourceVersion) } -// Validate ensures that the preconditions match. Returns nil if they are valid, an error otherwise -func (precondition *ScalePrecondition) Validate(controller *api.ReplicationController) error { +// ValidateReplicationController ensures that the preconditions match. Returns nil if they are valid, an error otherwise +func (precondition *ScalePrecondition) ValidateReplicationController(controller *api.ReplicationController) error { if precondition.Size != -1 && controller.Spec.Replicas != precondition.Size { return PreconditionError{"replicas", strconv.Itoa(precondition.Size), strconv.Itoa(controller.Spec.Replicas)} } @@ -79,6 +82,20 @@ func (precondition *ScalePrecondition) Validate(controller *api.ReplicationContr return nil } +// ValidateJob ensures that the preconditions match. Returns nil if they are valid, an error otherwise +func (precondition *ScalePrecondition) ValidateJob(job *extensions.Job) error { + if precondition.Size != -1 && job.Spec.Parallelism == nil { + return PreconditionError{"parallelism", strconv.Itoa(precondition.Size), "nil"} + } + if precondition.Size != -1 && *job.Spec.Parallelism != precondition.Size { + return PreconditionError{"parallelism", strconv.Itoa(precondition.Size), strconv.Itoa(*job.Spec.Parallelism)} + } + if precondition.ResourceVersion != "" && job.ResourceVersion != precondition.ResourceVersion { + return PreconditionError{"resource version", precondition.ResourceVersion, job.ResourceVersion} + } + return nil +} + type Scaler interface { // Scale scales the named resource after checking preconditions. It optionally // retries in the event of resource version mismatch (if retry is not nil), @@ -86,19 +103,24 @@ type Scaler interface { Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, wait *RetryParams) error // ScaleSimple does a simple one-shot attempt at scaling - not useful on it's own, but // a necessary building block for Scale - ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) (string, error) + ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error } -func ScalerFor(kind string, c ScalerClient) (Scaler, error) { +func ScalerFor(kind string, c client.Interface) (Scaler, error) { switch kind { case "ReplicationController": return &ReplicationControllerScaler{c}, nil + case "Job": + return &JobScaler{c}, nil } return nil, fmt.Errorf("no scaler has been implemented for %q", kind) } type ReplicationControllerScaler struct { - c ScalerClient + c client.Interface +} +type JobScaler struct { + c client.Interface } // RetryParams encapsulates the retry parameters used by kubectl's scaler. @@ -113,11 +135,15 @@ func NewRetryParams(interval, timeout time.Duration) *RetryParams { // ScaleCondition is a closure around Scale that facilitates retries via util.wait func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name string, count uint) wait.ConditionFunc { return func() (bool, error) { - _, err := r.ScaleSimple(namespace, name, precondition, count) + err := r.ScaleSimple(namespace, name, precondition, count) switch e, _ := err.(ControllerScaleError); err.(type) { case nil: return true, nil case ControllerScaleError: + // if it's invalid we shouldn't keep waiting + if e.FailureType == ControllerScaleUpdateInvalidFailure { + return false, err + } if e.FailureType == ControllerScaleUpdateFailure { return false, nil } @@ -126,23 +152,26 @@ func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name s } } -func (scaler *ReplicationControllerScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) (string, error) { - controller, err := scaler.c.GetReplicationController(namespace, name) +func (scaler *ReplicationControllerScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error { + controller, err := scaler.c.ReplicationControllers(namespace).Get(name) if err != nil { - return "", ControllerScaleError{ControllerScaleGetFailure, "Unknown", err} + return ControllerScaleError{ControllerScaleGetFailure, "Unknown", err} } if preconditions != nil { - if err := preconditions.Validate(controller); err != nil { - return "", err + if err := preconditions.ValidateReplicationController(controller); err != nil { + return err } } controller.Spec.Replicas = int(newSize) // TODO: do retry on 409 errors here? - if _, err := scaler.c.UpdateReplicationController(namespace, controller); err != nil { - return "", ControllerScaleError{ControllerScaleUpdateFailure, controller.ResourceVersion, err} + if _, err := scaler.c.ReplicationControllers(namespace).Update(controller); err != nil { + if errors.IsInvalid(err) { + return ControllerScaleError{ControllerScaleUpdateInvalidFailure, controller.ResourceVersion, err} + } + return ControllerScaleError{ControllerScaleUpdateFailure, controller.ResourceVersion, err} } // TODO: do a better job of printing objects here. - return "scaled", nil + return nil } // Scale updates a ReplicationController to a new size, with optional precondition check (if preconditions is not nil), @@ -161,40 +190,61 @@ func (scaler *ReplicationControllerScaler) Scale(namespace, name string, newSize return err } if waitForReplicas != nil { - rc, err := scaler.c.GetReplicationController(namespace, name) + rc, err := scaler.c.ReplicationControllers(namespace).Get(name) if err != nil { return err } return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, - scaler.c.ControllerHasDesiredReplicas(rc)) + client.ControllerHasDesiredReplicas(scaler.c, rc)) } return nil } -// ScalerClient abstracts access to ReplicationControllers. -type ScalerClient interface { - GetReplicationController(namespace, name string) (*api.ReplicationController, error) - UpdateReplicationController(namespace string, rc *api.ReplicationController) (*api.ReplicationController, error) - ControllerHasDesiredReplicas(rc *api.ReplicationController) wait.ConditionFunc -} - -func NewScalerClient(c client.Interface) ScalerClient { - return &realScalerClient{c} -} - -// realScalerClient is a ScalerClient which uses a Kube client. -type realScalerClient struct { - client client.Interface -} - -func (c *realScalerClient) GetReplicationController(namespace, name string) (*api.ReplicationController, error) { - return c.client.ReplicationControllers(namespace).Get(name) -} +// ScaleSimple is responsible for updating job's parallelism. +func (scaler *JobScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error { + job, err := scaler.c.Extensions().Jobs(namespace).Get(name) + if err != nil { + return ControllerScaleError{ControllerScaleGetFailure, "Unknown", err} + } + if preconditions != nil { + if err := preconditions.ValidateJob(job); err != nil { + return err + } + } + parallelism := int(newSize) + job.Spec.Parallelism = ¶llelism + if _, err := scaler.c.Extensions().Jobs(namespace).Update(job); err != nil { + if errors.IsInvalid(err) { + return ControllerScaleError{ControllerScaleUpdateInvalidFailure, job.ResourceVersion, err} + } + return ControllerScaleError{ControllerScaleUpdateFailure, job.ResourceVersion, err} -func (c *realScalerClient) UpdateReplicationController(namespace string, rc *api.ReplicationController) (*api.ReplicationController, error) { - return c.client.ReplicationControllers(namespace).Update(rc) + } + return nil } -func (c *realScalerClient) ControllerHasDesiredReplicas(rc *api.ReplicationController) wait.ConditionFunc { - return client.ControllerHasDesiredReplicas(c.client, rc) +// Scale updates a Job to a new size, with optional precondition check (if preconditions is not nil), +// optional retries (if retry is not nil), and then optionally waits for parallelism to reach desired +// number, which can be less than requested based on job's current progress. +func (scaler *JobScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error { + if preconditions == nil { + preconditions = &ScalePrecondition{-1, ""} + } + if retry == nil { + // Make it try only once, immediately + retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond} + } + cond := ScaleCondition(scaler, preconditions, namespace, name, newSize) + if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil { + return err + } + if waitForReplicas != nil { + job, err := scaler.c.Extensions().Jobs(namespace).Get(name) + if err != nil { + return err + } + return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, + client.JobHasDesiredParallelism(scaler.c, job)) + } + return nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/scale_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/scale_test.go index a8f77226a5e3..8bf64e70b078 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/scale_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/scale_test.go @@ -21,29 +21,75 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" + kerrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/apis/extensions" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/testclient" ) type ErrorReplicationControllers struct { testclient.FakeReplicationControllers + invalid bool } func (c *ErrorReplicationControllers) Update(controller *api.ReplicationController) (*api.ReplicationController, error) { + if c.invalid { + return nil, kerrors.NewInvalid(controller.Kind, controller.Name, nil) + } return nil, errors.New("Replication controller update failure") } type ErrorReplicationControllerClient struct { testclient.Fake + invalid bool } func (c *ErrorReplicationControllerClient) ReplicationControllers(namespace string) client.ReplicationControllerInterface { - return &ErrorReplicationControllers{testclient.FakeReplicationControllers{Fake: &c.Fake, Namespace: namespace}} + return &ErrorReplicationControllers{testclient.FakeReplicationControllers{Fake: &c.Fake, Namespace: namespace}, c.invalid} +} + +type ErrorJobs struct { + testclient.FakeJobs + invalid bool +} + +func (c *ErrorJobs) Update(job *extensions.Job) (*extensions.Job, error) { + if c.invalid { + return nil, kerrors.NewInvalid(job.Kind, job.Name, nil) + } + return nil, errors.New("Job update failure") +} + +func (c *ErrorJobs) Get(name string) (*extensions.Job, error) { + zero := 0 + return &extensions.Job{ + Spec: extensions.JobSpec{ + Parallelism: &zero, + }, + }, nil +} + +type ErrorJobClient struct { + testclient.FakeExperimental + invalid bool +} + +func (c *ErrorJobClient) Jobs(namespace string) client.JobInterface { + return &ErrorJobs{testclient.FakeJobs{Fake: &c.FakeExperimental, Namespace: namespace}, c.invalid} +} + +type ErrorExtensionsClient struct { + testclient.Fake + invalid bool +} + +func (c *ErrorExtensionsClient) Extensions() client.ExtensionsInterface { + return &ErrorJobClient{testclient.FakeExperimental{&c.Fake}, c.invalid} } func TestReplicationControllerScaleRetry(t *testing.T) { - fake := &ErrorReplicationControllerClient{Fake: testclient.Fake{}} - scaler := ReplicationControllerScaler{NewScalerClient(fake)} + fake := &ErrorReplicationControllerClient{Fake: testclient.Fake{}, invalid: false} + scaler := ReplicationControllerScaler{fake} preconditions := ScalePrecondition{-1, ""} count := uint(3) name := "foo" @@ -51,7 +97,7 @@ func TestReplicationControllerScaleRetry(t *testing.T) { scaleFunc := ScaleCondition(&scaler, &preconditions, namespace, name, count) pass, err := scaleFunc() - if pass != false { + if pass { t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass) } if err != nil { @@ -65,9 +111,28 @@ func TestReplicationControllerScaleRetry(t *testing.T) { } } +func TestReplicationControllerScaleInvalid(t *testing.T) { + fake := &ErrorReplicationControllerClient{Fake: testclient.Fake{}, invalid: true} + scaler := ReplicationControllerScaler{fake} + preconditions := ScalePrecondition{-1, ""} + count := uint(3) + name := "foo" + namespace := "default" + + scaleFunc := ScaleCondition(&scaler, &preconditions, namespace, name, count) + pass, err := scaleFunc() + if pass { + t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass) + } + e, ok := err.(ControllerScaleError) + if err == nil || !ok || e.FailureType != ControllerScaleUpdateInvalidFailure { + t.Errorf("Expected error on invalid update failure, got %v", err) + } +} + func TestReplicationControllerScale(t *testing.T) { fake := &testclient.Fake{} - scaler := ReplicationControllerScaler{NewScalerClient(fake)} + scaler := ReplicationControllerScaler{fake} preconditions := ScalePrecondition{-1, ""} count := uint(3) name := "foo" @@ -91,7 +156,7 @@ func TestReplicationControllerScaleFailsPreconditions(t *testing.T) { Replicas: 10, }, }) - scaler := ReplicationControllerScaler{NewScalerClient(fake)} + scaler := ReplicationControllerScaler{fake} preconditions := ScalePrecondition{2, ""} count := uint(3) name := "foo" @@ -99,14 +164,14 @@ func TestReplicationControllerScaleFailsPreconditions(t *testing.T) { actions := fake.Actions() if len(actions) != 1 { - t.Errorf("unexpected actions: %v, expected 2 actions (get, update)", actions) + t.Errorf("unexpected actions: %v, expected 1 action (get)", actions) } if action, ok := actions[0].(testclient.GetAction); !ok || action.GetResource() != "replicationcontrollers" || action.GetName() != name { t.Errorf("unexpected action: %v, expected get-replicationController %s", actions[0], name) } } -func TestPreconditionValidate(t *testing.T) { +func TestValidateReplicationController(t *testing.T) { tests := []struct { preconditions ScalePrecondition controller api.ReplicationController @@ -211,7 +276,218 @@ func TestPreconditionValidate(t *testing.T) { }, } for _, test := range tests { - err := test.preconditions.Validate(&test.controller) + err := test.preconditions.ValidateReplicationController(&test.controller) + if err != nil && !test.expectError { + t.Errorf("unexpected error: %v (%s)", err, test.test) + } + if err == nil && test.expectError { + t.Errorf("unexpected non-error: %v (%s)", err, test.test) + } + } +} + +func TestJobScaleRetry(t *testing.T) { + fake := &ErrorExtensionsClient{Fake: testclient.Fake{}, invalid: false} + scaler := JobScaler{fake} + preconditions := ScalePrecondition{-1, ""} + count := uint(3) + name := "foo" + namespace := "default" + + scaleFunc := ScaleCondition(&scaler, &preconditions, namespace, name, count) + pass, err := scaleFunc() + if pass != false { + t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass) + } + if err != nil { + t.Errorf("Did not expect an error on update failure, got %v", err) + } + preconditions = ScalePrecondition{3, ""} + scaleFunc = ScaleCondition(&scaler, &preconditions, namespace, name, count) + pass, err = scaleFunc() + if err == nil { + t.Errorf("Expected error on precondition failure") + } +} + +func TestJobScale(t *testing.T) { + fake := &testclient.Fake{} + scaler := JobScaler{fake} + preconditions := ScalePrecondition{-1, ""} + count := uint(3) + name := "foo" + scaler.Scale("default", name, count, &preconditions, nil, nil) + + actions := fake.Actions() + if len(actions) != 2 { + t.Errorf("unexpected actions: %v, expected 2 actions (get, update)", actions) + } + if action, ok := actions[0].(testclient.GetAction); !ok || action.GetResource() != "jobs" || action.GetName() != name { + t.Errorf("unexpected action: %v, expected get-replicationController %s", actions[0], name) + } + if action, ok := actions[1].(testclient.UpdateAction); !ok || action.GetResource() != "jobs" || *action.GetObject().(*extensions.Job).Spec.Parallelism != int(count) { + t.Errorf("unexpected action %v, expected update-job with parallelism = %d", actions[1], count) + } +} + +func TestJobScaleInvalid(t *testing.T) { + fake := &ErrorExtensionsClient{Fake: testclient.Fake{}, invalid: true} + scaler := JobScaler{fake} + preconditions := ScalePrecondition{-1, ""} + count := uint(3) + name := "foo" + namespace := "default" + + scaleFunc := ScaleCondition(&scaler, &preconditions, namespace, name, count) + pass, err := scaleFunc() + if pass { + t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass) + } + e, ok := err.(ControllerScaleError) + if err == nil || !ok || e.FailureType != ControllerScaleUpdateInvalidFailure { + t.Errorf("Expected error on invalid update failure, got %v", err) + } +} + +func TestJobScaleFailsPreconditions(t *testing.T) { + ten := 10 + fake := testclient.NewSimpleFake(&extensions.Job{ + Spec: extensions.JobSpec{ + Parallelism: &ten, + }, + }) + scaler := JobScaler{fake} + preconditions := ScalePrecondition{2, ""} + count := uint(3) + name := "foo" + scaler.Scale("default", name, count, &preconditions, nil, nil) + + actions := fake.Actions() + if len(actions) != 1 { + t.Errorf("unexpected actions: %v, expected 1 actions (get)", actions) + } + if action, ok := actions[0].(testclient.GetAction); !ok || action.GetResource() != "jobs" || action.GetName() != name { + t.Errorf("unexpected action: %v, expected get-job %s", actions[0], name) + } +} + +func TestValidateJob(t *testing.T) { + zero, ten, twenty := 0, 10, 20 + tests := []struct { + preconditions ScalePrecondition + job extensions.Job + expectError bool + test string + }{ + { + preconditions: ScalePrecondition{-1, ""}, + expectError: false, + test: "defaults", + }, + { + preconditions: ScalePrecondition{-1, ""}, + job: extensions.Job{ + ObjectMeta: api.ObjectMeta{ + ResourceVersion: "foo", + }, + Spec: extensions.JobSpec{ + Parallelism: &ten, + }, + }, + expectError: false, + test: "defaults 2", + }, + { + preconditions: ScalePrecondition{0, ""}, + job: extensions.Job{ + ObjectMeta: api.ObjectMeta{ + ResourceVersion: "foo", + }, + Spec: extensions.JobSpec{ + Parallelism: &zero, + }, + }, + expectError: false, + test: "size matches", + }, + { + preconditions: ScalePrecondition{-1, "foo"}, + job: extensions.Job{ + ObjectMeta: api.ObjectMeta{ + ResourceVersion: "foo", + }, + Spec: extensions.JobSpec{ + Parallelism: &ten, + }, + }, + expectError: false, + test: "resource version matches", + }, + { + preconditions: ScalePrecondition{10, "foo"}, + job: extensions.Job{ + ObjectMeta: api.ObjectMeta{ + ResourceVersion: "foo", + }, + Spec: extensions.JobSpec{ + Parallelism: &ten, + }, + }, + expectError: false, + test: "both match", + }, + { + preconditions: ScalePrecondition{10, "foo"}, + job: extensions.Job{ + ObjectMeta: api.ObjectMeta{ + ResourceVersion: "foo", + }, + Spec: extensions.JobSpec{ + Parallelism: &twenty, + }, + }, + expectError: true, + test: "size different", + }, + { + preconditions: ScalePrecondition{10, "foo"}, + job: extensions.Job{ + ObjectMeta: api.ObjectMeta{ + ResourceVersion: "foo", + }, + }, + expectError: true, + test: "parallelism nil", + }, + { + preconditions: ScalePrecondition{10, "foo"}, + job: extensions.Job{ + ObjectMeta: api.ObjectMeta{ + ResourceVersion: "bar", + }, + Spec: extensions.JobSpec{ + Parallelism: &ten, + }, + }, + expectError: true, + test: "version different", + }, + { + preconditions: ScalePrecondition{10, "foo"}, + job: extensions.Job{ + ObjectMeta: api.ObjectMeta{ + ResourceVersion: "bar", + }, + Spec: extensions.JobSpec{ + Parallelism: &twenty, + }, + }, + expectError: true, + test: "both different", + }, + } + for _, test := range tests { + err := test.preconditions.ValidateJob(&test.job) if err != nil && !test.expectError { t.Errorf("unexpected error: %v (%s)", err, test.test) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/service.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/service.go index 172dc6721caf..edee6544913f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/service.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/service.go @@ -18,10 +18,11 @@ package kubectl import ( "fmt" + "strconv" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" - "strconv" ) // The only difference between ServiceGeneratorV1 and V2 is that the service port is named "default" in V1, while it is left unnamed in V2. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/sorted_event_list_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/sorted_event_list_test.go index e2434978181b..4d65a15dce8f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/sorted_event_list_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/sorted_event_list_test.go @@ -23,7 +23,7 @@ import ( "time" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) // VerifyDatesInOrder checks the start of each line for a RFC1123Z date @@ -57,22 +57,22 @@ func TestSortableEvents(t *testing.T) { { Source: api.EventSource{Component: "kubelet"}, Message: "Item 1", - FirstTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), - LastTimestamp: util.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + FirstTimestamp: unversioned.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + LastTimestamp: unversioned.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "scheduler"}, Message: "Item 2", - FirstTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), - LastTimestamp: util.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + FirstTimestamp: unversioned.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), + LastTimestamp: unversioned.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)), Count: 1, }, { Source: api.EventSource{Component: "kubelet"}, Message: "Item 3", - FirstTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), - LastTimestamp: util.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + FirstTimestamp: unversioned.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), + LastTimestamp: unversioned.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)), Count: 1, }, }) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/sorting_printer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/sorting_printer.go index 6b2cb7d687b3..2ec610d42840 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/sorting_printer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/sorting_printer.go @@ -22,9 +22,11 @@ import ( "reflect" "sort" - "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/jsonpath" + + "github.com/golang/glog" ) // Sorting printer sorts list types before delegating to another printer. @@ -36,7 +38,6 @@ type SortingPrinter struct { func (s *SortingPrinter) PrintObj(obj runtime.Object, out io.Writer) error { if !runtime.IsListType(obj) { - fmt.Fprintf(out, "Not a list, skipping: %#v\n", obj) return s.Delegate.PrintObj(obj, out) } @@ -61,6 +62,17 @@ func (s *SortingPrinter) sortObj(obj runtime.Object) error { } parser := jsonpath.New("sorting") parser.Parse(s.SortField) + + for ix := range objs { + item := objs[ix] + switch u := item.(type) { + case *runtime.Unknown: + var err error + if objs[ix], err = api.Codec.Decode(u.RawJSON); err != nil { + return err + } + } + } values, err := parser.FindResults(reflect.ValueOf(objs[0]).Elem().Interface()) if err != nil { return err @@ -130,7 +142,7 @@ func (r *RuntimeSort) Less(i, j int) bool { less, err := isLess(iField, jField) if err != nil { - glog.Fatalf("Field %s in %v is an unsortable type: %s", r.field, iObj, iField.Kind().String()) + glog.Fatalf("Field %s in %v is an unsortable type: %s, err: %v", r.field, iObj, iField.Kind().String(), err) } return less } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/stop.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/stop.go index bca8ff277d9e..f90452abc455 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/stop.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/stop.go @@ -24,7 +24,10 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/wait" ) const ( @@ -56,10 +59,14 @@ func ReaperFor(kind string, c client.Interface) (Reaper, error) { switch kind { case "ReplicationController": return &ReplicationControllerReaper{c, Interval, Timeout}, nil + case "DaemonSet": + return &DaemonSetReaper{c, Interval, Timeout}, nil case "Pod": return &PodReaper{c}, nil case "Service": return &ServiceReaper{c}, nil + case "Job": + return &JobReaper{c, Interval, Timeout}, nil } return nil, &NoSuchReaperError{kind} } @@ -72,6 +79,14 @@ type ReplicationControllerReaper struct { client.Interface pollInterval, timeout time.Duration } +type DaemonSetReaper struct { + client.Interface + pollInterval, timeout time.Duration +} +type JobReaper struct { + client.Interface + pollInterval, timeout time.Duration +} type PodReaper struct { client.Interface } @@ -86,7 +101,7 @@ type objInterface interface { // getOverlappingControllers finds rcs that this controller overlaps, as well as rcs overlapping this controller. func getOverlappingControllers(c client.ReplicationControllerInterface, rc *api.ReplicationController) ([]api.ReplicationController, error) { - rcs, err := c.List(labels.Everything()) + rcs, err := c.List(labels.Everything(), fields.Everything()) if err != nil { return nil, fmt.Errorf("error getting replication controllers: %v", err) } @@ -103,7 +118,7 @@ func getOverlappingControllers(c client.ReplicationControllerInterface, rc *api. func (reaper *ReplicationControllerReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) { rc := reaper.ReplicationControllers(namespace) - scaler, err := ScalerFor("ReplicationController", NewScalerClient(*reaper)) + scaler, err := ScalerFor("ReplicationController", *reaper) if err != nil { return "", err } @@ -167,6 +182,71 @@ func (reaper *ReplicationControllerReaper) Stop(namespace, name string, timeout return fmt.Sprintf("%s stopped", name), nil } +func (reaper *DaemonSetReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) { + ds, err := reaper.Extensions().DaemonSets(namespace).Get(name) + if err != nil { + return "", err + } + + // We set the nodeSelector to a random label. This label is nearly guaranteed + // to not be set on any node so the DameonSetController will start deleting + // daemon pods. Once it's done deleting the daemon pods, it's safe to delete + // the DaemonSet. + ds.Spec.Template.Spec.NodeSelector = map[string]string{ + string(util.NewUUID()): string(util.NewUUID()), + } + // force update to avoid version conflict + ds.ResourceVersion = "" + + if ds, err = reaper.Extensions().DaemonSets(namespace).Update(ds); err != nil { + return "", err + } + + // Wait for the daemon set controller to kill all the daemon pods. + if err := wait.Poll(reaper.pollInterval, reaper.timeout, func() (bool, error) { + updatedDS, err := reaper.Extensions().DaemonSets(namespace).Get(name) + if err != nil { + return false, nil + } + return updatedDS.Status.CurrentNumberScheduled+updatedDS.Status.NumberMisscheduled == 0, nil + }); err != nil { + return "", err + } + + if err := reaper.Extensions().DaemonSets(namespace).Delete(name); err != nil { + return "", err + } + return fmt.Sprintf("%s stopped", name), nil +} + +func (reaper *JobReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) { + jobs := reaper.Extensions().Jobs(namespace) + scaler, err := ScalerFor("Job", *reaper) + if err != nil { + return "", err + } + job, err := jobs.Get(name) + if err != nil { + return "", err + } + if timeout == 0 { + // we will never have more active pods than job.Spec.Parallelism + parallelism := *job.Spec.Parallelism + timeout = Timeout + time.Duration(10*parallelism)*time.Second + } + + // TODO: handle overlapping jobs + retry := NewRetryParams(reaper.pollInterval, reaper.timeout) + waitForJobs := NewRetryParams(reaper.pollInterval, timeout) + if err = scaler.Scale(namespace, name, 0, nil, retry, waitForJobs); err != nil { + return "", err + } + if err := jobs.Delete(name, gracePeriod); err != nil { + return "", err + } + return fmt.Sprintf("%s stopped", name), nil +} + func (reaper *PodReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) { pods := reaper.Pods(namespace) _, err := pods.Get(name) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/stop_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/stop_test.go index 705d7def2374..c640d7712daa 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/stop_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/stop_test.go @@ -23,6 +23,7 @@ import ( "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/runtime" @@ -271,6 +272,78 @@ func TestReplicationControllerStop(t *testing.T) { } } +func TestJobStop(t *testing.T) { + name := "foo" + ns := "default" + zero := 0 + tests := []struct { + Name string + Objs []runtime.Object + StopError error + StopMessage string + ExpectedActions []string + }{ + { + Name: "OnlyOneJob", + Objs: []runtime.Object{ + &extensions.Job{ // GET + ObjectMeta: api.ObjectMeta{ + Name: name, + Namespace: ns, + }, + Spec: extensions.JobSpec{ + Parallelism: &zero, + Selector: map[string]string{"k1": "v1"}}, + }, + &extensions.JobList{ // LIST + Items: []extensions.Job{ + { + ObjectMeta: api.ObjectMeta{ + Name: name, + Namespace: ns, + }, + Spec: extensions.JobSpec{ + Parallelism: &zero, + Selector: map[string]string{"k1": "v1"}}, + }, + }, + }, + }, + StopError: nil, + StopMessage: "foo stopped", + ExpectedActions: []string{"get", "get", "update", "get", "get", "delete"}, + }, + } + + for _, test := range tests { + fake := testclient.NewSimpleFake(test.Objs...) + reaper := JobReaper{fake, time.Millisecond, time.Millisecond} + s, err := reaper.Stop(ns, name, 0, nil) + if !reflect.DeepEqual(err, test.StopError) { + t.Errorf("%s unexpected error: %v", test.Name, err) + continue + } + + if s != test.StopMessage { + t.Errorf("%s expected '%s', got '%s'", test.Name, test.StopMessage, s) + continue + } + actions := fake.Actions() + if len(actions) != len(test.ExpectedActions) { + t.Errorf("%s unexpected actions: %v, expected %d actions got %d", test.Name, actions, len(test.ExpectedActions), len(actions)) + continue + } + for i, verb := range test.ExpectedActions { + if actions[i].GetResource() != "jobs" { + t.Errorf("%s unexpected action: %+v, expected %s-job", test.Name, actions[i], verb) + } + if actions[i].GetVerb() != verb { + t.Errorf("%s unexpected action: %+v, expected %s-job", test.Name, actions[i], verb) + } + } + } +} + type noSuchPod struct { *testclient.FakePods } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/testing/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/testing/types.go new file mode 100644 index 000000000000..8eefd437c2e9 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/testing/types.go @@ -0,0 +1,33 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 testing + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" +) + +type TestStruct struct { + unversioned.TypeMeta `json:",inline"` + api.ObjectMeta `json:"metadata,omitempty"` + Key string `json:"Key"` + Map map[string]int `json:"Map"` + StringList []string `json:"StringList"` + IntList []int `json:"IntList"` +} + +func (ts *TestStruct) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go index c441b3f0d553..fa01dca30352 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go @@ -22,7 +22,7 @@ import ( "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" - "k8s.io/kubernetes/pkg/kubelet" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) // NewSourceApiserver creates a config source that watches and pulls from the apiserver. @@ -38,7 +38,7 @@ func newSourceApiserverFromLW(lw cache.ListerWatcher, updates chan<- interface{} for _, o := range objs { pods = append(pods, o.(*api.Pod)) } - updates <- kubelet.PodUpdate{Pods: pods, Op: kubelet.SET, Source: kubelet.ApiserverSource} + updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.ApiserverSource} } cache.NewReflector(lw, &api.Pod{}, cache.NewUndeltaStore(send, cache.MetaNamespaceKeyFunc), 0).Run() } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/apiserver_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/apiserver_test.go index 11b3f9828764..8563df66d525 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/apiserver_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/apiserver_test.go @@ -21,7 +21,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/client/cache" - "k8s.io/kubernetes/pkg/kubelet" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/watch" ) @@ -67,8 +67,8 @@ func TestNewSourceApiserver_UpdatesAndMultiplePods(t *testing.T) { if !ok { t.Errorf("Unable to read from channel when expected") } - update := got.(kubelet.PodUpdate) - expected := CreatePodUpdate(kubelet.SET, kubelet.ApiserverSource, pod1v1) + update := got.(kubetypes.PodUpdate) + expected := CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod1v1) if !api.Semantic.DeepEqual(expected, update) { t.Errorf("Expected %#v; Got %#v", expected, update) } @@ -79,10 +79,10 @@ func TestNewSourceApiserver_UpdatesAndMultiplePods(t *testing.T) { if !ok { t.Errorf("Unable to read from channel when expected") } - update = got.(kubelet.PodUpdate) + update = got.(kubetypes.PodUpdate) // Could be sorted either of these two ways: - expectedA := CreatePodUpdate(kubelet.SET, kubelet.ApiserverSource, pod1v1, pod2) - expectedB := CreatePodUpdate(kubelet.SET, kubelet.ApiserverSource, pod2, pod1v1) + expectedA := CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod1v1, pod2) + expectedB := CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod2, pod1v1) if !api.Semantic.DeepEqual(expectedA, update) && !api.Semantic.DeepEqual(expectedB, update) { t.Errorf("Expected %#v or %#v, Got %#v", expectedA, expectedB, update) @@ -94,9 +94,9 @@ func TestNewSourceApiserver_UpdatesAndMultiplePods(t *testing.T) { if !ok { t.Errorf("Unable to read from channel when expected") } - update = got.(kubelet.PodUpdate) - expectedA = CreatePodUpdate(kubelet.SET, kubelet.ApiserverSource, pod1v2, pod2) - expectedB = CreatePodUpdate(kubelet.SET, kubelet.ApiserverSource, pod2, pod1v2) + update = got.(kubetypes.PodUpdate) + expectedA = CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod1v2, pod2) + expectedB = CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod2, pod1v2) if !api.Semantic.DeepEqual(expectedA, update) && !api.Semantic.DeepEqual(expectedB, update) { t.Errorf("Expected %#v or %#v, Got %#v", expectedA, expectedB, update) @@ -108,8 +108,8 @@ func TestNewSourceApiserver_UpdatesAndMultiplePods(t *testing.T) { if !ok { t.Errorf("Unable to read from channel when expected") } - update = got.(kubelet.PodUpdate) - expected = CreatePodUpdate(kubelet.SET, kubelet.ApiserverSource, pod2) + update = got.(kubetypes.PodUpdate) + expected = CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource, pod2) if !api.Semantic.DeepEqual(expected, update) { t.Errorf("Expected %#v, Got %#v", expected, update) } @@ -120,8 +120,8 @@ func TestNewSourceApiserver_UpdatesAndMultiplePods(t *testing.T) { if !ok { t.Errorf("Unable to read from channel when expected") } - update = got.(kubelet.PodUpdate) - expected = CreatePodUpdate(kubelet.SET, kubelet.ApiserverSource) + update = got.(kubetypes.PodUpdate) + expected = CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource) if !api.Semantic.DeepEqual(expected, update) { t.Errorf("Expected %#v, Got %#v", expected, update) } @@ -150,7 +150,7 @@ func TestNewSourceApiserver_TwoNamespacesSameName(t *testing.T) { if !ok { t.Errorf("Unable to read from channel when expected") } - update := got.(kubelet.PodUpdate) + update := got.(kubetypes.PodUpdate) // Make sure that we get both pods. Catches bug #2294. if !(len(update.Pods) == 2) { t.Errorf("Expected %d, Got %d", 2, len(update.Pods)) @@ -162,7 +162,7 @@ func TestNewSourceApiserver_TwoNamespacesSameName(t *testing.T) { if !ok { t.Errorf("Unable to read from channel when expected") } - update = got.(kubelet.PodUpdate) + update = got.(kubetypes.PodUpdate) if !(len(update.Pods) == 1) { t.Errorf("Expected %d, Got %d", 1, len(update.Pods)) } @@ -184,8 +184,8 @@ func TestNewSourceApiserverInitialEmptySendsEmptyPodUpdate(t *testing.T) { if !ok { t.Errorf("Unable to read from channel when expected") } - update := got.(kubelet.PodUpdate) - expected := CreatePodUpdate(kubelet.SET, kubelet.ApiserverSource) + update := got.(kubetypes.PodUpdate) + expected := CreatePodUpdate(kubetypes.SET, kubetypes.ApiserverSource) if !api.Semantic.DeepEqual(expected, update) { t.Errorf("Expected %#v; Got %#v", expected, update) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/common.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/common.go index b1f075b3befe..207f80990d02 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/common.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/common.go @@ -25,7 +25,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/validation" - "k8s.io/kubernetes/pkg/kubelet" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" utilyaml "k8s.io/kubernetes/pkg/util/yaml" @@ -56,7 +56,7 @@ func applyDefaults(pod *api.Pod, source string, isFile bool, nodeName string) er glog.V(5).Infof("Generated Name %q for UID %q from URL %s", pod.Name, pod.UID, source) if pod.Namespace == "" { - pod.Namespace = kubelet.NamespaceDefault + pod.Namespace = kubetypes.NamespaceDefault } glog.V(5).Infof("Using namespace %q for pod %q from %s", pod.Namespace, pod.Name, source) @@ -72,7 +72,7 @@ func getSelfLink(name, namespace string) string { if len(namespace) == 0 { namespace = api.NamespaceDefault } - selfLink = fmt.Sprintf("/api/"+latest.Version+"/pods/namespaces/%s/%s", name, namespace) + selfLink = fmt.Sprintf("/api/"+latest.GroupOrDie("").Version+"/pods/namespaces/%s/%s", name, namespace) return selfLink } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/common_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/common_test.go index ccfb88effaa3..65f4a17b6bf5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/common_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/common_test.go @@ -23,6 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/registered" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/securitycontext" "github.com/ghodss/yaml" @@ -33,7 +34,7 @@ func noDefault(*api.Pod) error { return nil } func TestDecodeSinglePod(t *testing.T) { grace := int64(30) pod := &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ APIVersion: "", }, ObjectMeta: api.ObjectMeta{ @@ -52,6 +53,7 @@ func TestDecodeSinglePod(t *testing.T) { TerminationMessagePath: "/dev/termination-log", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }}, + SecurityContext: &api.PodSecurityContext{}, }, } json, err := testapi.Default.Codec().Encode(pod) @@ -69,7 +71,7 @@ func TestDecodeSinglePod(t *testing.T) { t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(json)) } - for _, version := range registered.RegisteredVersions { + for _, version := range registered.GroupVersionsForGroup("") { externalPod, err := testapi.Default.Converter().ConvertToVersion(pod, version) if err != nil { t.Errorf("unexpected error: %v", err) @@ -95,7 +97,7 @@ func TestDecodeSinglePod(t *testing.T) { func TestDecodePodList(t *testing.T) { grace := int64(30) pod := &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ APIVersion: "", }, ObjectMeta: api.ObjectMeta{ @@ -114,6 +116,7 @@ func TestDecodePodList(t *testing.T) { TerminationMessagePath: "/dev/termination-log", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }}, + SecurityContext: &api.PodSecurityContext{}, }, } podList := &api.PodList{ @@ -134,7 +137,7 @@ func TestDecodePodList(t *testing.T) { t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", podList, &podListOut, string(json)) } - for _, version := range registered.RegisteredVersions { + for _, version := range registered.GroupVersionsForGroup("") { externalPodList, err := testapi.Default.Converter().ConvertToVersion(podList, version) if err != nil { t.Errorf("unexpected error: %v", err) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config.go index d010be058c28..123ea71919cc 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config.go @@ -25,11 +25,9 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/client/record" - "k8s.io/kubernetes/pkg/kubelet" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - kubeletTypes "k8s.io/kubernetes/pkg/kubelet/types" - kubeletUtil "k8s.io/kubernetes/pkg/kubelet/util" - "k8s.io/kubernetes/pkg/util" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" + kubeletutil "k8s.io/kubernetes/pkg/kubelet/util" "k8s.io/kubernetes/pkg/util/config" utilerrors "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/fielderrors" @@ -40,9 +38,12 @@ import ( type PodConfigNotificationMode int const ( + // PodConfigNotificationUnknown is the default value for + // PodConfigNotificationMode when uninitialized. + PodConfigNotificationUnknown = iota // PodConfigNotificationSnapshot delivers the full configuration as a SET whenever // any change occurs. - PodConfigNotificationSnapshot = iota + PodConfigNotificationSnapshot // PodConfigNotificationSnapshotAndUpdates delivers an UPDATE message whenever pods are // changed, and a SET message if there are any additions or removals. PodConfigNotificationSnapshotAndUpdates @@ -58,9 +59,7 @@ type PodConfig struct { mux *config.Mux // the channel of denormalized changes passed to listeners - updates chan kubelet.PodUpdate - // an optional wait channel - wait <-chan struct{} + updates chan kubetypes.PodUpdate // contains the list of all configured sources sourcesLock sync.Mutex @@ -70,7 +69,7 @@ type PodConfig struct { // NewPodConfig creates an object that can merge many configuration sources into a stream // of normalized updates to a pod configuration. func NewPodConfig(mode PodConfigNotificationMode, recorder record.EventRecorder) *PodConfig { - updates := make(chan kubelet.PodUpdate, 50) + updates := make(chan kubetypes.PodUpdate, 50) storage := newPodStorage(updates, mode, recorder) podConfig := &PodConfig{ pods: storage, @@ -81,20 +80,6 @@ func NewPodConfig(mode PodConfigNotificationMode, recorder record.EventRecorder) return podConfig } -func (c *PodConfig) Wait(waitCh <-chan struct{}) { - c.wait = waitCh - ch := make(chan kubelet.PodUpdate) - oldCh := c.updates - go util.Forever(func() { - <-waitCh - for { - update := <-oldCh - ch <- update - } - }, 0) - c.updates = ch -} - // Channel creates or returns a config source channel. The channel // only accepts PodUpdates func (c *PodConfig) Channel(source string) chan<- interface{} { @@ -104,25 +89,18 @@ func (c *PodConfig) Channel(source string) chan<- interface{} { return c.mux.Channel(source) } -// SeenAllSources returns true if this config has received a SET -// message from all configured sources, false otherwise. -func (c *PodConfig) SeenAllSources() bool { +// SeenAllSources returns true if seenSources contains all sources in the +// config, and also this config has received a SET message from each source. +func (c *PodConfig) SeenAllSources(seenSources sets.String) bool { if c.pods == nil { return false } - if c.wait != nil { - select { - case <-c.wait: - default: - return false - } - } - glog.V(6).Infof("Looking for %v, have seen %v", c.sources.List(), c.pods.sourcesSeen) - return c.pods.seenSources(c.sources.List()...) + glog.V(6).Infof("Looking for %v, have seen %v", c.sources.List(), seenSources) + return seenSources.HasAll(c.sources.List()...) && c.pods.seenSources(c.sources.List()...) } // Updates returns a channel of updates to the configuration, properly denormalized. -func (c *PodConfig) Updates() <-chan kubelet.PodUpdate { +func (c *PodConfig) Updates() <-chan kubetypes.PodUpdate { return c.updates } @@ -144,7 +122,7 @@ type podStorage struct { // ensures that updates are delivered in strict order // on the updates channel updateLock sync.Mutex - updates chan<- kubelet.PodUpdate + updates chan<- kubetypes.PodUpdate // contains the set of all sources that have sent at least one SET sourcesSeenLock sync.Mutex @@ -157,7 +135,7 @@ type podStorage struct { // TODO: PodConfigNotificationMode could be handled by a listener to the updates channel // in the future, especially with multiple listeners. // TODO: allow initialization of the current state of the store with snapshotted version. -func newPodStorage(updates chan<- kubelet.PodUpdate, mode PodConfigNotificationMode, recorder record.EventRecorder) *podStorage { +func newPodStorage(updates chan<- kubetypes.PodUpdate, mode PodConfigNotificationMode, recorder record.EventRecorder) *podStorage { return &podStorage{ pods: make(map[string]map[string]*api.Pod), mode: mode, @@ -194,14 +172,16 @@ func (s *podStorage) Merge(source string, change interface{}) error { s.updates <- *updates } if len(deletes.Pods) > 0 || len(adds.Pods) > 0 { - s.updates <- kubelet.PodUpdate{Pods: s.MergedState().([]*api.Pod), Op: kubelet.SET, Source: source} + s.updates <- kubetypes.PodUpdate{Pods: s.MergedState().([]*api.Pod), Op: kubetypes.SET, Source: source} } case PodConfigNotificationSnapshot: if len(updates.Pods) > 0 || len(deletes.Pods) > 0 || len(adds.Pods) > 0 { - s.updates <- kubelet.PodUpdate{Pods: s.MergedState().([]*api.Pod), Op: kubelet.SET, Source: source} + s.updates <- kubetypes.PodUpdate{Pods: s.MergedState().([]*api.Pod), Op: kubetypes.SET, Source: source} } + case PodConfigNotificationUnknown: + fallthrough default: panic(fmt.Sprintf("unsupported PodConfigNotificationMode: %#v", s.mode)) } @@ -209,29 +189,23 @@ func (s *podStorage) Merge(source string, change interface{}) error { return nil } -// recordFirstSeenTime records the first seen time of this pod. -func recordFirstSeenTime(pod *api.Pod) { - glog.V(4).Infof("Receiving a new pod %q", kubeletUtil.FormatPodName(pod)) - pod.Annotations[kubelet.ConfigFirstSeenAnnotationKey] = kubeletTypes.NewTimestamp().GetString() -} - -func (s *podStorage) merge(source string, change interface{}) (adds, updates, deletes *kubelet.PodUpdate) { +func (s *podStorage) merge(source string, change interface{}) (adds, updates, deletes *kubetypes.PodUpdate) { s.podLock.Lock() defer s.podLock.Unlock() - adds = &kubelet.PodUpdate{Op: kubelet.ADD} - updates = &kubelet.PodUpdate{Op: kubelet.UPDATE} - deletes = &kubelet.PodUpdate{Op: kubelet.REMOVE} + adds = &kubetypes.PodUpdate{Op: kubetypes.ADD, Source: source} + updates = &kubetypes.PodUpdate{Op: kubetypes.UPDATE, Source: source} + deletes = &kubetypes.PodUpdate{Op: kubetypes.REMOVE, Source: source} pods := s.pods[source] if pods == nil { pods = make(map[string]*api.Pod) } - update := change.(kubelet.PodUpdate) + update := change.(kubetypes.PodUpdate) switch update.Op { - case kubelet.ADD, kubelet.UPDATE: - if update.Op == kubelet.ADD { + case kubetypes.ADD, kubetypes.UPDATE: + if update.Op == kubetypes.ADD { glog.V(4).Infof("Adding new pods from source %s : %v", source, update.Pods) } else { glog.V(4).Infof("Updating pods from source %s : %v", source, update.Pods) @@ -240,6 +214,11 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de filtered := filterInvalidPods(update.Pods, source, s.recorder) for _, ref := range filtered { name := kubecontainer.GetPodFullName(ref) + // Annotate the pod with the source before any comparison. + if ref.Annotations == nil { + ref.Annotations = make(map[string]string) + } + ref.Annotations[kubetypes.ConfigSourceAnnotationKey] = source if existing, found := pods[name]; found { if checkAndUpdatePod(existing, ref) { // this is an update @@ -250,16 +229,12 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de continue } // this is an add - if ref.Annotations == nil { - ref.Annotations = make(map[string]string) - } - ref.Annotations[kubelet.ConfigSourceAnnotationKey] = source recordFirstSeenTime(ref) pods[name] = ref adds.Pods = append(adds.Pods, ref) } - case kubelet.REMOVE: + case kubetypes.REMOVE: glog.V(4).Infof("Removing a pod %v", update) for _, value := range update.Pods { name := kubecontainer.GetPodFullName(value) @@ -272,7 +247,7 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de // this is a no-op } - case kubelet.SET: + case kubetypes.SET: glog.V(4).Infof("Setting pods for source %s", source) s.markSourceSet(source) // Clear the old map entries by just creating a new map @@ -282,6 +257,11 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de filtered := filterInvalidPods(update.Pods, source, s.recorder) for _, ref := range filtered { name := kubecontainer.GetPodFullName(ref) + // Annotate the pod with the source before any comparison. + if ref.Annotations == nil { + ref.Annotations = make(map[string]string) + } + ref.Annotations[kubetypes.ConfigSourceAnnotationKey] = source if existing, found := oldPods[name]; found { pods[name] = existing if checkAndUpdatePod(existing, ref) { @@ -292,10 +272,6 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de // this is a no-op continue } - if ref.Annotations == nil { - ref.Annotations = make(map[string]string) - } - ref.Annotations[kubelet.ConfigSourceAnnotationKey] = source recordFirstSeenTime(ref) pods[name] = ref adds.Pods = append(adds.Pods, ref) @@ -359,9 +335,9 @@ func filterInvalidPods(pods []*api.Pod, source string, recorder record.EventReco // Annotations that the kubelet adds to the pod. var localAnnotations = []string{ - kubelet.ConfigSourceAnnotationKey, - kubelet.ConfigMirrorAnnotationKey, - kubelet.ConfigFirstSeenAnnotationKey, + kubetypes.ConfigSourceAnnotationKey, + kubetypes.ConfigMirrorAnnotationKey, + kubetypes.ConfigFirstSeenAnnotationKey, } func isLocalAnnotationKey(key string) bool { @@ -377,9 +353,12 @@ func isLocalAnnotationKey(key string) bool { // for local annotations. func isAnnotationMapEqual(existingMap, candidateMap map[string]string) bool { if candidateMap == nil { - return true + candidateMap = make(map[string]string) } for k, v := range candidateMap { + if isLocalAnnotationKey(k) { + continue + } if existingValue, ok := existingMap[k]; ok && existingValue == v { continue } @@ -397,6 +376,12 @@ func isAnnotationMapEqual(existingMap, candidateMap map[string]string) bool { return true } +// recordFirstSeenTime records the first seen time of this pod. +func recordFirstSeenTime(pod *api.Pod) { + glog.V(4).Infof("Receiving a new pod %q", kubeletutil.FormatPodName(pod)) + pod.Annotations[kubetypes.ConfigFirstSeenAnnotationKey] = kubetypes.NewTimestamp().GetString() +} + // updateAnnotations returns an Annotation map containing the api annotation map plus // locally managed annotations func updateAnnotations(existing, ref *api.Pod) { @@ -412,19 +397,33 @@ func updateAnnotations(existing, ref *api.Pod) { existing.Annotations = annotations } +func podsDifferSemantically(existing, ref *api.Pod) bool { + if reflect.DeepEqual(existing.Spec, ref.Spec) && + reflect.DeepEqual(existing.Labels, ref.Labels) && + reflect.DeepEqual(existing.DeletionTimestamp, ref.DeletionTimestamp) && + reflect.DeepEqual(existing.DeletionGracePeriodSeconds, ref.DeletionGracePeriodSeconds) && + isAnnotationMapEqual(existing.Annotations, ref.Annotations) { + return false + } + return true +} + // checkAndUpdatePod updates existing if ref makes a meaningful change and returns true, or // returns false if there was no update. func checkAndUpdatePod(existing, ref *api.Pod) bool { // TODO: it would be better to update the whole object and only preserve certain things // like the source annotation or the UID (to ensure safety) - if reflect.DeepEqual(existing.Spec, ref.Spec) && - reflect.DeepEqual(existing.DeletionTimestamp, ref.DeletionTimestamp) && - reflect.DeepEqual(existing.DeletionGracePeriodSeconds, ref.DeletionGracePeriodSeconds) && - isAnnotationMapEqual(existing.Annotations, ref.Annotations) { + if !podsDifferSemantically(existing, ref) { return false } // this is an update + + // Overwrite the first-seen time with the existing one. This is our own + // internal annotation, there is no need to update. + ref.Annotations[kubetypes.ConfigFirstSeenAnnotationKey] = existing.Annotations[kubetypes.ConfigFirstSeenAnnotationKey] + existing.Spec = ref.Spec + existing.Labels = ref.Labels existing.DeletionTimestamp = ref.DeletionTimestamp existing.DeletionGracePeriodSeconds = ref.DeletionGracePeriodSeconds updateAnnotations(existing, ref) @@ -435,7 +434,7 @@ func checkAndUpdatePod(existing, ref *api.Pod) bool { func (s *podStorage) Sync() { s.updateLock.Lock() defer s.updateLock.Unlock() - s.updates <- kubelet.PodUpdate{Pods: s.MergedState().([]*api.Pod), Op: kubelet.SET, Source: kubelet.AllSource} + s.updates <- kubetypes.PodUpdate{Pods: s.MergedState().([]*api.Pod), Op: kubetypes.SET, Source: kubetypes.AllSource} } // Object implements config.Accessor diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config_test.go index fac24eca7ab5..00f9007db999 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config_test.go @@ -23,13 +23,12 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/client/record" "k8s.io/kubernetes/pkg/conversion" - "k8s.io/kubernetes/pkg/kubelet" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/types" ) const ( - NoneSource = "" TestSource = "test" ) @@ -53,7 +52,7 @@ func (s sortedPods) Less(i, j int) bool { return s[i].Namespace < s[j].Namespace } -func CreateValidPod(name, namespace, source string) *api.Pod { +func CreateValidPod(name, namespace string) *api.Pod { return &api.Pod{ ObjectMeta: api.ObjectMeta{ UID: types.UID(name), // for the purpose of testing, this is unique enough @@ -75,11 +74,11 @@ func CreateValidPod(name, namespace, source string) *api.Pod { } } -func CreatePodUpdate(op kubelet.PodOperation, source string, pods ...*api.Pod) kubelet.PodUpdate { - return kubelet.PodUpdate{Pods: pods, Op: op, Source: source} +func CreatePodUpdate(op kubetypes.PodOperation, source string, pods ...*api.Pod) kubetypes.PodUpdate { + return kubetypes.PodUpdate{Pods: pods, Op: op, Source: source} } -func createPodConfigTester(mode PodConfigNotificationMode) (chan<- interface{}, <-chan kubelet.PodUpdate, *PodConfig) { +func createPodConfigTester(mode PodConfigNotificationMode) (chan<- interface{}, <-chan kubetypes.PodUpdate, *PodConfig) { eventBroadcaster := record.NewBroadcaster() config := NewPodConfig(mode, eventBroadcaster.NewRecorder(api.EventSource{Component: "kubelet"})) channel := config.Channel(TestSource) @@ -87,28 +86,34 @@ func createPodConfigTester(mode PodConfigNotificationMode) (chan<- interface{}, return channel, ch, config } -func expectPodUpdate(t *testing.T, ch <-chan kubelet.PodUpdate, expected ...kubelet.PodUpdate) { +func expectPodUpdate(t *testing.T, ch <-chan kubetypes.PodUpdate, expected ...kubetypes.PodUpdate) { for i := range expected { update := <-ch sort.Sort(sortedPods(update.Pods)) - // Clear the annotation field before the comparison. - // TODO: consider mock out recordFirstSeen in config.go - for _, pod := range update.Pods { - delete(pod.Annotations, kubelet.ConfigFirstSeenAnnotationKey) - delete(pod.Annotations, kubelet.ConfigSourceAnnotationKey) + sort.Sort(sortedPods(expected[i].Pods)) + // Make copies of the expected/actual update to compare all fields + // except for "Pods", which are compared separately below. + expectedCopy, updateCopy := expected[i], update + expectedCopy.Pods, updateCopy.Pods = nil, nil + if !api.Semantic.DeepEqual(expectedCopy, updateCopy) { + t.Fatalf("Expected %#v, Got %#v", expectedCopy, updateCopy) } - for _, pod := range expected[i].Pods { - delete(pod.Annotations, kubelet.ConfigFirstSeenAnnotationKey) - delete(pod.Annotations, kubelet.ConfigSourceAnnotationKey) - } - if !api.Semantic.DeepEqual(expected[i], update) { + + if len(expected[i].Pods) != len(update.Pods) { t.Fatalf("Expected %#v, Got %#v", expected[i], update) } + // Compare pods one by one. This is necessary beacuse we don't want to + // compare local annotations. + for j := range expected[i].Pods { + if podsDifferSemantically(expected[i].Pods[j], update.Pods[j]) { + t.Fatalf("Expected %#v, Got %#v", expected[i].Pods[j], update.Pods[j]) + } + } } expectNoPodUpdate(t, ch) } -func expectNoPodUpdate(t *testing.T, ch <-chan kubelet.PodUpdate) { +func expectNoPodUpdate(t *testing.T, ch <-chan kubetypes.PodUpdate) { select { case update := <-ch: t.Errorf("Expected no update in channel, Got %#v", update) @@ -120,63 +125,63 @@ func TestNewPodAdded(t *testing.T) { channel, ch, config := createPodConfigTester(PodConfigNotificationIncremental) // see an update - podUpdate := CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", "")) + podUpdate := CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new"))) config.Sync() - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.SET, kubelet.AllSource, CreateValidPod("foo", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, kubetypes.AllSource, CreateValidPod("foo", "new"))) } func TestNewPodAddedInvalidNamespace(t *testing.T) { channel, ch, config := createPodConfigTester(PodConfigNotificationIncremental) // see an update - podUpdate := CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "", "")) + podUpdate := CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "")) channel <- podUpdate config.Sync() - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.SET, kubelet.AllSource)) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, kubetypes.AllSource)) } func TestNewPodAddedDefaultNamespace(t *testing.T) { channel, ch, config := createPodConfigTester(PodConfigNotificationIncremental) // see an update - podUpdate := CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "default", "")) + podUpdate := CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "default")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "default", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "default"))) config.Sync() - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.SET, kubelet.AllSource, CreateValidPod("foo", "default", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, kubetypes.AllSource, CreateValidPod("foo", "default"))) } func TestNewPodAddedDifferentNamespaces(t *testing.T) { channel, ch, config := createPodConfigTester(PodConfigNotificationIncremental) // see an update - podUpdate := CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "default", "")) + podUpdate := CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "default")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "default", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "default"))) // see an update in another namespace - podUpdate = CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", "")) + podUpdate = CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new"))) config.Sync() - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.SET, kubelet.AllSource, CreateValidPod("foo", "default", "test"), CreateValidPod("foo", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, kubetypes.AllSource, CreateValidPod("foo", "default"), CreateValidPod("foo", "new"))) } func TestInvalidPodFiltered(t *testing.T) { channel, ch, _ := createPodConfigTester(PodConfigNotificationIncremental) // see an update - podUpdate := CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", "")) + podUpdate := CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new"))) // add an invalid update - podUpdate = CreatePodUpdate(kubelet.UPDATE, NoneSource, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}) + podUpdate = CreatePodUpdate(kubetypes.UPDATE, TestSource, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}) channel <- podUpdate expectNoPodUpdate(t, ch) } @@ -185,87 +190,87 @@ func TestNewPodAddedSnapshotAndUpdates(t *testing.T) { channel, ch, config := createPodConfigTester(PodConfigNotificationSnapshotAndUpdates) // see an set - podUpdate := CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", "")) + podUpdate := CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.SET, TestSource, CreateValidPod("foo", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, TestSource, CreateValidPod("foo", "new"))) config.Sync() - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.SET, kubelet.AllSource, CreateValidPod("foo", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, kubetypes.AllSource, CreateValidPod("foo", "new"))) // container updates are separated as UPDATE pod := *podUpdate.Pods[0] pod.Spec.Containers = []api.Container{{Name: "bar", Image: "test", ImagePullPolicy: api.PullIfNotPresent}} - channel <- CreatePodUpdate(kubelet.ADD, NoneSource, &pod) - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.UPDATE, NoneSource, &pod)) + channel <- CreatePodUpdate(kubetypes.ADD, TestSource, &pod) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.UPDATE, TestSource, &pod)) } func TestNewPodAddedSnapshot(t *testing.T) { channel, ch, config := createPodConfigTester(PodConfigNotificationSnapshot) // see an set - podUpdate := CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", "")) + podUpdate := CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.SET, TestSource, CreateValidPod("foo", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, TestSource, CreateValidPod("foo", "new"))) config.Sync() - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.SET, kubelet.AllSource, CreateValidPod("foo", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, kubetypes.AllSource, CreateValidPod("foo", "new"))) // container updates are separated as UPDATE pod := *podUpdate.Pods[0] pod.Spec.Containers = []api.Container{{Name: "bar", Image: "test", ImagePullPolicy: api.PullIfNotPresent}} - channel <- CreatePodUpdate(kubelet.ADD, NoneSource, &pod) - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.SET, TestSource, &pod)) + channel <- CreatePodUpdate(kubetypes.ADD, TestSource, &pod) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, TestSource, &pod)) } func TestNewPodAddedUpdatedRemoved(t *testing.T) { channel, ch, _ := createPodConfigTester(PodConfigNotificationIncremental) // should register an add - podUpdate := CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", "")) + podUpdate := CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new"))) // should ignore ADDs that are identical expectNoPodUpdate(t, ch) - // an kubelet.ADD should be converted to kubelet.UPDATE - pod := CreateValidPod("foo", "new", "test") + // an kubetypes.ADD should be converted to kubetypes.UPDATE + pod := CreateValidPod("foo", "new") pod.Spec.Containers = []api.Container{{Name: "bar", Image: "test", ImagePullPolicy: api.PullIfNotPresent}} - podUpdate = CreatePodUpdate(kubelet.ADD, NoneSource, pod) + podUpdate = CreatePodUpdate(kubetypes.ADD, TestSource, pod) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.UPDATE, NoneSource, pod)) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.UPDATE, TestSource, pod)) - podUpdate = CreatePodUpdate(kubelet.REMOVE, NoneSource, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "new"}}) + podUpdate = CreatePodUpdate(kubetypes.REMOVE, TestSource, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "new"}}) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.REMOVE, NoneSource, pod)) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.REMOVE, TestSource, pod)) } func TestNewPodAddedUpdatedSet(t *testing.T) { channel, ch, _ := createPodConfigTester(PodConfigNotificationIncremental) // should register an add - podUpdate := CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", ""), CreateValidPod("foo2", "new", ""), CreateValidPod("foo3", "new", "")) + podUpdate := CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new"), CreateValidPod("foo2", "new"), CreateValidPod("foo3", "new")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo", "new", "test"), CreateValidPod("foo2", "new", "test"), CreateValidPod("foo3", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "new"), CreateValidPod("foo2", "new"), CreateValidPod("foo3", "new"))) // should ignore ADDs that are identical expectNoPodUpdate(t, ch) - // should be converted to an kubelet.ADD, kubelet.REMOVE, and kubelet.UPDATE - pod := CreateValidPod("foo2", "new", "test") + // should be converted to an kubetypes.ADD, kubetypes.REMOVE, and kubetypes.UPDATE + pod := CreateValidPod("foo2", "new") pod.Spec.Containers = []api.Container{{Name: "bar", Image: "test", ImagePullPolicy: api.PullIfNotPresent}} - podUpdate = CreatePodUpdate(kubelet.SET, NoneSource, pod, CreateValidPod("foo3", "new", ""), CreateValidPod("foo4", "new", "test")) + podUpdate = CreatePodUpdate(kubetypes.SET, TestSource, pod, CreateValidPod("foo3", "new"), CreateValidPod("foo4", "new")) channel <- podUpdate expectPodUpdate(t, ch, - CreatePodUpdate(kubelet.REMOVE, NoneSource, CreateValidPod("foo", "new", "test")), - CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo4", "new", "test")), - CreatePodUpdate(kubelet.UPDATE, NoneSource, pod)) + CreatePodUpdate(kubetypes.REMOVE, TestSource, CreateValidPod("foo", "new")), + CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo4", "new")), + CreatePodUpdate(kubetypes.UPDATE, TestSource, pod)) } func TestPodUpdateAnnotations(t *testing.T) { channel, ch, _ := createPodConfigTester(PodConfigNotificationIncremental) - pod := CreateValidPod("foo2", "new", "test") + pod := CreateValidPod("foo2", "new") pod.Annotations = make(map[string]string, 0) pod.Annotations["kubernetes.io/blah"] = "blah" @@ -274,22 +279,45 @@ func TestPodUpdateAnnotations(t *testing.T) { t.Fatalf("%v", err) } - podUpdate := CreatePodUpdate(kubelet.SET, NoneSource, CreateValidPod("foo1", "new", "test"), clone.(*api.Pod), CreateValidPod("foo3", "new", "test")) + podUpdate := CreatePodUpdate(kubetypes.SET, TestSource, CreateValidPod("foo1", "new"), clone.(*api.Pod), CreateValidPod("foo3", "new")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.ADD, NoneSource, CreateValidPod("foo1", "new", "test"), pod, CreateValidPod("foo3", "new", "test"))) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo1", "new"), pod, CreateValidPod("foo3", "new"))) pod.Annotations["kubenetes.io/blah"] = "superblah" - podUpdate = CreatePodUpdate(kubelet.SET, NoneSource, CreateValidPod("foo1", "new", "test"), pod, CreateValidPod("foo3", "new", "test")) + podUpdate = CreatePodUpdate(kubetypes.SET, TestSource, CreateValidPod("foo1", "new"), pod, CreateValidPod("foo3", "new")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.UPDATE, NoneSource, pod)) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.UPDATE, TestSource, pod)) pod.Annotations["kubernetes.io/otherblah"] = "doh" - podUpdate = CreatePodUpdate(kubelet.SET, NoneSource, CreateValidPod("foo1", "new", "test"), pod, CreateValidPod("foo3", "new", "test")) + podUpdate = CreatePodUpdate(kubetypes.SET, TestSource, CreateValidPod("foo1", "new"), pod, CreateValidPod("foo3", "new")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.UPDATE, NoneSource, pod)) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.UPDATE, TestSource, pod)) delete(pod.Annotations, "kubernetes.io/blah") - podUpdate = CreatePodUpdate(kubelet.SET, NoneSource, CreateValidPod("foo1", "new", "test"), pod, CreateValidPod("foo3", "new", "test")) + podUpdate = CreatePodUpdate(kubetypes.SET, TestSource, CreateValidPod("foo1", "new"), pod, CreateValidPod("foo3", "new")) channel <- podUpdate - expectPodUpdate(t, ch, CreatePodUpdate(kubelet.UPDATE, NoneSource, pod)) + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.UPDATE, TestSource, pod)) +} + +func TestPodUpdateLables(t *testing.T) { + channel, ch, _ := createPodConfigTester(PodConfigNotificationIncremental) + + pod := CreateValidPod("foo2", "new") + pod.Labels = make(map[string]string, 0) + pod.Labels["key"] = "value" + + clone, err := conversion.NewCloner().DeepCopy(pod) + if err != nil { + t.Fatalf("%v", err) + } + + podUpdate := CreatePodUpdate(kubetypes.SET, TestSource, clone.(*api.Pod)) + channel <- podUpdate + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.ADD, TestSource, pod)) + + pod.Labels["key"] = "newValue" + podUpdate = CreatePodUpdate(kubetypes.SET, TestSource, pod) + channel <- podUpdate + expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.UPDATE, TestSource, pod)) + } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/file.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/file.go index 354f158a154d..eff6c6956b6d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/file.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/file.go @@ -26,7 +26,7 @@ import ( "time" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/kubelet" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/util" "github.com/golang/glog" @@ -66,7 +66,7 @@ func (s *sourceFile) extractFromPath() error { return err } // Emit an update with an empty PodList to allow FileSource to be marked as seen - s.updates <- kubelet.PodUpdate{Pods: []*api.Pod{}, Op: kubelet.SET, Source: kubelet.FileSource} + s.updates <- kubetypes.PodUpdate{Pods: []*api.Pod{}, Op: kubetypes.SET, Source: kubetypes.FileSource} return fmt.Errorf("path does not exist, ignoring") } @@ -76,14 +76,14 @@ func (s *sourceFile) extractFromPath() error { if err != nil { return err } - s.updates <- kubelet.PodUpdate{Pods: pods, Op: kubelet.SET, Source: kubelet.FileSource} + s.updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.FileSource} case statInfo.Mode().IsRegular(): pod, err := s.extractFromFile(path) if err != nil { return err } - s.updates <- kubelet.PodUpdate{Pods: []*api.Pod{pod}, Op: kubelet.SET, Source: kubelet.FileSource} + s.updates <- kubetypes.PodUpdate{Pods: []*api.Pod{pod}, Op: kubetypes.SET, Source: kubetypes.FileSource} default: return fmt.Errorf("path is not a directory or file") @@ -92,8 +92,8 @@ func (s *sourceFile) extractFromPath() error { return nil } -// Get as many pod configs as we can from a directory. Return an error iff something -// prevented us from reading anything at all. Do not return an error if only some files +// Get as many pod configs as we can from a directory. Return an error if and only if something +// prevented us from reading anything at all. Do not return an error if only some files // were problematic. func (s *sourceFile) extractFromDir(name string) ([]*api.Pod, error) { dirents, err := filepath.Glob(filepath.Join(name, "[^.]*")) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/file_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/file_test.go index 94ad000d3f42..306801a8f12e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/file_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/file_test.go @@ -24,10 +24,12 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/validation" - "k8s.io/kubernetes/pkg/kubelet" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/securitycontext" + "k8s.io/kubernetes/pkg/util" ) func TestExtractFromNonExistentFile(t *testing.T) { @@ -44,13 +46,13 @@ func TestUpdateOnNonExistentFile(t *testing.T) { NewSourceFile("random_non_existent_path", "localhost", time.Millisecond, ch) select { case got := <-ch: - update := got.(kubelet.PodUpdate) - expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource) + update := got.(kubetypes.PodUpdate) + expected := CreatePodUpdate(kubetypes.SET, kubetypes.FileSource) if !api.Semantic.DeepDerivative(expected, update) { t.Fatalf("Expected %#v, Got %#v", expected, update) } - case <-time.After(time.Second): + case <-time.After(util.ForeverTestTimeout): t.Errorf("Expected update, timeout instead") } } @@ -73,12 +75,12 @@ func TestReadPodsFromFile(t *testing.T) { var testCases = []struct { desc string pod runtime.Object - expected kubelet.PodUpdate + expected kubetypes.PodUpdate }{ { desc: "Simple pod", pod: &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", APIVersion: "", }, @@ -88,10 +90,11 @@ func TestReadPodsFromFile(t *testing.T) { Namespace: "mynamespace", }, Spec: api.PodSpec{ - Containers: []api.Container{{Name: "image", Image: "test/image", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, + Containers: []api.Container{{Name: "image", Image: "test/image", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, + SecurityContext: &api.PodSecurityContext{}, }, }, - expected: CreatePodUpdate(kubelet.SET, kubelet.FileSource, &api.Pod{ + expected: CreatePodUpdate(kubetypes.SET, kubetypes.FileSource, &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-" + hostname, UID: "12345", @@ -109,6 +112,7 @@ func TestReadPodsFromFile(t *testing.T) { TerminationMessagePath: "/dev/termination-log", ImagePullPolicy: "IfNotPresent", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, + SecurityContext: &api.PodSecurityContext{}, }, }), }, @@ -133,7 +137,7 @@ func TestReadPodsFromFile(t *testing.T) { NewSourceFile(file.Name(), hostname, time.Millisecond, ch) select { case got := <-ch: - update := got.(kubelet.PodUpdate) + update := got.(kubetypes.PodUpdate) for _, pod := range update.Pods { if errs := validation.ValidatePod(pod); len(errs) > 0 { t.Errorf("%s: Invalid pod %#v, %#v", testCase.desc, pod, errs) @@ -142,7 +146,7 @@ func TestReadPodsFromFile(t *testing.T) { if !api.Semantic.DeepEqual(testCase.expected, update) { t.Errorf("%s: Expected %#v, Got %#v", testCase.desc, testCase.expected, update) } - case <-time.After(time.Second): + case <-time.After(util.ForeverTestTimeout): t.Errorf("%s: Expected update, timeout instead", testCase.desc) } }() @@ -176,8 +180,8 @@ func TestExtractFromEmptyDir(t *testing.T) { t.Fatalf("Unexpected error: %v", err) } - update := (<-ch).(kubelet.PodUpdate) - expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource) + update := (<-ch).(kubetypes.PodUpdate) + expected := CreatePodUpdate(kubetypes.SET, kubetypes.FileSource) if !api.Semantic.DeepEqual(expected, update) { t.Errorf("Expected %#v, Got %#v", expected, update) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/http.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/http.go index 8d9274b65cf7..fbdde92352f1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/http.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/http.go @@ -25,7 +25,7 @@ import ( "time" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/kubelet" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/util" "github.com/golang/glog" @@ -95,7 +95,7 @@ func (s *sourceURL) extractFromURL() error { } if len(data) == 0 { // Emit an update with an empty PodList to allow HTTPSource to be marked as seen - s.updates <- kubelet.PodUpdate{Pods: []*api.Pod{}, Op: kubelet.SET, Source: kubelet.HTTPSource} + s.updates <- kubetypes.PodUpdate{Pods: []*api.Pod{}, Op: kubetypes.SET, Source: kubetypes.HTTPSource} return fmt.Errorf("zero-length data received from %v", s.url) } // Short circuit if the data has not changed since the last time it was read. @@ -111,7 +111,7 @@ func (s *sourceURL) extractFromURL() error { // It parsed but could not be used. return singlePodErr } - s.updates <- kubelet.PodUpdate{Pods: []*api.Pod{pod}, Op: kubelet.SET, Source: kubelet.HTTPSource} + s.updates <- kubetypes.PodUpdate{Pods: []*api.Pod{pod}, Op: kubetypes.SET, Source: kubetypes.HTTPSource} return nil } @@ -126,7 +126,7 @@ func (s *sourceURL) extractFromURL() error { for i := range podList.Items { pods = append(pods, &podList.Items[i]) } - s.updates <- kubelet.PodUpdate{Pods: pods, Op: kubelet.SET, Source: kubelet.HTTPSource} + s.updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.HTTPSource} return nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/http_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/http_test.go index af7002416217..38bf5e85e1e5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/http_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/http_test.go @@ -25,8 +25,9 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/validation" - "k8s.io/kubernetes/pkg/kubelet" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/errors" @@ -58,16 +59,16 @@ func TestExtractInvalidPods(t *testing.T) { }{ { desc: "No version", - pod: &api.Pod{TypeMeta: api.TypeMeta{APIVersion: ""}}, + pod: &api.Pod{TypeMeta: unversioned.TypeMeta{APIVersion: ""}}, }, { desc: "Invalid version", - pod: &api.Pod{TypeMeta: api.TypeMeta{APIVersion: "v1betta2"}}, + pod: &api.Pod{TypeMeta: unversioned.TypeMeta{APIVersion: "v1betta2"}}, }, { desc: "Invalid volume name", pod: &api.Pod{ - TypeMeta: api.TypeMeta{APIVersion: testapi.Default.Version()}, + TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.Version()}, Spec: api.PodSpec{ Volumes: []api.Volume{{Name: "_INVALID_"}}, }, @@ -76,7 +77,7 @@ func TestExtractInvalidPods(t *testing.T) { { desc: "Duplicate volume names", pod: &api.Pod{ - TypeMeta: api.TypeMeta{APIVersion: testapi.Default.Version()}, + TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.Version()}, Spec: api.PodSpec{ Volumes: []api.Volume{{Name: "repeated"}, {Name: "repeated"}}, }, @@ -85,7 +86,7 @@ func TestExtractInvalidPods(t *testing.T) { { desc: "Unspecified container name", pod: &api.Pod{ - TypeMeta: api.TypeMeta{APIVersion: testapi.Default.Version()}, + TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.Version()}, Spec: api.PodSpec{ Containers: []api.Container{{Name: ""}}, }, @@ -94,7 +95,7 @@ func TestExtractInvalidPods(t *testing.T) { { desc: "Invalid container name", pod: &api.Pod{ - TypeMeta: api.TypeMeta{APIVersion: testapi.Default.Version()}, + TypeMeta: unversioned.TypeMeta{APIVersion: testapi.Default.Version()}, Spec: api.PodSpec{ Containers: []api.Container{{Name: "_INVALID_"}}, }, @@ -127,12 +128,12 @@ func TestExtractPodsFromHTTP(t *testing.T) { var testCases = []struct { desc string pods runtime.Object - expected kubelet.PodUpdate + expected kubetypes.PodUpdate }{ { desc: "Single pod", pods: &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", APIVersion: "", }, @@ -142,12 +143,13 @@ func TestExtractPodsFromHTTP(t *testing.T) { Namespace: "mynamespace", }, Spec: api.PodSpec{ - NodeName: hostname, - Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}}, + NodeName: hostname, + Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}}, + SecurityContext: &api.PodSecurityContext{}, }, }, - expected: CreatePodUpdate(kubelet.SET, - kubelet.HTTPSource, + expected: CreatePodUpdate(kubetypes.SET, + kubetypes.HTTPSource, &api.Pod{ ObjectMeta: api.ObjectMeta{ UID: "111", @@ -160,6 +162,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { NodeName: hostname, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, + SecurityContext: &api.PodSecurityContext{}, TerminationGracePeriodSeconds: &grace, Containers: []api.Container{{ @@ -174,7 +177,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { { desc: "Multiple pods", pods: &api.PodList{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "PodList", APIVersion: "", }, @@ -185,8 +188,9 @@ func TestExtractPodsFromHTTP(t *testing.T) { UID: "111", }, Spec: api.PodSpec{ - NodeName: hostname, - Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}}, + NodeName: hostname, + Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}}, + SecurityContext: &api.PodSecurityContext{}, }, }, { @@ -195,27 +199,29 @@ func TestExtractPodsFromHTTP(t *testing.T) { UID: "222", }, Spec: api.PodSpec{ - NodeName: hostname, - Containers: []api.Container{{Name: "2", Image: "bar", ImagePullPolicy: ""}}, + NodeName: hostname, + Containers: []api.Container{{Name: "2", Image: "bar", ImagePullPolicy: ""}}, + SecurityContext: &api.PodSecurityContext{}, }, }, }, }, - expected: CreatePodUpdate(kubelet.SET, - kubelet.HTTPSource, + expected: CreatePodUpdate(kubetypes.SET, + kubetypes.HTTPSource, &api.Pod{ ObjectMeta: api.ObjectMeta{ UID: "111", Name: "foo" + "-" + hostname, Namespace: "default", - SelfLink: getSelfLink("foo-"+hostname, kubelet.NamespaceDefault), + SelfLink: getSelfLink("foo-"+hostname, kubetypes.NamespaceDefault), }, Spec: api.PodSpec{ NodeName: hostname, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, + SecurityContext: &api.PodSecurityContext{}, Containers: []api.Container{{ Name: "1", @@ -231,13 +237,14 @@ func TestExtractPodsFromHTTP(t *testing.T) { Name: "bar" + "-" + hostname, Namespace: "default", - SelfLink: getSelfLink("bar-"+hostname, kubelet.NamespaceDefault), + SelfLink: getSelfLink("bar-"+hostname, kubetypes.NamespaceDefault), }, Spec: api.PodSpec{ NodeName: hostname, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, + SecurityContext: &api.PodSecurityContext{}, Containers: []api.Container{{ Name: "2", @@ -272,7 +279,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { t.Errorf("%s: Unexpected error: %v", testCase.desc, err) continue } - update := (<-ch).(kubelet.PodUpdate) + update := (<-ch).(kubetypes.PodUpdate) if !api.Semantic.DeepEqual(testCase.expected, update) { t.Errorf("%s: Expected: %#v, Got: %#v", testCase.desc, testCase.expected, update) @@ -287,7 +294,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { func TestURLWithHeader(t *testing.T) { pod := &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ APIVersion: testapi.Default.Version(), Kind: "Pod", }, @@ -318,7 +325,7 @@ func TestURLWithHeader(t *testing.T) { if err := c.extractFromURL(); err != nil { t.Fatalf("Unexpected error extracting from URL: %v", err) } - update := (<-ch).(kubelet.PodUpdate) + update := (<-ch).(kubetypes.PodUpdate) headerVal := fakeHandler.RequestReceived.Header["Metadata-Flavor"] if len(headerVal) != 1 || headerVal[0] != "Google" { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go new file mode 100644 index 000000000000..cd69c1ab45e4 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go @@ -0,0 +1,68 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 container + +import ( + "fmt" + "time" +) + +// Specified a policy for garbage collecting containers. +type ContainerGCPolicy struct { + // Minimum age at which a container can be garbage collected, zero for no limit. + MinAge time.Duration + + // Max number of dead containers any single pod (UID, container name) pair is + // allowed to have, less than zero for no limit. + MaxPerPodContainer int + + // Max number of total dead containers, less than zero for no limit. + MaxContainers int +} + +// Manages garbage collection of dead containers. +// +// Implementation is thread-compatible. +type ContainerGC interface { + // Garbage collect containers. + GarbageCollect() error +} + +// TODO(vmarmol): Preferentially remove pod infra containers. +type realContainerGC struct { + // Container runtime + runtime Runtime + + // Policy for garbage collection. + policy ContainerGCPolicy +} + +// New ContainerGC instance with the specified policy. +func NewContainerGC(runtime Runtime, policy ContainerGCPolicy) (ContainerGC, error) { + if policy.MinAge < 0 { + return nil, fmt.Errorf("invalid minimum garbage collection age: %v", policy.MinAge) + } + + return &realContainerGC{ + runtime: runtime, + policy: policy, + }, nil +} + +func (cgc *realContainerGC) GarbageCollect() error { + return cgc.runtime.GarbageCollect(cgc.policy) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/container_reference_manager.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/container_reference_manager.go index 0cb3097b0f71..1f44389c7f17 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/container_reference_manager.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/container_reference_manager.go @@ -28,32 +28,31 @@ import ( // for the caller. type RefManager struct { sync.RWMutex - // TODO(yifan): To use strong type. - containerIDToRef map[string]*api.ObjectReference + containerIDToRef map[ContainerID]*api.ObjectReference } // NewRefManager creates and returns a container reference manager // with empty contents. func NewRefManager() *RefManager { - return &RefManager{containerIDToRef: make(map[string]*api.ObjectReference)} + return &RefManager{containerIDToRef: make(map[ContainerID]*api.ObjectReference)} } // SetRef stores a reference to a pod's container, associating it with the given container ID. -func (c *RefManager) SetRef(id string, ref *api.ObjectReference) { +func (c *RefManager) SetRef(id ContainerID, ref *api.ObjectReference) { c.Lock() defer c.Unlock() c.containerIDToRef[id] = ref } // ClearRef forgets the given container id and its associated container reference. -func (c *RefManager) ClearRef(id string) { +func (c *RefManager) ClearRef(id ContainerID) { c.Lock() defer c.Unlock() delete(c.containerIDToRef, id) } // GetRef returns the container reference of the given ID, or (nil, false) if none is stored. -func (c *RefManager) GetRef(id string) (ref *api.ObjectReference, ok bool) { +func (c *RefManager) GetRef(id ContainerID) (ref *api.ObjectReference, ok bool) { c.RLock() defer c.RUnlock() ref, ok = c.containerIDToRef[id] diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/fake_runtime.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/fake_runtime.go index f93f5926db0a..994683762179 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/fake_runtime.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/fake_runtime.go @@ -33,7 +33,6 @@ type FakeRuntime struct { sync.Mutex CalledFunctions []string PodList []*Pod - ContainerList []*Container ImageList []Image PodStatus api.PodStatus StartedPods []string @@ -42,6 +41,7 @@ type FakeRuntime struct { KilledContainers []string VersionInfo string Err error + InspectErr error } // FakeRuntime should implement Runtime. @@ -88,7 +88,6 @@ func (f *FakeRuntime) ClearCalls() { f.CalledFunctions = []string{} f.PodList = []*Pod{} - f.ContainerList = []*Container{} f.PodStatus = api.PodStatus{} f.StartedPods = []string{} f.KilledPods = []string{} @@ -96,6 +95,7 @@ func (f *FakeRuntime) ClearCalls() { f.KilledContainers = []string{} f.VersionInfo = "" f.Err = nil + f.InspectErr = nil } func (f *FakeRuntime) assertList(expect []string, test []string) error { @@ -219,15 +219,7 @@ func (f *FakeRuntime) GetPodStatus(*api.Pod) (*api.PodStatus, error) { return &status, f.Err } -func (f *FakeRuntime) GetContainers(all bool) ([]*Container, error) { - f.Lock() - defer f.Unlock() - - f.CalledFunctions = append(f.CalledFunctions, "GetContainers") - return f.ContainerList, f.Err -} - -func (f *FakeRuntime) ExecInContainer(containerID string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { +func (f *FakeRuntime) ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { f.Lock() defer f.Unlock() @@ -235,7 +227,7 @@ func (f *FakeRuntime) ExecInContainer(containerID string, cmd []string, stdin io return f.Err } -func (f *FakeRuntime) AttachContainer(containerID string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { +func (f *FakeRuntime) AttachContainer(containerID ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { f.Lock() defer f.Unlock() @@ -243,7 +235,7 @@ func (f *FakeRuntime) AttachContainer(containerID string, stdin io.Reader, stdou return f.Err } -func (f *FakeRuntime) RunInContainer(containerID string, cmd []string) ([]byte, error) { +func (f *FakeRuntime) RunInContainer(containerID ContainerID, cmd []string) ([]byte, error) { f.Lock() defer f.Unlock() @@ -251,7 +243,7 @@ func (f *FakeRuntime) RunInContainer(containerID string, cmd []string) ([]byte, return []byte{}, f.Err } -func (f *FakeRuntime) GetContainerLogs(pod *api.Pod, containerID, tail string, follow bool, stdout, stderr io.Writer) (err error) { +func (f *FakeRuntime) GetContainerLogs(pod *api.Pod, containerID ContainerID, logOptions *api.PodLogOptions, stdout, stderr io.Writer) (err error) { f.Lock() defer f.Unlock() @@ -274,10 +266,10 @@ func (f *FakeRuntime) IsImagePresent(image ImageSpec) (bool, error) { f.CalledFunctions = append(f.CalledFunctions, "IsImagePresent") for _, i := range f.ImageList { if i.ID == image.Image { - return true, f.Err + return true, nil } } - return false, f.Err + return false, f.InspectErr } func (f *FakeRuntime) ListImages() ([]Image, error) { @@ -312,3 +304,11 @@ func (f *FakeRuntime) PortForward(pod *Pod, port uint16, stream io.ReadWriteClos f.CalledFunctions = append(f.CalledFunctions, "PortForward") return f.Err } + +func (f *FakeRuntime) GarbageCollect(gcPolicy ContainerGCPolicy) error { + f.Lock() + defer f.Unlock() + + f.CalledFunctions = append(f.CalledFunctions, "GarbageCollect") + return f.Err +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/helpers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/helpers.go index 346c0fdd9dcd..23251d0380f5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/helpers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/helpers.go @@ -18,7 +18,6 @@ package container import ( "hash/adler32" - "strings" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/util" @@ -29,7 +28,7 @@ import ( // HandlerRunner runs a lifecycle handler for a container. type HandlerRunner interface { - Run(containerID string, pod *api.Pod, container *api.Container, handler *api.Handler) error + Run(containerID ContainerID, pod *api.Pod, container *api.Container, handler *api.Handler) error } // RunContainerOptionsGenerator generates the options that necessary for @@ -38,20 +37,9 @@ type RunContainerOptionsGenerator interface { GenerateRunContainerOptions(pod *api.Pod, container *api.Container) (*RunContainerOptions, error) } -// Trims runtime prefix from ID or image name (e.g.: docker://busybox -> busybox). -func TrimRuntimePrefix(fullString string) string { - const prefixSeparator = "://" - - idx := strings.Index(fullString, prefixSeparator) - if idx < 0 { - return fullString - } - return fullString[idx+len(prefixSeparator):] -} - // ShouldContainerBeRestarted checks whether a container needs to be restarted. // TODO(yifan): Think about how to refactor this. -func ShouldContainerBeRestarted(container *api.Container, pod *api.Pod, podStatus *api.PodStatus, readinessManager *ReadinessManager) bool { +func ShouldContainerBeRestarted(container *api.Container, pod *api.Pod, podStatus *api.PodStatus) bool { podFullName := GetPodFullName(pod) // Get all dead container status. @@ -62,11 +50,6 @@ func ShouldContainerBeRestarted(container *api.Container, pod *api.Pod, podStatu } } - // Set dead containers to unready state. - for _, c := range resultStatus { - readinessManager.RemoveReadiness(TrimRuntimePrefix(c.ContainerID)) - } - // Check RestartPolicy for dead container. if len(resultStatus) > 0 { if pod.Spec.RestartPolicy == api.RestartPolicyNever { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/image_puller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/image_puller.go index b9268a0adcf5..3a5e5de9195f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/image_puller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/image_puller.go @@ -22,6 +22,7 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/client/record" + "k8s.io/kubernetes/pkg/util" ) // imagePuller pulls the image using Runtime.PullImage(). @@ -30,14 +31,16 @@ import ( type imagePuller struct { recorder record.EventRecorder runtime Runtime + backOff *util.Backoff } // NewImagePuller takes an event recorder and container runtime to create a // image puller that wraps the container runtime's PullImage interface. -func NewImagePuller(recorder record.EventRecorder, runtime Runtime) ImagePuller { +func NewImagePuller(recorder record.EventRecorder, runtime Runtime, imageBackOff *util.Backoff) ImagePuller { return &imagePuller{ recorder: recorder, runtime: runtime, + backOff: imageBackOff, } } @@ -56,24 +59,18 @@ func shouldPullImage(container *api.Container, imagePresent bool) bool { return false } -// reportImagePull reports 'image pulling', 'image pulled' or 'image pulling failed' events. -func (puller *imagePuller) reportImagePull(ref *api.ObjectReference, event string, image string, pullError error) { - if ref == nil { - return - } - - switch event { - case "pulling": - puller.recorder.Eventf(ref, "Pulling", "Pulling image %q", image) - case "pulled": - puller.recorder.Eventf(ref, "Pulled", "Successfully pulled image %q", image) - case "failed": - puller.recorder.Eventf(ref, "Failed", "Failed to pull image %q: %v", image, pullError) +// records an event using ref, event msg. log to glog using prefix, msg, logFn +func (puller *imagePuller) logIt(ref *api.ObjectReference, event, prefix, msg string, logFn func(args ...interface{})) { + if ref != nil { + puller.recorder.Eventf(ref, event, msg) + } else { + logFn(fmt.Sprint(prefix, " ", msg)) } } // PullImage pulls the image for the specified pod and container. -func (puller *imagePuller) PullImage(pod *api.Pod, container *api.Container, pullSecrets []api.Secret) error { +func (puller *imagePuller) PullImage(pod *api.Pod, container *api.Container, pullSecrets []api.Secret) (error, string) { + logPrefix := fmt.Sprintf("%s/%s", pod.Name, container.Image) ref, err := GenerateContainerRef(pod, container) if err != nil { glog.Errorf("Couldn't make a ref to pod %v, container %v: '%v'", pod.Name, container.Name, err) @@ -81,24 +78,36 @@ func (puller *imagePuller) PullImage(pod *api.Pod, container *api.Container, pul spec := ImageSpec{container.Image} present, err := puller.runtime.IsImagePresent(spec) if err != nil { - if ref != nil { - puller.recorder.Eventf(ref, "Failed", "Failed to inspect image %q: %v", container.Image, err) - } - return fmt.Errorf("failed to inspect image %q: %v", container.Image, err) + msg := fmt.Sprintf("Failed to inspect image %q: %v", container.Image, err) + puller.logIt(ref, "Failed", logPrefix, msg, glog.Warning) + return ErrImageInspect, msg } if !shouldPullImage(container, present) { - if present && ref != nil { - puller.recorder.Eventf(ref, "Pulled", "Container image %q already present on machine", container.Image) + if present { + msg := fmt.Sprintf("Container image %q already present on machine", container.Image) + puller.logIt(ref, "Pulled", logPrefix, msg, glog.Info) + return nil, "" + } else { + msg := fmt.Sprintf("Container image %q is not present with pull policy of Never", container.Image) + puller.logIt(ref, "ErrImageNeverPull", logPrefix, msg, glog.Warning) + return ErrImageNeverPull, msg } - return nil } - puller.reportImagePull(ref, "pulling", container.Image, nil) + backOffKey := fmt.Sprintf("%s_%s", pod.Name, container.Image) + if puller.backOff.IsInBackOffSinceUpdate(backOffKey, puller.backOff.Clock.Now()) { + msg := fmt.Sprintf("Back-off pulling image %q", container.Image) + puller.logIt(ref, "Back-off", logPrefix, msg, glog.Info) + return ErrImagePullBackOff, msg + } + puller.logIt(ref, "Pulling", logPrefix, fmt.Sprintf("pulling image %q", container.Image), glog.Info) if err = puller.runtime.PullImage(spec, pullSecrets); err != nil { - puller.reportImagePull(ref, "failed", container.Image, err) - return err + puller.logIt(ref, "Failed", logPrefix, fmt.Sprintf("Failed to pull image %q: %v", container.Image, err), glog.Warning) + puller.backOff.Next(backOffKey, puller.backOff.Clock.Now()) + return ErrImagePull, err.Error() } - puller.reportImagePull(ref, "pulled", container.Image, nil) - return nil + puller.logIt(ref, "Pulled", logPrefix, fmt.Sprintf("Successfully pulled image %q", container.Image), glog.Info) + puller.backOff.GC() + return nil, "" } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/image_puller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/image_puller_test.go new file mode 100644 index 000000000000..ad0d46e3b4dd --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/image_puller_test.go @@ -0,0 +1,119 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 container + +import ( + "errors" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/record" + "k8s.io/kubernetes/pkg/util" +) + +func TestPuller(t *testing.T) { + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: "test_pod", + Namespace: "test-ns", + UID: "bar", + ResourceVersion: "42", + SelfLink: "/api/v1/pods/foo", + }} + + cases := []struct { + containerImage string + policy api.PullPolicy + calledFunctions []string + inspectErr error + pullerErr error + expectedErr []error + }{ + { // pull missing image + containerImage: "missing_image", + policy: api.PullIfNotPresent, + calledFunctions: []string{"IsImagePresent", "PullImage"}, + inspectErr: nil, + pullerErr: nil, + expectedErr: []error{nil}}, + + { // image present, dont pull + containerImage: "present_image", + policy: api.PullIfNotPresent, + calledFunctions: []string{"IsImagePresent"}, + inspectErr: nil, + pullerErr: nil, + expectedErr: []error{nil, nil, nil}}, + // image present, pull it + {containerImage: "present_image", + policy: api.PullAlways, + calledFunctions: []string{"IsImagePresent", "PullImage"}, + inspectErr: nil, + pullerErr: nil, + expectedErr: []error{nil, nil, nil}}, + // missing image, error PullNever + {containerImage: "missing_image", + policy: api.PullNever, + calledFunctions: []string{"IsImagePresent"}, + inspectErr: nil, + pullerErr: nil, + expectedErr: []error{ErrImageNeverPull, ErrImageNeverPull, ErrImageNeverPull}}, + // missing image, unable to inspect + {containerImage: "missing_image", + policy: api.PullIfNotPresent, + calledFunctions: []string{"IsImagePresent"}, + inspectErr: errors.New("unknown inspectError"), + pullerErr: nil, + expectedErr: []error{ErrImageInspect, ErrImageInspect, ErrImageInspect}}, + // missing image, unable to fetch + {containerImage: "typo_image", + policy: api.PullIfNotPresent, + calledFunctions: []string{"IsImagePresent", "PullImage"}, + inspectErr: nil, + pullerErr: errors.New("404"), + expectedErr: []error{ErrImagePull, ErrImagePull, ErrImagePullBackOff, ErrImagePull, ErrImagePullBackOff, ErrImagePullBackOff}}, + } + + for i, c := range cases { + container := &api.Container{ + Name: "container_name", + Image: c.containerImage, + ImagePullPolicy: c.policy, + } + + backOff := util.NewBackOff(time.Second, time.Minute) + fakeClock := &util.FakeClock{Time: time.Now()} + backOff.Clock = fakeClock + + fakeRuntime := &FakeRuntime{} + fakeRecorder := &record.FakeRecorder{} + puller := NewImagePuller(fakeRecorder, fakeRuntime, backOff) + + fakeRuntime.ImageList = []Image{{"present_image", nil, 0}} + fakeRuntime.Err = c.pullerErr + fakeRuntime.InspectErr = c.inspectErr + + for tick, expected := range c.expectedErr { + fakeClock.Step(time.Second) + err, _ := puller.PullImage(pod, container, nil) + fakeRuntime.AssertCalls(c.calledFunctions) + assert.Equal(t, expected, err, "in test %d tick=%d", i, tick) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/readiness_manager.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/readiness_manager.go deleted file mode 100644 index ade99c39cb9b..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/readiness_manager.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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 container - -import "sync" - -// ReadinessManager maintains the readiness information(probe results) of -// containers over time to allow for implementation of health thresholds. -// This manager is thread-safe, no locks are necessary for the caller. -type ReadinessManager struct { - // guards states - sync.RWMutex - // TODO(yifan): To use strong type. - states map[string]bool -} - -// NewReadinessManager creates ane returns a readiness manager with empty -// contents. -func NewReadinessManager() *ReadinessManager { - return &ReadinessManager{states: make(map[string]bool)} -} - -// GetReadiness returns the readiness value for the container with the given ID. -// If the readiness value is found, returns it. -// If the readiness is not found, returns false. -func (r *ReadinessManager) GetReadiness(id string) bool { - r.RLock() - defer r.RUnlock() - state, found := r.states[id] - return state && found -} - -// SetReadiness sets the readiness value for the container with the given ID. -func (r *ReadinessManager) SetReadiness(id string, value bool) { - r.Lock() - defer r.Unlock() - r.states[id] = value -} - -// RemoveReadiness clears the readiness value for the container with the given ID. -func (r *ReadinessManager) RemoveReadiness(id string) { - r.Lock() - defer r.Unlock() - delete(r.states, id) -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/ref_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/ref_test.go index 17c2a6f11dd4..a2ed3a651873 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/ref_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/ref_test.go @@ -21,6 +21,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" ) func TestFieldPath(t *testing.T) { @@ -64,7 +65,7 @@ func TestFieldPath(t *testing.T) { func TestGenerateContainerRef(t *testing.T) { var ( okPod = api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", APIVersion: testapi.Default.Version(), }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/runtime.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/runtime.go index 141216dce0a2..570f46a66043 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/runtime.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container/runtime.go @@ -23,6 +23,7 @@ import ( "reflect" "strings" + "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" @@ -32,6 +33,22 @@ import ( // Container Terminated and Kubelet is backing off the restart var ErrCrashLoopBackOff = errors.New("CrashLoopBackOff") +var ( + // Container image pull failed, kubelet is backing off image pull + ErrImagePullBackOff = errors.New("ImagePullBackOff") + + // Unable to inspect image + ErrImageInspect = errors.New("ImageInspectError") + + // General image pull error + ErrImagePull = errors.New("ErrImagePull") + + // Required Image is absent on host and PullPolicy is NeverPullImage + ErrImageNeverPull = errors.New("ErrImageNeverPull") +) + +var ErrRunContainer = errors.New("RunContainerError") + type Version interface { // Compare compares two versions of the runtime. On success it returns -1 // if the version is less than the other, 1 if it is greater than the other, @@ -57,6 +74,8 @@ type Runtime interface { // specifies whether the runtime returns all containers including those already // exited and dead containers (used for garbage collection). GetPods(all bool) ([]*Pod, error) + // GarbageCollect removes dead containers using the specified container gc policy + GarbageCollect(gcPolicy ContainerGCPolicy) error // Syncs the running pod into the desired pod. SyncPod(pod *api.Pod, runningPod Pod, podStatus api.PodStatus, pullSecrets []api.Secret, backOff *util.Backoff) error // KillPod kills all the containers of a pod. Pod may be nil, running pod must not be. @@ -79,7 +98,7 @@ type Runtime interface { // default, it returns a snapshot of the container log. Set 'follow' to true to // stream the log. Set 'follow' to false and specify the number of lines (e.g. // "100" or "all") to tail the log. - GetContainerLogs(pod *api.Pod, containerID, tail string, follow bool, stdout, stderr io.Writer) (err error) + GetContainerLogs(pod *api.Pod, containerID ContainerID, logOptions *api.PodLogOptions, stdout, stderr io.Writer) (err error) // ContainerCommandRunner encapsulates the command runner interfaces for testability. ContainerCommandRunner // ContainerAttach encapsulates the attaching to containers for testability @@ -87,20 +106,18 @@ type Runtime interface { } type ContainerAttacher interface { - AttachContainer(id string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) (err error) + AttachContainer(id ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) (err error) } // CommandRunner encapsulates the command runner interfaces for testability. type ContainerCommandRunner interface { // TODO(vmarmol): Merge RunInContainer and ExecInContainer. // Runs the command in the container of the specified pod using nsinit. - // TODO(yifan): Use strong type for containerID. - RunInContainer(containerID string, cmd []string) ([]byte, error) + RunInContainer(containerID ContainerID, cmd []string) ([]byte, error) // Runs the command in the container of the specified pod using nsenter. // Attaches the processes stdin, stdout, and stderr. Optionally uses a // tty. - // TODO(yifan): Use strong type for containerID. - ExecInContainer(containerID string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error + ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error // Forward the specified port from the specified pod to the stream. PortForward(pod *Pod, port uint16, stream io.ReadWriteCloser) error } @@ -109,7 +126,7 @@ type ContainerCommandRunner interface { // It will check the presence of the image, and report the 'image pulling', // 'image pulled' events correspondingly. type ImagePuller interface { - PullImage(pod *api.Pod, container *api.Container, pullSecrets []api.Secret) error + PullImage(pod *api.Pod, container *api.Container, pullSecrets []api.Secret) (error, string) } // Pod is a group of containers, with the status of the pod. @@ -139,6 +156,15 @@ func BuildContainerID(typ, ID string) ContainerID { return ContainerID{Type: typ, ID: ID} } +// Convenience method for creating a ContainerID from an ID string. +func ParseContainerID(containerID string) ContainerID { + var id ContainerID + if err := id.ParseString(containerID); err != nil { + glog.Error(err) + } + return id +} + func (c *ContainerID) ParseString(data string) error { // Trim the quotes and split the type and ID. parts := strings.Split(strings.Trim(data, "\""), "://") @@ -153,6 +179,10 @@ func (c *ContainerID) String() string { return fmt.Sprintf("%s://%s", c.Type, c.ID) } +func (c *ContainerID) IsEmpty() bool { + return *c == ContainerID{} +} + func (c *ContainerID) MarshalJSON() ([]byte, error) { return []byte(fmt.Sprintf("%q", c.String())), nil } @@ -166,7 +196,7 @@ func (c *ContainerID) UnmarshalJSON(data []byte) error { type Container struct { // The ID of the container, used by the container runtime to identify // a container. - ID types.UID + ID ContainerID // The name of the container, which should be the same as specified by // api.Container. Name string diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_linux.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_linux.go index 0f3576b5d4b5..21b57eeb7858 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_linux.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_linux.go @@ -35,7 +35,10 @@ import ( "k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/errors" + "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/oom" + "k8s.io/kubernetes/pkg/util/sets" + utilsysctl "k8s.io/kubernetes/pkg/util/sysctl" ) const ( @@ -70,23 +73,134 @@ func newSystemContainer(containerName string) *systemContainer { } } +type nodeConfig struct { + dockerDaemonContainerName string + systemContainerName string + kubeletContainerName string +} + type containerManagerImpl struct { + cadvisorInterface cadvisor.Interface + mountUtil mount.Interface + nodeConfig // External containers being managed. systemContainers []*systemContainer } var _ containerManager = &containerManagerImpl{} +// checks if the required cgroups subsystems are mounted. +// As of now, only 'cpu' and 'memory' are required. +func validateSystemRequirements(mountUtil mount.Interface) error { + const ( + cgroupMountType = "cgroup" + localErr = "system validation failed" + ) + mountPoints, err := mountUtil.List() + if err != nil { + return fmt.Errorf("%s - %v", localErr, err) + } + expectedCgroups := sets.NewString("cpu", "cpuacct", "cpuset", "memory") + for _, mountPoint := range mountPoints { + if mountPoint.Type == cgroupMountType { + for _, opt := range mountPoint.Opts { + if expectedCgroups.Has(opt) { + expectedCgroups.Delete(opt) + } + } + } + } + + if expectedCgroups.Len() > 0 { + return fmt.Errorf("%s - Following Cgroup subsystem not mounted: %v", localErr, expectedCgroups.List()) + } + return nil +} + // TODO(vmarmol): Add limits to the system containers. // Takes the absolute name of the specified containers. // Empty container name disables use of the specified container. -func newContainerManager(cadvisorInterface cadvisor.Interface, dockerDaemonContainerName, systemContainerName, kubeletContainerName string) (containerManager, error) { - systemContainers := []*systemContainer{} +func newContainerManager(mountUtil mount.Interface, cadvisorInterface cadvisor.Interface, dockerDaemonContainerName, systemContainerName, kubeletContainerName string) (containerManager, error) { + return &containerManagerImpl{ + cadvisorInterface: cadvisorInterface, + mountUtil: mountUtil, + nodeConfig: nodeConfig{ + dockerDaemonContainerName: dockerDaemonContainerName, + systemContainerName: systemContainerName, + kubeletContainerName: kubeletContainerName, + }, + }, nil +} + +// Create a cgroup container manager. +func createManager(containerName string) *fs.Manager { + return &fs.Manager{ + Cgroups: &configs.Cgroup{ + Name: containerName, + AllowAllDevices: true, + }, + } +} + +// TODO: plumb this up as a flag to Kubelet in a future PR +type KernelTunableBehavior string + +const ( + KernelTunableWarn KernelTunableBehavior = "warn" + KernelTunableError KernelTunableBehavior = "error" + KernelTunableModify KernelTunableBehavior = "modify" +) + +// setupKernelTunables validates kernel tunable flags are set as expected +// depending upon the specified option, it will either warn, error, or modify the kernel tunable flags +func setupKernelTunables(option KernelTunableBehavior) error { + desiredState := map[string]int{ + utilsysctl.VmOvercommitMemory: utilsysctl.VmOvercommitMemoryAlways, + utilsysctl.VmPanicOnOOM: utilsysctl.VmPanicOnOOMInvokeOOMKiller, + } - if dockerDaemonContainerName != "" { - cont := newSystemContainer(dockerDaemonContainerName) + errList := []error{} + for flag, expectedValue := range desiredState { + val, err := utilsysctl.GetSysctl(flag) + if err != nil { + errList = append(errList, err) + continue + } + if val == expectedValue { + continue + } - info, err := cadvisorInterface.MachineInfo() + switch option { + case KernelTunableError: + errList = append(errList, fmt.Errorf("Invalid kernel flag: %v, expected value: %v, actual value: %v", flag, expectedValue, val)) + case KernelTunableWarn: + glog.V(2).Infof("Invalid kernel flag: %v, expected value: %v, actual value: %v", flag, expectedValue, val) + case KernelTunableModify: + glog.V(2).Infof("Updating kernel flag: %v, expected value: %v, actual value: %v", flag, expectedValue, val) + err = utilsysctl.SetSysctl(flag, expectedValue) + if err != nil { + errList = append(errList, err) + } + } + } + return errors.NewAggregate(errList) +} + +func (cm *containerManagerImpl) setupNode() error { + if err := validateSystemRequirements(cm.mountUtil); err != nil { + return err + } + + // TODO: plumb kernel tunable options into container manager, right now, we modify by default + if err := setupKernelTunables(KernelTunableModify); err != nil { + return err + } + + systemContainers := []*systemContainer{} + if cm.dockerDaemonContainerName != "" { + cont := newSystemContainer(cm.dockerDaemonContainerName) + + info, err := cm.cadvisorInterface.MachineInfo() var capacity = api.ResourceList{} if err != nil { } else { @@ -94,29 +208,29 @@ func newContainerManager(cadvisorInterface cadvisor.Interface, dockerDaemonConta } memoryLimit := (int64(capacity.Memory().Value() * DockerMemoryLimitThresholdPercent / 100)) if memoryLimit < MinDockerMemoryLimit { - glog.Warningf("Memory limit %d for container %s is too small, reset it to %d", memoryLimit, dockerDaemonContainerName, MinDockerMemoryLimit) + glog.Warningf("Memory limit %d for container %s is too small, reset it to %d", memoryLimit, cm.dockerDaemonContainerName, MinDockerMemoryLimit) memoryLimit = MinDockerMemoryLimit } - glog.V(2).Infof("Configure resource-only container %s with memory limit: %d", dockerDaemonContainerName, memoryLimit) + glog.V(2).Infof("Configure resource-only container %s with memory limit: %d", cm.dockerDaemonContainerName, memoryLimit) dockerContainer := &fs.Manager{ Cgroups: &configs.Cgroup{ - Name: dockerDaemonContainerName, + Name: cm.dockerDaemonContainerName, Memory: memoryLimit, MemorySwap: -1, AllowAllDevices: true, }, } cont.ensureStateFunc = func(manager *fs.Manager) error { - return ensureDockerInContainer(cadvisorInterface, -900, dockerContainer) + return ensureDockerInContainer(cm.cadvisorInterface, -900, dockerContainer) } systemContainers = append(systemContainers, cont) } - if systemContainerName != "" { - if systemContainerName == "/" { - return nil, fmt.Errorf("system container cannot be root (\"/\")") + if cm.systemContainerName != "" { + if cm.systemContainerName == "/" { + return fmt.Errorf("system container cannot be root (\"/\")") } rootContainer := &fs.Manager{ @@ -124,35 +238,27 @@ func newContainerManager(cadvisorInterface cadvisor.Interface, dockerDaemonConta Name: "/", }, } - manager := createManager(systemContainerName) + manager := createManager(cm.systemContainerName) err := ensureSystemContainer(rootContainer, manager) if err != nil { - return nil, err + return err } - systemContainers = append(systemContainers, newSystemContainer(systemContainerName)) - } - - if kubeletContainerName != "" { - systemContainers = append(systemContainers, newSystemContainer(kubeletContainerName)) + systemContainers = append(systemContainers, newSystemContainer(cm.systemContainerName)) } - return &containerManagerImpl{ - systemContainers: systemContainers, - }, nil -} - -// Create a cgroup container manager. -func createManager(containerName string) *fs.Manager { - return &fs.Manager{ - Cgroups: &configs.Cgroup{ - Name: containerName, - AllowAllDevices: true, - }, + if cm.kubeletContainerName != "" { + systemContainers = append(systemContainers, newSystemContainer(cm.kubeletContainerName)) } + cm.systemContainers = systemContainers + return nil } func (cm *containerManagerImpl) Start() error { + // Setup the node + if err := cm.setupNode(); err != nil { + return err + } // Don't run a background thread if there are no ensureStateFuncs. numEnsureStateFuncs := 0 for _, cont := range cm.systemContainers { @@ -228,8 +334,8 @@ func ensureDockerInContainer(cadvisor cadvisor.Interface, oomScoreAdj int, manag } // Also apply oom-score-adj to processes - oomAdjuster := oom.NewOomAdjuster() - if err := oomAdjuster.ApplyOomScoreAdj(pid, oomScoreAdj); err != nil { + oomAdjuster := oom.NewOOMAdjuster() + if err := oomAdjuster.ApplyOOMScoreAdj(pid, oomScoreAdj); err != nil { errs = append(errs, fmt.Errorf("failed to apply oom score %d to PID %d", oomScoreAdj, pid)) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_linux_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_linux_test.go new file mode 100644 index 000000000000..a0bd899e298b --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_linux_test.go @@ -0,0 +1,125 @@ +// +build linux + +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 kubelet + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + + "k8s.io/kubernetes/pkg/util/mount" +) + +type fakeMountInterface struct { + mountPoints []mount.MountPoint +} + +func (mi *fakeMountInterface) Mount(source string, target string, fstype string, options []string) error { + return fmt.Errorf("unsupported") +} + +func (mi *fakeMountInterface) Unmount(target string) error { + return fmt.Errorf("unsupported") +} + +func (mi *fakeMountInterface) List() ([]mount.MountPoint, error) { + return mi.mountPoints, nil +} + +func (mi *fakeMountInterface) IsLikelyNotMountPoint(file string) (bool, error) { + return false, fmt.Errorf("unsupported") +} + +func fakeContainerMgrMountInt() mount.Interface { + return &fakeMountInterface{ + []mount.MountPoint{ + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpuset"}, + }, + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpu"}, + }, + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpuacct"}, + }, + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "memory"}, + }, + }, + } +} + +func TestCgroupMountValidationSuccess(t *testing.T) { + assert.Nil(t, validateSystemRequirements(fakeContainerMgrMountInt())) +} + +func TestCgroupMountValidationMemoryMissing(t *testing.T) { + mountInt := &fakeMountInterface{ + []mount.MountPoint{ + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpuset"}, + }, + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpu"}, + }, + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpuacct"}, + }, + }, + } + assert.Error(t, validateSystemRequirements(mountInt)) +} + +func TestCgroupMountValidationMultipleSubsytem(t *testing.T) { + mountInt := &fakeMountInterface{ + []mount.MountPoint{ + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpuset", "memory"}, + }, + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpu"}, + }, + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpuacct"}, + }, + }, + } + assert.Nil(t, validateSystemRequirements(mountInt)) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_unsupported.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_unsupported.go index 8444852d0a00..c18e67997355 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_unsupported.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_unsupported.go @@ -23,6 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/kubelet/cadvisor" + "k8s.io/kubernetes/pkg/util/mount" ) type unsupportedContainerManager struct { @@ -38,6 +39,6 @@ func (unsupportedContainerManager) SystemContainersLimit() api.ResourceList { return api.ResourceList{} } -func newContainerManager(cadvisorInterface cadvisor.Interface, dockerDaemonContainer, systemContainer, kubeletContainer string) (containerManager, error) { +func newContainerManager(mounter mount.Interface, cadvisorInterface cadvisor.Interface, dockerDaemonContainer, systemContainer, kubeletContainer string) (containerManager, error) { return &unsupportedContainerManager{}, nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_unsupported_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_unsupported_test.go new file mode 100644 index 000000000000..3e1bf5c3c419 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_manager_unsupported_test.go @@ -0,0 +1,72 @@ +// +build !linux + +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 kubelet + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/util/mount" +) + +type fakeMountInterface struct { + mountPoints []mount.MountPoint +} + +func (mi *fakeMountInterface) Mount(source string, target string, fstype string, options []string) error { + return fmt.Errorf("unsupported") +} + +func (mi *fakeMountInterface) Unmount(target string) error { + return fmt.Errorf("unsupported") +} + +func (mi *fakeMountInterface) List() ([]mount.MountPoint, error) { + return mi.mountPoints, nil +} + +func (mi *fakeMountInterface) IsLikelyNotMountPoint(file string) (bool, error) { + return false, fmt.Errorf("unsupported") +} + +func fakeContainerMgrMountInt() mount.Interface { + return &fakeMountInterface{ + []mount.MountPoint{ + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpuset"}, + }, + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpu"}, + }, + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "cpuacct"}, + }, + { + Device: "cgroup", + Type: "cgroup", + Opts: []string{"rw", "relatime", "memory"}, + }, + }, + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_gc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/container_gc.go similarity index 66% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_gc.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/container_gc.go index 95027a3574e8..48a0a4c19e90 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_gc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/container_gc.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kubelet +package dockertools import ( "fmt" @@ -26,54 +26,17 @@ import ( docker "github.com/fsouza/go-dockerclient" "github.com/golang/glog" - "k8s.io/kubernetes/pkg/kubelet/dockertools" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/types" ) -// Specified a policy for garbage collecting containers. -type ContainerGCPolicy struct { - // Minimum age at which a container can be garbage collected, zero for no limit. - MinAge time.Duration - - // Max number of dead containers any single pod (UID, container name) pair is - // allowed to have, less than zero for no limit. - MaxPerPodContainer int - - // Max number of total dead containers, less than zero for no limit. - MaxContainers int -} - -// Manages garbage collection of dead containers. -// -// Implementation is thread-compatible. -type containerGC interface { - // Garbage collect containers. - GarbageCollect() error -} - -// TODO(vmarmol): Preferentially remove pod infra containers. -type realContainerGC struct { - // Docker client to use. - dockerClient dockertools.DockerInterface - - // Policy for garbage collection. - policy ContainerGCPolicy - - // The path to the symlinked docker logs +type containerGC struct { + client DockerInterface containerLogsDir string } -// New containerGC instance with the specified policy. -func newContainerGC(dockerClient dockertools.DockerInterface, policy ContainerGCPolicy) (containerGC, error) { - if policy.MinAge < 0 { - return nil, fmt.Errorf("invalid minimum garbage collection age: %v", policy.MinAge) - } - - return &realContainerGC{ - dockerClient: dockerClient, - policy: policy, - containerLogsDir: containerLogsDir, - }, nil +func NewContainerGC(client DockerInterface, containerLogsDir string) *containerGC { + return &containerGC{client: client, containerLogsDir: containerLogsDir} } // Internal information kept for containers being considered for GC. @@ -128,65 +91,7 @@ func (a byCreated) Len() int { return len(a) } func (a byCreated) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a byCreated) Less(i, j int) bool { return a[i].createTime.After(a[j].createTime) } -func (cgc *realContainerGC) GarbageCollect() error { - // Separate containers by evict units. - evictUnits, unidentifiedContainers, err := cgc.evictableContainers() - if err != nil { - return err - } - - // Remove unidentified containers. - for _, container := range unidentifiedContainers { - glog.Infof("Removing unidentified dead container %q with ID %q", container.name, container.id) - err = cgc.dockerClient.RemoveContainer(docker.RemoveContainerOptions{ID: container.id, RemoveVolumes: true}) - if err != nil { - glog.Warningf("Failed to remove unidentified dead container %q: %v", container.name, err) - } - } - - // Enforce max containers per evict unit. - if cgc.policy.MaxPerPodContainer >= 0 { - cgc.enforceMaxContainersPerEvictUnit(evictUnits, cgc.policy.MaxPerPodContainer) - } - - // Enforce max total number of containers. - if cgc.policy.MaxContainers >= 0 && evictUnits.NumContainers() > cgc.policy.MaxContainers { - // Leave an equal number of containers per evict unit (min: 1). - numContainersPerEvictUnit := cgc.policy.MaxContainers / evictUnits.NumEvictUnits() - if numContainersPerEvictUnit < 1 { - numContainersPerEvictUnit = 1 - } - cgc.enforceMaxContainersPerEvictUnit(evictUnits, numContainersPerEvictUnit) - - // If we still need to evict, evict oldest first. - numContainers := evictUnits.NumContainers() - if numContainers > cgc.policy.MaxContainers { - flattened := make([]containerGCInfo, 0, numContainers) - for uid := range evictUnits { - flattened = append(flattened, evictUnits[uid]...) - } - sort.Sort(byCreated(flattened)) - - cgc.removeOldestN(flattened, numContainers-cgc.policy.MaxContainers) - } - } - - // Remove dead symlinks - should only happen on upgrade - // from a k8s version without proper log symlink cleanup - logSymlinks, _ := filepath.Glob(path.Join(cgc.containerLogsDir, fmt.Sprintf("*.%s", dockertools.LogSuffix))) - for _, logSymlink := range logSymlinks { - if _, err = os.Stat(logSymlink); os.IsNotExist(err) { - err = os.Remove(logSymlink) - if err != nil { - glog.Warningf("Failed to remove container log dead symlink %q: %v", logSymlink, err) - } - } - } - - return nil -} - -func (cgc *realContainerGC) enforceMaxContainersPerEvictUnit(evictUnits containersByEvictUnit, MaxContainers int) { +func (cgc *containerGC) enforceMaxContainersPerEvictUnit(evictUnits containersByEvictUnit, MaxContainers int) { for uid := range evictUnits { toRemove := len(evictUnits[uid]) - MaxContainers @@ -197,15 +102,15 @@ func (cgc *realContainerGC) enforceMaxContainersPerEvictUnit(evictUnits containe } // Removes the oldest toRemove containers and returns the resulting slice. -func (cgc *realContainerGC) removeOldestN(containers []containerGCInfo, toRemove int) []containerGCInfo { +func (cgc *containerGC) removeOldestN(containers []containerGCInfo, toRemove int) []containerGCInfo { // Remove from oldest to newest (last to first). numToKeep := len(containers) - toRemove for i := numToKeep; i < len(containers); i++ { - err := cgc.dockerClient.RemoveContainer(docker.RemoveContainerOptions{ID: containers[i].id, RemoveVolumes: true}) + err := cgc.client.RemoveContainer(docker.RemoveContainerOptions{ID: containers[i].id, RemoveVolumes: true}) if err != nil { glog.Warningf("Failed to remove dead container %q: %v", containers[i].name, err) } - symlinkPath := dockertools.LogSymlink(cgc.containerLogsDir, containers[i].podNameWithNamespace, containers[i].containerName, containers[i].id) + symlinkPath := LogSymlink(cgc.containerLogsDir, containers[i].podNameWithNamespace, containers[i].containerName, containers[i].id) err = os.Remove(symlinkPath) if err != nil && !os.IsNotExist(err) { glog.Warningf("Failed to remove container %q log symlink %q: %v", containers[i].name, symlinkPath, err) @@ -218,18 +123,18 @@ func (cgc *realContainerGC) removeOldestN(containers []containerGCInfo, toRemove // Get all containers that are evictable. Evictable containers are: not running // and created more than MinAge ago. -func (cgc *realContainerGC) evictableContainers() (containersByEvictUnit, []containerGCInfo, error) { - containers, err := dockertools.GetKubeletDockerContainers(cgc.dockerClient, true) +func (cgc *containerGC) evictableContainers(minAge time.Duration) (containersByEvictUnit, []containerGCInfo, error) { + containers, err := GetKubeletDockerContainers(cgc.client, true) if err != nil { return containersByEvictUnit{}, []containerGCInfo{}, err } unidentifiedContainers := make([]containerGCInfo, 0) evictUnits := make(containersByEvictUnit) - newestGCTime := time.Now().Add(-cgc.policy.MinAge) + newestGCTime := time.Now().Add(-minAge) for _, container := range containers { // Prune out running containers. - data, err := cgc.dockerClient.InspectContainer(container.ID) + data, err := cgc.client.InspectContainer(container.ID) if err != nil { // Container may have been removed already, skip. continue @@ -245,7 +150,7 @@ func (cgc *realContainerGC) evictableContainers() (containersByEvictUnit, []cont createTime: data.Created, } - containerName, _, err := dockertools.ParseDockerName(container.Names[0]) + containerName, _, err := ParseDockerName(container.Names[0]) if err != nil { unidentifiedContainers = append(unidentifiedContainers, containerInfo) @@ -267,3 +172,62 @@ func (cgc *realContainerGC) evictableContainers() (containersByEvictUnit, []cont return evictUnits, unidentifiedContainers, nil } + +// GarbageCollect removes dead containers using the specified container gc policy +func (cgc *containerGC) GarbageCollect(gcPolicy kubecontainer.ContainerGCPolicy) error { + // Separate containers by evict units. + evictUnits, unidentifiedContainers, err := cgc.evictableContainers(gcPolicy.MinAge) + if err != nil { + return err + } + + // Remove unidentified containers. + for _, container := range unidentifiedContainers { + glog.Infof("Removing unidentified dead container %q with ID %q", container.name, container.id) + err = cgc.client.RemoveContainer(docker.RemoveContainerOptions{ID: container.id, RemoveVolumes: true}) + if err != nil { + glog.Warningf("Failed to remove unidentified dead container %q: %v", container.name, err) + } + } + + // Enforce max containers per evict unit. + if gcPolicy.MaxPerPodContainer >= 0 { + cgc.enforceMaxContainersPerEvictUnit(evictUnits, gcPolicy.MaxPerPodContainer) + } + + // Enforce max total number of containers. + if gcPolicy.MaxContainers >= 0 && evictUnits.NumContainers() > gcPolicy.MaxContainers { + // Leave an equal number of containers per evict unit (min: 1). + numContainersPerEvictUnit := gcPolicy.MaxContainers / evictUnits.NumEvictUnits() + if numContainersPerEvictUnit < 1 { + numContainersPerEvictUnit = 1 + } + cgc.enforceMaxContainersPerEvictUnit(evictUnits, numContainersPerEvictUnit) + + // If we still need to evict, evict oldest first. + numContainers := evictUnits.NumContainers() + if numContainers > gcPolicy.MaxContainers { + flattened := make([]containerGCInfo, 0, numContainers) + for uid := range evictUnits { + flattened = append(flattened, evictUnits[uid]...) + } + sort.Sort(byCreated(flattened)) + + cgc.removeOldestN(flattened, numContainers-gcPolicy.MaxContainers) + } + } + + // Remove dead symlinks - should only happen on upgrade + // from a k8s version without proper log symlink cleanup + logSymlinks, _ := filepath.Glob(path.Join(cgc.containerLogsDir, fmt.Sprintf("*.%s", LogSuffix))) + for _, logSymlink := range logSymlinks { + if _, err = os.Stat(logSymlink); os.IsNotExist(err) { + err = os.Remove(logSymlink) + if err != nil { + glog.Warningf("Failed to remove container log dead symlink %q: %v", logSymlink, err) + } + } + } + + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_gc_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/container_gc_test.go similarity index 92% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_gc_test.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/container_gc_test.go index c943a2fbc82d..e24e6ed3ab93 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/container_gc_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/container_gc_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kubelet +package dockertools import ( "fmt" @@ -25,23 +25,18 @@ import ( docker "github.com/fsouza/go-dockerclient" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "k8s.io/kubernetes/pkg/kubelet/dockertools" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" ) -func newTestContainerGC(t *testing.T, MinAge time.Duration, MaxPerPodContainer, MaxContainers int) (containerGC, *dockertools.FakeDockerClient) { - fakeDocker := new(dockertools.FakeDockerClient) - gc, err := newContainerGC(fakeDocker, ContainerGCPolicy{ - MinAge: MinAge, - MaxPerPodContainer: MaxPerPodContainer, - MaxContainers: MaxContainers, - }) - require.Nil(t, err) +func newTestContainerGC(t *testing.T) (*containerGC, *FakeDockerClient) { + fakeDocker := new(FakeDockerClient) + gc := NewContainerGC(fakeDocker, "") return gc, fakeDocker } // Makes a stable time object, lower id is earlier time. func makeTime(id int) time.Time { + var zero time.Time return zero.Add(time.Duration(id) * time.Second) } @@ -90,7 +85,7 @@ func verifyStringArrayEqualsAnyOrder(t *testing.T, actual, expected []string) { } func TestGarbageCollectZeroMaxContainers(t *testing.T) { - gc, fakeDocker := newTestContainerGC(t, time.Minute, 1, 0) + gc, fakeDocker := newTestContainerGC(t) fakeDocker.ContainerList = []docker.APIContainers{ makeAPIContainer("foo", "POD", "1876"), } @@ -98,12 +93,12 @@ func TestGarbageCollectZeroMaxContainers(t *testing.T) { makeContainerDetail("1876", false, makeTime(0)), ) - assert.Nil(t, gc.GarbageCollect()) + assert.Nil(t, gc.GarbageCollect(kubecontainer.ContainerGCPolicy{time.Minute, 1, 0})) assert.Len(t, fakeDocker.Removed, 1) } func TestGarbageCollectNoMaxPerPodContainerLimit(t *testing.T) { - gc, fakeDocker := newTestContainerGC(t, time.Minute, -1, 4) + gc, fakeDocker := newTestContainerGC(t) fakeDocker.ContainerList = []docker.APIContainers{ makeAPIContainer("foo", "POD", "1876"), makeAPIContainer("foo1", "POD", "2876"), @@ -119,12 +114,12 @@ func TestGarbageCollectNoMaxPerPodContainerLimit(t *testing.T) { makeContainerDetail("5876", false, makeTime(4)), ) - assert.Nil(t, gc.GarbageCollect()) + assert.Nil(t, gc.GarbageCollect(kubecontainer.ContainerGCPolicy{time.Minute, -1, 4})) assert.Len(t, fakeDocker.Removed, 1) } func TestGarbageCollectNoMaxLimit(t *testing.T) { - gc, fakeDocker := newTestContainerGC(t, time.Minute, 1, -1) + gc, fakeDocker := newTestContainerGC(t) fakeDocker.ContainerList = []docker.APIContainers{ makeAPIContainer("foo", "POD", "1876"), makeAPIContainer("foo1", "POD", "2876"), @@ -140,7 +135,7 @@ func TestGarbageCollectNoMaxLimit(t *testing.T) { makeContainerDetail("5876", false, makeTime(0)), ) - assert.Nil(t, gc.GarbageCollect()) + assert.Nil(t, gc.GarbageCollect(kubecontainer.ContainerGCPolicy{time.Minute, 1, -1})) assert.Len(t, fakeDocker.Removed, 0) } @@ -309,10 +304,10 @@ func TestGarbageCollect(t *testing.T) { } for i, test := range tests { t.Logf("Running test case with index %d", i) - gc, fakeDocker := newTestContainerGC(t, time.Hour, 2, 6) + gc, fakeDocker := newTestContainerGC(t) fakeDocker.ContainerList = test.containers fakeDocker.ContainerMap = test.containerDetails - assert.Nil(t, gc.GarbageCollect()) + assert.Nil(t, gc.GarbageCollect(kubecontainer.ContainerGCPolicy{time.Hour, 2, 6})) verifyStringArrayEqualsAnyOrder(t, fakeDocker.Removed, test.expectedRemoved) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/convert.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/convert.go index 584682cc0112..7f743f5bd35a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/convert.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/convert.go @@ -21,7 +21,7 @@ import ( docker "github.com/fsouza/go-dockerclient" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/types" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) // This file contains helper functions to convert docker API types to runtime @@ -38,7 +38,7 @@ func toRuntimeContainer(c *docker.APIContainers) (*kubecontainer.Container, erro return nil, err } return &kubecontainer.Container{ - ID: types.UID(c.ID), + ID: kubetypes.DockerID(c.ID).ContainerID(), Name: dockerName.ContainerName, Image: c.Image, Hash: hash, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/convert_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/convert_test.go index 1fee5aff02ac..acc99f660f28 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/convert_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/convert_test.go @@ -22,7 +22,6 @@ import ( docker "github.com/fsouza/go-dockerclient" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/types" ) func TestToRuntimeContainer(t *testing.T) { @@ -33,7 +32,7 @@ func TestToRuntimeContainer(t *testing.T) { Names: []string{"/k8s_bar.5678_foo_ns_1234_42"}, } expected := &kubecontainer.Container{ - ID: types.UID("ab2cdf"), + ID: kubecontainer.ContainerID{"docker", "ab2cdf"}, Name: "bar", Image: "bar_image", Hash: 0x5678, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/docker.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/docker.go index e2632a4fa3ea..72727fe92c8b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/docker.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/docker.go @@ -32,7 +32,7 @@ import ( "k8s.io/kubernetes/pkg/credentialprovider" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/leaky" - kubeletTypes "k8s.io/kubernetes/pkg/kubelet/types" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" utilerrors "k8s.io/kubernetes/pkg/util/errors" @@ -41,7 +41,7 @@ import ( const ( PodInfraContainerName = leaky.PodInfraContainerName DockerPrefix = "docker://" - PodInfraContainerImage = "gcr.io/google_containers/pause:0.8.0" + PodInfraContainerImage = "beta.gcr.io/google_containers/pause:2.0" LogSuffix = "log" ) @@ -212,7 +212,7 @@ func (p throttledDockerPuller) IsImagePresent(name string) (bool, error) { } // DockerContainers is a map of containers -type DockerContainers map[kubeletTypes.DockerID]*docker.APIContainers +type DockerContainers map[kubetypes.DockerID]*docker.APIContainers func (c DockerContainers) FindPodContainer(podFullName string, uid types.UID, containerName string) (*docker.APIContainers, bool, uint64) { for _, dockerContainer := range c { @@ -368,7 +368,7 @@ func GetKubeletDockerContainers(client DockerInterface, allContainers bool) (Doc glog.V(3).Infof("Docker Container: %s is not managed by kubelet.", container.Names[0]) continue } - result[kubeletTypes.DockerID(container.ID)] = container + result[kubetypes.DockerID(container.ID)] = container } return result, nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/docker_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/docker_test.go index 867cae23cc3e..7f69de5bdf4d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/docker_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/docker_test.go @@ -22,6 +22,7 @@ import ( "hash/adler32" "reflect" "sort" + "strconv" "strings" "testing" @@ -33,6 +34,7 @@ import ( "k8s.io/kubernetes/pkg/credentialprovider" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/network" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" ) @@ -170,10 +172,10 @@ func TestExecSupportNotExists(t *testing.T) { func TestDockerContainerCommand(t *testing.T) { runner := &DockerManager{} - containerID := "1234" + containerID := kubetypes.DockerID("1234").ContainerID() command := []string{"ls"} cmd, _ := runner.getRunInContainerCommand(containerID, command) - if cmd.Dir != "/var/lib/docker/execdriver/native/"+containerID { + if cmd.Dir != "/var/lib/docker/execdriver/native/"+containerID.ID { t.Errorf("unexpected command CWD: %s", cmd.Dir) } if !reflect.DeepEqual(cmd.Args, []string{"/usr/sbin/nsinit", "exec", "ls"}) { @@ -283,6 +285,12 @@ func TestPullWithSecrets(t *testing.T) { t.Errorf("unexpected error: %v", err) } + dockerConfigJson := map[string]map[string]map[string]string{"auths": dockerCfg} + dockerConfigJsonContent, err := json.Marshal(dockerConfigJson) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + tests := map[string]struct { imageName string passedSecrets []api.Secret @@ -313,6 +321,12 @@ func TestPullWithSecrets(t *testing.T) { credentialprovider.DockerConfig(map[string]credentialprovider.DockerConfigEntry{"index.docker.io/v1/": {"built-in", "password", "email"}}), []string{`ubuntu:latest using {"username":"passed-user","password":"passed-password","email":"passed-email"}`}, }, + "builtin keyring secrets, but use passed with new docker config": { + "ubuntu", + []api.Secret{{Type: api.SecretTypeDockerConfigJson, Data: map[string][]byte{api.DockerConfigJsonKey: dockerConfigJsonContent}}}, + credentialprovider.DockerConfig(map[string]credentialprovider.DockerConfigEntry{"index.docker.io/v1/": {"built-in", "password", "email"}}), + []string{`ubuntu:latest using {"username":"passed-user","password":"passed-password","email":"passed-email"}`}, + }, } for _, test := range tests { builtInKeyRing := &credentialprovider.BasicDockerKeyring{} @@ -504,7 +518,7 @@ type containersByID []*kubecontainer.Container func (b containersByID) Len() int { return len(b) } func (b containersByID) Swap(i, j int) { b[i], b[j] = b[j], b[i] } -func (b containersByID) Less(i, j int) bool { return b[i].ID < b[j].ID } +func (b containersByID) Less(i, j int) bool { return b[i].ID.ID < b[j].ID.ID } func TestFindContainersByPod(t *testing.T) { tests := []struct { @@ -547,12 +561,12 @@ func TestFindContainersByPod(t *testing.T) { Namespace: "ns", Containers: []*kubecontainer.Container{ { - ID: "foobar", + ID: kubetypes.DockerID("foobar").ContainerID(), Name: "foobar", Hash: 0x1234, }, { - ID: "baz", + ID: kubetypes.DockerID("baz").ContainerID(), Name: "baz", Hash: 0x1234, }, @@ -564,7 +578,7 @@ func TestFindContainersByPod(t *testing.T) { Namespace: "ns", Containers: []*kubecontainer.Container{ { - ID: "barbar", + ID: kubetypes.DockerID("barbar").ContainerID(), Name: "barbar", Hash: 0x1234, }, @@ -605,17 +619,17 @@ func TestFindContainersByPod(t *testing.T) { Namespace: "ns", Containers: []*kubecontainer.Container{ { - ID: "foobar", + ID: kubetypes.DockerID("foobar").ContainerID(), Name: "foobar", Hash: 0x1234, }, { - ID: "barfoo", + ID: kubetypes.DockerID("barfoo").ContainerID(), Name: "barfoo", Hash: 0x1234, }, { - ID: "baz", + ID: kubetypes.DockerID("baz").ContainerID(), Name: "baz", Hash: 0x1234, }, @@ -627,7 +641,7 @@ func TestFindContainersByPod(t *testing.T) { Namespace: "ns", Containers: []*kubecontainer.Container{ { - ID: "barbar", + ID: kubetypes.DockerID("barbar").ContainerID(), Name: "barbar", Hash: 0x1234, }, @@ -639,7 +653,7 @@ func TestFindContainersByPod(t *testing.T) { Namespace: "ns", Containers: []*kubecontainer.Container{ { - ID: "bazbaz", + ID: kubetypes.DockerID("bazbaz").ContainerID(), Name: "bazbaz", Hash: 0x1234, }, @@ -656,7 +670,8 @@ func TestFindContainersByPod(t *testing.T) { } fakeClient := &FakeDockerClient{} np, _ := network.InitNetworkPlugin([]network.NetworkPlugin{}, "", network.NewFakeHost(nil)) - containerManager := NewFakeDockerManager(fakeClient, &record.FakeRecorder{}, nil, nil, &cadvisorApi.MachineInfo{}, PodInfraContainerImage, 0, 0, "", kubecontainer.FakeOS{}, np, nil, nil) + // image back-off is set to nil, this test shouldnt pull images + containerManager := NewFakeDockerManager(fakeClient, &record.FakeRecorder{}, nil, nil, &cadvisorApi.MachineInfo{}, PodInfraContainerImage, 0, 0, "", kubecontainer.FakeOS{}, np, nil, nil, nil) for i, test := range tests { fakeClient.ContainerList = test.containerList fakeClient.ExitedContainerList = test.exitedContainerList @@ -698,42 +713,81 @@ func TestMakePortsAndBindings(t *testing.T) { HostPort: 445, Protocol: "foobar", }, + { + ContainerPort: 443, + HostPort: 446, + Protocol: "tcp", + }, + { + ContainerPort: 443, + HostPort: 446, + Protocol: "udp", + }, } + exposedPorts, bindings := makePortsAndBindings(ports) - if len(ports) != len(exposedPorts) || - len(ports) != len(bindings) { + + // Count the expected exposed ports and bindings + expectedExposedPorts := map[string]struct{}{} + + for _, binding := range ports { + dockerKey := strconv.Itoa(binding.ContainerPort) + "/" + string(binding.Protocol) + expectedExposedPorts[dockerKey] = struct{}{} + } + + // Should expose right ports in docker + if len(expectedExposedPorts) != len(exposedPorts) { t.Errorf("Unexpected ports and bindings, %#v %#v %#v", ports, exposedPorts, bindings) } - for key, value := range bindings { - switch value[0].HostPort { - case "8080": - if !reflect.DeepEqual(docker.Port("80/tcp"), key) { - t.Errorf("Unexpected docker port: %#v", key) - } - if value[0].HostIP != "127.0.0.1" { - t.Errorf("Unexpected host IP: %s", value[0].HostIP) - } - case "443": - if !reflect.DeepEqual(docker.Port("443/tcp"), key) { - t.Errorf("Unexpected docker port: %#v", key) - } - if value[0].HostIP != "" { - t.Errorf("Unexpected host IP: %s", value[0].HostIP) - } - case "444": - if !reflect.DeepEqual(docker.Port("444/udp"), key) { - t.Errorf("Unexpected docker port: %#v", key) - } - if value[0].HostIP != "" { - t.Errorf("Unexpected host IP: %s", value[0].HostIP) - } - case "445": - if !reflect.DeepEqual(docker.Port("445/tcp"), key) { - t.Errorf("Unexpected docker port: %#v", key) - } - if value[0].HostIP != "" { - t.Errorf("Unexpected host IP: %s", value[0].HostIP) + + // Construct expected bindings + expectPortBindings := map[string][]docker.PortBinding{ + "80/tcp": { + docker.PortBinding{ + HostPort: "8080", + HostIP: "127.0.0.1", + }, + }, + "443/tcp": { + docker.PortBinding{ + HostPort: "443", + HostIP: "", + }, + docker.PortBinding{ + HostPort: "446", + HostIP: "", + }, + }, + "443/udp": { + docker.PortBinding{ + HostPort: "446", + HostIP: "", + }, + }, + "444/udp": { + docker.PortBinding{ + HostPort: "444", + HostIP: "", + }, + }, + "445/tcp": { + docker.PortBinding{ + HostPort: "445", + HostIP: "", + }, + }, + } + + // interate the bindings by dockerPort, and check its portBindings + for dockerPort, portBindings := range bindings { + switch dockerPort { + case "80/tcp", "443/tcp", "443/udp", "444/udp", "445/tcp": + if !reflect.DeepEqual(expectPortBindings[string(dockerPort)], portBindings) { + t.Errorf("Unexpected portbindings for %#v, expected: %#v, but got: %#v", + dockerPort, expectPortBindings[string(dockerPort)], portBindings) } + default: + t.Errorf("Unexpected docker port: %#v with portbindings: %#v", dockerPort, portBindings) } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/fake_docker_client.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/fake_docker_client.go index d9de133117d5..3774f700a2db 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/fake_docker_client.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/fake_docker_client.go @@ -19,10 +19,12 @@ package dockertools import ( "encoding/json" "fmt" + "math/rand" "os" "reflect" "sort" "sync" + "time" docker "github.com/fsouza/go-dockerclient" @@ -31,6 +33,7 @@ import ( ) // FakeDockerClient is a simple fake docker client, so that kubelet can be run for testing without requiring a real docker setup. +// TODO: create a proper constructor for FakeDockerClient, so we won't need to check if ContainerMap is not nil. type FakeDockerClient struct { sync.Mutex ContainerList []docker.APIContainers @@ -50,6 +53,7 @@ type FakeDockerClient struct { Information docker.Env ExecInspect *docker.ExecInspect execCmd []string + EnableSleep bool } func (f *FakeDockerClient) ClearCalls() { @@ -173,22 +177,41 @@ func (f *FakeDockerClient) InspectImage(name string) (*docker.Image, error) { return f.Image, err } +// Sleeps random amount of time with the normal distribution with given mean and stddev +// (in milliseconds), we never sleep less than cutOffMillis +func (f *FakeDockerClient) normalSleep(mean, stdDev, cutOffMillis int) { + if !f.EnableSleep { + return + } + cutoff := (time.Duration)(cutOffMillis) * time.Millisecond + delay := (time.Duration)(rand.NormFloat64()*float64(stdDev)+float64(mean)) * time.Millisecond + if delay < cutoff { + delay = cutoff + } + time.Sleep(delay) +} + // CreateContainer is a test-spy implementation of DockerInterface.CreateContainer. // It adds an entry "create" to the internal method call record. func (f *FakeDockerClient) CreateContainer(c docker.CreateContainerOptions) (*docker.Container, error) { f.Lock() defer f.Unlock() f.called = append(f.called, "create") - err := f.popError("create") - if err == nil { - f.Created = append(f.Created, c.Name) - // This is not a very good fake. We'll just add this container's name to the list. - // Docker likes to add a '/', so copy that behavior. - name := "/" + c.Name - f.ContainerList = append(f.ContainerList, docker.APIContainers{ID: name, Names: []string{name}, Image: c.Config.Image}) - return &docker.Container{ID: name}, nil + if err := f.popError("create"); err != nil { + return nil, err + } + f.Created = append(f.Created, c.Name) + // This is not a very good fake. We'll just add this container's name to the list. + // Docker likes to add a '/', so copy that behavior. + name := "/" + c.Name + f.ContainerList = append(f.ContainerList, docker.APIContainers{ID: name, Names: []string{name}, Image: c.Config.Image}) + container := docker.Container{ID: name, Name: name, Config: c.Config} + if f.ContainerMap != nil { + containerCopy := container + f.ContainerMap[name] = &containerCopy } - return nil, err + f.normalSleep(200, 50, 50) + return &container, nil } // StartContainer is a test-spy implementation of DockerInterface.StartContainer. @@ -197,22 +220,37 @@ func (f *FakeDockerClient) StartContainer(id string, hostConfig *docker.HostConf f.Lock() defer f.Unlock() f.called = append(f.called, "start") - err := f.popError("start") - if err == nil { - - f.Container = &docker.Container{ - ID: id, - Name: id, // For testing purpose, we set name to id - Config: &docker.Config{Image: "testimage"}, - HostConfig: hostConfig, - State: docker.State{ - Running: true, - Pid: os.Getpid(), - }, - NetworkSettings: &docker.NetworkSettings{IPAddress: "1.2.3.4"}, + if err := f.popError("start"); err != nil { + return err + } + f.Container = &docker.Container{ + ID: id, + Name: id, // For testing purpose, we set name to id + Config: &docker.Config{Image: "testimage"}, + HostConfig: hostConfig, + State: docker.State{ + Running: true, + Pid: os.Getpid(), + StartedAt: time.Now(), + }, + NetworkSettings: &docker.NetworkSettings{IPAddress: "1.2.3.4"}, + } + if f.ContainerMap != nil { + container, ok := f.ContainerMap[id] + if !ok { + container = &docker.Container{ID: id, Name: id} } + container.HostConfig = hostConfig + container.State = docker.State{ + Running: true, + Pid: os.Getpid(), + StartedAt: time.Now(), + } + container.NetworkSettings = &docker.NetworkSettings{IPAddress: "2.3.4.5"} + f.ContainerMap[id] = container } - return err + f.normalSleep(200, 50, 50) + return nil } // StopContainer is a test-spy implementation of DockerInterface.StopContainer. @@ -221,20 +259,39 @@ func (f *FakeDockerClient) StopContainer(id string, timeout uint) error { f.Lock() defer f.Unlock() f.called = append(f.called, "stop") - err := f.popError("stop") - if err == nil { - f.Stopped = append(f.Stopped, id) - var newList []docker.APIContainers - for _, container := range f.ContainerList { - if container.ID == id { - f.ExitedContainerList = append(f.ExitedContainerList, container) - continue + if err := f.popError("stop"); err != nil { + return err + } + f.Stopped = append(f.Stopped, id) + var newList []docker.APIContainers + for _, container := range f.ContainerList { + if container.ID == id { + f.ExitedContainerList = append(f.ExitedContainerList, container) + continue + } + newList = append(newList, container) + } + f.ContainerList = newList + if f.ContainerMap != nil { + container, ok := f.ContainerMap[id] + if !ok { + container = &docker.Container{ + ID: id, + Name: id, + State: docker.State{ + Running: false, + StartedAt: time.Now().Add(-time.Second), + FinishedAt: time.Now(), + }, } - newList = append(newList, container) + } else { + container.State.FinishedAt = time.Now() + container.State.Running = false } - f.ContainerList = newList + f.ContainerMap[id] = container } - return err + f.normalSleep(200, 50, 50) + return nil } func (f *FakeDockerClient) RemoveContainer(opts docker.RemoveContainerOptions) error { @@ -245,6 +302,9 @@ func (f *FakeDockerClient) RemoveContainer(opts docker.RemoveContainerOptions) e if err == nil { f.Removed = append(f.Removed, opts.ID) } + if f.ContainerMap != nil { + delete(f.ContainerMap, opts.ID) + } return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/fake_manager.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/fake_manager.go index 5a98c9535993..d50726096423 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/fake_manager.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/fake_manager.go @@ -22,7 +22,8 @@ import ( kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/network" "k8s.io/kubernetes/pkg/kubelet/prober" - kubeletTypes "k8s.io/kubernetes/pkg/kubelet/types" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" + "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/oom" "k8s.io/kubernetes/pkg/util/procfs" ) @@ -30,7 +31,7 @@ import ( func NewFakeDockerManager( client DockerInterface, recorder record.EventRecorder, - readinessManager *kubecontainer.ReadinessManager, + prober prober.Prober, containerRefManager *kubecontainer.RefManager, machineInfo *cadvisorApi.MachineInfo, podInfraContainerImage string, @@ -40,14 +41,13 @@ func NewFakeDockerManager( osInterface kubecontainer.OSInterface, networkPlugin network.NetworkPlugin, generator kubecontainer.RunContainerOptionsGenerator, - httpClient kubeletTypes.HttpGetter) *DockerManager { + httpClient kubetypes.HttpGetter, imageBackOff *util.Backoff) *DockerManager { - fakeOomAdjuster := oom.NewFakeOomAdjuster() + fakeOOMAdjuster := oom.NewFakeOOMAdjuster() fakeProcFs := procfs.NewFakeProcFs() - dm := NewDockerManager(client, recorder, readinessManager, containerRefManager, machineInfo, podInfraContainerImage, qps, + dm := NewDockerManager(client, recorder, prober, containerRefManager, machineInfo, podInfraContainerImage, qps, burst, containerLogsDir, osInterface, networkPlugin, generator, httpClient, &NativeExecHandler{}, - fakeOomAdjuster, fakeProcFs, false) + fakeOOMAdjuster, fakeProcFs, false, imageBackOff) dm.dockerPuller = &FakeDockerPuller{} - dm.prober = prober.New(nil, readinessManager, containerRefManager, recorder) return dm } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/manager.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/manager.go index 36b395c12261..94e1126d7f54 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/manager.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/manager.go @@ -37,6 +37,7 @@ import ( cadvisorApi "github.com/google/cadvisor/info/v1" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/record" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/lifecycle" @@ -45,7 +46,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/network/hairpin" "k8s.io/kubernetes/pkg/kubelet/prober" "k8s.io/kubernetes/pkg/kubelet/qos" - kubeletTypes "k8s.io/kubernetes/pkg/kubelet/types" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/probe" "k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/types" @@ -73,6 +74,8 @@ const ( kubernetesPodLabel = "io.kubernetes.pod.data" kubernetesTerminationGracePeriodLabel = "io.kubernetes.pod.terminationGracePeriod" kubernetesContainerLabel = "io.kubernetes.container.name" + + DockerNetnsFmt = "/proc/%v/ns/net" ) // DockerManager implements the Runtime interface. @@ -84,7 +87,6 @@ var podInfraContainerImagePullPolicy = api.PullIfNotPresent type DockerManager struct { client DockerInterface recorder record.EventRecorder - readinessManager *kubecontainer.ReadinessManager containerRefManager *kubecontainer.RefManager os kubecontainer.OSInterface machineInfo *cadvisorApi.MachineInfo @@ -99,7 +101,7 @@ type DockerManager struct { // 2. We use an LRU cache to avoid extra garbage collection work. This // means that some entries may be recycled before a pod has been // deleted. - reasonCache stringCache + reasonCache reasonInfoCache // TODO(yifan): Record the pull failure so we can eliminate the image checking // in GetPodStatus()? // Lower level docker image puller. @@ -130,19 +132,22 @@ type DockerManager struct { execHandler ExecHandler // Used to set OOM scores of processes. - oomAdjuster *oom.OomAdjuster + oomAdjuster *oom.OOMAdjuster // Get information from /proc mount. procFs procfs.ProcFsInterface // If true, enforce container cpu limits with CFS quota support cpuCFSQuota bool + + // Container GC manager + containerGC *containerGC } func NewDockerManager( client DockerInterface, recorder record.EventRecorder, - readinessManager *kubecontainer.ReadinessManager, + prober prober.Prober, containerRefManager *kubecontainer.RefManager, machineInfo *cadvisorApi.MachineInfo, podInfraContainerImage string, @@ -152,11 +157,13 @@ func NewDockerManager( osInterface kubecontainer.OSInterface, networkPlugin network.NetworkPlugin, generator kubecontainer.RunContainerOptionsGenerator, - httpClient kubeletTypes.HttpGetter, + httpClient kubetypes.HttpGetter, execHandler ExecHandler, - oomAdjuster *oom.OomAdjuster, + oomAdjuster *oom.OOMAdjuster, procFs procfs.ProcFsInterface, - cpuCFSQuota bool) *DockerManager { + cpuCFSQuota bool, + imageBackOff *util.Backoff) *DockerManager { + // Work out the location of the Docker runtime, defaulting to /var/lib/docker // if there are any problems. dockerRoot := "/var/lib/docker" @@ -187,12 +194,11 @@ func NewDockerManager( } } - reasonCache := stringCache{cache: lru.New(maxReasonCacheEntries)} + reasonCache := reasonInfoCache{cache: lru.New(maxReasonCacheEntries)} dm := &DockerManager{ client: client, recorder: recorder, - readinessManager: readinessManager, containerRefManager: containerRefManager, os: osInterface, machineInfo: machineInfo, @@ -202,7 +208,7 @@ func NewDockerManager( dockerRoot: dockerRoot, containerLogsDir: containerLogsDir, networkPlugin: networkPlugin, - prober: nil, + prober: prober, generator: generator, execHandler: execHandler, oomAdjuster: oomAdjuster, @@ -210,42 +216,46 @@ func NewDockerManager( cpuCFSQuota: cpuCFSQuota, } dm.runner = lifecycle.NewHandlerRunner(httpClient, dm, dm) - dm.prober = prober.New(dm, readinessManager, containerRefManager, recorder) - dm.imagePuller = kubecontainer.NewImagePuller(recorder, dm) + dm.imagePuller = kubecontainer.NewImagePuller(recorder, dm, imageBackOff) + dm.containerGC = NewContainerGC(client, containerLogsDir) return dm } // A cache which stores strings keyed by _. -type stringCache struct { +type reasonInfoCache struct { lock sync.RWMutex cache *lru.Cache } +type reasonInfo struct { + reason string + message string +} -func (sc *stringCache) composeKey(uid types.UID, name string) string { +func (sc *reasonInfoCache) composeKey(uid types.UID, name string) string { return fmt.Sprintf("%s_%s", uid, name) } -func (sc *stringCache) Add(uid types.UID, name string, value string) { +func (sc *reasonInfoCache) Add(uid types.UID, name string, reason, message string) { sc.lock.Lock() defer sc.lock.Unlock() - sc.cache.Add(sc.composeKey(uid, name), value) + sc.cache.Add(sc.composeKey(uid, name), reasonInfo{reason, message}) } -func (sc *stringCache) Remove(uid types.UID, name string) { +func (sc *reasonInfoCache) Remove(uid types.UID, name string) { sc.lock.Lock() defer sc.lock.Unlock() sc.cache.Remove(sc.composeKey(uid, name)) } -func (sc *stringCache) Get(uid types.UID, name string) (string, bool) { +func (sc *reasonInfoCache) Get(uid types.UID, name string) (reasonInfo, bool) { sc.lock.RLock() defer sc.lock.RUnlock() value, ok := sc.cache.Get(sc.composeKey(uid, name)) if ok { - return value.(string), ok + return value.(reasonInfo), ok } else { - return "", ok + return reasonInfo{"", ""}, ok } } @@ -254,20 +264,29 @@ func (sc *stringCache) Get(uid types.UID, name string) (string, bool) { // stream the log. Set 'follow' to false and specify the number of lines (e.g. // "100" or "all") to tail the log. // TODO: Make 'RawTerminal' option flagable. -func (dm *DockerManager) GetContainerLogs(pod *api.Pod, containerID, tail string, follow bool, stdout, stderr io.Writer) (err error) { +func (dm *DockerManager) GetContainerLogs(pod *api.Pod, containerID kubecontainer.ContainerID, logOptions *api.PodLogOptions, stdout, stderr io.Writer) (err error) { + var since int64 + if logOptions.SinceSeconds != nil { + t := unversioned.Now().Add(-time.Duration(*logOptions.SinceSeconds) * time.Second) + since = t.Unix() + } + if logOptions.SinceTime != nil { + since = logOptions.SinceTime.Unix() + } opts := docker.LogsOptions{ - Container: containerID, + Container: containerID.ID, Stdout: true, Stderr: true, OutputStream: stdout, ErrorStream: stderr, - Timestamps: false, + Timestamps: logOptions.Timestamps, + Since: since, + Follow: logOptions.Follow, RawTerminal: false, - Follow: follow, } - if !follow { - opts.Tail = tail + if !logOptions.Follow && logOptions.TailLines != nil { + opts.Tail = strconv.FormatInt(*logOptions.TailLines, 10) } err = dm.client.Logs(opts) @@ -292,21 +311,64 @@ type containerStatusResult struct { err error } +const podIPDownwardAPISelector = "status.podIP" + +// podDependsOnIP returns whether any containers in a pod depend on using the pod IP via +// the downward API. +func podDependsOnPodIP(pod *api.Pod) bool { + for _, container := range pod.Spec.Containers { + for _, env := range container.Env { + if env.ValueFrom != nil && + env.ValueFrom.FieldRef != nil && + env.ValueFrom.FieldRef.FieldPath == podIPDownwardAPISelector { + return true + } + } + } + + return false +} + +// determineContainerIP determines the IP address of the given container. It is expected +// that the container passed is the infrastructure container of a pod and the responsibility +// of the caller to ensure that the correct container is passed. +func (dm *DockerManager) determineContainerIP(podNamespace, podName string, container *docker.Container) string { + result := "" + + if container.NetworkSettings != nil { + result = container.NetworkSettings.IPAddress + } + + if dm.networkPlugin.Name() != network.DefaultPluginName { + netStatus, err := dm.networkPlugin.Status(podNamespace, podName, kubetypes.DockerID(container.ID)) + if err != nil { + glog.Errorf("NetworkPlugin %s failed on the status hook for pod '%s' - %v", dm.networkPlugin.Name(), podName, err) + } else if netStatus != nil { + result = netStatus.IP.String() + } + } + + return result +} + func (dm *DockerManager) inspectContainer(dockerID, containerName, tPath string, pod *api.Pod) *containerStatusResult { result := containerStatusResult{api.ContainerStatus{}, "", nil} inspectResult, err := dm.client.InspectContainer(dockerID) - if err != nil { result.err = err return &result } + // NOTE (pmorie): this is a seriously fishy if statement. A nil result from + // InspectContainer seems like it should should always be paired with a + // non-nil error in the result of InspectContainer. if inspectResult == nil { + glog.Errorf("Received a nil result from InspectContainer without receiving an error for container ID %v", dockerID) // Why did we not get an error? return &result } - glog.V(3).Infof("Container inspect result: %+v", *inspectResult) + glog.V(4).Infof("Container inspect result: %+v", *inspectResult) result.status = api.ContainerStatus{ Name: containerName, Image: inspectResult.Config.Image, @@ -316,41 +378,40 @@ func (dm *DockerManager) inspectContainer(dockerID, containerName, tPath string, if inspectResult.State.Running { result.status.State.Running = &api.ContainerStateRunning{ - StartedAt: util.NewTime(inspectResult.State.StartedAt), + StartedAt: unversioned.NewTime(inspectResult.State.StartedAt), } if containerName == PodInfraContainerName { - if inspectResult.NetworkSettings != nil { - result.ip = inspectResult.NetworkSettings.IPAddress - } - // override the above if a network plugin exists - if dm.networkPlugin.Name() != network.DefaultPluginName { - netStatus, err := dm.networkPlugin.Status(pod.Namespace, pod.Name, kubeletTypes.DockerID(dockerID)) - if err != nil { - glog.Errorf("NetworkPlugin %s failed on the status hook for pod '%s' - %v", dm.networkPlugin.Name(), pod.Name, err) - } else if netStatus != nil { - result.ip = netStatus.IP.String() - } - } + result.ip = dm.determineContainerIP(pod.Namespace, pod.Name, inspectResult) } - } else if !inspectResult.State.FinishedAt.IsZero() { + } else if !inspectResult.State.FinishedAt.IsZero() || inspectResult.State.ExitCode != 0 { + // When a container fails to start State.ExitCode is non-zero, FinishedAt and StartedAt are both zero reason := "" - message := "" + message := inspectResult.State.Error + finishedAt := unversioned.NewTime(inspectResult.State.FinishedAt) + startedAt := unversioned.NewTime(inspectResult.State.StartedAt) + // Note: An application might handle OOMKilled gracefully. // In that case, the container is oom killed, but the exit // code could be 0. if inspectResult.State.OOMKilled { reason = "OOMKilled" - } else { + } else if inspectResult.State.ExitCode == 0 { + reason = "Completed" + } else if !inspectResult.State.FinishedAt.IsZero() { reason = "Error" - message = inspectResult.State.Error + } else { + // finishedAt is zero and ExitCode is nonZero occurs when docker fails to start the container + reason = ErrContainerCannotRun.Error() + // Adjust time to the time docker attempted to run the container, otherwise startedAt and finishedAt will be set to epoch, which is misleading + finishedAt = unversioned.NewTime(inspectResult.Created) + startedAt = unversioned.NewTime(inspectResult.Created) } result.status.State.Terminated = &api.ContainerStateTerminated{ - ExitCode: inspectResult.State.ExitCode, - Message: message, - Reason: reason, - - StartedAt: util.NewTime(inspectResult.State.StartedAt), - FinishedAt: util.NewTime(inspectResult.State.FinishedAt), + ExitCode: inspectResult.State.ExitCode, + Message: message, + Reason: reason, + StartedAt: startedAt, + FinishedAt: finishedAt, ContainerID: DockerPrefix + dockerID, } if tPath != "" { @@ -364,13 +425,7 @@ func (dm *DockerManager) inspectContainer(dockerID, containerName, tPath string, } } } - } else { - // TODO(dchen1107): Separate issue docker/docker#8294 was filed - result.status.State.Waiting = &api.ContainerStateWaiting{ - Reason: ErrContainerCannotRun.Error(), - } } - return &result } @@ -382,7 +437,7 @@ func (dm *DockerManager) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) { manifest := pod.Spec oldStatuses := make(map[string]api.ContainerStatus, len(pod.Spec.Containers)) - lastObservedTime := make(map[string]util.Time, len(pod.Spec.Containers)) + lastObservedTime := make(map[string]unversioned.Time, len(pod.Spec.Containers)) // Record the last time we observed a container termination. for _, status := range pod.Status.ContainerStatuses { oldStatuses[status.Name] = status @@ -485,11 +540,23 @@ func (dm *DockerManager) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) { // Handle the containers for which we cannot find any associated active or dead docker containers or are in restart backoff for _, container := range manifest.Containers { if containerStatus, found := statuses[container.Name]; found { - reason, ok := dm.reasonCache.Get(uid, container.Name) - if ok && reason == kubecontainer.ErrCrashLoopBackOff.Error() { + reasonInfo, ok := dm.reasonCache.Get(uid, container.Name) + if ok && reasonInfo.reason == kubecontainer.ErrCrashLoopBackOff.Error() { + // We need to increment the restart count if we are going to + // move the current state to last terminated state. + if containerStatus.State.Terminated != nil { + lastObservedTime, ok := lastObservedTime[container.Name] + if !ok || containerStatus.State.Terminated.FinishedAt.After(lastObservedTime.Time) { + containerStatus.RestartCount += 1 + } + } containerStatus.LastTerminationState = containerStatus.State - containerStatus.State.Waiting = &api.ContainerStateWaiting{Reason: reason} - containerStatus.State.Running = nil + containerStatus.State = api.ContainerState{ + Waiting: &api.ContainerStateWaiting{ + Reason: reasonInfo.reason, + Message: reasonInfo.message, + }, + } } continue } @@ -502,20 +569,27 @@ func (dm *DockerManager) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) { containerStatus.RestartCount = oldStatus.RestartCount containerStatus.LastTerminationState = oldStatus.LastTerminationState } - //Check image is ready on the node or not. - image := container.Image // TODO(dchen1107): docker/docker/issues/8365 to figure out if the image exists - _, err := dm.client.InspectImage(image) - if err == nil { - containerStatus.State.Waiting = &api.ContainerStateWaiting{ - Message: fmt.Sprintf("Image: %s is ready, container is creating", image), - Reason: "ContainerCreating", - } - } else if err == docker.ErrNoSuchImage { - containerStatus.State.Waiting = &api.ContainerStateWaiting{ - Message: fmt.Sprintf("Image: %s is not ready on the node", image), - Reason: "ImageNotReady", + reasonInfo, ok := dm.reasonCache.Get(uid, container.Name) + if !ok { + // default position for a container + // At this point there are no active or dead containers, the reasonCache is empty (no entry or the entry has expired) + // its reasonable to say the container is being created till a more accurate reason is logged + containerStatus.State = api.ContainerState{ + Waiting: &api.ContainerStateWaiting{ + Reason: fmt.Sprintf("ContainerCreating"), + Message: fmt.Sprintf("Image: %s is ready, container is creating", container.Image), + }, } + } else if reasonInfo.reason == kubecontainer.ErrImagePullBackOff.Error() || + reasonInfo.reason == kubecontainer.ErrImageInspect.Error() || + reasonInfo.reason == kubecontainer.ErrImagePull.Error() || + reasonInfo.reason == kubecontainer.ErrImageNeverPull.Error() { + // mark it as waiting, reason will be filled bellow + containerStatus.State = api.ContainerState{Waiting: &api.ContainerStateWaiting{}} + } else if reasonInfo.reason == kubecontainer.ErrRunContainer.Error() { + // mark it as waiting, reason will be filled bellow + containerStatus.State = api.ContainerState{Waiting: &api.ContainerStateWaiting{}} } statuses[container.Name] = &containerStatus } @@ -523,9 +597,11 @@ func (dm *DockerManager) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) { podStatus.ContainerStatuses = make([]api.ContainerStatus, 0) for containerName, status := range statuses { if status.State.Waiting != nil { + status.State.Running = nil // For containers in the waiting state, fill in a specific reason if it is recorded. - if reason, ok := dm.reasonCache.Get(uid, containerName); ok { - status.State.Waiting.Reason = reason + if reasonInfo, ok := dm.reasonCache.Get(uid, containerName); ok { + status.State.Waiting.Reason = reasonInfo.reason + status.State.Waiting.Message = reasonInfo.message } } podStatus.ContainerStatuses = append(podStatus.ContainerStatuses, *status) @@ -533,7 +609,7 @@ func (dm *DockerManager) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) { // Sort the container statuses since clients of this interface expect the list // of containers in a pod to behave like the output of `docker list`, which has a // deterministic order. - sort.Sort(kubeletTypes.SortedContainerStatuses(podStatus.ContainerStatuses)) + sort.Sort(kubetypes.SortedContainerStatuses(podStatus.ContainerStatuses)) return &podStatus, nil } @@ -584,13 +660,24 @@ func makePortsAndBindings(portMappings []kubecontainer.PortMapping) (map[docker. glog.Warningf("Unknown protocol %q: defaulting to TCP", port.Protocol) protocol = "/tcp" } + dockerPort := docker.Port(strconv.Itoa(interiorPort) + protocol) exposedPorts[dockerPort] = struct{}{} - portBindings[dockerPort] = []docker.PortBinding{ - { - HostPort: strconv.Itoa(exteriorPort), - HostIP: port.HostIP, - }, + + hostBinding := docker.PortBinding{ + HostPort: strconv.Itoa(exteriorPort), + HostIP: port.HostIP, + } + + // Allow multiple host ports bind to same docker port + if existedBindings, ok := portBindings[dockerPort]; ok { + // If a docker port already map to a host port, just append the host ports + portBindings[dockerPort] = append(existedBindings, hostBinding) + } else { + // Otherwise, it's fresh new port binding + portBindings[dockerPort] = []docker.PortBinding{ + hostBinding, + } } } return exposedPorts, portBindings @@ -604,7 +691,7 @@ func (dm *DockerManager) runContainer( netMode string, ipcMode string, utsMode string, - pidMode string) (string, error) { + pidMode string) (kubecontainer.ContainerID, error) { dockerName := KubeletContainerName{ PodFullName: kubecontainer.GetPodFullName(pod), @@ -634,7 +721,7 @@ func (dm *DockerManager) runContainer( } if container.Lifecycle != nil && container.Lifecycle.PreStop != nil { // TODO: This is kind of hacky, we should really just encode the bits we need. - data, err := latest.Codec.Encode(pod) + data, err := latest.GroupOrDie("").Codec.Encode(pod) if err != nil { glog.Errorf("Failed to encode pod: %s for prestop hook", pod.Name) } else { @@ -688,7 +775,7 @@ func (dm *DockerManager) runContainer( if ref != nil { dm.recorder.Eventf(ref, "Failed", "Failed to create docker container with error: %v", err) } - return "", err + return kubecontainer.ContainerID{}, err } if ref != nil { @@ -752,12 +839,12 @@ func (dm *DockerManager) runContainer( dm.recorder.Eventf(ref, "Failed", "Failed to start with docker id %v with error: %v", util.ShortenString(dockerContainer.ID, 12), err) } - return "", err + return kubecontainer.ContainerID{}, err } if ref != nil { dm.recorder.Eventf(ref, "Started", "Started with docker id %v", util.ShortenString(dockerContainer.ID, 12)) } - return dockerContainer.ID, nil + return kubetypes.DockerID(dockerContainer.ID).ContainerID(), nil } func setEntrypointAndCommand(container *api.Container, opts *kubecontainer.RunContainerOptions, dockerOpts *docker.CreateContainerOptions) { @@ -899,7 +986,7 @@ func (dm *DockerManager) podInfraContainerChanged(pod *api.Pod, podInfraContaine networkMode := "" var ports []api.ContainerPort - dockerPodInfraContainer, err := dm.client.InspectContainer(string(podInfraContainer.ID)) + dockerPodInfraContainer, err := dm.client.InspectContainer(podInfraContainer.ID.ID) if err != nil { return false, err } @@ -908,9 +995,9 @@ func (dm *DockerManager) podInfraContainerChanged(pod *api.Pod, podInfraContaine if dockerPodInfraContainer.HostConfig != nil { networkMode = dockerPodInfraContainer.HostConfig.NetworkMode } - if pod.Spec.HostNetwork { + if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork { if networkMode != "host" { - glog.V(4).Infof("host: %v, %v", pod.Spec.HostNetwork, networkMode) + glog.V(4).Infof("host: %v, %v", pod.Spec.SecurityContext.HostNetwork, networkMode) return true, nil } } else { @@ -985,14 +1072,14 @@ func (dm *DockerManager) nativeExecSupportExists() (bool, error) { return false, err } -func (dm *DockerManager) getRunInContainerCommand(containerID string, cmd []string) (*exec.Cmd, error) { +func (dm *DockerManager) getRunInContainerCommand(containerID kubecontainer.ContainerID, cmd []string) (*exec.Cmd, error) { args := append([]string{"exec"}, cmd...) command := exec.Command("/usr/sbin/nsinit", args...) - command.Dir = fmt.Sprintf("/var/lib/docker/execdriver/native/%s", containerID) + command.Dir = fmt.Sprintf("/var/lib/docker/execdriver/native/%s", containerID.ID) return command, nil } -func (dm *DockerManager) runInContainerUsingNsinit(containerID string, cmd []string) ([]byte, error) { +func (dm *DockerManager) runInContainerUsingNsinit(containerID kubecontainer.ContainerID, cmd []string) ([]byte, error) { c, err := dm.getRunInContainerCommand(containerID, cmd) if err != nil { return nil, err @@ -1001,8 +1088,7 @@ func (dm *DockerManager) runInContainerUsingNsinit(containerID string, cmd []str } // RunInContainer uses nsinit to run the command inside the container identified by containerID -// TODO(yifan): Use strong type for containerID. -func (dm *DockerManager) RunInContainer(containerID string, cmd []string) ([]byte, error) { +func (dm *DockerManager) RunInContainer(containerID kubecontainer.ContainerID, cmd []string) ([]byte, error) { // If native exec support does not exist in the local docker daemon use nsinit. useNativeExec, err := dm.nativeExecSupportExists() if err != nil { @@ -1014,7 +1100,7 @@ func (dm *DockerManager) RunInContainer(containerID string, cmd []string) ([]byt } glog.V(2).Infof("Using docker native exec to run cmd %+v inside container %s", cmd, containerID) createOpts := docker.CreateExecOptions{ - Container: containerID, + Container: containerID.ID, Cmd: cmd, AttachStdin: false, AttachStdout: true, @@ -1080,15 +1166,12 @@ func (d *dockerExitError) ExitStatus() int { } // ExecInContainer runs the command inside the container identified by containerID. -// -// TODO: -// - use strong type for containerId -func (dm *DockerManager) ExecInContainer(containerId string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { +func (dm *DockerManager) ExecInContainer(containerID kubecontainer.ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { if dm.execHandler == nil { return errors.New("unable to exec without an exec handler") } - container, err := dm.client.InspectContainer(containerId) + container, err := dm.client.InspectContainer(containerID.ID) if err != nil { return err } @@ -1099,9 +1182,9 @@ func (dm *DockerManager) ExecInContainer(containerId string, cmd []string, stdin return dm.execHandler.ExecInContainer(dm.client, container, cmd, stdin, stdout, stderr, tty) } -func (dm *DockerManager) AttachContainer(containerId string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { +func (dm *DockerManager) AttachContainer(containerID kubecontainer.ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { opts := docker.AttachToContainerOptions{ - Container: containerId, + Container: containerID.ID, InputStream: stdin, OutputStream: stdout, ErrorStream: stderr, @@ -1132,7 +1215,7 @@ func (dm *DockerManager) PortForward(pod *kubecontainer.Pod, port uint16, stream if podInfraContainer == nil { return noPodInfraContainerError(pod.Name, pod.Namespace) } - container, err := dm.client.InspectContainer(string(podInfraContainer.ID)) + container, err := dm.client.InspectContainer(podInfraContainer.ID.ID) if err != nil { return err } @@ -1142,19 +1225,68 @@ func (dm *DockerManager) PortForward(pod *kubecontainer.Pod, port uint16, stream } containerPid := container.State.Pid - // TODO what if the host doesn't have it??? - _, lookupErr := exec.LookPath("socat") + socatPath, lookupErr := exec.LookPath("socat") if lookupErr != nil { - return fmt.Errorf("Unable to do port forwarding: socat not found.") + return fmt.Errorf("unable to do port forwarding: socat not found.") } - args := []string{"-t", fmt.Sprintf("%d", containerPid), "-n", "socat", "-", fmt.Sprintf("TCP4:localhost:%d", port)} - // TODO use exec.LookPath - command := exec.Command("nsenter", args...) - command.Stdin = stream + + args := []string{"-t", fmt.Sprintf("%d", containerPid), "-n", socatPath, "-", fmt.Sprintf("TCP4:localhost:%d", port)} + + nsenterPath, lookupErr := exec.LookPath("nsenter") + if lookupErr != nil { + return fmt.Errorf("unable to do port forwarding: nsenter not found.") + } + + command := exec.Command(nsenterPath, args...) command.Stdout = stream + + // If we use Stdin, command.Run() won't return until the goroutine that's copying + // from stream finishes. Unfortunately, if you have a client like telnet connected + // via port forwarding, as long as the user's telnet client is connected to the user's + // local listener that port forwarding sets up, the telnet session never exits. This + // means that even if socat has finished running, command.Run() won't ever return + // (because the client still has the connection and stream open). + // + // The work around is to use StdinPipe(), as Wait() (called by Run()) closes the pipe + // when the command (socat) exits. + inPipe, err := command.StdinPipe() + if err != nil { + return fmt.Errorf("unable to do port forwarding: error creating stdin pipe: %v", err) + } + go func() { + io.Copy(inPipe, stream) + inPipe.Close() + }() + return command.Run() } +// Get the IP address of a container's interface using nsenter +func (dm *DockerManager) GetContainerIP(containerID, interfaceName string) (string, error) { + _, lookupErr := exec.LookPath("nsenter") + if lookupErr != nil { + return "", fmt.Errorf("Unable to obtain IP address of container: missing nsenter.") + } + container, err := dm.client.InspectContainer(containerID) + if err != nil { + return "", err + } + + if !container.State.Running { + return "", fmt.Errorf("container not running (%s)", container.ID) + } + + containerPid := container.State.Pid + extractIPCmd := fmt.Sprintf("ip -4 addr show %s | grep inet | awk -F\" \" '{print $2}'", interfaceName) + args := []string{"-t", fmt.Sprintf("%d", containerPid), "-n", "--", "bash", "-c", extractIPCmd} + command := exec.Command("nsenter", args...) + out, err := command.CombinedOutput() + if err != nil { + return "", err + } + return string(out), nil +} + // Kills all containers in the specified pod func (dm *DockerManager) KillPod(pod *api.Pod, runningPod kubecontainer.Pod) error { // Send the kills in parallel since they may take a long time. Len + 1 since there @@ -1200,7 +1332,7 @@ func (dm *DockerManager) KillPod(pod *api.Pod, runningPod kubecontainer.Pod) err } wg.Wait() if networkContainer != nil { - if err := dm.networkPlugin.TearDownPod(runningPod.Namespace, runningPod.Name, kubeletTypes.DockerID(networkContainer.ID)); err != nil { + if err := dm.networkPlugin.TearDownPod(runningPod.Namespace, runningPod.Name, kubetypes.DockerID(networkContainer.ID.ID)); err != nil { glog.Errorf("Failed tearing down the infra container: %v", err) errs <- err } @@ -1222,9 +1354,9 @@ func (dm *DockerManager) KillPod(pod *api.Pod, runningPod kubecontainer.Pod) err // KillContainerInPod kills a container in the pod. It must be passed either a container ID or a container and pod, // and will attempt to lookup the other information if missing. -func (dm *DockerManager) KillContainerInPod(containerID types.UID, container *api.Container, pod *api.Pod) error { +func (dm *DockerManager) KillContainerInPod(containerID kubecontainer.ContainerID, container *api.Container, pod *api.Pod) error { switch { - case len(containerID) == 0: + case containerID.IsEmpty(): // Locate the container. pods, err := dm.GetPods(false) if err != nil { @@ -1239,7 +1371,7 @@ func (dm *DockerManager) KillContainerInPod(containerID types.UID, container *ap case container == nil || pod == nil: // Read information about the container from labels - inspect, err := dm.client.InspectContainer(string(containerID)) + inspect, err := dm.client.InspectContainer(containerID.ID) if err != nil { return err } @@ -1259,8 +1391,8 @@ func (dm *DockerManager) KillContainerInPod(containerID types.UID, container *ap // killContainer accepts a containerID and an optional container or pod containing shutdown policies. Invoke // KillContainerInPod if information must be retrieved first. -func (dm *DockerManager) killContainer(containerID types.UID, container *api.Container, pod *api.Pod) error { - ID := string(containerID) +func (dm *DockerManager) killContainer(containerID kubecontainer.ContainerID, container *api.Container, pod *api.Pod) error { + ID := containerID.ID name := ID if container != nil { name = fmt.Sprintf("%s %s", name, container.Name) @@ -1279,7 +1411,7 @@ func (dm *DockerManager) killContainer(containerID types.UID, container *api.Con } } glog.V(2).Infof("Killing container %q with %d second grace period", name, gracePeriod) - start := util.Now() + start := unversioned.Now() if pod != nil && container != nil && container.Lifecycle != nil && container.Lifecycle.PreStop != nil { glog.V(4).Infof("Running preStop hook for container %q", name) @@ -1287,7 +1419,7 @@ func (dm *DockerManager) killContainer(containerID types.UID, container *api.Con go func() { defer close(done) defer util.HandleCrash() - if err := dm.runner.Run(ID, pod, container, container.Lifecycle.PreStop); err != nil { + if err := dm.runner.Run(containerID, pod, container, container.Lifecycle.PreStop); err != nil { glog.Errorf("preStop hook for container %q failed: %v", name, err) } }() @@ -1297,11 +1429,9 @@ func (dm *DockerManager) killContainer(containerID types.UID, container *api.Con case <-done: glog.V(4).Infof("preStop hook for container %q completed", name) } - gracePeriod -= int64(util.Now().Sub(start.Time).Seconds()) + gracePeriod -= int64(unversioned.Now().Sub(start.Time).Seconds()) } - dm.readinessManager.RemoveReadiness(ID) - // always give containers a minimal shutdown window to avoid unnecessary SIGKILLs if gracePeriod < minimumGracePeriodInSeconds { gracePeriod = minimumGracePeriodInSeconds @@ -1312,17 +1442,17 @@ func (dm *DockerManager) killContainer(containerID types.UID, container *api.Con return nil } if err == nil { - glog.V(2).Infof("Container %q exited after %s", name, util.Now().Sub(start.Time)) + glog.V(2).Infof("Container %q exited after %s", name, unversioned.Now().Sub(start.Time)) } else { - glog.V(2).Infof("Container %q termination failed after %s: %v", name, util.Now().Sub(start.Time), err) + glog.V(2).Infof("Container %q termination failed after %s: %v", name, unversioned.Now().Sub(start.Time), err) } - ref, ok := dm.containerRefManager.GetRef(ID) + ref, ok := dm.containerRefManager.GetRef(containerID) if !ok { glog.Warningf("No ref for pod '%q'", name) } else { // TODO: pass reason down here, and state, or move this call up the stack. dm.recorder.Eventf(ref, "Killing", "Killing with docker id %v", util.ShortenString(ID, 12)) - dm.containerRefManager.ClearRef(ID) + dm.containerRefManager.ClearRef(containerID) } return err } @@ -1339,7 +1469,7 @@ func containerAndPodFromLabels(inspect *docker.Container) (pod *api.Pod, contain // the pod data may not be set if body, found := labels[kubernetesPodLabel]; found { pod = &api.Pod{} - if err = latest.Codec.DecodeInto([]byte(body), pod); err == nil { + if err = latest.GroupOrDie("").Codec.DecodeInto([]byte(body), pod); err == nil { name := labels[kubernetesContainerLabel] for ix := range pod.Spec.Containers { if pod.Spec.Containers[ix].Name == name { @@ -1370,7 +1500,7 @@ func containerAndPodFromLabels(inspect *docker.Container) (pod *api.Pod, contain } // Run a single container from a pod. Returns the docker container ID -func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Container, netMode, ipcMode, pidMode string) (kubeletTypes.DockerID, error) { +func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Container, netMode, ipcMode, pidMode string) (kubecontainer.ContainerID, error) { start := time.Now() defer func() { metrics.ContainerManagerLatency.WithLabelValues("runContainerInPod").Observe(metrics.SinceInMicroseconds(start)) @@ -1383,16 +1513,16 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe opts, err := dm.generator.GenerateRunContainerOptions(pod, container) if err != nil { - return "", err + return kubecontainer.ContainerID{}, err } utsMode := "" - if pod.Spec.HostNetwork { + if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork { utsMode = "host" } id, err := dm.runContainer(pod, container, opts, ref, netMode, ipcMode, utsMode, pidMode) if err != nil { - return "", err + return kubecontainer.ContainerID{}, err } // Remember this reference so we can report events about this container @@ -1403,8 +1533,8 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe if container.Lifecycle != nil && container.Lifecycle.PostStart != nil { handlerErr := dm.runner.Run(id, pod, container, container.Lifecycle.PostStart) if handlerErr != nil { - dm.KillContainerInPod(types.UID(id), container, pod) - return kubeletTypes.DockerID(""), fmt.Errorf("failed to call event handler: %v", handlerErr) + dm.KillContainerInPod(id, container, pod) + return kubecontainer.ContainerID{}, fmt.Errorf("failed to call event handler: %v", handlerErr) } } @@ -1413,20 +1543,20 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe // capture these symbolic filenames which can be used for search terms in Elasticsearch or for // labels for Cloud Logging. podFullName := kubecontainer.GetPodFullName(pod) - containerLogFile := path.Join(dm.dockerRoot, "containers", id, fmt.Sprintf("%s-json.log", id)) - symlinkFile := LogSymlink(dm.containerLogsDir, podFullName, container.Name, id) + containerLogFile := path.Join(dm.dockerRoot, "containers", id.ID, fmt.Sprintf("%s-json.log", id.ID)) + symlinkFile := LogSymlink(dm.containerLogsDir, podFullName, container.Name, id.ID) if err = dm.os.Symlink(containerLogFile, symlinkFile); err != nil { glog.Errorf("Failed to create symbolic link to the log file of pod %q container %q: %v", podFullName, container.Name, err) } // Container information is used in adjusting OOM scores and adding ndots. - containerInfo, err := dm.client.InspectContainer(string(id)) + containerInfo, err := dm.client.InspectContainer(id.ID) if err != nil { - return "", err + return kubecontainer.ContainerID{}, err } // Ensure the PID actually exists, else we'll move ourselves. if containerInfo.State.Pid == 0 { - return "", fmt.Errorf("failed to get init PID for Docker container %q", string(id)) + return kubecontainer.ContainerID{}, fmt.Errorf("failed to get init PID for Docker container %q", id) } // Set OOM score of the container based on the priority of the container. @@ -1435,16 +1565,16 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe // whole pod will die. var oomScoreAdj int if container.Name == PodInfraContainerName { - oomScoreAdj = qos.PodInfraOomAdj + oomScoreAdj = qos.PodInfraOOMAdj } else { - oomScoreAdj = qos.GetContainerOomScoreAdjust(container, dm.machineInfo.MemoryCapacity) + oomScoreAdj = qos.GetContainerOOMScoreAdjust(container, dm.machineInfo.MemoryCapacity) } cgroupName, err := dm.procFs.GetFullContainerName(containerInfo.State.Pid) if err != nil { - return "", err + return kubecontainer.ContainerID{}, err } - if err = dm.oomAdjuster.ApplyOomScoreAdjContainer(cgroupName, oomScoreAdj, 5); err != nil { - return "", err + if err = dm.oomAdjuster.ApplyOOMScoreAdjContainer(cgroupName, oomScoreAdj, 5); err != nil { + return kubecontainer.ContainerID{}, err } // currently, Docker does not have a flag by which the ndots option can be passed. @@ -1457,7 +1587,7 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe err = addNDotsOption(containerInfo.ResolvConfPath) } - return kubeletTypes.DockerID(id), err + return id, err } func addNDotsOption(resolvFilePath string) error { @@ -1491,7 +1621,7 @@ func appendToFile(filePath, stringToAppend string) error { } // createPodInfraContainer starts the pod infra container for a pod. Returns the docker container ID of the newly created container. -func (dm *DockerManager) createPodInfraContainer(pod *api.Pod) (kubeletTypes.DockerID, error) { +func (dm *DockerManager) createPodInfraContainer(pod *api.Pod) (kubetypes.DockerID, error) { start := time.Now() defer func() { metrics.ContainerManagerLatency.WithLabelValues("createPodInfraContainer").Observe(metrics.SinceInMicroseconds(start)) @@ -1500,7 +1630,11 @@ func (dm *DockerManager) createPodInfraContainer(pod *api.Pod) (kubeletTypes.Doc netNamespace := "" var ports []api.ContainerPort - if pod.Spec.HostNetwork { + if dm.networkPlugin.Name() == "cni" { + netNamespace = "none" + } + + if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork { netNamespace = "host" } else { // Docker only exports ports from the pod infra container. Let's @@ -1518,7 +1652,8 @@ func (dm *DockerManager) createPodInfraContainer(pod *api.Pod) (kubeletTypes.Doc } // No pod secrets for the infra container. - if err := dm.imagePuller.PullImage(pod, container, nil); err != nil { + // The message isnt needed for the Infra container + if err, _ := dm.imagePuller.PullImage(pod, container, nil); err != nil { return "", err } @@ -1527,14 +1662,14 @@ func (dm *DockerManager) createPodInfraContainer(pod *api.Pod) (kubeletTypes.Doc return "", err } - return id, nil + return kubetypes.DockerID(id.ID), nil } // TODO(vmarmol): This will soon be made non-public when its only use is internal. // Structure keeping information on changes that need to happen for a pod. The semantics is as follows: // - startInfraContainer is true if new Infra Containers have to be started and old one (if running) killed. // Additionally if it is true then containersToKeep have to be empty -// - infraContainerId have to be set iff startInfraContainer is false. It stores dockerID of running Infra Container +// - infraContainerId have to be set if and only if startInfraContainer is false. It stores dockerID of running Infra Container // - containersToStart keeps indices of Specs of containers that have to be started. // - containersToKeep stores mapping from dockerIDs of running containers to indices of their Specs for containers that // should be kept running. If startInfraContainer is false then it contains an entry for infraContainerId (mapped to -1). @@ -1544,9 +1679,9 @@ func (dm *DockerManager) createPodInfraContainer(pod *api.Pod) (kubeletTypes.Doc type empty struct{} type PodContainerChangesSpec struct { StartInfraContainer bool - InfraContainerId kubeletTypes.DockerID + InfraContainerId kubetypes.DockerID ContainersToStart map[int]empty - ContainersToKeep map[kubeletTypes.DockerID]int + ContainersToKeep map[kubetypes.DockerID]int } func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kubecontainer.Pod, podStatus api.PodStatus) (PodContainerChangesSpec, error) { @@ -1560,11 +1695,10 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub glog.V(4).Infof("Syncing Pod %+v, podFullName: %q, uid: %q", pod, podFullName, uid) containersToStart := make(map[int]empty) - containersToKeep := make(map[kubeletTypes.DockerID]int) - createPodInfraContainer := false + containersToKeep := make(map[kubetypes.DockerID]int) var err error - var podInfraContainerID kubeletTypes.DockerID + var podInfraContainerID kubetypes.DockerID var changed bool podInfraContainer := runningPod.FindContainerByName(PodInfraContainerName) if podInfraContainer != nil { @@ -1575,7 +1709,7 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub } } - createPodInfraContainer = true + createPodInfraContainer := true if podInfraContainer == nil { glog.V(2).Infof("Need to restart pod infra container for %q because it is not found", podFullName) } else if changed { @@ -1583,7 +1717,7 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub } else { glog.V(4).Infof("Pod infra container looks good, keep it %q", podFullName) createPodInfraContainer = false - podInfraContainerID = kubeletTypes.DockerID(podInfraContainer.ID) + podInfraContainerID = kubetypes.DockerID(podInfraContainer.ID.ID) containersToKeep[podInfraContainerID] = -1 } @@ -1592,7 +1726,7 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub c := runningPod.FindContainerByName(container.Name) if c == nil { - if kubecontainer.ShouldContainerBeRestarted(&container, pod, &podStatus, dm.readinessManager) { + if kubecontainer.ShouldContainerBeRestarted(&container, pod, &podStatus) { // If we are here it means that the container is dead and should be restarted, or never existed and should // be created. We may be inserting this ID again if the container has changed and it has // RestartPolicy::Always, but it's not a big deal. @@ -1602,13 +1736,13 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub continue } - containerID := kubeletTypes.DockerID(c.ID) + containerID := kubetypes.DockerID(c.ID.ID) hash := c.Hash glog.V(3).Infof("pod %q container %q exists as %v", podFullName, container.Name, containerID) if createPodInfraContainer { // createPodInfraContainer == true and Container exists - // If we're creating infra containere everything will be killed anyway + // If we're creating infra container everything will be killed anyway // If RestartPolicy is Always or OnFailure we restart containers that were running before we // killed them when restarting Infra Container. if pod.Spec.RestartPolicy != api.RestartPolicyNever { @@ -1627,7 +1761,7 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub continue } - result, err := dm.prober.Probe(pod, podStatus, container, string(c.ID), c.Created) + result, err := dm.prober.ProbeLiveness(pod, podStatus, container, c.ID, c.Created) if err != nil { // TODO(vmarmol): examine this logic. glog.V(2).Infof("probe no-error: %q", container.Name) @@ -1639,8 +1773,10 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub containersToKeep[containerID] = index continue } - glog.Infof("pod %q container %q is unhealthy (probe result: %v), it will be killed and re-created.", podFullName, container.Name, result) - containersToStart[index] = empty{} + if pod.Spec.RestartPolicy != api.RestartPolicyNever { + glog.Infof("pod %q container %q is unhealthy (probe result: %v), it will be killed and re-created.", podFullName, container.Name, result) + containersToStart[index] = empty{} + } } // After the loop one of the following should be true: @@ -1650,7 +1786,7 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub // If Infra container is the last running one, we don't want to keep it. if !createPodInfraContainer && len(containersToStart) == 0 && len(containersToKeep) == 1 { - containersToKeep = make(map[kubeletTypes.DockerID]int) + containersToKeep = make(map[kubetypes.DockerID]int) } return PodContainerChangesSpec{ @@ -1662,12 +1798,12 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub } // updateReasonCache updates the failure reason based on the latest error. -func (dm *DockerManager) updateReasonCache(pod *api.Pod, container *api.Container, err error) { - if err == nil { +func (dm *DockerManager) updateReasonCache(pod *api.Pod, container *api.Container, briefError string, err error) { + if briefError == "" || err == nil { return } errString := err.Error() - dm.reasonCache.Add(pod.UID, container.Name, errString) + dm.reasonCache.Add(pod.UID, container.Name, briefError, errString) } // clearReasonCache removes the entry in the reason cache. @@ -1704,7 +1840,7 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, pod } else { // Otherwise kill any containers in this pod which are not specified as ones to keep. for _, container := range runningPod.Containers { - _, keep := containerChanges.ContainersToKeep[kubeletTypes.DockerID(container.ID)] + _, keep := containerChanges.ContainersToKeep[kubetypes.DockerID(container.ID.ID)] if !keep { glog.V(3).Infof("Killing unwanted container %+v", container) // attempt to find the appropriate container policy @@ -1728,13 +1864,21 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, pod if containerChanges.StartInfraContainer && (len(containerChanges.ContainersToStart) > 0) { glog.V(4).Infof("Creating pod infra container for %q", podFullName) podInfraContainerID, err = dm.createPodInfraContainer(pod) + if err != nil { + glog.Errorf("Failed to create pod infra container: %v; Skipping pod %q", err, podFullName) + return err + } // Call the networking plugin - if err == nil { - err = dm.networkPlugin.SetUpPod(pod.Namespace, pod.Name, podInfraContainerID) - } + err = dm.networkPlugin.SetUpPod(pod.Namespace, pod.Name, podInfraContainerID) if err != nil { glog.Errorf("Failed to create pod infra container: %v; Skipping pod %q", err, podFullName) + // Delete infra container + if delErr := dm.KillContainerInPod(kubecontainer.ContainerID{ + ID: string(podInfraContainerID), + Type: "docker"}, nil, pod); delErr != nil { + glog.Warningf("Clear infra container failed for pod %q: %v", podFullName, delErr) + } return err } @@ -1747,6 +1891,12 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, pod if err = hairpin.SetUpContainer(podInfraContainer.State.Pid, "eth0"); err != nil { glog.Warningf("Hairpin setup failed for pod %q: %v", podFullName, err) } + if podDependsOnPodIP(pod) { + // Find the pod IP after starting the infra container in order to expose + // it safely via the downward API without a race. + pod.Status.PodIP = dm.determineContainerIP(pod.Name, pod.Namespace, podInfraContainer) + } + } // Start everything @@ -1760,16 +1910,15 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, pod continue } glog.V(4).Infof("Creating container %+v in pod %v", container, podFullName) - err := dm.imagePuller.PullImage(pod, container, pullSecrets) - dm.updateReasonCache(pod, container, err) + err, msg := dm.imagePuller.PullImage(pod, container, pullSecrets) if err != nil { - glog.Warningf("Failed to pull image %q from pod %q and container %q: %v", container.Image, kubecontainer.GetPodFullName(pod), container.Name, err) + dm.updateReasonCache(pod, container, err.Error(), errors.New(msg)) continue } if container.SecurityContext != nil && container.SecurityContext.RunAsNonRoot { err := dm.verifyNonRoot(container) - dm.updateReasonCache(pod, container, err) + dm.updateReasonCache(pod, container, "VerifyNonRootError", err) if err != nil { glog.Errorf("Error running pod %q container %q: %v", kubecontainer.GetPodFullName(pod), container.Name, err) continue @@ -1783,7 +1932,7 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, pod // See createPodInfraContainer for infra container setup. namespaceMode := fmt.Sprintf("container:%v", podInfraContainerID) _, err = dm.runContainerInPod(pod, container, namespaceMode, namespaceMode, getPidMode(pod)) - dm.updateReasonCache(pod, container, err) + dm.updateReasonCache(pod, container, kubecontainer.ErrRunContainer.Error(), err) if err != nil { // TODO(bburns) : Perhaps blacklist a container after N failures? glog.Errorf("Error running pod %q container %q: %v", kubecontainer.GetPodFullName(pod), container.Name, err) @@ -1857,13 +2006,13 @@ func getUidFromUser(id string) string { } func (dm *DockerManager) doBackOff(pod *api.Pod, container *api.Container, podStatus api.PodStatus, backOff *util.Backoff) bool { - var ts util.Time + var ts unversioned.Time for _, containerStatus := range podStatus.ContainerStatuses { if containerStatus.Name != container.Name { continue } // first failure - if containerStatus.State.Terminated != nil { + if containerStatus.State.Terminated != nil && !containerStatus.State.Terminated.FinishedAt.IsZero() { ts = containerStatus.State.Terminated.FinishedAt break } @@ -1886,8 +2035,9 @@ func (dm *DockerManager) doBackOff(pod *api.Pod, container *api.Container, podSt if ref, err := kubecontainer.GenerateContainerRef(pod, container); err == nil { dm.recorder.Eventf(ref, "Backoff", "Back-off restarting failed docker container") } - dm.updateReasonCache(pod, container, kubecontainer.ErrCrashLoopBackOff) - glog.Infof("Back-off %s restarting failed container=%s pod=%s", backOff.Get(stableName), container.Name, kubecontainer.GetPodFullName(pod)) + err := fmt.Errorf("Back-off %s restarting failed container=%s pod=%s", backOff.Get(stableName), container.Name, kubecontainer.GetPodFullName(pod)) + dm.updateReasonCache(pod, container, kubecontainer.ErrCrashLoopBackOff.Error(), err) + glog.Infof("%s", err.Error()) return true } backOff.Next(stableName, ts.Time) @@ -1899,7 +2049,7 @@ func (dm *DockerManager) doBackOff(pod *api.Pod, container *api.Container, podSt // getPidMode returns the pid mode to use on the docker container based on pod.Spec.HostPID. func getPidMode(pod *api.Pod) string { pidMode := "" - if pod.Spec.HostPID { + if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostPID { pidMode = "host" } return pidMode @@ -1908,8 +2058,24 @@ func getPidMode(pod *api.Pod) string { // getIPCMode returns the ipc mode to use on the docker container based on pod.Spec.HostIPC. func getIPCMode(pod *api.Pod) string { ipcMode := "" - if pod.Spec.HostIPC { + if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostIPC { ipcMode = "host" } return ipcMode } + +// GetNetNs returns the network namespace path for the given container +func (dm *DockerManager) GetNetNs(containerID kubecontainer.ContainerID) (string, error) { + inspectResult, err := dm.client.InspectContainer(containerID.ID) + if err != nil { + glog.Errorf("Error inspecting container: '%v'", err) + return "", err + } + netnsPath := fmt.Sprintf(DockerNetnsFmt, inspectResult.State.Pid) + return netnsPath, nil +} + +// Garbage collection of dead containers +func (dm *DockerManager) GarbageCollect(gcPolicy kubecontainer.ContainerGCPolicy) error { + return dm.containerGC.GarbageCollect(gcPolicy) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/manager_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/manager_test.go index 4cadbffe3263..adc5509b5fb6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/manager_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/dockertools/manager_test.go @@ -17,7 +17,6 @@ limitations under the License. package dockertools import ( - "errors" "fmt" "io/ioutil" "net/http" @@ -32,13 +31,14 @@ import ( docker "github.com/fsouza/go-dockerclient" cadvisorApi "github.com/google/cadvisor/info/v1" + "github.com/stretchr/testify/assert" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/record" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/network" - kubeprober "k8s.io/kubernetes/pkg/kubelet/prober" - "k8s.io/kubernetes/pkg/probe" + "k8s.io/kubernetes/pkg/kubelet/prober" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" uexec "k8s.io/kubernetes/pkg/util/exec" @@ -77,14 +77,13 @@ func (*fakeOptionGenerator) GenerateRunContainerOptions(pod *api.Pod, container func newTestDockerManagerWithHTTPClient(fakeHTTPClient *fakeHTTP) (*DockerManager, *FakeDockerClient) { fakeDocker := &FakeDockerClient{VersionInfo: docker.Env{"Version=1.1.3", "ApiVersion=1.15"}, Errors: make(map[string]error), RemovedImages: sets.String{}} fakeRecorder := &record.FakeRecorder{} - readinessManager := kubecontainer.NewReadinessManager() containerRefManager := kubecontainer.NewRefManager() networkPlugin, _ := network.InitNetworkPlugin([]network.NetworkPlugin{}, "", network.NewFakeHost(nil)) optionGenerator := &fakeOptionGenerator{} dockerManager := NewFakeDockerManager( fakeDocker, fakeRecorder, - readinessManager, + prober.FakeProber{}, containerRefManager, &cadvisorApi.MachineInfo{}, PodInfraContainerImage, @@ -92,7 +91,8 @@ func newTestDockerManagerWithHTTPClient(fakeHTTPClient *fakeHTTP) (*DockerManage kubecontainer.FakeOS{}, networkPlugin, optionGenerator, - fakeHTTPClient) + fakeHTTPClient, + util.NewBackOff(time.Second, 300*time.Second)) return dockerManager, fakeDocker } @@ -349,7 +349,7 @@ func apiContainerToContainer(c docker.APIContainers) kubecontainer.Container { return kubecontainer.Container{} } return kubecontainer.Container{ - ID: types.UID(c.ID), + ID: kubecontainer.ContainerID{"docker", c.ID}, Name: dockerName.ContainerName, Hash: hash, } @@ -363,7 +363,7 @@ func dockerContainersToPod(containers DockerContainers) kubecontainer.Pod { continue } pod.Containers = append(pod.Containers, &kubecontainer.Container{ - ID: types.UID(c.ID), + ID: kubecontainer.ContainerID{"docker", c.ID}, Name: dockerName.ContainerName, Hash: hash, Image: c.Image, @@ -401,25 +401,17 @@ func TestKillContainerInPod(t *testing.T) { containerToKill := &containers[0] containerToSpare := &containers[1] fakeDocker.ContainerList = containers - // Set all containers to ready. - for _, c := range fakeDocker.ContainerList { - manager.readinessManager.SetReadiness(c.ID, true) - } - if err := manager.KillContainerInPod("", &pod.Spec.Containers[0], pod); err != nil { + if err := manager.KillContainerInPod(kubecontainer.ContainerID{}, &pod.Spec.Containers[0], pod); err != nil { t.Errorf("unexpected error: %v", err) } // Assert the container has been stopped. if err := fakeDocker.AssertStopped([]string{containerToKill.ID}); err != nil { t.Errorf("container was not stopped correctly: %v", err) } - - // Verify that the readiness has been removed for the stopped container. - if ready := manager.readinessManager.GetReadiness(containerToKill.ID); ready { - t.Errorf("exepcted container entry ID '%v' to not be found. states: %+v", containerToKill.ID, ready) - } - if ready := manager.readinessManager.GetReadiness(containerToSpare.ID); !ready { - t.Errorf("exepcted container entry ID '%v' to be found. states: %+v", containerToSpare.ID, ready) + // Assert the container has been spared. + if err := fakeDocker.AssertStopped([]string{containerToSpare.ID}); err == nil { + t.Errorf("container unexpectedly stopped: %v", containerToSpare.ID) } } @@ -474,12 +466,8 @@ func TestKillContainerInPodWithPreStop(t *testing.T) { }, }, } - // Set all containers to ready. - for _, c := range fakeDocker.ContainerList { - manager.readinessManager.SetReadiness(c.ID, true) - } - if err := manager.KillContainerInPod("", &pod.Spec.Containers[0], pod); err != nil { + if err := manager.KillContainerInPod(kubecontainer.ContainerID{}, &pod.Spec.Containers[0], pod); err != nil { t.Errorf("unexpected error: %v", err) } // Assert the container has been stopped. @@ -513,308 +501,12 @@ func TestKillContainerInPodWithError(t *testing.T) { Names: []string{"/k8s_bar_qux_new_1234_42"}, }, } - containerToKill := &containers[0] - containerToSpare := &containers[1] fakeDocker.ContainerList = containers fakeDocker.Errors["stop"] = fmt.Errorf("sample error") - // Set all containers to ready. - for _, c := range fakeDocker.ContainerList { - manager.readinessManager.SetReadiness(c.ID, true) - } - - if err := manager.KillContainerInPod("", &pod.Spec.Containers[0], pod); err == nil { + if err := manager.KillContainerInPod(kubecontainer.ContainerID{}, &pod.Spec.Containers[0], pod); err == nil { t.Errorf("expected error, found nil") } - - // Verify that the readiness has been removed even though the stop failed. - if ready := manager.readinessManager.GetReadiness(containerToKill.ID); ready { - t.Errorf("exepcted container entry ID '%v' to not be found. states: %+v", containerToKill.ID, ready) - } - if ready := manager.readinessManager.GetReadiness(containerToSpare.ID); !ready { - t.Errorf("exepcted container entry ID '%v' to be found. states: %+v", containerToSpare.ID, ready) - } -} - -type fakeExecProber struct { - result probe.Result - output string - err error -} - -func (p fakeExecProber) Probe(_ uexec.Cmd) (probe.Result, string, error) { - return p.result, p.output, p.err -} - -func replaceProber(dm *DockerManager, result probe.Result, err error) { - fakeExec := fakeExecProber{ - result: result, - err: err, - } - - dm.prober = kubeprober.NewTestProber(fakeExec, dm.readinessManager, dm.containerRefManager, &record.FakeRecorder{}) - return -} - -// TestProbeContainer tests the functionality of probeContainer. -// Test cases are: -// -// No probe. -// Only LivenessProbe. -// Only ReadinessProbe. -// Both probes. -// -// Also, for each probe, there will be several cases covering whether the initial -// delay has passed, whether the probe handler will return Success, Failure, -// Unknown or error. -// -// PLEASE READ THE PROBE DOCS BEFORE CHANGING THIS TEST IF YOU ARE UNSURE HOW PROBES ARE SUPPOSED TO WORK: -// (See https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/pod-states.md#pod-conditions) -func TestProbeContainer(t *testing.T) { - manager, _ := newTestDockerManager() - dc := &docker.APIContainers{ - ID: "foobar", - Created: time.Now().Unix(), - } - tests := []struct { - testContainer api.Container - expectError bool - expectedResult probe.Result - expectedReadiness bool - }{ - // No probes. - { - testContainer: api.Container{}, - expectedResult: probe.Success, - expectedReadiness: true, - }, - // Only LivenessProbe. expectedReadiness should always be true here. - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{InitialDelaySeconds: 100}, - }, - expectedResult: probe.Success, - expectedReadiness: true, - }, - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{InitialDelaySeconds: -100}, - }, - expectedResult: probe.Unknown, - expectedReadiness: true, - }, - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - }, - expectedResult: probe.Failure, - expectedReadiness: true, - }, - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - }, - expectedResult: probe.Success, - expectedReadiness: true, - }, - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - }, - expectedResult: probe.Unknown, - expectedReadiness: true, - }, - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - }, - expectError: true, - expectedResult: probe.Unknown, - expectedReadiness: true, - }, - // // Only ReadinessProbe. expectedResult should always be probe.Success here. - { - testContainer: api.Container{ - ReadinessProbe: &api.Probe{InitialDelaySeconds: 100}, - }, - expectedResult: probe.Success, - expectedReadiness: false, - }, - { - testContainer: api.Container{ - ReadinessProbe: &api.Probe{InitialDelaySeconds: -100}, - }, - expectedResult: probe.Success, - expectedReadiness: false, - }, - { - testContainer: api.Container{ - ReadinessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - }, - expectedResult: probe.Success, - expectedReadiness: true, - }, - { - testContainer: api.Container{ - ReadinessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - }, - expectedResult: probe.Success, - expectedReadiness: true, - }, - { - testContainer: api.Container{ - ReadinessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - }, - expectedResult: probe.Success, - expectedReadiness: true, - }, - { - testContainer: api.Container{ - ReadinessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - }, - expectError: false, - expectedResult: probe.Success, - expectedReadiness: true, - }, - // Both LivenessProbe and ReadinessProbe. - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{InitialDelaySeconds: 100}, - ReadinessProbe: &api.Probe{InitialDelaySeconds: 100}, - }, - expectedResult: probe.Success, - expectedReadiness: false, - }, - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{InitialDelaySeconds: 100}, - ReadinessProbe: &api.Probe{InitialDelaySeconds: -100}, - }, - expectedResult: probe.Success, - expectedReadiness: false, - }, - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{InitialDelaySeconds: -100}, - ReadinessProbe: &api.Probe{InitialDelaySeconds: 100}, - }, - expectedResult: probe.Unknown, - expectedReadiness: false, - }, - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{InitialDelaySeconds: -100}, - ReadinessProbe: &api.Probe{InitialDelaySeconds: -100}, - }, - expectedResult: probe.Unknown, - expectedReadiness: false, - }, - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - ReadinessProbe: &api.Probe{InitialDelaySeconds: -100}, - }, - expectedResult: probe.Unknown, - expectedReadiness: false, - }, - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - ReadinessProbe: &api.Probe{InitialDelaySeconds: -100}, - }, - expectedResult: probe.Failure, - expectedReadiness: false, - }, - { - testContainer: api.Container{ - LivenessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - ReadinessProbe: &api.Probe{ - InitialDelaySeconds: -100, - Handler: api.Handler{ - Exec: &api.ExecAction{}, - }, - }, - }, - expectedResult: probe.Success, - expectedReadiness: true, - }, - } - - for i, test := range tests { - if test.expectError { - replaceProber(manager, test.expectedResult, errors.New("error")) - } else { - replaceProber(manager, test.expectedResult, nil) - } - result, err := manager.prober.Probe(&api.Pod{}, api.PodStatus{}, test.testContainer, dc.ID, dc.Created) - if test.expectError && err == nil { - t.Errorf("[%d] Expected error but no error was returned.", i) - } - if !test.expectError && err != nil { - t.Errorf("[%d] Didn't expect error but got: %v", i, err) - } - if test.expectedResult != result { - t.Errorf("[%d] Expected result to be %v but was %v", i, test.expectedResult, result) - } - if test.expectedReadiness != manager.readinessManager.GetReadiness(dc.ID) { - t.Errorf("[%d] Expected readiness to be %v but was %v", i, test.expectedReadiness, manager.readinessManager.GetReadiness(dc.ID)) - } - } } func TestIsAExitError(t *testing.T) { @@ -828,7 +520,7 @@ func TestIsAExitError(t *testing.T) { func generatePodInfraContainerHash(pod *api.Pod) uint64 { var ports []api.ContainerPort - if !pod.Spec.HostNetwork { + if pod.Spec.SecurityContext == nil || !pod.Spec.SecurityContext.HostNetwork { for _, container := range pod.Spec.Containers { ports = append(ports, container.Ports...) } @@ -889,7 +581,6 @@ func TestSyncPodCreateNetAndContainer(t *testing.T) { // Create container. "create", "start", "inspect_container", }) - fakeDocker.Lock() found := false @@ -1288,60 +979,48 @@ func TestSyncPodWithPullPolicy(t *testing.T) { Spec: api.PodSpec{ Containers: []api.Container{ {Name: "bar", Image: "pull_always_image", ImagePullPolicy: api.PullAlways}, - {Name: "bar1", Image: "pull_never_image", ImagePullPolicy: api.PullNever}, {Name: "bar2", Image: "pull_if_not_present_image", ImagePullPolicy: api.PullIfNotPresent}, {Name: "bar3", Image: "existing_one", ImagePullPolicy: api.PullIfNotPresent}, {Name: "bar4", Image: "want:latest", ImagePullPolicy: api.PullIfNotPresent}, + {Name: "bar5", Image: "pull_never_image", ImagePullPolicy: api.PullNever}, }, }, } - runSyncPod(t, dm, fakeDocker, pod, nil) - - fakeDocker.Lock() - - eventSet := []string{ - `Pulling Pulling image "pod_infra_image"`, - `Pulled Successfully pulled image "pod_infra_image"`, - `Pulling Pulling image "pull_always_image"`, - `Pulled Successfully pulled image "pull_always_image"`, - `Pulling Pulling image "pull_if_not_present_image"`, - `Pulled Successfully pulled image "pull_if_not_present_image"`, - `Pulled Container image "existing_one" already present on machine`, - `Pulled Container image "want:latest" already present on machine`, + expectedStatusMap := map[string]api.ContainerState{ + "bar": {Running: &api.ContainerStateRunning{unversioned.Now()}}, + "bar2": {Running: &api.ContainerStateRunning{unversioned.Now()}}, + "bar3": {Running: &api.ContainerStateRunning{unversioned.Now()}}, + "bar4": {Running: &api.ContainerStateRunning{unversioned.Now()}}, + "bar5": {Waiting: &api.ContainerStateWaiting{Reason: kubecontainer.ErrImageNeverPull.Error(), + Message: "Container image \"pull_never_image\" is not present with pull policy of Never"}}, } - recorder := dm.recorder.(*record.FakeRecorder) - - var actualEvents []string - for _, ev := range recorder.Events { - if strings.HasPrefix(ev, "Pull") { - actualEvents = append(actualEvents, ev) - } + runSyncPod(t, dm, fakeDocker, pod, nil) + statuses, err := dm.GetPodStatus(pod) + if err != nil { + t.Errorf("unable to get pod status") } - sort.StringSlice(actualEvents).Sort() - sort.StringSlice(eventSet).Sort() - if !reflect.DeepEqual(actualEvents, eventSet) { - t.Errorf("Expected: %#v, Actual: %#v", eventSet, actualEvents) + for _, c := range pod.Spec.Containers { + if containerStatus, ok := api.GetContainerStatus(statuses.ContainerStatuses, c.Name); ok { + // copy the StartedAt time, to make the structs match + if containerStatus.State.Running != nil && expectedStatusMap[c.Name].Running != nil { + expectedStatusMap[c.Name].Running.StartedAt = containerStatus.State.Running.StartedAt + } + assert.Equal(t, containerStatus.State, expectedStatusMap[c.Name], "for container %s", c.Name) + } } - pulledImageSet := make(map[string]empty) - for v := range puller.ImagesPulled { - pulledImageSet[puller.ImagesPulled[v]] = empty{} - } + fakeDocker.Lock() + defer fakeDocker.Unlock() - if !reflect.DeepEqual(pulledImageSet, map[string]empty{ - "pod_infra_image": {}, - "pull_always_image": {}, - "pull_if_not_present_image": {}, - }) { - t.Errorf("Unexpected pulled containers: %v", puller.ImagesPulled) - } + pulledImageSorted := puller.ImagesPulled[:] + sort.Strings(pulledImageSorted) + assert.Equal(t, []string{"pod_infra_image", "pull_always_image", "pull_if_not_present_image"}, pulledImageSorted) - if len(fakeDocker.Created) != 6 { + if len(fakeDocker.Created) != 5 { t.Errorf("Unexpected containers created %v", fakeDocker.Created) } - fakeDocker.Unlock() } func TestSyncPodWithRestartPolicy(t *testing.T) { @@ -1728,7 +1407,7 @@ func TestGetPodCreationFailureReason(t *testing.T) { dm, fakeDocker := newTestDockerManager() // Inject the creation failure error to docker. - failureReason := "creation failure" + failureReason := "RunContainerError" fakeDocker.Errors = map[string]error{ "create": fmt.Errorf("%s", failureReason), } @@ -1786,7 +1465,7 @@ func TestGetPodPullImageFailureReason(t *testing.T) { puller := dm.dockerPuller.(*FakeDockerPuller) puller.HasImages = []string{} // Inject the pull image failure error. - failureReason := "pull image faiulre" + failureReason := kubecontainer.ErrImagePull.Error() puller.ErrorsToInject = []error{fmt.Errorf("%s", failureReason)} pod := &api.Pod{ @@ -2047,6 +1726,12 @@ func TestSyncPodEventHandlerFails(t *testing.T) { } } +type fakeReadWriteCloser struct{} + +func (*fakeReadWriteCloser) Read([]byte) (int, error) { return 0, nil } +func (*fakeReadWriteCloser) Write([]byte) (int, error) { return 0, nil } +func (*fakeReadWriteCloser) Close() error { return nil } + func TestPortForwardNoSuchContainer(t *testing.T) { dm, _ := newTestDockerManager() @@ -2059,7 +1744,8 @@ func TestPortForwardNoSuchContainer(t *testing.T) { Containers: nil, }, 5000, - nil, + // need a valid io.ReadWriteCloser here + &fakeReadWriteCloser{}, ) if err == nil { t.Fatal("unexpected non-error") @@ -2124,7 +1810,9 @@ func TestSyncPodWithHostNetwork(t *testing.T) { Containers: []api.Container{ {Name: "bar"}, }, - HostNetwork: true, + SecurityContext: &api.PodSecurityContext{ + HostNetwork: true, + }, }, } @@ -2346,7 +2034,8 @@ func TestGetPidMode(t *testing.T) { } // test true - pod.Spec.HostPID = true + pod.Spec.SecurityContext = &api.PodSecurityContext{} + pod.Spec.SecurityContext.HostPID = true pidMode = getPidMode(pod) if pidMode != "host" { t.Errorf("expected host pid mode for pod but got %v", pidMode) @@ -2363,9 +2052,68 @@ func TestGetIPCMode(t *testing.T) { } // test true - pod.Spec.HostIPC = true + pod.Spec.SecurityContext = &api.PodSecurityContext{} + pod.Spec.SecurityContext.HostIPC = true ipcMode = getIPCMode(pod) if ipcMode != "host" { t.Errorf("expected host ipc mode for pod but got %v", ipcMode) } } + +func TestPodDependsOnPodIP(t *testing.T) { + tests := []struct { + name string + expected bool + env api.EnvVar + }{ + { + name: "depends on pod IP", + expected: true, + env: api.EnvVar{ + Name: "POD_IP", + ValueFrom: &api.EnvVarSource{ + FieldRef: &api.ObjectFieldSelector{ + APIVersion: testapi.Default.Version(), + FieldPath: "status.podIP", + }, + }, + }, + }, + { + name: "literal value", + expected: false, + env: api.EnvVar{ + Name: "SOME_VAR", + Value: "foo", + }, + }, + { + name: "other downward api field", + expected: false, + env: api.EnvVar{ + Name: "POD_NAME", + ValueFrom: &api.EnvVarSource{ + FieldRef: &api.ObjectFieldSelector{ + APIVersion: testapi.Default.Version(), + FieldPath: "metadata.name", + }, + }, + }, + }, + } + + for _, tc := range tests { + pod := &api.Pod{ + Spec: api.PodSpec{ + Containers: []api.Container{ + {Env: []api.EnvVar{tc.env}}, + }, + }, + } + + result := podDependsOnPodIP(pod) + if e, a := tc.expected, result; e != a { + t.Errorf("%v: Unexpected result; expected %v, got %v", tc.name, e, a) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/fake_pod_workers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/fake_pod_workers.go index 7f036e60fd07..405eb21d22cd 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/fake_pod_workers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/fake_pod_workers.go @@ -19,6 +19,7 @@ package kubelet import ( "k8s.io/kubernetes/pkg/api" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/types" ) @@ -30,12 +31,12 @@ type fakePodWorkers struct { t TestingInterface } -func (f *fakePodWorkers) UpdatePod(pod *api.Pod, mirrorPod *api.Pod, updateComplete func()) { +func (f *fakePodWorkers) UpdatePod(pod *api.Pod, mirrorPod *api.Pod, updateType kubetypes.SyncPodType, updateComplete func()) { pods, err := f.runtimeCache.GetPods() if err != nil { f.t.Errorf("Unexpected error: %v", err) } - if err := f.syncPodFn(pod, mirrorPod, kubecontainer.Pods(pods).FindPodByID(pod.UID), SyncPodUpdate); err != nil { + if err := f.syncPodFn(pod, mirrorPod, kubecontainer.Pods(pods).FindPodByID(pod.UID), kubetypes.SyncPodUpdate); err != nil { f.t.Errorf("Unexpected error: %v", err) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/image_manager.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/image_manager.go index a198644f3479..1f40e2868814 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/image_manager.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/image_manager.go @@ -22,12 +22,11 @@ import ( "sync" "time" - docker "github.com/fsouza/go-dockerclient" "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/client/record" "k8s.io/kubernetes/pkg/kubelet/cadvisor" - "k8s.io/kubernetes/pkg/kubelet/dockertools" + "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" ) @@ -59,8 +58,8 @@ type ImageGCPolicy struct { } type realImageManager struct { - // Connection to the Docker daemon. - dockerClient dockertools.DockerInterface + // Container runtime + runtime container.Runtime // Records of images and their use. imageRecords map[string]*imageRecord @@ -91,7 +90,7 @@ type imageRecord struct { size int64 } -func newImageManager(dockerClient dockertools.DockerInterface, cadvisorInterface cadvisor.Interface, recorder record.EventRecorder, nodeRef *api.ObjectReference, policy ImageGCPolicy) (imageManager, error) { +func newImageManager(runtime container.Runtime, cadvisorInterface cadvisor.Interface, recorder record.EventRecorder, nodeRef *api.ObjectReference, policy ImageGCPolicy) (imageManager, error) { // Validate policy. if policy.HighThresholdPercent < 0 || policy.HighThresholdPercent > 100 { return nil, fmt.Errorf("invalid HighThresholdPercent %d, must be in range [0-100]", policy.HighThresholdPercent) @@ -100,7 +99,7 @@ func newImageManager(dockerClient dockertools.DockerInterface, cadvisorInterface return nil, fmt.Errorf("invalid LowThresholdPercent %d, must be in range [0-100]", policy.LowThresholdPercent) } im := &realImageManager{ - dockerClient: dockerClient, + runtime: runtime, policy: policy, imageRecords: make(map[string]*imageRecord), cadvisor: cadvisorInterface, @@ -130,21 +129,21 @@ func (im *realImageManager) Start() error { } func (im *realImageManager) detectImages(detected time.Time) error { - images, err := im.dockerClient.ListImages(docker.ListImagesOptions{}) + images, err := im.runtime.ListImages() if err != nil { return err } - containers, err := im.dockerClient.ListContainers(docker.ListContainersOptions{ - All: true, - }) + pods, err := im.runtime.GetPods(true) if err != nil { return err } // Make a set of images in use by containers. imagesInUse := sets.NewString() - for _, container := range containers { - imagesInUse.Insert(container.Image) + for _, pod := range pods { + for _, container := range pod.Containers { + imagesInUse.Insert(container.Image) + } } // Add new images and record those being used. @@ -163,11 +162,11 @@ func (im *realImageManager) detectImages(detected time.Time) error { } // Set last used time to now if the image is being used. - if isImageUsed(&image, imagesInUse) { + if isImageUsed(image, imagesInUse) { im.imageRecords[image.ID].lastUsed = now } - im.imageRecords[image.ID].size = image.VirtualSize + im.imageRecords[image.ID].size = image.Size } // Remove old images from our records. @@ -253,7 +252,7 @@ func (im *realImageManager) freeSpace(bytesToFree int64) (int64, error) { // Remove image. Continue despite errors. glog.Infof("[ImageManager]: Removing image %q to free %d bytes", image.id, image.size) - err := im.dockerClient.RemoveImage(image.id) + err := im.runtime.RemoveImage(container.ImageSpec{Image: image.id}) if err != nil { lastErr = err continue @@ -287,12 +286,12 @@ func (ev byLastUsedAndDetected) Less(i, j int) bool { } } -func isImageUsed(image *docker.APIImages, imagesInUse sets.String) bool { +func isImageUsed(image container.Image, imagesInUse sets.String) bool { // Check the image ID and all the RepoTags. if _, ok := imagesInUse[image.ID]; ok { return true } - for _, tag := range image.RepoTags { + for _, tag := range image.Tags { if _, ok := imagesInUse[tag]; ok { return true } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/image_manager_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/image_manager_test.go index 2cff1944c702..f843edb31fca 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/image_manager_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/image_manager_test.go @@ -21,30 +21,26 @@ import ( "testing" "time" - docker "github.com/fsouza/go-dockerclient" cadvisorApiV2 "github.com/google/cadvisor/info/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "k8s.io/kubernetes/pkg/client/record" "k8s.io/kubernetes/pkg/kubelet/cadvisor" - "k8s.io/kubernetes/pkg/kubelet/dockertools" - "k8s.io/kubernetes/pkg/util/sets" + "k8s.io/kubernetes/pkg/kubelet/container" ) var zero time.Time -func newRealImageManager(policy ImageGCPolicy) (*realImageManager, *dockertools.FakeDockerClient, *cadvisor.Mock) { - fakeDocker := &dockertools.FakeDockerClient{ - RemovedImages: sets.NewString(), - } +func newRealImageManager(policy ImageGCPolicy) (*realImageManager, *container.FakeRuntime, *cadvisor.Mock) { + fakeRuntime := &container.FakeRuntime{} mockCadvisor := new(cadvisor.Mock) return &realImageManager{ - dockerClient: fakeDocker, + runtime: fakeRuntime, policy: policy, imageRecords: make(map[string]*imageRecord), cadvisor: mockCadvisor, recorder: &record.FakeRecorder{}, - }, fakeDocker, mockCadvisor + }, fakeRuntime, mockCadvisor } // Accessors used for thread-safe testing. @@ -67,29 +63,33 @@ func imageName(id int) string { } // Make an image with the specified ID. -func makeImage(id int, size int64) docker.APIImages { - return docker.APIImages{ - ID: imageName(id), - VirtualSize: size, +func makeImage(id int, size int64) container.Image { + return container.Image{ + ID: imageName(id), + Size: size, } } // Make a container with the specified ID. It will use the image with the same ID. -func makeContainer(id int) docker.APIContainers { - return docker.APIContainers{ - ID: fmt.Sprintf("container-%d", id), +func makeContainer(id int) *container.Container { + return &container.Container{ + ID: container.ContainerID{"test", fmt.Sprintf("container-%d", id)}, Image: imageName(id), } } func TestDetectImagesInitialDetect(t *testing.T) { - manager, fakeDocker, _ := newRealImageManager(ImageGCPolicy{}) - fakeDocker.Images = []docker.APIImages{ + manager, fakeRuntime, _ := newRealImageManager(ImageGCPolicy{}) + fakeRuntime.ImageList = []container.Image{ makeImage(0, 1024), makeImage(1, 2048), } - fakeDocker.ContainerList = []docker.APIContainers{ - makeContainer(1), + fakeRuntime.PodList = []*container.Pod{ + { + Containers: []*container.Container{ + makeContainer(1), + }, + }, } startTime := time.Now().Add(-time.Millisecond) @@ -109,13 +109,17 @@ func TestDetectImagesInitialDetect(t *testing.T) { func TestDetectImagesWithNewImage(t *testing.T) { // Just one image initially. - manager, fakeDocker, _ := newRealImageManager(ImageGCPolicy{}) - fakeDocker.Images = []docker.APIImages{ + manager, fakeRuntime, _ := newRealImageManager(ImageGCPolicy{}) + fakeRuntime.ImageList = []container.Image{ makeImage(0, 1024), makeImage(1, 2048), } - fakeDocker.ContainerList = []docker.APIContainers{ - makeContainer(1), + fakeRuntime.PodList = []*container.Pod{ + { + Containers: []*container.Container{ + makeContainer(1), + }, + }, } err := manager.detectImages(zero) @@ -124,7 +128,7 @@ func TestDetectImagesWithNewImage(t *testing.T) { assert.Equal(manager.imageRecordsLen(), 2) // Add a new image. - fakeDocker.Images = []docker.APIImages{ + fakeRuntime.ImageList = []container.Image{ makeImage(0, 1024), makeImage(1, 1024), makeImage(2, 1024), @@ -150,13 +154,17 @@ func TestDetectImagesWithNewImage(t *testing.T) { } func TestDetectImagesContainerStopped(t *testing.T) { - manager, fakeDocker, _ := newRealImageManager(ImageGCPolicy{}) - fakeDocker.Images = []docker.APIImages{ + manager, fakeRuntime, _ := newRealImageManager(ImageGCPolicy{}) + fakeRuntime.ImageList = []container.Image{ makeImage(0, 1024), makeImage(1, 2048), } - fakeDocker.ContainerList = []docker.APIContainers{ - makeContainer(1), + fakeRuntime.PodList = []*container.Pod{ + { + Containers: []*container.Container{ + makeContainer(1), + }, + }, } err := manager.detectImages(zero) @@ -167,7 +175,7 @@ func TestDetectImagesContainerStopped(t *testing.T) { require.True(t, ok) // Simulate container being stopped. - fakeDocker.ContainerList = []docker.APIContainers{} + fakeRuntime.PodList = []*container.Pod{} err = manager.detectImages(time.Now()) require.NoError(t, err) assert.Equal(manager.imageRecordsLen(), 2) @@ -182,13 +190,17 @@ func TestDetectImagesContainerStopped(t *testing.T) { } func TestDetectImagesWithRemovedImages(t *testing.T) { - manager, fakeDocker, _ := newRealImageManager(ImageGCPolicy{}) - fakeDocker.Images = []docker.APIImages{ + manager, fakeRuntime, _ := newRealImageManager(ImageGCPolicy{}) + fakeRuntime.ImageList = []container.Image{ makeImage(0, 1024), makeImage(1, 2048), } - fakeDocker.ContainerList = []docker.APIContainers{ - makeContainer(1), + fakeRuntime.PodList = []*container.Pod{ + { + Containers: []*container.Container{ + makeContainer(1), + }, + }, } err := manager.detectImages(zero) @@ -197,48 +209,63 @@ func TestDetectImagesWithRemovedImages(t *testing.T) { assert.Equal(manager.imageRecordsLen(), 2) // Simulate both images being removed. - fakeDocker.Images = []docker.APIImages{} + fakeRuntime.ImageList = []container.Image{} err = manager.detectImages(time.Now()) require.NoError(t, err) assert.Equal(manager.imageRecordsLen(), 0) } func TestFreeSpaceImagesInUseContainersAreIgnored(t *testing.T) { - manager, fakeDocker, _ := newRealImageManager(ImageGCPolicy{}) - fakeDocker.Images = []docker.APIImages{ + manager, fakeRuntime, _ := newRealImageManager(ImageGCPolicy{}) + fakeRuntime.ImageList = []container.Image{ makeImage(0, 1024), makeImage(1, 2048), } - fakeDocker.ContainerList = []docker.APIContainers{ - makeContainer(1), + fakeRuntime.PodList = []*container.Pod{ + { + Containers: []*container.Container{ + makeContainer(1), + }, + }, } spaceFreed, err := manager.freeSpace(2048) assert := assert.New(t) require.NoError(t, err) assert.EqualValues(1024, spaceFreed) - assert.Len(fakeDocker.RemovedImages, 1) - assert.True(fakeDocker.RemovedImages.Has(imageName(0))) + assert.Len(fakeRuntime.ImageList, 1) } func TestFreeSpaceRemoveByLeastRecentlyUsed(t *testing.T) { - manager, fakeDocker, _ := newRealImageManager(ImageGCPolicy{}) - fakeDocker.Images = []docker.APIImages{ + manager, fakeRuntime, _ := newRealImageManager(ImageGCPolicy{}) + fakeRuntime.ImageList = []container.Image{ makeImage(0, 1024), makeImage(1, 2048), } - fakeDocker.ContainerList = []docker.APIContainers{ - makeContainer(0), - makeContainer(1), + fakeRuntime.PodList = []*container.Pod{ + { + Containers: []*container.Container{ + makeContainer(0), + makeContainer(1), + }, + }, } // Make 1 be more recently used than 0. require.NoError(t, manager.detectImages(zero)) - fakeDocker.ContainerList = []docker.APIContainers{ - makeContainer(1), + fakeRuntime.PodList = []*container.Pod{ + { + Containers: []*container.Container{ + makeContainer(1), + }, + }, } require.NoError(t, manager.detectImages(time.Now())) - fakeDocker.ContainerList = []docker.APIContainers{} + fakeRuntime.PodList = []*container.Pod{ + { + Containers: []*container.Container{}, + }, + } require.NoError(t, manager.detectImages(time.Now())) require.Equal(t, manager.imageRecordsLen(), 2) @@ -246,56 +273,58 @@ func TestFreeSpaceRemoveByLeastRecentlyUsed(t *testing.T) { assert := assert.New(t) require.NoError(t, err) assert.EqualValues(1024, spaceFreed) - assert.Len(fakeDocker.RemovedImages, 1) - assert.True(fakeDocker.RemovedImages.Has(imageName(0))) + assert.Len(fakeRuntime.ImageList, 1) } func TestFreeSpaceTiesBrokenByDetectedTime(t *testing.T) { - manager, fakeDocker, _ := newRealImageManager(ImageGCPolicy{}) - fakeDocker.Images = []docker.APIImages{ + manager, fakeRuntime, _ := newRealImageManager(ImageGCPolicy{}) + fakeRuntime.ImageList = []container.Image{ makeImage(0, 1024), } - fakeDocker.ContainerList = []docker.APIContainers{ - makeContainer(0), + fakeRuntime.PodList = []*container.Pod{ + { + Containers: []*container.Container{ + makeContainer(0), + }, + }, } // Make 1 more recently detected but used at the same time as 0. require.NoError(t, manager.detectImages(zero)) - fakeDocker.Images = []docker.APIImages{ + fakeRuntime.ImageList = []container.Image{ makeImage(0, 1024), makeImage(1, 2048), } - fakeDocker.ContainerList = []docker.APIContainers{ - makeContainer(0), - makeContainer(1), - } require.NoError(t, manager.detectImages(time.Now())) - fakeDocker.ContainerList = []docker.APIContainers{} + fakeRuntime.PodList = []*container.Pod{} require.NoError(t, manager.detectImages(time.Now())) require.Equal(t, manager.imageRecordsLen(), 2) spaceFreed, err := manager.freeSpace(1024) assert := assert.New(t) require.NoError(t, err) - assert.EqualValues(1024, spaceFreed) - assert.Len(fakeDocker.RemovedImages, 1) - assert.True(fakeDocker.RemovedImages.Has(imageName(0))) + assert.EqualValues(2048, spaceFreed) + assert.Len(fakeRuntime.ImageList, 1) } func TestFreeSpaceImagesAlsoDoesLookupByRepoTags(t *testing.T) { - manager, fakeDocker, _ := newRealImageManager(ImageGCPolicy{}) - fakeDocker.Images = []docker.APIImages{ + manager, fakeRuntime, _ := newRealImageManager(ImageGCPolicy{}) + fakeRuntime.ImageList = []container.Image{ makeImage(0, 1024), { - ID: "5678", - RepoTags: []string{"potato", "salad"}, - VirtualSize: 2048, + ID: "5678", + Tags: []string{"potato", "salad"}, + Size: 2048, }, } - fakeDocker.ContainerList = []docker.APIContainers{ + fakeRuntime.PodList = []*container.Pod{ { - ID: "c5678", - Image: "salad", + Containers: []*container.Container{ + { + ID: container.ContainerID{"test", "c5678"}, + Image: "salad", + }, + }, }, } @@ -303,8 +332,7 @@ func TestFreeSpaceImagesAlsoDoesLookupByRepoTags(t *testing.T) { assert := assert.New(t) require.NoError(t, err) assert.EqualValues(1024, spaceFreed) - assert.Len(fakeDocker.RemovedImages, 1) - assert.True(fakeDocker.RemovedImages.Has(imageName(0))) + assert.Len(fakeRuntime.ImageList, 1) } func TestGarbageCollectBelowLowThreshold(t *testing.T) { @@ -339,14 +367,14 @@ func TestGarbageCollectBelowSuccess(t *testing.T) { HighThresholdPercent: 90, LowThresholdPercent: 80, } - manager, fakeDocker, mockCadvisor := newRealImageManager(policy) + manager, fakeRuntime, mockCadvisor := newRealImageManager(policy) // Expect 95% usage and most of it gets freed. mockCadvisor.On("DockerImagesFsInfo").Return(cadvisorApiV2.FsInfo{ Usage: 950, Capacity: 1000, }, nil) - fakeDocker.Images = []docker.APIImages{ + fakeRuntime.ImageList = []container.Image{ makeImage(0, 450), } @@ -358,14 +386,14 @@ func TestGarbageCollectNotEnoughFreed(t *testing.T) { HighThresholdPercent: 90, LowThresholdPercent: 80, } - manager, fakeDocker, mockCadvisor := newRealImageManager(policy) + manager, fakeRuntime, mockCadvisor := newRealImageManager(policy) // Expect 95% usage and little of it gets freed. mockCadvisor.On("DockerImagesFsInfo").Return(cadvisorApiV2.FsInfo{ Usage: 950, Capacity: 1000, }, nil) - fakeDocker.Images = []docker.APIImages{ + fakeRuntime.ImageList = []container.Image{ makeImage(0, 50), } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/kubelet.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/kubelet.go index 284582166ae0..e0a186ced962 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/kubelet.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/kubelet.go @@ -38,6 +38,7 @@ import ( "k8s.io/kubernetes/pkg/api" apierrors "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/client/record" @@ -51,15 +52,20 @@ import ( "k8s.io/kubernetes/pkg/kubelet/envvars" "k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/kubernetes/pkg/kubelet/network" + kubepod "k8s.io/kubernetes/pkg/kubelet/pod" + "k8s.io/kubernetes/pkg/kubelet/prober" "k8s.io/kubernetes/pkg/kubelet/rkt" - kubeletTypes "k8s.io/kubernetes/pkg/kubelet/types" - kubeletUtil "k8s.io/kubernetes/pkg/kubelet/util" + "k8s.io/kubernetes/pkg/kubelet/status" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" + kubeletutil "k8s.io/kubernetes/pkg/kubelet/util" "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/probe" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/bandwidth" utilErrors "k8s.io/kubernetes/pkg/util/errors" + kubeio "k8s.io/kubernetes/pkg/util/io" "k8s.io/kubernetes/pkg/util/mount" nodeutil "k8s.io/kubernetes/pkg/util/node" "k8s.io/kubernetes/pkg/util/oom" @@ -113,7 +119,7 @@ type SyncHandler interface { HandlePodCleanups() error } -type SourcesReadyFn func() bool +type SourcesReadyFn func(sourcesSeen sets.String) bool // Wait for the container runtime to be up with a timeout. func waitUntilRuntimeIsUp(cr kubecontainer.Runtime, timeout time.Duration) error { @@ -142,9 +148,10 @@ func NewMainKubelet( pullBurst int, eventQPS float32, eventBurst int, - containerGCPolicy ContainerGCPolicy, + containerGCPolicy kubecontainer.ContainerGCPolicy, sourcesReady SourcesReadyFn, registerNode bool, + registerSchedulable bool, standaloneMode bool, clusterDomain string, clusterDNS net.IP, @@ -166,14 +173,18 @@ func NewMainKubelet( rktPath string, rktStage1Image string, mounter mount.Interface, + writer kubeio.Writer, dockerDaemonContainer string, systemContainer string, configureCBR0 bool, podCIDR string, + reconcileCIDR bool, pods int, dockerExecHandler dockertools.ExecHandler, resolverConfig string, - cpuCFSQuota bool) (*Kubelet, error) { + cpuCFSQuota bool, + daemonEndpoints *api.NodeDaemonEndpoints, + oomAdjuster *oom.OOMAdjuster) (*Kubelet, error) { if rootDirectory == "" { return nil, fmt.Errorf("invalid root directory %q", rootDirectory) } @@ -191,7 +202,7 @@ func NewMainKubelet( // than an interface. There is no way to construct a list+watcher using resource name. listWatch := &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { - return kubeClient.Services(api.NamespaceAll).List(labels.Everything()) + return kubeClient.Services(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return kubeClient.Services(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion) @@ -208,11 +219,7 @@ func NewMainKubelet( fieldSelector := fields.Set{client.ObjectNameField: nodeName}.AsSelector() listWatch := &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { - obj, err := kubeClient.Nodes().Get(nodeName) - if err != nil { - return nil, err - } - return &api.NodeList{Items: []api.Node{*obj}}, nil + return kubeClient.Nodes().List(labels.Everything(), fieldSelector) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return kubeClient.Nodes().Watch(labels.Everything(), fieldSelector, resourceVersion) @@ -232,20 +239,11 @@ func NewMainKubelet( Namespace: "", } - containerGC, err := newContainerGC(dockerClient, containerGCPolicy) - if err != nil { - return nil, err - } - imageManager, err := newImageManager(dockerClient, cadvisorInterface, recorder, nodeRef, imageGCPolicy) - if err != nil { - return nil, fmt.Errorf("failed to initialize image manager: %v", err) - } diskSpaceManager, err := newDiskSpaceManager(cadvisorInterface, diskSpacePolicy) if err != nil { return nil, fmt.Errorf("failed to initialize disk manager: %v", err) } - statusManager := newStatusManager(kubeClient) - readinessManager := kubecontainer.NewReadinessManager() + statusManager := status.NewManager(kubeClient) containerRefManager := kubecontainer.NewRefManager() volumeManager := newVolumeManager() @@ -260,10 +258,10 @@ func NewMainKubelet( rootDirectory: rootDirectory, resyncInterval: resyncInterval, containerRefManager: containerRefManager, - readinessManager: readinessManager, httpClient: &http.Client{}, sourcesReady: sourcesReady, registerNode: registerNode, + registerSchedulable: registerSchedulable, standaloneMode: standaloneMode, clusterDomain: clusterDomain, clusterDNS: clusterDNS, @@ -276,8 +274,6 @@ func NewMainKubelet( streamingConnectionIdleTimeout: streamingConnectionIdleTimeout, recorder: recorder, cadvisor: cadvisorInterface, - containerGC: containerGC, - imageManager: imageManager, diskSpaceManager: diskSpaceManager, statusManager: statusManager, volumeManager: volumeManager, @@ -289,12 +285,15 @@ func NewMainKubelet( oomWatcher: oomWatcher, cgroupRoot: cgroupRoot, mounter: mounter, + writer: writer, configureCBR0: configureCBR0, podCIDR: podCIDR, + reconcileCIDR: reconcileCIDR, pods: pods, syncLoopMonitor: util.AtomicValue{}, resolverConfig: resolverConfig, cpuCFSQuota: cpuCFSQuota, + daemonEndpoints: daemonEndpoints, } if plug, err := network.InitNetworkPlugin(networkPlugins, networkPluginName, &networkHost{klet}); err != nil { @@ -308,9 +307,8 @@ func NewMainKubelet( return nil, err } - oomAdjuster := oom.NewOomAdjuster() procFs := procfs.NewProcFs() - + imageBackOff := util.NewBackOff(resyncInterval, maxContainerBackOff) // Initialize the runtime. switch containerRuntime { case "docker": @@ -318,7 +316,7 @@ func NewMainKubelet( klet.containerRuntime = dockertools.NewDockerManager( dockerClient, recorder, - readinessManager, + klet, // prober containerRefManager, machineInfo, podInfraContainerImage, @@ -332,7 +330,9 @@ func NewMainKubelet( dockerExecHandler, oomAdjuster, procFs, - klet.cpuCFSQuota) + klet.cpuCFSQuota, + imageBackOff) + case "rkt": conf := &rkt.Config{ Path: rktPath, @@ -344,12 +344,14 @@ func NewMainKubelet( klet, recorder, containerRefManager, - readinessManager, - klet.volumeManager) + klet, // prober + klet.volumeManager, + imageBackOff) if err != nil { return nil, err } klet.containerRuntime = rktRuntime + klet.imageManager = rkt.NewImageManager(rktRuntime) // No Docker daemon to put in a container. dockerDaemonContainer = "" @@ -357,9 +359,23 @@ func NewMainKubelet( return nil, fmt.Errorf("unsupported container runtime %q specified", containerRuntime) } + // setup containerGC + containerGC, err := kubecontainer.NewContainerGC(klet.containerRuntime, containerGCPolicy) + if err != nil { + return nil, err + } + klet.containerGC = containerGC + + // setup imageManager + imageManager, err := newImageManager(klet.containerRuntime, cadvisorInterface, recorder, nodeRef, imageGCPolicy) + if err != nil { + return nil, fmt.Errorf("failed to initialize image manager: %v", err) + } + klet.imageManager = imageManager + // Setup container manager, can fail if the devices hierarchy is not mounted // (it is required by Docker however). - containerManager, err := newContainerManager(cadvisorInterface, dockerDaemonContainer, systemContainer, resourceContainer) + containerManager, err := newContainerManager(mounter, cadvisorInterface, dockerDaemonContainer, systemContainer, resourceContainer) if err != nil { return nil, fmt.Errorf("failed to create the Container Manager: %v", err) } @@ -378,7 +394,13 @@ func NewMainKubelet( klet.lastTimestampRuntimeUp = time.Now() klet.runner = klet.containerRuntime - klet.podManager = newBasicPodManager(klet.kubeClient) + klet.podManager = kubepod.NewBasicPodManager(kubepod.NewBasicMirrorClient(klet.kubeClient)) + + klet.prober = prober.New(klet.runner, containerRefManager, recorder) + klet.probeManager = prober.NewManager( + klet.resyncInterval, + klet.statusManager, + klet.prober) runtimeCache, err := kubecontainer.NewRuntimeCache(klet.containerRuntime) if err != nil { @@ -406,6 +428,7 @@ func NewMainKubelet( klet.backOff = util.NewBackOff(resyncInterval, maxContainerBackOff) klet.podKillingCh = make(chan *kubecontainer.Pod, podKillingChannelCapacity) + klet.sourcesSeen = sets.NewString() return klet, nil } @@ -429,8 +452,11 @@ type Kubelet struct { podWorkers PodWorkers resyncInterval time.Duration sourcesReady SourcesReadyFn + // sourcesSeen records the sources seen by kubelet. This set is not thread + // safe and should only be access by the main kubelet syncloop goroutine. + sourcesSeen sets.String - podManager podManager + podManager kubepod.Manager // Needed to report events for containers belonging to deleted/modified pods. // Tracks references for reporting events @@ -441,13 +467,15 @@ type Kubelet struct { // Optional, defaults to simple Docker implementation runner kubecontainer.ContainerCommandRunner // Optional, client for http requests, defaults to empty client - httpClient kubeletTypes.HttpGetter + httpClient kubetypes.HttpGetter // cAdvisor used for container information. cadvisor cadvisor.Interface // Set to true to have the node register itself with the apiserver. registerNode bool + // Set to true to have the node register itself as schedulable. + registerSchedulable bool // for internal book keeping; access only from within registerWithApiserver registrationCompleted bool @@ -480,8 +508,10 @@ type Kubelet struct { // Network plugin. networkPlugin network.NetworkPlugin - // Container readiness state manager. - readinessManager *kubecontainer.ReadinessManager + // Handles container readiness probing + probeManager prober.Manager + // TODO: Move prober ownership to the probeManager once the runtime no longer depends on it. + prober prober.Prober // How long to keep idle streaming command execution/port forwarding // connections open before terminating them @@ -491,7 +521,7 @@ type Kubelet struct { recorder record.EventRecorder // Policy for handling garbage collection of dead containers. - containerGC containerGC + containerGC kubecontainer.ContainerGC // Manager for images. imageManager imageManager @@ -503,7 +533,7 @@ type Kubelet struct { machineInfo *cadvisorApi.MachineInfo // Syncs pods statuses with apiserver; also used as a cache of statuses. - statusManager *statusManager + statusManager status.Manager // Manager for the volume maps for the pods. volumeManager *volumeManager @@ -545,6 +575,9 @@ type Kubelet struct { // Mounter to use for volumes. mounter mount.Interface + // Writer interface to use for volumes. + writer kubeio.Writer + // Manager of non-Runtime containers. containerManager containerManager @@ -552,6 +585,7 @@ type Kubelet struct { // the correct state. configureCBR0 bool podCIDR string + reconcileCIDR bool // Number of Pods which can be run by this Kubelet pods int @@ -575,6 +609,18 @@ type Kubelet struct { // True if container cpu limits should be enforced via cgroup CFS quota cpuCFSQuota bool + + // Information about the ports which are opened by daemons on Node running this Kubelet server. + daemonEndpoints *api.NodeDaemonEndpoints +} + +func (kl *Kubelet) allSourcesReady() bool { + // Make a copy of the sourcesSeen list because it's not thread-safe. + return kl.sourcesReady(sets.NewString(kl.sourcesSeen.List()...)) +} + +func (kl *Kubelet) addSource(source string) { + kl.sourcesSeen.Insert(source) } // getRootDir returns the full path to the directory under which kubelet can @@ -739,7 +785,7 @@ func (kl *Kubelet) StartGarbageCollection() { } // Run starts the kubelet reacting to config updates -func (kl *Kubelet) Run(updates <-chan PodUpdate) { +func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) { if kl.logServer == nil { kl.logServer = http.StripPrefix("/logs/", http.FileServer(http.Dir("/var/log/"))) } @@ -749,6 +795,7 @@ func (kl *Kubelet) Run(updates <-chan PodUpdate) { // Move Kubelet to a container. if kl.resourceContainer != "" { + // Fixme: I need to reside inside ContainerManager interface. err := util.RunInResourceContainer(kl.resourceContainer) if err != nil { glog.Warningf("Failed to move Kubelet to container %q: %v", kl.resourceContainer, err) @@ -793,6 +840,9 @@ func (kl *Kubelet) initialNodeStatus() (*api.Node, error) { Name: kl.nodeName, Labels: map[string]string{"kubernetes.io/hostname": kl.hostname}, }, + Spec: api.NodeSpec{ + Unschedulable: !kl.registerSchedulable, + }, } if kl.cloud != nil { instances, ok := kl.cloud.Instances() @@ -1209,20 +1259,20 @@ func (kl *Kubelet) makePodDataDirs(pod *api.Pod) error { return nil } -func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecontainer.Pod, updateType SyncPodType) error { +func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecontainer.Pod, updateType kubetypes.SyncPodType) error { podFullName := kubecontainer.GetPodFullName(pod) uid := pod.UID start := time.Now() var firstSeenTime time.Time - if firstSeenTimeStr, ok := pod.Annotations[ConfigFirstSeenAnnotationKey]; !ok { + if firstSeenTimeStr, ok := pod.Annotations[kubetypes.ConfigFirstSeenAnnotationKey]; !ok { glog.V(3).Infof("First seen time not recorded for pod %q", pod.UID) } else { - firstSeenTime = kubeletTypes.ConvertToTimestamp(firstSeenTimeStr).Get() + firstSeenTime = kubetypes.ConvertToTimestamp(firstSeenTimeStr).Get() } // Before returning, regenerate status and store it in the cache. defer func() { - if isStaticPod(pod) && mirrorPod == nil { + if kubepod.IsStaticPod(pod) && mirrorPod == nil { // No need to cache the status because the mirror pod does not // exist yet. return @@ -1291,12 +1341,9 @@ func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecont // status. Any race conditions here effectively boils down to -- the pod worker didn't sync // state of a newly started container with the apiserver before the kubelet restarted, so // it's OK to pretend like the kubelet started them after it restarted. - // - // Also note that deletes currently have an updateType of `create` set in UpdatePods. - // This, again, does not matter because deletes are not processed by this method. var podStatus api.PodStatus - if updateType == SyncPodCreate { + if updateType == kubetypes.SyncPodCreate { // This is the first time we are syncing the pod. Record the latency // since kubelet first saw the pod if firstSeenTime is set. if !firstSeenTime.IsZero() { @@ -1304,7 +1351,7 @@ func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecont } podStatus = pod.Status - podStatus.StartTime = &util.Time{Time: start} + podStatus.StartTime = &unversioned.Time{Time: start} kl.statusManager.SetPodStatus(pod, podStatus) glog.V(3).Infof("Not generating pod status for new pod %q", podFullName) } else { @@ -1332,7 +1379,7 @@ func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecont return err } if egress != nil || ingress != nil { - if pod.Spec.HostNetwork { + if podUsesHostNetwork(pod) { kl.recorder.Event(pod, "HostNetworkNotSupported", "Bandwidth shaping is not currently supported on the host network") } else if kl.shaper != nil { status, found := kl.statusManager.GetPodStatus(pod.UID) @@ -1352,7 +1399,7 @@ func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecont } } - if isStaticPod(pod) { + if kubepod.IsStaticPod(pod) { if mirrorPod != nil && !kl.podManager.IsMirrorPodOf(mirrorPod, pod) { // The mirror pod is semantically different from the static pod. Remove // it. The mirror pod will get recreated later. @@ -1371,6 +1418,10 @@ func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecont return nil } +func podUsesHostNetwork(pod *api.Pod) bool { + return pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork +} + // getPullSecretsForPod inspects the Pod and retrieves the referenced pull secrets // TODO duplicate secrets are being retrieved multiple times and there is no cache. Creating and using a secret manager interface will make this easier to address. func (kl *Kubelet) getPullSecretsForPod(pod *api.Pod) ([]api.Secret, error) { @@ -1539,7 +1590,7 @@ func (kl *Kubelet) cleanupTerminatedPods(pods []*api.Pod, runningPods []*kubecon // pastActiveDeadline returns true if the pod has been active for more than // ActiveDeadlineSeconds. func (kl *Kubelet) pastActiveDeadline(pod *api.Pod) bool { - now := util.Now() + now := unversioned.Now() if pod.Spec.ActiveDeadlineSeconds != nil { podStatus, ok := kl.statusManager.GetPodStatus(pod.UID) if !ok { @@ -1600,7 +1651,7 @@ func (kl *Kubelet) removeOrphanedPodStatuses(pods []*api.Pod, mirrorPods []*api. } func (kl *Kubelet) deletePod(uid types.UID) error { - if !kl.sourcesReady() { + if !kl.allSourcesReady() { // If the sources aren't ready, skip deletion, as we may accidentally delete pods // for sources that haven't reported yet. return fmt.Errorf("skipping delete because sources aren't ready yet") @@ -1632,13 +1683,6 @@ func (kl *Kubelet) deletePod(uid types.UID) error { // should not contain any blocking calls. Re-examine the function and decide // whether or not we should move it into a separte goroutine. func (kl *Kubelet) HandlePodCleanups() error { - if !kl.sourcesReady() { - // If the sources aren't ready, skip deletion, as we may accidentally delete pods - // for sources that haven't reported yet. - glog.V(4).Infof("Skipping cleanup, sources aren't ready yet.") - return nil - } - allPods, mirrorPods := kl.podManager.GetPodsAndMirrorPods() // Pod phase progresses monotonically. Once a pod has reached a final state, // it should never leave regardless of the restart policy. The statuses @@ -1659,6 +1703,7 @@ func (kl *Kubelet) HandlePodCleanups() error { // Stop the workers for no-longer existing pods. // TODO: is here the best place to forget pod workers? kl.podWorkers.ForgetNonExistingPodWorkers(desiredPods) + kl.probeManager.CleanupPods(activePods) runningPods, err := kl.runtimeCache.GetPods() if err != nil { @@ -1868,7 +1913,7 @@ func (kl *Kubelet) canAdmitPod(pods []*api.Pod, pod *api.Pod) (bool, string, str // any new change seen, will run a sync against desired state and running state. If // no changes are seen to the configuration, will synchronize the last known desired // state every sync-frequency seconds. Never returns. -func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) { +func (kl *Kubelet) syncLoop(updates <-chan kubetypes.PodUpdate, handler SyncHandler) { glog.Info("Starting kubelet main sync loop.") var housekeepingTimestamp time.Time for { @@ -1882,26 +1927,35 @@ func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) { glog.Infof("Skipping pod synchronization, network is not configured") continue } + + // Make sure we sync first to receive the pods from the sources before + // performing housekeeping. + if !kl.syncLoopIteration(updates, handler) { + break + } // We don't want to perform housekeeping too often, so we set a minimum // period for it. Housekeeping would be performed at least once every // kl.resyncInterval, and *no* more than once every // housekeepingMinimumPeriod. // TODO (#13418): Investigate whether we can/should spawn a dedicated // goroutine for housekeeping - if housekeepingTimestamp.IsZero() || time.Since(housekeepingTimestamp) > housekeepingMinimumPeriod { + if !kl.allSourcesReady() { + // If the sources aren't ready, skip housekeeping, as we may + // accidentally delete pods from unready sources. + glog.V(4).Infof("Skipping cleanup, sources aren't ready yet.") + } else if housekeepingTimestamp.IsZero() { + housekeepingTimestamp = time.Now() + } else if time.Since(housekeepingTimestamp) > housekeepingMinimumPeriod { glog.V(4).Infof("SyncLoop (housekeeping)") if err := handler.HandlePodCleanups(); err != nil { glog.Errorf("Failed cleaning pods: %v", err) } housekeepingTimestamp = time.Now() } - if !kl.syncLoopIteration(updates, handler) { - break - } } } -func (kl *Kubelet) syncLoopIteration(updates <-chan PodUpdate, handler SyncHandler) bool { +func (kl *Kubelet) syncLoopIteration(updates <-chan kubetypes.PodUpdate, handler SyncHandler) bool { kl.syncLoopMonitor.Store(time.Now()) select { case u, open := <-updates: @@ -1909,17 +1963,18 @@ func (kl *Kubelet) syncLoopIteration(updates <-chan PodUpdate, handler SyncHandl glog.Errorf("Update channel is closed. Exiting the sync loop.") return false } + kl.addSource(u.Source) switch u.Op { - case ADD: - glog.V(2).Infof("SyncLoop (ADD): %q", kubeletUtil.FormatPodNames(u.Pods)) + case kubetypes.ADD: + glog.V(2).Infof("SyncLoop (ADD, %q): %q", u.Source, kubeletutil.FormatPodNames(u.Pods)) handler.HandlePodAdditions(u.Pods) - case UPDATE: - glog.V(2).Infof("SyncLoop (UPDATE): %q", kubeletUtil.FormatPodNames(u.Pods)) + case kubetypes.UPDATE: + glog.V(2).Infof("SyncLoop (UPDATE, %q): %q", u.Source, kubeletutil.FormatPodNames(u.Pods)) handler.HandlePodUpdates(u.Pods) - case REMOVE: - glog.V(2).Infof("SyncLoop (REMOVE): %q", kubeletUtil.FormatPodNames(u.Pods)) + case kubetypes.REMOVE: + glog.V(2).Infof("SyncLoop (REMOVE, %q): %q", u.Source, kubeletutil.FormatPodNames(u.Pods)) handler.HandlePodDeletions(u.Pods) - case SET: + case kubetypes.SET: // TODO: Do we want to support this? glog.Errorf("Kubelet does not support snapshot update") } @@ -1932,16 +1987,16 @@ func (kl *Kubelet) syncLoopIteration(updates <-chan PodUpdate, handler SyncHandl return true } -func (kl *Kubelet) dispatchWork(pod *api.Pod, syncType SyncPodType, mirrorPod *api.Pod, start time.Time) { +func (kl *Kubelet) dispatchWork(pod *api.Pod, syncType kubetypes.SyncPodType, mirrorPod *api.Pod, start time.Time) { if kl.podIsTerminated(pod) { return } // Run the sync in an async worker. - kl.podWorkers.UpdatePod(pod, mirrorPod, func() { + kl.podWorkers.UpdatePod(pod, mirrorPod, syncType, func() { metrics.PodWorkerLatency.WithLabelValues(syncType.String()).Observe(metrics.SinceInMicroseconds(start)) }) // Note the number of containers for new pods. - if syncType == SyncPodCreate { + if syncType == kubetypes.SyncPodCreate { metrics.ContainersPerPodCount.Observe(float64(len(pod.Spec.Containers))) } } @@ -1952,7 +2007,7 @@ func (kl *Kubelet) handleMirrorPod(mirrorPod *api.Pod, start time.Time) { // corresponding static pod. Send update to the pod worker if the static // pod exists. if pod, ok := kl.podManager.GetPodByMirrorPod(mirrorPod); ok { - kl.dispatchWork(pod, SyncPodUpdate, mirrorPod, start) + kl.dispatchWork(pod, kubetypes.SyncPodUpdate, mirrorPod, start) } } @@ -1961,7 +2016,7 @@ func (kl *Kubelet) HandlePodAdditions(pods []*api.Pod) { sort.Sort(podsByCreationTime(pods)) for _, pod := range pods { kl.podManager.AddPod(pod) - if isMirrorPod(pod) { + if kubepod.IsMirrorPod(pod) { kl.handleMirrorPod(pod, start) continue } @@ -1977,7 +2032,8 @@ func (kl *Kubelet) HandlePodAdditions(pods []*api.Pod) { continue } mirrorPod, _ := kl.podManager.GetMirrorPodByPod(pod) - kl.dispatchWork(pod, SyncPodCreate, mirrorPod, start) + kl.dispatchWork(pod, kubetypes.SyncPodCreate, mirrorPod, start) + kl.probeManager.AddPod(pod) } } @@ -1985,14 +2041,14 @@ func (kl *Kubelet) HandlePodUpdates(pods []*api.Pod) { start := time.Now() for _, pod := range pods { kl.podManager.UpdatePod(pod) - if isMirrorPod(pod) { + if kubepod.IsMirrorPod(pod) { kl.handleMirrorPod(pod, start) continue } // TODO: Evaluate if we need to validate and reject updates. mirrorPod, _ := kl.podManager.GetMirrorPodByPod(pod) - kl.dispatchWork(pod, SyncPodUpdate, mirrorPod, start) + kl.dispatchWork(pod, kubetypes.SyncPodUpdate, mirrorPod, start) } } @@ -2000,15 +2056,16 @@ func (kl *Kubelet) HandlePodDeletions(pods []*api.Pod) { start := time.Now() for _, pod := range pods { kl.podManager.DeletePod(pod) - if isMirrorPod(pod) { + if kubepod.IsMirrorPod(pod) { kl.handleMirrorPod(pod, start) continue } // Deletion is allowed to fail because the periodic cleanup routine // will trigger deletion again. if err := kl.deletePod(pod.UID); err != nil { - glog.V(2).Infof("Failed to delete pod %q, err: %v", kubeletUtil.FormatPodName(pod), err) + glog.V(2).Infof("Failed to delete pod %q, err: %v", kubeletutil.FormatPodName(pod), err) } + kl.probeManager.RemovePod(pod) } } @@ -2016,7 +2073,7 @@ func (kl *Kubelet) HandlePodSyncs(pods []*api.Pod) { start := time.Now() for _, pod := range pods { mirrorPod, _ := kl.podManager.GetMirrorPodByPod(pod) - kl.dispatchWork(pod, SyncPodSync, mirrorPod, start) + kl.dispatchWork(pod, kubetypes.SyncPodSync, mirrorPod, start) } } @@ -2044,31 +2101,31 @@ func (kl *Kubelet) validatePodPhase(podStatus *api.PodStatus) error { return fmt.Errorf("pod is not in 'Running', 'Succeeded' or 'Failed' state - State: %q", podStatus.Phase) } -func (kl *Kubelet) validateContainerStatus(podStatus *api.PodStatus, containerName string, previous bool) (containerID string, err error) { +func (kl *Kubelet) validateContainerStatus(podStatus *api.PodStatus, containerName string, previous bool) (containerID kubecontainer.ContainerID, err error) { var cID string cStatus, found := api.GetContainerStatus(podStatus.ContainerStatuses, containerName) if !found { - return "", fmt.Errorf("container %q not found", containerName) + return kubecontainer.ContainerID{}, fmt.Errorf("container %q not found", containerName) } if previous { if cStatus.LastTerminationState.Terminated == nil { - return "", fmt.Errorf("previous terminated container %q not found", containerName) + return kubecontainer.ContainerID{}, fmt.Errorf("previous terminated container %q not found", containerName) } cID = cStatus.LastTerminationState.Terminated.ContainerID } else { if cStatus.State.Waiting != nil { - return "", fmt.Errorf("container %q is in waiting state.", containerName) + return kubecontainer.ContainerID{}, fmt.Errorf("container %q is in waiting state.", containerName) } cID = cStatus.ContainerID } - return kubecontainer.TrimRuntimePrefix(cID), nil + return kubecontainer.ParseContainerID(cID), nil } // GetKubeletContainerLogs returns logs from the container // TODO: this method is returning logs of random container attempts, when it should be returning the most recent attempt // or all of them. -func (kl *Kubelet) GetKubeletContainerLogs(podFullName, containerName, tail string, follow, previous bool, stdout, stderr io.Writer) error { +func (kl *Kubelet) GetKubeletContainerLogs(podFullName, containerName string, logOptions *api.PodLogOptions, stdout, stderr io.Writer) error { // TODO(vmarmol): Refactor to not need the pod status and verification. // Pod workers periodically write status to statusManager. If status is not // cached there, something is wrong (or kubelet just restarted and hasn't @@ -2092,13 +2149,13 @@ func (kl *Kubelet) GetKubeletContainerLogs(podFullName, containerName, tail stri // No log is available if pod is not in a "known" phase (e.g. Unknown). return fmt.Errorf("Pod %q in namespace %q : %v", name, namespace, err) } - containerID, err := kl.validateContainerStatus(&podStatus, containerName, previous) + containerID, err := kl.validateContainerStatus(&podStatus, containerName, logOptions.Previous) if err != nil { // No log is available if the container status is missing or is in the // waiting state. return fmt.Errorf("Pod %q in namespace %q: %v", name, namespace, err) } - return kl.containerRuntime.GetContainerLogs(pod, containerID, tail, follow, stdout, stderr) + return kl.containerRuntime.GetContainerLogs(pod, containerID, logOptions, stdout, stderr) } // GetHostname Returns the hostname as the kubelet sees it. @@ -2328,12 +2385,14 @@ func (kl *Kubelet) setNodeStatus(node *api.Node) error { node.Status.NodeInfo.KubeProxyVersion = version.Get().String() } + node.Status.DaemonEndpoints = *kl.daemonEndpoints + // Check whether container runtime can be reported as up. containerRuntimeUp := kl.containerRuntimeUp() // Check whether network is configured properly networkConfigured := kl.doneNetworkConfigure() - currentTime := util.Now() + currentTime := unversioned.Now() var newNodeReadyCondition api.NodeCondition var oldNodeReadyConditionStatus api.ConditionStatus if containerRuntimeUp && networkConfigured { @@ -2345,13 +2404,12 @@ func (kl *Kubelet) setNodeStatus(node *api.Node) error { LastHeartbeatTime: currentTime, } } else { - var reasons []string var messages []string if !containerRuntimeUp { messages = append(messages, "container runtime is down") } if !networkConfigured { - messages = append(reasons, "network not configured correctly") + messages = append(messages, "network not configured correctly") } newNodeReadyCondition = api.NodeCondition{ Type: api.NodeReady, @@ -2420,7 +2478,9 @@ func (kl *Kubelet) tryUpdateNodeStatus() error { return fmt.Errorf("no node instance returned for %q", kl.nodeName) } kl.networkConfigMutex.Lock() - kl.podCIDR = node.Spec.PodCIDR + if kl.reconcileCIDR { + kl.podCIDR = node.Spec.PodCIDR + } kl.networkConfigMutex.Unlock() if err := kl.setNodeStatus(node); err != nil { @@ -2495,29 +2555,51 @@ func GetPhase(spec *api.PodSpec, info []api.ContainerStatus) api.PodPhase { } } +func readyPodCondition(isPodReady bool, reason, message string) []api.PodCondition { + condition := api.PodCondition{ + Type: api.PodReady, + } + if isPodReady { + condition.Status = api.ConditionTrue + } else { + condition.Status = api.ConditionFalse + } + condition.Reason = reason + condition.Message = message + return []api.PodCondition{condition} +} + // getPodReadyCondition returns ready condition if all containers in a pod are ready, else it returns an unready condition. -func getPodReadyCondition(spec *api.PodSpec, statuses []api.ContainerStatus) []api.PodCondition { - ready := []api.PodCondition{{ - Type: api.PodReady, - Status: api.ConditionTrue, - }} - unready := []api.PodCondition{{ - Type: api.PodReady, - Status: api.ConditionFalse, - }} - if statuses == nil { - return unready +func getPodReadyCondition(spec *api.PodSpec, containerStatuses []api.ContainerStatus) []api.PodCondition { + // Find if all containers are ready or not. + if containerStatuses == nil { + return readyPodCondition(false, "UnknownContainerStatuses", "") } + unknownContainers := []string{} + unreadyContainers := []string{} for _, container := range spec.Containers { - if containerStatus, ok := api.GetContainerStatus(statuses, container.Name); ok { + if containerStatus, ok := api.GetContainerStatus(containerStatuses, container.Name); ok { if !containerStatus.Ready { - return unready + unreadyContainers = append(unreadyContainers, container.Name) } } else { - return unready + unknownContainers = append(unknownContainers, container.Name) } } - return ready + unreadyMessages := []string{} + if len(unknownContainers) > 0 { + unreadyMessages = append(unreadyMessages, fmt.Sprintf("containers with unknown status: %s", unknownContainers)) + } + if len(unreadyContainers) > 0 { + unreadyMessages = append(unreadyMessages, fmt.Sprintf("containers with unready status: %s", unreadyContainers)) + } + unreadyMessage := strings.Join(unreadyMessages, ", ") + if unreadyMessage != "" { + // return unready status. + return readyPodCondition(false, fmt.Sprint("ContainersNotReady"), unreadyMessage) + } + // return ready status. + return readyPodCondition(true, "", "") } // By passing the pod directly, this method avoids pod lookup, which requires @@ -2531,8 +2613,7 @@ func (kl *Kubelet) generatePodStatus(pod *api.Pod) (api.PodStatus, error) { podFullName := kubecontainer.GetPodFullName(pod) glog.V(3).Infof("Generating status for %q", podFullName) - - if existingStatus, ok := kl.statusManager.GetPodStatus(pod.UID); ok { + if existingStatus, hasExistingStatus := kl.statusManager.GetPodStatus(pod.UID); hasExistingStatus { // This is a hacky fix to ensure container restart counts increment // monotonically. Normally, we should not modify given pod. In this // case, we check if there are cached status for this pod, and update @@ -2575,15 +2656,7 @@ func (kl *Kubelet) generatePodStatus(pod *api.Pod) (api.PodStatus, error) { // Assume info is ready to process podStatus.Phase = GetPhase(spec, podStatus.ContainerStatuses) - for _, c := range spec.Containers { - for i, st := range podStatus.ContainerStatuses { - if st.Name == c.Name { - ready := st.State.Running != nil && kl.readinessManager.GetReadiness(kubecontainer.TrimRuntimePrefix(st.ContainerID)) - podStatus.ContainerStatuses[i].Ready = ready - break - } - } - } + kl.probeManager.UpdatePodStatus(pod.UID, podStatus) podStatus.Conditions = append(podStatus.Conditions, getPodReadyCondition(spec, podStatus.ContainerStatuses)...) @@ -2593,7 +2666,7 @@ func (kl *Kubelet) generatePodStatus(pod *api.Pod) (api.PodStatus, error) { glog.V(4).Infof("Cannot get host IP: %v", err) } else { podStatus.HostIP = hostIP.String() - if pod.Spec.HostNetwork && podStatus.PodIP == "" { + if podUsesHostNetwork(pod) && podStatus.PodIP == "" { podStatus.PodIP = hostIP.String() } } @@ -2630,7 +2703,7 @@ func (kl *Kubelet) RunInContainer(podFullName string, podUID types.UID, containe if container == nil { return nil, fmt.Errorf("container not found (%q)", containerName) } - return kl.runner.RunInContainer(string(container.ID), cmd) + return kl.runner.RunInContainer(container.ID, cmd) } // ExecInContainer executes a command in a container, connecting the supplied @@ -2645,7 +2718,7 @@ func (kl *Kubelet) ExecInContainer(podFullName string, podUID types.UID, contain if container == nil { return fmt.Errorf("container not found (%q)", containerName) } - return kl.runner.ExecInContainer(string(container.ID), cmd, stdin, stdout, stderr, tty) + return kl.runner.ExecInContainer(container.ID, cmd, stdin, stdout, stderr, tty) } func (kl *Kubelet) AttachContainer(podFullName string, podUID types.UID, containerName string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { @@ -2658,7 +2731,7 @@ func (kl *Kubelet) AttachContainer(podFullName string, podUID types.UID, contain if container == nil { return fmt.Errorf("container not found (%q)", containerName) } - return kl.containerRuntime.AttachContainer(string(container.ID), stdin, stdout, stderr, tty) + return kl.containerRuntime.AttachContainer(container.ID, stdin, stdout, stderr, tty) } // PortForward connects to the pod's port and copies data between the port @@ -2706,7 +2779,7 @@ func (kl *Kubelet) GetContainerInfo(podFullName string, podUID types.UID, contai return nil, ErrContainerNotFound } - ci, err := kl.cadvisor.DockerContainer(string(container.ID), req) + ci, err := kl.cadvisor.DockerContainer(container.ID.ID, req) if err != nil { return nil, err } @@ -2754,6 +2827,16 @@ func (kl *Kubelet) GetRuntime() kubecontainer.Runtime { return kl.containerRuntime } +// Proxy prober calls through the Kubelet to break the circular dependency between the runtime & +// prober. +// TODO: Remove this hack once the runtime no longer depends on the prober. +func (kl *Kubelet) ProbeLiveness(pod *api.Pod, status api.PodStatus, container api.Container, containerID kubecontainer.ContainerID, createdAt int64) (probe.Result, error) { + return kl.prober.ProbeLiveness(pod, status, container, containerID, createdAt) +} +func (kl *Kubelet) ProbeReadiness(pod *api.Pod, status api.PodStatus, container api.Container, containerID kubecontainer.ContainerID) (probe.Result, error) { + return kl.prober.ProbeReadiness(pod, status, container, containerID) +} + var minRsrc = resource.MustParse("1k") var maxRsrc = resource.MustParse("1P") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/kubelet_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/kubelet_test.go index 17deade5395e..d3d7940c7f3f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/kubelet_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/kubelet_test.go @@ -37,6 +37,7 @@ import ( apierrors "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/capabilities" "k8s.io/kubernetes/pkg/client/record" "k8s.io/kubernetes/pkg/client/unversioned/testclient" @@ -44,10 +45,15 @@ import ( "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/network" + kubepod "k8s.io/kubernetes/pkg/kubelet/pod" + "k8s.io/kubernetes/pkg/kubelet/prober" + "k8s.io/kubernetes/pkg/kubelet/status" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/bandwidth" + "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/pkg/volume" _ "k8s.io/kubernetes/pkg/volume/host_path" @@ -75,7 +81,7 @@ type TestKubelet struct { fakeRuntime *kubecontainer.FakeRuntime fakeCadvisor *cadvisor.Mock fakeKubeClient *testclient.Fake - fakeMirrorClient *fakeMirrorClient + fakeMirrorClient *kubepod.FakeMirrorClient } func newTestKubelet(t *testing.T) *TestKubelet { @@ -99,20 +105,20 @@ func newTestKubelet(t *testing.T) *TestKubelet { if err := os.MkdirAll(kubelet.rootDirectory, 0750); err != nil { t.Fatalf("can't mkdir(%q): %v", kubelet.rootDirectory, err) } - kubelet.sourcesReady = func() bool { return true } + kubelet.sourcesReady = func(_ sets.String) bool { return true } kubelet.masterServiceNamespace = api.NamespaceDefault kubelet.serviceLister = testServiceLister{} kubelet.nodeLister = testNodeLister{} - kubelet.readinessManager = kubecontainer.NewReadinessManager() kubelet.recorder = fakeRecorder - kubelet.statusManager = newStatusManager(fakeKubeClient) + kubelet.statusManager = status.NewManager(fakeKubeClient) if err := kubelet.setupDataDirs(); err != nil { t.Fatalf("can't initialize kubelet data dirs: %v", err) } + kubelet.daemonEndpoints = &api.NodeDaemonEndpoints{} mockCadvisor := &cadvisor.Mock{} kubelet.cadvisor = mockCadvisor - podManager, fakeMirrorClient := newFakePodManager() - kubelet.podManager = podManager + fakeMirrorClient := kubepod.NewFakeMirrorClient() + kubelet.podManager = kubepod.NewBasicPodManager(fakeMirrorClient) kubelet.containerRefManager = kubecontainer.NewRefManager() diskSpaceManager, err := newDiskSpaceManager(mockCadvisor, DiskSpacePolicy{}) if err != nil { @@ -127,8 +133,12 @@ func newTestKubelet(t *testing.T) *TestKubelet { runtimeCache: kubelet.runtimeCache, t: t, } + + kubelet.prober = prober.FakeProber{} + kubelet.probeManager = prober.FakeManager{} + kubelet.volumeManager = newVolumeManager() - kubelet.containerManager, _ = newContainerManager(mockCadvisor, "", "", "") + kubelet.containerManager, _ = newContainerManager(fakeContainerMgrMountInt(), mockCadvisor, "", "", "") kubelet.networkConfigured = true fakeClock := &util.FakeClock{Time: time.Now()} kubelet.backOff = util.NewBackOff(time.Second, time.Minute) @@ -304,7 +314,7 @@ func TestKubeletDirsCompat(t *testing.T) { } } -var emptyPodUIDs map[types.UID]SyncPodType +var emptyPodUIDs map[types.UID]kubetypes.SyncPodType func TestSyncLoopTimeUpdate(t *testing.T) { testKubelet := newTestKubelet(t) @@ -316,12 +326,12 @@ func TestSyncLoopTimeUpdate(t *testing.T) { t.Errorf("Unexpected sync loop time: %s, expected 0", loopTime1) } - kubelet.syncLoopIteration(make(chan PodUpdate), kubelet) + kubelet.syncLoopIteration(make(chan kubetypes.PodUpdate), kubelet) loopTime2 := kubelet.LatestLoopEntryTime() if loopTime2.IsZero() { t.Errorf("Unexpected sync loop time: 0, expected non-zero value.") } - kubelet.syncLoopIteration(make(chan PodUpdate), kubelet) + kubelet.syncLoopIteration(make(chan kubetypes.PodUpdate), kubelet) loopTime3 := kubelet.LatestLoopEntryTime() if !loopTime3.After(loopTime1) { t.Errorf("Sync Loop Time was not updated correctly. Second update timestamp should be greater than first update timestamp") @@ -334,8 +344,11 @@ func TestSyncLoopAbort(t *testing.T) { kubelet := testKubelet.kubelet kubelet.lastTimestampRuntimeUp = time.Now() kubelet.networkConfigured = true + // The syncLoop waits on time.After(resyncInterval), set it really big so that we don't race for + // the channel close + kubelet.resyncInterval = time.Second * 30 - ch := make(chan PodUpdate) + ch := make(chan kubetypes.PodUpdate) close(ch) // sanity check (also prevent this test from hanging in the next step) @@ -383,7 +396,7 @@ func TestSyncPodsDeletesWhenSourcesAreReady(t *testing.T) { testKubelet.fakeCadvisor.On("DockerImagesFsInfo").Return(cadvisorApiv2.FsInfo{}, nil) testKubelet.fakeCadvisor.On("RootFsInfo").Return(cadvisorApiv2.FsInfo{}, nil) kubelet := testKubelet.kubelet - kubelet.sourcesReady = func() bool { return ready } + kubelet.sourcesReady = func(_ sets.String) bool { return ready } fakeRuntime.PodList = []*kubecontainer.Pod{ { @@ -576,7 +589,7 @@ func TestGetContainerInfo(t *testing.T) { Containers: []*kubecontainer.Container{ { Name: "foo", - ID: types.UID(containerID), + ID: kubecontainer.ContainerID{"test", containerID}, }, }, }, @@ -658,7 +671,7 @@ func TestGetContainerInfoWhenCadvisorFailed(t *testing.T) { Namespace: "ns", Containers: []*kubecontainer.Container{ {Name: "foo", - ID: types.UID(containerID), + ID: kubecontainer.ContainerID{"test", containerID}, }, }, }, @@ -742,7 +755,7 @@ func TestGetContainerInfoWithNoMatchingContainers(t *testing.T) { Namespace: "ns", Containers: []*kubecontainer.Container{ {Name: "bar", - ID: types.UID("fakeID"), + ID: kubecontainer.ContainerID{"test", "fakeID"}, }, }}, } @@ -762,7 +775,7 @@ func TestGetContainerInfoWithNoMatchingContainers(t *testing.T) { type fakeContainerCommandRunner struct { Cmd []string - ID string + ID kubecontainer.ContainerID PodID types.UID E error Stdin io.Reader @@ -773,13 +786,13 @@ type fakeContainerCommandRunner struct { Stream io.ReadWriteCloser } -func (f *fakeContainerCommandRunner) RunInContainer(id string, cmd []string) ([]byte, error) { +func (f *fakeContainerCommandRunner) RunInContainer(id kubecontainer.ContainerID, cmd []string) ([]byte, error) { f.Cmd = cmd f.ID = id return []byte{}, f.E } -func (f *fakeContainerCommandRunner) ExecInContainer(id string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool) error { +func (f *fakeContainerCommandRunner) ExecInContainer(id kubecontainer.ContainerID, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool) error { f.Cmd = cmd f.ID = id f.Stdin = in @@ -825,7 +838,7 @@ func TestRunInContainer(t *testing.T) { fakeCommandRunner := fakeContainerCommandRunner{} kubelet.runner = &fakeCommandRunner - containerID := "abc1234" + containerID := kubecontainer.ContainerID{"test", "abc1234"} fakeRuntime.PodList = []*kubecontainer.Pod{ { ID: "12345678", @@ -833,7 +846,7 @@ func TestRunInContainer(t *testing.T) { Namespace: "nsFoo", Containers: []*kubecontainer.Container{ {Name: "containerFoo", - ID: types.UID(containerID), + ID: containerID, }, }, }, @@ -1749,30 +1762,30 @@ func getNotReadyStatus(cName string) api.ContainerStatus { Ready: false, } } +func getReadyCondition(status api.ConditionStatus, reason, message string) []api.PodCondition { + return []api.PodCondition{{ + Type: api.PodReady, + Status: status, + Reason: reason, + Message: message, + }} +} func TestGetPodReadyCondition(t *testing.T) { - ready := []api.PodCondition{{ - Type: api.PodReady, - Status: api.ConditionTrue, - }} - unready := []api.PodCondition{{ - Type: api.PodReady, - Status: api.ConditionFalse, - }} tests := []struct { - spec *api.PodSpec - info []api.ContainerStatus - expected []api.PodCondition + spec *api.PodSpec + containerStatuses []api.ContainerStatus + expected []api.PodCondition }{ { - spec: nil, - info: nil, - expected: unready, + spec: nil, + containerStatuses: nil, + expected: getReadyCondition(api.ConditionFalse, "UnknownContainerStatuses", ""), }, { - spec: &api.PodSpec{}, - info: []api.ContainerStatus{}, - expected: ready, + spec: &api.PodSpec{}, + containerStatuses: []api.ContainerStatus{}, + expected: getReadyCondition(api.ConditionTrue, "", ""), }, { spec: &api.PodSpec{ @@ -1780,19 +1793,8 @@ func TestGetPodReadyCondition(t *testing.T) { {Name: "1234"}, }, }, - info: []api.ContainerStatus{}, - expected: unready, - }, - { - spec: &api.PodSpec{ - Containers: []api.Container{ - {Name: "1234"}, - }, - }, - info: []api.ContainerStatus{ - getReadyStatus("1234"), - }, - expected: ready, + containerStatuses: []api.ContainerStatus{}, + expected: getReadyCondition(api.ConditionFalse, "ContainersNotReady", "containers with unknown status: [1234]"), }, { spec: &api.PodSpec{ @@ -1801,11 +1803,11 @@ func TestGetPodReadyCondition(t *testing.T) { {Name: "5678"}, }, }, - info: []api.ContainerStatus{ + containerStatuses: []api.ContainerStatus{ getReadyStatus("1234"), getReadyStatus("5678"), }, - expected: ready, + expected: getReadyCondition(api.ConditionTrue, "", ""), }, { spec: &api.PodSpec{ @@ -1814,10 +1816,10 @@ func TestGetPodReadyCondition(t *testing.T) { {Name: "5678"}, }, }, - info: []api.ContainerStatus{ + containerStatuses: []api.ContainerStatus{ getReadyStatus("1234"), }, - expected: unready, + expected: getReadyCondition(api.ConditionFalse, "ContainersNotReady", "containers with unknown status: [5678]"), }, { spec: &api.PodSpec{ @@ -1826,16 +1828,16 @@ func TestGetPodReadyCondition(t *testing.T) { {Name: "5678"}, }, }, - info: []api.ContainerStatus{ + containerStatuses: []api.ContainerStatus{ getReadyStatus("1234"), getNotReadyStatus("5678"), }, - expected: unready, + expected: getReadyCondition(api.ConditionFalse, "ContainersNotReady", "containers with unready status: [5678]"), }, } for i, test := range tests { - condition := getPodReadyCondition(test.spec, test.info) + condition := getPodReadyCondition(test.spec, test.containerStatuses) if !reflect.DeepEqual(condition, test.expected) { t.Errorf("On test case %v, expected:\n%+v\ngot\n%+v\n", i, test.expected, condition) } @@ -1866,7 +1868,7 @@ func TestExecInContainerNoSuchPod(t *testing.T) { if err == nil { t.Fatal("unexpected non-error") } - if fakeCommandRunner.ID != "" { + if !fakeCommandRunner.ID.IsEmpty() { t.Fatal("unexpected invocation of runner.ExecInContainer") } } @@ -1888,7 +1890,7 @@ func TestExecInContainerNoSuchContainer(t *testing.T) { Namespace: podNamespace, Containers: []*kubecontainer.Container{ {Name: "bar", - ID: "barID"}, + ID: kubecontainer.ContainerID{"test", "barID"}}, }, }, } @@ -1910,7 +1912,7 @@ func TestExecInContainerNoSuchContainer(t *testing.T) { if err == nil { t.Fatal("unexpected non-error") } - if fakeCommandRunner.ID != "" { + if !fakeCommandRunner.ID.IsEmpty() { t.Fatal("unexpected invocation of runner.ExecInContainer") } } @@ -1951,7 +1953,7 @@ func TestExecInContainer(t *testing.T) { Namespace: podNamespace, Containers: []*kubecontainer.Container{ {Name: containerID, - ID: types.UID(containerID), + ID: kubecontainer.ContainerID{"test", containerID}, }, }, }, @@ -1974,7 +1976,7 @@ func TestExecInContainer(t *testing.T) { if err != nil { t.Fatalf("unexpected error: %s", err) } - if e, a := containerID, fakeCommandRunner.ID; e != a { + if e, a := containerID, fakeCommandRunner.ID.ID; e != a { t.Fatalf("container name: expected %q, got %q", e, a) } if e, a := command, fakeCommandRunner.Cmd; !reflect.DeepEqual(e, a) { @@ -2015,7 +2017,7 @@ func TestPortForwardNoSuchPod(t *testing.T) { if err == nil { t.Fatal("unexpected non-error") } - if fakeCommandRunner.ID != "" { + if !fakeCommandRunner.ID.IsEmpty() { t.Fatal("unexpected invocation of runner.PortForward") } } @@ -2036,7 +2038,7 @@ func TestPortForward(t *testing.T) { Containers: []*kubecontainer.Container{ { Name: "foo", - ID: "containerFoo", + ID: kubecontainer.ContainerID{"test", "containerFoo"}, }, }, }, @@ -2121,8 +2123,8 @@ func TestHandlePortConflicts(t *testing.T) { }, } // Make sure the Pods are in the reverse order of creation time. - pods[1].CreationTimestamp = util.NewTime(time.Now()) - pods[0].CreationTimestamp = util.NewTime(time.Now().Add(1 * time.Second)) + pods[1].CreationTimestamp = unversioned.NewTime(time.Now()) + pods[0].CreationTimestamp = unversioned.NewTime(time.Now().Add(1 * time.Second)) // The newer pod should be rejected. conflictedPod := pods[0] @@ -2211,8 +2213,8 @@ func TestHandleMemExceeded(t *testing.T) { }, } // Make sure the Pods are in the reverse order of creation time. - pods[1].CreationTimestamp = util.NewTime(time.Now()) - pods[0].CreationTimestamp = util.NewTime(time.Now().Add(1 * time.Second)) + pods[1].CreationTimestamp = unversioned.NewTime(time.Now()) + pods[0].CreationTimestamp = unversioned.NewTime(time.Now().Add(1 * time.Second)) // The newer pod should be rejected. notfittingPod := pods[0] @@ -2386,8 +2388,8 @@ func TestUpdateNewNodeStatus(t *testing.T) { Status: api.ConditionTrue, Reason: "KubeletReady", Message: fmt.Sprintf("kubelet is posting ready status"), - LastHeartbeatTime: util.Time{}, - LastTransitionTime: util.Time{}, + LastHeartbeatTime: unversioned.Time{}, + LastTransitionTime: unversioned.Time{}, }, }, NodeInfo: api.NodeSystemInfo{ @@ -2433,8 +2435,8 @@ func TestUpdateNewNodeStatus(t *testing.T) { if updatedNode.Status.Conditions[0].LastTransitionTime.IsZero() { t.Errorf("unexpected zero last transition timestamp") } - updatedNode.Status.Conditions[0].LastHeartbeatTime = util.Time{} - updatedNode.Status.Conditions[0].LastTransitionTime = util.Time{} + updatedNode.Status.Conditions[0].LastHeartbeatTime = unversioned.Time{} + updatedNode.Status.Conditions[0].LastTransitionTime = unversioned.Time{} if !reflect.DeepEqual(expectedNode, updatedNode) { t.Errorf("unexpected objects: %s", util.ObjectDiff(expectedNode, updatedNode)) } @@ -2455,8 +2457,8 @@ func TestUpdateExistingNodeStatus(t *testing.T) { Status: api.ConditionTrue, Reason: "KubeletReady", Message: fmt.Sprintf("kubelet is posting ready status"), - LastHeartbeatTime: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - LastTransitionTime: util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + LastHeartbeatTime: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + LastTransitionTime: unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), }, }, Capacity: api.ResourceList{ @@ -2492,8 +2494,8 @@ func TestUpdateExistingNodeStatus(t *testing.T) { Status: api.ConditionTrue, Reason: "KubeletReady", Message: fmt.Sprintf("kubelet is posting ready status"), - LastHeartbeatTime: util.Time{}, // placeholder - LastTransitionTime: util.Time{}, // placeholder + LastHeartbeatTime: unversioned.Time{}, // placeholder + LastTransitionTime: unversioned.Time{}, // placeholder }, }, NodeInfo: api.NodeSystemInfo{ @@ -2535,15 +2537,15 @@ func TestUpdateExistingNodeStatus(t *testing.T) { t.Errorf("unexpected object type") } // Expect LastProbeTime to be updated to Now, while LastTransitionTime to be the same. - if reflect.DeepEqual(updatedNode.Status.Conditions[0].LastHeartbeatTime.Rfc3339Copy().UTC(), util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC).Time) { - t.Errorf("expected \n%v\n, got \n%v", util.Now(), util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC)) + if reflect.DeepEqual(updatedNode.Status.Conditions[0].LastHeartbeatTime.Rfc3339Copy().UTC(), unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC).Time) { + t.Errorf("expected \n%v\n, got \n%v", unversioned.Now(), unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC)) } - if !reflect.DeepEqual(updatedNode.Status.Conditions[0].LastTransitionTime.Rfc3339Copy().UTC(), util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC).Time) { + if !reflect.DeepEqual(updatedNode.Status.Conditions[0].LastTransitionTime.Rfc3339Copy().UTC(), unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC).Time) { t.Errorf("expected \n%#v\n, got \n%#v", updatedNode.Status.Conditions[0].LastTransitionTime.Rfc3339Copy(), - util.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC)) + unversioned.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC)) } - updatedNode.Status.Conditions[0].LastHeartbeatTime = util.Time{} - updatedNode.Status.Conditions[0].LastTransitionTime = util.Time{} + updatedNode.Status.Conditions[0].LastHeartbeatTime = unversioned.Time{} + updatedNode.Status.Conditions[0].LastTransitionTime = unversioned.Time{} if !reflect.DeepEqual(expectedNode, updatedNode) { t.Errorf("expected \n%v\n, got \n%v", expectedNode, updatedNode) } @@ -2587,8 +2589,8 @@ func TestUpdateNodeStatusWithoutContainerRuntime(t *testing.T) { Status: api.ConditionFalse, Reason: "KubeletNotReady", Message: fmt.Sprintf("container runtime is down"), - LastHeartbeatTime: util.Time{}, - LastTransitionTime: util.Time{}, + LastHeartbeatTime: unversioned.Time{}, + LastTransitionTime: unversioned.Time{}, }, }, NodeInfo: api.NodeSystemInfo{ @@ -2636,8 +2638,8 @@ func TestUpdateNodeStatusWithoutContainerRuntime(t *testing.T) { if updatedNode.Status.Conditions[0].LastTransitionTime.IsZero() { t.Errorf("unexpected zero last transition timestamp") } - updatedNode.Status.Conditions[0].LastHeartbeatTime = util.Time{} - updatedNode.Status.Conditions[0].LastTransitionTime = util.Time{} + updatedNode.Status.Conditions[0].LastHeartbeatTime = unversioned.Time{} + updatedNode.Status.Conditions[0].LastTransitionTime = unversioned.Time{} if !reflect.DeepEqual(expectedNode, updatedNode) { t.Errorf("unexpected objects: %s", util.ObjectDiff(expectedNode, updatedNode)) } @@ -2658,7 +2660,7 @@ func TestUpdateNodeStatusError(t *testing.T) { } func TestCreateMirrorPod(t *testing.T) { - for _, updateType := range []SyncPodType{SyncPodCreate, SyncPodUpdate} { + for _, updateType := range []kubetypes.SyncPodType{kubetypes.SyncPodCreate, kubetypes.SyncPodUpdate} { testKubelet := newTestKubelet(t) kl := testKubelet.kubelet manager := testKubelet.fakeMirrorClient @@ -2668,7 +2670,7 @@ func TestCreateMirrorPod(t *testing.T) { Name: "bar", Namespace: "foo", Annotations: map[string]string{ - ConfigSourceAnnotationKey: "file", + kubetypes.ConfigSourceAnnotationKey: "file", }, }, } @@ -2701,7 +2703,7 @@ func TestDeleteOutdatedMirrorPod(t *testing.T) { Name: "foo", Namespace: "ns", Annotations: map[string]string{ - ConfigSourceAnnotationKey: "file", + kubetypes.ConfigSourceAnnotationKey: "file", }, }, Spec: api.PodSpec{ @@ -2717,8 +2719,8 @@ func TestDeleteOutdatedMirrorPod(t *testing.T) { Name: "foo", Namespace: "ns", Annotations: map[string]string{ - ConfigSourceAnnotationKey: "api", - ConfigMirrorAnnotationKey: "mirror", + kubetypes.ConfigSourceAnnotationKey: "api", + kubetypes.ConfigMirrorAnnotationKey: "mirror", }, }, Spec: api.PodSpec{ @@ -2730,7 +2732,7 @@ func TestDeleteOutdatedMirrorPod(t *testing.T) { pods := []*api.Pod{pod, mirrorPod} kl.podManager.SetPods(pods) - err := kl.syncPod(pod, mirrorPod, container.Pod{}, SyncPodUpdate) + err := kl.syncPod(pod, mirrorPod, container.Pod{}, kubetypes.SyncPodUpdate) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -2755,8 +2757,8 @@ func TestDeleteOrphanedMirrorPods(t *testing.T) { Name: "pod1", Namespace: "ns", Annotations: map[string]string{ - ConfigSourceAnnotationKey: "api", - ConfigMirrorAnnotationKey: "mirror", + kubetypes.ConfigSourceAnnotationKey: "api", + kubetypes.ConfigMirrorAnnotationKey: "mirror", }, }, }, @@ -2766,8 +2768,8 @@ func TestDeleteOrphanedMirrorPods(t *testing.T) { Name: "pod2", Namespace: "ns", Annotations: map[string]string{ - ConfigSourceAnnotationKey: "api", - ConfigMirrorAnnotationKey: "mirror", + kubetypes.ConfigSourceAnnotationKey: "api", + kubetypes.ConfigMirrorAnnotationKey: "mirror", }, }, }, @@ -2798,7 +2800,7 @@ func TestGetContainerInfoForMirrorPods(t *testing.T) { Name: "qux", Namespace: "ns", Annotations: map[string]string{ - ConfigSourceAnnotationKey: "file", + kubetypes.ConfigSourceAnnotationKey: "file", }, }, Spec: api.PodSpec{ @@ -2813,8 +2815,8 @@ func TestGetContainerInfoForMirrorPods(t *testing.T) { Name: "qux", Namespace: "ns", Annotations: map[string]string{ - ConfigSourceAnnotationKey: "api", - ConfigMirrorAnnotationKey: "mirror", + kubetypes.ConfigSourceAnnotationKey: "api", + kubetypes.ConfigMirrorAnnotationKey: "mirror", }, }, Spec: api.PodSpec{ @@ -2848,7 +2850,7 @@ func TestGetContainerInfoForMirrorPods(t *testing.T) { Containers: []*kubecontainer.Container{ { Name: "foo", - ID: types.UID(containerID), + ID: kubecontainer.ContainerID{"test", containerID}, }, }, }, @@ -2880,7 +2882,7 @@ func TestDoNotCacheStatusForStaticPods(t *testing.T) { Name: "staticFoo", Namespace: "new", Annotations: map[string]string{ - ConfigSourceAnnotationKey: "file", + kubetypes.ConfigSourceAnnotationKey: "file", }, }, Spec: api.PodSpec{ @@ -2905,7 +2907,7 @@ func TestHostNetworkAllowed(t *testing.T) { capabilities.SetForTests(capabilities.Capabilities{ PrivilegedSources: capabilities.PrivilegedSources{ - HostNetworkSources: []string{ApiserverSource, FileSource}, + HostNetworkSources: []string{kubetypes.ApiserverSource, kubetypes.FileSource}, }, }) pod := &api.Pod{ @@ -2914,18 +2916,20 @@ func TestHostNetworkAllowed(t *testing.T) { Name: "foo", Namespace: "new", Annotations: map[string]string{ - ConfigSourceAnnotationKey: FileSource, + kubetypes.ConfigSourceAnnotationKey: kubetypes.FileSource, }, }, Spec: api.PodSpec{ Containers: []api.Container{ {Name: "foo"}, }, - HostNetwork: true, + SecurityContext: &api.PodSecurityContext{ + HostNetwork: true, + }, }, } kubelet.podManager.SetPods([]*api.Pod{pod}) - err := kubelet.syncPod(pod, nil, container.Pod{}, SyncPodUpdate) + err := kubelet.syncPod(pod, nil, container.Pod{}, kubetypes.SyncPodUpdate) if err != nil { t.Errorf("expected pod infra creation to succeed: %v", err) } @@ -2946,17 +2950,19 @@ func TestHostNetworkDisallowed(t *testing.T) { Name: "foo", Namespace: "new", Annotations: map[string]string{ - ConfigSourceAnnotationKey: FileSource, + kubetypes.ConfigSourceAnnotationKey: kubetypes.FileSource, }, }, Spec: api.PodSpec{ Containers: []api.Container{ {Name: "foo"}, }, - HostNetwork: true, + SecurityContext: &api.PodSecurityContext{ + HostNetwork: true, + }, }, } - err := kubelet.syncPod(pod, nil, container.Pod{}, SyncPodUpdate) + err := kubelet.syncPod(pod, nil, container.Pod{}, kubetypes.SyncPodUpdate) if err == nil { t.Errorf("expected pod infra creation to fail") } @@ -2983,7 +2989,7 @@ func TestPrivilegeContainerAllowed(t *testing.T) { }, } kubelet.podManager.SetPods([]*api.Pod{pod}) - err := kubelet.syncPod(pod, nil, container.Pod{}, SyncPodUpdate) + err := kubelet.syncPod(pod, nil, container.Pod{}, kubetypes.SyncPodUpdate) if err != nil { t.Errorf("expected pod infra creation to succeed: %v", err) } @@ -3009,7 +3015,7 @@ func TestPrivilegeContainerDisallowed(t *testing.T) { }, }, } - err := kubelet.syncPod(pod, nil, container.Pod{}, SyncPodUpdate) + err := kubelet.syncPod(pod, nil, container.Pod{}, kubetypes.SyncPodUpdate) if err == nil { t.Errorf("expected pod infra creation to fail") } @@ -3039,7 +3045,7 @@ func TestRegisterExistingNodeWithApiserver(t *testing.T) { kubeClient.AddReactor("create", "nodes", func(action testclient.Action) (bool, runtime.Object, error) { // Return an error on create. return true, &api.Node{}, &apierrors.StatusError{ - ErrStatus: api.Status{Reason: api.StatusReasonAlreadyExists}, + ErrStatus: unversioned.Status{Reason: unversioned.StatusReasonAlreadyExists}, } }) kubeClient.AddReactor("get", "nodes", func(action testclient.Action) (bool, runtime.Object, error) { @@ -3074,7 +3080,7 @@ func TestRegisterExistingNodeWithApiserver(t *testing.T) { done <- struct{}{} }() select { - case <-time.After(5 * time.Second): + case <-time.After(util.ForeverTestTimeout): t.Errorf("timed out waiting for registration") case <-done: return @@ -3162,8 +3168,8 @@ func TestIsPodPastActiveDeadline(t *testing.T) { exceededActiveDeadlineSeconds := int64(30) notYetActiveDeadlineSeconds := int64(120) - now := util.Now() - startTime := util.NewTime(now.Time.Add(-1 * time.Minute)) + now := unversioned.Now() + startTime := unversioned.NewTime(now.Time.Add(-1 * time.Minute)) pods[0].Status.StartTime = &startTime pods[0].Spec.ActiveDeadlineSeconds = &exceededActiveDeadlineSeconds pods[1].Status.StartTime = &startTime @@ -3188,8 +3194,8 @@ func TestSyncPodsSetStatusToFailedForPodsThatRunTooLong(t *testing.T) { testKubelet.fakeCadvisor.On("MachineInfo").Return(&cadvisorApi.MachineInfo{}, nil) kubelet := testKubelet.kubelet - now := util.Now() - startTime := util.NewTime(now.Time.Add(-1 * time.Minute)) + now := unversioned.Now() + startTime := unversioned.NewTime(now.Time.Add(-1 * time.Minute)) exceededActiveDeadlineSeconds := int64(30) pods := []*api.Pod{ @@ -3239,8 +3245,8 @@ func TestSyncPodsDoesNotSetPodsThatDidNotRunTooLongToFailed(t *testing.T) { testKubelet.fakeCadvisor.On("MachineInfo").Return(&cadvisorApi.MachineInfo{}, nil) kubelet := testKubelet.kubelet - now := util.Now() - startTime := util.NewTime(now.Time.Add(-1 * time.Minute)) + now := unversioned.Now() + startTime := unversioned.NewTime(now.Time.Add(-1 * time.Minute)) exceededActiveDeadlineSeconds := int64(300) pods := []*api.Pod{ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go index b8bcae6adb97..39f675c6ef79 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go @@ -24,12 +24,12 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - kubeletTypes "k8s.io/kubernetes/pkg/kubelet/types" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/util" ) type HandlerRunner struct { - httpGetter kubeletTypes.HttpGetter + httpGetter kubetypes.HttpGetter commandRunner kubecontainer.ContainerCommandRunner containerManager podStatusProvider } @@ -38,7 +38,7 @@ type podStatusProvider interface { GetPodStatus(pod *api.Pod) (*api.PodStatus, error) } -func NewHandlerRunner(httpGetter kubeletTypes.HttpGetter, commandRunner kubecontainer.ContainerCommandRunner, containerManager podStatusProvider) kubecontainer.HandlerRunner { +func NewHandlerRunner(httpGetter kubetypes.HttpGetter, commandRunner kubecontainer.ContainerCommandRunner, containerManager podStatusProvider) kubecontainer.HandlerRunner { return &HandlerRunner{ httpGetter: httpGetter, commandRunner: commandRunner, @@ -46,8 +46,7 @@ func NewHandlerRunner(httpGetter kubeletTypes.HttpGetter, commandRunner kubecont } } -// TODO(yifan): Use a strong type for containerID. -func (hr *HandlerRunner) Run(containerID string, pod *api.Pod, container *api.Container, handler *api.Handler) error { +func (hr *HandlerRunner) Run(containerID kubecontainer.ContainerID, pod *api.Pod, container *api.Container, handler *api.Handler) error { switch { case handler.Exec != nil: _, err := hr.commandRunner.RunInContainer(containerID, handler.Exec.Command) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers_test.go index 12c3fa2984af..3efe9e9898d4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers_test.go @@ -74,16 +74,16 @@ func TestResolvePortStringUnknown(t *testing.T) { type fakeContainerCommandRunner struct { Cmd []string - ID string + ID kubecontainer.ContainerID } -func (f *fakeContainerCommandRunner) RunInContainer(id string, cmd []string) ([]byte, error) { +func (f *fakeContainerCommandRunner) RunInContainer(id kubecontainer.ContainerID, cmd []string) ([]byte, error) { f.Cmd = cmd f.ID = id return []byte{}, nil } -func (f *fakeContainerCommandRunner) ExecInContainer(id string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool) error { +func (f *fakeContainerCommandRunner) ExecInContainer(id kubecontainer.ContainerID, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool) error { return nil } @@ -95,7 +95,7 @@ func TestRunHandlerExec(t *testing.T) { fakeCommandRunner := fakeContainerCommandRunner{} handlerRunner := NewHandlerRunner(&fakeHTTP{}, &fakeCommandRunner, nil) - containerID := "abc1234" + containerID := kubecontainer.ContainerID{"test", "abc1234"} containerName := "containerFoo" container := api.Container{ @@ -137,7 +137,7 @@ func TestRunHandlerHttp(t *testing.T) { fakeHttp := fakeHTTP{} handlerRunner := NewHandlerRunner(&fakeHttp, &fakeContainerCommandRunner{}, nil) - containerID := "abc1234" + containerID := kubecontainer.ContainerID{"test", "abc1234"} containerName := "containerFoo" container := api.Container{ @@ -168,7 +168,7 @@ func TestRunHandlerHttp(t *testing.T) { func TestRunHandlerNil(t *testing.T) { handlerRunner := NewHandlerRunner(&fakeHTTP{}, &fakeContainerCommandRunner{}, nil) - containerID := "abc1234" + containerID := kubecontainer.ContainerID{"test", "abc1234"} podName := "podFoo" podNamespace := "nsFoo" containerName := "containerFoo" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/cni/cni.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/cni/cni.go new file mode 100644 index 000000000000..5c2287fc721e --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/cni/cni.go @@ -0,0 +1,206 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 cni + +import ( + "fmt" + "net" + "sort" + "strings" + + "github.com/appc/cni/libcni" + cniTypes "github.com/appc/cni/pkg/types" + "github.com/golang/glog" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/dockertools" + "k8s.io/kubernetes/pkg/kubelet/network" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" +) + +const ( + CNIPluginName = "cni" + DefaultNetDir = "/etc/cni/net.d" + DefaultCNIDir = "/opt/cni/bin" + DefaultInterfaceName = "eth0" + VendorCNIDirTemplate = "%s/opt/%s/bin" +) + +type cniNetworkPlugin struct { + defaultNetwork *cniNetwork + host network.Host +} + +type cniNetwork struct { + name string + NetworkConfig *libcni.NetworkConfig + CNIConfig *libcni.CNIConfig +} + +func probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, vendorCNIDirPrefix string) []network.NetworkPlugin { + configList := make([]network.NetworkPlugin, 0) + network, err := getDefaultCNINetwork(pluginDir, vendorCNIDirPrefix) + if err != nil { + return configList + } + return append(configList, &cniNetworkPlugin{defaultNetwork: network}) +} + +func ProbeNetworkPlugins(pluginDir string) []network.NetworkPlugin { + return probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, "") +} + +func getDefaultCNINetwork(pluginDir, vendorCNIDirPrefix string) (*cniNetwork, error) { + if pluginDir == "" { + pluginDir = DefaultNetDir + } + files, err := libcni.ConfFiles(pluginDir) + switch { + case err != nil: + return nil, err + case len(files) == 0: + return nil, fmt.Errorf("No networks found in %s", pluginDir) + } + + sort.Strings(files) + for _, confFile := range files { + conf, err := libcni.ConfFromFile(confFile) + if err != nil { + glog.Warningf("Error loading CNI config file %s: %v", confFile, err) + continue + } + // Search for vendor-specific plugins as well as default plugins in the CNI codebase. + vendorCNIDir := fmt.Sprintf(VendorCNIDirTemplate, vendorCNIDirPrefix, conf.Network.Type) + cninet := &libcni.CNIConfig{ + Path: []string{DefaultCNIDir, vendorCNIDir}, + } + network := &cniNetwork{name: conf.Network.Name, NetworkConfig: conf, CNIConfig: cninet} + return network, nil + } + return nil, fmt.Errorf("No valid networks found in %s", pluginDir) +} + +func (plugin *cniNetworkPlugin) Init(host network.Host) error { + plugin.host = host + return nil +} + +func (plugin *cniNetworkPlugin) Name() string { + return CNIPluginName +} + +func (plugin *cniNetworkPlugin) SetUpPod(namespace string, name string, id kubetypes.DockerID) error { + runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) + if !ok { + return fmt.Errorf("CNI execution called on non-docker runtime") + } + netns, err := runtime.GetNetNs(id.ContainerID()) + if err != nil { + return err + } + + _, err = plugin.defaultNetwork.addToNetwork(name, namespace, id.ContainerID(), netns) + if err != nil { + glog.Errorf("Error while adding to cni network: %s", err) + return err + } + + return err +} + +func (plugin *cniNetworkPlugin) TearDownPod(namespace string, name string, id kubetypes.DockerID) error { + runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) + if !ok { + return fmt.Errorf("CNI execution called on non-docker runtime") + } + netns, err := runtime.GetNetNs(id.ContainerID()) + if err != nil { + return err + } + + return plugin.defaultNetwork.deleteFromNetwork(name, namespace, id.ContainerID(), netns) +} + +// TODO: Use the addToNetwork function to obtain the IP of the Pod. That will assume idempotent ADD call to the plugin. +// Also fix the runtime's call to Status function to be done only in the case that the IP is lost, no need to do periodic calls +func (plugin *cniNetworkPlugin) Status(namespace string, name string, id kubetypes.DockerID) (*network.PodNetworkStatus, error) { + runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) + if !ok { + return nil, fmt.Errorf("CNI execution called on non-docker runtime") + } + ipStr, err := runtime.GetContainerIP(string(id), DefaultInterfaceName) + if err != nil { + return nil, err + } + ip, _, err := net.ParseCIDR(strings.Trim(ipStr, "\n")) + if err != nil { + return nil, err + } + return &network.PodNetworkStatus{IP: ip}, nil +} + +func (network *cniNetwork) addToNetwork(podName string, podNamespace string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) (*cniTypes.Result, error) { + rt, err := buildCNIRuntimeConf(podName, podNamespace, podInfraContainerID, podNetnsPath) + if err != nil { + glog.Errorf("Error adding network: %v", err) + return nil, err + } + + netconf, cninet := network.NetworkConfig, network.CNIConfig + glog.V(4).Infof("About to run with conf.Network.Type=%v, c.Path=%v", netconf.Network.Type, cninet.Path) + res, err := cninet.AddNetwork(netconf, rt) + if err != nil { + glog.Errorf("Error adding network: %v", err) + return nil, err + } + + return res, nil +} + +func (network *cniNetwork) deleteFromNetwork(podName string, podNamespace string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) error { + rt, err := buildCNIRuntimeConf(podName, podNamespace, podInfraContainerID, podNetnsPath) + if err != nil { + glog.Errorf("Error deleting network: %v", err) + return err + } + + netconf, cninet := network.NetworkConfig, network.CNIConfig + glog.V(4).Infof("About to run with conf.Network.Type=%v, c.Path=%v", netconf.Network.Type, cninet.Path) + err = cninet.DelNetwork(netconf, rt) + if err != nil { + glog.Errorf("Error deleting network: %v", err) + return err + } + return nil +} + +func buildCNIRuntimeConf(podName string, podNs string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) (*libcni.RuntimeConf, error) { + glog.V(4).Infof("Got netns path %v", podNetnsPath) + glog.V(4).Infof("Using netns path %v", podNs) + + rt := &libcni.RuntimeConf{ + ContainerID: podInfraContainerID.ID, + NetNS: podNetnsPath, + IfName: DefaultInterfaceName, + Args: [][2]string{ + {"K8S_POD_NAMESPACE", podNs}, + {"K8S_POD_NAME", podName}, + {"K8S_POD_INFRA_CONTAINER_ID", podInfraContainerID.ID}, + }, + } + + return rt, nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/cni/cni_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/cni/cni_test.go new file mode 100644 index 000000000000..bfc743f1fbad --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/cni/cni_test.go @@ -0,0 +1,197 @@ +// +build linux + +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 cni + +import ( + "bytes" + "fmt" + "io/ioutil" + "math/rand" + "os" + "path" + "testing" + "text/template" + + docker "github.com/fsouza/go-dockerclient" + cadvisorApi "github.com/google/cadvisor/info/v1" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/record" + client "k8s.io/kubernetes/pkg/client/unversioned" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/dockertools" + "k8s.io/kubernetes/pkg/kubelet/network" + "k8s.io/kubernetes/pkg/kubelet/prober" + "k8s.io/kubernetes/pkg/util/sets" +) + +// The temp dir where test plugins will be stored. +const testNetworkConfigPath = "/tmp/fake/plugins/net/cni" +const testVendorCNIDirPrefix = "/tmp" + +func installPluginUnderTest(t *testing.T, vendorName string, plugName string) { + pluginDir := path.Join(testNetworkConfigPath, plugName) + err := os.MkdirAll(pluginDir, 0777) + if err != nil { + t.Fatalf("Failed to create plugin config dir: %v", err) + } + pluginConfig := path.Join(pluginDir, plugName+".conf") + f, err := os.Create(pluginConfig) + if err != nil { + t.Fatalf("Failed to install plugin") + } + networkConfig := fmt.Sprintf("{ \"name\": \"%s\", \"type\": \"%s\" }", plugName, vendorName) + + _, err = f.WriteString(networkConfig) + if err != nil { + t.Fatalf("Failed to write network config file (%v)", err) + } + f.Close() + + vendorCNIDir := fmt.Sprintf(VendorCNIDirTemplate, testVendorCNIDirPrefix, vendorName) + err = os.MkdirAll(vendorCNIDir, 0777) + if err != nil { + t.Fatalf("Failed to create plugin dir: %v", err) + } + pluginExec := path.Join(vendorCNIDir, vendorName) + f, err = os.Create(pluginExec) + + const execScriptTempl = `#!/bin/bash +read ignore +export $(echo ${CNI_ARGS} | sed 's/;/ /g') &> /dev/null +mkdir -p {{.OutputDir}} &> /dev/null +echo -n "$CNI_COMMAND $CNI_NETNS $K8S_POD_NAMESPACE $K8S_POD_NAME $K8S_POD_INFRA_CONTAINER_ID" >& {{.OutputFile}} +echo -n "{ \"ip4\": { \"ip\": \"10.1.0.23/24\" } }" +` + execTemplateData := &map[string]interface{}{ + "OutputFile": path.Join(pluginDir, plugName+".out"), + "OutputDir": pluginDir, + } + + tObj := template.Must(template.New("test").Parse(execScriptTempl)) + buf := &bytes.Buffer{} + if err := tObj.Execute(buf, *execTemplateData); err != nil { + t.Fatalf("Error in executing script template - %v", err) + } + execScript := buf.String() + _, err = f.WriteString(execScript) + if err != nil { + t.Fatalf("Failed to write plugin exec - %v", err) + } + + err = f.Chmod(0777) + if err != nil { + t.Fatalf("Failed to set exec perms on plugin") + } + + f.Close() +} + +func tearDownPlugin(plugName string, vendorName string) { + err := os.RemoveAll(testNetworkConfigPath) + if err != nil { + fmt.Printf("Error in cleaning up test: %v", err) + } + vendorCNIDir := fmt.Sprintf(VendorCNIDirTemplate, testVendorCNIDirPrefix, vendorName) + err = os.RemoveAll(vendorCNIDir) + if err != nil { + fmt.Printf("Error in cleaning up test: %v", err) + } +} + +type fakeNetworkHost struct { + kubeClient client.Interface +} + +func NewFakeHost(kubeClient client.Interface) *fakeNetworkHost { + host := &fakeNetworkHost{kubeClient: kubeClient} + return host +} + +func (fnh *fakeNetworkHost) GetPodByName(name, namespace string) (*api.Pod, bool) { + return nil, false +} + +func (fnh *fakeNetworkHost) GetKubeClient() client.Interface { + return nil +} + +func (nh *fakeNetworkHost) GetRuntime() kubecontainer.Runtime { + dm, fakeDockerClient := newTestDockerManager() + fakeDockerClient.Container = &docker.Container{ + ID: "foobar", + State: docker.State{Pid: 12345}, + } + return dm +} + +func newTestDockerManager() (*dockertools.DockerManager, *dockertools.FakeDockerClient) { + fakeDocker := &dockertools.FakeDockerClient{VersionInfo: docker.Env{"Version=1.1.3", "ApiVersion=1.15"}, Errors: make(map[string]error), RemovedImages: sets.String{}} + fakeRecorder := &record.FakeRecorder{} + containerRefManager := kubecontainer.NewRefManager() + networkPlugin, _ := network.InitNetworkPlugin([]network.NetworkPlugin{}, "", network.NewFakeHost(nil)) + dockerManager := dockertools.NewFakeDockerManager( + fakeDocker, + fakeRecorder, + prober.FakeProber{}, + containerRefManager, + &cadvisorApi.MachineInfo{}, + dockertools.PodInfraContainerImage, + 0, 0, "", + kubecontainer.FakeOS{}, + networkPlugin, + nil, + nil, + nil) + + return dockerManager, fakeDocker +} + +func TestCNIPlugin(t *testing.T) { + // install some random plugin + pluginName := fmt.Sprintf("test%d", rand.Intn(1000)) + vendorName := fmt.Sprintf("test_vendor%d", rand.Intn(1000)) + defer tearDownPlugin(pluginName, vendorName) + installPluginUnderTest(t, vendorName, pluginName) + + np := probeNetworkPluginsWithVendorCNIDirPrefix(path.Join(testNetworkConfigPath, pluginName), testVendorCNIDirPrefix) + plug, err := network.InitNetworkPlugin(np, "cni", NewFakeHost(nil)) + if err != nil { + t.Fatalf("Failed to select the desired plugin: %v", err) + } + + err = plug.SetUpPod("podNamespace", "podName", "dockerid2345") + if err != nil { + t.Errorf("Expected nil: %v", err) + } + output, err := ioutil.ReadFile(path.Join(testNetworkConfigPath, pluginName, pluginName+".out")) + expectedOutput := "ADD /proc/12345/ns/net podNamespace podName dockerid2345" + if string(output) != expectedOutput { + t.Errorf("Mismatch in expected output for setup hook. Expected '%s', got '%s'", expectedOutput, string(output)) + } + err = plug.TearDownPod("podNamespace", "podName", "dockerid4545454") + if err != nil { + t.Errorf("Expected nil: %v", err) + } + output, err = ioutil.ReadFile(path.Join(testNetworkConfigPath, pluginName, pluginName+".out")) + expectedOutput = "DEL /proc/12345/ns/net podNamespace podName dockerid4545454" + if string(output) != expectedOutput { + t.Errorf("Mismatch in expected output for setup hook. Expected '%s', got '%s'", expectedOutput, string(output)) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/exec/exec.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/exec/exec.go index 516e1904d926..a29388d70ed8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/exec/exec.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/exec/exec.go @@ -65,9 +65,9 @@ import ( "strings" "github.com/golang/glog" - "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/kubelet/network" - kubeletTypes "k8s.io/kubernetes/pkg/kubelet/types" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" utilexec "k8s.io/kubernetes/pkg/util/exec" ) @@ -132,19 +132,19 @@ func (plugin *execNetworkPlugin) validate() error { return nil } -func (plugin *execNetworkPlugin) SetUpPod(namespace string, name string, id kubeletTypes.DockerID) error { +func (plugin *execNetworkPlugin) SetUpPod(namespace string, name string, id kubetypes.DockerID) error { out, err := utilexec.New().Command(plugin.getExecutable(), setUpCmd, namespace, name, string(id)).CombinedOutput() glog.V(5).Infof("SetUpPod 'exec' network plugin output: %s, %v", string(out), err) return err } -func (plugin *execNetworkPlugin) TearDownPod(namespace string, name string, id kubeletTypes.DockerID) error { +func (plugin *execNetworkPlugin) TearDownPod(namespace string, name string, id kubetypes.DockerID) error { out, err := utilexec.New().Command(plugin.getExecutable(), tearDownCmd, namespace, name, string(id)).CombinedOutput() glog.V(5).Infof("TearDownPod 'exec' network plugin output: %s, %v", string(out), err) return err } -func (plugin *execNetworkPlugin) Status(namespace string, name string, id kubeletTypes.DockerID) (*network.PodNetworkStatus, error) { +func (plugin *execNetworkPlugin) Status(namespace string, name string, id kubetypes.DockerID) (*network.PodNetworkStatus, error) { out, err := utilexec.New().Command(plugin.getExecutable(), statusCmd, namespace, name, string(id)).CombinedOutput() glog.V(5).Infof("Status 'exec' network plugin output: %s, %v", string(out), err) if err != nil { @@ -154,7 +154,7 @@ func (plugin *execNetworkPlugin) Status(namespace string, name string, id kubele return nil, nil } findVersion := struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` }{} err = json.Unmarshal(out, &findVersion) if err != nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/exec/exec_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/exec/exec_test.go index a95ec54f2ed2..6ae690915fdc 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/exec/exec_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/exec/exec_test.go @@ -25,16 +25,44 @@ import ( "math/rand" "os" "path" + "sync" "testing" "text/template" "k8s.io/kubernetes/pkg/kubelet/network" + "k8s.io/kubernetes/pkg/util/sets" ) -// The temp dir where test plugins will be stored. -const testPluginPath = "/tmp/fake/plugins/net" +func tmpDirOrDie() string { + dir, err := ioutil.TempDir(os.TempDir(), "exec-test") + if err != nil { + panic(fmt.Sprintf("error creating tmp dir: %v", err)) + } + return path.Join(dir, "fake", "plugins", "net") +} + +var lock sync.Mutex +var namesInUse = sets.NewString() + +func selectName() string { + lock.Lock() + defer lock.Unlock() + for { + pluginName := fmt.Sprintf("test%d", rand.Intn(1000)) + if !namesInUse.Has(pluginName) { + namesInUse.Insert(pluginName) + return pluginName + } + } +} -func installPluginUnderTest(t *testing.T, vendorName string, plugName string, execTemplateData *map[string]interface{}) { +func releaseName(name string) { + lock.Lock() + defer lock.Unlock() + namesInUse.Delete(name) +} + +func installPluginUnderTest(t *testing.T, vendorName, testPluginPath, plugName string, execTemplateData *map[string]interface{}) { vendoredName := plugName if vendorName != "" { vendoredName = fmt.Sprintf("%s~%s", vendorName, plugName) @@ -85,7 +113,7 @@ echo -n $@ &> {{.OutputFile}} f.Close() } -func tearDownPlugin(plugName string) { +func tearDownPlugin(testPluginPath string) { err := os.RemoveAll(testPluginPath) if err != nil { fmt.Printf("Error in cleaning up test: %v", err) @@ -93,10 +121,15 @@ func tearDownPlugin(plugName string) { } func TestSelectPlugin(t *testing.T) { + // The temp dir where test plugins will be stored. + testPluginPath := tmpDirOrDie() + // install some random plugin under testPluginPath - pluginName := fmt.Sprintf("test%d", rand.Intn(1000)) - defer tearDownPlugin(pluginName) - installPluginUnderTest(t, "", pluginName, nil) + pluginName := selectName() + defer tearDownPlugin(testPluginPath) + defer releaseName(pluginName) + + installPluginUnderTest(t, "", testPluginPath, pluginName, nil) plug, err := network.InitNetworkPlugin(ProbeNetworkPlugins(testPluginPath), pluginName, network.NewFakeHost(nil)) if err != nil { @@ -108,11 +141,16 @@ func TestSelectPlugin(t *testing.T) { } func TestSelectVendoredPlugin(t *testing.T) { + // The temp dir where test plugins will be stored. + testPluginPath := tmpDirOrDie() + // install some random plugin under testPluginPath - pluginName := fmt.Sprintf("test%d", rand.Intn(1000)) - defer tearDownPlugin(pluginName) + pluginName := selectName() + defer tearDownPlugin(testPluginPath) + defer releaseName(pluginName) + vendor := "mycompany" - installPluginUnderTest(t, vendor, pluginName, nil) + installPluginUnderTest(t, vendor, testPluginPath, pluginName, nil) vendoredPluginName := fmt.Sprintf("%s/%s", vendor, pluginName) plug, err := network.InitNetworkPlugin(ProbeNetworkPlugins(testPluginPath), vendoredPluginName, network.NewFakeHost(nil)) @@ -125,10 +163,15 @@ func TestSelectVendoredPlugin(t *testing.T) { } func TestSelectWrongPlugin(t *testing.T) { + // The temp dir where test plugins will be stored. + testPluginPath := tmpDirOrDie() + // install some random plugin under testPluginPath - pluginName := fmt.Sprintf("test%d", rand.Intn(1000)) - defer tearDownPlugin(pluginName) - installPluginUnderTest(t, "", pluginName, nil) + pluginName := selectName() + defer tearDownPlugin(testPluginPath) + defer releaseName(pluginName) + + installPluginUnderTest(t, "", testPluginPath, pluginName, nil) wrongPlugin := "abcd" plug, err := network.InitNetworkPlugin(ProbeNetworkPlugins(testPluginPath), wrongPlugin, network.NewFakeHost(nil)) @@ -138,9 +181,15 @@ func TestSelectWrongPlugin(t *testing.T) { } func TestPluginValidation(t *testing.T) { - pluginName := fmt.Sprintf("test%d", rand.Intn(1000)) - defer tearDownPlugin(pluginName) - installPluginUnderTest(t, "", pluginName, nil) + // The temp dir where test plugins will be stored. + testPluginPath := tmpDirOrDie() + + // install some random plugin under testPluginPath + pluginName := selectName() + defer tearDownPlugin(testPluginPath) + defer releaseName(pluginName) + + installPluginUnderTest(t, "", testPluginPath, pluginName, nil) // modify the perms of the pluginExecutable f, err := os.Open(path.Join(testPluginPath, pluginName, pluginName)) @@ -161,9 +210,15 @@ func TestPluginValidation(t *testing.T) { } func TestPluginSetupHook(t *testing.T) { - pluginName := fmt.Sprintf("test%d", rand.Intn(1000)) - defer tearDownPlugin(pluginName) - installPluginUnderTest(t, "", pluginName, nil) + // The temp dir where test plugins will be stored. + testPluginPath := tmpDirOrDie() + + // install some random plugin under testPluginPath + pluginName := selectName() + defer tearDownPlugin(testPluginPath) + defer releaseName(pluginName) + + installPluginUnderTest(t, "", testPluginPath, pluginName, nil) plug, err := network.InitNetworkPlugin(ProbeNetworkPlugins(testPluginPath), pluginName, network.NewFakeHost(nil)) @@ -183,9 +238,15 @@ func TestPluginSetupHook(t *testing.T) { } func TestPluginTearDownHook(t *testing.T) { - pluginName := fmt.Sprintf("test%d", rand.Intn(1000)) - defer tearDownPlugin(pluginName) - installPluginUnderTest(t, "", pluginName, nil) + // The temp dir where test plugins will be stored. + testPluginPath := tmpDirOrDie() + + // install some random plugin under testPluginPath + pluginName := selectName() + defer tearDownPlugin(testPluginPath) + defer releaseName(pluginName) + + installPluginUnderTest(t, "", testPluginPath, pluginName, nil) plug, err := network.InitNetworkPlugin(ProbeNetworkPlugins(testPluginPath), pluginName, network.NewFakeHost(nil)) @@ -205,9 +266,15 @@ func TestPluginTearDownHook(t *testing.T) { } func TestPluginStatusHook(t *testing.T) { - pluginName := fmt.Sprintf("test%d", rand.Intn(1000)) - defer tearDownPlugin(pluginName) - installPluginUnderTest(t, "", pluginName, nil) + // The temp dir where test plugins will be stored. + testPluginPath := tmpDirOrDie() + + // install some random plugin under testPluginPath + pluginName := selectName() + defer tearDownPlugin(testPluginPath) + defer releaseName(pluginName) + + installPluginUnderTest(t, "", testPluginPath, pluginName, nil) plug, err := network.InitNetworkPlugin(ProbeNetworkPlugins(testPluginPath), pluginName, network.NewFakeHost(nil)) @@ -230,14 +297,20 @@ func TestPluginStatusHook(t *testing.T) { } func TestPluginStatusHookIPv6(t *testing.T) { - pluginName := fmt.Sprintf("test%d", rand.Intn(1000)) - defer tearDownPlugin(pluginName) + // The temp dir where test plugins will be stored. + testPluginPath := tmpDirOrDie() + + // install some random plugin under testPluginPath + pluginName := selectName() + defer tearDownPlugin(testPluginPath) + defer releaseName(pluginName) + pluginDir := path.Join(testPluginPath, pluginName) execTemplate := &map[string]interface{}{ "IPAddress": "fe80::e2cb:4eff:fef9:6710", "OutputFile": path.Join(pluginDir, pluginName+".out"), } - installPluginUnderTest(t, "", pluginName, execTemplate) + installPluginUnderTest(t, "", testPluginPath, pluginName, execTemplate) plug, err := network.InitNetworkPlugin(ProbeNetworkPlugins(testPluginPath), pluginName, network.NewFakeHost(nil)) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/plugins.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/plugins.go index ac46d4c9fe1b..e928f31ebd63 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/plugins.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/plugins.go @@ -23,10 +23,12 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" - kubeletTypes "k8s.io/kubernetes/pkg/kubelet/types" - "k8s.io/kubernetes/pkg/util" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/util/errors" + "k8s.io/kubernetes/pkg/util/validation" ) const DefaultPluginName = "kubernetes.io/no-op" @@ -44,19 +46,19 @@ type NetworkPlugin interface { // SetUpPod is the method called after the infra container of // the pod has been created but before the other containers of the // pod are launched. - SetUpPod(namespace string, name string, podInfraContainerID kubeletTypes.DockerID) error + SetUpPod(namespace string, name string, podInfraContainerID kubetypes.DockerID) error // TearDownPod is the method called before a pod's infra container will be deleted - TearDownPod(namespace string, name string, podInfraContainerID kubeletTypes.DockerID) error + TearDownPod(namespace string, name string, podInfraContainerID kubetypes.DockerID) error // Status is the method called to obtain the ipv4 or ipv6 addresses of the container - Status(namespace string, name string, podInfraContainerID kubeletTypes.DockerID) (*PodNetworkStatus, error) + Status(namespace string, name string, podInfraContainerID kubetypes.DockerID) (*PodNetworkStatus, error) } // PodNetworkStatus stores the network status of a pod (currently just the primary IP address) // This struct represents version "v1" type PodNetworkStatus struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // IP is the primary ipv4/ipv6 address of the pod. Among other things it is the address that - // - kube expects to be reachable across the cluster @@ -72,6 +74,9 @@ type Host interface { // GetKubeClient returns a client interface GetKubeClient() client.Interface + + // GetContainerRuntime returns the container runtime that implements the containers (e.g. docker/rkt) + GetRuntime() kubecontainer.Runtime } // InitNetworkPlugin inits the plugin that matches networkPluginName. Plugins must have unique names. @@ -87,7 +92,7 @@ func InitNetworkPlugin(plugins []NetworkPlugin, networkPluginName string, host H allErrs := []error{} for _, plugin := range plugins { name := plugin.Name() - if !util.IsQualifiedName(name) { + if !validation.IsQualifiedName(name) { allErrs = append(allErrs, fmt.Errorf("network plugin has invalid name: %#v", plugin)) continue } @@ -129,14 +134,14 @@ func (plugin *noopNetworkPlugin) Name() string { return DefaultPluginName } -func (plugin *noopNetworkPlugin) SetUpPod(namespace string, name string, id kubeletTypes.DockerID) error { +func (plugin *noopNetworkPlugin) SetUpPod(namespace string, name string, id kubetypes.DockerID) error { return nil } -func (plugin *noopNetworkPlugin) TearDownPod(namespace string, name string, id kubeletTypes.DockerID) error { +func (plugin *noopNetworkPlugin) TearDownPod(namespace string, name string, id kubetypes.DockerID) error { return nil } -func (plugin *noopNetworkPlugin) Status(namespace string, name string, id kubeletTypes.DockerID) (*PodNetworkStatus, error) { +func (plugin *noopNetworkPlugin) Status(namespace string, name string, id kubetypes.DockerID) (*PodNetworkStatus, error) { return nil, nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/testing.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/testing.go index 969fc7f6e76a..6b82534e38b9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/testing.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/network/testing.go @@ -22,6 +22,7 @@ package network import ( "k8s.io/kubernetes/pkg/api" client "k8s.io/kubernetes/pkg/client/unversioned" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" ) type fakeNetworkHost struct { @@ -40,3 +41,7 @@ func (fnh *fakeNetworkHost) GetPodByName(name, namespace string) (*api.Pod, bool func (fnh *fakeNetworkHost) GetKubeClient() client.Interface { return nil } + +func (nh *fakeNetworkHost) GetRuntime() kubecontainer.Runtime { + return &kubecontainer.FakeRuntime{} +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/networks.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/networks.go index a88a9f125cb0..5ec7a00fe7d8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/networks.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/networks.go @@ -19,6 +19,7 @@ package kubelet import ( "k8s.io/kubernetes/pkg/api" client "k8s.io/kubernetes/pkg/client/unversioned" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" ) // This just exports required functions from kubelet proper, for use by network @@ -34,3 +35,7 @@ func (nh *networkHost) GetPodByName(name, namespace string) (*api.Pod, bool) { func (nh *networkHost) GetKubeClient() client.Interface { return nh.kubelet.kubeClient } + +func (nh *networkHost) GetRuntime() kubecontainer.Runtime { + return nh.kubelet.GetRuntime() +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/oom_watcher.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/oom_watcher.go index d3aea9827d0b..3d4409436a7e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/oom_watcher.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/oom_watcher.go @@ -21,6 +21,7 @@ import ( "github.com/google/cadvisor/events" cadvisorApi "github.com/google/cadvisor/info/v1" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/record" "k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/util" @@ -63,7 +64,7 @@ func (ow *realOOMWatcher) Start(ref *api.ObjectReference) error { for event := range eventChannel.GetChannel() { glog.V(2).Infof("Got sys oom event from cadvisor: %v", event) - ow.recorder.PastEventf(ref, util.Time{Time: event.Timestamp}, systemOOMEvent, "System OOM encountered") + ow.recorder.PastEventf(ref, unversioned.Time{Time: event.Timestamp}, systemOOMEvent, "System OOM encountered") } glog.Errorf("Unexpectedly stopped receiving OOM notifications from cAdvisor") }() diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/oom_watcher_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/oom_watcher_test.go index fbb8d7b608ba..fc18cd6da00b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/oom_watcher_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/oom_watcher_test.go @@ -21,14 +21,14 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" ) type fakeEvent struct { object runtime.Object - timestamp util.Time + timestamp unversioned.Time reason string message string } @@ -38,14 +38,14 @@ type fakeRecorder struct { } func (f fakeRecorder) Event(object runtime.Object, reason, message string) { - f.events = append(f.events, fakeEvent{object, util.Now(), reason, message}) + f.events = append(f.events, fakeEvent{object, unversioned.Now(), reason, message}) } func (f fakeRecorder) Eventf(object runtime.Object, reason, messageFmt string, args ...interface{}) { - f.events = append(f.events, fakeEvent{object, util.Now(), reason, fmt.Sprintf(messageFmt, args...)}) + f.events = append(f.events, fakeEvent{object, unversioned.Now(), reason, fmt.Sprintf(messageFmt, args...)}) } -func (f fakeRecorder) PastEventf(object runtime.Object, timestamp util.Time, reason, messageFmt string, args ...interface{}) { +func (f fakeRecorder) PastEventf(object runtime.Object, timestamp unversioned.Time, reason, messageFmt string, args ...interface{}) { f.events = append(f.events, fakeEvent{object, timestamp, reason, fmt.Sprintf(messageFmt, args...)}) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/mirror_client_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/fake_mirror_client.go similarity index 55% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/mirror_client_test.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/fake_mirror_client.go index 9c372d5b33d4..5198f08a8b99 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/mirror_client_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/fake_mirror_client.go @@ -14,18 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kubelet +package pod import ( "sync" - "testing" "k8s.io/kubernetes/pkg/api" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/util/sets" ) -type fakeMirrorClient struct { +type FakeMirrorClient struct { mirrorPodLock sync.RWMutex // Note that a real mirror manager does not store the mirror pods in // itself. This fake manager does this to track calls. @@ -34,7 +33,15 @@ type fakeMirrorClient struct { deleteCounts map[string]int } -func (fmc *fakeMirrorClient) CreateMirrorPod(pod *api.Pod) error { +func NewFakeMirrorClient() *FakeMirrorClient { + m := FakeMirrorClient{} + m.mirrorPods = sets.NewString() + m.createCounts = make(map[string]int) + m.deleteCounts = make(map[string]int) + return &m +} + +func (fmc *FakeMirrorClient) CreateMirrorPod(pod *api.Pod) error { fmc.mirrorPodLock.Lock() defer fmc.mirrorPodLock.Unlock() podFullName := kubecontainer.GetPodFullName(pod) @@ -43,7 +50,7 @@ func (fmc *fakeMirrorClient) CreateMirrorPod(pod *api.Pod) error { return nil } -func (fmc *fakeMirrorClient) DeleteMirrorPod(podFullName string) error { +func (fmc *FakeMirrorClient) DeleteMirrorPod(podFullName string) error { fmc.mirrorPodLock.Lock() defer fmc.mirrorPodLock.Unlock() fmc.mirrorPods.Delete(podFullName) @@ -51,65 +58,26 @@ func (fmc *fakeMirrorClient) DeleteMirrorPod(podFullName string) error { return nil } -func newFakeMirrorClient() *fakeMirrorClient { - m := fakeMirrorClient{} - m.mirrorPods = sets.NewString() - m.createCounts = make(map[string]int) - m.deleteCounts = make(map[string]int) - return &m -} - -func (fmc *fakeMirrorClient) HasPod(podFullName string) bool { +func (fmc *FakeMirrorClient) HasPod(podFullName string) bool { fmc.mirrorPodLock.RLock() defer fmc.mirrorPodLock.RUnlock() return fmc.mirrorPods.Has(podFullName) } -func (fmc *fakeMirrorClient) NumOfPods() int { +func (fmc *FakeMirrorClient) NumOfPods() int { fmc.mirrorPodLock.RLock() defer fmc.mirrorPodLock.RUnlock() return fmc.mirrorPods.Len() } -func (fmc *fakeMirrorClient) GetPods() []string { +func (fmc *FakeMirrorClient) GetPods() []string { fmc.mirrorPodLock.RLock() defer fmc.mirrorPodLock.RUnlock() return fmc.mirrorPods.List() } -func (fmc *fakeMirrorClient) GetCounts(podFullName string) (int, int) { +func (fmc *FakeMirrorClient) GetCounts(podFullName string) (int, int) { fmc.mirrorPodLock.RLock() defer fmc.mirrorPodLock.RUnlock() return fmc.createCounts[podFullName], fmc.deleteCounts[podFullName] } - -func TestParsePodFullName(t *testing.T) { - type nameTuple struct { - Name string - Namespace string - } - successfulCases := map[string]nameTuple{ - "bar_foo": {Name: "bar", Namespace: "foo"}, - "bar.org_foo.com": {Name: "bar.org", Namespace: "foo.com"}, - "bar-bar_foo": {Name: "bar-bar", Namespace: "foo"}, - } - failedCases := []string{"barfoo", "bar_foo_foo", ""} - - for podFullName, expected := range successfulCases { - name, namespace, err := kubecontainer.ParsePodFullName(podFullName) - if err != nil { - t.Errorf("unexpected error when parsing the full name: %v", err) - continue - } - if name != expected.Name || namespace != expected.Namespace { - t.Errorf("expected name %q, namespace %q; got name %q, namespace %q", - expected.Name, expected.Namespace, name, namespace) - } - } - for _, podFullName := range failedCases { - _, _, err := kubecontainer.ParsePodFullName(podFullName) - if err == nil { - t.Errorf("expected error when parsing the full name, got none") - } - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_manager.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/manager.go similarity index 77% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_manager.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/manager.go index 1ea358accd15..8a6d9360aa5a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_manager.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/manager.go @@ -14,13 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kubelet +package pod import ( "sync" "k8s.io/kubernetes/pkg/api" - client "k8s.io/kubernetes/pkg/client/unversioned" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/types" ) @@ -40,7 +39,7 @@ import ( // When a static pod gets deleted, the associated orphaned mirror pod will // also be removed. -type podManager interface { +type Manager interface { GetPods() []*api.Pod GetPodByFullName(podFullName string) (*api.Pod, bool) GetPodByName(namespace, name string) (*api.Pod, bool) @@ -60,35 +59,13 @@ type podManager interface { DeleteOrphanedMirrorPods() TranslatePodUID(uid types.UID) types.UID IsMirrorPodOf(mirrorPod, pod *api.Pod) bool - mirrorClient + MirrorClient } -// SyncPodType classifies pod updates, eg: create, update. -type SyncPodType int - -const ( - SyncPodSync SyncPodType = iota - SyncPodUpdate - SyncPodCreate -) - -func (sp SyncPodType) String() string { - switch sp { - case SyncPodCreate: - return "create" - case SyncPodUpdate: - return "update" - case SyncPodSync: - return "sync" - default: - return "unknown" - } -} - -// All maps in basicPodManager should be set by calling UpdatePods(); +// All maps in basicManager should be set by calling UpdatePods(); // individual arrays/maps are not immutable and no other methods should attempt // to modify them. -type basicPodManager struct { +type basicManager struct { // Protects all internal maps. lock sync.RWMutex @@ -102,24 +79,24 @@ type basicPodManager struct { mirrorPodByFullName map[string]*api.Pod // A mirror pod client to create/delete mirror pods. - mirrorClient + MirrorClient } -func newBasicPodManager(apiserverClient client.Interface) *basicPodManager { - pm := &basicPodManager{} - pm.mirrorClient = newBasicMirrorClient(apiserverClient) +func NewBasicPodManager(client MirrorClient) Manager { + pm := &basicManager{} + pm.MirrorClient = client pm.SetPods(nil) return pm } // Set the internal pods based on the new pods. -func (pm *basicPodManager) SetPods(newPods []*api.Pod) { +func (pm *basicManager) SetPods(newPods []*api.Pod) { pm.lock.Lock() defer pm.lock.Unlock() pm.setPods(newPods) } -func (pm *basicPodManager) setPods(newPods []*api.Pod) { +func (pm *basicManager) setPods(newPods []*api.Pod) { podByUID := make(map[types.UID]*api.Pod) mirrorPodByUID := make(map[types.UID]*api.Pod) podByFullName := make(map[string]*api.Pod) @@ -127,7 +104,7 @@ func (pm *basicPodManager) setPods(newPods []*api.Pod) { for _, pod := range newPods { podFullName := kubecontainer.GetPodFullName(pod) - if isMirrorPod(pod) { + if IsMirrorPod(pod) { mirrorPodByUID[pod.UID] = pod mirrorPodByFullName[podFullName] = pod } else { @@ -142,15 +119,15 @@ func (pm *basicPodManager) setPods(newPods []*api.Pod) { pm.mirrorPodByFullName = mirrorPodByFullName } -func (pm *basicPodManager) AddPod(pod *api.Pod) { +func (pm *basicManager) AddPod(pod *api.Pod) { pm.UpdatePod(pod) } -func (pm *basicPodManager) UpdatePod(pod *api.Pod) { +func (pm *basicManager) UpdatePod(pod *api.Pod) { pm.lock.Lock() defer pm.lock.Unlock() podFullName := kubecontainer.GetPodFullName(pod) - if isMirrorPod(pod) { + if IsMirrorPod(pod) { pm.mirrorPodByUID[pod.UID] = pod pm.mirrorPodByFullName[podFullName] = pod } else { @@ -159,11 +136,11 @@ func (pm *basicPodManager) UpdatePod(pod *api.Pod) { } } -func (pm *basicPodManager) DeletePod(pod *api.Pod) { +func (pm *basicManager) DeletePod(pod *api.Pod) { pm.lock.Lock() defer pm.lock.Unlock() podFullName := kubecontainer.GetPodFullName(pod) - if isMirrorPod(pod) { + if IsMirrorPod(pod) { delete(pm.mirrorPodByUID, pod.UID) delete(pm.mirrorPodByFullName, podFullName) } else { @@ -173,14 +150,14 @@ func (pm *basicPodManager) DeletePod(pod *api.Pod) { } // GetPods returns the regular pods bound to the kubelet and their spec. -func (pm *basicPodManager) GetPods() []*api.Pod { +func (pm *basicManager) GetPods() []*api.Pod { pm.lock.RLock() defer pm.lock.RUnlock() return podsMapToPods(pm.podByUID) } // GetPodsAndMirrorPods returns the both regular and mirror pods. -func (pm *basicPodManager) GetPodsAndMirrorPods() ([]*api.Pod, []*api.Pod) { +func (pm *basicManager) GetPodsAndMirrorPods() ([]*api.Pod, []*api.Pod) { pm.lock.RLock() defer pm.lock.RUnlock() pods := podsMapToPods(pm.podByUID) @@ -189,20 +166,20 @@ func (pm *basicPodManager) GetPodsAndMirrorPods() ([]*api.Pod, []*api.Pod) { } // Returns all pods (including mirror pods). -func (pm *basicPodManager) getAllPods() []*api.Pod { +func (pm *basicManager) getAllPods() []*api.Pod { return append(podsMapToPods(pm.podByUID), podsMapToPods(pm.mirrorPodByUID)...) } // GetPodByName provides the (non-mirror) pod that matches namespace and name, // as well as whether the pod was found. -func (pm *basicPodManager) GetPodByName(namespace, name string) (*api.Pod, bool) { +func (pm *basicManager) GetPodByName(namespace, name string) (*api.Pod, bool) { podFullName := kubecontainer.BuildPodFullName(name, namespace) return pm.GetPodByFullName(podFullName) } // GetPodByName returns the (non-mirror) pod that matches full name, as well as // whether the pod was found. -func (pm *basicPodManager) GetPodByFullName(podFullName string) (*api.Pod, bool) { +func (pm *basicManager) GetPodByFullName(podFullName string) (*api.Pod, bool) { pm.lock.RLock() defer pm.lock.RUnlock() pod, ok := pm.podByFullName[podFullName] @@ -213,7 +190,7 @@ func (pm *basicPodManager) GetPodByFullName(podFullName string) (*api.Pod, bool) // Otherwise, return the original UID. All public-facing functions should // perform this translation for UIDs because user may provide a mirror pod UID, // which is not recognized by internal Kubelet functions. -func (pm *basicPodManager) TranslatePodUID(uid types.UID) types.UID { +func (pm *basicManager) TranslatePodUID(uid types.UID) types.UID { if uid == "" { return uid } @@ -229,7 +206,7 @@ func (pm *basicPodManager) TranslatePodUID(uid types.UID) types.UID { return uid } -func (pm *basicPodManager) getOrphanedMirrorPodNames() []string { +func (pm *basicManager) getOrphanedMirrorPodNames() []string { pm.lock.RLock() defer pm.lock.RUnlock() var podFullNames []string @@ -243,16 +220,16 @@ func (pm *basicPodManager) getOrphanedMirrorPodNames() []string { // Delete all mirror pods which do not have associated static pods. This method // sends deletion requets to the API server, but does NOT modify the internal -// pod storage in basicPodManager. -func (pm *basicPodManager) DeleteOrphanedMirrorPods() { +// pod storage in basicManager. +func (pm *basicManager) DeleteOrphanedMirrorPods() { podFullNames := pm.getOrphanedMirrorPodNames() for _, podFullName := range podFullNames { - pm.mirrorClient.DeleteMirrorPod(podFullName) + pm.MirrorClient.DeleteMirrorPod(podFullName) } } // Returns true if mirrorPod is a correct representation of pod; false otherwise. -func (pm *basicPodManager) IsMirrorPodOf(mirrorPod, pod *api.Pod) bool { +func (pm *basicManager) IsMirrorPodOf(mirrorPod, pod *api.Pod) bool { // Check name and namespace first. if pod.Name != mirrorPod.Name || pod.Namespace != mirrorPod.Namespace { return false @@ -268,14 +245,14 @@ func podsMapToPods(UIDMap map[types.UID]*api.Pod) []*api.Pod { return pods } -func (pm *basicPodManager) GetMirrorPodByPod(pod *api.Pod) (*api.Pod, bool) { +func (pm *basicManager) GetMirrorPodByPod(pod *api.Pod) (*api.Pod, bool) { pm.lock.RLock() defer pm.lock.RUnlock() mirrorPod, ok := pm.mirrorPodByFullName[kubecontainer.GetPodFullName(pod)] return mirrorPod, ok } -func (pm *basicPodManager) GetPodByMirrorPod(mirrorPod *api.Pod) (*api.Pod, bool) { +func (pm *basicManager) GetPodByMirrorPod(mirrorPod *api.Pod) (*api.Pod, bool) { pm.lock.RLock() defer pm.lock.RUnlock() pod, ok := pm.podByFullName[kubecontainer.GetPodFullName(mirrorPod)] diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_manager_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/manager_test.go similarity index 83% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_manager_test.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/manager_test.go index b658330d7edd..1dee50fef443 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_manager_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/manager_test.go @@ -14,21 +14,21 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kubelet +package pod import ( "reflect" "testing" "k8s.io/kubernetes/pkg/api" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) // Stub out mirror client for testing purpose. -func newFakePodManager() (*basicPodManager, *fakeMirrorClient) { - podManager := newBasicPodManager(nil) - fakeMirrorClient := newFakeMirrorClient() - podManager.mirrorClient = fakeMirrorClient - return podManager, fakeMirrorClient +func newTestManager() (*basicManager, *FakeMirrorClient) { + fakeMirrorClient := NewFakeMirrorClient() + manager := NewBasicPodManager(fakeMirrorClient).(*basicManager) + return manager, fakeMirrorClient } // Tests that pods/maps are properly set after the pod update, and the basic @@ -40,8 +40,8 @@ func TestGetSetPods(t *testing.T) { Name: "bar", Namespace: "default", Annotations: map[string]string{ - ConfigSourceAnnotationKey: "api", - ConfigMirrorAnnotationKey: "mirror", + kubetypes.ConfigSourceAnnotationKey: "api", + kubetypes.ConfigMirrorAnnotationKey: "mirror", }, }, } @@ -50,7 +50,7 @@ func TestGetSetPods(t *testing.T) { UID: "123456789", Name: "bar", Namespace: "default", - Annotations: map[string]string{ConfigSourceAnnotationKey: "file"}, + Annotations: map[string]string{kubetypes.ConfigSourceAnnotationKey: "file"}, }, } @@ -60,13 +60,13 @@ func TestGetSetPods(t *testing.T) { UID: "999999999", Name: "taco", Namespace: "default", - Annotations: map[string]string{ConfigSourceAnnotationKey: "api"}, + Annotations: map[string]string{kubetypes.ConfigSourceAnnotationKey: "api"}, }, }, staticPod, } updates := append(expectedPods, mirrorPod) - podManager, _ := newFakePodManager() + podManager, _ := newTestManager() podManager.SetPods(updates) // Tests that all regular pods are recorded corrrectly. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/mirror_client.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/mirror_client.go similarity index 70% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/mirror_client.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/mirror_client.go index e53cf51f63e6..00adcdf44b42 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/mirror_client.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/mirror_client.go @@ -14,20 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kubelet +package pod import ( - "fmt" - "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" client "k8s.io/kubernetes/pkg/client/unversioned" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) // Mirror client is used to create/delete a mirror pod. - -type mirrorClient interface { +type MirrorClient interface { CreateMirrorPod(*api.Pod) error DeleteMirrorPod(string) error } @@ -38,7 +36,7 @@ type basicMirrorClient struct { apiserverClient client.Interface } -func newBasicMirrorClient(apiserverClient client.Interface) *basicMirrorClient { +func NewBasicMirrorClient(apiserverClient client.Interface) MirrorClient { return &basicMirrorClient{apiserverClient: apiserverClient} } @@ -47,9 +45,16 @@ func (mc *basicMirrorClient) CreateMirrorPod(pod *api.Pod) error { if mc.apiserverClient == nil { return nil } - pod.Annotations[ConfigMirrorAnnotationKey] = MirrorType + // Make a copy of the pod. + copyPod := *pod + copyPod.Annotations = make(map[string]string) + + for k, v := range pod.Annotations { + copyPod.Annotations[k] = v + } + copyPod.Annotations[kubetypes.ConfigMirrorAnnotationKey] = kubetypes.MirrorType - _, err := mc.apiserverClient.Pods(pod.Namespace).Create(pod) + _, err := mc.apiserverClient.Pods(copyPod.Namespace).Create(©Pod) return err } @@ -70,25 +75,15 @@ func (mc *basicMirrorClient) DeleteMirrorPod(podFullName string) error { return nil } -// Helper functions. -func getPodSource(pod *api.Pod) (string, error) { - if pod.Annotations != nil { - if source, ok := pod.Annotations[ConfigSourceAnnotationKey]; ok { - return source, nil - } - } - return "", fmt.Errorf("cannot get source of pod %q", pod.UID) -} - -func isStaticPod(pod *api.Pod) bool { - source, err := getPodSource(pod) - return err == nil && source != ApiserverSource +func IsStaticPod(pod *api.Pod) bool { + source, err := kubetypes.GetPodSource(pod) + return err == nil && source != kubetypes.ApiserverSource } -func isMirrorPod(pod *api.Pod) bool { - if value, ok := pod.Annotations[ConfigMirrorAnnotationKey]; !ok { +func IsMirrorPod(pod *api.Pod) bool { + if value, ok := pod.Annotations[kubetypes.ConfigMirrorAnnotationKey]; !ok { return false } else { - return value == MirrorType + return value == kubetypes.MirrorType } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/mirror_client_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/mirror_client_test.go new file mode 100644 index 000000000000..d8baa05f805f --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod/mirror_client_test.go @@ -0,0 +1,54 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 pod + +import ( + "testing" + + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" +) + +func TestParsePodFullName(t *testing.T) { + type nameTuple struct { + Name string + Namespace string + } + successfulCases := map[string]nameTuple{ + "bar_foo": {Name: "bar", Namespace: "foo"}, + "bar.org_foo.com": {Name: "bar.org", Namespace: "foo.com"}, + "bar-bar_foo": {Name: "bar-bar", Namespace: "foo"}, + } + failedCases := []string{"barfoo", "bar_foo_foo", ""} + + for podFullName, expected := range successfulCases { + name, namespace, err := kubecontainer.ParsePodFullName(podFullName) + if err != nil { + t.Errorf("unexpected error when parsing the full name: %v", err) + continue + } + if name != expected.Name || namespace != expected.Namespace { + t.Errorf("expected name %q, namespace %q; got name %q, namespace %q", + expected.Name, expected.Namespace, name, namespace) + } + } + for _, podFullName := range failedCases { + _, _, err := kubecontainer.ParsePodFullName(podFullName) + if err == nil { + t.Errorf("expected error when parsing the full name, got none") + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_workers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_workers.go index 85cd333e2637..4ab840572dcf 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_workers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_workers.go @@ -24,18 +24,19 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/client/record" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" ) // PodWorkers is an abstract interface for testability. type PodWorkers interface { - UpdatePod(pod *api.Pod, mirrorPod *api.Pod, updateComplete func()) + UpdatePod(pod *api.Pod, mirrorPod *api.Pod, updateType kubetypes.SyncPodType, updateComplete func()) ForgetNonExistingPodWorkers(desiredPods map[types.UID]empty) ForgetWorker(uid types.UID) } -type syncPodFnType func(*api.Pod, *api.Pod, kubecontainer.Pod, SyncPodType) error +type syncPodFnType func(*api.Pod, *api.Pod, kubecontainer.Pod, kubetypes.SyncPodType) error type podWorkers struct { // Protects all per worker fields. @@ -74,7 +75,7 @@ type workUpdate struct { updateCompleteFn func() // A string describing the type of this update, eg: create - updateType SyncPodType + updateType kubetypes.SyncPodType } func newPodWorkers(runtimeCache kubecontainer.RuntimeCache, syncPodFn syncPodFnType, @@ -121,19 +122,11 @@ func (p *podWorkers) managePodLoop(podUpdates <-chan workUpdate) { } // Apply the new setting to the specified pod. updateComplete is called when the update is completed. -func (p *podWorkers) UpdatePod(pod *api.Pod, mirrorPod *api.Pod, updateComplete func()) { +func (p *podWorkers) UpdatePod(pod *api.Pod, mirrorPod *api.Pod, updateType kubetypes.SyncPodType, updateComplete func()) { uid := pod.UID var podUpdates chan workUpdate var exists bool - // TODO: Pipe this through from the kubelet. Currently kubelets operating with - // snapshot updates (PodConfigNotificationSnapshot) will send updates, creates - // and deletes as SET operations, which makes updates indistinguishable from - // creates. The intent here is to communicate to the pod worker that it can take - // certain liberties, like skipping status generation, when it receives a create - // event for a pod. - updateType := SyncPodUpdate - p.podLock.Lock() defer p.podLock.Unlock() if podUpdates, exists = p.podUpdates[uid]; !exists { @@ -148,7 +141,6 @@ func (p *podWorkers) UpdatePod(pod *api.Pod, mirrorPod *api.Pod, updateComplete // kubelet just restarted. In either case the kubelet is willing to believe // the status of the pod for the first pod worker sync. See corresponding // comment in syncPod. - updateType = SyncPodCreate go func() { defer util.HandleCrash() p.managePodLoop(podUpdates) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_workers_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_workers_test.go index aa0561bd5b49..8b7803d4cdd5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_workers_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/pod_workers_test.go @@ -30,6 +30,7 @@ import ( kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/network" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/types" ) @@ -45,7 +46,7 @@ func newPod(uid, name string) *api.Pod { func createFakeRuntimeCache(fakeRecorder *record.FakeRecorder) kubecontainer.RuntimeCache { fakeDocker := &dockertools.FakeDockerClient{} np, _ := network.InitNetworkPlugin([]network.NetworkPlugin{}, "", network.NewFakeHost(nil)) - dockerManager := dockertools.NewFakeDockerManager(fakeDocker, fakeRecorder, nil, nil, &cadvisorApi.MachineInfo{}, dockertools.PodInfraContainerImage, 0, 0, "", kubecontainer.FakeOS{}, np, nil, nil) + dockerManager := dockertools.NewFakeDockerManager(fakeDocker, fakeRecorder, nil, nil, &cadvisorApi.MachineInfo{}, dockertools.PodInfraContainerImage, 0, 0, "", kubecontainer.FakeOS{}, np, nil, nil, nil) return kubecontainer.NewFakeRuntimeCache(dockerManager) } @@ -56,7 +57,7 @@ func createPodWorkers() (*podWorkers, map[types.UID][]string) { fakeRuntimeCache := createFakeRuntimeCache(fakeRecorder) podWorkers := newPodWorkers( fakeRuntimeCache, - func(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecontainer.Pod, updateType SyncPodType) error { + func(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecontainer.Pod, updateType kubetypes.SyncPodType) error { func() { lock.Lock() defer lock.Unlock() @@ -93,7 +94,7 @@ func TestUpdatePod(t *testing.T) { numPods := 20 for i := 0; i < numPods; i++ { for j := i; j < numPods; j++ { - podWorkers.UpdatePod(newPod(string(j), string(i)), nil, func() {}) + podWorkers.UpdatePod(newPod(string(j), string(i)), nil, kubetypes.SyncPodCreate, func() {}) } } drainWorkers(podWorkers, numPods) @@ -121,44 +122,12 @@ func TestUpdatePod(t *testing.T) { } } -func TestUpdateType(t *testing.T) { - syncType := make(chan SyncPodType) - fakeRecorder := &record.FakeRecorder{} - podWorkers := newPodWorkers( - createFakeRuntimeCache(fakeRecorder), - func(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecontainer.Pod, updateType SyncPodType) error { - func() { - syncType <- updateType - }() - return nil - }, - fakeRecorder, - ) - cases := map[*api.Pod][]SyncPodType{ - newPod("u1", "n1"): {SyncPodCreate, SyncPodUpdate}, - newPod("u2", "n1"): {SyncPodCreate}, - } - for p, expectedTypes := range cases { - for i := range expectedTypes { - podWorkers.UpdatePod(p, nil, func() {}) - select { - case gotType := <-syncType: - if gotType != expectedTypes[i] { - t.Fatalf("Expected sync type %v got %v for pod with uid %v", expectedTypes[i], gotType, p.UID) - } - case <-time.After(100 * time.Millisecond): - t.Errorf("Unexpected delay is running pod worker") - } - } - } -} - func TestForgetNonExistingPodWorkers(t *testing.T) { podWorkers, _ := createPodWorkers() numPods := 20 for i := 0; i < numPods; i++ { - podWorkers.UpdatePod(newPod(string(i), "name"), nil, func() {}) + podWorkers.UpdatePod(newPod(string(i), "name"), nil, kubetypes.SyncPodUpdate, func() {}) } drainWorkers(podWorkers, numPods) @@ -194,12 +163,12 @@ type simpleFakeKubelet struct { wg sync.WaitGroup } -func (kl *simpleFakeKubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecontainer.Pod, updateType SyncPodType) error { +func (kl *simpleFakeKubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecontainer.Pod, updateType kubetypes.SyncPodType) error { kl.pod, kl.mirrorPod, kl.runningPod = pod, mirrorPod, runningPod return nil } -func (kl *simpleFakeKubelet) syncPodWithWaitGroup(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecontainer.Pod, updateType SyncPodType) error { +func (kl *simpleFakeKubelet) syncPodWithWaitGroup(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecontainer.Pod, updateType kubetypes.SyncPodType) error { kl.pod, kl.mirrorPod, kl.runningPod = pod, mirrorPod, runningPod kl.wg.Done() return nil @@ -225,7 +194,7 @@ func TestFakePodWorkers(t *testing.T) { fakeDocker := &dockertools.FakeDockerClient{} fakeRecorder := &record.FakeRecorder{} np, _ := network.InitNetworkPlugin([]network.NetworkPlugin{}, "", network.NewFakeHost(nil)) - dockerManager := dockertools.NewFakeDockerManager(fakeDocker, fakeRecorder, nil, nil, &cadvisorApi.MachineInfo{}, dockertools.PodInfraContainerImage, 0, 0, "", kubecontainer.FakeOS{}, np, nil, nil) + dockerManager := dockertools.NewFakeDockerManager(fakeDocker, fakeRecorder, nil, nil, &cadvisorApi.MachineInfo{}, dockertools.PodInfraContainerImage, 0, 0, "", kubecontainer.FakeOS{}, np, nil, nil, nil) fakeRuntimeCache := kubecontainer.NewFakeRuntimeCache(dockerManager) kubeletForRealWorkers := &simpleFakeKubelet{} @@ -385,8 +354,8 @@ func TestFakePodWorkers(t *testing.T) { kubeletForRealWorkers.wg.Add(1) fakeDocker.ContainerList = tt.containerList - realPodWorkers.UpdatePod(tt.pod, tt.mirrorPod, func() {}) - fakePodWorkers.UpdatePod(tt.pod, tt.mirrorPod, func() {}) + realPodWorkers.UpdatePod(tt.pod, tt.mirrorPod, kubetypes.SyncPodUpdate, func() {}) + fakePodWorkers.UpdatePod(tt.pod, tt.mirrorPod, kubetypes.SyncPodUpdate, func() {}) kubeletForRealWorkers.wg.Wait() diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/fake_manager.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/fake_manager.go new file mode 100644 index 000000000000..65742823cb2c --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/fake_manager.go @@ -0,0 +1,37 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 prober + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/types" +) + +type FakeManager struct{} + +var _ Manager = FakeManager{} + +// Unused methods. +func (_ FakeManager) AddPod(_ *api.Pod) {} +func (_ FakeManager) RemovePod(_ *api.Pod) {} +func (_ FakeManager) CleanupPods(_ []*api.Pod) {} + +func (_ FakeManager) UpdatePodStatus(_ types.UID, podStatus *api.PodStatus) { + for i := range podStatus.ContainerStatuses { + podStatus.ContainerStatuses[i].Ready = true + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/fake_prober.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/fake_prober.go new file mode 100644 index 000000000000..fd18dbd05d09 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/fake_prober.go @@ -0,0 +1,45 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 prober + +import ( + "k8s.io/kubernetes/pkg/api" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/probe" +) + +var _ Prober = FakeProber{} + +type FakeProber struct { + Readiness probe.Result + Liveness probe.Result + Error error +} + +func (f FakeProber) ProbeLiveness(_ *api.Pod, _ api.PodStatus, c api.Container, _ kubecontainer.ContainerID, _ int64) (probe.Result, error) { + if c.LivenessProbe == nil { + return probe.Success, nil + } + return f.Liveness, f.Error +} + +func (f FakeProber) ProbeReadiness(_ *api.Pod, _ api.PodStatus, c api.Container, _ kubecontainer.ContainerID) (probe.Result, error) { + if c.ReadinessProbe == nil { + return probe.Success, nil + } + return f.Readiness, f.Error +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/manager.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/manager.go new file mode 100644 index 000000000000..a39089a3f5da --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/manager.go @@ -0,0 +1,169 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 prober + +import ( + "sync" + "time" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/prober/results" + "k8s.io/kubernetes/pkg/kubelet/status" + "k8s.io/kubernetes/pkg/types" + "k8s.io/kubernetes/pkg/util/sets" +) + +// Manager manages pod probing. It creates a probe "worker" for every container that specifies a +// probe (AddPod). The worker periodically probes its assigned container and caches the results. The +// manager usse the cached probe results to set the appropriate Ready state in the PodStatus when +// requested (UpdatePodStatus). Updating probe parameters is not currently supported. +// TODO: Move liveness probing out of the runtime, to here. +type Manager interface { + // AddPod creates new probe workers for every container probe. This should be called for every + // pod created. + AddPod(pod *api.Pod) + + // RemovePod handles cleaning up the removed pod state, including terminating probe workers and + // deleting cached results. + RemovePod(pod *api.Pod) + + // CleanupPods handles cleaning up pods which should no longer be running. + // It takes a list of "active pods" which should not be cleaned up. + CleanupPods(activePods []*api.Pod) + + // UpdatePodStatus modifies the given PodStatus with the appropriate Ready state for each + // container based on container running status, cached probe results and worker states. + UpdatePodStatus(types.UID, *api.PodStatus) +} + +type manager struct { + // Caches the results of readiness probes. + readinessCache results.Manager + + // Map of active workers for readiness + readinessProbes map[containerPath]*worker + // Lock for accessing & mutating readinessProbes + workerLock sync.RWMutex + + // The statusManager cache provides pod IP and container IDs for probing. + statusManager status.Manager + + // prober executes the probe actions. + prober Prober + + // Default period for workers to execute a probe. + defaultProbePeriod time.Duration +} + +func NewManager( + defaultProbePeriod time.Duration, + statusManager status.Manager, + prober Prober) Manager { + return &manager{ + defaultProbePeriod: defaultProbePeriod, + statusManager: statusManager, + prober: prober, + readinessCache: results.NewManager(), + readinessProbes: make(map[containerPath]*worker), + } +} + +// Key uniquely identifying containers +type containerPath struct { + podUID types.UID + containerName string +} + +func (m *manager) AddPod(pod *api.Pod) { + m.workerLock.Lock() + defer m.workerLock.Unlock() + + key := containerPath{podUID: pod.UID} + for _, c := range pod.Spec.Containers { + key.containerName = c.Name + if _, ok := m.readinessProbes[key]; ok { + glog.Errorf("Readiness probe already exists! %v - %v", + kubecontainer.GetPodFullName(pod), c.Name) + return + } + if c.ReadinessProbe != nil { + m.readinessProbes[key] = m.newWorker(pod, c) + } + } +} + +func (m *manager) RemovePod(pod *api.Pod) { + m.workerLock.RLock() + defer m.workerLock.RUnlock() + + key := containerPath{podUID: pod.UID} + for _, c := range pod.Spec.Containers { + key.containerName = c.Name + if worker, ok := m.readinessProbes[key]; ok { + close(worker.stop) + } + } +} + +func (m *manager) CleanupPods(activePods []*api.Pod) { + desiredPods := make(map[types.UID]sets.Empty) + for _, pod := range activePods { + desiredPods[pod.UID] = sets.Empty{} + } + + m.workerLock.RLock() + defer m.workerLock.RUnlock() + + for path, worker := range m.readinessProbes { + if _, ok := desiredPods[path.podUID]; !ok { + close(worker.stop) + } + } +} + +func (m *manager) UpdatePodStatus(podUID types.UID, podStatus *api.PodStatus) { + for i, c := range podStatus.ContainerStatuses { + var ready bool + if c.State.Running == nil { + ready = false + } else if result, ok := m.readinessCache.Get( + kubecontainer.ParseContainerID(c.ContainerID)); ok { + ready = result == results.Success + } else { + // The check whether there is a probe which hasn't run yet. + _, exists := m.getReadinessProbe(podUID, c.Name) + ready = !exists + } + podStatus.ContainerStatuses[i].Ready = ready + } +} + +func (m *manager) getReadinessProbe(podUID types.UID, containerName string) (*worker, bool) { + m.workerLock.RLock() + defer m.workerLock.RUnlock() + probe, ok := m.readinessProbes[containerPath{podUID, containerName}] + return probe, ok +} + +// Called by the worker after exiting. +func (m *manager) removeReadinessProbe(podUID types.UID, containerName string) { + m.workerLock.Lock() + defer m.workerLock.Unlock() + delete(m.readinessProbes, containerPath{podUID, containerName}) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/manager_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/manager_test.go new file mode 100644 index 000000000000..9caf1cc37d01 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/manager_test.go @@ -0,0 +1,283 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 prober + +import ( + "fmt" + "testing" + "time" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/unversioned/testclient" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/prober/results" + "k8s.io/kubernetes/pkg/kubelet/status" + "k8s.io/kubernetes/pkg/probe" + "k8s.io/kubernetes/pkg/util/wait" +) + +func TestAddRemovePods(t *testing.T) { + noProbePod := api.Pod{ + ObjectMeta: api.ObjectMeta{ + UID: "no_probe_pod", + }, + Spec: api.PodSpec{ + Containers: []api.Container{{ + Name: "no_probe1", + }, { + Name: "no_probe2", + }}, + }, + } + + probePod := api.Pod{ + ObjectMeta: api.ObjectMeta{ + UID: "probe_pod", + }, + Spec: api.PodSpec{ + Containers: []api.Container{{ + Name: "no_probe1", + }, { + Name: "prober1", + ReadinessProbe: &api.Probe{}, + }, { + Name: "no_probe2", + }, { + Name: "prober2", + ReadinessProbe: &api.Probe{}, + }}, + }, + } + + m := newTestManager() + if err := expectProbes(m, nil); err != nil { + t.Error(err) + } + + // Adding a pod with no probes should be a no-op. + m.AddPod(&noProbePod) + if err := expectProbes(m, nil); err != nil { + t.Error(err) + } + + // Adding a pod with probes. + m.AddPod(&probePod) + probePaths := []containerPath{{"probe_pod", "prober1"}, {"probe_pod", "prober2"}} + if err := expectProbes(m, probePaths); err != nil { + t.Error(err) + } + + // Removing un-probed pod. + m.RemovePod(&noProbePod) + if err := expectProbes(m, probePaths); err != nil { + t.Error(err) + } + + // Removing probed pod. + m.RemovePod(&probePod) + if err := waitForWorkerExit(m, probePaths); err != nil { + t.Fatal(err) + } + if err := expectProbes(m, nil); err != nil { + t.Error(err) + } + + // Removing already removed pods should be a no-op. + m.RemovePod(&probePod) + if err := expectProbes(m, nil); err != nil { + t.Error(err) + } +} + +func TestCleanupPods(t *testing.T) { + m := newTestManager() + podToCleanup := api.Pod{ + ObjectMeta: api.ObjectMeta{ + UID: "pod_cleanup", + }, + Spec: api.PodSpec{ + Containers: []api.Container{{ + Name: "prober1", + ReadinessProbe: &api.Probe{}, + }, { + Name: "prober2", + ReadinessProbe: &api.Probe{}, + }}, + }, + } + podToKeep := api.Pod{ + ObjectMeta: api.ObjectMeta{ + UID: "pod_keep", + }, + Spec: api.PodSpec{ + Containers: []api.Container{{ + Name: "prober1", + ReadinessProbe: &api.Probe{}, + }, { + Name: "prober2", + ReadinessProbe: &api.Probe{}, + }}, + }, + } + m.AddPod(&podToCleanup) + m.AddPod(&podToKeep) + + m.CleanupPods([]*api.Pod{&podToKeep}) + + removedProbes := []containerPath{{"pod_cleanup", "prober1"}, {"pod_cleanup", "prober2"}} + expectedProbes := []containerPath{{"pod_keep", "prober1"}, {"pod_keep", "prober2"}} + if err := waitForWorkerExit(m, removedProbes); err != nil { + t.Fatal(err) + } + if err := expectProbes(m, expectedProbes); err != nil { + t.Error(err) + } +} + +func TestUpdatePodStatus(t *testing.T) { + const podUID = "pod_uid" + unprobed := api.ContainerStatus{ + Name: "unprobed_container", + ContainerID: "test://unprobed_container_id", + State: api.ContainerState{ + Running: &api.ContainerStateRunning{}, + }, + } + probedReady := api.ContainerStatus{ + Name: "probed_container_ready", + ContainerID: "test://probed_container_ready_id", + State: api.ContainerState{ + Running: &api.ContainerStateRunning{}, + }, + } + probedPending := api.ContainerStatus{ + Name: "probed_container_pending", + ContainerID: "test://probed_container_pending_id", + State: api.ContainerState{ + Running: &api.ContainerStateRunning{}, + }, + } + probedUnready := api.ContainerStatus{ + Name: "probed_container_unready", + ContainerID: "test://probed_container_unready_id", + State: api.ContainerState{ + Running: &api.ContainerStateRunning{}, + }, + } + terminated := api.ContainerStatus{ + Name: "terminated_container", + ContainerID: "test://terminated_container_id", + State: api.ContainerState{ + Terminated: &api.ContainerStateTerminated{}, + }, + } + podStatus := api.PodStatus{ + Phase: api.PodRunning, + ContainerStatuses: []api.ContainerStatus{ + unprobed, probedReady, probedPending, probedUnready, terminated, + }, + } + + m := newTestManager() + // Setup probe "workers" and cached results. + m.readinessProbes = map[containerPath]*worker{ + containerPath{podUID, probedReady.Name}: {}, + containerPath{podUID, probedPending.Name}: {}, + containerPath{podUID, probedUnready.Name}: {}, + containerPath{podUID, terminated.Name}: {}, + } + + m.readinessCache.Set(kubecontainer.ParseContainerID(probedReady.ContainerID), results.Success) + m.readinessCache.Set(kubecontainer.ParseContainerID(probedUnready.ContainerID), results.Failure) + m.readinessCache.Set(kubecontainer.ParseContainerID(terminated.ContainerID), results.Success) + + m.UpdatePodStatus(podUID, &podStatus) + + expectedReadiness := map[containerPath]bool{ + containerPath{podUID, unprobed.Name}: true, + containerPath{podUID, probedReady.Name}: true, + containerPath{podUID, probedPending.Name}: false, + containerPath{podUID, probedUnready.Name}: false, + containerPath{podUID, terminated.Name}: false, + } + for _, c := range podStatus.ContainerStatuses { + expected, ok := expectedReadiness[containerPath{podUID, c.Name}] + if !ok { + t.Fatalf("Missing expectation for test case: %v", c.Name) + } + if expected != c.Ready { + t.Errorf("Unexpected readiness for container %v: Expected %v but got %v", + c.Name, expected, c.Ready) + } + } +} + +func expectProbes(m *manager, expectedReadinessProbes []containerPath) error { + m.workerLock.RLock() + defer m.workerLock.RUnlock() + + var unexpected []containerPath + missing := make([]containerPath, len(expectedReadinessProbes)) + copy(missing, expectedReadinessProbes) + +outer: + for probePath := range m.readinessProbes { + for i, expectedPath := range missing { + if probePath == expectedPath { + missing = append(missing[:i], missing[i+1:]...) + continue outer + } + } + unexpected = append(unexpected, probePath) + } + + if len(missing) == 0 && len(unexpected) == 0 { + return nil // Yay! + } + + return fmt.Errorf("Unexpected probes: %v; Missing probes: %v;", unexpected, missing) +} + +func newTestManager() *manager { + const probePeriod = 1 + statusManager := status.NewManager(&testclient.Fake{}) + prober := FakeProber{Readiness: probe.Success} + return NewManager(probePeriod, statusManager, prober).(*manager) +} + +// Wait for the given workers to exit & clean up. +func waitForWorkerExit(m *manager, workerPaths []containerPath) error { + const interval = 100 * time.Millisecond + const timeout = 30 * time.Second + + for _, w := range workerPaths { + condition := func() (bool, error) { + _, exists := m.getReadinessProbe(w.podUID, w.containerName) + return !exists, nil + } + if exited, _ := condition(); exited { + continue // Already exited, no need to poll. + } + glog.Infof("Polling %v", w) + if err := wait.Poll(interval, timeout, condition); err != nil { + return err + } + } + + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/prober.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/prober.go index 01f010095d92..befdcc18b0ee 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/prober.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/prober.go @@ -41,7 +41,8 @@ const maxProbeRetries = 3 // Prober checks the healthiness of a container. type Prober interface { - Probe(pod *api.Pod, status api.PodStatus, container api.Container, containerID string, createdAt int64) (probe.Result, error) + ProbeLiveness(pod *api.Pod, status api.PodStatus, container api.Container, containerID kubecontainer.ContainerID, createdAt int64) (probe.Result, error) + ProbeReadiness(pod *api.Pod, status api.PodStatus, container api.Container, containerID kubecontainer.ContainerID) (probe.Result, error) } // Prober helps to check the liveness/readiness of a container. @@ -51,55 +52,30 @@ type prober struct { tcp tcprobe.TCPProber runner kubecontainer.ContainerCommandRunner - readinessManager *kubecontainer.ReadinessManager - refManager *kubecontainer.RefManager - recorder record.EventRecorder + refManager *kubecontainer.RefManager + recorder record.EventRecorder } // NewProber creates a Prober, it takes a command runner and // several container info managers. func New( runner kubecontainer.ContainerCommandRunner, - readinessManager *kubecontainer.ReadinessManager, refManager *kubecontainer.RefManager, recorder record.EventRecorder) Prober { return &prober{ - exec: execprobe.New(), - http: httprobe.New(), - tcp: tcprobe.New(), - runner: runner, - - readinessManager: readinessManager, - refManager: refManager, - recorder: recorder, - } -} - -// New prober for use in tests. -func NewTestProber( - exec execprobe.ExecProber, - readinessManager *kubecontainer.ReadinessManager, - refManager *kubecontainer.RefManager, - recorder record.EventRecorder) Prober { - - return &prober{ - exec: exec, - readinessManager: readinessManager, - refManager: refManager, - recorder: recorder, + exec: execprobe.New(), + http: httprobe.New(), + tcp: tcprobe.New(), + runner: runner, + refManager: refManager, + recorder: recorder, } } -// Probe checks the liveness/readiness of the given container. -func (pb *prober) Probe(pod *api.Pod, status api.PodStatus, container api.Container, containerID string, createdAt int64) (probe.Result, error) { - pb.probeReadiness(pod, status, container, containerID, createdAt) - return pb.probeLiveness(pod, status, container, containerID, createdAt) -} - -// probeLiveness probes the liveness of a container. +// ProbeLiveness probes the liveness of a container. // If the initalDelay since container creation on liveness probe has not passed the probe will return probe.Success. -func (pb *prober) probeLiveness(pod *api.Pod, status api.PodStatus, container api.Container, containerID string, createdAt int64) (probe.Result, error) { +func (pb *prober) ProbeLiveness(pod *api.Pod, status api.PodStatus, container api.Container, containerID kubecontainer.ContainerID, createdAt int64) (probe.Result, error) { var live probe.Result var output string var err error @@ -137,24 +113,20 @@ func (pb *prober) probeLiveness(pod *api.Pod, status api.PodStatus, container ap return probe.Success, nil } -// probeReadiness probes and sets the readiness of a container. -// If the initial delay on the readiness probe has not passed, we set readiness to false. -func (pb *prober) probeReadiness(pod *api.Pod, status api.PodStatus, container api.Container, containerID string, createdAt int64) { +// ProbeReadiness probes and sets the readiness of a container. +func (pb *prober) ProbeReadiness(pod *api.Pod, status api.PodStatus, container api.Container, containerID kubecontainer.ContainerID) (probe.Result, error) { var ready probe.Result var output string var err error p := container.ReadinessProbe if p == nil { ready = probe.Success - } else if time.Now().Unix()-createdAt < p.InitialDelaySeconds { - ready = probe.Failure } else { ready, output, err = pb.runProbeWithRetries(p, pod, status, container, containerID, maxProbeRetries) } ctrName := fmt.Sprintf("%s:%s", kubecontainer.GetPodFullName(pod), container.Name) if err != nil || ready == probe.Failure { // Readiness failed in one way or another. - pb.readinessManager.SetReadiness(containerID, false) ref, ok := pb.refManager.GetRef(containerID) if !ok { glog.Warningf("No ref for pod '%v' - '%v'", containerID, container.Name) @@ -164,26 +136,22 @@ func (pb *prober) probeReadiness(pod *api.Pod, status api.PodStatus, container a if ok { pb.recorder.Eventf(ref, "Unhealthy", "Readiness probe errored: %v", err) } - return } else { // ready != probe.Success glog.V(1).Infof("Readiness probe for %q failed (%v): %s", ctrName, ready, output) if ok { pb.recorder.Eventf(ref, "Unhealthy", "Readiness probe failed: %s", output) } - return } - } - if ready == probe.Success { - pb.readinessManager.SetReadiness(containerID, true) + return probe.Failure, err } glog.V(3).Infof("Readiness probe for %q succeeded", ctrName) - + return ready, nil } // runProbeWithRetries tries to probe the container in a finite loop, it returns the last result // if it never succeeds. -func (pb *prober) runProbeWithRetries(p *api.Probe, pod *api.Pod, status api.PodStatus, container api.Container, containerID string, retries int) (probe.Result, string, error) { +func (pb *prober) runProbeWithRetries(p *api.Probe, pod *api.Pod, status api.PodStatus, container api.Container, containerID kubecontainer.ContainerID, retries int) (probe.Result, string, error) { var err error var result probe.Result var output string @@ -196,7 +164,7 @@ func (pb *prober) runProbeWithRetries(p *api.Probe, pod *api.Pod, status api.Pod return result, output, err } -func (pb *prober) runProbe(p *api.Probe, pod *api.Pod, status api.PodStatus, container api.Container, containerID string) (probe.Result, string, error) { +func (pb *prober) runProbe(p *api.Probe, pod *api.Pod, status api.PodStatus, container api.Container, containerID kubecontainer.ContainerID) (probe.Result, string, error) { timeout := time.Duration(p.TimeoutSeconds) * time.Second if p.Exec != nil { glog.V(4).Infof("Exec-Probe Pod: %v, Container: %v, Command: %v", pod, container, p.Exec.Command) @@ -274,7 +242,7 @@ type execInContainer struct { run func() ([]byte, error) } -func (p *prober) newExecInContainer(pod *api.Pod, container api.Container, containerID string, cmd []string) exec.Cmd { +func (p *prober) newExecInContainer(pod *api.Pod, container api.Container, containerID kubecontainer.ContainerID, cmd []string) exec.Cmd { return execInContainer{func() ([]byte, error) { return p.runner.RunInContainer(containerID, cmd) }} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/prober_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/prober_test.go index 1bfff74b4de7..ebf62c59ebf8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/prober_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/prober_test.go @@ -17,9 +17,13 @@ limitations under the License. package prober import ( + "errors" "testing" + "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/record" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/probe" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/exec" @@ -160,11 +164,275 @@ func TestGetTCPAddrParts(t *testing.T) { } } -type FakeExecProber struct { +// TestProbeContainer tests the functionality of probeContainer. +// Test cases are: +// +// No probe. +// Only LivenessProbe. +// Only ReadinessProbe. +// Both probes. +// +// Also, for each probe, there will be several cases covering whether the initial +// delay has passed, whether the probe handler will return Success, Failure, +// Unknown or error. +// +// PLEASE READ THE PROBE DOCS BEFORE CHANGING THIS TEST IF YOU ARE UNSURE HOW PROBES ARE SUPPOSED TO WORK: +// (See https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/user-guide/pod-states.md#pod-conditions) +func TestProbeContainer(t *testing.T) { + prober := &prober{ + refManager: kubecontainer.NewRefManager(), + recorder: &record.FakeRecorder{}, + } + containerID := kubecontainer.ContainerID{"test", "foobar"} + createdAt := time.Now().Unix() + + tests := []struct { + testContainer api.Container + expectError bool + expectedLiveness probe.Result + expectedReadiness probe.Result + }{ + // No probes. + { + testContainer: api.Container{}, + expectedLiveness: probe.Success, + expectedReadiness: probe.Success, + }, + // Only LivenessProbe. expectedReadiness should always be true here. + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{InitialDelaySeconds: 100}, + }, + expectedLiveness: probe.Success, + expectedReadiness: probe.Success, + }, + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{InitialDelaySeconds: -100}, + }, + expectedLiveness: probe.Unknown, + expectedReadiness: probe.Success, + }, + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + }, + expectedLiveness: probe.Failure, + expectedReadiness: probe.Success, + }, + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + }, + expectedLiveness: probe.Success, + expectedReadiness: probe.Success, + }, + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + }, + expectedLiveness: probe.Unknown, + expectedReadiness: probe.Success, + }, + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + }, + expectError: true, + expectedLiveness: probe.Unknown, + expectedReadiness: probe.Success, + }, + // // Only ReadinessProbe. expectedLiveness should always be probe.Success here. + { + testContainer: api.Container{ + ReadinessProbe: &api.Probe{InitialDelaySeconds: 100}, + }, + expectedLiveness: probe.Success, + expectedReadiness: probe.Unknown, + }, + { + testContainer: api.Container{ + ReadinessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + }, + expectedLiveness: probe.Success, + expectedReadiness: probe.Success, + }, + { + testContainer: api.Container{ + ReadinessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + }, + expectedLiveness: probe.Success, + expectedReadiness: probe.Success, + }, + { + testContainer: api.Container{ + ReadinessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + }, + expectedLiveness: probe.Success, + expectedReadiness: probe.Success, + }, + { + testContainer: api.Container{ + ReadinessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + }, + expectError: false, + expectedLiveness: probe.Success, + expectedReadiness: probe.Success, + }, + // Both LivenessProbe and ReadinessProbe. + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{InitialDelaySeconds: 100}, + ReadinessProbe: &api.Probe{InitialDelaySeconds: 100}, + }, + expectedLiveness: probe.Success, + expectedReadiness: probe.Unknown, + }, + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{InitialDelaySeconds: 100}, + ReadinessProbe: &api.Probe{InitialDelaySeconds: -100}, + }, + expectedLiveness: probe.Success, + expectedReadiness: probe.Unknown, + }, + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{InitialDelaySeconds: -100}, + ReadinessProbe: &api.Probe{InitialDelaySeconds: 100}, + }, + expectedLiveness: probe.Unknown, + expectedReadiness: probe.Unknown, + }, + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{InitialDelaySeconds: -100}, + ReadinessProbe: &api.Probe{InitialDelaySeconds: -100}, + }, + expectedLiveness: probe.Unknown, + expectedReadiness: probe.Unknown, + }, + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + ReadinessProbe: &api.Probe{InitialDelaySeconds: -100}, + }, + expectedLiveness: probe.Unknown, + expectedReadiness: probe.Unknown, + }, + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + ReadinessProbe: &api.Probe{InitialDelaySeconds: -100}, + }, + expectedLiveness: probe.Failure, + expectedReadiness: probe.Unknown, + }, + { + testContainer: api.Container{ + LivenessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + ReadinessProbe: &api.Probe{ + InitialDelaySeconds: -100, + Handler: api.Handler{ + Exec: &api.ExecAction{}, + }, + }, + }, + expectedLiveness: probe.Success, + expectedReadiness: probe.Success, + }, + } + + for i, test := range tests { + if test.expectError { + prober.exec = fakeExecProber{test.expectedLiveness, errors.New("exec error")} + } else { + prober.exec = fakeExecProber{test.expectedLiveness, nil} + } + + liveness, err := prober.ProbeLiveness(&api.Pod{}, api.PodStatus{}, test.testContainer, containerID, createdAt) + if test.expectError && err == nil { + t.Errorf("[%d] Expected liveness probe error but no error was returned.", i) + } + if !test.expectError && err != nil { + t.Errorf("[%d] Didn't expect liveness probe error but got: %v", i, err) + } + if test.expectedLiveness != liveness { + t.Errorf("[%d] Expected liveness result to be %v but was %v", i, test.expectedLiveness, liveness) + } + + // TODO: Test readiness errors + prober.exec = fakeExecProber{test.expectedReadiness, nil} + readiness, err := prober.ProbeReadiness(&api.Pod{}, api.PodStatus{}, test.testContainer, containerID) + if err != nil { + t.Errorf("[%d] Unexpected readiness probe error: %v", i, err) + } + if test.expectedReadiness != readiness { + t.Errorf("[%d] Expected readiness result to be %v but was %v", i, test.expectedReadiness, readiness) + } + } +} + +type fakeExecProber struct { result probe.Result err error } -func (p FakeExecProber) Probe(_ exec.Cmd) (probe.Result, error) { - return p.result, p.err +func (p fakeExecProber) Probe(_ exec.Cmd) (probe.Result, string, error) { + return p.result, "", p.err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/results/results_manager.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/results/results_manager.go new file mode 100644 index 000000000000..208d3d5ffd4f --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/results/results_manager.go @@ -0,0 +1,89 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 results + +import ( + "sync" + + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" +) + +// Manager provides a probe results cache. +type Manager interface { + // Get returns the cached result for the container with the given ID. + Get(id kubecontainer.ContainerID) (Result, bool) + // Set sets the cached result for the container with the given ID. + Set(id kubecontainer.ContainerID, result Result) + // Remove clears the cached result for the container with the given ID. + Remove(id kubecontainer.ContainerID) +} + +// Result is the type for probe results. +type Result bool + +const ( + Success Result = true + Failure Result = false +) + +func (r Result) String() string { + switch r { + case Success: + return "Success" + case Failure: + return "Failure" + default: + return "UNKNOWN" + } +} + +// Manager implementation. +type manager struct { + // guards the cache + sync.RWMutex + // map of container ID -> probe Result + cache map[kubecontainer.ContainerID]Result +} + +var _ Manager = &manager{} + +// NewManager creates ane returns an empty results manager. +func NewManager() Manager { + return &manager{cache: make(map[kubecontainer.ContainerID]Result)} +} + +func (m *manager) Get(id kubecontainer.ContainerID) (Result, bool) { + m.RLock() + defer m.RUnlock() + result, found := m.cache[id] + return result, found +} + +func (m *manager) Set(id kubecontainer.ContainerID, result Result) { + m.Lock() + defer m.Unlock() + prev, exists := m.cache[id] + if !exists || prev != result { + m.cache[id] = result + } +} + +func (m *manager) Remove(id kubecontainer.ContainerID) { + m.Lock() + defer m.Unlock() + delete(m.cache, id) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/results/results_manager_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/results/results_manager_test.go new file mode 100644 index 000000000000..d815c1a84b81 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/results/results_manager_test.go @@ -0,0 +1,43 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 results + +import ( + "testing" + + "github.com/stretchr/testify/assert" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" +) + +func TestCacheOperations(t *testing.T) { + m := NewManager() + + unsetID := kubecontainer.ContainerID{"test", "unset"} + setID := kubecontainer.ContainerID{"test", "set"} + + _, found := m.Get(unsetID) + assert.False(t, found, "unset result found") + + m.Set(setID, Success) + result, found := m.Get(setID) + assert.True(t, result == Success, "set result") + assert.True(t, found, "set result found") + + m.Remove(setID) + _, found = m.Get(setID) + assert.False(t, found, "removed result found") +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/worker.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/worker.go new file mode 100644 index 000000000000..480218efe11d --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/worker.go @@ -0,0 +1,153 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 prober + +import ( + "time" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/prober/results" + kubeletutil "k8s.io/kubernetes/pkg/kubelet/util" + "k8s.io/kubernetes/pkg/probe" + "k8s.io/kubernetes/pkg/util" +) + +// worker handles the periodic probing of its assigned container. Each worker has a go-routine +// associated with it which runs the probe loop until the container permanently terminates, or the +// stop channel is closed. The worker uses the probe Manager's statusManager to get up-to-date +// container IDs. +// TODO: Handle liveness probing +type worker struct { + // Channel for stopping the probe, it should be closed to trigger a stop. + stop chan struct{} + + // The pod containing this probe (read-only) + pod *api.Pod + + // The container to probe (read-only) + container api.Container + + // Describes the probe configuration (read-only) + spec *api.Probe + + // The last known container ID for this worker. + containerID kubecontainer.ContainerID +} + +// Creates and starts a new probe worker. +func (m *manager) newWorker( + pod *api.Pod, + container api.Container) *worker { + + w := &worker{ + stop: make(chan struct{}), + pod: pod, + container: container, + spec: container.ReadinessProbe, + } + + // Start the worker thread. + go run(m, w) + + return w +} + +// run periodically probes the container. +func run(m *manager, w *worker) { + probeTicker := time.NewTicker(m.defaultProbePeriod) + + defer func() { + // Clean up. + probeTicker.Stop() + if !w.containerID.IsEmpty() { + m.readinessCache.Remove(w.containerID) + } + + m.removeReadinessProbe(w.pod.UID, w.container.Name) + }() + +probeLoop: + for doProbe(m, w) { + // Wait for next probe tick. + select { + case <-w.stop: + break probeLoop + case <-probeTicker.C: + // continue + } + } +} + +// doProbe probes the container once and records the result. +// Returns whether the worker should continue. +func doProbe(m *manager, w *worker) (keepGoing bool) { + defer util.HandleCrash(func(_ interface{}) { keepGoing = true }) + + status, ok := m.statusManager.GetPodStatus(w.pod.UID) + if !ok { + // Either the pod has not been created yet, or it was already deleted. + glog.V(3).Infof("No status for pod: %v", kubeletutil.FormatPodName(w.pod)) + return true + } + + // Worker should terminate if pod is terminated. + if status.Phase == api.PodFailed || status.Phase == api.PodSucceeded { + glog.V(3).Infof("Pod %v %v, exiting probe worker", + kubeletutil.FormatPodName(w.pod), status.Phase) + return false + } + + c, ok := api.GetContainerStatus(status.ContainerStatuses, w.container.Name) + if !ok { + // Either the container has not been created yet, or it was deleted. + glog.V(3).Infof("Non-existant container probed: %v - %v", + kubeletutil.FormatPodName(w.pod), w.container.Name) + return true // Wait for more information. + } + + if w.containerID.String() != c.ContainerID { + if !w.containerID.IsEmpty() { + m.readinessCache.Remove(w.containerID) + } + w.containerID = kubecontainer.ParseContainerID(c.ContainerID) + } + + if c.State.Running == nil { + glog.V(3).Infof("Non-running container probed: %v - %v", + kubeletutil.FormatPodName(w.pod), w.container.Name) + m.readinessCache.Set(w.containerID, results.Failure) + // Abort if the container will not be restarted. + return c.State.Terminated == nil || + w.pod.Spec.RestartPolicy != api.RestartPolicyNever + } + + if int64(time.Since(c.State.Running.StartedAt.Time).Seconds()) < w.spec.InitialDelaySeconds { + // Readiness defaults to false during the initial delay. + m.readinessCache.Set(w.containerID, results.Failure) + return true + } + + // TODO: Move error handling out of prober. + result, _ := m.prober.ProbeReadiness(w.pod, status, w.container, w.containerID) + if result != probe.Unknown { + m.readinessCache.Set(w.containerID, result != probe.Failure) + } + + return true +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/worker_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/worker_test.go new file mode 100644 index 000000000000..3a7a6262f73e --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/worker_test.go @@ -0,0 +1,243 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 prober + +import ( + "testing" + "time" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/prober/results" + "k8s.io/kubernetes/pkg/probe" +) + +const ( + containerName = "cOnTaInEr_NaMe" + podUID = "pOd_UiD" +) + +var containerID = kubecontainer.ContainerID{"test", "cOnTaInEr_Id"} + +func TestDoProbe(t *testing.T) { + m := newTestManager() + + // Test statuses. + runningStatus := getRunningStatus() + pendingStatus := getRunningStatus() + pendingStatus.ContainerStatuses[0].State.Running = nil + terminatedStatus := getRunningStatus() + terminatedStatus.ContainerStatuses[0].State.Running = nil + terminatedStatus.ContainerStatuses[0].State.Terminated = &api.ContainerStateTerminated{ + StartedAt: unversioned.Now(), + } + otherStatus := getRunningStatus() + otherStatus.ContainerStatuses[0].Name = "otherContainer" + failedStatus := getRunningStatus() + failedStatus.Phase = api.PodFailed + + tests := []struct { + probe api.Probe + podStatus *api.PodStatus + + expectContinue bool + expectReadySet bool + expectedReadiness results.Result + }{ + { // No status. + expectContinue: true, + }, + { // Pod failed + podStatus: &failedStatus, + }, + { // No container status + podStatus: &otherStatus, + expectContinue: true, + }, + { // Container waiting + podStatus: &pendingStatus, + expectContinue: true, + expectReadySet: true, + }, + { // Container terminated + podStatus: &terminatedStatus, + expectReadySet: true, + }, + { // Probe successful. + podStatus: &runningStatus, + expectContinue: true, + expectReadySet: true, + expectedReadiness: results.Success, + }, + { // Initial delay passed + podStatus: &runningStatus, + probe: api.Probe{ + InitialDelaySeconds: -100, + }, + expectContinue: true, + expectReadySet: true, + expectedReadiness: results.Success, + }, + } + + for i, test := range tests { + w := newTestWorker(test.probe) + if test.podStatus != nil { + m.statusManager.SetPodStatus(w.pod, *test.podStatus) + } + if c := doProbe(m, w); c != test.expectContinue { + t.Errorf("[%d] Expected continue to be %v but got %v", i, test.expectContinue, c) + } + ready, ok := m.readinessCache.Get(containerID) + if ok != test.expectReadySet { + t.Errorf("[%d] Expected to have readiness: %v but got %v", i, test.expectReadySet, ok) + } + if ready != test.expectedReadiness { + t.Errorf("[%d] Expected readiness: %v but got %v", i, test.expectedReadiness, ready) + } + + // Clean up. + m.statusManager.DeletePodStatus(podUID) + m.readinessCache.Remove(containerID) + } +} + +func TestInitialDelay(t *testing.T) { + m := newTestManager() + w := newTestWorker(api.Probe{ + InitialDelaySeconds: 10, + }) + m.statusManager.SetPodStatus(w.pod, getRunningStatus()) + + if !doProbe(m, w) { + t.Errorf("Expected to continue, but did not") + } + + ready, ok := m.readinessCache.Get(containerID) + if !ok { + t.Errorf("Expected readiness to be false, but was not set") + } else if ready { + t.Errorf("Expected readiness to be false, but was true") + } + + // 100 seconds later... + laterStatus := getRunningStatus() + laterStatus.ContainerStatuses[0].State.Running.StartedAt.Time = + time.Now().Add(-100 * time.Second) + m.statusManager.SetPodStatus(w.pod, laterStatus) + + // Second call should succeed (already waited). + if !doProbe(m, w) { + t.Errorf("Expected to continue, but did not") + } + + ready, ok = m.readinessCache.Get(containerID) + if !ok { + t.Errorf("Expected readiness to be true, but was not set") + } else if !ready { + t.Errorf("Expected readiness to be true, but was false") + } +} + +func TestCleanUp(t *testing.T) { + m := newTestManager() + pod := getTestPod(api.Probe{}) + m.statusManager.SetPodStatus(&pod, getRunningStatus()) + m.readinessCache.Set(containerID, results.Success) + w := m.newWorker(&pod, pod.Spec.Containers[0]) + m.readinessProbes[containerPath{podUID, containerName}] = w + + if ready, _ := m.readinessCache.Get(containerID); !ready { + t.Fatal("Expected readiness to be true.") + } + + close(w.stop) + if err := waitForWorkerExit(m, []containerPath{{podUID, containerName}}); err != nil { + t.Fatal(err) + } + + if _, ok := m.readinessCache.Get(containerID); ok { + t.Error("Expected readiness to be cleared.") + } + if _, ok := m.readinessProbes[containerPath{podUID, containerName}]; ok { + t.Error("Expected worker to be cleared.") + } +} + +func TestHandleCrash(t *testing.T) { + m := newTestManager() + m.prober = CrashingProber{} + w := newTestWorker(api.Probe{}) + m.statusManager.SetPodStatus(w.pod, getRunningStatus()) + + // doProbe should recover from the crash, and keep going. + if !doProbe(m, w) { + t.Error("Expected to keep going, but terminated.") + } + if _, ok := m.readinessCache.Get(containerID); ok { + t.Error("Expected readiness to be unchanged from crash.") + } +} + +func newTestWorker(probeSpec api.Probe) *worker { + pod := getTestPod(probeSpec) + return &worker{ + stop: make(chan struct{}), + pod: &pod, + container: pod.Spec.Containers[0], + spec: &probeSpec, + } +} + +func getRunningStatus() api.PodStatus { + containerStatus := api.ContainerStatus{ + Name: containerName, + ContainerID: containerID.String(), + } + containerStatus.State.Running = &api.ContainerStateRunning{unversioned.Now()} + podStatus := api.PodStatus{ + Phase: api.PodRunning, + ContainerStatuses: []api.ContainerStatus{containerStatus}, + } + return podStatus +} + +func getTestPod(probeSpec api.Probe) api.Pod { + container := api.Container{ + Name: containerName, + ReadinessProbe: &probeSpec, + } + pod := api.Pod{ + Spec: api.PodSpec{ + Containers: []api.Container{container}, + RestartPolicy: api.RestartPolicyNever, + }, + } + pod.UID = podUID + return pod +} + +type CrashingProber struct{} + +func (f CrashingProber) ProbeLiveness(_ *api.Pod, _ api.PodStatus, c api.Container, _ kubecontainer.ContainerID, _ int64) (probe.Result, error) { + panic("Intentional ProbeLiveness crash.") +} + +func (f CrashingProber) ProbeReadiness(_ *api.Pod, _ api.PodStatus, c api.Container, _ kubecontainer.ContainerID) (probe.Result, error) { + panic("Intentional ProbeReadiness crash.") +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/memory_policy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/memory_policy.go index 95e4830f2ac7..935727b3dc85 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/memory_policy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/memory_policy.go @@ -21,9 +21,9 @@ import ( ) const ( - PodInfraOomAdj int = -999 - KubeletOomScoreAdj int = -999 - KubeProxyOomScoreAdj int = -999 + PodInfraOOMAdj int = -999 + KubeletOOMScoreAdj int = -999 + KubeProxyOOMScoreAdj int = -999 ) // isMemoryBestEffort returns true if the container's memory requirements are best-effort. @@ -42,12 +42,12 @@ func isMemoryGuaranteed(container *api.Container) bool { return (*memoryRequest).Cmp(*memoryLimit) == 0 && memoryRequest.Value() != 0 } -// GetContainerOomAdjust returns the amount by which the OOM score of all processes in the +// GetContainerOOMAdjust returns the amount by which the OOM score of all processes in the // container should be adjusted. The OOM score of a process is the percentage of memory it consumes // multiplied by 100 (barring exceptional cases) + a configurable quantity which is between -1000 // and 1000. Containers with higher OOM scores are killed if the system runs out of memory. // See https://lwn.net/Articles/391222/ for more information. -func GetContainerOomScoreAdjust(container *api.Container, memoryCapacity int64) int { +func GetContainerOOMScoreAdjust(container *api.Container, memoryCapacity int64) int { if isMemoryGuaranteed(container) { // Memory guaranteed containers should be the last to get killed. return -999 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/memory_policy_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/memory_policy_test.go index bb0ddea210ba..27af3fd11605 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/memory_policy_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/memory_policy_test.go @@ -128,60 +128,60 @@ func TestIsMemoryGuaranteed(t *testing.T) { type oomTest struct { container *api.Container memoryCapacity int64 - lowOomScoreAdj int // The max oom_score_adj score the container should be assigned. - highOomScoreAdj int // The min oom_score_adj score the container should be assigned. + lowOOMScoreAdj int // The max oom_score_adj score the container should be assigned. + highOOMScoreAdj int // The min oom_score_adj score the container should be assigned. } -func TestGetContainerOomScoreAdjust(t *testing.T) { +func TestGetContainerOOMScoreAdjust(t *testing.T) { oomTests := []oomTest{ { container: &zeroRequestMemoryBestEffort, memoryCapacity: 4000000000, - lowOomScoreAdj: 1000, - highOomScoreAdj: 1000, + lowOOMScoreAdj: 1000, + highOOMScoreAdj: 1000, }, { container: &edgeMemoryBestEffort, memoryCapacity: 8000000000, - lowOomScoreAdj: 1000, - highOomScoreAdj: 1000, + lowOOMScoreAdj: 1000, + highOOMScoreAdj: 1000, }, { container: &noRequestMemoryBestEffort, memoryCapacity: 7230457451, - lowOomScoreAdj: 1000, - highOomScoreAdj: 1000, + lowOOMScoreAdj: 1000, + highOOMScoreAdj: 1000, }, { container: &noLimitMemoryBestEffort, memoryCapacity: 4000000000, - lowOomScoreAdj: 1000, - highOomScoreAdj: 1000, + lowOOMScoreAdj: 1000, + highOOMScoreAdj: 1000, }, { container: &memoryGuaranteed, memoryCapacity: 123456789, - lowOomScoreAdj: -999, - highOomScoreAdj: -999, + lowOOMScoreAdj: -999, + highOOMScoreAdj: -999, }, { container: &memoryBurstable, memoryCapacity: standardMemoryAmount, - lowOomScoreAdj: 495, - highOomScoreAdj: 505, + lowOOMScoreAdj: 495, + highOOMScoreAdj: 505, }, { container: &memoryBurstableNoLimit, memoryCapacity: standardMemoryAmount, - lowOomScoreAdj: 2, - highOomScoreAdj: 2, + lowOOMScoreAdj: 2, + highOOMScoreAdj: 2, }, } for _, test := range oomTests { - oomScoreAdj := GetContainerOomScoreAdjust(test.container, test.memoryCapacity) - if oomScoreAdj < test.lowOomScoreAdj || oomScoreAdj > test.highOomScoreAdj { - t.Errorf("oom_score_adj should be between %d and %d, but was %d", test.lowOomScoreAdj, test.highOomScoreAdj, oomScoreAdj) + oomScoreAdj := GetContainerOOMScoreAdjust(test.container, test.memoryCapacity) + if oomScoreAdj < test.lowOOMScoreAdj || oomScoreAdj > test.highOOMScoreAdj { + t.Errorf("oom_score_adj should be between %d and %d, but was %d", test.lowOOMScoreAdj, test.highOOMScoreAdj, oomScoreAdj) } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/util/qos.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/util/qos.go index 0ebb1c84fa18..165af3fc1e9e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/util/qos.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/qos/util/qos.go @@ -23,7 +23,7 @@ import ( const ( Guaranteed = "Guaranteed" Burstable = "Burstable" - BestEffort = "Best-Effort" + BestEffort = "BestEffort" ) // isResourceGuaranteed returns true if the container's resource requirements are Guaranteed. @@ -62,9 +62,17 @@ func GetQoS(container *api.Container) map[api.ResourceName]string { return resourceToQoS } -// allResources returns a set of resources the container has +// supportedComputeResources returns a list of supported compute resources +func supportedComputeResources() []api.ResourceName { + return []api.ResourceName{api.ResourceCPU, api.ResourceMemory} +} + +// allResources returns a set of all possible resources whose mapped key value is true if present on the container func allResources(container *api.Container) map[api.ResourceName]bool { resources := map[api.ResourceName]bool{} + for _, resource := range supportedComputeResources() { + resources[resource] = false + } for resource := range container.Resources.Requests { resources[resource] = true } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/container_id.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/container_id.go index aa35361dda9f..25a3584c5318 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/container_id.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/container_id.go @@ -19,6 +19,8 @@ package rkt import ( "fmt" "strings" + + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" ) // containerID defines the ID of rkt containers, it will @@ -29,17 +31,22 @@ type containerID struct { appName string // Name of the app in that pod. } +const RktType = "rkt" + // buildContainerID constructs the containers's ID using containerID, // which consists of the pod uuid and the container name. // The result can be used to uniquely identify a container. -func buildContainerID(c *containerID) string { - return fmt.Sprintf("%s:%s", c.uuid, c.appName) +func buildContainerID(c *containerID) kubecontainer.ContainerID { + return kubecontainer.ContainerID{ + Type: RktType, + ID: fmt.Sprintf("%s:%s", c.uuid, c.appName), + } } // parseContainerID parses the containerID into pod uuid and the container name. The // results can be used to get more information of the container. -func parseContainerID(id string) (*containerID, error) { - tuples := strings.Split(id, ":") +func parseContainerID(id kubecontainer.ContainerID) (*containerID, error) { + tuples := strings.Split(id.ID, ":") if len(tuples) != 2 { return nil, fmt.Errorf("rkt: cannot parse container ID for: %v", id) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/gc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/gc.go index ff3bfda959a2..555774de4740 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/gc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/gc.go @@ -16,16 +16,28 @@ limitations under the License. package rkt +import "github.com/golang/glog" + // ImageManager manages and garbage collects the container images for rkt. type ImageManager struct { - runtime *runtime + runtime *Runtime } -func NewImageManager(r *runtime) *ImageManager { +func NewImageManager(r *Runtime) *ImageManager { return &ImageManager{runtime: r} } -// GarbageCollect collects the images. It is not implemented by rkt yet. +// GarbageCollect collects the images. +// TODO(yifan): Enforce ImageGCPolicy. func (im *ImageManager) GarbageCollect() error { + if _, err := im.runtime.runCommand("image", "gc"); err != nil { + glog.Errorf("rkt: Failed to gc image: %v", err) + return err + } + return nil +} + +// Start is a no-op for rkt as we don't need to mark unused images in kubelet. +func (im *ImageManager) Start() error { return nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/pod_info.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/pod_info.go index d76614813d49..7c52ce7730d5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/pod_info.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/pod_info.go @@ -24,8 +24,8 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/util" ) // rkt pod state. @@ -143,7 +143,7 @@ func makeContainerStatus(container *kubecontainer.Container, podInfo *podInfo) a var status api.ContainerStatus status.Name = container.Name status.Image = container.Image - status.ContainerID = string(container.ID) + status.ContainerID = container.ID.String() // TODO(yifan): Add image ID info. switch podInfo.state { @@ -151,7 +151,7 @@ func makeContainerStatus(container *kubecontainer.Container, podInfo *podInfo) a // TODO(yifan): Get StartedAt. status.State = api.ContainerState{ Running: &api.ContainerStateRunning{ - StartedAt: util.Unix(container.Created, 0), + StartedAt: unversioned.Unix(container.Created, 0), }, } case Embryo, Preparing, Prepared: @@ -166,7 +166,7 @@ func makeContainerStatus(container *kubecontainer.Container, podInfo *podInfo) a status.State = api.ContainerState{ Terminated: &api.ContainerStateTerminated{ ExitCode: exitCode, - StartedAt: util.Unix(container.Created, 0), + StartedAt: unversioned.Unix(container.Created, 0), }, } default: diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go index 210eee15ed3c..1fe70ad07f5b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go @@ -27,6 +27,7 @@ import ( "path" "strconv" "strings" + "syscall" "time" appcschema "github.com/appc/spec/schema" @@ -41,16 +42,17 @@ import ( "k8s.io/kubernetes/pkg/credentialprovider" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/prober" - kubeletUtil "k8s.io/kubernetes/pkg/kubelet/util" + kubeletutil "k8s.io/kubernetes/pkg/kubelet/util" "k8s.io/kubernetes/pkg/probe" "k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" + utilexec "k8s.io/kubernetes/pkg/util/exec" ) const ( acVersion = "0.6.1" - rktMinimumVersion = "0.7.0" + rktMinimumVersion = "0.8.1" systemdMinimumVersion = "219" systemdServiceDir = "/run/systemd/system" @@ -68,21 +70,13 @@ const ( authDir = "auth.d" dockerAuthTemplate = `{"rktKind":"dockerAuth","rktVersion":"v1","registries":[%q],"credentials":{"user":%q,"password":%q}}` - // TODO(yifan): Merge with ContainerGCPolicy, i.e., derive - // the grace period from MinAge in ContainerGCPolicy. - // - // Duration to wait before discarding inactive pods from garbage - defaultGracePeriod = "1m" - // Duration to wait before expiring prepared pods. - defaultExpirePrepared = "1m" - defaultImageTag = "latest" ) -// runtime implements the Containerruntime for rkt. The implementation +// Runtime implements the Containerruntime for rkt. The implementation // uses systemd, so in order to run this runtime, systemd must be installed // on the machine. -type runtime struct { +type Runtime struct { systemd *dbus.Conn // The absolute path to rkt binary. rktBinAbsPath string @@ -94,12 +88,11 @@ type runtime struct { generator kubecontainer.RunContainerOptionsGenerator recorder record.EventRecorder prober prober.Prober - readinessManager *kubecontainer.ReadinessManager volumeGetter volumeGetter imagePuller kubecontainer.ImagePuller } -var _ kubecontainer.Runtime = &runtime{} +var _ kubecontainer.Runtime = &Runtime{} // TODO(yifan): Remove this when volumeManager is moved to separate package. type volumeGetter interface { @@ -113,8 +106,8 @@ func New(config *Config, generator kubecontainer.RunContainerOptionsGenerator, recorder record.EventRecorder, containerRefManager *kubecontainer.RefManager, - readinessManager *kubecontainer.ReadinessManager, - volumeGetter volumeGetter) (kubecontainer.Runtime, error) { + prober prober.Prober, + volumeGetter volumeGetter, imageBackOff *util.Backoff) (*Runtime, error) { systemdVersion, err := getSystemdVersion() if err != nil { @@ -143,7 +136,7 @@ func New(config *Config, } } - rkt := &runtime{ + rkt := &Runtime{ systemd: systemd, rktBinAbsPath: rktBinAbsPath, config: config, @@ -151,11 +144,10 @@ func New(config *Config, containerRefManager: containerRefManager, generator: generator, recorder: recorder, - readinessManager: readinessManager, + prober: prober, volumeGetter: volumeGetter, } - rkt.prober = prober.New(rkt, readinessManager, containerRefManager, recorder) - rkt.imagePuller = kubecontainer.NewImagePuller(recorder, rkt) + rkt.imagePuller = kubecontainer.NewImagePuller(recorder, rkt, imageBackOff) // Test the rkt version. version, err := rkt.Version() @@ -172,7 +164,7 @@ func New(config *Config, return rkt, nil } -func (r *runtime) buildCommand(args ...string) *exec.Cmd { +func (r *Runtime) buildCommand(args ...string) *exec.Cmd { cmd := exec.Command(r.rktBinAbsPath) cmd.Args = append(cmd.Args, r.config.buildGlobalOptions()...) cmd.Args = append(cmd.Args, args...) @@ -181,7 +173,7 @@ func (r *runtime) buildCommand(args ...string) *exec.Cmd { // runCommand invokes rkt binary with arguments and returns the result // from stdout in a list of strings. Each string in the list is a line. -func (r *runtime) runCommand(args ...string) ([]string, error) { +func (r *Runtime) runCommand(args ...string) ([]string, error) { glog.V(4).Info("rkt: Run command:", args) var stdout, stderr bytes.Buffer @@ -214,10 +206,10 @@ func rawValue(value string) *json.RawMessage { // rawValue converts the request, limit to *json.RawMessage func rawRequestLimit(request, limit string) *json.RawMessage { if request == "" { - return rawValue(fmt.Sprintf(`{"limit":%q}`, limit)) + request = limit } if limit == "" { - return rawValue(fmt.Sprintf(`{"request":%q}`, request)) + limit = request } return rawValue(fmt.Sprintf(`{"request":%q,"limit":%q}`, request, limit)) } @@ -396,7 +388,7 @@ func parseImageName(image string) (string, string) { // getImageManifest invokes 'rkt image cat-manifest' to retrive the image manifest // for the image. -func (r *runtime) getImageManifest(image string) (*appcschema.ImageManifest, error) { +func (r *Runtime) getImageManifest(image string) (*appcschema.ImageManifest, error) { var manifest appcschema.ImageManifest repoToPull, tag := parseImageName(image) @@ -415,12 +407,12 @@ func (r *runtime) getImageManifest(image string) (*appcschema.ImageManifest, err } // makePodManifest transforms a kubelet pod spec to the rkt pod manifest. -func (r *runtime) makePodManifest(pod *api.Pod, pullSecrets []api.Secret) (*appcschema.PodManifest, error) { +func (r *Runtime) makePodManifest(pod *api.Pod, pullSecrets []api.Secret) (*appcschema.PodManifest, error) { var globalPortMappings []kubecontainer.PortMapping manifest := appcschema.BlankPodManifest() for _, c := range pod.Spec.Containers { - if err := r.imagePuller.PullImage(pod, &c, pullSecrets); err != nil { + if err, _ := r.imagePuller.PullImage(pod, &c, pullSecrets); err != nil { return nil, err } imgManifest, err := r.getImageManifest(c.Image) @@ -467,7 +459,7 @@ func (r *runtime) makePodManifest(pod *api.Pod, pullSecrets []api.Secret) (*appc volumeMap, ok := r.volumeGetter.GetVolumes(pod.UID) if !ok { - return nil, fmt.Errorf("cannot get the volumes for pod %q", kubeletUtil.FormatPodName(pod)) + return nil, fmt.Errorf("cannot get the volumes for pod %q", kubeletutil.FormatPodName(pod)) } // Set global volumes. @@ -515,7 +507,7 @@ func apiPodToruntimePod(uuid string, pod *api.Pod) *kubecontainer.Pod { for i := range pod.Spec.Containers { c := &pod.Spec.Containers[i] p.Containers = append(p.Containers, &kubecontainer.Container{ - ID: types.UID(buildContainerID(&containerID{uuid, c.Name})), + ID: buildContainerID(&containerID{uuid, c.Name}), Name: c.Name, Image: c.Image, Hash: kubecontainer.HashContainer(c), @@ -537,7 +529,7 @@ func serviceFilePath(serviceName string) string { // // On success, it will return a string that represents name of the unit file // and the runtime pod. -func (r *runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *kubecontainer.Pod, error) { +func (r *Runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *kubecontainer.Pod, error) { // Generate the pod manifest from the pod spec. manifest, err := r.makePodManifest(pod, pullSecrets) if err != nil { @@ -587,7 +579,7 @@ func (r *runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k } var runPrepared string - if pod.Spec.HostNetwork { + if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork { runPrepared = fmt.Sprintf("%s run-prepared --mds-register=false %s", r.rktBinAbsPath, uuid) } else { runPrepared = fmt.Sprintf("%s run-prepared --mds-register=false --private-net %s", r.rktBinAbsPath, uuid) @@ -623,7 +615,7 @@ func (r *runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k } units = append(units, newUnitOption(unitKubernetesSection, unitRestartCount, strconv.Itoa(restartCount))) - glog.V(4).Infof("rkt: Creating service file %q for pod %q", serviceName, kubeletUtil.FormatPodName(pod)) + glog.V(4).Infof("rkt: Creating service file %q for pod %q", serviceName, kubeletutil.FormatPodName(pod)) serviceFile, err := os.Create(serviceFilePath(serviceName)) if err != nil { return "", nil, err @@ -645,10 +637,10 @@ func (r *runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k // generateEvents is a helper function that generates some container // life cycle events for containers in a pod. -func (r *runtime) generateEvents(runtimePod *kubecontainer.Pod, reason string, failure error) { +func (r *Runtime) generateEvents(runtimePod *kubecontainer.Pod, reason string, failure error) { // Set up container references. for _, c := range runtimePod.Containers { - containerID := string(c.ID) + containerID := c.ID id, err := parseContainerID(containerID) if err != nil { glog.Warningf("Invalid container ID %q", containerID) @@ -681,8 +673,8 @@ func (r *runtime) generateEvents(runtimePod *kubecontainer.Pod, reason string, f // RunPod first creates the unit file for a pod, and then // starts the unit over d-bus. -func (r *runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error { - glog.V(4).Infof("Rkt starts to run pod: name %q.", kubeletUtil.FormatPodName(pod)) +func (r *Runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error { + glog.V(4).Infof("Rkt starts to run pod: name %q.", kubeletutil.FormatPodName(pod)) name, runtimePod, prepareErr := r.preparePod(pod, pullSecrets) @@ -692,14 +684,14 @@ func (r *runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error { for i, c := range pod.Spec.Containers { ref, err := kubecontainer.GenerateContainerRef(pod, &c) if err != nil { - glog.Errorf("Couldn't make a ref to pod %q, container %v: '%v'", kubeletUtil.FormatPodName(pod), c.Name, err) + glog.Errorf("Couldn't make a ref to pod %q, container %v: '%v'", kubeletutil.FormatPodName(pod), c.Name, err) continue } if prepareErr != nil { r.recorder.Eventf(ref, "Failed", "Failed to create rkt container with error: %v", prepareErr) continue } - containerID := string(runtimePod.Containers[i].ID) + containerID := runtimePod.Containers[i].ID r.containerRefManager.SetRef(containerID, ref) } @@ -724,7 +716,7 @@ func (r *runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error { } // readServiceFile reads the service file and constructs the runtime pod and the rkt info. -func (r *runtime) readServiceFile(serviceName string) (*kubecontainer.Pod, *rktInfo, error) { +func (r *Runtime) readServiceFile(serviceName string) (*kubecontainer.Pod, *rktInfo, error) { f, err := os.Open(serviceFilePath(serviceName)) if err != nil { return nil, nil, err @@ -771,7 +763,7 @@ func (r *runtime) readServiceFile(serviceName string) (*kubecontainer.Pod, *rktI // Then it will use the result to construct a list of container runtime pods. // If all is false, then only running pods will be returned, otherwise all pods will be // returned. -func (r *runtime) GetPods(all bool) ([]*kubecontainer.Pod, error) { +func (r *Runtime) GetPods(all bool) ([]*kubecontainer.Pod, error) { glog.V(4).Infof("Rkt getting pods") units, err := r.systemd.ListUnits() @@ -798,14 +790,13 @@ func (r *runtime) GetPods(all bool) ([]*kubecontainer.Pod, error) { // KillPod invokes 'systemctl kill' to kill the unit that runs the pod. // TODO(yifan): Handle network plugin. -func (r *runtime) KillPod(pod *api.Pod, runningPod kubecontainer.Pod) error { +func (r *Runtime) KillPod(pod *api.Pod, runningPod kubecontainer.Pod) error { glog.V(4).Infof("Rkt is killing pod: name %q.", runningPod.Name) serviceName := makePodServiceFileName(runningPod.ID) r.generateEvents(&runningPod, "Killing", nil) for _, c := range runningPod.Containers { - id := string(c.ID) - r.containerRefManager.ClearRef(id) + r.containerRefManager.ClearRef(c.ID) } // Since all service file have 'KillMode=mixed', the processes in @@ -819,22 +810,32 @@ func (r *runtime) KillPod(pod *api.Pod, runningPod kubecontainer.Pod) error { // getPodStatus reads the service file and invokes 'rkt status $UUID' to get the // pod's status. -func (r *runtime) getPodStatus(serviceName string) (*api.PodStatus, error) { +func (r *Runtime) getPodStatus(serviceName string) (*api.PodStatus, error) { + var status api.PodStatus + // TODO(yifan): Get rkt uuid from the service file name. pod, rktInfo, err := r.readServiceFile(serviceName) - if err != nil { + if err != nil && !os.IsNotExist(err) { return nil, err } + + if os.IsNotExist(err) { + // Pod does not exit, means it's not been created yet, + // return empty status for now. + // TODO(yifan): Maybe inspect the image and return waiting status. + return &status, nil + } + podInfo, err := r.getPodInfo(rktInfo.uuid) if err != nil { return nil, err } - status := makePodStatus(pod, podInfo, rktInfo) + status = makePodStatus(pod, podInfo, rktInfo) return &status, nil } // GetPodStatus returns the status of the given pod. -func (r *runtime) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) { +func (r *Runtime) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) { serviceName := makePodServiceFileName(pod.UID) return r.getPodStatus(serviceName) } @@ -846,7 +847,7 @@ func (r *runtime) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) { // Example: // rkt:0.3.2+git --> []int{0, 3, 2}. // -func (r *runtime) Version() (kubecontainer.Version, error) { +func (r *Runtime) Version() (kubecontainer.Version, error) { output, err := r.runCommand("version") if err != nil { return nil, err @@ -870,7 +871,7 @@ func (r *runtime) Version() (kubecontainer.Version, error) { // TODO(yifan): This is very racy, unefficient, and unsafe, we need to provide // different namespaces. See: https://github.com/coreos/rkt/issues/836. -func (r *runtime) writeDockerAuthConfig(image string, credsSlice []docker.AuthConfiguration) error { +func (r *Runtime) writeDockerAuthConfig(image string, credsSlice []docker.AuthConfiguration) error { if len(credsSlice) == 0 { return nil } @@ -914,7 +915,7 @@ func (r *runtime) writeDockerAuthConfig(image string, credsSlice []docker.AuthCo // // http://issue.k8s.io/7203 // -func (r *runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Secret) error { +func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Secret) error { img := image.Image // TODO(yifan): The credential operation is a copy from dockertools package, // Need to resolve the code duplication. @@ -943,10 +944,16 @@ func (r *runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Sec } // TODO(yifan): Searching the image via 'rkt images' might not be the most efficient way. -func (r *runtime) IsImagePresent(image kubecontainer.ImageSpec) (bool, error) { +func (r *Runtime) IsImagePresent(image kubecontainer.ImageSpec) (bool, error) { repoToPull, tag := parseImageName(image.Image) - // TODO(yifan): Change appname to imagename. See https://github.com/coreos/rkt/issues/1295. - output, err := r.runCommand("image", "list", "--fields=appname", "--no-legend") + // Example output of 'rkt image list --fields=name': + // + // NAME + // nginx:latest + // coreos.com/rkt/stage1:0.8.1 + // + // With '--no-legend=true' the fist line (NAME) will be omitted. + output, err := r.runCommand("image", "list", "--no-legend=true", "--fields=name") if err != nil { return false, err } @@ -971,15 +978,11 @@ func (r *runtime) IsImagePresent(image kubecontainer.ImageSpec) (bool, error) { } // SyncPod syncs the running pod to match the specified desired pod. -func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus api.PodStatus, pullSecrets []api.Secret, backOff *util.Backoff) error { - podFullName := kubeletUtil.FormatPodName(pod) - if len(runningPod.Containers) == 0 { - glog.V(4).Infof("Pod %q is not running, will start it", podFullName) - return r.RunPod(pod, pullSecrets) - } +func (r *Runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus api.PodStatus, pullSecrets []api.Secret, backOff *util.Backoff) error { + podFullName := kubeletutil.FormatPodName(pod) // Add references to all containers. - unidentifiedContainers := make(map[types.UID]*kubecontainer.Container) + unidentifiedContainers := make(map[kubecontainer.ContainerID]*kubecontainer.Container) for _, c := range runningPod.Containers { unidentifiedContainers[c.ID] = c } @@ -990,7 +993,7 @@ func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus c := runningPod.FindContainerByName(container.Name) if c == nil { - if kubecontainer.ShouldContainerBeRestarted(&container, pod, &podStatus, r.readinessManager) { + if kubecontainer.ShouldContainerBeRestarted(&container, pod, &podStatus) { glog.V(3).Infof("Container %+v is dead, but RestartPolicy says that we should restart it.", container) // TODO(yifan): Containers in one pod are fate-sharing at this moment, see: // https://github.com/appc/spec/issues/276. @@ -1010,9 +1013,9 @@ func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus break } - result, err := r.prober.Probe(pod, podStatus, container, string(c.ID), c.Created) + result, err := r.prober.ProbeLiveness(pod, podStatus, container, c.ID, c.Created) // TODO(vmarmol): examine this logic. - if err == nil && result != probe.Success { + if err == nil && result != probe.Success && pod.Spec.RestartPolicy != api.RestartPolicyNever { glog.Infof("Pod %q container %q is unhealthy (probe result: %v), it will be killed and re-created.", podFullName, container.Name, result) restartPod = true break @@ -1030,8 +1033,11 @@ func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus } if restartPod { - if err := r.KillPod(pod, runningPod); err != nil { - return err + // Kill the pod only if the pod is actually running. + if len(runningPod.Containers) > 0 { + if err := r.KillPod(pod, runningPod); err != nil { + return err + } } if err := r.RunPod(pod, pullSecrets); err != nil { return err @@ -1049,34 +1055,33 @@ func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus // See https://github.com/coreos/rkt/blob/master/Documentation/commands.md#logging for more details. // // TODO(yifan): If the rkt is using lkvm as the stage1 image, then this function will fail. -func (r *runtime) GetContainerLogs(pod *api.Pod, containerID string, tail string, follow bool, stdout, stderr io.Writer) error { +func (r *Runtime) GetContainerLogs(pod *api.Pod, containerID kubecontainer.ContainerID, logOptions *api.PodLogOptions, stdout, stderr io.Writer) error { id, err := parseContainerID(containerID) if err != nil { return err } cmd := exec.Command("journalctl", "-M", fmt.Sprintf("rkt-%s", id.uuid), "-u", id.appName) - if follow { + if logOptions.Follow { cmd.Args = append(cmd.Args, "-f") } - if tail == "all" { + if logOptions.TailLines == nil { cmd.Args = append(cmd.Args, "-a") } else { - _, err := strconv.Atoi(tail) - if err == nil { - cmd.Args = append(cmd.Args, "-n", tail) - } + cmd.Args = append(cmd.Args, "-n", strconv.FormatInt(*logOptions.TailLines, 10)) } cmd.Stdout, cmd.Stderr = stdout, stderr return cmd.Run() } -// GarbageCollect collects the pods/containers. TODO(yifan): Enforce the gc policy. -func (r *runtime) GarbageCollect() error { +// GarbageCollect collects the pods/containers. +// TODO(yifan): Enforce the gc policy, also, it would be better if we can +// just GC kubernetes pods. +func (r *Runtime) GarbageCollect(gcPolicy kubecontainer.ContainerGCPolicy) error { if err := exec.Command("systemctl", "reset-failed").Run(); err != nil { glog.Errorf("rkt: Failed to reset failed systemd services: %v", err) } - if _, err := r.runCommand("gc", "--grace-period="+defaultGracePeriod, "--expire-prepared="+defaultExpirePrepared); err != nil { + if _, err := r.runCommand("gc", "--grace-period="+gcPolicy.MinAge.String(), "--expire-prepared="+gcPolicy.MinAge.String()); err != nil { glog.Errorf("rkt: Failed to gc: %v", err) return err } @@ -1086,7 +1091,7 @@ func (r *runtime) GarbageCollect() error { // Note: In rkt, the container ID is in the form of "UUID:appName", where // appName is the container name. // TODO(yifan): If the rkt is using lkvm as the stage1 image, then this function will fail. -func (r *runtime) RunInContainer(containerID string, cmd []string) ([]byte, error) { +func (r *Runtime) RunInContainer(containerID kubecontainer.ContainerID, cmd []string) ([]byte, error) { glog.V(4).Infof("Rkt running in container.") id, err := parseContainerID(containerID) @@ -1096,18 +1101,35 @@ func (r *runtime) RunInContainer(containerID string, cmd []string) ([]byte, erro args := append([]string{}, "enter", fmt.Sprintf("--app=%s", id.appName), id.uuid) args = append(args, cmd...) - result, err := r.runCommand(args...) - return []byte(strings.Join(result, "\n")), err + result, err := r.buildCommand(args...).CombinedOutput() + if err != nil { + if exitErr, ok := err.(*exec.ExitError); ok { + err = &rktExitError{exitErr} + } + } + return result, err } -func (r *runtime) AttachContainer(containerID string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { +// rktExitError implemets /pkg/util/exec.ExitError interface. +type rktExitError struct{ *exec.ExitError } + +var _ utilexec.ExitError = &rktExitError{} + +func (r *rktExitError) ExitStatus() int { + if status, ok := r.Sys().(syscall.WaitStatus); ok { + return status.ExitStatus() + } + return 0 +} + +func (r *Runtime) AttachContainer(containerID kubecontainer.ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { return fmt.Errorf("unimplemented") } // Note: In rkt, the container ID is in the form of "UUID:appName", where UUID is // the rkt UUID, and appName is the container name. // TODO(yifan): If the rkt is using lkvm as the stage1 image, then this function will fail. -func (r *runtime) ExecInContainer(containerID string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { +func (r *Runtime) ExecInContainer(containerID kubecontainer.ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { glog.V(4).Infof("Rkt execing in container.") id, err := parseContainerID(containerID) @@ -1159,7 +1181,7 @@ func (r *runtime) ExecInContainer(containerID string, cmd []string, stdin io.Rea } // findRktID returns the rkt uuid for the pod. -func (r *runtime) findRktID(pod *kubecontainer.Pod) (string, error) { +func (r *Runtime) findRktID(pod *kubecontainer.Pod) (string, error) { serviceName := makePodServiceFileName(pod.ID) f, err := os.Open(serviceFilePath(serviceName)) @@ -1195,7 +1217,7 @@ func (r *runtime) findRktID(pod *kubecontainer.Pod) (string, error) { // // TODO(yifan): Merge with the same function in dockertools. // TODO(yifan): If the rkt is using lkvm as the stage1 image, then this function will fail. -func (r *runtime) PortForward(pod *kubecontainer.Pod, port uint16, stream io.ReadWriteCloser) error { +func (r *Runtime) PortForward(pod *kubecontainer.Pod, port uint16, stream io.ReadWriteCloser) error { glog.V(4).Infof("Rkt port forwarding in container.") rktID, err := r.findRktID(pod) @@ -1208,19 +1230,39 @@ func (r *runtime) PortForward(pod *kubecontainer.Pod, port uint16, stream io.Rea return err } - _, lookupErr := exec.LookPath("socat") + socatPath, lookupErr := exec.LookPath("socat") if lookupErr != nil { return fmt.Errorf("unable to do port forwarding: socat not found.") } - args := []string{"-t", fmt.Sprintf("%d", info.pid), "-n", "socat", "-", fmt.Sprintf("TCP4:localhost:%d", port)} - _, lookupErr = exec.LookPath("nsenter") + args := []string{"-t", fmt.Sprintf("%d", info.pid), "-n", socatPath, "-", fmt.Sprintf("TCP4:localhost:%d", port)} + + nsenterPath, lookupErr := exec.LookPath("nsenter") if lookupErr != nil { return fmt.Errorf("unable to do port forwarding: nsenter not found.") } - command := exec.Command("nsenter", args...) - command.Stdin = stream + + command := exec.Command(nsenterPath, args...) command.Stdout = stream + + // If we use Stdin, command.Run() won't return until the goroutine that's copying + // from stream finishes. Unfortunately, if you have a client like telnet connected + // via port forwarding, as long as the user's telnet client is connected to the user's + // local listener that port forwarding sets up, the telnet session never exits. This + // means that even if socat has finished running, command.Run() won't ever return + // (because the client still has the connection and stream open). + // + // The work around is to use StdinPipe(), as Wait() (called by Run()) closes the pipe + // when the command (socat) exits. + inPipe, err := command.StdinPipe() + if err != nil { + return fmt.Errorf("unable to do port forwarding: error creating stdin pipe: %v", err) + } + go func() { + io.Copy(inPipe, stream) + inPipe.Close() + }() + return command.Run() } @@ -1235,7 +1277,7 @@ func isUUID(input string) bool { // getPodInfo returns the pod info of a single pod according // to the uuid. -func (r *runtime) getPodInfo(uuid string) (*podInfo, error) { +func (r *Runtime) getPodInfo(uuid string) (*podInfo, error) { status, err := r.runCommand("status", uuid) if err != nil { return nil, err @@ -1251,7 +1293,7 @@ func (r *runtime) getPodInfo(uuid string) (*podInfo, error) { // TODO(yifan): Replace with 'rkt image cat-manifest'. // imageName should be in the form of 'example.com/app:latest', which should matches // the result of 'rkt image list'. If the version is empty, then 'latest' is assumed. -func (r *runtime) getImageByName(imageName string) (*kubecontainer.Image, error) { +func (r *Runtime) getImageByName(imageName string) (*kubecontainer.Image, error) { // TODO(yifan): Print hash in 'rkt image cat-manifest'? images, err := r.ListImages() if err != nil { @@ -1279,8 +1321,15 @@ func (r *runtime) getImageByName(imageName string) (*kubecontainer.Image, error) } // ListImages lists all the available appc images on the machine by invoking 'rkt image list'. -func (r *runtime) ListImages() ([]kubecontainer.Image, error) { - output, err := r.runCommand("image", "list", "--no-legend=true", "--fields=key,appname") +func (r *Runtime) ListImages() ([]kubecontainer.Image, error) { + // Example output of 'rkt image list --fields=key,name': + // + // KEY NAME + // sha512-374770396f23dd153937cd66694fe705cf375bcec7da00cf87e1d9f72c192da7 nginx:latest + // sha512-bead9e0df8b1b4904d0c57ade2230e6d236e8473f62614a8bc6dcf11fc924123 coreos.com/rkt/stage1:0.8.1 + // + // With '--no-legend=true' the fist line (KEY NAME) will be omitted. + output, err := r.runCommand("image", "list", "--no-legend=true", "--fields=key,name") if err != nil { return nil, err } @@ -1318,7 +1367,7 @@ func parseImageInfo(input string) (*kubecontainer.Image, error) { // RemoveImage removes an on-disk image using 'rkt image rm'. // TODO(yifan): Use image ID to reference image. -func (r *runtime) RemoveImage(image kubecontainer.ImageSpec) error { +func (r *Runtime) RemoveImage(image kubecontainer.ImageSpec) error { img, err := r.getImageByName(image.Image) if err != nil { return err diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/runonce.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/runonce.go index e2c992803f85..d5d41f47f0e7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/runonce.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/runonce.go @@ -24,6 +24,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) const ( @@ -39,7 +40,7 @@ type RunPodResult struct { } // RunOnce polls from one configuration update and run the associated pods. -func (kl *Kubelet) RunOnce(updates <-chan PodUpdate) ([]RunPodResult, error) { +func (kl *Kubelet) RunOnce(updates <-chan kubetypes.PodUpdate) ([]RunPodResult, error) { select { case u := <-updates: glog.Infof("processing manifest with %d pods", len(u.Pods)) @@ -109,7 +110,7 @@ func (kl *Kubelet) runPod(pod *api.Pod, retryDelay time.Duration) error { glog.Infof("pod %q containers not running: syncing", pod.Name) // We don't create mirror pods in this mode; pass a dummy boolean value // to sycnPod. - if err = kl.syncPod(pod, nil, p, SyncPodUpdate); err != nil { + if err = kl.syncPod(pod, nil, p, kubetypes.SyncPodUpdate); err != nil { return fmt.Errorf("error syncing pod: %v", err) } if retry >= RunOnceMaxRetries { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/runonce_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/runonce_test.go index 4d6435cd332e..37e25277c7c9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/runonce_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/runonce_test.go @@ -17,161 +17,45 @@ limitations under the License. package kubelet import ( - "fmt" - "strconv" "testing" "time" - docker "github.com/fsouza/go-dockerclient" cadvisorApi "github.com/google/cadvisor/info/v1" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/client/record" "k8s.io/kubernetes/pkg/kubelet/cadvisor" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/network" + kubepod "k8s.io/kubernetes/pkg/kubelet/pod" + "k8s.io/kubernetes/pkg/kubelet/status" ) -type listContainersResult struct { - label string - containers []docker.APIContainers - err error -} - -type inspectContainersResult struct { - label string - container docker.Container - err error -} - -type testDocker struct { - listContainersResults []listContainersResult - inspectContainersResults []inspectContainersResult - dockertools.FakeDockerClient - t *testing.T -} - -func (d *testDocker) ListContainers(options docker.ListContainersOptions) ([]docker.APIContainers, error) { - if len(d.listContainersResults) > 0 { - result := d.listContainersResults[0] - d.listContainersResults = d.listContainersResults[1:] - d.t.Logf("ListContainers: %q, returning: (%v, %v)", result.label, result.containers, result.err) - return result.containers, result.err - } - return nil, fmt.Errorf("ListContainers error: no more test results") -} - -func (d *testDocker) InspectContainer(id string) (*docker.Container, error) { - if len(d.inspectContainersResults) > 0 { - result := d.inspectContainersResults[0] - d.inspectContainersResults = d.inspectContainersResults[1:] - d.t.Logf("InspectContainers: %q, returning: (%v, %v)", result.label, result.container, result.err) - return &result.container, result.err - } - return nil, fmt.Errorf("InspectContainer error: no more test results") -} - func TestRunOnce(t *testing.T) { cadvisor := &cadvisor.Mock{} cadvisor.On("MachineInfo").Return(&cadvisorApi.MachineInfo{}, nil) - - podManager, _ := newFakePodManager() + podManager := kubepod.NewBasicPodManager(kubepod.NewFakeMirrorClient()) diskSpaceManager, _ := newDiskSpaceManager(cadvisor, DiskSpacePolicy{}) + fakeRuntime := &kubecontainer.FakeRuntime{} kb := &Kubelet{ rootDirectory: "/tmp/kubelet", recorder: &record.FakeRecorder{}, cadvisor: cadvisor, nodeLister: testNodeLister{}, - statusManager: newStatusManager(nil), + statusManager: status.NewManager(nil), containerRefManager: kubecontainer.NewRefManager(), - readinessManager: kubecontainer.NewReadinessManager(), podManager: podManager, os: kubecontainer.FakeOS{}, volumeManager: newVolumeManager(), diskSpaceManager: diskSpaceManager, + containerRuntime: fakeRuntime, } - kb.containerManager, _ = newContainerManager(cadvisor, "", "", "") + kb.containerManager, _ = newContainerManager(fakeContainerMgrMountInt(), cadvisor, "", "", "") kb.networkPlugin, _ = network.InitNetworkPlugin([]network.NetworkPlugin{}, "", network.NewFakeHost(nil)) if err := kb.setupDataDirs(); err != nil { t.Errorf("Failed to init data dirs: %v", err) } - podContainers := []docker.APIContainers{ - { - Names: []string{"/k8s_bar." + strconv.FormatUint(kubecontainer.HashContainer(&api.Container{Name: "bar"}), 16) + "_foo_new_12345678_42"}, - ID: "1234", - Status: "running", - }, - { - Names: []string{"/k8s_net_foo.new.test_abcdefgh_42"}, - ID: "9876", - Status: "running", - }, - } - kb.dockerClient = &testDocker{ - listContainersResults: []listContainersResult{ - {label: "list pod container", containers: []docker.APIContainers{}}, - {label: "syncPod", containers: []docker.APIContainers{}}, - {label: "list pod container", containers: []docker.APIContainers{}}, - {label: "syncPod", containers: podContainers}, - {label: "list pod container", containers: podContainers}, - {label: "list pod container", containers: podContainers}, - }, - inspectContainersResults: []inspectContainersResult{ - { - label: "syncPod", - container: docker.Container{ - Config: &docker.Config{Image: "someimage"}, - State: docker.State{Running: true, Pid: 42}, - }, - }, - { - label: "syncPod", - container: docker.Container{ - Config: &docker.Config{Image: "someimage"}, - State: docker.State{Running: true, Pid: 42}, - }, - }, - { - label: "syncPod", - container: docker.Container{ - Config: &docker.Config{Image: "someimage"}, - State: docker.State{Running: true, Pid: 42}, - }, - }, - { - label: "syncPod", - container: docker.Container{ - Config: &docker.Config{Image: "someimage"}, - State: docker.State{Running: true, Pid: 42}, - }, - }, - { - label: "syncPod", - container: docker.Container{ - Config: &docker.Config{Image: "someimage"}, - State: docker.State{Running: true, Pid: 42}, - }, - }, - }, - t: t, - } - - kb.containerRuntime = dockertools.NewFakeDockerManager( - kb.dockerClient, - kb.recorder, - kb.readinessManager, - kb.containerRefManager, - &cadvisorApi.MachineInfo{}, - dockertools.PodInfraContainerImage, - 0, - 0, - "", - kubecontainer.FakeOS{}, - kb.networkPlugin, - kb, - nil) pods := []*api.Pod{ { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server.go index 66e21ebef563..a044ad1c8642 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server.go @@ -35,17 +35,24 @@ import ( "github.com/golang/glog" cadvisorApi "github.com/google/cadvisor/info/v1" "github.com/prometheus/client_golang/prometheus" + "k8s.io/kubernetes/pkg/api" + apierrs "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/auth/authenticator" "k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/healthz" "k8s.io/kubernetes/pkg/httplog" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/types" + "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/flushwriter" "k8s.io/kubernetes/pkg/util/httpstream" "k8s.io/kubernetes/pkg/util/httpstream/spdy" + "k8s.io/kubernetes/pkg/util/limitwriter" "k8s.io/kubernetes/pkg/util/wsstream" ) @@ -97,8 +104,6 @@ func ListenAndServeKubeletServer(host HostInterface, address net.IP, port uint, s := &http.Server{ Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)), Handler: &handler, - ReadTimeout: 60 * time.Minute, - WriteTimeout: 60 * time.Minute, MaxHeaderBytes: 1 << 20, } if tlsOptions != nil { @@ -117,8 +122,6 @@ func ListenAndServeKubeletReadOnlyServer(host HostInterface, address net.IP, por server := &http.Server{ Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)), Handler: &s, - ReadTimeout: 60 * time.Minute, - WriteTimeout: 60 * time.Minute, MaxHeaderBytes: 1 << 20, } glog.Fatal(server.ListenAndServe()) @@ -144,7 +147,7 @@ type HostInterface interface { RunInContainer(name string, uid types.UID, container string, cmd []string) ([]byte, error) ExecInContainer(name string, uid types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool) error AttachContainer(name string, uid types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool) error - GetKubeletContainerLogs(podFullName, containerName, tail string, follow, previous bool, stdout, stderr io.Writer) error + GetKubeletContainerLogs(podFullName, containerName string, logOptions *api.PodLogOptions, stdout, stderr io.Writer) error ServeLogs(w http.ResponseWriter, req *http.Request) PortForward(name string, uid types.UID, port uint16, stream io.ReadWriteCloser) error StreamingConnectionIdleTimeout() time.Duration @@ -396,6 +399,7 @@ func (s *Server) getContainerLogs(request *restful.Request, response *restful.Re if len(podID) == 0 { // TODO: Why return JSON when the rest return plaintext errors? + // TODO: Why return plaintext errors? response.WriteError(http.StatusBadRequest, fmt.Errorf(`{"message": "Missing podID."}`)) return } @@ -410,9 +414,32 @@ func (s *Server) getContainerLogs(request *restful.Request, response *restful.Re return } - follow, _ := strconv.ParseBool(request.QueryParameter("follow")) - previous, _ := strconv.ParseBool(request.QueryParameter("previous")) - tail := request.QueryParameter("tail") + query := request.Request.URL.Query() + // backwards compatibility for the "tail" query parameter + if tail := request.QueryParameter("tail"); len(tail) > 0 { + query["tailLines"] = []string{tail} + // "all" is the same as omitting tail + if tail == "all" { + delete(query, "tailLines") + } + } + // container logs on the kubelet are locked to v1 + versioned := &v1.PodLogOptions{} + if err := api.Scheme.Convert(&query, versioned); err != nil { + response.WriteError(http.StatusBadRequest, fmt.Errorf(`{"message": "Unable to decode query."}`)) + return + } + out, err := api.Scheme.ConvertToVersion(versioned, "") + if err != nil { + response.WriteError(http.StatusBadRequest, fmt.Errorf(`{"message": "Unable to convert request query."}`)) + return + } + logOptions := out.(*api.PodLogOptions) + logOptions.TypeMeta = unversioned.TypeMeta{} + if errs := validation.ValidatePodLogOptions(logOptions); len(errs) > 0 { + response.WriteError(apierrs.StatusUnprocessableEntity, fmt.Errorf(`{"message": "Invalid request."}`)) + return + } pod, ok := s.host.GetPodByName(podNamespace, podID) if !ok { @@ -436,11 +463,15 @@ func (s *Server) getContainerLogs(request *restful.Request, response *restful.Re return } fw := flushwriter.Wrap(response.ResponseWriter) + if logOptions.LimitBytes != nil { + fw = limitwriter.New(fw, *logOptions.LimitBytes) + } response.Header().Set("Transfer-Encoding", "chunked") response.WriteHeader(http.StatusOK) - err := s.host.GetKubeletContainerLogs(kubecontainer.GetPodFullName(pod), containerName, tail, follow, previous, fw, fw) - if err != nil { - response.WriteError(http.StatusInternalServerError, err) + if err := s.host.GetKubeletContainerLogs(kubecontainer.GetPodFullName(pod), containerName, logOptions, fw, fw); err != nil { + if err != limitwriter.ErrMaximumWrite { + response.WriteError(http.StatusInternalServerError, err) + } return } } @@ -452,7 +483,7 @@ func encodePods(pods []*api.Pod) (data []byte, err error) { for _, pod := range pods { podList.Items = append(podList.Items, *pod) } - return latest.Codec.Encode(podList) + return latest.GroupOrDie("").Codec.Encode(podList) } // getPods returns a list of pods bound to the Kubelet and their spec. @@ -513,7 +544,7 @@ func getContainerCoordinates(request *restful.Request) (namespace, pod string, u return } -const streamCreationTimeout = 30 * time.Second +const defaultStreamCreationTimeout = 30 * time.Second type Closer interface { Close() error @@ -672,7 +703,7 @@ func (s *Server) createStreams(request *restful.Request, response *restful.Respo conn.SetIdleTimeout(s.host.StreamingConnectionIdleTimeout()) // TODO make it configurable? - expired := time.NewTimer(streamCreationTimeout) + expired := time.NewTimer(defaultStreamCreationTimeout) var errorStream, stdinStream, stdoutStream, stderrStream httpstream.Stream receivedStreams := 0 @@ -720,6 +751,15 @@ func getPodCoordinates(request *restful.Request) (namespace, pod string, uid typ return } +// PortForwarder knows how to forward content from a data stream to/from a port +// in a pod. +type PortForwarder interface { + // PortForwarder copies data between a data stream and a port in a pod. + PortForward(name string, uid types.UID, port uint16, stream io.ReadWriteCloser) error +} + +// getPortForward handles a new restful port forward request. It determines the +// pod name and uid and then calls ServePortForward. func (s *Server) getPortForward(request *restful.Request, response *restful.Response) { podNamespace, podID, uid := getPodCoordinates(request) pod, ok := s.host.GetPodByName(podNamespace, podID) @@ -728,80 +768,280 @@ func (s *Server) getPortForward(request *restful.Request, response *restful.Resp return } + podName := kubecontainer.GetPodFullName(pod) + + ServePortForward(response.ResponseWriter, request.Request, s.host, podName, uid, s.host.StreamingConnectionIdleTimeout(), defaultStreamCreationTimeout) +} + +// ServePortForward handles a port forwarding request. A single request is +// kept alive as long as the client is still alive and the connection has not +// been timed out due to idleness. This function handles multiple forwarded +// connections; i.e., multiple `curl http://localhost:8888/` requests will be +// handled by a single invocation of ServePortForward. +func ServePortForward(w http.ResponseWriter, req *http.Request, portForwarder PortForwarder, podName string, uid types.UID, idleTimeout time.Duration, streamCreationTimeout time.Duration) { streamChan := make(chan httpstream.Stream, 1) + + glog.V(5).Infof("Upgrading port forward response") upgrader := spdy.NewResponseUpgrader() - conn := upgrader.UpgradeResponse(response.ResponseWriter, request.Request, func(stream httpstream.Stream) error { + conn := upgrader.UpgradeResponse(w, req, portForwardStreamReceived(streamChan)) + if conn == nil { + return + } + defer conn.Close() + + glog.V(5).Infof("(conn=%p) setting port forwarding streaming connection idle timeout to %v", conn, idleTimeout) + conn.SetIdleTimeout(idleTimeout) + + h := &portForwardStreamHandler{ + conn: conn, + streamChan: streamChan, + streamPairs: make(map[string]*portForwardStreamPair), + streamCreationTimeout: streamCreationTimeout, + pod: podName, + uid: uid, + forwarder: portForwarder, + } + h.run() +} + +// portForwardStreamReceived is the httpstream.NewStreamHandler for port +// forward streams. It checks each stream's port and stream type headers, +// rejecting any streams that with missing or invalid values. Each valid +// stream is sent to the streams channel. +func portForwardStreamReceived(streams chan httpstream.Stream) func(httpstream.Stream) error { + return func(stream httpstream.Stream) error { + // make sure it has a valid port header portString := stream.Headers().Get(api.PortHeader) + if len(portString) == 0 { + return fmt.Errorf("%q header is required", api.PortHeader) + } port, err := strconv.ParseUint(portString, 10, 16) if err != nil { - return fmt.Errorf("Unable to parse '%s' as a port: %v", portString, err) + return fmt.Errorf("unable to parse %q as a port: %v", portString, err) } if port < 1 { - return fmt.Errorf("Port '%d' must be greater than 0", port) + return fmt.Errorf("port %q must be > 0", portString) + } + + // make sure it has a valid stream type header + streamType := stream.Headers().Get(api.StreamType) + if len(streamType) == 0 { + return fmt.Errorf("%q header is required", api.StreamType) + } + if streamType != api.StreamTypeError && streamType != api.StreamTypeData { + return fmt.Errorf("invalid stream type %q", streamType) } - streamChan <- stream + + streams <- stream return nil - }) - if conn == nil { - return } - defer conn.Close() - conn.SetIdleTimeout(s.host.StreamingConnectionIdleTimeout()) +} + +// portForwardStreamHandler is capable of processing multiple port forward +// requests over a single httpstream.Connection. +type portForwardStreamHandler struct { + conn httpstream.Connection + streamChan chan httpstream.Stream + streamPairsLock sync.RWMutex + streamPairs map[string]*portForwardStreamPair + streamCreationTimeout time.Duration + pod string + uid types.UID + forwarder PortForwarder +} - var dataStreamLock sync.Mutex - dataStreamChans := make(map[string]chan httpstream.Stream) +// getStreamPair returns a portForwardStreamPair for requestID. This creates a +// new pair if one does not yet exist for the requestID. The returned bool is +// true if the pair was created. +func (h *portForwardStreamHandler) getStreamPair(requestID string) (*portForwardStreamPair, bool) { + h.streamPairsLock.Lock() + defer h.streamPairsLock.Unlock() + + if p, ok := h.streamPairs[requestID]; ok { + glog.V(5).Infof("(conn=%p, request=%s) found existing stream pair", h.conn, requestID) + return p, false + } + glog.V(5).Infof("(conn=%p, request=%s) creating new stream pair", h.conn, requestID) + + p := newPortForwardPair(requestID) + h.streamPairs[requestID] = p + + return p, true +} + +// monitorStreamPair waits for the pair to receive both its error and data +// streams, or for the timeout to expire (whichever happens first), and then +// removes the pair. +func (h *portForwardStreamHandler) monitorStreamPair(p *portForwardStreamPair, timeout <-chan time.Time) { + select { + case <-timeout: + err := fmt.Errorf("(conn=%p, request=%s) timed out waiting for streams", h.conn, p.requestID) + util.HandleError(err) + p.printError(err.Error()) + case <-p.complete: + glog.V(5).Infof("(conn=%p, request=%s) successfully received error and data streams", h.conn, p.requestID) + } + h.removeStreamPair(p.requestID) +} + +// hasStreamPair returns a bool indicating if a stream pair for requestID +// exists. +func (h *portForwardStreamHandler) hasStreamPair(requestID string) bool { + h.streamPairsLock.RLock() + defer h.streamPairsLock.RUnlock() + + _, ok := h.streamPairs[requestID] + return ok +} + +// removeStreamPair removes the stream pair identified by requestID from streamPairs. +func (h *portForwardStreamHandler) removeStreamPair(requestID string) { + h.streamPairsLock.Lock() + defer h.streamPairsLock.Unlock() + + delete(h.streamPairs, requestID) +} + +// requestID returns the request id for stream. +func (h *portForwardStreamHandler) requestID(stream httpstream.Stream) string { + requestID := stream.Headers().Get(api.PortForwardRequestIDHeader) + if len(requestID) == 0 { + glog.V(5).Infof("(conn=%p) stream received without %s header", h.conn, api.PortForwardRequestIDHeader) + // If we get here, it's because the connection came from an older client + // that isn't generating the request id header + // (https://github.com/kubernetes/kubernetes/blob/843134885e7e0b360eb5441e85b1410a8b1a7a0c/pkg/client/unversioned/portforward/portforward.go#L258-L287) + // + // This is a best-effort attempt at supporting older clients. + // + // When there aren't concurrent new forwarded connections, each connection + // will have a pair of streams (data, error), and the stream IDs will be + // consecutive odd numbers, e.g. 1 and 3 for the first connection. Convert + // the stream ID into a pseudo-request id by taking the stream type and + // using id = stream.Identifier() when the stream type is error, + // and id = stream.Identifier() - 2 when it's data. + // + // NOTE: this only works when there are not concurrent new streams from + // multiple forwarded connections; it's a best-effort attempt at supporting + // old clients that don't generate request ids. If there are concurrent + // new connections, it's possible that 1 connection gets streams whose IDs + // are not consecutive (e.g. 5 and 9 instead of 5 and 7). + streamType := stream.Headers().Get(api.StreamType) + switch streamType { + case api.StreamTypeError: + requestID = strconv.Itoa(int(stream.Identifier())) + case api.StreamTypeData: + requestID = strconv.Itoa(int(stream.Identifier()) - 2) + } + + glog.V(5).Infof("(conn=%p) automatically assigning request ID=%q from stream type=%s, stream ID=%d", h.conn, requestID, streamType, stream.Identifier()) + } + return requestID +} + +// run is the main loop for the portForwardStreamHandler. It processes new +// streams, invoking portForward for each complete stream pair. The loop exits +// when the httpstream.Connection is closed. +func (h *portForwardStreamHandler) run() { + glog.V(5).Infof("(conn=%p) waiting for port forward streams", h.conn) Loop: for { select { - case <-conn.CloseChan(): + case <-h.conn.CloseChan(): + glog.V(5).Infof("(conn=%p) upgraded connection closed", h.conn) break Loop - case stream := <-streamChan: + case stream := <-h.streamChan: + requestID := h.requestID(stream) streamType := stream.Headers().Get(api.StreamType) - port := stream.Headers().Get(api.PortHeader) - dataStreamLock.Lock() - switch streamType { - case "error": - ch := make(chan httpstream.Stream) - dataStreamChans[port] = ch - go waitForPortForwardDataStreamAndRun(kubecontainer.GetPodFullName(pod), uid, stream, ch, s.host) - case "data": - ch, ok := dataStreamChans[port] - if ok { - ch <- stream - delete(dataStreamChans, port) - } else { - glog.Errorf("Unable to locate data stream channel for port %s", port) - } - default: - glog.Errorf("streamType header must be 'error' or 'data', got: '%s'", streamType) - stream.Reset() + glog.V(5).Infof("(conn=%p, request=%s) received new stream of type %s", h.conn, requestID, streamType) + + p, created := h.getStreamPair(requestID) + if created { + go h.monitorStreamPair(p, time.After(h.streamCreationTimeout)) + } + if complete, err := p.add(stream); err != nil { + msg := fmt.Sprintf("error processing stream for request %s: %v", requestID, err) + util.HandleError(errors.New(msg)) + p.printError(msg) + } else if complete { + go h.portForward(p) } - dataStreamLock.Unlock() } } } -func waitForPortForwardDataStreamAndRun(pod string, uid types.UID, errorStream httpstream.Stream, dataStreamChan chan httpstream.Stream, host HostInterface) { - defer errorStream.Reset() +// portForward invokes the portForwardStreamHandler's forwarder.PortForward +// function for the given stream pair. +func (h *portForwardStreamHandler) portForward(p *portForwardStreamPair) { + defer p.dataStream.Close() + defer p.errorStream.Close() - var dataStream httpstream.Stream + portString := p.dataStream.Headers().Get(api.PortHeader) + port, _ := strconv.ParseUint(portString, 10, 16) - select { - case dataStream = <-dataStreamChan: - case <-time.After(streamCreationTimeout): - errorStream.Write([]byte("Timed out waiting for data stream")) - //TODO delete from dataStreamChans[port] - return - } + glog.V(5).Infof("(conn=%p, request=%s) invoking forwarder.PortForward for port %s", h.conn, p.requestID, portString) + err := h.forwarder.PortForward(h.pod, h.uid, uint16(port), p.dataStream) + glog.V(5).Infof("(conn=%p, request=%s) done invoking forwarder.PortForward for port %s", h.conn, p.requestID, portString) - portString := dataStream.Headers().Get(api.PortHeader) - port, _ := strconv.ParseUint(portString, 10, 16) - err := host.PortForward(pod, uid, uint16(port), dataStream) if err != nil { - msg := fmt.Errorf("Error forwarding port %d to pod %s, uid %v: %v", port, pod, uid, err) - glog.Error(msg) - errorStream.Write([]byte(msg.Error())) + msg := fmt.Errorf("error forwarding port %d to pod %s, uid %v: %v", port, h.pod, h.uid, err) + util.HandleError(msg) + fmt.Fprint(p.errorStream, msg.Error()) + } +} + +// portForwardStreamPair represents the error and data streams for a port +// forwarding request. +type portForwardStreamPair struct { + lock sync.RWMutex + requestID string + dataStream httpstream.Stream + errorStream httpstream.Stream + complete chan struct{} +} + +// newPortForwardPair creates a new portForwardStreamPair. +func newPortForwardPair(requestID string) *portForwardStreamPair { + return &portForwardStreamPair{ + requestID: requestID, + complete: make(chan struct{}), + } +} + +// add adds the stream to the portForwardStreamPair. If the pair already +// contains a stream for the new stream's type, an error is returned. add +// returns true if both the data and error streams for this pair have been +// received. +func (p *portForwardStreamPair) add(stream httpstream.Stream) (bool, error) { + p.lock.Lock() + defer p.lock.Unlock() + + switch stream.Headers().Get(api.StreamType) { + case api.StreamTypeError: + if p.errorStream != nil { + return false, errors.New("error stream already assigned") + } + p.errorStream = stream + case api.StreamTypeData: + if p.dataStream != nil { + return false, errors.New("data stream already assigned") + } + p.dataStream = stream + } + + complete := p.errorStream != nil && p.dataStream != nil + if complete { + close(p.complete) + } + return complete, nil +} + +// printError writes s to p.errorStream if p.errorStream has been set. +func (p *portForwardStreamPair) printError(s string) { + p.lock.RLock() + defer p.lock.RUnlock() + if p.errorStream != nil { + fmt.Fprint(p.errorStream, s) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server_test.go index 512c27a93049..6ba570318db8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server_test.go @@ -35,10 +35,12 @@ import ( cadvisorApi "github.com/google/cadvisor/info/v1" "k8s.io/kubernetes/pkg/api" + apierrs "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/auth/user" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/dockertools" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util/httpstream" "k8s.io/kubernetes/pkg/util/httpstream/spdy" @@ -58,7 +60,7 @@ type fakeKubelet struct { execFunc func(pod string, uid types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool) error attachFunc func(pod string, uid types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool) error portForwardFunc func(name string, uid types.UID, port uint16, stream io.ReadWriteCloser) error - containerLogsFunc func(podFullName, containerName, tail string, follow, pervious bool, stdout, stderr io.Writer) error + containerLogsFunc func(podFullName, containerName string, logOptions *api.PodLogOptions, stdout, stderr io.Writer) error streamingConnectionIdleTimeoutFunc func() time.Duration hostnameFunc func() string resyncInterval time.Duration @@ -105,8 +107,8 @@ func (fk *fakeKubelet) ServeLogs(w http.ResponseWriter, req *http.Request) { fk.logFunc(w, req) } -func (fk *fakeKubelet) GetKubeletContainerLogs(podFullName, containerName, tail string, follow, previous bool, stdout, stderr io.Writer) error { - return fk.containerLogsFunc(podFullName, containerName, tail, follow, previous, stdout, stderr) +func (fk *fakeKubelet) GetKubeletContainerLogs(podFullName, containerName string, logOptions *api.PodLogOptions, stdout, stderr io.Writer) error { + return fk.containerLogsFunc(podFullName, containerName, logOptions, stdout, stderr) } func (fk *fakeKubelet) GetHostname() string { @@ -209,7 +211,7 @@ func readResp(resp *http.Response) (string, error) { // A helper function to return the correct pod name. func getPodName(name, namespace string) string { if namespace == "" { - namespace = NamespaceDefault + namespace = kubetypes.NamespaceDefault } return name + "_" + namespace } @@ -768,22 +770,16 @@ func setPodByNameFunc(fw *serverTestFramework, namespace, pod, container string) } } -func setGetContainerLogsFunc(fw *serverTestFramework, t *testing.T, expectedPodName, expectedContainerName, expectedTail string, expectedFollow, expectedPrevious bool, output string) { - fw.fakeKubelet.containerLogsFunc = func(podFullName, containerName, tail string, follow, previous bool, stdout, stderr io.Writer) error { +func setGetContainerLogsFunc(fw *serverTestFramework, t *testing.T, expectedPodName, expectedContainerName string, expectedLogOptions *api.PodLogOptions, output string) { + fw.fakeKubelet.containerLogsFunc = func(podFullName, containerName string, logOptions *api.PodLogOptions, stdout, stderr io.Writer) error { if podFullName != expectedPodName { t.Errorf("expected %s, got %s", expectedPodName, podFullName) } if containerName != expectedContainerName { t.Errorf("expected %s, got %s", expectedContainerName, containerName) } - if tail != expectedTail { - t.Errorf("expected %s, got %s", expectedTail, tail) - } - if follow != expectedFollow { - t.Errorf("expected %t, got %t", expectedFollow, follow) - } - if previous != expectedPrevious { - t.Errorf("expected %t, got %t", expectedPrevious, previous) + if !reflect.DeepEqual(expectedLogOptions, logOptions) { + t.Errorf("expected %#v, got %#v", expectedLogOptions, logOptions) } io.WriteString(stdout, output) @@ -791,6 +787,7 @@ func setGetContainerLogsFunc(fw *serverTestFramework, t *testing.T, expectedPodN } } +// TODO: I really want to be a table driven test func TestContainerLogs(t *testing.T) { fw := newServerTest() output := "foo bar" @@ -798,11 +795,8 @@ func TestContainerLogs(t *testing.T) { podName := "foo" expectedPodName := getPodName(podName, podNamespace) expectedContainerName := "baz" - expectedTail := "" - expectedFollow := false - expectedPrevious := false setPodByNameFunc(fw, podNamespace, podName, expectedContainerName) - setGetContainerLogsFunc(fw, t, expectedPodName, expectedContainerName, expectedTail, expectedFollow, expectedPrevious, output) + setGetContainerLogsFunc(fw, t, expectedPodName, expectedContainerName, &api.PodLogOptions{}, output) resp, err := http.Get(fw.testHTTPServer.URL + "/containerLogs/" + podNamespace + "/" + podName + "/" + expectedContainerName) if err != nil { t.Errorf("Got error GETing: %v", err) @@ -819,6 +813,32 @@ func TestContainerLogs(t *testing.T) { } } +func TestContainerLogsWithLimitBytes(t *testing.T) { + fw := newServerTest() + output := "foo bar" + podNamespace := "other" + podName := "foo" + expectedPodName := getPodName(podName, podNamespace) + expectedContainerName := "baz" + bytes := int64(3) + setPodByNameFunc(fw, podNamespace, podName, expectedContainerName) + setGetContainerLogsFunc(fw, t, expectedPodName, expectedContainerName, &api.PodLogOptions{LimitBytes: &bytes}, output) + resp, err := http.Get(fw.testHTTPServer.URL + "/containerLogs/" + podNamespace + "/" + podName + "/" + expectedContainerName + "?limitBytes=3") + if err != nil { + t.Errorf("Got error GETing: %v", err) + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Errorf("Error reading container logs: %v", err) + } + result := string(body) + if result != output[:bytes] { + t.Errorf("Expected: '%v', got: '%v'", output[:bytes], result) + } +} + func TestContainerLogsWithTail(t *testing.T) { fw := newServerTest() output := "foo bar" @@ -826,11 +846,35 @@ func TestContainerLogsWithTail(t *testing.T) { podName := "foo" expectedPodName := getPodName(podName, podNamespace) expectedContainerName := "baz" - expectedTail := "5" - expectedFollow := false - expectedPrevious := false + expectedTail := int64(5) + setPodByNameFunc(fw, podNamespace, podName, expectedContainerName) + setGetContainerLogsFunc(fw, t, expectedPodName, expectedContainerName, &api.PodLogOptions{TailLines: &expectedTail}, output) + resp, err := http.Get(fw.testHTTPServer.URL + "/containerLogs/" + podNamespace + "/" + podName + "/" + expectedContainerName + "?tailLines=5") + if err != nil { + t.Errorf("Got error GETing: %v", err) + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Errorf("Error reading container logs: %v", err) + } + result := string(body) + if result != output { + t.Errorf("Expected: '%v', got: '%v'", output, result) + } +} + +func TestContainerLogsWithLegacyTail(t *testing.T) { + fw := newServerTest() + output := "foo bar" + podNamespace := "other" + podName := "foo" + expectedPodName := getPodName(podName, podNamespace) + expectedContainerName := "baz" + expectedTail := int64(5) setPodByNameFunc(fw, podNamespace, podName, expectedContainerName) - setGetContainerLogsFunc(fw, t, expectedPodName, expectedContainerName, expectedTail, expectedFollow, expectedPrevious, output) + setGetContainerLogsFunc(fw, t, expectedPodName, expectedContainerName, &api.PodLogOptions{TailLines: &expectedTail}, output) resp, err := http.Get(fw.testHTTPServer.URL + "/containerLogs/" + podNamespace + "/" + podName + "/" + expectedContainerName + "?tail=5") if err != nil { t.Errorf("Got error GETing: %v", err) @@ -847,6 +891,50 @@ func TestContainerLogsWithTail(t *testing.T) { } } +func TestContainerLogsWithTailAll(t *testing.T) { + fw := newServerTest() + output := "foo bar" + podNamespace := "other" + podName := "foo" + expectedPodName := getPodName(podName, podNamespace) + expectedContainerName := "baz" + setPodByNameFunc(fw, podNamespace, podName, expectedContainerName) + setGetContainerLogsFunc(fw, t, expectedPodName, expectedContainerName, &api.PodLogOptions{}, output) + resp, err := http.Get(fw.testHTTPServer.URL + "/containerLogs/" + podNamespace + "/" + podName + "/" + expectedContainerName + "?tail=all") + if err != nil { + t.Errorf("Got error GETing: %v", err) + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Errorf("Error reading container logs: %v", err) + } + result := string(body) + if result != output { + t.Errorf("Expected: '%v', got: '%v'", output, result) + } +} + +func TestContainerLogsWithInvalidTail(t *testing.T) { + fw := newServerTest() + output := "foo bar" + podNamespace := "other" + podName := "foo" + expectedPodName := getPodName(podName, podNamespace) + expectedContainerName := "baz" + setPodByNameFunc(fw, podNamespace, podName, expectedContainerName) + setGetContainerLogsFunc(fw, t, expectedPodName, expectedContainerName, &api.PodLogOptions{}, output) + resp, err := http.Get(fw.testHTTPServer.URL + "/containerLogs/" + podNamespace + "/" + podName + "/" + expectedContainerName + "?tail=-1") + if err != nil { + t.Errorf("Got error GETing: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != apierrs.StatusUnprocessableEntity { + t.Errorf("Unexpected non-error reading container logs: %#v", resp) + } +} + func TestContainerLogsWithFollow(t *testing.T) { fw := newServerTest() output := "foo bar" @@ -854,11 +942,8 @@ func TestContainerLogsWithFollow(t *testing.T) { podName := "foo" expectedPodName := getPodName(podName, podNamespace) expectedContainerName := "baz" - expectedTail := "" - expectedFollow := true - expectedPrevious := false setPodByNameFunc(fw, podNamespace, podName, expectedContainerName) - setGetContainerLogsFunc(fw, t, expectedPodName, expectedContainerName, expectedTail, expectedFollow, expectedPrevious, output) + setGetContainerLogsFunc(fw, t, expectedPodName, expectedContainerName, &api.PodLogOptions{Follow: true}, output) resp, err := http.Get(fw.testHTTPServer.URL + "/containerLogs/" + podNamespace + "/" + podName + "/" + expectedContainerName + "?follow=1") if err != nil { t.Errorf("Got error GETing: %v", err) @@ -1552,3 +1637,221 @@ func TestServePortForward(t *testing.T) { <-portForwardFuncDone } } + +type fakeHttpStream struct { + headers http.Header + id uint32 +} + +func newFakeHttpStream() *fakeHttpStream { + return &fakeHttpStream{ + headers: make(http.Header), + } +} + +var _ httpstream.Stream = &fakeHttpStream{} + +func (s *fakeHttpStream) Read(data []byte) (int, error) { + return 0, nil +} + +func (s *fakeHttpStream) Write(data []byte) (int, error) { + return 0, nil +} + +func (s *fakeHttpStream) Close() error { + return nil +} + +func (s *fakeHttpStream) Reset() error { + return nil +} + +func (s *fakeHttpStream) Headers() http.Header { + return s.headers +} + +func (s *fakeHttpStream) Identifier() uint32 { + return s.id +} + +func TestPortForwardStreamReceived(t *testing.T) { + tests := map[string]struct { + port string + streamType string + expectedError string + }{ + "missing port": { + expectedError: `"port" header is required`, + }, + "unable to parse port": { + port: "abc", + expectedError: `unable to parse "abc" as a port: strconv.ParseUint: parsing "abc": invalid syntax`, + }, + "negative port": { + port: "-1", + expectedError: `unable to parse "-1" as a port: strconv.ParseUint: parsing "-1": invalid syntax`, + }, + "missing stream type": { + port: "80", + expectedError: `"streamType" header is required`, + }, + "valid port with error stream": { + port: "80", + streamType: "error", + }, + "valid port with data stream": { + port: "80", + streamType: "data", + }, + "invalid stream type": { + port: "80", + streamType: "foo", + expectedError: `invalid stream type "foo"`, + }, + } + for name, test := range tests { + streams := make(chan httpstream.Stream, 1) + f := portForwardStreamReceived(streams) + stream := newFakeHttpStream() + if len(test.port) > 0 { + stream.headers.Set("port", test.port) + } + if len(test.streamType) > 0 { + stream.headers.Set("streamType", test.streamType) + } + err := f(stream) + if len(test.expectedError) > 0 { + if err == nil { + t.Errorf("%s: expected err=%q, but it was nil", name, test.expectedError) + } + if e, a := test.expectedError, err.Error(); e != a { + t.Errorf("%s: expected err=%q, got %q", name, e, a) + } + continue + } + if err != nil { + t.Errorf("%s: unexpected error %v", name, err) + continue + } + if s := <-streams; s != stream { + t.Errorf("%s: expected stream %#v, got %#v", name, stream, s) + } + } +} + +func TestGetStreamPair(t *testing.T) { + timeout := make(chan time.Time) + + h := &portForwardStreamHandler{ + streamPairs: make(map[string]*portForwardStreamPair), + } + + // test adding a new entry + p, created := h.getStreamPair("1") + if p == nil { + t.Fatalf("unexpected nil pair") + } + if !created { + t.Fatal("expected created=true") + } + if p.dataStream != nil { + t.Errorf("unexpected non-nil data stream") + } + if p.errorStream != nil { + t.Errorf("unexpected non-nil error stream") + } + + // start the monitor for this pair + monitorDone := make(chan struct{}) + go func() { + h.monitorStreamPair(p, timeout) + close(monitorDone) + }() + + if !h.hasStreamPair("1") { + t.Fatal("This should still be true") + } + + // make sure we can retrieve an existing entry + p2, created := h.getStreamPair("1") + if created { + t.Fatal("expected created=false") + } + if p != p2 { + t.Fatalf("retrieving an existing pair: expected %#v, got %#v", p, p2) + } + + // removed via complete + dataStream := newFakeHttpStream() + dataStream.headers.Set(api.StreamType, api.StreamTypeData) + complete, err := p.add(dataStream) + if err != nil { + t.Fatalf("unexpected error adding data stream to pair: %v", err) + } + if complete { + t.Fatalf("unexpected complete") + } + + errorStream := newFakeHttpStream() + errorStream.headers.Set(api.StreamType, api.StreamTypeError) + complete, err = p.add(errorStream) + if err != nil { + t.Fatalf("unexpected error adding error stream to pair: %v", err) + } + if !complete { + t.Fatal("unexpected incomplete") + } + + // make sure monitorStreamPair completed + <-monitorDone + + // make sure the pair was removed + if h.hasStreamPair("1") { + t.Fatal("expected removal of pair after both data and error streams received") + } + + // removed via timeout + p, created = h.getStreamPair("2") + if !created { + t.Fatal("expected created=true") + } + if p == nil { + t.Fatal("expected p not to be nil") + } + monitorDone = make(chan struct{}) + go func() { + h.monitorStreamPair(p, timeout) + close(monitorDone) + }() + // cause the timeout + close(timeout) + // make sure monitorStreamPair completed + <-monitorDone + if h.hasStreamPair("2") { + t.Fatal("expected stream pair to be removed") + } +} + +func TestRequestID(t *testing.T) { + h := &portForwardStreamHandler{} + + s := newFakeHttpStream() + s.headers.Set(api.StreamType, api.StreamTypeError) + s.id = 1 + if e, a := "1", h.requestID(s); e != a { + t.Errorf("expected %q, got %q", e, a) + } + + s.headers.Set(api.StreamType, api.StreamTypeData) + s.id = 3 + if e, a := "1", h.requestID(s); e != a { + t.Errorf("expected %q, got %q", e, a) + } + + s.id = 7 + s.headers.Set(api.PortForwardRequestIDHeader, "2") + if e, a := "2", h.requestID(s); e != a { + t.Errorf("expected %q, got %q", e, a) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status_manager.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status/manager.go similarity index 61% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status_manager.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status/manager.go index c52ccddb584c..8a55307118eb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status_manager.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status/manager.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kubelet +package status import ( "fmt" @@ -25,9 +25,10 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" - kubeletTypes "k8s.io/kubernetes/pkg/kubelet/types" - kubeletUtil "k8s.io/kubernetes/pkg/kubelet/util" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" + kubeletutil "k8s.io/kubernetes/pkg/kubelet/util" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" ) @@ -39,16 +40,42 @@ type podStatusSyncRequest struct { // Updates pod statuses in apiserver. Writes only when new status has changed. // All methods are thread-safe. -type statusManager struct { +type manager struct { kubeClient client.Interface // Map from pod full name to sync status of the corresponding pod. - podStatusesLock sync.RWMutex podStatuses map[types.UID]api.PodStatus + podStatusesLock sync.RWMutex podStatusChannel chan podStatusSyncRequest } -func newStatusManager(kubeClient client.Interface) *statusManager { - return &statusManager{ +// status.Manager is the Source of truth for kubelet pod status, and should be kept up-to-date with +// the latest api.PodStatus. It also syncs updates back to the API server. +type Manager interface { + // Start the API server status sync loop. + Start() + + // GetPodStatus returns the cached status for the provided pod UID, as well as whether it + // was a cache hit. + GetPodStatus(uid types.UID) (api.PodStatus, bool) + + // SetPodStatus caches updates the cached status for the given pod, and triggers a status update. + SetPodStatus(pod *api.Pod, status api.PodStatus) + + // TerminatePods resets the container status for the provided pods to terminated and triggers + // a status update. This function may not enqueue all the provided pods, in which case it will + // return false + TerminatePods(pods []*api.Pod) bool + + // DeletePodStatus simply removes the given pod from the status cache. + DeletePodStatus(uid types.UID) + + // RemoveOrphanedStatuses scans the status cache and removes any entries for pods not included in + // the provided podUIDs. + RemoveOrphanedStatuses(podUIDs map[types.UID]bool) +} + +func NewManager(kubeClient client.Interface) Manager { + return &manager{ kubeClient: kubeClient, podStatuses: make(map[types.UID]api.PodStatus), podStatusChannel: make(chan podStatusSyncRequest, 1000), // Buffer up to 1000 statuses @@ -58,56 +85,71 @@ func newStatusManager(kubeClient client.Interface) *statusManager { // isStatusEqual returns true if the given pod statuses are equal, false otherwise. // This method sorts container statuses so order does not affect equality. func isStatusEqual(oldStatus, status *api.PodStatus) bool { - sort.Sort(kubeletTypes.SortedContainerStatuses(status.ContainerStatuses)) - sort.Sort(kubeletTypes.SortedContainerStatuses(oldStatus.ContainerStatuses)) + sort.Sort(kubetypes.SortedContainerStatuses(status.ContainerStatuses)) + sort.Sort(kubetypes.SortedContainerStatuses(oldStatus.ContainerStatuses)) // TODO: More sophisticated equality checking. return reflect.DeepEqual(status, oldStatus) } -func (s *statusManager) Start() { +func (m *manager) Start() { // Don't start the status manager if we don't have a client. This will happen // on the master, where the kubelet is responsible for bootstrapping the pods // of the master components. - if s.kubeClient == nil { + if m.kubeClient == nil { glog.Infof("Kubernetes client is nil, not starting status manager.") return } // syncBatch blocks when no updates are available, we can run it in a tight loop. glog.Info("Starting to sync pod status with apiserver") go util.Until(func() { - err := s.syncBatch() + err := m.syncBatch() if err != nil { glog.Warningf("Failed to updated pod status: %v", err) } }, 0, util.NeverStop) } -func (s *statusManager) GetPodStatus(uid types.UID) (api.PodStatus, bool) { - s.podStatusesLock.RLock() - defer s.podStatusesLock.RUnlock() - status, ok := s.podStatuses[uid] +func (m *manager) GetPodStatus(uid types.UID) (api.PodStatus, bool) { + m.podStatusesLock.RLock() + defer m.podStatusesLock.RUnlock() + status, ok := m.podStatuses[uid] return status, ok } -func (s *statusManager) SetPodStatus(pod *api.Pod, status api.PodStatus) { - s.podStatusesLock.Lock() - defer s.podStatusesLock.Unlock() - oldStatus, found := s.podStatuses[pod.UID] +func (m *manager) SetPodStatus(pod *api.Pod, status api.PodStatus) { + m.podStatusesLock.Lock() + defer m.podStatusesLock.Unlock() + oldStatus, found := m.podStatuses[pod.UID] // ensure that the start time does not change across updates. if found && oldStatus.StartTime != nil { status.StartTime = oldStatus.StartTime } + // Set ReadyCondition.LastTransitionTime. + // Note we cannot do this while generating the status since we do not have oldStatus + // at that time for mirror pods. + if readyCondition := api.GetPodReadyCondition(status); readyCondition != nil { + // Need to set LastTransitionTime. + lastTransitionTime := unversioned.Now() + if found { + oldReadyCondition := api.GetPodReadyCondition(oldStatus) + if oldReadyCondition != nil && readyCondition.Status == oldReadyCondition.Status { + lastTransitionTime = oldReadyCondition.LastTransitionTime + } + } + readyCondition.LastTransitionTime = lastTransitionTime + } + // if the status has no start time, we need to set an initial time // TODO(yujuhong): Consider setting StartTime when generating the pod - // status instead, which would allow statusManager to become a simple cache + // status instead, which would allow manager to become a simple cache // again. if status.StartTime.IsZero() { if pod.Status.StartTime.IsZero() { // the pod did not have a previously recorded value so set to now - now := util.Now() + now := unversioned.Now() status.StartTime = &now } else { // the pod had a recorded value, but the kubelet restarted so we need to rebuild cache @@ -123,20 +165,17 @@ func (s *statusManager) SetPodStatus(pod *api.Pod, status api.PodStatus) { // workers and/or the kubelet but dropping the lock before sending the // status down the channel feels like an easy way to get a bullet in foot. if !found || !isStatusEqual(&oldStatus, &status) || pod.DeletionTimestamp != nil { - s.podStatuses[pod.UID] = status - s.podStatusChannel <- podStatusSyncRequest{pod, status} + m.podStatuses[pod.UID] = status + m.podStatusChannel <- podStatusSyncRequest{pod, status} } else { - glog.V(3).Infof("Ignoring same status for pod %q, status: %+v", kubeletUtil.FormatPodName(pod), status) + glog.V(3).Infof("Ignoring same status for pod %q, status: %+v", kubeletutil.FormatPodName(pod), status) } } -// TerminatePods resets the container status for the provided pods to terminated and triggers -// a status update. This function may not enqueue all the provided pods, in which case it will -// return false -func (s *statusManager) TerminatePods(pods []*api.Pod) bool { +func (m *manager) TerminatePods(pods []*api.Pod) bool { sent := true - s.podStatusesLock.Lock() - defer s.podStatusesLock.Unlock() + m.podStatusesLock.Lock() + defer m.podStatusesLock.Unlock() for _, pod := range pods { for i := range pod.Status.ContainerStatuses { pod.Status.ContainerStatuses[i].State = api.ContainerState{ @@ -144,36 +183,36 @@ func (s *statusManager) TerminatePods(pods []*api.Pod) bool { } } select { - case s.podStatusChannel <- podStatusSyncRequest{pod, pod.Status}: + case m.podStatusChannel <- podStatusSyncRequest{pod, pod.Status}: default: sent = false - glog.V(4).Infof("Termination notice for %q was dropped because the status channel is full", kubeletUtil.FormatPodName(pod)) + glog.V(4).Infof("Termination notice for %q was dropped because the status channel is full", kubeletutil.FormatPodName(pod)) } } return sent } -func (s *statusManager) DeletePodStatus(uid types.UID) { - s.podStatusesLock.Lock() - defer s.podStatusesLock.Unlock() - delete(s.podStatuses, uid) +func (m *manager) DeletePodStatus(uid types.UID) { + m.podStatusesLock.Lock() + defer m.podStatusesLock.Unlock() + delete(m.podStatuses, uid) } // TODO(filipg): It'd be cleaner if we can do this without signal from user. -func (s *statusManager) RemoveOrphanedStatuses(podUIDs map[types.UID]bool) { - s.podStatusesLock.Lock() - defer s.podStatusesLock.Unlock() - for key := range s.podStatuses { +func (m *manager) RemoveOrphanedStatuses(podUIDs map[types.UID]bool) { + m.podStatusesLock.Lock() + defer m.podStatusesLock.Unlock() + for key := range m.podStatuses { if _, ok := podUIDs[key]; !ok { glog.V(5).Infof("Removing %q from status map.", key) - delete(s.podStatuses, key) + delete(m.podStatuses, key) } } } // syncBatch syncs pods statuses with the apiserver. -func (s *statusManager) syncBatch() error { - syncRequest := <-s.podStatusChannel +func (m *manager) syncBatch() error { + syncRequest := <-m.podStatusChannel pod := syncRequest.pod status := syncRequest.status @@ -182,21 +221,21 @@ func (s *statusManager) syncBatch() error { ObjectMeta: pod.ObjectMeta, } // TODO: make me easier to express from client code - statusPod, err = s.kubeClient.Pods(statusPod.Namespace).Get(statusPod.Name) + statusPod, err = m.kubeClient.Pods(statusPod.Namespace).Get(statusPod.Name) if errors.IsNotFound(err) { glog.V(3).Infof("Pod %q was deleted on the server", pod.Name) return nil } if err == nil { if len(pod.UID) > 0 && statusPod.UID != pod.UID { - glog.V(3).Infof("Pod %q was deleted and then recreated, skipping status update", kubeletUtil.FormatPodName(pod)) + glog.V(3).Infof("Pod %q was deleted and then recreated, skipping status update", kubeletutil.FormatPodName(pod)) return nil } statusPod.Status = status // TODO: handle conflict as a retry, make that easier too. - statusPod, err = s.kubeClient.Pods(pod.Namespace).UpdateStatus(statusPod) + statusPod, err = m.kubeClient.Pods(pod.Namespace).UpdateStatus(statusPod) if err == nil { - glog.V(3).Infof("Status for pod %q updated successfully", kubeletUtil.FormatPodName(pod)) + glog.V(3).Infof("Status for pod %q updated successfully", kubeletutil.FormatPodName(pod)) if pod.DeletionTimestamp == nil { return nil @@ -205,9 +244,9 @@ func (s *statusManager) syncBatch() error { glog.V(3).Infof("Pod %q is terminated, but some pods are still running", pod.Name) return nil } - if err := s.kubeClient.Pods(statusPod.Namespace).Delete(statusPod.Name, api.NewDeleteOptions(0)); err == nil { + if err := m.kubeClient.Pods(statusPod.Namespace).Delete(statusPod.Name, api.NewDeleteOptions(0)); err == nil { glog.V(3).Infof("Pod %q fully terminated and removed from etcd", statusPod.Name) - s.DeletePodStatus(pod.UID) + m.DeletePodStatus(pod.UID) return nil } } @@ -220,8 +259,8 @@ func (s *statusManager) syncBatch() error { // is full, and the pod worker holding the lock is waiting on this method // to clear the channel. Even if this delete never runs subsequent container // changes on the node should trigger updates. - go s.DeletePodStatus(pod.UID) - return fmt.Errorf("error updating status for pod %q: %v", kubeletUtil.FormatPodName(pod), err) + go m.DeletePodStatus(pod.UID) + return fmt.Errorf("error updating status for pod %q: %v", kubeletutil.FormatPodName(pod), err) } // notRunning returns true if every status is terminated or waiting, or the status list diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status_manager_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status/manager_test.go similarity index 63% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status_manager_test.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status/manager_test.go index e04f24b80f00..c1b75d866a19 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status_manager_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/status/manager_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kubelet +package status import ( "fmt" @@ -24,9 +24,9 @@ import ( "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/testclient" - "k8s.io/kubernetes/pkg/util" ) var testPod *api.Pod = &api.Pod{ @@ -37,8 +37,8 @@ var testPod *api.Pod = &api.Pod{ }, } -func newTestStatusManager() *statusManager { - return newStatusManager(&testclient.Fake{}) +func newTestManager() *manager { + return NewManager(&testclient.Fake{}).(*manager) } func generateRandomMessage() string { @@ -66,7 +66,7 @@ func verifyActions(t *testing.T, kubeClient client.Interface, expectedActions [] } } -func verifyUpdates(t *testing.T, manager *statusManager, expectedUpdates int) { +func verifyUpdates(t *testing.T, manager *manager, expectedUpdates int) { // Consume all updates in the channel. numUpdates := 0 for { @@ -89,7 +89,7 @@ func verifyUpdates(t *testing.T, manager *statusManager, expectedUpdates int) { } func TestNewStatus(t *testing.T) { - syncer := newTestStatusManager() + syncer := newTestManager() syncer.SetPodStatus(testPod, getRandomPodStatus()) verifyUpdates(t, syncer, 1) @@ -100,7 +100,7 @@ func TestNewStatus(t *testing.T) { } func TestNewStatusPreservesPodStartTime(t *testing.T) { - syncer := newTestStatusManager() + syncer := newTestManager() pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ UID: "12345678", @@ -109,8 +109,8 @@ func TestNewStatusPreservesPodStartTime(t *testing.T) { }, Status: api.PodStatus{}, } - now := util.Now() - startTime := util.NewTime(now.Time.Add(-1 * time.Minute)) + now := unversioned.Now() + startTime := unversioned.NewTime(now.Time.Add(-1 * time.Minute)) pod.Status.StartTime = &startTime syncer.SetPodStatus(pod, getRandomPodStatus()) @@ -120,16 +120,47 @@ func TestNewStatusPreservesPodStartTime(t *testing.T) { } } +func getReadyPodStatus() api.PodStatus { + return api.PodStatus{ + Conditions: []api.PodCondition{ + { + Type: api.PodReady, + Status: api.ConditionTrue, + }, + }, + } +} + +func TestNewStatusSetsReadyTransitionTime(t *testing.T) { + syncer := newTestManager() + podStatus := getReadyPodStatus() + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + UID: "12345678", + Name: "foo", + Namespace: "new", + }, + Status: api.PodStatus{}, + } + syncer.SetPodStatus(pod, podStatus) + verifyUpdates(t, syncer, 1) + status, _ := syncer.GetPodStatus(pod.UID) + readyCondition := api.GetPodReadyCondition(status) + if readyCondition.LastTransitionTime.IsZero() { + t.Errorf("Unexpected: last transition time not set") + } +} + func TestChangedStatus(t *testing.T) { - syncer := newTestStatusManager() + syncer := newTestManager() syncer.SetPodStatus(testPod, getRandomPodStatus()) syncer.SetPodStatus(testPod, getRandomPodStatus()) verifyUpdates(t, syncer, 2) } func TestChangedStatusKeepsStartTime(t *testing.T) { - syncer := newTestStatusManager() - now := util.Now() + syncer := newTestManager() + now := unversioned.Now() firstStatus := getRandomPodStatus() firstStatus.StartTime = &now syncer.SetPodStatus(testPod, firstStatus) @@ -144,16 +175,76 @@ func TestChangedStatusKeepsStartTime(t *testing.T) { } } +func TestChangedStatusUpdatesLastTransitionTime(t *testing.T) { + syncer := newTestManager() + podStatus := getReadyPodStatus() + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + UID: "12345678", + Name: "foo", + Namespace: "new", + }, + Status: api.PodStatus{}, + } + syncer.SetPodStatus(pod, podStatus) + verifyUpdates(t, syncer, 1) + oldStatus, _ := syncer.GetPodStatus(pod.UID) + anotherStatus := getReadyPodStatus() + anotherStatus.Conditions[0].Status = api.ConditionFalse + syncer.SetPodStatus(pod, anotherStatus) + verifyUpdates(t, syncer, 1) + newStatus, _ := syncer.GetPodStatus(pod.UID) + + oldReadyCondition := api.GetPodReadyCondition(oldStatus) + newReadyCondition := api.GetPodReadyCondition(newStatus) + if newReadyCondition.LastTransitionTime.IsZero() { + t.Errorf("Unexpected: last transition time not set") + } + if !oldReadyCondition.LastTransitionTime.Before(newReadyCondition.LastTransitionTime) { + t.Errorf("Unexpected: new transition time %s, is not after old transition time %s", newReadyCondition.LastTransitionTime, oldReadyCondition.LastTransitionTime) + } +} + func TestUnchangedStatus(t *testing.T) { - syncer := newTestStatusManager() + syncer := newTestManager() podStatus := getRandomPodStatus() syncer.SetPodStatus(testPod, podStatus) syncer.SetPodStatus(testPod, podStatus) verifyUpdates(t, syncer, 1) } +func TestUnchangedStatusPreservesLastTransitionTime(t *testing.T) { + syncer := newTestManager() + podStatus := getReadyPodStatus() + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + UID: "12345678", + Name: "foo", + Namespace: "new", + }, + Status: api.PodStatus{}, + } + syncer.SetPodStatus(pod, podStatus) + verifyUpdates(t, syncer, 1) + oldStatus, _ := syncer.GetPodStatus(pod.UID) + anotherStatus := getReadyPodStatus() + syncer.SetPodStatus(pod, anotherStatus) + // No update. + verifyUpdates(t, syncer, 0) + newStatus, _ := syncer.GetPodStatus(pod.UID) + + oldReadyCondition := api.GetPodReadyCondition(oldStatus) + newReadyCondition := api.GetPodReadyCondition(newStatus) + if newReadyCondition.LastTransitionTime.IsZero() { + t.Errorf("Unexpected: last transition time not set") + } + if !oldReadyCondition.LastTransitionTime.Equal(newReadyCondition.LastTransitionTime) { + t.Errorf("Unexpected: new transition time %s, is not equal to old transition time %s", newReadyCondition.LastTransitionTime, oldReadyCondition.LastTransitionTime) + } +} + func TestSyncBatchIgnoresNotFound(t *testing.T) { - syncer := newTestStatusManager() + syncer := newTestManager() syncer.SetPodStatus(testPod, getRandomPodStatus()) err := syncer.syncBatch() if err != nil { @@ -165,7 +256,7 @@ func TestSyncBatchIgnoresNotFound(t *testing.T) { } func TestSyncBatch(t *testing.T) { - syncer := newTestStatusManager() + syncer := newTestManager() syncer.kubeClient = testclient.NewSimpleFake(testPod) syncer.SetPodStatus(testPod, getRandomPodStatus()) err := syncer.syncBatch() @@ -180,7 +271,7 @@ func TestSyncBatch(t *testing.T) { } func TestSyncBatchChecksMismatchedUID(t *testing.T) { - syncer := newTestStatusManager() + syncer := newTestManager() testPod.UID = "first" differentPod := *testPod differentPod.UID = "second" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go similarity index 80% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go index 63db74864d88..f3612ecc4d71 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kubelet +package types import ( "fmt" @@ -88,3 +88,35 @@ func GetValidatedSources(sources []string) ([]string, error) { } return validated, nil } + +// GetPodSource returns the source of the pod based on the annotation. +func GetPodSource(pod *api.Pod) (string, error) { + if pod.Annotations != nil { + if source, ok := pod.Annotations[ConfigSourceAnnotationKey]; ok { + return source, nil + } + } + return "", fmt.Errorf("cannot get source of pod %q", pod.UID) +} + +// SyncPodType classifies pod updates, eg: create, update. +type SyncPodType int + +const ( + SyncPodSync SyncPodType = iota + SyncPodUpdate + SyncPodCreate +) + +func (sp SyncPodType) String() string { + switch sp { + case SyncPodCreate: + return "create" + case SyncPodUpdate: + return "update" + case SyncPodSync: + return "sync" + default: + return "unknown" + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types/pod_update_test.go similarity index 98% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types_test.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types/pod_update_test.go index 057747ab2cb6..a753bb587277 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types/pod_update_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kubelet +package types import ( "testing" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types/types.go index 23e494eef454..ad1fb75b0655 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/types/types.go @@ -21,6 +21,7 @@ import ( "time" "k8s.io/kubernetes/pkg/api" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" ) // TODO: Reconcile custom types in kubelet/types and this subpackage @@ -28,6 +29,13 @@ import ( // DockerID is an ID of docker container. It is a type to make it clear when we're working with docker container Ids type DockerID string +func (id DockerID) ContainerID() kubecontainer.ContainerID { + return kubecontainer.ContainerID{ + Type: "docker", + ID: string(id), + } +} + type HttpGetter interface { Get(url string) (*http.Response, error) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/util.go index 1c2ab0a29c90..21edd8f4f344 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/util.go @@ -23,6 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/capabilities" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/securitycontext" ) @@ -40,7 +41,7 @@ func CapacityFromMachineInfo(info *cadvisorApi.MachineInfo) api.ResourceList { // Check whether we have the capabilities to run the specified pod. func canRunPod(pod *api.Pod) error { - if pod.Spec.HostNetwork { + if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork { allowed, err := allowHostNetwork(pod) if err != nil { return err @@ -50,7 +51,7 @@ func canRunPod(pod *api.Pod) error { } } - if pod.Spec.HostPID { + if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostPID { allowed, err := allowHostPID(pod) if err != nil { return err @@ -60,7 +61,7 @@ func canRunPod(pod *api.Pod) error { } } - if pod.Spec.HostIPC { + if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostIPC { allowed, err := allowHostIPC(pod) if err != nil { return err @@ -82,7 +83,7 @@ func canRunPod(pod *api.Pod) error { // Determined whether the specified pod is allowed to use host networking func allowHostNetwork(pod *api.Pod) (bool, error) { - podSource, err := getPodSource(pod) + podSource, err := kubetypes.GetPodSource(pod) if err != nil { return false, err } @@ -96,7 +97,7 @@ func allowHostNetwork(pod *api.Pod) (bool, error) { // Determined whether the specified pod is allowed to use host networking func allowHostPID(pod *api.Pod) (bool, error) { - podSource, err := getPodSource(pod) + podSource, err := kubetypes.GetPodSource(pod) if err != nil { return false, err } @@ -110,7 +111,7 @@ func allowHostPID(pod *api.Pod) (bool, error) { // Determined whether the specified pod is allowed to use host ipc func allowHostIPC(pod *api.Pod) (bool, error) { - podSource, err := getPodSource(pod) + podSource, err := kubetypes.GetPodSource(pod) if err != nil { return false, err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/volumes.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/volumes.go index d9b3c303bc97..8386e1a6f38e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/volumes.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/volumes.go @@ -28,6 +28,7 @@ import ( kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/io" "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" ) @@ -56,15 +57,15 @@ func (vh *volumeHost) GetKubeClient() client.Interface { return vh.kubelet.kubeClient } -func (vh *volumeHost) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { - b, err := vh.kubelet.newVolumeBuilderFromPlugins(spec, pod, opts, mounter) +func (vh *volumeHost) NewWrapperBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { + b, err := vh.kubelet.newVolumeBuilderFromPlugins(spec, pod, opts) if err == nil && b == nil { return nil, errUnsupportedVolumeType } return b, nil } -func (vh *volumeHost) NewWrapperCleaner(spec *volume.Spec, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { +func (vh *volumeHost) NewWrapperCleaner(spec *volume.Spec, podUID types.UID) (volume.Cleaner, error) { plugin, err := vh.kubelet.volumePluginMgr.FindPluginBySpec(spec) if err != nil { return nil, err @@ -73,7 +74,7 @@ func (vh *volumeHost) NewWrapperCleaner(spec *volume.Spec, podUID types.UID, mou // Not found but not an error return nil, nil } - c, err := plugin.NewCleaner(spec.Name(), podUID, mounter) + c, err := plugin.NewCleaner(spec.Name(), podUID) if err == nil && c == nil { return nil, errUnsupportedVolumeType } @@ -84,7 +85,15 @@ func (vh *volumeHost) GetCloudProvider() cloudprovider.Interface { return vh.kubelet.cloud } -func (kl *Kubelet) newVolumeBuilderFromPlugins(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (vh *volumeHost) GetMounter() mount.Interface { + return vh.kubelet.mounter +} + +func (vh *volumeHost) GetWriter() io.Writer { + return vh.kubelet.writer +} + +func (kl *Kubelet) newVolumeBuilderFromPlugins(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { plugin, err := kl.volumePluginMgr.FindPluginBySpec(spec) if err != nil { return nil, fmt.Errorf("can't use volume plugins for %s: %v", spec.Name(), err) @@ -93,7 +102,7 @@ func (kl *Kubelet) newVolumeBuilderFromPlugins(spec *volume.Spec, pod *api.Pod, // Not found but not an error return nil, nil } - builder, err := plugin.NewBuilder(spec, pod, opts, mounter) + builder, err := plugin.NewBuilder(spec, pod, opts) if err != nil { return nil, fmt.Errorf("failed to instantiate volume plugin for %s: %v", spec.Name(), err) } @@ -113,7 +122,7 @@ func (kl *Kubelet) mountExternalVolumes(pod *api.Pod) (kubecontainer.VolumeMap, // Try to use a plugin for this volume. internal := volume.NewSpecFromVolume(volSpec) - builder, err := kl.newVolumeBuilderFromPlugins(internal, pod, volume.VolumeOptions{RootContext: rootContext}, kl.mounter) + builder, err := kl.newVolumeBuilderFromPlugins(internal, pod, volume.VolumeOptions{RootContext: rootContext}) if err != nil { glog.Errorf("Could not create volume builder for pod %s: %v", pod.UID, err) return nil, err @@ -145,12 +154,19 @@ func (kl *Kubelet) getPodVolumes(podUID types.UID) ([]*volumeTuple, error) { for _, volumeKindDir := range volumeKindDirs { volumeKind := volumeKindDir.Name() volumeKindPath := path.Join(podVolDir, volumeKind) - volumeNameDirs, err := ioutil.ReadDir(volumeKindPath) + // ioutil.ReadDir exits without returning any healthy dir when encountering the first lstat error + // but skipping dirs means no cleanup for healthy volumes. switching to a no-exit api solves this problem + volumeNameDirs, volumeNameDirsStat, err := util.ReadDirNoExit(volumeKindPath) if err != nil { return []*volumeTuple{}, fmt.Errorf("could not read directory %s: %v", volumeKindPath, err) } - for _, volumeNameDir := range volumeNameDirs { - volumes = append(volumes, &volumeTuple{Kind: volumeKind, Name: volumeNameDir.Name()}) + for i, volumeNameDir := range volumeNameDirs { + if volumeNameDir != nil { + volumes = append(volumes, &volumeTuple{Kind: volumeKind, Name: volumeNameDir.Name()}) + } else { + lerr := volumeNameDirsStat[i] + glog.Errorf("Could not read directory %s: %v", podVolDir, lerr) + } } } return volumes, nil @@ -180,7 +196,7 @@ func (kl *Kubelet) getPodVolumesFromDisk() map[string]volume.Cleaner { // or volume objects. // Try to use a plugin for this volume. - cleaner, err := kl.newVolumeCleanerFromPlugins(volume.Kind, volume.Name, podUID, kl.mounter) + cleaner, err := kl.newVolumeCleanerFromPlugins(volume.Kind, volume.Name, podUID) if err != nil { glog.Errorf("Could not create volume cleaner for %s: %v", volume.Name, err) continue @@ -195,7 +211,7 @@ func (kl *Kubelet) getPodVolumesFromDisk() map[string]volume.Cleaner { return currentVolumes } -func (kl *Kubelet) newVolumeCleanerFromPlugins(kind string, name string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { +func (kl *Kubelet) newVolumeCleanerFromPlugins(kind string, name string, podUID types.UID) (volume.Cleaner, error) { plugName := util.UnescapeQualifiedNameForDisk(kind) plugin, err := kl.volumePluginMgr.FindPluginByName(plugName) if err != nil { @@ -206,7 +222,7 @@ func (kl *Kubelet) newVolumeCleanerFromPlugins(kind string, name string, podUID // Not found but not an error. return nil, nil } - cleaner, err := plugin.NewCleaner(name, podUID, mounter) + cleaner, err := plugin.NewCleaner(name, podUID) if err != nil { return nil, fmt.Errorf("failed to instantiate volume plugin for %s/%s: %v", podUID, kind, err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/labels/selector.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/labels/selector.go index 7d811cc48301..fabf0f1ccd3b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/labels/selector.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/labels/selector.go @@ -22,9 +22,9 @@ import ( "sort" "strings" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" "k8s.io/kubernetes/pkg/util/sets" + "k8s.io/kubernetes/pkg/util/validation" ) // Selector represents a label selector. @@ -52,6 +52,7 @@ func Everything() Selector { type Operator string const ( + DoesNotExistOperator Operator = "!" EqualsOperator Operator = "=" DoubleEqualsOperator Operator = "==" InOperator Operator = "in" @@ -85,10 +86,11 @@ type Requirement struct { // NewRequirement is the constructor for a Requirement. // If any of these rules is violated, an error is returned: -// (1) The operator can only be In, NotIn or Exists. -// (2) If the operator is In or NotIn, the values set must -// be non-empty. -// (3) The key is invalid due to its length, or sequence +// (1) The operator can only be In, NotIn, Equals, DoubleEquals, NotEquals, Exists, or DoesNotExist. +// (2) If the operator is In or NotIn, the values set must be non-empty. +// (3) If the operator is Equals, DoubleEquals, or NotEquals, the values set must contain one value. +// (4) If the operator is Exists or DoesNotExist, the value set must be empty. +// (5) The key is invalid due to its length, or sequence // of characters. See validateLabelKey for more details. // // The empty string is a valid value in the input values set. @@ -103,9 +105,12 @@ func NewRequirement(key string, op Operator, vals sets.String) (*Requirement, er } case EqualsOperator, DoubleEqualsOperator, NotEqualsOperator: if len(vals) != 1 { - return nil, fmt.Errorf("exact match compatibility requires one single value") + return nil, fmt.Errorf("exact-match compatibility requires one single value") + } + case ExistsOperator, DoesNotExistOperator: + if len(vals) != 0 { + return nil, fmt.Errorf("values set must be empty for exists and does not exist") } - case ExistsOperator: default: return nil, fmt.Errorf("operator '%v' is not recognized", op) } @@ -125,7 +130,7 @@ func NewRequirement(key string, op Operator, vals sets.String) (*Requirement, er // value for that key is in Requirement's value set. // (3) The operator is NotIn, Labels has the Requirement's key and // Labels' value for that key is not in Requirement's value set. -// (4) The operator is NotIn and Labels does not have the +// (4) The operator is DoesNotExist or NotIn and Labels does not have the // Requirement's key. func (r *Requirement) Matches(ls Labels) bool { switch r.operator { @@ -141,11 +146,27 @@ func (r *Requirement) Matches(ls Labels) bool { return !r.strValues.Has(ls.Get(r.key)) case ExistsOperator: return ls.Has(r.key) + case DoesNotExistOperator: + return !ls.Has(r.key) default: return false } } +func (r *Requirement) Key() string { + return r.key +} +func (r *Requirement) Operator() Operator { + return r.operator +} +func (r *Requirement) Values() sets.String { + ret := sets.String{} + for k := range r.strValues { + ret.Insert(k) + } + return ret +} + // Return true if the LabelSelector doesn't restrict selection space func (lsel LabelSelector) Empty() bool { if lsel == nil { @@ -159,6 +180,9 @@ func (lsel LabelSelector) Empty() bool { // returned. See NewRequirement for creating a valid Requirement. func (r *Requirement) String() string { var buffer bytes.Buffer + if r.operator == DoesNotExistOperator { + buffer.WriteString("!") + } buffer.WriteString(r.key) switch r.operator { @@ -172,7 +196,7 @@ func (r *Requirement) String() string { buffer.WriteString(" in ") case NotInOperator: buffer.WriteString(" notin ") - case ExistsOperator: + case ExistsOperator, DoesNotExistOperator: return buffer.String() } @@ -235,6 +259,7 @@ const ( EndOfStringToken ClosedParToken CommaToken + DoesNotExistToken DoubleEqualsToken EqualsToken IdentifierToken // to represent keys and values @@ -249,6 +274,7 @@ const ( var string2token = map[string]Token{ ")": ClosedParToken, ",": CommaToken, + "!": DoesNotExistToken, "==": DoubleEqualsToken, "=": EqualsToken, "in": InToken, @@ -443,7 +469,7 @@ func (p *Parser) parse() ([]Requirement, error) { for { tok, lit := p.lookahead(Values) switch tok { - case IdentifierToken: + case IdentifierToken, DoesNotExistToken: r, err := p.parseRequirement() if err != nil { return nil, fmt.Errorf("unable to parse requirement: %v", err) @@ -455,7 +481,7 @@ func (p *Parser) parse() ([]Requirement, error) { return requirements, nil case CommaToken: t2, l2 := p.lookahead(Values) - if t2 != IdentifierToken { + if t2 != IdentifierToken && t2 != DoesNotExistToken { return nil, fmt.Errorf("found '%s', expected: identifier after ','", l2) } default: @@ -464,7 +490,7 @@ func (p *Parser) parse() ([]Requirement, error) { case EndOfStringToken: return requirements, nil default: - return nil, fmt.Errorf("found '%s', expected: identifier or 'end of string'", lit) + return nil, fmt.Errorf("found '%s', expected: !, identifier, or 'end of string'", lit) } } } @@ -474,7 +500,7 @@ func (p *Parser) parseRequirement() (*Requirement, error) { if err != nil { return nil, err } - if operator == ExistsOperator { // operator Exists found lookahead set checked + if operator == ExistsOperator || operator == DoesNotExistOperator { // operator found lookahead set checked return NewRequirement(key, operator, nil) } operator, err = p.parseOperator() @@ -496,10 +522,15 @@ func (p *Parser) parseRequirement() (*Requirement, error) { } // parseKeyAndInferOperator parse literals. -// in case of no operator 'in, notin, ==, =, !=' are found -// the 'exists' operattor is inferred +// in case of no operator '!, in, notin, ==, =, !=' are found +// the 'exists' operator is inferred func (p *Parser) parseKeyAndInferOperator() (string, Operator, error) { + var operator Operator tok, literal := p.consume(Values) + if tok == DoesNotExistToken { + operator = DoesNotExistOperator + tok, literal = p.consume(Values) + } if tok != IdentifierToken { err := fmt.Errorf("found '%s', expected: identifier", literal) return "", "", err @@ -507,9 +538,10 @@ func (p *Parser) parseKeyAndInferOperator() (string, Operator, error) { if err := validateLabelKey(literal); err != nil { return "", "", err } - var operator Operator if t, _ := p.lookahead(Values); t == EndOfStringToken || t == CommaToken { - operator = ExistsOperator + if operator != DoesNotExistOperator { + operator = ExistsOperator + } } return literal, operator, nil } @@ -519,6 +551,7 @@ func (p *Parser) parseKeyAndInferOperator() (string, Operator, error) { func (p *Parser) parseOperator() (op Operator, err error) { tok, lit := p.consume(KeyAndOperator) switch tok { + // DoesNotExistToken shouldn't be here because it's a unary operator, not a binary operator case InToken: op = InOperator case EqualsToken: @@ -600,7 +633,12 @@ func (p *Parser) parseIdentifiersList() (sets.String, error) { // parseExactValue parses the only value for exact match style func (p *Parser) parseExactValue() (sets.String, error) { s := sets.NewString() - tok, lit := p.consume(Values) + tok, lit := p.lookahead(Values) + if tok == EndOfStringToken || tok == CommaToken { + s.Insert("") + return s, nil + } + tok, lit = p.consume(Values) if tok == IdentifierToken { s.Insert(lit) return s, nil @@ -614,7 +652,7 @@ func (p *Parser) parseExactValue() (sets.String, error) { // The input will cause an error if it does not follow this form: // // ::= | "," ] -// ::= KEY [ | +// ::= [!] KEY [ | ] // ::= "" | // ::= | // ::= "notin" @@ -629,13 +667,14 @@ func (p *Parser) parseExactValue() (sets.String, error) { // "x in (foo,,baz),y,z notin ()" // // Note: -// (1) Inclusion - " in " - denotes that the KEY is equal to any of the +// (1) Inclusion - " in " - denotes that the KEY exists and is equal to any of the // VALUEs in its requirement // (2) Exclusion - " notin " - denotes that the KEY is not equal to any -// of the VALUEs in its requirement +// of the VALUEs in its requirement or does not exist // (3) The empty string is a valid VALUE // (4) A requirement with just a KEY - as in "y" above - denotes that // the KEY exists and can be any VALUE. +// (5) A requirement with just !KEY requires that the KEY not exist. // func Parse(selector string) (Selector, error) { p := &Parser{l: &Lexer{s: selector, pos: 0}} @@ -647,17 +686,17 @@ func Parse(selector string) (Selector, error) { return nil, error } -const qualifiedNameErrorMsg string = "must match regex [" + util.DNS1123SubdomainFmt + " / ] " + util.DNS1123LabelFmt +const qualifiedNameErrorMsg string = "must match regex [" + validation.DNS1123SubdomainFmt + " / ] " + validation.DNS1123LabelFmt func validateLabelKey(k string) error { - if !util.IsQualifiedName(k) { + if !validation.IsQualifiedName(k) { return fielderrors.NewFieldInvalid("label key", k, qualifiedNameErrorMsg) } return nil } func validateLabelValue(v string) error { - if !util.IsValidLabelValue(v) { + if !validation.IsValidLabelValue(v) { return fielderrors.NewFieldInvalid("label value", v, qualifiedNameErrorMsg) } return nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/labels/selector_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/labels/selector_test.go index 181cb26890a0..32269c8f2c47 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/labels/selector_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/labels/selector_test.go @@ -29,17 +29,23 @@ func TestSelectorParse(t *testing.T) { "x=a,y=b,z=c", "", "x!=a,y=b", + "x=", + "x= ", + "x=,z= ", + "x= ,z= ", + "!x", } testBadStrings := []string{ "x=a||y=b", "x==a==b", + "!x=a", } for _, test := range testGoodStrings { lq, err := Parse(test) if err != nil { t.Errorf("%v: error %v (%#v)\n", test, err, err) } - if test != lq.String() { + if strings.Replace(test, " ", "", -1) != lq.String() { t.Errorf("%v restring gave: %v\n", test, lq.String()) } } @@ -99,10 +105,14 @@ func TestSelectorMatches(t *testing.T) { expectMatch(t, "x=y,z=w", Set{"x": "y", "z": "w"}) expectMatch(t, "x!=y,z!=w", Set{"x": "z", "z": "a"}) expectMatch(t, "notin=in", Set{"notin": "in"}) // in and notin in exactMatch + expectMatch(t, "x", Set{"x": "z"}) + expectMatch(t, "!x", Set{"y": "z"}) expectNoMatch(t, "x=z", Set{}) expectNoMatch(t, "x=y", Set{"x": "z"}) expectNoMatch(t, "x=y,z=w", Set{"x": "w", "z": "w"}) expectNoMatch(t, "x!=y,z!=w", Set{"x": "z", "z": "w"}) + expectNoMatch(t, "x", Set{"y": "z"}) + expectNoMatch(t, "!x", Set{"x": "z"}) labelset := Set{ "foo": "bar", @@ -174,11 +184,14 @@ func TestLexer(t *testing.T) { {"in", InToken}, {"=", EqualsToken}, {"==", DoubleEqualsToken}, + //Note that Lex returns the longest valid token found + {"!", DoesNotExistToken}, {"!=", NotEqualsToken}, {"(", OpenParToken}, {")", ClosedParToken}, + //Non-"special" characters are considered part of an identifier + {"~", IdentifierToken}, {"||", IdentifierToken}, - {"!", ErrorToken}, } for _, v := range testcases { l := &Lexer{s: v.s, pos: 0} @@ -209,6 +222,7 @@ func TestLexerSequence(t *testing.T) { {"key notin ( value )", []Token{IdentifierToken, NotInToken, OpenParToken, IdentifierToken, ClosedParToken}}, {"key in ( value1, value2 )", []Token{IdentifierToken, InToken, OpenParToken, IdentifierToken, CommaToken, IdentifierToken, ClosedParToken}}, {"key", []Token{IdentifierToken}}, + {"!key", []Token{DoesNotExistToken, IdentifierToken}}, {"()", []Token{OpenParToken, ClosedParToken}}, {"x in (),y", []Token{IdentifierToken, InToken, OpenParToken, ClosedParToken, CommaToken, IdentifierToken}}, {"== != (), = notin", []Token{DoubleEqualsToken, NotEqualsToken, OpenParToken, ClosedParToken, CommaToken, EqualsToken, NotInToken}}, @@ -244,6 +258,7 @@ func TestParserLookahead(t *testing.T) { {"key notin ( value )", []Token{IdentifierToken, NotInToken, OpenParToken, IdentifierToken, ClosedParToken, EndOfStringToken}}, {"key in ( value1, value2 )", []Token{IdentifierToken, InToken, OpenParToken, IdentifierToken, CommaToken, IdentifierToken, ClosedParToken, EndOfStringToken}}, {"key", []Token{IdentifierToken, EndOfStringToken}}, + {"!key", []Token{DoesNotExistToken, IdentifierToken, EndOfStringToken}}, {"()", []Token{OpenParToken, ClosedParToken, EndOfStringToken}}, {"", []Token{EndOfStringToken}}, {"x in (),y", []Token{IdentifierToken, InToken, OpenParToken, ClosedParToken, CommaToken, IdentifierToken, EndOfStringToken}}, @@ -281,6 +296,7 @@ func TestRequirementConstructor(t *testing.T) { {"x", InOperator, sets.NewString("foo"), true}, {"x", NotInOperator, sets.NewString("foo"), true}, {"x", ExistsOperator, nil, true}, + {"x", DoesNotExistOperator, nil, true}, {"1foo", InOperator, sets.NewString("bar"), true}, {"1234", InOperator, sets.NewString("bar"), true}, {strings.Repeat("a", 254), ExistsOperator, nil, false}, //breaks DNS rule that len(key) <= 253 @@ -306,6 +322,11 @@ func TestToString(t *testing.T) { getRequirement("y", NotInOperator, sets.NewString("jkl"), t), getRequirement("z", ExistsOperator, nil, t)}, "x in (abc,def),y notin (jkl),z", true}, + {&LabelSelector{ + getRequirement("x", NotInOperator, sets.NewString("abc", "def"), t), + getRequirement("y", NotEqualsOperator, sets.NewString("jkl"), t), + getRequirement("z", DoesNotExistOperator, nil, t)}, + "x notin (abc,def),y!=jkl,!z", true}, {&LabelSelector{ getRequirement("x", InOperator, sets.NewString("abc", "def"), t), req}, // adding empty req for the trailing ',' @@ -318,8 +339,9 @@ func TestToString(t *testing.T) { {&LabelSelector{ getRequirement("x", EqualsOperator, sets.NewString("abc"), t), getRequirement("y", DoubleEqualsOperator, sets.NewString("jkl"), t), - getRequirement("z", NotEqualsOperator, sets.NewString("a"), t)}, - "x=abc,y==jkl,z!=a", true}, + getRequirement("z", NotEqualsOperator, sets.NewString("a"), t), + getRequirement("z", ExistsOperator, nil, t)}, + "x=abc,y==jkl,z!=a,z", true}, } for _, ts := range toStringTests { if out := ts.In.String(); out == "" && ts.Valid { @@ -352,6 +374,14 @@ func TestRequirementLabelSelectorMatching(t *testing.T) { getRequirement("x", NotInOperator, sets.NewString(""), t), getRequirement("y", ExistsOperator, nil, t), }, true}, + {Set{"y": ""}, &LabelSelector{ + getRequirement("x", DoesNotExistOperator, nil, t), + getRequirement("y", ExistsOperator, nil, t), + }, true}, + {Set{"y": ""}, &LabelSelector{ + getRequirement("x", NotInOperator, sets.NewString(""), t), + getRequirement("y", DoesNotExistOperator, nil, t), + }, false}, {Set{"y": "baz"}, &LabelSelector{ getRequirement("x", InOperator, sets.NewString(""), t), }, false}, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/import_known_versions.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/import_known_versions.go new file mode 100644 index 000000000000..210e8cc2eac3 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/import_known_versions.go @@ -0,0 +1,23 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 master + +// These imports are the API groups the API server will support. +import ( + _ "k8s.io/kubernetes/pkg/api/install" + _ "k8s.io/kubernetes/pkg/apis/extensions/install" +) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go index f572ffcbb811..0f886fe8c5ab 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go @@ -33,10 +33,10 @@ import ( "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" + apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/api/v1" - "k8s.io/kubernetes/pkg/api/v1beta3" - "k8s.io/kubernetes/pkg/apis/experimental" - explatest "k8s.io/kubernetes/pkg/apis/experimental/latest" + expapi "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apiserver" "k8s.io/kubernetes/pkg/auth/authenticator" "k8s.io/kubernetes/pkg/auth/authorizer" @@ -53,6 +53,7 @@ import ( endpointsetcd "k8s.io/kubernetes/pkg/registry/endpoint/etcd" eventetcd "k8s.io/kubernetes/pkg/registry/event/etcd" expcontrolleretcd "k8s.io/kubernetes/pkg/registry/experimental/controller/etcd" + ingressetcd "k8s.io/kubernetes/pkg/registry/ingress/etcd" jobetcd "k8s.io/kubernetes/pkg/registry/job/etcd" limitrangeetcd "k8s.io/kubernetes/pkg/registry/limitrange/etcd" "k8s.io/kubernetes/pkg/registry/namespace" @@ -65,7 +66,6 @@ import ( podtemplateetcd "k8s.io/kubernetes/pkg/registry/podtemplate/etcd" resourcequotaetcd "k8s.io/kubernetes/pkg/registry/resourcequota/etcd" secretetcd "k8s.io/kubernetes/pkg/registry/secret/etcd" - sccetcd "k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd" "k8s.io/kubernetes/pkg/registry/service" etcdallocator "k8s.io/kubernetes/pkg/registry/service/allocator/etcd" serviceetcd "k8s.io/kubernetes/pkg/registry/service/etcd" @@ -77,7 +77,7 @@ import ( "k8s.io/kubernetes/pkg/storage" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" "k8s.io/kubernetes/pkg/tools" - //"k8s.io/kubernetes/pkg/ui" + "k8s.io/kubernetes/pkg/ui" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" @@ -88,6 +88,7 @@ import ( "github.com/emicklei/go-restful/swagger" "github.com/golang/glog" "github.com/prometheus/client_golang/prometheus" + "golang.org/x/net/context" "k8s.io/kubernetes/pkg/registry/service/allocator" "k8s.io/kubernetes/pkg/registry/service/portallocator" ) @@ -96,21 +97,89 @@ const ( DefaultEtcdPathPrefix = "/registry" ) +// StorageDestinations is a mapping from API group & resource to +// the underlying storage interfaces. +type StorageDestinations struct { + APIGroups map[string]*StorageDestinationsForAPIGroup +} + +type StorageDestinationsForAPIGroup struct { + Default storage.Interface + Overrides map[string]storage.Interface +} + +func NewStorageDestinations() StorageDestinations { + return StorageDestinations{ + APIGroups: map[string]*StorageDestinationsForAPIGroup{}, + } +} + +func (s *StorageDestinations) AddAPIGroup(group string, defaultStorage storage.Interface) { + s.APIGroups[group] = &StorageDestinationsForAPIGroup{ + Default: defaultStorage, + Overrides: map[string]storage.Interface{}, + } +} + +func (s *StorageDestinations) AddStorageOverride(group, resource string, override storage.Interface) { + if _, ok := s.APIGroups[group]; !ok { + s.AddAPIGroup(group, nil) + } + if s.APIGroups[group].Overrides == nil { + s.APIGroups[group].Overrides = map[string]storage.Interface{} + } + s.APIGroups[group].Overrides[resource] = override +} + +func (s *StorageDestinations) get(group, resource string) storage.Interface { + apigroup, ok := s.APIGroups[group] + if !ok { + glog.Errorf("No storage defined for API group: '%s'", apigroup) + return nil + } + if apigroup.Overrides != nil { + if client, exists := apigroup.Overrides[resource]; exists { + return client + } + } + return apigroup.Default +} + +// Get all backends for all registered storage destinations. +// Used for getting all instances for health validations. +func (s *StorageDestinations) backends() []string { + backends := sets.String{} + for _, group := range s.APIGroups { + if group.Default != nil { + for _, backend := range group.Default.Backends(context.TODO()) { + backends.Insert(backend) + } + } + if group.Overrides != nil { + for _, storage := range group.Overrides { + for _, backend := range storage.Backends(context.TODO()) { + backends.Insert(backend) + } + } + } + } + return backends.List() +} + // Config is a structure used to configure a Master. type Config struct { - DatabaseStorage storage.Interface - ExpDatabaseStorage storage.Interface - EventTTL time.Duration - NodeRegexp string - KubeletClient client.KubeletClient + StorageDestinations StorageDestinations + // StorageVersions is a map between groups and their storage versions + StorageVersions map[string]string + EventTTL time.Duration + NodeRegexp string + KubeletClient client.KubeletClient // allow downstream consumers to disable the core controller loops EnableCoreControllers bool EnableLogsSupport bool EnableUISupport bool // allow downstream consumers to disable swagger EnableSwaggerSupport bool - // allow v1beta3 to be conditionally enabled - EnableV1Beta3 bool // allow api versions to be conditionally disabled DisableV1 bool EnableExp bool @@ -119,7 +188,7 @@ type Config struct { EnableProfiling bool EnableWatchCache bool APIPrefix string - ExpAPIPrefix string + APIGroupPrefix string CorsAllowedOriginList []string Authenticator authenticator.Request // TODO(roberthbailey): Remove once the server no longer supports http basic auth. @@ -213,13 +282,12 @@ type Master struct { enableProfiling bool enableWatchCache bool apiPrefix string - expAPIPrefix string + apiGroupPrefix string corsAllowedOriginList []string authenticator authenticator.Request authorizer authorizer.Authorizer admissionControl admission.Interface masterCount int - v1beta3 bool v1 bool exp bool requestContextMapper api.RequestContextMapper @@ -260,7 +328,6 @@ type Master struct { // storage for third party objects thirdPartyStorage storage.Interface - // map from api path to storage for those objects thirdPartyResources map[string]*thirdpartyresourcedataetcd.REST // protects the map @@ -378,12 +445,11 @@ func New(c *Config) *Master { enableProfiling: c.EnableProfiling, enableWatchCache: c.EnableWatchCache, apiPrefix: c.APIPrefix, - expAPIPrefix: c.ExpAPIPrefix, + apiGroupPrefix: c.APIGroupPrefix, corsAllowedOriginList: c.CorsAllowedOriginList, authenticator: c.Authenticator, authorizer: c.Authorizer, admissionControl: c.AdmissionControl, - v1beta3: c.EnableV1Beta3, v1: !c.DisableV1, exp: c.EnableExp, requestContextMapper: c.RequestContextMapper, @@ -463,37 +529,37 @@ func (m *Master) init(c *Config) { } healthzChecks := []healthz.HealthzChecker{} - podStorage := podetcd.NewStorage(c.DatabaseStorage, c.EnableWatchCache, c.KubeletClient, m.proxyTransport) - podTemplateStorage := podtemplateetcd.NewREST(c.DatabaseStorage) + dbClient := func(resource string) storage.Interface { return c.StorageDestinations.get("", resource) } + podStorage := podetcd.NewStorage(dbClient("pods"), c.EnableWatchCache, c.KubeletClient, m.proxyTransport) - eventStorage := eventetcd.NewREST(c.DatabaseStorage, uint64(c.EventTTL.Seconds())) - limitRangeStorage := limitrangeetcd.NewREST(c.DatabaseStorage) + podTemplateStorage := podtemplateetcd.NewREST(dbClient("podTemplates")) - resourceQuotaStorage, resourceQuotaStatusStorage := resourcequotaetcd.NewREST(c.DatabaseStorage) - secretStorage := secretetcd.NewREST(c.DatabaseStorage) - serviceAccountStorage := serviceaccountetcd.NewREST(c.DatabaseStorage) - persistentVolumeStorage, persistentVolumeStatusStorage := pvetcd.NewREST(c.DatabaseStorage) - persistentVolumeClaimStorage, persistentVolumeClaimStatusStorage := pvcetcd.NewREST(c.DatabaseStorage) + eventStorage := eventetcd.NewREST(dbClient("events"), uint64(c.EventTTL.Seconds())) + limitRangeStorage := limitrangeetcd.NewREST(dbClient("limitRanges")) - namespaceStorage, namespaceStatusStorage, namespaceFinalizeStorage := namespaceetcd.NewREST(c.DatabaseStorage) + resourceQuotaStorage, resourceQuotaStatusStorage := resourcequotaetcd.NewREST(dbClient("resourceQuotas")) + secretStorage := secretetcd.NewREST(dbClient("secrets")) + serviceAccountStorage := serviceaccountetcd.NewREST(dbClient("serviceAccounts")) + persistentVolumeStorage, persistentVolumeStatusStorage := pvetcd.NewREST(dbClient("persistentVolumes")) + persistentVolumeClaimStorage, persistentVolumeClaimStatusStorage := pvcetcd.NewREST(dbClient("persistentVolumeClaims")) + + namespaceStorage, namespaceStatusStorage, namespaceFinalizeStorage := namespaceetcd.NewREST(dbClient("namespaces")) m.namespaceRegistry = namespace.NewRegistry(namespaceStorage) - endpointsStorage := endpointsetcd.NewREST(c.DatabaseStorage, c.EnableWatchCache) + endpointsStorage := endpointsetcd.NewREST(dbClient("endpoints"), c.EnableWatchCache) m.endpointRegistry = endpoint.NewRegistry(endpointsStorage) - securityContextConstraintsStorage := sccetcd.NewStorage(c.DatabaseStorage) - - nodeStorage, nodeStatusStorage := nodeetcd.NewREST(c.DatabaseStorage, c.EnableWatchCache, c.KubeletClient, m.proxyTransport) + nodeStorage, nodeStatusStorage := nodeetcd.NewREST(dbClient("nodes"), c.EnableWatchCache, c.KubeletClient, m.proxyTransport) m.nodeRegistry = node.NewRegistry(nodeStorage) - serviceStorage := serviceetcd.NewREST(c.DatabaseStorage) + serviceStorage := serviceetcd.NewREST(dbClient("services")) m.serviceRegistry = service.NewRegistry(serviceStorage) var serviceClusterIPRegistry service.RangeRegistry serviceClusterIPAllocator := ipallocator.NewAllocatorCIDRRange(m.serviceClusterIPRange, func(max int, rangeSpec string) allocator.Interface { mem := allocator.NewAllocationMap(max, rangeSpec) - etcd := etcdallocator.NewEtcd(mem, "/ranges/serviceips", "serviceipallocation", c.DatabaseStorage) + etcd := etcdallocator.NewEtcd(mem, "/ranges/serviceips", "serviceipallocation", dbClient("services")) serviceClusterIPRegistry = etcd return etcd }) @@ -502,13 +568,13 @@ func (m *Master) init(c *Config) { var serviceNodePortRegistry service.RangeRegistry serviceNodePortAllocator := portallocator.NewPortAllocatorCustom(m.serviceNodePortRange, func(max int, rangeSpec string) allocator.Interface { mem := allocator.NewAllocationMap(max, rangeSpec) - etcd := etcdallocator.NewEtcd(mem, "/ranges/servicenodeports", "servicenodeportallocation", c.DatabaseStorage) + etcd := etcdallocator.NewEtcd(mem, "/ranges/servicenodeports", "servicenodeportallocation", dbClient("services")) serviceNodePortRegistry = etcd return etcd }) m.serviceNodePortAllocator = serviceNodePortRegistry - controllerStorage := controlleretcd.NewREST(c.DatabaseStorage) + controllerStorage, controllerStatusStorage := controlleretcd.NewREST(dbClient("replicationControllers")) // TODO: Factor out the core API registration m.storage = map[string]rest.Storage{ @@ -524,12 +590,13 @@ func (m *Master) init(c *Config) { "podTemplates": podTemplateStorage, - "replicationControllers": controllerStorage, - "services": service.NewStorage(m.serviceRegistry, m.endpointRegistry, serviceClusterIPAllocator, serviceNodePortAllocator, m.proxyTransport), - "endpoints": endpointsStorage, - "nodes": nodeStorage, - "nodes/status": nodeStatusStorage, - "events": eventStorage, + "replicationControllers": controllerStorage, + "replicationControllers/status": controllerStatusStorage, + "services": service.NewStorage(m.serviceRegistry, m.endpointRegistry, serviceClusterIPAllocator, serviceNodePortAllocator, m.proxyTransport), + "endpoints": endpointsStorage, + "nodes": nodeStorage, + "nodes/status": nodeStatusStorage, + "events": eventStorage, "limitRanges": limitRangeStorage, "resourceQuotas": resourceQuotaStorage, @@ -539,7 +606,6 @@ func (m *Master) init(c *Config) { "namespaces/finalize": namespaceFinalizeStorage, "secrets": secretStorage, "serviceAccounts": serviceAccountStorage, - "securityContextConstraints": securityContextConstraintsStorage, "persistentVolumes": persistentVolumeStorage, "persistentVolumes/status": persistentVolumeStatusStorage, "persistentVolumeClaims": persistentVolumeClaimStorage, @@ -558,12 +624,6 @@ func (m *Master) init(c *Config) { } apiVersions := []string{} - if m.v1beta3 { - if err := m.api_v1beta3().InstallREST(m.handlerContainer); err != nil { - glog.Fatalf("Unable to setup API v1beta3: %v", err) - } - apiVersions = append(apiVersions, "v1beta3") - } if m.v1 { if err := m.api_v1().InstallREST(m.handlerContainer); err != nil { glog.Fatalf("Unable to setup API v1: %v", err) @@ -573,20 +633,47 @@ func (m *Master) init(c *Config) { apiserver.InstallSupport(m.muxHelper, m.rootWebService, c.EnableProfiling, healthzChecks...) apiserver.AddApiWebService(m.handlerContainer, c.APIPrefix, apiVersions) - defaultVersion := m.defaultAPIGroupVersion() - requestInfoResolver := &apiserver.APIRequestInfoResolver{APIPrefixes: sets.NewString(strings.TrimPrefix(defaultVersion.Root, "/")), RestMapper: defaultVersion.Mapper} - apiserver.InstallServiceErrorHandler(m.handlerContainer, requestInfoResolver, apiVersions) + apiserver.InstallServiceErrorHandler(m.handlerContainer, m.newAPIRequestInfoResolver(), apiVersions) + // allGroups records all supported groups at /apis + allGroups := []unversioned.APIGroup{} if m.exp { + m.thirdPartyStorage = c.StorageDestinations.APIGroups["extensions"].Default + m.thirdPartyResources = map[string]*thirdpartyresourcedataetcd.REST{} + expVersion := m.experimental(c) + if err := expVersion.InstallREST(m.handlerContainer); err != nil { glog.Fatalf("Unable to setup experimental api: %v", err) } - apiserver.AddApiWebService(m.handlerContainer, c.ExpAPIPrefix, []string{expVersion.Version}) - expRequestInfoResolver := &apiserver.APIRequestInfoResolver{APIPrefixes: sets.NewString(strings.TrimPrefix(expVersion.Root, "/")), RestMapper: expVersion.Mapper} - apiserver.InstallServiceErrorHandler(m.handlerContainer, expRequestInfoResolver, []string{expVersion.Version}) + g, err := latest.Group("extensions") + if err != nil { + glog.Fatalf("Unable to setup experimental api: %v", err) + } + expAPIVersions := []unversioned.GroupVersion{ + { + GroupVersion: expVersion.Version, + Version: apiutil.GetVersion(expVersion.Version), + }, + } + storageVersion, found := c.StorageVersions[g.Group] + if !found { + glog.Fatalf("Couldn't find storage version of group %v", g.Group) + } + group := unversioned.APIGroup{ + Name: g.Group, + Versions: expAPIVersions, + PreferredVersion: unversioned.GroupVersion{GroupVersion: storageVersion, Version: apiutil.GetVersion(storageVersion)}, + } + apiserver.AddGroupWebService(m.handlerContainer, c.APIGroupPrefix+"/"+latest.GroupOrDie("extensions").Group+"/", group) + allGroups = append(allGroups, group) + apiserver.InstallServiceErrorHandler(m.handlerContainer, m.newAPIRequestInfoResolver(), []string{expVersion.Version}) } + // This should be done after all groups are registered + // TODO: replace the hardcoded "apis". + apiserver.AddApisWebService(m.handlerContainer, "/apis", allGroups) + // Register root handler. // We do not register this using restful Webservice since we do not want to surface this in api docs. // Allow master to be embedded in contexts which already have something registered at the root @@ -597,9 +684,9 @@ func (m *Master) init(c *Config) { if c.EnableLogsSupport { apiserver.InstallLogsSupport(m.muxHelper) } - /*if c.EnableUISupport { - ui.InstallSupport(m.mux) - }*/ + if c.EnableUISupport { + ui.InstallSupport(m.muxHelper, m.enableSwaggerSupport) + } if c.EnableProfiling { m.mux.HandleFunc("/debug/pprof/", pprof.Index) @@ -623,7 +710,7 @@ func (m *Master) init(c *Config) { m.InsecureHandler = handler - attributeGetter := apiserver.NewRequestAttributeGetter(m.requestContextMapper, latest.RESTMapper, "api") + attributeGetter := apiserver.NewRequestAttributeGetter(m.requestContextMapper, m.newAPIRequestInfoResolver()) handler = apiserver.WithAuthorizationCheck(handler, attributeGetter, m.authorizer) // Install Authenticator @@ -727,7 +814,8 @@ func (m *Master) getServersToValidate(c *Config) map[string]apiserver.Server { "controller-manager": {Addr: "127.0.0.1", Port: ports.ControllerManagerPort, Path: "/healthz"}, "scheduler": {Addr: "127.0.0.1", Port: ports.SchedulerPort, Path: "/healthz"}, } - for ix, machine := range c.DatabaseStorage.Backends() { + + for ix, machine := range c.StorageDestinations.backends() { etcdUrl, err := url.Parse(machine) if err != nil { glog.Errorf("Failed to parse etcd url for validation: %v", err) @@ -752,16 +840,24 @@ func (m *Master) getServersToValidate(c *Config) map[string]apiserver.Server { return serversToValidate } +func (m *Master) newAPIRequestInfoResolver() *apiserver.APIRequestInfoResolver { + return &apiserver.APIRequestInfoResolver{ + sets.NewString(strings.Trim(m.apiPrefix, "/"), strings.Trim(thirdpartyprefix, "/")), // all possible API prefixes + sets.NewString(strings.Trim(m.apiPrefix, "/")), // APIPrefixes that won't have groups (legacy) + } +} + func (m *Master) defaultAPIGroupVersion() *apiserver.APIGroupVersion { return &apiserver.APIGroupVersion{ Root: m.apiPrefix, + APIRequestInfoResolver: m.newAPIRequestInfoResolver(), - Mapper: latest.RESTMapper, + Mapper: latest.GroupOrDie("").RESTMapper, Creater: api.Scheme, Convertor: api.Scheme, Typer: api.Scheme, - Linker: latest.SelfLinker, + Linker: latest.GroupOrDie("").SelfLinker, Admit: m.admissionControl, Context: m.requestContextMapper, @@ -770,22 +866,6 @@ func (m *Master) defaultAPIGroupVersion() *apiserver.APIGroupVersion { } } -// api_v1beta3 returns the resources and codec for API version v1beta3. -func (m *Master) api_v1beta3() *apiserver.APIGroupVersion { - storage := make(map[string]rest.Storage) - for k, v := range m.storage { - if k == "minions" || k == "minions/status" { - continue - } - storage[strings.ToLower(k)] = v - } - version := m.defaultAPIGroupVersion() - version.Storage = storage - version.Version = "v1beta3" - version.Codec = v1beta3.Codec - return version -} - // api_v1 returns the resources and codec for API version v1. func (m *Master) api_v1() *apiserver.APIGroupVersion { storage := make(map[string]rest.Storage) @@ -799,7 +879,95 @@ func (m *Master) api_v1() *apiserver.APIGroupVersion { return version } -func (m *Master) InstallThirdPartyAPI(rsrc *experimental.ThirdPartyResource) error { +// HasThirdPartyResource returns true if a particular third party resource currently installed. +func (m *Master) HasThirdPartyResource(rsrc *expapi.ThirdPartyResource) (bool, error) { + _, group, err := thirdpartyresourcedata.ExtractApiGroupAndKind(rsrc) + if err != nil { + return false, err + } + path := makeThirdPartyPath(group) + services := m.handlerContainer.RegisteredWebServices() + for ix := range services { + if services[ix].RootPath() == path { + return true, nil + } + } + return false, nil +} + +func (m *Master) removeThirdPartyStorage(path string) error { + m.thirdPartyResourcesLock.Lock() + defer m.thirdPartyResourcesLock.Unlock() + storage, found := m.thirdPartyResources[path] + if found { + if err := m.removeAllThirdPartyResources(storage); err != nil { + return err + } + delete(m.thirdPartyResources, path) + } + return nil +} + +// RemoveThirdPartyResource removes all resources matching `path`. Also deletes any stored data +func (m *Master) RemoveThirdPartyResource(path string) error { + if err := m.removeThirdPartyStorage(path); err != nil { + return err + } + + services := m.handlerContainer.RegisteredWebServices() + for ix := range services { + root := services[ix].RootPath() + if root == path || strings.HasPrefix(root, path+"/") { + m.handlerContainer.Remove(services[ix]) + } + } + return nil +} + +func (m *Master) removeAllThirdPartyResources(registry *thirdpartyresourcedataetcd.REST) error { + ctx := api.NewDefaultContext() + existingData, err := registry.List(ctx, labels.Everything(), fields.Everything()) + if err != nil { + return err + } + list, ok := existingData.(*expapi.ThirdPartyResourceDataList) + if !ok { + return fmt.Errorf("expected a *ThirdPartyResourceDataList, got %#v", list) + } + for ix := range list.Items { + item := &list.Items[ix] + if _, err := registry.Delete(ctx, item.Name, nil); err != nil { + return err + } + } + return nil +} + +// ListThirdPartyResources lists all currently installed third party resources +func (m *Master) ListThirdPartyResources() []string { + m.thirdPartyResourcesLock.RLock() + defer m.thirdPartyResourcesLock.RUnlock() + result := []string{} + for key := range m.thirdPartyResources { + result = append(result, key) + } + return result +} + +func (m *Master) addThirdPartyResourceStorage(path string, storage *thirdpartyresourcedataetcd.REST) { + m.thirdPartyResourcesLock.Lock() + defer m.thirdPartyResourcesLock.Unlock() + m.thirdPartyResources[path] = storage +} + +// InstallThirdPartyResource installs a third party resource specified by 'rsrc'. When a resource is +// installed a corresponding RESTful resource is added as a valid path in the web service provided by +// the master. +// +// For example, if you install a resource ThirdPartyResource{ Name: "foo.company.com", Versions: {"v1"} } +// then the following RESTful resource is created on the server: +// http:///apis/company.com/v1/foos/... +func (m *Master) InstallThirdPartyResource(rsrc *expapi.ThirdPartyResource) error { kind, group, err := thirdpartyresourcedata.ExtractApiGroupAndKind(rsrc) if err != nil { return err @@ -808,36 +976,45 @@ func (m *Master) InstallThirdPartyAPI(rsrc *experimental.ThirdPartyResource) err if err := thirdparty.InstallREST(m.handlerContainer); err != nil { glog.Fatalf("Unable to setup thirdparty api: %v", err) } - thirdPartyPrefix := "/thirdparty/" + group + "/" - apiserver.AddApiWebService(m.handlerContainer, thirdPartyPrefix, []string{rsrc.Versions[0].Name}) - thirdPartyRequestInfoResolver := &apiserver.APIRequestInfoResolver{APIPrefixes: sets.NewString(strings.TrimPrefix(group, "/")), RestMapper: thirdparty.Mapper} - apiserver.InstallServiceErrorHandler(m.handlerContainer, thirdPartyRequestInfoResolver, []string{thirdparty.Version}) + path := makeThirdPartyPath(group) + groupVersion := unversioned.GroupVersion{ + GroupVersion: group + "/" + rsrc.Versions[0].Name, + Version: rsrc.Versions[0].Name, + } + apiGroup := unversioned.APIGroup{ + Name: group, + Versions: []unversioned.GroupVersion{groupVersion}, + } + apiserver.AddGroupWebService(m.handlerContainer, path, apiGroup) + m.addThirdPartyResourceStorage(path, thirdparty.Storage[strings.ToLower(kind)+"s"].(*thirdpartyresourcedataetcd.REST)) + apiserver.InstallServiceErrorHandler(m.handlerContainer, m.newAPIRequestInfoResolver(), []string{thirdparty.Version}) return nil } func (m *Master) thirdpartyapi(group, kind, version string) *apiserver.APIGroupVersion { resourceStorage := thirdpartyresourcedataetcd.NewREST(m.thirdPartyStorage, group, kind) - apiRoot := "/thirdparty/" + group + "/" + apiRoot := makeThirdPartyPath("") storage := map[string]rest.Storage{ strings.ToLower(kind) + "s": resourceStorage, } return &apiserver.APIGroupVersion{ - Root: apiRoot, + Root: apiRoot, + Version: apiutil.GetGroupVersion(group, version), + APIRequestInfoResolver: m.newAPIRequestInfoResolver(), - Creater: thirdpartyresourcedata.NewObjectCreator(version, api.Scheme), + Creater: thirdpartyresourcedata.NewObjectCreator(group, version, api.Scheme), Convertor: api.Scheme, Typer: api.Scheme, - Mapper: thirdpartyresourcedata.NewMapper(explatest.RESTMapper, kind, version), - Codec: explatest.Codec, - Linker: explatest.SelfLinker, - Storage: storage, - Version: version, + Mapper: thirdpartyresourcedata.NewMapper(latest.GroupOrDie("extensions").RESTMapper, kind, version, group), + Codec: thirdpartyresourcedata.NewCodec(latest.GroupOrDie("extensions").Codec, kind), + Linker: latest.GroupOrDie("extensions").SelfLinker, + Storage: storage, + ServerVersion: latest.GroupOrDie("").GroupVersion, - Admit: m.admissionControl, Context: m.requestContextMapper, MinRequestTimeout: m.minRequestTimeout, @@ -846,35 +1023,59 @@ func (m *Master) thirdpartyapi(group, kind, version string) *apiserver.APIGroupV // experimental returns the resources and codec for the experimental api func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion { - controllerStorage := expcontrolleretcd.NewStorage(c.ExpDatabaseStorage) - autoscalerStorage := horizontalpodautoscaleretcd.NewREST(c.ExpDatabaseStorage) - thirdPartyResourceStorage := thirdpartyresourceetcd.NewREST(c.ExpDatabaseStorage) - daemonSetStorage := daemonetcd.NewREST(c.ExpDatabaseStorage) - deploymentStorage := deploymentetcd.NewREST(c.ExpDatabaseStorage) - jobStorage := jobetcd.NewREST(c.ExpDatabaseStorage) - + controllerStorage := expcontrolleretcd.NewStorage(c.StorageDestinations.get("", "replicationControllers")) + dbClient := func(resource string) storage.Interface { + return c.StorageDestinations.get("extensions", resource) + } + autoscalerStorage, autoscalerStatusStorage := horizontalpodautoscaleretcd.NewREST(dbClient("horizonalpodautoscalers")) + thirdPartyResourceStorage := thirdpartyresourceetcd.NewREST(dbClient("thirdpartyresources")) + daemonSetStorage, daemonSetStatusStorage := daemonetcd.NewREST(dbClient("daemonsets")) + deploymentStorage := deploymentetcd.NewStorage(dbClient("deployments")) + jobStorage, jobStatusStorage := jobetcd.NewREST(dbClient("jobs")) + ingressStorage := ingressetcd.NewREST(dbClient("ingress")) + + thirdPartyControl := ThirdPartyController{ + master: m, + thirdPartyResourceRegistry: thirdPartyResourceStorage, + } + go func() { + util.Forever(func() { + if err := thirdPartyControl.SyncResources(); err != nil { + glog.Warningf("third party resource sync failed: %v", err) + } + }, 10*time.Second) + }() storage := map[string]rest.Storage{ - strings.ToLower("replicationControllers"): controllerStorage.ReplicationController, - strings.ToLower("replicationControllers/scale"): controllerStorage.Scale, - strings.ToLower("horizontalpodautoscalers"): autoscalerStorage, - strings.ToLower("thirdpartyresources"): thirdPartyResourceStorage, - strings.ToLower("daemonsets"): daemonSetStorage, - strings.ToLower("deployments"): deploymentStorage, - strings.ToLower("jobs"): jobStorage, + strings.ToLower("replicationControllers"): controllerStorage.ReplicationController, + strings.ToLower("replicationControllers/scale"): controllerStorage.Scale, + strings.ToLower("horizontalpodautoscalers"): autoscalerStorage, + strings.ToLower("horizontalpodautoscalers/status"): autoscalerStatusStorage, + strings.ToLower("thirdpartyresources"): thirdPartyResourceStorage, + strings.ToLower("daemonsets"): daemonSetStorage, + strings.ToLower("daemonsets/status"): daemonSetStatusStorage, + strings.ToLower("deployments"): deploymentStorage.Deployment, + strings.ToLower("deployments/scale"): deploymentStorage.Scale, + strings.ToLower("jobs"): jobStorage, + strings.ToLower("jobs/status"): jobStatusStorage, + strings.ToLower("ingress"): ingressStorage, } + expMeta := latest.GroupOrDie("extensions") + return &apiserver.APIGroupVersion{ - Root: m.expAPIPrefix, + Root: m.apiGroupPrefix, + APIRequestInfoResolver: m.newAPIRequestInfoResolver(), Creater: api.Scheme, Convertor: api.Scheme, Typer: api.Scheme, - Mapper: explatest.RESTMapper, - Codec: explatest.Codec, - Linker: explatest.SelfLinker, - Storage: storage, - Version: explatest.Version, + Mapper: expMeta.RESTMapper, + Codec: expMeta.Codec, + Linker: expMeta.SelfLinker, + Storage: storage, + Version: expMeta.GroupVersion, + ServerVersion: latest.GroupOrDie("").GroupVersion, Admit: m.admissionControl, Context: m.requestContextMapper, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master_test.go index 16f9dd6e3908..ba393f7d9b9e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master_test.go @@ -26,18 +26,18 @@ import ( "net" "net/http" "net/http/httptest" - "os" "reflect" + "strings" "testing" - "github.com/emicklei/go-restful" - "github.com/stretchr/testify/assert" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" + apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/api/v1" - "k8s.io/kubernetes/pkg/apis/experimental" - explatest "k8s.io/kubernetes/pkg/apis/experimental/latest" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apiserver" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" @@ -45,10 +45,15 @@ import ( "k8s.io/kubernetes/pkg/registry/endpoint" "k8s.io/kubernetes/pkg/registry/namespace" "k8s.io/kubernetes/pkg/registry/registrytest" + thirdpartyresourcedatastorage "k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/etcd" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" "k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/util" + + "github.com/coreos/go-etcd/etcd" + "github.com/emicklei/go-restful" + "github.com/stretchr/testify/assert" ) // setUp is a convience function for setting up for (most) tests. @@ -57,9 +62,14 @@ func setUp(t *testing.T) (Master, Config, *assert.Assertions) { config := Config{} fakeClient := tools.NewFakeEtcdClient(t) fakeClient.Machines = []string{"http://machine1:4001", "http://machine2", "http://machine3:4003"} - config.DatabaseStorage = etcdstorage.NewEtcdStorage(fakeClient, latest.Codec, etcdtest.PathPrefix()) - config.ExpDatabaseStorage = etcdstorage.NewEtcdStorage(fakeClient, explatest.Codec, etcdtest.PathPrefix()) - + storageVersions := make(map[string]string) + storageDestinations := NewStorageDestinations() + storageDestinations.AddAPIGroup("", etcdstorage.NewEtcdStorage(fakeClient, testapi.Default.Codec(), etcdtest.PathPrefix())) + storageDestinations.AddAPIGroup("extensions", etcdstorage.NewEtcdStorage(fakeClient, testapi.Extensions.Codec(), etcdtest.PathPrefix())) + config.StorageDestinations = storageDestinations + storageVersions[""] = testapi.Default.Version() + storageVersions["extensions"] = testapi.Extensions.GroupAndVersion() + config.StorageVersions = storageVersions master.nodeRegistry = registrytest.NewNodeRegistry([]string{"node1", "node2"}, api.NodeResources{}) return master, config, assert.New(t) @@ -68,8 +78,6 @@ func setUp(t *testing.T) (Master, Config, *assert.Assertions) { // TestNew verifies that the New function returns a Master // using the configuration properly. func TestNew(t *testing.T) { - os.Setenv("ETCD_PREFIX", "thirdparty") - _, config, assert := setUp(t) config.KubeletClient = client.FakeKubeletClient{} @@ -87,7 +95,7 @@ func TestNew(t *testing.T) { assert.Equal(master.enableSwaggerSupport, config.EnableSwaggerSupport) assert.Equal(master.enableProfiling, config.EnableProfiling) assert.Equal(master.apiPrefix, config.APIPrefix) - assert.Equal(master.expAPIPrefix, config.ExpAPIPrefix) + assert.Equal(master.apiGroupPrefix, config.APIGroupPrefix) assert.Equal(master.corsAllowedOriginList, config.CorsAllowedOriginList) assert.Equal(master.authenticator, config.Authenticator) assert.Equal(master.authorizer, config.Authorizer) @@ -118,12 +126,12 @@ func TestNewEtcdStorage(t *testing.T) { assert := assert.New(t) fakeClient := tools.NewFakeEtcdClient(t) // Pass case - _, err := NewEtcdStorage(fakeClient, latest.InterfacesFor, latest.Version, etcdtest.PathPrefix()) + _, err := NewEtcdStorage(fakeClient, latest.GroupOrDie("").InterfacesFor, testapi.Default.Version(), etcdtest.PathPrefix()) assert.NoError(err, "Unable to create etcdstorage: %s", err) // Fail case errorFunc := func(apiVersion string) (*meta.VersionInterfaces, error) { return nil, errors.New("ERROR") } - _, err = NewEtcdStorage(fakeClient, errorFunc, latest.Version, etcdtest.PathPrefix()) + _, err = NewEtcdStorage(fakeClient, errorFunc, testapi.Default.Version(), etcdtest.PathPrefix()) assert.Error(err, "NewEtcdStorage should have failed") } @@ -313,16 +321,16 @@ func TestDefaultAPIGroupVersion(t *testing.T) { } // TestExpapi verifies that the unexported exapi creates -// the an experimental api APIGroupVersion. +// the an experimental unversioned.APIGroupVersion. func TestExpapi(t *testing.T) { master, config, assert := setUp(t) expAPIGroup := master.experimental(&config) - assert.Equal(expAPIGroup.Root, master.expAPIPrefix) - assert.Equal(expAPIGroup.Mapper, explatest.RESTMapper) - assert.Equal(expAPIGroup.Codec, explatest.Codec) - assert.Equal(expAPIGroup.Linker, explatest.SelfLinker) - assert.Equal(expAPIGroup.Version, explatest.Version) + assert.Equal(expAPIGroup.Root, master.apiGroupPrefix) + assert.Equal(expAPIGroup.Mapper, latest.GroupOrDie("extensions").RESTMapper) + assert.Equal(expAPIGroup.Codec, latest.GroupOrDie("extensions").Codec) + assert.Equal(expAPIGroup.Linker, latest.GroupOrDie("extensions").SelfLinker) + assert.Equal(expAPIGroup.Version, latest.GroupOrDie("extensions").GroupVersion) } // TestGetNodeAddresses verifies that proper results are returned @@ -356,31 +364,85 @@ func TestGetNodeAddresses(t *testing.T) { assert.Equal([]string{"127.0.0.2", "127.0.0.2"}, addrs) } +func TestDiscoveryAtAPIS(t *testing.T) { + master, config, assert := setUp(t) + master.exp = true + // ================= preparation for master.init() ====================== + portRange := util.PortRange{Base: 10, Size: 10} + master.serviceNodePortRange = portRange + + _, ipnet, err := net.ParseCIDR("192.168.1.1/24") + if !assert.NoError(err) { + t.Errorf("unexpected error: %v", err) + } + master.serviceClusterIPRange = ipnet + + mh := apiserver.MuxHelper{Mux: http.NewServeMux()} + master.muxHelper = &mh + master.rootWebService = new(restful.WebService) + + master.handlerContainer = restful.NewContainer() + + master.mux = http.NewServeMux() + master.requestContextMapper = api.NewRequestContextMapper() + // ======================= end of preparation =========================== + + master.init(&config) + server := httptest.NewServer(master.handlerContainer.ServeMux) + resp, err := http.Get(server.URL + "/apis") + if !assert.NoError(err) { + t.Errorf("unexpected error: %v", err) + } + + assert.Equal(http.StatusOK, resp.StatusCode) + + groupList := unversioned.APIGroupList{} + assert.NoError(decodeResponse(resp, &groupList)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + expectGroupName := "extensions" + expectVersions := []unversioned.GroupVersion{ + { + GroupVersion: testapi.Extensions.GroupAndVersion(), + Version: testapi.Extensions.Version(), + }, + } + expectPreferredVersion := unversioned.GroupVersion{ + GroupVersion: config.StorageVersions["extensions"], + Version: apiutil.GetVersion(config.StorageVersions["extensions"]), + } + assert.Equal(expectGroupName, groupList.Groups[0].Name) + assert.Equal(expectVersions, groupList.Groups[0].Versions) + assert.Equal(expectPreferredVersion, groupList.Groups[0].PreferredVersion) +} + var versionsToTest = []string{"v1", "v3"} type Foo struct { - api.TypeMeta `json:",inline"` - api.ObjectMeta `json:"metadata,omitempty" description:"standard object metadata"` + unversioned.TypeMeta `json:",inline"` + api.ObjectMeta `json:"metadata,omitempty" description:"standard object metadata"` SomeField string `json:"someField"` OtherField int `json:"otherField"` } type FooList struct { - api.TypeMeta `json:",inline"` - api.ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://docs.k8s.io/api-conventions.md#metadata"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata"` - items []Foo `json:"items"` + Items []Foo `json:"items"` } -func initThirdParty(t *testing.T, version string) (*tools.FakeEtcdClient, *httptest.Server, *assert.Assertions) { +func initThirdParty(t *testing.T, version string) (*Master, *tools.FakeEtcdClient, *httptest.Server, *assert.Assertions) { master, _, assert := setUp(t) - - api := &experimental.ThirdPartyResource{ + master.thirdPartyResources = map[string]*thirdpartyresourcedatastorage.REST{} + api := &extensions.ThirdPartyResource{ ObjectMeta: api.ObjectMeta{ Name: "foo.company.com", }, - Versions: []experimental.APIVersion{ + Versions: []extensions.APIVersion{ { APIGroup: "group", Name: version, @@ -391,14 +453,14 @@ func initThirdParty(t *testing.T, version string) (*tools.FakeEtcdClient, *httpt fakeClient := tools.NewFakeEtcdClient(t) fakeClient.Machines = []string{"http://machine1:4001", "http://machine2", "http://machine3:4003"} - master.thirdPartyStorage = etcdstorage.NewEtcdStorage(fakeClient, explatest.Codec, etcdtest.PathPrefix()) + master.thirdPartyStorage = etcdstorage.NewEtcdStorage(fakeClient, testapi.Extensions.Codec(), etcdtest.PathPrefix()) - if !assert.NoError(master.InstallThirdPartyAPI(api)) { + if !assert.NoError(master.InstallThirdPartyResource(api)) { t.FailNow() } server := httptest.NewServer(master.handlerContainer.ServeMux) - return fakeClient, server, assert + return &master, fakeClient, server, assert } func TestInstallThirdPartyAPIList(t *testing.T) { @@ -408,27 +470,90 @@ func TestInstallThirdPartyAPIList(t *testing.T) { } func testInstallThirdPartyAPIListVersion(t *testing.T, version string) { - fakeClient, server, assert := initThirdParty(t, version) - defer server.Close() + tests := []struct { + items []Foo + }{ + {}, + { + items: []Foo{}, + }, + { + items: []Foo{ + { + ObjectMeta: api.ObjectMeta{ + Name: "test", + }, + TypeMeta: unversioned.TypeMeta{ + Kind: "Foo", + APIVersion: version, + }, + SomeField: "test field", + OtherField: 10, + }, + { + ObjectMeta: api.ObjectMeta{ + Name: "bar", + }, + TypeMeta: unversioned.TypeMeta{ + Kind: "Foo", + APIVersion: version, + }, + SomeField: "test field another", + OtherField: 20, + }, + }, + }, + } + for _, test := range tests { + _, fakeClient, server, assert := initThirdParty(t, version) + defer server.Close() - fakeClient.ExpectNotFoundGet(etcdtest.PathPrefix() + "/ThirdPartyResourceData/company.com/foos/default") + if test.items == nil { + fakeClient.ExpectNotFoundGet(etcdtest.PathPrefix() + "/ThirdPartyResourceData/company.com/foos/default") + } else { + setupEtcdList(fakeClient, "/ThirdPartyResourceData/company.com/foos/default", test.items) + } - resp, err := http.Get(server.URL + "/thirdparty/company.com/" + version + "/namespaces/default/foos") - if !assert.NoError(err) { - return - } + resp, err := http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos") + if !assert.NoError(err) { + return + } + defer resp.Body.Close() - defer resp.Body.Close() + assert.Equal(http.StatusOK, resp.StatusCode) - assert.Equal(http.StatusOK, resp.StatusCode) + data, err := ioutil.ReadAll(resp.Body) + assert.NoError(err) - data, err := ioutil.ReadAll(resp.Body) - assert.NoError(err) + list := FooList{} + if err = json.Unmarshal(data, &list); err != nil { + t.Errorf("unexpected error: %v", err) + } - list := FooList{} - err = json.Unmarshal(data, &list) - assert.NoError(err) + if test.items == nil { + if len(list.Items) != 0 { + t.Errorf("expected no items, saw: %v", list.Items) + } + continue + } + if len(list.Items) != len(test.items) { + t.Errorf("unexpected length: %d vs %d", len(list.Items), len(test.items)) + continue + } + for ix := range list.Items { + // Copy things that are set dynamically on the server + expectedObj := test.items[ix] + expectedObj.SelfLink = list.Items[ix].SelfLink + expectedObj.Namespace = list.Items[ix].Namespace + expectedObj.UID = list.Items[ix].UID + expectedObj.CreationTimestamp = list.Items[ix].CreationTimestamp + + if !reflect.DeepEqual(list.Items[ix], expectedObj) { + t.Errorf("expected:\n%#v\nsaw:\n%#v\n", expectedObj, list.Items[ix]) + } + } + } } func encodeToThirdParty(name string, obj interface{}) ([]byte, error) { @@ -436,11 +561,11 @@ func encodeToThirdParty(name string, obj interface{}) ([]byte, error) { if err != nil { return nil, err } - thirdPartyData := experimental.ThirdPartyResourceData{ + thirdPartyData := extensions.ThirdPartyResourceData{ ObjectMeta: api.ObjectMeta{Name: name}, Data: serial, } - return latest.Codec.Encode(&thirdPartyData) + return testapi.Extensions.Codec().Encode(&thirdPartyData) } func storeToEtcd(fakeClient *tools.FakeEtcdClient, path, name string, obj interface{}) error { @@ -452,6 +577,23 @@ func storeToEtcd(fakeClient *tools.FakeEtcdClient, path, name string, obj interf return err } +func setupEtcdList(fakeClient *tools.FakeEtcdClient, path string, list []Foo) error { + resp := tools.EtcdResponseWithError{ + R: &etcd.Response{ + Node: &etcd.Node{}, + }, + } + for _, obj := range list { + data, err := encodeToThirdParty(obj.Name, obj) + if err != nil { + return err + } + resp.R.Node.Nodes = append(resp.R.Node.Nodes, &etcd.Node{Value: string(data)}) + } + fakeClient.Data[etcdtest.PathPrefix()+path] = resp + return nil +} + func decodeResponse(resp *http.Response, obj interface{}) error { defer resp.Body.Close() @@ -473,14 +615,14 @@ func TestInstallThirdPartyAPIGet(t *testing.T) { } func testInstallThirdPartyAPIGetVersion(t *testing.T, version string) { - fakeClient, server, assert := initThirdParty(t, version) + _, fakeClient, server, assert := initThirdParty(t, version) defer server.Close() expectedObj := Foo{ ObjectMeta: api.ObjectMeta{ Name: "test", }, - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Foo", APIVersion: version, }, @@ -492,7 +634,7 @@ func testInstallThirdPartyAPIGetVersion(t *testing.T, version string) { return } - resp, err := http.Get(server.URL + "/thirdparty/company.com/" + version + "/namespaces/default/foos/test") + resp, err := http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test") if !assert.NoError(err) { return } @@ -518,16 +660,16 @@ func TestInstallThirdPartyAPIPost(t *testing.T) { } func testInstallThirdPartyAPIPostForVersion(t *testing.T, version string) { - fakeClient, server, assert := initThirdParty(t, version) + _, fakeClient, server, assert := initThirdParty(t, version) defer server.Close() inputObj := Foo{ ObjectMeta: api.ObjectMeta{ Name: "test", }, - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Foo", - APIVersion: version, + APIVersion: "company.com/" + version, }, SomeField: "test field", OtherField: 10, @@ -537,8 +679,9 @@ func testInstallThirdPartyAPIPostForVersion(t *testing.T, version string) { return } - resp, err := http.Post(server.URL+"/thirdparty/company.com/"+version+"/namespaces/default/foos", "application/json", bytes.NewBuffer(data)) + resp, err := http.Post(server.URL+"/apis/company.com/"+version+"/namespaces/default/foos", "application/json", bytes.NewBuffer(data)) if !assert.NoError(err) { + t.Errorf("unexpected error: %v", err) return } @@ -562,11 +705,12 @@ func testInstallThirdPartyAPIPostForVersion(t *testing.T, version string) { t.FailNow() } - obj, err := explatest.Codec.Decode([]byte(etcdResp.Node.Value)) - assert.NoError(err) - - thirdPartyObj, ok := obj.(*experimental.ThirdPartyResourceData) - if !assert.True(ok) { + obj, err := testapi.Extensions.Codec().Decode([]byte(etcdResp.Node.Value)) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + thirdPartyObj, ok := obj.(*extensions.ThirdPartyResourceData) + if !ok { t.Errorf("unexpected object: %v", obj) } item = Foo{} @@ -584,7 +728,7 @@ func TestInstallThirdPartyAPIDelete(t *testing.T) { } func testInstallThirdPartyAPIDeleteVersion(t *testing.T, version string) { - fakeClient, server, assert := initThirdParty(t, version) + _, fakeClient, server, assert := initThirdParty(t, version) defer server.Close() expectedObj := Foo{ @@ -592,7 +736,7 @@ func testInstallThirdPartyAPIDeleteVersion(t *testing.T, version string) { Name: "test", Namespace: "default", }, - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Foo", }, SomeField: "test field", @@ -603,7 +747,7 @@ func testInstallThirdPartyAPIDeleteVersion(t *testing.T, version string) { return } - resp, err := http.Get(server.URL + "/thirdparty/company.com/" + version + "/namespaces/default/foos/test") + resp, err := http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test") if !assert.NoError(err) { return } @@ -620,14 +764,14 @@ func testInstallThirdPartyAPIDeleteVersion(t *testing.T, version string) { t.Errorf("expected:\n%v\nsaw:\n%v\n", expectedObj, item) } - resp, err = httpDelete(server.URL + "/thirdparty/company.com/" + version + "/namespaces/default/foos/test") + resp, err = httpDelete(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test") if !assert.NoError(err) { return } assert.Equal(http.StatusOK, resp.StatusCode) - resp, err = http.Get(server.URL + "/thirdparty/company.com/" + version + "/namespaces/default/foos/test") + resp, err = http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test") if !assert.NoError(err) { return } @@ -649,3 +793,88 @@ func httpDelete(url string) (*http.Response, error) { client := &http.Client{} return client.Do(req) } + +func TestInstallThirdPartyResourceRemove(t *testing.T) { + for _, version := range versionsToTest { + testInstallThirdPartyResourceRemove(t, version) + } +} + +func testInstallThirdPartyResourceRemove(t *testing.T, version string) { + master, fakeClient, server, assert := initThirdParty(t, version) + defer server.Close() + + expectedObj := Foo{ + ObjectMeta: api.ObjectMeta{ + Name: "test", + }, + TypeMeta: unversioned.TypeMeta{ + Kind: "Foo", + }, + SomeField: "test field", + OtherField: 10, + } + if !assert.NoError(storeToEtcd(fakeClient, "/ThirdPartyResourceData/company.com/foos/default/test", "test", expectedObj)) { + t.FailNow() + return + } + secondObj := expectedObj + secondObj.Name = "bar" + if !assert.NoError(storeToEtcd(fakeClient, "/ThirdPartyResourceData/company.com/foos/default/bar", "bar", secondObj)) { + t.FailNow() + return + } + + setupEtcdList(fakeClient, "/ThirdPartyResourceData/company.com/foos/default", []Foo{expectedObj, secondObj}) + + resp, err := http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test") + if !assert.NoError(err) { + t.FailNow() + return + } + + if resp.StatusCode != http.StatusOK { + t.Errorf("unexpected status: %v", resp) + } + + item := Foo{} + if err := decodeResponse(resp, &item); err != nil { + t.Errorf("unexpected error: %v", err) + } + + // TODO: validate etcd set things here + item.ObjectMeta = expectedObj.ObjectMeta + + if !assert.True(reflect.DeepEqual(item, expectedObj)) { + t.Errorf("expected:\n%v\nsaw:\n%v\n", expectedObj, item) + } + + path := makeThirdPartyPath("company.com") + master.RemoveThirdPartyResource(path) + + resp, err = http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test") + if !assert.NoError(err) { + return + } + + if resp.StatusCode != http.StatusNotFound { + t.Errorf("unexpected status: %v", resp) + } + expectDeletedKeys := []string{ + etcdtest.PathPrefix() + "/ThirdPartyResourceData/company.com/foos/default/test", + etcdtest.PathPrefix() + "/ThirdPartyResourceData/company.com/foos/default/bar", + } + if !assert.True(reflect.DeepEqual(fakeClient.DeletedKeys, expectDeletedKeys)) { + t.Errorf("unexpected deleted keys: %v", fakeClient.DeletedKeys) + } + installed := master.ListThirdPartyResources() + if len(installed) != 0 { + t.Errorf("Resource(s) still installed: %v", installed) + } + services := master.handlerContainer.RegisteredWebServices() + for ix := range services { + if strings.HasPrefix(services[ix].RootPath(), "/apis/company.com") { + t.Errorf("Web service still installed at %s: %#v", services[ix].RootPath(), services[ix]) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/thirdparty_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/thirdparty_controller.go new file mode 100644 index 000000000000..806de9f45f4b --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/thirdparty_controller.go @@ -0,0 +1,128 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 master + +import ( + "fmt" + "strings" + + "k8s.io/kubernetes/pkg/api" + expapi "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + thirdpartyresourceetcd "k8s.io/kubernetes/pkg/registry/thirdpartyresource/etcd" + "k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/sets" +) + +const thirdpartyprefix = "/apis" + +func makeThirdPartyPath(group string) string { + if len(group) == 0 { + return thirdpartyprefix + } + return thirdpartyprefix + "/" + group +} + +// resourceInterface is the interface for the parts of the master that know how to add/remove +// third party resources. Extracted into an interface for injection for testing. +type resourceInterface interface { + // Remove a third party resource based on the RESTful path for that resource + RemoveThirdPartyResource(path string) error + // Install a third party resource described by 'rsrc' + InstallThirdPartyResource(rsrc *expapi.ThirdPartyResource) error + // Is a particular third party resource currently installed? + HasThirdPartyResource(rsrc *expapi.ThirdPartyResource) (bool, error) + // List all currently installed third party resources + ListThirdPartyResources() []string +} + +// ThirdPartyController is a control loop that knows how to synchronize ThirdPartyResource objects with +// RESTful resources which are present in the API server. +type ThirdPartyController struct { + master resourceInterface + thirdPartyResourceRegistry *thirdpartyresourceetcd.REST +} + +// Synchronize a single resource with RESTful resources on the master +func (t *ThirdPartyController) SyncOneResource(rsrc *expapi.ThirdPartyResource) error { + // TODO: we also need to test if the existing installed resource matches the resource we are sync-ing. + // Currently, if there is an older, incompatible resource installed, we won't remove it. We should detect + // older, incompatible resources and remove them before testing if the resource exists. + hasResource, err := t.master.HasThirdPartyResource(rsrc) + if err != nil { + return err + } + if !hasResource { + return t.master.InstallThirdPartyResource(rsrc) + } + return nil +} + +// Synchronize all resources with RESTful resources on the master +func (t *ThirdPartyController) SyncResources() error { + list, err := t.thirdPartyResourceRegistry.List(api.NewDefaultContext(), labels.Everything(), fields.Everything()) + if err != nil { + return err + } + return t.syncResourceList(list) +} + +func (t *ThirdPartyController) syncResourceList(list runtime.Object) error { + existing := sets.String{} + switch list := list.(type) { + case *expapi.ThirdPartyResourceList: + // Loop across all schema objects for third party resources + for ix := range list.Items { + item := &list.Items[ix] + // extract the api group and resource kind from the schema + _, group, err := thirdpartyresourcedata.ExtractApiGroupAndKind(item) + if err != nil { + return err + } + // place it in the set of resources that we expect, so that we don't delete it in the delete pass + existing.Insert(makeThirdPartyPath(group)) + // ensure a RESTful resource for this schema exists on the master + if err := t.SyncOneResource(item); err != nil { + return err + } + } + default: + return fmt.Errorf("expected a *ThirdPartyResourceList, got %#v", list) + } + // deletion phase, get all installed RESTful resources + installed := t.master.ListThirdPartyResources() + for _, installedAPI := range installed { + found := false + // search across the expected restful resources to see if this resource belongs to one of the expected ones + for _, apiPath := range existing.List() { + if installedAPI == apiPath || strings.HasPrefix(installedAPI, apiPath+"/") { + found = true + break + } + } + // not expected, delete the resource + if !found { + if err := t.master.RemoveThirdPartyResource(installedAPI); err != nil { + return err + } + } + } + + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/thirdparty_controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/thirdparty_controller_test.go new file mode 100644 index 000000000000..47f618a7e42a --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/thirdparty_controller_test.go @@ -0,0 +1,204 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 master + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + expapi "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata" + "k8s.io/kubernetes/pkg/util/sets" +) + +type FakeAPIInterface struct { + removed []string + installed []*expapi.ThirdPartyResource + apis []string + t *testing.T +} + +func (f *FakeAPIInterface) RemoveThirdPartyResource(path string) error { + f.removed = append(f.removed, path) + return nil +} + +func (f *FakeAPIInterface) InstallThirdPartyResource(rsrc *expapi.ThirdPartyResource) error { + f.installed = append(f.installed, rsrc) + _, group, _ := thirdpartyresourcedata.ExtractApiGroupAndKind(rsrc) + f.apis = append(f.apis, makeThirdPartyPath(group)) + return nil +} + +func (f *FakeAPIInterface) HasThirdPartyResource(rsrc *expapi.ThirdPartyResource) (bool, error) { + if f.apis == nil { + return false, nil + } + _, group, _ := thirdpartyresourcedata.ExtractApiGroupAndKind(rsrc) + path := makeThirdPartyPath(group) + for _, api := range f.apis { + if api == path { + return true, nil + } + } + return false, nil +} + +func (f *FakeAPIInterface) ListThirdPartyResources() []string { + return f.apis +} + +func TestSyncAPIs(t *testing.T) { + tests := []struct { + list *expapi.ThirdPartyResourceList + apis []string + expectedInstalled []string + expectedRemoved []string + name string + }{ + { + list: &expapi.ThirdPartyResourceList{ + Items: []expapi.ThirdPartyResource{ + { + ObjectMeta: api.ObjectMeta{ + Name: "foo.example.com", + }, + }, + }, + }, + expectedInstalled: []string{"foo.example.com"}, + name: "simple add", + }, + { + list: &expapi.ThirdPartyResourceList{ + Items: []expapi.ThirdPartyResource{ + { + ObjectMeta: api.ObjectMeta{ + Name: "foo.example.com", + }, + }, + }, + }, + apis: []string{ + "/apis/example.com", + "/apis/example.com/v1", + }, + name: "does nothing", + }, + { + list: &expapi.ThirdPartyResourceList{ + Items: []expapi.ThirdPartyResource{ + { + ObjectMeta: api.ObjectMeta{ + Name: "foo.example.com", + }, + }, + }, + }, + apis: []string{ + "/apis/example.com", + "/apis/example.com/v1", + "/apis/example.co", + "/apis/example.co/v1", + }, + name: "deletes substring API", + expectedRemoved: []string{ + "/apis/example.co", + "/apis/example.co/v1", + }, + }, + { + list: &expapi.ThirdPartyResourceList{ + Items: []expapi.ThirdPartyResource{ + { + ObjectMeta: api.ObjectMeta{ + Name: "foo.example.com", + }, + }, + { + ObjectMeta: api.ObjectMeta{ + Name: "foo.company.com", + }, + }, + }, + }, + apis: []string{ + "/apis/company.com", + "/apis/company.com/v1", + }, + expectedInstalled: []string{"foo.example.com"}, + name: "adds with existing", + }, + { + list: &expapi.ThirdPartyResourceList{ + Items: []expapi.ThirdPartyResource{ + { + ObjectMeta: api.ObjectMeta{ + Name: "foo.example.com", + }, + }, + }, + }, + apis: []string{ + "/apis/company.com", + "/apis/company.com/v1", + }, + expectedInstalled: []string{"foo.example.com"}, + expectedRemoved: []string{"/apis/company.com", "/apis/company.com/v1"}, + name: "removes with existing", + }, + } + + for _, test := range tests { + fake := FakeAPIInterface{ + apis: test.apis, + t: t, + } + + cntrl := ThirdPartyController{master: &fake} + + if err := cntrl.syncResourceList(test.list); err != nil { + t.Errorf("[%s] unexpected error: %v", test.name) + } + if len(test.expectedInstalled) != len(fake.installed) { + t.Errorf("[%s] unexpected installed APIs: %d, expected %d (%#v)", test.name, len(fake.installed), len(test.expectedInstalled), fake.installed[0]) + continue + } else { + names := sets.String{} + for ix := range fake.installed { + names.Insert(fake.installed[ix].Name) + } + for _, name := range test.expectedInstalled { + if !names.Has(name) { + t.Errorf("[%s] missing installed API: %s", test.name, name) + } + } + } + if len(test.expectedRemoved) != len(fake.removed) { + t.Errorf("[%s] unexpected installed APIs: %d, expected %d", test.name, len(fake.removed), len(test.expectedRemoved)) + continue + } else { + names := sets.String{} + names.Insert(fake.removed...) + for _, name := range test.expectedRemoved { + if !names.Has(name) { + t.Errorf("[%s] missing removed API: %s (%s)", test.name, name, names) + } + } + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/config/api.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/config/api.go index cfd53c5f8b87..55951e5a7127 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/config/api.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/config/api.go @@ -25,7 +25,7 @@ import ( "k8s.io/kubernetes/pkg/fields" ) -// NewSourceAPIserver creates config source that watches for changes to the services and endpoints. +// NewSourceAPI creates config source that watches for changes to the services and endpoints. func NewSourceAPI(c *client.Client, period time.Duration, servicesChan chan<- ServiceUpdate, endpointsChan chan<- EndpointsUpdate) { servicesLW := cache.NewListWatchFromClient(c, "services", api.NamespaceAll, fields.Everything()) endpointsLW := cache.NewListWatchFromClient(c, "endpoints", api.NamespaceAll, fields.Everything()) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/iptables/proxier.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/iptables/proxier.go index 6fb74068cceb..a45f2dcd4419 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/iptables/proxier.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/iptables/proxier.go @@ -25,9 +25,7 @@ import ( "crypto/sha256" "encoding/base32" "fmt" - "io/ioutil" "net" - "path" "reflect" "strconv" "strings" @@ -43,6 +41,7 @@ import ( utilexec "k8s.io/kubernetes/pkg/util/exec" utiliptables "k8s.io/kubernetes/pkg/util/iptables" "k8s.io/kubernetes/pkg/util/slice" + utilsysctl "k8s.io/kubernetes/pkg/util/sysctl" ) // iptablesMinVersion is the minimum version of iptables for which we will use the Proxier @@ -66,7 +65,7 @@ const iptablesMasqueradeMark = "0x4d415351" // ShouldUseIptablesProxier returns true if we should use the iptables Proxier // instead of the "classic" userspace Proxier. This is determined by checking // the iptables version and for the existence of kernel features. It may return -// an error if it fails to get the itpables version without error, in which +// an error if it fails to get the iptables version without error, in which // case it will also return false. func ShouldUseIptablesProxier() (bool, error) { exec := utilexec.New() @@ -90,7 +89,7 @@ func ShouldUseIptablesProxier() (bool, error) { // Check for the required sysctls. We don't care about the value, just // that it exists. If this Proxier is chosen, we'll iniialize it as we // need. - _, err = getSysctl(sysctlRouteLocalnet) + _, err = utilsysctl.GetSysctl(sysctlRouteLocalnet) if err != nil { return false, err } @@ -98,26 +97,9 @@ func ShouldUseIptablesProxier() (bool, error) { return true, nil } -const sysctlBase = "/proc/sys" const sysctlRouteLocalnet = "net/ipv4/conf/all/route_localnet" const sysctlBridgeCallIptables = "net/bridge/bridge-nf-call-iptables" -func getSysctl(sysctl string) (int, error) { - data, err := ioutil.ReadFile(path.Join(sysctlBase, sysctl)) - if err != nil { - return -1, err - } - val, err := strconv.Atoi(strings.Trim(string(data), " \n")) - if err != nil { - return -1, err - } - return val, nil -} - -func setSysctl(sysctl string, newVal int) error { - return ioutil.WriteFile(path.Join(sysctlBase, sysctl), []byte(strconv.Itoa(newVal)), 0640) -} - // internal struct for string service information type serviceInfo struct { clusterIP net.IP @@ -127,7 +109,6 @@ type serviceInfo struct { loadBalancerStatus api.LoadBalancerStatus sessionAffinityType api.ServiceAffinity stickyMaxAgeSeconds int - endpoints []string // Deprecated, but required for back-compat (including e2e) externalIPs []string } @@ -145,6 +126,7 @@ func newServiceInfo(service proxy.ServicePortName) *serviceInfo { type Proxier struct { mu sync.Mutex // protects the following fields serviceMap map[proxy.ServicePortName]*serviceInfo + endpointsMap map[proxy.ServicePortName][]string portsMap map[localPort]closeable haveReceivedServiceUpdate bool // true once we've seen an OnServiceUpdate event haveReceivedEndpointsUpdate bool // true once we've seen an OnEndpointsUpdate event @@ -180,7 +162,7 @@ var _ proxy.ProxyProvider = &Proxier{} // will not terminate if a particular iptables call fails. func NewProxier(ipt utiliptables.Interface, exec utilexec.Interface, syncPeriod time.Duration, masqueradeAll bool) (*Proxier, error) { // Set the route_localnet sysctl we need for - if err := setSysctl(sysctlRouteLocalnet, 1); err != nil { + if err := utilsysctl.SetSysctl(sysctlRouteLocalnet, 1); err != nil { return nil, fmt.Errorf("can't set sysctl %s: %v", sysctlRouteLocalnet, err) } @@ -188,12 +170,13 @@ func NewProxier(ipt utiliptables.Interface, exec utilexec.Interface, syncPeriod // because we'll catch the error on the sysctl, which is what we actually // care about. exec.Command("modprobe", "br-netfilter").CombinedOutput() - if err := setSysctl(sysctlBridgeCallIptables, 1); err != nil { - return nil, fmt.Errorf("can't set sysctl %s: %v", sysctlBridgeCallIptables, err) + if err := utilsysctl.SetSysctl(sysctlBridgeCallIptables, 1); err != nil { + glog.Warningf("can't set sysctl %s: %v", sysctlBridgeCallIptables, err) } return &Proxier{ serviceMap: make(map[proxy.ServicePortName]*serviceInfo), + endpointsMap: make(map[proxy.ServicePortName][]string), portsMap: make(map[localPort]closeable), syncPeriod: syncPeriod, iptables: ipt, @@ -248,6 +231,13 @@ func ipsEqual(lhs, rhs []string) bool { return true } +// Sync is called to immediately synchronize the proxier state to iptables +func (proxier *Proxier) Sync() { + proxier.mu.Lock() + defer proxier.mu.Unlock() + proxier.syncProxyRules() +} + // SyncLoop runs periodic work. This is expected to run as a goroutine or as the main loop of the app. It does not return. func (proxier *Proxier) SyncLoop() { t := time.NewTicker(proxier.syncPeriod) @@ -255,11 +245,7 @@ func (proxier *Proxier) SyncLoop() { for { <-t.C glog.V(6).Infof("Periodic sync") - func() { - proxier.mu.Lock() - defer proxier.mu.Unlock() - proxier.syncProxyRules() - }() + proxier.Sync() } } @@ -299,7 +285,7 @@ func (proxier *Proxier) OnServiceUpdate(allServices []api.Service) { continue } if exists { - //Something changed. + // Something changed. glog.V(3).Infof("Something changed for service %q: removing it", serviceName) delete(proxier.serviceMap, serviceName) } @@ -321,10 +307,9 @@ func (proxier *Proxier) OnServiceUpdate(allServices []api.Service) { } } - for name, info := range proxier.serviceMap { - // Check for servicePorts that were not in this update and have no endpoints. - // This helps prevent unnecessarily removing and adding services. - if !activeServices[name] && info.endpoints == nil { + // Remove services missing from the update. + for name := range proxier.serviceMap { + if !activeServices[name] { glog.V(1).Infof("Removing service %q", name) delete(proxier.serviceMap, name) } @@ -339,7 +324,7 @@ func (proxier *Proxier) OnEndpointsUpdate(allEndpoints []api.Endpoints) { defer proxier.mu.Unlock() proxier.haveReceivedEndpointsUpdate = true - registeredEndpoints := make(map[proxy.ServicePortName]bool) // use a map as a set + activeEndpoints := make(map[proxy.ServicePortName]bool) // use a map as a set // Update endpoints for services. for i := range allEndpoints { @@ -361,33 +346,21 @@ func (proxier *Proxier) OnEndpointsUpdate(allEndpoints []api.Endpoints) { for portname := range portsToEndpoints { svcPort := proxy.ServicePortName{NamespacedName: types.NamespacedName{Namespace: svcEndpoints.Namespace, Name: svcEndpoints.Name}, Port: portname} - state, exists := proxier.serviceMap[svcPort] - if !exists || state == nil { - state = newServiceInfo(svcPort) - proxier.serviceMap[svcPort] = state - } - curEndpoints := []string{} - if state != nil { - curEndpoints = state.endpoints - } + curEndpoints := proxier.endpointsMap[svcPort] newEndpoints := flattenValidEndpoints(portsToEndpoints[portname]) - if len(curEndpoints) != len(newEndpoints) || !slicesEquiv(slice.CopyStrings(curEndpoints), newEndpoints) { - glog.V(1).Infof("Setting endpoints for %s to %+v", svcPort, newEndpoints) - state.endpoints = newEndpoints + glog.V(1).Infof("Setting endpoints for %q to %+v", svcPort, newEndpoints) + proxier.endpointsMap[svcPort] = newEndpoints } - registeredEndpoints[svcPort] = true + activeEndpoints[svcPort] = true } } + // Remove endpoints missing from the update. - for service, info := range proxier.serviceMap { - // if missing from update and not already set by previous endpoints event - if _, exists := registeredEndpoints[service]; !exists && info.endpoints != nil { - glog.V(2).Infof("Removing endpoints for %s", service) - // Set the endpoints to nil, we will check for this in OnServiceUpdate so that we - // only remove ServicePorts that have no endpoints and were not in the service update, - // that way we only remove ServicePorts that were not in both. - proxier.serviceMap[service].endpoints = nil + for name := range proxier.endpointsMap { + if !activeEndpoints[name] { + glog.V(2).Infof("Removing endpoints for %q", name) + delete(proxier.endpointsMap, name) } } @@ -488,7 +461,7 @@ func (proxier *Proxier) syncProxyRules() { existingChains := make(map[utiliptables.Chain]string) iptablesSaveRaw, err := proxier.iptables.Save(utiliptables.TableNAT) if err != nil { // if we failed to get any rules - glog.Errorf("Failed to execute iptable-save, syncing all rules. %s", err.Error()) + glog.Errorf("Failed to execute iptables-save, syncing all rules. %s", err.Error()) } else { // otherwise parse the output existingChains = getChainLines(utiliptables.TableNAT, iptablesSaveRaw) } @@ -658,7 +631,7 @@ func (proxier *Proxier) syncProxyRules() { // can group rules together. endpoints := make([]string, 0) endpointChains := make([]utiliptables.Chain, 0) - for _, ep := range svcInfo.endpoints { + for _, ep := range proxier.endpointsMap[svcName] { endpoints = append(endpoints, ep) endpointChain := servicePortEndpointChainName(svcName, protocol, ep) endpointChains = append(endpointChains, endpointChain) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/iptables/proxier_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/iptables/proxier_test.go index e696c8825528..d0ccc07f7e96 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/iptables/proxier_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/iptables/proxier_test.go @@ -17,8 +17,9 @@ limitations under the License. package iptables import ( - utiliptables "k8s.io/kubernetes/pkg/util/iptables" "testing" + + utiliptables "k8s.io/kubernetes/pkg/util/iptables" ) func checkAllLines(t *testing.T, table utiliptables.Table, save []byte, expectedLines map[utiliptables.Chain]string) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/types.go index a3f309db278c..15b227f1cc5e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/types.go @@ -29,6 +29,8 @@ type ProxyProvider interface { // Active service proxies are reinitialized if found in the update set or // removed if missing from the update set. OnServiceUpdate(services []api.Service) + // Sync immediately synchronizes the ProxyProvider's current state to iptables. + Sync() // SyncLoop runs periodic work. // This is expected to run as a goroutine or as the main loop of the app. // It does not return. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier.go index 5fecd71d8c07..205edf4b7d6b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier.go @@ -23,6 +23,7 @@ import ( "strings" "sync" "sync/atomic" + "syscall" "time" "github.com/golang/glog" @@ -97,7 +98,7 @@ type Proxier struct { // assert Proxier is a ProxyProvider var _ proxy.ProxyProvider = &Proxier{} -// A key for the portMap. The ip has to be a tring because slices can't be map +// A key for the portMap. The ip has to be a string because slices can't be map // keys. type portMapKey struct { ip string @@ -146,12 +147,21 @@ func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.In return nil, fmt.Errorf("failed to select a host interface: %v", err) } + err = setRLimit(64 * 1000) + if err != nil { + return nil, fmt.Errorf("failed to set open file handler limit: %v", err) + } + proxyPorts := newPortAllocator(pr) glog.V(2).Infof("Setting proxy IP to %v and initializing iptables", hostIP) return createProxier(loadBalancer, listenIP, iptables, hostIP, proxyPorts, syncPeriod) } +func setRLimit(limit uint64) error { + return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &syscall.Rlimit{Max: limit, Cur: limit}) +} + func createProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface, hostIP net.IP, proxyPorts PortAllocator, syncPeriod time.Duration) (*Proxier, error) { // convenient to pass nil for tests.. if proxyPorts == nil { @@ -208,13 +218,13 @@ func CleanupLeftovers(ipt iptables.Interface) (encounteredError bool) { // flush and delete chains. chains := []iptables.Chain{iptablesContainerPortalChain, iptablesHostPortalChain, iptablesHostNodePortChain, iptablesContainerNodePortChain} for _, c := range chains { - // flush chain, then if sucessful delete, delete will fail if flush fails. + // flush chain, then if successful delete, delete will fail if flush fails. if err := ipt.FlushChain(iptables.TableNAT, c); err != nil { glog.Errorf("Error flushing userspace chain: %v", err) encounteredError = true } else { if err = ipt.DeleteChain(iptables.TableNAT, c); err != nil { - glog.Errorf("Error flushing userspace chain: %v", err) + glog.Errorf("Error deleting userspace chain: %v", err) encounteredError = true } } @@ -222,6 +232,15 @@ func CleanupLeftovers(ipt iptables.Interface) (encounteredError bool) { return encounteredError } +// Sync is called to immediately synchronize the proxier state to iptables +func (proxier *Proxier) Sync() { + if err := iptablesInit(proxier.iptables); err != nil { + glog.Errorf("Failed to ensure iptables: %v", err) + } + proxier.ensurePortals() + proxier.cleanupStaleStickySessions() +} + // SyncLoop runs periodic work. This is expected to run as a goroutine or as the main loop of the app. It does not return. func (proxier *Proxier) SyncLoop() { t := time.NewTicker(proxier.syncPeriod) @@ -229,11 +248,7 @@ func (proxier *Proxier) SyncLoop() { for { <-t.C glog.V(6).Infof("Periodic sync") - if err := iptablesInit(proxier.iptables); err != nil { - glog.Errorf("Failed to ensure iptables: %v", err) - } - proxier.ensurePortals() - proxier.cleanupStaleStickySessions() + proxier.Sync() } } @@ -331,9 +346,9 @@ func (proxier *Proxier) addServiceOnPort(service proxy.ServicePortName, protocol } // How long we leave idle UDP connections open. -const udpIdleTimeout = 1 * time.Second +const udpIdleTimeout = 250 * time.Millisecond -// OnUpdate manages the active set of service proxies. +// OnServiceUpdate manages the active set of service proxies. // Active service proxies are reinitialized if found in the update set or // shutdown if missing from the update set. func (proxier *Proxier) OnServiceUpdate(services []api.Service) { @@ -908,7 +923,7 @@ func (proxier *Proxier) iptablesHostPortalArgs(destIP net.IP, addDstLocalMatch b // If the proxy is bound (see Proxier.listenIP) to 0.0.0.0 ("any // interface") we want to do the same as from-container traffic and use // REDIRECT. Except that it doesn't work (empirically). REDIRECT on - // localpackets sends the traffic to localhost (special case, but it is + // local packets sends the traffic to localhost (special case, but it is // documented) but the response comes from the eth0 IP (not sure why, // truthfully), which makes DNS unhappy. // diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier_test.go index 3c789e62be56..b8d6ecd460f5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier_test.go @@ -121,6 +121,12 @@ func (fake *fakeIptables) RestoreAll(data []byte, flush iptables.FlushFlag, coun return nil } +func (fake *fakeIptables) AddReloadFunc(reloadFunc func()) { +} + +func (fake *fakeIptables) Destroy() { +} + var tcpServerPort int var udpServerPort int diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxysocket.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxysocket.go index ca7f59ec3d40..19aaf9d9bfe6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxysocket.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxysocket.go @@ -132,7 +132,7 @@ func (tcp *tcpProxySocket) ProxyLoop(service proxy.ServicePortName, myInfo *serv glog.Errorf("Accept failed: %v", err) continue } - glog.V(2).Infof("Accepted TCP connection from %v to %v", inConn.RemoteAddr(), inConn.LocalAddr()) + glog.V(3).Infof("Accepted TCP connection from %v to %v", inConn.RemoteAddr(), inConn.LocalAddr()) outConn, err := tryConnect(service, inConn.(*net.TCPConn).RemoteAddr(), "tcp", proxier) if err != nil { glog.Errorf("Failed to connect to balancer: %v", err) @@ -247,7 +247,7 @@ func (udp *udpProxySocket) getBackendConn(activeClients *clientCache, cliAddr ne if !found { // TODO: This could spin up a new goroutine to make the outbound connection, // and keep accepting inbound traffic. - glog.V(2).Infof("New UDP connection from %s", cliAddr) + glog.V(3).Infof("New UDP connection from %s", cliAddr) var err error svrConn, err = tryConnect(service, cliAddr, "udp", proxier) if err != nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/roundrobin.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/roundrobin.go index 56a4251a1759..6c28fc016af7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/roundrobin.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/roundrobin.go @@ -91,7 +91,7 @@ func (lb *LoadBalancerRR) NewService(svcPort proxy.ServicePortName, affinityType // This assumes that lb.lock is already held. func (lb *LoadBalancerRR) newServiceInternal(svcPort proxy.ServicePortName, affinityType api.ServiceAffinity, ttlMinutes int) *balancerState { if ttlMinutes == 0 { - ttlMinutes = 180 //default to 3 hours if not specified. Should 0 be unlimeted instead???? + ttlMinutes = 180 //default to 3 hours if not specified. Should 0 be unlimited instead???? } if _, exists := lb.services[svcPort]; !exists { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/etcd/etcd.go index d6c8a735475f..720a066886e1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/etcd/etcd.go @@ -32,7 +32,7 @@ type REST struct { } // NewREST returns a RESTStorage object that will work against replication controllers. -func NewREST(s storage.Interface) *REST { +func NewREST(s storage.Interface) (*REST, *StatusREST) { prefix := "/controllers" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.ReplicationController{} }, @@ -67,5 +67,22 @@ func NewREST(s storage.Interface) *REST { Storage: s, } - return &REST{store} + statusStore := *store + statusStore.UpdateStrategy = controller.StatusStrategy + + return &REST{store}, &StatusREST{store: &statusStore} +} + +// StatusREST implements the REST endpoint for changing the status of a replication controller +type StatusREST struct { + store *etcdgeneric.Etcd +} + +func (r *StatusREST) New() runtime.Object { + return &api.ReplicationController{} +} + +// Update alters the status subset of an object. +func (r *StatusREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) { + return r.store.Update(ctx, obj) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/etcd/etcd_test.go index 00e583c4db30..37bae1a94be0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/etcd/etcd_test.go @@ -27,9 +27,10 @@ import ( "k8s.io/kubernetes/pkg/tools" ) -func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { +func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) { etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "") - return NewREST(etcdStorage), fakeClient + storage, statusStorage := NewREST(etcdStorage) + return storage, statusStorage, fakeClient } // createController is a helper function that returns a controller with the updated resource version. @@ -74,7 +75,7 @@ func validNewController() *api.ReplicationController { var validController = validNewController() func TestCreate(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) controller := validNewController() controller.ObjectMeta = api.ObjectMeta{} @@ -93,7 +94,7 @@ func TestCreate(t *testing.T) { } func TestUpdate(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestUpdate( // valid @@ -124,13 +125,13 @@ func TestUpdate(t *testing.T) { } func TestDelete(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestDelete(validNewController()) } func TestGenerationNumber(t *testing.T) { - storage, _ := newStorage(t) + storage, _, _ := newStorage(t) modifiedSno := *validNewController() modifiedSno.Generation = 100 modifiedSno.Status.ObservedGeneration = 10 @@ -179,19 +180,19 @@ func TestGenerationNumber(t *testing.T) { } func TestGet(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestGet(validNewController()) } func TestList(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestList(validNewController()) } func TestWatch(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestWatch( validController, @@ -220,3 +221,5 @@ func TestWatch(t *testing.T) { }, ) } + +//TODO TestUpdateStatus diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/strategy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/strategy.go index 1abd72deefff..4989f185fa8f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/strategy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/strategy.go @@ -50,17 +50,14 @@ func (rcStrategy) PrepareForCreate(obj runtime.Object) { controller.Status = api.ReplicationControllerStatus{} controller.Generation = 1 - controller.Status.ObservedGeneration = 0 } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. func (rcStrategy) PrepareForUpdate(obj, old runtime.Object) { - // TODO: once RC has a status sub-resource we can enable this. - //newController := obj.(*api.ReplicationController) - //oldController := old.(*api.ReplicationController) - //newController.Status = oldController.Status newController := obj.(*api.ReplicationController) oldController := old.(*api.ReplicationController) + // update is not allowed to set status + newController.Status = oldController.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 @@ -125,3 +122,20 @@ func MatchController(label labels.Selector, field fields.Selector) generic.Match }, } } + +type rcStatusStrategy struct { + rcStrategy +} + +var StatusStrategy = rcStatusStrategy{Strategy} + +func (rcStatusStrategy) PrepareForUpdate(obj, old runtime.Object) { + newRc := obj.(*api.ReplicationController) + oldRc := old.(*api.ReplicationController) + // update is not allowed to set spec + newRc.Spec = oldRc.Spec +} + +func (rcStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList { + return validation.ValidateReplicationControllerStatusUpdate(old.(*api.ReplicationController), obj.(*api.ReplicationController)) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/strategy_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/strategy_test.go new file mode 100644 index 000000000000..afea95019d12 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/controller/strategy_test.go @@ -0,0 +1,140 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 controller + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" +) + +func TestControllerStrategy(t *testing.T) { + ctx := api.NewDefaultContext() + if !Strategy.NamespaceScoped() { + t.Errorf("ReplicationController must be namespace scoped") + } + if Strategy.AllowCreateOnUpdate() { + t.Errorf("ReplicationController should not allow create on update") + } + + validSelector := map[string]string{"a": "b"} + validPodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: validSelector, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + }, + }, + } + rc := &api.ReplicationController{ + ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault}, + Spec: api.ReplicationControllerSpec{ + Selector: validSelector, + Template: &validPodTemplate.Template, + }, + Status: api.ReplicationControllerStatus{ + Replicas: 1, + ObservedGeneration: int64(10), + }, + } + + Strategy.PrepareForCreate(rc) + if rc.Status.Replicas != 0 { + t.Error("ReplicationController should not allow setting status.replicas on create") + } + if rc.Status.ObservedGeneration != int64(0) { + t.Error("ReplicationController should not allow setting status.observedGeneration on create") + } + errs := Strategy.Validate(ctx, rc) + if len(errs) != 0 { + t.Errorf("Unexpected error validating %v", errs) + } + + invalidRc := &api.ReplicationController{ + ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "4"}, + } + Strategy.PrepareForUpdate(invalidRc, rc) + errs = Strategy.ValidateUpdate(ctx, invalidRc, rc) + if len(errs) == 0 { + t.Errorf("Expected a validation error") + } + if invalidRc.ResourceVersion != "4" { + t.Errorf("Incoming resource version on update should not be mutated") + } +} + +func TestControllerStatusStrategy(t *testing.T) { + ctx := api.NewDefaultContext() + if !StatusStrategy.NamespaceScoped() { + t.Errorf("ReplicationController must be namespace scoped") + } + if StatusStrategy.AllowCreateOnUpdate() { + t.Errorf("ReplicationController should not allow create on update") + } + validSelector := map[string]string{"a": "b"} + validPodTemplate := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: validSelector, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + }, + }, + } + oldController := &api.ReplicationController{ + ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault, ResourceVersion: "10"}, + Spec: api.ReplicationControllerSpec{ + Replicas: 3, + Selector: validSelector, + Template: &validPodTemplate.Template, + }, + Status: api.ReplicationControllerStatus{ + Replicas: 1, + ObservedGeneration: int64(10), + }, + } + newController := &api.ReplicationController{ + ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault, ResourceVersion: "9"}, + Spec: api.ReplicationControllerSpec{ + Replicas: 1, + Selector: validSelector, + Template: &validPodTemplate.Template, + }, + Status: api.ReplicationControllerStatus{ + Replicas: 3, + ObservedGeneration: int64(11), + }, + } + StatusStrategy.PrepareForUpdate(newController, oldController) + if newController.Status.Replicas != 3 { + t.Errorf("Replication controller status updates should allow change of replicas: %v", newController.Status.Replicas) + } + if newController.Spec.Replicas != 3 { + t.Errorf("PrepareForUpdate should have preferred spec") + } + errs := StatusStrategy.ValidateUpdate(ctx, newController, oldController) + if len(errs) != 0 { + t.Errorf("Unexpected error %v", errs) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/etcd/etcd.go index d126968a2b19..a65e311ca49a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/etcd/etcd.go @@ -18,7 +18,7 @@ package etcd import ( "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/daemonset" @@ -37,12 +37,12 @@ type REST struct { var daemonPrefix = "/daemonsets" // NewREST returns a RESTStorage object that will work against DaemonSets. -func NewREST(s storage.Interface) *REST { +func NewREST(s storage.Interface) (*REST, *StatusREST) { store := &etcdgeneric.Etcd{ - NewFunc: func() runtime.Object { return &experimental.DaemonSet{} }, + NewFunc: func() runtime.Object { return &extensions.DaemonSet{} }, // NewListFunc returns an object capable of storing results of an etcd list. - NewListFunc: func() runtime.Object { return &experimental.DaemonSetList{} }, + NewListFunc: func() runtime.Object { return &extensions.DaemonSetList{} }, // Produces a path that etcd understands, to the root of the resource // by combining the namespace in the context with the given prefix KeyRootFunc: func(ctx api.Context) string { @@ -55,7 +55,7 @@ func NewREST(s storage.Interface) *REST { }, // Retrieve the name field of a daemon set ObjectNameFunc: func(obj runtime.Object) (string, error) { - return obj.(*experimental.DaemonSet).Name, nil + return obj.(*extensions.DaemonSet).Name, nil }, // Used to match objects based on labels/fields for list and watch PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { @@ -71,6 +71,22 @@ func NewREST(s storage.Interface) *REST { Storage: s, } + statusStore := *store + statusStore.UpdateStrategy = daemonset.StatusStrategy - return &REST{store} + return &REST{store}, &StatusREST{store: &statusStore} +} + +// StatusREST implements the REST endpoint for changing the status of a daemonset +type StatusREST struct { + store *etcdgeneric.Etcd +} + +func (r *StatusREST) New() runtime.Object { + return &extensions.DaemonSet{} +} + +// Update alters the status subset of an object. +func (r *StatusREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) { + return r.store.Update(ctx, obj) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/etcd/etcd_test.go index 5e3059d0a8a8..c86b4d7bb98c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/etcd/etcd_test.go @@ -20,7 +20,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/registrytest" @@ -28,18 +28,19 @@ import ( "k8s.io/kubernetes/pkg/tools" ) -func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { - etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "experimental") - return NewREST(etcdStorage), fakeClient +func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) { + etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "extensions") + storage, statusStorage := NewREST(etcdStorage) + return storage, statusStorage, fakeClient } -func newValidDaemonSet() *experimental.DaemonSet { - return &experimental.DaemonSet{ +func newValidDaemonSet() *extensions.DaemonSet { + return &extensions.DaemonSet{ ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, - Spec: experimental.DaemonSetSpec{ + Spec: extensions.DaemonSetSpec{ Selector: map[string]string{"a": "b"}, Template: &api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ @@ -64,7 +65,7 @@ func newValidDaemonSet() *experimental.DaemonSet { var validDaemonSet = newValidDaemonSet() func TestCreate(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) ds := newValidDaemonSet() ds.ObjectMeta = api.ObjectMeta{} @@ -72,8 +73,8 @@ func TestCreate(t *testing.T) { // valid ds, // invalid (invalid selector) - &experimental.DaemonSet{ - Spec: experimental.DaemonSetSpec{ + &extensions.DaemonSet{ + Spec: extensions.DaemonSetSpec{ Selector: map[string]string{}, Template: validDaemonSet.Spec.Template, }, @@ -82,35 +83,35 @@ func TestCreate(t *testing.T) { } func TestUpdate(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestUpdate( // valid newValidDaemonSet(), // updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.DaemonSet) + object := obj.(*extensions.DaemonSet) object.Spec.Template.Spec.NodeSelector = map[string]string{"c": "d"} return object }, // invalid updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.DaemonSet) + object := obj.(*extensions.DaemonSet) object.UID = "newUID" return object }, func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.DaemonSet) + object := obj.(*extensions.DaemonSet) object.Name = "" return object }, func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.DaemonSet) + object := obj.(*extensions.DaemonSet) object.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure return object }, func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.DaemonSet) + object := obj.(*extensions.DaemonSet) object.Spec.Selector = map[string]string{} return object }, @@ -118,25 +119,25 @@ func TestUpdate(t *testing.T) { } func TestDelete(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestDelete(newValidDaemonSet()) } func TestGet(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestGet(newValidDaemonSet()) } func TestList(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestList(newValidDaemonSet()) } func TestWatch(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestWatch( validDaemonSet, @@ -160,3 +161,5 @@ func TestWatch(t *testing.T) { }, ) } + +// TODO TestUpdateStatus diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/strategy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/strategy.go index 7369afe51ffb..3d03802fc804 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/strategy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/daemonset/strategy.go @@ -21,8 +21,8 @@ import ( "reflect" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" - "k8s.io/kubernetes/pkg/apis/experimental/validation" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -46,16 +46,19 @@ func (daemonSetStrategy) NamespaceScoped() bool { // PrepareForCreate clears the status of a daemon set before creation. func (daemonSetStrategy) PrepareForCreate(obj runtime.Object) { - daemonSet := obj.(*experimental.DaemonSet) - daemonSet.Status = experimental.DaemonSetStatus{} + daemonSet := obj.(*extensions.DaemonSet) + daemonSet.Status = extensions.DaemonSetStatus{} daemonSet.Generation = 1 } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. func (daemonSetStrategy) PrepareForUpdate(obj, old runtime.Object) { - newDaemonSet := obj.(*experimental.DaemonSet) - oldDaemonSet := old.(*experimental.DaemonSet) + newDaemonSet := obj.(*extensions.DaemonSet) + oldDaemonSet := old.(*extensions.DaemonSet) + + // update is not allowed to set status + newDaemonSet.Status = oldDaemonSet.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 @@ -75,7 +78,7 @@ func (daemonSetStrategy) PrepareForUpdate(obj, old runtime.Object) { // Validate validates a new daemon set. func (daemonSetStrategy) Validate(ctx api.Context, obj runtime.Object) fielderrors.ValidationErrorList { - daemonSet := obj.(*experimental.DaemonSet) + daemonSet := obj.(*extensions.DaemonSet) return validation.ValidateDaemonSet(daemonSet) } @@ -87,8 +90,8 @@ func (daemonSetStrategy) AllowCreateOnUpdate() bool { // ValidateUpdate is the default update validation for an end user. func (daemonSetStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList { - validationErrorList := validation.ValidateDaemonSet(obj.(*experimental.DaemonSet)) - updateErrorList := validation.ValidateDaemonSetUpdate(old.(*experimental.DaemonSet), obj.(*experimental.DaemonSet)) + validationErrorList := validation.ValidateDaemonSet(obj.(*extensions.DaemonSet)) + updateErrorList := validation.ValidateDaemonSetUpdate(old.(*extensions.DaemonSet), obj.(*extensions.DaemonSet)) return append(validationErrorList, updateErrorList...) } @@ -98,7 +101,7 @@ func (daemonSetStrategy) AllowUnconditionalUpdate() bool { } // DaemonSetToSelectableFields returns a field set that represents the object. -func DaemonSetToSelectableFields(daemon *experimental.DaemonSet) fields.Set { +func DaemonSetToSelectableFields(daemon *extensions.DaemonSet) fields.Set { return fields.Set{ "metadata.name": daemon.Name, } @@ -112,7 +115,7 @@ func MatchDaemonSet(label labels.Selector, field fields.Selector) generic.Matche Label: label, Field: field, GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { - ds, ok := obj.(*experimental.DaemonSet) + ds, ok := obj.(*extensions.DaemonSet) if !ok { return nil, nil, fmt.Errorf("given object is not a ds.") } @@ -120,3 +123,19 @@ func MatchDaemonSet(label labels.Selector, field fields.Selector) generic.Matche }, } } + +type daemonSetStatusStrategy struct { + daemonSetStrategy +} + +var StatusStrategy = daemonSetStatusStrategy{Strategy} + +func (daemonSetStatusStrategy) PrepareForUpdate(obj, old runtime.Object) { + newDaemonSet := obj.(*extensions.DaemonSet) + oldDaemonSet := old.(*extensions.DaemonSet) + newDaemonSet.Spec = oldDaemonSet.Spec +} + +func (daemonSetStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList { + return validation.ValidateDaemonSetStatusUpdate(obj.(*extensions.DaemonSet), old.(*extensions.DaemonSet)) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/etcd/etcd.go index 8eace5bcfc62..ce3496077677 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/etcd/etcd.go @@ -17,8 +17,12 @@ limitations under the License. package etcd import ( + "fmt" + "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/deployment" @@ -28,6 +32,22 @@ import ( "k8s.io/kubernetes/pkg/storage" ) +// DeploymentStorage includes dummy storage for Deployments and for Scale subresource. +type DeploymentStorage struct { + Deployment *REST + Scale *ScaleREST +} + +func NewStorage(s storage.Interface) DeploymentStorage { + deploymentRest := NewREST(s) + deploymentRegistry := deployment.NewRegistry(deploymentRest) + + return DeploymentStorage{ + Deployment: deploymentRest, + Scale: &ScaleREST{registry: &deploymentRegistry}, + } +} + type REST struct { *etcdgeneric.Etcd } @@ -36,9 +56,9 @@ type REST struct { func NewREST(s storage.Interface) *REST { prefix := "/deployments" store := &etcdgeneric.Etcd{ - NewFunc: func() runtime.Object { return &experimental.Deployment{} }, + NewFunc: func() runtime.Object { return &extensions.Deployment{} }, // NewListFunc returns an object capable of storing results of an etcd list. - NewListFunc: func() runtime.Object { return &experimental.DeploymentList{} }, + NewListFunc: func() runtime.Object { return &extensions.DeploymentList{} }, // Produces a path that etcd understands, to the root of the resource // by combining the namespace in the context with the given prefix. KeyRootFunc: func(ctx api.Context) string { @@ -51,7 +71,7 @@ func NewREST(s storage.Interface) *REST { }, // Retrieve the name field of a deployment. ObjectNameFunc: func(obj runtime.Object) (string, error) { - return obj.(*experimental.Deployment).Name, nil + return obj.(*extensions.Deployment).Name, nil }, // Used to match objects based on labels/fields for list. PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { @@ -69,3 +89,69 @@ func NewREST(s storage.Interface) *REST { } return &REST{store} } + +type ScaleREST struct { + registry *deployment.Registry +} + +// ScaleREST implements Patcher +var _ = rest.Patcher(&ScaleREST{}) + +// New creates a new Scale object +func (r *ScaleREST) New() runtime.Object { + return &extensions.Scale{} +} + +func (r *ScaleREST) Get(ctx api.Context, name string) (runtime.Object, error) { + deployment, err := (*r.registry).GetDeployment(ctx, name) + if err != nil { + return nil, errors.NewNotFound("scale", name) + } + return &extensions.Scale{ + ObjectMeta: api.ObjectMeta{ + Name: name, + Namespace: deployment.Namespace, + CreationTimestamp: deployment.CreationTimestamp, + }, + Spec: extensions.ScaleSpec{ + Replicas: deployment.Spec.Replicas, + }, + Status: extensions.ScaleStatus{ + Replicas: deployment.Status.Replicas, + Selector: deployment.Spec.Selector, + }, + }, nil +} + +func (r *ScaleREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) { + if obj == nil { + return nil, false, errors.NewBadRequest(fmt.Sprintf("nil update passed to Scale")) + } + scale, ok := obj.(*extensions.Scale) + if !ok { + return nil, false, errors.NewBadRequest(fmt.Sprintf("wrong object passed to Scale update: %v", obj)) + } + deployment, err := (*r.registry).GetDeployment(ctx, scale.Name) + if err != nil { + return nil, false, errors.NewNotFound("scale", scale.Name) + } + deployment.Spec.Replicas = scale.Spec.Replicas + deployment, err = (*r.registry).UpdateDeployment(ctx, deployment) + if err != nil { + return nil, false, errors.NewConflict("scale", scale.Name, err) + } + return &extensions.Scale{ + ObjectMeta: api.ObjectMeta{ + Name: deployment.Name, + Namespace: deployment.Namespace, + CreationTimestamp: deployment.CreationTimestamp, + }, + Spec: extensions.ScaleSpec{ + Replicas: deployment.Spec.Replicas, + }, + Status: extensions.ScaleStatus{ + Replicas: deployment.Status.Replicas, + Selector: deployment.Spec.Selector, + }, + }, false, nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/etcd/etcd_test.go index e11d113a6337..a81124969bd0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/etcd/etcd_test.go @@ -20,26 +20,33 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/tools" + "k8s.io/kubernetes/pkg/tools/etcdtest" + "k8s.io/kubernetes/pkg/util" ) -func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { - etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "experimental") - return NewREST(etcdStorage), fakeClient +func newStorage(t *testing.T) (*DeploymentStorage, *tools.FakeEtcdClient) { + etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "extensions") + deploymentStorage := NewStorage(etcdStorage) + return &deploymentStorage, fakeClient } -func validNewDeployment() *experimental.Deployment { - return &experimental.Deployment{ +var namespace = "foo-namespace" +var name = "foo-deployment" + +func validNewDeployment() *extensions.Deployment { + return &extensions.Deployment{ ObjectMeta: api.ObjectMeta{ - Name: "foo", - Namespace: api.NamespaceDefault, + Name: name, + Namespace: namespace, }, - Spec: experimental.DeploymentSpec{ + Spec: extensions.DeploymentSpec{ Selector: map[string]string{"a": "b"}, Template: &api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ @@ -58,23 +65,42 @@ func validNewDeployment() *experimental.Deployment { }, }, UniqueLabelKey: "my-label", + Replicas: 7, + }, + Status: extensions.DeploymentStatus{ + Replicas: 5, }, } } var validDeployment = *validNewDeployment() +func validNewScale() *extensions.Scale { + return &extensions.Scale{ + ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespace}, + Spec: extensions.ScaleSpec{ + Replicas: validDeployment.Spec.Replicas, + }, + Status: extensions.ScaleStatus{ + Replicas: validDeployment.Status.Replicas, + Selector: validDeployment.Spec.Template.Labels, + }, + } +} + +var validScale = *validNewScale() + func TestCreate(t *testing.T) { storage, fakeClient := newStorage(t) - test := registrytest.New(t, fakeClient, storage.Etcd) + test := registrytest.New(t, fakeClient, storage.Deployment.Etcd) deployment := validNewDeployment() deployment.ObjectMeta = api.ObjectMeta{} test.TestCreate( // valid deployment, // invalid (invalid selector) - &experimental.Deployment{ - Spec: experimental.DeploymentSpec{ + &extensions.Deployment{ + Spec: extensions.DeploymentSpec{ Selector: map[string]string{}, Template: validDeployment.Spec.Template, }, @@ -84,34 +110,34 @@ func TestCreate(t *testing.T) { func TestUpdate(t *testing.T) { storage, fakeClient := newStorage(t) - test := registrytest.New(t, fakeClient, storage.Etcd) + test := registrytest.New(t, fakeClient, storage.Deployment.Etcd) test.TestUpdate( // valid validNewDeployment(), // updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.Deployment) + object := obj.(*extensions.Deployment) object.Spec.Template.Spec.NodeSelector = map[string]string{"c": "d"} return object }, // invalid updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.Deployment) + object := obj.(*extensions.Deployment) object.UID = "newUID" return object }, func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.Deployment) + object := obj.(*extensions.Deployment) object.Name = "" return object }, func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.Deployment) + object := obj.(*extensions.Deployment) object.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure return object }, func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.Deployment) + object := obj.(*extensions.Deployment) object.Spec.Selector = map[string]string{} return object }, @@ -120,25 +146,25 @@ func TestUpdate(t *testing.T) { func TestDelete(t *testing.T) { storage, fakeClient := newStorage(t) - test := registrytest.New(t, fakeClient, storage.Etcd) + test := registrytest.New(t, fakeClient, storage.Deployment.Etcd) test.TestDelete(validNewDeployment()) } func TestGet(t *testing.T) { storage, fakeClient := newStorage(t) - test := registrytest.New(t, fakeClient, storage.Etcd) + test := registrytest.New(t, fakeClient, storage.Deployment.Etcd) test.TestGet(validNewDeployment()) } func TestList(t *testing.T) { storage, fakeClient := newStorage(t) - test := registrytest.New(t, fakeClient, storage.Etcd) + test := registrytest.New(t, fakeClient, storage.Deployment.Etcd) test.TestList(validNewDeployment()) } func TestWatch(t *testing.T) { storage, fakeClient := newStorage(t) - test := registrytest.New(t, fakeClient, storage.Etcd) + test := registrytest.New(t, fakeClient, storage.Deployment.Etcd) test.TestWatch( validNewDeployment(), // matching labels @@ -150,12 +176,63 @@ func TestWatch(t *testing.T) { }, // matching fields []fields.Set{ - {"metadata.name": "foo"}, + {"metadata.name": name}, }, // not matchin fields []fields.Set{ {"metadata.name": "bar"}, - {"name": "foo"}, + {"name": name}, }, ) } + +func TestScaleGet(t *testing.T) { + storage, fakeClient := newStorage(t) + + ctx := api.WithNamespace(api.NewContext(), namespace) + key := etcdtest.AddPrefix("/deployments/" + namespace + "/" + name) + if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Extensions.Codec(), &validDeployment), 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + + expect := &validScale + obj, err := storage.Scale.Get(ctx, name) + scale := obj.(*extensions.Scale) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if e, a := expect, scale; !api.Semantic.DeepEqual(e, a) { + t.Errorf("unexpected scale: %s", util.ObjectDiff(e, a)) + } +} + +func TestScaleUpdate(t *testing.T) { + storage, fakeClient := newStorage(t) + + ctx := api.WithNamespace(api.NewContext(), namespace) + key := etcdtest.AddPrefix("/deployments/" + namespace + "/" + name) + if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Extensions.Codec(), &validDeployment), 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + replicas := 12 + update := extensions.Scale{ + ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespace}, + Spec: extensions.ScaleSpec{ + Replicas: replicas, + }, + } + + if _, _, err := storage.Scale.Update(ctx, &update); err != nil { + t.Fatalf("unexpected error: %v", err) + } + response, err := fakeClient.Get(key, false, false) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + var deployment extensions.Deployment + testapi.Extensions.Codec().DecodeInto([]byte(response.Node.Value), &deployment) + if deployment.Spec.Replicas != replicas { + t.Errorf("wrong replicas count expected: %d got: %d", replicas, deployment.Spec.Replicas) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/registry.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/registry.go new file mode 100644 index 000000000000..12e76a25a92c --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/registry.go @@ -0,0 +1,87 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 deployment + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" +) + +// Registry is an interface for things that know how to store Deployments. +type Registry interface { + ListDeployments(ctx api.Context, label labels.Selector, field fields.Selector) (*extensions.DeploymentList, error) + GetDeployment(ctx api.Context, deploymentID string) (*extensions.Deployment, error) + CreateDeployment(ctx api.Context, deployment *extensions.Deployment) (*extensions.Deployment, error) + UpdateDeployment(ctx api.Context, deployment *extensions.Deployment) (*extensions.Deployment, error) + DeleteDeployment(ctx api.Context, deploymentID 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} +} + +// List obtains a list of Deployments that match selector. +func (s *storage) ListDeployments(ctx api.Context, label labels.Selector, field fields.Selector) (*extensions.DeploymentList, error) { + if !field.Empty() { + return nil, fmt.Errorf("field selector not supported yet") + } + obj, err := s.List(ctx, label, field) + if err != nil { + return nil, err + } + return obj.(*extensions.DeploymentList), err +} + +func (s *storage) GetDeployment(ctx api.Context, deploymentID string) (*extensions.Deployment, error) { + obj, err := s.Get(ctx, deploymentID) + if err != nil { + return nil, err + } + return obj.(*extensions.Deployment), nil +} + +func (s *storage) CreateDeployment(ctx api.Context, deployment *extensions.Deployment) (*extensions.Deployment, error) { + obj, err := s.Create(ctx, deployment) + if err != nil { + return nil, err + } + return obj.(*extensions.Deployment), nil +} + +func (s *storage) UpdateDeployment(ctx api.Context, deployment *extensions.Deployment) (*extensions.Deployment, error) { + obj, _, err := s.Update(ctx, deployment) + if err != nil { + return nil, err + } + return obj.(*extensions.Deployment), nil +} + +func (s *storage) DeleteDeployment(ctx api.Context, deploymentID string) error { + _, err := s.Delete(ctx, deploymentID, nil) + return err +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/strategy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/strategy.go index c865927f751f..01b651c08dac 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/strategy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/deployment/strategy.go @@ -20,8 +20,8 @@ import ( "fmt" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" - "k8s.io/kubernetes/pkg/apis/experimental/validation" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -50,7 +50,7 @@ func (deploymentStrategy) PrepareForCreate(obj runtime.Object) { // Validate validates a new deployment. func (deploymentStrategy) Validate(ctx api.Context, obj runtime.Object) errs.ValidationErrorList { - deployment := obj.(*experimental.Deployment) + deployment := obj.(*extensions.Deployment) return validation.ValidateDeployment(deployment) } @@ -65,7 +65,7 @@ func (deploymentStrategy) PrepareForUpdate(obj, old runtime.Object) { // ValidateUpdate is the default update validation for an end user. func (deploymentStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) errs.ValidationErrorList { - return validation.ValidateDeploymentUpdate(old.(*experimental.Deployment), obj.(*experimental.Deployment)) + return validation.ValidateDeploymentUpdate(old.(*extensions.Deployment), obj.(*extensions.Deployment)) } func (deploymentStrategy) AllowUnconditionalUpdate() bool { @@ -73,7 +73,7 @@ func (deploymentStrategy) AllowUnconditionalUpdate() bool { } // DeploymentToSelectableFields returns a field set that represents the object. -func DeploymentToSelectableFields(deployment *experimental.Deployment) fields.Set { +func DeploymentToSelectableFields(deployment *extensions.Deployment) fields.Set { return fields.Set{ "metadata.name": deployment.Name, } @@ -87,7 +87,7 @@ func MatchDeployment(label labels.Selector, field fields.Selector) generic.Match Label: label, Field: field, GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { - deployment, ok := obj.(*experimental.Deployment) + deployment, ok := obj.(*extensions.Deployment) if !ok { return nil, nil, fmt.Errorf("given object is not a deployment.") } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/experimental/controller/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/experimental/controller/etcd/etcd.go index 134f42f457fc..fc4cfe8161d4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/experimental/controller/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/experimental/controller/etcd/etcd.go @@ -28,7 +28,7 @@ import ( "k8s.io/kubernetes/pkg/registry/controller" "k8s.io/kubernetes/pkg/registry/controller/etcd" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" ) // Container includes dummy storage for RC pods and experimental storage for Scale. @@ -38,7 +38,9 @@ type ContainerStorage struct { } func NewStorage(s storage.Interface) ContainerStorage { - rcRegistry := controller.NewRegistry(etcd.NewREST(s)) + // scale does not set status, only updates spec so we ignore the status + controllerREST, _ := etcd.NewREST(s) + rcRegistry := controller.NewRegistry(controllerREST) return ContainerStorage{ ReplicationController: &RcREST{}, @@ -50,12 +52,12 @@ type ScaleREST struct { registry *controller.Registry } -// LogREST implements GetterWithOptions +// ScaleREST implements Patcher var _ = rest.Patcher(&ScaleREST{}) // New creates a new Scale object func (r *ScaleREST) New() runtime.Object { - return &experimental.Scale{} + return &extensions.Scale{} } func (r *ScaleREST) Get(ctx api.Context, name string) (runtime.Object, error) { @@ -63,16 +65,16 @@ func (r *ScaleREST) Get(ctx api.Context, name string) (runtime.Object, error) { if err != nil { return nil, errors.NewNotFound("scale", name) } - return &experimental.Scale{ + return &extensions.Scale{ ObjectMeta: api.ObjectMeta{ Name: name, Namespace: rc.Namespace, CreationTimestamp: rc.CreationTimestamp, }, - Spec: experimental.ScaleSpec{ + Spec: extensions.ScaleSpec{ Replicas: rc.Spec.Replicas, }, - Status: experimental.ScaleStatus{ + Status: extensions.ScaleStatus{ Replicas: rc.Status.Replicas, Selector: rc.Spec.Selector, }, @@ -83,7 +85,7 @@ func (r *ScaleREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, if obj == nil { return nil, false, errors.NewBadRequest(fmt.Sprintf("nil update passed to Scale")) } - scale, ok := obj.(*experimental.Scale) + scale, ok := obj.(*extensions.Scale) if !ok { return nil, false, errors.NewBadRequest(fmt.Sprintf("wrong object passed to Scale update: %v", obj)) } @@ -96,16 +98,16 @@ func (r *ScaleREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, if err != nil { return nil, false, errors.NewConflict("scale", scale.Name, err) } - return &experimental.Scale{ + return &extensions.Scale{ ObjectMeta: api.ObjectMeta{ Name: rc.Name, Namespace: rc.Namespace, CreationTimestamp: rc.CreationTimestamp, }, - Spec: experimental.ScaleSpec{ + Spec: extensions.ScaleSpec{ Replicas: rc.Spec.Replicas, }, - Status: experimental.ScaleStatus{ + Status: extensions.ScaleStatus{ Replicas: rc.Status.Replicas, Selector: rc.Spec.Selector, }, @@ -116,5 +118,5 @@ func (r *ScaleREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, type RcREST struct{} func (r *RcREST) New() runtime.Object { - return &experimental.ReplicationControllerDummy{} + return &extensions.ReplicationControllerDummy{} } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/experimental/controller/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/experimental/controller/etcd/etcd_test.go index c5bed83b3504..f1732ece8064 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/experimental/controller/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/experimental/controller/etcd/etcd_test.go @@ -21,7 +21,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/tools" @@ -30,7 +30,7 @@ import ( ) func newStorage(t *testing.T) (*ScaleREST, *tools.FakeEtcdClient) { - etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "experimental") + etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "") return NewStorage(etcdStorage).Scale, fakeClient } @@ -66,12 +66,12 @@ var validController = api.ReplicationController{ Spec: validControllerSpec, } -var validScale = experimental.Scale{ +var validScale = extensions.Scale{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test"}, - Spec: experimental.ScaleSpec{ + Spec: extensions.ScaleSpec{ Replicas: validReplicas, }, - Status: experimental.ScaleStatus{ + Status: extensions.ScaleStatus{ Replicas: 0, Selector: validPodTemplate.Template.Labels, }, @@ -82,13 +82,13 @@ func TestGet(t *testing.T) { ctx := api.WithNamespace(api.NewContext(), "test") key := etcdtest.AddPrefix("/controllers/test/foo") - if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Experimental.Codec(), &validController), 0); err != nil { + if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Default.Codec(), &validController), 0); err != nil { t.Fatalf("unexpected error: %v", err) } expect := &validScale obj, err := storage.Get(ctx, "foo") - scale := obj.(*experimental.Scale) + scale := obj.(*extensions.Scale) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -102,13 +102,13 @@ func TestUpdate(t *testing.T) { ctx := api.WithNamespace(api.NewContext(), "test") key := etcdtest.AddPrefix("/controllers/test/foo") - if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Experimental.Codec(), &validController), 0); err != nil { + if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Default.Codec(), &validController), 0); err != nil { t.Fatalf("unexpected error: %v", err) } replicas := 12 - update := experimental.Scale{ + update := extensions.Scale{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test"}, - Spec: experimental.ScaleSpec{ + Spec: extensions.ScaleSpec{ Replicas: replicas, }, } @@ -122,7 +122,7 @@ func TestUpdate(t *testing.T) { } var controller api.ReplicationController - testapi.Experimental.Codec().DecodeInto([]byte(response.Node.Value), &controller) + testapi.Extensions.Codec().DecodeInto([]byte(response.Node.Value), &controller) if controller.Spec.Replicas != replicas { t.Errorf("wrong replicas count expected: %d got: %d", replicas, controller.Spec.Replicas) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/etcd/etcd.go index 643d5e39047d..a620806e52ad 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/etcd/etcd.go @@ -25,6 +25,7 @@ import ( kubeerr "k8s.io/kubernetes/pkg/api/errors" etcderr "k8s.io/kubernetes/pkg/api/errors/etcd" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -150,28 +151,28 @@ func (e *Etcd) List(ctx api.Context, label labels.Selector, field fields.Selecto func (e *Etcd) ListPredicate(ctx api.Context, m generic.Matcher) (runtime.Object, error) { list := e.NewListFunc() trace := util.NewTrace("List " + reflect.TypeOf(list).String()) + filterFunc := e.filterAndDecorateFunction(m) defer trace.LogIfLong(600 * time.Millisecond) if name, ok := m.MatchesSingle(); ok { if key, err := e.KeyFunc(ctx, name); err == nil { trace.Step("About to read single object") - err = e.Storage.GetToList(key, list) + err := e.Storage.GetToList(ctx, key, filterFunc, list) trace.Step("Object extracted") if err != nil { return nil, err } - defer trace.Step("List filtered") - return generic.FilterList(list, m, generic.DecoratorFunc(e.Decorator)) + return list, nil } + // if we cannot extract a key based on the current context, the optimization is skipped } trace.Step("About to list directory") - err := e.Storage.List(e.KeyRootFunc(ctx), list) + err := e.Storage.List(ctx, e.KeyRootFunc(ctx), filterFunc, list) trace.Step("List extracted") if err != nil { return nil, err } - defer trace.Step("List filtered") - return generic.FilterList(list, m, generic.DecoratorFunc(e.Decorator)) + return list, nil } // Create inserts a new item according to the unique key from the object. @@ -195,7 +196,7 @@ func (e *Etcd) Create(ctx api.Context, obj runtime.Object) (runtime.Object, erro } trace.Step("About to create object") out := e.NewFunc() - if err := e.Storage.Create(key, obj, out, ttl); err != nil { + if err := e.Storage.Create(ctx, key, obj, out, ttl); err != nil { err = etcderr.InterpretCreateError(err, e.EndpointName, name) err = rest.CheckGeneratedNameError(e.CreateStrategy, err, obj) return nil, err @@ -239,7 +240,7 @@ func (e *Etcd) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool // TODO: expose TTL creating := false out := e.NewFunc() - err = e.Storage.GuaranteedUpdate(key, out, true, func(existing runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { + err = e.Storage.GuaranteedUpdate(ctx, key, out, true, func(existing runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { version, err := e.Storage.Versioner().ObjectResourceVersion(existing) if err != nil { return nil, nil, err @@ -329,7 +330,7 @@ func (e *Etcd) Get(ctx api.Context, name string) (runtime.Object, error) { return nil, err } trace.Step("About to read object") - if err := e.Storage.Get(key, obj, false); err != nil { + if err := e.Storage.Get(ctx, key, obj, false); err != nil { return nil, etcderr.InterpretGetError(err, e.EndpointName, name) } trace.Step("Object read") @@ -357,7 +358,7 @@ func (e *Etcd) Delete(ctx api.Context, name string, options *api.DeleteOptions) trace := util.NewTrace("Delete " + reflect.TypeOf(obj).String()) defer trace.LogIfLong(time.Second) trace.Step("About to read object") - if err := e.Storage.Get(key, obj, false); err != nil { + if err := e.Storage.Get(ctx, key, obj, false); err != nil { return nil, etcderr.InterpretDeleteError(err, e.EndpointName, name) } @@ -377,7 +378,7 @@ func (e *Etcd) Delete(ctx api.Context, name string, options *api.DeleteOptions) out := e.NewFunc() lastGraceful := int64(0) err := e.Storage.GuaranteedUpdate( - key, out, false, + ctx, key, out, false, storage.SimpleUpdate(func(existing runtime.Object) (runtime.Object, error) { graceful, pendingGraceful, err := rest.BeforeDelete(e.DeleteStrategy, ctx, existing, options) if err != nil { @@ -412,7 +413,7 @@ func (e *Etcd) Delete(ctx api.Context, name string, options *api.DeleteOptions) // delete immediately, or no graceful deletion supported out := e.NewFunc() trace.Step("About to delete object") - if err := e.Storage.Delete(key, out); err != nil { + if err := e.Storage.Delete(ctx, key, out); err != nil { return nil, etcderr.InterpretDeleteError(err, e.EndpointName, name) } return e.finalizeDelete(out, true) @@ -432,7 +433,7 @@ func (e *Etcd) finalizeDelete(obj runtime.Object, runHooks bool) (runtime.Object } return obj, nil } - return &api.Status{Status: api.StatusSuccess}, nil + return &unversioned.Status{Status: unversioned.StatusSuccess}, nil } // Watch makes a matcher for the given label and field, and calls @@ -449,8 +450,23 @@ func (e *Etcd) WatchPredicate(ctx api.Context, m generic.Matcher, resourceVersio if err != nil { return nil, err } + filterFunc := e.filterAndDecorateFunction(m) - filterFunc := func(obj runtime.Object) bool { + if name, ok := m.MatchesSingle(); ok { + if key, err := e.KeyFunc(ctx, name); err == nil { + if err != nil { + return nil, err + } + return e.Storage.Watch(ctx, key, version, filterFunc) + } + // if we cannot extract a key based on the current context, the optimization is skipped + } + + return e.Storage.WatchList(ctx, e.KeyRootFunc(ctx), version, filterFunc) +} + +func (e *Etcd) filterAndDecorateFunction(m generic.Matcher) func(runtime.Object) bool { + return func(obj runtime.Object) bool { matches, err := m.Matches(obj) if err != nil { glog.Errorf("unable to match watch: %v", err) @@ -464,14 +480,6 @@ func (e *Etcd) WatchPredicate(ctx api.Context, m generic.Matcher, resourceVersio } return matches } - - if name, ok := m.MatchesSingle(); ok { - if key, err := e.KeyFunc(ctx, name); err == nil { - return e.Storage.Watch(key, version, filterFunc) - } - } - - return e.Storage.WatchList(e.KeyRootFunc(ctx), version, filterFunc) } // calculateTTL is a helper for retrieving the updated TTL for an object or returning an error diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/etcd/etcd_test.go index 8569ccc84df0..ff98bc0d8712 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/etcd/etcd_test.go @@ -84,6 +84,9 @@ func NewTestGenericEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, *Etcd) { return podPrefix }, KeyFunc: func(ctx api.Context, id string) (string, error) { + if _, ok := api.NamespaceFrom(ctx); !ok { + return "", fmt.Errorf("namespace is required") + } return path.Join(podPrefix, id), nil }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.Pod).Name, nil }, @@ -126,11 +129,11 @@ func (everythingMatcher) MatchesSingle() (string, bool) { func TestEtcdList(t *testing.T) { podA := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, + ObjectMeta: api.ObjectMeta{Namespace: "test", Name: "foo"}, Spec: api.PodSpec{NodeName: "machine"}, } podB := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, + ObjectMeta: api.ObjectMeta{Namespace: "test", Name: "bar"}, Spec: api.PodSpec{NodeName: "machine"}, } @@ -148,10 +151,14 @@ func TestEtcdList(t *testing.T) { }, } + testContext := api.WithNamespace(api.NewContext(), "test") + noNamespaceContext := api.NewContext() + table := map[string]struct { in tools.EtcdResponseWithError m generic.Matcher out runtime.Object + context api.Context succeed bool }{ "empty": { @@ -194,6 +201,16 @@ func TestEtcdList(t *testing.T) { out: &api.PodList{Items: []api.Pod{*podA}}, succeed: true, }, + "normalFilteredNoNamespace": { + in: tools.EtcdResponseWithError{ + R: normalListResp, + E: nil, + }, + m: setMatcher{sets.NewString("foo")}, + out: &api.PodList{Items: []api.Pod{*podA}}, + context: noNamespaceContext, + succeed: true, + }, "normalFilteredMatchMultiple": { in: tools.EtcdResponseWithError{ R: normalListResp, @@ -206,23 +223,28 @@ func TestEtcdList(t *testing.T) { } for name, item := range table { + ctx := testContext + if item.context != nil { + ctx = item.context + } fakeClient, registry := NewTestGenericEtcdRegistry(t) if name, ok := item.m.MatchesSingle(); ok { - key, err := registry.KeyFunc(api.NewContext(), name) - if err != nil { - t.Errorf("Couldn't create key for %v", name) - continue + if key, err := registry.KeyFunc(ctx, name); err == nil { + key = etcdtest.AddPrefix(key) + fakeClient.Data[key] = item.in + } else { + key := registry.KeyRootFunc(ctx) + key = etcdtest.AddPrefix(key) + fakeClient.Data[key] = item.in } - key = etcdtest.AddPrefix(key) - fakeClient.Data[key] = item.in } else { - key, _ := registry.KeyFunc(api.NewContext(), name) + key := registry.KeyRootFunc(ctx) key = etcdtest.AddPrefix(key) fakeClient.Data[key] = item.in } - list, err := registry.ListPredicate(api.NewContext(), item.m) + list, err := registry.ListPredicate(ctx, item.m) if e, a := item.succeed, err == nil; e != a { - t.Errorf("%v: expected %v, got %v", name, e, a) + t.Errorf("%v: expected %v, got %v: %v", name, e, a, err) continue } if e, a := item.out, list; !api.Semantic.DeepDerivative(e, a) { @@ -233,11 +255,11 @@ func TestEtcdList(t *testing.T) { func TestEtcdCreate(t *testing.T) { podA := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault}, + ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test"}, Spec: api.PodSpec{NodeName: "machine"}, } podB := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault}, + ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test"}, Spec: api.PodSpec{NodeName: "machine2"}, } @@ -257,6 +279,8 @@ func TestEtcdCreate(t *testing.T) { E: tools.EtcdErrorNotFound, } + testContext := api.WithNamespace(api.NewContext(), "test") + table := map[string]struct { existing tools.EtcdResponseWithError expect tools.EtcdResponseWithError @@ -282,7 +306,7 @@ func TestEtcdCreate(t *testing.T) { fakeClient, registry := NewTestGenericEtcdRegistry(t) path := etcdtest.AddPrefix("pods/foo") fakeClient.Data[path] = item.existing - obj, err := registry.Create(api.NewDefaultContext(), item.toCreate) + obj, err := registry.Create(testContext, item.toCreate) if !item.errOK(err) { t.Errorf("%v: unexpected error: %v", name, err) } @@ -308,17 +332,22 @@ func TestEtcdCreate(t *testing.T) { } } +func podCopy(in *api.Pod) *api.Pod { + out := *in + return &out +} + func TestEtcdUpdate(t *testing.T) { podA := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault}, + ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test"}, Spec: api.PodSpec{NodeName: "machine"}, } podB := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault, ResourceVersion: "1"}, + ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "1"}, Spec: api.PodSpec{NodeName: "machine2"}, } podAWithResourceVersion := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault, ResourceVersion: "3"}, + ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "3"}, Spec: api.PodSpec{NodeName: "machine"}, } nodeWithPodA := tools.EtcdResponseWithError{ @@ -369,6 +398,8 @@ func TestEtcdUpdate(t *testing.T) { E: tools.EtcdErrorNotFound, } + testContext := api.WithNamespace(api.NewContext(), "test") + table := map[string]struct { existing tools.EtcdResponseWithError expect tools.EtcdResponseWithError @@ -381,18 +412,18 @@ func TestEtcdUpdate(t *testing.T) { "normal": { existing: nodeWithPodA, expect: nodeWithPodB, - toUpdate: podB, + toUpdate: podCopy(podB), errOK: func(err error) bool { return err == nil }, }, "notExisting": { existing: emptyNode, expect: emptyNode, - toUpdate: podA, + toUpdate: podCopy(podA), errOK: func(err error) bool { return errors.IsNotFound(err) }, }, "createIfNotFound": { existing: emptyNode, - toUpdate: podA, + toUpdate: podCopy(podA), allowCreate: true, objOK: hasCreated(t, podA), errOK: func(err error) bool { return err == nil }, @@ -400,13 +431,13 @@ func TestEtcdUpdate(t *testing.T) { "outOfDate": { existing: newerNodeWithPodA, expect: newerNodeWithPodA, - toUpdate: podB, + toUpdate: podCopy(podB), errOK: func(err error) bool { return errors.IsConflict(err) }, }, "unconditionalUpdate": { existing: nodeWithPodAWithResourceVersion, allowUnconditionalUpdate: true, - toUpdate: podA, + toUpdate: podCopy(podA), objOK: func(obj runtime.Object) bool { return true }, errOK: func(err error) bool { return err == nil }, }, @@ -418,7 +449,7 @@ func TestEtcdUpdate(t *testing.T) { registry.UpdateStrategy.(*testRESTStrategy).allowUnconditionalUpdate = item.allowUnconditionalUpdate path := etcdtest.AddPrefix("pods/foo") fakeClient.Data[path] = item.existing - obj, _, err := registry.Update(api.NewDefaultContext(), item.toUpdate) + obj, _, err := registry.Update(testContext, item.toUpdate) if !item.errOK(err) { t.Errorf("%v: unexpected error: %v", name, err) } @@ -446,7 +477,7 @@ func TestEtcdUpdate(t *testing.T) { func TestEtcdGet(t *testing.T) { podA := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, + ObjectMeta: api.ObjectMeta{Namespace: "test", Name: "foo", ResourceVersion: "1"}, Spec: api.PodSpec{NodeName: "machine"}, } @@ -485,11 +516,13 @@ func TestEtcdGet(t *testing.T) { }, } + testContext := api.WithNamespace(api.NewContext(), "test") + for name, item := range table { fakeClient, registry := NewTestGenericEtcdRegistry(t) path := etcdtest.AddPrefix("pods/foo") fakeClient.Data[path] = item.existing - got, err := registry.Get(api.NewContext(), key) + got, err := registry.Get(testContext, key) if !item.errOK(err) { t.Errorf("%v: unexpected error: %v", name, err) } @@ -522,6 +555,8 @@ func TestEtcdDelete(t *testing.T) { E: tools.EtcdErrorNotFound, } + testContext := api.WithNamespace(api.NewContext(), "test") + key := "foo" table := map[string]struct { @@ -545,7 +580,7 @@ func TestEtcdDelete(t *testing.T) { fakeClient, registry := NewTestGenericEtcdRegistry(t) path := etcdtest.AddPrefix("pods/foo") fakeClient.Data[path] = item.existing - obj, err := registry.Delete(api.NewContext(), key, nil) + obj, err := registry.Delete(testContext, key, nil) if !item.errOK(err) { t.Errorf("%v: unexpected error: %v (%#v)", name, err, obj) } @@ -560,23 +595,41 @@ func TestEtcdDelete(t *testing.T) { } func TestEtcdWatch(t *testing.T) { - table := map[string]generic.Matcher{ - "single": setMatcher{sets.NewString("foo")}, - "multi": setMatcher{sets.NewString("foo", "bar")}, + testContext := api.WithNamespace(api.NewContext(), "test") + noNamespaceContext := api.NewContext() + + table := map[string]struct { + generic.Matcher + context api.Context + }{ + "single": { + Matcher: setMatcher{sets.NewString("foo")}, + }, + "multi": { + Matcher: setMatcher{sets.NewString("foo", "bar")}, + }, + "singleNoNamespace": { + Matcher: setMatcher{sets.NewString("foo")}, + context: noNamespaceContext, + }, } for name, m := range table { + ctx := testContext + if m.context != nil { + ctx = m.context + } podA := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "foo", - Namespace: api.NamespaceDefault, + Namespace: "test", ResourceVersion: "1", }, Spec: api.PodSpec{NodeName: "machine"}, } respWithPodA := &etcd.Response{ Node: &etcd.Node{ - Key: "/registry/pods/default/foo", + Key: "/registry/pods/test/foo", Value: runtime.EncodeOrDie(testapi.Default.Codec(), podA), ModifiedIndex: 1, CreatedIndex: 1, @@ -585,7 +638,7 @@ func TestEtcdWatch(t *testing.T) { } fakeClient, registry := NewTestGenericEtcdRegistry(t) - wi, err := registry.WatchPredicate(api.NewContext(), m, "1") + wi, err := registry.WatchPredicate(ctx, m, "1") if err != nil { t.Errorf("%v: unexpected error: %v", name, err) continue diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/matcher.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/matcher.go index b3870747b339..a7e8705c1c4e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/matcher.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/matcher.go @@ -47,7 +47,7 @@ func (s *SelectionPredicate) Matches(obj runtime.Object) (bool, error) { return s.Label.Matches(labels) && s.Field.Matches(fields), nil } -// MatchesSingle will return (name, true) iff s.Field matches on the object's +// MatchesSingle will return (name, true) if and only if s.Field matches on the object's // name. func (s *SelectionPredicate) MatchesSingle() (string, bool) { // TODO: should be namespace.name @@ -118,38 +118,3 @@ var ( _ = Matcher(&SelectionPredicate{}) _ = Matcher(matcherFunc(nil)) ) - -// DecoratorFunc can mutate the provided object prior to being returned. -type DecoratorFunc func(obj runtime.Object) error - -// FilterList filters any list object that conforms to the api conventions, -// provided that 'm' works with the concrete type of list. d is an optional -// decorator for the returned functions. Only matching items are decorated. -func FilterList(list runtime.Object, m Matcher, d DecoratorFunc) (filtered runtime.Object, err error) { - // TODO: push a matcher down into tools.etcdHelper to avoid all this - // nonsense. This is a lot of unnecessary copies. - items, err := runtime.ExtractList(list) - if err != nil { - return nil, err - } - var filteredItems []runtime.Object - for _, obj := range items { - match, err := m.Matches(obj) - if err != nil { - return nil, err - } - if match { - if d != nil { - if err := d(obj); err != nil { - return nil, err - } - } - filteredItems = append(filteredItems, obj) - } - } - err = runtime.SetList(list, filteredItems) - if err != nil { - return nil, err - } - return list, nil -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/matcher_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/matcher_test.go index 669f15b5f804..5cd99cf0a123 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/matcher_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/matcher_test.go @@ -18,7 +18,6 @@ package generic import ( "errors" - "reflect" "testing" "k8s.io/kubernetes/pkg/fields" @@ -118,44 +117,6 @@ func TestSelectionPredicate(t *testing.T) { } } -func TestFilterList(t *testing.T) { - try := &IgnoredList{ - Items: []Ignored{ - {"foo"}, - {"bar"}, - {"baz"}, - {"qux"}, - {"zot"}, - }, - } - expect := &IgnoredList{ - Items: []Ignored{ - {"bar"}, - {"baz"}, - }, - } - - m := MatcherFunc(func(obj runtime.Object) (bool, error) { - i, ok := obj.(*Ignored) - if !ok { - return false, errors.New("wrong type") - } - return i.ID[0] == 'b', nil - }) - if _, matchesSingleObject := m.MatchesSingle(); matchesSingleObject { - t.Errorf("matcher unexpectedly matches only a single object.") - } - - got, err := FilterList(try, m, nil) - if err != nil { - t.Fatalf("Unexpected error %v", err) - } - - if e, a := expect, got; !reflect.DeepEqual(e, a) { - t.Errorf("Expected %#v, got %#v", e, a) - } -} - func TestSingleMatch(t *testing.T) { m := MatchOnKey("pod-name-here", func(obj runtime.Object) (bool, error) { return true, nil }) got, ok := m.MatchesSingle() diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/proxy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/proxy.go index cc4d74440f78..b53d3bef4b6e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/proxy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/proxy.go @@ -44,30 +44,32 @@ type UpgradeAwareProxyHandler struct { WrapTransport bool FlushInterval time.Duration MaxBytesPerSec int64 - err error + Responder ErrorResponder } const defaultFlushInterval = 200 * time.Millisecond -// NewUpgradeAwareProxyHandler creates a new proxy handler with a default flush interval -func NewUpgradeAwareProxyHandler(location *url.URL, transport http.RoundTripper, wrapTransport, upgradeRequired bool) *UpgradeAwareProxyHandler { +// ErrorResponder abstracts error reporting to the proxy handler to remove the need to hardcode a particular +// error format. +type ErrorResponder interface { + Error(err error) +} + +// NewUpgradeAwareProxyHandler creates a new proxy handler with a default flush interval. Responder is required for returning +// errors to the caller. +func NewUpgradeAwareProxyHandler(location *url.URL, transport http.RoundTripper, wrapTransport, upgradeRequired bool, responder ErrorResponder) *UpgradeAwareProxyHandler { return &UpgradeAwareProxyHandler{ Location: location, Transport: transport, WrapTransport: wrapTransport, UpgradeRequired: upgradeRequired, FlushInterval: defaultFlushInterval, + Responder: responder, } } -// RequestError returns an error that occurred while handling request -func (h *UpgradeAwareProxyHandler) RequestError() error { - return h.err -} - // ServeHTTP handles the proxy request func (h *UpgradeAwareProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { - h.err = nil if len(h.Location.Scheme) == 0 { h.Location.Scheme = "http" } @@ -75,7 +77,7 @@ func (h *UpgradeAwareProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Re return } if h.UpgradeRequired { - h.err = errors.NewBadRequest("Upgrade request required") + h.Responder.Error(errors.NewBadRequest("Upgrade request required")) return } @@ -108,7 +110,7 @@ func (h *UpgradeAwareProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Re newReq, err := http.NewRequest(req.Method, loc.String(), req.Body) if err != nil { - h.err = err + h.Responder.Error(err) return } newReq.Header = req.Header @@ -127,27 +129,27 @@ func (h *UpgradeAwareProxyHandler) tryUpgrade(w http.ResponseWriter, req *http.R backendConn, err := proxy.DialURL(h.Location, h.Transport) if err != nil { - h.err = err + h.Responder.Error(err) return true } defer backendConn.Close() requestHijackedConn, _, err := w.(http.Hijacker).Hijack() if err != nil { - h.err = err + h.Responder.Error(err) return true } defer requestHijackedConn.Close() newReq, err := http.NewRequest(req.Method, h.Location.String(), req.Body) if err != nil { - h.err = err + h.Responder.Error(err) return true } newReq.Header = req.Header if err = newReq.Write(backendConn); err != nil { - h.err = err + h.Responder.Error(err) return true } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/proxy_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/proxy_test.go index 829b1a6d5ef8..9497d7454d62 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/proxy_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/proxy_test.go @@ -26,6 +26,7 @@ import ( "net/http" "net/http/httptest" "net/url" + "strings" "testing" "golang.org/x/net/websocket" @@ -33,6 +34,19 @@ import ( "k8s.io/kubernetes/pkg/util/proxy" ) +type fakeResponder struct { + called bool + err error +} + +func (r *fakeResponder) Error(err error) { + if r.called { + panic("called twice") + } + r.called = true + r.err = err +} + type SimpleBackendHandler struct { requestURL url.URL requestHeader http.Header @@ -110,6 +124,8 @@ func TestServeHTTP(t *testing.T) { responseHeader map[string]string expectedRespHeader map[string]string notExpectedRespHeader []string + upgradeRequired bool + expectError func(err error) bool }{ { name: "root path, simple get", @@ -117,6 +133,15 @@ func TestServeHTTP(t *testing.T) { requestPath: "/", expectedPath: "/", }, + { + name: "no upgrade header sent", + method: "GET", + requestPath: "/", + upgradeRequired: true, + expectError: func(err error) bool { + return err != nil && strings.Contains(err.Error(), "Upgrade request required") + }, + }, { name: "simple path, get", method: "GET", @@ -163,7 +188,7 @@ func TestServeHTTP(t *testing.T) { }, } - for _, test := range tests { + for i, test := range tests { func() { backendResponse := "Hello" backendResponseHeader := test.responseHeader @@ -179,10 +204,13 @@ func TestServeHTTP(t *testing.T) { backendServer := httptest.NewServer(backendHandler) defer backendServer.Close() + responder := &fakeResponder{} backendURL, _ := url.Parse(backendServer.URL) backendURL.Path = test.requestPath proxyHandler := &UpgradeAwareProxyHandler{ - Location: backendURL, + Location: backendURL, + Responder: responder, + UpgradeRequired: test.upgradeRequired, } proxyServer := httptest.NewServer(proxyHandler) defer proxyServer.Close() @@ -214,6 +242,17 @@ func TestServeHTTP(t *testing.T) { t.Errorf("Error from proxy request: %v", err) } + if test.expectError != nil { + if !responder.called { + t.Errorf("%d: responder was not invoked", i) + return + } + if !test.expectError(responder.err) { + t.Errorf("%d: unexpected error: %v", i, responder.err) + } + return + } + // Validate backend request // Method if backendHandler.requestMethod != test.method { @@ -253,9 +292,8 @@ func TestServeHTTP(t *testing.T) { } // Error - err = proxyHandler.RequestError() - if err != nil { - t.Errorf("Unexpected proxy handler error: %v", err) + if responder.called { + t.Errorf("Unexpected proxy handler error: %v", responder.err) } }() } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/response_checker.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/response_checker.go new file mode 100644 index 000000000000..9213229df4d4 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/response_checker.go @@ -0,0 +1,70 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 rest + +import ( + "fmt" + "io" + "io/ioutil" + "net/http" + + "k8s.io/kubernetes/pkg/api/errors" +) + +// Check the http error status from a location URL. +// And convert an error into a structured API object. +// Finally ensure we close the body before returning the error +type HttpResponseChecker interface { + Check(resp *http.Response) error +} + +// Max length read from the response body of a location which returns error status +const ( + maxReadLength = 50000 +) + +// A generic http response checker to transform the error. +type GenericHttpResponseChecker struct { + Kind string + Name string +} + +func (checker GenericHttpResponseChecker) Check(resp *http.Response) error { + if resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusPartialContent { + defer resp.Body.Close() + bodyBytes, err := ioutil.ReadAll(io.LimitReader(resp.Body, maxReadLength)) + if err != nil { + return errors.NewInternalError(err) + } + bodyText := string(bodyBytes) + + switch { + case resp.StatusCode == http.StatusInternalServerError: + return errors.NewInternalError(fmt.Errorf("%s", bodyText)) + case resp.StatusCode == http.StatusBadRequest: + return errors.NewBadRequest(bodyText) + case resp.StatusCode == http.StatusNotFound: + return errors.NewGenericServerResponse(resp.StatusCode, "", checker.Kind, checker.Name, bodyText, 0, false) + } + return errors.NewGenericServerResponse(resp.StatusCode, "", checker.Kind, checker.Name, bodyText, 0, false) + } + return nil +} + +func NewGenericHttpResponseChecker(kind, name string) GenericHttpResponseChecker { + return GenericHttpResponseChecker{Kind: kind, Name: name} +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/response_checker_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/response_checker_test.go new file mode 100644 index 000000000000..ece5cd0a588e --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/response_checker_test.go @@ -0,0 +1,94 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 rest + +import ( + "bytes" + "fmt" + "io/ioutil" + "net/http" + "reflect" + "strings" + "testing" + + "k8s.io/kubernetes/pkg/api/errors" +) + +func TestGenericHttpResponseChecker(t *testing.T) { + responseChecker := NewGenericHttpResponseChecker("Pod", "foo") + tests := []struct { + resp *http.Response + expectError bool + expected error + name string + }{ + { + resp: &http.Response{ + Body: ioutil.NopCloser(bytes.NewBufferString("Success")), + StatusCode: http.StatusOK, + }, + expectError: false, + name: "ok", + }, + { + resp: &http.Response{ + Body: ioutil.NopCloser(bytes.NewBufferString("Invalid request.")), + StatusCode: http.StatusBadRequest, + }, + expectError: true, + expected: errors.NewBadRequest("Invalid request."), + name: "bad request", + }, + { + resp: &http.Response{ + Body: ioutil.NopCloser(bytes.NewBufferString("Pod does not exist.")), + StatusCode: http.StatusInternalServerError, + }, + expectError: true, + expected: errors.NewInternalError(fmt.Errorf("%s", "Pod does not exist.")), + name: "internal server error", + }, + } + for _, test := range tests { + err := responseChecker.Check(test.resp) + if test.expectError && err == nil { + t.Error("unexpected non-error") + } + if !test.expectError && err != nil { + t.Errorf("unexpected error: %v", err) + } + if test.expectError && !reflect.DeepEqual(err, test.expected) { + t.Errorf("expected: %s, saw: %s", test.expected, err) + } + } +} + +func TestGenericHttpResponseCheckerLimitReader(t *testing.T) { + responseChecker := NewGenericHttpResponseChecker("Pod", "foo") + excessedString := strings.Repeat("a", (maxReadLength + 10000)) + resp := &http.Response{ + Body: ioutil.NopCloser(bytes.NewBufferString(excessedString)), + StatusCode: http.StatusBadRequest, + } + err := responseChecker.Check(resp) + if err == nil { + t.Error("unexpected non-error") + } + if len(err.Error()) != maxReadLength { + t.Errorf("expected lenth of error message: %d, saw: %d", maxReadLength, len(err.Error())) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/streamer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/streamer.go index ee303dbb8629..6c5dedaba064 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/streamer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/streamer.go @@ -28,10 +28,11 @@ import ( // LocationStreamer is a resource that streams the contents of a particular // location URL type LocationStreamer struct { - Location *url.URL - Transport http.RoundTripper - ContentType string - Flush bool + Location *url.URL + Transport http.RoundTripper + ContentType string + Flush bool + ResponseChecker HttpResponseChecker } // a LocationStreamer must implement a rest.ResourceStreamer @@ -54,8 +55,15 @@ func (s *LocationStreamer) InputStream(apiVersion, acceptHeader string) (stream client := &http.Client{Transport: transport} resp, err := client.Get(s.Location.String()) if err != nil { - return + return nil, false, "", err } + + if s.ResponseChecker != nil { + if err = s.ResponseChecker.Check(resp); err != nil { + return nil, false, "", err + } + } + contentType = s.ContentType if len(contentType) == 0 { contentType = resp.Header.Get("Content-Type") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/streamer_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/streamer_test.go index 9b6d1bec8e0d..c81c22439f3d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/streamer_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/generic/rest/streamer_test.go @@ -24,7 +24,10 @@ import ( "net/http" "net/http/httptest" "net/url" + "reflect" "testing" + + "k8s.io/kubernetes/pkg/api/errors" ) func TestInputStreamReader(t *testing.T) { @@ -116,3 +119,29 @@ func TestInputStreamTransport(t *testing.T) { t.Errorf("Stream content does not match. Got: %s. Expected: %s.", string(result), message) } } + +func fakeInternalServerErrorTransport(mime, message string) http.RoundTripper { + content := fmt.Sprintf("HTTP/1.1 500 \"Internal Server Error\"\nContent-Type: %s\n\n%s", mime, message) + return &testTransport{body: content} +} + +func TestInputStreamInternalServerErrorTransport(t *testing.T) { + message := "Pod is in PodPending" + location, _ := url.Parse("http://www.example.com") + streamer := &LocationStreamer{ + Location: location, + Transport: fakeInternalServerErrorTransport("text/plain", message), + ResponseChecker: NewGenericHttpResponseChecker("", ""), + } + expectedError := errors.NewInternalError(fmt.Errorf("%s", message)) + + _, _, _, err := streamer.InputStream("", "") + if err == nil { + t.Errorf("unexpected non-error") + return + } + + if !reflect.DeepEqual(err, expectedError) { + t.Errorf("StreamInternalServerError does not match. Got: %s. Expected: %s.", err, expectedError) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd/etcd.go index b620cfe9d894..8512a907d5c7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd/etcd.go @@ -18,7 +18,7 @@ package etcd import ( "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -33,12 +33,12 @@ type REST struct { } // NewREST returns a RESTStorage object that will work against horizontal pod autoscalers. -func NewREST(s storage.Interface) *REST { +func NewREST(s storage.Interface) (*REST, *StatusREST) { prefix := "/horizontalpodautoscalers" store := &etcdgeneric.Etcd{ - NewFunc: func() runtime.Object { return &experimental.HorizontalPodAutoscaler{} }, + NewFunc: func() runtime.Object { return &extensions.HorizontalPodAutoscaler{} }, // NewListFunc returns an object capable of storing results of an etcd list. - NewListFunc: func() runtime.Object { return &experimental.HorizontalPodAutoscalerList{} }, + NewListFunc: func() runtime.Object { return &extensions.HorizontalPodAutoscalerList{} }, // Produces a path that etcd understands, to the root of the resource // by combining the namespace in the context with the given prefix KeyRootFunc: func(ctx api.Context) string { @@ -51,7 +51,7 @@ func NewREST(s storage.Interface) *REST { }, // Retrieve the name field of an autoscaler ObjectNameFunc: func(obj runtime.Object) (string, error) { - return obj.(*experimental.HorizontalPodAutoscaler).Name, nil + return obj.(*extensions.HorizontalPodAutoscaler).Name, nil }, // Used to match objects based on labels/fields for list PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { @@ -67,5 +67,21 @@ func NewREST(s storage.Interface) *REST { Storage: s, } - return &REST{store} + statusStore := *store + statusStore.UpdateStrategy = horizontalpodautoscaler.StatusStrategy + return &REST{store}, &StatusREST{store: &statusStore} +} + +// StatusREST implements the REST endpoint for changing the status of a daemonset +type StatusREST struct { + store *etcdgeneric.Etcd +} + +func (r *StatusREST) New() runtime.Object { + return &extensions.HorizontalPodAutoscaler{} +} + +// Update alters the status subset of an object. +func (r *StatusREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) { + return r.store.Update(ctx, obj) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd/etcd_test.go index 91e531049c08..027e8b500f0f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd/etcd_test.go @@ -21,9 +21,9 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" - "k8s.io/kubernetes/pkg/apis/experimental" - // Ensure that experimental/v1 package is initialized. - _ "k8s.io/kubernetes/pkg/apis/experimental/v1" + "k8s.io/kubernetes/pkg/apis/extensions" + // Ensure that extensions/v1beta1 package is initialized. + _ "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/registrytest" @@ -31,30 +31,31 @@ import ( "k8s.io/kubernetes/pkg/tools" ) -func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { - etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "experimental") - return NewREST(etcdStorage), fakeClient +func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) { + etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "extensions") + storage, statusStorage := NewREST(etcdStorage) + return storage, statusStorage, fakeClient } -func validNewHorizontalPodAutoscaler(name string) *experimental.HorizontalPodAutoscaler { - return &experimental.HorizontalPodAutoscaler{ +func validNewHorizontalPodAutoscaler(name string) *extensions.HorizontalPodAutoscaler { + return &extensions.HorizontalPodAutoscaler{ ObjectMeta: api.ObjectMeta{ Name: name, Namespace: api.NamespaceDefault, }, - Spec: experimental.HorizontalPodAutoscalerSpec{ - ScaleRef: &experimental.SubresourceReference{ + Spec: extensions.HorizontalPodAutoscalerSpec{ + ScaleRef: &extensions.SubresourceReference{ Subresource: "scale", }, - MinCount: 1, - MaxCount: 5, - Target: experimental.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")}, + MinReplicas: 1, + MaxReplicas: 5, + Target: extensions.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")}, }, } } func TestCreate(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) autoscaler := validNewHorizontalPodAutoscaler("foo") autoscaler.ObjectMeta = api.ObjectMeta{} @@ -62,45 +63,45 @@ func TestCreate(t *testing.T) { // valid autoscaler, // invalid - &experimental.HorizontalPodAutoscaler{}, + &extensions.HorizontalPodAutoscaler{}, ) } func TestUpdate(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestUpdate( // valid validNewHorizontalPodAutoscaler("foo"), // updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.HorizontalPodAutoscaler) - object.Spec.MaxCount = object.Spec.MaxCount + 1 + object := obj.(*extensions.HorizontalPodAutoscaler) + object.Spec.MaxReplicas = object.Spec.MaxReplicas + 1 return object }, ) } func TestDelete(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestDelete(validNewHorizontalPodAutoscaler("foo")) } func TestGet(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestGet(validNewHorizontalPodAutoscaler("foo")) } func TestList(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestList(validNewHorizontalPodAutoscaler("foo")) } func TestWatch(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestWatch( validNewHorizontalPodAutoscaler("foo"), @@ -119,3 +120,5 @@ func TestWatch(t *testing.T) { }, ) } + +// TODO TestUpdateStatus diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/strategy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/strategy.go index 88aa5c8f54c6..955da299c4c5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/strategy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/strategy.go @@ -20,8 +20,8 @@ import ( "fmt" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" - "k8s.io/kubernetes/pkg/apis/experimental/validation" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -46,12 +46,15 @@ func (autoscalerStrategy) NamespaceScoped() bool { // PrepareForCreate clears fields that are not allowed to be set by end users on creation. func (autoscalerStrategy) PrepareForCreate(obj runtime.Object) { - _ = obj.(*experimental.HorizontalPodAutoscaler) + newHPA := obj.(*extensions.HorizontalPodAutoscaler) + + // create cannot set status + newHPA.Status = extensions.HorizontalPodAutoscalerStatus{} } // Validate validates a new autoscaler. func (autoscalerStrategy) Validate(ctx api.Context, obj runtime.Object) errs.ValidationErrorList { - autoscaler := obj.(*experimental.HorizontalPodAutoscaler) + autoscaler := obj.(*extensions.HorizontalPodAutoscaler) return validation.ValidateHorizontalPodAutoscaler(autoscaler) } @@ -62,19 +65,22 @@ func (autoscalerStrategy) AllowCreateOnUpdate() bool { // PrepareForUpdate clears fields that are not allowed to be set by end users on update. func (autoscalerStrategy) PrepareForUpdate(obj, old runtime.Object) { - _ = obj.(*experimental.HorizontalPodAutoscaler) + newHPA := obj.(*extensions.HorizontalPodAutoscaler) + oldHPA := obj.(*extensions.HorizontalPodAutoscaler) + // Update is not allowed to set status + newHPA.Status = oldHPA.Status } // ValidateUpdate is the default update validation for an end user. func (autoscalerStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) errs.ValidationErrorList { - return validation.ValidateHorizontalPodAutoscalerUpdate(obj.(*experimental.HorizontalPodAutoscaler), old.(*experimental.HorizontalPodAutoscaler)) + return validation.ValidateHorizontalPodAutoscalerUpdate(obj.(*extensions.HorizontalPodAutoscaler), old.(*extensions.HorizontalPodAutoscaler)) } func (autoscalerStrategy) AllowUnconditionalUpdate() bool { return true } -func AutoscalerToSelectableFields(limitRange *experimental.HorizontalPodAutoscaler) fields.Set { +func AutoscalerToSelectableFields(limitRange *extensions.HorizontalPodAutoscaler) fields.Set { return fields.Set{} } @@ -83,7 +89,7 @@ func MatchAutoscaler(label labels.Selector, field fields.Selector) generic.Match Label: label, Field: field, GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { - hpa, ok := obj.(*experimental.HorizontalPodAutoscaler) + hpa, ok := obj.(*extensions.HorizontalPodAutoscaler) if !ok { return nil, nil, fmt.Errorf("given object is not a horizontal pod autoscaler.") } @@ -91,3 +97,20 @@ func MatchAutoscaler(label labels.Selector, field fields.Selector) generic.Match }, } } + +type autoscalerStatusStrategy struct { + autoscalerStrategy +} + +var StatusStrategy = autoscalerStatusStrategy{Strategy} + +func (autoscalerStatusStrategy) PrepareForUpdate(obj, old runtime.Object) { + newAutoscaler := obj.(*extensions.HorizontalPodAutoscaler) + oldAutoscaler := old.(*extensions.HorizontalPodAutoscaler) + // status changes are not allowed to update spec + newAutoscaler.Spec = oldAutoscaler.Spec +} + +func (autoscalerStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) errs.ValidationErrorList { + return validation.ValidateHorizontalPodAutoscalerStatusUpdate(obj.(*extensions.HorizontalPodAutoscaler), old.(*extensions.HorizontalPodAutoscaler)) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/doc.go similarity index 76% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/doc.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/doc.go index 1b5bf6ac7962..5a6272cc546b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/doc.go @@ -14,6 +14,4 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package securitycontextconstraints provides Registry interface and its REST -// implementation for storing SecurityContextConstraints api objects. -package securitycontextconstraints +package ingress diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/etcd/etcd.go new file mode 100644 index 000000000000..b9f3c61650c2 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/etcd/etcd.go @@ -0,0 +1,77 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 etcd + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/registry/generic" + etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd" + ingress "k8s.io/kubernetes/pkg/registry/ingress" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/storage" +) + +const ( + IngressPath string = "/ingress" +) + +// rest implements a RESTStorage for replication controllers against etcd +type REST struct { + *etcdgeneric.Etcd +} + +// NewREST returns a RESTStorage object that will work against replication controllers. +func NewREST(s storage.Interface) *REST { + store := &etcdgeneric.Etcd{ + NewFunc: func() runtime.Object { return &extensions.Ingress{} }, + + // NewListFunc returns an object capable of storing results of an etcd list. + NewListFunc: func() runtime.Object { return &extensions.IngressList{} }, + // Produces a ingress that etcd understands, to the root of the resource + // by combining the namespace in the context with the given prefix + KeyRootFunc: func(ctx api.Context) string { + return etcdgeneric.NamespaceKeyRootFunc(ctx, IngressPath) + }, + // Produces a ingress that etcd understands, to the resource by combining + // the namespace in the context with the given prefix + KeyFunc: func(ctx api.Context, name string) (string, error) { + return etcdgeneric.NamespaceKeyFunc(ctx, IngressPath, name) + }, + // Retrieve the name field of a replication controller + ObjectNameFunc: func(obj runtime.Object) (string, error) { + return obj.(*extensions.Ingress).Name, nil + }, + // Used to match objects based on labels/fields for list and watch + PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { + return ingress.MatchIngress(label, field) + }, + EndpointName: "ingress", + + // Used to validate controller creation + CreateStrategy: ingress.Strategy, + + // Used to validate controller updates + UpdateStrategy: ingress.Strategy, + + Storage: s, + } + + return &REST{store} +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/etcd/etcd_test.go new file mode 100644 index 000000000000..b5ecd92b3805 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/etcd/etcd_test.go @@ -0,0 +1,203 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 etcd + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/registry/registrytest" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/tools" + "k8s.io/kubernetes/pkg/util" +) + +func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { + etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "extensions") + ingressStorage := NewREST(etcdStorage) + return ingressStorage, fakeClient +} + +var ( + namespace = api.NamespaceNone + name = "foo-ingress" + defaultHostname = "foo.bar.com" + defaultBackendName = "default-backend" + defaultBackendPort = util.IntOrString{Kind: util.IntstrInt, IntVal: 80} + defaultLoadBalancer = "127.0.0.1" + defaultPath = "/foo" + defaultPathMap = map[string]string{defaultPath: defaultBackendName} +) + +type IngressRuleValues map[string]string + +func toHTTPIngressPaths(pathMap map[string]string) []extensions.HTTPIngressPath { + httpPaths := []extensions.HTTPIngressPath{} + for path, backend := range pathMap { + httpPaths = append(httpPaths, extensions.HTTPIngressPath{ + Path: path, + Backend: extensions.IngressBackend{ + ServiceName: backend, + ServicePort: defaultBackendPort, + }, + }) + } + return httpPaths +} + +func toIngressRules(hostRules map[string]IngressRuleValues) []extensions.IngressRule { + rules := []extensions.IngressRule{} + for host, pathMap := range hostRules { + rules = append(rules, extensions.IngressRule{ + Host: host, + IngressRuleValue: extensions.IngressRuleValue{ + HTTP: &extensions.HTTPIngressRuleValue{ + Paths: toHTTPIngressPaths(pathMap), + }, + }, + }) + } + return rules +} + +func newIngress(pathMap map[string]string) *extensions.Ingress { + return &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: extensions.IngressSpec{ + Backend: &extensions.IngressBackend{ + ServiceName: defaultBackendName, + ServicePort: defaultBackendPort, + }, + Rules: toIngressRules(map[string]IngressRuleValues{ + defaultHostname: pathMap, + }), + }, + Status: extensions.IngressStatus{ + LoadBalancer: api.LoadBalancerStatus{ + Ingress: []api.LoadBalancerIngress{ + {IP: defaultLoadBalancer}, + }, + }, + }, + } +} + +func validIngress() *extensions.Ingress { + return newIngress(defaultPathMap) +} + +func TestCreate(t *testing.T) { + storage, fakeClient := newStorage(t) + test := registrytest.New(t, fakeClient, storage.Etcd) + ingress := validIngress() + noDefaultBackendAndRules := validIngress() + noDefaultBackendAndRules.Spec.Backend = &extensions.IngressBackend{} + noDefaultBackendAndRules.Spec.Rules = []extensions.IngressRule{} + badPath := validIngress() + badPath.Spec.Rules = toIngressRules(map[string]IngressRuleValues{ + "foo.bar.com": {"/invalid[": "svc"}}) + test.TestCreate( + // valid + ingress, + noDefaultBackendAndRules, + badPath, + ) +} + +func TestUpdate(t *testing.T) { + storage, fakeClient := newStorage(t) + test := registrytest.New(t, fakeClient, storage.Etcd) + test.TestUpdate( + // valid + validIngress(), + // updateFunc + func(obj runtime.Object) runtime.Object { + object := obj.(*extensions.Ingress) + object.Spec.Rules = toIngressRules(map[string]IngressRuleValues{ + "bar.foo.com": {"/bar": defaultBackendName}, + }) + return object + }, + // invalid updateFunc: ObjeceMeta is not to be tampered with. + func(obj runtime.Object) runtime.Object { + object := obj.(*extensions.Ingress) + object.UID = "newUID" + return object + }, + + func(obj runtime.Object) runtime.Object { + object := obj.(*extensions.Ingress) + object.Name = "" + return object + }, + + func(obj runtime.Object) runtime.Object { + object := obj.(*extensions.Ingress) + object.Spec.Rules = toIngressRules(map[string]IngressRuleValues{ + "foo.bar.com": {"/invalid[": "svc"}}) + return object + }, + ) +} + +func TestDelete(t *testing.T) { + storage, fakeClient := newStorage(t) + test := registrytest.New(t, fakeClient, storage.Etcd) + test.TestDelete(validIngress()) +} + +func TestGet(t *testing.T) { + storage, fakeClient := newStorage(t) + test := registrytest.New(t, fakeClient, storage.Etcd) + test.TestGet(validIngress()) +} + +func TestList(t *testing.T) { + storage, fakeClient := newStorage(t) + test := registrytest.New(t, fakeClient, storage.Etcd) + test.TestList(validIngress()) +} + +func TestWatch(t *testing.T) { + storage, fakeClient := newStorage(t) + test := registrytest.New(t, fakeClient, storage.Etcd) + test.TestWatch( + validIngress(), + // matching labels + []labels.Set{}, + // not matching labels + []labels.Set{ + {"a": "c"}, + {"foo": "bar"}, + }, + // matching fields + []fields.Set{ + {"metadata.name": name}, + }, + // not matching fields + []fields.Set{ + {"metadata.name": "bar"}, + {"name": name}, + }, + ) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/strategy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/strategy.go new file mode 100644 index 000000000000..6bad71419de7 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/ingress/strategy.go @@ -0,0 +1,116 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 ingress + +import ( + "fmt" + "reflect" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/extensions/validation" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/registry/generic" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +// ingressStrategy implements verification logic for Replication Ingresss. +type ingressStrategy struct { + runtime.ObjectTyper + api.NameGenerator +} + +// Strategy is the default logic that applies when creating and updating Replication Ingress objects. +var Strategy = ingressStrategy{api.Scheme, api.SimpleNameGenerator} + +// NamespaceScoped returns true because all Ingress' need to be within a namespace. +func (ingressStrategy) NamespaceScoped() bool { + return true +} + +// PrepareForCreate clears the status of an Ingress before creation. +func (ingressStrategy) PrepareForCreate(obj runtime.Object) { + ingress := obj.(*extensions.Ingress) + ingress.Status = extensions.IngressStatus{} + + ingress.Generation = 1 +} + +// PrepareForUpdate clears fields that are not allowed to be set by end users on update. +func (ingressStrategy) PrepareForUpdate(obj, old runtime.Object) { + newIngress := obj.(*extensions.Ingress) + oldIngress := old.(*extensions.Ingress) + //TODO: Clear Ingress status once we have a sub-resource. + + // Any changes to the spec increment the generation number, any changes to the + // status should reflect the generation number of the corresponding object. + // See api.ObjectMeta description for more information on Generation. + if !reflect.DeepEqual(oldIngress.Spec, newIngress.Spec) { + newIngress.Generation = oldIngress.Generation + 1 + } + +} + +// Validate validates a new Ingress. +func (ingressStrategy) Validate(ctx api.Context, obj runtime.Object) fielderrors.ValidationErrorList { + ingress := obj.(*extensions.Ingress) + err := validation.ValidateIngress(ingress) + return err +} + +// AllowCreateOnUpdate is false for Ingress; this means POST is needed to create one. +func (ingressStrategy) AllowCreateOnUpdate() bool { + return false +} + +// ValidateUpdate is the default update validation for an end user. +func (ingressStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList { + validationErrorList := validation.ValidateIngress(obj.(*extensions.Ingress)) + updateErrorList := validation.ValidateIngressUpdate(old.(*extensions.Ingress), obj.(*extensions.Ingress)) + return append(validationErrorList, updateErrorList...) +} + +// AllowUnconditionalUpdate is the default update policy for Ingress objects. +func (ingressStrategy) AllowUnconditionalUpdate() bool { + return true +} + +// IngressToSelectableFields returns a label set that represents the object. +func IngressToSelectableFields(ingress *extensions.Ingress) fields.Set { + return fields.Set{ + "metadata.name": ingress.Name, + } +} + +// MatchIngress is the filter used by the generic etcd backend to ingress +// watch events from etcd to clients of the apiserver only interested in specific +// labels/fields. +func MatchIngress(label labels.Selector, field fields.Selector) generic.Matcher { + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + ingress, ok := obj.(*extensions.Ingress) + if !ok { + return nil, nil, fmt.Errorf("Given object is not an Ingress.") + } + return labels.Set(ingress.ObjectMeta.Labels), IngressToSelectableFields(ingress), nil + }, + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/doc.go index a76a224cbff6..d6351371c5a5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/doc.go @@ -14,6 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package controller provides Registry interface and it's RESTStorage +// Package job provides Registry interface and it's RESTStorage // implementation for storing Job api objects. package job diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/etcd/etcd.go index b6ff7bd77503..1ea6c6cc28d9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/etcd/etcd.go @@ -18,7 +18,7 @@ package etcd import ( "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -28,7 +28,7 @@ import ( "k8s.io/kubernetes/pkg/storage" ) -// rest implements a RESTStorage for jobs against etcd +// REST implements a RESTStorage for jobs against etcd type REST struct { *etcdgeneric.Etcd } @@ -38,12 +38,12 @@ type REST struct { var jobPrefix = "/jobs" // NewREST returns a RESTStorage object that will work against Jobs. -func NewREST(s storage.Interface) *REST { +func NewREST(s storage.Interface) (*REST, *StatusREST) { store := &etcdgeneric.Etcd{ - NewFunc: func() runtime.Object { return &experimental.Job{} }, + NewFunc: func() runtime.Object { return &extensions.Job{} }, // NewListFunc returns an object capable of storing results of an etcd list. - NewListFunc: func() runtime.Object { return &experimental.JobList{} }, + NewListFunc: func() runtime.Object { return &extensions.JobList{} }, // Produces a path that etcd understands, to the root of the resource // by combining the namespace in the context with the given prefix KeyRootFunc: func(ctx api.Context) string { @@ -56,7 +56,7 @@ func NewREST(s storage.Interface) *REST { }, // Retrieve the name field of a job ObjectNameFunc: func(obj runtime.Object) (string, error) { - return obj.(*experimental.Job).Name, nil + return obj.(*extensions.Job).Name, nil }, // Used to match objects based on labels/fields for list and watch PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { @@ -73,5 +73,22 @@ func NewREST(s storage.Interface) *REST { Storage: s, } - return &REST{store} + statusStore := *store + statusStore.UpdateStrategy = job.StatusStrategy + + return &REST{store}, &StatusREST{store: &statusStore} +} + +// StatusREST implements the REST endpoint for changing the status of a resourcequota. +type StatusREST struct { + store *etcdgeneric.Etcd +} + +func (r *StatusREST) New() runtime.Object { + return &extensions.Job{} +} + +// Update alters the status subset of an object. +func (r *StatusREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) { + return r.store.Update(ctx, obj) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/etcd/etcd_test.go index 2f04c1fa6b3f..399e25479524 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/etcd/etcd_test.go @@ -20,9 +20,9 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" - // Ensure that experimental/v1 package is initialized. - _ "k8s.io/kubernetes/pkg/apis/experimental/v1" + "k8s.io/kubernetes/pkg/apis/extensions" + // Ensure that extensions/v1beta1 package is initialized. + _ "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/registrytest" @@ -30,24 +30,25 @@ import ( "k8s.io/kubernetes/pkg/tools" ) -func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { - etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "experimental") - return NewREST(etcdStorage), fakeClient +func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) { + etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "extensions") + storage, statusStorage := NewREST(etcdStorage) + return storage, statusStorage, fakeClient } -func validNewJob() *experimental.Job { +func validNewJob() *extensions.Job { completions := 1 parallelism := 1 - return &experimental.Job{ + return &extensions.Job{ ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: "default", }, - Spec: experimental.JobSpec{ + Spec: extensions.JobSpec{ Completions: &completions, Parallelism: ¶llelism, Selector: map[string]string{"a": "b"}, - Template: &api.PodTemplateSpec{ + Template: api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: map[string]string{"a": "b"}, }, @@ -68,7 +69,7 @@ func validNewJob() *experimental.Job { } func TestCreate(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) validJob := validNewJob() validJob.ObjectMeta = api.ObjectMeta{} @@ -76,8 +77,8 @@ func TestCreate(t *testing.T) { // valid validJob, // invalid (empty selector) - &experimental.Job{ - Spec: experimental.JobSpec{ + &extensions.Job{ + Spec: extensions.JobSpec{ Completions: validJob.Spec.Completions, Selector: map[string]string{}, Template: validJob.Spec.Template, @@ -87,47 +88,52 @@ func TestCreate(t *testing.T) { } func TestUpdate(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) - completions := 2 + two := 2 test.TestUpdate( // valid validNewJob(), // updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.Job) - object.Spec.Completions = &completions + object := obj.(*extensions.Job) + object.Spec.Parallelism = &two return object }, // invalid updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.Job) + object := obj.(*extensions.Job) object.Spec.Selector = map[string]string{} return object }, + func(obj runtime.Object) runtime.Object { + object := obj.(*extensions.Job) + object.Spec.Completions = &two + return object + }, ) } func TestDelete(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestDelete(validNewJob()) } func TestGet(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestGet(validNewJob()) } func TestList(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestList(validNewJob()) } func TestWatch(t *testing.T) { - storage, fakeClient := newStorage(t) + storage, _, fakeClient := newStorage(t) test := registrytest.New(t, fakeClient, storage.Etcd) test.TestWatch( validNewJob(), @@ -146,3 +152,5 @@ func TestWatch(t *testing.T) { }, ) } + +// TODO: test update /status diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/registry.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/registry.go index de6e892157d7..fb36dfa55121 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/registry.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/registry.go @@ -21,7 +21,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/rest" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/watch" @@ -30,15 +30,15 @@ import ( // Registry is an interface for things that know how to store Jobs. type Registry interface { // ListJobs obtains a list of Jobs having labels and fields which match selector. - ListJobs(ctx api.Context, label labels.Selector, field fields.Selector) (*experimental.JobList, error) + ListJobs(ctx api.Context, label labels.Selector, field fields.Selector) (*extensions.JobList, error) // WatchJobs watch for new/changed/deleted Jobs. WatchJobs(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) // GetJobs gets a specific Job. - GetJob(ctx api.Context, name string) (*experimental.Job, error) + GetJob(ctx api.Context, name string) (*extensions.Job, error) // CreateJob creates a Job based on a specification. - CreateJob(ctx api.Context, job *experimental.Job) (*experimental.Job, error) + CreateJob(ctx api.Context, job *extensions.Job) (*extensions.Job, error) // UpdateJob updates an existing Job. - UpdateJob(ctx api.Context, job *experimental.Job) (*experimental.Job, error) + UpdateJob(ctx api.Context, job *extensions.Job) (*extensions.Job, error) // DeleteJob deletes an existing Job. DeleteJob(ctx api.Context, name string) error } @@ -54,7 +54,7 @@ func NewRegistry(s rest.StandardStorage) Registry { return &storage{s} } -func (s *storage) ListJobs(ctx api.Context, label labels.Selector, field fields.Selector) (*experimental.JobList, error) { +func (s *storage) ListJobs(ctx api.Context, label labels.Selector, field fields.Selector) (*extensions.JobList, error) { if !field.Empty() { return nil, fmt.Errorf("field selector not supported yet") } @@ -62,35 +62,35 @@ func (s *storage) ListJobs(ctx api.Context, label labels.Selector, field fields. if err != nil { return nil, err } - return obj.(*experimental.JobList), err + return obj.(*extensions.JobList), err } func (s *storage) WatchJobs(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { return s.Watch(ctx, label, field, resourceVersion) } -func (s *storage) GetJob(ctx api.Context, name string) (*experimental.Job, error) { +func (s *storage) GetJob(ctx api.Context, name string) (*extensions.Job, error) { obj, err := s.Get(ctx, name) if err != nil { return nil, err } - return obj.(*experimental.Job), nil + return obj.(*extensions.Job), nil } -func (s *storage) CreateJob(ctx api.Context, job *experimental.Job) (*experimental.Job, error) { +func (s *storage) CreateJob(ctx api.Context, job *extensions.Job) (*extensions.Job, error) { obj, err := s.Create(ctx, job) if err != nil { return nil, err } - return obj.(*experimental.Job), nil + return obj.(*extensions.Job), nil } -func (s *storage) UpdateJob(ctx api.Context, job *experimental.Job) (*experimental.Job, error) { +func (s *storage) UpdateJob(ctx api.Context, job *extensions.Job) (*extensions.Job, error) { obj, _, err := s.Update(ctx, job) if err != nil { return nil, err } - return obj.(*experimental.Job), nil + return obj.(*extensions.Job), nil } func (s *storage) DeleteJob(ctx api.Context, name string) error { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/strategy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/strategy.go index 4394d57744f5..b6221db434b5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/strategy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/strategy.go @@ -21,8 +21,8 @@ import ( "strconv" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" - "k8s.io/kubernetes/pkg/apis/experimental/validation" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -46,20 +46,20 @@ func (jobStrategy) NamespaceScoped() bool { // PrepareForCreate clears the status of a job before creation. func (jobStrategy) PrepareForCreate(obj runtime.Object) { - job := obj.(*experimental.Job) - job.Status = experimental.JobStatus{} + job := obj.(*extensions.Job) + job.Status = extensions.JobStatus{} } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. func (jobStrategy) PrepareForUpdate(obj, old runtime.Object) { - newJob := obj.(*experimental.Job) - oldJob := old.(*experimental.Job) + newJob := obj.(*extensions.Job) + oldJob := old.(*extensions.Job) newJob.Status = oldJob.Status } // Validate validates a new job. func (jobStrategy) Validate(ctx api.Context, obj runtime.Object) fielderrors.ValidationErrorList { - job := obj.(*experimental.Job) + job := obj.(*extensions.Job) return validation.ValidateJob(job) } @@ -74,16 +74,32 @@ func (jobStrategy) AllowCreateOnUpdate() bool { // ValidateUpdate is the default update validation for an end user. func (jobStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList { - validationErrorList := validation.ValidateJob(obj.(*experimental.Job)) - updateErrorList := validation.ValidateJobUpdate(old.(*experimental.Job), obj.(*experimental.Job)) + validationErrorList := validation.ValidateJob(obj.(*extensions.Job)) + updateErrorList := validation.ValidateJobUpdate(old.(*extensions.Job), obj.(*extensions.Job)) return append(validationErrorList, updateErrorList...) } +type jobStatusStrategy struct { + jobStrategy +} + +var StatusStrategy = jobStatusStrategy{Strategy} + +func (jobStatusStrategy) PrepareForUpdate(obj, old runtime.Object) { + newJob := obj.(*extensions.Job) + oldJob := old.(*extensions.Job) + newJob.Spec = oldJob.Spec +} + +func (jobStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList { + return validation.ValidateJobUpdateStatus(obj.(*extensions.Job), old.(*extensions.Job)) +} + // JobSelectableFields returns a field set that represents the object for matching purposes. -func JobToSelectableFields(job *experimental.Job) fields.Set { +func JobToSelectableFields(job *extensions.Job) fields.Set { return fields.Set{ "metadata.name": job.Name, - "status.successful": strconv.Itoa(job.Status.Successful), + "status.successful": strconv.Itoa(job.Status.Succeeded), } } @@ -95,7 +111,7 @@ func MatchJob(label labels.Selector, field fields.Selector) generic.Matcher { Label: label, Field: field, GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { - job, ok := obj.(*experimental.Job) + job, ok := obj.(*extensions.Job) if !ok { return nil, nil, fmt.Errorf("Given object is not a job.") } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/strategy_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/strategy_test.go new file mode 100644 index 000000000000..6b90786128ec --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/job/strategy_test.go @@ -0,0 +1,156 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 job + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" +) + +func TestJobStrategy(t *testing.T) { + ctx := api.NewDefaultContext() + if !Strategy.NamespaceScoped() { + t.Errorf("Job must be namespace scoped") + } + if Strategy.AllowCreateOnUpdate() { + t.Errorf("Job should not allow create on update") + } + + validSelector := map[string]string{"a": "b"} + validPodTemplateSpec := api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: validSelector, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyOnFailure, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + }, + } + job := &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: "myjob", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.JobSpec{ + Selector: validSelector, + Template: validPodTemplateSpec, + }, + Status: extensions.JobStatus{ + Active: 11, + }, + } + + Strategy.PrepareForCreate(job) + if job.Status.Active != 0 { + t.Errorf("Job does not allow setting status on create") + } + errs := Strategy.Validate(ctx, job) + if len(errs) != 0 { + t.Errorf("Unexpected error validating %v", errs) + } + parallelism := 10 + updatedJob := &extensions.Job{ + ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "4"}, + Spec: extensions.JobSpec{ + Parallelism: ¶llelism, + }, + Status: extensions.JobStatus{ + Active: 11, + }, + } + // ensure we do not change status + job.Status.Active = 10 + Strategy.PrepareForUpdate(updatedJob, job) + if updatedJob.Status.Active != 10 { + t.Errorf("PrepareForUpdate should have preserved prior version status") + } + errs = Strategy.ValidateUpdate(ctx, updatedJob, job) + if len(errs) == 0 { + t.Errorf("Expected a validation error") + } +} + +func TestJobStatusStrategy(t *testing.T) { + ctx := api.NewDefaultContext() + if !StatusStrategy.NamespaceScoped() { + t.Errorf("Job must be namespace scoped") + } + if StatusStrategy.AllowCreateOnUpdate() { + t.Errorf("Job should not allow create on update") + } + validSelector := map[string]string{"a": "b"} + validPodTemplateSpec := api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: validSelector, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyOnFailure, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + }, + } + oldParallelism := 10 + newParallelism := 11 + oldJob := &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: "myjob", + Namespace: api.NamespaceDefault, + ResourceVersion: "10", + }, + Spec: extensions.JobSpec{ + Selector: validSelector, + Template: validPodTemplateSpec, + Parallelism: &oldParallelism, + }, + Status: extensions.JobStatus{ + Active: 11, + }, + } + newJob := &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: "myjob", + Namespace: api.NamespaceDefault, + ResourceVersion: "9", + }, + Spec: extensions.JobSpec{ + Selector: validSelector, + Template: validPodTemplateSpec, + Parallelism: &newParallelism, + }, + Status: extensions.JobStatus{ + Active: 12, + }, + } + + StatusStrategy.PrepareForUpdate(newJob, oldJob) + if newJob.Status.Active != 12 { + t.Errorf("Job status updates must allow changes to job status") + } + if *newJob.Spec.Parallelism != 10 { + t.Errorf("Job status updates must now allow changes to job spec") + } + errs := StatusStrategy.ValidateUpdate(ctx, newJob, oldJob) + if len(errs) != 0 { + t.Errorf("Unexpected error %v", errs) + } + if newJob.ResourceVersion != "9" { + t.Errorf("Incoming resource version on update should not be mutated") + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/etcd/etcd.go index 798173902137..df343590fbd1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/etcd/etcd.go @@ -22,6 +22,7 @@ import ( "k8s.io/kubernetes/pkg/api" apierrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -29,7 +30,6 @@ import ( "k8s.io/kubernetes/pkg/registry/namespace" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" - "k8s.io/kubernetes/pkg/util" ) // rest implements a RESTStorage for namespaces against etcd @@ -95,7 +95,7 @@ func (r *REST) Delete(ctx api.Context, name string, options *api.DeleteOptions) // upon first request to delete, we switch the phase to start namespace termination if namespace.DeletionTimestamp.IsZero() { - now := util.Now() + now := unversioned.Now() namespace.DeletionTimestamp = &now namespace.Status.Phase = api.NamespaceTerminating result, _, err := r.status.Update(ctx, namespace) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/etcd/etcd_test.go index 653d84b6058c..6933bf7ffe74 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/etcd/etcd_test.go @@ -21,13 +21,13 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools/etcdtest" - "k8s.io/kubernetes/pkg/util" ) func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { @@ -129,7 +129,7 @@ func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) { storage, fakeClient := newStorage(t) key := etcdtest.AddPrefix("namespaces/foo") ctx := api.NewContext() - now := util.Now() + now := unversioned.Now() namespace := &api.Namespace{ ObjectMeta: api.ObjectMeta{ Name: "foo", @@ -152,7 +152,7 @@ func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) { storage, fakeClient := newStorage(t) key := etcdtest.AddPrefix("namespaces/foo") ctx := api.NewContext() - now := util.Now() + now := unversioned.Now() namespace := &api.Namespace{ ObjectMeta: api.ObjectMeta{ Name: "foo", diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/strategy_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/strategy_test.go index 2dba00454665..49ba8146011d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/strategy_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/namespace/strategy_test.go @@ -20,7 +20,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) func TestNamespaceStrategy(t *testing.T) { @@ -71,7 +71,7 @@ func TestNamespaceStatusStrategy(t *testing.T) { if StatusStrategy.AllowCreateOnUpdate() { t.Errorf("Namespaces should not allow create on update") } - now := util.Now() + now := unversioned.Now() oldNamespace := &api.Namespace{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}, Spec: api.NamespaceSpec{Finalizers: []api.FinalizerName{"kubernetes"}}, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/etcd/etcd.go index 6ad503e0745f..f54ad1928914 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/etcd/etcd.go @@ -26,6 +26,8 @@ import ( "k8s.io/kubernetes/pkg/api/errors" etcderr "k8s.io/kubernetes/pkg/api/errors/etcd" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/capabilities" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" @@ -147,19 +149,19 @@ func (r *BindingREST) Create(ctx api.Context, obj runtime.Object) (out runtime.O return nil, errors.NewInvalid("binding", binding.Name, fielderrors.ValidationErrorList{fielderrors.NewFieldRequired("to.name")}) } err = r.assignPod(ctx, binding.Name, binding.Target.Name, binding.Annotations) - out = &api.Status{Status: api.StatusSuccess} + out = &unversioned.Status{Status: unversioned.StatusSuccess} return } -// setPodHostAndAnnotations sets the given pod's host to 'machine' iff it was previously 'oldMachine' and merges -// the provided annotations with those of the pod. +// setPodHostAndAnnotations sets the given pod's host to 'machine' if and only if it was +// previously 'oldMachine' and merges the provided annotations with those of the pod. // Returns the current state of the pod, or an error. func (r *BindingREST) setPodHostAndAnnotations(ctx api.Context, podID, oldMachine, machine string, annotations map[string]string) (finalPod *api.Pod, err error) { podKey, err := r.store.KeyFunc(ctx, podID) if err != nil { return nil, err } - err = r.store.Storage.GuaranteedUpdate(podKey, &api.Pod{}, false, storage.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { + err = r.store.Storage.GuaranteedUpdate(ctx, podKey, &api.Pod{}, false, storage.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { pod, ok := obj.(*api.Pod) if !ok { return nil, fmt.Errorf("unexpected object: %#v", obj) @@ -211,6 +213,7 @@ func (r *StatusREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object } // LogREST implements the log endpoint for a Pod +// TODO: move me into pod/rest - I'm generic to store type via ResourceGetter type LogREST struct { store *etcdgeneric.Etcd kubeletConn client.ConnectionInfoGetter @@ -231,15 +234,19 @@ func (r *LogREST) Get(ctx api.Context, name string, opts runtime.Object) (runtim if !ok { return nil, fmt.Errorf("Invalid options object: %#v", opts) } + if errs := validation.ValidatePodLogOptions(logOpts); len(errs) > 0 { + return nil, errors.NewInvalid("podlogs", name, errs) + } location, transport, err := pod.LogLocation(r.store, r.kubeletConn, ctx, name, logOpts) if err != nil { return nil, err } return &genericrest.LocationStreamer{ - Location: location, - Transport: transport, - ContentType: "text/plain", - Flush: logOpts.Follow, + Location: location, + Transport: transport, + ContentType: "text/plain", + Flush: logOpts.Follow, + ResponseChecker: genericrest.NewGenericHttpResponseChecker("Pod", name), }, nil } @@ -249,6 +256,7 @@ func (r *LogREST) NewGetOptions() (runtime.Object, bool, string) { } // ProxyREST implements the proxy subresource for a Pod +// TODO: move me into pod/rest - I'm generic to store type via ResourceGetter type ProxyREST struct { store *etcdgeneric.Etcd proxyTransport http.RoundTripper @@ -275,7 +283,7 @@ func (r *ProxyREST) NewConnectOptions() (runtime.Object, bool, string) { } // Connect returns a handler for the pod proxy -func (r *ProxyREST) Connect(ctx api.Context, id string, opts runtime.Object) (rest.ConnectHandler, error) { +func (r *ProxyREST) Connect(ctx api.Context, id string, opts runtime.Object, responder rest.Responder) (http.Handler, error) { proxyOpts, ok := opts.(*api.PodProxyOptions) if !ok { return nil, fmt.Errorf("Invalid options object: %#v", opts) @@ -286,13 +294,14 @@ func (r *ProxyREST) Connect(ctx api.Context, id string, opts runtime.Object) (re } location.Path = path.Join(location.Path, proxyOpts.Path) // Return a proxy handler that uses the desired transport, wrapped with additional proxy handling (to get URL rewriting, X-Forwarded-* headers, etc) - return newThrottledUpgradeAwareProxyHandler(location, transport, true, false), nil + return newThrottledUpgradeAwareProxyHandler(location, transport, true, false, responder), nil } // Support both GET and POST methods. We must support GET for browsers that want to use WebSockets. var upgradeableMethods = []string{"GET", "POST"} // AttachREST implements the attach subresource for a Pod +// TODO: move me into pod/rest - I'm generic to store type via ResourceGetter type AttachREST struct { store *etcdgeneric.Etcd kubeletConn client.ConnectionInfoGetter @@ -307,7 +316,7 @@ func (r *AttachREST) New() runtime.Object { } // Connect returns a handler for the pod exec proxy -func (r *AttachREST) Connect(ctx api.Context, name string, opts runtime.Object) (rest.ConnectHandler, error) { +func (r *AttachREST) Connect(ctx api.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) { attachOpts, ok := opts.(*api.PodAttachOptions) if !ok { return nil, fmt.Errorf("Invalid options object: %#v", opts) @@ -316,7 +325,7 @@ func (r *AttachREST) Connect(ctx api.Context, name string, opts runtime.Object) if err != nil { return nil, err } - return newThrottledUpgradeAwareProxyHandler(location, transport, false, true), nil + return newThrottledUpgradeAwareProxyHandler(location, transport, false, true, responder), nil } // NewConnectOptions returns the versioned object that represents exec parameters @@ -330,6 +339,7 @@ func (r *AttachREST) ConnectMethods() []string { } // ExecREST implements the exec subresource for a Pod +// TODO: move me into pod/rest - I'm generic to store type via ResourceGetter type ExecREST struct { store *etcdgeneric.Etcd kubeletConn client.ConnectionInfoGetter @@ -344,16 +354,16 @@ func (r *ExecREST) New() runtime.Object { } // Connect returns a handler for the pod exec proxy -func (r *ExecREST) Connect(ctx api.Context, name string, opts runtime.Object) (rest.ConnectHandler, error) { +func (r *ExecREST) Connect(ctx api.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) { execOpts, ok := opts.(*api.PodExecOptions) if !ok { - return nil, fmt.Errorf("Invalid options object: %#v", opts) + return nil, fmt.Errorf("invalid options object: %#v", opts) } location, transport, err := pod.ExecLocation(r.store, r.kubeletConn, ctx, name, execOpts) if err != nil { return nil, err } - return newThrottledUpgradeAwareProxyHandler(location, transport, false, true), nil + return newThrottledUpgradeAwareProxyHandler(location, transport, false, true, responder), nil } // NewConnectOptions returns the versioned object that represents exec parameters @@ -367,6 +377,7 @@ func (r *ExecREST) ConnectMethods() []string { } // PortForwardREST implements the portforward subresource for a Pod +// TODO: move me into pod/rest - I'm generic to store type via ResourceGetter type PortForwardREST struct { store *etcdgeneric.Etcd kubeletConn client.ConnectionInfoGetter @@ -391,16 +402,16 @@ func (r *PortForwardREST) ConnectMethods() []string { } // Connect returns a handler for the pod portforward proxy -func (r *PortForwardREST) Connect(ctx api.Context, name string, opts runtime.Object) (rest.ConnectHandler, error) { +func (r *PortForwardREST) Connect(ctx api.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) { location, transport, err := pod.PortForwardLocation(r.store, r.kubeletConn, ctx, name) if err != nil { return nil, err } - return newThrottledUpgradeAwareProxyHandler(location, transport, false, true), nil + return newThrottledUpgradeAwareProxyHandler(location, transport, false, true, responder), nil } -func newThrottledUpgradeAwareProxyHandler(location *url.URL, transport http.RoundTripper, wrapTransport, upgradeRequired bool) *genericrest.UpgradeAwareProxyHandler { - handler := genericrest.NewUpgradeAwareProxyHandler(location, transport, wrapTransport, upgradeRequired) +func newThrottledUpgradeAwareProxyHandler(location *url.URL, transport http.RoundTripper, wrapTransport, upgradeRequired bool, responder rest.Responder) *genericrest.UpgradeAwareProxyHandler { + handler := genericrest.NewUpgradeAwareProxyHandler(location, transport, wrapTransport, upgradeRequired, responder) handler.MaxBytesPerSec = capabilities.Get().PerConnectionBandwidthLimitBytesPerSec return handler } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/etcd/etcd_test.go index 35318b83890b..19cc073954be 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/etcd/etcd_test.go @@ -64,6 +64,7 @@ func validNewPod() *api.Pod { SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, + SecurityContext: &api.PodSecurityContext{}, }, } } @@ -617,6 +618,7 @@ func TestEtcdUpdateScheduled(t *testing.T) { SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, + SecurityContext: &api.PodSecurityContext{}, }, }), 1) @@ -631,19 +633,18 @@ func TestEtcdUpdateScheduled(t *testing.T) { }, Spec: api.PodSpec{ NodeName: "machine", - Containers: []api.Container{ - { - Name: "foobar", - Image: "foo:v2", - ImagePullPolicy: api.PullIfNotPresent, - TerminationMessagePath: api.TerminationMessagePathDefault, - SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), - }, - }, + Containers: []api.Container{{ + Name: "foobar", + Image: "foo:v2", + ImagePullPolicy: api.PullIfNotPresent, + TerminationMessagePath: api.TerminationMessagePathDefault, + SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), + }}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, + SecurityContext: &api.PodSecurityContext{}, }, } _, _, err := storage.Update(ctx, &podIn) @@ -682,6 +683,7 @@ func TestEtcdUpdateStatus(t *testing.T) { SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }, }, + SecurityContext: &api.PodSecurityContext{}, }, } fakeClient.Set(key, runtime.EncodeOrDie(testapi.Default.Codec(), &podStart), 0) @@ -703,6 +705,7 @@ func TestEtcdUpdateStatus(t *testing.T) { TerminationMessagePath: api.TerminationMessagePathDefault, }, }, + SecurityContext: &api.PodSecurityContext{}, }, Status: api.PodStatus{ Phase: api.PodRunning, @@ -734,3 +737,21 @@ func TestEtcdUpdateStatus(t *testing.T) { t.Errorf("unexpected object: %s", util.ObjectDiff(&expected, podOut)) } } + +func TestPodLogValidates(t *testing.T) { + etcdStorage, _ := registrytest.NewEtcdStorage(t, "") + storage := NewStorage(etcdStorage, false, nil, nil) + + negativeOne := int64(-1) + testCases := []*api.PodLogOptions{ + {SinceSeconds: &negativeOne}, + {TailLines: &negativeOne}, + } + + for _, tc := range testCases { + _, err := storage.Log.Get(api.NewDefaultContext(), "test", tc) + if !errors.IsInvalid(err) { + t.Fatalf("unexpected error: %v", err) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/strategy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/strategy.go index 3ef20008c62f..82ac5c49b0f6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/strategy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/pod/strategy.go @@ -21,6 +21,8 @@ import ( "net" "net/http" "net/url" + "strconv" + "time" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" @@ -253,6 +255,21 @@ func LogLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ct if opts.Previous { params.Add("previous", "true") } + if opts.Timestamps { + params.Add("timestamps", "true") + } + if opts.SinceSeconds != nil { + params.Add("sinceSeconds", strconv.FormatInt(*opts.SinceSeconds, 10)) + } + if opts.SinceTime != nil { + params.Add("sinceTime", opts.SinceTime.Format(time.RFC3339)) + } + if opts.TailLines != nil { + params.Add("tailLines", strconv.FormatInt(*opts.TailLines, 10)) + } + if opts.LimitBytes != nil { + params.Add("limitBytes", strconv.FormatInt(*opts.LimitBytes, 10)) + } loc := &url.URL{ Scheme: nodeScheme, Host: fmt.Sprintf("%s:%d", nodeHost, nodePort), diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/registrytest/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/registrytest/etcd.go index c22a393dd1b1..9072a4918d1a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/registrytest/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/registrytest/etcd.go @@ -163,8 +163,8 @@ func getCodec(obj runtime.Object) (runtime.Codec, error) { var codec runtime.Codec if api.Scheme.Recognizes(testapi.Default.GroupAndVersion(), kind) { codec = testapi.Default.Codec() - } else if api.Scheme.Recognizes(testapi.Experimental.GroupAndVersion(), kind) { - codec = testapi.Experimental.Codec() + } else if api.Scheme.Recognizes(testapi.Extensions.GroupAndVersion(), kind) { + codec = testapi.Extensions.Codec() } else { return nil, fmt.Errorf("unexpected kind: %v", kind) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd.go deleted file mode 100644 index fa66a528a022..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 etcd - -import ( - "path" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/fields" - "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/registry/generic" - etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd" - "k8s.io/kubernetes/pkg/registry/securitycontextconstraints" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/storage" -) - -// REST implements a RESTStorage for security context constraints against etcd -type REST struct { - *etcdgeneric.Etcd -} - -const Prefix = "/securitycontextconstraints" - -// NewStorage returns a RESTStorage object that will work against security context constraints objects. -func NewStorage(s storage.Interface) *REST { - store := &etcdgeneric.Etcd{ - NewFunc: func() runtime.Object { return &api.SecurityContextConstraints{} }, - NewListFunc: func() runtime.Object { return &api.SecurityContextConstraintsList{} }, - KeyRootFunc: func(ctx api.Context) string { - return Prefix - }, - KeyFunc: func(ctx api.Context, name string) (string, error) { - return path.Join(Prefix, name), nil - }, - ObjectNameFunc: func(obj runtime.Object) (string, error) { - return obj.(*api.SecurityContextConstraints).Name, nil - }, - PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { - return securitycontextconstraints.Matcher(label, field) - }, - EndpointName: "securitycontextconstraints", - - CreateStrategy: securitycontextconstraints.Strategy, - UpdateStrategy: securitycontextconstraints.Strategy, - ReturnDeletedObject: true, - Storage: s, - } - return &REST{store} -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd_test.go deleted file mode 100644 index 75c433c84ab9..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd_test.go +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 etcd - -import ( - "testing" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/registry/registrytest" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/tools" -) - -func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { - etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "") - return NewStorage(etcdStorage), fakeClient -} - -func validNewSecurityContextConstraints(name string) *api.SecurityContextConstraints { - return &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{ - Name: name, - }, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyRunAsAny, - }, - RunAsUser: api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyRunAsAny, - }, - } -} - -func TestCreate(t *testing.T) { - storage, fakeClient := newStorage(t) - test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope() - scc := validNewSecurityContextConstraints("foo") - scc.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"} - test.TestCreate( - // valid - scc, - // invalid - &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{Name: "name with spaces"}, - }, - ) -} - -func TestUpdate(t *testing.T) { - storage, fakeEtcdClient := newStorage(t) - test := registrytest.New(t, fakeEtcdClient, storage.Etcd).ClusterScope() - test.TestUpdate( - validNewSecurityContextConstraints("foo"), - // updateFunc - func(obj runtime.Object) runtime.Object { - object := obj.(*api.SecurityContextConstraints) - object.AllowPrivilegedContainer = true - return object - }, - ) -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/registry.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/registry.go deleted file mode 100644 index 9e273657bb16..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/registry.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 securitycontextconstraints - -import ( - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/rest" - "k8s.io/kubernetes/pkg/fields" - "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/watch" -) - -// Registry is an interface implemented by things that know how to store SecurityContextConstraints objects. -type Registry interface { - // ListSecurityContextConstraints obtains a list of SecurityContextConstraints having labels which match selector. - ListSecurityContextConstraints(ctx api.Context, selector labels.Selector) (*api.SecurityContextConstraintsList, error) - // Watch for new/changed/deleted SecurityContextConstraints - WatchSecurityContextConstraints(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) - // Get a specific SecurityContextConstraints - GetSecurityContextConstraint(ctx api.Context, name string) (*api.SecurityContextConstraints, error) - // Create a SecurityContextConstraints based on a specification. - CreateSecurityContextConstraint(ctx api.Context, scc *api.SecurityContextConstraints) error - // Update an existing SecurityContextConstraints - UpdateSecurityContextConstraint(ctx api.Context, scc *api.SecurityContextConstraints) error - // Delete an existing SecurityContextConstraints - DeleteSecurityContextConstraint(ctx api.Context, name 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) ListSecurityContextConstraints(ctx api.Context, label labels.Selector) (*api.SecurityContextConstraintsList, error) { - obj, err := s.List(ctx, label, fields.Everything()) - if err != nil { - return nil, err - } - return obj.(*api.SecurityContextConstraintsList), nil -} - -func (s *storage) WatchSecurityContextConstraints(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { - return s.Watch(ctx, label, field, resourceVersion) -} - -func (s *storage) GetSecurityContextConstraint(ctx api.Context, name string) (*api.SecurityContextConstraints, error) { - obj, err := s.Get(ctx, name) - if err != nil { - return nil, err - } - return obj.(*api.SecurityContextConstraints), nil -} - -func (s *storage) CreateSecurityContextConstraint(ctx api.Context, scc *api.SecurityContextConstraints) error { - _, err := s.Create(ctx, scc) - return err -} - -func (s *storage) UpdateSecurityContextConstraint(ctx api.Context, scc *api.SecurityContextConstraints) error { - _, _, err := s.Update(ctx, scc) - return err -} - -func (s *storage) DeleteSecurityContextConstraint(ctx api.Context, name string) error { - _, err := s.Delete(ctx, name, nil) - return err -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/strategy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/strategy.go deleted file mode 100644 index 36103a80bb5a..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/strategy.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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 securitycontextconstraints - -import ( - "fmt" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/rest" - "k8s.io/kubernetes/pkg/api/validation" - "k8s.io/kubernetes/pkg/fields" - "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/registry/generic" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util/fielderrors" -) - -// strategy implements behavior for SecurityContextConstraints objects -type strategy struct { - runtime.ObjectTyper - api.NameGenerator -} - -// Strategy is the default logic that applies when creating and updating ServiceAccount -// objects via the REST API. -var Strategy = strategy{api.Scheme, api.SimpleNameGenerator} - -var _ = rest.RESTCreateStrategy(Strategy) - -var _ = rest.RESTUpdateStrategy(Strategy) - -func (strategy) NamespaceScoped() bool { - return false -} - -func (strategy) AllowCreateOnUpdate() bool { - return false -} - -func (strategy) AllowUnconditionalUpdate() bool { - return true -} - -func (strategy) PrepareForCreate(obj runtime.Object) { -} - -func (strategy) PrepareForUpdate(obj, old runtime.Object) { -} - -func (strategy) Validate(ctx api.Context, obj runtime.Object) fielderrors.ValidationErrorList { - return validation.ValidateSecurityContextConstraints(obj.(*api.SecurityContextConstraints)) -} - -func (strategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList { - return validation.ValidateSecurityContextConstraintsUpdate(old.(*api.SecurityContextConstraints), obj.(*api.SecurityContextConstraints)) -} - -// Matcher returns a generic matcher for a given label and field selector. -func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - scc, ok := obj.(*api.SecurityContextConstraints) - if !ok { - return false, fmt.Errorf("not a securitycontextconstraint") - } - fields := SelectableFields(scc) - return label.Matches(labels.Set(scc.Labels)) && field.Matches(fields), nil - }) -} - -// SelectableFields returns a label set that represents the object -func SelectableFields(obj *api.SecurityContextConstraints) labels.Set { - return labels.Set{ - "metadata.name": obj.Name, - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/bitmap.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/bitmap.go index 03e0116caee7..e90f396a6027 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/bitmap.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/bitmap.go @@ -79,10 +79,6 @@ func NewContiguousAllocationMap(max int, rangeSpec string) *AllocationBitmap { return &a } -func NewContiguousAllocationInterface(max int, rangeSpec string) Interface { - return NewContiguousAllocationMap(max, rangeSpec) -} - // Allocate attempts to reserve the provided item. // Returns true if it was allocated, false if it was already in use func (r *AllocationBitmap) Allocate(offset int) (bool, error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/etcd/etcd.go index 2a5b3e8aa7c7..35831a66db18 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/etcd/etcd.go @@ -29,6 +29,8 @@ import ( "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" + + "golang.org/x/net/context" ) var ( @@ -141,7 +143,7 @@ func (e *Etcd) Release(item int) error { // tryUpdate performs a read-update to persist the latest snapshot state of allocation. func (e *Etcd) tryUpdate(fn func() error) error { - err := e.storage.GuaranteedUpdate(e.baseKey, &api.RangeAllocation{}, true, + err := e.storage.GuaranteedUpdate(context.TODO(), e.baseKey, &api.RangeAllocation{}, true, storage.SimpleUpdate(func(input runtime.Object) (output runtime.Object, err error) { existing := input.(*api.RangeAllocation) if len(existing.ResourceVersion) == 0 { @@ -171,7 +173,7 @@ func (e *Etcd) Refresh() (*api.RangeAllocation, error) { defer e.lock.Unlock() existing := &api.RangeAllocation{} - if err := e.storage.Get(e.baseKey, existing, false); err != nil { + if err := e.storage.Get(context.TODO(), e.baseKey, existing, false); err != nil { if etcdstorage.IsEtcdNotFound(err) { return nil, nil } @@ -185,7 +187,7 @@ func (e *Etcd) Refresh() (*api.RangeAllocation, error) { // etcd. If the key does not exist, the object will have an empty ResourceVersion. func (e *Etcd) Get() (*api.RangeAllocation, error) { existing := &api.RangeAllocation{} - if err := e.storage.Get(e.baseKey, existing, true); err != nil { + if err := e.storage.Get(context.TODO(), e.baseKey, existing, true); err != nil { return nil, etcderr.InterpretGetError(err, e.kind, "") } return existing, nil @@ -198,7 +200,7 @@ func (e *Etcd) CreateOrUpdate(snapshot *api.RangeAllocation) error { defer e.lock.Unlock() last := "" - err := e.storage.GuaranteedUpdate(e.baseKey, &api.RangeAllocation{}, true, + err := e.storage.GuaranteedUpdate(context.TODO(), e.baseKey, &api.RangeAllocation{}, true, storage.SimpleUpdate(func(input runtime.Object) (output runtime.Object, err error) { existing := input.(*api.RangeAllocation) switch { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/etcd/etcd_test.go index 1c7d89dc926a..ddcac35e8a23 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/etcd/etcd_test.go @@ -27,6 +27,8 @@ import ( "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools/etcdtest" + + "golang.org/x/net/context" ) func newStorage(t *testing.T) (*Etcd, *tools.FakeEtcdClient, allocator.Interface) { @@ -84,7 +86,7 @@ func TestStore(t *testing.T) { other := allocator.NewAllocationMap(100, "rangeSpecValue") allocation := &api.RangeAllocation{} - if err := storage.storage.Get(key(), allocation, false); err != nil { + if err := storage.storage.Get(context.TODO(), key(), allocation, false); err != nil { t.Fatal(err) } if allocation.ResourceVersion != "2" { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/ipallocator/allocator.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/ipallocator/allocator.go index 7de40f49b804..3aa5e58f63c0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/ipallocator/allocator.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/ipallocator/allocator.go @@ -19,10 +19,11 @@ package ipallocator import ( "errors" "fmt" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/registry/service/allocator" "math/big" "net" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/registry/service/allocator" ) // Interface manages the allocation of IP addresses out of a range. Interface diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/portallocator/allocator.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/portallocator/allocator.go index c792b5728b47..e04eb6665a22 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/portallocator/allocator.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/portallocator/allocator.go @@ -19,6 +19,7 @@ package portallocator import ( "errors" "fmt" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/registry/service/allocator" "k8s.io/kubernetes/pkg/util" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/rest.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/rest.go index e3f3db49bd0a..3b524a2bc7f9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/rest.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/rest.go @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -165,7 +166,7 @@ func (rs *REST) Delete(ctx api.Context, id string) (runtime.Object, error) { } } - return &api.Status{Status: api.StatusSuccess}, nil + return &unversioned.Status{Status: unversioned.StatusSuccess}, nil } func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) { @@ -296,6 +297,9 @@ func (rs *REST) ResourceLocation(ctx api.Context, id string) (*url.URL, http.Rou // Find a Subset that has the port. for ssi := 0; ssi < len(eps.Subsets); ssi++ { ss := &eps.Subsets[(ssSeed+ssi)%len(eps.Subsets)] + if len(ss.Addresses) == 0 { + continue + } for i := range ss.Ports { if ss.Ports[i].Name == portStr { // Pick a random address. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/rest_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/rest_test.go index 55431746e048..3fe14916ee7e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/rest_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/rest_test.go @@ -440,6 +440,22 @@ func TestServiceRegistryResourceLocation(t *testing.T) { Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}}, }}, }, + { + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: api.NamespaceDefault, + }, + Subsets: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{}, + Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}}, + }, { + Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}}, + Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}}, + }, { + Addresses: []api.EndpointAddress{{IP: "1.2.3.5"}}, + Ports: []api.EndpointPort{}, + }}, + }, }, } storage, registry := NewTestREST(t, endpoints) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/etcd/etcd.go index 087a32938e85..6501d8e8eb97 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/etcd/etcd.go @@ -18,7 +18,7 @@ package etcd import ( "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -38,8 +38,8 @@ func NewREST(s storage.Interface) *REST { prefix := "/thirdpartyresources" store := &etcdgeneric.Etcd{ - NewFunc: func() runtime.Object { return &experimental.ThirdPartyResource{} }, - NewListFunc: func() runtime.Object { return &experimental.ThirdPartyResourceList{} }, + NewFunc: func() runtime.Object { return &extensions.ThirdPartyResource{} }, + NewListFunc: func() runtime.Object { return &extensions.ThirdPartyResourceList{} }, KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, @@ -47,7 +47,7 @@ func NewREST(s storage.Interface) *REST { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { - return obj.(*experimental.ThirdPartyResource).Name, nil + return obj.(*extensions.ThirdPartyResource).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return thirdpartyresource.Matcher(label, field) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/etcd/etcd_test.go index cb2ee1d72d30..63dce6c12f3a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/etcd/etcd_test.go @@ -20,9 +20,9 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" - // Ensure that experimental/v1 package is initialized. - _ "k8s.io/kubernetes/pkg/apis/experimental/v1" + "k8s.io/kubernetes/pkg/apis/extensions" + // Ensure that extensions/v1beta1 package is initialized. + _ "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/registrytest" @@ -31,17 +31,17 @@ import ( ) func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { - etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "experimental") + etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "extensions") return NewREST(etcdStorage), fakeClient } -func validNewThirdPartyResource(name string) *experimental.ThirdPartyResource { - return &experimental.ThirdPartyResource{ +func validNewThirdPartyResource(name string) *extensions.ThirdPartyResource { + return &extensions.ThirdPartyResource{ ObjectMeta: api.ObjectMeta{ Name: name, Namespace: api.NamespaceDefault, }, - Versions: []experimental.APIVersion{ + Versions: []extensions.APIVersion{ { Name: "stable/v1", }, @@ -58,7 +58,7 @@ func TestCreate(t *testing.T) { // valid rsrc, // invalid - &experimental.ThirdPartyResource{}, + &extensions.ThirdPartyResource{}, ) } @@ -70,7 +70,7 @@ func TestUpdate(t *testing.T) { validNewThirdPartyResource("foo"), // updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.ThirdPartyResource) + object := obj.(*extensions.ThirdPartyResource) object.Description = "new description" return object }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/strategy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/strategy.go index 733a1ea56de3..fff669ea21e3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/strategy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresource/strategy.go @@ -21,8 +21,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/rest" - "k8s.io/kubernetes/pkg/apis/experimental" - "k8s.io/kubernetes/pkg/apis/experimental/validation" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -52,7 +52,7 @@ func (strategy) PrepareForCreate(obj runtime.Object) { } func (strategy) Validate(ctx api.Context, obj runtime.Object) fielderrors.ValidationErrorList { - return validation.ValidateThirdPartyResource(obj.(*experimental.ThirdPartyResource)) + return validation.ValidateThirdPartyResource(obj.(*extensions.ThirdPartyResource)) } func (strategy) AllowCreateOnUpdate() bool { @@ -63,7 +63,7 @@ func (strategy) PrepareForUpdate(obj, old runtime.Object) { } func (strategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList { - return validation.ValidateThirdPartyResourceUpdate(old.(*experimental.ThirdPartyResource), obj.(*experimental.ThirdPartyResource)) + return validation.ValidateThirdPartyResourceUpdate(old.(*extensions.ThirdPartyResource), obj.(*extensions.ThirdPartyResource)) } func (strategy) AllowUnconditionalUpdate() bool { @@ -73,7 +73,7 @@ func (strategy) AllowUnconditionalUpdate() bool { // Matcher returns a generic matcher for a given label and field selector. func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - sa, ok := obj.(*experimental.ThirdPartyResource) + sa, ok := obj.(*extensions.ThirdPartyResource) if !ok { return false, fmt.Errorf("not a ThirdPartyResource") } @@ -83,6 +83,6 @@ func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { } // SelectableFields returns a label set that can be used for filter selection -func SelectableFields(obj *experimental.ThirdPartyResource) labels.Set { +func SelectableFields(obj *extensions.ThirdPartyResource) labels.Set { return labels.Set{} } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/codec.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/codec.go index 18c668cde0d8..c7eb8fd55eed 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/codec.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/codec.go @@ -20,12 +20,14 @@ import ( "bytes" "encoding/json" "fmt" + "io" "strings" - "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/meta" - "k8s.io/kubernetes/pkg/apis/experimental" - "k8s.io/kubernetes/pkg/apis/experimental/latest" + "k8s.io/kubernetes/pkg/api/unversioned" + apiutil "k8s.io/kubernetes/pkg/api/util" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/runtime" ) @@ -33,23 +35,31 @@ type thirdPartyResourceDataMapper struct { mapper meta.RESTMapper kind string version string + group string +} + +func (t *thirdPartyResourceDataMapper) isThirdPartyResource(resource string) bool { + return resource == strings.ToLower(t.kind)+"s" } func (t *thirdPartyResourceDataMapper) GroupForResource(resource string) (string, error) { + if t.isThirdPartyResource(resource) { + return t.group, nil + } return t.mapper.GroupForResource(resource) } -func (t *thirdPartyResourceDataMapper) RESTMapping(kind string, versions ...string) (*meta.RESTMapping, error) { - if len(versions) != 1 { - return nil, fmt.Errorf("unexpected set of versions: %v", versions) +func (t *thirdPartyResourceDataMapper) RESTMapping(kind string, groupVersions ...string) (*meta.RESTMapping, error) { + if len(groupVersions) != 1 { + return nil, fmt.Errorf("unexpected set of groupVersions: %v", groupVersions) } - if versions[0] != t.version { - return nil, fmt.Errorf("unknown version %s expected %s", versions[0], t.version) + if groupVersions[0] != apiutil.GetGroupVersion(t.group, t.version) { + return nil, fmt.Errorf("unknown version %s expected %s", groupVersions[0], apiutil.GetGroupVersion(t.group, t.version)) } if kind != "ThirdPartyResourceData" { return nil, fmt.Errorf("unknown kind %s expected %s", kind, t.kind) } - mapping, err := t.mapper.RESTMapping("ThirdPartyResourceData", latest.Version) + mapping, err := t.mapper.RESTMapping("ThirdPartyResourceData", latest.GroupOrDie("extensions").GroupVersion) if err != nil { return nil, err } @@ -66,14 +76,23 @@ func (t *thirdPartyResourceDataMapper) ResourceSingularizer(resource string) (si } func (t *thirdPartyResourceDataMapper) VersionAndKindForResource(resource string) (defaultVersion, kind string, err error) { + if t.isThirdPartyResource(resource) { + return t.version, t.kind, nil + } return t.mapper.VersionAndKindForResource(resource) } -func NewMapper(mapper meta.RESTMapper, kind, version string) meta.RESTMapper { +// ResourceIsValid takes a string (kind) and checks if it's a valid resource +func (t *thirdPartyResourceDataMapper) ResourceIsValid(resource string) bool { + return t.isThirdPartyResource(resource) || t.mapper.ResourceIsValid(resource) +} + +func NewMapper(mapper meta.RESTMapper, kind, version, group string) meta.RESTMapper { return &thirdPartyResourceDataMapper{ mapper: mapper, kind: kind, version: version, + group: group, } } @@ -86,7 +105,7 @@ func NewCodec(codec runtime.Codec, kind string) runtime.Codec { return &thirdPartyResourceDataCodec{codec, kind} } -func (t *thirdPartyResourceDataCodec) populate(objIn *experimental.ThirdPartyResourceData, data []byte) error { +func (t *thirdPartyResourceDataCodec) populate(objIn *extensions.ThirdPartyResourceData, data []byte) error { var obj interface{} if err := json.Unmarshal(data, &obj); err != nil { fmt.Printf("Invalid JSON:\n%s\n", string(data)) @@ -99,8 +118,8 @@ func (t *thirdPartyResourceDataCodec) populate(objIn *experimental.ThirdPartyRes return t.populateFromObject(objIn, mapObj, data) } -func (t *thirdPartyResourceDataCodec) populateFromObject(objIn *experimental.ThirdPartyResourceData, mapObj map[string]interface{}, data []byte) error { - typeMeta := api.TypeMeta{} +func (t *thirdPartyResourceDataCodec) populateFromObject(objIn *extensions.ThirdPartyResourceData, mapObj map[string]interface{}, data []byte) error { + typeMeta := unversioned.TypeMeta{} if err := json.Unmarshal(data, &typeMeta); err != nil { return err } @@ -127,7 +146,7 @@ func (t *thirdPartyResourceDataCodec) populateFromObject(objIn *experimental.Thi } func (t *thirdPartyResourceDataCodec) Decode(data []byte) (runtime.Object, error) { - result := &experimental.ThirdPartyResourceData{} + result := &extensions.ThirdPartyResourceData{} if err := t.populate(result, data); err != nil { return nil, err } @@ -148,7 +167,7 @@ func (t *thirdPartyResourceDataCodec) DecodeToVersion(data []byte, version strin } func (t *thirdPartyResourceDataCodec) DecodeInto(data []byte, obj runtime.Object) error { - thirdParty, ok := obj.(*experimental.ThirdPartyResourceData) + thirdParty, ok := obj.(*extensions.ThirdPartyResourceData) if !ok { return fmt.Errorf("unexpected object: %#v", obj) } @@ -156,7 +175,7 @@ func (t *thirdPartyResourceDataCodec) DecodeInto(data []byte, obj runtime.Object } func (t *thirdPartyResourceDataCodec) DecodeIntoWithSpecifiedVersionKind(data []byte, obj runtime.Object, version, kind string) error { - thirdParty, ok := obj.(*experimental.ThirdPartyResourceData) + thirdParty, ok := obj.(*extensions.ThirdPartyResourceData) if !ok { return fmt.Errorf("unexpected object: %#v", obj) } @@ -207,62 +226,75 @@ const template = `{ "items": [ %s ] }` -func encodeToJSON(obj *experimental.ThirdPartyResourceData) ([]byte, error) { +func encodeToJSON(obj *extensions.ThirdPartyResourceData, stream io.Writer) error { var objOut interface{} if err := json.Unmarshal(obj.Data, &objOut); err != nil { - return nil, err + return err } objMap, ok := objOut.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("unexpected type: %v", objOut) + return fmt.Errorf("unexpected type: %v", objOut) } objMap["metadata"] = obj.ObjectMeta - return json.Marshal(objMap) + encoder := json.NewEncoder(stream) + return encoder.Encode(objMap) } -func (t *thirdPartyResourceDataCodec) Encode(obj runtime.Object) (data []byte, err error) { +func (t *thirdPartyResourceDataCodec) Encode(obj runtime.Object) ([]byte, error) { + buff := &bytes.Buffer{} + if err := t.EncodeToStream(obj, buff); err != nil { + return nil, err + } + return buff.Bytes(), nil +} + +func (t *thirdPartyResourceDataCodec) EncodeToStream(obj runtime.Object, stream io.Writer) (err error) { switch obj := obj.(type) { - case *experimental.ThirdPartyResourceData: - return encodeToJSON(obj) - case *experimental.ThirdPartyResourceDataList: + case *extensions.ThirdPartyResourceData: + return encodeToJSON(obj, stream) + case *extensions.ThirdPartyResourceDataList: // TODO: There must be a better way to do this... - buff := &bytes.Buffer{} dataStrings := make([]string, len(obj.Items)) for ix := range obj.Items { - data, err := encodeToJSON(&obj.Items[ix]) + buff := &bytes.Buffer{} + err := encodeToJSON(&obj.Items[ix], buff) if err != nil { - return nil, err + return err } - dataStrings[ix] = string(data) + dataStrings[ix] = buff.String() } - fmt.Fprintf(buff, template, t.kind+"List", strings.Join(dataStrings, ",")) - return buff.Bytes(), nil - case *api.Status: - return t.delegate.Encode(obj) + fmt.Fprintf(stream, template, t.kind+"List", strings.Join(dataStrings, ",")) + return nil + case *unversioned.Status: + return t.delegate.EncodeToStream(obj, stream) default: - return nil, fmt.Errorf("unexpected object to encode: %#v", obj) + return fmt.Errorf("unexpected object to encode: %#v", obj) } } -func NewObjectCreator(version string, delegate runtime.ObjectCreater) runtime.ObjectCreater { - return &thirdPartyResourceDataCreator{version, delegate} +func NewObjectCreator(group, version string, delegate runtime.ObjectCreater) runtime.ObjectCreater { + return &thirdPartyResourceDataCreator{group, version, delegate} } type thirdPartyResourceDataCreator struct { + group string version string delegate runtime.ObjectCreater } -func (t *thirdPartyResourceDataCreator) New(version, kind string) (out runtime.Object, err error) { - if t.version != version { - return nil, fmt.Errorf("unknown version %s for kind %s", version, kind) - } +func (t *thirdPartyResourceDataCreator) New(groupVersion, kind string) (out runtime.Object, err error) { switch kind { case "ThirdPartyResourceData": - return &experimental.ThirdPartyResourceData{}, nil + if apiutil.GetGroupVersion(t.group, t.version) != groupVersion { + return nil, fmt.Errorf("unknown version %s for kind %s", groupVersion, kind) + } + return &extensions.ThirdPartyResourceData{}, nil case "ThirdPartyResourceDataList": - return &experimental.ThirdPartyResourceDataList{}, nil + if apiutil.GetGroupVersion(t.group, t.version) != groupVersion { + return nil, fmt.Errorf("unknown version %s for kind %s", groupVersion, kind) + } + return &extensions.ThirdPartyResourceDataList{}, nil default: - return t.delegate.New(latest.Version, kind) + return t.delegate.New(groupVersion, kind) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/codec_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/codec_test.go index 61cd10d8de4a..a83dad36cbfb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/codec_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/codec_test.go @@ -23,21 +23,23 @@ import ( "time" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/runtime" ) type Foo struct { - api.TypeMeta `json:",inline"` - api.ObjectMeta `json:"metadata,omitempty" description:"standard object metadata"` + unversioned.TypeMeta `json:",inline"` + api.ObjectMeta `json:"metadata,omitempty" description:"standard object metadata"` SomeField string `json:"someField"` OtherField int `json:"otherField"` } type FooList struct { - api.TypeMeta `json:",inline"` - api.ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://docs.k8s.io/api-conventions.md#metadata"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata"` items []Foo `json:"items"` } @@ -54,20 +56,20 @@ func TestCodec(t *testing.T) { name: "missing kind", }, { - obj: &Foo{ObjectMeta: api.ObjectMeta{Name: "bar"}, TypeMeta: api.TypeMeta{Kind: "Foo"}}, + obj: &Foo{ObjectMeta: api.ObjectMeta{Name: "bar"}, TypeMeta: unversioned.TypeMeta{Kind: "Foo"}}, name: "basic", }, { - obj: &Foo{ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "baz"}, TypeMeta: api.TypeMeta{Kind: "Foo"}}, + obj: &Foo{ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "baz"}, TypeMeta: unversioned.TypeMeta{Kind: "Foo"}}, name: "resource version", }, { obj: &Foo{ ObjectMeta: api.ObjectMeta{ Name: "bar", - CreationTimestamp: util.Time{time.Unix(100, 0)}, + CreationTimestamp: unversioned.Time{time.Unix(100, 0)}, }, - TypeMeta: api.TypeMeta{Kind: "Foo"}, + TypeMeta: unversioned.TypeMeta{Kind: "Foo"}, }, name: "creation time", }, @@ -78,7 +80,7 @@ func TestCodec(t *testing.T) { ResourceVersion: "baz", Labels: map[string]string{"foo": "bar", "baz": "blah"}, }, - TypeMeta: api.TypeMeta{Kind: "Foo"}, + TypeMeta: unversioned.TypeMeta{Kind: "Foo"}, }, name: "labels", }, @@ -101,7 +103,7 @@ func TestCodec(t *testing.T) { } continue } - rsrcObj, ok := obj.(*experimental.ThirdPartyResourceData) + rsrcObj, ok := obj.(*extensions.ThirdPartyResourceData) if !ok { t.Errorf("[%s] unexpected object: %v", test.name, obj) continue @@ -133,3 +135,49 @@ func TestCodec(t *testing.T) { } } } + +func TestCreater(t *testing.T) { + creater := NewObjectCreator("creater group", "creater version", api.Scheme) + tests := []struct { + name string + version string + kind string + expectedObj runtime.Object + expectErr bool + }{ + { + name: "valid ThirdPartyResourceData creation", + version: "creater group/creater version", + kind: "ThirdPartyResourceData", + expectedObj: &extensions.ThirdPartyResourceData{}, + expectErr: false, + }, + { + name: "invalid ThirdPartyResourceData creation", + version: "invalid version", + kind: "ThirdPartyResourceData", + expectedObj: nil, + expectErr: true, + }, + { + name: "valid ListOptions creation", + version: "v1", + kind: "ListOptions", + expectedObj: &v1.ListOptions{}, + expectErr: false, + }, + } + for _, test := range tests { + out, err := creater.New(test.version, test.kind) + if err != nil && !test.expectErr { + t.Errorf("[%s] unexpected error: %v", test.name, err) + } + if err == nil && test.expectErr { + t.Errorf("[%s] unexpected non-error", test.name) + } + if !reflect.DeepEqual(test.expectedObj, out) { + t.Errorf("[%s] unexpected error: expect: %v, got: %v", test.expectedObj, out) + } + + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/etcd/etcd.go index c6f1ecf8a13a..8f06635ff41c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/etcd/etcd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/etcd/etcd.go @@ -20,7 +20,7 @@ import ( "strings" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -40,8 +40,8 @@ func NewREST(s storage.Interface, group, kind string) *REST { prefix := "/ThirdPartyResourceData/" + group + "/" + strings.ToLower(kind) + "s" store := &etcdgeneric.Etcd{ - NewFunc: func() runtime.Object { return &experimental.ThirdPartyResourceData{} }, - NewListFunc: func() runtime.Object { return &experimental.ThirdPartyResourceDataList{} }, + NewFunc: func() runtime.Object { return &extensions.ThirdPartyResourceData{} }, + NewListFunc: func() runtime.Object { return &extensions.ThirdPartyResourceDataList{} }, KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, @@ -49,7 +49,7 @@ func NewREST(s storage.Interface, group, kind string) *REST { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { - return obj.(*experimental.ThirdPartyResourceData).Name, nil + return obj.(*extensions.ThirdPartyResourceData).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return thirdpartyresourcedata.Matcher(label, field) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/etcd/etcd_test.go index 975ce09d2aa3..fc2291507d9a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/etcd/etcd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/etcd/etcd_test.go @@ -20,9 +20,9 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" - // Ensure that experimental/v1 package is initialized. - _ "k8s.io/kubernetes/pkg/apis/experimental/v1" + "k8s.io/kubernetes/pkg/apis/extensions" + // Ensure that extensions/v1beta1 package is initialized. + _ "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/registrytest" @@ -31,12 +31,12 @@ import ( ) func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { - etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "experimental") + etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "extensions") return NewREST(etcdStorage, "foo", "bar"), fakeClient } -func validNewThirdPartyResourceData(name string) *experimental.ThirdPartyResourceData { - return &experimental.ThirdPartyResourceData{ +func validNewThirdPartyResourceData(name string) *extensions.ThirdPartyResourceData { + return &extensions.ThirdPartyResourceData{ ObjectMeta: api.ObjectMeta{ Name: name, Namespace: api.NamespaceDefault, @@ -54,7 +54,7 @@ func TestCreate(t *testing.T) { // valid rsrc, // invalid - &experimental.ThirdPartyResourceData{}, + &extensions.ThirdPartyResourceData{}, ) } @@ -66,7 +66,7 @@ func TestUpdate(t *testing.T) { validNewThirdPartyResourceData("foo"), // updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*experimental.ThirdPartyResourceData) + object := obj.(*extensions.ThirdPartyResourceData) object.Data = []byte("new description") return object }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/registry.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/registry.go index a1ae201453e9..d80aa0718e73 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/registry.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/registry.go @@ -19,7 +19,7 @@ package thirdpartyresourcedata import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/rest" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/watch" @@ -28,15 +28,15 @@ import ( // Registry is an interface implemented by things that know how to store ThirdPartyResourceData objects. type Registry interface { // ListThirdPartyResourceData obtains a list of ThirdPartyResourceData having labels which match selector. - ListThirdPartyResourceData(ctx api.Context, selector labels.Selector) (*experimental.ThirdPartyResourceDataList, error) + ListThirdPartyResourceData(ctx api.Context, selector labels.Selector) (*extensions.ThirdPartyResourceDataList, error) // Watch for new/changed/deleted ThirdPartyResourceData WatchThirdPartyResourceData(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) // Get a specific ThirdPartyResourceData - GetThirdPartyResourceData(ctx api.Context, name string) (*experimental.ThirdPartyResourceData, error) + GetThirdPartyResourceData(ctx api.Context, name string) (*extensions.ThirdPartyResourceData, error) // Create a ThirdPartyResourceData based on a specification. - CreateThirdPartyResourceData(ctx api.Context, resource *experimental.ThirdPartyResourceData) (*experimental.ThirdPartyResourceData, error) + CreateThirdPartyResourceData(ctx api.Context, resource *extensions.ThirdPartyResourceData) (*extensions.ThirdPartyResourceData, error) // Update an existing ThirdPartyResourceData - UpdateThirdPartyResourceData(ctx api.Context, resource *experimental.ThirdPartyResourceData) (*experimental.ThirdPartyResourceData, error) + UpdateThirdPartyResourceData(ctx api.Context, resource *extensions.ThirdPartyResourceData) (*extensions.ThirdPartyResourceData, error) // Delete an existing ThirdPartyResourceData DeleteThirdPartyResourceData(ctx api.Context, name string) error } @@ -52,34 +52,34 @@ func NewRegistry(s rest.StandardStorage) Registry { return &storage{s} } -func (s *storage) ListThirdPartyResourceData(ctx api.Context, label labels.Selector) (*experimental.ThirdPartyResourceDataList, error) { +func (s *storage) ListThirdPartyResourceData(ctx api.Context, label labels.Selector) (*extensions.ThirdPartyResourceDataList, error) { obj, err := s.List(ctx, label, fields.Everything()) if err != nil { return nil, err } - return obj.(*experimental.ThirdPartyResourceDataList), nil + return obj.(*extensions.ThirdPartyResourceDataList), nil } func (s *storage) WatchThirdPartyResourceData(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { return s.Watch(ctx, label, field, resourceVersion) } -func (s *storage) GetThirdPartyResourceData(ctx api.Context, name string) (*experimental.ThirdPartyResourceData, error) { +func (s *storage) GetThirdPartyResourceData(ctx api.Context, name string) (*extensions.ThirdPartyResourceData, error) { obj, err := s.Get(ctx, name) if err != nil { return nil, err } - return obj.(*experimental.ThirdPartyResourceData), nil + return obj.(*extensions.ThirdPartyResourceData), nil } -func (s *storage) CreateThirdPartyResourceData(ctx api.Context, ThirdPartyResourceData *experimental.ThirdPartyResourceData) (*experimental.ThirdPartyResourceData, error) { +func (s *storage) CreateThirdPartyResourceData(ctx api.Context, ThirdPartyResourceData *extensions.ThirdPartyResourceData) (*extensions.ThirdPartyResourceData, error) { obj, err := s.Create(ctx, ThirdPartyResourceData) - return obj.(*experimental.ThirdPartyResourceData), err + return obj.(*extensions.ThirdPartyResourceData), err } -func (s *storage) UpdateThirdPartyResourceData(ctx api.Context, ThirdPartyResourceData *experimental.ThirdPartyResourceData) (*experimental.ThirdPartyResourceData, error) { +func (s *storage) UpdateThirdPartyResourceData(ctx api.Context, ThirdPartyResourceData *extensions.ThirdPartyResourceData) (*extensions.ThirdPartyResourceData, error) { obj, _, err := s.Update(ctx, ThirdPartyResourceData) - return obj.(*experimental.ThirdPartyResourceData), err + return obj.(*extensions.ThirdPartyResourceData), err } func (s *storage) DeleteThirdPartyResourceData(ctx api.Context, name string) error { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/strategy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/strategy.go index d1e09fb6c499..05932374c66e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/strategy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/strategy.go @@ -21,8 +21,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/rest" - "k8s.io/kubernetes/pkg/apis/experimental" - "k8s.io/kubernetes/pkg/apis/experimental/validation" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/extensions/validation" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" @@ -52,7 +52,7 @@ func (strategy) PrepareForCreate(obj runtime.Object) { } func (strategy) Validate(ctx api.Context, obj runtime.Object) fielderrors.ValidationErrorList { - return validation.ValidateThirdPartyResourceData(obj.(*experimental.ThirdPartyResourceData)) + return validation.ValidateThirdPartyResourceData(obj.(*extensions.ThirdPartyResourceData)) } func (strategy) AllowCreateOnUpdate() bool { @@ -63,7 +63,7 @@ func (strategy) PrepareForUpdate(obj, old runtime.Object) { } func (strategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList { - return validation.ValidateThirdPartyResourceDataUpdate(old.(*experimental.ThirdPartyResourceData), obj.(*experimental.ThirdPartyResourceData)) + return validation.ValidateThirdPartyResourceDataUpdate(old.(*extensions.ThirdPartyResourceData), obj.(*extensions.ThirdPartyResourceData)) } func (strategy) AllowUnconditionalUpdate() bool { @@ -73,7 +73,7 @@ func (strategy) AllowUnconditionalUpdate() bool { // Matcher returns a generic matcher for a given label and field selector. func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - sa, ok := obj.(*experimental.ThirdPartyResourceData) + sa, ok := obj.(*extensions.ThirdPartyResourceData) if !ok { return false, fmt.Errorf("not a ThirdPartyResourceData") } @@ -83,6 +83,6 @@ func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { } // SelectableFields returns a label set that can be used for filter selection -func SelectableFields(obj *experimental.ThirdPartyResourceData) labels.Set { +func SelectableFields(obj *extensions.ThirdPartyResourceData) labels.Set { return labels.Set{} } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/util.go index db62f6282abe..482dadb1eff2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/util.go @@ -20,7 +20,7 @@ import ( "fmt" "strings" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" ) func convertToCamelCase(input string) string { @@ -40,7 +40,7 @@ func convertToCamelCase(input string) string { return result } -func ExtractApiGroupAndKind(rsrc *experimental.ThirdPartyResource) (kind string, group string, err error) { +func ExtractApiGroupAndKind(rsrc *extensions.ThirdPartyResource) (kind string, group string, err error) { parts := strings.Split(rsrc.Name, ".") if len(parts) < 3 { return "", "", fmt.Errorf("unexpectedly short resource name: %s, expected at least ..", rsrc.Name) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/util_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/util_test.go index 977e717997b0..a18722c17979 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/util_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/util_test.go @@ -20,7 +20,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" ) func TestExtractAPIGroupAndKind(t *testing.T) { @@ -47,7 +47,7 @@ func TestExtractAPIGroupAndKind(t *testing.T) { } for _, test := range tests { - kind, group, err := ExtractApiGroupAndKind(&experimental.ThirdPartyResource{ObjectMeta: api.ObjectMeta{Name: test.input}}) + kind, group, err := ExtractApiGroupAndKind(&extensions.ThirdPartyResource{ObjectMeta: api.ObjectMeta{Name: test.input}}) if err != nil && !test.expectErr { t.Errorf("unexpected error: %v", err) continue diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/codec.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/codec.go index 93b7102eb69e..5d06482ea546 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/codec.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/codec.go @@ -17,6 +17,8 @@ limitations under the License. package runtime import ( + "io" + "k8s.io/kubernetes/pkg/util/yaml" ) @@ -78,6 +80,10 @@ func (c *codecWrapper) Encode(obj Object) ([]byte, error) { return c.EncodeToVersion(obj, c.version) } +func (c *codecWrapper) EncodeToStream(obj Object, stream io.Writer) error { + return c.EncodeToVersionStream(obj, c.version, stream) +} + // TODO: Make this behaviour default when we move everyone away from // the unversioned types. // diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/conversion_generator.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/conversion_generator.go index 979313ee53b1..9bfab5ddc76e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/conversion_generator.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/conversion_generator.go @@ -44,6 +44,7 @@ func NewConversionGenerator(scheme *conversion.Scheme, targetPkg string) Convers scheme: scheme, targetPkg: targetPkg, convertibles: make(map[reflect.Type]reflect.Type), + overridden: make(map[reflect.Type]bool), pkgOverwrites: make(map[string]string), imports: make(map[string]string), shortImports: make(map[string]string), @@ -60,6 +61,7 @@ type conversionGenerator struct { scheme *conversion.Scheme targetPkg string convertibles map[reflect.Type]reflect.Type + overridden map[reflect.Type]bool // If pkgOverwrites is set for a given package name, that package name // will be replaced while writing conversion function. If empty, package // name will be omitted. @@ -165,9 +167,10 @@ func (g *conversionGenerator) generateConversionsBetween(inType, outType reflect if !existingConversion && (inErr != nil || outErr != nil) { return inErr } - if !existingConversion { - g.convertibles[inType] = outType + if existingConversion { + g.overridden[inType] = true } + g.convertibles[inType] = outType return nil default: // All simple types should be handled correctly with default conversion. @@ -368,7 +371,7 @@ func (g *conversionGenerator) RegisterConversionFunctions(w io.Writer, pkg strin // Write conversion function names alphabetically ordered. var names []string for inType, outType := range g.convertibles { - names = append(names, g.conversionFunctionName(inType, outType)) + names = append(names, g.generatedFunctionName(inType, outType)) } sort.Strings(names) @@ -482,6 +485,10 @@ func (g *conversionGenerator) conversionFunctionName(inType, outType reflect.Typ return funcName } +func (g *conversionGenerator) generatedFunctionName(inType, outType reflect.Type) string { + return "auto" + g.conversionFunctionName(inType, outType) +} + func (g *conversionGenerator) writeHeader(b *buffer, name, inType, outType string, indent int) { format := "func %s(in *%s, out *%s, s conversion.Scope) error {\n" stmt := fmt.Sprintf(format, name, inType, outType) @@ -654,10 +661,28 @@ func (g *conversionGenerator) writeConversionForPtr(b *buffer, inField, outField return nil } +func (g *conversionGenerator) canTryConversion(b *buffer, inType reflect.Type, inField, outField reflect.StructField, indent int) (bool, error) { + if inField.Type.Kind() != outField.Type.Kind() { + if !g.overridden[inType] { + return false, fmt.Errorf("input %s.%s (%s) does not match output (%s) and conversion is not overridden", inType, inField.Name, inField.Type.Kind(), outField.Type.Kind()) + } + b.addLine(fmt.Sprintf("// in.%s has no peer in out\n", inField.Name), indent) + return false, nil + } + return true, nil +} + func (g *conversionGenerator) writeConversionForStruct(b *buffer, inType, outType reflect.Type, indent int) error { for i := 0; i < inType.NumField(); i++ { inField := inType.Field(i) - outField, _ := outType.FieldByName(inField.Name) + outField, found := outType.FieldByName(inField.Name) + if !found { + if !g.overridden[inType] { + return fmt.Errorf("input %s.%s has no peer in output %s and conversion is not overridden", inType, inField.Name, outType) + } + b.addLine(fmt.Sprintf("// in.%s has no peer in out\n", inField.Name), indent) + continue + } existsConversion := g.scheme.Converter().HasConversionFunc(inField.Type, outField.Type) if existsConversion && !g.existsDedicatedConversionFunction(inField.Type, outField.Type) { @@ -672,16 +697,31 @@ func (g *conversionGenerator) writeConversionForStruct(b *buffer, inType, outTyp switch inField.Type.Kind() { case reflect.Map: + if try, err := g.canTryConversion(b, inType, inField, outField, indent); err != nil { + return err + } else if !try { + continue + } if err := g.writeConversionForMap(b, inField, outField, indent); err != nil { return err } continue case reflect.Ptr: + if try, err := g.canTryConversion(b, inType, inField, outField, indent); err != nil { + return err + } else if !try { + continue + } if err := g.writeConversionForPtr(b, inField, outField, indent); err != nil { return err } continue case reflect.Slice: + if try, err := g.canTryConversion(b, inType, inField, outField, indent); err != nil { + return err + } else if !try { + continue + } if err := g.writeConversionForSlice(b, inField, outField, indent); err != nil { return err } @@ -721,8 +761,9 @@ func (g *conversionGenerator) writeConversionForStruct(b *buffer, inType, outTyp } func (g *conversionGenerator) writeConversionForType(b *buffer, inType, outType reflect.Type, indent int) error { - funcName := g.conversionFunctionName(inType, outType) - g.writeHeader(b, funcName, g.typeName(inType), g.typeName(outType), indent) + // Always emit the auto-generated name. + autoFuncName := g.generatedFunctionName(inType, outType) + g.writeHeader(b, autoFuncName, g.typeName(inType), g.typeName(outType), indent) if err := g.writeDefaultingFunc(b, inType, indent+1); err != nil { return err } @@ -736,6 +777,15 @@ func (g *conversionGenerator) writeConversionForType(b *buffer, inType, outType } g.writeFooter(b, indent) b.addLine("\n", 0) + + if !g.overridden[inType] { + // Also emit the "user-facing" name. + userFuncName := g.conversionFunctionName(inType, outType) + g.writeHeader(b, userFuncName, g.typeName(inType), g.typeName(outType), indent) + b.addLine(fmt.Sprintf("return %s(in, out, s)\n", autoFuncName), indent+1) + b.addLine("}\n\n", 0) + } + return nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/deep_copy_generator.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/deep_copy_generator.go index 38fb54f5c472..5dee4e263ab0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/deep_copy_generator.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/deep_copy_generator.go @@ -403,8 +403,7 @@ func (g *deepCopyGenerator) writeDeepCopyForPtr(b *buffer, inField reflect.Struc ifStmt := fmt.Sprintf(ifFormat, inField.Name) b.addLine(ifStmt, indent) - kind := inField.Type.Elem().Kind() - switch kind { + switch inField.Type.Elem().Kind() { case reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface, reflect.Struct: if _, found := g.copyables[inField.Type.Elem()]; found { newFormat := "out.%s = new(%s)\n" @@ -421,10 +420,8 @@ func (g *deepCopyGenerator) writeDeepCopyForPtr(b *buffer, inField reflect.Struc ifStmt := fmt.Sprintf(ifFormat, inField.Name) b.addLine(ifStmt, indent+1) b.addLine("return err\n", indent+2) - if kind != reflect.Struct { - b.addLine("} else if newVal == nil {\n", indent+1) - b.addLine(fmt.Sprintf("out.%s = nil\n", inField.Name), indent+2) - } + b.addLine("} else if newVal == nil {\n", indent+1) + b.addLine(fmt.Sprintf("out.%s = nil\n", inField.Name), indent+2) b.addLine("} else {\n", indent+1) assignFormat := "out.%s = newVal.(%s)\n" assignStmt := fmt.Sprintf(assignFormat, inField.Name, g.typeName(inField.Type)) @@ -458,8 +455,7 @@ func (g *deepCopyGenerator) writeDeepCopyForSlice(b *buffer, inField reflect.Str forStmt := fmt.Sprintf(forFormat, inField.Name) b.addLine(forStmt, indent+1) - kind := inField.Type.Elem().Kind() - switch kind { + switch inField.Type.Elem().Kind() { case reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface, reflect.Struct: if _, found := g.copyables[inField.Type.Elem()]; found { assignFormat := "if err := %s(in.%s[i], &out.%s[i], c); err != nil {\n" @@ -473,10 +469,8 @@ func (g *deepCopyGenerator) writeDeepCopyForSlice(b *buffer, inField reflect.Str ifStmt := fmt.Sprintf(ifFormat, inField.Name) b.addLine(ifStmt, indent+2) b.addLine("return err\n", indent+3) - if kind != reflect.Struct { - b.addLine("} else if newVal == nil {\n", indent+2) - b.addLine(fmt.Sprintf("out.%s[i] = nil\n", inField.Name), indent+3) - } + b.addLine("} else if newVal == nil {\n", indent+2) + b.addLine(fmt.Sprintf("out.%s[i] = nil\n", inField.Name), indent+3) b.addLine("} else {\n", indent+2) assignFormat := "out.%s[i] = newVal.(%s)\n" assignStmt := fmt.Sprintf(assignFormat, inField.Name, g.typeName(inField.Type.Elem())) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/helper.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/helper.go index 7a3c266a78d5..4fd370ca5efa 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/helper.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/helper.go @@ -71,15 +71,18 @@ func ExtractList(obj Object) ([]Object, error) { list := make([]Object, items.Len()) for i := range list { raw := items.Index(i) - var found bool - switch raw.Kind() { - case reflect.Interface, reflect.Ptr: - list[i], found = raw.Interface().(Object) + switch item := raw.Interface().(type) { + case Object: + list[i] = item + case RawExtension: + list[i] = &Unknown{ + RawJSON: item.RawJSON, + } default: - list[i], found = raw.Addr().Interface().(Object) - } - if !found { - return nil, fmt.Errorf("item[%v]: Expected object, got %#v(%s)", i, raw.Interface(), raw.Kind()) + var found bool + if list[i], found = raw.Addr().Interface().(Object); !found { + return nil, fmt.Errorf("%v: item[%v]: Expected object, got %#v(%s)", obj, i, raw.Interface(), raw.Kind()) + } } } return list, nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/helper_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/helper_test.go index 7ec7cbdce568..fc5810b9bd7a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/helper_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/helper_test.go @@ -22,6 +22,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" @@ -87,6 +88,28 @@ func TestExtractListGeneric(t *testing.T) { } } +func TestExtractListGenericV1(t *testing.T) { + pl := &v1.List{ + Items: []runtime.RawExtension{ + {RawJSON: []byte("foo")}, + {RawJSON: []byte("bar")}, + }, + } + list, err := runtime.ExtractList(pl) + if err != nil { + t.Fatalf("Unexpected error %v", err) + } + if e, a := len(list), len(pl.Items); e != a { + t.Fatalf("Expected %v, got %v", e, a) + } + if obj, ok := list[0].(*runtime.Unknown); !ok { + t.Fatalf("Expected list[0] to be *runtime.Unknown, it is %#v", obj) + } + if obj, ok := list[1].(*runtime.Unknown); !ok { + t.Fatalf("Expected list[1] to be *runtime.Unknown, it is %#v", obj) + } +} + type fakePtrInterfaceList struct { Items *[]runtime.Object } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/interfaces.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/interfaces.go index d21274e402f1..12f65f8c8971 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/interfaces.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/interfaces.go @@ -16,6 +16,10 @@ limitations under the License. package runtime +import ( + "io" +) + // ObjectScheme represents common conversions between formal external API versions // and the internal Go structs. ObjectScheme is typically used with ObjectCodec to // transform internal Go structs into serialized versions. There may be many valid @@ -45,6 +49,7 @@ type Decoder interface { // Encoder defines methods for serializing API objects into bytes type Encoder interface { Encode(obj Object) (data []byte, err error) + EncodeToStream(obj Object, stream io.Writer) error } // Codec defines methods for serializing and deserializing API objects. @@ -67,6 +72,7 @@ type ObjectEncoder interface { // to a specified output version. An error is returned if the object // cannot be converted for any reason. EncodeToVersion(obj Object, outVersion string) ([]byte, error) + EncodeToVersionStream(obj Object, outVersion string, stream io.Writer) error } // ObjectConvertor converts an object to a different version. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/scheme.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/scheme.go index 4819a9322b17..0a2bf47c3e67 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/scheme.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/scheme.go @@ -19,6 +19,7 @@ package runtime import ( "encoding/json" "fmt" + "io" "net/url" "reflect" @@ -434,6 +435,10 @@ func (s *Scheme) EncodeToVersion(obj Object, destVersion string) (data []byte, e return s.raw.EncodeToVersion(obj, destVersion) } +func (s *Scheme) EncodeToVersionStream(obj Object, destVersion string, stream io.Writer) error { + return s.raw.EncodeToVersionStream(obj, destVersion, stream) +} + // Decode converts a YAML or JSON string back into a pointer to an api object. // Deduces the type based upon the APIVersion and Kind fields, which are set // by Encode. Only versioned objects (APIVersion != "") are accepted. The object diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/scheme_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/scheme_test.go index 270ac42e9f37..83f8d4c6e256 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/scheme_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/scheme_test.go @@ -246,13 +246,16 @@ func TestExtensionMapping(t *testing.T) { }{ { &InternalExtensionType{Extension: runtime.EmbeddedObject{Object: &ExtensionA{TestString: "foo"}}}, - `{"kind":"ExtensionType","apiVersion":"testExternal","extension":{"kind":"A","testString":"foo"}}`, + `{"kind":"ExtensionType","apiVersion":"testExternal","extension":{"kind":"A","testString":"foo"}} +`, }, { &InternalExtensionType{Extension: runtime.EmbeddedObject{Object: &ExtensionB{TestString: "bar"}}}, - `{"kind":"ExtensionType","apiVersion":"testExternal","extension":{"kind":"B","testString":"bar"}}`, + `{"kind":"ExtensionType","apiVersion":"testExternal","extension":{"kind":"B","testString":"bar"}} +`, }, { &InternalExtensionType{Extension: runtime.EmbeddedObject{Object: nil}}, - `{"kind":"ExtensionType","apiVersion":"testExternal","extension":null}`, + `{"kind":"ExtensionType","apiVersion":"testExternal","extension":null} +`, }, } @@ -261,7 +264,7 @@ func TestExtensionMapping(t *testing.T) { if err != nil { t.Errorf("unexpected error '%v' (%#v)", err, item.obj) } else if e, a := item.encoded, string(gotEncoded); e != a { - t.Errorf("expected %v, got %v", e, a) + t.Errorf("expected\n%#v\ngot\n%#v\n", e, a) } gotDecoded, err := scheme.Decode([]byte(item.encoded)) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontext/util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontext/util.go index 7a4718b4b1f5..893a4d825fab 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontext/util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontext/util.go @@ -21,7 +21,6 @@ import ( "strings" "k8s.io/kubernetes/pkg/api" - "github.com/golang/glog" ) // HasPrivilegedRequest returns the value of SecurityContext.Privileged, taking into account @@ -48,16 +47,6 @@ func HasCapabilitiesRequest(container *api.Container) bool { return len(container.SecurityContext.Capabilities.Add) > 0 || len(container.SecurityContext.Capabilities.Drop) > 0 } -// SELinuxOptionsString returns the string representation of a -// set of SELinuxOptions. -func SELinuxOptionsString(sel *api.SELinuxOptions) string { - if sel == nil { - return "" - } - - return fmt.Sprintf("%s:%s:%s:%s", sel.User, sel.Role, sel.Type, sel.Level) -} - const expectedSELinuxContextFields = 4 // ParseSELinuxOptions parses a string containing a full SELinux context @@ -78,31 +67,6 @@ func ParseSELinuxOptions(context string) (*api.SELinuxOptions, error) { }, nil } -// ProjectSELinuxOptions projects a source SELinuxOptions onto a target -// SELinuxOptions and returns a _new_ SELinuxOptions containing the result. -func ProjectSELinuxOptions(source, target *api.SELinuxOptions) *api.SELinuxOptions { - glog.V(4).Infof("Projecting security context %v onto %v", SELinuxOptionsString(source), SELinuxOptionsString(target)) - - // Copy the receiving options to project onto - result := &api.SELinuxOptions{} - *result = *target - - if source.User != "" { - result.User = source.User - } - if source.Role != "" { - result.Role = source.Role - } - if source.Type != "" { - result.Type = source.Type - } - if source.Level != "" { - result.Level = source.Level - } - - return result -} - // HasNonRootUID returns true if the runAsUser is set and is greater than 0. func HasRootUID(container *api.Container) bool { if container.SecurityContext == nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontext/util_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontext/util_test.go index 0e6d259009b7..d2f1e48d0148 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontext/util_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontext/util_test.go @@ -69,78 +69,6 @@ func TestParseSELinuxOptions(t *testing.T) { } } -func TestProjectSELinuxOptions(t *testing.T) { - baseContext := func() *api.SELinuxOptions { - return &api.SELinuxOptions{ - User: "user", - Role: "role", - Type: "type", - Level: "level", - } - } - - var ( - userContext = baseContext() - roleContext = baseContext() - typeContext = baseContext() - levelContext = baseContext() - allContext = baseContext() - ) - - userContext.User = "user2" - roleContext.Role = "role2" - typeContext.Type = "type2" - levelContext.Level = "level2" - allContext.User = "user3" - allContext.Role = "role3" - allContext.Type = "type3" - allContext.Level = "level3" - - cases := []struct { - name string - source *api.SELinuxOptions - target *api.SELinuxOptions - expected *api.SELinuxOptions - }{ - { - name: "project user", - source: userContext, - target: baseContext(), - expected: userContext, - }, - { - name: "project role", - source: roleContext, - target: baseContext(), - expected: roleContext, - }, - { - name: "project type", - source: typeContext, - target: baseContext(), - expected: typeContext, - }, - { - name: "project level", - source: levelContext, - target: baseContext(), - expected: levelContext, - }, - { - name: "project all", - source: allContext, - target: baseContext(), - expected: allContext, - }, - } - - for _, tc := range cases { - result := ProjectSELinuxOptions(tc.source, tc.target) - - compareContexts(tc.name, tc.expected, result, t) - } -} - func compareContexts(name string, ex, ac *api.SELinuxOptions, t *testing.T) { if e, a := ex.User, ac.User; e != a { t.Errorf("%v: expected user: %v, got: %v", name, e, a) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go deleted file mode 100644 index ce8a25aff07c..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go +++ /dev/null @@ -1,205 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 securitycontextconstraints - -import ( - "fmt" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/securitycontextconstraints/selinux" - "k8s.io/kubernetes/pkg/securitycontextconstraints/user" - "k8s.io/kubernetes/pkg/util/fielderrors" -) - -// simpleProvider is the default implementation of SecurityContextConstraintsProvider -type simpleProvider struct { - scc *api.SecurityContextConstraints - runAsUserStrategy user.RunAsUserSecurityContextConstraintsStrategy - seLinuxStrategy selinux.SELinuxSecurityContextConstraintsStrategy -} - -// ensure we implement the interface correctly. -var _ SecurityContextConstraintsProvider = &simpleProvider{} - -// NewSimpleProvider creates a new SecurityContextConstraintsProvider instance. -func NewSimpleProvider(scc *api.SecurityContextConstraints) (SecurityContextConstraintsProvider, error) { - if scc == nil { - return nil, fmt.Errorf("NewSimpleProvider requires a SecurityContextConstraints") - } - - var userStrat user.RunAsUserSecurityContextConstraintsStrategy = nil - var err error = nil - switch scc.RunAsUser.Type { - case api.RunAsUserStrategyMustRunAs: - userStrat, err = user.NewMustRunAs(&scc.RunAsUser) - case api.RunAsUserStrategyMustRunAsRange: - userStrat, err = user.NewMustRunAsRange(&scc.RunAsUser) - case api.RunAsUserStrategyMustRunAsNonRoot: - userStrat, err = user.NewRunAsNonRoot(&scc.RunAsUser) - case api.RunAsUserStrategyRunAsAny: - userStrat, err = user.NewRunAsAny(&scc.RunAsUser) - default: - err = fmt.Errorf("Unrecognized RunAsUser strategy type %s", scc.RunAsUser.Type) - } - if err != nil { - return nil, err - } - - var seLinuxStrat selinux.SELinuxSecurityContextConstraintsStrategy = nil - err = nil - switch scc.SELinuxContext.Type { - case api.SELinuxStrategyMustRunAs: - seLinuxStrat, err = selinux.NewMustRunAs(&scc.SELinuxContext) - case api.SELinuxStrategyRunAsAny: - seLinuxStrat, err = selinux.NewRunAsAny(&scc.SELinuxContext) - default: - err = fmt.Errorf("Unrecognized SELinuxContext strategy type %s", scc.SELinuxContext.Type) - } - if err != nil { - return nil, err - } - - return &simpleProvider{ - scc: scc, - runAsUserStrategy: userStrat, - seLinuxStrategy: seLinuxStrat, - }, nil -} - -// Create a SecurityContext based on the given constraints. If a setting is already set on the -// container's security context then it will not be changed. Validation should be used after -// the context is created to ensure it complies with the required restrictions. -// -// NOTE: this method works on a copy of the SC of the container. It is up to the caller to apply -// the SC if validation passes. -func (s *simpleProvider) CreateSecurityContext(pod *api.Pod, container *api.Container) (*api.SecurityContext, error) { - var sc *api.SecurityContext = nil - if container.SecurityContext != nil { - // work with a copy of the original - copy := *container.SecurityContext - sc = © - } else { - sc = &api.SecurityContext{} - } - if sc.RunAsUser == nil { - uid, err := s.runAsUserStrategy.Generate(pod, container) - if err != nil { - return nil, err - } - sc.RunAsUser = uid - } - - if sc.SELinuxOptions == nil { - seLinux, err := s.seLinuxStrategy.Generate(pod, container) - if err != nil { - return nil, err - } - sc.SELinuxOptions = seLinux - } - - if sc.Privileged == nil { - priv := false - sc.Privileged = &priv - } - - // if we're using the non-root strategy set the marker that this container should not be - // run as root which will signal to the kubelet to do a final check either on the runAsUser - // or, if runAsUser is not set, the image - if s.scc.RunAsUser.Type == api.RunAsUserStrategyMustRunAsNonRoot { - sc.RunAsNonRoot = true - } - - // No need to touch capabilities, they will validate or not. - return sc, nil -} - -// Ensure a container's SecurityContext is in compliance with the given constraints -func (s *simpleProvider) ValidateSecurityContext(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { - allErrs := fielderrors.ValidationErrorList{} - - if container.SecurityContext == nil { - allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext", container.SecurityContext, "No security context is set")) - return allErrs - } - - sc := container.SecurityContext - allErrs = append(allErrs, s.runAsUserStrategy.Validate(pod, container)...) - allErrs = append(allErrs, s.seLinuxStrategy.Validate(pod, container)...) - - if !s.scc.AllowPrivilegedContainer && *sc.Privileged { - allErrs = append(allErrs, fielderrors.NewFieldInvalid("privileged", *sc.Privileged, "Privileged containers are not allowed")) - } - - if sc.Capabilities != nil && len(sc.Capabilities.Add) > 0 { - for _, cap := range sc.Capabilities.Add { - found := false - for _, allowedCap := range s.scc.AllowedCapabilities { - if cap == allowedCap { - found = true - break - } - } - if !found { - allErrs = append(allErrs, fielderrors.NewFieldInvalid("capabilities.add", cap, "Capability is not allowed to be added")) - } - } - } - - if !s.scc.AllowHostDirVolumePlugin { - for _, v := range pod.Spec.Volumes { - if v.HostPath != nil { - allErrs = append(allErrs, fielderrors.NewFieldInvalid("VolumeMounts", v.Name, "Host Volumes are not allowed to be used")) - } - } - } - - if !s.scc.AllowHostNetwork && pod.Spec.HostNetwork { - allErrs = append(allErrs, fielderrors.NewFieldInvalid("hostNetwork", pod.Spec.HostNetwork, "Host network is not allowed to be used")) - } - - if !s.scc.AllowHostPorts { - for idx, c := range pod.Spec.Containers { - allErrs = append(allErrs, s.hasHostPort(&c).Prefix(fmt.Sprintf("containers.%d", idx))...) - } - } - - if !s.scc.AllowHostPID && pod.Spec.HostPID { - allErrs = append(allErrs, fielderrors.NewFieldInvalid("hostPID", pod.Spec.HostPID, "Host PID is not allowed to be used")) - } - - if !s.scc.AllowHostIPC && pod.Spec.HostIPC { - allErrs = append(allErrs, fielderrors.NewFieldInvalid("hostIPC", pod.Spec.HostIPC, "Host IPC is not allowed to be used")) - } - - return allErrs -} - -// hasHostPort checks the port definitions on the container for HostPort > 0. -func (s *simpleProvider) hasHostPort(container *api.Container) fielderrors.ValidationErrorList { - allErrs := fielderrors.ValidationErrorList{} - for _, cp := range container.Ports { - if cp.HostPort > 0 { - allErrs = append(allErrs, fielderrors.NewFieldInvalid("hostPort", cp.HostPort, "Host ports are not allowed to be used")) - } - } - return allErrs -} - -// Get the name of the SCC that this provider was initialized with. -func (s *simpleProvider) GetSCCName() string { - return s.scc.Name -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go deleted file mode 100644 index ca2f28268eb0..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go +++ /dev/null @@ -1,393 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 securitycontextconstraints - -import ( - "reflect" - "strings" - "testing" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" -) - -func TestCreateSecurityContextNonmutating(t *testing.T) { - // Create a pod with a security context that needs filling in - createPod := func() *api.Pod { - return &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{{ - SecurityContext: &api.SecurityContext{}, - }}, - }, - } - } - - // Create an SCC with strategies that will populate a blank security context - createSCC := func() *api.SecurityContextConstraints { - var uid int64 = 1 - return &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{ - Name: "scc-sa", - }, - RunAsUser: api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyMustRunAs, - UID: &uid, - }, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyMustRunAs, - SELinuxOptions: &api.SELinuxOptions{User: "you"}, - }, - } - } - - pod := createPod() - scc := createSCC() - - provider, err := NewSimpleProvider(scc) - if err != nil { - t.Fatal("unable to create provider %v", err) - } - sc, err := provider.CreateSecurityContext(pod, &pod.Spec.Containers[0]) - if err != nil { - t.Fatal("unable to create provider %v", err) - } - - // The generated security context should have filled in missing options, so they should differ - if reflect.DeepEqual(sc, &pod.Spec.Containers[0].SecurityContext) { - t.Error("expected created security context to be different than container's, but they were identical") - } - - // Creating the provider or the security context should not have mutated the scc or pod - if !reflect.DeepEqual(createPod(), pod) { - diff := util.ObjectDiff(createPod(), pod) - t.Errorf("pod was mutated by CreateSecurityContext. diff:\n%s", diff) - } - if !reflect.DeepEqual(createSCC(), scc) { - t.Error("different") - } -} - -func TestValidateFailures(t *testing.T) { - defaultSCC := func() *api.SecurityContextConstraints { - return &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{ - Name: "scc-sa", - }, - RunAsUser: api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyRunAsAny, - }, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyRunAsAny, - }, - } - } - - var notPriv bool = false - defaultPod := func() *api.Pod { - return &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - SecurityContext: &api.SecurityContext{ - // expected to be set by defaulting mechanisms - Privileged: ¬Priv, - // fill in the rest for test cases - }, - }, - }, - }, - } - } - - // fail user strat - failUserSCC := defaultSCC() - var uid int64 = 999 - var badUID int64 = 1 - failUserSCC.RunAsUser = api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyMustRunAs, - UID: &uid, - } - failUserPod := defaultPod() - failUserPod.Spec.Containers[0].SecurityContext.RunAsUser = &badUID - - // fail selinux strat - failSELinuxSCC := defaultSCC() - failSELinuxSCC.SELinuxContext = api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyMustRunAs, - SELinuxOptions: &api.SELinuxOptions{ - Level: "foo", - }, - } - failSELinuxPod := defaultPod() - failSELinuxPod.Spec.Containers[0].SecurityContext.SELinuxOptions = &api.SELinuxOptions{ - Level: "bar", - } - - failPrivPod := defaultPod() - var priv bool = true - failPrivPod.Spec.Containers[0].SecurityContext.Privileged = &priv - - failCapsPod := defaultPod() - failCapsPod.Spec.Containers[0].SecurityContext.Capabilities = &api.Capabilities{ - Add: []api.Capability{"foo"}, - } - - failHostDirPod := defaultPod() - failHostDirPod.Spec.Volumes = []api.Volume{ - { - Name: "bad volume", - VolumeSource: api.VolumeSource{ - HostPath: &api.HostPathVolumeSource{}, - }, - }, - } - - failHostNetworkPod := defaultPod() - failHostNetworkPod.Spec.HostNetwork = true - - failHostPIDPod := defaultPod() - failHostPIDPod.Spec.HostPID = true - - failHostIPCPod := defaultPod() - failHostIPCPod.Spec.HostIPC = true - - failHostPortPod := defaultPod() - failHostPortPod.Spec.Containers[0].Ports = []api.ContainerPort{{HostPort: 1}} - - errorCases := map[string]struct { - pod *api.Pod - scc *api.SecurityContextConstraints - expectedError string - }{ - "failUserSCC": { - pod: failUserPod, - scc: failUserSCC, - expectedError: "does not match required UID", - }, - "failSELinuxSCC": { - pod: failSELinuxPod, - scc: failSELinuxSCC, - expectedError: "does not match required level", - }, - "failPrivSCC": { - pod: failPrivPod, - scc: defaultSCC(), - expectedError: "Privileged containers are not allowed", - }, - "failCapsSCC": { - pod: failCapsPod, - scc: defaultSCC(), - expectedError: "Capability is not allowed to be added", - }, - "failHostDirSCC": { - pod: failHostDirPod, - scc: defaultSCC(), - expectedError: "Host Volumes are not allowed to be used", - }, - "failHostNetworkSCC": { - pod: failHostNetworkPod, - scc: defaultSCC(), - expectedError: "Host network is not allowed to be used", - }, - "failHostPortSCC": { - pod: failHostPortPod, - scc: defaultSCC(), - expectedError: "Host ports are not allowed to be used", - }, - "failHostPIDSCC": { - pod: failHostPIDPod, - scc: defaultSCC(), - expectedError: "Host PID is not allowed to be used", - }, - "failHostIPCSCC": { - pod: failHostIPCPod, - scc: defaultSCC(), - expectedError: "Host IPC is not allowed to be used", - }, - } - - for k, v := range errorCases { - provider, err := NewSimpleProvider(v.scc) - if err != nil { - t.Fatal("unable to create provider %v", err) - } - errs := provider.ValidateSecurityContext(v.pod, &v.pod.Spec.Containers[0]) - if len(errs) == 0 { - t.Errorf("%s expected validation failure but did not receive errors", k) - continue - } - if !strings.Contains(errs[0].Error(), v.expectedError) { - t.Errorf("%s received unexpected error %v", k, errs) - } - } -} - -func TestValidateSuccess(t *testing.T) { - defaultSCC := func() *api.SecurityContextConstraints { - return &api.SecurityContextConstraints{ - ObjectMeta: api.ObjectMeta{ - Name: "scc-sa", - }, - RunAsUser: api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyRunAsAny, - }, - SELinuxContext: api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyRunAsAny, - }, - } - } - - var notPriv bool = false - defaultPod := func() *api.Pod { - return &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - SecurityContext: &api.SecurityContext{ - // expected to be set by defaulting mechanisms - Privileged: ¬Priv, - // fill in the rest for test cases - }, - }, - }, - }, - } - } - - // fail user strat - userSCC := defaultSCC() - var uid int64 = 999 - userSCC.RunAsUser = api.RunAsUserStrategyOptions{ - Type: api.RunAsUserStrategyMustRunAs, - UID: &uid, - } - userPod := defaultPod() - userPod.Spec.Containers[0].SecurityContext.RunAsUser = &uid - - // fail selinux strat - seLinuxSCC := defaultSCC() - seLinuxSCC.SELinuxContext = api.SELinuxContextStrategyOptions{ - Type: api.SELinuxStrategyMustRunAs, - SELinuxOptions: &api.SELinuxOptions{ - Level: "foo", - }, - } - seLinuxPod := defaultPod() - seLinuxPod.Spec.Containers[0].SecurityContext.SELinuxOptions = &api.SELinuxOptions{ - Level: "foo", - } - - privSCC := defaultSCC() - privSCC.AllowPrivilegedContainer = true - privPod := defaultPod() - var priv bool = true - privPod.Spec.Containers[0].SecurityContext.Privileged = &priv - - capsSCC := defaultSCC() - capsSCC.AllowedCapabilities = []api.Capability{"foo"} - capsPod := defaultPod() - capsPod.Spec.Containers[0].SecurityContext.Capabilities = &api.Capabilities{ - Add: []api.Capability{"foo"}, - } - - hostDirSCC := defaultSCC() - hostDirSCC.AllowHostDirVolumePlugin = true - hostDirPod := defaultPod() - hostDirPod.Spec.Volumes = []api.Volume{ - { - Name: "bad volume", - VolumeSource: api.VolumeSource{ - HostPath: &api.HostPathVolumeSource{}, - }, - }, - } - - hostNetworkSCC := defaultSCC() - hostNetworkSCC.AllowHostNetwork = true - hostNetworkPod := defaultPod() - hostNetworkPod.Spec.HostNetwork = true - - hostPIDSCC := defaultSCC() - hostPIDSCC.AllowHostPID = true - hostPIDPod := defaultPod() - hostPIDPod.Spec.HostPID = true - - hostIPCSCC := defaultSCC() - hostIPCSCC.AllowHostIPC = true - hostIPCPod := defaultPod() - hostIPCPod.Spec.HostIPC = true - - hostPortSCC := defaultSCC() - hostPortSCC.AllowHostPorts = true - hostPortPod := defaultPod() - hostPortPod.Spec.Containers[0].Ports = []api.ContainerPort{{HostPort: 1}} - - errorCases := map[string]struct { - pod *api.Pod - scc *api.SecurityContextConstraints - }{ - "pass user must run as SCC": { - pod: userPod, - scc: userSCC, - }, - "pass seLinux must run as SCC": { - pod: seLinuxPod, - scc: seLinuxSCC, - }, - "pass priv validating SCC": { - pod: privPod, - scc: privSCC, - }, - "pass caps validating SCC": { - pod: capsPod, - scc: capsSCC, - }, - "pass hostDir validating SCC": { - pod: hostDirPod, - scc: hostDirSCC, - }, - "pass hostNetwork validating SCC": { - pod: hostNetworkPod, - scc: hostNetworkSCC, - }, - "pass hostPort validating SCC": { - pod: hostPortPod, - scc: hostPortSCC, - }, - "pass hostPID validating SCC": { - pod: hostPIDPod, - scc: hostPIDSCC, - }, - "pass hostIPC validating SCC": { - pod: hostIPCPod, - scc: hostIPCSCC, - }, - } - - for k, v := range errorCases { - provider, err := NewSimpleProvider(v.scc) - if err != nil { - t.Fatal("unable to create provider %v", err) - } - errs := provider.ValidateSecurityContext(v.pod, &v.pod.Spec.Containers[0]) - if len(errs) != 0 { - t.Errorf("%s expected validation pass but received errors %v", k, errs) - continue - } - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas.go deleted file mode 100644 index dc22b4cabbb3..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas.go +++ /dev/null @@ -1,82 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 selinux - -import ( - "fmt" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util/fielderrors" -) - -type mustRunAs struct { - opts *api.SELinuxContextStrategyOptions -} - -var _ SELinuxSecurityContextConstraintsStrategy = &mustRunAs{} - -func NewMustRunAs(options *api.SELinuxContextStrategyOptions) (SELinuxSecurityContextConstraintsStrategy, error) { - if options == nil { - return nil, fmt.Errorf("MustRunAs requires SELinuxContextStrategyOptions") - } - if options.SELinuxOptions == nil { - return nil, fmt.Errorf("MustRunAs requires SELinuxOptions") - } - return &mustRunAs{ - opts: options, - }, nil -} - -// Generate creates the SELinuxOptions based on constraint rules. -func (s *mustRunAs) Generate(pod *api.Pod, container *api.Container) (*api.SELinuxOptions, error) { - return s.opts.SELinuxOptions, nil -} - -// Validate ensures that the specified values fall within the range of the strategy. -func (s *mustRunAs) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { - allErrs := fielderrors.ValidationErrorList{} - - if container.SecurityContext == nil { - detail := fmt.Sprintf("unable to validate nil security context for container %s", container.Name) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext", container.SecurityContext, detail)) - return allErrs - } - if container.SecurityContext.SELinuxOptions == nil { - detail := fmt.Sprintf("unable to validate nil seLinuxOptions for container %s", container.Name) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("seLinuxOptions", container.SecurityContext.SELinuxOptions, detail)) - return allErrs - } - seLinux := container.SecurityContext.SELinuxOptions - if seLinux.Level != s.opts.SELinuxOptions.Level { - detail := fmt.Sprintf("seLinuxOptions.level on container %s does not match required level. Found %s, wanted %s", container.Name, seLinux.Level, s.opts.SELinuxOptions.Level) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("seLinuxOptions.level", seLinux.Level, detail)) - } - if seLinux.Role != s.opts.SELinuxOptions.Role { - detail := fmt.Sprintf("seLinuxOptions.role on container %s does not match required role. Found %s, wanted %s", container.Name, seLinux.Role, s.opts.SELinuxOptions.Role) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("seLinuxOptions.role", seLinux.Role, detail)) - } - if seLinux.Type != s.opts.SELinuxOptions.Type { - detail := fmt.Sprintf("seLinuxOptions.type on container %s does not match required type. Found %s, wanted %s", container.Name, seLinux.Type, s.opts.SELinuxOptions.Type) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("seLinuxOptions.type", seLinux.Type, detail)) - } - if seLinux.User != s.opts.SELinuxOptions.User { - detail := fmt.Sprintf("seLinuxOptions.user on container %s does not match required user. Found %s, wanted %s", container.Name, seLinux.User, s.opts.SELinuxOptions.User) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("seLinuxOptions.user", seLinux.User, detail)) - } - - return allErrs -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas_test.go deleted file mode 100644 index 085cf6e9dd36..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas_test.go +++ /dev/null @@ -1,157 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 selinux - -import ( - "k8s.io/kubernetes/pkg/api" - "reflect" - "strings" - "testing" -) - -func TestMustRunAsOptions(t *testing.T) { - tests := map[string]struct { - opts *api.SELinuxContextStrategyOptions - pass bool - }{ - "invalid opts": { - opts: &api.SELinuxContextStrategyOptions{}, - pass: false, - }, - "valid opts": { - opts: &api.SELinuxContextStrategyOptions{SELinuxOptions: &api.SELinuxOptions{}}, - pass: true, - }, - } - for name, tc := range tests { - _, err := NewMustRunAs(tc.opts) - if err != nil && tc.pass { - t.Errorf("%s expected to pass but received error %#v", name, err) - } - if err == nil && !tc.pass { - t.Errorf("%s expected to fail but did not receive an error", name) - } - } -} - -func TestMustRunAsGenerate(t *testing.T) { - opts := &api.SELinuxContextStrategyOptions{ - SELinuxOptions: &api.SELinuxOptions{ - User: "user", - Role: "role", - Type: "type", - Level: "level", - }, - } - mustRunAs, err := NewMustRunAs(opts) - if err != nil { - t.Fatal("unexpected error initializing NewMustRunAs %v", err) - } - generated, err := mustRunAs.Generate(nil, nil) - if err != nil { - t.Fatal("unexpected error generating selinux %v", err) - } - if !reflect.DeepEqual(generated, opts.SELinuxOptions) { - t.Errorf("generated selinux does not equal configured selinux") - } -} - -func TestMustRunAsValidate(t *testing.T) { - newValidOpts := func() *api.SELinuxOptions { - return &api.SELinuxOptions{ - User: "user", - Role: "role", - Level: "level", - Type: "type", - } - } - - role := newValidOpts() - role.Role = "invalid" - - user := newValidOpts() - user.User = "invalid" - - level := newValidOpts() - level.Level = "invalid" - - seType := newValidOpts() - seType.Type = "invalid" - - tests := map[string]struct { - seLinux *api.SELinuxOptions - expectedMsg string - }{ - "invalid role": { - seLinux: role, - expectedMsg: "does not match required role", - }, - "invalid user": { - seLinux: user, - expectedMsg: "does not match required user", - }, - "invalid level": { - seLinux: level, - expectedMsg: "does not match required level", - }, - "invalid type": { - seLinux: seType, - expectedMsg: "does not match required type", - }, - "valid": { - seLinux: newValidOpts(), - expectedMsg: "", - }, - } - - opts := &api.SELinuxContextStrategyOptions{ - SELinuxOptions: newValidOpts(), - } - - for name, tc := range tests { - mustRunAs, err := NewMustRunAs(opts) - if err != nil { - t.Errorf("unexpected error initializing NewMustRunAs for testcase %s: %#v", name, err) - continue - } - container := &api.Container{ - SecurityContext: &api.SecurityContext{ - SELinuxOptions: tc.seLinux, - }, - } - - errs := mustRunAs.Validate(nil, container) - //should've passed but didn't - if len(tc.expectedMsg) == 0 && len(errs) > 0 { - t.Errorf("%s expected no errors but received %v", name, errs) - } - //should've failed but didn't - if len(tc.expectedMsg) != 0 && len(errs) == 0 { - t.Errorf("%s expected error %s but received no errors", name, tc.expectedMsg) - } - //failed with additional messages - if len(tc.expectedMsg) != 0 && len(errs) > 1 { - t.Errorf("%s expected error %s but received multiple errors: %v", name, tc.expectedMsg, errs) - } - //check that we got the right message - if len(tc.expectedMsg) != 0 && len(errs) == 1 { - if !strings.Contains(errs[0].Error(), tc.expectedMsg) { - t.Errorf("%s expected error to contain %s but it did not: %v", name, tc.expectedMsg, errs) - } - } - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany.go deleted file mode 100644 index f2150af3f268..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 selinux - -import ( - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util/fielderrors" -) - -// runAsAny implements the SELinuxSecurityContextConstraintsStrategy interface. -type runAsAny struct{} - -var _ SELinuxSecurityContextConstraintsStrategy = &runAsAny{} - -// NewRunAsAny provides a strategy that will return the configured se linux context or nil. -func NewRunAsAny(options *api.SELinuxContextStrategyOptions) (SELinuxSecurityContextConstraintsStrategy, error) { - return &runAsAny{}, nil -} - -// Generate creates the SELinuxOptions based on constraint rules. -func (s *runAsAny) Generate(pod *api.Pod, container *api.Container) (*api.SELinuxOptions, error) { - return nil, nil -} - -// Validate ensures that the specified values fall within the range of the strategy. -func (s *runAsAny) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { - return fielderrors.ValidationErrorList{} -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany_test.go deleted file mode 100644 index 9fd50b67f7fb..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany_test.go +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 selinux - -import ( - "k8s.io/kubernetes/pkg/api" - "testing" -) - -func TestRunAsAnyOptions(t *testing.T) { - _, err := NewRunAsAny(nil) - if err != nil { - t.Fatalf("unexpected error initializing NewRunAsAny %v", err) - } - _, err = NewRunAsAny(&api.SELinuxContextStrategyOptions{}) - if err != nil { - t.Errorf("unexpected error initializing NewRunAsAny %v", err) - } -} - -func TestRunAsAnyGenerate(t *testing.T) { - s, err := NewRunAsAny(&api.SELinuxContextStrategyOptions{}) - if err != nil { - t.Fatalf("unexpected error initializing NewRunAsAny %v", err) - } - uid, err := s.Generate(nil, nil) - if uid != nil { - t.Errorf("expected nil uid but got %d", *uid) - } - if err != nil { - t.Errorf("unexpected error generating uid %v", err) - } -} - -func TestRunAsAnyValidate(t *testing.T) { - s, err := NewRunAsAny(&api.SELinuxContextStrategyOptions{ - SELinuxOptions: &api.SELinuxOptions{ - Level: "foo", - }, - }, - ) - if err != nil { - t.Fatalf("unexpected error initializing NewRunAsAny %v", err) - } - errs := s.Validate(nil, nil) - if len(errs) != 0 { - t.Errorf("unexpected errors validating with ") - } - s, err = NewRunAsAny(&api.SELinuxContextStrategyOptions{}) - if err != nil { - t.Fatalf("unexpected error initializing NewRunAsAny %v", err) - } - errs = s.Validate(nil, nil) - if len(errs) != 0 { - t.Errorf("unexpected errors validating with ") - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/types.go deleted file mode 100644 index 58f01981e3a2..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/types.go +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 selinux - -import ( - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util/fielderrors" -) - -// SELinuxSecurityContextConstraintsStrategy defines the interface for all SELinux constraint strategies. -type SELinuxSecurityContextConstraintsStrategy interface { - // Generate creates the SELinuxOptions based on constraint rules. - Generate(pod *api.Pod, container *api.Container) (*api.SELinuxOptions, error) - // Validate ensures that the specified values fall within the range of the strategy. - Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/types.go deleted file mode 100644 index 9e7b680aa945..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/types.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 securitycontextconstraints - -import ( - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util/fielderrors" -) - -// SecurityContextConstraintsProvider provides the implementation to generate a new security -// context based on constraints or validate an existing security context against constraints. -type SecurityContextConstraintsProvider interface { - // Create a SecurityContext based on the given constraints - CreateSecurityContext(pod *api.Pod, container *api.Container) (*api.SecurityContext, error) - // Ensure a container's SecurityContext is in compliance with the given constraints - ValidateSecurityContext(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList - // Get the name of the SCC that this provider was initialized with. - GetSCCName() string -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas.go deleted file mode 100644 index 47b7fa1a3ae2..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas.go +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 user - -import ( - "fmt" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util/fielderrors" -) - -// mustRunAs implements the RunAsUserSecurityContextConstraintsStrategy interface -type mustRunAs struct { - opts *api.RunAsUserStrategyOptions -} - -var _ RunAsUserSecurityContextConstraintsStrategy = &mustRunAs{} - -// NewMustRunAs provides a strategy that requires the container to run as a specific UID. -func NewMustRunAs(options *api.RunAsUserStrategyOptions) (RunAsUserSecurityContextConstraintsStrategy, error) { - if options == nil { - return nil, fmt.Errorf("MustRunAs requires run as user options") - } - if options.UID == nil { - return nil, fmt.Errorf("MustRunAs requires a UID") - } - return &mustRunAs{ - opts: options, - }, nil -} - -// Generate creates the uid based on policy rules. MustRunAs returns the UID it is initialized with. -func (s *mustRunAs) Generate(pod *api.Pod, container *api.Container) (*int64, error) { - return s.opts.UID, nil -} - -// Validate ensures that the specified values fall within the range of the strategy. -func (s *mustRunAs) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { - allErrs := fielderrors.ValidationErrorList{} - - if container.SecurityContext == nil { - detail := fmt.Sprintf("unable to validate nil security context for container %s", container.Name) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext", container.SecurityContext, detail)) - return allErrs - } - if container.SecurityContext.RunAsUser == nil { - detail := fmt.Sprintf("unable to validate nil runAsUser for container %s", container.Name) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext.runAsUser", container.SecurityContext.RunAsUser, detail)) - return allErrs - } - - if *s.opts.UID != *container.SecurityContext.RunAsUser { - detail := fmt.Sprintf("UID on container %s does not match required UID. Found %d, wanted %d", container.Name, *container.SecurityContext.RunAsUser, *s.opts.UID) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext.runAsUser", *container.SecurityContext.RunAsUser, detail)) - } - - return allErrs -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas_test.go deleted file mode 100644 index 26f53b7dd625..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas_test.go +++ /dev/null @@ -1,90 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 user - -import ( - "k8s.io/kubernetes/pkg/api" - "testing" -) - -func TestMustRunAsOptions(t *testing.T) { - var uid int64 = 1 - tests := map[string]struct { - opts *api.RunAsUserStrategyOptions - pass bool - }{ - "invalid opts": { - opts: &api.RunAsUserStrategyOptions{}, - pass: false, - }, - "valid opts": { - opts: &api.RunAsUserStrategyOptions{UID: &uid}, - pass: true, - }, - } - for name, tc := range tests { - _, err := NewMustRunAs(tc.opts) - if err != nil && tc.pass { - t.Errorf("%s expected to pass but received error %v", name, err) - } - if err == nil && !tc.pass { - t.Errorf("%s expected to fail but did not receive an error", name) - } - } -} - -func TestMustRunAsGenerate(t *testing.T) { - var uid int64 = 1 - opts := &api.RunAsUserStrategyOptions{UID: &uid} - mustRunAs, err := NewMustRunAs(opts) - if err != nil { - t.Fatal("unexpected error initializing NewMustRunAs %v", err) - } - generated, err := mustRunAs.Generate(nil, nil) - if err != nil { - t.Fatal("unexpected error generating uid %v", err) - } - if *generated != uid { - t.Errorf("generated uid does not equal configured uid") - } -} - -func TestMustRunAsValidate(t *testing.T) { - var uid int64 = 1 - var badUID int64 = 2 - opts := &api.RunAsUserStrategyOptions{UID: &uid} - mustRunAs, err := NewMustRunAs(opts) - if err != nil { - t.Fatal("unexpected error initializing NewMustRunAs %v", err) - } - container := &api.Container{ - SecurityContext: &api.SecurityContext{ - RunAsUser: &badUID, - }, - } - - errs := mustRunAs.Validate(nil, container) - if len(errs) == 0 { - t.Errorf("expected errors from mismatch uid but got none") - } - - container.SecurityContext.RunAsUser = &uid - errs = mustRunAs.Validate(nil, container) - if len(errs) != 0 { - t.Errorf("expected no errors from matching uid but got %v", errs) - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunasrange.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunasrange.go deleted file mode 100644 index ef65bd9d217e..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunasrange.go +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 user - -import ( - "fmt" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util/fielderrors" -) - -// mustRunAs implements the RunAsUserSecurityContextConstraintsStrategy interface -type mustRunAsRange struct { - opts *api.RunAsUserStrategyOptions -} - -// NewMustRunAs provides a strategy that requires the container to run as a specific UID in a range. -func NewMustRunAsRange(options *api.RunAsUserStrategyOptions) (RunAsUserSecurityContextConstraintsStrategy, error) { - if options == nil { - return nil, fmt.Errorf("MustRunAsRange requires run as user options") - } - if options.UIDRangeMin == nil { - return nil, fmt.Errorf("MustRunAsRange requires a UIDRangeMin") - } - if options.UIDRangeMax == nil { - return nil, fmt.Errorf("MustRunAsRange requires a UIDRangeMax") - } - return &mustRunAsRange{ - opts: options, - }, nil -} - -// Generate creates the uid based on policy rules. MustRunAs returns the UIDRangeMin it is initialized with. -func (s *mustRunAsRange) Generate(pod *api.Pod, container *api.Container) (*int64, error) { - return s.opts.UIDRangeMin, nil -} - -// Validate ensures that the specified values fall within the range of the strategy. -func (s *mustRunAsRange) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { - allErrs := fielderrors.ValidationErrorList{} - - if container.SecurityContext == nil { - detail := fmt.Sprintf("unable to validate nil security context for container %s", container.Name) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext", container.SecurityContext, detail)) - return allErrs - } - if container.SecurityContext.RunAsUser == nil { - detail := fmt.Sprintf("unable to validate nil RunAsUser for container %s", container.Name) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext.runAsUser", container.SecurityContext.RunAsUser, detail)) - return allErrs - } - - if *container.SecurityContext.RunAsUser < *s.opts.UIDRangeMin || *container.SecurityContext.RunAsUser > *s.opts.UIDRangeMax { - detail := fmt.Sprintf("UID on container %s does not match required range. Found %d, required min: %d max: %d", - container.Name, - *container.SecurityContext.RunAsUser, - *s.opts.UIDRangeMin, - *s.opts.UIDRangeMax) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext.runAsUser", *container.SecurityContext.RunAsUser, detail)) - } - - return allErrs -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot.go deleted file mode 100644 index 7d551f4a7d87..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 user - -import ( - "fmt" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util/fielderrors" -) - -type nonRoot struct{} - -var _ RunAsUserSecurityContextConstraintsStrategy = &nonRoot{} - -func NewRunAsNonRoot(options *api.RunAsUserStrategyOptions) (RunAsUserSecurityContextConstraintsStrategy, error) { - return &nonRoot{}, nil -} - -// Generate creates the uid based on policy rules. This strategy does return a UID. It assumes -// that the user will specify a UID or the container image specifies a UID. -func (s *nonRoot) Generate(pod *api.Pod, container *api.Container) (*int64, error) { - return nil, nil -} - -// Validate ensures that the specified values fall within the range of the strategy. Validation -// of this will pass if either the UID is not set, assuming that the image will provided the UID -// or if the UID is set it is not root. In order to work properly this assumes that the kubelet -// will populate an -func (s *nonRoot) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { - allErrs := fielderrors.ValidationErrorList{} - if container.SecurityContext == nil { - detail := fmt.Sprintf("unable to validate nil security context for container %s", container.Name) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext", container.SecurityContext, detail)) - return allErrs - } - if container.SecurityContext.RunAsUser != nil && *container.SecurityContext.RunAsUser == 0 { - detail := fmt.Sprintf("running with the root UID is forbidden by the security context constraints %s", container.Name) - allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext.runAsUser", *container.SecurityContext.RunAsUser, detail)) - return allErrs - } - return allErrs -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot_test.go deleted file mode 100644 index 4ca637dccc44..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot_test.go +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 user - -import ( - "k8s.io/kubernetes/pkg/api" - "testing" -) - -func TestNonRootOptions(t *testing.T) { - _, err := NewRunAsNonRoot(nil) - if err != nil { - t.Fatalf("unexpected error initializing NewRunAsNonRoot %v", err) - } - _, err = NewRunAsNonRoot(&api.RunAsUserStrategyOptions{}) - if err != nil { - t.Errorf("unexpected error initializing NewRunAsNonRoot %v", err) - } -} - -func TestNonRootGenerate(t *testing.T) { - s, err := NewRunAsNonRoot(&api.RunAsUserStrategyOptions{}) - if err != nil { - t.Fatalf("unexpected error initializing NewRunAsNonRoot %v", err) - } - uid, err := s.Generate(nil, nil) - if uid != nil { - t.Errorf("expected nil uid but got %d", *uid) - } - if err != nil { - t.Errorf("unexpected error generating uid %v", err) - } -} - -func TestNonRootValidate(t *testing.T) { - var uid int64 = 1 - var badUID int64 = 0 - s, err := NewRunAsNonRoot(&api.RunAsUserStrategyOptions{}) - if err != nil { - t.Fatal("unexpected error initializing NewMustRunAs %v", err) - } - container := &api.Container{ - SecurityContext: &api.SecurityContext{ - RunAsUser: &badUID, - }, - } - - errs := s.Validate(nil, container) - if len(errs) == 0 { - t.Errorf("expected errors from root uid but got none") - } - - container.SecurityContext.RunAsUser = &uid - errs = s.Validate(nil, container) - if len(errs) != 0 { - t.Errorf("expected no errors from non-root uid but got %v", errs) - } - - container.SecurityContext.RunAsUser = nil - errs = s.Validate(nil, container) - if len(errs) != 0 { - t.Errorf("expected no errors from nil uid but got %v", errs) - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany.go deleted file mode 100644 index 22b6916907be..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 user - -import ( - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util/fielderrors" -) - -// runAsAny implements the interface RunAsUserSecurityContextConstraintsStrategy. -type runAsAny struct{} - -var _ RunAsUserSecurityContextConstraintsStrategy = &runAsAny{} - -// NewRunAsAny provides a strategy that will return nil. -func NewRunAsAny(options *api.RunAsUserStrategyOptions) (RunAsUserSecurityContextConstraintsStrategy, error) { - return &runAsAny{}, nil -} - -// Generate creates the uid based on policy rules. -func (s *runAsAny) Generate(pod *api.Pod, container *api.Container) (*int64, error) { - return nil, nil -} - -// Validate ensures that the specified values fall within the range of the strategy. -func (s *runAsAny) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { - return fielderrors.ValidationErrorList{} -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany_test.go deleted file mode 100644 index b13ae29fc238..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany_test.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 user - -import ( - "k8s.io/kubernetes/pkg/api" - "testing" -) - -func TestRunAsAnyOptions(t *testing.T) { - _, err := NewRunAsAny(nil) - if err != nil { - t.Fatalf("unexpected error initializing NewRunAsAny %v", err) - } - _, err = NewRunAsAny(&api.RunAsUserStrategyOptions{}) - if err != nil { - t.Errorf("unexpected error initializing NewRunAsAny %v", err) - } -} - -func TestRunAsAnyGenerate(t *testing.T) { - s, err := NewRunAsAny(&api.RunAsUserStrategyOptions{}) - if err != nil { - t.Fatalf("unexpected error initializing NewRunAsAny %v", err) - } - uid, err := s.Generate(nil, nil) - if uid != nil { - t.Errorf("expected nil uid but got %d", *uid) - } - if err != nil { - t.Errorf("unexpected error generating uid %v", err) - } -} - -func TestRunAsAnyValidate(t *testing.T) { - s, err := NewRunAsAny(&api.RunAsUserStrategyOptions{}) - if err != nil { - t.Fatalf("unexpected error initializing NewRunAsAny %v", err) - } - errs := s.Validate(nil, nil) - if len(errs) != 0 { - t.Errorf("unexpected errors validating with ") - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/types.go deleted file mode 100644 index 9050d575e2e4..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/types.go +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 user - -import ( - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util/fielderrors" -) - -// RunAsUserSecurityContextConstraintsStrategy defines the interface for all uid constraint strategies. -type RunAsUserSecurityContextConstraintsStrategy interface { - // Generate creates the uid based on policy rules. - Generate(pod *api.Pod, container *api.Container) (*int64, error) - // Validate ensures that the specified values fall within the range of the strategy. - Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/util.go deleted file mode 100644 index e723b9d8e71d..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/util.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 user - -import ( - "fmt" - "strconv" - - "k8s.io/kubernetes/pkg/api" - client "k8s.io/kubernetes/pkg/client/unversioned" -) - -func AnnotationToIntPtr(sUID string) (*int64, error) { - uid, err := strconv.ParseInt(sUID, 10, 64) - if err != nil { - return nil, err - } - return &uid, nil -} - -func GetAllocatedID(kClient client.Interface, pod *api.Pod, annotation string) (*int64, error) { - if len(pod.Spec.ServiceAccountName) > 0 { - sa, err := kClient.ServiceAccounts(pod.Namespace).Get(pod.Spec.ServiceAccountName) - if err != nil { - return nil, err - } - sUID, ok := sa.Annotations[annotation] - if !ok { - return nil, fmt.Errorf("Unable to find annotation %s on service account %s", annotation, pod.Spec.ServiceAccountName) - } - return AnnotationToIntPtr(sUID) - } else { - ns, err := kClient.Namespaces().Get(pod.Namespace) - if err != nil { - return nil, err - } - sUID, ok := ns.Annotations[annotation] - if !ok { - return nil, fmt.Errorf("Unable to find annotation %s on namespace %s", annotation, pod.Namespace) - } - return AnnotationToIntPtr(sUID) - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/cacher.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/cacher.go index 730571d7dbaf..7fd1c68c0719 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/cacher.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/cacher.go @@ -31,6 +31,7 @@ import ( "k8s.io/kubernetes/pkg/watch" "github.com/golang/glog" + "golang.org/x/net/context" ) // CacherConfig contains the configuration for a given Cache. @@ -152,8 +153,8 @@ func (c *Cacher) startCaching(stopChannel <-chan struct{}) { } // Implements storage.Interface. -func (c *Cacher) Backends() []string { - return c.storage.Backends() +func (c *Cacher) Backends(ctx context.Context) []string { + return c.storage.Backends(ctx) } // Implements storage.Interface. @@ -162,22 +163,22 @@ func (c *Cacher) Versioner() Versioner { } // Implements storage.Interface. -func (c *Cacher) Create(key string, obj, out runtime.Object, ttl uint64) error { - return c.storage.Create(key, obj, out, ttl) +func (c *Cacher) Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error { + return c.storage.Create(ctx, key, obj, out, ttl) } // Implements storage.Interface. -func (c *Cacher) Set(key string, obj, out runtime.Object, ttl uint64) error { - return c.storage.Set(key, obj, out, ttl) +func (c *Cacher) Set(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error { + return c.storage.Set(ctx, key, obj, out, ttl) } // Implements storage.Interface. -func (c *Cacher) Delete(key string, out runtime.Object) error { - return c.storage.Delete(key, out) +func (c *Cacher) Delete(ctx context.Context, key string, out runtime.Object) error { + return c.storage.Delete(ctx, key, out) } // Implements storage.Interface. -func (c *Cacher) Watch(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) { +func (c *Cacher) Watch(ctx context.Context, key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) { // Do NOT allow Watch to start when the underlying structures are not propagated. c.usable.RLock() defer c.usable.RUnlock() @@ -203,23 +204,23 @@ func (c *Cacher) Watch(key string, resourceVersion uint64, filter FilterFunc) (w } // Implements storage.Interface. -func (c *Cacher) WatchList(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) { - return c.Watch(key, resourceVersion, filter) +func (c *Cacher) WatchList(ctx context.Context, key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) { + return c.Watch(ctx, key, resourceVersion, filter) } // Implements storage.Interface. -func (c *Cacher) Get(key string, objPtr runtime.Object, ignoreNotFound bool) error { - return c.storage.Get(key, objPtr, ignoreNotFound) +func (c *Cacher) Get(ctx context.Context, key string, objPtr runtime.Object, ignoreNotFound bool) error { + return c.storage.Get(ctx, key, objPtr, ignoreNotFound) } // Implements storage.Interface. -func (c *Cacher) GetToList(key string, listObj runtime.Object) error { - return c.storage.GetToList(key, listObj) +func (c *Cacher) GetToList(ctx context.Context, key string, filter FilterFunc, listObj runtime.Object) error { + return c.storage.GetToList(ctx, key, filter, listObj) } // Implements storage.Interface. -func (c *Cacher) List(key string, listObj runtime.Object) error { - return c.storage.List(key, listObj) +func (c *Cacher) List(ctx context.Context, key string, filter FilterFunc, listObj runtime.Object) error { + return c.storage.List(ctx, key, filter, listObj) } // ListFromMemory implements list operation (the same signature as List method) @@ -263,8 +264,8 @@ func (c *Cacher) ListFromMemory(key string, listObj runtime.Object) error { } // Implements storage.Interface. -func (c *Cacher) GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate UpdateFunc) error { - return c.storage.GuaranteedUpdate(key, ptrToType, ignoreNotFound, tryUpdate) +func (c *Cacher) GuaranteedUpdate(ctx context.Context, key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate UpdateFunc) error { + return c.storage.GuaranteedUpdate(ctx, key, ptrToType, ignoreNotFound, tryUpdate) } // Implements storage.Interface. @@ -303,7 +304,7 @@ func filterFunction(key string, keyFunc func(runtime.Object) (string, error), fi return func(obj runtime.Object) bool { objKey, err := keyFunc(obj) if err != nil { - glog.Errorf("Invalid object for filter: %v", obj) + glog.Errorf("invalid object for filter: %v", obj) return false } if !strings.HasPrefix(objKey, key) { @@ -343,7 +344,7 @@ func newCacherListerWatcher(storage Interface, resourcePrefix string, newListFun // Implements cache.ListerWatcher interface. func (lw *cacherListerWatcher) List() (runtime.Object, error) { list := lw.newListFunc() - if err := lw.storage.List(lw.resourcePrefix, list); err != nil { + if err := lw.storage.List(context.TODO(), lw.resourcePrefix, Everything, list); err != nil { return nil, err } return list, nil @@ -355,7 +356,7 @@ func (lw *cacherListerWatcher) Watch(resourceVersion string) (watch.Interface, e if err != nil { return nil, err } - return lw.storage.WatchList(lw.resourcePrefix, version, Everything) + return lw.storage.WatchList(context.TODO(), lw.resourcePrefix, version, Everything) } // cacherWatch implements watch.Interface diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/cacher_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/cacher_test.go index 57d6a01d8bf9..6e8bdc82ad86 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/cacher_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/cacher_test.go @@ -27,6 +27,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/testapi" + apitesting "k8s.io/kubernetes/pkg/api/testing" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" @@ -37,6 +39,8 @@ import ( "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/watch" + + "golang.org/x/net/context" ) func newTestCacher(client tools.EtcdClient) *storage.Cacher { @@ -55,14 +59,9 @@ func newTestCacher(client tools.EtcdClient) *storage.Cacher { } func makeTestPod(name string) *api.Pod { - gracePeriod := int64(30) return &api.Pod{ ObjectMeta: api.ObjectMeta{Namespace: "ns", Name: name}, - Spec: api.PodSpec{ - TerminationGracePeriodSeconds: &gracePeriod, - DNSPolicy: api.DNSClusterFirst, - RestartPolicy: api.RestartPolicyAlways, - }, + Spec: apitesting.DeepEqualSafePodSpec(), } } @@ -74,7 +73,7 @@ func waitForUpToDateCache(cacher *storage.Cacher, resourceVersion uint64) error } return result == resourceVersion, nil } - return wait.Poll(10*time.Millisecond, 100*time.Millisecond, ready) + return wait.Poll(10*time.Millisecond, util.ForeverTestTimeout, ready) } func TestListFromMemory(t *testing.T) { @@ -171,7 +170,7 @@ func TestListFromMemory(t *testing.T) { for _, item := range result.Items { // unset fields that are set by the infrastructure item.ObjectMeta.ResourceVersion = "" - item.ObjectMeta.CreationTimestamp = util.Time{} + item.ObjectMeta.CreationTimestamp = unversioned.Time{} var expected *api.Pod switch item.ObjectMeta.Name { @@ -253,7 +252,7 @@ func TestWatch(t *testing.T) { } // Set up Watch for object "podFoo". - watcher, err := cacher.Watch("pods/ns/foo", 2, storage.Everything) + watcher, err := cacher.Watch(context.TODO(), "pods/ns/foo", 2, storage.Everything) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -268,7 +267,7 @@ func TestWatch(t *testing.T) { // unset fields that are set by the infrastructure obj := event.Object.(*api.Pod) obj.ObjectMeta.ResourceVersion = "" - obj.ObjectMeta.CreationTimestamp = util.Time{} + obj.ObjectMeta.CreationTimestamp = unversioned.Time{} if e, a := test.object, obj; !reflect.DeepEqual(e, a) { t.Errorf("expected: %#v, got: %#v", e, a) } @@ -276,13 +275,13 @@ func TestWatch(t *testing.T) { } // Check whether we get too-old error. - _, err = cacher.Watch("pods/ns/foo", 1, storage.Everything) + _, err = cacher.Watch(context.TODO(), "pods/ns/foo", 1, storage.Everything) if err == nil { t.Errorf("exepcted 'error too old' error") } // Now test watch with initial state. - initialWatcher, err := cacher.Watch("pods/ns/foo", 2, storage.Everything) + initialWatcher, err := cacher.Watch(context.TODO(), "pods/ns/foo", 2, storage.Everything) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -295,7 +294,7 @@ func TestWatch(t *testing.T) { // unset fields that are set by the infrastructure obj := event.Object.(*api.Pod) obj.ObjectMeta.ResourceVersion = "" - obj.ObjectMeta.CreationTimestamp = util.Time{} + obj.ObjectMeta.CreationTimestamp = unversioned.Time{} if e, a := test.object, obj; !reflect.DeepEqual(e, a) { t.Errorf("expected: %#v, got: %#v", e, a) } @@ -303,7 +302,7 @@ func TestWatch(t *testing.T) { } // Now test watch from "now". - nowWatcher, err := cacher.Watch("pods/ns/foo", 0, storage.Everything) + nowWatcher, err := cacher.Watch(context.TODO(), "pods/ns/foo", 0, storage.Everything) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -312,7 +311,7 @@ func TestWatch(t *testing.T) { if obj := event.Object.(*api.Pod); event.Type != watch.Added || obj.ResourceVersion != "4" { t.Errorf("unexpected event: %v", event) } - case <-time.After(time.Millisecond * 100): + case <-time.After(util.ForeverTestTimeout): t.Errorf("timed out waiting for an event") } // Emit a new event and check if it is observed by the watcher. @@ -453,7 +452,7 @@ func TestFiltering(t *testing.T) { } return selector.Matches(labels.Set(metadata.Labels())) } - watcher, err := cacher.Watch("pods/ns/foo", 1, filter) + watcher, err := cacher.Watch(context.TODO(), "pods/ns/foo", 1, filter) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -468,7 +467,7 @@ func TestFiltering(t *testing.T) { // unset fields that are set by the infrastructure obj := event.Object.(*api.Pod) obj.ObjectMeta.ResourceVersion = "" - obj.ObjectMeta.CreationTimestamp = util.Time{} + obj.ObjectMeta.CreationTimestamp = unversioned.Time{} if e, a := test.object, obj; !reflect.DeepEqual(e, a) { t.Errorf("expected: %#v, got: %#v", e, a) } @@ -488,7 +487,7 @@ func TestStorageError(t *testing.T) { podFoo := makeTestPod("foo") // Set up Watch for object "podFoo". - watcher, err := cacher.Watch("pods/ns/foo", 1, storage.Everything) + watcher, err := cacher.Watch(context.TODO(), "pods/ns/foo", 1, storage.Everything) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/api_object_versioner.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/api_object_versioner.go index fe1eeb001953..41875fc55871 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/api_object_versioner.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/api_object_versioner.go @@ -21,9 +21,9 @@ import ( "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" - "k8s.io/kubernetes/pkg/util" ) // APIObjectVersioner implements versioning and extracting etcd node information @@ -37,7 +37,7 @@ func (a APIObjectVersioner) UpdateObject(obj runtime.Object, expiration *time.Ti return err } if expiration != nil { - objectMeta.DeletionTimestamp = &util.Time{Time: *expiration} + objectMeta.DeletionTimestamp = &unversioned.Time{Time: *expiration} } versionString := "" if resourceVersion != 0 { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/api_object_versioner_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/api_object_versioner_test.go index ff933d93aca0..1b7ff05c8489 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/api_object_versioner_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/api_object_versioner_test.go @@ -21,26 +21,27 @@ import ( "time" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" + storagetesting "k8s.io/kubernetes/pkg/storage/testing" ) func TestObjectVersioner(t *testing.T) { v := APIObjectVersioner{} - if ver, err := v.ObjectResourceVersion(&TestResource{ObjectMeta: api.ObjectMeta{ResourceVersion: "5"}}); err != nil || ver != 5 { + if ver, err := v.ObjectResourceVersion(&storagetesting.TestResource{ObjectMeta: api.ObjectMeta{ResourceVersion: "5"}}); err != nil || ver != 5 { t.Errorf("unexpected version: %d %v", ver, err) } - if ver, err := v.ObjectResourceVersion(&TestResource{ObjectMeta: api.ObjectMeta{ResourceVersion: "a"}}); err == nil || ver != 0 { + if ver, err := v.ObjectResourceVersion(&storagetesting.TestResource{ObjectMeta: api.ObjectMeta{ResourceVersion: "a"}}); err == nil || ver != 0 { t.Errorf("unexpected version: %d %v", ver, err) } - obj := &TestResource{ObjectMeta: api.ObjectMeta{ResourceVersion: "a"}} + obj := &storagetesting.TestResource{ObjectMeta: api.ObjectMeta{ResourceVersion: "a"}} if err := v.UpdateObject(obj, nil, 5); err != nil { t.Fatalf("unexpected error: %v", err) } if obj.ResourceVersion != "5" || obj.DeletionTimestamp != nil { t.Errorf("unexpected resource version: %#v", obj) } - now := util.Time{Time: time.Now()} - obj = &TestResource{ObjectMeta: api.ObjectMeta{ResourceVersion: "a"}} + now := unversioned.Time{Time: time.Now()} + obj = &storagetesting.TestResource{ObjectMeta: api.ObjectMeta{ResourceVersion: "a"}} if err := v.UpdateObject(obj, &now.Time, 5); err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper.go index f4a07472355a..2767e47e84b9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper.go @@ -35,6 +35,7 @@ import ( "k8s.io/kubernetes/pkg/watch" "github.com/golang/glog" + "golang.org/x/net/context" ) func NewEtcdStorage(client tools.EtcdClient, codec runtime.Codec, prefix string) storage.Interface { @@ -78,7 +79,10 @@ func (h *etcdHelper) Codec() runtime.Codec { } // Implements storage.Interface. -func (h *etcdHelper) Backends() []string { +func (h *etcdHelper) Backends(ctx context.Context) []string { + if ctx == nil { + glog.Errorf("Context is nil") + } return h.client.GetCluster() } @@ -88,7 +92,10 @@ func (h *etcdHelper) Versioner() storage.Versioner { } // Implements storage.Interface. -func (h *etcdHelper) Create(key string, obj, out runtime.Object, ttl uint64) error { +func (h *etcdHelper) Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error { + if ctx == nil { + glog.Errorf("Context is nil") + } key = h.prefixEtcdKey(key) data, err := h.codec.Encode(obj) if err != nil { @@ -116,7 +123,10 @@ func (h *etcdHelper) Create(key string, obj, out runtime.Object, ttl uint64) err } // Implements storage.Interface. -func (h *etcdHelper) Set(key string, obj, out runtime.Object, ttl uint64) error { +func (h *etcdHelper) Set(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error { + if ctx == nil { + glog.Errorf("Context is nil") + } var response *etcd.Response data, err := h.codec.Encode(obj) if err != nil { @@ -157,7 +167,10 @@ func (h *etcdHelper) Set(key string, obj, out runtime.Object, ttl uint64) error } // Implements storage.Interface. -func (h *etcdHelper) Delete(key string, out runtime.Object) error { +func (h *etcdHelper) Delete(ctx context.Context, key string, out runtime.Object) error { + if ctx == nil { + glog.Errorf("Context is nil") + } key = h.prefixEtcdKey(key) if _, err := conversion.EnforcePtr(out); err != nil { panic("unable to convert output object to pointer") @@ -176,7 +189,10 @@ func (h *etcdHelper) Delete(key string, out runtime.Object) error { } // Implements storage.Interface. -func (h *etcdHelper) Watch(key string, resourceVersion uint64, filter storage.FilterFunc) (watch.Interface, error) { +func (h *etcdHelper) Watch(ctx context.Context, key string, resourceVersion uint64, filter storage.FilterFunc) (watch.Interface, error) { + if ctx == nil { + glog.Errorf("Context is nil") + } key = h.prefixEtcdKey(key) w := newEtcdWatcher(false, nil, filter, h.codec, h.versioner, nil, h) go w.etcdWatch(h.client, key, resourceVersion) @@ -184,7 +200,10 @@ func (h *etcdHelper) Watch(key string, resourceVersion uint64, filter storage.Fi } // Implements storage.Interface. -func (h *etcdHelper) WatchList(key string, resourceVersion uint64, filter storage.FilterFunc) (watch.Interface, error) { +func (h *etcdHelper) WatchList(ctx context.Context, key string, resourceVersion uint64, filter storage.FilterFunc) (watch.Interface, error) { + if ctx == nil { + glog.Errorf("Context is nil") + } key = h.prefixEtcdKey(key) w := newEtcdWatcher(true, exceptKey(key), filter, h.codec, h.versioner, nil, h) go w.etcdWatch(h.client, key, resourceVersion) @@ -192,15 +211,21 @@ func (h *etcdHelper) WatchList(key string, resourceVersion uint64, filter storag } // Implements storage.Interface. -func (h *etcdHelper) Get(key string, objPtr runtime.Object, ignoreNotFound bool) error { +func (h *etcdHelper) Get(ctx context.Context, key string, objPtr runtime.Object, ignoreNotFound bool) error { + if ctx == nil { + glog.Errorf("Context is nil") + } key = h.prefixEtcdKey(key) - _, _, _, err := h.bodyAndExtractObj(key, objPtr, ignoreNotFound) + _, _, _, err := h.bodyAndExtractObj(ctx, key, objPtr, ignoreNotFound) return err } // bodyAndExtractObj performs the normal Get path to etcd, returning the parsed node and response for additional information // about the response, like the current etcd index and the ttl. -func (h *etcdHelper) bodyAndExtractObj(key string, objPtr runtime.Object, ignoreNotFound bool) (body string, node *etcd.Node, res *etcd.Response, err error) { +func (h *etcdHelper) bodyAndExtractObj(ctx context.Context, key string, objPtr runtime.Object, ignoreNotFound bool) (body string, node *etcd.Node, res *etcd.Response, err error) { + if ctx == nil { + glog.Errorf("Context is nil") + } startTime := time.Now() response, err := h.client.Get(key, false, false) metrics.RecordEtcdRequestLatency("get", getTypeName(objPtr), startTime) @@ -243,7 +268,10 @@ func (h *etcdHelper) extractObj(response *etcd.Response, inErr error, objPtr run } // Implements storage.Interface. -func (h *etcdHelper) GetToList(key string, listObj runtime.Object) error { +func (h *etcdHelper) GetToList(ctx context.Context, key string, filter storage.FilterFunc, listObj runtime.Object) error { + if ctx == nil { + glog.Errorf("Context is nil") + } trace := util.NewTrace("GetToList " + getTypeName(listObj)) listPtr, err := runtime.GetItemsPtr(listObj) if err != nil { @@ -265,7 +293,7 @@ func (h *etcdHelper) GetToList(key string, listObj runtime.Object) error { nodes := make([]*etcd.Node, 0) nodes = append(nodes, response.Node) - if err := h.decodeNodeList(nodes, listPtr); err != nil { + if err := h.decodeNodeList(nodes, filter, listPtr); err != nil { return err } trace.Step("Object decoded") @@ -278,7 +306,7 @@ func (h *etcdHelper) GetToList(key string, listObj runtime.Object) error { } // decodeNodeList walks the tree of each node in the list and decodes into the specified object -func (h *etcdHelper) decodeNodeList(nodes []*etcd.Node, slicePtr interface{}) error { +func (h *etcdHelper) decodeNodeList(nodes []*etcd.Node, filter storage.FilterFunc, slicePtr interface{}) error { trace := util.NewTrace("decodeNodeList " + getTypeName(slicePtr)) defer trace.LogIfLong(500 * time.Millisecond) v, err := conversion.EnforcePtr(slicePtr) @@ -289,14 +317,17 @@ func (h *etcdHelper) decodeNodeList(nodes []*etcd.Node, slicePtr interface{}) er for _, node := range nodes { if node.Dir { trace.Step("Decoding dir " + node.Key + " START") - if err := h.decodeNodeList(node.Nodes, slicePtr); err != nil { + if err := h.decodeNodeList(node.Nodes, filter, slicePtr); err != nil { return err } trace.Step("Decoding dir " + node.Key + " END") continue } - if obj, found := h.getFromCache(node.ModifiedIndex); found { - v.Set(reflect.Append(v, reflect.ValueOf(obj).Elem())) + if obj, found := h.getFromCache(node.ModifiedIndex, filter); found { + // obj != nil iff it matches the filter function. + if obj != nil { + v.Set(reflect.Append(v, reflect.ValueOf(obj).Elem())) + } } else { obj := reflect.New(v.Type().Elem()) if err := h.codec.DecodeInto([]byte(node.Value), obj.Interface().(runtime.Object)); err != nil { @@ -306,7 +337,9 @@ func (h *etcdHelper) decodeNodeList(nodes []*etcd.Node, slicePtr interface{}) er // being unable to set the version does not prevent the object from being extracted _ = h.versioner.UpdateObject(obj.Interface().(runtime.Object), node.Expiration, node.ModifiedIndex) } - v.Set(reflect.Append(v, obj.Elem())) + if filter(obj.Interface().(runtime.Object)) { + v.Set(reflect.Append(v, obj.Elem())) + } if node.ModifiedIndex != 0 { h.addToCache(node.ModifiedIndex, obj.Interface().(runtime.Object)) } @@ -317,7 +350,10 @@ func (h *etcdHelper) decodeNodeList(nodes []*etcd.Node, slicePtr interface{}) er } // Implements storage.Interface. -func (h *etcdHelper) List(key string, listObj runtime.Object) error { +func (h *etcdHelper) List(ctx context.Context, key string, filter storage.FilterFunc, listObj runtime.Object) error { + if ctx == nil { + glog.Errorf("Context is nil") + } trace := util.NewTrace("List " + getTypeName(listObj)) defer trace.LogIfLong(time.Second) listPtr, err := runtime.GetItemsPtr(listObj) @@ -327,13 +363,13 @@ func (h *etcdHelper) List(key string, listObj runtime.Object) error { key = h.prefixEtcdKey(key) startTime := time.Now() trace.Step("About to list etcd node") - nodes, index, err := h.listEtcdNode(key) + nodes, index, err := h.listEtcdNode(ctx, key) metrics.RecordEtcdRequestLatency("list", getTypeName(listPtr), startTime) trace.Step("Etcd node listed") if err != nil { return err } - if err := h.decodeNodeList(nodes, listPtr); err != nil { + if err := h.decodeNodeList(nodes, filter, listPtr); err != nil { return err } trace.Step("Node list decoded") @@ -345,7 +381,10 @@ func (h *etcdHelper) List(key string, listObj runtime.Object) error { return nil } -func (h *etcdHelper) listEtcdNode(key string) ([]*etcd.Node, uint64, error) { +func (h *etcdHelper) listEtcdNode(ctx context.Context, key string) ([]*etcd.Node, uint64, error) { + if ctx == nil { + glog.Errorf("Context is nil") + } result, err := h.client.Get(key, true, true) if err != nil { index, ok := etcdErrorIndex(err) @@ -363,7 +402,10 @@ func (h *etcdHelper) listEtcdNode(key string) ([]*etcd.Node, uint64, error) { } // Implements storage.Interface. -func (h *etcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate storage.UpdateFunc) error { +func (h *etcdHelper) GuaranteedUpdate(ctx context.Context, key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate storage.UpdateFunc) error { + if ctx == nil { + glog.Errorf("Context is nil") + } v, err := conversion.EnforcePtr(ptrToType) if err != nil { // Panic is appropriate, because this is a programming error. @@ -372,7 +414,7 @@ func (h *etcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno key = h.prefixEtcdKey(key) for { obj := reflect.New(v.Type()).Interface().(runtime.Object) - origBody, node, res, err := h.bodyAndExtractObj(key, obj, ignoreNotFound) + origBody, node, res, err := h.bodyAndExtractObj(ctx, key, obj, ignoreNotFound) if err != nil { return err } @@ -457,7 +499,7 @@ func (h *etcdHelper) prefixEtcdKey(key string) string { // their Node.ModifiedIndex, which is unique across all types. // All implementations must be thread-safe. type etcdCache interface { - getFromCache(index uint64) (runtime.Object, bool) + getFromCache(index uint64, filter storage.FilterFunc) (runtime.Object, bool) addToCache(index uint64, obj runtime.Object) } @@ -467,18 +509,22 @@ func getTypeName(obj interface{}) string { return reflect.TypeOf(obj).String() } -func (h *etcdHelper) getFromCache(index uint64) (runtime.Object, bool) { +func (h *etcdHelper) getFromCache(index uint64, filter storage.FilterFunc) (runtime.Object, bool) { startTime := time.Now() defer func() { metrics.ObserveGetCache(startTime) }() obj, found := h.cache.Get(index) if found { + if !filter(obj.(runtime.Object)) { + return nil, true + } // We should not return the object itself to avoid polluting the cache if someone // modifies returned values. objCopy, err := h.copier.Copy(obj.(runtime.Object)) if err != nil { glog.Errorf("Error during DeepCopy of cached object: %q", err) + // We can't return a copy, thus we report the object as not found. return nil, false } metrics.ObserveCacheHit() diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper_test.go index 99820304b98b..9df12c1de36f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper_test.go @@ -32,35 +32,31 @@ import ( "github.com/coreos/go-etcd/etcd" "github.com/stretchr/testify/assert" + "golang.org/x/net/context" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + apitesting "k8s.io/kubernetes/pkg/api/testing" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" + storagetesting "k8s.io/kubernetes/pkg/storage/testing" "k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools/etcdtest" ) const validEtcdVersion = "etcd 2.0.9" -type TestResource struct { - api.TypeMeta `json:",inline"` - api.ObjectMeta `json:"metadata"` - Value int `json:"value"` -} - -func (*TestResource) IsAnAPIObject() {} - var scheme *runtime.Scheme var codec runtime.Codec func init() { scheme = runtime.NewScheme() - scheme.AddKnownTypes("", &TestResource{}) - scheme.AddKnownTypes(testapi.Default.Version(), &TestResource{}) + scheme.AddKnownTypes("", &storagetesting.TestResource{}) + scheme.AddKnownTypes(testapi.Default.Version(), &storagetesting.TestResource{}) codec = runtime.CodecFor(scheme, testapi.Default.Version()) scheme.AddConversionFuncs( - func(in *TestResource, out *TestResource, s conversion.Scope) error { + func(in *storagetesting.TestResource, out *storagetesting.TestResource, s conversion.Scope) error { *out = *in return nil }, @@ -123,39 +119,83 @@ func TestList(t *testing.T) { }, }, } - grace := int64(30) expect := api.PodList{ - ListMeta: api.ListMeta{ResourceVersion: "10"}, + ListMeta: unversioned.ListMeta{ResourceVersion: "10"}, Items: []api.Pod{ { ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, { ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, { ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, + Spec: apitesting.DeepEqualSafePodSpec(), + }, + }, + } + + var got api.PodList + err := helper.List(context.TODO(), "/some/key", storage.Everything, &got) + if err != nil { + t.Errorf("Unexpected error %v", err) + } + if e, a := expect, got; !reflect.DeepEqual(e, a) { + t.Errorf("Expected %#v, got %#v", e, a) + } +} + +func TestListFiltered(t *testing.T) { + fakeClient := tools.NewFakeEtcdClient(t) + helper := newEtcdHelper(fakeClient, testapi.Default.Codec(), etcdtest.PathPrefix()) + key := etcdtest.AddPrefix("/some/key") + fakeClient.Data[key] = tools.EtcdResponseWithError{ + R: &etcd.Response{ + EtcdIndex: 10, + Node: &etcd.Node{ + Dir: true, + Nodes: []*etcd.Node{ + { + Key: "/foo", + Value: getEncodedPod("foo"), + Dir: false, + ModifiedIndex: 1, + }, + { + Key: "/bar", + Value: getEncodedPod("bar"), + Dir: false, + ModifiedIndex: 2, + }, + { + Key: "/baz", + Value: getEncodedPod("baz"), + Dir: false, + ModifiedIndex: 3, + }, }, }, }, } + expect := api.PodList{ + ListMeta: unversioned.ListMeta{ResourceVersion: "10"}, + Items: []api.Pod{ + { + ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"}, + Spec: apitesting.DeepEqualSafePodSpec(), + }, + }, + } + + filter := func(obj runtime.Object) bool { + pod := obj.(*api.Pod) + return pod.Name == "bar" + } var got api.PodList - err := helper.List("/some/key", &got) + err := helper.List(context.TODO(), "/some/key", filter, &got) if err != nil { t.Errorf("Unexpected error %v", err) } @@ -210,40 +250,27 @@ func TestListAcrossDirectories(t *testing.T) { }, }, } - grace := int64(30) expect := api.PodList{ - ListMeta: api.ListMeta{ResourceVersion: "10"}, + ListMeta: unversioned.ListMeta{ResourceVersion: "10"}, Items: []api.Pod{ // We expect list to be sorted by directory (e.g. namespace) first, then by name. { ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, { ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, { ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, }, } var got api.PodList - err := helper.List("/some/key", &got) + err := helper.List(context.TODO(), "/some/key", storage.Everything, &got) if err != nil { t.Errorf("Unexpected error %v", err) } @@ -286,39 +313,26 @@ func TestListExcludesDirectories(t *testing.T) { }, }, } - grace := int64(30) expect := api.PodList{ - ListMeta: api.ListMeta{ResourceVersion: "10"}, + ListMeta: unversioned.ListMeta{ResourceVersion: "10"}, Items: []api.Pod{ { ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, { ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, { ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), }, }, } var got api.PodList - err := helper.List("/some/key", &got) + err := helper.List(context.TODO(), "/some/key", storage.Everything, &got) if err != nil { t.Errorf("Unexpected error %v", err) } @@ -331,18 +345,13 @@ func TestGet(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) helper := newEtcdHelper(fakeClient, testapi.Default.Codec(), etcdtest.PathPrefix()) key := etcdtest.AddPrefix("/some/key") - grace := int64(30) expect := api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), } fakeClient.Set(key, runtime.EncodeOrDie(testapi.Default.Codec(), &expect), 0) var got api.Pod - err := helper.Get("/some/key", &got, false) + err := helper.Get(context.TODO(), "/some/key", &got, false) if err != nil { t.Errorf("Unexpected error %#v", err) } @@ -379,11 +388,11 @@ func TestGetNotFoundErr(t *testing.T) { } try := func(key string) { var got api.Pod - err := helper.Get(key, &got, false) + err := helper.Get(context.TODO(), key, &got, false) if err == nil { t.Errorf("%s: wanted error but didn't get one", key) } - err = helper.Get(key, &got, true) + err = helper.Get(context.TODO(), key, &got, true) if err != nil { t.Errorf("%s: didn't want error but got %#v", key, err) } @@ -399,7 +408,7 @@ func TestCreate(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) helper := newEtcdHelper(fakeClient, testapi.Default.Codec(), etcdtest.PathPrefix()) returnedObj := &api.Pod{} - err := helper.Create("/some/key", obj, returnedObj, 5) + err := helper.Create(context.TODO(), "/some/key", obj, returnedObj, 5) if err != nil { t.Errorf("Unexpected error %#v", err) } @@ -424,7 +433,7 @@ func TestCreateNilOutParam(t *testing.T) { obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} fakeClient := tools.NewFakeEtcdClient(t) helper := newEtcdHelper(fakeClient, testapi.Default.Codec(), etcdtest.PathPrefix()) - err := helper.Create("/some/key", obj, nil, 5) + err := helper.Create(context.TODO(), "/some/key", obj, nil, 5) if err != nil { t.Errorf("Unexpected error %#v", err) } @@ -435,7 +444,7 @@ func TestSet(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) helper := newEtcdHelper(fakeClient, testapi.Default.Codec(), etcdtest.PathPrefix()) returnedObj := &api.Pod{} - err := helper.Set("/some/key", obj, returnedObj, 5) + err := helper.Set(context.TODO(), "/some/key", obj, returnedObj, 5) if err != nil { t.Errorf("Unexpected error %#v", err) } @@ -462,7 +471,7 @@ func TestSetFailCAS(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) fakeClient.CasErr = fakeClient.NewError(123) helper := newEtcdHelper(fakeClient, testapi.Default.Codec(), etcdtest.PathPrefix()) - err := helper.Set("/some/key", obj, nil, 5) + err := helper.Set(context.TODO(), "/some/key", obj, nil, 5) if err == nil { t.Errorf("Expecting error.") } @@ -484,7 +493,7 @@ func TestSetWithVersion(t *testing.T) { } returnedObj := &api.Pod{} - err := helper.Set("/some/key", obj, returnedObj, 7) + err := helper.Set(context.TODO(), "/some/key", obj, returnedObj, 7) if err != nil { t.Fatalf("Unexpected error %#v", err) } @@ -511,7 +520,7 @@ func TestSetWithoutResourceVersioner(t *testing.T) { helper := newEtcdHelper(fakeClient, testapi.Default.Codec(), etcdtest.PathPrefix()) helper.versioner = nil returnedObj := &api.Pod{} - err := helper.Set("/some/key", obj, returnedObj, 3) + err := helper.Set(context.TODO(), "/some/key", obj, returnedObj, 3) key := etcdtest.AddPrefix("/some/key") if err != nil { t.Errorf("Unexpected error %#v", err) @@ -538,7 +547,7 @@ func TestSetNilOutParam(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) helper := newEtcdHelper(fakeClient, testapi.Default.Codec(), etcdtest.PathPrefix()) helper.versioner = nil - err := helper.Set("/some/key", obj, nil, 3) + err := helper.Set(context.TODO(), "/some/key", obj, nil, 3) if err != nil { t.Errorf("Unexpected error %#v", err) } @@ -552,8 +561,8 @@ func TestGuaranteedUpdate(t *testing.T) { // Create a new node. fakeClient.ExpectNotFoundGet(key) - obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} - err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { + obj := &storagetesting.TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} + err := helper.GuaranteedUpdate(context.TODO(), "/some/key", &storagetesting.TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { return obj, nil })) if err != nil { @@ -571,11 +580,11 @@ func TestGuaranteedUpdate(t *testing.T) { // Update an existing node. callbackCalled := false - objUpdate := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 2} - err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { + objUpdate := &storagetesting.TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 2} + err = helper.GuaranteedUpdate(context.TODO(), "/some/key", &storagetesting.TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { callbackCalled = true - if in.(*TestResource).Value != 1 { + if in.(*storagetesting.TestResource).Value != 1 { t.Errorf("Callback input was not current set value") } @@ -607,8 +616,8 @@ func TestGuaranteedUpdateTTL(t *testing.T) { // Create a new node. fakeClient.ExpectNotFoundGet(key) - obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} - err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { + obj := &storagetesting.TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} + err := helper.GuaranteedUpdate(context.TODO(), "/some/key", &storagetesting.TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { if res.TTL != 0 { t.Fatalf("unexpected response meta: %#v", res) } @@ -633,14 +642,14 @@ func TestGuaranteedUpdateTTL(t *testing.T) { // Update an existing node. callbackCalled := false - objUpdate := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 2} - err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { + objUpdate := &storagetesting.TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 2} + err = helper.GuaranteedUpdate(context.TODO(), "/some/key", &storagetesting.TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { if res.TTL != 10 { t.Fatalf("unexpected response meta: %#v", res) } callbackCalled = true - if in.(*TestResource).Value != 1 { + if in.(*storagetesting.TestResource).Value != 1 { t.Errorf("Callback input was not current set value") } @@ -665,14 +674,14 @@ func TestGuaranteedUpdateTTL(t *testing.T) { // Update an existing node and change ttl callbackCalled = false - objUpdate = &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 3} - err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { + objUpdate = &storagetesting.TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 3} + err = helper.GuaranteedUpdate(context.TODO(), "/some/key", &storagetesting.TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { if res.TTL != 10 { t.Fatalf("unexpected response meta: %#v", res) } callbackCalled = true - if in.(*TestResource).Value != 2 { + if in.(*storagetesting.TestResource).Value != 2 { t.Errorf("Callback input was not current set value") } @@ -708,8 +717,8 @@ func TestGuaranteedUpdateNoChange(t *testing.T) { // Create a new node. fakeClient.ExpectNotFoundGet(key) - obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} - err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { + obj := &storagetesting.TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} + err := helper.GuaranteedUpdate(context.TODO(), "/some/key", &storagetesting.TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { return obj, nil })) if err != nil { @@ -718,8 +727,8 @@ func TestGuaranteedUpdateNoChange(t *testing.T) { // Update an existing node with the same data callbackCalled := false - objUpdate := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} - err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { + objUpdate := &storagetesting.TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} + err = helper.GuaranteedUpdate(context.TODO(), "/some/key", &storagetesting.TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { fakeClient.Err = errors.New("should not be called") callbackCalled = true return objUpdate, nil @@ -740,20 +749,20 @@ func TestGuaranteedUpdateKeyNotFound(t *testing.T) { // Create a new node. fakeClient.ExpectNotFoundGet(key) - obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} + obj := &storagetesting.TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} f := storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { return obj, nil }) ignoreNotFound := false - err := helper.GuaranteedUpdate("/some/key", &TestResource{}, ignoreNotFound, f) + err := helper.GuaranteedUpdate(context.TODO(), "/some/key", &storagetesting.TestResource{}, ignoreNotFound, f) if err == nil { t.Errorf("Expected error for key not found.") } ignoreNotFound = true - err = helper.GuaranteedUpdate("/some/key", &TestResource{}, ignoreNotFound, f) + err = helper.GuaranteedUpdate(context.TODO(), "/some/key", &storagetesting.TestResource{}, ignoreNotFound, f) if err != nil { t.Errorf("Unexpected error %v.", err) } @@ -774,12 +783,12 @@ func TestGuaranteedUpdate_CreateCollision(t *testing.T) { wgForceCollision.Add(concurrency) for i := 0; i < concurrency; i++ { - // Increment TestResource.Value by 1 + // Increment storagetesting.TestResource.Value by 1 go func() { defer wgDone.Done() firstCall := true - err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { + err := helper.GuaranteedUpdate(context.TODO(), "/some/key", &storagetesting.TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { defer func() { firstCall = false }() if firstCall { @@ -788,8 +797,8 @@ func TestGuaranteedUpdate_CreateCollision(t *testing.T) { wgForceCollision.Wait() } - currValue := in.(*TestResource).Value - obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: currValue + 1} + currValue := in.(*storagetesting.TestResource).Value + obj := &storagetesting.TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: currValue + 1} return obj, nil })) if err != nil { @@ -799,9 +808,9 @@ func TestGuaranteedUpdate_CreateCollision(t *testing.T) { } wgDone.Wait() - // Check that stored TestResource has received all updates. + // Check that stored storagetesting.TestResource has received all updates. body := fakeClient.Data[key].R.Node.Value - stored := &TestResource{} + stored := &storagetesting.TestResource{} if err := codec.DecodeInto([]byte(body), stored); err != nil { t.Errorf("Error decoding stored value: %v", body) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_util.go index 2f20b2f97fa9..dedf1e36b33a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_util.go @@ -29,27 +29,27 @@ import ( "github.com/golang/glog" ) -// IsEtcdNotFound returns true iff err is an etcd not found error. +// IsEtcdNotFound returns true if and only if err is an etcd not found error. func IsEtcdNotFound(err error) bool { return isEtcdErrorNum(err, tools.EtcdErrorCodeNotFound) } -// IsEtcdNodeExist returns true iff err is an etcd node already exist error. +// IsEtcdNodeExist returns true if and only if err is an etcd node already exist error. func IsEtcdNodeExist(err error) bool { return isEtcdErrorNum(err, tools.EtcdErrorCodeNodeExist) } -// IsEtcdTestFailed returns true iff err is an etcd write conflict. +// IsEtcdTestFailed returns true if and only if err is an etcd write conflict. func IsEtcdTestFailed(err error) bool { return isEtcdErrorNum(err, tools.EtcdErrorCodeTestFailed) } -// IsEtcdWatchStoppedByUser returns true iff err is a client triggered stop. +// IsEtcdWatchStoppedByUser returns true if and only if err is a client triggered stop. func IsEtcdWatchStoppedByUser(err error) bool { return goetcd.ErrWatchStoppedByUser == err } -// isEtcdErrorNum returns true iff err is an etcd error, whose errorCode matches errorCode +// isEtcdErrorNum returns true if and only if err is an etcd error, whose errorCode matches errorCode func isEtcdErrorNum(err error, errorCode int) bool { etcdError, ok := err.(*goetcd.EtcdError) return ok && etcdError != nil && etcdError.ErrorCode == errorCode diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher.go index 4ab51cabbde7..9dae526586dc 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher.go @@ -20,7 +20,7 @@ import ( "sync" "time" - "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/tools" @@ -183,8 +183,8 @@ func (w *etcdWatcher) translate() { if err != nil { w.emit(watch.Event{ Type: watch.Error, - Object: &api.Status{ - Status: api.StatusFailure, + Object: &unversioned.Status{ + Status: unversioned.StatusFailure, Message: err.Error(), }, }) @@ -208,7 +208,7 @@ func (w *etcdWatcher) translate() { } func (w *etcdWatcher) decodeObject(node *etcd.Node) (runtime.Object, error) { - if obj, found := w.cache.getFromCache(node.ModifiedIndex); found { + if obj, found := w.cache.getFromCache(node.ModifiedIndex, storage.Everything); found { return obj, nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher_test.go index 43e630df18be..3f95b864f2ee 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher_test.go @@ -23,12 +23,16 @@ import ( "github.com/coreos/go-etcd/etcd" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools/etcdtest" + "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/watch" + + "golang.org/x/net/context" ) var versioner = APIObjectVersioner{} @@ -36,7 +40,7 @@ var versioner = APIObjectVersioner{} // Implements etcdCache interface as empty methods (i.e. does not cache any objects) type fakeEtcdCache struct{} -func (f *fakeEtcdCache) getFromCache(index uint64) (runtime.Object, bool) { +func (f *fakeEtcdCache) getFromCache(index uint64, filter storage.FilterFunc) (runtime.Object, bool) { return nil, false } @@ -46,7 +50,7 @@ func (f *fakeEtcdCache) addToCache(index uint64, obj runtime.Object) { var _ etcdCache = &fakeEtcdCache{} func TestWatchInterpretations(t *testing.T) { - codec := latest.Codec + codec := testapi.Default.Codec() // Declare some pods to make the test cases compact. podFoo := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} podBar := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}} @@ -215,13 +219,13 @@ func TestWatchInterpretation_ResponseBadData(t *testing.T) { } func TestWatchEtcdError(t *testing.T) { - codec := latest.Codec + codec := testapi.Default.Codec() fakeClient := tools.NewFakeEtcdClient(t) fakeClient.ExpectNotFoundGet("/some/key") fakeClient.WatchImmediateError = fmt.Errorf("immediate error") h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch("/some/key", 4, storage.Everything) + watching, err := h.Watch(context.TODO(), "/some/key", 4, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -231,27 +235,27 @@ func TestWatchEtcdError(t *testing.T) { if got.Type != watch.Error { t.Fatalf("Unexpected non-error") } - status, ok := got.Object.(*api.Status) + status, ok := got.Object.(*unversioned.Status) if !ok { t.Fatalf("Unexpected non-error object type") } if status.Message != "immediate error" { t.Errorf("Unexpected wrong error") } - if status.Status != api.StatusFailure { + if status.Status != unversioned.StatusFailure { t.Errorf("Unexpected wrong error status") } } func TestWatch(t *testing.T) { - codec := latest.Codec + codec := testapi.Default.Codec() fakeClient := tools.NewFakeEtcdClient(t) key := "/some/key" prefixedKey := etcdtest.AddPrefix(key) fakeClient.ExpectNotFoundGet(prefixedKey) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch(key, 0, storage.Everything) + watching, err := h.Watch(context.TODO(), key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -289,7 +293,7 @@ func TestWatch(t *testing.T) { if e, a := watch.Error, errEvent.Type; e != a { t.Errorf("Expected %v, got %v", e, a) } - if e, a := "Injected error", errEvent.Object.(*api.Status).Message; e != a { + if e, a := "Injected error", errEvent.Object.(*unversioned.Status).Message; e != a { t.Errorf("Expected %v, got %v", e, a) } } @@ -315,7 +319,7 @@ func makeSubsets(ip string, port int) []api.EndpointSubset { } func TestWatchEtcdState(t *testing.T) { - codec := latest.Codec + codec := testapi.Default.Codec() baseKey := "/somekey/foo" prefixedKey := etcdtest.AddPrefix(baseKey) type T struct { @@ -426,7 +430,7 @@ func TestWatchEtcdState(t *testing.T) { } h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch(baseKey, testCase.From, storage.Everything) + watching, err := h.Watch(context.TODO(), baseKey, testCase.From, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -453,7 +457,7 @@ func TestWatchEtcdState(t *testing.T) { } func TestWatchFromZeroIndex(t *testing.T) { - codec := latest.Codec + codec := testapi.Default.Codec() pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} testCases := map[string]struct { @@ -500,7 +504,7 @@ func TestWatchFromZeroIndex(t *testing.T) { fakeClient.Data[prefixedKey] = testCase.Response h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch(key, 0, storage.Everything) + watching, err := h.Watch(context.TODO(), key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -531,7 +535,7 @@ func TestWatchFromZeroIndex(t *testing.T) { } func TestWatchListFromZeroIndex(t *testing.T) { - codec := latest.Codec + codec := testapi.Default.Codec() pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} key := "/some/key" prefixedKey := etcdtest.AddPrefix(key) @@ -561,7 +565,7 @@ func TestWatchListFromZeroIndex(t *testing.T) { } h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.WatchList(key, 0, storage.Everything) + watching, err := h.WatchList(context.TODO(), key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -593,7 +597,7 @@ func TestWatchListFromZeroIndex(t *testing.T) { } func TestWatchListIgnoresRootKey(t *testing.T) { - codec := latest.Codec + codec := testapi.Default.Codec() pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} key := "/some/key" prefixedKey := etcdtest.AddPrefix(key) @@ -601,7 +605,7 @@ func TestWatchListIgnoresRootKey(t *testing.T) { fakeClient := tools.NewFakeEtcdClient(t) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.WatchList(key, 1, storage.Everything) + watching, err := h.WatchList(context.TODO(), key, 1, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -654,7 +658,7 @@ func TestWatchFromNotFound(t *testing.T) { } h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch(key, 0, storage.Everything) + watching, err := h.Watch(context.TODO(), key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -681,7 +685,7 @@ func TestWatchFromOtherError(t *testing.T) { } h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch(key, 0, storage.Everything) + watching, err := h.Watch(context.TODO(), key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -690,7 +694,7 @@ func TestWatchFromOtherError(t *testing.T) { if e, a := watch.Error, errEvent.Type; e != a { t.Errorf("Expected %v, got %v", e, a) } - if e, a := "101: () [2]", errEvent.Object.(*api.Status).Message; e != a { + if e, a := "101: () [2]", errEvent.Object.(*unversioned.Status).Message; e != a { t.Errorf("Expected %v, got %v", e, a) } @@ -699,7 +703,7 @@ func TestWatchFromOtherError(t *testing.T) { if ok { t.Fatalf("expected result channel to be closed") } - case <-time.After(1 * time.Second): + case <-time.After(util.ForeverTestTimeout): t.Fatalf("watch should have closed channel: %#v", watching) } @@ -717,7 +721,7 @@ func TestWatchPurposefulShutdown(t *testing.T) { fakeClient.ExpectNotFoundGet(prefixedKey) // Test purposeful shutdown - watching, err := h.Watch(key, 0, storage.Everything) + watching, err := h.Watch(context.TODO(), key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/interfaces.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/interfaces.go index 3ba685ab57ed..c55f2687fbeb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/interfaces.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/interfaces.go @@ -19,6 +19,7 @@ package storage import ( "time" + "golang.org/x/net/context" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/watch" ) @@ -55,7 +56,7 @@ type ResponseMeta struct { } // FilterFunc is a predicate which takes an API object and returns true -// iff the object should remain in the set. +// if and only if the object should remain in the set. type FilterFunc func(obj runtime.Object) bool // Everything is a FilterFunc which accepts all objects. @@ -74,7 +75,7 @@ type Interface interface { // Returns list of servers addresses of the underyling database. // TODO: This method is used only in a single place. Consider refactoring and getting rid // of this method from the interface. - Backends() []string + Backends(ctx context.Context) []string // Returns Versioner associated with this interface. Versioner() Versioner @@ -82,40 +83,40 @@ type Interface interface { // Create adds a new object at a key unless it already exists. 'ttl' is time-to-live // in seconds (0 means forever). If no error is returned and out is not nil, out will be // set to the read value from database. - Create(key string, obj, out runtime.Object, ttl uint64) error + Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error // Set marshals obj via json and stores in database under key. Will do an atomic update // if obj's ResourceVersion field is set. 'ttl' is time-to-live in seconds (0 means forever). // If no error is returned and out is not nil, out will be set to the read value from database. - Set(key string, obj, out runtime.Object, ttl uint64) error + Set(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error // Delete removes the specified key and returns the value that existed at that spot. - Delete(key string, out runtime.Object) error + Delete(ctx context.Context, key string, out runtime.Object) error // Watch begins watching the specified key. Events are decoded into API objects, // and any items passing 'filter' are sent down to returned watch.Interface. // resourceVersion may be used to specify what version to begin watching // (e.g. reconnecting without missing any updates). - Watch(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) + Watch(ctx context.Context, key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) // WatchList begins watching the specified key's items. Items are decoded into API // objects and any item passing 'filter' are sent down to returned watch.Interface. // resourceVersion may be used to specify what version to begin watching // (e.g. reconnecting without missing any updates). - WatchList(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) + WatchList(ctx context.Context, key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) // Get unmarshals json found at key into objPtr. On a not found error, will either // return a zero object of the requested type, or an error, depending on ignoreNotFound. // Treats empty responses and nil response nodes exactly like a not found error. - Get(key string, objPtr runtime.Object, ignoreNotFound bool) error + Get(ctx context.Context, key string, objPtr runtime.Object, ignoreNotFound bool) error // GetToList unmarshals json found at key and opaque it into *List api object // (an object that satisfies the runtime.IsList definition). - GetToList(key string, listObj runtime.Object) error + GetToList(ctx context.Context, key string, filter FilterFunc, listObj runtime.Object) error // List unmarshalls jsons found at directory defined by key and opaque them // into *List api object (an object that satisfies runtime.IsList definition). - List(key string, listObj runtime.Object) error + List(ctx context.Context, key string, filter FilterFunc, listObj runtime.Object) error // GuaranteedUpdate keeps calling 'tryUpdate()' to update key 'key' (of type 'ptrToType') // retrying the update until success if there is index conflict. @@ -141,7 +142,7 @@ type Interface interface { // return cur, nil, nil // } // }) - GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate UpdateFunc) error + GuaranteedUpdate(ctx context.Context, key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate UpdateFunc) error // Codec provides access to the underlying codec being used by the implementation. Codec() runtime.Codec diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/prober_fake.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/testing/types.go similarity index 69% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/prober_fake.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/testing/types.go index ad933ccf9bee..4fa38404cb47 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/prober/prober_fake.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/testing/types.go @@ -14,18 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -package prober +package testing import ( "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/probe" + "k8s.io/kubernetes/pkg/api/unversioned" ) -var _ Prober = &FakeProber{} - -type FakeProber struct { +type TestResource struct { + unversioned.TypeMeta `json:",inline"` + api.ObjectMeta `json:"metadata"` + Value int `json:"value"` } -func (fp *FakeProber) Probe(pod *api.Pod, status api.PodStatus, container api.Container, containerID string, createdAt int64) (probe.Result, error) { - return probe.Success, nil -} +func (*TestResource) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/watch_cache.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/watch_cache.go index 5535d41d4173..1b376feec1aa 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/watch_cache.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/watch_cache.go @@ -22,6 +22,7 @@ import ( "strconv" "sync" + "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/runtime" @@ -265,7 +266,7 @@ func (w *watchCache) GetAllEventsSinceThreadUnsafe(resourceVersion uint64) ([]wa return result, nil } if resourceVersion < oldest { - return nil, fmt.Errorf("too old resource version: %d (%d)", resourceVersion, oldest) + return nil, errors.NewInternalError(fmt.Errorf("too old resource version: %d (%d)", resourceVersion, oldest)) } // Binary seatch the smallest index at which resourceVersion is not smaller than diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/watch_cache_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/watch_cache_test.go index 48442b745fa3..bc62ca85b692 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/watch_cache_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/storage/watch_cache_test.go @@ -21,6 +21,8 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" @@ -119,6 +121,9 @@ func TestEvents(t *testing.T) { if err == nil { t.Errorf("expected error too old") } + if _, ok := err.(*errors.StatusError); !ok { + t.Errorf("expected error to be of type StatusError") + } } { result, err := store.GetAllEventsSince(2) @@ -252,7 +257,7 @@ func TestReflectorForWatchCache(t *testing.T) { return fw, nil }, ListFunc: func() (runtime.Object, error) { - return &api.PodList{ListMeta: api.ListMeta{ResourceVersion: "10"}}, nil + return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "10"}}, nil }, } r := cache.NewReflector(lw, &api.Pod{}, store, 0) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/tools/etcdtest/etcdtest.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/tools/etcdtest/etcdtest.go index 31a5f9f63ebb..5ba3643da24d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/tools/etcdtest/etcdtest.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/tools/etcdtest/etcdtest.go @@ -23,7 +23,11 @@ import ( // Returns the prefix set via the ETCD_PREFIX environment variable (if any). func PathPrefix() string { - return path.Join("/", os.Getenv("ETCD_PREFIX")) + pref := os.Getenv("ETCD_PREFIX") + if pref == "" { + pref = "registry" + } + return path.Join("/", pref) } // Adds the ETCD_PREFIX to the provided key diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/atomic_value.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/atomic_value.go index 718b712787e0..546e19d713fa 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/atomic_value.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/atomic_value.go @@ -46,7 +46,7 @@ func (at *AtomicValue) Load() interface{} { // for some quantity. type HighWaterMark int64 -// Check returns true iff 'current' is the highest value ever seen. +// Check returns true if and only if 'current' is the highest value ever seen. func (hwm *HighWaterMark) Check(current int64) bool { for { old := atomic.LoadInt64((*int64)(hwm)) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/atomic_value_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/atomic_value_test.go index 54a5efc9f297..d3fb0cad7f52 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/atomic_value_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/atomic_value_test.go @@ -38,7 +38,7 @@ func ExpectValue(t *testing.T, atomicValue *AtomicValue, expectedValue interface t.Errorf("Expected to find %v, found %v", expectedValue, actualValue) return } - case <-time.After(time.Second * 5): + case <-time.After(ForeverTestTimeout): t.Error("Value could not be read") return } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/backoff.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/backoff.go index d7936071af35..173e131872c1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/backoff.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/backoff.go @@ -84,6 +84,20 @@ func (p *Backoff) IsInBackOffSince(id string, eventTime time.Time) bool { return p.Clock.Now().Sub(eventTime) < entry.backoff } +// Returns True if time since lastupdate is less than the current backoff window. +func (p *Backoff) IsInBackOffSinceUpdate(id string, eventTime time.Time) bool { + p.Lock() + defer p.Unlock() + entry, ok := p.perItemBackoff[id] + if !ok { + return false + } + if hasExpired(eventTime, entry.lastUpdate, p.maxDuration) { + return false + } + return eventTime.Sub(entry.lastUpdate) < entry.backoff +} + // Garbage collect records that have aged past maxDuration. Backoff users are expected // to invoke this periodically. func (p *Backoff) GC() { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/backoff_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/backoff_test.go index 0a49f9eee748..f2bc9771578f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/backoff_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/backoff_test.go @@ -123,3 +123,72 @@ func TestBackoffGC(t *testing.T) { t.Errorf("expected GC of entry after %s got entry %v", tc.Now().Sub(lastUpdate), r) } } + +func TestIsInBackOffSinceUpdate(t *testing.T) { + id := "_idIsInBackOffSinceUpdate" + tc := &FakeClock{Time: time.Now()} + step := time.Second + maxDuration := 10 * step + b := NewFakeBackOff(step, maxDuration, tc) + startTime := tc.Now() + + cases := []struct { + tick time.Duration + inBackOff bool + value int + }{ + {tick: 0, inBackOff: false, value: 0}, + {tick: 1, inBackOff: false, value: 1}, + {tick: 2, inBackOff: true, value: 2}, + {tick: 3, inBackOff: false, value: 2}, + {tick: 4, inBackOff: true, value: 4}, + {tick: 5, inBackOff: true, value: 4}, + {tick: 6, inBackOff: true, value: 4}, + {tick: 7, inBackOff: false, value: 4}, + {tick: 8, inBackOff: true, value: 8}, + {tick: 9, inBackOff: true, value: 8}, + {tick: 10, inBackOff: true, value: 8}, + {tick: 11, inBackOff: true, value: 8}, + {tick: 12, inBackOff: true, value: 8}, + {tick: 13, inBackOff: true, value: 8}, + {tick: 14, inBackOff: true, value: 8}, + {tick: 15, inBackOff: false, value: 8}, + {tick: 16, inBackOff: true, value: 10}, + {tick: 17, inBackOff: true, value: 10}, + {tick: 18, inBackOff: true, value: 10}, + {tick: 19, inBackOff: true, value: 10}, + {tick: 20, inBackOff: true, value: 10}, + {tick: 21, inBackOff: true, value: 10}, + {tick: 22, inBackOff: true, value: 10}, + {tick: 23, inBackOff: true, value: 10}, + {tick: 24, inBackOff: true, value: 10}, + {tick: 25, inBackOff: false, value: 10}, + {tick: 26, inBackOff: true, value: 10}, + {tick: 27, inBackOff: true, value: 10}, + {tick: 28, inBackOff: true, value: 10}, + {tick: 29, inBackOff: true, value: 10}, + {tick: 30, inBackOff: true, value: 10}, + {tick: 31, inBackOff: true, value: 10}, + {tick: 32, inBackOff: true, value: 10}, + {tick: 33, inBackOff: true, value: 10}, + {tick: 34, inBackOff: true, value: 10}, + {tick: 35, inBackOff: false, value: 10}, + {tick: 56, inBackOff: false, value: 0}, + {tick: 57, inBackOff: false, value: 1}, + } + + for _, c := range cases { + tc.Time = startTime.Add(c.tick * step) + if c.inBackOff != b.IsInBackOffSinceUpdate(id, tc.Now()) { + t.Errorf("expected IsInBackOffSinceUpdate %v got %v at tick %s", c.inBackOff, b.IsInBackOffSinceUpdate(id, tc.Now()), c.tick*step) + } + + if c.inBackOff && (time.Duration(c.value)*step != b.Get(id)) { + t.Errorf("expected backoff value=%s got %s at tick %s", time.Duration(c.value)*step, b.Get(id), c.tick*step) + } + + if !c.inBackOff { + b.Next(id, tc.Now()) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/linux.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/linux.go index 7989394ec94d..dd45e822bac1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/linux.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/linux.go @@ -1,3 +1,5 @@ +// +build linux + /* Copyright 2015 The Kubernetes Authors All rights reserved. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/linux_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/linux_test.go index a1ac3e216b3e..f725570ff865 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/linux_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/linux_test.go @@ -1,3 +1,5 @@ +// +build linux + /* Copyright 2015 The Kubernetes Authors All rights reserved. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/unsupported.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/unsupported.go new file mode 100644 index 000000000000..7f980a26558e --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/bandwidth/unsupported.go @@ -0,0 +1,52 @@ +// +build !linux + +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 bandwidth + +import ( + "errors" + + "k8s.io/kubernetes/pkg/api/resource" +) + +type unsupportedShaper struct { +} + +func NewTCShaper(iface string) BandwidthShaper { + return &unsupportedShaper{} +} + +func (f *unsupportedShaper) Limit(cidr string, egress, ingress *resource.Quantity) error { + return errors.New("unimplemented") +} + +func (f *unsupportedShaper) Reset(cidr string) error { + return nil +} + +func (f *unsupportedShaper) ReconcileInterface() error { + return errors.New("unimplemented") +} + +func (f *unsupportedShaper) ReconcileCIDR(cidr string, egress, ingress *resource.Quantity) error { + return errors.New("unimplemented") +} + +func (f *unsupportedShaper) GetCIDRs() ([]string, error) { + return []string{}, nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/deployment/deployment.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/deployment/deployment.go new file mode 100644 index 000000000000..59ca0c95b044 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/deployment/deployment.go @@ -0,0 +1,157 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 deployment + +import ( + "fmt" + "hash/adler32" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/util" +) + +// Returns the old RCs targetted by the given Deployment. +func GetOldRCs(deployment extensions.Deployment, c client.Interface) ([]*api.ReplicationController, error) { + namespace := deployment.ObjectMeta.Namespace + // 1. Find all pods whose labels match deployment.Spec.Selector + podList, err := c.Pods(namespace).List(labels.SelectorFromSet(deployment.Spec.Selector), fields.Everything()) + if err != nil { + return nil, fmt.Errorf("error listing pods: %v", err) + } + // 2. Find the corresponding RCs for pods in podList. + // TODO: Right now we list all RCs and then filter. We should add an API for this. + oldRCs := map[string]api.ReplicationController{} + rcList, err := c.ReplicationControllers(namespace).List(labels.Everything(), fields.Everything()) + if err != nil { + return nil, fmt.Errorf("error listing replication controllers: %v", err) + } + for _, pod := range podList.Items { + podLabelsSelector := labels.Set(pod.ObjectMeta.Labels) + for _, rc := range rcList.Items { + rcLabelsSelector := labels.SelectorFromSet(rc.Spec.Selector) + if rcLabelsSelector.Matches(podLabelsSelector) { + // Filter out RC that has the same pod template spec as the deployment - that is the new RC. + if api.Semantic.DeepEqual(rc.Spec.Template, GetNewRCTemplate(deployment)) { + continue + } + oldRCs[rc.ObjectMeta.Name] = rc + } + } + } + requiredRCs := []*api.ReplicationController{} + for _, value := range oldRCs { + requiredRCs = append(requiredRCs, &value) + } + return requiredRCs, nil +} + +// Returns an RC that matches the intent of the given deployment. +// Returns nil if the new RC doesnt exist yet. +func GetNewRC(deployment extensions.Deployment, c client.Interface) (*api.ReplicationController, error) { + namespace := deployment.ObjectMeta.Namespace + rcList, err := c.ReplicationControllers(namespace).List(labels.Everything(), fields.Everything()) + if err != nil { + return nil, fmt.Errorf("error listing replication controllers: %v", err) + } + newRCTemplate := GetNewRCTemplate(deployment) + + for _, rc := range rcList.Items { + if api.Semantic.DeepEqual(rc.Spec.Template, newRCTemplate) { + // This is the new RC. + return &rc, nil + } + } + // new RC does not exist. + return nil, nil +} + +// Returns the desired PodTemplateSpec for the new RC corresponding to the given RC. +func GetNewRCTemplate(deployment extensions.Deployment) *api.PodTemplateSpec { + // newRC will have the same template as in deployment spec, plus a unique label in some cases. + newRCTemplate := &api.PodTemplateSpec{ + ObjectMeta: deployment.Spec.Template.ObjectMeta, + Spec: deployment.Spec.Template.Spec, + } + newRCTemplate.ObjectMeta.Labels = CloneAndAddLabel( + deployment.Spec.Template.ObjectMeta.Labels, + deployment.Spec.UniqueLabelKey, + GetPodTemplateSpecHash(newRCTemplate)) + return newRCTemplate +} + +// Clones the given map and returns a new map with the given key and value added. +// Returns the given map, if labelKey is empty. +func CloneAndAddLabel(labels map[string]string, labelKey string, labelValue uint32) map[string]string { + if labelKey == "" { + // Dont need to add a label. + return labels + } + // Clone. + newLabels := map[string]string{} + for key, value := range labels { + newLabels[key] = value + } + newLabels[labelKey] = fmt.Sprintf("%d", labelValue) + return newLabels +} + +func GetPodTemplateSpecHash(template *api.PodTemplateSpec) uint32 { + podTemplateSpecHasher := adler32.New() + util.DeepHashObject(podTemplateSpecHasher, template) + return podTemplateSpecHasher.Sum32() +} + +// Returns the sum of Replicas of the given replication controllers. +func GetReplicaCountForRCs(replicationControllers []*api.ReplicationController) int { + totalReplicaCount := 0 + for _, rc := range replicationControllers { + totalReplicaCount += rc.Spec.Replicas + } + return totalReplicaCount +} + +// Returns the number of available pods corresponding to the given RCs. +func GetAvailablePodsForRCs(c client.Interface, rcs []*api.ReplicationController) (int, error) { + // TODO: Use MinReadySeconds once https://github.com/kubernetes/kubernetes/pull/12894 is merged. + allPods, err := getPodsForRCs(c, rcs) + if err != nil { + return 0, err + } + readyPodCount := 0 + for _, pod := range allPods { + if api.IsPodReady(&pod) { + readyPodCount++ + } + } + return readyPodCount, nil +} + +func getPodsForRCs(c client.Interface, replicationControllers []*api.ReplicationController) ([]api.Pod, error) { + allPods := []api.Pod{} + for _, rc := range replicationControllers { + podList, err := c.Pods(rc.ObjectMeta.Namespace).List(labels.SelectorFromSet(rc.Spec.Selector), fields.Everything()) + if err != nil { + return allPods, fmt.Errorf("error listing pods: %v", err) + } + allPods = append(allPods, podList.Items...) + } + return allPods, nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/errors/errors.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/errors/errors.go index c30127370123..a1a8e7aa24c4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/errors/errors.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/errors/errors.go @@ -131,3 +131,20 @@ func Flatten(agg Aggregate) Aggregate { } return NewAggregate(result) } + +// AggregateGoroutines runs the provided functions in parallel, stuffing all +// non-nil errors into the returned Aggregate. +// Returns nil if all the functions complete successfully. +func AggregateGoroutines(funcs ...func() error) Aggregate { + errChan := make(chan error, len(funcs)) + for _, f := range funcs { + go func(f func() error) { errChan <- f() }(f) + } + errs := make([]error, 0) + for i := 0; i < cap(errChan); i++ { + if err := <-errChan; err != nil { + errs = append(errs, err) + } + } + return NewAggregate(errs) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/errors/errors_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/errors/errors_test.go index 1d77fddde0d5..7ecf919ffb0e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/errors/errors_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/errors/errors_test.go @@ -221,3 +221,66 @@ func TestFlatten(t *testing.T) { } } } + +func TestAggregateGoroutines(t *testing.T) { + testCases := []struct { + errs []error + expected map[string]bool // can't compare directly to Aggregate due to non-deterministic ordering + }{ + { + []error{}, + nil, + }, + { + []error{nil}, + nil, + }, + { + []error{nil, nil}, + nil, + }, + { + []error{fmt.Errorf("1")}, + map[string]bool{"1": true}, + }, + { + []error{fmt.Errorf("1"), nil}, + map[string]bool{"1": true}, + }, + { + []error{fmt.Errorf("1"), fmt.Errorf("267")}, + map[string]bool{"1": true, "267": true}, + }, + { + []error{fmt.Errorf("1"), nil, fmt.Errorf("1234")}, + map[string]bool{"1": true, "1234": true}, + }, + { + []error{nil, fmt.Errorf("1"), nil, fmt.Errorf("1234"), fmt.Errorf("22")}, + map[string]bool{"1": true, "1234": true, "22": true}, + }, + } + for i, testCase := range testCases { + funcs := make([]func() error, len(testCase.errs)) + for i := range testCase.errs { + err := testCase.errs[i] + funcs[i] = func() error { return err } + } + agg := AggregateGoroutines(funcs...) + if agg == nil { + if len(testCase.expected) > 0 { + t.Errorf("%d: expected %v, got nil", i, testCase.expected) + } + continue + } + if len(agg.Errors()) != len(testCase.expected) { + t.Errorf("%d: expected %d errors in aggregate, got %v", i, len(testCase.expected), agg) + continue + } + for _, err := range agg.Errors() { + if !testCase.expected[err.Error()] { + t.Errorf("%d: expected %v, got aggregate containing %v", i, testCase.expected, err) + } + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/fielderrors/fielderrors.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/fielderrors/fielderrors.go index 4650d329a41f..f1d85e01e503 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/fielderrors/fielderrors.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/fielderrors/fielderrors.go @@ -23,7 +23,6 @@ import ( "k8s.io/kubernetes/pkg/util/errors" "github.com/davecgh/go-spew/spew" - "github.com/golang/glog" ) // ValidationErrorType is a machine readable value providing more detail about why @@ -74,7 +73,7 @@ func (t ValidationErrorType) String() string { case ValidationErrorTypeTooLong: return "too long" default: - glog.Errorf("unrecognized validation type: %#v", t) + panic(fmt.Sprintf("unrecognized validation type: %#v", t)) return "" } } @@ -161,7 +160,7 @@ func (list ValidationErrorList) Prefix(prefix string) ValidationErrorList { } list[i] = err } else { - glog.Warningf("Programmer error: ValidationErrorList holds non-ValidationError: %#v", list[i]) + panic(fmt.Sprintf("Programmer error: ValidationErrorList holds non-ValidationError: %#v", list[i])) } } return list diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/httpstream/httpstream.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/httpstream/httpstream.go index a1c92dde7ff2..fff6840f2799 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/httpstream/httpstream.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/httpstream/httpstream.go @@ -37,6 +37,11 @@ type NewStreamHandler func(Stream) error // performs no other logic. func NoOpNewStreamHandler(stream Stream) error { return nil } +// Dialer knows how to open a streaming connection to a server. +type Dialer interface { + Dial() (Connection, error) +} + // UpgradeRoundTripper is a type of http.RoundTripper that is able to upgrade // HTTP requests to support multiplexed bidirectional streams. After RoundTrip() // is invoked, if the upgrade is successful, clients may retrieve the upgraded @@ -78,6 +83,8 @@ type Stream interface { Reset() error // Headers returns the headers used to create the stream. Headers() http.Header + // Identifier returns the stream's ID. + Identifier() uint32 } // IsUpgradeRequest returns true if the given request is a connection upgrade request diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/httpstream/spdy/roundtripper.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/httpstream/spdy/roundtripper.go index 348c5fa851fb..b00678221cf8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/httpstream/spdy/roundtripper.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/httpstream/spdy/roundtripper.go @@ -27,6 +27,7 @@ import ( "k8s.io/kubernetes/pkg/api" apierrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/httpstream" "k8s.io/kubernetes/third_party/golang/netutil" ) @@ -146,7 +147,7 @@ func (s *SpdyRoundTripper) NewConnection(resp *http.Response) (httpstream.Connec responseError = "unable to read error from server response" } else { if obj, err := api.Scheme.Decode(responseErrorBytes); err == nil { - if status, ok := obj.(*api.Status); ok { + if status, ok := obj.(*unversioned.Status); ok { return nil, &apierrors.StatusError{ErrStatus: *status} } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/io.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/io.go index fdaad2263a80..70bc605f5e34 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/io.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/io.go @@ -37,9 +37,9 @@ func LoadPodFromFile(filePath string) (*api.Pod, error) { if len(podDef) == 0 { return nil, fmt.Errorf("file was empty: %s", filePath) } - pod := &api.Pod{} - if err := latest.Codec.DecodeInto(podDef, pod); err != nil { + + if err := latest.GroupOrDie("").Codec.DecodeInto(podDef, pod); err != nil { return nil, fmt.Errorf("failed decoding file: %v", err) } return pod, nil @@ -50,7 +50,7 @@ func SavePodToFile(pod *api.Pod, filePath string, perm os.FileMode) error { if filePath == "" { return fmt.Errorf("file path not specified") } - data, err := latest.Codec.Encode(pod) + data, err := latest.GroupOrDie("").Codec.Encode(pod) if err != nil { return fmt.Errorf("failed encoding pod: %v", err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/io_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/io_test.go index 105bb5c5ee94..d6bd3f1f8ac9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/io_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/io_test.go @@ -14,33 +14,35 @@ See the License for the specific language governing permissions and limitations under the License. */ -package io +package io_test import ( "fmt" + "os" + "testing" + "github.com/pborman/uuid" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/util/io" "k8s.io/kubernetes/pkg/volume" - "os" - "testing" ) func TestSavePodToFile(t *testing.T) { pod := volume.NewPersistentVolumeRecyclerPodTemplate() // sets all default values on a pod for equality comparison after decoding from file - encoded, err := latest.Codec.Encode(pod) - latest.Codec.DecodeInto(encoded, pod) + encoded, err := latest.GroupOrDie("").Codec.Encode(pod) + latest.GroupOrDie("").Codec.DecodeInto(encoded, pod) path := fmt.Sprintf("/tmp/kube-io-test-%s", uuid.New()) defer os.Remove(path) - if err := SavePodToFile(pod, path, 777); err != nil { + if err := io.SavePodToFile(pod, path, 777); err != nil { t.Fatalf("failed to save pod to file: %v", err) } - podFromFile, err := LoadPodFromFile(path) + podFromFile, err := io.LoadPodFromFile(path) if err != nil { t.Fatalf("failed to load pod from file: %v", err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/writer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/writer.go new file mode 100644 index 000000000000..7e0217266b24 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/io/writer.go @@ -0,0 +1,77 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 io + +import ( + "fmt" + "io/ioutil" + "os" + "os/exec" + + "github.com/golang/glog" +) + +// Writer is an interface which allows to write data to a file. +type Writer interface { + WriteFile(filename string, data []byte, perm os.FileMode) error +} + +// StdWriter implements Writer interface and uses standard libraries +// for writing data to files. +type StdWriter struct { +} + +func (writer *StdWriter) WriteFile(filename string, data []byte, perm os.FileMode) error { + return ioutil.WriteFile(filename, data, perm) +} + +// Alternative implementation of Writer interface that allows writing data to file +// using nsenter command. +// If a program (e.g. kubelet) runs in a container it may want to write data to +// a mounted device. Since in Docker, mount propagation mode is set to private, +// it will not see the mounted device in its own namespace. To work around this +// limitaion one has to first enter hosts namespace (by using 'nsenter') and only +// then write data. +type NsenterWriter struct { +} + +func (writer *NsenterWriter) WriteFile(filename string, data []byte, perm os.FileMode) error { + cmd := "nsenter" + base_args := []string{ + "--mount=/rootfs/proc/1/ns/mnt", + "--", + } + + echo_args := append(base_args, "sh", "-c", + fmt.Sprintf("echo %q | cat > %s", data, filename)) + glog.V(5).Infof("Command to write data to file: %v %v", cmd, echo_args) + outputBytes, err := exec.Command(cmd, echo_args...).CombinedOutput() + if err != nil { + glog.Errorf("Output from writing to %q: %v", filename, string(outputBytes)) + return err + } + + chmod_args := append(base_args, "chmod", fmt.Sprintf("%o", perm), filename) + glog.V(5).Infof("Command to change permissions to file: %v %v", cmd, chmod_args) + outputBytes, err = exec.Command(cmd, chmod_args...).CombinedOutput() + if err != nil { + glog.Errorf("Output from chmod command: %v", string(outputBytes)) + return err + } + + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/iptables/iptables.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/iptables/iptables.go index ab0f0e71ff5b..e2fa00890c66 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/iptables/iptables.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/iptables/iptables.go @@ -25,7 +25,9 @@ import ( "sync" "github.com/coreos/go-semver/semver" + godbus "github.com/godbus/dbus" "github.com/golang/glog" + utildbus "k8s.io/kubernetes/pkg/util/dbus" utilexec "k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/sets" ) @@ -64,6 +66,10 @@ type Interface interface { Restore(table Table, data []byte, flush FlushFlag, counters RestoreCountersFlag) error // RestoreAll is the same as Restore except that no table is specified. RestoreAll(data []byte, flush FlushFlag, counters RestoreCountersFlag) error + // AddReloadFunc adds a function to call on iptables reload + AddReloadFunc(reloadFunc func()) + // Destroy cleans up resources used by the Interface + Destroy() } type Protocol byte @@ -100,7 +106,7 @@ type RestoreCountersFlag bool const RestoreCounters RestoreCountersFlag = true const NoRestoreCounters RestoreCountersFlag = false -// Option flag for Restore +// Option flag for Flush type FlushFlag bool const FlushTables FlushFlag = true @@ -118,24 +124,66 @@ const MinWait2Version = "1.4.22" type runner struct { mu sync.Mutex exec utilexec.Interface + dbus utildbus.Interface protocol Protocol hasCheck bool waitFlag []string + + reloadFuncs []func() + signal chan *godbus.Signal } // New returns a new Interface which will exec iptables. -func New(exec utilexec.Interface, protocol Protocol) Interface { +func New(exec utilexec.Interface, dbus utildbus.Interface, protocol Protocol) Interface { vstring, err := GetIptablesVersionString(exec) if err != nil { glog.Warningf("Error checking iptables version, assuming version at least %s: %v", MinCheckVersion, err) vstring = MinCheckVersion } - return &runner{ + runner := &runner{ exec: exec, + dbus: dbus, protocol: protocol, hasCheck: getIptablesHasCheckCommand(vstring), waitFlag: getIptablesWaitFlag(vstring), } + runner.connectToFirewallD() + return runner +} + +// Destroy is part of Interface. +func (runner *runner) Destroy() { + if runner.signal != nil { + runner.signal <- nil + } +} + +const ( + firewalldName = "org.fedoraproject.FirewallD1" + firewalldPath = "/org/fedoraproject/FirewallD1" + firewalldInterface = "org.fedoraproject.FirewallD1" +) + +// Connects to D-Bus and listens for FirewallD start/restart. (On non-FirewallD-using +// systems, this is effectively a no-op; we listen for the signals, but they will never be +// emitted, so reload() will never be called.) +func (runner *runner) connectToFirewallD() { + bus, err := runner.dbus.SystemBus() + if err != nil { + glog.V(1).Infof("Could not connect to D-Bus system bus: %s", err) + return + } + + rule := fmt.Sprintf("type='signal',sender='%s',path='%s',interface='%s',member='Reloaded'", firewalldName, firewalldPath, firewalldInterface) + bus.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule) + + rule = fmt.Sprintf("type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged',path='/org/freedesktop/DBus',sender='org.freedesktop.DBus',arg0='%s'", firewalldName) + bus.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule) + + runner.signal = make(chan *godbus.Signal, 10) + bus.Signal(runner.signal) + + go runner.dbusSignalHandler(bus) } // EnsureChain is part of Interface. @@ -178,7 +226,7 @@ func (runner *runner) DeleteChain(table Table, chain Chain) error { runner.mu.Lock() defer runner.mu.Unlock() - // TODO: we could call iptable -S first, ignore the output and check for non-zero return (more like DeleteRule) + // TODO: we could call iptables -S first, ignore the output and check for non-zero return (more like DeleteRule) out, err := runner.run(opDeleteChain, fullArgs) if err != nil { return fmt.Errorf("error deleting chain %q: %v: %s", chain, err, out) @@ -472,3 +520,50 @@ func GetIptablesVersionString(exec utilexec.Interface) (string, error) { } return match[1], nil } + +// goroutine to listen for D-Bus signals +func (runner *runner) dbusSignalHandler(bus utildbus.Connection) { + firewalld := bus.Object(firewalldName, firewalldPath) + + for s := range runner.signal { + if s == nil { + // Unregister + bus.Signal(runner.signal) + return + } + + switch s.Name { + case "org.freedesktop.DBus.NameOwnerChanged": + name := s.Body[0].(string) + new_owner := s.Body[2].(string) + + if name != firewalldName || len(new_owner) == 0 { + continue + } + + // FirewallD startup (specifically the part where it deletes + // all existing iptables rules) may not yet be complete when + // we get this signal, so make a dummy request to it to + // synchronize. + firewalld.Call(firewalldInterface+".getDefaultZone", 0) + + runner.reload() + case firewalldInterface + ".Reloaded": + runner.reload() + } + } +} + +// AddReloadFunc is part of Interface +func (runner *runner) AddReloadFunc(reloadFunc func()) { + runner.reloadFuncs = append(runner.reloadFuncs, reloadFunc) +} + +// runs all reload funcs to re-sync iptables rules +func (runner *runner) reload() { + glog.V(1).Infof("reloading iptables rules") + + for _, f := range runner.reloadFuncs { + f() + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/iptables/iptables_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/iptables/iptables_test.go index c8f7c1a100ea..8bef165957b3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/iptables/iptables_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/iptables/iptables_test.go @@ -19,7 +19,9 @@ package iptables import ( "strings" "testing" + "time" + "k8s.io/kubernetes/pkg/util/dbus" "k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/sets" ) @@ -55,7 +57,8 @@ func testEnsureChain(t *testing.T, protocol Protocol) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, protocol) + runner := New(&fexec, dbus.NewFake(nil, nil), protocol) + defer runner.Destroy() // Success. exists, err := runner.EnsureChain(TableNAT, Chain("FOOBAR")) if err != nil { @@ -112,7 +115,8 @@ func TestFlushChain(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() // Success. err := runner.FlushChain(TableNAT, Chain("FOOBAR")) if err != nil { @@ -149,7 +153,8 @@ func TestDeleteChain(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() // Success. err := runner.DeleteChain(TableNAT, Chain("FOOBAR")) if err != nil { @@ -185,7 +190,8 @@ func TestEnsureRuleAlreadyExists(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() exists, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123") if err != nil { t.Errorf("expected success, got %v", err) @@ -221,7 +227,8 @@ func TestEnsureRuleNew(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() exists, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123") if err != nil { t.Errorf("expected success, got %v", err) @@ -254,7 +261,8 @@ func TestEnsureRuleErrorChecking(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() _, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123") if err == nil { t.Errorf("expected failure") @@ -284,7 +292,8 @@ func TestEnsureRuleErrorCreating(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() _, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123") if err == nil { t.Errorf("expected failure") @@ -311,7 +320,8 @@ func TestDeleteRuleAlreadyExists(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123") if err != nil { t.Errorf("expected success, got %v", err) @@ -344,7 +354,8 @@ func TestDeleteRuleNew(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123") if err != nil { t.Errorf("expected success, got %v", err) @@ -374,7 +385,8 @@ func TestDeleteRuleErrorChecking(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123") if err == nil { t.Errorf("expected failure") @@ -404,7 +416,8 @@ func TestDeleteRuleErrorCreating(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123") if err == nil { t.Errorf("expected failure") @@ -565,7 +578,8 @@ func TestWaitFlagUnavailable(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() err := runner.DeleteChain(TableNAT, Chain("FOOBAR")) if err != nil { t.Errorf("expected success, got %v", err) @@ -593,7 +607,8 @@ func TestWaitFlagOld(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() err := runner.DeleteChain(TableNAT, Chain("FOOBAR")) if err != nil { t.Errorf("expected success, got %v", err) @@ -624,7 +639,8 @@ func TestWaitFlagNew(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec, ProtocolIpv4) + runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4) + defer runner.Destroy() err := runner.DeleteChain(TableNAT, Chain("FOOBAR")) if err != nil { t.Errorf("expected success, got %v", err) @@ -639,3 +655,114 @@ func TestWaitFlagNew(t *testing.T) { t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1]) } } + +func TestReload(t *testing.T) { + dbusConn := dbus.NewFakeConnection() + dbusConn.SetBusObject(func(method string, args ...interface{}) ([]interface{}, error) { return nil, nil }) + dbusConn.AddObject(firewalldName, firewalldPath, func(method string, args ...interface{}) ([]interface{}, error) { return nil, nil }) + fdbus := dbus.NewFake(dbusConn, nil) + + reloaded := make(chan bool, 2) + + fcmd := exec.FakeCmd{ + CombinedOutputScript: []exec.FakeCombinedOutputAction{ + // iptables version check + func() ([]byte, error) { return []byte("iptables v1.4.22"), nil }, + + // first reload + // EnsureChain + func() ([]byte, error) { return []byte{}, nil }, + // EnsureRule abc check + func() ([]byte, error) { return []byte{}, &exec.FakeExitError{1} }, + // EnsureRule abc + func() ([]byte, error) { return []byte{}, nil }, + + // second reload + // EnsureChain + func() ([]byte, error) { return []byte{}, nil }, + // EnsureRule abc check + func() ([]byte, error) { return []byte{}, &exec.FakeExitError{1} }, + // EnsureRule abc + func() ([]byte, error) { return []byte{}, nil }, + }, + } + fexec := exec.FakeExec{ + CommandScript: []exec.FakeCommandAction{ + func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, + func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, + func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, + func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, + func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, + func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, + func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, + }, + } + + runner := New(&fexec, fdbus, ProtocolIpv4) + defer runner.Destroy() + + runner.AddReloadFunc(func() { + exists, err := runner.EnsureChain(TableNAT, Chain("FOOBAR")) + if err != nil { + t.Errorf("expected success, got %v", err) + } + if exists { + t.Errorf("expected exists = false") + } + reloaded <- true + }) + + runner.AddReloadFunc(func() { + exists, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123") + if err != nil { + t.Errorf("expected success, got %v", err) + } + if exists { + t.Errorf("expected exists = false") + } + reloaded <- true + }) + + dbusConn.EmitSignal("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", firewalldName, "", ":1.1") + <-reloaded + <-reloaded + + if fcmd.CombinedOutputCalls != 4 { + t.Errorf("expected 4 CombinedOutput() calls total, got %d", fcmd.CombinedOutputCalls) + } + if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-t", "nat", "-N", "FOOBAR") { + t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1]) + } + if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") { + t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2]) + } + if !sets.NewString(fcmd.CombinedOutputLog[3]...).HasAll("iptables", "-t", "nat", "-A", "OUTPUT", "abc", "123") { + t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[3]) + } + + go func() { time.Sleep(time.Second / 100); reloaded <- true }() + dbusConn.EmitSignal(firewalldName, firewalldPath, firewalldInterface, "DefaultZoneChanged", "public") + dbusConn.EmitSignal("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", "io.k8s.Something", "", ":1.1") + <-reloaded + + if fcmd.CombinedOutputCalls != 4 { + t.Errorf("Incorrect signal caused a reload") + } + + dbusConn.EmitSignal(firewalldName, firewalldPath, firewalldInterface, "Reloaded") + <-reloaded + <-reloaded + + if fcmd.CombinedOutputCalls != 7 { + t.Errorf("expected 7 CombinedOutput() calls total, got %d", fcmd.CombinedOutputCalls) + } + if !sets.NewString(fcmd.CombinedOutputLog[4]...).HasAll("iptables", "-t", "nat", "-N", "FOOBAR") { + t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[4]) + } + if !sets.NewString(fcmd.CombinedOutputLog[5]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") { + t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[5]) + } + if !sets.NewString(fcmd.CombinedOutputLog[6]...).HasAll("iptables", "-t", "nat", "-A", "OUTPUT", "abc", "123") { + t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[6]) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/jsonpath/jsonpath_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/jsonpath/jsonpath_test.go index 6a79d9fdfc69..3345aee85b6f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/jsonpath/jsonpath_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/jsonpath/jsonpath_test.go @@ -190,8 +190,8 @@ func TestJSONInput(t *testing.T) { testJSONPath(pointsTests, t) } -// TestKubenates tests some use cases from kubenates -func TestKubenates(t *testing.T) { +// TestKubernetes tests some use cases from kubernetes +func TestKubernetes(t *testing.T) { var input = []byte(`{ "kind": "List", "items":[ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/limitwriter/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/limitwriter/doc.go new file mode 100644 index 000000000000..7daff9c079a6 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/limitwriter/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 limitwriter provides a writer that only allows a certain number of bytes to be +// written. +package limitwriter diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/limitwriter/limitwriter.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/limitwriter/limitwriter.go new file mode 100644 index 000000000000..88890a9fa249 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/limitwriter/limitwriter.go @@ -0,0 +1,53 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 limitwriter + +import ( + "errors" + "io" +) + +// New creates a writer that is limited to writing at most n bytes to w. This writer is not +// thread safe. +func New(w io.Writer, n int64) io.Writer { + return &limitWriter{ + w: w, + n: n, + } +} + +// ErrMaximumWrite is returned when all bytes have been written. +var ErrMaximumWrite = errors.New("maximum write") + +type limitWriter struct { + w io.Writer + n int64 +} + +func (w *limitWriter) Write(p []byte) (n int, err error) { + if int64(len(p)) > w.n { + p = p[:w.n] + } + if len(p) > 0 { + n, err = w.w.Write(p) + w.n -= int64(n) + } + if w.n == 0 { + err = ErrMaximumWrite + } + return +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/mount/mount.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/mount/mount.go index 83a8b0e7a60f..ac5f9a57a9f1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/mount/mount.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/mount/mount.go @@ -75,7 +75,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, // Try to mount the disk err := mounter.Interface.Mount(source, target, fstype, options) if err != nil { - // It is possible that this disk is not formatted. Double check using 'file' + // It is possible that this disk is not formatted. Double check using diskLooksUnformatted notFormatted, err := mounter.diskLooksUnformatted(source) if err == nil && notFormatted { // Disk is unformatted so format it. @@ -96,11 +96,12 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, return err } -// diskLooksUnformatted uses 'file' to see if the given disk is unformated +// diskLooksUnformatted uses 'lsblk' to see if the given disk is unformated func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) { - args := []string{"-L", "--special-files", disk} - cmd := mounter.Runner.Command("file", args...) + args := []string{"-nd", "-o", "FSTYPE", disk} + cmd := mounter.Runner.Command("lsblk", args...) dataOut, err := cmd.CombinedOutput() + output := strings.TrimSpace(string(dataOut)) // TODO (#13212): check if this disk has partitions and return false, and // an error if so. @@ -109,7 +110,7 @@ func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, erro return false, err } - return !strings.Contains(string(dataOut), "filesystem"), nil + return output == "", nil } // New returns a mount.Interface for the current system. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/mount/safe_format_and_mount_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/mount/safe_format_and_mount_test.go index 9833f7ba4f88..26a23ae6e680 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/mount/safe_format_and_mount_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/mount/safe_format_and_mount_test.go @@ -65,7 +65,7 @@ func TestSafeFormatAndMount(t *testing.T) { fstype: "ext4", mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'")}, execScripts: []ExecArgs{ - {"file", []string{"-L", "--special-files", "/dev/foo"}, "ext4 filesystem", nil}, + {"lsblk", []string{"-nd", "-o", "FSTYPE", "/dev/foo"}, "ext4", nil}, }, expectedError: fmt.Errorf("unknown filesystem type '(null)'"), }, @@ -73,7 +73,7 @@ func TestSafeFormatAndMount(t *testing.T) { fstype: "ext4", mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'")}, execScripts: []ExecArgs{ - {"file", []string{"-L", "--special-files", "/dev/foo"}, "data", nil}, + {"lsblk", []string{"-nd", "-o", "FSTYPE", "/dev/foo"}, "", nil}, {"mkfs.ext4", []string{"-E", "lazy_itable_init=0,lazy_journal_init=0", "-F", "/dev/foo"}, "", fmt.Errorf("formatting failed")}, }, expectedError: fmt.Errorf("formatting failed"), @@ -82,7 +82,7 @@ func TestSafeFormatAndMount(t *testing.T) { fstype: "ext4", mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), fmt.Errorf("Still cannot mount")}, execScripts: []ExecArgs{ - {"file", []string{"-L", "--special-files", "/dev/foo"}, "data", nil}, + {"lsblk", []string{"-nd", "-o", "FSTYPE", "/dev/foo"}, "", nil}, {"mkfs.ext4", []string{"-E", "lazy_itable_init=0,lazy_journal_init=0", "-F", "/dev/foo"}, "", nil}, }, expectedError: fmt.Errorf("Still cannot mount"), @@ -91,7 +91,7 @@ func TestSafeFormatAndMount(t *testing.T) { fstype: "ext4", mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), nil}, execScripts: []ExecArgs{ - {"file", []string{"-L", "--special-files", "/dev/foo"}, "data", nil}, + {"lsblk", []string{"-nd", "-o", "FSTYPE", "/dev/foo"}, "", nil}, {"mkfs.ext4", []string{"-E", "lazy_itable_init=0,lazy_journal_init=0", "-F", "/dev/foo"}, "", nil}, }, expectedError: nil, @@ -100,7 +100,7 @@ func TestSafeFormatAndMount(t *testing.T) { fstype: "ext3", mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), nil}, execScripts: []ExecArgs{ - {"file", []string{"-L", "--special-files", "/dev/foo"}, "data", nil}, + {"lsblk", []string{"-nd", "-o", "FSTYPE", "/dev/foo"}, "", nil}, {"mkfs.ext3", []string{"-E", "lazy_itable_init=0,lazy_journal_init=0", "-F", "/dev/foo"}, "", nil}, }, expectedError: nil, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/net.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/net.go deleted file mode 100644 index 1b5f3855e11f..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/net.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "fmt" - "net" - "strings" -) - -// IP adapts net.IP for use as a flag. -type IP net.IP - -func (ip IP) String() string { - return net.IP(ip).String() -} - -func (ip *IP) Set(value string) error { - *ip = IP(net.ParseIP(strings.TrimSpace(value))) - if *ip == nil { - return fmt.Errorf("invalid IP address: '%s'", value) - } - return nil -} - -func (*IP) Type() string { - return "ip" -} - -// IPNet adapts net.IPNet for use as a flag. -type IPNet net.IPNet - -func (ipnet IPNet) String() string { - n := net.IPNet(ipnet) - return n.String() -} - -func (ipnet *IPNet) Set(value string) error { - _, n, err := net.ParseCIDR(strings.TrimSpace(value)) - if err != nil { - return err - } - *ipnet = IPNet(*n) - return nil -} - -func (*IPNet) Type() string { - return "ipNet" -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom.go index b3400bda1807..c6d563ab2323 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom.go @@ -19,8 +19,8 @@ package oom // This is a struct instead of an interface to allow injection of process ID listers and // applying OOM score in tests. // TODO: make this an interface, and inject a mock ioutil struct for testing. -type OomAdjuster struct { +type OOMAdjuster struct { pidLister func(cgroupName string) ([]int, error) - ApplyOomScoreAdj func(pid int, oomScoreAdj int) error - ApplyOomScoreAdjContainer func(cgroupName string, oomScoreAdj, maxTries int) error + ApplyOOMScoreAdj func(pid int, oomScoreAdj int) error + ApplyOOMScoreAdjContainer func(cgroupName string, oomScoreAdj, maxTries int) error } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_fake.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_fake.go index e28d3a6d9828..bd0bf6f4558a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_fake.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_fake.go @@ -16,19 +16,20 @@ limitations under the License. package oom -type FakeOomAdjuster struct{} +type FakeOOMAdjuster struct{} -func NewFakeOomAdjuster() *OomAdjuster { - return &OomAdjuster{ - ApplyOomScoreAdj: fakeApplyOomScoreAdj, - ApplyOomScoreAdjContainer: fakeApplyOomScoreAdjContainer, +func NewFakeOOMAdjuster() *OOMAdjuster { + return &OOMAdjuster{ + pidLister: func(cgroupName string) ([]int, error) { return make([]int, 0), nil }, + ApplyOOMScoreAdj: fakeApplyOOMScoreAdj, + ApplyOOMScoreAdjContainer: fakeApplyOOMScoreAdjContainer, } } -func fakeApplyOomScoreAdj(pid int, oomScoreAdj int) error { +func fakeApplyOOMScoreAdj(pid int, oomScoreAdj int) error { return nil } -func fakeApplyOomScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error { +func fakeApplyOOMScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error { return nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_linux.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_linux.go index 1e765828b69b..c579d6805c11 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_linux.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_linux.go @@ -29,12 +29,12 @@ import ( "github.com/golang/glog" ) -func NewOomAdjuster() *OomAdjuster { - oomAdjuster := &OomAdjuster{ +func NewOOMAdjuster() *OOMAdjuster { + oomAdjuster := &OOMAdjuster{ pidLister: getPids, - ApplyOomScoreAdj: applyOomScoreAdj, + ApplyOOMScoreAdj: applyOOMScoreAdj, } - oomAdjuster.ApplyOomScoreAdjContainer = oomAdjuster.applyOomScoreAdjContainer + oomAdjuster.ApplyOOMScoreAdjContainer = oomAdjuster.applyOOMScoreAdjContainer return oomAdjuster } @@ -48,7 +48,7 @@ func getPids(cgroupName string) ([]int, error) { } // Writes 'value' to /proc//oom_score_adj. PID = 0 means self -func applyOomScoreAdj(pid int, oomScoreAdj int) error { +func applyOOMScoreAdj(pid int, oomScoreAdj int) error { if pid < 0 { return fmt.Errorf("invalid PID %d specified for oom_score_adj", pid) } @@ -79,7 +79,7 @@ func applyOomScoreAdj(pid int, oomScoreAdj int) error { // Writes 'value' to /proc//oom_score_adj for all processes in cgroup cgroupName. // Keeps trying to write until the process list of the cgroup stabilizes, or until maxTries tries. -func (oomAdjuster *OomAdjuster) applyOomScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error { +func (oomAdjuster *OOMAdjuster) applyOOMScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error { adjustedProcessSet := make(map[int]bool) for i := 0; i < maxTries; i++ { continueAdjusting := false @@ -93,7 +93,7 @@ func (oomAdjuster *OomAdjuster) applyOomScoreAdjContainer(cgroupName string, oom for _, pid := range pidList { if !adjustedProcessSet[pid] { continueAdjusting = true - if err = oomAdjuster.ApplyOomScoreAdj(pid, oomScoreAdj); err == nil { + if err = oomAdjuster.ApplyOOMScoreAdj(pid, oomScoreAdj); err == nil { adjustedProcessSet[pid] = true } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_linux_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_linux_test.go index fbe58bddc4fa..c3a850d91bed 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_linux_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_linux_test.go @@ -38,63 +38,63 @@ func sequenceToPidLister(pidListSequence [][]int) func(string) ([]int, error) { } } -// Tests that applyOomScoreAdjContainer correctly applies OOM scores to relevant processes, or +// Tests that applyOOMScoreAdjContainer correctly applies OOM scores to relevant processes, or // returns the right error. -func applyOomScoreAdjContainerTester(pidListSequence [][]int, maxTries int, appliedPids []int, expectedError bool, t *testing.T) { - pidOoms := make(map[int]bool) +func applyOOMScoreAdjContainerTester(pidListSequence [][]int, maxTries int, appliedPids []int, expectedError bool, t *testing.T) { + pidOOMs := make(map[int]bool) - // Mock ApplyOomScoreAdj and pidLister. - oomAdjuster := NewOomAdjuster() - oomAdjuster.ApplyOomScoreAdj = func(pid int, oomScoreAdj int) error { - pidOoms[pid] = true + // Mock ApplyOOMScoreAdj and pidLister. + oomAdjuster := NewOOMAdjuster() + oomAdjuster.ApplyOOMScoreAdj = func(pid int, oomScoreAdj int) error { + pidOOMs[pid] = true return nil } oomAdjuster.pidLister = sequenceToPidLister(pidListSequence) - err := oomAdjuster.ApplyOomScoreAdjContainer("", 100, maxTries) + err := oomAdjuster.ApplyOOMScoreAdjContainer("", 100, maxTries) // Check error value. if expectedError && err == nil { - t.Errorf("Expected error %+v when running ApplyOomScoreAdjContainer but got no error", expectedError) + t.Errorf("Expected error %+v when running ApplyOOMScoreAdjContainer but got no error", expectedError) return } else if !expectedError && err != nil { - t.Errorf("Expected no error but got error %+v when running ApplyOomScoreAdjContainer", err) + t.Errorf("Expected no error but got error %+v when running ApplyOOMScoreAdjContainer", err) return } else if err != nil { return } // Check that OOM scores were applied to the right processes. - if len(appliedPids) != len(pidOoms) { + if len(appliedPids) != len(pidOOMs) { t.Errorf("Applied OOM scores to incorrect number of processes") return } for _, pid := range appliedPids { - if !pidOoms[pid] { + if !pidOOMs[pid] { t.Errorf("Failed to apply OOM scores to process %d", pid) } } } -func TestOomScoreAdjContainer(t *testing.T) { +func TestOOMScoreAdjContainer(t *testing.T) { pidListSequenceEmpty := [][]int{} - applyOomScoreAdjContainerTester(pidListSequenceEmpty, 3, nil, true, t) + applyOOMScoreAdjContainerTester(pidListSequenceEmpty, 3, nil, true, t) pidListSequence1 := [][]int{ {1, 2}, } - applyOomScoreAdjContainerTester(pidListSequence1, 1, nil, true, t) - applyOomScoreAdjContainerTester(pidListSequence1, 2, []int{1, 2}, false, t) - applyOomScoreAdjContainerTester(pidListSequence1, 3, []int{1, 2}, false, t) + applyOOMScoreAdjContainerTester(pidListSequence1, 1, nil, true, t) + applyOOMScoreAdjContainerTester(pidListSequence1, 2, []int{1, 2}, false, t) + applyOOMScoreAdjContainerTester(pidListSequence1, 3, []int{1, 2}, false, t) pidListSequence3 := [][]int{ {1, 2}, {1, 2, 4, 5}, {2, 1, 4, 5, 3}, } - applyOomScoreAdjContainerTester(pidListSequence3, 1, nil, true, t) - applyOomScoreAdjContainerTester(pidListSequence3, 2, nil, true, t) - applyOomScoreAdjContainerTester(pidListSequence3, 3, nil, true, t) - applyOomScoreAdjContainerTester(pidListSequence3, 4, []int{1, 2, 3, 4, 5}, false, t) + applyOOMScoreAdjContainerTester(pidListSequence3, 1, nil, true, t) + applyOOMScoreAdjContainerTester(pidListSequence3, 2, nil, true, t) + applyOOMScoreAdjContainerTester(pidListSequence3, 3, nil, true, t) + applyOOMScoreAdjContainerTester(pidListSequence3, 4, []int{1, 2, 3, 4, 5}, false, t) pidListSequenceLag := [][]int{ {}, @@ -104,7 +104,7 @@ func TestOomScoreAdjContainer(t *testing.T) { {1, 2, 4, 5}, } for i := 1; i < 5; i++ { - applyOomScoreAdjContainerTester(pidListSequenceLag, i, nil, true, t) + applyOOMScoreAdjContainerTester(pidListSequenceLag, i, nil, true, t) } - applyOomScoreAdjContainerTester(pidListSequenceLag, 6, []int{1, 2, 4, 5}, false, t) + applyOOMScoreAdjContainerTester(pidListSequenceLag, 6, []int{1, 2, 4, 5}, false, t) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go index f44d527f88fc..9c4473f7e093 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go @@ -24,17 +24,17 @@ import ( var unsupportedErr = errors.New("setting OOM scores is unsupported in this build") -func NewOomAdjuster() *OomAdjuster { - return &OomAdjuster{ - ApplyOomScoreAdj: unsupportedApplyOomScoreAdj, - ApplyOomScoreAdjContainer: unsupportedApplyOomScoreAdjContainer, +func NewOOMAdjuster() *OOMAdjuster { + return &OOMAdjuster{ + ApplyOOMScoreAdj: unsupportedApplyOOMScoreAdj, + ApplyOOMScoreAdjContainer: unsupportedApplyOOMScoreAdjContainer, } } -func unsupportedApplyOomScoreAdj(pid int, oomScoreAdj int) error { +func unsupportedApplyOOMScoreAdj(pid int, oomScoreAdj int) error { return unsupportedErr } -func unsupportedApplyOomScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error { +func unsupportedApplyOOMScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error { return unsupportedErr } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/proxy/transport.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/proxy/transport.go index 6540c7340b66..b33657845246 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/proxy/transport.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/proxy/transport.go @@ -143,8 +143,11 @@ func (t *Transport) rewriteURL(targetURL string, sourceURL *url.URL) string { url.Scheme = t.Scheme url.Host = t.Host origPath := url.Path + // Do not rewrite URL if the sourceURL already contains the necessary prefix. + if strings.HasPrefix(url.Path, t.PathPrepend) { + return url.String() + } url.Path = path.Join(t.PathPrepend, url.Path) - if strings.HasSuffix(origPath, "/") { // Add back the trailing slash, which was stripped by path.Join(). url.Path += "/" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/proxy/transport_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/proxy/transport_test.go index 4f5fb01ced97..0e444f9ab5d9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/proxy/transport_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/proxy/transport_test.go @@ -150,6 +150,14 @@ func TestProxyTransport(t *testing.T) { redirectWant: "http://example.com/redirected/target/", forwardedURI: "/proxy/minion/minion1:10250/redirect", }, + "source contains the redirect already": { + input: `
      kubelet.loggoogle.log
      `, + sourceURL: "http://foo.com/logs/log.log", + transport: testTransport, + output: `
      kubelet.loggoogle.log
      `, + contentType: "text/html", + forwardedURI: "/proxy/minion/minion1:10250/logs/log.log", + }, } testItem := func(name string, item *Item) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/resource_container_linux.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/resource_container_linux.go index 2bc73b3bff47..161de74a70b3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/resource_container_linux.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/resource_container_linux.go @@ -20,6 +20,7 @@ package util import ( "os" + "syscall" "github.com/docker/libcontainer/cgroups/fs" "github.com/docker/libcontainer/configs" @@ -39,3 +40,7 @@ func RunInResourceContainer(containerName string) error { return manager.Apply(os.Getpid()) } + +func ApplyRLimitForSelf(maxOpenFiles uint64) { + syscall.Setrlimit(syscall.RLIMIT_NOFILE, &syscall.Rlimit{Max: maxOpenFiles, Cur: maxOpenFiles}) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/resource_container_unsupported.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/resource_container_unsupported.go index c470e300ee9d..a8ee51927b0c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/resource_container_unsupported.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/resource_container_unsupported.go @@ -25,3 +25,7 @@ import ( func RunInResourceContainer(containerName string) error { return errors.New("resource-only containers unsupported in this platform") } + +func ApplyRLimitForSelf(maxOpenFiles uint64) error { + return errors.New("SetRLimit unsupported in this platform") +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/sets/set.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/sets/set.go index 377d7de1eb09..5ac72017ef95 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/sets/set.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/sets/set.go @@ -61,13 +61,13 @@ func (s String) Delete(items ...string) { } } -// Has returns true iff item is contained in the set. +// Has returns true if and only if item is contained in the set. func (s String) Has(item string) bool { _, contained := s[item] return contained } -// HasAll returns true iff all items are contained in the set. +// HasAll returns true if and only if all items are contained in the set. func (s String) HasAll(items ...string) bool { for _, item := range items { if !s.Has(item) { @@ -144,7 +144,7 @@ func (s1 String) Intersection(s2 String) String { return result } -// IsSuperset returns true iff s1 is a superset of s2. +// IsSuperset returns true if and only if s1 is a superset of s2. func (s1 String) IsSuperset(s2 String) bool { for item := range s2 { if !s1.Has(item) { @@ -154,7 +154,7 @@ func (s1 String) IsSuperset(s2 String) bool { return true } -// Equal returns true iff s1 is equal (as a set) to s2. +// Equal returns true if and only if s1 is equal (as a set) to s2. // Two sets are equal if their membership is identical. // (In practice, this means same elements, order doesn't matter) func (s1 String) Equal(s2 String) bool { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/slice/slice.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/slice/slice.go index a9ee3ea62eaa..61657ca44adc 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/slice/slice.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/slice/slice.go @@ -18,8 +18,9 @@ limitations under the License. package slice import ( - utilrand "k8s.io/kubernetes/pkg/util/rand" "sort" + + utilrand "k8s.io/kubernetes/pkg/util/rand" ) // CopyStrings copies the contents of the specified string slice diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/ssh_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/ssh_test.go index df53b648bb01..74dc8a82b6d9 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/ssh_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/ssh_test.go @@ -18,15 +18,15 @@ package util import ( "fmt" + "io" "net" + "os" "reflect" + "strings" "testing" "github.com/golang/glog" "golang.org/x/crypto/ssh" - "io" - "os" - "strings" ) type testSSHServer struct { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/strategicpatch/patch.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/strategicpatch/patch.go index 34f6a70713ce..0ff10ec78754 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/strategicpatch/patch.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/strategicpatch/patch.go @@ -30,32 +30,105 @@ import ( // certain fields with metadata that indicates whether the elements of JSON // lists should be merged or replaced. // -// For more information, see the PATCH section of docs/api-conventions.md. +// For more information, see the PATCH section of docs/devel/api-conventions.md. // // Some of the content of this package was borrowed with minor adaptations from // evanphx/json-patch and openshift/origin. -const specialKey = "$patch" -const specialValue = "delete" +const ( + directiveMarker = "$patch" + deleteDirective = "delete" + replaceDirective = "replace" + mergeDirective = "merge" +) + +// IsPreconditionFailed returns true if the provided error indicates +// a precondition failed. +func IsPreconditionFailed(err error) bool { + _, ok := err.(errPreconditionFailed) + return ok +} + +type errPreconditionFailed struct { + message string +} + +func newErrPreconditionFailed(target map[string]interface{}) errPreconditionFailed { + s := fmt.Sprintf("precondition failed for: %v", target) + return errPreconditionFailed{s} +} + +func (err errPreconditionFailed) Error() string { + return err.message +} + +type errConflict struct { + message string +} + +func newErrConflict(patch, current []byte) errConflict { + s := fmt.Sprintf("patch:\n%s\nconflicts with current:\n%s\n", patch, current) + return errConflict{s} +} + +func (err errConflict) Error() string { + return err.message +} + +// IsConflict returns true if the provided error indicates +// a conflict between the patch and the current configuration. +func IsConflict(err error) bool { + _, ok := err.(errConflict) + return ok +} var errBadJSONDoc = fmt.Errorf("Invalid JSON document") var errNoListOfLists = fmt.Errorf("Lists of lists are not supported") -// CreateStrategicMergePatch creates a patch that can be passed to StrategicMergePatch. -// The original and modified documents must be passed to the method as json encoded content. -// It will return a mergeable json document with differences from original to modified, or an error -// if either of the two documents is invalid. +// The following code is adapted from github.com/openshift/origin/pkg/util/jsonmerge. +// Instead of defining a Delta that holds an original, a patch and a set of preconditions, +// the reconcile method accepts a set of preconditions as an argument. + +// PreconditionFunc asserts that an incompatible change is not present within a patch. +type PreconditionFunc func(interface{}) bool + +// RequireKeyUnchanged returns a precondition function that fails if the provided key +// is present in the patch (indicating that its value has changed). +func RequireKeyUnchanged(key string) PreconditionFunc { + return func(patch interface{}) bool { + patchMap, ok := patch.(map[string]interface{}) + if !ok { + return true + } + + // The presence of key means that its value has been changed, so the test fails. + _, ok = patchMap[key] + return !ok + } +} + +// Deprecated: Use the synonym CreateTwoWayMergePatch, instead. func CreateStrategicMergePatch(original, modified []byte, dataStruct interface{}) ([]byte, error) { + return CreateTwoWayMergePatch(original, modified, dataStruct) +} + +// CreateTwoWayMergePatch creates a patch that can be passed to StrategicMergePatch from an original +// document and a modified documernt, which are passed to the method as json encoded content. It will +// return a patch that yields the modified document when applied to the original document, or an error +// if either of the two documents is invalid. +func CreateTwoWayMergePatch(original, modified []byte, dataStruct interface{}, fns ...PreconditionFunc) ([]byte, error) { originalMap := map[string]interface{}{} - err := json.Unmarshal(original, &originalMap) - if err != nil { - return nil, errBadJSONDoc + if len(original) > 0 { + if err := json.Unmarshal(original, &originalMap); err != nil { + return nil, errBadJSONDoc + } } modifiedMap := map[string]interface{}{} - err = json.Unmarshal(modified, &modifiedMap) - if err != nil { - return nil, errBadJSONDoc + if len(modified) > 0 { + if err := json.Unmarshal(modified, &modifiedMap); err != nil { + return nil, errBadJSONDoc + } } t, err := getTagStructType(dataStruct) @@ -68,11 +141,18 @@ func CreateStrategicMergePatch(original, modified []byte, dataStruct interface{} return nil, err } + // Apply the preconditions to the patch, and return an error if any of them fail. + for _, fn := range fns { + if !fn(patchMap) { + return nil, newErrPreconditionFailed(patchMap) + } + } + return json.Marshal(patchMap) } // Returns a (recursive) strategic merge patch that yields modified when applied to original. -func diffMaps(original, modified map[string]interface{}, t reflect.Type, ignoreAdditions, ignoreChangesAndDeletions bool) (map[string]interface{}, error) { +func diffMaps(original, modified map[string]interface{}, t reflect.Type, ignoreChangesAndAdditions, ignoreDeletions bool) (map[string]interface{}, error) { patch := map[string]interface{}{} if t.Kind() == reflect.Ptr { t = t.Elem() @@ -80,42 +160,43 @@ func diffMaps(original, modified map[string]interface{}, t reflect.Type, ignoreA for key, modifiedValue := range modified { originalValue, ok := original[key] - // value was added if !ok { - if !ignoreAdditions { + // Key was added, so add to patch + if !ignoreChangesAndAdditions { patch[key] = modifiedValue } continue } - if key == specialKey { + if key == directiveMarker { originalString, ok := originalValue.(string) if !ok { - return nil, fmt.Errorf("invalid value for special key: %s", specialKey) + return nil, fmt.Errorf("invalid value for special key: %s", directiveMarker) } modifiedString, ok := modifiedValue.(string) if !ok { - return nil, fmt.Errorf("invalid value for special key: %s", specialKey) + return nil, fmt.Errorf("invalid value for special key: %s", directiveMarker) } if modifiedString != originalString { - patch[key] = modifiedValue + patch[directiveMarker] = modifiedValue } continue } - if !ignoreChangesAndDeletions { - // If types have changed, replace completely - if reflect.TypeOf(originalValue) != reflect.TypeOf(modifiedValue) { + if reflect.TypeOf(originalValue) != reflect.TypeOf(modifiedValue) { + // Types have changed, so add to patch + if !ignoreChangesAndAdditions { patch[key] = modifiedValue - continue } + + continue } - // Types are the same, compare values + // Types are the same, so compare values switch originalValueTyped := originalValue.(type) { case map[string]interface{}: modifiedValueTyped := modifiedValue.(map[string]interface{}) @@ -124,7 +205,7 @@ func diffMaps(original, modified map[string]interface{}, t reflect.Type, ignoreA return nil, err } - patchValue, err := diffMaps(originalValueTyped, modifiedValueTyped, fieldType, ignoreAdditions, ignoreChangesAndDeletions) + patchValue, err := diffMaps(originalValueTyped, modifiedValueTyped, fieldType, ignoreChangesAndAdditions, ignoreDeletions) if err != nil { return nil, err } @@ -141,8 +222,8 @@ func diffMaps(original, modified map[string]interface{}, t reflect.Type, ignoreA return nil, err } - if fieldPatchStrategy == "merge" { - patchValue, err := diffLists(originalValueTyped, modifiedValueTyped, fieldType.Elem(), fieldPatchMergeKey, ignoreAdditions, ignoreChangesAndDeletions) + if fieldPatchStrategy == mergeDirective { + patchValue, err := diffLists(originalValueTyped, modifiedValueTyped, fieldType.Elem(), fieldPatchMergeKey, ignoreChangesAndAdditions, ignoreDeletions) if err != nil { return nil, err } @@ -155,15 +236,16 @@ func diffMaps(original, modified map[string]interface{}, t reflect.Type, ignoreA } } - if !ignoreChangesAndDeletions { + if !ignoreChangesAndAdditions { if !reflect.DeepEqual(originalValue, modifiedValue) { + // Values are different, so add to patch patch[key] = modifiedValue } } } - if !ignoreChangesAndDeletions { - // Now add all deleted values as nil + if !ignoreDeletions { + // Add nils for deleted values for key := range original { _, found := modified[key] if !found { @@ -177,9 +259,9 @@ func diffMaps(original, modified map[string]interface{}, t reflect.Type, ignoreA // Returns a (recursive) strategic merge patch that yields modified when applied to original, // for a pair of lists with merge semantics. -func diffLists(original, modified []interface{}, t reflect.Type, mergeKey string, ignoreAdditions, ignoreChangesAndDeletions bool) ([]interface{}, error) { +func diffLists(original, modified []interface{}, t reflect.Type, mergeKey string, ignoreChangesAndAdditions, ignoreDeletions bool) ([]interface{}, error) { if len(original) == 0 { - if len(modified) == 0 || ignoreAdditions { + if len(modified) == 0 || ignoreChangesAndAdditions { return nil, nil } @@ -193,11 +275,10 @@ func diffLists(original, modified []interface{}, t reflect.Type, mergeKey string var patch []interface{} - // If the elements are not maps... if elementType.Kind() == reflect.Map { - patch, err = diffListsOfMaps(original, modified, t, mergeKey, ignoreAdditions, ignoreChangesAndDeletions) - } else { - patch, err = diffListsOfScalars(original, modified, ignoreAdditions) + patch, err = diffListsOfMaps(original, modified, t, mergeKey, ignoreChangesAndAdditions, ignoreDeletions) + } else if !ignoreChangesAndAdditions { + patch, err = diffListsOfScalars(original, modified) } if err != nil { @@ -209,7 +290,7 @@ func diffLists(original, modified []interface{}, t reflect.Type, mergeKey string // Returns a (recursive) strategic merge patch that yields modified when applied to original, // for a pair of lists of scalars with merge semantics. -func diffListsOfScalars(original, modified []interface{}, ignoreAdditions bool) ([]interface{}, error) { +func diffListsOfScalars(original, modified []interface{}) ([]interface{}, error) { if len(modified) == 0 { // There is no need to check the length of original because there is no way to create // a patch that deletes a scalar from a list of scalars with merge semantics. @@ -229,9 +310,7 @@ loopB: modifiedString := fmt.Sprintf("%v", modified[modifiedIndex]) if originalString >= modifiedString { if originalString != modifiedString { - if !ignoreAdditions { - patch = append(patch, modified[modifiedIndex]) - } + patch = append(patch, modified[modifiedIndex]) } continue loopB @@ -243,11 +322,9 @@ loopB: break } - if !ignoreAdditions { - // Add any remaining items found only in modified - for ; modifiedIndex < len(modifiedScalars); modifiedIndex++ { - patch = append(patch, modified[modifiedIndex]) - } + // Add any remaining items found only in modified + for ; modifiedIndex < len(modifiedScalars); modifiedIndex++ { + patch = append(patch, modified[modifiedIndex]) } return patch, nil @@ -258,7 +335,7 @@ var errBadArgTypeFmt = "expected a %s, but received a %t" // Returns a (recursive) strategic merge patch that yields modified when applied to original, // for a pair of lists of maps with merge semantics. -func diffListsOfMaps(original, modified []interface{}, t reflect.Type, mergeKey string, ignoreAdditions, ignoreChangesAndDeletions bool) ([]interface{}, error) { +func diffListsOfMaps(original, modified []interface{}, t reflect.Type, mergeKey string, ignoreChangesAndAdditions, ignoreDeletions bool) ([]interface{}, error) { patch := make([]interface{}, 0) originalSorted, err := sortMergeListsByNameArray(original, t, mergeKey, false) @@ -301,7 +378,8 @@ loopB: modifiedString := fmt.Sprintf("%v", modifiedValue) if originalString >= modifiedString { if originalString == modifiedString { - patchValue, err := diffMaps(originalMap, modifiedMap, t, ignoreAdditions, ignoreChangesAndDeletions) + // Merge key values are equal, so recurse + patchValue, err := diffMaps(originalMap, modifiedMap, t, ignoreChangesAndAdditions, ignoreDeletions) if err != nil { return nil, err } @@ -311,22 +389,24 @@ loopB: patchValue[mergeKey] = modifiedValue patch = append(patch, patchValue) } - } else if !ignoreAdditions { + } else if !ignoreChangesAndAdditions { + // Item was added, so add to patch patch = append(patch, modifiedMap) } continue loopB } - if !ignoreChangesAndDeletions { - patch = append(patch, map[string]interface{}{mergeKey: originalValue, specialKey: specialValue}) + if !ignoreDeletions { + // Item was deleted, so add delete directive + patch = append(patch, map[string]interface{}{mergeKey: originalValue, directiveMarker: deleteDirective}) } } break } - if !ignoreChangesAndDeletions { + if !ignoreDeletions { // Delete any remaining items found only in original for ; originalIndex < len(originalSorted); originalIndex++ { originalMap, ok := originalSorted[originalIndex].(map[string]interface{}) @@ -339,11 +419,11 @@ loopB: return nil, fmt.Errorf(errNoMergeKeyFmt, originalMap, mergeKey) } - patch = append(patch, map[string]interface{}{mergeKey: originalValue, specialKey: specialValue}) + patch = append(patch, map[string]interface{}{mergeKey: originalValue, directiveMarker: deleteDirective}) } } - if !ignoreAdditions { + if !ignoreChangesAndAdditions { // Add any remaining items found only in modified for ; modifiedIndex < len(modifiedSorted); modifiedIndex++ { patch = append(patch, modified[modifiedIndex]) @@ -353,7 +433,6 @@ loopB: return patch, nil } -// StrategicMergePatchData applies a patch using strategic merge patch semantics. // Deprecated: StrategicMergePatchData is deprecated. Use the synonym StrategicMergePatch, // instead, which follows the naming convention of evanphx/json-patch. func StrategicMergePatchData(original, patch []byte, dataStruct interface{}) ([]byte, error) { @@ -364,6 +443,14 @@ func StrategicMergePatchData(original, patch []byte, dataStruct interface{}) ([] // must be json encoded content. A patch can be created from an original and a modified document // by calling CreateStrategicMergePatch. func StrategicMergePatch(original, patch []byte, dataStruct interface{}) ([]byte, error) { + if original == nil { + original = []byte{} + } + + if patch == nil { + patch = []byte{} + } + originalMap := map[string]interface{}{} err := json.Unmarshal(original, &originalMap) if err != nil { @@ -390,6 +477,10 @@ func StrategicMergePatch(original, patch []byte, dataStruct interface{}) ([]byte } func getTagStructType(dataStruct interface{}) (reflect.Type, error) { + if dataStruct == nil { + return nil, fmt.Errorf(errBadArgTypeFmt, "struct", "nil") + } + t := reflect.TypeOf(dataStruct) if t.Kind() == reflect.Ptr { t = t.Elem() @@ -408,21 +499,26 @@ var errBadPatchTypeFmt = "unknown patch type: %s in map: %v" // both the original map and the patch because getting a deep copy of a map in // golang is highly non-trivial. func mergeMap(original, patch map[string]interface{}, t reflect.Type) (map[string]interface{}, error) { - // If the map contains "$patch: replace", don't merge it, just use the - // patch map directly. Later on, can add a non-recursive replace that only - // affects the map that the $patch is in. - if v, ok := patch[specialKey]; ok { - if v == "replace" { - delete(patch, specialKey) + if v, ok := patch[directiveMarker]; ok { + if v == replaceDirective { + // If the patch contains "$patch: replace", don't merge it, just use the + // patch directly. Later on, we can add a single level replace that only + // affects the map that the $patch is in. + delete(patch, directiveMarker) return patch, nil } + if v == deleteDirective { + // If the patch contains "$patch: delete", don't merge it, just return + // an empty map. + return map[string]interface{}{}, nil + } + return nil, fmt.Errorf(errBadPatchTypeFmt, v, patch) } // nil is an accepted value for original to simplify logic in other places. - // If original is nil, create a map so if patch requires us to modify the - // map, it'll work. + // If original is nil, replace it with an empty map and then apply the patch. if original == nil { original = map[string]interface{}{} } @@ -461,7 +557,7 @@ func mergeMap(original, patch map[string]interface{}, t reflect.Type) (map[strin return nil, err } - if originalType.Kind() == reflect.Map && fieldPatchStrategy != "replace" { + if originalType.Kind() == reflect.Map && fieldPatchStrategy != replaceDirective { typedOriginal := original[k].(map[string]interface{}) typedPatch := patchV.(map[string]interface{}) var err error @@ -473,7 +569,7 @@ func mergeMap(original, patch map[string]interface{}, t reflect.Type) (map[strin continue } - if originalType.Kind() == reflect.Slice && fieldPatchStrategy == "merge" { + if originalType.Kind() == reflect.Slice && fieldPatchStrategy == mergeDirective { elemType := fieldType.Elem() typedOriginal := original[k].([]interface{}) typedPatch := patchV.([]interface{}) @@ -527,9 +623,9 @@ func mergeSlice(original, patch []interface{}, elemType reflect.Type, mergeKey s replace := false for _, v := range patch { typedV := v.(map[string]interface{}) - patchType, ok := typedV[specialKey] + patchType, ok := typedV[directiveMarker] if ok { - if patchType == specialValue { + if patchType == deleteDirective { mergeValue, ok := typedV[mergeKey] if ok { _, originalKey, found, err := findMapInSliceBasedOnKeyValue(original, mergeKey, mergeValue) @@ -544,10 +640,10 @@ func mergeSlice(original, patch []interface{}, elemType reflect.Type, mergeKey s } else { return nil, fmt.Errorf("delete patch type with no merge key defined") } - } else if patchType == "replace" { + } else if patchType == replaceDirective { replace = true // Continue iterating through the array to prune any other $patch elements. - } else if patchType == "merge" { + } else if patchType == mergeDirective { return nil, fmt.Errorf("merging lists cannot yet be specified in the patch") } else { return nil, fmt.Errorf(errBadPatchTypeFmt, patchType, typedV) @@ -636,7 +732,7 @@ func sortMergeListsByName(mapJSON []byte, dataStruct interface{}) ([]byte, error func sortMergeListsByNameMap(s map[string]interface{}, t reflect.Type) (map[string]interface{}, error) { newS := map[string]interface{}{} for k, v := range s { - if k != specialKey { + if k != directiveMarker { fieldType, fieldPatchStrategy, fieldPatchMergeKey, err := forkedjson.LookupPatchMetadata(t, k) if err != nil { return nil, err @@ -650,7 +746,7 @@ func sortMergeListsByNameMap(s map[string]interface{}, t reflect.Type) (map[stri return nil, err } } else if typedV, ok := v.([]interface{}); ok { - if fieldPatchStrategy == "merge" { + if fieldPatchStrategy == mergeDirective { var err error v, err = sortMergeListsByNameArray(typedV, fieldType.Elem(), fieldPatchMergeKey, true) if err != nil { @@ -827,3 +923,108 @@ func sliceElementType(slices ...[]interface{}) (reflect.Type, error) { return prevType, nil } + +// HasConflicts returns true if the left and right JSON interface objects overlap with +// different values in any key. All keys are required to be strings. Since patches of the +// same Type have congruent keys, this is valid for multiple patch types. +func HasConflicts(left, right interface{}) (bool, error) { + switch typedLeft := left.(type) { + case map[string]interface{}: + switch typedRight := right.(type) { + case map[string]interface{}: + for key, leftValue := range typedLeft { + rightValue, ok := typedRight[key] + if !ok { + return false, nil + } + return HasConflicts(leftValue, rightValue) + } + return false, nil + default: + return true, nil + } + case []interface{}: + switch typedRight := right.(type) { + case []interface{}: + if len(typedLeft) != len(typedRight) { + return true, nil + } + for i := range typedLeft { + return HasConflicts(typedLeft[i], typedRight[i]) + } + return false, nil + default: + return true, nil + } + case string, float64, bool, int, int64, nil: + return !reflect.DeepEqual(left, right), nil + default: + return true, fmt.Errorf("unknown type: %v", reflect.TypeOf(left)) + } +} + +// CreateThreeWayMergePatch reconciles a modified configuration with an original configuration, +// while preserving any changes or deletions made to the original configuration in the interim, +// and not overridden by the current configuration. All three documents must be passed to the +// method as json encoded content. It will return a strategic merge patch, or an error if any +// of the documents is invalid, or if there are any preconditions that fail against the modified +// configuration, or, if force is false and there are conflicts between the modified and current +// configurations. +func CreateThreeWayMergePatch(original, modified, current []byte, dataStruct interface{}, force bool, fns ...PreconditionFunc) ([]byte, error) { + originalMap := map[string]interface{}{} + if len(original) > 0 { + if err := json.Unmarshal(original, &originalMap); err != nil { + return nil, errBadJSONDoc + } + } + + modifiedMap := map[string]interface{}{} + if len(modified) > 0 { + if err := json.Unmarshal(modified, &modifiedMap); err != nil { + return nil, errBadJSONDoc + } + } + + currentMap := map[string]interface{}{} + if len(current) > 0 { + if err := json.Unmarshal(current, ¤tMap); err != nil { + return nil, errBadJSONDoc + } + } + + t, err := getTagStructType(dataStruct) + if err != nil { + return nil, err + } + + // The patch is the difference from current to modified without deletions, plus deletions + // from original to modified. To find it, we compute deletions, which are the deletions from + // original to modified, and delta, which is the difference from current to modified without + // deletions, and then apply delta to deletions as a patch, which should be strictly additive. + deltaMap, err := diffMaps(currentMap, modifiedMap, t, false, true) + if err != nil { + return nil, err + } + + deletionsMap, err := diffMaps(originalMap, modifiedMap, t, true, false) + if err != nil { + return nil, err + } + + patchMap, err := mergeMap(deletionsMap, deltaMap, t) + if err != nil { + return nil, err + } + + // Apply the preconditions to the patch, and return an error if any of them fail. + for _, fn := range fns { + if !fn(patchMap) { + return nil, newErrPreconditionFailed(patchMap) + } + } + + // TODO(jackgr): If force is false, and the patch contains any keys that are also in current, + // then return a conflict error. + + return json.Marshal(patchMap) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/strategicpatch/patch_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/strategicpatch/patch_test.go index 08411114d046..3fff3e52f6d3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/strategicpatch/patch_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/strategicpatch/patch_test.go @@ -26,18 +26,18 @@ import ( "github.com/ghodss/yaml" ) -type StrategicMergePatchTestCases struct { - TestCases []StrategicMergePatchTestCase -} - type SortMergeListTestCases struct { TestCases []SortMergeListTestCase } -type StrategicMergePatchTestCaseData struct { - Original map[string]interface{} - Patch map[string]interface{} - Modified map[string]interface{} +type SortMergeListTestCase struct { + Description string + Original map[string]interface{} + Sorted map[string]interface{} +} + +type StrategicMergePatchTestCases struct { + TestCases []StrategicMergePatchTestCase } type StrategicMergePatchTestCase struct { @@ -45,10 +45,13 @@ type StrategicMergePatchTestCase struct { StrategicMergePatchTestCaseData } -type SortMergeListTestCase struct { - Description string - Original map[string]interface{} - Sorted map[string]interface{} +type StrategicMergePatchTestCaseData struct { + Original map[string]interface{} + TwoWay map[string]interface{} + Modified map[string]interface{} + Current map[string]interface{} + ThreeWay map[string]interface{} + Result map[string]interface{} } type MergeItem struct { @@ -63,6 +66,8 @@ type MergeItem struct { SimpleMap map[string]string } +var mergeItem MergeItem + // These are test cases for SortMergeList, used to assert that it (recursively) // sorts both merging and non merging lists correctly. var sortMergeListTestCaseData = []byte(` @@ -225,26 +230,22 @@ func TestSortMergeLists(t *testing.T) { tc := SortMergeListTestCases{} err := yaml.Unmarshal(sortMergeListTestCaseData, &tc) if err != nil { - t.Errorf("can't unmarshal test cases: %v", err) + t.Errorf("can't unmarshal test cases:%s\n", err) return } - var e MergeItem for _, c := range tc.TestCases { - sorted, err := sortMergeListsByName(toJSONOrFail(c.Original, t), e) - if err != nil { - t.Errorf("sort arrays returned error: %v", err) - } - - if !reflect.DeepEqual(sorted, toJSONOrFail(c.Sorted, t)) { - t.Errorf("sorting failed: %v\ntried to sort:\n%vexpected:\n%vgot:\n%v", - c.Description, toYAMLOrError(c.Original), toYAMLOrError(c.Sorted), jsonToYAMLOrError(sorted)) + original := testObjectToJSONOrFail(t, c.Original, c.Description) + sorted := testObjectToJSONOrFail(t, c.Sorted, c.Description) + if !reflect.DeepEqual(original, sorted) { + t.Errorf("error in test case: %s\ncannot sort object:\n%s\n%sexpected:\n%s\ngot:\n%s\n", + c.Description, toYAMLOrError(c.Original), toYAMLOrError(c.Sorted), jsonToYAMLOrError(original)) } } } // These are test cases for StrategicMergePatch that cannot be generated using -// CreateStrategicMergePatch because it doesn't use the replace directive, generate +// CreateTwoWayMergePatch because it doesn't use the replace directive, generate // duplicate integers for a merging list patch, or generate empty merging lists. var customStrategicMergePatchTestCaseData = []byte(` testCases: @@ -253,7 +254,7 @@ testCases: mergingIntList: - 1 - 2 - patch: + twoWay: mergingIntList: - 2 - 3 @@ -267,7 +268,7 @@ testCases: mergingList: - name: 1 - name: 2 - patch: + twoWay: mergingList: - $patch: replace modified: @@ -275,7 +276,7 @@ testCases: - description: merge empty merging lists original: mergingList: [] - patch: + twoWay: mergingList: [] modified: mergingList: [] @@ -283,14 +284,14 @@ testCases: original: name: 1 value: 1 - patch: + twoWay: $patch: replace modified: {} - description: add key and delete all keys from map original: name: 1 value: 1 - patch: + twoWay: other: a $patch: replace modified: @@ -301,110 +302,165 @@ func TestCustomStrategicMergePatch(t *testing.T) { tc := StrategicMergePatchTestCases{} err := yaml.Unmarshal(customStrategicMergePatchTestCaseData, &tc) if err != nil { - t.Errorf("can't unmarshal test cases: %v", err) + t.Errorf("can't unmarshal test cases:%v\n", err) return } for _, c := range tc.TestCases { - cOriginal, cPatch, cModified := testCaseToJSONOrFail(t, c) - testPatchApplication(t, cOriginal, cPatch, cModified, c.Description) - } -} - -func testCaseToJSONOrFail(t *testing.T, c StrategicMergePatchTestCase) ([]byte, []byte, []byte) { - var e MergeItem - cOriginal := toJSONOrFail(c.Original, t) - cPatch, err := sortMergeListsByName(toJSONOrFail(c.Patch, t), e) - if err != nil { - t.Errorf("error:%v sorting patch object:\n%v", err, c.Patch) - } - - cModified, err := sortMergeListsByName(toJSONOrFail(c.Modified, t), e) - if err != nil { - t.Errorf("error: %v sorting modified object:\n%v", err, c.Modified) - } - - return cOriginal, cPatch, cModified -} - -func testPatchApplication(t *testing.T, cOriginal, cPatch, cModified []byte, description string) { - var e MergeItem - modified, err := StrategicMergePatch(cOriginal, cPatch, e) - if err != nil { - t.Errorf("error applying patch: %v:\noriginal:\n%vpatch:\n%v", - err, jsonToYAMLOrError(cOriginal), jsonToYAMLOrError(cPatch)) - } - - // Sort the lists that have merged maps, since order is not significant. - modified, err = sortMergeListsByName(modified, e) - if err != nil { - t.Errorf("error: %v sorting modified object:\n%v", err, modified) - } - - if !reflect.DeepEqual(modified, cModified) { - t.Errorf("patch application failed: %v\noriginal:\n%vpatch:\n%vexpected modified:\n%vgot modified:\n%v", - description, jsonToYAMLOrError(cOriginal), jsonToYAMLOrError(cPatch), - jsonToYAMLOrError(cModified), jsonToYAMLOrError(modified)) + original, twoWay, modified := twoWayTestCaseToJSONOrFail(t, c) + testPatchApplication(t, original, twoWay, modified, c.Description) } } -// These are test cases for CreateStrategicMergePatch, used to assert that it -// generates the correct patch for a given outcome. They are also test cases for -// StrategicMergePatch, used to assert that applying a patch yields the correct -// outcome. +// These are test cases for StrategicMergePatch, to assert that applying a patch +// yields the correct outcome. They are also test cases for CreateTwoWayMergePatch +// and CreateThreeWayMergePatch, to assert that they both generate the correct patch +// for the given set of input documents. +// var createStrategicMergePatchTestCaseData = []byte(` testCases: - description: add field to map original: name: 1 - patch: + twoWay: + value: 1 + modified: + name: 1 + value: 1 + current: + name: 1 + other: a + threeWay: + value: 1 + result: + name: 1 + value: 1 + other: a + - description: add field to map with conflict + original: + name: 1 + twoWay: value: 1 modified: name: 1 value: 1 + current: + name: a + other: a + threeWay: + name: 1 + value: 1 + result: + name: 1 + value: 1 + other: a - description: add field and delete field from map original: name: 1 - patch: + twoWay: name: null value: 1 modified: value: 1 + current: + name: 1 + other: a + threeWay: + name: null + value: 1 + result: + value: 1 + other: a - description: delete field from nested map original: simpleMap: key1: 1 key2: 1 - patch: + twoWay: + simpleMap: + key2: null + modified: + simpleMap: + key1: 1 + current: + simpleMap: + key1: 1 + key2: 1 + other: a + threeWay: + simpleMap: + key2: null + result: + simpleMap: + key1: 1 + other: a + - description: delete field from nested map with conflict + original: + simpleMap: + key1: 1 + key2: 1 + twoWay: simpleMap: key2: null modified: simpleMap: key1: 1 + current: + simpleMap: + key1: a + key2: 1 + other: a + threeWay: + simpleMap: + key1: 1 + key2: null + result: + simpleMap: + key1: 1 + other: a - description: delete all fields from map original: name: 1 value: 1 - patch: + twoWay: name: null value: null modified: {} + current: + name: 1 + value: 1 + other: a + threeWay: + name: null + value: null + result: + other: a - description: add field and delete all fields from map original: name: 1 value: 1 - patch: - other: a + twoWay: name: null value: null + other: a modified: other: a + current: + name: 1 + value: a + other: b + threeWay: + name: null + value: null + other: a + result: + other: a - description: replace list of scalars original: nonMergingIntList: - 1 - 2 - patch: + twoWay: nonMergingIntList: - 2 - 3 @@ -412,12 +468,23 @@ testCases: nonMergingIntList: - 2 - 3 + current: + nonMergingIntList: + - 1 + threeWay: + nonMergingIntList: + - 2 + - 3 + result: + nonMergingIntList: + - 2 + - 3 - description: merge lists of scalars original: mergingIntList: - 1 - 2 - patch: + twoWay: mergingIntList: - 3 modified: @@ -425,13 +492,27 @@ testCases: - 1 - 2 - 3 + current: + mergingIntList: + - 1 + - 2 + - 4 + threeWay: + mergingIntList: + - 3 + result: + mergingIntList: + - 1 + - 2 + - 3 + - 4 - description: merge lists of maps original: mergingList: - name: 1 - name: 2 value: 2 - patch: + twoWay: mergingList: - name: 3 value: 3 @@ -442,13 +523,33 @@ testCases: value: 2 - name: 3 value: 3 + current: + mergingList: + - name: 1 + other: a + - name: 2 + value: 2 + other: b + threeWay: + mergingList: + - name: 3 + value: 3 + result: + mergingList: + - name: 1 + other: a + - name: 2 + value: 2 + other: b + - name: 3 + value: 3 - description: add field to map in merging list original: mergingList: - name: 1 - name: 2 value: 2 - patch: + twoWay: mergingList: - name: 1 value: 1 @@ -458,13 +559,32 @@ testCases: value: 1 - name: 2 value: 2 + current: + mergingList: + - name: 1 + other: a + - name: 2 + value: 2 + other: b + threeWay: + mergingList: + - name: 1 + value: 1 + result: + mergingList: + - name: 1 + value: 1 + other: a + - name: 2 + value: 2 + other: b - description: add duplicate field to map in merging list original: mergingList: - name: 1 - name: 2 value: 2 - patch: + twoWay: mergingList: - name: 1 value: 1 @@ -474,6 +594,24 @@ testCases: value: 1 - name: 2 value: 2 + current: + mergingList: + - name: 1 + value: 1 + other: a + - name: 2 + value: 2 + other: b + threeWay: + {} + result: + mergingList: + - name: 1 + value: 1 + other: a + - name: 2 + value: 2 + other: b - description: replace map field value in merging list original: mergingList: @@ -481,7 +619,7 @@ testCases: value: 1 - name: 2 value: 2 - patch: + twoWay: mergingList: - name: 1 value: a @@ -491,114 +629,364 @@ testCases: value: a - name: 2 value: 2 - - description: delete map from merging list - original: + current: mergingList: - name: 1 + value: 1 + other: a - name: 2 - patch: + value: 2 + other: b + threeWay: mergingList: - name: 1 - $patch: delete - modified: + value: a + result: mergingList: + - name: 1 + value: a + other: a - name: 2 - - description: delete missing map from merging list + value: 2 + other: b + - description: replace map field value in merging list with conflict original: mergingList: - name: 1 + value: 1 - name: 2 - patch: + value: 2 + twoWay: mergingList: - name: 1 - $patch: delete + value: a modified: mergingList: - - name: 2 - - description: add map and delete map from merging list - original: - merginglist: - name: 1 + value: a - name: 2 - patch: - merginglist: + value: 2 + current: + mergingList: - name: 1 - $patch: delete - - name: 3 - modified: - merginglist: + value: 1 + other: a - name: 2 - - name: 3 - - description: delete all maps from merging list - original: + value: b + other: b + threeWay: mergingList: - name: 1 + value: a - name: 2 - patch: + value: 2 + result: mergingList: - name: 1 - $patch: delete + value: a + other: a - name: 2 - $patch: delete - modified: - mergingList: [] - - description: delete all maps from partially empty merging list + value: 2 + other: b + - description: delete map from merging list original: mergingList: - name: 1 - name: 2 - patch: + twoWay: mergingList: - name: 1 $patch: delete - - name: 2 - $patch: delete modified: - mergingList: [] - - description: delete all maps from empty merging list - original: + mergingList: + - name: 2 + current: mergingList: - name: 1 + other: a - name: 2 - patch: + other: b + threeWay: mergingList: - name: 1 $patch: delete + result: + mergingList: - name: 2 - $patch: delete - modified: - mergingList: [] - - description: delete field from map in merging list + other: b + - description: delete missing map from merging list original: mergingList: - name: 1 - value: 1 - name: 2 - value: 2 - patch: + twoWay: mergingList: - name: 1 - value: null + $patch: delete modified: mergingList: - - name: 1 - name: 2 - value: 2 - - description: replace non merging list nested in merging list - original: + current: mergingList: - - name: 1 - nonMergingList: - - name: 1 - - name: 2 - value: 2 - name: 2 - patch: + other: b + threeWay: mergingList: - name: 1 - nonMergingList: - - name: 1 - value: 1 + $patch: delete + result: + mergingList: + - name: 2 + other: b + - description: delete map from merging list with conflict + original: + mergingList: + - name: 1 + - name: 2 + twoWay: + mergingList: + - name: 1 + $patch: delete + modified: + mergingList: + - name: 2 + current: + mergingList: + - name: 1 + other: a + threeWay: + mergingList: + - name: 1 + $patch: delete + - name: 2 + result: + mergingList: + - name: 2 + - description: add map and delete map from merging list + original: + merginglist: + - name: 1 + - name: 2 + twoWay: + merginglist: + - name: 1 + $patch: delete + - name: 3 + modified: + merginglist: + - name: 2 + - name: 3 + current: + merginglist: + - name: 1 + other: a + - name: 2 + other: b + - name: 4 + other: c + threeWay: + merginglist: + - name: 1 + $patch: delete + - name: 3 + result: + merginglist: + - name: 2 + other: b + - name: 3 + - name: 4 + other: c + - description: add map and delete map from merging list with conflict + original: + merginglist: + - name: 1 + - name: 2 + twoWay: + merginglist: + - name: 1 + $patch: delete + - name: 3 + modified: + merginglist: + - name: 2 + - name: 3 + current: + merginglist: + - name: 1 + other: a + - name: 4 + other: c + threeWay: + merginglist: + - name: 1 + $patch: delete + - name: 2 + - name: 3 + result: + merginglist: + - name: 2 + - name: 3 + - name: 4 + other: c + - description: delete all maps from merging list + original: + mergingList: + - name: 1 + - name: 2 + twoWay: + mergingList: + - name: 1 + $patch: delete + - name: 2 + $patch: delete + modified: + mergingList: [] + current: + mergingList: + - name: 1 + other: a + - name: 2 + other: b + threeWay: + mergingList: + - name: 1 + $patch: delete + - name: 2 + $patch: delete + result: + mergingList: [] + - description: delete all maps from partially empty merging list + original: + mergingList: + - name: 1 + - name: 2 + twoWay: + mergingList: + - name: 1 + $patch: delete + - name: 2 + $patch: delete + modified: + mergingList: [] + current: + mergingList: + - name: 1 + other: a + threeWay: + mergingList: + - name: 1 + $patch: delete + - name: 2 + $patch: delete + result: + mergingList: [] + - description: delete all maps from empty merging list + original: + mergingList: + - name: 1 + - name: 2 + twoWay: + mergingList: + - name: 1 + $patch: delete + - name: 2 + $patch: delete + modified: + mergingList: [] + current: + mergingList: [] + threeWay: + mergingList: + - name: 1 + $patch: delete + - name: 2 + $patch: delete + result: + mergingList: [] + - description: delete field from map in merging list + original: + mergingList: + - name: 1 + value: 1 + - name: 2 + value: 2 + twoWay: + mergingList: + - name: 1 + value: null + modified: + mergingList: + - name: 1 + - name: 2 + value: 2 + current: + mergingList: + - name: 1 + value: 1 + other: a + - name: 2 + other: b + threeWay: + mergingList: + - name: 1 + value: null + - name: 2 + value: 2 + result: + mergingList: + - name: 1 + other: a + - name: 2 + value: 2 + other: b + - description: delete field from map in merging list with conflict + original: + mergingList: + - name: 1 + value: 1 + - name: 2 + value: 2 + twoWay: + mergingList: + - name: 1 + value: null + modified: + mergingList: + - name: 1 + - name: 2 + value: 2 + current: + mergingList: + - name: 1 + value: a + other: a + threeWay: + mergingList: + - name: 1 + value: null + - name: 2 + value: 2 + result: + mergingList: + - name: 1 + other: a + - name: 2 + value: 2 + - description: replace non merging list nested in merging list + original: + mergingList: + - name: 1 + nonMergingList: + - name: 1 + - name: 2 + value: 2 + - name: 2 + twoWay: + mergingList: + - name: 1 + nonMergingList: + - name: 1 + value: 1 modified: mergingList: - name: 1 @@ -606,6 +994,31 @@ testCases: - name: 1 value: 1 - name: 2 + current: + mergingList: + - name: 1 + other: a + nonMergingList: + - name: 1 + - name: 2 + value: 2 + - name: 2 + other: b + threeWay: + mergingList: + - name: 1 + nonMergingList: + - name: 1 + value: 1 + result: + mergingList: + - name: 1 + other: a + nonMergingList: + - name: 1 + value: 1 + - name: 2 + other: b - description: add field to map in merging list nested in merging list original: mergingList: @@ -615,7 +1028,7 @@ testCases: - name: 2 value: 2 - name: 2 - patch: + twoWay: mergingList: - name: 1 mergingList: @@ -630,28 +1043,175 @@ testCases: - name: 2 value: 2 - name: 2 + current: + mergingList: + - name: 1 + other: a + mergingList: + - name: 1 + - name: 2 + value: 2 + - name: 2 + other: b + threeWay: + mergingList: + - name: 1 + mergingList: + - name: 1 + value: 1 + result: + mergingList: + - name: 1 + other: a + mergingList: + - name: 1 + value: 1 + - name: 2 + value: 2 + - name: 2 + other: b + - description: add field to map in merging list nested in merging list with value conflict + original: + mergingList: + - name: 1 + mergingList: + - name: 1 + - name: 2 + value: 2 + - name: 2 + twoWay: + mergingList: + - name: 1 + mergingList: + - name: 1 + value: 1 + modified: + mergingList: + - name: 1 + mergingList: + - name: 1 + value: 1 + - name: 2 + value: 2 + - name: 2 + current: + mergingList: + - name: 1 + other: a + mergingList: + - name: 1 + value: a + - name: 2 + value: b + - name: 2 + other: b + threeWay: + mergingList: + - name: 1 + mergingList: + - name: 1 + value: 1 + - name: 2 + value: 2 + result: + mergingList: + - name: 1 + other: a + mergingList: + - name: 1 + value: 1 + - name: 2 + value: 2 + - name: 2 + other: b + - description: add field to map in merging list nested in merging list with deletion conflict + original: + mergingList: + - name: 1 + mergingList: + - name: 1 + - name: 2 + value: 2 + - name: 2 + twoWay: + mergingList: + - name: 1 + mergingList: + - name: 1 + value: 1 + modified: + mergingList: + - name: 1 + mergingList: + - name: 1 + value: 1 + - name: 2 + value: 2 + - name: 2 + current: + mergingList: + - name: 1 + other: a + mergingList: + - name: 2 + value: 2 + - name: 2 + other: b + threeWay: + mergingList: + - name: 1 + mergingList: + - name: 1 + value: 1 + result: + mergingList: + - name: 1 + other: a + mergingList: + - name: 1 + value: 1 + - name: 2 + value: 2 + - name: 2 + other: b - description: merge empty merging lists original: mergingList: [] - patch: + twoWay: {} modified: mergingList: [] current: mergingList: [] + threeWay: + {} result: mergingList: [] - description: add map to merging list by pointer original: mergeItemPtr: - name: 1 - patch: + twoWay: mergeItemPtr: - name: 2 modified: mergeItemPtr: - name: 1 - name: 2 + current: + mergeItemPtr: + - name: 1 + other: a + - name: 3 + threeWay: + mergeItemPtr: + - name: 2 + result: + mergeItemPtr: + - name: 1 + other: a + - name: 2 + - name: 3 - description: add field to map in merging list by pointer original: mergeItemPtr: @@ -661,7 +1221,7 @@ testCases: - name: 2 value: 2 - name: 2 - patch: + twoWay: mergeItemPtr: - name: 1 mergeItemPtr: @@ -676,57 +1236,162 @@ testCases: - name: 2 value: 2 - name: 2 + current: + mergeItemPtr: + - name: 1 + other: a + mergeItemPtr: + - name: 1 + other: a + - name: 2 + value: 2 + other: b + - name: 2 + other: b + threeWay: + mergeItemPtr: + - name: 1 + mergeItemPtr: + - name: 1 + value: 1 + result: + mergeItemPtr: + - name: 1 + other: a + mergeItemPtr: + - name: 1 + value: 1 + other: a + - name: 2 + value: 2 + other: b + - name: 2 + other: b `) func TestStrategicMergePatch(t *testing.T) { tc := StrategicMergePatchTestCases{} err := yaml.Unmarshal(createStrategicMergePatchTestCaseData, &tc) if err != nil { - t.Errorf("can't unmarshal test cases: %v", err) + t.Errorf("can't unmarshal test cases:%s\n", err) return } - var e MergeItem for _, c := range tc.TestCases { - cOriginal, cPatch, cModified := testCaseToJSONOrFail(t, c) + testTwoWayPatch(t, c) + testThreeWayPatch(t, c) + } +} - // Test patch generation - patch, err := CreateStrategicMergePatch(cOriginal, cModified, e) - if err != nil { - t.Errorf("error generating patch: %s:\n%v", err, toYAMLOrError(c.StrategicMergePatchTestCaseData)) - } +func testTwoWayPatch(t *testing.T, c StrategicMergePatchTestCase) { + original, expected, modified := twoWayTestCaseToJSONOrFail(t, c) - // Sort the lists that have merged maps, since order is not significant. - patch, err = sortMergeListsByName(patch, e) - if err != nil { - t.Errorf("error: %s sorting patch object:\n%v", err, patch) - } + actual, err := CreateTwoWayMergePatch(original, modified, mergeItem) + if err != nil { + t.Errorf("error: %s in test case: %s\ncannot create two way patch:%s:\n%s\n", + err, c.Description, toYAMLOrError(c.StrategicMergePatchTestCaseData)) + } + + testPatchCreation(t, expected, actual, c.Description) + testPatchApplication(t, original, actual, modified, c.Description) +} + +func twoWayTestCaseToJSONOrFail(t *testing.T, c StrategicMergePatchTestCase) ([]byte, []byte, []byte) { + return testObjectToJSONOrFail(t, c.Original, c.Description), + testObjectToJSONOrFail(t, c.TwoWay, c.Description), + testObjectToJSONOrFail(t, c.Modified, c.Description) +} + +func testThreeWayPatch(t *testing.T, c StrategicMergePatchTestCase) { + original, modified, current, expected, result := threeWayTestCaseToJSONOrFail(t, c) - if !reflect.DeepEqual(patch, cPatch) { - t.Errorf("patch generation failed:\n%vgot patch:\n%v", toYAMLOrError(c.StrategicMergePatchTestCaseData), jsonToYAMLOrError(patch)) + actual, err := CreateThreeWayMergePatch(original, modified, current, mergeItem, false) + if err != nil { + if IsConflict(err) { + if len(c.Result) > 0 { + t.Errorf("error in test case: %s\nunexpected conflict occurred:\n%s\n", + c.Description, toYAMLOrError(c.StrategicMergePatchTestCaseData)) + } + + return } - // Test patch application - testPatchApplication(t, cOriginal, cPatch, cModified, c.Description) + t.Errorf("error: %s in test case: %s\ncannot create three way patch:\n%s\n", + err, c.Description, toYAMLOrError(c.StrategicMergePatchTestCaseData)) + } + + if len(c.Result) < 1 { + t.Errorf("error in test case: %s\nexpected conflict did not occur:\n%s\n", + c.Description, toYAMLOrError(c.StrategicMergePatchTestCaseData)) } + + testPatchCreation(t, expected, actual, c.Description) + testPatchApplication(t, current, actual, result, c.Description) } -func toYAMLOrError(v interface{}) string { - y, err := toYAML(v) +func threeWayTestCaseToJSONOrFail(t *testing.T, c StrategicMergePatchTestCase) ([]byte, []byte, []byte, []byte, []byte) { + return testObjectToJSONOrFail(t, c.Original, c.Description), + testObjectToJSONOrFail(t, c.Modified, c.Description), + testObjectToJSONOrFail(t, c.Current, c.Description), + testObjectToJSONOrFail(t, c.ThreeWay, c.Description), + testObjectToJSONOrFail(t, c.Result, c.Description) +} + +func testPatchCreation(t *testing.T, expected, actual []byte, description string) { + sorted, err := sortMergeListsByName(actual, mergeItem) if err != nil { - return err.Error() + t.Errorf("error: %s in test case: %s\ncannot sort patch:\n%s\n", + err, description, jsonToYAMLOrError(actual)) } - return y + if !reflect.DeepEqual(sorted, expected) { + t.Errorf("error in test case: %s\nexpected patch:\n%s\ngot:\n%s\n", + description, jsonToYAMLOrError(expected), jsonToYAMLOrError(sorted)) + } +} + +func testPatchApplication(t *testing.T, original, patch, expected []byte, description string) { + result, err := StrategicMergePatch(original, patch, mergeItem) + if err != nil { + t.Errorf("error: %s in test case: %s\ncannot apply patch:\n%s\nto original:\n%s\n", + err, description, jsonToYAMLOrError(patch), jsonToYAMLOrError(original)) + } + + sorted, err := sortMergeListsByName(result, mergeItem) + if err != nil { + t.Errorf("error: %s in test case: %s\ncannot sort result object:\n%s\n", + err, description, jsonToYAMLOrError(result)) + } + + if !reflect.DeepEqual(sorted, expected) { + format := "error in test case: %s\npatch application failed:\noriginal:\n%s\npatch:\n%s\nexpected:\n%s\ngot:\n%s\n" + t.Errorf(format, description, + jsonToYAMLOrError(original), jsonToYAMLOrError(patch), + jsonToYAMLOrError(expected), jsonToYAMLOrError(sorted)) + } } -func toJSONOrFail(v interface{}, t *testing.T) []byte { - theJSON, err := toJSON(v) +func testObjectToJSONOrFail(t *testing.T, o map[string]interface{}, description string) []byte { + j, err := toJSON(o) if err != nil { t.Error(err) } - return theJSON + r, err := sortMergeListsByName(j, mergeItem) + if err != nil { + t.Errorf("error: %s in test case: %s\ncannot sort object:\n%s\n", err, description, j) + } + + return r +} + +func toYAMLOrError(v interface{}) string { + y, err := toYAML(v) + if err != nil { + return err.Error() + } + + return y } func jsonToYAMLOrError(j []byte) string { @@ -741,7 +1406,7 @@ func jsonToYAMLOrError(j []byte) string { func toYAML(v interface{}) (string, error) { y, err := yaml.Marshal(v) if err != nil { - return "", fmt.Errorf("yaml marshal failed: %v\n%v", err, spew.Sdump(v)) + return "", fmt.Errorf("yaml marshal failed:%v\n%v\n", err, spew.Sdump(v)) } return string(y), nil @@ -750,7 +1415,7 @@ func toYAML(v interface{}) (string, error) { func toJSON(v interface{}) ([]byte, error) { j, err := json.Marshal(v) if err != nil { - return nil, fmt.Errorf("json marshal failed: %v\n%v", err, spew.Sdump(v)) + return nil, fmt.Errorf("json marshal failed:%v\n%v\n", err, spew.Sdump(v)) } return j, nil @@ -759,8 +1424,71 @@ func toJSON(v interface{}) ([]byte, error) { func jsonToYAML(j []byte) ([]byte, error) { y, err := yaml.JSONToYAML(j) if err != nil { - return nil, fmt.Errorf("json to yaml failed: %v\n%v", err, j) + return nil, fmt.Errorf("json to yaml failed:%v\n%v\n", err, j) } return y, nil } + +func TestHasConflicts(t *testing.T) { + testCases := []struct { + A interface{} + B interface{} + Ret bool + }{ + {A: "hello", B: "hello", Ret: false}, // 0 + {A: "hello", B: "hell", Ret: true}, + {A: "hello", B: nil, Ret: true}, + {A: "hello", B: 1, Ret: true}, + {A: "hello", B: float64(1.0), Ret: true}, + {A: "hello", B: false, Ret: true}, + {A: 1, B: 1, Ret: false}, + {A: false, B: false, Ret: false}, + {A: float64(3), B: float64(3), Ret: false}, + + {A: "hello", B: []interface{}{}, Ret: true}, // 6 + {A: []interface{}{1}, B: []interface{}{}, Ret: true}, + {A: []interface{}{}, B: []interface{}{}, Ret: false}, + {A: []interface{}{1}, B: []interface{}{1}, Ret: false}, + {A: map[string]interface{}{}, B: []interface{}{1}, Ret: true}, + + {A: map[string]interface{}{}, B: map[string]interface{}{"a": 1}, Ret: false}, // 11 + {A: map[string]interface{}{"a": 1}, B: map[string]interface{}{"a": 1}, Ret: false}, + {A: map[string]interface{}{"a": 1}, B: map[string]interface{}{"a": 2}, Ret: true}, + {A: map[string]interface{}{"a": 1}, B: map[string]interface{}{"b": 2}, Ret: false}, + + { // 15 + A: map[string]interface{}{"a": []interface{}{1}}, + B: map[string]interface{}{"a": []interface{}{1}}, + Ret: false, + }, + { + A: map[string]interface{}{"a": []interface{}{1}}, + B: map[string]interface{}{"a": []interface{}{}}, + Ret: true, + }, + { + A: map[string]interface{}{"a": []interface{}{1}}, + B: map[string]interface{}{"a": 1}, + Ret: true, + }, + } + + for i, testCase := range testCases { + out, err := HasConflicts(testCase.A, testCase.B) + if err != nil { + t.Errorf("%d: unexpected error: %v", i, err) + } + if out != testCase.Ret { + t.Errorf("%d: expected %t got %t", i, testCase.Ret, out) + continue + } + out, err = HasConflicts(testCase.B, testCase.A) + if err != nil { + t.Errorf("%d: unexpected error: %v", i, err) + } + if out != testCase.Ret { + t.Errorf("%d: expected reversed %t got %t", i, testCase.Ret, out) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/sysctl/sysctl.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/sysctl/sysctl.go new file mode 100644 index 000000000000..784a20ff23c5 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/sysctl/sysctl.go @@ -0,0 +1,51 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 sysctl + +import ( + "io/ioutil" + "path" + "strconv" + "strings" +) + +const ( + sysctlBase = "/proc/sys" + VmOvercommitMemory = "vm/overcommit_memory" + VmPanicOnOOM = "vm/panic_on_oom" + + VmOvercommitMemoryAlways = 1 // kernel performs no memory over-commit handling + VmPanicOnOOMInvokeOOMKiller = 0 // kernel calls the oom_killer function when OOM occurs +) + +// GetSysctl returns the value for the specified sysctl setting +func GetSysctl(sysctl string) (int, error) { + data, err := ioutil.ReadFile(path.Join(sysctlBase, sysctl)) + if err != nil { + return -1, err + } + val, err := strconv.Atoi(strings.Trim(string(data), " \n")) + if err != nil { + return -1, err + } + return val, nil +} + +// SetSysctl modifies the specified sysctl flag to the new value +func SetSysctl(sysctl string, newVal int) error { + return ioutil.WriteFile(path.Join(sysctlBase, sysctl), []byte(strconv.Itoa(newVal)), 0640) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/util.go index 2f84a9b2d68f..519203f5971a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/util.go @@ -22,6 +22,7 @@ import ( "encoding/json" "fmt" "io" + "math" "net" "net/http" "os" @@ -40,6 +41,15 @@ import ( // For testing, bypass HandleCrash. var ReallyCrash bool +// For any test of the style: +// ... +// <- time.After(timeout): +// t.Errorf("Timed out") +// The value for timeout should effectively be "forever." Obviously we don't want our tests to truly lock up forever, but 30s +// is long enough that it is effectively forever for the things that can slow down a run on a heavily contended machine +// (GC, seeks, etc), but not so long as to make a developer ctrl-c a test run if they do happen to break that test. +var ForeverTestTimeout = time.Second * 30 + // PanicHandlers is a list of functions which will be invoked when a panic happens. var PanicHandlers = []func(interface{}){logPanic} @@ -191,6 +201,25 @@ func (intstr *IntOrString) Fuzz(c fuzz.Continue) { } } +func GetIntOrPercentValue(intStr *IntOrString) (int, bool, error) { + switch intStr.Kind { + case IntstrInt: + return intStr.IntVal, false, nil + case IntstrString: + s := strings.Replace(intStr.StrVal, "%", "", -1) + v, err := strconv.Atoi(s) + if err != nil { + return 0, false, fmt.Errorf("invalid value %q: %v", intStr.StrVal, err) + } + return v, true, nil + } + return 0, false, fmt.Errorf("invalid value: neither int nor percentage") +} + +func GetValueFromPercent(percent int, value int) int { + return int(math.Ceil(float64(percent) * (float64(value)) / 100)) +} + // Takes a list of strings and compiles them into a list of regular expressions func CompileRegexps(regexpStrings []string) ([]*regexp.Regexp, error) { regexps := []*regexp.Regexp{} @@ -519,3 +548,35 @@ func FileExists(filename string) (bool, error) { } return true, nil } + +// borrowed from ioutil.ReadDir +// ReadDir reads the directory named by dirname and returns +// a list of directory entries, minus those with lstat errors +func ReadDirNoExit(dirname string) ([]os.FileInfo, []error, error) { + if dirname == "" { + dirname = "." + } + + f, err := os.Open(dirname) + if err != nil { + return nil, nil, err + } + defer f.Close() + + names, err := f.Readdirnames(-1) + list := make([]os.FileInfo, 0, len(names)) + errs := make([]error, 0, len(names)) + for _, filename := range names { + fip, lerr := os.Lstat(dirname + "/" + filename) + if os.IsNotExist(lerr) { + // File disappeared between readdir + stat. + // Just treat it as if it didn't exist. + continue + } + + list = append(list, fip) + errs = append(errs, lerr) + } + + return list, errs, nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation/validation.go similarity index 99% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation/validation.go index 20f68317201e..854a7ee7b53c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation/validation.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util +package validation import ( "net" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation/validation_test.go similarity index 99% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation_test.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation/validation_test.go index a0605665b76e..f8434493e099 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/validation/validation_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util +package validation import ( "strings" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wait/wait.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wait/wait.go index 61dab005a1ba..f31349248d19 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wait/wait.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wait/wait.go @@ -45,30 +45,52 @@ type ConditionFunc func() (done bool, err error) // may be missed if the condition takes too long or the time window is too short. // If you want to Poll something forever, see PollInfinite. // Poll always waits the interval before the first check of the condition. -// TODO: create a separate PollImmediate function that does not wait. func Poll(interval, timeout time.Duration, condition ConditionFunc) error { - return WaitFor(poller(interval, timeout), condition) + return pollInternal(poller(interval, timeout), condition) +} + +func pollInternal(wait WaitFunc, condition ConditionFunc) error { + done := make(chan struct{}) + defer close(done) + return WaitFor(wait, condition, done) +} + +func PollImmediate(interval, timeout time.Duration, condition ConditionFunc) error { + return pollImmediateInternal(poller(interval, timeout), condition) +} + +func pollImmediateInternal(wait WaitFunc, condition ConditionFunc) error { + done, err := condition() + if err != nil { + return err + } + if done { + return nil + } + return pollInternal(wait, condition) } // PollInfinite polls forever. func PollInfinite(interval time.Duration, condition ConditionFunc) error { - return WaitFor(poller(interval, 0), condition) + done := make(chan struct{}) + defer close(done) + return WaitFor(poller(interval, 0), condition, done) } // WaitFunc creates a channel that receives an item every time a test // should be executed and is closed when the last test should be invoked. -type WaitFunc func() <-chan struct{} +type WaitFunc func(done <-chan struct{}) <-chan struct{} -// WaitFor gets a channel from wait(), and then invokes c once for every value -// placed on the channel and once more when the channel is closed. If c -// returns an error the loop ends and that error is returned, and if c returns +// WaitFor gets a channel from wait(), and then invokes fn once for every value +// placed on the channel and once more when the channel is closed. If fn +// returns an error the loop ends and that error is returned, and if fn returns // true the loop ends and nil is returned. ErrWaitTimeout will be returned if -// the channel is closed without c ever returning true. -func WaitFor(wait WaitFunc, c ConditionFunc) error { - w := wait() +// the channel is closed without fn ever returning true. +func WaitFor(wait WaitFunc, fn ConditionFunc, done <-chan struct{}) error { + c := wait(done) for { - _, open := <-w - ok, err := c() + _, open := <-c + ok, err := fn() if err != nil { return err } @@ -88,11 +110,15 @@ func WaitFor(wait WaitFunc, c ConditionFunc) error { // the channel is closed. If timeout is 0, the channel // will never be closed. func poller(interval, timeout time.Duration) WaitFunc { - return WaitFunc(func() <-chan struct{} { + return WaitFunc(func(done <-chan struct{}) <-chan struct{} { ch := make(chan struct{}) + go func() { + defer close(ch) + tick := time.NewTicker(interval) defer tick.Stop() + var after <-chan time.Time if timeout != 0 { // time.After is more convenient, but it @@ -102,16 +128,19 @@ func poller(interval, timeout time.Duration) WaitFunc { after = timer.C defer timer.Stop() } + for { select { case <-tick.C: ch <- struct{}{} case <-after: - close(ch) + return + case <-done: return } } }() + return ch }) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wait/wait_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wait/wait_test.go index c7121050305d..315b9b4ca3a6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wait/wait_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wait/wait_test.go @@ -18,13 +18,18 @@ package wait import ( "errors" + "sync/atomic" "testing" "time" + + "k8s.io/kubernetes/pkg/util" ) func TestPoller(t *testing.T) { + done := make(chan struct{}) + defer close(done) w := poller(time.Millisecond, 2*time.Millisecond) - ch := w() + ch := w(done) count := 0 DRAIN: for { @@ -34,7 +39,7 @@ DRAIN: break DRAIN } count++ - case <-time.After(time.Second): + case <-time.After(util.ForeverTestTimeout): t.Errorf("unexpected timeout after poll") } } @@ -43,38 +48,103 @@ DRAIN: } } -func fakeTicker(count int) WaitFunc { - return func() <-chan struct{} { +func fakeTicker(max int, used *int32) WaitFunc { + return func(done <-chan struct{}) <-chan struct{} { ch := make(chan struct{}) go func() { - for i := 0; i < count; i++ { - ch <- struct{}{} + defer close(ch) + for i := 0; i < max; i++ { + select { + case ch <- struct{}{}: + case <-done: + return + } + if used != nil { + atomic.AddInt32(used, 1) + } } - close(ch) }() return ch } } +type fakePoller struct { + max int + used int32 // accessed with atomics +} + +func (fp *fakePoller) GetWaitFunc(interval, timeout time.Duration) WaitFunc { + return fakeTicker(fp.max, &fp.used) +} + func TestPoll(t *testing.T) { invocations := 0 f := ConditionFunc(func() (bool, error) { invocations++ return true, nil }) - if err := Poll(time.Microsecond, time.Microsecond, f); err != nil { + fp := fakePoller{max: 1} + if err := pollInternal(fp.GetWaitFunc(time.Microsecond, time.Microsecond), f); err != nil { t.Fatalf("unexpected error %v", err) } - if invocations == 0 { - t.Errorf("Expected at least one invocation, got zero") + if invocations != 1 { + t.Errorf("Expected exactly one invocation, got %d", invocations) + } + used := atomic.LoadInt32(&fp.used) + if used != 1 { + t.Errorf("Expected exactly one tick, got %d", used) } + expectedError := errors.New("Expected error") f = ConditionFunc(func() (bool, error) { return false, expectedError }) - if err := Poll(time.Microsecond, time.Microsecond, f); err == nil || err != expectedError { + fp = fakePoller{max: 1} + if err := pollInternal(fp.GetWaitFunc(time.Microsecond, time.Microsecond), f); err == nil || err != expectedError { t.Fatalf("Expected error %v, got none %v", expectedError, err) } + if invocations != 1 { + t.Errorf("Expected exactly one invocation, got %d", invocations) + } + used = atomic.LoadInt32(&fp.used) + if used != 1 { + t.Errorf("Expected exactly one tick, got %d", used) + } +} + +func TestPollImmediate(t *testing.T) { + invocations := 0 + f := ConditionFunc(func() (bool, error) { + invocations++ + return true, nil + }) + fp := fakePoller{max: 0} + if err := pollImmediateInternal(fp.GetWaitFunc(time.Microsecond, time.Microsecond), f); err != nil { + t.Fatalf("unexpected error %v", err) + } + if invocations != 1 { + t.Errorf("Expected exactly one invocation, got %d", invocations) + } + used := atomic.LoadInt32(&fp.used) + if used != 0 { + t.Errorf("Expected exactly zero ticks, got %d", used) + } + + expectedError := errors.New("Expected error") + f = ConditionFunc(func() (bool, error) { + return false, expectedError + }) + fp = fakePoller{max: 0} + if err := pollImmediateInternal(fp.GetWaitFunc(time.Microsecond, time.Microsecond), f); err == nil || err != expectedError { + t.Fatalf("Expected error %v, got none %v", expectedError, err) + } + if invocations != 1 { + t.Errorf("Expected exactly one invocation, got %d", invocations) + } + used = atomic.LoadInt32(&fp.used) + if used != 0 { + t.Errorf("Expected exactly zero ticks, got %d", used) + } } func TestPollForever(t *testing.T) { @@ -91,6 +161,7 @@ func TestPollForever(t *testing.T) { } return false, nil }) + if err := PollInfinite(time.Microsecond, f); err != nil { t.Fatalf("unexpected error %v", err) } @@ -109,7 +180,7 @@ func TestPollForever(t *testing.T) { if !open { t.Fatalf("did not expect channel to be closed") } - case <-time.After(time.Second): + case <-time.After(util.ForeverTestTimeout): t.Fatalf("channel did not return at least once within the poll interval") } } @@ -152,7 +223,7 @@ func TestWaitFor(t *testing.T) { return false, nil }), 2, - 3, + 3, // the contract of WaitFor() says the func is called once more at the end of the wait true, }, "returns immediately on error": { @@ -167,8 +238,12 @@ func TestWaitFor(t *testing.T) { } for k, c := range testCases { invocations = 0 - ticker := fakeTicker(c.Ticks) - err := WaitFor(ticker, c.F) + ticker := fakeTicker(c.Ticks, nil) + err := func() error { + done := make(chan struct{}) + defer close(done) + return WaitFor(ticker, c.F, done) + }() switch { case c.Err && err == nil: t.Errorf("%s: Expected error, got nil", k) @@ -178,7 +253,7 @@ func TestWaitFor(t *testing.T) { continue } if invocations != c.Invoked { - t.Errorf("%s: Expected %d invocations, called %d", k, c.Invoked, invocations) + t.Errorf("%s: Expected %d invocations, got %d", k, c.Invoked, invocations) } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wsstream/stream_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wsstream/stream_test.go index 6f5f62a878d6..0bd710c7e8aa 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wsstream/stream_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/wsstream/stream_test.go @@ -130,7 +130,7 @@ func TestStreamClosedDuringRead(t *testing.T) { if !reflect.DeepEqual(data, []byte(input)) { t.Errorf("unexpected server read: %v", data) } - if err == nil || !strings.HasSuffix(err.Error(), "use of closed network connection") { + if err == nil || !strings.Contains(err.Error(), "use of closed network connection") { t.Fatal(err) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/version/version.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/version/version.go index 563151bd1f4b..e337abe4baac 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/version/version.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/version/version.go @@ -16,6 +16,8 @@ limitations under the License. package version +import "github.com/prometheus/client_golang/prometheus" + // Info contains versioning information. // TODO: Add []string of api versions supported? It's still unclear // how we'll want to distribute that information. @@ -45,3 +47,17 @@ func Get() Info { func (info Info) String() string { return info.GitVersion } + +func init() { + buildInfo := prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "kubernetes_build_info", + Help: "A metric with a constant '1' value labeled by major, minor, git version, git commit and git tree state from which Kubernetes was built.", + }, + []string{"major", "minor", "gitVersion", "gitCommit", "gitTreeState"}, + ) + info := Get() + buildInfo.WithLabelValues(info.Major, info.Minor, info.GitVersion, info.GitCommit, info.GitTreeState).Set(1) + + prometheus.MustRegister(buildInfo) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go index ecada1a28af6..d72baf358388 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go @@ -26,7 +26,6 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" @@ -70,9 +69,9 @@ func (plugin *awsElasticBlockStorePlugin) GetAccessModes() []api.PersistentVolum } } -func (plugin *awsElasticBlockStorePlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (plugin *awsElasticBlockStorePlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) { // Inject real implementations here, test through the internal function. - return plugin.newBuilderInternal(spec, pod.UID, &AWSDiskUtil{}, mounter) + return plugin.newBuilderInternal(spec, pod.UID, &AWSDiskUtil{}, plugin.host.GetMounter()) } func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager ebsManager, mounter mount.Interface) (volume.Builder, error) { @@ -107,12 +106,12 @@ func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec, fsType: fsType, partition: partition, readOnly: readOnly, - diskMounter: &mount.SafeFormatAndMount{mounter, exec.New()}}, nil + diskMounter: &mount.SafeFormatAndMount{plugin.host.GetMounter(), exec.New()}}, nil } -func (plugin *awsElasticBlockStorePlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { +func (plugin *awsElasticBlockStorePlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { // Inject real implementations here, test through the internal function. - return plugin.newCleanerInternal(volName, podUID, &AWSDiskUtil{}, mounter) + return plugin.newCleanerInternal(volName, podUID, &AWSDiskUtil{}, plugin.host.GetMounter()) } func (plugin *awsElasticBlockStorePlugin) newCleanerInternal(volName string, podUID types.UID, manager ebsManager, mounter mount.Interface) (volume.Cleaner, error) { @@ -133,7 +132,7 @@ type ebsManager interface { DetachDisk(c *awsElasticBlockStoreCleaner) error } -// awsElasticBlockStore volumes are disk resources provided by Google Compute Engine +// awsElasticBlockStore volumes are disk resources provided by Amazon Web Services // that are attached to the kubelet's host machine and exposed to the pod. type awsElasticBlockStore struct { volName string @@ -156,11 +155,7 @@ func detachDiskLogError(ebs *awsElasticBlockStore) { // getVolumeProvider returns the AWS Volumes interface func (ebs *awsElasticBlockStore) getVolumeProvider() (aws_cloud.Volumes, error) { - name := "aws" - cloud, err := cloudprovider.GetCloudProvider(name, nil) - if err != nil { - return nil, err - } + cloud := ebs.plugin.host.GetCloudProvider() volumes, ok := cloud.(aws_cloud.Volumes) if !ok { return nil, fmt.Errorf("Cloud provider does not support volumes") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs_test.go index 517934b8fc48..81c4938ef7d1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs_test.go @@ -21,7 +21,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util/mount" @@ -192,7 +192,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { o.Add(pv) o.Add(claim) client := &testclient.Fake{} - client.AddReactor("*", "*", testclient.ObjectReaction(o, latest.RESTMapper)) + client.AddReactor("*", "*", testclient.ObjectReaction(o, testapi.Default.RESTMapper())) plugMgr := volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) @@ -201,7 +201,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes spec := volume.NewSpecFromPersistentVolume(pv, true) pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) if !builder.IsReadOnly() { t.Errorf("Expected true for builder.IsReadOnly") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/cephfs/cephfs.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/cephfs/cephfs.go index a98ce1d435be..4dbed2574cb2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/cephfs/cephfs.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/cephfs/cephfs.go @@ -63,7 +63,7 @@ func (plugin *cephfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { } } -func (plugin *cephfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (plugin *cephfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) { cephvs := plugin.getVolumeSource(spec) secret := "" if cephvs.SecretRef != nil { @@ -82,7 +82,7 @@ func (plugin *cephfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume glog.V(1).Infof("found ceph secret info: %s", name) } } - return plugin.newBuilderInternal(spec, pod.UID, mounter, secret) + return plugin.newBuilderInternal(spec, pod.UID, plugin.host.GetMounter(), secret) } func (plugin *cephfsPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, mounter mount.Interface, secret string) (volume.Builder, error) { @@ -110,8 +110,8 @@ func (plugin *cephfsPlugin) newBuilderInternal(spec *volume.Spec, podUID types.U }, nil } -func (plugin *cephfsPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { - return plugin.newCleanerInternal(volName, podUID, mounter) +func (plugin *cephfsPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { + return plugin.newCleanerInternal(volName, podUID, plugin.host.GetMounter()) } func (plugin *cephfsPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/cinder/cinder.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/cinder/cinder.go index 34f47af2de4a..6311142a3769 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/cinder/cinder.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/cinder/cinder.go @@ -62,8 +62,8 @@ func (plugin *cinderPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { } } -func (plugin *cinderPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { - return plugin.newBuilderInternal(spec, pod.UID, &CinderDiskUtil{}, mounter) +func (plugin *cinderPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) { + return plugin.newBuilderInternal(spec, pod.UID, &CinderDiskUtil{}, plugin.host.GetMounter()) } func (plugin *cinderPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager cdManager, mounter mount.Interface) (volume.Builder, error) { @@ -92,8 +92,8 @@ func (plugin *cinderPlugin) newBuilderInternal(spec *volume.Spec, podUID types.U blockDeviceMounter: &cinderSafeFormatAndMount{mounter, exec.New()}}, nil } -func (plugin *cinderPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { - return plugin.newCleanerInternal(volName, podUID, &CinderDiskUtil{}, mounter) +func (plugin *cinderPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { + return plugin.newCleanerInternal(volName, podUID, &CinderDiskUtil{}, plugin.host.GetMounter()) } func (plugin *cinderPlugin) newCleanerInternal(volName string, podUID types.UID, manager cdManager, mounter mount.Interface) (volume.Cleaner, error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go index c1b4b65bb7ff..6772bf981a21 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go @@ -30,7 +30,6 @@ import ( "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" utilErrors "k8s.io/kubernetes/pkg/util/errors" - "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" "github.com/golang/glog" @@ -64,13 +63,12 @@ func (plugin *downwardAPIPlugin) CanSupport(spec *volume.Spec) bool { return spec.Volume != nil && spec.Volume.DownwardAPI != nil } -func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { v := &downwardAPIVolume{ volName: spec.Name(), pod: pod, podUID: pod.UID, plugin: plugin, - mounter: mounter, } v.fieldReferenceFileNames = make(map[string]string) for _, fileInfo := range spec.Volume.DownwardAPI.Items { @@ -81,8 +79,8 @@ func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opt opts: &opts}, nil } -func (plugin *downwardAPIPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { - return &downwardAPIVolumeCleaner{&downwardAPIVolume{volName: volName, podUID: podUID, plugin: plugin, mounter: mounter}}, nil +func (plugin *downwardAPIPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { + return &downwardAPIVolumeCleaner{&downwardAPIVolume{volName: volName, podUID: podUID, plugin: plugin}}, nil } // downwardAPIVolume retrieves downward API data and placing them into the volume on the host. @@ -92,7 +90,6 @@ type downwardAPIVolume struct { pod *api.Pod podUID types.UID // TODO: remove this redundancy as soon NewCleaner func will have *api.POD and not only types.UID plugin *downwardAPIPlugin - mounter mount.Interface } // This is the spec for the volume that this plugin wraps. @@ -121,7 +118,7 @@ func (b *downwardAPIVolumeBuilder) SetUp() error { func (b *downwardAPIVolumeBuilder) SetUpAt(dir string) error { glog.V(3).Infof("Setting up a downwardAPI volume %v for pod %v/%v at %v", b.volName, b.pod.Namespace, b.pod.Name, dir) // Wrap EmptyDir. Here we rely on the idempotency of the wrapped plugin to avoid repeatedly mounting - wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, b.pod, *b.opts, b.mounter) + wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, b.pod, *b.opts) if err != nil { glog.Errorf("Couldn't setup downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error()) return err @@ -151,7 +148,7 @@ func (b *downwardAPIVolumeBuilder) SetUpAt(dir string) error { return nil } -// IsReadOnly func to fullfill volume.Builder interface +// IsReadOnly func to fulfill volume.Builder interface func (d *downwardAPIVolume) IsReadOnly() bool { return true } @@ -173,7 +170,7 @@ func (d *downwardAPIVolume) collectData() (map[string]string, error) { return data, utilErrors.NewAggregate(errlist) } -// isDataChanged iterate over all the entries to check wether at least one +// isDataChanged iterate over all the entries to check whether at least one // file needs to be updated. func (d *downwardAPIVolume) isDataChanged(data map[string]string) bool { for fileName, values := range data { @@ -360,7 +357,7 @@ func (c *downwardAPIVolumeCleaner) TearDownAt(dir string) error { glog.V(3).Infof("Tearing down volume %v for pod %v at %v", c.volName, c.podUID, dir) // Wrap EmptyDir, let it do the teardown. - wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID, c.mounter) + wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID) if err != nil { return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi_test.go index 82d9d72de121..d145182921ec 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi_test.go @@ -27,19 +27,18 @@ import ( client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/types" - "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/empty_dir" ) const basePath = "/tmp/fake" -func formatMap(m map[string]string) string { - var l string +func formatMap(m map[string]string) (fmtstr string) { for key, value := range m { - l += key + "=" + fmt.Sprintf("%q", value) + "\n" + fmtstr += fmt.Sprintf("%v=%q\n", key, value) } - return l + + return } func newTestHost(t *testing.T, client client.Interface) volume.VolumeHost { @@ -64,7 +63,7 @@ func TestCanSupport(t *testing.T) { } func CleanEverything(plugin volume.VolumePlugin, testVolumeName, volumePath string, testPodUID types.UID, t *testing.T) { - cleaner, err := plugin.NewCleaner(testVolumeName, testPodUID, mount.New()) + cleaner, err := plugin.NewCleaner(testVolumeName, testPodUID) if err != nil { t.Errorf("Failed to make a new Cleaner: %v", err) } @@ -117,7 +116,7 @@ func TestLabels(t *testing.T) { t.Errorf("Can't find the plugin by name") } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}} - builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) + builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) @@ -182,7 +181,7 @@ func TestAnnotations(t *testing.T) { t.Errorf("Can't find the plugin by name") } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Annotations: annotations}} - builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) + builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) } @@ -242,7 +241,7 @@ func TestName(t *testing.T) { t.Errorf("Can't find the plugin by name") } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Name: testName}} - builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) + builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) } @@ -303,7 +302,7 @@ func TestNamespace(t *testing.T) { t.Errorf("Can't find the plugin by name") } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Namespace: testNamespace}} - builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) + builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) } @@ -366,7 +365,7 @@ func TestWriteTwiceNoUpdate(t *testing.T) { t.Errorf("Can't find the plugin by name") } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}} - builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) + builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) @@ -450,7 +449,7 @@ func TestWriteTwiceWithUpdate(t *testing.T) { t.Errorf("Can't find the plugin by name") } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}} - builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) + builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) @@ -556,7 +555,7 @@ func TestWriteWithUnixPath(t *testing.T) { t.Errorf("Can't find the plugin by name") } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels, Annotations: annotations}} - builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) + builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) @@ -601,7 +600,8 @@ func TestWriteWithUnixPathBadPath(t *testing.T) { labels := map[string]string{ "key1": "value1", - "key2": "value2"} + "key2": "value2", + } fake := testclient.NewSimpleFake(&api.Pod{ ObjectMeta: api.ObjectMeta{ @@ -614,42 +614,48 @@ func TestWriteWithUnixPathBadPath(t *testing.T) { pluginMgr := volume.VolumePluginMgr{} pluginMgr.InitPlugins(ProbeVolumePlugins(), newTestHost(t, fake)) plugin, err := pluginMgr.FindPluginByName(downwardAPIPluginName) + if err != nil { + t.Errorf("Can't find the plugin by name") + } + volumeSpec := &api.Volume{ Name: testVolumeName, VolumeSource: api.VolumeSource{ DownwardAPI: &api.DownwardAPIVolumeSource{ Items: []api.DownwardAPIVolumeFile{ - {Path: "this//labels", FieldRef: api.ObjectFieldSelector{ - FieldPath: "metadata.labels"}}, - }}}, - } - if err != nil { - t.Errorf("Can't find the plugin by name") + { + Path: "this//labels", + FieldRef: api.ObjectFieldSelector{ + FieldPath: "metadata.labels", + }, + }, + }, + }, + }, } - pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}} - builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) + pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID, Labels: labels}} + builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) if err != nil { - t.Errorf("Failed to make a new Builder: %v", err) - } - if builder == nil { - t.Errorf("Got a nil Builder") + t.Fatalf("Failed to make a new Builder: %v", err) + } else if builder == nil { + t.Fatalf("Got a nil Builder") } volumePath := builder.GetPath() + defer CleanEverything(plugin, testVolumeName, volumePath, testPodUID, t) + err = builder.SetUp() if err != nil { - t.Errorf("Failed to setup volume: %v", err) + t.Fatalf("Failed to setup volume: %v", err) } - var data []byte - data, err = ioutil.ReadFile(path.Join(volumePath, "this/labels")) + data, err := ioutil.ReadFile(path.Join(volumePath, "this/labels")) if err != nil { - t.Errorf(err.Error()) + t.Fatalf(err.Error()) } if sortLines(string(data)) != sortLines(formatMap(labels)) { t.Errorf("Found `%s` expected %s", data, formatMap(labels)) } - CleanEverything(plugin, testVolumeName, volumePath, testPodUID, t) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/empty_dir/empty_dir.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/empty_dir/empty_dir.go index 4af7e8101b46..054998dfca78 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/empty_dir/empty_dir.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/empty_dir/empty_dir.go @@ -23,7 +23,6 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/mount" @@ -70,8 +69,8 @@ func (plugin *emptyDirPlugin) CanSupport(spec *volume.Spec) bool { return false } -func (plugin *emptyDirPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { - return plugin.newBuilderInternal(spec, pod, mounter, &realMountDetector{mounter}, opts, newChconRunner()) +func (plugin *emptyDirPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { + return plugin.newBuilderInternal(spec, pod, plugin.host.GetMounter(), &realMountDetector{plugin.host.GetMounter()}, opts, newChconRunner()) } func (plugin *emptyDirPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface, mountDetector mountDetector, opts volume.VolumeOptions, chconRunner chconRunner) (volume.Builder, error) { @@ -91,9 +90,9 @@ func (plugin *emptyDirPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod }, nil } -func (plugin *emptyDirPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { +func (plugin *emptyDirPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { // Inject real implementations here, test through the internal function. - return plugin.newCleanerInternal(volName, podUID, mounter, &realMountDetector{mounter}) + return plugin.newCleanerInternal(volName, podUID, plugin.host.GetMounter(), &realMountDetector{plugin.host.GetMounter()}) } func (plugin *emptyDirPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface, mountDetector mountDetector) (volume.Cleaner, error) { @@ -167,10 +166,7 @@ func (ed *emptyDir) SetUpAt(dir string) error { // Determine the effective SELinuxOptions to use for this volume. securityContext := "" if selinuxEnabled() { - securityContext, err = ed.determineEffectiveSELinuxOptions() - if err != nil { - return err - } + securityContext = ed.rootContext } switch ed.medium { @@ -189,45 +185,6 @@ func (ed *emptyDir) SetUpAt(dir string) error { return err } -// determineEffectiveSELinuxOptions determines the effective SELinux options -// that should be used for a particular plugin. -func (ed *emptyDir) determineEffectiveSELinuxOptions() (string, error) { - glog.V(4).Infof("Determining effective SELinux context for pod %v/%v", ed.pod.Namespace, ed.pod.Name) - var opts *api.SELinuxOptions - if ed.pod != nil { - // Use the security context, if defined, of the first - // container in the pod to mount this volume - for _, container := range ed.pod.Spec.Containers { - if !volumeutil.ContainerHasVolumeMountForName(&container, ed.volName) { - continue - } - - if container.SecurityContext != nil && - container.SecurityContext.SELinuxOptions != nil { - opts = container.SecurityContext.SELinuxOptions - break - } - } - } - - if opts == nil { - return ed.rootContext, nil - } - - glog.V(4).Infof("Specified security context for pod %v/%v: %v", ed.pod.Namespace, ed.pod.Name, securitycontext.SELinuxOptionsString(opts)) - - rootContextOpts, err := securitycontext.ParseSELinuxOptions(ed.rootContext) - if err != nil { - return "", err - } - - effectiveOpts := securitycontext.ProjectSELinuxOptions(opts, rootContextOpts) - - glog.V(4).Infof("Effective SELinux context for pod %v/%v: %v", ed.pod.Namespace, ed.pod.Name, securitycontext.SELinuxOptionsString(effectiveOpts)) - - return securitycontext.SELinuxOptionsString(effectiveOpts), nil -} - func (ed *emptyDir) IsReadOnly() bool { return false } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/empty_dir/empty_dir_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/empty_dir/empty_dir_test.go index 56ee0f2924d1..3373c91bf826 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/empty_dir/empty_dir_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/empty_dir/empty_dir_test.go @@ -121,45 +121,6 @@ func TestPluginTmpfs(t *testing.T) { expectedTeardownMounts: 1}) } -func TestPluginTmpfs_PodHasSELinuxOptions(t *testing.T) { - if !selinuxEnabled() { - return - } - - doTestPlugin(t, pluginTestConfig{ - medium: api.StorageMediumMemory, - rootContext: "user:role:type:range", - SELinuxOptions: &api.SELinuxOptions{ - Type: "type2", - Level: "level2", - }, - expectedSELinuxContext: "user:role:type2:level2", - expectedChcons: 1, - expectedSetupMounts: 1, - shouldBeMountedBeforeTeardown: true, - expectedTeardownMounts: 1}) -} - -func TestPluginTmpfs_PodHasSELinuxOptions_Idempotent(t *testing.T) { - if !selinuxEnabled() { - return - } - - doTestPlugin(t, pluginTestConfig{ - medium: api.StorageMediumMemory, - rootContext: "user:role:type:range", - SELinuxOptions: &api.SELinuxOptions{ - Type: "type2", - Level: "level2", - }, - idempotent: true, - expectedSELinuxContext: "user:role:type2:level2", - expectedChcons: 0, - expectedSetupMounts: 0, - shouldBeMountedBeforeTeardown: true, - expectedTeardownMounts: 1}) -} - type pluginTestConfig struct { medium api.StorageMedium rootContext string @@ -327,7 +288,7 @@ func TestPluginBackCompat(t *testing.T) { Name: "vol1", } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{RootContext: ""}, nil) + builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{RootContext: ""}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/disk_manager.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/disk_manager.go new file mode 100644 index 000000000000..b7419ecc95bf --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/disk_manager.go @@ -0,0 +1,112 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 fc + +import ( + "os" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/util/mount" +) + +// Abstract interface to disk operations. +type diskManager interface { + MakeGlobalPDName(disk fcDisk) string + // Attaches the disk to the kubelet's host machine. + AttachDisk(b fcDiskBuilder) error + // Detaches the disk from the kubelet's host machine. + DetachDisk(disk fcDiskCleaner, mntPath string) error +} + +// utility to mount a disk based filesystem +func diskSetUp(manager diskManager, b fcDiskBuilder, volPath string, mounter mount.Interface) error { + globalPDPath := manager.MakeGlobalPDName(*b.fcDisk) + // TODO: handle failed mounts here. + noMnt, err := mounter.IsLikelyNotMountPoint(volPath) + + if err != nil && !os.IsNotExist(err) { + glog.Errorf("cannot validate mountpoint: %s", volPath) + return err + } + if !noMnt { + return nil + } + if err := manager.AttachDisk(b); err != nil { + glog.Errorf("failed to attach disk") + return err + } + + if err := os.MkdirAll(volPath, 0750); err != nil { + glog.Errorf("failed to mkdir:%s", volPath) + return err + } + // Perform a bind mount to the full path to allow duplicate mounts of the same disk. + options := []string{"bind"} + if b.readOnly { + options = append(options, "ro") + } + err = mounter.Mount(globalPDPath, volPath, "", options) + if err != nil { + glog.Errorf("failed to bind mount:%s", globalPDPath) + return err + } + return nil +} + +// utility to tear down a disk based filesystem +func diskTearDown(manager diskManager, c fcDiskCleaner, volPath string, mounter mount.Interface) error { + noMnt, err := mounter.IsLikelyNotMountPoint(volPath) + if err != nil { + glog.Errorf("cannot validate mountpoint %s", volPath) + return err + } + if noMnt { + return os.Remove(volPath) + } + + refs, err := mount.GetMountRefs(mounter, volPath) + if err != nil { + glog.Errorf("failed to get reference count %s", volPath) + return err + } + if err := mounter.Unmount(volPath); err != nil { + glog.Errorf("failed to unmount %s", volPath) + return err + } + // If len(refs) is 1, then all bind mounts have been removed, and the + // remaining reference is the global mount. It is safe to detach. + if len(refs) == 1 { + mntPath := refs[0] + if err := manager.DetachDisk(c, mntPath); err != nil { + glog.Errorf("failed to detach disk from %s", mntPath) + return err + } + } + + noMnt, mntErr := mounter.IsLikelyNotMountPoint(volPath) + if mntErr != nil { + glog.Errorf("isMountpoint check failed: %v", mntErr) + return err + } + if noMnt { + if err := os.Remove(volPath); err != nil { + return err + } + } + return nil + +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/doc.go similarity index 76% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/doc.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/doc.go index 63be5769c474..454597efd599 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/doc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2014 The Kubernetes Authors All rights reserved. +Copyright 2015 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,5 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package selinux contains security context constraints SELinux strategy implementations. -package selinux +// Package fc contains the internal representation of +// Fibre Channel (fc) volumes. +package fc diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc.go new file mode 100644 index 000000000000..534fd25e59aa --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc.go @@ -0,0 +1,198 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 fc + +import ( + "fmt" + "strconv" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/types" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/exec" + "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/pkg/volume" +) + +// This is the primary entrypoint for volume plugins. +func ProbeVolumePlugins() []volume.VolumePlugin { + return []volume.VolumePlugin{&fcPlugin{nil, exec.New()}} +} + +type fcPlugin struct { + host volume.VolumeHost + exe exec.Interface +} + +var _ volume.VolumePlugin = &fcPlugin{} +var _ volume.PersistentVolumePlugin = &fcPlugin{} + +const ( + fcPluginName = "kubernetes.io/fc" +) + +func (plugin *fcPlugin) Init(host volume.VolumeHost) { + plugin.host = host +} + +func (plugin *fcPlugin) Name() string { + return fcPluginName +} + +func (plugin *fcPlugin) CanSupport(spec *volume.Spec) bool { + if (spec.Volume != nil && spec.Volume.FC == nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.FC == nil) { + return false + } + // TODO: turn this into a func so CanSupport can be unit tested without + // having to make system calls + // see if /sys/class/fc_transport is there, which indicates fc is connected + _, err := plugin.execCommand("ls", []string{"/sys/class/fc_transport"}) + if err == nil { + return true + } + + return false +} + +func (plugin *fcPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { + return []api.PersistentVolumeAccessMode{ + api.ReadWriteOnce, + api.ReadOnlyMany, + } +} + +func (plugin *fcPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) { + // Inject real implementations here, test through the internal function. + return plugin.newBuilderInternal(spec, pod.UID, &FCUtil{}, plugin.host.GetMounter()) +} + +func (plugin *fcPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Builder, error) { + // fc volumes used directly in a pod have a ReadOnly flag set by the pod author. + // fc volumes used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV + var readOnly bool + var fc *api.FCVolumeSource + if spec.Volume != nil && spec.Volume.FC != nil { + fc = spec.Volume.FC + readOnly = fc.ReadOnly + } else { + fc = spec.PersistentVolume.Spec.FC + readOnly = spec.ReadOnly + } + + if fc.Lun == nil { + return nil, fmt.Errorf("empty lun") + } + + lun := strconv.Itoa(*fc.Lun) + + return &fcDiskBuilder{ + fcDisk: &fcDisk{ + podUID: podUID, + volName: spec.Name(), + wwns: fc.TargetWWNs, + lun: lun, + manager: manager, + mounter: &mount.SafeFormatAndMount{mounter, exec.New()}, + io: &osIOHandler{}, + plugin: plugin}, + fsType: fc.FSType, + readOnly: readOnly, + }, nil +} + +func (plugin *fcPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { + // Inject real implementations here, test through the internal function. + return plugin.newCleanerInternal(volName, podUID, &FCUtil{}, plugin.host.GetMounter()) +} + +func (plugin *fcPlugin) newCleanerInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Cleaner, error) { + return &fcDiskCleaner{&fcDisk{ + podUID: podUID, + volName: volName, + manager: manager, + mounter: mounter, + plugin: plugin, + io: &osIOHandler{}, + }}, nil +} + +func (plugin *fcPlugin) execCommand(command string, args []string) ([]byte, error) { + cmd := plugin.exe.Command(command, args...) + return cmd.CombinedOutput() +} + +type fcDisk struct { + volName string + podUID types.UID + portal string + wwns []string + lun string + plugin *fcPlugin + mounter mount.Interface + // Utility interface that provides API calls to the provider to attach/detach disks. + manager diskManager + // io handler interface + io ioHandler +} + +func (fc *fcDisk) GetPath() string { + name := fcPluginName + // safe to use PodVolumeDir now: volume teardown occurs before pod is cleaned up + return fc.plugin.host.GetPodVolumeDir(fc.podUID, util.EscapeQualifiedNameForDisk(name), fc.volName) +} + +type fcDiskBuilder struct { + *fcDisk + readOnly bool + fsType string +} + +var _ volume.Builder = &fcDiskBuilder{} + +func (b *fcDiskBuilder) SetUp() error { + return b.SetUpAt(b.GetPath()) +} + +func (b *fcDiskBuilder) SetUpAt(dir string) error { + // diskSetUp checks mountpoints and prevent repeated calls + err := diskSetUp(b.manager, *b, dir, b.mounter) + if err != nil { + glog.Errorf("fc: failed to setup") + } + return err +} + +type fcDiskCleaner struct { + *fcDisk +} + +var _ volume.Cleaner = &fcDiskCleaner{} + +func (b *fcDiskBuilder) IsReadOnly() bool { + return b.readOnly +} + +// Unmounts the bind mount, and detaches the disk only if the disk +// resource was the last reference to that disk on the kubelet. +func (c *fcDiskCleaner) TearDown() error { + return c.TearDownAt(c.GetPath()) +} + +func (c *fcDiskCleaner) TearDownAt(dir string) error { + return diskTearDown(c.manager, *c, dir, c.mounter) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_test.go new file mode 100644 index 000000000000..e92cc41dfb41 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_test.go @@ -0,0 +1,252 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 fc + +import ( + "os" + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/client/unversioned/testclient" + "k8s.io/kubernetes/pkg/types" + "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/pkg/volume" +) + +func TestCanSupport(t *testing.T) { + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", nil, nil)) + + plug, err := plugMgr.FindPluginByName("kubernetes.io/fc") + if err != nil { + t.Errorf("Can't find the plugin by name") + } + if plug.Name() != "kubernetes.io/fc" { + t.Errorf("Wrong name: %s", plug.Name()) + } + if plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{}}}) { + t.Errorf("Expected false") + } +} + +func TestGetAccessModes(t *testing.T) { + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", nil, nil)) + + plug, err := plugMgr.FindPersistentPluginByName("kubernetes.io/fc") + if err != nil { + t.Errorf("Can't find the plugin by name") + } + if !contains(plug.GetAccessModes(), api.ReadWriteOnce) || !contains(plug.GetAccessModes(), api.ReadOnlyMany) { + t.Errorf("Expected two AccessModeTypes: %s and %s", api.ReadWriteOnce, api.ReadOnlyMany) + } +} + +func contains(modes []api.PersistentVolumeAccessMode, mode api.PersistentVolumeAccessMode) bool { + for _, m := range modes { + if m == mode { + return true + } + } + return false +} + +type fakeDiskManager struct { + attachCalled bool + detachCalled bool +} + +func (fake *fakeDiskManager) MakeGlobalPDName(disk fcDisk) string { + return "/tmp/fake_fc_path" +} +func (fake *fakeDiskManager) AttachDisk(b fcDiskBuilder) error { + globalPath := b.manager.MakeGlobalPDName(*b.fcDisk) + err := os.MkdirAll(globalPath, 0750) + if err != nil { + return err + } + // Simulate the global mount so that the fakeMounter returns the + // expected number of mounts for the attached disk. + b.mounter.Mount(globalPath, globalPath, b.fsType, nil) + + fake.attachCalled = true + return nil +} + +func (fake *fakeDiskManager) DetachDisk(c fcDiskCleaner, mntPath string) error { + globalPath := c.manager.MakeGlobalPDName(*c.fcDisk) + err := os.RemoveAll(globalPath) + if err != nil { + return err + } + fake.detachCalled = true + return nil +} + +func doTestPlugin(t *testing.T, spec *volume.Spec) { + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", nil, nil)) + + plug, err := plugMgr.FindPluginByName("kubernetes.io/fc") + if err != nil { + t.Errorf("Can't find the plugin by name") + } + fakeManager := &fakeDiskManager{} + fakeMounter := &mount.FakeMounter{} + builder, err := plug.(*fcPlugin).newBuilderInternal(spec, types.UID("poduid"), fakeManager, fakeMounter) + if err != nil { + t.Errorf("Failed to make a new Builder: %v", err) + } + if builder == nil { + t.Errorf("Got a nil Builder: %v") + } + + path := builder.GetPath() + if path != "/tmp/fake/pods/poduid/volumes/kubernetes.io~fc/vol1" { + t.Errorf("Got unexpected path: %s", path) + } + + if err := builder.SetUp(); err != nil { + t.Errorf("Expected success, got: %v", err) + } + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + t.Errorf("SetUp() failed, volume path not created: %s", path) + } else { + t.Errorf("SetUp() failed: %v", err) + } + } + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + t.Errorf("SetUp() failed, volume path not created: %s", path) + } else { + t.Errorf("SetUp() failed: %v", err) + } + } + if !fakeManager.attachCalled { + t.Errorf("Attach was not called") + } + + fakeManager = &fakeDiskManager{} + cleaner, err := plug.(*fcPlugin).newCleanerInternal("vol1", types.UID("poduid"), fakeManager, fakeMounter) + if err != nil { + t.Errorf("Failed to make a new Cleaner: %v", err) + } + if cleaner == nil { + t.Errorf("Got a nil Cleaner: %v") + } + + if err := cleaner.TearDown(); err != nil { + t.Errorf("Expected success, got: %v", err) + } + if _, err := os.Stat(path); err == nil { + t.Errorf("TearDown() failed, volume path still exists: %s", path) + } else if !os.IsNotExist(err) { + t.Errorf("SetUp() failed: %v", err) + } + if !fakeManager.detachCalled { + t.Errorf("Detach was not called") + } +} + +func TestPluginVolume(t *testing.T) { + lun := 0 + vol := &api.Volume{ + Name: "vol1", + VolumeSource: api.VolumeSource{ + FC: &api.FCVolumeSource{ + TargetWWNs: []string{"some_wwn"}, + FSType: "ext4", + Lun: &lun, + }, + }, + } + doTestPlugin(t, volume.NewSpecFromVolume(vol)) +} + +func TestPluginPersistentVolume(t *testing.T) { + lun := 0 + vol := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: "vol1", + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeSource: api.PersistentVolumeSource{ + FC: &api.FCVolumeSource{ + TargetWWNs: []string{"some_wwn"}, + FSType: "ext4", + Lun: &lun, + }, + }, + }, + } + doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false)) +} + +func TestPersistentClaimReadOnlyFlag(t *testing.T) { + lun := 0 + pv := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: "pvA", + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeSource: api.PersistentVolumeSource{ + FC: &api.FCVolumeSource{ + TargetWWNs: []string{"some_wwn"}, + FSType: "ext4", + Lun: &lun, + }, + }, + ClaimRef: &api.ObjectReference{ + Name: "claimA", + }, + }, + } + + claim := &api.PersistentVolumeClaim{ + ObjectMeta: api.ObjectMeta{ + Name: "claimA", + Namespace: "nsA", + }, + Spec: api.PersistentVolumeClaimSpec{ + VolumeName: "pvA", + }, + Status: api.PersistentVolumeClaimStatus{ + Phase: api.ClaimBound, + }, + } + + o := testclient.NewObjects(api.Scheme, api.Scheme) + o.Add(pv) + o.Add(claim) + client := &testclient.Fake{} + client.AddReactor("*", "*", testclient.ObjectReaction(o, testapi.Default.RESTMapper())) + + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) + plug, _ := plugMgr.FindPluginByName(fcPluginName) + + // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes + spec := volume.NewSpecFromPersistentVolume(pv, true) + pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) + + if !builder.IsReadOnly() { + t.Errorf("Expected true for builder.IsReadOnly") + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_util.go new file mode 100644 index 000000000000..b0dbc82b36e4 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_util.go @@ -0,0 +1,200 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 fc + +import ( + "fmt" + "io/ioutil" + "os" + "path" + "path/filepath" + "strings" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/volume" +) + +type ioHandler interface { + ReadDir(dirname string) ([]os.FileInfo, error) + Lstat(name string) (os.FileInfo, error) + EvalSymlinks(path string) (string, error) + WriteFile(filename string, data []byte, perm os.FileMode) error +} + +type osIOHandler struct{} + +func (handler *osIOHandler) ReadDir(dirname string) ([]os.FileInfo, error) { + return ioutil.ReadDir(dirname) +} +func (handler *osIOHandler) Lstat(name string) (os.FileInfo, error) { + return os.Lstat(name) +} +func (handler *osIOHandler) EvalSymlinks(path string) (string, error) { + return filepath.EvalSymlinks(path) +} +func (handler *osIOHandler) WriteFile(filename string, data []byte, perm os.FileMode) error { + return ioutil.WriteFile(filename, data, perm) +} + +// given a disk path like /dev/sdx, find the devicemapper parent +func findMultipathDeviceMapper(disk string, io ioHandler) string { + sys_path := "/sys/block/" + if dirs, err := io.ReadDir(sys_path); err == nil { + for _, f := range dirs { + name := f.Name() + if strings.HasPrefix(name, "dm-") { + if _, err1 := io.Lstat(sys_path + name + "/slaves/" + disk); err1 == nil { + return "/dev/" + name + } + } + } + } + return "" +} + +// given a wwn and lun, find the device and associated devicemapper parent +func findDisk(wwn, lun string, io ioHandler) (string, string) { + fc_path := "-fc-0x" + wwn + "-lun-" + lun + dev_path := "/dev/disk/by-path/" + if dirs, err := io.ReadDir(dev_path); err == nil { + for _, f := range dirs { + name := f.Name() + if strings.Contains(name, fc_path) { + if disk, err1 := io.EvalSymlinks(dev_path + name); err1 == nil { + arr := strings.Split(disk, "/") + l := len(arr) - 1 + dev := arr[l] + dm := findMultipathDeviceMapper(dev, io) + return disk, dm + } + } + } + } + return "", "" +} + +func createMultipathConf(path string, io ioHandler) { + if _, err := os.Lstat(path); err != nil { + data := []byte(`defaults { + find_multipaths yes + user_friendly_names yes +} + + +blacklist { +} +`) + io.WriteFile(path, data, 0664) + } +} + +// rescan scsi bus +func scsiHostRescan(io ioHandler) { + scsi_path := "/sys/class/scsi_host/" + if dirs, err := io.ReadDir(scsi_path); err == nil { + for _, f := range dirs { + name := scsi_path + f.Name() + "/scan" + data := []byte("- - -") + io.WriteFile(name, data, 0666) + } + } +} + +// make a directory like /var/lib/kubelet/plugins/kubernetes.io/pod/fc/target-lun-0 +func makePDNameInternal(host volume.VolumeHost, wwns []string, lun string) string { + return path.Join(host.GetPluginDir(fcPluginName), wwns[0]+"-lun-"+lun) +} + +type FCUtil struct{} + +func (util *FCUtil) MakeGlobalPDName(fc fcDisk) string { + return makePDNameInternal(fc.plugin.host, fc.wwns, fc.lun) +} + +func searchDisk(wwns []string, lun string, io ioHandler) (string, string) { + disk := "" + dm := "" + + rescaned := false + // two-phase search: + // first phase, search existing device path, if a multipath dm is found, exit loop + // otherwise, in second phase, rescan scsi bus and search again, return with any findings + for true { + for _, wwn := range wwns { + disk, dm = findDisk(wwn, lun, io) + // if multipath device is found, break + if dm != "" { + break + } + } + // if a dm is found, exit loop + if rescaned || dm != "" { + break + } + // rescan and search again + // create multipath conf if it is not there + createMultipathConf("/etc/multipath.conf", io) + // rescan scsi bus + scsiHostRescan(io) + rescaned = true + } + return disk, dm +} + +func (util *FCUtil) AttachDisk(b fcDiskBuilder) error { + devicePath := "" + wwns := b.wwns + lun := b.lun + io := b.io + disk, dm := searchDisk(wwns, lun, io) + // if no disk matches input wwn and lun, exit + if disk == "" && dm == "" { + return fmt.Errorf("no fc disk found") + } + + // if multipath devicemapper device is found, use it; otherwise use raw disk + if dm != "" { + devicePath = dm + } else { + devicePath = disk + } + // mount it + globalPDPath := b.manager.MakeGlobalPDName(*b.fcDisk) + noMnt, err := b.mounter.IsLikelyNotMountPoint(globalPDPath) + if !noMnt { + glog.Infof("fc: %s already mounted", globalPDPath) + return nil + } + + if err := os.MkdirAll(globalPDPath, 0750); err != nil { + return fmt.Errorf("fc: failed to mkdir %s, error", globalPDPath) + } + + err = b.mounter.Mount(devicePath, globalPDPath, b.fsType, nil) + if err != nil { + return fmt.Errorf("fc: failed to mount fc volume %s [%s] to %s, error %v", devicePath, b.fsType, globalPDPath, err) + } + + return err +} + +func (util *FCUtil) DetachDisk(c fcDiskCleaner, mntPath string) error { + if err := c.mounter.Unmount(mntPath); err != nil { + return fmt.Errorf("fc detach disk: failed to unmount: %s\nError: %v", mntPath, err) + } + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_util_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_util_test.go new file mode 100644 index 000000000000..dd47cf6ee71e --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/fc/fc_util_test.go @@ -0,0 +1,91 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 fc + +import ( + "os" + "testing" + "time" +) + +type fakeFileInfo struct { + name string +} + +func (fi *fakeFileInfo) Name() string { + return fi.name +} + +func (fi *fakeFileInfo) Size() int64 { + return 0 +} + +func (fi *fakeFileInfo) Mode() os.FileMode { + return 777 +} + +func (fi *fakeFileInfo) ModTime() time.Time { + return time.Now() +} +func (fi *fakeFileInfo) IsDir() bool { + return false +} + +func (fi *fakeFileInfo) Sys() interface{} { + return nil +} + +type fakeIOHandler struct{} + +func (handler *fakeIOHandler) ReadDir(dirname string) ([]os.FileInfo, error) { + switch dirname { + case "/dev/disk/by-path/": + f := &fakeFileInfo{ + name: "pci-0000:41:00.0-fc-0x500a0981891b8dc5-lun-0", + } + return []os.FileInfo{f}, nil + case "/sys/block/": + f := &fakeFileInfo{ + name: "dm-1", + } + return []os.FileInfo{f}, nil + } + return nil, nil +} + +func (handler *fakeIOHandler) Lstat(name string) (os.FileInfo, error) { + return nil, nil +} + +func (handler *fakeIOHandler) EvalSymlinks(path string) (string, error) { + return "/dev/sda", nil +} + +func (handler *fakeIOHandler) WriteFile(filename string, data []byte, perm os.FileMode) error { + return nil +} + +func TestIoHandler(t *testing.T) { + io := &fakeIOHandler{} + wwns := []string{"500a0981891b8dc5"} + lun := "0" + disk, dm := searchDisk(wwns, lun, io) + // if no disk matches input wwn and lun, exit + if disk == "" && dm == "" { + t.Errorf("no fc disk found") + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/doc.go new file mode 100644 index 000000000000..e07a0d519aa1 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 flocker contains the internal representation of Flocker volumes +package flocker diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/plugin.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/plugin.go new file mode 100644 index 000000000000..c6dbca868a7b --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/plugin.go @@ -0,0 +1,232 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 flocker + +import ( + "fmt" + "path" + "strconv" + "time" + + flockerClient "github.com/ClusterHQ/flocker-go" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/types" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/exec" + "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/pkg/volume" + volumeutil "k8s.io/kubernetes/pkg/volume/util" +) + +const ( + flockerPluginName = "kubernetes.io/flocker" + + defaultHost = "localhost" + defaultPort = 4523 + defaultCACertFile = "/etc/flocker/cluster.crt" + defaultClientKeyFile = "/etc/flocker/apiuser.key" + defaultClientCertFile = "/etc/flocker/apiuser.crt" + + timeoutWaitingForVolume = 2 * time.Minute + tickerWaitingForVolume = 5 * time.Second +) + +func ProbeVolumePlugins() []volume.VolumePlugin { + return []volume.VolumePlugin{&flockerPlugin{}} +} + +type flockerPlugin struct { + host volume.VolumeHost +} + +type flocker struct { + datasetName string + path string + pod *api.Pod + mounter mount.Interface + plugin *flockerPlugin +} + +func (p *flockerPlugin) Init(host volume.VolumeHost) { + p.host = host +} + +func (p flockerPlugin) Name() string { + return flockerPluginName +} + +func (p flockerPlugin) CanSupport(spec *volume.Spec) bool { + return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Flocker != nil) || + (spec.Volume != nil && spec.Volume.Flocker != nil) +} + +func (p *flockerPlugin) getFlockerVolumeSource(spec *volume.Spec) (*api.FlockerVolumeSource, bool) { + // AFAIK this will always be r/w, but perhaps for the future it will be needed + readOnly := false + + if spec.Volume != nil && spec.Volume.Flocker != nil { + return spec.Volume.Flocker, readOnly + } + return spec.PersistentVolume.Spec.Flocker, readOnly +} + +func (p *flockerPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { + source, readOnly := p.getFlockerVolumeSource(spec) + builder := flockerBuilder{ + flocker: &flocker{ + datasetName: source.DatasetName, + pod: pod, + mounter: p.host.GetMounter(), + plugin: p, + }, + exe: exec.New(), + opts: opts, + readOnly: readOnly, + } + return &builder, nil +} + +func (p *flockerPlugin) NewCleaner(datasetName string, podUID types.UID) (volume.Cleaner, error) { + // Flocker agent will take care of this, there is nothing we can do here + return nil, nil +} + +type flockerBuilder struct { + *flocker + client flockerClient.Clientable + exe exec.Interface + opts volume.VolumeOptions + readOnly bool +} + +func (b flockerBuilder) GetPath() string { + return b.flocker.path +} + +func (b flockerBuilder) SetUp() error { + return b.SetUpAt(b.flocker.datasetName) +} + +// newFlockerClient uses environment variables and pod attributes to return a +// flocker client capable of talking with the Flocker control service. +func (b flockerBuilder) newFlockerClient() (*flockerClient.Client, error) { + host := getenvOrFallback("FLOCKER_CONTROL_SERVICE_HOST", defaultHost) + portConfig := getenvOrFallback("FLOCKER_CONTROL_SERVICE_PORT", strconv.Itoa(defaultPort)) + port, err := strconv.Atoi(portConfig) + if err != nil { + return nil, err + } + caCertPath := getenvOrFallback("FLOCKER_CONTROL_SERVICE_CA_FILE", defaultCACertFile) + keyPath := getenvOrFallback("FLOCKER_CONTROL_SERVICE_CLIENT_KEY_FILE", defaultClientKeyFile) + certPath := getenvOrFallback("FLOCKER_CONTROL_SERVICE_CLIENT_CERT_FILE", defaultClientCertFile) + + c, err := flockerClient.NewClient(host, port, b.flocker.pod.Status.HostIP, caCertPath, keyPath, certPath) + return c, err +} + +func (b *flockerBuilder) getMetaDir() string { + return path.Join( + b.plugin.host.GetPodPluginDir( + b.flocker.pod.UID, util.EscapeQualifiedNameForDisk(flockerPluginName), + ), + b.datasetName, + ) +} + +/* +SetUpAt will setup a Flocker volume following this flow of calls to the Flocker +control service: + +1. Get the dataset id for the given volume name/dir +2. It should already be there, if it's not the user needs to manually create it +3. Check the current Primary UUID +4. If it doesn't match with the Primary UUID that we got on 2, then we will + need to update the Primary UUID for this volume. +5. Wait until the Primary UUID was updated or timeout. +*/ +func (b flockerBuilder) SetUpAt(dir string) error { + if volumeutil.IsReady(b.getMetaDir()) { + return nil + } + + if b.client == nil { + c, err := b.newFlockerClient() + if err != nil { + return err + } + b.client = c + } + + datasetID, err := b.client.GetDatasetID(dir) + if err != nil { + return err + } + + s, err := b.client.GetDatasetState(datasetID) + if err != nil { + return fmt.Errorf("The volume '%s' is not available in Flocker. You need to create this manually with Flocker CLI before using it.", dir) + } + + primaryUUID, err := b.client.GetPrimaryUUID() + if err != nil { + return err + } + + if s.Primary != primaryUUID { + if err := b.updateDatasetPrimary(datasetID, primaryUUID); err != nil { + return err + } + } + + b.flocker.path = s.Path + volumeutil.SetReady(b.getMetaDir()) + return nil +} + +func (b flockerBuilder) IsReadOnly() bool { + return b.readOnly +} + +// updateDatasetPrimary will update the primary in Flocker and wait for it to +// be ready. If it never gets to ready state it will timeout and error. +func (b flockerBuilder) updateDatasetPrimary(datasetID, primaryUUID string) error { + // We need to update the primary and wait for it to be ready + _, err := b.client.UpdatePrimaryForDataset(primaryUUID, datasetID) + if err != nil { + return err + } + + timeoutChan := time.NewTimer(timeoutWaitingForVolume).C + tickChan := time.NewTicker(tickerWaitingForVolume).C + + for { + if s, err := b.client.GetDatasetState(datasetID); err == nil && s.Primary == primaryUUID { + return nil + } + + select { + case <-timeoutChan: + return fmt.Errorf( + "Timed out waiting for the dataset_id: '%s' to be moved to the primary: '%s'\n%v", + datasetID, primaryUUID, err, + ) + case <-tickChan: + break + } + } + +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/plugin_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/plugin_test.go new file mode 100644 index 000000000000..331197d4c062 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/plugin_test.go @@ -0,0 +1,216 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 flocker + +import ( + "io/ioutil" + "os" + "testing" + + flockerClient "github.com/ClusterHQ/flocker-go" + "github.com/stretchr/testify/assert" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/types" + "k8s.io/kubernetes/pkg/volume" +) + +const pluginName = "kubernetes.io/flocker" + +func newInitializedVolumePlugMgr(t *testing.T) (volume.VolumePluginMgr, string) { + plugMgr := volume.VolumePluginMgr{} + dir, err := ioutil.TempDir("", "flocker") + assert.NoError(t, err) + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost(dir, nil, nil)) + return plugMgr, dir +} + +func TestGetByName(t *testing.T) { + assert := assert.New(t) + plugMgr, _ := newInitializedVolumePlugMgr(t) + + plug, err := plugMgr.FindPluginByName(pluginName) + assert.NotNil(plug, "Can't find the plugin by name") + assert.NoError(err) +} + +func TestCanSupport(t *testing.T) { + assert := assert.New(t) + plugMgr, _ := newInitializedVolumePlugMgr(t) + + plug, err := plugMgr.FindPluginByName(pluginName) + assert.NoError(err) + + specs := map[*volume.Spec]bool{ + &volume.Spec{ + Volume: &api.Volume{ + VolumeSource: api.VolumeSource{ + Flocker: &api.FlockerVolumeSource{}, + }, + }, + }: true, + &volume.Spec{ + PersistentVolume: &api.PersistentVolume{ + Spec: api.PersistentVolumeSpec{ + PersistentVolumeSource: api.PersistentVolumeSource{ + Flocker: &api.FlockerVolumeSource{}, + }, + }, + }, + }: true, + &volume.Spec{ + Volume: &api.Volume{ + VolumeSource: api.VolumeSource{}, + }, + }: false, + } + + for spec, expected := range specs { + actual := plug.CanSupport(spec) + assert.Equal(expected, actual) + } +} + +func TestGetFlockerVolumeSource(t *testing.T) { + assert := assert.New(t) + + p := flockerPlugin{} + + spec := &volume.Spec{ + Volume: &api.Volume{ + VolumeSource: api.VolumeSource{ + Flocker: &api.FlockerVolumeSource{}, + }, + }, + } + vs, ro := p.getFlockerVolumeSource(spec) + assert.False(ro) + assert.Equal(spec.Volume.Flocker, vs) + + spec = &volume.Spec{ + PersistentVolume: &api.PersistentVolume{ + Spec: api.PersistentVolumeSpec{ + PersistentVolumeSource: api.PersistentVolumeSource{ + Flocker: &api.FlockerVolumeSource{}, + }, + }, + }, + } + vs, ro = p.getFlockerVolumeSource(spec) + assert.False(ro) + assert.Equal(spec.PersistentVolume.Spec.Flocker, vs) +} + +func TestNewBuilder(t *testing.T) { + assert := assert.New(t) + + plugMgr, _ := newInitializedVolumePlugMgr(t) + plug, err := plugMgr.FindPluginByName(pluginName) + assert.NoError(err) + + spec := &volume.Spec{ + Volume: &api.Volume{ + VolumeSource: api.VolumeSource{ + Flocker: &api.FlockerVolumeSource{ + DatasetName: "something", + }, + }, + }, + } + + _, err = plug.NewBuilder(spec, &api.Pod{}, volume.VolumeOptions{}) + assert.NoError(err) +} + +func TestNewCleaner(t *testing.T) { + assert := assert.New(t) + + p := flockerPlugin{} + + cleaner, err := p.NewCleaner("", types.UID("")) + assert.Nil(cleaner) + assert.NoError(err) +} + +func TestIsReadOnly(t *testing.T) { + b := flockerBuilder{readOnly: true} + assert.True(t, b.IsReadOnly()) +} + +func TestGetPath(t *testing.T) { + const expectedPath = "/flocker/expected" + + assert := assert.New(t) + + b := flockerBuilder{flocker: &flocker{path: expectedPath}} + assert.Equal(expectedPath, b.GetPath()) +} + +type mockFlockerClient struct { + datasetID, primaryUUID, path string + datasetState *flockerClient.DatasetState +} + +func newMockFlockerClient(mockDatasetID, mockPrimaryUUID, mockPath string) *mockFlockerClient { + return &mockFlockerClient{ + datasetID: mockDatasetID, + primaryUUID: mockPrimaryUUID, + path: mockPath, + datasetState: &flockerClient.DatasetState{ + Path: mockPath, + DatasetID: mockDatasetID, + Primary: mockPrimaryUUID, + }, + } +} + +func (m mockFlockerClient) CreateDataset(metaName string) (*flockerClient.DatasetState, error) { + return m.datasetState, nil +} +func (m mockFlockerClient) GetDatasetState(datasetID string) (*flockerClient.DatasetState, error) { + return m.datasetState, nil +} +func (m mockFlockerClient) GetDatasetID(metaName string) (string, error) { + return m.datasetID, nil +} +func (m mockFlockerClient) GetPrimaryUUID() (string, error) { + return m.primaryUUID, nil +} +func (m mockFlockerClient) UpdatePrimaryForDataset(primaryUUID, datasetID string) (*flockerClient.DatasetState, error) { + return m.datasetState, nil +} + +func TestSetUpAtInternal(t *testing.T) { + const dir = "dir" + mockPath := "expected-to-be-set-properly" // package var + expectedPath := mockPath + + assert := assert.New(t) + + plugMgr, rootDir := newInitializedVolumePlugMgr(t) + if rootDir != "" { + defer os.RemoveAll(rootDir) + } + plug, err := plugMgr.FindPluginByName(flockerPluginName) + assert.NoError(err) + + pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} + b := flockerBuilder{flocker: &flocker{pod: pod, plugin: plug.(*flockerPlugin)}} + b.client = newMockFlockerClient("dataset-id", "primary-uid", mockPath) + + assert.NoError(b.SetUpAt(dir)) + assert.Equal(expectedPath, b.flocker.path) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/util.go new file mode 100644 index 000000000000..25e54f7b1dc0 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/util.go @@ -0,0 +1,28 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 flocker + +import "os" + +// getenvOrDefault returns the value of the enviroment variable if it's set, +// otherwise it return the default value provided. +func getenvOrFallback(key, defaultValue string) string { + if v := os.Getenv(key); v != "" { + return v + } + return defaultValue +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/backend/backend.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/util_test.go similarity index 59% rename from Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/backend/backend.go rename to Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/util_test.go index b4edf75ff5dd..72812f2b06b1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/containers/backend/backend.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/flocker/util_test.go @@ -14,24 +14,24 @@ See the License for the specific language governing permissions and limitations under the License. */ -package main +package flocker import ( - "fmt" - "log" - "net/http" "os" + "testing" + + "github.com/stretchr/testify/assert" ) -func printInfo(resp http.ResponseWriter, req *http.Request) { - name := os.Getenv("POD_NAME") - namespace := os.Getenv("POD_NAMESPACE") - fmt.Fprintf(resp, "Backend Container\n") - fmt.Fprintf(resp, "Backend Pod Name: %v\n", name) - fmt.Fprintf(resp, "Backend Namespace: %v\n", namespace) -} +func TestGetenvOrFallback(t *testing.T) { + const expected = "foo" + + assert := assert.New(t) + + key := "FLOCKER_SET_VAR" + os.Setenv(key, expected) + assert.Equal(expected, getenvOrFallback(key, "~"+expected)) -func main() { - http.HandleFunc("/", printInfo) - log.Fatal(http.ListenAndServe(":5000", nil)) + key = "FLOCKER_UNSET_VAR" + assert.Equal(expected, getenvOrFallback(key, expected)) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go index e48ea049825c..f1bae04a2648 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go @@ -66,9 +66,9 @@ func (plugin *gcePersistentDiskPlugin) GetAccessModes() []api.PersistentVolumeAc } } -func (plugin *gcePersistentDiskPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (plugin *gcePersistentDiskPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) { // Inject real implementations here, test through the internal function. - return plugin.newBuilderInternal(spec, pod.UID, &GCEDiskUtil{}, mounter) + return plugin.newBuilderInternal(spec, pod.UID, &GCEDiskUtil{}, plugin.host.GetMounter()) } func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Builder, error) { @@ -107,9 +107,9 @@ func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, pod diskMounter: &mount.SafeFormatAndMount{mounter, exec.New()}}, nil } -func (plugin *gcePersistentDiskPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { +func (plugin *gcePersistentDiskPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { // Inject real implementations here, test through the internal function. - return plugin.newCleanerInternal(volName, podUID, &GCEDiskUtil{}, mounter) + return plugin.newCleanerInternal(volName, podUID, &GCEDiskUtil{}, plugin.host.GetMounter()) } func (plugin *gcePersistentDiskPlugin) newCleanerInternal(volName string, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Cleaner, error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd_test.go index 2ced180a36db..caa9a64dffe6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd_test.go @@ -21,7 +21,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util/mount" @@ -206,7 +206,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { o.Add(pv) o.Add(claim) client := &testclient.Fake{} - client.AddReactor("*", "*", testclient.ObjectReaction(o, latest.RESTMapper)) + client.AddReactor("*", "*", testclient.ObjectReaction(o, testapi.Default.RESTMapper())) plugMgr := volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) @@ -215,7 +215,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes spec := volume.NewSpecFromPersistentVolume(pv, true) pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) if !builder.IsReadOnly() { t.Errorf("Expected true for builder.IsReadOnly") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_util.go index 47ddeb5f518d..bb3a1020940e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/gce_pd/gce_util.go @@ -40,7 +40,7 @@ const ( diskPartitionSuffix = "-part" diskSDPath = "/dev/sd" diskSDPattern = "/dev/sd*" - maxChecks = 10 + maxChecks = 60 maxRetries = 10 checkSleepDuration = time.Second errorSleepDuration = 5 * time.Second @@ -123,15 +123,17 @@ func (util *GCEDiskUtil) DetachDisk(c *gcePersistentDiskCleaner) error { // Attaches the specified persistent disk device to node, verifies that it is attached, and retries if it fails. func attachDiskAndVerify(b *gcePersistentDiskBuilder, sdBeforeSet sets.String) (string, error) { devicePaths := getDiskByIdPaths(b.gcePersistentDisk) - var gce cloudprovider.Interface + var gceCloud *gce_cloud.GCECloud for numRetries := 0; numRetries < maxRetries; numRetries++ { - if gce == nil { - var err error - gce, err = cloudprovider.GetCloudProvider("gce", nil) - if err != nil || gce == nil { + // Block execution until any pending detach goroutines for this pd have completed + detachCleanupManager.Send(b.pdName, true) + + var err error + if gceCloud == nil { + gceCloud, err = getCloudProvider() + if err != nil || gceCloud == nil { // Retry on error. See issue #11321 - glog.Errorf("Error getting GCECloudProvider while attaching PD %q: %v", b.pdName, err) - gce = nil + glog.Errorf("Error getting GCECloudProvider while detaching PD %q: %v", b.pdName, err) time.Sleep(errorSleepDuration) continue } @@ -141,27 +143,22 @@ func attachDiskAndVerify(b *gcePersistentDiskBuilder, sdBeforeSet sets.String) ( glog.Warningf("Timed out waiting for GCE PD %q to attach. Retrying attach.", b.pdName) } - if err := gce.(*gce_cloud.GCECloud).AttachDisk(b.pdName, b.readOnly); err != nil { - // Retry on error. See issue #11321. Continue and verify if disk is attached, because a - // previous attach operation may still succeed. + if err := gceCloud.AttachDisk(b.pdName, b.readOnly); err != nil { + // Retry on error. See issue #11321. glog.Errorf("Error attaching PD %q: %v", b.pdName, err) + time.Sleep(errorSleepDuration) + continue } for numChecks := 0; numChecks < maxChecks; numChecks++ { - if err := udevadmChangeToNewDrives(sdBeforeSet); err != nil { - // udevadm errors should not block disk attachment, log and continue - glog.Errorf("%v", err) - } - - for _, path := range devicePaths { - if pathExists, err := pathExists(path); err != nil { - // Retry on error. See issue #11321 - glog.Errorf("Error checking if path exists: %v", err) - } else if pathExists { - // A device path has successfully been created for the PD - glog.Infof("Successfully attached GCE PD %q.", b.pdName) - return path, nil - } + path, err := verifyDevicePath(devicePaths, sdBeforeSet) + if err != nil { + // Log error, if any, and continue checking periodically. See issue #11321 + glog.Errorf("Error verifying GCE PD (%q) is attached: %v", b.pdName, err) + } else if path != "" { + // A device path has successfully been created for the PD + glog.Infof("Successfully attached GCE PD %q.", b.pdName) + return path, nil } // Sleep then check again @@ -173,6 +170,24 @@ func attachDiskAndVerify(b *gcePersistentDiskBuilder, sdBeforeSet sets.String) ( return "", fmt.Errorf("Could not attach GCE PD %q. Timeout waiting for mount paths to be created.", b.pdName) } +// Returns the first path that exists, or empty string if none exist. +func verifyDevicePath(devicePaths []string, sdBeforeSet sets.String) (string, error) { + if err := udevadmChangeToNewDrives(sdBeforeSet); err != nil { + // udevadm errors should not block disk detachment, log and continue + glog.Errorf("udevadmChangeToNewDrives failed with: %v", err) + } + + for _, path := range devicePaths { + if pathExists, err := pathExists(path); err != nil { + return "", fmt.Errorf("Error checking if path exists: %v", err) + } else if pathExists { + return path, nil + } + } + + return "", nil +} + // Detaches the specified persistent disk device from node, verifies that it is detached, and retries if it fails. // This function is intended to be called asynchronously as a go routine. // It starts the detachCleanupManager with the specified pdName so that callers can wait for completion. @@ -204,15 +219,14 @@ func detachDiskAndVerify(c *gcePersistentDiskCleaner) { }() devicePaths := getDiskByIdPaths(c.gcePersistentDisk) - var gce cloudprovider.Interface + var gceCloud *gce_cloud.GCECloud for numRetries := 0; numRetries < maxRetries; numRetries++ { - if gce == nil { - var err error - gce, err = cloudprovider.GetCloudProvider("gce", nil) - if err != nil || gce == nil { + var err error + if gceCloud == nil { + gceCloud, err = getCloudProvider() + if err != nil || gceCloud == nil { // Retry on error. See issue #11321 glog.Errorf("Error getting GCECloudProvider while detaching PD %q: %v", c.pdName, err) - gce = nil time.Sleep(errorSleepDuration) continue } @@ -222,27 +236,18 @@ func detachDiskAndVerify(c *gcePersistentDiskCleaner) { glog.Warningf("Timed out waiting for GCE PD %q to detach. Retrying detach.", c.pdName) } - if err := gce.(*gce_cloud.GCECloud).DetachDisk(c.pdName); err != nil { + if err := gceCloud.DetachDisk(c.pdName); err != nil { // Retry on error. See issue #11321. Continue and verify if disk is detached, because a // previous detach operation may still succeed. glog.Errorf("Error detaching PD %q: %v", c.pdName, err) } for numChecks := 0; numChecks < maxChecks; numChecks++ { - allPathsRemoved := true - for _, path := range devicePaths { - if err := udevadmChangeToDrive(path); err != nil { - // udevadm errors should not block disk detachment, log and continue - glog.Errorf("%v", err) - } - if exists, err := pathExists(path); err != nil { - // Retry on error. See issue #11321 - glog.Errorf("Error checking if path exists: %v", err) - } else { - allPathsRemoved = allPathsRemoved && !exists - } - } - if allPathsRemoved { + allPathsRemoved, err := verifyAllPathsRemoved(devicePaths) + if err != nil { + // Log error, if any, and continue checking periodically. + glog.Errorf("Error verifying GCE PD (%q) is detached: %v", c.pdName, err) + } else if allPathsRemoved { // All paths to the PD have been succefully removed glog.Infof("Successfully detached GCE PD %q.", c.pdName) return @@ -258,6 +263,24 @@ func detachDiskAndVerify(c *gcePersistentDiskCleaner) { glog.Errorf("Failed to detach GCE PD %q. One or more mount paths was not removed.", c.pdName) } +// Returns the first path that exists, or empty string if none exist. +func verifyAllPathsRemoved(devicePaths []string) (bool, error) { + allPathsRemoved := true + for _, path := range devicePaths { + if err := udevadmChangeToDrive(path); err != nil { + // udevadm errors should not block disk detachment, log and continue + glog.Errorf("%v", err) + } + if exists, err := pathExists(path); err != nil { + return false, fmt.Errorf("Error checking if path exists: %v", err) + } else { + allPathsRemoved = allPathsRemoved && !exists + } + } + + return allPathsRemoved, nil +} + // Returns list of all /dev/disk/by-id/* paths for given PD. func getDiskByIdPaths(pd *gcePersistentDisk) []string { devicePaths := []string{ @@ -286,6 +309,17 @@ func pathExists(path string) (bool, error) { } } +// Return cloud provider +func getCloudProvider() (*gce_cloud.GCECloud, error) { + gceCloudProvider, err := cloudprovider.GetCloudProvider("gce", nil) + if err != nil || gceCloudProvider == nil { + return nil, err + } + + // The conversion must be safe otherwise bug in GetCloudProvider() + return gceCloudProvider.(*gce_cloud.GCECloud), nil +} + // Calls "udevadm trigger --action=change" for newly created "/dev/sd*" drives (exist only in after set). // This is workaround for Issue #7972. Once the underlying issue has been resolved, this may be removed. func udevadmChangeToNewDrives(sdBeforeSet sets.String) error { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/git_repo/git_repo.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/git_repo/git_repo.go index c15594ec3d98..23a04004727b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/git_repo/git_repo.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/git_repo/git_repo.go @@ -25,7 +25,6 @@ import ( "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/exec" - "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" volumeutil "k8s.io/kubernetes/pkg/volume/util" ) @@ -57,12 +56,11 @@ func (plugin *gitRepoPlugin) CanSupport(spec *volume.Spec) bool { return spec.Volume != nil && spec.Volume.GitRepo != nil } -func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { return &gitRepoVolumeBuilder{ gitRepoVolume: &gitRepoVolume{ volName: spec.Name(), podUID: pod.UID, - mounter: mounter, plugin: plugin, }, pod: *pod, @@ -73,12 +71,11 @@ func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts vo }, nil } -func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { +func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { return &gitRepoVolumeCleaner{ &gitRepoVolume{ volName: volName, podUID: podUID, - mounter: mounter, plugin: plugin, }, }, nil @@ -89,7 +86,6 @@ func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID, mounte type gitRepoVolume struct { volName string podUID types.UID - mounter mount.Interface plugin *gitRepoPlugin } @@ -134,7 +130,7 @@ func (b *gitRepoVolumeBuilder) SetUpAt(dir string) error { } // Wrap EmptyDir, let it do the setup. - wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &b.pod, b.opts, b.mounter) + wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &b.pod, b.opts) if err != nil { return err } @@ -196,7 +192,7 @@ func (c *gitRepoVolumeCleaner) TearDown() error { // TearDownAt simply deletes everything in the directory. func (c *gitRepoVolumeCleaner) TearDownAt(dir string) error { // Wrap EmptyDir, let it do the teardown. - wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID, c.mounter) + wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID) if err != nil { return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/git_repo/git_repo_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/git_repo/git_repo_test.go index 0afba537974f..5f9155041321 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/git_repo/git_repo_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/git_repo/git_repo_test.go @@ -27,7 +27,6 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util/exec" - "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/empty_dir" ) @@ -120,7 +119,7 @@ func TestPlugin(t *testing.T) { }, } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{RootContext: ""}, mount.New()) + builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{RootContext: ""}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) } @@ -142,7 +141,7 @@ func TestPlugin(t *testing.T) { } } - cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"), mount.New()) + cleaner, err := plug.NewCleaner("vol1", types.UID("poduid")) if err != nil { t.Errorf("Failed to make a new Cleaner: %v", err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs.go index 33c4a3515578..e5c658dafd6f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs.go @@ -66,7 +66,7 @@ func (plugin *glusterfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode } } -func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) { source, _ := plugin.getGlusterVolumeSource(spec) ep_name := source.EndpointsName ns := pod.Namespace @@ -76,7 +76,7 @@ func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ vol return nil, err } glog.V(1).Infof("Glusterfs: endpoints %v", ep) - return plugin.newBuilderInternal(spec, ep, pod, mounter, exec.New()) + return plugin.newBuilderInternal(spec, ep, pod, plugin.host.GetMounter(), exec.New()) } func (plugin *glusterfsPlugin) getGlusterVolumeSource(spec *volume.Spec) (*api.GlusterfsVolumeSource, bool) { @@ -104,8 +104,8 @@ func (plugin *glusterfsPlugin) newBuilderInternal(spec *volume.Spec, ep *api.End exe: exe}, nil } -func (plugin *glusterfsPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { - return plugin.newCleanerInternal(volName, podUID, mounter) +func (plugin *glusterfsPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { + return plugin.newCleanerInternal(volName, podUID, plugin.host.GetMounter()) } func (plugin *glusterfsPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs_test.go index 6b42c839f4e4..74250e59e8ef 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/glusterfs/glusterfs_test.go @@ -21,7 +21,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util/exec" @@ -201,7 +201,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { o.Add(claim) o.Add(ep) client := &testclient.Fake{} - client.AddReactor("*", "*", testclient.ObjectReaction(o, latest.RESTMapper)) + client.AddReactor("*", "*", testclient.ObjectReaction(o, testapi.Default.RESTMapper())) plugMgr := volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) @@ -210,7 +210,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes spec := volume.NewSpecFromPersistentVolume(pv, true) pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) if !builder.IsReadOnly() { t.Errorf("Expected true for builder.IsReadOnly") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/host_path/host_path.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/host_path/host_path.go index 02a83851848e..e74320acf98f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/host_path/host_path.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/host_path/host_path.go @@ -18,10 +18,13 @@ package host_path import ( "fmt" + "os" + "regexp" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/types" - "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/volume" ) @@ -34,6 +37,8 @@ func ProbeVolumePlugins(volumeConfig volume.VolumeConfig) []volume.VolumePlugin &hostPathPlugin{ host: nil, newRecyclerFunc: newRecycler, + newDeleterFunc: newDeleter, + newCreaterFunc: newCreater, config: volumeConfig, }, } @@ -44,6 +49,7 @@ func ProbeRecyclableVolumePlugins(recyclerFunc func(spec *volume.Spec, host volu &hostPathPlugin{ host: nil, newRecyclerFunc: recyclerFunc, + newCreaterFunc: newCreater, config: volumeConfig, }, } @@ -51,14 +57,18 @@ func ProbeRecyclableVolumePlugins(recyclerFunc func(spec *volume.Spec, host volu type hostPathPlugin struct { host volume.VolumeHost - // decouple creating recyclers by deferring to a function. Allows for easier testing. + // decouple creating Recyclers/Deleters/Creaters by deferring to a function. Allows for easier testing. newRecyclerFunc func(spec *volume.Spec, host volume.VolumeHost, volumeConfig volume.VolumeConfig) (volume.Recycler, error) + newDeleterFunc func(spec *volume.Spec, host volume.VolumeHost) (volume.Deleter, error) + newCreaterFunc func(options volume.VolumeOptions, host volume.VolumeHost) (volume.Creater, error) config volume.VolumeConfig } var _ volume.VolumePlugin = &hostPathPlugin{} var _ volume.PersistentVolumePlugin = &hostPathPlugin{} var _ volume.RecyclableVolumePlugin = &hostPathPlugin{} +var _ volume.DeletableVolumePlugin = &hostPathPlugin{} +var _ volume.CreatableVolumePlugin = &hostPathPlugin{} const ( hostPathPluginName = "kubernetes.io/host-path" @@ -83,7 +93,7 @@ func (plugin *hostPathPlugin) GetAccessModes() []api.PersistentVolumeAccessMode } } -func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, _ mount.Interface) (volume.Builder, error) { +func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) { if spec.Volume != nil && spec.Volume.HostPath != nil { return &hostPathBuilder{ hostPath: &hostPath{path: spec.Volume.HostPath.Path}, @@ -97,7 +107,7 @@ func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volu } } -func (plugin *hostPathPlugin) NewCleaner(volName string, podUID types.UID, _ mount.Interface) (volume.Cleaner, error) { +func (plugin *hostPathPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { return &hostPathCleaner{&hostPath{""}}, nil } @@ -105,6 +115,17 @@ func (plugin *hostPathPlugin) NewRecycler(spec *volume.Spec) (volume.Recycler, e return plugin.newRecyclerFunc(spec, plugin.host, plugin.config) } +func (plugin *hostPathPlugin) NewDeleter(spec *volume.Spec) (volume.Deleter, error) { + return plugin.newDeleterFunc(spec, plugin.host) +} + +func (plugin *hostPathPlugin) NewCreater(options volume.VolumeOptions) (volume.Creater, error) { + if len(options.AccessModes) == 0 { + options.AccessModes = plugin.GetAccessModes() + } + return plugin.newCreaterFunc(options, plugin.host) +} + func newRecycler(spec *volume.Spec, host volume.VolumeHost, config volume.VolumeConfig) (volume.Recycler, error) { if spec.PersistentVolume == nil || spec.PersistentVolume.Spec.HostPath == nil { return nil, fmt.Errorf("spec.PersistentVolumeSource.HostPath is nil") @@ -118,6 +139,17 @@ func newRecycler(spec *volume.Spec, host volume.VolumeHost, config volume.Volume }, nil } +func newDeleter(spec *volume.Spec, host volume.VolumeHost) (volume.Deleter, error) { + if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.HostPath == nil { + return nil, fmt.Errorf("spec.PersistentVolumeSource.HostPath is nil") + } + return &hostPathDeleter{spec.Name(), spec.PersistentVolume.Spec.HostPath.Path, host}, nil +} + +func newCreater(options volume.VolumeOptions, host volume.VolumeHost) (volume.Creater, error) { + return &hostPathCreater{options: options, host: host}, nil +} + // HostPath volumes represent a bare host file or directory mount. // The direct at the specified path will be directly exposed to the container. type hostPath struct { @@ -169,8 +201,8 @@ func (c *hostPathCleaner) TearDownAt(dir string) error { return fmt.Errorf("TearDownAt() does not make sense for host paths") } -// hostPathRecycler scrubs a hostPath volume by running "rm -rf" on the volume in a pod -// This recycler only works on a single host cluster and is for testing purposes only. +// hostPathRecycler implements a dynamic provisioning Recycler for the HostPath plugin +// This implementation is meant for testing only and only works in a single node cluster type hostPathRecycler struct { name string path string @@ -198,3 +230,64 @@ func (r *hostPathRecycler) Recycle() error { } return volume.RecycleVolumeByWatchingPodUntilCompletion(pod, r.host.GetKubeClient()) } + +// hostPathCreater implements a dynamic provisioning Creater for the HostPath plugin +// This implementation is meant for testing only and only works in a single node cluster. +type hostPathCreater struct { + host volume.VolumeHost + options volume.VolumeOptions +} + +// Create for hostPath simply creates a local /tmp/hostpath_pv/%s directory as a new PersistentVolume. +// This Creater is meant for development and testing only and WILL NOT WORK in a multi-node cluster. +func (r *hostPathCreater) Create() (*api.PersistentVolume, error) { + fullpath := fmt.Sprintf("/tmp/hostpath_pv/%s", util.NewUUID()) + err := os.MkdirAll(fullpath, 0750) + if err != nil { + return nil, err + } + + return &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + GenerateName: "pv-hostpath-", + Labels: map[string]string{ + "createdby": "hostpath dynamic provisioner", + }, + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeReclaimPolicy: r.options.PersistentVolumeReclaimPolicy, + AccessModes: r.options.AccessModes, + Capacity: api.ResourceList{ + api.ResourceName(api.ResourceStorage): resource.MustParse(fmt.Sprintf("%dMi", r.options.CapacityMB)), + }, + PersistentVolumeSource: api.PersistentVolumeSource{ + HostPath: &api.HostPathVolumeSource{ + Path: fullpath, + }, + }, + }, + }, nil +} + +// hostPathDeleter deletes a hostPath PV from the cluster. +// This deleter only works on a single host cluster and is for testing purposes only. +type hostPathDeleter struct { + name string + path string + host volume.VolumeHost +} + +func (r *hostPathDeleter) GetPath() string { + return r.path +} + +// Delete for hostPath removes the local directory so long as it is beneath /tmp/*. +// THIS IS FOR TESTING AND LOCAL DEVELOPMENT ONLY! This message should scare you away from using +// this deleter for anything other than development and testing. +func (r *hostPathDeleter) Delete() error { + regexp := regexp.MustCompile("/tmp/.+") + if !regexp.MatchString(r.GetPath()) { + return fmt.Errorf("host_path deleter only supports /tmp/.+ but received provided %s", r.GetPath()) + } + return os.RemoveAll(r.GetPath()) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/host_path/host_path_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/host_path/host_path_test.go index eae79c61ee76..68a5f8ec4b18 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/host_path/host_path_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/host_path/host_path_test.go @@ -17,12 +17,16 @@ limitations under the License. package host_path import ( + "fmt" + "os" "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/types" + "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/volume" ) @@ -64,7 +68,7 @@ func TestGetAccessModes(t *testing.T) { func TestRecycler(t *testing.T) { plugMgr := volume.VolumePluginMgr{} pluginHost := volume.NewFakeVolumeHost("/tmp/fake", nil, nil) - plugMgr.InitPlugins([]volume.VolumePlugin{&hostPathPlugin{nil, volume.NewFakeRecycler, volume.VolumeConfig{}}}, pluginHost) + plugMgr.InitPlugins([]volume.VolumePlugin{&hostPathPlugin{nil, volume.NewFakeRecycler, nil, nil, volume.VolumeConfig{}}}, pluginHost) spec := &volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{Path: "/foo"}}}}} plug, err := plugMgr.FindRecyclablePluginBySpec(spec) @@ -83,6 +87,101 @@ func TestRecycler(t *testing.T) { } } +func TestDeleter(t *testing.T) { + tempPath := fmt.Sprintf("/tmp/hostpath/%s", util.NewUUID()) + defer os.RemoveAll(tempPath) + err := os.MkdirAll(tempPath, 0750) + if err != nil { + t.Fatal("Failed to create tmp directory for deleter: %v", err) + } + + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), volume.NewFakeVolumeHost("/tmp/fake", nil, nil)) + + spec := &volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{Path: tempPath}}}}} + plug, err := plugMgr.FindDeletablePluginBySpec(spec) + if err != nil { + t.Errorf("Can't find the plugin by name") + } + deleter, err := plug.NewDeleter(spec) + if err != nil { + t.Errorf("Failed to make a new Deleter: %v", err) + } + if deleter.GetPath() != tempPath { + t.Errorf("Expected %s but got %s", tempPath, deleter.GetPath()) + } + if err := deleter.Delete(); err != nil { + t.Errorf("Mock Recycler expected to return nil but got %s", err) + } + if exists, _ := util.FileExists("foo"); exists { + t.Errorf("Temp path expected to be deleted, but was found at %s", tempPath) + } +} + +func TestDeleterTempDir(t *testing.T) { + tests := map[string]struct { + expectedFailure bool + path string + }{ + "just-tmp": {true, "/tmp"}, + "not-tmp": {true, "/nottmp"}, + "good-tmp": {false, "/tmp/scratch"}, + } + + for name, test := range tests { + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), volume.NewFakeVolumeHost("/tmp/fake", nil, nil)) + spec := &volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{Path: test.path}}}}} + plug, _ := plugMgr.FindDeletablePluginBySpec(spec) + deleter, _ := plug.NewDeleter(spec) + err := deleter.Delete() + if err == nil && test.expectedFailure { + t.Errorf("Expected failure for test '%s' but got nil err", name) + } + if err != nil && !test.expectedFailure { + t.Errorf("Unexpected failure for test '%s': %v", name, err) + } + } +} + +func TestCreater(t *testing.T) { + tempPath := "/tmp/hostpath/" + defer os.RemoveAll(tempPath) + err := os.MkdirAll(tempPath, 0750) + + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), volume.NewFakeVolumeHost("/tmp/fake", nil, nil)) + spec := &volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{Path: tempPath}}}}} + plug, err := plugMgr.FindCreatablePluginBySpec(spec) + if err != nil { + t.Errorf("Can't find the plugin by name") + } + creater, err := plug.NewCreater(volume.VolumeOptions{CapacityMB: 100, PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimDelete}) + if err != nil { + t.Errorf("Failed to make a new Creater: %v", err) + } + pv, err := creater.Create() + if err != nil { + t.Errorf("Unexpected error creating volume: %v", err) + } + if pv.Spec.HostPath.Path == "" { + t.Errorf("Expected pv.Spec.HostPath.Path to not be empty: %#v", pv) + } + expectedCapacity := resource.NewQuantity(100*1024*1024, resource.BinarySI) + actualCapacity := pv.Spec.Capacity[api.ResourceStorage] + expectedAmt := expectedCapacity.Value() + actualAmt := actualCapacity.Value() + if expectedAmt != actualAmt { + t.Errorf("Expected capacity %+v but got %+v", expectedAmt, actualAmt) + } + + if pv.Spec.PersistentVolumeReclaimPolicy != api.PersistentVolumeReclaimDelete { + t.Errorf("Expected reclaim policy %+v but got %+v", api.PersistentVolumeReclaimDelete, pv.Spec.PersistentVolumeReclaimPolicy) + } + + os.RemoveAll(pv.Spec.HostPath.Path) +} + func TestPlugin(t *testing.T) { plugMgr := volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), volume.NewFakeVolumeHost("fake", nil, nil)) @@ -96,7 +195,7 @@ func TestPlugin(t *testing.T) { VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{Path: "/vol1"}}, } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{}, nil) + builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) } @@ -113,7 +212,7 @@ func TestPlugin(t *testing.T) { t.Errorf("Expected success, got: %v", err) } - cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"), nil) + cleaner, err := plug.NewCleaner("vol1", types.UID("poduid")) if err != nil { t.Errorf("Failed to make a new Cleaner: %v", err) } @@ -158,7 +257,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { o.Add(pv) o.Add(claim) client := &testclient.Fake{} - client.AddReactor("*", "*", testclient.ObjectReaction(o, latest.RESTMapper)) + client.AddReactor("*", "*", testclient.ObjectReaction(o, testapi.Default.RESTMapper())) plugMgr := volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) @@ -167,7 +266,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes spec := volume.NewSpecFromPersistentVolume(pv, true) pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) if !builder.IsReadOnly() { t.Errorf("Expected true for builder.IsReadOnly") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi.go index ef9dca56fb50..1d67e04385fe 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi.go @@ -75,9 +75,9 @@ func (plugin *iscsiPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { } } -func (plugin *iscsiPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (plugin *iscsiPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) { // Inject real implementations here, test through the internal function. - return plugin.newBuilderInternal(spec, pod.UID, &ISCSIUtil{}, mounter) + return plugin.newBuilderInternal(spec, pod.UID, &ISCSIUtil{}, plugin.host.GetMounter()) } func (plugin *iscsiPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Builder, error) { @@ -110,9 +110,9 @@ func (plugin *iscsiPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UI }, nil } -func (plugin *iscsiPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { +func (plugin *iscsiPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { // Inject real implementations here, test through the internal function. - return plugin.newCleanerInternal(volName, podUID, &ISCSIUtil{}, mounter) + return plugin.newCleanerInternal(volName, podUID, &ISCSIUtil{}, plugin.host.GetMounter()) } func (plugin *iscsiPlugin) newCleanerInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Cleaner, error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi_test.go index 053279e9d88e..9ee8eef97693 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi_test.go @@ -21,7 +21,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util/mount" @@ -235,7 +235,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { o.Add(pv) o.Add(claim) client := &testclient.Fake{} - client.AddReactor("*", "*", testclient.ObjectReaction(o, latest.RESTMapper)) + client.AddReactor("*", "*", testclient.ObjectReaction(o, testapi.Default.RESTMapper())) plugMgr := volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) @@ -244,7 +244,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes spec := volume.NewSpecFromPersistentVolume(pv, true) pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) if !builder.IsReadOnly() { t.Errorf("Expected true for builder.IsReadOnly") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi_util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi_util.go index b3cafdbe9243..ede41cb99bef 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi_util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/iscsi/iscsi_util.go @@ -67,9 +67,9 @@ func getDevicePrefixRefCount(mounter mount.Interface, deviceNamePrefix string) ( return refCount, nil } -// make a directory like /var/lib/kubelet/plugins/kubernetes.io/pod/iscsi/portal-iqn-some_iqn-lun-0 +// make a directory like /var/lib/kubelet/plugins/kubernetes.io/iscsi/portal-some_iqn-lun-lun_id func makePDNameInternal(host volume.VolumeHost, portal string, iqn string, lun string) string { - return path.Join(host.GetPluginDir(iscsiPluginName), "iscsi", portal+"-iqn-"+iqn+"-lun-"+lun) + return path.Join(host.GetPluginDir(iscsiPluginName), portal+"-"+iqn+"-lun-"+lun) } type ISCSIUtil struct{} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/nfs/nfs.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/nfs/nfs.go index dc4352e4f96f..d3fdfb3452d1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/nfs/nfs.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/nfs/nfs.go @@ -79,8 +79,8 @@ func (plugin *nfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { } } -func (plugin *nfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { - return plugin.newBuilderInternal(spec, pod, mounter) +func (plugin *nfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) { + return plugin.newBuilderInternal(spec, pod, plugin.host.GetMounter()) } func (plugin *nfsPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface) (volume.Builder, error) { @@ -106,8 +106,8 @@ func (plugin *nfsPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mou }, nil } -func (plugin *nfsPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { - return plugin.newCleanerInternal(volName, podUID, mounter) +func (plugin *nfsPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { + return plugin.newCleanerInternal(volName, podUID, plugin.host.GetMounter()) } func (plugin *nfsPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/nfs/nfs_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/nfs/nfs_test.go index f95b8cc81d6c..594d6fb707c7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/nfs/nfs_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/nfs/nfs_test.go @@ -21,7 +21,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util/mount" @@ -236,7 +236,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { o.Add(pv) o.Add(claim) client := &testclient.Fake{} - client.AddReactor("*", "*", testclient.ObjectReaction(o, latest.RESTMapper)) + client.AddReactor("*", "*", testclient.ObjectReaction(o, testapi.Default.RESTMapper())) plugMgr := volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) @@ -245,7 +245,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes spec := volume.NewSpecFromPersistentVolume(pv, true) pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) if !builder.IsReadOnly() { t.Errorf("Expected true for builder.IsReadOnly") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/persistent_claim/persistent_claim.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/persistent_claim/persistent_claim.go index f2891f057a1e..de1659d6e939 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/persistent_claim/persistent_claim.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/persistent_claim/persistent_claim.go @@ -18,10 +18,10 @@ package persistent_claim import ( "fmt" + "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/types" - "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" ) @@ -52,7 +52,7 @@ func (plugin *persistentClaimPlugin) CanSupport(spec *volume.Spec) bool { return spec.Volume != nil && spec.Volume.PersistentVolumeClaim != nil } -func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { claim, err := plugin.host.GetKubeClient().PersistentVolumeClaims(pod.Namespace).Get(spec.Volume.PersistentVolumeClaim.ClaimName) if err != nil { glog.Errorf("Error finding claim: %+v\n", spec.Volume.PersistentVolumeClaim.ClaimName) @@ -79,7 +79,7 @@ func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, return nil, err } - builder, err := plugin.host.NewWrapperBuilder(volume.NewSpecFromPersistentVolume(pv, spec.ReadOnly), pod, opts, mounter) + builder, err := plugin.host.NewWrapperBuilder(volume.NewSpecFromPersistentVolume(pv, spec.ReadOnly), pod, opts) if err != nil { glog.Errorf("Error creating builder for claim: %+v\n", claim.Name) return nil, err @@ -92,6 +92,6 @@ func (plugin *persistentClaimPlugin) IsReadOnly() bool { return plugin.readOnly } -func (plugin *persistentClaimPlugin) NewCleaner(_ string, _ types.UID, _ mount.Interface) (volume.Cleaner, error) { +func (plugin *persistentClaimPlugin) NewCleaner(_ string, _ types.UID) (volume.Cleaner, error) { return nil, fmt.Errorf("This will never be called directly. The PV backing this claim has a cleaner. Kubelet uses that cleaner, not this one, when removing orphaned volumes.") } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/persistent_claim/persistent_claim_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/persistent_claim/persistent_claim_test.go index c0843128db7f..89ab507ce5d3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/persistent_claim/persistent_claim_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/persistent_claim/persistent_claim_test.go @@ -249,7 +249,7 @@ func TestNewBuilder(t *testing.T) { } spec := &volume.Spec{Volume: &api.Volume{VolumeSource: item.podVolume}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) if !item.expectedFailure { if err != nil { @@ -304,7 +304,7 @@ func TestNewBuilderClaimNotBound(t *testing.T) { } spec := &volume.Spec{Volume: &api.Volume{VolumeSource: podVolume}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) if builder != nil { t.Errorf("Expected a nil builder if the claim wasn't bound") } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/plugins.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/plugins.go index 3afe7fef939e..1c8b1d48230f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/plugins.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/plugins.go @@ -26,20 +26,28 @@ import ( client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/types" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/errors" + "k8s.io/kubernetes/pkg/util/io" "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/pkg/util/validation" ) // VolumeOptions contains option information about a volume. -// -// Currently, this struct containers only a single field for the -// rootcontext of the volume. This is a temporary measure in order -// to set the rootContext of tmpfs mounts correctly; it will be replaced -// and expanded on by future SecurityContext work. type VolumeOptions struct { // The rootcontext to use when performing mounts for a volume. + // This is a temporary measure in order to set the rootContext of tmpfs mounts correctly. + // it will be replaced and expanded on by future SecurityContext work. RootContext string + + // The attributes below are required by volume.Creater + // perhaps CreaterVolumeOptions struct? + + // CapacityMB is the size in MB of a volume. + CapacityMB int + // AccessModes of a volume + AccessModes []api.PersistentVolumeAccessMode + // Reclamation policy for a persistent volume + PersistentVolumeReclaimPolicy api.PersistentVolumeReclaimPolicy } // VolumePlugin is an interface to volume plugins that can be used on a @@ -64,12 +72,12 @@ type VolumePlugin interface { // Ownership of the spec pointer in *not* transferred. // - spec: The api.Volume spec // - pod: The enclosing pod - NewBuilder(spec *Spec, podRef *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error) + NewBuilder(spec *Spec, podRef *api.Pod, opts VolumeOptions) (Builder, error) // NewCleaner creates a new volume.Cleaner from recoverable state. // - name: The volume name, as per the api.Volume spec. // - podUID: The UID of the enclosing pod - NewCleaner(name string, podUID types.UID, mounter mount.Interface) (Cleaner, error) + NewCleaner(name string, podUID types.UID) (Cleaner, error) } // PersistentVolumePlugin is an extended interface of VolumePlugin and is used @@ -89,6 +97,23 @@ type RecyclableVolumePlugin interface { NewRecycler(spec *Spec) (Recycler, error) } +// DeletableVolumePlugin is an extended interface of VolumePlugin and is used by persistent volumes that want +// to be deleted from the cluster after their release from a PersistentVolumeClaim. +type DeletableVolumePlugin interface { + VolumePlugin + // NewDeleter creates a new volume.Deleter which knows how to delete this resource + // in accordance with the underlying storage provider after the volume's release from a claim + NewDeleter(spec *Spec) (Deleter, error) +} + +// CreatableVolumePlugin is an extended interface of VolumePlugin and is used to create volumes for the cluster. +type CreatableVolumePlugin interface { + VolumePlugin + // NewCreater creates a new volume.Creater which knows how to create PersistentVolumes in accordance with + // the plugin's underlying storage provider + NewCreater(options VolumeOptions) (Creater, error) +} + // VolumeHost is an interface that plugins can use to access the kubelet. type VolumeHost interface { // GetPluginDir returns the absolute path to a directory under which @@ -116,15 +141,21 @@ type VolumeHost interface { // the provided spec. This is used to implement volume plugins which // "wrap" other plugins. For example, the "secret" volume is // implemented in terms of the "emptyDir" volume. - NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error) + NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions) (Builder, error) // NewWrapperCleaner finds an appropriate plugin with which to handle // the provided spec. See comments on NewWrapperBuilder for more // context. - NewWrapperCleaner(spec *Spec, podUID types.UID, mounter mount.Interface) (Cleaner, error) + NewWrapperCleaner(spec *Spec, podUID types.UID) (Cleaner, error) - //Get cloud provider from kubelet + // Get cloud provider from kubelet. GetCloudProvider() cloudprovider.Interface + + // Get mounter interface. + GetMounter() mount.Interface + + // Get writer interface for writing data to disk. + GetWriter() io.Writer } // VolumePluginMgr tracks registered plugins. @@ -217,7 +248,7 @@ func (pm *VolumePluginMgr) InitPlugins(plugins []VolumePlugin, host VolumeHost) allErrs := []error{} for _, plugin := range plugins { name := plugin.Name() - if !util.IsQualifiedName(name) { + if !validation.IsQualifiedName(name) { allErrs = append(allErrs, fmt.Errorf("volume plugin has invalid name: %#v", plugin)) continue } @@ -316,6 +347,32 @@ func (pm *VolumePluginMgr) FindRecyclablePluginBySpec(spec *Spec) (RecyclableVol return nil, fmt.Errorf("no recyclable volume plugin matched") } +// FindDeletablePluginByName fetches a persistent volume plugin by name. If no plugin +// is found, returns error. +func (pm *VolumePluginMgr) FindDeletablePluginBySpec(spec *Spec) (DeletableVolumePlugin, error) { + volumePlugin, err := pm.FindPluginBySpec(spec) + if err != nil { + return nil, err + } + if deletableVolumePlugin, ok := volumePlugin.(DeletableVolumePlugin); ok { + return deletableVolumePlugin, nil + } + return nil, fmt.Errorf("no deletable volume plugin matched") +} + +// FindCreatablePluginBySpec fetches a persistent volume plugin by name. If no plugin +// is found, returns error. +func (pm *VolumePluginMgr) FindCreatablePluginBySpec(spec *Spec) (CreatableVolumePlugin, error) { + volumePlugin, err := pm.FindPluginBySpec(spec) + if err != nil { + return nil, err + } + if creatableVolumePlugin, ok := volumePlugin.(CreatableVolumePlugin); ok { + return creatableVolumePlugin, nil + } + return nil, fmt.Errorf("no creatable volume plugin matched") +} + // NewPersistentVolumeRecyclerPodTemplate creates a template for a recycler pod. By default, a recycler pod simply runs // "rm -rf" on a volume and tests for emptiness. Most attributes of the template will be correct for most // plugin implementations. The following attributes can be overridden per plugin via configuration: diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd.go index 90dece133cd7..7a29ed3578a7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd.go @@ -73,7 +73,7 @@ func (plugin *rbdPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { } } -func (plugin *rbdPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (plugin *rbdPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Builder, error) { secret := "" source, _ := plugin.getRBDVolumeSource(spec) @@ -95,7 +95,7 @@ func (plugin *rbdPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.Vo } // Inject real implementations here, test through the internal function. - return plugin.newBuilderInternal(spec, pod.UID, &RBDUtil{}, mounter, secret) + return plugin.newBuilderInternal(spec, pod.UID, &RBDUtil{}, plugin.host.GetMounter(), secret) } func (plugin *rbdPlugin) getRBDVolumeSource(spec *volume.Spec) (*api.RBDVolumeSource, bool) { @@ -131,7 +131,7 @@ func (plugin *rbdPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, Pool: pool, ReadOnly: readOnly, manager: manager, - mounter: mounter, + mounter: &mount.SafeFormatAndMount{mounter, exec.New()}, plugin: plugin, }, Mon: source.CephMonitors, @@ -142,9 +142,9 @@ func (plugin *rbdPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, }, nil } -func (plugin *rbdPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { +func (plugin *rbdPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { // Inject real implementations here, test through the internal function. - return plugin.newCleanerInternal(volName, podUID, &RBDUtil{}, mounter) + return plugin.newCleanerInternal(volName, podUID, &RBDUtil{}, plugin.host.GetMounter()) } func (plugin *rbdPlugin) newCleanerInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Cleaner, error) { @@ -201,18 +201,8 @@ func (b *rbdBuilder) SetUpAt(dir string) error { err := diskSetUp(b.manager, *b, dir, b.mounter) if err != nil { glog.Errorf("rbd: failed to setup") - return err } - globalPDPath := b.manager.MakeGlobalPDName(*b.rbd) - // make mountpoint rw/ro work as expected - //FIXME revisit pkg/util/mount and ensure rw/ro is implemented as expected - mode := "rw" - if b.ReadOnly { - mode = "ro" - } - b.plugin.execCommand("mount", []string{"-o", "remount," + mode, globalPDPath, dir}) - - return nil + return err } type rbdCleaner struct { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd_test.go index 10060ff1958f..a42f609e1857 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd_test.go @@ -21,7 +21,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util/mount" @@ -192,7 +192,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { o.Add(pv) o.Add(claim) client := &testclient.Fake{} - client.AddReactor("*", "*", testclient.ObjectReaction(o, latest.RESTMapper)) + client.AddReactor("*", "*", testclient.ObjectReaction(o, testapi.Default.RESTMapper())) plugMgr := volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) @@ -201,7 +201,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes spec := volume.NewSpecFromPersistentVolume(pv, true) pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} - builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) if !builder.IsReadOnly() { t.Errorf("Expected true for builder.IsReadOnly") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd_util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd_util.go index f7f36d36ff02..3b2c66cec429 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd_util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/rbd/rbd_util.go @@ -25,31 +25,63 @@ import ( "encoding/json" "errors" "fmt" + "io/ioutil" "math/rand" "os" "path" + "regexp" "strings" "time" "github.com/golang/glog" + "k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/node" "k8s.io/kubernetes/pkg/volume" ) +// search /sys/bus for rbd device that matches given pool and image +func getDevFromImageAndPool(pool, image string) (string, bool) { + // /sys/bus/rbd/devices/X/name and /sys/bus/rbd/devices/X/pool + sys_path := "/sys/bus/rbd/devices" + if dirs, err := ioutil.ReadDir(sys_path); err == nil { + for _, f := range dirs { + // pool and name format: + // see rbd_pool_show() and rbd_name_show() at + // https://github.com/torvalds/linux/blob/master/drivers/block/rbd.c + name := f.Name() + // first match pool, then match name + po := path.Join(sys_path, name, "pool") + img := path.Join(sys_path, name, "name") + exe := exec.New() + out, err := exe.Command("cat", po, img).CombinedOutput() + if err != nil { + continue + } + matched, err := regexp.MatchString("^"+pool+"\n"+image+"\n$", string(out)) + if err != nil || !matched { + continue + } + // found a match, check if device exists + devicePath := "/dev/rbd" + name + if _, err := os.Lstat(devicePath); err == nil { + return devicePath, true + } + } + } + return "", false +} + // stat a path, if not exists, retry maxRetries times -func waitForPathToExist(devicePath string, maxRetries int) bool { +func waitForPath(pool, image string, maxRetries int) (string, bool) { for i := 0; i < maxRetries; i++ { - _, err := os.Stat(devicePath) - if err == nil { - return true - } - if err != nil && !os.IsNotExist(err) { - return false + devicePath, found := getDevFromImageAndPool(pool, image) + if found { + return devicePath, true } time.Sleep(time.Second) } - return false + return "", false } // make a directory like /var/lib/kubelet/plugins/kubernetes.io/pod/rbd/pool-image-image @@ -178,9 +210,9 @@ func (util *RBDUtil) defencing(c rbdCleaner) error { func (util *RBDUtil) AttachDisk(b rbdBuilder) error { var err error - devicePath := strings.Join([]string{"/dev/rbd", b.Pool, b.Image}, "/") - exist := waitForPathToExist(devicePath, 1) - if !exist { + + devicePath, found := waitForPath(b.Pool, b.Image, 1) + if !found { // modprobe _, err = b.plugin.execCommand("modprobe", []string{"rbd"}) if err != nil { @@ -209,8 +241,8 @@ func (util *RBDUtil) AttachDisk(b rbdBuilder) error { if err != nil { return err } - exist = waitForPathToExist(devicePath, 10) - if !exist { + devicePath, found = waitForPath(b.Pool, b.Image, 10) + if !found { return errors.New("Could not map image: Timeout after 10s") } // mount it @@ -230,6 +262,8 @@ func (util *RBDUtil) AttachDisk(b rbdBuilder) error { // fence off other mappers if err := util.fencing(b); err != nil { + // rbd unmap before exit + b.plugin.execCommand("rbd", []string{"unmap", devicePath}) return fmt.Errorf("rbd: image %s is locked by other nodes", b.Image) } // rbd lock remove needs ceph and image config diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/secret/secret.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/secret/secret.go index 2162a42f0118..6591ccfdcc4c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/secret/secret.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/secret/secret.go @@ -18,7 +18,6 @@ package secret import ( "fmt" - "io/ioutil" "os" "path" @@ -26,6 +25,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" + ioutil "k8s.io/kubernetes/pkg/util/io" "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" volumeutil "k8s.io/kubernetes/pkg/volume/util" @@ -59,16 +59,16 @@ func (plugin *secretPlugin) CanSupport(spec *volume.Spec) bool { return spec.Volume != nil && spec.Volume.Secret != nil } -func (plugin *secretPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { +func (plugin *secretPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) { return &secretVolumeBuilder{ - secretVolume: &secretVolume{spec.Name(), pod.UID, plugin, mounter}, + secretVolume: &secretVolume{spec.Name(), pod.UID, plugin, plugin.host.GetMounter(), plugin.host.GetWriter()}, secretName: spec.Volume.Secret.SecretName, pod: *pod, opts: &opts}, nil } -func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { - return &secretVolumeCleaner{&secretVolume{volName, podUID, plugin, mounter}}, nil +func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { + return &secretVolumeCleaner{&secretVolume{volName, podUID, plugin, plugin.host.GetMounter(), plugin.host.GetWriter()}}, nil } type secretVolume struct { @@ -76,6 +76,7 @@ type secretVolume struct { podUID types.UID plugin *secretPlugin mounter mount.Interface + writer ioutil.Writer } var _ volume.Volume = &secretVolume{} @@ -126,7 +127,7 @@ func (b *secretVolumeBuilder) SetUpAt(dir string) error { glog.V(3).Infof("Setting up volume %v for pod %v at %v", b.volName, b.pod.UID, dir) // Wrap EmptyDir, let it do the setup. - wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &b.pod, *b.opts, b.mounter) + wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &b.pod, *b.opts) if err != nil { return err } @@ -155,7 +156,7 @@ func (b *secretVolumeBuilder) SetUpAt(dir string) error { for name, data := range secret.Data { hostFilePath := path.Join(dir, name) glog.V(3).Infof("Writing secret data %v/%v/%v (%v bytes) to host file %v", b.pod.Namespace, b.secretName, name, len(data), hostFilePath) - err := ioutil.WriteFile(hostFilePath, data, 0444) + err := b.writer.WriteFile(hostFilePath, data, 0444) if err != nil { glog.Errorf("Error writing secret data to host path: %v, %v", hostFilePath, err) return err @@ -195,7 +196,7 @@ func (c *secretVolumeCleaner) TearDownAt(dir string) error { glog.V(3).Infof("Tearing down volume %v for pod %v at %v", c.volName, c.podUID, dir) // Wrap EmptyDir, let it do the teardown. - wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID, c.mounter) + wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID) if err != nil { return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/secret/secret_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/secret/secret_test.go index d652bbf72d09..5ccc6aa76541 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/secret/secret_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/secret/secret_test.go @@ -85,7 +85,7 @@ func TestPlugin(t *testing.T) { } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID}} - builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) + builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) } @@ -140,14 +140,14 @@ func TestPluginIdempotent(t *testing.T) { podVolumeDir := fmt.Sprintf("%v/pods/test_pod_uid2/volumes/kubernetes.io~secret/test_volume_name", rootDir) podMetadataDir := fmt.Sprintf("%v/pods/test_pod_uid2/plugins/kubernetes.io~secret/test_volume_name", rootDir) pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID}} - mounter := &mount.FakeMounter{} + mounter := host.GetMounter().(*mount.FakeMounter) mounter.MountPoints = []mount.MountPoint{ { Path: podVolumeDir, }, } util.SetReady(podMetadataDir) - builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, mounter) + builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) } @@ -199,7 +199,7 @@ func TestPluginReboot(t *testing.T) { } pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: testPodUID}} - builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}, &mount.FakeMounter{}) + builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Builder: %v", err) } @@ -275,7 +275,7 @@ func doTestSecretDataInVolume(volumePath string, secret api.Secret, t *testing.T } func doTestCleanAndTeardown(plugin volume.VolumePlugin, podUID types.UID, testVolumeName, volumePath string, t *testing.T) { - cleaner, err := plugin.NewCleaner(testVolumeName, podUID, mount.New()) + cleaner, err := plugin.NewCleaner(testVolumeName, podUID) if err != nil { t.Errorf("Failed to make a new Cleaner: %v", err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/testing.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/testing.go index 31e34de7de06..9244eeda6ab4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/testing.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/testing.go @@ -26,6 +26,7 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/io" "k8s.io/kubernetes/pkg/util/mount" ) @@ -35,10 +36,14 @@ type fakeVolumeHost struct { kubeClient client.Interface pluginMgr VolumePluginMgr cloud cloudprovider.Interface + mounter mount.Interface + writer io.Writer } func NewFakeVolumeHost(rootDir string, kubeClient client.Interface, plugins []VolumePlugin) *fakeVolumeHost { host := &fakeVolumeHost{rootDir: rootDir, kubeClient: kubeClient, cloud: nil} + host.mounter = &mount.FakeMounter{} + host.writer = &io.StdWriter{} host.pluginMgr.InitPlugins(plugins, host) return host } @@ -63,20 +68,28 @@ func (f *fakeVolumeHost) GetCloudProvider() cloudprovider.Interface { return f.cloud } -func (f *fakeVolumeHost) NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error) { +func (f *fakeVolumeHost) GetMounter() mount.Interface { + return f.mounter +} + +func (f *fakeVolumeHost) GetWriter() io.Writer { + return f.writer +} + +func (f *fakeVolumeHost) NewWrapperBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions) (Builder, error) { plug, err := f.pluginMgr.FindPluginBySpec(spec) if err != nil { return nil, err } - return plug.NewBuilder(spec, pod, opts, mounter) + return plug.NewBuilder(spec, pod, opts) } -func (f *fakeVolumeHost) NewWrapperCleaner(spec *Spec, podUID types.UID, mounter mount.Interface) (Cleaner, error) { +func (f *fakeVolumeHost) NewWrapperCleaner(spec *Spec, podUID types.UID) (Cleaner, error) { plug, err := f.pluginMgr.FindPluginBySpec(spec) if err != nil { return nil, err } - return plug.NewCleaner(spec.Name(), podUID, mounter) + return plug.NewCleaner(spec.Name(), podUID) } func ProbeVolumePlugins(config VolumeConfig) []VolumePlugin { @@ -117,11 +130,11 @@ func (plugin *FakeVolumePlugin) CanSupport(spec *Spec) bool { return true } -func (plugin *FakeVolumePlugin) NewBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error) { +func (plugin *FakeVolumePlugin) NewBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions) (Builder, error) { return &FakeVolume{pod.UID, spec.Name(), plugin}, nil } -func (plugin *FakeVolumePlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (Cleaner, error) { +func (plugin *FakeVolumePlugin) NewCleaner(volName string, podUID types.UID) (Cleaner, error) { return &FakeVolume{podUID, volName, plugin}, nil } @@ -129,6 +142,10 @@ func (plugin *FakeVolumePlugin) NewRecycler(spec *Spec) (Recycler, error) { return &fakeRecycler{"/attributesTransferredFromSpec"}, nil } +func (plugin *FakeVolumePlugin) NewDeleter(spec *Spec) (Deleter, error) { + return &FakeDeleter{"/attributesTransferredFromSpec"}, nil +} + func (plugin *FakeVolumePlugin) GetAccessModes() []api.PersistentVolumeAccessMode { return []api.PersistentVolumeAccessMode{} } @@ -184,3 +201,16 @@ func NewFakeRecycler(spec *Spec, host VolumeHost, config VolumeConfig) (Recycler path: spec.PersistentVolume.Spec.HostPath.Path, }, nil } + +type FakeDeleter struct { + path string +} + +func (fd *FakeDeleter) Delete() error { + // nil is success, else error + return nil +} + +func (fd *FakeDeleter) GetPath() string { + return fd.path +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util/util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util/util.go index 093221398092..6b85dec4c0d0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util/util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util/util.go @@ -20,7 +20,6 @@ import ( "os" "path" - "k8s.io/kubernetes/pkg/api" "github.com/golang/glog" ) @@ -61,15 +60,3 @@ func SetReady(dir string) { } file.Close() } - -// ContainerHasVolumeMountForName determines whether the container has -// a volume mount for the volume with the given name. -func ContainerHasVolumeMountForName(container *api.Container, volumeName string) bool { - for _, mount := range container.VolumeMounts { - if mount.Name == volumeName { - return true - } - } - - return false -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util/util_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util/util_test.go deleted file mode 100644 index 6cb5df5dcd43..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util/util_test.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "testing" - - "k8s.io/kubernetes/pkg/api" -) - -func TestContainerHasVolumeMountForName(t *testing.T) { - cases := []struct { - name string - input *api.Container - volumeName string - expected bool - }{ - { - name: "positive", - input: &api.Container{ - VolumeMounts: []api.VolumeMount{ - { - Name: "volName", - }, - }, - }, - volumeName: "volName", - expected: true, - }, - { - name: "negative", - input: &api.Container{ - VolumeMounts: []api.VolumeMount{ - { - Name: "volName2", - }, - }, - }, - volumeName: "volName", - expected: false, - }, - } - - for _, tc := range cases { - actual := ContainerHasVolumeMountForName(tc.input, tc.volumeName) - - if e, a := tc.expected, actual; e != a { - t.Errorf("%v: expected: %v, got: %v", tc.name, e, a) - } - } -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util_test.go index aaef904837e2..5eefb8cc8517 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/util_test.go @@ -18,11 +18,11 @@ package volume import ( "fmt" + "strings" "testing" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" - "strings" ) func TestRecyclerSuccess(t *testing.T) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/volume.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/volume.go index ff2bf29b9445..67ed221b2648 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/volume.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/volume/volume.go @@ -18,6 +18,7 @@ package volume import ( "io/ioutil" + "k8s.io/kubernetes/pkg/api" "os" "path" ) @@ -65,6 +66,20 @@ type Recycler interface { Recycle() error } +// Create adds a new resource in the storage provider and creates a PersistentVolume for the new resource. +// Calls to Create should block until complete. +type Creater interface { + Create() (*api.PersistentVolume, error) +} + +// Delete removes the resource from the underlying storage provider. Calls to this method should block until +// the deletion is complete. Any error returned indicates the volume has failed to be reclaimed. +// A nil return indicates success. +type Deleter interface { + Volume + Delete() error +} + func RenameDirectory(oldPath, newName string) (string, error) { newPath, err := ioutil.TempDir(path.Dir(oldPath), newName) if err != nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/json/decoder_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/json/decoder_test.go index ba7bf7640fc4..95312acb2e3a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/json/decoder_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/json/decoder_test.go @@ -25,6 +25,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/watch" ) @@ -98,7 +99,7 @@ func TestDecoder_SourceClose(t *testing.T) { select { case <-done: break - case <-time.After(10 * time.Second): + case <-time.After(util.ForeverTestTimeout): t.Error("Timeout") } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/mux.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/mux.go index ccae32264fb1..c1cb40f6a8e4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/mux.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/mux.go @@ -59,7 +59,7 @@ type Broadcaster struct { } // NewBroadcaster creates a new Broadcaster. queueLength is the maximum number of events to queue per watcher. -// It is guaranteed that events will be distibuted in the order in which they ocur, +// It is guaranteed that events will be distributed in the order in which they occur, // but the order in which a single event is distributed among all of the watchers is unspecified. func NewBroadcaster(queueLength int, fullChannelBehavior FullChannelBehavior) *Broadcaster { m := &Broadcaster{ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/mux_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/mux_test.go index d3e48279cc68..515833f36097 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/mux_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/watch/mux_test.go @@ -21,6 +21,8 @@ import ( "sync" "testing" "time" + + "k8s.io/kubernetes/pkg/util" ) type myType struct { @@ -110,7 +112,7 @@ func TestBroadcasterWatcherStopDeadlock(t *testing.T) { }(m.Watch(), m.Watch()) m.Action(Added, &myType{}) select { - case <-time.After(5 * time.Second): + case <-time.After(util.ForeverTestTimeout): t.Error("timeout: deadlocked") case <-done: } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/server.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/server.go index 4670def03507..5f00956b6008 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/server.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/server.go @@ -56,6 +56,8 @@ type SchedulerServer struct { Kubeconfig string BindPodsQPS float32 BindPodsBurst int + KubeApiQps float32 + KubeApiBurst int } // NewSchedulerServer creates a new SchedulerServer with default parameters @@ -64,6 +66,10 @@ func NewSchedulerServer() *SchedulerServer { Port: ports.SchedulerPort, Address: net.ParseIP("127.0.0.1"), AlgorithmProvider: factory.DefaultProvider, + BindPodsQPS: 50.0, + BindPodsBurst: 100, + KubeApiQps: 50.0, + KubeApiBurst: 100, } return &s } @@ -77,8 +83,10 @@ func (s *SchedulerServer) AddFlags(fs *pflag.FlagSet) { fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/") fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)") fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.") - fs.Float32Var(&s.BindPodsQPS, "bind-pods-qps", 15.0, "Number of bindings per second scheduler is allowed to continuously make") - fs.IntVar(&s.BindPodsBurst, "bind-pods-burst", 20, "Number of bindings per second scheduler is allowed to make during bursts") + fs.Float32Var(&s.BindPodsQPS, "bind-pods-qps", s.BindPodsQPS, "Number of bindings per second scheduler is allowed to continuously make") + fs.IntVar(&s.BindPodsBurst, "bind-pods-burst", s.BindPodsBurst, "Number of bindings per second scheduler is allowed to make during bursts") + fs.Float32Var(&s.KubeApiQps, "kube-api-qps", s.KubeApiQps, "QPS to use while talking with kubernetes apiserver") + fs.IntVar(&s.KubeApiBurst, "kube-api-burst", s.KubeApiBurst, "Burst to use while talking with kubernetes apiserver") } // Run runs the specified SchedulerServer. This should never exit. @@ -95,8 +103,10 @@ func (s *SchedulerServer) Run(_ []string) error { if err != nil { return err } - kubeconfig.QPS = 20.0 - kubeconfig.Burst = 30 + + // Override kubeconfig qps/burst settings from flags + kubeconfig.QPS = s.KubeApiQps + kubeconfig.Burst = s.KubeApiBurst kubeClient, err := client.New(kubeconfig) if err != nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/exec/admission.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/exec/admission.go index fc33d4a70607..358dc37a3974 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/exec/admission.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/exec/admission.go @@ -90,11 +90,11 @@ func (d *denyExec) Admit(a admission.Attributes) (err error) { return admission.NewForbidden(a, err) } - if d.hostPID && pod.Spec.HostPID { + if d.hostPID && pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostPID { return admission.NewForbidden(a, fmt.Errorf("Cannot exec into or attach to a container using host pid")) } - if d.hostIPC && pod.Spec.HostIPC { + if d.hostIPC && pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostIPC { return admission.NewForbidden(a, fmt.Errorf("Cannot exec into or attach to a container using host ipc")) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/exec/admission_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/exec/admission_test.go index 2a5742aae341..351faf8b7bc7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/exec/admission_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/exec/admission_test.go @@ -34,10 +34,12 @@ func TestAdmission(t *testing.T) { } hostPIDPod := validPod("hostPID") - hostPIDPod.Spec.HostPID = true + hostPIDPod.Spec.SecurityContext = &api.PodSecurityContext{} + hostPIDPod.Spec.SecurityContext.HostPID = true hostIPCPod := validPod("hostIPC") - hostIPCPod.Spec.HostIPC = true + hostIPCPod.Spec.SecurityContext = &api.PodSecurityContext{} + hostIPCPod.Spec.SecurityContext.HostIPC = true testCases := map[string]struct { pod *api.Pod @@ -130,10 +132,12 @@ func TestDenyExecOnPrivileged(t *testing.T) { } hostPIDPod := validPod("hostPID") - hostPIDPod.Spec.HostPID = true + hostPIDPod.Spec.SecurityContext = &api.PodSecurityContext{} + hostPIDPod.Spec.SecurityContext.HostPID = true hostIPCPod := validPod("hostIPC") - hostIPCPod.Spec.HostIPC = true + hostIPCPod.Spec.SecurityContext = &api.PodSecurityContext{} + hostIPCPod.Spec.SecurityContext.HostIPC = true testCases := map[string]struct { pod *api.Pod diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/admission.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/admission.go index 090092cefef8..b3642a66163b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/admission.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/admission.go @@ -19,6 +19,7 @@ package initialresources import ( "flag" "io" + "sort" "strings" "time" @@ -31,14 +32,16 @@ import ( ) var ( - source = flag.String("ir-data-source", "influxdb", "Data source used by InitialResources. Supported options: influxdb.") + source = flag.String("ir-data-source", "influxdb", "Data source used by InitialResources. Supported options: influxdb, gcm.") percentile = flag.Int64("ir-percentile", 90, "Which percentile of samples should InitialResources use when estimating resources. For experiment purposes.") + nsOnly = flag.Bool("ir-namespace-only", false, "Whether the estimation should be made only based on data from the same namespace.") ) const ( - samplesThreshold = 60 - week = 7 * 24 * time.Hour - month = 30 * 24 * time.Hour + initialResourcesAnnotation = "kubernetes.io/initial-resources" + samplesThreshold = 30 + week = 7 * 24 * time.Hour + month = 30 * 24 * time.Hour ) // WARNING: this feature is experimental and will definitely change. @@ -48,19 +51,23 @@ func init() { if err != nil { return nil, err } - return newInitialResources(s), nil + return newInitialResources(s, *percentile, *nsOnly), nil }) } type initialResources struct { *admission.Handler - source dataSource + source dataSource + percentile int64 + nsOnly bool } -func newInitialResources(source dataSource) admission.Interface { +func newInitialResources(source dataSource, percentile int64, nsOnly bool) admission.Interface { return &initialResources{ - Handler: admission.NewHandler(admission.Create), - source: source, + Handler: admission.NewHandler(admission.Create), + source: source, + percentile: percentile, + nsOnly: nsOnly, } } @@ -81,6 +88,7 @@ func (ir initialResources) Admit(a admission.Attributes) (err error) { // The method veryfies whether resources should be set for the given pod and // if there is estimation available the method fills Request field. func (ir initialResources) estimateAndFillResourcesIfNotSet(pod *api.Pod) { + annotations := []string{} for i := range pod.Spec.Containers { c := &pod.Spec.Containers[i] req := c.Resources.Requests @@ -89,7 +97,7 @@ func (ir initialResources) estimateAndFillResourcesIfNotSet(pod *api.Pod) { var err error if _, ok := req[api.ResourceCPU]; !ok { if _, ok2 := lim[api.ResourceCPU]; !ok2 { - cpu, err = ir.getEstimation(api.ResourceCPU, c) + cpu, err = ir.getEstimation(api.ResourceCPU, c, pod.ObjectMeta.Namespace) if err != nil { glog.Errorf("Error while trying to estimate resources: %v", err) } @@ -97,7 +105,7 @@ func (ir initialResources) estimateAndFillResourcesIfNotSet(pod *api.Pod) { } if _, ok := req[api.ResourceMemory]; !ok { if _, ok2 := lim[api.ResourceMemory]; !ok2 { - mem, err = ir.getEstimation(api.ResourceMemory, c) + mem, err = ir.getEstimation(api.ResourceMemory, c, pod.ObjectMeta.Namespace) if err != nil { glog.Errorf("Error while trying to estimate resources: %v", err) } @@ -109,41 +117,82 @@ func (ir initialResources) estimateAndFillResourcesIfNotSet(pod *api.Pod) { c.Resources.Requests = api.ResourceList{} req = c.Resources.Requests } + setRes := []string{} if cpu != nil { glog.Infof("CPU estimation for container %v in pod %v/%v is %v", c.Name, pod.ObjectMeta.Namespace, pod.ObjectMeta.Name, cpu.String()) + setRes = append(setRes, string(api.ResourceCPU)) req[api.ResourceCPU] = *cpu } if mem != nil { glog.Infof("Memory estimation for container %v in pod %v/%v is %v", c.Name, pod.ObjectMeta.Namespace, pod.ObjectMeta.Name, mem.String()) + setRes = append(setRes, string(api.ResourceMemory)) req[api.ResourceMemory] = *mem } + if len(setRes) > 0 { + sort.Strings(setRes) + a := strings.Join(setRes, ", ") + " request for container " + c.Name + annotations = append(annotations, a) + } + } + if len(annotations) > 0 { + if pod.ObjectMeta.Annotations == nil { + pod.ObjectMeta.Annotations = make(map[string]string) + } + val := "Initial Resources plugin set: " + strings.Join(annotations, "; ") + pod.ObjectMeta.Annotations[initialResourcesAnnotation] = val } - // TODO(piosz): verify the estimates fits in LimitRanger } -func (ir initialResources) getEstimation(kind api.ResourceName, c *api.Container) (*resource.Quantity, error) { +func (ir initialResources) getEstimation(kind api.ResourceName, c *api.Container, ns string) (*resource.Quantity, error) { end := time.Now() start := end.Add(-week) var usage, samples int64 var err error - // Historical data from last 7 days for the same image:tag. - if usage, samples, err = ir.source.GetUsagePercentile(kind, *percentile, c.Image, true, start, end); err != nil { + // Historical data from last 7 days for the same image:tag within the same namespace. + if usage, samples, err = ir.source.GetUsagePercentile(kind, ir.percentile, c.Image, ns, true, start, end); err != nil { return nil, err } if samples < samplesThreshold { - // Historical data from last 30 days for the same image:tag. + // Historical data from last 30 days for the same image:tag within the same namespace. start := end.Add(-month) - if usage, samples, err = ir.source.GetUsagePercentile(kind, *percentile, c.Image, true, start, end); err != nil { + if usage, samples, err = ir.source.GetUsagePercentile(kind, ir.percentile, c.Image, ns, true, start, end); err != nil { return nil, err } } - if samples < samplesThreshold { - // Historical data from last 30 days for the same image. - start := end.Add(-month) - image := strings.Split(c.Image, ":")[0] - if usage, samples, err = ir.source.GetUsagePercentile(kind, *percentile, image, false, start, end); err != nil { - return nil, err + + // If we are allowed to estimate only based on data from the same namespace. + if ir.nsOnly { + if samples < samplesThreshold { + // Historical data from last 30 days for the same image within the same namespace. + start := end.Add(-month) + image := strings.Split(c.Image, ":")[0] + if usage, samples, err = ir.source.GetUsagePercentile(kind, ir.percentile, image, ns, false, start, end); err != nil { + return nil, err + } + } + } else { + if samples < samplesThreshold { + // Historical data from last 7 days for the same image:tag within all namespaces. + start := end.Add(-week) + if usage, samples, err = ir.source.GetUsagePercentile(kind, ir.percentile, c.Image, "", true, start, end); err != nil { + return nil, err + } + } + if samples < samplesThreshold { + // Historical data from last 30 days for the same image:tag within all namespaces. + start := end.Add(-month) + if usage, samples, err = ir.source.GetUsagePercentile(kind, ir.percentile, c.Image, "", true, start, end); err != nil { + return nil, err + } + } + if samples < samplesThreshold { + // Historical data from last 30 days for the same image within all namespaces. + start := end.Add(-month) + image := strings.Split(c.Image, ":")[0] + if usage, samples, err = ir.source.GetUsagePercentile(kind, ir.percentile, image, "", false, start, end); err != nil { + return nil, err + } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/admission_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/admission_test.go index 2bfaada487cb..8fe0ea01f6d2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/admission_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/admission_test.go @@ -26,11 +26,11 @@ import ( ) type fakeSource struct { - f func(kind api.ResourceName, perc int64, image string, exactMatch bool, start, end time.Time) (int64, int64, error) + f func(kind api.ResourceName, perc int64, image, namespace string, exactMatch bool, start, end time.Time) (int64, int64, error) } -func (s *fakeSource) GetUsagePercentile(kind api.ResourceName, perc int64, image string, exactMatch bool, start, end time.Time) (usage int64, samples int64, err error) { - return s.f(kind, perc, image, exactMatch, start, end) +func (s *fakeSource) GetUsagePercentile(kind api.ResourceName, perc int64, image, namespace string, exactMatch bool, start, end time.Time) (usage int64, samples int64, err error) { + return s.f(kind, perc, image, namespace, exactMatch, start, end) } func parseReq(cpu, mem string) api.ResourceList { @@ -55,18 +55,18 @@ func addContainer(pod *api.Pod, name, image string, request api.ResourceList) { }) } -func createPod(name string, image string, request api.ResourceList) api.Pod { - pod := api.Pod{ - ObjectMeta: api.ObjectMeta{Name: name, Namespace: "test"}, +func createPod(name string, image string, request api.ResourceList) *api.Pod { + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{Name: name, Namespace: "test-ns"}, Spec: api.PodSpec{}, } pod.Spec.Containers = []api.Container{} - addContainer(&pod, "c0", image, request) + addContainer(pod, "c0", image, request) return pod } -func getPods() []api.Pod { - return []api.Pod{ +func getPods() []*api.Pod { + return []*api.Pod{ createPod("p0", "image:v0", parseReq("", "")), createPod("p1", "image:v1", parseReq("", "300")), createPod("p2", "image:v2", parseReq("300m", "")), @@ -88,79 +88,116 @@ func verifyPod(t *testing.T, pod *api.Pod, cpu, mem int64) { verifyContainer(t, &pod.Spec.Containers[0], cpu, mem) } -func admit(t *testing.T, ir admission.Interface, pods []api.Pod) { +func verifyAnnotation(t *testing.T, pod *api.Pod, expected string) { + a, ok := pod.ObjectMeta.Annotations[initialResourcesAnnotation] + if !ok { + t.Errorf("No annotation but expected %v", expected) + } + if a != expected { + t.Errorf("Wrong annatation set by Initial Resources: got %v, expected %v", a, expected) + } +} + +func expectNoAnnotation(t *testing.T, pod *api.Pod) { + if a, ok := pod.ObjectMeta.Annotations[initialResourcesAnnotation]; ok { + t.Errorf("Expected no annatation but got %v", a) + } +} + +func admit(t *testing.T, ir admission.Interface, pods []*api.Pod) { for i := range pods { - p := &pods[i] + p := pods[i] if err := ir.Admit(admission.NewAttributesRecord(p, "Pod", "test", p.ObjectMeta.Name, "pods", "", admission.Create, nil)); err != nil { t.Error(err) } } } -func TestEstimationBasedOnTheSameImage7d(t *testing.T) { - f := func(_ api.ResourceName, _ int64, _ string, exactMatch bool, start, end time.Time) (int64, int64, error) { - if exactMatch && end.Sub(start) == week { +func performTest(t *testing.T, ir admission.Interface) { + pods := getPods() + admit(t, ir, pods) + + verifyPod(t, pods[0], 100, 100) + verifyPod(t, pods[1], 100, 300) + verifyPod(t, pods[2], 300, 100) + verifyPod(t, pods[3], 300, 300) + + verifyAnnotation(t, pods[0], "Initial Resources plugin set: cpu, memory request for container c0") + verifyAnnotation(t, pods[1], "Initial Resources plugin set: cpu request for container c0") + verifyAnnotation(t, pods[2], "Initial Resources plugin set: memory request for container c0") + expectNoAnnotation(t, pods[3]) +} + +func TestEstimationBasedOnTheSameImageSameNamespace7d(t *testing.T) { + f := func(_ api.ResourceName, _ int64, _, ns string, exactMatch bool, start, end time.Time) (int64, int64, error) { + if exactMatch && end.Sub(start) == week && ns == "test-ns" { return 100, 120, nil } return 200, 120, nil } - ir := newInitialResources(&fakeSource{f: f}) + performTest(t, newInitialResources(&fakeSource{f: f}, 90, false)) - pods := getPods() - admit(t, ir, pods) - - verifyPod(t, &pods[0], 100, 100) - verifyPod(t, &pods[1], 100, 300) - verifyPod(t, &pods[2], 300, 100) - verifyPod(t, &pods[3], 300, 300) } -func TestEstimationBasedOnTheSameImage30d(t *testing.T) { - f := func(_ api.ResourceName, _ int64, _ string, exactMatch bool, start, end time.Time) (int64, int64, error) { - if exactMatch && end.Sub(start) == week { +func TestEstimationBasedOnTheSameImageSameNamespace30d(t *testing.T) { + f := func(_ api.ResourceName, _ int64, _, ns string, exactMatch bool, start, end time.Time) (int64, int64, error) { + if exactMatch && end.Sub(start) == week && ns == "test-ns" { return 200, 20, nil } - if exactMatch && end.Sub(start) == month { + if exactMatch && end.Sub(start) == month && ns == "test-ns" { return 100, 120, nil } return 200, 120, nil } - ir := newInitialResources(&fakeSource{f: f}) + performTest(t, newInitialResources(&fakeSource{f: f}, 90, false)) +} - pods := getPods() - admit(t, ir, pods) +func TestEstimationBasedOnTheSameImageAllNamespaces7d(t *testing.T) { + f := func(_ api.ResourceName, _ int64, _, ns string, exactMatch bool, start, end time.Time) (int64, int64, error) { + if exactMatch && ns == "test-ns" { + return 200, 20, nil + } + if exactMatch && end.Sub(start) == week && ns == "" { + return 100, 120, nil + } + return 200, 120, nil + } + performTest(t, newInitialResources(&fakeSource{f: f}, 90, false)) +} - verifyPod(t, &pods[0], 100, 100) - verifyPod(t, &pods[1], 100, 300) - verifyPod(t, &pods[2], 300, 100) - verifyPod(t, &pods[3], 300, 300) +func TestEstimationBasedOnTheSameImageAllNamespaces30d(t *testing.T) { + f := func(_ api.ResourceName, _ int64, _, ns string, exactMatch bool, start, end time.Time) (int64, int64, error) { + if exactMatch && ns == "test-ns" { + return 200, 20, nil + } + if exactMatch && end.Sub(start) == week && ns == "" { + return 200, 20, nil + } + if exactMatch && end.Sub(start) == month && ns == "" { + return 100, 120, nil + } + return 200, 120, nil + } + performTest(t, newInitialResources(&fakeSource{f: f}, 90, false)) } func TestEstimationBasedOnOtherImages(t *testing.T) { - f := func(_ api.ResourceName, _ int64, image string, exactMatch bool, _, _ time.Time) (int64, int64, error) { - if image == "image" && !exactMatch { + f := func(_ api.ResourceName, _ int64, image, ns string, exactMatch bool, _, _ time.Time) (int64, int64, error) { + if image == "image" && !exactMatch && ns == "" { return 100, 5, nil } return 200, 20, nil } - ir := newInitialResources(&fakeSource{f: f}) - - pods := getPods() - admit(t, ir, pods) - - verifyPod(t, &pods[0], 100, 100) - verifyPod(t, &pods[1], 100, 300) - verifyPod(t, &pods[2], 300, 100) - verifyPod(t, &pods[3], 300, 300) + performTest(t, newInitialResources(&fakeSource{f: f}, 90, false)) } func TestNoData(t *testing.T) { - f := func(_ api.ResourceName, _ int64, _ string, _ bool, _, _ time.Time) (int64, int64, error) { + f := func(_ api.ResourceName, _ int64, _, ns string, _ bool, _, _ time.Time) (int64, int64, error) { return 200, 0, nil } - ir := newInitialResources(&fakeSource{f: f}) + ir := newInitialResources(&fakeSource{f: f}, 90, false) - pods := []api.Pod{ + pods := []*api.Pod{ createPod("p0", "image:v0", parseReq("", "")), } admit(t, ir, pods) @@ -168,25 +205,50 @@ func TestNoData(t *testing.T) { if pods[0].Spec.Containers[0].Resources.Requests != nil { t.Errorf("Unexpected resource estimation") } + + expectNoAnnotation(t, pods[0]) } func TestManyContainers(t *testing.T) { - f := func(_ api.ResourceName, _ int64, _ string, exactMatch bool, _, _ time.Time) (int64, int64, error) { + f := func(_ api.ResourceName, _ int64, _, ns string, exactMatch bool, _, _ time.Time) (int64, int64, error) { if exactMatch { return 100, 120, nil } return 200, 30, nil } - ir := newInitialResources(&fakeSource{f: f}) + ir := newInitialResources(&fakeSource{f: f}, 90, false) pod := createPod("p", "image:v0", parseReq("", "")) - addContainer(&pod, "c1", "image:v1", parseReq("", "300")) - addContainer(&pod, "c2", "image:v2", parseReq("300m", "")) - addContainer(&pod, "c3", "image:v3", parseReq("300m", "300")) - admit(t, ir, []api.Pod{pod}) + addContainer(pod, "c1", "image:v1", parseReq("", "300")) + addContainer(pod, "c2", "image:v2", parseReq("300m", "")) + addContainer(pod, "c3", "image:v3", parseReq("300m", "300")) + admit(t, ir, []*api.Pod{pod}) verifyContainer(t, &pod.Spec.Containers[0], 100, 100) verifyContainer(t, &pod.Spec.Containers[1], 100, 300) verifyContainer(t, &pod.Spec.Containers[2], 300, 100) verifyContainer(t, &pod.Spec.Containers[3], 300, 300) + + verifyAnnotation(t, pod, "Initial Resources plugin set: cpu, memory request for container c0; cpu request for container c1; memory request for container c2") +} + +func TestNamespaceAware(t *testing.T) { + f := func(_ api.ResourceName, _ int64, _, ns string, exactMatch bool, start, end time.Time) (int64, int64, error) { + if ns == "test-ns" { + return 200, 0, nil + } + return 200, 120, nil + } + ir := newInitialResources(&fakeSource{f: f}, 90, true) + + pods := []*api.Pod{ + createPod("p0", "image:v0", parseReq("", "")), + } + admit(t, ir, pods) + + if pods[0].Spec.Containers[0].Resources.Requests != nil { + t.Errorf("Unexpected resource estimation") + } + + expectNoAnnotation(t, pods[0]) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/data_source.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/data_source.go index b6bbbc15ea61..c391c007f7dc 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/data_source.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/data_source.go @@ -19,22 +19,11 @@ package initialresources import ( "flag" "fmt" - "strings" "time" - "github.com/golang/glog" - influxdb "github.com/influxdb/influxdb/client" "k8s.io/kubernetes/pkg/api" ) -const ( - cpuSeriesName = "autoscaling.cpu.usage.1m" - memSeriesName = "autoscaling.memory.usage.1m" - cpuContinuousQuery = "select derivative(value) as value from \"cpu/usage_ns_cumulative\" where pod_id <> '' group by pod_id, container_name, container_base_image, time(1m) into " + cpuSeriesName - memContinuousQuery = "select mean(value) as value from \"memory/usage_bytes_gauge\" where pod_id <> '' group by pod_id, container_name, container_base_image, time(1m) into " + memSeriesName - timeFormat = "2006-01-02 15:04:05" -) - var ( influxdbHost = flag.String("ir-influxdb-host", "localhost:8080/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb:api", "Address of InfluxDB which contains metrics requred by InitialResources") user = flag.String("ir-user", "root", "User used for connecting to InfluxDB") @@ -50,7 +39,7 @@ type dataSource interface { // withing time range (start, end), number of samples considered and error if occured. // If then take only samples that concern the same image (both name and take are the same), // otherwise consider also samples with the same image a possibly different tag. - GetUsagePercentile(kind api.ResourceName, perc int64, image string, exactMatch bool, start, end time.Time) (usage int64, samples int64, err error) + GetUsagePercentile(kind api.ResourceName, perc int64, image, namespace string, exactMatch bool, start, end time.Time) (usage int64, samples int64, err error) } func newDataSource(kind string) (dataSource, error) { @@ -60,133 +49,8 @@ func newDataSource(kind string) (dataSource, error) { if kind == "gcm" { return newGcmSource() } - return nil, fmt.Errorf("Unknown data source %v", kind) -} - -// TODO(piosz): rewrite this once we will migrate into InfluxDB v0.9. -type influxdbSource struct { - conf *influxdb.ClientConfig -} - -func newInfluxdbSource(host, user, password, db string) (dataSource, error) { - conf := &influxdb.ClientConfig{ - Host: host, - Username: user, - Password: password, - Database: db, - } - source := &influxdbSource{ - conf: conf, - } - go source.ensureAutoscalingSeriesExist() - return source, nil -} - -func ensureSeriesExists(conn *influxdb.Client, existingQueries *influxdb.Series, seriesName, contQuery string) error { - queryExists := false - for _, p := range existingQueries.GetPoints() { - id := p[1].(float64) - query := p[2].(string) - if strings.Contains(query, "into "+seriesName) { - if query != contQuery { - if _, err := conn.Query(fmt.Sprintf("drop continuous query %v", id), influxdb.Second); err != nil { - return err - } - } else { - queryExists = true - } - } - } - if !queryExists { - if _, err := conn.Query("drop series "+seriesName, influxdb.Second); err != nil { - return err - } - if _, err := conn.Query(contQuery, influxdb.Second); err != nil { - return err - } - } - return nil -} - -func (s *influxdbSource) ensureAutoscalingSeriesExist() { - for { - time.Sleep(30 * time.Second) - client, err := influxdb.NewClient(s.conf) - if err != nil { - glog.Errorf("Error while trying to create InfluxDB client: %v", err) - continue - } - series, err := client.Query("list continuous queries", influxdb.Second) - if err != nil { - glog.Errorf("Error while trying to list continuous queries: %v", err) - continue - } - if err := ensureSeriesExists(client, series[0], cpuSeriesName, cpuContinuousQuery); err != nil { - glog.Errorf("Error while trying to create create autoscaling series: %v", err) - continue - } - if err := ensureSeriesExists(client, series[0], memSeriesName, memContinuousQuery); err != nil { - glog.Errorf("Error while trying to create create autoscaling series: %v", err) - continue - } - break - } -} - -func (s *influxdbSource) query(query string, precision ...influxdb.TimePrecision) ([]*influxdb.Series, error) { - client, err := influxdb.NewClient(s.conf) - if err != nil { - return nil, err + if kind == "hawkular" { + return newHawkularSource() } - return client.Query(query, precision...) -} - -func (s *influxdbSource) GetUsagePercentile(kind api.ResourceName, perc int64, image string, exactMatch bool, start, end time.Time) (int64, int64, error) { - var series string - if kind == api.ResourceCPU { - series = cpuSeriesName - } else if kind == api.ResourceMemory { - series = memSeriesName - } - - var imgPattern string - if exactMatch { - imgPattern = "='" + image + "'" - } else { - imgPattern = "=~/^" + image + "/" - } - - query := fmt.Sprintf("select percentile(value, %v), count(pod_id) from %v where container_base_image%v and time > '%v' and time < '%v'", perc, series, imgPattern, start.UTC().Format(timeFormat), end.UTC().Format(timeFormat)) - var res []*influxdb.Series - var err error - if res, err = s.query(query, influxdb.Second); err != nil { - return 0, 0, fmt.Errorf("Error while trying to query InfluxDB: %v", err) - } - - // TODO(pszczesniak): fix issue with dropped data base - if len(res) == 0 { - return 0, 0, fmt.Errorf("Missing series %v in InfluxDB", series) - } - points := res[0].GetPoints() - if len(points) == 0 { - return 0, 0, fmt.Errorf("Missing data in series %v in InfluxDB", series) - } - p := points[0] - usage := p[1].(float64) - count := p[2].(float64) - if kind == api.ResourceCPU { - // convert from ns to millicores - usage = usage / 1000000 - } - return int64(usage), int64(count), nil -} - -type gcmSource struct{} - -func newGcmSource() (dataSource, error) { - return &gcmSource{}, fmt.Errorf("gcm source not implemented") -} - -func (s *gcmSource) GetUsagePercentile(kind api.ResourceName, perc int64, image string, exactMatch bool, start, end time.Time) (int64, int64, error) { - return 0, 0, fmt.Errorf("gcm source not implemented") + return nil, fmt.Errorf("Unknown data source %v", kind) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/gcm.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/gcm.go new file mode 100644 index 000000000000..ea60ddbecf36 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/gcm.go @@ -0,0 +1,133 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 initialresources + +import ( + "math" + "sort" + "time" + + "k8s.io/kubernetes/pkg/api" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + gcm "google.golang.org/api/cloudmonitoring/v2beta2" + gce "google.golang.org/cloud/compute/metadata" +) + +const ( + kubePrefix = "custom.cloudmonitoring.googleapis.com/kubernetes.io/" + cpuMetricName = kubePrefix + "cpu/usage_rate" + memMetricName = kubePrefix + "memory/usage" + labelImage = kubePrefix + "label/container_base_image" + labelNs = kubePrefix + "label/pod_namespace" +) + +type gcmSource struct { + project string + gcmService *gcm.Service +} + +func newGcmSource() (dataSource, error) { + // Detect project ID + projectId, err := gce.ProjectID() + if err != nil { + return nil, err + } + + // Create Google Cloud Monitoring service. + client := oauth2.NewClient(oauth2.NoContext, google.ComputeTokenSource("")) + s, err := gcm.New(client) + if err != nil { + return nil, err + } + + return &gcmSource{ + project: projectId, + gcmService: s, + }, nil +} + +func (s *gcmSource) query(metric, oldest, youngest string, labels []string, pageToken string) (*gcm.ListTimeseriesResponse, error) { + req := s.gcmService.Timeseries.List(s.project, metric, youngest, nil). + Oldest(oldest). + Aggregator("mean"). + Window("1m") + for _, l := range labels { + req = req.Labels(l) + } + if pageToken != "" { + req = req.PageToken(pageToken) + } + return req.Do() +} + +func retrieveRawSamples(res *gcm.ListTimeseriesResponse, output *[]int) { + for _, ts := range res.Timeseries { + for _, p := range ts.Points { + *output = append(*output, int(p.DoubleValue)) + } + } +} + +func (s *gcmSource) GetUsagePercentile(kind api.ResourceName, perc int64, image, namespace string, exactMatch bool, start, end time.Time) (int64, int64, error) { + var metric string + if kind == api.ResourceCPU { + metric = cpuMetricName + } else if kind == api.ResourceMemory { + metric = memMetricName + } + + var labels []string + if exactMatch { + labels = append(labels, labelImage+"=="+image) + } else { + labels = append(labels, labelImage+"=~"+image+".*") + } + if namespace != "" { + labels = append(labels, labelNs+"=="+namespace) + } + + oldest := start.Format(time.RFC3339) + youngest := end.Format(time.RFC3339) + + rawSamples := make([]int, 0) + pageToken := "" + for { + res, err := s.query(metric, oldest, youngest, labels, pageToken) + if err != nil { + return 0, 0, err + } + + retrieveRawSamples(res, &rawSamples) + + pageToken = res.NextPageToken + if pageToken == "" { + break + } + } + + count := len(rawSamples) + if count == 0 { + return 0, 0, nil + } + sort.Ints(rawSamples) + usageIndex := int64(math.Ceil(float64(count)*9/10)) - 1 + usage := rawSamples[usageIndex] + + return int64(usage), int64(count), nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/list.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/hawkular.go similarity index 53% rename from Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/list.go rename to Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/hawkular.go index 018d24b9b524..1482b0d75c67 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/list.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/hawkular.go @@ -1,5 +1,5 @@ /* -Copyright 2014 The Kubernetes Authors All rights reserved. +Copyright 2015 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,26 +14,21 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util +package initialresources import ( "fmt" - "strings" -) + "time" -type StringList []string + "k8s.io/kubernetes/pkg/api" +) -func (sl *StringList) String() string { - return fmt.Sprint(*sl) -} +type hawkularSource struct{} -func (sl *StringList) Set(value string) error { - for _, s := range strings.Split(value, ",") { - *sl = append(*sl, s) - } - return nil +func newHawkularSource() (dataSource, error) { + return nil, fmt.Errorf("hawkular source not implemented") } -func (*StringList) Type() string { - return "stringList" +func (s *hawkularSource) GetUsagePercentile(kind api.ResourceName, perc int64, image, namespace string, exactMatch bool, start, end time.Time) (int64, int64, error) { + return 0, 0, fmt.Errorf("gcm source not implemented") } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/influxdb.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/influxdb.go new file mode 100644 index 000000000000..3c6b75640078 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/initialresources/influxdb.go @@ -0,0 +1,158 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 initialresources + +import ( + "fmt" + "strings" + "time" + + "github.com/golang/glog" + influxdb "github.com/influxdb/influxdb/client" + "k8s.io/kubernetes/pkg/api" +) + +const ( + cpuSeriesName = "autoscaling.cpu.usage.2m" + memSeriesName = "autoscaling.memory.usage.2m" + cpuContinuousQuery = "select derivative(value) as value from \"cpu/usage_ns_cumulative\" where pod_id <> '' group by pod_id, pod_namespace, container_name, container_base_image, time(2m) into " + cpuSeriesName + memContinuousQuery = "select mean(value) as value from \"memory/usage_bytes_gauge\" where pod_id <> '' group by pod_id, pod_namespace, container_name, container_base_image, time(2m) into " + memSeriesName + timeFormat = "2006-01-02 15:04:05" +) + +// TODO(piosz): rewrite this once we will migrate into InfluxDB v0.9. +type influxdbSource struct { + conf *influxdb.ClientConfig +} + +func newInfluxdbSource(host, user, password, db string) (dataSource, error) { + conf := &influxdb.ClientConfig{ + Host: host, + Username: user, + Password: password, + Database: db, + } + source := &influxdbSource{ + conf: conf, + } + go source.ensureAutoscalingSeriesExist() + return source, nil +} + +func ensureSeriesExists(conn *influxdb.Client, existingQueries *influxdb.Series, seriesName, contQuery string) error { + queryExists := false + for _, p := range existingQueries.GetPoints() { + id := p[1].(float64) + query := p[2].(string) + if strings.Contains(query, "into "+seriesName) { + if query != contQuery { + if _, err := conn.Query(fmt.Sprintf("drop continuous query %v", id), influxdb.Second); err != nil { + return err + } + } else { + queryExists = true + } + } + } + if !queryExists { + if _, err := conn.Query("drop series "+seriesName, influxdb.Second); err != nil { + return err + } + if _, err := conn.Query(contQuery, influxdb.Second); err != nil { + return err + } + } + return nil +} + +func (s *influxdbSource) ensureAutoscalingSeriesExist() { + for { + time.Sleep(30 * time.Second) + client, err := influxdb.NewClient(s.conf) + if err != nil { + glog.Errorf("Error while trying to create InfluxDB client: %v", err) + continue + } + series, err := client.Query("list continuous queries", influxdb.Second) + if err != nil { + glog.Errorf("Error while trying to list continuous queries: %v", err) + continue + } + if err := ensureSeriesExists(client, series[0], cpuSeriesName, cpuContinuousQuery); err != nil { + glog.Errorf("Error while trying to create create autoscaling series: %v", err) + continue + } + if err := ensureSeriesExists(client, series[0], memSeriesName, memContinuousQuery); err != nil { + glog.Errorf("Error while trying to create create autoscaling series: %v", err) + continue + } + break + } +} + +func (s *influxdbSource) query(query string, precision ...influxdb.TimePrecision) ([]*influxdb.Series, error) { + client, err := influxdb.NewClient(s.conf) + if err != nil { + return nil, err + } + return client.Query(query, precision...) +} + +func (s *influxdbSource) GetUsagePercentile(kind api.ResourceName, perc int64, image, namespace string, exactMatch bool, start, end time.Time) (int64, int64, error) { + var series string + if kind == api.ResourceCPU { + series = cpuSeriesName + } else if kind == api.ResourceMemory { + series = memSeriesName + } + + var imgPattern string + if exactMatch { + imgPattern = "='" + image + "'" + } else { + // Escape character "/" in image pattern. + imgPattern = "=~/^" + strings.Replace(image, "/", "\\/", -1) + "/" + } + var namespaceCond string + if namespace != "" { + namespaceCond = " and pod_namespace='" + namespace + "'" + } + + query := fmt.Sprintf("select percentile(value, %v), count(pod_id) from %v where container_base_image%v%v and time > '%v' and time < '%v'", perc, series, imgPattern, namespaceCond, start.UTC().Format(timeFormat), end.UTC().Format(timeFormat)) + var res []*influxdb.Series + var err error + if res, err = s.query(query, influxdb.Second); err != nil { + return 0, 0, fmt.Errorf("Error while trying to query InfluxDB: %v", err) + } + + // TODO(pszczesniak): fix issue with dropped data base + if len(res) == 0 { + return 0, 0, fmt.Errorf("Missing data in series %v in InfluxDB", series) + } + points := res[0].GetPoints() + if len(points) == 0 { + return 0, 0, fmt.Errorf("Missing data in series %v in InfluxDB", series) + } + p := points[0] + usage := p[1].(float64) + count := p[2].(float64) + if kind == api.ResourceCPU { + // convert from ns to millicores + usage = usage / 1000000 + } + return int64(usage), int64(count), nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission.go index 012d08da8ada..e4069ff7ccdf 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission.go @@ -19,6 +19,8 @@ package limitranger import ( "fmt" "io" + "sort" + "strings" "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" @@ -33,6 +35,10 @@ import ( "k8s.io/kubernetes/pkg/watch" ) +const ( + limitRangerAnnotation = "kubernetes.io/limit-ranger" +) + func init() { admission.RegisterPlugin("LimitRanger", func(client client.Interface, config io.Reader) (admission.Interface, error) { return NewLimitRanger(client, Limit), nil @@ -94,7 +100,7 @@ func (l *limitRanger) Admit(a admission.Attributes) (err error) { func NewLimitRanger(client client.Interface, limitFunc LimitFunc) admission.Interface { lw := &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { - return client.LimitRanges(api.NamespaceAll).List(labels.Everything()) + return client.LimitRanges(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return client.LimitRanges(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion) @@ -162,9 +168,14 @@ func defaultContainerResourceRequirements(limitRange *api.LimitRange) api.Resour } // mergePodResourceRequirements merges enumerated requirements with default requirements +// it annotates the pod with information about what requirements were modified func mergePodResourceRequirements(pod *api.Pod, defaultRequirements *api.ResourceRequirements) { + annotations := []string{} + for i := range pod.Spec.Containers { container := &pod.Spec.Containers[i] + setRequests := []string{} + setLimits := []string{} if container.Resources.Limits == nil { container.Resources.Limits = api.ResourceList{} } @@ -175,14 +186,34 @@ func mergePodResourceRequirements(pod *api.Pod, defaultRequirements *api.Resourc _, found := container.Resources.Limits[k] if !found { container.Resources.Limits[k] = *v.Copy() + setLimits = append(setLimits, string(k)) } } for k, v := range defaultRequirements.Requests { _, found := container.Resources.Requests[k] if !found { container.Resources.Requests[k] = *v.Copy() + setRequests = append(setRequests, string(k)) } } + if len(setRequests) > 0 { + sort.Strings(setRequests) + a := strings.Join(setRequests, ", ") + " request for container " + container.Name + annotations = append(annotations, a) + } + if len(setLimits) > 0 { + sort.Strings(setLimits) + a := strings.Join(setLimits, ", ") + " limit for container " + container.Name + annotations = append(annotations, a) + } + } + + if len(annotations) > 0 { + if pod.ObjectMeta.Annotations == nil { + pod.ObjectMeta.Annotations = make(map[string]string) + } + val := "LimitRanger plugin set: " + strings.Join(annotations, "; ") + pod.ObjectMeta.Annotations[limitRangerAnnotation] = val } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission_test.go index 42aefb1818f9..3b6de315c546 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission_test.go @@ -125,6 +125,7 @@ func validPod(name string, numContainers int, resources api.ResourceRequirements pod.Spec.Containers = append(pod.Spec.Containers, api.Container{ Image: "foo:V" + strconv.Itoa(i), Resources: resources, + Name: "foo-" + strconv.Itoa(i), }) } return pod @@ -145,6 +146,22 @@ func TestDefaultContainerResourceRequirements(t *testing.T) { } } +func verifyAnnotation(t *testing.T, pod *api.Pod, expected string) { + a, ok := pod.ObjectMeta.Annotations[limitRangerAnnotation] + if !ok { + t.Errorf("No annotation but expected %v", expected) + } + if a != expected { + t.Errorf("Wrong annotation set by Limit Ranger: got %v, expected %v", a, expected) + } +} + +func expectNoAnnotation(t *testing.T, pod *api.Pod) { + if a, ok := pod.ObjectMeta.Annotations[limitRangerAnnotation]; ok { + t.Errorf("Expected no annotation but got %v", a) + } +} + func TestMergePodResourceRequirements(t *testing.T) { limitRange := validLimitRange() @@ -159,6 +176,7 @@ func TestMergePodResourceRequirements(t *testing.T) { t.Errorf("pod %v, expected != actual; %v != %v", pod.Name, expected, actual) } } + verifyAnnotation(t, &pod, "LimitRanger plugin set: cpu, memory request for container foo-0; cpu, memory limit for container foo-0") // pod with some resources enumerated should only merge empty input := getResourceRequirements(getResourceList("", "512Mi"), getResourceList("", "")) @@ -177,6 +195,20 @@ func TestMergePodResourceRequirements(t *testing.T) { t.Errorf("pod %v, expected != actual; %v != %v", pod.Name, expected, actual) } } + verifyAnnotation(t, &pod, "LimitRanger plugin set: cpu request for container foo-0; cpu, memory limit for container foo-0") + + // pod with all resources enumerated should not merge anything + input = getResourceRequirements(getResourceList("100m", "512Mi"), getResourceList("200m", "1G")) + pod = validPod("limit-memory", 1, input) + expected = input + mergePodResourceRequirements(&pod, &defaultRequirements) + for i := range pod.Spec.Containers { + actual := pod.Spec.Containers[i].Resources + if !api.Semantic.DeepEqual(expected, actual) { + t.Errorf("pod %v, expected != actual; %v != %v", pod.Name, expected, actual) + } + } + expectNoAnnotation(t, &pod) } func TestPodLimitFunc(t *testing.T) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/exists/admission.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/exists/admission.go index a405d4dacedb..ed5d33ceaac0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/exists/admission.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/exists/admission.go @@ -17,12 +17,12 @@ limitations under the License. package exists import ( - "fmt" "io" "time" "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" @@ -50,11 +50,11 @@ type exists struct { func (e *exists) Admit(a admission.Attributes) (err error) { defaultVersion, kind, err := api.RESTMapper.VersionAndKindForResource(a.GetResource()) if err != nil { - return admission.NewForbidden(a, err) + return errors.NewInternalError(err) } mapping, err := api.RESTMapper.RESTMapping(kind, defaultVersion) if err != nil { - return admission.NewForbidden(a, err) + return errors.NewInternalError(err) } if mapping.Scope.Name() != meta.RESTScopeNameNamespace { return nil @@ -68,7 +68,7 @@ func (e *exists) Admit(a admission.Attributes) (err error) { } _, exists, err := e.store.Get(namespace) if err != nil { - return admission.NewForbidden(a, err) + return errors.NewInternalError(err) } if exists { return nil @@ -77,7 +77,10 @@ func (e *exists) Admit(a admission.Attributes) (err error) { // in case of latency in our caches, make a call direct to storage to verify that it truly exists or not _, err = e.client.Namespaces().Get(a.GetNamespace()) if err != nil { - return admission.NewForbidden(a, fmt.Errorf("Namespace %s does not exist", a.GetNamespace())) + if errors.IsNotFound(err) { + return err + } + return errors.NewInternalError(err) } return nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/lifecycle/admission.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/lifecycle/admission.go index 80210f0cbf66..3fdc9fa91f68 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/lifecycle/admission.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/lifecycle/admission.go @@ -58,11 +58,11 @@ func (l *lifecycle) Admit(a admission.Attributes) (err error) { defaultVersion, kind, err := api.RESTMapper.VersionAndKindForResource(a.GetResource()) if err != nil { - return admission.NewForbidden(a, err) + return errors.NewInternalError(err) } mapping, err := api.RESTMapper.RESTMapping(kind, defaultVersion) if err != nil { - return admission.NewForbidden(a, err) + return errors.NewInternalError(err) } if mapping.Scope.Name() != meta.RESTScopeNameNamespace { return nil @@ -74,7 +74,7 @@ func (l *lifecycle) Admit(a admission.Attributes) (err error) { }, }) if err != nil { - return admission.NewForbidden(a, err) + return errors.NewInternalError(err) } // refuse to operate on non-existent namespaces @@ -82,7 +82,10 @@ func (l *lifecycle) Admit(a admission.Attributes) (err error) { // in case of latency in our caches, make a call direct to storage to verify that it truly exists or not namespaceObj, err = l.client.Namespaces().Get(a.GetNamespace()) if err != nil { - return admission.NewForbidden(a, fmt.Errorf("Namespace %s does not exist", a.GetNamespace())) + if errors.IsNotFound(err) { + return err + } + return errors.NewInternalError(err) } } @@ -93,6 +96,7 @@ func (l *lifecycle) Admit(a admission.Attributes) (err error) { return nil } + // TODO: This should probably not be a 403 return admission.NewForbidden(a, fmt.Errorf("Unable to create new content in namespace %s because it is being terminated.", a.GetNamespace())) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/lifecycle/admission_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/lifecycle/admission_test.go index dec42f15297a..984d9ab4a74a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/lifecycle/admission_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/namespace/lifecycle/admission_test.go @@ -26,7 +26,6 @@ import ( "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/watch" ) // TestAdmission @@ -44,10 +43,8 @@ func TestAdmission(t *testing.T) { store := cache.NewStore(cache.MetaNamespaceKeyFunc) store.Add(namespaceObj) - fakeWatch := watch.NewFake() - mockClient := &testclient.Fake{} - mockClient.AddWatchReactor("*", testclient.DefaultWatchReactor(fakeWatch, nil)) - mockClient.AddReactor("get", "namespaces", func(action testclient.Action) (bool, runtime.Object, error) { + mockClient := testclient.NewSimpleFake() + mockClient.PrependReactor("get", "namespaces", func(action testclient.Action) (bool, runtime.Object, error) { namespaceLock.RLock() defer namespaceLock.RUnlock() if getAction, ok := action.(testclient.GetAction); ok && getAction.GetName() == namespaceObj.Name { @@ -55,7 +52,7 @@ func TestAdmission(t *testing.T) { } return true, nil, fmt.Errorf("No result for action %v", action) }) - mockClient.AddReactor("list", "namespaces", func(action testclient.Action) (bool, runtime.Object, error) { + mockClient.PrependReactor("list", "namespaces", func(action testclient.Action) (bool, runtime.Object, error) { namespaceLock.RLock() defer namespaceLock.RUnlock() return true, &api.NamespaceList{Items: []api.Namespace{*namespaceObj}}, nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/admission.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/admission.go index 98a88ac9dfd6..099642d532e1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/admission.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/admission.go @@ -27,10 +27,11 @@ import ( "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" - "k8s.io/kubernetes/pkg/controller/resourcequota" + resourcequotacontroller "k8s.io/kubernetes/pkg/controller/resourcequota" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/watch" ) @@ -50,7 +51,7 @@ type quota struct { func NewResourceQuota(client client.Interface) admission.Interface { lw := &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { - return client.ResourceQuotas(api.NamespaceAll).List(labels.Everything()) + return client.ResourceQuotas(api.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return client.ResourceQuotas(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion) @@ -102,7 +103,7 @@ func (q *quota) Admit(a admission.Attributes) (err error) { items, err := q.indexer.Index("namespace", key) if err != nil { - return admission.NewForbidden(a, fmt.Errorf("Unable to %s %s at this time because there was an error enforcing quota", a.GetOperation(), a.GetResource())) + return admission.NewForbidden(a, fmt.Errorf("unable to %s %s at this time because there was an error enforcing quota", a.GetOperation(), a.GetResource())) } if len(items) == 0 { return nil @@ -149,7 +150,7 @@ func (q *quota) Admit(a admission.Attributes) (err error) { // we have concurrent requests to update quota, so look to retry if needed if retry == numRetries { - return admission.NewForbidden(a, fmt.Errorf("Unable to %s %s at this time because there are too many concurrent requests to increment quota", a.GetOperation(), a.GetResource())) + return admission.NewForbidden(a, fmt.Errorf("unable to %s %s at this time because there are too many concurrent requests to increment quota", a.GetOperation(), a.GetResource())) } time.Sleep(interval) // manually get the latest quota @@ -167,7 +168,8 @@ func (q *quota) Admit(a admission.Attributes) (err error) { // Return true if the usage must be recorded prior to admitting the new resource // Return an error if the operation should not pass admission control func IncrementUsage(a admission.Attributes, status *api.ResourceQuotaStatus, client client.Interface) (bool, error) { - dirty := false + var errs []error + dirty := true set := map[api.ResourceName]bool{} for k := range status.Hard { set[k] = true @@ -180,13 +182,13 @@ func IncrementUsage(a admission.Attributes, status *api.ResourceQuotaStatus, cli if hardFound { used, usedFound := status.Used[resourceName] if !usedFound { - return false, fmt.Errorf("Quota usage stats are not yet known, unable to admit resource until an accurate count is completed.") + return false, fmt.Errorf("quota usage stats are not yet known, unable to admit resource until an accurate count is completed.") } if used.Value() >= hard.Value() { - return false, fmt.Errorf("Limited to %s %s", hard.String(), resourceName) + errs = append(errs, fmt.Errorf("limited to %s %s", hard.String(), resourceName)) + dirty = false } else { status.Used[resourceName] = *resource.NewQuantity(used.Value()+int64(1), resource.DecimalSI) - dirty = true } } } @@ -194,7 +196,7 @@ func IncrementUsage(a admission.Attributes, status *api.ResourceQuotaStatus, cli if a.GetResource() == "pods" { for _, resourceName := range []api.ResourceName{api.ResourceMemory, api.ResourceCPU} { - // ignore tracking the resource if its not in the quota document + // ignore tracking the resource if it's not in the quota document if !set[resourceName] { continue } @@ -207,7 +209,7 @@ func IncrementUsage(a admission.Attributes, status *api.ResourceQuotaStatus, cli // if we do not yet know how much of the current resource is used, we cannot accept any request used, usedFound := status.Used[resourceName] if !usedFound { - return false, fmt.Errorf("Unable to admit pod until quota usage stats are calculated.") + return false, fmt.Errorf("unable to admit pod until quota usage stats are calculated.") } // the amount of resource being requested, or an error if it does not make a request that is tracked @@ -215,7 +217,7 @@ func IncrementUsage(a admission.Attributes, status *api.ResourceQuotaStatus, cli delta, err := resourcequotacontroller.PodRequests(pod, resourceName) if err != nil { - return false, fmt.Errorf("Must make a non-zero request for %s since it is tracked by quota.", resourceName) + return false, fmt.Errorf("must make a non-zero request for %s since it is tracked by quota.", resourceName) } // if this operation is an update, we need to find the delta usage from the previous state @@ -250,12 +252,14 @@ func IncrementUsage(a admission.Attributes, status *api.ResourceQuotaStatus, cli } if newUsageValue > hardUsageValue { - return false, fmt.Errorf("Unable to admit pod without exceeding quota for resource %s. Limited to %s but require %s to succeed.", resourceName, hard.String(), newUsage.String()) + errs = append(errs, fmt.Errorf("unable to admit pod without exceeding quota for resource %s: limited to %s but require %s to succeed.", resourceName, hard.String(), newUsage.String())) + dirty = false } else { status.Used[resourceName] = *newUsage - dirty = true } + } } - return dirty, nil + + return dirty, errors.NewAggregate(errs) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/admission_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/admission_test.go index 9628159bb47f..137bf1fe88a1 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/admission_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/admission_test.go @@ -25,7 +25,7 @@ import ( "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/client/unversioned/testclient" - "k8s.io/kubernetes/pkg/controller/resourcequota" + resourcequotacontroller "k8s.io/kubernetes/pkg/controller/resourcequota" ) func getResourceList(cpu, memory string) api.ResourceList { @@ -127,6 +127,14 @@ func TestIncrementUsagePodResources(t *testing.T) { hard: resource.MustParse("500Mi"), expectedError: true, }, + { + testName: "memory-not-allowed-with-different-format", + existing: validPod("a", 1, getResourceRequirements(getResourceList("", "100M"), getResourceList("", ""))), + input: validPod("b", 1, getResourceRequirements(getResourceList("", "450Mi"), getResourceList("", ""))), + resourceName: api.ResourceMemory, + hard: resource.MustParse("500Mi"), + expectedError: true, + }, { testName: "memory-no-request", existing: validPod("a", 1, getResourceRequirements(getResourceList("", "100Mi"), getResourceList("", ""))), diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go index 8dbd8ca43f5b..26ee52e69ed5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go @@ -20,7 +20,6 @@ import ( "fmt" "io" "math/rand" - "strconv" "time" "k8s.io/kubernetes/pkg/admission" @@ -28,8 +27,9 @@ import ( "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/controller/serviceaccount" "k8s.io/kubernetes/pkg/fields" - "k8s.io/kubernetes/pkg/kubelet" + kubelet "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/sets" @@ -39,19 +39,12 @@ import ( // DefaultServiceAccountName is the name of the default service account to set on pods which do not specify a service account const DefaultServiceAccountName = "default" -// EnforceMountableSecretsAnnotation is a default annotation that indicates that a service account should enforce mountable secrets. -// The value must be true to have this annotation take effect -const EnforceMountableSecretsAnnotation = "kubernetes.io/enforce-mountable-secrets" - // DefaultAPITokenMountPath is the path that ServiceAccountToken secrets are automounted to. // The token file would then be accessible at /var/run/secrets/kubernetes.io/serviceaccount const DefaultAPITokenMountPath = "/var/run/secrets/kubernetes.io/serviceaccount" -// PluginName is the name of this admission plugin -const PluginName = "ServiceAccount" - func init() { - admission.RegisterPlugin(PluginName, func(client client.Interface, config io.Reader) (admission.Interface, error) { + admission.RegisterPlugin("ServiceAccount", func(client client.Interface, config io.Reader) (admission.Interface, error) { serviceAccountAdmission := NewServiceAccount(client) serviceAccountAdmission.Run() return serviceAccountAdmission, nil @@ -188,7 +181,7 @@ func (s *serviceAccount) Admit(a admission.Attributes) (err error) { return admission.NewForbidden(a, fmt.Errorf("service account %s/%s was not found, retry after the service account is created", a.GetNamespace(), pod.Spec.ServiceAccountName)) } - if s.enforceMountableSecrets(serviceAccount) { + if s.LimitSecretReferences { if err := s.limitSecretReferences(serviceAccount, pod); err != nil { return admission.NewForbidden(a, err) } @@ -208,21 +201,6 @@ func (s *serviceAccount) Admit(a admission.Attributes) (err error) { return nil } -// enforceMountableSecrets indicates whether mountable secrets should be enforced for a particular service account -// A global setting of true will override any flag set on the individual service account -func (s *serviceAccount) enforceMountableSecrets(serviceAccount *api.ServiceAccount) bool { - if s.LimitSecretReferences { - return true - } - - if value, ok := serviceAccount.Annotations[EnforceMountableSecretsAnnotation]; ok { - enforceMountableSecretCheck, _ := strconv.ParseBool(value) - return enforceMountableSecretCheck - } - - return false -} - // getServiceAccount returns the ServiceAccount for the given namespace and name if it exists func (s *serviceAccount) getServiceAccount(namespace string, name string) (*api.ServiceAccount, error) { key := &api.ServiceAccount{ObjectMeta: api.ObjectMeta{Namespace: namespace}} @@ -296,20 +274,10 @@ func (s *serviceAccount) getServiceAccountTokens(serviceAccount *api.ServiceAcco tokens := []*api.Secret{} for _, obj := range index { token := obj.(*api.Secret) - if token.Type != api.SecretTypeServiceAccountToken { - continue - } - name := token.Annotations[api.ServiceAccountNameKey] - uid := token.Annotations[api.ServiceAccountUIDKey] - if name != serviceAccount.Name { - // Name must match - continue - } - if len(uid) > 0 && uid != string(serviceAccount.UID) { - // If UID is set, it must match - continue + + if serviceaccount.IsServiceAccountToken(token, serviceAccount) { + tokens = append(tokens, token) } - tokens = append(tokens, token) } return tokens, nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission_test.go index bcabe8bebf58..65549007e230 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission_test.go @@ -23,7 +23,7 @@ import ( "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/client/unversioned/testclient" - "k8s.io/kubernetes/pkg/kubelet" + kubelet "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/types" ) @@ -428,36 +428,6 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) { } } -func TestAllowUnreferencedSecretVolumesForPermissiveSAs(t *testing.T) { - ns := "myns" - - admit := NewServiceAccount(nil) - admit.LimitSecretReferences = false - admit.RequireAPIToken = false - - // Add the default service account for the ns into the cache - admit.serviceAccounts.Add(&api.ServiceAccount{ - ObjectMeta: api.ObjectMeta{ - Name: DefaultServiceAccountName, - Namespace: ns, - Annotations: map[string]string{EnforceMountableSecretsAnnotation: "true"}, - }, - }) - - pod := &api.Pod{ - Spec: api.PodSpec{ - Volumes: []api.Volume{ - {VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "foo"}}}, - }, - }, - } - attrs := admission.NewAttributesRecord(pod, "Pod", ns, "myname", string(api.ResourcePods), "", admission.Create, nil) - err := admit.Admit(attrs) - if err == nil { - t.Errorf("Expected rejection for using a secret the service account does not reference") - } -} - func TestAllowsReferencedImagePullSecrets(t *testing.T) { ns := "myns" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc/oidc.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc/oidc.go index 6f9f7e226ddb..3975f1737e89 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc/oidc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc/oidc.go @@ -21,7 +21,6 @@ import ( "crypto/tls" "crypto/x509" "fmt" - "net" "net/http" "net/url" "time" @@ -72,17 +71,11 @@ func New(issuerURL, clientID, caFile, usernameClaim string) (*OIDCAuthenticator, } // Copied from http.DefaultTransport. - tr := &http.Transport{ + tr := util.SetTransportDefaults(&http.Transport{ // According to golang's doc, if RootCAs is nil, // TLS uses the host's root CA set. TLSClientConfig: &tls.Config{RootCAs: roots}, - Proxy: http.ProxyFromEnvironment, - Dial: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - TLSHandshakeTimeout: 10 * time.Second, - } + }) hc := &http.Client{} hc.Transport = tr diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc/oidc_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc/oidc_test.go index ac9fe2607ec2..4c974ffdc06f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc/oidc_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc/oidc_test.go @@ -16,7 +16,6 @@ limitations under the License. package oidc -/* import ( "bytes" "crypto/rand" @@ -394,4 +393,3 @@ func TestOIDCAuthentication(t *testing.T) { } } } -*/ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/listers.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/listers.go index 5b7c173a4975..4bf01b7671bd 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/listers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/listers.go @@ -23,16 +23,16 @@ import ( "k8s.io/kubernetes/pkg/labels" ) -// MinionLister interface represents anything that can list minions for a scheduler. -type MinionLister interface { +// NodeLister interface represents anything that can list nodes for a scheduler. +type NodeLister interface { List() (list api.NodeList, err error) } -// FakeMinionLister implements MinionLister on a []string for test purposes. -type FakeMinionLister api.NodeList +// FakeNodeLister implements NodeLister on a []string for test purposes. +type FakeNodeLister api.NodeList -// List returns minions as a []string. -func (f FakeMinionLister) List() (api.NodeList, error) { +// List returns nodes as a []string. +func (f FakeNodeLister) List() (api.NodeList, error) { return api.NodeList(f), nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates.go index 83d8d2b83997..b1fff016da5a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates.go @@ -159,21 +159,21 @@ func (r *ResourceFit) PodFitsResources(pod *api.Pod, existingPods []*api.Pod, no pods = append(existingPods, pod) _, exceedingCPU, exceedingMemory := CheckPodsExceedingFreeResources(pods, info.Status.Capacity) if int64(len(pods)) > info.Status.Capacity.Pods().Value() { - glog.V(4).Infof("Cannot schedule Pod %v, because Node %v is full, running %v out of %v Pods.", pod, node, len(pods)-1, info.Status.Capacity.Pods().Value()) + glog.V(4).Infof("Cannot schedule Pod %+v, because Node %+v is full, running %v out of %v Pods.", pod, node, len(pods)-1, info.Status.Capacity.Pods().Value()) FailedResourceType = "PodExceedsMaxPodNumber" return false, nil } if len(exceedingCPU) > 0 { - glog.V(4).Infof("Cannot schedule Pod %v, because Node does not have sufficient CPU", pod) + glog.V(4).Infof("Cannot schedule Pod %+v, because Node does not have sufficient CPU", pod) FailedResourceType = "PodExceedsFreeCPU" return false, nil } if len(exceedingMemory) > 0 { - glog.V(4).Infof("Cannot schedule Pod %v, because Node does not have sufficient Memory", pod) + glog.V(4).Infof("Cannot schedule Pod %+v, because Node does not have sufficient Memory", pod) FailedResourceType = "PodExceedsFreeMemory" return false, nil } - glog.V(4).Infof("Schedule Pod %v on Node %v is allowed, Node is running only %v out of %v Pods.", pod, node, len(pods)-1, info.Status.Capacity.Pods().Value()) + glog.V(4).Infof("Schedule Pod %+v on Node %+v is allowed, Node is running only %v out of %v Pods.", pod, node, len(pods)-1, info.Status.Capacity.Pods().Value()) return true, nil } @@ -203,12 +203,12 @@ type NodeSelector struct { info NodeInfo } -func (n *NodeSelector) PodSelectorMatches(pod *api.Pod, existingPods []*api.Pod, node string) (bool, error) { - minion, err := n.info.GetNodeInfo(node) +func (n *NodeSelector) PodSelectorMatches(pod *api.Pod, existingPods []*api.Pod, nodeID string) (bool, error) { + node, err := n.info.GetNodeInfo(nodeID) if err != nil { return false, err } - return PodMatchesNodeLabels(pod, minion), nil + return PodMatchesNodeLabels(pod, node), nil } func PodFitsHost(pod *api.Pod, existingPods []*api.Pod, node string) (bool, error) { @@ -233,27 +233,27 @@ func NewNodeLabelPredicate(info NodeInfo, labels []string, presence bool) algori return labelChecker.CheckNodeLabelPresence } -// CheckNodeLabelPresence checks whether all of the specified labels exists on a minion or not, regardless of their value -// If "presence" is false, then returns false if any of the requested labels matches any of the minion's labels, +// CheckNodeLabelPresence checks whether all of the specified labels exists on a node or not, regardless of their value +// If "presence" is false, then returns false if any of the requested labels matches any of the node's labels, // otherwise returns true. -// If "presence" is true, then returns false if any of the requested labels does not match any of the minion's labels, +// If "presence" is true, then returns false if any of the requested labels does not match any of the node's labels, // otherwise returns true. // -// Consider the cases where the minions are placed in regions/zones/racks and these are identified by labels -// In some cases, it is required that only minions that are part of ANY of the defined regions/zones/racks be selected +// Consider the cases where the nodes are placed in regions/zones/racks and these are identified by labels +// In some cases, it is required that only nodes that are part of ANY of the defined regions/zones/racks be selected // -// Alternately, eliminating minions that have a certain label, regardless of value, is also useful -// A minion may have a label with "retiring" as key and the date as the value -// and it may be desirable to avoid scheduling new pods on this minion -func (n *NodeLabelChecker) CheckNodeLabelPresence(pod *api.Pod, existingPods []*api.Pod, node string) (bool, error) { +// Alternately, eliminating nodes that have a certain label, regardless of value, is also useful +// A node may have a label with "retiring" as key and the date as the value +// and it may be desirable to avoid scheduling new pods on this node +func (n *NodeLabelChecker) CheckNodeLabelPresence(pod *api.Pod, existingPods []*api.Pod, nodeID string) (bool, error) { var exists bool - minion, err := n.info.GetNodeInfo(node) + node, err := n.info.GetNodeInfo(nodeID) if err != nil { return false, err } - minionLabels := labels.Set(minion.Labels) + nodeLabels := labels.Set(node.Labels) for _, label := range n.labels { - exists = minionLabels.Has(label) + exists = nodeLabels.Has(label) if (exists && !n.presence) || (!exists && n.presence) { return false, nil } @@ -278,16 +278,16 @@ func NewServiceAffinityPredicate(podLister algorithm.PodLister, serviceLister al return affinity.CheckServiceAffinity } -// CheckServiceAffinity ensures that only the minions that match the specified labels are considered for scheduling. +// CheckServiceAffinity ensures that only the nodes that match the specified labels are considered for scheduling. // The set of labels to be considered are provided to the struct (ServiceAffinity). -// The pod is checked for the labels and any missing labels are then checked in the minion +// The pod is checked for the labels and any missing labels are then checked in the node // that hosts the service pods (peers) for the given pod. // // We add an implicit selector requiring some particular value V for label L to a pod, if: // - L is listed in the ServiceAffinity object that is passed into the function // - the pod does not have any NodeSelector for L -// - some other pod from the same service is already scheduled onto a minion that has value V for label L -func (s *ServiceAffinity) CheckServiceAffinity(pod *api.Pod, existingPods []*api.Pod, node string) (bool, error) { +// - some other pod from the same service is already scheduled onto a node that has value V for label L +func (s *ServiceAffinity) CheckServiceAffinity(pod *api.Pod, existingPods []*api.Pod, nodeID string) (bool, error) { var affinitySelector labels.Selector // check if the pod being scheduled has the affinity labels specified in its NodeSelector @@ -322,8 +322,8 @@ func (s *ServiceAffinity) CheckServiceAffinity(pod *api.Pod, existingPods []*api } } if len(nsServicePods) > 0 { - // consider any service pod and fetch the minion its hosted on - otherMinion, err := s.nodeInfo.GetNodeInfo(nsServicePods[0].Spec.NodeName) + // consider any service pod and fetch the node its hosted on + otherNode, err := s.nodeInfo.GetNodeInfo(nsServicePods[0].Spec.NodeName) if err != nil { return false, err } @@ -332,31 +332,31 @@ func (s *ServiceAffinity) CheckServiceAffinity(pod *api.Pod, existingPods []*api if _, exists := affinityLabels[l]; exists { continue } - if labels.Set(otherMinion.Labels).Has(l) { - affinityLabels[l] = labels.Set(otherMinion.Labels).Get(l) + if labels.Set(otherNode.Labels).Has(l) { + affinityLabels[l] = labels.Set(otherNode.Labels).Get(l) } } } } } - // if there are no existing pods in the service, consider all minions + // if there are no existing pods in the service, consider all nodes if len(affinityLabels) == 0 { affinitySelector = labels.Everything() } else { affinitySelector = labels.Set(affinityLabels).AsSelector() } - minion, err := s.nodeInfo.GetNodeInfo(node) + node, err := s.nodeInfo.GetNodeInfo(nodeID) if err != nil { return false, err } - // check if the minion matches the selector - return affinitySelector.Matches(labels.Set(minion.Labels)), nil + // check if the node matches the selector + return affinitySelector.Matches(labels.Set(node.Labels)), nil } -func PodFitsPorts(pod *api.Pod, existingPods []*api.Pod, node string) (bool, error) { +func PodFitsHostPorts(pod *api.Pod, existingPods []*api.Pod, node string) (bool, error) { existingPorts := getUsedPorts(existingPods...) wantPorts := getUsedPorts(pod) for wport := range wantPorts { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates_test.go index 288da26f785a..0942a40b99ac 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates_test.go @@ -244,7 +244,7 @@ func newPod(host string, hostPorts ...int) *api.Pod { } } -func TestPodFitsPorts(t *testing.T) { +func TestPodFitsHostPorts(t *testing.T) { tests := []struct { pod *api.Pod existingPods []*api.Pod @@ -291,7 +291,7 @@ func TestPodFitsPorts(t *testing.T) { }, } for _, test := range tests { - fits, err := PodFitsPorts(test.pod, test.existingPods, "machine") + fits, err := PodFitsHostPorts(test.pod, test.existingPods, "machine") if err != nil { t.Errorf("unexpected error: %v", err) } @@ -637,7 +637,7 @@ func TestServiceAffinity(t *testing.T) { services: []api.Service{{Spec: api.ServiceSpec{Selector: selector}}}, fits: true, labels: []string{"region"}, - test: "service pod on same minion", + test: "service pod on same node", }, { pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: selector}}, @@ -646,7 +646,7 @@ func TestServiceAffinity(t *testing.T) { services: []api.Service{{Spec: api.ServiceSpec{Selector: selector}}}, fits: true, labels: []string{"region"}, - test: "service pod on different minion, region match", + test: "service pod on different node, region match", }, { pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: selector}}, @@ -655,7 +655,7 @@ func TestServiceAffinity(t *testing.T) { services: []api.Service{{Spec: api.ServiceSpec{Selector: selector}}}, fits: false, labels: []string{"region"}, - test: "service pod on different minion, region mismatch", + test: "service pod on different node, region mismatch", }, { pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: selector, Namespace: "ns1"}}, @@ -691,7 +691,7 @@ func TestServiceAffinity(t *testing.T) { services: []api.Service{{Spec: api.ServiceSpec{Selector: selector}}}, fits: false, labels: []string{"region", "zone"}, - test: "service pod on different minion, multiple labels, not all match", + test: "service pod on different node, multiple labels, not all match", }, { pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: selector}}, @@ -700,7 +700,7 @@ func TestServiceAffinity(t *testing.T) { services: []api.Service{{Spec: api.ServiceSpec{Selector: selector}}}, fits: true, labels: []string{"region", "zone"}, - test: "service pod on different minion, multiple labels, all match", + test: "service pod on different node, multiple labels, all match", }, } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/priorities.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/priorities.go index 15ad12b55e0d..f020ec732419 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/priorities.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/priorities.go @@ -87,7 +87,7 @@ func calculateResourceOccupancy(pod *api.Pod, node api.Node, pods []*api.Pod) al } } // Add the resources requested by the current pod being scheduled. - // This also helps differentiate between differently sized, but empty, minions. + // This also helps differentiate between differently sized, but empty, nodes. for _, container := range pod.Spec.Containers { cpu, memory := getNonzeroRequests(&container.Resources.Requests) totalMilliCPU += cpu @@ -114,8 +114,8 @@ func calculateResourceOccupancy(pod *api.Pod, node api.Node, pods []*api.Pod) al // It calculates the percentage of memory and CPU requested by pods scheduled on the node, and prioritizes // based on the minimum of the average of the fraction of requested to capacity. // Details: cpu((capacity - sum(requested)) * 10 / capacity) + memory((capacity - sum(requested)) * 10 / capacity) / 2 -func LeastRequestedPriority(pod *api.Pod, podLister algorithm.PodLister, minionLister algorithm.MinionLister) (algorithm.HostPriorityList, error) { - nodes, err := minionLister.List() +func LeastRequestedPriority(pod *api.Pod, podLister algorithm.PodLister, nodeLister algorithm.NodeLister) (algorithm.HostPriorityList, error) { + nodes, err := nodeLister.List() if err != nil { return algorithm.HostPriorityList{}, err } @@ -141,32 +141,32 @@ func NewNodeLabelPriority(label string, presence bool) algorithm.PriorityFunctio return labelPrioritizer.CalculateNodeLabelPriority } -// CalculateNodeLabelPriority checks whether a particular label exists on a minion or not, regardless of its value. -// If presence is true, prioritizes minions that have the specified label, regardless of value. -// If presence is false, prioritizes minions that do not have the specified label. -func (n *NodeLabelPrioritizer) CalculateNodeLabelPriority(pod *api.Pod, podLister algorithm.PodLister, minionLister algorithm.MinionLister) (algorithm.HostPriorityList, error) { +// CalculateNodeLabelPriority checks whether a particular label exists on a node or not, regardless of its value. +// If presence is true, prioritizes nodes that have the specified label, regardless of value. +// If presence is false, prioritizes nodes that do not have the specified label. +func (n *NodeLabelPrioritizer) CalculateNodeLabelPriority(pod *api.Pod, podLister algorithm.PodLister, nodeLister algorithm.NodeLister) (algorithm.HostPriorityList, error) { var score int - minions, err := minionLister.List() + nodes, err := nodeLister.List() if err != nil { return nil, err } - labeledMinions := map[string]bool{} - for _, minion := range minions.Items { - exists := labels.Set(minion.Labels).Has(n.label) - labeledMinions[minion.Name] = (exists && n.presence) || (!exists && !n.presence) + labeledNodes := map[string]bool{} + for _, node := range nodes.Items { + exists := labels.Set(node.Labels).Has(n.label) + labeledNodes[node.Name] = (exists && n.presence) || (!exists && !n.presence) } result := []algorithm.HostPriority{} //score int - scale of 0-10 // 0 being the lowest priority and 10 being the highest - for minionName, success := range labeledMinions { + for nodeName, success := range labeledNodes { if success { score = 10 } else { score = 0 } - result = append(result, algorithm.HostPriority{Host: minionName, Score: score}) + result = append(result, algorithm.HostPriority{Host: nodeName, Score: score}) } return result, nil } @@ -177,8 +177,8 @@ func (n *NodeLabelPrioritizer) CalculateNodeLabelPriority(pod *api.Pod, podListe // close the two metrics are to each other. // Detail: score = 10 - abs(cpuFraction-memoryFraction)*10. The algorithm is partly inspired by: // "Wei Huang et al. An Energy Efficient Virtual Machine Placement Algorithm with Balanced Resource Utilization" -func BalancedResourceAllocation(pod *api.Pod, podLister algorithm.PodLister, minionLister algorithm.MinionLister) (algorithm.HostPriorityList, error) { - nodes, err := minionLister.List() +func BalancedResourceAllocation(pod *api.Pod, podLister algorithm.PodLister, nodeLister algorithm.NodeLister) (algorithm.HostPriorityList, error) { + nodes, err := nodeLister.List() if err != nil { return algorithm.HostPriorityList{}, err } @@ -203,7 +203,7 @@ func calculateBalancedResourceAllocation(pod *api.Pod, node api.Node, pods []*ap } } // Add the resources requested by the current pod being scheduled. - // This also helps differentiate between differently sized, but empty, minions. + // This also helps differentiate between differently sized, but empty, nodes. for _, container := range pod.Spec.Containers { cpu, memory := getNonzeroRequests(&container.Resources.Requests) totalMilliCPU += cpu diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/priorities_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/priorities_test.go index 63f2ddbdd1d2..312b950496db 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/priorities_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/priorities_test.go @@ -28,7 +28,7 @@ import ( "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm" ) -func makeMinion(node string, milliCPU, memory int64) api.Node { +func makeNode(node string, milliCPU, memory int64) api.Node { return api.Node{ ObjectMeta: api.ObjectMeta{Name: node}, Status: api.NodeStatus{ @@ -96,7 +96,7 @@ func TestZeroRequest(t *testing.T) { // and when the zero-request pod is the one being scheduled. { pod: &api.Pod{Spec: noResources}, - nodes: []api.Node{makeMinion("machine1", 1000, defaultMemoryRequest*10), makeMinion("machine2", 1000, defaultMemoryRequest*10)}, + nodes: []api.Node{makeNode("machine1", 1000, defaultMemoryRequest*10), makeNode("machine2", 1000, defaultMemoryRequest*10)}, test: "test priority of zero-request pod with machine with zero-request pod", pods: []*api.Pod{ {Spec: large1}, {Spec: noResources1}, @@ -105,7 +105,7 @@ func TestZeroRequest(t *testing.T) { }, { pod: &api.Pod{Spec: small}, - nodes: []api.Node{makeMinion("machine1", 1000, defaultMemoryRequest*10), makeMinion("machine2", 1000, defaultMemoryRequest*10)}, + nodes: []api.Node{makeNode("machine1", 1000, defaultMemoryRequest*10), makeNode("machine2", 1000, defaultMemoryRequest*10)}, test: "test priority of nonzero-request pod with machine with zero-request pod", pods: []*api.Pod{ {Spec: large1}, {Spec: noResources1}, @@ -115,7 +115,7 @@ func TestZeroRequest(t *testing.T) { // The point of this test is to verify that we're not just getting the same score no matter what we schedule. { pod: &api.Pod{Spec: large}, - nodes: []api.Node{makeMinion("machine1", 1000, defaultMemoryRequest*10), makeMinion("machine2", 1000, defaultMemoryRequest*10)}, + nodes: []api.Node{makeNode("machine1", 1000, defaultMemoryRequest*10), makeNode("machine2", 1000, defaultMemoryRequest*10)}, test: "test priority of larger pod with machine with zero-request pod", pods: []*api.Pod{ {Spec: large1}, {Spec: noResources1}, @@ -133,7 +133,7 @@ func TestZeroRequest(t *testing.T) { // plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go if you want // to test what's actually in production. []algorithm.PriorityConfig{{Function: LeastRequestedPriority, Weight: 1}, {Function: BalancedResourceAllocation, Weight: 1}, {Function: NewSelectorSpreadPriority(algorithm.FakeServiceLister([]api.Service{}), algorithm.FakeControllerLister([]api.ReplicationController{})), Weight: 1}}, - algorithm.FakeMinionLister(api.NodeList{Items: test.nodes})) + algorithm.FakeNodeLister(api.NodeList{Items: test.nodes})) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -222,52 +222,52 @@ func TestLeastRequested(t *testing.T) { }{ { /* - Minion1 scores (remaining resources) on 0-10 scale + Node1 scores (remaining resources) on 0-10 scale CPU Score: ((4000 - 0) *10) / 4000 = 10 Memory Score: ((10000 - 0) *10) / 10000 = 10 - Minion1 Score: (10 + 10) / 2 = 10 + Node1 Score: (10 + 10) / 2 = 10 - Minion2 scores (remaining resources) on 0-10 scale + Node2 scores (remaining resources) on 0-10 scale CPU Score: ((4000 - 0) *10) / 4000 = 10 Memory Score: ((10000 - 0) *10) / 10000 = 10 - Minion2 Score: (10 + 10) / 2 = 10 + Node2 Score: (10 + 10) / 2 = 10 */ pod: &api.Pod{Spec: noResources}, - nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)}, + nodes: []api.Node{makeNode("machine1", 4000, 10000), makeNode("machine2", 4000, 10000)}, expectedList: []algorithm.HostPriority{{"machine1", 10}, {"machine2", 10}}, test: "nothing scheduled, nothing requested", }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Score: ((4000 - 3000) *10) / 4000 = 2.5 Memory Score: ((10000 - 5000) *10) / 10000 = 5 - Minion1 Score: (2.5 + 5) / 2 = 3 + Node1 Score: (2.5 + 5) / 2 = 3 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Score: ((6000 - 3000) *10) / 6000 = 5 Memory Score: ((10000 - 5000) *10) / 10000 = 5 - Minion2 Score: (5 + 5) / 2 = 5 + Node2 Score: (5 + 5) / 2 = 5 */ pod: &api.Pod{Spec: cpuAndMemory}, - nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 6000, 10000)}, + nodes: []api.Node{makeNode("machine1", 4000, 10000), makeNode("machine2", 6000, 10000)}, expectedList: []algorithm.HostPriority{{"machine1", 3}, {"machine2", 5}}, test: "nothing scheduled, resources requested, differently sized machines", }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Score: ((4000 - 0) *10) / 4000 = 10 Memory Score: ((10000 - 0) *10) / 10000 = 10 - Minion1 Score: (10 + 10) / 2 = 10 + Node1 Score: (10 + 10) / 2 = 10 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Score: ((4000 - 0) *10) / 4000 = 10 Memory Score: ((10000 - 0) *10) / 10000 = 10 - Minion2 Score: (10 + 10) / 2 = 10 + Node2 Score: (10 + 10) / 2 = 10 */ pod: &api.Pod{Spec: noResources}, - nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)}, + nodes: []api.Node{makeNode("machine1", 4000, 10000), makeNode("machine2", 4000, 10000)}, expectedList: []algorithm.HostPriority{{"machine1", 10}, {"machine2", 10}}, test: "no resources requested, pods scheduled", pods: []*api.Pod{ @@ -279,18 +279,18 @@ func TestLeastRequested(t *testing.T) { }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Score: ((10000 - 6000) *10) / 10000 = 4 Memory Score: ((20000 - 0) *10) / 20000 = 10 - Minion1 Score: (4 + 10) / 2 = 7 + Node1 Score: (4 + 10) / 2 = 7 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Score: ((10000 - 6000) *10) / 10000 = 4 Memory Score: ((20000 - 5000) *10) / 20000 = 7.5 - Minion2 Score: (4 + 7.5) / 2 = 5 + Node2 Score: (4 + 7.5) / 2 = 5 */ pod: &api.Pod{Spec: noResources}, - nodes: []api.Node{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 20000)}, + nodes: []api.Node{makeNode("machine1", 10000, 20000), makeNode("machine2", 10000, 20000)}, expectedList: []algorithm.HostPriority{{"machine1", 7}, {"machine2", 5}}, test: "no resources requested, pods scheduled with resources", pods: []*api.Pod{ @@ -302,18 +302,18 @@ func TestLeastRequested(t *testing.T) { }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Score: ((10000 - 6000) *10) / 10000 = 4 Memory Score: ((20000 - 5000) *10) / 20000 = 7.5 - Minion1 Score: (4 + 7.5) / 2 = 5 + Node1 Score: (4 + 7.5) / 2 = 5 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Score: ((10000 - 6000) *10) / 10000 = 4 Memory Score: ((20000 - 10000) *10) / 20000 = 5 - Minion2 Score: (4 + 5) / 2 = 4 + Node2 Score: (4 + 5) / 2 = 4 */ pod: &api.Pod{Spec: cpuAndMemory}, - nodes: []api.Node{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 20000)}, + nodes: []api.Node{makeNode("machine1", 10000, 20000), makeNode("machine2", 10000, 20000)}, expectedList: []algorithm.HostPriority{{"machine1", 5}, {"machine2", 4}}, test: "resources requested, pods scheduled with resources", pods: []*api.Pod{ @@ -323,18 +323,18 @@ func TestLeastRequested(t *testing.T) { }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Score: ((10000 - 6000) *10) / 10000 = 4 Memory Score: ((20000 - 5000) *10) / 20000 = 7.5 - Minion1 Score: (4 + 7.5) / 2 = 5 + Node1 Score: (4 + 7.5) / 2 = 5 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Score: ((10000 - 6000) *10) / 10000 = 4 Memory Score: ((50000 - 10000) *10) / 50000 = 8 - Minion2 Score: (4 + 8) / 2 = 6 + Node2 Score: (4 + 8) / 2 = 6 */ pod: &api.Pod{Spec: cpuAndMemory}, - nodes: []api.Node{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 50000)}, + nodes: []api.Node{makeNode("machine1", 10000, 20000), makeNode("machine2", 10000, 50000)}, expectedList: []algorithm.HostPriority{{"machine1", 5}, {"machine2", 6}}, test: "resources requested, pods scheduled with resources, differently sized machines", pods: []*api.Pod{ @@ -344,20 +344,20 @@ func TestLeastRequested(t *testing.T) { }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Score: ((4000 - 6000) *10) / 4000 = 0 Memory Score: ((10000 - 0) *10) / 10000 = 10 - Minion1 Score: (0 + 10) / 2 = 5 + Node1 Score: (0 + 10) / 2 = 5 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Score: ((4000 - 6000) *10) / 4000 = 0 Memory Score: ((10000 - 5000) *10) / 10000 = 5 - Minion2 Score: (0 + 5) / 2 = 2 + Node2 Score: (0 + 5) / 2 = 2 */ pod: &api.Pod{Spec: cpuOnly}, - nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)}, + nodes: []api.Node{makeNode("machine1", 4000, 10000), makeNode("machine2", 4000, 10000)}, expectedList: []algorithm.HostPriority{{"machine1", 5}, {"machine2", 2}}, - test: "requested resources exceed minion capacity", + test: "requested resources exceed node capacity", pods: []*api.Pod{ {Spec: cpuOnly}, {Spec: cpuAndMemory}, @@ -365,9 +365,9 @@ func TestLeastRequested(t *testing.T) { }, { pod: &api.Pod{Spec: noResources}, - nodes: []api.Node{makeMinion("machine1", 0, 0), makeMinion("machine2", 0, 0)}, + nodes: []api.Node{makeNode("machine1", 0, 0), makeNode("machine2", 0, 0)}, expectedList: []algorithm.HostPriority{{"machine1", 0}, {"machine2", 0}}, - test: "zero minion resources, pods scheduled with resources", + test: "zero node resources, pods scheduled with resources", pods: []*api.Pod{ {Spec: cpuOnly}, {Spec: cpuAndMemory}, @@ -376,7 +376,7 @@ func TestLeastRequested(t *testing.T) { } for _, test := range tests { - list, err := LeastRequestedPriority(test.pod, algorithm.FakePodLister(test.pods), algorithm.FakeMinionLister(api.NodeList{Items: test.nodes})) + list, err := LeastRequestedPriority(test.pod, algorithm.FakePodLister(test.pods), algorithm.FakeNodeLister(api.NodeList{Items: test.nodes})) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -470,7 +470,7 @@ func TestNewNodeLabelPriority(t *testing.T) { label: test.label, presence: test.presence, } - list, err := prioritizer.CalculateNodeLabelPriority(nil, nil, algorithm.FakeMinionLister(api.NodeList{Items: test.nodes})) + list, err := prioritizer.CalculateNodeLabelPriority(nil, nil, algorithm.FakeNodeLister(api.NodeList{Items: test.nodes})) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -554,52 +554,52 @@ func TestBalancedResourceAllocation(t *testing.T) { }{ { /* - Minion1 scores (remaining resources) on 0-10 scale + Node1 scores (remaining resources) on 0-10 scale CPU Fraction: 0 / 4000 = 0% Memory Fraction: 0 / 10000 = 0% - Minion1 Score: 10 - (0-0)*10 = 10 + Node1 Score: 10 - (0-0)*10 = 10 - Minion2 scores (remaining resources) on 0-10 scale + Node2 scores (remaining resources) on 0-10 scale CPU Fraction: 0 / 4000 = 0 % Memory Fraction: 0 / 10000 = 0% - Minion2 Score: 10 - (0-0)*10 = 10 + Node2 Score: 10 - (0-0)*10 = 10 */ pod: &api.Pod{Spec: noResources}, - nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)}, + nodes: []api.Node{makeNode("machine1", 4000, 10000), makeNode("machine2", 4000, 10000)}, expectedList: []algorithm.HostPriority{{"machine1", 10}, {"machine2", 10}}, test: "nothing scheduled, nothing requested", }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Fraction: 3000 / 4000= 75% Memory Fraction: 5000 / 10000 = 50% - Minion1 Score: 10 - (0.75-0.5)*10 = 7 + Node1 Score: 10 - (0.75-0.5)*10 = 7 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Fraction: 3000 / 6000= 50% Memory Fraction: 5000/10000 = 50% - Minion2 Score: 10 - (0.5-0.5)*10 = 10 + Node2 Score: 10 - (0.5-0.5)*10 = 10 */ pod: &api.Pod{Spec: cpuAndMemory}, - nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 6000, 10000)}, + nodes: []api.Node{makeNode("machine1", 4000, 10000), makeNode("machine2", 6000, 10000)}, expectedList: []algorithm.HostPriority{{"machine1", 7}, {"machine2", 10}}, test: "nothing scheduled, resources requested, differently sized machines", }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Fraction: 0 / 4000= 0% Memory Fraction: 0 / 10000 = 0% - Minion1 Score: 10 - (0-0)*10 = 10 + Node1 Score: 10 - (0-0)*10 = 10 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Fraction: 0 / 4000= 0% Memory Fraction: 0 / 10000 = 0% - Minion2 Score: 10 - (0-0)*10 = 10 + Node2 Score: 10 - (0-0)*10 = 10 */ pod: &api.Pod{Spec: noResources}, - nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)}, + nodes: []api.Node{makeNode("machine1", 4000, 10000), makeNode("machine2", 4000, 10000)}, expectedList: []algorithm.HostPriority{{"machine1", 10}, {"machine2", 10}}, test: "no resources requested, pods scheduled", pods: []*api.Pod{ @@ -611,18 +611,18 @@ func TestBalancedResourceAllocation(t *testing.T) { }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Fraction: 6000 / 10000 = 60% Memory Fraction: 0 / 20000 = 0% - Minion1 Score: 10 - (0.6-0)*10 = 4 + Node1 Score: 10 - (0.6-0)*10 = 4 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Fraction: 6000 / 10000 = 60% Memory Fraction: 5000 / 20000 = 25% - Minion2 Score: 10 - (0.6-0.25)*10 = 6 + Node2 Score: 10 - (0.6-0.25)*10 = 6 */ pod: &api.Pod{Spec: noResources}, - nodes: []api.Node{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 20000)}, + nodes: []api.Node{makeNode("machine1", 10000, 20000), makeNode("machine2", 10000, 20000)}, expectedList: []algorithm.HostPriority{{"machine1", 4}, {"machine2", 6}}, test: "no resources requested, pods scheduled with resources", pods: []*api.Pod{ @@ -634,18 +634,18 @@ func TestBalancedResourceAllocation(t *testing.T) { }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Fraction: 6000 / 10000 = 60% Memory Fraction: 5000 / 20000 = 25% - Minion1 Score: 10 - (0.6-0.25)*10 = 6 + Node1 Score: 10 - (0.6-0.25)*10 = 6 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Fraction: 6000 / 10000 = 60% Memory Fraction: 10000 / 20000 = 50% - Minion2 Score: 10 - (0.6-0.5)*10 = 9 + Node2 Score: 10 - (0.6-0.5)*10 = 9 */ pod: &api.Pod{Spec: cpuAndMemory}, - nodes: []api.Node{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 20000)}, + nodes: []api.Node{makeNode("machine1", 10000, 20000), makeNode("machine2", 10000, 20000)}, expectedList: []algorithm.HostPriority{{"machine1", 6}, {"machine2", 9}}, test: "resources requested, pods scheduled with resources", pods: []*api.Pod{ @@ -655,18 +655,18 @@ func TestBalancedResourceAllocation(t *testing.T) { }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Fraction: 6000 / 10000 = 60% Memory Fraction: 5000 / 20000 = 25% - Minion1 Score: 10 - (0.6-0.25)*10 = 6 + Node1 Score: 10 - (0.6-0.25)*10 = 6 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Fraction: 6000 / 10000 = 60% Memory Fraction: 10000 / 50000 = 20% - Minion2 Score: 10 - (0.6-0.2)*10 = 6 + Node2 Score: 10 - (0.6-0.2)*10 = 6 */ pod: &api.Pod{Spec: cpuAndMemory}, - nodes: []api.Node{makeMinion("machine1", 10000, 20000), makeMinion("machine2", 10000, 50000)}, + nodes: []api.Node{makeNode("machine1", 10000, 20000), makeNode("machine2", 10000, 50000)}, expectedList: []algorithm.HostPriority{{"machine1", 6}, {"machine2", 6}}, test: "resources requested, pods scheduled with resources, differently sized machines", pods: []*api.Pod{ @@ -676,20 +676,20 @@ func TestBalancedResourceAllocation(t *testing.T) { }, { /* - Minion1 scores on 0-10 scale + Node1 scores on 0-10 scale CPU Fraction: 6000 / 4000 > 100% ==> Score := 0 Memory Fraction: 0 / 10000 = 0 - Minion1 Score: 0 + Node1 Score: 0 - Minion2 scores on 0-10 scale + Node2 scores on 0-10 scale CPU Fraction: 6000 / 4000 > 100% ==> Score := 0 Memory Fraction 5000 / 10000 = 50% - Minion2 Score: 0 + Node2 Score: 0 */ pod: &api.Pod{Spec: cpuOnly}, - nodes: []api.Node{makeMinion("machine1", 4000, 10000), makeMinion("machine2", 4000, 10000)}, + nodes: []api.Node{makeNode("machine1", 4000, 10000), makeNode("machine2", 4000, 10000)}, expectedList: []algorithm.HostPriority{{"machine1", 0}, {"machine2", 0}}, - test: "requested resources exceed minion capacity", + test: "requested resources exceed node capacity", pods: []*api.Pod{ {Spec: cpuOnly}, {Spec: cpuAndMemory}, @@ -697,9 +697,9 @@ func TestBalancedResourceAllocation(t *testing.T) { }, { pod: &api.Pod{Spec: noResources}, - nodes: []api.Node{makeMinion("machine1", 0, 0), makeMinion("machine2", 0, 0)}, + nodes: []api.Node{makeNode("machine1", 0, 0), makeNode("machine2", 0, 0)}, expectedList: []algorithm.HostPriority{{"machine1", 0}, {"machine2", 0}}, - test: "zero minion resources, pods scheduled with resources", + test: "zero node resources, pods scheduled with resources", pods: []*api.Pod{ {Spec: cpuOnly}, {Spec: cpuAndMemory}, @@ -708,7 +708,7 @@ func TestBalancedResourceAllocation(t *testing.T) { } for _, test := range tests { - list, err := BalancedResourceAllocation(test.pod, algorithm.FakePodLister(test.pods), algorithm.FakeMinionLister(api.NodeList{Items: test.nodes})) + list, err := BalancedResourceAllocation(test.pod, algorithm.FakePodLister(test.pods), algorithm.FakeNodeLister(api.NodeList{Items: test.nodes})) if err != nil { t.Errorf("unexpected error: %v", err) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/selector_spreading.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/selector_spreading.go index 11f5f9435980..c5a2a5aa5323 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/selector_spreading.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/selector_spreading.go @@ -39,7 +39,7 @@ func NewSelectorSpreadPriority(serviceLister algorithm.ServiceLister, controller // CalculateSpreadPriority spreads pods by minimizing the number of pods belonging to the same service or replication controller. It counts number of pods that run under // Services or RCs as the pod being scheduled and tries to minimize the number of conflicts. I.e. pushes scheduler towards a Node where there's a smallest number of // pods which match the same selectors of Services and RCs as current pod. -func (s *SelectorSpread) CalculateSpreadPriority(pod *api.Pod, podLister algorithm.PodLister, minionLister algorithm.MinionLister) (algorithm.HostPriorityList, error) { +func (s *SelectorSpread) CalculateSpreadPriority(pod *api.Pod, podLister algorithm.PodLister, nodeLister algorithm.NodeLister) (algorithm.HostPriorityList, error) { var maxCount int var nsPods []*api.Pod @@ -70,7 +70,7 @@ func (s *SelectorSpread) CalculateSpreadPriority(pod *api.Pod, podLister algorit } } - minions, err := minionLister.List() + nodes, err := nodeLister.List() if err != nil { return nil, err } @@ -87,7 +87,7 @@ func (s *SelectorSpread) CalculateSpreadPriority(pod *api.Pod, podLister algorit } if matches { counts[pod.Spec.NodeName]++ - // Compute the maximum number of pods hosted on any minion + // Compute the maximum number of pods hosted on any node if counts[pod.Spec.NodeName] > maxCount { maxCount = counts[pod.Spec.NodeName] } @@ -98,15 +98,15 @@ func (s *SelectorSpread) CalculateSpreadPriority(pod *api.Pod, podLister algorit result := []algorithm.HostPriority{} //score int - scale of 0-10 // 0 being the lowest priority and 10 being the highest - for _, minion := range minions.Items { - // initializing to the default/max minion score of 10 + for _, node := range nodes.Items { + // initializing to the default/max node score of 10 fScore := float32(10) if maxCount > 0 { - fScore = 10 * (float32(maxCount-counts[minion.Name]) / float32(maxCount)) + fScore = 10 * (float32(maxCount-counts[node.Name]) / float32(maxCount)) } - result = append(result, algorithm.HostPriority{Host: minion.Name, Score: int(fScore)}) + result = append(result, algorithm.HostPriority{Host: node.Name, Score: int(fScore)}) glog.V(10).Infof( - "%v -> %v: SelectorSpreadPriority, Score: (%d)", pod.Name, minion.Name, int(fScore), + "%v -> %v: SelectorSpreadPriority, Score: (%d)", pod.Name, node.Name, int(fScore), ) } return result, nil @@ -128,7 +128,7 @@ func NewServiceAntiAffinityPriority(serviceLister algorithm.ServiceLister, label // CalculateAntiAffinityPriority spreads pods by minimizing the number of pods belonging to the same service // on machines with the same value for a particular label. // The label to be considered is provided to the struct (ServiceAntiAffinity). -func (s *ServiceAntiAffinity) CalculateAntiAffinityPriority(pod *api.Pod, podLister algorithm.PodLister, minionLister algorithm.MinionLister) (algorithm.HostPriorityList, error) { +func (s *ServiceAntiAffinity) CalculateAntiAffinityPriority(pod *api.Pod, podLister algorithm.PodLister, nodeLister algorithm.NodeLister) (algorithm.HostPriorityList, error) { var nsServicePods []*api.Pod services, err := s.serviceLister.GetPodServices(pod) @@ -148,26 +148,26 @@ func (s *ServiceAntiAffinity) CalculateAntiAffinityPriority(pod *api.Pod, podLis } } - minions, err := minionLister.List() + nodes, err := nodeLister.List() if err != nil { return nil, err } - // separate out the minions that have the label from the ones that don't - otherMinions := []string{} - labeledMinions := map[string]string{} - for _, minion := range minions.Items { - if labels.Set(minion.Labels).Has(s.label) { - label := labels.Set(minion.Labels).Get(s.label) - labeledMinions[minion.Name] = label + // separate out the nodes that have the label from the ones that don't + otherNodes := []string{} + labeledNodes := map[string]string{} + for _, node := range nodes.Items { + if labels.Set(node.Labels).Has(s.label) { + label := labels.Set(node.Labels).Get(s.label) + labeledNodes[node.Name] = label } else { - otherMinions = append(otherMinions, minion.Name) + otherNodes = append(otherNodes, node.Name) } } podCounts := map[string]int{} for _, pod := range nsServicePods { - label, exists := labeledMinions[pod.Spec.NodeName] + label, exists := labeledNodes[pod.Spec.NodeName] if !exists { continue } @@ -178,17 +178,17 @@ func (s *ServiceAntiAffinity) CalculateAntiAffinityPriority(pod *api.Pod, podLis result := []algorithm.HostPriority{} //score int - scale of 0-10 // 0 being the lowest priority and 10 being the highest - for minion := range labeledMinions { - // initializing to the default/max minion score of 10 + for node := range labeledNodes { + // initializing to the default/max node score of 10 fScore := float32(10) if numServicePods > 0 { - fScore = 10 * (float32(numServicePods-podCounts[labeledMinions[minion]]) / float32(numServicePods)) + fScore = 10 * (float32(numServicePods-podCounts[labeledNodes[node]]) / float32(numServicePods)) } - result = append(result, algorithm.HostPriority{Host: minion, Score: int(fScore)}) + result = append(result, algorithm.HostPriority{Host: node, Score: int(fScore)}) } - // add the open minions with a score of 0 - for _, minion := range otherMinions { - result = append(result, algorithm.HostPriority{Host: minion, Score: 0}) + // add the open nodes with a score of 0 + for _, node := range otherNodes { + result = append(result, algorithm.HostPriority{Host: node, Score: 0}) } return result, nil diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/selector_spreading_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/selector_spreading_test.go index 5360a1aed55c..0d45d4a178be 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/selector_spreading_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/selector_spreading_test.go @@ -217,7 +217,7 @@ func TestSelectorSpreadPriority(t *testing.T) { for _, test := range tests { selectorSpread := SelectorSpread{serviceLister: algorithm.FakeServiceLister(test.services), controllerLister: algorithm.FakeControllerLister(test.rcs)} - list, err := selectorSpread.CalculateSpreadPriority(test.pod, algorithm.FakePodLister(test.pods), algorithm.FakeMinionLister(makeNodeList(test.nodes))) + list, err := selectorSpread.CalculateSpreadPriority(test.pod, algorithm.FakePodLister(test.pods), algorithm.FakeNodeLister(makeNodeList(test.nodes))) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -379,13 +379,13 @@ func TestZoneSpreadPriority(t *testing.T) { expectedList: []algorithm.HostPriority{{"machine11", 7}, {"machine12", 7}, {"machine21", 5}, {"machine22", 5}, {"machine01", 0}, {"machine02", 0}}, - test: "service pod on non-zoned minion", + test: "service pod on non-zoned node", }, } for _, test := range tests { zoneSpread := ServiceAntiAffinity{serviceLister: algorithm.FakeServiceLister(test.services), label: "zone"} - list, err := zoneSpread.CalculateAntiAffinityPriority(test.pod, algorithm.FakePodLister(test.pods), algorithm.FakeMinionLister(makeLabeledMinionList(test.nodes))) + list, err := zoneSpread.CalculateAntiAffinityPriority(test.pod, algorithm.FakePodLister(test.pods), algorithm.FakeNodeLister(makeLabeledNodeList(test.nodes))) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -398,7 +398,7 @@ func TestZoneSpreadPriority(t *testing.T) { } } -func makeLabeledMinionList(nodeMap map[string]map[string]string) (result api.NodeList) { +func makeLabeledNodeList(nodeMap map[string]map[string]string) (result api.NodeList) { nodes := []api.Node{} for nodeName, labels := range nodeMap { nodes = append(nodes, api.Node{ObjectMeta: api.ObjectMeta{Name: nodeName, Labels: labels}}) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/scheduler_interface.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/scheduler_interface.go index d5794eeb924a..4b50600c278d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/scheduler_interface.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/scheduler_interface.go @@ -23,5 +23,5 @@ import ( // Scheduler is an interface implemented by things that know how to schedule pods // onto machines. type ScheduleAlgorithm interface { - Schedule(*api.Pod, MinionLister) (selectedMachine string, err error) + Schedule(*api.Pod, NodeLister) (selectedMachine string, err error) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/scheduler_interface_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/scheduler_interface_test.go index 0e7ef58f65a8..bc75419916cb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/scheduler_interface_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/scheduler_interface_test.go @@ -25,14 +25,14 @@ import ( // Some functions used by multiple scheduler tests. type schedulerTester struct { - t *testing.T - scheduler ScheduleAlgorithm - minionLister MinionLister + t *testing.T + scheduler ScheduleAlgorithm + nodeLister NodeLister } // Call if you know exactly where pod should get scheduled. func (st *schedulerTester) expectSchedule(pod *api.Pod, expected string) { - actual, err := st.scheduler.Schedule(pod, st.minionLister) + actual, err := st.scheduler.Schedule(pod, st.nodeLister) if err != nil { st.t.Errorf("Unexpected error %v\nTried to scheduler: %#v", err, pod) return @@ -44,7 +44,7 @@ func (st *schedulerTester) expectSchedule(pod *api.Pod, expected string) { // Call if you can't predict where pod will be scheduled. func (st *schedulerTester) expectSuccess(pod *api.Pod) { - _, err := st.scheduler.Schedule(pod, st.minionLister) + _, err := st.scheduler.Schedule(pod, st.nodeLister) if err != nil { st.t.Errorf("Unexpected error %v\nTried to scheduler: %#v", err, pod) return @@ -53,7 +53,7 @@ func (st *schedulerTester) expectSuccess(pod *api.Pod) { // Call if pod should *not* schedule. func (st *schedulerTester) expectFailure(pod *api.Pod) { - _, err := st.scheduler.Schedule(pod, st.minionLister) + _, err := st.scheduler.Schedule(pod, st.nodeLister) if err == nil { st.t.Error("Unexpected non-error") } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/types.go index 6038968869be..1f340e255049 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/types.go @@ -46,7 +46,7 @@ func (h HostPriorityList) Swap(i, j int) { h[i], h[j] = h[j], h[i] } -type PriorityFunction func(pod *api.Pod, podLister PodLister, minionLister MinionLister) (HostPriorityList, error) +type PriorityFunction func(pod *api.Pod, podLister PodLister, nodeLister NodeLister) (HostPriorityList, error) type PriorityConfig struct { Function PriorityFunction diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/compatibility_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/compatibility_test.go index 62918ca184e4..0288bae78d87 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/compatibility_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/compatibility_test.go @@ -34,6 +34,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { // Do not change this JSON. A failure indicates backwards compatibility with 1.0 was broken. "1.0": { JSON: `{ + "kind": "Policy", + "apiVersion": "v1", "predicates": [ {"name": "MatchNodeSelector"}, {"name": "PodFitsResources"}, @@ -69,11 +71,18 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { // Do not change this JSON after 1.1 is tagged. A failure indicates backwards compatibility with 1.1 was broken. "1.1": { JSON: `{ - "priorities": [ + "kind": "Policy", + "apiVersion": "v1", + "predicates": [ + {"name": "PodFitsHostPorts"} + ],"priorities": [ {"name": "SelectorSpreadPriority", "weight": 2} ] }`, ExpectedPolicy: schedulerapi.Policy{ + Predicates: []schedulerapi.PredicatePolicy{ + {Name: "PodFitsHostPorts"}, + }, Priorities: []schedulerapi.PriorityPolicy{ {Name: "SelectorSpreadPriority", Weight: 2}, }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go index c8b801fd52f4..c3c0e389cf70 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go @@ -28,7 +28,7 @@ import ( func init() { factory.RegisterAlgorithmProvider(factory.DefaultProvider, defaultPredicates(), defaultPriorities()) - // EqualPriority is a prioritizer function that gives an equal weight of one to all minions + // EqualPriority is a prioritizer function that gives an equal weight of one to all nodes // Register the priority function so that its available // but do not include it as part of the default priorities factory.RegisterPriorityFunction("EqualPriority", scheduler.EqualPriority, 1) @@ -46,12 +46,15 @@ func init() { Weight: 1, }, ) + // PodFitsPorts has been replaced by PodFitsHostPorts for better user understanding. + // For backwards compatibility with 1.0, PodFitsPorts is regitered as well. + factory.RegisterFitPredicate("PodFitsPorts", predicates.PodFitsHostPorts) } func defaultPredicates() sets.String { return sets.NewString( // Fit is defined based on the absence of port conflicts. - factory.RegisterFitPredicate("PodFitsPorts", predicates.PodFitsPorts), + factory.RegisterFitPredicate("PodFitsHostPorts", predicates.PodFitsHostPorts), // Fit is determined by resource availability. factory.RegisterFitPredicateFactory( "PodFitsResources", diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/api/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/api/types.go index 555da43d4041..93bb557a7cfd 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/api/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/api/types.go @@ -16,12 +16,10 @@ limitations under the License. package api -import ( - "k8s.io/kubernetes/pkg/api" -) +import "k8s.io/kubernetes/pkg/api/unversioned" type Policy struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Holds the information to configure the fit predicate functions Predicates []PredicatePolicy `json:"predicates"` // Holds the information to configure the priority functions @@ -42,7 +40,7 @@ type PriorityPolicy struct { // For a custom priority, the name can be user-defined // For the Kubernetes provided priority functions, the name is the identifier of the pre-defined priority function Name string `json:"name"` - // The numeric multiplier for the minion scores that the priority function generates + // The numeric multiplier for the node scores that the priority function generates // The weight should be non-zero and can be a positive or a negative integer Weight int `json:"weight"` // Holds the parameters to configure the given priority function @@ -53,9 +51,9 @@ type PriorityPolicy struct { // Only one of its members may be specified type PredicateArgument struct { // The predicate that provides affinity for pods belonging to a service - // It uses a label to identify minions that belong to the same "group" + // It uses a label to identify nodes that belong to the same "group" ServiceAffinity *ServiceAffinity `json:"serviceAffinity"` - // The predicate that checks whether a particular minion has a certain label + // The predicate that checks whether a particular node has a certain label // defined or not, regardless of value LabelsPresence *LabelsPresence `json:"labelsPresence"` } @@ -64,41 +62,41 @@ type PredicateArgument struct { // Only one of its members may be specified type PriorityArgument struct { // The priority function that ensures a good spread (anti-affinity) for pods belonging to a service - // It uses a label to identify minions that belong to the same "group" + // It uses a label to identify nodes that belong to the same "group" ServiceAntiAffinity *ServiceAntiAffinity `json:"serviceAntiAffinity"` - // The priority function that checks whether a particular minion has a certain label + // The priority function that checks whether a particular node has a certain label // defined or not, regardless of value LabelPreference *LabelPreference `json:"labelPreference"` } // Holds the parameters that are used to configure the corresponding predicate type ServiceAffinity struct { - // The list of labels that identify minion "groups" - // All of the labels should match for the minion to be considered a fit for hosting the pod + // The list of labels that identify node "groups" + // All of the labels should match for the node to be considered a fit for hosting the pod Labels []string `json:"labels"` } // Holds the parameters that are used to configure the corresponding predicate type LabelsPresence struct { - // The list of labels that identify minion "groups" - // All of the labels should be either present (or absent) for the minion to be considered a fit for hosting the pod + // The list of labels that identify node "groups" + // All of the labels should be either present (or absent) for the node to be considered a fit for hosting the pod Labels []string `json:"labels"` - // The boolean flag that indicates whether the labels should be present or absent from the minion + // The boolean flag that indicates whether the labels should be present or absent from the node Presence bool `json:"presence"` } // Holds the parameters that are used to configure the corresponding priority function type ServiceAntiAffinity struct { - // Used to identify minion "groups" + // Used to identify node "groups" Label string `json:"label"` } // Holds the parameters that are used to configure the corresponding priority function type LabelPreference struct { - // Used to identify minion "groups" + // Used to identify node "groups" Label string `json:"label"` // This is a boolean flag - // If true, higher priority is given to minions that have the label - // If false, higher priority is given to minions that do not have the label + // If true, higher priority is given to nodes that have the label + // If false, higher priority is given to nodes that do not have the label Presence bool `json:"presence"` } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/api/v1/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/api/v1/types.go index ede00c340929..b7c0c395f80d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/api/v1/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/api/v1/types.go @@ -16,12 +16,10 @@ limitations under the License. package v1 -import ( - apiv1 "k8s.io/kubernetes/pkg/api/v1" -) +import "k8s.io/kubernetes/pkg/api/unversioned" type Policy struct { - apiv1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Holds the information to configure the fit predicate functions Predicates []PredicatePolicy `json:"predicates"` // Holds the information to configure the priority functions @@ -42,7 +40,7 @@ type PriorityPolicy struct { // For a custom priority, the name can be user-defined // For the Kubernetes provided priority functions, the name is the identifier of the pre-defined priority function Name string `json:"name"` - // The numeric multiplier for the minion scores that the priority function generates + // The numeric multiplier for the node scores that the priority function generates // The weight should be non-zero and can be a positive or a negative integer Weight int `json:"weight"` // Holds the parameters to configure the given priority function @@ -53,9 +51,9 @@ type PriorityPolicy struct { // Only one of its members may be specified type PredicateArgument struct { // The predicate that provides affinity for pods belonging to a service - // It uses a label to identify minions that belong to the same "group" + // It uses a label to identify nodes that belong to the same "group" ServiceAffinity *ServiceAffinity `json:"serviceAffinity"` - // The predicate that checks whether a particular minion has a certain label + // The predicate that checks whether a particular node has a certain label // defined or not, regardless of value LabelsPresence *LabelsPresence `json:"labelsPresence"` } @@ -64,41 +62,41 @@ type PredicateArgument struct { // Only one of its members may be specified type PriorityArgument struct { // The priority function that ensures a good spread (anti-affinity) for pods belonging to a service - // It uses a label to identify minions that belong to the same "group" + // It uses a label to identify nodes that belong to the same "group" ServiceAntiAffinity *ServiceAntiAffinity `json:"serviceAntiAffinity"` - // The priority function that checks whether a particular minion has a certain label + // The priority function that checks whether a particular node has a certain label // defined or not, regardless of value LabelPreference *LabelPreference `json:"labelPreference"` } // Holds the parameters that are used to configure the corresponding predicate type ServiceAffinity struct { - // The list of labels that identify minion "groups" - // All of the labels should match for the minion to be considered a fit for hosting the pod + // The list of labels that identify node "groups" + // All of the labels should match for the node to be considered a fit for hosting the pod Labels []string `json:"labels"` } // Holds the parameters that are used to configure the corresponding predicate type LabelsPresence struct { - // The list of labels that identify minion "groups" - // All of the labels should be either present (or absent) for the minion to be considered a fit for hosting the pod + // The list of labels that identify node "groups" + // All of the labels should be either present (or absent) for the node to be considered a fit for hosting the pod Labels []string `json:"labels"` - // The boolean flag that indicates whether the labels should be present or absent from the minion + // The boolean flag that indicates whether the labels should be present or absent from the node Presence bool `json:"presence"` } // Holds the parameters that are used to configure the corresponding priority function type ServiceAntiAffinity struct { - // Used to identify minion "groups" + // Used to identify node "groups" Label string `json:"label"` } // Holds the parameters that are used to configure the corresponding priority function type LabelPreference struct { - // Used to identify minion "groups" + // Used to identify node "groups" Label string `json:"label"` // This is a boolean flag - // If true, higher priority is given to minions that have the label - // If false, higher priority is given to minions that do not have the label + // If true, higher priority is given to nodes that have the label + // If false, higher priority is given to nodes that do not have the label Presence bool `json:"presence"` } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go index 2ecc723e203c..be3bf184eaf5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go @@ -51,7 +51,7 @@ type ConfigFactory struct { ScheduledPodLister *cache.StoreToPodLister // a means to list all known scheduled pods and pods assumed to have been scheduled. PodLister algorithm.PodLister - // a means to list all minions + // a means to list all nodes NodeLister *cache.StoreToNodeLister // a means to list all services ServiceLister *cache.StoreToServiceLister @@ -123,7 +123,7 @@ func (f *ConfigFactory) Create() (*scheduler.Config, error) { // Creates a scheduler from the name of a registered algorithm provider. func (f *ConfigFactory) CreateFromProvider(providerName string) (*scheduler.Config, error) { - glog.V(2).Infof("creating scheduler from algorithm provider '%v'", providerName) + glog.V(2).Infof("Creating scheduler from algorithm provider '%v'", providerName) provider, err := GetAlgorithmProvider(providerName) if err != nil { return nil, err @@ -134,7 +134,7 @@ func (f *ConfigFactory) CreateFromProvider(providerName string) (*scheduler.Conf // Creates a scheduler from the configuration file func (f *ConfigFactory) CreateFromConfig(policy schedulerapi.Policy) (*scheduler.Config, error) { - glog.V(2).Infof("creating scheduler from configuration: %v", policy) + glog.V(2).Infof("Creating scheduler from configuration: %v", policy) // validate the policy configuration if err := validation.ValidatePolicy(policy); err != nil { @@ -183,9 +183,9 @@ func (f *ConfigFactory) CreateFromKeys(predicateKeys, priorityKeys sets.String) // Begin populating scheduled pods. go f.scheduledPodPopulator.Run(f.StopEverything) - // Watch minions. - // Minions may be listed frequently, so provide a local up-to-date cache. - cache.NewReflector(f.createMinionLW(), &api.Node{}, f.NodeLister.Store, 0).RunUntil(f.StopEverything) + // Watch nodes. + // Nodes may be listed frequently, so provide a local up-to-date cache. + cache.NewReflector(f.createNodeLW(), &api.Node{}, f.NodeLister.Store, 0).RunUntil(f.StopEverything) // Watch and cache all service objects. Scheduler needs to find all pods // created by the same services or ReplicationControllers, so that it can spread them correctly. @@ -212,9 +212,9 @@ func (f *ConfigFactory) CreateFromKeys(predicateKeys, priorityKeys sets.String) return &scheduler.Config{ Modeler: f.modeler, // The scheduler only needs to consider schedulable nodes. - MinionLister: f.NodeLister.NodeCondition(api.NodeReady, api.ConditionTrue), - Algorithm: algo, - Binder: &binder{f.Client}, + NodeLister: f.NodeLister.NodeCondition(api.NodeReady, api.ConditionTrue), + Algorithm: algo, + Binder: &binder{f.Client}, NextPod: func() *api.Pod { pod := f.PodQueue.Pop().(*api.Pod) glog.V(2).Infof("About to try and schedule pod %v", pod.Name) @@ -248,8 +248,8 @@ func (factory *ConfigFactory) createAssignedPodLW() *cache.ListWatch { parseSelectorOrDie(client.PodHost+"!=")) } -// createMinionLW returns a cache.ListWatch that gets all changes to minions. -func (factory *ConfigFactory) createMinionLW() *cache.ListWatch { +// createNodeLW returns a cache.ListWatch that gets all changes to nodes. +func (factory *ConfigFactory) createNodeLW() *cache.ListWatch { // TODO: Filter out nodes that doesn't have NodeReady condition. fields := fields.Set{client.NodeUnschedulable: "false"}.AsSelector() return cache.NewListWatchFromClient(factory.Client, "nodes", api.NamespaceAll, fields) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory_test.go index 86a420f03ed2..7a54f7a69f93 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory_test.go @@ -24,8 +24,8 @@ import ( "time" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/testapi" + apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/runtime" @@ -124,27 +124,22 @@ func PredicateTwo(pod *api.Pod, existingPods []*api.Pod, node string) (bool, err return true, nil } -func PriorityOne(pod *api.Pod, podLister algorithm.PodLister, minionLister algorithm.MinionLister) (algorithm.HostPriorityList, error) { +func PriorityOne(pod *api.Pod, podLister algorithm.PodLister, nodeLister algorithm.NodeLister) (algorithm.HostPriorityList, error) { return []algorithm.HostPriority{}, nil } -func PriorityTwo(pod *api.Pod, podLister algorithm.PodLister, minionLister algorithm.MinionLister) (algorithm.HostPriorityList, error) { +func PriorityTwo(pod *api.Pod, podLister algorithm.PodLister, nodeLister algorithm.NodeLister) (algorithm.HostPriorityList, error) { return []algorithm.HostPriority{}, nil } func TestDefaultErrorFunc(t *testing.T) { - grace := int64(30) testPod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "bar"}, - Spec: api.PodSpec{ - RestartPolicy: api.RestartPolicyAlways, - DNSPolicy: api.DNSClusterFirst, - TerminationGracePeriodSeconds: &grace, - }, + Spec: apitesting.DeepEqualSafePodSpec(), } handler := util.FakeHandler{ StatusCode: 200, - ResponseBody: runtime.EncodeOrDie(latest.Codec, testPod), + ResponseBody: runtime.EncodeOrDie(testapi.Default.Codec(), testPod), T: t, } mux := http.NewServeMux() @@ -181,7 +176,7 @@ func TestDefaultErrorFunc(t *testing.T) { } } -func TestMinionEnumerator(t *testing.T) { +func TestNodeEnumerator(t *testing.T) { testList := &api.NodeList{ Items: []api.Node{ {ObjectMeta: api.ObjectMeta{Name: "foo"}}, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/plugins.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/plugins.go index 6251c86098c0..a2df0fa3f59b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/plugins.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/factory/plugins.go @@ -36,7 +36,7 @@ type PluginFactoryArgs struct { algorithm.PodLister algorithm.ServiceLister algorithm.ControllerLister - NodeLister algorithm.MinionLister + NodeLister algorithm.NodeLister NodeInfo predicates.NodeInfo } @@ -271,7 +271,7 @@ var validName = regexp.MustCompile("^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])$") func validateAlgorithmNameOrDie(name string) { if !validName.MatchString(name) { - glog.Fatalf("algorithm name %v does not match the name validation regexp \"%v\".", name, validName) + glog.Fatalf("Algorithm name %v does not match the name validation regexp \"%v\".", name, validName) } } @@ -285,7 +285,7 @@ func validatePredicateOrDie(predicate schedulerapi.PredicatePolicy) { numArgs++ } if numArgs != 1 { - glog.Fatalf("Exactly 1 predicate argument is required") + glog.Fatalf("Exactly 1 predicate argument is required, numArgs: %v", numArgs) } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/generic_scheduler.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/generic_scheduler.go index e0e7b06a15c1..649d89484a9f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/generic_scheduler.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/generic_scheduler.go @@ -44,7 +44,7 @@ func (f *FitError) Error() string { var reason string // We iterate over all nodes for logging purposes, even though we only return one reason from one node for node, predicateList := range f.FailedPredicates { - glog.Infof("failed to find fit for pod %v on node %s: %s", f.Pod.Name, node, strings.Join(predicateList.List(), ",")) + glog.Infof("Failed to find fit for pod %v on node %s: %s", f.Pod.Name, node, strings.Join(predicateList.List(), ",")) if len(reason) == 0 { reason, _ = predicateList.PopAny() } @@ -60,21 +60,21 @@ type genericScheduler struct { randomLock sync.Mutex } -func (g *genericScheduler) Schedule(pod *api.Pod, minionLister algorithm.MinionLister) (string, error) { - minions, err := minionLister.List() +func (g *genericScheduler) Schedule(pod *api.Pod, nodeLister algorithm.NodeLister) (string, error) { + nodes, err := nodeLister.List() if err != nil { return "", err } - if len(minions.Items) == 0 { + if len(nodes.Items) == 0 { return "", ErrNoNodesAvailable } - filteredNodes, failedPredicateMap, err := findNodesThatFit(pod, g.pods, g.predicates, minions) + filteredNodes, failedPredicateMap, err := findNodesThatFit(pod, g.pods, g.predicates, nodes) if err != nil { return "", err } - priorityList, err := PrioritizeNodes(pod, g.pods, g.prioritizers, algorithm.FakeMinionLister(filteredNodes)) + priorityList, err := PrioritizeNodes(pod, g.pods, g.prioritizers, algorithm.FakeNodeLister(filteredNodes)) if err != nil { return "", err } @@ -88,8 +88,8 @@ func (g *genericScheduler) Schedule(pod *api.Pod, minionLister algorithm.MinionL return g.selectHost(priorityList) } -// This method takes a prioritized list of minions and sorts them in reverse order based on scores -// and then picks one randomly from the minions that had the highest score +// This method takes a prioritized list of nodes and sorts them in reverse order based on scores +// and then picks one randomly from the nodes that had the highest score func (g *genericScheduler) selectHost(priorityList algorithm.HostPriorityList) (string, error) { if len(priorityList) == 0 { return "", fmt.Errorf("empty priorityList") @@ -104,8 +104,8 @@ func (g *genericScheduler) selectHost(priorityList algorithm.HostPriorityList) ( return hosts[ix], nil } -// Filters the minions to find the ones that fit based on the given predicate functions -// Each minion is passed through the predicate functions to determine if it is a fit +// Filters the nodes to find the ones that fit based on the given predicate functions +// Each node is passed through the predicate functions to determine if it is a fit func findNodesThatFit(pod *api.Pod, podLister algorithm.PodLister, predicateFuncs map[string]algorithm.FitPredicate, nodes api.NodeList) (api.NodeList, FailedPredicateMap, error) { filtered := []api.Node{} machineToPods, err := predicates.MapPodsToMachines(podLister) @@ -141,19 +141,19 @@ func findNodesThatFit(pod *api.Pod, podLister algorithm.PodLister, predicateFunc return api.NodeList{Items: filtered}, failedPredicateMap, nil } -// Prioritizes the minions by running the individual priority functions sequentially. +// Prioritizes the nodes by running the individual priority functions sequentially. // Each priority function is expected to set a score of 0-10 -// 0 is the lowest priority score (least preferred minion) and 10 is the highest +// 0 is the lowest priority score (least preferred node) and 10 is the highest // Each priority function can also have its own weight -// The minion scores returned by the priority function are multiplied by the weights to get weighted scores -// All scores are finally combined (added) to get the total weighted scores of all minions -func PrioritizeNodes(pod *api.Pod, podLister algorithm.PodLister, priorityConfigs []algorithm.PriorityConfig, minionLister algorithm.MinionLister) (algorithm.HostPriorityList, error) { +// The node scores returned by the priority function are multiplied by the weights to get weighted scores +// All scores are finally combined (added) to get the total weighted scores of all nodes +func PrioritizeNodes(pod *api.Pod, podLister algorithm.PodLister, priorityConfigs []algorithm.PriorityConfig, nodeLister algorithm.NodeLister) (algorithm.HostPriorityList, error) { result := algorithm.HostPriorityList{} // If no priority configs are provided, then the EqualPriority function is applied // This is required to generate the priority list in the required format if len(priorityConfigs) == 0 { - return EqualPriority(pod, podLister, minionLister) + return EqualPriority(pod, podLister, nodeLister) } combinedScores := map[string]int{} @@ -164,7 +164,7 @@ func PrioritizeNodes(pod *api.Pod, podLister algorithm.PodLister, priorityConfig continue } priorityFunc := priorityConfig.Function - prioritizedList, err := priorityFunc(pod, podLister, minionLister) + prioritizedList, err := priorityFunc(pod, podLister, nodeLister) if err != nil { return algorithm.HostPriorityList{}, err } @@ -192,17 +192,17 @@ func getBestHosts(list algorithm.HostPriorityList) []string { } // EqualPriority is a prioritizer function that gives an equal weight of one to all nodes -func EqualPriority(_ *api.Pod, podLister algorithm.PodLister, minionLister algorithm.MinionLister) (algorithm.HostPriorityList, error) { - nodes, err := minionLister.List() +func EqualPriority(_ *api.Pod, podLister algorithm.PodLister, nodeLister algorithm.NodeLister) (algorithm.HostPriorityList, error) { + nodes, err := nodeLister.List() if err != nil { - glog.Errorf("failed to list nodes: %v", err) + glog.Errorf("Failed to list nodes: %v", err) return []algorithm.HostPriority{}, err } result := []algorithm.HostPriority{} - for _, minion := range nodes.Items { + for _, node := range nodes.Items { result = append(result, algorithm.HostPriority{ - Host: minion.Name, + Host: node.Name, Score: 1, }) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/generic_scheduler_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/generic_scheduler_test.go index 4f1a1b416c48..ee70a7a4fb2d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/generic_scheduler_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/generic_scheduler_test.go @@ -44,31 +44,31 @@ func hasNoPodsPredicate(pod *api.Pod, existingPods []*api.Pod, node string) (boo return len(existingPods) == 0, nil } -func numericPriority(pod *api.Pod, podLister algorithm.PodLister, minionLister algorithm.MinionLister) (algorithm.HostPriorityList, error) { - nodes, err := minionLister.List() +func numericPriority(pod *api.Pod, podLister algorithm.PodLister, nodeLister algorithm.NodeLister) (algorithm.HostPriorityList, error) { + nodes, err := nodeLister.List() result := []algorithm.HostPriority{} if err != nil { return nil, fmt.Errorf("failed to list nodes: %v", err) } - for _, minion := range nodes.Items { - score, err := strconv.Atoi(minion.Name) + for _, node := range nodes.Items { + score, err := strconv.Atoi(node.Name) if err != nil { return nil, err } result = append(result, algorithm.HostPriority{ - Host: minion.Name, + Host: node.Name, Score: score, }) } return result, nil } -func reverseNumericPriority(pod *api.Pod, podLister algorithm.PodLister, minionLister algorithm.MinionLister) (algorithm.HostPriorityList, error) { +func reverseNumericPriority(pod *api.Pod, podLister algorithm.PodLister, nodeLister algorithm.NodeLister) (algorithm.HostPriorityList, error) { var maxScore float64 minScore := math.MaxFloat64 reverseResult := []algorithm.HostPriority{} - result, err := numericPriority(pod, podLister, minionLister) + result, err := numericPriority(pod, podLister, nodeLister) if err != nil { return nil, err } @@ -288,7 +288,7 @@ func TestGenericScheduler(t *testing.T) { for _, test := range tests { random := rand.New(rand.NewSource(0)) scheduler := NewGenericScheduler(test.predicates, test.prioritizers, algorithm.FakePodLister(test.pods), random) - machine, err := scheduler.Schedule(test.pod, algorithm.FakeMinionLister(makeNodeList(test.nodes))) + machine, err := scheduler.Schedule(test.pod, algorithm.FakeNodeLister(makeNodeList(test.nodes))) if test.expectsErr { if err == nil { t.Error("Unexpected non-error") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler.go index 26d6be414df7..189909e12388 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler.go @@ -56,25 +56,25 @@ type SystemModeler interface { ForgetPodByKey(key string) // For serializing calls to Assume/ForgetPod: imagine you want to add - // a pod iff a bind succeeds, but also remove a pod if it is deleted. + // a pod if and only if a bind succeeds, but also remove a pod if it is deleted. // TODO: if SystemModeler begins modeling things other than pods, this // should probably be parameterized or specialized for pods. LockedAction(f func()) } // Scheduler watches for new unscheduled pods. It attempts to find -// minions that they fit on and writes bindings back to the api server. +// nodes that they fit on and writes bindings back to the api server. type Scheduler struct { config *Config } type Config struct { // It is expected that changes made via modeler will be observed - // by MinionLister and Algorithm. - Modeler SystemModeler - MinionLister algorithm.MinionLister - Algorithm algorithm.ScheduleAlgorithm - Binder Binder + // by NodeLister and Algorithm. + Modeler SystemModeler + NodeLister algorithm.NodeLister + Algorithm algorithm.ScheduleAlgorithm + Binder Binder // Rate at which we can create pods BindPodsRateLimiter util.RateLimiter @@ -121,7 +121,7 @@ func (s *Scheduler) scheduleOne() { defer func() { metrics.E2eSchedulingLatency.Observe(metrics.SinceInMicroseconds(start)) }() - dest, err := s.config.Algorithm.Schedule(pod, s.config.MinionLister) + dest, err := s.config.Algorithm.Schedule(pod, s.config.NodeLister) metrics.SchedulingAlgorithmLatency.Observe(metrics.SinceInMicroseconds(start)) if err != nil { glog.V(1).Infof("Failed to schedule: %+v", pod) @@ -137,8 +137,8 @@ func (s *Scheduler) scheduleOne() { }, } - // We want to add the pod to the model iff the bind succeeds, but we don't want to race - // with any deletions, which happen asynchronously. + // We want to add the pod to the model if and only if the bind succeeds, + // but we don't want to race with any deletions, which happen asynchronously. s.config.Modeler.LockedAction(func() { bindingStart := time.Now() err := s.config.Binder.Bind(b) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler_test.go index dbac64faa9fc..6449e6b46656 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler_test.go @@ -60,7 +60,7 @@ type mockScheduler struct { err error } -func (es mockScheduler) Schedule(pod *api.Pod, ml algorithm.MinionLister) (string, error) { +func (es mockScheduler) Schedule(pod *api.Pod, ml algorithm.NodeLister) (string, error) { return es.machine, es.err } @@ -114,7 +114,7 @@ func TestScheduler(t *testing.T) { gotAssumedPod = pod }, }, - MinionLister: algorithm.FakeMinionLister( + NodeLister: algorithm.FakeNodeLister( api.NodeList{Items: []api.Node{{ObjectMeta: api.ObjectMeta{Name: "machine1"}}}}, ), Algorithm: item.algo, @@ -188,7 +188,7 @@ func TestSchedulerForgetAssumedPodAfterDelete(t *testing.T) { // Create the scheduler config algo := NewGenericScheduler( - map[string]algorithm.FitPredicate{"PodFitsPorts": predicates.PodFitsPorts}, + map[string]algorithm.FitPredicate{"PodFitsHostPorts": predicates.PodFitsHostPorts}, []algorithm.PriorityConfig{}, modeler.PodLister(), rand.New(rand.NewSource(time.Now().UnixNano()))) @@ -196,7 +196,7 @@ func TestSchedulerForgetAssumedPodAfterDelete(t *testing.T) { var gotBinding *api.Binding c := &Config{ Modeler: modeler, - MinionLister: algorithm.FakeMinionLister( + NodeLister: algorithm.FakeNodeLister( api.NodeList{Items: []api.Node{{ObjectMeta: api.ObjectMeta{Name: "machine1"}}}}, ), Algorithm: algo, @@ -329,7 +329,7 @@ func TestSchedulerRateLimitsBinding(t *testing.T) { fr := FakeRateLimiter{util.NewTokenBucketRateLimiter(0.02, 1), []bool{}} c := &Config{ Modeler: modeler, - MinionLister: algorithm.FakeMinionLister( + NodeLister: algorithm.FakeNodeLister( api.NodeList{Items: []api.Node{{ObjectMeta: api.ObjectMeta{Name: "machine1"}}}}, ), Algorithm: algo, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/autoscaling.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/autoscaling.go index 9cdd5c1625fb..ba8fc94ba0ad 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/autoscaling.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/autoscaling.go @@ -24,12 +24,16 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/util" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) +const ( + scaleUpTimeout = 20 * time.Minute + scaleDownTimeout = 30 * time.Minute +) + var _ = Describe("Autoscaling", func() { f := NewFramework("autoscaling") var nodeCount int @@ -54,45 +58,47 @@ var _ = Describe("Autoscaling", func() { }) It("[Skipped][Autoscaling Suite] should scale cluster size based on cpu utilization", func() { - setUpAutoscaler("cpu/node_utilization", 0.7, nodeCount, nodeCount+1) + setUpAutoscaler("cpu/node_utilization", 0.4, nodeCount, nodeCount+1) - ConsumeCpu(f, "cpu-utilization", nodeCount*coresPerNode) - expectNoError(waitForClusterSize(f.Client, nodeCount+1, 20*time.Minute)) + // Consume 50% CPU + millicoresPerReplica := 500 + rc := NewStaticResourceConsumer("cpu-utilization", nodeCount*coresPerNode, millicoresPerReplica*nodeCount*coresPerNode, 0, int64(millicoresPerReplica), 100, f) + expectNoError(waitForClusterSize(f.Client, nodeCount+1, scaleUpTimeout)) - StopConsuming(f, "cpu-utilization") - expectNoError(waitForClusterSize(f.Client, nodeCount, 20*time.Minute)) + rc.CleanUp() + expectNoError(waitForClusterSize(f.Client, nodeCount, scaleDownTimeout)) }) - It("[Skipped] should scale cluster size based on cpu reservation", func() { - setUpAutoscaler("cpu/node_reservation", 0.7, 1, 10) + It("[Skipped][Autoscaling Suite] should scale cluster size based on cpu reservation", func() { + setUpAutoscaler("cpu/node_reservation", 0.5, nodeCount, nodeCount+1) - ReserveCpu(f, "cpu-reservation", 800) - expectNoError(waitForClusterSize(f.Client, 2, 20*time.Minute)) + ReserveCpu(f, "cpu-reservation", 600*nodeCount*coresPerNode) + expectNoError(waitForClusterSize(f.Client, nodeCount+1, scaleUpTimeout)) - StopConsuming(f, "cpu-reservation") - expectNoError(waitForClusterSize(f.Client, 1, 20*time.Minute)) + expectNoError(DeleteRC(f.Client, f.Namespace.Name, "cpu-reservation")) + expectNoError(waitForClusterSize(f.Client, nodeCount, scaleDownTimeout)) }) It("[Skipped][Autoscaling Suite] should scale cluster size based on memory utilization", func() { - setUpAutoscaler("memory/node_utilization", 0.5, nodeCount, nodeCount+1) + setUpAutoscaler("memory/node_utilization", 0.6, nodeCount, nodeCount+1) - // Consume 60% of total memory capacity in 256MB chunks. - chunks := memCapacityMb * nodeCount * 6 / 10 / 256 - ConsumeMemory(f, "memory-utilization", chunks) - expectNoError(waitForClusterSize(f.Client, nodeCount+1, 20*time.Minute)) + // Consume 60% of total memory capacity + megabytesPerReplica := int(memCapacityMb * 6 / 10 / coresPerNode) + rc := NewStaticResourceConsumer("mem-utilization", nodeCount*coresPerNode, 0, megabytesPerReplica*nodeCount*coresPerNode, 100, int64(megabytesPerReplica+100), f) + expectNoError(waitForClusterSize(f.Client, nodeCount+1, scaleUpTimeout)) - StopConsuming(f, "memory-utilization") - expectNoError(waitForClusterSize(f.Client, nodeCount, 20*time.Minute)) + rc.CleanUp() + expectNoError(waitForClusterSize(f.Client, nodeCount, scaleDownTimeout)) }) - It("[Skipped] should scale cluster size based on memory reservation", func() { - setUpAutoscaler("memory/node_reservation", 0.5, 1, 10) + It("[Skipped][Autoscaling Suite] should scale cluster size based on memory reservation", func() { + setUpAutoscaler("memory/node_reservation", 0.5, nodeCount, nodeCount+1) - ReserveMemory(f, "memory-reservation", 2) - expectNoError(waitForClusterSize(f.Client, 2, 20*time.Minute)) + ReserveMemory(f, "memory-reservation", nodeCount*memCapacityMb*6/10) + expectNoError(waitForClusterSize(f.Client, nodeCount+1, scaleUpTimeout)) - StopConsuming(f, "memory-reservation") - expectNoError(waitForClusterSize(f.Client, 1, 20*time.Minute)) + expectNoError(DeleteRC(f.Client, f.Namespace.Name, "memory-reservation")) + expectNoError(waitForClusterSize(f.Client, nodeCount, scaleDownTimeout)) }) }) @@ -120,91 +126,30 @@ func cleanUpAutoscaler() { expectNoError(err, "Output: "+string(out)) } -func CreateService(f *Framework, name string) { - By("Running sevice" + name) - service := &api.Service{ - ObjectMeta: api.ObjectMeta{ - Name: name, - }, - Spec: api.ServiceSpec{ - Selector: map[string]string{ - "name": name, - }, - Ports: []api.ServicePort{{ - Port: 8080, - TargetPort: util.NewIntOrStringFromInt(8080), - }}, - }, - } - _, err := f.Client.Services(f.Namespace.Name).Create(service) - Expect(err).NotTo(HaveOccurred()) -} - -func ConsumeCpu(f *Framework, id string, cores int) { - CreateService(f, id) - By(fmt.Sprintf("Running RC which consumes %v cores", cores)) +func ReserveCpu(f *Framework, id string, millicores int) { + By(fmt.Sprintf("Running RC which reserves %v millicores", millicores)) config := &RCConfig{ Client: f.Client, Name: id, Namespace: f.Namespace.Name, Timeout: 10 * time.Minute, - Image: "jess/stress", - Command: []string{"stress", "-c", "1"}, - Replicas: cores, - CpuRequest: 500, - CpuLimit: 1000, + Image: "beta.gcr.io/google_containers/pause:2.0", + Replicas: millicores / 100, + CpuRequest: 100, } expectNoError(RunRC(*config)) } -// Consume chunks of size 256MB. -func ConsumeMemory(f *Framework, id string, chunks int) { - CreateService(f, id) - By(fmt.Sprintf("Running RC which consumes %v MB of memory in 256MB chunks", chunks*256)) +func ReserveMemory(f *Framework, id string, megabytes int) { + By(fmt.Sprintf("Running RC which reserves %v MB of memory", megabytes)) config := &RCConfig{ - Client: f.Client, - Name: id, - Namespace: f.Namespace.Name, - Timeout: 10 * time.Minute, - Image: "jess/stress", - Command: []string{"stress", "-m", "1", "--vm-hang", "0"}, - Replicas: chunks, - } - expectNoError(RunRC(*config)) -} - -func ReserveCpu(f *Framework, id string, millicores int) { - By(fmt.Sprintf("Running RC which reserves %v millicores", millicores)) - config := &RCConfig{ - Client: f.Client, - Name: id, - Namespace: f.Namespace.Name, - Timeout: 10 * time.Minute, - Image: "gcr.io/google_containers/pause", - Replicas: millicores / 100, - CpuLimit: 100, - } - expectNoError(RunRC(*config)) -} - -func ReserveMemory(f *Framework, id string, gigabytes int) { - By(fmt.Sprintf("Running RC which reserves %v GB of memory", gigabytes)) - config := &RCConfig{ - Client: f.Client, - Name: id, - Namespace: f.Namespace.Name, - Timeout: 10 * time.Minute, - Image: "gcr.io/google_containers/pause", - Replicas: 5 * gigabytes, - MemLimit: 200 * 1024 * 1024, + Client: f.Client, + Name: id, + Namespace: f.Namespace.Name, + Timeout: 10 * time.Minute, + Image: "beta.gcr.io/google_containers/pause:2.0", + Replicas: megabytes / 500, + MemRequest: 500 * 1024 * 1024, } expectNoError(RunRC(*config)) } - -func StopConsuming(f *Framework, id string) { - By("Stopping service " + id) - err := f.Client.Services(f.Namespace.Name).Delete(id) - Expect(err).NotTo(HaveOccurred()) - By("Stopping RC " + id) - expectNoError(DeleteRC(f.Client, f.Namespace.Name, id)) -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/autoscaling_utils.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/autoscaling_utils.go index 46a3c5fe9fa6..37665e9cc23b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/autoscaling_utils.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/autoscaling_utils.go @@ -17,6 +17,7 @@ limitations under the License. package e2e import ( + "fmt" "strconv" "time" @@ -28,14 +29,17 @@ import ( ) const ( - consumptionTimeInSeconds = 30 - sleepTime = 30 * time.Second - requestSizeInMillicores = 100 - port = 80 - targetPort = 8080 - timeoutRC = 120 * time.Second - image = "gcr.io/google_containers/resource_consumer:alpha" - rcIsNil = "ERROR: replicationController = nil" + dynamicConsumptionTimeInSeconds = 30 + staticConsumptionTimeInSeconds = 3600 + dynamicRequestSizeInMillicores = 100 + dynamicRequestSizeInMegabytes = 100 + port = 80 + targetPort = 8080 + timeoutRC = 120 * time.Second + startServiceTimeout = time.Minute + startServiceInterval = 5 * time.Second + resourceConsumerImage = "gcr.io/google_containers/resource_consumer:beta" + rcIsNil = "ERROR: replicationController = nil" ) /* @@ -47,62 +51,137 @@ rc.ConsumeCPU(300) // ... check your assumption here */ type ResourceConsumer struct { - name string - framework *Framework - channel chan int - stop chan int + name string + framework *Framework + cpu chan int + mem chan int + stopCPU chan int + stopMem chan int + consumptionTimeInSeconds int + sleepTime time.Duration + requestSizeInMillicores int + requestSizeInMegabytes int } -// NewResourceConsumer creates new ResourceConsumer -// cpu argument is in millicores -func NewResourceConsumer(name string, replicas int, cpu int, framework *Framework) *ResourceConsumer { - runServiceAndRCForResourceConsumer(framework.Client, framework.Namespace.Name, name, replicas) +func NewDynamicResourceConsumer(name string, replicas, initCPU, initMemory int, cpuLimit, memLimit int64, framework *Framework) *ResourceConsumer { + return newResourceConsumer(name, replicas, initCPU, initMemory, dynamicConsumptionTimeInSeconds, dynamicRequestSizeInMillicores, dynamicRequestSizeInMegabytes, cpuLimit, memLimit, framework) +} + +func NewStaticResourceConsumer(name string, replicas, initCPU, initMemory int, cpuLimit, memLimit int64, framework *Framework) *ResourceConsumer { + return newResourceConsumer(name, replicas, initCPU, initMemory, staticConsumptionTimeInSeconds, initCPU/replicas, initMemory/replicas, cpuLimit, memLimit, framework) +} + +/* +NewResourceConsumer creates new ResourceConsumer +initCPU argument is in millicores +initMemory argument is in megabytes +memLimit argument is in megabytes, memLimit is a maximum amount of memory that can be consumed by a single pod +cpuLimit argument is in millicores, cpuLimit is a maximum amount of cpu that can be consumed by a single pod +*/ +func newResourceConsumer(name string, replicas, initCPU, initMemory, consumptionTimeInSeconds, requestSizeInMillicores, requestSizeInMegabytes int, cpuLimit, memLimit int64, framework *Framework) *ResourceConsumer { + runServiceAndRCForResourceConsumer(framework.Client, framework.Namespace.Name, name, replicas, cpuLimit, memLimit) rc := &ResourceConsumer{ - name: name, - framework: framework, - channel: make(chan int), - stop: make(chan int), + name: name, + framework: framework, + cpu: make(chan int), + mem: make(chan int), + stopCPU: make(chan int), + stopMem: make(chan int), + consumptionTimeInSeconds: consumptionTimeInSeconds, + sleepTime: time.Duration(consumptionTimeInSeconds) * time.Second, + requestSizeInMillicores: requestSizeInMillicores, + requestSizeInMegabytes: requestSizeInMegabytes, } go rc.makeConsumeCPURequests() - rc.ConsumeCPU(cpu) + rc.ConsumeCPU(initCPU) + go rc.makeConsumeMemRequests() + rc.ConsumeMem(initMemory) return rc } // ConsumeCPU consumes given number of CPU func (rc *ResourceConsumer) ConsumeCPU(millicores int) { - rc.channel <- millicores + Logf("RC %s: consume %v millicores in total", rc.name, millicores) + rc.cpu <- millicores +} + +// ConsumeMem consumes given number of Mem +func (rc *ResourceConsumer) ConsumeMem(megabytes int) { + Logf("RC %s: consume %v MB in total", rc.name, megabytes) + rc.mem <- megabytes } func (rc *ResourceConsumer) makeConsumeCPURequests() { defer GinkgoRecover() var count int var rest int + sleepTime := time.Duration(0) + for { + select { + case millicores := <-rc.cpu: + Logf("RC %s: consume %v millicores in total", rc.name, millicores) + if rc.requestSizeInMillicores != 0 { + count = millicores / rc.requestSizeInMillicores + } + rest = millicores - count*rc.requestSizeInMillicores + case <-time.After(sleepTime): + Logf("RC %s: sending %v requests to consume %v millicores each and 1 request to consume %v millicores", rc.name, count, rc.requestSizeInMillicores, rest) + if count > 0 { + rc.sendConsumeCPURequests(count, rc.requestSizeInMillicores, rc.consumptionTimeInSeconds) + } + if rest > 0 { + go rc.sendOneConsumeCPURequest(rest, rc.consumptionTimeInSeconds) + } + sleepTime = rc.sleepTime + case <-rc.stopCPU: + return + } + } +} + +func (rc *ResourceConsumer) makeConsumeMemRequests() { + defer GinkgoRecover() + var count int + var rest int + sleepTime := time.Duration(0) for { select { - case millicores := <-rc.channel: - count = millicores / requestSizeInMillicores - rest = millicores - count*requestSizeInMillicores + case megabytes := <-rc.mem: + Logf("RC %s: consume %v MB in total", rc.name, megabytes) + if rc.requestSizeInMegabytes != 0 { + count = megabytes / rc.requestSizeInMegabytes + } + rest = megabytes - count*rc.requestSizeInMegabytes case <-time.After(sleepTime): + Logf("RC %s: sending %v requests to consume %v MB each and 1 request to consume %v MB", rc.name, count, rc.requestSizeInMegabytes, rest) if count > 0 { - rc.sendConsumeCPUrequests(count, requestSizeInMillicores, consumptionTimeInSeconds) + rc.sendConsumeMemRequests(count, rc.requestSizeInMegabytes, rc.consumptionTimeInSeconds) } if rest > 0 { - go rc.sendOneConsumeCPUrequest(rest, consumptionTimeInSeconds) + go rc.sendOneConsumeMemRequest(rest, rc.consumptionTimeInSeconds) } - case <-rc.stop: + sleepTime = rc.sleepTime + case <-rc.stopMem: return } } } -func (rc *ResourceConsumer) sendConsumeCPUrequests(requests, millicores, durationSec int) { +func (rc *ResourceConsumer) sendConsumeCPURequests(requests, millicores, durationSec int) { for i := 0; i < requests; i++ { - go rc.sendOneConsumeCPUrequest(millicores, durationSec) + go rc.sendOneConsumeCPURequest(millicores, durationSec) } } -// sendOneConsumeCPUrequest sends POST request for cpu consumption -func (rc *ResourceConsumer) sendOneConsumeCPUrequest(millicores int, durationSec int) { +func (rc *ResourceConsumer) sendConsumeMemRequests(requests, megabytes, durationSec int) { + for i := 0; i < requests; i++ { + go rc.sendOneConsumeMemRequest(megabytes, durationSec) + } +} + +// sendOneConsumeCPURequest sends POST request for cpu consumption +func (rc *ResourceConsumer) sendOneConsumeCPURequest(millicores int, durationSec int) { + defer GinkgoRecover() _, err := rc.framework.Client.Post(). Prefix("proxy"). Namespace(rc.framework.Namespace.Name). @@ -111,8 +190,22 @@ func (rc *ResourceConsumer) sendOneConsumeCPUrequest(millicores int, durationSec Suffix("ConsumeCPU"). Param("millicores", strconv.Itoa(millicores)). Param("durationSec", strconv.Itoa(durationSec)). - Do(). - Raw() + DoRaw() + expectNoError(err) +} + +// sendOneConsumeMemRequest sends POST request for memory consumption +func (rc *ResourceConsumer) sendOneConsumeMemRequest(megabytes int, durationSec int) { + defer GinkgoRecover() + _, err := rc.framework.Client.Post(). + Prefix("proxy"). + Namespace(rc.framework.Namespace.Name). + Resource("services"). + Name(rc.name). + Suffix("ConsumeMem"). + Param("megabytes", strconv.Itoa(megabytes)). + Param("durationSec", strconv.Itoa(durationSec)). + DoRaw() expectNoError(err) } @@ -139,13 +232,17 @@ func (rc *ResourceConsumer) WaitForReplicas(desiredReplicas int) { } func (rc *ResourceConsumer) CleanUp() { - rc.stop <- 0 + By(fmt.Sprintf("Removing consuming RC %s", rc.name)) + rc.stopCPU <- 0 + rc.stopMem <- 0 + // Wait some time to ensure all child goroutines are finished. + time.Sleep(10 * time.Second) expectNoError(DeleteRC(rc.framework.Client, rc.framework.Namespace.Name, rc.name)) expectNoError(rc.framework.Client.Services(rc.framework.Namespace.Name).Delete(rc.name)) - expectNoError(rc.framework.Client.Experimental().HorizontalPodAutoscalers(rc.framework.Namespace.Name).Delete(rc.name, api.NewDeleteOptions(0))) } -func runServiceAndRCForResourceConsumer(c *client.Client, ns, name string, replicas int) { +func runServiceAndRCForResourceConsumer(c *client.Client, ns, name string, replicas int, cpuLimitMillis, memLimitMb int64) { + By(fmt.Sprintf("Running consuming RC %s with %v replicas", name, replicas)) _, err := c.Services(ns).Create(&api.Service{ ObjectMeta: api.ObjectMeta{ Name: name, @@ -163,12 +260,19 @@ func runServiceAndRCForResourceConsumer(c *client.Client, ns, name string, repli }) expectNoError(err) config := RCConfig{ - Client: c, - Image: image, - Name: name, - Namespace: ns, - Timeout: timeoutRC, - Replicas: replicas, + Client: c, + Image: resourceConsumerImage, + Name: name, + Namespace: ns, + Timeout: timeoutRC, + Replicas: replicas, + CpuRequest: cpuLimitMillis, + CpuLimit: cpuLimitMillis, + MemRequest: memLimitMb * 1024 * 1024, // MemLimit is in bytes + MemLimit: memLimitMb * 1024 * 1024, } expectNoError(RunRC(config)) + // Make sure endpoints are propagated. + // TODO(piosz): replace sleep with endpoints watch. + time.Sleep(10 * time.Second) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/cluster_upgrade.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/cluster_upgrade.go index c559315154c4..a86c959b762b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/cluster_upgrade.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/cluster_upgrade.go @@ -461,7 +461,7 @@ func runCmd(command string, args ...string) (string, string, error) { func validate(f Framework, svcNameWant, rcNameWant string, ingress api.LoadBalancerIngress, podsWant int) error { Logf("Beginning cluster validation") // Verify RC. - rcs, err := f.Client.ReplicationControllers(f.Namespace.Name).List(labels.Everything()) + rcs, err := f.Client.ReplicationControllers(f.Namespace.Name).List(labels.Everything(), fields.Everything()) if err != nil { return fmt.Errorf("error listing RCs: %v", err) } @@ -522,8 +522,8 @@ func migTemplate() (string, error) { // An `instance-groups managed describe` call outputs what we want to stdout. output, _, err := retryCmd("gcloud", "compute", "instance-groups", "managed", fmt.Sprintf("--project=%s", testContext.CloudConfig.ProjectID), - fmt.Sprintf("--zone=%s", testContext.CloudConfig.Zone), "describe", + fmt.Sprintf("--zone=%s", testContext.CloudConfig.Zone), testContext.CloudConfig.NodeInstanceGroup) if err != nil { errLast = fmt.Errorf("gcloud compute instance-groups managed describe call failed with err: %v", err) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/container_probe.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/container_probe.go index 4a0ebc1061bf..0ceb3cd12e4b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/container_probe.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/container_probe.go @@ -40,7 +40,7 @@ var _ = Describe("Probing container", func() { AfterEach(framework.afterEach) - It("with readiness probe should not be ready before initial delay and never restart", func() { + It("with readiness probe should not be ready before initial delay and never restart [Conformance]", func() { p, err := podClient.Create(makePodSpec(probe.withInitialDelay().build(), nil)) expectNoError(err) startTime := time.Now() @@ -73,7 +73,7 @@ var _ = Describe("Probing container", func() { Expect(restartCount == 0).To(BeTrue(), "pod should have a restart count of 0 but got %v", restartCount) }) - It("with readiness probe that fails should never be ready and never restart", func() { + It("with readiness probe that fails should never be ready and never restart [Conformance]", func() { p, err := podClient.Create(makePodSpec(probe.withFailing().build(), nil)) expectNoError(err) @@ -118,6 +118,9 @@ func makePodSpec(readinessProbe, livenessProbe *api.Probe) *api.Pod { Image: "gcr.io/google_containers/test-webserver", LivenessProbe: livenessProbe, ReadinessProbe: readinessProbe, + }, { + Name: "test-noprobe", + Image: "beta.gcr.io/google_containers/pause:2.0", }, }, }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/core.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/core.go index 2d1c42b754e9..19f4c8573860 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/core.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/core.go @@ -38,7 +38,7 @@ func CoreDump(dir string) { provider := testContext.Provider // requires ssh - if !providerIs("gce", "gke") { + if !providerIs(providersWithSSH...) { fmt.Printf("Skipping SSH core dump, which is not implemented for %s", provider) return } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/daemon_restart.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/daemon_restart.go index 3067b52a8ae5..5e1a797a6951 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/daemon_restart.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/daemon_restart.go @@ -50,6 +50,9 @@ const ( restartTimeout = 10 * time.Minute numPods = 10 sshPort = 22 + ADD = "ADD" + DEL = "DEL" + UPDATE = "UPDATE" ) // nodeExec execs the given cmd on node via SSH. Note that the nodeName is an sshable name, @@ -126,6 +129,35 @@ func (r *restartDaemonConfig) restart() { r.waitUp() } +// podTracker records a serial history of events that might've affects pods. +type podTracker struct { + cache.ThreadSafeStore +} + +func (p *podTracker) remember(pod *api.Pod, eventType string) { + if eventType == UPDATE && pod.Status.Phase == api.PodRunning { + return + } + p.Add(fmt.Sprintf("[%v] %v: %v", time.Now(), eventType, pod.Name), pod) +} + +func (p *podTracker) String() (msg string) { + for _, k := range p.ListKeys() { + obj, exists := p.Get(k) + if !exists { + continue + } + pod := obj.(*api.Pod) + msg += fmt.Sprintf("%v Phase %v Host %v\n", k, pod.Status.Phase, pod.Spec.NodeName) + } + return +} + +func newPodTracker() *podTracker { + return &podTracker{cache.NewThreadSafeStore( + cache.Indexers{}, cache.Indices{})} +} + // replacePods replaces content of the store with the given pods. func replacePods(pods []*api.Pod, store cache.Store) { found := make([]interface{}, 0, len(pods)) @@ -162,6 +194,7 @@ var _ = Describe("DaemonRestart", func() { var controller *controllerFramework.Controller var newPods cache.Store var stopCh chan struct{} + var tracker *podTracker BeforeEach(func() { @@ -180,7 +213,7 @@ var _ = Describe("DaemonRestart", func() { Client: framework.Client, Name: rcName, Namespace: ns, - Image: "kubernetes/pause", + Image: "beta.gcr.io/google_containers/pause:2.0", Replicas: numPods, CreatedPods: &[]*api.Pod{}, } @@ -188,6 +221,7 @@ var _ = Describe("DaemonRestart", func() { replacePods(*config.CreatedPods, existingPods) stopCh = make(chan struct{}) + tracker = newPodTracker() newPods, controller = controllerFramework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { @@ -199,7 +233,17 @@ var _ = Describe("DaemonRestart", func() { }, &api.Pod{}, 0, - controllerFramework.ResourceEventHandlerFuncs{}, + controllerFramework.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + tracker.remember(obj.(*api.Pod), ADD) + }, + UpdateFunc: func(oldObj, newObj interface{}) { + tracker.remember(newObj.(*api.Pod), UPDATE) + }, + DeleteFunc: func(obj interface{}) { + tracker.remember(obj.(*api.Pod), DEL) + }, + }, ) go controller.Run(stopCh) }) @@ -235,12 +279,15 @@ var _ = Describe("DaemonRestart", func() { } if len(newKeys.List()) != len(existingKeys.List()) || !newKeys.IsSuperset(existingKeys) { - Failf("RcManager created/deleted pods after restart") + Failf("RcManager created/deleted pods after restart \n\n %+v", tracker) } }) It("Scheduler should continue assigning pods to nodes across restart", func() { + // TODO: Enabale this test in GKE once experimental API there is switched on + SkipIfProviderIs("gke") + restarter := NewRestartConfig( getMasterHost(), "kube-scheduler", ports.SchedulerPort, restartPollInterval, restartTimeout) @@ -256,7 +303,11 @@ var _ = Describe("DaemonRestart", func() { }) It("Kubelet should not restart containers across restart", func() { - nodeIPs, err := getMinionPublicIps(framework.Client) + + // TODO: Enabale this test in GKE once experimental API there is switched on + SkipIfProviderIs("gke") + + nodeIPs, err := getNodePublicIps(framework.Client) expectNoError(err) preRestarts, badNodes := getContainerRestarts(framework.Client, ns, labelSelector) if preRestarts != 0 { @@ -270,7 +321,7 @@ var _ = Describe("DaemonRestart", func() { postRestarts, badNodes := getContainerRestarts(framework.Client, ns, labelSelector) if postRestarts != preRestarts { dumpNodeDebugInfo(framework.Client, badNodes) - Failf("Net container restart count went from %v -> %v after kubelet restart on nodes %v", preRestarts, postRestarts, badNodes) + Failf("Net container restart count went from %v -> %v after kubelet restart on nodes %v \n\n %+v", preRestarts, postRestarts, badNodes, tracker) } }) }) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/daemon_set.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/daemon_set.go index 05f412768cec..78455f7c4266 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/daemon_set.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/daemon_set.go @@ -18,12 +18,17 @@ package e2e import ( "fmt" + "reflect" + "strings" "time" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/experimental" + apierrs "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/util/wait" @@ -31,46 +36,219 @@ import ( . "github.com/onsi/gomega" ) +const ( + // this should not be a multiple of 5, because node status updates + // every 5 seconds. See https://github.com/kubernetes/kubernetes/pull/14915. + dsRetryPeriod = 2 * time.Second + dsRetryTimeout = 1 * time.Minute + + daemonsetLabelPrefix = "daemonset-" + daemonsetNameLabel = daemonsetLabelPrefix + "name" + daemonsetColorLabel = daemonsetLabelPrefix + "color" +) + var _ = Describe("Daemon set", func() { f := &Framework{BaseName: "daemonsets"} + image := "gcr.io/google_containers/serve_hostname:1.1" + dsName := "daemon-set" + + var ns string + var c *client.Client + BeforeEach(func() { f.beforeEach() - err := clearNodeLabels(f.Client) + ns = f.Namespace.Name + c = f.Client + err := clearDaemonSetNodeLabels(c) Expect(err).NotTo(HaveOccurred()) }) AfterEach(func() { - err := clearNodeLabels(f.Client) + err := clearDaemonSetNodeLabels(f.Client) Expect(err).NotTo(HaveOccurred()) f.afterEach() }) - It("should launch a daemon pod on every node of the cluster", func() { - testDaemonSets(f) + It("should run and stop simple daemon", func() { + label := map[string]string{daemonsetNameLabel: dsName} + + Logf("Creating simple daemon set %s", dsName) + _, err := c.DaemonSets(ns).Create(&extensions.DaemonSet{ + ObjectMeta: api.ObjectMeta{ + Name: dsName, + }, + Spec: extensions.DaemonSetSpec{ + Template: &api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: label, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: dsName, + Image: image, + Ports: []api.ContainerPort{{ContainerPort: 9376}}, + }, + }, + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + defer func() { + Logf("Check that reaper kills all daemon pods for %s", dsName) + dsReaper, err := kubectl.ReaperFor("DaemonSet", c) + Expect(err).NotTo(HaveOccurred()) + _, err = dsReaper.Stop(ns, dsName, 0, nil) + Expect(err).NotTo(HaveOccurred()) + err = wait.Poll(dsRetryPeriod, dsRetryTimeout, checkRunningOnNoNodes(f, label)) + Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to be reaped") + }() + + By("Check that daemon pods launch on every node of the cluster.") + Expect(err).NotTo(HaveOccurred()) + err = wait.Poll(dsRetryPeriod, dsRetryTimeout, checkRunningOnAllNodes(f, label)) + Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to start") + + By("Stop a daemon pod, check that the daemon pod is revived.") + podClient := c.Pods(ns) + + podList, err := podClient.List(labels.Set(label).AsSelector(), fields.Everything()) + Expect(err).NotTo(HaveOccurred()) + Expect(len(podList.Items)).To(BeNumerically(">", 0)) + pod := podList.Items[0] + err = podClient.Delete(pod.Name, nil) + Expect(err).NotTo(HaveOccurred()) + err = wait.Poll(dsRetryPeriod, dsRetryTimeout, checkRunningOnAllNodes(f, label)) + Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to revive") + + }) + + It("should run and stop complex daemon", func() { + complexLabel := map[string]string{daemonsetNameLabel: dsName} + nodeSelector := map[string]string{daemonsetColorLabel: "blue"} + Logf("Creating daemon with a node selector %s", dsName) + _, err := c.DaemonSets(ns).Create(&extensions.DaemonSet{ + ObjectMeta: api.ObjectMeta{ + Name: dsName, + }, + Spec: extensions.DaemonSetSpec{ + Selector: complexLabel, + Template: &api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: complexLabel, + }, + Spec: api.PodSpec{ + NodeSelector: nodeSelector, + Containers: []api.Container{ + { + Name: dsName, + Image: image, + Ports: []api.ContainerPort{{ContainerPort: 9376}}, + }, + }, + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + + By("Initially, daemon pods should not be running on any nodes.") + err = wait.Poll(dsRetryPeriod, dsRetryTimeout, checkRunningOnNoNodes(f, complexLabel)) + Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pods to be running on no nodes") + + By("Change label of node, check that daemon pod is launched.") + nodeClient := c.Nodes() + nodeList, err := nodeClient.List(labels.Everything(), fields.Everything()) + Expect(len(nodeList.Items)).To(BeNumerically(">", 0)) + newNode, err := setDaemonSetNodeLabels(c, nodeList.Items[0].Name, nodeSelector) + Expect(err).NotTo(HaveOccurred(), "error setting labels on node") + daemonSetLabels, _ := separateDaemonSetNodeLabels(newNode.Labels) + Expect(len(daemonSetLabels)).To(Equal(1)) + err = wait.Poll(dsRetryPeriod, dsRetryTimeout, checkDaemonPodOnNodes(f, complexLabel, []string{newNode.Name})) + Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pods to be running on new nodes") + + By("remove the node selector and wait for daemons to be unscheduled") + _, err = setDaemonSetNodeLabels(c, nodeList.Items[0].Name, map[string]string{}) + Expect(err).NotTo(HaveOccurred(), "error removing labels on node") + Expect(wait.Poll(dsRetryPeriod, dsRetryTimeout, checkRunningOnNoNodes(f, complexLabel))). + NotTo(HaveOccurred(), "error waiting for daemon pod to not be running on nodes") + + By("We should now be able to delete the daemon set.") + Expect(c.DaemonSets(ns).Delete(dsName)).NotTo(HaveOccurred()) + }) }) -func clearNodeLabels(c *client.Client) error { +func separateDaemonSetNodeLabels(labels map[string]string) (map[string]string, map[string]string) { + daemonSetLabels := map[string]string{} + otherLabels := map[string]string{} + for k, v := range labels { + if strings.HasPrefix(k, daemonsetLabelPrefix) { + daemonSetLabels[k] = v + } else { + otherLabels[k] = v + } + } + return daemonSetLabels, otherLabels +} + +func clearDaemonSetNodeLabels(c *client.Client) error { nodeClient := c.Nodes() nodeList, err := nodeClient.List(labels.Everything(), fields.Everything()) if err != nil { return err } for _, node := range nodeList.Items { - if len(node.Labels) != 0 { - node.Labels = map[string]string{} - newNode, err := nodeClient.Update(&node) - if err != nil { - return err - } else if len(newNode.Labels) != 0 { - return fmt.Errorf("Could not make node labels nil.") - } + _, err := setDaemonSetNodeLabels(c, node.Name, map[string]string{}) + if err != nil { + return err } } return nil } +func setDaemonSetNodeLabels(c *client.Client, nodeName string, labels map[string]string) (*api.Node, error) { + nodeClient := c.Nodes() + var newNode *api.Node + var newLabels map[string]string + err := wait.Poll(dsRetryPeriod, dsRetryTimeout, func() (bool, error) { + node, err := nodeClient.Get(nodeName) + if err != nil { + return false, err + } + + // remove all labels this test is creating + daemonSetLabels, otherLabels := separateDaemonSetNodeLabels(node.Labels) + if reflect.DeepEqual(daemonSetLabels, labels) { + newNode = node + return true, nil + } + node.Labels = otherLabels + for k, v := range labels { + node.Labels[k] = v + } + newNode, err = nodeClient.Update(node) + if err == nil { + newLabels, _ = separateDaemonSetNodeLabels(newNode.Labels) + return true, err + } + if se, ok := err.(*apierrs.StatusError); ok && se.ErrStatus.Reason == unversioned.StatusReasonConflict { + Logf("failed to update node due to resource version conflict") + return false, nil + } + return false, err + }) + if err != nil { + return nil, err + } else if len(newLabels) != len(labels) { + return nil, fmt.Errorf("Could not set daemon set test labels as expected.") + } + + return newNode, nil +} + func checkDaemonPodOnNodes(f *Framework, selector map[string]string, nodeNames []string) func() (bool, error) { return func() (bool, error) { podList, err := f.Client.Pods(f.Namespace.Name).List(labels.Set(selector).AsSelector(), fields.Everything()) @@ -83,6 +261,7 @@ func checkDaemonPodOnNodes(f *Framework, selector map[string]string, nodeNames [ for _, pod := range pods { nodesToPodCount[pod.Spec.NodeName] += 1 } + Logf("nodesToPodCount: %#v", nodesToPodCount) // Ensure that exactly 1 pod is running on all nodes in nodeNames. for _, nodeName := range nodeNames { @@ -115,107 +294,3 @@ func checkRunningOnAllNodes(f *Framework, selector map[string]string) func() (bo func checkRunningOnNoNodes(f *Framework, selector map[string]string) func() (bool, error) { return checkDaemonPodOnNodes(f, selector, make([]string, 0)) } - -func testDaemonSets(f *Framework) { - ns := f.Namespace.Name - c := f.Client - simpleDSName := "simple-daemon-set" - image := "gcr.io/google_containers/serve_hostname:1.1" - label := map[string]string{"name": simpleDSName} - retryTimeout := 1 * time.Minute - retryInterval := 5 * time.Second - - Logf("Creating simple daemon set %s", simpleDSName) - _, err := c.DaemonSets(ns).Create(&experimental.DaemonSet{ - ObjectMeta: api.ObjectMeta{ - Name: simpleDSName, - }, - Spec: experimental.DaemonSetSpec{ - Template: &api.PodTemplateSpec{ - ObjectMeta: api.ObjectMeta{ - Labels: label, - }, - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: simpleDSName, - Image: image, - Ports: []api.ContainerPort{{ContainerPort: 9376}}, - }, - }, - }, - }, - }, - }) - Expect(err).NotTo(HaveOccurred()) - - By("Check that daemon pods launch on every node of the cluster.") - Expect(err).NotTo(HaveOccurred()) - err = wait.Poll(retryInterval, retryTimeout, checkRunningOnAllNodes(f, label)) - Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to start") - - By("Stop a daemon pod, check that the daemon pod is revived.") - podClient := c.Pods(ns) - - podList, err := podClient.List(labels.Set(label).AsSelector(), fields.Everything()) - Expect(err).NotTo(HaveOccurred()) - Expect(len(podList.Items)).To(BeNumerically(">", 0)) - pod := podList.Items[0] - err = podClient.Delete(pod.Name, nil) - Expect(err).NotTo(HaveOccurred()) - err = wait.Poll(retryInterval, retryTimeout, checkRunningOnAllNodes(f, label)) - Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to revive") - - complexDSName := "complex-daemon-set" - complexLabel := map[string]string{"name": complexDSName} - nodeSelector := map[string]string{"color": "blue"} - Logf("Creating daemon with a node selector %s", complexDSName) - _, err = c.DaemonSets(ns).Create(&experimental.DaemonSet{ - ObjectMeta: api.ObjectMeta{ - Name: complexDSName, - }, - Spec: experimental.DaemonSetSpec{ - Selector: complexLabel, - Template: &api.PodTemplateSpec{ - ObjectMeta: api.ObjectMeta{ - Labels: complexLabel, - }, - Spec: api.PodSpec{ - NodeSelector: nodeSelector, - Containers: []api.Container{ - { - Name: complexDSName, - Image: image, - Ports: []api.ContainerPort{{ContainerPort: 9376}}, - }, - }, - }, - }, - }, - }) - Expect(err).NotTo(HaveOccurred()) - - By("Initially, daemon pods should not be running on any nodes.") - err = wait.Poll(retryInterval, retryTimeout, checkRunningOnNoNodes(f, complexLabel)) - Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pods to be running on no nodes") - - By("Change label of node, check that daemon pod is launched.") - nodeClient := c.Nodes() - nodeList, err := nodeClient.List(labels.Everything(), fields.Everything()) - Expect(len(nodeList.Items)).To(BeNumerically(">", 0)) - nodeList.Items[0].Labels = nodeSelector - newNode, err := nodeClient.Update(&nodeList.Items[0]) - Expect(err).NotTo(HaveOccurred()) - Expect(len(newNode.Labels)).To(Equal(1)) - err = wait.Poll(retryInterval, retryTimeout, checkDaemonPodOnNodes(f, complexLabel, []string{newNode.Name})) - Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pods to be running on new nodes") - - By("remove the node selector and wait for") - newNode, err = nodeClient.Get(newNode.Name) - Expect(err).NotTo(HaveOccurred(), "error getting node") - newNode.Labels = map[string]string{} - newNode, err = nodeClient.Update(newNode) - Expect(err).NotTo(HaveOccurred()) - Expect(wait.Poll(retryInterval, retryTimeout, checkRunningOnNoNodes(f, complexLabel))). - NotTo(HaveOccurred(), "error waiting for daemon pod to not be running on nodes") -} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/density.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/density.go index 80b772de3305..3d0ec4ef90ff 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/density.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/density.go @@ -20,21 +20,20 @@ import ( "fmt" "math" "os" - "os/exec" "sort" "strconv" "sync" "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" - "k8s.io/kubernetes/pkg/controller/framework" + controllerFramework "k8s.io/kubernetes/pkg/controller/framework" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" - "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/watch" . "github.com/onsi/ginkgo" @@ -63,26 +62,17 @@ func (a latencySlice) Len() int { return len(a) } func (a latencySlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a latencySlice) Less(i, j int) bool { return a[i].Latency < a[j].Latency } -func printLatencies(latencies []podLatencyData, header string) { +func extractLatencyMetrics(latencies []podLatencyData) LatencyMetric { perc50 := latencies[len(latencies)/2].Latency perc90 := latencies[(len(latencies)*9)/10].Latency perc99 := latencies[(len(latencies)*99)/100].Latency - Logf("10%% %s: %v", header, latencies[(len(latencies)*9)/10:len(latencies)]) - Logf("perc50: %v, perc90: %v, perc99: %v", perc50, perc90, perc99) + return LatencyMetric{Perc50: perc50, Perc90: perc90, Perc99: perc99} } -// List nodes via gcloud. We don't rely on the apiserver because we really want the node ips -// and sometimes the node controller is slow to populate them. -func gcloudListNodes() { - Logf("Listing nodes via gcloud:") - output, err := exec.Command("gcloud", "compute", "instances", "list", - "--project="+testContext.CloudConfig.ProjectID, "--zone="+testContext.CloudConfig.Zone).CombinedOutput() - if err != nil { - Logf("Failed to list nodes: %v", err) - return - } - Logf(string(output)) - return +func printLatencies(latencies []podLatencyData, header string) { + metrics := extractLatencyMetrics(latencies) + Logf("10%% %s: %v", header, latencies[(len(latencies)*9)/10:len(latencies)]) + Logf("perc50: %v, perc90: %v, perc99: %v", metrics.Perc50, metrics.Perc90, metrics.Perc99) } // This test suite can take a long time to run, so by default it is added to @@ -91,43 +81,56 @@ func gcloudListNodes() { // -t/--test flag or ginkgo.focus flag. var _ = Describe("Density", func() { var c *client.Client - var minionCount int + var nodeCount int var RCName string var additionalPodsPrefix string var ns string var uuid string + framework := Framework{BaseName: "density", NamespaceDeletionTimeout: time.Hour} BeforeEach(func() { + framework.beforeEach() + c = framework.Client + ns = framework.Namespace.Name var err error - c, err = loadClient() - expectNoError(err) - minions, err := c.Nodes().List(labels.Everything(), fields.Everything()) + + nodes, err := c.Nodes().List(labels.Everything(), fields.Everything()) expectNoError(err) - minionCount = len(minions.Items) - Expect(minionCount).NotTo(BeZero()) + nodeCount = len(nodes.Items) + Expect(nodeCount).NotTo(BeZero()) // Terminating a namespace (deleting the remaining objects from it - which // generally means events) can affect the current run. Thus we wait for all // terminating namespace to be finally deleted before starting this test. - err = deleteTestingNS(c) + err = checkTestingNSDeletedExcept(c, ns) expectNoError(err) - nsForTesting, err := createTestingNS("density", c) - ns = nsForTesting.Name - expectNoError(err) uuid = string(util.NewUUID()) expectNoError(resetMetrics(c)) expectNoError(os.Mkdir(fmt.Sprintf(testContext.OutputDir+"/%s", uuid), 0777)) expectNoError(writePerfData(c, fmt.Sprintf(testContext.OutputDir+"/%s", uuid), "before")) - gcloudListNodes() + + Logf("Listing nodes for easy debugging:\n") + for _, node := range nodes.Items { + for _, address := range node.Status.Addresses { + if address.Type == api.NodeInternalIP { + Logf("Name: %v IP: %v", node.ObjectMeta.Name, address.Address) + } + } + } }) AfterEach(func() { + // We can't call it explicitly at the end, because it will not be called + // if Expect() fails. + defer framework.afterEach() + // Remove any remaining pods from this test if the // replication controller still exists and the replica count // isn't 0. This means the controller wasn't cleaned up - // during the test so clean it up here + // during the test so clean it up here. We want to do it separately + // to not cause a timeout on Namespace removal. rc, err := c.ReplicationControllers(ns).Get(RCName) if err == nil && rc.Spec.Replicas != 0 { By("Cleaning up the replication controller") @@ -136,20 +139,15 @@ var _ = Describe("Density", func() { } By("Removing additional pods if any") - for i := 1; i <= minionCount; i++ { + for i := 1; i <= nodeCount; i++ { name := additionalPodsPrefix + "-" + strconv.Itoa(i) c.Pods(ns).Delete(name, nil) } - By(fmt.Sprintf("Destroying namespace for this suite %v", ns)) - if err := c.Namespaces().Delete(ns); err != nil { - Failf("Couldn't delete ns %s", err) - } - expectNoError(writePerfData(c, fmt.Sprintf(testContext.OutputDir+"/%s", uuid), "after")) // Verify latency metrics - highLatencyRequests, err := HighLatencyRequests(c, 3*time.Second, sets.NewString("events")) + highLatencyRequests, err := HighLatencyRequests(c, 3*time.Second) expectNoError(err) Expect(highLatencyRequests).NotTo(BeNumerically(">", 0), "There should be no high-latency requests") }) @@ -160,7 +158,7 @@ var _ = Describe("Density", func() { skip bool // Controls if e2e latency tests should be run (they are slow) runLatencyTest bool - podsPerMinion int + podsPerNode int // Controls how often the apiserver is polled for pods interval time.Duration } @@ -170,17 +168,17 @@ var _ = Describe("Density", func() { // (metrics from other tests affects this one). // TODO: Reenable once we can measure latency only from a single test. // TODO: Expose runLatencyTest as ginkgo flag. - {podsPerMinion: 3, skip: true, runLatencyTest: false, interval: 10 * time.Second}, - {podsPerMinion: 30, skip: true, runLatencyTest: true, interval: 10 * time.Second}, + {podsPerNode: 3, skip: true, runLatencyTest: false, interval: 10 * time.Second}, + {podsPerNode: 30, skip: true, runLatencyTest: true, interval: 10 * time.Second}, // More than 30 pods per node is outside our v1.0 goals. // We might want to enable those tests in the future. - {podsPerMinion: 50, skip: true, runLatencyTest: false, interval: 10 * time.Second}, - {podsPerMinion: 100, skip: true, runLatencyTest: false, interval: 1 * time.Second}, + {podsPerNode: 50, skip: true, runLatencyTest: false, interval: 10 * time.Second}, + {podsPerNode: 100, skip: true, runLatencyTest: false, interval: 1 * time.Second}, } for _, testArg := range densityTests { - name := fmt.Sprintf("should allow starting %d pods per node", testArg.podsPerMinion) - if testArg.podsPerMinion == 30 { + name := fmt.Sprintf("should allow starting %d pods per node", testArg.podsPerNode) + if testArg.podsPerNode == 30 { name = "[Performance suite] " + name } if testArg.skip { @@ -188,13 +186,13 @@ var _ = Describe("Density", func() { } itArg := testArg It(name, func() { - totalPods := itArg.podsPerMinion * minionCount + totalPods := itArg.podsPerNode * nodeCount RCName = "density" + strconv.Itoa(totalPods) + "-" + uuid fileHndl, err := os.Create(fmt.Sprintf(testContext.OutputDir+"/%s/pod_states.csv", uuid)) expectNoError(err) defer fileHndl.Close() config := RCConfig{Client: c, - Image: "gcr.io/google_containers/pause:go", + Image: "beta.gcr.io/google_containers/pause:2.0", Name: RCName, Namespace: ns, PollInterval: itArg.interval, @@ -205,7 +203,7 @@ var _ = Describe("Density", func() { // Create a listener for events. events := make([](*api.Event), 0) - _, controller := framework.NewInformer( + _, controller := controllerFramework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return c.Events(ns).List(labels.Everything(), fields.Everything()) @@ -216,7 +214,7 @@ var _ = Describe("Density", func() { }, &api.Event{}, 0, - framework.ResourceEventHandlerFuncs{ + controllerFramework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { events = append(events, obj.(*api.Event)) }, @@ -253,11 +251,11 @@ var _ = Describe("Density", func() { if itArg.runLatencyTest { Logf("Schedling additional Pods to measure startup latencies") - createTimes := make(map[string]util.Time, 0) + createTimes := make(map[string]unversioned.Time, 0) nodes := make(map[string]string, 0) - scheduleTimes := make(map[string]util.Time, 0) - runTimes := make(map[string]util.Time, 0) - watchTimes := make(map[string]util.Time, 0) + scheduleTimes := make(map[string]unversioned.Time, 0) + runTimes := make(map[string]unversioned.Time, 0) + watchTimes := make(map[string]unversioned.Time, 0) var mutex sync.Mutex checkPod := func(p *api.Pod) { @@ -267,10 +265,10 @@ var _ = Describe("Density", func() { if p.Status.Phase == api.PodRunning { if _, found := watchTimes[p.Name]; !found { - watchTimes[p.Name] = util.Now() + watchTimes[p.Name] = unversioned.Now() createTimes[p.Name] = p.CreationTimestamp nodes[p.Name] = p.Spec.NodeName - var startTime util.Time + var startTime unversioned.Time for _, cs := range p.Status.ContainerStatuses { if cs.State.Running != nil { if startTime.Before(cs.State.Running.StartedAt) { @@ -278,7 +276,7 @@ var _ = Describe("Density", func() { } } } - if startTime != util.NewTime(time.Time{}) { + if startTime != unversioned.NewTime(time.Time{}) { runTimes[p.Name] = startTime } else { Failf("Pod %v is reported to be running, but none of its containers is", p.Name) @@ -288,7 +286,7 @@ var _ = Describe("Density", func() { } additionalPodsPrefix = "density-latency-pod-" + string(util.NewUUID()) - _, controller := framework.NewInformer( + _, controller := controllerFramework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { return c.Pods(ns).List(labels.SelectorFromSet(labels.Set{"name": additionalPodsPrefix}), fields.Everything()) @@ -299,7 +297,7 @@ var _ = Describe("Density", func() { }, &api.Pod{}, 0, - framework.ResourceEventHandlerFuncs{ + controllerFramework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { p, ok := obj.(*api.Pod) Expect(ok).To(Equal(true)) @@ -318,19 +316,19 @@ var _ = Describe("Density", func() { // Create some additional pods with throughput ~5 pods/sec. var wg sync.WaitGroup - wg.Add(minionCount) + wg.Add(nodeCount) podLabels := map[string]string{ "name": additionalPodsPrefix, } - for i := 1; i <= minionCount; i++ { + for i := 1; i <= nodeCount; i++ { name := additionalPodsPrefix + "-" + strconv.Itoa(i) - go createRunningPod(&wg, c, name, ns, "gcr.io/google_containers/pause:go", podLabels) + go createRunningPod(&wg, c, name, ns, "beta.gcr.io/google_containers/pause:2.0", podLabels) time.Sleep(200 * time.Millisecond) } wg.Wait() Logf("Waiting for all Pods begin observed by the watch...") - for start := time.Now(); len(watchTimes) < minionCount && time.Since(start) < timeout; time.Sleep(10 * time.Second) { + for start := time.Now(); len(watchTimes) < nodeCount && time.Since(start) < timeout; time.Sleep(10 * time.Second) { } close(stopCh) @@ -387,14 +385,10 @@ var _ = Describe("Density", func() { printLatencies(e2eLag, "worst e2e total latencies") // Test whether e2e pod startup time is acceptable. + podStartupLatency := PodStartupLatency{Latency: extractLatencyMetrics(e2eLag)} // TODO: Switch it to 5 seconds once we are sure our tests are passing. podStartupThreshold := 8 * time.Second - e2ePodStartupTime50perc := e2eLag[len(e2eLag)/2].Latency - e2ePodStartupTime90perc := e2eLag[len(e2eLag)*9/10].Latency - e2ePodStartupTime99perc := e2eLag[len(e2eLag)*99/100].Latency - Expect(e2ePodStartupTime50perc < podStartupThreshold).To(Equal(true), "Too high pod startup time 50th percentile") - Expect(e2ePodStartupTime90perc < podStartupThreshold).To(Equal(true), "Too high pod startup time 90th percentile") - Expect(e2ePodStartupTime99perc < podStartupThreshold).To(Equal(true), "Too high pod startup time 99th percentile") + expectNoError(VerifyPodStartupLatency(podStartupLatency, podStartupThreshold)) // Log suspicious latency metrics/docker errors from all nodes that had slow startup times for _, l := range startupLag { @@ -404,7 +398,7 @@ var _ = Describe("Density", func() { } Logf("Approx throughput: %v pods/min", - float64(minionCount)/(e2eLag[len(e2eLag)-1].Latency.Minutes())) + float64(nodeCount)/(e2eLag[len(e2eLag)-1].Latency.Minutes())) } }) } @@ -414,7 +408,7 @@ func createRunningPod(wg *sync.WaitGroup, c *client.Client, name, ns, image stri defer GinkgoRecover() defer wg.Done() pod := &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", }, ObjectMeta: api.ObjectMeta{ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/deployment.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/deployment.go new file mode 100644 index 000000000000..67ab373aabc4 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/deployment.go @@ -0,0 +1,271 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 e2e + +import ( + "fmt" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + deploymentUtil "k8s.io/kubernetes/pkg/util/deployment" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Deployment", func() { + f := NewFramework("deployment") + + It("deployment should create new pods", func() { + testNewDeployment(f) + }) + It("deployment should delete old pods and create new ones", func() { + testRollingUpdateDeployment(f) + }) + It("deployment should scale up and down in the right order", func() { + testRollingUpdateDeploymentEvents(f) + }) +}) + +func testNewDeployment(f *Framework) { + ns := f.Namespace.Name + c := f.Client + deploymentName := "nginx-deployment" + podLabels := map[string]string{"name": "nginx"} + Logf("Creating simple deployment %s", deploymentName) + _, err := c.Deployments(ns).Create(&extensions.Deployment{ + ObjectMeta: api.ObjectMeta{ + Name: deploymentName, + }, + Spec: extensions.DeploymentSpec{ + Replicas: 1, + Selector: podLabels, + UniqueLabelKey: "deployment.kubernetes.io/podTemplateHash", + Template: &api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: podLabels, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + defer func() { + Logf("deleting deployment %s", deploymentName) + Expect(c.Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred()) + }() + // Check that deployment is created fine. + deployment, err := c.Deployments(ns).Get(deploymentName) + Expect(err).NotTo(HaveOccurred()) + + // Verify that the required pods have come up. + err = verifyPods(c, ns, "nginx", false, 1) + if err != nil { + Logf("error in waiting for pods to come up: %s", err) + Expect(err).NotTo(HaveOccurred()) + } + // DeploymentStatus should be appropriately updated. + deployment, err = c.Deployments(ns).Get(deploymentName) + Expect(err).NotTo(HaveOccurred()) + Expect(deployment.Status.Replicas).Should(Equal(1)) + Expect(deployment.Status.UpdatedReplicas).Should(Equal(1)) +} + +func testRollingUpdateDeployment(f *Framework) { + ns := f.Namespace.Name + c := f.Client + // Create nginx pods. + deploymentPodLabels := map[string]string{"name": "sample-pod"} + rcPodLabels := map[string]string{ + "name": "sample-pod", + "pod": "nginx", + } + + rcName := "nginx-controller" + _, err := c.ReplicationControllers(ns).Create(&api.ReplicationController{ + ObjectMeta: api.ObjectMeta{ + Name: rcName, + }, + Spec: api.ReplicationControllerSpec{ + Replicas: 3, + Selector: rcPodLabels, + Template: &api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: rcPodLabels, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + defer func() { + Logf("deleting replication controller %s", rcName) + Expect(c.ReplicationControllers(ns).Delete(rcName)).NotTo(HaveOccurred()) + }() + // Verify that the required pods have come up. + err = verifyPods(c, ns, "sample-pod", false, 3) + if err != nil { + Logf("error in waiting for pods to come up: %s", err) + Expect(err).NotTo(HaveOccurred()) + } + + // Create a deployment to delete nginx pods and instead bring up redis pods. + deploymentName := "redis-deployment" + Logf("Creating deployment %s", deploymentName) + newDeployment := extensions.Deployment{ + ObjectMeta: api.ObjectMeta{ + Name: deploymentName, + }, + Spec: extensions.DeploymentSpec{ + Replicas: 3, + Selector: deploymentPodLabels, + UniqueLabelKey: "deployment.kubernetes.io/podTemplateHash", + Template: &api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: deploymentPodLabels, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "redis", + Image: "redis", + }, + }, + }, + }, + }, + } + _, err = c.Deployments(ns).Create(&newDeployment) + Expect(err).NotTo(HaveOccurred()) + defer func() { + Logf("deleting deployment %s", deploymentName) + Expect(c.Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred()) + }() + + err = waitForDeploymentStatus(c, ns, deploymentName, 3, 2, 4) + Expect(err).NotTo(HaveOccurred()) +} + +func testRollingUpdateDeploymentEvents(f *Framework) { + ns := f.Namespace.Name + c := f.Client + // Create nginx pods. + deploymentPodLabels := map[string]string{"name": "sample-pod"} + rcPodLabels := map[string]string{ + "name": "sample-pod", + "pod": "nginx", + } + rcName := "nginx-controller" + _, err := c.ReplicationControllers(ns).Create(&api.ReplicationController{ + ObjectMeta: api.ObjectMeta{ + Name: rcName, + }, + Spec: api.ReplicationControllerSpec{ + Replicas: 1, + Selector: rcPodLabels, + Template: &api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: rcPodLabels, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + defer func() { + Logf("deleting replication controller %s", rcName) + Expect(c.ReplicationControllers(ns).Delete(rcName)).NotTo(HaveOccurred()) + }() + // Verify that the required pods have come up. + err = verifyPods(c, ns, "sample-pod", false, 1) + if err != nil { + Logf("error in waiting for pods to come up: %s", err) + Expect(err).NotTo(HaveOccurred()) + } + + // Create a deployment to delete nginx pods and instead bring up redis pods. + deploymentName := "redis-deployment" + Logf("Creating deployment %s", deploymentName) + newDeployment := extensions.Deployment{ + ObjectMeta: api.ObjectMeta{ + Name: deploymentName, + }, + Spec: extensions.DeploymentSpec{ + Replicas: 1, + Selector: deploymentPodLabels, + UniqueLabelKey: "deployment.kubernetes.io/podTemplateHash", + Template: &api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: deploymentPodLabels, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "redis", + Image: "redis", + }, + }, + }, + }, + }, + } + _, err = c.Deployments(ns).Create(&newDeployment) + Expect(err).NotTo(HaveOccurred()) + defer func() { + Logf("deleting deployment %s", deploymentName) + Expect(c.Deployments(ns).Delete(deploymentName, nil)).NotTo(HaveOccurred()) + }() + + err = waitForDeploymentStatus(c, ns, deploymentName, 1, 0, 2) + Expect(err).NotTo(HaveOccurred()) + // Verify that the pods were scaled up and down as expected. We use events to verify that. + deployment, err := c.Deployments(ns).Get(deploymentName) + Expect(err).NotTo(HaveOccurred()) + waitForEvents(c, ns, deployment, 2) + events, err := c.Events(ns).Search(deployment) + if err != nil { + Logf("error in listing events: %s", err) + Expect(err).NotTo(HaveOccurred()) + } + // There should be 2 events, one to scale up the new RC and then to scale down the old RC. + Expect(len(events.Items)).Should(Equal(2)) + newRC, err := deploymentUtil.GetNewRC(*deployment, c) + Expect(err).NotTo(HaveOccurred()) + Expect(newRC).NotTo(Equal(nil)) + Expect(events.Items[0].Message).Should(Equal(fmt.Sprintf("Scaled up rc %s to 1", newRC.Name))) + Expect(events.Items[1].Message).Should(Equal(fmt.Sprintf("Scaled down rc %s to 0", rcName))) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/dns.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/dns.go index 33fb9b55d185..0f72849721c2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/dns.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/dns.go @@ -23,6 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -40,9 +41,9 @@ var dnsServiceLableSelector = labels.Set{ func createDNSPod(namespace, wheezyProbeCmd, jessieProbeCmd string) *api.Pod { pod := &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", - APIVersion: latest.Version, + APIVersion: latest.GroupOrDie("").Version, }, ObjectMeta: api.ObjectMeta{ Name: "dns-test-" + string(util.NewUUID()), diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/docker_containers.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/docker_containers.go index cae777a98427..c8f72b08a0c7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/docker_containers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/docker_containers.go @@ -17,6 +17,8 @@ limitations under the License. package e2e import ( + "time" + "k8s.io/kubernetes/pkg/api" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/util" @@ -39,43 +41,43 @@ var _ = Describe("Docker Containers", func() { }) AfterEach(func() { - if err := deleteNS(c, ns); err != nil { + if err := deleteNS(c, ns, 5*time.Minute /* namespace deletion timeout */); err != nil { Failf("Couldn't delete ns %s", err) } }) - It("should use the image defaults if command and args are blank", func() { - testContainerOutputInNamespace("use defaults", c, entrypointTestPod(), 0, []string{ + It("should use the image defaults if command and args are blank [Conformance]", func() { + testContainerOutput("use defaults", c, entrypointTestPod(), 0, []string{ "[/ep default arguments]", }, ns) }) - It("should be able to override the image's default arguments (docker cmd)", func() { + It("should be able to override the image's default arguments (docker cmd) [Conformance]", func() { pod := entrypointTestPod() pod.Spec.Containers[0].Args = []string{"override", "arguments"} - testContainerOutputInNamespace("override arguments", c, pod, 0, []string{ + testContainerOutput("override arguments", c, pod, 0, []string{ "[/ep override arguments]", }, ns) }) // Note: when you override the entrypoint, the image's arguments (docker cmd) // are ignored. - It("should be able to override the image's default commmand (docker entrypoint)", func() { + It("should be able to override the image's default commmand (docker entrypoint) [Conformance]", func() { pod := entrypointTestPod() pod.Spec.Containers[0].Command = []string{"/ep-2"} - testContainerOutputInNamespace("override command", c, pod, 0, []string{ + testContainerOutput("override command", c, pod, 0, []string{ "[/ep-2]", }, ns) }) - It("should be able to override the image's default command and arguments", func() { + It("should be able to override the image's default command and arguments [Conformance]", func() { pod := entrypointTestPod() pod.Spec.Containers[0].Command = []string{"/ep-2"} pod.Spec.Containers[0].Args = []string{"override", "arguments"} - testContainerOutputInNamespace("override all", c, pod, 0, []string{ + testContainerOutput("override all", c, pod, 0, []string{ "[/ep-2 override arguments]", }, ns) }) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/downward_api.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/downward_api.go index e5ade3f0fa76..73fde0804ba0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/downward_api.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/downward_api.go @@ -28,48 +28,77 @@ import ( var _ = Describe("Downward API", func() { framework := NewFramework("downward-api") - It("should provide pod name and namespace as env vars", func() { + It("should provide pod name and namespace as env vars [Conformance]", func() { podName := "downward-api-" + string(util.NewUUID()) - pod := &api.Pod{ - ObjectMeta: api.ObjectMeta{ - Name: podName, - Labels: map[string]string{"name": podName}, + env := []api.EnvVar{ + { + Name: "POD_NAME", + ValueFrom: &api.EnvVarSource{ + FieldRef: &api.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.name", + }, + }, }, - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "dapi-container", - Image: "gcr.io/google_containers/busybox", - Command: []string{"sh", "-c", "env"}, - Env: []api.EnvVar{ - { - Name: "POD_NAME", - ValueFrom: &api.EnvVarSource{ - FieldRef: &api.ObjectFieldSelector{ - APIVersion: "v1", - FieldPath: "metadata.name", - }, - }, - }, - { - Name: "POD_NAMESPACE", - ValueFrom: &api.EnvVarSource{ - FieldRef: &api.ObjectFieldSelector{ - APIVersion: "v1", - FieldPath: "metadata.namespace", - }, - }, - }, - }, + { + Name: "POD_NAMESPACE", + ValueFrom: &api.EnvVarSource{ + FieldRef: &api.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.namespace", }, }, - RestartPolicy: api.RestartPolicyNever, }, } - framework.TestContainerOutput("downward api env vars", pod, 0, []string{ + expectations := []string{ fmt.Sprintf("POD_NAME=%v", podName), fmt.Sprintf("POD_NAMESPACE=%v", framework.Namespace.Name), - }) + } + + testDownwardAPI(framework, podName, env, expectations) + }) + + It("should provide pod IP as an env var", func() { + podName := "downward-api-" + string(util.NewUUID()) + env := []api.EnvVar{ + { + Name: "POD_IP", + ValueFrom: &api.EnvVarSource{ + FieldRef: &api.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "status.podIP", + }, + }, + }, + } + + expectations := []string{ + "POD_IP=(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)", + } + + testDownwardAPI(framework, podName, env, expectations) }) }) + +func testDownwardAPI(framework *Framework, podName string, env []api.EnvVar, expectations []string) { + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: podName, + Labels: map[string]string{"name": podName}, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "dapi-container", + Image: "gcr.io/google_containers/busybox", + Command: []string{"sh", "-c", "env"}, + Env: env, + }, + }, + RestartPolicy: api.RestartPolicyNever, + }, + } + + framework.TestContainerOutputRegexp("downward api env vars", pod, 0, expectations) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/downwardapi_volume.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/downwardapi_volume.go index 5bc26907eee7..7e0ff66160cf 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/downwardapi_volume.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/downwardapi_volume.go @@ -28,7 +28,7 @@ import ( var _ = Describe("Downward API volume", func() { f := NewFramework("downward-api") - It("should provide labels and annotations files", func() { + It("should provide labels and annotations files [Conformance]", func() { podName := "metadata-volume-" + string(util.NewUUID()) pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ @@ -86,7 +86,7 @@ var _ = Describe("Downward API volume", func() { RestartPolicy: api.RestartPolicyNever, }, } - testContainerOutputInNamespace("downward API volume plugin", f.Client, pod, 0, []string{ + testContainerOutput("downward API volume plugin", f.Client, pod, 0, []string{ fmt.Sprintf("cluster=\"rack10\"\n"), fmt.Sprintf("builder=\"john-doe\"\n"), fmt.Sprintf("%s\n", podName), diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/e2e_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/e2e_test.go index cb7a833f44e2..628c814e563e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/e2e_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/e2e_test.go @@ -81,6 +81,7 @@ func init() { flag.IntVar(&testContext.MinStartupPods, "minStartupPods", 0, "The number of pods which we need to see in 'Running' state with a 'Ready' condition of true, before we try running tests. This is useful in any cluster which needs some base pod-based services running before it can be used.") flag.StringVar(&testContext.UpgradeTarget, "upgrade-target", "latest_ci", "Version to upgrade to (e.g. 'latest_stable', 'latest_release', 'latest_ci', '0.19.1', '0.19.1-669-gabac8c8') if doing an upgrade test.") flag.StringVar(&testContext.PrometheusPushGateway, "prom-push-gateway", "", "The URL to prometheus gateway, so that metrics can be pushed during e2es and scraped by prometheus. Typically something like 127.0.0.1:9091.") + flag.BoolVar(&testContext.VerifyServiceAccount, "e2e-verify-service-account", true, "If true tests will verify the service account before running.") } func TestE2E(t *testing.T) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/empty_dir.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/empty_dir.go index a8724cab931b..160ace41e38a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/empty_dir.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/empty_dir.go @@ -18,10 +18,12 @@ package e2e import ( "fmt" + "path" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util" - "path" . "github.com/onsi/ginkgo" ) @@ -35,59 +37,59 @@ var _ = Describe("EmptyDir volumes", func() { f := NewFramework("emptydir") - It("volume on tmpfs should have the correct mode", func() { + It("volume on tmpfs should have the correct mode [Conformance]", func() { doTestVolumeMode(f, testImageRootUid, api.StorageMediumMemory) }) - It("should support (root,0644,tmpfs)", func() { + It("should support (root,0644,tmpfs) [Conformance]", func() { doTest0644(f, testImageRootUid, api.StorageMediumMemory) }) - It("should support (root,0666,tmpfs)", func() { + It("should support (root,0666,tmpfs) [Conformance]", func() { doTest0666(f, testImageRootUid, api.StorageMediumMemory) }) - It("should support (root,0777,tmpfs)", func() { + It("should support (root,0777,tmpfs) [Conformance]", func() { doTest0777(f, testImageRootUid, api.StorageMediumMemory) }) - It("should support (non-root,0644,tmpfs)", func() { + It("should support (non-root,0644,tmpfs) [Conformance]", func() { doTest0644(f, testImageNonRootUid, api.StorageMediumMemory) }) - It("should support (non-root,0666,tmpfs)", func() { + It("should support (non-root,0666,tmpfs) [Conformance]", func() { doTest0666(f, testImageNonRootUid, api.StorageMediumMemory) }) - It("should support (non-root,0777,tmpfs)", func() { + It("should support (non-root,0777,tmpfs) [Conformance]", func() { doTest0777(f, testImageNonRootUid, api.StorageMediumMemory) }) - It("volume on default medium should have the correct mode", func() { + It("volume on default medium should have the correct mode [Conformance]", func() { doTestVolumeMode(f, testImageRootUid, api.StorageMediumDefault) }) - It("should support (root,0644,default)", func() { + It("should support (root,0644,default) [Conformance]", func() { doTest0644(f, testImageRootUid, api.StorageMediumDefault) }) - It("should support (root,0666,default)", func() { + It("should support (root,0666,default) [Conformance]", func() { doTest0666(f, testImageRootUid, api.StorageMediumDefault) }) - It("should support (root,0777,default)", func() { + It("should support (root,0777,default) [Conformance]", func() { doTest0777(f, testImageRootUid, api.StorageMediumDefault) }) - It("should support (non-root,0644,default)", func() { + It("should support (non-root,0644,default) [Conformance]", func() { doTest0644(f, testImageNonRootUid, api.StorageMediumDefault) }) - It("should support (non-root,0666,default)", func() { + It("should support (non-root,0666,default) [Conformance]", func() { doTest0666(f, testImageNonRootUid, api.StorageMediumDefault) }) - It("should support (non-root,0777,default)", func() { + It("should support (non-root,0777,default) [Conformance]", func() { doTest0777(f, testImageNonRootUid, api.StorageMediumDefault) }) }) @@ -205,9 +207,9 @@ func formatMedium(medium api.StorageMedium) string { func testPodWithVolume(image, path string, source *api.EmptyDirVolumeSource) *api.Pod { podName := "pod-" + string(util.NewUUID()) return &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", - APIVersion: latest.Version, + APIVersion: latest.GroupOrDie("").Version, }, ObjectMeta: api.ObjectMeta{ Name: podName, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/etcd_failure.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/etcd_failure.go index b6ba2b90dafd..436d35e6e2e5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/etcd_failure.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/etcd_failure.go @@ -49,7 +49,7 @@ var _ = Describe("Etcd failure", func() { Client: framework.Client, Name: "baz", Namespace: framework.Namespace.Name, - Image: "gcr.io/google_containers/nginx", + Image: "beta.gcr.io/google_containers/pause:2.0", Replicas: 1, })).NotTo(HaveOccurred()) }) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/events.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/events.go index 432c982330f2..d7d4ad287c89 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/events.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/events.go @@ -34,7 +34,7 @@ import ( var _ = Describe("Events", func() { framework := NewFramework("events") - It("should be sent by kubelets and the scheduler about pods scheduling and running", func() { + It("should be sent by kubelets and the scheduler about pods scheduling and running [Conformance]", func() { podClient := framework.Client.Pods(framework.Namespace.Name) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/examples.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/examples.go index 0c2efba36efa..6a0e17c24d89 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/examples.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/examples.go @@ -34,10 +34,9 @@ import ( ) const ( - podListTimeout = time.Minute - serverStartTimeout = podStartTimeout + 3*time.Minute - dnsReadyTimeout = time.Minute - endpointRegisterTimeout = time.Minute + podListTimeout = time.Minute + serverStartTimeout = podStartTimeout + 3*time.Minute + dnsReadyTimeout = time.Minute ) const queryDnsPythonTemplate string = ` @@ -63,7 +62,7 @@ var _ = Describe("Examples e2e", func() { AfterEach(func() { By(fmt.Sprintf("Destroying namespace for this suite %v", ns)) - if err := deleteNS(c, ns); err != nil { + if err := deleteNS(c, ns, 5*time.Minute /* namespace deletion timeout */); err != nil { Failf("Couldn't delete ns %s", err) } }) @@ -149,6 +148,9 @@ var _ = Describe("Examples e2e", func() { _, err := lookForStringInLog(ns, pod.Name, "rabbitmq", "Server startup complete", serverStartTimeout) Expect(err).NotTo(HaveOccurred()) }) + err := waitForEndpoint(c, ns, "rabbitmq-service") + Expect(err).NotTo(HaveOccurred()) + By("starting celery") runKubectl("create", "-f", celeryControllerYaml, nsFlag) forEachPod(c, ns, "component", "celery", func(pod api.Pod) { @@ -192,6 +194,10 @@ var _ = Describe("Examples e2e", func() { _, err = lookForStringInLog(ns, "spark-driver", "spark-driver", "Use kubectl exec", serverStartTimeout) Expect(err).NotTo(HaveOccurred()) + By("waiting for master endpoint") + err = waitForEndpoint(c, ns, "spark-master") + Expect(err).NotTo(HaveOccurred()) + By("starting workers") runKubectl("create", "-f", workerControllerJson, nsFlag) ScaleRC(c, ns, "spark-worker-controller", 2, true) @@ -221,6 +227,9 @@ var _ = Describe("Examples e2e", func() { _, err = lookForStringInLog(ns, "cassandra", "cassandra", "Listening for thrift clients", serverStartTimeout) Expect(err).NotTo(HaveOccurred()) + err = waitForEndpoint(c, ns, "cassandra") + Expect(err).NotTo(HaveOccurred()) + By("create and scale rc") runKubectl("create", "-f", controllerYaml, nsFlag) err = ScaleRC(c, ns, "cassandra", 2, true) @@ -263,6 +272,8 @@ var _ = Describe("Examples e2e", func() { By("checking if zookeeper is up and running") _, err = lookForStringInLog(ns, zookeeperPod, "zookeeper", "binding to port", serverStartTimeout) Expect(err).NotTo(HaveOccurred()) + err = waitForEndpoint(c, ns, "zookeeper") + Expect(err).NotTo(HaveOccurred()) By("starting Nimbus") runKubectl("create", "-f", nimbusPodJson, nsFlag) @@ -270,6 +281,9 @@ var _ = Describe("Examples e2e", func() { err = waitForPodRunningInNamespace(c, "nimbus", ns) Expect(err).NotTo(HaveOccurred()) + err = waitForEndpoint(c, ns, "nimbus") + Expect(err).NotTo(HaveOccurred()) + By("starting workers") runKubectl("create", "-f", workerControllerJson, nsFlag) forEachPod(c, ns, "name", "storm-worker", func(pod api.Pod) { @@ -382,6 +396,8 @@ var _ = Describe("Examples e2e", func() { }) } checkDbInstances() + err := waitForEndpoint(c, ns, "rethinkdb-driver") + Expect(err).NotTo(HaveOccurred()) By("scaling rethinkdb") ScaleRC(c, ns, "rethinkdb-rc", 2, true) @@ -390,7 +406,7 @@ var _ = Describe("Examples e2e", func() { By("starting admin") runKubectl("create", "-f", adminServiceYaml, nsFlag) runKubectl("create", "-f", adminPodYaml, nsFlag) - err := waitForPodRunningInNamespace(c, "rethinkdb-admin", ns) + err = waitForPodRunningInNamespace(c, "rethinkdb-admin", ns) Expect(err).NotTo(HaveOccurred()) checkDbInstances() content, err := makeHttpRequestToService(c, ns, "rethinkdb-admin", "/", endpointRegisterTimeout) @@ -420,6 +436,9 @@ var _ = Describe("Examples e2e", func() { Expect(err).NotTo(HaveOccurred()) }) + err := waitForEndpoint(c, ns, "hazelcast") + Expect(err).NotTo(HaveOccurred()) + By("scaling hazelcast") ScaleRC(c, ns, "hazelcast", 2, true) forEachPod(c, ns, "name", "hazelcast", func(pod api.Pod) { @@ -430,7 +449,7 @@ var _ = Describe("Examples e2e", func() { }) Describe("[Example]ClusterDns", func() { - It("should create pod that uses dns", func() { + It("should create pod that uses dns [Conformance]", func() { mkpath := func(file string) string { return filepath.Join(testContext.RepoRoot, "examples/cluster-dns", file) } @@ -458,7 +477,7 @@ var _ = Describe("Examples e2e", func() { var err error namespaces[i], err = createTestingNS(fmt.Sprintf("dnsexample%d", i), c) if namespaces[i] != nil { - defer deleteNS(c, namespaces[i].Name) + defer deleteNS(c, namespaces[i].Name, 5*time.Minute /* namespace deletion timeout */) } Expect(err).NotTo(HaveOccurred()) } @@ -562,22 +581,26 @@ func prepareResourceWithReplacedString(inputFile, old, new string) string { } func forEachPod(c *client.Client, ns, selectorKey, selectorValue string, fn func(api.Pod)) { - var pods *api.PodList - var err error + pods := []*api.Pod{} for t := time.Now(); time.Since(t) < podListTimeout; time.Sleep(poll) { - pods, err = c.Pods(ns).List(labels.SelectorFromSet(labels.Set(map[string]string{selectorKey: selectorValue})), fields.Everything()) + podList, err := c.Pods(ns).List(labels.SelectorFromSet(labels.Set(map[string]string{selectorKey: selectorValue})), fields.Everything()) Expect(err).NotTo(HaveOccurred()) - if len(pods.Items) > 0 { + for _, pod := range podList.Items { + if pod.Status.Phase == api.PodPending || pod.Status.Phase == api.PodRunning { + pods = append(pods, &pod) + } + } + if len(pods) > 0 { break } } - if pods == nil || len(pods.Items) == 0 { + if pods == nil || len(pods) == 0 { Failf("No pods found") } - for _, pod := range pods.Items { - err = waitForPodRunningInNamespace(c, pod.Name, ns) + for _, pod := range pods { + err := waitForPodRunningInNamespace(c, pod.Name, ns) Expect(err).NotTo(HaveOccurred()) - fn(pod) + fn(*pod) } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/expansion.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/expansion.go index a27bbaf19d5e..3cd4806f457f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/expansion.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/expansion.go @@ -26,7 +26,7 @@ import ( var _ = Describe("Variable Expansion", func() { framework := NewFramework("var-expansion") - It("should allow composing env vars into new env vars", func() { + It("should allow composing env vars into new env vars [Conformance]", func() { podName := "var-expansion-" + string(util.NewUUID()) pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ @@ -66,7 +66,7 @@ var _ = Describe("Variable Expansion", func() { }) }) - It("should allow substituting values in a container's command", func() { + It("should allow substituting values in a container's command [Conformance]", func() { podName := "var-expansion-" + string(util.NewUUID()) pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ @@ -96,7 +96,7 @@ var _ = Describe("Variable Expansion", func() { }) }) - It("should allow substituting values in a container's args", func() { + It("should allow substituting values in a container's args [Conformance]", func() { podName := "var-expansion-" + string(util.NewUUID()) pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/framework.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/framework.go index aa3b975f1d8b..c768a8602539 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/framework.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/framework.go @@ -36,25 +36,16 @@ import ( type Framework struct { BaseName string - Namespace *api.Namespace - Client *client.Client - - // Allows to override the initialization of the namespace - nsCreateFunc func(string, *client.Client) (*api.Namespace, error) + Namespace *api.Namespace + Client *client.Client + NamespaceDeletionTimeout time.Duration } // NewFramework makes a new framework and sets up a BeforeEach/AfterEach for // you (you can write additional before/after each functions). func NewFramework(baseName string) *Framework { - return InitializeFramework(baseName, createTestingNS) -} - -// InitializeFramework initialize the framework by allowing to pass a custom -// namespace creation function. -func InitializeFramework(baseName string, nsCreateFunc func(string, *client.Client) (*api.Namespace, error)) *Framework { f := &Framework{ - BaseName: baseName, - nsCreateFunc: nsCreateFunc, + BaseName: baseName, } BeforeEach(f.beforeEach) @@ -72,14 +63,18 @@ func (f *Framework) beforeEach() { f.Client = c By("Building a namespace api object") - namespace, err := f.nsCreateFunc(f.BaseName, f.Client) + namespace, err := createTestingNS(f.BaseName, f.Client) Expect(err).NotTo(HaveOccurred()) f.Namespace = namespace - By("Waiting for a default service account to be provisioned in namespace") - err = waitForDefaultServiceAccountInNamespace(c, namespace.Name) - Expect(err).NotTo(HaveOccurred()) + if testContext.VerifyServiceAccount { + By("Waiting for a default service account to be provisioned in namespace") + err = waitForDefaultServiceAccountInNamespace(c, namespace.Name) + Expect(err).NotTo(HaveOccurred()) + } else { + Logf("Skipping waiting for service account") + } } // afterEach deletes the namespace, after reading its events. @@ -107,7 +102,11 @@ func (f *Framework) afterEach() { By(fmt.Sprintf("Destroying namespace %q for this suite.", f.Namespace.Name)) - if err := deleteNS(f.Client, f.Namespace.Name); err != nil { + timeout := 5 * time.Minute + if f.NamespaceDeletionTimeout != 0 { + timeout = f.NamespaceDeletionTimeout + } + if err := deleteNS(f.Client, f.Namespace.Name, timeout); err != nil { Failf("Couldn't delete ns %q: %s", f.Namespace.Name, err) } // Paranoia-- prevent reuse! @@ -122,7 +121,12 @@ func (f *Framework) WaitForPodRunning(podName string) error { // Runs the given pod and verifies that the output of exact container matches the desired output. func (f *Framework) TestContainerOutput(scenarioName string, pod *api.Pod, containerIndex int, expectedOutput []string) { - testContainerOutputInNamespace(scenarioName, f.Client, pod, containerIndex, expectedOutput, f.Namespace.Name) + testContainerOutput(scenarioName, f.Client, pod, containerIndex, expectedOutput, f.Namespace.Name) +} + +// Runs the given pod and verifies that the output of exact container matches the desired regexps. +func (f *Framework) TestContainerOutputRegexp(scenarioName string, pod *api.Pod, containerIndex int, expectedOutput []string) { + testContainerOutputRegexp(scenarioName, f.Client, pod, containerIndex, expectedOutput, f.Namespace.Name) } // WaitForAnEndpoint waits for at least one endpoint to become available in the diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/google_compute.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/google_compute.go index 270831ff9e86..f33a78a57253 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/google_compute.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/google_compute.go @@ -18,10 +18,12 @@ package e2e import ( "fmt" - "github.com/golang/glog" "os/exec" "regexp" "strings" + "time" + + "github.com/golang/glog" ) func createGCEStaticIP(name string) (string, error) { @@ -31,13 +33,22 @@ func createGCEStaticIP(name string) (string, error) { // NAME REGION ADDRESS STATUS // test-static-ip us-central1 104.197.143.7 RESERVED - output, err := exec.Command("gcloud", "compute", "addresses", "create", - name, "--project", testContext.CloudConfig.ProjectID, - "--region", "us-central1", "-q").CombinedOutput() + var output []byte + var err error + for attempts := 0; attempts < 4; attempts++ { + output, err = exec.Command("gcloud", "compute", "addresses", "create", + name, "--project", testContext.CloudConfig.ProjectID, + "--region", "us-central1", "-q").CombinedOutput() + if err == nil { + break + } + glog.Errorf("Creating static IP with name:%s in project: %s", name, testContext.CloudConfig.ProjectID) + glog.Errorf("output: %s", output) + time.Sleep(time.Duration(5*attempts) * time.Second) + } if err != nil { return "", err } - glog.Errorf("Creating static IP with name:%s in project: %s", name, testContext.CloudConfig.ProjectID) text := string(output) if strings.Contains(text, "RESERVED") { r, _ := regexp.Compile("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/horizontal_pod_autoscaling.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/horizontal_pod_autoscaling.go index b1734ce5e042..1eb1e8c47f7a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/horizontal_pod_autoscaling.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/horizontal_pod_autoscaling.go @@ -17,107 +17,181 @@ limitations under the License. package e2e import ( - "time" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" - "k8s.io/kubernetes/pkg/apis/experimental" + "k8s.io/kubernetes/pkg/apis/extensions" . "github.com/onsi/ginkgo" ) const ( - sleep = 10 * time.Minute + kind = "replicationController" + subresource = "scale" ) var _ = Describe("Horizontal pod autoscaling", func() { var rc *ResourceConsumer f := NewFramework("horizontal-pod-autoscaling") - BeforeEach(func() { - Skip("Skipped Horizontal pod autoscaling test") + // CPU tests + It("[Skipped][Autoscaling Suite] should scale from 1 pod to 3 pods and from 3 to 5 (scale resource: CPU)", func() { + rc = NewDynamicResourceConsumer("rc", 1, 250, 0, 400, 100, f) + defer rc.CleanUp() + createCPUHorizontalPodAutoscaler(rc, "0.1") + rc.WaitForReplicas(3) + rc.ConsumeCPU(700) + rc.WaitForReplicas(5) + }) + + It("[Skipped][Autoscaling Suite] should scale from 5 pods to 3 pods and from 3 to 1 (scale resource: CPU)", func() { + rc = NewDynamicResourceConsumer("rc", 5, 700, 0, 200, 100, f) + defer rc.CleanUp() + createCPUHorizontalPodAutoscaler(rc, "0.3") + rc.WaitForReplicas(3) + rc.ConsumeCPU(100) + rc.WaitForReplicas(1) }) - AfterEach(func() { + // Memory tests + It("[Skipped][Autoscaling Suite] should scale from 1 pod to 3 pods and from 3 to 5 (scale resource: Memory)", func() { + rc = NewDynamicResourceConsumer("rc", 1, 0, 2200, 100, 2500, f) + defer rc.CleanUp() + createMemoryHorizontalPodAutoscaler(rc, "1000") + rc.WaitForReplicas(3) + rc.ConsumeMem(4200) + rc.WaitForReplicas(5) }) + It("[Skipped][Autoscaling Suite] should scale from 5 pods to 3 pods and from 3 to 1 (scale resource: Memory)", func() { + rc = NewDynamicResourceConsumer("rc", 5, 0, 2200, 100, 2500, f) + defer rc.CleanUp() + createMemoryHorizontalPodAutoscaler(rc, "1000") + rc.WaitForReplicas(3) + rc.ConsumeMem(100) + rc.WaitForReplicas(1) + }) + + // Backup tests, currently disabled It("[Skipped][Horizontal pod autoscaling Suite] should scale from 1 pod to 3 pods (scale resource: CPU)", func() { - rc = NewResourceConsumer("rc", 1, 700, f) - createHorizontalPodAutoscaler(rc, "0.3") + rc = NewDynamicResourceConsumer("rc", 1, 700, 0, 800, 100, f) + defer rc.CleanUp() + createCPUHorizontalPodAutoscaler(rc, "0.3") rc.WaitForReplicas(3) - rc.CleanUp() }) It("[Skipped][Horizontal pod autoscaling Suite] should scale from 3 pods to 1 pod (scale resource: CPU)", func() { - rc = NewResourceConsumer("rc", 3, 0, f) - createHorizontalPodAutoscaler(rc, "0.7") + rc = NewDynamicResourceConsumer("rc", 3, 0, 0, 100, 100, f) + defer rc.CleanUp() + createCPUHorizontalPodAutoscaler(rc, "0.7") rc.WaitForReplicas(1) - rc.CleanUp() }) It("[Skipped][Horizontal pod autoscaling Suite] should scale from 1 pod to maximum 5 pods (scale resource: CPU)", func() { - rc = NewResourceConsumer("rc", 1, 700, f) - createHorizontalPodAutoscaler(rc, "0.1") + rc = NewDynamicResourceConsumer("rc", 1, 700, 0, 800, 100, f) + defer rc.CleanUp() + createCPUHorizontalPodAutoscaler(rc, "0.1") rc.WaitForReplicas(5) - rc.CleanUp() }) It("[Skipped][Horizontal pod autoscaling Suite] should scale from 1 pod to 3 pods and from 3 to 1 (scale resource: CPU)", func() { - rc = NewResourceConsumer("rc", 1, 700, f) - createHorizontalPodAutoscaler(rc, "0.3") + rc = NewDynamicResourceConsumer("rc", 1, 700, 0, 800, 100, f) + defer rc.CleanUp() + createCPUHorizontalPodAutoscaler(rc, "0.3") rc.WaitForReplicas(3) rc.ConsumeCPU(300) rc.WaitForReplicas(1) - rc.CleanUp() - }) - - It("[Skipped][Horizontal pod autoscaling Suite] should scale from 1 pod to 3 pods and from 3 to 5 (scale resource: CPU)", func() { - rc = NewResourceConsumer("rc", 1, 300, f) - createHorizontalPodAutoscaler(rc, "0.1") - rc.WaitForReplicas(3) - rc.ConsumeCPU(700) - rc.WaitForReplicas(5) - rc.CleanUp() }) It("[Skipped][Horizontal pod autoscaling Suite] should scale from 3 pods to 1 pod and from 1 to 3 (scale resource: CPU)", func() { - rc = NewResourceConsumer("rc", 3, 0, f) - createHorizontalPodAutoscaler(rc, "0.3") + rc = NewDynamicResourceConsumer("rc", 3, 0, 0, 800, 100, f) + defer rc.CleanUp() + createCPUHorizontalPodAutoscaler(rc, "0.3") rc.WaitForReplicas(1) rc.ConsumeCPU(700) rc.WaitForReplicas(3) - rc.CleanUp() }) - It("[Skipped][Horizontal pod autoscaling Suite] should scale from 5 pods to 3 pods and from 3 to 1 (scale resource: CPU)", func() { - rc = NewResourceConsumer("rc", 5, 700, f) - createHorizontalPodAutoscaler(rc, "0.3") + It("[Skipped][Horizontal pod autoscaling Suite] should scale from 1 pod to 3 pods (scale resource: Memory)", func() { + rc = NewDynamicResourceConsumer("rc", 1, 0, 800, 100, 900, f) + defer rc.CleanUp() + createMemoryHorizontalPodAutoscaler(rc, "300") rc.WaitForReplicas(3) - rc.ConsumeCPU(100) + }) + + It("[Skipped][Horizontal pod autoscaling Suite] should scale from 3 pods to 1 pod (scale resource: Memory)", func() { + rc = NewDynamicResourceConsumer("rc", 3, 0, 0, 100, 100, f) + defer rc.CleanUp() + createMemoryHorizontalPodAutoscaler(rc, "700") rc.WaitForReplicas(1) - rc.CleanUp() }) + It("[Skipped][Horizontal pod autoscaling Suite] should scale from 1 pod to 3 pods and from 3 to 1 (scale resource: Memory)", func() { + rc = NewDynamicResourceConsumer("rc", 1, 0, 700, 100, 800, f) + defer rc.CleanUp() + createMemoryHorizontalPodAutoscaler(rc, "300") + rc.WaitForReplicas(3) + rc.ConsumeMem(100) + rc.WaitForReplicas(1) + }) + + It("[Skipped][Horizontal pod autoscaling Suite] should scale from 3 pods to 1 pod and from 1 to 3 (scale resource: Memory)", func() { + rc = NewDynamicResourceConsumer("rc", 3, 0, 0, 100, 800, f) + defer rc.CleanUp() + createMemoryHorizontalPodAutoscaler(rc, "300") + rc.WaitForReplicas(1) + rc.ConsumeMem(700) + rc.WaitForReplicas(3) + }) + + It("[Skipped][Horizontal pod autoscaling Suite] should scale from 1 pod to maximum 5 pods (scale resource: Memory)", func() { + rc = NewDynamicResourceConsumer("rc", 1, 0, 700, 100, 800, f) + defer rc.CleanUp() + createMemoryHorizontalPodAutoscaler(rc, "100") + rc.WaitForReplicas(5) + }) }) -func createHorizontalPodAutoscaler(rc *ResourceConsumer, cpu string) { - hpa := &experimental.HorizontalPodAutoscaler{ +func createCPUHorizontalPodAutoscaler(rc *ResourceConsumer, cpu string) { + hpa := &extensions.HorizontalPodAutoscaler{ + ObjectMeta: api.ObjectMeta{ + Name: rc.name, + Namespace: rc.framework.Namespace.Name, + }, + Spec: extensions.HorizontalPodAutoscalerSpec{ + ScaleRef: &extensions.SubresourceReference{ + Kind: kind, + Name: rc.name, + Namespace: rc.framework.Namespace.Name, + Subresource: subresource, + }, + MinReplicas: 1, + MaxReplicas: 5, + Target: extensions.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse(cpu)}, + }, + } + _, errHPA := rc.framework.Client.Extensions().HorizontalPodAutoscalers(rc.framework.Namespace.Name).Create(hpa) + expectNoError(errHPA) +} + +// argument memory is in megabytes +func createMemoryHorizontalPodAutoscaler(rc *ResourceConsumer, memory string) { + hpa := &extensions.HorizontalPodAutoscaler{ ObjectMeta: api.ObjectMeta{ Name: rc.name, Namespace: rc.framework.Namespace.Name, }, - Spec: experimental.HorizontalPodAutoscalerSpec{ - ScaleRef: &experimental.SubresourceReference{ - Kind: "replicationController", + Spec: extensions.HorizontalPodAutoscalerSpec{ + ScaleRef: &extensions.SubresourceReference{ + Kind: kind, Name: rc.name, Namespace: rc.framework.Namespace.Name, - Subresource: "scale", + Subresource: subresource, }, - MinCount: 1, - MaxCount: 5, - Target: experimental.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse(cpu)}, + MinReplicas: 1, + MaxReplicas: 5, + Target: extensions.ResourceConsumption{Resource: api.ResourceMemory, Quantity: resource.MustParse(memory + "M")}, }, } - _, errHPA := rc.framework.Client.Experimental().HorizontalPodAutoscalers(rc.framework.Namespace.Name).Create(hpa) + _, errHPA := rc.framework.Client.Extensions().HorizontalPodAutoscalers(rc.framework.Namespace.Name).Create(hpa) expectNoError(errHPA) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/host_path.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/host_path.go index 6e55c62bd5a0..9db3e9c682f3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/host_path.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/host_path.go @@ -18,11 +18,14 @@ package e2e import ( "fmt" + "os" + "path" + "time" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" - "os" - "path" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -51,12 +54,12 @@ var _ = Describe("hostPath", func() { AfterEach(func() { By(fmt.Sprintf("Destroying namespace for this suite %v", namespace.Name)) - if err := deleteNS(c, namespace.Name); err != nil { + if err := deleteNS(c, namespace.Name, 5*time.Minute /* namespace deletion timeout */); err != nil { Failf("Couldn't delete ns %s", err) } }) - It("should give a volume the correct mode", func() { + It("should give a volume the correct mode [Conformance]", func() { volumePath := "/test-volume" source := &api.HostPathVolumeSource{ Path: "/tmp", @@ -67,13 +70,13 @@ var _ = Describe("hostPath", func() { fmt.Sprintf("--fs_type=%v", volumePath), fmt.Sprintf("--file_mode=%v", volumePath), } - testContainerOutputInNamespace("hostPath mode", c, pod, 0, []string{ + testContainerOutput("hostPath mode", c, pod, 0, []string{ "mode of file \"/test-volume\": dtrwxrwxrwx", // we expect the sticky bit (mode flag t) to be set for the dir }, namespace.Name) }) - It("should support r/w", func() { + It("should support r/w [Conformance]", func() { volumePath := "/test-volume" filePath := path.Join(volumePath, "test-file") retryDuration := 180 @@ -93,7 +96,7 @@ var _ = Describe("hostPath", func() { } //Read the content of the file with the second container to //verify volumes being shared properly among continers within the pod. - testContainerOutputInNamespace("hostPath r/w", c, pod, 1, []string{ + testContainerOutput("hostPath r/w", c, pod, 1, []string{ "content of file \"/test-volume/test-file\": mount-tester new file", }, namespace.Name, ) @@ -121,9 +124,9 @@ func testPodWithHostVol(path string, source *api.HostPathVolumeSource) *api.Pod podName := "pod-host-path-test" return &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", - APIVersion: latest.Version, + APIVersion: latest.GroupOrDie("").Version, }, ObjectMeta: api.ObjectMeta{ Name: podName, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/initial_resources.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/initial_resources.go new file mode 100644 index 000000000000..c573ec7a0322 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/initial_resources.go @@ -0,0 +1,75 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 e2e + +import ( + "fmt" + "time" + + influxdb "github.com/influxdb/influxdb/client" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "k8s.io/kubernetes/pkg/api" +) + +var _ = Describe("Initial Resources", func() { + f := NewFramework("initial-resources") + + It("[Skipped] should set initial resources based on historical data", func() { + // Cleanup data in InfluxDB that left from previous tests. + influxdbClient, err := getInfluxdbClient(f.Client) + expectNoError(err, "failed to create influxdb client") + _, err = influxdbClient.Query("drop series autoscaling.cpu.usage.2m", influxdb.Second) + expectNoError(err) + _, err = influxdbClient.Query("drop series autoscaling.memory.usage.2m", influxdb.Second) + expectNoError(err) + + cpu := 100 + mem := 200 + for i := 0; i < 10; i++ { + rc := NewStaticResourceConsumer(fmt.Sprintf("ir-%d", i), 1, cpu, mem, int64(2*cpu), int64(2*mem), f) + defer rc.CleanUp() + } + // Wait some time to make sure usage data is gathered. + time.Sleep(10 * time.Minute) + + pod := runPod(f, "ir-test", resourceConsumerImage) + r := pod.Spec.Containers[0].Resources.Requests + Expect(r.Cpu().MilliValue()).Should(BeNumerically("~", cpu, 10)) + Expect(r.Memory().Value()).Should(BeNumerically("~", mem*1024*1024, 20*1024*1024)) + }) +}) + +func runPod(f *Framework, name, image string) *api.Pod { + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: name, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: name, + Image: image, + }, + }, + }, + } + createdPod, err := f.Client.Pods(f.Namespace.Name).Create(pod) + expectNoError(err) + expectNoError(waitForPodRunningInNamespace(f.Client, name, f.Namespace.Name)) + return createdPod +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/job.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/job.go new file mode 100644 index 000000000000..9554121436b2 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/job.go @@ -0,0 +1,261 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 e2e + +import ( + "time" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/apis/extensions" + client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/kubectl" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/util/wait" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +const ( + // How long to wait for a job to finish. + jobTimeout = 15 * time.Minute + + // Job selector name + jobSelectorKey = "job" +) + +// TODO: Activate these tests for GKE when we support experimental APIs there. +var _ = Describe("Job", func() { + f := NewFramework("job") + parallelism := 2 + completions := 4 + lotsOfFailures := 5 // more than completions + + // Simplest case: all pods succeed promptly + It("should run a job to completion when tasks succeed", func() { + SkipIfProviderIs("gke") + By("Creating a job") + job := newTestJob("succeed", "all-succeed", api.RestartPolicyNever, parallelism, completions) + job, err := createJob(f.Client, f.Namespace.Name, job) + Expect(err).NotTo(HaveOccurred()) + + By("Ensuring job reaches completions") + err = waitForJobFinish(f.Client, f.Namespace.Name, job.Name, completions) + Expect(err).NotTo(HaveOccurred()) + }) + + // Pods sometimes fail, but eventually succeed. + It("should run a job to completion when tasks sometimes fail and are locally restarted", func() { + SkipIfProviderIs("gke") + By("Creating a job") + // 50% chance of container success, local restarts. + job := newTestJob("randomlySucceedOrFail", "rand-local", api.RestartPolicyOnFailure, parallelism, completions) + job, err := createJob(f.Client, f.Namespace.Name, job) + Expect(err).NotTo(HaveOccurred()) + + By("Ensuring job reaches completions") + err = waitForJobFinish(f.Client, f.Namespace.Name, job.Name, completions) + Expect(err).NotTo(HaveOccurred()) + }) + + // Pods sometimes fail, but eventually succeed, after pod restarts + It("should run a job to completion when tasks sometimes fail and are not locally restarted", func() { + SkipIfProviderIs("gke") + By("Creating a job") + // 50% chance of container success, local restarts. + job := newTestJob("randomlySucceedOrFail", "rand-non-local", api.RestartPolicyNever, parallelism, completions) + job, err := createJob(f.Client, f.Namespace.Name, job) + Expect(err).NotTo(HaveOccurred()) + + By("Ensuring job reaches completions") + err = waitForJobFinish(f.Client, f.Namespace.Name, job.Name, completions) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should keep restarting failed pods", func() { + SkipIfProviderIs("gke") + By("Creating a job") + job := newTestJob("fail", "all-fail", api.RestartPolicyNever, parallelism, completions) + job, err := createJob(f.Client, f.Namespace.Name, job) + Expect(err).NotTo(HaveOccurred()) + + By("Ensuring job shows many failures") + err = wait.Poll(poll, jobTimeout, func() (bool, error) { + curr, err := f.Client.Extensions().Jobs(f.Namespace.Name).Get(job.Name) + if err != nil { + return false, err + } + return curr.Status.Failed > lotsOfFailures, nil + }) + }) + + It("should scale a job up", func() { + SkipIfProviderIs("gke") + startParallelism := 1 + endParallelism := 2 + By("Creating a job") + job := newTestJob("notTerminate", "scale-up", api.RestartPolicyNever, startParallelism, completions) + job, err := createJob(f.Client, f.Namespace.Name, job) + Expect(err).NotTo(HaveOccurred()) + + By("Ensuring active pods == startParallelism") + err = waitForAllPodsRunning(f.Client, f.Namespace.Name, job.Name, startParallelism) + Expect(err).NotTo(HaveOccurred()) + + By("scale job up") + scaler, err := kubectl.ScalerFor("Job", f.Client) + Expect(err).NotTo(HaveOccurred()) + waitForScale := kubectl.NewRetryParams(5*time.Second, 1*time.Minute) + waitForReplicas := kubectl.NewRetryParams(5*time.Second, 5*time.Minute) + scaler.Scale(f.Namespace.Name, job.Name, uint(endParallelism), nil, waitForScale, waitForReplicas) + Expect(err).NotTo(HaveOccurred()) + + By("Ensuring active pods == endParallelism") + err = waitForAllPodsRunning(f.Client, f.Namespace.Name, job.Name, endParallelism) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should scale a job down", func() { + SkipIfProviderIs("gke") + startParallelism := 2 + endParallelism := 1 + By("Creating a job") + job := newTestJob("notTerminate", "scale-down", api.RestartPolicyNever, startParallelism, completions) + job, err := createJob(f.Client, f.Namespace.Name, job) + Expect(err).NotTo(HaveOccurred()) + + By("Ensuring active pods == startParallelism") + err = waitForAllPodsRunning(f.Client, f.Namespace.Name, job.Name, startParallelism) + Expect(err).NotTo(HaveOccurred()) + + By("scale job down") + scaler, err := kubectl.ScalerFor("Job", f.Client) + Expect(err).NotTo(HaveOccurred()) + waitForScale := kubectl.NewRetryParams(5*time.Second, 1*time.Minute) + waitForReplicas := kubectl.NewRetryParams(5*time.Second, 5*time.Minute) + err = scaler.Scale(f.Namespace.Name, job.Name, uint(endParallelism), nil, waitForScale, waitForReplicas) + Expect(err).NotTo(HaveOccurred()) + + By("Ensuring active pods == endParallelism") + err = waitForAllPodsRunning(f.Client, f.Namespace.Name, job.Name, endParallelism) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should stop a job", func() { + SkipIfProviderIs("gke") + By("Creating a job") + job := newTestJob("notTerminate", "foo", api.RestartPolicyNever, parallelism, completions) + job, err := createJob(f.Client, f.Namespace.Name, job) + Expect(err).NotTo(HaveOccurred()) + + By("Ensuring active pods == parallelism") + err = waitForAllPodsRunning(f.Client, f.Namespace.Name, job.Name, parallelism) + Expect(err).NotTo(HaveOccurred()) + + By("scale job down") + reaper, err := kubectl.ReaperFor("Job", f.Client) + Expect(err).NotTo(HaveOccurred()) + timeout := 1 * time.Minute + _, err = reaper.Stop(f.Namespace.Name, job.Name, timeout, api.NewDeleteOptions(0)) + Expect(err).NotTo(HaveOccurred()) + + By("Ensuring job was deleted") + _, err = f.Client.Extensions().Jobs(f.Namespace.Name).Get(job.Name) + Expect(err).To(HaveOccurred()) + Expect(errors.IsNotFound(err)).To(BeTrue()) + }) +}) + +// newTestJob returns a job which does one of several testing behaviors. +func newTestJob(behavior, name string, rPol api.RestartPolicy, parallelism, completions int) *extensions.Job { + job := &extensions.Job{ + ObjectMeta: api.ObjectMeta{ + Name: name, + }, + Spec: extensions.JobSpec{ + Parallelism: ¶llelism, + Completions: &completions, + Template: api.PodTemplateSpec{ + ObjectMeta: api.ObjectMeta{ + Labels: map[string]string{jobSelectorKey: name}, + }, + Spec: api.PodSpec{ + RestartPolicy: rPol, + Containers: []api.Container{ + { + Name: "c", + Image: "gcr.io/google_containers/busybox", + Command: []string{}, + }, + }, + }, + }, + }, + } + switch behavior { + case "notTerminate": + job.Spec.Template.Spec.Containers[0].Command = []string{"sleep", "1000000"} + case "fail": + job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "exit 1"} + case "succeed": + job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "exit 0"} + case "randomlySucceedOrFail": + // Bash's $RANDOM generates pseudorandom int in range 0 - 32767. + // Dividing by 16384 gives roughly 50/50 chance of succeess. + job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "exit $(( $RANDOM / 16384 ))"} + } + return job +} + +func createJob(c *client.Client, ns string, job *extensions.Job) (*extensions.Job, error) { + return c.Extensions().Jobs(ns).Create(job) +} + +func deleteJob(c *client.Client, ns, name string) error { + return c.Extensions().Jobs(ns).Delete(name, api.NewDeleteOptions(0)) +} + +// Wait for all pods to become Running. Only use when pods will run for a long time, or it will be racy. +func waitForAllPodsRunning(c *client.Client, ns, jobName string, parallelism int) error { + label := labels.SelectorFromSet(labels.Set(map[string]string{jobSelectorKey: jobName})) + return wait.Poll(poll, jobTimeout, func() (bool, error) { + pods, err := c.Pods(ns).List(label, fields.Everything()) + if err != nil { + return false, err + } + count := 0 + for _, p := range pods.Items { + if p.Status.Phase == api.PodRunning { + count++ + } + } + return count == parallelism, nil + }) +} + +// Wait for job to reach completions. +func waitForJobFinish(c *client.Client, ns, jobName string, completions int) error { + return wait.Poll(poll, jobTimeout, func() (bool, error) { + curr, err := c.Extensions().Jobs(ns).Get(jobName) + if err != nil { + return false, err + } + return curr.Status.Succeeded == completions, nil + }) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/k8petstore.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/k8petstore.go new file mode 100644 index 000000000000..30b59b7ca925 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/k8petstore.go @@ -0,0 +1,170 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 e2e + +import ( + "fmt" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "log" + "os" + "os/exec" + "path/filepath" + "strconv" + "syscall" + "time" +) + +const ( + k8bpsContainerVersion = "r.2.8.19" // Container version, see the examples/k8petstore dockerfiles for details. + k8bpsThroughputDummy = "0" // Polling time = 0, since we poll in ginkgo rather than using the shell script tests. + k8bpsRedisSlaves = "1" // Number of redis slaves. + k8bpsDontRunTest = "0" // Don't bother embedded test. + k8bpsStartupTimeout = 30 * time.Second // Amount of elapsed time before petstore transactions are being stored. + + // Constants for the first test. We can make this a hashmap once we add scale tests to it. + k8bpsSmokeTestTransactions = 50 + k8bpsSmokeTestTimeout = 60 * time.Second +) + +// readTransactions reads # of transactions from the k8petstore web server endpoint. +// for more details see the source of the k8petstore web server. +func readTransactions(c *unversioned.Client, ns string) (error, int) { + body, err := c.Get(). + Namespace(ns). + Prefix("proxy"). + Resource("services"). + Name("frontend"). + Suffix("llen"). + DoRaw() + if err != nil { + return err, -1 + } else { + totalTrans, err := strconv.Atoi(string(body)) + return err, totalTrans + } +} + +// runK8petstore runs the k8petstore application, bound to external nodeport, and +// polls until minExpected transactions are acquired, in a maximum of maxSeconds. +func runK8petstore(restServers int, loadGenerators int, c *unversioned.Client, ns string, minExpected int, maxTime time.Duration) { + + var err error = nil + k8bpsScriptLocation := filepath.Join(testContext.RepoRoot, "examples/k8petstore/k8petstore-nodeport.sh") + + cmd := exec.Command( + k8bpsScriptLocation, + testContext.KubectlPath, + k8bpsContainerVersion, + k8bpsThroughputDummy, + strconv.Itoa(restServers), + strconv.Itoa(loadGenerators), + k8bpsRedisSlaves, + k8bpsDontRunTest, // Don't bother embedded test. + ns, + ) + + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + Logf("Starting k8petstore application....") + // Run the k8petstore app, and log / fail if it returns any errors. + // This should return quickly, assuming containers are downloaded. + if err = cmd.Start(); err != nil { + log.Fatal(err) + } + // Make sure there are no command errors. + if err = cmd.Wait(); err != nil { + if exiterr, ok := err.(*exec.ExitError); ok { + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + log.Printf("Exit Status: %d", status.ExitStatus()) + } + } + } + Expect(err).NotTo(HaveOccurred()) + Logf("... Done starting k8petstore ") + + totalTransactions := 0 + Logf("Start polling, timeout is %v seconds", maxTime) + + // How long until the FIRST transactions are created. + startupTimeout := time.After(time.Duration(k8bpsStartupTimeout)) + + // Maximum time to wait until we reach the nth transaction. + transactionsCompleteTimeout := time.After(time.Duration(maxTime)) + tick := time.Tick(2 * time.Second) + var ready = false + + Logf("Now waiting %v seconds to see progress (transactions > 3)", k8bpsStartupTimeout) +T: + for { + select { + case <-transactionsCompleteTimeout: + Logf("Timeout %v reached, transactions not complete. Breaking!", tick) + break T + case <-startupTimeout: + err, totalTransactions = readTransactions(c, ns) + Logf("Timeout %v reached. Checking if transactions have occured.", startupTimeout) + // If we don't have 3 transactions, fail the test. + if err != nil { + Logf("Failed : Error %v", err) + break T + } + if totalTransactions < 3 { + break T + } + ready = true + case <-tick: + // Pass if we've collected enough transactions + err, totalTransactions = readTransactions(c, ns) + if ready { + Expect(err).NotTo(HaveOccurred()) + } + if totalTransactions > minExpected { + break T + } + Logf("Time: %v, %v = total petstore transactions stored into redis.", time.Now(), totalTransactions) + } + } + + // We should have exceeded the minExpected num of transactions. + // If this fails, but there are transactions being created, we may need to recalibrate + // the minExpected value - or else - your cluster is broken/slow ! + Ω(totalTransactions).Should(BeNumerically(">", minExpected)) +} + +var _ = Describe("[Skipped][Example] Pet Store", func() { + + // The number of minions dictates total number of generators/transaction expectations. + var minionCount int + f := NewFramework("petstore") + + It(fmt.Sprintf("should scale to persist a nominal number ( %v ) of transactions in %v seconds", k8bpsSmokeTestTransactions, k8bpsSmokeTestTimeout), func() { + minions, err := f.Client.Nodes().List(labels.Everything(), fields.Everything()) + Expect(err).NotTo(HaveOccurred()) + minionCount = len(minions.Items) + + loadGenerators := minionCount + restServers := minionCount + fmt.Printf("load generators / rest servers [ %v / %v ] ", loadGenerators, restServers) + runK8petstore(restServers, loadGenerators, f.Client, f.Namespace.Name, k8bpsSmokeTestTransactions, k8bpsSmokeTestTimeout) + }) + +}) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kube-ui.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kube-ui.go index cf859a0b3bb3..a6c113e4ba96 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kube-ui.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kube-ui.go @@ -38,7 +38,7 @@ var _ = Describe("kube-ui", func() { f := NewFramework("kube-ui") - It("should check that the kube-ui instance is alive", func() { + It("should check that the kube-ui instance is alive [Conformance]", func() { By("Checking the kube-ui service exists.") err := waitForService(f.Client, uiNamespace, uiServiceName, true, poll, serviceStartTimeout) Expect(err).NotTo(HaveOccurred()) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubectl.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubectl.go index 411668119545..e64e83564bf5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubectl.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubectl.go @@ -17,6 +17,7 @@ limitations under the License. package e2e import ( + "bytes" "encoding/json" "errors" "fmt" @@ -32,10 +33,16 @@ import ( "strings" "time" + "github.com/ghodss/yaml" + "k8s.io/kubernetes/pkg/api" + apierrs "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/util/wait" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -58,10 +65,7 @@ const ( simplePodPort = 80 ) -var ( - portForwardRegexp = regexp.MustCompile("Forwarding from 127.0.0.1:([0-9]+) -> 80") - proxyRegexp = regexp.MustCompile("Starting to serve on 127.0.0.1:([0-9]+)") -) +var proxyRegexp = regexp.MustCompile("Starting to serve on 127.0.0.1:([0-9]+)") var _ = Describe("Kubectl client", func() { defer GinkgoRecover() @@ -79,7 +83,7 @@ var _ = Describe("Kubectl client", func() { AfterEach(func() { By(fmt.Sprintf("Destroying namespace for this suite %v", ns)) - if err := deleteNS(c, ns); err != nil { + if err := deleteNS(c, ns, 5*time.Minute /* namespace deletion timeout */); err != nil { Failf("Couldn't delete ns %s", err) } }) @@ -91,7 +95,7 @@ var _ = Describe("Kubectl client", func() { nautilusPath = filepath.Join(updateDemoRoot, "nautilus-rc.yaml") kittenPath = filepath.Join(updateDemoRoot, "kitten-rc.yaml") }) - It("should create and stop a replication controller", func() { + It("should create and stop a replication controller [Conformance]", func() { defer cleanup(nautilusPath, ns, updateDemoSelector) By("creating a replication controller") @@ -99,7 +103,7 @@ var _ = Describe("Kubectl client", func() { validateController(c, nautilusImage, 2, "update-demo", updateDemoSelector, getUDData("nautilus.jpg", ns), ns) }) - It("should scale a replication controller", func() { + It("should scale a replication controller [Conformance]", func() { defer cleanup(nautilusPath, ns, updateDemoSelector) By("creating a replication controller") @@ -113,7 +117,7 @@ var _ = Describe("Kubectl client", func() { validateController(c, nautilusImage, 2, "update-demo", updateDemoSelector, getUDData("nautilus.jpg", ns), ns) }) - It("should do a rolling update of a replication controller", func() { + It("should do a rolling update of a replication controller [Conformance]", func() { By("creating the initial replication controller") runKubectl("create", "-f", nautilusPath, fmt.Sprintf("--namespace=%v", ns)) validateController(c, nautilusImage, 2, "update-demo", updateDemoSelector, getUDData("nautilus.jpg", ns), ns) @@ -131,7 +135,7 @@ var _ = Describe("Kubectl client", func() { guestbookPath = filepath.Join(testContext.RepoRoot, "examples/guestbook") }) - It("should create and stop a working application", func() { + It("should create and stop a working application [Conformance]", func() { defer cleanup(guestbookPath, ns, frontendSelector, redisMasterSelector, redisSlaveSelector) By("creating all guestbook components") @@ -198,32 +202,11 @@ var _ = Describe("Kubectl client", func() { It("should support port-forward", func() { By("forwarding the container port to a local port") - cmd := kubectlCmd("port-forward", fmt.Sprintf("--namespace=%v", ns), simplePodName, fmt.Sprintf(":%d", simplePodPort)) + cmd, listenPort := runPortForward(ns, simplePodName, simplePodPort) defer tryKill(cmd) - // This is somewhat ugly but is the only way to retrieve the port that was picked - // by the port-forward command. We don't want to hard code the port as we have no - // way of guaranteeing we can pick one that isn't in use, particularly on Jenkins. - Logf("starting port-forward command and streaming output") - stdout, stderr, err := startCmdAndStreamOutput(cmd) - if err != nil { - Failf("Failed to start port-forward command: %v", err) - } - defer stdout.Close() - defer stderr.Close() - buf := make([]byte, 128) - var n int - Logf("reading from `kubectl port-forward` command's stderr") - if n, err = stderr.Read(buf); err != nil { - Failf("Failed to read from kubectl port-forward stderr: %v", err) - } - portForwardOutput := string(buf[:n]) - match := portForwardRegexp.FindStringSubmatch(portForwardOutput) - if len(match) != 2 { - Failf("Failed to parse kubectl port-forward output: %s", portForwardOutput) - } By("curling local port output") - localAddr := fmt.Sprintf("http://localhost:%s", match[1]) + localAddr := fmt.Sprintf("http://localhost:%d", listenPort) body, err := curl(localAddr) Logf("got: %s", body) if err != nil { @@ -236,7 +219,7 @@ var _ = Describe("Kubectl client", func() { }) Describe("Kubectl api-versions", func() { - It("should check if v1 is in available api versions", func() { + It("should check if v1 is in available api versions [Conformance]", func() { By("validating api verions") output := runKubectl("api-versions") if !strings.Contains(output, "Available Server Api Versions:") { @@ -248,8 +231,27 @@ var _ = Describe("Kubectl client", func() { }) }) + Describe("Kubectl apply", func() { + It("should apply a new configuration to an existing RC", func() { + mkpath := func(file string) string { + return filepath.Join(testContext.RepoRoot, "examples/guestbook-go", file) + } + controllerJson := mkpath("redis-master-controller.json") + nsFlag := fmt.Sprintf("--namespace=%v", ns) + By("creating Redis RC") + runKubectl("create", "-f", controllerJson, nsFlag) + By("applying a modified configuration") + stdin := modifyReplicationControllerConfiguration(controllerJson) + newKubectlCommand("apply", "-f", "-", nsFlag). + withStdinReader(stdin). + exec() + By("checking the result") + forEachReplicationController(c, ns, "app", "redis", validateReplicationControllerConfiguration) + }) + }) + Describe("Kubectl cluster-info", func() { - It("should check if Kubernetes master services is included in cluster-info", func() { + It("should check if Kubernetes master services is included in cluster-info [Conformance]", func() { By("validating cluster-info") output := runKubectl("cluster-info") // Can't check exact strings due to terminal control commands (colors) @@ -266,7 +268,7 @@ var _ = Describe("Kubectl client", func() { }) Describe("Kubectl describe", func() { - It("should check if kubectl describe prints relevant information for rc and pods", func() { + It("should check if kubectl describe prints relevant information for rc and pods [Conformance]", func() { mkpath := func(file string) string { return filepath.Join(testContext.RepoRoot, "examples/guestbook-go", file) } @@ -322,9 +324,9 @@ var _ = Describe("Kubectl client", func() { checkOutput(output, requiredStrings) // Node - minions, err := c.Nodes().List(labels.Everything(), fields.Everything()) + nodes, err := c.Nodes().List(labels.Everything(), fields.Everything()) Expect(err).NotTo(HaveOccurred()) - node := minions.Items[0] + node := nodes.Items[0] output = runKubectl("describe", "node", node.Name) requiredStrings = [][]string{ {"Name:", node.Name}, @@ -356,7 +358,7 @@ var _ = Describe("Kubectl client", func() { }) Describe("Kubectl expose", func() { - It("should create services for rc", func() { + It("should create services for rc [Conformance]", func() { mkpath := func(file string) string { return filepath.Join(testContext.RepoRoot, "examples/guestbook-go", file) } @@ -364,7 +366,6 @@ var _ = Describe("Kubectl client", func() { nsFlag := fmt.Sprintf("--namespace=%v", ns) redisPort := 6379 - serviceTimeout := 60 * time.Second By("creating Redis RC") runKubectl("create", "-f", controllerJson, nsFlag) @@ -372,30 +373,33 @@ var _ = Describe("Kubectl client", func() { lookForStringInLog(ns, pod.Name, "redis-master", "The server is now ready to accept connections", podStartTimeout) }) validateService := func(name string, servicePort int, timeout time.Duration) { - endpointFound := false - for t := time.Now(); time.Since(t) < timeout; time.Sleep(poll) { + err := wait.Poll(poll, timeout, func() (bool, error) { endpoints, err := c.Endpoints(ns).Get(name) - Expect(err).NotTo(HaveOccurred()) + if err != nil { + if apierrs.IsNotFound(err) { + err = nil + } + Logf("Get endpoints failed (interval %v): %v", poll, err) + return false, err + } uidToPort := getContainerPortsByPodUID(endpoints) if len(uidToPort) == 0 { Logf("No endpoint found, retrying") - continue + return false, nil } if len(uidToPort) > 1 { - Fail("To many endpoints found") + Fail("Too many endpoints found") } for _, port := range uidToPort { if port[0] != redisPort { Failf("Wrong endpoint port: %d", port[0]) } } - endpointFound = true - break - } - if !endpointFound { - Failf("1 endpoint is expected") - } + return true, nil + }) + Expect(err).NotTo(HaveOccurred()) + service, err := c.Services(ns).Get(name) Expect(err).NotTo(HaveOccurred()) @@ -413,13 +417,13 @@ var _ = Describe("Kubectl client", func() { By("exposing RC") runKubectl("expose", "rc", "redis-master", "--name=rm2", "--port=1234", fmt.Sprintf("--target-port=%d", redisPort), nsFlag) - waitForService(c, ns, "rm2", true, poll, serviceTimeout) - validateService("rm2", 1234, serviceTimeout) + waitForService(c, ns, "rm2", true, poll, serviceStartTimeout) + validateService("rm2", 1234, serviceStartTimeout) By("exposing service") runKubectl("expose", "service", "rm2", "--name=rm3", "--port=2345", fmt.Sprintf("--target-port=%d", redisPort), nsFlag) - waitForService(c, ns, "rm3", true, poll, serviceTimeout) - validateService("rm3", 2345, serviceTimeout) + waitForService(c, ns, "rm3", true, poll, serviceStartTimeout) + validateService("rm3", 2345, serviceStartTimeout) }) }) @@ -437,7 +441,7 @@ var _ = Describe("Kubectl client", func() { cleanup(podPath, ns, simplePodSelector) }) - It("should update the label on a resource", func() { + It("should update the label on a resource [Conformance]", func() { labelName := "testing-label" labelValue := "testing-label-value" @@ -460,24 +464,63 @@ var _ = Describe("Kubectl client", func() { }) Describe("Kubectl logs", func() { - It("should find a string in pod logs", func() { + var rcPath string + var nsFlag string + containerName := "redis-master" + BeforeEach(func() { mkpath := func(file string) string { return filepath.Join(testContext.RepoRoot, "examples/guestbook-go", file) } - controllerJson := mkpath("redis-master-controller.json") - nsFlag := fmt.Sprintf("--namespace=%v", ns) - By("creating Redis RC") - runKubectl("create", "-f", controllerJson, nsFlag) - By("checking logs") + rcPath = mkpath("redis-master-controller.json") + By("creating an rc") + nsFlag = fmt.Sprintf("--namespace=%v", ns) + runKubectl("create", "-f", rcPath, nsFlag) + }) + AfterEach(func() { + cleanup(rcPath, ns, simplePodSelector) + }) + + It("should be able to retrieve and filter logs [Conformance]", func() { forEachPod(c, ns, "app", "redis", func(pod api.Pod) { - _, err := lookForStringInLog(ns, pod.Name, "redis-master", "The server is now ready to accept connections", podStartTimeout) + By("checking for a matching strings") + _, err := lookForStringInLog(ns, pod.Name, containerName, "The server is now ready to accept connections", podStartTimeout) Expect(err).NotTo(HaveOccurred()) + + By("limiting log lines") + out := runKubectl("log", pod.Name, containerName, nsFlag, "--tail=1") + Expect(len(out)).NotTo(BeZero()) + Expect(len(strings.Split(out, "\n"))).To(Equal(1)) + + By("limiting log bytes") + out = runKubectl("log", pod.Name, containerName, nsFlag, "--limit-bytes=1") + Expect(len(strings.Split(out, "\n"))).To(Equal(1)) + Expect(len(out)).To(Equal(1)) + + By("exposing timestamps") + out = runKubectl("log", pod.Name, containerName, nsFlag, "--tail=1", "--timestamps") + lines := strings.Split(out, "\n") + Expect(len(lines)).To(Equal(1)) + words := strings.Split(lines[0], " ") + Expect(len(words)).To(BeNumerically(">", 1)) + if _, err := time.Parse(time.RFC3339Nano, words[0]); err != nil { + if _, err := time.Parse(time.RFC3339, words[0]); err != nil { + Failf("expected %q to be RFC3339 or RFC3339Nano", words[0]) + } + } + + By("restricting to a time range") + time.Sleep(1500 * time.Millisecond) // ensure that startup logs on the node are seen as older than 1s + out = runKubectl("log", pod.Name, containerName, nsFlag, "--since=1s") + recent := len(strings.Split(out, "\n")) + out = runKubectl("log", pod.Name, containerName, nsFlag, "--since=24h") + older := len(strings.Split(out, "\n")) + Expect(recent).To(BeNumerically("<", older)) }) }) }) Describe("Kubectl patch", func() { - It("should add annotations for pods in rc", func() { + It("should add annotations for pods in rc [Conformance]", func() { mkpath := func(file string) string { return filepath.Join(testContext.RepoRoot, "examples/guestbook-go", file) } @@ -506,7 +549,7 @@ var _ = Describe("Kubectl client", func() { }) Describe("Kubectl version", func() { - It("should check is all data is printed", func() { + It("should check is all data is printed [Conformance]", func() { version := runKubectl("version") requiredItems := []string{"Client Version:", "Server Version:", "Major:", "Minor:", "GitCommit:"} for _, item := range requiredItems { @@ -530,7 +573,7 @@ var _ = Describe("Kubectl client", func() { runKubectl("stop", "rc", rcName, nsFlag) }) - It("should create an rc from an image", func() { + It("should create an rc from an image [Conformance]", func() { image := "nginx" By("running the image " + image) @@ -573,7 +616,7 @@ var _ = Describe("Kubectl client", func() { runKubectl("stop", "pods", podName, nsFlag) }) - It("should create a pod from an image when restart is OnFailure", func() { + It("should create a pod from an image when restart is OnFailure [Conformance]", func() { image := "nginx" By("running the image " + image) @@ -592,7 +635,7 @@ var _ = Describe("Kubectl client", func() { } }) - It("should create a pod from an image when restart is Never", func() { + It("should create a pod from an image when restart is Never [Conformance]", func() { image := "nginx" By("running the image " + image) @@ -615,7 +658,7 @@ var _ = Describe("Kubectl client", func() { Describe("Proxy server", func() { // TODO: test proxy options (static, prefix, etc) - It("should support proxy with --port 0", func() { + It("should support proxy with --port 0 [Conformance]", func() { By("starting the proxy server") port, cmd, err := startProxyServer() if cmd != nil { @@ -627,12 +670,15 @@ var _ = Describe("Kubectl client", func() { By("curling proxy /api/ output") localAddr := fmt.Sprintf("http://localhost:%d/api/", port) apiVersions, err := getAPIVersions(localAddr) + if err != nil { + Failf("Expected at least one supported apiversion, got error %v", err) + } if len(apiVersions.Versions) < 1 { Failf("Expected at least one supported apiversion, got %v", apiVersions) } }) - It("should support --unix-socket=/path", func() { + It("should support --unix-socket=/path [Conformance]", func() { By("Starting the proxy") tmpdir, err := ioutil.TempDir("", "kubectl-proxy-unix") if err != nil { @@ -681,12 +727,12 @@ func checkOutput(output string, required [][]string) { } } -func getAPIVersions(apiEndpoint string) (*api.APIVersions, error) { +func getAPIVersions(apiEndpoint string) (*unversioned.APIVersions, error) { body, err := curl(apiEndpoint) if err != nil { return nil, fmt.Errorf("Failed http.Get of %s: %v", apiEndpoint, err) } - var apiVersions api.APIVersions + var apiVersions unversioned.APIVersions if err := json.Unmarshal([]byte(body), &apiVersions); err != nil { return nil, fmt.Errorf("Failed to parse /api output %s: %v", body, err) } @@ -769,6 +815,7 @@ func waitForGuestbookResponse(c *client.Client, cmd, arg, expectedResponse strin if err == nil && res == expectedResponse { return true } + Logf("Failed to get response from guestbook. err: %v, response: %s", err, res) } return false } @@ -792,6 +839,77 @@ type updateDemoData struct { Image string } +const applyTestLabel = "kubectl.kubernetes.io/apply-test" + +func readBytesFromFile(filename string) []byte { + file, err := os.Open(filename) + if err != nil { + Failf(err.Error()) + } + + data, err := ioutil.ReadAll(file) + if err != nil { + Failf(err.Error()) + } + + return data +} + +func readReplicationControllerFromFile(filename string) *api.ReplicationController { + data := readBytesFromFile(filename) + rc := api.ReplicationController{} + if err := yaml.Unmarshal(data, &rc); err != nil { + Failf(err.Error()) + } + + return &rc +} + +func modifyReplicationControllerConfiguration(filename string) io.Reader { + rc := readReplicationControllerFromFile(filename) + rc.Labels[applyTestLabel] = "ADDED" + rc.Spec.Selector[applyTestLabel] = "ADDED" + rc.Spec.Template.Labels[applyTestLabel] = "ADDED" + data, err := json.Marshal(rc) + if err != nil { + Failf("json marshal failed: %s\n", err) + } + + return bytes.NewReader(data) +} + +func forEachReplicationController(c *client.Client, ns, selectorKey, selectorValue string, fn func(api.ReplicationController)) { + var rcs *api.ReplicationControllerList + var err error + for t := time.Now(); time.Since(t) < podListTimeout; time.Sleep(poll) { + rcs, err = c.ReplicationControllers(ns).List(labels.SelectorFromSet(labels.Set(map[string]string{selectorKey: selectorValue})), fields.Everything()) + Expect(err).NotTo(HaveOccurred()) + if len(rcs.Items) > 0 { + break + } + } + + if rcs == nil || len(rcs.Items) == 0 { + Failf("No replication controllers found") + } + + for _, rc := range rcs.Items { + fn(rc) + } +} + +func validateReplicationControllerConfiguration(rc api.ReplicationController) { + if rc.Name == "redis-master" { + if _, ok := rc.Annotations[kubectl.LastAppliedConfigAnnotation]; !ok { + Failf("Annotation not found in modified configuration:\n%v\n", rc) + } + + if value, ok := rc.Labels[applyTestLabel]; !ok || value != "ADDED" { + Failf("Added label %s not found in modified configuration:\n%v\n", applyTestLabel, rc) + } + } +} + // getUDData creates a validator function based on the input string (i.e. kitten.jpg). // For example, if you send "kitten.jpg", this function veridies that the image jpg = kitten.jpg // in the container's json field. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet.go index 6741e7bf63af..b719a7b2ff40 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet.go @@ -37,7 +37,6 @@ const ( pollInterval = 1 * time.Second // Interval to poll /stats/container on a node containerStatsPollingInterval = 5 * time.Second - resourceCollectionTime = 1 * time.Minute ) // getPodMatches returns a set of pod names on the given node that matches the @@ -103,7 +102,7 @@ var _ = Describe("kubelet", func() { for _, node := range nodes.Items { nodeNames.Insert(node.Name) } - resourceMonitor = newResourceMonitor(framework.Client, targetContainers, containerStatsPollingInterval) + resourceMonitor = newResourceMonitor(framework.Client, targetContainers(), containerStatsPollingInterval) resourceMonitor.Start() }) @@ -131,7 +130,7 @@ var _ = Describe("kubelet", func() { Client: framework.Client, Name: rcName, Namespace: framework.Namespace.Name, - Image: "gcr.io/google_containers/pause:go", + Image: "beta.gcr.io/google_containers/pause:2.0", Replicas: totalPods, })).NotTo(HaveOccurred()) // Perform a sanity check so that we know all desired pods are @@ -160,16 +159,4 @@ var _ = Describe("kubelet", func() { }) } }) - - Describe("Monitor resource usage on node", func() { - It("Ask kubelet to report container resource usage", func() { - // TODO: After gathering some numbers, we should set a resource - // limit for each container and fail the test if the usage exceeds - // the preset limit. - By(fmt.Sprintf("Waiting %v to collect resource usage on node", resourceCollectionTime)) - time.Sleep(resourceCollectionTime) - resourceMonitor.LogLatest() - resourceMonitor.LogCPUSummary() - }) - }) }) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet_perf.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet_perf.go new file mode 100644 index 000000000000..471b82d73333 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet_perf.go @@ -0,0 +1,143 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 e2e + +import ( + "fmt" + "time" + + client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/sets" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +const ( + // Interval to poll /stats/container on a node + containerStatsPollingPeriod = 10 * time.Second + // The monitoring time for one test. + monitoringTime = 30 * time.Minute + // The periodic reporting period. + reportingPeriod = 5 * time.Minute +) + +func logPodsOnNodes(c *client.Client, nodeNames []string) { + for _, n := range nodeNames { + podList, err := GetKubeletPods(c, n) + if err != nil { + Logf("Unable to retrieve kubelet pods for node %v", n) + continue + } + Logf("%d pods are running on node %v", len(podList.Items), n) + } +} + +func runResourceTrackingTest(framework *Framework, podsPerNode int, nodeNames sets.String, resourceMonitor *resourceMonitor) { + numNodes := nodeNames.Len() + totalPods := podsPerNode * numNodes + By(fmt.Sprintf("Creating a RC of %d pods and wait until all pods of this RC are running", totalPods)) + rcName := fmt.Sprintf("resource%d-%s", totalPods, string(util.NewUUID())) + + // TODO: Use a more realistic workload + Expect(RunRC(RCConfig{ + Client: framework.Client, + Name: rcName, + Namespace: framework.Namespace.Name, + Image: "beta.gcr.io/google_containers/pause:2.0", + Replicas: totalPods, + })).NotTo(HaveOccurred()) + + // Log once and flush the stats. + resourceMonitor.LogLatest() + resourceMonitor.Reset() + + By("Start monitoring resource usage") + // Periodically dump the cpu summary until the deadline is met. + // Note that without calling resourceMonitor.Reset(), the stats + // would occupy increasingly more memory. This should be fine + // for the current test duration, but we should reclaim the + // entries if we plan to monitor longer (e.g., 8 hours). + deadline := time.Now().Add(monitoringTime) + for time.Now().Before(deadline) { + Logf("Still running...%v left", deadline.Sub(time.Now())) + time.Sleep(reportingPeriod) + timeLeft := deadline.Sub(time.Now()) + Logf("Still running...%v left", timeLeft) + if timeLeft < reportingPeriod { + time.Sleep(timeLeft) + } else { + time.Sleep(reportingPeriod) + } + logPodsOnNodes(framework.Client, nodeNames.List()) + } + + By("Reporting overall resource usage") + logPodsOnNodes(framework.Client, nodeNames.List()) + resourceMonitor.LogCPUSummary() + resourceMonitor.LogLatest() + + By("Deleting the RC") + DeleteRC(framework.Client, framework.Namespace.Name, rcName) +} + +var _ = Describe("Kubelet", func() { + var nodeNames sets.String + framework := NewFramework("kubelet-perf") + var resourceMonitor *resourceMonitor + + BeforeEach(func() { + nodes, err := framework.Client.Nodes().List(labels.Everything(), fields.Everything()) + expectNoError(err) + nodeNames = sets.NewString() + for _, node := range nodes.Items { + nodeNames.Insert(node.Name) + } + resourceMonitor = newResourceMonitor(framework.Client, targetContainers(), containerStatsPollingPeriod) + resourceMonitor.Start() + }) + + AfterEach(func() { + resourceMonitor.Stop() + }) + + Describe("regular resource usage tracking", func() { + density := []int{0, 35} + for i := range density { + podsPerNode := density[i] + name := fmt.Sprintf( + "over %v with %d pods per node", monitoringTime, podsPerNode) + It(name, func() { + runResourceTrackingTest(framework, podsPerNode, nodeNames, resourceMonitor) + }) + } + }) + Describe("experimental resource usage tracking", func() { + density := []int{50} + for i := range density { + podsPerNode := density[i] + name := fmt.Sprintf( + "over %v with %d pods per node.", monitoringTime, podsPerNode) + It(name, func() { + runResourceTrackingTest(framework, podsPerNode, nodeNames, resourceMonitor) + }) + } + }) +}) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet_stats.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet_stats.go index 98fca776661c..b75f812f916b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet_stats.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubelet_stats.go @@ -25,10 +25,12 @@ import ( "sort" "strconv" "strings" + "sync" "text/tabwriter" "time" cadvisor "github.com/google/cadvisor/info/v1" + "github.com/prometheus/common/model" "k8s.io/kubernetes/pkg/api" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" @@ -38,9 +40,6 @@ import ( "k8s.io/kubernetes/pkg/master/ports" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" - - "github.com/prometheus/client_golang/extraction" - "github.com/prometheus/client_golang/model" ) // KubeletMetric stores metrics scraped from the kubelet server's /metric endpoint. @@ -63,10 +62,13 @@ func (a KubeletMetricByLatency) Len() int { return len(a) } func (a KubeletMetricByLatency) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a KubeletMetricByLatency) Less(i, j int) bool { return a[i].Latency > a[j].Latency } -// KubeletMetricIngester implements extraction.Ingester -type kubeletMetricIngester []KubeletMetric +// ParseKubeletMetrics reads metrics from the kubelet server running on the given node +func ParseKubeletMetrics(metricsBlob string) ([]KubeletMetric, error) { + samples, err := extractMetricSamples(metricsBlob) + if err != nil { + return nil, err + } -func (k *kubeletMetricIngester) Ingest(samples model.Samples) error { acceptedMethods := sets.NewString( metrics.PodWorkerLatencyKey, metrics.PodWorkerStartLatencyKey, @@ -78,6 +80,7 @@ func (k *kubeletMetricIngester) Ingest(samples model.Samples) error { metrics.DockerErrorsKey, ) + var kms []KubeletMetric for _, sample := range samples { const prefix = metrics.KubeletSubsystem + "_" metricName := string(sample.Metric[model.MetricNameLabel]) @@ -105,16 +108,14 @@ func (k *kubeletMetricIngester) Ingest(samples model.Samples) error { } } - *k = append(*k, KubeletMetric{operation, method, quantile, time.Duration(int64(latency)) * time.Microsecond}) + kms = append(kms, KubeletMetric{ + operation, + method, + quantile, + time.Duration(int64(latency)) * time.Microsecond, + }) } - return nil -} - -// ReadKubeletMetrics reads metrics from the kubelet server running on the given node -func ParseKubeletMetrics(metricsBlob string) ([]KubeletMetric, error) { - var ingester kubeletMetricIngester - err := extraction.Processor004.ProcessSingle(strings.NewReader(metricsBlob), &ingester, &extraction.ProcessOptions{}) - return ingester, err + return kms, nil } // HighLatencyKubeletOperations logs and counts the high latency metrics exported by the kubelet server via /metrics. @@ -178,12 +179,20 @@ const ( ) // A list of containers for which we want to collect resource usage. -var targetContainers = []string{ - "/", - "/docker-daemon", - "/kubelet", - "/kube-proxy", - "/system", +func targetContainers() []string { + if providerIs("gce", "gke") { + return []string{ + "/", + "/docker-daemon", + "/kubelet", + "/kube-proxy", + "/system", + } + } else { + return []string{ + "/", + } + } } type containerResourceUsage struct { @@ -229,8 +238,9 @@ func getOneTimeResourceUsageOnNode(c *client.Client, nodeName string, cpuInterva return nil, err } // Process container infos that are relevant to us. - usageMap := make(map[string]*containerResourceUsage, len(targetContainers)) - for _, name := range targetContainers { + containers := targetContainers() + usageMap := make(map[string]*containerResourceUsage, len(containers)) + for _, name := range containers { info, ok := containerInfos[name] if !ok { return nil, fmt.Errorf("missing info for container %q on node %q", name, nodeName) @@ -337,6 +347,7 @@ func computeContainerResourceUsage(name string, oldStats, newStats *cadvisor.Con // list of containers, computes and cache resource usage up to // maxEntriesPerContainer for each container. type resourceCollector struct { + lock sync.RWMutex node string containers []string client *client.Client @@ -381,6 +392,8 @@ func (r *resourceCollector) collectStats(oldStats map[string]*cadvisor.Container Logf("Error getting container info on %q, err: %v", r.node, err) return } + r.lock.Lock() + defer r.lock.Unlock() for _, name := range r.containers { info, ok := infos[name] if !ok || len(info.Stats) < 1 { @@ -396,36 +409,52 @@ func (r *resourceCollector) collectStats(oldStats map[string]*cadvisor.Container // LogLatest logs the latest resource usage of each container. func (r *resourceCollector) LogLatest() { + r.lock.RLock() + defer r.lock.RUnlock() stats := make(map[string]*containerResourceUsage) for _, name := range r.containers { - s := r.buffers[name][len(r.buffers)-1] - if s == nil { + contStats, ok := r.buffers[name] + if !ok || len(contStats) == 0 { Logf("Resource usage on node %q is not ready yet", r.node) return } - stats[name] = s + stats[name] = contStats[len(contStats)-1] } Logf("\n%s", formatResourceUsageStats(r.node, stats)) } +// Reset frees the stats and start over. +func (r *resourceCollector) Reset() { + r.lock.Lock() + defer r.lock.Unlock() + for _, name := range r.containers { + r.buffers[name] = []*containerResourceUsage{} + } +} + type resourceUsageByCPU []*containerResourceUsage func (r resourceUsageByCPU) Len() int { return len(r) } func (r resourceUsageByCPU) Swap(i, j int) { r[i], r[j] = r[j], r[i] } func (r resourceUsageByCPU) Less(i, j int) bool { return r[i].CPUUsageInCores < r[j].CPUUsageInCores } -var percentiles = [...]float64{0.05, 0.50, 0.90, 0.95} +// The percentiles to report. +var percentiles = [...]float64{0.05, 0.20, 0.50, 0.70, 0.90, 0.95, 0.99} -// GetBasicCPUStats returns the 5-th, 50-th, and 95-th, percentiles the cpu -// usage in cores for containerName. This method examines all data currently in the buffer. +// GetBasicCPUStats returns the percentiles the cpu usage in cores for +// containerName. This method examines all data currently in the buffer. func (r *resourceCollector) GetBasicCPUStats(containerName string) map[float64]float64 { + r.lock.RLock() + defer r.lock.RUnlock() result := make(map[float64]float64, len(percentiles)) usages := r.buffers[containerName] sort.Sort(resourceUsageByCPU(usages)) for _, q := range percentiles { index := int(float64(len(usages))*q) - 1 if index < 0 { - index = 0 + // We don't have enough data. + result[q] = 0 + continue } result[q] = usages[index].CPUUsageInCores } @@ -467,6 +496,12 @@ func (r *resourceMonitor) Stop() { } } +func (r *resourceMonitor) Reset() { + for _, collector := range r.collectors { + collector.Reset() + } +} + func (r *resourceMonitor) LogLatest() { for _, collector := range r.collectors { collector.LogLatest() @@ -474,7 +509,7 @@ func (r *resourceMonitor) LogLatest() { } func (r *resourceMonitor) LogCPUSummary() { - // Example output for a node: + // Example output for a node (the percentiles may differ): // CPU usage of containers on node "e2e-test-yjhong-minion-0vj7": // container 5th% 50th% 90th% 95th% // "/" 0.051 0.159 0.387 0.455 @@ -491,7 +526,7 @@ func (r *resourceMonitor) LogCPUSummary() { buf := &bytes.Buffer{} w := tabwriter.NewWriter(buf, 1, 0, 1, ' ', 0) fmt.Fprintf(w, "%s\n", strings.Join(header, "\t")) - for _, containerName := range targetContainers { + for _, containerName := range targetContainers() { data := collector.GetBasicCPUStats(containerName) var s []string s = append(s, fmt.Sprintf("%q", containerName)) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubeproxy.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubeproxy.go new file mode 100644 index 000000000000..520bff4826c0 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/kubeproxy.go @@ -0,0 +1,526 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 e2e + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "strings" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + api "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" + client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/wait" +) + +const ( + endpointHttpPort = 8080 + endpointUdpPort = 8081 + endpointHostPort = 8082 + testContainerHttpPort = 8080 + clusterHttpPort = 80 + clusterUdpPort = 90 + nodeHttpPort = 32080 + nodeUdpPort = 32081 + loadBalancerHttpPort = 100 + netexecImageName = "gcr.io/google_containers/netexec:1.0" + testPodName = "test-container-pod" + nodePortServiceName = "node-port-service" + loadBalancerServiceName = "load-balancer-service" + enableLoadBalancerTest = false +) + +type KubeProxyTestConfig struct { + testContainerPod *api.Pod + testHostPod *api.Pod + endpointPods []*api.Pod + f *Framework + nodePortService *api.Service + loadBalancerService *api.Service + nodes []string +} + +var _ = Describe("KubeProxy", func() { + f := NewFramework("e2e-kubeproxy") + config := &KubeProxyTestConfig{ + f: f, + } + + It("should test kube-proxy", func() { + SkipUnlessProviderIs(providersWithSSH...) + + By("cleaning up any pre-existing namespaces used by this test") + config.cleanup() + + By("Setting up for the tests") + config.setup() + + //TODO Need to add hit externalIPs test + By("TODO: Need to add hit externalIPs test") + + By("Hit Test with All Endpoints") + config.hitAll() + + config.deleteNetProxyPod() + By("Hit Test with Fewer Endpoints") + config.hitAll() + + By("Deleting nodePortservice and ensuring that service cannot be hit") + config.deleteNodePortService() + config.hitNodePort(0) // expect 0 endpoints to be hit + + if enableLoadBalancerTest { + By("Deleting loadBalancerService and ensuring that service cannot be hit") + config.deleteLoadBalancerService() + config.hitLoadBalancer(0) // expect 0 endpoints to be hit + } + }) +}) + +func (config *KubeProxyTestConfig) hitAll() { + By("Hitting endpoints from host and container") + config.hitEndpoints() + + By("Hitting clusterIP from host and container") + config.hitClusterIP(len(config.endpointPods)) + + By("Hitting nodePort from host and container") + config.hitNodePort(len(config.endpointPods)) + + if enableLoadBalancerTest { + By("Waiting for LoadBalancer Ingress Setup") + config.waitForLoadBalancerIngressSetup() + + By("Hitting LoadBalancer") + config.hitLoadBalancer(len(config.endpointPods)) + } +} + +func (config *KubeProxyTestConfig) hitLoadBalancer(epCount int) { + lbIP := config.loadBalancerService.Status.LoadBalancer.Ingress[0].IP + hostNames := make(map[string]bool) + tries := epCount*epCount + 5 + for i := 0; i < tries; i++ { + transport := &http.Transport{} + httpClient := createHTTPClient(transport) + resp, err := httpClient.Get(fmt.Sprintf("http://%s:%d/hostName", lbIP, loadBalancerHttpPort)) + if err == nil { + defer resp.Body.Close() + hostName, err := ioutil.ReadAll(resp.Body) + if err == nil { + hostNames[string(hostName)] = true + } + } + transport.CloseIdleConnections() + } + Expect(len(hostNames)).To(BeNumerically("==", epCount), "LoadBalancer did not hit all pods") +} + +func createHTTPClient(transport *http.Transport) *http.Client { + client := &http.Client{ + Transport: transport, + Timeout: 5 * time.Second, + } + return client +} + +func (config *KubeProxyTestConfig) hitClusterIP(epCount int) { + clusterIP := config.nodePortService.Spec.ClusterIP + tries := epCount*epCount + 5 // if epCount == 0 + By("dialing(udp) node1 --> clusterIP:clusterUdpPort") + config.dialFromNode("udp", clusterIP, clusterUdpPort, tries, epCount) + By("dialing(http) node1 --> clusterIP:clusterHttpPort") + config.dialFromNode("http", clusterIP, clusterHttpPort, tries, epCount) + + By("dialing(udp) test container --> clusterIP:clusterUdpPort") + config.dialFromTestContainer("udp", clusterIP, clusterUdpPort, tries, epCount) + By("dialing(http) test container --> clusterIP:clusterHttpPort") + config.dialFromTestContainer("http", clusterIP, clusterHttpPort, tries, epCount) + + By("dialing(udp) endpoint container --> clusterIP:clusterUdpPort") + config.dialFromEndpointContainer("udp", clusterIP, clusterUdpPort, tries, epCount) + By("dialing(http) endpoint container --> clusterIP:clusterHttpPort") + config.dialFromEndpointContainer("http", clusterIP, clusterHttpPort, tries, epCount) +} + +func (config *KubeProxyTestConfig) hitNodePort(epCount int) { + node1_IP := config.nodes[0] + tries := epCount*epCount + 5 // + 10 if epCount == 0 + By("dialing(udp) node1 --> node1:nodeUdpPort") + config.dialFromNode("udp", node1_IP, nodeUdpPort, tries, epCount) + By("dialing(http) node1 --> node1:nodeHttpPort") + config.dialFromNode("http", node1_IP, nodeHttpPort, tries, epCount) + + By("dialing(udp) test container --> node1:nodeUdpPort") + config.dialFromTestContainer("udp", node1_IP, nodeUdpPort, tries, epCount) + By("dialing(http) container --> node1:nodeHttpPort") + config.dialFromTestContainer("http", node1_IP, nodeHttpPort, tries, epCount) + + By("dialing(udp) endpoint container --> node1:nodeUdpPort") + config.dialFromEndpointContainer("udp", node1_IP, nodeUdpPort, tries, epCount) + By("dialing(http) endpoint container --> node1:nodeHttpPort") + config.dialFromEndpointContainer("http", node1_IP, nodeHttpPort, tries, epCount) + + // TODO: doesnt work because masquerading is not done + By("TODO: Test disabled. dialing(udp) node --> 127.0.0.1:nodeUdpPort") + //config.dialFromNode("udp", "127.0.0.1", nodeUdpPort, tries, epCount) + // TODO: doesnt work because masquerading is not done + By("Test disabled. dialing(http) node --> 127.0.0.1:nodeHttpPort") + //config.dialFromNode("http", "127.0.0.1", nodeHttpPort, tries, epCount) + + node2_IP := config.nodes[1] + By("dialing(udp) node1 --> node2:nodeUdpPort") + config.dialFromNode("udp", node2_IP, nodeUdpPort, tries, epCount) + By("dialing(http) node1 --> node2:nodeHttpPort") + config.dialFromNode("http", node2_IP, nodeHttpPort, tries, epCount) +} + +func (config *KubeProxyTestConfig) hitEndpoints() { + for _, endpointPod := range config.endpointPods { + Expect(len(endpointPod.Status.PodIP)).To(BeNumerically(">", 0), "podIP is empty:%s", endpointPod.Status.PodIP) + By("dialing(udp) endpointPodIP:endpointUdpPort from node1") + config.dialFromNode("udp", endpointPod.Status.PodIP, endpointUdpPort, 5, 1) + By("dialing(http) endpointPodIP:endpointHttpPort from node1") + config.dialFromNode("http", endpointPod.Status.PodIP, endpointHttpPort, 5, 1) + By("dialing(udp) endpointPodIP:endpointUdpPort from test container") + config.dialFromTestContainer("udp", endpointPod.Status.PodIP, endpointUdpPort, 5, 1) + By("dialing(http) endpointPodIP:endpointHttpPort from test container") + config.dialFromTestContainer("http", endpointPod.Status.PodIP, endpointHttpPort, 5, 1) + } +} + +func (config *KubeProxyTestConfig) dialFromEndpointContainer(protocol, targetIP string, targetPort, tries, expectedCount int) { + config.dialFromContainer(protocol, config.endpointPods[0].Status.PodIP, targetIP, endpointHttpPort, targetPort, tries, expectedCount) +} + +func (config *KubeProxyTestConfig) dialFromTestContainer(protocol, targetIP string, targetPort, tries, expectedCount int) { + config.dialFromContainer(protocol, config.testContainerPod.Status.PodIP, targetIP, testContainerHttpPort, targetPort, tries, expectedCount) +} + +func (config *KubeProxyTestConfig) dialFromContainer(protocol, containerIP, targetIP string, containerHttpPort, targetPort, tries, expectedCount int) { + cmd := fmt.Sprintf("curl -q 'http://%s:%d/dial?request=hostName&protocol=%s&host=%s&port=%d&tries=%d'", + containerIP, + containerHttpPort, + protocol, + targetIP, + targetPort, + tries) + + By(fmt.Sprintf("Dialing from container. Running command:%s", cmd)) + stdout := config.ssh(cmd) + var output map[string][]string + err := json.Unmarshal([]byte(stdout), &output) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Could not unmarshal curl response: %s", stdout)) + hostNamesMap := array2map(output["responses"]) + Expect(len(hostNamesMap)).To(BeNumerically("==", expectedCount), fmt.Sprintf("Response was:%v", output)) +} + +func (config *KubeProxyTestConfig) dialFromNode(protocol, targetIP string, targetPort, tries, expectedCount int) { + var cmd string + if protocol == "udp" { + cmd = fmt.Sprintf("echo 'hostName' | nc -w 1 -u %s %d", targetIP, targetPort) + } else { + cmd = fmt.Sprintf("curl -s --connect-timeout 1 http://%s:%d/hostName", targetIP, targetPort) + } + forLoop := fmt.Sprintf("for i in $(seq 1 %d); do %s; echo; done | grep -v '^\\s*$' |sort | uniq -c | wc -l", tries, cmd) + By(fmt.Sprintf("Dialing from node. command:%s", forLoop)) + stdout := config.ssh(forLoop) + Expect(strconv.Atoi(strings.TrimSpace(stdout))).To(BeNumerically("==", expectedCount)) +} + +func (config *KubeProxyTestConfig) ssh(cmd string) string { + stdout, _, code, err := SSH(cmd, config.nodes[0]+":22", testContext.Provider) + Expect(err).NotTo(HaveOccurred(), "error while SSH-ing to node: %v (code %v)", err, code) + Expect(code).Should(BeZero(), "command exited with non-zero code %v. cmd:%s", code, cmd) + return stdout +} + +func (config *KubeProxyTestConfig) createNetShellPodSpec(podName string) *api.Pod { + pod := &api.Pod{ + TypeMeta: unversioned.TypeMeta{ + Kind: "Pod", + APIVersion: latest.GroupOrDie("").Version, + }, + ObjectMeta: api.ObjectMeta{ + Name: podName, + Namespace: config.f.Namespace.Name, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "webserver", + Image: netexecImageName, + ImagePullPolicy: api.PullIfNotPresent, + Command: []string{ + "/netexec", + fmt.Sprintf("--http-port=%d", endpointHttpPort), + fmt.Sprintf("--udp-port=%d", endpointUdpPort), + }, + Ports: []api.ContainerPort{ + { + Name: "http", + ContainerPort: endpointHttpPort, + }, + { + Name: "udp", + ContainerPort: endpointUdpPort, + }, + { + Name: "host", + ContainerPort: endpointHttpPort, + HostPort: endpointHostPort, + }, + }, + }, + }, + }, + } + return pod +} + +func (config *KubeProxyTestConfig) createTestPodSpec() *api.Pod { + pod := &api.Pod{ + TypeMeta: unversioned.TypeMeta{ + Kind: "Pod", + APIVersion: latest.GroupOrDie("").Version, + }, + ObjectMeta: api.ObjectMeta{ + Name: testPodName, + Namespace: config.f.Namespace.Name, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "webserver", + Image: netexecImageName, + ImagePullPolicy: api.PullIfNotPresent, + Command: []string{ + "/netexec", + fmt.Sprintf("--http-port=%d", endpointHttpPort), + fmt.Sprintf("--udp-port=%d", endpointUdpPort), + }, + Ports: []api.ContainerPort{ + { + Name: "http", + ContainerPort: testContainerHttpPort, + }, + }, + }, + }, + }, + } + return pod +} + +func (config *KubeProxyTestConfig) createNodePortService(selector map[string]string) { + serviceSpec := &api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: nodePortServiceName, + }, + Spec: api.ServiceSpec{ + Type: api.ServiceTypeNodePort, + Ports: []api.ServicePort{ + {Port: clusterHttpPort, Name: "http", Protocol: "TCP", NodePort: nodeHttpPort, TargetPort: util.NewIntOrStringFromInt(endpointHttpPort)}, + {Port: clusterUdpPort, Name: "udp", Protocol: "UDP", NodePort: nodeUdpPort, TargetPort: util.NewIntOrStringFromInt(endpointUdpPort)}, + }, + Selector: selector, + }, + } + config.nodePortService = config.createService(serviceSpec) +} + +func (config *KubeProxyTestConfig) deleteNodePortService() { + err := config.getServiceClient().Delete(config.nodePortService.Name) + Expect(err).NotTo(HaveOccurred(), "error while deleting NodePortService. err:%v)", err) + time.Sleep(15 * time.Second) // wait for kube-proxy to catch up with the service being deleted. +} + +func (config *KubeProxyTestConfig) createLoadBalancerService(selector map[string]string) { + serviceSpec := &api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: loadBalancerServiceName, + }, + Spec: api.ServiceSpec{ + Type: api.ServiceTypeLoadBalancer, + Ports: []api.ServicePort{ + {Port: loadBalancerHttpPort, Name: "http", Protocol: "TCP", TargetPort: util.NewIntOrStringFromInt(endpointHttpPort)}, + }, + Selector: selector, + }, + } + config.createService(serviceSpec) +} + +func (config *KubeProxyTestConfig) deleteLoadBalancerService() { + go func() { config.getServiceClient().Delete(config.loadBalancerService.Name) }() + time.Sleep(15 * time.Second) // wait for kube-proxy to catch up with the service being deleted. +} + +func (config *KubeProxyTestConfig) waitForLoadBalancerIngressSetup() { + err := wait.Poll(2*time.Second, 120*time.Second, func() (bool, error) { + service, err := config.getServiceClient().Get(loadBalancerServiceName) + if err != nil { + return false, err + } else { + if len(service.Status.LoadBalancer.Ingress) > 0 { + return true, nil + } else { + return false, fmt.Errorf("Service LoadBalancer Ingress was not setup.") + } + } + }) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Failed to setup Load Balancer Service. err:%v", err)) + config.loadBalancerService, _ = config.getServiceClient().Get(loadBalancerServiceName) +} + +func (config *KubeProxyTestConfig) createTestPod() { + testContainerPod := config.createTestPodSpec() + config.testContainerPod = config.createPod(testContainerPod) +} + +func (config *KubeProxyTestConfig) createService(serviceSpec *api.Service) *api.Service { + _, err := config.getServiceClient().Create(serviceSpec) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Failed to create %s service: %v", serviceSpec.Name, err)) + + err = waitForService(config.f.Client, config.f.Namespace.Name, serviceSpec.Name, true, 5*time.Second, 45*time.Second) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("error while waiting for service:%s err: %v", serviceSpec.Name, err)) + + createdService, err := config.getServiceClient().Get(serviceSpec.Name) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Failed to create %s service: %v", serviceSpec.Name, err)) + + return createdService +} + +func (config *KubeProxyTestConfig) setup() { + By("creating a selector") + selectorName := "selector-" + string(util.NewUUID()) + serviceSelector := map[string]string{ + selectorName: "true", + } + + By("Getting ssh-able hosts") + hosts, err := NodeSSHHosts(config.f.Client) + Expect(err).NotTo(HaveOccurred()) + config.nodes = make([]string, 0, len(hosts)) + for _, h := range hosts { + config.nodes = append(config.nodes, strings.TrimSuffix(h, ":22")) + } + + if enableLoadBalancerTest { + By("Creating the LoadBalancer Service on top of the pods in kubernetes") + config.createLoadBalancerService(serviceSelector) + } + + By("Creating the service pods in kubernetes") + podName := "netserver" + config.endpointPods = config.createNetProxyPods(podName, serviceSelector, testContext.CloudConfig.NumNodes) + + By("Creating the service on top of the pods in kubernetes") + config.createNodePortService(serviceSelector) + + By("Creating test pods") + config.createTestPod() +} + +func (config *KubeProxyTestConfig) cleanup() { + nsClient := config.getNamespacesClient() + nsList, err := nsClient.List(nil, nil) + if err == nil { + for _, ns := range nsList.Items { + if strings.Contains(ns.Name, config.f.BaseName) && ns.Name != config.f.Namespace.Name { + nsClient.Delete(ns.Name) + } + } + } +} + +func (config *KubeProxyTestConfig) createNetProxyPods(podName string, selector map[string]string, nodeCount int) []*api.Pod { + //testContext.CloudConfig.NumNodes + pods := make([]*api.Pod, 0) + + for i := 0; i < nodeCount; i++ { + podName := fmt.Sprintf("%s-%d", podName, i) + pod := config.createNetShellPodSpec(podName) + pod.ObjectMeta.Labels = selector + createdPod := config.createPod(pod) + pods = append(pods, createdPod) + } + return pods +} + +func (config *KubeProxyTestConfig) deleteNetProxyPod() { + pod := config.endpointPods[0] + config.getPodClient().Delete(pod.Name, nil) + config.endpointPods = config.endpointPods[1:] + // wait for pod being deleted. + err := waitForPodToDisappear(config.f.Client, config.f.Namespace.Name, pod.Name, labels.Everything(), time.Second, util.ForeverTestTimeout) + if err != nil { + Failf("Failed to delete %s pod: %v", pod.Name, err) + } + // wait for endpoint being removed. + err = waitForServiceEndpointsNum(config.f.Client, config.f.Namespace.Name, nodePortServiceName, len(config.endpointPods), time.Second, util.ForeverTestTimeout) + if err != nil { + Failf("Failed to remove endpoint from service: %s", nodePortServiceName) + } + // wait for kube-proxy to catch up with the pod being deleted. + time.Sleep(5 * time.Second) +} + +func (config *KubeProxyTestConfig) createPod(pod *api.Pod) *api.Pod { + createdPod, err := config.getPodClient().Create(pod) + if err != nil { + Failf("Failed to create %s pod: %v", pod.Name, err) + } + expectNoError(config.f.WaitForPodRunning(pod.Name)) + createdPod, err = config.getPodClient().Get(pod.Name) + if err != nil { + Failf("Failed to retrieve %s pod: %v", pod.Name, err) + } + return createdPod +} + +func (config *KubeProxyTestConfig) getPodClient() client.PodInterface { + return config.f.Client.Pods(config.f.Namespace.Name) +} + +func (config *KubeProxyTestConfig) getServiceClient() client.ServiceInterface { + return config.f.Client.Services(config.f.Namespace.Name) +} + +func (config *KubeProxyTestConfig) getNamespacesClient() client.NamespaceInterface { + return config.f.Client.Namespaces() +} + +func array2map(arr []string) map[string]bool { + retval := make(map[string]bool) + if len(arr) == 0 { + return retval + } + for _, str := range arr { + retval[str] = true + } + return retval +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/load.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/load.go index f71373767241..2d85cc7cb66b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/load.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/load.go @@ -26,7 +26,6 @@ import ( client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/util/sets" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -53,11 +52,12 @@ var _ = Describe("Load capacity", func() { var nodeCount int var ns string var configs []*RCConfig + framework := Framework{BaseName: "load", NamespaceDeletionTimeout: time.Hour} BeforeEach(func() { - var err error - c, err = loadClient() - expectNoError(err) + framework.beforeEach() + c = framework.Client + ns = framework.Namespace.Name nodes, err := c.Nodes().List(labels.Everything(), fields.Everything()) expectNoError(err) nodeCount = len(nodes.Items) @@ -66,11 +66,7 @@ var _ = Describe("Load capacity", func() { // Terminating a namespace (deleting the remaining objects from it - which // generally means events) can affect the current run. Thus we wait for all // terminating namespace to be finally deleted before starting this test. - err = deleteTestingNS(c) - expectNoError(err) - - nsForTesting, err := createTestingNS("load", c) - ns = nsForTesting.Name + err = checkTestingNSDeletedExcept(c, ns) expectNoError(err) expectNoError(resetMetrics(c)) @@ -78,15 +74,14 @@ var _ = Describe("Load capacity", func() { // TODO add flag that allows to skip cleanup on failure AfterEach(func() { - deleteAllRC(configs) + // We can't call it explicitly at the end, because it will not be called + // if Expect() fails. + defer framework.afterEach() - By(fmt.Sprintf("Destroying namespace for this suite %v", ns)) - if err := c.Namespaces().Delete(ns); err != nil { - Failf("Couldn't delete ns %s", err) - } + deleteAllRC(configs) // Verify latency metrics - highLatencyRequests, err := HighLatencyRequests(c, 3*time.Second, sets.NewString("events")) + highLatencyRequests, err := HighLatencyRequests(c, 3*time.Second) expectNoError(err, "Too many instances metrics above the threshold") Expect(highLatencyRequests).NotTo(BeNumerically(">", 0)) }) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/mesos.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/mesos.go new file mode 100644 index 000000000000..eeb8e2ea6d67 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/mesos.go @@ -0,0 +1,53 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 e2e + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/labels" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "k8s.io/kubernetes/pkg/fields" +) + +var _ = Describe("Mesos", func() { + framework := NewFramework("pods") + + BeforeEach(func() { + SkipUnlessProviderIs("mesos/docker") + }) + + It("applies slave attributes as labels", func() { + nodeClient := framework.Client.Nodes() + + rackA := labels.SelectorFromSet(map[string]string{"k8s.mesosphere.io/attribute-rack": "1"}) + nodes, err := nodeClient.List(rackA, fields.Everything()) + if err != nil { + Failf("Failed to query for node: %v", err) + } + Expect(len(nodes.Items)).To(Equal(1)) + + var addr string + for _, a := range nodes.Items[0].Status.Addresses { + if a.Type == api.NodeInternalIP { + addr = a.Address + } + } + Expect(len(addr)).NotTo(Equal("")) + }) +}) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/metrics_util.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/metrics_util.go new file mode 100644 index 000000000000..31af49b14252 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/metrics_util.go @@ -0,0 +1,303 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 e2e + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "sort" + "strconv" + "strings" + "time" + + client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/util/sets" + + "github.com/prometheus/common/expfmt" + "github.com/prometheus/common/model" +) + +// Dashboard metrics +type LatencyMetric struct { + Perc50 time.Duration `json:"Perc50"` + Perc90 time.Duration `json:"Perc90"` + Perc99 time.Duration `json:"Perc99"` +} + +type PodStartupLatency struct { + Latency LatencyMetric `json:"latency"` +} + +type APICall struct { + Resource string `json:"resource"` + Verb string `json:"verb"` + Latency LatencyMetric `json:"latency"` +} + +type APIResponsiveness struct { + APICalls []APICall `json:"apicalls"` +} + +func (a APIResponsiveness) Len() int { return len(a.APICalls) } +func (a APIResponsiveness) Swap(i, j int) { a.APICalls[i], a.APICalls[j] = a.APICalls[j], a.APICalls[i] } +func (a APIResponsiveness) Less(i, j int) bool { + return a.APICalls[i].Latency.Perc99 < a.APICalls[j].Latency.Perc99 +} + +// 0 <= quantile <=1 (e.g. 0.95 is 95%tile, 0.5 is median) +// Only 0.5, 0.9 and 0.99 quantiles are supported. +func (a *APIResponsiveness) addMetric(resource, verb string, quantile float64, latency time.Duration) { + for i, apicall := range a.APICalls { + if apicall.Resource == resource && apicall.Verb == verb { + a.APICalls[i] = setQuantile(apicall, quantile, latency) + return + } + } + apicall := setQuantile(APICall{Resource: resource, Verb: verb}, quantile, latency) + a.APICalls = append(a.APICalls, apicall) +} + +// 0 <= quantile <=1 (e.g. 0.95 is 95%tile, 0.5 is median) +// Only 0.5, 0.9 and 0.99 quantiles are supported. +func setQuantile(apicall APICall, quantile float64, latency time.Duration) APICall { + switch quantile { + case 0.5: + apicall.Latency.Perc50 = latency + case 0.9: + apicall.Latency.Perc90 = latency + case 0.99: + apicall.Latency.Perc99 = latency + } + return apicall +} + +func readLatencyMetrics(c *client.Client) (APIResponsiveness, error) { + var a APIResponsiveness + + body, err := getMetrics(c) + if err != nil { + return a, err + } + + samples, err := extractMetricSamples(body) + if err != nil { + return a, err + } + + ignoredResources := sets.NewString("events") + ignoredVerbs := sets.NewString("WATCHLIST", "PROXY") + + for _, sample := range samples { + // Example line: + // apiserver_request_latencies_summary{resource="namespaces",verb="LIST",quantile="0.99"} 908 + if sample.Metric[model.MetricNameLabel] != "apiserver_request_latencies_summary" { + continue + } + + resource := string(sample.Metric["resource"]) + verb := string(sample.Metric["verb"]) + if ignoredResources.Has(resource) || ignoredVerbs.Has(verb) { + continue + } + latency := sample.Value + quantile, err := strconv.ParseFloat(string(sample.Metric[model.QuantileLabel]), 64) + if err != nil { + return a, err + } + a.addMetric(resource, verb, quantile, time.Duration(int64(latency))*time.Microsecond) + } + + return a, err +} + +// Prints summary metrics for request types with latency above threshold +// and returns number of such request types. +func HighLatencyRequests(c *client.Client, threshold time.Duration) (int, error) { + metrics, err := readLatencyMetrics(c) + if err != nil { + return 0, err + } + sort.Sort(sort.Reverse(metrics)) + badMetrics := 0 + top := 5 + for _, metric := range metrics.APICalls { + isBad := false + if metric.Latency.Perc99 > threshold { + badMetrics++ + isBad = true + } + if top > 0 || isBad { + top-- + prefix := "" + if isBad { + prefix = "WARNING " + } + Logf("%vTop latency metric: %+v", prefix, metric) + } + } + + Logf("API calls latencies: %s", prettyPrintJSON(metrics)) + + return badMetrics, nil +} + +// Verifies whether 50, 90 and 99th percentiles of PodStartupLatency are smaller +// than the given threshold (returns error in the oposite case). +func VerifyPodStartupLatency(latency PodStartupLatency, podStartupThreshold time.Duration) error { + Logf("Pod startup latency: %s", prettyPrintJSON(latency)) + + if latency.Latency.Perc50 > podStartupThreshold { + return fmt.Errorf("too high pod startup latency 50th percentile: %v", latency.Latency.Perc50) + } + if latency.Latency.Perc90 > podStartupThreshold { + return fmt.Errorf("too high pod startup latency 90th percentile: %v", latency.Latency.Perc90) + } + if latency.Latency.Perc99 > podStartupThreshold { + return fmt.Errorf("too high pod startup latency 99th percentil: %v", latency.Latency.Perc99) + } + return nil +} + +// Resets latency metrics in apiserver. +func resetMetrics(c *client.Client) error { + Logf("Resetting latency metrics in apiserver...") + body, err := c.Get().AbsPath("/resetMetrics").DoRaw() + if err != nil { + return err + } + if string(body) != "metrics reset\n" { + return fmt.Errorf("Unexpected response: %q", string(body)) + } + return nil +} + +// Retrieves metrics information. +func getMetrics(c *client.Client) (string, error) { + body, err := c.Get().AbsPath("/metrics").DoRaw() + if err != nil { + return "", err + } + return string(body), nil +} + +func prettyPrintJSON(metrics interface{}) string { + output := &bytes.Buffer{} + if err := json.NewEncoder(output).Encode(metrics); err != nil { + return "" + } + formatted := &bytes.Buffer{} + if err := json.Indent(formatted, output.Bytes(), "", " "); err != nil { + return "" + } + return string(formatted.Bytes()) +} + +// Retrieves debug information. +func getDebugInfo(c *client.Client) (map[string]string, error) { + data := make(map[string]string) + for _, key := range []string{"block", "goroutine", "heap", "threadcreate"} { + resp, err := http.Get(c.Get().AbsPath(fmt.Sprintf("debug/pprof/%s", key)).URL().String() + "?debug=2") + if err != nil { + Logf("Warning: Error trying to fetch %s debug data: %v", key, err) + continue + } + body, err := ioutil.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + Logf("Warning: Error trying to read %s debug data: %v", key, err) + } + data[key] = string(body) + } + return data, nil +} + +func writePerfData(c *client.Client, dirName string, postfix string) error { + fname := fmt.Sprintf("%s/metrics_%s.txt", dirName, postfix) + + handler, err := os.Create(fname) + if err != nil { + return fmt.Errorf("Error creating file '%s': %v", fname, err) + } + + metrics, err := getMetrics(c) + if err != nil { + return fmt.Errorf("Error retrieving metrics: %v", err) + } + + _, err = handler.WriteString(metrics) + if err != nil { + return fmt.Errorf("Error writing metrics: %v", err) + } + + err = handler.Close() + if err != nil { + return fmt.Errorf("Error closing '%s': %v", fname, err) + } + + debug, err := getDebugInfo(c) + if err != nil { + return fmt.Errorf("Error retrieving debug information: %v", err) + } + + for key, value := range debug { + fname := fmt.Sprintf("%s/%s_%s.txt", dirName, key, postfix) + handler, err = os.Create(fname) + if err != nil { + return fmt.Errorf("Error creating file '%s': %v", fname, err) + } + _, err = handler.WriteString(value) + if err != nil { + return fmt.Errorf("Error writing %s: %v", key, err) + } + + err = handler.Close() + if err != nil { + return fmt.Errorf("Error closing '%s': %v", fname, err) + } + } + return nil +} + +// extractMetricSamples parses the prometheus metric samples from the input string. +func extractMetricSamples(metricsBlob string) ([]*model.Sample, error) { + dec, err := expfmt.NewDecoder(strings.NewReader(metricsBlob), expfmt.FmtText) + if err != nil { + return nil, err + } + decoder := expfmt.SampleDecoder{ + Dec: dec, + Opts: &expfmt.DecodeOptions{}, + } + + var samples []*model.Sample + for { + var v model.Vector + if err = decoder.Decode(&v); err != nil { + if err == io.EOF { + // Expected loop termination condition. + return samples, nil + } + return nil, err + } + samples = append(samples, v...) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/monitor_resources.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/monitor_resources.go index b8403de93359..a3c279a0980b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/monitor_resources.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/monitor_resources.go @@ -47,8 +47,8 @@ var allowedUsage = resourceUsagePerContainer{ }, "/kube-proxy": &containerResourceUsage{ CPUUsageInCores: 0.025, - MemoryUsageInBytes: 12000000, - MemoryWorkingSetInBytes: 12000000, + MemoryUsageInBytes: 100000000, + MemoryWorkingSetInBytes: 100000000, }, "/system": &containerResourceUsage{ CPUUsageInCores: 0.03, @@ -83,9 +83,9 @@ func computeAverage(sliceOfUsages []resourceUsagePerContainer) (result resourceU return } -// This tests does nothing except checking current resource usage of containers defained in kubelet_stats systemContainers variable. +// This tests does nothing except checking current resource usage of containers defined in kubelet_stats systemContainers variable. // Test fails if an average container resource consumption over datapointAmount tries exceeds amount defined in allowedUsage. -var _ = Describe("ResourceUsage", func() { +var _ = Describe("Resource usage of system containers", func() { var c *client.Client BeforeEach(func() { var err error @@ -119,7 +119,16 @@ var _ = Describe("ResourceUsage", func() { for container, cUsage := range usage { Logf("%v on %v usage: %#v", container, node, cUsage) if !allowedUsage[container].isStrictlyGreaterThan(cUsage) { - violating[node] = usage + if allowedUsage[container].CPUUsageInCores < cUsage.CPUUsageInCores { + Logf("CPU is too high for %s (%v)", container, cUsage.CPUUsageInCores) + } + if allowedUsage[container].MemoryUsageInBytes < cUsage.MemoryUsageInBytes { + Logf("Memory use is too high for %s (%v)", container, cUsage.MemoryUsageInBytes) + } + if allowedUsage[container].MemoryWorkingSetInBytes < cUsage.MemoryWorkingSetInBytes { + Logf("Working set is too high for %s (%v)", container, cUsage.MemoryWorkingSetInBytes) + } + violating[node][container] = usage[container] } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/monitoring.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/monitoring.go index 84e33a773743..9d669a2b1ccc 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/monitoring.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/monitoring.go @@ -78,7 +78,7 @@ func verifyExpectedRcsExistAndGetExpectedPods(c *client.Client) ([]string, error // situaiton when a heapster-monitoring-v1 and heapster-monitoring-v2 replication controller // is running (which would be an error except during a rolling update). for _, rcLabel := range rcLabels { - rcList, err := c.ReplicationControllers(api.NamespaceSystem).List(labels.Set{"k8s-app": rcLabel}.AsSelector()) + rcList, err := c.ReplicationControllers(api.NamespaceSystem).List(labels.Set{"k8s-app": rcLabel}.AsSelector(), fields.Everything()) if err != nil { return nil, err } @@ -103,7 +103,7 @@ func verifyExpectedRcsExistAndGetExpectedPods(c *client.Client) ([]string, error } func expectedServicesExist(c *client.Client) error { - serviceList, err := c.Services(api.NamespaceSystem).List(labels.Everything()) + serviceList, err := c.Services(api.NamespaceSystem).List(labels.Everything(), fields.Everything()) if err != nil { return err } @@ -132,6 +132,24 @@ func getAllNodesInCluster(c *client.Client) ([]string, error) { return result, nil } +func getInfluxdbClient(c *client.Client) (*influxdb.Client, error) { + kubeMasterHttpClient, ok := c.Client.(*http.Client) + if !ok { + Failf("failed to get master http client") + } + proxyUrl := fmt.Sprintf("%s/api/v1/proxy/namespaces/%s/services/%s:api/", getMasterHost(), api.NamespaceSystem, influxdbService) + config := &influxdb.ClientConfig{ + Host: proxyUrl, + // TODO(vishh): Infer username and pw from the Pod spec. + Username: influxdbUser, + Password: influxdbPW, + Database: influxdbDatabaseName, + HttpClient: kubeMasterHttpClient, + IsSecure: true, + } + return influxdb.NewClient(config) +} + func getInfluxdbData(c *influxdb.Client, query string) (map[string]bool, error) { series, err := c.Query(query, influxdb.Second) if err != nil { @@ -204,21 +222,8 @@ func testMonitoringUsingHeapsterInfluxdb(c *client.Client) { expectNoError(err) expectNoError(expectedServicesExist(c)) // TODO: Wait for all pods and services to be running. - kubeMasterHttpClient, ok := c.Client.(*http.Client) - if !ok { - Failf("failed to get master http client") - } - proxyUrl := fmt.Sprintf("%s/api/v1/proxy/namespaces/%s/services/%s:api/", getMasterHost(), api.NamespaceSystem, influxdbService) - config := &influxdb.ClientConfig{ - Host: proxyUrl, - // TODO(vishh): Infer username and pw from the Pod spec. - Username: influxdbUser, - Password: influxdbPW, - Database: influxdbDatabaseName, - HttpClient: kubeMasterHttpClient, - IsSecure: true, - } - influxdbClient, err := influxdb.NewClient(config) + + influxdbClient, err := getInfluxdbClient(c) expectNoError(err, "failed to create influxdb client") expectedNodes, err := getAllNodesInCluster(c) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/networking.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/networking.go index 2bcb2551330d..127e513ec411 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/networking.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/networking.go @@ -23,6 +23,7 @@ import ( "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/util" @@ -50,12 +51,12 @@ var _ = Describe("Networking", func() { } }) - It("should provide Internet connection for containers", func() { + It("should provide Internet connection for containers [Conformance]", func() { By("Running container which tries to wget google.com") podName := "wget-test" contName := "wget-test-container" pod := &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", }, ObjectMeta: api.ObjectMeta{ @@ -81,7 +82,7 @@ var _ = Describe("Networking", func() { }) // First test because it has no dependencies on variables created later on. - It("should provide unchanging, static URL paths for kubernetes api services.", func() { + It("should provide unchanging, static URL paths for kubernetes api services [Conformance]", func() { tests := []struct { path string }{ @@ -102,7 +103,7 @@ var _ = Describe("Networking", func() { }) //Now we can proceed with the test. - It("should function for intra-pod communication", func() { + It("should function for intra-pod communication [Conformance]", func() { By(fmt.Sprintf("Creating a service named %q in namespace %q", svcname, f.Namespace.Name)) svc, err := f.Client.Services(f.Namespace.Name).Create(&api.Service{ @@ -129,7 +130,6 @@ var _ = Describe("Networking", func() { // Clean up service defer func() { - defer GinkgoRecover() By("Cleaning up the service") if err = f.Client.Services(f.Namespace.Name).Delete(svc.Name); err != nil { Failf("unable to delete svc %v: %v", svc.Name, err) @@ -166,7 +166,6 @@ var _ = Describe("Networking", func() { // Clean up the pods defer func() { - defer GinkgoRecover() By("Cleaning up the webserver pods") for _, podName := range podNames { if err = f.Client.Pods(f.Namespace.Name).Delete(podName, nil); err != nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pd.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pd.go index f7ec6def9a54..4a4e4a390895 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pd.go @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" "k8s.io/kubernetes/pkg/fields" @@ -71,8 +72,9 @@ var _ = Describe("Pod Disks", func() { diskName, err := createPD() expectNoError(err, "Error creating PD") - host0Pod := testPDPod(diskName, host0Name, false /* readOnly */, 1 /* numContainers */) - host1Pod := testPDPod(diskName, host1Name, false /* readOnly */, 1 /* numContainers */) + host0Pod := testPDPod([]string{diskName}, host0Name, false /* readOnly */, 1 /* numContainers */) + host1Pod := testPDPod([]string{diskName}, host1Name, false /* readOnly */, 1 /* numContainers */) + containerName := "mycontainer" defer func() { By("cleaning up PD-RW test environment") @@ -82,7 +84,7 @@ var _ = Describe("Pod Disks", func() { podClient.Delete(host1Pod.Name, api.NewDeleteOptions(0)) detachPD(host0Name, diskName) detachPD(host1Name, diskName) - deletePD(diskName) + deletePDWithRetry(diskName) }() By("submitting host0Pod to kubernetes") @@ -91,10 +93,10 @@ var _ = Describe("Pod Disks", func() { expectNoError(framework.WaitForPodRunning(host0Pod.Name)) - testFile := "/testpd/tracker" + testFile := "/testpd1/tracker" testFileContents := fmt.Sprintf("%v", math_rand.Int()) - expectNoError(framework.WriteFileViaContainer(host0Pod.Name, "testpd" /* containerName */, testFile, testFileContents)) + expectNoError(framework.WriteFileViaContainer(host0Pod.Name, containerName, testFile, testFileContents)) Logf("Wrote value: %v", testFileContents) By("deleting host0Pod") @@ -106,7 +108,7 @@ var _ = Describe("Pod Disks", func() { expectNoError(framework.WaitForPodRunning(host1Pod.Name)) - v, err := framework.ReadFileViaContainer(host1Pod.Name, "testpd", testFile) + v, err := framework.ReadFileViaContainer(host1Pod.Name, containerName, testFile) expectNoError(err) Logf("Read value: %v", v) @@ -128,9 +130,9 @@ var _ = Describe("Pod Disks", func() { diskName, err := createPD() expectNoError(err, "Error creating PD") - rwPod := testPDPod(diskName, host0Name, false /* readOnly */, 1 /* numContainers */) - host0ROPod := testPDPod(diskName, host0Name, true /* readOnly */, 1 /* numContainers */) - host1ROPod := testPDPod(diskName, host1Name, true /* readOnly */, 1 /* numContainers */) + rwPod := testPDPod([]string{diskName}, host0Name, false /* readOnly */, 1 /* numContainers */) + host0ROPod := testPDPod([]string{diskName}, host0Name, true /* readOnly */, 1 /* numContainers */) + host1ROPod := testPDPod([]string{diskName}, host1Name, true /* readOnly */, 1 /* numContainers */) defer func() { By("cleaning up PD-RO test environment") @@ -142,7 +144,7 @@ var _ = Describe("Pod Disks", func() { detachPD(host0Name, diskName) detachPD(host1Name, diskName) - deletePD(diskName) + deletePDWithRetry(diskName) }() By("submitting rwPod to ensure PD is formatted") @@ -184,7 +186,7 @@ var _ = Describe("Pod Disks", func() { expectNoError(err, "Error creating PD") numContainers := 4 - host0Pod := testPDPod(diskName, host0Name, false /* readOnly */, numContainers) + host0Pod := testPDPod([]string{diskName}, host0Name, false /* readOnly */, numContainers) defer func() { By("cleaning up PD-RW test environment") @@ -192,7 +194,7 @@ var _ = Describe("Pod Disks", func() { // Teardown should do nothing unless test failed. podClient.Delete(host0Pod.Name, api.NewDeleteOptions(0)) detachPD(host0Name, diskName) - deletePD(diskName) + deletePDWithRetry(diskName) }() fileAndContentToVerify := make(map[string]string) @@ -205,19 +207,19 @@ var _ = Describe("Pod Disks", func() { expectNoError(framework.WaitForPodRunning(host0Pod.Name)) // randomly select a container and read/verify pd contents from it - containerName := fmt.Sprintf("testpd%v", math_rand.Intn(numContainers)+1) + containerName := fmt.Sprintf("mycontainer%v", math_rand.Intn(numContainers)+1) verifyPDContentsViaContainer(framework, host0Pod.Name, containerName, fileAndContentToVerify) // Randomly select a container to write a file to PD from - containerName = fmt.Sprintf("testpd%v", math_rand.Intn(numContainers)+1) - testFile := fmt.Sprintf("/testpd/tracker%v", i) + containerName = fmt.Sprintf("mycontainer%v", math_rand.Intn(numContainers)+1) + testFile := fmt.Sprintf("/testpd1/tracker%v", i) testFileContents := fmt.Sprintf("%v", math_rand.Int()) fileAndContentToVerify[testFile] = testFileContents expectNoError(framework.WriteFileViaContainer(host0Pod.Name, containerName, testFile, testFileContents)) Logf("Wrote value: \"%v\" to PD %q from pod %q container %q", testFileContents, diskName, host0Pod.Name, containerName) // Randomly select a container and read/verify pd contents from it - containerName = fmt.Sprintf("testpd%v", math_rand.Intn(numContainers)+1) + containerName = fmt.Sprintf("mycontainer%v", math_rand.Intn(numContainers)+1) verifyPDContentsViaContainer(framework, host0Pod.Name, containerName, fileAndContentToVerify) By("deleting host0Pod") @@ -229,6 +231,69 @@ var _ = Describe("Pod Disks", func() { return }) + + It("should schedule a pod w/two RW PDs both mounted to one container, write to PD, verify contents, delete pod, recreate pod, verify contents, and repeat in rapid succession", func() { + SkipUnlessProviderIs("gce", "gke", "aws") + + By("creating PD1") + disk1Name, err := createPD() + expectNoError(err, "Error creating PD1") + By("creating PD2") + disk2Name, err := createPD() + expectNoError(err, "Error creating PD2") + + host0Pod := testPDPod([]string{disk1Name, disk2Name}, host0Name, false /* readOnly */, 1 /* numContainers */) + + defer func() { + By("cleaning up PD-RW test environment") + // Teardown pods, PD. Ignore errors. + // Teardown should do nothing unless test failed. + podClient.Delete(host0Pod.Name, api.NewDeleteOptions(0)) + detachPD(host0Name, disk1Name) + detachPD(host0Name, disk2Name) + deletePDWithRetry(disk1Name) + deletePDWithRetry(disk2Name) + }() + + containerName := "mycontainer" + fileAndContentToVerify := make(map[string]string) + for i := 0; i < 3; i++ { + Logf("PD Read/Writer Iteration #%v", i) + By("submitting host0Pod to kubernetes") + _, err = podClient.Create(host0Pod) + expectNoError(err, fmt.Sprintf("Failed to create host0Pod: %v", err)) + + expectNoError(framework.WaitForPodRunning(host0Pod.Name)) + + // Read/verify pd contents for both disks from container + verifyPDContentsViaContainer(framework, host0Pod.Name, containerName, fileAndContentToVerify) + + // Write a file to both PDs from container + testFilePD1 := fmt.Sprintf("/testpd1/tracker%v", i) + testFilePD2 := fmt.Sprintf("/testpd2/tracker%v", i) + testFilePD1Contents := fmt.Sprintf("%v", math_rand.Int()) + testFilePD2Contents := fmt.Sprintf("%v", math_rand.Int()) + fileAndContentToVerify[testFilePD1] = testFilePD1Contents + fileAndContentToVerify[testFilePD2] = testFilePD2Contents + expectNoError(framework.WriteFileViaContainer(host0Pod.Name, containerName, testFilePD1, testFilePD1Contents)) + Logf("Wrote value: \"%v\" to PD1 (%q) from pod %q container %q", testFilePD1Contents, disk1Name, host0Pod.Name, containerName) + expectNoError(framework.WriteFileViaContainer(host0Pod.Name, containerName, testFilePD2, testFilePD2Contents)) + Logf("Wrote value: \"%v\" to PD2 (%q) from pod %q container %q", testFilePD2Contents, disk2Name, host0Pod.Name, containerName) + + // Read/verify pd contents for both disks from container + verifyPDContentsViaContainer(framework, host0Pod.Name, containerName, fileAndContentToVerify) + + By("deleting host0Pod") + expectNoError(podClient.Delete(host0Pod.Name, api.NewDeleteOptions(0)), "Failed to delete host0Pod") + } + + By(fmt.Sprintf("deleting PD1 %q", disk1Name)) + deletePDWithRetry(disk1Name) + By(fmt.Sprintf("deleting PD2 %q", disk2Name)) + deletePDWithRetry(disk2Name) + + return + }) }) func deletePDWithRetry(diskName string) { @@ -262,7 +327,7 @@ func createPD() (string, error) { zone := testContext.CloudConfig.Zone // TODO: make this hit the compute API directly instread of shelling out to gcloud. - err := exec.Command("gcloud", "compute", "--project="+testContext.CloudConfig.ProjectID, "disks", "create", "--zone="+zone, "--size=10GB", pdName).Run() + err := exec.Command("gcloud", "compute", "--quiet", "--project="+testContext.CloudConfig.ProjectID, "disks", "create", "--zone="+zone, "--size=10GB", pdName).Run() if err != nil { return "", err } @@ -283,10 +348,16 @@ func deletePD(pdName string) error { zone := testContext.CloudConfig.Zone // TODO: make this hit the compute API directly. - cmd := exec.Command("gcloud", "compute", "--project="+testContext.CloudConfig.ProjectID, "disks", "delete", "--zone="+zone, pdName) + cmd := exec.Command("gcloud", "compute", "--quiet", "--project="+testContext.CloudConfig.ProjectID, "disks", "delete", "--zone="+zone, pdName) data, err := cmd.CombinedOutput() if err != nil { - Logf("Error deleting PD: %s (%v)", string(data), err) + dataStr := string(data) + if strings.Contains(dataStr, "was not found") { + Logf("PD deletion implicitly succeeded because PD %q does not exist.", pdName) + return nil + } + + Logf("Error deleting PD: %s (%v)", dataStr, err) } return err } else { @@ -305,7 +376,7 @@ func detachPD(hostName, pdName string) error { zone := testContext.CloudConfig.Zone // TODO: make this hit the compute API directly. - return exec.Command("gcloud", "compute", "--project="+testContext.CloudConfig.ProjectID, "detach-disk", "--zone="+zone, "--disk="+pdName, instanceName).Run() + return exec.Command("gcloud", "compute", "--quiet", "--project="+testContext.CloudConfig.ProjectID, "detach-disk", "--zone="+zone, "--disk="+pdName, instanceName).Run() } else { volumes, ok := testContext.CloudConfig.Provider.(aws_cloud.Volumes) if !ok { @@ -315,23 +386,22 @@ func detachPD(hostName, pdName string) error { } } -func testPDPod(diskName, targetHost string, readOnly bool, numContainers int) *api.Pod { +func testPDPod(diskNames []string, targetHost string, readOnly bool, numContainers int) *api.Pod { containers := make([]api.Container, numContainers) for i := range containers { - containers[i].Name = "testpd" + containers[i].Name = "mycontainer" if numContainers > 1 { - containers[i].Name = fmt.Sprintf("testpd%v", i+1) + containers[i].Name = fmt.Sprintf("mycontainer%v", i+1) } containers[i].Image = "gcr.io/google_containers/busybox" containers[i].Command = []string{"sleep", "6000"} - containers[i].VolumeMounts = []api.VolumeMount{ - { - Name: "testpd", - MountPath: "/testpd", - }, + containers[i].VolumeMounts = make([]api.VolumeMount, len(diskNames)) + for k := range diskNames { + containers[i].VolumeMounts[k].Name = fmt.Sprintf("testpd%v", k+1) + containers[i].VolumeMounts[k].MountPath = fmt.Sprintf("/testpd%v", k+1) } containers[i].Resources.Limits = api.ResourceList{} @@ -340,9 +410,9 @@ func testPDPod(diskName, targetHost string, readOnly bool, numContainers int) *a } pod := &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", - APIVersion: latest.Version, + APIVersion: latest.GroupOrDie("").Version, }, ObjectMeta: api.ObjectMeta{ Name: "pd-test-" + string(util.NewUUID()), @@ -354,30 +424,28 @@ func testPDPod(diskName, targetHost string, readOnly bool, numContainers int) *a } if testContext.Provider == "gce" || testContext.Provider == "gke" { - pod.Spec.Volumes = []api.Volume{ - { - Name: "testpd", - VolumeSource: api.VolumeSource{ - GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{ - PDName: diskName, - FSType: "ext4", - ReadOnly: readOnly, - }, + pod.Spec.Volumes = make([]api.Volume, len(diskNames)) + for k, diskName := range diskNames { + pod.Spec.Volumes[k].Name = fmt.Sprintf("testpd%v", k+1) + pod.Spec.Volumes[k].VolumeSource = api.VolumeSource{ + GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{ + PDName: diskName, + FSType: "ext4", + ReadOnly: readOnly, }, - }, + } } } else if testContext.Provider == "aws" { - pod.Spec.Volumes = []api.Volume{ - { - Name: "testpd", - VolumeSource: api.VolumeSource{ - AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{ - VolumeID: diskName, - FSType: "ext4", - ReadOnly: readOnly, - }, + pod.Spec.Volumes = make([]api.Volume, len(diskNames)) + for k, diskName := range diskNames { + pod.Spec.Volumes[k].Name = fmt.Sprintf("testpd%v", k+1) + pod.Spec.Volumes[k].VolumeSource = api.VolumeSource{ + AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{ + VolumeID: diskName, + FSType: "ext4", + ReadOnly: readOnly, }, - }, + } } } else { panic("Unknown provider: " + testContext.Provider) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/persistent_volumes.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/persistent_volumes.go index 8341a27a0669..639dd2521c0f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/persistent_volumes.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/persistent_volumes.go @@ -18,14 +18,15 @@ package e2e import ( "fmt" + "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" - "time" ) // Marked with [Skipped] to skip the test by default (see driver.go), @@ -46,7 +47,7 @@ var _ = Describe("[Skipped] persistentVolumes", func() { AfterEach(func() { By(fmt.Sprintf("Destroying namespace for this suite %v", ns)) - if err := deleteNS(c, ns); err != nil { + if err := deleteNS(c, ns, 5*time.Minute /* namespace deletion timeout */); err != nil { Failf("Couldn't delete ns %s", err) } }) @@ -161,7 +162,7 @@ func makeCheckPod(ns string, nfsserver string) *api.Pod { // Prepare pod that mounts the NFS volume again and // checks that /mnt/index.html was scrubbed there return &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", APIVersion: testapi.Default.Version(), }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pods.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pods.go index 29e4a73332c9..9a1be3724f90 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pods.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pods.go @@ -40,7 +40,11 @@ import ( . "github.com/onsi/gomega" ) -func runLivenessTest(c *client.Client, ns string, podDescr *api.Pod, expectNumRestarts int) { +const ( + defaultObservationTimeout = time.Minute * 2 +) + +func runLivenessTest(c *client.Client, ns string, podDescr *api.Pod, expectNumRestarts int, timeout time.Duration) { By(fmt.Sprintf("Creating pod %s in namespace %s", podDescr.Name, ns)) _, err := c.Pods(ns).Create(podDescr) expectNoError(err, fmt.Sprintf("creating pod %s", podDescr.Name)) @@ -66,7 +70,7 @@ func runLivenessTest(c *client.Client, ns string, podDescr *api.Pod, expectNumRe By(fmt.Sprintf("Initial restart count of pod %s is %d", podDescr.Name, initialRestartCount)) // Wait for the restart state to be as desired. - deadline := time.Now().Add(2 * time.Minute) + deadline := time.Now().Add(timeout) lastRestartCount := initialRestartCount observedRestarts := 0 for start := time.Now(); time.Now().Before(deadline); time.Sleep(2 * time.Second) { @@ -133,7 +137,7 @@ func testHostIP(c *client.Client, ns string, pod *api.Pod) { var _ = Describe("Pods", func() { framework := NewFramework("pods") - PIt("should get a host IP", func() { + PIt("should get a host IP [Conformance]", func() { name := "pod-hostip-" + string(util.NewUUID()) testHostIP(framework.Client, framework.Namespace.Name, &api.Pod{ ObjectMeta: api.ObjectMeta{ @@ -143,14 +147,14 @@ var _ = Describe("Pods", func() { Containers: []api.Container{ { Name: "test", - Image: "gcr.io/google_containers/pause", + Image: "beta.gcr.io/google_containers/pause:2.0", }, }, }, }) }) - It("should be schedule with cpu and memory limits", func() { + It("should be schedule with cpu and memory limits [Conformance]", func() { podClient := framework.Client.Pods(framework.Namespace.Name) By("creating the pod") @@ -168,7 +172,7 @@ var _ = Describe("Pods", func() { Containers: []api.Container{ { Name: "nginx", - Image: "gcr.io/google_containers/pause", + Image: "beta.gcr.io/google_containers/pause:2.0", Resources: api.ResourceRequirements{ Limits: api.ResourceList{ api.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI), @@ -187,7 +191,7 @@ var _ = Describe("Pods", func() { expectNoError(framework.WaitForPodRunning(pod.Name)) }) - It("should be submitted and removed", func() { + It("should be submitted and removed [Conformance]", func() { podClient := framework.Client.Pods(framework.Namespace.Name) By("creating the pod") @@ -295,7 +299,7 @@ var _ = Describe("Pods", func() { Expect(len(pods.Items)).To(Equal(0)) }) - It("should be updated", func() { + It("should be updated [Conformance]", func() { podClient := framework.Client.Pods(framework.Namespace.Name) By("creating the pod") @@ -377,7 +381,7 @@ var _ = Describe("Pods", func() { Logf("Pod update OK") }) - It("should contain environment variables for services", func() { + It("should contain environment variables for services [Conformance]", func() { // Make a pod that will be a service. // This pod serves its hostname via HTTP. serverName := "server-envvars-" + string(util.NewUUID()) @@ -464,7 +468,7 @@ var _ = Describe("Pods", func() { }) }) - It("should be restarted with a docker exec \"cat /tmp/health\" liveness probe", func() { + It("should be restarted with a docker exec \"cat /tmp/health\" liveness probe [Conformance]", func() { runLivenessTest(framework.Client, framework.Namespace.Name, &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "liveness-exec", @@ -487,10 +491,10 @@ var _ = Describe("Pods", func() { }, }, }, - }, 1) + }, 1, defaultObservationTimeout) }) - It("should *not* be restarted with a docker exec \"cat /tmp/health\" liveness probe", func() { + It("should *not* be restarted with a docker exec \"cat /tmp/health\" liveness probe [Conformance]", func() { runLivenessTest(framework.Client, framework.Namespace.Name, &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "liveness-exec", @@ -513,10 +517,10 @@ var _ = Describe("Pods", func() { }, }, }, - }, 0) + }, 0, defaultObservationTimeout) }) - It("should be restarted with a /healthz http liveness probe", func() { + It("should be restarted with a /healthz http liveness probe [Conformance]", func() { runLivenessTest(framework.Client, framework.Namespace.Name, &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "liveness-http", @@ -540,10 +544,10 @@ var _ = Describe("Pods", func() { }, }, }, - }, 1) + }, 1, defaultObservationTimeout) }) - PIt("should have monotonically increasing restart count", func() { + It("should have monotonically increasing restart count [Conformance]", func() { runLivenessTest(framework.Client, framework.Namespace.Name, &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "liveness-http", @@ -567,10 +571,10 @@ var _ = Describe("Pods", func() { }, }, }, - }, 8) + }, 5, time.Minute*5) }) - It("should *not* be restarted with a /healthz http liveness probe", func() { + It("should *not* be restarted with a /healthz http liveness probe [Conformance]", func() { runLivenessTest(framework.Client, framework.Namespace.Name, &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "liveness-http", @@ -600,7 +604,7 @@ var _ = Describe("Pods", func() { }, }, }, - }, 0) + }, 0, defaultObservationTimeout) }) It("should support remote command execution over websockets", func() { @@ -751,7 +755,6 @@ var _ = Describe("Pods", func() { } }) - // The following tests for remote command execution and port forwarding are // commented out because the GCE environment does not currently have nsenter // in the kubelet's PATH, nor does it have socat installed. Once we figure @@ -814,7 +817,7 @@ var _ = Describe("Pods", func() { pod.Status.Host, pod.Name, pod.Spec.Containers[0].Name)) req := framework.Client.Get(). Prefix("proxy"). - Resource("minions"). + Resource("nodes"). Name(pod.Status.Host). Suffix("exec", framework.Namespace.Name, pod.Name, pod.Spec.Containers[0].Name) @@ -888,7 +891,7 @@ var _ = Describe("Pods", func() { req := framework.Client.Get(). Prefix("proxy"). - Resource("minions"). + Resource("nodes"). Name(pod.Status.Host). Suffix("portForward", framework.Namespace.Name, pod.Name) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/portforward.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/portforward.go new file mode 100644 index 000000000000..4f34af227453 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/portforward.go @@ -0,0 +1,234 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 e2e + +import ( + "fmt" + "io/ioutil" + "net" + "os/exec" + "regexp" + "strconv" + "strings" + + "k8s.io/kubernetes/pkg/api" + + . "github.com/onsi/ginkgo" +) + +const ( + podName = "pfpod" +) + +// TODO support other ports besides 80 +var portForwardRegexp = regexp.MustCompile("Forwarding from 127.0.0.1:([0-9]+) -> 80") + +func pfPod(expectedClientData, chunks, chunkSize, chunkIntervalMillis string) *api.Pod { + return &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: podName, + Labels: map[string]string{"name": podName}, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "portforwardtester", + Image: "gcr.io/google_containers/portforwardtester:1.0", + Env: []api.EnvVar{ + { + Name: "BIND_PORT", + Value: "80", + }, + { + Name: "EXPECTED_CLIENT_DATA", + Value: expectedClientData, + }, + { + Name: "CHUNKS", + Value: chunks, + }, + { + Name: "CHUNK_SIZE", + Value: chunkSize, + }, + { + Name: "CHUNK_INTERVAL", + Value: chunkIntervalMillis, + }, + }, + }, + }, + RestartPolicy: api.RestartPolicyNever, + }, + } +} + +func runPortForward(ns, podName string, port int) (*exec.Cmd, int) { + cmd := kubectlCmd("port-forward", fmt.Sprintf("--namespace=%v", ns), podName, fmt.Sprintf(":%d", port)) + // This is somewhat ugly but is the only way to retrieve the port that was picked + // by the port-forward command. We don't want to hard code the port as we have no + // way of guaranteeing we can pick one that isn't in use, particularly on Jenkins. + Logf("starting port-forward command and streaming output") + stdout, stderr, err := startCmdAndStreamOutput(cmd) + if err != nil { + Failf("Failed to start port-forward command: %v", err) + } + defer stdout.Close() + defer stderr.Close() + + buf := make([]byte, 128) + var n int + Logf("reading from `kubectl port-forward` command's stderr") + if n, err = stderr.Read(buf); err != nil { + Failf("Failed to read from kubectl port-forward stderr: %v", err) + } + portForwardOutput := string(buf[:n]) + match := portForwardRegexp.FindStringSubmatch(portForwardOutput) + if len(match) != 2 { + Failf("Failed to parse kubectl port-forward output: %s", portForwardOutput) + } + + listenPort, err := strconv.Atoi(match[1]) + if err != nil { + Failf("Error converting %s to an int: %v", match[1], err) + } + + return cmd, listenPort +} + +var _ = Describe("Port forwarding", func() { + framework := NewFramework("port-forwarding") + + Describe("With a server that expects a client request", func() { + It("should support a client that connects, sends no data, and disconnects [Conformance]", func() { + By("creating the target pod") + pod := pfPod("abc", "1", "1", "1") + framework.Client.Pods(framework.Namespace.Name).Create(pod) + framework.WaitForPodRunning(pod.Name) + + By("Running 'kubectl port-forward'") + cmd, listenPort := runPortForward(framework.Namespace.Name, pod.Name, 80) + defer tryKill(cmd) + + By("Dialing the local port") + conn, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", listenPort)) + if err != nil { + Failf("Couldn't connect to port %d: %v", listenPort, err) + } + + By("Closing the connection to the local port") + conn.Close() + + logOutput := runKubectl("logs", fmt.Sprintf("--namespace=%v", framework.Namespace.Name), "-f", podName) + verifyLogMessage(logOutput, "Accepted client connection") + verifyLogMessage(logOutput, "Expected to read 3 bytes from client, but got 0 instead") + }) + + It("should support a client that connects, sends data, and disconnects [Conformance]", func() { + By("creating the target pod") + pod := pfPod("abc", "10", "10", "100") + framework.Client.Pods(framework.Namespace.Name).Create(pod) + framework.WaitForPodRunning(pod.Name) + + By("Running 'kubectl port-forward'") + cmd, listenPort := runPortForward(framework.Namespace.Name, pod.Name, 80) + defer tryKill(cmd) + + By("Dialing the local port") + addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("127.0.0.1:%d", listenPort)) + if err != nil { + Failf("Error resolving tcp addr: %v", err) + } + conn, err := net.DialTCP("tcp", nil, addr) + if err != nil { + Failf("Couldn't connect to port %d: %v", listenPort, err) + } + defer func() { + By("Closing the connection to the local port") + conn.Close() + }() + + By("Sending the expected data to the local port") + fmt.Fprint(conn, "abc") + + By("Closing the write half of the client's connection") + conn.CloseWrite() + + By("Reading data from the local port") + fromServer, err := ioutil.ReadAll(conn) + if err != nil { + Failf("Unexpected error reading data from the server: %v", err) + } + + if e, a := strings.Repeat("x", 100), string(fromServer); e != a { + Failf("Expected %q from server, got %q", e, a) + } + + logOutput := runKubectl("logs", fmt.Sprintf("--namespace=%v", framework.Namespace.Name), "-f", podName) + verifyLogMessage(logOutput, "^Accepted client connection$") + verifyLogMessage(logOutput, "^Received expected client data$") + verifyLogMessage(logOutput, "^Done$") + }) + }) + Describe("With a server that expects no client request", func() { + It("should support a client that connects, sends no data, and disconnects [Conformance]", func() { + By("creating the target pod") + pod := pfPod("", "10", "10", "100") + framework.Client.Pods(framework.Namespace.Name).Create(pod) + framework.WaitForPodRunning(pod.Name) + + By("Running 'kubectl port-forward'") + cmd, listenPort := runPortForward(framework.Namespace.Name, pod.Name, 80) + defer tryKill(cmd) + + By("Dialing the local port") + conn, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", listenPort)) + if err != nil { + Failf("Couldn't connect to port %d: %v", listenPort, err) + } + defer func() { + By("Closing the connection to the local port") + conn.Close() + }() + + By("Reading data from the local port") + fromServer, err := ioutil.ReadAll(conn) + if err != nil { + Failf("Unexpected error reading data from the server: %v", err) + } + + if e, a := strings.Repeat("x", 100), string(fromServer); e != a { + Failf("Expected %q from server, got %q", e, a) + } + + logOutput := runKubectl("logs", fmt.Sprintf("--namespace=%v", framework.Namespace.Name), "-f", podName) + verifyLogMessage(logOutput, "Accepted client connection") + verifyLogMessage(logOutput, "Done") + }) + }) +}) + +func verifyLogMessage(log, expected string) { + re := regexp.MustCompile(expected) + lines := strings.Split(log, "\n") + for i := range lines { + if re.MatchString(lines[i]) { + return + } + } + Failf("Missing %q from log: %s", expected, log) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pre_stop.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pre_stop.go index abb1804d0c88..eee668d881fe 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pre_stop.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/pre_stop.go @@ -144,7 +144,7 @@ func testPreStop(c *client.Client, ns string) { var _ = Describe("PreStop", func() { f := NewFramework("prestop") - It("should call prestop when killing a pod", func() { + It("should call prestop when killing a pod [Conformance]", func() { testPreStop(f.Client, f.Namespace.Name) }) }) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/privileged.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/privileged.go new file mode 100644 index 000000000000..b2cf98e08f18 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/privileged.go @@ -0,0 +1,181 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 e2e + +import ( + "encoding/json" + "fmt" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" + client "k8s.io/kubernetes/pkg/client/unversioned" + "net/url" +) + +const ( + privilegedPodName = "privileged-pod" + privilegedContainerName = "privileged-container" + privilegedHttpPort = 8080 + privilegedUdpPort = 8081 + notPrivilegedHttpPort = 9090 + notPrivilegedUdpPort = 9091 + notPrivilegedContainerName = "not-privileged-container" + privilegedContainerImage = "gcr.io/google_containers/netexec:1.1" + privilegedCommand = "ip link add dummy1 type dummy" +) + +type PrivilegedPodTestConfig struct { + privilegedPod *api.Pod + f *Framework + nodes []string +} + +var _ = Describe("PrivilegedPod", func() { + f := NewFramework("e2e-privilegedpod") + config := &PrivilegedPodTestConfig{ + f: f, + } + It("should test privileged pod", func() { + SkipUnlessProviderIs(providersWithSSH...) + + By("Getting ssh-able hosts") + hosts, err := NodeSSHHosts(config.f.Client) + Expect(err).NotTo(HaveOccurred()) + if len(hosts) == 0 { + Failf("No ssh-able nodes") + } + config.nodes = hosts + + By("Creating a privileged pod") + config.createPrivilegedPod() + + By("Executing privileged command on privileged container") + config.runPrivilegedCommandOnPrivilegedContainer() + + By("Executing privileged command on non-privileged container") + config.runPrivilegedCommandOnNonPrivilegedContainer() + }) +}) + +func (config *PrivilegedPodTestConfig) runPrivilegedCommandOnPrivilegedContainer() { + outputMap := config.dialFromContainer(config.privilegedPod.Status.PodIP, privilegedHttpPort) + if len(outputMap["error"]) > 0 { + Failf("Privileged command failed unexpectedly on privileged container, output:%v", outputMap) + } +} + +func (config *PrivilegedPodTestConfig) runPrivilegedCommandOnNonPrivilegedContainer() { + outputMap := config.dialFromContainer(config.privilegedPod.Status.PodIP, notPrivilegedHttpPort) + if len(outputMap["error"]) == 0 { + Failf("Privileged command should have failed on non-privileged container, output:%v", outputMap) + } +} + +func (config *PrivilegedPodTestConfig) dialFromContainer(containerIP string, containerHttpPort int) map[string]string { + v := url.Values{} + v.Set("shellCommand", "ip link add dummy1 type dummy") + cmd := fmt.Sprintf("curl -q 'http://%s:%d/shell?%s'", + containerIP, + containerHttpPort, + v.Encode()) + + By(fmt.Sprintf("Exec-ing into container over http. Running command:%s", cmd)) + stdout := config.ssh(cmd) + Logf("Output is %q", stdout) + var output map[string]string + err := json.Unmarshal([]byte(stdout), &output) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Could not unmarshal curl response: %s", stdout)) + Logf("Deserialized output is %v", stdout) + return output +} + +func (config *PrivilegedPodTestConfig) createPrivilegedPodSpec() *api.Pod { + isPrivileged := true + notPrivileged := false + pod := &api.Pod{ + TypeMeta: unversioned.TypeMeta{ + Kind: "Pod", + APIVersion: latest.GroupOrDie("").Version, + }, + ObjectMeta: api.ObjectMeta{ + Name: privilegedPodName, + Namespace: config.f.Namespace.Name, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: privilegedContainerName, + Image: privilegedContainerImage, + ImagePullPolicy: api.PullIfNotPresent, + SecurityContext: &api.SecurityContext{Privileged: &isPrivileged}, + Command: []string{ + "/netexec", + fmt.Sprintf("--http-port=%d", privilegedHttpPort), + fmt.Sprintf("--udp-port=%d", privilegedUdpPort), + }, + }, + { + Name: notPrivilegedContainerName, + Image: privilegedContainerImage, + ImagePullPolicy: api.PullIfNotPresent, + SecurityContext: &api.SecurityContext{Privileged: ¬Privileged}, + Command: []string{ + "/netexec", + fmt.Sprintf("--http-port=%d", notPrivilegedHttpPort), + fmt.Sprintf("--udp-port=%d", notPrivilegedUdpPort), + }, + }, + }, + }, + } + return pod +} + +func (config *PrivilegedPodTestConfig) createPrivilegedPod() { + podSpec := config.createPrivilegedPodSpec() + config.privilegedPod = config.createPod(podSpec) +} + +func (config *PrivilegedPodTestConfig) createPod(pod *api.Pod) *api.Pod { + createdPod, err := config.getPodClient().Create(pod) + if err != nil { + Failf("Failed to create %q pod: %v", pod.Name, err) + } + expectNoError(config.f.WaitForPodRunning(pod.Name)) + createdPod, err = config.getPodClient().Get(pod.Name) + if err != nil { + Failf("Failed to retrieve %q pod: %v", pod.Name, err) + } + return createdPod +} + +func (config *PrivilegedPodTestConfig) getPodClient() client.PodInterface { + return config.f.Client.Pods(config.f.Namespace.Name) +} + +func (config *PrivilegedPodTestConfig) getNamespaceClient() client.NamespaceInterface { + return config.f.Client.Namespaces() +} + +func (config *PrivilegedPodTestConfig) ssh(cmd string) string { + stdout, _, code, err := SSH(cmd, config.nodes[0], testContext.Provider) + Expect(err).NotTo(HaveOccurred(), "error while SSH-ing to node: %v (code %v)", err, code) + Expect(code).Should(BeZero(), "command exited with non-zero code %v. cmd:%s", code, cmd) + return stdout +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/prompush.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/prompush.go index 2f76123e4c36..a8af6faad7a2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/prompush.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/prompush.go @@ -19,6 +19,7 @@ package e2e import ( "fmt" + "github.com/prometheus/client_golang/prometheus" ) @@ -38,9 +39,7 @@ var prom_registered = false // Reusable function for pushing metrics to prometheus. Handles initialization and so on. func promPushRunningPending(running, pending int) error { - if testContext.PrometheusPushGateway == "" { - Logf("Ignoring prom push, push gateway unavailable") return nil } else { // Register metrics if necessary diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/proxy.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/proxy.go index 5217fc06d648..69230b7b26b4 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/proxy.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/proxy.go @@ -53,13 +53,13 @@ func proxyContext(version string) { prefix := "/api/" + version // Port here has to be kept in sync with default kubelet port. - It("should proxy logs on node with explicit kubelet port", func() { nodeProxyTest(f, version, ":10250/logs/") }) + It("should proxy logs on node with explicit kubelet port [Conformance]", func() { nodeProxyTest(f, version, ":10250/logs/") }) - It("should proxy logs on node", func() { nodeProxyTest(f, version, "/logs/") }) + It("should proxy logs on node [Conformance]", func() { nodeProxyTest(f, version, "/logs/") }) - It("should proxy to cadvisor", func() { nodeProxyTest(f, version, ":4194/containers/") }) + It("should proxy to cadvisor [Conformance]", func() { nodeProxyTest(f, version, ":4194/containers/") }) - It("should proxy through a service and a pod", func() { + It("should proxy through a service and a pod [Conformance]", func() { labels := map[string]string{"proxy-service-target": "true"} service, err := f.Client.Services(f.Namespace.Name).Create(&api.Service{ ObjectMeta: api.ObjectMeta{ diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/rc.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/rc.go index 409b91505ded..0797e7f8e2b6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/rc.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/rc.go @@ -33,7 +33,7 @@ import ( var _ = Describe("ReplicationController", func() { framework := NewFramework("replication-controller") - It("should serve a basic image on each replica with a public image", func() { + It("should serve a basic image on each replica with a public image [Conformance]", func() { ServeImageOrFail(framework, "basic", "gcr.io/google_containers/serve_hostname:1.1") }) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/resize_nodes.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/resize_nodes.go index c3674726a01e..dbcd54ab7117 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/resize_nodes.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/resize_nodes.go @@ -25,6 +25,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -183,9 +184,9 @@ func rcByNameContainer(name string, replicas int, image string, labels map[strin // Add "name": name to the labels, overwriting if it exists. labels["name"] = name return &api.ReplicationController{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "ReplicationController", - APIVersion: latest.Version, + APIVersion: latest.GroupOrDie("").Version, }, ObjectMeta: api.ObjectMeta{ Name: name, @@ -225,7 +226,7 @@ func resizeRC(c *client.Client, ns, name string, replicas int) error { } func podsCreated(c *client.Client, ns, name string, replicas int) (*api.PodList, error) { - timeout := time.Minute + timeout := 2 * time.Minute // List the pods, making sure we observe all the replicas. label := labels.SelectorFromSet(labels.Set(map[string]string{"name": name})) for start := time.Now(); time.Since(start) < timeout; time.Sleep(5 * time.Second) { @@ -319,7 +320,7 @@ func performTemporaryNetworkFailure(c *client.Client, ns, rcName string, replica default: Failf("This test is not supported for provider %s and should be disabled", testContext.Provider) } - iptablesRule := fmt.Sprintf("OUTPUT --destination %s --jump DROP", master) + iptablesRule := fmt.Sprintf("OUTPUT --destination %s --jump REJECT", master) defer func() { // This code will execute even if setting the iptables rule failed. // It is on purpose because we may have an error even if the new rule @@ -345,7 +346,7 @@ func performTemporaryNetworkFailure(c *client.Client, ns, rcName string, replica } }) if err != nil { - Failf("Failed to remove the iptable DROP rule. Manual intervention is "+ + Failf("Failed to remove the iptable REJECT rule. Manual intervention is "+ "required on node %s: remove rule %s, if exists", node.Name, iptablesRule) } }() @@ -383,31 +384,17 @@ func performTemporaryNetworkFailure(c *client.Client, ns, rcName string, replica } var _ = Describe("Nodes", func() { + framework := Framework{BaseName: "resize-nodes"} var c *client.Client var ns string BeforeEach(func() { - var err error - c, err = loadClient() - expectNoError(err) - testingNs, err := createTestingNS("resize-nodes", c) - ns = testingNs.Name - Expect(err).NotTo(HaveOccurred()) + framework.beforeEach() + c = framework.Client + ns = framework.Namespace.Name }) - AfterEach(func() { - By("checking whether all nodes are healthy") - if err := allNodesReady(c, time.Minute); err != nil { - Failf("Not all nodes are ready: %v", err) - } - By(fmt.Sprintf("destroying namespace for this suite %s", ns)) - if err := deleteNS(c, ns); err != nil { - Failf("Couldn't delete namespace '%s', %v", ns, err) - } - if err := deleteTestingNS(c); err != nil { - Failf("Couldn't delete testing namespaces '%s', %v", ns, err) - } - }) + AfterEach(framework.afterEach) Describe("Resize", func() { var skipped bool diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/restart.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/restart.go index 3ee924231df1..33fa9dc635c0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/restart.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/restart.go @@ -225,7 +225,7 @@ func restartNodes(provider string, nt time.Duration) error { // with the following bash, but needs to be written in Go: // // # Step 1: Get instance names. -// list=$(gcloud preview instance-groups --project=${PROJECT} --zone=${ZONE} instances --group=${GROUP} list) +// list=$(gcloud compute instance-groups --project=${PROJECT} --zone=${ZONE} instances --group=${GROUP} list) // i="" // for l in $list; do // i="${l##*/},${i}" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/scheduler_predicates.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/scheduler_predicates.go index 13ac3c3c8368..b2cbafcf1152 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/scheduler_predicates.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/scheduler_predicates.go @@ -22,6 +22,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -31,13 +32,13 @@ import ( . "github.com/onsi/gomega" ) -// Returns a number of currently running and not running Pods. -func getPodsNumbers(pods *api.PodList) (runningPods, notRunningPods int) { +// Returns a number of currently scheduled and not scheduled Pods. +func getPodsScheduled(pods *api.PodList) (scheduledPods, notScheduledPods []api.Pod) { for _, pod := range pods.Items { - if pod.Status.Phase == api.PodRunning { - runningPods += 1 + if pod.Spec.NodeName != "" { + scheduledPods = append(scheduledPods, pod) } else { - notRunningPods += 1 + notScheduledPods = append(notScheduledPods, pod) } } return @@ -48,7 +49,7 @@ func getPodsNumbers(pods *api.PodList) (runningPods, notRunningPods int) { func startPods(c *client.Client, replicas int, ns string, podNamePrefix string, pod api.Pod) { allPods, err := c.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()) expectNoError(err) - podsRunningBefore, _ := getPodsNumbers(allPods) + podsScheduledBefore, _ := getPodsScheduled(allPods) for i := 0; i < replicas; i++ { podName := fmt.Sprintf("%v-%v", podNamePrefix, i) @@ -65,25 +66,25 @@ func startPods(c *client.Client, replicas int, ns string, podNamePrefix string, // completely broken vs. running slowly. timeout := 10 * time.Minute startTime := time.Now() - currentlyRunningPods := 0 - for podsRunningBefore+replicas != currentlyRunningPods { + currentlyScheduledPods := 0 + for len(podsScheduledBefore)+replicas != currentlyScheduledPods { allPods, err := c.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()) expectNoError(err) - runningPods := 0 + scheduledPods := 0 for _, pod := range allPods.Items { - if pod.Status.Phase == api.PodRunning { - runningPods += 1 + if pod.Spec.NodeName != "" { + scheduledPods += 1 } } - currentlyRunningPods = runningPods - Logf("%v pods running", currentlyRunningPods) + currentlyScheduledPods = scheduledPods + Logf("%v pods running", currentlyScheduledPods) if startTime.Add(timeout).Before(time.Now()) { Logf("Timed out after %v waiting for pods to start running.", timeout) break } time.Sleep(5 * time.Second) } - Expect(currentlyRunningPods).To(Equal(podsRunningBefore + replicas)) + Expect(currentlyScheduledPods).To(Equal(len(podsScheduledBefore) + replicas)) } func getRequestedCPU(pod api.Pod) int64 { @@ -94,10 +95,10 @@ func getRequestedCPU(pod api.Pod) int64 { return result } -func verifyResult(c *client.Client, podName string, ns string, oldNotRunning int) { +func verifyResult(c *client.Client, podName string, ns string) { allPods, err := c.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()) expectNoError(err) - _, notRunningPods := getPodsNumbers(allPods) + scheduledPods, notScheduledPods := getPodsScheduled(allPods) schedEvents, err := c.Events(ns).List( labels.Everything(), @@ -120,8 +121,8 @@ func verifyResult(c *client.Client, podName string, ns string, oldNotRunning int } } - Expect(notRunningPods).To(Equal(1+oldNotRunning), printOnce(fmt.Sprintf("Pods found in the cluster: %#v", allPods))) - Expect(schedEvents.Items).ToNot(BeEmpty(), printOnce(fmt.Sprintf("Pods found in the cluster: %#v", allPods))) + Expect(len(notScheduledPods)).To(Equal(1), printOnce(fmt.Sprintf("Not scheduled Pods: %#v", notScheduledPods))) + Expect(schedEvents.Items).ToNot(BeEmpty(), printOnce(fmt.Sprintf("Scheduled Pods: %#v", scheduledPods))) } func cleanupPods(c *client.Client, ns string) { @@ -134,31 +135,44 @@ func cleanupPods(c *client.Client, ns string) { } } +// Waits until all existing pods are scheduled and returns their amount. +func waitForStableCluster(c *client.Client) int { + timeout := 10 * time.Minute + startTime := time.Now() + + allPods, err := c.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()) + expectNoError(err) + scheduledPods, currentlyNotScheduledPods := getPodsScheduled(allPods) + for len(currentlyNotScheduledPods) != 0 { + time.Sleep(2 * time.Second) + + allPods, err := c.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()) + expectNoError(err) + scheduledPods, currentlyNotScheduledPods = getPodsScheduled(allPods) + + if startTime.Add(timeout).Before(time.Now()) { + Failf("Timed out after %v waiting for stable cluster.", timeout) + break + } + } + return len(scheduledPods) +} + var _ = Describe("SchedulerPredicates", func() { + framework := Framework{BaseName: "sched-pred"} var c *client.Client var nodeList *api.NodeList - var nodeCount int var totalPodCapacity int64 var RCName string var ns string - var uuid string BeforeEach(func() { + framework.beforeEach() + c = framework.Client + ns = framework.Namespace.Name var err error - c, err = loadClient() - expectNoError(err) nodeList, err = c.Nodes().List(labels.Everything(), fields.Everything()) expectNoError(err) - nodeCount = len(nodeList.Items) - Expect(nodeCount).NotTo(BeZero()) - - err = deleteTestingNS(c) - expectNoError(err) - - nsForTesting, err := createTestingNS("sched-pred", c) - ns = nsForTesting.Name - expectNoError(err) - uuid = string(util.NewUUID()) }) AfterEach(func() { @@ -168,17 +182,13 @@ var _ = Describe("SchedulerPredicates", func() { err := DeleteRC(c, ns, RCName) expectNoError(err) } - - By(fmt.Sprintf("Destroying namespace for this suite %v", ns)) - if err := deleteNS(c, ns); err != nil { - Failf("Couldn't delete ns %s", err) - } + framework.afterEach() }) // This test verifies that max-pods flag works as advertised. It assumes that cluster add-on pods stay stable // and cannot be run in parallel with any other test that touches Nodes or Pods. It is so because to check // if max-pods is working we need to fully saturate the cluster and keep it in this state for few seconds. - It("validates MaxPods limit number of pods that are allowed to run.", func() { + It("validates MaxPods limit number of pods that are allowed to run", func() { totalPodCapacity = 0 for _, node := range nodeList.Items { @@ -188,15 +198,13 @@ var _ = Describe("SchedulerPredicates", func() { Logf("Node: %v", node) } - allPods, err := c.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()) - expectNoError(err) - currentlyRunningPods, currentlyDeadPods := getPodsNumbers(allPods) - podsNeededForSaturation := int(totalPodCapacity) - currentlyRunningPods + currentlyScheduledPods := waitForStableCluster(c) + podsNeededForSaturation := int(totalPodCapacity) - currentlyScheduledPods By(fmt.Sprintf("Starting additional %v Pods to fully saturate the cluster max pods and trying to start another one", podsNeededForSaturation)) startPods(c, podsNeededForSaturation, ns, "maxp", api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", }, ObjectMeta: api.ObjectMeta{ @@ -207,15 +215,15 @@ var _ = Describe("SchedulerPredicates", func() { Containers: []api.Container{ { Name: "", - Image: "gcr.io/google_containers/pause:go", + Image: "beta.gcr.io/google_containers/pause:2.0", }, }, }, }) podName := "additional-pod" - _, err = c.Pods(ns).Create(&api.Pod{ - TypeMeta: api.TypeMeta{ + _, err := c.Pods(ns).Create(&api.Pod{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", }, ObjectMeta: api.ObjectMeta{ @@ -226,7 +234,7 @@ var _ = Describe("SchedulerPredicates", func() { Containers: []api.Container{ { Name: podName, - Image: "gcr.io/google_containers/pause:go", + Image: "beta.gcr.io/google_containers/pause:2.0", }, }, }, @@ -237,32 +245,30 @@ var _ = Describe("SchedulerPredicates", func() { Logf("Sleeping 10 seconds and crossing our fingers that scheduler will run in that time.") time.Sleep(10 * time.Second) - verifyResult(c, podName, ns, currentlyDeadPods) + verifyResult(c, podName, ns) cleanupPods(c, ns) }) // This test verifies we don't allow scheduling of pods in a way that sum of limits of pods is greater than machines capacity. // It assumes that cluster add-on pods stay stable and cannot be run in parallel with any other test that touches Nodes or Pods. // It is so because we need to have precise control on what's running in the cluster. - It("validates resource limits of pods that are allowed to run.", func() { + It("validates resource limits of pods that are allowed to run [Conformance]", func() { nodeToCapacityMap := make(map[string]int64) for _, node := range nodeList.Items { capacity, found := node.Status.Capacity["cpu"] Expect(found).To(Equal(true)) nodeToCapacityMap[node.Name] = capacity.MilliValue() } + waitForStableCluster(c) pods, err := c.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()) expectNoError(err) - var currentlyDeadPods int for _, pod := range pods.Items { _, found := nodeToCapacityMap[pod.Spec.NodeName] Expect(found).To(Equal(true)) if pod.Status.Phase == api.PodRunning { Logf("Pod %v requesting capacity %v on Node %v", pod.Name, getRequestedCPU(pod), pod.Spec.NodeName) nodeToCapacityMap[pod.Spec.NodeName] -= getRequestedCPU(pod) - } else { - currentlyDeadPods += 1 } } @@ -276,7 +282,7 @@ var _ = Describe("SchedulerPredicates", func() { By(fmt.Sprintf("Starting additional %v Pods to fully saturate the cluster CPU and trying to start another one", podsNeededForSaturation)) startPods(c, podsNeededForSaturation, ns, "overcommit", api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", }, ObjectMeta: api.ObjectMeta{ @@ -287,7 +293,7 @@ var _ = Describe("SchedulerPredicates", func() { Containers: []api.Container{ { Name: "", - Image: "gcr.io/google_containers/pause:go", + Image: "beta.gcr.io/google_containers/pause:2.0", Resources: api.ResourceRequirements{ Limits: api.ResourceList{ "cpu": *resource.NewMilliQuantity(milliCpuPerPod, "DecimalSI"), @@ -300,7 +306,7 @@ var _ = Describe("SchedulerPredicates", func() { podName := "additional-pod" _, err = c.Pods(ns).Create(&api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", }, ObjectMeta: api.ObjectMeta{ @@ -311,7 +317,7 @@ var _ = Describe("SchedulerPredicates", func() { Containers: []api.Container{ { Name: podName, - Image: "gcr.io/google_containers/pause:go", + Image: "beta.gcr.io/google_containers/pause:2.0", Resources: api.ResourceRequirements{ Limits: api.ResourceList{ "cpu": *resource.NewMilliQuantity(milliCpuPerPod, "DecimalSI"), @@ -327,22 +333,20 @@ var _ = Describe("SchedulerPredicates", func() { Logf("Sleeping 10 seconds and crossing our fingers that scheduler will run in that time.") time.Sleep(10 * time.Second) - verifyResult(c, podName, ns, currentlyDeadPods) + verifyResult(c, podName, ns) cleanupPods(c, ns) }) // Test Nodes does not have any label, hence it should be impossible to schedule Pod with // nonempty Selector set. - It("validates that NodeSelector is respected.", func() { + It("validates that NodeSelector is respected if not matching [Conformance]", func() { By("Trying to schedule Pod with nonempty NodeSelector.") podName := "restricted-pod" - allPods, err := c.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()) - expectNoError(err) - _, currentlyDeadPods := getPodsNumbers(allPods) + waitForStableCluster(c) - _, err = c.Pods(ns).Create(&api.Pod{ - TypeMeta: api.TypeMeta{ + _, err := c.Pods(ns).Create(&api.Pod{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", }, ObjectMeta: api.ObjectMeta{ @@ -353,7 +357,7 @@ var _ = Describe("SchedulerPredicates", func() { Containers: []api.Container{ { Name: podName, - Image: "gcr.io/google_containers/pause:go", + Image: "beta.gcr.io/google_containers/pause:2.0", }, }, NodeSelector: map[string]string{ @@ -367,7 +371,80 @@ var _ = Describe("SchedulerPredicates", func() { Logf("Sleeping 10 seconds and crossing our fingers that scheduler will run in that time.") time.Sleep(10 * time.Second) - verifyResult(c, podName, ns, currentlyDeadPods) + verifyResult(c, podName, ns) cleanupPods(c, ns) }) + + It("validates that NodeSelector is respected if matching [Conformance]", func() { + // launch a pod to find a node which can launch a pod. We intentionally do + // not just take the node list and choose the first of them. Depending on the + // cluster and the scheduler it might be that a "normal" pod cannot be + // scheduled onto it. + By("Trying to launch a pod without a label to get a node which can launch it.") + podName := "without-label" + _, err := c.Pods(ns).Create(&api.Pod{ + TypeMeta: unversioned.TypeMeta{ + Kind: "Pod", + }, + ObjectMeta: api.ObjectMeta{ + Name: podName, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: podName, + Image: "beta.gcr.io/google_containers/pause:2.0", + }, + }, + }, + }) + expectNoError(err) + expectNoError(waitForPodRunningInNamespace(c, podName, ns)) + pod, err := c.Pods(ns).Get(podName) + expectNoError(err) + + nodeName := pod.Spec.NodeName + err = c.Pods(ns).Delete(podName, api.NewDeleteOptions(0)) + expectNoError(err) + + By("Trying to apply a random label on the found node.") + k := fmt.Sprintf("kubernetes.io/e2e-%s", string(util.NewUUID())) + v := "42" + patch := fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s"}}}`, k, v) + err = c.Patch(api.MergePatchType).Resource("nodes").Name(nodeName).Body([]byte(patch)).Do().Error() + expectNoError(err) + + node, err := c.Nodes().Get(nodeName) + expectNoError(err) + Expect(node.Labels[k]).To(Equal(v)) + + By("Trying to relaunch the pod, now with labels.") + labelPodName := "with-labels" + _, err = c.Pods(ns).Create(&api.Pod{ + TypeMeta: unversioned.TypeMeta{ + Kind: "Pod", + }, + ObjectMeta: api.ObjectMeta{ + Name: labelPodName, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: labelPodName, + Image: "beta.gcr.io/google_containers/pause:2.0", + }, + }, + NodeSelector: map[string]string{ + "kubernetes.io/hostname": nodeName, + k: v, + }, + }, + }) + expectNoError(err) + defer c.Pods(ns).Delete(labelPodName, api.NewDeleteOptions(0)) + expectNoError(waitForPodRunningInNamespace(c, labelPodName, ns)) + labelPod, err := c.Pods(ns).Get(labelPodName) + expectNoError(err) + Expect(labelPod.Spec.NodeName).To(Equal(nodeName)) + }) }) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/secrets.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/secrets.go index 17f21e3e6014..b67e172e07ad 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/secrets.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/secrets.go @@ -28,7 +28,7 @@ import ( var _ = Describe("Secrets", func() { f := NewFramework("secrets") - It("should be consumable from pods", func() { + It("should be consumable from pods [Conformance]", func() { name := "secret-test-" + string(util.NewUUID()) volumeName := "secret-volume" volumeMountPath := "/etc/secret-volume" @@ -92,7 +92,7 @@ var _ = Describe("Secrets", func() { }, } - testContainerOutputInNamespace("consume secrets", f.Client, pod, 0, []string{ + testContainerOutput("consume secrets", f.Client, pod, 0, []string{ "content of file \"/etc/secret-volume/data-1\": value-1", "mode of file \"/etc/secret-volume/data-1\": -r--r--r--", }, f.Namespace.Name) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service.go index 7602f5b2d3f5..9c0b2e0f1c89 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service.go @@ -26,7 +26,6 @@ import ( "strings" "time" - "github.com/golang/glog" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "k8s.io/kubernetes/pkg/api" @@ -46,45 +45,40 @@ var _ = Describe("Services", func() { f := NewFramework("services") var c *client.Client - // Use these in tests. They're unique for each test to prevent name collisions. - var namespaces [2]string + var extraNamespaces []string BeforeEach(func() { var err error c, err = loadClient() Expect(err).NotTo(HaveOccurred()) - - By("Building a namespace api objects") - for i := range namespaces { - namespacePtr, err := createTestingNS(fmt.Sprintf("service-%d", i), c) - Expect(err).NotTo(HaveOccurred()) - namespaces[i] = namespacePtr.Name - } }) AfterEach(func() { - for _, ns := range namespaces { + for _, ns := range extraNamespaces { By(fmt.Sprintf("Destroying namespace %v", ns)) - if err := deleteNS(c, ns); err != nil { + if err := deleteNS(c, ns, 5*time.Minute /* namespace deletion timeout */); err != nil { Failf("Couldn't delete namespace %s: %s", ns, err) } } + extraNamespaces = nil }) // TODO: We get coverage of TCP/UDP and multi-port services through the DNS test. We should have a simpler test for multi-port TCP here. - It("should provide secure master service", func() { + + It("should provide secure master service [Conformance]", func() { _, err := c.Services(api.NamespaceDefault).Get("kubernetes") Expect(err).NotTo(HaveOccurred()) }) - It("should serve a basic endpoint from pods", func() { + It("should serve a basic endpoint from pods [Conformance]", func() { serviceName := "endpoint-test2" - ns := namespaces[0] + ns := f.Namespace.Name labels := map[string]string{ "foo": "bar", "baz": "blah", } + By("creating service " + serviceName + " in namespace " + ns) defer func() { err := c.Services(ns).Delete(serviceName) Expect(err).NotTo(HaveOccurred()) @@ -107,43 +101,38 @@ var _ = Describe("Services", func() { validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{}) - var names []string + names := map[string]bool{} defer func() { - for _, name := range names { + for name := range names { err := c.Pods(ns).Delete(name, nil) Expect(err).NotTo(HaveOccurred()) } }() - name1 := "test1" - addEndpointPodOrFail(c, ns, name1, labels, []api.ContainerPort{{ContainerPort: 80}}) - names = append(names, name1) + name1 := "pod1" + name2 := "pod2" + createPodOrFail(c, ns, name1, labels, []api.ContainerPort{{ContainerPort: 80}}) + names[name1] = true validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{name1: {80}}) - name2 := "test2" - addEndpointPodOrFail(c, ns, name2, labels, []api.ContainerPort{{ContainerPort: 80}}) - names = append(names, name2) - + createPodOrFail(c, ns, name2, labels, []api.ContainerPort{{ContainerPort: 80}}) + names[name2] = true validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{name1: {80}, name2: {80}}) - err = c.Pods(ns).Delete(name1, nil) - Expect(err).NotTo(HaveOccurred()) - names = []string{name2} - + deletePodOrFail(c, ns, name1) + delete(names, name1) validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{name2: {80}}) - err = c.Pods(ns).Delete(name2, nil) - Expect(err).NotTo(HaveOccurred()) - names = []string{} - + deletePodOrFail(c, ns, name2) + delete(names, name2) validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{}) }) - It("should serve multiport endpoints from pods", func() { + It("should serve multiport endpoints from pods [Conformance]", func() { // repacking functionality is intentionally not tested here - it's better to test it in an integration test. serviceName := "multi-endpoint-test" - ns := namespaces[0] + ns := f.Namespace.Name defer func() { err := c.Services(ns).Delete(serviceName) @@ -155,6 +144,7 @@ var _ = Describe("Services", func() { svc1port := "svc1" svc2port := "svc2" + By("creating service " + serviceName + " in namespace " + ns) service := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: serviceName, @@ -181,9 +171,9 @@ var _ = Describe("Services", func() { port2 := 101 validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{}) - var names []string + names := map[string]bool{} defer func() { - for _, name := range names { + for name := range names { err := c.Pods(ns).Delete(name, nil) Expect(err).NotTo(HaveOccurred()) } @@ -202,44 +192,30 @@ var _ = Describe("Services", func() { }, } - podname1 := "podname1" - addEndpointPodOrFail(c, ns, podname1, labels, containerPorts1) - names = append(names, podname1) + podname1 := "pod1" + podname2 := "pod2" + + createPodOrFail(c, ns, podname1, labels, containerPorts1) + names[podname1] = true validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{podname1: {port1}}) - podname2 := "podname2" - addEndpointPodOrFail(c, ns, podname2, labels, containerPorts2) - names = append(names, podname2) + createPodOrFail(c, ns, podname2, labels, containerPorts2) + names[podname2] = true validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{podname1: {port1}, podname2: {port2}}) - podname3 := "podname3" - addEndpointPodOrFail(c, ns, podname3, labels, append(containerPorts1, containerPorts2...)) - names = append(names, podname3) - validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{podname1: {port1}, podname2: {port2}, podname3: {port1, port2}}) - - err = c.Pods(ns).Delete(podname1, nil) - Expect(err).NotTo(HaveOccurred()) - names = []string{podname2, podname3} - - validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{podname2: {port2}, podname3: {port1, port2}}) - - err = c.Pods(ns).Delete(podname2, nil) - Expect(err).NotTo(HaveOccurred()) - names = []string{podname3} - - validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{podname3: {port1, port2}}) - - err = c.Pods(ns).Delete(podname3, nil) - Expect(err).NotTo(HaveOccurred()) - names = []string{} + deletePodOrFail(c, ns, podname1) + delete(names, podname1) + validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{podname2: {port2}}) + deletePodOrFail(c, ns, podname2) + delete(names, podname2) validateEndpointsOrFail(c, ns, serviceName, PortsByPodName{}) }) It("should be able to up and down services", func() { // this test uses NodeSSHHosts that does not work if a Node only reports LegacyHostIP - SkipUnlessProviderIs("gce", "gke", "aws") - ns := namespaces[0] + SkipUnlessProviderIs(providersWithSSH...) + ns := f.Namespace.Name numPods, servicePort := 3, 80 podNames1, svc1IP, err := startServeHostnameService(c, ns, "service1", servicePort, numPods) @@ -281,14 +257,18 @@ var _ = Describe("Services", func() { It("should work after restarting kube-proxy", func() { SkipUnlessProviderIs("gce", "gke") - ns := namespaces[0] + ns := f.Namespace.Name numPods, servicePort := 3, 80 - defer func() { expectNoError(stopServeHostnameService(c, ns, "service1")) }() - podNames1, svc1IP, err := startServeHostnameService(c, ns, "service1", servicePort, numPods) + svc1 := "service1" + svc2 := "service2" + + defer func() { expectNoError(stopServeHostnameService(c, ns, svc1)) }() + podNames1, svc1IP, err := startServeHostnameService(c, ns, svc1, servicePort, numPods) Expect(err).NotTo(HaveOccurred()) - defer func() { expectNoError(stopServeHostnameService(c, ns, "service2")) }() - podNames2, svc2IP, err := startServeHostnameService(c, ns, "service2", servicePort, numPods) + + defer func() { expectNoError(stopServeHostnameService(c, ns, svc2)) }() + podNames2, svc2IP, err := startServeHostnameService(c, ns, svc2, servicePort, numPods) Expect(err).NotTo(HaveOccurred()) if svc1IP == svc2IP { @@ -305,18 +285,18 @@ var _ = Describe("Services", func() { expectNoError(verifyServeHostnameServiceUp(c, host, podNames1, svc1IP, servicePort)) expectNoError(verifyServeHostnameServiceUp(c, host, podNames2, svc2IP, servicePort)) - // Restart kube-proxy and verify that services are still reachable (after some time). + By("Restarting kube-proxy") if err := restartKubeProxy(host); err != nil { Failf("error restarting kube-proxy: %v", err) } expectNoError(verifyServeHostnameServiceUp(c, host, podNames1, svc1IP, servicePort)) expectNoError(verifyServeHostnameServiceUp(c, host, podNames2, svc2IP, servicePort)) - // Remove iptable rules and make sure they come back. - By("Remove iptable rules and make sure they come back") + + By("Removing iptable rules") _, _, code, err := SSH(` - sudo iptables -t nat -F KUBE-SERVICES || true; - sudo iptables -t nat -F KUBE-PORTALS-HOST || true; - sudo iptables -t nat -F KUBE-PORTALS-CONTAINER || true`, host, testContext.Provider) + sudo iptables -t nat -F KUBE-SERVICES || true; + sudo iptables -t nat -F KUBE-PORTALS-HOST || true; + sudo iptables -t nat -F KUBE-PORTALS-CONTAINER || true`, host, testContext.Provider) if err != nil || code != 0 { Failf("couldn't remove iptable rules: %v (code %v)", err, code) } @@ -328,7 +308,7 @@ var _ = Describe("Services", func() { // TODO: restartApiserver doesn't work in GKE - fix it and reenable this test. SkipUnlessProviderIs("gce") - ns := namespaces[0] + ns := f.Namespace.Name numPods, servicePort := 3, 80 defer func() { expectNoError(stopServeHostnameService(c, ns, "service1")) }() @@ -363,134 +343,9 @@ var _ = Describe("Services", func() { expectNoError(verifyServeHostnameServiceUp(c, host, podNames2, svc2IP, servicePort)) }) - It("should be able to create a functioning external load balancer", func() { - // requires ExternalLoadBalancer - SkipUnlessProviderIs("gce", "gke", "aws") - - serviceName := "external-lb-test" - ns := namespaces[0] - - t := NewWebserverTest(c, ns, serviceName) - defer func() { - defer GinkgoRecover() - errs := t.Cleanup() - if len(errs) != 0 { - Failf("errors in cleanup: %v", errs) - } - }() - - inboundPort := 3000 - - service := t.BuildServiceSpec() - service.Spec.Type = api.ServiceTypeLoadBalancer - service.Spec.Ports[0].Port = inboundPort - service.Spec.Ports[0].TargetPort = util.NewIntOrStringFromInt(80) - - By("creating service " + serviceName + " with external load balancer in namespace " + ns) - result, err := t.CreateService(service) - Expect(err).NotTo(HaveOccurred()) - - // Wait for the load balancer to be created asynchronously, which is - // currently indicated by ingress point(s) being added to the status. - result, err = waitForLoadBalancerIngress(c, serviceName, ns) - Expect(err).NotTo(HaveOccurred()) - if len(result.Status.LoadBalancer.Ingress) != 1 { - Failf("got unexpected number (%v) of ingress points for externally load balanced service: %v", result.Status.LoadBalancer.Ingress, result) - } - ingress := result.Status.LoadBalancer.Ingress[0] - if len(result.Spec.Ports) != 1 { - Failf("got unexpected len(Spec.Ports) for LoadBalancer service: %v", result) - } - port := result.Spec.Ports[0] - if port.NodePort == 0 { - Failf("got unexpected Spec.Ports[0].nodePort for LoadBalancer service: %v", result) - } - if !ServiceNodePortRange.Contains(port.NodePort) { - Failf("got unexpected (out-of-range) port for LoadBalancer service: %v", result) - } - - By("creating pod to be part of service " + serviceName) - t.CreateWebserverRC(1) - - By("hitting the pod through the service's NodePort") - testReachable(pickMinionIP(c), port.NodePort) - - By("hitting the pod through the service's external load balancer") - testLoadBalancerReachable(ingress, inboundPort) - }) - - It("should be able to create a functioning external load balancer with user-provided load balancer ip", func() { - // requires ExternalLoadBalancer - SkipUnlessProviderIs("gce", "gke") - - serviceName := "lb-test-with-user-ip" - ns := namespaces[0] - - t := NewWebserverTest(c, ns, serviceName) - defer func() { - defer GinkgoRecover() - errs := t.Cleanup() - if len(errs) != 0 { - Failf("errors in cleanup: %v", errs) - } - }() - - inboundPort := 3000 - - service := t.BuildServiceSpec() - service.Spec.Type = api.ServiceTypeLoadBalancer - service.Spec.Ports[0].Port = inboundPort - service.Spec.Ports[0].TargetPort = util.NewIntOrStringFromInt(80) - - By("creating an external static ip") - rand.Seed(time.Now().UTC().UnixNano()) - staticIPName := fmt.Sprintf("e2e-external-lb-test-%d", rand.Intn(65535)) - glog.Errorf("static ip name is %s", staticIPName) - loadBalancerIP, err := createGCEStaticIP(staticIPName) - Expect(err).NotTo(HaveOccurred()) - defer func() { - deleteGCEStaticIP(staticIPName) - }() - - service.Spec.LoadBalancerIP = loadBalancerIP - - By("creating service " + serviceName + " with external load balancer in namespace " + ns) - result, err := t.CreateService(service) - Expect(err).NotTo(HaveOccurred()) - - // Wait for the load balancer to be created asynchronously, which is - // currently indicated by ingress point(s) being added to the status. - result, err = waitForLoadBalancerIngress(c, serviceName, ns) - Expect(err).NotTo(HaveOccurred()) - if len(result.Status.LoadBalancer.Ingress) != 1 { - Failf("got unexpected number (%v) of ingress points for externally load balanced service: %v", result.Status.LoadBalancer.Ingress, result) - } - ingress := result.Status.LoadBalancer.Ingress[0] - Expect(ingress.IP).To(Equal(loadBalancerIP)) - if len(result.Spec.Ports) != 1 { - Failf("got unexpected len(Spec.Ports) for LoadBalancer service: %v", result) - } - port := result.Spec.Ports[0] - if port.NodePort == 0 { - Failf("got unexpected Spec.Ports[0].nodePort for LoadBalancer service: %v", result) - } - if !ServiceNodePortRange.Contains(port.NodePort) { - Failf("got unexpected (out-of-range) port for LoadBalancer service: %v", result) - } - - By("creating pod to be part of service " + serviceName) - t.CreateWebserverRC(1) - - By("hitting the pod through the service's NodePort") - testReachable(pickMinionIP(c), port.NodePort) - - By("hitting the pod through the service's external load balancer") - testLoadBalancerReachable(ingress, inboundPort) - }) - It("should be able to create a functioning NodePort service", func() { serviceName := "nodeportservice-test" - ns := namespaces[0] + ns := f.Namespace.Name t := NewWebserverTest(c, ns, serviceName) defer func() { @@ -529,22 +384,25 @@ var _ = Describe("Services", func() { t.CreateWebserverRC(1) By("hitting the pod through the service's NodePort") - ip := pickMinionIP(c) + ip := pickNodeIP(c) testReachable(ip, nodePort) - hosts, err := NodeSSHHosts(c) - if err != nil { - Expect(err).NotTo(HaveOccurred()) - } - cmd := fmt.Sprintf(`test -n "$(ss -ant46 'sport = :%d' | tail -n +2 | grep LISTEN)"`, nodePort) - _, _, code, err := SSH(cmd, hosts[0], testContext.Provider) - if code != 0 { - Failf("expected node port (%d) to be in use", nodePort) + // this test uses NodeSSHHosts that does not work if a Node only reports LegacyHostIP + if providerIs(providersWithSSH...) { + hosts, err := NodeSSHHosts(c) + if err != nil { + Expect(err).NotTo(HaveOccurred()) + } + cmd := fmt.Sprintf(`test -n "$(ss -ant46 'sport = :%d' | tail -n +2 | grep LISTEN)"`, nodePort) + _, _, code, err := SSH(cmd, hosts[0], testContext.Provider) + if code != 0 { + Failf("expected node port (%d) to be in use", nodePort) + } } }) It("should be able to change the type and nodeport settings of a service", func() { - // requires ExternalLoadBalancer + // requires cloud load-balancer support SkipUnlessProviderIs("gce", "gke", "aws") serviceName := "mutability-service-test" @@ -575,7 +433,7 @@ var _ = Describe("Services", func() { Failf("got unexpected Spec.Ports[0].nodePort for default service: %v", service) } if len(service.Status.LoadBalancer.Ingress) != 0 { - Failf("got unexpected len(Status.LoadBalancer.Ingresss) for default service: %v", service) + Failf("got unexpected len(Status.LoadBalancer.Ingress) for default service: %v", service) } By("creating pod to be part of service " + t.ServiceName) @@ -600,17 +458,16 @@ var _ = Describe("Services", func() { if !ServiceNodePortRange.Contains(port.NodePort) { Failf("got unexpected (out-of-range) port for NodePort service: %v", service) } - if len(service.Status.LoadBalancer.Ingress) != 0 { - Failf("got unexpected len(Status.LoadBalancer.Ingresss) for NodePort service: %v", service) + Failf("got unexpected len(Status.LoadBalancer.Ingress) for NodePort service: %v", service) } + By("hitting the pod through the service's NodePort") - ip := pickMinionIP(f.Client) + ip := pickNodeIP(f.Client) nodePort1 := port.NodePort // Save for later! testReachable(ip, nodePort1) By("changing service " + serviceName + " to type=LoadBalancer") - service.Spec.Type = api.ServiceTypeLoadBalancer service, err = updateService(f.Client, f.Namespace.Name, serviceName, func(s *api.Service) { s.Spec.Type = api.ServiceTypeLoadBalancer }) @@ -631,14 +488,15 @@ var _ = Describe("Services", func() { Failf("got unexpected Spec.Ports[0].nodePort for LoadBalancer service: %v", service) } if len(service.Status.LoadBalancer.Ingress) != 1 { - Failf("got unexpected len(Status.LoadBalancer.Ingresss) for LoadBalancer service: %v", service) + Failf("got unexpected len(Status.LoadBalancer.Ingress) for LoadBalancer service: %v", service) } ingress1 := service.Status.LoadBalancer.Ingress[0] if ingress1.IP == "" && ingress1.Hostname == "" { - Failf("got unexpected Status.LoadBalancer.Ingresss[0] for LoadBalancer service: %v", service) + Failf("got unexpected Status.LoadBalancer.Ingress[0] for LoadBalancer service: %v", service) } + By("hitting the pod through the service's NodePort") - ip = pickMinionIP(f.Client) + ip = pickNodeIP(f.Client) testReachable(ip, nodePort1) By("hitting the pod through the service's LoadBalancer") testLoadBalancerReachable(ingress1, 80) @@ -665,25 +523,31 @@ var _ = Describe("Services", func() { Failf("got unexpected Spec.Ports[0].nodePort for NodePort service: %v", service) } if len(service.Status.LoadBalancer.Ingress) != 1 { - Failf("got unexpected len(Status.LoadBalancer.Ingresss) for NodePort service: %v", service) + Failf("got unexpected len(Status.LoadBalancer.Ingress) for NodePort service: %v", service) } - // TODO: Make this less of a hack. Watch for events? - Logf("Waiting 2 minutes to give service time to settle after changing configuration") - time.Sleep(time.Second * 120) - service, err = waitForLoadBalancerIngress(f.Client, serviceName, f.Namespace.Name) - Expect(err).NotTo(HaveOccurred()) - - ingress2 := service.Status.LoadBalancer.Ingress[0] - Expect(ingress1).To(Equal(ingress2)) - By("hitting the pod through the service's updated NodePort") testReachable(ip, nodePort2) - By("hitting the pod through the service's LoadBalancer") - testLoadBalancerReachable(ingress2, 80) By("checking the old NodePort is closed") testNotReachable(ip, nodePort1) + By("hitting the pod through the service's LoadBalancer") + i := 1 + for start := time.Now(); time.Since(start) < podStartTimeout; time.Sleep(3 * time.Second) { + service, err = waitForLoadBalancerIngress(f.Client, serviceName, f.Namespace.Name) + Expect(err).NotTo(HaveOccurred()) + + ingress2 := service.Status.LoadBalancer.Ingress[0] + if testLoadBalancerReachableInTime(ingress2, 80, 5*time.Second) { + break + } + + if i%5 == 0 { + Logf("Waiting for load-balancer changes (%v elapsed, will retry)", time.Since(start)) + } + i++ + } + By("changing service " + serviceName + " back to type=ClusterIP") service, err = updateService(f.Client, f.Namespace.Name, serviceName, func(s *api.Service) { s.Spec.Type = api.ServiceTypeClusterIP @@ -691,6 +555,9 @@ var _ = Describe("Services", func() { }) Expect(err).NotTo(HaveOccurred()) + if len(service.Status.LoadBalancer.Ingress) != 0 { + Failf("got unexpected len(Status.LoadBalancer.Ingress) for NodePort service: %v", service) + } if service.Spec.Type != api.ServiceTypeClusterIP { Failf("got unexpected Spec.Type for back-to-ClusterIP service: %v", service) } @@ -707,109 +574,22 @@ var _ = Describe("Services", func() { Expect(err).NotTo(HaveOccurred()) if len(service.Status.LoadBalancer.Ingress) != 0 { - Failf("got unexpected len(Status.LoadBalancer.Ingresss) for back-to-ClusterIP service: %v", service) + Failf("got unexpected len(Status.LoadBalancer.Ingress) for back-to-ClusterIP service: %v", service) } - By("checking the NodePort (original) is closed") - ip = pickMinionIP(f.Client) - testNotReachable(ip, nodePort1) - By("checking the NodePort (updated) is closed") - ip = pickMinionIP(f.Client) + By("checking the NodePort is closed") + ip = pickNodeIP(f.Client) testNotReachable(ip, nodePort2) By("checking the LoadBalancer is closed") - testLoadBalancerNotReachable(ingress2, 80) - }) - - It("should release the load balancer when Type goes from LoadBalancer -> NodePort", func() { - // requires ExternalLoadBalancer - SkipUnlessProviderIs("gce", "gke", "aws") - - serviceName := "service-release-lb" - ns := namespaces[0] - - t := NewWebserverTest(c, ns, serviceName) - defer func() { - defer GinkgoRecover() - errs := t.Cleanup() - if len(errs) != 0 { - Failf("errors in cleanup: %v", errs) - } - }() - - service := t.BuildServiceSpec() - service.Spec.Type = api.ServiceTypeLoadBalancer - - By("creating service " + serviceName + " with type LoadBalancer") - service, err := t.CreateService(service) - Expect(err).NotTo(HaveOccurred()) - - By("creating pod to be part of service " + t.ServiceName) - t.CreateWebserverRC(1) - - if service.Spec.Type != api.ServiceTypeLoadBalancer { - Failf("got unexpected Spec.Type for LoadBalancer service: %v", service) - } - if len(service.Spec.Ports) != 1 { - Failf("got unexpected len(Spec.Ports) for LoadBalancer service: %v", service) - } - nodePort := service.Spec.Ports[0].NodePort - if nodePort == 0 { - Failf("got unexpected Spec.Ports[0].NodePort for LoadBalancer service: %v", service) - } - - // Wait for the load balancer to be created asynchronously - service, err = waitForLoadBalancerIngress(c, serviceName, ns) - Expect(err).NotTo(HaveOccurred()) - - if len(service.Status.LoadBalancer.Ingress) != 1 { - Failf("got unexpected len(Status.LoadBalancer.Ingresss) for LoadBalancer service: %v", service) - } - ingress := service.Status.LoadBalancer.Ingress[0] - if ingress.IP == "" && ingress.Hostname == "" { - Failf("got unexpected Status.LoadBalancer.Ingresss[0] for LoadBalancer service: %v", service) - } - - By("hitting the pod through the service's NodePort") - ip := pickMinionIP(c) - testReachable(ip, nodePort) - By("hitting the pod through the service's LoadBalancer") - testLoadBalancerReachable(ingress, 80) - - By("changing service " + serviceName + " to type=NodePort") - service, err = updateService(c, ns, serviceName, func(s *api.Service) { - s.Spec.Type = api.ServiceTypeNodePort - }) - Expect(err).NotTo(HaveOccurred()) - - if service.Spec.Type != api.ServiceTypeNodePort { - Failf("got unexpected Spec.Type for NodePort service: %v", service) - } - if len(service.Spec.Ports) != 1 { - Failf("got unexpected len(Spec.Ports) for NodePort service: %v", service) - } - if service.Spec.Ports[0].NodePort != nodePort { - Failf("got unexpected Spec.Ports[0].NodePort for NodePort service: %v", service) - } - - // Wait for the load balancer to be created asynchronously - service, err = waitForLoadBalancerDestroy(c, serviceName, ns) - Expect(err).NotTo(HaveOccurred()) - - if len(service.Status.LoadBalancer.Ingress) != 0 { - Failf("got unexpected len(Status.LoadBalancer.Ingresss) for NodePort service: %v", service) - } - - By("hitting the pod through the service's NodePort") - testReachable(ip, nodePort) - By("checking the LoadBalancer is closed") - testLoadBalancerNotReachable(ingress, 80) + testLoadBalancerNotReachable(ingress1, 80) }) It("should prevent NodePort collisions", func() { - serviceName := "nodeport-collision" - serviceName2 := serviceName + "2" - ns := namespaces[0] + baseName := "nodeport-collision-" + serviceName1 := baseName + "1" + serviceName2 := baseName + "2" + ns := f.Namespace.Name - t := NewWebserverTest(c, ns, serviceName) + t := NewWebserverTest(c, ns, serviceName1) defer func() { defer GinkgoRecover() errs := t.Cleanup() @@ -818,10 +598,9 @@ var _ = Describe("Services", func() { } }() + By("creating service " + serviceName1 + " with type NodePort in namespace " + ns) service := t.BuildServiceSpec() service.Spec.Type = api.ServiceTypeNodePort - - By("creating service " + serviceName + " with type NodePort in namespace " + ns) result, err := t.CreateService(service) Expect(err).NotTo(HaveOccurred()) @@ -836,23 +615,21 @@ var _ = Describe("Services", func() { Failf("got unexpected Spec.Ports[0].nodePort for new service: %v", result) } - By("creating service " + serviceName + " with conflicting NodePort") - + By("creating service " + serviceName2 + " with conflicting NodePort") service2 := t.BuildServiceSpec() service2.Name = serviceName2 service2.Spec.Type = api.ServiceTypeNodePort service2.Spec.Ports[0].NodePort = port.NodePort - - By("creating service " + serviceName2 + " with conflicting NodePort") result2, err := t.CreateService(service2) if err == nil { Failf("Created service with conflicting NodePort: %v", result2) } - expectedErr := fmt.Sprintf("Service \"%s\" is invalid: spec.ports[0].nodePort: invalid value '%d', Details: provided port is already allocated", serviceName2, port.NodePort) + expectedErr := fmt.Sprintf("Service \"%s\" is invalid: spec.ports[0].nodePort: invalid value '%d', Details: provided port is already allocated", + serviceName2, port.NodePort) Expect(fmt.Sprintf("%v", err)).To(Equal(expectedErr)) - By("deleting original service " + serviceName + " with type NodePort in namespace " + ns) - err = t.DeleteService(serviceName) + By("deleting service " + serviceName1 + " to release NodePort") + err = t.DeleteService(serviceName1) Expect(err).NotTo(HaveOccurred()) By("creating service " + serviceName2 + " with no-longer-conflicting NodePort") @@ -862,7 +639,7 @@ var _ = Describe("Services", func() { It("should check NodePort out-of-range", func() { serviceName := "nodeport-range-test" - ns := namespaces[0] + ns := f.Namespace.Name t := NewWebserverTest(c, ns, serviceName) defer func() { @@ -928,7 +705,7 @@ var _ = Describe("Services", func() { It("should release NodePorts on delete", func() { serviceName := "nodeport-reuse" - ns := namespaces[0] + ns := f.Namespace.Name t := NewWebserverTest(c, ns, serviceName) defer func() { @@ -965,14 +742,17 @@ var _ = Describe("Services", func() { err = t.DeleteService(serviceName) Expect(err).NotTo(HaveOccurred()) - hosts, err := NodeSSHHosts(c) - if err != nil { - Expect(err).NotTo(HaveOccurred()) - } - cmd := fmt.Sprintf(`test -n "$(ss -ant46 'sport = :%d' | tail -n +2 | grep LISTEN)"`, nodePort) - _, _, code, err := SSH(cmd, hosts[0], testContext.Provider) - if code == 0 { - Failf("expected node port (%d) to not be in use", nodePort) + // this test uses NodeSSHHosts that does not work if a Node only reports LegacyHostIP + if providerIs(providersWithSSH...) { + hosts, err := NodeSSHHosts(c) + if err != nil { + Expect(err).NotTo(HaveOccurred()) + } + cmd := fmt.Sprintf(`test -n "$(ss -ant46 'sport = :%d' | tail -n +2 | grep LISTEN)"`, nodePort) + _, _, code, err := SSH(cmd, hosts[0], testContext.Provider) + if code == 0 { + Failf("expected node port (%d) to not be in use", nodePort) + } } By(fmt.Sprintf("creating service "+serviceName+" with same NodePort %d", nodePort)) @@ -983,54 +763,98 @@ var _ = Describe("Services", func() { Expect(err).NotTo(HaveOccurred()) }) - It("should correctly serve identically named services in different namespaces on different external IP addresses", func() { + // This test hits several load-balancer cases because LB turnup is slow. + It("should serve identically named services in different namespaces on different load-balancers", func() { // requires ExternalLoadBalancer SkipUnlessProviderIs("gce", "gke", "aws") - serviceNames := []string{"s0"} // Could add more here, but then it takes longer. - labels := map[string]string{ - "key0": "value0", - "key1": "value1", - } - service := &api.Service{ - ObjectMeta: api.ObjectMeta{}, - Spec: api.ServiceSpec{ - Selector: labels, - Ports: []api.ServicePort{{ - Port: 80, - TargetPort: util.NewIntOrStringFromInt(80), - }}, - Type: api.ServiceTypeLoadBalancer, - }, - } + ns1 := f.Namespace.Name + + By("Building a second namespace api object") + namespacePtr, err := createTestingNS("services", c) + Expect(err).NotTo(HaveOccurred()) + ns2 := namespacePtr.Name + extraNamespaces = append(extraNamespaces, ns2) + + serviceName := "test-svc" + servicePort := 9376 + + By("creating service " + serviceName + " with load balancer in namespace " + ns1) + t1 := NewWebserverTest(c, ns1, serviceName) + svc1 := t1.BuildServiceSpec() + svc1.Spec.Type = api.ServiceTypeLoadBalancer + svc1.Spec.Ports[0].Port = servicePort + svc1.Spec.Ports[0].TargetPort = util.NewIntOrStringFromInt(80) + _, err = t1.CreateService(svc1) + Expect(err).NotTo(HaveOccurred()) + + By("creating pod to be part of service " + serviceName + " in namespace " + ns1) + t1.CreateWebserverRC(1) + + loadBalancerIP := "" + if providerIs("gce", "gke") { + By("creating a static IP") + rand.Seed(time.Now().UTC().UnixNano()) + staticIPName := fmt.Sprintf("e2e-external-lb-test-%d", rand.Intn(65535)) + loadBalancerIP, err = createGCEStaticIP(staticIPName) + Expect(err).NotTo(HaveOccurred()) + defer func() { + // Release GCE static IP - this is not kube-managed and will not be automatically released. + deleteGCEStaticIP(staticIPName) + }() + } + + By("creating service " + serviceName + " with load balancer in namespace " + ns2) + t2 := NewWebserverTest(c, ns2, serviceName) + svc2 := t2.BuildServiceSpec() + svc2.Spec.Type = api.ServiceTypeLoadBalancer + svc2.Spec.Ports[0].Port = servicePort + svc2.Spec.Ports[0].TargetPort = util.NewIntOrStringFromInt(80) + svc2.Spec.LoadBalancerIP = loadBalancerIP + _, err = t2.CreateService(svc2) + Expect(err).NotTo(HaveOccurred()) + + By("creating pod to be part of service " + serviceName + " in namespace " + ns2) + t2.CreateWebserverRC(2) ingressPoints := []string{} - for _, namespace := range namespaces { - for _, serviceName := range serviceNames { - service.ObjectMeta.Name = serviceName - service.ObjectMeta.Namespace = namespace - By("creating service " + serviceName + " in namespace " + namespace) - _, err := c.Services(namespace).Create(service) - Expect(err).NotTo(HaveOccurred()) - defer func(namespace, serviceName string) { // clean up when we're done - By("deleting service " + serviceName + " in namespace " + namespace) - err := c.Services(namespace).Delete(serviceName) - Expect(err).NotTo(HaveOccurred()) - }(namespace, serviceName) + svcs := []*api.Service{svc1, svc2} + for _, svc := range svcs { + namespace := svc.Namespace + lbip := svc.Spec.LoadBalancerIP + + // Wait for the load balancer to be created asynchronously, which is + // currently indicated by ingress point(s) being added to the status. + result, err := waitForLoadBalancerIngress(c, serviceName, namespace) + Expect(err).NotTo(HaveOccurred()) + if len(result.Status.LoadBalancer.Ingress) != 1 { + Failf("got unexpected number (%v) of ingress points for externally load balanced service: %v", result.Status.LoadBalancer.Ingress, result) } - } - for _, namespace := range namespaces { - for _, serviceName := range serviceNames { - result, err := waitForLoadBalancerIngress(c, serviceName, namespace) - Expect(err).NotTo(HaveOccurred()) - for i := range result.Status.LoadBalancer.Ingress { - ingress := result.Status.LoadBalancer.Ingress[i].IP - if ingress == "" { - ingress = result.Status.LoadBalancer.Ingress[i].Hostname - } - ingressPoints = append(ingressPoints, ingress) // Save 'em to check uniqueness - } + ingress := result.Status.LoadBalancer.Ingress[0] + if len(result.Spec.Ports) != 1 { + Failf("got unexpected len(Spec.Ports) for LoadBalancer service: %v", result) + } + if lbip != "" { + Expect(ingress.IP).To(Equal(lbip)) + } + port := result.Spec.Ports[0] + if port.NodePort == 0 { + Failf("got unexpected Spec.Ports[0].nodePort for LoadBalancer service: %v", result) } + if !ServiceNodePortRange.Contains(port.NodePort) { + Failf("got unexpected (out-of-range) port for LoadBalancer service: %v", result) + } + ing := result.Status.LoadBalancer.Ingress[0].IP + if ing == "" { + ing = result.Status.LoadBalancer.Ingress[0].Hostname + } + ingressPoints = append(ingressPoints, ing) // Save 'em to check uniqueness + + By("hitting the pod through the service's NodePort") + testReachable(pickNodeIP(c), port.NodePort) + + By("hitting the pod through the service's external load balancer") + testLoadBalancerReachable(ingress, servicePort) } validateUniqueOrFail(ingressPoints) }) @@ -1064,7 +888,8 @@ func waitForLoadBalancerIngress(c *client.Client, serviceName, namespace string) const timeout = 20 * time.Minute var service *api.Service By(fmt.Sprintf("waiting up to %v for service %s in namespace %s to have a LoadBalancer ingress point", timeout, serviceName, namespace)) - for start := time.Now(); time.Since(start) < timeout; time.Sleep(5 * time.Second) { + i := 1 + for start := time.Now(); time.Since(start) < timeout; time.Sleep(3 * time.Second) { service, err := c.Services(namespace).Get(serviceName) if err != nil { Logf("Get service failed, ignoring for 5s: %v", err) @@ -1073,13 +898,17 @@ func waitForLoadBalancerIngress(c *client.Client, serviceName, namespace string) if len(service.Status.LoadBalancer.Ingress) > 0 { return service, nil } - Logf("Waiting for service %s in namespace %s to have a LoadBalancer ingress point (%v)", serviceName, namespace, time.Since(start)) + if i%5 == 0 { + Logf("Waiting for service %s in namespace %s to have a LoadBalancer ingress point (%v)", serviceName, namespace, time.Since(start)) + } + i++ } return service, fmt.Errorf("service %s in namespace %s doesn't have a LoadBalancer ingress point after %.2f seconds", serviceName, namespace, timeout.Seconds()) } func waitForLoadBalancerDestroy(c *client.Client, serviceName, namespace string) (*api.Service, error) { // TODO: once support ticket 21807001 is resolved, reduce this timeout back to something reasonable + // TODO: this should actually test that the LB was released at the cloud provider const timeout = 10 * time.Minute var service *api.Service By(fmt.Sprintf("waiting up to %v for service %s in namespace %s to have no LoadBalancer ingress points", timeout, serviceName, namespace)) @@ -1119,21 +948,18 @@ func getContainerPortsByPodUID(endpoints *api.Endpoints) PortsByPodUID { // use endpoint annotations to recover the container port in a Mesos setup // compare contrib/mesos/pkg/service/endpoints_controller.syncService - if providerIs("mesos/docker") { - key := fmt.Sprintf("k8s.mesosphere.io/containerPort_%s_%s_%d", port.Protocol, addr.IP, hostPort) - containerPortString := endpoints.Annotations[key] - if containerPortString == "" { - continue - } + key := fmt.Sprintf("k8s.mesosphere.io/containerPort_%s_%s_%d", port.Protocol, addr.IP, hostPort) + mesosContainerPortString := endpoints.Annotations[key] + if mesosContainerPortString != "" { var err error - containerPort, err = strconv.Atoi(containerPortString) + containerPort, err = strconv.Atoi(mesosContainerPortString) if err != nil { continue } - Logf("Mapped mesos host port %d to container port %d via annotation %s=%s", hostPort, containerPort, key, containerPortString) + Logf("Mapped mesos host port %d to container port %d via annotation %s=%s", hostPort, containerPort, key, mesosContainerPortString) } - Logf("Found pod %v, host port %d and container port %d", addr.TargetRef.UID, hostPort, containerPort) + // Logf("Found pod %v, host port %d and container port %d", addr.TargetRef.UID, hostPort, containerPort) if _, ok := m[addr.TargetRef.UID]; !ok { m[addr.TargetRef.UID] = make([]int, 0) } @@ -1156,9 +982,8 @@ func translatePodNameToUIDOrFail(c *client.Client, ns string, expectedEndpoints Failf("failed to get pod %s, that's pretty weird. validation failed: %s", name, err) } portsByUID[pod.ObjectMeta.UID] = portList - By(fmt.Sprintf("")) } - By(fmt.Sprintf("successfully translated pod names to UIDs: %v -> %v on namespace %s", expectedEndpoints, portsByUID, ns)) + // Logf("successfully translated pod names to UIDs: %v -> %v on namespace %s", expectedEndpoints, portsByUID, ns) return portsByUID } @@ -1185,26 +1010,31 @@ func validatePortsOrFail(endpoints PortsByPodUID, expectedEndpoints PortsByPodUI } func validateEndpointsOrFail(c *client.Client, namespace, serviceName string, expectedEndpoints PortsByPodName) { - By(fmt.Sprintf("Waiting up to %v for service %s in namespace %s to expose endpoints %v", serviceStartTimeout, serviceName, namespace, expectedEndpoints)) - for start := time.Now(); time.Since(start) < serviceStartTimeout; time.Sleep(5 * time.Second) { + By(fmt.Sprintf("waiting up to %v for service %s in namespace %s to expose endpoints %v", serviceStartTimeout, serviceName, namespace, expectedEndpoints)) + i := 1 + for start := time.Now(); time.Since(start) < serviceStartTimeout; time.Sleep(1 * time.Second) { endpoints, err := c.Endpoints(namespace).Get(serviceName) if err != nil { Logf("Get endpoints failed (%v elapsed, ignoring for 5s): %v", time.Since(start), err) continue } - Logf("Found endpoints %v", endpoints) + // Logf("Found endpoints %v", endpoints) portsByPodUID := getContainerPortsByPodUID(endpoints) - Logf("Found port by pod UID %v", portsByPodUID) + // Logf("Found port by pod UID %v", portsByPodUID) expectedPortsByPodUID := translatePodNameToUIDOrFail(c, namespace, expectedEndpoints) if len(portsByPodUID) == len(expectedEndpoints) { validatePortsOrFail(portsByPodUID, expectedPortsByPodUID) - By(fmt.Sprintf("Successfully validated that service %s in namespace %s exposes endpoints %v (%v elapsed)", serviceName, namespace, expectedEndpoints, time.Since(start))) + Logf("successfully validated that service %s in namespace %s exposes endpoints %v (%v elapsed)", + serviceName, namespace, expectedEndpoints, time.Since(start)) return } - Logf("Unexpected number of endpoints: found %v, expected %v (%v elapsed, ignoring for 5s)", portsByPodUID, expectedEndpoints, time.Since(start)) + if i%5 == 0 { + Logf("Unexpected endpoints: found %v, expected %v (%v elapsed, will retry)", portsByPodUID, expectedEndpoints, time.Since(start)) + } + i++ } if pods, err := c.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()); err == nil { @@ -1217,8 +1047,8 @@ func validateEndpointsOrFail(c *client.Client, namespace, serviceName string, ex Failf("Timed out waiting for service %s in namespace %s to expose endpoints %v (%v elapsed)", serviceName, namespace, expectedEndpoints, serviceStartTimeout) } -func addEndpointPodOrFail(c *client.Client, ns, name string, labels map[string]string, containerPorts []api.ContainerPort) { - By(fmt.Sprintf("Adding pod %v in namespace %v", name, ns)) +func createPodOrFail(c *client.Client, ns, name string, labels map[string]string, containerPorts []api.ContainerPort) { + By(fmt.Sprintf("creating pod %s in namespace %s", name, ns)) pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: name, @@ -1228,7 +1058,7 @@ func addEndpointPodOrFail(c *client.Client, ns, name string, labels map[string]s Containers: []api.Container{ { Name: "test", - Image: "gcr.io/google_containers/pause", + Image: "beta.gcr.io/google_containers/pause:2.0", Ports: containerPorts, }, }, @@ -1238,6 +1068,12 @@ func addEndpointPodOrFail(c *client.Client, ns, name string, labels map[string]s Expect(err).NotTo(HaveOccurred()) } +func deletePodOrFail(c *client.Client, ns, name string) { + By(fmt.Sprintf("deleting pod %s in namespace %s", name, ns)) + err := c.Pods(ns).Delete(name, nil) + Expect(err).NotTo(HaveOccurred()) +} + func collectAddresses(nodes *api.NodeList, addressType api.NodeAddressType) []string { ips := []string{} for i := range nodes.Items { @@ -1252,7 +1088,7 @@ func collectAddresses(nodes *api.NodeList, addressType api.NodeAddressType) []st return ips } -func getMinionPublicIps(c *client.Client) ([]string, error) { +func getNodePublicIps(c *client.Client) ([]string, error) { nodes, err := c.Nodes().List(labels.Everything(), fields.Everything()) if err != nil { return nil, err @@ -1265,8 +1101,8 @@ func getMinionPublicIps(c *client.Client) ([]string, error) { return ips, nil } -func pickMinionIP(c *client.Client) string { - publicIps, err := getMinionPublicIps(c) +func pickNodeIP(c *client.Client) string { + publicIps, err := getNodePublicIps(c) Expect(err).NotTo(HaveOccurred()) if len(publicIps) == 0 { Failf("got unexpected number (%d) of public IPs", len(publicIps)) @@ -1275,13 +1111,17 @@ func pickMinionIP(c *client.Client) string { return ip } -func testLoadBalancerReachable(ingress api.LoadBalancerIngress, port int) { +func testLoadBalancerReachable(ingress api.LoadBalancerIngress, port int) bool { + return testLoadBalancerReachableInTime(ingress, port, podStartTimeout) +} + +func testLoadBalancerReachableInTime(ingress api.LoadBalancerIngress, port int, timeout time.Duration) bool { ip := ingress.IP if ip == "" { ip = ingress.Hostname } - testReachable(ip, port) + return testReachableInTime(ip, port, timeout) } func testLoadBalancerNotReachable(ingress api.LoadBalancerIngress, port int) { @@ -1293,19 +1133,25 @@ func testLoadBalancerNotReachable(ingress api.LoadBalancerIngress, port int) { testNotReachable(ip, port) } -func testReachable(ip string, port int) { +func testReachable(ip string, port int) bool { + return testReachableInTime(ip, port, podStartTimeout) +} + +func testReachableInTime(ip string, port int, timeout time.Duration) bool { url := fmt.Sprintf("http://%s:%d", ip, port) if ip == "" { Failf("Got empty IP for reachability check (%s)", url) + return false } if port == 0 { Failf("Got port==0 for reachability check (%s)", url) + return false } desc := fmt.Sprintf("the url %s to be reachable", url) - By(fmt.Sprintf("Waiting up to %v for %s", podStartTimeout, desc)) + By(fmt.Sprintf("Waiting up to %v for %s", timeout, desc)) start := time.Now() - err := wait.Poll(poll, podStartTimeout, func() (bool, error) { + err := wait.PollImmediate(poll, timeout, func() (bool, error) { resp, err := httpGetNoConnectionPool(url) if err != nil { Logf("Got error waiting for reachability of %s: %v (%v)", url, err, time.Since(start)) @@ -1326,7 +1172,11 @@ func testReachable(ip string, port int) { Logf("Successfully reached %v", url) return true, nil }) - Expect(err).NotTo(HaveOccurred(), "Error waiting for %s", desc) + if err != nil { + Expect(err).NotTo(HaveOccurred(), "Error waiting for %s", desc) + return false + } + return true } func testNotReachable(ip string, port int) { @@ -1340,7 +1190,7 @@ func testNotReachable(ip string, port int) { desc := fmt.Sprintf("the url %s to be *not* reachable", url) By(fmt.Sprintf("Waiting up to %v for %s", podStartTimeout, desc)) - err := wait.Poll(poll, podStartTimeout, func() (bool, error) { + err := wait.PollImmediate(poll, podStartTimeout, func() (bool, error) { resp, err := httpGetNoConnectionPool(url) if err != nil { Logf("Successfully waited for %s", desc) @@ -1362,6 +1212,7 @@ func testNotReachable(ip string, port int) { func startServeHostnameService(c *client.Client, ns, name string, port, replicas int) ([]string, string, error) { podNames := make([]string, replicas) + By("creating service " + name + " in namespace " + ns) _, err := c.Services(ns).Create(&api.Service{ ObjectMeta: api.ObjectMeta{ Name: name, @@ -1389,7 +1240,7 @@ func startServeHostnameService(c *client.Client, ns, name string, port, replicas Name: name, Namespace: ns, PollInterval: 3 * time.Second, - Timeout: 30 * time.Second, + Timeout: podReadyBeforeTimeout, Replicas: replicas, CreatedPods: &createdPods, MaxContainerFailures: &maxContainerFailures, @@ -1444,6 +1295,7 @@ func verifyServeHostnameServiceUp(c *client.Client, host string, expectedPods [] command), } + By(fmt.Sprintf("verifying service has %d reachable backends", len(expectedPods))) for _, cmd := range commands { passed := false for start := time.Now(); time.Since(start) < time.Minute; time.Sleep(5) { @@ -1536,7 +1388,8 @@ func NewWebserverTest(client *client.Client, namespace string, serviceName strin func (t *WebserverTest) BuildServiceSpec() *api.Service { service := &api.Service{ ObjectMeta: api.ObjectMeta{ - Name: t.ServiceName, + Name: t.ServiceName, + Namespace: t.Namespace, }, Spec: api.ServiceSpec{ Selector: t.Labels, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service_accounts.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service_accounts.go index af4e71db5ca0..74af69f7d8af 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service_accounts.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service_accounts.go @@ -34,7 +34,7 @@ import ( var _ = Describe("ServiceAccounts", func() { f := NewFramework("svcaccounts") - It("should mount an API token into pods", func() { + It("should mount an API token into pods [Conformance]", func() { var tokenName string var tokenContent string var rootCAContent string diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service_latency.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service_latency.go index 7dfc4f090374..cc2258ab28af 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service_latency.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/service_latency.go @@ -44,7 +44,7 @@ func (d durations) Swap(i, j int) { d[i], d[j] = d[j], d[i] } var _ = Describe("Service endpoints latency", func() { f := NewFramework("svc-latency") - It("should not be very high", func() { + It("should not be very high [Conformance]", func() { const ( // These are very generous criteria. Ideally we will // get this much lower in the future. See issue @@ -119,7 +119,7 @@ var _ = Describe("Service endpoints latency", func() { func runServiceLatencies(f *Framework, inParallel, total int) (output []time.Duration, err error) { cfg := RCConfig{ Client: f.Client, - Image: "gcr.io/google_containers/pause:1.0", + Image: "beta.gcr.io/google_containers/pause:2.0", Name: "svc-latency-rc", Namespace: f.Namespace.Name, Replicas: 1, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/serviceloadbalancers.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/serviceloadbalancers.go new file mode 100644 index 000000000000..2f1e08a400d5 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/serviceloadbalancers.go @@ -0,0 +1,292 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 e2e + +import ( + "fmt" + "io/ioutil" + "net/http" + "path/filepath" + + "k8s.io/kubernetes/pkg/api" + client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/util/wait" + utilyaml "k8s.io/kubernetes/pkg/util/yaml" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +// getLoadBalancerControllers returns a list of LBCtesters. +func getLoadBalancerControllers(repoRoot string, client *client.Client) []LBCTester { + return []LBCTester{ + &haproxyControllerTester{ + name: "haproxy", + cfg: filepath.Join(repoRoot, "test", "e2e", "testing-manifests", "haproxyrc.yaml"), + client: client, + }, + } +} + +// getIngManagers returns a list of ingManagers. +func getIngManagers(repoRoot string, client *client.Client) []*ingManager { + return []*ingManager{ + { + name: "netexec", + rcCfgPaths: []string{filepath.Join(repoRoot, "test", "e2e", "testing-manifests", "netexecrc.yaml")}, + svcCfgPaths: []string{filepath.Join(repoRoot, "test", "e2e", "testing-manifests", "netexecsvc.yaml")}, + svcNames: []string{}, + client: client, + }, + } +} + +// LBCTester is an interface used to test loadbalancer controllers. +type LBCTester interface { + // start starts the loadbalancer controller in the given namespace + start(namespace string) error + // lookup returns the address (ip/hostname) associated with ingressKey + lookup(ingressKey string) string + // stop stops the loadbalancer controller + stop() error + // name returns the name of the loadbalancer + getName() string +} + +// haproxyControllerTester implementes LBCTester for bare metal haproxy LBs. +type haproxyControllerTester struct { + client *client.Client + cfg string + rcName string + rcNamespace string + name string + address []string +} + +func (h *haproxyControllerTester) getName() string { + return h.name +} + +func (h *haproxyControllerTester) start(namespace string) (err error) { + + // Create a replication controller with the given configuration. + rc := rcFromManifest(h.cfg) + rc.Namespace = namespace + rc.Spec.Template.Labels["rcName"] = rc.Name + + // Add the --namespace arg. + // TODO: Remove this when we have proper namespace support. + for i, c := range rc.Spec.Template.Spec.Containers { + rc.Spec.Template.Spec.Containers[i].Args = append( + c.Args, fmt.Sprintf("--namespace=%v", namespace)) + Logf("Container args %+v", rc.Spec.Template.Spec.Containers[i].Args) + } + + rc, err = h.client.ReplicationControllers(rc.Namespace).Create(rc) + if err != nil { + return + } + if err = waitForRCPodsRunning(h.client, namespace, h.rcName); err != nil { + return + } + h.rcName = rc.Name + h.rcNamespace = rc.Namespace + + // Find the pods of the rc we just created. + labelSelector := labels.SelectorFromSet( + labels.Set(map[string]string{"rcName": h.rcName})) + pods, err := h.client.Pods(h.rcNamespace).List( + labelSelector, fields.Everything()) + if err != nil { + return err + } + + // Find the external addresses of the nodes the pods are running on. + for _, p := range pods.Items { + wait.Poll(pollInterval, serviceRespondingTimeout, func() (bool, error) { + address, err := getHostExternalAddress(h.client, &p) + if err != nil { + Logf("%v", err) + return false, nil + } + h.address = append(h.address, address) + return true, nil + }) + } + if len(h.address) == 0 { + return fmt.Errorf("No external ips found for loadbalancer %v", h.getName()) + } + return nil +} + +func (h *haproxyControllerTester) stop() error { + return h.client.ReplicationControllers(h.rcNamespace).Delete(h.rcName) +} + +func (h *haproxyControllerTester) lookup(ingressKey string) string { + // The address of a service is the address of the lb/servicename, currently. + return fmt.Sprintf("http://%v/%v", h.address[0], ingressKey) +} + +// ingManager starts an rc and the associated service. +type ingManager struct { + rcCfgPaths []string + svcCfgPaths []string + ingCfgPath string + name string + namespace string + client *client.Client + svcNames []string +} + +func (s *ingManager) getName() string { + return s.name +} + +func (s *ingManager) start(namespace string) (err error) { + // Create rcs + for _, rcPath := range s.rcCfgPaths { + rc := rcFromManifest(rcPath) + rc.Namespace = namespace + rc.Spec.Template.Labels["rcName"] = rc.Name + rc, err = s.client.ReplicationControllers(rc.Namespace).Create(rc) + if err != nil { + return + } + if err = waitForRCPodsRunning(s.client, rc.Namespace, rc.Name); err != nil { + return + } + } + // Create services. + // Note that it's upto the caller to make sure the service actually matches + // the pods of the rc. + for _, svcPath := range s.svcCfgPaths { + svc := svcFromManifest(svcPath) + svc.Namespace = namespace + svc, err = s.client.Services(svc.Namespace).Create(svc) + if err != nil { + return + } + // TODO: This is short term till we have an Ingress. + s.svcNames = append(s.svcNames, svc.Name) + } + s.name = s.svcNames[0] + s.namespace = namespace + return nil +} + +func (s *ingManager) test(path string) error { + url := fmt.Sprintf("%v/hostName", path) + httpClient := &http.Client{} + return wait.Poll(pollInterval, serviceRespondingTimeout, func() (bool, error) { + body, err := simpleGET(httpClient, url) + if err != nil { + Logf("%v\n%v\n%v", url, body, err) + return false, nil + } + return true, nil + }) +} + +var _ = Describe("ServiceLoadBalancer", func() { + // These variables are initialized after framework's beforeEach. + var ns string + var repoRoot string + var client *client.Client + + framework := Framework{BaseName: "servicelb"} + + BeforeEach(func() { + framework.beforeEach() + client = framework.Client + ns = framework.Namespace.Name + repoRoot = testContext.RepoRoot + }) + + AfterEach(func() { + framework.afterEach() + }) + + It("should support simple GET on Ingress ips", func() { + for _, t := range getLoadBalancerControllers(repoRoot, client) { + By(fmt.Sprintf("Starting loadbalancer controller %v in namespace %v", t.getName(), ns)) + Expect(t.start(ns)).NotTo(HaveOccurred()) + + for _, s := range getIngManagers(repoRoot, client) { + By(fmt.Sprintf("Starting ingress manager %v in namespace %v", s.getName(), ns)) + Expect(s.start(ns)).NotTo(HaveOccurred()) + + for _, sName := range s.svcNames { + path := t.lookup(sName) + Logf("Testing path %v", path) + Expect(s.test(path)).NotTo(HaveOccurred()) + } + } + + Expect(t.stop()).NotTo(HaveOccurred()) + } + }) +}) + +// simpleGET executes a get on the given url, returns error if non-200 returned. +func simpleGET(c *http.Client, url string) (string, error) { + res, err := c.Get(url) + if err != nil { + return "", err + } + defer res.Body.Close() + rawBody, err := ioutil.ReadAll(res.Body) + if err != nil { + return "", err + } + body := string(rawBody) + if res.StatusCode != http.StatusOK { + err = fmt.Errorf( + "GET returned http error %v", res.StatusCode) + } + return body, err +} + +// rcFromManifest reads a .json/yaml file and returns the rc in it. +func rcFromManifest(fileName string) *api.ReplicationController { + var controller api.ReplicationController + Logf("Parsing rc from %v", fileName) + data, err := ioutil.ReadFile(fileName) + Expect(err).NotTo(HaveOccurred()) + + json, err := utilyaml.ToJSON(data) + Expect(err).NotTo(HaveOccurred()) + + Expect(api.Scheme.DecodeInto(json, &controller)).NotTo(HaveOccurred()) + return &controller +} + +// svcFromManifest reads a .json/yaml file and returns the rc in it. +func svcFromManifest(fileName string) *api.Service { + var svc api.Service + Logf("Parsing service from %v", fileName) + data, err := ioutil.ReadFile(fileName) + Expect(err).NotTo(HaveOccurred()) + + json, err := utilyaml.ToJSON(data) + Expect(err).NotTo(HaveOccurred()) + + Expect(api.Scheme.DecodeInto(json, &svc)).NotTo(HaveOccurred()) + return &svc +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/ssh.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/ssh.go index a78101c6156b..2efdf36af189 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/ssh.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/ssh.go @@ -35,7 +35,7 @@ var _ = Describe("SSH", func() { Expect(err).NotTo(HaveOccurred()) // When adding more providers here, also implement their functionality in util.go's getSigner(...). - SkipUnlessProviderIs("gce", "gke") + SkipUnlessProviderIs(providersWithSSH...) }) It("should SSH to all nodes and run commands", func() { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/haproxyrc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/haproxyrc.yaml new file mode 100644 index 000000000000..528aa25a1258 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/haproxyrc.yaml @@ -0,0 +1,49 @@ +kind: ReplicationController +apiVersion: v1 +metadata: + name: service-loadbalancer + labels: + app: service-loadbalancer + version: v1 +spec: + replicas: 1 + selector: + app: service-loadbalancer + version: v1 + template: + metadata: + labels: + app: service-loadbalancer + version: v1 + spec: + containers: + - image: gcr.io/google_containers/servicelb:0.1 + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz + port: 8081 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 5 + name: haproxy + ports: + # All http services + - containerPort: 80 + hostPort: 80 + protocol: TCP + # nginx https + - containerPort: 443 + hostPort: 8080 + protocol: TCP + # mysql + - containerPort: 3306 + hostPort: 3306 + protocol: TCP + # haproxy stats + - containerPort: 1936 + hostPort: 1936 + protocol: TCP + resources: {} + args: + - --tcp-services=mysql:3306,nginxsvc:443 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/netexecrc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/netexecrc.yaml new file mode 100644 index 000000000000..ecdcff159fce --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/netexecrc.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: netexec +spec: + # Assumes you have 3 nodes in your cluster. + replicas: 3 + template: + metadata: + labels: + app: netexec + spec: + containers: + - name: netexec + image: gcr.io/google_containers/netexec:1.0 + ports: + - containerPort: 8080 + # This is to force these pods to land on different hosts. + # TODO: use the downward api and get podname instead. + hostPort: 81 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/show-srv.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/netexecsvc.yaml similarity index 60% rename from Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/show-srv.yaml rename to Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/netexecsvc.yaml index 25a2d7473e02..1a1a3704e9b3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/show-srv.yaml +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/netexecsvc.yaml @@ -1,15 +1,15 @@ ---- apiVersion: v1 kind: Service metadata: - name: show-srv + name: netexec labels: - type: show-type + app: netexec spec: - type: LoadBalancer + Type: NodePort ports: - port: 80 - protocol: TCP targetPort: 8080 + protocol: TCP + name: http selector: - type: show-type + app: netexec diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/nginxrc.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/nginxrc.yaml new file mode 100644 index 000000000000..66a4f0bc30c8 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/nginxrc.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: my-nginx +spec: + replicas: 1 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginxhttps + image: bprashanth/nginxhttps:1.0 + ports: + - containerPort: 80 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/backend-srv.yaml b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/nginxsvc.yaml similarity index 52% rename from Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/backend-srv.yaml rename to Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/nginxsvc.yaml index 7083b37bf88e..22625ad14579 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/environment-guide/backend-srv.yaml +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/testing-manifests/nginxsvc.yaml @@ -1,13 +1,14 @@ ---- apiVersion: v1 kind: Service metadata: - name: backend-srv + name: nginxsvc labels: - type: backend-type + app: nginx spec: ports: - - port: 5000 + - port: 80 protocol: TCP + name: http selector: - type: backend-type + app: nginx + diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/util.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/util.go index 2f4542d55c33..625314bae958 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/util.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/util.go @@ -20,7 +20,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "math" "math/rand" "net/http" @@ -28,7 +27,6 @@ import ( "os" "os/exec" "path/filepath" - "sort" "strconv" "strings" "time" @@ -46,18 +44,19 @@ import ( "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" + deploymentUtil "k8s.io/kubernetes/pkg/util/deployment" "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/watch" "github.com/davecgh/go-spew/spew" - "github.com/prometheus/client_golang/extraction" - "github.com/prometheus/client_golang/model" "golang.org/x/crypto/ssh" "golang.org/x/net/websocket" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + gomegatypes "github.com/onsi/gomega/types" ) const ( @@ -72,7 +71,7 @@ const ( nonExist = "NonExist" // How often to poll pods and nodes. - poll = 5 * time.Second + poll = 2 * time.Second // service accounts are provisioned after namespace creation // a service account is required to support pod creation in a namespace as part of admission control @@ -86,16 +85,12 @@ const ( // be "ready" before the test starts, so this is small. nodeReadyInitialTimeout = 20 * time.Second - // How long pods have to be "ready" when a test begins. They should already - // be "ready" before the test starts, so this is small. - podReadyBeforeTimeout = 20 * time.Second + // How long pods have to be "ready" when a test begins. + podReadyBeforeTimeout = 2 * time.Minute podRespondingTimeout = 2 * time.Minute serviceRespondingTimeout = 2 * time.Minute - - // How wide to print pod names, by default. Useful for aligning printing to - // quickly scan through output. - podPrintWidth = 55 + endpointRegisterTimeout = time.Minute ) type CloudConfig struct { @@ -124,6 +119,7 @@ type TestContextType struct { MinStartupPods int UpgradeTarget string PrometheusPushGateway string + VerifyServiceAccount bool } var testContext TestContextType @@ -247,6 +243,9 @@ func providerIs(providers ...string) bool { return false } +// providersWithSSH are those providers where each node is accessible with SSH +var providersWithSSH = []string{"gce", "gke", "aws"} + type podCondition func(pod *api.Pod) (bool, error) // podReady returns whether pod has a condition of Ready with a status of true. @@ -337,11 +336,11 @@ func waitForPodsRunningReady(ns string, minPods int, timeout time.Duration) erro start := time.Now() Logf("Waiting up to %v for all pods (need at least %d) in namespace '%s' to be running and ready", timeout, minPods, ns) - if wait.Poll(poll, timeout, func() (bool, error) { + if wait.PollImmediate(poll, timeout, func() (bool, error) { // We get the new list of pods and replication controllers in every // iteration because more pods come online during startup and we want to // ensure they are also checked. - rcList, err := c.ReplicationControllers(ns).List(labels.Everything()) + rcList, err := c.ReplicationControllers(ns).List(labels.Everything(), fields.Everything()) if err != nil { Logf("Error getting replication controllers in namespace '%s': %v", ns, err) return false, nil @@ -413,22 +412,22 @@ func waitForServiceAccountInNamespace(c *client.Client, ns, serviceAccountName s } func waitForPodCondition(c *client.Client, ns, podName, desc string, timeout time.Duration, condition podCondition) error { - Logf("Waiting up to %[1]v for pod %-[2]*[3]s status to be %[4]s", timeout, podPrintWidth, podName, desc) + Logf("Waiting up to %[1]v for pod %[2]s status to be %[3]s", timeout, podName, desc) for start := time.Now(); time.Since(start) < timeout; time.Sleep(poll) { pod, err := c.Pods(ns).Get(podName) if err != nil { // Aligning this text makes it much more readable - Logf("Get pod %-[1]*[2]s in namespace '%[3]s' failed, ignoring for %[4]v. Error: %[5]v", - podPrintWidth, podName, ns, poll, err) + Logf("Get pod %[1]s in namespace '%[2]s' failed, ignoring for %[3]v. Error: %[4]v", + podName, ns, poll, err) continue } done, err := condition(pod) if done { return err } - Logf("Waiting for pod %-[1]*[2]s in namespace '%[3]s' status to be '%[4]s'"+ - "(found phase: %[5]q, readiness: %[6]t) (%[7]v elapsed)", - podPrintWidth, podName, ns, desc, pod.Status.Phase, podReady(pod), time.Since(start)) + Logf("Waiting for pod %[1]s in namespace '%[2]s' status to be '%[3]s'"+ + "(found phase: %[4]q, readiness: %[5]t) (%[6]v elapsed)", + podName, ns, desc, pod.Status.Phase, podReady(pod), time.Since(start)) } return fmt.Errorf("gave up waiting for pod '%s' to be '%s' after %v", podName, desc, timeout) } @@ -472,7 +471,7 @@ func createTestingNS(baseName string, c *client.Client) (*api.Namespace, error) } // Be robust about making the namespace creation call. var got *api.Namespace - if err := wait.Poll(poll, singleCallTimeout, func() (bool, error) { + if err := wait.PollImmediate(poll, singleCallTimeout, func() (bool, error) { var err error got, err = c.Namespaces().Create(namespaceObj) if err != nil { @@ -483,15 +482,17 @@ func createTestingNS(baseName string, c *client.Client) (*api.Namespace, error) return nil, err } - if err := waitForDefaultServiceAccountInNamespace(c, got.Name); err != nil { - return nil, err + if testContext.VerifyServiceAccount { + if err := waitForDefaultServiceAccountInNamespace(c, got.Name); err != nil { + return nil, err + } } return got, nil } -// deleteTestingNS checks whether all e2e based existing namespaces are in the Terminating state -// and waits until they are finally deleted. -func deleteTestingNS(c *client.Client) error { +// checkTestingNSDeletedExcept checks whether all e2e based existing namespaces are in the Terminating state +// and waits until they are finally deleted. It ignores namespace skip. +func checkTestingNSDeletedExcept(c *client.Client, skip string) error { // TODO: Since we don't have support for bulk resource deletion in the API, // while deleting a namespace we are deleting all objects from that namespace // one by one (one deletion == one API call). This basically exposes us to @@ -514,7 +515,7 @@ func deleteTestingNS(c *client.Client) error { } terminating := 0 for _, ns := range namespaces.Items { - if strings.HasPrefix(ns.ObjectMeta.Name, "e2e-tests-") { + if strings.HasPrefix(ns.ObjectMeta.Name, "e2e-tests-") && ns.ObjectMeta.Name != skip { if ns.Status.Phase == api.NamespaceActive { return fmt.Errorf("Namespace %s is active", ns.ObjectMeta.Name) } @@ -530,12 +531,12 @@ func deleteTestingNS(c *client.Client) error { // deleteNS deletes the provided namespace, waits for it to be completely deleted, and then checks // whether there are any pods remaining in a non-terminating state. -func deleteNS(c *client.Client, namespace string) error { +func deleteNS(c *client.Client, namespace string, timeout time.Duration) error { if err := c.Namespaces().Delete(namespace); err != nil { return err } - err := wait.Poll(5*time.Second, 5*time.Minute, func() (bool, error) { + err := wait.PollImmediate(5*time.Second, timeout, func() (bool, error) { if _, err := c.Namespaces().Get(namespace); err != nil { if apierrs.IsNotFound(err) { return true, nil @@ -623,7 +624,7 @@ func waitForPodSuccessInNamespace(c *client.Client, podName string, contName str func waitForRCPodOnNode(c *client.Client, ns, rcName, node string) (*api.Pod, error) { label := labels.SelectorFromSet(labels.Set(map[string]string{"name": rcName})) var p *api.Pod = nil - err := wait.Poll(10*time.Second, 5*time.Minute, func() (bool, error) { + err := wait.PollImmediate(10*time.Second, 5*time.Minute, func() (bool, error) { Logf("Waiting for pod %s to appear on node %s", rcName, node) pods, err := c.Pods(ns).List(label, fields.Everything()) if err != nil { @@ -641,11 +642,8 @@ func waitForRCPodOnNode(c *client.Client, ns, rcName, node string) (*api.Pod, er return p, err } -// waitForRCPodToDisappear returns nil if the pod from the given replication controller (described by rcName) no longer exists. -// In case of failure or too long waiting time, an error is returned. -func waitForRCPodToDisappear(c *client.Client, ns, rcName, podName string) error { - label := labels.SelectorFromSet(labels.Set(map[string]string{"name": rcName})) - return wait.Poll(20*time.Second, 5*time.Minute, func() (bool, error) { +func waitForPodToDisappear(c *client.Client, ns, podName string, label labels.Selector, interval, timeout time.Duration) error { + return wait.PollImmediate(interval, timeout, func() (bool, error) { Logf("Waiting for pod %s to disappear", podName) pods, err := c.Pods(ns).List(label, fields.Everything()) if err != nil { @@ -666,16 +664,33 @@ func waitForRCPodToDisappear(c *client.Client, ns, rcName, podName string) error }) } +// waitForRCPodToDisappear returns nil if the pod from the given replication controller (described by rcName) no longer exists. +// In case of failure or too long waiting time, an error is returned. +func waitForRCPodToDisappear(c *client.Client, ns, rcName, podName string) error { + label := labels.SelectorFromSet(labels.Set(map[string]string{"name": rcName})) + return waitForPodToDisappear(c, ns, podName, label, 20*time.Second, 5*time.Minute) +} + // waitForService waits until the service appears (exist == true), or disappears (exist == false) func waitForService(c *client.Client, namespace, name string, exist bool, interval, timeout time.Duration) error { - err := wait.Poll(interval, timeout, func() (bool, error) { + err := wait.PollImmediate(interval, timeout, func() (bool, error) { _, err := c.Services(namespace).Get(name) - if err != nil { - Logf("Get service %s in namespace %s failed (%v).", name, namespace, err) - return !exist, nil - } else { + switch { + case err == nil: + if !exist { + return false, nil + } Logf("Service %s in namespace %s found.", name, namespace) - return exist, nil + return true, nil + case apierrs.IsNotFound(err): + if exist { + return false, nil + } + Logf("Service %s in namespace %s disappeared.", name, namespace) + return true, nil + default: + Logf("Get service %s in namespace %s failed: %v", name, namespace, err) + return false, nil } }) if err != nil { @@ -685,9 +700,35 @@ func waitForService(c *client.Client, namespace, name string, exist bool, interv return nil } +//waitForServiceEndpointsNum waits until the amount of endpoints that implement service to expectNum. +func waitForServiceEndpointsNum(c *client.Client, namespace, serviceName string, expectNum int, interval, timeout time.Duration) error { + return wait.Poll(interval, timeout, func() (bool, error) { + Logf("Waiting for amount of service:%s endpoints to %d", serviceName, expectNum) + list, err := c.Endpoints(namespace).List(labels.Everything()) + if err != nil { + return false, err + } + + for _, e := range list.Items { + if e.Name == serviceName && countEndpointsNum(&e) == expectNum { + return true, nil + } + } + return false, nil + }) +} + +func countEndpointsNum(e *api.Endpoints) int { + num := 0 + for _, sub := range e.Subsets { + num += len(sub.Addresses) + } + return num +} + // waitForReplicationController waits until the RC appears (exist == true), or disappears (exist == false) func waitForReplicationController(c *client.Client, namespace, name string, exist bool, interval, timeout time.Duration) error { - err := wait.Poll(interval, timeout, func() (bool, error) { + err := wait.PollImmediate(interval, timeout, func() (bool, error) { _, err := c.ReplicationControllers(namespace).Get(name) if err != nil { Logf("Get ReplicationController %s in namespace %s failed (%v).", name, namespace, err) @@ -704,6 +745,20 @@ func waitForReplicationController(c *client.Client, namespace, name string, exis return nil } +func waitForEndpoint(c *client.Client, ns, name string) error { + for t := time.Now(); time.Since(t) < endpointRegisterTimeout; time.Sleep(poll) { + endpoint, err := c.Endpoints(ns).Get(name) + Expect(err).NotTo(HaveOccurred()) + if len(endpoint.Subsets) == 0 || len(endpoint.Subsets[0].Addresses) == 0 { + Logf("Endpoint %s/%s is not ready yet", ns, name) + continue + } else { + return nil + } + } + return fmt.Errorf("Failed to get entpoints for %s/%s", ns, name) +} + // Context for checking pods responses by issuing GETs to them and verifying if the answer with pod name. type podResponseChecker struct { c *client.Client @@ -768,13 +823,13 @@ func (r podResponseChecker) checkAllResponses() (done bool, err error) { func podsResponding(c *client.Client, ns, name string, wantName bool, pods *api.PodList) error { By("trying to dial each unique pod") label := labels.SelectorFromSet(labels.Set(map[string]string{"name": name})) - return wait.Poll(poll, podRespondingTimeout, podResponseChecker{c, ns, label, name, wantName, pods}.checkAllResponses) + return wait.PollImmediate(poll, podRespondingTimeout, podResponseChecker{c, ns, label, name, wantName, pods}.checkAllResponses) } func serviceResponding(c *client.Client, ns, name string) error { By(fmt.Sprintf("trying to dial the service %s.%s via the proxy", ns, name)) - return wait.Poll(poll, serviceRespondingTimeout, func() (done bool, err error) { + return wait.PollImmediate(poll, serviceRespondingTimeout, func() (done bool, err error) { body, err := c.Get(). Prefix("proxy"). Namespace(ns). @@ -823,6 +878,9 @@ func loadClient() (*client.Client, error) { if err != nil { return nil, fmt.Errorf("error creating client: %v", err.Error()) } + if c.Timeout == 0 { + c.Timeout = singleCallTimeout + } return c, nil } @@ -1024,10 +1082,29 @@ func tryKill(cmd *exec.Cmd) { } } -// testContainerOutputInNamespace runs the given pod in the given namespace and waits -// for all of the containers in the podSpec to move into the 'Success' status. It retrieves -// the exact container log and searches for lines of expected output. -func testContainerOutputInNamespace(scenarioName string, c *client.Client, pod *api.Pod, containerIndex int, expectedOutput []string, ns string) { +// testContainerOutput runs the given pod in the given namespace and waits +// for all of the containers in the podSpec to move into the 'Success' status, and tests +// the specified container log against the given expected output using a substring matcher. +func testContainerOutput(scenarioName string, c *client.Client, pod *api.Pod, containerIndex int, expectedOutput []string, ns string) { + testContainerOutputMatcher(scenarioName, c, pod, containerIndex, expectedOutput, ns, ContainSubstring) +} + +// testContainerOutputRegexp runs the given pod in the given namespace and waits +// for all of the containers in the podSpec to move into the 'Success' status, and tests +// the specified container log against the given expected output using a regexp matcher. +func testContainerOutputRegexp(scenarioName string, c *client.Client, pod *api.Pod, containerIndex int, expectedOutput []string, ns string) { + testContainerOutputMatcher(scenarioName, c, pod, containerIndex, expectedOutput, ns, MatchRegexp) +} + +// testContainerOutputMatcher runs the given pod in the given namespace and waits +// for all of the containers in the podSpec to move into the 'Success' status, and tests +// the specified container log against the given expected output using the given matcher. +func testContainerOutputMatcher(scenarioName string, + c *client.Client, + pod *api.Pod, + containerIndex int, + expectedOutput []string, ns string, + matcher func(string, ...interface{}) gomegatypes.GomegaMatcher) { By(fmt.Sprintf("Creating a pod to test %v", scenarioName)) defer c.Pods(ns).Delete(pod.Name, api.NewDeleteOptions(0)) @@ -1083,7 +1160,7 @@ func testContainerOutputInNamespace(scenarioName string, c *client.Client, pod * } for _, m := range expectedOutput { - Expect(string(logs)).To(ContainSubstring(m), "%q in container output", m) + Expect(string(logs)).To(matcher(m), "%q in container output", m) } } @@ -1157,7 +1234,6 @@ func Diff(oldPods []*api.Pod, curPods []*api.Pod) PodDiff { // It's the caller's responsibility to clean up externally (i.e. use the // namespace lifecycle for handling cleanup). func RunRC(config RCConfig) error { - // Don't force tests to fail if they don't care about containers restarting. var maxContainerFailures int if config.MaxContainerFailures == nil { @@ -1168,7 +1244,7 @@ func RunRC(config RCConfig) error { label := labels.SelectorFromSet(labels.Set(map[string]string{"name": config.Name})) - By(fmt.Sprintf("%v Creating replication controller %s", time.Now(), config.Name)) + By(fmt.Sprintf("creating replication controller %s in namespace %s", config.Name, config.Namespace)) rc := &api.ReplicationController{ ObjectMeta: api.ObjectMeta{ Name: config.Name, @@ -1235,7 +1311,7 @@ func RunRC(config RCConfig) error { if err != nil { return fmt.Errorf("Error creating replication controller: %v", err) } - Logf("%v Created replication controller with name: %v, namespace: %v, replica count: %v", time.Now(), rc.Name, config.Namespace, rc.Spec.Replicas) + Logf("Created replication controller with name: %v, namespace: %v, replica count: %v", rc.Name, config.Namespace, rc.Spec.Replicas) podStore := newPodStore(config.Client, config.Namespace, label, fields.Everything()) defer podStore.Stop() @@ -1256,6 +1332,7 @@ func RunRC(config RCConfig) error { terminating := 0 running := 0 + runningButNotReady := 0 waiting := 0 pending := 0 unknown := 0 @@ -1272,7 +1349,19 @@ func RunRC(config RCConfig) error { } created = append(created, p) if p.Status.Phase == api.PodRunning { - running++ + ready := false + for _, c := range p.Status.Conditions { + if c.Type == api.PodReady && c.Status == api.ConditionTrue { + ready = true + break + } + } + if ready { + // Only count a pod is running when it is also ready. + running++ + } else { + runningButNotReady++ + } for _, v := range FailedContainers(p) { failedContainers = failedContainers + v.restarts containerRestartNodes.Insert(p.Spec.NodeName) @@ -1294,13 +1383,13 @@ func RunRC(config RCConfig) error { *config.CreatedPods = pods } - Logf("%v %v Pods: %d out of %d created, %d running, %d pending, %d waiting, %d inactive, %d terminating, %d unknown ", - time.Now(), rc.Name, len(pods), config.Replicas, running, pending, waiting, inactive, terminating, unknown) + Logf("%v Pods: %d out of %d created, %d running, %d pending, %d waiting, %d inactive, %d terminating, %d unknown, %d runningButNotReady ", + rc.Name, len(pods), config.Replicas, running, pending, waiting, inactive, terminating, unknown, runningButNotReady) promPushRunningPending(running, pending) if config.PodStatusFile != nil { - fmt.Fprintf(config.PodStatusFile, "%s, %d, running, %d, pending, %d, waiting, %d, inactive, %d, unknown\n", time.Now(), running, pending, waiting, inactive, unknown) + fmt.Fprintf(config.PodStatusFile, "%d, running, %d, pending, %d, waiting, %d, inactive, %d, unknown, %d, runningButNotReady\n", running, pending, waiting, inactive, unknown, runningButNotReady) } if failedContainers > maxContainerFailures { @@ -1332,9 +1421,11 @@ func RunRC(config RCConfig) error { } if oldRunning != config.Replicas { - if pods, err := config.Client.Pods(api.NamespaceAll).List(labels.Everything(), fields.Everything()); err == nil { + // List only pods from a given replication controller. + if pods, err := config.Client.Pods(api.NamespaceAll).List(label, fields.Everything()); err == nil { + for _, pod := range pods.Items { - Logf("Pod %s\t%s\t%s\t%s", pod.Namespace, pod.Name, pod.Spec.NodeName, pod.DeletionTimestamp) + Logf("Pod %s\t%s\t%s\t%s", pod.Name, pod.Spec.NodeName, pod.Status.Phase, pod.DeletionTimestamp) } } else { Logf("Can't list pod debug info: %v", err) @@ -1412,8 +1503,8 @@ func getNodeEvents(c *client.Client, nodeName string) []api.Event { } func ScaleRC(c *client.Client, ns, name string, size uint, wait bool) error { - By(fmt.Sprintf("%v Scaling replication controller %s in namespace %s to %d", time.Now(), name, ns, size)) - scaler, err := kubectl.ScalerFor("ReplicationController", kubectl.NewScalerClient(c)) + By(fmt.Sprintf("Scaling replication controller %s in namespace %s to %d", name, ns, size)) + scaler, err := kubectl.ScalerFor("ReplicationController", c) if err != nil { return err } @@ -1468,7 +1559,7 @@ func waitForPodsWithLabel(c *client.Client, ns string, label labels.Selector) (p // Delete a Replication Controller and all pods it spawned func DeleteRC(c *client.Client, ns, name string) error { - By(fmt.Sprintf("%v Deleting replication controller %s in namespace %s", time.Now(), name, ns)) + By(fmt.Sprintf("deleting replication controller %s in namespace %s", name, ns)) rc, err := c.ReplicationControllers(ns).Get(name) if err != nil { if apierrs.IsNotFound(err) { @@ -1504,7 +1595,7 @@ func DeleteRC(c *client.Client, ns, name string) error { // waitForRCPodsGone waits until there are no pods reported under an RC's selector (because the pods // have completed termination). func waitForRCPodsGone(c *client.Client, rc *api.ReplicationController) error { - return wait.Poll(poll, 2*time.Minute, func() (bool, error) { + return wait.PollImmediate(poll, 2*time.Minute, func() (bool, error) { if pods, err := c.Pods(rc.Namespace).List(labels.SelectorFromSet(rc.Spec.Selector), fields.Everything()); err == nil && len(pods.Items) == 0 { return true, nil } @@ -1512,11 +1603,79 @@ func waitForRCPodsGone(c *client.Client, rc *api.ReplicationController) error { }) } +// Waits for the deployment to reach desired state. +// Returns an error if minAvailable or maxCreated is broken at any times. +func waitForDeploymentStatus(c *client.Client, ns, deploymentName string, desiredUpdatedReplicas, minAvailable, maxCreated int) error { + return wait.Poll(poll, 5*time.Minute, func() (bool, error) { + + deployment, err := c.Deployments(ns).Get(deploymentName) + if err != nil { + return false, err + } + oldRCs, err := deploymentUtil.GetOldRCs(*deployment, c) + if err != nil { + return false, err + } + newRC, err := deploymentUtil.GetNewRC(*deployment, c) + if err != nil { + return false, err + } + if newRC == nil { + // New RC hasnt been created yet. + return false, nil + } + allRCs := append(oldRCs, newRC) + totalCreated := deploymentUtil.GetReplicaCountForRCs(allRCs) + totalAvailable, err := deploymentUtil.GetAvailablePodsForRCs(c, allRCs) + if err != nil { + return false, err + } + if totalCreated > maxCreated { + return false, fmt.Errorf("total pods created: %d, more than the max allowed: %d", totalCreated, maxCreated) + } + if totalAvailable < minAvailable { + return false, fmt.Errorf("total pods available: %d, less than the min required: %d", totalAvailable, minAvailable) + } + + if deployment.Status.Replicas == desiredUpdatedReplicas && + deployment.Status.UpdatedReplicas == desiredUpdatedReplicas { + // Verify RCs. + if deploymentUtil.GetReplicaCountForRCs(oldRCs) != 0 { + return false, fmt.Errorf("old RCs are not fully scaled down") + } + if deploymentUtil.GetReplicaCountForRCs([]*api.ReplicationController{newRC}) != desiredUpdatedReplicas { + return false, fmt.Errorf("new RCs is not fully scaled up") + } + return true, nil + } + return false, nil + }) +} + +// Waits for the number of events on the given object to reach a desired count. +func waitForEvents(c *client.Client, ns string, objOrRef runtime.Object, desiredEventsCount int) error { + return wait.Poll(poll, 5*time.Minute, func() (bool, error) { + events, err := c.Events(ns).Search(objOrRef) + if err != nil { + return false, fmt.Errorf("error in listing events: %s", err) + } + eventsCount := len(events.Items) + if eventsCount == desiredEventsCount { + return true, nil + } + if eventsCount < desiredEventsCount { + return false, nil + } + // Number of events has exceeded the desired count. + return false, fmt.Errorf("number of events has exceeded the desired count, eventsCount: %d, desiredCount: %d", eventsCount, desiredEventsCount) + }) +} + // Convenient wrapper around listing nodes supporting retries. func listNodes(c *client.Client, label labels.Selector, field fields.Selector) (*api.NodeList, error) { var nodes *api.NodeList var errLast error - if wait.Poll(poll, singleCallTimeout, func() (bool, error) { + if wait.PollImmediate(poll, singleCallTimeout, func() (bool, error) { nodes, errLast = c.Nodes().List(label, field) return errLast == nil, nil }) != nil { @@ -1668,6 +1827,12 @@ func getSigner(provider string) (ssh.Signer, error) { case "gce", "gke": keyfile = "google_compute_engine" case "aws": + // If there is an env. variable override, use that. + aws_keyfile := os.Getenv("AWS_SSH_KEY") + if len(aws_keyfile) != 0 { + return util.MakePrivateKeySignerFromFile(aws_keyfile) + } + // Otherwise revert to home dir keyfile = "kube_aws_rsa" default: return nil, fmt.Errorf("getSigner(...) not implemented for %s", provider) @@ -1696,7 +1861,7 @@ func checkPodsRunningReady(c *client.Client, ns string, podNames []string, timeo // support only Go >= 1.4. for _, podName := range podNames { if !<-result { - Logf("Pod %-[1]*[2]s failed to be %[3]s.", podPrintWidth, podName, desc) + Logf("Pod %[1]s failed to be %[2]s.", podName, desc) success = false } } @@ -1758,7 +1923,7 @@ func allNodesReady(c *client.Client, timeout time.Duration) error { Logf("Waiting up to %v for all nodes to be ready", timeout) var notReady []api.Node - err := wait.Poll(poll, timeout, func() (bool, error) { + err := wait.PollImmediate(poll, timeout, func() (bool, error) { notReady = nil nodes, err := c.Nodes().List(labels.Everything(), fields.Everything()) if err != nil { @@ -1796,187 +1961,6 @@ func filterNodes(nodeList *api.NodeList, fn func(node api.Node) bool) { nodeList.Items = l } -// LatencyMetrics stores data about request latency at a given quantile -// broken down by verb (e.g. GET, PUT, LIST) and resource (e.g. pods, services). -type LatencyMetric struct { - Verb string - Resource string - // 0 <= quantile <=1, e.g. 0.95 is 95%tile, 0.5 is median. - Quantile float64 - Latency time.Duration -} - -// latencyMetricIngestor implements extraction.Ingester -type latencyMetricIngester []LatencyMetric - -func (l *latencyMetricIngester) Ingest(samples model.Samples) error { - for _, sample := range samples { - // Example line: - // apiserver_request_latencies_summary{resource="namespaces",verb="LIST",quantile="0.99"} 908 - if sample.Metric[model.MetricNameLabel] != "apiserver_request_latencies_summary" { - continue - } - - resource := string(sample.Metric["resource"]) - verb := string(sample.Metric["verb"]) - latency := sample.Value - quantile, err := strconv.ParseFloat(string(sample.Metric[model.QuantileLabel]), 64) - if err != nil { - return err - } - *l = append(*l, LatencyMetric{ - verb, - resource, - quantile, - time.Duration(int64(latency)) * time.Microsecond, - }) - } - return nil -} - -// LatencyMetricByLatency implements sort.Interface for []LatencyMetric based on -// the latency field. -type LatencyMetricByLatency []LatencyMetric - -func (a LatencyMetricByLatency) Len() int { return len(a) } -func (a LatencyMetricByLatency) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a LatencyMetricByLatency) Less(i, j int) bool { return a[i].Latency < a[j].Latency } - -func ReadLatencyMetrics(c *client.Client) ([]LatencyMetric, error) { - body, err := getMetrics(c) - if err != nil { - return nil, err - } - var ingester latencyMetricIngester - err = extraction.Processor004.ProcessSingle(strings.NewReader(body), &ingester, &extraction.ProcessOptions{}) - return ingester, err -} - -// Prints summary metrics for request types with latency above threshold -// and returns number of such request types. -func HighLatencyRequests(c *client.Client, threshold time.Duration, ignoredResources sets.String) (int, error) { - ignoredVerbs := sets.NewString("WATCHLIST", "PROXY") - - metrics, err := ReadLatencyMetrics(c) - if err != nil { - return 0, err - } - sort.Sort(sort.Reverse(LatencyMetricByLatency(metrics))) - var badMetrics []LatencyMetric - top := 5 - for _, metric := range metrics { - if ignoredResources.Has(metric.Resource) || ignoredVerbs.Has(metric.Verb) { - continue - } - isBad := false - if metric.Latency > threshold && - // We are only interested in 99%tile, but for logging purposes - // it's useful to have all the offending percentiles. - metric.Quantile <= 0.99 { - badMetrics = append(badMetrics, metric) - isBad = true - } - if top > 0 || isBad { - top-- - prefix := "" - if isBad { - prefix = "WARNING " - } - Logf("%vTop latency metric: %+v", prefix, metric) - } - } - - return len(badMetrics), nil -} - -// Reset latency metrics in apiserver. -func resetMetrics(c *client.Client) error { - Logf("Resetting latency metrics in apiserver...") - body, err := c.Get().AbsPath("/resetMetrics").DoRaw() - if err != nil { - return err - } - if string(body) != "metrics reset\n" { - return fmt.Errorf("Unexpected response: %q", string(body)) - } - return nil -} - -// Retrieve metrics information -func getMetrics(c *client.Client) (string, error) { - body, err := c.Get().AbsPath("/metrics").DoRaw() - if err != nil { - return "", err - } - return string(body), nil -} - -// Retrieve debug information -func getDebugInfo(c *client.Client) (map[string]string, error) { - data := make(map[string]string) - for _, key := range []string{"block", "goroutine", "heap", "threadcreate"} { - resp, err := http.Get(c.Get().AbsPath(fmt.Sprintf("debug/pprof/%s", key)).URL().String() + "?debug=2") - if err != nil { - Logf("Warning: Error trying to fetch %s debug data: %v", key, err) - continue - } - body, err := ioutil.ReadAll(resp.Body) - resp.Body.Close() - if err != nil { - Logf("Warning: Error trying to read %s debug data: %v", key, err) - } - data[key] = string(body) - } - return data, nil -} - -func writePerfData(c *client.Client, dirName string, postfix string) error { - fname := fmt.Sprintf("%s/metrics_%s.txt", dirName, postfix) - - handler, err := os.Create(fname) - if err != nil { - return fmt.Errorf("Error creating file '%s': %v", fname, err) - } - - metrics, err := getMetrics(c) - if err != nil { - return fmt.Errorf("Error retrieving metrics: %v", err) - } - - _, err = handler.WriteString(metrics) - if err != nil { - return fmt.Errorf("Error writing metrics: %v", err) - } - - err = handler.Close() - if err != nil { - return fmt.Errorf("Error closing '%s': %v", fname, err) - } - - debug, err := getDebugInfo(c) - if err != nil { - return fmt.Errorf("Error retrieving debug information: %v", err) - } - - for key, value := range debug { - fname := fmt.Sprintf("%s/%s_%s.txt", dirName, key, postfix) - handler, err = os.Create(fname) - if err != nil { - return fmt.Errorf("Error creating file '%s': %v", fname, err) - } - _, err = handler.WriteString(value) - if err != nil { - return fmt.Errorf("Error writing %s: %v", key, err) - } - - err = handler.Close() - if err != nil { - return fmt.Errorf("Error closing '%s': %v", fname, err) - } - } - return nil -} - // parseKVLines parses output that looks like lines containing ": " // and returns if is found. Otherwise, it returns the empty string. func parseKVLines(output, key string) string { @@ -2060,6 +2044,29 @@ func waitForClusterSize(c *client.Client, size int, timeout time.Duration) error return fmt.Errorf("timeout waiting %v for cluster size to be %d", timeout, size) } +// getHostExternalAddress gets the node for a pod and returns the first External +// address. Returns an error if the node the pod is on doesn't have an External +// address. +func getHostExternalAddress(client *client.Client, p *api.Pod) (externalAddress string, err error) { + node, err := client.Nodes().Get(p.Spec.NodeName) + if err != nil { + return "", err + } + for _, address := range node.Status.Addresses { + if address.Type == api.NodeExternalIP { + if address.Address != "" { + externalAddress = address.Address + break + } + } + } + if externalAddress == "" { + err = fmt.Errorf("No external address for pod %v on node %v", + p.Name, p.Spec.NodeName) + } + return +} + type extractRT struct { http.Header } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/volumes.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/volumes.go index a95d23d79113..062bbbc38323 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/volumes.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/volumes.go @@ -33,9 +33,11 @@ package e2e import ( "fmt" + "time" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" - "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -99,7 +101,7 @@ func startVolumeServer(client *client.Client, config VolumeTestConfig) *api.Pod privileged := new(bool) *privileged = true serverPod := &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", APIVersion: "v1", }, @@ -159,7 +161,7 @@ func testVolumeClient(client *client.Client, config VolumeTestConfig, volume api podClient := client.Pods(config.namespace) clientPod := &api.Pod{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", APIVersion: "v1", }, @@ -234,7 +236,7 @@ var _ = Describe("Volumes", func() { AfterEach(func() { if clean { - if err := deleteNS(c, namespace.Name); err != nil { + if err := deleteNS(c, namespace.Name, 5*time.Minute /* namespace deletion timeout */); err != nil { Failf("Couldn't delete ns %s", err) } } @@ -304,7 +306,7 @@ var _ = Describe("Volumes", func() { // create Endpoints for the server endpoints := api.Endpoints{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Endpoints", APIVersion: "v1", }, @@ -435,7 +437,7 @@ var _ = Describe("Volumes", func() { // create secrets for the server secret := api.Secret{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Secret", APIVersion: "v1", }, @@ -507,7 +509,7 @@ var _ = Describe("Volumes", func() { // create ceph secret secret := &api.Secret{ - TypeMeta: api.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Secret", APIVersion: "v1beta3", }, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/third_party/golang/template/exec.go b/Godeps/_workspace/src/k8s.io/kubernetes/third_party/golang/template/exec.go index 804f36274aed..739fd3509ced 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/third_party/golang/template/exec.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/third_party/golang/template/exec.go @@ -2,9 +2,10 @@ //The original private functions indirect and printableValue //are exported as public functions. package template + import ( - "reflect" "fmt" + "reflect" ) var Indirect = indirect @@ -15,7 +16,6 @@ var ( fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() ) - // indirect returns the item at the end of indirection, and a bool to indicate if it's nil. // We indirect through pointers and empty interfaces (only) because // non-empty interfaces have methods we might need. From e9a12151d67cedb4d3816a791ff02cfc61f024c9 Mon Sep 17 00:00:00 2001 From: deads2k Date: Tue, 11 Aug 2015 13:10:40 -0400 Subject: [PATCH 06/35] UPSTREAM: : Disable UIs for Kubernetes and etcd --- .../_workspace/src/k8s.io/kubernetes/pkg/master/master.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go index 0f886fe8c5ab..32a04929b63d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go @@ -77,7 +77,7 @@ import ( "k8s.io/kubernetes/pkg/storage" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" "k8s.io/kubernetes/pkg/tools" - "k8s.io/kubernetes/pkg/ui" + //"k8s.io/kubernetes/pkg/ui" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" @@ -684,9 +684,9 @@ func (m *Master) init(c *Config) { if c.EnableLogsSupport { apiserver.InstallLogsSupport(m.muxHelper) } - if c.EnableUISupport { - ui.InstallSupport(m.muxHelper, m.enableSwaggerSupport) - } + /*if c.EnableUISupport { + ui.InstallSupport(m.mux) + }*/ if c.EnableProfiling { m.mux.HandleFunc("/debug/pprof/", pprof.Index) From 97bd6c288493bd17c5330e9b0aedf50a6ce4c1d6 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Tue, 11 Aug 2015 13:31:00 -0400 Subject: [PATCH 07/35] UPSTREAM: : Allow pod start to be delayed in Kubelet Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/cmd/kubelet/app/server.go Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config.go --- .../kubernetes/cmd/kubelet/app/server.go | 4 ++++ .../kubernetes/pkg/kubelet/config/config.go | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/cmd/kubelet/app/server.go b/Godeps/_workspace/src/k8s.io/kubernetes/cmd/kubelet/app/server.go index 405ce99ecda7..11e500ff22a0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/cmd/kubelet/app/server.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/cmd/kubelet/app/server.go @@ -782,6 +782,9 @@ func startKubelet(k KubeletBootstrap, podCfg *config.PodConfig, kc *KubeletConfi func makePodSourceConfig(kc *KubeletConfig) *config.PodConfig { // source of all configuration cfg := config.NewPodConfig(config.PodConfigNotificationIncremental, kc.Recorder) + if kc.StartUpdates != nil { + cfg.Wait(kc.StartUpdates) + } // define file config source if kc.ConfigFile != "" { @@ -873,6 +876,7 @@ type KubeletConfig struct { TLSOptions *kubelet.TLSOptions Writer io.Writer VolumePlugins []volume.VolumePlugin + StartUpdates <-chan struct{} } func CreateAndInitKubelet(kc *KubeletConfig) (k KubeletBootstrap, pc *config.PodConfig, err error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config.go index 123ea71919cc..abd4020b1053 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/config/config.go @@ -28,6 +28,7 @@ import ( kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubeletutil "k8s.io/kubernetes/pkg/kubelet/util" + "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/config" utilerrors "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/fielderrors" @@ -60,6 +61,8 @@ type PodConfig struct { // the channel of denormalized changes passed to listeners updates chan kubetypes.PodUpdate + // an optional wait channel + wait <-chan struct{} // contains the list of all configured sources sourcesLock sync.Mutex @@ -80,6 +83,20 @@ func NewPodConfig(mode PodConfigNotificationMode, recorder record.EventRecorder) return podConfig } +func (c *PodConfig) Wait(waitCh <-chan struct{}) { + c.wait = waitCh + ch := make(chan kubetypes.PodUpdate) + oldCh := c.updates + go util.Forever(func() { + <-waitCh + for { + update := <-oldCh + ch <- update + } + }, 0) + c.updates = ch +} + // Channel creates or returns a config source channel. The channel // only accepts PodUpdates func (c *PodConfig) Channel(source string) chan<- interface{} { @@ -95,6 +112,13 @@ func (c *PodConfig) SeenAllSources(seenSources sets.String) bool { if c.pods == nil { return false } + if c.wait != nil { + select { + case <-c.wait: + default: + return false + } + } glog.V(6).Infof("Looking for %v, have seen %v", c.sources.List(), seenSources) return seenSources.HasAll(c.sources.List()...) && c.pods.seenSources(c.sources.List()...) } From dae0c95b2341bae5b9783482efc966066d8a0ad1 Mon Sep 17 00:00:00 2001 From: deads2k Date: Fri, 16 Oct 2015 16:11:22 -0400 Subject: [PATCH 08/35] UPSTREAM: : SCC --- Godeps/Godeps.json | 5 + .../kubernetes/pkg/api/deep_copy_generated.go | 151 +++++++ .../kubernetes/pkg/api/install/install.go | 3 +- .../src/k8s.io/kubernetes/pkg/api/register.go | 6 + .../kubernetes/pkg/api/testing/fuzzer.go | 11 + .../src/k8s.io/kubernetes/pkg/api/types.go | 133 ++++++ .../pkg/api/v1/conversion_generated.go | 340 +++++++++++++++ .../pkg/api/v1/deep_copy_generated.go | 151 +++++++ .../k8s.io/kubernetes/pkg/api/v1/register.go | 6 + .../src/k8s.io/kubernetes/pkg/api/v1/types.go | 133 ++++++ .../pkg/api/validation/validation.go | 47 +++ .../pkg/api/validation/validation_test.go | 133 ++++++ .../pkg/client/unversioned/client.go | 6 + .../unversioned/securitycontextconstraints.go | 115 +++++ .../securitycontextconstraints_test.go | 137 ++++++ .../fake_securitycontextconstraints.go | 61 +++ .../unversioned/testclient/testclient.go | 4 + .../k8s.io/kubernetes/pkg/kubectl/kubectl.go | 2 + .../pkg/kubectl/resource_printer.go | 20 + .../k8s.io/kubernetes/pkg/master/master.go | 4 + .../securitycontextconstraints/doc.go | 19 + .../securitycontextconstraints/etcd/etcd.go | 64 +++ .../etcd/etcd_test.go | 74 ++++ .../securitycontextconstraints/registry.go | 87 ++++ .../securitycontextconstraints/strategy.go | 88 ++++ .../pkg/registry/service/allocator/bitmap.go | 4 + .../securitycontextconstraints/provider.go | 205 +++++++++ .../provider_test.go | 395 ++++++++++++++++++ .../securitycontextconstraints/selinux/doc.go | 18 + .../selinux/mustrunas.go | 82 ++++ .../selinux/mustrunas_test.go | 157 +++++++ .../selinux/runasany.go | 42 ++ .../selinux/runasany_test.go | 71 ++++ .../selinux/types.go | 30 ++ .../pkg/securitycontextconstraints/types.go | 33 ++ .../securitycontextconstraints/user/doc.go | 18 + .../user/mustrunas.go | 71 ++++ .../user/mustrunas_test.go | 90 ++++ .../user/mustrunasrange.go | 76 ++++ .../user/nonroot.go | 57 +++ .../user/nonroot_test.go | 78 ++++ .../user/runasany.go | 42 ++ .../user/runasany_test.go | 58 +++ .../securitycontextconstraints/user/types.go | 30 ++ .../securitycontextconstraints/user/util.go | 57 +++ 45 files changed, 3412 insertions(+), 2 deletions(-) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_securitycontextconstraints.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/doc.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/registry.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/strategy.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/doc.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/types.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/types.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/doc.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunasrange.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/types.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/util.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index ec6634792e3f..3892fb7b1bb1 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1243,6 +1243,11 @@ "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", "Rev": "4c8e6f47ec23f390978e651232b375f5f9cde3c7" }, + { + "ImportPath": "k8s.io/kubernetes/pkg/securitycontextconstraints", + "Comment": "v1.1.0-alpha.1-653-g86b4e77", + "Rev": "86b4e777e1947c1bc00e422306a3ca74cbd54dbe" + }, { "ImportPath": "k8s.io/kubernetes/pkg/storage", "Comment": "v1.2.0-alpha.1-1107-g4c8e6f4", diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go index 8b73d005346a..92e30b79b438 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go @@ -1872,6 +1872,42 @@ func deepCopy_api_ResourceRequirements(in ResourceRequirements, out *ResourceReq return nil } +func deepCopy_api_RunAsUserStrategyOptions(in RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.UID != nil { + out.UID = new(int64) + *out.UID = *in.UID + } else { + out.UID = nil + } + if in.UIDRangeMin != nil { + out.UIDRangeMin = new(int64) + *out.UIDRangeMin = *in.UIDRangeMin + } else { + out.UIDRangeMin = nil + } + if in.UIDRangeMax != nil { + out.UIDRangeMax = new(int64) + *out.UIDRangeMax = *in.UIDRangeMax + } else { + out.UIDRangeMax = nil + } + return nil +} + +func deepCopy_api_SELinuxContextStrategyOptions(in SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(SELinuxOptions) + if err := deepCopy_api_SELinuxOptions(*in.SELinuxOptions, out.SELinuxOptions, c); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + return nil +} + func deepCopy_api_SELinuxOptions(in SELinuxOptions, out *SELinuxOptions, c *conversion.Cloner) error { out.User = in.User out.Role = in.Role @@ -1880,6 +1916,42 @@ func deepCopy_api_SELinuxOptions(in SELinuxOptions, out *SELinuxOptions, c *conv return nil } +func deepCopy_api_SupplementalGroupsStrategyOptions(in SupplementalGroupsStrategyOptions, out *SupplementalGroupsStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.Ranges != nil { + out.Ranges = make([]IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := deepCopy_api_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func deepCopy_api_FSGroupStrategyOptions(in FSGroupStrategyOptions, out *FSGroupStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.Ranges != nil { + out.Ranges = make([]IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := deepCopy_api_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func deepCopy_api_IDRange(in IDRange, out *IDRange, c *conversion.Cloner) error { + out.Max = in.Max + out.Min = in.Min + return nil +} + func deepCopy_api_Secret(in Secret, out *Secret, c *conversion.Cloner) error { if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err @@ -1961,6 +2033,78 @@ func deepCopy_api_SecurityContext(in SecurityContext, out *SecurityContext, c *c return nil } +func deepCopy_api_SecurityContextConstraints(in SecurityContextConstraints, out *SecurityContextConstraints, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + out.AllowPrivilegedContainer = in.AllowPrivilegedContainer + if in.AllowedCapabilities != nil { + out.AllowedCapabilities = make([]Capability, len(in.AllowedCapabilities)) + for i := range in.AllowedCapabilities { + out.AllowedCapabilities[i] = in.AllowedCapabilities[i] + } + } else { + out.AllowedCapabilities = nil + } + out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + out.AllowHostNetwork = in.AllowHostNetwork + out.AllowHostPorts = in.AllowHostPorts + out.AllowHostPID = in.AllowHostPID + out.AllowHostIPC = in.AllowHostIPC + if err := deepCopy_api_SELinuxContextStrategyOptions(in.SELinuxContext, &out.SELinuxContext, c); err != nil { + return err + } + if err := deepCopy_api_RunAsUserStrategyOptions(in.RunAsUser, &out.RunAsUser, c); err != nil { + return err + } + if err := deepCopy_api_FSGroupStrategyOptions(in.FSGroup, &out.FSGroup, c); err != nil { + return err + } + if err := deepCopy_api_SupplementalGroupsStrategyOptions(in.SupplementalGroups, &out.SupplementalGroups, c); err != nil { + return err + } + if in.Users != nil { + out.Users = make([]string, len(in.Users)) + for i := range in.Users { + out.Users[i] = in.Users[i] + } + } else { + out.Users = nil + } + if in.Groups != nil { + out.Groups = make([]string, len(in.Groups)) + for i := range in.Groups { + out.Groups[i] = in.Groups[i] + } + } else { + out.Groups = nil + } + return nil +} + +func deepCopy_api_SecurityContextConstraintsList(in SecurityContextConstraintsList, out *SecurityContextConstraintsList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]SecurityContextConstraints, len(in.Items)) + for i := range in.Items { + if err := deepCopy_api_SecurityContextConstraints(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + func deepCopy_api_SerializedReference(in SerializedReference, out *SerializedReference, c *conversion.Cloner) error { if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err @@ -2342,12 +2486,14 @@ func init() { deepCopy_api_ExecAction, deepCopy_api_FCVolumeSource, deepCopy_api_FlockerVolumeSource, + deepCopy_api_FSGroupStrategyOptions, deepCopy_api_GCEPersistentDiskVolumeSource, deepCopy_api_GitRepoVolumeSource, deepCopy_api_GlusterfsVolumeSource, deepCopy_api_HTTPGetAction, deepCopy_api_Handler, deepCopy_api_HostPathVolumeSource, + deepCopy_api_IDRange, deepCopy_api_ISCSIVolumeSource, deepCopy_api_Lifecycle, deepCopy_api_LimitRange, @@ -2411,11 +2557,15 @@ func init() { deepCopy_api_ResourceQuotaSpec, deepCopy_api_ResourceQuotaStatus, deepCopy_api_ResourceRequirements, + deepCopy_api_RunAsUserStrategyOptions, + deepCopy_api_SELinuxContextStrategyOptions, deepCopy_api_SELinuxOptions, deepCopy_api_Secret, deepCopy_api_SecretList, deepCopy_api_SecretVolumeSource, deepCopy_api_SecurityContext, + deepCopy_api_SecurityContextConstraints, + deepCopy_api_SecurityContextConstraintsList, deepCopy_api_SerializedReference, deepCopy_api_Service, deepCopy_api_ServiceAccount, @@ -2424,6 +2574,7 @@ func init() { deepCopy_api_ServicePort, deepCopy_api_ServiceSpec, deepCopy_api_ServiceStatus, + deepCopy_api_SupplementalGroupsStrategyOptions, deepCopy_api_TCPSocketAction, deepCopy_api_Volume, deepCopy_api_VolumeMount, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go index 49eeb3ca3304..91ee3accdfb7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go @@ -68,8 +68,6 @@ func init() { groupMeta.SelfLinker = runtime.SelfLinker(accessor) - // the list of kinds that are scoped at the root of the api hierarchy - // if a kind is not enumerated here, it is assumed to have a namespace scope // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope rootScoped := sets.NewString( @@ -77,6 +75,7 @@ func init() { "Minion", "Namespace", "PersistentVolume", + "SecurityContextConstraints", ) // these kinds should be excluded from the list of resources diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/register.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/register.go index 917b4a2318dc..d63fc7096718 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/register.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/register.go @@ -67,6 +67,9 @@ func init() { &ComponentStatusList{}, &SerializedReference{}, &RangeAllocation{}, + + &SecurityContextConstraints{}, + &SecurityContextConstraintsList{}, ) // Register Unversioned types @@ -114,3 +117,6 @@ func (*ComponentStatus) IsAnAPIObject() {} func (*ComponentStatusList) IsAnAPIObject() {} func (*SerializedReference) IsAnAPIObject() {} func (*RangeAllocation) IsAnAPIObject() {} + +func (*SecurityContextConstraints) IsAnAPIObject() {} +func (*SecurityContextConstraintsList) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/fuzzer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/fuzzer.go index 7b9385fe9d38..917bcdf96a6f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/fuzzer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/testing/fuzzer.go @@ -368,6 +368,17 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { // string, which will cause tests failure. s.APIGroup = "something" }, + func(scc *api.SecurityContextConstraints, c fuzz.Continue) { + c.FuzzNoCustom(scc) // fuzz self without calling this function again + userTypes := []api.RunAsUserStrategyType{api.RunAsUserStrategyMustRunAsNonRoot, api.RunAsUserStrategyMustRunAs, api.RunAsUserStrategyRunAsAny, api.RunAsUserStrategyMustRunAsRange} + scc.RunAsUser.Type = userTypes[c.Rand.Intn(len(userTypes))] + seLinuxTypes := []api.SELinuxContextStrategyType{api.SELinuxStrategyRunAsAny, api.SELinuxStrategyMustRunAs} + scc.SELinuxContext.Type = seLinuxTypes[c.Rand.Intn(len(seLinuxTypes))] + supGroupTypes := []api.SupplementalGroupsStrategyType{api.SupplementalGroupsStrategyMustRunAs, api.SupplementalGroupsStrategyMustRunAs} + scc.SupplementalGroups.Type = supGroupTypes[c.Rand.Intn(len(supGroupTypes))] + fsGroupTypes := []api.FSGroupStrategyType{api.FSGroupStrategyMustRunAs, api.FSGroupStrategyRunAsAny} + scc.FSGroup.Type = fsGroupTypes[c.Rand.Intn(len(fsGroupTypes))] + }, ) return f } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go index 35aadf2f5a49..cf12acf2af55 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go @@ -2089,3 +2089,136 @@ type RangeAllocation struct { // a single allocated address (the fifth bit on CIDR 10.0.0.0/8 is 10.0.0.4). Data []byte `json:"data"` } + +// SecurityContextConstraints governs the ability to make requests that affect the SecurityContext +// that will be applied to a container. +type SecurityContextConstraints struct { + unversioned.TypeMeta + ObjectMeta + + // AllowPrivilegedContainer determines if a container can request to be run as privileged. + AllowPrivilegedContainer bool + // AllowedCapabilities is a list of capabilities that can be requested to add to the container. + AllowedCapabilities []Capability + // AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin + AllowHostDirVolumePlugin bool + // AllowHostNetwork determines if the policy allows the use of HostNetwork in the pod spec. + AllowHostNetwork bool + // AllowHostPorts determines if the policy allows host ports in the containers. + AllowHostPorts bool + // AllowHostPID determines if the policy allows host pid in the containers. + AllowHostPID bool + // AllowHostIPC determines if the policy allows host ipc in the containers. + AllowHostIPC bool + // SELinuxContext is the strategy that will dictate what labels will be set in the SecurityContext. + SELinuxContext SELinuxContextStrategyOptions + // RunAsUser is the strategy that will dictate what RunAsUser is used in the SecurityContext. + RunAsUser RunAsUserStrategyOptions + // SupplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. + SupplementalGroups SupplementalGroupsStrategyOptions + // FSGroup is the strategy that will dictate what fs group is used by the SecurityContext. + FSGroup FSGroupStrategyOptions + + // The users who have permissions to use this security context constraints + Users []string + // The groups that have permission to use this security context constraints + Groups []string +} + +// SELinuxContextStrategyOptions defines the strategy type and any options used to create the strategy. +type SELinuxContextStrategyOptions struct { + // Type is the strategy that will dictate what SELinux context is used in the SecurityContext. + Type SELinuxContextStrategyType + // seLinuxOptions required to run as; required for MustRunAs + SELinuxOptions *SELinuxOptions +} + +// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. +type RunAsUserStrategyOptions struct { + // Type is the strategy that will dictate what RunAsUser is used in the SecurityContext. + Type RunAsUserStrategyType + // UID is the user id that containers must run as. Required for the MustRunAs strategy if not using + // namespace/service account allocated uids. + UID *int64 + // UIDRangeMin defines the min value for a strategy that allocates by range. + UIDRangeMin *int64 + // UIDRangeMax defines the max value for a strategy that allocates by range. + UIDRangeMax *int64 +} + +// FSGroupStrategyOptions defines the strategy type and options used to create the strategy. +type FSGroupStrategyOptions struct { + // Type is the strategy that will dictate what FSGroup is used in the SecurityContext. + Type FSGroupStrategyType + // Ranges are the allowed ranges of fs groups. If you would like to force a single + // fs group then supply a single range with the same start and end. + Ranges []IDRange +} + +// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. +type SupplementalGroupsStrategyOptions struct { + // Type is the strategy that will dictate what supplemental groups is used in the SecurityContext. + Type SupplementalGroupsStrategyType + // Ranges are the allowed ranges of supplemental groups. If you would like to force a single + // supplemental group then supply a single range with the same start and end. + Ranges []IDRange +} + +// IDRange provides a min/max of an allowed range of IDs. +// TODO: this could be reused for UIDs. +type IDRange struct { + // Min is the start of the range, inclusive. + Min int64 + // Max is the end of the range, inclusive. + Max int64 +} + +// SELinuxContextStrategyType denotes strategy types for generating SELinux options for a +// SecurityContext +type SELinuxContextStrategyType string + +// RunAsUserStrategyType denotes strategy types for generating RunAsUser values for a +// SecurityContext +type RunAsUserStrategyType string + +// SupplementalGroupsStrategyType denotes strategy types for determining valid supplemental +// groups for a SecurityContext. +type SupplementalGroupsStrategyType string + +// FSGroupStrategyType denotes strategy types for generating FSGroup values for a +// SecurityContext +type FSGroupStrategyType string + +const ( + // container must have SELinux labels of X applied. + SELinuxStrategyMustRunAs SELinuxContextStrategyType = "MustRunAs" + // container may make requests for any SELinux context labels. + SELinuxStrategyRunAsAny SELinuxContextStrategyType = "RunAsAny" + + // container must run as a particular uid. + RunAsUserStrategyMustRunAs RunAsUserStrategyType = "MustRunAs" + // container must run as a particular uid. + RunAsUserStrategyMustRunAsRange RunAsUserStrategyType = "MustRunAsRange" + // container must run as a non-root uid + RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategyType = "MustRunAsNonRoot" + // container may make requests for any uid. + RunAsUserStrategyRunAsAny RunAsUserStrategyType = "RunAsAny" + + // container must have FSGroup of X applied. + FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs" + // container may make requests for any FSGroup labels. + FSGroupStrategyRunAsAny FSGroupStrategyType = "RunAsAny" + + // container must run as a particular gid. + SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs" + // container may make requests for any gid. + SupplementalGroupsrStrategyRunAsAny SupplementalGroupsStrategyType = "RunAsAny" +) + +// SecurityContextConstraintsList is a list of SecurityContextConstraints objects +type SecurityContextConstraintsList struct { + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + + Items []SecurityContextConstraints `json:"items"` +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go index 0e9e777d8d26..54adb3728574 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go @@ -2544,6 +2544,48 @@ func autoconvert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, return nil } +func convert_api_RunAsUserStrategyOptions_To_v1_RunAsUserStrategyOptions(in *api.RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.RunAsUserStrategyOptions))(in) + } + out.Type = RunAsUserStrategyType(in.Type) + if in.UID != nil { + out.UID = new(int64) + *out.UID = *in.UID + } else { + out.UID = nil + } + if in.UIDRangeMin != nil { + out.UIDRangeMin = new(int64) + *out.UIDRangeMin = *in.UIDRangeMin + } else { + out.UIDRangeMin = nil + } + if in.UIDRangeMax != nil { + out.UIDRangeMax = new(int64) + *out.UIDRangeMax = *in.UIDRangeMax + } else { + out.UIDRangeMax = nil + } + return nil +} + +func convert_api_SELinuxContextStrategyOptions_To_v1_SELinuxContextStrategyOptions(in *api.SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SELinuxContextStrategyOptions))(in) + } + out.Type = SELinuxContextStrategyType(in.Type) + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(SELinuxOptions) + if err := convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + return nil +} + func convert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, out *SELinuxOptions, s conversion.Scope) error { return autoconvert_api_SELinuxOptions_To_v1_SELinuxOptions(in, out, s) } @@ -2674,6 +2716,84 @@ func convert_api_SerializedReference_To_v1_SerializedReference(in *api.Serialize return autoconvert_api_SerializedReference_To_v1_SerializedReference(in, out, s) } +func convert_api_SecurityContextConstraints_To_v1_SecurityContextConstraints(in *api.SecurityContextConstraints, out *SecurityContextConstraints, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SecurityContextConstraints))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.AllowPrivilegedContainer = in.AllowPrivilegedContainer + if in.AllowedCapabilities != nil { + out.AllowedCapabilities = make([]Capability, len(in.AllowedCapabilities)) + for i := range in.AllowedCapabilities { + out.AllowedCapabilities[i] = Capability(in.AllowedCapabilities[i]) + } + } else { + out.AllowedCapabilities = nil + } + out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + out.AllowHostNetwork = in.AllowHostNetwork + out.AllowHostPorts = in.AllowHostPorts + out.AllowHostPID = in.AllowHostPID + out.AllowHostIPC = in.AllowHostIPC + if err := convert_api_SELinuxContextStrategyOptions_To_v1_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil { + return err + } + if err := convert_api_RunAsUserStrategyOptions_To_v1_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil { + return err + } + if err := convert_api_FSGroupStrategyOptions_To_v1_FSGroupStrategyOptions(&in.FSGroup, &out.FSGroup, s); err != nil { + return err + } + if err := convert_api_SupplementalGroupsStrategyOptions_To_v1_SupplementalGroupsStrategyOptions(&in.SupplementalGroups, &out.SupplementalGroups, s); err != nil { + return err + } + if in.Users != nil { + out.Users = make([]string, len(in.Users)) + for i := range in.Users { + out.Users[i] = in.Users[i] + } + } else { + out.Users = nil + } + if in.Groups != nil { + out.Groups = make([]string, len(in.Groups)) + for i := range in.Groups { + out.Groups[i] = in.Groups[i] + } + } else { + out.Groups = nil + } + return nil +} + +func convert_api_SecurityContextConstraintsList_To_v1_SecurityContextConstraintsList(in *api.SecurityContextConstraintsList, out *SecurityContextConstraintsList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SecurityContextConstraintsList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]SecurityContextConstraints, len(in.Items)) + for i := range in.Items { + if err := convert_api_SecurityContextConstraints_To_v1_SecurityContextConstraints(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + func autoconvert_api_Service_To_v1_Service(in *api.Service, out *Service, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Service))(in) @@ -5563,6 +5683,48 @@ func convert_v1_SELinuxOptions_To_api_SELinuxOptions(in *SELinuxOptions, out *ap return autoconvert_v1_SELinuxOptions_To_api_SELinuxOptions(in, out, s) } +func convert_v1_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions(in *RunAsUserStrategyOptions, out *api.RunAsUserStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*RunAsUserStrategyOptions))(in) + } + out.Type = api.RunAsUserStrategyType(in.Type) + if in.UID != nil { + out.UID = new(int64) + *out.UID = *in.UID + } else { + out.UID = nil + } + if in.UIDRangeMin != nil { + out.UIDRangeMin = new(int64) + *out.UIDRangeMin = *in.UIDRangeMin + } else { + out.UIDRangeMin = nil + } + if in.UIDRangeMax != nil { + out.UIDRangeMax = new(int64) + *out.UIDRangeMax = *in.UIDRangeMax + } else { + out.UIDRangeMax = nil + } + return nil +} + +func convert_v1_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions(in *SELinuxContextStrategyOptions, out *api.SELinuxContextStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SELinuxContextStrategyOptions))(in) + } + out.Type = api.SELinuxContextStrategyType(in.Type) + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(api.SELinuxOptions) + if err := convert_v1_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + return nil +} + func autoconvert_v1_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Secret))(in) @@ -5689,6 +5851,84 @@ func convert_v1_SerializedReference_To_api_SerializedReference(in *SerializedRef return autoconvert_v1_SerializedReference_To_api_SerializedReference(in, out, s) } +func convert_v1_SecurityContextConstraints_To_api_SecurityContextConstraints(in *SecurityContextConstraints, out *api.SecurityContextConstraints, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SecurityContextConstraints))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.AllowPrivilegedContainer = in.AllowPrivilegedContainer + if in.AllowedCapabilities != nil { + out.AllowedCapabilities = make([]api.Capability, len(in.AllowedCapabilities)) + for i := range in.AllowedCapabilities { + out.AllowedCapabilities[i] = api.Capability(in.AllowedCapabilities[i]) + } + } else { + out.AllowedCapabilities = nil + } + out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + out.AllowHostNetwork = in.AllowHostNetwork + out.AllowHostPorts = in.AllowHostPorts + out.AllowHostPID = in.AllowHostPID + out.AllowHostIPC = in.AllowHostIPC + if err := convert_v1_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil { + return err + } + if err := convert_v1_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil { + return err + } + if err := convert_v1_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions(&in.FSGroup, &out.FSGroup, s); err != nil { + return err + } + if err := convert_v1_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions(&in.SupplementalGroups, &out.SupplementalGroups, s); err != nil { + return err + } + if in.Users != nil { + out.Users = make([]string, len(in.Users)) + for i := range in.Users { + out.Users[i] = in.Users[i] + } + } else { + out.Users = nil + } + if in.Groups != nil { + out.Groups = make([]string, len(in.Groups)) + for i := range in.Groups { + out.Groups[i] = in.Groups[i] + } + } else { + out.Groups = nil + } + return nil +} + +func convert_v1_SecurityContextConstraintsList_To_api_SecurityContextConstraintsList(in *SecurityContextConstraintsList, out *api.SecurityContextConstraintsList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SecurityContextConstraintsList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.SecurityContextConstraints, len(in.Items)) + for i := range in.Items { + if err := convert_v1_SecurityContextConstraints_To_api_SecurityContextConstraints(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + func autoconvert_v1_Service_To_api_Service(in *Service, out *api.Service, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Service))(in) @@ -6054,9 +6294,100 @@ func autoconvert_v1_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api. func convert_v1_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api.VolumeSource, s conversion.Scope) error { return autoconvert_v1_VolumeSource_To_api_VolumeSource(in, out, s) } +func convert_api_FSGroupStrategyOptions_To_v1_FSGroupStrategyOptions(in *api.FSGroupStrategyOptions, out *FSGroupStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.FSGroupStrategyOptions))(in) + } + out.Type = FSGroupStrategyType(in.Type) + if in.Ranges != nil { + out.Ranges = make([]IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := convert_api_IDRange_To_v1_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func convert_api_SupplementalGroupsStrategyOptions_To_v1_SupplementalGroupsStrategyOptions(in *api.SupplementalGroupsStrategyOptions, out *SupplementalGroupsStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SupplementalGroupsStrategyOptions))(in) + } + out.Type = SupplementalGroupsStrategyType(in.Type) + if in.Ranges != nil { + out.Ranges = make([]IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := convert_api_IDRange_To_v1_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func convert_api_IDRange_To_v1_IDRange(in *api.IDRange, out *IDRange, s conversion.Scope) error { + out.Min = in.Min + out.Max = in.Max + + return nil +} + +func convert_v1_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions(in *FSGroupStrategyOptions, out *api.FSGroupStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*FSGroupStrategyOptions))(in) + } + out.Type = api.FSGroupStrategyType(in.Type) + if in.Ranges != nil { + out.Ranges = make([]api.IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := convert_v1_IDRange_To_api_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func convert_v1_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions(in *SupplementalGroupsStrategyOptions, out *api.SupplementalGroupsStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SupplementalGroupsStrategyOptions))(in) + } + out.Type = api.SupplementalGroupsStrategyType(in.Type) + if in.Ranges != nil { + out.Ranges = make([]api.IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := convert_v1_IDRange_To_api_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func convert_v1_IDRange_To_api_IDRange(in *IDRange, out *api.IDRange, s conversion.Scope) error { + out.Min = in.Min + out.Max = in.Max + return nil +} func init() { err := api.Scheme.AddGeneratedConversionFuncs( + convert_api_FSGroupStrategyOptions_To_v1_FSGroupStrategyOptions, + convert_api_SupplementalGroupsStrategyOptions_To_v1_SupplementalGroupsStrategyOptions, + convert_api_IDRange_To_v1_IDRange, + convert_v1_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions, + convert_v1_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions, + convert_v1_IDRange_To_api_IDRange, + autoconvert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource, autoconvert_api_Binding_To_v1_Binding, autoconvert_api_Capabilities_To_v1_Capabilities, @@ -6293,6 +6624,15 @@ func init() { autoconvert_v1_VolumeMount_To_api_VolumeMount, autoconvert_v1_VolumeSource_To_api_VolumeSource, autoconvert_v1_Volume_To_api_Volume, + + convert_api_RunAsUserStrategyOptions_To_v1_RunAsUserStrategyOptions, + convert_api_SELinuxContextStrategyOptions_To_v1_SELinuxContextStrategyOptions, + convert_api_SecurityContextConstraintsList_To_v1_SecurityContextConstraintsList, + convert_api_SecurityContextConstraints_To_v1_SecurityContextConstraints, + convert_v1_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions, + convert_v1_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions, + convert_v1_SecurityContextConstraintsList_To_api_SecurityContextConstraintsList, + convert_v1_SecurityContextConstraints_To_api_SecurityContextConstraints, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go index 87cbcf4b71c7..59bce1c1ca9b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go @@ -1898,6 +1898,42 @@ func deepCopy_v1_ResourceRequirements(in ResourceRequirements, out *ResourceRequ return nil } +func deepCopy_v1_RunAsUserStrategyOptions(in RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.UID != nil { + out.UID = new(int64) + *out.UID = *in.UID + } else { + out.UID = nil + } + if in.UIDRangeMin != nil { + out.UIDRangeMin = new(int64) + *out.UIDRangeMin = *in.UIDRangeMin + } else { + out.UIDRangeMin = nil + } + if in.UIDRangeMax != nil { + out.UIDRangeMax = new(int64) + *out.UIDRangeMax = *in.UIDRangeMax + } else { + out.UIDRangeMax = nil + } + return nil +} + +func deepCopy_v1_SELinuxContextStrategyOptions(in SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(SELinuxOptions) + if err := deepCopy_v1_SELinuxOptions(*in.SELinuxOptions, out.SELinuxOptions, c); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + return nil +} + func deepCopy_v1_SELinuxOptions(in SELinuxOptions, out *SELinuxOptions, c *conversion.Cloner) error { out.User = in.User out.Role = in.Role @@ -1906,6 +1942,42 @@ func deepCopy_v1_SELinuxOptions(in SELinuxOptions, out *SELinuxOptions, c *conve return nil } +func deepCopy_v1_SupplementalGroupsStrategyOptions(in SupplementalGroupsStrategyOptions, out *SupplementalGroupsStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.Ranges != nil { + out.Ranges = make([]IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := deepCopy_v1_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func deepCopy_v1_FSGroupStrategyOptions(in FSGroupStrategyOptions, out *FSGroupStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.Ranges != nil { + out.Ranges = make([]IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := deepCopy_v1_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func deepCopy_v1_IDRange(in IDRange, out *IDRange, c *conversion.Cloner) error { + out.Max = in.Max + out.Min = in.Min + return nil +} + func deepCopy_v1_Secret(in Secret, out *Secret, c *conversion.Cloner) error { if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err @@ -1987,6 +2059,78 @@ func deepCopy_v1_SecurityContext(in SecurityContext, out *SecurityContext, c *co return nil } +func deepCopy_v1_SecurityContextConstraints(in SecurityContextConstraints, out *SecurityContextConstraints, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + out.AllowPrivilegedContainer = in.AllowPrivilegedContainer + if in.AllowedCapabilities != nil { + out.AllowedCapabilities = make([]Capability, len(in.AllowedCapabilities)) + for i := range in.AllowedCapabilities { + out.AllowedCapabilities[i] = in.AllowedCapabilities[i] + } + } else { + out.AllowedCapabilities = nil + } + out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + out.AllowHostNetwork = in.AllowHostNetwork + out.AllowHostPorts = in.AllowHostPorts + out.AllowHostPID = in.AllowHostPID + out.AllowHostIPC = in.AllowHostIPC + if err := deepCopy_v1_SELinuxContextStrategyOptions(in.SELinuxContext, &out.SELinuxContext, c); err != nil { + return err + } + if err := deepCopy_v1_RunAsUserStrategyOptions(in.RunAsUser, &out.RunAsUser, c); err != nil { + return err + } + if err := deepCopy_v1_FSGroupStrategyOptions(in.FSGroup, &out.FSGroup, c); err != nil { + return err + } + if err := deepCopy_v1_SupplementalGroupsStrategyOptions(in.SupplementalGroups, &out.SupplementalGroups, c); err != nil { + return err + } + if in.Users != nil { + out.Users = make([]string, len(in.Users)) + for i := range in.Users { + out.Users[i] = in.Users[i] + } + } else { + out.Users = nil + } + if in.Groups != nil { + out.Groups = make([]string, len(in.Groups)) + for i := range in.Groups { + out.Groups[i] = in.Groups[i] + } + } else { + out.Groups = nil + } + return nil +} + +func deepCopy_v1_SecurityContextConstraintsList(in SecurityContextConstraintsList, out *SecurityContextConstraintsList, c *conversion.Cloner) error { + if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]SecurityContextConstraints, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1_SecurityContextConstraints(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + func deepCopy_v1_SerializedReference(in SerializedReference, out *SerializedReference, c *conversion.Cloner) error { if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err @@ -2355,12 +2499,14 @@ func init() { deepCopy_v1_ExecAction, deepCopy_v1_FCVolumeSource, deepCopy_v1_FlockerVolumeSource, + deepCopy_v1_FSGroupStrategyOptions, deepCopy_v1_GCEPersistentDiskVolumeSource, deepCopy_v1_GitRepoVolumeSource, deepCopy_v1_GlusterfsVolumeSource, deepCopy_v1_HTTPGetAction, deepCopy_v1_Handler, deepCopy_v1_HostPathVolumeSource, + deepCopy_v1_IDRange, deepCopy_v1_ISCSIVolumeSource, deepCopy_v1_Lifecycle, deepCopy_v1_LimitRange, @@ -2424,11 +2570,15 @@ func init() { deepCopy_v1_ResourceQuotaSpec, deepCopy_v1_ResourceQuotaStatus, deepCopy_v1_ResourceRequirements, + deepCopy_v1_RunAsUserStrategyOptions, + deepCopy_v1_SELinuxContextStrategyOptions, deepCopy_v1_SELinuxOptions, deepCopy_v1_Secret, deepCopy_v1_SecretList, deepCopy_v1_SecretVolumeSource, deepCopy_v1_SecurityContext, + deepCopy_v1_SecurityContextConstraints, + deepCopy_v1_SecurityContextConstraintsList, deepCopy_v1_SerializedReference, deepCopy_v1_Service, deepCopy_v1_ServiceAccount, @@ -2437,6 +2587,7 @@ func init() { deepCopy_v1_ServicePort, deepCopy_v1_ServiceSpec, deepCopy_v1_ServiceStatus, + deepCopy_v1_SupplementalGroupsStrategyOptions, deepCopy_v1_TCPSocketAction, deepCopy_v1_Volume, deepCopy_v1_VolumeMount, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/register.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/register.go index 9957c98bf730..e91f0f41af2d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/register.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/register.go @@ -82,6 +82,9 @@ func addKnownTypes() { &ComponentStatusList{}, &SerializedReference{}, &RangeAllocation{}, + + &SecurityContextConstraints{}, + &SecurityContextConstraintsList{}, ) // Add common types @@ -129,3 +132,6 @@ func (*ComponentStatus) IsAnAPIObject() {} func (*ComponentStatusList) IsAnAPIObject() {} func (*SerializedReference) IsAnAPIObject() {} func (*RangeAllocation) IsAnAPIObject() {} + +func (*SecurityContextConstraints) IsAnAPIObject() {} +func (*SecurityContextConstraintsList) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go index 13f4618b7b8d..196e721c943e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go @@ -2519,3 +2519,136 @@ type RangeAllocation struct { // Data is a bit array containing all allocated addresses in the previous segment. Data []byte `json:"data"` } + +// SecurityContextConstraints governs the ability to make requests that affect the SecurityContext +// that will be applied to a container. +type SecurityContextConstraints struct { + unversioned.TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` + + // AllowPrivilegedContainer determines if a container can request to be run as privileged. + AllowPrivilegedContainer bool `json:"allowPrivilegedContainer" description:"allow containers to run as privileged"` + // AllowedCapabilities is a list of capabilities that can be requested to add to the container. + AllowedCapabilities []Capability `json:"allowedCapabilities" description:"capabilities that are allowed to be added"` + // AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin + AllowHostDirVolumePlugin bool `json:"allowHostDirVolumePlugin" description:"allow the use of the host dir volume plugin"` + // AllowHostNetwork determines if the policy allows the use of HostNetwork in the pod spec. + AllowHostNetwork bool `json:"allowHostNetwork" description:"allow the use of the hostNetwork in the pod spec"` + // AllowHostPorts determines if the policy allows host ports in the containers. + AllowHostPorts bool `json:"allowHostPorts" description:"allow the use of the host ports in the containers"` + // AllowHostPID determines if the policy allows host pid in the containers. + AllowHostPID bool `json:"allowHostPID" description:"allow the use of the host pid in the containers"` + // AllowHostIPC determines if the policy allows host ipc in the containers. + AllowHostIPC bool `json:"allowHostIPC" description:"allow the use of the host ipc in the containers"` + // SELinuxContext is the strategy that will dictate what labels will be set in the SecurityContext. + SELinuxContext SELinuxContextStrategyOptions `json:"seLinuxContext,omitempty" description:"strategy used to generate SELinuxOptions"` + // RunAsUser is the strategy that will dictate what RunAsUser is used in the SecurityContext. + RunAsUser RunAsUserStrategyOptions `json:"runAsUser,omitempty" description:"strategy used to generate RunAsUser"` + // SupplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. + SupplementalGroups SupplementalGroupsStrategyOptions `json:"supplementalGroups,omitempty" description:"strategy used to generate supplemental groups"` + // FSGroup is the strategy that will dictate what fs group is used by the SecurityContext. + FSGroup FSGroupStrategyOptions `json:"fsGroup,omitempty" description:"strategy used to generate fsGroup"` + + // The users who have permissions to use this security context constraints + Users []string `json:"users,omitempty" description:"users allowed to use this SecurityContextConstraints"` + // The groups that have permission to use this security context constraints + Groups []string `json:"groups,omitempty" description:"groups allowed to use this SecurityContextConstraints"` +} + +// SELinuxContextStrategyOptions defines the strategy type and any options used to create the strategy. +type SELinuxContextStrategyOptions struct { + // Type is the strategy that will dictate what SELinux context is used in the SecurityContext. + Type SELinuxContextStrategyType `json:"type,omitempty" description:"strategy used to generate the SELinux context"` + // seLinuxOptions required to run as; required for MustRunAs + SELinuxOptions *SELinuxOptions `json:"seLinuxOptions,omitempty" description:"seLinuxOptions required to run as; required for MustRunAs"` +} + +// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. +type RunAsUserStrategyOptions struct { + // Type is the strategy that will dictate what RunAsUser is used in the SecurityContext. + Type RunAsUserStrategyType `json:"type,omitempty" description:"strategy used to generate RunAsUser"` + // UID is the user id that containers must run as. Required for the MustRunAs strategy if not using + // namespace/service account allocated uids. + UID *int64 `json:"uid,omitempty" description:"the uid to always run as; required for MustRunAs"` + // UIDRangeMin defines the min value for a strategy that allocates by range. + UIDRangeMin *int64 `json:"uidRangeMin,omitempty" description:"min value for range based allocators"` + // UIDRangeMax defines the max value for a strategy that allocates by range. + UIDRangeMax *int64 `json:"uidRangeMax,omitempty" description:"max value for range based allocators"` +} + +// FSGroupStrategyOptions defines the strategy type and options used to create the strategy. +type FSGroupStrategyOptions struct { + // Type is the strategy that will dictate what FSGroup is used in the SecurityContext. + Type FSGroupStrategyType `json:"type,omitempty" description:"strategy used to generate fsGroup"` + // Ranges are the allowed ranges of fs groups. If you would like to force a single + // fs group then supply a single range with the same start and end. + Ranges []IDRange `json:"ranges,omitempty" description:"ranges of allowable IDs for fsGroup"` +} + +// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. +type SupplementalGroupsStrategyOptions struct { + // Type is the strategy that will dictate what supplemental groups is used in the SecurityContext. + Type SupplementalGroupsStrategyType `json:"type,omitempty" description:"strategy used to generate supplemental groups"` + // Ranges are the allowed ranges of supplemental groups. If you would like to force a single + // supplemental group then supply a single range with the same start and end. + Ranges []IDRange `json:"ranges,omitempty" description:"ranges of allowable IDs for supplemental groups"` +} + +// IDRange provides a min/max of an allowed range of IDs. +// TODO: this could be reused for UIDs. +type IDRange struct { + // Min is the start of the range, inclusive. + Min int64 `json:"min,omitempty" description:"min value for the range"` + // Max is the end of the range, inclusive. + Max int64 `json:"max,omitempty" description:"min value for the range"` +} + +// SELinuxContextStrategyType denotes strategy types for generating SELinux options for a +// SecurityContext +type SELinuxContextStrategyType string + +// RunAsUserStrategyType denotes strategy types for generating RunAsUser values for a +// SecurityContext +type RunAsUserStrategyType string + +// SupplementalGroupsStrategyType denotes strategy types for determining valid supplemental +// groups for a SecurityContext. +type SupplementalGroupsStrategyType string + +// FSGroupStrategyType denotes strategy types for generating FSGroup values for a +// SecurityContext +type FSGroupStrategyType string + +const ( + // container must have SELinux labels of X applied. + SELinuxStrategyMustRunAs SELinuxContextStrategyType = "MustRunAs" + // container may make requests for any SELinux context labels. + SELinuxStrategyRunAsAny SELinuxContextStrategyType = "RunAsAny" + + // container must run as a particular uid. + RunAsUserStrategyMustRunAs RunAsUserStrategyType = "MustRunAs" + // container must run as a particular uid. + RunAsUserStrategyMustRunAsRange RunAsUserStrategyType = "MustRunAsRange" + // container must run as a non-root uid + RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategyType = "MustRunAsNonRoot" + // container may make requests for any uid. + RunAsUserStrategyRunAsAny RunAsUserStrategyType = "RunAsAny" + + // container must have FSGroup of X applied. + FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs" + // container may make requests for any FSGroup labels. + FSGroupStrategyRunAsAny FSGroupStrategyType = "RunAsAny" + + // container must run as a particular gid. + SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs" + // container may make requests for any gid. + SupplementalGroupsrStrategyRunAsAny SupplementalGroupsStrategyType = "RunAsAny" +) + +// SecurityContextConstraintsList is a list of SecurityContextConstraints objects +type SecurityContextConstraintsList struct { + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + + Items []SecurityContextConstraints `json:"items"` +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go index d48f7183a4bf..83f2129a9484 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go @@ -182,6 +182,14 @@ func ValidateEndpointsName(name string, prefix bool) (bool, string) { return NameIsDNSSubdomain(name, prefix) } +// ValidateSecurityContextConstraintsName can be used to check whether the given +// security context constraint name is valid. +// Prefix indicates this name will be used as part of generation, in which case +// trailing dashes are allowed. +func ValidateSecurityContextConstraintsName(name string, prefix bool) (bool, string) { + return NameIsDNSSubdomain(name, prefix) +} + // NameIsDNSSubdomain is a ValidateNameFunc for names that must be a DNS subdomain. func NameIsDNSSubdomain(name string, prefix bool) (bool, string) { if prefix { @@ -2008,3 +2016,42 @@ func ValidatePodLogOptions(opts *api.PodLogOptions) errs.ValidationErrorList { } return allErrs } + +func ValidateSecurityContextConstraints(scc *api.SecurityContextConstraints) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, ValidateObjectMeta(&scc.ObjectMeta, false, ValidateSecurityContextConstraintsName).Prefix("metadata")...) + + // ensure the user strat has a valid type + switch scc.RunAsUser.Type { + case api.RunAsUserStrategyMustRunAs, api.RunAsUserStrategyMustRunAsNonRoot, api.RunAsUserStrategyRunAsAny, api.RunAsUserStrategyMustRunAsRange: + //good types + default: + msg := fmt.Sprintf("invalid strategy type. Valid values are %s, %s, %s", api.RunAsUserStrategyMustRunAs, api.RunAsUserStrategyMustRunAsNonRoot, api.RunAsUserStrategyRunAsAny) + allErrs = append(allErrs, errs.NewFieldInvalid("runAsUser.type", scc.RunAsUser.Type, msg)) + } + + // if specified, uid cannot be negative + if scc.RunAsUser.UID != nil { + if *scc.RunAsUser.UID < 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("runAsUser.uid", *scc.RunAsUser.UID, "uid cannot be negative")) + } + } + + // ensure the selinux strat has a valid type + switch scc.SELinuxContext.Type { + case api.SELinuxStrategyMustRunAs, api.SELinuxStrategyRunAsAny: + //good types + default: + msg := fmt.Sprintf("invalid strategy type. Valid values are %s, %s", api.SELinuxStrategyMustRunAs, api.SELinuxStrategyRunAsAny) + allErrs = append(allErrs, errs.NewFieldInvalid("seLinuxContext.type", scc.RunAsUser.Type, msg)) + } + + return allErrs +} + +func ValidateSecurityContextConstraintsUpdate(old *api.SecurityContextConstraints, new *api.SecurityContextConstraints) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, ValidateObjectMetaUpdate(&old.ObjectMeta, &new.ObjectMeta).Prefix("metadata")...) + allErrs = append(allErrs, ValidateSecurityContextConstraints(new)...) + return allErrs +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go index 426a02aa4abf..d4e23221e18d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go @@ -4021,3 +4021,136 @@ func TestValidPodLogOptions(t *testing.T) { } } } + +func TestValidateSecurityContextConstraints(t *testing.T) { + var invalidUID int64 = -1 + errorCases := map[string]struct { + scc *api.SecurityContextConstraints + errorType fielderrors.ValidationErrorType + errorDetail string + }{ + "no user options": { + scc: &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{Name: "foo"}, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyMustRunAs, + }, + }, + errorType: errors.ValidationErrorTypeInvalid, + errorDetail: "invalid strategy type. Valid values are MustRunAs, MustRunAsNonRoot, RunAsAny", + }, + "no selinux options": { + scc: &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{Name: "foo"}, + RunAsUser: api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyMustRunAs, + }, + }, + errorType: errors.ValidationErrorTypeInvalid, + errorDetail: "invalid strategy type. Valid values are MustRunAs, RunAsAny", + }, + "invalid user strategy type": { + scc: &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{Name: "foo"}, + RunAsUser: api.RunAsUserStrategyOptions{ + Type: "invalid", + }, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyMustRunAs, + }, + }, + errorType: errors.ValidationErrorTypeInvalid, + errorDetail: "invalid strategy type. Valid values are MustRunAs, MustRunAsNonRoot, RunAsAny", + }, + "invalid selinux strategy type": { + scc: &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{Name: "foo"}, + RunAsUser: api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyMustRunAs, + }, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: "invalid", + }, + }, + errorType: errors.ValidationErrorTypeInvalid, + errorDetail: "invalid strategy type. Valid values are MustRunAs, RunAsAny", + }, + "invalid uid": { + scc: &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{Name: "foo"}, + RunAsUser: api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyMustRunAs, + UID: &invalidUID, + }, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyMustRunAs, + }, + }, + errorType: errors.ValidationErrorTypeInvalid, + errorDetail: "uid cannot be negative", + }, + "missing object meta name": { + scc: &api.SecurityContextConstraints{ + RunAsUser: api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyMustRunAs, + }, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyMustRunAs, + }, + }, + errorType: errors.ValidationErrorTypeRequired, + }, + } + + for k, v := range errorCases { + if errs := ValidateSecurityContextConstraints(v.scc); len(errs) == 0 || errs[0].(*errors.ValidationError).Type != v.errorType || errs[0].(*errors.ValidationError).Detail != v.errorDetail { + t.Errorf("Expected error type %s with detail %s for %s, got %v", v.errorType, v.errorDetail, k, errs) + } + } + + var validUID int64 = 1 + successCases := map[string]struct { + scc *api.SecurityContextConstraints + }{ + "must run as": { + scc: &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{Name: "foo"}, + RunAsUser: api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyMustRunAs, + UID: &validUID, + }, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyMustRunAs, + }, + }, + }, + "run as any": { + scc: &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{Name: "foo"}, + RunAsUser: api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyRunAsAny, + }, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyRunAsAny, + }, + }, + }, + "run as non-root (user only)": { + scc: &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{Name: "foo"}, + RunAsUser: api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyMustRunAsNonRoot, + }, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyRunAsAny, + }, + }, + }, + } + + for k, v := range successCases { + if errs := ValidateSecurityContextConstraints(v.scc); len(errs) != 0 { + t.Errorf("Expected success for %s, got %v", k, errs) + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client.go index ef23b692382a..868f8e3fa454 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/client.go @@ -52,6 +52,8 @@ type Interface interface { ComponentStatusesInterface SwaggerSchemaInterface Extensions() ExtensionsInterface + + SecurityContextConstraintsInterface } func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface { @@ -62,6 +64,10 @@ func (c *Client) Nodes() NodeInterface { return newNodes(c) } +func (c *Client) SecurityContextConstraints() SecurityContextConstraintInterface { + return newSecurityContextConstraints(c) +} + func (c *Client) Events(namespace string) EventInterface { return newEvents(c, namespace) } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints.go new file mode 100644 index 000000000000..fc81d7713ed8 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints.go @@ -0,0 +1,115 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/watch" +) + +type SecurityContextConstraintsInterface interface { + SecurityContextConstraints() SecurityContextConstraintInterface +} + +type SecurityContextConstraintInterface interface { + Get(name string) (result *api.SecurityContextConstraints, err error) + Create(scc *api.SecurityContextConstraints) (*api.SecurityContextConstraints, error) + List(label labels.Selector, field fields.Selector) (*api.SecurityContextConstraintsList, error) + Delete(name string) error + Update(*api.SecurityContextConstraints) (*api.SecurityContextConstraints, error) + Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) +} + +// securityContextConstraints implements SecurityContextConstraintInterface +type securityContextConstraints struct { + client *Client +} + +// newSecurityContextConstraints returns a securityContextConstraints object. +func newSecurityContextConstraints(c *Client) *securityContextConstraints { + return &securityContextConstraints{c} +} + +func (s *securityContextConstraints) Create(scc *api.SecurityContextConstraints) (*api.SecurityContextConstraints, error) { + result := &api.SecurityContextConstraints{} + err := s.client.Post(). + Resource("securityContextConstraints"). + Body(scc). + Do(). + Into(result) + + return result, err +} + +// List returns a list of SecurityContextConstraints matching the selectors. +func (s *securityContextConstraints) List(label labels.Selector, field fields.Selector) (*api.SecurityContextConstraintsList, error) { + result := &api.SecurityContextConstraintsList{} + + err := s.client.Get(). + Resource("securityContextConstraints"). + LabelsSelectorParam(label). + FieldsSelectorParam(field). + Do(). + Into(result) + + return result, err +} + +// Get returns the given SecurityContextConstraints, or an error. +func (s *securityContextConstraints) Get(name string) (*api.SecurityContextConstraints, error) { + result := &api.SecurityContextConstraints{} + err := s.client.Get(). + Resource("securityContextConstraints"). + Name(name). + Do(). + Into(result) + + return result, err +} + +// Watch starts watching for SecurityContextConstraints matching the given selectors. +func (s *securityContextConstraints) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { + return s.client.Get(). + Prefix("watch"). + Resource("securityContextConstraints"). + Param("resourceVersion", resourceVersion). + LabelsSelectorParam(label). + FieldsSelectorParam(field). + Watch() +} + +func (s *securityContextConstraints) Delete(name string) error { + return s.client.Delete(). + Resource("securityContextConstraints"). + Name(name). + Do(). + Error() +} + +func (s *securityContextConstraints) Update(scc *api.SecurityContextConstraints) (result *api.SecurityContextConstraints, err error) { + result = &api.SecurityContextConstraints{} + err = s.client.Put(). + Resource("securityContextConstraints"). + Name(scc.Name). + Body(scc). + Do(). + Into(result) + + return +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints_test.go new file mode 100644 index 000000000000..ae91b79381e1 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/securitycontextconstraints_test.go @@ -0,0 +1,137 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + + "net/url" +) + +func TestSecurityContextConstraintsCreate(t *testing.T) { + ns := api.NamespaceNone + scc := &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + }, + } + + c := &testClient{ + Request: testRequest{ + Method: "POST", + Path: testapi.Default.ResourcePath(getSCCResoureName(), ns, ""), + Query: buildQueryValues(nil), + Body: scc, + }, + Response: Response{StatusCode: 200, Body: scc}, + } + + response, err := c.Setup(t).SecurityContextConstraints().Create(scc) + c.Validate(t, response, err) +} + +func TestSecurityContextConstraintsGet(t *testing.T) { + ns := api.NamespaceNone + scc := &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + }, + } + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: testapi.Default.ResourcePath(getSCCResoureName(), ns, "abc"), + Query: buildQueryValues(nil), + Body: nil, + }, + Response: Response{StatusCode: 200, Body: scc}, + } + + response, err := c.Setup(t).SecurityContextConstraints().Get("abc") + c.Validate(t, response, err) +} + +func TestSecurityContextConstraintsList(t *testing.T) { + ns := api.NamespaceNone + sccList := &api.SecurityContextConstraintsList{ + Items: []api.SecurityContextConstraints{ + { + ObjectMeta: api.ObjectMeta{ + Name: "abc", + }, + }, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: testapi.Default.ResourcePath(getSCCResoureName(), ns, ""), + Query: buildQueryValues(nil), + Body: nil, + }, + Response: Response{StatusCode: 200, Body: sccList}, + } + response, err := c.Setup(t).SecurityContextConstraints().List(labels.Everything(), fields.Everything()) + c.Validate(t, response, err) +} + +func TestSecurityContextConstraintsUpdate(t *testing.T) { + ns := api.NamespaceNone + scc := &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + ResourceVersion: "1", + }, + } + c := &testClient{ + Request: testRequest{Method: "PUT", Path: testapi.Default.ResourcePath(getSCCResoureName(), ns, "abc"), Query: buildQueryValues(nil)}, + Response: Response{StatusCode: 200, Body: scc}, + } + response, err := c.Setup(t).SecurityContextConstraints().Update(scc) + c.Validate(t, response, err) +} + +func TestSecurityContextConstraintsDelete(t *testing.T) { + ns := api.NamespaceNone + c := &testClient{ + Request: testRequest{Method: "DELETE", Path: testapi.Default.ResourcePath(getSCCResoureName(), ns, "foo"), Query: buildQueryValues(nil)}, + Response: Response{StatusCode: 200}, + } + err := c.Setup(t).SecurityContextConstraints().Delete("foo") + c.Validate(t, nil, err) +} + +func TestSecurityContextConstraintsWatch(t *testing.T) { + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: "/api/" + testapi.Default.Version() + "/watch/" + getSCCResoureName(), + Query: url.Values{"resourceVersion": []string{}}}, + Response: Response{StatusCode: 200}, + } + _, err := c.Setup(t).SecurityContextConstraints().Watch(labels.Everything(), fields.Everything(), "") + c.Validate(t, nil, err) +} + +func getSCCResoureName() string { + return "securitycontextconstraints" +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_securitycontextconstraints.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_securitycontextconstraints.go new file mode 100644 index 000000000000..d7e13ef1f5a6 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/fake_securitycontextconstraints.go @@ -0,0 +1,61 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 testclient + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/watch" +) + +// FakeSecurityContextConstraints implements SecurityContextConstraintInterface. Meant to be +// embedded into a struct to get a default implementation. This makes faking out just +// the method you want to test easier. +type FakeSecurityContextConstraints struct { + Fake *Fake + Namespace string +} + +func (c *FakeSecurityContextConstraints) List(label labels.Selector, field fields.Selector) (*api.SecurityContextConstraintsList, error) { + obj, err := c.Fake.Invokes(NewListAction("securitycontextconstraints", c.Namespace, label, field), &api.SecurityContextConstraintsList{}) + return obj.(*api.SecurityContextConstraintsList), err +} + +func (c *FakeSecurityContextConstraints) Get(name string) (*api.SecurityContextConstraints, error) { + obj, err := c.Fake.Invokes(NewGetAction("securitycontextconstraints", c.Namespace, name), &api.SecurityContextConstraints{}) + return obj.(*api.SecurityContextConstraints), err +} + +func (c *FakeSecurityContextConstraints) Create(scc *api.SecurityContextConstraints) (*api.SecurityContextConstraints, error) { + obj, err := c.Fake.Invokes(NewCreateAction("securitycontextconstraints", c.Namespace, scc), &api.SecurityContextConstraints{}) + return obj.(*api.SecurityContextConstraints), err +} + +func (c *FakeSecurityContextConstraints) Update(scc *api.SecurityContextConstraints) (*api.SecurityContextConstraints, error) { + obj, err := c.Fake.Invokes(NewUpdateAction("securitycontextconstraints", c.Namespace, scc), &api.SecurityContextConstraints{}) + return obj.(*api.SecurityContextConstraints), err +} + +func (c *FakeSecurityContextConstraints) Delete(name string) error { + _, err := c.Fake.Invokes(NewDeleteAction("securitycontextconstraints", c.Namespace, name), &api.SecurityContextConstraints{}) + return err +} + +func (c *FakeSecurityContextConstraints) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { + return c.Fake.InvokesWatch(NewWatchAction("securitycontextconstraints", c.Namespace, label, field, resourceVersion)) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient.go index fe0e2fdcd75f..d2b3c9e2a182 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/testclient/testclient.go @@ -228,6 +228,10 @@ func (c *Fake) Nodes() client.NodeInterface { return &FakeNodes{Fake: c} } +func (c *Fake) SecurityContextConstraints() client.SecurityContextConstraintInterface { + return &FakeSecurityContextConstraints{Fake: c} +} + func (c *Fake) Events(namespace string) client.EventInterface { return &FakeEvents{Fake: c, Namespace: namespace} } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/kubectl.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/kubectl.go index 691866ec6687..28575439fde2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/kubectl.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/kubectl.go @@ -109,6 +109,8 @@ func expandResourceShortcut(resource string) string { "ds": "daemonsets", "svc": "services", "ing": "ingress", + + "scc": "securityContextConstraints", } if expanded, ok := shortForms[resource]; ok { return expanded diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go index 3937cd9cf7f4..b9d69d30fa68 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go @@ -407,6 +407,7 @@ var thirdPartyResourceColumns = []string{"NAME", "DESCRIPTION", "VERSION(S)"} var horizontalPodAutoscalerColumns = []string{"NAME", "REFERENCE", "TARGET", "CURRENT", "MINPODS", "MAXPODS", "AGE"} var withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print cluster name too. var deploymentColumns = []string{"NAME", "UPDATEDREPLICAS", "AGE"} +var securityContextConstraintsColumns = []string{"NAME", "PRIV", "CAPS", "HOSTDIR", "SELINUX", "RUNASUSER"} // addDefaultHandlers adds print handlers for default Kubernetes types. func (h *HumanReadablePrinter) addDefaultHandlers() { @@ -452,6 +453,8 @@ func (h *HumanReadablePrinter) addDefaultHandlers() { h.Handler(deploymentColumns, printDeploymentList) h.Handler(horizontalPodAutoscalerColumns, printHorizontalPodAutoscaler) h.Handler(horizontalPodAutoscalerColumns, printHorizontalPodAutoscalerList) + h.Handler(securityContextConstraintsColumns, printSecurityContextConstraints) + h.Handler(securityContextConstraintsColumns, printSecurityContextConstraintsList) } func (h *HumanReadablePrinter) unknown(data []byte, w io.Writer) error { @@ -1424,6 +1427,23 @@ func printHorizontalPodAutoscalerList(list *extensions.HorizontalPodAutoscalerLi return nil } +func printSecurityContextConstraints(item *api.SecurityContextConstraints, w io.Writer, withNamespace, wide, showAll bool, columnLabels []string) error { + _, err := fmt.Fprintf(w, "%s\t%t\t%v\t%t\t%s\t%s\n", item.Name, item.AllowPrivilegedContainer, + item.AllowedCapabilities, item.AllowHostDirVolumePlugin, item.SELinuxContext.Type, + item.RunAsUser.Type) + return err +} + +func printSecurityContextConstraintsList(list *api.SecurityContextConstraintsList, w io.Writer, withNamespace, wide, showAll bool, columnLabels []string) error { + for _, item := range list.Items { + if err := printSecurityContextConstraints(&item, w, withNamespace, wide, showAll, columnLabels); err != nil { + return err + } + } + + return nil +} + func appendLabels(itemLabels map[string]string, columnLabels []string) string { var buffer bytes.Buffer diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go index 32a04929b63d..a969ea84eb12 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go @@ -66,6 +66,7 @@ import ( podtemplateetcd "k8s.io/kubernetes/pkg/registry/podtemplate/etcd" resourcequotaetcd "k8s.io/kubernetes/pkg/registry/resourcequota/etcd" secretetcd "k8s.io/kubernetes/pkg/registry/secret/etcd" + sccetcd "k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd" "k8s.io/kubernetes/pkg/registry/service" etcdallocator "k8s.io/kubernetes/pkg/registry/service/allocator/etcd" serviceetcd "k8s.io/kubernetes/pkg/registry/service/etcd" @@ -550,6 +551,8 @@ func (m *Master) init(c *Config) { endpointsStorage := endpointsetcd.NewREST(dbClient("endpoints"), c.EnableWatchCache) m.endpointRegistry = endpoint.NewRegistry(endpointsStorage) + securityContextConstraintsStorage := sccetcd.NewStorage(dbClient("securityContextConstraints")) + nodeStorage, nodeStatusStorage := nodeetcd.NewREST(dbClient("nodes"), c.EnableWatchCache, c.KubeletClient, m.proxyTransport) m.nodeRegistry = node.NewRegistry(nodeStorage) @@ -606,6 +609,7 @@ func (m *Master) init(c *Config) { "namespaces/finalize": namespaceFinalizeStorage, "secrets": secretStorage, "serviceAccounts": serviceAccountStorage, + "securityContextConstraints": securityContextConstraintsStorage, "persistentVolumes": persistentVolumeStorage, "persistentVolumes/status": persistentVolumeStatusStorage, "persistentVolumeClaims": persistentVolumeClaimStorage, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/doc.go new file mode 100644 index 000000000000..1b5bf6ac7962 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 securitycontextconstraints provides Registry interface and its REST +// implementation for storing SecurityContextConstraints api objects. +package securitycontextconstraints diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd.go new file mode 100644 index 000000000000..fa66a528a022 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd.go @@ -0,0 +1,64 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 etcd + +import ( + "path" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/registry/generic" + etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd" + "k8s.io/kubernetes/pkg/registry/securitycontextconstraints" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/storage" +) + +// REST implements a RESTStorage for security context constraints against etcd +type REST struct { + *etcdgeneric.Etcd +} + +const Prefix = "/securitycontextconstraints" + +// NewStorage returns a RESTStorage object that will work against security context constraints objects. +func NewStorage(s storage.Interface) *REST { + store := &etcdgeneric.Etcd{ + NewFunc: func() runtime.Object { return &api.SecurityContextConstraints{} }, + NewListFunc: func() runtime.Object { return &api.SecurityContextConstraintsList{} }, + KeyRootFunc: func(ctx api.Context) string { + return Prefix + }, + KeyFunc: func(ctx api.Context, name string) (string, error) { + return path.Join(Prefix, name), nil + }, + ObjectNameFunc: func(obj runtime.Object) (string, error) { + return obj.(*api.SecurityContextConstraints).Name, nil + }, + PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { + return securitycontextconstraints.Matcher(label, field) + }, + EndpointName: "securitycontextconstraints", + + CreateStrategy: securitycontextconstraints.Strategy, + UpdateStrategy: securitycontextconstraints.Strategy, + ReturnDeletedObject: true, + Storage: s, + } + return &REST{store} +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd_test.go new file mode 100644 index 000000000000..75c433c84ab9 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/etcd/etcd_test.go @@ -0,0 +1,74 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 etcd + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/registry/registrytest" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/tools" +) + +func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { + etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "") + return NewStorage(etcdStorage), fakeClient +} + +func validNewSecurityContextConstraints(name string) *api.SecurityContextConstraints { + return &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{ + Name: name, + }, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyRunAsAny, + }, + RunAsUser: api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyRunAsAny, + }, + } +} + +func TestCreate(t *testing.T) { + storage, fakeClient := newStorage(t) + test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope() + scc := validNewSecurityContextConstraints("foo") + scc.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"} + test.TestCreate( + // valid + scc, + // invalid + &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{Name: "name with spaces"}, + }, + ) +} + +func TestUpdate(t *testing.T) { + storage, fakeEtcdClient := newStorage(t) + test := registrytest.New(t, fakeEtcdClient, storage.Etcd).ClusterScope() + test.TestUpdate( + validNewSecurityContextConstraints("foo"), + // updateFunc + func(obj runtime.Object) runtime.Object { + object := obj.(*api.SecurityContextConstraints) + object.AllowPrivilegedContainer = true + return object + }, + ) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/registry.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/registry.go new file mode 100644 index 000000000000..9e273657bb16 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/registry.go @@ -0,0 +1,87 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 securitycontextconstraints + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/watch" +) + +// Registry is an interface implemented by things that know how to store SecurityContextConstraints objects. +type Registry interface { + // ListSecurityContextConstraints obtains a list of SecurityContextConstraints having labels which match selector. + ListSecurityContextConstraints(ctx api.Context, selector labels.Selector) (*api.SecurityContextConstraintsList, error) + // Watch for new/changed/deleted SecurityContextConstraints + WatchSecurityContextConstraints(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) + // Get a specific SecurityContextConstraints + GetSecurityContextConstraint(ctx api.Context, name string) (*api.SecurityContextConstraints, error) + // Create a SecurityContextConstraints based on a specification. + CreateSecurityContextConstraint(ctx api.Context, scc *api.SecurityContextConstraints) error + // Update an existing SecurityContextConstraints + UpdateSecurityContextConstraint(ctx api.Context, scc *api.SecurityContextConstraints) error + // Delete an existing SecurityContextConstraints + DeleteSecurityContextConstraint(ctx api.Context, name 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) ListSecurityContextConstraints(ctx api.Context, label labels.Selector) (*api.SecurityContextConstraintsList, error) { + obj, err := s.List(ctx, label, fields.Everything()) + if err != nil { + return nil, err + } + return obj.(*api.SecurityContextConstraintsList), nil +} + +func (s *storage) WatchSecurityContextConstraints(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { + return s.Watch(ctx, label, field, resourceVersion) +} + +func (s *storage) GetSecurityContextConstraint(ctx api.Context, name string) (*api.SecurityContextConstraints, error) { + obj, err := s.Get(ctx, name) + if err != nil { + return nil, err + } + return obj.(*api.SecurityContextConstraints), nil +} + +func (s *storage) CreateSecurityContextConstraint(ctx api.Context, scc *api.SecurityContextConstraints) error { + _, err := s.Create(ctx, scc) + return err +} + +func (s *storage) UpdateSecurityContextConstraint(ctx api.Context, scc *api.SecurityContextConstraints) error { + _, _, err := s.Update(ctx, scc) + return err +} + +func (s *storage) DeleteSecurityContextConstraint(ctx api.Context, name string) error { + _, err := s.Delete(ctx, name, nil) + return err +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/strategy.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/strategy.go new file mode 100644 index 000000000000..36103a80bb5a --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/securitycontextconstraints/strategy.go @@ -0,0 +1,88 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 securitycontextconstraints + +import ( + "fmt" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/validation" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/registry/generic" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +// strategy implements behavior for SecurityContextConstraints objects +type strategy struct { + runtime.ObjectTyper + api.NameGenerator +} + +// Strategy is the default logic that applies when creating and updating ServiceAccount +// objects via the REST API. +var Strategy = strategy{api.Scheme, api.SimpleNameGenerator} + +var _ = rest.RESTCreateStrategy(Strategy) + +var _ = rest.RESTUpdateStrategy(Strategy) + +func (strategy) NamespaceScoped() bool { + return false +} + +func (strategy) AllowCreateOnUpdate() bool { + return false +} + +func (strategy) AllowUnconditionalUpdate() bool { + return true +} + +func (strategy) PrepareForCreate(obj runtime.Object) { +} + +func (strategy) PrepareForUpdate(obj, old runtime.Object) { +} + +func (strategy) Validate(ctx api.Context, obj runtime.Object) fielderrors.ValidationErrorList { + return validation.ValidateSecurityContextConstraints(obj.(*api.SecurityContextConstraints)) +} + +func (strategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList { + return validation.ValidateSecurityContextConstraintsUpdate(old.(*api.SecurityContextConstraints), obj.(*api.SecurityContextConstraints)) +} + +// Matcher returns a generic matcher for a given label and field selector. +func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { + return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { + scc, ok := obj.(*api.SecurityContextConstraints) + if !ok { + return false, fmt.Errorf("not a securitycontextconstraint") + } + fields := SelectableFields(scc) + return label.Matches(labels.Set(scc.Labels)) && field.Matches(fields), nil + }) +} + +// SelectableFields returns a label set that represents the object +func SelectableFields(obj *api.SecurityContextConstraints) labels.Set { + return labels.Set{ + "metadata.name": obj.Name, + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/bitmap.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/bitmap.go index e90f396a6027..03e0116caee7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/bitmap.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/registry/service/allocator/bitmap.go @@ -79,6 +79,10 @@ func NewContiguousAllocationMap(max int, rangeSpec string) *AllocationBitmap { return &a } +func NewContiguousAllocationInterface(max int, rangeSpec string) Interface { + return NewContiguousAllocationMap(max, rangeSpec) +} + // Allocate attempts to reserve the provided item. // Returns true if it was allocated, false if it was already in use func (r *AllocationBitmap) Allocate(offset int) (bool, error) { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go new file mode 100644 index 000000000000..0410a3328fce --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go @@ -0,0 +1,205 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 securitycontextconstraints + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/securitycontextconstraints/selinux" + "k8s.io/kubernetes/pkg/securitycontextconstraints/user" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +// simpleProvider is the default implementation of SecurityContextConstraintsProvider +type simpleProvider struct { + scc *api.SecurityContextConstraints + runAsUserStrategy user.RunAsUserSecurityContextConstraintsStrategy + seLinuxStrategy selinux.SELinuxSecurityContextConstraintsStrategy +} + +// ensure we implement the interface correctly. +var _ SecurityContextConstraintsProvider = &simpleProvider{} + +// NewSimpleProvider creates a new SecurityContextConstraintsProvider instance. +func NewSimpleProvider(scc *api.SecurityContextConstraints) (SecurityContextConstraintsProvider, error) { + if scc == nil { + return nil, fmt.Errorf("NewSimpleProvider requires a SecurityContextConstraints") + } + + var userStrat user.RunAsUserSecurityContextConstraintsStrategy = nil + var err error = nil + switch scc.RunAsUser.Type { + case api.RunAsUserStrategyMustRunAs: + userStrat, err = user.NewMustRunAs(&scc.RunAsUser) + case api.RunAsUserStrategyMustRunAsRange: + userStrat, err = user.NewMustRunAsRange(&scc.RunAsUser) + case api.RunAsUserStrategyMustRunAsNonRoot: + userStrat, err = user.NewRunAsNonRoot(&scc.RunAsUser) + case api.RunAsUserStrategyRunAsAny: + userStrat, err = user.NewRunAsAny(&scc.RunAsUser) + default: + err = fmt.Errorf("Unrecognized RunAsUser strategy type %s", scc.RunAsUser.Type) + } + if err != nil { + return nil, err + } + + var seLinuxStrat selinux.SELinuxSecurityContextConstraintsStrategy = nil + err = nil + switch scc.SELinuxContext.Type { + case api.SELinuxStrategyMustRunAs: + seLinuxStrat, err = selinux.NewMustRunAs(&scc.SELinuxContext) + case api.SELinuxStrategyRunAsAny: + seLinuxStrat, err = selinux.NewRunAsAny(&scc.SELinuxContext) + default: + err = fmt.Errorf("Unrecognized SELinuxContext strategy type %s", scc.SELinuxContext.Type) + } + if err != nil { + return nil, err + } + + return &simpleProvider{ + scc: scc, + runAsUserStrategy: userStrat, + seLinuxStrategy: seLinuxStrat, + }, nil +} + +// Create a SecurityContext based on the given constraints. If a setting is already set on the +// container's security context then it will not be changed. Validation should be used after +// the context is created to ensure it complies with the required restrictions. +// +// NOTE: this method works on a copy of the SC of the container. It is up to the caller to apply +// the SC if validation passes. +func (s *simpleProvider) CreateSecurityContext(pod *api.Pod, container *api.Container) (*api.SecurityContext, error) { + var sc *api.SecurityContext = nil + if container.SecurityContext != nil { + // work with a copy of the original + copy := *container.SecurityContext + sc = © + } else { + sc = &api.SecurityContext{} + } + if sc.RunAsUser == nil { + uid, err := s.runAsUserStrategy.Generate(pod, container) + if err != nil { + return nil, err + } + sc.RunAsUser = uid + } + + if sc.SELinuxOptions == nil { + seLinux, err := s.seLinuxStrategy.Generate(pod, container) + if err != nil { + return nil, err + } + sc.SELinuxOptions = seLinux + } + + if sc.Privileged == nil { + priv := false + sc.Privileged = &priv + } + + // if we're using the non-root strategy set the marker that this container should not be + // run as root which will signal to the kubelet to do a final check either on the runAsUser + // or, if runAsUser is not set, the image + if s.scc.RunAsUser.Type == api.RunAsUserStrategyMustRunAsNonRoot { + sc.RunAsNonRoot = true + } + + // No need to touch capabilities, they will validate or not. + return sc, nil +} + +// Ensure a container's SecurityContext is in compliance with the given constraints +func (s *simpleProvider) ValidateSecurityContext(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { + allErrs := fielderrors.ValidationErrorList{} + + if container.SecurityContext == nil { + allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext", container.SecurityContext, "No security context is set")) + return allErrs + } + + sc := container.SecurityContext + allErrs = append(allErrs, s.runAsUserStrategy.Validate(pod, container)...) + allErrs = append(allErrs, s.seLinuxStrategy.Validate(pod, container)...) + + if !s.scc.AllowPrivilegedContainer && *sc.Privileged { + allErrs = append(allErrs, fielderrors.NewFieldInvalid("privileged", *sc.Privileged, "Privileged containers are not allowed")) + } + + if sc.Capabilities != nil && len(sc.Capabilities.Add) > 0 { + for _, cap := range sc.Capabilities.Add { + found := false + for _, allowedCap := range s.scc.AllowedCapabilities { + if cap == allowedCap { + found = true + break + } + } + if !found { + allErrs = append(allErrs, fielderrors.NewFieldInvalid("capabilities.add", cap, "Capability is not allowed to be added")) + } + } + } + + if !s.scc.AllowHostDirVolumePlugin { + for _, v := range pod.Spec.Volumes { + if v.HostPath != nil { + allErrs = append(allErrs, fielderrors.NewFieldInvalid("VolumeMounts", v.Name, "Host Volumes are not allowed to be used")) + } + } + } + + if !s.scc.AllowHostNetwork && pod.Spec.SecurityContext.HostNetwork { + allErrs = append(allErrs, fielderrors.NewFieldInvalid("hostNetwork", pod.Spec.SecurityContext.HostNetwork, "Host network is not allowed to be used")) + } + + if !s.scc.AllowHostPorts { + for idx, c := range pod.Spec.Containers { + allErrs = append(allErrs, s.hasHostPort(&c).Prefix(fmt.Sprintf("containers.%d", idx))...) + } + } + + if !s.scc.AllowHostPID && pod.Spec.SecurityContext.HostPID { + allErrs = append(allErrs, fielderrors.NewFieldInvalid("hostPID", pod.Spec.SecurityContext.HostPID, "Host PID is not allowed to be used")) + } + + if !s.scc.AllowHostIPC && pod.Spec.SecurityContext.HostIPC { + allErrs = append(allErrs, fielderrors.NewFieldInvalid("hostIPC", pod.Spec.SecurityContext.HostIPC, "Host IPC is not allowed to be used")) + } + + return allErrs +} + +// hasHostPort checks the port definitions on the container for HostPort > 0. +func (s *simpleProvider) hasHostPort(container *api.Container) fielderrors.ValidationErrorList { + allErrs := fielderrors.ValidationErrorList{} + for _, cp := range container.Ports { + if cp.HostPort > 0 { + allErrs = append(allErrs, fielderrors.NewFieldInvalid("hostPort", cp.HostPort, "Host ports are not allowed to be used")) + } + } + return allErrs +} + +// Get the name of the SCC that this provider was initialized with. +func (s *simpleProvider) GetSCCName() string { + return s.scc.Name +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go new file mode 100644 index 000000000000..5fb835904334 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go @@ -0,0 +1,395 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 securitycontextconstraints + +import ( + "reflect" + "strings" + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util" +) + +func TestCreateSecurityContextNonmutating(t *testing.T) { + // Create a pod with a security context that needs filling in + createPod := func() *api.Pod { + return &api.Pod{ + Spec: api.PodSpec{ + Containers: []api.Container{{ + SecurityContext: &api.SecurityContext{}, + }}, + }, + } + } + + // Create an SCC with strategies that will populate a blank security context + createSCC := func() *api.SecurityContextConstraints { + var uid int64 = 1 + return &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{ + Name: "scc-sa", + }, + RunAsUser: api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyMustRunAs, + UID: &uid, + }, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyMustRunAs, + SELinuxOptions: &api.SELinuxOptions{User: "you"}, + }, + } + } + + pod := createPod() + scc := createSCC() + + provider, err := NewSimpleProvider(scc) + if err != nil { + t.Fatal("unable to create provider %v", err) + } + sc, err := provider.CreateSecurityContext(pod, &pod.Spec.Containers[0]) + if err != nil { + t.Fatal("unable to create provider %v", err) + } + + // The generated security context should have filled in missing options, so they should differ + if reflect.DeepEqual(sc, &pod.Spec.Containers[0].SecurityContext) { + t.Error("expected created security context to be different than container's, but they were identical") + } + + // Creating the provider or the security context should not have mutated the scc or pod + if !reflect.DeepEqual(createPod(), pod) { + diff := util.ObjectDiff(createPod(), pod) + t.Errorf("pod was mutated by CreateSecurityContext. diff:\n%s", diff) + } + if !reflect.DeepEqual(createSCC(), scc) { + t.Error("different") + } +} + +func TestValidateFailures(t *testing.T) { + defaultSCC := func() *api.SecurityContextConstraints { + return &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{ + Name: "scc-sa", + }, + RunAsUser: api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyRunAsAny, + }, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyRunAsAny, + }, + } + } + + var notPriv bool = false + defaultPod := func() *api.Pod { + return &api.Pod{ + Spec: api.PodSpec{ + SecurityContext: &api.PodSecurityContext{}, + Containers: []api.Container{ + { + SecurityContext: &api.SecurityContext{ + // expected to be set by defaulting mechanisms + Privileged: ¬Priv, + // fill in the rest for test cases + }, + }, + }, + }, + } + } + + // fail user strat + failUserSCC := defaultSCC() + var uid int64 = 999 + var badUID int64 = 1 + failUserSCC.RunAsUser = api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyMustRunAs, + UID: &uid, + } + failUserPod := defaultPod() + failUserPod.Spec.Containers[0].SecurityContext.RunAsUser = &badUID + + // fail selinux strat + failSELinuxSCC := defaultSCC() + failSELinuxSCC.SELinuxContext = api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyMustRunAs, + SELinuxOptions: &api.SELinuxOptions{ + Level: "foo", + }, + } + failSELinuxPod := defaultPod() + failSELinuxPod.Spec.Containers[0].SecurityContext.SELinuxOptions = &api.SELinuxOptions{ + Level: "bar", + } + + failPrivPod := defaultPod() + var priv bool = true + failPrivPod.Spec.Containers[0].SecurityContext.Privileged = &priv + + failCapsPod := defaultPod() + failCapsPod.Spec.Containers[0].SecurityContext.Capabilities = &api.Capabilities{ + Add: []api.Capability{"foo"}, + } + + failHostDirPod := defaultPod() + failHostDirPod.Spec.Volumes = []api.Volume{ + { + Name: "bad volume", + VolumeSource: api.VolumeSource{ + HostPath: &api.HostPathVolumeSource{}, + }, + }, + } + + failHostNetworkPod := defaultPod() + failHostNetworkPod.Spec.SecurityContext.HostNetwork = true + + failHostPIDPod := defaultPod() + failHostPIDPod.Spec.SecurityContext.HostPID = true + + failHostIPCPod := defaultPod() + failHostIPCPod.Spec.SecurityContext.HostIPC = true + + failHostPortPod := defaultPod() + failHostPortPod.Spec.Containers[0].Ports = []api.ContainerPort{{HostPort: 1}} + + errorCases := map[string]struct { + pod *api.Pod + scc *api.SecurityContextConstraints + expectedError string + }{ + "failUserSCC": { + pod: failUserPod, + scc: failUserSCC, + expectedError: "does not match required UID", + }, + "failSELinuxSCC": { + pod: failSELinuxPod, + scc: failSELinuxSCC, + expectedError: "does not match required level", + }, + "failPrivSCC": { + pod: failPrivPod, + scc: defaultSCC(), + expectedError: "Privileged containers are not allowed", + }, + "failCapsSCC": { + pod: failCapsPod, + scc: defaultSCC(), + expectedError: "Capability is not allowed to be added", + }, + "failHostDirSCC": { + pod: failHostDirPod, + scc: defaultSCC(), + expectedError: "Host Volumes are not allowed to be used", + }, + "failHostNetworkSCC": { + pod: failHostNetworkPod, + scc: defaultSCC(), + expectedError: "Host network is not allowed to be used", + }, + "failHostPortSCC": { + pod: failHostPortPod, + scc: defaultSCC(), + expectedError: "Host ports are not allowed to be used", + }, + "failHostPIDSCC": { + pod: failHostPIDPod, + scc: defaultSCC(), + expectedError: "Host PID is not allowed to be used", + }, + "failHostIPCSCC": { + pod: failHostIPCPod, + scc: defaultSCC(), + expectedError: "Host IPC is not allowed to be used", + }, + } + + for k, v := range errorCases { + provider, err := NewSimpleProvider(v.scc) + if err != nil { + t.Fatal("unable to create provider %v", err) + } + errs := provider.ValidateSecurityContext(v.pod, &v.pod.Spec.Containers[0]) + if len(errs) == 0 { + t.Errorf("%s expected validation failure but did not receive errors", k) + continue + } + if !strings.Contains(errs[0].Error(), v.expectedError) { + t.Errorf("%s received unexpected error %v", k, errs) + } + } +} + +func TestValidateSuccess(t *testing.T) { + defaultSCC := func() *api.SecurityContextConstraints { + return &api.SecurityContextConstraints{ + ObjectMeta: api.ObjectMeta{ + Name: "scc-sa", + }, + RunAsUser: api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyRunAsAny, + }, + SELinuxContext: api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyRunAsAny, + }, + } + } + + var notPriv bool = false + defaultPod := func() *api.Pod { + return &api.Pod{ + Spec: api.PodSpec{ + SecurityContext: &api.PodSecurityContext{}, + Containers: []api.Container{ + { + SecurityContext: &api.SecurityContext{ + // expected to be set by defaulting mechanisms + Privileged: ¬Priv, + // fill in the rest for test cases + }, + }, + }, + }, + } + } + + // fail user strat + userSCC := defaultSCC() + var uid int64 = 999 + userSCC.RunAsUser = api.RunAsUserStrategyOptions{ + Type: api.RunAsUserStrategyMustRunAs, + UID: &uid, + } + userPod := defaultPod() + userPod.Spec.Containers[0].SecurityContext.RunAsUser = &uid + + // fail selinux strat + seLinuxSCC := defaultSCC() + seLinuxSCC.SELinuxContext = api.SELinuxContextStrategyOptions{ + Type: api.SELinuxStrategyMustRunAs, + SELinuxOptions: &api.SELinuxOptions{ + Level: "foo", + }, + } + seLinuxPod := defaultPod() + seLinuxPod.Spec.Containers[0].SecurityContext.SELinuxOptions = &api.SELinuxOptions{ + Level: "foo", + } + + privSCC := defaultSCC() + privSCC.AllowPrivilegedContainer = true + privPod := defaultPod() + var priv bool = true + privPod.Spec.Containers[0].SecurityContext.Privileged = &priv + + capsSCC := defaultSCC() + capsSCC.AllowedCapabilities = []api.Capability{"foo"} + capsPod := defaultPod() + capsPod.Spec.Containers[0].SecurityContext.Capabilities = &api.Capabilities{ + Add: []api.Capability{"foo"}, + } + + hostDirSCC := defaultSCC() + hostDirSCC.AllowHostDirVolumePlugin = true + hostDirPod := defaultPod() + hostDirPod.Spec.Volumes = []api.Volume{ + { + Name: "bad volume", + VolumeSource: api.VolumeSource{ + HostPath: &api.HostPathVolumeSource{}, + }, + }, + } + + hostNetworkSCC := defaultSCC() + hostNetworkSCC.AllowHostNetwork = true + hostNetworkPod := defaultPod() + hostNetworkPod.Spec.SecurityContext.HostNetwork = true + + hostPIDSCC := defaultSCC() + hostPIDSCC.AllowHostPID = true + hostPIDPod := defaultPod() + hostPIDPod.Spec.SecurityContext.HostPID = true + + hostIPCSCC := defaultSCC() + hostIPCSCC.AllowHostIPC = true + hostIPCPod := defaultPod() + hostIPCPod.Spec.SecurityContext.HostIPC = true + + hostPortSCC := defaultSCC() + hostPortSCC.AllowHostPorts = true + hostPortPod := defaultPod() + hostPortPod.Spec.Containers[0].Ports = []api.ContainerPort{{HostPort: 1}} + + errorCases := map[string]struct { + pod *api.Pod + scc *api.SecurityContextConstraints + }{ + "pass user must run as SCC": { + pod: userPod, + scc: userSCC, + }, + "pass seLinux must run as SCC": { + pod: seLinuxPod, + scc: seLinuxSCC, + }, + "pass priv validating SCC": { + pod: privPod, + scc: privSCC, + }, + "pass caps validating SCC": { + pod: capsPod, + scc: capsSCC, + }, + "pass hostDir validating SCC": { + pod: hostDirPod, + scc: hostDirSCC, + }, + "pass hostNetwork validating SCC": { + pod: hostNetworkPod, + scc: hostNetworkSCC, + }, + "pass hostPort validating SCC": { + pod: hostPortPod, + scc: hostPortSCC, + }, + "pass hostPID validating SCC": { + pod: hostPIDPod, + scc: hostPIDSCC, + }, + "pass hostIPC validating SCC": { + pod: hostIPCPod, + scc: hostIPCSCC, + }, + } + + for k, v := range errorCases { + provider, err := NewSimpleProvider(v.scc) + if err != nil { + t.Fatal("unable to create provider %v", err) + } + errs := provider.ValidateSecurityContext(v.pod, &v.pod.Spec.Containers[0]) + if len(errs) != 0 { + t.Errorf("%s expected validation pass but received errors %v", k, errs) + continue + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/doc.go new file mode 100644 index 000000000000..63be5769c474 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 selinux contains security context constraints SELinux strategy implementations. +package selinux diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas.go new file mode 100644 index 000000000000..dc22b4cabbb3 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas.go @@ -0,0 +1,82 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 selinux + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +type mustRunAs struct { + opts *api.SELinuxContextStrategyOptions +} + +var _ SELinuxSecurityContextConstraintsStrategy = &mustRunAs{} + +func NewMustRunAs(options *api.SELinuxContextStrategyOptions) (SELinuxSecurityContextConstraintsStrategy, error) { + if options == nil { + return nil, fmt.Errorf("MustRunAs requires SELinuxContextStrategyOptions") + } + if options.SELinuxOptions == nil { + return nil, fmt.Errorf("MustRunAs requires SELinuxOptions") + } + return &mustRunAs{ + opts: options, + }, nil +} + +// Generate creates the SELinuxOptions based on constraint rules. +func (s *mustRunAs) Generate(pod *api.Pod, container *api.Container) (*api.SELinuxOptions, error) { + return s.opts.SELinuxOptions, nil +} + +// Validate ensures that the specified values fall within the range of the strategy. +func (s *mustRunAs) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { + allErrs := fielderrors.ValidationErrorList{} + + if container.SecurityContext == nil { + detail := fmt.Sprintf("unable to validate nil security context for container %s", container.Name) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext", container.SecurityContext, detail)) + return allErrs + } + if container.SecurityContext.SELinuxOptions == nil { + detail := fmt.Sprintf("unable to validate nil seLinuxOptions for container %s", container.Name) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("seLinuxOptions", container.SecurityContext.SELinuxOptions, detail)) + return allErrs + } + seLinux := container.SecurityContext.SELinuxOptions + if seLinux.Level != s.opts.SELinuxOptions.Level { + detail := fmt.Sprintf("seLinuxOptions.level on container %s does not match required level. Found %s, wanted %s", container.Name, seLinux.Level, s.opts.SELinuxOptions.Level) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("seLinuxOptions.level", seLinux.Level, detail)) + } + if seLinux.Role != s.opts.SELinuxOptions.Role { + detail := fmt.Sprintf("seLinuxOptions.role on container %s does not match required role. Found %s, wanted %s", container.Name, seLinux.Role, s.opts.SELinuxOptions.Role) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("seLinuxOptions.role", seLinux.Role, detail)) + } + if seLinux.Type != s.opts.SELinuxOptions.Type { + detail := fmt.Sprintf("seLinuxOptions.type on container %s does not match required type. Found %s, wanted %s", container.Name, seLinux.Type, s.opts.SELinuxOptions.Type) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("seLinuxOptions.type", seLinux.Type, detail)) + } + if seLinux.User != s.opts.SELinuxOptions.User { + detail := fmt.Sprintf("seLinuxOptions.user on container %s does not match required user. Found %s, wanted %s", container.Name, seLinux.User, s.opts.SELinuxOptions.User) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("seLinuxOptions.user", seLinux.User, detail)) + } + + return allErrs +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas_test.go new file mode 100644 index 000000000000..085cf6e9dd36 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/mustrunas_test.go @@ -0,0 +1,157 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 selinux + +import ( + "k8s.io/kubernetes/pkg/api" + "reflect" + "strings" + "testing" +) + +func TestMustRunAsOptions(t *testing.T) { + tests := map[string]struct { + opts *api.SELinuxContextStrategyOptions + pass bool + }{ + "invalid opts": { + opts: &api.SELinuxContextStrategyOptions{}, + pass: false, + }, + "valid opts": { + opts: &api.SELinuxContextStrategyOptions{SELinuxOptions: &api.SELinuxOptions{}}, + pass: true, + }, + } + for name, tc := range tests { + _, err := NewMustRunAs(tc.opts) + if err != nil && tc.pass { + t.Errorf("%s expected to pass but received error %#v", name, err) + } + if err == nil && !tc.pass { + t.Errorf("%s expected to fail but did not receive an error", name) + } + } +} + +func TestMustRunAsGenerate(t *testing.T) { + opts := &api.SELinuxContextStrategyOptions{ + SELinuxOptions: &api.SELinuxOptions{ + User: "user", + Role: "role", + Type: "type", + Level: "level", + }, + } + mustRunAs, err := NewMustRunAs(opts) + if err != nil { + t.Fatal("unexpected error initializing NewMustRunAs %v", err) + } + generated, err := mustRunAs.Generate(nil, nil) + if err != nil { + t.Fatal("unexpected error generating selinux %v", err) + } + if !reflect.DeepEqual(generated, opts.SELinuxOptions) { + t.Errorf("generated selinux does not equal configured selinux") + } +} + +func TestMustRunAsValidate(t *testing.T) { + newValidOpts := func() *api.SELinuxOptions { + return &api.SELinuxOptions{ + User: "user", + Role: "role", + Level: "level", + Type: "type", + } + } + + role := newValidOpts() + role.Role = "invalid" + + user := newValidOpts() + user.User = "invalid" + + level := newValidOpts() + level.Level = "invalid" + + seType := newValidOpts() + seType.Type = "invalid" + + tests := map[string]struct { + seLinux *api.SELinuxOptions + expectedMsg string + }{ + "invalid role": { + seLinux: role, + expectedMsg: "does not match required role", + }, + "invalid user": { + seLinux: user, + expectedMsg: "does not match required user", + }, + "invalid level": { + seLinux: level, + expectedMsg: "does not match required level", + }, + "invalid type": { + seLinux: seType, + expectedMsg: "does not match required type", + }, + "valid": { + seLinux: newValidOpts(), + expectedMsg: "", + }, + } + + opts := &api.SELinuxContextStrategyOptions{ + SELinuxOptions: newValidOpts(), + } + + for name, tc := range tests { + mustRunAs, err := NewMustRunAs(opts) + if err != nil { + t.Errorf("unexpected error initializing NewMustRunAs for testcase %s: %#v", name, err) + continue + } + container := &api.Container{ + SecurityContext: &api.SecurityContext{ + SELinuxOptions: tc.seLinux, + }, + } + + errs := mustRunAs.Validate(nil, container) + //should've passed but didn't + if len(tc.expectedMsg) == 0 && len(errs) > 0 { + t.Errorf("%s expected no errors but received %v", name, errs) + } + //should've failed but didn't + if len(tc.expectedMsg) != 0 && len(errs) == 0 { + t.Errorf("%s expected error %s but received no errors", name, tc.expectedMsg) + } + //failed with additional messages + if len(tc.expectedMsg) != 0 && len(errs) > 1 { + t.Errorf("%s expected error %s but received multiple errors: %v", name, tc.expectedMsg, errs) + } + //check that we got the right message + if len(tc.expectedMsg) != 0 && len(errs) == 1 { + if !strings.Contains(errs[0].Error(), tc.expectedMsg) { + t.Errorf("%s expected error to contain %s but it did not: %v", name, tc.expectedMsg, errs) + } + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany.go new file mode 100644 index 000000000000..f2150af3f268 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany.go @@ -0,0 +1,42 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 selinux + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +// runAsAny implements the SELinuxSecurityContextConstraintsStrategy interface. +type runAsAny struct{} + +var _ SELinuxSecurityContextConstraintsStrategy = &runAsAny{} + +// NewRunAsAny provides a strategy that will return the configured se linux context or nil. +func NewRunAsAny(options *api.SELinuxContextStrategyOptions) (SELinuxSecurityContextConstraintsStrategy, error) { + return &runAsAny{}, nil +} + +// Generate creates the SELinuxOptions based on constraint rules. +func (s *runAsAny) Generate(pod *api.Pod, container *api.Container) (*api.SELinuxOptions, error) { + return nil, nil +} + +// Validate ensures that the specified values fall within the range of the strategy. +func (s *runAsAny) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { + return fielderrors.ValidationErrorList{} +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany_test.go new file mode 100644 index 000000000000..9fd50b67f7fb --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/runasany_test.go @@ -0,0 +1,71 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 selinux + +import ( + "k8s.io/kubernetes/pkg/api" + "testing" +) + +func TestRunAsAnyOptions(t *testing.T) { + _, err := NewRunAsAny(nil) + if err != nil { + t.Fatalf("unexpected error initializing NewRunAsAny %v", err) + } + _, err = NewRunAsAny(&api.SELinuxContextStrategyOptions{}) + if err != nil { + t.Errorf("unexpected error initializing NewRunAsAny %v", err) + } +} + +func TestRunAsAnyGenerate(t *testing.T) { + s, err := NewRunAsAny(&api.SELinuxContextStrategyOptions{}) + if err != nil { + t.Fatalf("unexpected error initializing NewRunAsAny %v", err) + } + uid, err := s.Generate(nil, nil) + if uid != nil { + t.Errorf("expected nil uid but got %d", *uid) + } + if err != nil { + t.Errorf("unexpected error generating uid %v", err) + } +} + +func TestRunAsAnyValidate(t *testing.T) { + s, err := NewRunAsAny(&api.SELinuxContextStrategyOptions{ + SELinuxOptions: &api.SELinuxOptions{ + Level: "foo", + }, + }, + ) + if err != nil { + t.Fatalf("unexpected error initializing NewRunAsAny %v", err) + } + errs := s.Validate(nil, nil) + if len(errs) != 0 { + t.Errorf("unexpected errors validating with ") + } + s, err = NewRunAsAny(&api.SELinuxContextStrategyOptions{}) + if err != nil { + t.Fatalf("unexpected error initializing NewRunAsAny %v", err) + } + errs = s.Validate(nil, nil) + if len(errs) != 0 { + t.Errorf("unexpected errors validating with ") + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/types.go new file mode 100644 index 000000000000..58f01981e3a2 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/selinux/types.go @@ -0,0 +1,30 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 selinux + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +// SELinuxSecurityContextConstraintsStrategy defines the interface for all SELinux constraint strategies. +type SELinuxSecurityContextConstraintsStrategy interface { + // Generate creates the SELinuxOptions based on constraint rules. + Generate(pod *api.Pod, container *api.Container) (*api.SELinuxOptions, error) + // Validate ensures that the specified values fall within the range of the strategy. + Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/types.go new file mode 100644 index 000000000000..9e7b680aa945 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/types.go @@ -0,0 +1,33 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 securitycontextconstraints + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +// SecurityContextConstraintsProvider provides the implementation to generate a new security +// context based on constraints or validate an existing security context against constraints. +type SecurityContextConstraintsProvider interface { + // Create a SecurityContext based on the given constraints + CreateSecurityContext(pod *api.Pod, container *api.Container) (*api.SecurityContext, error) + // Ensure a container's SecurityContext is in compliance with the given constraints + ValidateSecurityContext(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList + // Get the name of the SCC that this provider was initialized with. + GetSCCName() string +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/doc.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/doc.go new file mode 100644 index 000000000000..a3ce47444557 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 user contains security context constraints user strategy implementations. +package user diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas.go new file mode 100644 index 000000000000..47b7fa1a3ae2 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas.go @@ -0,0 +1,71 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 user + +import ( + "fmt" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +// mustRunAs implements the RunAsUserSecurityContextConstraintsStrategy interface +type mustRunAs struct { + opts *api.RunAsUserStrategyOptions +} + +var _ RunAsUserSecurityContextConstraintsStrategy = &mustRunAs{} + +// NewMustRunAs provides a strategy that requires the container to run as a specific UID. +func NewMustRunAs(options *api.RunAsUserStrategyOptions) (RunAsUserSecurityContextConstraintsStrategy, error) { + if options == nil { + return nil, fmt.Errorf("MustRunAs requires run as user options") + } + if options.UID == nil { + return nil, fmt.Errorf("MustRunAs requires a UID") + } + return &mustRunAs{ + opts: options, + }, nil +} + +// Generate creates the uid based on policy rules. MustRunAs returns the UID it is initialized with. +func (s *mustRunAs) Generate(pod *api.Pod, container *api.Container) (*int64, error) { + return s.opts.UID, nil +} + +// Validate ensures that the specified values fall within the range of the strategy. +func (s *mustRunAs) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { + allErrs := fielderrors.ValidationErrorList{} + + if container.SecurityContext == nil { + detail := fmt.Sprintf("unable to validate nil security context for container %s", container.Name) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext", container.SecurityContext, detail)) + return allErrs + } + if container.SecurityContext.RunAsUser == nil { + detail := fmt.Sprintf("unable to validate nil runAsUser for container %s", container.Name) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext.runAsUser", container.SecurityContext.RunAsUser, detail)) + return allErrs + } + + if *s.opts.UID != *container.SecurityContext.RunAsUser { + detail := fmt.Sprintf("UID on container %s does not match required UID. Found %d, wanted %d", container.Name, *container.SecurityContext.RunAsUser, *s.opts.UID) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext.runAsUser", *container.SecurityContext.RunAsUser, detail)) + } + + return allErrs +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas_test.go new file mode 100644 index 000000000000..26f53b7dd625 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunas_test.go @@ -0,0 +1,90 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 user + +import ( + "k8s.io/kubernetes/pkg/api" + "testing" +) + +func TestMustRunAsOptions(t *testing.T) { + var uid int64 = 1 + tests := map[string]struct { + opts *api.RunAsUserStrategyOptions + pass bool + }{ + "invalid opts": { + opts: &api.RunAsUserStrategyOptions{}, + pass: false, + }, + "valid opts": { + opts: &api.RunAsUserStrategyOptions{UID: &uid}, + pass: true, + }, + } + for name, tc := range tests { + _, err := NewMustRunAs(tc.opts) + if err != nil && tc.pass { + t.Errorf("%s expected to pass but received error %v", name, err) + } + if err == nil && !tc.pass { + t.Errorf("%s expected to fail but did not receive an error", name) + } + } +} + +func TestMustRunAsGenerate(t *testing.T) { + var uid int64 = 1 + opts := &api.RunAsUserStrategyOptions{UID: &uid} + mustRunAs, err := NewMustRunAs(opts) + if err != nil { + t.Fatal("unexpected error initializing NewMustRunAs %v", err) + } + generated, err := mustRunAs.Generate(nil, nil) + if err != nil { + t.Fatal("unexpected error generating uid %v", err) + } + if *generated != uid { + t.Errorf("generated uid does not equal configured uid") + } +} + +func TestMustRunAsValidate(t *testing.T) { + var uid int64 = 1 + var badUID int64 = 2 + opts := &api.RunAsUserStrategyOptions{UID: &uid} + mustRunAs, err := NewMustRunAs(opts) + if err != nil { + t.Fatal("unexpected error initializing NewMustRunAs %v", err) + } + container := &api.Container{ + SecurityContext: &api.SecurityContext{ + RunAsUser: &badUID, + }, + } + + errs := mustRunAs.Validate(nil, container) + if len(errs) == 0 { + t.Errorf("expected errors from mismatch uid but got none") + } + + container.SecurityContext.RunAsUser = &uid + errs = mustRunAs.Validate(nil, container) + if len(errs) != 0 { + t.Errorf("expected no errors from matching uid but got %v", errs) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunasrange.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunasrange.go new file mode 100644 index 000000000000..ef65bd9d217e --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/mustrunasrange.go @@ -0,0 +1,76 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 user + +import ( + "fmt" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +// mustRunAs implements the RunAsUserSecurityContextConstraintsStrategy interface +type mustRunAsRange struct { + opts *api.RunAsUserStrategyOptions +} + +// NewMustRunAs provides a strategy that requires the container to run as a specific UID in a range. +func NewMustRunAsRange(options *api.RunAsUserStrategyOptions) (RunAsUserSecurityContextConstraintsStrategy, error) { + if options == nil { + return nil, fmt.Errorf("MustRunAsRange requires run as user options") + } + if options.UIDRangeMin == nil { + return nil, fmt.Errorf("MustRunAsRange requires a UIDRangeMin") + } + if options.UIDRangeMax == nil { + return nil, fmt.Errorf("MustRunAsRange requires a UIDRangeMax") + } + return &mustRunAsRange{ + opts: options, + }, nil +} + +// Generate creates the uid based on policy rules. MustRunAs returns the UIDRangeMin it is initialized with. +func (s *mustRunAsRange) Generate(pod *api.Pod, container *api.Container) (*int64, error) { + return s.opts.UIDRangeMin, nil +} + +// Validate ensures that the specified values fall within the range of the strategy. +func (s *mustRunAsRange) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { + allErrs := fielderrors.ValidationErrorList{} + + if container.SecurityContext == nil { + detail := fmt.Sprintf("unable to validate nil security context for container %s", container.Name) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext", container.SecurityContext, detail)) + return allErrs + } + if container.SecurityContext.RunAsUser == nil { + detail := fmt.Sprintf("unable to validate nil RunAsUser for container %s", container.Name) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext.runAsUser", container.SecurityContext.RunAsUser, detail)) + return allErrs + } + + if *container.SecurityContext.RunAsUser < *s.opts.UIDRangeMin || *container.SecurityContext.RunAsUser > *s.opts.UIDRangeMax { + detail := fmt.Sprintf("UID on container %s does not match required range. Found %d, required min: %d max: %d", + container.Name, + *container.SecurityContext.RunAsUser, + *s.opts.UIDRangeMin, + *s.opts.UIDRangeMax) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext.runAsUser", *container.SecurityContext.RunAsUser, detail)) + } + + return allErrs +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot.go new file mode 100644 index 000000000000..7d551f4a7d87 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot.go @@ -0,0 +1,57 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 user + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +type nonRoot struct{} + +var _ RunAsUserSecurityContextConstraintsStrategy = &nonRoot{} + +func NewRunAsNonRoot(options *api.RunAsUserStrategyOptions) (RunAsUserSecurityContextConstraintsStrategy, error) { + return &nonRoot{}, nil +} + +// Generate creates the uid based on policy rules. This strategy does return a UID. It assumes +// that the user will specify a UID or the container image specifies a UID. +func (s *nonRoot) Generate(pod *api.Pod, container *api.Container) (*int64, error) { + return nil, nil +} + +// Validate ensures that the specified values fall within the range of the strategy. Validation +// of this will pass if either the UID is not set, assuming that the image will provided the UID +// or if the UID is set it is not root. In order to work properly this assumes that the kubelet +// will populate an +func (s *nonRoot) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { + allErrs := fielderrors.ValidationErrorList{} + if container.SecurityContext == nil { + detail := fmt.Sprintf("unable to validate nil security context for container %s", container.Name) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext", container.SecurityContext, detail)) + return allErrs + } + if container.SecurityContext.RunAsUser != nil && *container.SecurityContext.RunAsUser == 0 { + detail := fmt.Sprintf("running with the root UID is forbidden by the security context constraints %s", container.Name) + allErrs = append(allErrs, fielderrors.NewFieldInvalid("securityContext.runAsUser", *container.SecurityContext.RunAsUser, detail)) + return allErrs + } + return allErrs +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot_test.go new file mode 100644 index 000000000000..4ca637dccc44 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/nonroot_test.go @@ -0,0 +1,78 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 user + +import ( + "k8s.io/kubernetes/pkg/api" + "testing" +) + +func TestNonRootOptions(t *testing.T) { + _, err := NewRunAsNonRoot(nil) + if err != nil { + t.Fatalf("unexpected error initializing NewRunAsNonRoot %v", err) + } + _, err = NewRunAsNonRoot(&api.RunAsUserStrategyOptions{}) + if err != nil { + t.Errorf("unexpected error initializing NewRunAsNonRoot %v", err) + } +} + +func TestNonRootGenerate(t *testing.T) { + s, err := NewRunAsNonRoot(&api.RunAsUserStrategyOptions{}) + if err != nil { + t.Fatalf("unexpected error initializing NewRunAsNonRoot %v", err) + } + uid, err := s.Generate(nil, nil) + if uid != nil { + t.Errorf("expected nil uid but got %d", *uid) + } + if err != nil { + t.Errorf("unexpected error generating uid %v", err) + } +} + +func TestNonRootValidate(t *testing.T) { + var uid int64 = 1 + var badUID int64 = 0 + s, err := NewRunAsNonRoot(&api.RunAsUserStrategyOptions{}) + if err != nil { + t.Fatal("unexpected error initializing NewMustRunAs %v", err) + } + container := &api.Container{ + SecurityContext: &api.SecurityContext{ + RunAsUser: &badUID, + }, + } + + errs := s.Validate(nil, container) + if len(errs) == 0 { + t.Errorf("expected errors from root uid but got none") + } + + container.SecurityContext.RunAsUser = &uid + errs = s.Validate(nil, container) + if len(errs) != 0 { + t.Errorf("expected no errors from non-root uid but got %v", errs) + } + + container.SecurityContext.RunAsUser = nil + errs = s.Validate(nil, container) + if len(errs) != 0 { + t.Errorf("expected no errors from nil uid but got %v", errs) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany.go new file mode 100644 index 000000000000..22b6916907be --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany.go @@ -0,0 +1,42 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 user + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +// runAsAny implements the interface RunAsUserSecurityContextConstraintsStrategy. +type runAsAny struct{} + +var _ RunAsUserSecurityContextConstraintsStrategy = &runAsAny{} + +// NewRunAsAny provides a strategy that will return nil. +func NewRunAsAny(options *api.RunAsUserStrategyOptions) (RunAsUserSecurityContextConstraintsStrategy, error) { + return &runAsAny{}, nil +} + +// Generate creates the uid based on policy rules. +func (s *runAsAny) Generate(pod *api.Pod, container *api.Container) (*int64, error) { + return nil, nil +} + +// Validate ensures that the specified values fall within the range of the strategy. +func (s *runAsAny) Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList { + return fielderrors.ValidationErrorList{} +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany_test.go new file mode 100644 index 000000000000..b13ae29fc238 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/runasany_test.go @@ -0,0 +1,58 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 user + +import ( + "k8s.io/kubernetes/pkg/api" + "testing" +) + +func TestRunAsAnyOptions(t *testing.T) { + _, err := NewRunAsAny(nil) + if err != nil { + t.Fatalf("unexpected error initializing NewRunAsAny %v", err) + } + _, err = NewRunAsAny(&api.RunAsUserStrategyOptions{}) + if err != nil { + t.Errorf("unexpected error initializing NewRunAsAny %v", err) + } +} + +func TestRunAsAnyGenerate(t *testing.T) { + s, err := NewRunAsAny(&api.RunAsUserStrategyOptions{}) + if err != nil { + t.Fatalf("unexpected error initializing NewRunAsAny %v", err) + } + uid, err := s.Generate(nil, nil) + if uid != nil { + t.Errorf("expected nil uid but got %d", *uid) + } + if err != nil { + t.Errorf("unexpected error generating uid %v", err) + } +} + +func TestRunAsAnyValidate(t *testing.T) { + s, err := NewRunAsAny(&api.RunAsUserStrategyOptions{}) + if err != nil { + t.Fatalf("unexpected error initializing NewRunAsAny %v", err) + } + errs := s.Validate(nil, nil) + if len(errs) != 0 { + t.Errorf("unexpected errors validating with ") + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/types.go new file mode 100644 index 000000000000..9050d575e2e4 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/types.go @@ -0,0 +1,30 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 user + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util/fielderrors" +) + +// RunAsUserSecurityContextConstraintsStrategy defines the interface for all uid constraint strategies. +type RunAsUserSecurityContextConstraintsStrategy interface { + // Generate creates the uid based on policy rules. + Generate(pod *api.Pod, container *api.Container) (*int64, error) + // Validate ensures that the specified values fall within the range of the strategy. + Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/util.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/util.go new file mode 100644 index 000000000000..e723b9d8e71d --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/user/util.go @@ -0,0 +1,57 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 user + +import ( + "fmt" + "strconv" + + "k8s.io/kubernetes/pkg/api" + client "k8s.io/kubernetes/pkg/client/unversioned" +) + +func AnnotationToIntPtr(sUID string) (*int64, error) { + uid, err := strconv.ParseInt(sUID, 10, 64) + if err != nil { + return nil, err + } + return &uid, nil +} + +func GetAllocatedID(kClient client.Interface, pod *api.Pod, annotation string) (*int64, error) { + if len(pod.Spec.ServiceAccountName) > 0 { + sa, err := kClient.ServiceAccounts(pod.Namespace).Get(pod.Spec.ServiceAccountName) + if err != nil { + return nil, err + } + sUID, ok := sa.Annotations[annotation] + if !ok { + return nil, fmt.Errorf("Unable to find annotation %s on service account %s", annotation, pod.Spec.ServiceAccountName) + } + return AnnotationToIntPtr(sUID) + } else { + ns, err := kClient.Namespaces().Get(pod.Namespace) + if err != nil { + return nil, err + } + sUID, ok := ns.Annotations[annotation] + if !ok { + return nil, fmt.Errorf("Unable to find annotation %s on namespace %s", annotation, pod.Namespace) + } + return AnnotationToIntPtr(sUID) + } +} From 922d85627d230b937904e686a44700c32590abff Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Tue, 11 Aug 2015 13:32:04 -0400 Subject: [PATCH 09/35] UPSTREAM: : Add deprecated fields to migrate 1.0.0 k8s v1 data Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go --- .../kubernetes/pkg/api/v1/conversion.go | 11 +++++ .../pkg/api/v1/conversion_generated.go | 4 ++ .../pkg/api/v1/deep_copy_generated.go | 7 ++++ .../k8s.io/kubernetes/pkg/api/v1/defaults.go | 42 +++++++++++++++++++ .../src/k8s.io/kubernetes/pkg/api/v1/types.go | 6 +++ 5 files changed, 70 insertions(+) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go index ba5f619d175e..71d12a32ac2d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go @@ -303,6 +303,10 @@ func convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversi } else { out.ImagePullSecrets = nil } + + // carry conversion + out.DeprecatedHost = in.NodeName + return nil } @@ -359,6 +363,12 @@ func convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversi out.ServiceAccountName = in.DeprecatedServiceAccount } out.NodeName = in.NodeName + + // carry conversion + if in.NodeName == "" { + out.NodeName = in.DeprecatedHost + } + if in.SecurityContext != nil { out.SecurityContext = new(api.PodSecurityContext) if err := convert_v1_PodSecurityContext_To_api_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { @@ -371,6 +381,7 @@ func convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversi out.SecurityContext.HostNetwork = in.HostNetwork out.SecurityContext.HostPID = in.HostPID out.SecurityContext.HostIPC = in.HostIPC + if in.ImagePullSecrets != nil { out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets)) for i := range in.ImagePullSecrets { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go index 54adb3728574..d8e3e2c70fce 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go @@ -2960,6 +2960,10 @@ func autoconvert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *Ser } out.LoadBalancerIP = in.LoadBalancerIP out.SessionAffinity = ServiceAffinity(in.SessionAffinity) + + // Carry conversion + out.DeprecatedPortalIP = in.ClusterIP + return nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go index 59bce1c1ca9b..d4d666432454 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go @@ -1572,6 +1572,10 @@ func deepCopy_v1_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error { } else { out.ImagePullSecrets = nil } + + // Carry copy + out.DeprecatedHost = in.DeprecatedHost + out.DeprecatedServiceAccount = in.DeprecatedServiceAccount return nil } @@ -2277,6 +2281,9 @@ func deepCopy_v1_ServiceSpec(in ServiceSpec, out *ServiceSpec, c *conversion.Clo } out.SessionAffinity = in.SessionAffinity out.LoadBalancerIP = in.LoadBalancerIP + + // Carry copy + out.DeprecatedPortalIP = in.DeprecatedPortalIP return nil } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go index c4a67e3295ac..1d0faf3f0ee6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go @@ -55,6 +55,14 @@ func addDefaultingFuncs() { if obj.Protocol == "" { obj.Protocol = ProtocolTCP } + + // Carry conversion to make port case valid + switch strings.ToUpper(string(obj.Protocol)) { + case string(ProtocolTCP): + obj.Protocol = ProtocolTCP + case string(ProtocolUDP): + obj.Protocol = ProtocolUDP + } }, func(obj *Container) { if obj.ImagePullPolicy == "" { @@ -87,6 +95,20 @@ func addDefaultingFuncs() { sp.TargetPort = util.NewIntOrStringFromInt(sp.Port) } } + + // Carry conversion + if len(obj.ClusterIP) == 0 && len(obj.DeprecatedPortalIP) > 0 { + obj.ClusterIP = obj.DeprecatedPortalIP + } + }, + func(obj *ServicePort) { + // Carry conversion to make port case valid + switch strings.ToUpper(string(obj.Protocol)) { + case string(ProtocolTCP): + obj.Protocol = ProtocolTCP + case string(ProtocolUDP): + obj.Protocol = ProtocolUDP + } }, func(obj *Pod) { // If limits are specified, but requests are not, default requests to limits @@ -116,9 +138,20 @@ func addDefaultingFuncs() { if obj.HostNetwork { defaultHostNetworkPorts(&obj.Containers) } + if obj.SecurityContext == nil { obj.SecurityContext = &PodSecurityContext{} } + + // Carry migration from serviceAccount to serviceAccountName + if len(obj.ServiceAccountName) == 0 && len(obj.DeprecatedServiceAccount) > 0 { + obj.ServiceAccountName = obj.DeprecatedServiceAccount + } + // Carry migration from host to nodeName + if len(obj.NodeName) == 0 && len(obj.DeprecatedHost) > 0 { + obj.NodeName = obj.DeprecatedHost + } + if obj.TerminationGracePeriodSeconds == nil { period := int64(DefaultTerminationGracePeriodSeconds) obj.TerminationGracePeriodSeconds = &period @@ -158,6 +191,15 @@ func addDefaultingFuncs() { } } }, + func(obj *EndpointPort) { + // Carry conversion to make port case valid + switch strings.ToUpper(string(obj.Protocol)) { + case string(ProtocolTCP): + obj.Protocol = ProtocolTCP + case string(ProtocolUDP): + obj.Protocol = ProtocolUDP + } + }, func(obj *HTTPGetAction) { if obj.Path == "" { obj.Path = "/" diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go index 196e721c943e..d9fd1ef8bc7b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go @@ -1217,6 +1217,9 @@ type PodSpec struct { // More info: http://releases.k8s.io/HEAD/docs/user-guide/node-selection/README.md NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // DeprecatedHost is a request to schedule this pod onto a specific node + DeprecatedHost string `json:"host,omitempty" description:"deprecated, use nodeName instead"` + // ServiceAccountName is the name of the ServiceAccount to use to run this pod. // More info: http://releases.k8s.io/HEAD/docs/design/service_accounts.md ServiceAccountName string `json:"serviceAccountName,omitempty"` @@ -1499,6 +1502,9 @@ type ServiceSpec struct { // More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview Selector map[string]string `json:"selector,omitempty"` + // DeprecatedPortalIP + DeprecatedPortalIP string `json:"portalIP,omitempty" description:"deprecated, use clusterIP instead"` + // ClusterIP is usually assigned by the master and is the IP address of the service. // If specified, it will be allocated to the service if it is unused // or else creation of the service will fail. From b36aeb4edcbd9e929cf9492254c4e3773bc51b1a Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 15 Oct 2015 16:37:45 -0400 Subject: [PATCH 10/35] UPSTREAM: : helper methods paralleling old latest fields --- .../kubernetes/pkg/api/latest/latest.go | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest.go index 9341466615f0..10e9a04dc0eb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest.go @@ -147,3 +147,64 @@ type GroupMeta struct { // string, or an error if the version is not known. InterfacesFor func(version string) (*meta.VersionInterfaces, error) } + +type GroupVersion struct { + Group string + Version string +} + +func InterfacesFor(groupVersion GroupVersion) (*meta.VersionInterfaces, error) { + kubeAPIGroup, err := Group(groupVersion.Group) + if err != nil { + return nil, err + } + + return kubeAPIGroup.InterfacesFor(groupVersion.Version) +} + +func CodecFor(group string) (runtime.Codec, error) { + kubeAPIGroup, err := Group(group) + if err != nil { + return nil, err + } + + return kubeAPIGroup.Codec, nil +} + +func RESTMapperFor(group string) (meta.RESTMapper, error) { + kubeAPIGroup, err := Group(group) + if err != nil { + return nil, err + } + + return kubeAPIGroup.RESTMapper, nil +} + +func DefaultVersionFor(group string) (string, error) { + kubeAPIGroup, err := Group(group) + if err != nil { + return "", err + } + + return kubeAPIGroup.Version, nil +} + +func InterfacesForLegacyGroup(version string) (*meta.VersionInterfaces, error) { + return GroupOrDie("").InterfacesFor(version) +} + +func CodecForLegacyGroup() runtime.Codec { + return GroupOrDie("").Codec +} + +func RESTMapperForLegacyGroup() meta.RESTMapper { + return GroupOrDie("").RESTMapper +} + +func DefaultVersionForLegacyGroup() string { + return GroupOrDie("").Version +} + +func VersionsForLegacyGroup() []string { + return GroupOrDie("").Versions +} From 17978ffa6952d73c5275c3ca34d31a1c7fc6dd82 Mon Sep 17 00:00:00 2001 From: Paul Weil Date: Tue, 11 Aug 2015 13:42:35 -0400 Subject: [PATCH 11/35] UPSTREAM: : reallow the ability to post across namespaces in api --- .../src/k8s.io/kubernetes/pkg/apiserver/api_installer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go index 1a463dd34bdd..848eb394ae2e 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go @@ -350,6 +350,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if !hasSubresource { namer = scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), true} actions = appendIf(actions, action{"LIST", resource, params, namer}, isLister) + actions = appendIf(actions, action{"POST", resource, params, namer}, isCreater) actions = appendIf(actions, action{"WATCHLIST", "watch/" + resource, params, namer}, allowWatchList) } break From 212c015c5c78020d5ead2b6608ea4d7ca3511870 Mon Sep 17 00:00:00 2001 From: deads2k Date: Tue, 11 Aug 2015 13:57:39 -0400 Subject: [PATCH 12/35] UPSTREAM: : update describer for dockercfg secrets --- .../_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe.go index 8966b0cf6189..eef1629b8b4c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/describe.go @@ -972,7 +972,8 @@ func describeSecret(secret *api.Secret) (string, error) { fmt.Fprintf(out, "\nData\n====\n") for k, v := range secret.Data { switch { - case k == api.ServiceAccountTokenKey && secret.Type == api.SecretTypeServiceAccountToken: + case k == api.ServiceAccountTokenKey && secret.Type == api.SecretTypeServiceAccountToken, + k == api.DockerConfigKey && secret.Type == api.SecretTypeDockercfg: fmt.Fprintf(out, "%s:\t%s\n", k, string(v)) default: fmt.Fprintf(out, "%s:\t%d bytes\n", k, len(v)) From 0048df42fe7293f6615aa703ae2f433d6e5854f6 Mon Sep 17 00:00:00 2001 From: kargakis Date: Thu, 24 Sep 2015 14:49:57 +0200 Subject: [PATCH 13/35] UPSTREAM: : Disable --validate by default Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go --- .../src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go index 9e3283fa4615..591440040814 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go @@ -279,7 +279,7 @@ func GetFlagDuration(cmd *cobra.Command, flag string) time.Duration { } func AddValidateFlags(cmd *cobra.Command) { - cmd.Flags().Bool("validate", true, "If true, use a schema to validate the input before sending it") + cmd.Flags().Bool("validate", false, "If true, use a schema to validate the input before sending it") cmd.Flags().String("schema-cache-dir", fmt.Sprintf("~/%s/%s", clientcmd.RecommendedHomeDir, clientcmd.RecommendedSchemaName), fmt.Sprintf("If non-empty, load/store cached API schemas in this directory, default is '$HOME/%s/%s'", clientcmd.RecommendedHomeDir, clientcmd.RecommendedSchemaName)) } From 228fdbafb823998761ca4e66bc83e3097363c9a6 Mon Sep 17 00:00:00 2001 From: deads2k Date: Fri, 16 Oct 2015 16:12:42 -0400 Subject: [PATCH 14/35] UPSTREAM: : Back n forth downward/metadata conversions --- .../kubernetes/pkg/api/v1/conversion.go | 101 + .../pkg/api/v1/conversion_generated.go | 279 -- .../api/v1/conversion_volumesource_test.go | 75 + .../pkg/api/v1/deep_copy_generated.go | 37 +- .../src/k8s.io/kubernetes/pkg/api/v1/types.go | 21 +- .../experimental/v1/conversion_generated.go | 2494 +++++++++++++++++ .../pkg/apis/extensions/v1beta1/conversion.go | 116 + .../extensions/v1beta1/deep_copy_generated.go | 34 + 8 files changed, 2874 insertions(+), 283 deletions(-) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_volumesource_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/conversion_generated.go diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go index 71d12a32ac2d..a0aa732756b8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion.go @@ -33,6 +33,9 @@ func addConversionFuncs() { convert_v1_PodSpec_To_api_PodSpec, convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec, convert_v1_ServiceSpec_To_api_ServiceSpec, + + convert_api_VolumeSource_To_v1_VolumeSource, + convert_v1_VolumeSource_To_api_VolumeSource, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. @@ -433,3 +436,101 @@ func convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *PodSecurityCont } return nil } + +// This will convert our internal represantation of VolumeSource to its v1 representation +// Used for keeping backwards compatibility for the Metadata field +func convert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *VolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.VolumeSource))(in) + } + + if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { + return err + } + + if in.DownwardAPI != nil { + out.Metadata = new(MetadataVolumeSource) + if err := convert_api_DownwardAPIVolumeSource_To_v1_MetadataVolumeSource(in.DownwardAPI, out.Metadata, s); err != nil { + return err + } + } + return nil +} + +// downward -> metadata (api -> v1) +func convert_api_DownwardAPIVolumeSource_To_v1_MetadataVolumeSource(in *api.DownwardAPIVolumeSource, out *MetadataVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]MetadataFile, len(in.Items)) + for i := range in.Items { + if err := convert_api_DownwardAPIVolumeFile_To_v1_MetadataFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } + + return nil +} + +func convert_api_DownwardAPIVolumeFile_To_v1_MetadataFile(in *api.DownwardAPIVolumeFile, out *MetadataFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeFile))(in) + } + out.Name = in.Path + if err := convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + return nil +} + +// This will convert the v1 representation of VolumeSource to our internal representation +// Used for keeping backwards compatibility for the Metadata field +func convert_v1_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api.VolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*VolumeSource))(in) + } + + if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { + return err + } + + if in.Metadata != nil { + out.DownwardAPI = new(api.DownwardAPIVolumeSource) + if err := convert_v1_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in.Metadata, out.DownwardAPI, s); err != nil { + return err + } + } + + return nil +} + +// metadata -> downward (v1 -> api) +func convert_v1_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in *MetadataVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*MetadataVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]api.DownwardAPIVolumeFile, len(in.Items)) + for i := range in.Items { + if err := convert_v1_MetadataFile_To_api_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } + + return nil +} + +func convert_v1_MetadataFile_To_api_DownwardAPIVolumeFile(in *MetadataFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*MetadataFile))(in) + } + out.Path = in.Name + if err := convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go index d8e3e2c70fce..b6953cb8943b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go @@ -3024,145 +3024,6 @@ func convert_api_VolumeMount_To_v1_VolumeMount(in *api.VolumeMount, out *VolumeM return autoconvert_api_VolumeMount_To_v1_VolumeMount(in, out, s) } -func autoconvert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *VolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*api.VolumeSource))(in) - } - if in.HostPath != nil { - out.HostPath = new(HostPathVolumeSource) - if err := convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in.HostPath, out.HostPath, s); err != nil { - return err - } - } else { - out.HostPath = nil - } - if in.EmptyDir != nil { - out.EmptyDir = new(EmptyDirVolumeSource) - if err := convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in.EmptyDir, out.EmptyDir, s); err != nil { - return err - } - } else { - out.EmptyDir = nil - } - if in.GCEPersistentDisk != nil { - out.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) - if err := convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in.GCEPersistentDisk, out.GCEPersistentDisk, s); err != nil { - return err - } - } else { - out.GCEPersistentDisk = nil - } - if in.AWSElasticBlockStore != nil { - out.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) - if err := convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in.AWSElasticBlockStore, out.AWSElasticBlockStore, s); err != nil { - return err - } - } else { - out.AWSElasticBlockStore = nil - } - if in.GitRepo != nil { - out.GitRepo = new(GitRepoVolumeSource) - if err := convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in.GitRepo, out.GitRepo, s); err != nil { - return err - } - } else { - out.GitRepo = nil - } - if in.Secret != nil { - out.Secret = new(SecretVolumeSource) - if err := convert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in.Secret, out.Secret, s); err != nil { - return err - } - } else { - out.Secret = nil - } - if in.NFS != nil { - out.NFS = new(NFSVolumeSource) - if err := convert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in.NFS, out.NFS, s); err != nil { - return err - } - } else { - out.NFS = nil - } - if in.ISCSI != nil { - out.ISCSI = new(ISCSIVolumeSource) - if err := convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { - return err - } - } else { - out.ISCSI = nil - } - if in.Glusterfs != nil { - out.Glusterfs = new(GlusterfsVolumeSource) - if err := convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { - return err - } - } else { - out.Glusterfs = nil - } - if in.PersistentVolumeClaim != nil { - out.PersistentVolumeClaim = new(PersistentVolumeClaimVolumeSource) - if err := convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in.PersistentVolumeClaim, out.PersistentVolumeClaim, s); err != nil { - return err - } - } else { - out.PersistentVolumeClaim = nil - } - if in.RBD != nil { - out.RBD = new(RBDVolumeSource) - if err := convert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in.RBD, out.RBD, s); err != nil { - return err - } - } else { - out.RBD = nil - } - if in.Cinder != nil { - out.Cinder = new(CinderVolumeSource) - if err := convert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in.Cinder, out.Cinder, s); err != nil { - return err - } - } else { - out.Cinder = nil - } - if in.CephFS != nil { - out.CephFS = new(CephFSVolumeSource) - if err := convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in.CephFS, out.CephFS, s); err != nil { - return err - } - } else { - out.CephFS = nil - } - if in.Flocker != nil { - out.Flocker = new(FlockerVolumeSource) - if err := convert_api_FlockerVolumeSource_To_v1_FlockerVolumeSource(in.Flocker, out.Flocker, s); err != nil { - return err - } - } else { - out.Flocker = nil - } - if in.DownwardAPI != nil { - out.DownwardAPI = new(DownwardAPIVolumeSource) - if err := convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in.DownwardAPI, out.DownwardAPI, s); err != nil { - return err - } - } else { - out.DownwardAPI = nil - } - if in.FC != nil { - out.FC = new(FCVolumeSource) - if err := convert_api_FCVolumeSource_To_v1_FCVolumeSource(in.FC, out.FC, s); err != nil { - return err - } - } else { - out.FC = nil - } - return nil -} - -func convert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *VolumeSource, s conversion.Scope) error { - return autoconvert_api_VolumeSource_To_v1_VolumeSource(in, out, s) -} - func autoconvert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in *AWSElasticBlockStoreVolumeSource, out *api.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*AWSElasticBlockStoreVolumeSource))(in) @@ -6160,144 +6021,6 @@ func convert_v1_VolumeMount_To_api_VolumeMount(in *VolumeMount, out *api.VolumeM return autoconvert_v1_VolumeMount_To_api_VolumeMount(in, out, s) } -func autoconvert_v1_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api.VolumeSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*VolumeSource))(in) - } - if in.HostPath != nil { - out.HostPath = new(api.HostPathVolumeSource) - if err := convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in.HostPath, out.HostPath, s); err != nil { - return err - } - } else { - out.HostPath = nil - } - if in.EmptyDir != nil { - out.EmptyDir = new(api.EmptyDirVolumeSource) - if err := convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in.EmptyDir, out.EmptyDir, s); err != nil { - return err - } - } else { - out.EmptyDir = nil - } - if in.GCEPersistentDisk != nil { - out.GCEPersistentDisk = new(api.GCEPersistentDiskVolumeSource) - if err := convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in.GCEPersistentDisk, out.GCEPersistentDisk, s); err != nil { - return err - } - } else { - out.GCEPersistentDisk = nil - } - if in.AWSElasticBlockStore != nil { - out.AWSElasticBlockStore = new(api.AWSElasticBlockStoreVolumeSource) - if err := convert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in.AWSElasticBlockStore, out.AWSElasticBlockStore, s); err != nil { - return err - } - } else { - out.AWSElasticBlockStore = nil - } - if in.GitRepo != nil { - out.GitRepo = new(api.GitRepoVolumeSource) - if err := convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in.GitRepo, out.GitRepo, s); err != nil { - return err - } - } else { - out.GitRepo = nil - } - if in.Secret != nil { - out.Secret = new(api.SecretVolumeSource) - if err := convert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in.Secret, out.Secret, s); err != nil { - return err - } - } else { - out.Secret = nil - } - if in.NFS != nil { - out.NFS = new(api.NFSVolumeSource) - if err := convert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in.NFS, out.NFS, s); err != nil { - return err - } - } else { - out.NFS = nil - } - if in.ISCSI != nil { - out.ISCSI = new(api.ISCSIVolumeSource) - if err := convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { - return err - } - } else { - out.ISCSI = nil - } - if in.Glusterfs != nil { - out.Glusterfs = new(api.GlusterfsVolumeSource) - if err := convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { - return err - } - } else { - out.Glusterfs = nil - } - if in.PersistentVolumeClaim != nil { - out.PersistentVolumeClaim = new(api.PersistentVolumeClaimVolumeSource) - if err := convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in.PersistentVolumeClaim, out.PersistentVolumeClaim, s); err != nil { - return err - } - } else { - out.PersistentVolumeClaim = nil - } - if in.RBD != nil { - out.RBD = new(api.RBDVolumeSource) - if err := convert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in.RBD, out.RBD, s); err != nil { - return err - } - } else { - out.RBD = nil - } - if in.Cinder != nil { - out.Cinder = new(api.CinderVolumeSource) - if err := convert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in.Cinder, out.Cinder, s); err != nil { - return err - } - } else { - out.Cinder = nil - } - if in.CephFS != nil { - out.CephFS = new(api.CephFSVolumeSource) - if err := convert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in.CephFS, out.CephFS, s); err != nil { - return err - } - } else { - out.CephFS = nil - } - if in.Flocker != nil { - out.Flocker = new(api.FlockerVolumeSource) - if err := convert_v1_FlockerVolumeSource_To_api_FlockerVolumeSource(in.Flocker, out.Flocker, s); err != nil { - return err - } - } else { - out.Flocker = nil - } - if in.DownwardAPI != nil { - out.DownwardAPI = new(api.DownwardAPIVolumeSource) - if err := convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in.DownwardAPI, out.DownwardAPI, s); err != nil { - return err - } - } else { - out.DownwardAPI = nil - } - if in.FC != nil { - out.FC = new(api.FCVolumeSource) - if err := convert_v1_FCVolumeSource_To_api_FCVolumeSource(in.FC, out.FC, s); err != nil { - return err - } - } else { - out.FC = nil - } - return nil -} - -func convert_v1_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api.VolumeSource, s conversion.Scope) error { - return autoconvert_v1_VolumeSource_To_api_VolumeSource(in, out, s) -} func convert_api_FSGroupStrategyOptions_To_v1_FSGroupStrategyOptions(in *api.FSGroupStrategyOptions, out *FSGroupStrategyOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.FSGroupStrategyOptions))(in) @@ -6508,7 +6231,6 @@ func init() { autoconvert_api_Service_To_v1_Service, autoconvert_api_TCPSocketAction_To_v1_TCPSocketAction, autoconvert_api_VolumeMount_To_v1_VolumeMount, - autoconvert_api_VolumeSource_To_v1_VolumeSource, autoconvert_api_Volume_To_v1_Volume, autoconvert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource, autoconvert_v1_Binding_To_api_Binding, @@ -6626,7 +6348,6 @@ func init() { autoconvert_v1_Service_To_api_Service, autoconvert_v1_TCPSocketAction_To_api_TCPSocketAction, autoconvert_v1_VolumeMount_To_api_VolumeMount, - autoconvert_v1_VolumeSource_To_api_VolumeSource, autoconvert_v1_Volume_To_api_Volume, convert_api_RunAsUserStrategyOptions_To_v1_RunAsUserStrategyOptions, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_volumesource_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_volumesource_test.go new file mode 100644 index 000000000000..a833f0e189bd --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_volumesource_test.go @@ -0,0 +1,75 @@ +package v1 + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/conversion" +) + +func TestAPItoV1VolumeSourceConversion(t *testing.T) { + c := conversion.NewConverter() + c.Debug = t + + if err := c.RegisterConversionFunc(convert_api_VolumeSource_To_v1_VolumeSource); err != nil { + t.Fatalf("unexpected error %v", err) + } + + in := api.VolumeSource{ + DownwardAPI: &api.DownwardAPIVolumeSource{ + Items: []api.DownwardAPIVolumeFile{ + { + Path: "./test/api-to-v1/conversion", + }, + }, + }, + } + out := VolumeSource{} + + if err := c.Convert(&in, &out, 0, nil); err != nil { + t.Fatalf("unexpected error %v", err) + } + if e, a := in.DownwardAPI.Items[0].Path, out.Metadata.Items[0].Name; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := in.DownwardAPI.Items[0].Path, out.DownwardAPI.Items[0].Path; e != a { + t.Errorf("expected %v, got %v", e, a) + } +} + +func TestV1toAPIVolumeSourceConversion(t *testing.T) { + c := conversion.NewConverter() + c.Debug = t + + if err := c.RegisterConversionFunc(convert_v1_VolumeSource_To_api_VolumeSource); err != nil { + t.Fatalf("unexpected error %v", err) + } + + in := VolumeSource{ + DownwardAPI: &DownwardAPIVolumeSource{ + Items: []DownwardAPIVolumeFile{ + { + Path: "./test/v1-to-api/conversion", + }, + }, + }, + Metadata: &MetadataVolumeSource{ + Items: []MetadataFile{ + { + Name: "./test/v1-to-api/conversion", + }, + }, + }, + } + out := api.VolumeSource{} + + if err := c.Convert(&in, &out, 0, nil); err != nil { + t.Fatalf("unexpected error %v", err) + } + if e, a := in.Metadata.Items[0].Name, out.DownwardAPI.Items[0].Path; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := in.DownwardAPI.Items[0].Path, out.DownwardAPI.Items[0].Path; e != a { + t.Errorf("expected %v, got %v", e, a) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go index d4d666432454..e3b26129591c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go @@ -873,6 +873,28 @@ func deepCopy_v1_LocalObjectReference(in LocalObjectReference, out *LocalObjectR return nil } +func deepCopy_v1_MetadataFile(in MetadataFile, out *MetadataFile, c *conversion.Cloner) error { + out.Name = in.Name + if err := deepCopy_v1_ObjectFieldSelector(in.FieldRef, &out.FieldRef, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1_MetadataVolumeSource(in MetadataVolumeSource, out *MetadataVolumeSource, c *conversion.Cloner) error { + if in.Items != nil { + out.Items = make([]MetadataFile, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1_MetadataFile(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + func deepCopy_v1_NFSVolumeSource(in NFSVolumeSource, out *NFSVolumeSource, c *conversion.Cloner) error { out.Server = in.Server out.Path = in.Path @@ -1548,6 +1570,7 @@ func deepCopy_v1_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error { } else { out.NodeSelector = nil } + out.DeprecatedHost = in.DeprecatedHost out.ServiceAccountName = in.ServiceAccountName out.DeprecatedServiceAccount = in.DeprecatedServiceAccount out.NodeName = in.NodeName @@ -1573,9 +1596,6 @@ func deepCopy_v1_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error { out.ImagePullSecrets = nil } - // Carry copy - out.DeprecatedHost = in.DeprecatedHost - out.DeprecatedServiceAccount = in.DeprecatedServiceAccount return nil } @@ -2445,6 +2465,15 @@ func deepCopy_v1_VolumeSource(in VolumeSource, out *VolumeSource, c *conversion. } else { out.FC = nil } + + if in.Metadata != nil { + out.Metadata = new(MetadataVolumeSource) + if err := deepCopy_v1_MetadataVolumeSource(*in.Metadata, out.Metadata, c); err != nil { + return err + } + } else { + out.Metadata = nil + } return nil } @@ -2525,6 +2554,8 @@ func init() { deepCopy_v1_LoadBalancerIngress, deepCopy_v1_LoadBalancerStatus, deepCopy_v1_LocalObjectReference, + deepCopy_v1_MetadataFile, + deepCopy_v1_MetadataVolumeSource, deepCopy_v1_NFSVolumeSource, deepCopy_v1_Namespace, deepCopy_v1_NamespaceList, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go index d9fd1ef8bc7b..236b1b0e0b12 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go @@ -246,7 +246,6 @@ type VolumeSource struct { // Cinder represents a cinder volume attached and mounted on kubelets host machine // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md Cinder *CinderVolumeSource `json:"cinder,omitempty"` - // CephFS represents a Ceph FS mount on the host that shares a pod's lifetime CephFS *CephFSVolumeSource `json:"cephfs,omitempty"` @@ -257,6 +256,10 @@ type VolumeSource struct { DownwardAPI *DownwardAPIVolumeSource `json:"downwardAPI,omitempty"` // FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. FC *FCVolumeSource `json:"fc,omitempty"` + + // Metadata represents metadata about the pod that should populate this volume + // NOTE: Deprecated in favor of DownwardAPI + Metadata *MetadataVolumeSource `json:"metadata,omitempty" description: "Metadata volume containing information about the pod"` } // PersistentVolumeClaimVolumeSource references the user's PVC in the same namespace. @@ -2451,6 +2454,22 @@ type ComponentStatusList struct { Items []ComponentStatus `json:"items"` } +// MetadataVolumeSource represents a volume containing metadata about a pod. +// NOTE: Deprecated in favor of DownwardAPIVolumeSource +type MetadataVolumeSource struct { + // Items is a list of metadata file name + Items []MetadataFile `json:"items,omitempty" description:"list of metadata files"` +} + +// MetadataFile expresses information about a file holding pod metadata. +// NOTE: Deprecated in favor of DownwardAPIVolumeFile +type MetadataFile struct { + // Required: Name is the name of the file + Name string `json:"name" description:"the name of the file to be created"` + // Required: Selects a field of the pod: only annotations, labels, name and namespace are supported. + FieldRef ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod. Supported fields: metadata.annotations, metadata.labels, metadata.name, metadata.namespace"` +} + // DownwardAPIVolumeSource represents a volume containing downward API info type DownwardAPIVolumeSource struct { // Items is a list of downward API volume file diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/conversion_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/conversion_generated.go new file mode 100644 index 000000000000..2035113a1a95 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/experimental/v1/conversion_generated.go @@ -0,0 +1,2494 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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. +*/ + +// DO NOT EDIT. THIS FILE IS AUTO-GENERATED BY $KUBEROOT/hack/update-generated-conversions.sh + +package v1 + +import ( + reflect "reflect" + + api "k8s.io/kubernetes/pkg/api" + resource "k8s.io/kubernetes/pkg/api/resource" + v1 "k8s.io/kubernetes/pkg/api/v1" + experimental "k8s.io/kubernetes/pkg/apis/experimental" + conversion "k8s.io/kubernetes/pkg/conversion" +) + +func convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource(in *api.AWSElasticBlockStoreVolumeSource, out *v1.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.AWSElasticBlockStoreVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_Capabilities_To_v1_Capabilities(in *api.Capabilities, out *v1.Capabilities, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Capabilities))(in) + } + if in.Add != nil { + out.Add = make([]v1.Capability, len(in.Add)) + for i := range in.Add { + out.Add[i] = v1.Capability(in.Add[i]) + } + } else { + out.Add = nil + } + if in.Drop != nil { + out.Drop = make([]v1.Capability, len(in.Drop)) + for i := range in.Drop { + out.Drop[i] = v1.Capability(in.Drop[i]) + } + } else { + out.Drop = nil + } + return nil +} + +func convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource(in *api.CephFSVolumeSource, out *v1.CephFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.CephFSVolumeSource))(in) + } + if in.Monitors != nil { + out.Monitors = make([]string, len(in.Monitors)) + for i := range in.Monitors { + out.Monitors[i] = in.Monitors[i] + } + } else { + out.Monitors = nil + } + out.User = in.User + out.SecretFile = in.SecretFile + if in.SecretRef != nil { + out.SecretRef = new(v1.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_CinderVolumeSource_To_v1_CinderVolumeSource(in *api.CinderVolumeSource, out *v1.CinderVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.CinderVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_Container_To_v1_Container(in *api.Container, out *v1.Container, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Container))(in) + } + out.Name = in.Name + out.Image = in.Image + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + if in.Args != nil { + out.Args = make([]string, len(in.Args)) + for i := range in.Args { + out.Args[i] = in.Args[i] + } + } else { + out.Args = nil + } + out.WorkingDir = in.WorkingDir + if in.Ports != nil { + out.Ports = make([]v1.ContainerPort, len(in.Ports)) + for i := range in.Ports { + if err := convert_api_ContainerPort_To_v1_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.Env != nil { + out.Env = make([]v1.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_api_EnvVar_To_v1_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + if err := convert_api_ResourceRequirements_To_v1_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { + return err + } + if in.VolumeMounts != nil { + out.VolumeMounts = make([]v1.VolumeMount, len(in.VolumeMounts)) + for i := range in.VolumeMounts { + if err := convert_api_VolumeMount_To_v1_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { + return err + } + } + } else { + out.VolumeMounts = nil + } + if in.LivenessProbe != nil { + out.LivenessProbe = new(v1.Probe) + if err := convert_api_Probe_To_v1_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { + return err + } + } else { + out.LivenessProbe = nil + } + if in.ReadinessProbe != nil { + out.ReadinessProbe = new(v1.Probe) + if err := convert_api_Probe_To_v1_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { + return err + } + } else { + out.ReadinessProbe = nil + } + if in.Lifecycle != nil { + out.Lifecycle = new(v1.Lifecycle) + if err := convert_api_Lifecycle_To_v1_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { + return err + } + } else { + out.Lifecycle = nil + } + out.TerminationMessagePath = in.TerminationMessagePath + out.ImagePullPolicy = v1.PullPolicy(in.ImagePullPolicy) + if in.SecurityContext != nil { + out.SecurityContext = new(v1.SecurityContext) + if err := convert_api_SecurityContext_To_v1_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + out.Stdin = in.Stdin + out.TTY = in.TTY + return nil +} + +func convert_api_ContainerPort_To_v1_ContainerPort(in *api.ContainerPort, out *v1.ContainerPort, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ContainerPort))(in) + } + out.Name = in.Name + out.HostPort = in.HostPort + out.ContainerPort = in.ContainerPort + out.Protocol = v1.Protocol(in.Protocol) + out.HostIP = in.HostIP + return nil +} + +func convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in *api.DownwardAPIVolumeFile, out *v1.DownwardAPIVolumeFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeFile))(in) + } + out.Path = in.Path + if err := convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + return nil +} + +func convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in *api.DownwardAPIVolumeSource, out *v1.DownwardAPIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]v1.DownwardAPIVolumeFile, len(in.Items)) + for i := range in.Items { + if err := convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource(in *api.EmptyDirVolumeSource, out *v1.EmptyDirVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EmptyDirVolumeSource))(in) + } + out.Medium = v1.StorageMedium(in.Medium) + return nil +} + +func convert_api_EnvVar_To_v1_EnvVar(in *api.EnvVar, out *v1.EnvVar, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EnvVar))(in) + } + out.Name = in.Name + out.Value = in.Value + if in.ValueFrom != nil { + out.ValueFrom = new(v1.EnvVarSource) + if err := convert_api_EnvVarSource_To_v1_EnvVarSource(in.ValueFrom, out.ValueFrom, s); err != nil { + return err + } + } else { + out.ValueFrom = nil + } + return nil +} + +func convert_api_EnvVarSource_To_v1_EnvVarSource(in *api.EnvVarSource, out *v1.EnvVarSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EnvVarSource))(in) + } + if in.FieldRef != nil { + out.FieldRef = new(v1.ObjectFieldSelector) + if err := convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in.FieldRef, out.FieldRef, s); err != nil { + return err + } + } else { + out.FieldRef = nil + } + return nil +} + +func convert_api_ExecAction_To_v1_ExecAction(in *api.ExecAction, out *v1.ExecAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ExecAction))(in) + } + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + return nil +} + +func convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource(in *api.GCEPersistentDiskVolumeSource, out *v1.GCEPersistentDiskVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.GCEPersistentDiskVolumeSource))(in) + } + out.PDName = in.PDName + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource(in *api.GitRepoVolumeSource, out *v1.GitRepoVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.GitRepoVolumeSource))(in) + } + out.Repository = in.Repository + out.Revision = in.Revision + return nil +} + +func convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource(in *api.GlusterfsVolumeSource, out *v1.GlusterfsVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.GlusterfsVolumeSource))(in) + } + out.EndpointsName = in.EndpointsName + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, out *v1.HTTPGetAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.HTTPGetAction))(in) + } + out.Path = in.Path + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + out.Host = in.Host + out.Scheme = v1.URIScheme(in.Scheme) + return nil +} + +func convert_api_Handler_To_v1_Handler(in *api.Handler, out *v1.Handler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Handler))(in) + } + if in.Exec != nil { + out.Exec = new(v1.ExecAction) + if err := convert_api_ExecAction_To_v1_ExecAction(in.Exec, out.Exec, s); err != nil { + return err + } + } else { + out.Exec = nil + } + if in.HTTPGet != nil { + out.HTTPGet = new(v1.HTTPGetAction) + if err := convert_api_HTTPGetAction_To_v1_HTTPGetAction(in.HTTPGet, out.HTTPGet, s); err != nil { + return err + } + } else { + out.HTTPGet = nil + } + if in.TCPSocket != nil { + out.TCPSocket = new(v1.TCPSocketAction) + if err := convert_api_TCPSocketAction_To_v1_TCPSocketAction(in.TCPSocket, out.TCPSocket, s); err != nil { + return err + } + } else { + out.TCPSocket = nil + } + return nil +} + +func convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource(in *api.HostPathVolumeSource, out *v1.HostPathVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.HostPathVolumeSource))(in) + } + out.Path = in.Path + return nil +} + +func convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in *api.ISCSIVolumeSource, out *v1.ISCSIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ISCSIVolumeSource))(in) + } + out.TargetPortal = in.TargetPortal + out.IQN = in.IQN + out.Lun = in.Lun + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_Lifecycle_To_v1_Lifecycle(in *api.Lifecycle, out *v1.Lifecycle, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Lifecycle))(in) + } + if in.PostStart != nil { + out.PostStart = new(v1.Handler) + if err := convert_api_Handler_To_v1_Handler(in.PostStart, out.PostStart, s); err != nil { + return err + } + } else { + out.PostStart = nil + } + if in.PreStop != nil { + out.PreStop = new(v1.Handler) + if err := convert_api_Handler_To_v1_Handler(in.PreStop, out.PreStop, s); err != nil { + return err + } + } else { + out.PreStop = nil + } + return nil +} + +func convert_api_ListMeta_To_v1_ListMeta(in *api.ListMeta, out *v1.ListMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ListMeta))(in) + } + out.SelfLink = in.SelfLink + out.ResourceVersion = in.ResourceVersion + return nil +} + +func convert_api_LocalObjectReference_To_v1_LocalObjectReference(in *api.LocalObjectReference, out *v1.LocalObjectReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LocalObjectReference))(in) + } + out.Name = in.Name + return nil +} + +func convert_api_NFSVolumeSource_To_v1_NFSVolumeSource(in *api.NFSVolumeSource, out *v1.NFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NFSVolumeSource))(in) + } + out.Server = in.Server + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *api.ObjectFieldSelector, out *v1.ObjectFieldSelector, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ObjectFieldSelector))(in) + } + out.APIVersion = in.APIVersion + out.FieldPath = in.FieldPath + return nil +} + +func convert_api_ObjectMeta_To_v1_ObjectMeta(in *api.ObjectMeta, out *v1.ObjectMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ObjectMeta))(in) + } + out.Name = in.Name + out.GenerateName = in.GenerateName + out.Namespace = in.Namespace + out.SelfLink = in.SelfLink + out.UID = in.UID + out.ResourceVersion = in.ResourceVersion + out.Generation = in.Generation + if err := s.Convert(&in.CreationTimestamp, &out.CreationTimestamp, 0); err != nil { + return err + } + if in.DeletionTimestamp != nil { + if err := s.Convert(&in.DeletionTimestamp, &out.DeletionTimestamp, 0); err != nil { + return err + } + } else { + out.DeletionTimestamp = nil + } + if in.DeletionGracePeriodSeconds != nil { + out.DeletionGracePeriodSeconds = new(int64) + *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds + } else { + out.DeletionGracePeriodSeconds = nil + } + if in.Labels != nil { + out.Labels = make(map[string]string) + for key, val := range in.Labels { + out.Labels[key] = val + } + } else { + out.Labels = nil + } + if in.Annotations != nil { + out.Annotations = make(map[string]string) + for key, val := range in.Annotations { + out.Annotations[key] = val + } + } else { + out.Annotations = nil + } + return nil +} + +func convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource(in *api.PersistentVolumeClaimVolumeSource, out *v1.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolumeClaimVolumeSource))(in) + } + out.ClaimName = in.ClaimName + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *v1.PodTemplateSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodTemplateSpec))(in) + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_PodSpec_To_v1_PodSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_api_Probe_To_v1_Probe(in *api.Probe, out *v1.Probe, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Probe))(in) + } + if err := convert_api_Handler_To_v1_Handler(&in.Handler, &out.Handler, s); err != nil { + return err + } + out.InitialDelaySeconds = in.InitialDelaySeconds + out.TimeoutSeconds = in.TimeoutSeconds + return nil +} + +func convert_api_RBDVolumeSource_To_v1_RBDVolumeSource(in *api.RBDVolumeSource, out *v1.RBDVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.RBDVolumeSource))(in) + } + if in.CephMonitors != nil { + out.CephMonitors = make([]string, len(in.CephMonitors)) + for i := range in.CephMonitors { + out.CephMonitors[i] = in.CephMonitors[i] + } + } else { + out.CephMonitors = nil + } + out.RBDImage = in.RBDImage + out.FSType = in.FSType + out.RBDPool = in.RBDPool + out.RadosUser = in.RadosUser + out.Keyring = in.Keyring + if in.SecretRef != nil { + out.SecretRef = new(v1.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_ResourceRequirements_To_v1_ResourceRequirements(in *api.ResourceRequirements, out *v1.ResourceRequirements, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ResourceRequirements))(in) + } + if in.Limits != nil { + out.Limits = make(v1.ResourceList) + for key, val := range in.Limits { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Limits[v1.ResourceName(key)] = newVal + } + } else { + out.Limits = nil + } + if in.Requests != nil { + out.Requests = make(v1.ResourceList) + for key, val := range in.Requests { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Requests[v1.ResourceName(key)] = newVal + } + } else { + out.Requests = nil + } + return nil +} + +func convert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, out *v1.SELinuxOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SELinuxOptions))(in) + } + out.User = in.User + out.Role = in.Role + out.Type = in.Type + out.Level = in.Level + return nil +} + +func convert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretVolumeSource, out *v1.SecretVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SecretVolumeSource))(in) + } + out.SecretName = in.SecretName + return nil +} + +func convert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityContext, out *v1.SecurityContext, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SecurityContext))(in) + } + if in.Capabilities != nil { + out.Capabilities = new(v1.Capabilities) + if err := convert_api_Capabilities_To_v1_Capabilities(in.Capabilities, out.Capabilities, s); err != nil { + return err + } + } else { + out.Capabilities = nil + } + if in.Privileged != nil { + out.Privileged = new(bool) + *out.Privileged = *in.Privileged + } else { + out.Privileged = nil + } + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(v1.SELinuxOptions) + if err := convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + if in.RunAsUser != nil { + out.RunAsUser = new(int64) + *out.RunAsUser = *in.RunAsUser + } else { + out.RunAsUser = nil + } + out.RunAsNonRoot = in.RunAsNonRoot + return nil +} + +func convert_api_TCPSocketAction_To_v1_TCPSocketAction(in *api.TCPSocketAction, out *v1.TCPSocketAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.TCPSocketAction))(in) + } + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + return nil +} + +func convert_api_TypeMeta_To_v1_TypeMeta(in *api.TypeMeta, out *v1.TypeMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.TypeMeta))(in) + } + out.Kind = in.Kind + out.APIVersion = in.APIVersion + return nil +} + +func convert_api_Volume_To_v1_Volume(in *api.Volume, out *v1.Volume, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Volume))(in) + } + out.Name = in.Name + if err := convert_api_VolumeSource_To_v1_VolumeSource(&in.VolumeSource, &out.VolumeSource, s); err != nil { + return err + } + return nil +} + +func convert_api_VolumeMount_To_v1_VolumeMount(in *api.VolumeMount, out *v1.VolumeMount, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.VolumeMount))(in) + } + out.Name = in.Name + out.ReadOnly = in.ReadOnly + out.MountPath = in.MountPath + return nil +} + +func convert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in *v1.AWSElasticBlockStoreVolumeSource, out *api.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.AWSElasticBlockStoreVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_Capabilities_To_api_Capabilities(in *v1.Capabilities, out *api.Capabilities, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Capabilities))(in) + } + if in.Add != nil { + out.Add = make([]api.Capability, len(in.Add)) + for i := range in.Add { + out.Add[i] = api.Capability(in.Add[i]) + } + } else { + out.Add = nil + } + if in.Drop != nil { + out.Drop = make([]api.Capability, len(in.Drop)) + for i := range in.Drop { + out.Drop[i] = api.Capability(in.Drop[i]) + } + } else { + out.Drop = nil + } + return nil +} + +func convert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource(in *v1.CephFSVolumeSource, out *api.CephFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.CephFSVolumeSource))(in) + } + if in.Monitors != nil { + out.Monitors = make([]string, len(in.Monitors)) + for i := range in.Monitors { + out.Monitors[i] = in.Monitors[i] + } + } else { + out.Monitors = nil + } + out.User = in.User + out.SecretFile = in.SecretFile + if in.SecretRef != nil { + out.SecretRef = new(api.LocalObjectReference) + if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_CinderVolumeSource_To_api_CinderVolumeSource(in *v1.CinderVolumeSource, out *api.CinderVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.CinderVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_Container_To_api_Container(in *v1.Container, out *api.Container, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Container))(in) + } + out.Name = in.Name + out.Image = in.Image + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + if in.Args != nil { + out.Args = make([]string, len(in.Args)) + for i := range in.Args { + out.Args[i] = in.Args[i] + } + } else { + out.Args = nil + } + out.WorkingDir = in.WorkingDir + if in.Ports != nil { + out.Ports = make([]api.ContainerPort, len(in.Ports)) + for i := range in.Ports { + if err := convert_v1_ContainerPort_To_api_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.Env != nil { + out.Env = make([]api.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_v1_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + if err := convert_v1_ResourceRequirements_To_api_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { + return err + } + if in.VolumeMounts != nil { + out.VolumeMounts = make([]api.VolumeMount, len(in.VolumeMounts)) + for i := range in.VolumeMounts { + if err := convert_v1_VolumeMount_To_api_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { + return err + } + } + } else { + out.VolumeMounts = nil + } + if in.LivenessProbe != nil { + out.LivenessProbe = new(api.Probe) + if err := convert_v1_Probe_To_api_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { + return err + } + } else { + out.LivenessProbe = nil + } + if in.ReadinessProbe != nil { + out.ReadinessProbe = new(api.Probe) + if err := convert_v1_Probe_To_api_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { + return err + } + } else { + out.ReadinessProbe = nil + } + if in.Lifecycle != nil { + out.Lifecycle = new(api.Lifecycle) + if err := convert_v1_Lifecycle_To_api_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { + return err + } + } else { + out.Lifecycle = nil + } + out.TerminationMessagePath = in.TerminationMessagePath + out.ImagePullPolicy = api.PullPolicy(in.ImagePullPolicy) + if in.SecurityContext != nil { + out.SecurityContext = new(api.SecurityContext) + if err := convert_v1_SecurityContext_To_api_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + out.Stdin = in.Stdin + out.TTY = in.TTY + return nil +} + +func convert_v1_ContainerPort_To_api_ContainerPort(in *v1.ContainerPort, out *api.ContainerPort, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ContainerPort))(in) + } + out.Name = in.Name + out.HostPort = in.HostPort + out.ContainerPort = in.ContainerPort + out.Protocol = api.Protocol(in.Protocol) + out.HostIP = in.HostIP + return nil +} + +func convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *v1.DownwardAPIVolumeFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.DownwardAPIVolumeFile))(in) + } + out.Path = in.Path + if err := convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + return nil +} + +func convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *v1.DownwardAPIVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.DownwardAPIVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]api.DownwardAPIVolumeFile, len(in.Items)) + for i := range in.Items { + if err := convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in *v1.EmptyDirVolumeSource, out *api.EmptyDirVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.EmptyDirVolumeSource))(in) + } + out.Medium = api.StorageMedium(in.Medium) + return nil +} + +func convert_v1_EnvVar_To_api_EnvVar(in *v1.EnvVar, out *api.EnvVar, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.EnvVar))(in) + } + out.Name = in.Name + out.Value = in.Value + if in.ValueFrom != nil { + out.ValueFrom = new(api.EnvVarSource) + if err := convert_v1_EnvVarSource_To_api_EnvVarSource(in.ValueFrom, out.ValueFrom, s); err != nil { + return err + } + } else { + out.ValueFrom = nil + } + return nil +} + +func convert_v1_EnvVarSource_To_api_EnvVarSource(in *v1.EnvVarSource, out *api.EnvVarSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.EnvVarSource))(in) + } + if in.FieldRef != nil { + out.FieldRef = new(api.ObjectFieldSelector) + if err := convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in.FieldRef, out.FieldRef, s); err != nil { + return err + } + } else { + out.FieldRef = nil + } + return nil +} + +func convert_v1_ExecAction_To_api_ExecAction(in *v1.ExecAction, out *api.ExecAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ExecAction))(in) + } + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + return nil +} + +func convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in *v1.GCEPersistentDiskVolumeSource, out *api.GCEPersistentDiskVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.GCEPersistentDiskVolumeSource))(in) + } + out.PDName = in.PDName + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in *v1.GitRepoVolumeSource, out *api.GitRepoVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.GitRepoVolumeSource))(in) + } + out.Repository = in.Repository + out.Revision = in.Revision + return nil +} + +func convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in *v1.GlusterfsVolumeSource, out *api.GlusterfsVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.GlusterfsVolumeSource))(in) + } + out.EndpointsName = in.EndpointsName + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_HTTPGetAction_To_api_HTTPGetAction(in *v1.HTTPGetAction, out *api.HTTPGetAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.HTTPGetAction))(in) + } + out.Path = in.Path + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + out.Host = in.Host + out.Scheme = api.URIScheme(in.Scheme) + return nil +} + +func convert_v1_Handler_To_api_Handler(in *v1.Handler, out *api.Handler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Handler))(in) + } + if in.Exec != nil { + out.Exec = new(api.ExecAction) + if err := convert_v1_ExecAction_To_api_ExecAction(in.Exec, out.Exec, s); err != nil { + return err + } + } else { + out.Exec = nil + } + if in.HTTPGet != nil { + out.HTTPGet = new(api.HTTPGetAction) + if err := convert_v1_HTTPGetAction_To_api_HTTPGetAction(in.HTTPGet, out.HTTPGet, s); err != nil { + return err + } + } else { + out.HTTPGet = nil + } + if in.TCPSocket != nil { + out.TCPSocket = new(api.TCPSocketAction) + if err := convert_v1_TCPSocketAction_To_api_TCPSocketAction(in.TCPSocket, out.TCPSocket, s); err != nil { + return err + } + } else { + out.TCPSocket = nil + } + return nil +} + +func convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource(in *v1.HostPathVolumeSource, out *api.HostPathVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.HostPathVolumeSource))(in) + } + out.Path = in.Path + return nil +} + +func convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in *v1.ISCSIVolumeSource, out *api.ISCSIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ISCSIVolumeSource))(in) + } + out.TargetPortal = in.TargetPortal + out.IQN = in.IQN + out.Lun = in.Lun + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_Lifecycle_To_api_Lifecycle(in *v1.Lifecycle, out *api.Lifecycle, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Lifecycle))(in) + } + if in.PostStart != nil { + out.PostStart = new(api.Handler) + if err := convert_v1_Handler_To_api_Handler(in.PostStart, out.PostStart, s); err != nil { + return err + } + } else { + out.PostStart = nil + } + if in.PreStop != nil { + out.PreStop = new(api.Handler) + if err := convert_v1_Handler_To_api_Handler(in.PreStop, out.PreStop, s); err != nil { + return err + } + } else { + out.PreStop = nil + } + return nil +} + +func convert_v1_ListMeta_To_api_ListMeta(in *v1.ListMeta, out *api.ListMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ListMeta))(in) + } + out.SelfLink = in.SelfLink + out.ResourceVersion = in.ResourceVersion + return nil +} + +func convert_v1_LocalObjectReference_To_api_LocalObjectReference(in *v1.LocalObjectReference, out *api.LocalObjectReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.LocalObjectReference))(in) + } + out.Name = in.Name + return nil +} + +func convert_v1_NFSVolumeSource_To_api_NFSVolumeSource(in *v1.NFSVolumeSource, out *api.NFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.NFSVolumeSource))(in) + } + out.Server = in.Server + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *v1.ObjectFieldSelector, out *api.ObjectFieldSelector, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ObjectFieldSelector))(in) + } + out.APIVersion = in.APIVersion + out.FieldPath = in.FieldPath + return nil +} + +func convert_v1_ObjectMeta_To_api_ObjectMeta(in *v1.ObjectMeta, out *api.ObjectMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ObjectMeta))(in) + } + out.Name = in.Name + out.GenerateName = in.GenerateName + out.Namespace = in.Namespace + out.SelfLink = in.SelfLink + out.UID = in.UID + out.ResourceVersion = in.ResourceVersion + out.Generation = in.Generation + if err := s.Convert(&in.CreationTimestamp, &out.CreationTimestamp, 0); err != nil { + return err + } + if in.DeletionTimestamp != nil { + if err := s.Convert(&in.DeletionTimestamp, &out.DeletionTimestamp, 0); err != nil { + return err + } + } else { + out.DeletionTimestamp = nil + } + if in.DeletionGracePeriodSeconds != nil { + out.DeletionGracePeriodSeconds = new(int64) + *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds + } else { + out.DeletionGracePeriodSeconds = nil + } + if in.Labels != nil { + out.Labels = make(map[string]string) + for key, val := range in.Labels { + out.Labels[key] = val + } + } else { + out.Labels = nil + } + if in.Annotations != nil { + out.Annotations = make(map[string]string) + for key, val := range in.Annotations { + out.Annotations[key] = val + } + } else { + out.Annotations = nil + } + return nil +} + +func convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in *v1.PersistentVolumeClaimVolumeSource, out *api.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.PersistentVolumeClaimVolumeSource))(in) + } + out.ClaimName = in.ClaimName + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *v1.PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.PodTemplateSpec))(in) + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1_PodSpec_To_api_PodSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_v1_Probe_To_api_Probe(in *v1.Probe, out *api.Probe, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Probe))(in) + } + if err := convert_v1_Handler_To_api_Handler(&in.Handler, &out.Handler, s); err != nil { + return err + } + out.InitialDelaySeconds = in.InitialDelaySeconds + out.TimeoutSeconds = in.TimeoutSeconds + return nil +} + +func convert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in *v1.RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.RBDVolumeSource))(in) + } + if in.CephMonitors != nil { + out.CephMonitors = make([]string, len(in.CephMonitors)) + for i := range in.CephMonitors { + out.CephMonitors[i] = in.CephMonitors[i] + } + } else { + out.CephMonitors = nil + } + out.RBDImage = in.RBDImage + out.FSType = in.FSType + out.RBDPool = in.RBDPool + out.RadosUser = in.RadosUser + out.Keyring = in.Keyring + if in.SecretRef != nil { + out.SecretRef = new(api.LocalObjectReference) + if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1_ResourceRequirements_To_api_ResourceRequirements(in *v1.ResourceRequirements, out *api.ResourceRequirements, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ResourceRequirements))(in) + } + if in.Limits != nil { + out.Limits = make(api.ResourceList) + for key, val := range in.Limits { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Limits[api.ResourceName(key)] = newVal + } + } else { + out.Limits = nil + } + if in.Requests != nil { + out.Requests = make(api.ResourceList) + for key, val := range in.Requests { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Requests[api.ResourceName(key)] = newVal + } + } else { + out.Requests = nil + } + return nil +} + +func convert_v1_SELinuxOptions_To_api_SELinuxOptions(in *v1.SELinuxOptions, out *api.SELinuxOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.SELinuxOptions))(in) + } + out.User = in.User + out.Role = in.Role + out.Type = in.Type + out.Level = in.Level + return nil +} + +func convert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *v1.SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.SecretVolumeSource))(in) + } + out.SecretName = in.SecretName + return nil +} + +func convert_v1_SecurityContext_To_api_SecurityContext(in *v1.SecurityContext, out *api.SecurityContext, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.SecurityContext))(in) + } + if in.Capabilities != nil { + out.Capabilities = new(api.Capabilities) + if err := convert_v1_Capabilities_To_api_Capabilities(in.Capabilities, out.Capabilities, s); err != nil { + return err + } + } else { + out.Capabilities = nil + } + if in.Privileged != nil { + out.Privileged = new(bool) + *out.Privileged = *in.Privileged + } else { + out.Privileged = nil + } + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(api.SELinuxOptions) + if err := convert_v1_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + if in.RunAsUser != nil { + out.RunAsUser = new(int64) + *out.RunAsUser = *in.RunAsUser + } else { + out.RunAsUser = nil + } + out.RunAsNonRoot = in.RunAsNonRoot + return nil +} + +func convert_v1_TCPSocketAction_To_api_TCPSocketAction(in *v1.TCPSocketAction, out *api.TCPSocketAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.TCPSocketAction))(in) + } + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + return nil +} + +func convert_v1_TypeMeta_To_api_TypeMeta(in *v1.TypeMeta, out *api.TypeMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.TypeMeta))(in) + } + out.Kind = in.Kind + out.APIVersion = in.APIVersion + return nil +} + +func convert_v1_Volume_To_api_Volume(in *v1.Volume, out *api.Volume, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Volume))(in) + } + out.Name = in.Name + if err := convert_v1_VolumeSource_To_api_VolumeSource(&in.VolumeSource, &out.VolumeSource, s); err != nil { + return err + } + return nil +} + +func convert_v1_VolumeMount_To_api_VolumeMount(in *v1.VolumeMount, out *api.VolumeMount, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.VolumeMount))(in) + } + out.Name = in.Name + out.ReadOnly = in.ReadOnly + out.MountPath = in.MountPath + return nil +} + +func convert_experimental_APIVersion_To_v1_APIVersion(in *experimental.APIVersion, out *APIVersion, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.APIVersion))(in) + } + out.Name = in.Name + out.APIGroup = in.APIGroup + return nil +} + +func convert_experimental_DaemonSet_To_v1_DaemonSet(in *experimental.DaemonSet, out *DaemonSet, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.DaemonSet))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_experimental_DaemonSetSpec_To_v1_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_experimental_DaemonSetStatus_To_v1_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_experimental_DaemonSetList_To_v1_DaemonSetList(in *experimental.DaemonSetList, out *DaemonSetList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.DaemonSetList))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]DaemonSet, len(in.Items)) + for i := range in.Items { + if err := convert_experimental_DaemonSet_To_v1_DaemonSet(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_experimental_DaemonSetSpec_To_v1_DaemonSetSpec(in *experimental.DaemonSetSpec, out *DaemonSetSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.DaemonSetSpec))(in) + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(v1.PodTemplateSpec) + if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + return nil +} + +func convert_experimental_DaemonSetStatus_To_v1_DaemonSetStatus(in *experimental.DaemonSetStatus, out *DaemonSetStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.DaemonSetStatus))(in) + } + out.CurrentNumberScheduled = in.CurrentNumberScheduled + out.NumberMisscheduled = in.NumberMisscheduled + out.DesiredNumberScheduled = in.DesiredNumberScheduled + return nil +} + +func convert_experimental_Deployment_To_v1_Deployment(in *experimental.Deployment, out *Deployment, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.Deployment))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_experimental_DeploymentSpec_To_v1_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_experimental_DeploymentStatus_To_v1_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_experimental_DeploymentList_To_v1_DeploymentList(in *experimental.DeploymentList, out *DeploymentList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.DeploymentList))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Deployment, len(in.Items)) + for i := range in.Items { + if err := convert_experimental_Deployment_To_v1_Deployment(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_experimental_DeploymentStatus_To_v1_DeploymentStatus(in *experimental.DeploymentStatus, out *DeploymentStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.DeploymentStatus))(in) + } + out.Replicas = in.Replicas + out.UpdatedReplicas = in.UpdatedReplicas + return nil +} + +func convert_experimental_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(in *experimental.HorizontalPodAutoscaler, out *HorizontalPodAutoscaler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.HorizontalPodAutoscaler))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_experimental_HorizontalPodAutoscalerSpec_To_v1_HorizontalPodAutoscalerSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if in.Status != nil { + out.Status = new(HorizontalPodAutoscalerStatus) + if err := convert_experimental_HorizontalPodAutoscalerStatus_To_v1_HorizontalPodAutoscalerStatus(in.Status, out.Status, s); err != nil { + return err + } + } else { + out.Status = nil + } + return nil +} + +func convert_experimental_HorizontalPodAutoscalerList_To_v1_HorizontalPodAutoscalerList(in *experimental.HorizontalPodAutoscalerList, out *HorizontalPodAutoscalerList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.HorizontalPodAutoscalerList))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]HorizontalPodAutoscaler, len(in.Items)) + for i := range in.Items { + if err := convert_experimental_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_experimental_HorizontalPodAutoscalerSpec_To_v1_HorizontalPodAutoscalerSpec(in *experimental.HorizontalPodAutoscalerSpec, out *HorizontalPodAutoscalerSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.HorizontalPodAutoscalerSpec))(in) + } + if in.ScaleRef != nil { + out.ScaleRef = new(SubresourceReference) + if err := convert_experimental_SubresourceReference_To_v1_SubresourceReference(in.ScaleRef, out.ScaleRef, s); err != nil { + return err + } + } else { + out.ScaleRef = nil + } + out.MinCount = in.MinCount + out.MaxCount = in.MaxCount + if err := convert_experimental_ResourceConsumption_To_v1_ResourceConsumption(&in.Target, &out.Target, s); err != nil { + return err + } + return nil +} + +func convert_experimental_HorizontalPodAutoscalerStatus_To_v1_HorizontalPodAutoscalerStatus(in *experimental.HorizontalPodAutoscalerStatus, out *HorizontalPodAutoscalerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.HorizontalPodAutoscalerStatus))(in) + } + out.CurrentReplicas = in.CurrentReplicas + out.DesiredReplicas = in.DesiredReplicas + if in.CurrentConsumption != nil { + out.CurrentConsumption = new(ResourceConsumption) + if err := convert_experimental_ResourceConsumption_To_v1_ResourceConsumption(in.CurrentConsumption, out.CurrentConsumption, s); err != nil { + return err + } + } else { + out.CurrentConsumption = nil + } + if in.LastScaleTimestamp != nil { + if err := s.Convert(&in.LastScaleTimestamp, &out.LastScaleTimestamp, 0); err != nil { + return err + } + } else { + out.LastScaleTimestamp = nil + } + return nil +} + +func convert_experimental_Job_To_v1_Job(in *experimental.Job, out *Job, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.Job))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_experimental_JobSpec_To_v1_JobSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_experimental_JobStatus_To_v1_JobStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_experimental_JobCondition_To_v1_JobCondition(in *experimental.JobCondition, out *JobCondition, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.JobCondition))(in) + } + out.Type = JobConditionType(in.Type) + out.Status = v1.ConditionStatus(in.Status) + if err := s.Convert(&in.LastProbeTime, &out.LastProbeTime, 0); err != nil { + return err + } + if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message + return nil +} + +func convert_experimental_JobList_To_v1_JobList(in *experimental.JobList, out *JobList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.JobList))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Job, len(in.Items)) + for i := range in.Items { + if err := convert_experimental_Job_To_v1_Job(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_experimental_JobSpec_To_v1_JobSpec(in *experimental.JobSpec, out *JobSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.JobSpec))(in) + } + if in.Parallelism != nil { + out.Parallelism = new(int) + *out.Parallelism = *in.Parallelism + } else { + out.Parallelism = nil + } + if in.Completions != nil { + out.Completions = new(int) + *out.Completions = *in.Completions + } else { + out.Completions = nil + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(v1.PodTemplateSpec) + if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + return nil +} + +func convert_experimental_JobStatus_To_v1_JobStatus(in *experimental.JobStatus, out *JobStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.JobStatus))(in) + } + if in.Conditions != nil { + out.Conditions = make([]JobCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := convert_experimental_JobCondition_To_v1_JobCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + if in.StartTime != nil { + if err := s.Convert(&in.StartTime, &out.StartTime, 0); err != nil { + return err + } + } else { + out.StartTime = nil + } + if in.CompletionTime != nil { + if err := s.Convert(&in.CompletionTime, &out.CompletionTime, 0); err != nil { + return err + } + } else { + out.CompletionTime = nil + } + out.Active = in.Active + out.Successful = in.Successful + out.Unsuccessful = in.Unsuccessful + return nil +} + +func convert_experimental_ReplicationControllerDummy_To_v1_ReplicationControllerDummy(in *experimental.ReplicationControllerDummy, out *ReplicationControllerDummy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.ReplicationControllerDummy))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + return nil +} + +func convert_experimental_ResourceConsumption_To_v1_ResourceConsumption(in *experimental.ResourceConsumption, out *ResourceConsumption, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.ResourceConsumption))(in) + } + out.Resource = v1.ResourceName(in.Resource) + if err := s.Convert(&in.Quantity, &out.Quantity, 0); err != nil { + return err + } + return nil +} + +func convert_experimental_Scale_To_v1_Scale(in *experimental.Scale, out *Scale, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.Scale))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_experimental_ScaleSpec_To_v1_ScaleSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_experimental_ScaleStatus_To_v1_ScaleStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_experimental_ScaleSpec_To_v1_ScaleSpec(in *experimental.ScaleSpec, out *ScaleSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.ScaleSpec))(in) + } + out.Replicas = in.Replicas + return nil +} + +func convert_experimental_ScaleStatus_To_v1_ScaleStatus(in *experimental.ScaleStatus, out *ScaleStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.ScaleStatus))(in) + } + out.Replicas = in.Replicas + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + return nil +} + +func convert_experimental_SubresourceReference_To_v1_SubresourceReference(in *experimental.SubresourceReference, out *SubresourceReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.SubresourceReference))(in) + } + out.Kind = in.Kind + out.Namespace = in.Namespace + out.Name = in.Name + out.APIVersion = in.APIVersion + out.Subresource = in.Subresource + return nil +} + +func convert_experimental_ThirdPartyResource_To_v1_ThirdPartyResource(in *experimental.ThirdPartyResource, out *ThirdPartyResource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.ThirdPartyResource))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.Description = in.Description + if in.Versions != nil { + out.Versions = make([]APIVersion, len(in.Versions)) + for i := range in.Versions { + if err := convert_experimental_APIVersion_To_v1_APIVersion(&in.Versions[i], &out.Versions[i], s); err != nil { + return err + } + } + } else { + out.Versions = nil + } + return nil +} + +func convert_experimental_ThirdPartyResourceData_To_v1_ThirdPartyResourceData(in *experimental.ThirdPartyResourceData, out *ThirdPartyResourceData, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.ThirdPartyResourceData))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Data, &out.Data, 0); err != nil { + return err + } + return nil +} + +func convert_experimental_ThirdPartyResourceDataList_To_v1_ThirdPartyResourceDataList(in *experimental.ThirdPartyResourceDataList, out *ThirdPartyResourceDataList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.ThirdPartyResourceDataList))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ThirdPartyResourceData, len(in.Items)) + for i := range in.Items { + if err := convert_experimental_ThirdPartyResourceData_To_v1_ThirdPartyResourceData(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_experimental_ThirdPartyResourceList_To_v1_ThirdPartyResourceList(in *experimental.ThirdPartyResourceList, out *ThirdPartyResourceList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*experimental.ThirdPartyResourceList))(in) + } + if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ThirdPartyResource, len(in.Items)) + for i := range in.Items { + if err := convert_experimental_ThirdPartyResource_To_v1_ThirdPartyResource(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1_APIVersion_To_experimental_APIVersion(in *APIVersion, out *experimental.APIVersion, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*APIVersion))(in) + } + out.Name = in.Name + out.APIGroup = in.APIGroup + return nil +} + +func convert_v1_DaemonSet_To_experimental_DaemonSet(in *DaemonSet, out *experimental.DaemonSet, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DaemonSet))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1_DaemonSetSpec_To_experimental_DaemonSetSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1_DaemonSetStatus_To_experimental_DaemonSetStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1_DaemonSetList_To_experimental_DaemonSetList(in *DaemonSetList, out *experimental.DaemonSetList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DaemonSetList))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]experimental.DaemonSet, len(in.Items)) + for i := range in.Items { + if err := convert_v1_DaemonSet_To_experimental_DaemonSet(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1_DaemonSetSpec_To_experimental_DaemonSetSpec(in *DaemonSetSpec, out *experimental.DaemonSetSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DaemonSetSpec))(in) + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(api.PodTemplateSpec) + if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + return nil +} + +func convert_v1_DaemonSetStatus_To_experimental_DaemonSetStatus(in *DaemonSetStatus, out *experimental.DaemonSetStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DaemonSetStatus))(in) + } + out.CurrentNumberScheduled = in.CurrentNumberScheduled + out.NumberMisscheduled = in.NumberMisscheduled + out.DesiredNumberScheduled = in.DesiredNumberScheduled + return nil +} + +func convert_v1_Deployment_To_experimental_Deployment(in *Deployment, out *experimental.Deployment, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Deployment))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1_DeploymentSpec_To_experimental_DeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1_DeploymentStatus_To_experimental_DeploymentStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1_DeploymentList_To_experimental_DeploymentList(in *DeploymentList, out *experimental.DeploymentList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DeploymentList))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]experimental.Deployment, len(in.Items)) + for i := range in.Items { + if err := convert_v1_Deployment_To_experimental_Deployment(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1_DeploymentStatus_To_experimental_DeploymentStatus(in *DeploymentStatus, out *experimental.DeploymentStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DeploymentStatus))(in) + } + out.Replicas = in.Replicas + out.UpdatedReplicas = in.UpdatedReplicas + return nil +} + +func convert_v1_HorizontalPodAutoscaler_To_experimental_HorizontalPodAutoscaler(in *HorizontalPodAutoscaler, out *experimental.HorizontalPodAutoscaler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HorizontalPodAutoscaler))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1_HorizontalPodAutoscalerSpec_To_experimental_HorizontalPodAutoscalerSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if in.Status != nil { + out.Status = new(experimental.HorizontalPodAutoscalerStatus) + if err := convert_v1_HorizontalPodAutoscalerStatus_To_experimental_HorizontalPodAutoscalerStatus(in.Status, out.Status, s); err != nil { + return err + } + } else { + out.Status = nil + } + return nil +} + +func convert_v1_HorizontalPodAutoscalerList_To_experimental_HorizontalPodAutoscalerList(in *HorizontalPodAutoscalerList, out *experimental.HorizontalPodAutoscalerList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HorizontalPodAutoscalerList))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]experimental.HorizontalPodAutoscaler, len(in.Items)) + for i := range in.Items { + if err := convert_v1_HorizontalPodAutoscaler_To_experimental_HorizontalPodAutoscaler(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1_HorizontalPodAutoscalerSpec_To_experimental_HorizontalPodAutoscalerSpec(in *HorizontalPodAutoscalerSpec, out *experimental.HorizontalPodAutoscalerSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HorizontalPodAutoscalerSpec))(in) + } + if in.ScaleRef != nil { + out.ScaleRef = new(experimental.SubresourceReference) + if err := convert_v1_SubresourceReference_To_experimental_SubresourceReference(in.ScaleRef, out.ScaleRef, s); err != nil { + return err + } + } else { + out.ScaleRef = nil + } + out.MinCount = in.MinCount + out.MaxCount = in.MaxCount + if err := convert_v1_ResourceConsumption_To_experimental_ResourceConsumption(&in.Target, &out.Target, s); err != nil { + return err + } + return nil +} + +func convert_v1_HorizontalPodAutoscalerStatus_To_experimental_HorizontalPodAutoscalerStatus(in *HorizontalPodAutoscalerStatus, out *experimental.HorizontalPodAutoscalerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HorizontalPodAutoscalerStatus))(in) + } + out.CurrentReplicas = in.CurrentReplicas + out.DesiredReplicas = in.DesiredReplicas + if in.CurrentConsumption != nil { + out.CurrentConsumption = new(experimental.ResourceConsumption) + if err := convert_v1_ResourceConsumption_To_experimental_ResourceConsumption(in.CurrentConsumption, out.CurrentConsumption, s); err != nil { + return err + } + } else { + out.CurrentConsumption = nil + } + if in.LastScaleTimestamp != nil { + if err := s.Convert(&in.LastScaleTimestamp, &out.LastScaleTimestamp, 0); err != nil { + return err + } + } else { + out.LastScaleTimestamp = nil + } + return nil +} + +func convert_v1_Job_To_experimental_Job(in *Job, out *experimental.Job, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Job))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1_JobSpec_To_experimental_JobSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1_JobStatus_To_experimental_JobStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1_JobCondition_To_experimental_JobCondition(in *JobCondition, out *experimental.JobCondition, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*JobCondition))(in) + } + out.Type = experimental.JobConditionType(in.Type) + out.Status = api.ConditionStatus(in.Status) + if err := s.Convert(&in.LastProbeTime, &out.LastProbeTime, 0); err != nil { + return err + } + if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message + return nil +} + +func convert_v1_JobList_To_experimental_JobList(in *JobList, out *experimental.JobList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*JobList))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]experimental.Job, len(in.Items)) + for i := range in.Items { + if err := convert_v1_Job_To_experimental_Job(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1_JobSpec_To_experimental_JobSpec(in *JobSpec, out *experimental.JobSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*JobSpec))(in) + } + if in.Parallelism != nil { + out.Parallelism = new(int) + *out.Parallelism = *in.Parallelism + } else { + out.Parallelism = nil + } + if in.Completions != nil { + out.Completions = new(int) + *out.Completions = *in.Completions + } else { + out.Completions = nil + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(api.PodTemplateSpec) + if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + return nil +} + +func convert_v1_JobStatus_To_experimental_JobStatus(in *JobStatus, out *experimental.JobStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*JobStatus))(in) + } + if in.Conditions != nil { + out.Conditions = make([]experimental.JobCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := convert_v1_JobCondition_To_experimental_JobCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + if in.StartTime != nil { + if err := s.Convert(&in.StartTime, &out.StartTime, 0); err != nil { + return err + } + } else { + out.StartTime = nil + } + if in.CompletionTime != nil { + if err := s.Convert(&in.CompletionTime, &out.CompletionTime, 0); err != nil { + return err + } + } else { + out.CompletionTime = nil + } + out.Active = in.Active + out.Successful = in.Successful + out.Unsuccessful = in.Unsuccessful + return nil +} + +func convert_v1_ReplicationControllerDummy_To_experimental_ReplicationControllerDummy(in *ReplicationControllerDummy, out *experimental.ReplicationControllerDummy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ReplicationControllerDummy))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + return nil +} + +func convert_v1_ResourceConsumption_To_experimental_ResourceConsumption(in *ResourceConsumption, out *experimental.ResourceConsumption, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ResourceConsumption))(in) + } + out.Resource = api.ResourceName(in.Resource) + if err := s.Convert(&in.Quantity, &out.Quantity, 0); err != nil { + return err + } + return nil +} + +func convert_v1_Scale_To_experimental_Scale(in *Scale, out *experimental.Scale, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Scale))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1_ScaleSpec_To_experimental_ScaleSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1_ScaleStatus_To_experimental_ScaleStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1_ScaleSpec_To_experimental_ScaleSpec(in *ScaleSpec, out *experimental.ScaleSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ScaleSpec))(in) + } + out.Replicas = in.Replicas + return nil +} + +func convert_v1_ScaleStatus_To_experimental_ScaleStatus(in *ScaleStatus, out *experimental.ScaleStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ScaleStatus))(in) + } + out.Replicas = in.Replicas + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + return nil +} + +func convert_v1_SubresourceReference_To_experimental_SubresourceReference(in *SubresourceReference, out *experimental.SubresourceReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SubresourceReference))(in) + } + out.Kind = in.Kind + out.Namespace = in.Namespace + out.Name = in.Name + out.APIVersion = in.APIVersion + out.Subresource = in.Subresource + return nil +} + +func convert_v1_ThirdPartyResource_To_experimental_ThirdPartyResource(in *ThirdPartyResource, out *experimental.ThirdPartyResource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ThirdPartyResource))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.Description = in.Description + if in.Versions != nil { + out.Versions = make([]experimental.APIVersion, len(in.Versions)) + for i := range in.Versions { + if err := convert_v1_APIVersion_To_experimental_APIVersion(&in.Versions[i], &out.Versions[i], s); err != nil { + return err + } + } + } else { + out.Versions = nil + } + return nil +} + +func convert_v1_ThirdPartyResourceData_To_experimental_ThirdPartyResourceData(in *ThirdPartyResourceData, out *experimental.ThirdPartyResourceData, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ThirdPartyResourceData))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Data, &out.Data, 0); err != nil { + return err + } + return nil +} + +func convert_v1_ThirdPartyResourceDataList_To_experimental_ThirdPartyResourceDataList(in *ThirdPartyResourceDataList, out *experimental.ThirdPartyResourceDataList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ThirdPartyResourceDataList))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]experimental.ThirdPartyResourceData, len(in.Items)) + for i := range in.Items { + if err := convert_v1_ThirdPartyResourceData_To_experimental_ThirdPartyResourceData(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1_ThirdPartyResourceList_To_experimental_ThirdPartyResourceList(in *ThirdPartyResourceList, out *experimental.ThirdPartyResourceList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ThirdPartyResourceList))(in) + } + if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]experimental.ThirdPartyResource, len(in.Items)) + for i := range in.Items { + if err := convert_v1_ThirdPartyResource_To_experimental_ThirdPartyResource(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func init() { + err := api.Scheme.AddGeneratedConversionFuncs( + convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource, + convert_api_Capabilities_To_v1_Capabilities, + convert_api_CephFSVolumeSource_To_v1_CephFSVolumeSource, + convert_api_CinderVolumeSource_To_v1_CinderVolumeSource, + convert_api_ContainerPort_To_v1_ContainerPort, + convert_api_Container_To_v1_Container, + convert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile, + convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource, + convert_api_EmptyDirVolumeSource_To_v1_EmptyDirVolumeSource, + convert_api_EnvVarSource_To_v1_EnvVarSource, + convert_api_EnvVar_To_v1_EnvVar, + convert_api_ExecAction_To_v1_ExecAction, + convert_api_GCEPersistentDiskVolumeSource_To_v1_GCEPersistentDiskVolumeSource, + convert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource, + convert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource, + convert_api_HTTPGetAction_To_v1_HTTPGetAction, + convert_api_Handler_To_v1_Handler, + convert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource, + convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource, + convert_api_Lifecycle_To_v1_Lifecycle, + convert_api_ListMeta_To_v1_ListMeta, + convert_api_LocalObjectReference_To_v1_LocalObjectReference, + convert_api_NFSVolumeSource_To_v1_NFSVolumeSource, + convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector, + convert_api_ObjectMeta_To_v1_ObjectMeta, + convert_api_PersistentVolumeClaimVolumeSource_To_v1_PersistentVolumeClaimVolumeSource, + convert_api_PodTemplateSpec_To_v1_PodTemplateSpec, + convert_api_Probe_To_v1_Probe, + convert_api_RBDVolumeSource_To_v1_RBDVolumeSource, + convert_api_ResourceRequirements_To_v1_ResourceRequirements, + convert_api_SELinuxOptions_To_v1_SELinuxOptions, + convert_api_SecretVolumeSource_To_v1_SecretVolumeSource, + convert_api_SecurityContext_To_v1_SecurityContext, + convert_api_TCPSocketAction_To_v1_TCPSocketAction, + convert_api_TypeMeta_To_v1_TypeMeta, + convert_api_VolumeMount_To_v1_VolumeMount, + convert_api_Volume_To_v1_Volume, + convert_experimental_APIVersion_To_v1_APIVersion, + convert_experimental_DaemonSetList_To_v1_DaemonSetList, + convert_experimental_DaemonSetSpec_To_v1_DaemonSetSpec, + convert_experimental_DaemonSetStatus_To_v1_DaemonSetStatus, + convert_experimental_DaemonSet_To_v1_DaemonSet, + convert_experimental_DeploymentList_To_v1_DeploymentList, + convert_experimental_DeploymentStatus_To_v1_DeploymentStatus, + convert_experimental_Deployment_To_v1_Deployment, + convert_experimental_HorizontalPodAutoscalerList_To_v1_HorizontalPodAutoscalerList, + convert_experimental_HorizontalPodAutoscalerSpec_To_v1_HorizontalPodAutoscalerSpec, + convert_experimental_HorizontalPodAutoscalerStatus_To_v1_HorizontalPodAutoscalerStatus, + convert_experimental_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler, + convert_experimental_JobCondition_To_v1_JobCondition, + convert_experimental_JobList_To_v1_JobList, + convert_experimental_JobSpec_To_v1_JobSpec, + convert_experimental_JobStatus_To_v1_JobStatus, + convert_experimental_Job_To_v1_Job, + convert_experimental_ReplicationControllerDummy_To_v1_ReplicationControllerDummy, + convert_experimental_ResourceConsumption_To_v1_ResourceConsumption, + convert_experimental_ScaleSpec_To_v1_ScaleSpec, + convert_experimental_ScaleStatus_To_v1_ScaleStatus, + convert_experimental_Scale_To_v1_Scale, + convert_experimental_SubresourceReference_To_v1_SubresourceReference, + convert_experimental_ThirdPartyResourceDataList_To_v1_ThirdPartyResourceDataList, + convert_experimental_ThirdPartyResourceData_To_v1_ThirdPartyResourceData, + convert_experimental_ThirdPartyResourceList_To_v1_ThirdPartyResourceList, + convert_experimental_ThirdPartyResource_To_v1_ThirdPartyResource, + convert_v1_APIVersion_To_experimental_APIVersion, + convert_v1_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource, + convert_v1_Capabilities_To_api_Capabilities, + convert_v1_CephFSVolumeSource_To_api_CephFSVolumeSource, + convert_v1_CinderVolumeSource_To_api_CinderVolumeSource, + convert_v1_ContainerPort_To_api_ContainerPort, + convert_v1_Container_To_api_Container, + convert_v1_DaemonSetList_To_experimental_DaemonSetList, + convert_v1_DaemonSetSpec_To_experimental_DaemonSetSpec, + convert_v1_DaemonSetStatus_To_experimental_DaemonSetStatus, + convert_v1_DaemonSet_To_experimental_DaemonSet, + convert_v1_DeploymentList_To_experimental_DeploymentList, + convert_v1_DeploymentStatus_To_experimental_DeploymentStatus, + convert_v1_Deployment_To_experimental_Deployment, + convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile, + convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource, + convert_v1_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource, + convert_v1_EnvVarSource_To_api_EnvVarSource, + convert_v1_EnvVar_To_api_EnvVar, + convert_v1_ExecAction_To_api_ExecAction, + convert_v1_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource, + convert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource, + convert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource, + convert_v1_HTTPGetAction_To_api_HTTPGetAction, + convert_v1_Handler_To_api_Handler, + convert_v1_HorizontalPodAutoscalerList_To_experimental_HorizontalPodAutoscalerList, + convert_v1_HorizontalPodAutoscalerSpec_To_experimental_HorizontalPodAutoscalerSpec, + convert_v1_HorizontalPodAutoscalerStatus_To_experimental_HorizontalPodAutoscalerStatus, + convert_v1_HorizontalPodAutoscaler_To_experimental_HorizontalPodAutoscaler, + convert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource, + convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource, + convert_v1_JobCondition_To_experimental_JobCondition, + convert_v1_JobList_To_experimental_JobList, + convert_v1_JobSpec_To_experimental_JobSpec, + convert_v1_JobStatus_To_experimental_JobStatus, + convert_v1_Job_To_experimental_Job, + convert_v1_Lifecycle_To_api_Lifecycle, + convert_v1_ListMeta_To_api_ListMeta, + convert_v1_LocalObjectReference_To_api_LocalObjectReference, + convert_v1_NFSVolumeSource_To_api_NFSVolumeSource, + convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector, + convert_v1_ObjectMeta_To_api_ObjectMeta, + convert_v1_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource, + convert_v1_PodTemplateSpec_To_api_PodTemplateSpec, + convert_v1_Probe_To_api_Probe, + convert_v1_RBDVolumeSource_To_api_RBDVolumeSource, + convert_v1_ReplicationControllerDummy_To_experimental_ReplicationControllerDummy, + convert_v1_ResourceConsumption_To_experimental_ResourceConsumption, + convert_v1_ResourceRequirements_To_api_ResourceRequirements, + convert_v1_SELinuxOptions_To_api_SELinuxOptions, + convert_v1_ScaleSpec_To_experimental_ScaleSpec, + convert_v1_ScaleStatus_To_experimental_ScaleStatus, + convert_v1_Scale_To_experimental_Scale, + convert_v1_SecretVolumeSource_To_api_SecretVolumeSource, + convert_v1_SecurityContext_To_api_SecurityContext, + convert_v1_SubresourceReference_To_experimental_SubresourceReference, + convert_v1_TCPSocketAction_To_api_TCPSocketAction, + convert_v1_ThirdPartyResourceDataList_To_experimental_ThirdPartyResourceDataList, + convert_v1_ThirdPartyResourceData_To_experimental_ThirdPartyResourceData, + convert_v1_ThirdPartyResourceList_To_experimental_ThirdPartyResourceList, + convert_v1_ThirdPartyResource_To_experimental_ThirdPartyResource, + convert_v1_TypeMeta_To_api_TypeMeta, + convert_v1_VolumeMount_To_api_VolumeMount, + convert_v1_Volume_To_api_Volume, + ) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion.go index 0f6ffac777e9..9db46f1a07f2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion.go @@ -37,6 +37,9 @@ func addConversionFuncs() { convert_v1beta1_DeploymentStrategy_To_extensions_DeploymentStrategy, convert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment, convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment, + + convert_api_VolumeSource_To_v1beta1_VolumeSource, + convert_v1beta1_VolumeSource_To_api_VolumeSource, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. @@ -340,3 +343,116 @@ func convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *v1.PodSecurityC } return nil } + +// This will convert our internal represantation of VolumeSource to its v1 representation +// Used for keeping backwards compatibility for the Metadata field +func convert_api_VolumeSource_To_v1beta1_VolumeSource(in *api.VolumeSource, out *v1.VolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.VolumeSource))(in) + } + + if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { + return err + } + + if in.DownwardAPI != nil { + out.DownwardAPI = new(v1.DownwardAPIVolumeSource) + if err := convert_api_DownwardAPIVolumeSource_To_v1_DownwardAPIVolumeSource(in.DownwardAPI, out.DownwardAPI, s); err != nil { + return err + } + + // also copy to Metadata + out.Metadata = new(v1.MetadataVolumeSource) + if err := convert_api_DownwardAPIVolumeSource_To_v1_MetadataVolumeSource(in.DownwardAPI, out.Metadata, s); err != nil { + return err + } + } else { + out.DownwardAPI = nil + } + return nil +} + +// downward -> metadata (api -> v1) +func convert_api_DownwardAPIVolumeSource_To_v1_MetadataVolumeSource(in *api.DownwardAPIVolumeSource, out *v1.MetadataVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]v1.MetadataFile, len(in.Items)) + for i := range in.Items { + if err := convert_api_DownwardAPIVolumeFile_To_v1_MetadataFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } + return nil +} + +func convert_api_DownwardAPIVolumeFile_To_v1_MetadataFile(in *api.DownwardAPIVolumeFile, out *v1.MetadataFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeFile))(in) + } + out.Name = in.Path + if err := convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + return nil +} + +// This will convert the v1 representation of VolumeSource to our internal representation +// Used for keeping backwards compatibility for the Metadata field +func convert_v1beta1_VolumeSource_To_api_VolumeSource(in *v1.VolumeSource, out *api.VolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.VolumeSource))(in) + } + + if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { + return err + } + + // if specified Metadata will stomp DownwardAPI + if in.Metadata != nil { + out.DownwardAPI = new(api.DownwardAPIVolumeSource) + if err := convert_v1_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in.Metadata, out.DownwardAPI, s); err != nil { + return err + } + } else { + if in.DownwardAPI != nil { + out.DownwardAPI = new(api.DownwardAPIVolumeSource) + if err := convert_v1_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in.DownwardAPI, out.DownwardAPI, s); err != nil { + return err + } + } else { + out.DownwardAPI = nil + } + } + return nil +} + +// metadata -> downward (v1 -> api) +func convert_v1_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in *v1.MetadataVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.MetadataVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]api.DownwardAPIVolumeFile, len(in.Items)) + for i := range in.Items { + if err := convert_v1_MetadataFile_To_api_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } + return nil +} + +func convert_v1_MetadataFile_To_api_DownwardAPIVolumeFile(in *v1.MetadataFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.MetadataFile))(in) + } + out.Path = in.Name + if err := convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/deep_copy_generated.go index a573e9b8ac48..5b6671640ae5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/deep_copy_generated.go @@ -434,6 +434,28 @@ func deepCopy_v1_LocalObjectReference(in v1.LocalObjectReference, out *v1.LocalO return nil } +func deepCopy_v1_MetadataFile(in v1.MetadataFile, out *v1.MetadataFile, c *conversion.Cloner) error { + out.Name = in.Name + if err := deepCopy_v1_ObjectFieldSelector(in.FieldRef, &out.FieldRef, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1_MetadataVolumeSource(in v1.MetadataVolumeSource, out *v1.MetadataVolumeSource, c *conversion.Cloner) error { + if in.Items != nil { + out.Items = make([]v1.MetadataFile, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1_MetadataFile(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + func deepCopy_v1_NFSVolumeSource(in v1.NFSVolumeSource, out *v1.NFSVolumeSource, c *conversion.Cloner) error { out.Server = in.Server out.Path = in.Path @@ -544,6 +566,7 @@ func deepCopy_v1_PodSpec(in v1.PodSpec, out *v1.PodSpec, c *conversion.Cloner) e } else { out.NodeSelector = nil } + out.DeprecatedHost = in.DeprecatedHost out.ServiceAccountName = in.ServiceAccountName out.DeprecatedServiceAccount = in.DeprecatedServiceAccount out.NodeName = in.NodeName @@ -841,6 +864,15 @@ func deepCopy_v1_VolumeSource(in v1.VolumeSource, out *v1.VolumeSource, c *conve } else { out.FC = nil } + + if in.Metadata != nil { + out.Metadata = new(v1.MetadataVolumeSource) + if err := deepCopy_v1_MetadataVolumeSource(*in.Metadata, out.Metadata, c); err != nil { + return err + } + } else { + out.Metadata = nil + } return nil } @@ -1554,6 +1586,8 @@ func init() { deepCopy_v1_LoadBalancerIngress, deepCopy_v1_LoadBalancerStatus, deepCopy_v1_LocalObjectReference, + deepCopy_v1_MetadataFile, + deepCopy_v1_MetadataVolumeSource, deepCopy_v1_NFSVolumeSource, deepCopy_v1_ObjectFieldSelector, deepCopy_v1_ObjectMeta, From c1ceb6a94552bffe990cc2c6f58925cb0ee720fb Mon Sep 17 00:00:00 2001 From: deads2k Date: Tue, 11 Aug 2015 13:41:49 -0400 Subject: [PATCH 15/35] UPSTREAM: : support pointing oc exec to old openshift server Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec.go Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward.go Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec.go Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward.go --- .../k8s.io/kubernetes/pkg/kubectl/cmd/exec.go | 36 ++++++++++++++++++- .../kubernetes/pkg/kubectl/cmd/portforward.go | 25 ++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec.go index a0c0c88924b5..fb2c2bbbcac7 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/exec.go @@ -28,6 +28,7 @@ import ( "github.com/golang/glog" "github.com/spf13/cobra" "k8s.io/kubernetes/pkg/api" + apierrors "k8s.io/kubernetes/pkg/api/errors" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -224,6 +225,7 @@ func (p *ExecOptions) Run() error { Namespace(pod.Namespace). SubResource("exec"). Param("container", containerName) + req.VersionedParams(&api.PodExecOptions{ Container: containerName, Command: p.Command, @@ -233,5 +235,37 @@ func (p *ExecOptions) Run() error { TTY: tty, }, api.Scheme) - return p.Executor.Execute("POST", req.URL(), p.Config, stdin, p.Out, p.Err, tty) + postErr := p.Executor.Execute("POST", req.URL(), p.Config, stdin, p.Out, p.Err, tty) + + // if we don't have an error, return. If we did get an error, try a GET because v3.0.0 shipped with exec running as a GET. + if postErr == nil { + return nil + } + // only try the get if the error is either a forbidden or method not supported, otherwise trying with a GET probably won't help + if !apierrors.IsForbidden(postErr) && !apierrors.IsMethodNotSupported(postErr) { + return postErr + } + + getReq := p.Client.RESTClient.Get(). + Resource("pods"). + Name(pod.Name). + Namespace(pod.Namespace). + SubResource("exec"). + Param("container", containerName) + getReq.VersionedParams(&api.PodExecOptions{ + Container: containerName, + Command: p.Command, + Stdin: stdin != nil, + Stdout: p.Out != nil, + Stderr: p.Err != nil, + TTY: tty, + }, api.Scheme) + + getErr := p.Executor.Execute("GET", getReq.URL(), p.Config, stdin, p.Out, p.Err, tty) + if getErr == nil { + return nil + } + + // if we got a getErr, return the postErr because it's more likely to be correct. GET is legacy + return postErr } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward.go index 942a1c5009e2..52570ace3003 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/portforward.go @@ -24,6 +24,7 @@ import ( "github.com/golang/glog" "github.com/spf13/cobra" "k8s.io/kubernetes/pkg/api" + apierrors "k8s.io/kubernetes/pkg/api/errors" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/portforward" "k8s.io/kubernetes/pkg/client/unversioned/remotecommand" @@ -136,5 +137,27 @@ func RunPortForward(f *cmdutil.Factory, cmd *cobra.Command, args []string, fw po Name(pod.Name). SubResource("portforward") - return fw.ForwardPorts("POST", req.URL(), config, args, stopCh) + postErr := fw.ForwardPorts("POST", req.URL(), config, args, stopCh) + + // if we don't have an error, return. If we did get an error, try a GET because v3.0.0 shipped with port-forward running as a GET. + if postErr == nil { + return nil + } + // only try the get if the error is either a forbidden or method not supported, otherwise trying with a GET probably won't help + if !apierrors.IsForbidden(postErr) && !apierrors.IsMethodNotSupported(postErr) { + return postErr + } + + getReq := client.RESTClient.Get(). + Resource("pods"). + Namespace(namespace). + Name(pod.Name). + SubResource("portforward") + getErr := fw.ForwardPorts("GET", getReq.URL(), config, args, stopCh) + if getErr == nil { + return nil + } + + // if we got a getErr, return the postErr because it's more likely to be correct. GET is legacy + return postErr } From 5507f84740ecb0c9258dbc57ffbef53e81d4f4b1 Mon Sep 17 00:00:00 2001 From: deads2k Date: Tue, 11 Aug 2015 12:57:51 -0400 Subject: [PATCH 16/35] UPSTREAM: : v1beta3 Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest.go Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/latest/latest.go Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/registered/registered.go Godeps/_workspace/src/k8s.io/kubernetes/pkg/master/master.go pkg/authorization/api/v1beta3/conversion.go --- .../kubernetes/pkg/api/install/install.go | 7 + .../pkg/api/registered/registered.go | 3 +- .../kubernetes/pkg/api/v1beta3/conversion.go | 892 ++++ .../pkg/api/v1beta3/conversion_generated.go | 4709 +++++++++++++++++ .../pkg/api/v1beta3/conversion_test.go | 139 + .../v1beta3/conversion_volumesource_test.go | 62 + .../pkg/api/v1beta3/deep_copy_generated.go | 2530 +++++++++ .../kubernetes/pkg/api/v1beta3/defaults.go | 218 + .../pkg/api/v1beta3/defaults_test.go | 471 ++ .../kubernetes/pkg/api/v1beta3/register.go | 134 + .../kubernetes/pkg/api/v1beta3/types.go | 2252 ++++++++ .../pkg/client/unversioned/request.go | 34 + .../pkg/kubectl/cmd/rollingupdate.go | 5 + 13 files changed, 11455 insertions(+), 1 deletion(-) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_volumesource_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/register.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go index 91ee3accdfb7..4f7f66270701 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/install/install.go @@ -32,6 +32,7 @@ import ( "k8s.io/kubernetes/pkg/api/registered" apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/api/v1beta3" "k8s.io/kubernetes/pkg/runtime" ) @@ -103,6 +104,12 @@ func init() { // string, or an error if the version is not known. func interfacesFor(version string) (*meta.VersionInterfaces, error) { switch version { + case "v1beta3": + return &meta.VersionInterfaces{ + Codec: v1beta3.Codec, + ObjectConvertor: api.Scheme, + MetadataAccessor: accessor, + }, nil case "v1": return &meta.VersionInterfaces{ Codec: v1.Codec, diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/registered/registered.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/registered/registered.go index a3f8ddfbfc4d..9dae8fceac3c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/registered/registered.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/registered/registered.go @@ -33,11 +33,12 @@ func init() { // TODO: caesarxuchao: rename this variable to validGroupVersions validAPIVersions := map[string]bool{ "v1": true, + "v1beta3": true, "extensions/v1beta1": true, } // The default list of supported api versions, in order of most preferred to the least. - defaultSupportedVersions := "v1,extensions/v1beta1" + defaultSupportedVersions := "v1,extensions/v1beta1,v1beta3" // Env var KUBE_API_VERSIONS is a comma separated list of API versions that should be registered in the scheme. // The versions should be in the order of most preferred to the least. supportedVersions := os.Getenv("KUBE_API_VERSIONS") diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion.go new file mode 100644 index 000000000000..88504439de93 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion.go @@ -0,0 +1,892 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 v1beta3 + +import ( + "fmt" + "reflect" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/conversion" +) + +func addConversionFuncs() { + // Add non-generated conversion functions + err := api.Scheme.AddConversionFuncs( + convert_v1beta3_Container_To_api_Container, + convert_api_Container_To_v1beta3_Container, + convert_v1beta3_ServiceSpec_To_api_ServiceSpec, + convert_api_ServiceSpec_To_v1beta3_ServiceSpec, + convert_v1beta3_PodSpec_To_api_PodSpec, + convert_api_PodSpec_To_v1beta3_PodSpec, + convert_v1beta3_ContainerState_To_api_ContainerState, + convert_api_ContainerState_To_v1beta3_ContainerState, + convert_api_ContainerStateTerminated_To_v1beta3_ContainerStateTerminated, + convert_v1beta3_ContainerStateTerminated_To_api_ContainerStateTerminated, + convert_v1beta3_StatusDetails_To_api_StatusDetails, + convert_api_StatusDetails_To_v1beta3_StatusDetails, + convert_v1beta3_StatusCause_To_api_StatusCause, + convert_api_StatusCause_To_v1beta3_StatusCause, + convert_api_ReplicationControllerSpec_To_v1beta3_ReplicationControllerSpec, + convert_v1beta3_ReplicationControllerSpec_To_api_ReplicationControllerSpec, + convert_v1beta3_VolumeSource_To_api_VolumeSource, + convert_api_VolumeSource_To_v1beta3_VolumeSource, + ) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } + + // Add field conversion funcs. + err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Pod", + func(label, value string) (string, string, error) { + switch label { + case "metadata.name", + "metadata.namespace", + "metadata.labels", + "metadata.annotations", + "status.podIP", + "status.phase": + return label, value, nil + case "spec.host": + return "spec.nodeName", value, nil + default: + return "", "", fmt.Errorf("field label not supported: %s", label) + } + }) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } + err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Node", + func(label, value string) (string, string, error) { + switch label { + case "metadata.name": + return label, value, nil + case "spec.unschedulable": + return label, value, nil + default: + return "", "", fmt.Errorf("field label not supported: %s", label) + } + }) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } + err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "ReplicationController", + func(label, value string) (string, string, error) { + switch label { + case "metadata.name", + "status.replicas": + return label, value, nil + default: + return "", "", fmt.Errorf("field label not supported: %s", label) + } + }) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } + err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Event", + func(label, value string) (string, string, error) { + switch label { + case "involvedObject.kind", + "involvedObject.namespace", + "involvedObject.name", + "involvedObject.uid", + "involvedObject.apiVersion", + "involvedObject.resourceVersion", + "involvedObject.fieldPath", + "reason", + "source": + return label, value, nil + default: + return "", "", fmt.Errorf("field label not supported: %s", label) + } + }) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } + err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Namespace", + func(label, value string) (string, string, error) { + switch label { + case "status.phase": + return label, value, nil + default: + return "", "", fmt.Errorf("field label not supported: %s", label) + } + }) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } + err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Secret", + func(label, value string) (string, string, error) { + switch label { + case "type": + return label, value, nil + default: + return "", "", fmt.Errorf("field label not supported: %s", label) + } + }) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } + err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "ServiceAccount", + func(label, value string) (string, string, error) { + switch label { + case "metadata.name": + return label, value, nil + default: + return "", "", fmt.Errorf("field label not supported: %s", label) + } + }) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } + err = api.Scheme.AddFieldLabelConversionFunc("v1beta3", "Endpoints", + func(label, value string) (string, string, error) { + switch label { + case "metadata.name": + return label, value, nil + default: + return "", "", fmt.Errorf("field label not supported: %s", label) + } + }) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } +} + +func convert_v1beta3_Container_To_api_Container(in *Container, out *api.Container, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Container))(in) + } + out.Name = in.Name + out.Image = in.Image + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } + if in.Args != nil { + out.Args = make([]string, len(in.Args)) + for i := range in.Args { + out.Args[i] = in.Args[i] + } + } + out.WorkingDir = in.WorkingDir + if in.Ports != nil { + out.Ports = make([]api.ContainerPort, len(in.Ports)) + for i := range in.Ports { + if err := convert_v1beta3_ContainerPort_To_api_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { + return err + } + } + } + if in.Env != nil { + out.Env = make([]api.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_v1beta3_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } + if err := s.Convert(&in.Resources, &out.Resources, 0); err != nil { + return err + } + if in.VolumeMounts != nil { + out.VolumeMounts = make([]api.VolumeMount, len(in.VolumeMounts)) + for i := range in.VolumeMounts { + if err := convert_v1beta3_VolumeMount_To_api_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { + return err + } + } + } + if in.LivenessProbe != nil { + out.LivenessProbe = new(api.Probe) + if err := convert_v1beta3_Probe_To_api_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { + return err + } + } else { + out.LivenessProbe = nil + } + if in.ReadinessProbe != nil { + out.ReadinessProbe = new(api.Probe) + if err := convert_v1beta3_Probe_To_api_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { + return err + } + } else { + out.ReadinessProbe = nil + } + if in.Lifecycle != nil { + out.Lifecycle = new(api.Lifecycle) + if err := convert_v1beta3_Lifecycle_To_api_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { + return err + } + } else { + out.Lifecycle = nil + } + out.TerminationMessagePath = in.TerminationMessagePath + out.ImagePullPolicy = api.PullPolicy(in.ImagePullPolicy) + if in.SecurityContext != nil { + if in.SecurityContext.Capabilities != nil { + if !reflect.DeepEqual(in.SecurityContext.Capabilities.Add, in.Capabilities.Add) || + !reflect.DeepEqual(in.SecurityContext.Capabilities.Drop, in.Capabilities.Drop) { + return fmt.Errorf("container capability settings do not match security context settings, cannot convert") + } + } + if in.SecurityContext.Privileged != nil { + if in.Privileged != *in.SecurityContext.Privileged { + return fmt.Errorf("container privileged settings do not match security context settings, cannot convert") + } + } + } + if in.SecurityContext != nil { + out.SecurityContext = new(api.SecurityContext) + if err := convert_v1beta3_SecurityContext_To_api_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + + out.Stdin = in.Stdin + out.TTY = in.TTY + return nil +} + +func convert_api_Container_To_v1beta3_Container(in *api.Container, out *Container, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Container))(in) + } + out.Name = in.Name + out.Image = in.Image + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } + if in.Args != nil { + out.Args = make([]string, len(in.Args)) + for i := range in.Args { + out.Args[i] = in.Args[i] + } + } + out.WorkingDir = in.WorkingDir + if in.Ports != nil { + out.Ports = make([]ContainerPort, len(in.Ports)) + for i := range in.Ports { + if err := convert_api_ContainerPort_To_v1beta3_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { + return err + } + } + } + if in.Env != nil { + out.Env = make([]EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_api_EnvVar_To_v1beta3_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } + if err := s.Convert(&in.Resources, &out.Resources, 0); err != nil { + return err + } + if in.VolumeMounts != nil { + out.VolumeMounts = make([]VolumeMount, len(in.VolumeMounts)) + for i := range in.VolumeMounts { + if err := convert_api_VolumeMount_To_v1beta3_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { + return err + } + } + } + if in.LivenessProbe != nil { + out.LivenessProbe = new(Probe) + if err := convert_api_Probe_To_v1beta3_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { + return err + } + } else { + out.LivenessProbe = nil + } + if in.ReadinessProbe != nil { + out.ReadinessProbe = new(Probe) + if err := convert_api_Probe_To_v1beta3_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { + return err + } + } else { + out.ReadinessProbe = nil + } + if in.Lifecycle != nil { + out.Lifecycle = new(Lifecycle) + if err := convert_api_Lifecycle_To_v1beta3_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { + return err + } + } else { + out.Lifecycle = nil + } + out.TerminationMessagePath = in.TerminationMessagePath + out.ImagePullPolicy = PullPolicy(in.ImagePullPolicy) + if in.SecurityContext != nil { + out.SecurityContext = new(SecurityContext) + if err := convert_api_SecurityContext_To_v1beta3_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + // now that we've converted set the container field from security context + if out.SecurityContext != nil && out.SecurityContext.Privileged != nil { + out.Privileged = *out.SecurityContext.Privileged + } + // now that we've converted set the container field from security context + if out.SecurityContext != nil && out.SecurityContext.Capabilities != nil { + out.Capabilities = *out.SecurityContext.Capabilities + } + + out.Stdin = in.Stdin + out.TTY = in.TTY + return nil +} + +func convert_v1beta3_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.ServiceSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ServiceSpec))(in) + } + if in.Ports != nil { + out.Ports = make([]api.ServicePort, len(in.Ports)) + for i := range in.Ports { + if err := convert_v1beta3_ServicePort_To_api_ServicePort(&in.Ports[i], &out.Ports[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + out.ClusterIP = in.PortalIP + + typeIn := in.Type + if typeIn == "" { + if in.CreateExternalLoadBalancer { + typeIn = ServiceTypeLoadBalancer + } else { + typeIn = ServiceTypeClusterIP + } + } + if err := s.Convert(&typeIn, &out.Type, 0); err != nil { + return err + } + + if in.PublicIPs != nil { + out.ExternalIPs = make([]string, len(in.PublicIPs)) + for i := range in.PublicIPs { + out.ExternalIPs[i] = in.PublicIPs[i] + } + } else { + out.ExternalIPs = nil + } + out.SessionAffinity = api.ServiceAffinity(in.SessionAffinity) + return nil +} + +func convert_api_ServiceSpec_To_v1beta3_ServiceSpec(in *api.ServiceSpec, out *ServiceSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ServiceSpec))(in) + } + if in.Ports != nil { + out.Ports = make([]ServicePort, len(in.Ports)) + for i := range in.Ports { + if err := convert_api_ServicePort_To_v1beta3_ServicePort(&in.Ports[i], &out.Ports[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + out.PortalIP = in.ClusterIP + + if err := s.Convert(&in.Type, &out.Type, 0); err != nil { + return err + } + out.CreateExternalLoadBalancer = in.Type == api.ServiceTypeLoadBalancer + + if in.ExternalIPs != nil { + out.PublicIPs = make([]string, len(in.ExternalIPs)) + for i := range in.ExternalIPs { + out.PublicIPs[i] = in.ExternalIPs[i] + } + } else { + out.PublicIPs = nil + } + out.SessionAffinity = ServiceAffinity(in.SessionAffinity) + return nil +} + +func convert_v1beta3_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodSpec))(in) + } + if in.Volumes != nil { + out.Volumes = make([]api.Volume, len(in.Volumes)) + for i := range in.Volumes { + if err := convert_v1beta3_Volume_To_api_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil { + return err + } + } + } else { + out.Volumes = nil + } + if in.Containers != nil { + out.Containers = make([]api.Container, len(in.Containers)) + for i := range in.Containers { + if err := convert_v1beta3_Container_To_api_Container(&in.Containers[i], &out.Containers[i], s); err != nil { + return err + } + } + } else { + out.Containers = nil + } + out.RestartPolicy = api.RestartPolicy(in.RestartPolicy) + if in.TerminationGracePeriodSeconds != nil { + out.TerminationGracePeriodSeconds = new(int64) + *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds + } else { + out.TerminationGracePeriodSeconds = nil + } + if in.ActiveDeadlineSeconds != nil { + out.ActiveDeadlineSeconds = new(int64) + *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds + } else { + out.ActiveDeadlineSeconds = nil + } + out.DNSPolicy = api.DNSPolicy(in.DNSPolicy) + if in.NodeSelector != nil { + out.NodeSelector = make(map[string]string) + for key, val := range in.NodeSelector { + out.NodeSelector[key] = val + } + } else { + out.NodeSelector = nil + } + out.ServiceAccountName = in.ServiceAccount + out.NodeName = in.Host + out.SecurityContext = &api.PodSecurityContext{} + out.SecurityContext.HostNetwork = in.HostNetwork + out.SecurityContext.HostPID = in.HostPID + out.SecurityContext.HostIPC = in.HostIPC + if in.ImagePullSecrets != nil { + out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets)) + for i := range in.ImagePullSecrets { + if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { + return err + } + } + } else { + out.ImagePullSecrets = nil + } + return nil +} + +func convert_api_PodSpec_To_v1beta3_PodSpec(in *api.PodSpec, out *PodSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodSpec))(in) + } + if in.Volumes != nil { + out.Volumes = make([]Volume, len(in.Volumes)) + for i := range in.Volumes { + if err := convert_api_Volume_To_v1beta3_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil { + return err + } + } + } else { + out.Volumes = nil + } + if in.Containers != nil { + out.Containers = make([]Container, len(in.Containers)) + for i := range in.Containers { + if err := convert_api_Container_To_v1beta3_Container(&in.Containers[i], &out.Containers[i], s); err != nil { + return err + } + } + } else { + out.Containers = nil + } + out.RestartPolicy = RestartPolicy(in.RestartPolicy) + if in.TerminationGracePeriodSeconds != nil { + out.TerminationGracePeriodSeconds = new(int64) + *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds + } else { + out.TerminationGracePeriodSeconds = nil + } + if in.ActiveDeadlineSeconds != nil { + out.ActiveDeadlineSeconds = new(int64) + *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds + } else { + out.ActiveDeadlineSeconds = nil + } + out.DNSPolicy = DNSPolicy(in.DNSPolicy) + if in.NodeSelector != nil { + out.NodeSelector = make(map[string]string) + for key, val := range in.NodeSelector { + out.NodeSelector[key] = val + } + } else { + out.NodeSelector = nil + } + out.ServiceAccount = in.ServiceAccountName + out.Host = in.NodeName + if in.SecurityContext != nil { + out.HostNetwork = in.SecurityContext.HostNetwork + out.HostPID = in.SecurityContext.HostPID + out.HostIPC = in.SecurityContext.HostIPC + } + if in.ImagePullSecrets != nil { + out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) + for i := range in.ImagePullSecrets { + if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { + return err + } + } + } else { + out.ImagePullSecrets = nil + } + return nil +} + +func convert_api_ContainerState_To_v1beta3_ContainerState(in *api.ContainerState, out *ContainerState, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ContainerState))(in) + } + if in.Waiting != nil { + out.Waiting = new(ContainerStateWaiting) + if err := convert_api_ContainerStateWaiting_To_v1beta3_ContainerStateWaiting(in.Waiting, out.Waiting, s); err != nil { + return err + } + } else { + out.Waiting = nil + } + if in.Running != nil { + out.Running = new(ContainerStateRunning) + if err := convert_api_ContainerStateRunning_To_v1beta3_ContainerStateRunning(in.Running, out.Running, s); err != nil { + return err + } + } else { + out.Running = nil + } + if in.Terminated != nil { + out.Termination = new(ContainerStateTerminated) + if err := convert_api_ContainerStateTerminated_To_v1beta3_ContainerStateTerminated(in.Terminated, out.Termination, s); err != nil { + return err + } + } else { + out.Termination = nil + } + return nil +} + +func convert_v1beta3_ContainerState_To_api_ContainerState(in *ContainerState, out *api.ContainerState, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ContainerState))(in) + } + if in.Waiting != nil { + out.Waiting = new(api.ContainerStateWaiting) + if err := convert_v1beta3_ContainerStateWaiting_To_api_ContainerStateWaiting(in.Waiting, out.Waiting, s); err != nil { + return err + } + } else { + out.Waiting = nil + } + if in.Running != nil { + out.Running = new(api.ContainerStateRunning) + if err := convert_v1beta3_ContainerStateRunning_To_api_ContainerStateRunning(in.Running, out.Running, s); err != nil { + return err + } + } else { + out.Running = nil + } + if in.Termination != nil { + out.Terminated = new(api.ContainerStateTerminated) + if err := convert_v1beta3_ContainerStateTerminated_To_api_ContainerStateTerminated(in.Termination, out.Terminated, s); err != nil { + return err + } + } else { + out.Terminated = nil + } + return nil +} + +func convert_api_ContainerStateTerminated_To_v1beta3_ContainerStateTerminated(in *api.ContainerStateTerminated, out *ContainerStateTerminated, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ContainerStateTerminated))(in) + } + out.ExitCode = in.ExitCode + out.Signal = in.Signal + out.Reason = in.Reason + out.Message = in.Message + if err := s.Convert(&in.StartedAt, &out.StartedAt, 0); err != nil { + return err + } + if err := s.Convert(&in.FinishedAt, &out.FinishedAt, 0); err != nil { + return err + } + out.ContainerID = in.ContainerID + return nil +} + +func convert_v1beta3_ContainerStateTerminated_To_api_ContainerStateTerminated(in *ContainerStateTerminated, out *api.ContainerStateTerminated, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ContainerStateTerminated))(in) + } + out.ExitCode = in.ExitCode + out.Signal = in.Signal + out.Reason = in.Reason + out.Message = in.Message + if err := s.Convert(&in.StartedAt, &out.StartedAt, 0); err != nil { + return err + } + if err := s.Convert(&in.FinishedAt, &out.FinishedAt, 0); err != nil { + return err + } + out.ContainerID = in.ContainerID + return nil +} + +func convert_v1beta3_StatusDetails_To_api_StatusDetails(in *StatusDetails, out *unversioned.StatusDetails, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*StatusDetails))(in) + } + out.Name = in.ID + out.Kind = in.Kind + if in.Causes != nil { + out.Causes = make([]unversioned.StatusCause, len(in.Causes)) + for i := range in.Causes { + if err := convert_v1beta3_StatusCause_To_api_StatusCause(&in.Causes[i], &out.Causes[i], s); err != nil { + return err + } + } + } else { + out.Causes = nil + } + out.RetryAfterSeconds = in.RetryAfterSeconds + return nil +} + +func convert_api_StatusDetails_To_v1beta3_StatusDetails(in *unversioned.StatusDetails, out *StatusDetails, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*unversioned.StatusDetails))(in) + } + out.ID = in.Name + out.Kind = in.Kind + if in.Causes != nil { + out.Causes = make([]StatusCause, len(in.Causes)) + for i := range in.Causes { + if err := convert_api_StatusCause_To_v1beta3_StatusCause(&in.Causes[i], &out.Causes[i], s); err != nil { + return err + } + } + } else { + out.Causes = nil + } + out.RetryAfterSeconds = in.RetryAfterSeconds + return nil +} + +func convert_v1beta3_StatusCause_To_api_StatusCause(in *StatusCause, out *unversioned.StatusCause, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*StatusCause))(in) + } + out.Type = unversioned.CauseType(in.Type) + out.Message = in.Message + out.Field = in.Field + return nil +} + +func convert_api_StatusCause_To_v1beta3_StatusCause(in *unversioned.StatusCause, out *StatusCause, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*unversioned.StatusCause))(in) + } + out.Type = CauseType(in.Type) + out.Message = in.Message + out.Field = in.Field + return nil +} + +func convert_api_ReplicationControllerSpec_To_v1beta3_ReplicationControllerSpec(in *api.ReplicationControllerSpec, out *ReplicationControllerSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ReplicationControllerSpec))(in) + } + out.Replicas = &in.Replicas + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(PodTemplateSpec) + if err := convert_api_PodTemplateSpec_To_v1beta3_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + return nil +} + +func convert_v1beta3_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *ReplicationControllerSpec, out *api.ReplicationControllerSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ReplicationControllerSpec))(in) + } + out.Replicas = *in.Replicas + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(api.PodTemplateSpec) + if err := convert_v1beta3_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { + return err + } + } else { + out.Template = nil + } + return nil +} + +// This will convert our internal represantation of VolumeSource to its v1beta3 representation +// Used for keeping backwards compatibility for the Metadata field +func convert_api_VolumeSource_To_v1beta3_VolumeSource(in *api.VolumeSource, out *VolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.VolumeSource))(in) + } + + if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { + return err + } + + if in.DownwardAPI != nil { + out.Metadata = new(MetadataVolumeSource) + if err := convert_api_DownwardAPIVolumeSource_To_v1beta3_MetadataVolumeSource(in.DownwardAPI, out.Metadata, s); err != nil { + return err + } + } + return nil +} + +// downward -> metadata (api -> v1beta3) +func convert_api_DownwardAPIVolumeSource_To_v1beta3_MetadataVolumeSource(in *api.DownwardAPIVolumeSource, out *MetadataVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]MetadataFile, len(in.Items)) + for i := range in.Items { + if err := convert_api_DownwardAPIVolumeFile_To_v1beta3_MetadataFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } + return nil +} + +func convert_api_DownwardAPIVolumeFile_To_v1beta3_MetadataFile(in *api.DownwardAPIVolumeFile, out *MetadataFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeFile))(in) + } + out.Name = in.Path + if err := convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + return nil +} + +// This will convert the v1beta3 representation of VolumeSource to our internal representation +// Used for keeping backwards compatibility for the Metadata field +func convert_v1beta3_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api.VolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*VolumeSource))(in) + } + + if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil { + return err + } + + // if specified Metadata will stomp DownwardAPI + if in.Metadata != nil { + out.DownwardAPI = new(api.DownwardAPIVolumeSource) + if err := convert_v1beta3_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in.Metadata, out.DownwardAPI, s); err != nil { + return err + } + } + return nil +} + +// metadata -> downward (v1beta3 -> api) +func convert_v1beta3_MetadataVolumeSource_To_api_DownwardAPIVolumeSource(in *MetadataVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*MetadataVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]api.DownwardAPIVolumeFile, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_MetadataFile_To_api_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } + return nil +} + +func convert_v1beta3_MetadataFile_To_api_DownwardAPIVolumeFile(in *MetadataFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*MetadataFile))(in) + } + out.Path = in.Name + if err := convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + return nil +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go new file mode 100644 index 000000000000..b8ac60c376a5 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go @@ -0,0 +1,4709 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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. +*/ + +// DO NOT EDIT. THIS FILE IS AUTO-GENERATED BY $KUBEROOT/hack/update-generated-conversions.sh + +package v1beta3 + +import ( + reflect "reflect" + + api "k8s.io/kubernetes/pkg/api" + resource "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" + conversion "k8s.io/kubernetes/pkg/conversion" +) + +func convert_api_AWSElasticBlockStoreVolumeSource_To_v1beta3_AWSElasticBlockStoreVolumeSource(in *api.AWSElasticBlockStoreVolumeSource, out *AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.AWSElasticBlockStoreVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_Binding_To_v1beta3_Binding(in *api.Binding, out *Binding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Binding))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.Target, &out.Target, s); err != nil { + return err + } + return nil +} + +func convert_api_Capabilities_To_v1beta3_Capabilities(in *api.Capabilities, out *Capabilities, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Capabilities))(in) + } + if in.Add != nil { + out.Add = make([]Capability, len(in.Add)) + for i := range in.Add { + out.Add[i] = Capability(in.Add[i]) + } + } else { + out.Add = nil + } + if in.Drop != nil { + out.Drop = make([]Capability, len(in.Drop)) + for i := range in.Drop { + out.Drop[i] = Capability(in.Drop[i]) + } + } else { + out.Drop = nil + } + return nil +} + +func convert_api_CephFSVolumeSource_To_v1beta3_CephFSVolumeSource(in *api.CephFSVolumeSource, out *CephFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.CephFSVolumeSource))(in) + } + if in.Monitors != nil { + out.Monitors = make([]string, len(in.Monitors)) + for i := range in.Monitors { + out.Monitors[i] = in.Monitors[i] + } + } else { + out.Monitors = nil + } + out.User = in.User + out.SecretFile = in.SecretFile + if in.SecretRef != nil { + out.SecretRef = new(LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_CinderVolumeSource_To_v1beta3_CinderVolumeSource(in *api.CinderVolumeSource, out *CinderVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.CinderVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_ComponentCondition_To_v1beta3_ComponentCondition(in *api.ComponentCondition, out *ComponentCondition, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ComponentCondition))(in) + } + out.Type = ComponentConditionType(in.Type) + out.Status = ConditionStatus(in.Status) + out.Message = in.Message + out.Error = in.Error + return nil +} + +func convert_api_ComponentStatus_To_v1beta3_ComponentStatus(in *api.ComponentStatus, out *ComponentStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ComponentStatus))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Conditions != nil { + out.Conditions = make([]ComponentCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := convert_api_ComponentCondition_To_v1beta3_ComponentCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +func convert_api_ComponentStatusList_To_v1beta3_ComponentStatusList(in *api.ComponentStatusList, out *ComponentStatusList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ComponentStatusList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ComponentStatus, len(in.Items)) + for i := range in.Items { + if err := convert_api_ComponentStatus_To_v1beta3_ComponentStatus(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_ContainerPort_To_v1beta3_ContainerPort(in *api.ContainerPort, out *ContainerPort, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ContainerPort))(in) + } + out.Name = in.Name + out.HostPort = in.HostPort + out.ContainerPort = in.ContainerPort + out.Protocol = Protocol(in.Protocol) + out.HostIP = in.HostIP + return nil +} + +func convert_api_ContainerStateRunning_To_v1beta3_ContainerStateRunning(in *api.ContainerStateRunning, out *ContainerStateRunning, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ContainerStateRunning))(in) + } + if err := s.Convert(&in.StartedAt, &out.StartedAt, 0); err != nil { + return err + } + return nil +} + +func convert_api_ContainerStateWaiting_To_v1beta3_ContainerStateWaiting(in *api.ContainerStateWaiting, out *ContainerStateWaiting, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ContainerStateWaiting))(in) + } + out.Reason = in.Reason + return nil +} + +func convert_api_ContainerStatus_To_v1beta3_ContainerStatus(in *api.ContainerStatus, out *ContainerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ContainerStatus))(in) + } + out.Name = in.Name + if err := convert_api_ContainerState_To_v1beta3_ContainerState(&in.State, &out.State, s); err != nil { + return err + } + if err := convert_api_ContainerState_To_v1beta3_ContainerState(&in.LastTerminationState, &out.LastTerminationState, s); err != nil { + return err + } + out.Ready = in.Ready + out.RestartCount = in.RestartCount + out.Image = in.Image + out.ImageID = in.ImageID + out.ContainerID = in.ContainerID + return nil +} + +func convert_api_DeleteOptions_To_v1beta3_DeleteOptions(in *api.DeleteOptions, out *DeleteOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DeleteOptions))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if in.GracePeriodSeconds != nil { + out.GracePeriodSeconds = new(int64) + *out.GracePeriodSeconds = *in.GracePeriodSeconds + } else { + out.GracePeriodSeconds = nil + } + return nil +} + +func convert_api_DownwardAPIVolumeFile_To_v1beta3_DownwardAPIVolumeFile(in *api.DownwardAPIVolumeFile, out *DownwardAPIVolumeFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeFile))(in) + } + out.Path = in.Path + if err := convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + return nil +} + +func convert_api_DownwardAPIVolumeSource_To_v1beta3_DownwardAPIVolumeSource(in *api.DownwardAPIVolumeSource, out *DownwardAPIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.DownwardAPIVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]DownwardAPIVolumeFile, len(in.Items)) + for i := range in.Items { + if err := convert_api_DownwardAPIVolumeFile_To_v1beta3_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_EmptyDirVolumeSource_To_v1beta3_EmptyDirVolumeSource(in *api.EmptyDirVolumeSource, out *EmptyDirVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EmptyDirVolumeSource))(in) + } + out.Medium = StorageMedium(in.Medium) + return nil +} + +func convert_api_EndpointAddress_To_v1beta3_EndpointAddress(in *api.EndpointAddress, out *EndpointAddress, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EndpointAddress))(in) + } + out.IP = in.IP + if in.TargetRef != nil { + out.TargetRef = new(ObjectReference) + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(in.TargetRef, out.TargetRef, s); err != nil { + return err + } + } else { + out.TargetRef = nil + } + return nil +} + +func convert_api_EndpointPort_To_v1beta3_EndpointPort(in *api.EndpointPort, out *EndpointPort, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EndpointPort))(in) + } + out.Name = in.Name + out.Port = in.Port + out.Protocol = Protocol(in.Protocol) + return nil +} + +func convert_api_EndpointSubset_To_v1beta3_EndpointSubset(in *api.EndpointSubset, out *EndpointSubset, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EndpointSubset))(in) + } + if in.Addresses != nil { + out.Addresses = make([]EndpointAddress, len(in.Addresses)) + for i := range in.Addresses { + if err := convert_api_EndpointAddress_To_v1beta3_EndpointAddress(&in.Addresses[i], &out.Addresses[i], s); err != nil { + return err + } + } + } else { + out.Addresses = nil + } + if in.Ports != nil { + out.Ports = make([]EndpointPort, len(in.Ports)) + for i := range in.Ports { + if err := convert_api_EndpointPort_To_v1beta3_EndpointPort(&in.Ports[i], &out.Ports[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + return nil +} + +func convert_api_Endpoints_To_v1beta3_Endpoints(in *api.Endpoints, out *Endpoints, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Endpoints))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Subsets != nil { + out.Subsets = make([]EndpointSubset, len(in.Subsets)) + for i := range in.Subsets { + if err := convert_api_EndpointSubset_To_v1beta3_EndpointSubset(&in.Subsets[i], &out.Subsets[i], s); err != nil { + return err + } + } + } else { + out.Subsets = nil + } + return nil +} + +func convert_api_EndpointsList_To_v1beta3_EndpointsList(in *api.EndpointsList, out *EndpointsList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EndpointsList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Endpoints, len(in.Items)) + for i := range in.Items { + if err := convert_api_Endpoints_To_v1beta3_Endpoints(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_EnvVar_To_v1beta3_EnvVar(in *api.EnvVar, out *EnvVar, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EnvVar))(in) + } + out.Name = in.Name + out.Value = in.Value + if in.ValueFrom != nil { + out.ValueFrom = new(EnvVarSource) + if err := convert_api_EnvVarSource_To_v1beta3_EnvVarSource(in.ValueFrom, out.ValueFrom, s); err != nil { + return err + } + } else { + out.ValueFrom = nil + } + return nil +} + +func convert_api_EnvVarSource_To_v1beta3_EnvVarSource(in *api.EnvVarSource, out *EnvVarSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EnvVarSource))(in) + } + if in.FieldRef != nil { + out.FieldRef = new(ObjectFieldSelector) + if err := convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(in.FieldRef, out.FieldRef, s); err != nil { + return err + } + } else { + out.FieldRef = nil + } + return nil +} + +func convert_api_Event_To_v1beta3_Event(in *api.Event, out *Event, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Event))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.InvolvedObject, &out.InvolvedObject, s); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message + if err := convert_api_EventSource_To_v1beta3_EventSource(&in.Source, &out.Source, s); err != nil { + return err + } + if err := s.Convert(&in.FirstTimestamp, &out.FirstTimestamp, 0); err != nil { + return err + } + if err := s.Convert(&in.LastTimestamp, &out.LastTimestamp, 0); err != nil { + return err + } + out.Count = in.Count + return nil +} + +func convert_api_EventList_To_v1beta3_EventList(in *api.EventList, out *EventList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EventList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Event, len(in.Items)) + for i := range in.Items { + if err := convert_api_Event_To_v1beta3_Event(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_EventSource_To_v1beta3_EventSource(in *api.EventSource, out *EventSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.EventSource))(in) + } + out.Component = in.Component + out.Host = in.Host + return nil +} + +func convert_api_ExecAction_To_v1beta3_ExecAction(in *api.ExecAction, out *ExecAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ExecAction))(in) + } + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + return nil +} + +func convert_api_GCEPersistentDiskVolumeSource_To_v1beta3_GCEPersistentDiskVolumeSource(in *api.GCEPersistentDiskVolumeSource, out *GCEPersistentDiskVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.GCEPersistentDiskVolumeSource))(in) + } + out.PDName = in.PDName + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_GitRepoVolumeSource_To_v1beta3_GitRepoVolumeSource(in *api.GitRepoVolumeSource, out *GitRepoVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.GitRepoVolumeSource))(in) + } + out.Repository = in.Repository + out.Revision = in.Revision + return nil +} + +func convert_api_GlusterfsVolumeSource_To_v1beta3_GlusterfsVolumeSource(in *api.GlusterfsVolumeSource, out *GlusterfsVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.GlusterfsVolumeSource))(in) + } + out.EndpointsName = in.EndpointsName + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_HTTPGetAction_To_v1beta3_HTTPGetAction(in *api.HTTPGetAction, out *HTTPGetAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.HTTPGetAction))(in) + } + out.Path = in.Path + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + out.Host = in.Host + out.Scheme = URIScheme(in.Scheme) + return nil +} + +func convert_api_Handler_To_v1beta3_Handler(in *api.Handler, out *Handler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Handler))(in) + } + if in.Exec != nil { + out.Exec = new(ExecAction) + if err := convert_api_ExecAction_To_v1beta3_ExecAction(in.Exec, out.Exec, s); err != nil { + return err + } + } else { + out.Exec = nil + } + if in.HTTPGet != nil { + out.HTTPGet = new(HTTPGetAction) + if err := convert_api_HTTPGetAction_To_v1beta3_HTTPGetAction(in.HTTPGet, out.HTTPGet, s); err != nil { + return err + } + } else { + out.HTTPGet = nil + } + if in.TCPSocket != nil { + out.TCPSocket = new(TCPSocketAction) + if err := convert_api_TCPSocketAction_To_v1beta3_TCPSocketAction(in.TCPSocket, out.TCPSocket, s); err != nil { + return err + } + } else { + out.TCPSocket = nil + } + return nil +} + +func convert_api_HostPathVolumeSource_To_v1beta3_HostPathVolumeSource(in *api.HostPathVolumeSource, out *HostPathVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.HostPathVolumeSource))(in) + } + out.Path = in.Path + return nil +} + +func convert_api_ISCSIVolumeSource_To_v1beta3_ISCSIVolumeSource(in *api.ISCSIVolumeSource, out *ISCSIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ISCSIVolumeSource))(in) + } + out.TargetPortal = in.TargetPortal + out.IQN = in.IQN + out.Lun = in.Lun + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_Lifecycle_To_v1beta3_Lifecycle(in *api.Lifecycle, out *Lifecycle, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Lifecycle))(in) + } + if in.PostStart != nil { + out.PostStart = new(Handler) + if err := convert_api_Handler_To_v1beta3_Handler(in.PostStart, out.PostStart, s); err != nil { + return err + } + } else { + out.PostStart = nil + } + if in.PreStop != nil { + out.PreStop = new(Handler) + if err := convert_api_Handler_To_v1beta3_Handler(in.PreStop, out.PreStop, s); err != nil { + return err + } + } else { + out.PreStop = nil + } + return nil +} + +func convert_api_LimitRange_To_v1beta3_LimitRange(in *api.LimitRange, out *LimitRange, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LimitRange))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_LimitRangeSpec_To_v1beta3_LimitRangeSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_api_LimitRangeItem_To_v1beta3_LimitRangeItem(in *api.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LimitRangeItem))(in) + } + out.Type = LimitType(in.Type) + if in.Max != nil { + out.Max = make(ResourceList) + for key, val := range in.Max { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Max[ResourceName(key)] = newVal + } + } else { + out.Max = nil + } + if in.Min != nil { + out.Min = make(ResourceList) + for key, val := range in.Min { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Min[ResourceName(key)] = newVal + } + } else { + out.Min = nil + } + if in.Default != nil { + out.Default = make(ResourceList) + for key, val := range in.Default { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Default[ResourceName(key)] = newVal + } + } else { + out.Default = nil + } + if in.DefaultRequest != nil { + out.DefaultRequest = make(ResourceList) + for key, val := range in.DefaultRequest { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.DefaultRequest[ResourceName(key)] = newVal + } + } else { + out.DefaultRequest = nil + } + if in.MaxLimitRequestRatio != nil { + out.MaxLimitRequestRatio = make(ResourceList) + for key, val := range in.MaxLimitRequestRatio { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.MaxLimitRequestRatio[ResourceName(key)] = newVal + } + } else { + out.MaxLimitRequestRatio = nil + } + return nil +} + +func convert_api_LimitRangeList_To_v1beta3_LimitRangeList(in *api.LimitRangeList, out *LimitRangeList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LimitRangeList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]LimitRange, len(in.Items)) + for i := range in.Items { + if err := convert_api_LimitRange_To_v1beta3_LimitRange(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_LimitRangeSpec_To_v1beta3_LimitRangeSpec(in *api.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LimitRangeSpec))(in) + } + if in.Limits != nil { + out.Limits = make([]LimitRangeItem, len(in.Limits)) + for i := range in.Limits { + if err := convert_api_LimitRangeItem_To_v1beta3_LimitRangeItem(&in.Limits[i], &out.Limits[i], s); err != nil { + return err + } + } + } else { + out.Limits = nil + } + return nil +} + +func convert_api_List_To_v1beta3_List(in *api.List, out *List, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.List))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Items, &out.Items, 0); err != nil { + return err + } + return nil +} + +func convert_api_ListMeta_To_v1beta3_ListMeta(in *unversioned.ListMeta, out *ListMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*unversioned.ListMeta))(in) + } + out.SelfLink = in.SelfLink + out.ResourceVersion = in.ResourceVersion + return nil +} + +func convert_api_ListOptions_To_v1beta3_ListOptions(in *api.ListOptions, out *ListOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ListOptions))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LabelSelector, &out.LabelSelector, 0); err != nil { + return err + } + if err := s.Convert(&in.FieldSelector, &out.FieldSelector, 0); err != nil { + return err + } + out.Watch = in.Watch + out.ResourceVersion = in.ResourceVersion + return nil +} + +func convert_api_LoadBalancerIngress_To_v1beta3_LoadBalancerIngress(in *api.LoadBalancerIngress, out *LoadBalancerIngress, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LoadBalancerIngress))(in) + } + out.IP = in.IP + out.Hostname = in.Hostname + return nil +} + +func convert_api_LoadBalancerStatus_To_v1beta3_LoadBalancerStatus(in *api.LoadBalancerStatus, out *LoadBalancerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LoadBalancerStatus))(in) + } + if in.Ingress != nil { + out.Ingress = make([]LoadBalancerIngress, len(in.Ingress)) + for i := range in.Ingress { + if err := convert_api_LoadBalancerIngress_To_v1beta3_LoadBalancerIngress(&in.Ingress[i], &out.Ingress[i], s); err != nil { + return err + } + } + } else { + out.Ingress = nil + } + return nil +} + +func convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in *api.LocalObjectReference, out *LocalObjectReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LocalObjectReference))(in) + } + out.Name = in.Name + return nil +} + +func convert_api_NFSVolumeSource_To_v1beta3_NFSVolumeSource(in *api.NFSVolumeSource, out *NFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NFSVolumeSource))(in) + } + out.Server = in.Server + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_Namespace_To_v1beta3_Namespace(in *api.Namespace, out *Namespace, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Namespace))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_NamespaceSpec_To_v1beta3_NamespaceSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_api_NamespaceStatus_To_v1beta3_NamespaceStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_api_NamespaceList_To_v1beta3_NamespaceList(in *api.NamespaceList, out *NamespaceList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NamespaceList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Namespace, len(in.Items)) + for i := range in.Items { + if err := convert_api_Namespace_To_v1beta3_Namespace(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_NamespaceSpec_To_v1beta3_NamespaceSpec(in *api.NamespaceSpec, out *NamespaceSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NamespaceSpec))(in) + } + if in.Finalizers != nil { + out.Finalizers = make([]FinalizerName, len(in.Finalizers)) + for i := range in.Finalizers { + out.Finalizers[i] = FinalizerName(in.Finalizers[i]) + } + } else { + out.Finalizers = nil + } + return nil +} + +func convert_api_NamespaceStatus_To_v1beta3_NamespaceStatus(in *api.NamespaceStatus, out *NamespaceStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NamespaceStatus))(in) + } + out.Phase = NamespacePhase(in.Phase) + return nil +} + +func convert_api_Node_To_v1beta3_Node(in *api.Node, out *Node, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Node))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_NodeSpec_To_v1beta3_NodeSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_api_NodeStatus_To_v1beta3_NodeStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_api_NodeAddress_To_v1beta3_NodeAddress(in *api.NodeAddress, out *NodeAddress, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NodeAddress))(in) + } + out.Type = NodeAddressType(in.Type) + out.Address = in.Address + return nil +} + +func convert_api_NodeCondition_To_v1beta3_NodeCondition(in *api.NodeCondition, out *NodeCondition, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NodeCondition))(in) + } + out.Type = NodeConditionType(in.Type) + out.Status = ConditionStatus(in.Status) + if err := s.Convert(&in.LastHeartbeatTime, &out.LastHeartbeatTime, 0); err != nil { + return err + } + if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message + return nil +} + +func convert_api_NodeList_To_v1beta3_NodeList(in *api.NodeList, out *NodeList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NodeList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Node, len(in.Items)) + for i := range in.Items { + if err := convert_api_Node_To_v1beta3_Node(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_NodeSpec_To_v1beta3_NodeSpec(in *api.NodeSpec, out *NodeSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NodeSpec))(in) + } + out.PodCIDR = in.PodCIDR + out.ExternalID = in.ExternalID + out.ProviderID = in.ProviderID + out.Unschedulable = in.Unschedulable + return nil +} + +func convert_api_NodeStatus_To_v1beta3_NodeStatus(in *api.NodeStatus, out *NodeStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NodeStatus))(in) + } + if in.Capacity != nil { + out.Capacity = make(ResourceList) + for key, val := range in.Capacity { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Capacity[ResourceName(key)] = newVal + } + } else { + out.Capacity = nil + } + out.Phase = NodePhase(in.Phase) + if in.Conditions != nil { + out.Conditions = make([]NodeCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := convert_api_NodeCondition_To_v1beta3_NodeCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + if in.Addresses != nil { + out.Addresses = make([]NodeAddress, len(in.Addresses)) + for i := range in.Addresses { + if err := convert_api_NodeAddress_To_v1beta3_NodeAddress(&in.Addresses[i], &out.Addresses[i], s); err != nil { + return err + } + } + } else { + out.Addresses = nil + } + if err := convert_api_NodeSystemInfo_To_v1beta3_NodeSystemInfo(&in.NodeInfo, &out.NodeInfo, s); err != nil { + return err + } + return nil +} + +func convert_api_NodeSystemInfo_To_v1beta3_NodeSystemInfo(in *api.NodeSystemInfo, out *NodeSystemInfo, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.NodeSystemInfo))(in) + } + out.MachineID = in.MachineID + out.SystemUUID = in.SystemUUID + out.BootID = in.BootID + out.KernelVersion = in.KernelVersion + out.OsImage = in.OsImage + out.ContainerRuntimeVersion = in.ContainerRuntimeVersion + out.KubeletVersion = in.KubeletVersion + out.KubeProxyVersion = in.KubeProxyVersion + return nil +} + +func convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(in *api.ObjectFieldSelector, out *ObjectFieldSelector, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ObjectFieldSelector))(in) + } + out.APIVersion = in.APIVersion + out.FieldPath = in.FieldPath + return nil +} + +func convert_api_ObjectMeta_To_v1beta3_ObjectMeta(in *api.ObjectMeta, out *ObjectMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ObjectMeta))(in) + } + out.Name = in.Name + out.GenerateName = in.GenerateName + out.Namespace = in.Namespace + out.SelfLink = in.SelfLink + out.UID = in.UID + out.ResourceVersion = in.ResourceVersion + out.Generation = in.Generation + if err := s.Convert(&in.CreationTimestamp, &out.CreationTimestamp, 0); err != nil { + return err + } + if in.DeletionTimestamp != nil { + if err := s.Convert(&in.DeletionTimestamp, &out.DeletionTimestamp, 0); err != nil { + return err + } + } else { + out.DeletionTimestamp = nil + } + if in.DeletionGracePeriodSeconds != nil { + out.DeletionGracePeriodSeconds = new(int64) + *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds + } else { + out.DeletionGracePeriodSeconds = nil + } + if in.Labels != nil { + out.Labels = make(map[string]string) + for key, val := range in.Labels { + out.Labels[key] = val + } + } else { + out.Labels = nil + } + if in.Annotations != nil { + out.Annotations = make(map[string]string) + for key, val := range in.Annotations { + out.Annotations[key] = val + } + } else { + out.Annotations = nil + } + return nil +} + +func convert_api_ObjectReference_To_v1beta3_ObjectReference(in *api.ObjectReference, out *ObjectReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ObjectReference))(in) + } + out.Kind = in.Kind + out.Namespace = in.Namespace + out.Name = in.Name + out.UID = in.UID + out.APIVersion = in.APIVersion + out.ResourceVersion = in.ResourceVersion + out.FieldPath = in.FieldPath + return nil +} + +func convert_api_PersistentVolume_To_v1beta3_PersistentVolume(in *api.PersistentVolume, out *PersistentVolume, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolume))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_PersistentVolumeSpec_To_v1beta3_PersistentVolumeSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_api_PersistentVolumeStatus_To_v1beta3_PersistentVolumeStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_api_PersistentVolumeClaim_To_v1beta3_PersistentVolumeClaim(in *api.PersistentVolumeClaim, out *PersistentVolumeClaim, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolumeClaim))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_PersistentVolumeClaimSpec_To_v1beta3_PersistentVolumeClaimSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_api_PersistentVolumeClaimStatus_To_v1beta3_PersistentVolumeClaimStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_api_PersistentVolumeClaimList_To_v1beta3_PersistentVolumeClaimList(in *api.PersistentVolumeClaimList, out *PersistentVolumeClaimList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolumeClaimList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]PersistentVolumeClaim, len(in.Items)) + for i := range in.Items { + if err := convert_api_PersistentVolumeClaim_To_v1beta3_PersistentVolumeClaim(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_PersistentVolumeClaimSpec_To_v1beta3_PersistentVolumeClaimSpec(in *api.PersistentVolumeClaimSpec, out *PersistentVolumeClaimSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolumeClaimSpec))(in) + } + if in.AccessModes != nil { + out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) + for i := range in.AccessModes { + out.AccessModes[i] = PersistentVolumeAccessMode(in.AccessModes[i]) + } + } else { + out.AccessModes = nil + } + if err := convert_api_ResourceRequirements_To_v1beta3_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { + return err + } + out.VolumeName = in.VolumeName + return nil +} + +func convert_api_PersistentVolumeClaimStatus_To_v1beta3_PersistentVolumeClaimStatus(in *api.PersistentVolumeClaimStatus, out *PersistentVolumeClaimStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolumeClaimStatus))(in) + } + out.Phase = PersistentVolumeClaimPhase(in.Phase) + if in.AccessModes != nil { + out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) + for i := range in.AccessModes { + out.AccessModes[i] = PersistentVolumeAccessMode(in.AccessModes[i]) + } + } else { + out.AccessModes = nil + } + if in.Capacity != nil { + out.Capacity = make(ResourceList) + for key, val := range in.Capacity { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Capacity[ResourceName(key)] = newVal + } + } else { + out.Capacity = nil + } + return nil +} + +func convert_api_PersistentVolumeClaimVolumeSource_To_v1beta3_PersistentVolumeClaimVolumeSource(in *api.PersistentVolumeClaimVolumeSource, out *PersistentVolumeClaimVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolumeClaimVolumeSource))(in) + } + out.ClaimName = in.ClaimName + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_PersistentVolumeList_To_v1beta3_PersistentVolumeList(in *api.PersistentVolumeList, out *PersistentVolumeList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolumeList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]PersistentVolume, len(in.Items)) + for i := range in.Items { + if err := convert_api_PersistentVolume_To_v1beta3_PersistentVolume(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_PersistentVolumeSource_To_v1beta3_PersistentVolumeSource(in *api.PersistentVolumeSource, out *PersistentVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolumeSource))(in) + } + if in.GCEPersistentDisk != nil { + out.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) + if err := convert_api_GCEPersistentDiskVolumeSource_To_v1beta3_GCEPersistentDiskVolumeSource(in.GCEPersistentDisk, out.GCEPersistentDisk, s); err != nil { + return err + } + } else { + out.GCEPersistentDisk = nil + } + if in.AWSElasticBlockStore != nil { + out.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) + if err := convert_api_AWSElasticBlockStoreVolumeSource_To_v1beta3_AWSElasticBlockStoreVolumeSource(in.AWSElasticBlockStore, out.AWSElasticBlockStore, s); err != nil { + return err + } + } else { + out.AWSElasticBlockStore = nil + } + if in.HostPath != nil { + out.HostPath = new(HostPathVolumeSource) + if err := convert_api_HostPathVolumeSource_To_v1beta3_HostPathVolumeSource(in.HostPath, out.HostPath, s); err != nil { + return err + } + } else { + out.HostPath = nil + } + if in.Glusterfs != nil { + out.Glusterfs = new(GlusterfsVolumeSource) + if err := convert_api_GlusterfsVolumeSource_To_v1beta3_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { + return err + } + } else { + out.Glusterfs = nil + } + if in.NFS != nil { + out.NFS = new(NFSVolumeSource) + if err := convert_api_NFSVolumeSource_To_v1beta3_NFSVolumeSource(in.NFS, out.NFS, s); err != nil { + return err + } + } else { + out.NFS = nil + } + if in.RBD != nil { + out.RBD = new(RBDVolumeSource) + if err := convert_api_RBDVolumeSource_To_v1beta3_RBDVolumeSource(in.RBD, out.RBD, s); err != nil { + return err + } + } else { + out.RBD = nil + } + if in.ISCSI != nil { + out.ISCSI = new(ISCSIVolumeSource) + if err := convert_api_ISCSIVolumeSource_To_v1beta3_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { + return err + } + } else { + out.ISCSI = nil + } + if in.Cinder != nil { + out.Cinder = new(CinderVolumeSource) + if err := convert_api_CinderVolumeSource_To_v1beta3_CinderVolumeSource(in.Cinder, out.Cinder, s); err != nil { + return err + } + } else { + out.Cinder = nil + } + if in.CephFS != nil { + out.CephFS = new(CephFSVolumeSource) + if err := convert_api_CephFSVolumeSource_To_v1beta3_CephFSVolumeSource(in.CephFS, out.CephFS, s); err != nil { + return err + } + } else { + out.CephFS = nil + } + return nil +} + +func convert_api_PersistentVolumeSpec_To_v1beta3_PersistentVolumeSpec(in *api.PersistentVolumeSpec, out *PersistentVolumeSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolumeSpec))(in) + } + if in.Capacity != nil { + out.Capacity = make(ResourceList) + for key, val := range in.Capacity { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Capacity[ResourceName(key)] = newVal + } + } else { + out.Capacity = nil + } + if err := convert_api_PersistentVolumeSource_To_v1beta3_PersistentVolumeSource(&in.PersistentVolumeSource, &out.PersistentVolumeSource, s); err != nil { + return err + } + if in.AccessModes != nil { + out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) + for i := range in.AccessModes { + out.AccessModes[i] = PersistentVolumeAccessMode(in.AccessModes[i]) + } + } else { + out.AccessModes = nil + } + if in.ClaimRef != nil { + out.ClaimRef = new(ObjectReference) + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(in.ClaimRef, out.ClaimRef, s); err != nil { + return err + } + } else { + out.ClaimRef = nil + } + out.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimPolicy(in.PersistentVolumeReclaimPolicy) + return nil +} + +func convert_api_PersistentVolumeStatus_To_v1beta3_PersistentVolumeStatus(in *api.PersistentVolumeStatus, out *PersistentVolumeStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PersistentVolumeStatus))(in) + } + out.Phase = PersistentVolumePhase(in.Phase) + out.Message = in.Message + out.Reason = in.Reason + return nil +} + +func convert_api_Pod_To_v1beta3_Pod(in *api.Pod, out *Pod, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Pod))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_PodSpec_To_v1beta3_PodSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_api_PodStatus_To_v1beta3_PodStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_api_PodCondition_To_v1beta3_PodCondition(in *api.PodCondition, out *PodCondition, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodCondition))(in) + } + out.Type = PodConditionType(in.Type) + out.Status = ConditionStatus(in.Status) + return nil +} + +func convert_api_PodExecOptions_To_v1beta3_PodExecOptions(in *api.PodExecOptions, out *PodExecOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodExecOptions))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + out.Stdin = in.Stdin + out.Stdout = in.Stdout + out.Stderr = in.Stderr + out.TTY = in.TTY + out.Container = in.Container + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + return nil +} + +func convert_api_PodList_To_v1beta3_PodList(in *api.PodList, out *PodList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Pod, len(in.Items)) + for i := range in.Items { + if err := convert_api_Pod_To_v1beta3_Pod(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_PodLogOptions_To_v1beta3_PodLogOptions(in *api.PodLogOptions, out *PodLogOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodLogOptions))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + out.Container = in.Container + out.Follow = in.Follow + out.Previous = in.Previous + return nil +} + +func convert_api_PodProxyOptions_To_v1beta3_PodProxyOptions(in *api.PodProxyOptions, out *PodProxyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodProxyOptions))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + out.Path = in.Path + return nil +} + +func convert_api_PodStatus_To_v1beta3_PodStatus(in *api.PodStatus, out *PodStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodStatus))(in) + } + out.Phase = PodPhase(in.Phase) + if in.Conditions != nil { + out.Conditions = make([]PodCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := convert_api_PodCondition_To_v1beta3_PodCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + out.Message = in.Message + out.Reason = in.Reason + out.HostIP = in.HostIP + out.PodIP = in.PodIP + if in.StartTime != nil { + if err := s.Convert(&in.StartTime, &out.StartTime, 0); err != nil { + return err + } + } else { + out.StartTime = nil + } + if in.ContainerStatuses != nil { + out.ContainerStatuses = make([]ContainerStatus, len(in.ContainerStatuses)) + for i := range in.ContainerStatuses { + if err := convert_api_ContainerStatus_To_v1beta3_ContainerStatus(&in.ContainerStatuses[i], &out.ContainerStatuses[i], s); err != nil { + return err + } + } + } else { + out.ContainerStatuses = nil + } + return nil +} + +func convert_api_PodStatusResult_To_v1beta3_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodStatusResult))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_PodStatus_To_v1beta3_PodStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_api_PodTemplate_To_v1beta3_PodTemplate(in *api.PodTemplate, out *PodTemplate, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodTemplate))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_PodTemplateSpec_To_v1beta3_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +func convert_api_PodTemplateList_To_v1beta3_PodTemplateList(in *api.PodTemplateList, out *PodTemplateList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodTemplateList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]PodTemplate, len(in.Items)) + for i := range in.Items { + if err := convert_api_PodTemplate_To_v1beta3_PodTemplate(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_PodTemplateSpec_To_v1beta3_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PodTemplateSpec))(in) + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_PodSpec_To_v1beta3_PodSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_api_Probe_To_v1beta3_Probe(in *api.Probe, out *Probe, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Probe))(in) + } + if err := convert_api_Handler_To_v1beta3_Handler(&in.Handler, &out.Handler, s); err != nil { + return err + } + out.InitialDelaySeconds = in.InitialDelaySeconds + out.TimeoutSeconds = in.TimeoutSeconds + return nil +} + +func convert_api_RBDVolumeSource_To_v1beta3_RBDVolumeSource(in *api.RBDVolumeSource, out *RBDVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.RBDVolumeSource))(in) + } + if in.CephMonitors != nil { + out.CephMonitors = make([]string, len(in.CephMonitors)) + for i := range in.CephMonitors { + out.CephMonitors[i] = in.CephMonitors[i] + } + } else { + out.CephMonitors = nil + } + out.RBDImage = in.RBDImage + out.FSType = in.FSType + out.RBDPool = in.RBDPool + out.RadosUser = in.RadosUser + out.Keyring = in.Keyring + if in.SecretRef != nil { + out.SecretRef = new(LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_api_RangeAllocation_To_v1beta3_RangeAllocation(in *api.RangeAllocation, out *RangeAllocation, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.RangeAllocation))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.Range = in.Range + if err := s.Convert(&in.Data, &out.Data, 0); err != nil { + return err + } + return nil +} + +func convert_api_ReplicationController_To_v1beta3_ReplicationController(in *api.ReplicationController, out *ReplicationController, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ReplicationController))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_ReplicationControllerSpec_To_v1beta3_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_api_ReplicationControllerStatus_To_v1beta3_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_api_ReplicationControllerList_To_v1beta3_ReplicationControllerList(in *api.ReplicationControllerList, out *ReplicationControllerList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ReplicationControllerList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ReplicationController, len(in.Items)) + for i := range in.Items { + if err := convert_api_ReplicationController_To_v1beta3_ReplicationController(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_ReplicationControllerStatus_To_v1beta3_ReplicationControllerStatus(in *api.ReplicationControllerStatus, out *ReplicationControllerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ReplicationControllerStatus))(in) + } + out.Replicas = in.Replicas + out.ObservedGeneration = in.ObservedGeneration + return nil +} + +func convert_api_ResourceQuota_To_v1beta3_ResourceQuota(in *api.ResourceQuota, out *ResourceQuota, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ResourceQuota))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_ResourceQuotaSpec_To_v1beta3_ResourceQuotaSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_api_ResourceQuotaStatus_To_v1beta3_ResourceQuotaStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_api_ResourceQuotaList_To_v1beta3_ResourceQuotaList(in *api.ResourceQuotaList, out *ResourceQuotaList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ResourceQuotaList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ResourceQuota, len(in.Items)) + for i := range in.Items { + if err := convert_api_ResourceQuota_To_v1beta3_ResourceQuota(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_ResourceQuotaSpec_To_v1beta3_ResourceQuotaSpec(in *api.ResourceQuotaSpec, out *ResourceQuotaSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ResourceQuotaSpec))(in) + } + if in.Hard != nil { + out.Hard = make(ResourceList) + for key, val := range in.Hard { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Hard[ResourceName(key)] = newVal + } + } else { + out.Hard = nil + } + return nil +} + +func convert_api_ResourceQuotaStatus_To_v1beta3_ResourceQuotaStatus(in *api.ResourceQuotaStatus, out *ResourceQuotaStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ResourceQuotaStatus))(in) + } + if in.Hard != nil { + out.Hard = make(ResourceList) + for key, val := range in.Hard { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Hard[ResourceName(key)] = newVal + } + } else { + out.Hard = nil + } + if in.Used != nil { + out.Used = make(ResourceList) + for key, val := range in.Used { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Used[ResourceName(key)] = newVal + } + } else { + out.Used = nil + } + return nil +} + +func convert_api_ResourceRequirements_To_v1beta3_ResourceRequirements(in *api.ResourceRequirements, out *ResourceRequirements, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ResourceRequirements))(in) + } + if in.Limits != nil { + out.Limits = make(ResourceList) + for key, val := range in.Limits { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Limits[ResourceName(key)] = newVal + } + } else { + out.Limits = nil + } + if in.Requests != nil { + out.Requests = make(ResourceList) + for key, val := range in.Requests { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Requests[ResourceName(key)] = newVal + } + } else { + out.Requests = nil + } + return nil +} + +func convert_api_FSGroupStrategyOptions_To_v1beta3_FSGroupStrategyOptions(in *api.FSGroupStrategyOptions, out *FSGroupStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.FSGroupStrategyOptions))(in) + } + out.Type = FSGroupStrategyType(in.Type) + if in.Ranges != nil { + out.Ranges = make([]IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := convert_api_IDRange_To_v1beta3_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func convert_api_SupplementalGroupsStrategyOptions_To_v1beta3_SupplementalGroupsStrategyOptions(in *api.SupplementalGroupsStrategyOptions, out *SupplementalGroupsStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SupplementalGroupsStrategyOptions))(in) + } + out.Type = SupplementalGroupsStrategyType(in.Type) + if in.Ranges != nil { + out.Ranges = make([]IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := convert_api_IDRange_To_v1beta3_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func convert_api_IDRange_To_v1beta3_IDRange(in *api.IDRange, out *IDRange, s conversion.Scope) error { + out.Min = in.Min + out.Max = in.Max + return nil +} + +func convert_api_RunAsUserStrategyOptions_To_v1beta3_RunAsUserStrategyOptions(in *api.RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.RunAsUserStrategyOptions))(in) + } + out.Type = RunAsUserStrategyType(in.Type) + if in.UID != nil { + out.UID = new(int64) + *out.UID = *in.UID + } else { + out.UID = nil + } + if in.UIDRangeMin != nil { + out.UIDRangeMin = new(int64) + *out.UIDRangeMin = *in.UIDRangeMin + } else { + out.UIDRangeMin = nil + } + if in.UIDRangeMax != nil { + out.UIDRangeMax = new(int64) + *out.UIDRangeMax = *in.UIDRangeMax + } else { + out.UIDRangeMax = nil + } + return nil +} + +func convert_api_SELinuxContextStrategyOptions_To_v1beta3_SELinuxContextStrategyOptions(in *api.SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SELinuxContextStrategyOptions))(in) + } + out.Type = SELinuxContextStrategyType(in.Type) + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(SELinuxOptions) + if err := convert_api_SELinuxOptions_To_v1beta3_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + return nil +} + +func convert_api_SELinuxOptions_To_v1beta3_SELinuxOptions(in *api.SELinuxOptions, out *SELinuxOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SELinuxOptions))(in) + } + out.User = in.User + out.Role = in.Role + out.Type = in.Type + out.Level = in.Level + return nil +} + +func convert_api_Secret_To_v1beta3_Secret(in *api.Secret, out *Secret, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Secret))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Data != nil { + out.Data = make(map[string][]uint8) + for key, val := range in.Data { + newVal := []uint8{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Data[key] = newVal + } + } else { + out.Data = nil + } + out.Type = SecretType(in.Type) + return nil +} + +func convert_api_SecretList_To_v1beta3_SecretList(in *api.SecretList, out *SecretList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SecretList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Secret, len(in.Items)) + for i := range in.Items { + if err := convert_api_Secret_To_v1beta3_Secret(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_SecretVolumeSource_To_v1beta3_SecretVolumeSource(in *api.SecretVolumeSource, out *SecretVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SecretVolumeSource))(in) + } + out.SecretName = in.SecretName + return nil +} + +func convert_api_SecurityContext_To_v1beta3_SecurityContext(in *api.SecurityContext, out *SecurityContext, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SecurityContext))(in) + } + if in.Capabilities != nil { + out.Capabilities = new(Capabilities) + if err := convert_api_Capabilities_To_v1beta3_Capabilities(in.Capabilities, out.Capabilities, s); err != nil { + return err + } + } else { + out.Capabilities = nil + } + if in.Privileged != nil { + out.Privileged = new(bool) + *out.Privileged = *in.Privileged + } else { + out.Privileged = nil + } + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(SELinuxOptions) + if err := convert_api_SELinuxOptions_To_v1beta3_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + if in.RunAsUser != nil { + out.RunAsUser = new(int64) + *out.RunAsUser = *in.RunAsUser + } else { + out.RunAsUser = nil + } + out.RunAsNonRoot = in.RunAsNonRoot + return nil +} + +func convert_api_SecurityContextConstraints_To_v1beta3_SecurityContextConstraints(in *api.SecurityContextConstraints, out *SecurityContextConstraints, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SecurityContextConstraints))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.AllowPrivilegedContainer = in.AllowPrivilegedContainer + if in.AllowedCapabilities != nil { + out.AllowedCapabilities = make([]Capability, len(in.AllowedCapabilities)) + for i := range in.AllowedCapabilities { + out.AllowedCapabilities[i] = Capability(in.AllowedCapabilities[i]) + } + } else { + out.AllowedCapabilities = nil + } + out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + out.AllowHostNetwork = in.AllowHostNetwork + out.AllowHostPorts = in.AllowHostPorts + out.AllowHostPID = in.AllowHostPID + out.AllowHostIPC = in.AllowHostIPC + if err := convert_api_SELinuxContextStrategyOptions_To_v1beta3_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil { + return err + } + if err := convert_api_RunAsUserStrategyOptions_To_v1beta3_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil { + return err + } + if err := convert_api_FSGroupStrategyOptions_To_v1beta3_FSGroupStrategyOptions(&in.FSGroup, &out.FSGroup, s); err != nil { + return err + } + if err := convert_api_SupplementalGroupsStrategyOptions_To_v1beta3_SupplementalGroupsStrategyOptions(&in.SupplementalGroups, &out.SupplementalGroups, s); err != nil { + return err + } + if in.Users != nil { + out.Users = make([]string, len(in.Users)) + for i := range in.Users { + out.Users[i] = in.Users[i] + } + } else { + out.Users = nil + } + if in.Groups != nil { + out.Groups = make([]string, len(in.Groups)) + for i := range in.Groups { + out.Groups[i] = in.Groups[i] + } + } else { + out.Groups = nil + } + return nil +} + +func convert_api_SecurityContextConstraintsList_To_v1beta3_SecurityContextConstraintsList(in *api.SecurityContextConstraintsList, out *SecurityContextConstraintsList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SecurityContextConstraintsList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]SecurityContextConstraints, len(in.Items)) + for i := range in.Items { + if err := convert_api_SecurityContextConstraints_To_v1beta3_SecurityContextConstraints(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_SerializedReference_To_v1beta3_SerializedReference(in *api.SerializedReference, out *SerializedReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SerializedReference))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.Reference, &out.Reference, s); err != nil { + return err + } + return nil +} + +func convert_api_Service_To_v1beta3_Service(in *api.Service, out *Service, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Service))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_api_ServiceSpec_To_v1beta3_ServiceSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_api_ServiceStatus_To_v1beta3_ServiceStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_api_ServiceAccount_To_v1beta3_ServiceAccount(in *api.ServiceAccount, out *ServiceAccount, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ServiceAccount))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Secrets != nil { + out.Secrets = make([]ObjectReference, len(in.Secrets)) + for i := range in.Secrets { + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.Secrets[i], &out.Secrets[i], s); err != nil { + return err + } + } + } else { + out.Secrets = nil + } + if in.ImagePullSecrets != nil { + out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) + for i := range in.ImagePullSecrets { + if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { + return err + } + } + } else { + out.ImagePullSecrets = nil + } + return nil +} + +func convert_api_ServiceAccountList_To_v1beta3_ServiceAccountList(in *api.ServiceAccountList, out *ServiceAccountList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ServiceAccountList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ServiceAccount, len(in.Items)) + for i := range in.Items { + if err := convert_api_ServiceAccount_To_v1beta3_ServiceAccount(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_ServiceList_To_v1beta3_ServiceList(in *api.ServiceList, out *ServiceList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ServiceList))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Service, len(in.Items)) + for i := range in.Items { + if err := convert_api_Service_To_v1beta3_Service(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_ServicePort_To_v1beta3_ServicePort(in *api.ServicePort, out *ServicePort, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ServicePort))(in) + } + out.Name = in.Name + out.Protocol = Protocol(in.Protocol) + out.Port = in.Port + if err := s.Convert(&in.TargetPort, &out.TargetPort, 0); err != nil { + return err + } + out.NodePort = in.NodePort + return nil +} + +func convert_api_ServiceStatus_To_v1beta3_ServiceStatus(in *api.ServiceStatus, out *ServiceStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ServiceStatus))(in) + } + if err := convert_api_LoadBalancerStatus_To_v1beta3_LoadBalancerStatus(&in.LoadBalancer, &out.LoadBalancer, s); err != nil { + return err + } + return nil +} + +func convert_api_Status_To_v1beta3_Status(in *unversioned.Status, out *Status, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*unversioned.Status))(in) + } + if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + out.Status = in.Status + out.Message = in.Message + out.Reason = StatusReason(in.Reason) + if in.Details != nil { + out.Details = new(StatusDetails) + if err := convert_api_StatusDetails_To_v1beta3_StatusDetails(in.Details, out.Details, s); err != nil { + return err + } + } else { + out.Details = nil + } + out.Code = in.Code + return nil +} + +func convert_api_TCPSocketAction_To_v1beta3_TCPSocketAction(in *api.TCPSocketAction, out *TCPSocketAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.TCPSocketAction))(in) + } + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + return nil +} + +func convert_api_TypeMeta_To_v1beta3_TypeMeta(in *unversioned.TypeMeta, out *TypeMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*unversioned.TypeMeta))(in) + } + out.Kind = in.Kind + out.APIVersion = in.APIVersion + return nil +} + +func convert_api_Volume_To_v1beta3_Volume(in *api.Volume, out *Volume, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Volume))(in) + } + out.Name = in.Name + if err := convert_api_VolumeSource_To_v1beta3_VolumeSource(&in.VolumeSource, &out.VolumeSource, s); err != nil { + return err + } + return nil +} + +func convert_api_VolumeMount_To_v1beta3_VolumeMount(in *api.VolumeMount, out *VolumeMount, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.VolumeMount))(in) + } + out.Name = in.Name + out.ReadOnly = in.ReadOnly + out.MountPath = in.MountPath + return nil +} + +func convert_v1beta3_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in *AWSElasticBlockStoreVolumeSource, out *api.AWSElasticBlockStoreVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*AWSElasticBlockStoreVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1beta3_Binding_To_api_Binding(in *Binding, out *api.Binding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Binding))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.Target, &out.Target, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_Capabilities_To_api_Capabilities(in *Capabilities, out *api.Capabilities, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Capabilities))(in) + } + if in.Add != nil { + out.Add = make([]api.Capability, len(in.Add)) + for i := range in.Add { + out.Add[i] = api.Capability(in.Add[i]) + } + } else { + out.Add = nil + } + if in.Drop != nil { + out.Drop = make([]api.Capability, len(in.Drop)) + for i := range in.Drop { + out.Drop[i] = api.Capability(in.Drop[i]) + } + } else { + out.Drop = nil + } + return nil +} + +func convert_v1beta3_CephFSVolumeSource_To_api_CephFSVolumeSource(in *CephFSVolumeSource, out *api.CephFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*CephFSVolumeSource))(in) + } + if in.Monitors != nil { + out.Monitors = make([]string, len(in.Monitors)) + for i := range in.Monitors { + out.Monitors[i] = in.Monitors[i] + } + } else { + out.Monitors = nil + } + out.User = in.User + out.SecretFile = in.SecretFile + if in.SecretRef != nil { + out.SecretRef = new(api.LocalObjectReference) + if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1beta3_CinderVolumeSource_To_api_CinderVolumeSource(in *CinderVolumeSource, out *api.CinderVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*CinderVolumeSource))(in) + } + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1beta3_ComponentCondition_To_api_ComponentCondition(in *ComponentCondition, out *api.ComponentCondition, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ComponentCondition))(in) + } + out.Type = api.ComponentConditionType(in.Type) + out.Status = api.ConditionStatus(in.Status) + out.Message = in.Message + out.Error = in.Error + return nil +} + +func convert_v1beta3_ComponentStatus_To_api_ComponentStatus(in *ComponentStatus, out *api.ComponentStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ComponentStatus))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Conditions != nil { + out.Conditions = make([]api.ComponentCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := convert_v1beta3_ComponentCondition_To_api_ComponentCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +func convert_v1beta3_ComponentStatusList_To_api_ComponentStatusList(in *ComponentStatusList, out *api.ComponentStatusList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ComponentStatusList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.ComponentStatus, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_ComponentStatus_To_api_ComponentStatus(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_ContainerPort_To_api_ContainerPort(in *ContainerPort, out *api.ContainerPort, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ContainerPort))(in) + } + out.Name = in.Name + out.HostPort = in.HostPort + out.ContainerPort = in.ContainerPort + out.Protocol = api.Protocol(in.Protocol) + out.HostIP = in.HostIP + return nil +} + +func convert_v1beta3_ContainerStateRunning_To_api_ContainerStateRunning(in *ContainerStateRunning, out *api.ContainerStateRunning, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ContainerStateRunning))(in) + } + if err := s.Convert(&in.StartedAt, &out.StartedAt, 0); err != nil { + return err + } + return nil +} + +func convert_v1beta3_ContainerStateWaiting_To_api_ContainerStateWaiting(in *ContainerStateWaiting, out *api.ContainerStateWaiting, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ContainerStateWaiting))(in) + } + out.Reason = in.Reason + return nil +} + +func convert_v1beta3_ContainerStatus_To_api_ContainerStatus(in *ContainerStatus, out *api.ContainerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ContainerStatus))(in) + } + out.Name = in.Name + if err := convert_v1beta3_ContainerState_To_api_ContainerState(&in.State, &out.State, s); err != nil { + return err + } + if err := convert_v1beta3_ContainerState_To_api_ContainerState(&in.LastTerminationState, &out.LastTerminationState, s); err != nil { + return err + } + out.Ready = in.Ready + out.RestartCount = in.RestartCount + out.Image = in.Image + out.ImageID = in.ImageID + out.ContainerID = in.ContainerID + return nil +} + +func convert_v1beta3_DeleteOptions_To_api_DeleteOptions(in *DeleteOptions, out *api.DeleteOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DeleteOptions))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if in.GracePeriodSeconds != nil { + out.GracePeriodSeconds = new(int64) + *out.GracePeriodSeconds = *in.GracePeriodSeconds + } else { + out.GracePeriodSeconds = nil + } + return nil +} + +func convert_v1beta3_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *DownwardAPIVolumeFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DownwardAPIVolumeFile))(in) + } + out.Path = in.Path + if err := convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource(in *DownwardAPIVolumeSource, out *api.DownwardAPIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*DownwardAPIVolumeSource))(in) + } + if in.Items != nil { + out.Items = make([]api.DownwardAPIVolumeFile, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource(in *EmptyDirVolumeSource, out *api.EmptyDirVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*EmptyDirVolumeSource))(in) + } + out.Medium = api.StorageMedium(in.Medium) + return nil +} + +func convert_v1beta3_EndpointAddress_To_api_EndpointAddress(in *EndpointAddress, out *api.EndpointAddress, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*EndpointAddress))(in) + } + out.IP = in.IP + if in.TargetRef != nil { + out.TargetRef = new(api.ObjectReference) + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(in.TargetRef, out.TargetRef, s); err != nil { + return err + } + } else { + out.TargetRef = nil + } + return nil +} + +func convert_v1beta3_EndpointPort_To_api_EndpointPort(in *EndpointPort, out *api.EndpointPort, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*EndpointPort))(in) + } + out.Name = in.Name + out.Port = in.Port + out.Protocol = api.Protocol(in.Protocol) + return nil +} + +func convert_v1beta3_EndpointSubset_To_api_EndpointSubset(in *EndpointSubset, out *api.EndpointSubset, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*EndpointSubset))(in) + } + if in.Addresses != nil { + out.Addresses = make([]api.EndpointAddress, len(in.Addresses)) + for i := range in.Addresses { + if err := convert_v1beta3_EndpointAddress_To_api_EndpointAddress(&in.Addresses[i], &out.Addresses[i], s); err != nil { + return err + } + } + } else { + out.Addresses = nil + } + if in.Ports != nil { + out.Ports = make([]api.EndpointPort, len(in.Ports)) + for i := range in.Ports { + if err := convert_v1beta3_EndpointPort_To_api_EndpointPort(&in.Ports[i], &out.Ports[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + return nil +} + +func convert_v1beta3_Endpoints_To_api_Endpoints(in *Endpoints, out *api.Endpoints, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Endpoints))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Subsets != nil { + out.Subsets = make([]api.EndpointSubset, len(in.Subsets)) + for i := range in.Subsets { + if err := convert_v1beta3_EndpointSubset_To_api_EndpointSubset(&in.Subsets[i], &out.Subsets[i], s); err != nil { + return err + } + } + } else { + out.Subsets = nil + } + return nil +} + +func convert_v1beta3_EndpointsList_To_api_EndpointsList(in *EndpointsList, out *api.EndpointsList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*EndpointsList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.Endpoints, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_Endpoints_To_api_Endpoints(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_EnvVar_To_api_EnvVar(in *EnvVar, out *api.EnvVar, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*EnvVar))(in) + } + out.Name = in.Name + out.Value = in.Value + if in.ValueFrom != nil { + out.ValueFrom = new(api.EnvVarSource) + if err := convert_v1beta3_EnvVarSource_To_api_EnvVarSource(in.ValueFrom, out.ValueFrom, s); err != nil { + return err + } + } else { + out.ValueFrom = nil + } + return nil +} + +func convert_v1beta3_EnvVarSource_To_api_EnvVarSource(in *EnvVarSource, out *api.EnvVarSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*EnvVarSource))(in) + } + if in.FieldRef != nil { + out.FieldRef = new(api.ObjectFieldSelector) + if err := convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(in.FieldRef, out.FieldRef, s); err != nil { + return err + } + } else { + out.FieldRef = nil + } + return nil +} + +func convert_v1beta3_Event_To_api_Event(in *Event, out *api.Event, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Event))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.InvolvedObject, &out.InvolvedObject, s); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message + if err := convert_v1beta3_EventSource_To_api_EventSource(&in.Source, &out.Source, s); err != nil { + return err + } + if err := s.Convert(&in.FirstTimestamp, &out.FirstTimestamp, 0); err != nil { + return err + } + if err := s.Convert(&in.LastTimestamp, &out.LastTimestamp, 0); err != nil { + return err + } + out.Count = in.Count + return nil +} + +func convert_v1beta3_EventList_To_api_EventList(in *EventList, out *api.EventList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*EventList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.Event, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_Event_To_api_Event(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_EventSource_To_api_EventSource(in *EventSource, out *api.EventSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*EventSource))(in) + } + out.Component = in.Component + out.Host = in.Host + return nil +} + +func convert_v1beta3_ExecAction_To_api_ExecAction(in *ExecAction, out *api.ExecAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ExecAction))(in) + } + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + return nil +} + +func convert_v1beta3_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in *GCEPersistentDiskVolumeSource, out *api.GCEPersistentDiskVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*GCEPersistentDiskVolumeSource))(in) + } + out.PDName = in.PDName + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1beta3_GitRepoVolumeSource_To_api_GitRepoVolumeSource(in *GitRepoVolumeSource, out *api.GitRepoVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*GitRepoVolumeSource))(in) + } + out.Repository = in.Repository + out.Revision = in.Revision + return nil +} + +func convert_v1beta3_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in *GlusterfsVolumeSource, out *api.GlusterfsVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*GlusterfsVolumeSource))(in) + } + out.EndpointsName = in.EndpointsName + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1beta3_HTTPGetAction_To_api_HTTPGetAction(in *HTTPGetAction, out *api.HTTPGetAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HTTPGetAction))(in) + } + out.Path = in.Path + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + out.Host = in.Host + out.Scheme = api.URIScheme(in.Scheme) + return nil +} + +func convert_v1beta3_Handler_To_api_Handler(in *Handler, out *api.Handler, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Handler))(in) + } + if in.Exec != nil { + out.Exec = new(api.ExecAction) + if err := convert_v1beta3_ExecAction_To_api_ExecAction(in.Exec, out.Exec, s); err != nil { + return err + } + } else { + out.Exec = nil + } + if in.HTTPGet != nil { + out.HTTPGet = new(api.HTTPGetAction) + if err := convert_v1beta3_HTTPGetAction_To_api_HTTPGetAction(in.HTTPGet, out.HTTPGet, s); err != nil { + return err + } + } else { + out.HTTPGet = nil + } + if in.TCPSocket != nil { + out.TCPSocket = new(api.TCPSocketAction) + if err := convert_v1beta3_TCPSocketAction_To_api_TCPSocketAction(in.TCPSocket, out.TCPSocket, s); err != nil { + return err + } + } else { + out.TCPSocket = nil + } + return nil +} + +func convert_v1beta3_HostPathVolumeSource_To_api_HostPathVolumeSource(in *HostPathVolumeSource, out *api.HostPathVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*HostPathVolumeSource))(in) + } + out.Path = in.Path + return nil +} + +func convert_v1beta3_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in *ISCSIVolumeSource, out *api.ISCSIVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ISCSIVolumeSource))(in) + } + out.TargetPortal = in.TargetPortal + out.IQN = in.IQN + out.Lun = in.Lun + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1beta3_Lifecycle_To_api_Lifecycle(in *Lifecycle, out *api.Lifecycle, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Lifecycle))(in) + } + if in.PostStart != nil { + out.PostStart = new(api.Handler) + if err := convert_v1beta3_Handler_To_api_Handler(in.PostStart, out.PostStart, s); err != nil { + return err + } + } else { + out.PostStart = nil + } + if in.PreStop != nil { + out.PreStop = new(api.Handler) + if err := convert_v1beta3_Handler_To_api_Handler(in.PreStop, out.PreStop, s); err != nil { + return err + } + } else { + out.PreStop = nil + } + return nil +} + +func convert_v1beta3_LimitRange_To_api_LimitRange(in *LimitRange, out *api.LimitRange, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*LimitRange))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_LimitRangeSpec_To_api_LimitRangeSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_LimitRangeItem_To_api_LimitRangeItem(in *LimitRangeItem, out *api.LimitRangeItem, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*LimitRangeItem))(in) + } + out.Type = api.LimitType(in.Type) + if in.Max != nil { + out.Max = make(api.ResourceList) + for key, val := range in.Max { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Max[api.ResourceName(key)] = newVal + } + } else { + out.Max = nil + } + if in.Min != nil { + out.Min = make(api.ResourceList) + for key, val := range in.Min { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Min[api.ResourceName(key)] = newVal + } + } else { + out.Min = nil + } + if in.Default != nil { + out.Default = make(api.ResourceList) + for key, val := range in.Default { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Default[api.ResourceName(key)] = newVal + } + } else { + out.Default = nil + } + if in.DefaultRequest != nil { + out.DefaultRequest = make(api.ResourceList) + for key, val := range in.DefaultRequest { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.DefaultRequest[api.ResourceName(key)] = newVal + } + } else { + out.DefaultRequest = nil + } + if in.MaxLimitRequestRatio != nil { + out.MaxLimitRequestRatio = make(api.ResourceList) + for key, val := range in.MaxLimitRequestRatio { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.MaxLimitRequestRatio[api.ResourceName(key)] = newVal + } + } else { + out.MaxLimitRequestRatio = nil + } + return nil +} + +func convert_v1beta3_LimitRangeList_To_api_LimitRangeList(in *LimitRangeList, out *api.LimitRangeList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*LimitRangeList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.LimitRange, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_LimitRange_To_api_LimitRange(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_LimitRangeSpec_To_api_LimitRangeSpec(in *LimitRangeSpec, out *api.LimitRangeSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*LimitRangeSpec))(in) + } + if in.Limits != nil { + out.Limits = make([]api.LimitRangeItem, len(in.Limits)) + for i := range in.Limits { + if err := convert_v1beta3_LimitRangeItem_To_api_LimitRangeItem(&in.Limits[i], &out.Limits[i], s); err != nil { + return err + } + } + } else { + out.Limits = nil + } + return nil +} + +func convert_v1beta3_List_To_api_List(in *List, out *api.List, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*List))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Items, &out.Items, 0); err != nil { + return err + } + return nil +} + +func convert_v1beta3_ListMeta_To_api_ListMeta(in *ListMeta, out *unversioned.ListMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ListMeta))(in) + } + out.SelfLink = in.SelfLink + out.ResourceVersion = in.ResourceVersion + return nil +} + +func convert_v1beta3_ListOptions_To_api_ListOptions(in *ListOptions, out *api.ListOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ListOptions))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LabelSelector, &out.LabelSelector, 0); err != nil { + return err + } + if err := s.Convert(&in.FieldSelector, &out.FieldSelector, 0); err != nil { + return err + } + out.Watch = in.Watch + out.ResourceVersion = in.ResourceVersion + return nil +} + +func convert_v1beta3_LoadBalancerIngress_To_api_LoadBalancerIngress(in *LoadBalancerIngress, out *api.LoadBalancerIngress, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*LoadBalancerIngress))(in) + } + out.IP = in.IP + out.Hostname = in.Hostname + return nil +} + +func convert_v1beta3_LoadBalancerStatus_To_api_LoadBalancerStatus(in *LoadBalancerStatus, out *api.LoadBalancerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*LoadBalancerStatus))(in) + } + if in.Ingress != nil { + out.Ingress = make([]api.LoadBalancerIngress, len(in.Ingress)) + for i := range in.Ingress { + if err := convert_v1beta3_LoadBalancerIngress_To_api_LoadBalancerIngress(&in.Ingress[i], &out.Ingress[i], s); err != nil { + return err + } + } + } else { + out.Ingress = nil + } + return nil +} + +func convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in *LocalObjectReference, out *api.LocalObjectReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*LocalObjectReference))(in) + } + out.Name = in.Name + return nil +} + +func convert_v1beta3_NFSVolumeSource_To_api_NFSVolumeSource(in *NFSVolumeSource, out *api.NFSVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NFSVolumeSource))(in) + } + out.Server = in.Server + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1beta3_Namespace_To_api_Namespace(in *Namespace, out *api.Namespace, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Namespace))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_NamespaceSpec_To_api_NamespaceSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta3_NamespaceStatus_To_api_NamespaceStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_NamespaceList_To_api_NamespaceList(in *NamespaceList, out *api.NamespaceList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NamespaceList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.Namespace, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_Namespace_To_api_Namespace(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_NamespaceSpec_To_api_NamespaceSpec(in *NamespaceSpec, out *api.NamespaceSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NamespaceSpec))(in) + } + if in.Finalizers != nil { + out.Finalizers = make([]api.FinalizerName, len(in.Finalizers)) + for i := range in.Finalizers { + out.Finalizers[i] = api.FinalizerName(in.Finalizers[i]) + } + } else { + out.Finalizers = nil + } + return nil +} + +func convert_v1beta3_NamespaceStatus_To_api_NamespaceStatus(in *NamespaceStatus, out *api.NamespaceStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NamespaceStatus))(in) + } + out.Phase = api.NamespacePhase(in.Phase) + return nil +} + +func convert_v1beta3_Node_To_api_Node(in *Node, out *api.Node, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Node))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_NodeSpec_To_api_NodeSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta3_NodeStatus_To_api_NodeStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_NodeAddress_To_api_NodeAddress(in *NodeAddress, out *api.NodeAddress, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NodeAddress))(in) + } + out.Type = api.NodeAddressType(in.Type) + out.Address = in.Address + return nil +} + +func convert_v1beta3_NodeCondition_To_api_NodeCondition(in *NodeCondition, out *api.NodeCondition, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NodeCondition))(in) + } + out.Type = api.NodeConditionType(in.Type) + out.Status = api.ConditionStatus(in.Status) + if err := s.Convert(&in.LastHeartbeatTime, &out.LastHeartbeatTime, 0); err != nil { + return err + } + if err := s.Convert(&in.LastTransitionTime, &out.LastTransitionTime, 0); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message + return nil +} + +func convert_v1beta3_NodeList_To_api_NodeList(in *NodeList, out *api.NodeList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NodeList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.Node, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_Node_To_api_Node(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_NodeSpec_To_api_NodeSpec(in *NodeSpec, out *api.NodeSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NodeSpec))(in) + } + out.PodCIDR = in.PodCIDR + out.ExternalID = in.ExternalID + out.ProviderID = in.ProviderID + out.Unschedulable = in.Unschedulable + return nil +} + +func convert_v1beta3_NodeStatus_To_api_NodeStatus(in *NodeStatus, out *api.NodeStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NodeStatus))(in) + } + if in.Capacity != nil { + out.Capacity = make(api.ResourceList) + for key, val := range in.Capacity { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Capacity[api.ResourceName(key)] = newVal + } + } else { + out.Capacity = nil + } + out.Phase = api.NodePhase(in.Phase) + if in.Conditions != nil { + out.Conditions = make([]api.NodeCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := convert_v1beta3_NodeCondition_To_api_NodeCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + if in.Addresses != nil { + out.Addresses = make([]api.NodeAddress, len(in.Addresses)) + for i := range in.Addresses { + if err := convert_v1beta3_NodeAddress_To_api_NodeAddress(&in.Addresses[i], &out.Addresses[i], s); err != nil { + return err + } + } + } else { + out.Addresses = nil + } + if err := convert_v1beta3_NodeSystemInfo_To_api_NodeSystemInfo(&in.NodeInfo, &out.NodeInfo, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_NodeSystemInfo_To_api_NodeSystemInfo(in *NodeSystemInfo, out *api.NodeSystemInfo, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*NodeSystemInfo))(in) + } + out.MachineID = in.MachineID + out.SystemUUID = in.SystemUUID + out.BootID = in.BootID + out.KernelVersion = in.KernelVersion + out.OsImage = in.OsImage + out.ContainerRuntimeVersion = in.ContainerRuntimeVersion + out.KubeletVersion = in.KubeletVersion + out.KubeProxyVersion = in.KubeProxyVersion + return nil +} + +func convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(in *ObjectFieldSelector, out *api.ObjectFieldSelector, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ObjectFieldSelector))(in) + } + out.APIVersion = in.APIVersion + out.FieldPath = in.FieldPath + return nil +} + +func convert_v1beta3_ObjectMeta_To_api_ObjectMeta(in *ObjectMeta, out *api.ObjectMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ObjectMeta))(in) + } + out.Name = in.Name + out.GenerateName = in.GenerateName + out.Namespace = in.Namespace + out.SelfLink = in.SelfLink + out.UID = in.UID + out.ResourceVersion = in.ResourceVersion + out.Generation = in.Generation + if err := s.Convert(&in.CreationTimestamp, &out.CreationTimestamp, 0); err != nil { + return err + } + if in.DeletionTimestamp != nil { + if err := s.Convert(&in.DeletionTimestamp, &out.DeletionTimestamp, 0); err != nil { + return err + } + } else { + out.DeletionTimestamp = nil + } + if in.DeletionGracePeriodSeconds != nil { + out.DeletionGracePeriodSeconds = new(int64) + *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds + } else { + out.DeletionGracePeriodSeconds = nil + } + if in.Labels != nil { + out.Labels = make(map[string]string) + for key, val := range in.Labels { + out.Labels[key] = val + } + } else { + out.Labels = nil + } + if in.Annotations != nil { + out.Annotations = make(map[string]string) + for key, val := range in.Annotations { + out.Annotations[key] = val + } + } else { + out.Annotations = nil + } + return nil +} + +func convert_v1beta3_ObjectReference_To_api_ObjectReference(in *ObjectReference, out *api.ObjectReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ObjectReference))(in) + } + out.Kind = in.Kind + out.Namespace = in.Namespace + out.Name = in.Name + out.UID = in.UID + out.APIVersion = in.APIVersion + out.ResourceVersion = in.ResourceVersion + out.FieldPath = in.FieldPath + return nil +} + +func convert_v1beta3_PersistentVolume_To_api_PersistentVolume(in *PersistentVolume, out *api.PersistentVolume, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PersistentVolume))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_PersistentVolumeSpec_To_api_PersistentVolumeSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta3_PersistentVolumeStatus_To_api_PersistentVolumeStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_PersistentVolumeClaim_To_api_PersistentVolumeClaim(in *PersistentVolumeClaim, out *api.PersistentVolumeClaim, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PersistentVolumeClaim))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta3_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_PersistentVolumeClaimList_To_api_PersistentVolumeClaimList(in *PersistentVolumeClaimList, out *api.PersistentVolumeClaimList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PersistentVolumeClaimList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.PersistentVolumeClaim, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_PersistentVolumeClaim_To_api_PersistentVolumeClaim(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec(in *PersistentVolumeClaimSpec, out *api.PersistentVolumeClaimSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PersistentVolumeClaimSpec))(in) + } + if in.AccessModes != nil { + out.AccessModes = make([]api.PersistentVolumeAccessMode, len(in.AccessModes)) + for i := range in.AccessModes { + out.AccessModes[i] = api.PersistentVolumeAccessMode(in.AccessModes[i]) + } + } else { + out.AccessModes = nil + } + if err := convert_v1beta3_ResourceRequirements_To_api_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { + return err + } + out.VolumeName = in.VolumeName + return nil +} + +func convert_v1beta3_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus(in *PersistentVolumeClaimStatus, out *api.PersistentVolumeClaimStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PersistentVolumeClaimStatus))(in) + } + out.Phase = api.PersistentVolumeClaimPhase(in.Phase) + if in.AccessModes != nil { + out.AccessModes = make([]api.PersistentVolumeAccessMode, len(in.AccessModes)) + for i := range in.AccessModes { + out.AccessModes[i] = api.PersistentVolumeAccessMode(in.AccessModes[i]) + } + } else { + out.AccessModes = nil + } + if in.Capacity != nil { + out.Capacity = make(api.ResourceList) + for key, val := range in.Capacity { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Capacity[api.ResourceName(key)] = newVal + } + } else { + out.Capacity = nil + } + return nil +} + +func convert_v1beta3_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource(in *PersistentVolumeClaimVolumeSource, out *api.PersistentVolumeClaimVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PersistentVolumeClaimVolumeSource))(in) + } + out.ClaimName = in.ClaimName + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1beta3_PersistentVolumeList_To_api_PersistentVolumeList(in *PersistentVolumeList, out *api.PersistentVolumeList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PersistentVolumeList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.PersistentVolume, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_PersistentVolume_To_api_PersistentVolume(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_PersistentVolumeSource_To_api_PersistentVolumeSource(in *PersistentVolumeSource, out *api.PersistentVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PersistentVolumeSource))(in) + } + if in.GCEPersistentDisk != nil { + out.GCEPersistentDisk = new(api.GCEPersistentDiskVolumeSource) + if err := convert_v1beta3_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource(in.GCEPersistentDisk, out.GCEPersistentDisk, s); err != nil { + return err + } + } else { + out.GCEPersistentDisk = nil + } + if in.AWSElasticBlockStore != nil { + out.AWSElasticBlockStore = new(api.AWSElasticBlockStoreVolumeSource) + if err := convert_v1beta3_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource(in.AWSElasticBlockStore, out.AWSElasticBlockStore, s); err != nil { + return err + } + } else { + out.AWSElasticBlockStore = nil + } + if in.HostPath != nil { + out.HostPath = new(api.HostPathVolumeSource) + if err := convert_v1beta3_HostPathVolumeSource_To_api_HostPathVolumeSource(in.HostPath, out.HostPath, s); err != nil { + return err + } + } else { + out.HostPath = nil + } + if in.Glusterfs != nil { + out.Glusterfs = new(api.GlusterfsVolumeSource) + if err := convert_v1beta3_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { + return err + } + } else { + out.Glusterfs = nil + } + if in.NFS != nil { + out.NFS = new(api.NFSVolumeSource) + if err := convert_v1beta3_NFSVolumeSource_To_api_NFSVolumeSource(in.NFS, out.NFS, s); err != nil { + return err + } + } else { + out.NFS = nil + } + if in.RBD != nil { + out.RBD = new(api.RBDVolumeSource) + if err := convert_v1beta3_RBDVolumeSource_To_api_RBDVolumeSource(in.RBD, out.RBD, s); err != nil { + return err + } + } else { + out.RBD = nil + } + if in.ISCSI != nil { + out.ISCSI = new(api.ISCSIVolumeSource) + if err := convert_v1beta3_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { + return err + } + } else { + out.ISCSI = nil + } + if in.CephFS != nil { + out.CephFS = new(api.CephFSVolumeSource) + if err := convert_v1beta3_CephFSVolumeSource_To_api_CephFSVolumeSource(in.CephFS, out.CephFS, s); err != nil { + return err + } + } else { + out.CephFS = nil + } + if in.Cinder != nil { + out.Cinder = new(api.CinderVolumeSource) + if err := convert_v1beta3_CinderVolumeSource_To_api_CinderVolumeSource(in.Cinder, out.Cinder, s); err != nil { + return err + } + } else { + out.Cinder = nil + } + return nil +} + +func convert_v1beta3_PersistentVolumeSpec_To_api_PersistentVolumeSpec(in *PersistentVolumeSpec, out *api.PersistentVolumeSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PersistentVolumeSpec))(in) + } + if in.Capacity != nil { + out.Capacity = make(api.ResourceList) + for key, val := range in.Capacity { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Capacity[api.ResourceName(key)] = newVal + } + } else { + out.Capacity = nil + } + if err := convert_v1beta3_PersistentVolumeSource_To_api_PersistentVolumeSource(&in.PersistentVolumeSource, &out.PersistentVolumeSource, s); err != nil { + return err + } + if in.AccessModes != nil { + out.AccessModes = make([]api.PersistentVolumeAccessMode, len(in.AccessModes)) + for i := range in.AccessModes { + out.AccessModes[i] = api.PersistentVolumeAccessMode(in.AccessModes[i]) + } + } else { + out.AccessModes = nil + } + if in.ClaimRef != nil { + out.ClaimRef = new(api.ObjectReference) + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(in.ClaimRef, out.ClaimRef, s); err != nil { + return err + } + } else { + out.ClaimRef = nil + } + out.PersistentVolumeReclaimPolicy = api.PersistentVolumeReclaimPolicy(in.PersistentVolumeReclaimPolicy) + return nil +} + +func convert_v1beta3_PersistentVolumeStatus_To_api_PersistentVolumeStatus(in *PersistentVolumeStatus, out *api.PersistentVolumeStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PersistentVolumeStatus))(in) + } + out.Phase = api.PersistentVolumePhase(in.Phase) + out.Message = in.Message + out.Reason = in.Reason + return nil +} + +func convert_v1beta3_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Pod))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_PodSpec_To_api_PodSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta3_PodStatus_To_api_PodStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_PodCondition_To_api_PodCondition(in *PodCondition, out *api.PodCondition, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodCondition))(in) + } + out.Type = api.PodConditionType(in.Type) + out.Status = api.ConditionStatus(in.Status) + return nil +} + +func convert_v1beta3_PodExecOptions_To_api_PodExecOptions(in *PodExecOptions, out *api.PodExecOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodExecOptions))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + out.Stdin = in.Stdin + out.Stdout = in.Stdout + out.Stderr = in.Stderr + out.TTY = in.TTY + out.Container = in.Container + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + return nil +} + +func convert_v1beta3_PodList_To_api_PodList(in *PodList, out *api.PodList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.Pod, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_Pod_To_api_Pod(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_PodLogOptions_To_api_PodLogOptions(in *PodLogOptions, out *api.PodLogOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodLogOptions))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + out.Container = in.Container + out.Follow = in.Follow + out.Previous = in.Previous + return nil +} + +func convert_v1beta3_PodProxyOptions_To_api_PodProxyOptions(in *PodProxyOptions, out *api.PodProxyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodProxyOptions))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + out.Path = in.Path + return nil +} + +func convert_v1beta3_PodStatus_To_api_PodStatus(in *PodStatus, out *api.PodStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodStatus))(in) + } + out.Phase = api.PodPhase(in.Phase) + if in.Conditions != nil { + out.Conditions = make([]api.PodCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := convert_v1beta3_PodCondition_To_api_PodCondition(&in.Conditions[i], &out.Conditions[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + out.Message = in.Message + out.Reason = in.Reason + out.HostIP = in.HostIP + out.PodIP = in.PodIP + if in.StartTime != nil { + if err := s.Convert(&in.StartTime, &out.StartTime, 0); err != nil { + return err + } + } else { + out.StartTime = nil + } + if in.ContainerStatuses != nil { + out.ContainerStatuses = make([]api.ContainerStatus, len(in.ContainerStatuses)) + for i := range in.ContainerStatuses { + if err := convert_v1beta3_ContainerStatus_To_api_ContainerStatus(&in.ContainerStatuses[i], &out.ContainerStatuses[i], s); err != nil { + return err + } + } + } else { + out.ContainerStatuses = nil + } + return nil +} + +func convert_v1beta3_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodStatusResult))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_PodStatus_To_api_PodStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_PodTemplate_To_api_PodTemplate(in *PodTemplate, out *api.PodTemplate, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodTemplate))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_PodTemplateList_To_api_PodTemplateList(in *PodTemplateList, out *api.PodTemplateList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodTemplateList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.PodTemplate, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_PodTemplate_To_api_PodTemplate(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*PodTemplateSpec))(in) + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_PodSpec_To_api_PodSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_Probe_To_api_Probe(in *Probe, out *api.Probe, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Probe))(in) + } + if err := convert_v1beta3_Handler_To_api_Handler(&in.Handler, &out.Handler, s); err != nil { + return err + } + out.InitialDelaySeconds = in.InitialDelaySeconds + out.TimeoutSeconds = in.TimeoutSeconds + return nil +} + +func convert_v1beta3_RBDVolumeSource_To_api_RBDVolumeSource(in *RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*RBDVolumeSource))(in) + } + if in.CephMonitors != nil { + out.CephMonitors = make([]string, len(in.CephMonitors)) + for i := range in.CephMonitors { + out.CephMonitors[i] = in.CephMonitors[i] + } + } else { + out.CephMonitors = nil + } + out.RBDImage = in.RBDImage + out.FSType = in.FSType + out.RBDPool = in.RBDPool + out.RadosUser = in.RadosUser + out.Keyring = in.Keyring + if in.SecretRef != nil { + out.SecretRef = new(api.LocalObjectReference) + if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in.SecretRef, out.SecretRef, s); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func convert_v1beta3_RangeAllocation_To_api_RangeAllocation(in *RangeAllocation, out *api.RangeAllocation, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*RangeAllocation))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.Range = in.Range + if err := s.Convert(&in.Data, &out.Data, 0); err != nil { + return err + } + return nil +} + +func convert_v1beta3_ReplicationController_To_api_ReplicationController(in *ReplicationController, out *api.ReplicationController, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ReplicationController))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ReplicationControllerSpec_To_api_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta3_ReplicationControllerStatus_To_api_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_ReplicationControllerList_To_api_ReplicationControllerList(in *ReplicationControllerList, out *api.ReplicationControllerList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ReplicationControllerList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.ReplicationController, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_ReplicationController_To_api_ReplicationController(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_ReplicationControllerStatus_To_api_ReplicationControllerStatus(in *ReplicationControllerStatus, out *api.ReplicationControllerStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ReplicationControllerStatus))(in) + } + out.Replicas = in.Replicas + out.ObservedGeneration = in.ObservedGeneration + return nil +} + +func convert_v1beta3_ResourceQuota_To_api_ResourceQuota(in *ResourceQuota, out *api.ResourceQuota, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ResourceQuota))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ResourceQuotaSpec_To_api_ResourceQuotaSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta3_ResourceQuotaStatus_To_api_ResourceQuotaStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_ResourceQuotaList_To_api_ResourceQuotaList(in *ResourceQuotaList, out *api.ResourceQuotaList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ResourceQuotaList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.ResourceQuota, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_ResourceQuota_To_api_ResourceQuota(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_ResourceQuotaSpec_To_api_ResourceQuotaSpec(in *ResourceQuotaSpec, out *api.ResourceQuotaSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ResourceQuotaSpec))(in) + } + if in.Hard != nil { + out.Hard = make(api.ResourceList) + for key, val := range in.Hard { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Hard[api.ResourceName(key)] = newVal + } + } else { + out.Hard = nil + } + return nil +} + +func convert_v1beta3_ResourceQuotaStatus_To_api_ResourceQuotaStatus(in *ResourceQuotaStatus, out *api.ResourceQuotaStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ResourceQuotaStatus))(in) + } + if in.Hard != nil { + out.Hard = make(api.ResourceList) + for key, val := range in.Hard { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Hard[api.ResourceName(key)] = newVal + } + } else { + out.Hard = nil + } + if in.Used != nil { + out.Used = make(api.ResourceList) + for key, val := range in.Used { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Used[api.ResourceName(key)] = newVal + } + } else { + out.Used = nil + } + return nil +} + +func convert_v1beta3_ResourceRequirements_To_api_ResourceRequirements(in *ResourceRequirements, out *api.ResourceRequirements, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ResourceRequirements))(in) + } + if in.Limits != nil { + out.Limits = make(api.ResourceList) + for key, val := range in.Limits { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Limits[api.ResourceName(key)] = newVal + } + } else { + out.Limits = nil + } + if in.Requests != nil { + out.Requests = make(api.ResourceList) + for key, val := range in.Requests { + newVal := resource.Quantity{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Requests[api.ResourceName(key)] = newVal + } + } else { + out.Requests = nil + } + return nil +} + +func convert_v1beta3_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions(in *FSGroupStrategyOptions, out *api.FSGroupStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*FSGroupStrategyOptions))(in) + } + out.Type = api.FSGroupStrategyType(in.Type) + if in.Ranges != nil { + out.Ranges = make([]api.IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := convert_v1beta3_IDRange_To_api_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func convert_v1beta3_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions(in *SupplementalGroupsStrategyOptions, out *api.SupplementalGroupsStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SupplementalGroupsStrategyOptions))(in) + } + out.Type = api.SupplementalGroupsStrategyType(in.Type) + if in.Ranges != nil { + out.Ranges = make([]api.IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := convert_v1beta3_IDRange_To_api_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func convert_v1beta3_IDRange_To_api_IDRange(in *IDRange, out *api.IDRange, s conversion.Scope) error { + out.Min = in.Min + out.Max = in.Max + return nil +} + +func convert_v1beta3_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions(in *RunAsUserStrategyOptions, out *api.RunAsUserStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*RunAsUserStrategyOptions))(in) + } + out.Type = api.RunAsUserStrategyType(in.Type) + if in.UID != nil { + out.UID = new(int64) + *out.UID = *in.UID + } else { + out.UID = nil + } + if in.UIDRangeMin != nil { + out.UIDRangeMin = new(int64) + *out.UIDRangeMin = *in.UIDRangeMin + } else { + out.UIDRangeMin = nil + } + if in.UIDRangeMax != nil { + out.UIDRangeMax = new(int64) + *out.UIDRangeMax = *in.UIDRangeMax + } else { + out.UIDRangeMax = nil + } + return nil +} + +func convert_v1beta3_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions(in *SELinuxContextStrategyOptions, out *api.SELinuxContextStrategyOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SELinuxContextStrategyOptions))(in) + } + out.Type = api.SELinuxContextStrategyType(in.Type) + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(api.SELinuxOptions) + if err := convert_v1beta3_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + return nil +} + +func convert_v1beta3_SELinuxOptions_To_api_SELinuxOptions(in *SELinuxOptions, out *api.SELinuxOptions, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SELinuxOptions))(in) + } + out.User = in.User + out.Role = in.Role + out.Type = in.Type + out.Level = in.Level + return nil +} + +func convert_v1beta3_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Secret))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Data != nil { + out.Data = make(map[string][]uint8) + for key, val := range in.Data { + newVal := []uint8{} + if err := s.Convert(&val, &newVal, 0); err != nil { + return err + } + out.Data[key] = newVal + } + } else { + out.Data = nil + } + out.Type = api.SecretType(in.Type) + return nil +} + +func convert_v1beta3_SecretList_To_api_SecretList(in *SecretList, out *api.SecretList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SecretList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.Secret, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_Secret_To_api_Secret(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_SecretVolumeSource_To_api_SecretVolumeSource(in *SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SecretVolumeSource))(in) + } + out.SecretName = in.SecretName + return nil +} + +func convert_v1beta3_SecurityContext_To_api_SecurityContext(in *SecurityContext, out *api.SecurityContext, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SecurityContext))(in) + } + if in.Capabilities != nil { + out.Capabilities = new(api.Capabilities) + if err := convert_v1beta3_Capabilities_To_api_Capabilities(in.Capabilities, out.Capabilities, s); err != nil { + return err + } + } else { + out.Capabilities = nil + } + if in.Privileged != nil { + out.Privileged = new(bool) + *out.Privileged = *in.Privileged + } else { + out.Privileged = nil + } + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(api.SELinuxOptions) + if err := convert_v1beta3_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + if in.RunAsUser != nil { + out.RunAsUser = new(int64) + *out.RunAsUser = *in.RunAsUser + } else { + out.RunAsUser = nil + } + out.RunAsNonRoot = in.RunAsNonRoot + return nil +} + +func convert_v1beta3_SecurityContextConstraints_To_api_SecurityContextConstraints(in *SecurityContextConstraints, out *api.SecurityContextConstraints, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SecurityContextConstraints))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.AllowPrivilegedContainer = in.AllowPrivilegedContainer + if in.AllowedCapabilities != nil { + out.AllowedCapabilities = make([]api.Capability, len(in.AllowedCapabilities)) + for i := range in.AllowedCapabilities { + out.AllowedCapabilities[i] = api.Capability(in.AllowedCapabilities[i]) + } + } else { + out.AllowedCapabilities = nil + } + out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + out.AllowHostNetwork = in.AllowHostNetwork + out.AllowHostPorts = in.AllowHostPorts + out.AllowHostPID = in.AllowHostPID + out.AllowHostIPC = in.AllowHostIPC + if err := convert_v1beta3_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil { + return err + } + if err := convert_v1beta3_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil { + return err + } + if err := convert_v1beta3_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions(&in.FSGroup, &out.FSGroup, s); err != nil { + return err + } + if err := convert_v1beta3_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions(&in.SupplementalGroups, &out.SupplementalGroups, s); err != nil { + return err + } + if in.Users != nil { + out.Users = make([]string, len(in.Users)) + for i := range in.Users { + out.Users[i] = in.Users[i] + } + } else { + out.Users = nil + } + if in.Groups != nil { + out.Groups = make([]string, len(in.Groups)) + for i := range in.Groups { + out.Groups[i] = in.Groups[i] + } + } else { + out.Groups = nil + } + return nil +} + +func convert_v1beta3_SecurityContextConstraintsList_To_api_SecurityContextConstraintsList(in *SecurityContextConstraintsList, out *api.SecurityContextConstraintsList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SecurityContextConstraintsList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.SecurityContextConstraints, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_SecurityContextConstraints_To_api_SecurityContextConstraints(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_SerializedReference_To_api_SerializedReference(in *SerializedReference, out *api.SerializedReference, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*SerializedReference))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.Reference, &out.Reference, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_Service_To_api_Service(in *Service, out *api.Service, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Service))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ServiceSpec_To_api_ServiceSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := convert_v1beta3_ServiceStatus_To_api_ServiceStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_ServiceAccount_To_api_ServiceAccount(in *ServiceAccount, out *api.ServiceAccount, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ServiceAccount))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Secrets != nil { + out.Secrets = make([]api.ObjectReference, len(in.Secrets)) + for i := range in.Secrets { + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.Secrets[i], &out.Secrets[i], s); err != nil { + return err + } + } + } else { + out.Secrets = nil + } + if in.ImagePullSecrets != nil { + out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets)) + for i := range in.ImagePullSecrets { + if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { + return err + } + } + } else { + out.ImagePullSecrets = nil + } + return nil +} + +func convert_v1beta3_ServiceAccountList_To_api_ServiceAccountList(in *ServiceAccountList, out *api.ServiceAccountList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ServiceAccountList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.ServiceAccount, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_ServiceAccount_To_api_ServiceAccount(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_ServiceList_To_api_ServiceList(in *ServiceList, out *api.ServiceList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ServiceList))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.Service, len(in.Items)) + for i := range in.Items { + if err := convert_v1beta3_Service_To_api_Service(&in.Items[i], &out.Items[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_ServicePort_To_api_ServicePort(in *ServicePort, out *api.ServicePort, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ServicePort))(in) + } + out.Name = in.Name + out.Protocol = api.Protocol(in.Protocol) + out.Port = in.Port + if err := s.Convert(&in.TargetPort, &out.TargetPort, 0); err != nil { + return err + } + out.NodePort = in.NodePort + return nil +} + +func convert_v1beta3_ServiceStatus_To_api_ServiceStatus(in *ServiceStatus, out *api.ServiceStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ServiceStatus))(in) + } + if err := convert_v1beta3_LoadBalancerStatus_To_api_LoadBalancerStatus(&in.LoadBalancer, &out.LoadBalancer, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_Status_To_api_Status(in *Status, out *unversioned.Status, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Status))(in) + } + if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + out.Status = in.Status + out.Message = in.Message + out.Reason = unversioned.StatusReason(in.Reason) + if in.Details != nil { + out.Details = new(unversioned.StatusDetails) + if err := convert_v1beta3_StatusDetails_To_api_StatusDetails(in.Details, out.Details, s); err != nil { + return err + } + } else { + out.Details = nil + } + out.Code = in.Code + return nil +} + +func convert_v1beta3_TCPSocketAction_To_api_TCPSocketAction(in *TCPSocketAction, out *api.TCPSocketAction, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*TCPSocketAction))(in) + } + if err := s.Convert(&in.Port, &out.Port, 0); err != nil { + return err + } + return nil +} + +func convert_v1beta3_TypeMeta_To_api_TypeMeta(in *TypeMeta, out *unversioned.TypeMeta, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*TypeMeta))(in) + } + out.Kind = in.Kind + out.APIVersion = in.APIVersion + return nil +} + +func convert_v1beta3_Volume_To_api_Volume(in *Volume, out *api.Volume, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*Volume))(in) + } + out.Name = in.Name + if err := convert_v1beta3_VolumeSource_To_api_VolumeSource(&in.VolumeSource, &out.VolumeSource, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_VolumeMount_To_api_VolumeMount(in *VolumeMount, out *api.VolumeMount, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*VolumeMount))(in) + } + out.Name = in.Name + out.ReadOnly = in.ReadOnly + out.MountPath = in.MountPath + return nil +} + +func init() { + err := api.Scheme.AddGeneratedConversionFuncs( + convert_api_AWSElasticBlockStoreVolumeSource_To_v1beta3_AWSElasticBlockStoreVolumeSource, + convert_api_Binding_To_v1beta3_Binding, + convert_api_Capabilities_To_v1beta3_Capabilities, + convert_api_CephFSVolumeSource_To_v1beta3_CephFSVolumeSource, + convert_api_CinderVolumeSource_To_v1beta3_CinderVolumeSource, + convert_api_ComponentCondition_To_v1beta3_ComponentCondition, + convert_api_ComponentStatusList_To_v1beta3_ComponentStatusList, + convert_api_ComponentStatus_To_v1beta3_ComponentStatus, + convert_api_ContainerPort_To_v1beta3_ContainerPort, + convert_api_ContainerStateRunning_To_v1beta3_ContainerStateRunning, + convert_api_ContainerStateWaiting_To_v1beta3_ContainerStateWaiting, + convert_api_ContainerStatus_To_v1beta3_ContainerStatus, + convert_api_DeleteOptions_To_v1beta3_DeleteOptions, + convert_api_DownwardAPIVolumeFile_To_v1beta3_DownwardAPIVolumeFile, + convert_api_DownwardAPIVolumeSource_To_v1beta3_DownwardAPIVolumeSource, + convert_api_EmptyDirVolumeSource_To_v1beta3_EmptyDirVolumeSource, + convert_api_EndpointAddress_To_v1beta3_EndpointAddress, + convert_api_EndpointPort_To_v1beta3_EndpointPort, + convert_api_EndpointSubset_To_v1beta3_EndpointSubset, + convert_api_EndpointsList_To_v1beta3_EndpointsList, + convert_api_Endpoints_To_v1beta3_Endpoints, + convert_api_EnvVarSource_To_v1beta3_EnvVarSource, + convert_api_EnvVar_To_v1beta3_EnvVar, + convert_api_EventList_To_v1beta3_EventList, + convert_api_EventSource_To_v1beta3_EventSource, + convert_api_Event_To_v1beta3_Event, + convert_api_ExecAction_To_v1beta3_ExecAction, + convert_api_FSGroupStrategyOptions_To_v1beta3_FSGroupStrategyOptions, + convert_api_GCEPersistentDiskVolumeSource_To_v1beta3_GCEPersistentDiskVolumeSource, + convert_api_GitRepoVolumeSource_To_v1beta3_GitRepoVolumeSource, + convert_api_GlusterfsVolumeSource_To_v1beta3_GlusterfsVolumeSource, + convert_api_HTTPGetAction_To_v1beta3_HTTPGetAction, + convert_api_Handler_To_v1beta3_Handler, + convert_api_HostPathVolumeSource_To_v1beta3_HostPathVolumeSource, + convert_api_IDRange_To_v1beta3_IDRange, + convert_api_ISCSIVolumeSource_To_v1beta3_ISCSIVolumeSource, + convert_api_Lifecycle_To_v1beta3_Lifecycle, + convert_api_LimitRangeItem_To_v1beta3_LimitRangeItem, + convert_api_LimitRangeList_To_v1beta3_LimitRangeList, + convert_api_LimitRangeSpec_To_v1beta3_LimitRangeSpec, + convert_api_LimitRange_To_v1beta3_LimitRange, + convert_api_ListMeta_To_v1beta3_ListMeta, + convert_api_ListOptions_To_v1beta3_ListOptions, + convert_api_List_To_v1beta3_List, + convert_api_LoadBalancerIngress_To_v1beta3_LoadBalancerIngress, + convert_api_LoadBalancerStatus_To_v1beta3_LoadBalancerStatus, + convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference, + convert_api_NFSVolumeSource_To_v1beta3_NFSVolumeSource, + convert_api_NamespaceList_To_v1beta3_NamespaceList, + convert_api_NamespaceSpec_To_v1beta3_NamespaceSpec, + convert_api_NamespaceStatus_To_v1beta3_NamespaceStatus, + convert_api_Namespace_To_v1beta3_Namespace, + convert_api_NodeAddress_To_v1beta3_NodeAddress, + convert_api_NodeCondition_To_v1beta3_NodeCondition, + convert_api_NodeList_To_v1beta3_NodeList, + convert_api_NodeSpec_To_v1beta3_NodeSpec, + convert_api_NodeStatus_To_v1beta3_NodeStatus, + convert_api_NodeSystemInfo_To_v1beta3_NodeSystemInfo, + convert_api_Node_To_v1beta3_Node, + convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector, + convert_api_ObjectMeta_To_v1beta3_ObjectMeta, + convert_api_ObjectReference_To_v1beta3_ObjectReference, + convert_api_PersistentVolumeClaimList_To_v1beta3_PersistentVolumeClaimList, + convert_api_PersistentVolumeClaimSpec_To_v1beta3_PersistentVolumeClaimSpec, + convert_api_PersistentVolumeClaimStatus_To_v1beta3_PersistentVolumeClaimStatus, + convert_api_PersistentVolumeClaimVolumeSource_To_v1beta3_PersistentVolumeClaimVolumeSource, + convert_api_PersistentVolumeClaim_To_v1beta3_PersistentVolumeClaim, + convert_api_PersistentVolumeList_To_v1beta3_PersistentVolumeList, + convert_api_PersistentVolumeSource_To_v1beta3_PersistentVolumeSource, + convert_api_PersistentVolumeSpec_To_v1beta3_PersistentVolumeSpec, + convert_api_PersistentVolumeStatus_To_v1beta3_PersistentVolumeStatus, + convert_api_PersistentVolume_To_v1beta3_PersistentVolume, + convert_api_PodCondition_To_v1beta3_PodCondition, + convert_api_PodExecOptions_To_v1beta3_PodExecOptions, + convert_api_PodList_To_v1beta3_PodList, + convert_api_PodLogOptions_To_v1beta3_PodLogOptions, + convert_api_PodProxyOptions_To_v1beta3_PodProxyOptions, + convert_api_PodStatusResult_To_v1beta3_PodStatusResult, + convert_api_PodStatus_To_v1beta3_PodStatus, + convert_api_PodTemplateList_To_v1beta3_PodTemplateList, + convert_api_PodTemplateSpec_To_v1beta3_PodTemplateSpec, + convert_api_PodTemplate_To_v1beta3_PodTemplate, + convert_api_Pod_To_v1beta3_Pod, + convert_api_Probe_To_v1beta3_Probe, + convert_api_RBDVolumeSource_To_v1beta3_RBDVolumeSource, + convert_api_RangeAllocation_To_v1beta3_RangeAllocation, + convert_api_ReplicationControllerList_To_v1beta3_ReplicationControllerList, + convert_api_ReplicationControllerStatus_To_v1beta3_ReplicationControllerStatus, + convert_api_ReplicationController_To_v1beta3_ReplicationController, + convert_api_ResourceQuotaList_To_v1beta3_ResourceQuotaList, + convert_api_ResourceQuotaSpec_To_v1beta3_ResourceQuotaSpec, + convert_api_ResourceQuotaStatus_To_v1beta3_ResourceQuotaStatus, + convert_api_ResourceQuota_To_v1beta3_ResourceQuota, + convert_api_ResourceRequirements_To_v1beta3_ResourceRequirements, + convert_api_RunAsUserStrategyOptions_To_v1beta3_RunAsUserStrategyOptions, + convert_api_SELinuxContextStrategyOptions_To_v1beta3_SELinuxContextStrategyOptions, + convert_api_SELinuxOptions_To_v1beta3_SELinuxOptions, + convert_api_SecretList_To_v1beta3_SecretList, + convert_api_SecretVolumeSource_To_v1beta3_SecretVolumeSource, + convert_api_Secret_To_v1beta3_Secret, + convert_api_SecurityContextConstraintsList_To_v1beta3_SecurityContextConstraintsList, + convert_api_SecurityContextConstraints_To_v1beta3_SecurityContextConstraints, + convert_api_SecurityContext_To_v1beta3_SecurityContext, + convert_api_SerializedReference_To_v1beta3_SerializedReference, + convert_api_ServiceAccountList_To_v1beta3_ServiceAccountList, + convert_api_ServiceAccount_To_v1beta3_ServiceAccount, + convert_api_ServiceList_To_v1beta3_ServiceList, + convert_api_ServicePort_To_v1beta3_ServicePort, + convert_api_ServiceStatus_To_v1beta3_ServiceStatus, + convert_api_Service_To_v1beta3_Service, + convert_api_Status_To_v1beta3_Status, + convert_api_SupplementalGroupsStrategyOptions_To_v1beta3_SupplementalGroupsStrategyOptions, + convert_api_TCPSocketAction_To_v1beta3_TCPSocketAction, + convert_api_TypeMeta_To_v1beta3_TypeMeta, + convert_api_VolumeMount_To_v1beta3_VolumeMount, + convert_api_Volume_To_v1beta3_Volume, + convert_v1beta3_AWSElasticBlockStoreVolumeSource_To_api_AWSElasticBlockStoreVolumeSource, + convert_v1beta3_Binding_To_api_Binding, + convert_v1beta3_Capabilities_To_api_Capabilities, + convert_v1beta3_CephFSVolumeSource_To_api_CephFSVolumeSource, + convert_v1beta3_CinderVolumeSource_To_api_CinderVolumeSource, + convert_v1beta3_ComponentCondition_To_api_ComponentCondition, + convert_v1beta3_ComponentStatusList_To_api_ComponentStatusList, + convert_v1beta3_ComponentStatus_To_api_ComponentStatus, + convert_v1beta3_ContainerPort_To_api_ContainerPort, + convert_v1beta3_ContainerStateRunning_To_api_ContainerStateRunning, + convert_v1beta3_ContainerStateWaiting_To_api_ContainerStateWaiting, + convert_v1beta3_ContainerStatus_To_api_ContainerStatus, + convert_v1beta3_DeleteOptions_To_api_DeleteOptions, + convert_v1beta3_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile, + convert_v1beta3_DownwardAPIVolumeSource_To_api_DownwardAPIVolumeSource, + convert_v1beta3_EmptyDirVolumeSource_To_api_EmptyDirVolumeSource, + convert_v1beta3_EndpointAddress_To_api_EndpointAddress, + convert_v1beta3_EndpointPort_To_api_EndpointPort, + convert_v1beta3_EndpointSubset_To_api_EndpointSubset, + convert_v1beta3_EndpointsList_To_api_EndpointsList, + convert_v1beta3_Endpoints_To_api_Endpoints, + convert_v1beta3_EnvVarSource_To_api_EnvVarSource, + convert_v1beta3_EnvVar_To_api_EnvVar, + convert_v1beta3_EventList_To_api_EventList, + convert_v1beta3_EventSource_To_api_EventSource, + convert_v1beta3_Event_To_api_Event, + convert_v1beta3_ExecAction_To_api_ExecAction, + convert_v1beta3_FSGroupStrategyOptions_To_api_FSGroupStrategyOptions, + convert_v1beta3_GCEPersistentDiskVolumeSource_To_api_GCEPersistentDiskVolumeSource, + convert_v1beta3_GitRepoVolumeSource_To_api_GitRepoVolumeSource, + convert_v1beta3_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource, + convert_v1beta3_HTTPGetAction_To_api_HTTPGetAction, + convert_v1beta3_Handler_To_api_Handler, + convert_v1beta3_HostPathVolumeSource_To_api_HostPathVolumeSource, + convert_v1beta3_IDRange_To_api_IDRange, + convert_v1beta3_ISCSIVolumeSource_To_api_ISCSIVolumeSource, + convert_v1beta3_Lifecycle_To_api_Lifecycle, + convert_v1beta3_LimitRangeItem_To_api_LimitRangeItem, + convert_v1beta3_LimitRangeList_To_api_LimitRangeList, + convert_v1beta3_LimitRangeSpec_To_api_LimitRangeSpec, + convert_v1beta3_LimitRange_To_api_LimitRange, + convert_v1beta3_ListMeta_To_api_ListMeta, + convert_v1beta3_ListOptions_To_api_ListOptions, + convert_v1beta3_List_To_api_List, + convert_v1beta3_LoadBalancerIngress_To_api_LoadBalancerIngress, + convert_v1beta3_LoadBalancerStatus_To_api_LoadBalancerStatus, + convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference, + convert_v1beta3_NFSVolumeSource_To_api_NFSVolumeSource, + convert_v1beta3_NamespaceList_To_api_NamespaceList, + convert_v1beta3_NamespaceSpec_To_api_NamespaceSpec, + convert_v1beta3_NamespaceStatus_To_api_NamespaceStatus, + convert_v1beta3_Namespace_To_api_Namespace, + convert_v1beta3_NodeAddress_To_api_NodeAddress, + convert_v1beta3_NodeCondition_To_api_NodeCondition, + convert_v1beta3_NodeList_To_api_NodeList, + convert_v1beta3_NodeSpec_To_api_NodeSpec, + convert_v1beta3_NodeStatus_To_api_NodeStatus, + convert_v1beta3_NodeSystemInfo_To_api_NodeSystemInfo, + convert_v1beta3_Node_To_api_Node, + convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector, + convert_v1beta3_ObjectMeta_To_api_ObjectMeta, + convert_v1beta3_ObjectReference_To_api_ObjectReference, + convert_v1beta3_PersistentVolumeClaimList_To_api_PersistentVolumeClaimList, + convert_v1beta3_PersistentVolumeClaimSpec_To_api_PersistentVolumeClaimSpec, + convert_v1beta3_PersistentVolumeClaimStatus_To_api_PersistentVolumeClaimStatus, + convert_v1beta3_PersistentVolumeClaimVolumeSource_To_api_PersistentVolumeClaimVolumeSource, + convert_v1beta3_PersistentVolumeClaim_To_api_PersistentVolumeClaim, + convert_v1beta3_PersistentVolumeList_To_api_PersistentVolumeList, + convert_v1beta3_PersistentVolumeSource_To_api_PersistentVolumeSource, + convert_v1beta3_PersistentVolumeSpec_To_api_PersistentVolumeSpec, + convert_v1beta3_PersistentVolumeStatus_To_api_PersistentVolumeStatus, + convert_v1beta3_PersistentVolume_To_api_PersistentVolume, + convert_v1beta3_PodCondition_To_api_PodCondition, + convert_v1beta3_PodExecOptions_To_api_PodExecOptions, + convert_v1beta3_PodList_To_api_PodList, + convert_v1beta3_PodLogOptions_To_api_PodLogOptions, + convert_v1beta3_PodProxyOptions_To_api_PodProxyOptions, + convert_v1beta3_PodStatusResult_To_api_PodStatusResult, + convert_v1beta3_PodStatus_To_api_PodStatus, + convert_v1beta3_PodTemplateList_To_api_PodTemplateList, + convert_v1beta3_PodTemplateSpec_To_api_PodTemplateSpec, + convert_v1beta3_PodTemplate_To_api_PodTemplate, + convert_v1beta3_Pod_To_api_Pod, + convert_v1beta3_Probe_To_api_Probe, + convert_v1beta3_RBDVolumeSource_To_api_RBDVolumeSource, + convert_v1beta3_RangeAllocation_To_api_RangeAllocation, + convert_v1beta3_ReplicationControllerList_To_api_ReplicationControllerList, + convert_v1beta3_ReplicationControllerStatus_To_api_ReplicationControllerStatus, + convert_v1beta3_ReplicationController_To_api_ReplicationController, + convert_v1beta3_ResourceQuotaList_To_api_ResourceQuotaList, + convert_v1beta3_ResourceQuotaSpec_To_api_ResourceQuotaSpec, + convert_v1beta3_ResourceQuotaStatus_To_api_ResourceQuotaStatus, + convert_v1beta3_ResourceQuota_To_api_ResourceQuota, + convert_v1beta3_ResourceRequirements_To_api_ResourceRequirements, + convert_v1beta3_RunAsUserStrategyOptions_To_api_RunAsUserStrategyOptions, + convert_v1beta3_SELinuxContextStrategyOptions_To_api_SELinuxContextStrategyOptions, + convert_v1beta3_SELinuxOptions_To_api_SELinuxOptions, + convert_v1beta3_SecretList_To_api_SecretList, + convert_v1beta3_SecretVolumeSource_To_api_SecretVolumeSource, + convert_v1beta3_Secret_To_api_Secret, + convert_v1beta3_SecurityContextConstraintsList_To_api_SecurityContextConstraintsList, + convert_v1beta3_SecurityContextConstraints_To_api_SecurityContextConstraints, + convert_v1beta3_SecurityContext_To_api_SecurityContext, + convert_v1beta3_SerializedReference_To_api_SerializedReference, + convert_v1beta3_ServiceAccountList_To_api_ServiceAccountList, + convert_v1beta3_ServiceAccount_To_api_ServiceAccount, + convert_v1beta3_ServiceList_To_api_ServiceList, + convert_v1beta3_ServicePort_To_api_ServicePort, + convert_v1beta3_ServiceStatus_To_api_ServiceStatus, + convert_v1beta3_Service_To_api_Service, + convert_v1beta3_Status_To_api_Status, + convert_v1beta3_SupplementalGroupsStrategyOptions_To_api_SupplementalGroupsStrategyOptions, + convert_v1beta3_TCPSocketAction_To_api_TCPSocketAction, + convert_v1beta3_TypeMeta_To_api_TypeMeta, + convert_v1beta3_VolumeMount_To_api_VolumeMount, + convert_v1beta3_Volume_To_api_Volume, + ) + if err != nil { + // If one of the conversion functions is malformed, detect it immediately. + panic(err) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_test.go new file mode 100644 index 000000000000..a4c3aabffac8 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_test.go @@ -0,0 +1,139 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 v1beta3_test + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/resource" + versioned "k8s.io/kubernetes/pkg/api/v1beta3" +) + +func TestResourceQuotaStatusConversion(t *testing.T) { + // should serialize as "0" + expected := resource.NewQuantity(int64(0), resource.DecimalSI) + if "0" != expected.String() { + t.Errorf("Expected: 0, Actual: %v, do not require units", expected.String()) + } + + parsed := resource.MustParse("0") + if "0" != parsed.String() { + t.Errorf("Expected: 0, Actual: %v, do not require units", parsed.String()) + } + + quota := &api.ResourceQuota{} + quota.Status = api.ResourceQuotaStatus{} + quota.Status.Hard = api.ResourceList{} + quota.Status.Used = api.ResourceList{} + quota.Status.Hard[api.ResourcePods] = *expected + + // round-trip the object + data, _ := versioned.Codec.Encode(quota) + object, _ := versioned.Codec.Decode(data) + after := object.(*api.ResourceQuota) + actualQuantity := after.Status.Hard[api.ResourcePods] + actual := &actualQuantity + + // should be "0", but was "0m" + if expected.String() != actual.String() { + t.Errorf("Expected %v, Actual %v", expected.String(), actual.String()) + } +} + +func TestNodeConversion(t *testing.T) { + obj, err := versioned.Codec.Decode([]byte(`{"kind":"Minion","apiVersion":"v1beta3"}`)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if _, ok := obj.(*api.Node); !ok { + t.Errorf("unexpected type: %#v", obj) + } + + obj, err = versioned.Codec.Decode([]byte(`{"kind":"MinionList","apiVersion":"v1beta3"}`)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if _, ok := obj.(*api.NodeList); !ok { + t.Errorf("unexpected type: %#v", obj) + } + + obj = &api.Node{} + if err := versioned.Codec.DecodeInto([]byte(`{"kind":"Minion","apiVersion":"v1beta3"}`), obj); err != nil { + t.Fatalf("unexpected error: %v", err) + } +} + +func TestBadSecurityContextConversion(t *testing.T) { + priv := false + testCases := map[string]struct { + c *versioned.Container + err string + }{ + // this use case must use true for the container and false for the sc. Otherwise the defaulter + // will assume privileged was left undefined (since it is the default value) and copy the + // sc setting upwards + "mismatched privileged": { + c: &versioned.Container{ + Privileged: true, + SecurityContext: &versioned.SecurityContext{ + Privileged: &priv, + }, + }, + err: "container privileged settings do not match security context settings, cannot convert", + }, + "mismatched caps add": { + c: &versioned.Container{ + Capabilities: versioned.Capabilities{ + Add: []versioned.Capability{"foo"}, + }, + SecurityContext: &versioned.SecurityContext{ + Capabilities: &versioned.Capabilities{ + Add: []versioned.Capability{"bar"}, + }, + }, + }, + err: "container capability settings do not match security context settings, cannot convert", + }, + "mismatched caps drop": { + c: &versioned.Container{ + Capabilities: versioned.Capabilities{ + Drop: []versioned.Capability{"foo"}, + }, + SecurityContext: &versioned.SecurityContext{ + Capabilities: &versioned.Capabilities{ + Drop: []versioned.Capability{"bar"}, + }, + }, + }, + err: "container capability settings do not match security context settings, cannot convert", + }, + } + + for k, v := range testCases { + got := api.Container{} + err := api.Scheme.Convert(v.c, &got) + if err == nil { + t.Errorf("expected error for case %s but got none", k) + } else { + if err.Error() != v.err { + t.Errorf("unexpected error for case %s. Expected: %s but got: %s", k, v.err, err.Error()) + } + } + } + +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_volumesource_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_volumesource_test.go new file mode 100644 index 000000000000..02393ad4227d --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_volumesource_test.go @@ -0,0 +1,62 @@ +package v1beta3 + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/conversion" +) + +func TestAPItoV1Beta3VolumeSourceConversion(t *testing.T) { + c := conversion.NewConverter() + c.Debug = t + + if err := c.RegisterConversionFunc(convert_api_VolumeSource_To_v1beta3_VolumeSource); err != nil { + t.Fatalf("unexpected error %v", err) + } + + in := api.VolumeSource{ + DownwardAPI: &api.DownwardAPIVolumeSource{ + Items: []api.DownwardAPIVolumeFile{ + { + Path: "./test/api-to-v1beta3/conversion", + }, + }, + }, + } + out := VolumeSource{} + + if err := c.Convert(&in, &out, 0, nil); err != nil { + t.Fatalf("unexpected error %v", err) + } + if e, a := in.DownwardAPI.Items[0].Path, out.Metadata.Items[0].Name; e != a { + t.Errorf("expected %v, got %v", e, a) + } +} + +func TestV1Beta3toAPIVolumeSourceConversion(t *testing.T) { + c := conversion.NewConverter() + c.Debug = t + + if err := c.RegisterConversionFunc(convert_v1beta3_VolumeSource_To_api_VolumeSource); err != nil { + t.Fatalf("unexpected error %v", err) + } + + in := VolumeSource{ + Metadata: &MetadataVolumeSource{ + Items: []MetadataFile{ + { + Name: "./test/v1beta3-to-api/conversion", + }, + }, + }, + } + out := api.VolumeSource{} + + if err := c.Convert(&in, &out, 0, nil); err != nil { + t.Fatalf("unexpected error %v", err) + } + if e, a := in.Metadata.Items[0].Name, out.DownwardAPI.Items[0].Path; e != a { + t.Errorf("expected %v, got %v", e, a) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go new file mode 100644 index 000000000000..48f525e8307a --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go @@ -0,0 +1,2530 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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. +*/ + +// DO NOT EDIT. THIS FILE IS AUTO-GENERATED BY $KUBEROOT/hack/update-generated-deep-copies.sh. + +package v1beta3 + +import ( + time "time" + + api "k8s.io/kubernetes/pkg/api" + resource "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" + conversion "k8s.io/kubernetes/pkg/conversion" + runtime "k8s.io/kubernetes/pkg/runtime" + util "k8s.io/kubernetes/pkg/util" + inf "speter.net/go/exp/math/dec/inf" +) + +func deepCopy_resource_Quantity(in resource.Quantity, out *resource.Quantity, c *conversion.Cloner) error { + if in.Amount != nil { + if newVal, err := c.DeepCopy(in.Amount); err != nil { + return err + } else if newVal == nil { + out.Amount = nil + } else { + out.Amount = newVal.(*inf.Dec) + } + } else { + out.Amount = nil + } + out.Format = in.Format + return nil +} + +func deepCopy_v1beta3_AWSElasticBlockStoreVolumeSource(in AWSElasticBlockStoreVolumeSource, out *AWSElasticBlockStoreVolumeSource, c *conversion.Cloner) error { + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_v1beta3_Binding(in Binding, out *Binding, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectReference(in.Target, &out.Target, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_Capabilities(in Capabilities, out *Capabilities, c *conversion.Cloner) error { + if in.Add != nil { + out.Add = make([]Capability, len(in.Add)) + for i := range in.Add { + out.Add[i] = in.Add[i] + } + } else { + out.Add = nil + } + if in.Drop != nil { + out.Drop = make([]Capability, len(in.Drop)) + for i := range in.Drop { + out.Drop[i] = in.Drop[i] + } + } else { + out.Drop = nil + } + return nil +} + +func deepCopy_v1beta3_CephFSVolumeSource(in CephFSVolumeSource, out *CephFSVolumeSource, c *conversion.Cloner) error { + if in.Monitors != nil { + out.Monitors = make([]string, len(in.Monitors)) + for i := range in.Monitors { + out.Monitors[i] = in.Monitors[i] + } + } else { + out.Monitors = nil + } + out.User = in.User + out.SecretFile = in.SecretFile + if in.SecretRef != nil { + out.SecretRef = new(LocalObjectReference) + if err := deepCopy_v1beta3_LocalObjectReference(*in.SecretRef, out.SecretRef, c); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_v1beta3_CinderVolumeSource(in CinderVolumeSource, out *CinderVolumeSource, c *conversion.Cloner) error { + out.VolumeID = in.VolumeID + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_v1beta3_ComponentCondition(in ComponentCondition, out *ComponentCondition, c *conversion.Cloner) error { + out.Type = in.Type + out.Status = in.Status + out.Message = in.Message + out.Error = in.Error + return nil +} + +func deepCopy_v1beta3_ComponentStatus(in ComponentStatus, out *ComponentStatus, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if in.Conditions != nil { + out.Conditions = make([]ComponentCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := deepCopy_v1beta3_ComponentCondition(in.Conditions[i], &out.Conditions[i], c); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +func deepCopy_v1beta3_ComponentStatusList(in ComponentStatusList, out *ComponentStatusList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ComponentStatus, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_ComponentStatus(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_Container(in Container, out *Container, c *conversion.Cloner) error { + out.Name = in.Name + out.Image = in.Image + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + if in.Args != nil { + out.Args = make([]string, len(in.Args)) + for i := range in.Args { + out.Args[i] = in.Args[i] + } + } else { + out.Args = nil + } + out.WorkingDir = in.WorkingDir + if in.Ports != nil { + out.Ports = make([]ContainerPort, len(in.Ports)) + for i := range in.Ports { + if err := deepCopy_v1beta3_ContainerPort(in.Ports[i], &out.Ports[i], c); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.Env != nil { + out.Env = make([]EnvVar, len(in.Env)) + for i := range in.Env { + if err := deepCopy_v1beta3_EnvVar(in.Env[i], &out.Env[i], c); err != nil { + return err + } + } + } else { + out.Env = nil + } + if err := deepCopy_v1beta3_ResourceRequirements(in.Resources, &out.Resources, c); err != nil { + return err + } + if in.VolumeMounts != nil { + out.VolumeMounts = make([]VolumeMount, len(in.VolumeMounts)) + for i := range in.VolumeMounts { + if err := deepCopy_v1beta3_VolumeMount(in.VolumeMounts[i], &out.VolumeMounts[i], c); err != nil { + return err + } + } + } else { + out.VolumeMounts = nil + } + if in.LivenessProbe != nil { + out.LivenessProbe = new(Probe) + if err := deepCopy_v1beta3_Probe(*in.LivenessProbe, out.LivenessProbe, c); err != nil { + return err + } + } else { + out.LivenessProbe = nil + } + if in.ReadinessProbe != nil { + out.ReadinessProbe = new(Probe) + if err := deepCopy_v1beta3_Probe(*in.ReadinessProbe, out.ReadinessProbe, c); err != nil { + return err + } + } else { + out.ReadinessProbe = nil + } + if in.Lifecycle != nil { + out.Lifecycle = new(Lifecycle) + if err := deepCopy_v1beta3_Lifecycle(*in.Lifecycle, out.Lifecycle, c); err != nil { + return err + } + } else { + out.Lifecycle = nil + } + out.TerminationMessagePath = in.TerminationMessagePath + out.Privileged = in.Privileged + out.ImagePullPolicy = in.ImagePullPolicy + if err := deepCopy_v1beta3_Capabilities(in.Capabilities, &out.Capabilities, c); err != nil { + return err + } + if in.SecurityContext != nil { + out.SecurityContext = new(SecurityContext) + if err := deepCopy_v1beta3_SecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + out.Stdin = in.Stdin + out.TTY = in.TTY + return nil +} + +func deepCopy_v1beta3_ContainerPort(in ContainerPort, out *ContainerPort, c *conversion.Cloner) error { + out.Name = in.Name + out.HostPort = in.HostPort + out.ContainerPort = in.ContainerPort + out.Protocol = in.Protocol + out.HostIP = in.HostIP + return nil +} + +func deepCopy_v1beta3_ContainerState(in ContainerState, out *ContainerState, c *conversion.Cloner) error { + if in.Waiting != nil { + out.Waiting = new(ContainerStateWaiting) + if err := deepCopy_v1beta3_ContainerStateWaiting(*in.Waiting, out.Waiting, c); err != nil { + return err + } + } else { + out.Waiting = nil + } + if in.Running != nil { + out.Running = new(ContainerStateRunning) + if err := deepCopy_v1beta3_ContainerStateRunning(*in.Running, out.Running, c); err != nil { + return err + } + } else { + out.Running = nil + } + if in.Termination != nil { + out.Termination = new(ContainerStateTerminated) + if err := deepCopy_v1beta3_ContainerStateTerminated(*in.Termination, out.Termination, c); err != nil { + return err + } + } else { + out.Termination = nil + } + return nil +} + +func deepCopy_v1beta3_ContainerStateRunning(in ContainerStateRunning, out *ContainerStateRunning, c *conversion.Cloner) error { + if err := deepCopy_util_Time(in.StartedAt, &out.StartedAt, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_ContainerStateTerminated(in ContainerStateTerminated, out *ContainerStateTerminated, c *conversion.Cloner) error { + out.ExitCode = in.ExitCode + out.Signal = in.Signal + out.Reason = in.Reason + out.Message = in.Message + if err := deepCopy_util_Time(in.StartedAt, &out.StartedAt, c); err != nil { + return err + } + if err := deepCopy_util_Time(in.FinishedAt, &out.FinishedAt, c); err != nil { + return err + } + out.ContainerID = in.ContainerID + return nil +} + +func deepCopy_v1beta3_ContainerStateWaiting(in ContainerStateWaiting, out *ContainerStateWaiting, c *conversion.Cloner) error { + out.Reason = in.Reason + return nil +} + +func deepCopy_v1beta3_ContainerStatus(in ContainerStatus, out *ContainerStatus, c *conversion.Cloner) error { + out.Name = in.Name + if err := deepCopy_v1beta3_ContainerState(in.State, &out.State, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ContainerState(in.LastTerminationState, &out.LastTerminationState, c); err != nil { + return err + } + out.Ready = in.Ready + out.RestartCount = in.RestartCount + out.Image = in.Image + out.ImageID = in.ImageID + out.ContainerID = in.ContainerID + return nil +} + +func deepCopy_v1beta3_DeleteOptions(in DeleteOptions, out *DeleteOptions, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if in.GracePeriodSeconds != nil { + out.GracePeriodSeconds = new(int64) + *out.GracePeriodSeconds = *in.GracePeriodSeconds + } else { + out.GracePeriodSeconds = nil + } + return nil +} + +func deepCopy_v1beta3_DownwardAPIVolumeFile(in DownwardAPIVolumeFile, out *DownwardAPIVolumeFile, c *conversion.Cloner) error { + out.Path = in.Path + if err := deepCopy_v1beta3_ObjectFieldSelector(in.FieldRef, &out.FieldRef, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_DownwardAPIVolumeSource(in DownwardAPIVolumeSource, out *DownwardAPIVolumeSource, c *conversion.Cloner) error { + if in.Items != nil { + out.Items = make([]DownwardAPIVolumeFile, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_DownwardAPIVolumeFile(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_EmptyDirVolumeSource(in EmptyDirVolumeSource, out *EmptyDirVolumeSource, c *conversion.Cloner) error { + out.Medium = in.Medium + return nil +} + +func deepCopy_v1beta3_EndpointAddress(in EndpointAddress, out *EndpointAddress, c *conversion.Cloner) error { + out.IP = in.IP + if in.TargetRef != nil { + out.TargetRef = new(ObjectReference) + if err := deepCopy_v1beta3_ObjectReference(*in.TargetRef, out.TargetRef, c); err != nil { + return err + } + } else { + out.TargetRef = nil + } + return nil +} + +func deepCopy_v1beta3_EndpointPort(in EndpointPort, out *EndpointPort, c *conversion.Cloner) error { + out.Name = in.Name + out.Port = in.Port + out.Protocol = in.Protocol + return nil +} + +func deepCopy_v1beta3_EndpointSubset(in EndpointSubset, out *EndpointSubset, c *conversion.Cloner) error { + if in.Addresses != nil { + out.Addresses = make([]EndpointAddress, len(in.Addresses)) + for i := range in.Addresses { + if err := deepCopy_v1beta3_EndpointAddress(in.Addresses[i], &out.Addresses[i], c); err != nil { + return err + } + } + } else { + out.Addresses = nil + } + if in.Ports != nil { + out.Ports = make([]EndpointPort, len(in.Ports)) + for i := range in.Ports { + if err := deepCopy_v1beta3_EndpointPort(in.Ports[i], &out.Ports[i], c); err != nil { + return err + } + } + } else { + out.Ports = nil + } + return nil +} + +func deepCopy_v1beta3_Endpoints(in Endpoints, out *Endpoints, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if in.Subsets != nil { + out.Subsets = make([]EndpointSubset, len(in.Subsets)) + for i := range in.Subsets { + if err := deepCopy_v1beta3_EndpointSubset(in.Subsets[i], &out.Subsets[i], c); err != nil { + return err + } + } + } else { + out.Subsets = nil + } + return nil +} + +func deepCopy_v1beta3_EndpointsList(in EndpointsList, out *EndpointsList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Endpoints, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_Endpoints(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_EnvVar(in EnvVar, out *EnvVar, c *conversion.Cloner) error { + out.Name = in.Name + out.Value = in.Value + if in.ValueFrom != nil { + out.ValueFrom = new(EnvVarSource) + if err := deepCopy_v1beta3_EnvVarSource(*in.ValueFrom, out.ValueFrom, c); err != nil { + return err + } + } else { + out.ValueFrom = nil + } + return nil +} + +func deepCopy_v1beta3_EnvVarSource(in EnvVarSource, out *EnvVarSource, c *conversion.Cloner) error { + if in.FieldRef != nil { + out.FieldRef = new(ObjectFieldSelector) + if err := deepCopy_v1beta3_ObjectFieldSelector(*in.FieldRef, out.FieldRef, c); err != nil { + return err + } + } else { + out.FieldRef = nil + } + return nil +} + +func deepCopy_v1beta3_Event(in Event, out *Event, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectReference(in.InvolvedObject, &out.InvolvedObject, c); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message + if err := deepCopy_v1beta3_EventSource(in.Source, &out.Source, c); err != nil { + return err + } + if err := deepCopy_util_Time(in.FirstTimestamp, &out.FirstTimestamp, c); err != nil { + return err + } + if err := deepCopy_util_Time(in.LastTimestamp, &out.LastTimestamp, c); err != nil { + return err + } + out.Count = in.Count + return nil +} + +func deepCopy_v1beta3_EventList(in EventList, out *EventList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Event, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_Event(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_EventSource(in EventSource, out *EventSource, c *conversion.Cloner) error { + out.Component = in.Component + out.Host = in.Host + return nil +} + +func deepCopy_v1beta3_ExecAction(in ExecAction, out *ExecAction, c *conversion.Cloner) error { + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + return nil +} + +func deepCopy_v1beta3_GCEPersistentDiskVolumeSource(in GCEPersistentDiskVolumeSource, out *GCEPersistentDiskVolumeSource, c *conversion.Cloner) error { + out.PDName = in.PDName + out.FSType = in.FSType + out.Partition = in.Partition + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_v1beta3_GitRepoVolumeSource(in GitRepoVolumeSource, out *GitRepoVolumeSource, c *conversion.Cloner) error { + out.Repository = in.Repository + out.Revision = in.Revision + return nil +} + +func deepCopy_v1beta3_GlusterfsVolumeSource(in GlusterfsVolumeSource, out *GlusterfsVolumeSource, c *conversion.Cloner) error { + out.EndpointsName = in.EndpointsName + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_v1beta3_HTTPGetAction(in HTTPGetAction, out *HTTPGetAction, c *conversion.Cloner) error { + out.Path = in.Path + if err := deepCopy_util_IntOrString(in.Port, &out.Port, c); err != nil { + return err + } + out.Host = in.Host + out.Scheme = in.Scheme + return nil +} + +func deepCopy_v1beta3_Handler(in Handler, out *Handler, c *conversion.Cloner) error { + if in.Exec != nil { + out.Exec = new(ExecAction) + if err := deepCopy_v1beta3_ExecAction(*in.Exec, out.Exec, c); err != nil { + return err + } + } else { + out.Exec = nil + } + if in.HTTPGet != nil { + out.HTTPGet = new(HTTPGetAction) + if err := deepCopy_v1beta3_HTTPGetAction(*in.HTTPGet, out.HTTPGet, c); err != nil { + return err + } + } else { + out.HTTPGet = nil + } + if in.TCPSocket != nil { + out.TCPSocket = new(TCPSocketAction) + if err := deepCopy_v1beta3_TCPSocketAction(*in.TCPSocket, out.TCPSocket, c); err != nil { + return err + } + } else { + out.TCPSocket = nil + } + return nil +} + +func deepCopy_v1beta3_HostPathVolumeSource(in HostPathVolumeSource, out *HostPathVolumeSource, c *conversion.Cloner) error { + out.Path = in.Path + return nil +} + +func deepCopy_v1beta3_ISCSIVolumeSource(in ISCSIVolumeSource, out *ISCSIVolumeSource, c *conversion.Cloner) error { + out.TargetPortal = in.TargetPortal + out.IQN = in.IQN + out.Lun = in.Lun + out.FSType = in.FSType + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_v1beta3_Lifecycle(in Lifecycle, out *Lifecycle, c *conversion.Cloner) error { + if in.PostStart != nil { + out.PostStart = new(Handler) + if err := deepCopy_v1beta3_Handler(*in.PostStart, out.PostStart, c); err != nil { + return err + } + } else { + out.PostStart = nil + } + if in.PreStop != nil { + out.PreStop = new(Handler) + if err := deepCopy_v1beta3_Handler(*in.PreStop, out.PreStop, c); err != nil { + return err + } + } else { + out.PreStop = nil + } + return nil +} + +func deepCopy_v1beta3_LimitRange(in LimitRange, out *LimitRange, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_LimitRangeSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_LimitRangeItem(in LimitRangeItem, out *LimitRangeItem, c *conversion.Cloner) error { + out.Type = in.Type + if in.Max != nil { + out.Max = make(ResourceList) + for key, val := range in.Max { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.Max[key] = *newVal + } + } else { + out.Max = nil + } + if in.Min != nil { + out.Min = make(ResourceList) + for key, val := range in.Min { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.Min[key] = *newVal + } + } else { + out.Min = nil + } + if in.Default != nil { + out.Default = make(ResourceList) + for key, val := range in.Default { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.Default[key] = *newVal + } + } else { + out.Default = nil + } + if in.DefaultRequest != nil { + out.DefaultRequest = make(ResourceList) + for key, val := range in.DefaultRequest { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.DefaultRequest[key] = *newVal + } + } else { + out.DefaultRequest = nil + } + if in.MaxLimitRequestRatio != nil { + out.MaxLimitRequestRatio = make(ResourceList) + for key, val := range in.MaxLimitRequestRatio { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.MaxLimitRequestRatio[key] = *newVal + } + } else { + out.MaxLimitRequestRatio = nil + } + return nil +} + +func deepCopy_v1beta3_LimitRangeList(in LimitRangeList, out *LimitRangeList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]LimitRange, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_LimitRange(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_LimitRangeSpec(in LimitRangeSpec, out *LimitRangeSpec, c *conversion.Cloner) error { + if in.Limits != nil { + out.Limits = make([]LimitRangeItem, len(in.Limits)) + for i := range in.Limits { + if err := deepCopy_v1beta3_LimitRangeItem(in.Limits[i], &out.Limits[i], c); err != nil { + return err + } + } + } else { + out.Limits = nil + } + return nil +} + +func deepCopy_v1beta3_List(in List, out *List, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]runtime.RawExtension, len(in.Items)) + for i := range in.Items { + if err := deepCopy_runtime_RawExtension(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_ListMeta(in ListMeta, out *ListMeta, c *conversion.Cloner) error { + out.SelfLink = in.SelfLink + out.ResourceVersion = in.ResourceVersion + return nil +} + +func deepCopy_v1beta3_ListOptions(in ListOptions, out *ListOptions, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + out.LabelSelector = in.LabelSelector + out.FieldSelector = in.FieldSelector + out.Watch = in.Watch + out.ResourceVersion = in.ResourceVersion + return nil +} + +func deepCopy_v1beta3_LoadBalancerIngress(in LoadBalancerIngress, out *LoadBalancerIngress, c *conversion.Cloner) error { + out.IP = in.IP + out.Hostname = in.Hostname + return nil +} + +func deepCopy_v1beta3_LoadBalancerStatus(in LoadBalancerStatus, out *LoadBalancerStatus, c *conversion.Cloner) error { + if in.Ingress != nil { + out.Ingress = make([]LoadBalancerIngress, len(in.Ingress)) + for i := range in.Ingress { + if err := deepCopy_v1beta3_LoadBalancerIngress(in.Ingress[i], &out.Ingress[i], c); err != nil { + return err + } + } + } else { + out.Ingress = nil + } + return nil +} + +func deepCopy_v1beta3_LocalObjectReference(in LocalObjectReference, out *LocalObjectReference, c *conversion.Cloner) error { + out.Name = in.Name + return nil +} + +func deepCopy_v1beta3_MetadataFile(in MetadataFile, out *MetadataFile, c *conversion.Cloner) error { + out.Name = in.Name + if err := deepCopy_v1beta3_ObjectFieldSelector(in.FieldRef, &out.FieldRef, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_MetadataVolumeSource(in MetadataVolumeSource, out *MetadataVolumeSource, c *conversion.Cloner) error { + if in.Items != nil { + out.Items = make([]MetadataFile, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_MetadataFile(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_NFSVolumeSource(in NFSVolumeSource, out *NFSVolumeSource, c *conversion.Cloner) error { + out.Server = in.Server + out.Path = in.Path + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_v1beta3_Namespace(in Namespace, out *Namespace, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_NamespaceSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + if err := deepCopy_v1beta3_NamespaceStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_NamespaceList(in NamespaceList, out *NamespaceList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Namespace, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_Namespace(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_NamespaceSpec(in NamespaceSpec, out *NamespaceSpec, c *conversion.Cloner) error { + if in.Finalizers != nil { + out.Finalizers = make([]FinalizerName, len(in.Finalizers)) + for i := range in.Finalizers { + out.Finalizers[i] = in.Finalizers[i] + } + } else { + out.Finalizers = nil + } + return nil +} + +func deepCopy_v1beta3_NamespaceStatus(in NamespaceStatus, out *NamespaceStatus, c *conversion.Cloner) error { + out.Phase = in.Phase + return nil +} + +func deepCopy_v1beta3_Node(in Node, out *Node, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_NodeSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + if err := deepCopy_v1beta3_NodeStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_NodeAddress(in NodeAddress, out *NodeAddress, c *conversion.Cloner) error { + out.Type = in.Type + out.Address = in.Address + return nil +} + +func deepCopy_v1beta3_NodeCondition(in NodeCondition, out *NodeCondition, c *conversion.Cloner) error { + out.Type = in.Type + out.Status = in.Status + if err := deepCopy_util_Time(in.LastHeartbeatTime, &out.LastHeartbeatTime, c); err != nil { + return err + } + if err := deepCopy_util_Time(in.LastTransitionTime, &out.LastTransitionTime, c); err != nil { + return err + } + out.Reason = in.Reason + out.Message = in.Message + return nil +} + +func deepCopy_v1beta3_NodeList(in NodeList, out *NodeList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Node, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_Node(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_NodeSpec(in NodeSpec, out *NodeSpec, c *conversion.Cloner) error { + out.PodCIDR = in.PodCIDR + out.ExternalID = in.ExternalID + out.ProviderID = in.ProviderID + out.Unschedulable = in.Unschedulable + return nil +} + +func deepCopy_v1beta3_NodeStatus(in NodeStatus, out *NodeStatus, c *conversion.Cloner) error { + if in.Capacity != nil { + out.Capacity = make(ResourceList) + for key, val := range in.Capacity { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.Capacity[key] = *newVal + } + } else { + out.Capacity = nil + } + out.Phase = in.Phase + if in.Conditions != nil { + out.Conditions = make([]NodeCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := deepCopy_v1beta3_NodeCondition(in.Conditions[i], &out.Conditions[i], c); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + if in.Addresses != nil { + out.Addresses = make([]NodeAddress, len(in.Addresses)) + for i := range in.Addresses { + if err := deepCopy_v1beta3_NodeAddress(in.Addresses[i], &out.Addresses[i], c); err != nil { + return err + } + } + } else { + out.Addresses = nil + } + if err := deepCopy_v1beta3_NodeSystemInfo(in.NodeInfo, &out.NodeInfo, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_NodeSystemInfo(in NodeSystemInfo, out *NodeSystemInfo, c *conversion.Cloner) error { + out.MachineID = in.MachineID + out.SystemUUID = in.SystemUUID + out.BootID = in.BootID + out.KernelVersion = in.KernelVersion + out.OsImage = in.OsImage + out.ContainerRuntimeVersion = in.ContainerRuntimeVersion + out.KubeletVersion = in.KubeletVersion + out.KubeProxyVersion = in.KubeProxyVersion + return nil +} + +func deepCopy_v1beta3_ObjectFieldSelector(in ObjectFieldSelector, out *ObjectFieldSelector, c *conversion.Cloner) error { + out.APIVersion = in.APIVersion + out.FieldPath = in.FieldPath + return nil +} + +func deepCopy_v1beta3_ObjectMeta(in ObjectMeta, out *ObjectMeta, c *conversion.Cloner) error { + out.Name = in.Name + out.GenerateName = in.GenerateName + out.Namespace = in.Namespace + out.SelfLink = in.SelfLink + out.UID = in.UID + out.ResourceVersion = in.ResourceVersion + out.Generation = in.Generation + if err := deepCopy_util_Time(in.CreationTimestamp, &out.CreationTimestamp, c); err != nil { + return err + } + if in.DeletionTimestamp != nil { + out.DeletionTimestamp = new(unversioned.Time) + if err := deepCopy_util_Time(*in.DeletionTimestamp, out.DeletionTimestamp, c); err != nil { + return err + } + } else { + out.DeletionTimestamp = nil + } + if in.DeletionGracePeriodSeconds != nil { + out.DeletionGracePeriodSeconds = new(int64) + *out.DeletionGracePeriodSeconds = *in.DeletionGracePeriodSeconds + } else { + out.DeletionGracePeriodSeconds = nil + } + if in.Labels != nil { + out.Labels = make(map[string]string) + for key, val := range in.Labels { + out.Labels[key] = val + } + } else { + out.Labels = nil + } + if in.Annotations != nil { + out.Annotations = make(map[string]string) + for key, val := range in.Annotations { + out.Annotations[key] = val + } + } else { + out.Annotations = nil + } + return nil +} + +func deepCopy_v1beta3_ObjectReference(in ObjectReference, out *ObjectReference, c *conversion.Cloner) error { + out.Kind = in.Kind + out.Namespace = in.Namespace + out.Name = in.Name + out.UID = in.UID + out.APIVersion = in.APIVersion + out.ResourceVersion = in.ResourceVersion + out.FieldPath = in.FieldPath + return nil +} + +func deepCopy_v1beta3_PersistentVolume(in PersistentVolume, out *PersistentVolume, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_PersistentVolumeSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + if err := deepCopy_v1beta3_PersistentVolumeStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_PersistentVolumeClaim(in PersistentVolumeClaim, out *PersistentVolumeClaim, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_PersistentVolumeClaimSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + if err := deepCopy_v1beta3_PersistentVolumeClaimStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_PersistentVolumeClaimList(in PersistentVolumeClaimList, out *PersistentVolumeClaimList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]PersistentVolumeClaim, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_PersistentVolumeClaim(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_PersistentVolumeClaimSpec(in PersistentVolumeClaimSpec, out *PersistentVolumeClaimSpec, c *conversion.Cloner) error { + if in.AccessModes != nil { + out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) + for i := range in.AccessModes { + out.AccessModes[i] = in.AccessModes[i] + } + } else { + out.AccessModes = nil + } + if err := deepCopy_v1beta3_ResourceRequirements(in.Resources, &out.Resources, c); err != nil { + return err + } + out.VolumeName = in.VolumeName + return nil +} + +func deepCopy_v1beta3_PersistentVolumeClaimStatus(in PersistentVolumeClaimStatus, out *PersistentVolumeClaimStatus, c *conversion.Cloner) error { + out.Phase = in.Phase + if in.AccessModes != nil { + out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) + for i := range in.AccessModes { + out.AccessModes[i] = in.AccessModes[i] + } + } else { + out.AccessModes = nil + } + if in.Capacity != nil { + out.Capacity = make(ResourceList) + for key, val := range in.Capacity { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.Capacity[key] = *newVal + } + } else { + out.Capacity = nil + } + return nil +} + +func deepCopy_v1beta3_PersistentVolumeClaimVolumeSource(in PersistentVolumeClaimVolumeSource, out *PersistentVolumeClaimVolumeSource, c *conversion.Cloner) error { + out.ClaimName = in.ClaimName + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_v1beta3_PersistentVolumeList(in PersistentVolumeList, out *PersistentVolumeList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]PersistentVolume, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_PersistentVolume(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_PersistentVolumeSource(in PersistentVolumeSource, out *PersistentVolumeSource, c *conversion.Cloner) error { + if in.GCEPersistentDisk != nil { + out.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) + if err := deepCopy_v1beta3_GCEPersistentDiskVolumeSource(*in.GCEPersistentDisk, out.GCEPersistentDisk, c); err != nil { + return err + } + } else { + out.GCEPersistentDisk = nil + } + if in.AWSElasticBlockStore != nil { + out.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) + if err := deepCopy_v1beta3_AWSElasticBlockStoreVolumeSource(*in.AWSElasticBlockStore, out.AWSElasticBlockStore, c); err != nil { + return err + } + } else { + out.AWSElasticBlockStore = nil + } + if in.HostPath != nil { + out.HostPath = new(HostPathVolumeSource) + if err := deepCopy_v1beta3_HostPathVolumeSource(*in.HostPath, out.HostPath, c); err != nil { + return err + } + } else { + out.HostPath = nil + } + if in.Glusterfs != nil { + out.Glusterfs = new(GlusterfsVolumeSource) + if err := deepCopy_v1beta3_GlusterfsVolumeSource(*in.Glusterfs, out.Glusterfs, c); err != nil { + return err + } + } else { + out.Glusterfs = nil + } + if in.NFS != nil { + out.NFS = new(NFSVolumeSource) + if err := deepCopy_v1beta3_NFSVolumeSource(*in.NFS, out.NFS, c); err != nil { + return err + } + } else { + out.NFS = nil + } + if in.RBD != nil { + out.RBD = new(RBDVolumeSource) + if err := deepCopy_v1beta3_RBDVolumeSource(*in.RBD, out.RBD, c); err != nil { + return err + } + } else { + out.RBD = nil + } + if in.ISCSI != nil { + out.ISCSI = new(ISCSIVolumeSource) + if err := deepCopy_v1beta3_ISCSIVolumeSource(*in.ISCSI, out.ISCSI, c); err != nil { + return err + } + } else { + out.ISCSI = nil + } + if in.CephFS != nil { + out.CephFS = new(CephFSVolumeSource) + if err := deepCopy_v1beta3_CephFSVolumeSource(*in.CephFS, out.CephFS, c); err != nil { + return err + } + } else { + out.CephFS = nil + } + if in.Cinder != nil { + out.Cinder = new(CinderVolumeSource) + if err := deepCopy_v1beta3_CinderVolumeSource(*in.Cinder, out.Cinder, c); err != nil { + return err + } + } else { + out.Cinder = nil + } + return nil +} + +func deepCopy_v1beta3_PersistentVolumeSpec(in PersistentVolumeSpec, out *PersistentVolumeSpec, c *conversion.Cloner) error { + if in.Capacity != nil { + out.Capacity = make(ResourceList) + for key, val := range in.Capacity { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.Capacity[key] = *newVal + } + } else { + out.Capacity = nil + } + if err := deepCopy_v1beta3_PersistentVolumeSource(in.PersistentVolumeSource, &out.PersistentVolumeSource, c); err != nil { + return err + } + if in.AccessModes != nil { + out.AccessModes = make([]PersistentVolumeAccessMode, len(in.AccessModes)) + for i := range in.AccessModes { + out.AccessModes[i] = in.AccessModes[i] + } + } else { + out.AccessModes = nil + } + if in.ClaimRef != nil { + out.ClaimRef = new(ObjectReference) + if err := deepCopy_v1beta3_ObjectReference(*in.ClaimRef, out.ClaimRef, c); err != nil { + return err + } + } else { + out.ClaimRef = nil + } + out.PersistentVolumeReclaimPolicy = in.PersistentVolumeReclaimPolicy + return nil +} + +func deepCopy_v1beta3_PersistentVolumeStatus(in PersistentVolumeStatus, out *PersistentVolumeStatus, c *conversion.Cloner) error { + out.Phase = in.Phase + out.Message = in.Message + out.Reason = in.Reason + return nil +} + +func deepCopy_v1beta3_Pod(in Pod, out *Pod, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_PodSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + if err := deepCopy_v1beta3_PodStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_PodCondition(in PodCondition, out *PodCondition, c *conversion.Cloner) error { + out.Type = in.Type + out.Status = in.Status + return nil +} + +func deepCopy_v1beta3_PodExecOptions(in PodExecOptions, out *PodExecOptions, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + out.Stdin = in.Stdin + out.Stdout = in.Stdout + out.Stderr = in.Stderr + out.TTY = in.TTY + out.Container = in.Container + if in.Command != nil { + out.Command = make([]string, len(in.Command)) + for i := range in.Command { + out.Command[i] = in.Command[i] + } + } else { + out.Command = nil + } + return nil +} + +func deepCopy_v1beta3_PodList(in PodList, out *PodList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Pod, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_Pod(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_PodLogOptions(in PodLogOptions, out *PodLogOptions, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + out.Container = in.Container + out.Follow = in.Follow + out.Previous = in.Previous + return nil +} + +func deepCopy_v1beta3_PodProxyOptions(in PodProxyOptions, out *PodProxyOptions, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + out.Path = in.Path + return nil +} + +func deepCopy_v1beta3_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error { + if in.Volumes != nil { + out.Volumes = make([]Volume, len(in.Volumes)) + for i := range in.Volumes { + if err := deepCopy_v1beta3_Volume(in.Volumes[i], &out.Volumes[i], c); err != nil { + return err + } + } + } else { + out.Volumes = nil + } + if in.Containers != nil { + out.Containers = make([]Container, len(in.Containers)) + for i := range in.Containers { + if err := deepCopy_v1beta3_Container(in.Containers[i], &out.Containers[i], c); err != nil { + return err + } + } + } else { + out.Containers = nil + } + out.RestartPolicy = in.RestartPolicy + if in.TerminationGracePeriodSeconds != nil { + out.TerminationGracePeriodSeconds = new(int64) + *out.TerminationGracePeriodSeconds = *in.TerminationGracePeriodSeconds + } else { + out.TerminationGracePeriodSeconds = nil + } + if in.ActiveDeadlineSeconds != nil { + out.ActiveDeadlineSeconds = new(int64) + *out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds + } else { + out.ActiveDeadlineSeconds = nil + } + out.DNSPolicy = in.DNSPolicy + if in.NodeSelector != nil { + out.NodeSelector = make(map[string]string) + for key, val := range in.NodeSelector { + out.NodeSelector[key] = val + } + } else { + out.NodeSelector = nil + } + out.ServiceAccount = in.ServiceAccount + out.Host = in.Host + out.HostNetwork = in.HostNetwork + out.HostPID = in.HostPID + out.HostIPC = in.HostIPC + if in.ImagePullSecrets != nil { + out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) + for i := range in.ImagePullSecrets { + if err := deepCopy_v1beta3_LocalObjectReference(in.ImagePullSecrets[i], &out.ImagePullSecrets[i], c); err != nil { + return err + } + } + } else { + out.ImagePullSecrets = nil + } + return nil +} + +func deepCopy_v1beta3_PodStatus(in PodStatus, out *PodStatus, c *conversion.Cloner) error { + out.Phase = in.Phase + if in.Conditions != nil { + out.Conditions = make([]PodCondition, len(in.Conditions)) + for i := range in.Conditions { + if err := deepCopy_v1beta3_PodCondition(in.Conditions[i], &out.Conditions[i], c); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + out.Message = in.Message + out.Reason = in.Reason + out.HostIP = in.HostIP + out.PodIP = in.PodIP + if in.StartTime != nil { + out.StartTime = new(unversioned.Time) + if err := deepCopy_util_Time(*in.StartTime, out.StartTime, c); err != nil { + return err + } + } else { + out.StartTime = nil + } + if in.ContainerStatuses != nil { + out.ContainerStatuses = make([]ContainerStatus, len(in.ContainerStatuses)) + for i := range in.ContainerStatuses { + if err := deepCopy_v1beta3_ContainerStatus(in.ContainerStatuses[i], &out.ContainerStatuses[i], c); err != nil { + return err + } + } + } else { + out.ContainerStatuses = nil + } + return nil +} + +func deepCopy_v1beta3_PodStatusResult(in PodStatusResult, out *PodStatusResult, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_PodStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_PodTemplate(in PodTemplate, out *PodTemplate, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_PodTemplateSpec(in.Template, &out.Template, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_PodTemplateList(in PodTemplateList, out *PodTemplateList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]PodTemplate, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_PodTemplate(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_PodTemplateSpec(in PodTemplateSpec, out *PodTemplateSpec, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_PodSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_Probe(in Probe, out *Probe, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_Handler(in.Handler, &out.Handler, c); err != nil { + return err + } + out.InitialDelaySeconds = in.InitialDelaySeconds + out.TimeoutSeconds = in.TimeoutSeconds + return nil +} + +func deepCopy_v1beta3_RBDVolumeSource(in RBDVolumeSource, out *RBDVolumeSource, c *conversion.Cloner) error { + if in.CephMonitors != nil { + out.CephMonitors = make([]string, len(in.CephMonitors)) + for i := range in.CephMonitors { + out.CephMonitors[i] = in.CephMonitors[i] + } + } else { + out.CephMonitors = nil + } + out.RBDImage = in.RBDImage + out.FSType = in.FSType + out.RBDPool = in.RBDPool + out.RadosUser = in.RadosUser + out.Keyring = in.Keyring + if in.SecretRef != nil { + out.SecretRef = new(LocalObjectReference) + if err := deepCopy_v1beta3_LocalObjectReference(*in.SecretRef, out.SecretRef, c); err != nil { + return err + } + } else { + out.SecretRef = nil + } + out.ReadOnly = in.ReadOnly + return nil +} + +func deepCopy_v1beta3_RangeAllocation(in RangeAllocation, out *RangeAllocation, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + out.Range = in.Range + if in.Data != nil { + out.Data = make([]uint8, len(in.Data)) + for i := range in.Data { + out.Data[i] = in.Data[i] + } + } else { + out.Data = nil + } + return nil +} + +func deepCopy_v1beta3_ReplicationController(in ReplicationController, out *ReplicationController, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ReplicationControllerSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ReplicationControllerStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_ReplicationControllerList(in ReplicationControllerList, out *ReplicationControllerList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ReplicationController, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_ReplicationController(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_ReplicationControllerSpec(in ReplicationControllerSpec, out *ReplicationControllerSpec, c *conversion.Cloner) error { + if in.Replicas != nil { + out.Replicas = new(int) + *out.Replicas = *in.Replicas + } else { + out.Replicas = nil + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + if in.Template != nil { + out.Template = new(PodTemplateSpec) + if err := deepCopy_v1beta3_PodTemplateSpec(*in.Template, out.Template, c); err != nil { + return err + } + } else { + out.Template = nil + } + return nil +} + +func deepCopy_v1beta3_ReplicationControllerStatus(in ReplicationControllerStatus, out *ReplicationControllerStatus, c *conversion.Cloner) error { + out.Replicas = in.Replicas + out.ObservedGeneration = in.ObservedGeneration + return nil +} + +func deepCopy_v1beta3_ResourceQuota(in ResourceQuota, out *ResourceQuota, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ResourceQuotaSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ResourceQuotaStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_ResourceQuotaList(in ResourceQuotaList, out *ResourceQuotaList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ResourceQuota, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_ResourceQuota(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_ResourceQuotaSpec(in ResourceQuotaSpec, out *ResourceQuotaSpec, c *conversion.Cloner) error { + if in.Hard != nil { + out.Hard = make(ResourceList) + for key, val := range in.Hard { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.Hard[key] = *newVal + } + } else { + out.Hard = nil + } + return nil +} + +func deepCopy_v1beta3_ResourceQuotaStatus(in ResourceQuotaStatus, out *ResourceQuotaStatus, c *conversion.Cloner) error { + if in.Hard != nil { + out.Hard = make(ResourceList) + for key, val := range in.Hard { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.Hard[key] = *newVal + } + } else { + out.Hard = nil + } + if in.Used != nil { + out.Used = make(ResourceList) + for key, val := range in.Used { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.Used[key] = *newVal + } + } else { + out.Used = nil + } + return nil +} + +func deepCopy_v1beta3_ResourceRequirements(in ResourceRequirements, out *ResourceRequirements, c *conversion.Cloner) error { + if in.Limits != nil { + out.Limits = make(ResourceList) + for key, val := range in.Limits { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.Limits[key] = *newVal + } + } else { + out.Limits = nil + } + if in.Requests != nil { + out.Requests = make(ResourceList) + for key, val := range in.Requests { + newVal := new(resource.Quantity) + if err := deepCopy_resource_Quantity(val, newVal, c); err != nil { + return err + } + out.Requests[key] = *newVal + } + } else { + out.Requests = nil + } + return nil +} + +func deepCopy_v1beta3_RunAsUserStrategyOptions(in RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.UID != nil { + out.UID = new(int64) + *out.UID = *in.UID + } else { + out.UID = nil + } + if in.UIDRangeMin != nil { + out.UIDRangeMin = new(int64) + *out.UIDRangeMin = *in.UIDRangeMin + } else { + out.UIDRangeMin = nil + } + if in.UIDRangeMax != nil { + out.UIDRangeMax = new(int64) + *out.UIDRangeMax = *in.UIDRangeMax + } else { + out.UIDRangeMax = nil + } + return nil +} + +func deepCopy_v1beta3_SELinuxContextStrategyOptions(in SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(SELinuxOptions) + if err := deepCopy_v1beta3_SELinuxOptions(*in.SELinuxOptions, out.SELinuxOptions, c); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + return nil +} + +func deepCopy_v1beta3_SELinuxOptions(in SELinuxOptions, out *SELinuxOptions, c *conversion.Cloner) error { + out.User = in.User + out.Role = in.Role + out.Type = in.Type + out.Level = in.Level + return nil +} + +func deepCopy_v1beta3_SupplementalGroupsStrategyOptions(in SupplementalGroupsStrategyOptions, out *SupplementalGroupsStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.Ranges != nil { + out.Ranges = make([]IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := deepCopy_v1beta3_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func deepCopy_v1beta3_FSGroupStrategyOptions(in FSGroupStrategyOptions, out *FSGroupStrategyOptions, c *conversion.Cloner) error { + out.Type = in.Type + if in.Ranges != nil { + out.Ranges = make([]IDRange, len(in.Ranges)) + for i := range in.Ranges { + if err := deepCopy_v1beta3_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil { + return err + } + } + } else { + out.Ranges = nil + } + return nil +} + +func deepCopy_v1beta3_IDRange(in IDRange, out *IDRange, c *conversion.Cloner) error { + out.Max = in.Max + out.Min = in.Min + return nil +} + +func deepCopy_v1beta3_Secret(in Secret, out *Secret, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if in.Data != nil { + out.Data = make(map[string][]uint8) + for key, val := range in.Data { + if newVal, err := c.DeepCopy(val); err != nil { + return err + } else { + out.Data[key] = newVal.([]uint8) + } + } + } else { + out.Data = nil + } + out.Type = in.Type + return nil +} + +func deepCopy_v1beta3_SecretList(in SecretList, out *SecretList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Secret, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_Secret(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_SecretVolumeSource(in SecretVolumeSource, out *SecretVolumeSource, c *conversion.Cloner) error { + out.SecretName = in.SecretName + return nil +} + +func deepCopy_v1beta3_SecurityContext(in SecurityContext, out *SecurityContext, c *conversion.Cloner) error { + if in.Capabilities != nil { + out.Capabilities = new(Capabilities) + if err := deepCopy_v1beta3_Capabilities(*in.Capabilities, out.Capabilities, c); err != nil { + return err + } + } else { + out.Capabilities = nil + } + if in.Privileged != nil { + out.Privileged = new(bool) + *out.Privileged = *in.Privileged + } else { + out.Privileged = nil + } + if in.SELinuxOptions != nil { + out.SELinuxOptions = new(SELinuxOptions) + if err := deepCopy_v1beta3_SELinuxOptions(*in.SELinuxOptions, out.SELinuxOptions, c); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + if in.RunAsUser != nil { + out.RunAsUser = new(int64) + *out.RunAsUser = *in.RunAsUser + } else { + out.RunAsUser = nil + } + out.RunAsNonRoot = in.RunAsNonRoot + return nil +} + +func deepCopy_v1beta3_SecurityContextConstraints(in SecurityContextConstraints, out *SecurityContextConstraints, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + out.AllowPrivilegedContainer = in.AllowPrivilegedContainer + if in.AllowedCapabilities != nil { + out.AllowedCapabilities = make([]Capability, len(in.AllowedCapabilities)) + for i := range in.AllowedCapabilities { + out.AllowedCapabilities[i] = in.AllowedCapabilities[i] + } + } else { + out.AllowedCapabilities = nil + } + out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + out.AllowHostNetwork = in.AllowHostNetwork + out.AllowHostPorts = in.AllowHostPorts + out.AllowHostPID = in.AllowHostPID + out.AllowHostIPC = in.AllowHostIPC + if err := deepCopy_v1beta3_SELinuxContextStrategyOptions(in.SELinuxContext, &out.SELinuxContext, c); err != nil { + return err + } + if err := deepCopy_v1beta3_RunAsUserStrategyOptions(in.RunAsUser, &out.RunAsUser, c); err != nil { + return err + } + if err := deepCopy_v1beta3_FSGroupStrategyOptions(in.FSGroup, &out.FSGroup, c); err != nil { + return err + } + if err := deepCopy_v1beta3_SupplementalGroupsStrategyOptions(in.SupplementalGroups, &out.SupplementalGroups, c); err != nil { + return err + } + if in.Users != nil { + out.Users = make([]string, len(in.Users)) + for i := range in.Users { + out.Users[i] = in.Users[i] + } + } else { + out.Users = nil + } + if in.Groups != nil { + out.Groups = make([]string, len(in.Groups)) + for i := range in.Groups { + out.Groups[i] = in.Groups[i] + } + } else { + out.Groups = nil + } + return nil +} + +func deepCopy_v1beta3_SecurityContextConstraintsList(in SecurityContextConstraintsList, out *SecurityContextConstraintsList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]SecurityContextConstraints, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_SecurityContextConstraints(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_SerializedReference(in SerializedReference, out *SerializedReference, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectReference(in.Reference, &out.Reference, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_Service(in Service, out *Service, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ServiceSpec(in.Spec, &out.Spec, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ServiceStatus(in.Status, &out.Status, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_ServiceAccount(in ServiceAccount, out *ServiceAccount, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if in.Secrets != nil { + out.Secrets = make([]ObjectReference, len(in.Secrets)) + for i := range in.Secrets { + if err := deepCopy_v1beta3_ObjectReference(in.Secrets[i], &out.Secrets[i], c); err != nil { + return err + } + } + } else { + out.Secrets = nil + } + if in.ImagePullSecrets != nil { + out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) + for i := range in.ImagePullSecrets { + if err := deepCopy_v1beta3_LocalObjectReference(in.ImagePullSecrets[i], &out.ImagePullSecrets[i], c); err != nil { + return err + } + } + } else { + out.ImagePullSecrets = nil + } + return nil +} + +func deepCopy_v1beta3_ServiceAccountList(in ServiceAccountList, out *ServiceAccountList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]ServiceAccount, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_ServiceAccount(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_ServiceList(in ServiceList, out *ServiceList, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]Service, len(in.Items)) + for i := range in.Items { + if err := deepCopy_v1beta3_Service(in.Items[i], &out.Items[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func deepCopy_v1beta3_ServicePort(in ServicePort, out *ServicePort, c *conversion.Cloner) error { + out.Name = in.Name + out.Protocol = in.Protocol + out.Port = in.Port + if err := deepCopy_util_IntOrString(in.TargetPort, &out.TargetPort, c); err != nil { + return err + } + out.NodePort = in.NodePort + return nil +} + +func deepCopy_v1beta3_ServiceSpec(in ServiceSpec, out *ServiceSpec, c *conversion.Cloner) error { + if in.Ports != nil { + out.Ports = make([]ServicePort, len(in.Ports)) + for i := range in.Ports { + if err := deepCopy_v1beta3_ServicePort(in.Ports[i], &out.Ports[i], c); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.Selector != nil { + out.Selector = make(map[string]string) + for key, val := range in.Selector { + out.Selector[key] = val + } + } else { + out.Selector = nil + } + out.PortalIP = in.PortalIP + out.CreateExternalLoadBalancer = in.CreateExternalLoadBalancer + out.Type = in.Type + if in.PublicIPs != nil { + out.PublicIPs = make([]string, len(in.PublicIPs)) + for i := range in.PublicIPs { + out.PublicIPs[i] = in.PublicIPs[i] + } + } else { + out.PublicIPs = nil + } + out.SessionAffinity = in.SessionAffinity + return nil +} + +func deepCopy_v1beta3_ServiceStatus(in ServiceStatus, out *ServiceStatus, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_LoadBalancerStatus(in.LoadBalancer, &out.LoadBalancer, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_Status(in Status, out *Status, c *conversion.Cloner) error { + if err := deepCopy_v1beta3_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := deepCopy_v1beta3_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + out.Status = in.Status + out.Message = in.Message + out.Reason = in.Reason + if in.Details != nil { + out.Details = new(StatusDetails) + if err := deepCopy_v1beta3_StatusDetails(*in.Details, out.Details, c); err != nil { + return err + } + } else { + out.Details = nil + } + out.Code = in.Code + return nil +} + +func deepCopy_v1beta3_StatusCause(in StatusCause, out *StatusCause, c *conversion.Cloner) error { + out.Type = in.Type + out.Message = in.Message + out.Field = in.Field + return nil +} + +func deepCopy_v1beta3_StatusDetails(in StatusDetails, out *StatusDetails, c *conversion.Cloner) error { + out.ID = in.ID + out.Kind = in.Kind + if in.Causes != nil { + out.Causes = make([]StatusCause, len(in.Causes)) + for i := range in.Causes { + if err := deepCopy_v1beta3_StatusCause(in.Causes[i], &out.Causes[i], c); err != nil { + return err + } + } + } else { + out.Causes = nil + } + out.RetryAfterSeconds = in.RetryAfterSeconds + return nil +} + +func deepCopy_v1beta3_TCPSocketAction(in TCPSocketAction, out *TCPSocketAction, c *conversion.Cloner) error { + if err := deepCopy_util_IntOrString(in.Port, &out.Port, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_TypeMeta(in TypeMeta, out *TypeMeta, c *conversion.Cloner) error { + out.Kind = in.Kind + out.APIVersion = in.APIVersion + return nil +} + +func deepCopy_v1beta3_Volume(in Volume, out *Volume, c *conversion.Cloner) error { + out.Name = in.Name + if err := deepCopy_v1beta3_VolumeSource(in.VolumeSource, &out.VolumeSource, c); err != nil { + return err + } + return nil +} + +func deepCopy_v1beta3_VolumeMount(in VolumeMount, out *VolumeMount, c *conversion.Cloner) error { + out.Name = in.Name + out.ReadOnly = in.ReadOnly + out.MountPath = in.MountPath + return nil +} + +func deepCopy_v1beta3_VolumeSource(in VolumeSource, out *VolumeSource, c *conversion.Cloner) error { + if in.HostPath != nil { + out.HostPath = new(HostPathVolumeSource) + if err := deepCopy_v1beta3_HostPathVolumeSource(*in.HostPath, out.HostPath, c); err != nil { + return err + } + } else { + out.HostPath = nil + } + if in.EmptyDir != nil { + out.EmptyDir = new(EmptyDirVolumeSource) + if err := deepCopy_v1beta3_EmptyDirVolumeSource(*in.EmptyDir, out.EmptyDir, c); err != nil { + return err + } + } else { + out.EmptyDir = nil + } + if in.GCEPersistentDisk != nil { + out.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) + if err := deepCopy_v1beta3_GCEPersistentDiskVolumeSource(*in.GCEPersistentDisk, out.GCEPersistentDisk, c); err != nil { + return err + } + } else { + out.GCEPersistentDisk = nil + } + if in.AWSElasticBlockStore != nil { + out.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) + if err := deepCopy_v1beta3_AWSElasticBlockStoreVolumeSource(*in.AWSElasticBlockStore, out.AWSElasticBlockStore, c); err != nil { + return err + } + } else { + out.AWSElasticBlockStore = nil + } + if in.GitRepo != nil { + out.GitRepo = new(GitRepoVolumeSource) + if err := deepCopy_v1beta3_GitRepoVolumeSource(*in.GitRepo, out.GitRepo, c); err != nil { + return err + } + } else { + out.GitRepo = nil + } + if in.Secret != nil { + out.Secret = new(SecretVolumeSource) + if err := deepCopy_v1beta3_SecretVolumeSource(*in.Secret, out.Secret, c); err != nil { + return err + } + } else { + out.Secret = nil + } + if in.NFS != nil { + out.NFS = new(NFSVolumeSource) + if err := deepCopy_v1beta3_NFSVolumeSource(*in.NFS, out.NFS, c); err != nil { + return err + } + } else { + out.NFS = nil + } + if in.ISCSI != nil { + out.ISCSI = new(ISCSIVolumeSource) + if err := deepCopy_v1beta3_ISCSIVolumeSource(*in.ISCSI, out.ISCSI, c); err != nil { + return err + } + } else { + out.ISCSI = nil + } + if in.Glusterfs != nil { + out.Glusterfs = new(GlusterfsVolumeSource) + if err := deepCopy_v1beta3_GlusterfsVolumeSource(*in.Glusterfs, out.Glusterfs, c); err != nil { + return err + } + } else { + out.Glusterfs = nil + } + if in.PersistentVolumeClaim != nil { + out.PersistentVolumeClaim = new(PersistentVolumeClaimVolumeSource) + if err := deepCopy_v1beta3_PersistentVolumeClaimVolumeSource(*in.PersistentVolumeClaim, out.PersistentVolumeClaim, c); err != nil { + return err + } + } else { + out.PersistentVolumeClaim = nil + } + if in.RBD != nil { + out.RBD = new(RBDVolumeSource) + if err := deepCopy_v1beta3_RBDVolumeSource(*in.RBD, out.RBD, c); err != nil { + return err + } + } else { + out.RBD = nil + } + if in.CephFS != nil { + out.CephFS = new(CephFSVolumeSource) + if err := deepCopy_v1beta3_CephFSVolumeSource(*in.CephFS, out.CephFS, c); err != nil { + return err + } + } else { + out.CephFS = nil + } + if in.Metadata != nil { + out.Metadata = new(MetadataVolumeSource) + if err := deepCopy_v1beta3_MetadataVolumeSource(*in.Metadata, out.Metadata, c); err != nil { + return err + } + } else { + out.Metadata = nil + } + if in.DownwardAPI != nil { + out.DownwardAPI = new(DownwardAPIVolumeSource) + if err := deepCopy_v1beta3_DownwardAPIVolumeSource(*in.DownwardAPI, out.DownwardAPI, c); err != nil { + return err + } + } else { + out.DownwardAPI = nil + } + if in.Cinder != nil { + out.Cinder = new(CinderVolumeSource) + if err := deepCopy_v1beta3_CinderVolumeSource(*in.Cinder, out.Cinder, c); err != nil { + return err + } + } else { + out.Cinder = nil + } + return nil +} + +func deepCopy_runtime_RawExtension(in runtime.RawExtension, out *runtime.RawExtension, c *conversion.Cloner) error { + if in.RawJSON != nil { + out.RawJSON = make([]uint8, len(in.RawJSON)) + for i := range in.RawJSON { + out.RawJSON[i] = in.RawJSON[i] + } + } else { + out.RawJSON = nil + } + return nil +} + +func deepCopy_util_IntOrString(in util.IntOrString, out *util.IntOrString, c *conversion.Cloner) error { + out.Kind = in.Kind + out.IntVal = in.IntVal + out.StrVal = in.StrVal + return nil +} + +func deepCopy_util_Time(in unversioned.Time, out *unversioned.Time, c *conversion.Cloner) error { + if newVal, err := c.DeepCopy(in.Time); err != nil { + return err + } else { + out.Time = newVal.(time.Time) + } + return nil +} + +func init() { + err := api.Scheme.AddGeneratedDeepCopyFuncs( + deepCopy_resource_Quantity, + deepCopy_v1beta3_AWSElasticBlockStoreVolumeSource, + deepCopy_v1beta3_Binding, + deepCopy_v1beta3_Capabilities, + deepCopy_v1beta3_CephFSVolumeSource, + deepCopy_v1beta3_CinderVolumeSource, + deepCopy_v1beta3_ComponentCondition, + deepCopy_v1beta3_ComponentStatus, + deepCopy_v1beta3_ComponentStatusList, + deepCopy_v1beta3_Container, + deepCopy_v1beta3_ContainerPort, + deepCopy_v1beta3_ContainerState, + deepCopy_v1beta3_ContainerStateRunning, + deepCopy_v1beta3_ContainerStateTerminated, + deepCopy_v1beta3_ContainerStateWaiting, + deepCopy_v1beta3_ContainerStatus, + deepCopy_v1beta3_DeleteOptions, + deepCopy_v1beta3_DownwardAPIVolumeFile, + deepCopy_v1beta3_DownwardAPIVolumeSource, + deepCopy_v1beta3_EmptyDirVolumeSource, + deepCopy_v1beta3_EndpointAddress, + deepCopy_v1beta3_EndpointPort, + deepCopy_v1beta3_EndpointSubset, + deepCopy_v1beta3_Endpoints, + deepCopy_v1beta3_EndpointsList, + deepCopy_v1beta3_EnvVar, + deepCopy_v1beta3_EnvVarSource, + deepCopy_v1beta3_Event, + deepCopy_v1beta3_EventList, + deepCopy_v1beta3_EventSource, + deepCopy_v1beta3_ExecAction, + deepCopy_v1beta3_FSGroupStrategyOptions, + deepCopy_v1beta3_GCEPersistentDiskVolumeSource, + deepCopy_v1beta3_GitRepoVolumeSource, + deepCopy_v1beta3_GlusterfsVolumeSource, + deepCopy_v1beta3_HTTPGetAction, + deepCopy_v1beta3_Handler, + deepCopy_v1beta3_HostPathVolumeSource, + deepCopy_v1beta3_IDRange, + deepCopy_v1beta3_ISCSIVolumeSource, + deepCopy_v1beta3_Lifecycle, + deepCopy_v1beta3_LimitRange, + deepCopy_v1beta3_LimitRangeItem, + deepCopy_v1beta3_LimitRangeList, + deepCopy_v1beta3_LimitRangeSpec, + deepCopy_v1beta3_List, + deepCopy_v1beta3_ListMeta, + deepCopy_v1beta3_ListOptions, + deepCopy_v1beta3_LoadBalancerIngress, + deepCopy_v1beta3_LoadBalancerStatus, + deepCopy_v1beta3_LocalObjectReference, + deepCopy_v1beta3_MetadataFile, + deepCopy_v1beta3_MetadataVolumeSource, + deepCopy_v1beta3_NFSVolumeSource, + deepCopy_v1beta3_Namespace, + deepCopy_v1beta3_NamespaceList, + deepCopy_v1beta3_NamespaceSpec, + deepCopy_v1beta3_NamespaceStatus, + deepCopy_v1beta3_Node, + deepCopy_v1beta3_NodeAddress, + deepCopy_v1beta3_NodeCondition, + deepCopy_v1beta3_NodeList, + deepCopy_v1beta3_NodeSpec, + deepCopy_v1beta3_NodeStatus, + deepCopy_v1beta3_NodeSystemInfo, + deepCopy_v1beta3_ObjectFieldSelector, + deepCopy_v1beta3_ObjectMeta, + deepCopy_v1beta3_ObjectReference, + deepCopy_v1beta3_PersistentVolume, + deepCopy_v1beta3_PersistentVolumeClaim, + deepCopy_v1beta3_PersistentVolumeClaimList, + deepCopy_v1beta3_PersistentVolumeClaimSpec, + deepCopy_v1beta3_PersistentVolumeClaimStatus, + deepCopy_v1beta3_PersistentVolumeClaimVolumeSource, + deepCopy_v1beta3_PersistentVolumeList, + deepCopy_v1beta3_PersistentVolumeSource, + deepCopy_v1beta3_PersistentVolumeSpec, + deepCopy_v1beta3_PersistentVolumeStatus, + deepCopy_v1beta3_Pod, + deepCopy_v1beta3_PodCondition, + deepCopy_v1beta3_PodExecOptions, + deepCopy_v1beta3_PodList, + deepCopy_v1beta3_PodLogOptions, + deepCopy_v1beta3_PodProxyOptions, + deepCopy_v1beta3_PodSpec, + deepCopy_v1beta3_PodStatus, + deepCopy_v1beta3_PodStatusResult, + deepCopy_v1beta3_PodTemplate, + deepCopy_v1beta3_PodTemplateList, + deepCopy_v1beta3_PodTemplateSpec, + deepCopy_v1beta3_Probe, + deepCopy_v1beta3_RBDVolumeSource, + deepCopy_v1beta3_RangeAllocation, + deepCopy_v1beta3_ReplicationController, + deepCopy_v1beta3_ReplicationControllerList, + deepCopy_v1beta3_ReplicationControllerSpec, + deepCopy_v1beta3_ReplicationControllerStatus, + deepCopy_v1beta3_ResourceQuota, + deepCopy_v1beta3_ResourceQuotaList, + deepCopy_v1beta3_ResourceQuotaSpec, + deepCopy_v1beta3_ResourceQuotaStatus, + deepCopy_v1beta3_ResourceRequirements, + deepCopy_v1beta3_RunAsUserStrategyOptions, + deepCopy_v1beta3_SELinuxContextStrategyOptions, + deepCopy_v1beta3_SELinuxOptions, + deepCopy_v1beta3_Secret, + deepCopy_v1beta3_SecretList, + deepCopy_v1beta3_SecretVolumeSource, + deepCopy_v1beta3_SecurityContext, + deepCopy_v1beta3_SecurityContextConstraints, + deepCopy_v1beta3_SecurityContextConstraintsList, + deepCopy_v1beta3_SerializedReference, + deepCopy_v1beta3_Service, + deepCopy_v1beta3_ServiceAccount, + deepCopy_v1beta3_ServiceAccountList, + deepCopy_v1beta3_ServiceList, + deepCopy_v1beta3_ServicePort, + deepCopy_v1beta3_ServiceSpec, + deepCopy_v1beta3_ServiceStatus, + deepCopy_v1beta3_Status, + deepCopy_v1beta3_StatusCause, + deepCopy_v1beta3_StatusDetails, + deepCopy_v1beta3_SupplementalGroupsStrategyOptions, + deepCopy_v1beta3_TCPSocketAction, + deepCopy_v1beta3_TypeMeta, + deepCopy_v1beta3_Volume, + deepCopy_v1beta3_VolumeMount, + deepCopy_v1beta3_VolumeSource, + deepCopy_runtime_RawExtension, + deepCopy_util_IntOrString, + deepCopy_util_Time, + ) + if err != nil { + // if one of the deep copy functions is malformed, detect it immediately. + panic(err) + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go new file mode 100644 index 000000000000..35c6f91d28d9 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go @@ -0,0 +1,218 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 v1beta3 + +import ( + "strings" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util" + "github.com/golang/glog" +) + +func addDefaultingFuncs() { + api.Scheme.AddDefaultingFuncs( + func(obj *ReplicationController) { + var labels map[string]string + if obj.Spec.Template != nil { + labels = obj.Spec.Template.Labels + } + // TODO: support templates defined elsewhere when we support them in the API + if labels != nil { + if len(obj.Spec.Selector) == 0 { + obj.Spec.Selector = labels + } + if len(obj.Labels) == 0 { + obj.Labels = labels + } + } + if obj.Spec.Replicas == nil { + obj.Spec.Replicas = new(int) + *obj.Spec.Replicas = 0 + } + }, + func(obj *Volume) { + if util.AllPtrFieldsNil(&obj.VolumeSource) { + obj.VolumeSource = VolumeSource{ + EmptyDir: &EmptyDirVolumeSource{}, + } + } + }, + func(obj *ContainerPort) { + if obj.Protocol == "" { + obj.Protocol = ProtocolTCP + } + }, + func(obj *Container) { + if obj.ImagePullPolicy == "" { + // TODO(dchen1107): Move ParseImageName code to pkg/util + parts := strings.Split(obj.Image, ":") + // Check image tag + if parts[len(parts)-1] == "latest" { + obj.ImagePullPolicy = PullAlways + } else { + obj.ImagePullPolicy = PullIfNotPresent + } + } + if obj.TerminationMessagePath == "" { + obj.TerminationMessagePath = TerminationMessagePathDefault + } + defaultSecurityContext(obj) + }, + func(obj *ServiceSpec) { + if obj.SessionAffinity == "" { + obj.SessionAffinity = ServiceAffinityNone + } + if obj.Type == "" { + if obj.CreateExternalLoadBalancer { + obj.Type = ServiceTypeLoadBalancer + } else { + obj.Type = ServiceTypeClusterIP + } + } else if obj.Type == ServiceTypeLoadBalancer { + obj.CreateExternalLoadBalancer = true + } + for i := range obj.Ports { + sp := &obj.Ports[i] + if sp.Protocol == "" { + sp.Protocol = ProtocolTCP + } + if sp.TargetPort == util.NewIntOrStringFromInt(0) || sp.TargetPort == util.NewIntOrStringFromString("") { + sp.TargetPort = util.NewIntOrStringFromInt(sp.Port) + } + } + }, + func(obj *PodSpec) { + if obj.DNSPolicy == "" { + obj.DNSPolicy = DNSClusterFirst + } + if obj.RestartPolicy == "" { + obj.RestartPolicy = RestartPolicyAlways + } + if obj.HostNetwork { + defaultHostNetworkPorts(&obj.Containers) + } + }, + func(obj *Probe) { + if obj.TimeoutSeconds == 0 { + obj.TimeoutSeconds = 1 + } + }, + func(obj *Secret) { + if obj.Type == "" { + obj.Type = SecretTypeOpaque + } + }, + func(obj *PersistentVolume) { + if obj.Status.Phase == "" { + obj.Status.Phase = VolumePending + } + if obj.Spec.PersistentVolumeReclaimPolicy == "" { + obj.Spec.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimRetain + } + }, + func(obj *PersistentVolumeClaim) { + if obj.Status.Phase == "" { + obj.Status.Phase = ClaimPending + } + }, + func(obj *Endpoints) { + for i := range obj.Subsets { + ss := &obj.Subsets[i] + for i := range ss.Ports { + ep := &ss.Ports[i] + if ep.Protocol == "" { + ep.Protocol = ProtocolTCP + } + } + } + }, + func(obj *HTTPGetAction) { + if obj.Path == "" { + obj.Path = "/" + } + if obj.Scheme == "" { + obj.Scheme = URISchemeHTTP + } + }, + func(obj *NamespaceStatus) { + if obj.Phase == "" { + obj.Phase = NamespaceActive + } + }, + func(obj *Node) { + if obj.Spec.ExternalID == "" { + obj.Spec.ExternalID = obj.Name + } + }, + func(obj *ObjectFieldSelector) { + if obj.APIVersion == "" { + obj.APIVersion = "v1beta3" + } + }, + ) +} + +// With host networking default all container ports to host ports. +func defaultHostNetworkPorts(containers *[]Container) { + for i := range *containers { + for j := range (*containers)[i].Ports { + if (*containers)[i].Ports[j].HostPort == 0 { + (*containers)[i].Ports[j].HostPort = (*containers)[i].Ports[j].ContainerPort + } + } + } +} + +// defaultSecurityContext performs the downward and upward merges of a pod definition +func defaultSecurityContext(container *Container) { + if container.SecurityContext == nil { + if (len(container.Capabilities.Add) == 0) && (len(container.Capabilities.Drop) == 0) && (container.Privileged == false) { + return + } + glog.V(5).Infof("creating security context for container %s", container.Name) + container.SecurityContext = &SecurityContext{} + } + // if there are no capabilities defined on the SecurityContext then copy the container settings + if container.SecurityContext.Capabilities == nil { + container.SecurityContext.Capabilities = &container.Capabilities + } else { + // if there are capabilities defined on the security context and the container setting is + // empty then assume that it was left off the pod definition and ensure that the container + // settings match the security context settings (checked by the convert functions). If + // there are settings in both then don't touch it, the converter will error if they don't + // match + if len(container.Capabilities.Add) == 0 { + container.Capabilities.Add = container.SecurityContext.Capabilities.Add + } + if len(container.Capabilities.Drop) == 0 { + container.Capabilities.Drop = container.SecurityContext.Capabilities.Drop + } + } + // if there are no privileged settings on the security context then copy the container settings + if container.SecurityContext.Privileged == nil { + container.SecurityContext.Privileged = &container.Privileged + } else { + // we don't have a good way to know if container.Privileged was set or just defaulted to false + // so the best we can do here is check if the securityContext is set to true and the + // container is set to false and assume that the Privileged field was left off the container + // definition and not an intentional mismatch + if *container.SecurityContext.Privileged && !container.Privileged { + container.Privileged = *container.SecurityContext.Privileged + } + } +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go new file mode 100644 index 000000000000..b9c232400113 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go @@ -0,0 +1,471 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 v1beta3_test + +import ( + "reflect" + "testing" + + "k8s.io/kubernetes/pkg/api" + versioned "k8s.io/kubernetes/pkg/api/v1beta3" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util" +) + +func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { + data, err := versioned.Codec.Encode(obj) + if err != nil { + t.Errorf("%v\n %#v", err, obj) + return nil + } + obj2, err := api.Codec.Decode(data) + if err != nil { + t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj) + return nil + } + obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object) + err = api.Scheme.Convert(obj2, obj3) + if err != nil { + t.Errorf("%v\nSource: %#v", err, obj2) + return nil + } + return obj3 +} + +func TestSetDefaultReplicationController(t *testing.T) { + tests := []struct { + rc *versioned.ReplicationController + expectLabels bool + expectSelector bool + }{ + { + rc: &versioned.ReplicationController{ + Spec: versioned.ReplicationControllerSpec{ + Template: &versioned.PodTemplateSpec{ + ObjectMeta: versioned.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + expectLabels: true, + expectSelector: true, + }, + { + rc: &versioned.ReplicationController{ + ObjectMeta: versioned.ObjectMeta{ + Labels: map[string]string{ + "bar": "foo", + }, + }, + Spec: versioned.ReplicationControllerSpec{ + Template: &versioned.PodTemplateSpec{ + ObjectMeta: versioned.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + expectLabels: false, + expectSelector: true, + }, + { + rc: &versioned.ReplicationController{ + ObjectMeta: versioned.ObjectMeta{ + Labels: map[string]string{ + "bar": "foo", + }, + }, + Spec: versioned.ReplicationControllerSpec{ + Selector: map[string]string{ + "some": "other", + }, + Template: &versioned.PodTemplateSpec{ + ObjectMeta: versioned.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + expectLabels: false, + expectSelector: false, + }, + { + rc: &versioned.ReplicationController{ + Spec: versioned.ReplicationControllerSpec{ + Selector: map[string]string{ + "some": "other", + }, + Template: &versioned.PodTemplateSpec{ + ObjectMeta: versioned.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + expectLabels: true, + expectSelector: false, + }, + } + + for _, test := range tests { + rc := test.rc + obj2 := roundTrip(t, runtime.Object(rc)) + rc2, ok := obj2.(*versioned.ReplicationController) + if !ok { + t.Errorf("unexpected object: %v", rc2) + t.FailNow() + } + if test.expectSelector != reflect.DeepEqual(rc2.Spec.Selector, rc2.Spec.Template.Labels) { + if test.expectSelector { + t.Errorf("expected: %v, got: %v", rc2.Spec.Template.Labels, rc2.Spec.Selector) + } else { + t.Errorf("unexpected equality: %v", rc.Spec.Selector) + } + } + if test.expectLabels != reflect.DeepEqual(rc2.Labels, rc2.Spec.Template.Labels) { + if test.expectLabels { + t.Errorf("expected: %v, got: %v", rc2.Spec.Template.Labels, rc2.Labels) + } else { + t.Errorf("unexpected equality: %v", rc.Labels) + } + } + } +} + +func TestSetDefaultService(t *testing.T) { + svc := &versioned.Service{} + obj2 := roundTrip(t, runtime.Object(svc)) + svc2 := obj2.(*versioned.Service) + if svc2.Spec.SessionAffinity != versioned.ServiceAffinityNone { + t.Errorf("Expected default session affinity type:%s, got: %s", versioned.ServiceAffinityNone, svc2.Spec.SessionAffinity) + } + if svc2.Spec.Type != versioned.ServiceTypeClusterIP { + t.Errorf("Expected default type:%s, got: %s", versioned.ServiceTypeClusterIP, svc2.Spec.Type) + } +} + +func TestSetDefaultServiceWithLoadbalancer(t *testing.T) { + svc := &versioned.Service{} + svc.Spec.CreateExternalLoadBalancer = true + obj2 := roundTrip(t, runtime.Object(svc)) + svc2 := obj2.(*versioned.Service) + if svc2.Spec.Type != versioned.ServiceTypeLoadBalancer { + t.Errorf("Expected default type:%s, got: %s", versioned.ServiceTypeLoadBalancer, svc2.Spec.Type) + } +} + +func TestSetDefaultSecret(t *testing.T) { + s := &versioned.Secret{} + obj2 := roundTrip(t, runtime.Object(s)) + s2 := obj2.(*versioned.Secret) + + if s2.Type != versioned.SecretTypeOpaque { + t.Errorf("Expected secret type %v, got %v", versioned.SecretTypeOpaque, s2.Type) + } +} + +func TestSetDefaultPersistentVolume(t *testing.T) { + pv := &versioned.PersistentVolume{} + obj2 := roundTrip(t, runtime.Object(pv)) + pv2 := obj2.(*versioned.PersistentVolume) + + if pv2.Status.Phase != versioned.VolumePending { + t.Errorf("Expected volume phase %v, got %v", versioned.VolumePending, pv2.Status.Phase) + } + if pv2.Spec.PersistentVolumeReclaimPolicy != versioned.PersistentVolumeReclaimRetain { + t.Errorf("Expected pv reclaim policy %v, got %v", versioned.PersistentVolumeReclaimRetain, pv2.Spec.PersistentVolumeReclaimPolicy) + } +} + +func TestSetDefaultPersistentVolumeClaim(t *testing.T) { + pvc := &versioned.PersistentVolumeClaim{} + obj2 := roundTrip(t, runtime.Object(pvc)) + pvc2 := obj2.(*versioned.PersistentVolumeClaim) + + if pvc2.Status.Phase != versioned.ClaimPending { + t.Errorf("Expected claim phase %v, got %v", versioned.ClaimPending, pvc2.Status.Phase) + } +} + +func TestSetDefaulEndpointsProtocol(t *testing.T) { + in := &versioned.Endpoints{Subsets: []versioned.EndpointSubset{ + {Ports: []versioned.EndpointPort{{}, {Protocol: "UDP"}, {}}}, + }} + obj := roundTrip(t, runtime.Object(in)) + out := obj.(*versioned.Endpoints) + + for i := range out.Subsets { + for j := range out.Subsets[i].Ports { + if in.Subsets[i].Ports[j].Protocol == "" { + if out.Subsets[i].Ports[j].Protocol != versioned.ProtocolTCP { + t.Errorf("Expected protocol %s, got %s", versioned.ProtocolTCP, out.Subsets[i].Ports[j].Protocol) + } + } else { + if out.Subsets[i].Ports[j].Protocol != in.Subsets[i].Ports[j].Protocol { + t.Errorf("Expected protocol %s, got %s", in.Subsets[i].Ports[j].Protocol, out.Subsets[i].Ports[j].Protocol) + } + } + } + } +} + +func TestSetDefaulServiceTargetPort(t *testing.T) { + in := &versioned.Service{Spec: versioned.ServiceSpec{Ports: []versioned.ServicePort{{Port: 1234}}}} + obj := roundTrip(t, runtime.Object(in)) + out := obj.(*versioned.Service) + if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromInt(1234) { + t.Errorf("Expected TargetPort to be defaulted, got %s", out.Spec.Ports[0].TargetPort) + } + + in = &versioned.Service{Spec: versioned.ServiceSpec{Ports: []versioned.ServicePort{{Port: 1234, TargetPort: util.NewIntOrStringFromInt(5678)}}}} + obj = roundTrip(t, runtime.Object(in)) + out = obj.(*versioned.Service) + if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromInt(5678) { + t.Errorf("Expected TargetPort to be unchanged, got %s", out.Spec.Ports[0].TargetPort) + } +} + +func TestSetDefaultServicePort(t *testing.T) { + // Unchanged if set. + in := &versioned.Service{Spec: versioned.ServiceSpec{ + Ports: []versioned.ServicePort{ + {Protocol: "UDP", Port: 9376, TargetPort: util.NewIntOrStringFromString("p")}, + {Protocol: "UDP", Port: 8675, TargetPort: util.NewIntOrStringFromInt(309)}, + }, + }} + out := roundTrip(t, runtime.Object(in)).(*versioned.Service) + if out.Spec.Ports[0].Protocol != versioned.ProtocolUDP { + t.Errorf("Expected protocol %s, got %s", versioned.ProtocolUDP, out.Spec.Ports[0].Protocol) + } + if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromString("p") { + t.Errorf("Expected port %d, got %s", in.Spec.Ports[0].Port, out.Spec.Ports[0].TargetPort) + } + if out.Spec.Ports[1].Protocol != versioned.ProtocolUDP { + t.Errorf("Expected protocol %s, got %s", versioned.ProtocolUDP, out.Spec.Ports[1].Protocol) + } + if out.Spec.Ports[1].TargetPort != util.NewIntOrStringFromInt(309) { + t.Errorf("Expected port %d, got %s", in.Spec.Ports[1].Port, out.Spec.Ports[1].TargetPort) + } + + // Defaulted. + in = &versioned.Service{Spec: versioned.ServiceSpec{ + Ports: []versioned.ServicePort{ + {Protocol: "", Port: 9376, TargetPort: util.NewIntOrStringFromString("")}, + {Protocol: "", Port: 8675, TargetPort: util.NewIntOrStringFromInt(0)}, + }, + }} + out = roundTrip(t, runtime.Object(in)).(*versioned.Service) + if out.Spec.Ports[0].Protocol != versioned.ProtocolTCP { + t.Errorf("Expected protocol %s, got %s", versioned.ProtocolTCP, out.Spec.Ports[0].Protocol) + } + if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromInt(in.Spec.Ports[0].Port) { + t.Errorf("Expected port %d, got %d", in.Spec.Ports[0].Port, out.Spec.Ports[0].TargetPort) + } + if out.Spec.Ports[1].Protocol != versioned.ProtocolTCP { + t.Errorf("Expected protocol %s, got %s", versioned.ProtocolTCP, out.Spec.Ports[1].Protocol) + } + if out.Spec.Ports[1].TargetPort != util.NewIntOrStringFromInt(in.Spec.Ports[1].Port) { + t.Errorf("Expected port %d, got %d", in.Spec.Ports[1].Port, out.Spec.Ports[1].TargetPort) + } +} + +func TestSetDefaultNamespace(t *testing.T) { + s := &versioned.Namespace{} + obj2 := roundTrip(t, runtime.Object(s)) + s2 := obj2.(*versioned.Namespace) + + if s2.Status.Phase != versioned.NamespaceActive { + t.Errorf("Expected phase %v, got %v", versioned.NamespaceActive, s2.Status.Phase) + } +} + +func TestSetDefaultPodSpecHostNetwork(t *testing.T) { + portNum := 8080 + s := versioned.PodSpec{} + s.HostNetwork = true + s.Containers = []versioned.Container{ + { + Ports: []versioned.ContainerPort{ + { + ContainerPort: portNum, + }, + }, + }, + } + pod := &versioned.Pod{ + Spec: s, + } + obj2 := roundTrip(t, runtime.Object(pod)) + pod2 := obj2.(*versioned.Pod) + s2 := pod2.Spec + + hostPortNum := s2.Containers[0].Ports[0].HostPort + if hostPortNum != portNum { + t.Errorf("Expected container port to be defaulted, was made %d instead of %d", hostPortNum, portNum) + } +} + +func TestSetDefaultNodeExternalID(t *testing.T) { + name := "node0" + n := &versioned.Node{} + n.Name = name + obj2 := roundTrip(t, runtime.Object(n)) + n2 := obj2.(*versioned.Node) + if n2.Spec.ExternalID != name { + t.Errorf("Expected default External ID: %s, got: %s", name, n2.Spec.ExternalID) + } + if n2.Spec.ProviderID != "" { + t.Errorf("Expected empty default Cloud Provider ID, got: %s", n2.Spec.ProviderID) + } +} + +func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { + s := versioned.PodSpec{ + Containers: []versioned.Container{ + { + Env: []versioned.EnvVar{ + { + ValueFrom: &versioned.EnvVarSource{ + FieldRef: &versioned.ObjectFieldSelector{}, + }, + }, + }, + }, + }, + } + pod := &versioned.Pod{ + Spec: s, + } + obj2 := roundTrip(t, runtime.Object(pod)) + pod2 := obj2.(*versioned.Pod) + s2 := pod2.Spec + + apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion + if apiVersion != "v1beta3" { + t.Errorf("Expected default APIVersion v1beta3, got: %v", apiVersion) + } +} + +func TestSetDefaultSecurityContext(t *testing.T) { + priv := false + privTrue := true + testCases := map[string]struct { + c versioned.Container + }{ + "downward defaulting caps": { + c: versioned.Container{ + Privileged: false, + Capabilities: versioned.Capabilities{ + Add: []versioned.Capability{"foo"}, + Drop: []versioned.Capability{"bar"}, + }, + SecurityContext: &versioned.SecurityContext{ + Privileged: &priv, + }, + }, + }, + "downward defaulting priv": { + c: versioned.Container{ + Privileged: false, + Capabilities: versioned.Capabilities{ + Add: []versioned.Capability{"foo"}, + Drop: []versioned.Capability{"bar"}, + }, + SecurityContext: &versioned.SecurityContext{ + Capabilities: &versioned.Capabilities{ + Add: []versioned.Capability{"foo"}, + Drop: []versioned.Capability{"bar"}, + }, + }, + }, + }, + "upward defaulting caps": { + c: versioned.Container{ + Privileged: false, + SecurityContext: &versioned.SecurityContext{ + Privileged: &priv, + Capabilities: &versioned.Capabilities{ + Add: []versioned.Capability{"biz"}, + Drop: []versioned.Capability{"baz"}, + }, + }, + }, + }, + "upward defaulting priv": { + c: versioned.Container{ + Capabilities: versioned.Capabilities{ + Add: []versioned.Capability{"foo"}, + Drop: []versioned.Capability{"bar"}, + }, + SecurityContext: &versioned.SecurityContext{ + Privileged: &privTrue, + Capabilities: &versioned.Capabilities{ + Add: []versioned.Capability{"foo"}, + Drop: []versioned.Capability{"bar"}, + }, + }, + }, + }, + } + + pod := &versioned.Pod{ + Spec: versioned.PodSpec{}, + } + + for k, v := range testCases { + pod.Spec.Containers = []versioned.Container{v.c} + obj := roundTrip(t, runtime.Object(pod)) + defaultedPod := obj.(*versioned.Pod) + c := defaultedPod.Spec.Containers[0] + if isEqual, issues := areSecurityContextAndContainerEqual(&c); !isEqual { + t.Errorf("test case %s expected the security context to have the same values as the container but found %#v", k, issues) + } + } +} + +func areSecurityContextAndContainerEqual(c *versioned.Container) (bool, []string) { + issues := make([]string, 0) + equal := true + + if c.SecurityContext == nil || c.SecurityContext.Privileged == nil || c.SecurityContext.Capabilities == nil { + equal = false + issues = append(issues, "Expected non nil settings for SecurityContext") + return equal, issues + } + if *c.SecurityContext.Privileged != c.Privileged { + equal = false + issues = append(issues, "The defaulted SecurityContext.Privileged value did not match the container value") + } + if !reflect.DeepEqual(c.Capabilities.Add, c.Capabilities.Add) { + equal = false + issues = append(issues, "The defaulted SecurityContext.Capabilities.Add did not match the container settings") + } + if !reflect.DeepEqual(c.Capabilities.Drop, c.Capabilities.Drop) { + equal = false + issues = append(issues, "The defaulted SecurityContext.Capabilities.Drop did not match the container settings") + } + return equal, issues +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/register.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/register.go new file mode 100644 index 000000000000..974dda550350 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/register.go @@ -0,0 +1,134 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 v1beta3 + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/registered" + "k8s.io/kubernetes/pkg/runtime" +) + +// Codec encodes internal objects to the v1beta3 scheme +var Codec = runtime.CodecFor(api.Scheme, "v1beta3") + +func init() { + // Check if v1beta3 is in the list of supported API versions. + if !registered.IsRegisteredAPIVersion("v1beta3") { + return + } + + // Register the API. + addKnownTypes() + addConversionFuncs() + addDefaultingFuncs() +} + +// Adds the list of known types to api.Scheme. +func addKnownTypes() { + api.Scheme.AddKnownTypes("v1beta3", + &Pod{}, + &PodList{}, + &PodStatusResult{}, + &PodTemplate{}, + &PodTemplateList{}, + &ReplicationController{}, + &ReplicationControllerList{}, + &Service{}, + &ServiceList{}, + &Endpoints{}, + &EndpointsList{}, + &Node{}, + &NodeList{}, + &Binding{}, + &Status{}, + &Event{}, + &EventList{}, + &List{}, + &LimitRange{}, + &LimitRangeList{}, + &ResourceQuota{}, + &ResourceQuotaList{}, + &Namespace{}, + &NamespaceList{}, + &Secret{}, + &SecretList{}, + &ServiceAccount{}, + &ServiceAccountList{}, + &PersistentVolume{}, + &PersistentVolumeList{}, + &PersistentVolumeClaim{}, + &PersistentVolumeClaimList{}, + &DeleteOptions{}, + &ListOptions{}, + &PodLogOptions{}, + &PodExecOptions{}, + &PodProxyOptions{}, + &ComponentStatus{}, + &ComponentStatusList{}, + &SerializedReference{}, + &RangeAllocation{}, + &SecurityContextConstraints{}, + &SecurityContextConstraintsList{}, + ) + // Legacy names are supported + api.Scheme.AddKnownTypeWithName("v1beta3", "Minion", &Node{}) + api.Scheme.AddKnownTypeWithName("v1beta3", "MinionList", &NodeList{}) +} + +func (*Pod) IsAnAPIObject() {} +func (*PodList) IsAnAPIObject() {} +func (*PodStatusResult) IsAnAPIObject() {} +func (*PodTemplate) IsAnAPIObject() {} +func (*PodTemplateList) IsAnAPIObject() {} +func (*ReplicationController) IsAnAPIObject() {} +func (*ReplicationControllerList) IsAnAPIObject() {} +func (*Service) IsAnAPIObject() {} +func (*ServiceList) IsAnAPIObject() {} +func (*Endpoints) IsAnAPIObject() {} +func (*EndpointsList) IsAnAPIObject() {} +func (*Node) IsAnAPIObject() {} +func (*NodeList) IsAnAPIObject() {} +func (*Binding) IsAnAPIObject() {} +func (*Status) IsAnAPIObject() {} +func (*Event) IsAnAPIObject() {} +func (*EventList) IsAnAPIObject() {} +func (*List) IsAnAPIObject() {} +func (*LimitRange) IsAnAPIObject() {} +func (*LimitRangeList) IsAnAPIObject() {} +func (*ResourceQuota) IsAnAPIObject() {} +func (*ResourceQuotaList) IsAnAPIObject() {} +func (*Namespace) IsAnAPIObject() {} +func (*NamespaceList) IsAnAPIObject() {} +func (*Secret) IsAnAPIObject() {} +func (*SecretList) IsAnAPIObject() {} +func (*ServiceAccount) IsAnAPIObject() {} +func (*ServiceAccountList) IsAnAPIObject() {} +func (*PersistentVolume) IsAnAPIObject() {} +func (*PersistentVolumeList) IsAnAPIObject() {} +func (*PersistentVolumeClaim) IsAnAPIObject() {} +func (*PersistentVolumeClaimList) IsAnAPIObject() {} +func (*DeleteOptions) IsAnAPIObject() {} +func (*ListOptions) IsAnAPIObject() {} +func (*PodLogOptions) IsAnAPIObject() {} +func (*PodExecOptions) IsAnAPIObject() {} +func (*PodProxyOptions) IsAnAPIObject() {} +func (*ComponentStatus) IsAnAPIObject() {} +func (*ComponentStatusList) IsAnAPIObject() {} +func (*SerializedReference) IsAnAPIObject() {} +func (*RangeAllocation) IsAnAPIObject() {} +func (*SecurityContextConstraints) IsAnAPIObject() {} +func (*SecurityContextConstraintsList) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go new file mode 100644 index 000000000000..f8c338741303 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go @@ -0,0 +1,2252 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 v1beta3 + +import ( + "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/types" + "k8s.io/kubernetes/pkg/util" +) + +// Common string formats +// --------------------- +// Many fields in this API have formatting requirements. The commonly used +// formats are defined here. +// +// C_IDENTIFIER: This is a string that conforms to the definition of an "identifier" +// in the C language. This is captured by the following regex: +// [A-Za-z_][A-Za-z0-9_]* +// This defines the format, but not the length restriction, which should be +// specified at the definition of any field of this type. +// +// DNS_LABEL: This is a string, no more than 63 characters long, that conforms +// to the definition of a "label" in RFCs 1035 and 1123. This is captured +// by the following regex: +// [a-z0-9]([-a-z0-9]*[a-z0-9])? +// +// DNS_SUBDOMAIN: This is a string, no more than 253 characters long, that conforms +// to the definition of a "subdomain" in RFCs 1035 and 1123. This is captured +// by the following regex: +// [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)* +// or more simply: +// DNS_LABEL(\.DNS_LABEL)* +// +// IANA_SVC_NAME: This is a string, no more than 15 characters long, that +// conforms to the definition of IANA service name in RFC 6335. +// It must contains at least one letter [a-z] and it must contains only [a-z0-9-]. +// Hypens ('-') cannot be leading or trailing character of the string +// and cannot be adjacent to other hyphens. + +// TypeMeta describes an individual object in an API response or request +// with strings representing the type of the object and its API schema version. +// Structures that are versioned or persisted should inline TypeMeta. +type TypeMeta struct { + // Kind is a string value representing the REST resource this object represents. + // Servers may infer this from the endpoint the client submits requests to. + Kind string `json:"kind,omitempty" description:"kind of object, in CamelCase; cannot be updated"` + + // APIVersion defines the versioned schema of this representation of an object. + // Servers should convert recognized schemas to the latest internal value, and + // may reject unrecognized values. + APIVersion string `json:"apiVersion,omitempty" description:"version of the schema the object should have"` +} + +// ListMeta describes metadata that synthetic resources must have, including lists and +// various status objects. +type ListMeta struct { + // SelfLink is a URL representing this object. + SelfLink string `json:"selfLink,omitempty" description:"URL for the object; populated by the system, read-only"` + + // An opaque value that represents the version of this response for use with optimistic + // concurrency and change monitoring endpoints. Clients must treat these values as opaque + // and values may only be valid for a particular resource or set of resources. Only servers + // will generate resource versions. + ResourceVersion string `json:"resourceVersion,omitempty" description:"string that identifies the internal version of this object that can be used by clients to determine when objects have changed; populated by the system, read-only; value must be treated as opaque by clients and passed unmodified back to the server: http://releases.k8s.io/v1.0.0/docs/api-conventions.md#concurrency-control-and-consistency"` +} + +// ObjectMeta is metadata that all persisted resources must have, which includes all objects +// users must create. +type ObjectMeta struct { + // Name is unique within a namespace. Name is required when creating resources, although + // some resources may allow a client to request the generation of an appropriate name + // automatically. Name is primarily intended for creation idempotence and configuration + // definition. + Name string `json:"name,omitempty" description:"string that identifies an object. Must be unique within a namespace; cannot be updated"` + + // GenerateName indicates that the name should be made unique by the server prior to persisting + // it. A non-empty value for the field indicates the name will be made unique (and the name + // returned to the client will be different than the name passed). The value of this field will + // be combined with a unique suffix on the server if the Name field has not been provided. + // The provided value must be valid within the rules for Name, and may be truncated by the length + // of the suffix required to make the value unique on the server. + // + // If this field is specified, and Name is not present, the server will NOT return a 409 if the + // generated name exists - instead, it will either return 201 Created or 500 with Reason + // ServerTimeout indicating a unique name could not be found in the time allotted, and the client + // should retry (optionally after the time indicated in the Retry-After header). + GenerateName string `json:"generateName,omitempty" description:"an optional prefix to use to generate a unique name; has the same validation rules as name; optional, and is applied only name if is not specified"` + + // Namespace defines the space within which name must be unique. An empty namespace is + // equivalent to the "default" namespace, but "default" is the canonical representation. + // Not all objects are required to be scoped to a namespace - the value of this field for + // those objects will be empty. + Namespace string `json:"namespace,omitempty" description:"namespace of the object; must be a DNS_LABEL; cannot be updated"` + + // SelfLink is a URL representing this object. + SelfLink string `json:"selfLink,omitempty" description:"URL for the object; populated by the system, read-only"` + + // UID is the unique in time and space value for this object. It is typically generated by + // the server on successful creation of a resource and is not allowed to change on PUT + // operations. + UID types.UID `json:"uid,omitempty" description:"unique UUID across space and time; populated by the system; read-only"` + + // An opaque value that represents the version of this resource. May be used for optimistic + // concurrency, change detection, and the watch operation on a resource or set of resources. + // Clients must treat these values as opaque and values may only be valid for a particular + // resource or set of resources. Only servers will generate resource versions. + ResourceVersion string `json:"resourceVersion,omitempty" description:"string that identifies the internal version of this object that can be used by clients to determine when objects have changed; populated by the system, read-only; value must be treated as opaque by clients and passed unmodified back to the server: http://releases.k8s.io/v1.0.0/docs/api-conventions.md#concurrency-control-and-consistency"` + + // A sequence number representing a specific generation of the desired state. + // Currently only implemented by replication controllers. + Generation int64 `json:"generation,omitempty" description:"a sequence number representing a specific generation of the desired state; populated by the system; read-only"` + + // CreationTimestamp is a timestamp representing the server time when this object was + // created. It is not guaranteed to be set in happens-before order across separate operations. + // Clients may not set this value. It is represented in RFC3339 form and is in UTC. + CreationTimestamp unversioned.Time `json:"creationTimestamp,omitempty" description:"RFC 3339 date and time at which the object was created; populated by the system, read-only; null for lists"` + + // DeletionTimestamp is the time after which this resource will be deleted. This + // field is set by the server when a graceful deletion is requested by the user, and is not + // directly settable by a client. The resource will be deleted (no longer visible from + // resource lists, and not reachable by name) after the time in this field. Once set, this + // value may not be unset or be set further into the future, although it may be shortened + // or the resource may be deleted prior to this time. For example, a user may request that + // a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination + // signal to the containers in the pod. Once the resource is deleted in the API, the Kubelet + // will send a hard termination signal to the container. + DeletionTimestamp *unversioned.Time `json:"deletionTimestamp,omitempty" description:"RFC 3339 date and time at which the object will be deleted; populated by the system when a graceful deletion is requested, read-only; if not set, graceful deletion of the object has not been requested"` + + // Number of seconds allowed for this object to gracefully terminate before + // it will be removed from the system. Only set when deletionTimestamp is also set. + // May only be shortened. + // Read-only. + DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty"` + + // Labels are key value pairs that may be used to scope and select individual resources. + // TODO: replace map[string]string with labels.LabelSet type + Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize objects; may match selectors of replication controllers and services"` + + // Annotations are unstructured key value data stored with a resource that may be set by + // external tooling. They are not queryable and should be preserved when modifying + // objects. + Annotations map[string]string `json:"annotations,omitempty" description:"map of string keys and values that can be used by external tooling to store and retrieve arbitrary metadata about objects"` +} + +const ( + // NamespaceDefault means the object is in the default namespace which is applied when not specified by clients + NamespaceDefault string = "default" + // NamespaceAll is the default argument to specify on a context when you want to list or filter resources across all namespaces + NamespaceAll string = "" +) + +// Volume represents a named volume in a pod that may be accessed by any containers in the pod. +type Volume struct { + // Required: This must be a DNS_LABEL. Each volume in a pod must have + // a unique name. + Name string `json:"name" description:"volume name; must be a DNS_LABEL and unique within the pod"` + // Source represents the location and type of a volume to mount. + // This is optional for now. If not specified, the Volume is implied to be an EmptyDir. + // This implied behavior is deprecated and will be removed in a future version. + VolumeSource `json:",inline"` +} + +// VolumeSource represents the source location of a volume to mount. +// Only one of its members may be specified. +type VolumeSource struct { + // HostPath represents a pre-existing file or directory on the host + // machine that is directly exposed to the container. This is generally + // used for system agents or other privileged things that are allowed + // to see the host machine. Most containers will NOT need this. + // TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + // mount host directories as read/write. + HostPath *HostPathVolumeSource `json:"hostPath,omitempty" description:"pre-existing host file or directory; generally for privileged system daemons or other agents tied to the host"` + // EmptyDir represents a temporary directory that shares a pod's lifetime. + EmptyDir *EmptyDirVolumeSource `json:"emptyDir,omitempty" description:"temporary directory that shares a pod's lifetime"` + // GCEPersistentDisk represents a GCE Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty" description:"GCE disk resource attached to the host machine on demand"` + // AWSElasticBlockStore represents an AWS Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty" description:"AWS disk resource attached to the host machine on demand"` + // GitRepo represents a git repository at a particular revision. + GitRepo *GitRepoVolumeSource `json:"gitRepo,omitempty" description:"git repository at a particular revision"` + // Secret represents a secret that should populate this volume. + Secret *SecretVolumeSource `json:"secret,omitempty" description:"secret to populate volume"` + // NFS represents an NFS mount on the host that shares a pod's lifetime + NFS *NFSVolumeSource `json:"nfs,omitempty" description:"NFS volume that will be mounted in the host machine"` + // ISCSI represents an ISCSI Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi,omitempty" description:"iSCSI disk attached to host machine on demand"` + // Glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime + Glusterfs *GlusterfsVolumeSource `json:"glusterfs,omitempty" description:"Glusterfs volume that will be mounted on the host machine "` + // PersistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace + PersistentVolumeClaim *PersistentVolumeClaimVolumeSource `json:"persistentVolumeClaim,omitempty" description:"a reference to a PersistentVolumeClaim in the same namespace"` + // RBD represents a Rados Block Device mount on the host that shares a pod's lifetime + RBD *RBDVolumeSource `json:"rbd,omitempty" description:"rados block volume that will be mounted on the host machine"` + // Cinder represents a cinder volume attached and mounted on kubelets host machine + // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md + Cinder *CinderVolumeSource `json:"cinder,omitempty"` + // CephFS represents a Ceph FS mount on the host that shares a pod's lifetime + CephFS *CephFSVolumeSource `json:"cephfs,omitempty" description:"Ceph filesystem that will be mounted on the host machine"` + // Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running + Flocker *FlockerVolumeSource `json:"flocker,omitempty"` + + // DownwardAPI represents metadata about the pod that should populate this volume + DownwardAPI *DownwardAPIVolumeSource `json:"downwardAPI,omitempty" description: "Metadata volume containing information about the pod"` + // FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + FC *FCVolumeSource `json:"fc,omitempty"` + + // Metadata represents metadata about the pod that should populate this volume + // NOTE: Deprecated in favor of DownwardAPI + Metadata *MetadataVolumeSource `json:"metadata,omitempty" description: "Metadata volume containing information about the pod"` +} + +type PersistentVolumeClaimVolumeSource struct { + // ClaimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume + ClaimName string `json:"claimName,omitempty" description:"the name of the claim in the same namespace to be mounted as a volume"` + // Optional: Defaults to false (read/write). ReadOnly here + // will force the ReadOnly setting in VolumeMounts + ReadOnly bool `json:"readOnly,omitempty" description:"mount volume as read-only when true; default false"` +} + +// Similar to VolumeSource but meant for the administrator who creates PVs. +// Exactly one of its members must be set. +type PersistentVolumeSource struct { + // GCEPersistentDisk represents a GCE Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty" description:"GCE disk resource provisioned by an admin"` + // AWSElasticBlockStore represents an AWS Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty" description:"AWS disk resource provisioned by an admin"` + // HostPath represents a directory on the host. + // This is useful for development and testing only. + // on-host storage is not supported in any way. + HostPath *HostPathVolumeSource `json:"hostPath,omitempty" description:"a HostPath provisioned by a developer or tester; for develment use only"` + // Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod + Glusterfs *GlusterfsVolumeSource `json:"glusterfs,omitempty" description:"Glusterfs volume resource provisioned by an admin"` + // NFS represents an NFS mount on the host + NFS *NFSVolumeSource `json:"nfs,omitempty" description:"NFS volume resource provisioned by an admin"` + // RBD represents a Rados Block Device mount on the host that shares a pod's lifetime + RBD *RBDVolumeSource `json:"rbd,omitempty" description:"rados block volume that will be mounted on the host machine"` + // ISCSI represents an ISCSI Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi,omitempty" description:"an iSCSI disk resource provisioned by an admin"` + // CephFS represents a Ceph FS mount on the host that shares a pod's lifetime + CephFS *CephFSVolumeSource `json:"cephfs,omitempty" description:"Ceph filesystem that will be mounted on the host machine"` + // Cinder represents a cinder volume attached and mounted on kubelets host machine + // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md + Cinder *CinderVolumeSource `json:"cinder,omitempty"` + // FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + FC *FCVolumeSource `json:"fc,omitempty"` + // Flocker represents a Flocker volume attached to a kubelet's host machine and exposed to the pod for its usage. This depends on the Flocker control service being running + Flocker *FlockerVolumeSource `json:"flocker,omitempty"` +} + +type PersistentVolume struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + //Spec defines a persistent volume owned by the cluster + Spec PersistentVolumeSpec `json:"spec,omitempty" description:"specification of a persistent volume as provisioned by an administrator"` + + // Status represents the current information about persistent volume. + Status PersistentVolumeStatus `json:"status,omitempty" description:"current status of a persistent volume; populated by the system, read-only"` +} + +type PersistentVolumeSpec struct { + // Resources represents the actual resources of the volume + Capacity ResourceList `json:"capacity,omitempty" description:"a description of the persistent volume's resources and capacity"` + // Source represents the location and type of a volume to mount. + PersistentVolumeSource `json:",inline" description:"the actual volume backing the persistent volume"` + // AccessModes contains all ways the volume can be mounted + AccessModes []PersistentVolumeAccessMode `json:"accessModes,omitempty" description:"all ways the volume can be mounted"` + // ClaimRef is part of a bi-directional binding between PersistentVolume and PersistentVolumeClaim. + // ClaimRef is expected to be non-nil when bound. + // claim.VolumeName is the authoritative bind between PV and PVC. + ClaimRef *ObjectReference `json:"claimRef,omitempty" description:"when bound, a reference to the bound claim"` + // Optional: what happens to a persistent volume when released from its claim. + PersistentVolumeReclaimPolicy PersistentVolumeReclaimPolicy `json:"persistentVolumeReclaimPolicy,omitempty" description:"what happens to a volume when released from its claim; Valid options are Retain (default) and Recycle. Recyling must be supported by the volume plugin underlying this persistent volume."` +} + +// PersistentVolumeReclaimPolicy describes a policy for end-of-life maintenance of persistent volumes +type PersistentVolumeReclaimPolicy string + +const ( + // PersistentVolumeReclaimRecycle means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim. + // The volume plugin must support Recycling. + PersistentVolumeReclaimRecycle PersistentVolumeReclaimPolicy = "Recycle" + // PersistentVolumeReclaimDelete means the volume will be deleted from Kubernetes on release from its claim. + // The volume plugin must support Deletion. + // TODO: implement w/ DeletableVolumePlugin + // PersistentVolumeReclaimDelete PersistentVolumeReclaimPolicy = "Delete" + // PersistentVolumeReclaimRetain means the volume will left in its current phase (Released) for manual reclamation by the administrator. + // The default policy is Retain. + PersistentVolumeReclaimRetain PersistentVolumeReclaimPolicy = "Retain" +) + +type PersistentVolumeStatus struct { + // Phase indicates if a volume is available, bound to a claim, or released by a claim + Phase PersistentVolumePhase `json:"phase,omitempty" description:"the current phase of a persistent volume"` + // A human-readable message indicating details about why the volume is in this state. + Message string `json:"message,omitempty" description:"human-readable message indicating details about why the volume is in this state"` + // Reason is a brief CamelCase string that describes any failure and is meant for machine parsing and tidy display in the CLI + Reason string `json:"reason,omitempty" description:"(brief) reason the volume is not is not available"` +} + +type PersistentVolumeList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#types-kinds"` + Items []PersistentVolume `json:"items,omitempty" description:"list of persistent volumes"` +} + +// PersistentVolumeClaim is a user's request for and claim to a persistent volume +type PersistentVolumeClaim struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Spec defines the volume requested by a pod author + Spec PersistentVolumeClaimSpec `json:"spec,omitempty" description:"the desired characteristics of a volume"` + + // Status represents the current information about a claim + Status PersistentVolumeClaimStatus `json:"status,omitempty" description:"the current status of a persistent volume claim; read-only"` +} + +type PersistentVolumeClaimList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#types-kinds"` + Items []PersistentVolumeClaim `json:"items,omitempty" description:"a list of persistent volume claims"` +} + +// PersistentVolumeClaimSpec describes the common attributes of storage devices +// and allows a Source for provider-specific attributes +type PersistentVolumeClaimSpec struct { + // Contains the types of access modes required + AccessModes []PersistentVolumeAccessMode `json:"accessModes,omitempty" description:"the desired access modes the volume should have"` + // Resources represents the minimum resources required + Resources ResourceRequirements `json:"resources,omitempty" description:"the desired resources the volume should have"` + // VolumeName is the binding reference to the PersistentVolume backing this claim + VolumeName string `json:"volumeName,omitempty" description:"the binding reference to the persistent volume backing this claim"` +} + +type PersistentVolumeClaimStatus struct { + // Phase represents the current phase of PersistentVolumeClaim + Phase PersistentVolumeClaimPhase `json:"phase,omitempty" description:"the current phase of the claim"` + // AccessModes contains all ways the volume backing the PVC can be mounted + AccessModes []PersistentVolumeAccessMode `json:"accessModes,omitempty" description:"the actual access modes the volume has"` + // Represents the actual resources of the underlying volume + Capacity ResourceList `json:"capacity,omitempty" description:"the actual resources the volume has"` +} + +type PersistentVolumeAccessMode string + +const ( + // can be mounted read/write mode to exactly 1 host + ReadWriteOnce PersistentVolumeAccessMode = "ReadWriteOnce" + // can be mounted in read-only mode to many hosts + ReadOnlyMany PersistentVolumeAccessMode = "ReadOnlyMany" + // can be mounted in read/write mode to many hosts + ReadWriteMany PersistentVolumeAccessMode = "ReadWriteMany" +) + +type PersistentVolumePhase string + +const ( + // used for PersistentVolumes that are not available + VolumePending PersistentVolumePhase = "Pending" + // used for PersistentVolumes that are not yet bound + // Available volumes are held by the binder and matched to PersistentVolumeClaims + VolumeAvailable PersistentVolumePhase = "Available" + // used for PersistentVolumes that are bound + VolumeBound PersistentVolumePhase = "Bound" + // used for PersistentVolumes where the bound PersistentVolumeClaim was deleted + // released volumes must be recycled before becoming available again + // this phase is used by the persistent volume claim binder to signal to another process to reclaim the resource + VolumeReleased PersistentVolumePhase = "Released" + // used for PersistentVolumes that failed to be correctly recycled or deleted after being released from a claim + VolumeFailed PersistentVolumePhase = "Failed" +) + +type PersistentVolumeClaimPhase string + +const ( + // used for PersistentVolumeClaims that are not yet bound + ClaimPending PersistentVolumeClaimPhase = "Pending" + // used for PersistentVolumeClaims that are bound + ClaimBound PersistentVolumeClaimPhase = "Bound" +) + +// HostPathVolumeSource represents bare host directory volume. +type HostPathVolumeSource struct { + Path string `json:"path" description:"path of the directory on the host"` +} + +type EmptyDirVolumeSource struct { + // Optional: what type of storage medium should back this directory. + // The default is "" which means to use the node's default medium. + Medium StorageMedium `json:"medium,omitempty" description:"type of storage used to back the volume; must be an empty string (default) or Memory"` +} + +// GlusterfsVolumeSource represents a Glusterfs Mount that lasts the lifetime of a pod +type GlusterfsVolumeSource struct { + // Required: EndpointsName is the endpoint name that details Glusterfs topology + EndpointsName string `json:"endpoints" description:"gluster hosts endpoints name"` + + // Required: Path is the Glusterfs volume path + Path string `json:"path" description:"path to gluster volume"` + + // Optional: Defaults to false (read/write). ReadOnly here will force + // the Glusterfs volume to be mounted with read-only permissions + ReadOnly bool `json:"readOnly,omitempty" description:"glusterfs volume to be mounted with read-only permissions"` +} + +// DownwardAPIVolumeSource represents a volume containing downward API info +type DownwardAPIVolumeSource struct { + // Items is a list of DownwardAPIVolume file + Items []DownwardAPIVolumeFile `json:"items,omitempty"` +} + +// DownwardAPIVolumeFile represents a single file containing information from the downward API +type DownwardAPIVolumeFile struct { + // Required: Path is the relative path name of the file to be created. Must not be absolute or contain the '..' path. Must be utf-8 encoded. The first item of the relative path must not start with '..' + Path string `json:"path"` + // Required: Selects a field of the pod: only annotations, labels, name and namespace are supported. + FieldRef ObjectFieldSelector `json:"fieldRef"` +} + +// StorageMedium defines ways that storage can be allocated to a volume. +type StorageMedium string + +// RBDVolumeSource represents a Rados Block Device Mount that lasts the lifetime of a pod +type RBDVolumeSource struct { + // Required: CephMonitors is a collection of Ceph monitors + CephMonitors []string `json:"monitors" description:"a collection of Ceph monitors"` + // Required: RBDImage is the rados image name + RBDImage string `json:"image" description:"rados image name"` + // Required: Filesystem type to mount. + // Must be a filesystem type supported by the host operating system. + // Ex. "ext4", "xfs", "ntfs" + // TODO: how do we prevent errors in the filesystem from compromising the machine + FSType string `json:"fsType,omitempty" description:"file system type to mount, such as ext4, xfs, ntfs"` + // Optional: RadosPool is the rados pool name,default is rbd + RBDPool string `json:"pool" description:"rados pool name; default is rbd; optional"` + // Optional: RBDUser is the rados user name, default is admin + RadosUser string `json:"user" description:"rados user name; default is admin; optional"` + // Optional: Keyring is the path to key ring for RBDUser, default is /etc/ceph/keyring + Keyring string `json:"keyring" description:"keyring is the path to key ring for rados user; default is /etc/ceph/keyring; optional"` + // Optional: SecretRef is name of the authentication secret for RBDUser, default is empty. + SecretRef *LocalObjectReference `json:"secretRef" description:"name of a secret to authenticate the RBD user; if provided overrides keyring; optional"` + // Optional: Defaults to false (read/write). ReadOnly here will force + // the ReadOnly setting in VolumeMounts. + ReadOnly bool `json:"readOnly,omitempty" description:"rbd volume to be mounted with read-only permissions"` +} + +// CinderVolumeSource represents a cinder volume resource in Openstack. +// A Cinder volume must exist before mounting to a container. +// The volume must also be in the same region as the kubelet. +type CinderVolumeSource struct { + // volume id used to identify the volume in cinder + // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md + VolumeID string `json:"volumeID"` + // Required: Filesystem type to mount. + // Must be a filesystem type supported by the host operating system. + // Only ext3 and ext4 are allowed + // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md + FSType string `json:"fsType,omitempty"` + // Optional: Defaults to false (read/write). ReadOnly here will force + // the ReadOnly setting in VolumeMounts. + // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md + ReadOnly bool `json:"readOnly,omitempty"` +} + +// CephFSVolumeSource represents a Ceph Filesystem Mount that lasts the lifetime of a pod +type CephFSVolumeSource struct { + // Required: Monitors is a collection of Ceph monitors + Monitors []string `json:"monitors" description:"a collection of Ceph monitors"` + // Optional: User is the rados user name, default is admin + User string `json:"user,omitempty" description:"rados user name; default is admin; optional"` + // Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + SecretFile string `json:"secretFile,omitempty" description:"path to secret for rados user; default is /etc/ceph/user.secret; optional"` + // Optional: SecretRef is reference to the authentication secret for User, default is empty. + SecretRef *LocalObjectReference `json:"secretRef,omitempty" description:"name of a secret to authenticate the user; if provided overrides keyring; optional"` + // Optional: Defaults to false (read/write). ReadOnly here will force + // the ReadOnly setting in VolumeMounts. + ReadOnly bool `json:"readOnly,omitempty" description:"Ceph fs to be mounted with read-only permissions"` +} + +// FlockerVolumeSource represents a Flocker volume mounted by the Flocker agent. +type FlockerVolumeSource struct { + // Required: the volume name. This is going to be store on metadata -> name on the payload for Flocker + DatasetName string `json:"datasetName"` +} + +const ( + StorageMediumDefault StorageMedium = "" // use whatever the default is for the node + StorageMediumMemory StorageMedium = "Memory" // use memory (tmpfs) +) + +// Protocol defines network protocols supported for things like conatiner ports. +type Protocol string + +const ( + // ProtocolTCP is the TCP protocol. + ProtocolTCP Protocol = "TCP" + // ProtocolUDP is the UDP protocol. + ProtocolUDP Protocol = "UDP" +) + +// GCEPersistentDiskVolumeSource represents a Persistent Disk resource in Google Compute Engine. +// +// A GCE PD must exist and be formatted before mounting to a container. +// The disk must also be in the same GCE project and zone as the kubelet. +// A GCE PD can only be mounted as read/write once. +type GCEPersistentDiskVolumeSource struct { + // Unique name of the PD resource. Used to identify the disk in GCE + PDName string `json:"pdName" description:"unique name of the PD resource in GCE"` + // Required: Filesystem type to mount. + // Must be a filesystem type supported by the host operating system. + // Ex. "ext4", "xfs", "ntfs" + // TODO: how do we prevent errors in the filesystem from compromising the machine + FSType string `json:"fsType" description:"file system type to mount, such as ext4, xfs, ntfs"` + // Optional: Partition on the disk to mount. + // If omitted, kubelet will attempt to mount the device name. + // Ex. For /dev/sda1, this field is "1", for /dev/sda, this field is 0 or empty. + Partition int `json:"partition,omitempty" description:"partition on the disk to mount (e.g., '1' for /dev/sda1); if omitted the plain device name (e.g., /dev/sda) will be mounted"` + // Optional: Defaults to false (read/write). ReadOnly here will force + // the ReadOnly setting in VolumeMounts. + ReadOnly bool `json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"` +} + +// AWSElasticBlockStoreVolumeSource represents a Persistent Disk resource in AWS. +// +// An AWS PD must exist and be formatted before mounting to a container. +// The disk must also be in the same AWS zone as the kubelet. +// A AWS PD can only be mounted on a single machine. +type AWSElasticBlockStoreVolumeSource struct { + // Unique id of the PD resource. Used to identify the disk in AWS + VolumeID string `json:"volumeID" description:"unique id of the PD resource in AWS"` + // Required: Filesystem type to mount. + // Must be a filesystem type supported by the host operating system. + // Ex. "ext4", "xfs", "ntfs" + // TODO: how do we prevent errors in the filesystem from compromising the machine + FSType string `json:"fsType" description:"file system type to mount, such as ext4, xfs, ntfs"` + // Optional: Partition on the disk to mount. + // If omitted, kubelet will attempt to mount the device name. + // Ex. For /dev/sda1, this field is "1", for /dev/sda, this field 0 or empty. + Partition int `json:"partition,omitempty" description:"partition on the disk to mount (e.g., '1' for /dev/sda1); if omitted the plain device name (e.g., /dev/sda) will be mounted"` + // Optional: Defaults to false (read/write). ReadOnly here will force + // the ReadOnly setting in VolumeMounts. + ReadOnly bool `json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"` +} + +// GitRepoVolumeSource represents a volume that is pulled from git when the pod is created. +type GitRepoVolumeSource struct { + // Repository URL + Repository string `json:"repository" description:"repository URL"` + // Commit hash, this is optional + Revision string `json:"revision,omitempty" description:"commit hash for the specified revision"` +} + +// SecretVolumeSource adapts a Secret into a VolumeSource +// +// http://releases.k8s.io/v1.0.0/docs/design/secrets.md +type SecretVolumeSource struct { + // Name of the secret in the pod's namespace to use + SecretName string `json:"secretName" description:"secretName is the name of a secret in the pod's namespace"` +} + +// NFSVolumeSource represents an NFS mount that lasts the lifetime of a pod +type NFSVolumeSource struct { + // Server is the hostname or IP address of the NFS server + Server string `json:"server" description:"the hostname or IP address of the NFS server"` + + // Path is the exported NFS share + Path string `json:"path" description:"the path that is exported by the NFS server"` + + // Optional: Defaults to false (read/write). ReadOnly here will force + // the NFS export to be mounted with read-only permissions + ReadOnly bool `json:"readOnly,omitempty" description:"forces the NFS export to be mounted with read-only permissions"` +} + +// A ISCSI Disk can only be mounted as read/write once. +type ISCSIVolumeSource struct { + // Required: iSCSI target portal + // the portal is either an IP or ip_addr:port if port is other than default (typically TCP ports 860 and 3260) + TargetPortal string `json:"targetPortal" description:"iSCSI target portal"` + // Required: target iSCSI Qualified Name + IQN string `json:"iqn" description:"iSCSI Qualified Name"` + // Required: iSCSI target lun number + Lun int `json:"lun" description:"iscsi target lun number"` + // Required: Filesystem type to mount. + // Must be a filesystem type supported by the host operating system. + // Ex. "ext4", "xfs", "ntfs" + // TODO: how do we prevent errors in the filesystem from compromising the machine + FSType string `json:"fsType" description:"file system type to mount, such as ext4, xfs, ntfs"` + // Optional: Defaults to false (read/write). ReadOnly here will force + // the ReadOnly setting in VolumeMounts. + ReadOnly bool `json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"` +} + +// A Fibre Channel Disk can only be mounted as read/write once. +type FCVolumeSource struct { + // Required: FC target world wide names (WWNs) + TargetWWNs []string `json:"targetWWNs"` + // Required: FC target lun number + Lun *int `json:"lun"` + // Required: Filesystem type to mount. + // Must be a filesystem type supported by the host operating system. + // Ex. "ext4", "xfs", "ntfs" + // TODO: how do we prevent errors in the filesystem from compromising the machine + FSType string `json:"fsType"` + // Optional: Defaults to false (read/write). ReadOnly here will force + // the ReadOnly setting in VolumeMounts. + ReadOnly bool `json:"readOnly,omitempty"` +} + +// ContainerPort represents a network port in a single container. +type ContainerPort struct { + // Optional: If specified, this must be a IANA_SVC_NAME. Each named port + // in a pod must have a unique name. + Name string `json:"name,omitempty" description:"name for the port that can be referred to by services; must be a IANA_SVC_NAME and unique within the pod"` + // Optional: If specified, this must be a valid port number, 0 < x < 65536. + // If HostNetwork is specified, this must match ContainerPort. + HostPort int `json:"hostPort,omitempty" description:"number of port to expose on the host; most containers do not need this"` + // Required: This must be a valid port number, 0 < x < 65536. + ContainerPort int `json:"containerPort" description:"number of port to expose on the pod's IP address"` + // Optional: Defaults to "TCP". + Protocol Protocol `json:"protocol,omitempty" description:"protocol for port; must be UDP or TCP; TCP if unspecified"` + // Optional: What host IP to bind the external port to. + HostIP string `json:"hostIP,omitempty" description:"host IP to bind the port to"` +} + +// VolumeMount describes a mounting of a Volume within a container. +type VolumeMount struct { + // Required: This must match the Name of a Volume [above]. + Name string `json:"name" description:"name of the volume to mount"` + // Optional: Defaults to false (read-write). + ReadOnly bool `json:"readOnly,omitempty" description:"mounted read-only if true, read-write otherwise (false or unspecified)"` + // Required. + MountPath string `json:"mountPath" description:"path within the container at which the volume should be mounted"` +} + +// EnvVar represents an environment variable present in a Container. +type EnvVar struct { + // Required: This must be a C_IDENTIFIER. + Name string `json:"name" description:"name of the environment variable; must be a C_IDENTIFIER"` + // Optional: no more than one of the following may be specified. + // Optional: Defaults to ""; variable references $(VAR_NAME) are expanded + // using the previous defined environment variables in the container and + // any service environment variables. If a variable cannot be resolved, + // the reference in the input string will be unchanged. The $(VAR_NAME) + // syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped + // references will never be expanded, regardless of whether the variable + // exists or not. + Value string `json:"value,omitempty" description:"value of the environment variable; defaults to empty string; variable references $(VAR_NAME) are expanded using the previously defined environment varibles in the container and any service environment variables; if a variable cannot be resolved, the reference in the input string will be unchanged; the $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME) ; escaped references will never be expanded, regardless of whether the variable exists or not"` + // Optional: Specifies a source the value of this var should come from. + ValueFrom *EnvVarSource `json:"valueFrom,omitempty" description:"source for the environment variable's value; cannot be used if value is not empty"` +} + +// EnvVarSource represents a source for the value of an EnvVar. +type EnvVarSource struct { + // Required: Selects a field of the pod; only name and namespace are supported. + FieldRef *ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod; only name and namespace are supported"` +} + +// ObjectFieldSelector selects an APIVersioned field of an object. +type ObjectFieldSelector struct { + // Optional: Version of the schema the FieldPath is written in terms of, defaults to "v1beta3" + APIVersion string `json:"apiVersion,omitempty" description:"version of the schema that fieldPath is written in terms of; defaults to v1beta3"` + // Required: Path of the field to select in the specified API version + FieldPath string `json:"fieldPath" description:"path of the field to select in the specified API version"` +} + +// HTTPGetAction describes an action based on HTTP Get requests. +type HTTPGetAction struct { + // Optional: Path to access on the HTTP server. + Path string `json:"path,omitempty" description:"path to access on the HTTP server"` + // Required: Name or number of the port to access on the container. + Port util.IntOrString `json:"port" description:"number or name of the port to access on the container; number must be in the range 1 to 65535; name must be a IANA_SVC_NAME"` + // Optional: Host name to connect to, defaults to the pod IP. + Host string `json:"host,omitempty" description:"hostname to connect to; defaults to pod IP"` + // Optional: Scheme to use for connecting to the host, defaults to HTTP. + Scheme URIScheme `json:"scheme,omitempty" description:"scheme to connect with, must be HTTP or HTTPS, defaults to HTTP"` +} + +// URIScheme identifies the scheme used for connection to a host for Get actions +type URIScheme string + +const ( + // URISchemeHTTP means that the scheme used will be http:// + URISchemeHTTP URIScheme = "HTTP" + // URISchemeHTTPS means that the scheme used will be https:// + URISchemeHTTPS URIScheme = "HTTPS" +) + +// TCPSocketAction describes an action based on opening a socket +type TCPSocketAction struct { + // Required: Port to connect to. + Port util.IntOrString `json:"port" description:"number or name of the port to access on the container; number must be in the range 1 to 65535; name must be a IANA_SVC_NAME"` +} + +// ExecAction describes a "run in container" action. +type ExecAction struct { + // Command is the command line to execute inside the container, the working directory for the + // command is root ('/') in the container's filesystem. The command is simply exec'd, it is + // not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + // a shell, you need to explicitly call out to that shell. + Command []string `json:"command,omitempty" description:"command line to execute inside the container; working directory for the command is root ('/') in the container's file system; the command is exec'd, not run inside a shell; exit status of 0 is treated as live/healthy and non-zero is unhealthy"` +} + +// Probe describes a liveness probe to be examined to the container. +type Probe struct { + // The action taken to determine the health of a container + Handler `json:",inline"` + // Length of time before health checking is activated. In seconds. + InitialDelaySeconds int64 `json:"initialDelaySeconds,omitempty" description:"number of seconds after the container has started before liveness probes are initiated"` + // Length of time before health checking times out. In seconds. + TimeoutSeconds int64 `json:"timeoutSeconds,omitempty" description:"number of seconds after which liveness probes timeout; defaults to 1 second"` +} + +// PullPolicy describes a policy for if/when to pull a container image +type PullPolicy string + +const ( + // PullAlways means that kubelet always attempts to pull the latest image. Container will fail If the pull fails. + PullAlways PullPolicy = "Always" + // PullNever means that kubelet never pulls an image, but only uses a local image. Container will fail if the image isn't present + PullNever PullPolicy = "Never" + // PullIfNotPresent means that kubelet pulls if the image isn't present on disk. Container will fail if the image isn't present and the pull fails. + PullIfNotPresent PullPolicy = "IfNotPresent" +) + +// Capability represent POSIX capabilities type +type Capability string + +// Capabilities represent POSIX capabilities that can be added or removed to a running container. +type Capabilities struct { + // Added capabilities + Add []Capability `json:"add,omitempty" description:"added capabilities"` + // Removed capabilities + Drop []Capability `json:"drop,omitempty" description:"droped capabilities"` +} + +// ResourceRequirements describes the compute resource requirements. +type ResourceRequirements struct { + // Limits describes the maximum amount of compute resources required. + Limits ResourceList `json:"limits,omitempty" description:"Maximum amount of compute resources allowed"` + // Requests describes the minimum amount of compute resources required. + // Note: 'Requests' are honored only for Persistent Volumes as of now. + // TODO: Update the scheduler to use 'Requests' in addition to 'Limits'. If Request is omitted for a container, + // it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value + Requests ResourceList `json:"requests,omitempty" description:"Minimum amount of resources requested; requests are honored only for persistent volumes as of now"` +} + +const ( + // TerminationMessagePathDefault means the default path to capture the application termination message running in a container + TerminationMessagePathDefault string = "/dev/termination-log" +) + +// Container represents a single container that is expected to be run on the host. +type Container struct { + // Required: This must be a DNS_LABEL. Each container in a pod must + // have a unique name. + Name string `json:"name" description:"name of the container; must be a DNS_LABEL and unique within the pod; cannot be updated"` + // Required. + Image string `json:"image" description:"Docker image name"` + // Optional: The docker image's entrypoint is used if this is not provided; cannot be updated. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax + // can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, + // regardless of whether the variable exists or not. + Command []string `json:"command,omitempty" description:"entrypoint array; not executed within a shell; the docker image's entrypoint is used if this is not provided; cannot be updated; variable references $(VAR_NAME) are expanded using the container's environment variables; if a variable cannot be resolved, the reference in the input string will be unchanged; the $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME) ; escaped references will never be expanded, regardless of whether the variable exists or not"` + // Optional: The docker image's cmd is used if this is not provided; cannot be updated. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax + // can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, + // regardless of whether the variable exists or not. + Args []string `json:"args,omitempty" description:"command array; the docker image's cmd is used if this is not provided; arguments to the entrypoint; cannot be updated; variable references $(VAR_NAME) are expanded using the container's environment variables; if a variable cannot be resolved, the reference in the input string will be unchanged; the $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME) ; escaped references will never be expanded, regardless of whether the variable exists or not"` + // Optional: Defaults to Docker's default. + WorkingDir string `json:"workingDir,omitempty" description:"container's working directory; defaults to image's default; cannot be updated"` + Ports []ContainerPort `json:"ports,omitempty" description:"list of ports to expose from the container; cannot be updated" patchStrategy:"merge" patchMergeKey:"containerPort"` + Env []EnvVar `json:"env,omitempty" description:"list of environment variables to set in the container; cannot be updated" patchStrategy:"merge" patchMergeKey:"name"` + Resources ResourceRequirements `json:"resources,omitempty" description:"Compute Resources required by this container; cannot be updated"` + VolumeMounts []VolumeMount `json:"volumeMounts,omitempty" description:"pod volumes to mount into the container's filesyste; cannot be updated" patchStrategy:"merge" patchMergeKey:"name"` + LivenessProbe *Probe `json:"livenessProbe,omitempty" description:"periodic probe of container liveness; container will be restarted if the probe fails; cannot be updated"` + ReadinessProbe *Probe `json:"readinessProbe,omitempty" description:"periodic probe of container service readiness; container will be removed from service endpoints if the probe fails; cannot be updated"` + Lifecycle *Lifecycle `json:"lifecycle,omitempty" description:"actions that the management system should take in response to container lifecycle events; cannot be updated"` + // Optional: Defaults to /dev/termination-log + TerminationMessagePath string `json:"terminationMessagePath,omitempty" description:"path at which the file to which the container's termination message will be written is mounted into the container's filesystem; message written is intended to be brief final status, such as an assertion failure message; defaults to /dev/termination-log; cannot be updated"` + // Deprecated - see SecurityContext. Optional: Default to false. + Privileged bool `json:"privileged,omitempty" description:"whether or not the container is granted privileged status; defaults to false; cannot be updated; deprecated; See SecurityContext."` + // Optional: Policy for pulling images for this container + ImagePullPolicy PullPolicy `json:"imagePullPolicy,omitempty" description:"image pull policy; one of Always, Never, IfNotPresent; defaults to Always if :latest tag is specified, or IfNotPresent otherwise; cannot be updated"` + // Deprecated - see SecurityContext. Optional: Capabilities for container. + Capabilities Capabilities `json:"capabilities,omitempty" description:"capabilities for container; cannot be updated; deprecated; See SecurityContext."` + // Optional: SecurityContext defines the security options the pod should be run with + SecurityContext *SecurityContext `json:"securityContext,omitempty" description:"security options the pod should run with"` + + // Variables for interactive containers, these have very specialized use-cases (e.g. debugging) + // and shouldn't be used for general purpose containers. + Stdin bool `json:"stdin,omitempty" description:"Whether this container should allocate a buffer for stdin in the container runtime; default is false"` + TTY bool `json:"tty,omitempty" description:"Whether this container should allocate a TTY for itself, also requires 'stdin' to be true; default is false"` +} + +// Handler defines a specific action that should be taken +// TODO: pass structured data to these actions, and document that data here. +type Handler struct { + // One and only one of the following should be specified. + // Exec specifies the action to take. + Exec *ExecAction `json:"exec,omitempty" description:"exec-based handler"` + // HTTPGet specifies the http request to perform. + HTTPGet *HTTPGetAction `json:"httpGet,omitempty" description:"HTTP-based handler"` + // TCPSocket specifies an action involving a TCP port. + // TODO: implement a realistic TCP lifecycle hook + TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty" description:"TCP-based handler; TCP hooks not yet supported"` +} + +// Lifecycle describes actions that the management system should take in response to container lifecycle +// events. For the PostStart and PreStop lifecycle handlers, management of the container blocks +// until the action is complete, unless the container process fails, in which case the handler is aborted. +type Lifecycle struct { + // PostStart is called immediately after a container is created. If the handler fails, the container + // is terminated and restarted. + PostStart *Handler `json:"postStart,omitempty" description:"called immediately after a container is started; if the handler fails, the container is terminated and restarted according to its restart policy; other management of the container blocks until the hook completes"` + // PreStop is called immediately before a container is terminated. The reason for termination is + // passed to the handler. Regardless of the outcome of the handler, the container is eventually terminated. + PreStop *Handler `json:"preStop,omitempty" description:"called before a container is terminated; the container is terminated after the handler completes; other management of the container blocks until the hook completes"` +} + +type ConditionStatus string + +// These are valid condition statuses. "ConditionTrue" means a resource is in the condition; +// "ConditionFalse" means a resource is not in the condition; "ConditionUnknown" means kubernetes +// can't decide if a resource is in the condition or not. In the future, we could add other +// intermediate conditions, e.g. ConditionDegraded. +const ( + ConditionTrue ConditionStatus = "True" + ConditionFalse ConditionStatus = "False" + ConditionUnknown ConditionStatus = "Unknown" +) + +type ContainerStateWaiting struct { + // Reason could be pulling image, + Reason string `json:"reason,omitempty" description:"(brief) reason the container is not yet running, such as pulling its image"` +} + +type ContainerStateRunning struct { + StartedAt unversioned.Time `json:"startedAt,omitempty" description:"time at which the container was last (re-)started"` +} + +type ContainerStateTerminated struct { + ExitCode int `json:"exitCode" description:"exit status from the last termination of the container"` + Signal int `json:"signal,omitempty" description:"signal from the last termination of the container"` + Reason string `json:"reason,omitempty" description:"(brief) reason from the last termination of the container"` + Message string `json:"message,omitempty" description:"message regarding the last termination of the container"` + StartedAt unversioned.Time `json:"startedAt,omitempty" description:"time at which previous execution of the container started"` + FinishedAt unversioned.Time `json:"finishedAt,omitempty" description:"time at which the container last terminated"` + ContainerID string `json:"containerID,omitempty" description:"container's ID in the format 'docker://'"` +} + +// ContainerState holds a possible state of container. +// Only one of its members may be specified. +// If none of them is specified, the default one is ContainerStateWaiting. +type ContainerState struct { + Waiting *ContainerStateWaiting `json:"waiting,omitempty" description:"details about a waiting container"` + Running *ContainerStateRunning `json:"running,omitempty" description:"details about a running container"` + Termination *ContainerStateTerminated `json:"termination,omitempty" description:"details about a terminated container"` +} + +type ContainerStatus struct { + // Required: This must be a DNS_LABEL. Each container in a pod must have a unique name. + Name string `json:"name" description:"name of the container; must be a DNS_LABEL and unique within the pod; cannot be updated"` + // TODO(dchen1107): Should we rename PodStatus to a more generic name or have a separate states + // defined for container? + State ContainerState `json:"state,omitempty" description:"details about the container's current condition"` + LastTerminationState ContainerState `json:"lastState,omitempty" description:"details about the container's last termination condition"` + Ready bool `json:"ready" description:"specifies whether the container has passed its readiness probe"` + // Note that this is calculated from dead containers. But those containers are subject to + // garbage collection. This value will get capped at 5 by GC. + RestartCount int `json:"restartCount" description:"the number of times the container has been restarted, currently based on the number of dead containers that have not yet been removed"` + // TODO(dchen1107): Which image the container is running with? + // The image the container is running + Image string `json:"image" description:"image of the container"` + ImageID string `json:"imageID" description:"ID of the container's image"` + ContainerID string `json:"containerID,omitempty" description:"container's ID in the format 'docker://'"` +} + +// PodPhase is a label for the condition of a pod at the current time. +type PodPhase string + +// These are the valid statuses of pods. +const ( + // PodPending means the pod has been accepted by the system, but one or more of the containers + // has not been started. This includes time before being bound to a node, as well as time spent + // pulling images onto the host. + PodPending PodPhase = "Pending" + // PodRunning means the pod has been bound to a node and all of the containers have been started. + // At least one container is still running or is in the process of being restarted. + PodRunning PodPhase = "Running" + // PodSucceeded means that all containers in the pod have voluntarily terminated + // with a container exit code of 0, and the system is not going to restart any of these containers. + PodSucceeded PodPhase = "Succeeded" + // PodFailed means that all containers in the pod have terminated, and at least one container has + // terminated in a failure (exited with a non-zero exit code or was stopped by the system). + PodFailed PodPhase = "Failed" + // PodUnknown means that for some reason the state of the pod could not be obtained, typically due + // to an error in communicating with the host of the pod. + PodUnknown PodPhase = "Unknown" +) + +// PodConditionType is a valid value for PodCondition.Type +type PodConditionType string + +// These are valid conditions of pod. +const ( + // PodReady means the pod is able to service requests and should be added to the + // load balancing pools of all matching services. + PodReady PodConditionType = "Ready" +) + +// TODO: add LastTransitionTime, Reason, Message to match NodeCondition api. +type PodCondition struct { + // Type is the type of the condition + Type PodConditionType `json:"type" description:"kind of the condition, currently only Ready"` + // Status is the status of the condition + Status ConditionStatus `json:"status" description:"status of the condition, one of True, False, Unknown"` +} + +// RestartPolicy describes how the container should be restarted. +// Only one of the following restart policies may be specified. +// If none of the following policies is specified, the default one +// is RestartPolicyAlways. +type RestartPolicy string + +const ( + RestartPolicyAlways RestartPolicy = "Always" + RestartPolicyOnFailure RestartPolicy = "OnFailure" + RestartPolicyNever RestartPolicy = "Never" +) + +// DNSPolicy defines how a pod's DNS will be configured. +type DNSPolicy string + +const ( + // DNSClusterFirst indicates that the pod should use cluster DNS + // first, if it is available, then fall back on the default (as + // determined by kubelet) DNS settings. + DNSClusterFirst DNSPolicy = "ClusterFirst" + + // DNSDefault indicates that the pod should use the default (as + // determined by kubelet) DNS settings. + DNSDefault DNSPolicy = "Default" +) + +// PodSpec is a description of a pod +type PodSpec struct { + Volumes []Volume `json:"volumes,omitempty" description:"list of volumes that can be mounted by containers belonging to the pod" patchStrategy:"merge" patchMergeKey:"name"` + // Required: there must be at least one container in a pod. + Containers []Container `json:"containers" description:"list of containers belonging to the pod; cannot be updated; containers cannot currently be added or removed; there must be at least one container in a Pod" patchStrategy:"merge" patchMergeKey:"name"` + RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of Always, OnFailure, Never; defaults to Always"` + // Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + // Value must be non-negative integer. The value zero indicates delete immediately. + // If this value is nil, the default grace period will be used instead. + // The grace period is the duration in seconds after the processes running in the pod are sent + // a termination signal and the time when the processes are forcibly halted with a kill signal. + // Set this value longer than the expected cleanup time for your process. + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" description:"optional duration in seconds the pod needs to terminate gracefully; may be decreased in delete request; value must be non-negative integer; the value zero indicates delete immediately; if this value is not set, the default grace period will be used instead; the grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal; set this value longer than the expected cleanup time for your process"` + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" description:"optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers; value must be a positive integer` + // Optional: Set DNS policy. Defaults to "ClusterFirst" + DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty" description:"DNS policy for containers within the pod; one of 'ClusterFirst' or 'Default'"` + // NodeSelector is a selector which must be true for the pod to fit on a node + NodeSelector map[string]string `json:"nodeSelector,omitempty" description:"selector which must match a node's labels for the pod to be scheduled on that node"` + + // ServiceAccount is the name of the ServiceAccount to use to run this pod + ServiceAccount string `json:"serviceAccount,omitempty" description:"name of the ServiceAccount to use to run this pod"` + + // Host is a request to schedule this pod onto a specific host. If it is non-empty, + // the the scheduler simply schedules this pod onto that host, assuming that it fits + // resource requirements. + Host string `json:"host,omitempty" description:"host requested for this pod"` + // Uses the host's network namespace. If this option is set, the ports that will be + // used must be specified. + // Optional: Default to false. + HostNetwork bool `json:"hostNetwork,omitempty" description:"host networking requested for this pod"` + // Use the host's pid namespace. + // Optional: Default to false. + HostPID bool `json:"hostPID,omitempty" description:"use the host's pid namespace"` + // Use the host's ipc namespace. + // Optional: Default to false. + HostIPC bool `json:"hostIPC,omitempty" description:"use the host's ipc namespace"` + // ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + // If specified, these secrets will be passed to individual puller implementations for them to use. For example, + // in the case of docker, only DockerConfig type secrets are honored. + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" description:"list of references to secrets in the same namespace available for pulling the container images" patchStrategy:"merge" patchMergeKey:"name"` +} + +// PodStatus represents information about the status of a pod. Status may trail the actual +// state of a system. +type PodStatus struct { + Phase PodPhase `json:"phase,omitempty" description:"current condition of the pod."` + Conditions []PodCondition `json:"Condition,omitempty" description:"current service state of pod" patchStrategy:"merge" patchMergeKey:"type"` + // A human readable message indicating details about why the pod is in this state. + Message string `json:"message,omitempty" description:"human readable message indicating details about why the pod is in this condition"` + // A brief CamelCase message indicating details about why the pod is in this state. e.g. 'OutOfDisk' + Reason string `json:"reason,omitempty" description:"(brief-CamelCase) reason indicating details about why the pod is in this condition"` + + HostIP string `json:"hostIP,omitempty" description:"IP address of the host to which the pod is assigned; empty if not yet scheduled"` + PodIP string `json:"podIP,omitempty" description:"IP address allocated to the pod; routable at least within the cluster; empty if not yet allocated"` + + StartTime *unversioned.Time `json:"startTime,omitempty" description:"RFC 3339 date and time at which the object was acknowledged by the Kubelet. This is before the Kubelet pulled the container image(s) for the pod."` + + // The list has one entry per container in the manifest. Each entry is currently the output + // of `docker inspect`. + ContainerStatuses []ContainerStatus `json:"containerStatuses,omitempty" description:"list of container statuses"` +} + +// PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded +type PodStatusResult struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + // Status represents the current information about a pod. This data may not be up + // to date. + Status PodStatus `json:"status,omitempty" description:"most recently observed status of the pod; populated by the system, read-only; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` +} + +// Pod is a collection of containers that can run on a host. This resource is created +// by clients and scheduled onto hosts. +type Pod struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Spec defines the behavior of a pod. + Spec PodSpec `json:"spec,omitempty" description:"specification of the desired behavior of the pod; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` + + // Status represents the current information about a pod. This data may not be up + // to date. + Status PodStatus `json:"status,omitempty" description:"most recently observed status of the pod; populated by the system, read-only; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` +} + +// PodList is a list of Pods. +type PodList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#types-kinds"` + + Items []Pod `json:"items" description:"list of pods"` +} + +// PodTemplateSpec describes the data a pod should have when created from a template +type PodTemplateSpec struct { + // Metadata of the pods created from this template. + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Spec defines the behavior of a pod. + Spec PodSpec `json:"spec,omitempty" description:"specification of the desired behavior of the pod; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` +} + +// PodTemplate describes a template for creating copies of a predefined pod. +type PodTemplate struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Template defines the pods that will be created from this pod template + Template PodTemplateSpec `json:"template,omitempty" description:"the template of the desired behavior of the pod; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` +} + +// PodTemplateList is a list of PodTemplates. +type PodTemplateList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Items []PodTemplate `json:"items" description:"list of pod templates"` +} + +// ReplicationControllerSpec is the specification of a replication controller. +type ReplicationControllerSpec struct { + // Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. + Replicas *int `json:"replicas,omitempty" description:"number of replicas desired"` + + // Selector is a label query over pods that should match the Replicas count. + // If Selector is empty, it is defaulted to the labels present on the Pod template. + Selector map[string]string `json:"selector,omitempty" description:"label keys and values that must match in order to be controlled by this replication controller, if empty defaulted to labels on Pod template"` + + // TemplateRef is a reference to an object that describes the pod that will be created if + // insufficient replicas are detected. + //TemplateRef *ObjectReference `json:"templateRef,omitempty" description:"reference to an object that describes the pod that will be created if insufficient replicas are detected"` + + // Template is the object that describes the pod that will be created if + // insufficient replicas are detected. This takes precedence over a + // TemplateRef. + Template *PodTemplateSpec `json:"template,omitempty" description:"object that describes the pod that will be created if insufficient replicas are detected; takes precendence over templateRef"` +} + +// ReplicationControllerStatus represents the current status of a replication +// controller. +type ReplicationControllerStatus struct { + // Replicas is the number of actual replicas. + Replicas int `json:"replicas" description:"most recently oberved number of replicas"` + + // ObservedGeneration is the most recent generation observed by the controller. + ObservedGeneration int64 `json:"observedGeneration,omitempty" description:"reflects the generation of the most recently observed replication controller"` +} + +// ReplicationController represents the configuration of a replication controller. +type ReplicationController struct { + TypeMeta `json:",inline"` + // If the Labels of a ReplicationController are empty, they are defaulted to be the same as the Pod(s) that the replication controller manages. + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Spec defines the desired behavior of this replication controller. + Spec ReplicationControllerSpec `json:"spec,omitempty" description:"specification of the desired behavior of the replication controller; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` + + // Status is the current status of this replication controller. This data may be + // out of date by some window of time. + Status ReplicationControllerStatus `json:"status,omitempty" description:"most recently observed status of the replication controller; populated by the system, read-only; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` +} + +// ReplicationControllerList is a collection of replication controllers. +type ReplicationControllerList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Items []ReplicationController `json:"items" description:"list of replication controllers"` +} + +// Session Affinity Type string +type ServiceAffinity string + +const ( + // ServiceAffinityClientIP is the Client IP based. + ServiceAffinityClientIP ServiceAffinity = "ClientIP" + + // ServiceAffinityNone - no session affinity. + ServiceAffinityNone ServiceAffinity = "None" +) + +// Service Type string describes ingress methods for a service +type ServiceType string + +const ( + // ServiceTypeClusterIP means a service will only be accessible inside the + // cluster, via the portal IP. + ServiceTypeClusterIP ServiceType = "ClusterIP" + + // ServiceTypeNodePort means a service will be exposed on one port of + // every node, in addition to 'ClusterIP' type. + ServiceTypeNodePort ServiceType = "NodePort" + + // ServiceTypeLoadBalancer means a service will be exposed via an + // external load balancer (if the cloud provider supports it), in addition + // to 'NodePort' type. + ServiceTypeLoadBalancer ServiceType = "LoadBalancer" +) + +// ServiceStatus represents the current status of a service +type ServiceStatus struct { + // LoadBalancer contains the current status of the load-balancer, + // if one is present. + LoadBalancer LoadBalancerStatus `json:"loadBalancer,omitempty" description:"status of load-balancer"` +} + +// LoadBalancerStatus represents the status of a load-balancer +type LoadBalancerStatus struct { + // Ingress is a list containing ingress points for the load-balancer; + // traffic intended for the service should be sent to these ingress points. + Ingress []LoadBalancerIngress `json:"ingress,omitempty" description:"load-balancer ingress points"` +} + +// LoadBalancerIngress represents the status of a load-balancer ingress point: +// traffic intended for the service should be sent to an ingress point. +type LoadBalancerIngress struct { + // IP is set for load-balancer ingress points that are IP based + // (typically GCE or OpenStack load-balancers) + IP string `json:"ip,omitempty" description:"IP address of ingress point"` + + // Hostname is set for load-balancer ingress points that are DNS based + // (typically AWS load-balancers) + Hostname string `json:"hostname,omitempty" description:"hostname of ingress point"` +} + +// ServiceSpec describes the attributes that a user creates on a service +type ServiceSpec struct { + // Required: The list of ports that are exposed by this service. + Ports []ServicePort `json:"ports" description:"ports exposed by the service"` + + // This service will route traffic to pods having labels matching this selector. If null, no endpoints will be automatically created. If empty, all pods will be selected. + Selector map[string]string `json:"selector,omitempty" description:"label keys and values that must match in order to receive traffic for this service; if empty, all pods are selected, if not specified, endpoints must be manually specified"` + + // PortalIP is usually assigned by the master. If specified by the user + // we will try to respect it or else fail the request. This field can + // not be changed by updates. + // Valid values are None, empty string (""), or a valid IP address + // None can be specified for headless services when proxying is not required + PortalIP string `json:"portalIP,omitempty description: IP address of the service; usually assigned by the system; if specified, it will be allocated to the service if unused, and creation of the service will fail otherwise; cannot be updated; 'None' can be specified for a headless service when proxying is not required"` + + // CreateExternalLoadBalancer indicates whether a load balancer should be created for this service. + CreateExternalLoadBalancer bool `json:"createExternalLoadBalancer,omitempty" description:"set up a cloud-provider-specific load balancer on an external IP"` + + // Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer + Type ServiceType `json:"type,omitempty" description:"type of this service; must be ClusterIP, NodePort, or LoadBalancer; defaults to ClusterIP"` + + // Deprecated. PublicIPs are used by external load balancers, or can be set by + // users to handle external traffic that arrives at a node. + PublicIPs []string `json:"publicIPs,omitempty" description:"deprecated. externally visible IPs (e.g. load balancers) that should be proxied to this service"` + + // Optional: Supports "ClientIP" and "None". Used to maintain session affinity. + SessionAffinity ServiceAffinity `json:"sessionAffinity,omitempty" description:"enable client IP based session affinity; must be ClientIP or None; defaults to None"` +} + +type ServicePort struct { + // Optional if only one ServicePort is defined on this service: The + // name of this port within the service. This must be a DNS_LABEL. + // All ports within a ServiceSpec must have unique names. This maps to + // the 'Name' field in EndpointPort objects. + Name string `json:"name,omitempty" description:"the name of this port; optional if only one port is defined"` + + // Optional: The IP protocol for this port. Supports "TCP" and "UDP", + // default is TCP. + Protocol Protocol `json:"protocol,omitempty" description:"the protocol used by this port; must be UDP or TCP; TCP if unspecified"` + + // Required: The port that will be exposed by this service. + Port int `json:"port" description:"the port number that is exposed"` + + // Optional: The target port on pods selected by this service. + // If this is a string, it will be looked up as a named port in the + // target Pod's container ports. If this is not specified, the value + // of Port is used (an identity map). + TargetPort util.IntOrString `json:"targetPort,omitempty" description:"number or name of the port to access on the pods targeted by the service; defaults to the service port; number must be in the range 1 to 65535; name must be a IANA_SVC_NAME"` + + // The port on each node on which this service is exposed. + // Default is to auto-allocate a port if the ServiceType of this Service requires one. + NodePort int `json:"nodePort" description:"the port on each node on which this service is exposed"` +} + +// Service is a named abstraction of software service (for example, mysql) consisting of local port +// (for example 3306) that the proxy listens on, and the selector that determines which pods +// will answer requests sent through the proxy. +type Service struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Spec defines the behavior of a service. + Spec ServiceSpec `json:"spec,omitempty" description:"specification of the desired behavior of the service; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` + + // Status represents the current status of a service. + Status ServiceStatus `json:"status,omitempty" description:"most recently observed status of the service; populated by the system, read-only; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` +} + +const ( + // PortalIPNone - do not assign a portal IP + // no proxying required and no environment variables should be created for pods + PortalIPNone = "None" +) + +// ServiceList holds a list of services. +type ServiceList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Items []Service `json:"items" description:"list of services"` +} + +// ServiceAccount binds together: +// * a name, understood by users, and perhaps by peripheral systems, for an identity +// * a principal that can be authenticated and authorized +// * a set of secrets +type ServiceAccount struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount + Secrets []ObjectReference `json:"secrets,omitempty" description:"list of secrets that can be used by pods running as this service account" patchStrategy:"merge" patchMergeKey:"name"` + + // ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images + // in pods that reference this ServiceAccount. ImagePullSecrets are distinct from Secrets because Secrets + // can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet. + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" description:"list of references to secrets in the same namespace available for pulling container images"` +} + +// ServiceAccountList is a list of ServiceAccount objects +type ServiceAccountList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Items []ServiceAccount `json:"items" description:"list of ServiceAccounts"` +} + +// Endpoints is a collection of endpoints that implement the actual service. Example: +// Name: "mysvc", +// Subsets: [ +// { +// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], +// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] +// }, +// { +// Addresses: [{"ip": "10.10.3.3"}], +// Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}] +// }, +// ] +type Endpoints struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // The set of all endpoints is the union of all subsets. + Subsets []EndpointSubset `json:"subsets" description:"sets of addresses and ports that comprise a service"` +} + +// EndpointSubset is a group of addresses with a common set of ports. The +// expanded set of endpoints is the Cartesian product of Addresses x Ports. +// For example, given: +// { +// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], +// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] +// } +// The resulting set of endpoints can be viewed as: +// a: [ 10.10.1.1:8675, 10.10.2.2:8675 ], +// b: [ 10.10.1.1:309, 10.10.2.2:309 ] +type EndpointSubset struct { + Addresses []EndpointAddress `json:"addresses,omitempty" description:"IP addresses which offer the related ports"` + Ports []EndpointPort `json:"ports,omitempty" description:"port numbers available on the related IP addresses"` +} + +// EndpointAddress is a tuple that describes single IP address. +type EndpointAddress struct { + // The IP of this endpoint. + // TODO: This should allow hostname or IP, see #4447. + IP string `json:"IP" description:"IP address of the endpoint"` + + // Optional: The kubernetes object related to the entry point. + TargetRef *ObjectReference `json:"targetRef,omitempty" description:"reference to object providing the endpoint"` +} + +// EndpointPort is a tuple that describes a single port. +type EndpointPort struct { + // The name of this port (corresponds to ServicePort.Name). Optional + // if only one port is defined. Must be a DNS_LABEL. + Name string `json:"name,omitempty" description:"name of this port"` + + // The port number. + Port int `json:"port" description:"port number of the endpoint"` + + // The IP protocol for this port. + Protocol Protocol `json:"protocol,omitempty" description:"protocol for this port; must be UDP or TCP; TCP if unspecified"` +} + +// EndpointsList is a list of endpoints. +type EndpointsList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Items []Endpoints `json:"items" description:"list of endpoints"` +} + +// NodeSpec describes the attributes that a node is created with. +type NodeSpec struct { + // PodCIDR represents the pod IP range assigned to the node + PodCIDR string `json:"podCIDR,omitempty" description:"pod IP range assigned to the node"` + // External ID of the node assigned by some machine database (e.g. a cloud provider) + ExternalID string `json:"externalID,omitempty" description:"deprecated. External ID assigned to the node by some machine database (e.g. a cloud provider). Defaults to node name when empty."` + // ID of the node assigned by the cloud provider + ProviderID string `json:"providerID,omitempty" description:"ID of the node assigned by the cloud provider in the format: ://"` + // Unschedulable controls node schedulability of new pods. By default node is schedulable. + Unschedulable bool `json:"unschedulable,omitempty" description:"disable pod scheduling on the node"` +} + +// NodeSystemInfo is a set of ids/uuids to uniquely identify the node. +type NodeSystemInfo struct { + // MachineID is the machine-id reported by the node + MachineID string `json:"machineID" description:"machine-id reported by the node"` + // SystemUUID is the system-uuid reported by the node + SystemUUID string `json:"systemUUID" description:"system-uuid reported by the node"` + // BootID is the boot-id reported by the node + BootID string `json:"bootID" description:"boot id is the boot-id reported by the node"` + // Kernel version reported by the node + KernelVersion string `json:"kernelVersion" description:"Kernel version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64)"` + // OS image used reported by the node + OsImage string `json:"osImage" description:"OS image used reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy))"` + // Container runtime version reported by the node + ContainerRuntimeVersion string `json:"containerRuntimeVersion" description:"Container runtime version reported by the node through runtime remote API (e.g. docker://1.5.0)"` + // Kubelet version reported by the node + KubeletVersion string `json:"kubeletVersion" description:"Kubelet version reported by the node"` + // Kube-proxy version reported by the node + KubeProxyVersion string `json:"kubeProxyVersion" description:"Kube-proxy version reported by the node"` +} + +// NodeStatus is information about the current status of a node. +type NodeStatus struct { + // Capacity represents the available resources of a node. + // see http://releases.k8s.io/v1.0.0/docs/resources.md for more details. + Capacity ResourceList `json:"capacity,omitempty" description:"compute resource capacity of the node; http://releases.k8s.io/v1.0.0/docs/resources.md"` + // NodePhase is the current lifecycle phase of the node. + Phase NodePhase `json:"phase,omitempty" description:"most recently observed lifecycle phase of the node"` + // Conditions is an array of current node conditions. + Conditions []NodeCondition `json:"conditions,omitempty" description:"list of node conditions observed" patchStrategy:"merge" patchMergeKey:"type"` + // Queried from cloud provider, if available. + Addresses []NodeAddress `json:"addresses,omitempty" description:"list of addresses reachable to the node" patchStrategy:"merge" patchMergeKey:"type"` + // NodeSystemInfo is a set of ids/uuids to uniquely identify the node + NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty" description:"set of ids/uuids to uniquely identify the node"` +} + +type NodePhase string + +// These are the valid phases of node. +const ( + // NodePending means the node has been created/added by the system, but not configured. + NodePending NodePhase = "Pending" + // NodeRunning means the node has been configured and has Kubernetes components running. + NodeRunning NodePhase = "Running" + // NodeTerminated means the node has been removed from the cluster. + NodeTerminated NodePhase = "Terminated" +) + +type NodeConditionType string + +// These are valid conditions of node. Currently, we don't have enough information to decide +// node condition. In the future, we will add more. The proposed set of conditions are: +// NodeReachable, NodeLive, NodeReady, NodeSchedulable, NodeRunnable. +const ( + // NodeReady means kubelet is healthy and ready to accept pods. + NodeReady NodeConditionType = "Ready" +) + +type NodeCondition struct { + Type NodeConditionType `json:"type" description:"type of node condition, currently only Ready"` + Status ConditionStatus `json:"status" description:"status of the condition, one of True, False, Unknown"` + LastHeartbeatTime unversioned.Time `json:"lastHeartbeatTime,omitempty" description:"last time we got an update on a given condition"` + LastTransitionTime unversioned.Time `json:"lastTransitionTime,omitempty" description:"last time the condition transit from one status to another"` + Reason string `json:"reason,omitempty" description:"(brief) reason for the condition's last transition"` + Message string `json:"message,omitempty" description:"human readable message indicating details about last transition"` +} + +type NodeAddressType string + +// These are valid address type of node. +const ( + NodeHostName NodeAddressType = "Hostname" + NodeExternalIP NodeAddressType = "ExternalIP" + NodeInternalIP NodeAddressType = "InternalIP" +) + +type NodeAddress struct { + Type NodeAddressType `json:"type" description:"node address type, one of Hostname, ExternalIP or InternalIP"` + Address string `json:"address" description:"the node address"` +} + +// ResourceName is the name identifying various resources in a ResourceList. +type ResourceName string + +const ( + // CPU, in cores. (500m = .5 cores) + ResourceCPU ResourceName = "cpu" + // Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) + ResourceMemory ResourceName = "memory" + // Volume size, in bytes (e,g. 5Gi = 5GiB = 5 * 1024 * 1024 * 1024) + ResourceStorage ResourceName = "storage" +) + +// ResourceList is a set of (resource name, quantity) pairs. +type ResourceList map[ResourceName]resource.Quantity + +// Node is a worker node in Kubernetes. +// The name of the node according to etcd is in ID. +type Node struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Spec defines the behavior of a node. + Spec NodeSpec `json:"spec,omitempty" description:"specification of a node; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` + + // Status describes the current status of a Node + Status NodeStatus `json:"status,omitempty" description:"most recently observed status of the node; populated by the system, read-only; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` +} + +// NodeList is a list of minions. +type NodeList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Items []Node `json:"items" description:"list of nodes"` +} + +type FinalizerName string + +// These are internal finalizer values to Kubernetes, must be qualified name unless defined here +const ( + FinalizerKubernetes FinalizerName = "kubernetes" +) + +// NamespaceSpec describes the attributes on a Namespace +type NamespaceSpec struct { + // Finalizers is an opaque list of values that must be empty to permanently remove object from storage + Finalizers []FinalizerName `json:"finalizers,omitempty" description:"an opaque list of values that must be empty to permanently remove object from storage"` +} + +// NamespaceStatus is information about the current status of a Namespace. +type NamespaceStatus struct { + // Phase is the current lifecycle phase of the namespace. + Phase NamespacePhase `json:"phase,omitempty" description:"phase is the current lifecycle phase of the namespace"` +} + +type NamespacePhase string + +// These are the valid phases of a namespace. +const ( + // NamespaceActive means the namespace is available for use in the system + NamespaceActive NamespacePhase = "Active" + // NamespaceTerminating means the namespace is undergoing graceful termination + NamespaceTerminating NamespacePhase = "Terminating" +) + +// A namespace provides a scope for Names. +// Use of multiple namespaces is optional +type Namespace struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Spec defines the behavior of the Namespace. + Spec NamespaceSpec `json:"spec,omitempty" description:"spec defines the behavior of the Namespace; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` + + // Status describes the current status of a Namespace + Status NamespaceStatus `json:"status,omitempty" description:"status describes the current status of a Namespace; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` +} + +// NamespaceList is a list of Namespaces. +type NamespaceList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Items is the list of Namespace objects in the list + Items []Namespace `json:"items" description:"items is the list of Namespace objects in the list"` +} + +// Binding ties one object to another - for example, a pod is bound to a node by a scheduler. +type Binding struct { + TypeMeta `json:",inline"` + // ObjectMeta describes the object that is being bound. + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Target is the object to bind to. + Target ObjectReference `json:"target" description:"an object to bind to"` +} + +// DeleteOptions may be provided when deleting an API object +type DeleteOptions struct { + TypeMeta `json:",inline"` + + // Optional duration in seconds before the object should be deleted. Value must be non-negative integer. + // The value zero indicates delete immediately. If this value is nil, the default grace period for the + // specified type will be used. + GracePeriodSeconds *int64 `json:"gracePeriodSeconds,omitempty" description:"the duration in seconds to wait before deleting this object; defaults to a per object value if not specified; zero means delete immediately"` +} + +// ListOptions is the query options to a standard REST list call +type ListOptions struct { + TypeMeta `json:",inline"` + + // A selector based on labels + LabelSelector string `json:"labelSelector,omitempty" description:"a selector to restrict the list of returned objects by their labels; defaults to everything"` + // A selector based on fields + FieldSelector string `json:"fieldSelector,omitempty" description:"a selector to restrict the list of returned objects by their fields; defaults to everything"` + // If true, watch for changes to the selected resources + Watch bool `json:"watch,omitempty" description:"watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion"` + // The desired resource version to watch + ResourceVersion string `json:"resourceVersion,omitempty" description:"when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history"` +} + +// PodLogOptions is the query options for a Pod's logs REST call +type PodLogOptions struct { + TypeMeta `json:",inline"` + + // Container for which to return logs + Container string `json:"container,omitempty" description:"the container for which to stream logs; defaults to only container if there is one container in the pod"` + + // If true, follow the logs for the pod + Follow bool `json:"follow,omitempty" description:"follow the log stream of the pod; defaults to false"` + + // If true, return previous terminated container logs + Previous bool `json:"previous,omitempty" description:"return previous terminated container logs; defaults to false"` +} + +// PodExecOptions is the query options to a Pod's remote exec call +type PodExecOptions struct { + TypeMeta `json:",inline"` + + // Stdin if true indicates that stdin is to be redirected for the exec call + Stdin bool `json:"stdin,omitempty" description:"redirect the standard input stream of the pod for this call; defaults to false"` + + // Stdout if true indicates that stdout is to be redirected for the exec call + Stdout bool `json:"stdout,omitempty" description:"redirect the standard output stream of the pod for this call; defaults to true"` + + // Stderr if true indicates that stderr is to be redirected for the exec call + Stderr bool `json:"stderr,omitempty" description:"redirect the standard error stream of the pod for this call; defaults to true"` + + // TTY if true indicates that a tty will be allocated for the exec call + TTY bool `json:"tty,omitempty" description:"allocate a terminal for this exec call; defaults to false"` + + // Container in which to execute the command. + Container string `json:"container,omitempty" description:"the container in which to execute the command. Defaults to only container if there is only one container in the pod."` + + // Command is the remote command to execute; argv array; not executed within a shell. + Command []string `json:"command" description:"the command to execute; argv array; not executed within a shell"` +} + +// PodProxyOptions is the query options to a Pod's proxy call +type PodProxyOptions struct { + TypeMeta `json:",inline"` + + // Path is the URL path to use for the current proxy request + Path string `json:"path,omitempty" description:"URL path to use in proxy request to pod"` +} + +// Status is a return value for calls that don't return other objects. +type Status struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // One of: "Success" or "Failure" + Status string `json:"status,omitempty" description:"status of the operation; either Success, or Failure"` + // A human-readable description of the status of this operation. + Message string `json:"message,omitempty" description:"human-readable description of the status of this operation"` + // A machine-readable description of why this operation is in the + // "Failure" status. If this value is empty there + // is no information available. A Reason clarifies an HTTP status + // code but does not override it. + Reason StatusReason `json:"reason,omitempty" description:"machine-readable description of why this operation is in the 'Failure' status; if this value is empty there is no information available; a reason clarifies an HTTP status code but does not override it"` + // Extended data associated with the reason. Each reason may define its + // own extended details. This field is optional and the data returned + // is not guaranteed to conform to any schema except that defined by + // the reason type. + Details *StatusDetails `json:"details,omitempty" description:"extended data associated with the reason; each reason may define its own extended details; this field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type"` + // Suggested HTTP return code for this status, 0 if not set. + Code int `json:"code,omitempty" description:"suggested HTTP return code for this status; 0 if not set"` +} + +// StatusDetails is a set of additional properties that MAY be set by the +// server to provide additional information about a response. The Reason +// field of a Status object defines what attributes will be set. Clients +// must ignore fields that do not match the defined type of each attribute, +// and should assume that any attribute may be empty, invalid, or under +// defined. +type StatusDetails struct { + // The ID attribute of the resource associated with the status StatusReason + // (when there is a single ID which can be described). + ID string `json:"id,omitempty" description:"the ID attribute of the resource associated with the status StatusReason (when there is a single ID which can be described)"` + // The kind attribute of the resource associated with the status StatusReason. + // On some operations may differ from the requested resource Kind. + Kind string `json:"kind,omitempty" description:"the kind attribute of the resource associated with the status StatusReason; on some operations may differ from the requested resource Kind"` + // The Causes array includes more details associated with the StatusReason + // failure. Not all StatusReasons may provide detailed causes. + Causes []StatusCause `json:"causes,omitempty" description:"the Causes array includes more details associated with the StatusReason failure; not all StatusReasons may provide detailed causes"` + // If specified, the time in seconds before the operation should be retried. + RetryAfterSeconds int `json:"retryAfterSeconds,omitempty" description:"the number of seconds before the client should attempt to retry this operation"` +} + +// Values of Status.Status +const ( + StatusSuccess = "Success" + StatusFailure = "Failure" +) + +// StatusReason is an enumeration of possible failure causes. Each StatusReason +// must map to a single HTTP status code, but multiple reasons may map +// to the same HTTP status code. +// TODO: move to apiserver +type StatusReason string + +const ( + // StatusReasonUnknown means the server has declined to indicate a specific reason. + // The details field may contain other information about this error. + // Status code 500. + StatusReasonUnknown StatusReason = "" + + // StatusReasonNotFound means one or more resources required for this operation + // could not be found. + // Details (optional): + // "kind" string - the kind attribute of the missing resource + // on some operations may differ from the requested + // resource. + // "id" string - the identifier of the missing resource + // Status code 404 + StatusReasonNotFound StatusReason = "NotFound" + + // StatusReasonAlreadyExists means the resource you are creating already exists. + // Details (optional): + // "kind" string - the kind attribute of the conflicting resource + // "id" string - the identifier of the conflicting resource + // Status code 409 + StatusReasonAlreadyExists StatusReason = "AlreadyExists" + + // StatusReasonConflict means the requested update operation cannot be completed + // due to a conflict in the operation. The client may need to alter the request. + // Each resource may define custom details that indicate the nature of the + // conflict. + // Status code 409 + StatusReasonConflict StatusReason = "Conflict" + + // StatusReasonInvalid means the requested create or update operation cannot be + // completed due to invalid data provided as part of the request. The client may + // need to alter the request. When set, the client may use the StatusDetails + // message field as a summary of the issues encountered. + // Details (optional): + // "kind" string - the kind attribute of the invalid resource + // "id" string - the identifier of the invalid resource + // "causes" - one or more StatusCause entries indicating the data in the + // provided resource that was invalid. The code, message, and + // field attributes will be set. + // Status code 422 + StatusReasonInvalid StatusReason = "Invalid" + + // StatusReasonServerTimeout means the server can be reached and understood the request, + // but cannot complete the action in a reasonable time. The client should retry the request. + // This is may be due to temporary server load or a transient communication issue with + // another server. Status code 500 is used because the HTTP spec provides no suitable + // server-requested client retry and the 5xx class represents actionable errors. + // Details (optional): + // "kind" string - the kind attribute of the resource being acted on. + // "id" string - the operation that is being attempted. + // Status code 500 + StatusReasonServerTimeout StatusReason = "ServerTimeout" +) + +// StatusCause provides more information about an api.Status failure, including +// cases when multiple errors are encountered. +type StatusCause struct { + // A machine-readable description of the cause of the error. If this value is + // empty there is no information available. + Type CauseType `json:"reason,omitempty" description:"machine-readable description of the cause of the error; if this value is empty there is no information available"` + // A human-readable description of the cause of the error. This field may be + // presented as-is to a reader. + Message string `json:"message,omitempty" description:"human-readable description of the cause of the error; this field may be presented as-is to a reader"` + // The field of the resource that has caused this error, as named by its JSON + // serialization. May include dot and postfix notation for nested attributes. + // Arrays are zero-indexed. Fields may appear more than once in an array of + // causes due to fields having multiple errors. + // Optional. + // + // Examples: + // "name" - the field "name" on the current resource + // "items[0].name" - the field "name" on the first array entry in "items" + Field string `json:"field,omitempty" description:"field of the resource that has caused this error, as named by its JSON serialization; may include dot and postfix notation for nested attributes; arrays are zero-indexed; fields may appear more than once in an array of causes due to fields having multiple errors"` +} + +// CauseType is a machine readable value providing more detail about what +// occured in a status response. An operation may have multiple causes for a +// status (whether Failure or Success). +type CauseType string + +const ( + // CauseTypeFieldValueNotFound is used to report failure to find a requested value + // (e.g. looking up an ID). + CauseTypeFieldValueNotFound CauseType = "FieldValueNotFound" + // CauseTypeFieldValueRequired is used to report required values that are not + // provided (e.g. empty strings, null values, or empty arrays). + CauseTypeFieldValueRequired CauseType = "FieldValueRequired" + // CauseTypeFieldValueDuplicate is used to report collisions of values that must be + // unique (e.g. unique IDs). + CauseTypeFieldValueDuplicate CauseType = "FieldValueDuplicate" + // CauseTypeFieldValueInvalid is used to report malformed values (e.g. failed regex + // match). + CauseTypeFieldValueInvalid CauseType = "FieldValueInvalid" + // CauseTypeFieldValueNotSupported is used to report valid (as per formatting rules) + // values that can not be handled (e.g. an enumerated string). + CauseTypeFieldValueNotSupported CauseType = "FieldValueNotSupported" +) + +// ObjectReference contains enough information to let you inspect or modify the referred object. +type ObjectReference struct { + Kind string `json:"kind,omitempty" description:"kind of the referent"` + Namespace string `json:"namespace,omitempty" description:"namespace of the referent"` + Name string `json:"name,omitempty" description:"name of the referent"` + UID types.UID `json:"uid,omitempty" description:"uid of the referent"` + APIVersion string `json:"apiVersion,omitempty" description:"API version of the referent"` + ResourceVersion string `json:"resourceVersion,omitempty" description:"specific resourceVersion to which this reference is made, if any: http://releases.k8s.io/v1.0.0/docs/api-conventions.md#concurrency-control-and-consistency"` + + // Optional. If referring to a piece of an object instead of an entire object, this string + // should contain information to identify the sub-object. For example, if the object + // reference is to a container within a pod, this would take on a value like: + // "spec.containers{name}" (where "name" refers to the name of the container that triggered + // the event) or if no container name is specified "spec.containers[2]" (container with + // index 2 in this pod). This syntax is chosen only to have some well-defined way of + // referencing a part of an object. + // TODO: this design is not final and this field is subject to change in the future. + FieldPath string `json:"fieldPath,omitempty" description:"if referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]"` +} + +// LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. +type LocalObjectReference struct { + //TODO: Add other useful fields. apiVersion, kind, uid? + Name string `json:"name,omitempty" description:"name of the referent"` +} + +type SerializedReference struct { + TypeMeta `json:",inline"` + Reference ObjectReference `json:"reference,omitempty" description:"the reference to an object in the system"` +} + +type EventSource struct { + // Component from which the event is generated. + Component string `json:"component,omitempty" description:"component that generated the event"` + // Host name on which the event is generated. + Host string `json:"host,omitempty" description:"name of the host where the event is generated"` +} + +// Event is a report of an event somewhere in the cluster. +// TODO: Decide whether to store these separately or with the object they apply to. +type Event struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Required. The object that this event is about. + InvolvedObject ObjectReference `json:"involvedObject" description:"object this event is about"` + + // Optional; this should be a short, machine understandable string that gives the reason + // for this event being generated. + // TODO: provide exact specification for format. + Reason string `json:"reason,omitempty" description:"short, machine understandable string that gives the reason for the transition into the object's current status"` + + // Optional. A human-readable description of the status of this operation. + // TODO: decide on maximum length. + Message string `json:"message,omitempty" description:"human-readable description of the status of this operation"` + + // Optional. The component reporting this event. Should be a short machine understandable string. + Source EventSource `json:"source,omitempty" description:"component reporting this event"` + + // The time at which the event was first recorded. (Time of server receipt is in TypeMeta.) + FirstTimestamp unversioned.Time `json:"firstTimestamp,omitempty" description:"the time at which the event was first recorded"` + + // The time at which the most recent occurance of this event was recorded. + LastTimestamp unversioned.Time `json:"lastTimestamp,omitempty" description:"the time at which the most recent occurance of this event was recorded"` + + // The number of times this event has occurred. + Count int `json:"count,omitempty" description:"the number of times this event has occurred"` +} + +// EventList is a list of events. +type EventList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Items []Event `json:"items" description:"list of events"` +} + +// List holds a list of objects, which may not be known by the server. +type List struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Items []runtime.RawExtension `json:"items" description:"list of objects"` +} + +// A type of object that is limited +type LimitType string + +const ( + // Limit that applies to all pods in a namespace + LimitTypePod LimitType = "Pod" + // Limit that applies to all containers in a namespace + LimitTypeContainer LimitType = "Container" +) + +// LimitRangeItem defines a min/max usage limit for any resource that matches on kind +type LimitRangeItem struct { + // Type of resource that this limit applies to + Type LimitType `json:"type,omitempty" description:"type of resource that this limit applies to"` + // Max usage constraints on this kind by resource name + Max ResourceList `json:"max,omitempty" description:"max usage constraints on this kind by resource name"` + // Min usage constraints on this kind by resource name + Min ResourceList `json:"min,omitempty" description:"min usage constraints on this kind by resource name"` + // Default usage constraints on this kind by resource name + Default ResourceList `json:"default,omitempty" description:"default values on this kind by resource name if omitted"` + // DefaultRequest is the default resource requirement request value by resource name if resource request is omitted. + DefaultRequest ResourceList `json:"defaultRequest,omitempty"` + // MaxLimitRequestRatio if specified, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value; this represents the max burst for the named resource. + MaxLimitRequestRatio ResourceList `json:"maxLimitRequestRatio,omitempty"` +} + +// LimitRangeSpec defines a min/max usage limit for resources that match on kind +type LimitRangeSpec struct { + // Limits is the list of LimitRangeItem objects that are enforced + Limits []LimitRangeItem `json:"limits" description:"limits is the list of LimitRangeItem objects that are enforced"` +} + +// LimitRange sets resource usage limits for each kind of resource in a Namespace +type LimitRange struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Spec defines the limits enforced + Spec LimitRangeSpec `json:"spec,omitempty" description:"spec defines the limits enforced; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` +} + +// LimitRangeList is a list of LimitRange items. +type LimitRangeList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Items is a list of LimitRange objects + Items []LimitRange `json:"items" description:"items is a list of LimitRange objects"` +} + +// The following identify resource constants for Kubernetes object types +const ( + // Pods, number + ResourcePods ResourceName = "pods" + // Services, number + ResourceServices ResourceName = "services" + // ReplicationControllers, number + ResourceReplicationControllers ResourceName = "replicationcontrollers" + // ResourceQuotas, number + ResourceQuotas ResourceName = "resourcequotas" + // ResourceSecrets, number + ResourceSecrets ResourceName = "secrets" + // ResourcePersistentVolumeClaims, number + ResourcePersistentVolumeClaims ResourceName = "persistentvolumeclaims" +) + +// ResourceQuotaSpec defines the desired hard limits to enforce for Quota +type ResourceQuotaSpec struct { + // Hard is the set of desired hard limits for each named resource + Hard ResourceList `json:"hard,omitempty" description:"hard is the set of desired hard limits for each named resource"` +} + +// ResourceQuotaStatus defines the enforced hard limits and observed use +type ResourceQuotaStatus struct { + // Hard is the set of enforced hard limits for each named resource + Hard ResourceList `json:"hard,omitempty" description:"hard is the set of enforced hard limits for each named resource"` + // Used is the current observed total usage of the resource in the namespace + Used ResourceList `json:"used,omitempty" description:"used is the current observed total usage of the resource in the namespace"` +} + +// ResourceQuota sets aggregate quota restrictions enforced per namespace +type ResourceQuota struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Spec defines the desired quota + Spec ResourceQuotaSpec `json:"spec,omitempty" description:"spec defines the desired quota; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` + + // Status defines the actual enforced quota and its current usage + Status ResourceQuotaStatus `json:"status,omitempty" description:"status defines the actual enforced quota and current usage; http://releases.k8s.io/v1.0.0/docs/api-conventions.md#spec-and-status"` +} + +// ResourceQuotaList is a list of ResourceQuota items +type ResourceQuotaList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Items is a list of ResourceQuota objects + Items []ResourceQuota `json:"items" description:"items is a list of ResourceQuota objects"` +} + +// Secret holds secret data of a certain type. The total bytes of the values in +// the Data field must be less than MaxSecretSize bytes. +type Secret struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + // Data contains the secret data. Each key must be a valid DNS_SUBDOMAIN + // or leading dot followed by valid DNS_SUBDOMAIN. + // The serialized form of the secret data is a base64 encoded string, + // representing the arbitrary (possibly non-string) data value here. + Data map[string][]byte `json:"data,omitempty" description:"data contains the secret data. Each key must be a valid DNS_SUBDOMAIN or leading dot followed by valid DNS_SUBDOMAIN. Each value must be a base64 encoded string as described in https://tools.ietf.org/html/rfc4648#section-4"` + + // Used to facilitate programmatic handling of secret data. + Type SecretType `json:"type,omitempty" description:"type facilitates programmatic handling of secret data"` +} + +const MaxSecretSize = 1 * 1024 * 1024 + +type SecretType string + +const ( + // SecretTypeOpaque is the default; arbitrary user-defined data + SecretTypeOpaque SecretType = "Opaque" + + // SecretTypeServiceAccountToken contains a token that identifies a service account to the API + // + // Required fields: + // - Secret.Annotations["kubernetes.io/service-account.name"] - the name of the ServiceAccount the token identifies + // - Secret.Annotations["kubernetes.io/service-account.uid"] - the UID of the ServiceAccount the token identifies + // - Secret.Data["token"] - a token that identifies the service account to the API + SecretTypeServiceAccountToken SecretType = "kubernetes.io/service-account-token" + + // ServiceAccountNameKey is the key of the required annotation for SecretTypeServiceAccountToken secrets + ServiceAccountNameKey = "kubernetes.io/service-account.name" + // ServiceAccountUIDKey is the key of the required annotation for SecretTypeServiceAccountToken secrets + ServiceAccountUIDKey = "kubernetes.io/service-account.uid" + // ServiceAccountTokenKey is the key of the required data for SecretTypeServiceAccountToken secrets + ServiceAccountTokenKey = "token" + // ServiceAccountKubeconfigKey is the key of the optional kubeconfig data for SecretTypeServiceAccountToken secrets + ServiceAccountKubeconfigKey = "kubernetes.kubeconfig" + // ServiceAccountRootCAKey is the key of the optional root certificate authority for SecretTypeServiceAccountToken secrets + ServiceAccountRootCAKey = "ca.crt" + + // SecretTypeDockercfg contains a dockercfg file that follows the same format rules as ~/.dockercfg + // + // Required fields: + // - Secret.Data[".dockercfg"] - a serialized ~/.dockercfg file + SecretTypeDockercfg SecretType = "kubernetes.io/dockercfg" + + // DockerConfigKey is the key of the required data for SecretTypeDockercfg secrets + DockerConfigKey = ".dockercfg" +) + +type SecretList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Items []Secret `json:"items" description:"items is a list of secret objects"` +} + +// Type and constants for component health validation. +type ComponentConditionType string + +// These are the valid conditions for the component. +const ( + ComponentHealthy ComponentConditionType = "Healthy" +) + +type ComponentCondition struct { + Type ComponentConditionType `json:"type" description:"type of component condition, currently only Healthy"` + Status ConditionStatus `json:"status" description:"current status of this component condition, one of True, False, Unknown"` + Message string `json:"message,omitempty" description:"health check message received from the component"` + Error string `json:"error,omitempty" description:"error code from health check attempt (if any)"` +} + +// ComponentStatus (and ComponentStatusList) holds the cluster validation info. +type ComponentStatus struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Conditions []ComponentCondition `json:"conditions,omitempty" description:"list of component conditions observed" patchStrategy:"merge" patchMergeKey:"type"` +} + +type ComponentStatusList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Items []ComponentStatus `json:"items" description:"list of component status objects"` +} + +// SecurityContext holds security configuration that will be applied to a container. SecurityContext +// contains duplication of some existing fields from the Container resource. These duplicate fields +// will be populated based on the Container configuration if they are not set. Defining them on +// both the Container AND the SecurityContext will result in an error. +type SecurityContext struct { + // Capabilities are the capabilities to add/drop when running the container + // Must match Container.Capabilities or be unset. Will be defaulted to Container.Capabilities if left unset + Capabilities *Capabilities `json:"capabilities,omitempty" description:"the linux capabilites that should be added or removed"` + + // Run the container in privileged mode + // Must match Container.Privileged or be unset. Will be defaulted to Container.Privileged if left unset + Privileged *bool `json:"privileged,omitempty" description:"run the container in privileged mode"` + + // SELinuxOptions are the labels to be applied to the container + // and volumes + SELinuxOptions *SELinuxOptions `json:"seLinuxOptions,omitempty" description:"options that control the SELinux labels applied"` + + // RunAsUser is the UID to run the entrypoint of the container process. + RunAsUser *int64 `json:"runAsUser,omitempty" description:"the user id that runs the first process in the container"` + + // RunAsNonRoot indicates that the container should be run as a non-root user. If the RunAsUser + // field is not explicitly set then the kubelet may check the image for a specified user or + // perform defaulting to specify a user. + RunAsNonRoot bool `json:"runAsNonRoot,omitempty" description:"indicates the container be must run as a non-root user either by specifying the runAsUser or in the image specification"` +} + +// SELinuxOptions are the labels to be applied to the container. +type SELinuxOptions struct { + // SELinux user label + User string `json:"user,omitempty" description:"the user label to apply to the container"` + + // SELinux role label + Role string `json:"role,omitempty" description:"the role label to apply to the container"` + + // SELinux type label + Type string `json:"type,omitempty" description:"the type label to apply to the container"` + + // SELinux level label. + Level string `json:"level,omitempty" description:"the level label to apply to the container"` +} + +// RangeAllocation is not a public type +type RangeAllocation struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/v1.0.0/docs/api-conventions.md#metadata"` + + Range string `json:"range" description:"a range string that identifies the range represented by 'data'; required"` + Data []byte `json:"data" description:"a bit array containing all allocated addresses in the previous segment"` +} + +// SecurityContextConstraints governs the ability to make requests that affect the SecurityContext +// that will be applied to a container. +type SecurityContextConstraints struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` + + // AllowPrivilegedContainer determines if a container can request to be run as privileged. + AllowPrivilegedContainer bool `json:"allowPrivilegedContainer" description:"allow containers to run as privileged"` + // AllowedCapabilities is a list of capabilities that can be requested to add to the container. + AllowedCapabilities []Capability `json:"allowedCapabilities" description:"capabilities that are allowed to be added"` + // AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin + AllowHostDirVolumePlugin bool `json:"allowHostDirVolumePlugin" description:"allow the use of the host dir volume plugin"` + // AllowHostNetwork determines if the policy allows the use of HostNetwork in the pod spec. + AllowHostNetwork bool `json:"allowHostNetwork" description:"allow the use of the hostNetwork in the pod spec"` + // AllowHostPorts determines if the policy allows host ports in the containers. + AllowHostPorts bool `json:"allowHostPorts" description:"allow the use of the host ports in the containers"` + // AllowHostPID determines if the policy allows host pid in the containers. + AllowHostPID bool `json:"allowHostPID" description:"allow the use of the host pid in the containers"` + // AllowHostIPC determines if the policy allows host ipc in the containers. + AllowHostIPC bool `json:"allowHostIPC" description:"allow the use of the host ipc in the containers"` + // SELinuxContext is the strategy that will dictate what labels will be set in the SecurityContext. + SELinuxContext SELinuxContextStrategyOptions `json:"seLinuxContext,omitempty" description:"strategy used to generate SELinuxOptions"` + // RunAsUser is the strategy that will dictate what RunAsUser is used in the SecurityContext. + RunAsUser RunAsUserStrategyOptions `json:"runAsUser,omitempty" description:"strategy used to generate RunAsUser"` + // SupplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. + SupplementalGroups SupplementalGroupsStrategyOptions `json:"supplementalGroups,omitempty" description:"strategy used to generate supplemental groups"` + // FSGroup is the strategy that will dictate what fs group is used by the SecurityContext. + FSGroup FSGroupStrategyOptions `json:"fsGroup,omitempty" description:"strategy used to generate fsGroup"` + + // The users who have permissions to use this security context constraints + Users []string `json:"users,omitempty" description:"users allowed to use this SecurityContextConstraints"` + // The groups that have permission to use this security context constraints + Groups []string `json:"groups,omitempty" description:"groups allowed to use this SecurityContextConstraints"` +} + +// SELinuxContextStrategyOptions defines the strategy type and any options used to create the strategy. +type SELinuxContextStrategyOptions struct { + // Type is the strategy that will dictate what SELinux context is used in the SecurityContext. + Type SELinuxContextStrategyType `json:"type,omitempty" description:"strategy used to generate the SELinux context"` + // seLinuxOptions required to run as; required for MustRunAs + SELinuxOptions *SELinuxOptions `json:"seLinuxOptions,omitempty" description:"seLinuxOptions required to run as; required for MustRunAs"` +} + +// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. +type RunAsUserStrategyOptions struct { + // Type is the strategy that will dictate what RunAsUser is used in the SecurityContext. + Type RunAsUserStrategyType `json:"type,omitempty" description:"strategy used to generate RunAsUser"` + // UID is the user id that containers must run as. Required for the MustRunAs strategy if not using + // namespace/service account allocated uids. + UID *int64 `json:"uid,omitempty" description:"the uid to always run as; required for MustRunAs"` + // UIDRangeMin defines the min value for a strategy that allocates by range. + UIDRangeMin *int64 `json:"uidRangeMin,omitempty" description:"min value for range based allocators"` + // UIDRangeMax defines the max value for a strategy that allocates by range. + UIDRangeMax *int64 `json:"uidRangeMax,omitempty" description:"max value for range based allocators"` +} + +// FSGroupStrategyOptions defines the strategy type and options used to create the strategy. +type FSGroupStrategyOptions struct { + // Type is the strategy that will dictate what FSGroup is used in the SecurityContext. + Type FSGroupStrategyType `json:"type,omitempty" description:"strategy used to generate fsGroup"` + // Ranges are the allowed ranges of fs groups. If you would like to force a single + // fs group then supply a single range with the same start and end. + Ranges []IDRange `json:"ranges,omitempty" description:"ranges of allowable IDs for fsGroup"` +} + +// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. +type SupplementalGroupsStrategyOptions struct { + // Type is the strategy that will dictate what supplemental groups is used in the SecurityContext. + Type SupplementalGroupsStrategyType `json:"type,omitempty" description:"strategy used to generate supplemental groups"` + // Ranges are the allowed ranges of supplemental groups. If you would like to force a single + // supplemental group then supply a single range with the same start and end. + Ranges []IDRange `json:"ranges,omitempty" description:"ranges of allowable IDs for supplemental groups"` +} + +// IDRange provides a min/max of an allowed range of IDs. +// TODO: this could be reused for UIDs. +type IDRange struct { + // Min is the start of the range, inclusive. + Min int64 `json:"min,omitempty" description:"min value for the range"` + // Max is the end of the range, inclusive. + Max int64 `json:"max,omitempty" description:"min value for the range"` +} + +// SELinuxContextStrategyType denotes strategy types for generating SELinux options for a +// SecurityContext +type SELinuxContextStrategyType string + +// RunAsUserStrategyType denotes strategy types for generating RunAsUser values for a +// SecurityContext +type RunAsUserStrategyType string + +// SupplementalGroupsStrategyType denotes strategy types for determining valid supplemental +// groups for a SecurityContext. +type SupplementalGroupsStrategyType string + +// FSGroupStrategyType denotes strategy types for generating FSGroup values for a +// SecurityContext +type FSGroupStrategyType string + +const ( + // container must have SELinux labels of X applied. + SELinuxStrategyMustRunAs SELinuxContextStrategyType = "MustRunAs" + // container may make requests for any SELinux context labels. + SELinuxStrategyRunAsAny SELinuxContextStrategyType = "RunAsAny" + + // container must run as a particular uid. + RunAsUserStrategyMustRunAs RunAsUserStrategyType = "MustRunAs" + // container must run as a particular uid. + RunAsUserStrategyMustRunAsRange RunAsUserStrategyType = "MustRunAsRange" + // container must run as a non-root uid + RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategyType = "MustRunAsNonRoot" + // container may make requests for any uid. + RunAsUserStrategyRunAsAny RunAsUserStrategyType = "RunAsAny" + + // container must have FSGroup of X applied. + FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs" + // container may make requests for any FSGroup labels. + FSGroupStrategyRunAsAny FSGroupStrategyType = "RunAsAny" + + // container must run as a particular gid. + SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs" + // container may make requests for any gid. + SupplementalGroupsrStrategyRunAsAny SupplementalGroupsStrategyType = "RunAsAny" +) + +// SecurityContextConstraintsList is a list of SecurityContextConstraints objects +type SecurityContextConstraintsList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty"` + + Items []SecurityContextConstraints `json:"items"` +} + +// MetadataVolumeSource represents a volume containing metadata about a pod. +// NOTE: Deprecated in favor of DownwardAPIVolumeSource +type MetadataVolumeSource struct { + // Items is a list of metadata file name + Items []MetadataFile `json:"items,omitempty" description:"list of metadata files"` +} + +// MetadataFile expresses information about a file holding pod metadata. +// NOTE: Deprecated in favor of DownwardAPIVolumeFile +type MetadataFile struct { + // Required: Name is the name of the file + Name string `json:"name" description:"the name of the file to be created"` + // Required: Selects a field of the pod: only annotations, labels, name and namespace are supported. + FieldRef ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod. Supported fields: metadata.annotations, metadata.labels, metadata.name, metadata.namespace"` +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go index 04c71854d634..64859ea220f3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go @@ -320,6 +320,40 @@ func (v versionToResourceToFieldMapping) filterField(apiVersion, resourceType, f } var fieldMappings = versionToResourceToFieldMapping{ + "v1beta3": resourceTypeToFieldMapping{ + "nodes": clientFieldNameToAPIVersionFieldName{ + ObjectNameField: "metadata.name", + NodeUnschedulable: "spec.unschedulable", + }, + "minions": clientFieldNameToAPIVersionFieldName{ + ObjectNameField: "metadata.name", + NodeUnschedulable: "spec.unschedulable", + }, + "pods": clientFieldNameToAPIVersionFieldName{ + PodHost: "spec.host", + }, + "secrets": clientFieldNameToAPIVersionFieldName{ + SecretType: "type", + }, + "serviceAccounts": clientFieldNameToAPIVersionFieldName{ + ObjectNameField: "metadata.name", + }, + "endpoints": clientFieldNameToAPIVersionFieldName{ + ObjectNameField: "metadata.name", + }, + "events": clientFieldNameToAPIVersionFieldName{ + ObjectNameField: "metadata.name", + EventReason: "reason", + EventSource: "source", + EventInvolvedKind: "involvedObject.kind", + EventInvolvedNamespace: "involvedObject.namespace", + EventInvolvedName: "involvedObject.name", + EventInvolvedUID: "involvedObject.uid", + EventInvolvedAPIVersion: "involvedObject.apiVersion", + EventInvolvedResourceVersion: "involvedObject.resourceVersion", + EventInvolvedFieldPath: "involvedObject.fieldPath", + }, + }, "v1": resourceTypeToFieldMapping{ "nodes": clientFieldNameToAPIVersionFieldName{ ObjectNameField: "metadata.name", diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate.go index 3192d27e20e8..a372d87c11b3 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate.go @@ -30,6 +30,7 @@ import ( "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/api/v1beta3" "k8s.io/kubernetes/pkg/kubectl" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" @@ -374,6 +375,10 @@ func isReplicasDefaulted(info *resource.Info) bool { return false } switch info.Mapping.APIVersion { + case "v1beta3": + if rc, ok := info.VersionedObject.(*v1beta3.ReplicationController); ok { + return rc.Spec.Replicas == nil + } case "v1": if rc, ok := info.VersionedObject.(*v1.ReplicationController); ok { return rc.Spec.Replicas == nil From 7423c7582a0e54db4259244498a7a2bb389b8403 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Tue, 11 Aug 2015 13:26:16 -0400 Subject: [PATCH 17/35] UPSTREAM: : Suppress aggressive output of warning Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go --- .../src/k8s.io/kubernetes/pkg/client/unversioned/request.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go index 64859ea220f3..40c25d18e372 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/unversioned/request.go @@ -307,13 +307,11 @@ type versionToResourceToFieldMapping map[string]resourceTypeToFieldMapping func (v versionToResourceToFieldMapping) filterField(apiVersion, resourceType, field, value string) (newField, newValue string, err error) { rMapping, ok := v[apiVersion] if !ok { - glog.Warningf("Field selector: %v - %v - %v - %v: need to check if this is versioned correctly.", apiVersion, resourceType, field, value) return field, value, nil } newField, newValue, err = rMapping.filterField(resourceType, field, value) if err != nil { // This is only a warning until we find and fix all of the client's usages. - glog.Warningf("Field selector: %v - %v - %v - %v: need to check if this is versioned correctly.", apiVersion, resourceType, field, value) return field, value, nil } return newField, newValue, nil From cdbc5e5f62bc5fb8abdc6beebcc422196b86f880 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Tue, 11 Aug 2015 13:30:26 -0400 Subject: [PATCH 18/35] UPSTREAM: : Hack date-time format on *util.Time Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go --- .../src/k8s.io/kubernetes/pkg/apiserver/api_installer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go index 848eb394ae2e..eddc205302f0 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/apiserver/api_installer.go @@ -835,7 +835,7 @@ func typeToJSON(typeName string) string { return "integer" case "float64", "float32": return "number" - case "unversioned.Time": + case "unversioned.Time", "*unversioned.Time": return "string" case "byte": return "string" From 82905bb321bb56fb139bb324d08f62845a50945c Mon Sep 17 00:00:00 2001 From: deads2k Date: Tue, 11 Aug 2015 15:20:21 -0400 Subject: [PATCH 19/35] UPSTREAM: : add back flag types to reduce noise during this rebase --- .../src/k8s.io/kubernetes/pkg/util/list.go | 39 ++++++++++++ .../src/k8s.io/kubernetes/pkg/util/net.go | 63 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/list.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/net.go diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/list.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/list.go new file mode 100644 index 000000000000..018d24b9b524 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/list.go @@ -0,0 +1,39 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "fmt" + "strings" +) + +type StringList []string + +func (sl *StringList) String() string { + return fmt.Sprint(*sl) +} + +func (sl *StringList) Set(value string) error { + for _, s := range strings.Split(value, ",") { + *sl = append(*sl, s) + } + return nil +} + +func (*StringList) Type() string { + return "stringList" +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/net.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/net.go new file mode 100644 index 000000000000..1b5f3855e11f --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/net.go @@ -0,0 +1,63 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "fmt" + "net" + "strings" +) + +// IP adapts net.IP for use as a flag. +type IP net.IP + +func (ip IP) String() string { + return net.IP(ip).String() +} + +func (ip *IP) Set(value string) error { + *ip = IP(net.ParseIP(strings.TrimSpace(value))) + if *ip == nil { + return fmt.Errorf("invalid IP address: '%s'", value) + } + return nil +} + +func (*IP) Type() string { + return "ip" +} + +// IPNet adapts net.IPNet for use as a flag. +type IPNet net.IPNet + +func (ipnet IPNet) String() string { + n := net.IPNet(ipnet) + return n.String() +} + +func (ipnet *IPNet) Set(value string) error { + _, n, err := net.ParseCIDR(strings.TrimSpace(value)) + if err != nil { + return err + } + *ipnet = IPNet(*n) + return nil +} + +func (*IPNet) Type() string { + return "ipNet" +} From f52a2243e674157f99aea30875abb8935b3d3394 Mon Sep 17 00:00:00 2001 From: deads2k Date: Mon, 19 Oct 2015 11:06:42 -0400 Subject: [PATCH 20/35] UPSTREAM: : make test pass with old codec --- .../src/k8s.io/kubernetes/pkg/kubectl/cmd/get_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get_test.go index e5f07480da11..e673b54df33f 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/get_test.go @@ -166,7 +166,8 @@ func TestGetUnknownSchemaObjectListGeneric(t *testing.T) { outputVersion: "unlikelyversion", listVersion: testapi.Default.Version(), testtypeVersion: "unlikelyversion", - rcVersion: testapi.Default.Version(), // see expected behavior 3b + // TODO figure out which part of the test harness is broken. + rcVersion: "v1beta3", // see expected behavior 3b }, "handles common version": { outputVersion: testapi.Default.Version(), From 965ecea6024953ea0107e8d85f088149ee64a4f4 Mon Sep 17 00:00:00 2001 From: deads2k Date: Fri, 16 Oct 2015 11:38:58 -0400 Subject: [PATCH 21/35] UPSTREAM: : tweak generator to handle conversions in other packages --- .../kubernetes/pkg/runtime/conversion_generator.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/conversion_generator.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/conversion_generator.go index 9bfab5ddc76e..aa01149e5de5 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/conversion_generator.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/conversion_generator.go @@ -579,7 +579,7 @@ func (g *conversionGenerator) writeConversionForSlice(b *buffer, inField, outFie } if !assigned { assignStmt := "" - if g.existsDedicatedConversionFunction(inField.Type.Elem(), outField.Type.Elem()) { + if g.existsDedicatedConversionFunction(inField.Type.Elem(), outField.Type.Elem()) && !g.isCustomRegisteredConversionFunction(inField.Type.Elem(), outField.Type.Elem()) { assignFormat := "if err := %s(&in.%s[i], &out.%s[i], s); err != nil {\n" funcName := g.conversionFunctionName(inField.Type.Elem(), outField.Type.Elem()) assignStmt = fmt.Sprintf(assignFormat, funcName, inField.Name, outField.Name) @@ -639,7 +639,7 @@ func (g *conversionGenerator) writeConversionForPtr(b *buffer, inField, outField ifStmt := fmt.Sprintf(ifFormat, inField.Name) b.addLine(ifStmt, indent) assignStmt := "" - if g.existsDedicatedConversionFunction(inField.Type.Elem(), outField.Type.Elem()) { + if g.existsDedicatedConversionFunction(inField.Type.Elem(), outField.Type.Elem()) && !g.isCustomRegisteredConversionFunction(inField.Type.Elem(), outField.Type.Elem()) { newFormat := "out.%s = new(%s)\n" newStmt := fmt.Sprintf(newFormat, outField.Name, g.typeName(outField.Type.Elem())) b.addLine(newStmt, indent+1) @@ -745,7 +745,7 @@ func (g *conversionGenerator) writeConversionForStruct(b *buffer, inType, outTyp } assignStmt := "" - if g.existsDedicatedConversionFunction(inField.Type, outField.Type) { + if g.existsDedicatedConversionFunction(inField.Type, outField.Type) && !g.isCustomRegisteredConversionFunction(inField.Type, outField.Type) { assignFormat := "if err := %s(&in.%s, &out.%s, s); err != nil {\n" funcName := g.conversionFunctionName(inField.Type, outField.Type) assignStmt = fmt.Sprintf(assignFormat, funcName, inField.Name, outField.Name) @@ -841,6 +841,10 @@ func (g *conversionGenerator) existsDedicatedConversionFunction(inType, outType return g.scheme.Converter().HasConversionFunc(inType, outType) } +func (g *conversionGenerator) isCustomRegisteredConversionFunction(inType, outType reflect.Type) bool { + return g.scheme.Converter().HasConversionFunc(inType, outType) +} + func (g *conversionGenerator) OverwritePackage(pkg, overwrite string) { g.pkgOverwrites[pkg] = overwrite } From 904886f946b31dad5d621d890e629da4b32ed09f Mon Sep 17 00:00:00 2001 From: deads2k Date: Tue, 11 Aug 2015 13:56:46 -0400 Subject: [PATCH 22/35] UPSTREAM: 8890: Allowing ActiveDeadlineSeconds to be updated for a pod Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go --- .../pkg/api/validation/validation.go | 17 ++++++++ .../pkg/api/validation/validation_test.go | 43 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go index 83f2129a9484..0ef04becbd58 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation.go @@ -1168,6 +1168,15 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { allErrs = append(allErrs, errs.NewFieldInvalid("spec.containers", "content of spec.containers is not printed out, please refer to the \"details\"", "may not add or remove containers")) return allErrs } + + // for updates, we are allowing ActiveDeadlineSeconds to be 0 + // since a user may just want to terminate the containers without deleting the pod + if newPod.Spec.ActiveDeadlineSeconds != nil { + if *newPod.Spec.ActiveDeadlineSeconds <= 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("activeDeadlineSeconds", newPod.Spec.ActiveDeadlineSeconds, "activeDeadlineSeconds must be a positive integer greater than 0")) + } + } + pod := *newPod // Tricky, we need to copy the container list so that we don't overwrite the update var newContainers []api.Container @@ -1176,6 +1185,14 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { newContainers = append(newContainers, container) } pod.Spec.Containers = newContainers + + // allow ActiveDeadlineSeconds to be updated as well + pod.Spec.ActiveDeadlineSeconds = nil + if oldPod.Spec.ActiveDeadlineSeconds != nil { + activeDeadlineSeconds := *oldPod.Spec.ActiveDeadlineSeconds + pod.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds + } + if !api.Semantic.DeepEqual(pod.Spec, oldPod.Spec) { //TODO: Pinpoint the specific field that causes the invalid error after we have strategic merge diff allErrs = append(allErrs, errs.NewFieldInvalid("spec", "content of spec is not printed out, please refer to the \"details\"", "may not update fields other than container.image")) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go index d4e23221e18d..2607976895f6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/validation/validation_test.go @@ -1438,6 +1438,9 @@ func TestValidatePodUpdate(t *testing.T) { now := unversioned.Now() grace := int64(30) grace2 := int64(31) + activeDeadlineSecondsZero := int64(0) + activeDeadlineSecondsNegative := int64(-30) + activeDeadlineSecondsPositive := int64(30) tests := []struct { a api.Pod b api.Pod @@ -1524,6 +1527,46 @@ func TestValidatePodUpdate(t *testing.T) { false, "more containers", }, + { + api.Pod{ + Spec: api.PodSpec{ + ActiveDeadlineSeconds: &activeDeadlineSecondsZero, + }, + }, + api.Pod{}, + false, + "activedeadlineseconds change to 0", + }, + { + api.Pod{ + Spec: api.PodSpec{ + ActiveDeadlineSeconds: &activeDeadlineSecondsPositive, + }, + }, + api.Pod{}, + true, + "activedeadlineseconds change to positive", + }, + { + api.Pod{ + Spec: api.PodSpec{ + ActiveDeadlineSeconds: &activeDeadlineSecondsNegative, + }, + }, + api.Pod{}, + false, + "activedeadlineseconds change to negative", + }, + { + api.Pod{ + Spec: api.PodSpec{ + ActiveDeadlineSeconds: &activeDeadlineSecondsPositive, + }, + }, + api.Pod{}, + true, + "activedeadlineseconds change back to nil", + }, { api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", DeletionTimestamp: &now}, From 0f62e6675f4da532387f2e718e148115994cde69 Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 15 Oct 2015 16:51:17 -0400 Subject: [PATCH 23/35] UPSTREAM: 15232: refactor logs to be composeable --- .../k8s.io/kubernetes/pkg/kubectl/cmd/log.go | 183 ++++++++++-------- .../kubernetes/pkg/kubectl/cmd/log_test.go | 123 ------------ 2 files changed, 104 insertions(+), 202 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log.go index e67df4eaa3f4..e6f150ec750d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log.go @@ -17,6 +17,7 @@ limitations under the License. package cmd import ( + "errors" "fmt" "io" "math" @@ -30,7 +31,6 @@ import ( "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" - "k8s.io/kubernetes/pkg/util/sets" ) const ( @@ -50,137 +50,162 @@ $ kubectl logs --tail=20 nginx $ kubectl logs --since=1h nginx` ) -func selectContainer(pod *api.Pod, in io.Reader, out io.Writer) string { - fmt.Fprintf(out, "Please select a container:\n") - options := sets.String{} - for ix := range pod.Spec.Containers { - fmt.Fprintf(out, "[%d] %s\n", ix+1, pod.Spec.Containers[ix].Name) - options.Insert(pod.Spec.Containers[ix].Name) - } - for { - var input string - fmt.Fprintf(out, "> ") - fmt.Fscanln(in, &input) - if options.Has(input) { - return input - } - ix, err := strconv.Atoi(input) - if err == nil && ix > 0 && ix <= len(pod.Spec.Containers) { - return pod.Spec.Containers[ix-1].Name - } - fmt.Fprintf(out, "Invalid input: %s", input) - } -} - -type logParams struct { - containerName string +type LogsOptions struct { + Client *client.Client + + PodNamespace string + PodName string + ContainerName string + Follow bool + Timestamps bool + Previous bool + LimitBytes int + Tail int + SinceTime *unversioned.Time + SinceSeconds time.Duration + + Out io.Writer } // NewCmdLog creates a new pod log command func NewCmdLog(f *cmdutil.Factory, out io.Writer) *cobra.Command { - params := &logParams{} + o := &LogsOptions{ + Out: out, + Tail: -1, + } + cmd := &cobra.Command{ Use: "logs [-f] [-p] POD [-c CONTAINER]", Short: "Print the logs for a container in a pod.", Long: "Print the logs for a container in a pod. If the pod has only one container, the container name is optional.", Example: log_example, Run: func(cmd *cobra.Command, args []string) { - err := RunLog(f, out, cmd, args, params) - cmdutil.CheckErr(err) + if len(os.Args) > 1 && os.Args[1] == "log" { + printDeprecationWarning("logs", "log") + } + + cmdutil.CheckErr(o.Complete(f, out, cmd, args)) + if err := o.Validate(); err != nil { + cmdutil.CheckErr(cmdutil.UsageError(cmd, err.Error())) + } + cmdutil.CheckErr(o.RunLog()) }, Aliases: []string{"log"}, } - cmd.Flags().BoolP("follow", "f", false, "Specify if the logs should be streamed.") - cmd.Flags().Bool("timestamps", false, "Include timestamps on each line in the log output") + cmd.Flags().BoolVarP(&o.Follow, "follow", "f", o.Follow, "Specify if the logs should be streamed.") + cmd.Flags().BoolVar(&o.Timestamps, "timestamps", o.Timestamps, "Include timestamps on each line in the log output") cmd.Flags().Bool("interactive", true, "If true, prompt the user for input when required. Default true.") - cmd.Flags().BoolP("previous", "p", false, "If true, print the logs for the previous instance of the container in a pod if it exists.") - cmd.Flags().Int("limit-bytes", 0, "Maximum bytes of logs to return. Defaults to no limit.") - cmd.Flags().Int("tail", -1, "Lines of recent log file to display. Defaults to -1, showing all log lines.") + cmd.Flags().MarkDeprecated("interactive", "This flag is no longer respected and there is no replacement.") + cmd.Flags().IntVar(&o.LimitBytes, "limit-bytes", o.LimitBytes, "Maximum bytes of logs to return. Defaults to no limit.") + cmd.Flags().BoolVarP(&o.Previous, "previous", "p", o.Previous, "If true, print the logs for the previous instance of the container in a pod if it exists.") + cmd.Flags().IntVar(&o.Tail, "tail", o.Tail, "Lines of recent log file to display. Defaults to -1, showing all log lines.") cmd.Flags().String("since-time", "", "Only return logs after a specific date (RFC3339). Defaults to all logs. Only one of since-time / since may be used.") - cmd.Flags().Duration("since", 0, "Only return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to all logs. Only one of since-time / since may be used.") - cmd.Flags().StringVarP(¶ms.containerName, "container", "c", "", "Container name") + cmd.Flags().DurationVar(&o.SinceSeconds, "since", o.SinceSeconds, "Only return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to all logs. Only one of since-time / since may be used.") + cmd.Flags().StringVarP(&o.ContainerName, "container", "c", o.ContainerName, "Container name") return cmd } -// RunLog retrieves a pod log -func RunLog(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, p *logParams) error { - if len(os.Args) > 1 && os.Args[1] == "log" { - printDeprecationWarning("logs", "log") - } - - if len(args) == 0 { +func (o *LogsOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { + switch len(args) { + case 0: return cmdutil.UsageError(cmd, "POD is required for log") - } - if len(args) > 2 { - return cmdutil.UsageError(cmd, "log POD [CONTAINER]") - } + case 1: + o.PodName = args[0] + case 2: + if cmd.Flag("container").Changed { + return cmdutil.UsageError(cmd, "only one of -c, [CONTAINER] arg is allowed") + } + o.PodName = args[0] + o.ContainerName = args[1] - sinceSeconds := cmdutil.GetFlagDuration(cmd, "since") - sinceTime := cmdutil.GetFlagString(cmd, "since-time") - if len(sinceTime) > 0 && sinceSeconds > 0 { - return cmdutil.UsageError(cmd, "only one of --since, --since-time may be specified") + default: + return cmdutil.UsageError(cmd, "log POD [-c CONTAINER]") } - namespace, _, err := f.DefaultNamespace() + var err error + o.PodNamespace, _, err = f.DefaultNamespace() if err != nil { return err } - client, err := f.Client() + o.Client, err = f.Client() if err != nil { return err } - podID := args[0] + sinceTime := cmdutil.GetFlagString(cmd, "since-time") + if len(sinceTime) > 0 { + t, err := api.ParseRFC3339(sinceTime, unversioned.Now) + if err != nil { + return err + } + o.SinceTime = &t + } + + return nil +} + +func (o *LogsOptions) Validate() error { + if len(o.PodName) == 0 { + return errors.New("POD must be specified") + } + if o.LimitBytes < 0 { + return errors.New("--limit-bytes must be greater than or equal to zero") + } + if o.Tail < -1 { + return errors.New("--tail must be greater than or equal to -1") + } + if o.SinceTime != nil && o.SinceSeconds > 0 { + return errors.New("only one of --since, --since-time may be specified") + } + + return nil +} - pod, err := client.Pods(namespace).Get(podID) +// RunLog retrieves a pod log +func (o *LogsOptions) RunLog() error { + pod, err := o.Client.Pods(o.PodNamespace).Get(o.PodName) if err != nil { return err } // [-c CONTAINER] - container := p.containerName + container := o.ContainerName if len(container) == 0 { // [CONTAINER] (container as arg not flag) is supported as legacy behavior. See PR #10519 for more details. - if len(args) == 1 { - if len(pod.Spec.Containers) != 1 { - podContainersNames := []string{} - for _, container := range pod.Spec.Containers { - podContainersNames = append(podContainersNames, container.Name) - } - - return fmt.Errorf("Pod %s has the following containers: %s; please specify the container to print logs for with -c", pod.ObjectMeta.Name, strings.Join(podContainersNames, ", ")) + if len(pod.Spec.Containers) != 1 { + podContainersNames := []string{} + for _, container := range pod.Spec.Containers { + podContainersNames = append(podContainersNames, container.Name) } - container = pod.Spec.Containers[0].Name - } else { - container = args[1] + + return fmt.Errorf("Pod %s has the following containers: %s; please specify the container to print logs for with -c", pod.ObjectMeta.Name, strings.Join(podContainersNames, ", ")) } + container = pod.Spec.Containers[0].Name } logOptions := &api.PodLogOptions{ Container: container, - Follow: cmdutil.GetFlagBool(cmd, "follow"), - Previous: cmdutil.GetFlagBool(cmd, "previous"), - Timestamps: cmdutil.GetFlagBool(cmd, "timestamps"), + Follow: o.Follow, + Previous: o.Previous, + Timestamps: o.Timestamps, } - if sinceSeconds > 0 { + if o.SinceSeconds > 0 { // round up to the nearest second - sec := int64(math.Ceil(float64(sinceSeconds) / float64(time.Second))) + sec := int64(math.Ceil(float64(o.SinceSeconds) / float64(time.Second))) logOptions.SinceSeconds = &sec } - if t, err := api.ParseRFC3339(sinceTime, unversioned.Now); err == nil { - logOptions.SinceTime = &t - } - if limitBytes := cmdutil.GetFlagInt(cmd, "limit-bytes"); limitBytes != 0 { - i := int64(limitBytes) + logOptions.SinceTime = o.SinceTime + if o.LimitBytes != 0 { + i := int64(o.LimitBytes) logOptions.LimitBytes = &i } - if tail := cmdutil.GetFlagInt(cmd, "tail"); tail >= 0 { - i := int64(tail) + if o.Tail >= 0 { + i := int64(o.Tail) logOptions.TailLines = &i } - return handleLog(client, namespace, podID, logOptions, out) + return handleLog(o.Client, o.PodNamespace, o.PodName, logOptions, o.Out) } func handleLog(client *client.Client, namespace, podID string, logOptions *api.PodLogOptions, out io.Writer) error { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log_test.go index 16171223cc3c..013b4ee5fafd 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/log_test.go @@ -27,129 +27,6 @@ import ( "k8s.io/kubernetes/pkg/client/unversioned/fake" ) -func TestSelectContainer(t *testing.T) { - tests := []struct { - input string - pod api.Pod - expectedContainer string - }{ - { - input: "1\n", - pod: api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "foo", - }, - }, - }, - }, - expectedContainer: "foo", - }, - { - input: "foo\n", - pod: api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "foo", - }, - }, - }, - }, - expectedContainer: "foo", - }, - { - input: "foo\n", - pod: api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "bar", - }, - { - Name: "foo", - }, - }, - }, - }, - expectedContainer: "foo", - }, - { - input: "2\n", - pod: api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "bar", - }, - { - Name: "foo", - }, - }, - }, - }, - expectedContainer: "foo", - }, - { - input: "-1\n2\n", - pod: api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "bar", - }, - { - Name: "foo", - }, - }, - }, - }, - expectedContainer: "foo", - }, - { - input: "3\n2\n", - pod: api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "bar", - }, - { - Name: "foo", - }, - }, - }, - }, - expectedContainer: "foo", - }, - { - input: "baz\n2\n", - pod: api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "bar", - }, - { - Name: "foo", - }, - }, - }, - }, - expectedContainer: "foo", - }, - } - - for _, test := range tests { - var buff bytes.Buffer - container := selectContainer(&test.pod, bytes.NewBufferString(test.input), &buff) - if container != test.expectedContainer { - t.Errorf("unexpected output: %s for input: %s", container, test.input) - } - } -} - func TestLog(t *testing.T) { tests := []struct { name, version, podPath, logPath, container string From 57f9a602815baa257516c28c9e2c8df64e54173b Mon Sep 17 00:00:00 2001 From: deads2k Date: Wed, 12 Aug 2015 15:51:43 -0400 Subject: [PATCH 24/35] UPSTREAM: 12498: Re-add timeouts for kubelet which is not in the upstream PR. --- Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server.go index a044ad1c8642..9dae252c5462 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubelet/server.go @@ -104,6 +104,8 @@ func ListenAndServeKubeletServer(host HostInterface, address net.IP, port uint, s := &http.Server{ Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)), Handler: &handler, + ReadTimeout: 60 * time.Minute, + WriteTimeout: 60 * time.Minute, MaxHeaderBytes: 1 << 20, } if tlsOptions != nil { @@ -122,6 +124,8 @@ func ListenAndServeKubeletReadOnlyServer(host HostInterface, address net.IP, por server := &http.Server{ Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)), Handler: &s, + ReadTimeout: 60 * time.Minute, + WriteTimeout: 60 * time.Minute, MaxHeaderBytes: 1 << 20, } glog.Fatal(server.ListenAndServe()) From 01df4bd4aabac7d9b3c57dfd0ca520a051bb013e Mon Sep 17 00:00:00 2001 From: deads2k Date: Tue, 28 Jul 2015 09:11:41 -0400 Subject: [PATCH 25/35] UPSTREAM: 11827: allow permissive SA secret ref limitting Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller.go Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller_test.go --- .../serviceaccounts_controller.go | 55 ++++++++++--------- .../serviceaccounts_controller_test.go | 5 +- .../pkg/admission/serviceaccount/admission.go | 27 ++++++++- .../serviceaccount/admission_test.go | 30 ++++++++++ 4 files changed, 88 insertions(+), 29 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller.go index 0bb3b5e48844..27e933fd0f87 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller.go @@ -29,7 +29,6 @@ import ( "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/watch" ) @@ -44,8 +43,8 @@ func nameIndexFunc(obj interface{}) ([]string, error) { // ServiceAccountsControllerOptions contains options for running a ServiceAccountsController type ServiceAccountsControllerOptions struct { - // Names is the set of service account names to ensure exist in every namespace - Names sets.String + // ServiceAccounts is the list of service accounts to ensure exist in every namespace + ServiceAccounts []api.ServiceAccount // ServiceAccountResync is the interval between full resyncs of ServiceAccounts. // If non-zero, all service accounts will be re-listed this often. @@ -59,20 +58,24 @@ type ServiceAccountsControllerOptions struct { } func DefaultServiceAccountsControllerOptions() ServiceAccountsControllerOptions { - return ServiceAccountsControllerOptions{Names: sets.NewString("default")} + return ServiceAccountsControllerOptions{ + ServiceAccounts: []api.ServiceAccount{ + {ObjectMeta: api.ObjectMeta{Name: "default"}}, + }, + } } // NewServiceAccountsController returns a new *ServiceAccountsController. func NewServiceAccountsController(cl client.Interface, options ServiceAccountsControllerOptions) *ServiceAccountsController { e := &ServiceAccountsController{ - client: cl, - names: options.Names, + client: cl, + serviceAccountsToEnsure: options.ServiceAccounts, } accountSelector := fields.Everything() - if len(options.Names) == 1 { + if len(options.ServiceAccounts) == 1 { // If we're maintaining a single account, we can scope the accounts we watch to just that name - accountSelector = fields.SelectorFromSet(map[string]string{client.ObjectNameField: options.Names.List()[0]}) + accountSelector = fields.SelectorFromSet(map[string]string{client.ObjectNameField: options.ServiceAccounts[0].Name}) } e.serviceAccounts, e.serviceAccountController = framework.NewIndexerInformer( &cache.ListWatch{ @@ -116,8 +119,8 @@ func NewServiceAccountsController(cl client.Interface, options ServiceAccountsCo type ServiceAccountsController struct { stopChan chan struct{} - client client.Interface - names sets.String + client client.Interface + serviceAccountsToEnsure []api.ServiceAccount serviceAccounts cache.Indexer namespaces cache.Indexer @@ -153,24 +156,26 @@ func (e *ServiceAccountsController) serviceAccountDeleted(obj interface{}) { return } // If the deleted service account is one we're maintaining, recreate it - if e.names.Has(serviceAccount.Name) { - e.createServiceAccountIfNeeded(serviceAccount.Name, serviceAccount.Namespace) + for _, sa := range e.serviceAccountsToEnsure { + if sa.Name == serviceAccount.Name { + e.createServiceAccountIfNeeded(sa, serviceAccount.Namespace) + } } } // namespaceAdded reacts to a Namespace creation by creating a default ServiceAccount object func (e *ServiceAccountsController) namespaceAdded(obj interface{}) { namespace := obj.(*api.Namespace) - for _, name := range e.names.List() { - e.createServiceAccountIfNeeded(name, namespace.Name) + for _, sa := range e.serviceAccountsToEnsure { + e.createServiceAccountIfNeeded(sa, namespace.Name) } } // namespaceUpdated reacts to a Namespace update (or re-list) by creating a default ServiceAccount in the namespace if needed func (e *ServiceAccountsController) namespaceUpdated(oldObj interface{}, newObj interface{}) { newNamespace := newObj.(*api.Namespace) - for _, name := range e.names.List() { - e.createServiceAccountIfNeeded(name, newNamespace.Name) + for _, sa := range e.serviceAccountsToEnsure { + e.createServiceAccountIfNeeded(sa, newNamespace.Name) } } @@ -178,13 +183,13 @@ func (e *ServiceAccountsController) namespaceUpdated(oldObj interface{}, newObj // * the named ServiceAccount does not already exist // * the specified namespace exists // * the specified namespace is in the ACTIVE phase -func (e *ServiceAccountsController) createServiceAccountIfNeeded(name, namespace string) { - serviceAccount, err := e.getServiceAccount(name, namespace) +func (e *ServiceAccountsController) createServiceAccountIfNeeded(sa api.ServiceAccount, namespace string) { + existingServiceAccount, err := e.getServiceAccount(sa.Name, namespace) if err != nil { glog.Error(err) return } - if serviceAccount != nil { + if existingServiceAccount != nil { // If service account already exists, it doesn't need to be created return } @@ -203,20 +208,18 @@ func (e *ServiceAccountsController) createServiceAccountIfNeeded(name, namespace return } - e.createServiceAccount(name, namespace) + e.createServiceAccount(sa, namespace) } // createDefaultServiceAccount creates a default ServiceAccount in the specified namespace -func (e *ServiceAccountsController) createServiceAccount(name, namespace string) { - serviceAccount := &api.ServiceAccount{} - serviceAccount.Name = name - serviceAccount.Namespace = namespace - if _, err := e.client.ServiceAccounts(namespace).Create(serviceAccount); err != nil { +func (e *ServiceAccountsController) createServiceAccount(sa api.ServiceAccount, namespace string) { + sa.Namespace = namespace + if _, err := e.client.ServiceAccounts(namespace).Create(&sa); err != nil { glog.Error(err) } } -// getDefaultServiceAccount returns the ServiceAccount with the given name for the given namespace +// getServiceAccount returns the ServiceAccount with the given name for the given namespace func (e *ServiceAccountsController) getServiceAccount(name, namespace string) (*api.ServiceAccount, error) { key := &api.ServiceAccount{ObjectMeta: api.ObjectMeta{Namespace: namespace}} accounts, err := e.serviceAccounts.Index("namespace", key) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller_test.go index 146ce7d567ea..f569e811a529 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/controller/serviceaccount/serviceaccounts_controller_test.go @@ -151,7 +151,10 @@ func TestServiceAccountCreation(t *testing.T) { for k, tc := range testcases { client := testclient.NewSimpleFake(defaultServiceAccount, managedServiceAccount) options := DefaultServiceAccountsControllerOptions() - options.Names = sets.NewString(defaultName, managedName) + options.ServiceAccounts = []api.ServiceAccount{ + {ObjectMeta: api.ObjectMeta{Name: defaultName}}, + {ObjectMeta: api.ObjectMeta{Name: managedName}}, + } controller := NewServiceAccountsController(client, options) if tc.ExistingNamespace != nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go index 26ee52e69ed5..cd6c873cf97c 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "math/rand" + "strconv" "time" "k8s.io/kubernetes/pkg/admission" @@ -39,12 +40,19 @@ import ( // DefaultServiceAccountName is the name of the default service account to set on pods which do not specify a service account const DefaultServiceAccountName = "default" +// EnforceMountableSecretsAnnotation is a default annotation that indicates that a service account should enforce mountable secrets. +// The value must be true to have this annotation take effect +const EnforceMountableSecretsAnnotation = "kubernetes.io/enforce-mountable-secrets" + // DefaultAPITokenMountPath is the path that ServiceAccountToken secrets are automounted to. // The token file would then be accessible at /var/run/secrets/kubernetes.io/serviceaccount const DefaultAPITokenMountPath = "/var/run/secrets/kubernetes.io/serviceaccount" +// PluginName is the name of this admission plugin +const PluginName = "ServiceAccount" + func init() { - admission.RegisterPlugin("ServiceAccount", func(client client.Interface, config io.Reader) (admission.Interface, error) { + admission.RegisterPlugin(PluginName, func(client client.Interface, config io.Reader) (admission.Interface, error) { serviceAccountAdmission := NewServiceAccount(client) serviceAccountAdmission.Run() return serviceAccountAdmission, nil @@ -181,7 +189,7 @@ func (s *serviceAccount) Admit(a admission.Attributes) (err error) { return admission.NewForbidden(a, fmt.Errorf("service account %s/%s was not found, retry after the service account is created", a.GetNamespace(), pod.Spec.ServiceAccountName)) } - if s.LimitSecretReferences { + if s.enforceMountableSecrets(serviceAccount) { if err := s.limitSecretReferences(serviceAccount, pod); err != nil { return admission.NewForbidden(a, err) } @@ -201,6 +209,21 @@ func (s *serviceAccount) Admit(a admission.Attributes) (err error) { return nil } +// enforceMountableSecrets indicates whether mountable secrets should be enforced for a particular service account +// A global setting of true will override any flag set on the individual service account +func (s *serviceAccount) enforceMountableSecrets(serviceAccount *api.ServiceAccount) bool { + if s.LimitSecretReferences { + return true + } + + if value, ok := serviceAccount.Annotations[EnforceMountableSecretsAnnotation]; ok { + enforceMountableSecretCheck, _ := strconv.ParseBool(value) + return enforceMountableSecretCheck + } + + return false +} + // getServiceAccount returns the ServiceAccount for the given namespace and name if it exists func (s *serviceAccount) getServiceAccount(namespace string, name string) (*api.ServiceAccount, error) { key := &api.ServiceAccount{ObjectMeta: api.ObjectMeta{Namespace: namespace}} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission_test.go index 65549007e230..f4fd2a69c162 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission_test.go @@ -428,6 +428,36 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) { } } +func TestAllowUnreferencedSecretVolumesForPermissiveSAs(t *testing.T) { + ns := "myns" + + admit := NewServiceAccount(nil) + admit.LimitSecretReferences = false + admit.RequireAPIToken = false + + // Add the default service account for the ns into the cache + admit.serviceAccounts.Add(&api.ServiceAccount{ + ObjectMeta: api.ObjectMeta{ + Name: DefaultServiceAccountName, + Namespace: ns, + Annotations: map[string]string{EnforceMountableSecretsAnnotation: "true"}, + }, + }) + + pod := &api.Pod{ + Spec: api.PodSpec{ + Volumes: []api.Volume{ + {VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "foo"}}}, + }, + }, + } + attrs := admission.NewAttributesRecord(pod, "Pod", ns, "myname", string(api.ResourcePods), "", admission.Create, nil) + err := admit.Admit(attrs) + if err == nil { + t.Errorf("Expected rejection for using a secret the service account does not reference") + } +} + func TestAllowsReferencedImagePullSecrets(t *testing.T) { ns := "myns" From 00ed697a68a2e1403ee46fb22f538ee7d8bea387 Mon Sep 17 00:00:00 2001 From: kargakis Date: Thu, 24 Sep 2015 17:01:44 +0200 Subject: [PATCH 26/35] UPSTREAM: 14496: deep-copies: Structs cannot be nil --- .../pkg/runtime/deep_copy_generator.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/deep_copy_generator.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/deep_copy_generator.go index 5dee4e263ab0..38fb54f5c472 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/deep_copy_generator.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/runtime/deep_copy_generator.go @@ -403,7 +403,8 @@ func (g *deepCopyGenerator) writeDeepCopyForPtr(b *buffer, inField reflect.Struc ifStmt := fmt.Sprintf(ifFormat, inField.Name) b.addLine(ifStmt, indent) - switch inField.Type.Elem().Kind() { + kind := inField.Type.Elem().Kind() + switch kind { case reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface, reflect.Struct: if _, found := g.copyables[inField.Type.Elem()]; found { newFormat := "out.%s = new(%s)\n" @@ -420,8 +421,10 @@ func (g *deepCopyGenerator) writeDeepCopyForPtr(b *buffer, inField reflect.Struc ifStmt := fmt.Sprintf(ifFormat, inField.Name) b.addLine(ifStmt, indent+1) b.addLine("return err\n", indent+2) - b.addLine("} else if newVal == nil {\n", indent+1) - b.addLine(fmt.Sprintf("out.%s = nil\n", inField.Name), indent+2) + if kind != reflect.Struct { + b.addLine("} else if newVal == nil {\n", indent+1) + b.addLine(fmt.Sprintf("out.%s = nil\n", inField.Name), indent+2) + } b.addLine("} else {\n", indent+1) assignFormat := "out.%s = newVal.(%s)\n" assignStmt := fmt.Sprintf(assignFormat, inField.Name, g.typeName(inField.Type)) @@ -455,7 +458,8 @@ func (g *deepCopyGenerator) writeDeepCopyForSlice(b *buffer, inField reflect.Str forStmt := fmt.Sprintf(forFormat, inField.Name) b.addLine(forStmt, indent+1) - switch inField.Type.Elem().Kind() { + kind := inField.Type.Elem().Kind() + switch kind { case reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface, reflect.Struct: if _, found := g.copyables[inField.Type.Elem()]; found { assignFormat := "if err := %s(in.%s[i], &out.%s[i], c); err != nil {\n" @@ -469,8 +473,10 @@ func (g *deepCopyGenerator) writeDeepCopyForSlice(b *buffer, inField reflect.Str ifStmt := fmt.Sprintf(ifFormat, inField.Name) b.addLine(ifStmt, indent+2) b.addLine("return err\n", indent+3) - b.addLine("} else if newVal == nil {\n", indent+2) - b.addLine(fmt.Sprintf("out.%s[i] = nil\n", inField.Name), indent+3) + if kind != reflect.Struct { + b.addLine("} else if newVal == nil {\n", indent+2) + b.addLine(fmt.Sprintf("out.%s[i] = nil\n", inField.Name), indent+3) + } b.addLine("} else {\n", indent+2) assignFormat := "out.%s[i] = newVal.(%s)\n" assignStmt := fmt.Sprintf(assignFormat, inField.Name, g.typeName(inField.Type.Elem())) From 52bb8f40a79bbea6f5cf15ee5f9410354c4e26f4 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sun, 11 Oct 2015 18:00:55 -0400 Subject: [PATCH 27/35] UPSTREAM: 15451 : Add our types to kubectl get error Needs to be made generic upstream. Conflicts: Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go --- .../k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go | 133 ++++++++++-------- 1 file changed, 73 insertions(+), 60 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go index b52b67161637..680735a3b6db 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go @@ -17,18 +17,18 @@ limitations under the License. package cmd import ( - "io" + "io" - "github.com/golang/glog" - cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config" - cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" - "k8s.io/kubernetes/pkg/util" + "github.com/golang/glog" + cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config" + cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + "k8s.io/kubernetes/pkg/util" - "github.com/spf13/cobra" + "github.com/spf13/cobra" ) const ( - bash_completion_func = `# call kubectl get $1, + bash_completion_func = `# call kubectl get $1, __kubectl_parse_get() { local template @@ -109,80 +109,93 @@ __custom_func() { esac } ` - valid_resources = `Valid resource types include: + valid_resources = `Valid resource types include: * pods (aka 'po') * replicationcontrollers (aka 'rc') * daemonsets (aka 'ds') * services (aka 'svc') + * deploymentconfigs (aka 'dc') + * buildconfigs (aka 'bc') + * builds + * routes + * replicationcontrollers (aka 'rc') * events (aka 'ev') - * nodes (aka 'no') - * namespaces (aka 'ns') + * projects * secrets + * imagestraams (aka 'is') + * imagestreamtags (aka 'istag') + * imagestreamimages (aka 'isimage') * persistentvolumes (aka 'pv') * persistentvolumeclaims (aka 'pvc') + * policies + * rolebindings * limitranges (aka 'limits') * resourcequotas (aka 'quota') + * nodes (aka 'no') + * namespaces (aka 'ns') + * users + * groups ` ) // NewKubectlCommand creates the `kubectl` command and its nested children. func NewKubectlCommand(f *cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command { - // Parent command to which all subcommands are added. - cmds := &cobra.Command{ - Use: "kubectl", - Short: "kubectl controls the Kubernetes cluster manager", - Long: `kubectl controls the Kubernetes cluster manager. + // Parent command to which all subcommands are added. + cmds := &cobra.Command{ + Use: "kubectl", + Short: "kubectl controls the Kubernetes cluster manager", + Long: `kubectl controls the Kubernetes cluster manager. Find more information at https://github.com/kubernetes/kubernetes.`, - Run: runHelp, - BashCompletionFunction: bash_completion_func, - } - - f.BindFlags(cmds.PersistentFlags()) - - // From this point and forward we get warnings on flags that contain "_" separators - cmds.SetGlobalNormalizationFunc(util.WarnWordSepNormalizeFunc) - - cmds.AddCommand(NewCmdGet(f, out)) - cmds.AddCommand(NewCmdDescribe(f, out)) - cmds.AddCommand(NewCmdCreate(f, out)) - cmds.AddCommand(NewCmdReplace(f, out)) - cmds.AddCommand(NewCmdPatch(f, out)) - cmds.AddCommand(NewCmdDelete(f, out)) - cmds.AddCommand(NewCmdEdit(f, out)) - cmds.AddCommand(NewCmdApply(f, out)) - - cmds.AddCommand(NewCmdNamespace(out)) - cmds.AddCommand(NewCmdLog(f, out)) - cmds.AddCommand(NewCmdRollingUpdate(f, out)) - cmds.AddCommand(NewCmdScale(f, out)) - - cmds.AddCommand(NewCmdAttach(f, in, out, err)) - cmds.AddCommand(NewCmdExec(f, in, out, err)) - cmds.AddCommand(NewCmdPortForward(f)) - cmds.AddCommand(NewCmdProxy(f, out)) - - cmds.AddCommand(NewCmdRun(f, in, out, err)) - cmds.AddCommand(NewCmdStop(f, out)) - cmds.AddCommand(NewCmdExposeService(f, out)) - - cmds.AddCommand(NewCmdLabel(f, out)) - cmds.AddCommand(NewCmdAnnotate(f, out)) - - cmds.AddCommand(cmdconfig.NewCmdConfig(cmdconfig.NewDefaultPathOptions(), out)) - cmds.AddCommand(NewCmdClusterInfo(f, out)) - cmds.AddCommand(NewCmdApiVersions(f, out)) - cmds.AddCommand(NewCmdVersion(f, out)) - cmds.AddCommand(NewCmdExplain(f, out)) - cmds.AddCommand(NewCmdConvert(f, out)) - - return cmds + Run: runHelp, + BashCompletionFunction: bash_completion_func, + } + + f.BindFlags(cmds.PersistentFlags()) + + // From this point and forward we get warnings on flags that contain "_" separators + cmds.SetGlobalNormalizationFunc(util.WarnWordSepNormalizeFunc) + + cmds.AddCommand(NewCmdGet(f, out)) + cmds.AddCommand(NewCmdDescribe(f, out)) + cmds.AddCommand(NewCmdCreate(f, out)) + cmds.AddCommand(NewCmdReplace(f, out)) + cmds.AddCommand(NewCmdPatch(f, out)) + cmds.AddCommand(NewCmdDelete(f, out)) + cmds.AddCommand(NewCmdEdit(f, out)) + cmds.AddCommand(NewCmdApply(f, out)) + + cmds.AddCommand(NewCmdNamespace(out)) + cmds.AddCommand(NewCmdLog(f, out)) + cmds.AddCommand(NewCmdRollingUpdate(f, out)) + cmds.AddCommand(NewCmdScale(f, out)) + + cmds.AddCommand(NewCmdAttach(f, in, out, err)) + cmds.AddCommand(NewCmdExec(f, in, out, err)) + cmds.AddCommand(NewCmdPortForward(f)) + cmds.AddCommand(NewCmdProxy(f, out)) + + cmds.AddCommand(NewCmdRun(f, in, out, err)) + cmds.AddCommand(NewCmdStop(f, out)) + cmds.AddCommand(NewCmdExposeService(f, out)) + + cmds.AddCommand(NewCmdLabel(f, out)) + cmds.AddCommand(NewCmdAnnotate(f, out)) + + cmds.AddCommand(cmdconfig.NewCmdConfig(cmdconfig.NewDefaultPathOptions(), out)) + cmds.AddCommand(NewCmdClusterInfo(f, out)) + cmds.AddCommand(NewCmdApiVersions(f, out)) + cmds.AddCommand(NewCmdVersion(f, out)) + cmds.AddCommand(NewCmdExplain(f, out)) + cmds.AddCommand(NewCmdConvert(f, out)) + + return cmds } func runHelp(cmd *cobra.Command, args []string) { - cmd.Help() + cmd.Help() } func printDeprecationWarning(command, alias string) { - glog.Warningf("%s is DEPRECATED and will be removed in a future version. Use %s instead.", alias, command) + glog.Warningf("%s is DEPRECATED and will be removed in a future version. Use %s instead.", alias, command) } From a60c36e5609a995bb50f5cde966c417e27b40219 Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 15 Oct 2015 16:26:57 -0400 Subject: [PATCH 28/35] UPSTREAM: TODO: expose ResyncPeriod function --- .../kube-controller-manager/app/controllermanager.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go b/Godeps/_workspace/src/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go index 029b60c26fac..d0c8ad5b0fbb 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go @@ -201,7 +201,7 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet) { fs.IntVar(&s.KubeApiBurst, "kube-api-burst", s.KubeApiBurst, "Burst to use while talking with kubernetes apiserver") } -func (s *CMServer) resyncPeriod() time.Duration { +func (s *CMServer) ResyncPeriod() time.Duration { factor := rand.Float64() + 1 return time.Duration(float64(s.MinResyncPeriod.Nanoseconds()) * factor) } @@ -247,14 +247,14 @@ func (s *CMServer) Run(_ []string) error { glog.Fatal(server.ListenAndServe()) }() - go endpointcontroller.NewEndpointController(kubeClient, s.resyncPeriod). + go endpointcontroller.NewEndpointController(kubeClient, s.ResyncPeriod). Run(s.ConcurrentEndpointSyncs, util.NeverStop) - go replicationcontroller.NewReplicationManager(kubeClient, s.resyncPeriod, replicationcontroller.BurstReplicas). + go replicationcontroller.NewReplicationManager(kubeClient, s.ResyncPeriod, replicationcontroller.BurstReplicas). Run(s.ConcurrentRCSyncs, util.NeverStop) if s.TerminatedPodGCThreshold > 0 { - go gc.New(kubeClient, s.resyncPeriod, s.TerminatedPodGCThreshold). + go gc.New(kubeClient, s.ResyncPeriod, s.TerminatedPodGCThreshold). Run(util.NeverStop) } @@ -290,10 +290,10 @@ func (s *CMServer) Run(_ []string) error { namespacecontroller.NewNamespaceController(kubeClient, s.EnableExperimental, s.NamespaceSyncPeriod).Run() if s.EnableExperimental { - go daemon.NewDaemonSetsController(kubeClient, s.resyncPeriod). + go daemon.NewDaemonSetsController(kubeClient, s.ResyncPeriod). Run(s.ConcurrentDSCSyncs, util.NeverStop) - go job.NewJobController(kubeClient, s.resyncPeriod). + go job.NewJobController(kubeClient, s.ResyncPeriod). Run(s.ConcurrentJobSyncs, util.NeverStop) podautoscaler.NewHorizontalController(kubeClient, metrics.NewHeapsterMetricsClient(kubeClient)). From 5d308eea8263ced01937532930ac6f63413ec9a6 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Sun, 18 Oct 2015 21:27:53 -0400 Subject: [PATCH 29/35] UPSTREAM: 15807: Platform-specific setRLimit implementations --- .../kubernetes/pkg/proxy/userspace/proxier.go | 5 ---- .../kubernetes/pkg/proxy/userspace/rlimit.go | 25 +++++++++++++++++++ .../pkg/proxy/userspace/rlimit_windows.go | 23 +++++++++++++++++ 3 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/rlimit.go create mode 100644 Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/rlimit_windows.go diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier.go index 205edf4b7d6b..f682b3d5b8dd 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/proxier.go @@ -23,7 +23,6 @@ import ( "strings" "sync" "sync/atomic" - "syscall" "time" "github.com/golang/glog" @@ -158,10 +157,6 @@ func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.In return createProxier(loadBalancer, listenIP, iptables, hostIP, proxyPorts, syncPeriod) } -func setRLimit(limit uint64) error { - return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &syscall.Rlimit{Max: limit, Cur: limit}) -} - func createProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface, hostIP net.IP, proxyPorts PortAllocator, syncPeriod time.Duration) (*Proxier, error) { // convenient to pass nil for tests.. if proxyPorts == nil { diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/rlimit.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/rlimit.go new file mode 100644 index 000000000000..0f634e051cba --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/rlimit.go @@ -0,0 +1,25 @@ +// +build !windows + +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 userspace + +import "syscall" + +func setRLimit(limit uint64) error { + return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &syscall.Rlimit{Max: limit, Cur: limit}) +} diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/rlimit_windows.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/rlimit_windows.go new file mode 100644 index 000000000000..346ee18bb934 --- /dev/null +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/proxy/userspace/rlimit_windows.go @@ -0,0 +1,23 @@ +// +build windows + +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 userspace + +func setRLimit(limit uint64) error { + return nil +} From 0d62b29db1140bf1e1bd624b10fc2002dc7b6ba8 Mon Sep 17 00:00:00 2001 From: deads2k Date: Mon, 19 Oct 2015 13:33:54 -0400 Subject: [PATCH 30/35] UPSTREAM: 12221: Allow custom namespace creation in e2e framework --- .../src/k8s.io/kubernetes/test/e2e/framework.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/framework.go b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/framework.go index c768a8602539..ed4075f461c2 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/framework.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/test/e2e/framework.go @@ -39,13 +39,23 @@ type Framework struct { Namespace *api.Namespace Client *client.Client NamespaceDeletionTimeout time.Duration + + // Allows to override the initialization of the namespace + nsCreateFunc func(string, *client.Client) (*api.Namespace, error) } // NewFramework makes a new framework and sets up a BeforeEach/AfterEach for // you (you can write additional before/after each functions). func NewFramework(baseName string) *Framework { + return InitializeFramework(baseName, createTestingNS) +} + +// InitializeFramework initialize the framework by allowing to pass a custom +// namespace creation function. +func InitializeFramework(baseName string, nsCreateFunc func(string, *client.Client) (*api.Namespace, error)) *Framework { f := &Framework{ - BaseName: baseName, + BaseName: baseName, + nsCreateFunc: nsCreateFunc, } BeforeEach(f.beforeEach) @@ -63,7 +73,7 @@ func (f *Framework) beforeEach() { f.Client = c By("Building a namespace api object") - namespace, err := createTestingNS(f.BaseName, f.Client) + namespace, err := f.nsCreateFunc(f.BaseName, f.Client) Expect(err).NotTo(HaveOccurred()) f.Namespace = namespace From 6e7e750a2a63d1e1861bd929ea86e0f7775584ac Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 15 Oct 2015 14:01:16 -0400 Subject: [PATCH 31/35] UPSTREAM: openshift-sdn(TODO): handle boring upstream refactors --- .../pkg/cmd/admin/network/project_options.go | 3 ++- .../openshift/openshift-sdn/plugins/osdn/osdn.go | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Godeps/_workspace/src/github.com/openshift/openshift-sdn/pkg/cmd/admin/network/project_options.go b/Godeps/_workspace/src/github.com/openshift/openshift-sdn/pkg/cmd/admin/network/project_options.go index e7a98628c30f..a84a1f14c486 100644 --- a/Godeps/_workspace/src/github.com/openshift/openshift-sdn/pkg/cmd/admin/network/project_options.go +++ b/Godeps/_workspace/src/github.com/openshift/openshift-sdn/pkg/cmd/admin/network/project_options.go @@ -11,6 +11,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" kclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/labels" @@ -178,7 +179,7 @@ func (p *ProjectOptions) CreateOrUpdateNetNamespace(name string, id uint) error func newNetNamespace(name string, id uint) *sdnapi.NetNamespace { return &sdnapi.NetNamespace{ - TypeMeta: kapi.TypeMeta{Kind: "NetNamespace"}, + TypeMeta: unversioned.TypeMeta{Kind: "NetNamespace"}, ObjectMeta: kapi.ObjectMeta{Name: name}, NetName: name, NetID: id, diff --git a/Godeps/_workspace/src/github.com/openshift/openshift-sdn/plugins/osdn/osdn.go b/Godeps/_workspace/src/github.com/openshift/openshift-sdn/plugins/osdn/osdn.go index 68cefc73ffe0..5941a2d1f6a4 100644 --- a/Godeps/_workspace/src/github.com/openshift/openshift-sdn/plugins/osdn/osdn.go +++ b/Godeps/_workspace/src/github.com/openshift/openshift-sdn/plugins/osdn/osdn.go @@ -12,6 +12,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" kclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" @@ -84,7 +85,7 @@ func (oi *OsdnRegistryInterface) DeleteSubnet(nodeName string) error { func (oi *OsdnRegistryInterface) CreateSubnet(nodeName string, sub *osdnapi.Subnet) error { hs := &api.HostSubnet{ - TypeMeta: kapi.TypeMeta{Kind: "HostSubnet"}, + TypeMeta: unversioned.TypeMeta{Kind: "HostSubnet"}, ObjectMeta: kapi.ObjectMeta{Name: nodeName}, Host: nodeName, HostIP: sub.NodeIP, @@ -277,7 +278,7 @@ func (oi *OsdnRegistryInterface) WriteNetworkConfig(network string, subnetLength } } cn = &api.ClusterNetwork{ - TypeMeta: kapi.TypeMeta{Kind: "ClusterNetwork"}, + TypeMeta: unversioned.TypeMeta{Kind: "ClusterNetwork"}, ObjectMeta: kapi.ObjectMeta{Name: "default"}, Network: network, HostSubnetLength: int(subnetLength), @@ -374,7 +375,7 @@ func (oi *OsdnRegistryInterface) GetNetNamespace(name string) (osdnapi.NetNamesp func (oi *OsdnRegistryInterface) WriteNetNamespace(name string, id uint) error { netns := &api.NetNamespace{ - TypeMeta: kapi.TypeMeta{Kind: "NetNamespace"}, + TypeMeta: unversioned.TypeMeta{Kind: "NetNamespace"}, ObjectMeta: kapi.ObjectMeta{Name: name}, NetName: name, NetID: id, @@ -397,7 +398,7 @@ func (oi *OsdnRegistryInterface) GetServices() ([]osdnapi.Service, string, error } func (oi *OsdnRegistryInterface) getServices(namespace string) ([]osdnapi.Service, string, error) { - kServList, err := oi.kClient.Services(namespace).List(labels.Everything()) + kServList, err := oi.kClient.Services(namespace).List(labels.Everything(), fields.Everything()) if err != nil { return nil, "", err } @@ -498,7 +499,7 @@ func (oi *OsdnRegistryInterface) runEventQueue(resourceName string) (*oscache.Ev case "service": expectedType = &kapi.Service{} lw.ListFunc = func() (runtime.Object, error) { - return oi.kClient.Services(kapi.NamespaceAll).List(labels.Everything()) + return oi.kClient.Services(kapi.NamespaceAll).List(labels.Everything(), fields.Everything()) } lw.WatchFunc = func(resourceVersion string) (watch.Interface, error) { return oi.kClient.Services(kapi.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion) From 76d264fb266cf8df92d97dbd020a29e44d344ac4 Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 15 Oct 2015 14:30:42 -0400 Subject: [PATCH 32/35] UPSTREAM: openshift-sdn(TODO): update for iptables.New call --- .../openshift/openshift-sdn/pkg/ovssubnet/common.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Godeps/_workspace/src/github.com/openshift/openshift-sdn/pkg/ovssubnet/common.go b/Godeps/_workspace/src/github.com/openshift/openshift-sdn/pkg/ovssubnet/common.go index 9c6e00697ca2..a01b7d89f7c7 100644 --- a/Godeps/_workspace/src/github.com/openshift/openshift-sdn/pkg/ovssubnet/common.go +++ b/Godeps/_workspace/src/github.com/openshift/openshift-sdn/pkg/ovssubnet/common.go @@ -14,6 +14,7 @@ import ( "github.com/openshift/openshift-sdn/pkg/ovssubnet/controller/kube" "github.com/openshift/openshift-sdn/pkg/ovssubnet/controller/multitenant" + utildbus "k8s.io/kubernetes/pkg/util/dbus" kexec "k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/iptables" ) @@ -702,7 +703,8 @@ func SetupIptables(fw *firewalld.Interface, clusterNetworkCIDR string) error { } } } else { - ipt := iptables.New(kexec.New(), iptables.ProtocolIpv4) + dbus := utildbus.New() + ipt := iptables.New(kexec.New(), dbus, iptables.ProtocolIpv4) _, err := ipt.EnsureRule(iptables.Append, iptables.TableNAT, iptables.ChainPostrouting, "-s", clusterNetworkCIDR, "!", "-d", clusterNetworkCIDR, "-j", "MASQUERADE") if err != nil { From 987aca9b5e3fc33d772dd5d6b46ec61386cd02a4 Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 15 Oct 2015 14:46:50 -0400 Subject: [PATCH 33/35] refactors --- api/swagger-spec/api-v1.json | 834 +++-- api/swagger-spec/oapi-v1.json | 601 ++-- contrib/completions/bash/oadm | 1 + contrib/completions/bash/oc | 97 + contrib/completions/bash/openshift | 248 +- docs/generated/oadm_by_example_content.adoc | 2 +- docs/generated/oc_by_example_content.adoc | 55 +- hack/api-description-whitelist.txt | 10 + hack/copy-kube-artifacts.sh | 26 + pkg/api/deep_copy_generated.go | 209 +- pkg/api/graph/graphview/veneering_test.go | 6 +- pkg/api/latest/latest.go | 8 +- pkg/api/latest/tags_test.go | 2 +- pkg/api/v1/conversion_generated.go | 2666 ++++++++++++--- pkg/api/v1/deep_copy_generated.go | 205 +- pkg/api/v1beta3/conversion_generated.go | 2891 +++++++++++++---- pkg/api/v1beta3/deep_copy_generated.go | 201 +- pkg/auth/oauth/registry/registry_test.go | 4 +- pkg/authorization/api/types.go | 74 +- pkg/authorization/api/v1/types.go | 88 +- pkg/authorization/api/v1beta3/types.go | 104 +- .../api/validation/validation.go | 4 +- .../authorizer/adapter/attributes.go | 2 +- .../authorizer/adapter/attributes_test.go | 2 +- .../authorizer/bootstrap_policy_test.go | 8 +- .../registry/clusterrole/proxy/proxy.go | 3 +- .../clusterrolebinding/proxy/proxy.go | 3 +- .../registry/policybinding/strategy.go | 6 +- .../role/policybased/virtual_storage.go | 14 +- .../role/policybased/virtual_storage_test.go | 6 +- .../policybased/virtual_storage.go | 10 +- .../policybased/virtual_storage_test.go | 8 +- pkg/build/admission/admission_test.go | 10 +- pkg/build/api/sort_test.go | 8 +- pkg/build/api/types.go | 26 +- pkg/build/api/v1/types.go | 32 +- pkg/build/api/v1beta3/types.go | 36 +- pkg/build/api/validation/validation.go | 8 +- pkg/build/controller/controller.go | 10 +- pkg/build/controller/controller_test.go | 12 +- pkg/build/controller/factory/factory.go | 3 +- pkg/build/controller/factory/factory_test.go | 4 +- pkg/build/controller/strategy/util.go | 4 +- pkg/build/generator/generator.go | 8 +- pkg/build/prune/data.go | 6 +- pkg/build/prune/data_test.go | 6 +- pkg/build/prune/prune_test.go | 4 +- pkg/build/prune/resolvers_test.go | 4 +- pkg/build/registry/build/strategy.go | 4 +- pkg/build/registry/build/strategy_test.go | 4 +- .../registry/buildconfig/webhook_test.go | 2 +- pkg/client/projectrequests.go | 8 +- pkg/client/testclient/fake_projectrequests.go | 6 +- pkg/cmd/admin/node/evacuate.go | 2 +- pkg/cmd/admin/prune/deployments.go | 2 +- pkg/cmd/admin/prune/images.go | 2 +- pkg/cmd/admin/router/router.go | 4 +- pkg/cmd/cli/cli.go | 3 + pkg/cmd/cli/cmd/deploy.go | 2 +- pkg/cmd/cli/cmd/exporter.go | 7 +- pkg/cmd/cli/cmd/expose.go | 2 +- pkg/cmd/cli/cmd/logs.go | 76 +- pkg/cmd/cli/cmd/process.go | 5 +- pkg/cmd/cli/cmd/rollback.go | 3 +- pkg/cmd/cli/cmd/wrappers.go | 75 +- pkg/cmd/cli/describe/deployments.go | 4 +- pkg/cmd/cli/describe/describer.go | 8 +- pkg/cmd/cli/describe/describer_test.go | 2 +- pkg/cmd/cli/describe/printer.go | 4 +- pkg/cmd/cli/describe/projectstatus.go | 16 +- pkg/cmd/infra/deployer/deployer.go | 5 +- pkg/cmd/server/admin/create_nodeconfig.go | 2 +- pkg/cmd/server/api/types.go | 30 +- pkg/cmd/server/api/v1/types.go | 31 +- pkg/cmd/server/api/validation/master.go | 3 +- pkg/cmd/server/api/validation/validation.go | 4 +- pkg/cmd/server/bootstrappolicy/policy.go | 5 + pkg/cmd/server/kubernetes/master.go | 10 +- pkg/cmd/server/kubernetes/master_config.go | 11 +- pkg/cmd/server/kubernetes/node.go | 7 +- pkg/cmd/server/kubernetes/node_config.go | 9 +- pkg/cmd/server/origin/asset.go | 2 +- pkg/cmd/server/origin/handlers.go | 12 +- pkg/cmd/server/origin/master_config.go | 4 +- pkg/cmd/server/start/kubernetes/proxy.go | 8 +- pkg/cmd/server/start/start_master.go | 8 +- pkg/cmd/util/clientcmd/factory.go | 6 + pkg/cmd/util/clientcmd/factory_fake.go | 151 - pkg/cmd/util/gendocs/gendocs.go | 3 +- pkg/cmd/util/tokencmd/request_token.go | 6 +- pkg/controller/controller.go | 5 +- pkg/deploy/api/types.go | 9 +- pkg/deploy/api/v1/types.go | 11 +- pkg/deploy/api/v1beta3/types.go | 13 +- pkg/deploy/api/validation/validation.go | 9 +- pkg/deploy/controller/deployerpod/factory.go | 4 +- pkg/deploy/controller/deployment/factory.go | 2 +- .../controller/deploymentconfig/factory.go | 2 +- pkg/deploy/prune/data.go | 6 +- pkg/deploy/prune/data_test.go | 6 +- pkg/deploy/prune/prune_test.go | 4 +- pkg/deploy/prune/resolvers_test.go | 4 +- pkg/deploy/prune/sort_test.go | 4 +- pkg/deploy/reaper/reaper.go | 3 +- pkg/deploy/scaler/scale.go | 90 +- pkg/deploy/scaler/scale_test.go | 3 +- pkg/deploy/scaler/test/support.go | 4 +- pkg/deploy/strategy/recreate/recreate.go | 2 +- pkg/dns/serviceaccessor.go | 2 +- pkg/generate/app/app.go | 4 +- pkg/generate/app/cmd/newapp.go | 9 +- pkg/generate/app/cmd/newapp_test.go | 8 +- pkg/generate/app/pipeline.go | 5 +- pkg/image/api/conversion.go | 4 +- pkg/image/api/docker10/dockertypes.go | 27 +- pkg/image/api/dockerpre012/conversion.go | 4 +- pkg/image/api/dockerpre012/dockertypes.go | 27 +- pkg/image/api/dockertypes.go | 49 +- pkg/image/api/sort.go | 4 +- pkg/image/api/types.go | 22 +- pkg/image/api/v1/types.go | 32 +- pkg/image/api/v1beta3/types.go | 24 +- pkg/image/controller/controller.go | 3 +- pkg/image/prune/imagepruner.go | 7 +- pkg/image/prune/imagepruner_test.go | 6 +- pkg/image/registry/image/etcd/etcd_test.go | 20 +- .../registry/imagestream/etcd/etcd_test.go | 34 +- pkg/image/registry/imagestream/registry.go | 7 +- pkg/image/registry/imagestream/strategy.go | 6 +- .../registry/imagestreamimage/rest_test.go | 8 +- .../registry/imagestreammapping/registry.go | 7 +- pkg/image/registry/imagestreammapping/rest.go | 8 +- .../registry/imagestreammapping/rest_test.go | 22 +- pkg/image/registry/imagestreamtag/registry.go | 7 +- pkg/image/registry/imagestreamtag/rest.go | 3 +- .../registry/imagestreamtag/rest_test.go | 18 +- pkg/ipfailover/keepalived/generator.go | 4 +- pkg/ipfailover/keepalived/generator_test.go | 2 +- pkg/oauth/api/types.go | 25 +- pkg/oauth/api/v1/types.go | 41 +- pkg/oauth/api/v1beta3/types.go | 41 +- .../osinserver/registrystorage/storage.go | 6 +- pkg/project/api/types.go | 9 +- pkg/project/api/v1/types.go | 19 +- pkg/project/api/v1beta3/types.go | 19 +- pkg/project/controller/controller_test.go | 2 +- pkg/project/registry/project/proxy/proxy.go | 40 +- .../registry/project/proxy/proxy_test.go | 4 +- .../projectrequest/delegated/delegated.go | 9 +- pkg/route/api/types.go | 7 +- pkg/route/api/v1/types.go | 9 +- pkg/route/api/v1beta3/types.go | 11 +- pkg/route/api/validation/validation.go | 3 +- pkg/sdn/api/types.go | 19 +- pkg/sdn/api/v1/types.go | 31 +- pkg/sdn/api/v1beta3/types.go | 31 +- .../controllers/docker_registry_service.go | 2 +- pkg/template/api/types.go | 7 +- pkg/template/api/v1/types.go | 9 +- pkg/template/api/v1beta3/types.go | 11 +- pkg/template/template_test.go | 11 +- pkg/user/api/types.go | 25 +- pkg/user/api/v1/types.go | 39 +- pkg/user/api/v1beta3/types.go | 39 +- pkg/user/registry/useridentitymapping/rest.go | 3 +- pkg/util/labels_test.go | 5 +- pkg/util/labelselector/labelselector.go | 8 +- pkg/util/namer/namer.go | 4 +- pkg/util/namer/namer_test.go | 20 +- pkg/util/rest/webhook.go | 7 +- plugins/route/allocation/simple/plugin.go | 4 +- test/cmd/admin.sh | 6 +- test/extended/util/framework.go | 5 +- test/integration/buildclient_test.go | 17 +- test/integration/deploy_trigger_test.go | 17 +- test/integration/router_test.go | 9 +- .../unprivileged_newproject_test.go | 5 +- test/util/helpers.go | 6 +- 178 files changed, 7183 insertions(+), 3103 deletions(-) delete mode 100644 pkg/cmd/util/clientcmd/factory_fake.go diff --git a/api/swagger-spec/api-v1.json b/api/swagger-spec/api-v1.json index f2df5b83162e..a41472c7339f 100644 --- a/api/swagger-spec/api-v1.json +++ b/api/swagger-spec/api-v1.json @@ -10,7 +10,7 @@ "apis": [ { "path": "/api/v1/namespaces/{namespace}/bindings", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Binding", @@ -61,7 +61,7 @@ }, { "path": "/api/v1/bindings", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Binding", @@ -104,7 +104,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/componentstatuses", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ComponentStatusList", @@ -179,7 +179,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/componentstatuses/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ComponentStatus", @@ -230,7 +230,7 @@ }, { "path": "/api/v1/componentstatuses", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ComponentStatusList", @@ -297,7 +297,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/endpoints", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.EndpointsList", @@ -417,7 +417,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/endpoints", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -492,7 +492,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/endpoints/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Endpoints", @@ -607,7 +607,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -648,7 +648,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Endpoints", "nickname": "deleteNamespacedEndpoints", @@ -690,7 +690,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -704,7 +704,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/endpoints/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -787,7 +787,7 @@ }, { "path": "/api/v1/endpoints", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.EndpointsList", @@ -891,7 +891,7 @@ }, { "path": "/api/v1/watch/endpoints", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -958,7 +958,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/events", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.EventList", @@ -1078,7 +1078,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/events", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -1153,7 +1153,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/events/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Event", @@ -1268,7 +1268,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -1309,7 +1309,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Event", "nickname": "deleteNamespacedEvent", @@ -1351,7 +1351,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -1365,7 +1365,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/events/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -1448,7 +1448,7 @@ }, { "path": "/api/v1/events", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.EventList", @@ -1552,7 +1552,7 @@ }, { "path": "/api/v1/watch/events", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -1619,7 +1619,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/limitranges", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.LimitRangeList", @@ -1739,7 +1739,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/limitranges", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -1814,7 +1814,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/limitranges/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.LimitRange", @@ -1929,7 +1929,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -1970,7 +1970,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a LimitRange", "nickname": "deleteNamespacedLimitRange", @@ -2012,7 +2012,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -2026,7 +2026,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/limitranges/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -2109,7 +2109,7 @@ }, { "path": "/api/v1/limitranges", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.LimitRangeList", @@ -2213,7 +2213,7 @@ }, { "path": "/api/v1/watch/limitranges", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -2280,7 +2280,7 @@ }, { "path": "/api/v1/namespaces", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.NamespaceList", @@ -2384,7 +2384,7 @@ }, { "path": "/api/v1/watch/namespaces", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -2451,7 +2451,7 @@ }, { "path": "/api/v1/namespaces/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Namespace", @@ -2550,7 +2550,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -2583,7 +2583,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Namespace", "nickname": "deleteNamespacedNamespace", @@ -2617,7 +2617,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -2631,7 +2631,7 @@ }, { "path": "/api/v1/watch/namespaces/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -2706,7 +2706,7 @@ }, { "path": "/api/v1/namespaces/{name}/finalize", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Namespace", @@ -2757,7 +2757,7 @@ }, { "path": "/api/v1/namespaces/{name}/status", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Namespace", @@ -2808,7 +2808,7 @@ }, { "path": "/api/v1/nodes", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.NodeList", @@ -2912,7 +2912,7 @@ }, { "path": "/api/v1/watch/nodes", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -2979,7 +2979,7 @@ }, { "path": "/api/v1/nodes/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Node", @@ -3078,7 +3078,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -3111,7 +3111,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Node", "nickname": "deleteNamespacedNode", @@ -3145,7 +3145,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -3159,7 +3159,7 @@ }, { "path": "/api/v1/watch/nodes/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -3234,7 +3234,7 @@ }, { "path": "/api/v1/proxy/nodes/{name}/{path:*}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "string", @@ -3253,7 +3253,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -3283,7 +3283,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -3313,7 +3313,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -3343,7 +3343,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -3373,7 +3373,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -3403,7 +3403,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -3420,7 +3420,7 @@ }, { "path": "/api/v1/proxy/nodes/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "string", @@ -3558,7 +3558,7 @@ }, { "path": "/api/v1/nodes/{name}/status", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Node", @@ -3609,7 +3609,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/persistentvolumeclaims", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PersistentVolumeClaimList", @@ -3729,7 +3729,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/persistentvolumeclaims", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -3804,7 +3804,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/persistentvolumeclaims/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PersistentVolumeClaim", @@ -3919,7 +3919,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -3960,7 +3960,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a PersistentVolumeClaim", "nickname": "deleteNamespacedPersistentVolumeClaim", @@ -4002,7 +4002,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -4016,7 +4016,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/persistentvolumeclaims/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -4099,7 +4099,7 @@ }, { "path": "/api/v1/persistentvolumeclaims", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PersistentVolumeClaimList", @@ -4203,7 +4203,7 @@ }, { "path": "/api/v1/watch/persistentvolumeclaims", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -4270,7 +4270,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/persistentvolumeclaims/{name}/status", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PersistentVolumeClaim", @@ -4329,7 +4329,7 @@ }, { "path": "/api/v1/persistentvolumes", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PersistentVolumeList", @@ -4433,7 +4433,7 @@ }, { "path": "/api/v1/watch/persistentvolumes", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -4500,7 +4500,7 @@ }, { "path": "/api/v1/persistentvolumes/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PersistentVolume", @@ -4599,7 +4599,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -4632,7 +4632,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a PersistentVolume", "nickname": "deleteNamespacedPersistentVolume", @@ -4666,7 +4666,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -4680,7 +4680,7 @@ }, { "path": "/api/v1/watch/persistentvolumes/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -4755,7 +4755,7 @@ }, { "path": "/api/v1/persistentvolumes/{name}/status", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PersistentVolume", @@ -4806,7 +4806,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/pods", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PodList", @@ -4926,7 +4926,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/pods", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -5001,7 +5001,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/pods/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Pod", @@ -5116,7 +5116,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -5157,7 +5157,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Pod", "nickname": "deleteNamespacedPod", @@ -5199,7 +5199,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -5213,7 +5213,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/pods/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -5296,7 +5296,7 @@ }, { "path": "/api/v1/proxy/namespaces/{namespace}/pods/{name}/{path:*}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "string", @@ -5323,7 +5323,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -5361,7 +5361,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -5399,7 +5399,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -5437,7 +5437,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -5475,7 +5475,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -5513,7 +5513,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -5530,7 +5530,7 @@ }, { "path": "/api/v1/proxy/namespaces/{namespace}/pods/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "string", @@ -5716,7 +5716,7 @@ }, { "path": "/api/v1/pods", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PodList", @@ -5820,7 +5820,7 @@ }, { "path": "/api/v1/watch/pods", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -5887,7 +5887,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/pods/{name}/attach", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "string", @@ -6033,7 +6033,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/pods/{name}/binding", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Binding", @@ -6092,7 +6092,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/pods/{name}/exec", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "string", @@ -6141,7 +6141,7 @@ "allowMultiple": false }, { - "type": "", + "type": "string", "paramType": "query", "name": "command", "description": "Command is the remote command to execute. argv array. Not executed within a shell.", @@ -6219,7 +6219,7 @@ "allowMultiple": false }, { - "type": "", + "type": "string", "paramType": "query", "name": "command", "description": "Command is the remote command to execute. argv array. Not executed within a shell.", @@ -6254,7 +6254,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/pods/{name}/log", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Pod", @@ -6294,6 +6294,46 @@ "required": false, "allowMultiple": false }, + { + "type": "*int64", + "paramType": "query", + "name": "sinceSeconds", + "description": "A relative time in seconds before the current time from which to show logs. If this value precedes the time a pod was started, only logs since the pod start will be returned. If this value is in the future, no logs will be returned. Only one of sinceSeconds or sinceTime may be specified.", + "required": false, + "allowMultiple": false + }, + { + "type": "string", + "paramType": "query", + "name": "sinceTime", + "description": "An RFC3339 timestamp from which to show logs. If this value preceeds the time a pod was started, only logs since the pod start will be returned. If this value is in the future, no logs will be returned. Only one of sinceSeconds or sinceTime may be specified.", + "required": false, + "allowMultiple": false + }, + { + "type": "boolean", + "paramType": "query", + "name": "timestamps", + "description": "If true, add an RFC3339 or RFC3339Nano timestamp at the beginning of every line of log output. Defaults to false.", + "required": false, + "allowMultiple": false + }, + { + "type": "*int64", + "paramType": "query", + "name": "tailLines", + "description": "If set, the number of lines from the end of the logs to show. If not specified, logs are shown from the creation of the container or sinceSeconds or sinceTime", + "required": false, + "allowMultiple": false + }, + { + "type": "*int64", + "paramType": "query", + "name": "limitBytes", + "description": "If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit.", + "required": false, + "allowMultiple": false + }, { "type": "string", "paramType": "path", @@ -6329,7 +6369,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/pods/{name}/portforward", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "string", @@ -6395,7 +6435,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/pods/{name}/proxy", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "string", @@ -6629,7 +6669,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/pods/{name}/proxy/{path:*}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "string", @@ -6664,7 +6704,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -6710,7 +6750,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -6756,7 +6796,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -6802,7 +6842,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -6848,7 +6888,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -6894,7 +6934,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -6911,7 +6951,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/pods/{name}/status", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Pod", @@ -6970,7 +7010,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/podtemplates", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PodTemplateList", @@ -7090,7 +7130,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/podtemplates", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -7165,7 +7205,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/podtemplates/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PodTemplate", @@ -7280,7 +7320,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -7321,7 +7361,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a PodTemplate", "nickname": "deleteNamespacedPodTemplate", @@ -7363,7 +7403,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -7377,7 +7417,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/podtemplates/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -7460,7 +7500,7 @@ }, { "path": "/api/v1/podtemplates", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.PodTemplateList", @@ -7564,7 +7604,7 @@ }, { "path": "/api/v1/watch/podtemplates", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -7631,7 +7671,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/replicationcontrollers", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ReplicationControllerList", @@ -7751,7 +7791,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/replicationcontrollers", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -7826,7 +7866,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/replicationcontrollers/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ReplicationController", @@ -7941,7 +7981,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -7982,7 +8022,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a ReplicationController", "nickname": "deleteNamespacedReplicationController", @@ -8024,7 +8064,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -8038,7 +8078,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/replicationcontrollers/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -8121,7 +8161,7 @@ }, { "path": "/api/v1/replicationcontrollers", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ReplicationControllerList", @@ -8225,7 +8265,7 @@ }, { "path": "/api/v1/watch/replicationcontrollers", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -8290,9 +8330,68 @@ } ] }, + { + "path": "/api/v1/namespaces/{namespace}/replicationcontrollers/{name}/status", + "description": "API at /api/v1", + "operations": [ + { + "type": "v1.ReplicationController", + "method": "PUT", + "summary": "replace status of the specified ReplicationController", + "nickname": "replaceNamespacedReplicationControllerStatus", + "parameters": [ + { + "type": "string", + "paramType": "query", + "name": "pretty", + "description": "If 'true', then the output is pretty printed.", + "required": false, + "allowMultiple": false + }, + { + "type": "v1.ReplicationController", + "paramType": "body", + "name": "body", + "description": "", + "required": true, + "allowMultiple": false + }, + { + "type": "string", + "paramType": "path", + "name": "namespace", + "description": "object name and auth scope, such as for teams and projects", + "required": true, + "allowMultiple": false + }, + { + "type": "string", + "paramType": "path", + "name": "name", + "description": "name of the ReplicationController", + "required": true, + "allowMultiple": false + } + ], + "responseMessages": [ + { + "code": 200, + "message": "OK", + "responseModel": "v1.ReplicationController" + } + ], + "produces": [ + "application/json" + ], + "consumes": [ + "*/*" + ] + } + ] + }, { "path": "/api/v1/namespaces/{namespace}/resourcequotas", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ResourceQuotaList", @@ -8412,7 +8511,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/resourcequotas", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -8487,7 +8586,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/resourcequotas/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ResourceQuota", @@ -8602,7 +8701,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -8643,7 +8742,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a ResourceQuota", "nickname": "deleteNamespacedResourceQuota", @@ -8685,7 +8784,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -8699,7 +8798,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/resourcequotas/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -8782,7 +8881,7 @@ }, { "path": "/api/v1/resourcequotas", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ResourceQuotaList", @@ -8886,7 +8985,7 @@ }, { "path": "/api/v1/watch/resourcequotas", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -8953,7 +9052,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/resourcequotas/{name}/status", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ResourceQuota", @@ -9012,7 +9111,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/secrets", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.SecretList", @@ -9132,7 +9231,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/secrets", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -9207,7 +9306,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/secrets/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Secret", @@ -9322,7 +9421,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -9363,7 +9462,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Secret", "nickname": "deleteNamespacedSecret", @@ -9405,7 +9504,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -9419,7 +9518,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/secrets/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -9502,7 +9601,7 @@ }, { "path": "/api/v1/secrets", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.SecretList", @@ -9606,7 +9705,7 @@ }, { "path": "/api/v1/watch/secrets", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -9673,7 +9772,7 @@ }, { "path": "/api/v1/securitycontextconstraints", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.SecurityContextConstraintsList", @@ -9777,7 +9876,7 @@ }, { "path": "/api/v1/watch/securitycontextconstraints", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -9844,7 +9943,7 @@ }, { "path": "/api/v1/securitycontextconstraints/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.SecurityContextConstraints", @@ -9943,7 +10042,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -9976,7 +10075,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a SecurityContextConstraints", "nickname": "deleteNamespacedSecurityContextConstraints", @@ -10010,7 +10109,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -10024,7 +10123,7 @@ }, { "path": "/api/v1/watch/securitycontextconstraints/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -10099,7 +10198,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/serviceaccounts", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ServiceAccountList", @@ -10219,7 +10318,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/serviceaccounts", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -10294,7 +10393,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/serviceaccounts/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ServiceAccount", @@ -10409,7 +10508,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -10450,7 +10549,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a ServiceAccount", "nickname": "deleteNamespacedServiceAccount", @@ -10492,7 +10591,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -10506,7 +10605,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/serviceaccounts/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -10589,7 +10688,7 @@ }, { "path": "/api/v1/serviceaccounts", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ServiceAccountList", @@ -10693,7 +10792,7 @@ }, { "path": "/api/v1/watch/serviceaccounts", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -10760,7 +10859,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/services", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ServiceList", @@ -10880,7 +10979,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/services", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -10955,7 +11054,7 @@ }, { "path": "/api/v1/namespaces/{namespace}/services/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.Service", @@ -11070,7 +11169,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -11111,7 +11210,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Service", "nickname": "deleteNamespacedService", @@ -11145,7 +11244,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -11159,7 +11258,7 @@ }, { "path": "/api/v1/watch/namespaces/{namespace}/services/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -11242,7 +11341,7 @@ }, { "path": "/api/v1/proxy/namespaces/{namespace}/services/{name}/{path:*}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "string", @@ -11269,7 +11368,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -11307,7 +11406,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -11345,7 +11444,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -11383,7 +11482,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -11421,7 +11520,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -11459,7 +11558,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -11476,7 +11575,7 @@ }, { "path": "/api/v1/proxy/namespaces/{namespace}/services/{name}", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "string", @@ -11662,7 +11761,7 @@ }, { "path": "/api/v1/services", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "v1.ServiceList", @@ -11766,7 +11865,7 @@ }, { "path": "/api/v1/watch/services", - "description": "API at /api/v1 version v1", + "description": "API at /api/v1", "operations": [ { "type": "json.WatchEvent", @@ -11830,6 +11929,25 @@ ] } ] + }, + { + "path": "/api/v1", + "description": "API at /api/v1", + "operations": [ + { + "type": "void", + "method": "GET", + "summary": "get available resources", + "nickname": "getAPIResources", + "parameters": [], + "produces": [ + "application/json" + ], + "consumes": [ + "application/json" + ] + } + ] } ], "models": { @@ -11842,11 +11960,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -11957,14 +12075,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -11976,9 +12094,9 @@ } } }, - "v1.ListMeta": { - "id": "v1.ListMeta", - "description": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects.", + "unversioned.ListMeta": { + "id": "unversioned.ListMeta", + "description": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.", "properties": { "selfLink": { "type": "string", @@ -11996,11 +12114,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -12050,14 +12168,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -12078,11 +12196,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -12093,7 +12211,7 @@ "items": { "$ref": "v1.EndpointSubset" }, - "description": "The set of all endpoints is the union of all subsets. Sets of addresses and ports that comprise a service." + "description": "The set of all endpoints is the union of all subsets. Addresses are placed into subsets according to the IPs they share. A single address with multiple ports, some of which are ready and some of which are not (because they come from different containers) will result in the address being displayed in different subsets for the different ports. No address will appear in both Addresses and NotReadyAddresses in the same subset. Sets of addresses and ports that comprise a service." } } }, @@ -12106,7 +12224,14 @@ "items": { "$ref": "v1.EndpointAddress" }, - "description": "IP addresses which offer the related ports." + "description": "IP addresses which offer the related ports that are marked as ready. These endpoints should be considered safe for load balancers and clients to utilize." + }, + "notReadyAddresses": { + "type": "array", + "items": { + "$ref": "v1.EndpointAddress" + }, + "description": "IP addresses which offer the related ports but are not currently marked as ready because they have not yet finished starting, have recently failed a readiness check, or have recently failed a liveness check." }, "ports": { "type": "array", @@ -12169,24 +12294,25 @@ } } }, - "api.Patch": { - "id": "api.Patch", + "unversioned.Patch": { + "id": "unversioned.Patch", + "description": "Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.", "properties": {} }, - "v1.Status": { - "id": "v1.Status", + "unversioned.Status": { + "id": "unversioned.Status", "description": "Status is a return value for calls that don't return other objects.", "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "status": { @@ -12202,8 +12328,8 @@ "description": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it." }, "details": { - "$ref": "v1.StatusDetails", - "description": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type." + "$ref": "unversioned.StatusDetails", + "description": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type." }, "code": { "type": "integer", @@ -12212,8 +12338,8 @@ } } }, - "v1.StatusDetails": { - "id": "v1.StatusDetails", + "unversioned.StatusDetails": { + "id": "unversioned.StatusDetails", "description": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.", "properties": { "name": { @@ -12227,7 +12353,7 @@ "causes": { "type": "array", "items": { - "$ref": "v1.StatusCause" + "$ref": "unversioned.StatusCause" }, "description": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes." }, @@ -12238,8 +12364,8 @@ } } }, - "v1.StatusCause": { - "id": "v1.StatusCause", + "unversioned.StatusCause": { + "id": "unversioned.StatusCause", "description": "StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.", "properties": { "reason": { @@ -12248,11 +12374,11 @@ }, "message": { "type": "string", - "description": "A human-readable description of the cause of the error. This field may be presented as-is to a reader." + "description": "A human-readable description of the cause of the error. This field may be presented as-is to a reader." }, "field": { "type": "string", - "description": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"" + "description": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"" } } }, @@ -12265,11 +12391,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "gracePeriodSeconds": { "type": "integer", @@ -12287,14 +12413,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -12316,11 +12442,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -12380,14 +12506,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -12405,11 +12531,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -12476,14 +12602,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -12501,11 +12627,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -12557,14 +12683,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -12582,11 +12708,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -12650,9 +12776,13 @@ }, "description": "List of addresses reachable to the node. Queried from cloud provider, if available. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-addresses" }, + "daemonEndpoints": { + "$ref": "v1.NodeDaemonEndpoints", + "description": "Endpoints of daemons running on the Node." + }, "nodeInfo": { "$ref": "v1.NodeSystemInfo", - "description": "NodeSystemInfo is a set of ids/uuids to uniquely identify the node. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-info" + "description": "Set of ids/uuids to uniquely identify the node. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-info" } } }, @@ -12708,6 +12838,30 @@ } } }, + "v1.NodeDaemonEndpoints": { + "id": "v1.NodeDaemonEndpoints", + "description": "NodeDaemonEndpoints lists ports opened by daemons running on the Node.", + "properties": { + "kubeletEndpoint": { + "$ref": "v1.DaemonEndpoint", + "description": "Endpoint on which Kubelet is listening." + } + } + }, + "v1.DaemonEndpoint": { + "id": "v1.DaemonEndpoint", + "description": "DaemonEndpoint contains information about a single Daemon endpoint.", + "required": [ + "Port" + ], + "properties": { + "Port": { + "type": "integer", + "format": "int32", + "description": "Port number of the given endpoint." + } + } + }, "v1.NodeSystemInfo": { "id": "v1.NodeSystemInfo", "description": "NodeSystemInfo is a set of ids/uuids to uniquely identify the node.", @@ -12724,35 +12878,35 @@ "properties": { "machineID": { "type": "string", - "description": "MachineID is the machine-id reported by the node." + "description": "Machine ID reported by the node." }, "systemUUID": { "type": "string", - "description": "SystemUUID is the system-uuid reported by the node." + "description": "System UUID reported by the node." }, "bootID": { "type": "string", - "description": "BootID is the boot-id reported by the node." + "description": "Boot ID reported by the node." }, "kernelVersion": { "type": "string", - "description": "Kernel version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64)" + "description": "Kernel Version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64)." }, "osImage": { "type": "string", - "description": "OS image used reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy))" + "description": "OS Image reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy))." }, "containerRuntimeVersion": { "type": "string", - "description": "Container runtime version reported by the node through runtime remote API (e.g. docker://1.5.0)" + "description": "ContainerRuntime Version reported by the node through runtime remote API (e.g. docker://1.5.0)." }, "kubeletVersion": { "type": "string", - "description": "Kubelet version reported by the node." + "description": "Kubelet Version reported by the node." }, "kubeProxyVersion": { "type": "string", - "description": "Kube-proxy version reported by the node." + "description": "KubeProxy Version reported by the node." } } }, @@ -12765,14 +12919,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -12790,11 +12944,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -12879,14 +13033,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -12904,11 +13058,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -12942,7 +13096,7 @@ }, "hostPath": { "$ref": "v1.HostPathVolumeSource", - "description": "HostPath represents a directory on the host. Provisioned by a developer or tester. This is useful for development and testing only. On-host storage is not supported in any way. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath" + "description": "HostPath represents a directory on the host. Provisioned by a developer or tester. This is useful for single-node development and testing only! On-host storage is not supported in any way and WILL NOT WORK in a multi-node cluster. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath" }, "glusterfs": { "$ref": "v1.GlusterfsVolumeSource", @@ -12968,6 +13122,14 @@ "$ref": "v1.CephFSVolumeSource", "description": "CephFS represents a Ceph FS mount on the host that shares a pod's lifetime" }, + "fc": { + "$ref": "v1.FCVolumeSource", + "description": "FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod." + }, + "flocker": { + "$ref": "v1.FlockerVolumeSource", + "description": "Flocker represents a Flocker volume attached to a kubelet's host machine and exposed to the pod for its usage. This depends on the Flocker control service being running" + }, "accessModes": { "type": "array", "items": { @@ -13241,6 +13403,50 @@ } } }, + "v1.FCVolumeSource": { + "id": "v1.FCVolumeSource", + "description": "A Fibre Channel Disk can only be mounted as read/write once.", + "required": [ + "targetWWNs", + "lun", + "fsType" + ], + "properties": { + "targetWWNs": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Required: FC target world wide names (WWNs)" + }, + "lun": { + "type": "integer", + "format": "int32", + "description": "Required: FC target lun number" + }, + "fsType": { + "type": "string", + "description": "Required: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\"" + }, + "readOnly": { + "type": "boolean", + "description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts." + } + } + }, + "v1.FlockerVolumeSource": { + "id": "v1.FlockerVolumeSource", + "description": "FlockerVolumeSource represents a Flocker volume mounted by the Flocker agent.", + "required": [ + "datasetName" + ], + "properties": { + "datasetName": { + "type": "string", + "description": "Required: the volume name. This is going to be store on metadata -\u003e name on the payload for Flocker" + } + } + }, "v1.PersistentVolumeStatus": { "id": "v1.PersistentVolumeStatus", "description": "PersistentVolumeStatus is the current status of a persistent volume.", @@ -13268,14 +13474,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -13293,11 +13499,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -13384,6 +13590,10 @@ "type": "boolean", "description": "Use the host's ipc namespace. Optional: Default to false." }, + "securityContext": { + "$ref": "v1.PodSecurityContext", + "description": "SecurityContext holds pod-level security attributes and common container settings" + }, "imagePullSecrets": { "type": "array", "items": { @@ -13456,10 +13666,18 @@ "$ref": "v1.CephFSVolumeSource", "description": "CephFS represents a Ceph FS mount on the host that shares a pod's lifetime" }, + "flocker": { + "$ref": "v1.FlockerVolumeSource", + "description": "Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running" + }, "downwardAPI": { "$ref": "v1.DownwardAPIVolumeSource", "description": "DownwardAPI represents downward API about the pod that should populate this volume" }, + "fc": { + "$ref": "v1.FCVolumeSource", + "description": "FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod." + }, "metadata": { "$ref": "v1.MetadataVolumeSource" } @@ -13963,6 +14181,11 @@ } } }, + "v1.PodSecurityContext": { + "id": "v1.PodSecurityContext", + "description": "PodSecurityContext holds pod-level security attributes and common container settings.", + "properties": {} + }, "v1.PodStatus": { "id": "v1.PodStatus", "description": "PodStatus represents information about the status of a pod. Status may trail the actual state of a system.", @@ -14022,6 +14245,22 @@ "status": { "type": "string", "description": "Status is the status of the condition. Can be True, False, Unknown. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions" + }, + "lastProbeTime": { + "type": "string", + "description": "Last time we probed the condition." + }, + "lastTransitionTime": { + "type": "string", + "description": "Last time the condition transitioned from one status to another." + }, + "reason": { + "type": "string", + "description": "Unique, one-word, CamelCase reason for the condition's last transition." + }, + "message": { + "type": "string", + "description": "Human-readable message indicating details about last transition." } } }, @@ -14161,14 +14400,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -14186,11 +14425,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -14225,14 +14464,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -14250,11 +14489,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -14317,14 +14556,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -14342,11 +14581,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -14395,14 +14634,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -14420,11 +14659,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -14448,14 +14687,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -14479,11 +14718,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -14644,14 +14883,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -14669,11 +14908,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -14704,14 +14943,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "items": { @@ -14729,11 +14968,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta", @@ -14784,7 +15023,14 @@ "items": { "type": "string" }, - "description": "ExternalIPs are used by external load balancers, or can be set by users to handle external traffic that arrives at a node. Externally visible IPs (e.g. load balancers) that should be proxied to this service." + "description": "externalIPs is a list of IP addresses for which nodes in the cluster will also accept traffic for this service. These IPs are not managed by Kubernetes. The user is responsible for ensuring that traffic arrives at a node with this IP. A common example is external load-balancers that are not part of the Kubernetes system. A previous form of this functionality exists as the deprecatedPublicIPs field. When using this field, callers should also clear the deprecatedPublicIPs field." + }, + "deprecatedPublicIPs": { + "type": "array", + "items": { + "type": "string" + }, + "description": "deprecatedPublicIPs is deprecated and replaced by the externalIPs field with almost the exact same semantics. This field is retained in the v1 API for compatibility until at least 8/20/2016. It will be removed from any new API revisions. If both deprecatedPublicIPs *and* externalIPs are set, deprecatedPublicIPs is used." }, "sessionAffinity": { "type": "string", diff --git a/api/swagger-spec/oapi-v1.json b/api/swagger-spec/oapi-v1.json index d80581b2cca4..6d478756b69a 100644 --- a/api/swagger-spec/oapi-v1.json +++ b/api/swagger-spec/oapi-v1.json @@ -320,7 +320,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -361,7 +361,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a BuildConfig", "nickname": "deleteNamespacedBuildConfig", @@ -403,7 +403,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -809,7 +809,7 @@ { "type": "string", "paramType": "path", - "name": "path:*", + "name": "path", "description": "path to the resource", "required": true, "allowMultiple": false @@ -1136,7 +1136,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -1177,7 +1177,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Build", "nickname": "deleteNamespacedBuild", @@ -1219,7 +1219,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -1883,7 +1883,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -1916,7 +1916,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a ClusterNetwork", "nickname": "deleteNamespacedClusterNetwork", @@ -1950,7 +1950,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -2309,7 +2309,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -2342,7 +2342,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a ClusterPolicy", "nickname": "deleteNamespacedClusterPolicy", @@ -2376,7 +2376,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -2735,7 +2735,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -2768,7 +2768,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a ClusterPolicyBinding", "nickname": "deleteNamespacedClusterPolicyBinding", @@ -2802,7 +2802,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -3094,7 +3094,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -3127,7 +3127,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a ClusterRoleBinding", "nickname": "deleteNamespacedClusterRoleBinding", @@ -3161,7 +3161,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -3378,7 +3378,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -3411,7 +3411,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a ClusterRole", "nickname": "deleteNamespacedClusterRole", @@ -3445,7 +3445,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -3863,7 +3863,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -3904,7 +3904,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a DeploymentConfig", "nickname": "deleteNamespacedDeploymentConfig", @@ -3946,7 +3946,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -4535,7 +4535,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -4568,7 +4568,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Group", "nickname": "deleteNamespacedGroup", @@ -4602,7 +4602,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -4961,7 +4961,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -4994,7 +4994,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a HostSubnet", "nickname": "deleteNamespacedHostSubnet", @@ -5028,7 +5028,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -5387,7 +5387,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -5420,7 +5420,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Identity", "nickname": "deleteNamespacedIdentity", @@ -5454,7 +5454,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -5813,7 +5813,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -5846,7 +5846,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Image", "nickname": "deleteNamespacedImage", @@ -5880,7 +5880,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -6424,7 +6424,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -6465,7 +6465,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a ImageStream", "nickname": "deleteNamespacedImageStream", @@ -6507,7 +6507,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -6882,7 +6882,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a ImageStreamTag", "nickname": "deleteNamespacedImageStreamTag", @@ -6916,7 +6916,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -7388,7 +7388,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -7421,7 +7421,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a NetNamespace", "nickname": "deleteNamespacedNetNamespace", @@ -7455,7 +7455,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -7688,7 +7688,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a OAuthAccessToken", "nickname": "deleteNamespacedOAuthAccessToken", @@ -7722,7 +7722,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -7880,7 +7880,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a OAuthAuthorizeToken", "nickname": "deleteNamespacedOAuthAuthorizeToken", @@ -7914,7 +7914,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -8198,7 +8198,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -8231,7 +8231,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a OAuthClientAuthorization", "nickname": "deleteNamespacedOAuthClientAuthorization", @@ -8265,7 +8265,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -8624,7 +8624,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -8657,7 +8657,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a OAuthClient", "nickname": "deleteNamespacedOAuthClient", @@ -8691,7 +8691,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -9090,7 +9090,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -9131,7 +9131,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Policy", "nickname": "deleteNamespacedPolicy", @@ -9173,7 +9173,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -9751,7 +9751,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -9792,7 +9792,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a PolicyBinding", "nickname": "deleteNamespacedPolicyBinding", @@ -9834,7 +9834,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -10199,7 +10199,7 @@ "description": "OpenShift REST API, version v1", "operations": [ { - "type": "v1.Status", + "type": "unversioned.Status", "method": "GET", "summary": "list objects of kind ProjectRequest", "nickname": "listNamespacedProjectRequest", @@ -10249,7 +10249,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -10503,7 +10503,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -10536,7 +10536,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Project", "nickname": "deleteNamespacedProject", @@ -10562,7 +10562,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -10905,7 +10905,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -10946,7 +10946,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a RoleBinding", "nickname": "deleteNamespacedRoleBinding", @@ -10988,7 +10988,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -11341,7 +11341,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -11382,7 +11382,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Role", "nickname": "deleteNamespacedRole", @@ -11424,7 +11424,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -11852,7 +11852,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -11893,7 +11893,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Route", "nickname": "deleteNamespacedRoute", @@ -11935,7 +11935,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -12666,7 +12666,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -12707,7 +12707,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a Template", "nickname": "deleteNamespacedTemplate", @@ -12749,7 +12749,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -13159,7 +13159,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -13192,7 +13192,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a UserIdentityMapping", "nickname": "deleteNamespacedUserIdentityMapping", @@ -13218,7 +13218,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -13502,7 +13502,7 @@ "allowMultiple": false }, { - "type": "api.Patch", + "type": "unversioned.Patch", "paramType": "body", "name": "body", "description": "", @@ -13535,7 +13535,7 @@ ] }, { - "type": "v1.Status", + "type": "unversioned.Status", "method": "DELETE", "summary": "delete a User", "nickname": "deleteNamespacedUser", @@ -13569,7 +13569,7 @@ { "code": 200, "message": "OK", - "responseModel": "v1.Status" + "responseModel": "unversioned.Status" } ], "produces": [ @@ -13655,6 +13655,25 @@ ] } ] + }, + { + "path": "/oapi/v1", + "description": "OpenShift REST API, version v1", + "operations": [ + { + "type": "void", + "method": "GET", + "summary": "get available resources", + "nickname": "getAPIResources", + "parameters": [], + "produces": [ + "application/json" + ], + "consumes": [ + "application/json" + ] + } + ] } ], "models": { @@ -13666,14 +13685,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -13684,9 +13703,9 @@ } } }, - "v1.ListMeta": { - "id": "v1.ListMeta", - "description": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects.", + "unversioned.ListMeta": { + "id": "unversioned.ListMeta", + "description": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.", "properties": { "selfLink": { "type": "string", @@ -13707,11 +13726,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -14265,24 +14284,25 @@ } } }, - "api.Patch": { - "id": "api.Patch", + "unversioned.Patch": { + "id": "unversioned.Patch", + "description": "Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.", "properties": {} }, - "v1.Status": { - "id": "v1.Status", + "unversioned.Status": { + "id": "unversioned.Status", "description": "Status is a return value for calls that don't return other objects.", "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta", + "$ref": "unversioned.ListMeta", "description": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "status": { @@ -14298,8 +14318,8 @@ "description": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it." }, "details": { - "$ref": "v1.StatusDetails", - "description": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type." + "$ref": "unversioned.StatusDetails", + "description": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type." }, "code": { "type": "integer", @@ -14308,8 +14328,8 @@ } } }, - "v1.StatusDetails": { - "id": "v1.StatusDetails", + "unversioned.StatusDetails": { + "id": "unversioned.StatusDetails", "description": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.", "properties": { "name": { @@ -14323,7 +14343,7 @@ "causes": { "type": "array", "items": { - "$ref": "v1.StatusCause" + "$ref": "unversioned.StatusCause" }, "description": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes." }, @@ -14334,8 +14354,8 @@ } } }, - "v1.StatusCause": { - "id": "v1.StatusCause", + "unversioned.StatusCause": { + "id": "unversioned.StatusCause", "description": "StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.", "properties": { "reason": { @@ -14344,11 +14364,11 @@ }, "message": { "type": "string", - "description": "A human-readable description of the cause of the error. This field may be presented as-is to a reader." + "description": "A human-readable description of the cause of the error. This field may be presented as-is to a reader." }, "field": { "type": "string", - "description": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"" + "description": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"" } } }, @@ -14361,11 +14381,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "gracePeriodSeconds": { "type": "integer", @@ -14379,11 +14399,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -14415,14 +14435,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -14438,11 +14458,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -14539,14 +14559,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" } } }, @@ -14558,14 +14578,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -14586,11 +14606,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -14618,14 +14638,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -14645,11 +14665,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -14692,11 +14712,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -14767,14 +14787,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -14795,11 +14815,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -14849,11 +14869,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -14893,14 +14913,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -14919,14 +14939,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -14946,11 +14966,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "spec": { "$ref": "v1.DeploymentConfigRollbackSpec", @@ -14998,14 +15018,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -15025,11 +15045,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -15356,6 +15376,10 @@ "type": "boolean", "description": "Use the host's ipc namespace. Optional: Default to false." }, + "securityContext": { + "$ref": "v1.PodSecurityContext", + "description": "SecurityContext holds pod-level security attributes and common container settings" + }, "imagePullSecrets": { "type": "array", "items": { @@ -15428,10 +15452,18 @@ "$ref": "v1.CephFSVolumeSource", "description": "CephFS represents a Ceph FS mount on the host that shares a pod's lifetime" }, + "flocker": { + "$ref": "v1.FlockerVolumeSource", + "description": "Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running" + }, "downwardAPI": { "$ref": "v1.DownwardAPIVolumeSource", "description": "DownwardAPI represents downward API about the pod that should populate this volume" }, + "fc": { + "$ref": "v1.FCVolumeSource", + "description": "FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod." + }, "metadata": { "$ref": "v1.MetadataVolumeSource" } @@ -15741,6 +15773,19 @@ } } }, + "v1.FlockerVolumeSource": { + "id": "v1.FlockerVolumeSource", + "description": "FlockerVolumeSource represents a Flocker volume mounted by the Flocker agent.", + "required": [ + "datasetName" + ], + "properties": { + "datasetName": { + "type": "string", + "description": "Required: the volume name. This is going to be store on metadata -\u003e name on the payload for Flocker" + } + } + }, "v1.DownwardAPIVolumeSource": { "id": "v1.DownwardAPIVolumeSource", "description": "DownwardAPIVolumeSource represents a volume containing downward API info", @@ -15772,6 +15817,37 @@ } } }, + "v1.FCVolumeSource": { + "id": "v1.FCVolumeSource", + "description": "A Fibre Channel Disk can only be mounted as read/write once.", + "required": [ + "targetWWNs", + "lun", + "fsType" + ], + "properties": { + "targetWWNs": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Required: FC target world wide names (WWNs)" + }, + "lun": { + "type": "integer", + "format": "int32", + "description": "Required: FC target lun number" + }, + "fsType": { + "type": "string", + "description": "Required: Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\"" + }, + "readOnly": { + "type": "boolean", + "description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts." + } + } + }, "v1.MetadataVolumeSource": { "id": "v1.MetadataVolumeSource", "properties": { @@ -16130,6 +16206,11 @@ } } }, + "v1.PodSecurityContext": { + "id": "v1.PodSecurityContext", + "description": "PodSecurityContext holds pod-level security attributes and common container settings.", + "properties": {} + }, "v1.DeploymentConfigStatus": { "id": "v1.DeploymentConfigStatus", "properties": { @@ -16196,14 +16277,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -16222,11 +16303,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -16248,14 +16329,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -16276,11 +16357,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -16307,14 +16388,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -16335,11 +16416,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -16370,14 +16451,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -16393,11 +16474,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -16428,11 +16509,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -16452,11 +16533,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -16479,14 +16560,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -16505,11 +16586,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -16629,11 +16710,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -16656,11 +16737,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "namespace": { "type": "string", @@ -16698,11 +16779,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "namespace": { "type": "string", @@ -16745,14 +16826,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -16772,11 +16853,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -16799,14 +16880,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -16822,11 +16903,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -16877,14 +16958,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -16900,11 +16981,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -16951,14 +17032,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -16974,11 +17055,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -17012,14 +17093,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -17035,11 +17116,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -17069,14 +17150,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -17096,11 +17177,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -17143,11 +17224,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -17169,14 +17250,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -17197,11 +17278,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -17251,11 +17332,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -17295,11 +17376,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -17374,11 +17455,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -17401,14 +17482,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -17424,11 +17505,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -17480,11 +17561,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "namespace": { "type": "string", @@ -17516,14 +17597,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -17542,14 +17623,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -17568,14 +17649,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -17595,11 +17676,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -17698,11 +17779,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "namespace": { "type": "string", @@ -17745,14 +17826,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -17768,11 +17849,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" @@ -17795,14 +17876,14 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { - "$ref": "v1.ListMeta" + "$ref": "unversioned.ListMeta" }, "items": { "type": "array", @@ -17822,11 +17903,11 @@ "properties": { "kind": { "type": "string", - "description": "A string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" }, "apiVersion": { "type": "string", - "description": "APIVersion defines the version of the schema of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources" }, "metadata": { "$ref": "v1.ObjectMeta" diff --git a/contrib/completions/bash/oadm b/contrib/completions/bash/oadm index fff1b76c6184..17751c41be33 100644 --- a/contrib/completions/bash/oadm +++ b/contrib/completions/bash/oadm @@ -1368,6 +1368,7 @@ _oadm() flags+=("--ir-data-source=") flags+=("--ir-dbname=") flags+=("--ir-influxdb-host=") + flags+=("--ir-namespace-only") flags+=("--ir-password=") flags+=("--ir-percentile=") flags+=("--ir-user=") diff --git a/contrib/completions/bash/oc b/contrib/completions/bash/oc index 080953832874..ef2c6c00db88 100644 --- a/contrib/completions/bash/oc +++ b/contrib/completions/bash/oc @@ -615,6 +615,7 @@ _oc_get() must_have_one_noun+=("clusterrole") must_have_one_noun+=("clusterrolebinding") must_have_one_noun+=("componentstatus") + must_have_one_noun+=("daemonset") must_have_one_noun+=("deployment") must_have_one_noun+=("deploymentconfig") must_have_one_noun+=("endpoints") @@ -627,7 +628,9 @@ _oc_get() must_have_one_noun+=("imagestream") must_have_one_noun+=("imagestreamimage") must_have_one_noun+=("imagestreamtag") + must_have_one_noun+=("ingress") must_have_one_noun+=("ispersonalsubjectaccessreview") + must_have_one_noun+=("job") must_have_one_noun+=("limitrange") must_have_one_noun+=("namespace") must_have_one_noun+=("netnamespace") @@ -861,6 +864,7 @@ _oc_label() must_have_one_noun+=("clusterrole") must_have_one_noun+=("clusterrolebinding") must_have_one_noun+=("componentstatus") + must_have_one_noun+=("daemonset") must_have_one_noun+=("deployment") must_have_one_noun+=("deploymentconfig") must_have_one_noun+=("endpoints") @@ -873,7 +877,9 @@ _oc_label() must_have_one_noun+=("imagestream") must_have_one_noun+=("imagestreamimage") must_have_one_noun+=("imagestreamtag") + must_have_one_noun+=("ingress") must_have_one_noun+=("ispersonalsubjectaccessreview") + must_have_one_noun+=("job") must_have_one_noun+=("limitrange") must_have_one_noun+=("namespace") must_have_one_noun+=("netnamespace") @@ -1040,6 +1046,7 @@ _oc_delete() must_have_one_noun+=("clusterrole") must_have_one_noun+=("clusterrolebinding") must_have_one_noun+=("componentstatus") + must_have_one_noun+=("daemonset") must_have_one_noun+=("deployment") must_have_one_noun+=("deploymentconfig") must_have_one_noun+=("endpoints") @@ -1052,7 +1059,9 @@ _oc_delete() must_have_one_noun+=("imagestream") must_have_one_noun+=("imagestreamimage") must_have_one_noun+=("imagestreamtag") + must_have_one_noun+=("ingress") must_have_one_noun+=("ispersonalsubjectaccessreview") + must_have_one_noun+=("job") must_have_one_noun+=("limitrange") must_have_one_noun+=("namespace") must_have_one_noun+=("netnamespace") @@ -1083,6 +1092,22 @@ _oc_delete() must_have_one_noun+=("useridentitymapping") } +_oc_explain() +{ + last_command="oc_explain" + commands=() + + flags=() + two_word_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--recursive") + + must_have_one_flag=() + must_have_one_noun=() +} + _oc_logs() { last_command="oc_logs" @@ -1098,8 +1123,13 @@ _oc_logs() flags+=("--follow") flags+=("-f") flags+=("--interactive") + flags+=("--limit-bytes=") flags+=("--previous") flags+=("-p") + flags+=("--since=") + flags+=("--since-time=") + flags+=("--tail=") + flags+=("--timestamps") must_have_one_flag=() must_have_one_noun=() @@ -1200,6 +1230,7 @@ _oc_proxy() flags+=("--accept-hosts=") flags+=("--accept-paths=") + flags+=("--address=") flags+=("--api-prefix=") flags+=("--disable-filter") flags+=("--port=") @@ -1275,6 +1306,33 @@ _oc_replace() must_have_one_noun=() } +_oc_apply() +{ + last_command="oc_apply" + commands=() + + flags=() + two_word_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + flags+=("--output=") + two_word_flags+=("-o") + flags+=("--schema-cache-dir=") + flags+=("--validate") + + must_have_one_flag=() + must_have_one_flag+=("--filename=") + must_have_one_flag+=("-f") + must_have_one_noun=() +} + _oc_patch() { last_command="oc_patch" @@ -1725,6 +1783,41 @@ _oc_secrets() must_have_one_noun=() } +_oc_convert() +{ + last_command="oc_convert" + commands=() + + flags=() + two_word_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + flags+=("--local") + flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + flags+=("--output-version=") + flags+=("--schema-cache-dir=") + flags+=("--show-all") + flags+=("-a") + flags+=("--sort-by=") + flags+=("--template=") + two_word_flags+=("-t") + flags+=("--validate") + + must_have_one_flag=() + must_have_one_flag+=("--filename=") + must_have_one_flag+=("-f") + must_have_one_noun=() +} + _oc_logout() { last_command="oc_logout" @@ -1958,6 +2051,7 @@ _oc() commands+=("expose") commands+=("stop") commands+=("delete") + commands+=("explain") commands+=("logs") commands+=("rsh") commands+=("rsync") @@ -1966,6 +2060,7 @@ _oc() commands+=("proxy") commands+=("create") commands+=("replace") + commands+=("apply") commands+=("patch") commands+=("process") commands+=("export") @@ -1973,6 +2068,7 @@ _oc() commands+=("attach") commands+=("policy") commands+=("secrets") + commands+=("convert") commands+=("logout") commands+=("config") commands+=("whoami") @@ -2008,6 +2104,7 @@ _oc() flags+=("--ir-data-source=") flags+=("--ir-dbname=") flags+=("--ir-influxdb-host=") + flags+=("--ir-namespace-only") flags+=("--ir-password=") flags+=("--ir-percentile=") flags+=("--ir-user=") diff --git a/contrib/completions/bash/openshift b/contrib/completions/bash/openshift index 30415b51c604..4cb64d720b4a 100644 --- a/contrib/completions/bash/openshift +++ b/contrib/completions/bash/openshift @@ -316,11 +316,11 @@ _openshift_start_kubernetes_apiserver() flags+=("--etcd-config=") flags+=("--etcd-prefix=") flags+=("--etcd-servers=") + flags+=("--etcd-servers-overrides=") flags+=("--event-storage-age-limit=") flags+=("--event-storage-event-limit=") flags+=("--event-ttl=") flags+=("--experimental-keystone-url=") - flags+=("--experimental-prefix=") flags+=("--external-hostname=") flags+=("--global-housekeeping-interval=") flags+=("--housekeeping-interval=") @@ -330,6 +330,7 @@ _openshift_start_kubernetes_apiserver() flags+=("--ir-data-source=") flags+=("--ir-dbname=") flags+=("--ir-influxdb-host=") + flags+=("--ir-namespace-only") flags+=("--ir-password=") flags+=("--ir-percentile=") flags+=("--ir-user=") @@ -358,6 +359,7 @@ _openshift_start_kubernetes_apiserver() flags+=("--portal-net=") flags+=("--profiling") flags+=("--public-address-override=") + flags+=("--repair-malformed-updates") flags+=("--runtime-config=") flags+=("--secure-port=") flags+=("--service-account-key-file=") @@ -369,6 +371,7 @@ _openshift_start_kubernetes_apiserver() flags+=("--ssh-user=") flags+=("--stderrthreshold=") flags+=("--storage-version=") + flags+=("--storage-versions=") flags+=("--tls-cert-file=") flags+=("--tls-private-key-file=") flags+=("--token-auth-file=") @@ -403,11 +406,12 @@ _openshift_start_kubernetes_controller-manager() flags+=("--container-hints=") flags+=("--deleting-pods-burst=") flags+=("--deleting-pods-qps=") + flags+=("--deployment-controller-sync-period=") flags+=("--docker=") flags+=("--docker-only") flags+=("--docker-root=") flags+=("--docker-run=") - flags+=("--enable-horizontal-pod-autoscaler") + flags+=("--enable-experimental") flags+=("--enable-load-reader") flags+=("--event-storage-age-limit=") flags+=("--event-storage-event-limit=") @@ -418,9 +422,12 @@ _openshift_start_kubernetes_controller-manager() flags+=("--ir-data-source=") flags+=("--ir-dbname=") flags+=("--ir-influxdb-host=") + flags+=("--ir-namespace-only") flags+=("--ir-password=") flags+=("--ir-percentile=") flags+=("--ir-user=") + flags+=("--kube-api-burst=") + flags+=("--kube-api-qps=") flags+=("--kubeconfig=") flags+=("--log-backtrace-at=") flags+=("--log-cadvisor-usage") @@ -428,6 +435,7 @@ _openshift_start_kubernetes_controller-manager() flags+=("--logtostderr") flags+=("--machine-id-file=") flags+=("--master=") + flags+=("--min-resync-period=") flags+=("--namespace-sync-period=") flags+=("--node-monitor-grace-period=") flags+=("--node-monitor-period=") @@ -449,6 +457,7 @@ _openshift_start_kubernetes_controller-manager() flags+=("--service-account-private-key-file=") flags+=("--service-sync-period=") flags+=("--stderrthreshold=") + flags+=("--terminated-pod-gc-threshold=") flags+=("--v=") flags+=("--vmodule=") @@ -515,9 +524,12 @@ _openshift_start_kubernetes_kubelet() flags+=("--ir-data-source=") flags+=("--ir-dbname=") flags+=("--ir-influxdb-host=") + flags+=("--ir-namespace-only") flags+=("--ir-password=") flags+=("--ir-percentile=") flags+=("--ir-user=") + flags+=("--kube-api-burst=") + flags+=("--kube-api-qps=") flags+=("--kubeconfig=") flags+=("--log-backtrace-at=") flags+=("--log-cadvisor-usage") @@ -528,6 +540,7 @@ _openshift_start_kubernetes_kubelet() flags+=("--manifest-url=") flags+=("--manifest-url-header=") flags+=("--master-service-namespace=") + flags+=("--max-open-files=") flags+=("--max-pods=") flags+=("--maximum-dead-containers=") flags+=("--maximum-dead-containers-per-container=") @@ -541,7 +554,9 @@ _openshift_start_kubernetes_kubelet() flags+=("--port=") flags+=("--read-only-port=") flags+=("--really-crash-for-testing") + flags+=("--reconcile-cidr") flags+=("--register-node") + flags+=("--register-schedulable") flags+=("--registry-burst=") flags+=("--registry-qps=") flags+=("--resolv-conf=") @@ -595,11 +610,13 @@ _openshift_start_kubernetes_proxy() flags+=("--ir-data-source=") flags+=("--ir-dbname=") flags+=("--ir-influxdb-host=") + flags+=("--ir-namespace-only") flags+=("--ir-password=") flags+=("--ir-percentile=") flags+=("--ir-user=") + flags+=("--kube-api-burst=") + flags+=("--kube-api-qps=") flags+=("--kubeconfig=") - flags+=("--legacy-userspace-proxy") flags+=("--log-backtrace-at=") flags+=("--log-cadvisor-usage") flags+=("--log-dir=") @@ -608,6 +625,7 @@ _openshift_start_kubernetes_proxy() flags+=("--masquerade-all") flags+=("--master=") flags+=("--oom-score-adj=") + flags+=("--proxy-mode=") flags+=("--proxy-port-range=") flags+=("--resource-container=") flags+=("--stderrthreshold=") @@ -648,9 +666,12 @@ _openshift_start_kubernetes_scheduler() flags+=("--ir-data-source=") flags+=("--ir-dbname=") flags+=("--ir-influxdb-host=") + flags+=("--ir-namespace-only") flags+=("--ir-password=") flags+=("--ir-percentile=") flags+=("--ir-user=") + flags+=("--kube-api-burst=") + flags+=("--kube-api-qps=") flags+=("--kubeconfig=") flags+=("--log-backtrace-at=") flags+=("--log-cadvisor-usage") @@ -1935,6 +1956,7 @@ _openshift_admin() flags+=("--ir-data-source=") flags+=("--ir-dbname=") flags+=("--ir-influxdb-host=") + flags+=("--ir-namespace-only") flags+=("--ir-password=") flags+=("--ir-percentile=") flags+=("--ir-user=") @@ -2332,6 +2354,7 @@ _openshift_cli_get() must_have_one_noun+=("clusterrole") must_have_one_noun+=("clusterrolebinding") must_have_one_noun+=("componentstatus") + must_have_one_noun+=("daemonset") must_have_one_noun+=("deployment") must_have_one_noun+=("deploymentconfig") must_have_one_noun+=("endpoints") @@ -2344,7 +2367,9 @@ _openshift_cli_get() must_have_one_noun+=("imagestream") must_have_one_noun+=("imagestreamimage") must_have_one_noun+=("imagestreamtag") + must_have_one_noun+=("ingress") must_have_one_noun+=("ispersonalsubjectaccessreview") + must_have_one_noun+=("job") must_have_one_noun+=("limitrange") must_have_one_noun+=("namespace") must_have_one_noun+=("netnamespace") @@ -2578,6 +2603,7 @@ _openshift_cli_label() must_have_one_noun+=("clusterrole") must_have_one_noun+=("clusterrolebinding") must_have_one_noun+=("componentstatus") + must_have_one_noun+=("daemonset") must_have_one_noun+=("deployment") must_have_one_noun+=("deploymentconfig") must_have_one_noun+=("endpoints") @@ -2590,7 +2616,9 @@ _openshift_cli_label() must_have_one_noun+=("imagestream") must_have_one_noun+=("imagestreamimage") must_have_one_noun+=("imagestreamtag") + must_have_one_noun+=("ingress") must_have_one_noun+=("ispersonalsubjectaccessreview") + must_have_one_noun+=("job") must_have_one_noun+=("limitrange") must_have_one_noun+=("namespace") must_have_one_noun+=("netnamespace") @@ -2757,6 +2785,7 @@ _openshift_cli_delete() must_have_one_noun+=("clusterrole") must_have_one_noun+=("clusterrolebinding") must_have_one_noun+=("componentstatus") + must_have_one_noun+=("daemonset") must_have_one_noun+=("deployment") must_have_one_noun+=("deploymentconfig") must_have_one_noun+=("endpoints") @@ -2769,7 +2798,9 @@ _openshift_cli_delete() must_have_one_noun+=("imagestream") must_have_one_noun+=("imagestreamimage") must_have_one_noun+=("imagestreamtag") + must_have_one_noun+=("ingress") must_have_one_noun+=("ispersonalsubjectaccessreview") + must_have_one_noun+=("job") must_have_one_noun+=("limitrange") must_have_one_noun+=("namespace") must_have_one_noun+=("netnamespace") @@ -2800,6 +2831,22 @@ _openshift_cli_delete() must_have_one_noun+=("useridentitymapping") } +_openshift_cli_explain() +{ + last_command="openshift_cli_explain" + commands=() + + flags=() + two_word_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--recursive") + + must_have_one_flag=() + must_have_one_noun=() +} + _openshift_cli_logs() { last_command="openshift_cli_logs" @@ -2815,8 +2862,13 @@ _openshift_cli_logs() flags+=("--follow") flags+=("-f") flags+=("--interactive") + flags+=("--limit-bytes=") flags+=("--previous") flags+=("-p") + flags+=("--since=") + flags+=("--since-time=") + flags+=("--tail=") + flags+=("--timestamps") must_have_one_flag=() must_have_one_noun=() @@ -2917,6 +2969,7 @@ _openshift_cli_proxy() flags+=("--accept-hosts=") flags+=("--accept-paths=") + flags+=("--address=") flags+=("--api-prefix=") flags+=("--disable-filter") flags+=("--port=") @@ -2992,6 +3045,33 @@ _openshift_cli_replace() must_have_one_noun=() } +_openshift_cli_apply() +{ + last_command="openshift_cli_apply" + commands=() + + flags=() + two_word_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + flags+=("--output=") + two_word_flags+=("-o") + flags+=("--schema-cache-dir=") + flags+=("--validate") + + must_have_one_flag=() + must_have_one_flag+=("--filename=") + must_have_one_flag+=("-f") + must_have_one_noun=() +} + _openshift_cli_patch() { last_command="openshift_cli_patch" @@ -3442,6 +3522,41 @@ _openshift_cli_secrets() must_have_one_noun=() } +_openshift_cli_convert() +{ + last_command="openshift_cli_convert" + commands=() + + flags=() + two_word_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + flags+=("--local") + flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + flags+=("--output-version=") + flags+=("--schema-cache-dir=") + flags+=("--show-all") + flags+=("-a") + flags+=("--sort-by=") + flags+=("--template=") + two_word_flags+=("-t") + flags+=("--validate") + + must_have_one_flag=() + must_have_one_flag+=("--filename=") + must_have_one_flag+=("-f") + must_have_one_noun=() +} + _openshift_cli_logout() { last_command="openshift_cli_logout" @@ -3675,6 +3790,7 @@ _openshift_cli() commands+=("expose") commands+=("stop") commands+=("delete") + commands+=("explain") commands+=("logs") commands+=("rsh") commands+=("rsync") @@ -3683,6 +3799,7 @@ _openshift_cli() commands+=("proxy") commands+=("create") commands+=("replace") + commands+=("apply") commands+=("patch") commands+=("process") commands+=("export") @@ -3690,6 +3807,7 @@ _openshift_cli() commands+=("attach") commands+=("policy") commands+=("secrets") + commands+=("convert") commands+=("logout") commands+=("config") commands+=("whoami") @@ -3724,6 +3842,7 @@ _openshift_cli() flags+=("--ir-data-source=") flags+=("--ir-dbname=") flags+=("--ir-influxdb-host=") + flags+=("--ir-namespace-only") flags+=("--ir-password=") flags+=("--ir-percentile=") flags+=("--ir-user=") @@ -3790,6 +3909,7 @@ _openshift_kube_get() must_have_one_noun+=("clusterrole") must_have_one_noun+=("clusterrolebinding") must_have_one_noun+=("componentstatus") + must_have_one_noun+=("daemonset") must_have_one_noun+=("deployment") must_have_one_noun+=("deploymentconfig") must_have_one_noun+=("endpoints") @@ -3802,7 +3922,9 @@ _openshift_kube_get() must_have_one_noun+=("imagestream") must_have_one_noun+=("imagestreamimage") must_have_one_noun+=("imagestreamtag") + must_have_one_noun+=("ingress") must_have_one_noun+=("ispersonalsubjectaccessreview") + must_have_one_noun+=("job") must_have_one_noun+=("limitrange") must_have_one_noun+=("namespace") must_have_one_noun+=("netnamespace") @@ -3989,6 +4111,7 @@ _openshift_kube_delete() must_have_one_noun+=("clusterrole") must_have_one_noun+=("clusterrolebinding") must_have_one_noun+=("componentstatus") + must_have_one_noun+=("daemonset") must_have_one_noun+=("deployment") must_have_one_noun+=("deploymentconfig") must_have_one_noun+=("endpoints") @@ -4001,7 +4124,9 @@ _openshift_kube_delete() must_have_one_noun+=("imagestream") must_have_one_noun+=("imagestreamimage") must_have_one_noun+=("imagestreamtag") + must_have_one_noun+=("ingress") must_have_one_noun+=("ispersonalsubjectaccessreview") + must_have_one_noun+=("job") must_have_one_noun+=("limitrange") must_have_one_noun+=("namespace") must_have_one_noun+=("netnamespace") @@ -4032,6 +4157,57 @@ _openshift_kube_delete() must_have_one_noun+=("useridentitymapping") } +_openshift_kube_edit() +{ + last_command="openshift_kube_edit" + commands=() + + flags=() + two_word_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + flags+=("--output=") + two_word_flags+=("-o") + flags+=("--output-version=") + + must_have_one_flag=() + must_have_one_noun=() +} + +_openshift_kube_apply() +{ + last_command="openshift_kube_apply" + commands=() + + flags=() + two_word_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + flags+=("--output=") + two_word_flags+=("-o") + flags+=("--schema-cache-dir=") + flags+=("--validate") + + must_have_one_flag=() + must_have_one_flag+=("--filename=") + must_have_one_flag+=("-f") + must_have_one_noun=() +} + _openshift_kube_namespace() { last_command="openshift_kube_namespace" @@ -4062,8 +4238,13 @@ _openshift_kube_logs() flags+=("--follow") flags+=("-f") flags+=("--interactive") + flags+=("--limit-bytes=") flags+=("--previous") flags+=("-p") + flags+=("--since=") + flags+=("--since-time=") + flags+=("--tail=") + flags+=("--timestamps") must_have_one_flag=() must_have_one_noun=() @@ -4212,6 +4393,7 @@ _openshift_kube_proxy() flags+=("--accept-hosts=") flags+=("--accept-paths=") + flags+=("--address=") flags+=("--api-prefix=") flags+=("--disable-filter") flags+=("--port=") @@ -4390,6 +4572,7 @@ _openshift_kube_label() must_have_one_noun+=("clusterrole") must_have_one_noun+=("clusterrolebinding") must_have_one_noun+=("componentstatus") + must_have_one_noun+=("daemonset") must_have_one_noun+=("deployment") must_have_one_noun+=("deploymentconfig") must_have_one_noun+=("endpoints") @@ -4402,7 +4585,9 @@ _openshift_kube_label() must_have_one_noun+=("imagestream") must_have_one_noun+=("imagestreamimage") must_have_one_noun+=("imagestreamtag") + must_have_one_noun+=("ingress") must_have_one_noun+=("ispersonalsubjectaccessreview") + must_have_one_noun+=("job") must_have_one_noun+=("limitrange") must_have_one_noun+=("namespace") must_have_one_noun+=("netnamespace") @@ -4659,6 +4844,57 @@ _openshift_kube_version() must_have_one_noun=() } +_openshift_kube_explain() +{ + last_command="openshift_kube_explain" + commands=() + + flags=() + two_word_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--recursive") + + must_have_one_flag=() + must_have_one_noun=() +} + +_openshift_kube_convert() +{ + last_command="openshift_kube_convert" + commands=() + + flags=() + two_word_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--filename=") + flags_with_completion+=("--filename") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__handle_filename_extension_flag json|stdin|yaml|yml") + flags+=("--local") + flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + flags+=("--output-version=") + flags+=("--schema-cache-dir=") + flags+=("--show-all") + flags+=("-a") + flags+=("--sort-by=") + flags+=("--template=") + two_word_flags+=("-t") + flags+=("--validate") + + must_have_one_flag=() + must_have_one_flag+=("--filename=") + must_have_one_flag+=("-f") + must_have_one_noun=() +} + _openshift_kube_options() { last_command="openshift_kube_options" @@ -4684,6 +4920,8 @@ _openshift_kube() commands+=("replace") commands+=("patch") commands+=("delete") + commands+=("edit") + commands+=("apply") commands+=("namespace") commands+=("logs") commands+=("rolling-update") @@ -4701,6 +4939,8 @@ _openshift_kube() commands+=("cluster-info") commands+=("api-versions") commands+=("version") + commands+=("explain") + commands+=("convert") commands+=("options") flags=() @@ -4732,6 +4972,7 @@ _openshift_kube() flags+=("--ir-data-source=") flags+=("--ir-dbname=") flags+=("--ir-influxdb-host=") + flags+=("--ir-namespace-only") flags+=("--ir-password=") flags+=("--ir-percentile=") flags+=("--ir-user=") @@ -5021,6 +5262,7 @@ _openshift_ex() flags+=("--ir-data-source=") flags+=("--ir-dbname=") flags+=("--ir-influxdb-host=") + flags+=("--ir-namespace-only") flags+=("--ir-password=") flags+=("--ir-percentile=") flags+=("--ir-user=") diff --git a/docs/generated/oadm_by_example_content.adoc b/docs/generated/oadm_by_example_content.adoc index 7b088c9d3153..8b1341655367 100644 --- a/docs/generated/oadm_by_example_content.adoc +++ b/docs/generated/oadm_by_example_content.adoc @@ -92,7 +92,7 @@ Sets a user entry in kubeconfig == oadm config view -displays Merged kubeconfig settings or a specified kubeconfig file. +Displays merged kubeconfig settings or a specified kubeconfig file. ==== diff --git a/docs/generated/oc_by_example_content.adoc b/docs/generated/oc_by_example_content.adoc index 91864c2f4602..05740a760bb2 100644 --- a/docs/generated/oc_by_example_content.adoc +++ b/docs/generated/oc_by_example_content.adoc @@ -32,6 +32,22 @@ Update the annotations on a resource ==== +== oc apply +Apply a configuration to a resource by filename or stdin + +==== + +[options="nowrap"] +---- +# Apply the configuration in pod.json to a pod. +$ openshift cli apply -f ./pod.json + +# Apply the JSON passed into stdin to a pod. +$ cat pod.json | openshift cli apply -f - +---- +==== + + == oc attach Attach to a running container. @@ -153,7 +169,7 @@ Sets a user entry in kubeconfig == oc config view -displays Merged kubeconfig settings or a specified kubeconfig file. +Displays merged kubeconfig settings or a specified kubeconfig file. ==== @@ -168,6 +184,27 @@ displays Merged kubeconfig settings or a specified kubeconfig file. ==== +== oc convert +Convert config files between different API versions + +==== + +[options="nowrap"] +---- +# Convert 'pod.yaml' to latest version and print to stdout. +$ openshift cli convert -f pod.yaml + +# Convert the live state of the resource specified by 'pod.yaml' to the latest version +# and print to stdout in json format. +$ openshift cli convert -f pod.yaml --local -o json + +# Convert all files under current directory to latest version and create them all. +$ openshift cli convert -f . | kubectl create -f - + +---- +==== + + == oc create Create a resource by filename or stdin @@ -321,6 +358,22 @@ Execute a command in a container. ==== +== oc explain +Documentation of resources. + +==== + +[options="nowrap"] +---- +# Get the documentation of the resource and its fields +$ openshift cli explain pods + +# Get the documentation of a specific field of a resource +$ openshift cli explain pods.spec.containers +---- +==== + + == oc export Export resources so they can be used elsewhere diff --git a/hack/api-description-whitelist.txt b/hack/api-description-whitelist.txt index d7a33da807dd..1e539703a421 100644 --- a/hack/api-description-whitelist.txt +++ b/hack/api-description-whitelist.txt @@ -50,6 +50,7 @@ v1.containerstatewaiting v1.containerstatus v1.custombuildstrategy v1.customdeploymentstrategyparams +v1.daemonendpoint v1.deleteoptions v1.deploymentcause v1.deploymentcauseimagetrigger @@ -76,7 +77,9 @@ v1.eventlist v1.eventsource v1.execaction v1.execnewpodhook +v1.fcvolumesource v1.finalizername +v1.flockervolumesource v1.gcepersistentdiskvolumesource v1.gitbuildsource v1.gitrepovolumesource @@ -127,6 +130,7 @@ v1.namespacestatus v1.nfsvolumesource v1.nodeaddress v1.nodecondition +v1.nodedaemonendpoints v1.nodelist v1.nodespec v1.nodestatus @@ -154,6 +158,7 @@ v1.persistentvolumestatus v1.podcondition v1.podlist v1.podspec +v1.podsecuritycontext v1.podstatus v1.podtemplate v1.podtemplatelist @@ -221,3 +226,8 @@ v1.userlist v1.volume v1.volumemount v1.webhooktrigger +unversioned.status +unversioned.statuscause +unversioned.statusdetails +unversioned.patch +unversioned.listmeta diff --git a/hack/copy-kube-artifacts.sh b/hack/copy-kube-artifacts.sh index dcaafefac8c1..8f46947779c1 100755 --- a/hack/copy-kube-artifacts.sh +++ b/hack/copy-kube-artifacts.sh @@ -24,12 +24,37 @@ docs/user-guide/multi-pod.yaml examples/examples_test.go examples/pod examples/iscsi/README.md +docs/user-guide/walkthrough/README.md +docs/user-guide/simple-yaml.md +pkg/client/testdata/myCA.cer +pkg/client/testdata/myCA.key +pkg/client/testdata/mycertvalid.cer +pkg/client/testdata/mycertvalid.key +pkg/client/testdata/mycertvalid.req " descriptor_dirs="cmd/integration +docs/admin/ docs/admin/limitrange/ +docs/admin/namespaces/ +docs/admin/resourcequota/ +docs/user-guide/ +docs/user-guide/downward-api/ +docs/user-guide/downward-api/volume/ +docs/user-guide/liveness/ +docs/user-guide/logging-demo/ +docs/user-guide/node-selection/ +docs/user-guide/persistent-volumes/claims/ +docs/user-guide/persistent-volumes/simpletest/ +docs/user-guide/persistent-volumes/volumes/ +docs/user-guide/secrets/ +docs/user-guide/update-demo/ +docs/user-guide/walkthrough/ examples/ +examples/cephfs/ examples/elasticsearch/ +examples/experimental/ +examples/fibre_channel/ examples/guestbook examples/guestbook-go examples/iscsi @@ -42,6 +67,7 @@ examples/cluster-dns examples/elasticsearch examples/explorer examples/hazelcast +examples/javaweb-tomcat-sidecar/ examples/meteor examples/mysql-wordpress-pd examples/nfs diff --git a/pkg/api/deep_copy_generated.go b/pkg/api/deep_copy_generated.go index 1aa90bc62b60..ab3115634405 100644 --- a/pkg/api/deep_copy_generated.go +++ b/pkg/api/deep_copy_generated.go @@ -13,6 +13,7 @@ import ( templateapi "github.com/openshift/origin/pkg/template/api" userapi "github.com/openshift/origin/pkg/user/api" pkgapi "k8s.io/kubernetes/pkg/api" + unversioned "k8s.io/kubernetes/pkg/api/unversioned" conversion "k8s.io/kubernetes/pkg/conversion" runtime "k8s.io/kubernetes/pkg/runtime" util "k8s.io/kubernetes/pkg/util" @@ -36,7 +37,7 @@ func deepCopy_api_ClusterPolicy(in api.ClusterPolicy, out *api.ClusterPolicy, c if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -46,7 +47,7 @@ func deepCopy_api_ClusterPolicy(in api.ClusterPolicy, out *api.ClusterPolicy, c if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if in.Roles != nil { out.Roles = make(map[string]*api.ClusterRole) @@ -67,7 +68,7 @@ func deepCopy_api_ClusterPolicyBinding(in api.ClusterPolicyBinding, out *api.Clu if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -77,7 +78,7 @@ func deepCopy_api_ClusterPolicyBinding(in api.ClusterPolicyBinding, out *api.Clu if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if newVal, err := c.DeepCopy(in.PolicyRef); err != nil { return err @@ -103,12 +104,12 @@ func deepCopy_api_ClusterPolicyBindingList(in api.ClusterPolicyBindingList, out if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]api.ClusterPolicyBinding, len(in.Items)) @@ -127,12 +128,12 @@ func deepCopy_api_ClusterPolicyList(in api.ClusterPolicyList, out *api.ClusterPo if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]api.ClusterPolicy, len(in.Items)) @@ -151,7 +152,7 @@ func deepCopy_api_ClusterRole(in api.ClusterRole, out *api.ClusterRole, c *conve if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -175,7 +176,7 @@ func deepCopy_api_ClusterRoleBinding(in api.ClusterRoleBinding, out *api.Cluster if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -206,12 +207,12 @@ func deepCopy_api_ClusterRoleBindingList(in api.ClusterRoleBindingList, out *api if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]api.ClusterRoleBinding, len(in.Items)) @@ -230,12 +231,12 @@ func deepCopy_api_ClusterRoleList(in api.ClusterRoleList, out *api.ClusterRoleLi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]api.ClusterRole, len(in.Items)) @@ -254,7 +255,7 @@ func deepCopy_api_IsPersonalSubjectAccessReview(in api.IsPersonalSubjectAccessRe if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } return nil } @@ -263,7 +264,7 @@ func deepCopy_api_LocalResourceAccessReview(in api.LocalResourceAccessReview, ou if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_api_AuthorizationAttributes(in.Action, &out.Action, c); err != nil { return err @@ -275,7 +276,7 @@ func deepCopy_api_LocalSubjectAccessReview(in api.LocalSubjectAccessReview, out if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_api_AuthorizationAttributes(in.Action, &out.Action, c); err != nil { return err @@ -300,7 +301,7 @@ func deepCopy_api_Policy(in api.Policy, out *api.Policy, c *conversion.Cloner) e if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -310,7 +311,7 @@ func deepCopy_api_Policy(in api.Policy, out *api.Policy, c *conversion.Cloner) e if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if in.Roles != nil { out.Roles = make(map[string]*api.Role) @@ -331,7 +332,7 @@ func deepCopy_api_PolicyBinding(in api.PolicyBinding, out *api.PolicyBinding, c if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -341,7 +342,7 @@ func deepCopy_api_PolicyBinding(in api.PolicyBinding, out *api.PolicyBinding, c if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if newVal, err := c.DeepCopy(in.PolicyRef); err != nil { return err @@ -367,12 +368,12 @@ func deepCopy_api_PolicyBindingList(in api.PolicyBindingList, out *api.PolicyBin if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]api.PolicyBinding, len(in.Items)) @@ -391,12 +392,12 @@ func deepCopy_api_PolicyList(in api.PolicyList, out *api.PolicyList, c *conversi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]api.Policy, len(in.Items)) @@ -480,7 +481,7 @@ func deepCopy_api_ResourceAccessReview(in api.ResourceAccessReview, out *api.Res if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_api_AuthorizationAttributes(in.Action, &out.Action, c); err != nil { return err @@ -492,7 +493,7 @@ func deepCopy_api_ResourceAccessReviewResponse(in api.ResourceAccessReviewRespon if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } out.Namespace = in.Namespace if in.Users != nil { @@ -526,7 +527,7 @@ func deepCopy_api_Role(in api.Role, out *api.Role, c *conversion.Cloner) error { if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -550,7 +551,7 @@ func deepCopy_api_RoleBinding(in api.RoleBinding, out *api.RoleBinding, c *conve if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -581,12 +582,12 @@ func deepCopy_api_RoleBindingList(in api.RoleBindingList, out *api.RoleBindingLi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]api.RoleBinding, len(in.Items)) @@ -605,12 +606,12 @@ func deepCopy_api_RoleList(in api.RoleList, out *api.RoleList, c *conversion.Clo if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]api.Role, len(in.Items)) @@ -629,7 +630,7 @@ func deepCopy_api_SubjectAccessReview(in api.SubjectAccessReview, out *api.Subje if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_api_AuthorizationAttributes(in.Action, &out.Action, c); err != nil { return err @@ -654,7 +655,7 @@ func deepCopy_api_SubjectAccessReviewResponse(in api.SubjectAccessReviewResponse if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } out.Namespace = in.Namespace out.Allowed = in.Allowed @@ -666,7 +667,7 @@ func deepCopy_api_Build(in buildapi.Build, out *buildapi.Build, c *conversion.Cl if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -686,7 +687,7 @@ func deepCopy_api_BuildConfig(in buildapi.BuildConfig, out *buildapi.BuildConfig if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -706,12 +707,12 @@ func deepCopy_api_BuildConfigList(in buildapi.BuildConfigList, out *buildapi.Bui if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]buildapi.BuildConfig, len(in.Items)) @@ -752,12 +753,12 @@ func deepCopy_api_BuildList(in buildapi.BuildList, out *buildapi.BuildList, c *c if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]buildapi.Build, len(in.Items)) @@ -776,12 +777,12 @@ func deepCopy_api_BuildLog(in buildapi.BuildLog, out *buildapi.BuildLog, c *conv if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } return nil } @@ -790,7 +791,7 @@ func deepCopy_api_BuildLogOptions(in buildapi.BuildLogOptions, out *buildapi.Bui if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } out.Follow = in.Follow out.NoWait = in.NoWait @@ -823,7 +824,7 @@ func deepCopy_api_BuildRequest(in buildapi.BuildRequest, out *buildapi.BuildRequ if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -935,7 +936,7 @@ func deepCopy_api_BuildStatus(in buildapi.BuildStatus, out *buildapi.BuildStatus if newVal, err := c.DeepCopy(in.StartTimestamp); err != nil { return err } else { - out.StartTimestamp = newVal.(*util.Time) + out.StartTimestamp = newVal.(*unversioned.Time) } } else { out.StartTimestamp = nil @@ -944,7 +945,7 @@ func deepCopy_api_BuildStatus(in buildapi.BuildStatus, out *buildapi.BuildStatus if newVal, err := c.DeepCopy(in.CompletionTimestamp); err != nil { return err } else { - out.CompletionTimestamp = newVal.(*util.Time) + out.CompletionTimestamp = newVal.(*unversioned.Time) } } else { out.CompletionTimestamp = nil @@ -1248,7 +1249,7 @@ func deepCopy_api_DeploymentConfig(in deployapi.DeploymentConfig, out *deployapi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1284,12 +1285,12 @@ func deepCopy_api_DeploymentConfigList(in deployapi.DeploymentConfigList, out *d if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]deployapi.DeploymentConfig, len(in.Items)) @@ -1308,7 +1309,7 @@ func deepCopy_api_DeploymentConfigRollback(in deployapi.DeploymentConfigRollback if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_api_DeploymentConfigRollbackSpec(in.Spec, &out.Spec, c); err != nil { return err @@ -1661,7 +1662,7 @@ func deepCopy_api_DockerImage(in imageapi.DockerImage, out *imageapi.DockerImage if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } out.ID = in.ID out.Parent = in.Parent @@ -1669,7 +1670,7 @@ func deepCopy_api_DockerImage(in imageapi.DockerImage, out *imageapi.DockerImage if newVal, err := c.DeepCopy(in.Created); err != nil { return err } else { - out.Created = newVal.(util.Time) + out.Created = newVal.(unversioned.Time) } out.Container = in.Container if err := deepCopy_api_DockerConfig(in.ContainerConfig, &out.ContainerConfig, c); err != nil { @@ -1694,7 +1695,7 @@ func deepCopy_api_Image(in imageapi.Image, out *imageapi.Image, c *conversion.Cl if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1714,12 +1715,12 @@ func deepCopy_api_ImageList(in imageapi.ImageList, out *imageapi.ImageList, c *c if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]imageapi.Image, len(in.Items)) @@ -1738,7 +1739,7 @@ func deepCopy_api_ImageStream(in imageapi.ImageStream, out *imageapi.ImageStream if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1758,7 +1759,7 @@ func deepCopy_api_ImageStreamImage(in imageapi.ImageStreamImage, out *imageapi.I if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1775,12 +1776,12 @@ func deepCopy_api_ImageStreamList(in imageapi.ImageStreamList, out *imageapi.Ima if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]imageapi.ImageStream, len(in.Items)) @@ -1799,7 +1800,7 @@ func deepCopy_api_ImageStreamMapping(in imageapi.ImageStreamMapping, out *imagea if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1852,7 +1853,7 @@ func deepCopy_api_ImageStreamTag(in imageapi.ImageStreamTag, out *imageapi.Image if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1869,7 +1870,7 @@ func deepCopy_api_TagEvent(in imageapi.TagEvent, out *imageapi.TagEvent, c *conv if newVal, err := c.DeepCopy(in.Created); err != nil { return err } else { - out.Created = newVal.(util.Time) + out.Created = newVal.(unversioned.Time) } out.DockerImageReference = in.DockerImageReference out.Image = in.Image @@ -1915,7 +1916,7 @@ func deepCopy_api_OAuthAccessToken(in oauthapi.OAuthAccessToken, out *oauthapi.O if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1944,12 +1945,12 @@ func deepCopy_api_OAuthAccessTokenList(in oauthapi.OAuthAccessTokenList, out *oa if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapi.OAuthAccessToken, len(in.Items)) @@ -1968,7 +1969,7 @@ func deepCopy_api_OAuthAuthorizeToken(in oauthapi.OAuthAuthorizeToken, out *oaut if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1996,12 +1997,12 @@ func deepCopy_api_OAuthAuthorizeTokenList(in oauthapi.OAuthAuthorizeTokenList, o if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapi.OAuthAuthorizeToken, len(in.Items)) @@ -2020,7 +2021,7 @@ func deepCopy_api_OAuthClient(in oauthapi.OAuthClient, out *oauthapi.OAuthClient if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2044,7 +2045,7 @@ func deepCopy_api_OAuthClientAuthorization(in oauthapi.OAuthClientAuthorization, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2069,12 +2070,12 @@ func deepCopy_api_OAuthClientAuthorizationList(in oauthapi.OAuthClientAuthorizat if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapi.OAuthClientAuthorization, len(in.Items)) @@ -2093,12 +2094,12 @@ func deepCopy_api_OAuthClientList(in oauthapi.OAuthClientList, out *oauthapi.OAu if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapi.OAuthClient, len(in.Items)) @@ -2117,7 +2118,7 @@ func deepCopy_api_Project(in projectapi.Project, out *projectapi.Project, c *con if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2137,12 +2138,12 @@ func deepCopy_api_ProjectList(in projectapi.ProjectList, out *projectapi.Project if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]projectapi.Project, len(in.Items)) @@ -2161,7 +2162,7 @@ func deepCopy_api_ProjectRequest(in projectapi.ProjectRequest, out *projectapi.P if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2194,7 +2195,7 @@ func deepCopy_api_Route(in routeapi.Route, out *routeapi.Route, c *conversion.Cl if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2214,12 +2215,12 @@ func deepCopy_api_RouteList(in routeapi.RouteList, out *routeapi.RouteList, c *c if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]routeapi.Route, len(in.Items)) @@ -2287,7 +2288,7 @@ func deepCopy_api_ClusterNetwork(in sdnapi.ClusterNetwork, out *sdnapi.ClusterNe if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2304,12 +2305,12 @@ func deepCopy_api_ClusterNetworkList(in sdnapi.ClusterNetworkList, out *sdnapi.C if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]sdnapi.ClusterNetwork, len(in.Items)) @@ -2328,7 +2329,7 @@ func deepCopy_api_HostSubnet(in sdnapi.HostSubnet, out *sdnapi.HostSubnet, c *co if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2345,12 +2346,12 @@ func deepCopy_api_HostSubnetList(in sdnapi.HostSubnetList, out *sdnapi.HostSubne if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]sdnapi.HostSubnet, len(in.Items)) @@ -2369,7 +2370,7 @@ func deepCopy_api_NetNamespace(in sdnapi.NetNamespace, out *sdnapi.NetNamespace, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2385,12 +2386,12 @@ func deepCopy_api_NetNamespaceList(in sdnapi.NetNamespaceList, out *sdnapi.NetNa if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]sdnapi.NetNamespace, len(in.Items)) @@ -2420,7 +2421,7 @@ func deepCopy_api_Template(in templateapi.Template, out *templateapi.Template, c if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2466,12 +2467,12 @@ func deepCopy_api_TemplateList(in templateapi.TemplateList, out *templateapi.Tem if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]templateapi.Template, len(in.Items)) @@ -2490,7 +2491,7 @@ func deepCopy_api_Group(in userapi.Group, out *userapi.Group, c *conversion.Clon if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2512,12 +2513,12 @@ func deepCopy_api_GroupList(in userapi.GroupList, out *userapi.GroupList, c *con if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]userapi.Group, len(in.Items)) @@ -2536,7 +2537,7 @@ func deepCopy_api_Identity(in userapi.Identity, out *userapi.Identity, c *conver if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2565,12 +2566,12 @@ func deepCopy_api_IdentityList(in userapi.IdentityList, out *userapi.IdentityLis if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]userapi.Identity, len(in.Items)) @@ -2589,7 +2590,7 @@ func deepCopy_api_User(in userapi.User, out *userapi.User, c *conversion.Cloner) if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2620,7 +2621,7 @@ func deepCopy_api_UserIdentityMapping(in userapi.UserIdentityMapping, out *usera if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2644,12 +2645,12 @@ func deepCopy_api_UserList(in userapi.UserList, out *userapi.UserList, c *conver if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapi.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapi.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]userapi.User, len(in.Items)) diff --git a/pkg/api/graph/graphview/veneering_test.go b/pkg/api/graph/graphview/veneering_test.go index 282c281a6f86..0d9f5e76267d 100644 --- a/pkg/api/graph/graphview/veneering_test.go +++ b/pkg/api/graph/graphview/veneering_test.go @@ -163,7 +163,7 @@ func TestGraph(t *testing.T) { ObjectMeta: kapi.ObjectMeta{ Name: "build1-1-abc", Labels: map[string]string{buildapi.BuildConfigLabel: "build1"}, - CreationTimestamp: util.NewTime(now.Add(-10 * time.Second)), + CreationTimestamp: unversioned.NewTime(now.Add(-10 * time.Second)), }, Status: buildapi.BuildStatus{ Phase: buildapi.BuildPhaseFailed, @@ -173,7 +173,7 @@ func TestGraph(t *testing.T) { ObjectMeta: kapi.ObjectMeta{ Name: "build1-2-abc", Labels: map[string]string{buildapi.BuildConfigLabel: "build1"}, - CreationTimestamp: util.NewTime(now.Add(-5 * time.Second)), + CreationTimestamp: unversioned.NewTime(now.Add(-5 * time.Second)), }, Status: buildapi.BuildStatus{ Phase: buildapi.BuildPhaseComplete, @@ -183,7 +183,7 @@ func TestGraph(t *testing.T) { ObjectMeta: kapi.ObjectMeta{ Name: "build1-3-abc", Labels: map[string]string{buildapi.BuildConfigLabel: "build1"}, - CreationTimestamp: util.NewTime(now.Add(-15 * time.Second)), + CreationTimestamp: unversioned.NewTime(now.Add(-15 * time.Second)), }, Status: buildapi.BuildStatus{ Phase: buildapi.BuildPhasePending, diff --git a/pkg/api/latest/latest.go b/pkg/api/latest/latest.go index b5858c1e274c..2936d6c8b8cd 100644 --- a/pkg/api/latest/latest.go +++ b/pkg/api/latest/latest.go @@ -94,7 +94,13 @@ func OriginKind(kind, apiVersion string) bool { } func init() { - kubeMapper := klatest.RESTMapper + // this keeps us consistent with old code. We can decide if we want to expand our RESTMapper to cover + // api.RESTMapper, which is different than what you'd get from latest. + kubeAPIGroup, err := klatest.Group("") + if err != nil { + panic(err) + } + kubeMapper := kubeAPIGroup.RESTMapper // list of versions we support on the server, in preferred order versions := []string{"v1", "v1beta3"} diff --git a/pkg/api/latest/tags_test.go b/pkg/api/latest/tags_test.go index e43ce2987910..b3a556e090b1 100644 --- a/pkg/api/latest/tags_test.go +++ b/pkg/api/latest/tags_test.go @@ -43,7 +43,7 @@ func checkDescriptions(objType reflect.Type, seen *map[reflect.Type]bool, t *tes if structField.Name == "TypeMeta" || structField.Name == "ObjectMeta" || structField.Name == "ListMeta" { continue } - if structField.Type == reflect.TypeOf(util.Time{}) || structField.Type == reflect.TypeOf(time.Time{}) || structField.Type == reflect.TypeOf(runtime.RawExtension{}) { + if structField.Type == reflect.TypeOf(unversioned.Time{}) || structField.Type == reflect.TypeOf(time.Time{}) || structField.Type == reflect.TypeOf(runtime.RawExtension{}) { continue } diff --git a/pkg/api/v1/conversion_generated.go b/pkg/api/v1/conversion_generated.go index 563260e09539..ebc510e1b6ef 100644 --- a/pkg/api/v1/conversion_generated.go +++ b/pkg/api/v1/conversion_generated.go @@ -29,14 +29,55 @@ import ( reflect "reflect" ) -func convert_api_ClusterPolicyBindingList_To_v1_ClusterPolicyBindingList(in *api.ClusterPolicyBindingList, out *v1.ClusterPolicyBindingList, s conversion.Scope) error { +func autoconvert_api_ClusterPolicy_To_v1_ClusterPolicy(in *api.ClusterPolicy, out *v1.ClusterPolicy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ClusterPolicy))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := s.Convert(&in.Roles, &out.Roles, 0); err != nil { + return err + } + return nil +} + +func autoconvert_api_ClusterPolicyBinding_To_v1_ClusterPolicyBinding(in *api.ClusterPolicyBinding, out *v1.ClusterPolicyBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ClusterPolicyBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := convert_api_ObjectReference_To_v1_ObjectReference(&in.PolicyRef, &out.PolicyRef, s); err != nil { + return err + } + if err := s.Convert(&in.RoleBindings, &out.RoleBindings, 0); err != nil { + return err + } + return nil +} + +func autoconvert_api_ClusterPolicyBindingList_To_v1_ClusterPolicyBindingList(in *api.ClusterPolicyBindingList, out *v1.ClusterPolicyBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ClusterPolicyBindingList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -52,14 +93,18 @@ func convert_api_ClusterPolicyBindingList_To_v1_ClusterPolicyBindingList(in *api return nil } -func convert_api_ClusterPolicyList_To_v1_ClusterPolicyList(in *api.ClusterPolicyList, out *v1.ClusterPolicyList, s conversion.Scope) error { +func convert_api_ClusterPolicyBindingList_To_v1_ClusterPolicyBindingList(in *api.ClusterPolicyBindingList, out *v1.ClusterPolicyBindingList, s conversion.Scope) error { + return autoconvert_api_ClusterPolicyBindingList_To_v1_ClusterPolicyBindingList(in, out, s) +} + +func autoconvert_api_ClusterPolicyList_To_v1_ClusterPolicyList(in *api.ClusterPolicyList, out *v1.ClusterPolicyList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ClusterPolicyList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -75,11 +120,15 @@ func convert_api_ClusterPolicyList_To_v1_ClusterPolicyList(in *api.ClusterPolicy return nil } -func convert_api_ClusterRole_To_v1_ClusterRole(in *api.ClusterRole, out *v1.ClusterRole, s conversion.Scope) error { +func convert_api_ClusterPolicyList_To_v1_ClusterPolicyList(in *api.ClusterPolicyList, out *v1.ClusterPolicyList, s conversion.Scope) error { + return autoconvert_api_ClusterPolicyList_To_v1_ClusterPolicyList(in, out, s) +} + +func autoconvert_api_ClusterRole_To_v1_ClusterRole(in *api.ClusterRole, out *v1.ClusterRole, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ClusterRole))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -98,14 +147,44 @@ func convert_api_ClusterRole_To_v1_ClusterRole(in *api.ClusterRole, out *v1.Clus return nil } -func convert_api_ClusterRoleBindingList_To_v1_ClusterRoleBindingList(in *api.ClusterRoleBindingList, out *v1.ClusterRoleBindingList, s conversion.Scope) error { +func convert_api_ClusterRole_To_v1_ClusterRole(in *api.ClusterRole, out *v1.ClusterRole, s conversion.Scope) error { + return autoconvert_api_ClusterRole_To_v1_ClusterRole(in, out, s) +} + +func autoconvert_api_ClusterRoleBinding_To_v1_ClusterRoleBinding(in *api.ClusterRoleBinding, out *v1.ClusterRoleBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ClusterRoleBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Subjects != nil { + out.Subjects = make([]pkgapiv1.ObjectReference, len(in.Subjects)) + for i := range in.Subjects { + if err := convert_api_ObjectReference_To_v1_ObjectReference(&in.Subjects[i], &out.Subjects[i], s); err != nil { + return err + } + } + } else { + out.Subjects = nil + } + if err := convert_api_ObjectReference_To_v1_ObjectReference(&in.RoleRef, &out.RoleRef, s); err != nil { + return err + } + return nil +} + +func autoconvert_api_ClusterRoleBindingList_To_v1_ClusterRoleBindingList(in *api.ClusterRoleBindingList, out *v1.ClusterRoleBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ClusterRoleBindingList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -121,14 +200,18 @@ func convert_api_ClusterRoleBindingList_To_v1_ClusterRoleBindingList(in *api.Clu return nil } -func convert_api_ClusterRoleList_To_v1_ClusterRoleList(in *api.ClusterRoleList, out *v1.ClusterRoleList, s conversion.Scope) error { +func convert_api_ClusterRoleBindingList_To_v1_ClusterRoleBindingList(in *api.ClusterRoleBindingList, out *v1.ClusterRoleBindingList, s conversion.Scope) error { + return autoconvert_api_ClusterRoleBindingList_To_v1_ClusterRoleBindingList(in, out, s) +} + +func autoconvert_api_ClusterRoleList_To_v1_ClusterRoleList(in *api.ClusterRoleList, out *v1.ClusterRoleList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ClusterRoleList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -144,24 +227,97 @@ func convert_api_ClusterRoleList_To_v1_ClusterRoleList(in *api.ClusterRoleList, return nil } -func convert_api_IsPersonalSubjectAccessReview_To_v1_IsPersonalSubjectAccessReview(in *api.IsPersonalSubjectAccessReview, out *v1.IsPersonalSubjectAccessReview, s conversion.Scope) error { +func convert_api_ClusterRoleList_To_v1_ClusterRoleList(in *api.ClusterRoleList, out *v1.ClusterRoleList, s conversion.Scope) error { + return autoconvert_api_ClusterRoleList_To_v1_ClusterRoleList(in, out, s) +} + +func autoconvert_api_IsPersonalSubjectAccessReview_To_v1_IsPersonalSubjectAccessReview(in *api.IsPersonalSubjectAccessReview, out *v1.IsPersonalSubjectAccessReview, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.IsPersonalSubjectAccessReview))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } return nil } -func convert_api_PolicyBindingList_To_v1_PolicyBindingList(in *api.PolicyBindingList, out *v1.PolicyBindingList, s conversion.Scope) error { +func convert_api_IsPersonalSubjectAccessReview_To_v1_IsPersonalSubjectAccessReview(in *api.IsPersonalSubjectAccessReview, out *v1.IsPersonalSubjectAccessReview, s conversion.Scope) error { + return autoconvert_api_IsPersonalSubjectAccessReview_To_v1_IsPersonalSubjectAccessReview(in, out, s) +} + +func autoconvert_api_LocalResourceAccessReview_To_v1_LocalResourceAccessReview(in *api.LocalResourceAccessReview, out *v1.LocalResourceAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LocalResourceAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.Action has no peer in out + return nil +} + +func autoconvert_api_LocalSubjectAccessReview_To_v1_LocalSubjectAccessReview(in *api.LocalSubjectAccessReview, out *v1.LocalSubjectAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LocalSubjectAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.Action has no peer in out + out.User = in.User + // in.Groups has no peer in out + return nil +} + +func autoconvert_api_Policy_To_v1_Policy(in *api.Policy, out *v1.Policy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Policy))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := s.Convert(&in.Roles, &out.Roles, 0); err != nil { + return err + } + return nil +} + +func autoconvert_api_PolicyBinding_To_v1_PolicyBinding(in *api.PolicyBinding, out *v1.PolicyBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PolicyBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := convert_api_ObjectReference_To_v1_ObjectReference(&in.PolicyRef, &out.PolicyRef, s); err != nil { + return err + } + if err := s.Convert(&in.RoleBindings, &out.RoleBindings, 0); err != nil { + return err + } + return nil +} + +func autoconvert_api_PolicyBindingList_To_v1_PolicyBindingList(in *api.PolicyBindingList, out *v1.PolicyBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PolicyBindingList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -177,14 +333,18 @@ func convert_api_PolicyBindingList_To_v1_PolicyBindingList(in *api.PolicyBinding return nil } -func convert_api_PolicyList_To_v1_PolicyList(in *api.PolicyList, out *v1.PolicyList, s conversion.Scope) error { +func convert_api_PolicyBindingList_To_v1_PolicyBindingList(in *api.PolicyBindingList, out *v1.PolicyBindingList, s conversion.Scope) error { + return autoconvert_api_PolicyBindingList_To_v1_PolicyBindingList(in, out, s) +} + +func autoconvert_api_PolicyList_To_v1_PolicyList(in *api.PolicyList, out *v1.PolicyList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PolicyList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -200,11 +360,61 @@ func convert_api_PolicyList_To_v1_PolicyList(in *api.PolicyList, out *v1.PolicyL return nil } -func convert_api_Role_To_v1_Role(in *api.Role, out *v1.Role, s conversion.Scope) error { +func convert_api_PolicyList_To_v1_PolicyList(in *api.PolicyList, out *v1.PolicyList, s conversion.Scope) error { + return autoconvert_api_PolicyList_To_v1_PolicyList(in, out, s) +} + +func autoconvert_api_PolicyRule_To_v1_PolicyRule(in *api.PolicyRule, out *v1.PolicyRule, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PolicyRule))(in) + } + // in.Verbs has no peer in out + if err := s.Convert(&in.AttributeRestrictions, &out.AttributeRestrictions, 0); err != nil { + return err + } + if in.APIGroups != nil { + out.APIGroups = make([]string, len(in.APIGroups)) + for i := range in.APIGroups { + out.APIGroups[i] = in.APIGroups[i] + } + } else { + out.APIGroups = nil + } + // in.Resources has no peer in out + // in.ResourceNames has no peer in out + // in.NonResourceURLs has no peer in out + return nil +} + +func autoconvert_api_ResourceAccessReview_To_v1_ResourceAccessReview(in *api.ResourceAccessReview, out *v1.ResourceAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ResourceAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.Action has no peer in out + return nil +} + +func autoconvert_api_ResourceAccessReviewResponse_To_v1_ResourceAccessReviewResponse(in *api.ResourceAccessReviewResponse, out *v1.ResourceAccessReviewResponse, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ResourceAccessReviewResponse))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + out.Namespace = in.Namespace + // in.Users has no peer in out + // in.Groups has no peer in out + return nil +} + +func autoconvert_api_Role_To_v1_Role(in *api.Role, out *v1.Role, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Role))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -223,14 +433,44 @@ func convert_api_Role_To_v1_Role(in *api.Role, out *v1.Role, s conversion.Scope) return nil } -func convert_api_RoleBindingList_To_v1_RoleBindingList(in *api.RoleBindingList, out *v1.RoleBindingList, s conversion.Scope) error { +func convert_api_Role_To_v1_Role(in *api.Role, out *v1.Role, s conversion.Scope) error { + return autoconvert_api_Role_To_v1_Role(in, out, s) +} + +func autoconvert_api_RoleBinding_To_v1_RoleBinding(in *api.RoleBinding, out *v1.RoleBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.RoleBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Subjects != nil { + out.Subjects = make([]pkgapiv1.ObjectReference, len(in.Subjects)) + for i := range in.Subjects { + if err := convert_api_ObjectReference_To_v1_ObjectReference(&in.Subjects[i], &out.Subjects[i], s); err != nil { + return err + } + } + } else { + out.Subjects = nil + } + if err := convert_api_ObjectReference_To_v1_ObjectReference(&in.RoleRef, &out.RoleRef, s); err != nil { + return err + } + return nil +} + +func autoconvert_api_RoleBindingList_To_v1_RoleBindingList(in *api.RoleBindingList, out *v1.RoleBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.RoleBindingList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -246,14 +486,18 @@ func convert_api_RoleBindingList_To_v1_RoleBindingList(in *api.RoleBindingList, return nil } -func convert_api_RoleList_To_v1_RoleList(in *api.RoleList, out *v1.RoleList, s conversion.Scope) error { +func convert_api_RoleBindingList_To_v1_RoleBindingList(in *api.RoleBindingList, out *v1.RoleBindingList, s conversion.Scope) error { + return autoconvert_api_RoleBindingList_To_v1_RoleBindingList(in, out, s) +} + +func autoconvert_api_RoleList_To_v1_RoleList(in *api.RoleList, out *v1.RoleList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.RoleList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -269,11 +513,28 @@ func convert_api_RoleList_To_v1_RoleList(in *api.RoleList, out *v1.RoleList, s c return nil } -func convert_api_SubjectAccessReviewResponse_To_v1_SubjectAccessReviewResponse(in *api.SubjectAccessReviewResponse, out *v1.SubjectAccessReviewResponse, s conversion.Scope) error { +func convert_api_RoleList_To_v1_RoleList(in *api.RoleList, out *v1.RoleList, s conversion.Scope) error { + return autoconvert_api_RoleList_To_v1_RoleList(in, out, s) +} + +func autoconvert_api_SubjectAccessReview_To_v1_SubjectAccessReview(in *api.SubjectAccessReview, out *v1.SubjectAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SubjectAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.Action has no peer in out + out.User = in.User + // in.Groups has no peer in out + return nil +} + +func autoconvert_api_SubjectAccessReviewResponse_To_v1_SubjectAccessReviewResponse(in *api.SubjectAccessReviewResponse, out *v1.SubjectAccessReviewResponse, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.SubjectAccessReviewResponse))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Namespace = in.Namespace @@ -282,14 +543,59 @@ func convert_api_SubjectAccessReviewResponse_To_v1_SubjectAccessReviewResponse(i return nil } -func convert_v1_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList(in *v1.ClusterPolicyBindingList, out *api.ClusterPolicyBindingList, s conversion.Scope) error { +func convert_api_SubjectAccessReviewResponse_To_v1_SubjectAccessReviewResponse(in *api.SubjectAccessReviewResponse, out *v1.SubjectAccessReviewResponse, s conversion.Scope) error { + return autoconvert_api_SubjectAccessReviewResponse_To_v1_SubjectAccessReviewResponse(in, out, s) +} + +func autoconvert_v1_ClusterPolicy_To_api_ClusterPolicy(in *v1.ClusterPolicy, out *api.ClusterPolicy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ClusterPolicy))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := s.Convert(&in.Roles, &out.Roles, 0); err != nil { + return err + } + return nil +} + +func autoconvert_v1_ClusterPolicyBinding_To_api_ClusterPolicyBinding(in *v1.ClusterPolicyBinding, out *api.ClusterPolicyBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ClusterPolicyBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.PolicyRef, &out.PolicyRef, s); err != nil { + return err + } + if err := s.Convert(&in.RoleBindings, &out.RoleBindings, 0); err != nil { + return err + } + return nil +} + +func autoconvert_v1_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList(in *v1.ClusterPolicyBindingList, out *api.ClusterPolicyBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.ClusterPolicyBindingList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -305,14 +611,18 @@ func convert_v1_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList(in *v1. return nil } -func convert_v1_ClusterPolicyList_To_api_ClusterPolicyList(in *v1.ClusterPolicyList, out *api.ClusterPolicyList, s conversion.Scope) error { +func convert_v1_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList(in *v1.ClusterPolicyBindingList, out *api.ClusterPolicyBindingList, s conversion.Scope) error { + return autoconvert_v1_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList(in, out, s) +} + +func autoconvert_v1_ClusterPolicyList_To_api_ClusterPolicyList(in *v1.ClusterPolicyList, out *api.ClusterPolicyList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.ClusterPolicyList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -328,11 +638,15 @@ func convert_v1_ClusterPolicyList_To_api_ClusterPolicyList(in *v1.ClusterPolicyL return nil } -func convert_v1_ClusterRole_To_api_ClusterRole(in *v1.ClusterRole, out *api.ClusterRole, s conversion.Scope) error { +func convert_v1_ClusterPolicyList_To_api_ClusterPolicyList(in *v1.ClusterPolicyList, out *api.ClusterPolicyList, s conversion.Scope) error { + return autoconvert_v1_ClusterPolicyList_To_api_ClusterPolicyList(in, out, s) +} + +func autoconvert_v1_ClusterRole_To_api_ClusterRole(in *v1.ClusterRole, out *api.ClusterRole, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.ClusterRole))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -351,14 +665,46 @@ func convert_v1_ClusterRole_To_api_ClusterRole(in *v1.ClusterRole, out *api.Clus return nil } -func convert_v1_ClusterRoleBindingList_To_api_ClusterRoleBindingList(in *v1.ClusterRoleBindingList, out *api.ClusterRoleBindingList, s conversion.Scope) error { +func convert_v1_ClusterRole_To_api_ClusterRole(in *v1.ClusterRole, out *api.ClusterRole, s conversion.Scope) error { + return autoconvert_v1_ClusterRole_To_api_ClusterRole(in, out, s) +} + +func autoconvert_v1_ClusterRoleBinding_To_api_ClusterRoleBinding(in *v1.ClusterRoleBinding, out *api.ClusterRoleBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ClusterRoleBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + // in.UserNames has no peer in out + // in.GroupNames has no peer in out + if in.Subjects != nil { + out.Subjects = make([]pkgapi.ObjectReference, len(in.Subjects)) + for i := range in.Subjects { + if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.Subjects[i], &out.Subjects[i], s); err != nil { + return err + } + } + } else { + out.Subjects = nil + } + if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.RoleRef, &out.RoleRef, s); err != nil { + return err + } + return nil +} + +func autoconvert_v1_ClusterRoleBindingList_To_api_ClusterRoleBindingList(in *v1.ClusterRoleBindingList, out *api.ClusterRoleBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.ClusterRoleBindingList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -374,14 +720,18 @@ func convert_v1_ClusterRoleBindingList_To_api_ClusterRoleBindingList(in *v1.Clus return nil } -func convert_v1_ClusterRoleList_To_api_ClusterRoleList(in *v1.ClusterRoleList, out *api.ClusterRoleList, s conversion.Scope) error { +func convert_v1_ClusterRoleBindingList_To_api_ClusterRoleBindingList(in *v1.ClusterRoleBindingList, out *api.ClusterRoleBindingList, s conversion.Scope) error { + return autoconvert_v1_ClusterRoleBindingList_To_api_ClusterRoleBindingList(in, out, s) +} + +func autoconvert_v1_ClusterRoleList_To_api_ClusterRoleList(in *v1.ClusterRoleList, out *api.ClusterRoleList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.ClusterRoleList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -397,24 +747,97 @@ func convert_v1_ClusterRoleList_To_api_ClusterRoleList(in *v1.ClusterRoleList, o return nil } -func convert_v1_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview(in *v1.IsPersonalSubjectAccessReview, out *api.IsPersonalSubjectAccessReview, s conversion.Scope) error { +func convert_v1_ClusterRoleList_To_api_ClusterRoleList(in *v1.ClusterRoleList, out *api.ClusterRoleList, s conversion.Scope) error { + return autoconvert_v1_ClusterRoleList_To_api_ClusterRoleList(in, out, s) +} + +func autoconvert_v1_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview(in *v1.IsPersonalSubjectAccessReview, out *api.IsPersonalSubjectAccessReview, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.IsPersonalSubjectAccessReview))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } return nil } -func convert_v1_PolicyBindingList_To_api_PolicyBindingList(in *v1.PolicyBindingList, out *api.PolicyBindingList, s conversion.Scope) error { +func convert_v1_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview(in *v1.IsPersonalSubjectAccessReview, out *api.IsPersonalSubjectAccessReview, s conversion.Scope) error { + return autoconvert_v1_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview(in, out, s) +} + +func autoconvert_v1_LocalResourceAccessReview_To_api_LocalResourceAccessReview(in *v1.LocalResourceAccessReview, out *api.LocalResourceAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.LocalResourceAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.AuthorizationAttributes has no peer in out + return nil +} + +func autoconvert_v1_LocalSubjectAccessReview_To_api_LocalSubjectAccessReview(in *v1.LocalSubjectAccessReview, out *api.LocalSubjectAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.LocalSubjectAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.AuthorizationAttributes has no peer in out + out.User = in.User + // in.GroupsSlice has no peer in out + return nil +} + +func autoconvert_v1_Policy_To_api_Policy(in *v1.Policy, out *api.Policy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.Policy))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := s.Convert(&in.Roles, &out.Roles, 0); err != nil { + return err + } + return nil +} + +func autoconvert_v1_PolicyBinding_To_api_PolicyBinding(in *v1.PolicyBinding, out *api.PolicyBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.PolicyBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.PolicyRef, &out.PolicyRef, s); err != nil { + return err + } + if err := s.Convert(&in.RoleBindings, &out.RoleBindings, 0); err != nil { + return err + } + return nil +} + +func autoconvert_v1_PolicyBindingList_To_api_PolicyBindingList(in *v1.PolicyBindingList, out *api.PolicyBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.PolicyBindingList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -430,14 +853,18 @@ func convert_v1_PolicyBindingList_To_api_PolicyBindingList(in *v1.PolicyBindingL return nil } -func convert_v1_PolicyList_To_api_PolicyList(in *v1.PolicyList, out *api.PolicyList, s conversion.Scope) error { +func convert_v1_PolicyBindingList_To_api_PolicyBindingList(in *v1.PolicyBindingList, out *api.PolicyBindingList, s conversion.Scope) error { + return autoconvert_v1_PolicyBindingList_To_api_PolicyBindingList(in, out, s) +} + +func autoconvert_v1_PolicyList_To_api_PolicyList(in *v1.PolicyList, out *api.PolicyList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.PolicyList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -453,11 +880,61 @@ func convert_v1_PolicyList_To_api_PolicyList(in *v1.PolicyList, out *api.PolicyL return nil } -func convert_v1_Role_To_api_Role(in *v1.Role, out *api.Role, s conversion.Scope) error { +func convert_v1_PolicyList_To_api_PolicyList(in *v1.PolicyList, out *api.PolicyList, s conversion.Scope) error { + return autoconvert_v1_PolicyList_To_api_PolicyList(in, out, s) +} + +func autoconvert_v1_PolicyRule_To_api_PolicyRule(in *v1.PolicyRule, out *api.PolicyRule, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.PolicyRule))(in) + } + // in.Verbs has no peer in out + if err := s.Convert(&in.AttributeRestrictions, &out.AttributeRestrictions, 0); err != nil { + return err + } + if in.APIGroups != nil { + out.APIGroups = make([]string, len(in.APIGroups)) + for i := range in.APIGroups { + out.APIGroups[i] = in.APIGroups[i] + } + } else { + out.APIGroups = nil + } + // in.Resources has no peer in out + // in.ResourceNames has no peer in out + // in.NonResourceURLsSlice has no peer in out + return nil +} + +func autoconvert_v1_ResourceAccessReview_To_api_ResourceAccessReview(in *v1.ResourceAccessReview, out *api.ResourceAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ResourceAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.AuthorizationAttributes has no peer in out + return nil +} + +func autoconvert_v1_ResourceAccessReviewResponse_To_api_ResourceAccessReviewResponse(in *v1.ResourceAccessReviewResponse, out *api.ResourceAccessReviewResponse, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.ResourceAccessReviewResponse))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + out.Namespace = in.Namespace + // in.UsersSlice has no peer in out + // in.GroupsSlice has no peer in out + return nil +} + +func autoconvert_v1_Role_To_api_Role(in *v1.Role, out *api.Role, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.Role))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -476,14 +953,46 @@ func convert_v1_Role_To_api_Role(in *v1.Role, out *api.Role, s conversion.Scope) return nil } -func convert_v1_RoleBindingList_To_api_RoleBindingList(in *v1.RoleBindingList, out *api.RoleBindingList, s conversion.Scope) error { +func convert_v1_Role_To_api_Role(in *v1.Role, out *api.Role, s conversion.Scope) error { + return autoconvert_v1_Role_To_api_Role(in, out, s) +} + +func autoconvert_v1_RoleBinding_To_api_RoleBinding(in *v1.RoleBinding, out *api.RoleBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.RoleBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + // in.UserNames has no peer in out + // in.GroupNames has no peer in out + if in.Subjects != nil { + out.Subjects = make([]pkgapi.ObjectReference, len(in.Subjects)) + for i := range in.Subjects { + if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.Subjects[i], &out.Subjects[i], s); err != nil { + return err + } + } + } else { + out.Subjects = nil + } + if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.RoleRef, &out.RoleRef, s); err != nil { + return err + } + return nil +} + +func autoconvert_v1_RoleBindingList_To_api_RoleBindingList(in *v1.RoleBindingList, out *api.RoleBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.RoleBindingList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -499,14 +1008,18 @@ func convert_v1_RoleBindingList_To_api_RoleBindingList(in *v1.RoleBindingList, o return nil } -func convert_v1_RoleList_To_api_RoleList(in *v1.RoleList, out *api.RoleList, s conversion.Scope) error { +func convert_v1_RoleBindingList_To_api_RoleBindingList(in *v1.RoleBindingList, out *api.RoleBindingList, s conversion.Scope) error { + return autoconvert_v1_RoleBindingList_To_api_RoleBindingList(in, out, s) +} + +func autoconvert_v1_RoleList_To_api_RoleList(in *v1.RoleList, out *api.RoleList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.RoleList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -522,11 +1035,28 @@ func convert_v1_RoleList_To_api_RoleList(in *v1.RoleList, out *api.RoleList, s c return nil } -func convert_v1_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse(in *v1.SubjectAccessReviewResponse, out *api.SubjectAccessReviewResponse, s conversion.Scope) error { +func convert_v1_RoleList_To_api_RoleList(in *v1.RoleList, out *api.RoleList, s conversion.Scope) error { + return autoconvert_v1_RoleList_To_api_RoleList(in, out, s) +} + +func autoconvert_v1_SubjectAccessReview_To_api_SubjectAccessReview(in *v1.SubjectAccessReview, out *api.SubjectAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1.SubjectAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.AuthorizationAttributes has no peer in out + out.User = in.User + // in.GroupsSlice has no peer in out + return nil +} + +func autoconvert_v1_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse(in *v1.SubjectAccessReviewResponse, out *api.SubjectAccessReviewResponse, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1.SubjectAccessReviewResponse))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Namespace = in.Namespace @@ -535,11 +1065,15 @@ func convert_v1_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse(i return nil } -func convert_api_Build_To_v1_Build(in *buildapi.Build, out *apiv1.Build, s conversion.Scope) error { +func convert_v1_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse(in *v1.SubjectAccessReviewResponse, out *api.SubjectAccessReviewResponse, s conversion.Scope) error { + return autoconvert_v1_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse(in, out, s) +} + +func autoconvert_api_Build_To_v1_Build(in *buildapi.Build, out *apiv1.Build, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.Build))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -554,11 +1088,15 @@ func convert_api_Build_To_v1_Build(in *buildapi.Build, out *apiv1.Build, s conve return nil } -func convert_api_BuildConfig_To_v1_BuildConfig(in *buildapi.BuildConfig, out *apiv1.BuildConfig, s conversion.Scope) error { +func convert_api_Build_To_v1_Build(in *buildapi.Build, out *apiv1.Build, s conversion.Scope) error { + return autoconvert_api_Build_To_v1_Build(in, out, s) +} + +func autoconvert_api_BuildConfig_To_v1_BuildConfig(in *buildapi.BuildConfig, out *apiv1.BuildConfig, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildConfig))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -573,14 +1111,18 @@ func convert_api_BuildConfig_To_v1_BuildConfig(in *buildapi.BuildConfig, out *ap return nil } -func convert_api_BuildConfigList_To_v1_BuildConfigList(in *buildapi.BuildConfigList, out *apiv1.BuildConfigList, s conversion.Scope) error { +func convert_api_BuildConfig_To_v1_BuildConfig(in *buildapi.BuildConfig, out *apiv1.BuildConfig, s conversion.Scope) error { + return autoconvert_api_BuildConfig_To_v1_BuildConfig(in, out, s) +} + +func autoconvert_api_BuildConfigList_To_v1_BuildConfigList(in *buildapi.BuildConfigList, out *apiv1.BuildConfigList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildConfigList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -596,7 +1138,11 @@ func convert_api_BuildConfigList_To_v1_BuildConfigList(in *buildapi.BuildConfigL return nil } -func convert_api_BuildConfigSpec_To_v1_BuildConfigSpec(in *buildapi.BuildConfigSpec, out *apiv1.BuildConfigSpec, s conversion.Scope) error { +func convert_api_BuildConfigList_To_v1_BuildConfigList(in *buildapi.BuildConfigList, out *apiv1.BuildConfigList, s conversion.Scope) error { + return autoconvert_api_BuildConfigList_To_v1_BuildConfigList(in, out, s) +} + +func autoconvert_api_BuildConfigSpec_To_v1_BuildConfigSpec(in *buildapi.BuildConfigSpec, out *apiv1.BuildConfigSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildConfigSpec))(in) } @@ -616,7 +1162,11 @@ func convert_api_BuildConfigSpec_To_v1_BuildConfigSpec(in *buildapi.BuildConfigS return nil } -func convert_api_BuildConfigStatus_To_v1_BuildConfigStatus(in *buildapi.BuildConfigStatus, out *apiv1.BuildConfigStatus, s conversion.Scope) error { +func convert_api_BuildConfigSpec_To_v1_BuildConfigSpec(in *buildapi.BuildConfigSpec, out *apiv1.BuildConfigSpec, s conversion.Scope) error { + return autoconvert_api_BuildConfigSpec_To_v1_BuildConfigSpec(in, out, s) +} + +func autoconvert_api_BuildConfigStatus_To_v1_BuildConfigStatus(in *buildapi.BuildConfigStatus, out *apiv1.BuildConfigStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildConfigStatus))(in) } @@ -624,14 +1174,18 @@ func convert_api_BuildConfigStatus_To_v1_BuildConfigStatus(in *buildapi.BuildCon return nil } -func convert_api_BuildList_To_v1_BuildList(in *buildapi.BuildList, out *apiv1.BuildList, s conversion.Scope) error { +func convert_api_BuildConfigStatus_To_v1_BuildConfigStatus(in *buildapi.BuildConfigStatus, out *apiv1.BuildConfigStatus, s conversion.Scope) error { + return autoconvert_api_BuildConfigStatus_To_v1_BuildConfigStatus(in, out, s) +} + +func autoconvert_api_BuildList_To_v1_BuildList(in *buildapi.BuildList, out *apiv1.BuildList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -647,24 +1201,32 @@ func convert_api_BuildList_To_v1_BuildList(in *buildapi.BuildList, out *apiv1.Bu return nil } -func convert_api_BuildLog_To_v1_BuildLog(in *buildapi.BuildLog, out *apiv1.BuildLog, s conversion.Scope) error { +func convert_api_BuildList_To_v1_BuildList(in *buildapi.BuildList, out *apiv1.BuildList, s conversion.Scope) error { + return autoconvert_api_BuildList_To_v1_BuildList(in, out, s) +} + +func autoconvert_api_BuildLog_To_v1_BuildLog(in *buildapi.BuildLog, out *apiv1.BuildLog, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildLog))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } return nil } -func convert_api_BuildLogOptions_To_v1_BuildLogOptions(in *buildapi.BuildLogOptions, out *apiv1.BuildLogOptions, s conversion.Scope) error { +func convert_api_BuildLog_To_v1_BuildLog(in *buildapi.BuildLog, out *apiv1.BuildLog, s conversion.Scope) error { + return autoconvert_api_BuildLog_To_v1_BuildLog(in, out, s) +} + +func autoconvert_api_BuildLogOptions_To_v1_BuildLogOptions(in *buildapi.BuildLogOptions, out *apiv1.BuildLogOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildLogOptions))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Follow = in.Follow @@ -672,11 +1234,38 @@ func convert_api_BuildLogOptions_To_v1_BuildLogOptions(in *buildapi.BuildLogOpti return nil } -func convert_api_BuildRequest_To_v1_BuildRequest(in *buildapi.BuildRequest, out *apiv1.BuildRequest, s conversion.Scope) error { +func convert_api_BuildLogOptions_To_v1_BuildLogOptions(in *buildapi.BuildLogOptions, out *apiv1.BuildLogOptions, s conversion.Scope) error { + return autoconvert_api_BuildLogOptions_To_v1_BuildLogOptions(in, out, s) +} + +func autoconvert_api_BuildOutput_To_v1_BuildOutput(in *buildapi.BuildOutput, out *apiv1.BuildOutput, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.BuildOutput))(in) + } + if in.To != nil { + out.To = new(pkgapiv1.ObjectReference) + if err := convert_api_ObjectReference_To_v1_ObjectReference(in.To, out.To, s); err != nil { + return err + } + } else { + out.To = nil + } + if in.PushSecret != nil { + out.PushSecret = new(pkgapiv1.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(in.PushSecret, out.PushSecret, s); err != nil { + return err + } + } else { + out.PushSecret = nil + } + return nil +} + +func autoconvert_api_BuildRequest_To_v1_BuildRequest(in *buildapi.BuildRequest, out *apiv1.BuildRequest, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildRequest))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -715,7 +1304,11 @@ func convert_api_BuildRequest_To_v1_BuildRequest(in *buildapi.BuildRequest, out return nil } -func convert_api_BuildSource_To_v1_BuildSource(in *buildapi.BuildSource, out *apiv1.BuildSource, s conversion.Scope) error { +func convert_api_BuildRequest_To_v1_BuildRequest(in *buildapi.BuildRequest, out *apiv1.BuildRequest, s conversion.Scope) error { + return autoconvert_api_BuildRequest_To_v1_BuildRequest(in, out, s) +} + +func autoconvert_api_BuildSource_To_v1_BuildSource(in *buildapi.BuildSource, out *apiv1.BuildSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildSource))(in) } @@ -746,7 +1339,11 @@ func convert_api_BuildSource_To_v1_BuildSource(in *buildapi.BuildSource, out *ap return nil } -func convert_api_BuildSpec_To_v1_BuildSpec(in *buildapi.BuildSpec, out *apiv1.BuildSpec, s conversion.Scope) error { +func convert_api_BuildSource_To_v1_BuildSource(in *buildapi.BuildSource, out *apiv1.BuildSource, s conversion.Scope) error { + return autoconvert_api_BuildSource_To_v1_BuildSource(in, out, s) +} + +func autoconvert_api_BuildSpec_To_v1_BuildSpec(in *buildapi.BuildSpec, out *apiv1.BuildSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildSpec))(in) } @@ -780,7 +1377,11 @@ func convert_api_BuildSpec_To_v1_BuildSpec(in *buildapi.BuildSpec, out *apiv1.Bu return nil } -func convert_api_BuildStatus_To_v1_BuildStatus(in *buildapi.BuildStatus, out *apiv1.BuildStatus, s conversion.Scope) error { +func convert_api_BuildSpec_To_v1_BuildSpec(in *buildapi.BuildSpec, out *apiv1.BuildSpec, s conversion.Scope) error { + return autoconvert_api_BuildSpec_To_v1_BuildSpec(in, out, s) +} + +func autoconvert_api_BuildStatus_To_v1_BuildStatus(in *buildapi.BuildStatus, out *apiv1.BuildStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildStatus))(in) } @@ -814,7 +1415,11 @@ func convert_api_BuildStatus_To_v1_BuildStatus(in *buildapi.BuildStatus, out *ap return nil } -func convert_api_BuildStrategy_To_v1_BuildStrategy(in *buildapi.BuildStrategy, out *apiv1.BuildStrategy, s conversion.Scope) error { +func convert_api_BuildStatus_To_v1_BuildStatus(in *buildapi.BuildStatus, out *apiv1.BuildStatus, s conversion.Scope) error { + return autoconvert_api_BuildStatus_To_v1_BuildStatus(in, out, s) +} + +func autoconvert_api_BuildStrategy_To_v1_BuildStrategy(in *buildapi.BuildStrategy, out *apiv1.BuildStrategy, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildStrategy))(in) } @@ -831,19 +1436,130 @@ func convert_api_BuildStrategy_To_v1_BuildStrategy(in *buildapi.BuildStrategy, o return err } } else { - out.SourceStrategy = nil + out.SourceStrategy = nil + } + if in.CustomStrategy != nil { + if err := s.Convert(&in.CustomStrategy, &out.CustomStrategy, 0); err != nil { + return err + } + } else { + out.CustomStrategy = nil + } + return nil +} + +func convert_api_BuildStrategy_To_v1_BuildStrategy(in *buildapi.BuildStrategy, out *apiv1.BuildStrategy, s conversion.Scope) error { + return autoconvert_api_BuildStrategy_To_v1_BuildStrategy(in, out, s) +} + +func autoconvert_api_BuildTriggerPolicy_To_v1_BuildTriggerPolicy(in *buildapi.BuildTriggerPolicy, out *apiv1.BuildTriggerPolicy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.BuildTriggerPolicy))(in) + } + out.Type = apiv1.BuildTriggerType(in.Type) + if in.GitHubWebHook != nil { + out.GitHubWebHook = new(apiv1.WebHookTrigger) + if err := convert_api_WebHookTrigger_To_v1_WebHookTrigger(in.GitHubWebHook, out.GitHubWebHook, s); err != nil { + return err + } + } else { + out.GitHubWebHook = nil + } + if in.GenericWebHook != nil { + out.GenericWebHook = new(apiv1.WebHookTrigger) + if err := convert_api_WebHookTrigger_To_v1_WebHookTrigger(in.GenericWebHook, out.GenericWebHook, s); err != nil { + return err + } + } else { + out.GenericWebHook = nil + } + if in.ImageChange != nil { + out.ImageChange = new(apiv1.ImageChangeTrigger) + if err := convert_api_ImageChangeTrigger_To_v1_ImageChangeTrigger(in.ImageChange, out.ImageChange, s); err != nil { + return err + } + } else { + out.ImageChange = nil + } + return nil +} + +func autoconvert_api_CustomBuildStrategy_To_v1_CustomBuildStrategy(in *buildapi.CustomBuildStrategy, out *apiv1.CustomBuildStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.CustomBuildStrategy))(in) + } + if err := convert_api_ObjectReference_To_v1_ObjectReference(&in.From, &out.From, s); err != nil { + return err + } + if in.PullSecret != nil { + out.PullSecret = new(pkgapiv1.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil + } + if in.Env != nil { + out.Env = make([]pkgapiv1.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_api_EnvVar_To_v1_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + out.ExposeDockerSocket = in.ExposeDockerSocket + out.ForcePull = in.ForcePull + if in.Secrets != nil { + out.Secrets = make([]apiv1.SecretSpec, len(in.Secrets)) + for i := range in.Secrets { + if err := convert_api_SecretSpec_To_v1_SecretSpec(&in.Secrets[i], &out.Secrets[i], s); err != nil { + return err + } + } + } else { + out.Secrets = nil + } + return nil +} + +func autoconvert_api_DockerBuildStrategy_To_v1_DockerBuildStrategy(in *buildapi.DockerBuildStrategy, out *apiv1.DockerBuildStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.DockerBuildStrategy))(in) + } + if in.From != nil { + out.From = new(pkgapiv1.ObjectReference) + if err := convert_api_ObjectReference_To_v1_ObjectReference(in.From, out.From, s); err != nil { + return err + } + } else { + out.From = nil + } + if in.PullSecret != nil { + out.PullSecret = new(pkgapiv1.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil } - if in.CustomStrategy != nil { - if err := s.Convert(&in.CustomStrategy, &out.CustomStrategy, 0); err != nil { - return err + out.NoCache = in.NoCache + if in.Env != nil { + out.Env = make([]pkgapiv1.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_api_EnvVar_To_v1_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } } } else { - out.CustomStrategy = nil + out.Env = nil } + out.ForcePull = in.ForcePull return nil } -func convert_api_GitBuildSource_To_v1_GitBuildSource(in *buildapi.GitBuildSource, out *apiv1.GitBuildSource, s conversion.Scope) error { +func autoconvert_api_GitBuildSource_To_v1_GitBuildSource(in *buildapi.GitBuildSource, out *apiv1.GitBuildSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.GitBuildSource))(in) } @@ -854,7 +1570,11 @@ func convert_api_GitBuildSource_To_v1_GitBuildSource(in *buildapi.GitBuildSource return nil } -func convert_api_GitSourceRevision_To_v1_GitSourceRevision(in *buildapi.GitSourceRevision, out *apiv1.GitSourceRevision, s conversion.Scope) error { +func convert_api_GitBuildSource_To_v1_GitBuildSource(in *buildapi.GitBuildSource, out *apiv1.GitBuildSource, s conversion.Scope) error { + return autoconvert_api_GitBuildSource_To_v1_GitBuildSource(in, out, s) +} + +func autoconvert_api_GitSourceRevision_To_v1_GitSourceRevision(in *buildapi.GitSourceRevision, out *apiv1.GitSourceRevision, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.GitSourceRevision))(in) } @@ -869,7 +1589,11 @@ func convert_api_GitSourceRevision_To_v1_GitSourceRevision(in *buildapi.GitSourc return nil } -func convert_api_ImageChangeTrigger_To_v1_ImageChangeTrigger(in *buildapi.ImageChangeTrigger, out *apiv1.ImageChangeTrigger, s conversion.Scope) error { +func convert_api_GitSourceRevision_To_v1_GitSourceRevision(in *buildapi.GitSourceRevision, out *apiv1.GitSourceRevision, s conversion.Scope) error { + return autoconvert_api_GitSourceRevision_To_v1_GitSourceRevision(in, out, s) +} + +func autoconvert_api_ImageChangeTrigger_To_v1_ImageChangeTrigger(in *buildapi.ImageChangeTrigger, out *apiv1.ImageChangeTrigger, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.ImageChangeTrigger))(in) } @@ -885,7 +1609,11 @@ func convert_api_ImageChangeTrigger_To_v1_ImageChangeTrigger(in *buildapi.ImageC return nil } -func convert_api_SecretSpec_To_v1_SecretSpec(in *buildapi.SecretSpec, out *apiv1.SecretSpec, s conversion.Scope) error { +func convert_api_ImageChangeTrigger_To_v1_ImageChangeTrigger(in *buildapi.ImageChangeTrigger, out *apiv1.ImageChangeTrigger, s conversion.Scope) error { + return autoconvert_api_ImageChangeTrigger_To_v1_ImageChangeTrigger(in, out, s) +} + +func autoconvert_api_SecretSpec_To_v1_SecretSpec(in *buildapi.SecretSpec, out *apiv1.SecretSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.SecretSpec))(in) } @@ -896,7 +1624,42 @@ func convert_api_SecretSpec_To_v1_SecretSpec(in *buildapi.SecretSpec, out *apiv1 return nil } -func convert_api_SourceControlUser_To_v1_SourceControlUser(in *buildapi.SourceControlUser, out *apiv1.SourceControlUser, s conversion.Scope) error { +func convert_api_SecretSpec_To_v1_SecretSpec(in *buildapi.SecretSpec, out *apiv1.SecretSpec, s conversion.Scope) error { + return autoconvert_api_SecretSpec_To_v1_SecretSpec(in, out, s) +} + +func autoconvert_api_SourceBuildStrategy_To_v1_SourceBuildStrategy(in *buildapi.SourceBuildStrategy, out *apiv1.SourceBuildStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.SourceBuildStrategy))(in) + } + if err := convert_api_ObjectReference_To_v1_ObjectReference(&in.From, &out.From, s); err != nil { + return err + } + if in.PullSecret != nil { + out.PullSecret = new(pkgapiv1.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil + } + if in.Env != nil { + out.Env = make([]pkgapiv1.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_api_EnvVar_To_v1_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + out.Scripts = in.Scripts + out.Incremental = in.Incremental + out.ForcePull = in.ForcePull + return nil +} + +func autoconvert_api_SourceControlUser_To_v1_SourceControlUser(in *buildapi.SourceControlUser, out *apiv1.SourceControlUser, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.SourceControlUser))(in) } @@ -905,7 +1668,11 @@ func convert_api_SourceControlUser_To_v1_SourceControlUser(in *buildapi.SourceCo return nil } -func convert_api_SourceRevision_To_v1_SourceRevision(in *buildapi.SourceRevision, out *apiv1.SourceRevision, s conversion.Scope) error { +func convert_api_SourceControlUser_To_v1_SourceControlUser(in *buildapi.SourceControlUser, out *apiv1.SourceControlUser, s conversion.Scope) error { + return autoconvert_api_SourceControlUser_To_v1_SourceControlUser(in, out, s) +} + +func autoconvert_api_SourceRevision_To_v1_SourceRevision(in *buildapi.SourceRevision, out *apiv1.SourceRevision, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.SourceRevision))(in) } @@ -921,7 +1688,11 @@ func convert_api_SourceRevision_To_v1_SourceRevision(in *buildapi.SourceRevision return nil } -func convert_api_WebHookTrigger_To_v1_WebHookTrigger(in *buildapi.WebHookTrigger, out *apiv1.WebHookTrigger, s conversion.Scope) error { +func convert_api_SourceRevision_To_v1_SourceRevision(in *buildapi.SourceRevision, out *apiv1.SourceRevision, s conversion.Scope) error { + return autoconvert_api_SourceRevision_To_v1_SourceRevision(in, out, s) +} + +func autoconvert_api_WebHookTrigger_To_v1_WebHookTrigger(in *buildapi.WebHookTrigger, out *apiv1.WebHookTrigger, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.WebHookTrigger))(in) } @@ -929,11 +1700,15 @@ func convert_api_WebHookTrigger_To_v1_WebHookTrigger(in *buildapi.WebHookTrigger return nil } -func convert_v1_Build_To_api_Build(in *apiv1.Build, out *buildapi.Build, s conversion.Scope) error { +func convert_api_WebHookTrigger_To_v1_WebHookTrigger(in *buildapi.WebHookTrigger, out *apiv1.WebHookTrigger, s conversion.Scope) error { + return autoconvert_api_WebHookTrigger_To_v1_WebHookTrigger(in, out, s) +} + +func autoconvert_v1_Build_To_api_Build(in *apiv1.Build, out *buildapi.Build, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.Build))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -948,11 +1723,15 @@ func convert_v1_Build_To_api_Build(in *apiv1.Build, out *buildapi.Build, s conve return nil } -func convert_v1_BuildConfig_To_api_BuildConfig(in *apiv1.BuildConfig, out *buildapi.BuildConfig, s conversion.Scope) error { +func convert_v1_Build_To_api_Build(in *apiv1.Build, out *buildapi.Build, s conversion.Scope) error { + return autoconvert_v1_Build_To_api_Build(in, out, s) +} + +func autoconvert_v1_BuildConfig_To_api_BuildConfig(in *apiv1.BuildConfig, out *buildapi.BuildConfig, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildConfig))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -967,14 +1746,18 @@ func convert_v1_BuildConfig_To_api_BuildConfig(in *apiv1.BuildConfig, out *build return nil } -func convert_v1_BuildConfigList_To_api_BuildConfigList(in *apiv1.BuildConfigList, out *buildapi.BuildConfigList, s conversion.Scope) error { +func convert_v1_BuildConfig_To_api_BuildConfig(in *apiv1.BuildConfig, out *buildapi.BuildConfig, s conversion.Scope) error { + return autoconvert_v1_BuildConfig_To_api_BuildConfig(in, out, s) +} + +func autoconvert_v1_BuildConfigList_To_api_BuildConfigList(in *apiv1.BuildConfigList, out *buildapi.BuildConfigList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildConfigList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -990,7 +1773,11 @@ func convert_v1_BuildConfigList_To_api_BuildConfigList(in *apiv1.BuildConfigList return nil } -func convert_v1_BuildConfigSpec_To_api_BuildConfigSpec(in *apiv1.BuildConfigSpec, out *buildapi.BuildConfigSpec, s conversion.Scope) error { +func convert_v1_BuildConfigList_To_api_BuildConfigList(in *apiv1.BuildConfigList, out *buildapi.BuildConfigList, s conversion.Scope) error { + return autoconvert_v1_BuildConfigList_To_api_BuildConfigList(in, out, s) +} + +func autoconvert_v1_BuildConfigSpec_To_api_BuildConfigSpec(in *apiv1.BuildConfigSpec, out *buildapi.BuildConfigSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildConfigSpec))(in) } @@ -1010,7 +1797,11 @@ func convert_v1_BuildConfigSpec_To_api_BuildConfigSpec(in *apiv1.BuildConfigSpec return nil } -func convert_v1_BuildConfigStatus_To_api_BuildConfigStatus(in *apiv1.BuildConfigStatus, out *buildapi.BuildConfigStatus, s conversion.Scope) error { +func convert_v1_BuildConfigSpec_To_api_BuildConfigSpec(in *apiv1.BuildConfigSpec, out *buildapi.BuildConfigSpec, s conversion.Scope) error { + return autoconvert_v1_BuildConfigSpec_To_api_BuildConfigSpec(in, out, s) +} + +func autoconvert_v1_BuildConfigStatus_To_api_BuildConfigStatus(in *apiv1.BuildConfigStatus, out *buildapi.BuildConfigStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildConfigStatus))(in) } @@ -1018,14 +1809,18 @@ func convert_v1_BuildConfigStatus_To_api_BuildConfigStatus(in *apiv1.BuildConfig return nil } -func convert_v1_BuildList_To_api_BuildList(in *apiv1.BuildList, out *buildapi.BuildList, s conversion.Scope) error { +func convert_v1_BuildConfigStatus_To_api_BuildConfigStatus(in *apiv1.BuildConfigStatus, out *buildapi.BuildConfigStatus, s conversion.Scope) error { + return autoconvert_v1_BuildConfigStatus_To_api_BuildConfigStatus(in, out, s) +} + +func autoconvert_v1_BuildList_To_api_BuildList(in *apiv1.BuildList, out *buildapi.BuildList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1041,24 +1836,32 @@ func convert_v1_BuildList_To_api_BuildList(in *apiv1.BuildList, out *buildapi.Bu return nil } -func convert_v1_BuildLog_To_api_BuildLog(in *apiv1.BuildLog, out *buildapi.BuildLog, s conversion.Scope) error { +func convert_v1_BuildList_To_api_BuildList(in *apiv1.BuildList, out *buildapi.BuildList, s conversion.Scope) error { + return autoconvert_v1_BuildList_To_api_BuildList(in, out, s) +} + +func autoconvert_v1_BuildLog_To_api_BuildLog(in *apiv1.BuildLog, out *buildapi.BuildLog, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildLog))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } return nil } -func convert_v1_BuildLogOptions_To_api_BuildLogOptions(in *apiv1.BuildLogOptions, out *buildapi.BuildLogOptions, s conversion.Scope) error { +func convert_v1_BuildLog_To_api_BuildLog(in *apiv1.BuildLog, out *buildapi.BuildLog, s conversion.Scope) error { + return autoconvert_v1_BuildLog_To_api_BuildLog(in, out, s) +} + +func autoconvert_v1_BuildLogOptions_To_api_BuildLogOptions(in *apiv1.BuildLogOptions, out *buildapi.BuildLogOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildLogOptions))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Follow = in.Follow @@ -1066,11 +1869,38 @@ func convert_v1_BuildLogOptions_To_api_BuildLogOptions(in *apiv1.BuildLogOptions return nil } -func convert_v1_BuildRequest_To_api_BuildRequest(in *apiv1.BuildRequest, out *buildapi.BuildRequest, s conversion.Scope) error { +func convert_v1_BuildLogOptions_To_api_BuildLogOptions(in *apiv1.BuildLogOptions, out *buildapi.BuildLogOptions, s conversion.Scope) error { + return autoconvert_v1_BuildLogOptions_To_api_BuildLogOptions(in, out, s) +} + +func autoconvert_v1_BuildOutput_To_api_BuildOutput(in *apiv1.BuildOutput, out *buildapi.BuildOutput, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*apiv1.BuildOutput))(in) + } + if in.To != nil { + out.To = new(pkgapi.ObjectReference) + if err := convert_v1_ObjectReference_To_api_ObjectReference(in.To, out.To, s); err != nil { + return err + } + } else { + out.To = nil + } + if in.PushSecret != nil { + out.PushSecret = new(pkgapi.LocalObjectReference) + if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.PushSecret, out.PushSecret, s); err != nil { + return err + } + } else { + out.PushSecret = nil + } + return nil +} + +func autoconvert_v1_BuildRequest_To_api_BuildRequest(in *apiv1.BuildRequest, out *buildapi.BuildRequest, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildRequest))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1109,7 +1939,11 @@ func convert_v1_BuildRequest_To_api_BuildRequest(in *apiv1.BuildRequest, out *bu return nil } -func convert_v1_BuildSource_To_api_BuildSource(in *apiv1.BuildSource, out *buildapi.BuildSource, s conversion.Scope) error { +func convert_v1_BuildRequest_To_api_BuildRequest(in *apiv1.BuildRequest, out *buildapi.BuildRequest, s conversion.Scope) error { + return autoconvert_v1_BuildRequest_To_api_BuildRequest(in, out, s) +} + +func autoconvert_v1_BuildSource_To_api_BuildSource(in *apiv1.BuildSource, out *buildapi.BuildSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildSource))(in) } @@ -1140,7 +1974,11 @@ func convert_v1_BuildSource_To_api_BuildSource(in *apiv1.BuildSource, out *build return nil } -func convert_v1_BuildSpec_To_api_BuildSpec(in *apiv1.BuildSpec, out *buildapi.BuildSpec, s conversion.Scope) error { +func convert_v1_BuildSource_To_api_BuildSource(in *apiv1.BuildSource, out *buildapi.BuildSource, s conversion.Scope) error { + return autoconvert_v1_BuildSource_To_api_BuildSource(in, out, s) +} + +func autoconvert_v1_BuildSpec_To_api_BuildSpec(in *apiv1.BuildSpec, out *buildapi.BuildSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildSpec))(in) } @@ -1174,7 +2012,11 @@ func convert_v1_BuildSpec_To_api_BuildSpec(in *apiv1.BuildSpec, out *buildapi.Bu return nil } -func convert_v1_BuildStatus_To_api_BuildStatus(in *apiv1.BuildStatus, out *buildapi.BuildStatus, s conversion.Scope) error { +func convert_v1_BuildSpec_To_api_BuildSpec(in *apiv1.BuildSpec, out *buildapi.BuildSpec, s conversion.Scope) error { + return autoconvert_v1_BuildSpec_To_api_BuildSpec(in, out, s) +} + +func autoconvert_v1_BuildStatus_To_api_BuildStatus(in *apiv1.BuildStatus, out *buildapi.BuildStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildStatus))(in) } @@ -1208,7 +2050,11 @@ func convert_v1_BuildStatus_To_api_BuildStatus(in *apiv1.BuildStatus, out *build return nil } -func convert_v1_BuildStrategy_To_api_BuildStrategy(in *apiv1.BuildStrategy, out *buildapi.BuildStrategy, s conversion.Scope) error { +func convert_v1_BuildStatus_To_api_BuildStatus(in *apiv1.BuildStatus, out *buildapi.BuildStatus, s conversion.Scope) error { + return autoconvert_v1_BuildStatus_To_api_BuildStatus(in, out, s) +} + +func autoconvert_v1_BuildStrategy_To_api_BuildStrategy(in *apiv1.BuildStrategy, out *buildapi.BuildStrategy, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.BuildStrategy))(in) } @@ -1237,7 +2083,118 @@ func convert_v1_BuildStrategy_To_api_BuildStrategy(in *apiv1.BuildStrategy, out return nil } -func convert_v1_GitBuildSource_To_api_GitBuildSource(in *apiv1.GitBuildSource, out *buildapi.GitBuildSource, s conversion.Scope) error { +func convert_v1_BuildStrategy_To_api_BuildStrategy(in *apiv1.BuildStrategy, out *buildapi.BuildStrategy, s conversion.Scope) error { + return autoconvert_v1_BuildStrategy_To_api_BuildStrategy(in, out, s) +} + +func autoconvert_v1_BuildTriggerPolicy_To_api_BuildTriggerPolicy(in *apiv1.BuildTriggerPolicy, out *buildapi.BuildTriggerPolicy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*apiv1.BuildTriggerPolicy))(in) + } + out.Type = buildapi.BuildTriggerType(in.Type) + if in.GitHubWebHook != nil { + out.GitHubWebHook = new(buildapi.WebHookTrigger) + if err := convert_v1_WebHookTrigger_To_api_WebHookTrigger(in.GitHubWebHook, out.GitHubWebHook, s); err != nil { + return err + } + } else { + out.GitHubWebHook = nil + } + if in.GenericWebHook != nil { + out.GenericWebHook = new(buildapi.WebHookTrigger) + if err := convert_v1_WebHookTrigger_To_api_WebHookTrigger(in.GenericWebHook, out.GenericWebHook, s); err != nil { + return err + } + } else { + out.GenericWebHook = nil + } + if in.ImageChange != nil { + out.ImageChange = new(buildapi.ImageChangeTrigger) + if err := convert_v1_ImageChangeTrigger_To_api_ImageChangeTrigger(in.ImageChange, out.ImageChange, s); err != nil { + return err + } + } else { + out.ImageChange = nil + } + return nil +} + +func autoconvert_v1_CustomBuildStrategy_To_api_CustomBuildStrategy(in *apiv1.CustomBuildStrategy, out *buildapi.CustomBuildStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*apiv1.CustomBuildStrategy))(in) + } + if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.From, &out.From, s); err != nil { + return err + } + if in.PullSecret != nil { + out.PullSecret = new(pkgapi.LocalObjectReference) + if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil + } + if in.Env != nil { + out.Env = make([]pkgapi.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_v1_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + out.ExposeDockerSocket = in.ExposeDockerSocket + out.ForcePull = in.ForcePull + if in.Secrets != nil { + out.Secrets = make([]buildapi.SecretSpec, len(in.Secrets)) + for i := range in.Secrets { + if err := convert_v1_SecretSpec_To_api_SecretSpec(&in.Secrets[i], &out.Secrets[i], s); err != nil { + return err + } + } + } else { + out.Secrets = nil + } + return nil +} + +func autoconvert_v1_DockerBuildStrategy_To_api_DockerBuildStrategy(in *apiv1.DockerBuildStrategy, out *buildapi.DockerBuildStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*apiv1.DockerBuildStrategy))(in) + } + if in.From != nil { + out.From = new(pkgapi.ObjectReference) + if err := convert_v1_ObjectReference_To_api_ObjectReference(in.From, out.From, s); err != nil { + return err + } + } else { + out.From = nil + } + if in.PullSecret != nil { + out.PullSecret = new(pkgapi.LocalObjectReference) + if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil + } + out.NoCache = in.NoCache + if in.Env != nil { + out.Env = make([]pkgapi.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_v1_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + out.ForcePull = in.ForcePull + return nil +} + +func autoconvert_v1_GitBuildSource_To_api_GitBuildSource(in *apiv1.GitBuildSource, out *buildapi.GitBuildSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.GitBuildSource))(in) } @@ -1248,7 +2205,11 @@ func convert_v1_GitBuildSource_To_api_GitBuildSource(in *apiv1.GitBuildSource, o return nil } -func convert_v1_GitSourceRevision_To_api_GitSourceRevision(in *apiv1.GitSourceRevision, out *buildapi.GitSourceRevision, s conversion.Scope) error { +func convert_v1_GitBuildSource_To_api_GitBuildSource(in *apiv1.GitBuildSource, out *buildapi.GitBuildSource, s conversion.Scope) error { + return autoconvert_v1_GitBuildSource_To_api_GitBuildSource(in, out, s) +} + +func autoconvert_v1_GitSourceRevision_To_api_GitSourceRevision(in *apiv1.GitSourceRevision, out *buildapi.GitSourceRevision, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.GitSourceRevision))(in) } @@ -1263,7 +2224,11 @@ func convert_v1_GitSourceRevision_To_api_GitSourceRevision(in *apiv1.GitSourceRe return nil } -func convert_v1_ImageChangeTrigger_To_api_ImageChangeTrigger(in *apiv1.ImageChangeTrigger, out *buildapi.ImageChangeTrigger, s conversion.Scope) error { +func convert_v1_GitSourceRevision_To_api_GitSourceRevision(in *apiv1.GitSourceRevision, out *buildapi.GitSourceRevision, s conversion.Scope) error { + return autoconvert_v1_GitSourceRevision_To_api_GitSourceRevision(in, out, s) +} + +func autoconvert_v1_ImageChangeTrigger_To_api_ImageChangeTrigger(in *apiv1.ImageChangeTrigger, out *buildapi.ImageChangeTrigger, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.ImageChangeTrigger))(in) } @@ -1279,7 +2244,11 @@ func convert_v1_ImageChangeTrigger_To_api_ImageChangeTrigger(in *apiv1.ImageChan return nil } -func convert_v1_SecretSpec_To_api_SecretSpec(in *apiv1.SecretSpec, out *buildapi.SecretSpec, s conversion.Scope) error { +func convert_v1_ImageChangeTrigger_To_api_ImageChangeTrigger(in *apiv1.ImageChangeTrigger, out *buildapi.ImageChangeTrigger, s conversion.Scope) error { + return autoconvert_v1_ImageChangeTrigger_To_api_ImageChangeTrigger(in, out, s) +} + +func autoconvert_v1_SecretSpec_To_api_SecretSpec(in *apiv1.SecretSpec, out *buildapi.SecretSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.SecretSpec))(in) } @@ -1290,7 +2259,42 @@ func convert_v1_SecretSpec_To_api_SecretSpec(in *apiv1.SecretSpec, out *buildapi return nil } -func convert_v1_SourceControlUser_To_api_SourceControlUser(in *apiv1.SourceControlUser, out *buildapi.SourceControlUser, s conversion.Scope) error { +func convert_v1_SecretSpec_To_api_SecretSpec(in *apiv1.SecretSpec, out *buildapi.SecretSpec, s conversion.Scope) error { + return autoconvert_v1_SecretSpec_To_api_SecretSpec(in, out, s) +} + +func autoconvert_v1_SourceBuildStrategy_To_api_SourceBuildStrategy(in *apiv1.SourceBuildStrategy, out *buildapi.SourceBuildStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*apiv1.SourceBuildStrategy))(in) + } + if err := convert_v1_ObjectReference_To_api_ObjectReference(&in.From, &out.From, s); err != nil { + return err + } + if in.PullSecret != nil { + out.PullSecret = new(pkgapi.LocalObjectReference) + if err := convert_v1_LocalObjectReference_To_api_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil + } + if in.Env != nil { + out.Env = make([]pkgapi.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_v1_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + out.Scripts = in.Scripts + out.Incremental = in.Incremental + out.ForcePull = in.ForcePull + return nil +} + +func autoconvert_v1_SourceControlUser_To_api_SourceControlUser(in *apiv1.SourceControlUser, out *buildapi.SourceControlUser, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.SourceControlUser))(in) } @@ -1299,7 +2303,11 @@ func convert_v1_SourceControlUser_To_api_SourceControlUser(in *apiv1.SourceContr return nil } -func convert_v1_SourceRevision_To_api_SourceRevision(in *apiv1.SourceRevision, out *buildapi.SourceRevision, s conversion.Scope) error { +func convert_v1_SourceControlUser_To_api_SourceControlUser(in *apiv1.SourceControlUser, out *buildapi.SourceControlUser, s conversion.Scope) error { + return autoconvert_v1_SourceControlUser_To_api_SourceControlUser(in, out, s) +} + +func autoconvert_v1_SourceRevision_To_api_SourceRevision(in *apiv1.SourceRevision, out *buildapi.SourceRevision, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.SourceRevision))(in) } @@ -1315,7 +2323,11 @@ func convert_v1_SourceRevision_To_api_SourceRevision(in *apiv1.SourceRevision, o return nil } -func convert_v1_WebHookTrigger_To_api_WebHookTrigger(in *apiv1.WebHookTrigger, out *buildapi.WebHookTrigger, s conversion.Scope) error { +func convert_v1_SourceRevision_To_api_SourceRevision(in *apiv1.SourceRevision, out *buildapi.SourceRevision, s conversion.Scope) error { + return autoconvert_v1_SourceRevision_To_api_SourceRevision(in, out, s) +} + +func autoconvert_v1_WebHookTrigger_To_api_WebHookTrigger(in *apiv1.WebHookTrigger, out *buildapi.WebHookTrigger, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1.WebHookTrigger))(in) } @@ -1323,14 +2335,35 @@ func convert_v1_WebHookTrigger_To_api_WebHookTrigger(in *apiv1.WebHookTrigger, o return nil } -func convert_api_DeploymentConfigList_To_v1_DeploymentConfigList(in *deployapi.DeploymentConfigList, out *deployapiv1.DeploymentConfigList, s conversion.Scope) error { +func convert_v1_WebHookTrigger_To_api_WebHookTrigger(in *apiv1.WebHookTrigger, out *buildapi.WebHookTrigger, s conversion.Scope) error { + return autoconvert_v1_WebHookTrigger_To_api_WebHookTrigger(in, out, s) +} + +func autoconvert_api_DeploymentConfig_To_v1_DeploymentConfig(in *deployapi.DeploymentConfig, out *deployapiv1.DeploymentConfig, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*deployapi.DeploymentConfig))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + // in.Triggers has no peer in out + // in.Template has no peer in out + // in.LatestVersion has no peer in out + // in.Details has no peer in out + return nil +} + +func autoconvert_api_DeploymentConfigList_To_v1_DeploymentConfigList(in *deployapi.DeploymentConfigList, out *deployapiv1.DeploymentConfigList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*deployapi.DeploymentConfigList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1346,11 +2379,15 @@ func convert_api_DeploymentConfigList_To_v1_DeploymentConfigList(in *deployapi.D return nil } -func convert_api_DeploymentConfigRollback_To_v1_DeploymentConfigRollback(in *deployapi.DeploymentConfigRollback, out *deployapiv1.DeploymentConfigRollback, s conversion.Scope) error { +func convert_api_DeploymentConfigList_To_v1_DeploymentConfigList(in *deployapi.DeploymentConfigList, out *deployapiv1.DeploymentConfigList, s conversion.Scope) error { + return autoconvert_api_DeploymentConfigList_To_v1_DeploymentConfigList(in, out, s) +} + +func autoconvert_api_DeploymentConfigRollback_To_v1_DeploymentConfigRollback(in *deployapi.DeploymentConfigRollback, out *deployapiv1.DeploymentConfigRollback, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*deployapi.DeploymentConfigRollback))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_DeploymentConfigRollbackSpec_To_v1_DeploymentConfigRollbackSpec(&in.Spec, &out.Spec, s); err != nil { @@ -1359,7 +2396,11 @@ func convert_api_DeploymentConfigRollback_To_v1_DeploymentConfigRollback(in *dep return nil } -func convert_api_DeploymentConfigRollbackSpec_To_v1_DeploymentConfigRollbackSpec(in *deployapi.DeploymentConfigRollbackSpec, out *deployapiv1.DeploymentConfigRollbackSpec, s conversion.Scope) error { +func convert_api_DeploymentConfigRollback_To_v1_DeploymentConfigRollback(in *deployapi.DeploymentConfigRollback, out *deployapiv1.DeploymentConfigRollback, s conversion.Scope) error { + return autoconvert_api_DeploymentConfigRollback_To_v1_DeploymentConfigRollback(in, out, s) +} + +func autoconvert_api_DeploymentConfigRollbackSpec_To_v1_DeploymentConfigRollbackSpec(in *deployapi.DeploymentConfigRollbackSpec, out *deployapiv1.DeploymentConfigRollbackSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*deployapi.DeploymentConfigRollbackSpec))(in) } @@ -1373,14 +2414,33 @@ func convert_api_DeploymentConfigRollbackSpec_To_v1_DeploymentConfigRollbackSpec return nil } -func convert_v1_DeploymentConfigList_To_api_DeploymentConfigList(in *deployapiv1.DeploymentConfigList, out *deployapi.DeploymentConfigList, s conversion.Scope) error { +func convert_api_DeploymentConfigRollbackSpec_To_v1_DeploymentConfigRollbackSpec(in *deployapi.DeploymentConfigRollbackSpec, out *deployapiv1.DeploymentConfigRollbackSpec, s conversion.Scope) error { + return autoconvert_api_DeploymentConfigRollbackSpec_To_v1_DeploymentConfigRollbackSpec(in, out, s) +} + +func autoconvert_v1_DeploymentConfig_To_api_DeploymentConfig(in *deployapiv1.DeploymentConfig, out *deployapi.DeploymentConfig, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*deployapiv1.DeploymentConfig))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + // in.Spec has no peer in out + // in.Status has no peer in out + return nil +} + +func autoconvert_v1_DeploymentConfigList_To_api_DeploymentConfigList(in *deployapiv1.DeploymentConfigList, out *deployapi.DeploymentConfigList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*deployapiv1.DeploymentConfigList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1396,11 +2456,15 @@ func convert_v1_DeploymentConfigList_To_api_DeploymentConfigList(in *deployapiv1 return nil } -func convert_v1_DeploymentConfigRollback_To_api_DeploymentConfigRollback(in *deployapiv1.DeploymentConfigRollback, out *deployapi.DeploymentConfigRollback, s conversion.Scope) error { +func convert_v1_DeploymentConfigList_To_api_DeploymentConfigList(in *deployapiv1.DeploymentConfigList, out *deployapi.DeploymentConfigList, s conversion.Scope) error { + return autoconvert_v1_DeploymentConfigList_To_api_DeploymentConfigList(in, out, s) +} + +func autoconvert_v1_DeploymentConfigRollback_To_api_DeploymentConfigRollback(in *deployapiv1.DeploymentConfigRollback, out *deployapi.DeploymentConfigRollback, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*deployapiv1.DeploymentConfigRollback))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec(&in.Spec, &out.Spec, s); err != nil { @@ -1409,7 +2473,11 @@ func convert_v1_DeploymentConfigRollback_To_api_DeploymentConfigRollback(in *dep return nil } -func convert_v1_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec(in *deployapiv1.DeploymentConfigRollbackSpec, out *deployapi.DeploymentConfigRollbackSpec, s conversion.Scope) error { +func convert_v1_DeploymentConfigRollback_To_api_DeploymentConfigRollback(in *deployapiv1.DeploymentConfigRollback, out *deployapi.DeploymentConfigRollback, s conversion.Scope) error { + return autoconvert_v1_DeploymentConfigRollback_To_api_DeploymentConfigRollback(in, out, s) +} + +func autoconvert_v1_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec(in *deployapiv1.DeploymentConfigRollbackSpec, out *deployapi.DeploymentConfigRollbackSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*deployapiv1.DeploymentConfigRollbackSpec))(in) } @@ -1423,14 +2491,37 @@ func convert_v1_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec return nil } -func convert_api_ImageList_To_v1_ImageList(in *imageapi.ImageList, out *imageapiv1.ImageList, s conversion.Scope) error { +func convert_v1_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec(in *deployapiv1.DeploymentConfigRollbackSpec, out *deployapi.DeploymentConfigRollbackSpec, s conversion.Scope) error { + return autoconvert_v1_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec(in, out, s) +} + +func autoconvert_api_Image_To_v1_Image(in *imageapi.Image, out *imageapiv1.Image, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapi.Image))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.DockerImageReference = in.DockerImageReference + if err := s.Convert(&in.DockerImageMetadata, &out.DockerImageMetadata, 0); err != nil { + return err + } + out.DockerImageMetadataVersion = in.DockerImageMetadataVersion + out.DockerImageManifest = in.DockerImageManifest + return nil +} + +func autoconvert_api_ImageList_To_v1_ImageList(in *imageapi.ImageList, out *imageapiv1.ImageList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*imageapi.ImageList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1446,11 +2537,15 @@ func convert_api_ImageList_To_v1_ImageList(in *imageapi.ImageList, out *imageapi return nil } -func convert_api_ImageStream_To_v1_ImageStream(in *imageapi.ImageStream, out *imageapiv1.ImageStream, s conversion.Scope) error { +func convert_api_ImageList_To_v1_ImageList(in *imageapi.ImageList, out *imageapiv1.ImageList, s conversion.Scope) error { + return autoconvert_api_ImageList_To_v1_ImageList(in, out, s) +} + +func autoconvert_api_ImageStream_To_v1_ImageStream(in *imageapi.ImageStream, out *imageapiv1.ImageStream, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*imageapi.ImageStream))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1465,11 +2560,15 @@ func convert_api_ImageStream_To_v1_ImageStream(in *imageapi.ImageStream, out *im return nil } -func convert_api_ImageStreamImage_To_v1_ImageStreamImage(in *imageapi.ImageStreamImage, out *imageapiv1.ImageStreamImage, s conversion.Scope) error { +func convert_api_ImageStream_To_v1_ImageStream(in *imageapi.ImageStream, out *imageapiv1.ImageStream, s conversion.Scope) error { + return autoconvert_api_ImageStream_To_v1_ImageStream(in, out, s) +} + +func autoconvert_api_ImageStreamImage_To_v1_ImageStreamImage(in *imageapi.ImageStreamImage, out *imageapiv1.ImageStreamImage, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*imageapi.ImageStreamImage))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1481,14 +2580,18 @@ func convert_api_ImageStreamImage_To_v1_ImageStreamImage(in *imageapi.ImageStrea return nil } -func convert_api_ImageStreamList_To_v1_ImageStreamList(in *imageapi.ImageStreamList, out *imageapiv1.ImageStreamList, s conversion.Scope) error { +func convert_api_ImageStreamImage_To_v1_ImageStreamImage(in *imageapi.ImageStreamImage, out *imageapiv1.ImageStreamImage, s conversion.Scope) error { + return autoconvert_api_ImageStreamImage_To_v1_ImageStreamImage(in, out, s) +} + +func autoconvert_api_ImageStreamList_To_v1_ImageStreamList(in *imageapi.ImageStreamList, out *imageapiv1.ImageStreamList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*imageapi.ImageStreamList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1504,11 +2607,55 @@ func convert_api_ImageStreamList_To_v1_ImageStreamList(in *imageapi.ImageStreamL return nil } -func convert_api_ImageStreamTag_To_v1_ImageStreamTag(in *imageapi.ImageStreamTag, out *imageapiv1.ImageStreamTag, s conversion.Scope) error { +func convert_api_ImageStreamList_To_v1_ImageStreamList(in *imageapi.ImageStreamList, out *imageapiv1.ImageStreamList, s conversion.Scope) error { + return autoconvert_api_ImageStreamList_To_v1_ImageStreamList(in, out, s) +} + +func autoconvert_api_ImageStreamMapping_To_v1_ImageStreamMapping(in *imageapi.ImageStreamMapping, out *imageapiv1.ImageStreamMapping, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapi.ImageStreamMapping))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + // in.DockerImageRepository has no peer in out + if err := s.Convert(&in.Image, &out.Image, 0); err != nil { + return err + } + out.Tag = in.Tag + return nil +} + +func autoconvert_api_ImageStreamSpec_To_v1_ImageStreamSpec(in *imageapi.ImageStreamSpec, out *imageapiv1.ImageStreamSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapi.ImageStreamSpec))(in) + } + out.DockerImageRepository = in.DockerImageRepository + if err := s.Convert(&in.Tags, &out.Tags, 0); err != nil { + return err + } + return nil +} + +func autoconvert_api_ImageStreamStatus_To_v1_ImageStreamStatus(in *imageapi.ImageStreamStatus, out *imageapiv1.ImageStreamStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapi.ImageStreamStatus))(in) + } + out.DockerImageRepository = in.DockerImageRepository + if err := s.Convert(&in.Tags, &out.Tags, 0); err != nil { + return err + } + return nil +} + +func autoconvert_api_ImageStreamTag_To_v1_ImageStreamTag(in *imageapi.ImageStreamTag, out *imageapiv1.ImageStreamTag, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*imageapi.ImageStreamTag))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1520,14 +2667,37 @@ func convert_api_ImageStreamTag_To_v1_ImageStreamTag(in *imageapi.ImageStreamTag return nil } -func convert_v1_ImageList_To_api_ImageList(in *imageapiv1.ImageList, out *imageapi.ImageList, s conversion.Scope) error { +func convert_api_ImageStreamTag_To_v1_ImageStreamTag(in *imageapi.ImageStreamTag, out *imageapiv1.ImageStreamTag, s conversion.Scope) error { + return autoconvert_api_ImageStreamTag_To_v1_ImageStreamTag(in, out, s) +} + +func autoconvert_v1_Image_To_api_Image(in *imageapiv1.Image, out *imageapi.Image, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapiv1.Image))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.DockerImageReference = in.DockerImageReference + if err := s.Convert(&in.DockerImageMetadata, &out.DockerImageMetadata, 0); err != nil { + return err + } + out.DockerImageMetadataVersion = in.DockerImageMetadataVersion + out.DockerImageManifest = in.DockerImageManifest + return nil +} + +func autoconvert_v1_ImageList_To_api_ImageList(in *imageapiv1.ImageList, out *imageapi.ImageList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*imageapiv1.ImageList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1543,11 +2713,15 @@ func convert_v1_ImageList_To_api_ImageList(in *imageapiv1.ImageList, out *imagea return nil } -func convert_v1_ImageStream_To_api_ImageStream(in *imageapiv1.ImageStream, out *imageapi.ImageStream, s conversion.Scope) error { +func convert_v1_ImageList_To_api_ImageList(in *imageapiv1.ImageList, out *imageapi.ImageList, s conversion.Scope) error { + return autoconvert_v1_ImageList_To_api_ImageList(in, out, s) +} + +func autoconvert_v1_ImageStream_To_api_ImageStream(in *imageapiv1.ImageStream, out *imageapi.ImageStream, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*imageapiv1.ImageStream))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1562,11 +2736,15 @@ func convert_v1_ImageStream_To_api_ImageStream(in *imageapiv1.ImageStream, out * return nil } -func convert_v1_ImageStreamImage_To_api_ImageStreamImage(in *imageapiv1.ImageStreamImage, out *imageapi.ImageStreamImage, s conversion.Scope) error { +func convert_v1_ImageStream_To_api_ImageStream(in *imageapiv1.ImageStream, out *imageapi.ImageStream, s conversion.Scope) error { + return autoconvert_v1_ImageStream_To_api_ImageStream(in, out, s) +} + +func autoconvert_v1_ImageStreamImage_To_api_ImageStreamImage(in *imageapiv1.ImageStreamImage, out *imageapi.ImageStreamImage, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*imageapiv1.ImageStreamImage))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1578,14 +2756,18 @@ func convert_v1_ImageStreamImage_To_api_ImageStreamImage(in *imageapiv1.ImageStr return nil } -func convert_v1_ImageStreamList_To_api_ImageStreamList(in *imageapiv1.ImageStreamList, out *imageapi.ImageStreamList, s conversion.Scope) error { +func convert_v1_ImageStreamImage_To_api_ImageStreamImage(in *imageapiv1.ImageStreamImage, out *imageapi.ImageStreamImage, s conversion.Scope) error { + return autoconvert_v1_ImageStreamImage_To_api_ImageStreamImage(in, out, s) +} + +func autoconvert_v1_ImageStreamList_To_api_ImageStreamList(in *imageapiv1.ImageStreamList, out *imageapi.ImageStreamList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*imageapiv1.ImageStreamList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1601,11 +2783,54 @@ func convert_v1_ImageStreamList_To_api_ImageStreamList(in *imageapiv1.ImageStrea return nil } -func convert_v1_ImageStreamTag_To_api_ImageStreamTag(in *imageapiv1.ImageStreamTag, out *imageapi.ImageStreamTag, s conversion.Scope) error { +func convert_v1_ImageStreamList_To_api_ImageStreamList(in *imageapiv1.ImageStreamList, out *imageapi.ImageStreamList, s conversion.Scope) error { + return autoconvert_v1_ImageStreamList_To_api_ImageStreamList(in, out, s) +} + +func autoconvert_v1_ImageStreamMapping_To_api_ImageStreamMapping(in *imageapiv1.ImageStreamMapping, out *imageapi.ImageStreamMapping, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapiv1.ImageStreamMapping))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Image, &out.Image, 0); err != nil { + return err + } + out.Tag = in.Tag + return nil +} + +func autoconvert_v1_ImageStreamSpec_To_api_ImageStreamSpec(in *imageapiv1.ImageStreamSpec, out *imageapi.ImageStreamSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapiv1.ImageStreamSpec))(in) + } + out.DockerImageRepository = in.DockerImageRepository + if err := s.Convert(&in.Tags, &out.Tags, 0); err != nil { + return err + } + return nil +} + +func autoconvert_v1_ImageStreamStatus_To_api_ImageStreamStatus(in *imageapiv1.ImageStreamStatus, out *imageapi.ImageStreamStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapiv1.ImageStreamStatus))(in) + } + out.DockerImageRepository = in.DockerImageRepository + if err := s.Convert(&in.Tags, &out.Tags, 0); err != nil { + return err + } + return nil +} + +func autoconvert_v1_ImageStreamTag_To_api_ImageStreamTag(in *imageapiv1.ImageStreamTag, out *imageapi.ImageStreamTag, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*imageapiv1.ImageStreamTag))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1617,11 +2842,15 @@ func convert_v1_ImageStreamTag_To_api_ImageStreamTag(in *imageapiv1.ImageStreamT return nil } -func convert_api_OAuthAccessToken_To_v1_OAuthAccessToken(in *oauthapi.OAuthAccessToken, out *oauthapiv1.OAuthAccessToken, s conversion.Scope) error { +func convert_v1_ImageStreamTag_To_api_ImageStreamTag(in *imageapiv1.ImageStreamTag, out *imageapi.ImageStreamTag, s conversion.Scope) error { + return autoconvert_v1_ImageStreamTag_To_api_ImageStreamTag(in, out, s) +} + +func autoconvert_api_OAuthAccessToken_To_v1_OAuthAccessToken(in *oauthapi.OAuthAccessToken, out *oauthapiv1.OAuthAccessToken, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthAccessToken))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1645,14 +2874,18 @@ func convert_api_OAuthAccessToken_To_v1_OAuthAccessToken(in *oauthapi.OAuthAcces return nil } -func convert_api_OAuthAccessTokenList_To_v1_OAuthAccessTokenList(in *oauthapi.OAuthAccessTokenList, out *oauthapiv1.OAuthAccessTokenList, s conversion.Scope) error { +func convert_api_OAuthAccessToken_To_v1_OAuthAccessToken(in *oauthapi.OAuthAccessToken, out *oauthapiv1.OAuthAccessToken, s conversion.Scope) error { + return autoconvert_api_OAuthAccessToken_To_v1_OAuthAccessToken(in, out, s) +} + +func autoconvert_api_OAuthAccessTokenList_To_v1_OAuthAccessTokenList(in *oauthapi.OAuthAccessTokenList, out *oauthapiv1.OAuthAccessTokenList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthAccessTokenList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1668,11 +2901,15 @@ func convert_api_OAuthAccessTokenList_To_v1_OAuthAccessTokenList(in *oauthapi.OA return nil } -func convert_api_OAuthAuthorizeToken_To_v1_OAuthAuthorizeToken(in *oauthapi.OAuthAuthorizeToken, out *oauthapiv1.OAuthAuthorizeToken, s conversion.Scope) error { +func convert_api_OAuthAccessTokenList_To_v1_OAuthAccessTokenList(in *oauthapi.OAuthAccessTokenList, out *oauthapiv1.OAuthAccessTokenList, s conversion.Scope) error { + return autoconvert_api_OAuthAccessTokenList_To_v1_OAuthAccessTokenList(in, out, s) +} + +func autoconvert_api_OAuthAuthorizeToken_To_v1_OAuthAuthorizeToken(in *oauthapi.OAuthAuthorizeToken, out *oauthapiv1.OAuthAuthorizeToken, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthAuthorizeToken))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1695,14 +2932,18 @@ func convert_api_OAuthAuthorizeToken_To_v1_OAuthAuthorizeToken(in *oauthapi.OAut return nil } -func convert_api_OAuthAuthorizeTokenList_To_v1_OAuthAuthorizeTokenList(in *oauthapi.OAuthAuthorizeTokenList, out *oauthapiv1.OAuthAuthorizeTokenList, s conversion.Scope) error { +func convert_api_OAuthAuthorizeToken_To_v1_OAuthAuthorizeToken(in *oauthapi.OAuthAuthorizeToken, out *oauthapiv1.OAuthAuthorizeToken, s conversion.Scope) error { + return autoconvert_api_OAuthAuthorizeToken_To_v1_OAuthAuthorizeToken(in, out, s) +} + +func autoconvert_api_OAuthAuthorizeTokenList_To_v1_OAuthAuthorizeTokenList(in *oauthapi.OAuthAuthorizeTokenList, out *oauthapiv1.OAuthAuthorizeTokenList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthAuthorizeTokenList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1718,11 +2959,15 @@ func convert_api_OAuthAuthorizeTokenList_To_v1_OAuthAuthorizeTokenList(in *oauth return nil } -func convert_api_OAuthClient_To_v1_OAuthClient(in *oauthapi.OAuthClient, out *oauthapiv1.OAuthClient, s conversion.Scope) error { +func convert_api_OAuthAuthorizeTokenList_To_v1_OAuthAuthorizeTokenList(in *oauthapi.OAuthAuthorizeTokenList, out *oauthapiv1.OAuthAuthorizeTokenList, s conversion.Scope) error { + return autoconvert_api_OAuthAuthorizeTokenList_To_v1_OAuthAuthorizeTokenList(in, out, s) +} + +func autoconvert_api_OAuthClient_To_v1_OAuthClient(in *oauthapi.OAuthClient, out *oauthapiv1.OAuthClient, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthClient))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1741,11 +2986,15 @@ func convert_api_OAuthClient_To_v1_OAuthClient(in *oauthapi.OAuthClient, out *oa return nil } -func convert_api_OAuthClientAuthorization_To_v1_OAuthClientAuthorization(in *oauthapi.OAuthClientAuthorization, out *oauthapiv1.OAuthClientAuthorization, s conversion.Scope) error { +func convert_api_OAuthClient_To_v1_OAuthClient(in *oauthapi.OAuthClient, out *oauthapiv1.OAuthClient, s conversion.Scope) error { + return autoconvert_api_OAuthClient_To_v1_OAuthClient(in, out, s) +} + +func autoconvert_api_OAuthClientAuthorization_To_v1_OAuthClientAuthorization(in *oauthapi.OAuthClientAuthorization, out *oauthapiv1.OAuthClientAuthorization, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthClientAuthorization))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1765,14 +3014,18 @@ func convert_api_OAuthClientAuthorization_To_v1_OAuthClientAuthorization(in *oau return nil } -func convert_api_OAuthClientAuthorizationList_To_v1_OAuthClientAuthorizationList(in *oauthapi.OAuthClientAuthorizationList, out *oauthapiv1.OAuthClientAuthorizationList, s conversion.Scope) error { +func convert_api_OAuthClientAuthorization_To_v1_OAuthClientAuthorization(in *oauthapi.OAuthClientAuthorization, out *oauthapiv1.OAuthClientAuthorization, s conversion.Scope) error { + return autoconvert_api_OAuthClientAuthorization_To_v1_OAuthClientAuthorization(in, out, s) +} + +func autoconvert_api_OAuthClientAuthorizationList_To_v1_OAuthClientAuthorizationList(in *oauthapi.OAuthClientAuthorizationList, out *oauthapiv1.OAuthClientAuthorizationList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthClientAuthorizationList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1788,14 +3041,18 @@ func convert_api_OAuthClientAuthorizationList_To_v1_OAuthClientAuthorizationList return nil } -func convert_api_OAuthClientList_To_v1_OAuthClientList(in *oauthapi.OAuthClientList, out *oauthapiv1.OAuthClientList, s conversion.Scope) error { +func convert_api_OAuthClientAuthorizationList_To_v1_OAuthClientAuthorizationList(in *oauthapi.OAuthClientAuthorizationList, out *oauthapiv1.OAuthClientAuthorizationList, s conversion.Scope) error { + return autoconvert_api_OAuthClientAuthorizationList_To_v1_OAuthClientAuthorizationList(in, out, s) +} + +func autoconvert_api_OAuthClientList_To_v1_OAuthClientList(in *oauthapi.OAuthClientList, out *oauthapiv1.OAuthClientList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthClientList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1811,11 +3068,15 @@ func convert_api_OAuthClientList_To_v1_OAuthClientList(in *oauthapi.OAuthClientL return nil } -func convert_v1_OAuthAccessToken_To_api_OAuthAccessToken(in *oauthapiv1.OAuthAccessToken, out *oauthapi.OAuthAccessToken, s conversion.Scope) error { +func convert_api_OAuthClientList_To_v1_OAuthClientList(in *oauthapi.OAuthClientList, out *oauthapiv1.OAuthClientList, s conversion.Scope) error { + return autoconvert_api_OAuthClientList_To_v1_OAuthClientList(in, out, s) +} + +func autoconvert_v1_OAuthAccessToken_To_api_OAuthAccessToken(in *oauthapiv1.OAuthAccessToken, out *oauthapi.OAuthAccessToken, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1.OAuthAccessToken))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1839,14 +3100,18 @@ func convert_v1_OAuthAccessToken_To_api_OAuthAccessToken(in *oauthapiv1.OAuthAcc return nil } -func convert_v1_OAuthAccessTokenList_To_api_OAuthAccessTokenList(in *oauthapiv1.OAuthAccessTokenList, out *oauthapi.OAuthAccessTokenList, s conversion.Scope) error { +func convert_v1_OAuthAccessToken_To_api_OAuthAccessToken(in *oauthapiv1.OAuthAccessToken, out *oauthapi.OAuthAccessToken, s conversion.Scope) error { + return autoconvert_v1_OAuthAccessToken_To_api_OAuthAccessToken(in, out, s) +} + +func autoconvert_v1_OAuthAccessTokenList_To_api_OAuthAccessTokenList(in *oauthapiv1.OAuthAccessTokenList, out *oauthapi.OAuthAccessTokenList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1.OAuthAccessTokenList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1862,11 +3127,15 @@ func convert_v1_OAuthAccessTokenList_To_api_OAuthAccessTokenList(in *oauthapiv1. return nil } -func convert_v1_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken(in *oauthapiv1.OAuthAuthorizeToken, out *oauthapi.OAuthAuthorizeToken, s conversion.Scope) error { +func convert_v1_OAuthAccessTokenList_To_api_OAuthAccessTokenList(in *oauthapiv1.OAuthAccessTokenList, out *oauthapi.OAuthAccessTokenList, s conversion.Scope) error { + return autoconvert_v1_OAuthAccessTokenList_To_api_OAuthAccessTokenList(in, out, s) +} + +func autoconvert_v1_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken(in *oauthapiv1.OAuthAuthorizeToken, out *oauthapi.OAuthAuthorizeToken, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1.OAuthAuthorizeToken))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1889,14 +3158,18 @@ func convert_v1_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken(in *oauthapiv1.OA return nil } -func convert_v1_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList(in *oauthapiv1.OAuthAuthorizeTokenList, out *oauthapi.OAuthAuthorizeTokenList, s conversion.Scope) error { +func convert_v1_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken(in *oauthapiv1.OAuthAuthorizeToken, out *oauthapi.OAuthAuthorizeToken, s conversion.Scope) error { + return autoconvert_v1_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken(in, out, s) +} + +func autoconvert_v1_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList(in *oauthapiv1.OAuthAuthorizeTokenList, out *oauthapi.OAuthAuthorizeTokenList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1.OAuthAuthorizeTokenList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1912,11 +3185,15 @@ func convert_v1_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList(in *oauth return nil } -func convert_v1_OAuthClient_To_api_OAuthClient(in *oauthapiv1.OAuthClient, out *oauthapi.OAuthClient, s conversion.Scope) error { +func convert_v1_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList(in *oauthapiv1.OAuthAuthorizeTokenList, out *oauthapi.OAuthAuthorizeTokenList, s conversion.Scope) error { + return autoconvert_v1_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList(in, out, s) +} + +func autoconvert_v1_OAuthClient_To_api_OAuthClient(in *oauthapiv1.OAuthClient, out *oauthapi.OAuthClient, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1.OAuthClient))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1935,11 +3212,15 @@ func convert_v1_OAuthClient_To_api_OAuthClient(in *oauthapiv1.OAuthClient, out * return nil } -func convert_v1_OAuthClientAuthorization_To_api_OAuthClientAuthorization(in *oauthapiv1.OAuthClientAuthorization, out *oauthapi.OAuthClientAuthorization, s conversion.Scope) error { +func convert_v1_OAuthClient_To_api_OAuthClient(in *oauthapiv1.OAuthClient, out *oauthapi.OAuthClient, s conversion.Scope) error { + return autoconvert_v1_OAuthClient_To_api_OAuthClient(in, out, s) +} + +func autoconvert_v1_OAuthClientAuthorization_To_api_OAuthClientAuthorization(in *oauthapiv1.OAuthClientAuthorization, out *oauthapi.OAuthClientAuthorization, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1.OAuthClientAuthorization))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1959,14 +3240,18 @@ func convert_v1_OAuthClientAuthorization_To_api_OAuthClientAuthorization(in *oau return nil } -func convert_v1_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList(in *oauthapiv1.OAuthClientAuthorizationList, out *oauthapi.OAuthClientAuthorizationList, s conversion.Scope) error { +func convert_v1_OAuthClientAuthorization_To_api_OAuthClientAuthorization(in *oauthapiv1.OAuthClientAuthorization, out *oauthapi.OAuthClientAuthorization, s conversion.Scope) error { + return autoconvert_v1_OAuthClientAuthorization_To_api_OAuthClientAuthorization(in, out, s) +} + +func autoconvert_v1_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList(in *oauthapiv1.OAuthClientAuthorizationList, out *oauthapi.OAuthClientAuthorizationList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1.OAuthClientAuthorizationList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1982,14 +3267,18 @@ func convert_v1_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList return nil } -func convert_v1_OAuthClientList_To_api_OAuthClientList(in *oauthapiv1.OAuthClientList, out *oauthapi.OAuthClientList, s conversion.Scope) error { +func convert_v1_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList(in *oauthapiv1.OAuthClientAuthorizationList, out *oauthapi.OAuthClientAuthorizationList, s conversion.Scope) error { + return autoconvert_v1_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList(in, out, s) +} + +func autoconvert_v1_OAuthClientList_To_api_OAuthClientList(in *oauthapiv1.OAuthClientList, out *oauthapi.OAuthClientList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1.OAuthClientList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2005,11 +3294,15 @@ func convert_v1_OAuthClientList_To_api_OAuthClientList(in *oauthapiv1.OAuthClien return nil } -func convert_api_Project_To_v1_Project(in *projectapi.Project, out *projectapiv1.Project, s conversion.Scope) error { +func convert_v1_OAuthClientList_To_api_OAuthClientList(in *oauthapiv1.OAuthClientList, out *oauthapi.OAuthClientList, s conversion.Scope) error { + return autoconvert_v1_OAuthClientList_To_api_OAuthClientList(in, out, s) +} + +func autoconvert_api_Project_To_v1_Project(in *projectapi.Project, out *projectapiv1.Project, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapi.Project))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2024,14 +3317,18 @@ func convert_api_Project_To_v1_Project(in *projectapi.Project, out *projectapiv1 return nil } -func convert_api_ProjectList_To_v1_ProjectList(in *projectapi.ProjectList, out *projectapiv1.ProjectList, s conversion.Scope) error { +func convert_api_Project_To_v1_Project(in *projectapi.Project, out *projectapiv1.Project, s conversion.Scope) error { + return autoconvert_api_Project_To_v1_Project(in, out, s) +} + +func autoconvert_api_ProjectList_To_v1_ProjectList(in *projectapi.ProjectList, out *projectapiv1.ProjectList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapi.ProjectList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2047,11 +3344,15 @@ func convert_api_ProjectList_To_v1_ProjectList(in *projectapi.ProjectList, out * return nil } -func convert_api_ProjectRequest_To_v1_ProjectRequest(in *projectapi.ProjectRequest, out *projectapiv1.ProjectRequest, s conversion.Scope) error { +func convert_api_ProjectList_To_v1_ProjectList(in *projectapi.ProjectList, out *projectapiv1.ProjectList, s conversion.Scope) error { + return autoconvert_api_ProjectList_To_v1_ProjectList(in, out, s) +} + +func autoconvert_api_ProjectRequest_To_v1_ProjectRequest(in *projectapi.ProjectRequest, out *projectapiv1.ProjectRequest, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapi.ProjectRequest))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2062,7 +3363,11 @@ func convert_api_ProjectRequest_To_v1_ProjectRequest(in *projectapi.ProjectReque return nil } -func convert_api_ProjectSpec_To_v1_ProjectSpec(in *projectapi.ProjectSpec, out *projectapiv1.ProjectSpec, s conversion.Scope) error { +func convert_api_ProjectRequest_To_v1_ProjectRequest(in *projectapi.ProjectRequest, out *projectapiv1.ProjectRequest, s conversion.Scope) error { + return autoconvert_api_ProjectRequest_To_v1_ProjectRequest(in, out, s) +} + +func autoconvert_api_ProjectSpec_To_v1_ProjectSpec(in *projectapi.ProjectSpec, out *projectapiv1.ProjectSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapi.ProjectSpec))(in) } @@ -2077,7 +3382,11 @@ func convert_api_ProjectSpec_To_v1_ProjectSpec(in *projectapi.ProjectSpec, out * return nil } -func convert_api_ProjectStatus_To_v1_ProjectStatus(in *projectapi.ProjectStatus, out *projectapiv1.ProjectStatus, s conversion.Scope) error { +func convert_api_ProjectSpec_To_v1_ProjectSpec(in *projectapi.ProjectSpec, out *projectapiv1.ProjectSpec, s conversion.Scope) error { + return autoconvert_api_ProjectSpec_To_v1_ProjectSpec(in, out, s) +} + +func autoconvert_api_ProjectStatus_To_v1_ProjectStatus(in *projectapi.ProjectStatus, out *projectapiv1.ProjectStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapi.ProjectStatus))(in) } @@ -2085,11 +3394,15 @@ func convert_api_ProjectStatus_To_v1_ProjectStatus(in *projectapi.ProjectStatus, return nil } -func convert_v1_Project_To_api_Project(in *projectapiv1.Project, out *projectapi.Project, s conversion.Scope) error { +func convert_api_ProjectStatus_To_v1_ProjectStatus(in *projectapi.ProjectStatus, out *projectapiv1.ProjectStatus, s conversion.Scope) error { + return autoconvert_api_ProjectStatus_To_v1_ProjectStatus(in, out, s) +} + +func autoconvert_v1_Project_To_api_Project(in *projectapiv1.Project, out *projectapi.Project, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapiv1.Project))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2104,14 +3417,18 @@ func convert_v1_Project_To_api_Project(in *projectapiv1.Project, out *projectapi return nil } -func convert_v1_ProjectList_To_api_ProjectList(in *projectapiv1.ProjectList, out *projectapi.ProjectList, s conversion.Scope) error { +func convert_v1_Project_To_api_Project(in *projectapiv1.Project, out *projectapi.Project, s conversion.Scope) error { + return autoconvert_v1_Project_To_api_Project(in, out, s) +} + +func autoconvert_v1_ProjectList_To_api_ProjectList(in *projectapiv1.ProjectList, out *projectapi.ProjectList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapiv1.ProjectList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2127,11 +3444,15 @@ func convert_v1_ProjectList_To_api_ProjectList(in *projectapiv1.ProjectList, out return nil } -func convert_v1_ProjectRequest_To_api_ProjectRequest(in *projectapiv1.ProjectRequest, out *projectapi.ProjectRequest, s conversion.Scope) error { +func convert_v1_ProjectList_To_api_ProjectList(in *projectapiv1.ProjectList, out *projectapi.ProjectList, s conversion.Scope) error { + return autoconvert_v1_ProjectList_To_api_ProjectList(in, out, s) +} + +func autoconvert_v1_ProjectRequest_To_api_ProjectRequest(in *projectapiv1.ProjectRequest, out *projectapi.ProjectRequest, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapiv1.ProjectRequest))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2142,7 +3463,11 @@ func convert_v1_ProjectRequest_To_api_ProjectRequest(in *projectapiv1.ProjectReq return nil } -func convert_v1_ProjectSpec_To_api_ProjectSpec(in *projectapiv1.ProjectSpec, out *projectapi.ProjectSpec, s conversion.Scope) error { +func convert_v1_ProjectRequest_To_api_ProjectRequest(in *projectapiv1.ProjectRequest, out *projectapi.ProjectRequest, s conversion.Scope) error { + return autoconvert_v1_ProjectRequest_To_api_ProjectRequest(in, out, s) +} + +func autoconvert_v1_ProjectSpec_To_api_ProjectSpec(in *projectapiv1.ProjectSpec, out *projectapi.ProjectSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapiv1.ProjectSpec))(in) } @@ -2157,7 +3482,11 @@ func convert_v1_ProjectSpec_To_api_ProjectSpec(in *projectapiv1.ProjectSpec, out return nil } -func convert_v1_ProjectStatus_To_api_ProjectStatus(in *projectapiv1.ProjectStatus, out *projectapi.ProjectStatus, s conversion.Scope) error { +func convert_v1_ProjectSpec_To_api_ProjectSpec(in *projectapiv1.ProjectSpec, out *projectapi.ProjectSpec, s conversion.Scope) error { + return autoconvert_v1_ProjectSpec_To_api_ProjectSpec(in, out, s) +} + +func autoconvert_v1_ProjectStatus_To_api_ProjectStatus(in *projectapiv1.ProjectStatus, out *projectapi.ProjectStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapiv1.ProjectStatus))(in) } @@ -2165,11 +3494,15 @@ func convert_v1_ProjectStatus_To_api_ProjectStatus(in *projectapiv1.ProjectStatu return nil } -func convert_api_Route_To_v1_Route(in *routeapi.Route, out *routeapiv1.Route, s conversion.Scope) error { +func convert_v1_ProjectStatus_To_api_ProjectStatus(in *projectapiv1.ProjectStatus, out *projectapi.ProjectStatus, s conversion.Scope) error { + return autoconvert_v1_ProjectStatus_To_api_ProjectStatus(in, out, s) +} + +func autoconvert_api_Route_To_v1_Route(in *routeapi.Route, out *routeapiv1.Route, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.Route))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2184,14 +3517,18 @@ func convert_api_Route_To_v1_Route(in *routeapi.Route, out *routeapiv1.Route, s return nil } -func convert_api_RouteList_To_v1_RouteList(in *routeapi.RouteList, out *routeapiv1.RouteList, s conversion.Scope) error { +func convert_api_Route_To_v1_Route(in *routeapi.Route, out *routeapiv1.Route, s conversion.Scope) error { + return autoconvert_api_Route_To_v1_Route(in, out, s) +} + +func autoconvert_api_RouteList_To_v1_RouteList(in *routeapi.RouteList, out *routeapiv1.RouteList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.RouteList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2207,7 +3544,11 @@ func convert_api_RouteList_To_v1_RouteList(in *routeapi.RouteList, out *routeapi return nil } -func convert_api_RoutePort_To_v1_RoutePort(in *routeapi.RoutePort, out *routeapiv1.RoutePort, s conversion.Scope) error { +func convert_api_RouteList_To_v1_RouteList(in *routeapi.RouteList, out *routeapiv1.RouteList, s conversion.Scope) error { + return autoconvert_api_RouteList_To_v1_RouteList(in, out, s) +} + +func autoconvert_api_RoutePort_To_v1_RoutePort(in *routeapi.RoutePort, out *routeapiv1.RoutePort, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.RoutePort))(in) } @@ -2217,7 +3558,11 @@ func convert_api_RoutePort_To_v1_RoutePort(in *routeapi.RoutePort, out *routeapi return nil } -func convert_api_RouteSpec_To_v1_RouteSpec(in *routeapi.RouteSpec, out *routeapiv1.RouteSpec, s conversion.Scope) error { +func convert_api_RoutePort_To_v1_RoutePort(in *routeapi.RoutePort, out *routeapiv1.RoutePort, s conversion.Scope) error { + return autoconvert_api_RoutePort_To_v1_RoutePort(in, out, s) +} + +func autoconvert_api_RouteSpec_To_v1_RouteSpec(in *routeapi.RouteSpec, out *routeapiv1.RouteSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.RouteSpec))(in) } @@ -2245,14 +3590,22 @@ func convert_api_RouteSpec_To_v1_RouteSpec(in *routeapi.RouteSpec, out *routeapi return nil } -func convert_api_RouteStatus_To_v1_RouteStatus(in *routeapi.RouteStatus, out *routeapiv1.RouteStatus, s conversion.Scope) error { +func convert_api_RouteSpec_To_v1_RouteSpec(in *routeapi.RouteSpec, out *routeapiv1.RouteSpec, s conversion.Scope) error { + return autoconvert_api_RouteSpec_To_v1_RouteSpec(in, out, s) +} + +func autoconvert_api_RouteStatus_To_v1_RouteStatus(in *routeapi.RouteStatus, out *routeapiv1.RouteStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.RouteStatus))(in) } return nil } -func convert_api_TLSConfig_To_v1_TLSConfig(in *routeapi.TLSConfig, out *routeapiv1.TLSConfig, s conversion.Scope) error { +func convert_api_RouteStatus_To_v1_RouteStatus(in *routeapi.RouteStatus, out *routeapiv1.RouteStatus, s conversion.Scope) error { + return autoconvert_api_RouteStatus_To_v1_RouteStatus(in, out, s) +} + +func autoconvert_api_TLSConfig_To_v1_TLSConfig(in *routeapi.TLSConfig, out *routeapiv1.TLSConfig, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.TLSConfig))(in) } @@ -2264,11 +3617,15 @@ func convert_api_TLSConfig_To_v1_TLSConfig(in *routeapi.TLSConfig, out *routeapi return nil } -func convert_v1_Route_To_api_Route(in *routeapiv1.Route, out *routeapi.Route, s conversion.Scope) error { +func convert_api_TLSConfig_To_v1_TLSConfig(in *routeapi.TLSConfig, out *routeapiv1.TLSConfig, s conversion.Scope) error { + return autoconvert_api_TLSConfig_To_v1_TLSConfig(in, out, s) +} + +func autoconvert_v1_Route_To_api_Route(in *routeapiv1.Route, out *routeapi.Route, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1.Route))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2283,14 +3640,18 @@ func convert_v1_Route_To_api_Route(in *routeapiv1.Route, out *routeapi.Route, s return nil } -func convert_v1_RouteList_To_api_RouteList(in *routeapiv1.RouteList, out *routeapi.RouteList, s conversion.Scope) error { +func convert_v1_Route_To_api_Route(in *routeapiv1.Route, out *routeapi.Route, s conversion.Scope) error { + return autoconvert_v1_Route_To_api_Route(in, out, s) +} + +func autoconvert_v1_RouteList_To_api_RouteList(in *routeapiv1.RouteList, out *routeapi.RouteList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1.RouteList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2306,7 +3667,11 @@ func convert_v1_RouteList_To_api_RouteList(in *routeapiv1.RouteList, out *routea return nil } -func convert_v1_RoutePort_To_api_RoutePort(in *routeapiv1.RoutePort, out *routeapi.RoutePort, s conversion.Scope) error { +func convert_v1_RouteList_To_api_RouteList(in *routeapiv1.RouteList, out *routeapi.RouteList, s conversion.Scope) error { + return autoconvert_v1_RouteList_To_api_RouteList(in, out, s) +} + +func autoconvert_v1_RoutePort_To_api_RoutePort(in *routeapiv1.RoutePort, out *routeapi.RoutePort, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1.RoutePort))(in) } @@ -2316,7 +3681,11 @@ func convert_v1_RoutePort_To_api_RoutePort(in *routeapiv1.RoutePort, out *routea return nil } -func convert_v1_RouteSpec_To_api_RouteSpec(in *routeapiv1.RouteSpec, out *routeapi.RouteSpec, s conversion.Scope) error { +func convert_v1_RoutePort_To_api_RoutePort(in *routeapiv1.RoutePort, out *routeapi.RoutePort, s conversion.Scope) error { + return autoconvert_v1_RoutePort_To_api_RoutePort(in, out, s) +} + +func autoconvert_v1_RouteSpec_To_api_RouteSpec(in *routeapiv1.RouteSpec, out *routeapi.RouteSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1.RouteSpec))(in) } @@ -2344,14 +3713,22 @@ func convert_v1_RouteSpec_To_api_RouteSpec(in *routeapiv1.RouteSpec, out *routea return nil } -func convert_v1_RouteStatus_To_api_RouteStatus(in *routeapiv1.RouteStatus, out *routeapi.RouteStatus, s conversion.Scope) error { +func convert_v1_RouteSpec_To_api_RouteSpec(in *routeapiv1.RouteSpec, out *routeapi.RouteSpec, s conversion.Scope) error { + return autoconvert_v1_RouteSpec_To_api_RouteSpec(in, out, s) +} + +func autoconvert_v1_RouteStatus_To_api_RouteStatus(in *routeapiv1.RouteStatus, out *routeapi.RouteStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1.RouteStatus))(in) } return nil } -func convert_v1_TLSConfig_To_api_TLSConfig(in *routeapiv1.TLSConfig, out *routeapi.TLSConfig, s conversion.Scope) error { +func convert_v1_RouteStatus_To_api_RouteStatus(in *routeapiv1.RouteStatus, out *routeapi.RouteStatus, s conversion.Scope) error { + return autoconvert_v1_RouteStatus_To_api_RouteStatus(in, out, s) +} + +func autoconvert_v1_TLSConfig_To_api_TLSConfig(in *routeapiv1.TLSConfig, out *routeapi.TLSConfig, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1.TLSConfig))(in) } @@ -2363,11 +3740,15 @@ func convert_v1_TLSConfig_To_api_TLSConfig(in *routeapiv1.TLSConfig, out *routea return nil } -func convert_api_ClusterNetwork_To_v1_ClusterNetwork(in *sdnapi.ClusterNetwork, out *sdnapiv1.ClusterNetwork, s conversion.Scope) error { +func convert_v1_TLSConfig_To_api_TLSConfig(in *routeapiv1.TLSConfig, out *routeapi.TLSConfig, s conversion.Scope) error { + return autoconvert_v1_TLSConfig_To_api_TLSConfig(in, out, s) +} + +func autoconvert_api_ClusterNetwork_To_v1_ClusterNetwork(in *sdnapi.ClusterNetwork, out *sdnapiv1.ClusterNetwork, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.ClusterNetwork))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2379,14 +3760,18 @@ func convert_api_ClusterNetwork_To_v1_ClusterNetwork(in *sdnapi.ClusterNetwork, return nil } -func convert_api_ClusterNetworkList_To_v1_ClusterNetworkList(in *sdnapi.ClusterNetworkList, out *sdnapiv1.ClusterNetworkList, s conversion.Scope) error { +func convert_api_ClusterNetwork_To_v1_ClusterNetwork(in *sdnapi.ClusterNetwork, out *sdnapiv1.ClusterNetwork, s conversion.Scope) error { + return autoconvert_api_ClusterNetwork_To_v1_ClusterNetwork(in, out, s) +} + +func autoconvert_api_ClusterNetworkList_To_v1_ClusterNetworkList(in *sdnapi.ClusterNetworkList, out *sdnapiv1.ClusterNetworkList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.ClusterNetworkList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2402,11 +3787,15 @@ func convert_api_ClusterNetworkList_To_v1_ClusterNetworkList(in *sdnapi.ClusterN return nil } -func convert_api_HostSubnet_To_v1_HostSubnet(in *sdnapi.HostSubnet, out *sdnapiv1.HostSubnet, s conversion.Scope) error { +func convert_api_ClusterNetworkList_To_v1_ClusterNetworkList(in *sdnapi.ClusterNetworkList, out *sdnapiv1.ClusterNetworkList, s conversion.Scope) error { + return autoconvert_api_ClusterNetworkList_To_v1_ClusterNetworkList(in, out, s) +} + +func autoconvert_api_HostSubnet_To_v1_HostSubnet(in *sdnapi.HostSubnet, out *sdnapiv1.HostSubnet, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.HostSubnet))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2418,14 +3807,18 @@ func convert_api_HostSubnet_To_v1_HostSubnet(in *sdnapi.HostSubnet, out *sdnapiv return nil } -func convert_api_HostSubnetList_To_v1_HostSubnetList(in *sdnapi.HostSubnetList, out *sdnapiv1.HostSubnetList, s conversion.Scope) error { +func convert_api_HostSubnet_To_v1_HostSubnet(in *sdnapi.HostSubnet, out *sdnapiv1.HostSubnet, s conversion.Scope) error { + return autoconvert_api_HostSubnet_To_v1_HostSubnet(in, out, s) +} + +func autoconvert_api_HostSubnetList_To_v1_HostSubnetList(in *sdnapi.HostSubnetList, out *sdnapiv1.HostSubnetList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.HostSubnetList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2441,11 +3834,15 @@ func convert_api_HostSubnetList_To_v1_HostSubnetList(in *sdnapi.HostSubnetList, return nil } -func convert_api_NetNamespace_To_v1_NetNamespace(in *sdnapi.NetNamespace, out *sdnapiv1.NetNamespace, s conversion.Scope) error { +func convert_api_HostSubnetList_To_v1_HostSubnetList(in *sdnapi.HostSubnetList, out *sdnapiv1.HostSubnetList, s conversion.Scope) error { + return autoconvert_api_HostSubnetList_To_v1_HostSubnetList(in, out, s) +} + +func autoconvert_api_NetNamespace_To_v1_NetNamespace(in *sdnapi.NetNamespace, out *sdnapiv1.NetNamespace, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.NetNamespace))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2456,14 +3853,18 @@ func convert_api_NetNamespace_To_v1_NetNamespace(in *sdnapi.NetNamespace, out *s return nil } -func convert_api_NetNamespaceList_To_v1_NetNamespaceList(in *sdnapi.NetNamespaceList, out *sdnapiv1.NetNamespaceList, s conversion.Scope) error { +func convert_api_NetNamespace_To_v1_NetNamespace(in *sdnapi.NetNamespace, out *sdnapiv1.NetNamespace, s conversion.Scope) error { + return autoconvert_api_NetNamespace_To_v1_NetNamespace(in, out, s) +} + +func autoconvert_api_NetNamespaceList_To_v1_NetNamespaceList(in *sdnapi.NetNamespaceList, out *sdnapiv1.NetNamespaceList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.NetNamespaceList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2479,11 +3880,15 @@ func convert_api_NetNamespaceList_To_v1_NetNamespaceList(in *sdnapi.NetNamespace return nil } -func convert_v1_ClusterNetwork_To_api_ClusterNetwork(in *sdnapiv1.ClusterNetwork, out *sdnapi.ClusterNetwork, s conversion.Scope) error { +func convert_api_NetNamespaceList_To_v1_NetNamespaceList(in *sdnapi.NetNamespaceList, out *sdnapiv1.NetNamespaceList, s conversion.Scope) error { + return autoconvert_api_NetNamespaceList_To_v1_NetNamespaceList(in, out, s) +} + +func autoconvert_v1_ClusterNetwork_To_api_ClusterNetwork(in *sdnapiv1.ClusterNetwork, out *sdnapi.ClusterNetwork, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1.ClusterNetwork))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2495,14 +3900,18 @@ func convert_v1_ClusterNetwork_To_api_ClusterNetwork(in *sdnapiv1.ClusterNetwork return nil } -func convert_v1_ClusterNetworkList_To_api_ClusterNetworkList(in *sdnapiv1.ClusterNetworkList, out *sdnapi.ClusterNetworkList, s conversion.Scope) error { +func convert_v1_ClusterNetwork_To_api_ClusterNetwork(in *sdnapiv1.ClusterNetwork, out *sdnapi.ClusterNetwork, s conversion.Scope) error { + return autoconvert_v1_ClusterNetwork_To_api_ClusterNetwork(in, out, s) +} + +func autoconvert_v1_ClusterNetworkList_To_api_ClusterNetworkList(in *sdnapiv1.ClusterNetworkList, out *sdnapi.ClusterNetworkList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1.ClusterNetworkList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2518,11 +3927,15 @@ func convert_v1_ClusterNetworkList_To_api_ClusterNetworkList(in *sdnapiv1.Cluste return nil } -func convert_v1_HostSubnet_To_api_HostSubnet(in *sdnapiv1.HostSubnet, out *sdnapi.HostSubnet, s conversion.Scope) error { +func convert_v1_ClusterNetworkList_To_api_ClusterNetworkList(in *sdnapiv1.ClusterNetworkList, out *sdnapi.ClusterNetworkList, s conversion.Scope) error { + return autoconvert_v1_ClusterNetworkList_To_api_ClusterNetworkList(in, out, s) +} + +func autoconvert_v1_HostSubnet_To_api_HostSubnet(in *sdnapiv1.HostSubnet, out *sdnapi.HostSubnet, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1.HostSubnet))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2534,14 +3947,18 @@ func convert_v1_HostSubnet_To_api_HostSubnet(in *sdnapiv1.HostSubnet, out *sdnap return nil } -func convert_v1_HostSubnetList_To_api_HostSubnetList(in *sdnapiv1.HostSubnetList, out *sdnapi.HostSubnetList, s conversion.Scope) error { +func convert_v1_HostSubnet_To_api_HostSubnet(in *sdnapiv1.HostSubnet, out *sdnapi.HostSubnet, s conversion.Scope) error { + return autoconvert_v1_HostSubnet_To_api_HostSubnet(in, out, s) +} + +func autoconvert_v1_HostSubnetList_To_api_HostSubnetList(in *sdnapiv1.HostSubnetList, out *sdnapi.HostSubnetList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1.HostSubnetList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2557,11 +3974,15 @@ func convert_v1_HostSubnetList_To_api_HostSubnetList(in *sdnapiv1.HostSubnetList return nil } -func convert_v1_NetNamespace_To_api_NetNamespace(in *sdnapiv1.NetNamespace, out *sdnapi.NetNamespace, s conversion.Scope) error { +func convert_v1_HostSubnetList_To_api_HostSubnetList(in *sdnapiv1.HostSubnetList, out *sdnapi.HostSubnetList, s conversion.Scope) error { + return autoconvert_v1_HostSubnetList_To_api_HostSubnetList(in, out, s) +} + +func autoconvert_v1_NetNamespace_To_api_NetNamespace(in *sdnapiv1.NetNamespace, out *sdnapi.NetNamespace, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1.NetNamespace))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2572,14 +3993,18 @@ func convert_v1_NetNamespace_To_api_NetNamespace(in *sdnapiv1.NetNamespace, out return nil } -func convert_v1_NetNamespaceList_To_api_NetNamespaceList(in *sdnapiv1.NetNamespaceList, out *sdnapi.NetNamespaceList, s conversion.Scope) error { +func convert_v1_NetNamespace_To_api_NetNamespace(in *sdnapiv1.NetNamespace, out *sdnapi.NetNamespace, s conversion.Scope) error { + return autoconvert_v1_NetNamespace_To_api_NetNamespace(in, out, s) +} + +func autoconvert_v1_NetNamespaceList_To_api_NetNamespaceList(in *sdnapiv1.NetNamespaceList, out *sdnapi.NetNamespaceList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1.NetNamespaceList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2595,7 +4020,11 @@ func convert_v1_NetNamespaceList_To_api_NetNamespaceList(in *sdnapiv1.NetNamespa return nil } -func convert_api_Parameter_To_v1_Parameter(in *templateapi.Parameter, out *templateapiv1.Parameter, s conversion.Scope) error { +func convert_v1_NetNamespaceList_To_api_NetNamespaceList(in *sdnapiv1.NetNamespaceList, out *sdnapi.NetNamespaceList, s conversion.Scope) error { + return autoconvert_v1_NetNamespaceList_To_api_NetNamespaceList(in, out, s) +} + +func autoconvert_api_Parameter_To_v1_Parameter(in *templateapi.Parameter, out *templateapiv1.Parameter, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*templateapi.Parameter))(in) } @@ -2609,14 +4038,45 @@ func convert_api_Parameter_To_v1_Parameter(in *templateapi.Parameter, out *templ return nil } -func convert_api_TemplateList_To_v1_TemplateList(in *templateapi.TemplateList, out *templateapiv1.TemplateList, s conversion.Scope) error { +func convert_api_Parameter_To_v1_Parameter(in *templateapi.Parameter, out *templateapiv1.Parameter, s conversion.Scope) error { + return autoconvert_api_Parameter_To_v1_Parameter(in, out, s) +} + +func autoconvert_api_Template_To_v1_Template(in *templateapi.Template, out *templateapiv1.Template, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*templateapi.Template))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Parameters != nil { + out.Parameters = make([]templateapiv1.Parameter, len(in.Parameters)) + for i := range in.Parameters { + if err := convert_api_Parameter_To_v1_Parameter(&in.Parameters[i], &out.Parameters[i], s); err != nil { + return err + } + } + } else { + out.Parameters = nil + } + if err := s.Convert(&in.Objects, &out.Objects, 0); err != nil { + return err + } + // in.ObjectLabels has no peer in out + return nil +} + +func autoconvert_api_TemplateList_To_v1_TemplateList(in *templateapi.TemplateList, out *templateapiv1.TemplateList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*templateapi.TemplateList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2632,7 +4092,11 @@ func convert_api_TemplateList_To_v1_TemplateList(in *templateapi.TemplateList, o return nil } -func convert_v1_Parameter_To_api_Parameter(in *templateapiv1.Parameter, out *templateapi.Parameter, s conversion.Scope) error { +func convert_api_TemplateList_To_v1_TemplateList(in *templateapi.TemplateList, out *templateapiv1.TemplateList, s conversion.Scope) error { + return autoconvert_api_TemplateList_To_v1_TemplateList(in, out, s) +} + +func autoconvert_v1_Parameter_To_api_Parameter(in *templateapiv1.Parameter, out *templateapi.Parameter, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*templateapiv1.Parameter))(in) } @@ -2646,14 +4110,52 @@ func convert_v1_Parameter_To_api_Parameter(in *templateapiv1.Parameter, out *tem return nil } -func convert_v1_TemplateList_To_api_TemplateList(in *templateapiv1.TemplateList, out *templateapi.TemplateList, s conversion.Scope) error { +func convert_v1_Parameter_To_api_Parameter(in *templateapiv1.Parameter, out *templateapi.Parameter, s conversion.Scope) error { + return autoconvert_v1_Parameter_To_api_Parameter(in, out, s) +} + +func autoconvert_v1_Template_To_api_Template(in *templateapiv1.Template, out *templateapi.Template, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*templateapiv1.Template))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Objects, &out.Objects, 0); err != nil { + return err + } + if in.Parameters != nil { + out.Parameters = make([]templateapi.Parameter, len(in.Parameters)) + for i := range in.Parameters { + if err := convert_v1_Parameter_To_api_Parameter(&in.Parameters[i], &out.Parameters[i], s); err != nil { + return err + } + } + } else { + out.Parameters = nil + } + if in.Labels != nil { + out.Labels = make(map[string]string) + for key, val := range in.Labels { + out.Labels[key] = val + } + } else { + out.Labels = nil + } + return nil +} + +func autoconvert_v1_TemplateList_To_api_TemplateList(in *templateapiv1.TemplateList, out *templateapi.TemplateList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*templateapiv1.TemplateList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2669,11 +4171,15 @@ func convert_v1_TemplateList_To_api_TemplateList(in *templateapiv1.TemplateList, return nil } -func convert_api_Group_To_v1_Group(in *userapi.Group, out *userapiv1.Group, s conversion.Scope) error { +func convert_v1_TemplateList_To_api_TemplateList(in *templateapiv1.TemplateList, out *templateapi.TemplateList, s conversion.Scope) error { + return autoconvert_v1_TemplateList_To_api_TemplateList(in, out, s) +} + +func autoconvert_api_Group_To_v1_Group(in *userapi.Group, out *userapiv1.Group, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.Group))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2690,14 +4196,18 @@ func convert_api_Group_To_v1_Group(in *userapi.Group, out *userapiv1.Group, s co return nil } -func convert_api_GroupList_To_v1_GroupList(in *userapi.GroupList, out *userapiv1.GroupList, s conversion.Scope) error { +func convert_api_Group_To_v1_Group(in *userapi.Group, out *userapiv1.Group, s conversion.Scope) error { + return autoconvert_api_Group_To_v1_Group(in, out, s) +} + +func autoconvert_api_GroupList_To_v1_GroupList(in *userapi.GroupList, out *userapiv1.GroupList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.GroupList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2713,11 +4223,15 @@ func convert_api_GroupList_To_v1_GroupList(in *userapi.GroupList, out *userapiv1 return nil } -func convert_api_Identity_To_v1_Identity(in *userapi.Identity, out *userapiv1.Identity, s conversion.Scope) error { +func convert_api_GroupList_To_v1_GroupList(in *userapi.GroupList, out *userapiv1.GroupList, s conversion.Scope) error { + return autoconvert_api_GroupList_To_v1_GroupList(in, out, s) +} + +func autoconvert_api_Identity_To_v1_Identity(in *userapi.Identity, out *userapiv1.Identity, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.Identity))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2739,14 +4253,18 @@ func convert_api_Identity_To_v1_Identity(in *userapi.Identity, out *userapiv1.Id return nil } -func convert_api_IdentityList_To_v1_IdentityList(in *userapi.IdentityList, out *userapiv1.IdentityList, s conversion.Scope) error { +func convert_api_Identity_To_v1_Identity(in *userapi.Identity, out *userapiv1.Identity, s conversion.Scope) error { + return autoconvert_api_Identity_To_v1_Identity(in, out, s) +} + +func autoconvert_api_IdentityList_To_v1_IdentityList(in *userapi.IdentityList, out *userapiv1.IdentityList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.IdentityList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2762,11 +4280,15 @@ func convert_api_IdentityList_To_v1_IdentityList(in *userapi.IdentityList, out * return nil } -func convert_api_User_To_v1_User(in *userapi.User, out *userapiv1.User, s conversion.Scope) error { +func convert_api_IdentityList_To_v1_IdentityList(in *userapi.IdentityList, out *userapiv1.IdentityList, s conversion.Scope) error { + return autoconvert_api_IdentityList_To_v1_IdentityList(in, out, s) +} + +func autoconvert_api_User_To_v1_User(in *userapi.User, out *userapiv1.User, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.User))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2792,11 +4314,15 @@ func convert_api_User_To_v1_User(in *userapi.User, out *userapiv1.User, s conver return nil } -func convert_api_UserIdentityMapping_To_v1_UserIdentityMapping(in *userapi.UserIdentityMapping, out *userapiv1.UserIdentityMapping, s conversion.Scope) error { +func convert_api_User_To_v1_User(in *userapi.User, out *userapiv1.User, s conversion.Scope) error { + return autoconvert_api_User_To_v1_User(in, out, s) +} + +func autoconvert_api_UserIdentityMapping_To_v1_UserIdentityMapping(in *userapi.UserIdentityMapping, out *userapiv1.UserIdentityMapping, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.UserIdentityMapping))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2811,14 +4337,18 @@ func convert_api_UserIdentityMapping_To_v1_UserIdentityMapping(in *userapi.UserI return nil } -func convert_api_UserList_To_v1_UserList(in *userapi.UserList, out *userapiv1.UserList, s conversion.Scope) error { +func convert_api_UserIdentityMapping_To_v1_UserIdentityMapping(in *userapi.UserIdentityMapping, out *userapiv1.UserIdentityMapping, s conversion.Scope) error { + return autoconvert_api_UserIdentityMapping_To_v1_UserIdentityMapping(in, out, s) +} + +func autoconvert_api_UserList_To_v1_UserList(in *userapi.UserList, out *userapiv1.UserList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.UserList))(in) } - if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2834,11 +4364,15 @@ func convert_api_UserList_To_v1_UserList(in *userapi.UserList, out *userapiv1.Us return nil } -func convert_v1_Group_To_api_Group(in *userapiv1.Group, out *userapi.Group, s conversion.Scope) error { +func convert_api_UserList_To_v1_UserList(in *userapi.UserList, out *userapiv1.UserList, s conversion.Scope) error { + return autoconvert_api_UserList_To_v1_UserList(in, out, s) +} + +func autoconvert_v1_Group_To_api_Group(in *userapiv1.Group, out *userapi.Group, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1.Group))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2855,14 +4389,18 @@ func convert_v1_Group_To_api_Group(in *userapiv1.Group, out *userapi.Group, s co return nil } -func convert_v1_GroupList_To_api_GroupList(in *userapiv1.GroupList, out *userapi.GroupList, s conversion.Scope) error { +func convert_v1_Group_To_api_Group(in *userapiv1.Group, out *userapi.Group, s conversion.Scope) error { + return autoconvert_v1_Group_To_api_Group(in, out, s) +} + +func autoconvert_v1_GroupList_To_api_GroupList(in *userapiv1.GroupList, out *userapi.GroupList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1.GroupList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2878,11 +4416,15 @@ func convert_v1_GroupList_To_api_GroupList(in *userapiv1.GroupList, out *userapi return nil } -func convert_v1_Identity_To_api_Identity(in *userapiv1.Identity, out *userapi.Identity, s conversion.Scope) error { +func convert_v1_GroupList_To_api_GroupList(in *userapiv1.GroupList, out *userapi.GroupList, s conversion.Scope) error { + return autoconvert_v1_GroupList_To_api_GroupList(in, out, s) +} + +func autoconvert_v1_Identity_To_api_Identity(in *userapiv1.Identity, out *userapi.Identity, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1.Identity))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2904,14 +4446,18 @@ func convert_v1_Identity_To_api_Identity(in *userapiv1.Identity, out *userapi.Id return nil } -func convert_v1_IdentityList_To_api_IdentityList(in *userapiv1.IdentityList, out *userapi.IdentityList, s conversion.Scope) error { +func convert_v1_Identity_To_api_Identity(in *userapiv1.Identity, out *userapi.Identity, s conversion.Scope) error { + return autoconvert_v1_Identity_To_api_Identity(in, out, s) +} + +func autoconvert_v1_IdentityList_To_api_IdentityList(in *userapiv1.IdentityList, out *userapi.IdentityList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1.IdentityList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2927,11 +4473,15 @@ func convert_v1_IdentityList_To_api_IdentityList(in *userapiv1.IdentityList, out return nil } -func convert_v1_User_To_api_User(in *userapiv1.User, out *userapi.User, s conversion.Scope) error { +func convert_v1_IdentityList_To_api_IdentityList(in *userapiv1.IdentityList, out *userapi.IdentityList, s conversion.Scope) error { + return autoconvert_v1_IdentityList_To_api_IdentityList(in, out, s) +} + +func autoconvert_v1_User_To_api_User(in *userapiv1.User, out *userapi.User, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1.User))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2957,11 +4507,15 @@ func convert_v1_User_To_api_User(in *userapiv1.User, out *userapi.User, s conver return nil } -func convert_v1_UserIdentityMapping_To_api_UserIdentityMapping(in *userapiv1.UserIdentityMapping, out *userapi.UserIdentityMapping, s conversion.Scope) error { +func convert_v1_User_To_api_User(in *userapiv1.User, out *userapi.User, s conversion.Scope) error { + return autoconvert_v1_User_To_api_User(in, out, s) +} + +func autoconvert_v1_UserIdentityMapping_To_api_UserIdentityMapping(in *userapiv1.UserIdentityMapping, out *userapi.UserIdentityMapping, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1.UserIdentityMapping))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2976,14 +4530,18 @@ func convert_v1_UserIdentityMapping_To_api_UserIdentityMapping(in *userapiv1.Use return nil } -func convert_v1_UserList_To_api_UserList(in *userapiv1.UserList, out *userapi.UserList, s conversion.Scope) error { +func convert_v1_UserIdentityMapping_To_api_UserIdentityMapping(in *userapiv1.UserIdentityMapping, out *userapi.UserIdentityMapping, s conversion.Scope) error { + return autoconvert_v1_UserIdentityMapping_To_api_UserIdentityMapping(in, out, s) +} + +func autoconvert_v1_UserList_To_api_UserList(in *userapiv1.UserList, out *userapi.UserList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1.UserList))(in) } - if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2999,7 +4557,11 @@ func convert_v1_UserList_To_api_UserList(in *userapiv1.UserList, out *userapi.Us return nil } -func convert_api_EnvVar_To_v1_EnvVar(in *pkgapi.EnvVar, out *pkgapiv1.EnvVar, s conversion.Scope) error { +func convert_v1_UserList_To_api_UserList(in *userapiv1.UserList, out *userapi.UserList, s conversion.Scope) error { + return autoconvert_v1_UserList_To_api_UserList(in, out, s) +} + +func autoconvert_api_EnvVar_To_v1_EnvVar(in *pkgapi.EnvVar, out *pkgapiv1.EnvVar, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.EnvVar))(in) } @@ -3016,7 +4578,11 @@ func convert_api_EnvVar_To_v1_EnvVar(in *pkgapi.EnvVar, out *pkgapiv1.EnvVar, s return nil } -func convert_api_EnvVarSource_To_v1_EnvVarSource(in *pkgapi.EnvVarSource, out *pkgapiv1.EnvVarSource, s conversion.Scope) error { +func convert_api_EnvVar_To_v1_EnvVar(in *pkgapi.EnvVar, out *pkgapiv1.EnvVar, s conversion.Scope) error { + return autoconvert_api_EnvVar_To_v1_EnvVar(in, out, s) +} + +func autoconvert_api_EnvVarSource_To_v1_EnvVarSource(in *pkgapi.EnvVarSource, out *pkgapiv1.EnvVarSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.EnvVarSource))(in) } @@ -3031,16 +4597,11 @@ func convert_api_EnvVarSource_To_v1_EnvVarSource(in *pkgapi.EnvVarSource, out *p return nil } -func convert_api_ListMeta_To_v1_ListMeta(in *pkgapi.ListMeta, out *pkgapiv1.ListMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*pkgapi.ListMeta))(in) - } - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil +func convert_api_EnvVarSource_To_v1_EnvVarSource(in *pkgapi.EnvVarSource, out *pkgapiv1.EnvVarSource, s conversion.Scope) error { + return autoconvert_api_EnvVarSource_To_v1_EnvVarSource(in, out, s) } -func convert_api_LocalObjectReference_To_v1_LocalObjectReference(in *pkgapi.LocalObjectReference, out *pkgapiv1.LocalObjectReference, s conversion.Scope) error { +func autoconvert_api_LocalObjectReference_To_v1_LocalObjectReference(in *pkgapi.LocalObjectReference, out *pkgapiv1.LocalObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.LocalObjectReference))(in) } @@ -3048,7 +4609,11 @@ func convert_api_LocalObjectReference_To_v1_LocalObjectReference(in *pkgapi.Loca return nil } -func convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *pkgapi.ObjectFieldSelector, out *pkgapiv1.ObjectFieldSelector, s conversion.Scope) error { +func convert_api_LocalObjectReference_To_v1_LocalObjectReference(in *pkgapi.LocalObjectReference, out *pkgapiv1.LocalObjectReference, s conversion.Scope) error { + return autoconvert_api_LocalObjectReference_To_v1_LocalObjectReference(in, out, s) +} + +func autoconvert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *pkgapi.ObjectFieldSelector, out *pkgapiv1.ObjectFieldSelector, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.ObjectFieldSelector))(in) } @@ -3057,7 +4622,11 @@ func convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *pkgapi.Object return nil } -func convert_api_ObjectMeta_To_v1_ObjectMeta(in *pkgapi.ObjectMeta, out *pkgapiv1.ObjectMeta, s conversion.Scope) error { +func convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in *pkgapi.ObjectFieldSelector, out *pkgapiv1.ObjectFieldSelector, s conversion.Scope) error { + return autoconvert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(in, out, s) +} + +func autoconvert_api_ObjectMeta_To_v1_ObjectMeta(in *pkgapi.ObjectMeta, out *pkgapiv1.ObjectMeta, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.ObjectMeta))(in) } @@ -3103,7 +4672,11 @@ func convert_api_ObjectMeta_To_v1_ObjectMeta(in *pkgapi.ObjectMeta, out *pkgapiv return nil } -func convert_api_ObjectReference_To_v1_ObjectReference(in *pkgapi.ObjectReference, out *pkgapiv1.ObjectReference, s conversion.Scope) error { +func convert_api_ObjectMeta_To_v1_ObjectMeta(in *pkgapi.ObjectMeta, out *pkgapiv1.ObjectMeta, s conversion.Scope) error { + return autoconvert_api_ObjectMeta_To_v1_ObjectMeta(in, out, s) +} + +func autoconvert_api_ObjectReference_To_v1_ObjectReference(in *pkgapi.ObjectReference, out *pkgapiv1.ObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.ObjectReference))(in) } @@ -3117,7 +4690,11 @@ func convert_api_ObjectReference_To_v1_ObjectReference(in *pkgapi.ObjectReferenc return nil } -func convert_api_ResourceRequirements_To_v1_ResourceRequirements(in *pkgapi.ResourceRequirements, out *pkgapiv1.ResourceRequirements, s conversion.Scope) error { +func convert_api_ObjectReference_To_v1_ObjectReference(in *pkgapi.ObjectReference, out *pkgapiv1.ObjectReference, s conversion.Scope) error { + return autoconvert_api_ObjectReference_To_v1_ObjectReference(in, out, s) +} + +func autoconvert_api_ResourceRequirements_To_v1_ResourceRequirements(in *pkgapi.ResourceRequirements, out *pkgapiv1.ResourceRequirements, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.ResourceRequirements))(in) } @@ -3148,16 +4725,11 @@ func convert_api_ResourceRequirements_To_v1_ResourceRequirements(in *pkgapi.Reso return nil } -func convert_api_TypeMeta_To_v1_TypeMeta(in *pkgapi.TypeMeta, out *pkgapiv1.TypeMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*pkgapi.TypeMeta))(in) - } - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil +func convert_api_ResourceRequirements_To_v1_ResourceRequirements(in *pkgapi.ResourceRequirements, out *pkgapiv1.ResourceRequirements, s conversion.Scope) error { + return autoconvert_api_ResourceRequirements_To_v1_ResourceRequirements(in, out, s) } -func convert_v1_EnvVar_To_api_EnvVar(in *pkgapiv1.EnvVar, out *pkgapi.EnvVar, s conversion.Scope) error { +func autoconvert_v1_EnvVar_To_api_EnvVar(in *pkgapiv1.EnvVar, out *pkgapi.EnvVar, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1.EnvVar))(in) } @@ -3174,7 +4746,11 @@ func convert_v1_EnvVar_To_api_EnvVar(in *pkgapiv1.EnvVar, out *pkgapi.EnvVar, s return nil } -func convert_v1_EnvVarSource_To_api_EnvVarSource(in *pkgapiv1.EnvVarSource, out *pkgapi.EnvVarSource, s conversion.Scope) error { +func convert_v1_EnvVar_To_api_EnvVar(in *pkgapiv1.EnvVar, out *pkgapi.EnvVar, s conversion.Scope) error { + return autoconvert_v1_EnvVar_To_api_EnvVar(in, out, s) +} + +func autoconvert_v1_EnvVarSource_To_api_EnvVarSource(in *pkgapiv1.EnvVarSource, out *pkgapi.EnvVarSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1.EnvVarSource))(in) } @@ -3189,16 +4765,11 @@ func convert_v1_EnvVarSource_To_api_EnvVarSource(in *pkgapiv1.EnvVarSource, out return nil } -func convert_v1_ListMeta_To_api_ListMeta(in *pkgapiv1.ListMeta, out *pkgapi.ListMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*pkgapiv1.ListMeta))(in) - } - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil +func convert_v1_EnvVarSource_To_api_EnvVarSource(in *pkgapiv1.EnvVarSource, out *pkgapi.EnvVarSource, s conversion.Scope) error { + return autoconvert_v1_EnvVarSource_To_api_EnvVarSource(in, out, s) } -func convert_v1_LocalObjectReference_To_api_LocalObjectReference(in *pkgapiv1.LocalObjectReference, out *pkgapi.LocalObjectReference, s conversion.Scope) error { +func autoconvert_v1_LocalObjectReference_To_api_LocalObjectReference(in *pkgapiv1.LocalObjectReference, out *pkgapi.LocalObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1.LocalObjectReference))(in) } @@ -3206,7 +4777,11 @@ func convert_v1_LocalObjectReference_To_api_LocalObjectReference(in *pkgapiv1.Lo return nil } -func convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *pkgapiv1.ObjectFieldSelector, out *pkgapi.ObjectFieldSelector, s conversion.Scope) error { +func convert_v1_LocalObjectReference_To_api_LocalObjectReference(in *pkgapiv1.LocalObjectReference, out *pkgapi.LocalObjectReference, s conversion.Scope) error { + return autoconvert_v1_LocalObjectReference_To_api_LocalObjectReference(in, out, s) +} + +func autoconvert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *pkgapiv1.ObjectFieldSelector, out *pkgapi.ObjectFieldSelector, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1.ObjectFieldSelector))(in) } @@ -3215,7 +4790,11 @@ func convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *pkgapiv1.Obje return nil } -func convert_v1_ObjectMeta_To_api_ObjectMeta(in *pkgapiv1.ObjectMeta, out *pkgapi.ObjectMeta, s conversion.Scope) error { +func convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in *pkgapiv1.ObjectFieldSelector, out *pkgapi.ObjectFieldSelector, s conversion.Scope) error { + return autoconvert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(in, out, s) +} + +func autoconvert_v1_ObjectMeta_To_api_ObjectMeta(in *pkgapiv1.ObjectMeta, out *pkgapi.ObjectMeta, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1.ObjectMeta))(in) } @@ -3261,7 +4840,11 @@ func convert_v1_ObjectMeta_To_api_ObjectMeta(in *pkgapiv1.ObjectMeta, out *pkgap return nil } -func convert_v1_ObjectReference_To_api_ObjectReference(in *pkgapiv1.ObjectReference, out *pkgapi.ObjectReference, s conversion.Scope) error { +func convert_v1_ObjectMeta_To_api_ObjectMeta(in *pkgapiv1.ObjectMeta, out *pkgapi.ObjectMeta, s conversion.Scope) error { + return autoconvert_v1_ObjectMeta_To_api_ObjectMeta(in, out, s) +} + +func autoconvert_v1_ObjectReference_To_api_ObjectReference(in *pkgapiv1.ObjectReference, out *pkgapi.ObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1.ObjectReference))(in) } @@ -3275,7 +4858,11 @@ func convert_v1_ObjectReference_To_api_ObjectReference(in *pkgapiv1.ObjectRefere return nil } -func convert_v1_ResourceRequirements_To_api_ResourceRequirements(in *pkgapiv1.ResourceRequirements, out *pkgapi.ResourceRequirements, s conversion.Scope) error { +func convert_v1_ObjectReference_To_api_ObjectReference(in *pkgapiv1.ObjectReference, out *pkgapi.ObjectReference, s conversion.Scope) error { + return autoconvert_v1_ObjectReference_To_api_ObjectReference(in, out, s) +} + +func autoconvert_v1_ResourceRequirements_To_api_ResourceRequirements(in *pkgapiv1.ResourceRequirements, out *pkgapi.ResourceRequirements, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1.ResourceRequirements))(in) } @@ -3306,183 +4893,220 @@ func convert_v1_ResourceRequirements_To_api_ResourceRequirements(in *pkgapiv1.Re return nil } -func convert_v1_TypeMeta_To_api_TypeMeta(in *pkgapiv1.TypeMeta, out *pkgapi.TypeMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*pkgapiv1.TypeMeta))(in) - } - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil +func convert_v1_ResourceRequirements_To_api_ResourceRequirements(in *pkgapiv1.ResourceRequirements, out *pkgapi.ResourceRequirements, s conversion.Scope) error { + return autoconvert_v1_ResourceRequirements_To_api_ResourceRequirements(in, out, s) } func init() { err := pkgapi.Scheme.AddGeneratedConversionFuncs( - convert_api_BuildConfigList_To_v1_BuildConfigList, - convert_api_BuildConfigSpec_To_v1_BuildConfigSpec, - convert_api_BuildConfigStatus_To_v1_BuildConfigStatus, - convert_api_BuildConfig_To_v1_BuildConfig, - convert_api_BuildList_To_v1_BuildList, - convert_api_BuildLogOptions_To_v1_BuildLogOptions, - convert_api_BuildLog_To_v1_BuildLog, - convert_api_BuildRequest_To_v1_BuildRequest, - convert_api_BuildSource_To_v1_BuildSource, - convert_api_BuildSpec_To_v1_BuildSpec, - convert_api_BuildStatus_To_v1_BuildStatus, - convert_api_BuildStrategy_To_v1_BuildStrategy, - convert_api_Build_To_v1_Build, - convert_api_ClusterNetworkList_To_v1_ClusterNetworkList, - convert_api_ClusterNetwork_To_v1_ClusterNetwork, - convert_api_ClusterPolicyBindingList_To_v1_ClusterPolicyBindingList, - convert_api_ClusterPolicyList_To_v1_ClusterPolicyList, - convert_api_ClusterRoleBindingList_To_v1_ClusterRoleBindingList, - convert_api_ClusterRoleList_To_v1_ClusterRoleList, - convert_api_ClusterRole_To_v1_ClusterRole, - convert_api_DeploymentConfigList_To_v1_DeploymentConfigList, - convert_api_DeploymentConfigRollbackSpec_To_v1_DeploymentConfigRollbackSpec, - convert_api_DeploymentConfigRollback_To_v1_DeploymentConfigRollback, - convert_api_EnvVarSource_To_v1_EnvVarSource, - convert_api_EnvVar_To_v1_EnvVar, - convert_api_GitBuildSource_To_v1_GitBuildSource, - convert_api_GitSourceRevision_To_v1_GitSourceRevision, - convert_api_GroupList_To_v1_GroupList, - convert_api_Group_To_v1_Group, - convert_api_HostSubnetList_To_v1_HostSubnetList, - convert_api_HostSubnet_To_v1_HostSubnet, - convert_api_IdentityList_To_v1_IdentityList, - convert_api_Identity_To_v1_Identity, - convert_api_ImageChangeTrigger_To_v1_ImageChangeTrigger, - convert_api_ImageList_To_v1_ImageList, - convert_api_ImageStreamImage_To_v1_ImageStreamImage, - convert_api_ImageStreamList_To_v1_ImageStreamList, - convert_api_ImageStreamTag_To_v1_ImageStreamTag, - convert_api_ImageStream_To_v1_ImageStream, - convert_api_IsPersonalSubjectAccessReview_To_v1_IsPersonalSubjectAccessReview, - convert_api_ListMeta_To_v1_ListMeta, - convert_api_LocalObjectReference_To_v1_LocalObjectReference, - convert_api_NetNamespaceList_To_v1_NetNamespaceList, - convert_api_NetNamespace_To_v1_NetNamespace, - convert_api_OAuthAccessTokenList_To_v1_OAuthAccessTokenList, - convert_api_OAuthAccessToken_To_v1_OAuthAccessToken, - convert_api_OAuthAuthorizeTokenList_To_v1_OAuthAuthorizeTokenList, - convert_api_OAuthAuthorizeToken_To_v1_OAuthAuthorizeToken, - convert_api_OAuthClientAuthorizationList_To_v1_OAuthClientAuthorizationList, - convert_api_OAuthClientAuthorization_To_v1_OAuthClientAuthorization, - convert_api_OAuthClientList_To_v1_OAuthClientList, - convert_api_OAuthClient_To_v1_OAuthClient, - convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector, - convert_api_ObjectMeta_To_v1_ObjectMeta, - convert_api_ObjectReference_To_v1_ObjectReference, - convert_api_Parameter_To_v1_Parameter, - convert_api_PolicyBindingList_To_v1_PolicyBindingList, - convert_api_PolicyList_To_v1_PolicyList, - convert_api_ProjectList_To_v1_ProjectList, - convert_api_ProjectRequest_To_v1_ProjectRequest, - convert_api_ProjectSpec_To_v1_ProjectSpec, - convert_api_ProjectStatus_To_v1_ProjectStatus, - convert_api_Project_To_v1_Project, - convert_api_ResourceRequirements_To_v1_ResourceRequirements, - convert_api_RoleBindingList_To_v1_RoleBindingList, - convert_api_RoleList_To_v1_RoleList, - convert_api_Role_To_v1_Role, - convert_api_RouteList_To_v1_RouteList, - convert_api_RoutePort_To_v1_RoutePort, - convert_api_RouteSpec_To_v1_RouteSpec, - convert_api_RouteStatus_To_v1_RouteStatus, - convert_api_Route_To_v1_Route, - convert_api_SecretSpec_To_v1_SecretSpec, - convert_api_SourceControlUser_To_v1_SourceControlUser, - convert_api_SourceRevision_To_v1_SourceRevision, - convert_api_SubjectAccessReviewResponse_To_v1_SubjectAccessReviewResponse, - convert_api_TLSConfig_To_v1_TLSConfig, - convert_api_TemplateList_To_v1_TemplateList, - convert_api_TypeMeta_To_v1_TypeMeta, - convert_api_UserIdentityMapping_To_v1_UserIdentityMapping, - convert_api_UserList_To_v1_UserList, - convert_api_User_To_v1_User, - convert_api_WebHookTrigger_To_v1_WebHookTrigger, - convert_v1_BuildConfigList_To_api_BuildConfigList, - convert_v1_BuildConfigSpec_To_api_BuildConfigSpec, - convert_v1_BuildConfigStatus_To_api_BuildConfigStatus, - convert_v1_BuildConfig_To_api_BuildConfig, - convert_v1_BuildList_To_api_BuildList, - convert_v1_BuildLogOptions_To_api_BuildLogOptions, - convert_v1_BuildLog_To_api_BuildLog, - convert_v1_BuildRequest_To_api_BuildRequest, - convert_v1_BuildSource_To_api_BuildSource, - convert_v1_BuildSpec_To_api_BuildSpec, - convert_v1_BuildStatus_To_api_BuildStatus, - convert_v1_BuildStrategy_To_api_BuildStrategy, - convert_v1_Build_To_api_Build, - convert_v1_ClusterNetworkList_To_api_ClusterNetworkList, - convert_v1_ClusterNetwork_To_api_ClusterNetwork, - convert_v1_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList, - convert_v1_ClusterPolicyList_To_api_ClusterPolicyList, - convert_v1_ClusterRoleBindingList_To_api_ClusterRoleBindingList, - convert_v1_ClusterRoleList_To_api_ClusterRoleList, - convert_v1_ClusterRole_To_api_ClusterRole, - convert_v1_DeploymentConfigList_To_api_DeploymentConfigList, - convert_v1_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec, - convert_v1_DeploymentConfigRollback_To_api_DeploymentConfigRollback, - convert_v1_EnvVarSource_To_api_EnvVarSource, - convert_v1_EnvVar_To_api_EnvVar, - convert_v1_GitBuildSource_To_api_GitBuildSource, - convert_v1_GitSourceRevision_To_api_GitSourceRevision, - convert_v1_GroupList_To_api_GroupList, - convert_v1_Group_To_api_Group, - convert_v1_HostSubnetList_To_api_HostSubnetList, - convert_v1_HostSubnet_To_api_HostSubnet, - convert_v1_IdentityList_To_api_IdentityList, - convert_v1_Identity_To_api_Identity, - convert_v1_ImageChangeTrigger_To_api_ImageChangeTrigger, - convert_v1_ImageList_To_api_ImageList, - convert_v1_ImageStreamImage_To_api_ImageStreamImage, - convert_v1_ImageStreamList_To_api_ImageStreamList, - convert_v1_ImageStreamTag_To_api_ImageStreamTag, - convert_v1_ImageStream_To_api_ImageStream, - convert_v1_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview, - convert_v1_ListMeta_To_api_ListMeta, - convert_v1_LocalObjectReference_To_api_LocalObjectReference, - convert_v1_NetNamespaceList_To_api_NetNamespaceList, - convert_v1_NetNamespace_To_api_NetNamespace, - convert_v1_OAuthAccessTokenList_To_api_OAuthAccessTokenList, - convert_v1_OAuthAccessToken_To_api_OAuthAccessToken, - convert_v1_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList, - convert_v1_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken, - convert_v1_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList, - convert_v1_OAuthClientAuthorization_To_api_OAuthClientAuthorization, - convert_v1_OAuthClientList_To_api_OAuthClientList, - convert_v1_OAuthClient_To_api_OAuthClient, - convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector, - convert_v1_ObjectMeta_To_api_ObjectMeta, - convert_v1_ObjectReference_To_api_ObjectReference, - convert_v1_Parameter_To_api_Parameter, - convert_v1_PolicyBindingList_To_api_PolicyBindingList, - convert_v1_PolicyList_To_api_PolicyList, - convert_v1_ProjectList_To_api_ProjectList, - convert_v1_ProjectRequest_To_api_ProjectRequest, - convert_v1_ProjectSpec_To_api_ProjectSpec, - convert_v1_ProjectStatus_To_api_ProjectStatus, - convert_v1_Project_To_api_Project, - convert_v1_ResourceRequirements_To_api_ResourceRequirements, - convert_v1_RoleBindingList_To_api_RoleBindingList, - convert_v1_RoleList_To_api_RoleList, - convert_v1_Role_To_api_Role, - convert_v1_RouteList_To_api_RouteList, - convert_v1_RoutePort_To_api_RoutePort, - convert_v1_RouteSpec_To_api_RouteSpec, - convert_v1_RouteStatus_To_api_RouteStatus, - convert_v1_Route_To_api_Route, - convert_v1_SecretSpec_To_api_SecretSpec, - convert_v1_SourceControlUser_To_api_SourceControlUser, - convert_v1_SourceRevision_To_api_SourceRevision, - convert_v1_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse, - convert_v1_TLSConfig_To_api_TLSConfig, - convert_v1_TemplateList_To_api_TemplateList, - convert_v1_TypeMeta_To_api_TypeMeta, - convert_v1_UserIdentityMapping_To_api_UserIdentityMapping, - convert_v1_UserList_To_api_UserList, - convert_v1_User_To_api_User, - convert_v1_WebHookTrigger_To_api_WebHookTrigger, + autoconvert_api_BuildConfigList_To_v1_BuildConfigList, + autoconvert_api_BuildConfigSpec_To_v1_BuildConfigSpec, + autoconvert_api_BuildConfigStatus_To_v1_BuildConfigStatus, + autoconvert_api_BuildConfig_To_v1_BuildConfig, + autoconvert_api_BuildList_To_v1_BuildList, + autoconvert_api_BuildLogOptions_To_v1_BuildLogOptions, + autoconvert_api_BuildLog_To_v1_BuildLog, + autoconvert_api_BuildOutput_To_v1_BuildOutput, + autoconvert_api_BuildRequest_To_v1_BuildRequest, + autoconvert_api_BuildSource_To_v1_BuildSource, + autoconvert_api_BuildSpec_To_v1_BuildSpec, + autoconvert_api_BuildStatus_To_v1_BuildStatus, + autoconvert_api_BuildStrategy_To_v1_BuildStrategy, + autoconvert_api_BuildTriggerPolicy_To_v1_BuildTriggerPolicy, + autoconvert_api_Build_To_v1_Build, + autoconvert_api_ClusterNetworkList_To_v1_ClusterNetworkList, + autoconvert_api_ClusterNetwork_To_v1_ClusterNetwork, + autoconvert_api_ClusterPolicyBindingList_To_v1_ClusterPolicyBindingList, + autoconvert_api_ClusterPolicyBinding_To_v1_ClusterPolicyBinding, + autoconvert_api_ClusterPolicyList_To_v1_ClusterPolicyList, + autoconvert_api_ClusterPolicy_To_v1_ClusterPolicy, + autoconvert_api_ClusterRoleBindingList_To_v1_ClusterRoleBindingList, + autoconvert_api_ClusterRoleBinding_To_v1_ClusterRoleBinding, + autoconvert_api_ClusterRoleList_To_v1_ClusterRoleList, + autoconvert_api_ClusterRole_To_v1_ClusterRole, + autoconvert_api_CustomBuildStrategy_To_v1_CustomBuildStrategy, + autoconvert_api_DeploymentConfigList_To_v1_DeploymentConfigList, + autoconvert_api_DeploymentConfigRollbackSpec_To_v1_DeploymentConfigRollbackSpec, + autoconvert_api_DeploymentConfigRollback_To_v1_DeploymentConfigRollback, + autoconvert_api_DeploymentConfig_To_v1_DeploymentConfig, + autoconvert_api_DockerBuildStrategy_To_v1_DockerBuildStrategy, + autoconvert_api_EnvVarSource_To_v1_EnvVarSource, + autoconvert_api_EnvVar_To_v1_EnvVar, + autoconvert_api_GitBuildSource_To_v1_GitBuildSource, + autoconvert_api_GitSourceRevision_To_v1_GitSourceRevision, + autoconvert_api_GroupList_To_v1_GroupList, + autoconvert_api_Group_To_v1_Group, + autoconvert_api_HostSubnetList_To_v1_HostSubnetList, + autoconvert_api_HostSubnet_To_v1_HostSubnet, + autoconvert_api_IdentityList_To_v1_IdentityList, + autoconvert_api_Identity_To_v1_Identity, + autoconvert_api_ImageChangeTrigger_To_v1_ImageChangeTrigger, + autoconvert_api_ImageList_To_v1_ImageList, + autoconvert_api_ImageStreamImage_To_v1_ImageStreamImage, + autoconvert_api_ImageStreamList_To_v1_ImageStreamList, + autoconvert_api_ImageStreamMapping_To_v1_ImageStreamMapping, + autoconvert_api_ImageStreamSpec_To_v1_ImageStreamSpec, + autoconvert_api_ImageStreamStatus_To_v1_ImageStreamStatus, + autoconvert_api_ImageStreamTag_To_v1_ImageStreamTag, + autoconvert_api_ImageStream_To_v1_ImageStream, + autoconvert_api_Image_To_v1_Image, + autoconvert_api_IsPersonalSubjectAccessReview_To_v1_IsPersonalSubjectAccessReview, + autoconvert_api_LocalObjectReference_To_v1_LocalObjectReference, + autoconvert_api_LocalResourceAccessReview_To_v1_LocalResourceAccessReview, + autoconvert_api_LocalSubjectAccessReview_To_v1_LocalSubjectAccessReview, + autoconvert_api_NetNamespaceList_To_v1_NetNamespaceList, + autoconvert_api_NetNamespace_To_v1_NetNamespace, + autoconvert_api_OAuthAccessTokenList_To_v1_OAuthAccessTokenList, + autoconvert_api_OAuthAccessToken_To_v1_OAuthAccessToken, + autoconvert_api_OAuthAuthorizeTokenList_To_v1_OAuthAuthorizeTokenList, + autoconvert_api_OAuthAuthorizeToken_To_v1_OAuthAuthorizeToken, + autoconvert_api_OAuthClientAuthorizationList_To_v1_OAuthClientAuthorizationList, + autoconvert_api_OAuthClientAuthorization_To_v1_OAuthClientAuthorization, + autoconvert_api_OAuthClientList_To_v1_OAuthClientList, + autoconvert_api_OAuthClient_To_v1_OAuthClient, + autoconvert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector, + autoconvert_api_ObjectMeta_To_v1_ObjectMeta, + autoconvert_api_ObjectReference_To_v1_ObjectReference, + autoconvert_api_Parameter_To_v1_Parameter, + autoconvert_api_PolicyBindingList_To_v1_PolicyBindingList, + autoconvert_api_PolicyBinding_To_v1_PolicyBinding, + autoconvert_api_PolicyList_To_v1_PolicyList, + autoconvert_api_PolicyRule_To_v1_PolicyRule, + autoconvert_api_Policy_To_v1_Policy, + autoconvert_api_ProjectList_To_v1_ProjectList, + autoconvert_api_ProjectRequest_To_v1_ProjectRequest, + autoconvert_api_ProjectSpec_To_v1_ProjectSpec, + autoconvert_api_ProjectStatus_To_v1_ProjectStatus, + autoconvert_api_Project_To_v1_Project, + autoconvert_api_ResourceAccessReviewResponse_To_v1_ResourceAccessReviewResponse, + autoconvert_api_ResourceAccessReview_To_v1_ResourceAccessReview, + autoconvert_api_ResourceRequirements_To_v1_ResourceRequirements, + autoconvert_api_RoleBindingList_To_v1_RoleBindingList, + autoconvert_api_RoleBinding_To_v1_RoleBinding, + autoconvert_api_RoleList_To_v1_RoleList, + autoconvert_api_Role_To_v1_Role, + autoconvert_api_RouteList_To_v1_RouteList, + autoconvert_api_RoutePort_To_v1_RoutePort, + autoconvert_api_RouteSpec_To_v1_RouteSpec, + autoconvert_api_RouteStatus_To_v1_RouteStatus, + autoconvert_api_Route_To_v1_Route, + autoconvert_api_SecretSpec_To_v1_SecretSpec, + autoconvert_api_SourceBuildStrategy_To_v1_SourceBuildStrategy, + autoconvert_api_SourceControlUser_To_v1_SourceControlUser, + autoconvert_api_SourceRevision_To_v1_SourceRevision, + autoconvert_api_SubjectAccessReviewResponse_To_v1_SubjectAccessReviewResponse, + autoconvert_api_SubjectAccessReview_To_v1_SubjectAccessReview, + autoconvert_api_TLSConfig_To_v1_TLSConfig, + autoconvert_api_TemplateList_To_v1_TemplateList, + autoconvert_api_Template_To_v1_Template, + autoconvert_api_UserIdentityMapping_To_v1_UserIdentityMapping, + autoconvert_api_UserList_To_v1_UserList, + autoconvert_api_User_To_v1_User, + autoconvert_api_WebHookTrigger_To_v1_WebHookTrigger, + autoconvert_v1_BuildConfigList_To_api_BuildConfigList, + autoconvert_v1_BuildConfigSpec_To_api_BuildConfigSpec, + autoconvert_v1_BuildConfigStatus_To_api_BuildConfigStatus, + autoconvert_v1_BuildConfig_To_api_BuildConfig, + autoconvert_v1_BuildList_To_api_BuildList, + autoconvert_v1_BuildLogOptions_To_api_BuildLogOptions, + autoconvert_v1_BuildLog_To_api_BuildLog, + autoconvert_v1_BuildOutput_To_api_BuildOutput, + autoconvert_v1_BuildRequest_To_api_BuildRequest, + autoconvert_v1_BuildSource_To_api_BuildSource, + autoconvert_v1_BuildSpec_To_api_BuildSpec, + autoconvert_v1_BuildStatus_To_api_BuildStatus, + autoconvert_v1_BuildStrategy_To_api_BuildStrategy, + autoconvert_v1_BuildTriggerPolicy_To_api_BuildTriggerPolicy, + autoconvert_v1_Build_To_api_Build, + autoconvert_v1_ClusterNetworkList_To_api_ClusterNetworkList, + autoconvert_v1_ClusterNetwork_To_api_ClusterNetwork, + autoconvert_v1_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList, + autoconvert_v1_ClusterPolicyBinding_To_api_ClusterPolicyBinding, + autoconvert_v1_ClusterPolicyList_To_api_ClusterPolicyList, + autoconvert_v1_ClusterPolicy_To_api_ClusterPolicy, + autoconvert_v1_ClusterRoleBindingList_To_api_ClusterRoleBindingList, + autoconvert_v1_ClusterRoleBinding_To_api_ClusterRoleBinding, + autoconvert_v1_ClusterRoleList_To_api_ClusterRoleList, + autoconvert_v1_ClusterRole_To_api_ClusterRole, + autoconvert_v1_CustomBuildStrategy_To_api_CustomBuildStrategy, + autoconvert_v1_DeploymentConfigList_To_api_DeploymentConfigList, + autoconvert_v1_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec, + autoconvert_v1_DeploymentConfigRollback_To_api_DeploymentConfigRollback, + autoconvert_v1_DeploymentConfig_To_api_DeploymentConfig, + autoconvert_v1_DockerBuildStrategy_To_api_DockerBuildStrategy, + autoconvert_v1_EnvVarSource_To_api_EnvVarSource, + autoconvert_v1_EnvVar_To_api_EnvVar, + autoconvert_v1_GitBuildSource_To_api_GitBuildSource, + autoconvert_v1_GitSourceRevision_To_api_GitSourceRevision, + autoconvert_v1_GroupList_To_api_GroupList, + autoconvert_v1_Group_To_api_Group, + autoconvert_v1_HostSubnetList_To_api_HostSubnetList, + autoconvert_v1_HostSubnet_To_api_HostSubnet, + autoconvert_v1_IdentityList_To_api_IdentityList, + autoconvert_v1_Identity_To_api_Identity, + autoconvert_v1_ImageChangeTrigger_To_api_ImageChangeTrigger, + autoconvert_v1_ImageList_To_api_ImageList, + autoconvert_v1_ImageStreamImage_To_api_ImageStreamImage, + autoconvert_v1_ImageStreamList_To_api_ImageStreamList, + autoconvert_v1_ImageStreamMapping_To_api_ImageStreamMapping, + autoconvert_v1_ImageStreamSpec_To_api_ImageStreamSpec, + autoconvert_v1_ImageStreamStatus_To_api_ImageStreamStatus, + autoconvert_v1_ImageStreamTag_To_api_ImageStreamTag, + autoconvert_v1_ImageStream_To_api_ImageStream, + autoconvert_v1_Image_To_api_Image, + autoconvert_v1_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview, + autoconvert_v1_LocalObjectReference_To_api_LocalObjectReference, + autoconvert_v1_LocalResourceAccessReview_To_api_LocalResourceAccessReview, + autoconvert_v1_LocalSubjectAccessReview_To_api_LocalSubjectAccessReview, + autoconvert_v1_NetNamespaceList_To_api_NetNamespaceList, + autoconvert_v1_NetNamespace_To_api_NetNamespace, + autoconvert_v1_OAuthAccessTokenList_To_api_OAuthAccessTokenList, + autoconvert_v1_OAuthAccessToken_To_api_OAuthAccessToken, + autoconvert_v1_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList, + autoconvert_v1_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken, + autoconvert_v1_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList, + autoconvert_v1_OAuthClientAuthorization_To_api_OAuthClientAuthorization, + autoconvert_v1_OAuthClientList_To_api_OAuthClientList, + autoconvert_v1_OAuthClient_To_api_OAuthClient, + autoconvert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector, + autoconvert_v1_ObjectMeta_To_api_ObjectMeta, + autoconvert_v1_ObjectReference_To_api_ObjectReference, + autoconvert_v1_Parameter_To_api_Parameter, + autoconvert_v1_PolicyBindingList_To_api_PolicyBindingList, + autoconvert_v1_PolicyBinding_To_api_PolicyBinding, + autoconvert_v1_PolicyList_To_api_PolicyList, + autoconvert_v1_PolicyRule_To_api_PolicyRule, + autoconvert_v1_Policy_To_api_Policy, + autoconvert_v1_ProjectList_To_api_ProjectList, + autoconvert_v1_ProjectRequest_To_api_ProjectRequest, + autoconvert_v1_ProjectSpec_To_api_ProjectSpec, + autoconvert_v1_ProjectStatus_To_api_ProjectStatus, + autoconvert_v1_Project_To_api_Project, + autoconvert_v1_ResourceAccessReviewResponse_To_api_ResourceAccessReviewResponse, + autoconvert_v1_ResourceAccessReview_To_api_ResourceAccessReview, + autoconvert_v1_ResourceRequirements_To_api_ResourceRequirements, + autoconvert_v1_RoleBindingList_To_api_RoleBindingList, + autoconvert_v1_RoleBinding_To_api_RoleBinding, + autoconvert_v1_RoleList_To_api_RoleList, + autoconvert_v1_Role_To_api_Role, + autoconvert_v1_RouteList_To_api_RouteList, + autoconvert_v1_RoutePort_To_api_RoutePort, + autoconvert_v1_RouteSpec_To_api_RouteSpec, + autoconvert_v1_RouteStatus_To_api_RouteStatus, + autoconvert_v1_Route_To_api_Route, + autoconvert_v1_SecretSpec_To_api_SecretSpec, + autoconvert_v1_SourceBuildStrategy_To_api_SourceBuildStrategy, + autoconvert_v1_SourceControlUser_To_api_SourceControlUser, + autoconvert_v1_SourceRevision_To_api_SourceRevision, + autoconvert_v1_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse, + autoconvert_v1_SubjectAccessReview_To_api_SubjectAccessReview, + autoconvert_v1_TLSConfig_To_api_TLSConfig, + autoconvert_v1_TemplateList_To_api_TemplateList, + autoconvert_v1_Template_To_api_Template, + autoconvert_v1_UserIdentityMapping_To_api_UserIdentityMapping, + autoconvert_v1_UserList_To_api_UserList, + autoconvert_v1_User_To_api_User, + autoconvert_v1_WebHookTrigger_To_api_WebHookTrigger, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. diff --git a/pkg/api/v1/deep_copy_generated.go b/pkg/api/v1/deep_copy_generated.go index 38f79d1d72bc..ea94776a8321 100644 --- a/pkg/api/v1/deep_copy_generated.go +++ b/pkg/api/v1/deep_copy_generated.go @@ -13,6 +13,7 @@ import ( templateapiv1 "github.com/openshift/origin/pkg/template/api/v1" userapiv1 "github.com/openshift/origin/pkg/user/api/v1" api "k8s.io/kubernetes/pkg/api" + unversioned "k8s.io/kubernetes/pkg/api/unversioned" pkgapiv1 "k8s.io/kubernetes/pkg/api/v1" conversion "k8s.io/kubernetes/pkg/conversion" runtime "k8s.io/kubernetes/pkg/runtime" @@ -36,7 +37,7 @@ func deepCopy_v1_ClusterPolicy(in v1.ClusterPolicy, out *v1.ClusterPolicy, c *co if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -46,7 +47,7 @@ func deepCopy_v1_ClusterPolicy(in v1.ClusterPolicy, out *v1.ClusterPolicy, c *co if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if in.Roles != nil { out.Roles = make([]v1.NamedClusterRole, len(in.Roles)) @@ -65,7 +66,7 @@ func deepCopy_v1_ClusterPolicyBinding(in v1.ClusterPolicyBinding, out *v1.Cluste if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -75,7 +76,7 @@ func deepCopy_v1_ClusterPolicyBinding(in v1.ClusterPolicyBinding, out *v1.Cluste if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if newVal, err := c.DeepCopy(in.PolicyRef); err != nil { return err @@ -99,12 +100,12 @@ func deepCopy_v1_ClusterPolicyBindingList(in v1.ClusterPolicyBindingList, out *v if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1.ClusterPolicyBinding, len(in.Items)) @@ -123,12 +124,12 @@ func deepCopy_v1_ClusterPolicyList(in v1.ClusterPolicyList, out *v1.ClusterPolic if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1.ClusterPolicy, len(in.Items)) @@ -147,7 +148,7 @@ func deepCopy_v1_ClusterRole(in v1.ClusterRole, out *v1.ClusterRole, c *conversi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -171,7 +172,7 @@ func deepCopy_v1_ClusterRoleBinding(in v1.ClusterRoleBinding, out *v1.ClusterRol if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -218,12 +219,12 @@ func deepCopy_v1_ClusterRoleBindingList(in v1.ClusterRoleBindingList, out *v1.Cl if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1.ClusterRoleBinding, len(in.Items)) @@ -242,12 +243,12 @@ func deepCopy_v1_ClusterRoleList(in v1.ClusterRoleList, out *v1.ClusterRoleList, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1.ClusterRole, len(in.Items)) @@ -266,7 +267,7 @@ func deepCopy_v1_IsPersonalSubjectAccessReview(in v1.IsPersonalSubjectAccessRevi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } return nil } @@ -275,7 +276,7 @@ func deepCopy_v1_LocalResourceAccessReview(in v1.LocalResourceAccessReview, out if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_v1_AuthorizationAttributes(in.AuthorizationAttributes, &out.AuthorizationAttributes, c); err != nil { return err @@ -287,7 +288,7 @@ func deepCopy_v1_LocalSubjectAccessReview(in v1.LocalSubjectAccessReview, out *v if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_v1_AuthorizationAttributes(in.AuthorizationAttributes, &out.AuthorizationAttributes, c); err != nil { return err @@ -340,7 +341,7 @@ func deepCopy_v1_Policy(in v1.Policy, out *v1.Policy, c *conversion.Cloner) erro if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -350,7 +351,7 @@ func deepCopy_v1_Policy(in v1.Policy, out *v1.Policy, c *conversion.Cloner) erro if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if in.Roles != nil { out.Roles = make([]v1.NamedRole, len(in.Roles)) @@ -369,7 +370,7 @@ func deepCopy_v1_PolicyBinding(in v1.PolicyBinding, out *v1.PolicyBinding, c *co if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -379,7 +380,7 @@ func deepCopy_v1_PolicyBinding(in v1.PolicyBinding, out *v1.PolicyBinding, c *co if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if newVal, err := c.DeepCopy(in.PolicyRef); err != nil { return err @@ -403,12 +404,12 @@ func deepCopy_v1_PolicyBindingList(in v1.PolicyBindingList, out *v1.PolicyBindin if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1.PolicyBinding, len(in.Items)) @@ -427,12 +428,12 @@ func deepCopy_v1_PolicyList(in v1.PolicyList, out *v1.PolicyList, c *conversion. if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1.Policy, len(in.Items)) @@ -500,7 +501,7 @@ func deepCopy_v1_ResourceAccessReview(in v1.ResourceAccessReview, out *v1.Resour if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_v1_AuthorizationAttributes(in.AuthorizationAttributes, &out.AuthorizationAttributes, c); err != nil { return err @@ -512,7 +513,7 @@ func deepCopy_v1_ResourceAccessReviewResponse(in v1.ResourceAccessReviewResponse if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } out.Namespace = in.Namespace if in.UsersSlice != nil { @@ -538,7 +539,7 @@ func deepCopy_v1_Role(in v1.Role, out *v1.Role, c *conversion.Cloner) error { if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -562,7 +563,7 @@ func deepCopy_v1_RoleBinding(in v1.RoleBinding, out *v1.RoleBinding, c *conversi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -609,12 +610,12 @@ func deepCopy_v1_RoleBindingList(in v1.RoleBindingList, out *v1.RoleBindingList, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1.RoleBinding, len(in.Items)) @@ -633,12 +634,12 @@ func deepCopy_v1_RoleList(in v1.RoleList, out *v1.RoleList, c *conversion.Cloner if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1.Role, len(in.Items)) @@ -657,7 +658,7 @@ func deepCopy_v1_SubjectAccessReview(in v1.SubjectAccessReview, out *v1.SubjectA if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_v1_AuthorizationAttributes(in.AuthorizationAttributes, &out.AuthorizationAttributes, c); err != nil { return err @@ -678,7 +679,7 @@ func deepCopy_v1_SubjectAccessReviewResponse(in v1.SubjectAccessReviewResponse, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } out.Namespace = in.Namespace out.Allowed = in.Allowed @@ -690,7 +691,7 @@ func deepCopy_v1_Build(in apiv1.Build, out *apiv1.Build, c *conversion.Cloner) e if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -710,7 +711,7 @@ func deepCopy_v1_BuildConfig(in apiv1.BuildConfig, out *apiv1.BuildConfig, c *co if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -730,12 +731,12 @@ func deepCopy_v1_BuildConfigList(in apiv1.BuildConfigList, out *apiv1.BuildConfi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]apiv1.BuildConfig, len(in.Items)) @@ -776,12 +777,12 @@ func deepCopy_v1_BuildList(in apiv1.BuildList, out *apiv1.BuildList, c *conversi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]apiv1.Build, len(in.Items)) @@ -800,12 +801,12 @@ func deepCopy_v1_BuildLog(in apiv1.BuildLog, out *apiv1.BuildLog, c *conversion. if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } return nil } @@ -814,7 +815,7 @@ func deepCopy_v1_BuildLogOptions(in apiv1.BuildLogOptions, out *apiv1.BuildLogOp if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } out.Follow = in.Follow out.NoWait = in.NoWait @@ -847,7 +848,7 @@ func deepCopy_v1_BuildRequest(in apiv1.BuildRequest, out *apiv1.BuildRequest, c if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -959,7 +960,7 @@ func deepCopy_v1_BuildStatus(in apiv1.BuildStatus, out *apiv1.BuildStatus, c *co if newVal, err := c.DeepCopy(in.StartTimestamp); err != nil { return err } else { - out.StartTimestamp = newVal.(*util.Time) + out.StartTimestamp = newVal.(*unversioned.Time) } } else { out.StartTimestamp = nil @@ -968,7 +969,7 @@ func deepCopy_v1_BuildStatus(in apiv1.BuildStatus, out *apiv1.BuildStatus, c *co if newVal, err := c.DeepCopy(in.CompletionTimestamp); err != nil { return err } else { - out.CompletionTimestamp = newVal.(*util.Time) + out.CompletionTimestamp = newVal.(*unversioned.Time) } } else { out.CompletionTimestamp = nil @@ -1275,7 +1276,7 @@ func deepCopy_v1_DeploymentConfig(in deployapiv1.DeploymentConfig, out *deployap if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1295,12 +1296,12 @@ func deepCopy_v1_DeploymentConfigList(in deployapiv1.DeploymentConfigList, out * if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]deployapiv1.DeploymentConfig, len(in.Items)) @@ -1319,7 +1320,7 @@ func deepCopy_v1_DeploymentConfigRollback(in deployapiv1.DeploymentConfigRollbac if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_v1_DeploymentConfigRollbackSpec(in.Spec, &out.Spec, c); err != nil { return err @@ -1605,7 +1606,7 @@ func deepCopy_v1_Image(in imageapiv1.Image, out *imageapiv1.Image, c *conversion if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1627,12 +1628,12 @@ func deepCopy_v1_ImageList(in imageapiv1.ImageList, out *imageapiv1.ImageList, c if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]imageapiv1.Image, len(in.Items)) @@ -1651,7 +1652,7 @@ func deepCopy_v1_ImageStream(in imageapiv1.ImageStream, out *imageapiv1.ImageStr if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1671,7 +1672,7 @@ func deepCopy_v1_ImageStreamImage(in imageapiv1.ImageStreamImage, out *imageapiv if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1688,12 +1689,12 @@ func deepCopy_v1_ImageStreamList(in imageapiv1.ImageStreamList, out *imageapiv1. if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]imageapiv1.ImageStream, len(in.Items)) @@ -1712,7 +1713,7 @@ func deepCopy_v1_ImageStreamMapping(in imageapiv1.ImageStreamMapping, out *image if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1760,7 +1761,7 @@ func deepCopy_v1_ImageStreamTag(in imageapiv1.ImageStreamTag, out *imageapiv1.Im if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1814,7 +1815,7 @@ func deepCopy_v1_TagEvent(in imageapiv1.TagEvent, out *imageapiv1.TagEvent, c *c if newVal, err := c.DeepCopy(in.Created); err != nil { return err } else { - out.Created = newVal.(util.Time) + out.Created = newVal.(unversioned.Time) } out.DockerImageReference = in.DockerImageReference out.Image = in.Image @@ -1825,7 +1826,7 @@ func deepCopy_v1_OAuthAccessToken(in oauthapiv1.OAuthAccessToken, out *oauthapiv if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1854,12 +1855,12 @@ func deepCopy_v1_OAuthAccessTokenList(in oauthapiv1.OAuthAccessTokenList, out *o if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapiv1.OAuthAccessToken, len(in.Items)) @@ -1878,7 +1879,7 @@ func deepCopy_v1_OAuthAuthorizeToken(in oauthapiv1.OAuthAuthorizeToken, out *oau if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1906,12 +1907,12 @@ func deepCopy_v1_OAuthAuthorizeTokenList(in oauthapiv1.OAuthAuthorizeTokenList, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapiv1.OAuthAuthorizeToken, len(in.Items)) @@ -1930,7 +1931,7 @@ func deepCopy_v1_OAuthClient(in oauthapiv1.OAuthClient, out *oauthapiv1.OAuthCli if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1954,7 +1955,7 @@ func deepCopy_v1_OAuthClientAuthorization(in oauthapiv1.OAuthClientAuthorization if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1979,12 +1980,12 @@ func deepCopy_v1_OAuthClientAuthorizationList(in oauthapiv1.OAuthClientAuthoriza if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapiv1.OAuthClientAuthorization, len(in.Items)) @@ -2003,12 +2004,12 @@ func deepCopy_v1_OAuthClientList(in oauthapiv1.OAuthClientList, out *oauthapiv1. if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapiv1.OAuthClient, len(in.Items)) @@ -2027,7 +2028,7 @@ func deepCopy_v1_Project(in projectapiv1.Project, out *projectapiv1.Project, c * if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2047,12 +2048,12 @@ func deepCopy_v1_ProjectList(in projectapiv1.ProjectList, out *projectapiv1.Proj if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]projectapiv1.Project, len(in.Items)) @@ -2071,7 +2072,7 @@ func deepCopy_v1_ProjectRequest(in projectapiv1.ProjectRequest, out *projectapiv if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2104,7 +2105,7 @@ func deepCopy_v1_Route(in routeapiv1.Route, out *routeapiv1.Route, c *conversion if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2124,12 +2125,12 @@ func deepCopy_v1_RouteList(in routeapiv1.RouteList, out *routeapiv1.RouteList, c if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]routeapiv1.Route, len(in.Items)) @@ -2197,7 +2198,7 @@ func deepCopy_v1_ClusterNetwork(in sdnapiv1.ClusterNetwork, out *sdnapiv1.Cluste if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2214,12 +2215,12 @@ func deepCopy_v1_ClusterNetworkList(in sdnapiv1.ClusterNetworkList, out *sdnapiv if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]sdnapiv1.ClusterNetwork, len(in.Items)) @@ -2238,7 +2239,7 @@ func deepCopy_v1_HostSubnet(in sdnapiv1.HostSubnet, out *sdnapiv1.HostSubnet, c if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2255,12 +2256,12 @@ func deepCopy_v1_HostSubnetList(in sdnapiv1.HostSubnetList, out *sdnapiv1.HostSu if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]sdnapiv1.HostSubnet, len(in.Items)) @@ -2279,7 +2280,7 @@ func deepCopy_v1_NetNamespace(in sdnapiv1.NetNamespace, out *sdnapiv1.NetNamespa if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2295,12 +2296,12 @@ func deepCopy_v1_NetNamespaceList(in sdnapiv1.NetNamespaceList, out *sdnapiv1.Ne if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]sdnapiv1.NetNamespace, len(in.Items)) @@ -2330,7 +2331,7 @@ func deepCopy_v1_Template(in templateapiv1.Template, out *templateapiv1.Template if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2374,12 +2375,12 @@ func deepCopy_v1_TemplateList(in templateapiv1.TemplateList, out *templateapiv1. if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]templateapiv1.Template, len(in.Items)) @@ -2398,7 +2399,7 @@ func deepCopy_v1_Group(in userapiv1.Group, out *userapiv1.Group, c *conversion.C if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2420,12 +2421,12 @@ func deepCopy_v1_GroupList(in userapiv1.GroupList, out *userapiv1.GroupList, c * if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]userapiv1.Group, len(in.Items)) @@ -2444,7 +2445,7 @@ func deepCopy_v1_Identity(in userapiv1.Identity, out *userapiv1.Identity, c *con if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2473,12 +2474,12 @@ func deepCopy_v1_IdentityList(in userapiv1.IdentityList, out *userapiv1.Identity if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]userapiv1.Identity, len(in.Items)) @@ -2497,7 +2498,7 @@ func deepCopy_v1_User(in userapiv1.User, out *userapiv1.User, c *conversion.Clon if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2528,7 +2529,7 @@ func deepCopy_v1_UserIdentityMapping(in userapiv1.UserIdentityMapping, out *user if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2552,12 +2553,12 @@ func deepCopy_v1_UserList(in userapiv1.UserList, out *userapiv1.UserList, c *con if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]userapiv1.User, len(in.Items)) diff --git a/pkg/api/v1beta3/conversion_generated.go b/pkg/api/v1beta3/conversion_generated.go index 0e3b05364a57..fbe828ca85f9 100644 --- a/pkg/api/v1beta3/conversion_generated.go +++ b/pkg/api/v1beta3/conversion_generated.go @@ -29,11 +29,11 @@ import ( reflect "reflect" ) -func convert_api_ClusterPolicy_To_v1beta3_ClusterPolicy(in *api.ClusterPolicy, out *v1beta3.ClusterPolicy, s conversion.Scope) error { +func autoconvert_api_ClusterPolicy_To_v1beta3_ClusterPolicy(in *api.ClusterPolicy, out *v1beta3.ClusterPolicy, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ClusterPolicy))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -48,14 +48,40 @@ func convert_api_ClusterPolicy_To_v1beta3_ClusterPolicy(in *api.ClusterPolicy, o return nil } -func convert_api_ClusterPolicyBindingList_To_v1beta3_ClusterPolicyBindingList(in *api.ClusterPolicyBindingList, out *v1beta3.ClusterPolicyBindingList, s conversion.Scope) error { +func convert_api_ClusterPolicy_To_v1beta3_ClusterPolicy(in *api.ClusterPolicy, out *v1beta3.ClusterPolicy, s conversion.Scope) error { + return autoconvert_api_ClusterPolicy_To_v1beta3_ClusterPolicy(in, out, s) +} + +func autoconvert_api_ClusterPolicyBinding_To_v1beta3_ClusterPolicyBinding(in *api.ClusterPolicyBinding, out *v1beta3.ClusterPolicyBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ClusterPolicyBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.PolicyRef, &out.PolicyRef, s); err != nil { + return err + } + if err := s.Convert(&in.RoleBindings, &out.RoleBindings, 0); err != nil { + return err + } + return nil +} + +func autoconvert_api_ClusterPolicyBindingList_To_v1beta3_ClusterPolicyBindingList(in *api.ClusterPolicyBindingList, out *v1beta3.ClusterPolicyBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ClusterPolicyBindingList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -71,20 +97,24 @@ func convert_api_ClusterPolicyBindingList_To_v1beta3_ClusterPolicyBindingList(in return nil } -func convert_api_ClusterPolicyList_To_v1beta3_ClusterPolicyList(in *api.ClusterPolicyList, out *v1beta3.ClusterPolicyList, s conversion.Scope) error { +func convert_api_ClusterPolicyBindingList_To_v1beta3_ClusterPolicyBindingList(in *api.ClusterPolicyBindingList, out *v1beta3.ClusterPolicyBindingList, s conversion.Scope) error { + return autoconvert_api_ClusterPolicyBindingList_To_v1beta3_ClusterPolicyBindingList(in, out, s) +} + +func autoconvert_api_ClusterPolicyList_To_v1beta3_ClusterPolicyList(in *api.ClusterPolicyList, out *v1beta3.ClusterPolicyList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ClusterPolicyList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { out.Items = make([]v1beta3.ClusterPolicy, len(in.Items)) for i := range in.Items { - if err := convert_api_ClusterPolicy_To_v1beta3_ClusterPolicy(&in.Items[i], &out.Items[i], s); err != nil { + if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { return err } } @@ -94,11 +124,15 @@ func convert_api_ClusterPolicyList_To_v1beta3_ClusterPolicyList(in *api.ClusterP return nil } -func convert_api_ClusterRole_To_v1beta3_ClusterRole(in *api.ClusterRole, out *v1beta3.ClusterRole, s conversion.Scope) error { +func convert_api_ClusterPolicyList_To_v1beta3_ClusterPolicyList(in *api.ClusterPolicyList, out *v1beta3.ClusterPolicyList, s conversion.Scope) error { + return autoconvert_api_ClusterPolicyList_To_v1beta3_ClusterPolicyList(in, out, s) +} + +func autoconvert_api_ClusterRole_To_v1beta3_ClusterRole(in *api.ClusterRole, out *v1beta3.ClusterRole, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ClusterRole))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -117,14 +151,44 @@ func convert_api_ClusterRole_To_v1beta3_ClusterRole(in *api.ClusterRole, out *v1 return nil } -func convert_api_ClusterRoleBindingList_To_v1beta3_ClusterRoleBindingList(in *api.ClusterRoleBindingList, out *v1beta3.ClusterRoleBindingList, s conversion.Scope) error { +func convert_api_ClusterRole_To_v1beta3_ClusterRole(in *api.ClusterRole, out *v1beta3.ClusterRole, s conversion.Scope) error { + return autoconvert_api_ClusterRole_To_v1beta3_ClusterRole(in, out, s) +} + +func autoconvert_api_ClusterRoleBinding_To_v1beta3_ClusterRoleBinding(in *api.ClusterRoleBinding, out *v1beta3.ClusterRoleBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ClusterRoleBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Subjects != nil { + out.Subjects = make([]pkgapiv1beta3.ObjectReference, len(in.Subjects)) + for i := range in.Subjects { + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.Subjects[i], &out.Subjects[i], s); err != nil { + return err + } + } + } else { + out.Subjects = nil + } + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.RoleRef, &out.RoleRef, s); err != nil { + return err + } + return nil +} + +func autoconvert_api_ClusterRoleBindingList_To_v1beta3_ClusterRoleBindingList(in *api.ClusterRoleBindingList, out *v1beta3.ClusterRoleBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ClusterRoleBindingList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -140,14 +204,18 @@ func convert_api_ClusterRoleBindingList_To_v1beta3_ClusterRoleBindingList(in *ap return nil } -func convert_api_ClusterRoleList_To_v1beta3_ClusterRoleList(in *api.ClusterRoleList, out *v1beta3.ClusterRoleList, s conversion.Scope) error { +func convert_api_ClusterRoleBindingList_To_v1beta3_ClusterRoleBindingList(in *api.ClusterRoleBindingList, out *v1beta3.ClusterRoleBindingList, s conversion.Scope) error { + return autoconvert_api_ClusterRoleBindingList_To_v1beta3_ClusterRoleBindingList(in, out, s) +} + +func autoconvert_api_ClusterRoleList_To_v1beta3_ClusterRoleList(in *api.ClusterRoleList, out *v1beta3.ClusterRoleList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.ClusterRoleList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -163,24 +231,97 @@ func convert_api_ClusterRoleList_To_v1beta3_ClusterRoleList(in *api.ClusterRoleL return nil } -func convert_api_IsPersonalSubjectAccessReview_To_v1beta3_IsPersonalSubjectAccessReview(in *api.IsPersonalSubjectAccessReview, out *v1beta3.IsPersonalSubjectAccessReview, s conversion.Scope) error { +func convert_api_ClusterRoleList_To_v1beta3_ClusterRoleList(in *api.ClusterRoleList, out *v1beta3.ClusterRoleList, s conversion.Scope) error { + return autoconvert_api_ClusterRoleList_To_v1beta3_ClusterRoleList(in, out, s) +} + +func autoconvert_api_IsPersonalSubjectAccessReview_To_v1beta3_IsPersonalSubjectAccessReview(in *api.IsPersonalSubjectAccessReview, out *v1beta3.IsPersonalSubjectAccessReview, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.IsPersonalSubjectAccessReview))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } return nil } -func convert_api_PolicyBindingList_To_v1beta3_PolicyBindingList(in *api.PolicyBindingList, out *v1beta3.PolicyBindingList, s conversion.Scope) error { +func convert_api_IsPersonalSubjectAccessReview_To_v1beta3_IsPersonalSubjectAccessReview(in *api.IsPersonalSubjectAccessReview, out *v1beta3.IsPersonalSubjectAccessReview, s conversion.Scope) error { + return autoconvert_api_IsPersonalSubjectAccessReview_To_v1beta3_IsPersonalSubjectAccessReview(in, out, s) +} + +func autoconvert_api_LocalResourceAccessReview_To_v1beta3_LocalResourceAccessReview(in *api.LocalResourceAccessReview, out *v1beta3.LocalResourceAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LocalResourceAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.Action has no peer in out + return nil +} + +func autoconvert_api_LocalSubjectAccessReview_To_v1beta3_LocalSubjectAccessReview(in *api.LocalSubjectAccessReview, out *v1beta3.LocalSubjectAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.LocalSubjectAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.Action has no peer in out + out.User = in.User + // in.Groups has no peer in out + return nil +} + +func autoconvert_api_Policy_To_v1beta3_Policy(in *api.Policy, out *v1beta3.Policy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.Policy))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := s.Convert(&in.Roles, &out.Roles, 0); err != nil { + return err + } + return nil +} + +func autoconvert_api_PolicyBinding_To_v1beta3_PolicyBinding(in *api.PolicyBinding, out *v1beta3.PolicyBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PolicyBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.PolicyRef, &out.PolicyRef, s); err != nil { + return err + } + if err := s.Convert(&in.RoleBindings, &out.RoleBindings, 0); err != nil { + return err + } + return nil +} + +func autoconvert_api_PolicyBindingList_To_v1beta3_PolicyBindingList(in *api.PolicyBindingList, out *v1beta3.PolicyBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PolicyBindingList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -196,14 +337,18 @@ func convert_api_PolicyBindingList_To_v1beta3_PolicyBindingList(in *api.PolicyBi return nil } -func convert_api_PolicyList_To_v1beta3_PolicyList(in *api.PolicyList, out *v1beta3.PolicyList, s conversion.Scope) error { +func convert_api_PolicyBindingList_To_v1beta3_PolicyBindingList(in *api.PolicyBindingList, out *v1beta3.PolicyBindingList, s conversion.Scope) error { + return autoconvert_api_PolicyBindingList_To_v1beta3_PolicyBindingList(in, out, s) +} + +func autoconvert_api_PolicyList_To_v1beta3_PolicyList(in *api.PolicyList, out *v1beta3.PolicyList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PolicyList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -219,11 +364,61 @@ func convert_api_PolicyList_To_v1beta3_PolicyList(in *api.PolicyList, out *v1bet return nil } -func convert_api_Role_To_v1beta3_Role(in *api.Role, out *v1beta3.Role, s conversion.Scope) error { +func convert_api_PolicyList_To_v1beta3_PolicyList(in *api.PolicyList, out *v1beta3.PolicyList, s conversion.Scope) error { + return autoconvert_api_PolicyList_To_v1beta3_PolicyList(in, out, s) +} + +func autoconvert_api_PolicyRule_To_v1beta3_PolicyRule(in *api.PolicyRule, out *v1beta3.PolicyRule, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.PolicyRule))(in) + } + // in.Verbs has no peer in out + if err := s.Convert(&in.AttributeRestrictions, &out.AttributeRestrictions, 0); err != nil { + return err + } + if in.APIGroups != nil { + out.APIGroups = make([]string, len(in.APIGroups)) + for i := range in.APIGroups { + out.APIGroups[i] = in.APIGroups[i] + } + } else { + out.APIGroups = nil + } + // in.Resources has no peer in out + // in.ResourceNames has no peer in out + // in.NonResourceURLs has no peer in out + return nil +} + +func autoconvert_api_ResourceAccessReview_To_v1beta3_ResourceAccessReview(in *api.ResourceAccessReview, out *v1beta3.ResourceAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ResourceAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.Action has no peer in out + return nil +} + +func autoconvert_api_ResourceAccessReviewResponse_To_v1beta3_ResourceAccessReviewResponse(in *api.ResourceAccessReviewResponse, out *v1beta3.ResourceAccessReviewResponse, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.ResourceAccessReviewResponse))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + out.Namespace = in.Namespace + // in.Users has no peer in out + // in.Groups has no peer in out + return nil +} + +func autoconvert_api_Role_To_v1beta3_Role(in *api.Role, out *v1beta3.Role, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.Role))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -242,14 +437,44 @@ func convert_api_Role_To_v1beta3_Role(in *api.Role, out *v1beta3.Role, s convers return nil } -func convert_api_RoleBindingList_To_v1beta3_RoleBindingList(in *api.RoleBindingList, out *v1beta3.RoleBindingList, s conversion.Scope) error { +func convert_api_Role_To_v1beta3_Role(in *api.Role, out *v1beta3.Role, s conversion.Scope) error { + return autoconvert_api_Role_To_v1beta3_Role(in, out, s) +} + +func autoconvert_api_RoleBinding_To_v1beta3_RoleBinding(in *api.RoleBinding, out *v1beta3.RoleBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.RoleBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Subjects != nil { + out.Subjects = make([]pkgapiv1beta3.ObjectReference, len(in.Subjects)) + for i := range in.Subjects { + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.Subjects[i], &out.Subjects[i], s); err != nil { + return err + } + } + } else { + out.Subjects = nil + } + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.RoleRef, &out.RoleRef, s); err != nil { + return err + } + return nil +} + +func autoconvert_api_RoleBindingList_To_v1beta3_RoleBindingList(in *api.RoleBindingList, out *v1beta3.RoleBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.RoleBindingList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -265,14 +490,18 @@ func convert_api_RoleBindingList_To_v1beta3_RoleBindingList(in *api.RoleBindingL return nil } -func convert_api_RoleList_To_v1beta3_RoleList(in *api.RoleList, out *v1beta3.RoleList, s conversion.Scope) error { +func convert_api_RoleBindingList_To_v1beta3_RoleBindingList(in *api.RoleBindingList, out *v1beta3.RoleBindingList, s conversion.Scope) error { + return autoconvert_api_RoleBindingList_To_v1beta3_RoleBindingList(in, out, s) +} + +func autoconvert_api_RoleList_To_v1beta3_RoleList(in *api.RoleList, out *v1beta3.RoleList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.RoleList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -288,11 +517,28 @@ func convert_api_RoleList_To_v1beta3_RoleList(in *api.RoleList, out *v1beta3.Rol return nil } -func convert_api_SubjectAccessReviewResponse_To_v1beta3_SubjectAccessReviewResponse(in *api.SubjectAccessReviewResponse, out *v1beta3.SubjectAccessReviewResponse, s conversion.Scope) error { +func convert_api_RoleList_To_v1beta3_RoleList(in *api.RoleList, out *v1beta3.RoleList, s conversion.Scope) error { + return autoconvert_api_RoleList_To_v1beta3_RoleList(in, out, s) +} + +func autoconvert_api_SubjectAccessReview_To_v1beta3_SubjectAccessReview(in *api.SubjectAccessReview, out *v1beta3.SubjectAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*api.SubjectAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.Action has no peer in out + out.User = in.User + // in.Groups has no peer in out + return nil +} + +func autoconvert_api_SubjectAccessReviewResponse_To_v1beta3_SubjectAccessReviewResponse(in *api.SubjectAccessReviewResponse, out *v1beta3.SubjectAccessReviewResponse, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.SubjectAccessReviewResponse))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Namespace = in.Namespace @@ -301,11 +547,15 @@ func convert_api_SubjectAccessReviewResponse_To_v1beta3_SubjectAccessReviewRespo return nil } -func convert_v1beta3_ClusterPolicy_To_api_ClusterPolicy(in *v1beta3.ClusterPolicy, out *api.ClusterPolicy, s conversion.Scope) error { +func convert_api_SubjectAccessReviewResponse_To_v1beta3_SubjectAccessReviewResponse(in *api.SubjectAccessReviewResponse, out *v1beta3.SubjectAccessReviewResponse, s conversion.Scope) error { + return autoconvert_api_SubjectAccessReviewResponse_To_v1beta3_SubjectAccessReviewResponse(in, out, s) +} + +func autoconvert_v1beta3_ClusterPolicy_To_api_ClusterPolicy(in *v1beta3.ClusterPolicy, out *api.ClusterPolicy, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1beta3.ClusterPolicy))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -320,14 +570,40 @@ func convert_v1beta3_ClusterPolicy_To_api_ClusterPolicy(in *v1beta3.ClusterPolic return nil } -func convert_v1beta3_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList(in *v1beta3.ClusterPolicyBindingList, out *api.ClusterPolicyBindingList, s conversion.Scope) error { +func convert_v1beta3_ClusterPolicy_To_api_ClusterPolicy(in *v1beta3.ClusterPolicy, out *api.ClusterPolicy, s conversion.Scope) error { + return autoconvert_v1beta3_ClusterPolicy_To_api_ClusterPolicy(in, out, s) +} + +func autoconvert_v1beta3_ClusterPolicyBinding_To_api_ClusterPolicyBinding(in *v1beta3.ClusterPolicyBinding, out *api.ClusterPolicyBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.ClusterPolicyBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.PolicyRef, &out.PolicyRef, s); err != nil { + return err + } + if err := s.Convert(&in.RoleBindings, &out.RoleBindings, 0); err != nil { + return err + } + return nil +} + +func autoconvert_v1beta3_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList(in *v1beta3.ClusterPolicyBindingList, out *api.ClusterPolicyBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1beta3.ClusterPolicyBindingList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -343,14 +619,18 @@ func convert_v1beta3_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList(in return nil } -func convert_v1beta3_ClusterPolicyList_To_api_ClusterPolicyList(in *v1beta3.ClusterPolicyList, out *api.ClusterPolicyList, s conversion.Scope) error { +func convert_v1beta3_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList(in *v1beta3.ClusterPolicyBindingList, out *api.ClusterPolicyBindingList, s conversion.Scope) error { + return autoconvert_v1beta3_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList(in, out, s) +} + +func autoconvert_v1beta3_ClusterPolicyList_To_api_ClusterPolicyList(in *v1beta3.ClusterPolicyList, out *api.ClusterPolicyList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1beta3.ClusterPolicyList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -366,11 +646,15 @@ func convert_v1beta3_ClusterPolicyList_To_api_ClusterPolicyList(in *v1beta3.Clus return nil } -func convert_v1beta3_ClusterRole_To_api_ClusterRole(in *v1beta3.ClusterRole, out *api.ClusterRole, s conversion.Scope) error { +func convert_v1beta3_ClusterPolicyList_To_api_ClusterPolicyList(in *v1beta3.ClusterPolicyList, out *api.ClusterPolicyList, s conversion.Scope) error { + return autoconvert_v1beta3_ClusterPolicyList_To_api_ClusterPolicyList(in, out, s) +} + +func autoconvert_v1beta3_ClusterRole_To_api_ClusterRole(in *v1beta3.ClusterRole, out *api.ClusterRole, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1beta3.ClusterRole))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -389,43 +673,52 @@ func convert_v1beta3_ClusterRole_To_api_ClusterRole(in *v1beta3.ClusterRole, out return nil } -func convert_v1beta3_ClusterRoleBindingList_To_api_ClusterRoleBindingList(in *v1beta3.ClusterRoleBindingList, out *api.ClusterRoleBindingList, s conversion.Scope) error { +func convert_v1beta3_ClusterRole_To_api_ClusterRole(in *v1beta3.ClusterRole, out *api.ClusterRole, s conversion.Scope) error { + return autoconvert_v1beta3_ClusterRole_To_api_ClusterRole(in, out, s) +} + +func autoconvert_v1beta3_ClusterRoleBinding_To_api_ClusterRoleBinding(in *v1beta3.ClusterRoleBinding, out *api.ClusterRoleBinding, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1beta3.ClusterRoleBindingList))(in) + defaulting.(func(*v1beta3.ClusterRoleBinding))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { return err } - if in.Items != nil { - out.Items = make([]api.ClusterRoleBinding, len(in.Items)) - for i := range in.Items { - if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { + // in.UserNames has no peer in out + // in.GroupNames has no peer in out + if in.Subjects != nil { + out.Subjects = make([]pkgapi.ObjectReference, len(in.Subjects)) + for i := range in.Subjects { + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.Subjects[i], &out.Subjects[i], s); err != nil { return err } } } else { - out.Items = nil + out.Subjects = nil + } + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.RoleRef, &out.RoleRef, s); err != nil { + return err } return nil } -func convert_v1beta3_ClusterRoleList_To_api_ClusterRoleList(in *v1beta3.ClusterRoleList, out *api.ClusterRoleList, s conversion.Scope) error { +func autoconvert_v1beta3_ClusterRoleBindingList_To_api_ClusterRoleBindingList(in *v1beta3.ClusterRoleBindingList, out *api.ClusterRoleBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1beta3.ClusterRoleList))(in) + defaulting.(func(*v1beta3.ClusterRoleBindingList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { - out.Items = make([]api.ClusterRole, len(in.Items)) + out.Items = make([]api.ClusterRoleBinding, len(in.Items)) for i := range in.Items { - if err := convert_v1beta3_ClusterRole_To_api_ClusterRole(&in.Items[i], &out.Items[i], s); err != nil { + if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { return err } } @@ -435,30 +728,24 @@ func convert_v1beta3_ClusterRoleList_To_api_ClusterRoleList(in *v1beta3.ClusterR return nil } -func convert_v1beta3_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview(in *v1beta3.IsPersonalSubjectAccessReview, out *api.IsPersonalSubjectAccessReview, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1beta3.IsPersonalSubjectAccessReview))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err - } - return nil +func convert_v1beta3_ClusterRoleBindingList_To_api_ClusterRoleBindingList(in *v1beta3.ClusterRoleBindingList, out *api.ClusterRoleBindingList, s conversion.Scope) error { + return autoconvert_v1beta3_ClusterRoleBindingList_To_api_ClusterRoleBindingList(in, out, s) } -func convert_v1beta3_PolicyBindingList_To_api_PolicyBindingList(in *v1beta3.PolicyBindingList, out *api.PolicyBindingList, s conversion.Scope) error { +func autoconvert_v1beta3_ClusterRoleList_To_api_ClusterRoleList(in *v1beta3.ClusterRoleList, out *api.ClusterRoleList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1beta3.PolicyBindingList))(in) + defaulting.(func(*v1beta3.ClusterRoleList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { - out.Items = make([]api.PolicyBinding, len(in.Items)) + out.Items = make([]api.ClusterRole, len(in.Items)) for i := range in.Items { - if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { + if err := convert_v1beta3_ClusterRole_To_api_ClusterRole(&in.Items[i], &out.Items[i], s); err != nil { return err } } @@ -468,14 +755,124 @@ func convert_v1beta3_PolicyBindingList_To_api_PolicyBindingList(in *v1beta3.Poli return nil } -func convert_v1beta3_PolicyList_To_api_PolicyList(in *v1beta3.PolicyList, out *api.PolicyList, s conversion.Scope) error { +func convert_v1beta3_ClusterRoleList_To_api_ClusterRoleList(in *v1beta3.ClusterRoleList, out *api.ClusterRoleList, s conversion.Scope) error { + return autoconvert_v1beta3_ClusterRoleList_To_api_ClusterRoleList(in, out, s) +} + +func autoconvert_v1beta3_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview(in *v1beta3.IsPersonalSubjectAccessReview, out *api.IsPersonalSubjectAccessReview, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*v1beta3.PolicyList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err + defaulting.(func(*v1beta3.IsPersonalSubjectAccessReview))(in) } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + return nil +} + +func convert_v1beta3_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview(in *v1beta3.IsPersonalSubjectAccessReview, out *api.IsPersonalSubjectAccessReview, s conversion.Scope) error { + return autoconvert_v1beta3_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview(in, out, s) +} + +func autoconvert_v1beta3_LocalResourceAccessReview_To_api_LocalResourceAccessReview(in *v1beta3.LocalResourceAccessReview, out *api.LocalResourceAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.LocalResourceAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.AuthorizationAttributes has no peer in out + return nil +} + +func autoconvert_v1beta3_LocalSubjectAccessReview_To_api_LocalSubjectAccessReview(in *v1beta3.LocalSubjectAccessReview, out *api.LocalSubjectAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.LocalSubjectAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.AuthorizationAttributes has no peer in out + out.User = in.User + // in.GroupsSlice has no peer in out + return nil +} + +func autoconvert_v1beta3_Policy_To_api_Policy(in *v1beta3.Policy, out *api.Policy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.Policy))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := s.Convert(&in.Roles, &out.Roles, 0); err != nil { + return err + } + return nil +} + +func autoconvert_v1beta3_PolicyBinding_To_api_PolicyBinding(in *v1beta3.PolicyBinding, out *api.PolicyBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.PolicyBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.LastModified, &out.LastModified, 0); err != nil { + return err + } + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.PolicyRef, &out.PolicyRef, s); err != nil { + return err + } + if err := s.Convert(&in.RoleBindings, &out.RoleBindings, 0); err != nil { + return err + } + return nil +} + +func autoconvert_v1beta3_PolicyBindingList_To_api_PolicyBindingList(in *v1beta3.PolicyBindingList, out *api.PolicyBindingList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.PolicyBindingList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]api.PolicyBinding, len(in.Items)) + for i := range in.Items { + if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_PolicyBindingList_To_api_PolicyBindingList(in *v1beta3.PolicyBindingList, out *api.PolicyBindingList, s conversion.Scope) error { + return autoconvert_v1beta3_PolicyBindingList_To_api_PolicyBindingList(in, out, s) +} + +func autoconvert_v1beta3_PolicyList_To_api_PolicyList(in *v1beta3.PolicyList, out *api.PolicyList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.PolicyList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -491,11 +888,62 @@ func convert_v1beta3_PolicyList_To_api_PolicyList(in *v1beta3.PolicyList, out *a return nil } -func convert_v1beta3_Role_To_api_Role(in *v1beta3.Role, out *api.Role, s conversion.Scope) error { +func convert_v1beta3_PolicyList_To_api_PolicyList(in *v1beta3.PolicyList, out *api.PolicyList, s conversion.Scope) error { + return autoconvert_v1beta3_PolicyList_To_api_PolicyList(in, out, s) +} + +func autoconvert_v1beta3_PolicyRule_To_api_PolicyRule(in *v1beta3.PolicyRule, out *api.PolicyRule, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.PolicyRule))(in) + } + // in.Verbs has no peer in out + if err := s.Convert(&in.AttributeRestrictions, &out.AttributeRestrictions, 0); err != nil { + return err + } + if in.APIGroups != nil { + out.APIGroups = make([]string, len(in.APIGroups)) + for i := range in.APIGroups { + out.APIGroups[i] = in.APIGroups[i] + } + } else { + out.APIGroups = nil + } + // in.ResourceKinds has no peer in out + // in.Resources has no peer in out + // in.ResourceNames has no peer in out + // in.NonResourceURLsSlice has no peer in out + return nil +} + +func autoconvert_v1beta3_ResourceAccessReview_To_api_ResourceAccessReview(in *v1beta3.ResourceAccessReview, out *api.ResourceAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.ResourceAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.AuthorizationAttributes has no peer in out + return nil +} + +func autoconvert_v1beta3_ResourceAccessReviewResponse_To_api_ResourceAccessReviewResponse(in *v1beta3.ResourceAccessReviewResponse, out *api.ResourceAccessReviewResponse, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.ResourceAccessReviewResponse))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + out.Namespace = in.Namespace + // in.UsersSlice has no peer in out + // in.GroupsSlice has no peer in out + return nil +} + +func autoconvert_v1beta3_Role_To_api_Role(in *v1beta3.Role, out *api.Role, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1beta3.Role))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -514,14 +962,46 @@ func convert_v1beta3_Role_To_api_Role(in *v1beta3.Role, out *api.Role, s convers return nil } -func convert_v1beta3_RoleBindingList_To_api_RoleBindingList(in *v1beta3.RoleBindingList, out *api.RoleBindingList, s conversion.Scope) error { +func convert_v1beta3_Role_To_api_Role(in *v1beta3.Role, out *api.Role, s conversion.Scope) error { + return autoconvert_v1beta3_Role_To_api_Role(in, out, s) +} + +func autoconvert_v1beta3_RoleBinding_To_api_RoleBinding(in *v1beta3.RoleBinding, out *api.RoleBinding, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.RoleBinding))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + // in.UserNames has no peer in out + // in.GroupNames has no peer in out + if in.Subjects != nil { + out.Subjects = make([]pkgapi.ObjectReference, len(in.Subjects)) + for i := range in.Subjects { + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.Subjects[i], &out.Subjects[i], s); err != nil { + return err + } + } + } else { + out.Subjects = nil + } + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.RoleRef, &out.RoleRef, s); err != nil { + return err + } + return nil +} + +func autoconvert_v1beta3_RoleBindingList_To_api_RoleBindingList(in *v1beta3.RoleBindingList, out *api.RoleBindingList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1beta3.RoleBindingList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -537,14 +1017,18 @@ func convert_v1beta3_RoleBindingList_To_api_RoleBindingList(in *v1beta3.RoleBind return nil } -func convert_v1beta3_RoleList_To_api_RoleList(in *v1beta3.RoleList, out *api.RoleList, s conversion.Scope) error { +func convert_v1beta3_RoleBindingList_To_api_RoleBindingList(in *v1beta3.RoleBindingList, out *api.RoleBindingList, s conversion.Scope) error { + return autoconvert_v1beta3_RoleBindingList_To_api_RoleBindingList(in, out, s) +} + +func autoconvert_v1beta3_RoleList_To_api_RoleList(in *v1beta3.RoleList, out *api.RoleList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1beta3.RoleList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -560,11 +1044,28 @@ func convert_v1beta3_RoleList_To_api_RoleList(in *v1beta3.RoleList, out *api.Rol return nil } -func convert_v1beta3_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse(in *v1beta3.SubjectAccessReviewResponse, out *api.SubjectAccessReviewResponse, s conversion.Scope) error { +func convert_v1beta3_RoleList_To_api_RoleList(in *v1beta3.RoleList, out *api.RoleList, s conversion.Scope) error { + return autoconvert_v1beta3_RoleList_To_api_RoleList(in, out, s) +} + +func autoconvert_v1beta3_SubjectAccessReview_To_api_SubjectAccessReview(in *v1beta3.SubjectAccessReview, out *api.SubjectAccessReview, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*v1beta3.SubjectAccessReview))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + // in.AuthorizationAttributes has no peer in out + out.User = in.User + // in.GroupsSlice has no peer in out + return nil +} + +func autoconvert_v1beta3_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse(in *v1beta3.SubjectAccessReviewResponse, out *api.SubjectAccessReviewResponse, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*v1beta3.SubjectAccessReviewResponse))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Namespace = in.Namespace @@ -573,11 +1074,15 @@ func convert_v1beta3_SubjectAccessReviewResponse_To_api_SubjectAccessReviewRespo return nil } -func convert_api_Build_To_v1beta3_Build(in *buildapi.Build, out *apiv1beta3.Build, s conversion.Scope) error { +func convert_v1beta3_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse(in *v1beta3.SubjectAccessReviewResponse, out *api.SubjectAccessReviewResponse, s conversion.Scope) error { + return autoconvert_v1beta3_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse(in, out, s) +} + +func autoconvert_api_Build_To_v1beta3_Build(in *buildapi.Build, out *apiv1beta3.Build, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.Build))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -592,11 +1097,15 @@ func convert_api_Build_To_v1beta3_Build(in *buildapi.Build, out *apiv1beta3.Buil return nil } -func convert_api_BuildConfig_To_v1beta3_BuildConfig(in *buildapi.BuildConfig, out *apiv1beta3.BuildConfig, s conversion.Scope) error { +func convert_api_Build_To_v1beta3_Build(in *buildapi.Build, out *apiv1beta3.Build, s conversion.Scope) error { + return autoconvert_api_Build_To_v1beta3_Build(in, out, s) +} + +func autoconvert_api_BuildConfig_To_v1beta3_BuildConfig(in *buildapi.BuildConfig, out *apiv1beta3.BuildConfig, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildConfig))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -611,14 +1120,18 @@ func convert_api_BuildConfig_To_v1beta3_BuildConfig(in *buildapi.BuildConfig, ou return nil } -func convert_api_BuildConfigList_To_v1beta3_BuildConfigList(in *buildapi.BuildConfigList, out *apiv1beta3.BuildConfigList, s conversion.Scope) error { +func convert_api_BuildConfig_To_v1beta3_BuildConfig(in *buildapi.BuildConfig, out *apiv1beta3.BuildConfig, s conversion.Scope) error { + return autoconvert_api_BuildConfig_To_v1beta3_BuildConfig(in, out, s) +} + +func autoconvert_api_BuildConfigList_To_v1beta3_BuildConfigList(in *buildapi.BuildConfigList, out *apiv1beta3.BuildConfigList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildConfigList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -634,7 +1147,11 @@ func convert_api_BuildConfigList_To_v1beta3_BuildConfigList(in *buildapi.BuildCo return nil } -func convert_api_BuildConfigSpec_To_v1beta3_BuildConfigSpec(in *buildapi.BuildConfigSpec, out *apiv1beta3.BuildConfigSpec, s conversion.Scope) error { +func convert_api_BuildConfigList_To_v1beta3_BuildConfigList(in *buildapi.BuildConfigList, out *apiv1beta3.BuildConfigList, s conversion.Scope) error { + return autoconvert_api_BuildConfigList_To_v1beta3_BuildConfigList(in, out, s) +} + +func autoconvert_api_BuildConfigSpec_To_v1beta3_BuildConfigSpec(in *buildapi.BuildConfigSpec, out *apiv1beta3.BuildConfigSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildConfigSpec))(in) } @@ -654,7 +1171,11 @@ func convert_api_BuildConfigSpec_To_v1beta3_BuildConfigSpec(in *buildapi.BuildCo return nil } -func convert_api_BuildConfigStatus_To_v1beta3_BuildConfigStatus(in *buildapi.BuildConfigStatus, out *apiv1beta3.BuildConfigStatus, s conversion.Scope) error { +func convert_api_BuildConfigSpec_To_v1beta3_BuildConfigSpec(in *buildapi.BuildConfigSpec, out *apiv1beta3.BuildConfigSpec, s conversion.Scope) error { + return autoconvert_api_BuildConfigSpec_To_v1beta3_BuildConfigSpec(in, out, s) +} + +func autoconvert_api_BuildConfigStatus_To_v1beta3_BuildConfigStatus(in *buildapi.BuildConfigStatus, out *apiv1beta3.BuildConfigStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildConfigStatus))(in) } @@ -662,14 +1183,18 @@ func convert_api_BuildConfigStatus_To_v1beta3_BuildConfigStatus(in *buildapi.Bui return nil } -func convert_api_BuildList_To_v1beta3_BuildList(in *buildapi.BuildList, out *apiv1beta3.BuildList, s conversion.Scope) error { +func convert_api_BuildConfigStatus_To_v1beta3_BuildConfigStatus(in *buildapi.BuildConfigStatus, out *apiv1beta3.BuildConfigStatus, s conversion.Scope) error { + return autoconvert_api_BuildConfigStatus_To_v1beta3_BuildConfigStatus(in, out, s) +} + +func autoconvert_api_BuildList_To_v1beta3_BuildList(in *buildapi.BuildList, out *apiv1beta3.BuildList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -685,24 +1210,32 @@ func convert_api_BuildList_To_v1beta3_BuildList(in *buildapi.BuildList, out *api return nil } -func convert_api_BuildLog_To_v1beta3_BuildLog(in *buildapi.BuildLog, out *apiv1beta3.BuildLog, s conversion.Scope) error { +func convert_api_BuildList_To_v1beta3_BuildList(in *buildapi.BuildList, out *apiv1beta3.BuildList, s conversion.Scope) error { + return autoconvert_api_BuildList_To_v1beta3_BuildList(in, out, s) +} + +func autoconvert_api_BuildLog_To_v1beta3_BuildLog(in *buildapi.BuildLog, out *apiv1beta3.BuildLog, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildLog))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } return nil } -func convert_api_BuildLogOptions_To_v1beta3_BuildLogOptions(in *buildapi.BuildLogOptions, out *apiv1beta3.BuildLogOptions, s conversion.Scope) error { +func convert_api_BuildLog_To_v1beta3_BuildLog(in *buildapi.BuildLog, out *apiv1beta3.BuildLog, s conversion.Scope) error { + return autoconvert_api_BuildLog_To_v1beta3_BuildLog(in, out, s) +} + +func autoconvert_api_BuildLogOptions_To_v1beta3_BuildLogOptions(in *buildapi.BuildLogOptions, out *apiv1beta3.BuildLogOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildLogOptions))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Follow = in.Follow @@ -710,11 +1243,38 @@ func convert_api_BuildLogOptions_To_v1beta3_BuildLogOptions(in *buildapi.BuildLo return nil } -func convert_api_BuildRequest_To_v1beta3_BuildRequest(in *buildapi.BuildRequest, out *apiv1beta3.BuildRequest, s conversion.Scope) error { +func convert_api_BuildLogOptions_To_v1beta3_BuildLogOptions(in *buildapi.BuildLogOptions, out *apiv1beta3.BuildLogOptions, s conversion.Scope) error { + return autoconvert_api_BuildLogOptions_To_v1beta3_BuildLogOptions(in, out, s) +} + +func autoconvert_api_BuildOutput_To_v1beta3_BuildOutput(in *buildapi.BuildOutput, out *apiv1beta3.BuildOutput, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.BuildOutput))(in) + } + if in.To != nil { + out.To = new(pkgapiv1beta3.ObjectReference) + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(in.To, out.To, s); err != nil { + return err + } + } else { + out.To = nil + } + if in.PushSecret != nil { + out.PushSecret = new(pkgapiv1beta3.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in.PushSecret, out.PushSecret, s); err != nil { + return err + } + } else { + out.PushSecret = nil + } + return nil +} + +func autoconvert_api_BuildRequest_To_v1beta3_BuildRequest(in *buildapi.BuildRequest, out *apiv1beta3.BuildRequest, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildRequest))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -753,7 +1313,11 @@ func convert_api_BuildRequest_To_v1beta3_BuildRequest(in *buildapi.BuildRequest, return nil } -func convert_api_BuildSource_To_v1beta3_BuildSource(in *buildapi.BuildSource, out *apiv1beta3.BuildSource, s conversion.Scope) error { +func convert_api_BuildRequest_To_v1beta3_BuildRequest(in *buildapi.BuildRequest, out *apiv1beta3.BuildRequest, s conversion.Scope) error { + return autoconvert_api_BuildRequest_To_v1beta3_BuildRequest(in, out, s) +} + +func autoconvert_api_BuildSource_To_v1beta3_BuildSource(in *buildapi.BuildSource, out *apiv1beta3.BuildSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildSource))(in) } @@ -784,7 +1348,11 @@ func convert_api_BuildSource_To_v1beta3_BuildSource(in *buildapi.BuildSource, ou return nil } -func convert_api_BuildSpec_To_v1beta3_BuildSpec(in *buildapi.BuildSpec, out *apiv1beta3.BuildSpec, s conversion.Scope) error { +func convert_api_BuildSource_To_v1beta3_BuildSource(in *buildapi.BuildSource, out *apiv1beta3.BuildSource, s conversion.Scope) error { + return autoconvert_api_BuildSource_To_v1beta3_BuildSource(in, out, s) +} + +func autoconvert_api_BuildSpec_To_v1beta3_BuildSpec(in *buildapi.BuildSpec, out *apiv1beta3.BuildSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildSpec))(in) } @@ -818,7 +1386,11 @@ func convert_api_BuildSpec_To_v1beta3_BuildSpec(in *buildapi.BuildSpec, out *api return nil } -func convert_api_BuildStatus_To_v1beta3_BuildStatus(in *buildapi.BuildStatus, out *apiv1beta3.BuildStatus, s conversion.Scope) error { +func convert_api_BuildSpec_To_v1beta3_BuildSpec(in *buildapi.BuildSpec, out *apiv1beta3.BuildSpec, s conversion.Scope) error { + return autoconvert_api_BuildSpec_To_v1beta3_BuildSpec(in, out, s) +} + +func autoconvert_api_BuildStatus_To_v1beta3_BuildStatus(in *buildapi.BuildStatus, out *apiv1beta3.BuildStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildStatus))(in) } @@ -852,7 +1424,11 @@ func convert_api_BuildStatus_To_v1beta3_BuildStatus(in *buildapi.BuildStatus, ou return nil } -func convert_api_BuildStrategy_To_v1beta3_BuildStrategy(in *buildapi.BuildStrategy, out *apiv1beta3.BuildStrategy, s conversion.Scope) error { +func convert_api_BuildStatus_To_v1beta3_BuildStatus(in *buildapi.BuildStatus, out *apiv1beta3.BuildStatus, s conversion.Scope) error { + return autoconvert_api_BuildStatus_To_v1beta3_BuildStatus(in, out, s) +} + +func autoconvert_api_BuildStrategy_To_v1beta3_BuildStrategy(in *buildapi.BuildStrategy, out *apiv1beta3.BuildStrategy, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.BuildStrategy))(in) } @@ -881,60 +1457,218 @@ func convert_api_BuildStrategy_To_v1beta3_BuildStrategy(in *buildapi.BuildStrate return nil } -func convert_api_GitBuildSource_To_v1beta3_GitBuildSource(in *buildapi.GitBuildSource, out *apiv1beta3.GitBuildSource, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*buildapi.GitBuildSource))(in) - } - out.URI = in.URI - out.Ref = in.Ref - out.HTTPProxy = in.HTTPProxy - out.HTTPSProxy = in.HTTPSProxy - return nil +func convert_api_BuildStrategy_To_v1beta3_BuildStrategy(in *buildapi.BuildStrategy, out *apiv1beta3.BuildStrategy, s conversion.Scope) error { + return autoconvert_api_BuildStrategy_To_v1beta3_BuildStrategy(in, out, s) } -func convert_api_GitSourceRevision_To_v1beta3_GitSourceRevision(in *buildapi.GitSourceRevision, out *apiv1beta3.GitSourceRevision, s conversion.Scope) error { +func autoconvert_api_BuildTriggerPolicy_To_v1beta3_BuildTriggerPolicy(in *buildapi.BuildTriggerPolicy, out *apiv1beta3.BuildTriggerPolicy, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*buildapi.GitSourceRevision))(in) - } - out.Commit = in.Commit - if err := convert_api_SourceControlUser_To_v1beta3_SourceControlUser(&in.Author, &out.Author, s); err != nil { - return err + defaulting.(func(*buildapi.BuildTriggerPolicy))(in) } - if err := convert_api_SourceControlUser_To_v1beta3_SourceControlUser(&in.Committer, &out.Committer, s); err != nil { - return err + out.Type = apiv1beta3.BuildTriggerType(in.Type) + if in.GitHubWebHook != nil { + out.GitHubWebHook = new(apiv1beta3.WebHookTrigger) + if err := convert_api_WebHookTrigger_To_v1beta3_WebHookTrigger(in.GitHubWebHook, out.GitHubWebHook, s); err != nil { + return err + } + } else { + out.GitHubWebHook = nil } - out.Message = in.Message - return nil -} - -func convert_api_ImageChangeTrigger_To_v1beta3_ImageChangeTrigger(in *buildapi.ImageChangeTrigger, out *apiv1beta3.ImageChangeTrigger, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*buildapi.ImageChangeTrigger))(in) + if in.GenericWebHook != nil { + out.GenericWebHook = new(apiv1beta3.WebHookTrigger) + if err := convert_api_WebHookTrigger_To_v1beta3_WebHookTrigger(in.GenericWebHook, out.GenericWebHook, s); err != nil { + return err + } + } else { + out.GenericWebHook = nil } - out.LastTriggeredImageID = in.LastTriggeredImageID - if in.From != nil { - out.From = new(pkgapiv1beta3.ObjectReference) - if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(in.From, out.From, s); err != nil { + if in.ImageChange != nil { + out.ImageChange = new(apiv1beta3.ImageChangeTrigger) + if err := convert_api_ImageChangeTrigger_To_v1beta3_ImageChangeTrigger(in.ImageChange, out.ImageChange, s); err != nil { return err } } else { - out.From = nil + out.ImageChange = nil } return nil } -func convert_api_SecretSpec_To_v1beta3_SecretSpec(in *buildapi.SecretSpec, out *apiv1beta3.SecretSpec, s conversion.Scope) error { +func autoconvert_api_CustomBuildStrategy_To_v1beta3_CustomBuildStrategy(in *buildapi.CustomBuildStrategy, out *apiv1beta3.CustomBuildStrategy, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*buildapi.SecretSpec))(in) + defaulting.(func(*buildapi.CustomBuildStrategy))(in) } - if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(&in.SecretSource, &out.SecretSource, s); err != nil { + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.From, &out.From, s); err != nil { return err } - out.MountPath = in.MountPath - return nil -} + if in.PullSecret != nil { + out.PullSecret = new(pkgapiv1beta3.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil + } + if in.Env != nil { + out.Env = make([]pkgapiv1beta3.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_api_EnvVar_To_v1beta3_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + out.ExposeDockerSocket = in.ExposeDockerSocket + out.ForcePull = in.ForcePull + if in.Secrets != nil { + out.Secrets = make([]apiv1beta3.SecretSpec, len(in.Secrets)) + for i := range in.Secrets { + if err := convert_api_SecretSpec_To_v1beta3_SecretSpec(&in.Secrets[i], &out.Secrets[i], s); err != nil { + return err + } + } + } else { + out.Secrets = nil + } + return nil +} -func convert_api_SourceControlUser_To_v1beta3_SourceControlUser(in *buildapi.SourceControlUser, out *apiv1beta3.SourceControlUser, s conversion.Scope) error { +func autoconvert_api_DockerBuildStrategy_To_v1beta3_DockerBuildStrategy(in *buildapi.DockerBuildStrategy, out *apiv1beta3.DockerBuildStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.DockerBuildStrategy))(in) + } + if in.From != nil { + out.From = new(pkgapiv1beta3.ObjectReference) + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(in.From, out.From, s); err != nil { + return err + } + } else { + out.From = nil + } + if in.PullSecret != nil { + out.PullSecret = new(pkgapiv1beta3.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil + } + out.NoCache = in.NoCache + if in.Env != nil { + out.Env = make([]pkgapiv1beta3.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_api_EnvVar_To_v1beta3_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + out.ForcePull = in.ForcePull + return nil +} + +func autoconvert_api_GitBuildSource_To_v1beta3_GitBuildSource(in *buildapi.GitBuildSource, out *apiv1beta3.GitBuildSource, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.GitBuildSource))(in) + } + out.URI = in.URI + out.Ref = in.Ref + out.HTTPProxy = in.HTTPProxy + out.HTTPSProxy = in.HTTPSProxy + return nil +} + +func convert_api_GitBuildSource_To_v1beta3_GitBuildSource(in *buildapi.GitBuildSource, out *apiv1beta3.GitBuildSource, s conversion.Scope) error { + return autoconvert_api_GitBuildSource_To_v1beta3_GitBuildSource(in, out, s) +} + +func autoconvert_api_GitSourceRevision_To_v1beta3_GitSourceRevision(in *buildapi.GitSourceRevision, out *apiv1beta3.GitSourceRevision, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.GitSourceRevision))(in) + } + out.Commit = in.Commit + if err := convert_api_SourceControlUser_To_v1beta3_SourceControlUser(&in.Author, &out.Author, s); err != nil { + return err + } + if err := convert_api_SourceControlUser_To_v1beta3_SourceControlUser(&in.Committer, &out.Committer, s); err != nil { + return err + } + out.Message = in.Message + return nil +} + +func convert_api_GitSourceRevision_To_v1beta3_GitSourceRevision(in *buildapi.GitSourceRevision, out *apiv1beta3.GitSourceRevision, s conversion.Scope) error { + return autoconvert_api_GitSourceRevision_To_v1beta3_GitSourceRevision(in, out, s) +} + +func autoconvert_api_ImageChangeTrigger_To_v1beta3_ImageChangeTrigger(in *buildapi.ImageChangeTrigger, out *apiv1beta3.ImageChangeTrigger, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.ImageChangeTrigger))(in) + } + out.LastTriggeredImageID = in.LastTriggeredImageID + if in.From != nil { + out.From = new(pkgapiv1beta3.ObjectReference) + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(in.From, out.From, s); err != nil { + return err + } + } else { + out.From = nil + } + return nil +} + +func convert_api_ImageChangeTrigger_To_v1beta3_ImageChangeTrigger(in *buildapi.ImageChangeTrigger, out *apiv1beta3.ImageChangeTrigger, s conversion.Scope) error { + return autoconvert_api_ImageChangeTrigger_To_v1beta3_ImageChangeTrigger(in, out, s) +} + +func autoconvert_api_SecretSpec_To_v1beta3_SecretSpec(in *buildapi.SecretSpec, out *apiv1beta3.SecretSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.SecretSpec))(in) + } + if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(&in.SecretSource, &out.SecretSource, s); err != nil { + return err + } + out.MountPath = in.MountPath + return nil +} + +func convert_api_SecretSpec_To_v1beta3_SecretSpec(in *buildapi.SecretSpec, out *apiv1beta3.SecretSpec, s conversion.Scope) error { + return autoconvert_api_SecretSpec_To_v1beta3_SecretSpec(in, out, s) +} + +func autoconvert_api_SourceBuildStrategy_To_v1beta3_SourceBuildStrategy(in *buildapi.SourceBuildStrategy, out *apiv1beta3.SourceBuildStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*buildapi.SourceBuildStrategy))(in) + } + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.From, &out.From, s); err != nil { + return err + } + if in.PullSecret != nil { + out.PullSecret = new(pkgapiv1beta3.LocalObjectReference) + if err := convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil + } + if in.Env != nil { + out.Env = make([]pkgapiv1beta3.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_api_EnvVar_To_v1beta3_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + out.Scripts = in.Scripts + out.Incremental = in.Incremental + out.ForcePull = in.ForcePull + return nil +} + +func autoconvert_api_SourceControlUser_To_v1beta3_SourceControlUser(in *buildapi.SourceControlUser, out *apiv1beta3.SourceControlUser, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.SourceControlUser))(in) } @@ -943,7 +1677,11 @@ func convert_api_SourceControlUser_To_v1beta3_SourceControlUser(in *buildapi.Sou return nil } -func convert_api_SourceRevision_To_v1beta3_SourceRevision(in *buildapi.SourceRevision, out *apiv1beta3.SourceRevision, s conversion.Scope) error { +func convert_api_SourceControlUser_To_v1beta3_SourceControlUser(in *buildapi.SourceControlUser, out *apiv1beta3.SourceControlUser, s conversion.Scope) error { + return autoconvert_api_SourceControlUser_To_v1beta3_SourceControlUser(in, out, s) +} + +func autoconvert_api_SourceRevision_To_v1beta3_SourceRevision(in *buildapi.SourceRevision, out *apiv1beta3.SourceRevision, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.SourceRevision))(in) } @@ -959,7 +1697,11 @@ func convert_api_SourceRevision_To_v1beta3_SourceRevision(in *buildapi.SourceRev return nil } -func convert_api_WebHookTrigger_To_v1beta3_WebHookTrigger(in *buildapi.WebHookTrigger, out *apiv1beta3.WebHookTrigger, s conversion.Scope) error { +func convert_api_SourceRevision_To_v1beta3_SourceRevision(in *buildapi.SourceRevision, out *apiv1beta3.SourceRevision, s conversion.Scope) error { + return autoconvert_api_SourceRevision_To_v1beta3_SourceRevision(in, out, s) +} + +func autoconvert_api_WebHookTrigger_To_v1beta3_WebHookTrigger(in *buildapi.WebHookTrigger, out *apiv1beta3.WebHookTrigger, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*buildapi.WebHookTrigger))(in) } @@ -967,11 +1709,15 @@ func convert_api_WebHookTrigger_To_v1beta3_WebHookTrigger(in *buildapi.WebHookTr return nil } -func convert_v1beta3_Build_To_api_Build(in *apiv1beta3.Build, out *buildapi.Build, s conversion.Scope) error { +func convert_api_WebHookTrigger_To_v1beta3_WebHookTrigger(in *buildapi.WebHookTrigger, out *apiv1beta3.WebHookTrigger, s conversion.Scope) error { + return autoconvert_api_WebHookTrigger_To_v1beta3_WebHookTrigger(in, out, s) +} + +func autoconvert_v1beta3_Build_To_api_Build(in *apiv1beta3.Build, out *buildapi.Build, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.Build))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -986,11 +1732,15 @@ func convert_v1beta3_Build_To_api_Build(in *apiv1beta3.Build, out *buildapi.Buil return nil } -func convert_v1beta3_BuildConfig_To_api_BuildConfig(in *apiv1beta3.BuildConfig, out *buildapi.BuildConfig, s conversion.Scope) error { +func convert_v1beta3_Build_To_api_Build(in *apiv1beta3.Build, out *buildapi.Build, s conversion.Scope) error { + return autoconvert_v1beta3_Build_To_api_Build(in, out, s) +} + +func autoconvert_v1beta3_BuildConfig_To_api_BuildConfig(in *apiv1beta3.BuildConfig, out *buildapi.BuildConfig, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildConfig))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1005,14 +1755,18 @@ func convert_v1beta3_BuildConfig_To_api_BuildConfig(in *apiv1beta3.BuildConfig, return nil } -func convert_v1beta3_BuildConfigList_To_api_BuildConfigList(in *apiv1beta3.BuildConfigList, out *buildapi.BuildConfigList, s conversion.Scope) error { +func convert_v1beta3_BuildConfig_To_api_BuildConfig(in *apiv1beta3.BuildConfig, out *buildapi.BuildConfig, s conversion.Scope) error { + return autoconvert_v1beta3_BuildConfig_To_api_BuildConfig(in, out, s) +} + +func autoconvert_v1beta3_BuildConfigList_To_api_BuildConfigList(in *apiv1beta3.BuildConfigList, out *buildapi.BuildConfigList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildConfigList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1028,7 +1782,11 @@ func convert_v1beta3_BuildConfigList_To_api_BuildConfigList(in *apiv1beta3.Build return nil } -func convert_v1beta3_BuildConfigSpec_To_api_BuildConfigSpec(in *apiv1beta3.BuildConfigSpec, out *buildapi.BuildConfigSpec, s conversion.Scope) error { +func convert_v1beta3_BuildConfigList_To_api_BuildConfigList(in *apiv1beta3.BuildConfigList, out *buildapi.BuildConfigList, s conversion.Scope) error { + return autoconvert_v1beta3_BuildConfigList_To_api_BuildConfigList(in, out, s) +} + +func autoconvert_v1beta3_BuildConfigSpec_To_api_BuildConfigSpec(in *apiv1beta3.BuildConfigSpec, out *buildapi.BuildConfigSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildConfigSpec))(in) } @@ -1048,7 +1806,11 @@ func convert_v1beta3_BuildConfigSpec_To_api_BuildConfigSpec(in *apiv1beta3.Build return nil } -func convert_v1beta3_BuildConfigStatus_To_api_BuildConfigStatus(in *apiv1beta3.BuildConfigStatus, out *buildapi.BuildConfigStatus, s conversion.Scope) error { +func convert_v1beta3_BuildConfigSpec_To_api_BuildConfigSpec(in *apiv1beta3.BuildConfigSpec, out *buildapi.BuildConfigSpec, s conversion.Scope) error { + return autoconvert_v1beta3_BuildConfigSpec_To_api_BuildConfigSpec(in, out, s) +} + +func autoconvert_v1beta3_BuildConfigStatus_To_api_BuildConfigStatus(in *apiv1beta3.BuildConfigStatus, out *buildapi.BuildConfigStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildConfigStatus))(in) } @@ -1056,14 +1818,18 @@ func convert_v1beta3_BuildConfigStatus_To_api_BuildConfigStatus(in *apiv1beta3.B return nil } -func convert_v1beta3_BuildList_To_api_BuildList(in *apiv1beta3.BuildList, out *buildapi.BuildList, s conversion.Scope) error { +func convert_v1beta3_BuildConfigStatus_To_api_BuildConfigStatus(in *apiv1beta3.BuildConfigStatus, out *buildapi.BuildConfigStatus, s conversion.Scope) error { + return autoconvert_v1beta3_BuildConfigStatus_To_api_BuildConfigStatus(in, out, s) +} + +func autoconvert_v1beta3_BuildList_To_api_BuildList(in *apiv1beta3.BuildList, out *buildapi.BuildList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1079,24 +1845,32 @@ func convert_v1beta3_BuildList_To_api_BuildList(in *apiv1beta3.BuildList, out *b return nil } -func convert_v1beta3_BuildLog_To_api_BuildLog(in *apiv1beta3.BuildLog, out *buildapi.BuildLog, s conversion.Scope) error { +func convert_v1beta3_BuildList_To_api_BuildList(in *apiv1beta3.BuildList, out *buildapi.BuildList, s conversion.Scope) error { + return autoconvert_v1beta3_BuildList_To_api_BuildList(in, out, s) +} + +func autoconvert_v1beta3_BuildLog_To_api_BuildLog(in *apiv1beta3.BuildLog, out *buildapi.BuildLog, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildLog))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } return nil } -func convert_v1beta3_BuildLogOptions_To_api_BuildLogOptions(in *apiv1beta3.BuildLogOptions, out *buildapi.BuildLogOptions, s conversion.Scope) error { +func convert_v1beta3_BuildLog_To_api_BuildLog(in *apiv1beta3.BuildLog, out *buildapi.BuildLog, s conversion.Scope) error { + return autoconvert_v1beta3_BuildLog_To_api_BuildLog(in, out, s) +} + +func autoconvert_v1beta3_BuildLogOptions_To_api_BuildLogOptions(in *apiv1beta3.BuildLogOptions, out *buildapi.BuildLogOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildLogOptions))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } out.Follow = in.Follow @@ -1104,11 +1878,38 @@ func convert_v1beta3_BuildLogOptions_To_api_BuildLogOptions(in *apiv1beta3.Build return nil } -func convert_v1beta3_BuildRequest_To_api_BuildRequest(in *apiv1beta3.BuildRequest, out *buildapi.BuildRequest, s conversion.Scope) error { +func convert_v1beta3_BuildLogOptions_To_api_BuildLogOptions(in *apiv1beta3.BuildLogOptions, out *buildapi.BuildLogOptions, s conversion.Scope) error { + return autoconvert_v1beta3_BuildLogOptions_To_api_BuildLogOptions(in, out, s) +} + +func autoconvert_v1beta3_BuildOutput_To_api_BuildOutput(in *apiv1beta3.BuildOutput, out *buildapi.BuildOutput, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*apiv1beta3.BuildOutput))(in) + } + if in.To != nil { + out.To = new(pkgapi.ObjectReference) + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(in.To, out.To, s); err != nil { + return err + } + } else { + out.To = nil + } + if in.PushSecret != nil { + out.PushSecret = new(pkgapi.LocalObjectReference) + if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in.PushSecret, out.PushSecret, s); err != nil { + return err + } + } else { + out.PushSecret = nil + } + return nil +} + +func autoconvert_v1beta3_BuildRequest_To_api_BuildRequest(in *apiv1beta3.BuildRequest, out *buildapi.BuildRequest, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildRequest))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1147,7 +1948,11 @@ func convert_v1beta3_BuildRequest_To_api_BuildRequest(in *apiv1beta3.BuildReques return nil } -func convert_v1beta3_BuildSource_To_api_BuildSource(in *apiv1beta3.BuildSource, out *buildapi.BuildSource, s conversion.Scope) error { +func convert_v1beta3_BuildRequest_To_api_BuildRequest(in *apiv1beta3.BuildRequest, out *buildapi.BuildRequest, s conversion.Scope) error { + return autoconvert_v1beta3_BuildRequest_To_api_BuildRequest(in, out, s) +} + +func autoconvert_v1beta3_BuildSource_To_api_BuildSource(in *apiv1beta3.BuildSource, out *buildapi.BuildSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildSource))(in) } @@ -1178,7 +1983,11 @@ func convert_v1beta3_BuildSource_To_api_BuildSource(in *apiv1beta3.BuildSource, return nil } -func convert_v1beta3_BuildSpec_To_api_BuildSpec(in *apiv1beta3.BuildSpec, out *buildapi.BuildSpec, s conversion.Scope) error { +func convert_v1beta3_BuildSource_To_api_BuildSource(in *apiv1beta3.BuildSource, out *buildapi.BuildSource, s conversion.Scope) error { + return autoconvert_v1beta3_BuildSource_To_api_BuildSource(in, out, s) +} + +func autoconvert_v1beta3_BuildSpec_To_api_BuildSpec(in *apiv1beta3.BuildSpec, out *buildapi.BuildSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildSpec))(in) } @@ -1212,7 +2021,11 @@ func convert_v1beta3_BuildSpec_To_api_BuildSpec(in *apiv1beta3.BuildSpec, out *b return nil } -func convert_v1beta3_BuildStatus_To_api_BuildStatus(in *apiv1beta3.BuildStatus, out *buildapi.BuildStatus, s conversion.Scope) error { +func convert_v1beta3_BuildSpec_To_api_BuildSpec(in *apiv1beta3.BuildSpec, out *buildapi.BuildSpec, s conversion.Scope) error { + return autoconvert_v1beta3_BuildSpec_To_api_BuildSpec(in, out, s) +} + +func autoconvert_v1beta3_BuildStatus_To_api_BuildStatus(in *apiv1beta3.BuildStatus, out *buildapi.BuildStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildStatus))(in) } @@ -1246,7 +2059,11 @@ func convert_v1beta3_BuildStatus_To_api_BuildStatus(in *apiv1beta3.BuildStatus, return nil } -func convert_v1beta3_BuildStrategy_To_api_BuildStrategy(in *apiv1beta3.BuildStrategy, out *buildapi.BuildStrategy, s conversion.Scope) error { +func convert_v1beta3_BuildStatus_To_api_BuildStatus(in *apiv1beta3.BuildStatus, out *buildapi.BuildStatus, s conversion.Scope) error { + return autoconvert_v1beta3_BuildStatus_To_api_BuildStatus(in, out, s) +} + +func autoconvert_v1beta3_BuildStrategy_To_api_BuildStrategy(in *apiv1beta3.BuildStrategy, out *buildapi.BuildStrategy, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.BuildStrategy))(in) } @@ -1275,7 +2092,118 @@ func convert_v1beta3_BuildStrategy_To_api_BuildStrategy(in *apiv1beta3.BuildStra return nil } -func convert_v1beta3_GitBuildSource_To_api_GitBuildSource(in *apiv1beta3.GitBuildSource, out *buildapi.GitBuildSource, s conversion.Scope) error { +func convert_v1beta3_BuildStrategy_To_api_BuildStrategy(in *apiv1beta3.BuildStrategy, out *buildapi.BuildStrategy, s conversion.Scope) error { + return autoconvert_v1beta3_BuildStrategy_To_api_BuildStrategy(in, out, s) +} + +func autoconvert_v1beta3_BuildTriggerPolicy_To_api_BuildTriggerPolicy(in *apiv1beta3.BuildTriggerPolicy, out *buildapi.BuildTriggerPolicy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*apiv1beta3.BuildTriggerPolicy))(in) + } + out.Type = buildapi.BuildTriggerType(in.Type) + if in.GitHubWebHook != nil { + out.GitHubWebHook = new(buildapi.WebHookTrigger) + if err := convert_v1beta3_WebHookTrigger_To_api_WebHookTrigger(in.GitHubWebHook, out.GitHubWebHook, s); err != nil { + return err + } + } else { + out.GitHubWebHook = nil + } + if in.GenericWebHook != nil { + out.GenericWebHook = new(buildapi.WebHookTrigger) + if err := convert_v1beta3_WebHookTrigger_To_api_WebHookTrigger(in.GenericWebHook, out.GenericWebHook, s); err != nil { + return err + } + } else { + out.GenericWebHook = nil + } + if in.ImageChange != nil { + out.ImageChange = new(buildapi.ImageChangeTrigger) + if err := convert_v1beta3_ImageChangeTrigger_To_api_ImageChangeTrigger(in.ImageChange, out.ImageChange, s); err != nil { + return err + } + } else { + out.ImageChange = nil + } + return nil +} + +func autoconvert_v1beta3_CustomBuildStrategy_To_api_CustomBuildStrategy(in *apiv1beta3.CustomBuildStrategy, out *buildapi.CustomBuildStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*apiv1beta3.CustomBuildStrategy))(in) + } + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.From, &out.From, s); err != nil { + return err + } + if in.PullSecret != nil { + out.PullSecret = new(pkgapi.LocalObjectReference) + if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil + } + if in.Env != nil { + out.Env = make([]pkgapi.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_v1beta3_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + out.ExposeDockerSocket = in.ExposeDockerSocket + out.ForcePull = in.ForcePull + if in.Secrets != nil { + out.Secrets = make([]buildapi.SecretSpec, len(in.Secrets)) + for i := range in.Secrets { + if err := convert_v1beta3_SecretSpec_To_api_SecretSpec(&in.Secrets[i], &out.Secrets[i], s); err != nil { + return err + } + } + } else { + out.Secrets = nil + } + return nil +} + +func autoconvert_v1beta3_DockerBuildStrategy_To_api_DockerBuildStrategy(in *apiv1beta3.DockerBuildStrategy, out *buildapi.DockerBuildStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*apiv1beta3.DockerBuildStrategy))(in) + } + if in.From != nil { + out.From = new(pkgapi.ObjectReference) + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(in.From, out.From, s); err != nil { + return err + } + } else { + out.From = nil + } + if in.PullSecret != nil { + out.PullSecret = new(pkgapi.LocalObjectReference) + if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil + } + out.NoCache = in.NoCache + if in.Env != nil { + out.Env = make([]pkgapi.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_v1beta3_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + out.ForcePull = in.ForcePull + return nil +} + +func autoconvert_v1beta3_GitBuildSource_To_api_GitBuildSource(in *apiv1beta3.GitBuildSource, out *buildapi.GitBuildSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.GitBuildSource))(in) } @@ -1286,7 +2214,11 @@ func convert_v1beta3_GitBuildSource_To_api_GitBuildSource(in *apiv1beta3.GitBuil return nil } -func convert_v1beta3_GitSourceRevision_To_api_GitSourceRevision(in *apiv1beta3.GitSourceRevision, out *buildapi.GitSourceRevision, s conversion.Scope) error { +func convert_v1beta3_GitBuildSource_To_api_GitBuildSource(in *apiv1beta3.GitBuildSource, out *buildapi.GitBuildSource, s conversion.Scope) error { + return autoconvert_v1beta3_GitBuildSource_To_api_GitBuildSource(in, out, s) +} + +func autoconvert_v1beta3_GitSourceRevision_To_api_GitSourceRevision(in *apiv1beta3.GitSourceRevision, out *buildapi.GitSourceRevision, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.GitSourceRevision))(in) } @@ -1301,7 +2233,11 @@ func convert_v1beta3_GitSourceRevision_To_api_GitSourceRevision(in *apiv1beta3.G return nil } -func convert_v1beta3_ImageChangeTrigger_To_api_ImageChangeTrigger(in *apiv1beta3.ImageChangeTrigger, out *buildapi.ImageChangeTrigger, s conversion.Scope) error { +func convert_v1beta3_GitSourceRevision_To_api_GitSourceRevision(in *apiv1beta3.GitSourceRevision, out *buildapi.GitSourceRevision, s conversion.Scope) error { + return autoconvert_v1beta3_GitSourceRevision_To_api_GitSourceRevision(in, out, s) +} + +func autoconvert_v1beta3_ImageChangeTrigger_To_api_ImageChangeTrigger(in *apiv1beta3.ImageChangeTrigger, out *buildapi.ImageChangeTrigger, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.ImageChangeTrigger))(in) } @@ -1317,7 +2253,11 @@ func convert_v1beta3_ImageChangeTrigger_To_api_ImageChangeTrigger(in *apiv1beta3 return nil } -func convert_v1beta3_SecretSpec_To_api_SecretSpec(in *apiv1beta3.SecretSpec, out *buildapi.SecretSpec, s conversion.Scope) error { +func convert_v1beta3_ImageChangeTrigger_To_api_ImageChangeTrigger(in *apiv1beta3.ImageChangeTrigger, out *buildapi.ImageChangeTrigger, s conversion.Scope) error { + return autoconvert_v1beta3_ImageChangeTrigger_To_api_ImageChangeTrigger(in, out, s) +} + +func autoconvert_v1beta3_SecretSpec_To_api_SecretSpec(in *apiv1beta3.SecretSpec, out *buildapi.SecretSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.SecretSpec))(in) } @@ -1328,7 +2268,42 @@ func convert_v1beta3_SecretSpec_To_api_SecretSpec(in *apiv1beta3.SecretSpec, out return nil } -func convert_v1beta3_SourceControlUser_To_api_SourceControlUser(in *apiv1beta3.SourceControlUser, out *buildapi.SourceControlUser, s conversion.Scope) error { +func convert_v1beta3_SecretSpec_To_api_SecretSpec(in *apiv1beta3.SecretSpec, out *buildapi.SecretSpec, s conversion.Scope) error { + return autoconvert_v1beta3_SecretSpec_To_api_SecretSpec(in, out, s) +} + +func autoconvert_v1beta3_SourceBuildStrategy_To_api_SourceBuildStrategy(in *apiv1beta3.SourceBuildStrategy, out *buildapi.SourceBuildStrategy, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*apiv1beta3.SourceBuildStrategy))(in) + } + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.From, &out.From, s); err != nil { + return err + } + if in.PullSecret != nil { + out.PullSecret = new(pkgapi.LocalObjectReference) + if err := convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in.PullSecret, out.PullSecret, s); err != nil { + return err + } + } else { + out.PullSecret = nil + } + if in.Env != nil { + out.Env = make([]pkgapi.EnvVar, len(in.Env)) + for i := range in.Env { + if err := convert_v1beta3_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { + return err + } + } + } else { + out.Env = nil + } + out.Scripts = in.Scripts + out.Incremental = in.Incremental + out.ForcePull = in.ForcePull + return nil +} + +func autoconvert_v1beta3_SourceControlUser_To_api_SourceControlUser(in *apiv1beta3.SourceControlUser, out *buildapi.SourceControlUser, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.SourceControlUser))(in) } @@ -1337,7 +2312,11 @@ func convert_v1beta3_SourceControlUser_To_api_SourceControlUser(in *apiv1beta3.S return nil } -func convert_v1beta3_SourceRevision_To_api_SourceRevision(in *apiv1beta3.SourceRevision, out *buildapi.SourceRevision, s conversion.Scope) error { +func convert_v1beta3_SourceControlUser_To_api_SourceControlUser(in *apiv1beta3.SourceControlUser, out *buildapi.SourceControlUser, s conversion.Scope) error { + return autoconvert_v1beta3_SourceControlUser_To_api_SourceControlUser(in, out, s) +} + +func autoconvert_v1beta3_SourceRevision_To_api_SourceRevision(in *apiv1beta3.SourceRevision, out *buildapi.SourceRevision, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.SourceRevision))(in) } @@ -1353,26 +2332,271 @@ func convert_v1beta3_SourceRevision_To_api_SourceRevision(in *apiv1beta3.SourceR return nil } -func convert_v1beta3_WebHookTrigger_To_api_WebHookTrigger(in *apiv1beta3.WebHookTrigger, out *buildapi.WebHookTrigger, s conversion.Scope) error { +func convert_v1beta3_SourceRevision_To_api_SourceRevision(in *apiv1beta3.SourceRevision, out *buildapi.SourceRevision, s conversion.Scope) error { + return autoconvert_v1beta3_SourceRevision_To_api_SourceRevision(in, out, s) +} + +func autoconvert_v1beta3_WebHookTrigger_To_api_WebHookTrigger(in *apiv1beta3.WebHookTrigger, out *buildapi.WebHookTrigger, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*apiv1beta3.WebHookTrigger))(in) } - out.Secret = in.Secret + out.Secret = in.Secret + return nil +} + +func convert_v1beta3_WebHookTrigger_To_api_WebHookTrigger(in *apiv1beta3.WebHookTrigger, out *buildapi.WebHookTrigger, s conversion.Scope) error { + return autoconvert_v1beta3_WebHookTrigger_To_api_WebHookTrigger(in, out, s) +} + +func autoconvert_api_DeploymentConfig_To_v1beta3_DeploymentConfig(in *deployapi.DeploymentConfig, out *deployapiv1beta3.DeploymentConfig, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*deployapi.DeploymentConfig))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + // in.Triggers has no peer in out + // in.Template has no peer in out + // in.LatestVersion has no peer in out + // in.Details has no peer in out + return nil +} + +func autoconvert_api_DeploymentConfigList_To_v1beta3_DeploymentConfigList(in *deployapi.DeploymentConfigList, out *deployapiv1beta3.DeploymentConfigList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*deployapi.DeploymentConfigList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]deployapiv1beta3.DeploymentConfig, len(in.Items)) + for i := range in.Items { + if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_DeploymentConfigList_To_v1beta3_DeploymentConfigList(in *deployapi.DeploymentConfigList, out *deployapiv1beta3.DeploymentConfigList, s conversion.Scope) error { + return autoconvert_api_DeploymentConfigList_To_v1beta3_DeploymentConfigList(in, out, s) +} + +func autoconvert_api_DeploymentConfigRollback_To_v1beta3_DeploymentConfigRollback(in *deployapi.DeploymentConfigRollback, out *deployapiv1beta3.DeploymentConfigRollback, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*deployapi.DeploymentConfigRollback))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_DeploymentConfigRollbackSpec_To_v1beta3_DeploymentConfigRollbackSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_api_DeploymentConfigRollback_To_v1beta3_DeploymentConfigRollback(in *deployapi.DeploymentConfigRollback, out *deployapiv1beta3.DeploymentConfigRollback, s conversion.Scope) error { + return autoconvert_api_DeploymentConfigRollback_To_v1beta3_DeploymentConfigRollback(in, out, s) +} + +func autoconvert_api_DeploymentConfigRollbackSpec_To_v1beta3_DeploymentConfigRollbackSpec(in *deployapi.DeploymentConfigRollbackSpec, out *deployapiv1beta3.DeploymentConfigRollbackSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*deployapi.DeploymentConfigRollbackSpec))(in) + } + if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.From, &out.From, s); err != nil { + return err + } + out.IncludeTriggers = in.IncludeTriggers + out.IncludeTemplate = in.IncludeTemplate + out.IncludeReplicationMeta = in.IncludeReplicationMeta + out.IncludeStrategy = in.IncludeStrategy + return nil +} + +func convert_api_DeploymentConfigRollbackSpec_To_v1beta3_DeploymentConfigRollbackSpec(in *deployapi.DeploymentConfigRollbackSpec, out *deployapiv1beta3.DeploymentConfigRollbackSpec, s conversion.Scope) error { + return autoconvert_api_DeploymentConfigRollbackSpec_To_v1beta3_DeploymentConfigRollbackSpec(in, out, s) +} + +func autoconvert_v1beta3_DeploymentConfig_To_api_DeploymentConfig(in *deployapiv1beta3.DeploymentConfig, out *deployapi.DeploymentConfig, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*deployapiv1beta3.DeploymentConfig))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + // in.Spec has no peer in out + // in.Status has no peer in out + return nil +} + +func autoconvert_v1beta3_DeploymentConfigList_To_api_DeploymentConfigList(in *deployapiv1beta3.DeploymentConfigList, out *deployapi.DeploymentConfigList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*deployapiv1beta3.DeploymentConfigList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]deployapi.DeploymentConfig, len(in.Items)) + for i := range in.Items { + if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_v1beta3_DeploymentConfigList_To_api_DeploymentConfigList(in *deployapiv1beta3.DeploymentConfigList, out *deployapi.DeploymentConfigList, s conversion.Scope) error { + return autoconvert_v1beta3_DeploymentConfigList_To_api_DeploymentConfigList(in, out, s) +} + +func autoconvert_v1beta3_DeploymentConfigRollback_To_api_DeploymentConfigRollback(in *deployapiv1beta3.DeploymentConfigRollback, out *deployapi.DeploymentConfigRollback, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*deployapiv1beta3.DeploymentConfigRollback))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1beta3_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func convert_v1beta3_DeploymentConfigRollback_To_api_DeploymentConfigRollback(in *deployapiv1beta3.DeploymentConfigRollback, out *deployapi.DeploymentConfigRollback, s conversion.Scope) error { + return autoconvert_v1beta3_DeploymentConfigRollback_To_api_DeploymentConfigRollback(in, out, s) +} + +func autoconvert_v1beta3_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec(in *deployapiv1beta3.DeploymentConfigRollbackSpec, out *deployapi.DeploymentConfigRollbackSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*deployapiv1beta3.DeploymentConfigRollbackSpec))(in) + } + if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.From, &out.From, s); err != nil { + return err + } + out.IncludeTriggers = in.IncludeTriggers + out.IncludeTemplate = in.IncludeTemplate + out.IncludeReplicationMeta = in.IncludeReplicationMeta + out.IncludeStrategy = in.IncludeStrategy + return nil +} + +func convert_v1beta3_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec(in *deployapiv1beta3.DeploymentConfigRollbackSpec, out *deployapi.DeploymentConfigRollbackSpec, s conversion.Scope) error { + return autoconvert_v1beta3_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec(in, out, s) +} + +func autoconvert_api_Image_To_v1beta3_Image(in *imageapi.Image, out *imageapiv1beta3.Image, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapi.Image))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.DockerImageReference = in.DockerImageReference + if err := s.Convert(&in.DockerImageMetadata, &out.DockerImageMetadata, 0); err != nil { + return err + } + out.DockerImageMetadataVersion = in.DockerImageMetadataVersion + out.DockerImageManifest = in.DockerImageManifest + return nil +} + +func autoconvert_api_ImageList_To_v1beta3_ImageList(in *imageapi.ImageList, out *imageapiv1beta3.ImageList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapi.ImageList))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { + return err + } + if in.Items != nil { + out.Items = make([]imageapiv1beta3.Image, len(in.Items)) + for i := range in.Items { + if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func convert_api_ImageList_To_v1beta3_ImageList(in *imageapi.ImageList, out *imageapiv1beta3.ImageList, s conversion.Scope) error { + return autoconvert_api_ImageList_To_v1beta3_ImageList(in, out, s) +} + +func autoconvert_api_ImageStream_To_v1beta3_ImageStream(in *imageapi.ImageStream, out *imageapiv1beta3.ImageStream, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapi.ImageStream))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.Status, 0); err != nil { + return err + } + return nil +} + +func autoconvert_api_ImageStreamImage_To_v1beta3_ImageStreamImage(in *imageapi.ImageStreamImage, out *imageapiv1beta3.ImageStreamImage, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapi.ImageStreamImage))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Image, &out.Image, 0); err != nil { + return err + } return nil } -func convert_api_DeploymentConfigList_To_v1beta3_DeploymentConfigList(in *deployapi.DeploymentConfigList, out *deployapiv1beta3.DeploymentConfigList, s conversion.Scope) error { +func autoconvert_api_ImageStreamList_To_v1beta3_ImageStreamList(in *imageapi.ImageStreamList, out *imageapiv1beta3.ImageStreamList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*deployapi.DeploymentConfigList))(in) + defaulting.(func(*imageapi.ImageStreamList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { - out.Items = make([]deployapiv1beta3.DeploymentConfig, len(in.Items)) + out.Items = make([]imageapiv1beta3.ImageStream, len(in.Items)) for i := range in.Items { if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { return err @@ -1384,95 +2608,97 @@ func convert_api_DeploymentConfigList_To_v1beta3_DeploymentConfigList(in *deploy return nil } -func convert_api_DeploymentConfigRollback_To_v1beta3_DeploymentConfigRollback(in *deployapi.DeploymentConfigRollback, out *deployapiv1beta3.DeploymentConfigRollback, s conversion.Scope) error { +func convert_api_ImageStreamList_To_v1beta3_ImageStreamList(in *imageapi.ImageStreamList, out *imageapiv1beta3.ImageStreamList, s conversion.Scope) error { + return autoconvert_api_ImageStreamList_To_v1beta3_ImageStreamList(in, out, s) +} + +func autoconvert_api_ImageStreamMapping_To_v1beta3_ImageStreamMapping(in *imageapi.ImageStreamMapping, out *imageapiv1beta3.ImageStreamMapping, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*deployapi.DeploymentConfigRollback))(in) + defaulting.(func(*imageapi.ImageStreamMapping))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_DeploymentConfigRollbackSpec_To_v1beta3_DeploymentConfigRollbackSpec(&in.Spec, &out.Spec, s); err != nil { + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + // in.DockerImageRepository has no peer in out + if err := s.Convert(&in.Image, &out.Image, 0); err != nil { return err } + out.Tag = in.Tag return nil } -func convert_api_DeploymentConfigRollbackSpec_To_v1beta3_DeploymentConfigRollbackSpec(in *deployapi.DeploymentConfigRollbackSpec, out *deployapiv1beta3.DeploymentConfigRollbackSpec, s conversion.Scope) error { +func autoconvert_api_ImageStreamSpec_To_v1beta3_ImageStreamSpec(in *imageapi.ImageStreamSpec, out *imageapiv1beta3.ImageStreamSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*deployapi.DeploymentConfigRollbackSpec))(in) + defaulting.(func(*imageapi.ImageStreamSpec))(in) } - if err := convert_api_ObjectReference_To_v1beta3_ObjectReference(&in.From, &out.From, s); err != nil { + out.DockerImageRepository = in.DockerImageRepository + if err := s.Convert(&in.Tags, &out.Tags, 0); err != nil { return err } - out.IncludeTriggers = in.IncludeTriggers - out.IncludeTemplate = in.IncludeTemplate - out.IncludeReplicationMeta = in.IncludeReplicationMeta - out.IncludeStrategy = in.IncludeStrategy return nil } -func convert_v1beta3_DeploymentConfigList_To_api_DeploymentConfigList(in *deployapiv1beta3.DeploymentConfigList, out *deployapi.DeploymentConfigList, s conversion.Scope) error { +func autoconvert_api_ImageStreamStatus_To_v1beta3_ImageStreamStatus(in *imageapi.ImageStreamStatus, out *imageapiv1beta3.ImageStreamStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*deployapiv1beta3.DeploymentConfigList))(in) - } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { - return err + defaulting.(func(*imageapi.ImageStreamStatus))(in) } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + out.DockerImageRepository = in.DockerImageRepository + if err := s.Convert(&in.Tags, &out.Tags, 0); err != nil { return err } - if in.Items != nil { - out.Items = make([]deployapi.DeploymentConfig, len(in.Items)) - for i := range in.Items { - if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { - return err - } - } - } else { - out.Items = nil - } return nil } -func convert_v1beta3_DeploymentConfigRollback_To_api_DeploymentConfigRollback(in *deployapiv1beta3.DeploymentConfigRollback, out *deployapi.DeploymentConfigRollback, s conversion.Scope) error { +func autoconvert_api_ImageStreamTag_To_v1beta3_ImageStreamTag(in *imageapi.ImageStreamTag, out *imageapiv1beta3.ImageStreamTag, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*deployapiv1beta3.DeploymentConfigRollback))(in) + defaulting.(func(*imageapi.ImageStreamTag))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec(&in.Spec, &out.Spec, s); err != nil { + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Image, &out.Image, 0); err != nil { return err } return nil } -func convert_v1beta3_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec(in *deployapiv1beta3.DeploymentConfigRollbackSpec, out *deployapi.DeploymentConfigRollbackSpec, s conversion.Scope) error { +func autoconvert_v1beta3_Image_To_api_Image(in *imageapiv1beta3.Image, out *imageapi.Image, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*deployapiv1beta3.DeploymentConfigRollbackSpec))(in) + defaulting.(func(*imageapiv1beta3.Image))(in) } - if err := convert_v1beta3_ObjectReference_To_api_ObjectReference(&in.From, &out.From, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - out.IncludeTriggers = in.IncludeTriggers - out.IncludeTemplate = in.IncludeTemplate - out.IncludeReplicationMeta = in.IncludeReplicationMeta - out.IncludeStrategy = in.IncludeStrategy + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + out.DockerImageReference = in.DockerImageReference + if err := s.Convert(&in.DockerImageMetadata, &out.DockerImageMetadata, 0); err != nil { + return err + } + out.DockerImageMetadataVersion = in.DockerImageMetadataVersion + out.DockerImageManifest = in.DockerImageManifest return nil } -func convert_api_ImageList_To_v1beta3_ImageList(in *imageapi.ImageList, out *imageapiv1beta3.ImageList, s conversion.Scope) error { +func autoconvert_v1beta3_ImageList_To_api_ImageList(in *imageapiv1beta3.ImageList, out *imageapi.ImageList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*imageapi.ImageList))(in) + defaulting.(func(*imageapiv1beta3.ImageList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { - out.Items = make([]imageapiv1beta3.Image, len(in.Items)) + out.Items = make([]imageapi.Image, len(in.Items)) for i := range in.Items { if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { return err @@ -1484,41 +2710,52 @@ func convert_api_ImageList_To_v1beta3_ImageList(in *imageapi.ImageList, out *ima return nil } -func convert_api_ImageStreamList_To_v1beta3_ImageStreamList(in *imageapi.ImageStreamList, out *imageapiv1beta3.ImageStreamList, s conversion.Scope) error { +func convert_v1beta3_ImageList_To_api_ImageList(in *imageapiv1beta3.ImageList, out *imageapi.ImageList, s conversion.Scope) error { + return autoconvert_v1beta3_ImageList_To_api_ImageList(in, out, s) +} + +func autoconvert_v1beta3_ImageStream_To_api_ImageStream(in *imageapiv1beta3.ImageStream, out *imageapi.ImageStream, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*imageapi.ImageStreamList))(in) + defaulting.(func(*imageapiv1beta3.ImageStream))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { return err } - if in.Items != nil { - out.Items = make([]imageapiv1beta3.ImageStream, len(in.Items)) - for i := range in.Items { - if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { - return err - } - } - } else { - out.Items = nil + if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.Status, 0); err != nil { + return err } return nil } -func convert_v1beta3_ImageList_To_api_ImageList(in *imageapiv1beta3.ImageList, out *imageapi.ImageList, s conversion.Scope) error { +func autoconvert_v1beta3_ImageStreamImage_To_api_ImageStreamImage(in *imageapiv1beta3.ImageStreamImage, out *imageapi.ImageStreamImage, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*imageapiv1beta3.ImageList))(in) + defaulting.(func(*imageapiv1beta3.ImageStreamImage))(in) + } + if err := s.Convert(&in.Image, &out.Image, 0); err != nil { + return err + } + // in.ImageName has no peer in out + return nil +} + +func autoconvert_v1beta3_ImageStreamList_To_api_ImageStreamList(in *imageapiv1beta3.ImageStreamList, out *imageapi.ImageStreamList, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapiv1beta3.ImageStreamList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { - out.Items = make([]imageapi.Image, len(in.Items)) + out.Items = make([]imageapi.ImageStream, len(in.Items)) for i := range in.Items { if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { return err @@ -1531,33 +2768,64 @@ func convert_v1beta3_ImageList_To_api_ImageList(in *imageapiv1beta3.ImageList, o } func convert_v1beta3_ImageStreamList_To_api_ImageStreamList(in *imageapiv1beta3.ImageStreamList, out *imageapi.ImageStreamList, s conversion.Scope) error { + return autoconvert_v1beta3_ImageStreamList_To_api_ImageStreamList(in, out, s) +} + +func autoconvert_v1beta3_ImageStreamMapping_To_api_ImageStreamMapping(in *imageapiv1beta3.ImageStreamMapping, out *imageapi.ImageStreamMapping, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*imageapiv1beta3.ImageStreamList))(in) + defaulting.(func(*imageapiv1beta3.ImageStreamMapping))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { return err } - if in.Items != nil { - out.Items = make([]imageapi.ImageStream, len(in.Items)) - for i := range in.Items { - if err := s.Convert(&in.Items[i], &out.Items[i], 0); err != nil { - return err - } - } - } else { - out.Items = nil + if err := s.Convert(&in.Image, &out.Image, 0); err != nil { + return err } + out.Tag = in.Tag return nil } -func convert_api_OAuthAccessToken_To_v1beta3_OAuthAccessToken(in *oauthapi.OAuthAccessToken, out *oauthapiv1beta3.OAuthAccessToken, s conversion.Scope) error { +func autoconvert_v1beta3_ImageStreamSpec_To_api_ImageStreamSpec(in *imageapiv1beta3.ImageStreamSpec, out *imageapi.ImageStreamSpec, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapiv1beta3.ImageStreamSpec))(in) + } + out.DockerImageRepository = in.DockerImageRepository + if err := s.Convert(&in.Tags, &out.Tags, 0); err != nil { + return err + } + return nil +} + +func autoconvert_v1beta3_ImageStreamStatus_To_api_ImageStreamStatus(in *imageapiv1beta3.ImageStreamStatus, out *imageapi.ImageStreamStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapiv1beta3.ImageStreamStatus))(in) + } + out.DockerImageRepository = in.DockerImageRepository + if err := s.Convert(&in.Tags, &out.Tags, 0); err != nil { + return err + } + return nil +} + +func autoconvert_v1beta3_ImageStreamTag_To_api_ImageStreamTag(in *imageapiv1beta3.ImageStreamTag, out *imageapi.ImageStreamTag, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*imageapiv1beta3.ImageStreamTag))(in) + } + if err := s.Convert(&in.Image, &out.Image, 0); err != nil { + return err + } + // in.ImageName has no peer in out + return nil +} + +func autoconvert_api_OAuthAccessToken_To_v1beta3_OAuthAccessToken(in *oauthapi.OAuthAccessToken, out *oauthapiv1beta3.OAuthAccessToken, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthAccessToken))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1581,14 +2849,18 @@ func convert_api_OAuthAccessToken_To_v1beta3_OAuthAccessToken(in *oauthapi.OAuth return nil } -func convert_api_OAuthAccessTokenList_To_v1beta3_OAuthAccessTokenList(in *oauthapi.OAuthAccessTokenList, out *oauthapiv1beta3.OAuthAccessTokenList, s conversion.Scope) error { +func convert_api_OAuthAccessToken_To_v1beta3_OAuthAccessToken(in *oauthapi.OAuthAccessToken, out *oauthapiv1beta3.OAuthAccessToken, s conversion.Scope) error { + return autoconvert_api_OAuthAccessToken_To_v1beta3_OAuthAccessToken(in, out, s) +} + +func autoconvert_api_OAuthAccessTokenList_To_v1beta3_OAuthAccessTokenList(in *oauthapi.OAuthAccessTokenList, out *oauthapiv1beta3.OAuthAccessTokenList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthAccessTokenList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1604,11 +2876,15 @@ func convert_api_OAuthAccessTokenList_To_v1beta3_OAuthAccessTokenList(in *oautha return nil } -func convert_api_OAuthAuthorizeToken_To_v1beta3_OAuthAuthorizeToken(in *oauthapi.OAuthAuthorizeToken, out *oauthapiv1beta3.OAuthAuthorizeToken, s conversion.Scope) error { +func convert_api_OAuthAccessTokenList_To_v1beta3_OAuthAccessTokenList(in *oauthapi.OAuthAccessTokenList, out *oauthapiv1beta3.OAuthAccessTokenList, s conversion.Scope) error { + return autoconvert_api_OAuthAccessTokenList_To_v1beta3_OAuthAccessTokenList(in, out, s) +} + +func autoconvert_api_OAuthAuthorizeToken_To_v1beta3_OAuthAuthorizeToken(in *oauthapi.OAuthAuthorizeToken, out *oauthapiv1beta3.OAuthAuthorizeToken, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthAuthorizeToken))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1631,14 +2907,18 @@ func convert_api_OAuthAuthorizeToken_To_v1beta3_OAuthAuthorizeToken(in *oauthapi return nil } -func convert_api_OAuthAuthorizeTokenList_To_v1beta3_OAuthAuthorizeTokenList(in *oauthapi.OAuthAuthorizeTokenList, out *oauthapiv1beta3.OAuthAuthorizeTokenList, s conversion.Scope) error { +func convert_api_OAuthAuthorizeToken_To_v1beta3_OAuthAuthorizeToken(in *oauthapi.OAuthAuthorizeToken, out *oauthapiv1beta3.OAuthAuthorizeToken, s conversion.Scope) error { + return autoconvert_api_OAuthAuthorizeToken_To_v1beta3_OAuthAuthorizeToken(in, out, s) +} + +func autoconvert_api_OAuthAuthorizeTokenList_To_v1beta3_OAuthAuthorizeTokenList(in *oauthapi.OAuthAuthorizeTokenList, out *oauthapiv1beta3.OAuthAuthorizeTokenList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthAuthorizeTokenList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1654,11 +2934,15 @@ func convert_api_OAuthAuthorizeTokenList_To_v1beta3_OAuthAuthorizeTokenList(in * return nil } -func convert_api_OAuthClient_To_v1beta3_OAuthClient(in *oauthapi.OAuthClient, out *oauthapiv1beta3.OAuthClient, s conversion.Scope) error { +func convert_api_OAuthAuthorizeTokenList_To_v1beta3_OAuthAuthorizeTokenList(in *oauthapi.OAuthAuthorizeTokenList, out *oauthapiv1beta3.OAuthAuthorizeTokenList, s conversion.Scope) error { + return autoconvert_api_OAuthAuthorizeTokenList_To_v1beta3_OAuthAuthorizeTokenList(in, out, s) +} + +func autoconvert_api_OAuthClient_To_v1beta3_OAuthClient(in *oauthapi.OAuthClient, out *oauthapiv1beta3.OAuthClient, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthClient))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1677,11 +2961,15 @@ func convert_api_OAuthClient_To_v1beta3_OAuthClient(in *oauthapi.OAuthClient, ou return nil } -func convert_api_OAuthClientAuthorization_To_v1beta3_OAuthClientAuthorization(in *oauthapi.OAuthClientAuthorization, out *oauthapiv1beta3.OAuthClientAuthorization, s conversion.Scope) error { +func convert_api_OAuthClient_To_v1beta3_OAuthClient(in *oauthapi.OAuthClient, out *oauthapiv1beta3.OAuthClient, s conversion.Scope) error { + return autoconvert_api_OAuthClient_To_v1beta3_OAuthClient(in, out, s) +} + +func autoconvert_api_OAuthClientAuthorization_To_v1beta3_OAuthClientAuthorization(in *oauthapi.OAuthClientAuthorization, out *oauthapiv1beta3.OAuthClientAuthorization, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthClientAuthorization))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1701,14 +2989,18 @@ func convert_api_OAuthClientAuthorization_To_v1beta3_OAuthClientAuthorization(in return nil } -func convert_api_OAuthClientAuthorizationList_To_v1beta3_OAuthClientAuthorizationList(in *oauthapi.OAuthClientAuthorizationList, out *oauthapiv1beta3.OAuthClientAuthorizationList, s conversion.Scope) error { +func convert_api_OAuthClientAuthorization_To_v1beta3_OAuthClientAuthorization(in *oauthapi.OAuthClientAuthorization, out *oauthapiv1beta3.OAuthClientAuthorization, s conversion.Scope) error { + return autoconvert_api_OAuthClientAuthorization_To_v1beta3_OAuthClientAuthorization(in, out, s) +} + +func autoconvert_api_OAuthClientAuthorizationList_To_v1beta3_OAuthClientAuthorizationList(in *oauthapi.OAuthClientAuthorizationList, out *oauthapiv1beta3.OAuthClientAuthorizationList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthClientAuthorizationList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1724,14 +3016,18 @@ func convert_api_OAuthClientAuthorizationList_To_v1beta3_OAuthClientAuthorizatio return nil } -func convert_api_OAuthClientList_To_v1beta3_OAuthClientList(in *oauthapi.OAuthClientList, out *oauthapiv1beta3.OAuthClientList, s conversion.Scope) error { +func convert_api_OAuthClientAuthorizationList_To_v1beta3_OAuthClientAuthorizationList(in *oauthapi.OAuthClientAuthorizationList, out *oauthapiv1beta3.OAuthClientAuthorizationList, s conversion.Scope) error { + return autoconvert_api_OAuthClientAuthorizationList_To_v1beta3_OAuthClientAuthorizationList(in, out, s) +} + +func autoconvert_api_OAuthClientList_To_v1beta3_OAuthClientList(in *oauthapi.OAuthClientList, out *oauthapiv1beta3.OAuthClientList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapi.OAuthClientList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1747,11 +3043,15 @@ func convert_api_OAuthClientList_To_v1beta3_OAuthClientList(in *oauthapi.OAuthCl return nil } -func convert_v1beta3_OAuthAccessToken_To_api_OAuthAccessToken(in *oauthapiv1beta3.OAuthAccessToken, out *oauthapi.OAuthAccessToken, s conversion.Scope) error { +func convert_api_OAuthClientList_To_v1beta3_OAuthClientList(in *oauthapi.OAuthClientList, out *oauthapiv1beta3.OAuthClientList, s conversion.Scope) error { + return autoconvert_api_OAuthClientList_To_v1beta3_OAuthClientList(in, out, s) +} + +func autoconvert_v1beta3_OAuthAccessToken_To_api_OAuthAccessToken(in *oauthapiv1beta3.OAuthAccessToken, out *oauthapi.OAuthAccessToken, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1beta3.OAuthAccessToken))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1775,14 +3075,18 @@ func convert_v1beta3_OAuthAccessToken_To_api_OAuthAccessToken(in *oauthapiv1beta return nil } -func convert_v1beta3_OAuthAccessTokenList_To_api_OAuthAccessTokenList(in *oauthapiv1beta3.OAuthAccessTokenList, out *oauthapi.OAuthAccessTokenList, s conversion.Scope) error { +func convert_v1beta3_OAuthAccessToken_To_api_OAuthAccessToken(in *oauthapiv1beta3.OAuthAccessToken, out *oauthapi.OAuthAccessToken, s conversion.Scope) error { + return autoconvert_v1beta3_OAuthAccessToken_To_api_OAuthAccessToken(in, out, s) +} + +func autoconvert_v1beta3_OAuthAccessTokenList_To_api_OAuthAccessTokenList(in *oauthapiv1beta3.OAuthAccessTokenList, out *oauthapi.OAuthAccessTokenList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1beta3.OAuthAccessTokenList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1798,11 +3102,15 @@ func convert_v1beta3_OAuthAccessTokenList_To_api_OAuthAccessTokenList(in *oautha return nil } -func convert_v1beta3_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken(in *oauthapiv1beta3.OAuthAuthorizeToken, out *oauthapi.OAuthAuthorizeToken, s conversion.Scope) error { +func convert_v1beta3_OAuthAccessTokenList_To_api_OAuthAccessTokenList(in *oauthapiv1beta3.OAuthAccessTokenList, out *oauthapi.OAuthAccessTokenList, s conversion.Scope) error { + return autoconvert_v1beta3_OAuthAccessTokenList_To_api_OAuthAccessTokenList(in, out, s) +} + +func autoconvert_v1beta3_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken(in *oauthapiv1beta3.OAuthAuthorizeToken, out *oauthapi.OAuthAuthorizeToken, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1beta3.OAuthAuthorizeToken))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1825,14 +3133,18 @@ func convert_v1beta3_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken(in *oauthapi return nil } -func convert_v1beta3_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList(in *oauthapiv1beta3.OAuthAuthorizeTokenList, out *oauthapi.OAuthAuthorizeTokenList, s conversion.Scope) error { +func convert_v1beta3_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken(in *oauthapiv1beta3.OAuthAuthorizeToken, out *oauthapi.OAuthAuthorizeToken, s conversion.Scope) error { + return autoconvert_v1beta3_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken(in, out, s) +} + +func autoconvert_v1beta3_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList(in *oauthapiv1beta3.OAuthAuthorizeTokenList, out *oauthapi.OAuthAuthorizeTokenList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1beta3.OAuthAuthorizeTokenList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1848,11 +3160,15 @@ func convert_v1beta3_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList(in * return nil } -func convert_v1beta3_OAuthClient_To_api_OAuthClient(in *oauthapiv1beta3.OAuthClient, out *oauthapi.OAuthClient, s conversion.Scope) error { +func convert_v1beta3_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList(in *oauthapiv1beta3.OAuthAuthorizeTokenList, out *oauthapi.OAuthAuthorizeTokenList, s conversion.Scope) error { + return autoconvert_v1beta3_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList(in, out, s) +} + +func autoconvert_v1beta3_OAuthClient_To_api_OAuthClient(in *oauthapiv1beta3.OAuthClient, out *oauthapi.OAuthClient, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1beta3.OAuthClient))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1871,11 +3187,15 @@ func convert_v1beta3_OAuthClient_To_api_OAuthClient(in *oauthapiv1beta3.OAuthCli return nil } -func convert_v1beta3_OAuthClientAuthorization_To_api_OAuthClientAuthorization(in *oauthapiv1beta3.OAuthClientAuthorization, out *oauthapi.OAuthClientAuthorization, s conversion.Scope) error { +func convert_v1beta3_OAuthClient_To_api_OAuthClient(in *oauthapiv1beta3.OAuthClient, out *oauthapi.OAuthClient, s conversion.Scope) error { + return autoconvert_v1beta3_OAuthClient_To_api_OAuthClient(in, out, s) +} + +func autoconvert_v1beta3_OAuthClientAuthorization_To_api_OAuthClientAuthorization(in *oauthapiv1beta3.OAuthClientAuthorization, out *oauthapi.OAuthClientAuthorization, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1beta3.OAuthClientAuthorization))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1895,14 +3215,18 @@ func convert_v1beta3_OAuthClientAuthorization_To_api_OAuthClientAuthorization(in return nil } -func convert_v1beta3_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList(in *oauthapiv1beta3.OAuthClientAuthorizationList, out *oauthapi.OAuthClientAuthorizationList, s conversion.Scope) error { +func convert_v1beta3_OAuthClientAuthorization_To_api_OAuthClientAuthorization(in *oauthapiv1beta3.OAuthClientAuthorization, out *oauthapi.OAuthClientAuthorization, s conversion.Scope) error { + return autoconvert_v1beta3_OAuthClientAuthorization_To_api_OAuthClientAuthorization(in, out, s) +} + +func autoconvert_v1beta3_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList(in *oauthapiv1beta3.OAuthClientAuthorizationList, out *oauthapi.OAuthClientAuthorizationList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1beta3.OAuthClientAuthorizationList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1918,14 +3242,18 @@ func convert_v1beta3_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizatio return nil } -func convert_v1beta3_OAuthClientList_To_api_OAuthClientList(in *oauthapiv1beta3.OAuthClientList, out *oauthapi.OAuthClientList, s conversion.Scope) error { +func convert_v1beta3_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList(in *oauthapiv1beta3.OAuthClientAuthorizationList, out *oauthapi.OAuthClientAuthorizationList, s conversion.Scope) error { + return autoconvert_v1beta3_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList(in, out, s) +} + +func autoconvert_v1beta3_OAuthClientList_To_api_OAuthClientList(in *oauthapiv1beta3.OAuthClientList, out *oauthapi.OAuthClientList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*oauthapiv1beta3.OAuthClientList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1941,11 +3269,15 @@ func convert_v1beta3_OAuthClientList_To_api_OAuthClientList(in *oauthapiv1beta3. return nil } -func convert_api_Project_To_v1beta3_Project(in *projectapi.Project, out *projectapiv1beta3.Project, s conversion.Scope) error { +func convert_v1beta3_OAuthClientList_To_api_OAuthClientList(in *oauthapiv1beta3.OAuthClientList, out *oauthapi.OAuthClientList, s conversion.Scope) error { + return autoconvert_v1beta3_OAuthClientList_To_api_OAuthClientList(in, out, s) +} + +func autoconvert_api_Project_To_v1beta3_Project(in *projectapi.Project, out *projectapiv1beta3.Project, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapi.Project))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1960,14 +3292,18 @@ func convert_api_Project_To_v1beta3_Project(in *projectapi.Project, out *project return nil } -func convert_api_ProjectList_To_v1beta3_ProjectList(in *projectapi.ProjectList, out *projectapiv1beta3.ProjectList, s conversion.Scope) error { +func convert_api_Project_To_v1beta3_Project(in *projectapi.Project, out *projectapiv1beta3.Project, s conversion.Scope) error { + return autoconvert_api_Project_To_v1beta3_Project(in, out, s) +} + +func autoconvert_api_ProjectList_To_v1beta3_ProjectList(in *projectapi.ProjectList, out *projectapiv1beta3.ProjectList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapi.ProjectList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -1983,11 +3319,15 @@ func convert_api_ProjectList_To_v1beta3_ProjectList(in *projectapi.ProjectList, return nil } -func convert_api_ProjectRequest_To_v1beta3_ProjectRequest(in *projectapi.ProjectRequest, out *projectapiv1beta3.ProjectRequest, s conversion.Scope) error { +func convert_api_ProjectList_To_v1beta3_ProjectList(in *projectapi.ProjectList, out *projectapiv1beta3.ProjectList, s conversion.Scope) error { + return autoconvert_api_ProjectList_To_v1beta3_ProjectList(in, out, s) +} + +func autoconvert_api_ProjectRequest_To_v1beta3_ProjectRequest(in *projectapi.ProjectRequest, out *projectapiv1beta3.ProjectRequest, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapi.ProjectRequest))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -1998,7 +3338,11 @@ func convert_api_ProjectRequest_To_v1beta3_ProjectRequest(in *projectapi.Project return nil } -func convert_api_ProjectSpec_To_v1beta3_ProjectSpec(in *projectapi.ProjectSpec, out *projectapiv1beta3.ProjectSpec, s conversion.Scope) error { +func convert_api_ProjectRequest_To_v1beta3_ProjectRequest(in *projectapi.ProjectRequest, out *projectapiv1beta3.ProjectRequest, s conversion.Scope) error { + return autoconvert_api_ProjectRequest_To_v1beta3_ProjectRequest(in, out, s) +} + +func autoconvert_api_ProjectSpec_To_v1beta3_ProjectSpec(in *projectapi.ProjectSpec, out *projectapiv1beta3.ProjectSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapi.ProjectSpec))(in) } @@ -2013,7 +3357,11 @@ func convert_api_ProjectSpec_To_v1beta3_ProjectSpec(in *projectapi.ProjectSpec, return nil } -func convert_api_ProjectStatus_To_v1beta3_ProjectStatus(in *projectapi.ProjectStatus, out *projectapiv1beta3.ProjectStatus, s conversion.Scope) error { +func convert_api_ProjectSpec_To_v1beta3_ProjectSpec(in *projectapi.ProjectSpec, out *projectapiv1beta3.ProjectSpec, s conversion.Scope) error { + return autoconvert_api_ProjectSpec_To_v1beta3_ProjectSpec(in, out, s) +} + +func autoconvert_api_ProjectStatus_To_v1beta3_ProjectStatus(in *projectapi.ProjectStatus, out *projectapiv1beta3.ProjectStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapi.ProjectStatus))(in) } @@ -2021,11 +3369,15 @@ func convert_api_ProjectStatus_To_v1beta3_ProjectStatus(in *projectapi.ProjectSt return nil } -func convert_v1beta3_Project_To_api_Project(in *projectapiv1beta3.Project, out *projectapi.Project, s conversion.Scope) error { +func convert_api_ProjectStatus_To_v1beta3_ProjectStatus(in *projectapi.ProjectStatus, out *projectapiv1beta3.ProjectStatus, s conversion.Scope) error { + return autoconvert_api_ProjectStatus_To_v1beta3_ProjectStatus(in, out, s) +} + +func autoconvert_v1beta3_Project_To_api_Project(in *projectapiv1beta3.Project, out *projectapi.Project, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapiv1beta3.Project))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2040,14 +3392,18 @@ func convert_v1beta3_Project_To_api_Project(in *projectapiv1beta3.Project, out * return nil } -func convert_v1beta3_ProjectList_To_api_ProjectList(in *projectapiv1beta3.ProjectList, out *projectapi.ProjectList, s conversion.Scope) error { +func convert_v1beta3_Project_To_api_Project(in *projectapiv1beta3.Project, out *projectapi.Project, s conversion.Scope) error { + return autoconvert_v1beta3_Project_To_api_Project(in, out, s) +} + +func autoconvert_v1beta3_ProjectList_To_api_ProjectList(in *projectapiv1beta3.ProjectList, out *projectapi.ProjectList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapiv1beta3.ProjectList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2063,11 +3419,15 @@ func convert_v1beta3_ProjectList_To_api_ProjectList(in *projectapiv1beta3.Projec return nil } -func convert_v1beta3_ProjectRequest_To_api_ProjectRequest(in *projectapiv1beta3.ProjectRequest, out *projectapi.ProjectRequest, s conversion.Scope) error { +func convert_v1beta3_ProjectList_To_api_ProjectList(in *projectapiv1beta3.ProjectList, out *projectapi.ProjectList, s conversion.Scope) error { + return autoconvert_v1beta3_ProjectList_To_api_ProjectList(in, out, s) +} + +func autoconvert_v1beta3_ProjectRequest_To_api_ProjectRequest(in *projectapiv1beta3.ProjectRequest, out *projectapi.ProjectRequest, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapiv1beta3.ProjectRequest))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2078,7 +3438,11 @@ func convert_v1beta3_ProjectRequest_To_api_ProjectRequest(in *projectapiv1beta3. return nil } -func convert_v1beta3_ProjectSpec_To_api_ProjectSpec(in *projectapiv1beta3.ProjectSpec, out *projectapi.ProjectSpec, s conversion.Scope) error { +func convert_v1beta3_ProjectRequest_To_api_ProjectRequest(in *projectapiv1beta3.ProjectRequest, out *projectapi.ProjectRequest, s conversion.Scope) error { + return autoconvert_v1beta3_ProjectRequest_To_api_ProjectRequest(in, out, s) +} + +func autoconvert_v1beta3_ProjectSpec_To_api_ProjectSpec(in *projectapiv1beta3.ProjectSpec, out *projectapi.ProjectSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapiv1beta3.ProjectSpec))(in) } @@ -2093,7 +3457,11 @@ func convert_v1beta3_ProjectSpec_To_api_ProjectSpec(in *projectapiv1beta3.Projec return nil } -func convert_v1beta3_ProjectStatus_To_api_ProjectStatus(in *projectapiv1beta3.ProjectStatus, out *projectapi.ProjectStatus, s conversion.Scope) error { +func convert_v1beta3_ProjectSpec_To_api_ProjectSpec(in *projectapiv1beta3.ProjectSpec, out *projectapi.ProjectSpec, s conversion.Scope) error { + return autoconvert_v1beta3_ProjectSpec_To_api_ProjectSpec(in, out, s) +} + +func autoconvert_v1beta3_ProjectStatus_To_api_ProjectStatus(in *projectapiv1beta3.ProjectStatus, out *projectapi.ProjectStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*projectapiv1beta3.ProjectStatus))(in) } @@ -2101,11 +3469,15 @@ func convert_v1beta3_ProjectStatus_To_api_ProjectStatus(in *projectapiv1beta3.Pr return nil } -func convert_api_Route_To_v1beta3_Route(in *routeapi.Route, out *routeapiv1beta3.Route, s conversion.Scope) error { +func convert_v1beta3_ProjectStatus_To_api_ProjectStatus(in *projectapiv1beta3.ProjectStatus, out *projectapi.ProjectStatus, s conversion.Scope) error { + return autoconvert_v1beta3_ProjectStatus_To_api_ProjectStatus(in, out, s) +} + +func autoconvert_api_Route_To_v1beta3_Route(in *routeapi.Route, out *routeapiv1beta3.Route, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.Route))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2120,14 +3492,18 @@ func convert_api_Route_To_v1beta3_Route(in *routeapi.Route, out *routeapiv1beta3 return nil } -func convert_api_RouteList_To_v1beta3_RouteList(in *routeapi.RouteList, out *routeapiv1beta3.RouteList, s conversion.Scope) error { +func convert_api_Route_To_v1beta3_Route(in *routeapi.Route, out *routeapiv1beta3.Route, s conversion.Scope) error { + return autoconvert_api_Route_To_v1beta3_Route(in, out, s) +} + +func autoconvert_api_RouteList_To_v1beta3_RouteList(in *routeapi.RouteList, out *routeapiv1beta3.RouteList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.RouteList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2143,7 +3519,11 @@ func convert_api_RouteList_To_v1beta3_RouteList(in *routeapi.RouteList, out *rou return nil } -func convert_api_RoutePort_To_v1beta3_RoutePort(in *routeapi.RoutePort, out *routeapiv1beta3.RoutePort, s conversion.Scope) error { +func convert_api_RouteList_To_v1beta3_RouteList(in *routeapi.RouteList, out *routeapiv1beta3.RouteList, s conversion.Scope) error { + return autoconvert_api_RouteList_To_v1beta3_RouteList(in, out, s) +} + +func autoconvert_api_RoutePort_To_v1beta3_RoutePort(in *routeapi.RoutePort, out *routeapiv1beta3.RoutePort, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.RoutePort))(in) } @@ -2153,7 +3533,11 @@ func convert_api_RoutePort_To_v1beta3_RoutePort(in *routeapi.RoutePort, out *rou return nil } -func convert_api_RouteSpec_To_v1beta3_RouteSpec(in *routeapi.RouteSpec, out *routeapiv1beta3.RouteSpec, s conversion.Scope) error { +func convert_api_RoutePort_To_v1beta3_RoutePort(in *routeapi.RoutePort, out *routeapiv1beta3.RoutePort, s conversion.Scope) error { + return autoconvert_api_RoutePort_To_v1beta3_RoutePort(in, out, s) +} + +func autoconvert_api_RouteSpec_To_v1beta3_RouteSpec(in *routeapi.RouteSpec, out *routeapiv1beta3.RouteSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.RouteSpec))(in) } @@ -2181,14 +3565,22 @@ func convert_api_RouteSpec_To_v1beta3_RouteSpec(in *routeapi.RouteSpec, out *rou return nil } -func convert_api_RouteStatus_To_v1beta3_RouteStatus(in *routeapi.RouteStatus, out *routeapiv1beta3.RouteStatus, s conversion.Scope) error { +func convert_api_RouteSpec_To_v1beta3_RouteSpec(in *routeapi.RouteSpec, out *routeapiv1beta3.RouteSpec, s conversion.Scope) error { + return autoconvert_api_RouteSpec_To_v1beta3_RouteSpec(in, out, s) +} + +func autoconvert_api_RouteStatus_To_v1beta3_RouteStatus(in *routeapi.RouteStatus, out *routeapiv1beta3.RouteStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.RouteStatus))(in) } return nil } -func convert_api_TLSConfig_To_v1beta3_TLSConfig(in *routeapi.TLSConfig, out *routeapiv1beta3.TLSConfig, s conversion.Scope) error { +func convert_api_RouteStatus_To_v1beta3_RouteStatus(in *routeapi.RouteStatus, out *routeapiv1beta3.RouteStatus, s conversion.Scope) error { + return autoconvert_api_RouteStatus_To_v1beta3_RouteStatus(in, out, s) +} + +func autoconvert_api_TLSConfig_To_v1beta3_TLSConfig(in *routeapi.TLSConfig, out *routeapiv1beta3.TLSConfig, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapi.TLSConfig))(in) } @@ -2200,11 +3592,15 @@ func convert_api_TLSConfig_To_v1beta3_TLSConfig(in *routeapi.TLSConfig, out *rou return nil } -func convert_v1beta3_Route_To_api_Route(in *routeapiv1beta3.Route, out *routeapi.Route, s conversion.Scope) error { +func convert_api_TLSConfig_To_v1beta3_TLSConfig(in *routeapi.TLSConfig, out *routeapiv1beta3.TLSConfig, s conversion.Scope) error { + return autoconvert_api_TLSConfig_To_v1beta3_TLSConfig(in, out, s) +} + +func autoconvert_v1beta3_Route_To_api_Route(in *routeapiv1beta3.Route, out *routeapi.Route, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1beta3.Route))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2219,14 +3615,18 @@ func convert_v1beta3_Route_To_api_Route(in *routeapiv1beta3.Route, out *routeapi return nil } -func convert_v1beta3_RouteList_To_api_RouteList(in *routeapiv1beta3.RouteList, out *routeapi.RouteList, s conversion.Scope) error { +func convert_v1beta3_Route_To_api_Route(in *routeapiv1beta3.Route, out *routeapi.Route, s conversion.Scope) error { + return autoconvert_v1beta3_Route_To_api_Route(in, out, s) +} + +func autoconvert_v1beta3_RouteList_To_api_RouteList(in *routeapiv1beta3.RouteList, out *routeapi.RouteList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1beta3.RouteList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2242,7 +3642,11 @@ func convert_v1beta3_RouteList_To_api_RouteList(in *routeapiv1beta3.RouteList, o return nil } -func convert_v1beta3_RoutePort_To_api_RoutePort(in *routeapiv1beta3.RoutePort, out *routeapi.RoutePort, s conversion.Scope) error { +func convert_v1beta3_RouteList_To_api_RouteList(in *routeapiv1beta3.RouteList, out *routeapi.RouteList, s conversion.Scope) error { + return autoconvert_v1beta3_RouteList_To_api_RouteList(in, out, s) +} + +func autoconvert_v1beta3_RoutePort_To_api_RoutePort(in *routeapiv1beta3.RoutePort, out *routeapi.RoutePort, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1beta3.RoutePort))(in) } @@ -2252,7 +3656,11 @@ func convert_v1beta3_RoutePort_To_api_RoutePort(in *routeapiv1beta3.RoutePort, o return nil } -func convert_v1beta3_RouteSpec_To_api_RouteSpec(in *routeapiv1beta3.RouteSpec, out *routeapi.RouteSpec, s conversion.Scope) error { +func convert_v1beta3_RoutePort_To_api_RoutePort(in *routeapiv1beta3.RoutePort, out *routeapi.RoutePort, s conversion.Scope) error { + return autoconvert_v1beta3_RoutePort_To_api_RoutePort(in, out, s) +} + +func autoconvert_v1beta3_RouteSpec_To_api_RouteSpec(in *routeapiv1beta3.RouteSpec, out *routeapi.RouteSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1beta3.RouteSpec))(in) } @@ -2280,14 +3688,22 @@ func convert_v1beta3_RouteSpec_To_api_RouteSpec(in *routeapiv1beta3.RouteSpec, o return nil } -func convert_v1beta3_RouteStatus_To_api_RouteStatus(in *routeapiv1beta3.RouteStatus, out *routeapi.RouteStatus, s conversion.Scope) error { +func convert_v1beta3_RouteSpec_To_api_RouteSpec(in *routeapiv1beta3.RouteSpec, out *routeapi.RouteSpec, s conversion.Scope) error { + return autoconvert_v1beta3_RouteSpec_To_api_RouteSpec(in, out, s) +} + +func autoconvert_v1beta3_RouteStatus_To_api_RouteStatus(in *routeapiv1beta3.RouteStatus, out *routeapi.RouteStatus, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1beta3.RouteStatus))(in) } return nil } -func convert_v1beta3_TLSConfig_To_api_TLSConfig(in *routeapiv1beta3.TLSConfig, out *routeapi.TLSConfig, s conversion.Scope) error { +func convert_v1beta3_RouteStatus_To_api_RouteStatus(in *routeapiv1beta3.RouteStatus, out *routeapi.RouteStatus, s conversion.Scope) error { + return autoconvert_v1beta3_RouteStatus_To_api_RouteStatus(in, out, s) +} + +func autoconvert_v1beta3_TLSConfig_To_api_TLSConfig(in *routeapiv1beta3.TLSConfig, out *routeapi.TLSConfig, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*routeapiv1beta3.TLSConfig))(in) } @@ -2299,11 +3715,15 @@ func convert_v1beta3_TLSConfig_To_api_TLSConfig(in *routeapiv1beta3.TLSConfig, o return nil } -func convert_api_ClusterNetwork_To_v1beta3_ClusterNetwork(in *sdnapi.ClusterNetwork, out *sdnapiv1beta3.ClusterNetwork, s conversion.Scope) error { +func convert_v1beta3_TLSConfig_To_api_TLSConfig(in *routeapiv1beta3.TLSConfig, out *routeapi.TLSConfig, s conversion.Scope) error { + return autoconvert_v1beta3_TLSConfig_To_api_TLSConfig(in, out, s) +} + +func autoconvert_api_ClusterNetwork_To_v1beta3_ClusterNetwork(in *sdnapi.ClusterNetwork, out *sdnapiv1beta3.ClusterNetwork, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.ClusterNetwork))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2315,14 +3735,18 @@ func convert_api_ClusterNetwork_To_v1beta3_ClusterNetwork(in *sdnapi.ClusterNetw return nil } -func convert_api_ClusterNetworkList_To_v1beta3_ClusterNetworkList(in *sdnapi.ClusterNetworkList, out *sdnapiv1beta3.ClusterNetworkList, s conversion.Scope) error { +func convert_api_ClusterNetwork_To_v1beta3_ClusterNetwork(in *sdnapi.ClusterNetwork, out *sdnapiv1beta3.ClusterNetwork, s conversion.Scope) error { + return autoconvert_api_ClusterNetwork_To_v1beta3_ClusterNetwork(in, out, s) +} + +func autoconvert_api_ClusterNetworkList_To_v1beta3_ClusterNetworkList(in *sdnapi.ClusterNetworkList, out *sdnapiv1beta3.ClusterNetworkList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.ClusterNetworkList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2338,11 +3762,15 @@ func convert_api_ClusterNetworkList_To_v1beta3_ClusterNetworkList(in *sdnapi.Clu return nil } -func convert_api_HostSubnet_To_v1beta3_HostSubnet(in *sdnapi.HostSubnet, out *sdnapiv1beta3.HostSubnet, s conversion.Scope) error { +func convert_api_ClusterNetworkList_To_v1beta3_ClusterNetworkList(in *sdnapi.ClusterNetworkList, out *sdnapiv1beta3.ClusterNetworkList, s conversion.Scope) error { + return autoconvert_api_ClusterNetworkList_To_v1beta3_ClusterNetworkList(in, out, s) +} + +func autoconvert_api_HostSubnet_To_v1beta3_HostSubnet(in *sdnapi.HostSubnet, out *sdnapiv1beta3.HostSubnet, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.HostSubnet))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2354,14 +3782,18 @@ func convert_api_HostSubnet_To_v1beta3_HostSubnet(in *sdnapi.HostSubnet, out *sd return nil } -func convert_api_HostSubnetList_To_v1beta3_HostSubnetList(in *sdnapi.HostSubnetList, out *sdnapiv1beta3.HostSubnetList, s conversion.Scope) error { +func convert_api_HostSubnet_To_v1beta3_HostSubnet(in *sdnapi.HostSubnet, out *sdnapiv1beta3.HostSubnet, s conversion.Scope) error { + return autoconvert_api_HostSubnet_To_v1beta3_HostSubnet(in, out, s) +} + +func autoconvert_api_HostSubnetList_To_v1beta3_HostSubnetList(in *sdnapi.HostSubnetList, out *sdnapiv1beta3.HostSubnetList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.HostSubnetList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2377,11 +3809,15 @@ func convert_api_HostSubnetList_To_v1beta3_HostSubnetList(in *sdnapi.HostSubnetL return nil } -func convert_api_NetNamespace_To_v1beta3_NetNamespace(in *sdnapi.NetNamespace, out *sdnapiv1beta3.NetNamespace, s conversion.Scope) error { +func convert_api_HostSubnetList_To_v1beta3_HostSubnetList(in *sdnapi.HostSubnetList, out *sdnapiv1beta3.HostSubnetList, s conversion.Scope) error { + return autoconvert_api_HostSubnetList_To_v1beta3_HostSubnetList(in, out, s) +} + +func autoconvert_api_NetNamespace_To_v1beta3_NetNamespace(in *sdnapi.NetNamespace, out *sdnapiv1beta3.NetNamespace, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.NetNamespace))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2392,14 +3828,18 @@ func convert_api_NetNamespace_To_v1beta3_NetNamespace(in *sdnapi.NetNamespace, o return nil } -func convert_api_NetNamespaceList_To_v1beta3_NetNamespaceList(in *sdnapi.NetNamespaceList, out *sdnapiv1beta3.NetNamespaceList, s conversion.Scope) error { +func convert_api_NetNamespace_To_v1beta3_NetNamespace(in *sdnapi.NetNamespace, out *sdnapiv1beta3.NetNamespace, s conversion.Scope) error { + return autoconvert_api_NetNamespace_To_v1beta3_NetNamespace(in, out, s) +} + +func autoconvert_api_NetNamespaceList_To_v1beta3_NetNamespaceList(in *sdnapi.NetNamespaceList, out *sdnapiv1beta3.NetNamespaceList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapi.NetNamespaceList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2415,11 +3855,15 @@ func convert_api_NetNamespaceList_To_v1beta3_NetNamespaceList(in *sdnapi.NetName return nil } -func convert_v1beta3_ClusterNetwork_To_api_ClusterNetwork(in *sdnapiv1beta3.ClusterNetwork, out *sdnapi.ClusterNetwork, s conversion.Scope) error { +func convert_api_NetNamespaceList_To_v1beta3_NetNamespaceList(in *sdnapi.NetNamespaceList, out *sdnapiv1beta3.NetNamespaceList, s conversion.Scope) error { + return autoconvert_api_NetNamespaceList_To_v1beta3_NetNamespaceList(in, out, s) +} + +func autoconvert_v1beta3_ClusterNetwork_To_api_ClusterNetwork(in *sdnapiv1beta3.ClusterNetwork, out *sdnapi.ClusterNetwork, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1beta3.ClusterNetwork))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2431,14 +3875,18 @@ func convert_v1beta3_ClusterNetwork_To_api_ClusterNetwork(in *sdnapiv1beta3.Clus return nil } -func convert_v1beta3_ClusterNetworkList_To_api_ClusterNetworkList(in *sdnapiv1beta3.ClusterNetworkList, out *sdnapi.ClusterNetworkList, s conversion.Scope) error { +func convert_v1beta3_ClusterNetwork_To_api_ClusterNetwork(in *sdnapiv1beta3.ClusterNetwork, out *sdnapi.ClusterNetwork, s conversion.Scope) error { + return autoconvert_v1beta3_ClusterNetwork_To_api_ClusterNetwork(in, out, s) +} + +func autoconvert_v1beta3_ClusterNetworkList_To_api_ClusterNetworkList(in *sdnapiv1beta3.ClusterNetworkList, out *sdnapi.ClusterNetworkList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1beta3.ClusterNetworkList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2454,11 +3902,15 @@ func convert_v1beta3_ClusterNetworkList_To_api_ClusterNetworkList(in *sdnapiv1be return nil } -func convert_v1beta3_HostSubnet_To_api_HostSubnet(in *sdnapiv1beta3.HostSubnet, out *sdnapi.HostSubnet, s conversion.Scope) error { +func convert_v1beta3_ClusterNetworkList_To_api_ClusterNetworkList(in *sdnapiv1beta3.ClusterNetworkList, out *sdnapi.ClusterNetworkList, s conversion.Scope) error { + return autoconvert_v1beta3_ClusterNetworkList_To_api_ClusterNetworkList(in, out, s) +} + +func autoconvert_v1beta3_HostSubnet_To_api_HostSubnet(in *sdnapiv1beta3.HostSubnet, out *sdnapi.HostSubnet, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1beta3.HostSubnet))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2470,14 +3922,18 @@ func convert_v1beta3_HostSubnet_To_api_HostSubnet(in *sdnapiv1beta3.HostSubnet, return nil } -func convert_v1beta3_HostSubnetList_To_api_HostSubnetList(in *sdnapiv1beta3.HostSubnetList, out *sdnapi.HostSubnetList, s conversion.Scope) error { +func convert_v1beta3_HostSubnet_To_api_HostSubnet(in *sdnapiv1beta3.HostSubnet, out *sdnapi.HostSubnet, s conversion.Scope) error { + return autoconvert_v1beta3_HostSubnet_To_api_HostSubnet(in, out, s) +} + +func autoconvert_v1beta3_HostSubnetList_To_api_HostSubnetList(in *sdnapiv1beta3.HostSubnetList, out *sdnapi.HostSubnetList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1beta3.HostSubnetList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2493,11 +3949,15 @@ func convert_v1beta3_HostSubnetList_To_api_HostSubnetList(in *sdnapiv1beta3.Host return nil } -func convert_v1beta3_NetNamespace_To_api_NetNamespace(in *sdnapiv1beta3.NetNamespace, out *sdnapi.NetNamespace, s conversion.Scope) error { +func convert_v1beta3_HostSubnetList_To_api_HostSubnetList(in *sdnapiv1beta3.HostSubnetList, out *sdnapi.HostSubnetList, s conversion.Scope) error { + return autoconvert_v1beta3_HostSubnetList_To_api_HostSubnetList(in, out, s) +} + +func autoconvert_v1beta3_NetNamespace_To_api_NetNamespace(in *sdnapiv1beta3.NetNamespace, out *sdnapi.NetNamespace, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1beta3.NetNamespace))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2508,14 +3968,18 @@ func convert_v1beta3_NetNamespace_To_api_NetNamespace(in *sdnapiv1beta3.NetNames return nil } -func convert_v1beta3_NetNamespaceList_To_api_NetNamespaceList(in *sdnapiv1beta3.NetNamespaceList, out *sdnapi.NetNamespaceList, s conversion.Scope) error { +func convert_v1beta3_NetNamespace_To_api_NetNamespace(in *sdnapiv1beta3.NetNamespace, out *sdnapi.NetNamespace, s conversion.Scope) error { + return autoconvert_v1beta3_NetNamespace_To_api_NetNamespace(in, out, s) +} + +func autoconvert_v1beta3_NetNamespaceList_To_api_NetNamespaceList(in *sdnapiv1beta3.NetNamespaceList, out *sdnapi.NetNamespaceList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*sdnapiv1beta3.NetNamespaceList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2531,7 +3995,11 @@ func convert_v1beta3_NetNamespaceList_To_api_NetNamespaceList(in *sdnapiv1beta3. return nil } -func convert_api_Parameter_To_v1beta3_Parameter(in *templateapi.Parameter, out *templateapiv1beta3.Parameter, s conversion.Scope) error { +func convert_v1beta3_NetNamespaceList_To_api_NetNamespaceList(in *sdnapiv1beta3.NetNamespaceList, out *sdnapi.NetNamespaceList, s conversion.Scope) error { + return autoconvert_v1beta3_NetNamespaceList_To_api_NetNamespaceList(in, out, s) +} + +func autoconvert_api_Parameter_To_v1beta3_Parameter(in *templateapi.Parameter, out *templateapiv1beta3.Parameter, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*templateapi.Parameter))(in) } @@ -2545,14 +4013,45 @@ func convert_api_Parameter_To_v1beta3_Parameter(in *templateapi.Parameter, out * return nil } -func convert_api_TemplateList_To_v1beta3_TemplateList(in *templateapi.TemplateList, out *templateapiv1beta3.TemplateList, s conversion.Scope) error { +func convert_api_Parameter_To_v1beta3_Parameter(in *templateapi.Parameter, out *templateapiv1beta3.Parameter, s conversion.Scope) error { + return autoconvert_api_Parameter_To_v1beta3_Parameter(in, out, s) +} + +func autoconvert_api_Template_To_v1beta3_Template(in *templateapi.Template, out *templateapiv1beta3.Template, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*templateapi.Template))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if in.Parameters != nil { + out.Parameters = make([]templateapiv1beta3.Parameter, len(in.Parameters)) + for i := range in.Parameters { + if err := convert_api_Parameter_To_v1beta3_Parameter(&in.Parameters[i], &out.Parameters[i], s); err != nil { + return err + } + } + } else { + out.Parameters = nil + } + if err := s.Convert(&in.Objects, &out.Objects, 0); err != nil { + return err + } + // in.ObjectLabels has no peer in out + return nil +} + +func autoconvert_api_TemplateList_To_v1beta3_TemplateList(in *templateapi.TemplateList, out *templateapiv1beta3.TemplateList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*templateapi.TemplateList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2568,7 +4067,11 @@ func convert_api_TemplateList_To_v1beta3_TemplateList(in *templateapi.TemplateLi return nil } -func convert_v1beta3_Parameter_To_api_Parameter(in *templateapiv1beta3.Parameter, out *templateapi.Parameter, s conversion.Scope) error { +func convert_api_TemplateList_To_v1beta3_TemplateList(in *templateapi.TemplateList, out *templateapiv1beta3.TemplateList, s conversion.Scope) error { + return autoconvert_api_TemplateList_To_v1beta3_TemplateList(in, out, s) +} + +func autoconvert_v1beta3_Parameter_To_api_Parameter(in *templateapiv1beta3.Parameter, out *templateapi.Parameter, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*templateapiv1beta3.Parameter))(in) } @@ -2582,14 +4085,52 @@ func convert_v1beta3_Parameter_To_api_Parameter(in *templateapiv1beta3.Parameter return nil } -func convert_v1beta3_TemplateList_To_api_TemplateList(in *templateapiv1beta3.TemplateList, out *templateapi.TemplateList, s conversion.Scope) error { +func convert_v1beta3_Parameter_To_api_Parameter(in *templateapiv1beta3.Parameter, out *templateapi.Parameter, s conversion.Scope) error { + return autoconvert_v1beta3_Parameter_To_api_Parameter(in, out, s) +} + +func autoconvert_v1beta3_Template_To_api_Template(in *templateapiv1beta3.Template, out *templateapi.Template, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*templateapiv1beta3.Template))(in) + } + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := s.Convert(&in.Objects, &out.Objects, 0); err != nil { + return err + } + if in.Parameters != nil { + out.Parameters = make([]templateapi.Parameter, len(in.Parameters)) + for i := range in.Parameters { + if err := convert_v1beta3_Parameter_To_api_Parameter(&in.Parameters[i], &out.Parameters[i], s); err != nil { + return err + } + } + } else { + out.Parameters = nil + } + if in.Labels != nil { + out.Labels = make(map[string]string) + for key, val := range in.Labels { + out.Labels[key] = val + } + } else { + out.Labels = nil + } + return nil +} + +func autoconvert_v1beta3_TemplateList_To_api_TemplateList(in *templateapiv1beta3.TemplateList, out *templateapi.TemplateList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*templateapiv1beta3.TemplateList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2605,11 +4146,15 @@ func convert_v1beta3_TemplateList_To_api_TemplateList(in *templateapiv1beta3.Tem return nil } -func convert_api_Group_To_v1beta3_Group(in *userapi.Group, out *userapiv1beta3.Group, s conversion.Scope) error { +func convert_v1beta3_TemplateList_To_api_TemplateList(in *templateapiv1beta3.TemplateList, out *templateapi.TemplateList, s conversion.Scope) error { + return autoconvert_v1beta3_TemplateList_To_api_TemplateList(in, out, s) +} + +func autoconvert_api_Group_To_v1beta3_Group(in *userapi.Group, out *userapiv1beta3.Group, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.Group))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2626,14 +4171,18 @@ func convert_api_Group_To_v1beta3_Group(in *userapi.Group, out *userapiv1beta3.G return nil } -func convert_api_GroupList_To_v1beta3_GroupList(in *userapi.GroupList, out *userapiv1beta3.GroupList, s conversion.Scope) error { +func convert_api_Group_To_v1beta3_Group(in *userapi.Group, out *userapiv1beta3.Group, s conversion.Scope) error { + return autoconvert_api_Group_To_v1beta3_Group(in, out, s) +} + +func autoconvert_api_GroupList_To_v1beta3_GroupList(in *userapi.GroupList, out *userapiv1beta3.GroupList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.GroupList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2649,11 +4198,15 @@ func convert_api_GroupList_To_v1beta3_GroupList(in *userapi.GroupList, out *user return nil } -func convert_api_Identity_To_v1beta3_Identity(in *userapi.Identity, out *userapiv1beta3.Identity, s conversion.Scope) error { +func convert_api_GroupList_To_v1beta3_GroupList(in *userapi.GroupList, out *userapiv1beta3.GroupList, s conversion.Scope) error { + return autoconvert_api_GroupList_To_v1beta3_GroupList(in, out, s) +} + +func autoconvert_api_Identity_To_v1beta3_Identity(in *userapi.Identity, out *userapiv1beta3.Identity, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.Identity))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2675,14 +4228,18 @@ func convert_api_Identity_To_v1beta3_Identity(in *userapi.Identity, out *userapi return nil } -func convert_api_IdentityList_To_v1beta3_IdentityList(in *userapi.IdentityList, out *userapiv1beta3.IdentityList, s conversion.Scope) error { +func convert_api_Identity_To_v1beta3_Identity(in *userapi.Identity, out *userapiv1beta3.Identity, s conversion.Scope) error { + return autoconvert_api_Identity_To_v1beta3_Identity(in, out, s) +} + +func autoconvert_api_IdentityList_To_v1beta3_IdentityList(in *userapi.IdentityList, out *userapiv1beta3.IdentityList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.IdentityList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2698,11 +4255,15 @@ func convert_api_IdentityList_To_v1beta3_IdentityList(in *userapi.IdentityList, return nil } -func convert_api_User_To_v1beta3_User(in *userapi.User, out *userapiv1beta3.User, s conversion.Scope) error { +func convert_api_IdentityList_To_v1beta3_IdentityList(in *userapi.IdentityList, out *userapiv1beta3.IdentityList, s conversion.Scope) error { + return autoconvert_api_IdentityList_To_v1beta3_IdentityList(in, out, s) +} + +func autoconvert_api_User_To_v1beta3_User(in *userapi.User, out *userapiv1beta3.User, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.User))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2728,11 +4289,15 @@ func convert_api_User_To_v1beta3_User(in *userapi.User, out *userapiv1beta3.User return nil } -func convert_api_UserIdentityMapping_To_v1beta3_UserIdentityMapping(in *userapi.UserIdentityMapping, out *userapiv1beta3.UserIdentityMapping, s conversion.Scope) error { +func convert_api_User_To_v1beta3_User(in *userapi.User, out *userapiv1beta3.User, s conversion.Scope) error { + return autoconvert_api_User_To_v1beta3_User(in, out, s) +} + +func autoconvert_api_UserIdentityMapping_To_v1beta3_UserIdentityMapping(in *userapi.UserIdentityMapping, out *userapiv1beta3.UserIdentityMapping, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.UserIdentityMapping))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_api_ObjectMeta_To_v1beta3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2747,14 +4312,18 @@ func convert_api_UserIdentityMapping_To_v1beta3_UserIdentityMapping(in *userapi. return nil } -func convert_api_UserList_To_v1beta3_UserList(in *userapi.UserList, out *userapiv1beta3.UserList, s conversion.Scope) error { +func convert_api_UserIdentityMapping_To_v1beta3_UserIdentityMapping(in *userapi.UserIdentityMapping, out *userapiv1beta3.UserIdentityMapping, s conversion.Scope) error { + return autoconvert_api_UserIdentityMapping_To_v1beta3_UserIdentityMapping(in, out, s) +} + +func autoconvert_api_UserList_To_v1beta3_UserList(in *userapi.UserList, out *userapiv1beta3.UserList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapi.UserList))(in) } - if err := convert_api_TypeMeta_To_v1beta3_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_api_ListMeta_To_v1beta3_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2770,11 +4339,15 @@ func convert_api_UserList_To_v1beta3_UserList(in *userapi.UserList, out *userapi return nil } -func convert_v1beta3_Group_To_api_Group(in *userapiv1beta3.Group, out *userapi.Group, s conversion.Scope) error { +func convert_api_UserList_To_v1beta3_UserList(in *userapi.UserList, out *userapiv1beta3.UserList, s conversion.Scope) error { + return autoconvert_api_UserList_To_v1beta3_UserList(in, out, s) +} + +func autoconvert_v1beta3_Group_To_api_Group(in *userapiv1beta3.Group, out *userapi.Group, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1beta3.Group))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2791,14 +4364,18 @@ func convert_v1beta3_Group_To_api_Group(in *userapiv1beta3.Group, out *userapi.G return nil } -func convert_v1beta3_GroupList_To_api_GroupList(in *userapiv1beta3.GroupList, out *userapi.GroupList, s conversion.Scope) error { +func convert_v1beta3_Group_To_api_Group(in *userapiv1beta3.Group, out *userapi.Group, s conversion.Scope) error { + return autoconvert_v1beta3_Group_To_api_Group(in, out, s) +} + +func autoconvert_v1beta3_GroupList_To_api_GroupList(in *userapiv1beta3.GroupList, out *userapi.GroupList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1beta3.GroupList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2814,11 +4391,15 @@ func convert_v1beta3_GroupList_To_api_GroupList(in *userapiv1beta3.GroupList, ou return nil } -func convert_v1beta3_Identity_To_api_Identity(in *userapiv1beta3.Identity, out *userapi.Identity, s conversion.Scope) error { +func convert_v1beta3_GroupList_To_api_GroupList(in *userapiv1beta3.GroupList, out *userapi.GroupList, s conversion.Scope) error { + return autoconvert_v1beta3_GroupList_To_api_GroupList(in, out, s) +} + +func autoconvert_v1beta3_Identity_To_api_Identity(in *userapiv1beta3.Identity, out *userapi.Identity, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1beta3.Identity))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2840,14 +4421,18 @@ func convert_v1beta3_Identity_To_api_Identity(in *userapiv1beta3.Identity, out * return nil } -func convert_v1beta3_IdentityList_To_api_IdentityList(in *userapiv1beta3.IdentityList, out *userapi.IdentityList, s conversion.Scope) error { +func convert_v1beta3_Identity_To_api_Identity(in *userapiv1beta3.Identity, out *userapi.Identity, s conversion.Scope) error { + return autoconvert_v1beta3_Identity_To_api_Identity(in, out, s) +} + +func autoconvert_v1beta3_IdentityList_To_api_IdentityList(in *userapiv1beta3.IdentityList, out *userapi.IdentityList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1beta3.IdentityList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2863,11 +4448,15 @@ func convert_v1beta3_IdentityList_To_api_IdentityList(in *userapiv1beta3.Identit return nil } -func convert_v1beta3_User_To_api_User(in *userapiv1beta3.User, out *userapi.User, s conversion.Scope) error { +func convert_v1beta3_IdentityList_To_api_IdentityList(in *userapiv1beta3.IdentityList, out *userapi.IdentityList, s conversion.Scope) error { + return autoconvert_v1beta3_IdentityList_To_api_IdentityList(in, out, s) +} + +func autoconvert_v1beta3_User_To_api_User(in *userapiv1beta3.User, out *userapi.User, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1beta3.User))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2893,11 +4482,15 @@ func convert_v1beta3_User_To_api_User(in *userapiv1beta3.User, out *userapi.User return nil } -func convert_v1beta3_UserIdentityMapping_To_api_UserIdentityMapping(in *userapiv1beta3.UserIdentityMapping, out *userapi.UserIdentityMapping, s conversion.Scope) error { +func convert_v1beta3_User_To_api_User(in *userapiv1beta3.User, out *userapi.User, s conversion.Scope) error { + return autoconvert_v1beta3_User_To_api_User(in, out, s) +} + +func autoconvert_v1beta3_UserIdentityMapping_To_api_UserIdentityMapping(in *userapiv1beta3.UserIdentityMapping, out *userapi.UserIdentityMapping, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1beta3.UserIdentityMapping))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } if err := convert_v1beta3_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { @@ -2912,14 +4505,18 @@ func convert_v1beta3_UserIdentityMapping_To_api_UserIdentityMapping(in *userapiv return nil } -func convert_v1beta3_UserList_To_api_UserList(in *userapiv1beta3.UserList, out *userapi.UserList, s conversion.Scope) error { +func convert_v1beta3_UserIdentityMapping_To_api_UserIdentityMapping(in *userapiv1beta3.UserIdentityMapping, out *userapi.UserIdentityMapping, s conversion.Scope) error { + return autoconvert_v1beta3_UserIdentityMapping_To_api_UserIdentityMapping(in, out, s) +} + +func autoconvert_v1beta3_UserList_To_api_UserList(in *userapiv1beta3.UserList, out *userapi.UserList, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*userapiv1beta3.UserList))(in) } - if err := convert_v1beta3_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err } - if err := convert_v1beta3_ListMeta_To_api_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + if err := s.Convert(&in.ListMeta, &out.ListMeta, 0); err != nil { return err } if in.Items != nil { @@ -2935,7 +4532,11 @@ func convert_v1beta3_UserList_To_api_UserList(in *userapiv1beta3.UserList, out * return nil } -func convert_api_EnvVar_To_v1beta3_EnvVar(in *pkgapi.EnvVar, out *pkgapiv1beta3.EnvVar, s conversion.Scope) error { +func convert_v1beta3_UserList_To_api_UserList(in *userapiv1beta3.UserList, out *userapi.UserList, s conversion.Scope) error { + return autoconvert_v1beta3_UserList_To_api_UserList(in, out, s) +} + +func autoconvert_api_EnvVar_To_v1beta3_EnvVar(in *pkgapi.EnvVar, out *pkgapiv1beta3.EnvVar, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.EnvVar))(in) } @@ -2952,7 +4553,11 @@ func convert_api_EnvVar_To_v1beta3_EnvVar(in *pkgapi.EnvVar, out *pkgapiv1beta3. return nil } -func convert_api_EnvVarSource_To_v1beta3_EnvVarSource(in *pkgapi.EnvVarSource, out *pkgapiv1beta3.EnvVarSource, s conversion.Scope) error { +func convert_api_EnvVar_To_v1beta3_EnvVar(in *pkgapi.EnvVar, out *pkgapiv1beta3.EnvVar, s conversion.Scope) error { + return autoconvert_api_EnvVar_To_v1beta3_EnvVar(in, out, s) +} + +func autoconvert_api_EnvVarSource_To_v1beta3_EnvVarSource(in *pkgapi.EnvVarSource, out *pkgapiv1beta3.EnvVarSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.EnvVarSource))(in) } @@ -2967,16 +4572,11 @@ func convert_api_EnvVarSource_To_v1beta3_EnvVarSource(in *pkgapi.EnvVarSource, o return nil } -func convert_api_ListMeta_To_v1beta3_ListMeta(in *pkgapi.ListMeta, out *pkgapiv1beta3.ListMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*pkgapi.ListMeta))(in) - } - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil +func convert_api_EnvVarSource_To_v1beta3_EnvVarSource(in *pkgapi.EnvVarSource, out *pkgapiv1beta3.EnvVarSource, s conversion.Scope) error { + return autoconvert_api_EnvVarSource_To_v1beta3_EnvVarSource(in, out, s) } -func convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in *pkgapi.LocalObjectReference, out *pkgapiv1beta3.LocalObjectReference, s conversion.Scope) error { +func autoconvert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in *pkgapi.LocalObjectReference, out *pkgapiv1beta3.LocalObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.LocalObjectReference))(in) } @@ -2984,7 +4584,11 @@ func convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in *pkgapi return nil } -func convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(in *pkgapi.ObjectFieldSelector, out *pkgapiv1beta3.ObjectFieldSelector, s conversion.Scope) error { +func convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in *pkgapi.LocalObjectReference, out *pkgapiv1beta3.LocalObjectReference, s conversion.Scope) error { + return autoconvert_api_LocalObjectReference_To_v1beta3_LocalObjectReference(in, out, s) +} + +func autoconvert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(in *pkgapi.ObjectFieldSelector, out *pkgapiv1beta3.ObjectFieldSelector, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.ObjectFieldSelector))(in) } @@ -2993,7 +4597,11 @@ func convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(in *pkgapi.O return nil } -func convert_api_ObjectMeta_To_v1beta3_ObjectMeta(in *pkgapi.ObjectMeta, out *pkgapiv1beta3.ObjectMeta, s conversion.Scope) error { +func convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(in *pkgapi.ObjectFieldSelector, out *pkgapiv1beta3.ObjectFieldSelector, s conversion.Scope) error { + return autoconvert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector(in, out, s) +} + +func autoconvert_api_ObjectMeta_To_v1beta3_ObjectMeta(in *pkgapi.ObjectMeta, out *pkgapiv1beta3.ObjectMeta, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.ObjectMeta))(in) } @@ -3039,7 +4647,11 @@ func convert_api_ObjectMeta_To_v1beta3_ObjectMeta(in *pkgapi.ObjectMeta, out *pk return nil } -func convert_api_ObjectReference_To_v1beta3_ObjectReference(in *pkgapi.ObjectReference, out *pkgapiv1beta3.ObjectReference, s conversion.Scope) error { +func convert_api_ObjectMeta_To_v1beta3_ObjectMeta(in *pkgapi.ObjectMeta, out *pkgapiv1beta3.ObjectMeta, s conversion.Scope) error { + return autoconvert_api_ObjectMeta_To_v1beta3_ObjectMeta(in, out, s) +} + +func autoconvert_api_ObjectReference_To_v1beta3_ObjectReference(in *pkgapi.ObjectReference, out *pkgapiv1beta3.ObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.ObjectReference))(in) } @@ -3053,7 +4665,11 @@ func convert_api_ObjectReference_To_v1beta3_ObjectReference(in *pkgapi.ObjectRef return nil } -func convert_api_ResourceRequirements_To_v1beta3_ResourceRequirements(in *pkgapi.ResourceRequirements, out *pkgapiv1beta3.ResourceRequirements, s conversion.Scope) error { +func convert_api_ObjectReference_To_v1beta3_ObjectReference(in *pkgapi.ObjectReference, out *pkgapiv1beta3.ObjectReference, s conversion.Scope) error { + return autoconvert_api_ObjectReference_To_v1beta3_ObjectReference(in, out, s) +} + +func autoconvert_api_ResourceRequirements_To_v1beta3_ResourceRequirements(in *pkgapi.ResourceRequirements, out *pkgapiv1beta3.ResourceRequirements, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapi.ResourceRequirements))(in) } @@ -3084,16 +4700,11 @@ func convert_api_ResourceRequirements_To_v1beta3_ResourceRequirements(in *pkgapi return nil } -func convert_api_TypeMeta_To_v1beta3_TypeMeta(in *pkgapi.TypeMeta, out *pkgapiv1beta3.TypeMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*pkgapi.TypeMeta))(in) - } - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil +func convert_api_ResourceRequirements_To_v1beta3_ResourceRequirements(in *pkgapi.ResourceRequirements, out *pkgapiv1beta3.ResourceRequirements, s conversion.Scope) error { + return autoconvert_api_ResourceRequirements_To_v1beta3_ResourceRequirements(in, out, s) } -func convert_v1beta3_EnvVar_To_api_EnvVar(in *pkgapiv1beta3.EnvVar, out *pkgapi.EnvVar, s conversion.Scope) error { +func autoconvert_v1beta3_EnvVar_To_api_EnvVar(in *pkgapiv1beta3.EnvVar, out *pkgapi.EnvVar, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1beta3.EnvVar))(in) } @@ -3110,7 +4721,11 @@ func convert_v1beta3_EnvVar_To_api_EnvVar(in *pkgapiv1beta3.EnvVar, out *pkgapi. return nil } -func convert_v1beta3_EnvVarSource_To_api_EnvVarSource(in *pkgapiv1beta3.EnvVarSource, out *pkgapi.EnvVarSource, s conversion.Scope) error { +func convert_v1beta3_EnvVar_To_api_EnvVar(in *pkgapiv1beta3.EnvVar, out *pkgapi.EnvVar, s conversion.Scope) error { + return autoconvert_v1beta3_EnvVar_To_api_EnvVar(in, out, s) +} + +func autoconvert_v1beta3_EnvVarSource_To_api_EnvVarSource(in *pkgapiv1beta3.EnvVarSource, out *pkgapi.EnvVarSource, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1beta3.EnvVarSource))(in) } @@ -3125,16 +4740,11 @@ func convert_v1beta3_EnvVarSource_To_api_EnvVarSource(in *pkgapiv1beta3.EnvVarSo return nil } -func convert_v1beta3_ListMeta_To_api_ListMeta(in *pkgapiv1beta3.ListMeta, out *pkgapi.ListMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*pkgapiv1beta3.ListMeta))(in) - } - out.SelfLink = in.SelfLink - out.ResourceVersion = in.ResourceVersion - return nil +func convert_v1beta3_EnvVarSource_To_api_EnvVarSource(in *pkgapiv1beta3.EnvVarSource, out *pkgapi.EnvVarSource, s conversion.Scope) error { + return autoconvert_v1beta3_EnvVarSource_To_api_EnvVarSource(in, out, s) } -func convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in *pkgapiv1beta3.LocalObjectReference, out *pkgapi.LocalObjectReference, s conversion.Scope) error { +func autoconvert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in *pkgapiv1beta3.LocalObjectReference, out *pkgapi.LocalObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1beta3.LocalObjectReference))(in) } @@ -3142,7 +4752,11 @@ func convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in *pkgapi return nil } -func convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(in *pkgapiv1beta3.ObjectFieldSelector, out *pkgapi.ObjectFieldSelector, s conversion.Scope) error { +func convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in *pkgapiv1beta3.LocalObjectReference, out *pkgapi.LocalObjectReference, s conversion.Scope) error { + return autoconvert_v1beta3_LocalObjectReference_To_api_LocalObjectReference(in, out, s) +} + +func autoconvert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(in *pkgapiv1beta3.ObjectFieldSelector, out *pkgapi.ObjectFieldSelector, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1beta3.ObjectFieldSelector))(in) } @@ -3151,7 +4765,11 @@ func convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(in *pkgapiv1 return nil } -func convert_v1beta3_ObjectMeta_To_api_ObjectMeta(in *pkgapiv1beta3.ObjectMeta, out *pkgapi.ObjectMeta, s conversion.Scope) error { +func convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(in *pkgapiv1beta3.ObjectFieldSelector, out *pkgapi.ObjectFieldSelector, s conversion.Scope) error { + return autoconvert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector(in, out, s) +} + +func autoconvert_v1beta3_ObjectMeta_To_api_ObjectMeta(in *pkgapiv1beta3.ObjectMeta, out *pkgapi.ObjectMeta, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1beta3.ObjectMeta))(in) } @@ -3197,7 +4815,11 @@ func convert_v1beta3_ObjectMeta_To_api_ObjectMeta(in *pkgapiv1beta3.ObjectMeta, return nil } -func convert_v1beta3_ObjectReference_To_api_ObjectReference(in *pkgapiv1beta3.ObjectReference, out *pkgapi.ObjectReference, s conversion.Scope) error { +func convert_v1beta3_ObjectMeta_To_api_ObjectMeta(in *pkgapiv1beta3.ObjectMeta, out *pkgapi.ObjectMeta, s conversion.Scope) error { + return autoconvert_v1beta3_ObjectMeta_To_api_ObjectMeta(in, out, s) +} + +func autoconvert_v1beta3_ObjectReference_To_api_ObjectReference(in *pkgapiv1beta3.ObjectReference, out *pkgapi.ObjectReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1beta3.ObjectReference))(in) } @@ -3211,7 +4833,11 @@ func convert_v1beta3_ObjectReference_To_api_ObjectReference(in *pkgapiv1beta3.Ob return nil } -func convert_v1beta3_ResourceRequirements_To_api_ResourceRequirements(in *pkgapiv1beta3.ResourceRequirements, out *pkgapi.ResourceRequirements, s conversion.Scope) error { +func convert_v1beta3_ObjectReference_To_api_ObjectReference(in *pkgapiv1beta3.ObjectReference, out *pkgapi.ObjectReference, s conversion.Scope) error { + return autoconvert_v1beta3_ObjectReference_To_api_ObjectReference(in, out, s) +} + +func autoconvert_v1beta3_ResourceRequirements_To_api_ResourceRequirements(in *pkgapiv1beta3.ResourceRequirements, out *pkgapi.ResourceRequirements, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*pkgapiv1beta3.ResourceRequirements))(in) } @@ -3242,179 +4868,220 @@ func convert_v1beta3_ResourceRequirements_To_api_ResourceRequirements(in *pkgapi return nil } -func convert_v1beta3_TypeMeta_To_api_TypeMeta(in *pkgapiv1beta3.TypeMeta, out *pkgapi.TypeMeta, s conversion.Scope) error { - if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*pkgapiv1beta3.TypeMeta))(in) - } - out.Kind = in.Kind - out.APIVersion = in.APIVersion - return nil +func convert_v1beta3_ResourceRequirements_To_api_ResourceRequirements(in *pkgapiv1beta3.ResourceRequirements, out *pkgapi.ResourceRequirements, s conversion.Scope) error { + return autoconvert_v1beta3_ResourceRequirements_To_api_ResourceRequirements(in, out, s) } func init() { err := pkgapi.Scheme.AddGeneratedConversionFuncs( - convert_api_BuildConfigList_To_v1beta3_BuildConfigList, - convert_api_BuildConfigSpec_To_v1beta3_BuildConfigSpec, - convert_api_BuildConfigStatus_To_v1beta3_BuildConfigStatus, - convert_api_BuildConfig_To_v1beta3_BuildConfig, - convert_api_BuildList_To_v1beta3_BuildList, - convert_api_BuildLogOptions_To_v1beta3_BuildLogOptions, - convert_api_BuildLog_To_v1beta3_BuildLog, - convert_api_BuildRequest_To_v1beta3_BuildRequest, - convert_api_BuildSource_To_v1beta3_BuildSource, - convert_api_BuildSpec_To_v1beta3_BuildSpec, - convert_api_BuildStatus_To_v1beta3_BuildStatus, - convert_api_BuildStrategy_To_v1beta3_BuildStrategy, - convert_api_Build_To_v1beta3_Build, - convert_api_ClusterNetworkList_To_v1beta3_ClusterNetworkList, - convert_api_ClusterNetwork_To_v1beta3_ClusterNetwork, - convert_api_ClusterPolicyBindingList_To_v1beta3_ClusterPolicyBindingList, - convert_api_ClusterPolicyList_To_v1beta3_ClusterPolicyList, - convert_api_ClusterPolicy_To_v1beta3_ClusterPolicy, - convert_api_ClusterRoleBindingList_To_v1beta3_ClusterRoleBindingList, - convert_api_ClusterRoleList_To_v1beta3_ClusterRoleList, - convert_api_ClusterRole_To_v1beta3_ClusterRole, - convert_api_DeploymentConfigList_To_v1beta3_DeploymentConfigList, - convert_api_DeploymentConfigRollbackSpec_To_v1beta3_DeploymentConfigRollbackSpec, - convert_api_DeploymentConfigRollback_To_v1beta3_DeploymentConfigRollback, - convert_api_EnvVarSource_To_v1beta3_EnvVarSource, - convert_api_EnvVar_To_v1beta3_EnvVar, - convert_api_GitBuildSource_To_v1beta3_GitBuildSource, - convert_api_GitSourceRevision_To_v1beta3_GitSourceRevision, - convert_api_GroupList_To_v1beta3_GroupList, - convert_api_Group_To_v1beta3_Group, - convert_api_HostSubnetList_To_v1beta3_HostSubnetList, - convert_api_HostSubnet_To_v1beta3_HostSubnet, - convert_api_IdentityList_To_v1beta3_IdentityList, - convert_api_Identity_To_v1beta3_Identity, - convert_api_ImageChangeTrigger_To_v1beta3_ImageChangeTrigger, - convert_api_ImageList_To_v1beta3_ImageList, - convert_api_ImageStreamList_To_v1beta3_ImageStreamList, - convert_api_IsPersonalSubjectAccessReview_To_v1beta3_IsPersonalSubjectAccessReview, - convert_api_ListMeta_To_v1beta3_ListMeta, - convert_api_LocalObjectReference_To_v1beta3_LocalObjectReference, - convert_api_NetNamespaceList_To_v1beta3_NetNamespaceList, - convert_api_NetNamespace_To_v1beta3_NetNamespace, - convert_api_OAuthAccessTokenList_To_v1beta3_OAuthAccessTokenList, - convert_api_OAuthAccessToken_To_v1beta3_OAuthAccessToken, - convert_api_OAuthAuthorizeTokenList_To_v1beta3_OAuthAuthorizeTokenList, - convert_api_OAuthAuthorizeToken_To_v1beta3_OAuthAuthorizeToken, - convert_api_OAuthClientAuthorizationList_To_v1beta3_OAuthClientAuthorizationList, - convert_api_OAuthClientAuthorization_To_v1beta3_OAuthClientAuthorization, - convert_api_OAuthClientList_To_v1beta3_OAuthClientList, - convert_api_OAuthClient_To_v1beta3_OAuthClient, - convert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector, - convert_api_ObjectMeta_To_v1beta3_ObjectMeta, - convert_api_ObjectReference_To_v1beta3_ObjectReference, - convert_api_Parameter_To_v1beta3_Parameter, - convert_api_PolicyBindingList_To_v1beta3_PolicyBindingList, - convert_api_PolicyList_To_v1beta3_PolicyList, - convert_api_ProjectList_To_v1beta3_ProjectList, - convert_api_ProjectRequest_To_v1beta3_ProjectRequest, - convert_api_ProjectSpec_To_v1beta3_ProjectSpec, - convert_api_ProjectStatus_To_v1beta3_ProjectStatus, - convert_api_Project_To_v1beta3_Project, - convert_api_ResourceRequirements_To_v1beta3_ResourceRequirements, - convert_api_RoleBindingList_To_v1beta3_RoleBindingList, - convert_api_RoleList_To_v1beta3_RoleList, - convert_api_Role_To_v1beta3_Role, - convert_api_RouteList_To_v1beta3_RouteList, - convert_api_RoutePort_To_v1beta3_RoutePort, - convert_api_RouteSpec_To_v1beta3_RouteSpec, - convert_api_RouteStatus_To_v1beta3_RouteStatus, - convert_api_Route_To_v1beta3_Route, - convert_api_SecretSpec_To_v1beta3_SecretSpec, - convert_api_SourceControlUser_To_v1beta3_SourceControlUser, - convert_api_SourceRevision_To_v1beta3_SourceRevision, - convert_api_SubjectAccessReviewResponse_To_v1beta3_SubjectAccessReviewResponse, - convert_api_TLSConfig_To_v1beta3_TLSConfig, - convert_api_TemplateList_To_v1beta3_TemplateList, - convert_api_TypeMeta_To_v1beta3_TypeMeta, - convert_api_UserIdentityMapping_To_v1beta3_UserIdentityMapping, - convert_api_UserList_To_v1beta3_UserList, - convert_api_User_To_v1beta3_User, - convert_api_WebHookTrigger_To_v1beta3_WebHookTrigger, - convert_v1beta3_BuildConfigList_To_api_BuildConfigList, - convert_v1beta3_BuildConfigSpec_To_api_BuildConfigSpec, - convert_v1beta3_BuildConfigStatus_To_api_BuildConfigStatus, - convert_v1beta3_BuildConfig_To_api_BuildConfig, - convert_v1beta3_BuildList_To_api_BuildList, - convert_v1beta3_BuildLogOptions_To_api_BuildLogOptions, - convert_v1beta3_BuildLog_To_api_BuildLog, - convert_v1beta3_BuildRequest_To_api_BuildRequest, - convert_v1beta3_BuildSource_To_api_BuildSource, - convert_v1beta3_BuildSpec_To_api_BuildSpec, - convert_v1beta3_BuildStatus_To_api_BuildStatus, - convert_v1beta3_BuildStrategy_To_api_BuildStrategy, - convert_v1beta3_Build_To_api_Build, - convert_v1beta3_ClusterNetworkList_To_api_ClusterNetworkList, - convert_v1beta3_ClusterNetwork_To_api_ClusterNetwork, - convert_v1beta3_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList, - convert_v1beta3_ClusterPolicyList_To_api_ClusterPolicyList, - convert_v1beta3_ClusterPolicy_To_api_ClusterPolicy, - convert_v1beta3_ClusterRoleBindingList_To_api_ClusterRoleBindingList, - convert_v1beta3_ClusterRoleList_To_api_ClusterRoleList, - convert_v1beta3_ClusterRole_To_api_ClusterRole, - convert_v1beta3_DeploymentConfigList_To_api_DeploymentConfigList, - convert_v1beta3_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec, - convert_v1beta3_DeploymentConfigRollback_To_api_DeploymentConfigRollback, - convert_v1beta3_EnvVarSource_To_api_EnvVarSource, - convert_v1beta3_EnvVar_To_api_EnvVar, - convert_v1beta3_GitBuildSource_To_api_GitBuildSource, - convert_v1beta3_GitSourceRevision_To_api_GitSourceRevision, - convert_v1beta3_GroupList_To_api_GroupList, - convert_v1beta3_Group_To_api_Group, - convert_v1beta3_HostSubnetList_To_api_HostSubnetList, - convert_v1beta3_HostSubnet_To_api_HostSubnet, - convert_v1beta3_IdentityList_To_api_IdentityList, - convert_v1beta3_Identity_To_api_Identity, - convert_v1beta3_ImageChangeTrigger_To_api_ImageChangeTrigger, - convert_v1beta3_ImageList_To_api_ImageList, - convert_v1beta3_ImageStreamList_To_api_ImageStreamList, - convert_v1beta3_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview, - convert_v1beta3_ListMeta_To_api_ListMeta, - convert_v1beta3_LocalObjectReference_To_api_LocalObjectReference, - convert_v1beta3_NetNamespaceList_To_api_NetNamespaceList, - convert_v1beta3_NetNamespace_To_api_NetNamespace, - convert_v1beta3_OAuthAccessTokenList_To_api_OAuthAccessTokenList, - convert_v1beta3_OAuthAccessToken_To_api_OAuthAccessToken, - convert_v1beta3_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList, - convert_v1beta3_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken, - convert_v1beta3_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList, - convert_v1beta3_OAuthClientAuthorization_To_api_OAuthClientAuthorization, - convert_v1beta3_OAuthClientList_To_api_OAuthClientList, - convert_v1beta3_OAuthClient_To_api_OAuthClient, - convert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector, - convert_v1beta3_ObjectMeta_To_api_ObjectMeta, - convert_v1beta3_ObjectReference_To_api_ObjectReference, - convert_v1beta3_Parameter_To_api_Parameter, - convert_v1beta3_PolicyBindingList_To_api_PolicyBindingList, - convert_v1beta3_PolicyList_To_api_PolicyList, - convert_v1beta3_ProjectList_To_api_ProjectList, - convert_v1beta3_ProjectRequest_To_api_ProjectRequest, - convert_v1beta3_ProjectSpec_To_api_ProjectSpec, - convert_v1beta3_ProjectStatus_To_api_ProjectStatus, - convert_v1beta3_Project_To_api_Project, - convert_v1beta3_ResourceRequirements_To_api_ResourceRequirements, - convert_v1beta3_RoleBindingList_To_api_RoleBindingList, - convert_v1beta3_RoleList_To_api_RoleList, - convert_v1beta3_Role_To_api_Role, - convert_v1beta3_RouteList_To_api_RouteList, - convert_v1beta3_RoutePort_To_api_RoutePort, - convert_v1beta3_RouteSpec_To_api_RouteSpec, - convert_v1beta3_RouteStatus_To_api_RouteStatus, - convert_v1beta3_Route_To_api_Route, - convert_v1beta3_SecretSpec_To_api_SecretSpec, - convert_v1beta3_SourceControlUser_To_api_SourceControlUser, - convert_v1beta3_SourceRevision_To_api_SourceRevision, - convert_v1beta3_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse, - convert_v1beta3_TLSConfig_To_api_TLSConfig, - convert_v1beta3_TemplateList_To_api_TemplateList, - convert_v1beta3_TypeMeta_To_api_TypeMeta, - convert_v1beta3_UserIdentityMapping_To_api_UserIdentityMapping, - convert_v1beta3_UserList_To_api_UserList, - convert_v1beta3_User_To_api_User, - convert_v1beta3_WebHookTrigger_To_api_WebHookTrigger, + autoconvert_api_BuildConfigList_To_v1beta3_BuildConfigList, + autoconvert_api_BuildConfigSpec_To_v1beta3_BuildConfigSpec, + autoconvert_api_BuildConfigStatus_To_v1beta3_BuildConfigStatus, + autoconvert_api_BuildConfig_To_v1beta3_BuildConfig, + autoconvert_api_BuildList_To_v1beta3_BuildList, + autoconvert_api_BuildLogOptions_To_v1beta3_BuildLogOptions, + autoconvert_api_BuildLog_To_v1beta3_BuildLog, + autoconvert_api_BuildOutput_To_v1beta3_BuildOutput, + autoconvert_api_BuildRequest_To_v1beta3_BuildRequest, + autoconvert_api_BuildSource_To_v1beta3_BuildSource, + autoconvert_api_BuildSpec_To_v1beta3_BuildSpec, + autoconvert_api_BuildStatus_To_v1beta3_BuildStatus, + autoconvert_api_BuildStrategy_To_v1beta3_BuildStrategy, + autoconvert_api_BuildTriggerPolicy_To_v1beta3_BuildTriggerPolicy, + autoconvert_api_Build_To_v1beta3_Build, + autoconvert_api_ClusterNetworkList_To_v1beta3_ClusterNetworkList, + autoconvert_api_ClusterNetwork_To_v1beta3_ClusterNetwork, + autoconvert_api_ClusterPolicyBindingList_To_v1beta3_ClusterPolicyBindingList, + autoconvert_api_ClusterPolicyBinding_To_v1beta3_ClusterPolicyBinding, + autoconvert_api_ClusterPolicyList_To_v1beta3_ClusterPolicyList, + autoconvert_api_ClusterPolicy_To_v1beta3_ClusterPolicy, + autoconvert_api_ClusterRoleBindingList_To_v1beta3_ClusterRoleBindingList, + autoconvert_api_ClusterRoleBinding_To_v1beta3_ClusterRoleBinding, + autoconvert_api_ClusterRoleList_To_v1beta3_ClusterRoleList, + autoconvert_api_ClusterRole_To_v1beta3_ClusterRole, + autoconvert_api_CustomBuildStrategy_To_v1beta3_CustomBuildStrategy, + autoconvert_api_DeploymentConfigList_To_v1beta3_DeploymentConfigList, + autoconvert_api_DeploymentConfigRollbackSpec_To_v1beta3_DeploymentConfigRollbackSpec, + autoconvert_api_DeploymentConfigRollback_To_v1beta3_DeploymentConfigRollback, + autoconvert_api_DeploymentConfig_To_v1beta3_DeploymentConfig, + autoconvert_api_DockerBuildStrategy_To_v1beta3_DockerBuildStrategy, + autoconvert_api_EnvVarSource_To_v1beta3_EnvVarSource, + autoconvert_api_EnvVar_To_v1beta3_EnvVar, + autoconvert_api_GitBuildSource_To_v1beta3_GitBuildSource, + autoconvert_api_GitSourceRevision_To_v1beta3_GitSourceRevision, + autoconvert_api_GroupList_To_v1beta3_GroupList, + autoconvert_api_Group_To_v1beta3_Group, + autoconvert_api_HostSubnetList_To_v1beta3_HostSubnetList, + autoconvert_api_HostSubnet_To_v1beta3_HostSubnet, + autoconvert_api_IdentityList_To_v1beta3_IdentityList, + autoconvert_api_Identity_To_v1beta3_Identity, + autoconvert_api_ImageChangeTrigger_To_v1beta3_ImageChangeTrigger, + autoconvert_api_ImageList_To_v1beta3_ImageList, + autoconvert_api_ImageStreamImage_To_v1beta3_ImageStreamImage, + autoconvert_api_ImageStreamList_To_v1beta3_ImageStreamList, + autoconvert_api_ImageStreamMapping_To_v1beta3_ImageStreamMapping, + autoconvert_api_ImageStreamSpec_To_v1beta3_ImageStreamSpec, + autoconvert_api_ImageStreamStatus_To_v1beta3_ImageStreamStatus, + autoconvert_api_ImageStreamTag_To_v1beta3_ImageStreamTag, + autoconvert_api_ImageStream_To_v1beta3_ImageStream, + autoconvert_api_Image_To_v1beta3_Image, + autoconvert_api_IsPersonalSubjectAccessReview_To_v1beta3_IsPersonalSubjectAccessReview, + autoconvert_api_LocalObjectReference_To_v1beta3_LocalObjectReference, + autoconvert_api_LocalResourceAccessReview_To_v1beta3_LocalResourceAccessReview, + autoconvert_api_LocalSubjectAccessReview_To_v1beta3_LocalSubjectAccessReview, + autoconvert_api_NetNamespaceList_To_v1beta3_NetNamespaceList, + autoconvert_api_NetNamespace_To_v1beta3_NetNamespace, + autoconvert_api_OAuthAccessTokenList_To_v1beta3_OAuthAccessTokenList, + autoconvert_api_OAuthAccessToken_To_v1beta3_OAuthAccessToken, + autoconvert_api_OAuthAuthorizeTokenList_To_v1beta3_OAuthAuthorizeTokenList, + autoconvert_api_OAuthAuthorizeToken_To_v1beta3_OAuthAuthorizeToken, + autoconvert_api_OAuthClientAuthorizationList_To_v1beta3_OAuthClientAuthorizationList, + autoconvert_api_OAuthClientAuthorization_To_v1beta3_OAuthClientAuthorization, + autoconvert_api_OAuthClientList_To_v1beta3_OAuthClientList, + autoconvert_api_OAuthClient_To_v1beta3_OAuthClient, + autoconvert_api_ObjectFieldSelector_To_v1beta3_ObjectFieldSelector, + autoconvert_api_ObjectMeta_To_v1beta3_ObjectMeta, + autoconvert_api_ObjectReference_To_v1beta3_ObjectReference, + autoconvert_api_Parameter_To_v1beta3_Parameter, + autoconvert_api_PolicyBindingList_To_v1beta3_PolicyBindingList, + autoconvert_api_PolicyBinding_To_v1beta3_PolicyBinding, + autoconvert_api_PolicyList_To_v1beta3_PolicyList, + autoconvert_api_PolicyRule_To_v1beta3_PolicyRule, + autoconvert_api_Policy_To_v1beta3_Policy, + autoconvert_api_ProjectList_To_v1beta3_ProjectList, + autoconvert_api_ProjectRequest_To_v1beta3_ProjectRequest, + autoconvert_api_ProjectSpec_To_v1beta3_ProjectSpec, + autoconvert_api_ProjectStatus_To_v1beta3_ProjectStatus, + autoconvert_api_Project_To_v1beta3_Project, + autoconvert_api_ResourceAccessReviewResponse_To_v1beta3_ResourceAccessReviewResponse, + autoconvert_api_ResourceAccessReview_To_v1beta3_ResourceAccessReview, + autoconvert_api_ResourceRequirements_To_v1beta3_ResourceRequirements, + autoconvert_api_RoleBindingList_To_v1beta3_RoleBindingList, + autoconvert_api_RoleBinding_To_v1beta3_RoleBinding, + autoconvert_api_RoleList_To_v1beta3_RoleList, + autoconvert_api_Role_To_v1beta3_Role, + autoconvert_api_RouteList_To_v1beta3_RouteList, + autoconvert_api_RoutePort_To_v1beta3_RoutePort, + autoconvert_api_RouteSpec_To_v1beta3_RouteSpec, + autoconvert_api_RouteStatus_To_v1beta3_RouteStatus, + autoconvert_api_Route_To_v1beta3_Route, + autoconvert_api_SecretSpec_To_v1beta3_SecretSpec, + autoconvert_api_SourceBuildStrategy_To_v1beta3_SourceBuildStrategy, + autoconvert_api_SourceControlUser_To_v1beta3_SourceControlUser, + autoconvert_api_SourceRevision_To_v1beta3_SourceRevision, + autoconvert_api_SubjectAccessReviewResponse_To_v1beta3_SubjectAccessReviewResponse, + autoconvert_api_SubjectAccessReview_To_v1beta3_SubjectAccessReview, + autoconvert_api_TLSConfig_To_v1beta3_TLSConfig, + autoconvert_api_TemplateList_To_v1beta3_TemplateList, + autoconvert_api_Template_To_v1beta3_Template, + autoconvert_api_UserIdentityMapping_To_v1beta3_UserIdentityMapping, + autoconvert_api_UserList_To_v1beta3_UserList, + autoconvert_api_User_To_v1beta3_User, + autoconvert_api_WebHookTrigger_To_v1beta3_WebHookTrigger, + autoconvert_v1beta3_BuildConfigList_To_api_BuildConfigList, + autoconvert_v1beta3_BuildConfigSpec_To_api_BuildConfigSpec, + autoconvert_v1beta3_BuildConfigStatus_To_api_BuildConfigStatus, + autoconvert_v1beta3_BuildConfig_To_api_BuildConfig, + autoconvert_v1beta3_BuildList_To_api_BuildList, + autoconvert_v1beta3_BuildLogOptions_To_api_BuildLogOptions, + autoconvert_v1beta3_BuildLog_To_api_BuildLog, + autoconvert_v1beta3_BuildOutput_To_api_BuildOutput, + autoconvert_v1beta3_BuildRequest_To_api_BuildRequest, + autoconvert_v1beta3_BuildSource_To_api_BuildSource, + autoconvert_v1beta3_BuildSpec_To_api_BuildSpec, + autoconvert_v1beta3_BuildStatus_To_api_BuildStatus, + autoconvert_v1beta3_BuildStrategy_To_api_BuildStrategy, + autoconvert_v1beta3_BuildTriggerPolicy_To_api_BuildTriggerPolicy, + autoconvert_v1beta3_Build_To_api_Build, + autoconvert_v1beta3_ClusterNetworkList_To_api_ClusterNetworkList, + autoconvert_v1beta3_ClusterNetwork_To_api_ClusterNetwork, + autoconvert_v1beta3_ClusterPolicyBindingList_To_api_ClusterPolicyBindingList, + autoconvert_v1beta3_ClusterPolicyBinding_To_api_ClusterPolicyBinding, + autoconvert_v1beta3_ClusterPolicyList_To_api_ClusterPolicyList, + autoconvert_v1beta3_ClusterPolicy_To_api_ClusterPolicy, + autoconvert_v1beta3_ClusterRoleBindingList_To_api_ClusterRoleBindingList, + autoconvert_v1beta3_ClusterRoleBinding_To_api_ClusterRoleBinding, + autoconvert_v1beta3_ClusterRoleList_To_api_ClusterRoleList, + autoconvert_v1beta3_ClusterRole_To_api_ClusterRole, + autoconvert_v1beta3_CustomBuildStrategy_To_api_CustomBuildStrategy, + autoconvert_v1beta3_DeploymentConfigList_To_api_DeploymentConfigList, + autoconvert_v1beta3_DeploymentConfigRollbackSpec_To_api_DeploymentConfigRollbackSpec, + autoconvert_v1beta3_DeploymentConfigRollback_To_api_DeploymentConfigRollback, + autoconvert_v1beta3_DeploymentConfig_To_api_DeploymentConfig, + autoconvert_v1beta3_DockerBuildStrategy_To_api_DockerBuildStrategy, + autoconvert_v1beta3_EnvVarSource_To_api_EnvVarSource, + autoconvert_v1beta3_EnvVar_To_api_EnvVar, + autoconvert_v1beta3_GitBuildSource_To_api_GitBuildSource, + autoconvert_v1beta3_GitSourceRevision_To_api_GitSourceRevision, + autoconvert_v1beta3_GroupList_To_api_GroupList, + autoconvert_v1beta3_Group_To_api_Group, + autoconvert_v1beta3_HostSubnetList_To_api_HostSubnetList, + autoconvert_v1beta3_HostSubnet_To_api_HostSubnet, + autoconvert_v1beta3_IdentityList_To_api_IdentityList, + autoconvert_v1beta3_Identity_To_api_Identity, + autoconvert_v1beta3_ImageChangeTrigger_To_api_ImageChangeTrigger, + autoconvert_v1beta3_ImageList_To_api_ImageList, + autoconvert_v1beta3_ImageStreamImage_To_api_ImageStreamImage, + autoconvert_v1beta3_ImageStreamList_To_api_ImageStreamList, + autoconvert_v1beta3_ImageStreamMapping_To_api_ImageStreamMapping, + autoconvert_v1beta3_ImageStreamSpec_To_api_ImageStreamSpec, + autoconvert_v1beta3_ImageStreamStatus_To_api_ImageStreamStatus, + autoconvert_v1beta3_ImageStreamTag_To_api_ImageStreamTag, + autoconvert_v1beta3_ImageStream_To_api_ImageStream, + autoconvert_v1beta3_Image_To_api_Image, + autoconvert_v1beta3_IsPersonalSubjectAccessReview_To_api_IsPersonalSubjectAccessReview, + autoconvert_v1beta3_LocalObjectReference_To_api_LocalObjectReference, + autoconvert_v1beta3_LocalResourceAccessReview_To_api_LocalResourceAccessReview, + autoconvert_v1beta3_LocalSubjectAccessReview_To_api_LocalSubjectAccessReview, + autoconvert_v1beta3_NetNamespaceList_To_api_NetNamespaceList, + autoconvert_v1beta3_NetNamespace_To_api_NetNamespace, + autoconvert_v1beta3_OAuthAccessTokenList_To_api_OAuthAccessTokenList, + autoconvert_v1beta3_OAuthAccessToken_To_api_OAuthAccessToken, + autoconvert_v1beta3_OAuthAuthorizeTokenList_To_api_OAuthAuthorizeTokenList, + autoconvert_v1beta3_OAuthAuthorizeToken_To_api_OAuthAuthorizeToken, + autoconvert_v1beta3_OAuthClientAuthorizationList_To_api_OAuthClientAuthorizationList, + autoconvert_v1beta3_OAuthClientAuthorization_To_api_OAuthClientAuthorization, + autoconvert_v1beta3_OAuthClientList_To_api_OAuthClientList, + autoconvert_v1beta3_OAuthClient_To_api_OAuthClient, + autoconvert_v1beta3_ObjectFieldSelector_To_api_ObjectFieldSelector, + autoconvert_v1beta3_ObjectMeta_To_api_ObjectMeta, + autoconvert_v1beta3_ObjectReference_To_api_ObjectReference, + autoconvert_v1beta3_Parameter_To_api_Parameter, + autoconvert_v1beta3_PolicyBindingList_To_api_PolicyBindingList, + autoconvert_v1beta3_PolicyBinding_To_api_PolicyBinding, + autoconvert_v1beta3_PolicyList_To_api_PolicyList, + autoconvert_v1beta3_PolicyRule_To_api_PolicyRule, + autoconvert_v1beta3_Policy_To_api_Policy, + autoconvert_v1beta3_ProjectList_To_api_ProjectList, + autoconvert_v1beta3_ProjectRequest_To_api_ProjectRequest, + autoconvert_v1beta3_ProjectSpec_To_api_ProjectSpec, + autoconvert_v1beta3_ProjectStatus_To_api_ProjectStatus, + autoconvert_v1beta3_Project_To_api_Project, + autoconvert_v1beta3_ResourceAccessReviewResponse_To_api_ResourceAccessReviewResponse, + autoconvert_v1beta3_ResourceAccessReview_To_api_ResourceAccessReview, + autoconvert_v1beta3_ResourceRequirements_To_api_ResourceRequirements, + autoconvert_v1beta3_RoleBindingList_To_api_RoleBindingList, + autoconvert_v1beta3_RoleBinding_To_api_RoleBinding, + autoconvert_v1beta3_RoleList_To_api_RoleList, + autoconvert_v1beta3_Role_To_api_Role, + autoconvert_v1beta3_RouteList_To_api_RouteList, + autoconvert_v1beta3_RoutePort_To_api_RoutePort, + autoconvert_v1beta3_RouteSpec_To_api_RouteSpec, + autoconvert_v1beta3_RouteStatus_To_api_RouteStatus, + autoconvert_v1beta3_Route_To_api_Route, + autoconvert_v1beta3_SecretSpec_To_api_SecretSpec, + autoconvert_v1beta3_SourceBuildStrategy_To_api_SourceBuildStrategy, + autoconvert_v1beta3_SourceControlUser_To_api_SourceControlUser, + autoconvert_v1beta3_SourceRevision_To_api_SourceRevision, + autoconvert_v1beta3_SubjectAccessReviewResponse_To_api_SubjectAccessReviewResponse, + autoconvert_v1beta3_SubjectAccessReview_To_api_SubjectAccessReview, + autoconvert_v1beta3_TLSConfig_To_api_TLSConfig, + autoconvert_v1beta3_TemplateList_To_api_TemplateList, + autoconvert_v1beta3_Template_To_api_Template, + autoconvert_v1beta3_UserIdentityMapping_To_api_UserIdentityMapping, + autoconvert_v1beta3_UserList_To_api_UserList, + autoconvert_v1beta3_User_To_api_User, + autoconvert_v1beta3_WebHookTrigger_To_api_WebHookTrigger, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. diff --git a/pkg/api/v1beta3/deep_copy_generated.go b/pkg/api/v1beta3/deep_copy_generated.go index fec3053a1ce9..e1c0ef52187d 100644 --- a/pkg/api/v1beta3/deep_copy_generated.go +++ b/pkg/api/v1beta3/deep_copy_generated.go @@ -13,6 +13,7 @@ import ( templateapiv1beta3 "github.com/openshift/origin/pkg/template/api/v1beta3" userapiv1beta3 "github.com/openshift/origin/pkg/user/api/v1beta3" api "k8s.io/kubernetes/pkg/api" + unversioned "k8s.io/kubernetes/pkg/api/unversioned" pkgapiv1beta3 "k8s.io/kubernetes/pkg/api/v1beta3" conversion "k8s.io/kubernetes/pkg/conversion" runtime "k8s.io/kubernetes/pkg/runtime" @@ -36,7 +37,7 @@ func deepCopy_v1beta3_ClusterPolicy(in v1beta3.ClusterPolicy, out *v1beta3.Clust if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -46,7 +47,7 @@ func deepCopy_v1beta3_ClusterPolicy(in v1beta3.ClusterPolicy, out *v1beta3.Clust if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if in.Roles != nil { out.Roles = make([]v1beta3.NamedClusterRole, len(in.Roles)) @@ -65,7 +66,7 @@ func deepCopy_v1beta3_ClusterPolicyBinding(in v1beta3.ClusterPolicyBinding, out if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -75,7 +76,7 @@ func deepCopy_v1beta3_ClusterPolicyBinding(in v1beta3.ClusterPolicyBinding, out if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if newVal, err := c.DeepCopy(in.PolicyRef); err != nil { return err @@ -99,12 +100,12 @@ func deepCopy_v1beta3_ClusterPolicyBindingList(in v1beta3.ClusterPolicyBindingLi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1beta3.ClusterPolicyBinding, len(in.Items)) @@ -123,12 +124,12 @@ func deepCopy_v1beta3_ClusterPolicyList(in v1beta3.ClusterPolicyList, out *v1bet if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1beta3.ClusterPolicy, len(in.Items)) @@ -147,7 +148,7 @@ func deepCopy_v1beta3_ClusterRole(in v1beta3.ClusterRole, out *v1beta3.ClusterRo if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -171,7 +172,7 @@ func deepCopy_v1beta3_ClusterRoleBinding(in v1beta3.ClusterRoleBinding, out *v1b if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -218,12 +219,12 @@ func deepCopy_v1beta3_ClusterRoleBindingList(in v1beta3.ClusterRoleBindingList, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1beta3.ClusterRoleBinding, len(in.Items)) @@ -242,12 +243,12 @@ func deepCopy_v1beta3_ClusterRoleList(in v1beta3.ClusterRoleList, out *v1beta3.C if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1beta3.ClusterRole, len(in.Items)) @@ -266,7 +267,7 @@ func deepCopy_v1beta3_IsPersonalSubjectAccessReview(in v1beta3.IsPersonalSubject if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } return nil } @@ -275,7 +276,7 @@ func deepCopy_v1beta3_LocalResourceAccessReview(in v1beta3.LocalResourceAccessRe if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_v1beta3_AuthorizationAttributes(in.AuthorizationAttributes, &out.AuthorizationAttributes, c); err != nil { return err @@ -287,7 +288,7 @@ func deepCopy_v1beta3_LocalSubjectAccessReview(in v1beta3.LocalSubjectAccessRevi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_v1beta3_AuthorizationAttributes(in.AuthorizationAttributes, &out.AuthorizationAttributes, c); err != nil { return err @@ -340,7 +341,7 @@ func deepCopy_v1beta3_Policy(in v1beta3.Policy, out *v1beta3.Policy, c *conversi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -350,7 +351,7 @@ func deepCopy_v1beta3_Policy(in v1beta3.Policy, out *v1beta3.Policy, c *conversi if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if in.Roles != nil { out.Roles = make([]v1beta3.NamedRole, len(in.Roles)) @@ -369,7 +370,7 @@ func deepCopy_v1beta3_PolicyBinding(in v1beta3.PolicyBinding, out *v1beta3.Polic if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -379,7 +380,7 @@ func deepCopy_v1beta3_PolicyBinding(in v1beta3.PolicyBinding, out *v1beta3.Polic if newVal, err := c.DeepCopy(in.LastModified); err != nil { return err } else { - out.LastModified = newVal.(util.Time) + out.LastModified = newVal.(unversioned.Time) } if newVal, err := c.DeepCopy(in.PolicyRef); err != nil { return err @@ -403,12 +404,12 @@ func deepCopy_v1beta3_PolicyBindingList(in v1beta3.PolicyBindingList, out *v1bet if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1beta3.PolicyBinding, len(in.Items)) @@ -427,12 +428,12 @@ func deepCopy_v1beta3_PolicyList(in v1beta3.PolicyList, out *v1beta3.PolicyList, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1beta3.Policy, len(in.Items)) @@ -508,7 +509,7 @@ func deepCopy_v1beta3_ResourceAccessReview(in v1beta3.ResourceAccessReview, out if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_v1beta3_AuthorizationAttributes(in.AuthorizationAttributes, &out.AuthorizationAttributes, c); err != nil { return err @@ -520,7 +521,7 @@ func deepCopy_v1beta3_ResourceAccessReviewResponse(in v1beta3.ResourceAccessRevi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } out.Namespace = in.Namespace if in.UsersSlice != nil { @@ -546,7 +547,7 @@ func deepCopy_v1beta3_Role(in v1beta3.Role, out *v1beta3.Role, c *conversion.Clo if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -570,7 +571,7 @@ func deepCopy_v1beta3_RoleBinding(in v1beta3.RoleBinding, out *v1beta3.RoleBindi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -617,12 +618,12 @@ func deepCopy_v1beta3_RoleBindingList(in v1beta3.RoleBindingList, out *v1beta3.R if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1beta3.RoleBinding, len(in.Items)) @@ -641,12 +642,12 @@ func deepCopy_v1beta3_RoleList(in v1beta3.RoleList, out *v1beta3.RoleList, c *co if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]v1beta3.Role, len(in.Items)) @@ -665,7 +666,7 @@ func deepCopy_v1beta3_SubjectAccessReview(in v1beta3.SubjectAccessReview, out *v if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_v1beta3_AuthorizationAttributes(in.AuthorizationAttributes, &out.AuthorizationAttributes, c); err != nil { return err @@ -686,7 +687,7 @@ func deepCopy_v1beta3_SubjectAccessReviewResponse(in v1beta3.SubjectAccessReview if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } out.Namespace = in.Namespace out.Allowed = in.Allowed @@ -698,7 +699,7 @@ func deepCopy_v1beta3_Build(in apiv1beta3.Build, out *apiv1beta3.Build, c *conve if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -718,7 +719,7 @@ func deepCopy_v1beta3_BuildConfig(in apiv1beta3.BuildConfig, out *apiv1beta3.Bui if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -738,12 +739,12 @@ func deepCopy_v1beta3_BuildConfigList(in apiv1beta3.BuildConfigList, out *apiv1b if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]apiv1beta3.BuildConfig, len(in.Items)) @@ -784,12 +785,12 @@ func deepCopy_v1beta3_BuildList(in apiv1beta3.BuildList, out *apiv1beta3.BuildLi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]apiv1beta3.Build, len(in.Items)) @@ -808,12 +809,12 @@ func deepCopy_v1beta3_BuildLog(in apiv1beta3.BuildLog, out *apiv1beta3.BuildLog, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } return nil } @@ -822,7 +823,7 @@ func deepCopy_v1beta3_BuildLogOptions(in apiv1beta3.BuildLogOptions, out *apiv1b if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } out.Follow = in.Follow out.NoWait = in.NoWait @@ -855,7 +856,7 @@ func deepCopy_v1beta3_BuildRequest(in apiv1beta3.BuildRequest, out *apiv1beta3.B if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -967,7 +968,7 @@ func deepCopy_v1beta3_BuildStatus(in apiv1beta3.BuildStatus, out *apiv1beta3.Bui if newVal, err := c.DeepCopy(in.StartTimestamp); err != nil { return err } else { - out.StartTimestamp = newVal.(*util.Time) + out.StartTimestamp = newVal.(*unversioned.Time) } } else { out.StartTimestamp = nil @@ -976,7 +977,7 @@ func deepCopy_v1beta3_BuildStatus(in apiv1beta3.BuildStatus, out *apiv1beta3.Bui if newVal, err := c.DeepCopy(in.CompletionTimestamp); err != nil { return err } else { - out.CompletionTimestamp = newVal.(*util.Time) + out.CompletionTimestamp = newVal.(*unversioned.Time) } } else { out.CompletionTimestamp = nil @@ -1283,7 +1284,7 @@ func deepCopy_v1beta3_DeploymentConfig(in deployapiv1beta3.DeploymentConfig, out if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1303,12 +1304,12 @@ func deepCopy_v1beta3_DeploymentConfigList(in deployapiv1beta3.DeploymentConfigL if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]deployapiv1beta3.DeploymentConfig, len(in.Items)) @@ -1327,7 +1328,7 @@ func deepCopy_v1beta3_DeploymentConfigRollback(in deployapiv1beta3.DeploymentCon if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if err := deepCopy_v1beta3_DeploymentConfigRollbackSpec(in.Spec, &out.Spec, c); err != nil { return err @@ -1613,7 +1614,7 @@ func deepCopy_v1beta3_Image(in imageapiv1beta3.Image, out *imageapiv1beta3.Image if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1635,12 +1636,12 @@ func deepCopy_v1beta3_ImageList(in imageapiv1beta3.ImageList, out *imageapiv1bet if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]imageapiv1beta3.Image, len(in.Items)) @@ -1659,7 +1660,7 @@ func deepCopy_v1beta3_ImageStream(in imageapiv1beta3.ImageStream, out *imageapiv if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1687,12 +1688,12 @@ func deepCopy_v1beta3_ImageStreamList(in imageapiv1beta3.ImageStreamList, out *i if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]imageapiv1beta3.ImageStream, len(in.Items)) @@ -1711,7 +1712,7 @@ func deepCopy_v1beta3_ImageStreamMapping(in imageapiv1beta3.ImageStreamMapping, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1804,7 +1805,7 @@ func deepCopy_v1beta3_TagEvent(in imageapiv1beta3.TagEvent, out *imageapiv1beta3 if newVal, err := c.DeepCopy(in.Created); err != nil { return err } else { - out.Created = newVal.(util.Time) + out.Created = newVal.(unversioned.Time) } out.DockerImageReference = in.DockerImageReference out.Image = in.Image @@ -1815,7 +1816,7 @@ func deepCopy_v1beta3_OAuthAccessToken(in oauthapiv1beta3.OAuthAccessToken, out if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1844,12 +1845,12 @@ func deepCopy_v1beta3_OAuthAccessTokenList(in oauthapiv1beta3.OAuthAccessTokenLi if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapiv1beta3.OAuthAccessToken, len(in.Items)) @@ -1868,7 +1869,7 @@ func deepCopy_v1beta3_OAuthAuthorizeToken(in oauthapiv1beta3.OAuthAuthorizeToken if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1896,12 +1897,12 @@ func deepCopy_v1beta3_OAuthAuthorizeTokenList(in oauthapiv1beta3.OAuthAuthorizeT if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapiv1beta3.OAuthAuthorizeToken, len(in.Items)) @@ -1920,7 +1921,7 @@ func deepCopy_v1beta3_OAuthClient(in oauthapiv1beta3.OAuthClient, out *oauthapiv if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1944,7 +1945,7 @@ func deepCopy_v1beta3_OAuthClientAuthorization(in oauthapiv1beta3.OAuthClientAut if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -1969,12 +1970,12 @@ func deepCopy_v1beta3_OAuthClientAuthorizationList(in oauthapiv1beta3.OAuthClien if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapiv1beta3.OAuthClientAuthorization, len(in.Items)) @@ -1993,12 +1994,12 @@ func deepCopy_v1beta3_OAuthClientList(in oauthapiv1beta3.OAuthClientList, out *o if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]oauthapiv1beta3.OAuthClient, len(in.Items)) @@ -2017,7 +2018,7 @@ func deepCopy_v1beta3_Project(in projectapiv1beta3.Project, out *projectapiv1bet if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2037,12 +2038,12 @@ func deepCopy_v1beta3_ProjectList(in projectapiv1beta3.ProjectList, out *project if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]projectapiv1beta3.Project, len(in.Items)) @@ -2061,7 +2062,7 @@ func deepCopy_v1beta3_ProjectRequest(in projectapiv1beta3.ProjectRequest, out *p if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2094,7 +2095,7 @@ func deepCopy_v1beta3_Route(in routeapiv1beta3.Route, out *routeapiv1beta3.Route if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2114,12 +2115,12 @@ func deepCopy_v1beta3_RouteList(in routeapiv1beta3.RouteList, out *routeapiv1bet if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]routeapiv1beta3.Route, len(in.Items)) @@ -2187,7 +2188,7 @@ func deepCopy_v1beta3_ClusterNetwork(in sdnapiv1beta3.ClusterNetwork, out *sdnap if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2204,12 +2205,12 @@ func deepCopy_v1beta3_ClusterNetworkList(in sdnapiv1beta3.ClusterNetworkList, ou if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]sdnapiv1beta3.ClusterNetwork, len(in.Items)) @@ -2228,7 +2229,7 @@ func deepCopy_v1beta3_HostSubnet(in sdnapiv1beta3.HostSubnet, out *sdnapiv1beta3 if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2245,12 +2246,12 @@ func deepCopy_v1beta3_HostSubnetList(in sdnapiv1beta3.HostSubnetList, out *sdnap if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]sdnapiv1beta3.HostSubnet, len(in.Items)) @@ -2269,7 +2270,7 @@ func deepCopy_v1beta3_NetNamespace(in sdnapiv1beta3.NetNamespace, out *sdnapiv1b if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2285,12 +2286,12 @@ func deepCopy_v1beta3_NetNamespaceList(in sdnapiv1beta3.NetNamespaceList, out *s if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]sdnapiv1beta3.NetNamespace, len(in.Items)) @@ -2320,7 +2321,7 @@ func deepCopy_v1beta3_Template(in templateapiv1beta3.Template, out *templateapiv if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2364,12 +2365,12 @@ func deepCopy_v1beta3_TemplateList(in templateapiv1beta3.TemplateList, out *temp if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]templateapiv1beta3.Template, len(in.Items)) @@ -2388,7 +2389,7 @@ func deepCopy_v1beta3_Group(in userapiv1beta3.Group, out *userapiv1beta3.Group, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2410,12 +2411,12 @@ func deepCopy_v1beta3_GroupList(in userapiv1beta3.GroupList, out *userapiv1beta3 if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]userapiv1beta3.Group, len(in.Items)) @@ -2434,7 +2435,7 @@ func deepCopy_v1beta3_Identity(in userapiv1beta3.Identity, out *userapiv1beta3.I if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2463,12 +2464,12 @@ func deepCopy_v1beta3_IdentityList(in userapiv1beta3.IdentityList, out *userapiv if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]userapiv1beta3.Identity, len(in.Items)) @@ -2487,7 +2488,7 @@ func deepCopy_v1beta3_User(in userapiv1beta3.User, out *userapiv1beta3.User, c * if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2518,7 +2519,7 @@ func deepCopy_v1beta3_UserIdentityMapping(in userapiv1beta3.UserIdentityMapping, if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ObjectMeta); err != nil { return err @@ -2542,12 +2543,12 @@ func deepCopy_v1beta3_UserList(in userapiv1beta3.UserList, out *userapiv1beta3.U if newVal, err := c.DeepCopy(in.TypeMeta); err != nil { return err } else { - out.TypeMeta = newVal.(pkgapiv1beta3.TypeMeta) + out.TypeMeta = newVal.(unversioned.TypeMeta) } if newVal, err := c.DeepCopy(in.ListMeta); err != nil { return err } else { - out.ListMeta = newVal.(pkgapiv1beta3.ListMeta) + out.ListMeta = newVal.(unversioned.ListMeta) } if in.Items != nil { out.Items = make([]userapiv1beta3.User, len(in.Items)) diff --git a/pkg/auth/oauth/registry/registry_test.go b/pkg/auth/oauth/registry/registry_test.go index 1681ca0bd66f..76f62a6e0071 100644 --- a/pkg/auth/oauth/registry/registry_test.go +++ b/pkg/auth/oauth/registry/registry_test.go @@ -288,7 +288,7 @@ func TestAuthenticateTokenExpired(t *testing.T) { tokenRegistry := &test.AccessTokenRegistry{ Err: nil, AccessToken: &oapi.OAuthAccessToken{ - ObjectMeta: kapi.ObjectMeta{CreationTimestamp: util.Time{Time: time.Now().Add(-1 * time.Hour)}}, + ObjectMeta: kapi.ObjectMeta{CreationTimestamp: unversioned.Time{Time: time.Now().Add(-1 * time.Hour)}}, ExpiresIn: 600, // 10 minutes }, } @@ -310,7 +310,7 @@ func TestAuthenticateTokenValidated(t *testing.T) { tokenRegistry := &test.AccessTokenRegistry{ Err: nil, AccessToken: &oapi.OAuthAccessToken{ - ObjectMeta: kapi.ObjectMeta{CreationTimestamp: util.Time{Time: time.Now()}}, + ObjectMeta: kapi.ObjectMeta{CreationTimestamp: unversioned.Time{Time: time.Now()}}, ExpiresIn: 600, // 10 minutes UserName: "foo", UserUID: string("bar"), diff --git a/pkg/authorization/api/types.go b/pkg/authorization/api/types.go index 8871bf1f33f9..ea49765cbca5 100644 --- a/pkg/authorization/api/types.go +++ b/pkg/authorization/api/types.go @@ -2,8 +2,8 @@ package api import ( kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" kruntime "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" ) @@ -93,7 +93,7 @@ var ( KubeInternalsGroupName: {"minions", "nodes", "bindings", "events", "namespaces"}, KubeExposedGroupName: {"pods", "replicationcontrollers", "serviceaccounts", "services", "endpoints", "persistentvolumeclaims", "pods/log"}, KubeAllGroupName: {KubeInternalsGroupName, KubeExposedGroupName, QuotaGroupName}, - KubeStatusGroupName: {"pods/status", "resourcequotas/status", "namespaces/status"}, + KubeStatusGroupName: {"pods/status", "resourcequotas/status", "namespaces/status", "replicationcontrollers/status"}, OpenshiftEscalatingViewableGroupName: {"oauthauthorizetokens", "oauthaccesstokens"}, KubeEscalatingViewableGroupName: {"secrets"}, @@ -135,12 +135,12 @@ type PolicyRule struct { // IsPersonalSubjectAccessReview is a marker for PolicyRule.AttributeRestrictions that denotes that subjectaccessreviews on self should be allowed type IsPersonalSubjectAccessReview struct { - kapi.TypeMeta + unversioned.TypeMeta } // Role is a logical grouping of PolicyRules that can be referenced as a unit by RoleBindings. type Role struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Rules holds all the PolicyRules for this Role @@ -151,7 +151,7 @@ type Role struct { // It adds who information via Users and Groups and namespace information by which namespace it exists in. RoleBindings in a given // namespace only have effect in that namespace (excepting the master namespace which has power in all namespaces). type RoleBinding struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Subjects hold object references of to authorize with this rule @@ -166,11 +166,11 @@ type RoleBinding struct { // Policy is a object that holds all the Roles for a particular namespace. There is at most // one Policy document per namespace. type Policy struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // LastModified is the last time that any part of the Policy was created, updated, or deleted - LastModified util.Time + LastModified unversioned.Time // Roles holds all the Roles held by this Policy, mapped by Role.Name Roles map[string]*Role @@ -179,11 +179,11 @@ type Policy struct { // PolicyBinding is a object that holds all the RoleBindings for a particular namespace. There is // one PolicyBinding document per referenced Policy namespace type PolicyBinding struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // LastModified is the last time that any part of the PolicyBinding was created, updated, or deleted - LastModified util.Time + LastModified unversioned.Time // PolicyRef is a reference to the Policy that contains all the Roles that this PolicyBinding's RoleBindings may reference PolicyRef kapi.ObjectReference @@ -193,7 +193,7 @@ type PolicyBinding struct { // ResourceAccessReviewResponse describes who can perform the action type ResourceAccessReviewResponse struct { - kapi.TypeMeta + unversioned.TypeMeta // Namespace is the namespace used for the access review Namespace string @@ -206,7 +206,7 @@ type ResourceAccessReviewResponse struct { // ResourceAccessReview is a means to request a list of which users and groups are authorized to perform the // action specified by spec type ResourceAccessReview struct { - kapi.TypeMeta + unversioned.TypeMeta // Action describes the action being tested Action AuthorizationAttributes @@ -214,7 +214,7 @@ type ResourceAccessReview struct { // SubjectAccessReviewResponse describes whether or not a user or group can perform an action type SubjectAccessReviewResponse struct { - kapi.TypeMeta + unversioned.TypeMeta // Namespace is the namespace used for the access review Namespace string @@ -226,7 +226,7 @@ type SubjectAccessReviewResponse struct { // SubjectAccessReview is an object for requesting information about whether a user or group can perform an action type SubjectAccessReview struct { - kapi.TypeMeta + unversioned.TypeMeta // Action describes the action being tested Action AuthorizationAttributes @@ -238,7 +238,7 @@ type SubjectAccessReview struct { // LocalResourceAccessReview is a means to request a list of which users and groups are authorized to perform the action specified by spec in a particular namespace type LocalResourceAccessReview struct { - kapi.TypeMeta + unversioned.TypeMeta // Action describes the action being tested Action AuthorizationAttributes @@ -246,7 +246,7 @@ type LocalResourceAccessReview struct { // LocalSubjectAccessReview is an object for requesting information about whether a user or group can perform an action in a particular namespace type LocalSubjectAccessReview struct { - kapi.TypeMeta + unversioned.TypeMeta // Action describes the action being tested. The Namespace element is FORCED to the current namespace. Action AuthorizationAttributes @@ -271,8 +271,8 @@ type AuthorizationAttributes struct { // PolicyList is a collection of Policies type PolicyList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of policies Items []Policy @@ -280,8 +280,8 @@ type PolicyList struct { // PolicyBindingList is a collection of PolicyBindings type PolicyBindingList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of policyBindings Items []PolicyBinding @@ -289,8 +289,8 @@ type PolicyBindingList struct { // RoleBindingList is a collection of RoleBindings type RoleBindingList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of roleBindings Items []RoleBinding @@ -298,8 +298,8 @@ type RoleBindingList struct { // RoleList is a collection of Roles type RoleList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of roles Items []Role @@ -307,7 +307,7 @@ type RoleList struct { // ClusterRole is a logical grouping of PolicyRules that can be referenced as a unit by ClusterRoleBindings. type ClusterRole struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Rules holds all the PolicyRules for this ClusterRole @@ -318,7 +318,7 @@ type ClusterRole struct { // It adds who information via Users and Groups and namespace information by which namespace it exists in. ClusterRoleBindings in a given // namespace only have effect in that namespace (excepting the master namespace which has power in all namespaces). type ClusterRoleBinding struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Subjects hold object references of to authorize with this rule @@ -333,11 +333,11 @@ type ClusterRoleBinding struct { // ClusterPolicy is a object that holds all the ClusterRoles for a particular namespace. There is at most // one ClusterPolicy document per namespace. type ClusterPolicy struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // LastModified is the last time that any part of the ClusterPolicy was created, updated, or deleted - LastModified util.Time + LastModified unversioned.Time // Roles holds all the ClusterRoles held by this ClusterPolicy, mapped by Role.Name Roles map[string]*ClusterRole @@ -346,11 +346,11 @@ type ClusterPolicy struct { // ClusterPolicyBinding is a object that holds all the ClusterRoleBindings for a particular namespace. There is // one ClusterPolicyBinding document per referenced ClusterPolicy namespace type ClusterPolicyBinding struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // LastModified is the last time that any part of the ClusterPolicyBinding was created, updated, or deleted - LastModified util.Time + LastModified unversioned.Time // ClusterPolicyRef is a reference to the ClusterPolicy that contains all the ClusterRoles that this ClusterPolicyBinding's RoleBindings may reference PolicyRef kapi.ObjectReference @@ -360,8 +360,8 @@ type ClusterPolicyBinding struct { // ClusterPolicyList is a collection of ClusterPolicies type ClusterPolicyList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of ClusterPolicies Items []ClusterPolicy @@ -369,8 +369,8 @@ type ClusterPolicyList struct { // ClusterPolicyBindingList is a collection of ClusterPolicyBindings type ClusterPolicyBindingList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of ClusterPolicyBindings Items []ClusterPolicyBinding @@ -378,8 +378,8 @@ type ClusterPolicyBindingList struct { // ClusterRoleBindingList is a collection of ClusterRoleBindings type ClusterRoleBindingList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of ClusterRoleBindings Items []ClusterRoleBinding @@ -387,8 +387,8 @@ type ClusterRoleBindingList struct { // ClusterRoleList is a collection of ClusterRoles type ClusterRoleList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of ClusterRoles Items []ClusterRole diff --git a/pkg/authorization/api/v1/types.go b/pkg/authorization/api/v1/types.go index ad41df31932c..1100106ada3b 100644 --- a/pkg/authorization/api/v1/types.go +++ b/pkg/authorization/api/v1/types.go @@ -1,9 +1,9 @@ package v1 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1" kruntime "k8s.io/kubernetes/pkg/runtime" - kutil "k8s.io/kubernetes/pkg/util" ) // Authorization is calculated against @@ -36,13 +36,13 @@ type PolicyRule struct { // IsPersonalSubjectAccessReview is a marker for PolicyRule.AttributeRestrictions that denotes that subjectaccessreviews on self should be allowed type IsPersonalSubjectAccessReview struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` } // Role is a logical grouping of PolicyRules that can be referenced as a unit by RoleBindings. type Role struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Rules holds all the PolicyRules for this Role Rules []PolicyRule `json:"rules" description:"all the rules for this role"` @@ -52,8 +52,8 @@ type Role struct { // It adds who information via Users and Groups and namespace information by which namespace it exists in. RoleBindings in a given // namespace only have effect in that namespace (excepting the master namespace which has power in all namespaces). type RoleBinding struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // UserNames holds all the usernames directly bound to the role UserNames []string `json:"userNames" description:"all the usernames directly bound to the role"` @@ -71,11 +71,11 @@ type RoleBinding struct { // Policy is a object that holds all the Roles for a particular namespace. There is at most // one Policy document per namespace. type Policy struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // LastModified is the last time that any part of the Policy was created, updated, or deleted - LastModified kutil.Time `json:"lastModified" description:"last time that any part of the policy was created, updated, or deleted"` + LastModified unversioned.Time `json:"lastModified" description:"last time that any part of the policy was created, updated, or deleted"` // Roles holds all the Roles held by this Policy, mapped by Role.Name Roles []NamedRole `json:"roles" description:"roles held by this policy"` @@ -84,11 +84,11 @@ type Policy struct { // PolicyBinding is a object that holds all the RoleBindings for a particular namespace. There is // one PolicyBinding document per referenced Policy namespace type PolicyBinding struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // LastModified is the last time that any part of the PolicyBinding was created, updated, or deleted - LastModified kutil.Time `json:"lastModified" description:"last time that any part of the object was created, updated, or deleted"` + LastModified unversioned.Time `json:"lastModified" description:"last time that any part of the object was created, updated, or deleted"` // PolicyRef is a reference to the Policy that contains all the Roles that this PolicyBinding's RoleBindings may reference PolicyRef kapi.ObjectReference `json:"policyRef" description:"reference to the policy that contains all the Roles that this object's roleBindings may reference"` @@ -108,7 +108,7 @@ type NamedRoleBinding struct { // ResourceAccessReviewResponse describes who can perform the action type ResourceAccessReviewResponse struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Namespace is the namespace used for the access review Namespace string `json:"namespace,omitempty" description:"namespace used for the access review"` @@ -121,7 +121,7 @@ type ResourceAccessReviewResponse struct { // ResourceAccessReview is a means to request a list of which users and groups are authorized to perform the // action specified by spec type ResourceAccessReview struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // AuthorizationAttributes describes the action being tested. AuthorizationAttributes `json:",inline" description:"the action being tested"` @@ -129,7 +129,7 @@ type ResourceAccessReview struct { // SubjectAccessReviewResponse describes whether or not a user or group can perform an action type SubjectAccessReviewResponse struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Namespace is the namespace used for the access review Namespace string `json:"namespace,omitempty" description:"the namespace used for the access review"` @@ -141,7 +141,7 @@ type SubjectAccessReviewResponse struct { // SubjectAccessReview is an object for requesting information about whether a user or group can perform an action type SubjectAccessReview struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // AuthorizationAttributes describes the action being tested. AuthorizationAttributes `json:",inline" description:"the action being tested"` @@ -153,7 +153,7 @@ type SubjectAccessReview struct { // LocalResourceAccessReview is a means to request a list of which users and groups are authorized to perform the action specified by spec in a particular namespace type LocalResourceAccessReview struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // AuthorizationAttributes describes the action being tested. The Namespace element is FORCED to the current namespace. AuthorizationAttributes `json:",inline" description:"the action being tested"` @@ -161,7 +161,7 @@ type LocalResourceAccessReview struct { // LocalSubjectAccessReview is an object for requesting information about whether a user or group can perform an action in a particular namespace type LocalSubjectAccessReview struct { - kapi.TypeMeta + unversioned.TypeMeta // AuthorizationAttributes describes the action being tested. The Namespace element is FORCED to the current namespace. AuthorizationAttributes `json:",inline" description:"the action being tested"` @@ -186,8 +186,8 @@ type AuthorizationAttributes struct { // PolicyList is a collection of Policies type PolicyList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of Policies Items []Policy `json:"items" description:"list of policies"` @@ -195,8 +195,8 @@ type PolicyList struct { // PolicyBindingList is a collection of PolicyBindings type PolicyBindingList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of PolicyBindings Items []PolicyBinding `json:"items" description:"list of policy bindings"` @@ -204,8 +204,8 @@ type PolicyBindingList struct { // RoleBindingList is a collection of RoleBindings type RoleBindingList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of RoleBindings Items []RoleBinding `json:"items" description:"list of role bindings"` @@ -213,8 +213,8 @@ type RoleBindingList struct { // RoleList is a collection of Roles type RoleList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of Roles Items []Role `json:"items" description:"list of roles"` @@ -222,8 +222,8 @@ type RoleList struct { // ClusterRole is a logical grouping of PolicyRules that can be referenced as a unit by ClusterRoleBindings. type ClusterRole struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Rules holds all the PolicyRules for this ClusterRole Rules []PolicyRule `json:"rules" description:"list of policy rules"` @@ -233,8 +233,8 @@ type ClusterRole struct { // It adds who information via Users and Groups and namespace information by which namespace it exists in. ClusterRoleBindings in a given // namespace only have effect in that namespace (excepting the master namespace which has power in all namespaces). type ClusterRoleBinding struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // UserNames holds all the usernames directly bound to the role UserNames []string `json:"userNames" description:"all user names directly bound to the role"` @@ -252,11 +252,11 @@ type ClusterRoleBinding struct { // ClusterPolicy is a object that holds all the ClusterRoles for a particular namespace. There is at most // one ClusterPolicy document per namespace. type ClusterPolicy struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // LastModified is the last time that any part of the ClusterPolicy was created, updated, or deleted - LastModified kutil.Time `json:"lastModified" description:"last time any part of the object was created, updated, or deleted"` + LastModified unversioned.Time `json:"lastModified" description:"last time any part of the object was created, updated, or deleted"` // Roles holds all the ClusterRoles held by this ClusterPolicy, mapped by ClusterRole.Name Roles []NamedClusterRole `json:"roles" description:"all the roles held by this policy, mapped by role name"` @@ -265,11 +265,11 @@ type ClusterPolicy struct { // ClusterPolicyBinding is a object that holds all the ClusterRoleBindings for a particular namespace. There is // one ClusterPolicyBinding document per referenced ClusterPolicy namespace type ClusterPolicyBinding struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // LastModified is the last time that any part of the ClusterPolicyBinding was created, updated, or deleted - LastModified kutil.Time `json:"lastModified" description:"last time any part of the object was created, updated, or deleted"` + LastModified unversioned.Time `json:"lastModified" description:"last time any part of the object was created, updated, or deleted"` // PolicyRef is a reference to the ClusterPolicy that contains all the ClusterRoles that this ClusterPolicyBinding's RoleBindings may reference PolicyRef kapi.ObjectReference `json:"policyRef" description:"reference to the cluster policy that this cluster policy binding's role bindings may reference"` @@ -289,8 +289,8 @@ type NamedClusterRoleBinding struct { // ClusterPolicyList is a collection of ClusterPolicies type ClusterPolicyList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of ClusterPolicies Items []ClusterPolicy `json:"items" description:"list of cluster policies"` @@ -298,8 +298,8 @@ type ClusterPolicyList struct { // ClusterPolicyBindingList is a collection of ClusterPolicyBindings type ClusterPolicyBindingList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of ClusterPolicyBindings Items []ClusterPolicyBinding `json:"items" description:"list of cluster policy bindings"` @@ -307,8 +307,8 @@ type ClusterPolicyBindingList struct { // ClusterRoleBindingList is a collection of ClusterRoleBindings type ClusterRoleBindingList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of ClusterRoleBindings Items []ClusterRoleBinding `json:"items" description:"list of cluster role bindings"` @@ -316,8 +316,8 @@ type ClusterRoleBindingList struct { // ClusterRoleList is a collection of ClusterRoles type ClusterRoleList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of ClusterRoles Items []ClusterRole `json:"items" description:"list of cluster roles"` diff --git a/pkg/authorization/api/v1beta3/types.go b/pkg/authorization/api/v1beta3/types.go index f48cff286f0c..d3e691b518b5 100644 --- a/pkg/authorization/api/v1beta3/types.go +++ b/pkg/authorization/api/v1beta3/types.go @@ -1,9 +1,9 @@ package v1beta3 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1beta3" kruntime "k8s.io/kubernetes/pkg/runtime" - kutil "k8s.io/kubernetes/pkg/util" ) // Authorization is calculated against @@ -39,13 +39,13 @@ type PolicyRule struct { // IsPersonalSubjectAccessReview is a marker for PolicyRule.AttributeRestrictions that denotes that subjectaccessreviews on self should be allowed type IsPersonalSubjectAccessReview struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` } // Role is a logical grouping of PolicyRules that can be referenced as a unit by RoleBindings. type Role struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Rules holds all the PolicyRules for this Role Rules []PolicyRule `json:"rules"` @@ -55,8 +55,8 @@ type Role struct { // It adds who information via Users and Groups and namespace information by which namespace it exists in. RoleBindings in a given // namespace only have effect in that namespace (excepting the master namespace which has power in all namespaces). type RoleBinding struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // UserNames holds all the usernames directly bound to the role UserNames []string `json:"userNames"` @@ -74,11 +74,11 @@ type RoleBinding struct { // Policy is a object that holds all the Roles for a particular namespace. There is at most // one Policy document per namespace. type Policy struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // LastModified is the last time that any part of the Policy was created, updated, or deleted - LastModified kutil.Time `json:"lastModified"` + LastModified unversioned.Time `json:"lastModified"` // Roles holds all the Roles held by this Policy, mapped by Role.Name Roles []NamedRole `json:"roles"` @@ -87,11 +87,11 @@ type Policy struct { // PolicyBinding is a object that holds all the RoleBindings for a particular namespace. There is // one PolicyBinding document per referenced Policy namespace type PolicyBinding struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // LastModified is the last time that any part of the PolicyBinding was created, updated, or deleted - LastModified kutil.Time `json:"lastModified"` + LastModified unversioned.Time `json:"lastModified"` // PolicyRef is a reference to the Policy that contains all the Roles that this PolicyBinding's RoleBindings may reference PolicyRef kapi.ObjectReference `json:"policyRef"` @@ -111,7 +111,7 @@ type NamedRoleBinding struct { // ResourceAccessReviewResponse describes who can perform the action type ResourceAccessReviewResponse struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Namespace is the namespace used for the access review Namespace string `json:"namespace,omitempty"` @@ -124,7 +124,7 @@ type ResourceAccessReviewResponse struct { // ResourceAccessReview is a means to request a list of which users and groups are authorized to perform the // action specified by spec type ResourceAccessReview struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // AuthorizationAttributes describes the action being tested AuthorizationAttributes `json:",inline"` @@ -132,7 +132,7 @@ type ResourceAccessReview struct { // SubjectAccessReviewResponse describes whether or not a user or group can perform an action type SubjectAccessReviewResponse struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Namespace is the namespace used for the access review Namespace string `json:"namespace,omitempty"` @@ -144,7 +144,7 @@ type SubjectAccessReviewResponse struct { // SubjectAccessReview is an object for requesting information about whether a user or group can perform an action type SubjectAccessReview struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // AuthorizationAttributes describes the action being tested AuthorizationAttributes `json:",inline"` @@ -156,7 +156,7 @@ type SubjectAccessReview struct { // LocalResourceAccessReview is a means to request a list of which users and groups are authorized to perform the action specified by spec in a particular namespace type LocalResourceAccessReview struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // AuthorizationAttributes describes the action being tested. The Namespace element is FORCED to the current namespace. AuthorizationAttributes `json:",inline"` @@ -164,7 +164,7 @@ type LocalResourceAccessReview struct { // LocalSubjectAccessReview is an object for requesting information about whether a user or group can perform an action in a particular namespace type LocalSubjectAccessReview struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // AuthorizationAttributes describes the action being tested. The Namespace element is FORCED to the current namespace. AuthorizationAttributes `json:",inline"` @@ -189,36 +189,36 @@ type AuthorizationAttributes struct { // PolicyList is a collection of Policies type PolicyList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []Policy `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []Policy `json:"items"` } // PolicyBindingList is a collection of PolicyBindings type PolicyBindingList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []PolicyBinding `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []PolicyBinding `json:"items"` } // RoleBindingList is a collection of RoleBindings type RoleBindingList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []RoleBinding `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []RoleBinding `json:"items"` } // RoleList is a collection of Roles type RoleList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []Role `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []Role `json:"items"` } // ClusterRole is a logical grouping of PolicyRules that can be referenced as a unit by ClusterRoleBindings. type ClusterRole struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Rules holds all the PolicyRules for this ClusterRole Rules []PolicyRule `json:"rules"` @@ -228,8 +228,8 @@ type ClusterRole struct { // It adds who information via Users and Groups and namespace information by which namespace it exists in. ClusterRoleBindings in a given // namespace only have effect in that namespace (excepting the master namespace which has power in all namespaces). type ClusterRoleBinding struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // UserNames holds all the usernames directly bound to the role UserNames []string `json:"userNames"` @@ -247,11 +247,11 @@ type ClusterRoleBinding struct { // ClusterPolicy is a object that holds all the ClusterRoles for a particular namespace. There is at most // one ClusterPolicy document per namespace. type ClusterPolicy struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // LastModified is the last time that any part of the ClusterPolicy was created, updated, or deleted - LastModified kutil.Time `json:"lastModified"` + LastModified unversioned.Time `json:"lastModified"` // ClusterRoles holds all the ClusterRoles held by this ClusterPolicy, mapped by ClusterRole.Name Roles []NamedClusterRole `json:"roles"` @@ -260,11 +260,11 @@ type ClusterPolicy struct { // ClusterPolicyBinding is a object that holds all the ClusterRoleBindings for a particular namespace. There is // one ClusterPolicyBinding document per referenced ClusterPolicy namespace type ClusterPolicyBinding struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // LastModified is the last time that any part of the ClusterPolicyBinding was created, updated, or deleted - LastModified kutil.Time `json:"lastModified"` + LastModified unversioned.Time `json:"lastModified"` // PolicyRef is a reference to the ClusterPolicy that contains all the ClusterRoles that this ClusterPolicyBinding's RoleBindings may reference PolicyRef kapi.ObjectReference `json:"policyRef"` @@ -284,28 +284,28 @@ type NamedClusterRoleBinding struct { // ClusterPolicyList is a collection of ClusterPolicies type ClusterPolicyList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []ClusterPolicy `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []ClusterPolicy `json:"items"` } // ClusterPolicyBindingList is a collection of ClusterPolicyBindings type ClusterPolicyBindingList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []ClusterPolicyBinding `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []ClusterPolicyBinding `json:"items"` } // ClusterRoleBindingList is a collection of ClusterRoleBindings type ClusterRoleBindingList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []ClusterRoleBinding `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []ClusterRoleBinding `json:"items"` } // ClusterRoleList is a collection of ClusterRoles type ClusterRoleList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []ClusterRole `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []ClusterRole `json:"items"` } diff --git a/pkg/authorization/api/validation/validation.go b/pkg/authorization/api/validation/validation.go index ab42568e8522..c9ca92e4d5c9 100644 --- a/pkg/authorization/api/validation/validation.go +++ b/pkg/authorization/api/validation/validation.go @@ -5,8 +5,8 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/validation" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" + kvalidation "k8s.io/kubernetes/pkg/util/validation" oapi "github.com/openshift/origin/pkg/api" authorizationapi "github.com/openshift/origin/pkg/authorization/api" @@ -240,7 +240,7 @@ func ValidateRoleBinding(roleBinding *authorizationapi.RoleBinding, isNamespaced allErrs = append(allErrs, validation.ValidateObjectMeta(&roleBinding.ObjectMeta, isNamespaced, oapi.MinimalNameRequirements).Prefix("metadata")...) // roleRef namespace is empty when referring to global policy. - if (len(roleBinding.RoleRef.Namespace) > 0) && !util.IsDNS1123Subdomain(roleBinding.RoleRef.Namespace) { + if (len(roleBinding.RoleRef.Namespace) > 0) && !kvalidation.IsDNS1123Subdomain(roleBinding.RoleRef.Namespace) { allErrs = append(allErrs, fielderrors.NewFieldInvalid("roleRef.namespace", roleBinding.RoleRef.Namespace, "roleRef.namespace must be a valid subdomain")) } diff --git a/pkg/authorization/authorizer/adapter/attributes.go b/pkg/authorization/authorizer/adapter/attributes.go index 523d9055ec78..88740bad684e 100644 --- a/pkg/authorization/authorizer/adapter/attributes.go +++ b/pkg/authorization/authorizer/adapter/attributes.go @@ -40,10 +40,10 @@ func OriginAuthorizerAttributes(kattrs kauthorizer.Attributes) (kapi.Context, oa oattrs := &oauthorizer.DefaultAuthorizationAttributes{ Verb: kattrs.GetVerb(), Resource: kattrs.GetResource(), + APIGroup: kattrs.GetAPIGroup(), // TODO: add to kube authorizer attributes // APIVersion string - // APIGroup string // ResourceName string // RequestAttributes interface{} // NonResourceURL bool diff --git a/pkg/authorization/authorizer/adapter/attributes_test.go b/pkg/authorization/authorizer/adapter/attributes_test.go index e908f7bb1f6f..d304432262f3 100644 --- a/pkg/authorization/authorizer/adapter/attributes_test.go +++ b/pkg/authorization/authorizer/adapter/attributes_test.go @@ -93,7 +93,7 @@ func TestRoundTrip(t *testing.T) { func TestAttributeIntersection(t *testing.T) { // These are the things we expect to be shared // Everything in this list should be used by OriginAuthorizerAttributes - expectedIntersection := sets.NewString("GetVerb", "GetResource") + expectedIntersection := sets.NewString("GetVerb", "GetResource", "GetAPIGroup") // These are the things we expect to only be in the Kubernetes interface // Everything in this list should be used by OriginAuthorizerAttributes or derivative (like IsReadOnly) diff --git a/pkg/authorization/authorizer/bootstrap_policy_test.go b/pkg/authorization/authorizer/bootstrap_policy_test.go index 27a7183112f3..569f29c14e48 100644 --- a/pkg/authorization/authorizer/bootstrap_policy_test.go +++ b/pkg/authorization/authorizer/bootstrap_policy_test.go @@ -546,10 +546,10 @@ func GetBootstrapPolicy() *authorizationapi.ClusterPolicy { policy := &authorizationapi.ClusterPolicy{ ObjectMeta: kapi.ObjectMeta{ Name: authorizationapi.PolicyName, - CreationTimestamp: util.Now(), + CreationTimestamp: unversioned.Now(), UID: util.NewUUID(), }, - LastModified: util.Now(), + LastModified: unversioned.Now(), Roles: make(map[string]*authorizationapi.ClusterRole), } @@ -565,10 +565,10 @@ func GetBootstrapPolicyBinding() *authorizationapi.ClusterPolicyBinding { policyBinding := &authorizationapi.ClusterPolicyBinding{ ObjectMeta: kapi.ObjectMeta{ Name: ":Default", - CreationTimestamp: util.Now(), + CreationTimestamp: unversioned.Now(), UID: util.NewUUID(), }, - LastModified: util.Now(), + LastModified: unversioned.Now(), RoleBindings: make(map[string]*authorizationapi.ClusterRoleBinding), } diff --git a/pkg/authorization/registry/clusterrole/proxy/proxy.go b/pkg/authorization/registry/clusterrole/proxy/proxy.go index 3c4f8ad6dafa..b3b106ebf44c 100644 --- a/pkg/authorization/registry/clusterrole/proxy/proxy.go +++ b/pkg/authorization/registry/clusterrole/proxy/proxy.go @@ -2,6 +2,7 @@ package proxy import ( kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" @@ -54,7 +55,7 @@ func (s *ClusterRoleStorage) Delete(ctx kapi.Context, name string, options *kapi return nil, err } - return ret.(*kapi.Status), err + return ret.(*unversioned.Status), err } func (s *ClusterRoleStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) { diff --git a/pkg/authorization/registry/clusterrolebinding/proxy/proxy.go b/pkg/authorization/registry/clusterrolebinding/proxy/proxy.go index 267cd5502ba1..4ed41f3144ae 100644 --- a/pkg/authorization/registry/clusterrolebinding/proxy/proxy.go +++ b/pkg/authorization/registry/clusterrolebinding/proxy/proxy.go @@ -2,6 +2,7 @@ package proxy import ( kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" @@ -63,7 +64,7 @@ func (s *ClusterRoleBindingStorage) Delete(ctx kapi.Context, name string, option return nil, err } - return ret.(*kapi.Status), err + return ret.(*unversioned.Status), err } func (s *ClusterRoleBindingStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) { diff --git a/pkg/authorization/registry/policybinding/strategy.go b/pkg/authorization/registry/policybinding/strategy.go index e06ca6667160..3e304425cce5 100644 --- a/pkg/authorization/registry/policybinding/strategy.go +++ b/pkg/authorization/registry/policybinding/strategy.go @@ -4,11 +4,11 @@ import ( "fmt" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" authorizationapi "github.com/openshift/origin/pkg/authorization/api" @@ -104,8 +104,8 @@ func NewEmptyPolicyBinding(namespace, policyNamespace, policyBindingName string) binding := &authorizationapi.PolicyBinding{} binding.Name = policyBindingName binding.Namespace = namespace - binding.CreationTimestamp = util.Now() - binding.LastModified = util.Now() + binding.CreationTimestamp = unversioned.Now() + binding.LastModified = unversioned.Now() binding.PolicyRef = kapi.ObjectReference{Name: authorizationapi.PolicyName, Namespace: policyNamespace} binding.RoleBindings = make(map[string]*authorizationapi.RoleBinding) diff --git a/pkg/authorization/registry/role/policybased/virtual_storage.go b/pkg/authorization/registry/role/policybased/virtual_storage.go index 040b3111966d..edd74a396379 100644 --- a/pkg/authorization/registry/role/policybased/virtual_storage.go +++ b/pkg/authorization/registry/role/policybased/virtual_storage.go @@ -6,10 +6,10 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kapierrors "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" authorizationapi "github.com/openshift/origin/pkg/authorization/api" policyregistry "github.com/openshift/origin/pkg/authorization/registry/policy" @@ -89,12 +89,12 @@ func (m *VirtualStorage) Delete(ctx kapi.Context, name string, options *kapi.Del } delete(policy.Roles, name) - policy.LastModified = util.Now() + policy.LastModified = unversioned.Now() if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil { return nil, err } - return &kapi.Status{Status: kapi.StatusSuccess}, nil + return &unversioned.Status{Status: unversioned.StatusSuccess}, nil } func (m *VirtualStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) { @@ -114,7 +114,7 @@ func (m *VirtualStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.O role.ResourceVersion = policy.ResourceVersion policy.Roles[role.Name] = role - policy.LastModified = util.Now() + policy.LastModified = unversioned.Now() if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil { return nil, err @@ -152,7 +152,7 @@ func (m *VirtualStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.O role.ResourceVersion = policy.ResourceVersion policy.Roles[role.Name] = role - policy.LastModified = util.Now() + policy.LastModified = unversioned.Now() if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil { return nil, false, err @@ -193,8 +193,8 @@ func NewEmptyPolicy(namespace string) *authorizationapi.Policy { policy := &authorizationapi.Policy{} policy.Name = authorizationapi.PolicyName policy.Namespace = namespace - policy.CreationTimestamp = util.Now() - policy.LastModified = util.Now() + policy.CreationTimestamp = unversioned.Now() + policy.LastModified = unversioned.Now() policy.Roles = make(map[string]*authorizationapi.Role) return policy diff --git a/pkg/authorization/registry/role/policybased/virtual_storage_test.go b/pkg/authorization/registry/role/policybased/virtual_storage_test.go index 68ab2cae78a2..c2c7e543e579 100644 --- a/pkg/authorization/registry/role/policybased/virtual_storage_test.go +++ b/pkg/authorization/registry/role/policybased/virtual_storage_test.go @@ -76,7 +76,7 @@ func TestCreateValid(t *testing.T) { } switch r := obj.(type) { - case *kapi.Status: + case *unversioned.Status: t.Errorf("Got back unexpected status: %#v", r) case *authorizationapi.Role: // expected case @@ -103,7 +103,7 @@ func TestUpdate(t *testing.T) { } switch obj.(type) { - case *kapi.Status: + case *unversioned.Status: t.Errorf("Unexpected operation error: %v", obj) case *authorizationapi.Role: @@ -161,7 +161,7 @@ func TestDeleteValid(t *testing.T) { } switch r := obj.(type) { - case *kapi.Status: + case *unversioned.Status: if r.Status != "Success" { t.Fatalf("Got back non-success status: %#v", r) } diff --git a/pkg/authorization/registry/rolebinding/policybased/virtual_storage.go b/pkg/authorization/registry/rolebinding/policybased/virtual_storage.go index 4628923e0c44..197258ffbca0 100644 --- a/pkg/authorization/registry/rolebinding/policybased/virtual_storage.go +++ b/pkg/authorization/registry/rolebinding/policybased/virtual_storage.go @@ -7,10 +7,10 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kapierrors "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" authorizationapi "github.com/openshift/origin/pkg/authorization/api" clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy" @@ -101,13 +101,13 @@ func (m *VirtualStorage) Delete(ctx kapi.Context, name string, options *kapi.Del } delete(owningPolicyBinding.RoleBindings, name) - owningPolicyBinding.LastModified = util.Now() + owningPolicyBinding.LastModified = unversioned.Now() if err := m.BindingRegistry.UpdatePolicyBinding(ctx, owningPolicyBinding); err != nil { return nil, err } - return &kapi.Status{Status: kapi.StatusSuccess}, nil + return &unversioned.Status{Status: unversioned.StatusSuccess}, nil } func (m *VirtualStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) { @@ -146,7 +146,7 @@ func (m *VirtualStorage) createRoleBinding(ctx kapi.Context, obj runtime.Object, roleBinding.ResourceVersion = policyBinding.ResourceVersion policyBinding.RoleBindings[roleBinding.Name] = roleBinding - policyBinding.LastModified = util.Now() + policyBinding.LastModified = unversioned.Now() if err := m.BindingRegistry.UpdatePolicyBinding(ctx, policyBinding); err != nil { return nil, err @@ -201,7 +201,7 @@ func (m *VirtualStorage) updateRoleBinding(ctx kapi.Context, obj runtime.Object, roleBinding.ResourceVersion = policyBinding.ResourceVersion policyBinding.RoleBindings[roleBinding.Name] = roleBinding - policyBinding.LastModified = util.Now() + policyBinding.LastModified = unversioned.Now() if err := m.BindingRegistry.UpdatePolicyBinding(ctx, policyBinding); err != nil { return nil, false, err diff --git a/pkg/authorization/registry/rolebinding/policybased/virtual_storage_test.go b/pkg/authorization/registry/rolebinding/policybased/virtual_storage_test.go index 9f2b8b1b7725..702f898b1deb 100644 --- a/pkg/authorization/registry/rolebinding/policybased/virtual_storage_test.go +++ b/pkg/authorization/registry/rolebinding/policybased/virtual_storage_test.go @@ -100,7 +100,7 @@ func TestCreateValidAutoCreateMasterPolicyBindings(t *testing.T) { } switch r := obj.(type) { - case *kapi.Status: + case *unversioned.Status: t.Errorf("Got back unexpected status: %#v", r) case *authorizationapi.RoleBinding: // expected case @@ -125,7 +125,7 @@ func TestCreateValid(t *testing.T) { } switch obj.(type) { - case *kapi.Status: + case *unversioned.Status: t.Errorf("Got back unexpected status: %#v", obj) case *authorizationapi.RoleBinding: // expected case @@ -159,7 +159,7 @@ func TestUpdate(t *testing.T) { } switch obj.(type) { - case *kapi.Status: + case *unversioned.Status: t.Errorf("Unexpected operation error: %v", obj) case *authorizationapi.RoleBinding: @@ -254,7 +254,7 @@ func TestDeleteValid(t *testing.T) { } switch r := obj.(type) { - case *kapi.Status: + case *unversioned.Status: if r.Status != "Success" { t.Fatalf("Got back non-success status: %#v", r) } diff --git a/pkg/build/admission/admission_test.go b/pkg/build/admission/admission_test.go index 29b9ffabe550..9fee21c2205b 100644 --- a/pkg/build/admission/admission_test.go +++ b/pkg/build/admission/admission_test.go @@ -28,6 +28,7 @@ func TestBuildAdmission(t *testing.T) { reviewResponse *authorizationapi.SubjectAccessReviewResponse expectedResource string expectAccept bool + expectedError string }{ { name: "allowed source build", @@ -125,6 +126,7 @@ func TestBuildAdmission(t *testing.T) { resource: buildConfigsResource, reviewResponse: reviewResponse(true, ""), expectAccept: false, + expectedError: "Internal error occurred: [Unrecognized request object &admission.fakeObject{}, couldn't find ObjectMeta field in admission.fakeObject{}]", }, } @@ -135,8 +137,12 @@ func TestBuildAdmission(t *testing.T) { if err != nil && test.expectAccept { t.Errorf("%s: unexpected error: %v", test.name, err) } - if (err == nil || !apierrors.IsForbidden(err)) && !test.expectAccept { - t.Errorf("%s: expecting reject error", test.name) + + if !apierrors.IsForbidden(err) && !test.expectAccept { + if (len(test.expectedError) != 0) || (test.expectedError == err.Error()) { + continue + } + t.Errorf("%s: expecting reject error, got %v", test.name, err) } } } diff --git a/pkg/build/api/sort_test.go b/pkg/build/api/sort_test.go index f06d100fe84c..060d81894f54 100644 --- a/pkg/build/api/sort_test.go +++ b/pkg/build/api/sort_test.go @@ -10,8 +10,8 @@ import ( ) func TestSortBuildSliceByCreationTimestamp(t *testing.T) { - present := util.Now() - past := util.NewTime(present.Add(-time.Minute)) + present := unversioned.Now() + past := unversioned.NewTime(present.Add(-time.Minute)) builds := []Build{ { ObjectMeta: kapi.ObjectMeta{ @@ -33,8 +33,8 @@ func TestSortBuildSliceByCreationTimestamp(t *testing.T) { } func TestSortBuildPtrSliceByCreationTimestamp(t *testing.T) { - present := util.Now() - past := util.NewTime(present.Add(-time.Minute)) + present := unversioned.Now() + past := unversioned.NewTime(present.Add(-time.Minute)) builds := []*Build{ { ObjectMeta: kapi.ObjectMeta{ diff --git a/pkg/build/api/types.go b/pkg/build/api/types.go index 1332ea4d8327..6b4a7b12b911 100644 --- a/pkg/build/api/types.go +++ b/pkg/build/api/types.go @@ -4,7 +4,7 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/sets" ) @@ -26,7 +26,7 @@ const ( // Build encapsulates the inputs needed to produce a new deployable image, as well as // the status of the execution and a reference to the Pod which executed the build. type Build struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Spec is all the inputs used to execute the build. @@ -79,13 +79,13 @@ type BuildStatus struct { // StartTimestamp is a timestamp representing the server time when this Build started // running in a Pod. // It is represented in RFC3339 form and is in UTC. - StartTimestamp *util.Time + StartTimestamp *unversioned.Time // CompletionTimestamp is a timestamp representing the server time when this Build was // finished, whether that build failed or succeeded. It reflects the time at which // the Pod running the Build terminated. // It is represented in RFC3339 form and is in UTC. - CompletionTimestamp *util.Time + CompletionTimestamp *unversioned.Time // Duration contains time.Duration object describing build time. Duration time.Duration @@ -350,7 +350,7 @@ const BuildConfigLabel = "buildconfig" // BuildConfig is a template which can be used to create new builds. type BuildConfig struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Spec holds all the input necessary to produce a new build, and the conditions when @@ -444,8 +444,8 @@ const ( // BuildList is a collection of Builds. type BuildList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of builds Items []Build @@ -453,8 +453,8 @@ type BuildList struct { // BuildConfigList is a collection of BuildConfigs. type BuildConfigList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of build configs Items []BuildConfig @@ -488,13 +488,13 @@ type GitRefInfo struct { // BuildLog is the (unused) resource associated with the build log redirector type BuildLog struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta } // BuildRequest is the resource used to pass parameters to build generator type BuildRequest struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Revision is the information from the source for a specific repo snapshot. @@ -514,7 +514,7 @@ type BuildRequest struct { // BuildLogOptions is the REST options for a build log type BuildLogOptions struct { - kapi.TypeMeta + unversioned.TypeMeta // Follow if true indicates that the build log should be streamed until // the build terminates. diff --git a/pkg/build/api/v1/types.go b/pkg/build/api/v1/types.go index 58e3be39888f..3c25b1e2cde6 100644 --- a/pkg/build/api/v1/types.go +++ b/pkg/build/api/v1/types.go @@ -3,15 +3,15 @@ package v1 import ( "time" + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1" - "k8s.io/kubernetes/pkg/util" ) // Build encapsulates the inputs needed to produce a new deployable image, as well as // the status of the execution and a reference to the Pod which executed the build. type Build struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Spec is all the inputs used to execute the build. Spec BuildSpec `json:"spec,omitempty" description:"specification of the desired behavior for a build"` @@ -63,13 +63,13 @@ type BuildStatus struct { // StartTimestamp is a timestamp representing the server time when this Build started // running in a Pod. // It is represented in RFC3339 form and is in UTC. - StartTimestamp *util.Time `json:"startTimestamp,omitempty" description:"server time when this build started running in a pod"` + StartTimestamp *unversioned.Time `json:"startTimestamp,omitempty" description:"server time when this build started running in a pod"` // CompletionTimestamp is a timestamp representing the server time when this Build was // finished, whether that build failed or succeeded. It reflects the time at which // the Pod running the Build terminated. // It is represented in RFC3339 form and is in UTC. - CompletionTimestamp *util.Time `json:"completionTimestamp,omitempty" description:"server time when the pod running this build stopped running"` + CompletionTimestamp *unversioned.Time `json:"completionTimestamp,omitempty" description:"server time when the pod running this build stopped running"` // Duration contains time.Duration object describing build time. Duration time.Duration `json:"duration,omitempty" description:"amount of time the build has been running"` @@ -328,8 +328,8 @@ const BuildConfigLabel = "buildconfig" // BuildConfig is a template which can be used to create new builds. type BuildConfig struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Spec holds all the input necessary to produce a new build, and the conditions when // to trigger them. @@ -414,8 +414,8 @@ const ( // BuildList is a collection of Builds. type BuildList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of builds Items []Build `json:"items" description:"list of builds"` @@ -423,8 +423,8 @@ type BuildList struct { // BuildConfigList is a collection of BuildConfigs. type BuildConfigList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of build configs Items []BuildConfig `json:"items" description:"list of build configs"` @@ -447,14 +447,14 @@ type GitInfo struct { // BuildLog is the (unused) resource associated with the build log redirector type BuildLog struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` } // BuildRequest is the resource used to pass parameters to build generator type BuildRequest struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Revision is the information from the source for a specific repo snapshot. Revision *SourceRevision `json:"revision,omitempty" description:"information from the source for a specific repo snapshot"` @@ -473,7 +473,7 @@ type BuildRequest struct { // BuildLogOptions is the REST options for a build log type BuildLogOptions struct { - kapi.TypeMeta + unversioned.TypeMeta // Follow if true indicates that the build log should be streamed until // the build terminates. diff --git a/pkg/build/api/v1beta3/types.go b/pkg/build/api/v1beta3/types.go index 540e7207a97f..25842ea7dd67 100644 --- a/pkg/build/api/v1beta3/types.go +++ b/pkg/build/api/v1beta3/types.go @@ -3,15 +3,15 @@ package v1beta3 import ( "time" + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1beta3" - "k8s.io/kubernetes/pkg/util" ) // Build encapsulates the inputs needed to produce a new deployable image, as well as // the status of the execution and a reference to the Pod which executed the build. type Build struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Spec is all the inputs used to execute the build. Spec BuildSpec `json:"spec,omitempty"` @@ -63,13 +63,13 @@ type BuildStatus struct { // StartTimestamp is a timestamp representing the server time when this Build started // running in a Pod. // It is represented in RFC3339 form and is in UTC. - StartTimestamp *util.Time `json:"startTimestamp,omitempty"` + StartTimestamp *unversioned.Time `json:"startTimestamp,omitempty"` // CompletionTimestamp is a timestamp representing the server time when this Build was // finished, whether that build failed or succeeded. It reflects the time at which // the Pod running the Build terminated. // It is represented in RFC3339 form and is in UTC. - CompletionTimestamp *util.Time `json:"completionTimestamp,omitempty"` + CompletionTimestamp *unversioned.Time `json:"completionTimestamp,omitempty"` // Duration contains time.Duration object describing build time. Duration time.Duration `json:"duration,omitempty"` @@ -317,8 +317,8 @@ const BuildConfigLabel = "buildconfig" // BuildConfig is a template which can be used to create new builds. type BuildConfig struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Spec holds all the input necessary to produce a new build, and the conditions when // to trigger them. @@ -399,16 +399,16 @@ const ( // BuildList is a collection of Builds. type BuildList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []Build `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []Build `json:"items"` } // BuildConfigList is a collection of BuildConfigs. type BuildConfigList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []BuildConfig `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []BuildConfig `json:"items"` } // GenericWebHookEvent is the payload expected for a generic webhook post @@ -428,14 +428,14 @@ type GitInfo struct { // BuildLog is the (unused) resource associated with the build log redirector type BuildLog struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` } // BuildRequest is the resource used to pass parameters to build generator type BuildRequest struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Revision is the information from the source for a specific repo snapshot. Revision *SourceRevision `json:"revision,omitempty"` @@ -454,7 +454,7 @@ type BuildRequest struct { // BuildLogOptions is the REST options for a build log type BuildLogOptions struct { - kapi.TypeMeta + unversioned.TypeMeta // Follow if true indicates that the build log should be streamed until // the build terminates. diff --git a/pkg/build/api/validation/validation.go b/pkg/build/api/validation/validation.go index a68fdd3a18a1..e0e246999a9f 100644 --- a/pkg/build/api/validation/validation.go +++ b/pkg/build/api/validation/validation.go @@ -6,8 +6,8 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/validation" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" + kvalidation "k8s.io/kubernetes/pkg/util/validation" oapi "github.com/openshift/origin/pkg/api" buildapi "github.com/openshift/origin/pkg/build/api" @@ -216,7 +216,7 @@ func validateToImageReference(reference *kapi.ObjectReference) fielderrors.Valid } else if _, _, ok := imageapi.SplitImageStreamTag(name); !ok { allErrs = append(allErrs, fielderrors.NewFieldInvalid("name", name, "ImageStreamTag object references must be in the form :")) } - if len(namespace) != 0 && !util.IsDNS1123Subdomain(namespace) { + if len(namespace) != 0 && !kvalidation.IsDNS1123Subdomain(namespace) { allErrs = append(allErrs, fielderrors.NewFieldInvalid("namespace", namespace, "namespace must be a valid subdomain")) } @@ -247,7 +247,7 @@ func validateFromImageReference(reference *kapi.ObjectReference) fielderrors.Val allErrs = append(allErrs, fielderrors.NewFieldInvalid("name", name, "ImageStreamTag object references must be in the form :")) } - if len(namespace) != 0 && !util.IsDNS1123Subdomain(namespace) { + if len(namespace) != 0 && !kvalidation.IsDNS1123Subdomain(namespace) { allErrs = append(allErrs, fielderrors.NewFieldInvalid("namespace", namespace, "namespace must be a valid subdomain")) } @@ -264,7 +264,7 @@ func validateFromImageReference(reference *kapi.ObjectReference) fielderrors.Val if len(name) == 0 { allErrs = append(allErrs, fielderrors.NewFieldRequired("name")) } - if len(namespace) != 0 && !util.IsDNS1123Subdomain(namespace) { + if len(namespace) != 0 && !kvalidation.IsDNS1123Subdomain(namespace) { allErrs = append(allErrs, fielderrors.NewFieldInvalid("namespace", namespace, "namespace must be a valid subdomain")) } case "": diff --git a/pkg/build/controller/controller.go b/pkg/build/controller/controller.go index fea1cc484125..403a75d673bf 100644 --- a/pkg/build/controller/controller.go +++ b/pkg/build/controller/controller.go @@ -7,9 +7,9 @@ import ( kapi "k8s.io/kubernetes/pkg/api" errors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/client/record" - "k8s.io/kubernetes/pkg/util" buildapi "github.com/openshift/origin/pkg/build/api" buildclient "github.com/openshift/origin/pkg/build/client" @@ -63,7 +63,7 @@ func (bc *BuildController) CancelBuild(build *buildapi.Build) error { } build.Status.Phase = buildapi.BuildPhaseCancelled - now := util.Now() + now := unversioned.Now() build.Status.CompletionTimestamp = &now if err := bc.BuildUpdater.Update(build.Namespace, build); err != nil { return fmt.Errorf("Failed to update build %s/%s: %v", build.Namespace, build.Name, err) @@ -262,11 +262,11 @@ func (bc *BuildPodController) HandlePod(pod *kapi.Pod) error { glog.V(4).Infof("Updating build %s/%s status %s -> %s", build.Namespace, build.Name, build.Status.Phase, nextStatus) build.Status.Phase = nextStatus if buildutil.IsBuildComplete(build) { - now := util.Now() + now := unversioned.Now() build.Status.CompletionTimestamp = &now } if build.Status.Phase == buildapi.BuildPhaseRunning { - now := util.Now() + now := unversioned.Now() build.Status.StartTimestamp = &now } if err := bc.BuildUpdater.Update(build.Namespace, build); err != nil { @@ -318,7 +318,7 @@ func (bc *BuildPodDeleteController) HandleBuildPodDeletion(pod *kapi.Pod) error glog.V(4).Infof("Updating build %s/%s status %s -> %s", build.Namespace, build.Name, build.Status.Phase, nextStatus) build.Status.Phase = nextStatus build.Status.Message = "The pod for this build was deleted before the build completed." - now := util.Now() + now := unversioned.Now() build.Status.CompletionTimestamp = &now if err := bc.BuildUpdater.Update(build.Namespace, build); err != nil { return fmt.Errorf("Failed to update build %s/%s: %v", build.Namespace, build.Name, err) diff --git a/pkg/build/controller/controller_test.go b/pkg/build/controller/controller_test.go index 59b14a0817b7..67124b184de8 100644 --- a/pkg/build/controller/controller_test.go +++ b/pkg/build/controller/controller_test.go @@ -407,14 +407,14 @@ func TestHandlePod(t *testing.T) { matchID bool inStatus buildapi.BuildPhase outStatus buildapi.BuildPhase - startTimestamp *util.Time - completionTimestamp *util.Time + startTimestamp *unversioned.Time + completionTimestamp *unversioned.Time podStatus kapi.PodPhase exitCode int buildUpdater buildclient.BuildUpdater podManager podManager } - dummy := util.Now() + dummy := unversioned.Now() curtime := &dummy tests := []handlePodTest{ { // 0 @@ -529,10 +529,10 @@ func TestCancelBuild(t *testing.T) { exitCode int buildUpdater buildclient.BuildUpdater podManager podManager - startTimestamp *util.Time - completionTimestamp *util.Time + startTimestamp *unversioned.Time + completionTimestamp *unversioned.Time } - dummy := util.Now() + dummy := unversioned.Now() curtime := &dummy tests := []handleCancelBuildTest{ diff --git a/pkg/build/controller/factory/factory.go b/pkg/build/controller/factory/factory.go index f3c51e8d696f..05dd564268f7 100644 --- a/pkg/build/controller/factory/factory.go +++ b/pkg/build/controller/factory/factory.go @@ -8,6 +8,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kerrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/client/record" kclient "k8s.io/kubernetes/pkg/client/unversioned" @@ -39,7 +40,7 @@ func limitedLogAndRetry(buildupdater buildclient.BuildUpdater, maxTimeout time.D } build.Status.Phase = buildapi.BuildPhaseFailed build.Status.Message = err.Error() - now := kutil.Now() + now := unversioned.Now() build.Status.CompletionTimestamp = &now glog.V(3).Infof("Giving up retrying Build %s/%s: %v", build.Namespace, build.Name, err) kutil.HandleError(err) diff --git a/pkg/build/controller/factory/factory_test.go b/pkg/build/controller/factory/factory_test.go index 830aa0c10506..cfbd7f90adcd 100644 --- a/pkg/build/controller/factory/factory_test.go +++ b/pkg/build/controller/factory/factory_test.go @@ -27,7 +27,7 @@ func TestLimitedLogAndRetryFinish(t *testing.T) { updater := &buildUpdater{} err := errors.New("funky error") - now := kutil.Now() + now := unversioned.Now() retry := controller.Retry{ Count: 0, StartTimestamp: kutil.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-31, now.Second(), now.Nanosecond(), now.Location()), @@ -53,7 +53,7 @@ func TestLimitedLogAndRetryProcessing(t *testing.T) { updater := &buildUpdater{} err := errors.New("funky error") - now := kutil.Now() + now := unversioned.Now() retry := controller.Retry{ Count: 0, StartTimestamp: kutil.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-10, now.Second(), now.Nanosecond(), now.Location()), diff --git a/pkg/build/controller/strategy/util.go b/pkg/build/controller/strategy/util.go index 691118369d41..954a457702c9 100644 --- a/pkg/build/controller/strategy/util.go +++ b/pkg/build/controller/strategy/util.go @@ -8,7 +8,7 @@ import ( imageapi "github.com/openshift/origin/pkg/image/api" "github.com/openshift/origin/pkg/util/namer" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + kvalidation "k8s.io/kubernetes/pkg/util/validation" ) const ( @@ -77,7 +77,7 @@ func setupBuildEnv(build *buildapi.Build, pod *kapi.Pod) error { // mountSecretVolume is a helper method responsible for actual mounting secret // volumes into a pod. func mountSecretVolume(pod *kapi.Pod, secretName, mountPath, volumePrefix string) { - volumeName := namer.GetName(secretName, volumePrefix, util.DNS1123SubdomainMaxLength) + volumeName := namer.GetName(secretName, volumePrefix, kvalidation.DNS1123SubdomainMaxLength) volume := kapi.Volume{ Name: volumeName, VolumeSource: kapi.VolumeSource{ diff --git a/pkg/build/generator/generator.go b/pkg/build/generator/generator.go index 1adfb0cbabff..3a6e492d4a82 100644 --- a/pkg/build/generator/generator.go +++ b/pkg/build/generator/generator.go @@ -7,11 +7,13 @@ import ( "strings" "github.com/golang/glog" + kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" kclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/credentialprovider" - "k8s.io/kubernetes/pkg/util" + kvalidation "k8s.io/kubernetes/pkg/util/validation" buildapi "github.com/openshift/origin/pkg/build/api" buildutil "github.com/openshift/origin/pkg/build/util" @@ -599,11 +601,11 @@ func getNextBuildNameFromBuild(build *buildapi.Build, buildConfig *buildapi.Buil nameElems := strings.Split(buildName, "-") buildName = strings.Join(nameElems[:len(nameElems)-1], "-") } - suffix := fmt.Sprintf("%v", util.Now().UnixNano()) + suffix := fmt.Sprintf("%v", unversioned.Now().UnixNano()) if len(suffix) > 10 { suffix = suffix[len(suffix)-10:] } - return namer.GetName(buildName, suffix, util.DNS1123SubdomainMaxLength) + return namer.GetName(buildName, suffix, kvalidation.DNS1123SubdomainMaxLength) } diff --git a/pkg/build/prune/data.go b/pkg/build/prune/data.go index 6befaf17615d..e530106147e8 100644 --- a/pkg/build/prune/data.go +++ b/pkg/build/prune/data.go @@ -5,8 +5,8 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" - "k8s.io/kubernetes/pkg/util" buildapi "github.com/openshift/origin/pkg/build/api" ) @@ -54,8 +54,8 @@ type FilterPredicate func(build *buildapi.Build) bool // NewFilterBeforePredicate is a function that returns true if the build was created before the current time minus specified duration func NewFilterBeforePredicate(d time.Duration) FilterPredicate { - now := util.Now() - before := util.NewTime(now.Time.Add(-1 * d)) + now := unversioned.Now() + before := unversioned.NewTime(now.Time.Add(-1 * d)) return func(build *buildapi.Build) bool { return build.CreationTimestamp.Before(before) } diff --git a/pkg/build/prune/data_test.go b/pkg/build/prune/data_test.go index 18019fa5894b..94caa39a463e 100644 --- a/pkg/build/prune/data_test.go +++ b/pkg/build/prune/data_test.go @@ -16,7 +16,7 @@ func mockBuildConfig(namespace, name string) *buildapi.BuildConfig { return &buildapi.BuildConfig{ObjectMeta: kapi.ObjectMeta{Namespace: namespace, Name: name}} } -func withCreated(build *buildapi.Build, creationTimestamp util.Time) *buildapi.Build { +func withCreated(build *buildapi.Build, creationTimestamp unversioned.Time) *buildapi.Build { build.CreationTimestamp = creationTimestamp return build } @@ -68,8 +68,8 @@ func TestBuildByBuildConfigIndexFunc(t *testing.T) { func TestFilterBeforePredicate(t *testing.T) { youngerThan := time.Hour - now := util.Now() - old := util.NewTime(now.Time.Add(-1 * youngerThan)) + now := unversioned.Now() + old := unversioned.NewTime(now.Time.Add(-1 * youngerThan)) builds := []*buildapi.Build{ { ObjectMeta: kapi.ObjectMeta{ diff --git a/pkg/build/prune/prune_test.go b/pkg/build/prune/prune_test.go index 340ca3667121..2a63f02b7701 100644 --- a/pkg/build/prune/prune_test.go +++ b/pkg/build/prune/prune_test.go @@ -56,8 +56,8 @@ func TestPruneTask(t *testing.T) { for _, BuildPhaseOption := range BuildPhaseOptions { keepYoungerThan := time.Hour - now := util.Now() - old := util.NewTime(now.Time.Add(-1 * keepYoungerThan)) + now := unversioned.Now() + old := unversioned.NewTime(now.Time.Add(-1 * keepYoungerThan)) buildConfigs := []*buildapi.BuildConfig{} builds := []*buildapi.Build{} diff --git a/pkg/build/prune/resolvers_test.go b/pkg/build/prune/resolvers_test.go index 2fdd1bd75b2c..ccd55866f5c6 100644 --- a/pkg/build/prune/resolvers_test.go +++ b/pkg/build/prune/resolvers_test.go @@ -126,9 +126,9 @@ func TestPerBuildConfigResolver(t *testing.T) { } } - now := util.Now() + now := unversioned.Now() for i := range builds { - creationTimestamp := util.NewTime(now.Time.Add(-1 * time.Duration(i) * time.Hour)) + creationTimestamp := unversioned.NewTime(now.Time.Add(-1 * time.Duration(i) * time.Hour)) builds[i].CreationTimestamp = creationTimestamp } diff --git a/pkg/build/registry/build/strategy.go b/pkg/build/registry/build/strategy.go index cfa52e1e9275..78998dae9f5f 100644 --- a/pkg/build/registry/build/strategy.go +++ b/pkg/build/registry/build/strategy.go @@ -6,11 +6,11 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" "github.com/openshift/origin/pkg/build/api" @@ -35,7 +35,7 @@ var Decorator = func(obj runtime.Object) error { } else { completionTimestamp := build.Status.CompletionTimestamp if completionTimestamp == nil { - dummy := util.Now() + dummy := unversioned.Now() completionTimestamp = &dummy } build.Status.Duration = completionTimestamp.Rfc3339Copy().Time.Sub(build.Status.StartTimestamp.Rfc3339Copy().Time) diff --git a/pkg/build/registry/build/strategy_test.go b/pkg/build/registry/build/strategy_test.go index 8a7845b14dc7..ab965e24d2b0 100644 --- a/pkg/build/registry/build/strategy_test.go +++ b/pkg/build/registry/build/strategy_test.go @@ -87,8 +87,8 @@ func TestBuildDecorator(t *testing.T) { Phase: buildapi.BuildPhaseNew, }, } - now := util.Now() - startTime := util.NewTime(now.Time.Add(-1 * time.Minute)) + now := unversioned.Now() + startTime := unversioned.NewTime(now.Time.Add(-1 * time.Minute)) build.Status.StartTimestamp = &startTime err := Decorator(build) if err != nil { diff --git a/pkg/build/registry/buildconfig/webhook_test.go b/pkg/build/registry/buildconfig/webhook_test.go index 7df7bcd8a20c..83f7a72258d9 100644 --- a/pkg/build/registry/buildconfig/webhook_test.go +++ b/pkg/build/registry/buildconfig/webhook_test.go @@ -51,7 +51,7 @@ func newStorage() (*rest.WebHook, *buildConfigInstantiator, *test.BuildConfigReg func TestNewWebHook(t *testing.T) { hook, _, _ := newStorage() - if out, ok := hook.New().(*kapi.Status); !ok { + if out, ok := hook.New().(*unversioned.Status); !ok { t.Errorf("unexpected new: %#v", out) } } diff --git a/pkg/client/projectrequests.go b/pkg/client/projectrequests.go index 33fb238cce4f..8d1ba30979e6 100644 --- a/pkg/client/projectrequests.go +++ b/pkg/client/projectrequests.go @@ -1,7 +1,7 @@ package client import ( - kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -16,7 +16,7 @@ type ProjectRequestsInterface interface { // ProjectRequestInterface exposes methods on projectRequest resources. type ProjectRequestInterface interface { Create(p *projectapi.ProjectRequest) (*projectapi.Project, error) - List(label labels.Selector, field fields.Selector) (*kapi.Status, error) + List(label labels.Selector, field fields.Selector) (*unversioned.Status, error) } type projectRequests struct { @@ -38,8 +38,8 @@ func (c *projectRequests) Create(p *projectapi.ProjectRequest) (result *projecta } // List returns a status object indicating that a user can call the Create or an error indicating why not -func (c *projectRequests) List(label labels.Selector, field fields.Selector) (result *kapi.Status, err error) { - result = &kapi.Status{} +func (c *projectRequests) List(label labels.Selector, field fields.Selector) (result *unversioned.Status, err error) { + result = &unversioned.Status{} err = c.r.Get().Resource("projectRequests").LabelsSelectorParam(label).FieldsSelectorParam(field).Do().Into(result) return result, err } diff --git a/pkg/client/testclient/fake_projectrequests.go b/pkg/client/testclient/fake_projectrequests.go index 02b83958c67b..ee349f2eae37 100644 --- a/pkg/client/testclient/fake_projectrequests.go +++ b/pkg/client/testclient/fake_projectrequests.go @@ -15,13 +15,13 @@ type FakeProjectRequests struct { Fake *Fake } -func (c *FakeProjectRequests) List(label labels.Selector, field fields.Selector) (*kapi.Status, error) { - obj, err := c.Fake.Invokes(ktestclient.NewRootListAction("newprojects", label, field), &kapi.Status{}) +func (c *FakeProjectRequests) List(label labels.Selector, field fields.Selector) (*unversioned.Status, error) { + obj, err := c.Fake.Invokes(ktestclient.NewRootListAction("newprojects", label, field), &unversioned.Status{}) if obj == nil { return nil, err } - return obj.(*kapi.Status), err + return obj.(*unversioned.Status), err } func (c *FakeProjectRequests) Create(inObj *projectapi.ProjectRequest) (*projectapi.Project, error) { diff --git a/pkg/cmd/admin/node/evacuate.go b/pkg/cmd/admin/node/evacuate.go index 150a2e85372b..a172915bde62 100644 --- a/pkg/cmd/admin/node/evacuate.go +++ b/pkg/cmd/admin/node/evacuate.go @@ -69,7 +69,7 @@ func (e *EvacuateOptions) RunEvacuate(node *kapi.Node) error { if err != nil { return err } - rcs, err := e.Options.Kclient.ReplicationControllers(kapi.NamespaceAll).List(labels.Everything()) + rcs, err := e.Options.Kclient.ReplicationControllers(kapi.NamespaceAll).List(labels.Everything(), fields.Everything()) if err != nil { return err } diff --git a/pkg/cmd/admin/prune/deployments.go b/pkg/cmd/admin/prune/deployments.go index 65b9413c3963..b1d423e11330 100644 --- a/pkg/cmd/admin/prune/deployments.go +++ b/pkg/cmd/admin/prune/deployments.go @@ -60,7 +60,7 @@ func NewCmdPruneDeployments(f *clientcmd.Factory, parentName, name string, out i cmdutil.CheckErr(err) } - deploymentList, err := kclient.ReplicationControllers(kapi.NamespaceAll).List(labels.Everything()) + deploymentList, err := kclient.ReplicationControllers(kapi.NamespaceAll).List(labels.Everything(), fields.Everything()) if err != nil { cmdutil.CheckErr(err) } diff --git a/pkg/cmd/admin/prune/images.go b/pkg/cmd/admin/prune/images.go index b7caf5f9df75..f5332445c9c8 100644 --- a/pkg/cmd/admin/prune/images.go +++ b/pkg/cmd/admin/prune/images.go @@ -112,7 +112,7 @@ func (o *PruneImagesOptions) Complete(f *clientcmd.Factory, args []string, out i return err } - allRCs, err := kClient.ReplicationControllers(kapi.NamespaceAll).List(labels.Everything()) + allRCs, err := kClient.ReplicationControllers(kapi.NamespaceAll).List(labels.Everything(), fields.Everything()) if err != nil { return err } diff --git a/pkg/cmd/admin/router/router.go b/pkg/cmd/admin/router/router.go index 4e333339e1ac..fa823086fac5 100644 --- a/pkg/cmd/admin/router/router.go +++ b/pkg/cmd/admin/router/router.go @@ -527,7 +527,9 @@ func RunCmdRouter(f *clientcmd.Factory, cmd *cobra.Command, out io.Writer, cfg * Template: &kapi.PodTemplateSpec{ ObjectMeta: kapi.ObjectMeta{Labels: label}, Spec: kapi.PodSpec{ - HostNetwork: cfg.HostNetwork, + SecurityContext: &kapi.PodSecurityContext{ + HostNetwork: cfg.HostNetwork, + }, ServiceAccountName: cfg.ServiceAccount, NodeSelector: nodeSelector, Containers: []kapi.Container{ diff --git a/pkg/cmd/cli/cli.go b/pkg/cmd/cli/cli.go index 95a46b7661e3..7d0e75fd40c1 100644 --- a/pkg/cmd/cli/cli.go +++ b/pkg/cmd/cli/cli.go @@ -108,6 +108,7 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) * { Message: "Troubleshooting and Debugging Commands:", Commands: []*cobra.Command{ + cmd.NewCmdExplain(fullName, f, out), cmd.NewCmdLogs(fullName, f, out), cmd.NewCmdRsh(cmd.RshRecommendedName, fullName, f, in, out, errout), cmd.NewCmdRsync(cmd.RsyncRecommendedName, fullName, f, out, errout), @@ -121,6 +122,7 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) * Commands: []*cobra.Command{ cmd.NewCmdCreate(fullName, f, out), cmd.NewCmdReplace(fullName, f, out), + cmd.NewCmdApply(fullName, f, out), cmd.NewCmdPatch(fullName, f, out), cmd.NewCmdProcess(fullName, f, out), cmd.NewCmdExport(fullName, f, in, out), @@ -128,6 +130,7 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) * cmd.NewCmdAttach(fullName, f, in, out, errout), policy.NewCmdPolicy(policy.PolicyRecommendedName, fullName+" "+policy.PolicyRecommendedName, f, out), secrets.NewCmdSecrets(secrets.SecretsRecommendedName, fullName+" "+secrets.SecretsRecommendedName, f, in, out, fullName+" edit"), + cmd.NewCmdConvert(fullName, f, out), }, }, { diff --git a/pkg/cmd/cli/cmd/deploy.go b/pkg/cmd/cli/cmd/deploy.go index 8f93e43e9e9a..1965d43b98ab 100644 --- a/pkg/cmd/cli/cmd/deploy.go +++ b/pkg/cmd/cli/cmd/deploy.go @@ -284,7 +284,7 @@ func (o DeployOptions) retry(config *deployapi.DeploymentConfig, out io.Writer) // cancel cancels any deployment process in progress for config. func (o DeployOptions) cancel(config *deployapi.DeploymentConfig, out io.Writer) error { - deployments, err := o.kubeClient.ReplicationControllers(config.Namespace).List(deployutil.ConfigSelector(config.Name)) + deployments, err := o.kubeClient.ReplicationControllers(config.Namespace).List(deployutil.ConfigSelector(config.Name), fields.Everything()) if err != nil { return err } diff --git a/pkg/cmd/cli/cmd/exporter.go b/pkg/cmd/cli/cmd/exporter.go index 0150847ecb99..f2a5de954606 100644 --- a/pkg/cmd/cli/cmd/exporter.go +++ b/pkg/cmd/cli/cmd/exporter.go @@ -8,9 +8,7 @@ import ( "github.com/spf13/pflag" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" - + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/registry/controller" "k8s.io/kubernetes/pkg/registry/endpoint" "k8s.io/kubernetes/pkg/registry/namespace" @@ -21,6 +19,7 @@ import ( "k8s.io/kubernetes/pkg/registry/resourcequota" "k8s.io/kubernetes/pkg/registry/secret" "k8s.io/kubernetes/pkg/registry/serviceaccount" + "k8s.io/kubernetes/pkg/runtime" buildapi "github.com/openshift/origin/pkg/build/api" buildrest "github.com/openshift/origin/pkg/build/registry/build" @@ -47,7 +46,7 @@ func exportObjectMeta(objMeta *kapi.ObjectMeta, exact bool) { if !exact { objMeta.Namespace = "" } - objMeta.CreationTimestamp = util.Time{} + objMeta.CreationTimestamp = unversioned.Time{} objMeta.DeletionTimestamp = nil objMeta.ResourceVersion = "" objMeta.SelfLink = "" diff --git a/pkg/cmd/cli/cmd/expose.go b/pkg/cmd/cli/cmd/expose.go index 32517a9acd94..a32fac782fc7 100644 --- a/pkg/cmd/cli/cmd/expose.go +++ b/pkg/cmd/cli/cmd/expose.go @@ -176,7 +176,7 @@ func validateFlags(cmd *cobra.Command, generator string) error { if len(cmdutil.GetFlagString(cmd, "external-ip")) != 0 { invalidFlags = append(invalidFlags, "--external-ip") } - if cmdutil.GetFlagInt(cmd, "port") != -1 { + if len(cmdutil.GetFlagString(cmd, "port")) != 0 { invalidFlags = append(invalidFlags, "--port") } if cmdutil.GetFlagBool(cmd, "create-external-load-balancer") { diff --git a/pkg/cmd/cli/cmd/logs.go b/pkg/cmd/cli/cmd/logs.go index 46cbc8f3c16b..6ab25da00323 100644 --- a/pkg/cmd/cli/cmd/logs.go +++ b/pkg/cmd/cli/cmd/logs.go @@ -9,7 +9,8 @@ import ( "github.com/spf13/cobra" - kclient "k8s.io/kubernetes/pkg/client/unversioned" + kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" kcmd "k8s.io/kubernetes/pkg/kubectl/cmd" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -37,23 +38,21 @@ If the pod has only one container, the container name is optional.` ) type OpenShiftLogsOptions struct { - KubeClient *kclient.Client OriginClient *client.Client Namespace string ResourceString string - ContainerName string - Follow bool - Interactive bool - Previous bool - Out io.Writer + + KubeLogOptions *kcmd.LogsOptions } // NewCmdLogs creates a new pod log command func NewCmdLogs(fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { o := &OpenShiftLogsOptions{ - Out: out, - Interactive: true, + KubeLogOptions: &kcmd.LogsOptions{ + Out: out, + Tail: -1, + }, } cmd := &cobra.Command{ @@ -71,10 +70,18 @@ func NewCmdLogs(fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Com }, Aliases: []string{"log"}, } - cmd.Flags().BoolVarP(&o.Follow, "follow", "f", o.Follow, "Specify if the logs should be streamed.") - cmd.Flags().BoolVar(&o.Interactive, "interactive", o.Interactive, "If true, prompt the user for input when required. Default true.") - cmd.Flags().BoolVarP(&o.Previous, "previous", "p", o.Previous, "If true, print the logs for the previous instance of the container in a pod if it exists.") - cmd.Flags().StringVarP(&o.ContainerName, "container", "c", o.ContainerName, "Container name") + + cmd.Flags().BoolVarP(&o.KubeLogOptions.Follow, "follow", "f", o.KubeLogOptions.Follow, "Specify if the logs should be streamed.") + cmd.Flags().BoolVar(&o.KubeLogOptions.Timestamps, "timestamps", o.KubeLogOptions.Timestamps, "Include timestamps on each line in the log output") + cmd.Flags().Bool("interactive", true, "If true, prompt the user for input when required. Default true.") + cmd.Flags().MarkDeprecated("interactive", "This flag is no longer respected and there is no replacement.") + cmd.Flags().IntVar(&o.KubeLogOptions.LimitBytes, "limit-bytes", o.KubeLogOptions.LimitBytes, "Maximum bytes of logs to return. Defaults to no limit.") + cmd.Flags().BoolVarP(&o.KubeLogOptions.Previous, "previous", "p", o.KubeLogOptions.Previous, "If true, print the logs for the previous instance of the container in a pod if it exists.") + cmd.Flags().IntVar(&o.KubeLogOptions.Tail, "tail", o.KubeLogOptions.Tail, "Lines of recent log file to display. Defaults to -1, showing all log lines.") + cmd.Flags().String("since-time", "", "Only return logs after a specific date (RFC3339). Defaults to all logs. Only one of since-time / since may be used.") + cmd.Flags().DurationVar(&o.KubeLogOptions.SinceSeconds, "since", o.KubeLogOptions.SinceSeconds, "Only return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to all logs. Only one of since-time / since may be used.") + cmd.Flags().StringVarP(&o.KubeLogOptions.ContainerName, "container", "c", o.KubeLogOptions.ContainerName, "Container name") + return cmd } @@ -87,7 +94,7 @@ func (o *OpenShiftLogsOptions) Complete(f *clientcmd.Factory, out io.Writer, cmd o.ResourceString = args[0] case 2: o.ResourceString = args[0] - o.ContainerName = args[1] + o.KubeLogOptions.ContainerName = args[1] default: return cmdutil.UsageError(cmd, "log RESOURCE") @@ -98,11 +105,23 @@ func (o *OpenShiftLogsOptions) Complete(f *clientcmd.Factory, out io.Writer, cmd if err != nil { return err } - o.OriginClient, o.KubeClient, err = f.Clients() + o.OriginClient, o.KubeLogOptions.Client, err = f.Clients() if err != nil { return err } + o.KubeLogOptions.PodName = o.ResourceString + o.KubeLogOptions.PodNamespace = o.Namespace + + sinceTime := cmdutil.GetFlagString(cmd, "since-time") + if len(sinceTime) > 0 { + t, err := kapi.ParseRFC3339(sinceTime, unversioned.Now) + if err != nil { + return err + } + o.KubeLogOptions.SinceTime = &t + } + return nil } @@ -111,21 +130,10 @@ func (o *OpenShiftLogsOptions) Validate() error { return errors.New("RESOURCE must be specified") } - return nil + return o.KubeLogOptions.Validate() } func (o *OpenShiftLogsOptions) RunLog() error { - kLogsOptions := &kcmd.LogsOptions{ - Client: o.KubeClient, - - PodNamespace: o.Namespace, - ContainerName: o.ContainerName, - Follow: o.Follow, - Interactive: o.Interactive, - Previous: o.Previous, - Out: o.Out, - } - resourceType := "pod" resourceName := o.ResourceString tokens := strings.SplitN(o.ResourceString, "/", 2) @@ -136,9 +144,13 @@ func (o *OpenShiftLogsOptions) RunLog() error { resourceType = strings.ToLower(resourceType) // if we're requesting a pod, delegate directly to kubectl logs - if (resourceType == "pods") || (resourceType == "pod") || len(o.ContainerName) > 0 { - kLogsOptions.PodName = resourceName - return kLogsOptions.RunLog() + if (resourceType == "pods") || (resourceType == "pod") || (resourceType == "po") { + o.KubeLogOptions.PodName = resourceName + return o.KubeLogOptions.RunLog() + } + + if len(o.KubeLogOptions.ContainerName) > 0 { + return errors.New("container cannot be specified with anything besides a pod") } switch resourceType { @@ -172,7 +184,7 @@ func (o *OpenShiftLogsOptions) RunLog() error { // to take advantage of all of their extra options. func (o *OpenShiftLogsOptions) runLogsForBuild(build *buildapi.Build) error { opts := buildapi.BuildLogOptions{ - Follow: o.Follow, + Follow: o.KubeLogOptions.Follow, NoWait: false, } @@ -182,6 +194,6 @@ func (o *OpenShiftLogsOptions) runLogsForBuild(build *buildapi.Build) error { } defer readCloser.Close() - _, err = io.Copy(o.Out, readCloser) + _, err = io.Copy(o.KubeLogOptions.Out, readCloser) return err } diff --git a/pkg/cmd/cli/cmd/process.go b/pkg/cmd/cli/cmd/process.go index 288f1d39c71b..5856f042cfee 100644 --- a/pkg/cmd/cli/cmd/process.go +++ b/pkg/cmd/cli/cmd/process.go @@ -10,6 +10,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/kubectl" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" @@ -129,7 +130,7 @@ func RunProcess(f *clientcmd.Factory, out io.Writer, cmd *cobra.Command, args [] } return err } - templateObj.CreationTimestamp = util.Now() + templateObj.CreationTimestamp = unversioned.Now() infos = append(infos, &resource.Info{Object: templateObj}) } else { infos, err = resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). @@ -231,7 +232,7 @@ func RunProcess(f *clientcmd.Factory, out io.Writer, cmd *cobra.Command, args [] } return p.PrintObj(&kapi.List{ - ListMeta: kapi.ListMeta{}, + ListMeta: unversioned.ListMeta{}, Items: objects, }, out) } diff --git a/pkg/cmd/cli/cmd/rollback.go b/pkg/cmd/cli/cmd/rollback.go index 1fb8cc858af1..e74733221c74 100644 --- a/pkg/cmd/cli/cmd/rollback.go +++ b/pkg/cmd/cli/cmd/rollback.go @@ -10,6 +10,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kerrors "k8s.io/kubernetes/pkg/api/errors" kclient "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/fields" kubectl "k8s.io/kubernetes/pkg/kubectl" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" @@ -308,7 +309,7 @@ func (o *RollbackOptions) findResource(targetName string) (runtime.Object, error // version will be returned. func (o *RollbackOptions) findTargetDeployment(config *deployapi.DeploymentConfig, desiredVersion int) (*kapi.ReplicationController, error) { // Find deployments for the config sorted by version descending. - deployments, err := o.kc.ReplicationControllers(config.Namespace).List(deployutil.ConfigSelector(config.Name)) + deployments, err := o.kc.ReplicationControllers(config.Namespace).List(deployutil.ConfigSelector(config.Name), fields.Everything()) if err != nil { return nil, err } diff --git a/pkg/cmd/cli/cmd/wrappers.go b/pkg/cmd/cli/cmd/wrappers.go index 84f8b0a8d445..d3f40f12b30b 100644 --- a/pkg/cmd/cli/cmd/wrappers.go +++ b/pkg/cmd/cli/cmd/wrappers.go @@ -8,7 +8,7 @@ import ( "github.com/spf13/cobra" kcmd "k8s.io/kubernetes/pkg/kubectl/cmd" - kutil "k8s.io/kubernetes/pkg/util" + kvalidation "k8s.io/kubernetes/pkg/util/validation" "github.com/openshift/origin/pkg/cmd/cli/describe" "github.com/openshift/origin/pkg/cmd/util/clientcmd" @@ -427,7 +427,78 @@ resource-version will be used.` // NewCmdLabel is a wrapper for the Kubernetes cli label command func NewCmdLabel(fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { cmd := kcmd.NewCmdLabel(f.Factory, out) - cmd.Long = fmt.Sprintf(labelLong, kutil.LabelValueMaxLength) + cmd.Long = fmt.Sprintf(labelLong, kvalidation.LabelValueMaxLength) cmd.Example = fmt.Sprintf(labelExample, fullName) return cmd } + +const ( + applyLong = `Apply a configuration to a resource by filename or stdin. + +JSON and YAML formats are accepted.` + + applyExample = `# Apply the configuration in pod.json to a pod. +$ %[1]s apply -f ./pod.json + +# Apply the JSON passed into stdin to a pod. +$ cat pod.json | %[1]s apply -f -` +) + +func NewCmdApply(fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { + cmd := kcmd.NewCmdApply(f.Factory, out) + cmd.Long = applyLong + cmd.Example = fmt.Sprintf(applyExample, fullName) + return cmd +} + +const ( + explainLong = `Documentation of resources. + +Possible resource types include: pods (po), services (svc), +replicationcontrollers (rc), nodes (no), events (ev), componentstatuses (cs), +limitranges (limits), persistentvolumes (pv), persistentvolumeclaims (pvc), +resourcequotas (quota), namespaces (ns) or endpoints (ep).` + + explainExample = `# Get the documentation of the resource and its fields +$ %[1]s explain pods + +# Get the documentation of a specific field of a resource +$ %[1]s explain pods.spec.containers` +) + +func NewCmdExplain(fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { + cmd := kcmd.NewCmdExplain(f.Factory, out) + cmd.Long = explainLong + cmd.Example = fmt.Sprintf(explainExample, fullName) + return cmd +} + +const ( + convertLong = `Convert config files between different API versions. Both YAML +and JSON formats are accepted. + +The command takes filename, directory, or URL as input, and convert it into format +of version specified by --output-version flag. If target version is not specified or +not supported, convert to latest version. + +The default output will be printed to stdout in YAML format. One can use -o option +to change to output destination. +` + convertExample = `# Convert 'pod.yaml' to latest version and print to stdout. +$ %[1]s convert -f pod.yaml + +# Convert the live state of the resource specified by 'pod.yaml' to the latest version +# and print to stdout in json format. +$ %[1]s convert -f pod.yaml --local -o json + +# Convert all files under current directory to latest version and create them all. +$ %[1]s convert -f . | kubectl create -f - +` +) + +func NewCmdConvert(fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { + cmd := kcmd.NewCmdConvert(f.Factory, out) + cmd.Long = convertLong + cmd.Example = fmt.Sprintf(convertExample, fullName) + return cmd +} diff --git a/pkg/cmd/cli/describe/deployments.go b/pkg/cmd/cli/describe/deployments.go index 1416ad85da2f..a7e9c2a441ea 100644 --- a/pkg/cmd/cli/describe/deployments.go +++ b/pkg/cmd/cli/describe/deployments.go @@ -101,7 +101,7 @@ func NewDeploymentConfigDescriber(client client.Interface, kclient kclient.Inter return kclient.ReplicationControllers(namespace).Get(name) }, listDeploymentsFunc: func(namespace string, selector labels.Selector) (*kapi.ReplicationControllerList, error) { - return kclient.ReplicationControllers(namespace).List(selector) + return kclient.ReplicationControllers(namespace).List(selector, fields.Everything()) }, listPodsFunc: func(namespace string, selector labels.Selector) (*kapi.PodList, error) { return kclient.Pods(namespace).List(selector, fields.Everything()) @@ -324,7 +324,7 @@ func NewLatestDeploymentsDescriber(client client.Interface, kclient kclient.Inte return kclient.ReplicationControllers(namespace).Get(name) }, listDeploymentsFunc: func(namespace string, selector labels.Selector) (*kapi.ReplicationControllerList, error) { - return kclient.ReplicationControllers(namespace).List(selector) + return kclient.ReplicationControllers(namespace).List(selector, fields.Everything()) }, listPodsFunc: func(namespace string, selector labels.Selector) (*kapi.PodList, error) { return kclient.Pods(namespace).List(selector, fields.Everything()) diff --git a/pkg/cmd/cli/describe/describer.go b/pkg/cmd/cli/describe/describer.go index 03605db10d44..c5630e6ef652 100644 --- a/pkg/cmd/cli/describe/describer.go +++ b/pkg/cmd/cli/describe/describer.go @@ -16,12 +16,12 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kerrs "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" kclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" kctl "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" authorizationapi "github.com/openshift/origin/pkg/authorization/api" @@ -149,7 +149,7 @@ func (d *BuildDescriber) Describe(namespace, name string) (string, error) { } func describeBuildDuration(build *buildapi.Build) string { - t := util.Now().Rfc3339Copy() + t := unversioned.Now().Rfc3339Copy() if build.Status.StartTimestamp == nil && build.Status.CompletionTimestamp != nil && (build.Status.Phase == buildapi.BuildPhaseCancelled || @@ -595,12 +595,12 @@ func (d *ProjectDescriber) Describe(namespace, name string) (string, error) { return "", err } resourceQuotasClient := d.kubeClient.ResourceQuotas(name) - resourceQuotaList, err := resourceQuotasClient.List(labels.Everything()) + resourceQuotaList, err := resourceQuotasClient.List(labels.Everything(), fields.Everything()) if err != nil { return "", err } limitRangesClient := d.kubeClient.LimitRanges(name) - limitRangeList, err := limitRangesClient.List(labels.Everything()) + limitRangeList, err := limitRangesClient.List(labels.Everything(), fields.Everything()) if err != nil { return "", err } diff --git a/pkg/cmd/cli/describe/describer_test.go b/pkg/cmd/cli/describe/describer_test.go index 496d7f7fc85b..51f9d284608f 100644 --- a/pkg/cmd/cli/describe/describer_test.go +++ b/pkg/cmd/cli/describe/describer_test.go @@ -217,7 +217,7 @@ func TestDescribeBuildDuration(t *testing.T) { creation := kutil.Date(2015, time.April, 9, 6, 0, 0, 0, time.Local) // now a minute ago - minuteAgo := kutil.Unix(kutil.Now().Rfc3339Copy().Time.Unix()-60, 0) + minuteAgo := kutil.Unix(unversioned.Now().Rfc3339Copy().Time.Unix()-60, 0) start := kutil.Date(2015, time.April, 9, 6, 1, 0, 0, time.Local) completion := kutil.Date(2015, time.April, 9, 6, 2, 0, 0, time.Local) duration := completion.Rfc3339Copy().Time.Sub(start.Rfc3339Copy().Time) diff --git a/pkg/cmd/cli/describe/printer.go b/pkg/cmd/cli/describe/printer.go index 015deb1239e8..7d1f3c6edd17 100644 --- a/pkg/cmd/cli/describe/printer.go +++ b/pkg/cmd/cli/describe/printer.go @@ -8,9 +8,9 @@ import ( "text/tabwriter" "time" + "k8s.io/kubernetes/pkg/api/unversioned" kctl "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" authorizationapi "github.com/openshift/origin/pkg/authorization/api" @@ -321,7 +321,7 @@ func printImageStream(stream *imageapi.ImageStream, w io.Writer, withNamespace, tags := "" const numOfTagsShown = 3 - var latest util.Time + var latest unversioned.Time for _, list := range stream.Status.Tags { if len(list.Items) > 0 { if list.Items[0].Created.After(latest.Time) { diff --git a/pkg/cmd/cli/describe/projectstatus.go b/pkg/cmd/cli/describe/projectstatus.go index a8d755fb05bc..7b8c83044aa5 100644 --- a/pkg/cmd/cli/describe/projectstatus.go +++ b/pkg/cmd/cli/describe/projectstatus.go @@ -10,10 +10,10 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kapierrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" kclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/util" utilerrors "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/sets" @@ -404,11 +404,11 @@ func describeAdditionalBuildDetail(build *buildgraph.BuildConfigNode, lastSucces } out := []string{} - passTime := util.Time{} + passTime := unversioned.Time{} if lastSuccessfulBuild != nil { passTime = buildTimestamp(lastSuccessfulBuild.Build) } - failTime := util.Time{} + failTime := unversioned.Time{} if lastUnsuccessfulBuild != nil { failTime = buildTimestamp(lastUnsuccessfulBuild.Build) } @@ -444,7 +444,7 @@ func describeAdditionalBuildDetail(build *buildgraph.BuildConfigNode, lastSucces return out } -func describeBuildPhase(build *buildapi.Build, t *util.Time, parentName string, pushTargetResolved bool) string { +func describeBuildPhase(build *buildapi.Build, t *unversioned.Time, parentName string, pushTargetResolved bool) string { imageStreamFailure := "" // if we're using an image stream and that image stream is the internal registry and that registry doesn't exist if (build.Spec.Output.To != nil) && !pushTargetResolved { @@ -521,9 +521,9 @@ func describeSourceControlUser(user buildapi.SourceControlUser) string { return fmt.Sprintf("%s <%s>", user.Name, user.Email) } -func buildTimestamp(build *buildapi.Build) util.Time { +func buildTimestamp(build *buildapi.Build) unversioned.Time { if build == nil { - return util.Time{} + return unversioned.Time{} } if !build.Status.CompletionTimestamp.IsZero() { return *build.Status.CompletionTimestamp @@ -723,7 +723,7 @@ type rcLoader struct { } func (l *rcLoader) Load() error { - list, err := l.lister.ReplicationControllers(l.namespace).List(labels.Everything()) + list, err := l.lister.ReplicationControllers(l.namespace).List(labels.Everything(), fields.Everything()) if err != nil { return err } @@ -747,7 +747,7 @@ type serviceLoader struct { } func (l *serviceLoader) Load() error { - list, err := l.lister.Services(l.namespace).List(labels.Everything()) + list, err := l.lister.Services(l.namespace).List(labels.Everything(), fields.Everything()) if err != nil { return err } diff --git a/pkg/cmd/infra/deployer/deployer.go b/pkg/cmd/infra/deployer/deployer.go index b7ef86f9d35f..d579ad0eb932 100644 --- a/pkg/cmd/infra/deployer/deployer.go +++ b/pkg/cmd/infra/deployer/deployer.go @@ -9,6 +9,7 @@ import ( "github.com/spf13/cobra" kapi "k8s.io/kubernetes/pkg/api" kclient "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/kubectl" "github.com/openshift/origin/pkg/api/latest" @@ -78,13 +79,13 @@ func NewCommandDeployer(name string) *cobra.Command { // NewDeployer makes a new Deployer from a kube client. func NewDeployer(client kclient.Interface) *Deployer { - scaler, _ := kubectl.ScalerFor("ReplicationController", kubectl.NewScalerClient(client)) + scaler, _ := kubectl.ScalerFor("ReplicationController", client) return &Deployer{ getDeployment: func(namespace, name string) (*kapi.ReplicationController, error) { return client.ReplicationControllers(namespace).Get(name) }, getDeployments: func(namespace, configName string) (*kapi.ReplicationControllerList, error) { - return client.ReplicationControllers(namespace).List(deployutil.ConfigSelector(configName)) + return client.ReplicationControllers(namespace).List(deployutil.ConfigSelector(configName), fields.Everything()) }, scaler: scaler, strategyFor: func(config *deployapi.DeploymentConfig) (strategy.DeploymentStrategy, error) { diff --git a/pkg/cmd/server/admin/create_nodeconfig.go b/pkg/cmd/server/admin/create_nodeconfig.go index dd0d5c71d853..56c21dec2bce 100644 --- a/pkg/cmd/server/admin/create_nodeconfig.go +++ b/pkg/cmd/server/admin/create_nodeconfig.go @@ -432,7 +432,7 @@ func (o CreateNodeConfigOptions) MakeNodeJSON(nodeJSONFile string) error { node := &kapi.Node{} node.Name = o.NodeName - json, err := klatest.Codec.Encode(node) + json, err := klatest.CodecForLegacyGroup().Encode(node) if err != nil { return err } diff --git a/pkg/cmd/server/api/types.go b/pkg/cmd/server/api/types.go index 7d7e50bdd82d..f26af820b0c6 100644 --- a/pkg/cmd/server/api/types.go +++ b/pkg/cmd/server/api/types.go @@ -1,7 +1,7 @@ package api import ( - "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/sets" ) @@ -35,7 +35,7 @@ type ExtendedArguments map[string][]string // NodeConfig is the fully specified config starting an OpenShift node type NodeConfig struct { - api.TypeMeta + unversioned.TypeMeta // NodeName is the value used to identify this particular node in the cluster. If possible, this should be your fully qualified hostname. // If you're describing a set of static nodes to the master, this value must match one of the values in the list @@ -137,7 +137,7 @@ const ( type FeatureList []string type MasterConfig struct { - api.TypeMeta + unversioned.TypeMeta // ServingInfo describes how to start serving ServingInfo HTTPServingInfo @@ -492,7 +492,7 @@ type SessionConfig struct { // SessionSecrets list the secrets to use to sign/encrypt and authenticate/decrypt created sessions. type SessionSecrets struct { - api.TypeMeta + unversioned.TypeMeta // Secrets is a list of secrets // New sessions are signed and encrypted using the first secret. @@ -521,29 +521,29 @@ type IdentityProvider struct { } type BasicAuthPasswordIdentityProvider struct { - api.TypeMeta + unversioned.TypeMeta // RemoteConnectionInfo contains information about how to connect to the external basic auth server RemoteConnectionInfo RemoteConnectionInfo } type AllowAllPasswordIdentityProvider struct { - api.TypeMeta + unversioned.TypeMeta } type DenyAllPasswordIdentityProvider struct { - api.TypeMeta + unversioned.TypeMeta } type HTPasswdPasswordIdentityProvider struct { - api.TypeMeta + unversioned.TypeMeta // File is a reference to your htpasswd file File string } type LDAPPasswordIdentityProvider struct { - api.TypeMeta + unversioned.TypeMeta // URL is an RFC 2255 URL which specifies the LDAP search parameters to use. The syntax of the URL is // ldap://host:port/basedn?attribute?scope?filter URL string @@ -579,7 +579,7 @@ type LDAPAttributeMapping struct { } type KeystonePasswordIdentityProvider struct { - api.TypeMeta + unversioned.TypeMeta // RemoteConnectionInfo contains information about how to connect to the keystone server RemoteConnectionInfo RemoteConnectionInfo // Domain Name is required for keystone v3 @@ -587,7 +587,7 @@ type KeystonePasswordIdentityProvider struct { } type RequestHeaderIdentityProvider struct { - api.TypeMeta + unversioned.TypeMeta // LoginURL is a URL to redirect unauthenticated /authorize requests to // Unauthenticated requests from OAuth clients which expect interactive logins will be redirected here @@ -612,7 +612,7 @@ type RequestHeaderIdentityProvider struct { } type GitHubIdentityProvider struct { - api.TypeMeta + unversioned.TypeMeta // ClientID is the oauth client ID ClientID string @@ -621,7 +621,7 @@ type GitHubIdentityProvider struct { } type GoogleIdentityProvider struct { - api.TypeMeta + unversioned.TypeMeta // ClientID is the oauth client ID ClientID string @@ -633,7 +633,7 @@ type GoogleIdentityProvider struct { } type OpenIDIdentityProvider struct { - api.TypeMeta + unversioned.TypeMeta // CA is the optional trusted certificate authority bundle to use when making requests to the server // If empty, the default system roots are used @@ -779,7 +779,7 @@ type AssetExtensionsConfig struct { } type LDAPSyncConfig struct { - api.TypeMeta + unversioned.TypeMeta // URL is the scheme, host and port of the LDAP server to connect to: scheme://host:port URL string diff --git a/pkg/cmd/server/api/v1/types.go b/pkg/cmd/server/api/v1/types.go index b62e546b7b8f..61a5b5a70052 100644 --- a/pkg/cmd/server/api/v1/types.go +++ b/pkg/cmd/server/api/v1/types.go @@ -1,8 +1,7 @@ package v1 import ( - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" ) @@ -10,7 +9,7 @@ type ExtendedArguments map[string][]string // NodeConfig is the fully specified config starting an OpenShift node type NodeConfig struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // NodeName is the value used to identify this particular node in the cluster. If possible, this should be your fully qualified hostname. // If you're describing a set of static nodes to the master, this value must match one of the values in the list @@ -116,7 +115,7 @@ const ( type FeatureList []string type MasterConfig struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // ServingInfo describes how to start serving ServingInfo HTTPServingInfo `json:"servingInfo"` @@ -471,7 +470,7 @@ type SessionConfig struct { // SessionSecrets list the secrets to use to sign/encrypt and authenticate/decrypt created sessions. type SessionSecrets struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Secrets is a list of secrets // New sessions are signed and encrypted using the first secret. @@ -500,29 +499,29 @@ type IdentityProvider struct { } type BasicAuthPasswordIdentityProvider struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // RemoteConnectionInfo contains information about how to connect to the external basic auth server RemoteConnectionInfo `json:",inline"` } type AllowAllPasswordIdentityProvider struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` } type DenyAllPasswordIdentityProvider struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` } type HTPasswdPasswordIdentityProvider struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // File is a reference to your htpasswd file File string `json:"file"` } type LDAPPasswordIdentityProvider struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // URL is an RFC 2255 URL which specifies the LDAP search parameters to use. The syntax of the URL is // ldap://host:port/basedn?attribute?scope?filter URL string `json:"url"` @@ -558,7 +557,7 @@ type LDAPAttributeMapping struct { } type KeystonePasswordIdentityProvider struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // RemoteConnectionInfo contains information about how to connect to the keystone server RemoteConnectionInfo `json:",inline"` // Domain Name is required for keystone v3 @@ -566,7 +565,7 @@ type KeystonePasswordIdentityProvider struct { } type RequestHeaderIdentityProvider struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // LoginURL is a URL to redirect unauthenticated /authorize requests to // Unauthenticated requests from OAuth clients which expect interactive logins will be redirected here @@ -591,7 +590,7 @@ type RequestHeaderIdentityProvider struct { } type GitHubIdentityProvider struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // ClientID is the oauth client ID ClientID string `json:"clientID"` @@ -600,7 +599,7 @@ type GitHubIdentityProvider struct { } type GoogleIdentityProvider struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // ClientID is the oauth client ID ClientID string `json:"clientID"` @@ -612,7 +611,7 @@ type GoogleIdentityProvider struct { } type OpenIDIdentityProvider struct { - v1.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // CA is the optional trusted certificate authority bundle to use when making requests to the server // If empty, the default system roots are used @@ -754,7 +753,7 @@ type AssetExtensionsConfig struct { } type LDAPSyncConfig struct { - api.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Host is the scheme, host and port of the LDAP server to connect to: // scheme://host:port URL string `json:"url"` diff --git a/pkg/cmd/server/api/validation/master.go b/pkg/cmd/server/api/validation/master.go index 1ee9507af889..a05a5f1eb804 100644 --- a/pkg/cmd/server/api/validation/master.go +++ b/pkg/cmd/server/api/validation/master.go @@ -16,6 +16,7 @@ import ( "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" "k8s.io/kubernetes/pkg/util/sets" + kuval "k8s.io/kubernetes/pkg/util/validation" "github.com/openshift/origin/pkg/cmd/server/api" "github.com/openshift/origin/pkg/cmd/server/bootstrappolicy" @@ -467,7 +468,7 @@ func ValidateRoutingConfig(config api.RoutingConfig) fielderrors.ValidationError if len(config.Subdomain) == 0 { allErrs = append(allErrs, fielderrors.NewFieldRequired("subdomain")) - } else if !util.IsDNS1123Subdomain(config.Subdomain) { + } else if !kuval.IsDNS1123Subdomain(config.Subdomain) { allErrs = append(allErrs, fielderrors.NewFieldInvalid("subdomain", config.Subdomain, "must be a valid subdomain")) } diff --git a/pkg/cmd/server/api/validation/validation.go b/pkg/cmd/server/api/validation/validation.go index 99e72e76328f..771cfafd4dc7 100644 --- a/pkg/cmd/server/api/validation/validation.go +++ b/pkg/cmd/server/api/validation/validation.go @@ -12,9 +12,9 @@ import ( "github.com/spf13/pflag" kvalidation "k8s.io/kubernetes/pkg/api/validation" - kutil "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" "k8s.io/kubernetes/pkg/util/sets" + kuval "k8s.io/kubernetes/pkg/util/validation" "github.com/openshift/origin/pkg/cmd/server/api" cmdutil "github.com/openshift/origin/pkg/cmd/util" @@ -127,7 +127,7 @@ func ValidateNamedCertificates(fieldName string, namedCertificates []api.NamedCe // validate names as domain names or *.*.foo.com domain names validDNSName := true for _, s := range strings.Split(name, ".") { - if s != "*" && !kutil.IsDNS1123Label(s) { + if s != "*" && !kuval.IsDNS1123Label(s) { validDNSName = false } } diff --git a/pkg/cmd/server/bootstrappolicy/policy.go b/pkg/cmd/server/bootstrappolicy/policy.go index c64123d4e796..4c70c405a99b 100644 --- a/pkg/cmd/server/bootstrappolicy/policy.go +++ b/pkg/cmd/server/bootstrappolicy/policy.go @@ -313,6 +313,11 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole { Verbs: sets.NewString("get", "update"), Resources: sets.NewString("replicationcontrollers"), }, + // ReplicationManager.syncReplicationController() -> updateReplicaCount() + { + Verbs: sets.NewString("update"), + Resources: sets.NewString("replicationcontrollers/status"), + }, // ReplicationManager.podController.ListWatch { Verbs: sets.NewString("list", "watch"), diff --git a/pkg/cmd/server/kubernetes/master.go b/pkg/cmd/server/kubernetes/master.go index 46c683a49780..016db87a1435 100644 --- a/pkg/cmd/server/kubernetes/master.go +++ b/pkg/cmd/server/kubernetes/master.go @@ -45,9 +45,6 @@ func (c *MasterConfig) InstallAPI(container *restful.Container) []string { _ = master.New(c.Master) messages := []string{} - if c.Master.EnableV1Beta3 { - messages = append(messages, fmt.Sprintf("Started Kubernetes API at %%s%s (deprecated)", KubeAPIPrefixV1Beta3)) - } if !c.Master.DisableV1 { messages = append(messages, fmt.Sprintf("Started Kubernetes API at %%s%s", KubeAPIPrefixV1)) } @@ -58,7 +55,7 @@ func (c *MasterConfig) InstallAPI(container *restful.Container) []string { // RunNamespaceController starts the Kubernetes Namespace Manager func (c *MasterConfig) RunNamespaceController() { // TODO: Add OR c.ControllerManager.EnableDeploymentController once we have upstream deployments - experimentalMode := c.ControllerManager.EnableHorizontalPodAutoscaler + experimentalMode := c.ControllerManager.EnableExperimental namespaceController := namespacecontroller.NewNamespaceController(c.KubeClient, experimentalMode, c.ControllerManager.NamespaceSyncPeriod) namespaceController.Run() } @@ -99,13 +96,13 @@ func (c *MasterConfig) RunPersistentVolumeClaimRecycler(recyclerImageName string // RunReplicationController starts the Kubernetes replication controller sync loop func (c *MasterConfig) RunReplicationController(client *client.Client) { - controllerManager := replicationcontroller.NewReplicationManager(client, replicationcontroller.BurstReplicas) + controllerManager := replicationcontroller.NewReplicationManager(client, c.ControllerManager.ResyncPeriod, replicationcontroller.BurstReplicas) go controllerManager.Run(c.ControllerManager.ConcurrentRCSyncs, util.NeverStop) } // RunEndpointController starts the Kubernetes replication controller sync loop func (c *MasterConfig) RunEndpointController() { - endpoints := endpointcontroller.NewEndpointController(c.KubeClient) + endpoints := endpointcontroller.NewEndpointController(c.KubeClient, c.ControllerManager.ResyncPeriod) go endpoints.Run(c.ControllerManager.ConcurrentEndpointSyncs, util.NeverStop) } @@ -139,6 +136,7 @@ func (c *MasterConfig) RunNodeController() { s.PodEvictionTimeout, util.NewTokenBucketRateLimiter(s.DeletingPodsQps, s.DeletingPodsBurst), + util.NewTokenBucketRateLimiter(s.DeletingPodsQps, s.DeletingPodsBurst), // upstream uses the same ones too s.NodeMonitorGracePeriod, s.NodeStartupGracePeriod, diff --git a/pkg/cmd/server/kubernetes/master_config.go b/pkg/cmd/server/kubernetes/master_config.go index 42030f5ac132..ce4406282222 100644 --- a/pkg/cmd/server/kubernetes/master_config.go +++ b/pkg/cmd/server/kubernetes/master_config.go @@ -52,7 +52,7 @@ func BuildKubernetesMasterConfig(options configapi.MasterConfig, requestContextM if err != nil { return nil, err } - databaseStorage, err := master.NewEtcdStorage(etcdClient, kapilatest.InterfacesFor, options.EtcdStorageConfig.KubernetesStorageVersion, options.EtcdStorageConfig.KubernetesStoragePrefix) + databaseStorage, err := master.NewEtcdStorage(etcdClient, kapilatest.InterfacesForLegacyGroup, options.EtcdStorageConfig.KubernetesStorageVersion, options.EtcdStorageConfig.KubernetesStoragePrefix) if err != nil { return nil, fmt.Errorf("Error setting up Kubernetes server storage: %v", err) } @@ -147,12 +147,14 @@ func BuildKubernetesMasterConfig(options configapi.MasterConfig, requestContextM proxyClientCerts = append(proxyClientCerts, clientCert) } + storageDestinations := master.NewStorageDestinations() + storageDestinations.AddAPIGroup("", databaseStorage) + m := &master.Config{ PublicAddress: net.ParseIP(options.KubernetesMasterConfig.MasterIP), ReadWritePort: port, - DatabaseStorage: databaseStorage, - ExpDatabaseStorage: databaseStorage, + StorageDestinations: storageDestinations, EventTTL: server.EventTTL, //MinRequestTimeout: server.MinRequestTimeout, @@ -172,8 +174,7 @@ func BuildKubernetesMasterConfig(options configapi.MasterConfig, requestContextM Authorizer: apiserver.NewAlwaysAllowAuthorizer(), AdmissionControl: admissionController, - EnableV1Beta3: configapi.HasKubernetesAPILevel(*options.KubernetesMasterConfig, "v1beta3"), - DisableV1: !configapi.HasKubernetesAPILevel(*options.KubernetesMasterConfig, "v1"), + DisableV1: !configapi.HasKubernetesAPILevel(*options.KubernetesMasterConfig, "v1"), // Set the TLS options for proxying to pods and services // Proxying to nodes uses the kubeletClient TLS config (so can provide a different cert, and verify the node hostname) diff --git a/pkg/cmd/server/kubernetes/node.go b/pkg/cmd/server/kubernetes/node.go index e3821ddcd8cc..e34f5b862997 100644 --- a/pkg/cmd/server/kubernetes/node.go +++ b/pkg/cmd/server/kubernetes/node.go @@ -17,6 +17,7 @@ import ( pconfig "k8s.io/kubernetes/pkg/proxy/config" proxy "k8s.io/kubernetes/pkg/proxy/userspace" "k8s.io/kubernetes/pkg/util" + utildbus "k8s.io/kubernetes/pkg/util/dbus" kexec "k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/iptables" @@ -140,7 +141,7 @@ func (c *NodeConfig) RunKubelet() { c.KubeletConfig.RootDirectory = c.VolumeDir // hook for overriding the cadvisor interface for integration tests - c.KubeletConfig.CadvisorInterface = defaultCadvisorInterface + c.KubeletConfig.CAdvisorInterface = defaultCadvisorInterface go func() { glog.Fatal(c.KubeletServer.Run(c.KubeletConfig)) @@ -194,7 +195,9 @@ func (c *NodeConfig) RunProxy(endpointsFilterer FilteringEndpointsConfigHandler) } go util.Forever(func() { - proxier, err := proxy.NewProxier(loadBalancer, ip, iptables.New(kexec.New(), protocol), util.PortRange{}, syncPeriod) + dbus := utildbus.New() + iptables := iptables.New(kexec.New(), dbus, protocol) + proxier, err := proxy.NewProxier(loadBalancer, ip, iptables, util.PortRange{}, syncPeriod) if err != nil { switch { // conflicting use of iptables, retry diff --git a/pkg/cmd/server/kubernetes/node_config.go b/pkg/cmd/server/kubernetes/node_config.go index 598f8188be2c..136d9610082b 100644 --- a/pkg/cmd/server/kubernetes/node_config.go +++ b/pkg/cmd/server/kubernetes/node_config.go @@ -14,6 +14,7 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/kubelet" "k8s.io/kubernetes/pkg/kubelet/dockertools" + kubelettypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/errors" @@ -119,14 +120,14 @@ func BuildKubernetesNodeConfig(options configapi.NodeConfig) (*NodeConfig, error server.Address = kubeAddress server.Port = uint(kubePort) server.ReadOnlyPort = 0 // no read only access - server.CadvisorPort = 0 // no unsecured cadvisor access + server.CAdvisorPort = 0 // no unsecured cadvisor access server.HealthzPort = 0 // no unsecured healthz access server.ClusterDNS = dnsIP server.ClusterDomain = options.DNSDomain server.NetworkPluginName = options.NetworkConfig.NetworkPluginName - server.HostNetworkSources = strings.Join([]string{kubelet.ApiserverSource, kubelet.FileSource}, ",") - server.HostPIDSources = strings.Join([]string{kubelet.ApiserverSource, kubelet.FileSource}, ",") - server.HostIPCSources = strings.Join([]string{kubelet.ApiserverSource, kubelet.FileSource}, ",") + server.HostNetworkSources = strings.Join([]string{kubelettypes.ApiserverSource, kubelettypes.FileSource}, ",") + server.HostPIDSources = strings.Join([]string{kubelettypes.ApiserverSource, kubelettypes.FileSource}, ",") + server.HostIPCSources = strings.Join([]string{kubelettypes.ApiserverSource, kubelettypes.FileSource}, ",") server.HTTPCheckFrequency = 0 // no remote HTTP pod creation access server.FileCheckFrequency = time.Duration(fileCheckInterval) * time.Second server.PodInfraContainerImage = imageTemplate.ExpandOrDie("pod") diff --git a/pkg/cmd/server/origin/asset.go b/pkg/cmd/server/origin/asset.go index decfc4fbff1d..193b9a6a0cc2 100644 --- a/pkg/cmd/server/origin/asset.go +++ b/pkg/cmd/server/origin/asset.go @@ -163,7 +163,7 @@ func (c *AssetConfig) addHandlers(mux *http.ServeMux) error { versions := sets.NewString() versions.Insert(latest.Versions...) - versions.Insert(klatest.Versions...) + versions.Insert(klatest.VersionsForLegacyGroup()...) for _, version := range versions.List() { for kind, t := range api.Scheme.KnownTypes(version) { if strings.Contains(t.PkgPath(), "kubernetes/pkg/expapi") { diff --git a/pkg/cmd/server/origin/handlers.go b/pkg/cmd/server/origin/handlers.go index 22da388f4b97..8e9be8d5354f 100644 --- a/pkg/cmd/server/origin/handlers.go +++ b/pkg/cmd/server/origin/handlers.go @@ -14,10 +14,10 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kapierrors "k8s.io/kubernetes/pkg/api/errors" klatest "k8s.io/kubernetes/pkg/api/latest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apiserver" "k8s.io/kubernetes/pkg/util/sets" - "github.com/openshift/origin/pkg/api/latest" "github.com/openshift/origin/pkg/authorization/authorizer" ) @@ -27,7 +27,7 @@ func indexAPIPaths(handler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { if req.URL.Path == "/" { // TODO once we have a MuxHelper we will not need to hardcode this list of paths - object := kapi.RootPaths{Paths: []string{ + object := unversioned.RootPaths{Paths: []string{ "/api", "/api/v1beta3", "/api/v1", @@ -94,7 +94,7 @@ func (c *MasterConfig) authorizationFilter(handler http.Handler) http.Handler { func forbidden(reason string, attributes authorizer.AuthorizationAttributes, w http.ResponseWriter, req *http.Request) { kind := "" name := "" - apiVersion := klatest.Version + apiVersion := klatest.DefaultVersionForLegacyGroup() // the attributes can be empty for two basic reasons: // 1. malformed API request // 2. not an API request at all @@ -114,8 +114,8 @@ func forbidden(reason string, attributes authorizer.AuthorizationAttributes, w h // Not all API versions in valid API requests will have a matching codec in kubernetes. If we can't find one, // just default to the latest kube codec. - codec := klatest.Codec - if requestedCodec, err := klatest.InterfacesFor(apiVersion); err == nil { + codec := klatest.CodecForLegacyGroup() + if requestedCodec, err := klatest.InterfacesForLegacyGroup(apiVersion); err == nil { codec = requestedCodec } @@ -143,7 +143,7 @@ func cacheControlFilter(handler http.Handler, value string) http.Handler { // namespacingFilter adds a filter that adds the namespace of the request to the context. Not all requests will have namespaces, // but any that do will have the appropriate value added. func namespacingFilter(handler http.Handler, contextMapper kapi.RequestContextMapper) http.Handler { - infoResolver := &apiserver.APIRequestInfoResolver{APIPrefixes: sets.NewString("api", "osapi", "oapi"), RestMapper: latest.RESTMapper} + infoResolver := &apiserver.APIRequestInfoResolver{APIPrefixes: sets.NewString("api", "osapi", "oapi"), GrouplessAPIPrefixes: sets.NewString("api", "osapi", "oapi")} return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { ctx, ok := contextMapper.Get(req) diff --git a/pkg/cmd/server/origin/master_config.go b/pkg/cmd/server/origin/master_config.go index bc3136baee00..d26b299da8d5 100644 --- a/pkg/cmd/server/origin/master_config.go +++ b/pkg/cmd/server/origin/master_config.go @@ -252,7 +252,7 @@ func newServiceAccountTokenGetter(options configapi.MasterConfig, client *etcdcl tokenGetter = serviceaccount.NewGetterFromClient(kubeClient) } else { // When we're running in-process, go straight to etcd (using the KubernetesStorageVersion/KubernetesStoragePrefix, since service accounts are kubernetes objects) - ketcdHelper, err := master.NewEtcdStorage(client, kapilatest.InterfacesFor, options.EtcdStorageConfig.KubernetesStorageVersion, options.EtcdStorageConfig.KubernetesStoragePrefix) + ketcdHelper, err := master.NewEtcdStorage(client, kapilatest.InterfacesForLegacyGroup, options.EtcdStorageConfig.KubernetesStorageVersion, options.EtcdStorageConfig.KubernetesStoragePrefix) if err != nil { return nil, fmt.Errorf("Error setting up Kubernetes server storage: %v", err) } @@ -334,7 +334,7 @@ func newAuthorizer(policyClient policyclient.ReadOnlyPolicyClient, projectReques } func newAuthorizationAttributeBuilder(requestContextMapper kapi.RequestContextMapper) authorizer.AuthorizationAttributeBuilder { - authorizationAttributeBuilder := authorizer.NewAuthorizationAttributeBuilder(requestContextMapper, &apiserver.APIRequestInfoResolver{APIPrefixes: sets.NewString("api", "osapi", "oapi"), RestMapper: latest.RESTMapper}) + authorizationAttributeBuilder := authorizer.NewAuthorizationAttributeBuilder(requestContextMapper, &apiserver.APIRequestInfoResolver{APIPrefixes: sets.NewString("api", "osapi", "oapi"), GrouplessAPIPrefixes: sets.NewString("api", "osapi", "oapi")}) return authorizationAttributeBuilder } diff --git a/pkg/cmd/server/start/kubernetes/proxy.go b/pkg/cmd/server/start/kubernetes/proxy.go index 435c2ba940ca..fa7a748aad63 100644 --- a/pkg/cmd/server/start/kubernetes/proxy.go +++ b/pkg/cmd/server/start/kubernetes/proxy.go @@ -10,6 +10,7 @@ import ( "github.com/spf13/pflag" "k8s.io/kubernetes/cmd/kube-proxy/app" + kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/util" ) @@ -20,7 +21,7 @@ This command launches an instance of the Kubernetes proxy (kube-proxy).` // NewProxyCommand provides a CLI handler for the 'proxy' command func NewProxyCommand(name, fullName string, out io.Writer) *cobra.Command { - s := app.NewProxyServer() + proxyConfig := app.NewProxyConfig() cmd := &cobra.Command{ Use: name, @@ -32,6 +33,9 @@ func NewProxyCommand(name, fullName string, out io.Writer) *cobra.Command { util.InitLogs() defer util.FlushLogs() + s, err := app.NewProxyServerDefault(proxyConfig) + kcmdutil.CheckErr(err) + if err := s.Run(pflag.CommandLine.Args()); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) @@ -43,7 +47,7 @@ func NewProxyCommand(name, fullName string, out io.Writer) *cobra.Command { flags := cmd.Flags() flags.SetNormalizeFunc(util.WordSepNormalizeFunc) flags.AddGoFlagSet(flag.CommandLine) - s.AddFlags(flags) + proxyConfig.AddFlags(flags) return cmd } diff --git a/pkg/cmd/server/start/start_master.go b/pkg/cmd/server/start/start_master.go index 53e01ee9ee01..4a1885d90333 100644 --- a/pkg/cmd/server/start/start_master.go +++ b/pkg/cmd/server/start/start_master.go @@ -18,7 +18,7 @@ import ( kerrors "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/capabilities" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" - "k8s.io/kubernetes/pkg/kubelet" + kubelettypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/util/sets" "github.com/openshift/origin/pkg/cmd/server/admin" @@ -368,9 +368,9 @@ func (m *Master) Start() error { capabilities.Initialize(capabilities.Capabilities{ AllowPrivileged: true, PrivilegedSources: capabilities.PrivilegedSources{ - HostNetworkSources: []string{kubelet.ApiserverSource, kubelet.FileSource}, - HostPIDSources: []string{kubelet.ApiserverSource, kubelet.FileSource}, - HostIPCSources: []string{kubelet.ApiserverSource, kubelet.FileSource}, + HostNetworkSources: []string{kubelettypes.ApiserverSource, kubelettypes.FileSource}, + HostPIDSources: []string{kubelettypes.ApiserverSource, kubelettypes.FileSource}, + HostIPCSources: []string{kubelettypes.ApiserverSource, kubelettypes.FileSource}, }, }) diff --git a/pkg/cmd/util/clientcmd/factory.go b/pkg/cmd/util/clientcmd/factory.go index 242488d0dfd8..547c72b9c5ec 100644 --- a/pkg/cmd/util/clientcmd/factory.go +++ b/pkg/cmd/util/clientcmd/factory.go @@ -239,6 +239,12 @@ func (e ShortcutExpander) AliasesForResource(resource string) ([]string, bool) { return nil, false } +// ResourceIsValid takes a string (kind) and checks if it's a valid resource. +// It expands the resource first, then invokes the wrapped mapper. +func (e ShortcutExpander) ResourceIsValid(resource string) bool { + return e.RESTMapper.ResourceIsValid(expandResourceShortcut(resource)) +} + // expandResourceShortcut will return the expanded version of resource // (something that a pkg/api/meta.RESTMapper can understand), if it is // indeed a shortcut. Otherwise, will return resource unmodified. diff --git a/pkg/cmd/util/clientcmd/factory_fake.go b/pkg/cmd/util/clientcmd/factory_fake.go deleted file mode 100644 index 18a925db310a..000000000000 --- a/pkg/cmd/util/clientcmd/factory_fake.go +++ /dev/null @@ -1,151 +0,0 @@ -package clientcmd - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/latest" - "k8s.io/kubernetes/pkg/api/meta" - "k8s.io/kubernetes/pkg/api/testapi" - "k8s.io/kubernetes/pkg/api/validation" - kclient "k8s.io/kubernetes/pkg/client/unversioned" - clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" - "k8s.io/kubernetes/pkg/kubectl" - cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" - "k8s.io/kubernetes/pkg/kubectl/resource" - "k8s.io/kubernetes/pkg/runtime" - - "github.com/openshift/origin/pkg/client" -) - -type fakeClientConfig struct { - Raw clientcmdapi.Config - Client *kclient.Config - NS string - Explicit bool - Err error -} - -// RawConfig returns the merged result of all overrides -func (c *fakeClientConfig) RawConfig() (clientcmdapi.Config, error) { - return c.Raw, c.Err -} - -// ClientConfig returns a complete client config -func (c *fakeClientConfig) ClientConfig() (*kclient.Config, error) { - return c.Client, c.Err -} - -// Namespace returns the namespace resulting from the merged result of all overrides -func (c *fakeClientConfig) Namespace() (string, bool, error) { - return c.NS, c.Explicit, c.Err -} - -type testPrinter struct { - Objects []runtime.Object - Err error -} - -func (t *testPrinter) PrintObj(obj runtime.Object, out io.Writer) error { - t.Objects = append(t.Objects, obj) - fmt.Fprintf(out, "%#v", obj) - return t.Err -} - -func (t *testPrinter) HandledResources() []string { - return []string{} -} - -type testFactory struct { - Mapper meta.RESTMapper - Typer runtime.ObjectTyper - Client kubectl.RESTClient - Describer kubectl.Describer - Printer kubectl.ResourcePrinter - Validator validation.Schema - Namespace string - ClientConfig *kclient.Config - Err error -} - -// newFakeKubeFactory returns a new fake Kubernetes factory -// TODO: Use this from upstream -func newFakeKubeFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) { - t := &testFactory{ - Client: &kclient.FakeRESTClient{}, - Printer: &testPrinter{}, - Validator: validation.NullSchema{}, - ClientConfig: &kclient.Config{}, - } - generators := map[string]kubectl.Generator{ - "run/v1": kubectl.BasicReplicationController{}, - "service/v1": kubectl.ServiceGeneratorV1{}, - "service/v2": kubectl.ServiceGeneratorV2{}, - } - return &cmdutil.Factory{ - Object: func() (meta.RESTMapper, runtime.ObjectTyper) { - return latest.RESTMapper, api.Scheme - }, - Client: func() (*kclient.Client, error) { - // Swap out the HTTP client out of the client with the fake's version. - fakeClient := t.Client.(*kclient.FakeRESTClient) - c := kclient.NewOrDie(t.ClientConfig) - c.Client = fakeClient.Client - return c, t.Err - }, - RESTClient: func(*meta.RESTMapping) (resource.RESTClient, error) { - return t.Client, t.Err - }, - Describer: func(*meta.RESTMapping) (kubectl.Describer, error) { - return t.Describer, t.Err - }, - Printer: func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, wide bool, showAll bool, columnLabels []string) (kubectl.ResourcePrinter, error) { - return t.Printer, t.Err - }, - Validator: func(validate bool, cacheDir string) (validation.Schema, error) { - return t.Validator, t.Err - }, - DefaultNamespace: func() (string, bool, error) { - return t.Namespace, false, t.Err - }, - ClientConfig: func() (*kclient.Config, error) { - return t.ClientConfig, t.Err - }, - Generator: func(name string) (kubectl.Generator, bool) { - generator, ok := generators[name] - return generator, ok - }, - }, t, testapi.Default.Codec() -} - -// NewFakeFactory returns a new fake OpenShift factory -func NewFakeFactory(namespace string, fake *kclient.FakeRESTClient) (*Factory, *testFactory, runtime.Codec) { - kf, t, codec := newFakeKubeFactory() - - t.Namespace = namespace - - // Create an OpenShift client and inject it into the client cache - osClient := client.NewOrDie(t.ClientConfig) - fake.Codec = codec - osClient.Client = fake - clients := &clientCache{ - clients: map[string]*client.Client{"v1": osClient}, - defaultConfig: &kclient.Config{}, - } - - // Override here any other function we need - - return &Factory{ - Factory: kf, - OpenShiftClientConfig: &fakeClientConfig{}, - clients: clients, - }, t, codec -} - -// ObjBody wraps an object into a readcloser -func ObjBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser { - return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj)))) -} diff --git a/pkg/cmd/util/gendocs/gendocs.go b/pkg/cmd/util/gendocs/gendocs.go index 516af3398d9c..40a1f05367ec 100644 --- a/pkg/cmd/util/gendocs/gendocs.go +++ b/pkg/cmd/util/gendocs/gendocs.go @@ -9,6 +9,7 @@ import ( "github.com/spf13/cobra" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/runtime" ) @@ -46,7 +47,7 @@ func GenDocs(cmd *cobra.Command, filename string) error { } err = printer.PrintObj(&kapi.List{ - ListMeta: kapi.ListMeta{}, + ListMeta: unversioned.ListMeta{}, Items: items, }, out) if err != nil { diff --git a/pkg/cmd/util/tokencmd/request_token.go b/pkg/cmd/util/tokencmd/request_token.go index 6c19c551e768..c9053e6ff41a 100644 --- a/pkg/cmd/util/tokencmd/request_token.go +++ b/pkg/cmd/util/tokencmd/request_token.go @@ -9,8 +9,8 @@ import ( "net/url" "strings" - "k8s.io/kubernetes/pkg/api" apierrs "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" kclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/util/sets" ) @@ -76,8 +76,8 @@ func RequestToken(clientCfg *kclient.Config, reader io.Reader, defaultUsername s unauthorizedError := apierrs.NewUnauthorized("") // Attempt to read body content and include as an error detail if details, err := ioutil.ReadAll(resp.Body); err == nil && len(details) > 0 { - unauthorizedError.(*apierrs.StatusError).ErrStatus.Details = &api.StatusDetails{ - Causes: []api.StatusCause{ + unauthorizedError.(*apierrs.StatusError).ErrStatus.Details = &unversioned.StatusDetails{ + Causes: []unversioned.StatusCause{ {Message: string(details)}, }, } diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 5f622a8a6786..bc86217f1be0 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -1,6 +1,7 @@ package controller import ( + "k8s.io/kubernetes/pkg/api/unversioned" kcache "k8s.io/kubernetes/pkg/client/cache" kutil "k8s.io/kubernetes/pkg/util" ) @@ -107,7 +108,7 @@ type Retry struct { Count int // StartTimestamp is retry start timestamp - StartTimestamp kutil.Time + StartTimestamp unversioned.Time } // ReQueue is a queue that allows an object to be requeued @@ -134,7 +135,7 @@ func (r *QueueRetryManager) Retry(resource interface{}, err error) { id, _ := r.keyFunc(resource) if _, exists := r.retries[id]; !exists { - r.retries[id] = Retry{0, kutil.Now()} + r.retries[id] = Retry{0, unversioned.Now()} } tries := r.retries[id] diff --git a/pkg/deploy/api/types.go b/pkg/deploy/api/types.go index 7e973e06c0aa..415ab82e85bd 100644 --- a/pkg/deploy/api/types.go +++ b/pkg/deploy/api/types.go @@ -2,6 +2,7 @@ package api import ( kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" kutil "k8s.io/kubernetes/pkg/util" ) @@ -235,7 +236,7 @@ const DeploymentCancelledAnnotationValue = "true" // state of the DeploymentConfig. Each change to the DeploymentConfig which should result in // a new deployment results in an increment of LatestVersion. type DeploymentConfig struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Triggers determine how updates to a DeploymentConfig result in new deployments. If no triggers // are defined, a new deployment can only occur as a result of an explicit client update to the @@ -329,8 +330,8 @@ type DeploymentCauseImageTrigger struct { // DeploymentConfigList is a collection of deployment configs. type DeploymentConfigList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of deployment configs Items []DeploymentConfig @@ -338,7 +339,7 @@ type DeploymentConfigList struct { // DeploymentConfigRollback provides the input to rollback generation. type DeploymentConfigRollback struct { - kapi.TypeMeta + unversioned.TypeMeta // Spec defines the options to rollback generation. Spec DeploymentConfigRollbackSpec } diff --git a/pkg/deploy/api/v1/types.go b/pkg/deploy/api/v1/types.go index c4e8ef5d693a..96a79b9cde36 100644 --- a/pkg/deploy/api/v1/types.go +++ b/pkg/deploy/api/v1/types.go @@ -1,6 +1,7 @@ package v1 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1" kutil "k8s.io/kubernetes/pkg/util" ) @@ -209,8 +210,8 @@ const ( // state of the DeploymentConfig. Each change to the DeploymentConfig which should result in // a new deployment results in an increment of LatestVersion. type DeploymentConfig struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Spec represents a desired deployment state and how to deploy to it. Spec DeploymentConfigSpec `json:"spec" description:"a desired deployment state and how to deploy it"` @@ -320,8 +321,8 @@ type DeploymentCauseImageTrigger struct { // DeploymentConfigList is a collection of deployment configs. type DeploymentConfigList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of deployment configs Items []DeploymentConfig `json:"items" description:"a list of deployment configs"` @@ -329,7 +330,7 @@ type DeploymentConfigList struct { // DeploymentConfigRollback provides the input to rollback generation. type DeploymentConfigRollback struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Spec defines the options to rollback generation. Spec DeploymentConfigRollbackSpec `json:"spec" description:"options for rollback generation"` } diff --git a/pkg/deploy/api/v1beta3/types.go b/pkg/deploy/api/v1beta3/types.go index b86fe9fcfca5..937259dde751 100644 --- a/pkg/deploy/api/v1beta3/types.go +++ b/pkg/deploy/api/v1beta3/types.go @@ -1,6 +1,7 @@ package v1beta3 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1beta3" kutil "k8s.io/kubernetes/pkg/util" ) @@ -227,8 +228,8 @@ const DeploymentCancelledAnnotationValue = "true" // state of the DeploymentConfig. Each change to the DeploymentConfig which should result in // a new deployment results in an increment of LatestVersion. type DeploymentConfig struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Spec represents a desired deployment state and how to deploy to it. Spec DeploymentConfigSpec `json:"spec" description:"a desired deployment state and how to deploy it"` // Status represents a desired deployment state and how to deploy to it. @@ -334,14 +335,14 @@ type DeploymentCauseImageTrigger struct { // A DeploymentConfigList is a collection of deployment configs. type DeploymentConfigList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []DeploymentConfig `json:"items" description:"a list of deployment configs"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []DeploymentConfig `json:"items" description:"a list of deployment configs"` } // DeploymentConfigRollback provides the input to rollback generation. type DeploymentConfigRollback struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` // Spec defines the options to rollback generation. Spec DeploymentConfigRollbackSpec `json:"spec" description:"options for rollback generation"` } diff --git a/pkg/deploy/api/validation/validation.go b/pkg/deploy/api/validation/validation.go index 86af8fd18325..35621be3c366 100644 --- a/pkg/deploy/api/validation/validation.go +++ b/pkg/deploy/api/validation/validation.go @@ -11,6 +11,7 @@ import ( "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" "k8s.io/kubernetes/pkg/util/sets" + kvalidation "k8s.io/kubernetes/pkg/util/validation" deployapi "github.com/openshift/origin/pkg/deploy/api" ) @@ -162,8 +163,8 @@ func validateEnv(vars []kapi.EnvVar) fielderrors.ValidationErrorList { if len(ev.Name) == 0 { vErrs = append(vErrs, fielderrors.NewFieldRequired("name")) } - if !util.IsCIdentifier(ev.Name) { - vErrs = append(vErrs, fielderrors.NewFieldInvalid("name", ev.Name, "must match regex "+util.CIdentifierFmt)) + if !kvalidation.IsCIdentifier(ev.Name) { + vErrs = append(vErrs, fielderrors.NewFieldInvalid("name", ev.Name, "must match regex "+kvalidation.CIdentifierFmt)) } allErrs = append(allErrs, vErrs.PrefixIndex(i)...) } @@ -256,10 +257,10 @@ func validateImageChangeParams(params *deployapi.DeploymentTriggerImageChangePar errs = append(errs, fielderrors.NewFieldInvalid("from.kind", params.From.Kind, msg)) } - if !util.IsDNS1123Subdomain(params.From.Name) { + if !kvalidation.IsDNS1123Subdomain(params.From.Name) { errs = append(errs, fielderrors.NewFieldInvalid("from.name", params.From.Name, "name must be a valid subdomain")) } - if len(params.From.Namespace) != 0 && !util.IsDNS1123Subdomain(params.From.Namespace) { + if len(params.From.Namespace) != 0 && !kvalidation.IsDNS1123Subdomain(params.From.Namespace) { errs = append(errs, fielderrors.NewFieldInvalid("from.namespace", params.From.Namespace, "namespace must be a valid subdomain")) } diff --git a/pkg/deploy/controller/deployerpod/factory.go b/pkg/deploy/controller/deployerpod/factory.go index 4f7575c7ba60..dd6189271293 100644 --- a/pkg/deploy/controller/deployerpod/factory.go +++ b/pkg/deploy/controller/deployerpod/factory.go @@ -27,7 +27,7 @@ type DeployerPodControllerFactory struct { func (factory *DeployerPodControllerFactory) Create() controller.RunnableController { deploymentLW := &deployutil.ListWatcherImpl{ ListFunc: func() (runtime.Object, error) { - return factory.KubeClient.ReplicationControllers(kapi.NamespaceAll).List(labels.Everything()) + return factory.KubeClient.ReplicationControllers(kapi.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return factory.KubeClient.ReplicationControllers(kapi.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion) @@ -69,7 +69,7 @@ func (factory *DeployerPodControllerFactory) Create() controller.RunnableControl return factory.KubeClient.ReplicationControllers(namespace).Update(deployment) }, listDeploymentsForConfigFunc: func(namespace, configName string) (*kapi.ReplicationControllerList, error) { - return factory.KubeClient.ReplicationControllers(namespace).List(deployutil.ConfigSelector(configName)) + return factory.KubeClient.ReplicationControllers(namespace).List(deployutil.ConfigSelector(configName), fields.Everything()) }, }, deployerPodsFor: func(namespace, name string) (*kapi.PodList, error) { diff --git a/pkg/deploy/controller/deployment/factory.go b/pkg/deploy/controller/deployment/factory.go index 1612cd62cf0c..cf93ac05156a 100644 --- a/pkg/deploy/controller/deployment/factory.go +++ b/pkg/deploy/controller/deployment/factory.go @@ -40,7 +40,7 @@ func (factory *DeploymentControllerFactory) Create() controller.RunnableControll // TODO: Investigate specifying annotation field selectors to fetch only 'deployments' // Currently field selectors are not supported for replication controllers ListFunc: func() (runtime.Object, error) { - return factory.KubeClient.ReplicationControllers(kapi.NamespaceAll).List(labels.Everything()) + return factory.KubeClient.ReplicationControllers(kapi.NamespaceAll).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(resourceVersion string) (watch.Interface, error) { return factory.KubeClient.ReplicationControllers(kapi.NamespaceAll).Watch(labels.Everything(), fields.Everything(), resourceVersion) diff --git a/pkg/deploy/controller/deploymentconfig/factory.go b/pkg/deploy/controller/deploymentconfig/factory.go index d8342be46287..eaa15935b3d9 100644 --- a/pkg/deploy/controller/deploymentconfig/factory.go +++ b/pkg/deploy/controller/deploymentconfig/factory.go @@ -54,7 +54,7 @@ func (factory *DeploymentConfigControllerFactory) Create() controller.RunnableCo }, listDeploymentsForConfigFunc: func(namespace, configName string) (*kapi.ReplicationControllerList, error) { sel := deployutil.ConfigSelector(configName) - list, err := factory.KubeClient.ReplicationControllers(namespace).List(sel) + list, err := factory.KubeClient.ReplicationControllers(namespace).List(sel, fields.Everything()) if err != nil { return nil, err } diff --git a/pkg/deploy/prune/data.go b/pkg/deploy/prune/data.go index 92ab00cbac42..1e810115b0e1 100644 --- a/pkg/deploy/prune/data.go +++ b/pkg/deploy/prune/data.go @@ -5,8 +5,8 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" - "k8s.io/kubernetes/pkg/util" deployapi "github.com/openshift/origin/pkg/deploy/api" deployutil "github.com/openshift/origin/pkg/deploy/util" @@ -55,8 +55,8 @@ type FilterPredicate func(item *kapi.ReplicationController) bool // NewFilterBeforePredicate is a function that returns true if the build was created before the current time minus specified duration func NewFilterBeforePredicate(d time.Duration) FilterPredicate { - now := util.Now() - before := util.NewTime(now.Time.Add(-1 * d)) + now := unversioned.Now() + before := unversioned.NewTime(now.Time.Add(-1 * d)) return func(item *kapi.ReplicationController) bool { return item.CreationTimestamp.Before(before) } diff --git a/pkg/deploy/prune/data_test.go b/pkg/deploy/prune/data_test.go index 85cde9451cdd..2ef4b28d431a 100644 --- a/pkg/deploy/prune/data_test.go +++ b/pkg/deploy/prune/data_test.go @@ -22,7 +22,7 @@ func withSize(item *kapi.ReplicationController, replicas int) *kapi.ReplicationC return item } -func withCreated(item *kapi.ReplicationController, creationTimestamp util.Time) *kapi.ReplicationController { +func withCreated(item *kapi.ReplicationController, creationTimestamp unversioned.Time) *kapi.ReplicationController { item.CreationTimestamp = creationTimestamp return item } @@ -65,8 +65,8 @@ func TestDeploymentByDeploymentConfigIndexFunc(t *testing.T) { func TestFilterBeforePredicate(t *testing.T) { youngerThan := time.Hour - now := util.Now() - old := util.NewTime(now.Time.Add(-1 * youngerThan)) + now := unversioned.Now() + old := unversioned.NewTime(now.Time.Add(-1 * youngerThan)) items := []*kapi.ReplicationController{} items = append(items, withCreated(mockDeployment("a", "old", nil), old)) items = append(items, withCreated(mockDeployment("a", "new", nil), now)) diff --git a/pkg/deploy/prune/prune_test.go b/pkg/deploy/prune/prune_test.go index ede52204806f..c9db7c19c793 100644 --- a/pkg/deploy/prune/prune_test.go +++ b/pkg/deploy/prune/prune_test.go @@ -53,8 +53,8 @@ func TestPruneTask(t *testing.T) { for _, deploymentStatusOption := range deploymentStatusOptions { keepYoungerThan := time.Hour - now := util.Now() - old := util.NewTime(now.Time.Add(-1 * keepYoungerThan)) + now := unversioned.Now() + old := unversioned.NewTime(now.Time.Add(-1 * keepYoungerThan)) deploymentConfigs := []*deployapi.DeploymentConfig{} deployments := []*kapi.ReplicationController{} diff --git a/pkg/deploy/prune/resolvers_test.go b/pkg/deploy/prune/resolvers_test.go index 397f095d7c1c..a02ba2bd8743 100644 --- a/pkg/deploy/prune/resolvers_test.go +++ b/pkg/deploy/prune/resolvers_test.go @@ -122,9 +122,9 @@ func TestPerDeploymentConfigResolver(t *testing.T) { } } - now := util.Now() + now := unversioned.Now() for i := range deployments { - creationTimestamp := util.NewTime(now.Time.Add(-1 * time.Duration(i) * time.Hour)) + creationTimestamp := unversioned.NewTime(now.Time.Add(-1 * time.Duration(i) * time.Hour)) deployments[i].CreationTimestamp = creationTimestamp } diff --git a/pkg/deploy/prune/sort_test.go b/pkg/deploy/prune/sort_test.go index 5a64ec57f827..38a8c8d50459 100644 --- a/pkg/deploy/prune/sort_test.go +++ b/pkg/deploy/prune/sort_test.go @@ -11,8 +11,8 @@ import ( // TestSort verifies that builds are sorted by most recently created func TestSort(t *testing.T) { - present := util.Now() - past := util.NewTime(present.Time.Add(-1 * time.Minute)) + present := unversioned.Now() + past := unversioned.NewTime(present.Time.Add(-1 * time.Minute)) controllers := []*kapi.ReplicationController{ { ObjectMeta: kapi.ObjectMeta{ diff --git a/pkg/deploy/reaper/reaper.go b/pkg/deploy/reaper/reaper.go index 3e82455cfbfe..7cd5382cc58f 100644 --- a/pkg/deploy/reaper/reaper.go +++ b/pkg/deploy/reaper/reaper.go @@ -8,6 +8,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kerrors "k8s.io/kubernetes/pkg/api/errors" kclient "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/kubectl" "github.com/openshift/origin/pkg/client" @@ -46,7 +47,7 @@ func (reaper *DeploymentConfigReaper) Stop(namespace, name string, timeout time. } // Clean up deployments related to the config. - rcList, err := reaper.kc.ReplicationControllers(namespace).List(util.ConfigSelector(name)) + rcList, err := reaper.kc.ReplicationControllers(namespace).List(util.ConfigSelector(name), fields.Everything()) if err != nil { return "", err } diff --git a/pkg/deploy/scaler/scale.go b/pkg/deploy/scaler/scale.go index a0822d1a74da..bf01124bba99 100644 --- a/pkg/deploy/scaler/scale.go +++ b/pkg/deploy/scaler/scale.go @@ -4,25 +4,26 @@ import ( "time" "github.com/golang/glog" - kapi "k8s.io/kubernetes/pkg/api" kerrors "k8s.io/kubernetes/pkg/api/errors" kclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/util/wait" "github.com/openshift/origin/pkg/client" - "github.com/openshift/origin/pkg/deploy/api" "github.com/openshift/origin/pkg/deploy/util" ) // NewDeploymentConfigScaler returns a new scaler for deploymentConfigs -func NewDeploymentConfigScaler(oc *client.Client, kc *kclient.Client) kubectl.Scaler { - return &DeploymentConfigScaler{c: NewScalerClient(oc, kc)} +func NewDeploymentConfigScaler(oc client.Interface, kc kclient.Interface) kubectl.Scaler { + return &DeploymentConfigScaler{rcClient: kc, dcClient: oc, clientInterface: kc} } // DeploymentConfigScaler is a wrapper for the kubectl Scaler client type DeploymentConfigScaler struct { - c kubectl.ScalerClient + rcClient kclient.ReplicationControllersNamespacer + dcClient client.DeploymentConfigsNamespacer + + clientInterface kclient.Interface } // Scale updates a replication controller created by the DeploymentConfig with the provided namespace/name, @@ -40,7 +41,13 @@ func (scaler *DeploymentConfigScaler) Scale(namespace, name string, newSize uint if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil { if scaleErr := err.(kubectl.ControllerScaleError); kerrors.IsNotFound(scaleErr.ActualError) { glog.Infof("No deployment found for dc/%s. Scaling the deployment configuration template...", name) - if _, err := scaler.c.(*realScalerClient).UpdateDeploymentConfig(namespace, name, newSize); err != nil { + dc, err := scaler.dcClient.DeploymentConfigs(namespace).Get(name) + if err != nil { + return err + } + dc.Template.ControllerTemplate.Replicas = int(newSize) + + if _, err := scaler.dcClient.DeploymentConfigs(namespace).Update(dc); err != nil { return err } return nil @@ -48,78 +55,37 @@ func (scaler *DeploymentConfigScaler) Scale(namespace, name string, newSize uint return err } if waitForReplicas != nil { - rc, err := scaler.c.GetReplicationController(namespace, name) + rc, err := scaler.rcClient.ReplicationControllers(namespace).Get(name) if err != nil { return err } - return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, - scaler.c.ControllerHasDesiredReplicas(rc)) + return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, kclient.ControllerHasDesiredReplicas(scaler.clientInterface, rc)) } return nil } // ScaleSimple does a simple one-shot attempt at scaling - not useful on it's own, but // a necessary building block for Scale -func (scaler *DeploymentConfigScaler) ScaleSimple(namespace, name string, preconditions *kubectl.ScalePrecondition, newSize uint) (string, error) { - const scaled = "scaled" - controller, err := scaler.c.GetReplicationController(namespace, name) +func (scaler *DeploymentConfigScaler) ScaleSimple(namespace, name string, preconditions *kubectl.ScalePrecondition, newSize uint) error { + dc, err := scaler.dcClient.DeploymentConfigs(namespace).Get(name) + if err != nil { + return err + } + controller, err := scaler.rcClient.ReplicationControllers(namespace).Get(util.LatestDeploymentNameForConfig(dc)) if err != nil { - return "", kubectl.ControllerScaleError{FailureType: kubectl.ControllerScaleGetFailure, ResourceVersion: "Unknown", ActualError: err} + return kubectl.ControllerScaleError{FailureType: kubectl.ControllerScaleGetFailure, ResourceVersion: "Unknown", ActualError: err} } + if preconditions != nil { - if err := preconditions.Validate(controller); err != nil { - return "", err + if err := preconditions.ValidateReplicationController(controller); err != nil { + return err } } controller.Spec.Replicas = int(newSize) // TODO: do retry on 409 errors here? - if _, err := scaler.c.UpdateReplicationController(namespace, controller); err != nil { - return "", kubectl.ControllerScaleError{FailureType: kubectl.ControllerScaleUpdateFailure, ResourceVersion: controller.ResourceVersion, ActualError: err} + if _, err := scaler.rcClient.ReplicationControllers(namespace).Update(controller); err != nil { + return kubectl.ControllerScaleError{FailureType: kubectl.ControllerScaleUpdateFailure, ResourceVersion: controller.ResourceVersion, ActualError: err} } // TODO: do a better job of printing objects here. - return scaled, nil -} - -// NewScalerClient returns a new Scaler client bundling both the OpenShift and -// Kubernetes clients -func NewScalerClient(oc client.Interface, kc kclient.Interface) kubectl.ScalerClient { - return &realScalerClient{oc: oc, kc: kc} -} - -// realScalerClient is a ScalerClient which uses an OpenShift and a Kube client. -type realScalerClient struct { - oc client.Interface - kc kclient.Interface -} - -// GetReplicationController returns the most recent replication controller associated with the deploymentConfig -// with the provided namespace/name combination -func (c *realScalerClient) GetReplicationController(namespace, name string) (*kapi.ReplicationController, error) { - dc, err := c.oc.DeploymentConfigs(namespace).Get(name) - if err != nil { - return nil, err - } - return c.kc.ReplicationControllers(namespace).Get(util.LatestDeploymentNameForConfig(dc)) -} - -// UpdateReplicationController updates the provided replication controller -func (c *realScalerClient) UpdateReplicationController(namespace string, rc *kapi.ReplicationController) (*kapi.ReplicationController, error) { - return c.kc.ReplicationControllers(namespace).Update(rc) -} - -// ControllerHasDesiredReplicas checks whether the provided replication controller has the desired replicas -// number set -func (c *realScalerClient) ControllerHasDesiredReplicas(rc *kapi.ReplicationController) wait.ConditionFunc { - return kclient.ControllerHasDesiredReplicas(c.kc, rc) -} - -// UpdateDeploymentConfig tries to get and update the provided deployment configuration template with the -// provided replicas size -func (c *realScalerClient) UpdateDeploymentConfig(namespace, name string, newSize uint) (*api.DeploymentConfig, error) { - dc, err := c.oc.DeploymentConfigs(namespace).Get(name) - if err != nil { - return nil, err - } - dc.Template.ControllerTemplate.Replicas = int(newSize) - return c.oc.DeploymentConfigs(namespace).Update(dc) + return nil } diff --git a/pkg/deploy/scaler/scale_test.go b/pkg/deploy/scaler/scale_test.go index 3cae68587c0c..0b73f23fa472 100644 --- a/pkg/deploy/scaler/scale_test.go +++ b/pkg/deploy/scaler/scale_test.go @@ -66,7 +66,6 @@ func TestScale(t *testing.T) { kc: ktestclient.NewSimpleFake(mkDeploymentList(1)), expected: []ktestclient.Action{ ktestclient.NewGetAction("deploymentconfigs", "default", "foo"), - ktestclient.NewGetAction("deploymentconfigs", "default", "foo"), }, kexpected: []ktestclient.Action{ ktestclient.NewGetAction("replicationcontrollers", "default", "config-1"), @@ -96,7 +95,7 @@ func TestScale(t *testing.T) { } for _, test := range tests { - scaler := DeploymentConfigScaler{NewScalerClient(test.oc, test.kc)} + scaler := NewDeploymentConfigScaler(test.oc, test.kc) got := scaler.Scale(test.namespace, test.name, test.count, test.preconditions, test.retry, test.waitForReplicas) if got != test.expectedErr { t.Errorf("%s: error mismatch: expected %v, got %v", test.testName, test.expectedErr, got) diff --git a/pkg/deploy/scaler/test/support.go b/pkg/deploy/scaler/test/support.go index 3b831af7218c..010b57bbfff0 100644 --- a/pkg/deploy/scaler/test/support.go +++ b/pkg/deploy/scaler/test/support.go @@ -20,6 +20,6 @@ func (t *FakeScaler) Scale(namespace, name string, newSize uint, preconditions * return nil } -func (t *FakeScaler) ScaleSimple(namespace, name string, preconditions *kubectl.ScalePrecondition, newSize uint) (string, error) { - return "error", fmt.Errorf("unexpected call to ScaleSimple") +func (t *FakeScaler) ScaleSimple(namespace, name string, preconditions *kubectl.ScalePrecondition, newSize uint) error { + return fmt.Errorf("unexpected call to ScaleSimple") } diff --git a/pkg/deploy/strategy/recreate/recreate.go b/pkg/deploy/strategy/recreate/recreate.go index 2b7b48c4e288..713d1f0f8d1c 100644 --- a/pkg/deploy/strategy/recreate/recreate.go +++ b/pkg/deploy/strategy/recreate/recreate.go @@ -43,7 +43,7 @@ type RecreateDeploymentStrategy struct { // NewRecreateDeploymentStrategy makes a RecreateDeploymentStrategy backed by // a real HookExecutor and client. func NewRecreateDeploymentStrategy(client kclient.Interface, codec runtime.Codec) *RecreateDeploymentStrategy { - scaler, _ := kubectl.ScalerFor("ReplicationController", kubectl.NewScalerClient(client)) + scaler, _ := kubectl.ScalerFor("ReplicationController", client) return &RecreateDeploymentStrategy{ getReplicationController: func(namespace, name string) (*kapi.ReplicationController, error) { return client.ReplicationControllers(namespace).Get(name) diff --git a/pkg/dns/serviceaccessor.go b/pkg/dns/serviceaccessor.go index e0fd649ecc18..c10bb95fe82d 100644 --- a/pkg/dns/serviceaccessor.go +++ b/pkg/dns/serviceaccessor.go @@ -92,7 +92,7 @@ func (a cachedServiceNamespacer) Get(name string) (*api.Service, error) { return item.(*api.Service), nil } -func (a cachedServiceNamespacer) List(label labels.Selector) (*api.ServiceList, error) { +func (a cachedServiceNamespacer) List(label labels.Selector, field fields.Selector) (*api.ServiceList, error) { if !label.Empty() { return nil, fmt.Errorf("label selection on the cache is not currently implemented") } diff --git a/pkg/generate/app/app.go b/pkg/generate/app/app.go index 04bf6fe7fd97..22764f559715 100644 --- a/pkg/generate/app/app.go +++ b/pkg/generate/app/app.go @@ -15,7 +15,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/runtime" - kutil "k8s.io/kubernetes/pkg/util" + kvalidation "k8s.io/kubernetes/pkg/util/validation" buildapi "github.com/openshift/origin/pkg/build/api" deployapi "github.com/openshift/origin/pkg/deploy/api" @@ -371,7 +371,7 @@ func (r *ImageRef) DeployableContainer() (container *kapi.Container, triggers [] // Create volume mounts with names based on container name maxDigits := len(fmt.Sprintf("%d", len(r.Info.Config.Volumes))) - baseName := namer.GetName(container.Name, volumeNameInfix, kutil.LabelValueMaxLength-maxDigits-1) + baseName := namer.GetName(container.Name, volumeNameInfix, kvalidation.LabelValueMaxLength-maxDigits-1) i := 1 for volume := range r.Info.Config.Volumes { r.HasEmptyDir = true diff --git a/pkg/generate/app/cmd/newapp.go b/pkg/generate/app/cmd/newapp.go index 25664fa5d8c7..9001d52d4053 100644 --- a/pkg/generate/app/cmd/newapp.go +++ b/pkg/generate/app/cmd/newapp.go @@ -16,6 +16,7 @@ import ( "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/errors" + kvalidation "k8s.io/kubernetes/pkg/util/validation" buildapi "github.com/openshift/origin/pkg/build/api" "github.com/openshift/origin/pkg/client" @@ -469,9 +470,9 @@ func ensureValidUniqueName(names map[string]int, name string) (string, error) { if len(name) < 2 { return "", fmt.Errorf("invalid name: %s", name) } - if len(name) > util.DNS1123SubdomainMaxLength { - glog.V(4).Infof("Trimming %s to maximum allowable length (%d)\n", name, util.DNS1123SubdomainMaxLength) - name = name[:util.DNS1123SubdomainMaxLength] + if len(name) > kvalidation.DNS1123SubdomainMaxLength { + glog.V(4).Infof("Trimming %s to maximum allowable length (%d)\n", name, kvalidation.DNS1123SubdomainMaxLength) + name = name[:kvalidation.DNS1123SubdomainMaxLength] } // Make all names lowercase @@ -484,7 +485,7 @@ func ensureValidUniqueName(names map[string]int, name string) (string, error) { } count++ names[name] = count - newName := namer.GetName(name, strconv.Itoa(count), util.DNS1123SubdomainMaxLength) + newName := namer.GetName(name, strconv.Itoa(count), kvalidation.DNS1123SubdomainMaxLength) return newName, nil } diff --git a/pkg/generate/app/cmd/newapp_test.go b/pkg/generate/app/cmd/newapp_test.go index 6c5bfade6244..8dca85889c8b 100644 --- a/pkg/generate/app/cmd/newapp_test.go +++ b/pkg/generate/app/cmd/newapp_test.go @@ -1243,7 +1243,7 @@ func TestNewAppBuildConfigEnvVars(t *testing.T) { func TestEnsureValidUniqueName(t *testing.T) { chars := []byte("abcdefghijk") longBytes := []byte{} - for i := 0; i < (util.DNS1123SubdomainMaxLength + 20); i++ { + for i := 0; i < (kvalidation.DNS1123SubdomainMaxLength + 20); i++ { longBytes = append(longBytes, chars[i%len(chars)]) } longName := string(longBytes) @@ -1271,9 +1271,9 @@ func TestEnsureValidUniqueName(t *testing.T) { { name: "long name", input: []string{longName, longName, longName}, - expected: []string{longName[:util.DNS1123SubdomainMaxLength], - namer.GetName(longName[:util.DNS1123SubdomainMaxLength], "1", util.DNS1123SubdomainMaxLength), - namer.GetName(longName[:util.DNS1123SubdomainMaxLength], "2", util.DNS1123SubdomainMaxLength), + expected: []string{longName[:kvalidation.DNS1123SubdomainMaxLength], + namer.GetName(longName[:kvalidation.DNS1123SubdomainMaxLength], "1", kvalidation.DNS1123SubdomainMaxLength), + namer.GetName(longName[:kvalidation.DNS1123SubdomainMaxLength], "2", kvalidation.DNS1123SubdomainMaxLength), }, }, } diff --git a/pkg/generate/app/pipeline.go b/pkg/generate/app/pipeline.go index 2f67002656de..18e15dc90c2b 100644 --- a/pkg/generate/app/pipeline.go +++ b/pkg/generate/app/pipeline.go @@ -11,6 +11,7 @@ import ( "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/runtime" kutil "k8s.io/kubernetes/pkg/util" + kuval "k8s.io/kubernetes/pkg/util/validation" deploy "github.com/openshift/origin/pkg/deploy/api" image "github.com/openshift/origin/pkg/image/api" @@ -174,8 +175,8 @@ func makeValidServiceName(name string) (string, string) { switch { case len(name) == 0: return "", "service-" - case len(name) > kutil.DNS952LabelMaxLength: - name = name[:kutil.DNS952LabelMaxLength] + case len(name) > kuval.DNS952LabelMaxLength: + name = name[:kuval.DNS952LabelMaxLength] } return name, "" } diff --git a/pkg/image/api/conversion.go b/pkg/image/api/conversion.go index b7b68c10674f..87a58cc63137 100644 --- a/pkg/image/api/conversion.go +++ b/pkg/image/api/conversion.go @@ -4,8 +4,8 @@ import ( "github.com/fsouza/go-dockerclient" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/conversion" - "k8s.io/kubernetes/pkg/util" ) func init() { @@ -21,7 +21,7 @@ func init() { out.ID = in.ID out.Parent = in.Parent out.Comment = in.Comment - out.Created = util.NewTime(in.Created) + out.Created = unversioned.NewTime(in.Created) out.Container = in.Container out.DockerVersion = in.DockerVersion out.Author = in.Author diff --git a/pkg/image/api/docker10/dockertypes.go b/pkg/image/api/docker10/dockertypes.go index df7477992935..4fab3baa1060 100644 --- a/pkg/image/api/docker10/dockertypes.go +++ b/pkg/image/api/docker10/dockertypes.go @@ -1,26 +1,25 @@ package docker10 import ( - kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) // DockerImage is the type representing a docker image and its various properties when // retrieved from the Docker client API. type DockerImage struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` - ID string `json:"Id"` - Parent string `json:"Parent,omitempty"` - Comment string `json:"Comment,omitempty"` - Created util.Time `json:"Created,omitempty"` - Container string `json:"Container,omitempty"` - ContainerConfig DockerConfig `json:"ContainerConfig,omitempty"` - DockerVersion string `json:"DockerVersion,omitempty"` - Author string `json:"Author,omitempty"` - Config *DockerConfig `json:"Config,omitempty"` - Architecture string `json:"Architecture,omitempty"` - Size int64 `json:"Size,omitempty"` + ID string `json:"Id"` + Parent string `json:"Parent,omitempty"` + Comment string `json:"Comment,omitempty"` + Created unversioned.Time `json:"Created,omitempty"` + Container string `json:"Container,omitempty"` + ContainerConfig DockerConfig `json:"ContainerConfig,omitempty"` + DockerVersion string `json:"DockerVersion,omitempty"` + Author string `json:"Author,omitempty"` + Config *DockerConfig `json:"Config,omitempty"` + Architecture string `json:"Architecture,omitempty"` + Size int64 `json:"Size,omitempty"` } // DockerConfig is the list of configuration options used when creating a container. diff --git a/pkg/image/api/dockerpre012/conversion.go b/pkg/image/api/dockerpre012/conversion.go index dd91264b291f..b11e34738f37 100644 --- a/pkg/image/api/dockerpre012/conversion.go +++ b/pkg/image/api/dockerpre012/conversion.go @@ -4,8 +4,8 @@ import ( "github.com/fsouza/go-dockerclient" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/conversion" - "k8s.io/kubernetes/pkg/util" newer "github.com/openshift/origin/pkg/image/api" ) @@ -23,7 +23,7 @@ func init() { out.ID = in.ID out.Parent = in.Parent out.Comment = in.Comment - out.Created = util.NewTime(in.Created) + out.Created = unversioned.NewTime(in.Created) out.Container = in.Container out.DockerVersion = in.DockerVersion out.Author = in.Author diff --git a/pkg/image/api/dockerpre012/dockertypes.go b/pkg/image/api/dockerpre012/dockertypes.go index e8f3c74fa21d..07620520ea55 100644 --- a/pkg/image/api/dockerpre012/dockertypes.go +++ b/pkg/image/api/dockerpre012/dockertypes.go @@ -1,26 +1,25 @@ package dockerpre012 import ( - kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) // DockerImage is for earlier versions of the Docker API (pre-012 to be specific). It is also the // version of metadata that the Docker registry uses to persist metadata. type DockerImage struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` - ID string `json:"id"` - Parent string `json:"parent,omitempty"` - Comment string `json:"comment,omitempty"` - Created util.Time `json:"created"` - Container string `json:"container,omitempty"` - ContainerConfig DockerConfig `json:"container_config,omitempty"` - DockerVersion string `json:"docker_version,omitempty"` - Author string `json:"author,omitempty"` - Config *DockerConfig `json:"config,omitempty"` - Architecture string `json:"architecture,omitempty"` - Size int64 `json:"size,omitempty"` + ID string `json:"id"` + Parent string `json:"parent,omitempty"` + Comment string `json:"comment,omitempty"` + Created unversioned.Time `json:"created"` + Container string `json:"container,omitempty"` + ContainerConfig DockerConfig `json:"container_config,omitempty"` + DockerVersion string `json:"docker_version,omitempty"` + Author string `json:"author,omitempty"` + Config *DockerConfig `json:"config,omitempty"` + Architecture string `json:"architecture,omitempty"` + Size int64 `json:"size,omitempty"` } // DockerConfig is the list of configuration options used when creating a container. diff --git a/pkg/image/api/dockertypes.go b/pkg/image/api/dockertypes.go index 9462431a185a..54a1e79d7e76 100644 --- a/pkg/image/api/dockertypes.go +++ b/pkg/image/api/dockertypes.go @@ -1,26 +1,25 @@ package api import ( - kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) // DockerImage is the type representing a docker image and its various properties when // retrieved from the Docker client API. type DockerImage struct { - kapi.TypeMeta `json:",inline"` + unversioned.TypeMeta `json:",inline"` - ID string `json:"Id"` - Parent string `json:"Parent,omitempty"` - Comment string `json:"Comment,omitempty"` - Created util.Time `json:"Created,omitempty"` - Container string `json:"Container,omitempty"` - ContainerConfig DockerConfig `json:"ContainerConfig,omitempty"` - DockerVersion string `json:"DockerVersion,omitempty"` - Author string `json:"Author,omitempty"` - Config *DockerConfig `json:"Config,omitempty"` - Architecture string `json:"Architecture,omitempty"` - Size int64 `json:"Size,omitempty"` + ID string `json:"Id"` + Parent string `json:"Parent,omitempty"` + Comment string `json:"Comment,omitempty"` + Created unversioned.Time `json:"Created,omitempty"` + Container string `json:"Container,omitempty"` + ContainerConfig DockerConfig `json:"ContainerConfig,omitempty"` + DockerVersion string `json:"DockerVersion,omitempty"` + Author string `json:"Author,omitempty"` + Config *DockerConfig `json:"Config,omitempty"` + Architecture string `json:"Architecture,omitempty"` + Size int64 `json:"Size,omitempty"` } // DockerConfig is the list of configuration options used when creating a container. @@ -80,15 +79,15 @@ type DockerHistory struct { // DockerV1CompatibilityImage represents the structured v1 // compatibility information. type DockerV1CompatibilityImage struct { - ID string `json:"id"` - Parent string `json:"parent,omitempty"` - Comment string `json:"comment,omitempty"` - Created util.Time `json:"created"` - Container string `json:"container,omitempty"` - ContainerConfig DockerConfig `json:"container_config,omitempty"` - DockerVersion string `json:"docker_version,omitempty"` - Author string `json:"author,omitempty"` - Config *DockerConfig `json:"config,omitempty"` - Architecture string `json:"architecture,omitempty"` - Size int64 `json:"size,omitempty"` + ID string `json:"id"` + Parent string `json:"parent,omitempty"` + Comment string `json:"comment,omitempty"` + Created unversioned.Time `json:"created"` + Container string `json:"container,omitempty"` + ContainerConfig DockerConfig `json:"container_config,omitempty"` + DockerVersion string `json:"docker_version,omitempty"` + Author string `json:"author,omitempty"` + Config *DockerConfig `json:"config,omitempty"` + Architecture string `json:"architecture,omitempty"` + Size int64 `json:"size,omitempty"` } diff --git a/pkg/image/api/sort.go b/pkg/image/api/sort.go index 733242893844..0cd39a72fb90 100644 --- a/pkg/image/api/sort.go +++ b/pkg/image/api/sort.go @@ -3,12 +3,12 @@ package api import ( "sort" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) type tag struct { Name string - Created util.Time + Created unversioned.Time } type byCreationTimestamp []tag diff --git a/pkg/image/api/types.go b/pkg/image/api/types.go index 69d86bfce601..ef8e18ac7361 100644 --- a/pkg/image/api/types.go +++ b/pkg/image/api/types.go @@ -2,13 +2,13 @@ package api import ( kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) // ImageList is a list of Image objects. type ImageList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []Image } @@ -31,7 +31,7 @@ const ( // Image is an immutable representation of a Docker image and metadata at a point in time. type Image struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // The string that can be used to pull this image. @@ -46,8 +46,8 @@ type Image struct { // ImageStreamList is a list of ImageStream objects. type ImageStreamList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []ImageStream } @@ -56,7 +56,7 @@ type ImageStreamList struct { // when images are tagged in a stream, and an optional reference to a Docker image // repository on a registry. type ImageStream struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Spec describes the desired state of this stream @@ -99,7 +99,7 @@ type TagEventList struct { // TagEvent is used by ImageRepositoryStatus to keep a historical record of images associated with a tag. type TagEvent struct { // When the TagEvent was created - Created util.Time + Created unversioned.Time // The string that can be used to pull this image DockerImageReference string // The image @@ -109,7 +109,7 @@ type TagEvent struct { // ImageStreamMapping represents a mapping from a single tag to a Docker image as // well as the reference to the Docker image repository the image came from. type ImageStreamMapping struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // The Docker image repository the specified image is located in @@ -122,7 +122,7 @@ type ImageStreamMapping struct { } type ImageStreamTag struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // The Image associated with the ImageStream and tag. @@ -131,7 +131,7 @@ type ImageStreamTag struct { // ImageStreamImage represents an Image that is retrieved by image name from an ImageStream. type ImageStreamImage struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // The Image associated with the ImageStream and image name. diff --git a/pkg/image/api/v1/types.go b/pkg/image/api/v1/types.go index a6461e78079e..f5b8bcd7d0a4 100644 --- a/pkg/image/api/v1/types.go +++ b/pkg/image/api/v1/types.go @@ -1,15 +1,15 @@ package v1 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" ) // ImageList is a list of Image objects. type ImageList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of images Items []Image `json:"items" description:"list of image objects"` @@ -17,8 +17,8 @@ type ImageList struct { // Image is an immutable representation of a Docker image and metadata at a point in time. type Image struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // DockerImageReference is the string that can be used to pull this image. DockerImageReference string `json:"dockerImageReference,omitempty" description:"string that can be used to pull this image"` @@ -32,8 +32,8 @@ type Image struct { // ImageStreamList is a list of ImageStream objects. type ImageStreamList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of imageStreams Items []ImageStream `json:"items" description:"list of image stream objects"` @@ -43,8 +43,8 @@ type ImageStreamList struct { // when images are tagged in a stream, and an optional reference to a Docker image // repository on a registry. type ImageStream struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Spec describes the desired state of this stream Spec ImageStreamSpec `json:"spec" description:"desired state of the stream"` @@ -89,7 +89,7 @@ type NamedTagEventList struct { // TagEvent is used by ImageStreamStatus to keep a historical record of images associated with a tag. type TagEvent struct { // Created holds the time the TagEvent was created - Created util.Time `json:"created" description:"when the event was created"` + Created unversioned.Time `json:"created" description:"when the event was created"` // DockerImageReference is the string that can be used to pull this image DockerImageReference string `json:"dockerImageReference" description:"the string that can be used to pull this image"` // Image is the image @@ -99,8 +99,8 @@ type TagEvent struct { // ImageStreamMapping represents a mapping from a single tag to a Docker image as // well as the reference to the Docker image stream the image came from. type ImageStreamMapping struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Image is a Docker image. Image Image `json:"image" description:"a Docker image"` @@ -110,8 +110,8 @@ type ImageStreamMapping struct { // ImageStreamTag represents an Image that is retrieved by tag name from an ImageStream. type ImageStreamTag struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Image associated with the ImageStream and tag. Image Image `json:"image" description:"the image associated with the ImageStream and tag"` @@ -119,8 +119,8 @@ type ImageStreamTag struct { // ImageStreamImage represents an Image that is retrieved by image name from an ImageStream. type ImageStreamImage struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Image associated with the ImageStream and image name. Image Image `json:"image" description:"the image associated with the ImageStream and image name"` diff --git a/pkg/image/api/v1beta3/types.go b/pkg/image/api/v1beta3/types.go index 6ea98458aa49..2730f898b0d7 100644 --- a/pkg/image/api/v1beta3/types.go +++ b/pkg/image/api/v1beta3/types.go @@ -1,23 +1,23 @@ package v1beta3 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1beta3" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" ) // ImageList is a list of Image objects. type ImageList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []Image `json:"items"` } // Image is an immutable representation of a Docker image and metadata at a point in time. type Image struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // The string that can be used to pull this image. DockerImageReference string `json:"dockerImageReference,omitempty"` @@ -31,8 +31,8 @@ type Image struct { // ImageStreamList is a list of ImageStream objects. type ImageStreamList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` Items []ImageStream `json:"items"` } @@ -41,8 +41,8 @@ type ImageStreamList struct { // when images are tagged in a stream, and an optional reference to a Docker image // repository on a registry. type ImageStream struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Spec describes the desired state of this stream Spec ImageStreamSpec `json:"spec"` @@ -84,7 +84,7 @@ type NamedTagEventList struct { // TagEvent is used by ImageRepositoryStatus to keep a historical record of images associated with a tag. type TagEvent struct { // When the TagEvent was created - Created util.Time `json:"created"` + Created unversioned.Time `json:"created"` // The string that can be used to pull this image DockerImageReference string `json:"dockerImageReference"` // The image @@ -94,8 +94,8 @@ type TagEvent struct { // ImageStreamMapping represents a mapping from a single tag to a Docker image as // well as the reference to the Docker image repository the image came from. type ImageStreamMapping struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // A Docker image. Image Image `json:"image"` diff --git a/pkg/image/controller/controller.go b/pkg/image/controller/controller.go index af3af73bf3cc..53036d461f53 100644 --- a/pkg/image/controller/controller.go +++ b/pkg/image/controller/controller.go @@ -6,6 +6,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util" "github.com/openshift/origin/pkg/client" @@ -158,7 +159,7 @@ func (c *ImportController) Next(stream *api.ImageStream) error { // done marks the stream as being processed due to an error or failure condition func (c *ImportController) done(stream *api.ImageStream, reason string, retry int) error { if len(reason) == 0 { - reason = util.Now().UTC().Format(time.RFC3339) + reason = unversioned.Now().UTC().Format(time.RFC3339) } if stream.Annotations == nil { stream.Annotations = make(map[string]string) diff --git a/pkg/image/prune/imagepruner.go b/pkg/image/prune/imagepruner.go index 6ce41984b31f..93a1e8505853 100644 --- a/pkg/image/prune/imagepruner.go +++ b/pkg/image/prune/imagepruner.go @@ -21,6 +21,7 @@ import ( imagegraph "github.com/openshift/origin/pkg/image/graph/nodes" "github.com/openshift/origin/pkg/image/registry/imagestreamimage" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util" kerrors "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/sets" @@ -281,7 +282,7 @@ func addImagesToGraph(g graph.Graph, images *imageapi.ImageList, algorithm prune continue } - age := util.Now().Sub(image.CreationTimestamp.Time) + age := unversioned.Now().Sub(image.CreationTimestamp.Time) if age < algorithm.keepYoungerThan { glog.V(4).Infof("Image %q is younger than minimum pruning age, skipping (age=%v)", image.Name, age) continue @@ -322,7 +323,7 @@ func addImageStreamsToGraph(g graph.Graph, streams *imageapi.ImageStreamList, al // use a weak reference for old image revisions by default oldImageRevisionReferenceKind := WeakReferencedImageEdgeKind - age := util.Now().Sub(stream.CreationTimestamp.Time) + age := unversioned.Now().Sub(stream.CreationTimestamp.Time) if age < algorithm.keepYoungerThan { // stream's age is below threshold - use a strong reference for old image revisions instead glog.V(4).Infof("Stream %s/%s is below age threshold - none of its images are eligible for pruning", stream.Namespace, stream.Name) @@ -388,7 +389,7 @@ func addPodsToGraph(g graph.Graph, pods *kapi.PodList, algorithm pruneAlgorithm) glog.V(4).Infof("Examining pod %s/%s", pod.Namespace, pod.Name) if pod.Status.Phase != kapi.PodRunning && pod.Status.Phase != kapi.PodPending { - age := util.Now().Sub(pod.CreationTimestamp.Time) + age := unversioned.Now().Sub(pod.CreationTimestamp.Time) if age >= algorithm.keepYoungerThan { glog.V(4).Infof("Pod %s/%s is not running or pending and age is at least minimum pruning age - skipping", pod.Namespace, pod.Name) // not pending or running, age is at least minimum pruning age, skip diff --git a/pkg/image/prune/imagepruner_test.go b/pkg/image/prune/imagepruner_test.go index d48a3eab6aa7..0695a93f68d6 100644 --- a/pkg/image/prune/imagepruner_test.go +++ b/pkg/image/prune/imagepruner_test.go @@ -48,7 +48,7 @@ func agedImage(id, ref string, ageInMinutes int64) imageapi.Image { ) if ageInMinutes >= 0 { - image.CreationTimestamp = util.NewTime(util.Now().Add(time.Duration(-1*ageInMinutes) * time.Minute)) + image.CreationTimestamp = unversioned.NewTime(unversioned.Now().Add(time.Duration(-1*ageInMinutes) * time.Minute)) } return image @@ -127,7 +127,7 @@ func agedPod(namespace, name string, phase kapi.PodPhase, ageInMinutes int64, co } if ageInMinutes >= 0 { - pod.CreationTimestamp = util.NewTime(util.Now().Add(time.Duration(-1*ageInMinutes) * time.Minute)) + pod.CreationTimestamp = unversioned.NewTime(unversioned.Now().Add(time.Duration(-1*ageInMinutes) * time.Minute)) } return pod @@ -169,7 +169,7 @@ func agedStream(registry, namespace, name string, ageInMinutes int64, tags map[s } if ageInMinutes >= 0 { - stream.CreationTimestamp = util.NewTime(util.Now().Add(time.Duration(-1*ageInMinutes) * time.Minute)) + stream.CreationTimestamp = unversioned.NewTime(unversioned.Now().Add(time.Duration(-1*ageInMinutes) * time.Minute)) } return stream diff --git a/pkg/image/registry/image/etcd/etcd_test.go b/pkg/image/registry/image/etcd/etcd_test.go index 3e671e9fa335..305a944c1b3b 100644 --- a/pkg/image/registry/image/etcd/etcd_test.go +++ b/pkg/image/registry/image/etcd/etcd_test.go @@ -126,7 +126,7 @@ func TestCreateAlreadyExists(t *testing.T) { DockerImageReference: "foo/bar:abcd1234", } - fakeEtcdClient.Data["/images/foo"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images/foo")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, existingImage), @@ -165,7 +165,7 @@ func TestListError(t *testing.T) { func TestListEmptyList(t *testing.T) { fakeEtcdClient, helper := newHelper(t) fakeEtcdClient.ChangeIndex = 1 - fakeEtcdClient.Data["/images"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images")] = tools.EtcdResponseWithError{ R: &etcd.Response{}, E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound), } @@ -186,7 +186,7 @@ func TestListEmptyList(t *testing.T) { func TestListPopulatedList(t *testing.T) { fakeEtcdClient, helper := newHelper(t) fakeEtcdClient.ChangeIndex = 1 - fakeEtcdClient.Data["/images"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ @@ -214,7 +214,7 @@ func TestListPopulatedList(t *testing.T) { func TestListFiltered(t *testing.T) { fakeEtcdClient, helper := newHelper(t) fakeEtcdClient.ChangeIndex = 1 - fakeEtcdClient.Data["/images"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ @@ -305,7 +305,7 @@ func TestGetError(t *testing.T) { func TestGetNotFound(t *testing.T) { fakeEtcdClient, helper := newHelper(t) storage := NewREST(helper) - fakeEtcdClient.Data["/images/foo"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images/foo")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, @@ -327,7 +327,7 @@ func TestGetOK(t *testing.T) { ObjectMeta: kapi.ObjectMeta{Name: "foo"}, DockerImageReference: "openshift/ruby-19-centos", } - fakeEtcdClient.Data["/images/foo"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images/foo")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, expectedImage), @@ -350,7 +350,7 @@ func TestGetOK(t *testing.T) { func TestDelete(t *testing.T) { fakeEtcdClient, helper := newHelper(t) - fakeEtcdClient.Data["/images/foo"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images/foo")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, &api.Image{}), @@ -368,16 +368,16 @@ func TestDelete(t *testing.T) { t.Errorf("Unexpected non-nil error: %#v", err) } - status, ok := obj.(*kapi.Status) + status, ok := obj.(*unversioned.Status) if !ok { t.Fatalf("Expected status type, got: %#v", obj) } - if status.Status != kapi.StatusSuccess { + if status.Status != unversioned.StatusSuccess { t.Errorf("Expected status=success, got: %#v", status) } if len(fakeEtcdClient.DeletedKeys) != 1 { t.Errorf("Expected 1 delete, found %#v", fakeEtcdClient.DeletedKeys) - } else if key := "/images/foo"; fakeEtcdClient.DeletedKeys[0] != key { + } else if key := etcdtest.AddPrefix("/images/foo"); fakeEtcdClient.DeletedKeys[0] != key { t.Errorf("Unexpected key: %s, expected %s", fakeEtcdClient.DeletedKeys[0], key) } } diff --git a/pkg/image/registry/imagestream/etcd/etcd_test.go b/pkg/image/registry/imagestream/etcd/etcd_test.go index 649582ec0a44..c635722048ba 100644 --- a/pkg/image/registry/imagestream/etcd/etcd_test.go +++ b/pkg/image/registry/imagestream/etcd/etcd_test.go @@ -90,15 +90,15 @@ func TestGetImageStreamOK(t *testing.T) { ctx := kapi.NewDefaultContext() repoName := "foo" key, _ := storage.store.KeyFunc(ctx, repoName) - fakeEtcdClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ObjectMeta: kapi.ObjectMeta{Name: repoName}}), 0) + fakeEtcdClient.Set(etcdtest.AddPrefix(""+key), runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ObjectMeta: kapi.ObjectMeta{Name: repoName}}), 0) obj, err := storage.Get(kapi.NewDefaultContext(), repoName) + if err != nil { + t.Errorf("Unexpected non-nil error: %#v", err) + } if obj == nil { t.Fatalf("Unexpected nil stream") } - if err != nil { - t.Fatalf("Unexpected non-nil error: %#v", err) - } stream := obj.(*api.ImageStream) if e, a := repoName, stream.Name; e != a { t.Errorf("Expected %#v, got %#v", e, a) @@ -123,7 +123,7 @@ func TestListImageStreamsError(t *testing.T) { func TestListImageStreamsEmptyList(t *testing.T) { fakeEtcdClient, helper := newHelper(t) fakeEtcdClient.ChangeIndex = 1 - fakeEtcdClient.Data["/imagestreams/default"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default")] = tools.EtcdResponseWithError{ R: &etcd.Response{}, E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound), } @@ -145,7 +145,7 @@ func TestListImageStreamsPopulatedList(t *testing.T) { fakeEtcdClient, helper := newHelper(t) storage, _ := NewREST(helper, noDefaultRegistry, &fakeSubjectAccessReviewRegistry{}) - fakeEtcdClient.Data["/imagestreams/default"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ @@ -197,7 +197,7 @@ func TestCreateImageStreamOK(t *testing.T) { } actual := &api.ImageStream{} - if err := helper.Get("/imagestreams/default/foo", actual, false); err != nil { + if err := helper.Get(kapi.NewDefaultContext(), "/imagestreams/default/foo", actual, false); err != nil { t.Fatalf("unexpected extraction error: %v", err) } if actual.Name != stream.Name { @@ -250,7 +250,7 @@ func TestCreateImageStreamSpecTagsFromSet(t *testing.T) { if len(otherNamespace) == 0 { otherNamespace = "default" } - fakeEtcdClient.Data[fmt.Sprintf("/imagestreams/%s/other", otherNamespace)] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[fmt.Sprintf(etcdtest.AddPrefix("/imagestreams/%s/other"), otherNamespace)] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ @@ -307,7 +307,7 @@ func TestCreateImageStreamSpecTagsFromSet(t *testing.T) { } actual := &api.ImageStream{} - if err := helper.Get("/imagestreams/default/foo", actual, false); err != nil { + if err := helper.Get(kapi.NewDefaultContext(), "/imagestreams/default/foo", actual, false); err != nil { t.Fatalf("%s: unexpected extraction error: %v", name, err) } if e, a := fmt.Sprintf("%s/other:latest", otherNamespace), actual.Status.Tags["other"].Items[0].DockerImageReference; e != a { @@ -354,7 +354,7 @@ func TestUpdateRegistryErrorSaving(t *testing.T) { func TestUpdateImageStreamOK(t *testing.T) { fakeEtcdClient, helper := newHelper(t) - fakeEtcdClient.Data["/imagestreams/default/bar"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/bar")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ @@ -416,7 +416,7 @@ func TestUpdateImageStreamSpecTagsFromSet(t *testing.T) { } storage, _ := NewREST(helper, noDefaultRegistry, sarRegistry) - fakeEtcdClient.Data["/imagestreams/default/foo"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/foo")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ @@ -431,7 +431,7 @@ func TestUpdateImageStreamSpecTagsFromSet(t *testing.T) { if len(otherNamespace) == 0 { otherNamespace = "default" } - fakeEtcdClient.Data[fmt.Sprintf("/imagestreams/%s/other", otherNamespace)] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[fmt.Sprintf(etcdtest.AddPrefix("/imagestreams/%s/other"), otherNamespace)] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ @@ -488,7 +488,7 @@ func TestUpdateImageStreamSpecTagsFromSet(t *testing.T) { } actual := &api.ImageStream{} - if err := helper.Get("/imagestreams/default/foo", actual, false); err != nil { + if err := helper.Get(kapi.NewDefaultContext(), "/imagestreams/default/foo", actual, false); err != nil { t.Fatalf("%s: unexpected extraction error: %v", name, err) } if e, a := fmt.Sprintf("%s/other:latest", otherNamespace), actual.Status.Tags["other"].Items[0].DockerImageReference; e != a { @@ -499,7 +499,7 @@ func TestUpdateImageStreamSpecTagsFromSet(t *testing.T) { func TestDeleteImageStream(t *testing.T) { fakeEtcdClient, helper := newHelper(t) - fakeEtcdClient.Data["/imagestreams/default/foo"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/foo")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ @@ -515,18 +515,18 @@ func TestDeleteImageStream(t *testing.T) { if err != nil { t.Fatalf("Unexpected non-nil error: %#v", err) } - status, ok := obj.(*kapi.Status) + status, ok := obj.(*unversioned.Status) if !ok { t.Fatalf("Expected status, got %#v", obj) } - if status.Status != kapi.StatusSuccess { + if status.Status != unversioned.StatusSuccess { t.Errorf("Expected status=success, got %#v", status) } } func TestUpdateImageStreamConflictingNamespace(t *testing.T) { fakeEtcdClient, helper := newHelper(t) - fakeEtcdClient.Data["/imagestreams/legal-name/bar"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/legal-name/bar")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ diff --git a/pkg/image/registry/imagestream/registry.go b/pkg/image/registry/imagestream/registry.go index 5a024edcba17..68a523d36b75 100644 --- a/pkg/image/registry/imagestream/registry.go +++ b/pkg/image/registry/imagestream/registry.go @@ -3,6 +3,7 @@ package imagestream import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" @@ -24,7 +25,7 @@ type Registry interface { // UpdateImageStream updates an image stream's status. UpdateImageStreamStatus(ctx kapi.Context, repo *api.ImageStream) (*api.ImageStream, error) // DeleteImageStream deletes an image stream. - DeleteImageStream(ctx kapi.Context, id string) (*kapi.Status, error) + DeleteImageStream(ctx kapi.Context, id string) (*unversioned.Status, error) // WatchImageStreams watches for new/changed/deleted image streams. WatchImageStreams(ctx kapi.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) } @@ -92,12 +93,12 @@ func (s *storage) UpdateImageStreamStatus(ctx kapi.Context, imageStream *api.Ima return obj.(*api.ImageStream), nil } -func (s *storage) DeleteImageStream(ctx kapi.Context, imageStreamID string) (*kapi.Status, error) { +func (s *storage) DeleteImageStream(ctx kapi.Context, imageStreamID string) (*unversioned.Status, error) { obj, err := s.Delete(ctx, imageStreamID, nil) if err != nil { return nil, err } - return obj.(*kapi.Status), nil + return obj.(*unversioned.Status), nil } func (s *storage) WatchImageStreams(ctx kapi.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { diff --git a/pkg/image/registry/imagestream/strategy.go b/pkg/image/registry/imagestream/strategy.go index e17ef87c82c8..7a3819992533 100644 --- a/pkg/image/registry/imagestream/strategy.go +++ b/pkg/image/registry/imagestream/strategy.go @@ -7,12 +7,12 @@ import ( "github.com/golang/glog" kapi "k8s.io/kubernetes/pkg/api" kerrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/auth/user" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" "k8s.io/kubernetes/pkg/util/sets" @@ -218,7 +218,7 @@ func tagReferenceToTagEvent(stream *api.ImageStream, tagRef api.TagReference, ta switch tagRef.From.Kind { case "DockerImage": return &api.TagEvent{ - Created: util.Now(), + Created: unversioned.Now(), DockerImageReference: tagRef.From.Name, }, nil @@ -233,7 +233,7 @@ func tagReferenceToTagEvent(stream *api.ImageStream, tagRef api.TagReference, ta case 1: ref.ID = resolvedIDs.List()[0] return &api.TagEvent{ - Created: util.Now(), + Created: unversioned.Now(), DockerImageReference: ref.String(), Image: ref.ID, }, nil diff --git a/pkg/image/registry/imagestreamimage/rest_test.go b/pkg/image/registry/imagestreamimage/rest_test.go index 38a8eb68def7..afc0f3b47d7c 100644 --- a/pkg/image/registry/imagestreamimage/rest_test.go +++ b/pkg/image/registry/imagestreamimage/rest_test.go @@ -235,7 +235,7 @@ func TestGet(t *testing.T) { fakeEtcdClient, _, storage := setup(t) if test.repo != nil { - fakeEtcdClient.Data["/imagestreams/default/repo"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/repo")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, test.repo), @@ -243,7 +243,7 @@ func TestGet(t *testing.T) { }, } } else { - fakeEtcdClient.Data["/imagestreams/default/repo"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/repo")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, @@ -252,7 +252,7 @@ func TestGet(t *testing.T) { } if test.image != nil { - fakeEtcdClient.Data["/images/id"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images/id")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, test.image), @@ -260,7 +260,7 @@ func TestGet(t *testing.T) { }, } } else { - fakeEtcdClient.Data["/images/id"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images/id")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, diff --git a/pkg/image/registry/imagestreammapping/registry.go b/pkg/image/registry/imagestreammapping/registry.go index 98841571f9b2..6561e63f4895 100644 --- a/pkg/image/registry/imagestreammapping/registry.go +++ b/pkg/image/registry/imagestreammapping/registry.go @@ -3,13 +3,14 @@ package imagestreammapping import ( "github.com/openshift/origin/pkg/image/api" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" ) // Registry is an interface for things that know how to store ImageStreamMapping objects. type Registry interface { // CreateImageStreamMapping creates a new image stream mapping. - CreateImageStreamMapping(ctx kapi.Context, mapping *api.ImageStreamMapping) (*kapi.Status, error) + CreateImageStreamMapping(ctx kapi.Context, mapping *api.ImageStreamMapping) (*unversioned.Status, error) } // Storage is an interface for a standard REST Storage backend @@ -28,10 +29,10 @@ func NewRegistry(s Storage) Registry { return &storage{s} } -func (s *storage) CreateImageStreamMapping(ctx kapi.Context, mapping *api.ImageStreamMapping) (*kapi.Status, error) { +func (s *storage) CreateImageStreamMapping(ctx kapi.Context, mapping *api.ImageStreamMapping) (*unversioned.Status, error) { obj, err := s.Create(ctx, mapping) if err != nil { return nil, err } - return obj.(*kapi.Status), nil + return obj.(*unversioned.Status), nil } diff --git a/pkg/image/registry/imagestreammapping/rest.go b/pkg/image/registry/imagestreammapping/rest.go index a4450c6b2829..19b39534bd70 100644 --- a/pkg/image/registry/imagestreammapping/rest.go +++ b/pkg/image/registry/imagestreammapping/rest.go @@ -4,9 +4,9 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" "github.com/openshift/origin/pkg/image/api" @@ -85,14 +85,14 @@ func (s *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, err } next := api.TagEvent{ - Created: util.Now(), + Created: unversioned.Now(), DockerImageReference: image.DockerImageReference, Image: image.Name, } if !api.AddTagEventToImageStream(stream, tag, next) { // nothing actually changed - return &kapi.Status{Status: kapi.StatusSuccess}, nil + return &unversioned.Status{Status: unversioned.StatusSuccess}, nil } api.UpdateTrackingTags(stream, tag, next) @@ -101,7 +101,7 @@ func (s *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, err return nil, err } - return &kapi.Status{Status: kapi.StatusSuccess}, nil + return &unversioned.Status{Status: unversioned.StatusSuccess}, nil } // findStreamForMapping retrieves an ImageStream whose DockerImageRepository matches dockerRepo. diff --git a/pkg/image/registry/imagestreammapping/rest_test.go b/pkg/image/registry/imagestreammapping/rest_test.go index 4558eab9e43f..e4395985a909 100644 --- a/pkg/image/registry/imagestreammapping/rest_test.go +++ b/pkg/image/registry/imagestreammapping/rest_test.go @@ -134,7 +134,7 @@ func TestCreateSuccessWithName(t *testing.T) { ObjectMeta: kapi.ObjectMeta{Namespace: "default", Name: "somerepo"}, } - fakeEtcdClient.Data["/imagestreams/default/somerepo"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/somerepo")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, initialRepo), @@ -150,7 +150,7 @@ func TestCreateSuccessWithName(t *testing.T) { } image := &api.Image{} - if err := helper.Get("/images/imageID1", image, false); err != nil { + if err := helper.Get(kapi.NewDefaultContext(), "/images/imageID1", image, false); err != nil { t.Errorf("Unexpected error retrieving image: %#v", err) } if e, a := mapping.Image.DockerImageReference, image.DockerImageReference; e != a { @@ -161,7 +161,7 @@ func TestCreateSuccessWithName(t *testing.T) { } repo := &api.ImageStream{} - if err := helper.Get("/imagestreams/default/somerepo", repo, false); err != nil { + if err := helper.Get(kapi.NewDefaultContext(), "/imagestreams/default/somerepo", repo, false); err != nil { t.Errorf("Unexpected non-nil err: %#v", err) } if e, a := "imageID1", repo.Status.Tags["latest"].Items[0].Image; e != a { @@ -214,7 +214,7 @@ func TestAddExistingImageWithNewTag(t *testing.T) { } fakeEtcdClient, _, storage := setup(t) - fakeEtcdClient.Data["/imagestreams/default"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ @@ -226,7 +226,7 @@ func TestAddExistingImageWithNewTag(t *testing.T) { }, }, } - fakeEtcdClient.Data["/imagestreams/default/somerepo"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/somerepo")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, existingRepo), @@ -234,7 +234,7 @@ func TestAddExistingImageWithNewTag(t *testing.T) { }, }, } - fakeEtcdClient.Data["/images/default/"+imageID] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images/default/"+imageID)] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, existingImage), @@ -293,7 +293,7 @@ func TestAddExistingImageAndTag(t *testing.T) { } fakeEtcdClient, _, storage := setup(t) - fakeEtcdClient.Data["/imagestreams/default"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Nodes: []*etcd.Node{ @@ -305,7 +305,7 @@ func TestAddExistingImageAndTag(t *testing.T) { }, }, } - fakeEtcdClient.Data["/imagestreams/default/somerepo"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/somerepo")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, existingRepo), @@ -313,7 +313,7 @@ func TestAddExistingImageAndTag(t *testing.T) { }, }, } - fakeEtcdClient.Data["/images/default/existingImage"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images/default/existingImage")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, existingImage), @@ -387,7 +387,7 @@ func TestTrackingTags(t *testing.T) { }, } - if err := etcdHelper.Create("/imagestreams/default/stream", &stream, nil, 0); err != nil { + if err := etcdHelper.Create(kapi.NewDefaultContext(), "/imagestreams/default/stream", &stream, nil, 0); err != nil { t.Fatalf("Unable to create stream: %v", err) } @@ -412,7 +412,7 @@ func TestTrackingTags(t *testing.T) { t.Fatalf("Unexpected error creating mapping: %v", err) } - if err := etcdHelper.Get("/imagestreams/default/stream", &stream, false); err != nil { + if err := etcdHelper.Get(kapi.NewDefaultContext(), "/imagestreams/default/stream", &stream, false); err != nil { t.Fatalf("error extracting updated stream: %v", err) } diff --git a/pkg/image/registry/imagestreamtag/registry.go b/pkg/image/registry/imagestreamtag/registry.go index fe4c3bbb2021..910cfc152fa9 100644 --- a/pkg/image/registry/imagestreamtag/registry.go +++ b/pkg/image/registry/imagestreamtag/registry.go @@ -4,12 +4,13 @@ import ( "github.com/openshift/origin/pkg/image/api" kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" ) // Registry is an interface for things that know how to store ImageStreamTag objects. type Registry interface { GetImageStreamTag(ctx kapi.Context, nameAndTag string) (*api.ImageStreamTag, error) - DeleteImageStreamTag(ctx kapi.Context, nameAndTag string) (*kapi.Status, error) + DeleteImageStreamTag(ctx kapi.Context, nameAndTag string) (*unversioned.Status, error) } // Storage is an interface for a standard REST Storage backend @@ -37,10 +38,10 @@ func (s *storage) GetImageStreamTag(ctx kapi.Context, nameAndTag string) (*api.I return obj.(*api.ImageStreamTag), nil } -func (s *storage) DeleteImageStreamTag(ctx kapi.Context, nameAndTag string) (*kapi.Status, error) { +func (s *storage) DeleteImageStreamTag(ctx kapi.Context, nameAndTag string) (*unversioned.Status, error) { obj, err := s.Delete(ctx, nameAndTag) if err != nil { return nil, err } - return obj.(*kapi.Status), err + return obj.(*unversioned.Status), err } diff --git a/pkg/image/registry/imagestreamtag/rest.go b/pkg/image/registry/imagestreamtag/rest.go index b5e6ded65f9a..6306b61697f4 100644 --- a/pkg/image/registry/imagestreamtag/rest.go +++ b/pkg/image/registry/imagestreamtag/rest.go @@ -6,6 +6,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "github.com/openshift/origin/pkg/image/api" @@ -128,5 +129,5 @@ func (r *REST) Delete(ctx kapi.Context, id string) (runtime.Object, error) { return nil, fmt.Errorf("Error removing tag from image stream: %s", err) } - return &kapi.Status{Status: kapi.StatusSuccess}, nil + return &unversioned.Status{Status: unversioned.StatusSuccess}, nil } diff --git a/pkg/image/registry/imagestreamtag/rest_test.go b/pkg/image/registry/imagestreamtag/rest_test.go index 7f6f95fe8f7d..73a0bd8fd0bf 100644 --- a/pkg/image/registry/imagestreamtag/rest_test.go +++ b/pkg/image/registry/imagestreamtag/rest_test.go @@ -67,7 +67,7 @@ func setup(t *testing.T) (*tools.FakeEtcdClient, kstorage.Interface, *REST) { } type statusError interface { - Status() kapi.Status + Status() unversioned.Status } func TestNameAndTag(t *testing.T) { @@ -205,7 +205,7 @@ func TestGetImageStreamTag(t *testing.T) { fakeEtcdClient, _, storage := setup(t) if testCase.image != nil { - fakeEtcdClient.Data["/images/"+testCase.image.Name] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images/"+testCase.image.Name)] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, testCase.image), @@ -214,7 +214,7 @@ func TestGetImageStreamTag(t *testing.T) { }, } } else { - fakeEtcdClient.Data["/images/10"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/images/10")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, @@ -223,7 +223,7 @@ func TestGetImageStreamTag(t *testing.T) { } if testCase.repo != nil { - fakeEtcdClient.Data["/imagestreams/default/test"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/test")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, testCase.repo), @@ -232,7 +232,7 @@ func TestGetImageStreamTag(t *testing.T) { }, } } else { - fakeEtcdClient.Data["/imagestreams/default/test"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/test")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, @@ -373,7 +373,7 @@ func TestDeleteImageStreamTag(t *testing.T) { for name, testCase := range tests { fakeEtcdClient, helper, storage := setup(t) if testCase.repo != nil { - fakeEtcdClient.Data["/imagestreams/default/test"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/test")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, testCase.repo), @@ -382,7 +382,7 @@ func TestDeleteImageStreamTag(t *testing.T) { }, } } else { - fakeEtcdClient.Data["/imagestreams/default/test"] = tools.EtcdResponseWithError{ + fakeEtcdClient.Data[etcdtest.AddPrefix("/imagestreams/default/test")] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: nil, }, @@ -403,13 +403,13 @@ func TestDeleteImageStreamTag(t *testing.T) { if obj == nil { t.Fatalf("%s: unexpected nil response", name) } - expectedStatus := &kapi.Status{Status: kapi.StatusSuccess} + expectedStatus := &unversioned.Status{Status: unversioned.StatusSuccess} if e, a := expectedStatus, obj; !reflect.DeepEqual(e, a) { t.Errorf("%s: expected %#v, got %#v", name, e, a) } updatedRepo := &api.ImageStream{} - if err := helper.Get("/imagestreams/default/test", updatedRepo, false); err != nil { + if err := helper.Get(kapi.NewDefaultContext(), "/imagestreams/default/test", updatedRepo, false); err != nil { t.Fatalf("%s: error retrieving updated repo: %s", name, err) } expected := map[string]api.TagReference{ diff --git a/pkg/ipfailover/keepalived/generator.go b/pkg/ipfailover/keepalived/generator.go index cd3ebc6b4514..c7c8dd5c1399 100644 --- a/pkg/ipfailover/keepalived/generator.go +++ b/pkg/ipfailover/keepalived/generator.go @@ -155,7 +155,9 @@ func GenerateDeploymentConfig(name string, options *ipfailover.IPFailoverConfigC podTemplate := &kapi.PodTemplateSpec{ ObjectMeta: kapi.ObjectMeta{Labels: selector}, Spec: kapi.PodSpec{ - HostNetwork: true, + SecurityContext: &kapi.PodSecurityContext{ + HostNetwork: true, + }, NodeSelector: generateNodeSelector(name, selector), Containers: containers, Volumes: generateVolumeConfig(), diff --git a/pkg/ipfailover/keepalived/generator_test.go b/pkg/ipfailover/keepalived/generator_test.go index 47f8ca44f1e4..3be9283f0ef9 100644 --- a/pkg/ipfailover/keepalived/generator_test.go +++ b/pkg/ipfailover/keepalived/generator_test.go @@ -101,7 +101,7 @@ func TestGenerateDeploymentConfig(t *testing.T) { } podSpec := controller.Template.Spec - if !podSpec.HostNetwork { + if !podSpec.SecurityContext.HostNetwork { t.Errorf("Test case for %s got HostNetwork disabled where HostNetwork was expected to be enabled", tc.Name) } diff --git a/pkg/oauth/api/types.go b/pkg/oauth/api/types.go index 1365e7c933a1..78effbbccc0a 100644 --- a/pkg/oauth/api/types.go +++ b/pkg/oauth/api/types.go @@ -2,10 +2,11 @@ package api import ( kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" ) type OAuthAccessToken struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // ClientName references the client that created this token. @@ -34,7 +35,7 @@ type OAuthAccessToken struct { } type OAuthAuthorizeToken struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // ClientName references the client that created this token. @@ -61,7 +62,7 @@ type OAuthAuthorizeToken struct { } type OAuthClient struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Secret is the unique secret associated with a client @@ -75,7 +76,7 @@ type OAuthClient struct { } type OAuthClientAuthorization struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // ClientName references the client that created this authorization @@ -93,25 +94,25 @@ type OAuthClientAuthorization struct { } type OAuthAccessTokenList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []OAuthAccessToken } type OAuthAuthorizeTokenList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []OAuthAuthorizeToken } type OAuthClientList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []OAuthClient } type OAuthClientAuthorizationList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []OAuthClientAuthorization } diff --git a/pkg/oauth/api/v1/types.go b/pkg/oauth/api/v1/types.go index ca183aa973dc..fe8ceb3bd06b 100644 --- a/pkg/oauth/api/v1/types.go +++ b/pkg/oauth/api/v1/types.go @@ -1,12 +1,13 @@ package v1 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1" ) type OAuthAccessToken struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // ClientName references the client that created this token. ClientName string `json:"clientName,omitempty" description:"references the client that created this token"` @@ -34,8 +35,8 @@ type OAuthAccessToken struct { } type OAuthAuthorizeToken struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // ClientName references the client that created this token. ClientName string `json:"clientName,omitempty" description:"references the client that created this token"` @@ -61,8 +62,8 @@ type OAuthAuthorizeToken struct { } type OAuthClient struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Secret is the unique secret associated with a client Secret string `json:"secret,omitempty" description:"unique secret associated with a client"` @@ -75,8 +76,8 @@ type OAuthClient struct { } type OAuthClientAuthorization struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // ClientName references the client that created this authorization ClientName string `json:"clientName,omitempty" description:"references the client that created this authorization"` @@ -93,25 +94,25 @@ type OAuthClientAuthorization struct { } type OAuthAccessTokenList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []OAuthAccessToken `json:"items" description:"list of oauth access tokens"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []OAuthAccessToken `json:"items" description:"list of oauth access tokens"` } type OAuthAuthorizeTokenList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []OAuthAuthorizeToken `json:"items" description:"list of oauth authorization tokens"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []OAuthAuthorizeToken `json:"items" description:"list of oauth authorization tokens"` } type OAuthClientList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []OAuthClient `json:"items" description:"list of oauth clients"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []OAuthClient `json:"items" description:"list of oauth clients"` } type OAuthClientAuthorizationList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []OAuthClientAuthorization `json:"items" description:"list of oauth client authorizations"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []OAuthClientAuthorization `json:"items" description:"list of oauth client authorizations"` } diff --git a/pkg/oauth/api/v1beta3/types.go b/pkg/oauth/api/v1beta3/types.go index 57c0e6bb2e9d..5323174e3c71 100644 --- a/pkg/oauth/api/v1beta3/types.go +++ b/pkg/oauth/api/v1beta3/types.go @@ -1,12 +1,13 @@ package v1beta3 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1beta3" ) type OAuthAccessToken struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // ClientName references the client that created this token. ClientName string `json:"clientName,omitempty"` @@ -34,8 +35,8 @@ type OAuthAccessToken struct { } type OAuthAuthorizeToken struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // ClientName references the client that created this token. ClientName string `json:"clientName,omitempty"` @@ -61,8 +62,8 @@ type OAuthAuthorizeToken struct { } type OAuthClient struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Secret is the unique secret associated with a client Secret string `json:"secret,omitempty"` @@ -75,8 +76,8 @@ type OAuthClient struct { } type OAuthClientAuthorization struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // ClientName references the client that created this authorization ClientName string `json:"clientName,omitempty"` @@ -93,25 +94,25 @@ type OAuthClientAuthorization struct { } type OAuthAccessTokenList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []OAuthAccessToken `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []OAuthAccessToken `json:"items"` } type OAuthAuthorizeTokenList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []OAuthAuthorizeToken `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []OAuthAuthorizeToken `json:"items"` } type OAuthClientList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []OAuthClient `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []OAuthClient `json:"items"` } type OAuthClientAuthorizationList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []OAuthClientAuthorization `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []OAuthClientAuthorization `json:"items"` } diff --git a/pkg/oauth/server/osinserver/registrystorage/storage.go b/pkg/oauth/server/osinserver/registrystorage/storage.go index eb475641eeaa..5e2d65cc0593 100644 --- a/pkg/oauth/server/osinserver/registrystorage/storage.go +++ b/pkg/oauth/server/osinserver/registrystorage/storage.go @@ -7,7 +7,7 @@ import ( "github.com/RangelReale/osin" kapi "k8s.io/kubernetes/pkg/api" kerrors "k8s.io/kubernetes/pkg/api/errors" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" "github.com/openshift/origin/pkg/oauth/api" "github.com/openshift/origin/pkg/oauth/registry/oauthaccesstoken" @@ -158,7 +158,7 @@ func (s *storage) convertToAuthorizeToken(data *osin.AuthorizeData) (*api.OAuthA token := &api.OAuthAuthorizeToken{ ObjectMeta: kapi.ObjectMeta{ Name: data.Code, - CreationTimestamp: util.Time{Time: data.CreatedAt}, + CreationTimestamp: unversioned.Time{Time: data.CreatedAt}, }, ClientName: data.Client.GetId(), ExpiresIn: int64(data.ExpiresIn), @@ -198,7 +198,7 @@ func (s *storage) convertToAccessToken(data *osin.AccessData) (*api.OAuthAccessT token := &api.OAuthAccessToken{ ObjectMeta: kapi.ObjectMeta{ Name: data.AccessToken, - CreationTimestamp: util.Time{Time: data.CreatedAt}, + CreationTimestamp: unversioned.Time{Time: data.CreatedAt}, }, ExpiresIn: int64(data.ExpiresIn), RefreshToken: data.RefreshToken, diff --git a/pkg/project/api/types.go b/pkg/project/api/types.go index 84b8ed4decc2..16571a994fe4 100644 --- a/pkg/project/api/types.go +++ b/pkg/project/api/types.go @@ -2,12 +2,13 @@ package api import ( kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" ) // ProjectList is a list of Project objects. type ProjectList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []Project } @@ -29,7 +30,7 @@ type ProjectStatus struct { // Project is a logical top-level container for a set of origin resources type Project struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta Spec ProjectSpec @@ -37,7 +38,7 @@ type Project struct { } type ProjectRequest struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta DisplayName string Description string diff --git a/pkg/project/api/v1/types.go b/pkg/project/api/v1/types.go index 42632ccfaa35..137bafe6697b 100644 --- a/pkg/project/api/v1/types.go +++ b/pkg/project/api/v1/types.go @@ -1,14 +1,15 @@ package v1 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1" ) // ProjectList is a list of Project objects. type ProjectList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []Project `json:"items" description:"list of projects"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []Project `json:"items" description:"list of projects"` } const ( @@ -29,8 +30,8 @@ type ProjectStatus struct { // Project is a logical top-level container for a set of origin resources type Project struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Spec defines the behavior of the Namespace. Spec ProjectSpec `json:"spec,omitempty" description:"spec defines the behavior of the Project"` @@ -40,8 +41,8 @@ type Project struct { } type ProjectRequest struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` - DisplayName string `json:"displayName,omitempty" description:"display name to apply to a project"` - Description string `json:"description,omitempty" description:"description to apply to a project"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` + DisplayName string `json:"displayName,omitempty" description:"display name to apply to a project"` + Description string `json:"description,omitempty" description:"description to apply to a project"` } diff --git a/pkg/project/api/v1beta3/types.go b/pkg/project/api/v1beta3/types.go index 02ec6e3be195..c64a42c02583 100644 --- a/pkg/project/api/v1beta3/types.go +++ b/pkg/project/api/v1beta3/types.go @@ -1,14 +1,15 @@ package v1beta3 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1beta3" ) // ProjectList is a list of Project objects. type ProjectList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []Project `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []Project `json:"items"` } const ( @@ -29,8 +30,8 @@ type ProjectStatus struct { // Project is a logical top-level container for a set of origin resources type Project struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Spec defines the behavior of the Namespace. Spec ProjectSpec `json:"spec,omitempty" description:"spec defines the behavior of the Project"` @@ -40,10 +41,10 @@ type Project struct { } type ProjectRequest struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` - DisplayName string `json:"displayName,omitempty"` - Description string `json:"description,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` + DisplayName string `json:"displayName,omitempty"` + Description string `json:"description,omitempty"` } // These constants represent annotations keys affixed to projects diff --git a/pkg/project/controller/controller_test.go b/pkg/project/controller/controller_test.go index 38209861317a..50d279176fb2 100644 --- a/pkg/project/controller/controller_test.go +++ b/pkg/project/controller/controller_test.go @@ -17,7 +17,7 @@ func TestSyncNamespaceThatIsTerminating(t *testing.T) { KubeClient: mockKubeClient, Client: mockOriginClient, } - now := util.Now() + now := unversioned.Now() testNamespace := &kapi.Namespace{ ObjectMeta: kapi.ObjectMeta{ Name: "test", diff --git a/pkg/project/registry/project/proxy/proxy.go b/pkg/project/registry/project/proxy/proxy.go index 48876288d0c9..7fe4a304eb08 100644 --- a/pkg/project/registry/project/proxy/proxy.go +++ b/pkg/project/registry/project/proxy/proxy.go @@ -6,6 +6,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kerrors "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" kclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -101,7 +102,7 @@ func (s *REST) List(ctx kapi.Context, label labels.Selector, field fields.Select return nil, err } m := nsregistry.MatchNamespace(label, field) - list, err := generic.FilterList(namespaceList, m, nil) + list, err := filterList(namespaceList, m, nil) if err != nil { return nil, err } @@ -160,5 +161,40 @@ func (s *REST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, boo // Delete deletes a Project specified by its name func (s *REST) Delete(ctx kapi.Context, name string) (runtime.Object, error) { - return &kapi.Status{Status: kapi.StatusSuccess}, s.client.Delete(name) + return &unversioned.Status{Status: unversioned.StatusSuccess}, s.client.Delete(name) +} + +// decoratorFunc can mutate the provided object prior to being returned. +type decoratorFunc func(obj runtime.Object) error + +// filterList filters any list object that conforms to the api conventions, +// provided that 'm' works with the concrete type of list. d is an optional +// decorator for the returned functions. Only matching items are decorated. +func filterList(list runtime.Object, m generic.Matcher, d decoratorFunc) (filtered runtime.Object, err error) { + // TODO: push a matcher down into tools.etcdHelper to avoid all this + // nonsense. This is a lot of unnecessary copies. + items, err := runtime.ExtractList(list) + if err != nil { + return nil, err + } + var filteredItems []runtime.Object + for _, obj := range items { + match, err := m.Matches(obj) + if err != nil { + return nil, err + } + if match { + if d != nil { + if err := d(obj); err != nil { + return nil, err + } + } + filteredItems = append(filteredItems, obj) + } + } + err = runtime.SetList(list, filteredItems) + if err != nil { + return nil, err + } + return list, nil } diff --git a/pkg/project/registry/project/proxy/proxy_test.go b/pkg/project/registry/project/proxy/proxy_test.go index dd914f54ee30..c55f992ed6ea 100644 --- a/pkg/project/registry/project/proxy/proxy_test.go +++ b/pkg/project/registry/project/proxy/proxy_test.go @@ -126,11 +126,11 @@ func TestDeleteProject(t *testing.T) { if err != nil { t.Errorf("Unexpected non-nil error: %#v", err) } - status, ok := obj.(*kapi.Status) + status, ok := obj.(*unversioned.Status) if !ok { t.Errorf("Expected status type, got: %#v", obj) } - if status.Status != kapi.StatusSuccess { + if status.Status != unversioned.StatusSuccess { t.Errorf("Expected status=success, got: %#v", status) } if len(mockClient.Actions()) != 1 { diff --git a/pkg/project/registry/projectrequest/delegated/delegated.go b/pkg/project/registry/projectrequest/delegated/delegated.go index 76346bfe8863..8baf775098ea 100644 --- a/pkg/project/registry/projectrequest/delegated/delegated.go +++ b/pkg/project/registry/projectrequest/delegated/delegated.go @@ -8,6 +8,7 @@ import ( kapierror "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" kclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/kubectl/resource" @@ -49,7 +50,7 @@ func (r *REST) New() runtime.Object { } func (r *REST) NewList() runtime.Object { - return &kapi.Status{} + return &unversioned.Status{} } func (r *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) { @@ -166,15 +167,15 @@ func (r *REST) List(ctx kapi.Context, label labels.Selector, field fields.Select return nil, err } if accessReviewResponse.Allowed { - return &kapi.Status{Status: kapi.StatusSuccess}, nil + return &unversioned.Status{Status: unversioned.StatusSuccess}, nil } forbiddenError, _ := kapierror.NewForbidden("ProjectRequest", "", errors.New("you may not request a new project via this API.")).(*kapierror.StatusError) if len(r.message) > 0 { forbiddenError.ErrStatus.Message = r.message - forbiddenError.ErrStatus.Details = &kapi.StatusDetails{ + forbiddenError.ErrStatus.Details = &unversioned.StatusDetails{ Kind: "ProjectRequest", - Causes: []kapi.StatusCause{ + Causes: []unversioned.StatusCause{ {Message: r.message}, }, } diff --git a/pkg/route/api/types.go b/pkg/route/api/types.go index 30d9d1a4e1b5..a633d96df3e3 100644 --- a/pkg/route/api/types.go +++ b/pkg/route/api/types.go @@ -2,12 +2,13 @@ package api import ( kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util" ) // Route encapsulates the inputs needed to connect an alias to endpoints. type Route struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Spec is the desired behavior of the route @@ -52,8 +53,8 @@ type RouteStatus struct { // RouteList is a collection of Routes. type RouteList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta // Items is a list of routes Items []Route diff --git a/pkg/route/api/v1/types.go b/pkg/route/api/v1/types.go index 9751b4cf66d8..641967145ded 100644 --- a/pkg/route/api/v1/types.go +++ b/pkg/route/api/v1/types.go @@ -1,14 +1,15 @@ package v1 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/util" ) // Route encapsulates the inputs needed to connect an alias to endpoints. type Route struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Spec is the desired state of the route Spec RouteSpec `json:"spec" description:"desired state of the route"` @@ -18,8 +19,8 @@ type Route struct { // RouteList is a collection of Routes. type RouteList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of routes Items []Route `json:"items" description:"list of routes"` diff --git a/pkg/route/api/v1beta3/types.go b/pkg/route/api/v1beta3/types.go index 6a5133d3ba6f..84e2ae24927c 100644 --- a/pkg/route/api/v1beta3/types.go +++ b/pkg/route/api/v1beta3/types.go @@ -1,14 +1,15 @@ package v1beta3 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1beta3" "k8s.io/kubernetes/pkg/util" ) // Route encapsulates the inputs needed to connect an alias to endpoints. type Route struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` Spec RouteSpec `json:"spec"` Status RouteStatus `json:"status"` @@ -16,9 +17,9 @@ type Route struct { // RouteList is a collection of Routes. type RouteList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []Route `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []Route `json:"items"` } // RouteSpec describes the route the user wishes to exist. diff --git a/pkg/route/api/validation/validation.go b/pkg/route/api/validation/validation.go index 57b754512882..75c5ea03c332 100644 --- a/pkg/route/api/validation/validation.go +++ b/pkg/route/api/validation/validation.go @@ -8,6 +8,7 @@ import ( kval "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" + kvalidation "k8s.io/kubernetes/pkg/util/validation" oapi "github.com/openshift/origin/pkg/api" routeapi "github.com/openshift/origin/pkg/route/api" @@ -22,7 +23,7 @@ func ValidateRoute(route *routeapi.Route) fielderrors.ValidationErrorList { //host is not required but if it is set ensure it meets DNS requirements if len(route.Spec.Host) > 0 { - if !util.IsDNS1123Subdomain(route.Spec.Host) { + if !kvalidation.IsDNS1123Subdomain(route.Spec.Host) { result = append(result, fielderrors.NewFieldInvalid("host", route.Spec.Host, "host must conform to DNS 952 subdomain conventions")) } } diff --git a/pkg/sdn/api/types.go b/pkg/sdn/api/types.go index a9e0b990e361..fe550a22fde3 100644 --- a/pkg/sdn/api/types.go +++ b/pkg/sdn/api/types.go @@ -2,10 +2,11 @@ package api import ( kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" ) type ClusterNetwork struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta Network string @@ -14,14 +15,14 @@ type ClusterNetwork struct { } type ClusterNetworkList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []ClusterNetwork } // HostSubnet encapsulates the inputs needed to define the container subnet network on a node type HostSubnet struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // host may just be an IP address, resolvable hostname or a complete DNS @@ -32,14 +33,14 @@ type HostSubnet struct { // HostSubnetList is a collection of HostSubnets type HostSubnetList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []HostSubnet } // NetNamespace holds the network id against its name type NetNamespace struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta NetName string @@ -48,7 +49,7 @@ type NetNamespace struct { // NetNamespaceList is a collection of NetNamespaces type NetNamespaceList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []NetNamespace } diff --git a/pkg/sdn/api/v1/types.go b/pkg/sdn/api/v1/types.go index 17b8c6e1b6c9..eb10be71b2b9 100644 --- a/pkg/sdn/api/v1/types.go +++ b/pkg/sdn/api/v1/types.go @@ -1,12 +1,13 @@ package v1 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1" ) type ClusterNetwork struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` Network string `json:"network" description:"CIDR string to specify the global overlay network's L3 space"` HostSubnetLength int `json:"hostsubnetlength" description:"number of bits to allocate to each host's subnet e.g. 8 would mean a /24 network on the host"` @@ -14,15 +15,15 @@ type ClusterNetwork struct { } type ClusterNetworkList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []ClusterNetwork `json:"items" description:"list of cluster networks"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []ClusterNetwork `json:"items" description:"list of cluster networks"` } // HostSubnet encapsulates the inputs needed to define the container subnet network on a node type HostSubnet struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // host may just be an IP address, resolvable hostname or a complete DNS Host string `json:"host" description:"Name of the host that is registered at the master. A lease will be sought after this name."` @@ -32,15 +33,15 @@ type HostSubnet struct { // HostSubnetList is a collection of HostSubnets type HostSubnetList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []HostSubnet `json:"items" description:"list of host subnets"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []HostSubnet `json:"items" description:"list of host subnets"` } // NetNamespace encapsulates the inputs needed to define a unique network namespace on the cluster type NetNamespace struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` NetName string `json:"netname" description:"Name of the network namespace."` NetID uint `json:"netid" description:"NetID of the network namespace assigned to each overlay network packet."` @@ -48,7 +49,7 @@ type NetNamespace struct { // NetNamespaceList is a collection of NetNamespaces type NetNamespaceList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []NetNamespace `json:"items" description:"list of net namespaces"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []NetNamespace `json:"items" description:"list of net namespaces"` } diff --git a/pkg/sdn/api/v1beta3/types.go b/pkg/sdn/api/v1beta3/types.go index 92b91ce72629..685fd7f0fb3c 100644 --- a/pkg/sdn/api/v1beta3/types.go +++ b/pkg/sdn/api/v1beta3/types.go @@ -1,12 +1,13 @@ package v1beta3 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1beta3" ) type ClusterNetwork struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` Network string `json:"network" description:"CIDR string to specify the global overlay network's L3 space"` HostSubnetLength int `json:"hostsubnetlength" description:"number of bits to allocate to each host's subnet e.g. 8 would mean a /24 network on the host"` @@ -14,15 +15,15 @@ type ClusterNetwork struct { } type ClusterNetworkList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []ClusterNetwork `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []ClusterNetwork `json:"items"` } // HostSubnet encapsulates the inputs needed to define the container subnet network on a node type HostSubnet struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // host may just be an IP address, resolvable hostname or a complete DNS Host string `json:"host" description:"Name of the host that is registered at the master. A lease will be sought after this name."` @@ -32,15 +33,15 @@ type HostSubnet struct { // HostSubnetList is a collection of HostSubnets type HostSubnetList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []HostSubnet `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []HostSubnet `json:"items"` } // NetNamespace encapsulates the inputs needed to define a unique network namespace on the cluster type NetNamespace struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` NetName string `json:"netname" description:"Name of the network namespace."` NetID uint `json:"netid" description:"NetID of the network namespace assigned to each overlay network packet."` @@ -48,7 +49,7 @@ type NetNamespace struct { // NetNamespaceList is a collection of NetNamespaces type NetNamespaceList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []NetNamespace `json:"items" description:"list of net namespaces"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []NetNamespace `json:"items" description:"list of net namespaces"` } diff --git a/pkg/serviceaccounts/controllers/docker_registry_service.go b/pkg/serviceaccounts/controllers/docker_registry_service.go index 28bf74891b8e..578f5927e343 100644 --- a/pkg/serviceaccounts/controllers/docker_registry_service.go +++ b/pkg/serviceaccounts/controllers/docker_registry_service.go @@ -45,7 +45,7 @@ func NewDockerRegistryServiceController(cl client.Interface, options DockerRegis _, e.serviceController = framework.NewInformer( &cache.ListWatch{ ListFunc: func() (runtime.Object, error) { - return e.client.Services(options.RegistryNamespace).List(labels.Everything()) + return e.client.Services(options.RegistryNamespace).List(labels.Everything(), fields.Everything()) }, WatchFunc: func(rv string) (watch.Interface, error) { return e.client.Services(options.RegistryNamespace).Watch(labels.Everything(), fields.Everything(), rv) diff --git a/pkg/template/api/types.go b/pkg/template/api/types.go index 6472b099cdb6..e2d699dd2f5f 100644 --- a/pkg/template/api/types.go +++ b/pkg/template/api/types.go @@ -2,12 +2,13 @@ package api import ( kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" ) // Template contains the inputs needed to produce a Config. type Template struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // Optional: Parameters is an array of Parameters used during the @@ -24,8 +25,8 @@ type Template struct { // TemplateList is a list of Template objects. type TemplateList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []Template } diff --git a/pkg/template/api/v1/types.go b/pkg/template/api/v1/types.go index cfd285232dde..6b8cfac32907 100644 --- a/pkg/template/api/v1/types.go +++ b/pkg/template/api/v1/types.go @@ -1,14 +1,15 @@ package v1 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/runtime" ) // Template contains the inputs needed to produce a Config. type Template struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Objects is an array of objects to include in this template. Required. Objects []runtime.RawExtension `json:"objects" description:"list of objects to include in the template"` @@ -24,8 +25,8 @@ type Template struct { // TemplateList is a list of Template objects. type TemplateList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of templates Items []Template `json:"items" description:"list of templates"` diff --git a/pkg/template/api/v1beta3/types.go b/pkg/template/api/v1beta3/types.go index d8718bf81c8d..6f71af83b61c 100644 --- a/pkg/template/api/v1beta3/types.go +++ b/pkg/template/api/v1beta3/types.go @@ -1,14 +1,15 @@ package v1beta3 import ( + "k8s.io/kubernetes/pkg/api/unversioned" kapi "k8s.io/kubernetes/pkg/api/v1beta3" "k8s.io/kubernetes/pkg/runtime" ) // Template contains the inputs needed to produce a Config. type Template struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Required: Objects is an array of objects to include in this template Objects []runtime.RawExtension `json:"objects"` @@ -24,9 +25,9 @@ type Template struct { // TemplateList is a list of Template objects. type TemplateList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []Template `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []Template `json:"items"` } // Parameter defines a name/value variable that is to be processed during diff --git a/pkg/template/template_test.go b/pkg/template/template_test.go index 9fb769ad51f5..fabd3be36477 100644 --- a/pkg/template/template_test.go +++ b/pkg/template/template_test.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "math/rand" "regexp" + "strings" "testing" _ "k8s.io/kubernetes/pkg/api/latest" @@ -164,8 +165,9 @@ func TestProcessValueEscape(t *testing.T) { t.Fatalf("unexpected error during encoding Config: %#v", err) } expect := `{"kind":"Template","apiVersion":"v1beta3","metadata":{"creationTimestamp":null},"objects":[{"apiVersion":"v1beta31","kind":"Service","metadata":{"labels":{"key1":"1","key2":"$1"}}}],"parameters":[{"name":"VALUE","value":"1"}]}` - if expect != string(result) { - t.Errorf("unexpected output: %s", util.StringDiff(expect, string(result))) + stringResult := strings.TrimSpace(string(result)) + if expect != stringResult { + t.Errorf("unexpected output: %s", util.StringDiff(expect, stringResult)) } } @@ -322,8 +324,9 @@ func TestEvaluateLabels(t *testing.T) { } expect := testCase.Output expect = trailingWhitespace.ReplaceAllString(expect, "") - if expect != string(result) { - t.Errorf("%s: unexpected output: %s", k, util.StringDiff(expect, string(result))) + stringResult := strings.TrimSpace(string(result)) + if expect != stringResult { + t.Errorf("%s: unexpected output: %s", k, util.StringDiff(expect, stringResult)) continue } } diff --git a/pkg/user/api/types.go b/pkg/user/api/types.go index 8470415d57d9..ca411f979f98 100644 --- a/pkg/user/api/types.go +++ b/pkg/user/api/types.go @@ -1,12 +1,15 @@ package api -import kapi "k8s.io/kubernetes/pkg/api" +import ( + kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" +) // Auth system gets identity name and provider // POST to UserIdentityMapping, get back error or a filled out UserIdentityMapping object type User struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta FullName string @@ -17,13 +20,13 @@ type User struct { } type UserList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []User } type Identity struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta // ProviderName is the source of identity information @@ -40,13 +43,13 @@ type Identity struct { } type IdentityList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []Identity } type UserIdentityMapping struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta Identity kapi.ObjectReference @@ -55,15 +58,15 @@ type UserIdentityMapping struct { // Group represents a referenceable set of Users type Group struct { - kapi.TypeMeta + unversioned.TypeMeta kapi.ObjectMeta Users []string } type GroupList struct { - kapi.TypeMeta - kapi.ListMeta + unversioned.TypeMeta + unversioned.ListMeta Items []Group } diff --git a/pkg/user/api/v1/types.go b/pkg/user/api/v1/types.go index 51069a7767a1..544c468efe93 100644 --- a/pkg/user/api/v1/types.go +++ b/pkg/user/api/v1/types.go @@ -1,13 +1,16 @@ package v1 -import kapi "k8s.io/kubernetes/pkg/api/v1" +import ( + "k8s.io/kubernetes/pkg/api/unversioned" + kapi "k8s.io/kubernetes/pkg/api/v1" +) // Auth system gets identity name and provider // POST to UserIdentityMapping, get back error or a filled out UserIdentityMapping object type User struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` FullName string `json:"fullName,omitempty" description:"full name of user"` @@ -17,14 +20,14 @@ type User struct { } type UserList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []User `json:"items" description:"list of users"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []User `json:"items" description:"list of users"` } type Identity struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // ProviderName is the source of identity information ProviderName string `json:"providerName" description:"source of identity information"` @@ -40,14 +43,14 @@ type Identity struct { } type IdentityList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []Identity `json:"items" description:"list of identities"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []Identity `json:"items" description:"list of identities"` } type UserIdentityMapping struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` Identity kapi.ObjectReference `json:"identity,omitempty" description:"reference to an identity"` User kapi.ObjectReference `json:"user,omitempty" description:"reference to a user"` @@ -55,17 +58,17 @@ type UserIdentityMapping struct { // Group represents a referenceable set of Users type Group struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Users is the list of users in this group. Users []string `json:"users" description:"list of users in this group"` } type GroupList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []Group `json:"items" description:"list of groups"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []Group `json:"items" description:"list of groups"` } func (*GroupList) IsAnAPIObject() {} diff --git a/pkg/user/api/v1beta3/types.go b/pkg/user/api/v1beta3/types.go index e1a7a66a3eec..95090e0de48b 100644 --- a/pkg/user/api/v1beta3/types.go +++ b/pkg/user/api/v1beta3/types.go @@ -1,13 +1,16 @@ package v1beta3 -import kapi "k8s.io/kubernetes/pkg/api/v1beta3" +import ( + "k8s.io/kubernetes/pkg/api/unversioned" + kapi "k8s.io/kubernetes/pkg/api/v1beta3" +) // Auth system gets identity name and provider // POST to UserIdentityMapping, get back error or a filled out UserIdentityMapping object type User struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` FullName string `json:"fullName,omitempty"` @@ -17,14 +20,14 @@ type User struct { } type UserList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []User `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []User `json:"items"` } type Identity struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // ProviderName is the source of identity information ProviderName string `json:"providerName"` @@ -40,14 +43,14 @@ type Identity struct { } type IdentityList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []Identity `json:"items"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []Identity `json:"items"` } type UserIdentityMapping struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` Identity kapi.ObjectReference `json:"identity,omitempty"` User kapi.ObjectReference `json:"user,omitempty"` @@ -55,17 +58,17 @@ type UserIdentityMapping struct { // Group represents a referenceable set of Users type Group struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` // Users is the list of users in this group. Users []string `json:"users" description:"list of users in this group"` } type GroupList struct { - kapi.TypeMeta `json:",inline"` - kapi.ListMeta `json:"metadata,omitempty"` - Items []Group `json:"items" description:"list of groups"` + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []Group `json:"items" description:"list of groups"` } func (*GroupList) IsAnAPIObject() {} diff --git a/pkg/user/registry/useridentitymapping/rest.go b/pkg/user/registry/useridentitymapping/rest.go index eace92f828ed..8617fcb20a38 100644 --- a/pkg/user/registry/useridentitymapping/rest.go +++ b/pkg/user/registry/useridentitymapping/rest.go @@ -6,6 +6,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kerrs "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" @@ -188,7 +189,7 @@ func (s *REST) Delete(ctx kapi.Context, name string) (runtime.Object, error) { } } - return &kapi.Status{Status: kapi.StatusSuccess}, nil + return &unversioned.Status{Status: unversioned.StatusSuccess}, nil } // getRelatedObjects returns the identity, user, and mapping for the named identity diff --git a/pkg/util/labels_test.go b/pkg/util/labels_test.go index b3e64e0dacfb..07cd8e355116 100644 --- a/pkg/util/labels_test.go +++ b/pkg/util/labels_test.go @@ -6,14 +6,15 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kmeta "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" deployapi "github.com/openshift/origin/pkg/deploy/api" ) type FakeLabelsResource struct { - kapi.TypeMeta `json:",inline"` - kapi.ObjectMeta `json:"metadata,omitempty"` + unversioned.TypeMeta `json:",inline"` + kapi.ObjectMeta `json:"metadata,omitempty"` } func (*FakeLabelsResource) IsAnAPIObject() {} diff --git a/pkg/util/labelselector/labelselector.go b/pkg/util/labelselector/labelselector.go index 65fb1ccccb3e..c9e8b90d87a9 100644 --- a/pkg/util/labelselector/labelselector.go +++ b/pkg/util/labelselector/labelselector.go @@ -23,8 +23,8 @@ package labelselector import ( "fmt" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" + kvalidation "k8s.io/kubernetes/pkg/util/validation" ) // constants definition for lexer token @@ -356,17 +356,17 @@ func Equals(labels1, labels2 map[string]string) bool { return true } -const qualifiedNameErrorMsg string = "must match regex [" + util.DNS1123SubdomainFmt + " / ] " + util.DNS1123LabelFmt +const qualifiedNameErrorMsg string = "must match regex [" + kvalidation.DNS1123SubdomainFmt + " / ] " + kvalidation.DNS1123LabelFmt func validateLabelKey(k string) error { - if !util.IsQualifiedName(k) { + if !kvalidation.IsQualifiedName(k) { return fielderrors.NewFieldInvalid("label key", k, qualifiedNameErrorMsg) } return nil } func validateLabelValue(v string) error { - if !util.IsValidLabelValue(v) { + if !kvalidation.IsValidLabelValue(v) { return fielderrors.NewFieldInvalid("label value", v, qualifiedNameErrorMsg) } return nil diff --git a/pkg/util/namer/namer.go b/pkg/util/namer/namer.go index ea70aa7373df..7deed2b2697d 100644 --- a/pkg/util/namer/namer.go +++ b/pkg/util/namer/namer.go @@ -4,7 +4,7 @@ import ( "fmt" "hash/fnv" - "k8s.io/kubernetes/pkg/util" + kvalidation "k8s.io/kubernetes/pkg/util/validation" ) // GetName returns a name given a base ("deployment-5") and a suffix ("deploy") @@ -34,7 +34,7 @@ func GetName(base, suffix string, maxLength int) string { // GetPodName calls GetName with the length restriction for pods func GetPodName(base, suffix string) string { - return GetName(base, suffix, util.DNS1123SubdomainMaxLength) + return GetName(base, suffix, kvalidation.DNS1123SubdomainMaxLength) } // min returns the lesser of its 2 inputs diff --git a/pkg/util/namer/namer_test.go b/pkg/util/namer/namer_test.go index 8d3a4c03c3a6..0c318cf046b1 100644 --- a/pkg/util/namer/namer_test.go +++ b/pkg/util/namer/namer_test.go @@ -10,8 +10,8 @@ import ( func TestGetName(t *testing.T) { for i := 0; i < 10; i++ { - shortName := randSeq(rand.Intn(util.DNS1123SubdomainMaxLength-1) + 1) - longName := randSeq(util.DNS1123SubdomainMaxLength + rand.Intn(100)) + shortName := randSeq(rand.Intn(kvalidation.DNS1123SubdomainMaxLength-1) + 1) + longName := randSeq(kvalidation.DNS1123SubdomainMaxLength + rand.Intn(100)) tests := []struct { base, suffix, expected string @@ -24,7 +24,7 @@ func TestGetName(t *testing.T) { { base: longName, suffix: "deploy", - expected: longName[:util.DNS1123SubdomainMaxLength-16] + "-" + hash(longName) + "-deploy", + expected: longName[:kvalidation.DNS1123SubdomainMaxLength-16] + "-" + hash(longName) + "-deploy", }, { base: shortName, @@ -49,12 +49,12 @@ func TestGetName(t *testing.T) { { base: longName, suffix: "", - expected: longName[:util.DNS1123SubdomainMaxLength-10] + "-" + hash(longName) + "-", + expected: longName[:kvalidation.DNS1123SubdomainMaxLength-10] + "-" + hash(longName) + "-", }, } for _, test := range tests { - result := GetName(test.base, test.suffix, util.DNS1123SubdomainMaxLength) + result := GetName(test.base, test.suffix, kvalidation.DNS1123SubdomainMaxLength) if result != test.expected { t.Errorf("Got unexpected result. Expected: %s Got: %s", test.expected, result) } @@ -64,14 +64,14 @@ func TestGetName(t *testing.T) { func TestGetNameIsDifferent(t *testing.T) { shortName := randSeq(32) - deployerName := GetName(shortName, "deploy", util.DNS1123SubdomainMaxLength) - builderName := GetName(shortName, "build", util.DNS1123SubdomainMaxLength) + deployerName := GetName(shortName, "deploy", kvalidation.DNS1123SubdomainMaxLength) + builderName := GetName(shortName, "build", kvalidation.DNS1123SubdomainMaxLength) if deployerName == builderName { t.Errorf("Expecting names to be different: %s\n", deployerName) } - longName := randSeq(util.DNS1123SubdomainMaxLength + 10) - deployerName = GetName(longName, "deploy", util.DNS1123SubdomainMaxLength) - builderName = GetName(longName, "build", util.DNS1123SubdomainMaxLength) + longName := randSeq(kvalidation.DNS1123SubdomainMaxLength + 10) + deployerName = GetName(longName, "deploy", kvalidation.DNS1123SubdomainMaxLength) + builderName = GetName(longName, "build", kvalidation.DNS1123SubdomainMaxLength) if deployerName == builderName { t.Errorf("Expecting names to be different: %s\n", deployerName) } diff --git a/pkg/util/rest/webhook.go b/pkg/util/rest/webhook.go index f6002e29c06e..f4abf9cae063 100644 --- a/pkg/util/rest/webhook.go +++ b/pkg/util/rest/webhook.go @@ -21,6 +21,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" ) @@ -68,11 +69,11 @@ func NewHTTPWebHook(handler http.Handler, allowGet bool) *WebHook { // New() responds with the status object. func (h *WebHook) New() runtime.Object { - return &api.Status{} + return &unversioned.Status{} } // Connect responds to connections with a ConnectHandler -func (h *WebHook) Connect(ctx api.Context, name string, options runtime.Object) (rest.ConnectHandler, error) { +func (h *WebHook) Connect(ctx api.Context, name string, options runtime.Object, r rest.Responder) (http.Handler, error) { return &WebHookHandler{ handler: h.h, ctx: ctx, @@ -103,7 +104,7 @@ type WebHookHandler struct { err error } -var _ rest.ConnectHandler = &WebHookHandler{} +var _ http.Handler = &WebHookHandler{} func (h *WebHookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.err = h.handler.ServeHTTP(w, r, h.ctx, h.name, h.options.Path) diff --git a/plugins/route/allocation/simple/plugin.go b/plugins/route/allocation/simple/plugin.go index e3358395f4ad..6fa275d7d5a4 100644 --- a/plugins/route/allocation/simple/plugin.go +++ b/plugins/route/allocation/simple/plugin.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/golang/glog" - "k8s.io/kubernetes/pkg/util" + kvalidation "k8s.io/kubernetes/pkg/util/validation" routeapi "github.com/openshift/origin/pkg/route/api" ) @@ -27,7 +27,7 @@ func NewSimpleAllocationPlugin(suffix string) (*SimpleAllocationPlugin, error) { glog.V(4).Infof("Route plugin initialized with suffix=%s", suffix) // Check that the DNS suffix is valid. - if !util.IsDNS1123Subdomain(suffix) { + if !kvalidation.IsDNS1123Subdomain(suffix) { return nil, fmt.Errorf("invalid DNS suffix: %s", suffix) } diff --git a/test/cmd/admin.sh b/test/cmd/admin.sh index 2373e2ecdc4d..194b736ca938 100755 --- a/test/cmd/admin.sh +++ b/test/cmd/admin.sh @@ -93,7 +93,7 @@ oadm policy reconcile-cluster-roles --additive-only --confirm [ "$(oc get clusterroles/basic-user -o json | grep custom-annotation)" ] [ "$(oc get clusterroles/basic-user -o json | grep groups)" ] oadm policy reconcile-cluster-roles --confirm -[ ! "$(oc get clusterroles/basic-user -o json | grep groups)" ] +[ ! "$(oc get clusterroles/basic-user -o yaml | grep -v "kubectl.kubernetes.io/last-applied-configuration" | grep groups)" ] # Ensure a removed binding gets re-added oc delete clusterrolebinding/cluster-status-binding @@ -113,10 +113,10 @@ oadm policy reconcile-cluster-role-bindings --confirm [ "$(oc get clusterrolebindings/basic-users -o json | grep custom-annotation)" ] [ "$(oc get clusterrolebindings/basic-users -o json | grep custom-user)" ] # Ensure a customized binding's roleref is corrected -[ ! "$(oc get clusterrolebindings/basic-users -o json | grep cluster-status)" ] +[ ! "$(oc get clusterrolebindings/basic-users -o json | grep -v "kubectl.kubernetes.io/last-applied-configuration" | grep cluster-status)" ] # Ensure --additive-only=false removes customized users from the binding oadm policy reconcile-cluster-role-bindings --additive-only=false --confirm -[ ! "$(oc get clusterrolebindings/basic-users -o json | grep custom-user)" ] +[ ! "$(oc get clusterrolebindings/basic-users -o json | grep -v "kubectl.kubernetes.io/last-applied-configuration" | grep custom-user)" ] echo "admin-policy: ok" diff --git a/test/extended/util/framework.go b/test/extended/util/framework.go index 83e9c552048a..13ee8176474d 100644 --- a/test/extended/util/framework.go +++ b/test/extended/util/framework.go @@ -15,6 +15,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/unversioned" kclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -320,7 +321,7 @@ func GetDockerImageReference(c client.ImageStreamInterface, name, tag string) (s func GetPodForContainer(container kapi.Container) *kapi.Pod { name := namer.GetPodName("test-pod", string(kutil.NewUUID())) return &kapi.Pod{ - TypeMeta: kapi.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "Pod", APIVersion: "v1", }, @@ -338,7 +339,7 @@ func GetPodForContainer(container kapi.Container) *kapi.Pod { // CreatePersistentVolume creates a HostPath Persistent Volume. func CreatePersistentVolume(name, capacity, hostPath string) *kapi.PersistentVolume { return &kapi.PersistentVolume{ - TypeMeta: kapi.TypeMeta{ + TypeMeta: unversioned.TypeMeta{ Kind: "PersistentVolume", APIVersion: "v1", }, diff --git a/test/integration/buildclient_test.go b/test/integration/buildclient_test.go index 6b238c964898..3bf4bd69151a 100644 --- a/test/integration/buildclient_test.go +++ b/test/integration/buildclient_test.go @@ -192,7 +192,7 @@ func NewTestBuildOpenshift(t *testing.T) *testBuildOpenshift { osMux := http.NewServeMux() openshift.server = httptest.NewServer(osMux) - kubeClient := kclient.NewOrDie(&kclient.Config{Host: openshift.server.URL, Version: klatest.Version}) + kubeClient := kclient.NewOrDie(&kclient.Config{Host: openshift.server.URL, Version: klatest.DefaultVersionForLegacyGroup()}) osClient := osclient.NewOrDie(&kclient.Config{Host: openshift.server.URL, Version: latest.Version}) openshift.Client = osClient @@ -205,13 +205,16 @@ func NewTestBuildOpenshift(t *testing.T) *testBuildOpenshift { handlerContainer := master.NewHandlerContainer(osMux) + storageDestinations := master.NewStorageDestinations() + storageDestinations.AddAPIGroup("", etcdHelper) + _ = master.New(&master.Config{ - DatabaseStorage: etcdHelper, - KubeletClient: kubeletClient, - APIPrefix: "/api", - AdmissionControl: admit.NewAlwaysAdmit(), - RestfulContainer: handlerContainer, - DisableV1: false, + StorageDestinations: storageDestinations, + KubeletClient: kubeletClient, + APIPrefix: "/api", + AdmissionControl: admit.NewAlwaysAdmit(), + RestfulContainer: handlerContainer, + DisableV1: false, }) interfaces, _ := latest.InterfacesFor(latest.Version) diff --git a/test/integration/deploy_trigger_test.go b/test/integration/deploy_trigger_test.go index 4f2224883b72..b7b535944ca9 100644 --- a/test/integration/deploy_trigger_test.go +++ b/test/integration/deploy_trigger_test.go @@ -316,7 +316,7 @@ func NewTestDeployOpenshift(t *testing.T) *testDeployOpenshift { osMux := http.NewServeMux() openshift.server = httptest.NewServer(osMux) - kubeClient := kclient.NewOrDie(&kclient.Config{Host: openshift.server.URL, Version: klatest.Version}) + kubeClient := kclient.NewOrDie(&kclient.Config{Host: openshift.server.URL, Version: klatest.DefaultVersionForLegacyGroup()}) osClient := osclient.NewOrDie(&kclient.Config{Host: openshift.server.URL, Version: latest.Version}) openshift.Client = osClient @@ -329,13 +329,16 @@ func NewTestDeployOpenshift(t *testing.T) *testDeployOpenshift { handlerContainer := master.NewHandlerContainer(osMux) + storageDestinations := master.NewStorageDestinations() + storageDestinations.AddAPIGroup("", etcdHelper) + _ = master.New(&master.Config{ - DatabaseStorage: etcdHelper, - KubeletClient: kubeletClient, - APIPrefix: "/api", - AdmissionControl: admit.NewAlwaysAdmit(), - RestfulContainer: handlerContainer, - DisableV1: false, + StorageDestinations: storageDestinations, + KubeletClient: kubeletClient, + APIPrefix: "/api", + AdmissionControl: admit.NewAlwaysAdmit(), + RestfulContainer: handlerContainer, + DisableV1: false, }) interfaces, _ := latest.InterfacesFor(latest.Version) diff --git a/test/integration/router_test.go b/test/integration/router_test.go index 0a8dce57fd16..b1ce1e67cc55 100644 --- a/test/integration/router_test.go +++ b/test/integration/router_test.go @@ -20,6 +20,7 @@ import ( "golang.org/x/net/websocket" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/v1beta3" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/watch" @@ -431,7 +432,7 @@ func TestRouterPathSpecificity(t *testing.T) { t.Fatalf("Couldn't get http endpoint: %v", err) } - now := util.Now() + now := unversioned.Now() //create path based route endpointEvent := &watch.Event{ @@ -488,7 +489,7 @@ func TestRouterPathSpecificity(t *testing.T) { Type: watch.Added, Object: &routeapi.Route{ ObjectMeta: kapi.ObjectMeta{ - CreationTimestamp: util.Time{Time: now.Add(time.Hour)}, + CreationTimestamp: unversioned.Time{Time: now.Add(time.Hour)}, Name: "path", Namespace: "alt", }, @@ -572,7 +573,7 @@ func TestRouterPathSpecificity(t *testing.T) { Type: watch.Added, Object: &routeapi.Route{ ObjectMeta: kapi.ObjectMeta{ - CreationTimestamp: util.Time{Time: now.Add(time.Hour)}, + CreationTimestamp: unversioned.Time{Time: now.Add(time.Hour)}, Name: "host", Namespace: "alt", }, @@ -598,7 +599,7 @@ func TestRouterPathSpecificity(t *testing.T) { Type: watch.Added, Object: &routeapi.Route{ ObjectMeta: kapi.ObjectMeta{ - CreationTimestamp: util.Time{Time: now.Add(-time.Hour)}, + CreationTimestamp: unversioned.Time{Time: now.Add(-time.Hour)}, Name: "host", Namespace: "alt", }, diff --git a/test/integration/unprivileged_newproject_test.go b/test/integration/unprivileged_newproject_test.go index 51c25bfa5f35..7010a3e2d70f 100644 --- a/test/integration/unprivileged_newproject_test.go +++ b/test/integration/unprivileged_newproject_test.go @@ -9,6 +9,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kapierrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -59,8 +60,8 @@ func TestUnprivilegedNewProject(t *testing.T) { if err != nil { t.Fatalf("unexpected error: %v", err) } - if allowed.Status != kapi.StatusSuccess { - t.Fatalf("expected %v, got %v", kapi.StatusSuccess, allowed.Status) + if allowed.Status != unversioned.StatusSuccess { + t.Fatalf("expected %v, got %v", unversioned.StatusSuccess, allowed.Status) } requestProject := oc.NewProjectOptions{ diff --git a/test/util/helpers.go b/test/util/helpers.go index 53b88c956c9b..faad5200549c 100644 --- a/test/util/helpers.go +++ b/test/util/helpers.go @@ -18,7 +18,7 @@ func CreateSampleImageStream(namespace string) *imageapi.ImageStream { fmt.Printf("ERROR: Unable to read: %v", err) return nil } - latest.Codec.DecodeInto(jsonData, &stream) + latest.CodecForLegacyGroup().DecodeInto(jsonData, &stream) client, _ := GetClusterAdminClient(KubeConfigPath()) result, err := client.ImageStreams(namespace).Create(&stream) @@ -44,7 +44,7 @@ func GetBuildFixture(filename string) *buildapi.Build { fmt.Printf("ERROR: Unable to read %s: %v", filename, err) return nil } - latest.Codec.DecodeInto(jsonData, &build) + latest.CodecForLegacyGroup().DecodeInto(jsonData, &build) return &build } @@ -55,6 +55,6 @@ func GetSecretFixture(filename string) *kapi.Secret { fmt.Printf("ERROR: Unable to read %s: %v", filename, err) return nil } - latest.Codec.DecodeInto(jsonData, &secret) + latest.CodecForLegacyGroup().DecodeInto(jsonData, &secret) return &secret } From 88d4bc36ed747201468bd29949ce8bca84960a0d Mon Sep 17 00:00:00 2001 From: Maciej Szulik Date: Fri, 16 Oct 2015 11:23:24 +0200 Subject: [PATCH 34/35] help unit tests compile --- pkg/api/graph/graphview/veneering_test.go | 2 +- pkg/api/latest/tags_test.go | 2 +- pkg/auth/oauth/registry/registry_test.go | 2 +- .../authorizer/bootstrap_policy_test.go | 1 + .../role/policybased/virtual_storage_test.go | 1 + .../policybased/virtual_storage_test.go | 1 + pkg/build/api/sort_test.go | 2 +- pkg/build/controller/controller_test.go | 2 +- pkg/build/controller/factory/factory_test.go | 6 ++-- pkg/build/prune/data_test.go | 2 +- pkg/build/prune/prune_test.go | 2 +- pkg/build/prune/resolvers_test.go | 2 +- pkg/build/registry/build/strategy_test.go | 2 +- .../registry/buildconfig/webhook_test.go | 31 ++++++++++++++++-- pkg/client/testclient/fake_projectrequests.go | 2 +- pkg/cmd/cli/describe/describer_test.go | 10 +++--- pkg/cmd/cli/describe/helpers_test.go | 10 +++--- pkg/cmd/cli/describe/printer_test.go | 20 ++++++------ pkg/deploy/prune/data_test.go | 2 +- pkg/deploy/prune/prune_test.go | 2 +- pkg/deploy/prune/resolvers_test.go | 2 +- pkg/deploy/prune/sort_test.go | 2 +- pkg/generate/app/cmd/newapp_test.go | 1 + pkg/image/api/helper_test.go | 3 +- pkg/image/api/sort_test.go | 8 ++--- pkg/image/prune/imagepruner_test.go | 2 +- pkg/image/registry/image/etcd/etcd_test.go | 10 +++--- .../registry/imagestream/etcd/etcd_test.go | 1 + .../registry/imagestreamtag/rest_test.go | 6 ++-- pkg/project/controller/controller_test.go | 2 +- .../registry/project/proxy/proxy_test.go | 1 + pkg/security/admission/admission_test.go | 16 ++++++---- pkg/util/namer/namer_test.go | 2 +- pkg/util/rest/webhook.go | 32 +++++++++---------- .../route/allocation/simple/plugin_test.go | 6 ++-- plugins/router/template/plugin_test.go | 8 ++--- 36 files changed, 122 insertions(+), 84 deletions(-) diff --git a/pkg/api/graph/graphview/veneering_test.go b/pkg/api/graph/graphview/veneering_test.go index 0d9f5e76267d..fbc9ff3e5455 100644 --- a/pkg/api/graph/graphview/veneering_test.go +++ b/pkg/api/graph/graphview/veneering_test.go @@ -8,7 +8,7 @@ import ( "github.com/gonum/graph/concrete" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" osgraph "github.com/openshift/origin/pkg/api/graph" osgraphtest "github.com/openshift/origin/pkg/api/graph/test" diff --git a/pkg/api/latest/tags_test.go b/pkg/api/latest/tags_test.go index b3a556e090b1..4cdc2beddabc 100644 --- a/pkg/api/latest/tags_test.go +++ b/pkg/api/latest/tags_test.go @@ -7,8 +7,8 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" ) diff --git a/pkg/auth/oauth/registry/registry_test.go b/pkg/auth/oauth/registry/registry_test.go index 76f62a6e0071..b1bf7bea5b0a 100644 --- a/pkg/auth/oauth/registry/registry_test.go +++ b/pkg/auth/oauth/registry/registry_test.go @@ -10,7 +10,7 @@ import ( "github.com/RangelReale/osincli" kapi "k8s.io/kubernetes/pkg/api" apierrs "k8s.io/kubernetes/pkg/api/errors" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" "github.com/openshift/origin/pkg/auth/api" "github.com/openshift/origin/pkg/auth/oauth/handlers" diff --git a/pkg/authorization/authorizer/bootstrap_policy_test.go b/pkg/authorization/authorizer/bootstrap_policy_test.go index 569f29c14e48..2e2e07388139 100644 --- a/pkg/authorization/authorizer/bootstrap_policy_test.go +++ b/pkg/authorization/authorizer/bootstrap_policy_test.go @@ -4,6 +4,7 @@ import ( "testing" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/auth/user" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" diff --git a/pkg/authorization/registry/role/policybased/virtual_storage_test.go b/pkg/authorization/registry/role/policybased/virtual_storage_test.go index c2c7e543e579..09c35a010729 100644 --- a/pkg/authorization/registry/role/policybased/virtual_storage_test.go +++ b/pkg/authorization/registry/role/policybased/virtual_storage_test.go @@ -6,6 +6,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kapierrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/sets" authorizationapi "github.com/openshift/origin/pkg/authorization/api" diff --git a/pkg/authorization/registry/rolebinding/policybased/virtual_storage_test.go b/pkg/authorization/registry/rolebinding/policybased/virtual_storage_test.go index 702f898b1deb..3d4dc4098166 100644 --- a/pkg/authorization/registry/rolebinding/policybased/virtual_storage_test.go +++ b/pkg/authorization/registry/rolebinding/policybased/virtual_storage_test.go @@ -8,6 +8,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kapierrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/auth/user" "k8s.io/kubernetes/pkg/util/sets" diff --git a/pkg/build/api/sort_test.go b/pkg/build/api/sort_test.go index 060d81894f54..1cea162e3bf3 100644 --- a/pkg/build/api/sort_test.go +++ b/pkg/build/api/sort_test.go @@ -6,7 +6,7 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) func TestSortBuildSliceByCreationTimestamp(t *testing.T) { diff --git a/pkg/build/controller/controller_test.go b/pkg/build/controller/controller_test.go index 67124b184de8..3dbc79d23703 100644 --- a/pkg/build/controller/controller_test.go +++ b/pkg/build/controller/controller_test.go @@ -7,8 +7,8 @@ import ( kapi "k8s.io/kubernetes/pkg/api" kerrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/record" - "k8s.io/kubernetes/pkg/util" buildapi "github.com/openshift/origin/pkg/build/api" buildclient "github.com/openshift/origin/pkg/build/client" diff --git a/pkg/build/controller/factory/factory_test.go b/pkg/build/controller/factory/factory_test.go index cfbd7f90adcd..3a9bd7ae49bc 100644 --- a/pkg/build/controller/factory/factory_test.go +++ b/pkg/build/controller/factory/factory_test.go @@ -8,7 +8,7 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" - kutil "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" buildapi "github.com/openshift/origin/pkg/build/api" controller "github.com/openshift/origin/pkg/controller" @@ -30,7 +30,7 @@ func TestLimitedLogAndRetryFinish(t *testing.T) { now := unversioned.Now() retry := controller.Retry{ Count: 0, - StartTimestamp: kutil.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-31, now.Second(), now.Nanosecond(), now.Location()), + StartTimestamp: unversioned.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-31, now.Second(), now.Nanosecond(), now.Location()), } if limitedLogAndRetry(updater, 30*time.Minute)(&buildapi.Build{Status: buildapi.BuildStatus{Phase: buildapi.BuildPhaseNew}}, err, retry) { t.Error("Expected no more retries after reaching timeout!") @@ -56,7 +56,7 @@ func TestLimitedLogAndRetryProcessing(t *testing.T) { now := unversioned.Now() retry := controller.Retry{ Count: 0, - StartTimestamp: kutil.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-10, now.Second(), now.Nanosecond(), now.Location()), + StartTimestamp: unversioned.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-10, now.Second(), now.Nanosecond(), now.Location()), } if !limitedLogAndRetry(updater, 30*time.Minute)(&buildapi.Build{Status: buildapi.BuildStatus{Phase: buildapi.BuildPhaseNew}}, err, retry) { t.Error("Expected more retries!") diff --git a/pkg/build/prune/data_test.go b/pkg/build/prune/data_test.go index 94caa39a463e..3d209f152e83 100644 --- a/pkg/build/prune/data_test.go +++ b/pkg/build/prune/data_test.go @@ -6,7 +6,7 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/sets" buildapi "github.com/openshift/origin/pkg/build/api" diff --git a/pkg/build/prune/prune_test.go b/pkg/build/prune/prune_test.go index 2a63f02b7701..901e59659bb2 100644 --- a/pkg/build/prune/prune_test.go +++ b/pkg/build/prune/prune_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/sets" buildapi "github.com/openshift/origin/pkg/build/api" diff --git a/pkg/build/prune/resolvers_test.go b/pkg/build/prune/resolvers_test.go index ccd55866f5c6..3ceaaa7a8044 100644 --- a/pkg/build/prune/resolvers_test.go +++ b/pkg/build/prune/resolvers_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/sets" buildapi "github.com/openshift/origin/pkg/build/api" diff --git a/pkg/build/registry/build/strategy_test.go b/pkg/build/registry/build/strategy_test.go index ab965e24d2b0..9d3f5f5ff992 100644 --- a/pkg/build/registry/build/strategy_test.go +++ b/pkg/build/registry/build/strategy_test.go @@ -5,7 +5,7 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" buildapi "github.com/openshift/origin/pkg/build/api" ) diff --git a/pkg/build/registry/buildconfig/webhook_test.go b/pkg/build/registry/buildconfig/webhook_test.go index 83f7a72258d9..3f51beb98d26 100644 --- a/pkg/build/registry/buildconfig/webhook_test.go +++ b/pkg/build/registry/buildconfig/webhook_test.go @@ -9,6 +9,8 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/runtime" "github.com/openshift/origin/pkg/build/api" "github.com/openshift/origin/pkg/build/registry/test" @@ -56,6 +58,30 @@ func TestNewWebHook(t *testing.T) { } } +type fakeResponder struct { + called bool + statusCode int + object runtime.Object + err error +} + +func (r *fakeResponder) Object(statusCode int, obj runtime.Object) { + if r.called { + panic("called twice") + } + r.called = true + r.statusCode = statusCode + r.object = obj +} + +func (r *fakeResponder) Error(err error) { + if r.called { + panic("called twice") + } + r.called = true + r.err = err +} + func TestConnectWebHook(t *testing.T) { testCases := map[string]struct { Name string @@ -106,14 +132,15 @@ func TestConnectWebHook(t *testing.T) { if testCase.RegErr != nil { registry.Err = testCase.RegErr } - handler, err := hook.Connect(kapi.NewDefaultContext(), testCase.Name, &kapi.PodProxyOptions{Path: testCase.Path}) + responder := &fakeResponder{} + handler, err := hook.Connect(kapi.NewDefaultContext(), testCase.Name, &kapi.PodProxyOptions{Path: testCase.Path}, responder) if err != nil { t.Errorf("%s: %v", k, err) continue } w := httptest.NewRecorder() handler.ServeHTTP(w, &http.Request{}) - if err := handler.RequestError(); !testCase.ErrFn(err) { + if err := responder.err; !testCase.ErrFn(err) { t.Errorf("%s: unexpected error: %v", k, err) continue } diff --git a/pkg/client/testclient/fake_projectrequests.go b/pkg/client/testclient/fake_projectrequests.go index ee349f2eae37..d44105ba5723 100644 --- a/pkg/client/testclient/fake_projectrequests.go +++ b/pkg/client/testclient/fake_projectrequests.go @@ -1,7 +1,7 @@ package testclient import ( - kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" ktestclient "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" diff --git a/pkg/cmd/cli/describe/describer_test.go b/pkg/cmd/cli/describe/describer_test.go index 51f9d284608f..e9e4c84b7c4f 100644 --- a/pkg/cmd/cli/describe/describer_test.go +++ b/pkg/cmd/cli/describe/describer_test.go @@ -7,10 +7,10 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" ktestclient "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/labels" - kutil "k8s.io/kubernetes/pkg/util" authorizationapi "github.com/openshift/origin/pkg/authorization/api" buildapi "github.com/openshift/origin/pkg/build/api" @@ -215,11 +215,11 @@ func TestDescribeBuildDuration(t *testing.T) { output string } - creation := kutil.Date(2015, time.April, 9, 6, 0, 0, 0, time.Local) + creation := unversioned.Date(2015, time.April, 9, 6, 0, 0, 0, time.Local) // now a minute ago - minuteAgo := kutil.Unix(unversioned.Now().Rfc3339Copy().Time.Unix()-60, 0) - start := kutil.Date(2015, time.April, 9, 6, 1, 0, 0, time.Local) - completion := kutil.Date(2015, time.April, 9, 6, 2, 0, 0, time.Local) + minuteAgo := unversioned.Unix(unversioned.Now().Rfc3339Copy().Time.Unix()-60, 0) + start := unversioned.Date(2015, time.April, 9, 6, 1, 0, 0, time.Local) + completion := unversioned.Date(2015, time.April, 9, 6, 2, 0, 0, time.Local) duration := completion.Rfc3339Copy().Time.Sub(start.Rfc3339Copy().Time) zeroDuration := time.Duration(0) diff --git a/pkg/cmd/cli/describe/helpers_test.go b/pkg/cmd/cli/describe/helpers_test.go index f561301872be..b9105b84bc82 100644 --- a/pkg/cmd/cli/describe/helpers_test.go +++ b/pkg/cmd/cli/describe/helpers_test.go @@ -8,7 +8,7 @@ import ( imageapi "github.com/openshift/origin/pkg/image/api" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) func TestFormatImageStreamTags(t *testing.T) { @@ -36,12 +36,12 @@ func TestFormatImageStreamTags(t *testing.T) { imageapi.DefaultImageTag: { Items: []imageapi.TagEvent{ { - Created: util.Date(2015, 3, 24, 9, 38, 0, 0, time.UTC), + Created: unversioned.Date(2015, 3, 24, 9, 38, 0, 0, time.UTC), DockerImageReference: "registry:5000/foo/bar@sha256:4bd26aef1ce78b4f05ede83496276f11e3343441574ca1ce89dffd146c708c16", Image: "sha256:4bd26aef1ce78b4f05ede83496276f11e3343441574ca1ce89dffd146c708c16", }, { - Created: util.Date(2015, 3, 23, 7, 15, 0, 0, time.UTC), + Created: unversioned.Date(2015, 3, 23, 7, 15, 0, 0, time.UTC), DockerImageReference: "registry:5000/foo/bar@sha256:062b80555a5dd7f5d58e78b266785a399277ff8c3e402ce5fa5d8571788e6bad", Image: "sha256:062b80555a5dd7f5d58e78b266785a399277ff8c3e402ce5fa5d8571788e6bad", }, @@ -50,7 +50,7 @@ func TestFormatImageStreamTags(t *testing.T) { "spec1": { Items: []imageapi.TagEvent{ { - Created: util.Date(2015, 3, 24, 9, 38, 0, 0, time.UTC), + Created: unversioned.Date(2015, 3, 24, 9, 38, 0, 0, time.UTC), DockerImageReference: "registry:5000/foo/bar@sha256:4bd26aef1ce78b4f05ede83496276f11e3343441574ca1ce89dffd146c708c16", Image: "sha256:4bd26aef1ce78b4f05ede83496276f11e3343441574ca1ce89dffd146c708c16", }, @@ -59,7 +59,7 @@ func TestFormatImageStreamTags(t *testing.T) { "spec2": { Items: []imageapi.TagEvent{ { - Created: util.Date(2015, 3, 24, 9, 38, 0, 0, time.UTC), + Created: unversioned.Date(2015, 3, 24, 9, 38, 0, 0, time.UTC), DockerImageReference: "mysql:latest", Image: "sha256:e52c6534db85036dabac5e71ff14e720db94def2d90f986f3548425ea27b3719", }, diff --git a/pkg/cmd/cli/describe/printer_test.go b/pkg/cmd/cli/describe/printer_test.go index 67462de3a082..4a76c066da22 100644 --- a/pkg/cmd/cli/describe/printer_test.go +++ b/pkg/cmd/cli/describe/printer_test.go @@ -9,8 +9,8 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" - kutil "k8s.io/kubernetes/pkg/util" authorizationapi "github.com/openshift/origin/pkg/authorization/api" buildapi "github.com/openshift/origin/pkg/build/api" @@ -130,7 +130,7 @@ func mockStreams() []*imageapi.ImageStream { Items: []imageapi.TagEvent{ { DockerImageReference: "other-ref", - Created: kutil.Date(2015, 9, 4, 13, 52, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 52, 0, 0, time.UTC), Image: "other-image", }, }, @@ -139,7 +139,7 @@ func mockStreams() []*imageapi.ImageStream { Items: []imageapi.TagEvent{ { DockerImageReference: "latest-ref", - Created: kutil.Date(2015, 9, 4, 13, 53, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 53, 0, 0, time.UTC), Image: "latest-image", }, }, @@ -155,7 +155,7 @@ func mockStreams() []*imageapi.ImageStream { Items: []imageapi.TagEvent{ { DockerImageReference: "other-ref", - Created: kutil.Date(2015, 9, 4, 13, 52, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 52, 0, 0, time.UTC), Image: "other-image", }, }, @@ -164,7 +164,7 @@ func mockStreams() []*imageapi.ImageStream { Items: []imageapi.TagEvent{ { DockerImageReference: "latest-ref", - Created: kutil.Date(2015, 9, 4, 13, 53, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 53, 0, 0, time.UTC), Image: "latest-image", }, }, @@ -173,7 +173,7 @@ func mockStreams() []*imageapi.ImageStream { Items: []imageapi.TagEvent{ { DockerImageReference: "third-ref", - Created: kutil.Date(2015, 9, 4, 13, 54, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 54, 0, 0, time.UTC), Image: "third-image", }, }, @@ -189,7 +189,7 @@ func mockStreams() []*imageapi.ImageStream { Items: []imageapi.TagEvent{ { DockerImageReference: "other-ref", - Created: kutil.Date(2015, 9, 4, 13, 52, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 52, 0, 0, time.UTC), Image: "other-image", }, }, @@ -198,7 +198,7 @@ func mockStreams() []*imageapi.ImageStream { Items: []imageapi.TagEvent{ { DockerImageReference: "latest-ref", - Created: kutil.Date(2015, 9, 4, 13, 53, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 53, 0, 0, time.UTC), Image: "latest-image", }, }, @@ -207,7 +207,7 @@ func mockStreams() []*imageapi.ImageStream { Items: []imageapi.TagEvent{ { DockerImageReference: "third-ref", - Created: kutil.Date(2015, 9, 4, 13, 54, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 54, 0, 0, time.UTC), Image: "third-image", }, }, @@ -216,7 +216,7 @@ func mockStreams() []*imageapi.ImageStream { Items: []imageapi.TagEvent{ { DockerImageReference: "another-ref", - Created: kutil.Date(2015, 9, 4, 13, 55, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 55, 0, 0, time.UTC), Image: "another-image", }, }, diff --git a/pkg/deploy/prune/data_test.go b/pkg/deploy/prune/data_test.go index 2ef4b28d431a..3062d5a03887 100644 --- a/pkg/deploy/prune/data_test.go +++ b/pkg/deploy/prune/data_test.go @@ -6,7 +6,7 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/sets" deployapi "github.com/openshift/origin/pkg/deploy/api" diff --git a/pkg/deploy/prune/prune_test.go b/pkg/deploy/prune/prune_test.go index c9db7c19c793..8f9379db5d7a 100644 --- a/pkg/deploy/prune/prune_test.go +++ b/pkg/deploy/prune/prune_test.go @@ -6,7 +6,7 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/sets" deployapi "github.com/openshift/origin/pkg/deploy/api" diff --git a/pkg/deploy/prune/resolvers_test.go b/pkg/deploy/prune/resolvers_test.go index a02ba2bd8743..2d090e18080e 100644 --- a/pkg/deploy/prune/resolvers_test.go +++ b/pkg/deploy/prune/resolvers_test.go @@ -7,7 +7,7 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/sets" deployapi "github.com/openshift/origin/pkg/deploy/api" diff --git a/pkg/deploy/prune/sort_test.go b/pkg/deploy/prune/sort_test.go index 38a8c8d50459..3da4050e2981 100644 --- a/pkg/deploy/prune/sort_test.go +++ b/pkg/deploy/prune/sort_test.go @@ -6,7 +6,7 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" ) // TestSort verifies that builds are sorted by most recently created diff --git a/pkg/generate/app/cmd/newapp_test.go b/pkg/generate/app/cmd/newapp_test.go index 8dca85889c8b..c25818598875 100644 --- a/pkg/generate/app/cmd/newapp_test.go +++ b/pkg/generate/app/cmd/newapp_test.go @@ -18,6 +18,7 @@ import ( "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" + kvalidation "k8s.io/kubernetes/pkg/util/validation" buildapi "github.com/openshift/origin/pkg/build/api" client "github.com/openshift/origin/pkg/client/testclient" diff --git a/pkg/image/api/helper_test.go b/pkg/image/api/helper_test.go index c7ea24e7e567..94ac0237dda4 100644 --- a/pkg/image/api/helper_test.go +++ b/pkg/image/api/helper_test.go @@ -7,6 +7,7 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util" ) @@ -431,7 +432,7 @@ func TestImageWithMetadata(t *testing.T) { ID: "2d24f826cb16146e2016ff349a8a33ed5830f3b938d45c0f82943f4ab8c097e7", Parent: "117ee323aaa9d1b136ea55e4421f4ce413dfc6c0cc6b2186dea6c88d93e1ad7c", Comment: "", - Created: util.Date(2015, 2, 21, 2, 11, 6, 735146646, time.UTC), + Created: unversioned.Date(2015, 2, 21, 2, 11, 6, 735146646, time.UTC), Container: "c9a3eda5951d28aa8dbe5933be94c523790721e4f80886d0a8e7a710132a38ec", ContainerConfig: DockerConfig{ Hostname: "43bd710ec89a", diff --git a/pkg/image/api/sort_test.go b/pkg/image/api/sort_test.go index f2a09f17e35e..370301187090 100644 --- a/pkg/image/api/sort_test.go +++ b/pkg/image/api/sort_test.go @@ -1,7 +1,7 @@ package api import ( - kutil "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" "reflect" "testing" @@ -21,7 +21,7 @@ func TestSortStatusTags(t *testing.T) { Items: []TagEvent{ { DockerImageReference: "other-ref", - Created: kutil.Date(2015, 9, 4, 13, 52, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 52, 0, 0, time.UTC), Image: "other-image", }, }, @@ -30,7 +30,7 @@ func TestSortStatusTags(t *testing.T) { Items: []TagEvent{ { DockerImageReference: "latest-ref", - Created: kutil.Date(2015, 9, 4, 13, 53, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 53, 0, 0, time.UTC), Image: "latest-image", }, }, @@ -39,7 +39,7 @@ func TestSortStatusTags(t *testing.T) { Items: []TagEvent{ { DockerImageReference: "third-ref", - Created: kutil.Date(2015, 9, 4, 13, 54, 0, 0, time.UTC), + Created: unversioned.Date(2015, 9, 4, 13, 54, 0, 0, time.UTC), Image: "third-image", }, }, diff --git a/pkg/image/prune/imagepruner_test.go b/pkg/image/prune/imagepruner_test.go index 0695a93f68d6..e31a78502ff4 100644 --- a/pkg/image/prune/imagepruner_test.go +++ b/pkg/image/prune/imagepruner_test.go @@ -11,9 +11,9 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" ktc "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" buildapi "github.com/openshift/origin/pkg/build/api" diff --git a/pkg/image/registry/image/etcd/etcd_test.go b/pkg/image/registry/image/etcd/etcd_test.go index 305a944c1b3b..719d22e2b6d6 100644 --- a/pkg/image/registry/image/etcd/etcd_test.go +++ b/pkg/image/registry/image/etcd/etcd_test.go @@ -6,13 +6,10 @@ import ( "testing" "time" - "github.com/coreos/go-etcd/etcd" - "github.com/openshift/origin/pkg/api/latest" - "github.com/openshift/origin/pkg/image/api" - "github.com/openshift/origin/pkg/image/registry/image" kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/registrytest" @@ -23,6 +20,11 @@ import ( "k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/watch" + + "github.com/coreos/go-etcd/etcd" + "github.com/openshift/origin/pkg/api/latest" + "github.com/openshift/origin/pkg/image/api" + "github.com/openshift/origin/pkg/image/registry/image" ) // This copy and paste is not pure ignorance. This is that we can be sure that the key is getting made as we diff --git a/pkg/image/registry/imagestream/etcd/etcd_test.go b/pkg/image/registry/imagestream/etcd/etcd_test.go index c635722048ba..fde662f33756 100644 --- a/pkg/image/registry/imagestream/etcd/etcd_test.go +++ b/pkg/image/registry/imagestream/etcd/etcd_test.go @@ -13,6 +13,7 @@ import ( "github.com/openshift/origin/pkg/image/registry/imagestream" kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/auth/user" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" diff --git a/pkg/image/registry/imagestreamtag/rest_test.go b/pkg/image/registry/imagestreamtag/rest_test.go index 73a0bd8fd0bf..ec61f8271999 100644 --- a/pkg/image/registry/imagestreamtag/rest_test.go +++ b/pkg/image/registry/imagestreamtag/rest_test.go @@ -8,13 +8,13 @@ import ( "github.com/coreos/go-etcd/etcd" kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/auth/user" "k8s.io/kubernetes/pkg/runtime" kstorage "k8s.io/kubernetes/pkg/storage" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" "k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools/etcdtest" - "k8s.io/kubernetes/pkg/util" "github.com/openshift/origin/pkg/api/latest" authorizationapi "github.com/openshift/origin/pkg/authorization/api" @@ -153,7 +153,7 @@ func TestGetImageStreamTag(t *testing.T) { "latest": { Items: []api.TagEvent{ { - Created: util.Date(2015, 3, 24, 9, 38, 0, 0, time.UTC), + Created: unversioned.Date(2015, 3, 24, 9, 38, 0, 0, time.UTC), DockerImageReference: "test", Image: "10", }, @@ -264,7 +264,7 @@ func TestGetImageStreamTag(t *testing.T) { if e, a := map[string]string{"size": "large", "color": "blue"}, actual.Image.Annotations; !reflect.DeepEqual(e, a) { t.Errorf("%s: annotations: expected %v, got %v", name, e, a) } - if e, a := util.Date(2015, 3, 24, 9, 38, 0, 0, time.UTC), actual.CreationTimestamp; !a.Equal(e) { + if e, a := unversioned.Date(2015, 3, 24, 9, 38, 0, 0, time.UTC), actual.CreationTimestamp; !a.Equal(e) { t.Errorf("%s: timestamp: expected %v, got %v", name, e, a) } } diff --git a/pkg/project/controller/controller_test.go b/pkg/project/controller/controller_test.go index 50d279176fb2..f4e4cffa3ed4 100644 --- a/pkg/project/controller/controller_test.go +++ b/pkg/project/controller/controller_test.go @@ -6,8 +6,8 @@ import ( "github.com/openshift/origin/pkg/client/testclient" "github.com/openshift/origin/pkg/project/api" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" ktestclient "k8s.io/kubernetes/pkg/client/unversioned/testclient" - "k8s.io/kubernetes/pkg/util" ) func TestSyncNamespaceThatIsTerminating(t *testing.T) { diff --git a/pkg/project/registry/project/proxy/proxy_test.go b/pkg/project/registry/project/proxy/proxy_test.go index c55f992ed6ea..c25b591a7437 100644 --- a/pkg/project/registry/project/proxy/proxy_test.go +++ b/pkg/project/registry/project/proxy/proxy_test.go @@ -7,6 +7,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/auth/user" "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/fields" diff --git a/pkg/security/admission/admission_test.go b/pkg/security/admission/admission_test.go index 01b2b3f83ff6..2232327f3006 100644 --- a/pkg/security/admission/admission_test.go +++ b/pkg/security/admission/admission_test.go @@ -91,6 +91,7 @@ func TestAdmit(t *testing.T) { return &kapi.Pod{ Spec: kapi.PodSpec{ ServiceAccountName: "default", + SecurityContext: &kapi.PodSecurityContext{}, Containers: []kapi.Container{ { SecurityContext: &kapi.SecurityContext{}, @@ -125,13 +126,13 @@ func TestAdmit(t *testing.T) { } requestsHostNetwork := goodPod() - requestsHostNetwork.Spec.HostNetwork = true + requestsHostNetwork.Spec.SecurityContext.HostNetwork = true requestsHostPID := goodPod() - requestsHostPID.Spec.HostPID = true + requestsHostPID.Spec.SecurityContext.HostPID = true requestsHostIPC := goodPod() - requestsHostIPC.Spec.HostIPC = true + requestsHostIPC.Spec.SecurityContext.HostIPC = true requestsHostPorts := goodPod() requestsHostPorts.Spec.Containers[0].Ports = []kapi.ContainerPort{{HostPort: 1}} @@ -293,7 +294,8 @@ func TestAssignSecurityContext(t *testing.T) { "container SC is not changed when invalid": { pod: &kapi.Pod{ Spec: kapi.PodSpec{ - Containers: []kapi.Container{createContainer(true)}, + SecurityContext: &kapi.PodSecurityContext{}, + Containers: []kapi.Container{createContainer(true)}, }, }, shouldValidate: false, @@ -302,7 +304,8 @@ func TestAssignSecurityContext(t *testing.T) { pod: &kapi.Pod{ Spec: kapi.PodSpec{ // good pod and bad pod - Containers: []kapi.Container{createContainer(false), createContainer(true)}, + SecurityContext: &kapi.PodSecurityContext{}, + Containers: []kapi.Container{createContainer(false), createContainer(true)}, }, }, shouldValidate: false, @@ -310,7 +313,8 @@ func TestAssignSecurityContext(t *testing.T) { "pod validates": { pod: &kapi.Pod{ Spec: kapi.PodSpec{ - Containers: []kapi.Container{createContainer(false)}, + SecurityContext: &kapi.PodSecurityContext{}, + Containers: []kapi.Container{createContainer(false)}, }, }, shouldValidate: true, diff --git a/pkg/util/namer/namer_test.go b/pkg/util/namer/namer_test.go index 0c318cf046b1..393ef21f10ca 100644 --- a/pkg/util/namer/namer_test.go +++ b/pkg/util/namer/namer_test.go @@ -4,7 +4,7 @@ import ( "math/rand" "testing" - "k8s.io/kubernetes/pkg/util" + kvalidation "k8s.io/kubernetes/pkg/util/validation" ) func TestGetName(t *testing.T) { diff --git a/pkg/util/rest/webhook.go b/pkg/util/rest/webhook.go index f4abf9cae063..e9216ccd35b1 100644 --- a/pkg/util/rest/webhook.go +++ b/pkg/util/rest/webhook.go @@ -73,12 +73,13 @@ func (h *WebHook) New() runtime.Object { } // Connect responds to connections with a ConnectHandler -func (h *WebHook) Connect(ctx api.Context, name string, options runtime.Object, r rest.Responder) (http.Handler, error) { +func (h *WebHook) Connect(ctx api.Context, name string, options runtime.Object, responder rest.Responder) (http.Handler, error) { return &WebHookHandler{ - handler: h.h, - ctx: ctx, - name: name, - options: options.(*api.PodProxyOptions), + handler: h.h, + ctx: ctx, + name: name, + options: options.(*api.PodProxyOptions), + responder: responder, }, nil } @@ -97,22 +98,19 @@ func (h *WebHook) ConnectMethods() []string { // WebHookHandler responds to web hook requests from the master. type WebHookHandler struct { - handler HookHandler - ctx api.Context - name string - options *api.PodProxyOptions - err error + handler HookHandler + ctx api.Context + name string + options *api.PodProxyOptions + responder rest.Responder } var _ http.Handler = &WebHookHandler{} func (h *WebHookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - h.err = h.handler.ServeHTTP(w, r, h.ctx, h.name, h.options.Path) - if h.err == nil { - w.WriteHeader(http.StatusOK) + if err := h.handler.ServeHTTP(w, r, h.ctx, h.name, h.options.Path); err != nil { + h.responder.Error(err) + return } -} - -func (h *WebHookHandler) RequestError() error { - return h.err + w.WriteHeader(http.StatusOK) } diff --git a/plugins/route/allocation/simple/plugin_test.go b/plugins/route/allocation/simple/plugin_test.go index 04af1ab1d624..8ba7ec6ea542 100644 --- a/plugins/route/allocation/simple/plugin_test.go +++ b/plugins/route/allocation/simple/plugin_test.go @@ -4,7 +4,7 @@ import ( "testing" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/validation" "github.com/openshift/origin/pkg/route/api" rac "github.com/openshift/origin/pkg/route/controller/allocation" @@ -150,7 +150,7 @@ func TestSimpleAllocationPlugin(t *testing.T) { case tc.empty: continue } - if !util.IsDNS1123Subdomain(name) { + if !validation.IsDNS1123Subdomain(name) { t.Errorf("Test case %s got %s - invalid DNS name.", tc.name, name) } } @@ -244,7 +244,7 @@ func TestSimpleAllocationPluginViaController(t *testing.T) { case tc.empty: continue } - if !util.IsDNS1123Subdomain(name) { + if !validation.IsDNS1123Subdomain(name) { t.Errorf("Test case %s got %s - invalid DNS name.", tc.name, name) } } diff --git a/plugins/router/template/plugin_test.go b/plugins/router/template/plugin_test.go index f7aac9156278..0cd1b36b2e02 100644 --- a/plugins/router/template/plugin_test.go +++ b/plugins/router/template/plugin_test.go @@ -8,7 +8,7 @@ import ( "time" kapi "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/watch" @@ -351,7 +351,7 @@ func TestHandleRoute(t *testing.T) { // here plugin := controller.NewUniqueHost(templatePlugin, controller.HostForRoute) - original := util.Time{Time: time.Now()} + original := unversioned.Time{Time: time.Now()} //add route := &routeapi.Route{ @@ -394,7 +394,7 @@ func TestHandleRoute(t *testing.T) { // attempt to add a second route with a newer time, verify it is ignored duplicateRoute := &routeapi.Route{ ObjectMeta: kapi.ObjectMeta{ - CreationTimestamp: util.Time{Time: original.Add(time.Hour)}, + CreationTimestamp: unversioned.Time{Time: original.Add(time.Hour)}, Namespace: "foo", Name: "dupe", }, @@ -430,7 +430,7 @@ func TestHandleRoute(t *testing.T) { } // add a second route with an older time, verify it takes effect - duplicateRoute.CreationTimestamp = util.Time{Time: original.Add(-time.Hour)} + duplicateRoute.CreationTimestamp = unversioned.Time{Time: original.Add(-time.Hour)} if err := plugin.HandleRoute(watch.Added, duplicateRoute); err != nil { t.Fatal("unexpected error") } From 1eb472bbcf14650834567decae869020b076b1ed Mon Sep 17 00:00:00 2001 From: Dan Mace Date: Tue, 6 Oct 2015 11:30:46 -0400 Subject: [PATCH 35/35] Disable v1beta3 in REST API --- assets/app/config.js | 5 +- assets/app/scripts/services/data.js | 14 +++- assets/test/spec/services/dataServiceSpec.js | 8 +- hack/test-cmd.sh | 6 +- hack/util.sh | 2 +- pkg/assets/bindata.go | 10 ++- pkg/assets/handlers.go | 7 +- pkg/client/client.go | 8 +- pkg/cmd/cli/cmd/loginoptions.go | 2 +- pkg/cmd/server/api/types.go | 25 +++++- pkg/cmd/server/api/v1/conversions.go | 2 +- pkg/cmd/server/api/validation/master.go | 32 +++++-- pkg/cmd/server/api/validation/master_test.go | 83 +++++++++++++++++++ pkg/cmd/server/kubernetes/master.go | 5 +- pkg/cmd/server/origin/asset.go | 11 ++- pkg/cmd/server/origin/handlers.go | 3 - pkg/cmd/server/origin/master.go | 16 +--- pkg/cmd/util/clientcmd/errors_test.go | 21 +++++ pkg/cmd/util/clientcmd/factory.go | 50 ++++++++--- pkg/cmd/util/clientcmd/factory_test.go | 71 ++++++++++++++++ test/cmd/basicresources.sh | 5 ++ test/cmd/builds.sh | 6 +- test/fixtures/mixed-api-versions.yaml | 41 +++++++++ test/integration/router/router_http_server.go | 2 - test/integration/template_test.go | 14 ++-- .../v1.0.0/test-end-to-end.sh | 2 +- 26 files changed, 366 insertions(+), 85 deletions(-) create mode 100644 pkg/cmd/util/clientcmd/errors_test.go create mode 100644 pkg/cmd/util/clientcmd/factory_test.go create mode 100644 test/fixtures/mixed-api-versions.yaml diff --git a/assets/app/config.js b/assets/app/config.js index fd0c45a53730..d964b623c009 100644 --- a/assets/app/config.js +++ b/assets/app/config.js @@ -6,8 +6,7 @@ window.OPENSHIFT_CONFIG = { openshift: { hostPort: "localhost:8443", prefixes: { - "v1beta3": "/osapi", - "*": "/oapi" + "v1": "/oapi" }, resources: { "buildconfigs": true, @@ -60,7 +59,7 @@ window.OPENSHIFT_CONFIG = { k8s: { hostPort: "localhost:8443", prefixes: { - "*": "/api" + "v1": "/api" }, resources: { "bindings": true, diff --git a/assets/app/scripts/services/data.js b/assets/app/scripts/services/data.js index b73ffae1e92c..6e6054bc05b3 100644 --- a/assets/app/scripts/services/data.js +++ b/assets/app/scripts/services/data.js @@ -262,9 +262,17 @@ angular.module('openshiftConsole') var resource = self.kindToResource(object.kind); if (!resource) { failureResults.push({ - data: { - message: "Unrecognized kind: " + object.kind + "." - } + data: {message: "Unrecognized kind " + object.kind} + }); + remaining--; + _checkDone(); + return; + } + + var resourceInfo = self.resourceInfo(resource, object.apiVersion); + if (!resourceInfo) { + failureResults.push({ + data: {message: "Unknown API version "+object.apiVersion+" for kind " + object.kind} }); remaining--; _checkDone(); diff --git a/assets/test/spec/services/dataServiceSpec.js b/assets/test/spec/services/dataServiceSpec.js index 945c385d2c76..44452b586c2d 100644 --- a/assets/test/spec/services/dataServiceSpec.js +++ b/assets/test/spec/services/dataServiceSpec.js @@ -61,13 +61,13 @@ describe("DataService", function(){ [{resource:'pods/proxy', name:"mypod", namespace:"myns", myparam1:"myvalue"}, "http://localhost:8443/api/v1/namespaces/myns/pods/mypod/proxy?myparam1=myvalue"], // Different API versions - [{resource:'builds',apiVersion:'v1beta3'}, "http://localhost:8443/osapi/v1beta3/builds"], + [{resource:'builds',apiVersion:'v1beta3'}, null], [{resource:'builds',apiVersion:'v1' }, "http://localhost:8443/oapi/v1/builds"], - [{resource:'builds',apiVersion:'unknown'}, "http://localhost:8443/oapi/unknown/builds"], + [{resource:'builds',apiVersion:'unknown'}, null], - [{resource:'pods', apiVersion:'v1beta3'}, "http://localhost:8443/api/v1beta3/pods"], + [{resource:'pods', apiVersion:'v1beta3'}, null], [{resource:'pods', apiVersion:'v1' }, "http://localhost:8443/api/v1/pods"], - [{resource:'pods', apiVersion:'unknown'}, "http://localhost:8443/api/unknown/pods"] + [{resource:'pods', apiVersion:'unknown'}, null] ]; angular.forEach(tc, function(item) { diff --git a/hack/test-cmd.sh b/hack/test-cmd.sh index bd3f85a1ec3a..200aa43eb4d4 100755 --- a/hack/test-cmd.sh +++ b/hack/test-cmd.sh @@ -135,7 +135,7 @@ openshift start \ # breaking the config fails the validation check cp ${MASTER_CONFIG_DIR}/master-config.yaml ${BASETMPDIR}/master-config-broken.yaml os::util::sed '5,10d' ${BASETMPDIR}/master-config-broken.yaml -[ "$(openshift ex validate master-config ${BASETMPDIR}/master-config-broken.yaml 2>&1 | grep error)" ] +[ "$(openshift ex validate master-config ${BASETMPDIR}/master-config-broken.yaml 2>&1 | grep ERROR)" ] cp ${NODE_CONFIG_DIR}/node-config.yaml ${BASETMPDIR}/node-config-broken.yaml os::util::sed '5,10d' ${BASETMPDIR}/node-config-broken.yaml @@ -205,8 +205,8 @@ fi # must only accept one arg (server) [ "$(oc login https://server1 https://server2.com 2>&1 | grep 'Only the server URL may be specified')" ] # logs in with a valid certificate authority -oc login ${KUBERNETES_MASTER} --certificate-authority="${MASTER_CONFIG_DIR}/ca.crt" -u test-user -p anything --api-version=v1beta3 -grep -q "v1beta3" ${HOME}/.kube/config +oc login ${KUBERNETES_MASTER} --certificate-authority="${MASTER_CONFIG_DIR}/ca.crt" -u test-user -p anything --api-version=v1 +grep -q "v1" ${HOME}/.kube/config oc logout # logs in skipping certificate check oc login ${KUBERNETES_MASTER} --insecure-skip-tls-verify -u test-user -p anything diff --git a/hack/util.sh b/hack/util.sh index fea943e780da..1c47abf34359 100644 --- a/hack/util.sh +++ b/hack/util.sh @@ -586,7 +586,7 @@ function os::build:wait_for_start() { function os::build:wait_for_end() { echo "[INFO] Waiting for $1 namespace build to complete" wait_for_command "oc get -n $1 builds | grep -i complete" $((10*TIME_MIN)) "oc get -n $1 builds | grep -i -e failed -e error" - BUILD_ID=`oc get -n $1 builds --output-version=v1beta3 --template="{{with index .items 0}}{{.metadata.name}}{{end}}"` + BUILD_ID=`oc get -n $1 builds --output-version=v1 --template="{{with index .items 0}}{{.metadata.name}}{{end}}"` echo "[INFO] Build ${BUILD_ID} finished" # TODO: fix set +e diff --git a/pkg/assets/bindata.go b/pkg/assets/bindata.go index 210ca763689b..ba504e9826a2 100644 --- a/pkg/assets/bindata.go +++ b/pkg/assets/bindata.go @@ -18816,13 +18816,19 @@ failure:h var f = d.defer(), g = [], h = [], i = this, j = a.length; return a.forEach(function(a) { var d = i.kindToResource(a.kind); -return d ? void i.create(d, null, a, b, c).then(function(a) { +if (!d) return h.push({ +data:{ +message:"Unrecognized kind " + a.kind +} +}), j--, void e(); +var f = i.resourceInfo(d, a.apiVersion); +return f ? void i.create(d, null, a, b, c).then(function(a) { g.push(a), j--, e(); }, function(a) { h.push(a), j--, e(); }) :(h.push({ data:{ -message:"Unrecognized kind: " + a.kind + "." +message:"Unknown API version " + a.apiVersion + " for kind " + a.kind } }), j--, void e()); }), f.promise; diff --git a/pkg/assets/handlers.go b/pkg/assets/handlers.go index df8e53751031..5fed7aabde18 100644 --- a/pkg/assets/handlers.go +++ b/pkg/assets/handlers.go @@ -147,8 +147,7 @@ window.OPENSHIFT_CONFIG = { openshift: { hostPort: "{{ .MasterAddr | js}}", prefixes: { - "v1beta3": "{{ .MasterLegacyPrefix | js}}", - "*": "{{ .MasterPrefix | js}}" + "v1": "{{ .MasterPrefix | js}}" }, resources: { {{range $i,$e := .MasterResources}}{{if $i}}, @@ -158,7 +157,7 @@ window.OPENSHIFT_CONFIG = { k8s: { hostPort: "{{ .KubernetesAddr | js}}", prefixes: { - "*": "{{ .KubernetesPrefix | js}}" + "v1": "{{ .KubernetesPrefix | js}}" }, resources: { {{range $i,$e := .KubernetesResources}}{{if $i}}, @@ -182,8 +181,6 @@ type WebConsoleConfig struct { MasterAddr string // MasterPrefix is the OpenShift API context root MasterPrefix string - // MasterLegacyPrefix is the OpenShift API context root for legacy API versions - MasterLegacyPrefix string // MasterResources holds resource names for the OpenShift API MasterResources []string // KubernetesAddr is the host:port the UI should call the kubernetes API on. Scheme is derived from the scheme the UI is served on, so they must be the same. diff --git a/pkg/client/client.go b/pkg/client/client.go index b352c0d930c4..3705592cc81b 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -258,16 +258,10 @@ func SetOpenShiftDefaults(config *kclient.Config) error { } if config.Version == "" { // Clients default to the preferred code API version - // TODO: implement version negotiation (highest version supported by server) config.Version = latest.Version } if config.Prefix == "" { - switch config.Version { - case "v1beta3": - config.Prefix = "/osapi" - default: - config.Prefix = "/oapi" - } + config.Prefix = "/oapi" } version := config.Version versionInterfaces, err := latest.InterfacesFor(version) diff --git a/pkg/cmd/cli/cmd/loginoptions.go b/pkg/cmd/cli/cmd/loginoptions.go index c4ee70604141..0d448f020a21 100644 --- a/pkg/cmd/cli/cmd/loginoptions.go +++ b/pkg/cmd/cli/cmd/loginoptions.go @@ -128,7 +128,7 @@ func (o *LoginOptions) getClientConfig() (*kclient.Config, error) { return nil, err } - result := osClient.Get().AbsPath("/osapi").Do() + result := osClient.Get().AbsPath("/").Do() if result.Error() != nil { switch { case o.InsecureTLS: diff --git a/pkg/cmd/server/api/types.go b/pkg/cmd/server/api/types.go index f26af820b0c6..3039e586acb2 100644 --- a/pkg/cmd/server/api/types.go +++ b/pkg/cmd/server/api/types.go @@ -4,6 +4,8 @@ import ( "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/sets" + + "github.com/openshift/origin/pkg/api/latest" ) // A new entry shall be added to FeatureAliases for every change to following values. @@ -16,10 +18,25 @@ const ( var ( KnownKubernetesAPILevels = []string{"v1beta1", "v1beta2", "v1beta3", "v1"} KnownOpenShiftAPILevels = []string{"v1beta1", "v1beta3", "v1"} - DefaultKubernetesAPILevels = []string{"v1beta3", "v1"} - DefaultOpenShiftAPILevels = []string{"v1beta3", "v1"} - DeadKubernetesAPILevels = []string{"v1beta1", "v1beta2"} - DeadOpenShiftAPILevels = []string{"v1beta1"} + DefaultKubernetesAPILevels = []string{"v1"} + DefaultOpenShiftAPILevels = []string{"v1"} + DeadKubernetesAPILevels = []string{"v1beta1", "v1beta2", "v1beta3"} + DeadOpenShiftAPILevels = []string{"v1beta1", "v1beta3"} + // KnownKubernetesStorageVersionLevels are storage versions that can be + // dealt with internally. + KnownKubernetesStorageVersionLevels = []string{"v1", "v1beta3"} + // KnownOpenShiftStorageVersionLevels are storage versions that can be dealt + // with internally + KnownOpenShiftStorageVersionLevels = latest.Versions + // DefaultOpenShiftStorageVersionLevel is the default storage version for + // resources. + DefaultOpenShiftStorageVersionLevel = latest.Versions[0] + // DeadKubernetesStorageVersionLevels are storage versions which shouldn't + // be exposed externally. + DeadKubernetesStorageVersionLevels = []string{"v1beta3"} + // DeadOpenShiftStorageVersionLevels are storage versions which shouldn't be + // exposed externally. + DeadOpenShiftStorageVersionLevels = []string{"v1beta1", "v1beta3"} // FeatureAliases maps deprecated names of feature flag to their canonical // names. Aliases must be lower-cased for O(1) lookup. diff --git a/pkg/cmd/server/api/v1/conversions.go b/pkg/cmd/server/api/v1/conversions.go index 49da65ccdefb..ae0980e58385 100644 --- a/pkg/cmd/server/api/v1/conversions.go +++ b/pkg/cmd/server/api/v1/conversions.go @@ -96,7 +96,7 @@ func init() { obj.KubernetesStoragePrefix = "kubernetes.io" } if len(obj.OpenShiftStorageVersion) == 0 { - obj.OpenShiftStorageVersion = "v1" + obj.OpenShiftStorageVersion = newer.DefaultOpenShiftStorageVersionLevel } if len(obj.OpenShiftStoragePrefix) == 0 { obj.OpenShiftStoragePrefix = "openshift.io" diff --git a/pkg/cmd/server/api/validation/master.go b/pkg/cmd/server/api/validation/master.go index a05a5f1eb804..e453f0311675 100644 --- a/pkg/cmd/server/api/validation/master.go +++ b/pkg/cmd/server/api/validation/master.go @@ -198,12 +198,16 @@ func ValidateAPILevels(apiLevels []string, knownAPILevels, deadAPILevels []strin func ValidateEtcdStorageConfig(config api.EtcdStorageConfig) fielderrors.ValidationErrorList { allErrs := fielderrors.ValidationErrorList{} - if len(config.KubernetesStorageVersion) == 0 { - allErrs = append(allErrs, fielderrors.NewFieldRequired("kubernetesStorageVersion")) - } - if len(config.OpenShiftStorageVersion) == 0 { - allErrs = append(allErrs, fielderrors.NewFieldRequired("openShiftStorageVersion")) - } + allErrs = append(allErrs, ValidateStorageVersionLevel( + config.KubernetesStorageVersion, + api.KnownKubernetesStorageVersionLevels, + api.DeadKubernetesStorageVersionLevels, + "kubernetesStorageVersion")...) + allErrs = append(allErrs, ValidateStorageVersionLevel( + config.OpenShiftStorageVersion, + api.KnownOpenShiftStorageVersionLevels, + api.DeadOpenShiftStorageVersionLevels, + "openShiftStorageVersion")...) if strings.ContainsRune(config.KubernetesStoragePrefix, '%') { allErrs = append(allErrs, fielderrors.NewFieldInvalid("kubernetesStoragePrefix", config.KubernetesStoragePrefix, "the '%' character may not be used in etcd path prefixes")) @@ -215,6 +219,22 @@ func ValidateEtcdStorageConfig(config api.EtcdStorageConfig) fielderrors.Validat return allErrs } +func ValidateStorageVersionLevel(level string, knownAPILevels, deadAPILevels []string, name string) fielderrors.ValidationErrorList { + allErrs := fielderrors.ValidationErrorList{} + + if len(level) == 0 { + allErrs = append(allErrs, fielderrors.NewFieldRequired(name)) + return allErrs + } + supportedLevels := sets.NewString(knownAPILevels...) + supportedLevels.Delete(deadAPILevels...) + if !supportedLevels.Has(level) { + allErrs = append(allErrs, fielderrors.NewFieldValueNotSupported(name, level, supportedLevels.List())) + } + + return allErrs +} + func ValidateServiceAccountConfig(config api.ServiceAccountConfig, builtInKubernetes bool) ValidationResults { validationResults := ValidationResults{} diff --git a/pkg/cmd/server/api/validation/master_test.go b/pkg/cmd/server/api/validation/master_test.go index d7b94d86e00f..54bd74dec45a 100644 --- a/pkg/cmd/server/api/validation/master_test.go +++ b/pkg/cmd/server/api/validation/master_test.go @@ -3,8 +3,11 @@ package validation import ( "testing" + kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" + "github.com/openshift/origin/pkg/cmd/server/api" configapi "github.com/openshift/origin/pkg/cmd/server/api" ) @@ -127,3 +130,83 @@ func TestFailingControllerArgs(t *testing.T) { t.Errorf("expected %v, got %v", e, a) } } + +func TestValidate_ValidateEtcdStorageConfig(t *testing.T) { + osField := "openShiftStorageVersion" + kubeField := "kubernetesStorageVersion" + tests := []struct { + label string + kubeStorageVersion string + openshiftStorageVersion string + name string + expected fielderrors.ValidationErrorList + }{ + { + label: "valid levels", + kubeStorageVersion: "v1", + openshiftStorageVersion: "v1", + expected: fielderrors.ValidationErrorList{}, + }, + { + label: "unknown openshift level", + kubeStorageVersion: "v1", + openshiftStorageVersion: "bogus", + expected: fielderrors.ValidationErrorList{ + fielderrors.NewFieldValueNotSupported(osField, "bogus", []string{"v1"}), + }, + }, + { + label: "unsupported openshift level", + kubeStorageVersion: "v1", + openshiftStorageVersion: "v1beta3", + expected: fielderrors.ValidationErrorList{ + fielderrors.NewFieldValueNotSupported(osField, "v1beta3", []string{"v1"}), + }, + }, + { + label: "missing openshift level", + kubeStorageVersion: "v1", + openshiftStorageVersion: "", + expected: fielderrors.ValidationErrorList{ + fielderrors.NewFieldRequired(osField), + }, + }, + { + label: "unknown kube level", + kubeStorageVersion: "bogus", + openshiftStorageVersion: "v1", + expected: fielderrors.ValidationErrorList{ + fielderrors.NewFieldValueNotSupported(kubeField, "bogus", []string{"v1"}), + }, + }, + { + label: "unsupported kube level", + kubeStorageVersion: "v1beta3", + openshiftStorageVersion: "v1", + expected: fielderrors.ValidationErrorList{ + fielderrors.NewFieldValueNotSupported(kubeField, "v1beta3", []string{"v1"}), + }, + }, + { + label: "missing kube level", + kubeStorageVersion: "", + openshiftStorageVersion: "v1", + expected: fielderrors.ValidationErrorList{ + fielderrors.NewFieldRequired(kubeField), + }, + }, + } + + for _, test := range tests { + t.Logf("evaluating test: %s", test.label) + config := api.EtcdStorageConfig{ + OpenShiftStorageVersion: test.openshiftStorageVersion, + KubernetesStorageVersion: test.kubeStorageVersion, + } + results := ValidateEtcdStorageConfig(config) + if !kapi.Semantic.DeepEqual(test.expected, results) { + t.Errorf("unexpected validation results; diff:\n%v", util.ObjectDiff(test.expected, results)) + return + } + } +} diff --git a/pkg/cmd/server/kubernetes/master.go b/pkg/cmd/server/kubernetes/master.go index 016db87a1435..962dffe7e0ec 100644 --- a/pkg/cmd/server/kubernetes/master.go +++ b/pkg/cmd/server/kubernetes/master.go @@ -31,9 +31,8 @@ import ( ) const ( - KubeAPIPrefix = "/api" - KubeAPIPrefixV1Beta3 = "/api/v1beta3" - KubeAPIPrefixV1 = "/api/v1" + KubeAPIPrefix = "/api" + KubeAPIPrefixV1 = "/api/v1" ) // InstallAPI starts a Kubernetes master and registers the supported REST APIs diff --git a/pkg/cmd/server/origin/asset.go b/pkg/cmd/server/origin/asset.go index 193b9a6a0cc2..b5faba5106c7 100644 --- a/pkg/cmd/server/origin/asset.go +++ b/pkg/cmd/server/origin/asset.go @@ -164,6 +164,8 @@ func (c *AssetConfig) addHandlers(mux *http.ServeMux) error { versions := sets.NewString() versions.Insert(latest.Versions...) versions.Insert(klatest.VersionsForLegacyGroup()...) + deadOriginVersions := sets.NewString(configapi.DeadOpenShiftAPILevels...) + deadKubernetesVersions := sets.NewString(configapi.DeadKubernetesAPILevels...) for _, version := range versions.List() { for kind, t := range api.Scheme.KnownTypes(version) { if strings.Contains(t.PkgPath(), "kubernetes/pkg/expapi") { @@ -174,9 +176,13 @@ func (c *AssetConfig) addHandlers(mux *http.ServeMux) error { } resource, _ := meta.KindToResource(kind, false) if latest.OriginKind(kind, version) { - originResources.Insert(resource) + if !deadOriginVersions.Has(version) { + originResources.Insert(resource) + } } else { - k8sResources.Insert(resource) + if !deadKubernetesVersions.Has(version) { + k8sResources.Insert(resource) + } } } } @@ -195,7 +201,6 @@ func (c *AssetConfig) addHandlers(mux *http.ServeMux) error { config := assets.WebConsoleConfig{ MasterAddr: masterURL.Host, MasterPrefix: OpenShiftAPIPrefix, - MasterLegacyPrefix: LegacyOpenShiftAPIPrefix, MasterResources: originResources.List(), KubernetesAddr: masterURL.Host, KubernetesPrefix: KubernetesAPIPrefix, diff --git a/pkg/cmd/server/origin/handlers.go b/pkg/cmd/server/origin/handlers.go index 8e9be8d5354f..7640e18e56b8 100644 --- a/pkg/cmd/server/origin/handlers.go +++ b/pkg/cmd/server/origin/handlers.go @@ -29,7 +29,6 @@ func indexAPIPaths(handler http.Handler) http.Handler { // TODO once we have a MuxHelper we will not need to hardcode this list of paths object := unversioned.RootPaths{Paths: []string{ "/api", - "/api/v1beta3", "/api/v1", "/controllers", "/healthz", @@ -37,8 +36,6 @@ func indexAPIPaths(handler http.Handler) http.Handler { "/logs/", "/metrics", "/ready", - "/osapi", - "/osapi/v1beta3", "/oapi", "/oapi/v1", "/swaggerapi/", diff --git a/pkg/cmd/server/origin/master.go b/pkg/cmd/server/origin/master.go index ed2acb9523c2..3897a35b5861 100644 --- a/pkg/cmd/server/origin/master.go +++ b/pkg/cmd/server/origin/master.go @@ -274,14 +274,6 @@ func (c *MasterConfig) InstallProtectedAPI(container *restful.Container) []strin legacyAPIVersions := []string{} currentAPIVersions := []string{} - if configapi.HasOpenShiftAPILevel(c.Options, OpenShiftAPIV1Beta3) { - if err := c.api_v1beta3(storage).InstallREST(container); err != nil { - glog.Fatalf("Unable to initialize v1beta3 API: %v", err) - } - messages = append(messages, fmt.Sprintf("Started Origin API at %%s%s", OpenShiftAPIPrefixV1Beta3)) - legacyAPIVersions = append(legacyAPIVersions, OpenShiftAPIV1Beta3) - } - if configapi.HasOpenShiftAPILevel(c.Options, OpenShiftAPIV1) { if err := c.api_v1(storage).InstallREST(container); err != nil { glog.Fatalf("Unable to initialize v1 API: %v", err) @@ -307,6 +299,10 @@ func (c *MasterConfig) InstallProtectedAPI(container *restful.Container) []strin container.Add(root) } + // The old API prefix must continue to return 200 (with an empty versions + // list) for backwards compatibility, even though we won't service any other + // requests through the route. Take care when considering whether to delete + // this route. initAPIVersionRoute(root, LegacyOpenShiftAPIPrefix, legacyAPIVersions...) initAPIVersionRoute(root, OpenShiftAPIPrefix, currentAPIVersions...) @@ -502,10 +498,6 @@ func (c *MasterConfig) InstallUnprotectedAPI(container *restful.Container) []str // initAPIVersionRoute initializes the osapi endpoint to behave similar to the upstream api endpoint func initAPIVersionRoute(root *restful.WebService, prefix string, versions ...string) { - if len(versions) == 0 { - return - } - versionHandler := apiserver.APIVersionHandler(versions...) root.Route(root.GET(prefix).To(versionHandler). Doc("list supported server API versions"). diff --git a/pkg/cmd/util/clientcmd/errors_test.go b/pkg/cmd/util/clientcmd/errors_test.go new file mode 100644 index 000000000000..da7649106442 --- /dev/null +++ b/pkg/cmd/util/clientcmd/errors_test.go @@ -0,0 +1,21 @@ +package clientcmd + +import ( + "net/http" + "net/http/httptest" + "testing" +) + +func TestIsCertificateAuthorityUnknown(t *testing.T) { + server := httptest.NewTLSServer(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})) + defer server.Close() + + req, _ := http.NewRequest("GET", server.URL, nil) + _, err := http.DefaultClient.Do(req) + if err == nil { + t.Fatalf("Expected TLS error") + } + if !IsCertificateAuthorityUnknown(err) { + t.Fatalf("Expected IsCertificateAuthorityUnknown error, error message was %q", err.Error()) + } +} diff --git a/pkg/cmd/util/clientcmd/factory.go b/pkg/cmd/util/clientcmd/factory.go index 547c72b9c5ec..19442dc432c5 100644 --- a/pkg/cmd/util/clientcmd/factory.go +++ b/pkg/cmd/util/clientcmd/factory.go @@ -55,6 +55,7 @@ func NewFactory(clientConfig kclientcmd.ClientConfig) *Factory { clients := &clientCache{ clients: make(map[string]*client.Client), + configs: make(map[string]*kclient.Config), loader: clientConfig, } @@ -71,7 +72,9 @@ func NewFactory(clientConfig kclientcmd.ClientConfig) *Factory { } w.Object = func() (meta.RESTMapper, runtime.ObjectTyper) { - if cfg, err := clientConfig.ClientConfig(); err == nil { + // Output using whatever version was negotiated in the client cache. The + // version we decode with may not be the same as what the server requires. + if cfg, err := clients.ClientConfigForVersion(""); err == nil { return kubectl.OutputVersionMapper{RESTMapper: mapper, OutputVersion: cfg.Version}, api.Scheme } return mapper, api.Scheme @@ -265,12 +268,16 @@ func expandResourceShortcut(resource string) string { return resource } -// clientCache caches previously loaded clients for reuse, and ensures MatchServerVersion -// is invoked only once +// clientCache caches previously loaded clients for reuse. This is largely +// copied from upstream (because of typing) but reuses the negotiation logic. +// TODO: Consolidate this entire concept with upstream's ClientCache. type clientCache struct { loader kclientcmd.ClientConfig clients map[string]*client.Client + configs map[string]*kclient.Config defaultConfig *kclient.Config + // negotiatingClient is used only for negotiating versions with the server. + negotiatingClient *kclient.Client } // ClientConfigForVersion returns the correct config for a server @@ -283,11 +290,36 @@ func (c *clientCache) ClientConfigForVersion(version string) (*kclient.Config, e c.defaultConfig = config } // TODO: have a better config copy method + if config, ok := c.configs[version]; ok { + return config, nil + } + if c.negotiatingClient == nil { + // TODO: We want to reuse the upstream negotiation logic, which is coupled + // to a concrete kube Client. The negotiation will ultimately try and + // build an unversioned URL using the config prefix to ask for supported + // server versions. If we use the default kube client config, the prefix + // will be /api, while we need to use the OpenShift prefix to ask for the + // OpenShift server versions. For now, set OpenShift defaults on the + // config to ensure the right prefix gets used. The client cache and + // negotiation logic should be refactored upstream to support downstream + // reuse so that we don't need to do any of this cache or negotiation + // duplication. + negotiatingConfig := *c.defaultConfig + client.SetOpenShiftDefaults(&negotiatingConfig) + negotiatingClient, err := kclient.New(&negotiatingConfig) + if err != nil { + return nil, err + } + c.negotiatingClient = negotiatingClient + } config := *c.defaultConfig - if len(version) != 0 { - config.Version = version + negotiatedVersion, err := kclient.NegotiateVersion(c.negotiatingClient, &config, version, latest.Versions) + if err != nil { + return nil, err } + config.Version = negotiatedVersion client.SetOpenShiftDefaults(&config) + c.configs[version] = &config return &config, nil } @@ -295,15 +327,13 @@ func (c *clientCache) ClientConfigForVersion(version string) (*kclient.Config, e // ClientForVersion initializes or reuses a client for the specified version, or returns an // error if that is not possible func (c *clientCache) ClientForVersion(version string) (*client.Client, error) { + if client, ok := c.clients[version]; ok { + return client, nil + } config, err := c.ClientConfigForVersion(version) if err != nil { return nil, err } - - if client, ok := c.clients[config.Version]; ok { - return client, nil - } - client, err := client.New(config) if err != nil { return nil, err diff --git a/pkg/cmd/util/clientcmd/factory_test.go b/pkg/cmd/util/clientcmd/factory_test.go new file mode 100644 index 000000000000..3d8c52d2a199 --- /dev/null +++ b/pkg/cmd/util/clientcmd/factory_test.go @@ -0,0 +1,71 @@ +package clientcmd + +import ( + "net/http" + "net/http/httptest" + "testing" + + kclient "k8s.io/kubernetes/pkg/client/unversioned" + + "github.com/openshift/origin/pkg/client" +) + +func TestClientConfigForVersion(t *testing.T) { + called := 0 + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + if req.URL.Path != "/oapi" { + t.Fatalf("Unexpected path called during negotiation: %s", req.URL.Path) + } + called++ + w.Write([]byte(`{"versions":["v1"]}`)) + })) + defer server.Close() + + defaultConfig := &kclient.Config{Host: server.URL} + client.SetOpenShiftDefaults(defaultConfig) + + clients := &clientCache{ + clients: make(map[string]*client.Client), + configs: make(map[string]*kclient.Config), + defaultConfig: defaultConfig, + } + + // First call, negotiate + called = 0 + v1Config, err := clients.ClientConfigForVersion("v1") + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if v1Config.Version != "v1" { + t.Fatalf("Expected v1, got %v", v1Config.Version) + } + if called != 1 { + t.Fatalf("Expected to be called 1 time during negotiation, was called %d times", called) + } + + // Second call, cache + called = 0 + v1Config, err = clients.ClientConfigForVersion("v1") + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if v1Config.Version != "v1" { + t.Fatalf("Expected v1, got %v", v1Config.Version) + } + if called != 0 { + t.Fatalf("Expected not be called again getting a config from cache, was called %d additional times", called) + } + + // Call for unsupported version, negotiate to supported version + called = 0 + v1beta3Config, err := clients.ClientConfigForVersion("v1beta3") + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if v1beta3Config.Version != "v1" { + t.Fatalf("Expected to negotiate v1 for v1beta3 config, got %v", v1beta3Config.Version) + } + if called != 1 { + t.Fatalf("Expected to be called once getting a config for a new version, was called %d times", called) + } +} diff --git a/test/cmd/basicresources.sh b/test/cmd/basicresources.sh index ae4a5b62da06..da72630d3f8c 100755 --- a/test/cmd/basicresources.sh +++ b/test/cmd/basicresources.sh @@ -43,6 +43,11 @@ oc create -f test/integration/fixtures/test-service.json oc delete services frontend echo "services: ok" +oc create -f test/fixtures/mixed-api-versions.yaml +oc get -f test/fixtures/mixed-api-versions.yaml -o yaml > /dev/null +oc delete -f test/fixtures/mixed-api-versions.yaml +echo "list version conversion: ok" + oc get nodes ( # subshell so we can unset kubeconfig diff --git a/test/cmd/builds.sh b/test/cmd/builds.sh index d241a419f063..3f121f3ae0bc 100755 --- a/test/cmd/builds.sh +++ b/test/cmd/builds.sh @@ -32,15 +32,13 @@ oc get bc/ruby-sample-build -t '{{ .spec.output.to.name }}' | grep 'different' oc patch bc/ruby-sample-build -p "{\"spec\":{\"output\":{\"to\":{\"name\":\"${REAL_OUTPUT_TO}\"}}}}" echo "patchAnonFields: ok" -[ "$(oc describe buildConfigs ruby-sample-build --api-version=v1beta3 | grep --text "Webhook GitHub" | grep -F "${url}/osapi/v1beta3/namespaces/${project}/buildconfigs/ruby-sample-build/webhooks/secret101/github")" ] -[ "$(oc describe buildConfigs ruby-sample-build --api-version=v1beta3 | grep --text "Webhook Generic" | grep -F "${url}/osapi/v1beta3/namespaces/${project}/buildconfigs/ruby-sample-build/webhooks/secret101/generic")" ] +[ "$(oc describe buildConfigs ruby-sample-build | grep --text "Webhook GitHub" | grep -F "${url}/oapi/v1/namespaces/${project}/buildconfigs/ruby-sample-build/webhooks/secret101/github")" ] +[ "$(oc describe buildConfigs ruby-sample-build | grep --text "Webhook Generic" | grep -F "${url}/oapi/v1/namespaces/${project}/buildconfigs/ruby-sample-build/webhooks/secret101/generic")" ] oc start-build --list-webhooks='all' ruby-sample-build [ "$(oc start-build --list-webhooks='all' ruby-sample-build | grep --text "generic")" ] [ "$(oc start-build --list-webhooks='all' ruby-sample-build | grep --text "github")" ] [ "$(oc start-build --list-webhooks='github' ruby-sample-build | grep --text "secret101")" ] [ ! "$(oc start-build --list-webhooks='blah')" ] -webhook=$(oc start-build --list-webhooks='generic' ruby-sample-build --api-version=v1beta3 | head -n 1) -oc start-build --from-webhook="${webhook}" webhook=$(oc start-build --list-webhooks='generic' ruby-sample-build --api-version=v1 | head -n 1) oc start-build --from-webhook="${webhook}" oc get builds diff --git a/test/fixtures/mixed-api-versions.yaml b/test/fixtures/mixed-api-versions.yaml new file mode 100644 index 000000000000..37ed469e76c0 --- /dev/null +++ b/test/fixtures/mixed-api-versions.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: List +metadata: {} +items: + +- apiVersion: v1 + kind: Secret + metadata: + annotations: + description: v1 Secret - used to test v1 negotiation of k8s objects + name: v1-secret + +- apiVersion: v1beta3 + kind: Secret + metadata: + annotations: + description: v1beta3 Secret - used to test v1beta3 negotiation of k8s objects + name: v1beta3-secret + +- apiVersion: v1 + kind: Route + metadata: + annotations: + description: v1 Route - used to test v1 negotiation of origin objects + name: v1-route + spec: + to: + kind: Service + name: test + +- apiVersion: v1beta3 + kind: Route + metadata: + annotations: + description: v1beta3 Route - used to test v1beta3 negotiation of origin objects + name: v1beta3-route + spec: + to: + kind: Service + name: test + diff --git a/test/integration/router/router_http_server.go b/test/integration/router/router_http_server.go index 40e887032f69..b797ca2960d7 100644 --- a/test/integration/router/router_http_server.go +++ b/test/integration/router/router_http_server.go @@ -181,8 +181,6 @@ func (s *TestHttpService) startMaster() error { for _, version := range apis { masterServer.HandleFunc(fmt.Sprintf("/api/%s/endpoints", version), s.handleEndpointList) masterServer.HandleFunc(fmt.Sprintf("/api/%s/watch/endpoints", version), s.handleEndpointWatch) - masterServer.HandleFunc(fmt.Sprintf("/osapi/%s/routes", version), s.handleRouteList) - masterServer.HandleFunc(fmt.Sprintf("/osapi/%s/watch/routes", version), s.handleRouteWatch) masterServer.HandleFunc(fmt.Sprintf("/oapi/%s/routes", version), s.handleRouteList) masterServer.HandleFunc(fmt.Sprintf("/oapi/%s/watch/routes", version), s.handleRouteWatch) } diff --git a/test/integration/template_test.go b/test/integration/template_test.go index 80cf4d00154d..710f11fc49e6 100644 --- a/test/integration/template_test.go +++ b/test/integration/template_test.go @@ -5,7 +5,7 @@ package integration import ( "testing" - "k8s.io/kubernetes/pkg/api/v1beta3" + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/runtime" "github.com/openshift/origin/pkg/client" @@ -22,7 +22,7 @@ func TestTemplate(t *testing.T) { if err != nil { t.Fatalf("unexpected error: %v", err) } - for _, version := range []string{"v1", "v1beta3"} { + for _, version := range []string{"v1"} { config, err := testutil.GetClusterAdminClientConfig(path) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -42,13 +42,13 @@ func TestTemplate(t *testing.T) { }, }, Objects: []runtime.Object{ - &v1beta3.Service{ - ObjectMeta: v1beta3.ObjectMeta{ + &v1.Service{ + ObjectMeta: v1.ObjectMeta{ Name: "${NAME}-tester", Namespace: "somevalue", }, - Spec: v1beta3.ServiceSpec{ - PortalIP: "1.2.3.4", + Spec: v1.ServiceSpec{ + ClusterIP: "1.2.3.4", SessionAffinity: "some-bad-${VALUE}", }, }, @@ -69,7 +69,7 @@ func TestTemplate(t *testing.T) { spec := svc["spec"].(map[string]interface{}) meta := svc["metadata"].(map[string]interface{}) // keep existing values - if spec["portalIP"] != "1.2.3.4" { + if spec["clusterIP"] != "1.2.3.4" { t.Fatalf("unexpected object: %#v", svc) } // replace a value diff --git a/test/old-start-configs/v1.0.0/test-end-to-end.sh b/test/old-start-configs/v1.0.0/test-end-to-end.sh index 322e9a9781b6..742286088722 100755 --- a/test/old-start-configs/v1.0.0/test-end-to-end.sh +++ b/test/old-start-configs/v1.0.0/test-end-to-end.sh @@ -275,7 +275,7 @@ fi wait_for_url "${KUBELET_SCHEME}://${KUBELET_HOST}:${KUBELET_PORT}/healthz" "[INFO] kubelet: " 0.5 60 wait_for_url "${API_SCHEME}://${API_HOST}:${API_PORT}/healthz" "apiserver: " 0.25 80 wait_for_url "${API_SCHEME}://${API_HOST}:${API_PORT}/healthz/ready" "apiserver(ready): " 0.25 80 -wait_for_url "${API_SCHEME}://${API_HOST}:${API_PORT}/api/v1beta3/nodes/${KUBELET_HOST}" "apiserver(nodes): " 0.25 80 +wait_for_url "${API_SCHEME}://${API_HOST}:${API_PORT}/api/v1/nodes/${KUBELET_HOST}" "apiserver(nodes): " 0.25 80 # COMPATIBILITY update the cluster roles and role bindings so that new images can be used. oadm policy reconcile-cluster-roles --confirm

      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 z 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 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-overview.png b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/k8s-ui-overview.png deleted file mode 100644 index ca98b28255c450d8cfa30291d67b51ac004f101d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78341 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�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 diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/known-issues.md b/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/known-issues.md deleted file mode 100644 index 894657a9629e..000000000000 --- a/Godeps/_workspace/src/k8s.io/kubernetes/docs/user-guide/known-issues.md +++ /dev/null @@ -1,59 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

    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